From 252ecca9cf3d9c37281c6ce6c21314f0082f80a7 Mon Sep 17 00:00:00 2001 From: topicchi Date: Fri, 17 Mar 2023 11:40:49 +0000 Subject: [PATCH] daily_automated --- ...rduino as a floppy disk controller.desktop | 7 + trunk/Arduino/ArduinoFDC/ArduinoFDC.cpp | 1793 ++ trunk/Arduino/ArduinoFDC/ArduinoFDC.h | 140 + trunk/Arduino/ArduinoFDC/ArduinoFDC.ino | 990 ++ ...an Arduino as a floppy disk controller.url | 2 + trunk/Arduino/ArduinoFDC/LICENSE | 674 + trunk/Arduino/ArduinoFDC/README.md | 377 + trunk/Arduino/ArduinoFDC/XModem.cpp | 378 + trunk/Arduino/ArduinoFDC/XModem.h | 84 + trunk/Arduino/ArduinoFDC/diskio.cpp | 132 + trunk/Arduino/ArduinoFDC/diskio.h | 80 + trunk/Arduino/ArduinoFDC/ff.c | 6984 ++++++++ trunk/Arduino/ArduinoFDC/ff.h | 425 + trunk/Arduino/ArduinoFDC/ffconf.h | 302 + trunk/Arduino/ArduinoFDC/images/ArduDOS.png | Bin 0 -> 46331 bytes trunk/Arduino/ArduinoFDC/images/setup.jpg | Bin 0 -> 1237219 bytes .../CameraWebServer/CameraWebServer.ino | 112 + trunk/Arduino/CameraWebServer/app_httpd.cpp | 662 + trunk/Arduino/CameraWebServer/camera_index.h | 557 + trunk/Arduino/CameraWebServer/camera_pins.h | 156 + ...uino Floppy Disk Reader and Writer.desktop | 7 + ...uino Floppy Disk Reader and Writer.desktop | 7 + .../ArduinoFloppyReader.exe | Bin 0 -> 434176 bytes .../ArduinoFloppyReaderWin.exe | Bin 0 -> 4065280 bytes .../FloppyDriveController.sketch.ino | 1607 ++ .../FloppyDriveController.sketch/LICENSE.txt | 674 + .../V2.4/AmigaFloppyDiskReader-10.jpg | Bin 0 -> 98621 bytes .../V2.4/ArduinoFloppyReader.exe | Bin 0 -> 252416 bytes .../V2.4/ArduinoFloppyReaderWin.exe | Bin 0 -> 3743744 bytes .../FloppyDriveController.sketch.ino | 1083 ++ .../FloppyDriveController.sketch/LICENSE.txt | 674 + .../V2.4/LICENSE.txt | 674 + .../V2.4/Mingos Commodorepage.desktop | 7 + .../V2.4/encryptable | 0 .../V2.4/readme.txt | 80 + .../.github/FUNDING.yml | 1 + .../ArduinoFloppyReader/.gitattributes | 63 + .../ArduinoFloppyReader/.gitignore | 340 + .../ArduinoFloppyReader.sln | 41 + .../ArduinoFloppyReader.vcxproj | 185 + .../ArduinoFloppyReader.vcxproj.filters | 51 + .../ArduinoFloppyReader/ArduinoReaderWriter | Bin 0 -> 204320 bytes .../ArduinoFloppyReader/Main.cpp | 304 + .../ArduinoFloppyReader/makefile | 196 + .../ArduinoFloppyReader/makefile.bak | 71 + .../ArduinoFloppyReader/readme.txt | 10 + .../ArduinoFloppyReader/targetver.h | 8 + .../ArduinoFloppyReaderWin.aps | Bin 0 -> 426764 bytes .../ArduinoFloppyReaderWin.cpp | 122 + .../ArduinoFloppyReaderWin.h | 52 + .../ArduinoFloppyReaderWin.rc | Bin 0 -> 22624 bytes .../ArduinoFloppyReaderWin.vcxproj | 269 + .../ArduinoFloppyReaderWin.vcxproj.filters | 119 + .../ArduinoFloppyReaderWinDlg.cpp | 850 + .../ArduinoFloppyReaderWinDlg.h | 108 + .../ArduinoFloppyReaderWin/ReadMe.txt | 118 + .../res/ArduinoFloppyReaderWin.ico | Bin 0 -> 141217 bytes .../res/ArduinoFloppyReaderWin.rc2 | Bin 0 -> 828 bytes .../ArduinoFloppyReaderWin/res/fin.bmp | Bin 0 -> 23078 bytes .../ArduinoFloppyReaderWin/res/fin2.bmp | Bin 0 -> 23078 bytes .../ArduinoFloppyReaderWin/res/finpartial.bmp | Bin 0 -> 23078 bytes .../res/finpartial2.bmp | Bin 0 -> 23078 bytes .../ArduinoFloppyReaderWin/res/floppy.bmp | Bin 0 -> 14070 bytes .../ArduinoFloppyReaderWin/res/scp.bmp | Bin 0 -> 135846 bytes .../ArduinoFloppyReaderWin/res/sfx.wav | Bin 0 -> 10420 bytes .../ArduinoFloppyReaderWin/resource.h | Bin 0 -> 4956 bytes .../ArduinoFloppyReaderWin/stdafx.cpp | 8 + .../ArduinoFloppyReaderWin/stdafx.h | 53 + .../ArduinoFloppyReaderWin/targetver.h | 8 + .../ArduinoFloppyReader/LICENSE.txt | 674 + .../ArduinoFloppyReader/lib/ADFWriter.cpp | 1654 ++ .../ArduinoFloppyReader/lib/ADFWriter.h | 109 + .../lib/ArduinoInterface.cpp | 1346 ++ .../lib/ArduinoInterface.h | 269 + .../lib/RotationExtractor.cpp | 401 + .../lib/RotationExtractor.h | 200 + .../ArduinoFloppyReader/lib/SerialIO.cpp | 620 + .../ArduinoFloppyReader/lib/SerialIO.h | 134 + .../FloppyDriveController.sketch.ino | 1640 ++ .../FloppyDriveController.sketch/LICENSE.txt | 674 + .../LICENSE.txt | 674 + .../ArduinoFloppyDiskReader-master/readme.md | 89 + .../V2.6/ArduinoFloppyReader.exe | Bin 0 -> 436736 bytes .../V2.6/ArduinoFloppyReaderWin.exe | Bin 0 -> 4069888 bytes .../FloppyDriveController.sketch.ino | 1640 ++ .../FloppyDriveController.sketch/LICENSE.txt | 674 + .../V2.6/LICENSE.txt | 674 + .../V2.6/readme.txt | 41 + .../promini_writer.gif | Bin 0 -> 53313 bytes .../FloppyDriveController.sketch/readme.txt | 37 + trunk/Arduino/GRBL_1.1f/GRBL.ino | 29 + trunk/Arduino/GRBL_1.1f/config.h | 628 + trunk/Arduino/GRBL_1.1f/coolant_control.c | 126 + trunk/Arduino/GRBL_1.1f/coolant_control.h | 47 + trunk/Arduino/GRBL_1.1f/cpu_map.h | 160 + trunk/Arduino/GRBL_1.1f/defaults.h | 493 + trunk/Arduino/GRBL_1.1f/eagle_example.gcode | 1225 ++ trunk/Arduino/GRBL_1.1f/eagle_example_2.gcode | 1197 ++ trunk/Arduino/GRBL_1.1f/eeprom.c | 151 + trunk/Arduino/GRBL_1.1f/eeprom.h | 29 + .../examples/grblUpload/grblUpload.ino | 29 + .../GRBL_1.1f/examples/grblUpload/license.txt | 21 + .../grblWrite_BuildInfo.ino | 109 + .../examples/grblWrite_BuildInfo/license.txt | 21 + trunk/Arduino/GRBL_1.1f/gcode.c | 1159 ++ trunk/Arduino/GRBL_1.1f/gcode.h | 248 + trunk/Arduino/GRBL_1.1f/grbl.h | 116 + trunk/Arduino/GRBL_1.1f/jog.c | 50 + trunk/Arduino/GRBL_1.1f/jog.h | 32 + trunk/Arduino/GRBL_1.1f/limits.c | 360 + trunk/Arduino/GRBL_1.1f/limits.h | 41 + trunk/Arduino/GRBL_1.1f/main.c | 109 + trunk/Arduino/GRBL_1.1f/makefile | 130 + trunk/Arduino/GRBL_1.1f/motion_control.c | 388 + trunk/Arduino/GRBL_1.1f/motion_control.h | 66 + trunk/Arduino/GRBL_1.1f/nuts_bolts.c | 190 + trunk/Arduino/GRBL_1.1f/nuts_bolts.h | 87 + trunk/Arduino/GRBL_1.1f/planner.c | 522 + trunk/Arduino/GRBL_1.1f/planner.h | 150 + trunk/Arduino/GRBL_1.1f/print.c | 200 + trunk/Arduino/GRBL_1.1f/print.h | 51 + trunk/Arduino/GRBL_1.1f/probe.c | 66 + trunk/Arduino/GRBL_1.1f/probe.h | 43 + trunk/Arduino/GRBL_1.1f/protocol.c | 765 + trunk/Arduino/GRBL_1.1f/protocol.h | 49 + trunk/Arduino/GRBL_1.1f/report.c | 647 + trunk/Arduino/GRBL_1.1f/report.h | 131 + trunk/Arduino/GRBL_1.1f/serial.c | 204 + trunk/Arduino/GRBL_1.1f/serial.h | 62 + trunk/Arduino/GRBL_1.1f/settings.c | 340 + trunk/Arduino/GRBL_1.1f/settings.h | 153 + trunk/Arduino/GRBL_1.1f/spindle_control.c | 283 + trunk/Arduino/GRBL_1.1f/spindle_control.h | 73 + trunk/Arduino/GRBL_1.1f/stepper.c | 1022 ++ trunk/Arduino/GRBL_1.1f/stepper.h | 59 + trunk/Arduino/GRBL_1.1f/system.c | 407 + trunk/Arduino/GRBL_1.1f/system.h | 208 + .../Arduino/GRBL_1.1f_Nano/GRBL_1.1f_Nano.ino | 29 + trunk/Arduino/GRBL_1.1f_Nano/config.h | 628 + .../Arduino/GRBL_1.1f_Nano/coolant_control.c | 126 + .../Arduino/GRBL_1.1f_Nano/coolant_control.h | 47 + trunk/Arduino/GRBL_1.1f_Nano/cpu_map.h | 160 + trunk/Arduino/GRBL_1.1f_Nano/defaults.h | 493 + .../GRBL_1.1f_Nano/eagle_example.gcode | 1225 ++ .../GRBL_1.1f_Nano/eagle_example_2.gcode | 1197 ++ trunk/Arduino/GRBL_1.1f_Nano/eeprom.c | 151 + trunk/Arduino/GRBL_1.1f_Nano/eeprom.h | 29 + trunk/Arduino/GRBL_1.1f_Nano/gcode.c | 1159 ++ trunk/Arduino/GRBL_1.1f_Nano/gcode.h | 248 + trunk/Arduino/GRBL_1.1f_Nano/grbl.h | 116 + trunk/Arduino/GRBL_1.1f_Nano/jog.c | 50 + trunk/Arduino/GRBL_1.1f_Nano/jog.h | 32 + trunk/Arduino/GRBL_1.1f_Nano/limits.c | 360 + trunk/Arduino/GRBL_1.1f_Nano/limits.h | 41 + trunk/Arduino/GRBL_1.1f_Nano/main.c | 109 + trunk/Arduino/GRBL_1.1f_Nano/makefile | 130 + trunk/Arduino/GRBL_1.1f_Nano/motion_control.c | 388 + trunk/Arduino/GRBL_1.1f_Nano/motion_control.h | 66 + trunk/Arduino/GRBL_1.1f_Nano/nuts_bolts.c | 190 + trunk/Arduino/GRBL_1.1f_Nano/nuts_bolts.h | 87 + trunk/Arduino/GRBL_1.1f_Nano/planner.c | 522 + trunk/Arduino/GRBL_1.1f_Nano/planner.h | 150 + trunk/Arduino/GRBL_1.1f_Nano/print.c | 200 + trunk/Arduino/GRBL_1.1f_Nano/print.h | 51 + trunk/Arduino/GRBL_1.1f_Nano/probe.c | 66 + trunk/Arduino/GRBL_1.1f_Nano/probe.h | 43 + trunk/Arduino/GRBL_1.1f_Nano/protocol.c | 765 + trunk/Arduino/GRBL_1.1f_Nano/protocol.h | 49 + trunk/Arduino/GRBL_1.1f_Nano/report.c | 647 + trunk/Arduino/GRBL_1.1f_Nano/report.h | 131 + trunk/Arduino/GRBL_1.1f_Nano/serial.c | 204 + trunk/Arduino/GRBL_1.1f_Nano/serial.h | 62 + trunk/Arduino/GRBL_1.1f_Nano/settings.c | 340 + trunk/Arduino/GRBL_1.1f_Nano/settings.h | 153 + .../Arduino/GRBL_1.1f_Nano/spindle_control.c | 283 + .../Arduino/GRBL_1.1f_Nano/spindle_control.h | 73 + trunk/Arduino/GRBL_1.1f_Nano/stepper.c | 1022 ++ trunk/Arduino/GRBL_1.1f_Nano/stepper.h | 59 + trunk/Arduino/GRBL_1.1f_Nano/system.c | 407 + trunk/Arduino/GRBL_1.1f_Nano/system.h | 208 + .../GRBL_Adafruit_motor_driverV2.ino | 58 + .../GRBL_Adafruit_motor_driverV2/config.h | 69 + .../GRBL_Adafruit_motor_driverV2/eeprom.cpp | 174 + .../GRBL_Adafruit_motor_driverV2/eeprom.h | 31 + .../GRBL_Adafruit_motor_driverV2/g_print.cpp | 99 + .../GRBL_Adafruit_motor_driverV2/g_print.h | 35 + .../GRBL_Adafruit_motor_driverV2/gcode.cpp | 390 + .../GRBL_Adafruit_motor_driverV2/gcode.h | 22 + .../limit_switch.h | 45 + .../limit_swtch.cpp | 60 + .../GRBL_Adafruit_motor_driverV2/makefile | 130 + .../nuts_bolts.cpp | 70 + .../GRBL_Adafruit_motor_driverV2/nuts_bolts.h | 53 + .../GRBL_Adafruit_motor_driverV2/protocol.cpp | 180 + .../GRBL_Adafruit_motor_driverV2/protocol.h | 43 + .../GRBL_Adafruit_motor_driverV2/serial.cpp | 43 + .../GRBL_Adafruit_motor_driverV2/serial.h | 34 + .../GRBL_Adafruit_motor_driverV2/settings.cpp | 358 + .../GRBL_Adafruit_motor_driverV2/settings.h | 64 + .../stepper_control.cpp | 416 + .../stepper_control.h | 37 + trunk/Arduino/Marlin_1.1.6/Conditionals.h | 27 + trunk/Arduino/Marlin_1.1.6/Conditionals_LCD.h | 480 + .../Arduino/Marlin_1.1.6/Conditionals_post.h | 926 ++ trunk/Arduino/Marlin_1.1.6/Configuration.h | 1701 ++ .../Arduino/Marlin_1.1.6/Configuration_adv.h | 1424 ++ .../Marlin_1.1.6/G26_Mesh_Validation_Tool.cpp | 887 + .../Marlin_1.1.6/I2CPositionEncoder.cpp | 1132 ++ .../Arduino/Marlin_1.1.6/I2CPositionEncoder.h | 359 + .../Marlin_1.1.6/M100_Free_Mem_Chk.cpp | 333 + trunk/Arduino/Marlin_1.1.6/Makefile | 544 + .../Marlin_1.1.6/Marlin-1.1.x/.gitattributes | 20 + .../Marlin-1.1.x/.github/issue_template.md | 36 + .../Marlin_1.1.6/Marlin-1.1.x/.gitignore | 141 + .../Marlin_1.1.6/Marlin-1.1.x/.travis.yml | 359 + .../Arduino/Marlin_1.1.6/Marlin-1.1.x/LICENSE | 677 + .../Marlin_1.1.6/Marlin-1.1.x/README.md | 86 + .../Marlin-1.1.x/buildroot/bin/build_marlin | 8 + .../buildroot/bin/build_marlin_fail | 4 + .../bin/generate_version_header_for_marlin | 55 + .../Marlin-1.1.x/buildroot/bin/opt_disable | 5 + .../buildroot/bin/opt_disable_adv | 5 + .../Marlin-1.1.x/buildroot/bin/opt_enable | 5 + .../Marlin-1.1.x/buildroot/bin/opt_enable_adv | 5 + .../Marlin-1.1.x/buildroot/bin/opt_set | 3 + .../Marlin-1.1.x/buildroot/bin/opt_set_adv | 3 + .../Marlin-1.1.x/buildroot/bin/pins_set | 3 + .../buildroot/bin/restore_configs | 9 + .../buildroot/bin/use_example_configs | 7 + .../Marlin-1.1.x/buildroot/etc/.astylerc | 23 + .../buildroot/share/cmake/CMakeLists.txt | 123 + .../buildroot/share/fonts/HD44780_C.fon | Bin 0 -> 4176 bytes .../buildroot/share/fonts/HD44780_J.fon | Bin 0 -> 4176 bytes .../buildroot/share/fonts/HD44780_W.fon | Bin 0 -> 4432 bytes .../buildroot/share/fonts/ISO10646-1-tr.fon | Bin 0 -> 4224 bytes .../buildroot/share/fonts/ISO10646-1.fon | Bin 0 -> 4192 bytes .../share/fonts/ISO10646-4_Greek.fon | Bin 0 -> 4224 bytes .../share/fonts/ISO10646-5_Cyrillic.fon | Bin 0 -> 4224 bytes .../buildroot/share/fonts/ISO10646_CN.fon | Bin 0 -> 6192 bytes .../buildroot/share/fonts/ISO10646_CZ.fon | Bin 0 -> 4224 bytes .../buildroot/share/fonts/ISO10646_Kana.fon | Bin 0 -> 4208 bytes .../buildroot/share/fonts/ISO10646_SK.fon | Bin 0 -> 4224 bytes .../buildroot/share/fonts/Marlin_symbols.fon | Bin 0 -> 784 bytes .../buildroot/share/fonts/README.md | 23 + .../buildroot/share/fonts/make_fonts.bat | 10 + .../buildroot/share/git/README.md | 60 + .../buildroot/share/git/firstpush | 28 + .../Marlin-1.1.x/buildroot/share/git/ghtp | 33 + .../Marlin-1.1.x/buildroot/share/git/mfadd | 20 + .../Marlin-1.1.x/buildroot/share/git/mfclean | 30 + .../Marlin-1.1.x/buildroot/share/git/mfdoc | 35 + .../Marlin-1.1.x/buildroot/share/git/mfinfo | 39 + .../Marlin-1.1.x/buildroot/share/git/mfinit | 17 + .../Marlin-1.1.x/buildroot/share/git/mfnew | 20 + .../Marlin-1.1.x/buildroot/share/git/mfpr | 37 + .../Marlin-1.1.x/buildroot/share/git/mfpub | 116 + .../Marlin-1.1.x/buildroot/share/git/mfqp | 28 + .../Marlin-1.1.x/buildroot/share/git/mfrb | 19 + .../Marlin-1.1.x/buildroot/share/git/mfup | 56 + .../pin_interrupt_test/pin_interrupt_test.ino | 32 + .../share/pixmaps/logo/marlin-1080.png | Bin 0 -> 56379 bytes .../share/pixmaps/logo/marlin-250.png | Bin 0 -> 10741 bytes .../share/pixmaps/logo/marlin-old-250.png | Bin 0 -> 4172 bytes .../share/pixmaps/logo/marlin-old-627.png | Bin 0 -> 39702 bytes .../share/pixmaps/logo/marlin-old.svg | 106 + .../buildroot/share/pixmaps/logo/marlin.svg | 131 + .../buildroot/share/scripts/MarlinMesh.scad | 256 + .../share/scripts/createSpeedLookupTable.py | 50 + .../scripts/createTemperatureLookupMarlin.py | 156 + .../share/scripts/findMissingTranslations.sh | 44 + .../buildroot/share/scripts/g29_auto.py | 186 + .../Marlin_1.1.6/Marlin-1.1.x/platformio.ini | 82 + trunk/Arduino/Marlin_1.1.6/Marlin.h | 497 + trunk/Arduino/Marlin_1.1.6/MarlinConfig.h | 41 + trunk/Arduino/Marlin_1.1.6/MarlinSerial.cpp | 654 + trunk/Arduino/Marlin_1.1.6/MarlinSerial.h | 180 + trunk/Arduino/Marlin_1.1.6/Marlin_1.1.6.ino | 72 + trunk/Arduino/Marlin_1.1.6/Marlin_main.cpp | 13689 ++++++++++++++++ .../Marlin_1.1.6/Max7219_Debug_LEDs.cpp | 236 + .../Arduino/Marlin_1.1.6/Max7219_Debug_LEDs.h | 88 + trunk/Arduino/Marlin_1.1.6/SanityCheck.h | 1386 ++ trunk/Arduino/Marlin_1.1.6/Sd2Card.cpp | 729 + trunk/Arduino/Marlin_1.1.6/Sd2Card.h | 251 + trunk/Arduino/Marlin_1.1.6/SdBaseFile.cpp | 1826 +++ trunk/Arduino/Marlin_1.1.6/SdBaseFile.h | 492 + trunk/Arduino/Marlin_1.1.6/SdFatConfig.h | 134 + trunk/Arduino/Marlin_1.1.6/SdFatStructs.h | 655 + trunk/Arduino/Marlin_1.1.6/SdFatUtil.cpp | 91 + trunk/Arduino/Marlin_1.1.6/SdFatUtil.h | 56 + trunk/Arduino/Marlin_1.1.6/SdFile.cpp | 102 + trunk/Arduino/Marlin_1.1.6/SdFile.h | 63 + trunk/Arduino/Marlin_1.1.6/SdInfo.h | 289 + trunk/Arduino/Marlin_1.1.6/SdVolume.cpp | 420 + trunk/Arduino/Marlin_1.1.6/SdVolume.h | 227 + trunk/Arduino/Marlin_1.1.6/Version.h | 94 + trunk/Arduino/Marlin_1.1.6/blinkm.cpp | 46 + trunk/Arduino/Marlin_1.1.6/blinkm.h | 31 + trunk/Arduino/Marlin_1.1.6/boards.h | 106 + trunk/Arduino/Marlin_1.1.6/buzzer.h | 146 + trunk/Arduino/Marlin_1.1.6/cardreader.cpp | 885 + trunk/Arduino/Marlin_1.1.6/cardreader.h | 190 + trunk/Arduino/Marlin_1.1.6/circularqueue.h | 145 + .../Marlin_1.1.6/configuration_store.cpp | 1852 +++ .../Marlin_1.1.6/configuration_store.h | 82 + trunk/Arduino/Marlin_1.1.6/dac_mcp4728.cpp | 151 + trunk/Arduino/Marlin_1.1.6/dac_mcp4728.h | 66 + .../Arduino/Marlin_1.1.6/digipot_mcp4018.cpp | 106 + .../Arduino/Marlin_1.1.6/digipot_mcp4451.cpp | 79 + trunk/Arduino/Marlin_1.1.6/dogm_bitmaps.h | 514 + .../Marlin_1.1.6/dogm_font_data_6x9_marlin.h | 180 + .../Marlin_1.1.6/dogm_font_data_HD44780_C.h | 194 + .../Marlin_1.1.6/dogm_font_data_HD44780_J.h | 192 + .../Marlin_1.1.6/dogm_font_data_HD44780_W.h | 226 + .../Marlin_1.1.6/dogm_font_data_ISO10646_1.h | 198 + .../dogm_font_data_ISO10646_1_PL.h | 184 + .../dogm_font_data_ISO10646_1_tr.h | 197 + .../dogm_font_data_ISO10646_5_Cyrillic.h | 196 + .../Marlin_1.1.6/dogm_font_data_ISO10646_CN.h | 293 + .../Marlin_1.1.6/dogm_font_data_ISO10646_CZ.h | 192 + .../dogm_font_data_ISO10646_Greek.h | 205 + .../dogm_font_data_ISO10646_Kana.h | 192 + .../Marlin_1.1.6/dogm_font_data_ISO10646_SK.h | 151 + .../dogm_font_data_Marlin_symbols.h | 45 + trunk/Arduino/Marlin_1.1.6/duration_t.h | 167 + .../Arduino/Marlin_1.1.6/endstop_interrupts.h | 206 + trunk/Arduino/Marlin_1.1.6/endstops.cpp | 451 + trunk/Arduino/Marlin_1.1.6/endstops.h | 102 + trunk/Arduino/Marlin_1.1.6/enum.h | 189 + .../AlephObjects/TAZ4/Configuration.h | 1720 ++ .../AlephObjects/TAZ4/Configuration_adv.h | 1424 ++ .../AliExpress/CL-260/Configuration.h | 1700 ++ .../AliExpress/CL-260/README.txt | 15 + .../Anet/A6/Configuration.h | 1859 +++ .../Anet/A6/Configuration_adv.h | 1424 ++ .../Anet/A8/Configuration.h | 1708 ++ .../Anet/A8/Configuration_adv.h | 1424 ++ .../BQ/Hephestos/Configuration.h | 1691 ++ .../BQ/Hephestos/Configuration_adv.h | 1424 ++ .../BQ/Hephestos_2/Configuration.h | 1701 ++ .../BQ/Hephestos_2/Configuration_adv.h | 1424 ++ .../BQ/Hephestos_2/README.md | 22 + .../BQ/Hephestos_2/_Bootscreen.h | 103 + .../BQ/WITBOX/Configuration.h | 1691 ++ .../BQ/WITBOX/Configuration_adv.h | 1424 ++ .../Cartesio/Configuration.h | 1699 ++ .../Cartesio/Configuration_adv.h | 1424 ++ .../Cartesio/_Bootscreen.h | 103 + .../Creality/CR-10/Configuration.h | 1712 ++ .../Creality/CR-10/Configuration_adv.h | 1424 ++ .../Creality/CR-10/_Bootscreen.h | 100 + .../Felix/Configuration.h | 1682 ++ .../Felix/Configuration_adv.h | 1424 ++ .../Felix/DUAL/Configuration.h | 1682 ++ .../example_configurations/Felix/README.md | 60 + .../Folger Tech/i3-2020/Configuration.h | 1705 ++ .../Folger Tech/i3-2020/Configuration_adv.h | 1424 ++ .../Geeetech/GT2560/Configuration.h | 1724 ++ .../Geeetech/I3_Pro_X-GT2560/Configuration.h | 1700 ++ .../Infitary/i3-M508/Configuration.h | 1704 ++ .../Infitary/i3-M508/Configuration_adv.h | 1424 ++ .../Malyan/M150/Configuration.h | 1728 ++ .../Malyan/M150/Configuration_adv.h | 1424 ++ .../Malyan/M150/README.md | 3 + .../Malyan/M150/_Bootscreen.h | 104 + .../RepRapWorld/Megatronics/Configuration.h | 1700 ++ .../RigidBot/Configuration.h | 1700 ++ .../RigidBot/Configuration_adv.h | 1424 ++ .../SCARA/Configuration.h | 1712 ++ .../SCARA/Configuration_adv.h | 1424 ++ .../Sanguinololu/Configuration.h | 1731 ++ .../Sanguinololu/Configuration_adv.h | 1391 ++ .../TinyBoy2/Configuration.h | 1756 ++ .../TinyBoy2/Configuration_adv.h | 1424 ++ .../Velleman/K8200/Configuration.h | 1735 ++ .../Velleman/K8200/Configuration_adv.h | 1437 ++ .../Velleman/K8200/README.md | 20 + .../Velleman/K8400/Configuration.h | 1700 ++ .../Velleman/K8400/Configuration_adv.h | 1424 ++ .../Velleman/K8400/Dual-head/Configuration.h | 1700 ++ .../Velleman/K8400/README.md | 15 + .../adafruit/ST7565/Configuration.h | 1700 ++ .../FLSUN/auto_calibrate/Configuration.h | 1828 +++ .../FLSUN/auto_calibrate/Configuration_adv.h | 1426 ++ .../delta/FLSUN/kossel_mini/Configuration.h | 1821 ++ .../FLSUN/kossel_mini/Configuration_adv.h | 1426 ++ .../delta/generic/Configuration.h | 1816 ++ .../delta/generic/Configuration_adv.h | 1426 ++ .../delta/kossel_mini/Configuration.h | 1819 ++ .../delta/kossel_mini/Configuration_adv.h | 1426 ++ .../delta/kossel_pro/Configuration.h | 1819 ++ .../delta/kossel_pro/Configuration_adv.h | 1431 ++ .../delta/kossel_pro/README.md | 5 + .../delta/kossel_xl/Configuration.h | 1828 +++ .../delta/kossel_xl/Configuration_adv.h | 1426 ++ .../delta/kossel_xl/README.md | 21 + .../gCreate/gMax1.5+/Configuration.h | 1714 ++ .../gCreate/gMax1.5+/Configuration_adv.h | 1425 ++ .../gCreate/gMax1.5+/_Bootscreen.h | 108 + .../makibox/Configuration.h | 1703 ++ .../makibox/Configuration_adv.h | 1424 ++ .../tvrrug/Round2/Configuration.h | 1695 ++ .../tvrrug/Round2/Configuration_adv.h | 1424 ++ .../wt150/Configuration.h | 1705 ++ .../wt150/Configuration_adv.h | 1424 ++ trunk/Arduino/Marlin_1.1.6/fastio.h | 320 + trunk/Arduino/Marlin_1.1.6/fastio_1280.h | 1115 ++ trunk/Arduino/Marlin_1.1.6/fastio_1281.h | 720 + trunk/Arduino/Marlin_1.1.6/fastio_168.h | 362 + trunk/Arduino/Marlin_1.1.6/fastio_644.h | 531 + trunk/Arduino/Marlin_1.1.6/fastio_AT90USB.h | 702 + trunk/Arduino/Marlin_1.1.6/gcode.cpp | 282 + trunk/Arduino/Marlin_1.1.6/gcode.h | 323 + .../Marlin_1.1.6/hex_print_routines.cpp | 55 + .../Arduino/Marlin_1.1.6/hex_print_routines.h | 48 + trunk/Arduino/Marlin_1.1.6/language.h | 312 + trunk/Arduino/Marlin_1.1.6/language_an.h | 253 + trunk/Arduino/Marlin_1.1.6/language_bg.h | 143 + trunk/Arduino/Marlin_1.1.6/language_ca.h | 261 + trunk/Arduino/Marlin_1.1.6/language_cn.h | 167 + trunk/Arduino/Marlin_1.1.6/language_cz.h | 349 + trunk/Arduino/Marlin_1.1.6/language_cz_utf8.h | 351 + trunk/Arduino/Marlin_1.1.6/language_da.h | 249 + trunk/Arduino/Marlin_1.1.6/language_de.h | 351 + trunk/Arduino/Marlin_1.1.6/language_el-gr.h | 180 + trunk/Arduino/Marlin_1.1.6/language_el.h | 234 + trunk/Arduino/Marlin_1.1.6/language_en.h | 937 ++ trunk/Arduino/Marlin_1.1.6/language_es.h | 265 + trunk/Arduino/Marlin_1.1.6/language_eu.h | 235 + trunk/Arduino/Marlin_1.1.6/language_fi.h | 160 + trunk/Arduino/Marlin_1.1.6/language_fr.h | 344 + trunk/Arduino/Marlin_1.1.6/language_gl.h | 252 + trunk/Arduino/Marlin_1.1.6/language_hr.h | 248 + trunk/Arduino/Marlin_1.1.6/language_it.h | 346 + trunk/Arduino/Marlin_1.1.6/language_kana.h | 322 + .../Arduino/Marlin_1.1.6/language_kana_utf8.h | 225 + trunk/Arduino/Marlin_1.1.6/language_nl.h | 281 + trunk/Arduino/Marlin_1.1.6/language_pl-DOGM.h | 240 + .../Marlin_1.1.6/language_pl-HD44780.h | 265 + trunk/Arduino/Marlin_1.1.6/language_pl.h | 45 + trunk/Arduino/Marlin_1.1.6/language_pt-br.h | 171 + .../Marlin_1.1.6/language_pt-br_utf8.h | 172 + trunk/Arduino/Marlin_1.1.6/language_pt.h | 177 + trunk/Arduino/Marlin_1.1.6/language_pt_utf8.h | 178 + trunk/Arduino/Marlin_1.1.6/language_ru.h | 336 + trunk/Arduino/Marlin_1.1.6/language_sk_utf8.h | 350 + trunk/Arduino/Marlin_1.1.6/language_test.h | 235 + trunk/Arduino/Marlin_1.1.6/language_tr.h | 269 + trunk/Arduino/Marlin_1.1.6/language_uk.h | 240 + trunk/Arduino/Marlin_1.1.6/language_zh_CN.h | 238 + trunk/Arduino/Marlin_1.1.6/language_zh_TW.h | 238 + .../Marlin_1.1.6/least_squares_fit.cpp | 71 + .../Arduino/Marlin_1.1.6/least_squares_fit.h | 90 + trunk/Arduino/Marlin_1.1.6/macros.h | 211 + .../Marlin_1.1.6/mesh_bed_leveling.cpp | 50 + .../Arduino/Marlin_1.1.6/mesh_bed_leveling.h | 122 + trunk/Arduino/Marlin_1.1.6/nozzle.cpp | 238 + trunk/Arduino/Marlin_1.1.6/nozzle.h | 109 + trunk/Arduino/Marlin_1.1.6/pca9632.cpp | 117 + trunk/Arduino/Marlin_1.1.6/pca9632.h | 36 + trunk/Arduino/Marlin_1.1.6/pins.h | 652 + trunk/Arduino/Marlin_1.1.6/pinsDebug.h | 583 + .../Marlin_1.1.6/pinsDebug_Teensyduino.h | 106 + trunk/Arduino/Marlin_1.1.6/pinsDebug_list.h | 779 + .../Arduino/Marlin_1.1.6/pinsDebug_plus_70.h | 341 + trunk/Arduino/Marlin_1.1.6/pins_3DRAG.h | 163 + trunk/Arduino/Marlin_1.1.6/pins_5DPRINT.h | 132 + trunk/Arduino/Marlin_1.1.6/pins_ANET_10.h | 270 + trunk/Arduino/Marlin_1.1.6/pins_AZTEEG_X1.h | 29 + trunk/Arduino/Marlin_1.1.6/pins_AZTEEG_X3.h | 99 + .../Arduino/Marlin_1.1.6/pins_AZTEEG_X3_PRO.h | 170 + .../Arduino/Marlin_1.1.6/pins_BAM_DICE_DUE.h | 48 + .../Marlin_1.1.6/pins_BQ_ZUM_MEGA_3D.h | 118 + trunk/Arduino/Marlin_1.1.6/pins_BRAINWAVE.h | 123 + .../Arduino/Marlin_1.1.6/pins_BRAINWAVE_PRO.h | 137 + trunk/Arduino/Marlin_1.1.6/pins_CHEAPTRONIC.h | 88 + .../Arduino/Marlin_1.1.6/pins_CHEAPTRONICv2.h | 122 + .../Arduino/Marlin_1.1.6/pins_CNCONTROLS_11.h | 122 + .../Arduino/Marlin_1.1.6/pins_CNCONTROLS_12.h | 127 + trunk/Arduino/Marlin_1.1.6/pins_ELEFU_3.h | 149 + trunk/Arduino/Marlin_1.1.6/pins_FELIX2.h | 63 + .../Marlin_1.1.6/pins_GEN3_MONOLITHIC.h | 101 + trunk/Arduino/Marlin_1.1.6/pins_GEN3_PLUS.h | 101 + trunk/Arduino/Marlin_1.1.6/pins_GEN6.h | 119 + trunk/Arduino/Marlin_1.1.6/pins_GEN6_DELUXE.h | 55 + trunk/Arduino/Marlin_1.1.6/pins_GEN7_12.h | 149 + trunk/Arduino/Marlin_1.1.6/pins_GEN7_13.h | 55 + trunk/Arduino/Marlin_1.1.6/pins_GEN7_14.h | 118 + trunk/Arduino/Marlin_1.1.6/pins_GEN7_CUSTOM.h | 138 + .../Arduino/Marlin_1.1.6/pins_GT2560_REV_A.h | 133 + .../Marlin_1.1.6/pins_GT2560_REV_A_PLUS.h | 36 + trunk/Arduino/Marlin_1.1.6/pins_K8200.h | 32 + trunk/Arduino/Marlin_1.1.6/pins_K8400.h | 73 + trunk/Arduino/Marlin_1.1.6/pins_LEAPFROG.h | 91 + .../Marlin_1.1.6/pins_MEGACONTROLLER.h | 162 + trunk/Arduino/Marlin_1.1.6/pins_MEGATRONICS.h | 130 + .../Arduino/Marlin_1.1.6/pins_MEGATRONICS_2.h | 145 + .../Arduino/Marlin_1.1.6/pins_MEGATRONICS_3.h | 196 + trunk/Arduino/Marlin_1.1.6/pins_MELZI.h | 29 + .../Marlin_1.1.6/pins_MELZI_CREALITY.h | 107 + .../Arduino/Marlin_1.1.6/pins_MELZI_MAKR3D.h | 29 + .../Marlin_1.1.6/pins_MIGHTYBOARD_REVE.h | 333 + trunk/Arduino/Marlin_1.1.6/pins_MINIRAMBO.h | 160 + trunk/Arduino/Marlin_1.1.6/pins_MINITRONICS.h | 144 + trunk/Arduino/Marlin_1.1.6/pins_MKS_13.h | 144 + trunk/Arduino/Marlin_1.1.6/pins_MKS_BASE.h | 50 + trunk/Arduino/Marlin_1.1.6/pins_OMCA.h | 148 + trunk/Arduino/Marlin_1.1.6/pins_OMCA_A.h | 135 + trunk/Arduino/Marlin_1.1.6/pins_PRINTRBOARD.h | 177 + .../Marlin_1.1.6/pins_PRINTRBOARD_REVF.h | 219 + trunk/Arduino/Marlin_1.1.6/pins_RAMBO.h | 228 + trunk/Arduino/Marlin_1.1.6/pins_RAMPS.h | 485 + trunk/Arduino/Marlin_1.1.6/pins_RAMPS_13.h | 41 + trunk/Arduino/Marlin_1.1.6/pins_RAMPS_OLD.h | 111 + trunk/Arduino/Marlin_1.1.6/pins_RIGIDBOARD.h | 133 + .../Arduino/Marlin_1.1.6/pins_RIGIDBOARD_V2.h | 52 + trunk/Arduino/Marlin_1.1.6/pins_RUMBA.h | 158 + .../Marlin_1.1.6/pins_SAINSMART_2IN1.h | 41 + .../Marlin_1.1.6/pins_SANGUINOLOLU_11.h | 310 + .../Marlin_1.1.6/pins_SANGUINOLOLU_12.h | 41 + trunk/Arduino/Marlin_1.1.6/pins_SAV_MKI.h | 184 + trunk/Arduino/Marlin_1.1.6/pins_SCOOVO_X9H.h | 158 + trunk/Arduino/Marlin_1.1.6/pins_SETHI.h | 123 + trunk/Arduino/Marlin_1.1.6/pins_STB_11.h | 28 + trunk/Arduino/Marlin_1.1.6/pins_TEENSY2.h | 184 + trunk/Arduino/Marlin_1.1.6/pins_TEENSYLU.h | 164 + trunk/Arduino/Marlin_1.1.6/pins_ULTIMAIN_2.h | 135 + trunk/Arduino/Marlin_1.1.6/pins_ULTIMAKER.h | 164 + .../Arduino/Marlin_1.1.6/pins_ULTIMAKER_OLD.h | 283 + trunk/Arduino/Marlin_1.1.6/pins_ZRIB_V20.h | 39 + trunk/Arduino/Marlin_1.1.6/planner.cpp | 1535 ++ trunk/Arduino/Marlin_1.1.6/planner.h | 473 + trunk/Arduino/Marlin_1.1.6/planner_bezier.cpp | 194 + trunk/Arduino/Marlin_1.1.6/planner_bezier.h | 43 + trunk/Arduino/Marlin_1.1.6/point_t.h | 77 + trunk/Arduino/Marlin_1.1.6/printcounter.cpp | 234 + trunk/Arduino/Marlin_1.1.6/printcounter.h | 175 + trunk/Arduino/Marlin_1.1.6/serial.cpp | 36 + trunk/Arduino/Marlin_1.1.6/serial.h | 101 + trunk/Arduino/Marlin_1.1.6/servo.cpp | 322 + trunk/Arduino/Marlin_1.1.6/servo.h | 161 + trunk/Arduino/Marlin_1.1.6/softspi.h | 770 + .../Arduino/Marlin_1.1.6/speed_lookuptable.h | 174 + trunk/Arduino/Marlin_1.1.6/spi.h | 57 + trunk/Arduino/Marlin_1.1.6/stepper.cpp | 1626 ++ trunk/Arduino/Marlin_1.1.6/stepper.h | 374 + trunk/Arduino/Marlin_1.1.6/stepper_dac.cpp | 125 + trunk/Arduino/Marlin_1.1.6/stepper_dac.h | 57 + .../Marlin_1.1.6/stepper_indirection.cpp | 338 + .../Marlin_1.1.6/stepper_indirection.h | 485 + trunk/Arduino/Marlin_1.1.6/stopwatch.cpp | 106 + trunk/Arduino/Marlin_1.1.6/stopwatch.h | 117 + trunk/Arduino/Marlin_1.1.6/temperature.cpp | 2133 +++ trunk/Arduino/Marlin_1.1.6/temperature.h | 578 + trunk/Arduino/Marlin_1.1.6/thermistornames.h | 97 + .../Arduino/Marlin_1.1.6/thermistortable_1.h | 89 + .../Arduino/Marlin_1.1.6/thermistortable_10.h | 56 + .../Marlin_1.1.6/thermistortable_1010.h | 38 + .../Marlin_1.1.6/thermistortable_1047.h | 33 + .../Arduino/Marlin_1.1.6/thermistortable_11.h | 75 + .../Marlin_1.1.6/thermistortable_110.h | 33 + .../Arduino/Marlin_1.1.6/thermistortable_12.h | 55 + .../Arduino/Marlin_1.1.6/thermistortable_13.h | 48 + .../Marlin_1.1.6/thermistortable_147.h | 33 + .../Arduino/Marlin_1.1.6/thermistortable_2.h | 61 + .../Arduino/Marlin_1.1.6/thermistortable_20.h | 100 + .../Arduino/Marlin_1.1.6/thermistortable_3.h | 53 + .../Arduino/Marlin_1.1.6/thermistortable_4.h | 45 + .../Arduino/Marlin_1.1.6/thermistortable_5.h | 60 + .../Arduino/Marlin_1.1.6/thermistortable_51.h | 81 + .../Arduino/Marlin_1.1.6/thermistortable_52.h | 60 + .../Arduino/Marlin_1.1.6/thermistortable_55.h | 60 + .../Arduino/Marlin_1.1.6/thermistortable_6.h | 63 + .../Arduino/Marlin_1.1.6/thermistortable_60.h | 105 + .../Arduino/Marlin_1.1.6/thermistortable_66.h | 52 + .../Arduino/Marlin_1.1.6/thermistortable_7.h | 83 + .../Arduino/Marlin_1.1.6/thermistortable_70.h | 86 + .../Arduino/Marlin_1.1.6/thermistortable_71.h | 171 + .../Arduino/Marlin_1.1.6/thermistortable_75.h | 69 + .../Arduino/Marlin_1.1.6/thermistortable_8.h | 45 + .../Arduino/Marlin_1.1.6/thermistortable_9.h | 56 + .../Marlin_1.1.6/thermistortable_998.h | 32 + .../Marlin_1.1.6/thermistortable_999.h | 32 + trunk/Arduino/Marlin_1.1.6/thermistortables.h | 248 + trunk/Arduino/Marlin_1.1.6/twibus.cpp | 204 + trunk/Arduino/Marlin_1.1.6/twibus.h | 242 + trunk/Arduino/Marlin_1.1.6/types.h | 28 + trunk/Arduino/Marlin_1.1.6/ubl.cpp | 196 + trunk/Arduino/Marlin_1.1.6/ubl.h | 412 + trunk/Arduino/Marlin_1.1.6/ubl_G29.cpp | 1859 +++ trunk/Arduino/Marlin_1.1.6/ubl_motion.cpp | 740 + trunk/Arduino/Marlin_1.1.6/ultralcd.cpp | 5022 ++++++ trunk/Arduino/Marlin_1.1.6/ultralcd.h | 204 + .../Arduino/Marlin_1.1.6/ultralcd_impl_DOGM.h | 1044 ++ .../Marlin_1.1.6/ultralcd_impl_HD44780.h | 1514 ++ .../ultralcd_st7565_u8glib_VIKI.h | 253 + .../Marlin_1.1.6/ultralcd_st7920_u8glib_rrd.h | 186 + trunk/Arduino/Marlin_1.1.6/utf_mapper.h | 671 + trunk/Arduino/Marlin_1.1.6/utility.cpp | 257 + trunk/Arduino/Marlin_1.1.6/utility.h | 86 + trunk/Arduino/Marlin_1.1.6/vector_3.cpp | 160 + trunk/Arduino/Marlin_1.1.6/vector_3.h | 83 + trunk/Arduino/Marlin_1.1.6/watchdog.cpp | 56 + trunk/Arduino/Marlin_1.1.6/watchdog.h | 36 + .../Marlin_K8600_1.1.0RC7/Conditionals.h | 27 + .../Marlin_K8600_1.1.0RC7/Conditionals_LCD.h | 319 + .../Marlin_K8600_1.1.0RC7/Conditionals_post.h | 663 + .../Marlin_K8600_1.1.0RC7/Configuration.h | 1327 ++ .../Marlin_K8600_1.1.0RC7/Configuration_adv.h | 799 + .../M100_Free_Mem_Chk.cpp | 248 + trunk/Arduino/Marlin_K8600_1.1.0RC7/Makefile | 521 + trunk/Arduino/Marlin_K8600_1.1.0RC7/Marlin.h | 401 + .../Marlin_K8600_1.1.0RC7/MarlinConfig.h | 41 + .../Marlin_K8600_1.1.0RC7/MarlinSerial.cpp | 539 + .../Marlin_K8600_1.1.0RC7/MarlinSerial.h | 181 + .../Marlin_K8600_1.1.0RC7.ino | 80 + .../Marlin_K8600_1.1.0RC7/Marlin_main.cpp | 8784 ++++++++++ .../Marlin_K8600_1.1.0RC7/SanityCheck.h | 736 + .../Arduino/Marlin_K8600_1.1.0RC7/Sd2Card.cpp | 719 + trunk/Arduino/Marlin_K8600_1.1.0RC7/Sd2Card.h | 251 + .../Marlin_K8600_1.1.0RC7/SdBaseFile.cpp | 1826 +++ .../Marlin_K8600_1.1.0RC7/SdBaseFile.h | 492 + .../Marlin_K8600_1.1.0RC7/SdFatConfig.h | 134 + .../Marlin_K8600_1.1.0RC7/SdFatStructs.h | 655 + .../Marlin_K8600_1.1.0RC7/SdFatUtil.cpp | 91 + .../Arduino/Marlin_K8600_1.1.0RC7/SdFatUtil.h | 57 + .../Arduino/Marlin_K8600_1.1.0RC7/SdFile.cpp | 102 + trunk/Arduino/Marlin_K8600_1.1.0RC7/SdFile.h | 63 + trunk/Arduino/Marlin_K8600_1.1.0RC7/SdInfo.h | 289 + .../Marlin_K8600_1.1.0RC7/SdVolume.cpp | 420 + .../Arduino/Marlin_K8600_1.1.0RC7/SdVolume.h | 227 + trunk/Arduino/Marlin_K8600_1.1.0RC7/Version.h | 92 + .../Arduino/Marlin_K8600_1.1.0RC7/blinkm.cpp | 46 + trunk/Arduino/Marlin_K8600_1.1.0RC7/blinkm.h | 31 + trunk/Arduino/Marlin_K8600_1.1.0RC7/boards.h | 102 + trunk/Arduino/Marlin_K8600_1.1.0RC7/buzzer.h | 145 + .../Marlin_K8600_1.1.0RC7/cardreader.cpp | 624 + .../Marlin_K8600_1.1.0RC7/cardreader.h | 129 + .../Marlin_K8600_1.1.0RC7/circularqueue.h | 145 + .../configuration_store.cpp | 994 ++ .../configuration_store.h | 44 + .../Marlin_K8600_1.1.0RC7/dac_mcp4728.cpp | 138 + .../Marlin_K8600_1.1.0RC7/dac_mcp4728.h | 65 + .../Marlin_K8600_1.1.0RC7/digipot_mcp4451.cpp | 79 + .../Marlin_K8600_1.1.0RC7/dogm_bitmaps.h | 422 + .../dogm_font_data_6x9_marlin.h | 180 + .../dogm_font_data_HD44780_C.h | 194 + .../dogm_font_data_HD44780_J.h | 192 + .../dogm_font_data_HD44780_W.h | 226 + .../dogm_font_data_ISO10646_1.h | 198 + .../dogm_font_data_ISO10646_5_Cyrillic.h | 196 + .../dogm_font_data_ISO10646_CN.h | 293 + .../dogm_font_data_ISO10646_Greek.h | 206 + .../dogm_font_data_ISO10646_Kana.h | 192 + .../dogm_font_data_Marlin_symbols.h | 45 + .../Marlin_K8600_1.1.0RC7/duration_t.h | 155 + .../Marlin_K8600_1.1.0RC7/endstops.cpp | 378 + .../Arduino/Marlin_K8600_1.1.0RC7/endstops.h | 95 + trunk/Arduino/Marlin_K8600_1.1.0RC7/enum.h | 193 + trunk/Arduino/Marlin_K8600_1.1.0RC7/fastio.h | 4051 +++++ .../Arduino/Marlin_K8600_1.1.0RC7/language.h | 244 + .../Marlin_K8600_1.1.0RC7/language_an.h | 157 + .../Marlin_K8600_1.1.0RC7/language_bg.h | 159 + .../Marlin_K8600_1.1.0RC7/language_ca.h | 158 + .../Marlin_K8600_1.1.0RC7/language_cn.h | 162 + .../Marlin_K8600_1.1.0RC7/language_cz.h | 262 + .../Marlin_K8600_1.1.0RC7/language_da.h | 197 + .../Marlin_K8600_1.1.0RC7/language_de.h | 227 + .../Marlin_K8600_1.1.0RC7/language_el-gr.h | 198 + .../Marlin_K8600_1.1.0RC7/language_el.h | 254 + .../Marlin_K8600_1.1.0RC7/language_en.h | 738 + .../Marlin_K8600_1.1.0RC7/language_es.h | 195 + .../Marlin_K8600_1.1.0RC7/language_eu.h | 157 + .../Marlin_K8600_1.1.0RC7/language_fi.h | 158 + .../Marlin_K8600_1.1.0RC7/language_fr.h | 171 + .../Marlin_K8600_1.1.0RC7/language_gl.h | 259 + .../Marlin_K8600_1.1.0RC7/language_hr.h | 197 + .../Marlin_K8600_1.1.0RC7/language_it.h | 238 + .../Marlin_K8600_1.1.0RC7/language_kana.h | 292 + .../language_kana_utf8.h | 226 + .../Marlin_K8600_1.1.0RC7/language_nl.h | 170 + .../Marlin_K8600_1.1.0RC7/language_pl.h | 193 + .../Marlin_K8600_1.1.0RC7/language_pt-br.h | 170 + .../language_pt-br_utf8.h | 170 + .../Marlin_K8600_1.1.0RC7/language_pt.h | 180 + .../Marlin_K8600_1.1.0RC7/language_pt_utf8.h | 180 + .../Marlin_K8600_1.1.0RC7/language_ru.h | 169 + .../Marlin_K8600_1.1.0RC7/language_test.h | 237 + trunk/Arduino/Marlin_K8600_1.1.0RC7/macros.h | 121 + .../mesh_bed_leveling.cpp | 37 + .../Marlin_K8600_1.1.0RC7/mesh_bed_leveling.h | 105 + trunk/Arduino/Marlin_K8600_1.1.0RC7/nozzle.h | 195 + trunk/Arduino/Marlin_K8600_1.1.0RC7/pins.h | 476 + .../Marlin_K8600_1.1.0RC7/pins_3DRAG.h | 95 + .../Marlin_K8600_1.1.0RC7/pins_5DPRINT.h | 79 + trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_99.h | 53 + .../Arduino/Marlin_K8600_1.1.0RC7/pins_A4JP.h | 141 + .../Marlin_K8600_1.1.0RC7/pins_AZTEEG_X1.h | 30 + .../Marlin_K8600_1.1.0RC7/pins_AZTEEG_X3.h | 56 + .../pins_AZTEEG_X3_PRO.h | 112 + .../Marlin_K8600_1.1.0RC7/pins_BAM_DICE_DUE.h | 38 + .../pins_BQ_ZUM_MEGA_3D.h | 69 + .../Marlin_K8600_1.1.0RC7/pins_BRAINWAVE.h | 66 + .../pins_BRAINWAVE_PRO.h | 77 + .../Marlin_K8600_1.1.0RC7/pins_CHEAPTRONIC.h | 87 + .../pins_CNCONTROLS_11.h | 101 + .../pins_CNCONTROLS_12.h | 105 + .../Marlin_K8600_1.1.0RC7/pins_ELEFU_3.h | 125 + .../Marlin_K8600_1.1.0RC7/pins_FELIX2.h | 47 + .../pins_GEN3_MONOLITHIC.h | 69 + .../Marlin_K8600_1.1.0RC7/pins_GEN3_PLUS.h | 60 + .../Arduino/Marlin_K8600_1.1.0RC7/pins_GEN6.h | 75 + .../Marlin_K8600_1.1.0RC7/pins_GEN6_DELUXE.h | 29 + .../Marlin_K8600_1.1.0RC7/pins_GEN7_12.h | 87 + .../Marlin_K8600_1.1.0RC7/pins_GEN7_13.h | 30 + .../Marlin_K8600_1.1.0RC7/pins_GEN7_14.h | 71 + .../Marlin_K8600_1.1.0RC7/pins_GEN7_CUSTOM.h | 90 + .../Marlin_K8600_1.1.0RC7/pins_K8200.h | 32 + .../Marlin_K8600_1.1.0RC7/pins_K8400.h | 52 + .../Marlin_K8600_1.1.0RC7/pins_K8600.h | 111 + .../Marlin_K8600_1.1.0RC7/pins_LEAPFROG.h | 73 + .../pins_MEGACONTROLLER.h | 123 + .../Marlin_K8600_1.1.0RC7/pins_MEGATRONICS.h | 97 + .../pins_MEGATRONICS_2.h | 104 + .../pins_MEGATRONICS_3.h | 147 + .../Marlin_K8600_1.1.0RC7/pins_MELZI.h | 34 + .../Marlin_K8600_1.1.0RC7/pins_MELZI_MAKR3D.h | 34 + .../Marlin_K8600_1.1.0RC7/pins_MINIRAMBO.h | 116 + .../Marlin_K8600_1.1.0RC7/pins_MINITRONICS.h | 109 + .../Marlin_K8600_1.1.0RC7/pins_MKS_13.h | 128 + .../Marlin_K8600_1.1.0RC7/pins_MKS_BASE.h | 36 + .../Arduino/Marlin_K8600_1.1.0RC7/pins_OMCA.h | 107 + .../Marlin_K8600_1.1.0RC7/pins_OMCA_A.h | 92 + .../Marlin_K8600_1.1.0RC7/pins_PRINTRBOARD.h | 136 + .../pins_PRINTRBOARD_REVF.h | 137 + .../Marlin_K8600_1.1.0RC7/pins_RAMBO.h | 181 + .../Marlin_K8600_1.1.0RC7/pins_RAMPS.h | 344 + .../Marlin_K8600_1.1.0RC7/pins_RAMPS_13.h | 41 + .../Marlin_K8600_1.1.0RC7/pins_RAMPS_14.h | 296 + .../Marlin_K8600_1.1.0RC7/pins_RAMPS_OLD.h | 80 + .../Marlin_K8600_1.1.0RC7/pins_RIGIDBOARD.h | 117 + .../pins_RIGIDBOARD_V2.h | 43 + .../Marlin_K8600_1.1.0RC7/pins_RUMBA.h | 126 + .../pins_SAINSMART_2IN1.h | 38 + .../pins_SANGUINOLOLU_11.h | 191 + .../pins_SANGUINOLOLU_12.h | 42 + .../Marlin_K8600_1.1.0RC7/pins_SAV_MKI.h | 119 + .../Marlin_K8600_1.1.0RC7/pins_SETHI.h | 86 + .../Marlin_K8600_1.1.0RC7/pins_STB_11.h | 34 + .../Marlin_K8600_1.1.0RC7/pins_TEENSY2.h | 122 + .../Marlin_K8600_1.1.0RC7/pins_TEENSYLU.h | 93 + .../Marlin_K8600_1.1.0RC7/pins_ULTIMAIN_2.h | 94 + .../Marlin_K8600_1.1.0RC7/pins_ULTIMAKER.h | 119 + .../pins_ULTIMAKER_OLD.h | 74 + .../Arduino/Marlin_K8600_1.1.0RC7/planner.cpp | 1205 ++ trunk/Arduino/Marlin_K8600_1.1.0RC7/planner.h | 335 + .../Marlin_K8600_1.1.0RC7/planner_bezier.cpp | 203 + .../Marlin_K8600_1.1.0RC7/planner_bezier.h | 43 + trunk/Arduino/Marlin_K8600_1.1.0RC7/point_t.h | 77 + .../Marlin_K8600_1.1.0RC7/printcounter.cpp | 233 + .../Marlin_K8600_1.1.0RC7/printcounter.h | 175 + .../Marlin_K8600_1.1.0RC7/qr_solve.cpp | 1591 ++ .../Arduino/Marlin_K8600_1.1.0RC7/qr_solve.h | 44 + trunk/Arduino/Marlin_K8600_1.1.0RC7/servo.cpp | 320 + trunk/Arduino/Marlin_K8600_1.1.0RC7/servo.h | 161 + .../Marlin_K8600_1.1.0RC7/speed_lookuptable.h | 174 + .../Arduino/Marlin_K8600_1.1.0RC7/stepper.cpp | 1250 ++ trunk/Arduino/Marlin_K8600_1.1.0RC7/stepper.h | 380 + .../Marlin_K8600_1.1.0RC7/stepper_dac.cpp | 114 + .../Marlin_K8600_1.1.0RC7/stepper_dac.h | 55 + .../stepper_indirection.cpp | 245 + .../stepper_indirection.h | 395 + .../Marlin_K8600_1.1.0RC7/stopwatch.cpp | 106 + .../Arduino/Marlin_K8600_1.1.0RC7/stopwatch.h | 117 + .../Marlin_K8600_1.1.0RC7/temperature.cpp | 1837 +++ .../Marlin_K8600_1.1.0RC7/temperature.h | 465 + .../Marlin_K8600_1.1.0RC7/thermistornames.h | 95 + .../Marlin_K8600_1.1.0RC7/thermistortables.h | 1323 ++ .../Arduino/Marlin_K8600_1.1.0RC7/twibus.cpp | 118 + trunk/Arduino/Marlin_K8600_1.1.0RC7/twibus.h | 137 + trunk/Arduino/Marlin_K8600_1.1.0RC7/types.h | 28 + .../Marlin_K8600_1.1.0RC7/ultralcd.cpp | 3305 ++++ .../Arduino/Marlin_K8600_1.1.0RC7/ultralcd.h | 195 + .../ultralcd_impl_DOGM.h | 634 + .../ultralcd_impl_HD44780.h | 1115 ++ .../ultralcd_st7920_u8glib_rrd.h | 191 + .../Marlin_K8600_1.1.0RC7/utf_mapper.h | 358 + .../Arduino/Marlin_K8600_1.1.0RC7/utility.cpp | 34 + trunk/Arduino/Marlin_K8600_1.1.0RC7/utility.h | 28 + .../Marlin_K8600_1.1.0RC7/vector_3.cpp | 160 + .../Arduino/Marlin_K8600_1.1.0RC7/vector_3.h | 82 + .../Marlin_K8600_1.1.0RC7/watchdog.cpp | 56 + .../Arduino/Marlin_K8600_1.1.0RC7/watchdog.h | 36 + .../Arduino/Marlin_K8600_Original/eeprom.bin | Bin 0 -> 4096 bytes .../Arduino/Marlin_K8600_Original/eeprom.hex | 1 + trunk/Arduino/Marlin_K8600_Original/efuse.bin | 1 + trunk/Arduino/Marlin_K8600_Original/efuse.hex | 1 + trunk/Arduino/Marlin_K8600_Original/flash.bin | 35 + trunk/Arduino/Marlin_K8600_Original/flash.hex | 1 + trunk/Arduino/Marlin_K8600_Original/hfuse.bin | 1 + trunk/Arduino/Marlin_K8600_Original/hfuse.hex | 1 + trunk/Arduino/Marlin_K8600_Original/lfuse.bin | 1 + trunk/Arduino/Marlin_K8600_Original/lfuse.hex | 1 + .../micronucleus-1.11-ledpb1.hex | 119 + .../micronucleus-1.11.hex | 118 + trunk/Arduino/Repetier_0.92.9/BedLeveling.cpp | 708 + trunk/Arduino/Repetier_0.92.9/Commands.cpp | 2463 +++ trunk/Arduino/Repetier_0.92.9/Commands.h | 53 + .../Arduino/Repetier_0.92.9/Communication.cpp | 637 + trunk/Arduino/Repetier_0.92.9/Communication.h | 479 + trunk/Arduino/Repetier_0.92.9/Configuration.h | 1088 ++ trunk/Arduino/Repetier_0.92.9/Drivers.cpp | 215 + trunk/Arduino/Repetier_0.92.9/Drivers.h | 153 + trunk/Arduino/Repetier_0.92.9/Eeprom.cpp | 1151 ++ trunk/Arduino/Repetier_0.92.9/Eeprom.h | 574 + trunk/Arduino/Repetier_0.92.9/Events.h | 90 + trunk/Arduino/Repetier_0.92.9/Extruder.cpp | 2738 ++++ trunk/Arduino/Repetier_0.92.9/Extruder.h | 319 + trunk/Arduino/Repetier_0.92.9/FatStructs.h | 418 + trunk/Arduino/Repetier_0.92.9/HAL.cpp | 1470 ++ trunk/Arduino/Repetier_0.92.9/HAL.h | 770 + trunk/Arduino/Repetier_0.92.9/Printer.cpp | 2477 +++ trunk/Arduino/Repetier_0.92.9/Printer.h | 1171 ++ trunk/Arduino/Repetier_0.92.9/README.txt | 40 + trunk/Arduino/Repetier_0.92.9/Repetier.h | 1011 ++ .../Repetier_0.92.9/Repetier_0.92.9.ino | 174 + trunk/Arduino/Repetier_0.92.9/SDCard.cpp | 651 + trunk/Arduino/Repetier_0.92.9/SdFat.cpp | 4494 +++++ trunk/Arduino/Repetier_0.92.9/SdFat.h | 2326 +++ trunk/Arduino/Repetier_0.92.9/fastio.h | 3737 +++++ trunk/Arduino/Repetier_0.92.9/gcode.cpp | 1243 ++ trunk/Arduino/Repetier_0.92.9/gcode.h | 255 + trunk/Arduino/Repetier_0.92.9/logo.h | 46 + trunk/Arduino/Repetier_0.92.9/makefile | 140 + trunk/Arduino/Repetier_0.92.9/motion.cpp | 2914 ++++ trunk/Arduino/Repetier_0.92.9/motion.h | 719 + trunk/Arduino/Repetier_0.92.9/pins.h | 2860 ++++ trunk/Arduino/Repetier_0.92.9/u8glib_ex.h | 10713 ++++++++++++ trunk/Arduino/Repetier_0.92.9/ui.cpp | 3837 +++++ trunk/Arduino/Repetier_0.92.9/ui.h | 2139 +++ trunk/Arduino/Repetier_0.92.9/uiconfig.h | 455 + trunk/Arduino/Repetier_0.92.9/uilang.cpp | 6635 ++++++++ trunk/Arduino/Repetier_0.92.9/uilang.h | 3893 +++++ trunk/Arduino/Repetier_0.92.9/uimenu.h | 1097 ++ .../EEprom/EEPROM Storage Cad Artwork.oxps | Bin 0 -> 32264 bytes .../EEprom/EEPROM Storage Card Schematic.png | Bin 0 -> 35067 bytes .../EEPROM Storage Card (64Kbit)-B_Cu.gbl | 1151 ++ ...EEPROM Storage Card (64Kbit)-Edge_Cuts.gbr | 24 + .../EEPROM Storage Card (64Kbit)-F_SilkS.gto | 493 + .../Gerber/EEPROM Storage Card (64Kbit).txt | 37 + ...BASIC Computer • Hackaday Projects.website | 17 + ...ingle Chip Computer - Instructable.website | 15 + ... Computer - TinyBasicPlus · GitHub.website | 17 + .../Single Chip Computer.pdf | Bin 0 -> 60258 bytes .../Single_Chip_Computer.ino | 2178 +++ .../Single_Chip_Computer_1.14.hex | 1406 ++ .../Single_Chip_Computer_1.15.ino.txt | 2278 +++ .../Single_chip_Computer_1.14.ino.txt | 2171 +++ .../Single_Chip_VIC20/Single_Chip_VIC20.ino | 179 + trunk/Arduino/Single_Chip_VIC20/cpu.c | 1384 ++ .../Single_Chip_VIC20/lightbox_NANO20.jpg | Bin 0 -> 35053 bytes trunk/Arduino/esp32-cam-webserver/.gitignore | 7 + trunk/Arduino/esp32-cam-webserver/.travis.yml | 42 + trunk/Arduino/esp32-cam-webserver/API.md | 89 + .../esp32-cam-webserver/CONTRIBUTING.md | 49 + .../Docs/board-selection-small.png | Bin 0 -> 223751 bytes .../Docs/favicon-16x16.png | Bin 0 -> 629 bytes .../Docs/favicon-32x32.png | Bin 0 -> 1051 bytes .../Docs/favicon-README.md | 21 + .../esp32-cam-webserver/Docs/favicon.ico | Bin 0 -> 4286 bytes .../Docs/headline-image.png | Bin 0 -> 100079 bytes .../esp32-cam-webserver/Docs/hookup.png | Bin 0 -> 60487 bytes .../Docs/linearled/README.md | 156 + .../Docs/linearled/linearled.c | 29 + .../esp32-cam-webserver/Docs/logo-big.png | Bin 0 -> 37687 bytes .../Arduino/esp32-cam-webserver/Docs/logo.png | Bin 0 -> 6089 bytes .../Arduino/esp32-cam-webserver/Docs/logo.svg | 131 + .../Docs/mygodsitsfullofcats.png | Bin 0 -> 632096 bytes .../esp32-cam-webserver/Docs/screenshot.png | Bin 0 -> 361102 bytes .../Docs/webcams.programmer.jpg | Bin 0 -> 79439 bytes trunk/Arduino/esp32-cam-webserver/LICENSE | 504 + trunk/Arduino/esp32-cam-webserver/README.md | 111 + .../Arduino/esp32-cam-webserver/app_httpd.cpp | 1102 ++ .../Arduino/esp32-cam-webserver/camera_pins.h | 219 + trunk/Arduino/esp32-cam-webserver/css.h | 366 + .../esp32-cam-webserver.ino | 663 + .../Arduino/esp32-cam-webserver/index_other.h | 490 + .../esp32-cam-webserver/index_ov2640.h | 651 + .../esp32-cam-webserver/index_ov3660.h | 653 + .../esp32-cam-webserver/myconfig.sample.h | 164 + .../esp32-cam-webserver/platformio.ini | 17 + .../esp32-cam-webserver/src/favicons.h | 520 + .../esp32-cam-webserver/src/jsonlib/README.md | 5 + .../src/jsonlib/jsonlib-LICENSE | 201 + .../src/jsonlib/jsonlib.cpp | 120 + .../esp32-cam-webserver/src/jsonlib/jsonlib.h | 15 + trunk/Arduino/esp32-cam-webserver/src/logo.h | 137 + .../esp32-cam-webserver/src/parsebytes.cpp | 16 + .../esp32-cam-webserver/src/parsebytes.h | 1 + .../Arduino/esp32-cam-webserver/src/version.h | 3 + trunk/Arduino/esp32-cam-webserver/storage.cpp | 202 + trunk/Arduino/esp32-cam-webserver/storage.h | 17 + 901 files changed, 399824 insertions(+) create mode 100644 trunk/Arduino/ArduinoFDC/ Library for using an Arduino as a floppy disk controller.desktop create mode 100644 trunk/Arduino/ArduinoFDC/ArduinoFDC.cpp create mode 100644 trunk/Arduino/ArduinoFDC/ArduinoFDC.h create mode 100644 trunk/Arduino/ArduinoFDC/ArduinoFDC.ino create mode 100644 trunk/Arduino/ArduinoFDC/GitHub - dhansel-ArduinoFDC- Library for using an Arduino as a floppy disk controller.url create mode 100644 trunk/Arduino/ArduinoFDC/LICENSE create mode 100644 trunk/Arduino/ArduinoFDC/README.md create mode 100644 trunk/Arduino/ArduinoFDC/XModem.cpp create mode 100644 trunk/Arduino/ArduinoFDC/XModem.h create mode 100644 trunk/Arduino/ArduinoFDC/diskio.cpp create mode 100644 trunk/Arduino/ArduinoFDC/diskio.h create mode 100644 trunk/Arduino/ArduinoFDC/ff.c create mode 100644 trunk/Arduino/ArduinoFDC/ff.h create mode 100644 trunk/Arduino/ArduinoFDC/ffconf.h create mode 100644 trunk/Arduino/ArduinoFDC/images/ArduDOS.png create mode 100644 trunk/Arduino/ArduinoFDC/images/setup.jpg create mode 100644 trunk/Arduino/CameraWebServer/CameraWebServer.ino create mode 100644 trunk/Arduino/CameraWebServer/app_httpd.cpp create mode 100644 trunk/Arduino/CameraWebServer/camera_index.h create mode 100644 trunk/Arduino/CameraWebServer/camera_pins.h create mode 100644 trunk/Arduino/FloppyDriveController.sketch/Amiga Floppy Disk Reader and Writer - Amiga Arduino Floppy Disk Reader and Writer.desktop create mode 100644 trunk/Arduino/FloppyDriveController.sketch/Arduino Pro Mini Amiga Disk Reader_Writer - Amiga Arduino Floppy Disk Reader and Writer.desktop create mode 100644 trunk/Arduino/FloppyDriveController.sketch/ArduinoFloppyReader.exe create mode 100644 trunk/Arduino/FloppyDriveController.sketch/ArduinoFloppyReaderWin.exe create mode 100644 trunk/Arduino/FloppyDriveController.sketch/FloppyDriveController.sketch.ino create mode 100644 trunk/Arduino/FloppyDriveController.sketch/LICENSE.txt create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.4/AmigaFloppyDiskReader-10.jpg create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.4/ArduinoFloppyReader.exe create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.4/ArduinoFloppyReaderWin.exe create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.4/FloppyDriveController.sketch/FloppyDriveController.sketch.ino create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.4/FloppyDriveController.sketch/LICENSE.txt create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.4/LICENSE.txt create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.4/Mingos Commodorepage.desktop create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.4/encryptable create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.4/readme.txt create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/.github/FUNDING.yml create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/.gitattributes create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/.gitignore create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReader.sln create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReader/ArduinoFloppyReader.vcxproj create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReader/ArduinoFloppyReader.vcxproj.filters create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReader/ArduinoReaderWriter create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReader/Main.cpp create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReader/makefile create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReader/makefile.bak create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReader/readme.txt create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReader/targetver.h create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/ArduinoFloppyReaderWin.aps create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/ArduinoFloppyReaderWin.cpp create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/ArduinoFloppyReaderWin.h create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/ArduinoFloppyReaderWin.rc create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/ArduinoFloppyReaderWin.vcxproj create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/ArduinoFloppyReaderWin.vcxproj.filters create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/ArduinoFloppyReaderWinDlg.cpp create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/ArduinoFloppyReaderWinDlg.h create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/ReadMe.txt create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/res/ArduinoFloppyReaderWin.ico create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/res/ArduinoFloppyReaderWin.rc2 create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/res/fin.bmp create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/res/fin2.bmp create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/res/finpartial.bmp create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/res/finpartial2.bmp create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/res/floppy.bmp create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/res/scp.bmp create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/res/sfx.wav create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/resource.h create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/stdafx.cpp create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/stdafx.h create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/targetver.h create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/LICENSE.txt create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/lib/ADFWriter.cpp create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/lib/ADFWriter.h create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/lib/ArduinoInterface.cpp create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/lib/ArduinoInterface.h create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/lib/RotationExtractor.cpp create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/lib/RotationExtractor.h create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/lib/SerialIO.cpp create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/lib/SerialIO.h create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/FloppyDriveController.sketch/FloppyDriveController.sketch.ino create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/FloppyDriveController.sketch/LICENSE.txt create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/LICENSE.txt create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/readme.md create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyReader.exe create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyReaderWin.exe create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.6/FloppyDriveController.sketch/FloppyDriveController.sketch.ino create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.6/FloppyDriveController.sketch/LICENSE.txt create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.6/LICENSE.txt create mode 100644 trunk/Arduino/FloppyDriveController.sketch/V2.6/readme.txt create mode 100644 trunk/Arduino/FloppyDriveController.sketch/promini_writer.gif create mode 100644 trunk/Arduino/FloppyDriveController.sketch/readme.txt create mode 100644 trunk/Arduino/GRBL_1.1f/GRBL.ino create mode 100644 trunk/Arduino/GRBL_1.1f/config.h create mode 100644 trunk/Arduino/GRBL_1.1f/coolant_control.c create mode 100644 trunk/Arduino/GRBL_1.1f/coolant_control.h create mode 100644 trunk/Arduino/GRBL_1.1f/cpu_map.h create mode 100644 trunk/Arduino/GRBL_1.1f/defaults.h create mode 100644 trunk/Arduino/GRBL_1.1f/eagle_example.gcode create mode 100644 trunk/Arduino/GRBL_1.1f/eagle_example_2.gcode create mode 100644 trunk/Arduino/GRBL_1.1f/eeprom.c create mode 100644 trunk/Arduino/GRBL_1.1f/eeprom.h create mode 100644 trunk/Arduino/GRBL_1.1f/examples/grblUpload/grblUpload.ino create mode 100644 trunk/Arduino/GRBL_1.1f/examples/grblUpload/license.txt create mode 100644 trunk/Arduino/GRBL_1.1f/examples/grblWrite_BuildInfo/grblWrite_BuildInfo.ino create mode 100644 trunk/Arduino/GRBL_1.1f/examples/grblWrite_BuildInfo/license.txt create mode 100644 trunk/Arduino/GRBL_1.1f/gcode.c create mode 100644 trunk/Arduino/GRBL_1.1f/gcode.h create mode 100644 trunk/Arduino/GRBL_1.1f/grbl.h create mode 100644 trunk/Arduino/GRBL_1.1f/jog.c create mode 100644 trunk/Arduino/GRBL_1.1f/jog.h create mode 100644 trunk/Arduino/GRBL_1.1f/limits.c create mode 100644 trunk/Arduino/GRBL_1.1f/limits.h create mode 100644 trunk/Arduino/GRBL_1.1f/main.c create mode 100644 trunk/Arduino/GRBL_1.1f/makefile create mode 100644 trunk/Arduino/GRBL_1.1f/motion_control.c create mode 100644 trunk/Arduino/GRBL_1.1f/motion_control.h create mode 100644 trunk/Arduino/GRBL_1.1f/nuts_bolts.c create mode 100644 trunk/Arduino/GRBL_1.1f/nuts_bolts.h create mode 100644 trunk/Arduino/GRBL_1.1f/planner.c create mode 100644 trunk/Arduino/GRBL_1.1f/planner.h create mode 100644 trunk/Arduino/GRBL_1.1f/print.c create mode 100644 trunk/Arduino/GRBL_1.1f/print.h create mode 100644 trunk/Arduino/GRBL_1.1f/probe.c create mode 100644 trunk/Arduino/GRBL_1.1f/probe.h create mode 100644 trunk/Arduino/GRBL_1.1f/protocol.c create mode 100644 trunk/Arduino/GRBL_1.1f/protocol.h create mode 100644 trunk/Arduino/GRBL_1.1f/report.c create mode 100644 trunk/Arduino/GRBL_1.1f/report.h create mode 100644 trunk/Arduino/GRBL_1.1f/serial.c create mode 100644 trunk/Arduino/GRBL_1.1f/serial.h create mode 100644 trunk/Arduino/GRBL_1.1f/settings.c create mode 100644 trunk/Arduino/GRBL_1.1f/settings.h create mode 100644 trunk/Arduino/GRBL_1.1f/spindle_control.c create mode 100644 trunk/Arduino/GRBL_1.1f/spindle_control.h create mode 100644 trunk/Arduino/GRBL_1.1f/stepper.c create mode 100644 trunk/Arduino/GRBL_1.1f/stepper.h create mode 100644 trunk/Arduino/GRBL_1.1f/system.c create mode 100644 trunk/Arduino/GRBL_1.1f/system.h create mode 100644 trunk/Arduino/GRBL_1.1f_Nano/GRBL_1.1f_Nano.ino create mode 100644 trunk/Arduino/GRBL_1.1f_Nano/config.h create mode 100644 trunk/Arduino/GRBL_1.1f_Nano/coolant_control.c create mode 100644 trunk/Arduino/GRBL_1.1f_Nano/coolant_control.h create mode 100644 trunk/Arduino/GRBL_1.1f_Nano/cpu_map.h create mode 100644 trunk/Arduino/GRBL_1.1f_Nano/defaults.h create mode 100644 trunk/Arduino/GRBL_1.1f_Nano/eagle_example.gcode create mode 100644 trunk/Arduino/GRBL_1.1f_Nano/eagle_example_2.gcode create mode 100644 trunk/Arduino/GRBL_1.1f_Nano/eeprom.c create mode 100644 trunk/Arduino/GRBL_1.1f_Nano/eeprom.h create mode 100644 trunk/Arduino/GRBL_1.1f_Nano/gcode.c create mode 100644 trunk/Arduino/GRBL_1.1f_Nano/gcode.h create mode 100644 trunk/Arduino/GRBL_1.1f_Nano/grbl.h create mode 100644 trunk/Arduino/GRBL_1.1f_Nano/jog.c create mode 100644 trunk/Arduino/GRBL_1.1f_Nano/jog.h create mode 100644 trunk/Arduino/GRBL_1.1f_Nano/limits.c create mode 100644 trunk/Arduino/GRBL_1.1f_Nano/limits.h create mode 100644 trunk/Arduino/GRBL_1.1f_Nano/main.c create mode 100644 trunk/Arduino/GRBL_1.1f_Nano/makefile create mode 100644 trunk/Arduino/GRBL_1.1f_Nano/motion_control.c create mode 100644 trunk/Arduino/GRBL_1.1f_Nano/motion_control.h create mode 100644 trunk/Arduino/GRBL_1.1f_Nano/nuts_bolts.c create mode 100644 trunk/Arduino/GRBL_1.1f_Nano/nuts_bolts.h create mode 100644 trunk/Arduino/GRBL_1.1f_Nano/planner.c create mode 100644 trunk/Arduino/GRBL_1.1f_Nano/planner.h create mode 100644 trunk/Arduino/GRBL_1.1f_Nano/print.c create mode 100644 trunk/Arduino/GRBL_1.1f_Nano/print.h create mode 100644 trunk/Arduino/GRBL_1.1f_Nano/probe.c create mode 100644 trunk/Arduino/GRBL_1.1f_Nano/probe.h create mode 100644 trunk/Arduino/GRBL_1.1f_Nano/protocol.c create mode 100644 trunk/Arduino/GRBL_1.1f_Nano/protocol.h create mode 100644 trunk/Arduino/GRBL_1.1f_Nano/report.c create mode 100644 trunk/Arduino/GRBL_1.1f_Nano/report.h create mode 100644 trunk/Arduino/GRBL_1.1f_Nano/serial.c create mode 100644 trunk/Arduino/GRBL_1.1f_Nano/serial.h create mode 100644 trunk/Arduino/GRBL_1.1f_Nano/settings.c create mode 100644 trunk/Arduino/GRBL_1.1f_Nano/settings.h create mode 100644 trunk/Arduino/GRBL_1.1f_Nano/spindle_control.c create mode 100644 trunk/Arduino/GRBL_1.1f_Nano/spindle_control.h create mode 100644 trunk/Arduino/GRBL_1.1f_Nano/stepper.c create mode 100644 trunk/Arduino/GRBL_1.1f_Nano/stepper.h create mode 100644 trunk/Arduino/GRBL_1.1f_Nano/system.c create mode 100644 trunk/Arduino/GRBL_1.1f_Nano/system.h create mode 100644 trunk/Arduino/GRBL_Adafruit_motor_driverV2/GRBL_Adafruit_motor_driverV2.ino create mode 100644 trunk/Arduino/GRBL_Adafruit_motor_driverV2/config.h create mode 100644 trunk/Arduino/GRBL_Adafruit_motor_driverV2/eeprom.cpp create mode 100644 trunk/Arduino/GRBL_Adafruit_motor_driverV2/eeprom.h create mode 100644 trunk/Arduino/GRBL_Adafruit_motor_driverV2/g_print.cpp create mode 100644 trunk/Arduino/GRBL_Adafruit_motor_driverV2/g_print.h create mode 100644 trunk/Arduino/GRBL_Adafruit_motor_driverV2/gcode.cpp create mode 100644 trunk/Arduino/GRBL_Adafruit_motor_driverV2/gcode.h create mode 100644 trunk/Arduino/GRBL_Adafruit_motor_driverV2/limit_switch.h create mode 100644 trunk/Arduino/GRBL_Adafruit_motor_driverV2/limit_swtch.cpp create mode 100644 trunk/Arduino/GRBL_Adafruit_motor_driverV2/makefile create mode 100644 trunk/Arduino/GRBL_Adafruit_motor_driverV2/nuts_bolts.cpp create mode 100644 trunk/Arduino/GRBL_Adafruit_motor_driverV2/nuts_bolts.h create mode 100644 trunk/Arduino/GRBL_Adafruit_motor_driverV2/protocol.cpp create mode 100644 trunk/Arduino/GRBL_Adafruit_motor_driverV2/protocol.h create mode 100644 trunk/Arduino/GRBL_Adafruit_motor_driverV2/serial.cpp create mode 100644 trunk/Arduino/GRBL_Adafruit_motor_driverV2/serial.h create mode 100644 trunk/Arduino/GRBL_Adafruit_motor_driverV2/settings.cpp create mode 100644 trunk/Arduino/GRBL_Adafruit_motor_driverV2/settings.h create mode 100644 trunk/Arduino/GRBL_Adafruit_motor_driverV2/stepper_control.cpp create mode 100644 trunk/Arduino/GRBL_Adafruit_motor_driverV2/stepper_control.h create mode 100644 trunk/Arduino/Marlin_1.1.6/Conditionals.h create mode 100644 trunk/Arduino/Marlin_1.1.6/Conditionals_LCD.h create mode 100644 trunk/Arduino/Marlin_1.1.6/Conditionals_post.h create mode 100644 trunk/Arduino/Marlin_1.1.6/Configuration.h create mode 100644 trunk/Arduino/Marlin_1.1.6/Configuration_adv.h create mode 100644 trunk/Arduino/Marlin_1.1.6/G26_Mesh_Validation_Tool.cpp create mode 100644 trunk/Arduino/Marlin_1.1.6/I2CPositionEncoder.cpp create mode 100644 trunk/Arduino/Marlin_1.1.6/I2CPositionEncoder.h create mode 100644 trunk/Arduino/Marlin_1.1.6/M100_Free_Mem_Chk.cpp create mode 100644 trunk/Arduino/Marlin_1.1.6/Makefile create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/.gitattributes create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/.github/issue_template.md create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/.gitignore create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/.travis.yml create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/LICENSE create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/README.md create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/bin/build_marlin create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/bin/build_marlin_fail create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/bin/generate_version_header_for_marlin create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/bin/opt_disable create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/bin/opt_disable_adv create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/bin/opt_enable create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/bin/opt_enable_adv create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/bin/opt_set create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/bin/opt_set_adv create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/bin/pins_set create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/bin/restore_configs create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/bin/use_example_configs create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/etc/.astylerc create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/cmake/CMakeLists.txt create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/fonts/HD44780_C.fon create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/fonts/HD44780_J.fon create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/fonts/HD44780_W.fon create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/fonts/ISO10646-1-tr.fon create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/fonts/ISO10646-1.fon create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/fonts/ISO10646-4_Greek.fon create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/fonts/ISO10646-5_Cyrillic.fon create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/fonts/ISO10646_CN.fon create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/fonts/ISO10646_CZ.fon create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/fonts/ISO10646_Kana.fon create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/fonts/ISO10646_SK.fon create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/fonts/Marlin_symbols.fon create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/fonts/README.md create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/fonts/make_fonts.bat create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/git/README.md create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/git/firstpush create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/git/ghtp create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/git/mfadd create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/git/mfclean create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/git/mfdoc create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/git/mfinfo create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/git/mfinit create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/git/mfnew create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/git/mfpr create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/git/mfpub create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/git/mfqp create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/git/mfrb create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/git/mfup create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/pin_interrupt_test/pin_interrupt_test.ino create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/pixmaps/logo/marlin-1080.png create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/pixmaps/logo/marlin-250.png create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/pixmaps/logo/marlin-old-250.png create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/pixmaps/logo/marlin-old-627.png create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/pixmaps/logo/marlin-old.svg create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/pixmaps/logo/marlin.svg create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/scripts/MarlinMesh.scad create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/scripts/createSpeedLookupTable.py create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/scripts/createTemperatureLookupMarlin.py create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/scripts/findMissingTranslations.sh create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/scripts/g29_auto.py create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/platformio.ini create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin.h create mode 100644 trunk/Arduino/Marlin_1.1.6/MarlinConfig.h create mode 100644 trunk/Arduino/Marlin_1.1.6/MarlinSerial.cpp create mode 100644 trunk/Arduino/Marlin_1.1.6/MarlinSerial.h create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin_1.1.6.ino create mode 100644 trunk/Arduino/Marlin_1.1.6/Marlin_main.cpp create mode 100644 trunk/Arduino/Marlin_1.1.6/Max7219_Debug_LEDs.cpp create mode 100644 trunk/Arduino/Marlin_1.1.6/Max7219_Debug_LEDs.h create mode 100644 trunk/Arduino/Marlin_1.1.6/SanityCheck.h create mode 100644 trunk/Arduino/Marlin_1.1.6/Sd2Card.cpp create mode 100644 trunk/Arduino/Marlin_1.1.6/Sd2Card.h create mode 100644 trunk/Arduino/Marlin_1.1.6/SdBaseFile.cpp create mode 100644 trunk/Arduino/Marlin_1.1.6/SdBaseFile.h create mode 100644 trunk/Arduino/Marlin_1.1.6/SdFatConfig.h create mode 100644 trunk/Arduino/Marlin_1.1.6/SdFatStructs.h create mode 100644 trunk/Arduino/Marlin_1.1.6/SdFatUtil.cpp create mode 100644 trunk/Arduino/Marlin_1.1.6/SdFatUtil.h create mode 100644 trunk/Arduino/Marlin_1.1.6/SdFile.cpp create mode 100644 trunk/Arduino/Marlin_1.1.6/SdFile.h create mode 100644 trunk/Arduino/Marlin_1.1.6/SdInfo.h create mode 100644 trunk/Arduino/Marlin_1.1.6/SdVolume.cpp create mode 100644 trunk/Arduino/Marlin_1.1.6/SdVolume.h create mode 100644 trunk/Arduino/Marlin_1.1.6/Version.h create mode 100644 trunk/Arduino/Marlin_1.1.6/blinkm.cpp create mode 100644 trunk/Arduino/Marlin_1.1.6/blinkm.h create mode 100644 trunk/Arduino/Marlin_1.1.6/boards.h create mode 100644 trunk/Arduino/Marlin_1.1.6/buzzer.h create mode 100644 trunk/Arduino/Marlin_1.1.6/cardreader.cpp create mode 100644 trunk/Arduino/Marlin_1.1.6/cardreader.h create mode 100644 trunk/Arduino/Marlin_1.1.6/circularqueue.h create mode 100644 trunk/Arduino/Marlin_1.1.6/configuration_store.cpp create mode 100644 trunk/Arduino/Marlin_1.1.6/configuration_store.h create mode 100644 trunk/Arduino/Marlin_1.1.6/dac_mcp4728.cpp create mode 100644 trunk/Arduino/Marlin_1.1.6/dac_mcp4728.h create mode 100644 trunk/Arduino/Marlin_1.1.6/digipot_mcp4018.cpp create mode 100644 trunk/Arduino/Marlin_1.1.6/digipot_mcp4451.cpp create mode 100644 trunk/Arduino/Marlin_1.1.6/dogm_bitmaps.h create mode 100644 trunk/Arduino/Marlin_1.1.6/dogm_font_data_6x9_marlin.h create mode 100644 trunk/Arduino/Marlin_1.1.6/dogm_font_data_HD44780_C.h create mode 100644 trunk/Arduino/Marlin_1.1.6/dogm_font_data_HD44780_J.h create mode 100644 trunk/Arduino/Marlin_1.1.6/dogm_font_data_HD44780_W.h create mode 100644 trunk/Arduino/Marlin_1.1.6/dogm_font_data_ISO10646_1.h create mode 100644 trunk/Arduino/Marlin_1.1.6/dogm_font_data_ISO10646_1_PL.h create mode 100644 trunk/Arduino/Marlin_1.1.6/dogm_font_data_ISO10646_1_tr.h create mode 100644 trunk/Arduino/Marlin_1.1.6/dogm_font_data_ISO10646_5_Cyrillic.h create mode 100644 trunk/Arduino/Marlin_1.1.6/dogm_font_data_ISO10646_CN.h create mode 100644 trunk/Arduino/Marlin_1.1.6/dogm_font_data_ISO10646_CZ.h create mode 100644 trunk/Arduino/Marlin_1.1.6/dogm_font_data_ISO10646_Greek.h create mode 100644 trunk/Arduino/Marlin_1.1.6/dogm_font_data_ISO10646_Kana.h create mode 100644 trunk/Arduino/Marlin_1.1.6/dogm_font_data_ISO10646_SK.h create mode 100644 trunk/Arduino/Marlin_1.1.6/dogm_font_data_Marlin_symbols.h create mode 100644 trunk/Arduino/Marlin_1.1.6/duration_t.h create mode 100644 trunk/Arduino/Marlin_1.1.6/endstop_interrupts.h create mode 100644 trunk/Arduino/Marlin_1.1.6/endstops.cpp create mode 100644 trunk/Arduino/Marlin_1.1.6/endstops.h create mode 100644 trunk/Arduino/Marlin_1.1.6/enum.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/AlephObjects/TAZ4/Configuration.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/AlephObjects/TAZ4/Configuration_adv.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/AliExpress/CL-260/Configuration.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/AliExpress/CL-260/README.txt create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/Anet/A6/Configuration.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/Anet/A6/Configuration_adv.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/Anet/A8/Configuration.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/Anet/A8/Configuration_adv.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/BQ/Hephestos/Configuration.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/BQ/Hephestos/Configuration_adv.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/BQ/Hephestos_2/Configuration.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/BQ/Hephestos_2/Configuration_adv.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/BQ/Hephestos_2/README.md create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/BQ/Hephestos_2/_Bootscreen.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/BQ/WITBOX/Configuration.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/BQ/WITBOX/Configuration_adv.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/Cartesio/Configuration.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/Cartesio/Configuration_adv.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/Cartesio/_Bootscreen.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/Creality/CR-10/Configuration.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/Creality/CR-10/Configuration_adv.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/Creality/CR-10/_Bootscreen.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/Felix/Configuration.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/Felix/Configuration_adv.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/Felix/DUAL/Configuration.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/Felix/README.md create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/Folger Tech/i3-2020/Configuration.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/Folger Tech/i3-2020/Configuration_adv.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/Geeetech/GT2560/Configuration.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/Geeetech/I3_Pro_X-GT2560/Configuration.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/Infitary/i3-M508/Configuration.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/Infitary/i3-M508/Configuration_adv.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/Malyan/M150/Configuration.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/Malyan/M150/Configuration_adv.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/Malyan/M150/README.md create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/Malyan/M150/_Bootscreen.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/RepRapWorld/Megatronics/Configuration.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/RigidBot/Configuration.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/RigidBot/Configuration_adv.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/SCARA/Configuration.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/SCARA/Configuration_adv.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/Sanguinololu/Configuration.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/Sanguinololu/Configuration_adv.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/TinyBoy2/Configuration.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/TinyBoy2/Configuration_adv.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/Velleman/K8200/Configuration.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/Velleman/K8200/Configuration_adv.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/Velleman/K8200/README.md create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/Velleman/K8400/Configuration.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/Velleman/K8400/Configuration_adv.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/Velleman/K8400/Dual-head/Configuration.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/Velleman/K8400/README.md create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/adafruit/ST7565/Configuration.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/delta/FLSUN/auto_calibrate/Configuration.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/delta/FLSUN/auto_calibrate/Configuration_adv.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/delta/FLSUN/kossel_mini/Configuration.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/delta/FLSUN/kossel_mini/Configuration_adv.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/delta/generic/Configuration.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/delta/generic/Configuration_adv.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/delta/kossel_mini/Configuration.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/delta/kossel_mini/Configuration_adv.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/delta/kossel_pro/Configuration.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/delta/kossel_pro/Configuration_adv.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/delta/kossel_pro/README.md create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/delta/kossel_xl/Configuration.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/delta/kossel_xl/Configuration_adv.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/delta/kossel_xl/README.md create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/gCreate/gMax1.5+/Configuration.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/gCreate/gMax1.5+/Configuration_adv.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/gCreate/gMax1.5+/_Bootscreen.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/makibox/Configuration.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/makibox/Configuration_adv.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/tvrrug/Round2/Configuration.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/tvrrug/Round2/Configuration_adv.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/wt150/Configuration.h create mode 100644 trunk/Arduino/Marlin_1.1.6/example_configurations/wt150/Configuration_adv.h create mode 100644 trunk/Arduino/Marlin_1.1.6/fastio.h create mode 100644 trunk/Arduino/Marlin_1.1.6/fastio_1280.h create mode 100644 trunk/Arduino/Marlin_1.1.6/fastio_1281.h create mode 100644 trunk/Arduino/Marlin_1.1.6/fastio_168.h create mode 100644 trunk/Arduino/Marlin_1.1.6/fastio_644.h create mode 100644 trunk/Arduino/Marlin_1.1.6/fastio_AT90USB.h create mode 100644 trunk/Arduino/Marlin_1.1.6/gcode.cpp create mode 100644 trunk/Arduino/Marlin_1.1.6/gcode.h create mode 100644 trunk/Arduino/Marlin_1.1.6/hex_print_routines.cpp create mode 100644 trunk/Arduino/Marlin_1.1.6/hex_print_routines.h create mode 100644 trunk/Arduino/Marlin_1.1.6/language.h create mode 100644 trunk/Arduino/Marlin_1.1.6/language_an.h create mode 100644 trunk/Arduino/Marlin_1.1.6/language_bg.h create mode 100644 trunk/Arduino/Marlin_1.1.6/language_ca.h create mode 100644 trunk/Arduino/Marlin_1.1.6/language_cn.h create mode 100644 trunk/Arduino/Marlin_1.1.6/language_cz.h create mode 100644 trunk/Arduino/Marlin_1.1.6/language_cz_utf8.h create mode 100644 trunk/Arduino/Marlin_1.1.6/language_da.h create mode 100644 trunk/Arduino/Marlin_1.1.6/language_de.h create mode 100644 trunk/Arduino/Marlin_1.1.6/language_el-gr.h create mode 100644 trunk/Arduino/Marlin_1.1.6/language_el.h create mode 100644 trunk/Arduino/Marlin_1.1.6/language_en.h create mode 100644 trunk/Arduino/Marlin_1.1.6/language_es.h create mode 100644 trunk/Arduino/Marlin_1.1.6/language_eu.h create mode 100644 trunk/Arduino/Marlin_1.1.6/language_fi.h create mode 100644 trunk/Arduino/Marlin_1.1.6/language_fr.h create mode 100644 trunk/Arduino/Marlin_1.1.6/language_gl.h create mode 100644 trunk/Arduino/Marlin_1.1.6/language_hr.h create mode 100644 trunk/Arduino/Marlin_1.1.6/language_it.h create mode 100644 trunk/Arduino/Marlin_1.1.6/language_kana.h create mode 100644 trunk/Arduino/Marlin_1.1.6/language_kana_utf8.h create mode 100644 trunk/Arduino/Marlin_1.1.6/language_nl.h create mode 100644 trunk/Arduino/Marlin_1.1.6/language_pl-DOGM.h create mode 100644 trunk/Arduino/Marlin_1.1.6/language_pl-HD44780.h create mode 100644 trunk/Arduino/Marlin_1.1.6/language_pl.h create mode 100644 trunk/Arduino/Marlin_1.1.6/language_pt-br.h create mode 100644 trunk/Arduino/Marlin_1.1.6/language_pt-br_utf8.h create mode 100644 trunk/Arduino/Marlin_1.1.6/language_pt.h create mode 100644 trunk/Arduino/Marlin_1.1.6/language_pt_utf8.h create mode 100644 trunk/Arduino/Marlin_1.1.6/language_ru.h create mode 100644 trunk/Arduino/Marlin_1.1.6/language_sk_utf8.h create mode 100644 trunk/Arduino/Marlin_1.1.6/language_test.h create mode 100644 trunk/Arduino/Marlin_1.1.6/language_tr.h create mode 100644 trunk/Arduino/Marlin_1.1.6/language_uk.h create mode 100644 trunk/Arduino/Marlin_1.1.6/language_zh_CN.h create mode 100644 trunk/Arduino/Marlin_1.1.6/language_zh_TW.h create mode 100644 trunk/Arduino/Marlin_1.1.6/least_squares_fit.cpp create mode 100644 trunk/Arduino/Marlin_1.1.6/least_squares_fit.h create mode 100644 trunk/Arduino/Marlin_1.1.6/macros.h create mode 100644 trunk/Arduino/Marlin_1.1.6/mesh_bed_leveling.cpp create mode 100644 trunk/Arduino/Marlin_1.1.6/mesh_bed_leveling.h create mode 100644 trunk/Arduino/Marlin_1.1.6/nozzle.cpp create mode 100644 trunk/Arduino/Marlin_1.1.6/nozzle.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pca9632.cpp create mode 100644 trunk/Arduino/Marlin_1.1.6/pca9632.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pinsDebug.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pinsDebug_Teensyduino.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pinsDebug_list.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pinsDebug_plus_70.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_3DRAG.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_5DPRINT.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_ANET_10.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_AZTEEG_X1.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_AZTEEG_X3.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_AZTEEG_X3_PRO.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_BAM_DICE_DUE.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_BQ_ZUM_MEGA_3D.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_BRAINWAVE.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_BRAINWAVE_PRO.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_CHEAPTRONIC.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_CHEAPTRONICv2.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_CNCONTROLS_11.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_CNCONTROLS_12.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_ELEFU_3.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_FELIX2.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_GEN3_MONOLITHIC.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_GEN3_PLUS.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_GEN6.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_GEN6_DELUXE.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_GEN7_12.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_GEN7_13.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_GEN7_14.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_GEN7_CUSTOM.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_GT2560_REV_A.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_GT2560_REV_A_PLUS.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_K8200.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_K8400.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_LEAPFROG.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_MEGACONTROLLER.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_MEGATRONICS.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_MEGATRONICS_2.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_MEGATRONICS_3.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_MELZI.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_MELZI_CREALITY.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_MELZI_MAKR3D.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_MIGHTYBOARD_REVE.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_MINIRAMBO.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_MINITRONICS.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_MKS_13.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_MKS_BASE.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_OMCA.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_OMCA_A.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_PRINTRBOARD.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_PRINTRBOARD_REVF.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_RAMBO.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_RAMPS.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_RAMPS_13.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_RAMPS_OLD.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_RIGIDBOARD.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_RIGIDBOARD_V2.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_RUMBA.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_SAINSMART_2IN1.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_SANGUINOLOLU_11.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_SANGUINOLOLU_12.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_SAV_MKI.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_SCOOVO_X9H.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_SETHI.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_STB_11.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_TEENSY2.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_TEENSYLU.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_ULTIMAIN_2.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_ULTIMAKER.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_ULTIMAKER_OLD.h create mode 100644 trunk/Arduino/Marlin_1.1.6/pins_ZRIB_V20.h create mode 100644 trunk/Arduino/Marlin_1.1.6/planner.cpp create mode 100644 trunk/Arduino/Marlin_1.1.6/planner.h create mode 100644 trunk/Arduino/Marlin_1.1.6/planner_bezier.cpp create mode 100644 trunk/Arduino/Marlin_1.1.6/planner_bezier.h create mode 100644 trunk/Arduino/Marlin_1.1.6/point_t.h create mode 100644 trunk/Arduino/Marlin_1.1.6/printcounter.cpp create mode 100644 trunk/Arduino/Marlin_1.1.6/printcounter.h create mode 100644 trunk/Arduino/Marlin_1.1.6/serial.cpp create mode 100644 trunk/Arduino/Marlin_1.1.6/serial.h create mode 100644 trunk/Arduino/Marlin_1.1.6/servo.cpp create mode 100644 trunk/Arduino/Marlin_1.1.6/servo.h create mode 100644 trunk/Arduino/Marlin_1.1.6/softspi.h create mode 100644 trunk/Arduino/Marlin_1.1.6/speed_lookuptable.h create mode 100644 trunk/Arduino/Marlin_1.1.6/spi.h create mode 100644 trunk/Arduino/Marlin_1.1.6/stepper.cpp create mode 100644 trunk/Arduino/Marlin_1.1.6/stepper.h create mode 100644 trunk/Arduino/Marlin_1.1.6/stepper_dac.cpp create mode 100644 trunk/Arduino/Marlin_1.1.6/stepper_dac.h create mode 100644 trunk/Arduino/Marlin_1.1.6/stepper_indirection.cpp create mode 100644 trunk/Arduino/Marlin_1.1.6/stepper_indirection.h create mode 100644 trunk/Arduino/Marlin_1.1.6/stopwatch.cpp create mode 100644 trunk/Arduino/Marlin_1.1.6/stopwatch.h create mode 100644 trunk/Arduino/Marlin_1.1.6/temperature.cpp create mode 100644 trunk/Arduino/Marlin_1.1.6/temperature.h create mode 100644 trunk/Arduino/Marlin_1.1.6/thermistornames.h create mode 100644 trunk/Arduino/Marlin_1.1.6/thermistortable_1.h create mode 100644 trunk/Arduino/Marlin_1.1.6/thermistortable_10.h create mode 100644 trunk/Arduino/Marlin_1.1.6/thermistortable_1010.h create mode 100644 trunk/Arduino/Marlin_1.1.6/thermistortable_1047.h create mode 100644 trunk/Arduino/Marlin_1.1.6/thermistortable_11.h create mode 100644 trunk/Arduino/Marlin_1.1.6/thermistortable_110.h create mode 100644 trunk/Arduino/Marlin_1.1.6/thermistortable_12.h create mode 100644 trunk/Arduino/Marlin_1.1.6/thermistortable_13.h create mode 100644 trunk/Arduino/Marlin_1.1.6/thermistortable_147.h create mode 100644 trunk/Arduino/Marlin_1.1.6/thermistortable_2.h create mode 100644 trunk/Arduino/Marlin_1.1.6/thermistortable_20.h create mode 100644 trunk/Arduino/Marlin_1.1.6/thermistortable_3.h create mode 100644 trunk/Arduino/Marlin_1.1.6/thermistortable_4.h create mode 100644 trunk/Arduino/Marlin_1.1.6/thermistortable_5.h create mode 100644 trunk/Arduino/Marlin_1.1.6/thermistortable_51.h create mode 100644 trunk/Arduino/Marlin_1.1.6/thermistortable_52.h create mode 100644 trunk/Arduino/Marlin_1.1.6/thermistortable_55.h create mode 100644 trunk/Arduino/Marlin_1.1.6/thermistortable_6.h create mode 100644 trunk/Arduino/Marlin_1.1.6/thermistortable_60.h create mode 100644 trunk/Arduino/Marlin_1.1.6/thermistortable_66.h create mode 100644 trunk/Arduino/Marlin_1.1.6/thermistortable_7.h create mode 100644 trunk/Arduino/Marlin_1.1.6/thermistortable_70.h create mode 100644 trunk/Arduino/Marlin_1.1.6/thermistortable_71.h create mode 100644 trunk/Arduino/Marlin_1.1.6/thermistortable_75.h create mode 100644 trunk/Arduino/Marlin_1.1.6/thermistortable_8.h create mode 100644 trunk/Arduino/Marlin_1.1.6/thermistortable_9.h create mode 100644 trunk/Arduino/Marlin_1.1.6/thermistortable_998.h create mode 100644 trunk/Arduino/Marlin_1.1.6/thermistortable_999.h create mode 100644 trunk/Arduino/Marlin_1.1.6/thermistortables.h create mode 100644 trunk/Arduino/Marlin_1.1.6/twibus.cpp create mode 100644 trunk/Arduino/Marlin_1.1.6/twibus.h create mode 100644 trunk/Arduino/Marlin_1.1.6/types.h create mode 100644 trunk/Arduino/Marlin_1.1.6/ubl.cpp create mode 100644 trunk/Arduino/Marlin_1.1.6/ubl.h create mode 100644 trunk/Arduino/Marlin_1.1.6/ubl_G29.cpp create mode 100644 trunk/Arduino/Marlin_1.1.6/ubl_motion.cpp create mode 100644 trunk/Arduino/Marlin_1.1.6/ultralcd.cpp create mode 100644 trunk/Arduino/Marlin_1.1.6/ultralcd.h create mode 100644 trunk/Arduino/Marlin_1.1.6/ultralcd_impl_DOGM.h create mode 100644 trunk/Arduino/Marlin_1.1.6/ultralcd_impl_HD44780.h create mode 100644 trunk/Arduino/Marlin_1.1.6/ultralcd_st7565_u8glib_VIKI.h create mode 100644 trunk/Arduino/Marlin_1.1.6/ultralcd_st7920_u8glib_rrd.h create mode 100644 trunk/Arduino/Marlin_1.1.6/utf_mapper.h create mode 100644 trunk/Arduino/Marlin_1.1.6/utility.cpp create mode 100644 trunk/Arduino/Marlin_1.1.6/utility.h create mode 100644 trunk/Arduino/Marlin_1.1.6/vector_3.cpp create mode 100644 trunk/Arduino/Marlin_1.1.6/vector_3.h create mode 100644 trunk/Arduino/Marlin_1.1.6/watchdog.cpp create mode 100644 trunk/Arduino/Marlin_1.1.6/watchdog.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/Conditionals.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/Conditionals_LCD.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/Conditionals_post.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/Configuration.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/Configuration_adv.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/M100_Free_Mem_Chk.cpp create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/Makefile create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/Marlin.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/MarlinConfig.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/MarlinSerial.cpp create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/MarlinSerial.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/Marlin_K8600_1.1.0RC7.ino create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/Marlin_main.cpp create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/SanityCheck.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/Sd2Card.cpp create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/Sd2Card.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/SdBaseFile.cpp create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/SdBaseFile.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/SdFatConfig.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/SdFatStructs.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/SdFatUtil.cpp create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/SdFatUtil.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/SdFile.cpp create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/SdFile.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/SdInfo.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/SdVolume.cpp create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/SdVolume.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/Version.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/blinkm.cpp create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/blinkm.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/boards.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/buzzer.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/cardreader.cpp create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/cardreader.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/circularqueue.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/configuration_store.cpp create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/configuration_store.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/dac_mcp4728.cpp create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/dac_mcp4728.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/digipot_mcp4451.cpp create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/dogm_bitmaps.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/dogm_font_data_6x9_marlin.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/dogm_font_data_HD44780_C.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/dogm_font_data_HD44780_J.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/dogm_font_data_HD44780_W.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/dogm_font_data_ISO10646_1.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/dogm_font_data_ISO10646_5_Cyrillic.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/dogm_font_data_ISO10646_CN.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/dogm_font_data_ISO10646_Greek.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/dogm_font_data_ISO10646_Kana.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/dogm_font_data_Marlin_symbols.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/duration_t.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/endstops.cpp create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/endstops.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/enum.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/fastio.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/language.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/language_an.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/language_bg.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/language_ca.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/language_cn.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/language_cz.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/language_da.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/language_de.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/language_el-gr.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/language_el.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/language_en.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/language_es.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/language_eu.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/language_fi.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/language_fr.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/language_gl.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/language_hr.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/language_it.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/language_kana.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/language_kana_utf8.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/language_nl.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/language_pl.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/language_pt-br.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/language_pt-br_utf8.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/language_pt.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/language_pt_utf8.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/language_ru.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/language_test.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/macros.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/mesh_bed_leveling.cpp create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/mesh_bed_leveling.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/nozzle.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_3DRAG.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_5DPRINT.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_99.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_A4JP.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_AZTEEG_X1.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_AZTEEG_X3.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_AZTEEG_X3_PRO.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_BAM_DICE_DUE.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_BQ_ZUM_MEGA_3D.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_BRAINWAVE.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_BRAINWAVE_PRO.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_CHEAPTRONIC.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_CNCONTROLS_11.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_CNCONTROLS_12.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_ELEFU_3.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_FELIX2.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_GEN3_MONOLITHIC.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_GEN3_PLUS.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_GEN6.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_GEN6_DELUXE.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_GEN7_12.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_GEN7_13.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_GEN7_14.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_GEN7_CUSTOM.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_K8200.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_K8400.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_K8600.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_LEAPFROG.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_MEGACONTROLLER.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_MEGATRONICS.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_MEGATRONICS_2.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_MEGATRONICS_3.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_MELZI.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_MELZI_MAKR3D.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_MINIRAMBO.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_MINITRONICS.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_MKS_13.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_MKS_BASE.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_OMCA.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_OMCA_A.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_PRINTRBOARD.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_PRINTRBOARD_REVF.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_RAMBO.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_RAMPS.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_RAMPS_13.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_RAMPS_14.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_RAMPS_OLD.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_RIGIDBOARD.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_RIGIDBOARD_V2.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_RUMBA.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_SAINSMART_2IN1.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_SANGUINOLOLU_11.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_SANGUINOLOLU_12.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_SAV_MKI.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_SETHI.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_STB_11.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_TEENSY2.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_TEENSYLU.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_ULTIMAIN_2.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_ULTIMAKER.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_ULTIMAKER_OLD.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/planner.cpp create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/planner.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/planner_bezier.cpp create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/planner_bezier.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/point_t.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/printcounter.cpp create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/printcounter.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/qr_solve.cpp create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/qr_solve.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/servo.cpp create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/servo.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/speed_lookuptable.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/stepper.cpp create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/stepper.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/stepper_dac.cpp create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/stepper_dac.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/stepper_indirection.cpp create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/stepper_indirection.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/stopwatch.cpp create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/stopwatch.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/temperature.cpp create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/temperature.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/thermistornames.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/thermistortables.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/twibus.cpp create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/twibus.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/types.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/ultralcd.cpp create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/ultralcd.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/ultralcd_impl_DOGM.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/ultralcd_impl_HD44780.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/ultralcd_st7920_u8glib_rrd.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/utf_mapper.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/utility.cpp create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/utility.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/vector_3.cpp create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/vector_3.h create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/watchdog.cpp create mode 100644 trunk/Arduino/Marlin_K8600_1.1.0RC7/watchdog.h create mode 100644 trunk/Arduino/Marlin_K8600_Original/eeprom.bin create mode 100644 trunk/Arduino/Marlin_K8600_Original/eeprom.hex create mode 100644 trunk/Arduino/Marlin_K8600_Original/efuse.bin create mode 100644 trunk/Arduino/Marlin_K8600_Original/efuse.hex create mode 100644 trunk/Arduino/Marlin_K8600_Original/flash.bin create mode 100644 trunk/Arduino/Marlin_K8600_Original/flash.hex create mode 100644 trunk/Arduino/Marlin_K8600_Original/hfuse.bin create mode 100644 trunk/Arduino/Marlin_K8600_Original/hfuse.hex create mode 100644 trunk/Arduino/Marlin_K8600_Original/lfuse.bin create mode 100644 trunk/Arduino/Marlin_K8600_Original/lfuse.hex create mode 100644 trunk/Arduino/Micronucleus_Bootloader/micronucleus-1.11-ledpb1.hex create mode 100644 trunk/Arduino/Micronucleus_Bootloader/micronucleus-1.11.hex create mode 100644 trunk/Arduino/Repetier_0.92.9/BedLeveling.cpp create mode 100644 trunk/Arduino/Repetier_0.92.9/Commands.cpp create mode 100644 trunk/Arduino/Repetier_0.92.9/Commands.h create mode 100644 trunk/Arduino/Repetier_0.92.9/Communication.cpp create mode 100644 trunk/Arduino/Repetier_0.92.9/Communication.h create mode 100644 trunk/Arduino/Repetier_0.92.9/Configuration.h create mode 100644 trunk/Arduino/Repetier_0.92.9/Drivers.cpp create mode 100644 trunk/Arduino/Repetier_0.92.9/Drivers.h create mode 100644 trunk/Arduino/Repetier_0.92.9/Eeprom.cpp create mode 100644 trunk/Arduino/Repetier_0.92.9/Eeprom.h create mode 100644 trunk/Arduino/Repetier_0.92.9/Events.h create mode 100644 trunk/Arduino/Repetier_0.92.9/Extruder.cpp create mode 100644 trunk/Arduino/Repetier_0.92.9/Extruder.h create mode 100644 trunk/Arduino/Repetier_0.92.9/FatStructs.h create mode 100644 trunk/Arduino/Repetier_0.92.9/HAL.cpp create mode 100644 trunk/Arduino/Repetier_0.92.9/HAL.h create mode 100644 trunk/Arduino/Repetier_0.92.9/Printer.cpp create mode 100644 trunk/Arduino/Repetier_0.92.9/Printer.h create mode 100644 trunk/Arduino/Repetier_0.92.9/README.txt create mode 100644 trunk/Arduino/Repetier_0.92.9/Repetier.h create mode 100644 trunk/Arduino/Repetier_0.92.9/Repetier_0.92.9.ino create mode 100644 trunk/Arduino/Repetier_0.92.9/SDCard.cpp create mode 100644 trunk/Arduino/Repetier_0.92.9/SdFat.cpp create mode 100644 trunk/Arduino/Repetier_0.92.9/SdFat.h create mode 100644 trunk/Arduino/Repetier_0.92.9/fastio.h create mode 100644 trunk/Arduino/Repetier_0.92.9/gcode.cpp create mode 100644 trunk/Arduino/Repetier_0.92.9/gcode.h create mode 100644 trunk/Arduino/Repetier_0.92.9/logo.h create mode 100644 trunk/Arduino/Repetier_0.92.9/makefile create mode 100644 trunk/Arduino/Repetier_0.92.9/motion.cpp create mode 100644 trunk/Arduino/Repetier_0.92.9/motion.h create mode 100644 trunk/Arduino/Repetier_0.92.9/pins.h create mode 100644 trunk/Arduino/Repetier_0.92.9/u8glib_ex.h create mode 100644 trunk/Arduino/Repetier_0.92.9/ui.cpp create mode 100644 trunk/Arduino/Repetier_0.92.9/ui.h create mode 100644 trunk/Arduino/Repetier_0.92.9/uiconfig.h create mode 100644 trunk/Arduino/Repetier_0.92.9/uilang.cpp create mode 100644 trunk/Arduino/Repetier_0.92.9/uilang.h create mode 100644 trunk/Arduino/Repetier_0.92.9/uimenu.h create mode 100644 trunk/Arduino/Single_Chip_Computer/EEprom/EEPROM Storage Cad Artwork.oxps create mode 100644 trunk/Arduino/Single_Chip_Computer/EEprom/EEPROM Storage Card Schematic.png create mode 100644 trunk/Arduino/Single_Chip_Computer/EEprom/Gerber/EEPROM Storage Card (64Kbit)-B_Cu.gbl create mode 100644 trunk/Arduino/Single_Chip_Computer/EEprom/Gerber/EEPROM Storage Card (64Kbit)-Edge_Cuts.gbr create mode 100644 trunk/Arduino/Single_Chip_Computer/EEprom/Gerber/EEPROM Storage Card (64Kbit)-F_SilkS.gto create mode 100644 trunk/Arduino/Single_Chip_Computer/EEprom/Gerber/EEPROM Storage Card (64Kbit).txt create mode 100644 trunk/Arduino/Single_Chip_Computer/Single Chip AVR BASIC Computer • Hackaday Projects.website create mode 100644 trunk/Arduino/Single_Chip_Computer/Single Chip Computer - Instructable.website create mode 100644 trunk/Arduino/Single_Chip_Computer/Single Chip Computer - TinyBasicPlus · GitHub.website create mode 100644 trunk/Arduino/Single_Chip_Computer/Single Chip Computer.pdf create mode 100644 trunk/Arduino/Single_Chip_Computer/Single_Chip_Computer.ino create mode 100644 trunk/Arduino/Single_Chip_Computer/Single_Chip_Computer_1.14.hex create mode 100644 trunk/Arduino/Single_Chip_Computer/Single_Chip_Computer_1.15.ino.txt create mode 100644 trunk/Arduino/Single_Chip_Computer/Single_chip_Computer_1.14.ino.txt create mode 100644 trunk/Arduino/Single_Chip_VIC20/Single_Chip_VIC20.ino create mode 100644 trunk/Arduino/Single_Chip_VIC20/cpu.c create mode 100644 trunk/Arduino/Single_Chip_VIC20/lightbox_NANO20.jpg create mode 100644 trunk/Arduino/esp32-cam-webserver/.gitignore create mode 100644 trunk/Arduino/esp32-cam-webserver/.travis.yml create mode 100644 trunk/Arduino/esp32-cam-webserver/API.md create mode 100644 trunk/Arduino/esp32-cam-webserver/CONTRIBUTING.md create mode 100644 trunk/Arduino/esp32-cam-webserver/Docs/board-selection-small.png create mode 100644 trunk/Arduino/esp32-cam-webserver/Docs/favicon-16x16.png create mode 100644 trunk/Arduino/esp32-cam-webserver/Docs/favicon-32x32.png create mode 100644 trunk/Arduino/esp32-cam-webserver/Docs/favicon-README.md create mode 100644 trunk/Arduino/esp32-cam-webserver/Docs/favicon.ico create mode 100644 trunk/Arduino/esp32-cam-webserver/Docs/headline-image.png create mode 100644 trunk/Arduino/esp32-cam-webserver/Docs/hookup.png create mode 100644 trunk/Arduino/esp32-cam-webserver/Docs/linearled/README.md create mode 100644 trunk/Arduino/esp32-cam-webserver/Docs/linearled/linearled.c create mode 100644 trunk/Arduino/esp32-cam-webserver/Docs/logo-big.png create mode 100644 trunk/Arduino/esp32-cam-webserver/Docs/logo.png create mode 100644 trunk/Arduino/esp32-cam-webserver/Docs/logo.svg create mode 100644 trunk/Arduino/esp32-cam-webserver/Docs/mygodsitsfullofcats.png create mode 100644 trunk/Arduino/esp32-cam-webserver/Docs/screenshot.png create mode 100644 trunk/Arduino/esp32-cam-webserver/Docs/webcams.programmer.jpg create mode 100644 trunk/Arduino/esp32-cam-webserver/LICENSE create mode 100644 trunk/Arduino/esp32-cam-webserver/README.md create mode 100644 trunk/Arduino/esp32-cam-webserver/app_httpd.cpp create mode 100644 trunk/Arduino/esp32-cam-webserver/camera_pins.h create mode 100644 trunk/Arduino/esp32-cam-webserver/css.h create mode 100644 trunk/Arduino/esp32-cam-webserver/esp32-cam-webserver.ino create mode 100644 trunk/Arduino/esp32-cam-webserver/index_other.h create mode 100644 trunk/Arduino/esp32-cam-webserver/index_ov2640.h create mode 100644 trunk/Arduino/esp32-cam-webserver/index_ov3660.h create mode 100644 trunk/Arduino/esp32-cam-webserver/myconfig.sample.h create mode 100644 trunk/Arduino/esp32-cam-webserver/platformio.ini create mode 100644 trunk/Arduino/esp32-cam-webserver/src/favicons.h create mode 100644 trunk/Arduino/esp32-cam-webserver/src/jsonlib/README.md create mode 100644 trunk/Arduino/esp32-cam-webserver/src/jsonlib/jsonlib-LICENSE create mode 100644 trunk/Arduino/esp32-cam-webserver/src/jsonlib/jsonlib.cpp create mode 100644 trunk/Arduino/esp32-cam-webserver/src/jsonlib/jsonlib.h create mode 100644 trunk/Arduino/esp32-cam-webserver/src/logo.h create mode 100644 trunk/Arduino/esp32-cam-webserver/src/parsebytes.cpp create mode 100644 trunk/Arduino/esp32-cam-webserver/src/parsebytes.h create mode 100644 trunk/Arduino/esp32-cam-webserver/src/version.h create mode 100644 trunk/Arduino/esp32-cam-webserver/storage.cpp create mode 100644 trunk/Arduino/esp32-cam-webserver/storage.h diff --git a/trunk/Arduino/ArduinoFDC/ Library for using an Arduino as a floppy disk controller.desktop b/trunk/Arduino/ArduinoFDC/ Library for using an Arduino as a floppy disk controller.desktop new file mode 100644 index 00000000..1f6c2e3c --- /dev/null +++ b/trunk/Arduino/ArduinoFDC/ Library for using an Arduino as a floppy disk controller.desktop @@ -0,0 +1,7 @@ +[Desktop Entry] +Version=1.0 +Type=Link +Name=GitHub - dhansel/ArduinoFDC: Library for using an Arduino as a floppy disk controller +Comment= +Icon=user-bookmarks +URL=https://github.com/dhansel/ArduinoFDC diff --git a/trunk/Arduino/ArduinoFDC/ArduinoFDC.cpp b/trunk/Arduino/ArduinoFDC/ArduinoFDC.cpp new file mode 100644 index 00000000..6b3a8d72 --- /dev/null +++ b/trunk/Arduino/ArduinoFDC/ArduinoFDC.cpp @@ -0,0 +1,1793 @@ +// ----------------------------------------------------------------------------- +// 3.5"/5.25" DD/HD Disk controller for Arduino +// Copyright (C) 2021 David Hansel +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// ----------------------------------------------------------------------------- + +#include "ArduinoFDC.h" + +#if defined(__AVR_ATmega328P__) + +// ------------------------------- Pin assignments for Arduino UNO/Nano/Pro Mini (Atmega328p) ------------------------------ + +#define PIN_STEP 2 // can be changed to different pin +#define PIN_STEPDIR 3 // can be changed to different pin +#define PIN_MOTORA 4 // can be changed to different pin +#define PIN_SELECTA 5 // can be changed to different pin +#define PIN_SIDE 6 // can be changed to different pin +#define PIN_INDEX 7 // accesses via IDXPORT/IDXBIT #defines below +#define PIN_READDATA 8 // must be pin 8 (ICP for timer1) +#define PIN_WRITEDATA 9 // must be pin 9 (OCP for timer1) +#define PIN_WRITEGATE 10 // accessed via WGPORT/WGBIT #defines below +#define PIN_TRACK0 11 // can be changed to different pin +#define PIN_WRITEPROT 12 // can be changed to different pin or commented out +#define PIN_DENSITY 13 // can be changed to different pin or commented out +#define PIN_MOTORB A0 // can be changed to different pin or commented out (together with PIN_SELECTB) +#define PIN_SELECTB A1 // can be changed to different pin or commented out (together with PIN_MOTORB) + + +asm (" .equ TIFR, 0x16\n" // timer 1 flag register + " .equ TOV, 0\n" // overflow flag + " .equ OCF, 1\n" // output compare flag + " .equ ICF, 5\n" // input capture flag + " .equ TCCRC, 0x82\n" // timer 1 control register C + " .equ FOC, 0x80\n" // force output compare flag + " .equ TCNTL, 0x84\n" // timer 1 counter (low byte) + " .equ ICRL, 0x86\n" // timer 1 input capture register (low byte) + " .equ OCRL, 0x88\n" // timer 1 output compare register (low byte) + " .equ IDXPORT, 0x29\n" // INDEX pin register (digital pin 7, register PD7, accessed via LDS instruction) + " .equ IDXBIT, 7\n" // INDEX pin bit (digital pin 7, register PD7) + ); + +#define TIFR TIFR1 // timer 1 flag register +#define TOV TOV1 // overflow flag +#define OCF OCF1A // output compare flag +#define ICF ICF1 // input capture flag +#define TCCRA TCCR1A // timer 1 control register A +#define COMA1 COM1A1 // timer 1 output compare mode bit 1 +#define COMA0 COM1A0 // timer 1 output compare mode bit 0 +#define TCCRB TCCR1B // timer 1 control register B +#define CS1 CS11 // timer 1 clock select bit 1 +#define CS0 CS10 // timer 1 clock select bit 0 +#define WGM2 WGM12 // timer 1 waveform mode bit 2 +#define TCCRC TCCR1C // timer 1 control register C +#define FOC FOC1A // force output compare flag +#define OCR OCR1A // timer 1 output compare register +#define TCNT TCNT1 // timer 1 counter +#define IDXPORT PIND // INDEX pin port (digital pin 7, register PD7) +#define IDXBIT 7 // INDEX pin bit (digital pin 7, register PD7) +#define WGPORT DDRB // WRITEGATE pin port (digital pin 10, register PB2) +#define WGBIT 2 // WRITEGATE pin bit (digital pin 10, register PB2) +#define OCDDR DDRB // DDR controlling WRITEDATA pin +#define OCBIT 1 // bit for WRITEDATA pin + + +#elif defined(__AVR_ATmega32U4__) + +// ----------------------- Pin assignments for Arduino Leonardo/Micro (Atmega32U4) -------------------------- + +#define PIN_STEP 2 // can be changed to different pin +#define PIN_STEPDIR 3 // can be changed to different pin +#define PIN_READDATA 4 // must be pin 4 (ICP for timer1) +#define PIN_MOTORA 5 // can be changed to different pin +#define PIN_SELECTA 6 // can be changed to different pin +#define PIN_SIDE 7 // can be changed to different pin +#define PIN_INDEX 8 // accesses via IDXPORT/IDXBIT #defines below +#define PIN_WRITEDATA 9 // must be pin 9 (OCP for timer1) +#define PIN_WRITEGATE 10 // accessed via WGPORT/WGBIT #defines below +#if defined(ARDUINO_AVR_LEONARDO) +#define PIN_TRACK0 11 // can be changed to different pin +#define PIN_WRITEPROT 12 // can be changed to different pin or commented out +#define PIN_DENSITY 13 // can be changed to different pin or commented out +#else +#define PIN_TRACK0 14 // can be changed to different pin +#define PIN_WRITEPROT 15 // can be changed to different pin or commented out +#define PIN_DENSITY 16 // can be changed to different pin or commented out +#endif +#define PIN_MOTORB A0 // can be changed to different pin or commented out (together with PIN_SELECTB) +#define PIN_SELECTB A1 // can be changed to different pin or commented out (together with PIN_MOTORB) + + +asm (" .equ TIFR, 0x16\n" // timer 1 flag register + " .equ TOV, 0\n" // overflow flag + " .equ OCF, 1\n" // output compare flag + " .equ ICF, 5\n" // input capture flag + " .equ TCCRC, 0x82\n" // timer 1 control register C + " .equ FOC, 0x80\n" // force output compare flag + " .equ TCNTL, 0x84\n" // timer 1 counter (low byte) + " .equ ICRL, 0x86\n" // timer 1 input capture register (low byte) + " .equ OCRL, 0x88\n" // timer 1 output compare register (low byte) + " .equ IDXPORT, 0x23\n" // INDEX pin register (digital pin 8, register PB4, accessed via LDS instruction) + " .equ IDXBIT, 4\n" // INDEX pin bit (digital pin 8, register PB4) + ); + +#define TIFR TIFR1 // timer 1 flag register +#define TOV TOV1 // overflow flag +#define OCF OCF1A // output compare flag +#define ICF ICF1 // input capture flag +#define TCCRA TCCR1A // timer 1 control register A +#define COMA1 COM1A1 // timer 1 output compare mode bit 1 +#define COMA0 COM1A0 // timer 1 output compare mode bit 0 +#define TCCRB TCCR1B // timer 1 control register B +#define CS1 CS11 // timer 1 clock select bit 1 +#define CS0 CS10 // timer 1 clock select bit 0 +#define WGM2 WGM12 // timer 1 waveform mode bit 2 +#define TCCRC TCCR1C // timer 1 control register C +#define FOC FOC1A // force output compare flag +#define OCR OCR1A // timer 1 output compare register +#define TCNT TCNT1 // timer 1 counter +#define IDXPORT PINB // INDEX pin port (digital pin 8, register PB4) +#define IDXBIT 4 // INDEX pin bit (digital pin 8, register PB4) +#define WGPORT DDRB // WRITEGATE pin port (digital pin 10, register PB6) +#define WGBIT 6 // WRITEGATE pin bit (digital pin 10, register PB6) +#define OCDDR DDRB // WRITEDATA pin port (digital pin 9, register PB5) +#define OCBIT 5 // WRITEDATA pin bit (digital pin 9, register PB5) + + +#elif defined(__AVR_ATmega2560__) + +// ------------------------------ Pin assignments for Arduino Mega (Atmega2560) ----------------------------- + +#define PIN_STEP 53 // can be changed to different pin +#define PIN_STEPDIR 52 // can be changed to different pin +#define PIN_MOTORA 51 // can be changed to different pin +#define PIN_SELECTA 50 // can be changed to different pin +#define PIN_SIDE 49 // can be changed to different pin +#define PIN_INDEX 47 // accessed via IDXPORT/IDXBIT #defines below +#define PIN_READDATA 48 // must be pin 48 (ICP for timer5) +#define PIN_WRITEDATA 46 // must be pin 46 (OCP for timer5) +#define PIN_WRITEGATE 45 // accessed via WGPORT/WGBIT #defines below +#define PIN_TRACK0 44 // can be changed to different pin +#define PIN_WRITEPROT 43 // can be changed to different pin or commented out +#define PIN_DENSITY 42 // can be changed to different pin or commented out +#define PIN_MOTORB 41 // can be changed to different pin or commented out (together with PIN_SELECTB) +#define PIN_SELECTB 40 // can be changed to different pin or commented out (together with PIN_MOTORB) + + +asm (" .equ TIFR, 0x1A\n" // timer 5 flag register + " .equ TOV, 0\n" // overflow flag + " .equ OCF, 1\n" // output compare flag + " .equ ICF, 5\n" // input capture flag + " .equ TCCRC, 0x122\n" // timer 5 control register C + " .equ FOC, 0x80\n" // force output compare flag + " .equ TCNTL, 0x124\n" // timer 5 counter (low byte) + " .equ ICRL, 0x126\n" // timer 5 input capture register (low byte) + " .equ OCRL, 0x128\n" // timer 5 output compare register (low byte) + " .equ IDXPORT, 0x109\n" // INDEX pin register (digital pin 47, register PL2) + " .equ IDXBIT, 2\n" // INDEX pin bit (digital pin 47, register PL2) + ); + +#define TIFR TIFR5 // timer 5 flag register +#define TOV TOV5 // overflow flag +#define OCF OCF5A // output compare flag +#define ICF ICF5 // input capture flag +#define TCCRA TCCR5A // timer 5 control register A +#define COMA1 COM5A1 // timer 5 output compare mode bit 1 +#define COMA0 COM5A0 // timer 5 output compare mode bit 0 +#define TCCRB TCCR5B // timer 5 control register B +#define CS1 CS51 // timer 5 clock select bit 1 +#define CS0 CS50 // timer 5 clock select bit 0 +#define WGM2 WGM52 // timer 5 waveform mode bit 2 +#define TCCRC TCCR5C // timer 5 control register C +#define FOC FOC5A // force output compare flag +#define OCR OCR5A // timer 5 output compare register +#define TCNT TCNT5 // timer 5 counter +#define IDXPORT PINL // INDEX pin port (digital pin 47, register PL2) +#define IDXBIT 2 // INDEX pin bit (digital pin 47, register PL2) +#define WGPORT DDRL // WRITEGATE pin port (digital pin 45, register PL4) +#define WGBIT 4 // WRITEGATE pin bit (digital pin 45, register PL4) +#define OCDDR DDRL // DDR controlling WRITEDATA pin +#define OCBIT 3 // bit for WRITEDATA pin + + +#else + +#error "ArduinoFDC library requires either an ATMega328P, Atmega32U4 or ATMega2560 processor (Arduino UNO, Leonardo or MEGA)" + +#endif + +#if F_CPU != 16000000 +#error "ArduinoFDC library requires 16MHz clock speed" +#endif + + +struct DriveGeometryStruct +{ + byte numTracks; + byte numSectors; + byte dataGap; + byte trackSpacing; +}; + + +static struct DriveGeometryStruct geometry[5] = + { + {40, 9, 80, 1}, // 5.25" DD (360 KB) + {40, 9, 80, 2}, // 5.25" DD disk in HD drive (360 KB) + {80, 15, 85, 1}, // 5.25" HD (1.2 MB) + {80, 9, 80, 1}, // 3.5" DD (720 KB) + {80, 18, 100, 1} // 3.5" HD (1.44 MB) + }; + + +// un-commenting this will write more detailed error information to Serial +//#define DEBUG + +ArduinoFDCClass ArduinoFDC; +static byte header[7]; + + +// digitalWrite function for simulating open-collector outputs. +// Each output pin must be initialized by digitalWrite(pin, LOW) and pinMode(PIN, INPUT) +// after that, switching the pinMode to INPUT will set the pin to high-Z state +// and switching to OUTPUT will pull the pin low. +// The floppy disk interface specification expects outputs to be open-collector +void digitalWriteOC(byte pin, byte state) +{ if( state==LOW ) pinMode(pin, OUTPUT); else pinMode(pin, INPUT); } + + + +static const uint16_t PROGMEM crc16_table[256] = +{ + 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF, + 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6, 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE, + 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485, 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D, + 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4, 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC, + 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823, 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B, + 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12, 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A, + 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41, 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49, + 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70, 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78, + 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F, 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067, + 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E, 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256, + 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D, 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, + 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C, 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634, + 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB, 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3, + 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A, 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92, + 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9, 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1, + 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8, 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0 +}; + + +static uint16_t calc_crc(byte *buf, int n) +{ + // already includes sync marks (0xA1, 0xA1, 0xA1) + uint16_t crc = 0xCDB4; + + // compute CRC of remaining data + while( n-- > 0 ) + crc = pgm_read_word_near(crc16_table + (((crc >> 8) ^ *buf++) & 0xff)) ^ (crc << 8); + + return crc; +} + + +static bool is_write_protected() +{ +#if defined(PIN_WRITEPROT) + return !digitalRead(PIN_WRITEPROT); +#else + return false; +#endif +} + +static bool check_pulse() +{ + // reset timer and capture/overrun flags + TCNT = 0; + TIFR = bit(ICF) | bit(TOV); + + // wait for either input capture or timer overrun + while( !(TIFR & (bit(ICF) | bit(TOV))) ); + + // if there was an input capture then we are ok + bool res = (TIFR & bit(ICF))!=0; + + // reset input capture and timer overun flags + TIFR = bit(ICF) | bit(TOV); + + return res; +} + + +static bool wait_index_hole() +{ + // reset timer and overrun flags + TCNT = 0; + TIFR = bit(TOV); + byte ctr = 0; + + // wait for END of index hole (in case we're on the hole right now) + while( !(IDXPORT & bit(IDXBIT)) ) + { + if( TIFR & bit(TOV) ) + { + // timer overflow happens every 4.096ms (65536 cycles at 16MHz) + // meaning we haven't found a sync in that amount of time + if( ++ctr == 0 ) + { + // we have tried for 256 * 4.096ms = 1.048 seconds to find a index hole + // one rotation is 166 or 200ms so we have tried for 5 or more rotations => give up +#ifdef DEBUG + Serial.println(F("No index hole signal!")); Serial.flush(); +#endif + return false; + } + + // clear overflow flag + TIFR = bit(TOV); + } + } + + // wait for START of index hole (same as above) + ctr = 0; + while( (IDXPORT & bit(IDXBIT)) ) + { + if( TIFR & bit(TOV) ) + { + if( ++ctr == 0 ) + { +#ifdef DEBUG + Serial.println(F("No index hole signal!")); Serial.flush(); +#endif + return false; + } + + TIFR = bit(TOV); + } + } + + return true; +} + + + +static byte read_data(byte bitlen, byte *buffer, unsigned int n, byte verify) +{ + byte status; + + // expect at least 10 bytes of 0x00 followed by three sync marks (0xA1 with one missing clock bit) + // Data bits : 0 0 ...0 1 0 1 0 0*0 0 1 1 0 1 0 0*0 0 1 1 0 1 0 0*0 0 1 + // In MFM : (0)1010...10 0100010010001001 0100010010001001 0100010010001001 + + asm volatile + ( + // define READPULSE macro (wait for pulse) + // macro arguments: + // length: none => just wait for pulse, don't check ( 9 cycles) + // 1 => wait for pulse and jump if NOT short (12/14 cycles) + // 2 => wait for pulse and jump if NOT medium (14/16 cycles) + // 3 => wait for pulse and jump if NOT long (12/14 cycles) + // dst: label to jump to if DIFFERENT pulse found + // + // on entry: r16 contains minimum length of medium pulse + // r17 contains minimum length of long pulse + // r18 contains time of previous pulse + // on exit: r18 is updated to the time of this pulse + // r22 contains the pulse length in timer ticks (=processor cycles) + // CLOBBERS: r19 + ".macro READPULSE length=0,dst=undefined\n" + " sbis TIFR, ICF\n" // (1/2) skip next instruction if timer input capture seen + " rjmp .-4\n" // (2) wait more + " lds r19, ICRL\n" // (2) get time of input capture (ICR1L, lower 8 bits only) + " sbi TIFR, ICF\n " // (2) clear input capture flag + " mov r22, r19\n" // (1) calculate time since previous capture... + " sub r22, r18\n" // (1) ...into r22 + " mov r18, r19\n" // (1) set r18 to time of current capture + " .if \\length == 1\n" // waiting for short pule? + " cp r22, r16\n" // (1) compare r22 to min medium pulse + " brlo .+2\n" // (1/2) skip jump if less + " rjmp \\dst\n" // (3) not the expected pulse => jump to dst + " .else \n" + " .if \\length == 2\n" // waiting for medium pulse? + " cp r16, r22\n" // (1) min medium pulse < r22? => carry set if so + " brcc .+2\n" // (1/2) skip next instruction if carry is clear + " cp r22, r17\n" // (1) r22 < min long pulse? => carry set if so + " brcs .+2\n" // (1/2) skip jump if greater + " rjmp \\dst\n" // (3) not the expected pulse => jump to dst + " .else\n" + " .if \\length == 3\n" + " cp r22, r17\n" // (1) min long pulse < r22? + " brsh .+2\n" // (1/2) skip jump if greater + " rjmp \\dst\n" // (3) not the expected pulse => jump to dst + " .endif\n" + " .endif\n" + " .endif\n" + ".endm\n" + + // define STOREBIT macro for storing or verifying data bit + // storing data : 5/14 cycles for "1", 4/13 cycles for "0" + // verifying data : 5/15 cycles for "1", 4/14 cycles for "0" + ".macro STOREBIT data:req,done:req\n" + " lsl r20\n" // (1) shift received data + ".if \\data != 0\n" + " ori r20, 1\n" // (1) store "1" bit + ".endif\n" + " dec r21\n" // (1) decrement bit counter + " brne .+22\n" // (1/2) skip if bit counter >0 + " cpi %1, 0\n" // (1) are we verifying? + " brne .+4\n" // (1/2) if yes, jump to verify + " st Z+, r20\n" // (2) store received data byte + " rjmp .+6\n" // (2) skip verify + " ld r21, Z+\n" // (2) get next expected byte + " cpse r20, r21\n" // (1/2) compare to received byte + " rjmp rddiff\n" // (2) jump if different + + " ldi r21, 8\n" // (1) re-initialize bit counter + " subi r26, 1\n" // (1) subtract one from byte counter + " sbci r27, 0\n" // (1) + " brmi \\done\n" // (1/2) done if byte counter<0 + ".endm\n" + + // prepare for reading SYNC + " mov r16, %2\n" // (1) r16 = 2.5 * (MFM bit len) = minimum length of medium pulse + " lsr r16\n" // (1) + " add r16, %2\n" // (1) + " add r16, %2\n" // (1) + " mov r17, r16\n" // (1) r17 = 3.5 * (MFM bit len) = minimum length of long pulse + " add r17, %2\n" // (1) + " ldi %0, 0\n" // (1) default return status is S_OK + " mov r15, %0\n" // (1) initialize timer overflow counter + " sbi TIFR, TOV\n" // (2) reset timer overflow flag + + // wait for at least 80x "10" (short) pulse followed by "100" (medium) pulse + "ws0: ldi r20, 0\n" // (1) initialize "short pulse" counter + "ws1: sbis TIFR, TOV\n" // (1/2) skip next instruction if timer overflow occurred + " rjmp ws2\n" // (2) continue (no overflow) + " sbi TIFR, TOV\n" // (2) reset timer overflow flag + " dec r15\n" // (1) overflow happens every 4.096ms, decrement overflow counter + " brne ws2\n" // (1/2) continue if fewer than 256 overflows + " ldi %0, 3\n" // (1) no sync found in 1.048s => return status is is S_NOSYNC + " rjmp rdend\n" // (2) done + "ws2: inc r20\n" // (1) increment "short pulse" counter + " READPULSE\n" // (9) wait for pulse + " cp r22, r16\n" // (1) pulse length < min medium pulse? + " brlo ws1\n" // (1/2) repeat if so + " cp r22, r17\n" // (1) pulse length < min long pulse? + " brsh ws0\n" // (1/2) restart if this was a long pulse (expecting medium) + " cpi r20, 80\n" // (1) did we see at least 80 short pulses? + " brlo ws0\n" // (1/2) restart if not + + // expect remaining part of first sync mark (..00010010001001) + " READPULSE 3,ws0\n" // (12) expect long pulse (0001) + " READPULSE 2,ws0\n" // (14) expect medium pulse (001) + " READPULSE 3,ws0\n" // (12) expect long pulse (0001) + " READPULSE 2,ws0\n" // (14) expect medium pulse (001) + + // expect second sync mark (0100010010001001) + " READPULSE 1,ws0\n" // (12) expect short pulse (01) + " READPULSE 3,ws0\n" // (12) expect long pulse (0001) + " READPULSE 2,ws0\n" // (14) expect medium pulse (001) + " READPULSE 3,ws0\n" // (12) expect long pulse (0001) + " READPULSE 2,ws0\n" // (14) expect medium pulse (001) + + // expect third sync mark (0100010010001001) + " READPULSE 1,ws0\n" // (12) expect short pulse (01) + " READPULSE 3,ws0\n" // (12) expect long pulse (0001) + " READPULSE 2,ws0\n" // (14) expect medium pulse (001) + " READPULSE 3,ws0\n" // (12) expect long pulse (0001) + " READPULSE 2,ws0\n" // (14) expect medium pulse (001) + + // found SYNC => prepare for reading data + " tst r27\n" // (1) test byte count + " brpl .+2\n" // (1/2) skip following instruction if not negative + " rjmp rdend\n" // (2) nothing to read (only waiting for sync) => end + " ldi r21, 8\n" // (1) initialize bit counter (8 bits per byte) + + // odd section (previous data bit was "1", no unprocessed MFM bit) + // shortest path: 19 cycles, longest path: 34 cycles + // (longest path only happens when finishing a byte, about every 5-6 pulses) + "rdo: READPULSE\n" // (9) wait for pulse + " cp r22, r16\n" // (1) pulse length >= min medium pulse? + " brlo rdos\n" // (1/2) jump if not + " cp r22, r17\n" // (1) pulse length >= min long pulse? + " brlo rdom\n" // (1/2) jump if not + + // long pulse (0001) => read "01", still odd + " STOREBIT 0,rddone\n" // (4/13) store "0" bit + " STOREBIT 1,rddone\n" // (5/14) store "1" bit + " rjmp rdo\n" // (2) back to start (still odd) + + // jump target for relative conditional jumps in STOREBIT macro + "rddone: rjmp rdend\n" + + // medium pulse (001) => read "0", now even + "rdom: STOREBIT 0,rddone\n" // (4/13) store "0" bit + " rjmp rde\n" // (2) back to start (now even) + + // short pulse (01) => read "1", still odd + "rdos: STOREBIT 1,rddone\n" // (5/14) store "1" bit + " rjmp rdo\n" // (2) back to start (still odd) + + // even section (previous data bit was "0", previous MFM "1" bit not yet processed) + // shortest path: 19 cycles, longest path: 31 cycles + "rde: READPULSE\n" // (9) wait for pulse + " cp r22, r16\n" // (1) pulse length >= min medium pulse? + " brlo rdes\n" // (1/2) jump if not + + // either medium pulse (1001) or long pulse (10001) => read "01" + // (a long pulse should never occur in this section but it may just be a + // slightly too long medium pulse so count it as medium) + " STOREBIT 0,rdend\n" // (4/13) store "0" bit + " STOREBIT 1,rdend\n" // (5/14) store "1" bit + " rjmp rdo\n" // (2) back to start (now odd) + + // short pulse (101) => read "0" + "rdes: STOREBIT 0,rdend\n" // (5/14) store "0" bit + " rjmp rde\n" // (2) back to start (still even) + + "rddiff: ldi %0, 8\n" // return status is S_VERIFY (verify error) + "rdend:\n" + + : "=r"(status) // outputs + : "r"(verify), "r"(bitlen), "x"(n-1), "z"(buffer) // inputs (x=r26/r27, z=r30/r31) + : "r15", "r16", "r17", "r18", "r19", "r20", "r21", "r22"); // clobbers + + return status; +} + + +asm (// define WRITEPULSE macro (used in write_data and format_track) + ".macro WRITEPULSE length=0\n" + " .if \\length==1\n" + " sts OCRL, r16\n" // (2) set OCRxA to short pulse length + " .endif\n" + " .if \\length==2\n" + " sts OCRL, r17\n" // (2) set OCRxA to medium pulse length + " .endif\n" + " .if \\length==3\n" + " sts OCRL, r18\n" // (2) set OCRxA to long pulse length + " .endif\n" + " sbis TIFR, OCF\n" // (1/2) skip next instruction if OCFx is set + " rjmp .-4\n" // (2) wait more + " ldi r19, FOC\n" // (1) + " sts TCCRC, r19\n" // (2) set OCP back HIGH (was set LOW when timer expired) + " sbi TIFR, OCF\n" // (2) reset OCFx (output compare flag) + ".endm\n"); + + +static void write_data(byte bitlen, byte *buffer, unsigned int n) +{ + // make sure OC1A is high before we enable WRITE_GATE + OCDDR &= ~bit(OCBIT); // disable OC1A pin + TCCRA = bit(COMA1) | bit(COMA0); // set OC1A on compare match + TCCRC |= bit(FOC); // force compare match + TCCRA = 0; // disable OC1A control by timer + OCDDR |= bit(OCBIT); // enable OC1A pin + + // wait through beginning of header gap (22 bytes of 0x4F) + TCCRB |= bit(WGM2); // WGMx2:10 = 010 => clear-timer-on-compare (CTC) mode + TCNT = 0; // reset timer + OCR = 352 * bitlen - 256; // 352 MFM bit lengths (22 bytes * 8 bits/byte * 2 MFM bits/data bit) * cycles/MFM bit - 16us (overhead) + TIFR = bit(OCF); // clear OCFx + while( !(TIFR & bit(OCF)) ); // wait for OCFx + OCR = 255; // clear OCRH byte (we only modify OCRL below) + TIFR = bit(OCF); // clear OCFx + + // set WRITEGATE to OUTPUT (pulls it low) + WGPORT |= bit(WGBIT); + + // enable OC1A output pin control by timer (WRITE_DATA), initially high + TCCRA = bit(COMA0); // COMxA1:0 = 01 => toggle OC1A on compare match + + asm volatile + (// define GETNEXTBIT macro for getting next data bit into carry (4/9 cycles) + // on entry: R20 contains the current byte + // R21 contains the bit counter + // X (R26/R27) contains the byte counter + // Z (R30/R31) contains pointer to data buffer + ".macro GETNEXTBIT\n" + " dec r21\n" // (1) decrement bit counter + " brpl .+10\n" // (1/2) skip the following if bit counter >= 0 + " subi r26, 1\n" // (1) subtract one from byte counter + " sbci r27, 0\n" // (1) + " brmi wdone\n" // (1/2) done if byte counter <0 + " ld r20, Z+\n" // (2) get next byte + " ldi r21, 7\n" // (1) reset bit counter (7 more bits after this first one) + " rol r20\n" // (1) get next data bit into carry + ".endm\n" + + // initialize pulse-length registers (r16, r17, r18) + " mov r16, %0\n" // r16 = (2*bitlen)-1 = time for short ("01") pulse + " add r16, %0\n" + " dec r16\n" + " mov r17, r16\n" // r17 = (3*bitlen)-1 = time for medium ("001") pulse + " add r17, %0\n" + " mov r18, r17\n" // r18 = (4*bitlen)-1 = time for long ("0001") pulse + " add r18, %0\n" + + // write 12 bytes (96 bits) of "0" (i.e. 96 "10" sequences, i.e. short pulses) + " ldi r20, 0\n" + " sts TCNTL, r20\n" // reset timer + " ldi r20, 96\n" // initialize counter + "wri: WRITEPULSE 1\n" // write short pulse + " dec r20\n" // decremet counter + " brne wri\n" // repeat until 0 + + // first sync "A1": 00100010010001001 + " WRITEPULSE 2\n" // write medium pulse + " WRITEPULSE 3\n" // write long pulse + " WRITEPULSE 2\n" // write medium pulse + " WRITEPULSE 3\n" // write long pulse (this is the missing clock bit) + " WRITEPULSE 2\n" // write medium pulse + + // second sync "A1": 0100010010001001 + " WRITEPULSE 1\n" // write short pulse + " WRITEPULSE 3\n" // write long pulse + " WRITEPULSE 2\n" // write medium pulse + " WRITEPULSE 3\n" // write long pulse (this is the missing clock bit) + " WRITEPULSE 2\n" // write medium pulse + + // third sync "A1": 0100010010001001 + " WRITEPULSE 1\n" // write short pulse + " WRITEPULSE 3\n" // write long pulse + " WRITEPULSE 2\n" // write medium pulse + " WRITEPULSE 3\n" // write long pulse (this is the missing clock bit) + " WRITEPULSE 2\n" // write medium pulse + + // start writing data + " sts OCRL, r16\n" // (2) set up timer for "01" sequence + " ldi r21, 0\n" // (1) initialize bit counter to fetch next byte + + // just wrote a "1" bit => must be followed by either "01" (for "1" bit) or "00" (for "0" bit) + // (have time to fetch next bit during the leading "0") + "wro: GETNEXTBIT\n" // (4/9) fetch next data bit into carry + " brcs wro1\n" // (1/2) jump if "1" + // next bit is "0" => write "00" + " lds r19, OCRL\n" // (2) get current OCRxAL value + " add r19, %0\n" // (2) add one-bit time + " sts OCRL, r19\n" // (2) set new OCRxAL value + " rjmp wre\n" // (2) now even + // next bit is "1" => write "01" + "wro1: WRITEPULSE\n" // (7) wait and write pulse + " sts OCRL, r16\n" // (2) set up timer for another "01" sequence + " rjmp wro\n" // (2) still odd + + // just wrote a "0" bit, (i.e. either "10" or "00") where time for the trailing "0" was already added + // to the pulse length (have time to fetch next bit during the already-added "0") + "wre: GETNEXTBIT\n" // (4/9) fetch next data bit into carry + " brcs wre1\n" // (1/2) jump if "1" + // next bit is "0" => write "10" + " WRITEPULSE\n" // (7) wait and write pulse + " sts OCRL, r16\n" // (2) set up timer for another "10" sequence + " rjmp wre\n" // (2) still even + // next bit is "1" => write "01" + "wre1: lds r19, OCRL\n" // (2) get current OCRxAL value + " add r19, %0\n" // (2) add one-bit time + " sts OCRL, r19\n" // (2) set new OCRxAL value + " WRITEPULSE\n" // (7) wait and write pulse + " sts OCRL, r16\n" // (2) set up timer for "01" sequence + " rjmp wro\n" // (2) now odd + + // done writing + "wdone: WRITEPULSE\n" // (9) wait for and write final pulse + + : // no outputs + : "r"(bitlen), "x"(n), "z"(buffer) // inputs (x=r26/r27, z=r30/r31) + : "r16", "r17", "r18", "r19", "r20", "r21"); // clobbers + + // set WRITEGATE back to input (releases it HIGH) + WGPORT &= ~bit(WGBIT); + + // COMxA1:0 = 00 => disconnect OC1A (will go high) + TCCRA = 0; + + // WGMx2:10 = 000 => Normal timer mode + TCCRB &= ~bit(WGM2); +} + + + +static byte format_track(byte *buffer, byte driveType, byte bitlen, byte track, byte side) +{ + // 3.5" DD disk: + // writing 95 + 1 + 65 + (7 + 37 + 515 + 69) * 8 + (7 + 37 + 515) bytes + // => 5744 bytes per track = 45952 bits + // data rate 250 kbit/second, rotation rate 300 RPM (0.2s per rotation) + // => 50000 bits unformatted capacity per track + + // 3.5" HD disk: + // writing 95 + 1 + 65 + (7 + 37 + 515 + 69) * 17 + (7 + 37 + 515) bytes + // => 5744 bytes per track = 45952 bits + // data rate 500 kbit/second, rotation rate 300 RPM (0.2s per rotation) + // => 100000 bits unformatted capacity per track + byte i; + + byte numsec = geometry[driveType].numSectors; + byte datagaplen = geometry[driveType].dataGap; + + // pre-compute ID records + byte *ptr = buffer; + for(i=0; i clear-timer-on-compare (CTC) mode + TCNT = 0; // reset timer + OCR = 32; // clear OCRxH byte (we only modify OCRxL below) + TIFR = bit(OCF); // clear OCFx + + // set WRITEGATE to OUTPUT (pulls it low) + WGPORT |= bit(WGBIT); + + // enable OC1A output pin control by timer (WRITE_DATA), initially high + TCCRA = bit(COMA0); // COMxA1:0 = 01 => toggle OC1A on compare match + + asm volatile + (".macro WRTPS\n" + " sts OCRL, r16\n" + " call waitp\n" + ".endm\n" + ".macro WRTPM\n" + " sts OCRL, r17\n" + " call waitp\n" + ".endm\n" + ".macro WRTPL\n" + " sts OCRL, r18\n" + " call waitp\n" + ".endm\n" + + // initialize + " mov r16, %0\n" // r16 = (2*bitlen)-1 = time for short ("01") pulse + " add r16, %0\n" + " dec r16\n" + " mov r17, r16\n" // r17 = (3*bitlen)-1 = time for medium ("001") pulse + " add r17, %0\n" + " mov r18, r17\n" // r18 = (4*bitlen)-1 = time for long ("0001") pulse + " add r18, %0\n" + + // 1) ---------- 56x 0x4E (pre-index gap) + // + // 0x4E 0x4E ... + // 0 1 0 0 1 1 1 0 0 1 0 0 1 1 1 0 ... + // 1001001001010100 1001001001010100 ... + // M M M M S S M M M M S S ... + // => (MMMMSS)x56 + " ldi r20, 56\n" // (1) write 56 gap bytes + " call wrtgap\n" // returns 20 cycles after final pulse was written + + // 2) ---------- 12x 0x00 + // + // 0x4E 0x00 0x00 ... + // 0 1 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ... + // 1001001001010100 1010101010101010 1010101010101010 ... + // S M M M S S M S S S S S S S S S S S S S S S ... + // => MSx95 + " WRTPM\n" // write medium pulse + " ldi r20, 95\n" // write 95 short pulses + " call wrtshort\n" // returns 20 cycles after final pulse was written + + // 3) ---------- 3x SYNC 0xC2 + // + // 0x00 0xC2 0xC2 0xC2 + // 0 0 0 0 0 0 0 0 1 1 0 0*0 0 1 0 1 1 0 0*0 0 1 0 1 1 0 0*0 0 1 0 + // 1010101010101010 0101001000100100 0101001000100100 0101001000100100 + // S S S S S S S S M S M L M L S M L M L S M L M + // => MSMLM(LSMLM)x2 + " ldi r20, 3\n" + " WRTPM\n" // write medium pulse (returns 14 cycles after pulse) + " rjmp iskip\n" // (2) + "iloop: WRTPL\n" // write long pulse + "iskip: WRTPS\n" // write short pulse + " WRTPM\n" // write medium pulse + " WRTPL\n" // write long pulse + " WRTPM\n" // write medium pulse + " dec r20\n" // (1) + " brne iloop\n" // (1/2) + + // 4) ---------- index record (0xFC) + // + // 0xC2 0xFC + // 1 1 0 0*0 0 1 0 1 1 1 1 1 1 0 0 + // 0101001000100100 0101010101010010 + // L S M L M L S S S S S M + // => LSSSSSM + " WRTPL\n" // write long pulse (returns 14 cycles after pulse) + " ldi r20, 5\n" // (1) write 5 short pulses + " call wrtshort\n" // 6 cycles until timer update, 20 cycles after pulse + " WRTPM\n" // write medium pulse + + // 5) ---------- 50x 0x4E (post-index gap) + // + // 0xFC 0x4E 0x4E ... + // 1 1 1 1 1 1 0 0 0 1 0 0 1 1 1 0 0 1 0 0 1 1 1 0 ... + // 0101010101010010 1001001001010100 1001001001010100 ... + // L S S S S S M S M M M S S M M M M S S ... + // => SMMMSS (MMMMSS)x49 + " ldi r20, 49\n" // (1) write 49 gap bytes + " WRTPS\n" // write short pulse + " call wrtgap2\n" // returns 20 cycles after final pulse was written + + // 6) ---------- 12x 0x00 + // + // 0x4E 0x00 0x00 ... + // 0 1 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ... + // 1001001001010100 1010101010101010 1010101010101010 ... + // S M M M S S M S S S S S S S S S S S S S S S ... + // => MSx95 + "secstart: WRTPM\n" // write medium pulse + " ldi r20, 95\n" // write 95 short pulses + " call wrtshort\n" // returns 20 cycles after final pulse was written + + // 7) ---------- 3x SYNC 0xA1 + // + // 0x00 0xA1 0xA1 0xA1 + // 0 0 0 0 0 0 0 0 1 0 1 0 0*0 0 1 1 0 1 0 0*0 0 1 1 0 1 0 0*0 0 1 + // 1010101010101010 0100010010001001 0100010010001001 0100010010001001 + // S S S S S S S S M L M L M S L M L M S L M L M + // => MLMLM(SLMLM)x2 + + // do not have sufficient time after final pulse from "wrtsync" call + // => only write two bytes in "wrtsync", write final pulses directly to save time + " ldi r20, 2\n" // only write first two bytes of sync + " call wrtsync\n" // returns 20 cycles after final pulse was written + " WRTPS\n" + " WRTPL\n" + " WRTPM\n" + " WRTPL\n" + " WRITEPULSE 2\n" // write medium pulse, returns 10 cycles after pulse was written + + // 8) ---------- ID record plus first 0x4E: 0xFE (cylinder) (side) (sector) (length) (CRC1) (CRC2) 0x4E) + // + // 0xA1 ... 0x4E + // 1 0 1 0 0*0 0 1 ... 0 1 0 0 1 1 1 0 + // 0100010010001001 ... ??01001001010100 + // S L M L M ... ? ? M M S S + // => (write pre-calculated bytes, starting odd) + // worst case needs 20 cycles before timer is initialized + " sts OCRL, r16\n" // (2) set up timer for "01" sequence + " ldi r21, 0\n" // (1) initialize bit counter to fetch next byte + " ldi r26, 8\n" // (1) initialize byte counter (8 bytes to write) + // just wrote a "1" bit => must be followed by either "01" (for "1" bit) or "00" (for "0" bit) + // (have time to fetch next bit during the leading "0") + "fio: dec r21\n" // (1) decrement bit counter + " brpl fio0\n" // (1/2) skip the following if bit counter >= 0 + " subi r26, 1\n" // (1) subtract one from byte counter + " brmi fidone\n" // (1/2) done if byte counter <0 + " ld r20, Z+\n" // (2) get next byte + " ldi r21, 7\n" // (1) reset bit counter (7 more bits after this first one) + "fio0: rol r20\n" // (1) get next data bit into carry + " brcs fio1\n" // (1/2) jump if "1" + // next bit is "0" => write "00" + " lds r19, OCRL\n" // (2) get current OCRxAL value + " add r19, %0\n" // (2) add one-bit time + " sts OCRL, r19\n" // (2) set new OCRxAL value + " rjmp fie\n" // (2) now even + // next bit is "1" => write "01" + "fio1: WRITEPULSE\n" // (7) wait and write pulse + " sts OCRL, r16\n" // (2) set up timer for another "01" sequence + " rjmp fio\n" // (2) still odd + // just wrote a "0" bit, (i.e. either "10" or "00") where time for the trailing "0" was already added + // to the pulse length (have time to fetch next bit during the already-added "0") + "fie: dec r21\n" // (1) decrement bit counter + " brpl fie0\n" // (1/2) skip the following if bit counter >= 0 + " subi r26, 1\n" // (1) subtract one from byte counter + " brmi fidone\n" // (1/2) done if byte counter <0 + " ld r20, Z+\n" // (2) get next byte + " ldi r21, 7\n" // (1) reset bit counter (7 more bits after this first one) + "fie0: rol r20\n" // (1) get next data bit into carry + " brcs fie1\n" // (1/2) jump if "1" + // next bit is "0" => write "10" + " WRITEPULSE\n" // (7) wait and write pulse + " sts OCRL, r16\n" // (2) set up timer for another "10" sequence + " rjmp fie\n" // (2) still even + // next bit is "1" => write "01" + "fie1: lds r19, OCRL\n" // (2) get current OCRxAL value + " add r19, %0\n" // (2) add one-bit time + " sts OCRL, r19\n" // (2) set new OCRxAL value + " WRITEPULSE\n" // (7) wait and write pulse + " sts OCRL, r16\n" // (2) set up timer for "01" sequence + " rjmp fio\n" // (2) now odd + "fidone: \n" + + // 9) ---------- 21x 0x4E (post-ID gap) + // + // 0x4E 0x4E ... + // 0 1 0 0 1 1 1 0 0 1 0 0 1 1 1 0 ... + // 1001001001010100 1001001001010100 ... + // S M M M S S M M M M S S ... + // => (MMMMSS)x21 + " ldi r20, 21\n" // (1) write 21 gap bytes + " call wrtgap\n" // returns 20 cycles after final pulse was written + + // 10) ---------- 12x 0x00 + // + // 0x4E 0x00 0x00 ... + // 0 1 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ... + // 1001001001010100 1010101010101010 1010101010101010 ... + // S M M M S S M S S S S S S S S S S S S S S S ... + // => MSx95 + " WRTPM\n" // write medium pulse + " ldi r20, 95\n" // write 95 short pulses + " call wrtshort\n" // returns 20 cycles after final pulse was written + + // 11) ---------- 3x SYNC 0xA1 + // + // 0x00 0xA1 0xA1 0xA1 + // 0 0 0 0 0 0 0 0 1 0 1 0 0*0 0 1 1 0 1 0 0*0 0 1 1 0 1 0 0*0 0 1 + // 1010101010101010 0100010010001001 0100010010001001 0100010010001001 + // S S S S S S S S M L M L M S L M L M S L M L M + // => MLMLM(SLMLM)x2 + " ldi r20, 3\n" // write three sync bytes + " call wrtsync\n" // returns 20 cycles after final pulse was written + + // 12) ---------- data record 0xFB + // + // 0xA1 0xFB + // 1 0 1 0 0*0 0 1 1 1 1 1 1 0 1 1 + // 0100010010001001 0101010101000101 + // S L M L M S S S S S L S + // => SSSSSLS + " ldi r20, 5\n" // write 5 short pulses + " call wrtshort\n" // returns 20 cycles after final pulse was written + " WRTPL\n" // write long pulse + " WRTPS\n" // write short pulse + + // 13) ---------- data (512x 0xF6) + // + // 0xFB 0xF6 0xF6 ... + // 1 1 1 1 1 0 1 1 1 1 1 1 0 1 1 0 1 1 1 1 0 1 1 0 ... + // 0101010101000101 0101010100010100 0101010100010100 ... + // S S S S S L S S S S S L S L S S S L S ... + // => SSSSLS LSSSLS + " ldi r26, 0\n" // write 2*256+0 = 512 bytes + " ldi r27, 2\n" + " WRTPS\n" // write short pulse + " rjmp dskip\n" + "dloop: WRTPL\n" // write long pulse + "dskip: WRTPS\n" // write short pulse + " WRTPS\n" // write short pulse + " WRTPS\n" // write short pulse + " WRTPL\n" // write long pulse + " WRTPS\n" // write short pulse + " dec r26\n" // decrement byte counter (low) + " brne dloop\n" // loop until 0 + " dec r27\n" // decrement byte counter (high) + " brne dloop\n" // loop until 0 + + // 14) ---------- data checksum (0x2B, 0xF6) + // + // 0xF6 0x2B 0xF6 + // 1 1 1 1 0 1 1 0 0 0 1 0 1 0 1 1 1 1 1 1 0 1 1 0 + // 0101010100010100 1010010001000101 0101010100010100 + // L S S S L S M S M L L S S S S S L S + // => MSMLSLSSSSLS + " WRTPM\n" // write medium pulse + " WRTPS\n" // write short pulse + " WRTPM\n" // write medium pulse + " WRTPL\n" // write long pulse + " WRTPL\n" // write short pulse + " WRTPS\n" // write long pulse + " WRTPS\n" // write short pulse + " WRTPS\n" // write short pulse + " WRTPS\n" // write short pulse + " WRTPS\n" // write short pulse + " WRTPL\n" // write long pulse + " WRTPS\n" // write short pulse + + // if this was the last sector then the track is done + " dec %1\n" // (1) decrement sector counter + " breq ftdone\n" // (1/2) jump if done + + // 15) ---------- 54/102x 0x4E (post-data gap) + // + // 0xF6 0x4E 0x4E ... + // 1 1 1 1 0 1 1 0 0 1 0 0 1 1 1 0 0 1 0 0 1 1 1 0 ... + // 0101010100010100 1001001001010100 1001001001010100 ... + // S S S S L S M M M M S S ... + // => (MMMMSS) x datagaplen + " mov r20, %2\n" // (1) write "datagaplen" gap bytes + " call wrtgap\n" // returns 20 cycles after final pulse was written + " rjmp secstart\n" // (2) repeat for next sector + + // ---------- track format done => write GAP bytes (0x4E) until INDEX hole seen + "ftdone: ldi r20, 1\n" // (1) write one byte + " call wrtgap\n" // returns 20 cycles after final pulse was written + " lds r20, IDXPORT\n" // (2) read INDEX signal + " sbrc r20, IDXBIT\n" // (1/2) skip next instruction if PIND7 (INDEX) is LOW + " rjmp ftdone\n" // (2) write more gap bytes + " rjmp ftend\n" // done + + // -------------- subroutines + + // write short pulses + // r20 contains number of short pulses to write + // => takes 6 cycles until timer is initialized (including call) + // => returns 20 cycles (max) after final pulse is written (including return statement) + "wrtshort: WRTPS\n" + " dec r20\n" // (1) + " brne wrtshort\n" // (1/2) + " ret\n" // (4) + + // write gap (0x4E) => (MMMMSS) x r20 + // r20 contains number of gap bytes to write + // => takes 6 cycles until timer is initialized (including call) + // => returns 20 cycles (max) after final pulse is written (including return statement) + "wrtgap: WRTPM\n" + "wrtgap2: WRTPM\n" + " WRTPM\n" + " WRTPM\n" + " WRTPS\n" + " WRTPS\n" + " dec r20\n" // (1) + " brne wrtgap\n" // (1/2) + " ret\n" // (4) + + // write SYNC (0xA1 with missing clock bit) => MLMLM (SLMLM) x r20 + // r20 contains nyumber of SYNC bytes to write + // => takes 7 cycles until timer is initialized (including call) + // => returns 20 cycles (max) after final pulse is written (including return statement) + "wrtsync: WRTPM\n" // write medium pulse (returns 14 cycles after pulse) + " rjmp sskip\n" // (2) + "sloop: WRTPS\n" // write short pulse + "sskip: WRTPL\n" // write long pulse + " WRTPM\n" // write medium pulse + " WRTPL\n" // write long pulse + " WRTPM\n" // write medium pulse + " dec r20\n" // (1) + " brne sloop\n" // (1/2) + " ret\n" // (4) return + + // wait for pulse to be written + // => returns 14 cycles (max) after pulse is written (including return statement) + "waitp: sbis TIFR, OCF\n" // (1/2) skip next instruction if OCFx is set + " rjmp .-4\n" // (2) wait more + " ldi r19, FOC\n" // (1) + " sts TCCRC, r19\n" // (2) set OCP back HIGH (was set LOW when timer expired) + " sbi TIFR, OCF\n" // (2) reset OCFx (output compare flag) + " ret\n" // (4) return + + "ftend:\n" + + : // no outputs + : "r"(bitlen), "r"(numsec), "r"(datagaplen), "z"(buffer) // inputs (z=r30/r31) + : "r16", "r17", "r18", "r19", "r20", "r21", "r26", "r27"); // clobbers + + // set WRITEGATE back to input (releases it HIGH) + WGPORT &= ~bit(WGBIT); + + // COMxA1:0 = 00 => disconnect OC1A (will go high) + TCCRA = 0; + + // WGMx2:10 = 000 => Normal timer mode + TCCRB &= ~bit(WGM2); + + interrupts(); + + return S_OK; +} + + +static byte wait_header(byte bitlen, byte track, byte side, byte sector) +{ + byte attempts = 50; + + // check whether we can see any data pulses from the drive at all + if( !check_pulse() ) + { +#ifdef DEBUG + Serial.println(F("Drive not ready!")); Serial.flush(); +#endif + return S_NOTREADY; + } + + do + { + // wait for sync sequence and read 7 bytes of data + byte status = read_data(bitlen, header, 7, false); + + if( status==S_OK ) + { + // make sure this is an ID record and check whether it contains the + // expected track/side/sector information and the CRC is ok + if( header[0]==0xFE && (track==0xFF || track==header[1]) && side==header[2] && sector==header[3] ) + { + if( calc_crc(header, 5) == 256u*header[5]+header[6] ) + return S_OK; +#ifdef DEBUG + else + { Serial.println(F("Header CRC error!")); Serial.flush(); } +#endif + } +#ifdef DEBUG + else + { + static const char hex[17] = "0123456789ABCDEF"; + Serial.write('H'); + for(byte i=0; i<5; i++) { Serial.write(hex[header[i]/16]); Serial.write(hex[header[i]&15]); } + Serial.write(calc_crc(header, 5) == 256u*header[5]+header[6] ? '+' : '-'); + Serial.write(10); + } +#endif + } + else + return status; + } + while( --attempts>0 ); + +#ifdef DEBUG + if( attempts==0 ) + { Serial.println(F("Unable to find header!")); Serial.flush(); } +#endif + + return S_NOHEADER; +} + + +static void step_track() +{ + // produce LOW->HIGH pulse on STEP pin + digitalWriteOC(PIN_STEP, LOW); + delay(1); + digitalWriteOC(PIN_STEP, HIGH); + delay(10); +} + + +static bool step_to_track0() +{ + byte n = 82; + + // step outward until TRACK0 line goes low + digitalWriteOC(PIN_STEPDIR, HIGH); + while( --n > 0 && digitalRead(PIN_TRACK0) ) step_track(); + + if( n==0 ) + { + // we have stpped for more than 80 tracks and are still not + // seeing the TRACK0 signal +#ifdef DEBUG + Serial.println(F("No Track0 signal!")); Serial.flush(); +#endif + return false; + } + + return true; +} + + +static void step_tracks(byte driveType, int tracks) +{ + // if tracks<0 then step outward (outward towards track 0) otherwise step inward + digitalWriteOC(PIN_STEPDIR, tracks<0 ? HIGH : LOW); + tracks = abs(tracks); + tracks = tracks * geometry[driveType].trackSpacing; + while( tracks-->0 ) step_track(); + delay(100); +} + + +static byte find_sector(byte driveType, byte bitLength, byte track, byte side, byte sector) +{ + // select side + digitalWriteOC(PIN_SIDE, side>0 ? LOW : HIGH); + + // wait for sector header + byte res = wait_header(bitLength, -1, side, sector); + + // if we found the sector header but it's not on the correct track then step to correct track and check again + if( res==S_OK && header[1]!=track ) + { + // make sure that the track number in the header we read is sensible + if( header[1] 32 cycles/bit + // for 360 RPM (166 ms/rotation) data rate is 300 mbps => 27 cycles/bit + bitLength = l > 180000 ? 32 : 27; + break; + } + } + + m_bitLength[m_currentDrive] = bitLength; + } + + return m_bitLength[m_currentDrive]; +} + + +byte ArduinoFDCClass::readSector(byte track, byte side, byte sector, byte *buffer) +{ + byte res = S_OK; + byte driveType = m_driveType[m_currentDrive]; + + // do some sanity checks + if( !m_initialized ) + return S_NOTINIT; + else if( track>=geometry[driveType].numTracks || sector<1 || sector>geometry[driveType].numSectors || side>1 ) + return S_NOHEADER; + + // if motor is not running then turn it on now + bool turnMotorOff = false; + if( !motorRunning() ) + { + turnMotorOff = true; + motorOn(); + } + + // assert DRIVE_SELECT + driveSelect(LOW); + + // get MFM bit length (in processor cycles, motor must be running for this) + byte bitLength = getBitLength(); + + if( bitLength==0 ) + res = S_NOTREADY; + else + { + // set up timer + TCCRA = 0; + TCCRB = bit(CS0); // falling edge input capture, prescaler 1, no output compare + TCCRC = 0; + + // reading data is time sensitive so we can't have interrupts + noInterrupts(); + + // find the requested sector + res = find_sector(driveType, bitLength, track, side, sector); + + // if we found the sector then read the data + if( res==S_OK ) + { + // wait for data sync mark and read data + if( read_data(bitLength, buffer, 515, false)==S_OK ) + { + if( buffer[0]!=0xFB ) + { +#ifdef DEBUG + Serial.println(F("Unexpected record identifier")); + for(int i=0; i<7; i++) { Serial.print(buffer[i], HEX); Serial.write(' '); } + Serial.println(); +#endif + res = S_INVALIDID; + } + else if( calc_crc(buffer, 513) != 256u*buffer[513]+buffer[514] ) + { +#ifdef DEBUG + Serial.print(F("Data CRC error. Found: ")); Serial.print(256u*buffer[513]+buffer[514], HEX); Serial.print(", expected: "); Serial.println(calc_crc(buffer, 513), HEX); +#endif + res = S_CRC; + } + } + } + + // interrupts are ok again + interrupts(); + + // stop timer + TCCRB = 0; + } + + // de-assert DRIVE_SELECT + driveSelect(HIGH); + + // if we turned the motor on then turn it off again + if( turnMotorOff ) motorOff(); + + return res; +} + + +byte ArduinoFDCClass::writeSector(byte track, byte side, byte sector, byte *buffer, bool verify) +{ + byte res = S_OK; + byte driveType = m_driveType[m_currentDrive]; + + // do some sanity checks + if( !m_initialized ) + return S_NOTINIT; + else if( track>=geometry[driveType].numTracks || sector<1 || sector>geometry[driveType].numSectors || side>1 ) + return S_NOHEADER; + + // if motor is not running then turn it on now + bool turnMotorOff = false; + if( !motorRunning() ) + { + turnMotorOff = true; + motorOn(); + } + + // assert DRIVE_SELECT + driveSelect(LOW); + + // get MFM bit length (in processor cycles, motor must be running for this) + byte bitLength = getBitLength(); + + // set up timer + TCCRA = 0; + TCCRB = bit(CS0); // falling edge input capture, prescaler 1, no output compare + TCCRC = 0; + + // check write protect (drive must be selected for this) + if( bitLength==0 ) + res = S_NOTREADY; + else if( is_write_protected() ) + res = wait_index_hole() ? S_READONLY : S_NOTREADY; + else + { + // calculate CRC for the sector data + buffer[0] = 0xFB; // "data" id + uint16_t crc = calc_crc(buffer, 513); + buffer[513] = crc/256; + buffer[514] = crc&255; + buffer[515] = 0x4E; // first byte of post-data gap + + // writing data is time sensitive so we can't have interrupts + noInterrupts(); + + // find the requested sector + res = find_sector(driveType, bitLength, track, side, sector); + + // if we found the sector then write the data + if( res==S_OK ) + { + // write the sector data + write_data(bitLength, buffer, 516); + + // if we are supposed to verify the data then do so now + if( verify ) + { + // wait for sector to come around again + res = wait_header(bitLength, track, side, sector); + + // wait for data sync mark and compare the data + if( res==S_OK ) res = read_data(bitLength, buffer, 515, true); + } + } + + // interrupts are ok again + interrupts(); + } + + // de-assert DRIVE_SELECT + driveSelect(HIGH); + + // stop timer + TCCRB = 0; + + // if we turned the motor on then turn it off again + if( turnMotorOff ) motorOff(); + + return res; +} + + +byte ArduinoFDCClass::formatDisk(byte *buffer, byte fromTrack, byte toTrack) +{ + byte res = S_OK; + byte driveType = m_driveType[m_currentDrive]; + byte numTracks = geometry[driveType].numTracks; + + // do some sanity checks + if( !m_initialized ) + return S_NOTINIT; + else if( fromTrack>toTrack || fromTrack >= numTracks ) + return S_OK; + + // if motor is not running then turn it on now + bool turnMotorOff = false; + if( !motorRunning() ) + { + turnMotorOff = true; + motorOn(); + } + + // assert DRIVE_SELECT + driveSelect(LOW); + + // get MFM bit length (in processor cycles, motor must be running for this) + byte bitLength = getBitLength(); + + // set up timer + TCCRA = 0; + TCCRB = bit(CS0); // prescaler 1 + TCCRC = 0; + + if( bitLength==0 || !wait_index_hole() ) + res = S_NOTREADY; + else if( is_write_protected() ) + res = S_READONLY; + else if( !step_to_track0() ) + res = S_NOTRACK0; + else + { + if( fromTrack>0 ) step_tracks(driveType, fromTrack); + if( toTrack>=numTracks ) toTrack = numTracks-1; + for(byte track=fromTrack; track<=toTrack; track++) + { + digitalWriteOC(PIN_SIDE, HIGH); + res = format_track(buffer, driveType, bitLength, track, 0); if( res!=S_OK ) break; + digitalWriteOC(PIN_SIDE, LOW); + res = format_track(buffer, driveType, bitLength, track, 1); if( res!=S_OK ) break; + if( track+1<=toTrack ) step_tracks(driveType, 1); + } + } + + // de-assert DRIVE_SELECT + driveSelect(HIGH); + + // if we turned the motor on then turn it off again + if( turnMotorOff ) motorOff(); + + // stop timer + TCCRB = 0; + + return res; +} + + +void ArduinoFDCClass::motorOn() +{ + if( !motorRunning() ) + { +#if defined(PIN_MOTORB) && defined(PIN_SELECTB) + digitalWriteOC(m_currentDrive==0 ? PIN_MOTORA : PIN_MOTORB, LOW); +#else + digitalWriteOC(PIN_MOTORA, LOW); +#endif + + m_motorState[m_currentDrive] = true; + + // allow some time for the motor to spin up + delay(1000); + } +} + + +void ArduinoFDCClass::motorOff() +{ +#if defined(PIN_MOTORB) && defined(PIN_SELECTB) + digitalWriteOC(m_currentDrive==0 ? PIN_MOTORA : PIN_MOTORB, HIGH); +#else + digitalWriteOC(PIN_MOTORA, HIGH); +#endif + + m_motorState[m_currentDrive] = false; +} + + +bool ArduinoFDCClass::motorRunning() const +{ + return m_motorState[m_currentDrive]; +} + + + +bool ArduinoFDCClass::selectDrive(byte drive) +{ + if( drive == m_currentDrive ) + return true; + else + { +#if defined(PIN_MOTORB) && defined(PIN_SELECTB) + m_currentDrive = (drive==0) ? 0 : 1; + setDensityPin(); + return true; +#else +#ifdef DEBUG + if( drive!=0 ) Serial.println(F("PIN_MOTORB and/or PIN_SELECTB not defined - Can only control drive A")); +#endif + return false; +#endif + } +} + + +bool ArduinoFDCClass::haveDisk() const +{ + bool res = false; + + // set up and start timer (prescaler 1), select drive + TCCRA = 0; + TCCRB = bit(CS0); + TCCRC = 0; + driveSelect(LOW); + + if( motorRunning() ) + res = wait_index_hole(); + else + { +#if defined(PIN_MOTORB) && defined(PIN_SELECTB) + digitalWriteOC(m_currentDrive==0 ? PIN_MOTORA : PIN_MOTORB, LOW); + res = wait_index_hole(); + digitalWriteOC(m_currentDrive==0 ? PIN_MOTORA : PIN_MOTORB, HIGH); +#else + digitalWriteOC(PIN_MOTORA, LOW); + res = wait_index_hole(); + digitalWriteOC(PIN_MOTORA, HIGH); +#endif + } + + // de-select drive, stop timer + driveSelect(HIGH); + TCCRB = 0; + + return res; +} + + +bool ArduinoFDCClass::isWriteProtected() const +{ + bool res = false; + +#if defined(PIN_WRITEPROT) + driveSelect(LOW); + res = is_write_protected(); + driveSelect(HIGH); +#endif + + return res; +} + + +byte ArduinoFDCClass::selectedDrive() const +{ + return m_currentDrive; +} + + +byte ArduinoFDCClass::numTracks() const +{ + return geometry[m_driveType[m_currentDrive]].numTracks; +} + + +byte ArduinoFDCClass::numSectors() const +{ + return geometry[m_driveType[m_currentDrive]].numSectors; +} diff --git a/trunk/Arduino/ArduinoFDC/ArduinoFDC.h b/trunk/Arduino/ArduinoFDC/ArduinoFDC.h new file mode 100644 index 00000000..d233c032 --- /dev/null +++ b/trunk/Arduino/ArduinoFDC/ArduinoFDC.h @@ -0,0 +1,140 @@ +// ----------------------------------------------------------------------------- +// 3.5"/5.25" DD/HD Disk controller for Arduino +// Copyright (C) 2021 David Hansel +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// ----------------------------------------------------------------------------- + +#ifndef ARDUINOFDC_H +#define ARDUINOFDC_H + +#include "Arduino.h" + +// return status for readSector/writeSector and formatDisk functions +#define S_OK 0 // no error +#define S_NOTINIT 1 // ArduinoFDC.begin() was not called +#define S_NOTREADY 2 // Drive is not ready (no disk or power) +#define S_NOSYNC 3 // No sync marks found +#define S_NOHEADER 4 // Sector header not found +#define S_INVALIDID 5 // Sector data record has invalid id +#define S_CRC 6 // Sector data checksum error +#define S_NOTRACK0 7 // No track0 signal +#define S_VERIFY 8 // Verify after write failed +#define S_READONLY 9 // Attempt to write to a write-protected disk + +class ArduinoFDCClass +{ + public: + + enum DriveType { + DT_5_DD, // 5.25" double density (360 KB) + DT_5_DDonHD, // 5.25" double density disk in high density drive (360 KB) + DT_5_HD, // 5.25" high density (1.2 MB) + DT_3_DD, // 3.5" double density (720 KB) + DT_3_HD // 3.5" high density (1.44 MB) + }; + + enum DensityPinMode { + DP_DISCONNECT = 0, // density pin disconnected (set to INPUT mode) + DP_OUTPUT_LOW_FOR_HD, // density pin goes LOW for high density disk + DP_OUTPUT_LOW_FOR_DD // density pin goes LOW for double density disk + }; + + ArduinoFDCClass(); + + // Initialize pins used for controlling the disk drive + void begin(enum DriveType driveAType = DT_3_HD, enum DriveType driveBType = DT_3_HD); + + // Release pins used for controlling the disk drive + void end(); + + // Select drive A(0) or B(1). + bool selectDrive(byte drive); + + // Returns which drive is currently selected, A (0) or B (1) + byte selectedDrive() const; + + // set the drive type for the currently selected drive + void setDriveType(enum DriveType type); + + // get the type of the currently selected drive + enum DriveType getDriveType() const; + + // returns true if a disk is detected in the drive + bool haveDisk() const; + + // returns true if the disk is write protected + bool isWriteProtected() const; + + // get number of tracks for the currently selected drive + byte numTracks() const; + + // get number of sectors for the currently selected drive + byte numSectors() const; + + // set the density pin mode for the currently selected drive + void setDensityPinMode(enum DensityPinMode mode); + + // Read a sector from disk, + // buffer MUST have a size of at least 516 bytes. + // IMPORTANT: On successful return, the 512 bytes of sector data + // read will be in buffer[1..512] (NOT: 0..511!) + // See error codes above for possible return values + byte readSector(byte track, byte side, byte sector, byte *buffer); + + // Write a sector to disk, + // buffer MUST have a size of at least 516 bytes. + // IMPORTANT: The 512 bytes of sector data to be written + // must be in buffer[1..512] (NOT: 0..511!) + // if "verify" is true then the data will be re-read after writing + // and compared to the data just written. + // See error codes above for possible return values + byte writeSector(byte track, byte side, byte sector, byte *buffer, bool verify); + + // Formats a disk + // buffer is needed to store temporary data while formatting and MUST have + // a size of at least 144 bytes. + // All sector data is initialized with 0xF6. + // See error codes above for possible return values + // IMPORTANT: No DOS file system is initialized, i.e. DOS or Windows + // will NOT recognize this as a valid disk + byte formatDisk(byte *buffer, byte fromTrack=0, byte toTrack=255); + + // Turn the disk drive motor on. The readSector/writeSector/formatDisk + // functions will turn on the motor automatically if it is not running + // yet. In that case (and ONLY then) they will also turn it off when finished. + void motorOn(); + + // Turn the disk drive motor off + void motorOff(); + + // Returns true if the disk drive motor is currently running + bool motorRunning() const; + + private: + void driveSelect(bool state) const; + void setDensityPin(); + byte getBitLength(); + + enum DriveType m_driveType[2]; + enum DensityPinMode m_densityPinMode[2]; + byte m_currentDrive, m_bitLength[2]; + bool m_initialized, m_motorState[2]; +}; + + +extern ArduinoFDCClass ArduinoFDC; + +#endif diff --git a/trunk/Arduino/ArduinoFDC/ArduinoFDC.ino b/trunk/Arduino/ArduinoFDC/ArduinoFDC.ino new file mode 100644 index 00000000..8af3159c --- /dev/null +++ b/trunk/Arduino/ArduinoFDC/ArduinoFDC.ino @@ -0,0 +1,990 @@ +// ----------------------------------------------------------------------------- +// 3.5"/5.25" DD/HD Disk controller for Arduino +// Copyright (C) 2021 David Hansel +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// ----------------------------------------------------------------------------- + +#include "ArduinoFDC.h" +#include "ff.h" + + +// comment this out to remove high-level ArduDOS functions +#define USE_ARDUDOS + +// commenting this out will remove the low-level disk monitor +#define USE_MONITOR + +// comenting this out will remove support for XModem data transfers +//#define USE_XMODEM + + +#if defined(__AVR_ATmega32U4__) && defined(USE_ARDUDOS) && (defined(USE_MONITOR) || defined(USE_XMODEM)) +#warning "Arduino Leonardo/Micro program memory is too small to support ArduDOS together with other components!" +#undef USE_MONITOR +#undef USE_XMODEM +#endif + +// ------------------------------------------------------------------------------------------------- +// Basic helper functions +// ------------------------------------------------------------------------------------------------- + +#define TEMPBUFFER_SIZE 80 +byte tempbuffer[TEMPBUFFER_SIZE]; + +unsigned long motor_timeout = 0; + + +void print_hex(byte b) +{ + if( b<16 ) Serial.write('0'); + Serial.print(b, HEX); +} + + +void dump_buffer(int offset, byte *buf, int n) +{ + int i = 0; + while( i0 ) + { Serial.write(8); Serial.write(' '); Serial.write(8); l--; } + } + else if( isprint(i) && l0 && millis() > motor_timeout ) { ArduinoFDC.motorOff(); motor_timeout = 0; } + } + while(true); + + while( l>0 && isspace(buf[l-1]) ) l--; + buf[l] = 0; + return buf; +} + + +bool confirm_formatting() +{ + int c; + Serial.print(F("Formatting will erase all data on the disk in drive ")); + Serial.write('A' + ArduinoFDC.selectedDrive()); + Serial.print(F(". Continue (y/n)?")); + while( (c=Serial.read())<0 ); + do { delay(1); } while( Serial.read()>=0 ); + Serial.println(); + return c=='y'; +} + + +void print_drive_type(byte n) +{ + switch( n ) + { + case ArduinoFDCClass::DT_5_DD: Serial.print(F("5.25\" DD")); break; + case ArduinoFDCClass::DT_5_DDonHD: Serial.print(F("5.25\" DD disk in HD drive")); break; + case ArduinoFDCClass::DT_5_HD: Serial.print(F("5.25\" HD")); break; + case ArduinoFDCClass::DT_3_DD: Serial.print(F("3.5\" DD")); break; + case ArduinoFDCClass::DT_3_HD: Serial.print(F("3.5\" HD")); break; + default: Serial.print(F("Unknown")); + } +} + + +void print_error(byte n) +{ + Serial.print(F("Error: ")); + switch( n ) + { + case S_OK : Serial.print(F("No error")); break; + case S_NOTINIT : Serial.print(F("ArduinoFDC.begin() was not called")); break; + case S_NOTREADY : Serial.print(F("Drive not ready")); break; + case S_NOSYNC : Serial.print(F("No sync marks found")); break; + case S_NOHEADER : Serial.print(F("Sector header not found")); break; + case S_INVALIDID : Serial.print(F("Data record has unexpected id")); break; + case S_CRC : Serial.print(F("Data checksum error")); break; + case S_NOTRACK0 : Serial.print(F("No track 0 signal detected")); break; + case S_VERIFY : Serial.print(F("Verify after write failed")); break; + case S_READONLY : Serial.print(F("Disk is write protected")); break; + default : Serial.print(F("Unknonwn error")); break; + } + Serial.println('!'); +} + + +void set_drive_type(int n) +{ + ArduinoFDC.setDriveType((ArduinoFDCClass::DriveType) n); + Serial.print(F("Setting disk type for drive ")); Serial.write('A'+ArduinoFDC.selectedDrive()); + Serial.print(F(" to ")); print_drive_type(ArduinoFDC.getDriveType()); + Serial.println(); +} + + +// ------------------------------------------------------------------------------------------------- +// XModem data transfer functions +// ------------------------------------------------------------------------------------------------- + + +int recvChar(int msDelay) +{ + unsigned long start = millis(); + while( (int) (millis()-start) < msDelay) + { + if( Serial.available() ) return (uint8_t) Serial.read(); + } + + return -1; +} + + +void sendData(const char *data, int size) +{ + Serial.write((const uint8_t *) data, size); +} + + +// ------------------------------------------------------------------------------------------------- +// High-level ArduDOS +// ------------------------------------------------------------------------------------------------- + + +#ifdef USE_ARDUDOS + +static FATFS FatFs; +static FIL FatFsFile; + +#ifdef USE_XMODEM + +#include "XModem.h" +FRESULT xmodem_status = FR_OK; + +bool xmodemHandlerSend(unsigned long no, char* data, int size) +{ + UINT br; + xmodem_status = f_read(&FatFsFile, data, size, &br); + + // if there is an error or there is nothing more to read then return + if( xmodem_status != FR_OK || br==0 ) return false; + + // XMODEM sends blocks of 128 bytes so if we have less than that + // fill the rest of the buffer with EOF (ASCII 26) characters + while( (int) br")); + char *cmd = read_user_cmd(tempbuffer, TEMPBUFFER_SIZE); + + if( strcmp_PF(cmd, PSTR("a:"))==0 || strcmp_PF(cmd, PSTR("b:"))==0 ) + { + byte drive = cmd[0]-'a'; + if( drive != ArduinoFDC.selectedDrive() ) + { + ArduinoFDC.motorOff(); + motor_timeout = 0; + ArduinoFDC.selectDrive(drive); + } + + f_mount(&FatFs, "0:", 0); + } + else if( strncmp_P(cmd, PSTR("dir"), 3)==0 ) + { + DIR dir; + FILINFO finfo; + + ArduinoFDC.motorOn(); + fr = f_opendir(&dir, strlen(cmd)<5 ? "0:\\" : cmd+4); + if (fr == FR_OK) + { + count = 0; + while(1) + { + fr = f_readdir(&dir, &finfo); + if( fr!=FR_OK || finfo.fname[0]==0 ) + break; + + char *c = finfo.fname; + byte col = 0; + while( *c!=0 && *c!='.' ) { Serial.write(toupper(*c)); col++; c++; } + while( col<9 ) { Serial.write(' '); col++; } + if( *c=='.' ) + { + c++; + while( *c!=0 ) { Serial.write(toupper(*c)); col++; c++; } + } + while( col<14 ) { Serial.write(' '); col++; } + if( finfo.fattrib & AM_DIR ) + Serial.println(F("")); + else + Serial.println(finfo.fsize); + count++; + } + + f_closedir(&dir); + + if( fr==FR_OK ) + { + if( count==0 ) Serial.println(F("No files.")); + + FATFS *fs; + DWORD fre_clust; + fr = f_getfree("0:", &fre_clust, &fs); + + if( fr==FR_OK ) + { Serial.print(fre_clust * fs->csize * 512); Serial.println(F(" bytes free.")); } + } + + if( fr!=FR_OK ) + print_ff_error(fr); + } + else + print_ff_error(fr); + } + else if( strncmp_P(cmd, PSTR("type "), 5)==0 ) + { + ArduinoFDC.motorOn(); + fr = f_open(&FatFsFile, cmd+5, FA_READ); + if( fr == FR_OK ) + { + count = 1; + while( count>0 ) + { + fr = f_read(&FatFsFile, tempbuffer, TEMPBUFFER_SIZE, &count); + if( fr == FR_OK ) + Serial.write(tempbuffer, count); + else + print_ff_error(fr); + } + f_close(&FatFsFile); + } + else + print_ff_error(fr); + } + else if( strncmp_P(cmd, PSTR("dump "), 5)==0 ) + { + ArduinoFDC.motorOn(); + fr = f_open(&FatFsFile, cmd+5, FA_READ); + if( fr == FR_OK ) + { + count = 1; + int offset = 0; + while( count>0 ) + { + fr = f_read(&FatFsFile, tempbuffer, (TEMPBUFFER_SIZE/16)*16, &count); + if( fr == FR_OK ) + { dump_buffer(offset, tempbuffer, count); offset += count; } + else + print_ff_error(fr); + } + f_close(&FatFsFile); + } + else + print_ff_error(fr); + } + else if( strncmp_P(cmd, PSTR("write "), 6)==0 ) + { + ArduinoFDC.motorOn(); + fr = f_open(&FatFsFile, cmd+6, FA_WRITE | FA_CREATE_NEW); + if( fr == FR_OK ) + { + motor_timeout = 0; + while( true ) + { + char *s = read_user_cmd(tempbuffer, TEMPBUFFER_SIZE); + if( s[0] ) + { + fr = f_write(&FatFsFile, s, strlen(cmd), &count); + if( fr==FR_OK ) fr = f_write(&FatFsFile, "\r\n", 2, &count); + if( fr!=FR_OK ) print_ff_error(fr); + } + else + break; + } + + f_close(&FatFsFile); + } + else + print_ff_error(fr); + } + else if( strncmp_P(cmd, PSTR("del "), 4)==0 ) + { + ArduinoFDC.motorOn(); + fr = f_unlink(cmd+4); + if( fr != FR_OK ) + print_ff_error(fr); + } + else if( strncmp_P(cmd, PSTR("mkdir "), 6)==0 ) + { + ArduinoFDC.motorOn(); + fr = f_mkdir(cmd+6); + if( fr != FR_OK ) + print_ff_error(fr); + } + else if( strncmp_P(cmd, PSTR("rmdir "), 6)==0 ) + { + ArduinoFDC.motorOn(); + fr = f_rmdir(cmd+6); + if( fr != FR_OK ) + print_ff_error(fr); + } + else if( strncmp_P(cmd, PSTR("disktype "), 9)==0 ) + { + set_drive_type(atoi(cmd+9)); + f_mount(&FatFs, "0:", 0); + } + else if( strncmp_P(cmd, PSTR("format"), 6)==0 ) + { + MKFS_PARM param; + param.fmt = FM_FAT | FM_SFD; // FAT12 type, no disk partitioning + param.n_fat = 2; // number of FATs + param.n_heads = 2; // number of heads + param.n_sec_track = ArduinoFDC.numSectors(); + param.align = 1; // block alignment (not used for FAT12) + + switch( ArduinoFDC.getDriveType() ) + { + case ArduinoFDCClass::DT_5_DD: + case ArduinoFDCClass::DT_5_DDonHD: + param.au_size = 1024; // bytes/cluster + param.n_root = 112; // number of root directory entries + param.media = 0xFD; // media descriptor + break; + + case ArduinoFDCClass::DT_5_HD: + param.au_size = 512; // bytes/cluster + param.n_root = 224; // number of root directory entries + param.media = 0xF9; // media descriptor + break; + + case ArduinoFDCClass::DT_3_DD: + param.au_size = 1024; // bytes/cluster + param.n_root = 112; // number of root directory entries + param.media = 0xF9; // media descriptor + break; + + case ArduinoFDCClass::DT_3_HD: + param.au_size = 512; // bytes/cluster + param.n_root = 224; // number of root directory entries + param.media = 0xF0; // media descriptor + break; + } + + if( confirm_formatting() ) + { + byte st; + ArduinoFDC.motorOn(); + f_unmount("0:"); + if( strstr(cmd, "/q") || (st=ArduinoFDC.formatDisk(FatFs.win))==S_OK ) + { + Serial.println(F("Initializing file system...\n")); + FRESULT fr = f_mkfs ("0:", ¶m, FatFs.win, 512); + if( fr != FR_OK ) print_ff_error(fr); + } + else + print_error(st); + + f_mount(&FatFs, "0:", 0); + } + } +#ifdef USE_MONITOR + else if( strncmp_P(cmd, PSTR("monitor"), max(3, strlen(cmd)))==0 ) + { + motor_timeout = 0; + monitor(); + f_mount(&FatFs, "0:", 0); + } +#endif +#ifdef USE_XMODEM + else if( strncmp_P(cmd, PSTR("receive "), 8)==0 ) + { + ArduinoFDC.motorOn(); + fr = f_open(&FatFsFile, cmd+8, FA_WRITE | FA_CREATE_NEW); + if( fr == FR_OK ) + { + Serial.println(F("Send file via XModem now...")); + + XModem modem(recvChar, sendData, xmodemHandlerReceive); + xmodem_status = FR_OK; + modem.receive(); + + if( xmodem_status == FR_OK ) + Serial.println(F("\r\nSuccess!")); + else + { + unsigned long t = millis() + 500; + while( millis() < t ) { if( Serial.read()>=0 ) t = millis()+500; } + while( Serial.read()<0 ); + + Serial.println('\r'); + if( xmodem_status!=S_OK ) print_ff_error(xmodem_status); + } + + f_close(&FatFsFile); + } + else + print_ff_error(fr); + } + else if( strncmp_P(cmd, PSTR("send "), 5)==0 ) + { + ArduinoFDC.motorOn(); + fr = f_open(&FatFsFile, cmd+5, FA_READ); + if( fr == FR_OK ) + { + Serial.println(F("Receive file via XModem now...")); + + XModem modem(recvChar, sendData, xmodemHandlerSend); + xmodem_status = FR_OK; + modem.transmit(); + + if( xmodem_status == FR_OK ) + Serial.println(F("\r\nSuccess!")); + else + { + unsigned long t = millis() + 500; + while( millis() < t ) { if( Serial.read()>=0 ) t = millis()+500; } + while( Serial.read()<0 ); + + Serial.println('\r'); + if( xmodem_status!=S_OK ) print_ff_error(xmodem_status); + } + + f_close(&FatFsFile); + } + else + print_ff_error(fr); + } +#endif +#if !defined(USE_ARDUDOS) || !defined(USE_MONITOR) || !defined(USE_XMODEM) || defined(__AVR_ATmega2560__) + // must save flash space if all three of ARDUDOS/MONITR/XMODEM are enabled on UNO + else if( strcmp_P(cmd, PSTR("help"))==0 || strcmp_P(cmd, PSTR("h"))==0 || strcmp_P(cmd, PSTR("?"))==0 ) + { + Serial.print(F("Valid commands: dir, type, dump, write, del, mkdir, rmdir, disktype, format")); +#ifdef USE_MONITOR + Serial.print(F(", monitor")); +#endif +#ifdef USE_XMODEM + Serial.print(F(", send, receive")); +#endif + Serial.println(); + } +#endif + else if( cmd[0]!=0 ) + { + Serial.print(F("Unknown command: ")); + Serial.print(cmd); + } + + motor_timeout = millis() + 5000; + } +} + +#endif + + +// ------------------------------------------------------------------------------------------------- +// Low-level disk monitor +// ------------------------------------------------------------------------------------------------- + + +#ifdef USE_MONITOR + +// re-use the FatFs data buffer if ARDUDOS is enabled (to save RAM) +#ifdef USE_ARDUDOS +#define databuffer FatFs.win +#else +static byte databuffer[516]; +#endif + + +#ifdef USE_XMODEM + +#include "XModem.h" + +byte xmodem_status_mon = S_OK; +bool xmodem_verify = false; +word xmodem_sector = 0, xmodem_data_ptr = 0xFFFF; + + +bool xmodemHandlerSendMon(unsigned long no, char* data, int size) +{ + if( xmodem_data_ptr>=512 ) + { + byte numsec = ArduinoFDC.numSectors(); + if( xmodem_sector >= 2*numsec*ArduinoFDC.numTracks() ) + { xmodem_status_mon = S_OK; return false; } + + byte head = 0; + byte track = xmodem_sector / (numsec*2); + byte sector = xmodem_sector % (numsec*2); + if( sector >= numsec ) { head = 1; sector -= numsec; } + + byte r = S_NOHEADER, retry = 5; + while( retry>0 && r!=S_OK ) { r = ArduinoFDC.readSector(track, head, sector+1, databuffer); retry--; } + if( r!=S_OK ) { xmodem_status_mon = r; return false; } + + xmodem_data_ptr = 0; + xmodem_sector++; + } + + // "size" is always 128 and sector length is 512, i.e. a multiple of "size" + // readSector returns data in databuffer[1..512] + memcpy(data, databuffer+1+xmodem_data_ptr, size); + xmodem_data_ptr += size; + return true; +} + + +bool xmodemHandlerReceiveMon(unsigned long no, char* data, int size) +{ + // "size" is always 128 and sector length is 512, i.e. a multiple of "size" + // writeSector expects data in databuffer[1..512] + memcpy(databuffer+1+xmodem_data_ptr, data, size); + xmodem_data_ptr += size; + + if( xmodem_data_ptr>=512 ) + { + byte numsec = ArduinoFDC.numSectors(); + if( xmodem_sector >= 2*numsec*ArduinoFDC.numTracks() ) + { xmodem_status_mon = S_OK; return false; } + + byte head = 0; + byte track = xmodem_sector / (numsec*2); + byte sector = xmodem_sector % (numsec*2); + if( sector >= numsec ) { head = 1; sector -= numsec; } + + byte r = S_NOHEADER, retry = 5; + while( retry>0 && r!=S_OK ) { r = ArduinoFDC.writeSector(track, head, sector+1, databuffer, xmodem_verify); retry--; } + if( r!=S_OK ) { xmodem_status_mon = r; return false; } + + xmodem_data_ptr = 0; + xmodem_sector++; + } + + return true; +} + +#endif + + +void monitor() +{ + char cmd; + int a1, a2, a3, head, track, sector, n; + + ArduinoFDC.motorOn(); + while( true ) + { + Serial.print(F("\r\n\r\nCommand: ")); + n = sscanf(read_user_cmd(tempbuffer, 512), "%c%i,%i,%i", &cmd, &a1, &a2, &a3); + if( n<=0 || isspace(cmd) ) continue; + + if( cmd=='r' && n>=3 ) + { + track=a1; sector=a2; head= (n==3) ? 0 : a3; + if( head>=0 && head<2 && track>=0 && track=1 && sector<=ArduinoFDC.numSectors() ) + { + Serial.print(F("Reading track ")); Serial.print(track); + Serial.print(F(" sector ")); Serial.print(sector); + Serial.print(F(" side ")); Serial.println(head); + Serial.flush(); + + byte status = ArduinoFDC.readSector(track, head, sector, databuffer); + if( status==S_OK ) + { + dump_buffer(0, databuffer+1, 512); + Serial.println(); + } + else + print_error(status); + } + else + Serial.println(F("Invalid sector specification")); + } + else if( cmd=='r' && n==1 ) + { + ArduinoFDC.motorOn(); + for(track=0; track ok")); + break; + } + else if( (status==S_INVALIDID || status==S_CRC) && (attempts++ < 10) ) + Serial.println(F(" => CRC error, trying again")); + else + { + Serial.print(F(" => ")); + print_error(status); + break; + } + } + + sector+=2; + if( sector>ArduinoFDC.numSectors() ) sector = 2; + } + } + } + else if( cmd=='w' && n>=3 ) + { + track=a1; sector=a2; head= (n==3) ? 0 : a3; + if( head>=0 && head<2 && track>=0 && track=1 && sector<=ArduinoFDC.numSectors() ) + { + Serial.print(F("Writing and verifying track ")); Serial.print(track); + Serial.print(F(" sector ")); Serial.print(sector); + Serial.print(F(" side ")); Serial.println(head); + Serial.flush(); + + byte status = ArduinoFDC.writeSector(track, head, sector, databuffer, true); + if( status==S_OK ) + Serial.println(F("Ok.")); + else + print_error(status); + } + else + Serial.println(F("Invalid sector specification")); + } + else if( cmd=='w' && n>=1 ) + { + bool verify = n>1 && a2>0; + char c; + Serial.print(F("Write current buffer to all sectors in drive ")); + Serial.write('A' + ArduinoFDC.selectedDrive()); + Serial.println(F(". Continue (y/n)?")); + while( (c=Serial.read())<0 ); + if( c=='y' ) + { + ArduinoFDC.motorOn(); + for(track=0; track ok")); + else + { + Serial.print(F(" => ")); + print_error(status); + } + + sector+=2; + if( sector>ArduinoFDC.numSectors() ) sector = 2; + } + } + } + } + else if( cmd=='b' ) + { + Serial.println(F("Buffer contents:")); + dump_buffer(0, databuffer+1, 512); + } + else if( cmd=='B' ) + { + Serial.print(F("Filling buffer")); + if( n==1 ) + { + for(int i=0; i<512; i++) databuffer[i+1] = i; + } + else + { + Serial.print(F(" with 0x")); + Serial.print(a1, HEX); + for(int i=0; i<512; i++) databuffer[i+1] = a1; + } + Serial.println(); + } + else if( cmd=='m' ) + { + if( n==1 ) + { + Serial.print(F("Drive ")); + Serial.write('A' + ArduinoFDC.selectedDrive()); + Serial.print(F(" motor is ")); + Serial.println(ArduinoFDC.motorRunning() ? F("on") : F("off")); + } + else + { + Serial.print(F("Turning drive ")); + Serial.write('A' + ArduinoFDC.selectedDrive()); + Serial.print(F(" motor ")); + if( n==1 || a1==0 ) + { + Serial.println(F("off")); + ArduinoFDC.motorOff(); + } + else + { + Serial.println(F("on")); + ArduinoFDC.motorOn(); + } + } + } + else if( cmd=='s' ) + { + if( n==1 ) + { + Serial.print(F("Current drive is ")); + Serial.write('A' + ArduinoFDC.selectedDrive()); + } + else + { + Serial.print(F("Selecting drive ")); + Serial.write(a1>0 ? 'B' : 'A'); + Serial.println(); + ArduinoFDC.selectDrive(n>1 && a1>0); + ArduinoFDC.motorOn(); + } + } + else if( cmd=='t' && n>1 ) + { + set_drive_type(a1); + } + else if( cmd=='f' ) + { + if( confirm_formatting() ) + { + Serial.println(F("Formatting disk...")); + byte status = ArduinoFDC.formatDisk(databuffer, n>1 ? a1 : 0, n>2 ? a2 : 255); + if( status!=S_OK ) print_error(status); + memset(databuffer, 0, 513); + } + } +#ifdef USE_XMODEM + else if( cmd=='R' ) + { + Serial.println(F("Send image via XModem now...")); + xmodem_status_mon = S_OK; + xmodem_sector = 0; + xmodem_data_ptr = 0; + xmodem_verify = n>1 && (a1!=0); + + XModem modem(recvChar, sendData, xmodemHandlerReceiveMon); + if( modem.receive() && xmodem_status_mon==S_OK ) + Serial.println(F("\r\nSuccess!")); + else + { + unsigned long t = millis() + 500; + while( millis() < t ) { if( Serial.read()>=0 ) t = millis()+500; } + while( Serial.read()<0 ); + + Serial.println('\r'); + if( xmodem_status_mon!=S_OK ) print_error(xmodem_status_mon); + } + } + else if( cmd=='S' ) + { + Serial.println(F("Receive image via XModem now...")); + xmodem_status_mon = S_OK; + xmodem_sector = 0; + xmodem_data_ptr = 0xFFFF; + + XModem modem(recvChar, sendData, xmodemHandlerSendMon); + if( modem.transmit() && xmodem_status_mon==S_OK ) + Serial.println(F("\r\nSuccess!")); + else + { + unsigned long t = millis() + 500; + while( millis() < t ) { if( Serial.read()>=0 ) t = millis()+500; } + while( Serial.read()<0 ); + + Serial.println('\r'); + if( xmodem_status_mon!=S_OK ) print_error(xmodem_status_mon); + } + } +#endif +#ifdef USE_ARDUDOS + else if (cmd=='x' ) + return; +#endif +#if !defined(USE_ARDUDOS) || !defined(USE_MONITOR) || !defined(USE_XMODEM) || defined(__AVR_ATmega2560__) + // must save flash space if all three of ARDUDOS/MONITR/XMODEM are enabled on UNO + else if( cmd=='h' || cmd=='?' ) + { + Serial.println(F("Commands (t=track (0-based), s=sector (1-based), h=head (0/1)):")); + Serial.println(F("r t,s,h Read sector to buffer and print buffer")); + Serial.println(F("r Read ALL sectors and print pass/fail")); + Serial.println(F("w t,s,h Write buffer to sector")); + Serial.println(F("w [0/1] Write buffer to ALL sectors (without/with verify)")); + Serial.println(F("b Print buffer")); + Serial.println(F("B [n] Fill buffer with 'n' or 00..FF if n not given")); + Serial.println(F("m 0/1 Turn drive motor off/on")); + Serial.println(F("s 0/1 Select drive A/B")); + Serial.println(F("t 0-4 Set type of current drive (5.25DD/5.25DDinHD/5.25HD/3.5DD/3.5HD)")); + Serial.println(F("f Low-level format disk (tf)")); +#ifdef USE_XMODEM + Serial.println(F("S Read disk image and send via XModem")); + Serial.println(F("R [0/1] Receive disk image via XModem and write to disk (without/with verify)")); +#endif +#ifdef USE_ARDUDOS + Serial.println(F("x Exit monitor\n")); +#endif + } +#endif + else + Serial.println(F("Invalid command")); + } +} + +#endif + + +// ------------------------------------------------------------------------------------------------- +// Main functions +// ------------------------------------------------------------------------------------------------- + + +void setup() +{ + Serial.begin(115200); + ArduinoFDC.begin(ArduinoFDCClass::DT_3_HD, ArduinoFDCClass::DT_3_HD); + + // must save flash space if all three of ARDUDOS/MONITOR/XMODEM are enabled on UNO +#if !defined(USE_ARDUDOS) || !defined(USE_MONITOR) || !defined(USE_XMODEM) || defined(__AVR_ATmega2560__) + Serial.print(F("Drive A: ")); print_drive_type(ArduinoFDC.getDriveType()); Serial.println(); + if( ArduinoFDC.selectDrive(1) ) + { + Serial.print(F("Drive B: ")); print_drive_type(ArduinoFDC.getDriveType()); Serial.println(); + ArduinoFDC.selectDrive(0); + } +#endif +} + + +void loop() +{ +#if defined(USE_ARDUDOS) + arduDOS(); +#elif defined(USE_MONITOR) + monitor(); +#else +#error "Need at least one of USE_ARDUDOS and USE_MONITOR" +#endif +} diff --git a/trunk/Arduino/ArduinoFDC/GitHub - dhansel-ArduinoFDC- Library for using an Arduino as a floppy disk controller.url b/trunk/Arduino/ArduinoFDC/GitHub - dhansel-ArduinoFDC- Library for using an Arduino as a floppy disk controller.url new file mode 100644 index 00000000..f3be6ec4 --- /dev/null +++ b/trunk/Arduino/ArduinoFDC/GitHub - dhansel-ArduinoFDC- Library for using an Arduino as a floppy disk controller.url @@ -0,0 +1,2 @@ +[InternetShortcut] +URL=https://github.com/dhansel/ArduinoFDC diff --git a/trunk/Arduino/ArduinoFDC/LICENSE b/trunk/Arduino/ArduinoFDC/LICENSE new file mode 100644 index 00000000..f288702d --- /dev/null +++ b/trunk/Arduino/ArduinoFDC/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + 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. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + 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/trunk/Arduino/ArduinoFDC/README.md b/trunk/Arduino/ArduinoFDC/README.md new file mode 100644 index 00000000..ff1e7217 --- /dev/null +++ b/trunk/Arduino/ArduinoFDC/README.md @@ -0,0 +1,377 @@ +# ArduinoFDC + +![ArduinoFDC Setup](images/setup.jpg) + +ArduinoFDC is a sketch that implements a floppy disk controller. It works with Arduino Uno, Leonardo, Nano, Pro Mini, Micro and Mega. + +ArduinoFDC consists of three parts: + +1. A [library](#library-functions) providing low-level functions to allow reading and writing disks at the +sector level as well as low-level formatting disks. +2. Integration of ChaN's brilliant [FatFS](http://elm-chan.org/fsw/ff/00index_e.html) +library to provide file-level functions for reading and writing files and directories +in a FAT (MS-DOS) file system and a high-level format function to initialize a FAT file system. +3. An example sketch implementing [ArduDOS](#ardudos), a (very) small DOS environment for browsing +a FAT file system as well as a [low-level disk monitor](#low-level-disk-monitor) to access sector data on the disk, +including the ability to transfer whole disks or single files via the XModem protocol. + +ArduinoFDC works with double density (DD) as well as high density (HD) +disk drives. It can read, write and format 5.25" DD (360KB), 5.25" HD (1.2MB), 3.5" DD (720KB) +and 3.5" HD (1.44MB) disks. + +## Wiring: + +The table below shows how to wire the Arduino pins to the 34-pin IDC +connector on the floppy drive cable. + +The pin numbers are defined at the top of the ArduinoFDC.cpp file. Some of them can +easily be changed whereas others are hard-coded in the controller code. Refer to +the comments at the top of the ArduinoFDC.cpp file if you want to use different +pin assignments. + +Floppy Cable | Uno/Mini/Nano | Leonardo/Micro | Mega | Notes | Function +-----------------|---------------|-----------------|--------|--------|--------------- +2 | 13 | 13/16 | 42 | 3,4,5 | Density select +8 | 7 | 8 | 47 | | Index +10 | 4 | 5 | 51 | 1,3 | Motor Enable A +12 | A1 | A1 | 40 | 1,3,4 | Drive Select B +14 | 5 | 6 | 50 | 1,3 | Drive Select A +16 | A0 | A0 | 41 | 1,3,4 | Motor Enable B +18 | 3 | 3 | 52 | 3 | Head Step Direction +20 | 2 | 2 | 53 | 3 | Head Step Pulse +22 | 9 | 9 | 46 | | Write Data +24 | 10 | 10 | 45 | | Write Gate +26 | 11 | 11/14 | 44 | 3 | Track 0 +28 | 12 | 12/15 | 43 | 3,4 | Write Protect +30 | 8 | 4 | 48 | 2 | Read Data +32 | 6 | 7 | 49 | 3 | Side Select +1,3,5,...,31,33 | GND | GND | GND | 6 | Signal Ground + +**Note 1:** +The pin numbers for the SELECT/MOTOR signals assume you are wiring to +the controller end of a floppy drive cable. If you are wiring directly +to the floppy drive, the A/B pins will be reversed (search the web +for "Floppy drive twist" for more information). + +**Note 2:** +It is **highly** recommended (but not entirely necessary) to add a 1k +pull-up resistor to +5V to this signal. The Arduino's built-in pull-up +resistors are very weak (20-50k) and may not pull the signal up quickly enough. +Without the resistor you may encounter read errors (bad CRC, header not found), +especially when reading HD disks. Whether it works without the resistor will +depend on your specific drive, drive cable, connections and Arduino. + +**Note 3:** +This signal can easily be moved to a different pin on the Arduino by +changing the corresponding `#define PIN_XXX ...` statement at the top +of ArduinoFDC.cpp + +**Note 4:** +This signal is not essential for the functionality of the controller. +The corresponding pin can be freed by commenting out the `#define PIN_XXX ...` +statement at the top of ArduinoFDC.cpp + +**Note 5:** +See section "DENSITY control signal" below. + +**Note 6:** +You should be able to just pick one of the GND pins. However, some cables/drives +do not actually connect all of these to ground. If your setup does not work +it may be worth trying a different GND pin. + + +## Supported disk/drive types + +To properly read/write data, the library must be configured for the drive/disk +combination that is being used. The drive type can be passed into the `begin` functions +or set afterwards by calling the `setDriveType` function. Supported types are: +* **ArduinoFDC::DT_5_DD**: Double-density disk in a 5.25" double-density drive +* **ArduinoFDC::DT_5_DDonHD**: Double-density disk in a 5.25" high-density drive +* **ArduinoFDC::DT_5_HD**: High-density disk in a 5.25" high-density drive +* **ArduinoFDC::DT_3_DD**: Double-density disk in a 3.5" double- or high-density drive +* **ArduinoFDC::DT_3_HD**: High-density disk in a 3.5" high-density drive + +## DENSITY control signal + +The function of the DENSITY control signal line between the controller and the +floppy drive is not well defined and varies between drives. Furthermore most drives +can be configured by jumpers (also called "straps"). You may want to consult the +documentation for your drive for details. + +In their default configuration most 3.5" drives do not use this signal. The drive +itself determines the type of disk (DD or HD) by the presence of a hole in the disk +(on the opposite edge from the "write protect" hole). The controller must be configured +separately for the correct type (DD or HD), otherwise reading/writing will fail. + +For 5.25" HD drives this signal is generally an input from the controller to the drive. +If the signal is LOW then low density mode is selected, otherwise high density is used. +However, for some drives the opposite is true. Many drives can be configured via jumpers +to select the expected levals. + +The controller can be configured what to do with this signal by calling the "setDensityPinMode" +function. The following modes are supported: +* **ArduinoFDC::DP_DISCONNECT**: This configures the DENSITY pin as INPUT. It does not actually read the pin. +* **ArduinoFDC::DP_OUTPUT_LOW_FOR_HD**: This configures the DENSITY pin as an OUTPUT and sets it LOW if the disk type is HD. +* **ArduinoFDC::DP_OUTPUT_LOW_FOR_DD**: This configures the DENSITY pin as an OUTPUT and sets it LOW if the disk type is DD. + +By default, the mode is set to DP_DISCONNECT for 3.5" drives and DP_OUTPUT_LOW_FOR_DD for 5.25" drives. + +Another way to handle the DENSITY signal is to comment out the `#define PIN_DENSITY` line +at the top of ArduinoFDC.cpp and hard-wire the DENSITY signal from the disk drive cable +to the proper level (or leave it disconnected). + +## Library functions: + +To use the low-level disk access library functions (listed below), copy ArduinoFDC.h and ArduinoFDC.cpp +into your Arduino sketch directory and add `#include "ArduinoFDC.h"` to your sketch. + +To use the FAT file system functions, additionally copy ff.h, ff.c, ffconf.h, diskio.h and diskio.cpp. +Then add `#include "ff.h"` and `#include "ArduinoFDC.h"` to your sketch. For documentation of the FatFS +functions refer to the [FatFS documentation](http://elm-chan.org/fsw/ff/00index_e.html). + +#### `void ArduinoFDC.begin(driveAtype, driveBtype)` +Initializes the Arduino pins used by the controller. For possible drive types see +the "[Supported disk/drive types](#supported-diskdrive-types)" section above. If left out both types default to +ArduinoFDC::DT_3_HD. + +#### `void ArduinoFDC.end()` +Releases the pins initialized by ArduinoFDC.begin() + +#### `bool ArduinoFDC.selectDrive(byte drive)` +Selects drive A (0) or B (1) to be used for subsequent calls to +readSector/writeSector/formatDisk. Calling `begin()` selects drive A. +Returns 'false' if trying to select drive 1 when the corresponding control +pins are commented out in ArduinoFDC.cpp + +#### `byte ArduinoFDC.selectedDrive()` +Returns which drive is currently selected, A (0) or B (1). + +#### `void ArduinoFDC.setDriveType(driveType)` +Sets the disk/drive type for the currently selected drive. For possible drive types see +the "[Supported disk/drive types](#supported-diskdrive-types)" section above. + +#### `byte ArduinoFDC.getDriveType(driveType)` +Returns the drive type of the currently selected drive. + +#### `void ArduinoFDC.setDensityPinMode(mode)` +Sets the function of the DENSITY pin for the currently selected drive. +See section "[Density control signal](#density-control-signal)" above. + +#### `byte ArduinoFDC.numTracks()` +Returns the number of tracks for the drive type of the currently selected drive. + +#### `byte ArduinoFDC.numSectors()` +Returns the number of sectors per track for the drive type of the currently selected drive. + +#### `bool ArduinoFDC.haveDisk()` +Returns true if a disk is in the drive. This is done by looking for the index +hole. If the drive motor is not currently running this haveDisk() will temporarily +turn it on. + +#### `bool ArduinoFDC.isWriteProtected()` +Returns true if the disk is write protected. If no disk is in the drive then +the result may be either true or false. If the WRITE PROTECT signal is not connected +then the result is always false. + +#### `void ArduinoFDC.motorOn()` +Turns the disk drive motor on. + +The `readSector`/`writeSector`/`formatDisk` functions will turn the motor on **and** back off +automatically if it is not already running. Note that turning on the motor also includes +a one second delay to allow it to spin up. If you are reading/writing multiple sectors +you may want to use the `motorOn` and `motorOff` functions to manually turn the motor on +and off. + +#### `void ArduinoFDC.motorOff()` +Turns the disk drive motor off. + +#### `bool ArduinoFDC.motorRunning()` +Returns *true* if the disk drive motor is currently running and *false* if not. + +#### `byte ArduinoFDC.readSector(byte track, byte side, byte sector, byte *buffer)` +Reads data from a sector from the flopy disk. Always reads a full sector (512 bytes). + +* The "track" parameter must be in range 0..(numTracks()-1) +* The "side" parameter must either be 0 or 1 +* The "sector" paramter must be in range 1..numSectors() +* The "buffer" parameter must be a pointer to a byte array of size (at least) 516 bytes. + +The function returns 0 if reading succeeded. Otherwise an error code is returned +(see [Troubleshooting](#troubleshooting) section below) + +**IMPORTANT:** On successful return, the sector data that was read will be in buffer[1..512] (**NOT** buffer[0..511]) + +#### `byte ArduinoFDC.writeSector(byte track, byte side, byte sector, byte *buffer, bool verify)` +Writes data to a sector on the floppy disk. Always writes a full sector (512 bytes). + +* The "track" parameter must be in range 0..(numTracks()-1) +* The "side" parameter must either be 0 or 1 +* The "sector" paramter must be in range 1..numSectors() +* The "buffer" parameter must be a pointer to a byte array of size (at least) 516 bytes. +* If the "verify" parameter is *true*, the data written will be read back and compared to what was written. +If a difference is detected then the function will return *false*. +If the "verify" parameter is *false* then no verification is done. The function may still return *false* +if the proper sector location on disk can not be found before writing. + +The function returns 0 if writing succeeded. Otherwise an error code is returned +(see [Troubleshooting](#troubleshooting) section below) + +**IMPORTANT:** The sector data to be written must be in buffer[1..512] (**NOT** buffer[0..511]) + +#### `bool ArduinoFDC.formatDisk(byte *buffer, byte from_track=0, byte to_track=255)` +Formats a floppy disk according to the format specified by the "setDriveType()" function. +A subset of tracks can be formatted by specifying the from_track and to_track parameters. + +A buffer of size at least 144 bytes is needed to store temporary data during formatting. +The buffer is passed in as an argument to allow re-using other buffers in your sketch. +If you do not have a buffer to be re-used, just declare `byte buffer[144]` before calling formatDisk(). + +This function does **not** set up any file system on the disk. It only sets up the +low-level sector structure that allows reading and writing of sectors (and fills all +sector data with 0xF6 bytes). + +The function returns 0 if formatting succeeded. Otherwise an error code is returned +(see [Troubleshooting](#troubleshooting) section below). Note that no verification of the formatted disk +is performed. The only possible error conditions are missing track 0 or index hole signals. +You can use the `readSector`function to verify that data can be read properly +after formatting. + +## ArduDOS + +ArduDOS is a minimal DOS that allows the user to browse the file system +on the disk and read/write files. The basic functionality is modeled on MS-DOS +with some exceptions: +1. All commands operate **only** on the currently selected drive. If two drives are + connected then use "b:" or "a:" to switch drives. +2. The working directory is **always** the top-level directory of the disk. No "cd" + command is available to change the directory. Therefore, all paths given as + arguments to commands must be relative to the top-level directory. +3. Disk changes are **not** automatically detected. After changing a disk, re-select + the current drive (e.g. "a:") to notify ArduDOS of the change. + +ArduDOS is easy to access from either Arduio's serial monitor or any other +serial terminal. Set the monitor or terminal's baud rate to 115200 before connecting. +The following commands are available: + +* `dir [directory]`
+ Show the listing of the specified directory (default is root directory). +* `type filename`
+ Type out the specified file to the screen (best for text files). +* `dump filename`
+ Dump the specified file to the screen in hexadecimal notation (best for binary files). +* `write filename`
+ Receive text line-by-line from the user and write it to the specified file. + Enter an empty line to finish. +* `del filename`
+ Delete the specified file. +* `mkdir dirname`
+ Create the specified directory. +* `rmdir dirname`
+ Remove the specified directory. +* `disktype 0/1/2/3/4`
+ Set the drive type of the current drive, where 0/1/2/3/4 stands for the drive type + as listed (in the same order) in section "[Supported disk/drive types](#supported-diskdrive-types)" above. +* `format [/q]`
+ Low-level format a disk and initialize a FAT file system. If `/q` argument is given, + performs a quick format, i.e. only resets the file system without low-level format. +* `monitor`
+ Enter the low-level disk monitor (see the "[Low-level disk monitor](#low-level-disk-monitor)" section below). +* `send filename` (only available if `#define USE_XMODEM` is enabled at the top of ArduinoFDC.ino)
+ Send the specified file via XModem protocol. See the "[XModem](#xmodem)" section below for more details. +* `receive filename` (only available if `#define USE_XMODEM` is enabled at the top of ArduinoFDC.ino)
+ Receive the specified file via XModem protocol. See the "[XModem](#xmodem)" section below for more details. + +![ArduDOS session](images/ArduDOS.png) + +## Low-level disk monitor + +Like ArduDOS, the low-level monitor is easy to use with the Arduino serial monitor. +When using ArduDOS (i.e. `#define USE_ARDUDOS` is enabled at the top of ArduinoFDC.ino), +use the "monitor" command to enter the low-level monitor. + +If ArduDOS is not enabled then the sketch drops directly into the disk monitor mode. +Set Arduino's serial monitor to 115200 baud to connect. + +When running, the monitor will show a command prompt. Enter your command in the +serial monitor's input line and press *Enter* to execute the command. + +The following commands are supported: +* `r track, sector[,side]`
+ Read the sector specified by track/sector/side, copy its contents to an internal + buffer and show the buffer content. If the *side* parameter is left out it defaults + to zero. +* `w track, sector[,side]`
+ Write the current buffer contents to the sector specified by track/sector/side + and verify the data after writing. Shows "Ok" or "Error" status after execution. + If the *side* parameter is left out it defaults to zero. +* `f`
+ Low-level format the disk. No file system is initialized, all sectors are filled + with 0xF6. To format and/or add a file system use the "format" command in ArduDOS + (see ArduDOS section above). +* `b`
+ Show the current buffer content +* `B [n]`
+ Fill the buffer with value *n*. If *n* is left out then fill the buffer with + bytes 0,1,2,...255,0,1,2,...255. +* `m [0/1]`
+ Turn the motor of the currently selected drive off/on. If the *0/1* parameter is left out + then the current motor status is shown. +* `r`
+ Read ALL sectors on the disk and show status Ok/Error for each one. +* `w [0/1]`
+ Write the current buffer content to ALL sectors on the disk. If the *0/1* parameter + is 1 then verify every sector after writing it (significantly slower). + If the *0/1* parameter is left out it defaults to 0. +* `s [0/1]`
+ Select drive A (0) or B (1). If the *0/1* parameter is left out then the currently + selected drive is shown. +* `t 0/1/2/3/4`
+ Set the drive type of the current drive, where 0/1/2/3/4 stands for the drive type + as listed (in the same order) in section "[Supported disk/drive types](#supported-diskdrive-types)" above. +* `S` (only available if `#define USE_XMODEM` is enabled at the top of ArduinoFDC.ino)
+ Read all sectors of the current disk and transmit them via XModem protocol. See + the "[XModem](#xmodem)" section below for more details. +* `R` (only available if `#define USE_XMODEM` is enabled at the top of ArduinoFDC.ino)
+ Receive a disk image via XModem and write it to the current disk. See + the "[XModem](#xmodem)" section below for more details. +* `x` (only if the monitor is entered from ArduDOS via the "monitor" command)
+ Exit the monitor and return to [ArduDOS](#ardudos). + +## XModem + +Both ArduDOS and the low-level monitor can transmit and receive data via the XModem protocol. +If you want to use this functionality, first un-comment the `#define USE_XMODEM` setting at +the top of file ArduinoFDC.ino and re-upload the sketch. + +Use a terminal program that supports XModem to send/receive the data. I recommend TeraTerm. +First start the transfer on the controller then initiate the XModem send/receive function in +the terminal program. + +Note that *no error messages* can be displayed during the XModem transfers since the transfer +takes place over the same serial connection as the terminal. If the transfer stops prematurely +and nothing is shown in the terminal, pressing ENTER will get the command prompt back. + +## Troubleshooting + +The following table lists the error codes returned by the `readSector`, `writeSector` +and `formatDisk` functions including possible causes for each error. Pin numbers refer +to pins on the Arduino UNO. + +\# | Code | Meaning | Possible causes +--|-------------|---------|---------------- +0 | S_OK | No error, the operation succeeded | +1 | S_NOTINIT | The ArduinoFDC.begin() function has not been called | +2 | S_NOTREADY | No data at all is received from the disk drive | - no disk in drive
- drive does not have power
- pins MOTOR (4/12), SELECT (5/13), READ (8), INDEX (7) or GND not properly connected +3 | S_NOSYNC | Data is received but no sync mark can be found | - disk not formatted or not formatted for the correct density
- GND pin not properly connected +4 | S_NOHEADER | Sync marks are found but either no sector header or no header with the expected track/side/sector markings | - pins STEP (2), STEPDIR (3), SIDE (6) or GND not properly connected
- bad disk or unknown format
- misaligned disk drive
- invalid track, sector or head number given +5 | S_INVALIDID | The data record was not started by a 0xFB byte as expected | - bad disk or unknown format +6 | S_CRC | The sector data checksum is incorrect | - bad disk or unknown format
- pullup resistors too weak (see note 2 in wiring section) +7 | S_NOTRACK0 | When trying to move the read head to track 0, the TRACK0 signal was not seen, even after stepping more than 80 tracks. | - pins STEP (2), STEPDIR (3), SELECT (5/13), TRACK0 (11) or GND not properly connected
- drive does not have power +8 | S_VERIFY | When reading back data that was just written, the data did not match | - pins WRITEGATE (10) or WRITEDATA (9) not properly connected
- disk is write protected and WRITEPROTECT (12) pin is not connected
- bad disk +9 | S_READONLY | Attempting to write to a write-protected disk | - disk is write protected + +## Acknowledgements + +The ArduDOS functionality would not have been possible without ChaN's brilliant [FatFS](http://elm-chan.org/fsw/ff/00index_e.html) library. + +The XModem communication uses the arduino-xmodem code available at https://code.google.com/archive/p/arduino-xmodem. diff --git a/trunk/Arduino/ArduinoFDC/XModem.cpp b/trunk/Arduino/ArduinoFDC/XModem.cpp new file mode 100644 index 00000000..c01b113b --- /dev/null +++ b/trunk/Arduino/ArduinoFDC/XModem.cpp @@ -0,0 +1,378 @@ +// This code was taken from: https://github.com/mgk/arduino-xmodem +// (https://code.google.com/archive/p/arduino-xmodem) +// which was released under GPL V3: +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// ----------------------------------------------------------------------------- + +#include +#include + +#include "XModem.h" +#ifdef UTEST +#include "CppUTestExt/MockSupport.h" +#endif +const unsigned char XModem::NACK = 21; +const unsigned char XModem::ACK = 6; + +const unsigned char XModem::SOH = 1; +const unsigned char XModem::EOT = 4; +const unsigned char XModem::CAN = 0x18; + +const int XModem::receiveDelay=7000; +const int XModem::rcvRetryLimit = 10; + + + + +XModem::XModem(int (*recvChar)(int msDelay), + void (*sendData)(const char *data, int len)) +{ + this->sendData = sendData; + this->recvChar = recvChar; + this->dataHandler = NULL; + +} +XModem::XModem(int (*recvChar)(int msDelay), + void (*sendData)(const char *data, int len), + bool (*dataHandler)(unsigned long number, char *buffer, int len)) +{ + this->sendData = sendData; + this->recvChar = recvChar; + this->dataHandler = dataHandler; + +} + +bool XModem::dataAvail(int delay) +{ + if (this->byte != -1) + return true; + if ((this->byte = this->recvChar(delay)) != -1) + return true; + else + return false; + +} +int XModem::dataRead(int delay) +{ + int b; + if(this->byte != -1) + { + b = this->byte; + this->byte = -1; + return b; + } + return this->recvChar(delay); +} +void XModem::dataWrite(char symbol) +{ + this->sendData(&symbol, 1); +} +bool XModem::receiveFrameNo() +{ + unsigned char num = + (unsigned char)this->dataRead(XModem::receiveDelay); + unsigned char invnum = + (unsigned char)this->dataRead(XModem::receiveDelay); + this->repeatedBlock = false; + //check for repeated block + if (invnum == (255-num) && num == this->blockNo-1) { + this->repeatedBlock = true; + return true; + } + + if(num != this-> blockNo || invnum != (255-num)) + return false; + else + return true; +} +bool XModem::receiveData() +{ + for(int i = 0; i < 128; i++) { + int byte = this->dataRead(XModem::receiveDelay); + if(byte != -1) + this->buffer[i] = (unsigned char)byte; + else + return false; + } + return true; +} +bool XModem::checkCrc() +{ + unsigned short frame_crc = ((unsigned char)this-> + dataRead(XModem::receiveDelay)) << 8; + + frame_crc |= (unsigned char)this->dataRead(XModem::receiveDelay); + //now calculate crc on data + unsigned short crc = this->crc16_ccitt(this->buffer, 128); + + if(frame_crc != crc) + return false; + else + return true; + +} +bool XModem::checkChkSum() +{ + unsigned char frame_chksum = (unsigned char)this-> + dataRead(XModem::receiveDelay); + //calculate chksum + unsigned char chksum = 0; + for(int i = 0; i< 128; i++) { + chksum += this->buffer[i]; + } + if(frame_chksum == chksum) + return true; + else + return false; +} +bool XModem::sendNack() +{ + this->dataWrite(XModem::NACK); + this->retries++; + if(this->retries < XModem::rcvRetryLimit) + return true; + else + return false; + +} +bool XModem::receiveFrames(transfer_t transfer) +{ + bool handlerOk = true; + this->blockNo = 1; + this->blockNoExt = 1; + this->retries = 0; + while (1) { + char cmd = this->dataRead(1000); + switch(cmd){ + case XModem::SOH: + if (!this->receiveFrameNo()) { + if (this->sendNack()) + break; + else + return false; + } + if (!this->receiveData()) { + if (this->sendNack()) + break; + else + return false; + + }; + if (transfer == Crc) { + if (!this->checkCrc()) { + if (this->sendNack()) + break; + else + return false; + } + } else { + if(!this->checkChkSum()) { + if (this->sendNack()) + break; + else + return false; + } + } + //callback + if(handlerOk && this->dataHandler != NULL && this->repeatedBlock == false) + handlerOk = this->dataHandler(this->blockNoExt, this->buffer, 128); + //ack + if( handlerOk ) + { + this->dataWrite(XModem::ACK); + if(this->repeatedBlock == false) + { + this->blockNo++; + this->blockNoExt++; + } + this->retries = 0; + } + else if( !this->sendNack() ) + return false; + + break; + case XModem::EOT: + this->dataWrite(XModem::ACK); + return true; + case XModem::CAN: + //wait second CAN + if(this->dataRead(XModem::receiveDelay) == + XModem::CAN) { + this->dataWrite(XModem::ACK); + //this->flushInput(); + return false; + } + //something wrong + this->dataWrite(XModem::CAN); + this->dataWrite(XModem::CAN); + this->dataWrite(XModem::CAN); + return false; + default: + //something wrong + this->dataWrite(XModem::CAN); + this->dataWrite(XModem::CAN); + this->dataWrite(XModem::CAN); + return false; + } + + } +} +void XModem::init() +{ + //set preread byte + this->byte = -1; +} +bool XModem::receive() +{ + this->init(); + + for (int i =0; i < 128; i++) + { + this->dataWrite('C'); + if (this->dataAvail(1000)) + return receiveFrames(Crc); + + } + for (int i =0; i < 128; i++) + { + this->dataWrite(XModem::NACK); + if (this->dataAvail(1000)) + return receiveFrames(ChkSum); + } + return false; +} +unsigned short XModem::crc16_ccitt(char *buf, int size) +{ + unsigned short crc = 0; + while (--size >= 0) { + int i; + crc ^= (unsigned short) *buf++ << 8; + for (i = 0; i < 8; i++) + if (crc & 0x8000) + crc = crc << 1 ^ 0x1021; + else + crc <<= 1; + } + return crc; +} +unsigned char XModem::generateChkSum(const char *buf, int len) +{ + //calculate chksum + unsigned char chksum = 0; + for(int i = 0; i< len; i++) { + chksum += buf[i]; + } + return chksum; + +} + +bool XModem::transmitFrames(transfer_t transfer) +{ + this->blockNo = 1; + this->blockNoExt = 1; + // use this only in unit tetsing + //memset(this->buffer, 'A', 128); + while(1) + { + //get data + if (this->dataHandler != NULL) + { + if( false == + this->dataHandler(this->blockNoExt, this->buffer+3, + 128)) + { + //end of transfer + this->dataWrite(XModem::EOT); + //wait ACK + if (this->dataRead(XModem::receiveDelay) == + XModem::ACK) + return true; + else + return false; + + } + + } + else + { + //cancel transfer - send CAN twice + this->dataWrite(XModem::CAN); + this->dataWrite(XModem::CAN); + //wait ACK + if (this->dataRead(XModem::receiveDelay) == + XModem::ACK) + return true; + else + return false; + } + //SOH + buffer[0] = XModem::SOH; + //frame number + buffer[1] = this->blockNo; + //inv frame number + buffer[2] = (unsigned char)(255-(this->blockNo)); + //(data is already in buffer starting at byte 3) + //checksum or crc + if (transfer == ChkSum) { + buffer[3+128] = this->generateChkSum(buffer+3, 128); + this->sendData(buffer, 3+128+1); + } else { + unsigned short crc; + crc = this->crc16_ccitt(this->buffer+3, 128); + buffer[3+128+0] = (unsigned char)(crc >> 8); + buffer[3+128+1] = (unsigned char)(crc);; + this->sendData(buffer, 3+128+2); + } + + //TO DO - wait NACK or CAN or ACK + int ret = this->dataRead(XModem::receiveDelay); + switch(ret) + { + case XModem::ACK: //data is ok - go to next chunk + this->blockNo++; + this->blockNoExt++; + continue; + case XModem::NACK: //resend data + continue; + case XModem::CAN: //abort transmision + return false; + + } + + } + return false; +} +bool XModem::transmit() +{ + int retry = 0; + int sym; + this->init(); + + //wait for CRC transfer + while(retry < 256) + { + if(this->dataAvail(1000)) + { + sym = this->dataRead(1); //data is here - no delay + if(sym == 'C') + return this->transmitFrames(Crc); + if(sym == XModem::NACK) + return this->transmitFrames(ChkSum); + } + retry++; + } + return false; +} diff --git a/trunk/Arduino/ArduinoFDC/XModem.h b/trunk/Arduino/ArduinoFDC/XModem.h new file mode 100644 index 00000000..bb4671a7 --- /dev/null +++ b/trunk/Arduino/ArduinoFDC/XModem.h @@ -0,0 +1,84 @@ +// This code was taken from: https://code.google.com/archive/p/arduino-xmodem +// (https://code.google.com/archive/p/arduino-xmodem) +// which was released under GPL V3: +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// ----------------------------------------------------------------------------- + +#ifndef XMODEM_H +#define XMODEM_H + +typedef enum { + Crc, + ChkSum +} transfer_t; + + +class XModem { + private: + //delay when receive bytes in frame - 7 secs + static const int receiveDelay; + //retry limit when receiving + static const int rcvRetryLimit; + //holds readed byte (due to dataAvail()) + int byte; + //expected block number + unsigned char blockNo; + //extended block number, send to dataHandler() + unsigned long blockNoExt; + //retry counter for NACK + int retries; + //buffer + char buffer[133]; + //repeated block flag + bool repeatedBlock; + + int (*recvChar)(int); + void (*sendData)(const char *data, int len); + bool (*dataHandler)(unsigned long number, char *buffer, int len); + unsigned short crc16_ccitt(char *buf, int size); + bool dataAvail(int delay); + int dataRead(int delay); + void dataWrite(char symbol); + bool receiveFrameNo(void); + bool receiveData(void); + bool checkCrc(void); + bool checkChkSum(void); + bool receiveFrames(transfer_t transfer); + bool sendNack(void); + void init(void); + + bool transmitFrames(transfer_t); + unsigned char generateChkSum(const char *buffer, int len); + + public: + static const unsigned char NACK; + static const unsigned char ACK; + static const unsigned char SOH; + static const unsigned char EOT; + static const unsigned char CAN; + + XModem(int (*recvChar)(int), void (*sendData)(const char *data, int len)); + XModem(int (*recvChar)(int), void (*sendData)(const char *data, int len), + bool (*dataHandler)(unsigned long, char*, int)); + bool receive(); + bool transmit(); + + + +}; + + +#endif diff --git a/trunk/Arduino/ArduinoFDC/diskio.cpp b/trunk/Arduino/ArduinoFDC/diskio.cpp new file mode 100644 index 00000000..e4035fc8 --- /dev/null +++ b/trunk/Arduino/ArduinoFDC/diskio.cpp @@ -0,0 +1,132 @@ +// ----------------------------------------------------------------------------- +// 3.5"/5.25" DD/HD Disk controller for Arduino +// Copyright (C) 2021 David Hansel +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// ----------------------------------------------------------------------------- + +#include "diskio.h" +#include "ArduinoFDC.h" + + +DSTATUS disk_status(BYTE pdrv) +{ + // STA_NOINIT: Drive not initialized + // STA_NODISK: No medium in the drive + // STA_PROTECT: Write protected + return ArduinoFDC.isWriteProtected() ? STA_PROTECT : 0; +} + + +DSTATUS disk_initialize(BYTE pdrv) +{ + return ((ArduinoFDC.haveDisk() ? 0 : (STA_NODISK|STA_NOINIT)) | + (ArduinoFDC.isWriteProtected() ? STA_PROTECT : 0)); +} + + +DRESULT disk_read(BYTE pdrv, BYTE *buf, DWORD sec, UINT count) +{ + DRESULT res = RES_OK; + + byte numsec = ArduinoFDC.numSectors(); + + if( count!=1 || sec>2*numsec*ArduinoFDC.numTracks() ) + res = RES_PARERR; + else + { + byte head = 0; + byte track = sec / (numsec*2); + byte sector = sec % (numsec*2); + if( sector >= numsec ) { head = 1; sector -= numsec; } + + byte r = S_NOHEADER, retry = 5; + while( retry>0 && r!=S_OK ) { r = ArduinoFDC.readSector(track, head, sector+1, buf); retry--; } + + if( r==S_OK ) + { + memmove(buf, buf+1, 512); + res = RES_OK; + } + else if( r==S_NOTREADY ) + res = RES_NOTRDY; + else + res = RES_ERROR; + } + + return res; +} + + +DRESULT disk_write(BYTE pdrv, BYTE *buf, DWORD sec, UINT count) +{ + DRESULT res = RES_OK; + byte numsec = ArduinoFDC.numSectors(); + + if( count!=1 || sec>2*numsec*ArduinoFDC.numTracks() ) + res = RES_PARERR; + else + { + byte head = 0; + byte track = sec / (numsec*2); + byte sector = sec % (numsec*2); + + if( sector >= numsec ) { head = 1; sector -= numsec; } + + memmove(buf+1, buf, 512); + byte r = S_NOHEADER, retry = 3; + while( retry>0 && r!=S_OK ) { r = ArduinoFDC.writeSector(track, head, sector+1, buf, true); retry--; } + memmove(buf, buf+1, 512); + + if( r==S_OK ) + res = RES_OK; + else if( r==S_NOTREADY ) + res = RES_NOTRDY; + else if( r==S_READONLY ) + res = RES_WRPRT; + else + res = RES_ERROR; + } + + return res; +} + + +DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void* buff) +{ + DRESULT res = RES_ERROR; + + switch( cmd ) + { + case CTRL_SYNC: + res = RES_OK; + break; + + case GET_SECTOR_COUNT: + *((DWORD *) buff) = (DWORD) ArduinoFDC.numSectors() * (DWORD) ArduinoFDC.numTracks() * 2; + res = RES_OK; + break; + + case GET_SECTOR_SIZE: + *((DWORD *) buff) = 512; + break; + + case GET_BLOCK_SIZE: + *((DWORD *) buff) = 1; + break; + } + + return res; +} diff --git a/trunk/Arduino/ArduinoFDC/diskio.h b/trunk/Arduino/ArduinoFDC/diskio.h new file mode 100644 index 00000000..999960b2 --- /dev/null +++ b/trunk/Arduino/ArduinoFDC/diskio.h @@ -0,0 +1,80 @@ +/*-----------------------------------------------------------------------/ +/ Low level disk interface modlue include file (C)ChaN, 2014 / +/-----------------------------------------------------------------------*/ + +#ifndef _DISKIO_DEFINED +#define _DISKIO_DEFINED + +#ifdef __cplusplus +extern "C" { +#endif + +#define _USE_WRITE 1 /* 1: Enable disk_write function */ +#define _USE_IOCTL 1 /* 1: Enable disk_ioctl function */ + +#include "ff.h" + + +/* Status of Disk Functions */ +typedef BYTE DSTATUS; + +/* Results of Disk Functions */ +typedef enum { + RES_OK = 0, /* 0: Successful */ + RES_ERROR, /* 1: R/W Error */ + RES_WRPRT, /* 2: Write Protected */ + RES_NOTRDY, /* 3: Not Ready */ + RES_PARERR /* 4: Invalid Parameter */ +} DRESULT; + + +/*---------------------------------------*/ +/* Prototypes for disk control functions */ + + +DSTATUS disk_initialize (BYTE pdrv); +DSTATUS disk_status (BYTE pdrv); +DRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count); +DRESULT disk_write (BYTE pdrv, BYTE* buff, DWORD sector, UINT count); +DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff); +DWORD get_fattime (void); + +/* Disk Status Bits (DSTATUS) */ + +#define STA_NOINIT 0x01 /* Drive not initialized */ +#define STA_NODISK 0x02 /* No medium in the drive */ +#define STA_PROTECT 0x04 /* Write protected */ + + +/* Command code for disk_ioctrl fucntion */ + +/* Generic command (Used by FatFs) */ +#define CTRL_SYNC 0 /* Complete pending write process (needed at _FS_READONLY == 0) */ +#define GET_SECTOR_COUNT 1 /* Get media size (needed at _USE_MKFS == 1) */ +#define GET_SECTOR_SIZE 2 /* Get sector size (needed at _MAX_SS != _MIN_SS) */ +#define GET_BLOCK_SIZE 3 /* Get erase block size (needed at _USE_MKFS == 1) */ +#define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at _USE_TRIM == 1) */ + +/* Generic command (Not used by FatFs) */ +#define CTRL_POWER 5 /* Get/Set power status */ +#define CTRL_LOCK 6 /* Lock/Unlock media removal */ +#define CTRL_EJECT 7 /* Eject media */ +#define CTRL_FORMAT 8 /* Create physical format on the media */ + +/* MMC/SDC specific ioctl command */ +#define MMC_GET_TYPE 10 /* Get card type */ +#define MMC_GET_CSD 11 /* Get CSD */ +#define MMC_GET_CID 12 /* Get CID */ +#define MMC_GET_OCR 13 /* Get OCR */ +#define MMC_GET_SDSTAT 14 /* Get SD status */ + +/* ATA/CF specific ioctl command */ +#define ATA_GET_REV 20 /* Get F/W revision */ +#define ATA_GET_MODEL 21 /* Get model name */ +#define ATA_GET_SN 22 /* Get serial number */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/trunk/Arduino/ArduinoFDC/ff.c b/trunk/Arduino/ArduinoFDC/ff.c new file mode 100644 index 00000000..c116f35c --- /dev/null +++ b/trunk/Arduino/ArduinoFDC/ff.c @@ -0,0 +1,6984 @@ +/*----------------------------------------------------------------------------/ +/ FatFs - Generic FAT Filesystem Module R0.14b / +/-----------------------------------------------------------------------------/ +/ +/ Copyright (C) 2021, ChaN, all right reserved. +/ +/ FatFs module is an open source software. Redistribution and use of FatFs in +/ source and binary forms, with or without modification, are permitted provided +/ that the following condition is met: +/ +/ 1. Redistributions of source code must retain the above copyright notice, +/ this condition and the following disclaimer. +/ +/ This software is provided by the copyright holder and contributors "AS IS" +/ and any warranties related to this software are DISCLAIMED. +/ The copyright owner or contributors be NOT LIABLE for any damages caused +/ by use of this software. +/ +/----------------------------------------------------------------------------*/ + + +#include +#include "ff.h" /* Declarations of FatFs API */ +#include "diskio.h" /* Declarations of device I/O functions */ + + +/*-------------------------------------------------------------------------- + + Module Private Definitions + +---------------------------------------------------------------------------*/ + +#if FF_DEFINED != 86631 /* Revision ID */ +#error Wrong include file (ff.h). +#endif + + +/* Limits and boundaries */ +#define MAX_DIR 0x200000 /* Max size of FAT directory */ +#define MAX_DIR_EX 0x10000000 /* Max size of exFAT directory */ +#define MAX_FAT12 0xFF5 /* Max FAT12 clusters (differs from specs, but right for real DOS/Windows behavior) */ +#define MAX_FAT16 0xFFF5 /* Max FAT16 clusters (differs from specs, but right for real DOS/Windows behavior) */ +#define MAX_FAT32 0x0FFFFFF5 /* Max FAT32 clusters (not specified, practical limit) */ +#define MAX_EXFAT 0x7FFFFFFD /* Max exFAT clusters (differs from specs, implementation limit) */ + + +/* Character code support macros */ +#define IsUpper(c) ((c) >= 'A' && (c) <= 'Z') +#define IsLower(c) ((c) >= 'a' && (c) <= 'z') +#define IsDigit(c) ((c) >= '0' && (c) <= '9') +#define IsSeparator(c) ((c) == '/' || (c) == '\\') +#define IsTerminator(c) ((UINT)(c) < (FF_USE_LFN ? ' ' : '!')) +#define IsSurrogate(c) ((c) >= 0xD800 && (c) <= 0xDFFF) +#define IsSurrogateH(c) ((c) >= 0xD800 && (c) <= 0xDBFF) +#define IsSurrogateL(c) ((c) >= 0xDC00 && (c) <= 0xDFFF) + + +/* Additional file access control and file status flags for internal use */ +#define FA_SEEKEND 0x20 /* Seek to end of the file on file open */ +#define FA_MODIFIED 0x40 /* File has been modified */ +#define FA_DIRTY 0x80 /* FIL.buf[] needs to be written-back */ + + +/* Additional file attribute bits for internal use */ +#define AM_VOL 0x08 /* Volume label */ +#define AM_LFN 0x0F /* LFN entry */ +#define AM_MASK 0x3F /* Mask of defined bits in FAT */ +#define AM_MASKX 0x37 /* Mask of defined bits in exFAT */ + + +/* Name status flags in fn[11] */ +#define NSFLAG 11 /* Index of the name status byte */ +#define NS_LOSS 0x01 /* Out of 8.3 format */ +#define NS_LFN 0x02 /* Force to create LFN entry */ +#define NS_LAST 0x04 /* Last segment */ +#define NS_BODY 0x08 /* Lower case flag (body) */ +#define NS_EXT 0x10 /* Lower case flag (ext) */ +#define NS_DOT 0x20 /* Dot entry */ +#define NS_NOLFN 0x40 /* Do not find LFN */ +#define NS_NONAME 0x80 /* Not followed */ + + +/* exFAT directory entry types */ +#define ET_BITMAP 0x81 /* Allocation bitmap */ +#define ET_UPCASE 0x82 /* Up-case table */ +#define ET_VLABEL 0x83 /* Volume label */ +#define ET_FILEDIR 0x85 /* File and directory */ +#define ET_STREAM 0xC0 /* Stream extension */ +#define ET_FILENAME 0xC1 /* Name extension */ + + +/* FatFs refers the FAT structure as simple byte array instead of structure member +/ because the C structure is not binary compatible between different platforms */ + +#define BS_JmpBoot 0 /* x86 jump instruction (3-byte) */ +#define BS_OEMName 3 /* OEM name (8-byte) */ +#define BPB_BytsPerSec 11 /* Sector size [byte] (WORD) */ +#define BPB_SecPerClus 13 /* Cluster size [sector] (BYTE) */ +#define BPB_RsvdSecCnt 14 /* Size of reserved area [sector] (WORD) */ +#define BPB_NumFATs 16 /* Number of FATs (BYTE) */ +#define BPB_RootEntCnt 17 /* Size of root directory area for FAT [entry] (WORD) */ +#define BPB_TotSec16 19 /* Volume size (16-bit) [sector] (WORD) */ +#define BPB_Media 21 /* Media descriptor byte (BYTE) */ +#define BPB_FATSz16 22 /* FAT size (16-bit) [sector] (WORD) */ +#define BPB_SecPerTrk 24 /* Number of sectors per track for int13h [sector] (WORD) */ +#define BPB_NumHeads 26 /* Number of heads for int13h (WORD) */ +#define BPB_HiddSec 28 /* Volume offset from top of the drive (DWORD) */ +#define BPB_TotSec32 32 /* Volume size (32-bit) [sector] (DWORD) */ +#define BS_DrvNum 36 /* Physical drive number for int13h (BYTE) */ +#define BS_NTres 37 /* WindowsNT error flag (BYTE) */ +#define BS_BootSig 38 /* Extended boot signature (BYTE) */ +#define BS_VolID 39 /* Volume serial number (DWORD) */ +#define BS_VolLab 43 /* Volume label string (8-byte) */ +#define BS_FilSysType 54 /* Filesystem type string (8-byte) */ +#define BS_BootCode 62 /* Boot code (448-byte) */ +#define BS_55AA 510 /* Signature word (WORD) */ + +#define BPB_FATSz32 36 /* FAT32: FAT size [sector] (DWORD) */ +#define BPB_ExtFlags32 40 /* FAT32: Extended flags (WORD) */ +#define BPB_FSVer32 42 /* FAT32: Filesystem version (WORD) */ +#define BPB_RootClus32 44 /* FAT32: Root directory cluster (DWORD) */ +#define BPB_FSInfo32 48 /* FAT32: Offset of FSINFO sector (WORD) */ +#define BPB_BkBootSec32 50 /* FAT32: Offset of backup boot sector (WORD) */ +#define BS_DrvNum32 64 /* FAT32: Physical drive number for int13h (BYTE) */ +#define BS_NTres32 65 /* FAT32: Error flag (BYTE) */ +#define BS_BootSig32 66 /* FAT32: Extended boot signature (BYTE) */ +#define BS_VolID32 67 /* FAT32: Volume serial number (DWORD) */ +#define BS_VolLab32 71 /* FAT32: Volume label string (8-byte) */ +#define BS_FilSysType32 82 /* FAT32: Filesystem type string (8-byte) */ +#define BS_BootCode32 90 /* FAT32: Boot code (420-byte) */ + +#define BPB_ZeroedEx 11 /* exFAT: MBZ field (53-byte) */ +#define BPB_VolOfsEx 64 /* exFAT: Volume offset from top of the drive [sector] (QWORD) */ +#define BPB_TotSecEx 72 /* exFAT: Volume size [sector] (QWORD) */ +#define BPB_FatOfsEx 80 /* exFAT: FAT offset from top of the volume [sector] (DWORD) */ +#define BPB_FatSzEx 84 /* exFAT: FAT size [sector] (DWORD) */ +#define BPB_DataOfsEx 88 /* exFAT: Data offset from top of the volume [sector] (DWORD) */ +#define BPB_NumClusEx 92 /* exFAT: Number of clusters (DWORD) */ +#define BPB_RootClusEx 96 /* exFAT: Root directory start cluster (DWORD) */ +#define BPB_VolIDEx 100 /* exFAT: Volume serial number (DWORD) */ +#define BPB_FSVerEx 104 /* exFAT: Filesystem version (WORD) */ +#define BPB_VolFlagEx 106 /* exFAT: Volume flags (WORD) */ +#define BPB_BytsPerSecEx 108 /* exFAT: Log2 of sector size in unit of byte (BYTE) */ +#define BPB_SecPerClusEx 109 /* exFAT: Log2 of cluster size in unit of sector (BYTE) */ +#define BPB_NumFATsEx 110 /* exFAT: Number of FATs (BYTE) */ +#define BPB_DrvNumEx 111 /* exFAT: Physical drive number for int13h (BYTE) */ +#define BPB_PercInUseEx 112 /* exFAT: Percent in use (BYTE) */ +#define BPB_RsvdEx 113 /* exFAT: Reserved (7-byte) */ +#define BS_BootCodeEx 120 /* exFAT: Boot code (390-byte) */ + +#define DIR_Name 0 /* Short file name (11-byte) */ +#define DIR_Attr 11 /* Attribute (BYTE) */ +#define DIR_NTres 12 /* Lower case flag (BYTE) */ +#define DIR_CrtTime10 13 /* Created time sub-second (BYTE) */ +#define DIR_CrtTime 14 /* Created time (DWORD) */ +#define DIR_LstAccDate 18 /* Last accessed date (WORD) */ +#define DIR_FstClusHI 20 /* Higher 16-bit of first cluster (WORD) */ +#define DIR_ModTime 22 /* Modified time (DWORD) */ +#define DIR_FstClusLO 26 /* Lower 16-bit of first cluster (WORD) */ +#define DIR_FileSize 28 /* File size (DWORD) */ +#define LDIR_Ord 0 /* LFN: LFN order and LLE flag (BYTE) */ +#define LDIR_Attr 11 /* LFN: LFN attribute (BYTE) */ +#define LDIR_Type 12 /* LFN: Entry type (BYTE) */ +#define LDIR_Chksum 13 /* LFN: Checksum of the SFN (BYTE) */ +#define LDIR_FstClusLO 26 /* LFN: MBZ field (WORD) */ +#define XDIR_Type 0 /* exFAT: Type of exFAT directory entry (BYTE) */ +#define XDIR_NumLabel 1 /* exFAT: Number of volume label characters (BYTE) */ +#define XDIR_Label 2 /* exFAT: Volume label (11-WORD) */ +#define XDIR_CaseSum 4 /* exFAT: Sum of case conversion table (DWORD) */ +#define XDIR_NumSec 1 /* exFAT: Number of secondary entries (BYTE) */ +#define XDIR_SetSum 2 /* exFAT: Sum of the set of directory entries (WORD) */ +#define XDIR_Attr 4 /* exFAT: File attribute (WORD) */ +#define XDIR_CrtTime 8 /* exFAT: Created time (DWORD) */ +#define XDIR_ModTime 12 /* exFAT: Modified time (DWORD) */ +#define XDIR_AccTime 16 /* exFAT: Last accessed time (DWORD) */ +#define XDIR_CrtTime10 20 /* exFAT: Created time subsecond (BYTE) */ +#define XDIR_ModTime10 21 /* exFAT: Modified time subsecond (BYTE) */ +#define XDIR_CrtTZ 22 /* exFAT: Created timezone (BYTE) */ +#define XDIR_ModTZ 23 /* exFAT: Modified timezone (BYTE) */ +#define XDIR_AccTZ 24 /* exFAT: Last accessed timezone (BYTE) */ +#define XDIR_GenFlags 33 /* exFAT: General secondary flags (BYTE) */ +#define XDIR_NumName 35 /* exFAT: Number of file name characters (BYTE) */ +#define XDIR_NameHash 36 /* exFAT: Hash of file name (WORD) */ +#define XDIR_ValidFileSize 40 /* exFAT: Valid file size (QWORD) */ +#define XDIR_FstClus 52 /* exFAT: First cluster of the file data (DWORD) */ +#define XDIR_FileSize 56 /* exFAT: File/Directory size (QWORD) */ + +#define SZDIRE 32 /* Size of a directory entry */ +#define DDEM 0xE5 /* Deleted directory entry mark set to DIR_Name[0] */ +#define RDDEM 0x05 /* Replacement of the character collides with DDEM */ +#define LLEF 0x40 /* Last long entry flag in LDIR_Ord */ + +#define FSI_LeadSig 0 /* FAT32 FSI: Leading signature (DWORD) */ +#define FSI_StrucSig 484 /* FAT32 FSI: Structure signature (DWORD) */ +#define FSI_Free_Count 488 /* FAT32 FSI: Number of free clusters (DWORD) */ +#define FSI_Nxt_Free 492 /* FAT32 FSI: Last allocated cluster (DWORD) */ + +#define MBR_Table 446 /* MBR: Offset of partition table in the MBR */ +#define SZ_PTE 16 /* MBR: Size of a partition table entry */ +#define PTE_Boot 0 /* MBR PTE: Boot indicator */ +#define PTE_StHead 1 /* MBR PTE: Start head */ +#define PTE_StSec 2 /* MBR PTE: Start sector */ +#define PTE_StCyl 3 /* MBR PTE: Start cylinder */ +#define PTE_System 4 /* MBR PTE: System ID */ +#define PTE_EdHead 5 /* MBR PTE: End head */ +#define PTE_EdSec 6 /* MBR PTE: End sector */ +#define PTE_EdCyl 7 /* MBR PTE: End cylinder */ +#define PTE_StLba 8 /* MBR PTE: Start in LBA */ +#define PTE_SizLba 12 /* MBR PTE: Size in LBA */ + +#define GPTH_Sign 0 /* GPT: Header signature (8-byte) */ +#define GPTH_Rev 8 /* GPT: Revision (DWORD) */ +#define GPTH_Size 12 /* GPT: Header size (DWORD) */ +#define GPTH_Bcc 16 /* GPT: Header BCC (DWORD) */ +#define GPTH_CurLba 24 /* GPT: Main header LBA (QWORD) */ +#define GPTH_BakLba 32 /* GPT: Backup header LBA (QWORD) */ +#define GPTH_FstLba 40 /* GPT: First LBA for partitions (QWORD) */ +#define GPTH_LstLba 48 /* GPT: Last LBA for partitions (QWORD) */ +#define GPTH_DskGuid 56 /* GPT: Disk GUID (16-byte) */ +#define GPTH_PtOfs 72 /* GPT: Partation table LBA (QWORD) */ +#define GPTH_PtNum 80 /* GPT: Number of table entries (DWORD) */ +#define GPTH_PteSize 84 /* GPT: Size of table entry (DWORD) */ +#define GPTH_PtBcc 88 /* GPT: Partation table BCC (DWORD) */ +#define SZ_GPTE 128 /* GPT: Size of partition table entry */ +#define GPTE_PtGuid 0 /* GPT PTE: Partition type GUID (16-byte) */ +#define GPTE_UpGuid 16 /* GPT PTE: Partition unique GUID (16-byte) */ +#define GPTE_FstLba 32 /* GPT PTE: First LBA (QWORD) */ +#define GPTE_LstLba 40 /* GPT PTE: Last LBA inclusive (QWORD) */ +#define GPTE_Flags 48 /* GPT PTE: Flags (QWORD) */ +#define GPTE_Name 56 /* GPT PTE: Name */ + + +/* Post process on fatal error in the file operations */ +#define ABORT(fs, res) { fp->err = (BYTE)(res); LEAVE_FF(fs, res); } + + +/* Re-entrancy related */ +#if FF_FS_REENTRANT +#if FF_USE_LFN == 1 +#error Static LFN work area cannot be used in thread-safe configuration +#endif +#define LEAVE_FF(fs, res) { unlock_fs(fs, res); return res; } +#else +#define LEAVE_FF(fs, res) return res +#endif + + +/* Definitions of logical drive - physical location conversion */ +#if FF_MULTI_PARTITION +#define LD2PD(vol) VolToPart[vol].pd /* Get physical drive number */ +#define LD2PT(vol) VolToPart[vol].pt /* Get partition number (0:auto search, 1..:forced partition number) */ +#else +#define LD2PD(vol) (BYTE)(vol) /* Each logical drive is associated with the same physical drive number */ +#define LD2PT(vol) 0 /* Auto partition search */ +#endif + + +/* Definitions of sector size */ +#if (FF_MAX_SS < FF_MIN_SS) || (FF_MAX_SS != 512 && FF_MAX_SS != 1024 && FF_MAX_SS != 2048 && FF_MAX_SS != 4096) || (FF_MIN_SS != 512 && FF_MIN_SS != 1024 && FF_MIN_SS != 2048 && FF_MIN_SS != 4096) +#error Wrong sector size configuration +#endif +#if FF_MAX_SS == FF_MIN_SS +#define SS(fs) ((UINT)FF_MAX_SS) /* Fixed sector size */ +#else +#define SS(fs) ((fs)->ssize) /* Variable sector size */ +#endif + + +/* Timestamp */ +#if FF_FS_NORTC == 1 +#if FF_NORTC_YEAR < 1980 || FF_NORTC_YEAR > 2107 || FF_NORTC_MON < 1 || FF_NORTC_MON > 12 || FF_NORTC_MDAY < 1 || FF_NORTC_MDAY > 31 +#error Invalid FF_FS_NORTC settings +#endif +#define GET_FATTIME() ((DWORD)(FF_NORTC_YEAR - 1980) << 25 | (DWORD)FF_NORTC_MON << 21 | (DWORD)FF_NORTC_MDAY << 16) +#else +#define GET_FATTIME() get_fattime() +#endif + + +/* File lock controls */ +#if FF_FS_LOCK != 0 +#if FF_FS_READONLY +#error FF_FS_LOCK must be 0 at read-only configuration +#endif +typedef struct { + FATFS *fs; /* Object ID 1, volume (NULL:blank entry) */ + DWORD clu; /* Object ID 2, containing directory (0:root) */ + DWORD ofs; /* Object ID 3, offset in the directory */ + WORD ctr; /* Object open counter, 0:none, 0x01..0xFF:read mode open count, 0x100:write mode */ +} FILESEM; +#endif + + +/* SBCS up-case tables (\x80-\xFF) */ +#define TBL_CT437 {0x80,0x9A,0x45,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x49,0x49,0x49,0x8E,0x8F, \ + 0x90,0x92,0x92,0x4F,0x99,0x4F,0x55,0x55,0x59,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ + 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ + 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \ + 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} +#define TBL_CT720 {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \ + 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ + 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ + 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \ + 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} +#define TBL_CT737 {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \ + 0x90,0x92,0x92,0x93,0x94,0x95,0x96,0x97,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87, \ + 0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0xAA,0x92,0x93,0x94,0x95,0x96, \ + 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ + 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0x97,0xEA,0xEB,0xEC,0xE4,0xED,0xEE,0xEF,0xF5,0xF0,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \ + 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} +#define TBL_CT771 {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \ + 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \ + 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ + 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDC,0xDE,0xDE, \ + 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0xF0,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF8,0xFA,0xFA,0xFC,0xFC,0xFE,0xFF} +#define TBL_CT775 {0x80,0x9A,0x91,0xA0,0x8E,0x95,0x8F,0x80,0xAD,0xED,0x8A,0x8A,0xA1,0x8D,0x8E,0x8F, \ + 0x90,0x92,0x92,0xE2,0x99,0x95,0x96,0x97,0x97,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xE0,0xA3,0xA3,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ + 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ + 0xB5,0xB6,0xB7,0xB8,0xBD,0xBE,0xC6,0xC7,0xA5,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE3,0xE8,0xE8,0xEA,0xEA,0xEE,0xED,0xEE,0xEF, \ + 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} +#define TBL_CT850 {0x43,0x55,0x45,0x41,0x41,0x41,0x41,0x43,0x45,0x45,0x45,0x49,0x49,0x49,0x41,0x41, \ + 0x45,0x92,0x92,0x4F,0x4F,0x4F,0x55,0x55,0x59,0x4F,0x55,0x4F,0x9C,0x4F,0x9E,0x9F, \ + 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ + 0xB0,0xB1,0xB2,0xB3,0xB4,0x41,0x41,0x41,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0x41,0x41,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ + 0xD1,0xD1,0x45,0x45,0x45,0x49,0x49,0x49,0x49,0xD9,0xDA,0xDB,0xDC,0xDD,0x49,0xDF, \ + 0x4F,0xE1,0x4F,0x4F,0x4F,0x4F,0xE6,0xE8,0xE8,0x55,0x55,0x55,0x59,0x59,0xEE,0xEF, \ + 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} +#define TBL_CT852 {0x80,0x9A,0x90,0xB6,0x8E,0xDE,0x8F,0x80,0x9D,0xD3,0x8A,0x8A,0xD7,0x8D,0x8E,0x8F, \ + 0x90,0x91,0x91,0xE2,0x99,0x95,0x95,0x97,0x97,0x99,0x9A,0x9B,0x9B,0x9D,0x9E,0xAC, \ + 0xB5,0xD6,0xE0,0xE9,0xA4,0xA4,0xA6,0xA6,0xA8,0xA8,0xAA,0x8D,0xAC,0xB8,0xAE,0xAF, \ + 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBD,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC6,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ + 0xD1,0xD1,0xD2,0xD3,0xD2,0xD5,0xD6,0xD7,0xB7,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE3,0xD5,0xE6,0xE6,0xE8,0xE9,0xE8,0xEB,0xED,0xED,0xDD,0xEF, \ + 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xEB,0xFC,0xFC,0xFE,0xFF} +#define TBL_CT855 {0x81,0x81,0x83,0x83,0x85,0x85,0x87,0x87,0x89,0x89,0x8B,0x8B,0x8D,0x8D,0x8F,0x8F, \ + 0x91,0x91,0x93,0x93,0x95,0x95,0x97,0x97,0x99,0x99,0x9B,0x9B,0x9D,0x9D,0x9F,0x9F, \ + 0xA1,0xA1,0xA3,0xA3,0xA5,0xA5,0xA7,0xA7,0xA9,0xA9,0xAB,0xAB,0xAD,0xAD,0xAE,0xAF, \ + 0xB0,0xB1,0xB2,0xB3,0xB4,0xB6,0xB6,0xB8,0xB8,0xB9,0xBA,0xBB,0xBC,0xBE,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ + 0xD1,0xD1,0xD3,0xD3,0xD5,0xD5,0xD7,0xD7,0xDD,0xD9,0xDA,0xDB,0xDC,0xDD,0xE0,0xDF, \ + 0xE0,0xE2,0xE2,0xE4,0xE4,0xE6,0xE6,0xE8,0xE8,0xEA,0xEA,0xEC,0xEC,0xEE,0xEE,0xEF, \ + 0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF8,0xFA,0xFA,0xFC,0xFC,0xFD,0xFE,0xFF} +#define TBL_CT857 {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0x49,0x8E,0x8F, \ + 0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x98,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9E, \ + 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA6,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ + 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ + 0xD0,0xD1,0xD2,0xD3,0xD4,0x49,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xDE,0xED,0xEE,0xEF, \ + 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} +#define TBL_CT860 {0x80,0x9A,0x90,0x8F,0x8E,0x91,0x86,0x80,0x89,0x89,0x92,0x8B,0x8C,0x98,0x8E,0x8F, \ + 0x90,0x91,0x92,0x8C,0x99,0xA9,0x96,0x9D,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0x86,0x8B,0x9F,0x96,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ + 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ + 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \ + 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} +#define TBL_CT861 {0x80,0x9A,0x90,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x8B,0x8B,0x8D,0x8E,0x8F, \ + 0x90,0x92,0x92,0x4F,0x99,0x8D,0x55,0x97,0x97,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \ + 0xA4,0xA5,0xA6,0xA7,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ + 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ + 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \ + 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} +#define TBL_CT862 {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \ + 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ + 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ + 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \ + 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} +#define TBL_CT863 {0x43,0x55,0x45,0x41,0x41,0x41,0x86,0x43,0x45,0x45,0x45,0x49,0x49,0x8D,0x41,0x8F, \ + 0x45,0x45,0x45,0x4F,0x45,0x49,0x55,0x55,0x98,0x4F,0x55,0x9B,0x9C,0x55,0x55,0x9F, \ + 0xA0,0xA1,0x4F,0x55,0xA4,0xA5,0xA6,0xA7,0x49,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ + 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ + 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \ + 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} +#define TBL_CT864 {0x80,0x9A,0x45,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x49,0x49,0x49,0x8E,0x8F, \ + 0x90,0x92,0x92,0x4F,0x99,0x4F,0x55,0x55,0x59,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ + 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ + 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \ + 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} +#define TBL_CT865 {0x80,0x9A,0x90,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x49,0x49,0x49,0x8E,0x8F, \ + 0x90,0x92,0x92,0x4F,0x99,0x4F,0x55,0x55,0x59,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ + 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ + 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \ + 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} +#define TBL_CT866 {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \ + 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \ + 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ + 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0xF0,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} +#define TBL_CT869 {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \ + 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x86,0x9C,0x8D,0x8F,0x90, \ + 0x91,0x90,0x92,0x95,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ + 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ + 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xA4,0xA5,0xA6,0xD9,0xDA,0xDB,0xDC,0xA7,0xA8,0xDF, \ + 0xA9,0xAA,0xAC,0xAD,0xB5,0xB6,0xB7,0xB8,0xBD,0xBE,0xC6,0xC7,0xCF,0xCF,0xD0,0xEF, \ + 0xF0,0xF1,0xD1,0xD2,0xD3,0xF5,0xD4,0xF7,0xF8,0xF9,0xD5,0x96,0x95,0x98,0xFE,0xFF} + + +/* DBCS code range |----- 1st byte -----| |----------- 2nd byte -----------| */ +/* <------> <------> <------> <------> <------> */ +#define TBL_DC932 {0x81, 0x9F, 0xE0, 0xFC, 0x40, 0x7E, 0x80, 0xFC, 0x00, 0x00} +#define TBL_DC936 {0x81, 0xFE, 0x00, 0x00, 0x40, 0x7E, 0x80, 0xFE, 0x00, 0x00} +#define TBL_DC949 {0x81, 0xFE, 0x00, 0x00, 0x41, 0x5A, 0x61, 0x7A, 0x81, 0xFE} +#define TBL_DC950 {0x81, 0xFE, 0x00, 0x00, 0x40, 0x7E, 0xA1, 0xFE, 0x00, 0x00} + + +/* Macros for table definitions */ +#define MERGE_2STR(a, b) a ## b +#define MKCVTBL(hd, cp) MERGE_2STR(hd, cp) + + + + +/*-------------------------------------------------------------------------- + + Module Private Work Area + +---------------------------------------------------------------------------*/ +/* Remark: Variables defined here without initial value shall be guaranteed +/ zero/null at start-up. If not, the linker option or start-up routine is +/ not compliance with C standard. */ + +/*--------------------------------*/ +/* File/Volume controls */ +/*--------------------------------*/ + +#if FF_VOLUMES < 1 || FF_VOLUMES > 10 +#error Wrong FF_VOLUMES setting +#endif +static FATFS* FatFs[FF_VOLUMES]; /* Pointer to the filesystem objects (logical drives) */ +static WORD Fsid; /* Filesystem mount ID */ + +#if FF_FS_RPATH != 0 +static BYTE CurrVol; /* Current drive */ +#endif + +#if FF_FS_LOCK != 0 +static FILESEM Files[FF_FS_LOCK]; /* Open object lock semaphores */ +#endif + +#if FF_STR_VOLUME_ID +#ifdef FF_VOLUME_STRS +static const char* const VolumeStr[FF_VOLUMES] = {FF_VOLUME_STRS}; /* Pre-defined volume ID */ +#endif +#endif + +#if FF_LBA64 +#if FF_MIN_GPT > 0x100000000 +#error Wrong FF_MIN_GPT setting +#endif +static const BYTE GUID_MS_Basic[16] = {0xA2,0xA0,0xD0,0xEB,0xE5,0xB9,0x33,0x44,0x87,0xC0,0x68,0xB6,0xB7,0x26,0x99,0xC7}; +#endif + + + +/*--------------------------------*/ +/* LFN/Directory working buffer */ +/*--------------------------------*/ + +#if FF_USE_LFN == 0 /* Non-LFN configuration */ +#if FF_FS_EXFAT +#error LFN must be enabled when enable exFAT +#endif +#define DEF_NAMBUF +#define INIT_NAMBUF(fs) +#define FREE_NAMBUF() +#define LEAVE_MKFS(res) return res + +#else /* LFN configurations */ +#if FF_MAX_LFN < 12 || FF_MAX_LFN > 255 +#error Wrong setting of FF_MAX_LFN +#endif +#if FF_LFN_BUF < FF_SFN_BUF || FF_SFN_BUF < 12 +#error Wrong setting of FF_LFN_BUF or FF_SFN_BUF +#endif +#if FF_LFN_UNICODE < 0 || FF_LFN_UNICODE > 3 +#error Wrong setting of FF_LFN_UNICODE +#endif +static const BYTE LfnOfs[] = {1,3,5,7,9,14,16,18,20,22,24,28,30}; /* FAT: Offset of LFN characters in the directory entry */ +#define MAXDIRB(nc) ((nc + 44U) / 15 * SZDIRE) /* exFAT: Size of directory entry block scratchpad buffer needed for the name length */ + +#if FF_USE_LFN == 1 /* LFN enabled with static working buffer */ +#if FF_FS_EXFAT +static BYTE DirBuf[MAXDIRB(FF_MAX_LFN)]; /* Directory entry block scratchpad buffer */ +#endif +static WCHAR LfnBuf[FF_MAX_LFN + 1]; /* LFN working buffer */ +#define DEF_NAMBUF +#define INIT_NAMBUF(fs) +#define FREE_NAMBUF() +#define LEAVE_MKFS(res) return res + +#elif FF_USE_LFN == 2 /* LFN enabled with dynamic working buffer on the stack */ +#if FF_FS_EXFAT +#define DEF_NAMBUF WCHAR lbuf[FF_MAX_LFN+1]; BYTE dbuf[MAXDIRB(FF_MAX_LFN)]; /* LFN working buffer and directory entry block scratchpad buffer */ +#define INIT_NAMBUF(fs) { (fs)->lfnbuf = lbuf; (fs)->dirbuf = dbuf; } +#define FREE_NAMBUF() +#else +#define DEF_NAMBUF WCHAR lbuf[FF_MAX_LFN+1]; /* LFN working buffer */ +#define INIT_NAMBUF(fs) { (fs)->lfnbuf = lbuf; } +#define FREE_NAMBUF() +#endif +#define LEAVE_MKFS(res) return res + +#elif FF_USE_LFN == 3 /* LFN enabled with dynamic working buffer on the heap */ +#if FF_FS_EXFAT +#define DEF_NAMBUF WCHAR *lfn; /* Pointer to LFN working buffer and directory entry block scratchpad buffer */ +#define INIT_NAMBUF(fs) { lfn = ff_memalloc((FF_MAX_LFN+1)*2 + MAXDIRB(FF_MAX_LFN)); if (!lfn) LEAVE_FF(fs, FR_NOT_ENOUGH_CORE); (fs)->lfnbuf = lfn; (fs)->dirbuf = (BYTE*)(lfn+FF_MAX_LFN+1); } +#define FREE_NAMBUF() ff_memfree(lfn) +#else +#define DEF_NAMBUF WCHAR *lfn; /* Pointer to LFN working buffer */ +#define INIT_NAMBUF(fs) { lfn = ff_memalloc((FF_MAX_LFN+1)*2); if (!lfn) LEAVE_FF(fs, FR_NOT_ENOUGH_CORE); (fs)->lfnbuf = lfn; } +#define FREE_NAMBUF() ff_memfree(lfn) +#endif +#define LEAVE_MKFS(res) { if (!work) ff_memfree(buf); return res; } +#define MAX_MALLOC 0x8000 /* Must be >=FF_MAX_SS */ + +#else +#error Wrong setting of FF_USE_LFN + +#endif /* FF_USE_LFN == 1 */ +#endif /* FF_USE_LFN == 0 */ + + + +/*--------------------------------*/ +/* Code conversion tables */ +/*--------------------------------*/ + +#if FF_CODE_PAGE == -1 /* no code page character transformations */ +#elif FF_CODE_PAGE == 0 /* Run-time code page configuration */ +#define CODEPAGE CodePage +static WORD CodePage; /* Current code page */ +static const BYTE *ExCvt, *DbcTbl; /* Pointer to current SBCS up-case table and DBCS code range table below */ + +static const BYTE Ct437[] = TBL_CT437; +static const BYTE Ct720[] = TBL_CT720; +static const BYTE Ct737[] = TBL_CT737; +static const BYTE Ct771[] = TBL_CT771; +static const BYTE Ct775[] = TBL_CT775; +static const BYTE Ct850[] = TBL_CT850; +static const BYTE Ct852[] = TBL_CT852; +static const BYTE Ct855[] = TBL_CT855; +static const BYTE Ct857[] = TBL_CT857; +static const BYTE Ct860[] = TBL_CT860; +static const BYTE Ct861[] = TBL_CT861; +static const BYTE Ct862[] = TBL_CT862; +static const BYTE Ct863[] = TBL_CT863; +static const BYTE Ct864[] = TBL_CT864; +static const BYTE Ct865[] = TBL_CT865; +static const BYTE Ct866[] = TBL_CT866; +static const BYTE Ct869[] = TBL_CT869; +static const BYTE Dc932[] = TBL_DC932; +static const BYTE Dc936[] = TBL_DC936; +static const BYTE Dc949[] = TBL_DC949; +static const BYTE Dc950[] = TBL_DC950; + +#elif FF_CODE_PAGE < 900 /* Static code page configuration (SBCS) */ +#define CODEPAGE FF_CODE_PAGE +static const BYTE ExCvt[] = MKCVTBL(TBL_CT, FF_CODE_PAGE); + +#else /* Static code page configuration (DBCS) */ +#define CODEPAGE FF_CODE_PAGE +static const BYTE DbcTbl[] = MKCVTBL(TBL_DC, FF_CODE_PAGE); + +#endif + + + + +/*-------------------------------------------------------------------------- + + Module Private Functions + +---------------------------------------------------------------------------*/ + + +/*-----------------------------------------------------------------------*/ +/* Load/Store multi-byte word in the FAT structure */ +/*-----------------------------------------------------------------------*/ + +static WORD ld_word (const BYTE* ptr) /* Load a 2-byte little-endian word */ +{ + WORD rv; + + rv = ptr[1]; + rv = rv << 8 | ptr[0]; + return rv; +} + +static DWORD ld_dword (const BYTE* ptr) /* Load a 4-byte little-endian word */ +{ + DWORD rv; + + rv = ptr[3]; + rv = rv << 8 | ptr[2]; + rv = rv << 8 | ptr[1]; + rv = rv << 8 | ptr[0]; + return rv; +} + +#if FF_FS_EXFAT +static QWORD ld_qword (const BYTE* ptr) /* Load an 8-byte little-endian word */ +{ + QWORD rv; + + rv = ptr[7]; + rv = rv << 8 | ptr[6]; + rv = rv << 8 | ptr[5]; + rv = rv << 8 | ptr[4]; + rv = rv << 8 | ptr[3]; + rv = rv << 8 | ptr[2]; + rv = rv << 8 | ptr[1]; + rv = rv << 8 | ptr[0]; + return rv; +} +#endif + +#if !FF_FS_READONLY +static void st_word (BYTE* ptr, WORD val) /* Store a 2-byte word in little-endian */ +{ + *ptr++ = (BYTE)val; val >>= 8; + *ptr++ = (BYTE)val; +} + +static void st_dword (BYTE* ptr, DWORD val) /* Store a 4-byte word in little-endian */ +{ + *ptr++ = (BYTE)val; val >>= 8; + *ptr++ = (BYTE)val; val >>= 8; + *ptr++ = (BYTE)val; val >>= 8; + *ptr++ = (BYTE)val; +} + +#if FF_FS_EXFAT +static void st_qword (BYTE* ptr, QWORD val) /* Store an 8-byte word in little-endian */ +{ + *ptr++ = (BYTE)val; val >>= 8; + *ptr++ = (BYTE)val; val >>= 8; + *ptr++ = (BYTE)val; val >>= 8; + *ptr++ = (BYTE)val; val >>= 8; + *ptr++ = (BYTE)val; val >>= 8; + *ptr++ = (BYTE)val; val >>= 8; + *ptr++ = (BYTE)val; val >>= 8; + *ptr++ = (BYTE)val; +} +#endif +#endif /* !FF_FS_READONLY */ + + + +/*-----------------------------------------------------------------------*/ +/* String functions */ +/*-----------------------------------------------------------------------*/ + +/* Test if the byte is DBC 1st byte */ +static int dbc_1st (BYTE c) +{ +#if FF_CODE_PAGE == 0 /* Variable code page */ + if (DbcTbl && c >= DbcTbl[0]) { + if (c <= DbcTbl[1]) return 1; /* 1st byte range 1 */ + if (c >= DbcTbl[2] && c <= DbcTbl[3]) return 1; /* 1st byte range 2 */ + } +#elif FF_CODE_PAGE >= 900 /* DBCS fixed code page */ + if (c >= DbcTbl[0]) { + if (c <= DbcTbl[1]) return 1; + if (c >= DbcTbl[2] && c <= DbcTbl[3]) return 1; + } +#else /* SBCS fixed code page */ + if (c != 0) return 0; /* Always false */ +#endif + return 0; +} + + +/* Test if the byte is DBC 2nd byte */ +static int dbc_2nd (BYTE c) +{ +#if FF_CODE_PAGE == 0 /* Variable code page */ + if (DbcTbl && c >= DbcTbl[4]) { + if (c <= DbcTbl[5]) return 1; /* 2nd byte range 1 */ + if (c >= DbcTbl[6] && c <= DbcTbl[7]) return 1; /* 2nd byte range 2 */ + if (c >= DbcTbl[8] && c <= DbcTbl[9]) return 1; /* 2nd byte range 3 */ + } +#elif FF_CODE_PAGE >= 900 /* DBCS fixed code page */ + if (c >= DbcTbl[4]) { + if (c <= DbcTbl[5]) return 1; + if (c >= DbcTbl[6] && c <= DbcTbl[7]) return 1; + if (c >= DbcTbl[8] && c <= DbcTbl[9]) return 1; + } +#else /* SBCS fixed code page */ + if (c != 0) return 0; /* Always false */ +#endif + return 0; +} + + +#if FF_USE_LFN + +/* Get a Unicode code point from the TCHAR string in defined API encodeing */ +static DWORD tchar2uni ( /* Returns a character in UTF-16 encoding (>=0x10000 on surrogate pair, 0xFFFFFFFF on decode error) */ + const TCHAR** str /* Pointer to pointer to TCHAR string in configured encoding */ +) +{ + DWORD uc; + const TCHAR *p = *str; + +#if FF_LFN_UNICODE == 1 /* UTF-16 input */ + WCHAR wc; + + uc = *p++; /* Get a unit */ + if (IsSurrogate(uc)) { /* Surrogate? */ + wc = *p++; /* Get low surrogate */ + if (!IsSurrogateH(uc) || !IsSurrogateL(wc)) return 0xFFFFFFFF; /* Wrong surrogate? */ + uc = uc << 16 | wc; + } + +#elif FF_LFN_UNICODE == 2 /* UTF-8 input */ + BYTE b; + int nf; + + uc = (BYTE)*p++; /* Get an encoding unit */ + if (uc & 0x80) { /* Multiple byte code? */ + if ((uc & 0xE0) == 0xC0) { /* 2-byte sequence? */ + uc &= 0x1F; nf = 1; + } else if ((uc & 0xF0) == 0xE0) { /* 3-byte sequence? */ + uc &= 0x0F; nf = 2; + } else if ((uc & 0xF8) == 0xF0) { /* 4-byte sequence? */ + uc &= 0x07; nf = 3; + } else { /* Wrong sequence */ + return 0xFFFFFFFF; + } + do { /* Get trailing bytes */ + b = (BYTE)*p++; + if ((b & 0xC0) != 0x80) return 0xFFFFFFFF; /* Wrong sequence? */ + uc = uc << 6 | (b & 0x3F); + } while (--nf != 0); + if (uc < 0x80 || IsSurrogate(uc) || uc >= 0x110000) return 0xFFFFFFFF; /* Wrong code? */ + if (uc >= 0x010000) uc = 0xD800DC00 | ((uc - 0x10000) << 6 & 0x3FF0000) | (uc & 0x3FF); /* Make a surrogate pair if needed */ + } + +#elif FF_LFN_UNICODE == 3 /* UTF-32 input */ + uc = (TCHAR)*p++; /* Get a unit */ + if (uc >= 0x110000 || IsSurrogate(uc)) return 0xFFFFFFFF; /* Wrong code? */ + if (uc >= 0x010000) uc = 0xD800DC00 | ((uc - 0x10000) << 6 & 0x3FF0000) | (uc & 0x3FF); /* Make a surrogate pair if needed */ + +#else /* ANSI/OEM input */ + BYTE b; + WCHAR wc; + + wc = (BYTE)*p++; /* Get a byte */ + if (dbc_1st((BYTE)wc)) { /* Is it a DBC 1st byte? */ + b = (BYTE)*p++; /* Get 2nd byte */ + if (!dbc_2nd(b)) return 0xFFFFFFFF; /* Invalid code? */ + wc = (wc << 8) + b; /* Make a DBC */ + } + if (wc != 0) { + wc = ff_oem2uni(wc, CODEPAGE); /* ANSI/OEM ==> Unicode */ + if (wc == 0) return 0xFFFFFFFF; /* Invalid code? */ + } + uc = wc; + +#endif + *str = p; /* Next read pointer */ + return uc; +} + + +/* Store a Unicode char in defined API encoding */ +static UINT put_utf ( /* Returns number of encoding units written (0:buffer overflow or wrong encoding) */ + DWORD chr, /* UTF-16 encoded character (Surrogate pair if >=0x10000) */ + TCHAR* buf, /* Output buffer */ + UINT szb /* Size of the buffer */ +) +{ +#if FF_LFN_UNICODE == 1 /* UTF-16 output */ + WCHAR hs, wc; + + hs = (WCHAR)(chr >> 16); + wc = (WCHAR)chr; + if (hs == 0) { /* Single encoding unit? */ + if (szb < 1 || IsSurrogate(wc)) return 0; /* Buffer overflow or wrong code? */ + *buf = wc; + return 1; + } + if (szb < 2 || !IsSurrogateH(hs) || !IsSurrogateL(wc)) return 0; /* Buffer overflow or wrong surrogate? */ + *buf++ = hs; + *buf++ = wc; + return 2; + +#elif FF_LFN_UNICODE == 2 /* UTF-8 output */ + DWORD hc; + + if (chr < 0x80) { /* Single byte code? */ + if (szb < 1) return 0; /* Buffer overflow? */ + *buf = (TCHAR)chr; + return 1; + } + if (chr < 0x800) { /* 2-byte sequence? */ + if (szb < 2) return 0; /* Buffer overflow? */ + *buf++ = (TCHAR)(0xC0 | (chr >> 6 & 0x1F)); + *buf++ = (TCHAR)(0x80 | (chr >> 0 & 0x3F)); + return 2; + } + if (chr < 0x10000) { /* 3-byte sequence? */ + if (szb < 3 || IsSurrogate(chr)) return 0; /* Buffer overflow or wrong code? */ + *buf++ = (TCHAR)(0xE0 | (chr >> 12 & 0x0F)); + *buf++ = (TCHAR)(0x80 | (chr >> 6 & 0x3F)); + *buf++ = (TCHAR)(0x80 | (chr >> 0 & 0x3F)); + return 3; + } + /* 4-byte sequence */ + if (szb < 4) return 0; /* Buffer overflow? */ + hc = ((chr & 0xFFFF0000) - 0xD8000000) >> 6; /* Get high 10 bits */ + chr = (chr & 0xFFFF) - 0xDC00; /* Get low 10 bits */ + if (hc >= 0x100000 || chr >= 0x400) return 0; /* Wrong surrogate? */ + chr = (hc | chr) + 0x10000; + *buf++ = (TCHAR)(0xF0 | (chr >> 18 & 0x07)); + *buf++ = (TCHAR)(0x80 | (chr >> 12 & 0x3F)); + *buf++ = (TCHAR)(0x80 | (chr >> 6 & 0x3F)); + *buf++ = (TCHAR)(0x80 | (chr >> 0 & 0x3F)); + return 4; + +#elif FF_LFN_UNICODE == 3 /* UTF-32 output */ + DWORD hc; + + if (szb < 1) return 0; /* Buffer overflow? */ + if (chr >= 0x10000) { /* Out of BMP? */ + hc = ((chr & 0xFFFF0000) - 0xD8000000) >> 6; /* Get high 10 bits */ + chr = (chr & 0xFFFF) - 0xDC00; /* Get low 10 bits */ + if (hc >= 0x100000 || chr >= 0x400) return 0; /* Wrong surrogate? */ + chr = (hc | chr) + 0x10000; + } + *buf++ = (TCHAR)chr; + return 1; + +#else /* ANSI/OEM output */ + WCHAR wc; + + wc = ff_uni2oem(chr, CODEPAGE); + if (wc >= 0x100) { /* Is this a DBC? */ + if (szb < 2) return 0; + *buf++ = (char)(wc >> 8); /* Store DBC 1st byte */ + *buf++ = (TCHAR)wc; /* Store DBC 2nd byte */ + return 2; + } + if (wc == 0 || szb < 1) return 0; /* Invalid char or buffer overflow? */ + *buf++ = (TCHAR)wc; /* Store the character */ + return 1; +#endif +} +#endif /* FF_USE_LFN */ + + +#if FF_FS_REENTRANT +/*-----------------------------------------------------------------------*/ +/* Request/Release grant to access the volume */ +/*-----------------------------------------------------------------------*/ +static int lock_fs ( /* 1:Ok, 0:timeout */ + FATFS* fs /* Filesystem object */ +) +{ + return ff_req_grant(fs->sobj); +} + + +static void unlock_fs ( + FATFS* fs, /* Filesystem object */ + FRESULT res /* Result code to be returned */ +) +{ + if (fs && res != FR_NOT_ENABLED && res != FR_INVALID_DRIVE && res != FR_TIMEOUT) { + ff_rel_grant(fs->sobj); + } +} + +#endif + + + +#if FF_FS_LOCK != 0 +/*-----------------------------------------------------------------------*/ +/* File lock control functions */ +/*-----------------------------------------------------------------------*/ + +static FRESULT chk_lock ( /* Check if the file can be accessed */ + DIR* dp, /* Directory object pointing the file to be checked */ + int acc /* Desired access type (0:Read mode open, 1:Write mode open, 2:Delete or rename) */ +) +{ + UINT i, be; + + /* Search open object table for the object */ + be = 0; + for (i = 0; i < FF_FS_LOCK; i++) { + if (Files[i].fs) { /* Existing entry */ + if (Files[i].fs == dp->obj.fs && /* Check if the object matches with an open object */ + Files[i].clu == dp->obj.sclust && + Files[i].ofs == dp->dptr) break; + } else { /* Blank entry */ + be = 1; + } + } + if (i == FF_FS_LOCK) { /* The object has not been opened */ + return (!be && acc != 2) ? FR_TOO_MANY_OPEN_FILES : FR_OK; /* Is there a blank entry for new object? */ + } + + /* The object was opened. Reject any open against writing file and all write mode open */ + return (acc != 0 || Files[i].ctr == 0x100) ? FR_LOCKED : FR_OK; +} + + +static int enq_lock (void) /* Check if an entry is available for a new object */ +{ + UINT i; + + for (i = 0; i < FF_FS_LOCK && Files[i].fs; i++) ; + return (i == FF_FS_LOCK) ? 0 : 1; +} + + +static UINT inc_lock ( /* Increment object open counter and returns its index (0:Internal error) */ + DIR* dp, /* Directory object pointing the file to register or increment */ + int acc /* Desired access (0:Read, 1:Write, 2:Delete/Rename) */ +) +{ + UINT i; + + + for (i = 0; i < FF_FS_LOCK; i++) { /* Find the object */ + if (Files[i].fs == dp->obj.fs + && Files[i].clu == dp->obj.sclust + && Files[i].ofs == dp->dptr) break; + } + + if (i == FF_FS_LOCK) { /* Not opened. Register it as new. */ + for (i = 0; i < FF_FS_LOCK && Files[i].fs; i++) ; + if (i == FF_FS_LOCK) return 0; /* No free entry to register (int err) */ + Files[i].fs = dp->obj.fs; + Files[i].clu = dp->obj.sclust; + Files[i].ofs = dp->dptr; + Files[i].ctr = 0; + } + + if (acc >= 1 && Files[i].ctr) return 0; /* Access violation (int err) */ + + Files[i].ctr = acc ? 0x100 : Files[i].ctr + 1; /* Set semaphore value */ + + return i + 1; /* Index number origin from 1 */ +} + + +static FRESULT dec_lock ( /* Decrement object open counter */ + UINT i /* Semaphore index (1..) */ +) +{ + WORD n; + FRESULT res; + + + if (--i < FF_FS_LOCK) { /* Index number origin from 0 */ + n = Files[i].ctr; + if (n == 0x100) n = 0; /* If write mode open, delete the entry */ + if (n > 0) n--; /* Decrement read mode open count */ + Files[i].ctr = n; + if (n == 0) Files[i].fs = 0; /* Delete the entry if open count gets zero */ + res = FR_OK; + } else { + res = FR_INT_ERR; /* Invalid index nunber */ + } + return res; +} + + +static void clear_lock ( /* Clear lock entries of the volume */ + FATFS *fs +) +{ + UINT i; + + for (i = 0; i < FF_FS_LOCK; i++) { + if (Files[i].fs == fs) Files[i].fs = 0; + } +} + +#endif /* FF_FS_LOCK != 0 */ + + + +/*-----------------------------------------------------------------------*/ +/* Move/Flush disk access window in the filesystem object */ +/*-----------------------------------------------------------------------*/ +#if !FF_FS_READONLY +static FRESULT sync_window ( /* Returns FR_OK or FR_DISK_ERR */ + FATFS* fs /* Filesystem object */ +) +{ + FRESULT res = FR_OK; + + + if (fs->wflag) { /* Is the disk access window dirty? */ + if (disk_write(fs->pdrv, fs->win, fs->winsect, 1) == RES_OK) { /* Write it back into the volume */ + fs->wflag = 0; /* Clear window dirty flag */ + if (fs->winsect - fs->fatbase < fs->fsize) { /* Is it in the 1st FAT? */ + if (fs->n_fats == 2) disk_write(fs->pdrv, fs->win, fs->winsect + fs->fsize, 1); /* Reflect it to 2nd FAT if needed */ + } + } else { + res = FR_DISK_ERR; + } + } + return res; +} +#endif + + +static FRESULT move_window ( /* Returns FR_OK or FR_DISK_ERR */ + FATFS* fs, /* Filesystem object */ + LBA_t sect /* Sector LBA to make appearance in the fs->win[] */ +) +{ + FRESULT res = FR_OK; + + + if (sect != fs->winsect) { /* Window offset changed? */ +#if !FF_FS_READONLY + res = sync_window(fs); /* Flush the window */ +#endif + if (res == FR_OK) { /* Fill sector window with new data */ + if (disk_read(fs->pdrv, fs->win, sect, 1) != RES_OK) { + sect = (LBA_t)0 - 1; /* Invalidate window if read data is not valid */ + res = FR_DISK_ERR; + } + fs->winsect = sect; + } + } + return res; +} + + + + +#if !FF_FS_READONLY +/*-----------------------------------------------------------------------*/ +/* Synchronize filesystem and data on the storage */ +/*-----------------------------------------------------------------------*/ + +static FRESULT sync_fs ( /* Returns FR_OK or FR_DISK_ERR */ + FATFS* fs /* Filesystem object */ +) +{ + FRESULT res; + + + res = sync_window(fs); + if (res == FR_OK) { + if (fs->fs_type == FS_FAT32 && fs->fsi_flag == 1) { /* FAT32: Update FSInfo sector if needed */ + /* Create FSInfo structure */ + memset(fs->win, 0, sizeof fs->win); + st_word(fs->win + BS_55AA, 0xAA55); /* Boot signature */ + st_dword(fs->win + FSI_LeadSig, 0x41615252); /* Leading signature */ + st_dword(fs->win + FSI_StrucSig, 0x61417272); /* Structure signature */ + st_dword(fs->win + FSI_Free_Count, fs->free_clst); /* Number of free clusters */ + st_dword(fs->win + FSI_Nxt_Free, fs->last_clst); /* Last allocated culuster */ + fs->winsect = fs->volbase + 1; /* Write it into the FSInfo sector (Next to VBR) */ + disk_write(fs->pdrv, fs->win, fs->winsect, 1); + fs->fsi_flag = 0; + } + /* Make sure that no pending write process in the lower layer */ + if (disk_ioctl(fs->pdrv, CTRL_SYNC, 0) != RES_OK) res = FR_DISK_ERR; + } + + return res; +} + +#endif + + + +/*-----------------------------------------------------------------------*/ +/* Get physical sector number from cluster number */ +/*-----------------------------------------------------------------------*/ + +static LBA_t clst2sect ( /* !=0:Sector number, 0:Failed (invalid cluster#) */ + FATFS* fs, /* Filesystem object */ + DWORD clst /* Cluster# to be converted */ +) +{ + clst -= 2; /* Cluster number is origin from 2 */ + if (clst >= fs->n_fatent - 2) return 0; /* Is it invalid cluster number? */ + return fs->database + (LBA_t)fs->csize * clst; /* Start sector number of the cluster */ +} + + + + +/*-----------------------------------------------------------------------*/ +/* FAT access - Read value of an FAT entry */ +/*-----------------------------------------------------------------------*/ + +static DWORD get_fat ( /* 0xFFFFFFFF:Disk error, 1:Internal error, 2..0x7FFFFFFF:Cluster status */ + FFOBJID* obj, /* Corresponding object */ + DWORD clst /* Cluster number to get the value */ +) +{ + UINT wc, bc; + DWORD val; + FATFS *fs = obj->fs; + + + if (clst < 2 || clst >= fs->n_fatent) { /* Check if in valid range */ + val = 1; /* Internal error */ + + } else { + val = 0xFFFFFFFF; /* Default value falls on disk error */ + + switch (fs->fs_type) { + case FS_FAT12 : + bc = (UINT)clst; bc += bc / 2; + if (move_window(fs, fs->fatbase + (bc / SS(fs))) != FR_OK) break; + wc = fs->win[bc++ % SS(fs)]; /* Get 1st byte of the entry */ + if (move_window(fs, fs->fatbase + (bc / SS(fs))) != FR_OK) break; + wc |= fs->win[bc % SS(fs)] << 8; /* Merge 2nd byte of the entry */ + val = (clst & 1) ? (wc >> 4) : (wc & 0xFFF); /* Adjust bit position */ + break; + + case FS_FAT16 : + if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 2))) != FR_OK) break; + val = ld_word(fs->win + clst * 2 % SS(fs)); /* Simple WORD array */ + break; + + case FS_FAT32 : + if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 4))) != FR_OK) break; + val = ld_dword(fs->win + clst * 4 % SS(fs)) & 0x0FFFFFFF; /* Simple DWORD array but mask out upper 4 bits */ + break; +#if FF_FS_EXFAT + case FS_EXFAT : + if ((obj->objsize != 0 && obj->sclust != 0) || obj->stat == 0) { /* Object except root dir must have valid data length */ + DWORD cofs = clst - obj->sclust; /* Offset from start cluster */ + DWORD clen = (DWORD)((LBA_t)((obj->objsize - 1) / SS(fs)) / fs->csize); /* Number of clusters - 1 */ + + if (obj->stat == 2 && cofs <= clen) { /* Is it a contiguous chain? */ + val = (cofs == clen) ? 0x7FFFFFFF : clst + 1; /* No data on the FAT, generate the value */ + break; + } + if (obj->stat == 3 && cofs < obj->n_cont) { /* Is it in the 1st fragment? */ + val = clst + 1; /* Generate the value */ + break; + } + if (obj->stat != 2) { /* Get value from FAT if FAT chain is valid */ + if (obj->n_frag != 0) { /* Is it on the growing edge? */ + val = 0x7FFFFFFF; /* Generate EOC */ + } else { + if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 4))) != FR_OK) break; + val = ld_dword(fs->win + clst * 4 % SS(fs)) & 0x7FFFFFFF; + } + break; + } + } + val = 1; /* Internal error */ + break; +#endif + default: + val = 1; /* Internal error */ + } + } + + return val; +} + + + + +#if !FF_FS_READONLY +/*-----------------------------------------------------------------------*/ +/* FAT access - Change value of an FAT entry */ +/*-----------------------------------------------------------------------*/ + +static FRESULT put_fat ( /* FR_OK(0):succeeded, !=0:error */ + FATFS* fs, /* Corresponding filesystem object */ + DWORD clst, /* FAT index number (cluster number) to be changed */ + DWORD val /* New value to be set to the entry */ +) +{ + UINT bc; + BYTE *p; + FRESULT res = FR_INT_ERR; + + + if (clst >= 2 && clst < fs->n_fatent) { /* Check if in valid range */ + switch (fs->fs_type) { + case FS_FAT12: + bc = (UINT)clst; bc += bc / 2; /* bc: byte offset of the entry */ + res = move_window(fs, fs->fatbase + (bc / SS(fs))); + if (res != FR_OK) break; + p = fs->win + bc++ % SS(fs); + *p = (clst & 1) ? ((*p & 0x0F) | ((BYTE)val << 4)) : (BYTE)val; /* Update 1st byte */ + fs->wflag = 1; + res = move_window(fs, fs->fatbase + (bc / SS(fs))); + if (res != FR_OK) break; + p = fs->win + bc % SS(fs); + *p = (clst & 1) ? (BYTE)(val >> 4) : ((*p & 0xF0) | ((BYTE)(val >> 8) & 0x0F)); /* Update 2nd byte */ + fs->wflag = 1; + break; + + case FS_FAT16: + res = move_window(fs, fs->fatbase + (clst / (SS(fs) / 2))); + if (res != FR_OK) break; + st_word(fs->win + clst * 2 % SS(fs), (WORD)val); /* Simple WORD array */ + fs->wflag = 1; + break; + + case FS_FAT32: +#if FF_FS_EXFAT + case FS_EXFAT: +#endif + res = move_window(fs, fs->fatbase + (clst / (SS(fs) / 4))); + if (res != FR_OK) break; + if (!FF_FS_EXFAT || fs->fs_type != FS_EXFAT) { + val = (val & 0x0FFFFFFF) | (ld_dword(fs->win + clst * 4 % SS(fs)) & 0xF0000000); + } + st_dword(fs->win + clst * 4 % SS(fs), val); + fs->wflag = 1; + break; + } + } + return res; +} + +#endif /* !FF_FS_READONLY */ + + + + +#if FF_FS_EXFAT && !FF_FS_READONLY +/*-----------------------------------------------------------------------*/ +/* exFAT: Accessing FAT and Allocation Bitmap */ +/*-----------------------------------------------------------------------*/ + +/*--------------------------------------*/ +/* Find a contiguous free cluster block */ +/*--------------------------------------*/ + +static DWORD find_bitmap ( /* 0:Not found, 2..:Cluster block found, 0xFFFFFFFF:Disk error */ + FATFS* fs, /* Filesystem object */ + DWORD clst, /* Cluster number to scan from */ + DWORD ncl /* Number of contiguous clusters to find (1..) */ +) +{ + BYTE bm, bv; + UINT i; + DWORD val, scl, ctr; + + + clst -= 2; /* The first bit in the bitmap corresponds to cluster #2 */ + if (clst >= fs->n_fatent - 2) clst = 0; + scl = val = clst; ctr = 0; + for (;;) { + if (move_window(fs, fs->bitbase + val / 8 / SS(fs)) != FR_OK) return 0xFFFFFFFF; + i = val / 8 % SS(fs); bm = 1 << (val % 8); + do { + do { + bv = fs->win[i] & bm; bm <<= 1; /* Get bit value */ + if (++val >= fs->n_fatent - 2) { /* Next cluster (with wrap-around) */ + val = 0; bm = 0; i = SS(fs); + } + if (bv == 0) { /* Is it a free cluster? */ + if (++ctr == ncl) return scl + 2; /* Check if run length is sufficient for required */ + } else { + scl = val; ctr = 0; /* Encountered a cluster in-use, restart to scan */ + } + if (val == clst) return 0; /* All cluster scanned? */ + } while (bm != 0); + bm = 1; + } while (++i < SS(fs)); + } +} + + +/*----------------------------------------*/ +/* Set/Clear a block of allocation bitmap */ +/*----------------------------------------*/ + +static FRESULT change_bitmap ( + FATFS* fs, /* Filesystem object */ + DWORD clst, /* Cluster number to change from */ + DWORD ncl, /* Number of clusters to be changed */ + int bv /* bit value to be set (0 or 1) */ +) +{ + BYTE bm; + UINT i; + LBA_t sect; + + + clst -= 2; /* The first bit corresponds to cluster #2 */ + sect = fs->bitbase + clst / 8 / SS(fs); /* Sector address */ + i = clst / 8 % SS(fs); /* Byte offset in the sector */ + bm = 1 << (clst % 8); /* Bit mask in the byte */ + for (;;) { + if (move_window(fs, sect++) != FR_OK) return FR_DISK_ERR; + do { + do { + if (bv == (int)((fs->win[i] & bm) != 0)) return FR_INT_ERR; /* Is the bit expected value? */ + fs->win[i] ^= bm; /* Flip the bit */ + fs->wflag = 1; + if (--ncl == 0) return FR_OK; /* All bits processed? */ + } while (bm <<= 1); /* Next bit */ + bm = 1; + } while (++i < SS(fs)); /* Next byte */ + i = 0; + } +} + + +/*---------------------------------------------*/ +/* Fill the first fragment of the FAT chain */ +/*---------------------------------------------*/ + +static FRESULT fill_first_frag ( + FFOBJID* obj /* Pointer to the corresponding object */ +) +{ + FRESULT res; + DWORD cl, n; + + + if (obj->stat == 3) { /* Has the object been changed 'fragmented' in this session? */ + for (cl = obj->sclust, n = obj->n_cont; n; cl++, n--) { /* Create cluster chain on the FAT */ + res = put_fat(obj->fs, cl, cl + 1); + if (res != FR_OK) return res; + } + obj->stat = 0; /* Change status 'FAT chain is valid' */ + } + return FR_OK; +} + + +/*---------------------------------------------*/ +/* Fill the last fragment of the FAT chain */ +/*---------------------------------------------*/ + +static FRESULT fill_last_frag ( + FFOBJID* obj, /* Pointer to the corresponding object */ + DWORD lcl, /* Last cluster of the fragment */ + DWORD term /* Value to set the last FAT entry */ +) +{ + FRESULT res; + + + while (obj->n_frag > 0) { /* Create the chain of last fragment */ + res = put_fat(obj->fs, lcl - obj->n_frag + 1, (obj->n_frag > 1) ? lcl - obj->n_frag + 2 : term); + if (res != FR_OK) return res; + obj->n_frag--; + } + return FR_OK; +} + +#endif /* FF_FS_EXFAT && !FF_FS_READONLY */ + + + +#if !FF_FS_READONLY +/*-----------------------------------------------------------------------*/ +/* FAT handling - Remove a cluster chain */ +/*-----------------------------------------------------------------------*/ + +static FRESULT remove_chain ( /* FR_OK(0):succeeded, !=0:error */ + FFOBJID* obj, /* Corresponding object */ + DWORD clst, /* Cluster to remove a chain from */ + DWORD pclst /* Previous cluster of clst (0 if entire chain) */ +) +{ + FRESULT res = FR_OK; + DWORD nxt; + FATFS *fs = obj->fs; +#if FF_FS_EXFAT || FF_USE_TRIM + DWORD scl = clst, ecl = clst; +#endif +#if FF_USE_TRIM + LBA_t rt[2]; +#endif + + if (clst < 2 || clst >= fs->n_fatent) return FR_INT_ERR; /* Check if in valid range */ + + /* Mark the previous cluster 'EOC' on the FAT if it exists */ + if (pclst != 0 && (!FF_FS_EXFAT || fs->fs_type != FS_EXFAT || obj->stat != 2)) { + res = put_fat(fs, pclst, 0xFFFFFFFF); + if (res != FR_OK) return res; + } + + /* Remove the chain */ + do { + nxt = get_fat(obj, clst); /* Get cluster status */ + if (nxt == 0) break; /* Empty cluster? */ + if (nxt == 1) return FR_INT_ERR; /* Internal error? */ + if (nxt == 0xFFFFFFFF) return FR_DISK_ERR; /* Disk error? */ + if (!FF_FS_EXFAT || fs->fs_type != FS_EXFAT) { + res = put_fat(fs, clst, 0); /* Mark the cluster 'free' on the FAT */ + if (res != FR_OK) return res; + } + if (fs->free_clst < fs->n_fatent - 2) { /* Update FSINFO */ + fs->free_clst++; + fs->fsi_flag |= 1; + } +#if FF_FS_EXFAT || FF_USE_TRIM + if (ecl + 1 == nxt) { /* Is next cluster contiguous? */ + ecl = nxt; + } else { /* End of contiguous cluster block */ +#if FF_FS_EXFAT + if (fs->fs_type == FS_EXFAT) { + res = change_bitmap(fs, scl, ecl - scl + 1, 0); /* Mark the cluster block 'free' on the bitmap */ + if (res != FR_OK) return res; + } +#endif +#if FF_USE_TRIM + rt[0] = clst2sect(fs, scl); /* Start of data area to be freed */ + rt[1] = clst2sect(fs, ecl) + fs->csize - 1; /* End of data area to be freed */ + disk_ioctl(fs->pdrv, CTRL_TRIM, rt); /* Inform storage device that the data in the block may be erased */ +#endif + scl = ecl = nxt; + } +#endif + clst = nxt; /* Next cluster */ + } while (clst < fs->n_fatent); /* Repeat while not the last link */ + +#if FF_FS_EXFAT + /* Some post processes for chain status */ + if (fs->fs_type == FS_EXFAT) { + if (pclst == 0) { /* Has the entire chain been removed? */ + obj->stat = 0; /* Change the chain status 'initial' */ + } else { + if (obj->stat == 0) { /* Is it a fragmented chain from the beginning of this session? */ + clst = obj->sclust; /* Follow the chain to check if it gets contiguous */ + while (clst != pclst) { + nxt = get_fat(obj, clst); + if (nxt < 2) return FR_INT_ERR; + if (nxt == 0xFFFFFFFF) return FR_DISK_ERR; + if (nxt != clst + 1) break; /* Not contiguous? */ + clst++; + } + if (clst == pclst) { /* Has the chain got contiguous again? */ + obj->stat = 2; /* Change the chain status 'contiguous' */ + } + } else { + if (obj->stat == 3 && pclst >= obj->sclust && pclst <= obj->sclust + obj->n_cont) { /* Was the chain fragmented in this session and got contiguous again? */ + obj->stat = 2; /* Change the chain status 'contiguous' */ + } + } + } + } +#endif + return FR_OK; +} + + + + +/*-----------------------------------------------------------------------*/ +/* FAT handling - Stretch a chain or Create a new chain */ +/*-----------------------------------------------------------------------*/ + +static DWORD create_chain ( /* 0:No free cluster, 1:Internal error, 0xFFFFFFFF:Disk error, >=2:New cluster# */ + FFOBJID* obj, /* Corresponding object */ + DWORD clst /* Cluster# to stretch, 0:Create a new chain */ +) +{ + DWORD cs, ncl, scl; + FRESULT res; + FATFS *fs = obj->fs; + + + if (clst == 0) { /* Create a new chain */ + scl = fs->last_clst; /* Suggested cluster to start to find */ + if (scl == 0 || scl >= fs->n_fatent) scl = 1; + } + else { /* Stretch a chain */ + cs = get_fat(obj, clst); /* Check the cluster status */ + if (cs < 2) return 1; /* Test for insanity */ + if (cs == 0xFFFFFFFF) return cs; /* Test for disk error */ + if (cs < fs->n_fatent) return cs; /* It is already followed by next cluster */ + scl = clst; /* Cluster to start to find */ + } + if (fs->free_clst == 0) return 0; /* No free cluster */ + +#if FF_FS_EXFAT + if (fs->fs_type == FS_EXFAT) { /* On the exFAT volume */ + ncl = find_bitmap(fs, scl, 1); /* Find a free cluster */ + if (ncl == 0 || ncl == 0xFFFFFFFF) return ncl; /* No free cluster or hard error? */ + res = change_bitmap(fs, ncl, 1, 1); /* Mark the cluster 'in use' */ + if (res == FR_INT_ERR) return 1; + if (res == FR_DISK_ERR) return 0xFFFFFFFF; + if (clst == 0) { /* Is it a new chain? */ + obj->stat = 2; /* Set status 'contiguous' */ + } else { /* It is a stretched chain */ + if (obj->stat == 2 && ncl != scl + 1) { /* Is the chain got fragmented? */ + obj->n_cont = scl - obj->sclust; /* Set size of the contiguous part */ + obj->stat = 3; /* Change status 'just fragmented' */ + } + } + if (obj->stat != 2) { /* Is the file non-contiguous? */ + if (ncl == clst + 1) { /* Is the cluster next to previous one? */ + obj->n_frag = obj->n_frag ? obj->n_frag + 1 : 2; /* Increment size of last framgent */ + } else { /* New fragment */ + if (obj->n_frag == 0) obj->n_frag = 1; + res = fill_last_frag(obj, clst, ncl); /* Fill last fragment on the FAT and link it to new one */ + if (res == FR_OK) obj->n_frag = 1; + } + } + } else +#endif + { /* On the FAT/FAT32 volume */ + ncl = 0; + if (scl == clst) { /* Stretching an existing chain? */ + ncl = scl + 1; /* Test if next cluster is free */ + if (ncl >= fs->n_fatent) ncl = 2; + cs = get_fat(obj, ncl); /* Get next cluster status */ + if (cs == 1 || cs == 0xFFFFFFFF) return cs; /* Test for error */ + if (cs != 0) { /* Not free? */ + cs = fs->last_clst; /* Start at suggested cluster if it is valid */ + if (cs >= 2 && cs < fs->n_fatent) scl = cs; + ncl = 0; + } + } + if (ncl == 0) { /* The new cluster cannot be contiguous and find another fragment */ + ncl = scl; /* Start cluster */ + for (;;) { + ncl++; /* Next cluster */ + if (ncl >= fs->n_fatent) { /* Check wrap-around */ + ncl = 2; + if (ncl > scl) return 0; /* No free cluster found? */ + } + cs = get_fat(obj, ncl); /* Get the cluster status */ + if (cs == 0) break; /* Found a free cluster? */ + if (cs == 1 || cs == 0xFFFFFFFF) return cs; /* Test for error */ + if (ncl == scl) return 0; /* No free cluster found? */ + } + } + res = put_fat(fs, ncl, 0xFFFFFFFF); /* Mark the new cluster 'EOC' */ + if (res == FR_OK && clst != 0) { + res = put_fat(fs, clst, ncl); /* Link it from the previous one if needed */ + } + } + + if (res == FR_OK) { /* Update FSINFO if function succeeded. */ + fs->last_clst = ncl; + if (fs->free_clst <= fs->n_fatent - 2) fs->free_clst--; + fs->fsi_flag |= 1; + } else { + ncl = (res == FR_DISK_ERR) ? 0xFFFFFFFF : 1; /* Failed. Generate error status */ + } + + return ncl; /* Return new cluster number or error status */ +} + +#endif /* !FF_FS_READONLY */ + + + + +#if FF_USE_FASTSEEK +/*-----------------------------------------------------------------------*/ +/* FAT handling - Convert offset into cluster with link map table */ +/*-----------------------------------------------------------------------*/ + +static DWORD clmt_clust ( /* <2:Error, >=2:Cluster number */ + FIL* fp, /* Pointer to the file object */ + FSIZE_t ofs /* File offset to be converted to cluster# */ +) +{ + DWORD cl, ncl, *tbl; + FATFS *fs = fp->obj.fs; + + + tbl = fp->cltbl + 1; /* Top of CLMT */ + cl = (DWORD)(ofs / SS(fs) / fs->csize); /* Cluster order from top of the file */ + for (;;) { + ncl = *tbl++; /* Number of cluters in the fragment */ + if (ncl == 0) return 0; /* End of table? (error) */ + if (cl < ncl) break; /* In this fragment? */ + cl -= ncl; tbl++; /* Next fragment */ + } + return cl + *tbl; /* Return the cluster number */ +} + +#endif /* FF_USE_FASTSEEK */ + + + + +/*-----------------------------------------------------------------------*/ +/* Directory handling - Fill a cluster with zeros */ +/*-----------------------------------------------------------------------*/ + +#if !FF_FS_READONLY +static FRESULT dir_clear ( /* Returns FR_OK or FR_DISK_ERR */ + FATFS *fs, /* Filesystem object */ + DWORD clst /* Directory table to clear */ +) +{ + LBA_t sect; + UINT n, szb; + BYTE *ibuf; + + + if (sync_window(fs) != FR_OK) return FR_DISK_ERR; /* Flush disk access window */ + sect = clst2sect(fs, clst); /* Top of the cluster */ + fs->winsect = sect; /* Set window to top of the cluster */ + memset(fs->win, 0, sizeof fs->win); /* Clear window buffer */ +#if FF_USE_LFN == 3 /* Quick table clear by using multi-secter write */ + /* Allocate a temporary buffer */ + for (szb = ((DWORD)fs->csize * SS(fs) >= MAX_MALLOC) ? MAX_MALLOC : fs->csize * SS(fs), ibuf = 0; szb > SS(fs) && (ibuf = ff_memalloc(szb)) == 0; szb /= 2) ; + if (szb > SS(fs)) { /* Buffer allocated? */ + memset(ibuf, 0, szb); + szb /= SS(fs); /* Bytes -> Sectors */ + for (n = 0; n < fs->csize && disk_write(fs->pdrv, ibuf, sect + n, szb) == RES_OK; n += szb) ; /* Fill the cluster with 0 */ + ff_memfree(ibuf); + } else +#endif + { + ibuf = fs->win; szb = 1; /* Use window buffer (many single-sector writes may take a time) */ + for (n = 0; n < fs->csize && disk_write(fs->pdrv, ibuf, sect + n, szb) == RES_OK; n += szb) ; /* Fill the cluster with 0 */ + } + return (n == fs->csize) ? FR_OK : FR_DISK_ERR; +} +#endif /* !FF_FS_READONLY */ + + + + +/*-----------------------------------------------------------------------*/ +/* Directory handling - Set directory index */ +/*-----------------------------------------------------------------------*/ + +static FRESULT dir_sdi ( /* FR_OK(0):succeeded, !=0:error */ + DIR* dp, /* Pointer to directory object */ + DWORD ofs /* Offset of directory table */ +) +{ + DWORD csz, clst; + FATFS *fs = dp->obj.fs; + + + if (ofs >= (DWORD)((FF_FS_EXFAT && fs->fs_type == FS_EXFAT) ? MAX_DIR_EX : MAX_DIR) || ofs % SZDIRE) { /* Check range of offset and alignment */ + return FR_INT_ERR; + } + dp->dptr = ofs; /* Set current offset */ + clst = dp->obj.sclust; /* Table start cluster (0:root) */ + if (clst == 0 && fs->fs_type >= FS_FAT32) { /* Replace cluster# 0 with root cluster# */ + clst = (DWORD)fs->dirbase; + if (FF_FS_EXFAT) dp->obj.stat = 0; /* exFAT: Root dir has an FAT chain */ + } + + if (clst == 0) { /* Static table (root-directory on the FAT volume) */ + if (ofs / SZDIRE >= fs->n_rootdir) return FR_INT_ERR; /* Is index out of range? */ + dp->sect = fs->dirbase; + + } else { /* Dynamic table (sub-directory or root-directory on the FAT32/exFAT volume) */ + csz = (DWORD)fs->csize * SS(fs); /* Bytes per cluster */ + while (ofs >= csz) { /* Follow cluster chain */ + clst = get_fat(&dp->obj, clst); /* Get next cluster */ + if (clst == 0xFFFFFFFF) return FR_DISK_ERR; /* Disk error */ + if (clst < 2 || clst >= fs->n_fatent) return FR_INT_ERR; /* Reached to end of table or internal error */ + ofs -= csz; + } + dp->sect = clst2sect(fs, clst); + } + dp->clust = clst; /* Current cluster# */ + if (dp->sect == 0) return FR_INT_ERR; + dp->sect += ofs / SS(fs); /* Sector# of the directory entry */ + dp->dir = fs->win + (ofs % SS(fs)); /* Pointer to the entry in the win[] */ + + return FR_OK; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Directory handling - Move directory table index next */ +/*-----------------------------------------------------------------------*/ + +static FRESULT dir_next ( /* FR_OK(0):succeeded, FR_NO_FILE:End of table, FR_DENIED:Could not stretch */ + DIR* dp, /* Pointer to the directory object */ + int stretch /* 0: Do not stretch table, 1: Stretch table if needed */ +) +{ + DWORD ofs, clst; + FATFS *fs = dp->obj.fs; + + + ofs = dp->dptr + SZDIRE; /* Next entry */ + if (ofs >= (DWORD)((FF_FS_EXFAT && fs->fs_type == FS_EXFAT) ? MAX_DIR_EX : MAX_DIR)) dp->sect = 0; /* Disable it if the offset reached the max value */ + if (dp->sect == 0) return FR_NO_FILE; /* Report EOT if it has been disabled */ + + if (ofs % SS(fs) == 0) { /* Sector changed? */ + dp->sect++; /* Next sector */ + + if (dp->clust == 0) { /* Static table */ + if (ofs / SZDIRE >= fs->n_rootdir) { /* Report EOT if it reached end of static table */ + dp->sect = 0; return FR_NO_FILE; + } + } + else { /* Dynamic table */ + if ((ofs / SS(fs) & (fs->csize - 1)) == 0) { /* Cluster changed? */ + clst = get_fat(&dp->obj, dp->clust); /* Get next cluster */ + if (clst <= 1) return FR_INT_ERR; /* Internal error */ + if (clst == 0xFFFFFFFF) return FR_DISK_ERR; /* Disk error */ + if (clst >= fs->n_fatent) { /* It reached end of dynamic table */ +#if !FF_FS_READONLY + if (!stretch) { /* If no stretch, report EOT */ + dp->sect = 0; return FR_NO_FILE; + } + clst = create_chain(&dp->obj, dp->clust); /* Allocate a cluster */ + if (clst == 0) return FR_DENIED; /* No free cluster */ + if (clst == 1) return FR_INT_ERR; /* Internal error */ + if (clst == 0xFFFFFFFF) return FR_DISK_ERR; /* Disk error */ + if (dir_clear(fs, clst) != FR_OK) return FR_DISK_ERR; /* Clean up the stretched table */ + if (FF_FS_EXFAT) dp->obj.stat |= 4; /* exFAT: The directory has been stretched */ +#else + if (!stretch) dp->sect = 0; /* (this line is to suppress compiler warning) */ + dp->sect = 0; return FR_NO_FILE; /* Report EOT */ +#endif + } + dp->clust = clst; /* Initialize data for new cluster */ + dp->sect = clst2sect(fs, clst); + } + } + } + dp->dptr = ofs; /* Current entry */ + dp->dir = fs->win + ofs % SS(fs); /* Pointer to the entry in the win[] */ + + return FR_OK; +} + + + + +#if !FF_FS_READONLY +/*-----------------------------------------------------------------------*/ +/* Directory handling - Reserve a block of directory entries */ +/*-----------------------------------------------------------------------*/ + +static FRESULT dir_alloc ( /* FR_OK(0):succeeded, !=0:error */ + DIR* dp, /* Pointer to the directory object */ + UINT n_ent /* Number of contiguous entries to allocate */ +) +{ + FRESULT res; + UINT n; + FATFS *fs = dp->obj.fs; + + + res = dir_sdi(dp, 0); + if (res == FR_OK) { + n = 0; + do { + res = move_window(fs, dp->sect); + if (res != FR_OK) break; +#if FF_FS_EXFAT + if ((fs->fs_type == FS_EXFAT) ? (int)((dp->dir[XDIR_Type] & 0x80) == 0) : (int)(dp->dir[DIR_Name] == DDEM || dp->dir[DIR_Name] == 0)) { /* Is the entry free? */ +#else + if (dp->dir[DIR_Name] == DDEM || dp->dir[DIR_Name] == 0) { /* Is the entry free? */ +#endif + if (++n == n_ent) break; /* Is a block of contiguous free entries found? */ + } else { + n = 0; /* Not a free entry, restart to search */ + } + res = dir_next(dp, 1); /* Next entry with table stretch enabled */ + } while (res == FR_OK); + } + + if (res == FR_NO_FILE) res = FR_DENIED; /* No directory entry to allocate */ + return res; +} + +#endif /* !FF_FS_READONLY */ + + + + +/*-----------------------------------------------------------------------*/ +/* FAT: Directory handling - Load/Store start cluster number */ +/*-----------------------------------------------------------------------*/ + +static DWORD ld_clust ( /* Returns the top cluster value of the SFN entry */ + FATFS* fs, /* Pointer to the fs object */ + const BYTE* dir /* Pointer to the key entry */ +) +{ + DWORD cl; + + cl = ld_word(dir + DIR_FstClusLO); + if (fs->fs_type == FS_FAT32) { + cl |= (DWORD)ld_word(dir + DIR_FstClusHI) << 16; + } + + return cl; +} + + +#if !FF_FS_READONLY +static void st_clust ( + FATFS* fs, /* Pointer to the fs object */ + BYTE* dir, /* Pointer to the key entry */ + DWORD cl /* Value to be set */ +) +{ + st_word(dir + DIR_FstClusLO, (WORD)cl); + if (fs->fs_type == FS_FAT32) { + st_word(dir + DIR_FstClusHI, (WORD)(cl >> 16)); + } +} +#endif + + + +#if FF_USE_LFN +/*--------------------------------------------------------*/ +/* FAT-LFN: Compare a part of file name with an LFN entry */ +/*--------------------------------------------------------*/ + +static int cmp_lfn ( /* 1:matched, 0:not matched */ + const WCHAR* lfnbuf, /* Pointer to the LFN working buffer to be compared */ + BYTE* dir /* Pointer to the directory entry containing the part of LFN */ +) +{ + UINT i, s; + WCHAR wc, uc; + + + if (ld_word(dir + LDIR_FstClusLO) != 0) return 0; /* Check LDIR_FstClusLO */ + + i = ((dir[LDIR_Ord] & 0x3F) - 1) * 13; /* Offset in the LFN buffer */ + + for (wc = 1, s = 0; s < 13; s++) { /* Process all characters in the entry */ + uc = ld_word(dir + LfnOfs[s]); /* Pick an LFN character */ + if (wc != 0) { + if (i >= FF_MAX_LFN + 1 || ff_wtoupper(uc) != ff_wtoupper(lfnbuf[i++])) { /* Compare it */ + return 0; /* Not matched */ + } + wc = uc; + } else { + if (uc != 0xFFFF) return 0; /* Check filler */ + } + } + + if ((dir[LDIR_Ord] & LLEF) && wc && lfnbuf[i]) return 0; /* Last segment matched but different length */ + + return 1; /* The part of LFN matched */ +} + + +#if FF_FS_MINIMIZE <= 1 || FF_FS_RPATH >= 2 || FF_USE_LABEL || FF_FS_EXFAT +/*-----------------------------------------------------*/ +/* FAT-LFN: Pick a part of file name from an LFN entry */ +/*-----------------------------------------------------*/ + +static int pick_lfn ( /* 1:succeeded, 0:buffer overflow or invalid LFN entry */ + WCHAR* lfnbuf, /* Pointer to the LFN working buffer */ + BYTE* dir /* Pointer to the LFN entry */ +) +{ + UINT i, s; + WCHAR wc, uc; + + + if (ld_word(dir + LDIR_FstClusLO) != 0) return 0; /* Check LDIR_FstClusLO is 0 */ + + i = ((dir[LDIR_Ord] & ~LLEF) - 1) * 13; /* Offset in the LFN buffer */ + + for (wc = 1, s = 0; s < 13; s++) { /* Process all characters in the entry */ + uc = ld_word(dir + LfnOfs[s]); /* Pick an LFN character */ + if (wc != 0) { + if (i >= FF_MAX_LFN + 1) return 0; /* Buffer overflow? */ + lfnbuf[i++] = wc = uc; /* Store it */ + } else { + if (uc != 0xFFFF) return 0; /* Check filler */ + } + } + + if (dir[LDIR_Ord] & LLEF && wc != 0) { /* Put terminator if it is the last LFN part and not terminated */ + if (i >= FF_MAX_LFN + 1) return 0; /* Buffer overflow? */ + lfnbuf[i] = 0; + } + + return 1; /* The part of LFN is valid */ +} +#endif + + +#if !FF_FS_READONLY +/*-----------------------------------------*/ +/* FAT-LFN: Create an entry of LFN entries */ +/*-----------------------------------------*/ + +static void put_lfn ( + const WCHAR* lfn, /* Pointer to the LFN */ + BYTE* dir, /* Pointer to the LFN entry to be created */ + BYTE ord, /* LFN order (1-20) */ + BYTE sum /* Checksum of the corresponding SFN */ +) +{ + UINT i, s; + WCHAR wc; + + + dir[LDIR_Chksum] = sum; /* Set checksum */ + dir[LDIR_Attr] = AM_LFN; /* Set attribute. LFN entry */ + dir[LDIR_Type] = 0; + st_word(dir + LDIR_FstClusLO, 0); + + i = (ord - 1) * 13; /* Get offset in the LFN working buffer */ + s = wc = 0; + do { + if (wc != 0xFFFF) wc = lfn[i++]; /* Get an effective character */ + st_word(dir + LfnOfs[s], wc); /* Put it */ + if (wc == 0) wc = 0xFFFF; /* Padding characters for following items */ + } while (++s < 13); + if (wc == 0xFFFF || !lfn[i]) ord |= LLEF; /* Last LFN part is the start of LFN sequence */ + dir[LDIR_Ord] = ord; /* Set the LFN order */ +} + +#endif /* !FF_FS_READONLY */ +#endif /* FF_USE_LFN */ + + + +#if FF_USE_LFN && !FF_FS_READONLY +/*-----------------------------------------------------------------------*/ +/* FAT-LFN: Create a Numbered SFN */ +/*-----------------------------------------------------------------------*/ + +static void gen_numname ( + BYTE* dst, /* Pointer to the buffer to store numbered SFN */ + const BYTE* src, /* Pointer to SFN in directory form */ + const WCHAR* lfn, /* Pointer to LFN */ + UINT seq /* Sequence number */ +) +{ + BYTE ns[8], c; + UINT i, j; + WCHAR wc; + DWORD sreg; + + + memcpy(dst, src, 11); /* Prepare the SFN to be modified */ + + if (seq > 5) { /* In case of many collisions, generate a hash number instead of sequential number */ + sreg = seq; + while (*lfn) { /* Create a CRC as hash value */ + wc = *lfn++; + for (i = 0; i < 16; i++) { + sreg = (sreg << 1) + (wc & 1); + wc >>= 1; + if (sreg & 0x10000) sreg ^= 0x11021; + } + } + seq = (UINT)sreg; + } + + /* Make suffix (~ + hexdecimal) */ + i = 7; + do { + c = (BYTE)((seq % 16) + '0'); seq /= 16; + if (c > '9') c += 7; + ns[i--] = c; + } while (i && seq); + ns[i] = '~'; + + /* Append the suffix to the SFN body */ + for (j = 0; j < i && dst[j] != ' '; j++) { /* Find the offset to append */ + if (dbc_1st(dst[j])) { /* To avoid DBC break up */ + if (j == i - 1) break; + j++; + } + } + do { /* Append the suffix */ + dst[j++] = (i < 8) ? ns[i++] : ' '; + } while (j < 8); +} +#endif /* FF_USE_LFN && !FF_FS_READONLY */ + + + +#if FF_USE_LFN +/*-----------------------------------------------------------------------*/ +/* FAT-LFN: Calculate checksum of an SFN entry */ +/*-----------------------------------------------------------------------*/ + +static BYTE sum_sfn ( + const BYTE* dir /* Pointer to the SFN entry */ +) +{ + BYTE sum = 0; + UINT n = 11; + + do { + sum = (sum >> 1) + (sum << 7) + *dir++; + } while (--n); + return sum; +} + +#endif /* FF_USE_LFN */ + + + +#if FF_FS_EXFAT +/*-----------------------------------------------------------------------*/ +/* exFAT: Checksum */ +/*-----------------------------------------------------------------------*/ + +static WORD xdir_sum ( /* Get checksum of the directoly entry block */ + const BYTE* dir /* Directory entry block to be calculated */ +) +{ + UINT i, szblk; + WORD sum; + + + szblk = (dir[XDIR_NumSec] + 1) * SZDIRE; /* Number of bytes of the entry block */ + for (i = sum = 0; i < szblk; i++) { + if (i == XDIR_SetSum) { /* Skip 2-byte sum field */ + i++; + } else { + sum = ((sum & 1) ? 0x8000 : 0) + (sum >> 1) + dir[i]; + } + } + return sum; +} + + + +static WORD xname_sum ( /* Get check sum (to be used as hash) of the file name */ + const WCHAR* name /* File name to be calculated */ +) +{ + WCHAR chr; + WORD sum = 0; + + + while ((chr = *name++) != 0) { + chr = (WCHAR)ff_wtoupper(chr); /* File name needs to be up-case converted */ + sum = ((sum & 1) ? 0x8000 : 0) + (sum >> 1) + (chr & 0xFF); + sum = ((sum & 1) ? 0x8000 : 0) + (sum >> 1) + (chr >> 8); + } + return sum; +} + + +#if !FF_FS_READONLY && FF_USE_MKFS +static DWORD xsum32 ( /* Returns 32-bit checksum */ + BYTE dat, /* Byte to be calculated (byte-by-byte processing) */ + DWORD sum /* Previous sum value */ +) +{ + sum = ((sum & 1) ? 0x80000000 : 0) + (sum >> 1) + dat; + return sum; +} +#endif + + + +/*-----------------------------------*/ +/* exFAT: Get a directry entry block */ +/*-----------------------------------*/ + +static FRESULT load_xdir ( /* FR_INT_ERR: invalid entry block */ + DIR* dp /* Reading direcotry object pointing top of the entry block to load */ +) +{ + FRESULT res; + UINT i, sz_ent; + BYTE *dirb = dp->obj.fs->dirbuf; /* Pointer to the on-memory direcotry entry block 85+C0+C1s */ + + + /* Load file directory entry */ + res = move_window(dp->obj.fs, dp->sect); + if (res != FR_OK) return res; + if (dp->dir[XDIR_Type] != ET_FILEDIR) return FR_INT_ERR; /* Invalid order */ + memcpy(dirb + 0 * SZDIRE, dp->dir, SZDIRE); + sz_ent = (dirb[XDIR_NumSec] + 1) * SZDIRE; + if (sz_ent < 3 * SZDIRE || sz_ent > 19 * SZDIRE) return FR_INT_ERR; + + /* Load stream extension entry */ + res = dir_next(dp, 0); + if (res == FR_NO_FILE) res = FR_INT_ERR; /* It cannot be */ + if (res != FR_OK) return res; + res = move_window(dp->obj.fs, dp->sect); + if (res != FR_OK) return res; + if (dp->dir[XDIR_Type] != ET_STREAM) return FR_INT_ERR; /* Invalid order */ + memcpy(dirb + 1 * SZDIRE, dp->dir, SZDIRE); + if (MAXDIRB(dirb[XDIR_NumName]) > sz_ent) return FR_INT_ERR; + + /* Load file name entries */ + i = 2 * SZDIRE; /* Name offset to load */ + do { + res = dir_next(dp, 0); + if (res == FR_NO_FILE) res = FR_INT_ERR; /* It cannot be */ + if (res != FR_OK) return res; + res = move_window(dp->obj.fs, dp->sect); + if (res != FR_OK) return res; + if (dp->dir[XDIR_Type] != ET_FILENAME) return FR_INT_ERR; /* Invalid order */ + if (i < MAXDIRB(FF_MAX_LFN)) memcpy(dirb + i, dp->dir, SZDIRE); + } while ((i += SZDIRE) < sz_ent); + + /* Sanity check (do it for only accessible object) */ + if (i <= MAXDIRB(FF_MAX_LFN)) { + if (xdir_sum(dirb) != ld_word(dirb + XDIR_SetSum)) return FR_INT_ERR; + } + return FR_OK; +} + + +/*------------------------------------------------------------------*/ +/* exFAT: Initialize object allocation info with loaded entry block */ +/*------------------------------------------------------------------*/ + +static void init_alloc_info ( + FATFS* fs, /* Filesystem object */ + FFOBJID* obj /* Object allocation information to be initialized */ +) +{ + obj->sclust = ld_dword(fs->dirbuf + XDIR_FstClus); /* Start cluster */ + obj->objsize = ld_qword(fs->dirbuf + XDIR_FileSize); /* Size */ + obj->stat = fs->dirbuf[XDIR_GenFlags] & 2; /* Allocation status */ + obj->n_frag = 0; /* No last fragment info */ +} + + + +#if !FF_FS_READONLY || FF_FS_RPATH != 0 +/*------------------------------------------------*/ +/* exFAT: Load the object's directory entry block */ +/*------------------------------------------------*/ + +static FRESULT load_obj_xdir ( + DIR* dp, /* Blank directory object to be used to access containing direcotry */ + const FFOBJID* obj /* Object with its containing directory information */ +) +{ + FRESULT res; + + /* Open object containing directory */ + dp->obj.fs = obj->fs; + dp->obj.sclust = obj->c_scl; + dp->obj.stat = (BYTE)obj->c_size; + dp->obj.objsize = obj->c_size & 0xFFFFFF00; + dp->obj.n_frag = 0; + dp->blk_ofs = obj->c_ofs; + + res = dir_sdi(dp, dp->blk_ofs); /* Goto object's entry block */ + if (res == FR_OK) { + res = load_xdir(dp); /* Load the object's entry block */ + } + return res; +} +#endif + + +#if !FF_FS_READONLY +/*----------------------------------------*/ +/* exFAT: Store the directory entry block */ +/*----------------------------------------*/ + +static FRESULT store_xdir ( + DIR* dp /* Pointer to the direcotry object */ +) +{ + FRESULT res; + UINT nent; + BYTE *dirb = dp->obj.fs->dirbuf; /* Pointer to the direcotry entry block 85+C0+C1s */ + + /* Create set sum */ + st_word(dirb + XDIR_SetSum, xdir_sum(dirb)); + nent = dirb[XDIR_NumSec] + 1; + + /* Store the direcotry entry block to the directory */ + res = dir_sdi(dp, dp->blk_ofs); + while (res == FR_OK) { + res = move_window(dp->obj.fs, dp->sect); + if (res != FR_OK) break; + memcpy(dp->dir, dirb, SZDIRE); + dp->obj.fs->wflag = 1; + if (--nent == 0) break; + dirb += SZDIRE; + res = dir_next(dp, 0); + } + return (res == FR_OK || res == FR_DISK_ERR) ? res : FR_INT_ERR; +} + + + +/*-------------------------------------------*/ +/* exFAT: Create a new directory enrty block */ +/*-------------------------------------------*/ + +static void create_xdir ( + BYTE* dirb, /* Pointer to the direcotry entry block buffer */ + const WCHAR* lfn /* Pointer to the object name */ +) +{ + UINT i; + BYTE nc1, nlen; + WCHAR wc; + + + /* Create file-directory and stream-extension entry */ + memset(dirb, 0, 2 * SZDIRE); + dirb[0 * SZDIRE + XDIR_Type] = ET_FILEDIR; + dirb[1 * SZDIRE + XDIR_Type] = ET_STREAM; + + /* Create file-name entries */ + i = SZDIRE * 2; /* Top of file_name entries */ + nlen = nc1 = 0; wc = 1; + do { + dirb[i++] = ET_FILENAME; dirb[i++] = 0; + do { /* Fill name field */ + if (wc != 0 && (wc = lfn[nlen]) != 0) nlen++; /* Get a character if exist */ + st_word(dirb + i, wc); /* Store it */ + i += 2; + } while (i % SZDIRE != 0); + nc1++; + } while (lfn[nlen]); /* Fill next entry if any char follows */ + + dirb[XDIR_NumName] = nlen; /* Set name length */ + dirb[XDIR_NumSec] = 1 + nc1; /* Set secondary count (C0 + C1s) */ + st_word(dirb + XDIR_NameHash, xname_sum(lfn)); /* Set name hash */ +} + +#endif /* !FF_FS_READONLY */ +#endif /* FF_FS_EXFAT */ + + + +#if FF_FS_MINIMIZE <= 1 || FF_FS_RPATH >= 2 || FF_USE_LABEL || FF_FS_EXFAT +/*-----------------------------------------------------------------------*/ +/* Read an object from the directory */ +/*-----------------------------------------------------------------------*/ + +#define DIR_READ_FILE(dp) dir_read(dp, 0) +#define DIR_READ_LABEL(dp) dir_read(dp, 1) + +static FRESULT dir_read ( + DIR* dp, /* Pointer to the directory object */ + int vol /* Filtered by 0:file/directory or 1:volume label */ +) +{ + FRESULT res = FR_NO_FILE; + FATFS *fs = dp->obj.fs; + BYTE attr, b; +#if FF_USE_LFN + BYTE ord = 0xFF, sum = 0xFF; +#endif + + while (dp->sect) { + res = move_window(fs, dp->sect); + if (res != FR_OK) break; + b = dp->dir[DIR_Name]; /* Test for the entry type */ + if (b == 0) { + res = FR_NO_FILE; break; /* Reached to end of the directory */ + } +#if FF_FS_EXFAT + if (fs->fs_type == FS_EXFAT) { /* On the exFAT volume */ + if (FF_USE_LABEL && vol) { + if (b == ET_VLABEL) break; /* Volume label entry? */ + } else { + if (b == ET_FILEDIR) { /* Start of the file entry block? */ + dp->blk_ofs = dp->dptr; /* Get location of the block */ + res = load_xdir(dp); /* Load the entry block */ + if (res == FR_OK) { + dp->obj.attr = fs->dirbuf[XDIR_Attr] & AM_MASK; /* Get attribute */ + } + break; + } + } + } else +#endif + { /* On the FAT/FAT32 volume */ + dp->obj.attr = attr = dp->dir[DIR_Attr] & AM_MASK; /* Get attribute */ +#if FF_USE_LFN /* LFN configuration */ + if (b == DDEM || b == '.' || (int)((attr & ~AM_ARC) == AM_VOL) != vol) { /* An entry without valid data */ + ord = 0xFF; + } else { + if (attr == AM_LFN) { /* An LFN entry is found */ + if (b & LLEF) { /* Is it start of an LFN sequence? */ + sum = dp->dir[LDIR_Chksum]; + b &= (BYTE)~LLEF; ord = b; + dp->blk_ofs = dp->dptr; + } + /* Check LFN validity and capture it */ + ord = (b == ord && sum == dp->dir[LDIR_Chksum] && pick_lfn(fs->lfnbuf, dp->dir)) ? ord - 1 : 0xFF; + } else { /* An SFN entry is found */ + if (ord != 0 || sum != sum_sfn(dp->dir)) { /* Is there a valid LFN? */ + dp->blk_ofs = 0xFFFFFFFF; /* It has no LFN. */ + } + break; + } + } +#else /* Non LFN configuration */ + if (b != DDEM && b != '.' && attr != AM_LFN && (int)((attr & ~AM_ARC) == AM_VOL) == vol) { /* Is it a valid entry? */ + break; + } +#endif + } + res = dir_next(dp, 0); /* Next entry */ + if (res != FR_OK) break; + } + + if (res != FR_OK) dp->sect = 0; /* Terminate the read operation on error or EOT */ + return res; +} + +#endif /* FF_FS_MINIMIZE <= 1 || FF_USE_LABEL || FF_FS_RPATH >= 2 */ + + + +/*-----------------------------------------------------------------------*/ +/* Directory handling - Find an object in the directory */ +/*-----------------------------------------------------------------------*/ + +static FRESULT dir_find ( /* FR_OK(0):succeeded, !=0:error */ + DIR* dp /* Pointer to the directory object with the file name */ +) +{ + FRESULT res; + FATFS *fs = dp->obj.fs; + BYTE c; +#if FF_USE_LFN + BYTE a, ord, sum; +#endif + + res = dir_sdi(dp, 0); /* Rewind directory object */ + if (res != FR_OK) return res; +#if FF_FS_EXFAT + if (fs->fs_type == FS_EXFAT) { /* On the exFAT volume */ + BYTE nc; + UINT di, ni; + WORD hash = xname_sum(fs->lfnbuf); /* Hash value of the name to find */ + + while ((res = DIR_READ_FILE(dp)) == FR_OK) { /* Read an item */ +#if FF_MAX_LFN < 255 + if (fs->dirbuf[XDIR_NumName] > FF_MAX_LFN) continue; /* Skip comparison if inaccessible object name */ +#endif + if (ld_word(fs->dirbuf + XDIR_NameHash) != hash) continue; /* Skip comparison if hash mismatched */ + for (nc = fs->dirbuf[XDIR_NumName], di = SZDIRE * 2, ni = 0; nc; nc--, di += 2, ni++) { /* Compare the name */ + if ((di % SZDIRE) == 0) di += 2; + if (ff_wtoupper(ld_word(fs->dirbuf + di)) != ff_wtoupper(fs->lfnbuf[ni])) break; + } + if (nc == 0 && !fs->lfnbuf[ni]) break; /* Name matched? */ + } + return res; + } +#endif + /* On the FAT/FAT32 volume */ +#if FF_USE_LFN + ord = sum = 0xFF; dp->blk_ofs = 0xFFFFFFFF; /* Reset LFN sequence */ +#endif + do { + res = move_window(fs, dp->sect); + if (res != FR_OK) break; + c = dp->dir[DIR_Name]; + if (c == 0) { res = FR_NO_FILE; break; } /* Reached to end of table */ +#if FF_USE_LFN /* LFN configuration */ + dp->obj.attr = a = dp->dir[DIR_Attr] & AM_MASK; + if (c == DDEM || ((a & AM_VOL) && a != AM_LFN)) { /* An entry without valid data */ + ord = 0xFF; dp->blk_ofs = 0xFFFFFFFF; /* Reset LFN sequence */ + } else { + if (a == AM_LFN) { /* An LFN entry is found */ + if (!(dp->fn[NSFLAG] & NS_NOLFN)) { + if (c & LLEF) { /* Is it start of LFN sequence? */ + sum = dp->dir[LDIR_Chksum]; + c &= (BYTE)~LLEF; ord = c; /* LFN start order */ + dp->blk_ofs = dp->dptr; /* Start offset of LFN */ + } + /* Check validity of the LFN entry and compare it with given name */ + ord = (c == ord && sum == dp->dir[LDIR_Chksum] && cmp_lfn(fs->lfnbuf, dp->dir)) ? ord - 1 : 0xFF; + } + } else { /* An SFN entry is found */ + if (ord == 0 && sum == sum_sfn(dp->dir)) break; /* LFN matched? */ + if (!(dp->fn[NSFLAG] & NS_LOSS) && !memcmp(dp->dir, dp->fn, 11)) break; /* SFN matched? */ + ord = 0xFF; dp->blk_ofs = 0xFFFFFFFF; /* Reset LFN sequence */ + } + } +#else /* Non LFN configuration */ + dp->obj.attr = dp->dir[DIR_Attr] & AM_MASK; + if (!(dp->dir[DIR_Attr] & AM_VOL) && !memcmp(dp->dir, dp->fn, 11)) break; /* Is it a valid entry? */ +#endif + res = dir_next(dp, 0); /* Next entry */ + } while (res == FR_OK); + + return res; +} + + + + +#if !FF_FS_READONLY +/*-----------------------------------------------------------------------*/ +/* Register an object to the directory */ +/*-----------------------------------------------------------------------*/ + +static FRESULT dir_register ( /* FR_OK:succeeded, FR_DENIED:no free entry or too many SFN collision, FR_DISK_ERR:disk error */ + DIR* dp /* Target directory with object name to be created */ +) +{ + FRESULT res; + FATFS *fs = dp->obj.fs; +#if FF_USE_LFN /* LFN configuration */ + UINT n, len, n_ent; + BYTE sn[12], sum; + + + if (dp->fn[NSFLAG] & (NS_DOT | NS_NONAME)) return FR_INVALID_NAME; /* Check name validity */ + for (len = 0; fs->lfnbuf[len]; len++) ; /* Get lfn length */ + +#if FF_FS_EXFAT + if (fs->fs_type == FS_EXFAT) { /* On the exFAT volume */ + n_ent = (len + 14) / 15 + 2; /* Number of entries to allocate (85+C0+C1s) */ + res = dir_alloc(dp, n_ent); /* Allocate directory entries */ + if (res != FR_OK) return res; + dp->blk_ofs = dp->dptr - SZDIRE * (n_ent - 1); /* Set the allocated entry block offset */ + + if (dp->obj.stat & 4) { /* Has the directory been stretched by new allocation? */ + dp->obj.stat &= ~4; + res = fill_first_frag(&dp->obj); /* Fill the first fragment on the FAT if needed */ + if (res != FR_OK) return res; + res = fill_last_frag(&dp->obj, dp->clust, 0xFFFFFFFF); /* Fill the last fragment on the FAT if needed */ + if (res != FR_OK) return res; + if (dp->obj.sclust != 0) { /* Is it a sub-directory? */ + DIR dj; + + res = load_obj_xdir(&dj, &dp->obj); /* Load the object status */ + if (res != FR_OK) return res; + dp->obj.objsize += (DWORD)fs->csize * SS(fs); /* Increase the directory size by cluster size */ + st_qword(fs->dirbuf + XDIR_FileSize, dp->obj.objsize); + st_qword(fs->dirbuf + XDIR_ValidFileSize, dp->obj.objsize); + fs->dirbuf[XDIR_GenFlags] = dp->obj.stat | 1; /* Update the allocation status */ + res = store_xdir(&dj); /* Store the object status */ + if (res != FR_OK) return res; + } + } + + create_xdir(fs->dirbuf, fs->lfnbuf); /* Create on-memory directory block to be written later */ + return FR_OK; + } +#endif + /* On the FAT/FAT32 volume */ + memcpy(sn, dp->fn, 12); + if (sn[NSFLAG] & NS_LOSS) { /* When LFN is out of 8.3 format, generate a numbered name */ + dp->fn[NSFLAG] = NS_NOLFN; /* Find only SFN */ + for (n = 1; n < 100; n++) { + gen_numname(dp->fn, sn, fs->lfnbuf, n); /* Generate a numbered name */ + res = dir_find(dp); /* Check if the name collides with existing SFN */ + if (res != FR_OK) break; + } + if (n == 100) return FR_DENIED; /* Abort if too many collisions */ + if (res != FR_NO_FILE) return res; /* Abort if the result is other than 'not collided' */ + dp->fn[NSFLAG] = sn[NSFLAG]; + } + + /* Create an SFN with/without LFNs. */ + n_ent = (sn[NSFLAG] & NS_LFN) ? (len + 12) / 13 + 1 : 1; /* Number of entries to allocate */ + res = dir_alloc(dp, n_ent); /* Allocate entries */ + if (res == FR_OK && --n_ent) { /* Set LFN entry if needed */ + res = dir_sdi(dp, dp->dptr - n_ent * SZDIRE); + if (res == FR_OK) { + sum = sum_sfn(dp->fn); /* Checksum value of the SFN tied to the LFN */ + do { /* Store LFN entries in bottom first */ + res = move_window(fs, dp->sect); + if (res != FR_OK) break; + put_lfn(fs->lfnbuf, dp->dir, (BYTE)n_ent, sum); + fs->wflag = 1; + res = dir_next(dp, 0); /* Next entry */ + } while (res == FR_OK && --n_ent); + } + } + +#else /* Non LFN configuration */ + res = dir_alloc(dp, 1); /* Allocate an entry for SFN */ + +#endif + + /* Set SFN entry */ + if (res == FR_OK) { + res = move_window(fs, dp->sect); + if (res == FR_OK) { + memset(dp->dir, 0, SZDIRE); /* Clean the entry */ + memcpy(dp->dir + DIR_Name, dp->fn, 11); /* Put SFN */ +#if FF_USE_LFN + dp->dir[DIR_NTres] = dp->fn[NSFLAG] & (NS_BODY | NS_EXT); /* Put NT flag */ +#endif + fs->wflag = 1; + } + } + + return res; +} + +#endif /* !FF_FS_READONLY */ + + + +#if !FF_FS_READONLY && FF_FS_MINIMIZE == 0 +/*-----------------------------------------------------------------------*/ +/* Remove an object from the directory */ +/*-----------------------------------------------------------------------*/ + +static FRESULT dir_remove ( /* FR_OK:Succeeded, FR_DISK_ERR:A disk error */ + DIR* dp /* Directory object pointing the entry to be removed */ +) +{ + FRESULT res; + FATFS *fs = dp->obj.fs; +#if FF_USE_LFN /* LFN configuration */ + DWORD last = dp->dptr; + + res = (dp->blk_ofs == 0xFFFFFFFF) ? FR_OK : dir_sdi(dp, dp->blk_ofs); /* Goto top of the entry block if LFN is exist */ + if (res == FR_OK) { + do { + res = move_window(fs, dp->sect); + if (res != FR_OK) break; + if (FF_FS_EXFAT && fs->fs_type == FS_EXFAT) { /* On the exFAT volume */ + dp->dir[XDIR_Type] &= 0x7F; /* Clear the entry InUse flag. */ + } else { /* On the FAT/FAT32 volume */ + dp->dir[DIR_Name] = DDEM; /* Mark the entry 'deleted'. */ + } + fs->wflag = 1; + if (dp->dptr >= last) break; /* If reached last entry then all entries of the object has been deleted. */ + res = dir_next(dp, 0); /* Next entry */ + } while (res == FR_OK); + if (res == FR_NO_FILE) res = FR_INT_ERR; + } +#else /* Non LFN configuration */ + + res = move_window(fs, dp->sect); + if (res == FR_OK) { + dp->dir[DIR_Name] = DDEM; /* Mark the entry 'deleted'.*/ + fs->wflag = 1; + } +#endif + + return res; +} + +#endif /* !FF_FS_READONLY && FF_FS_MINIMIZE == 0 */ + + + +#if FF_FS_MINIMIZE <= 1 || FF_FS_RPATH >= 2 +/*-----------------------------------------------------------------------*/ +/* Get file information from directory entry */ +/*-----------------------------------------------------------------------*/ + +static void get_fileinfo ( + DIR* dp, /* Pointer to the directory object */ + FILINFO* fno /* Pointer to the file information to be filled */ +) +{ + UINT si, di; +#if FF_USE_LFN + BYTE lcf; + WCHAR wc, hs; + FATFS *fs = dp->obj.fs; + UINT nw; +#else + TCHAR c; +#endif + + + fno->fname[0] = 0; /* Invaidate file info */ + if (dp->sect == 0) return; /* Exit if read pointer has reached end of directory */ + +#if FF_USE_LFN /* LFN configuration */ +#if FF_FS_EXFAT + if (fs->fs_type == FS_EXFAT) { /* exFAT volume */ + UINT nc = 0; + + si = SZDIRE * 2; di = 0; /* 1st C1 entry in the entry block */ + hs = 0; + while (nc < fs->dirbuf[XDIR_NumName]) { + if (si >= MAXDIRB(FF_MAX_LFN)) { di = 0; break; } /* Truncated directory block? */ + if ((si % SZDIRE) == 0) si += 2; /* Skip entry type field */ + wc = ld_word(fs->dirbuf + si); si += 2; nc++; /* Get a character */ + if (hs == 0 && IsSurrogate(wc)) { /* Is it a surrogate? */ + hs = wc; continue; /* Get low surrogate */ + } + nw = put_utf((DWORD)hs << 16 | wc, &fno->fname[di], FF_LFN_BUF - di); /* Store it in API encoding */ + if (nw == 0) { di = 0; break; } /* Buffer overflow or wrong char? */ + di += nw; + hs = 0; + } + if (hs != 0) di = 0; /* Broken surrogate pair? */ + if (di == 0) fno->fname[di++] = '?'; /* Inaccessible object name? */ + fno->fname[di] = 0; /* Terminate the name */ + fno->altname[0] = 0; /* exFAT does not support SFN */ + + fno->fattrib = fs->dirbuf[XDIR_Attr] & AM_MASKX; /* Attribute */ + fno->fsize = (fno->fattrib & AM_DIR) ? 0 : ld_qword(fs->dirbuf + XDIR_FileSize); /* Size */ + fno->ftime = ld_word(fs->dirbuf + XDIR_ModTime + 0); /* Time */ + fno->fdate = ld_word(fs->dirbuf + XDIR_ModTime + 2); /* Date */ + return; + } else +#endif + { /* FAT/FAT32 volume */ + if (dp->blk_ofs != 0xFFFFFFFF) { /* Get LFN if available */ + si = di = 0; + hs = 0; + while (fs->lfnbuf[si] != 0) { + wc = fs->lfnbuf[si++]; /* Get an LFN character (UTF-16) */ + if (hs == 0 && IsSurrogate(wc)) { /* Is it a surrogate? */ + hs = wc; continue; /* Get low surrogate */ + } + nw = put_utf((DWORD)hs << 16 | wc, &fno->fname[di], FF_LFN_BUF - di); /* Store it in API encoding */ + if (nw == 0) { di = 0; break; } /* Buffer overflow or wrong char? */ + di += nw; + hs = 0; + } + if (hs != 0) di = 0; /* Broken surrogate pair? */ + fno->fname[di] = 0; /* Terminate the LFN (null string means LFN is invalid) */ + } + } + + si = di = 0; + while (si < 11) { /* Get SFN from SFN entry */ + wc = dp->dir[si++]; /* Get a char */ + if (wc == ' ') continue; /* Skip padding spaces */ + if (wc == RDDEM) wc = DDEM; /* Restore replaced DDEM character */ + if (si == 9 && di < FF_SFN_BUF) fno->altname[di++] = '.'; /* Insert a . if extension is exist */ +#if FF_LFN_UNICODE >= 1 /* Unicode output */ + if (dbc_1st((BYTE)wc) && si != 8 && si != 11 && dbc_2nd(dp->dir[si])) { /* Make a DBC if needed */ + wc = wc << 8 | dp->dir[si++]; + } + wc = ff_oem2uni(wc, CODEPAGE); /* ANSI/OEM -> Unicode */ + if (wc == 0) { di = 0; break; } /* Wrong char in the current code page? */ + nw = put_utf(wc, &fno->altname[di], FF_SFN_BUF - di); /* Store it in API encoding */ + if (nw == 0) { di = 0; break; } /* Buffer overflow? */ + di += nw; +#else /* ANSI/OEM output */ + fno->altname[di++] = (TCHAR)wc; /* Store it without any conversion */ +#endif + } + fno->altname[di] = 0; /* Terminate the SFN (null string means SFN is invalid) */ + + if (fno->fname[0] == 0) { /* If LFN is invalid, altname[] needs to be copied to fname[] */ + if (di == 0) { /* If LFN and SFN both are invalid, this object is inaccesible */ + fno->fname[di++] = '?'; + } else { + for (si = di = 0, lcf = NS_BODY; fno->altname[si]; si++, di++) { /* Copy altname[] to fname[] with case information */ + wc = (WCHAR)fno->altname[si]; + if (wc == '.') lcf = NS_EXT; + if (IsUpper(wc) && (dp->dir[DIR_NTres] & lcf)) wc += 0x20; + fno->fname[di] = (TCHAR)wc; + } + } + fno->fname[di] = 0; /* Terminate the LFN */ + if (!dp->dir[DIR_NTres]) fno->altname[0] = 0; /* Altname is not needed if neither LFN nor case info is exist. */ + } + +#else /* Non-LFN configuration */ + si = di = 0; + while (si < 11) { /* Copy name body and extension */ + c = (TCHAR)dp->dir[si++]; + if (c == ' ') continue; /* Skip padding spaces */ + if (c == RDDEM) c = DDEM; /* Restore replaced DDEM character */ + if (si == 9) fno->fname[di++] = '.';/* Insert a . if extension is exist */ + fno->fname[di++] = c; + } + fno->fname[di] = 0; /* Terminate the SFN */ +#endif + + fno->fattrib = dp->dir[DIR_Attr] & AM_MASK; /* Attribute */ + fno->fsize = ld_dword(dp->dir + DIR_FileSize); /* Size */ + fno->ftime = ld_word(dp->dir + DIR_ModTime + 0); /* Time */ + fno->fdate = ld_word(dp->dir + DIR_ModTime + 2); /* Date */ +} + +#endif /* FF_FS_MINIMIZE <= 1 || FF_FS_RPATH >= 2 */ + + + +#if FF_USE_FIND && FF_FS_MINIMIZE <= 1 +/*-----------------------------------------------------------------------*/ +/* Pattern matching */ +/*-----------------------------------------------------------------------*/ + +#define FIND_RECURS 4 /* Maximum number of wildcard terms in the pattern to limit recursion */ + + +static DWORD get_achar ( /* Get a character and advance ptr */ + const TCHAR** ptr /* Pointer to pointer to the ANSI/OEM or Unicode string */ +) +{ + DWORD chr; + + +#if FF_USE_LFN && FF_LFN_UNICODE >= 1 /* Unicode input */ + chr = tchar2uni(ptr); + if (chr == 0xFFFFFFFF) chr = 0; /* Wrong UTF encoding is recognized as end of the string */ + chr = ff_wtoupper(chr); + +#else /* ANSI/OEM input */ + chr = (BYTE)*(*ptr)++; /* Get a byte */ + if (IsLower(chr)) chr -= 0x20; /* To upper ASCII char */ +#if FF_CODE_PAGE == 0 + if (ExCvt && chr >= 0x80) chr = ExCvt[chr - 0x80]; /* To upper SBCS extended char */ +#elif FF_CODE_PAGE < 900 + if (chr >= 0x80) chr = ExCvt[chr - 0x80]; /* To upper SBCS extended char */ +#endif +#if FF_CODE_PAGE == 0 || FF_CODE_PAGE >= 900 + if (dbc_1st((BYTE)chr)) { /* Get DBC 2nd byte if needed */ + chr = dbc_2nd((BYTE)**ptr) ? chr << 8 | (BYTE)*(*ptr)++ : 0; + } +#endif + +#endif + return chr; +} + + +static int pattern_match ( /* 0:mismatched, 1:matched */ + const TCHAR* pat, /* Matching pattern */ + const TCHAR* nam, /* String to be tested */ + UINT skip, /* Number of pre-skip chars (number of ?s, b8:infinite (* specified)) */ + UINT recur /* Recursion count */ +) +{ + const TCHAR *pptr, *nptr; + DWORD pchr, nchr; + UINT sk; + + + while ((skip & 0xFF) != 0) { /* Pre-skip name chars */ + if (!get_achar(&nam)) return 0; /* Branch mismatched if less name chars */ + skip--; + } + if (*pat == 0 && skip) return 1; /* Matched? (short circuit) */ + + do { + pptr = pat; nptr = nam; /* Top of pattern and name to match */ + for (;;) { + if (*pptr == '?' || *pptr == '*') { /* Wildcard term? */ + if (recur == 0) return 0; /* Too many wildcard terms? */ + sk = 0; + do { /* Analyze the wildcard term */ + if (*pptr++ == '?') sk++; else sk |= 0x100; + } while (*pptr == '?' || *pptr == '*'); + if (pattern_match(pptr, nptr, sk, recur - 1)) return 1; /* Test new branch (recursive call) */ + nchr = *nptr; break; /* Branch mismatched */ + } + pchr = get_achar(&pptr); /* Get a pattern char */ + nchr = get_achar(&nptr); /* Get a name char */ + if (pchr != nchr) break; /* Branch mismatched? */ + if (pchr == 0) return 1; /* Branch matched? (matched at end of both strings) */ + } + get_achar(&nam); /* nam++ */ + } while (skip && nchr); /* Retry until end of name if infinite search is specified */ + + return 0; +} + +#endif /* FF_USE_FIND && FF_FS_MINIMIZE <= 1 */ + + + +/*-----------------------------------------------------------------------*/ +/* Pick a top segment and create the object name in directory form */ +/*-----------------------------------------------------------------------*/ + +static FRESULT create_name ( /* FR_OK: successful, FR_INVALID_NAME: could not create */ + DIR* dp, /* Pointer to the directory object */ + const TCHAR** path /* Pointer to pointer to the segment in the path string */ +) +{ +#if FF_USE_LFN /* LFN configuration */ + BYTE b, cf; + WCHAR wc, *lfn; + DWORD uc; + UINT i, ni, si, di; + const TCHAR *p; + + + /* Create LFN into LFN working buffer */ + p = *path; lfn = dp->obj.fs->lfnbuf; di = 0; + for (;;) { + uc = tchar2uni(&p); /* Get a character */ + if (uc == 0xFFFFFFFF) return FR_INVALID_NAME; /* Invalid code or UTF decode error */ + if (uc >= 0x10000) lfn[di++] = (WCHAR)(uc >> 16); /* Store high surrogate if needed */ + wc = (WCHAR)uc; + if (wc < ' ' || IsSeparator(wc)) break; /* Break if end of the path or a separator is found */ + if (wc < 0x80 && strchr("*:<>|\"\?\x7F", (int)wc)) return FR_INVALID_NAME; /* Reject illegal characters for LFN */ + if (di >= FF_MAX_LFN) return FR_INVALID_NAME; /* Reject too long name */ + lfn[di++] = wc; /* Store the Unicode character */ + } + if (wc < ' ') { /* Stopped at end of the path? */ + cf = NS_LAST; /* Last segment */ + } else { /* Stopped at a separator */ + while (IsSeparator(*p)) p++; /* Skip duplicated separators if exist */ + cf = 0; /* Next segment may follow */ + if (IsTerminator(*p)) cf = NS_LAST; /* Ignore terminating separator */ + } + *path = p; /* Return pointer to the next segment */ + +#if FF_FS_RPATH != 0 + if ((di == 1 && lfn[di - 1] == '.') || + (di == 2 && lfn[di - 1] == '.' && lfn[di - 2] == '.')) { /* Is this segment a dot name? */ + lfn[di] = 0; + for (i = 0; i < 11; i++) { /* Create dot name for SFN entry */ + dp->fn[i] = (i < di) ? '.' : ' '; + } + dp->fn[i] = cf | NS_DOT; /* This is a dot entry */ + return FR_OK; + } +#endif + while (di) { /* Snip off trailing spaces and dots if exist */ + wc = lfn[di - 1]; + if (wc != ' ' && wc != '.') break; + di--; + } + lfn[di] = 0; /* LFN is created into the working buffer */ + if (di == 0) return FR_INVALID_NAME; /* Reject null name */ + + /* Create SFN in directory form */ + for (si = 0; lfn[si] == ' '; si++) ; /* Remove leading spaces */ + if (si > 0 || lfn[si] == '.') cf |= NS_LOSS | NS_LFN; /* Is there any leading space or dot? */ + while (di > 0 && lfn[di - 1] != '.') di--; /* Find last dot (di<=si: no extension) */ + + memset(dp->fn, ' ', 11); + i = b = 0; ni = 8; + for (;;) { + wc = lfn[si++]; /* Get an LFN character */ + if (wc == 0) break; /* Break on end of the LFN */ + if (wc == ' ' || (wc == '.' && si != di)) { /* Remove embedded spaces and dots */ + cf |= NS_LOSS | NS_LFN; + continue; + } + + if (i >= ni || si == di) { /* End of field? */ + if (ni == 11) { /* Name extension overflow? */ + cf |= NS_LOSS | NS_LFN; + break; + } + if (si != di) cf |= NS_LOSS | NS_LFN; /* Name body overflow? */ + if (si > di) break; /* No name extension? */ + si = di; i = 8; ni = 11; b <<= 2; /* Enter name extension */ + continue; + } + + if (wc >= 0x80) { /* Is this an extended character? */ + cf |= NS_LFN; /* LFN entry needs to be created */ +#if FF_CODE_PAGE == 0 + if (ExCvt) { /* In SBCS cfg */ + wc = ff_uni2oem(wc, CODEPAGE); /* Unicode ==> ANSI/OEM code */ + if (wc & 0x80) wc = ExCvt[wc & 0x7F]; /* Convert extended character to upper (SBCS) */ + } else { /* In DBCS cfg */ + wc = ff_uni2oem(ff_wtoupper(wc), CODEPAGE); /* Unicode ==> Up-convert ==> ANSI/OEM code */ + } +#elif FF_CODE_PAGE < 900 /* In SBCS cfg */ + wc = ff_uni2oem(wc, CODEPAGE); /* Unicode ==> ANSI/OEM code */ + if (wc & 0x80) wc = ExCvt[wc & 0x7F]; /* Convert extended character to upper (SBCS) */ +#else /* In DBCS cfg */ + wc = ff_uni2oem(ff_wtoupper(wc), CODEPAGE); /* Unicode ==> Up-convert ==> ANSI/OEM code */ +#endif + } + + if (wc >= 0x100) { /* Is this a DBC? */ + if (i >= ni - 1) { /* Field overflow? */ + cf |= NS_LOSS | NS_LFN; + i = ni; continue; /* Next field */ + } + dp->fn[i++] = (BYTE)(wc >> 8); /* Put 1st byte */ + } else { /* SBC */ + if (wc == 0 || strchr("+,;=[]", (int)wc)) { /* Replace illegal characters for SFN */ + wc = '_'; cf |= NS_LOSS | NS_LFN;/* Lossy conversion */ + } else { + if (IsUpper(wc)) { /* ASCII upper case? */ + b |= 2; + } + if (IsLower(wc)) { /* ASCII lower case? */ + b |= 1; wc -= 0x20; + } + } + } + dp->fn[i++] = (BYTE)wc; + } + + if (dp->fn[0] == DDEM) dp->fn[0] = RDDEM; /* If the first character collides with DDEM, replace it with RDDEM */ + + if (ni == 8) b <<= 2; /* Shift capital flags if no extension */ + if ((b & 0x0C) == 0x0C || (b & 0x03) == 0x03) cf |= NS_LFN; /* LFN entry needs to be created if composite capitals */ + if (!(cf & NS_LFN)) { /* When LFN is in 8.3 format without extended character, NT flags are created */ + if (b & 0x01) cf |= NS_EXT; /* NT flag (Extension has small capital letters only) */ + if (b & 0x04) cf |= NS_BODY; /* NT flag (Body has small capital letters only) */ + } + + dp->fn[NSFLAG] = cf; /* SFN is created into dp->fn[] */ + + return FR_OK; + + +#else /* FF_USE_LFN : Non-LFN configuration */ + BYTE c, d, *sfn; + UINT ni, si, i; + const char *p; + + /* Create file name in directory form */ + p = *path; sfn = dp->fn; + memset(sfn, ' ', 11); + si = i = 0; ni = 8; +#if FF_FS_RPATH != 0 + if (p[si] == '.') { /* Is this a dot entry? */ + for (;;) { + c = (BYTE)p[si++]; + if (c != '.' || si >= 3) break; + sfn[i++] = c; + } + if (!IsSeparator(c) && c > ' ') return FR_INVALID_NAME; + *path = p + si; /* Return pointer to the next segment */ + sfn[NSFLAG] = (c <= ' ') ? NS_LAST | NS_DOT : NS_DOT; /* Set last segment flag if end of the path */ + return FR_OK; + } +#endif + for (;;) { + c = (BYTE)p[si++]; /* Get a byte */ + if (c <= ' ') break; /* Break if end of the path name */ + if (IsSeparator(c)) { /* Break if a separator is found */ + while (IsSeparator(p[si])) si++; /* Skip duplicated separator if exist */ + break; + } + if (c == '.' || i >= ni) { /* End of body or field overflow? */ + if (ni == 11 || c != '.') return FR_INVALID_NAME; /* Field overflow or invalid dot? */ + i = 8; ni = 11; /* Enter file extension field */ + continue; + } +#if FF_CODE_PAGE == 0 + if (ExCvt && c >= 0x80) { /* Is SBC extended character? */ + c = ExCvt[c & 0x7F]; /* To upper SBC extended character */ + } +#elif FF_CODE_PAGE > 0 && FF_CODE_PAGE < 900 + if (c >= 0x80) { /* Is SBC extended character? */ + c = ExCvt[c & 0x7F]; /* To upper SBC extended character */ + } +#endif + if (dbc_1st(c)) { /* Check if it is a DBC 1st byte */ + d = (BYTE)p[si++]; /* Get 2nd byte */ + if (!dbc_2nd(d) || i >= ni - 1) return FR_INVALID_NAME; /* Reject invalid DBC */ + sfn[i++] = c; + sfn[i++] = d; + } else { /* SBC */ + if (strchr("*+,:;<=>[]|\"\?\x7F", (int)c)) return FR_INVALID_NAME; /* Reject illegal chrs for SFN */ + if (IsLower(c)) c -= 0x20; /* To upper */ + sfn[i++] = c; + } + } + *path = &p[si]; /* Return pointer to the next segment */ + if (i == 0) return FR_INVALID_NAME; /* Reject nul string */ + + if (sfn[0] == DDEM) sfn[0] = RDDEM; /* If the first character collides with DDEM, replace it with RDDEM */ + sfn[NSFLAG] = (c <= ' ' || p[si] <= ' ') ? NS_LAST : 0; /* Set last segment flag if end of the path */ + + return FR_OK; +#endif /* FF_USE_LFN */ +} + + + + +/*-----------------------------------------------------------------------*/ +/* Follow a file path */ +/*-----------------------------------------------------------------------*/ + +static FRESULT follow_path ( /* FR_OK(0): successful, !=0: error code */ + DIR* dp, /* Directory object to return last directory and found object */ + const TCHAR* path /* Full-path string to find a file or directory */ +) +{ + FRESULT res; + BYTE ns; + FATFS *fs = dp->obj.fs; + + +#if FF_FS_RPATH != 0 + if (!IsSeparator(*path) && (FF_STR_VOLUME_ID != 2 || !IsTerminator(*path))) { /* Without heading separator */ + dp->obj.sclust = fs->cdir; /* Start at the current directory */ + } else +#endif + { /* With heading separator */ + while (IsSeparator(*path)) path++; /* Strip separators */ + dp->obj.sclust = 0; /* Start from the root directory */ + } +#if FF_FS_EXFAT + dp->obj.n_frag = 0; /* Invalidate last fragment counter of the object */ +#if FF_FS_RPATH != 0 + if (fs->fs_type == FS_EXFAT && dp->obj.sclust) { /* exFAT: Retrieve the sub-directory's status */ + DIR dj; + + dp->obj.c_scl = fs->cdc_scl; + dp->obj.c_size = fs->cdc_size; + dp->obj.c_ofs = fs->cdc_ofs; + res = load_obj_xdir(&dj, &dp->obj); + if (res != FR_OK) return res; + dp->obj.objsize = ld_dword(fs->dirbuf + XDIR_FileSize); + dp->obj.stat = fs->dirbuf[XDIR_GenFlags] & 2; + } +#endif +#endif + + if ((UINT)*path < ' ') { /* Null path name is the origin directory itself */ + dp->fn[NSFLAG] = NS_NONAME; + res = dir_sdi(dp, 0); + + } else { /* Follow path */ + for (;;) { + res = create_name(dp, &path); /* Get a segment name of the path */ + if (res != FR_OK) break; + res = dir_find(dp); /* Find an object with the segment name */ + ns = dp->fn[NSFLAG]; + if (res != FR_OK) { /* Failed to find the object */ + if (res == FR_NO_FILE) { /* Object is not found */ + if (FF_FS_RPATH && (ns & NS_DOT)) { /* If dot entry is not exist, stay there */ + if (!(ns & NS_LAST)) continue; /* Continue to follow if not last segment */ + dp->fn[NSFLAG] = NS_NONAME; + res = FR_OK; + } else { /* Could not find the object */ + if (!(ns & NS_LAST)) res = FR_NO_PATH; /* Adjust error code if not last segment */ + } + } + break; + } + if (ns & NS_LAST) break; /* Last segment matched. Function completed. */ + /* Get into the sub-directory */ + if (!(dp->obj.attr & AM_DIR)) { /* It is not a sub-directory and cannot follow */ + res = FR_NO_PATH; break; + } +#if FF_FS_EXFAT + if (fs->fs_type == FS_EXFAT) { /* Save containing directory information for next dir */ + dp->obj.c_scl = dp->obj.sclust; + dp->obj.c_size = ((DWORD)dp->obj.objsize & 0xFFFFFF00) | dp->obj.stat; + dp->obj.c_ofs = dp->blk_ofs; + init_alloc_info(fs, &dp->obj); /* Open next directory */ + } else +#endif + { + dp->obj.sclust = ld_clust(fs, fs->win + dp->dptr % SS(fs)); /* Open next directory */ + } + } + } + + return res; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Get logical drive number from path name */ +/*-----------------------------------------------------------------------*/ + +static int get_ldnumber ( /* Returns logical drive number (-1:invalid drive number or null pointer) */ + const TCHAR** path /* Pointer to pointer to the path name */ +) +{ + const TCHAR *tp, *tt; + TCHAR tc; + int i; + int vol = -1; +#if FF_STR_VOLUME_ID /* Find string volume ID */ + const char *sp; + char c; +#endif + + tt = tp = *path; + if (!tp) return vol; /* Invalid path name? */ + do tc = *tt++; while (!IsTerminator(tc) && tc != ':'); /* Find a colon in the path */ + + if (tc == ':') { /* DOS/Windows style volume ID? */ + i = FF_VOLUMES; + if (IsDigit(*tp) && tp + 2 == tt) { /* Is there a numeric volume ID + colon? */ + i = (int)*tp - '0'; /* Get the LD number */ + } +#if FF_STR_VOLUME_ID == 1 /* Arbitrary string is enabled */ + else { + i = 0; + do { + sp = VolumeStr[i]; tp = *path; /* This string volume ID and path name */ + do { /* Compare the volume ID with path name */ + c = *sp++; tc = *tp++; + if (IsLower(c)) c -= 0x20; + if (IsLower(tc)) tc -= 0x20; + } while (c && (TCHAR)c == tc); + } while ((c || tp != tt) && ++i < FF_VOLUMES); /* Repeat for each id until pattern match */ + } +#endif + if (i < FF_VOLUMES) { /* If a volume ID is found, get the drive number and strip it */ + vol = i; /* Drive number */ + *path = tt; /* Snip the drive prefix off */ + } + return vol; + } +#if FF_STR_VOLUME_ID == 2 /* Unix style volume ID is enabled */ + if (*tp == '/') { /* Is there a volume ID? */ + while (*(tp + 1) == '/') tp++; /* Skip duplicated separator */ + i = 0; + do { + tt = tp; sp = VolumeStr[i]; /* Path name and this string volume ID */ + do { /* Compare the volume ID with path name */ + c = *sp++; tc = *(++tt); + if (IsLower(c)) c -= 0x20; + if (IsLower(tc)) tc -= 0x20; + } while (c && (TCHAR)c == tc); + } while ((c || (tc != '/' && !IsTerminator(tc))) && ++i < FF_VOLUMES); /* Repeat for each ID until pattern match */ + if (i < FF_VOLUMES) { /* If a volume ID is found, get the drive number and strip it */ + vol = i; /* Drive number */ + *path = tt; /* Snip the drive prefix off */ + } + return vol; + } +#endif + /* No drive prefix is found */ +#if FF_FS_RPATH != 0 + vol = CurrVol; /* Default drive is current drive */ +#else + vol = 0; /* Default drive is 0 */ +#endif + return vol; /* Return the default drive */ +} + + + + +/*-----------------------------------------------------------------------*/ +/* GPT support functions */ +/*-----------------------------------------------------------------------*/ + +#if FF_LBA64 + +/* Calculate CRC32 in byte-by-byte */ + +static DWORD crc32 ( /* Returns next CRC value */ + DWORD crc, /* Current CRC value */ + BYTE d /* A byte to be processed */ +) +{ + BYTE b; + + + for (b = 1; b; b <<= 1) { + crc ^= (d & b) ? 1 : 0; + crc = (crc & 1) ? crc >> 1 ^ 0xEDB88320 : crc >> 1; + } + return crc; +} + + +/* Check validity of GPT header */ + +static int test_gpt_header ( /* 0:Invalid, 1:Valid */ + const BYTE* gpth /* Pointer to the GPT header */ +) +{ + UINT i; + DWORD bcc; + + + if (memcmp(gpth + GPTH_Sign, "EFI PART" "\0\0\1\0" "\x5C\0\0", 16)) return 0; /* Check sign, version (1.0) and length (92) */ + for (i = 0, bcc = 0xFFFFFFFF; i < 92; i++) { /* Check header BCC */ + bcc = crc32(bcc, i - GPTH_Bcc < 4 ? 0 : gpth[i]); + } + if (~bcc != ld_dword(gpth + GPTH_Bcc)) return 0; + if (ld_dword(gpth + GPTH_PteSize) != SZ_GPTE) return 0; /* Table entry size (must be SZ_GPTE bytes) */ + if (ld_dword(gpth + GPTH_PtNum) > 128) return 0; /* Table size (must be 128 entries or less) */ + + return 1; +} + +#if !FF_FS_READONLY && FF_USE_MKFS + +/* Generate random value */ +static DWORD make_rand ( + DWORD seed, /* Seed value */ + BYTE* buff, /* Output buffer */ + UINT n /* Data length */ +) +{ + UINT r; + + + if (seed == 0) seed = 1; + do { + for (r = 0; r < 8; r++) seed = seed & 1 ? seed >> 1 ^ 0xA3000000 : seed >> 1; /* Shift 8 bits the 32-bit LFSR */ + *buff++ = (BYTE)seed; + } while (--n); + return seed; +} + +#endif +#endif + + + +/*-----------------------------------------------------------------------*/ +/* Load a sector and check if it is an FAT VBR */ +/*-----------------------------------------------------------------------*/ + +/* Check what the sector is */ + +static UINT check_fs ( /* 0:FAT/FAT32 VBR, 1:exFAT VBR, 2:Not FAT and valid BS, 3:Not FAT and invalid BS, 4:Disk error */ + FATFS* fs, /* Filesystem object */ + LBA_t sect /* Sector to load and check if it is an FAT-VBR or not */ +) +{ + WORD w, sign; + BYTE b; + + + fs->wflag = 0; fs->winsect = (LBA_t)0 - 1; /* Invaidate window */ + if (move_window(fs, sect) != FR_OK) return 4; /* Load the boot sector */ + sign = ld_word(fs->win + BS_55AA); +#if FF_FS_EXFAT + if (sign == 0xAA55 && !memcmp(fs->win + BS_JmpBoot, "\xEB\x76\x90" "EXFAT ", 11)) return 1; /* It is an exFAT VBR */ +#endif + b = fs->win[BS_JmpBoot]; + if (b == 0xEB || b == 0xE9 || b == 0xE8) { /* Valid JumpBoot code? (short jump, near jump or near call) */ + if (sign == 0xAA55 && !memcmp(fs->win + BS_FilSysType32, "FAT32 ", 8)) { + return 0; /* It is an FAT32 VBR */ + } + /* FAT volumes formatted with early MS-DOS lack BS_55AA and BS_FilSysType, so FAT VBR needs to be identified without them. */ + w = ld_word(fs->win + BPB_BytsPerSec); + b = fs->win[BPB_SecPerClus]; + if ((w & (w - 1)) == 0 && w >= FF_MIN_SS && w <= FF_MAX_SS /* Properness of sector size (512-4096 and 2^n) */ + && b != 0 && (b & (b - 1)) == 0 /* Properness of cluster size (2^n) */ + && ld_word(fs->win + BPB_RsvdSecCnt) != 0 /* Properness of reserved sectors (MNBZ) */ + && (UINT)fs->win[BPB_NumFATs] - 1 <= 1 /* Properness of FATs (1 or 2) */ + && ld_word(fs->win + BPB_RootEntCnt) != 0 /* Properness of root dir entries (MNBZ) */ + && (ld_word(fs->win + BPB_TotSec16) >= 128 || ld_dword(fs->win + BPB_TotSec32) >= 0x10000) /* Properness of volume sectors (>=128) */ + && ld_word(fs->win + BPB_FATSz16) != 0) { /* Properness of FAT size (MNBZ) */ + return 0; /* It can be presumed an FAT VBR */ + } + } + return sign == 0xAA55 ? 2 : 3; /* Not an FAT VBR (valid or invalid BS) */ +} + + +/* Find an FAT volume */ +/* (It supports only generic partitioning rules, MBR, GPT and SFD) */ + +static UINT find_volume ( /* Returns BS status found in the hosting drive */ + FATFS* fs, /* Filesystem object */ + UINT part /* Partition to fined = 0:auto, 1..:forced */ +) +{ + UINT fmt, i; + DWORD mbr_pt[4]; + + + fmt = check_fs(fs, 0); /* Load sector 0 and check if it is an FAT VBR as SFD format */ + if (fmt != 2 && (fmt >= 3 || part == 0)) return fmt; /* Returns if it is an FAT VBR as auto scan, not a BS or disk error */ + + /* Sector 0 is not an FAT VBR or forced partition number wants a partition */ + +#if FF_LBA64 + if (fs->win[MBR_Table + PTE_System] == 0xEE) { /* GPT protective MBR? */ + DWORD n_ent, v_ent, ofs; + QWORD pt_lba; + + if (move_window(fs, 1) != FR_OK) return 4; /* Load GPT header sector (next to MBR) */ + if (!test_gpt_header(fs->win)) return 3; /* Check if GPT header is valid */ + n_ent = ld_dword(fs->win + GPTH_PtNum); /* Number of entries */ + pt_lba = ld_qword(fs->win + GPTH_PtOfs); /* Table location */ + for (v_ent = i = 0; i < n_ent; i++) { /* Find FAT partition */ + if (move_window(fs, pt_lba + i * SZ_GPTE / SS(fs)) != FR_OK) return 4; /* PT sector */ + ofs = i * SZ_GPTE % SS(fs); /* Offset in the sector */ + if (!memcmp(fs->win + ofs + GPTE_PtGuid, GUID_MS_Basic, 16)) { /* MS basic data partition? */ + v_ent++; + fmt = check_fs(fs, ld_qword(fs->win + ofs + GPTE_FstLba)); /* Load VBR and check status */ + if (part == 0 && fmt <= 1) return fmt; /* Auto search (valid FAT volume found first) */ + if (part != 0 && v_ent == part) return fmt; /* Forced partition order (regardless of it is valid or not) */ + } + } + return 3; /* Not found */ + } +#endif + if (FF_MULTI_PARTITION && part > 4) return 3; /* MBR has 4 partitions max */ + for (i = 0; i < 4; i++) { /* Load partition offset in the MBR */ + mbr_pt[i] = ld_dword(fs->win + MBR_Table + i * SZ_PTE + PTE_StLba); + } + i = part ? part - 1 : 0; /* Table index to find first */ + do { /* Find an FAT volume */ + fmt = mbr_pt[i] ? check_fs(fs, mbr_pt[i]) : 3; /* Check if the partition is FAT */ + } while (part == 0 && fmt >= 2 && ++i < 4); + return fmt; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Determine logical drive number and mount the volume if needed */ +/*-----------------------------------------------------------------------*/ + +static FRESULT mount_volume ( /* FR_OK(0): successful, !=0: an error occurred */ + const TCHAR** path, /* Pointer to pointer to the path name (drive number) */ + FATFS** rfs, /* Pointer to pointer to the found filesystem object */ + BYTE mode /* !=0: Check write protection for write access */ +) +{ + int vol; + DSTATUS stat; + LBA_t bsect; + DWORD tsect, sysect, fasize, nclst, szbfat; + WORD nrsv; + FATFS *fs; + UINT fmt; + + + /* Get logical drive number */ + *rfs = 0; + vol = get_ldnumber(path); + if (vol < 0) return FR_INVALID_DRIVE; + + /* Check if the filesystem object is valid or not */ + fs = FatFs[vol]; /* Get pointer to the filesystem object */ + if (!fs) return FR_NOT_ENABLED; /* Is the filesystem object available? */ +#if FF_FS_REENTRANT + if (!lock_fs(fs)) return FR_TIMEOUT; /* Lock the volume */ +#endif + *rfs = fs; /* Return pointer to the filesystem object */ + + mode &= (BYTE)~FA_READ; /* Desired access mode, write access or not */ + if (fs->fs_type != 0) { /* If the volume has been mounted */ + stat = disk_status(fs->pdrv); + if (!(stat & STA_NOINIT)) { /* and the physical drive is kept initialized */ + if (!FF_FS_READONLY && mode && (stat & STA_PROTECT)) { /* Check write protection if needed */ + return FR_WRITE_PROTECTED; + } + return FR_OK; /* The filesystem object is already valid */ + } + } + + /* The filesystem object is not valid. */ + /* Following code attempts to mount the volume. (find an FAT volume, analyze the BPB and initialize the filesystem object) */ + + fs->fs_type = 0; /* Clear the filesystem object */ + fs->pdrv = LD2PD(vol); /* Volume hosting physical drive */ + stat = disk_initialize(fs->pdrv); /* Initialize the physical drive */ + if (stat & STA_NOINIT) { /* Check if the initialization succeeded */ + return FR_NOT_READY; /* Failed to initialize due to no medium or hard error */ + } + if (!FF_FS_READONLY && mode && (stat & STA_PROTECT)) { /* Check disk write protection if needed */ + return FR_WRITE_PROTECTED; + } +#if FF_MAX_SS != FF_MIN_SS /* Get sector size (multiple sector size cfg only) */ + if (disk_ioctl(fs->pdrv, GET_SECTOR_SIZE, &SS(fs)) != RES_OK) return FR_DISK_ERR; + if (SS(fs) > FF_MAX_SS || SS(fs) < FF_MIN_SS || (SS(fs) & (SS(fs) - 1))) return FR_DISK_ERR; +#endif + + /* Find an FAT volume on the drive */ + fmt = find_volume(fs, LD2PT(vol)); + if (fmt == 4) return FR_DISK_ERR; /* An error occured in the disk I/O layer */ + if (fmt >= 2) return FR_NO_FILESYSTEM; /* No FAT volume is found */ + bsect = fs->winsect; /* Volume offset */ + + /* An FAT volume is found (bsect). Following code initializes the filesystem object */ + +#if FF_FS_EXFAT + if (fmt == 1) { + QWORD maxlba; + DWORD so, cv, bcl, i; + + for (i = BPB_ZeroedEx; i < BPB_ZeroedEx + 53 && fs->win[i] == 0; i++) ; /* Check zero filler */ + if (i < BPB_ZeroedEx + 53) return FR_NO_FILESYSTEM; + + if (ld_word(fs->win + BPB_FSVerEx) != 0x100) return FR_NO_FILESYSTEM; /* Check exFAT version (must be version 1.0) */ + + if (1 << fs->win[BPB_BytsPerSecEx] != SS(fs)) { /* (BPB_BytsPerSecEx must be equal to the physical sector size) */ + return FR_NO_FILESYSTEM; + } + + maxlba = ld_qword(fs->win + BPB_TotSecEx) + bsect; /* Last LBA of the volume + 1 */ + if (!FF_LBA64 && maxlba >= 0x100000000) return FR_NO_FILESYSTEM; /* (It cannot be accessed in 32-bit LBA) */ + + fs->fsize = ld_dword(fs->win + BPB_FatSzEx); /* Number of sectors per FAT */ + + fs->n_fats = fs->win[BPB_NumFATsEx]; /* Number of FATs */ + if (fs->n_fats != 1) return FR_NO_FILESYSTEM; /* (Supports only 1 FAT) */ + + fs->csize = 1 << fs->win[BPB_SecPerClusEx]; /* Cluster size */ + if (fs->csize == 0) return FR_NO_FILESYSTEM; /* (Must be 1..32768 sectors) */ + + nclst = ld_dword(fs->win + BPB_NumClusEx); /* Number of clusters */ + if (nclst > MAX_EXFAT) return FR_NO_FILESYSTEM; /* (Too many clusters) */ + fs->n_fatent = nclst + 2; + + /* Boundaries and Limits */ + fs->volbase = bsect; + fs->database = bsect + ld_dword(fs->win + BPB_DataOfsEx); + fs->fatbase = bsect + ld_dword(fs->win + BPB_FatOfsEx); + if (maxlba < (QWORD)fs->database + nclst * fs->csize) return FR_NO_FILESYSTEM; /* (Volume size must not be smaller than the size requiered) */ + fs->dirbase = ld_dword(fs->win + BPB_RootClusEx); + + /* Get bitmap location and check if it is contiguous (implementation assumption) */ + so = i = 0; + for (;;) { /* Find the bitmap entry in the root directory (in only first cluster) */ + if (i == 0) { + if (so >= fs->csize) return FR_NO_FILESYSTEM; /* Not found? */ + if (move_window(fs, clst2sect(fs, (DWORD)fs->dirbase) + so) != FR_OK) return FR_DISK_ERR; + so++; + } + if (fs->win[i] == ET_BITMAP) break; /* Is it a bitmap entry? */ + i = (i + SZDIRE) % SS(fs); /* Next entry */ + } + bcl = ld_dword(fs->win + i + 20); /* Bitmap cluster */ + if (bcl < 2 || bcl >= fs->n_fatent) return FR_NO_FILESYSTEM; /* (Wrong cluster#) */ + fs->bitbase = fs->database + fs->csize * (bcl - 2); /* Bitmap sector */ + for (;;) { /* Check if bitmap is contiguous */ + if (move_window(fs, fs->fatbase + bcl / (SS(fs) / 4)) != FR_OK) return FR_DISK_ERR; + cv = ld_dword(fs->win + bcl % (SS(fs) / 4) * 4); + if (cv == 0xFFFFFFFF) break; /* Last link? */ + if (cv != ++bcl) return FR_NO_FILESYSTEM; /* Fragmented? */ + } + +#if !FF_FS_READONLY + fs->last_clst = fs->free_clst = 0xFFFFFFFF; /* Initialize cluster allocation information */ +#endif + fmt = FS_EXFAT; /* FAT sub-type */ + } else +#endif /* FF_FS_EXFAT */ + { + if (ld_word(fs->win + BPB_BytsPerSec) != SS(fs)) return FR_NO_FILESYSTEM; /* (BPB_BytsPerSec must be equal to the physical sector size) */ + + fasize = ld_word(fs->win + BPB_FATSz16); /* Number of sectors per FAT */ + if (fasize == 0) fasize = ld_dword(fs->win + BPB_FATSz32); + fs->fsize = fasize; + + fs->n_fats = fs->win[BPB_NumFATs]; /* Number of FATs */ + if (fs->n_fats != 1 && fs->n_fats != 2) return FR_NO_FILESYSTEM; /* (Must be 1 or 2) */ + fasize *= fs->n_fats; /* Number of sectors for FAT area */ + + fs->csize = fs->win[BPB_SecPerClus]; /* Cluster size */ + if (fs->csize == 0 || (fs->csize & (fs->csize - 1))) return FR_NO_FILESYSTEM; /* (Must be power of 2) */ + + fs->n_rootdir = ld_word(fs->win + BPB_RootEntCnt); /* Number of root directory entries */ + if (fs->n_rootdir % (SS(fs) / SZDIRE)) return FR_NO_FILESYSTEM; /* (Must be sector aligned) */ + + tsect = ld_word(fs->win + BPB_TotSec16); /* Number of sectors on the volume */ + if (tsect == 0) tsect = ld_dword(fs->win + BPB_TotSec32); + + nrsv = ld_word(fs->win + BPB_RsvdSecCnt); /* Number of reserved sectors */ + if (nrsv == 0) return FR_NO_FILESYSTEM; /* (Must not be 0) */ + + /* Determine the FAT sub type */ + sysect = nrsv + fasize + fs->n_rootdir / (SS(fs) / SZDIRE); /* RSV + FAT + DIR */ + if (tsect < sysect) return FR_NO_FILESYSTEM; /* (Invalid volume size) */ + nclst = (tsect - sysect) / fs->csize; /* Number of clusters */ + if (nclst == 0) return FR_NO_FILESYSTEM; /* (Invalid volume size) */ + fmt = 0; + if (nclst <= MAX_FAT32) fmt = FS_FAT32; + if (nclst <= MAX_FAT16) fmt = FS_FAT16; + if (nclst <= MAX_FAT12) fmt = FS_FAT12; + if (fmt == 0) return FR_NO_FILESYSTEM; + + /* Boundaries and Limits */ + fs->n_fatent = nclst + 2; /* Number of FAT entries */ + fs->volbase = bsect; /* Volume start sector */ + fs->fatbase = bsect + nrsv; /* FAT start sector */ + fs->database = bsect + sysect; /* Data start sector */ + if (fmt == FS_FAT32) { + if (ld_word(fs->win + BPB_FSVer32) != 0) return FR_NO_FILESYSTEM; /* (Must be FAT32 revision 0.0) */ + if (fs->n_rootdir != 0) return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must be 0) */ + fs->dirbase = ld_dword(fs->win + BPB_RootClus32); /* Root directory start cluster */ + szbfat = fs->n_fatent * 4; /* (Needed FAT size) */ + } else { + if (fs->n_rootdir == 0) return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must not be 0) */ + fs->dirbase = fs->fatbase + fasize; /* Root directory start sector */ + szbfat = (fmt == FS_FAT16) ? /* (Needed FAT size) */ + fs->n_fatent * 2 : fs->n_fatent * 3 / 2 + (fs->n_fatent & 1); + } + if (fs->fsize < (szbfat + (SS(fs) - 1)) / SS(fs)) return FR_NO_FILESYSTEM; /* (BPB_FATSz must not be less than the size needed) */ + +#if !FF_FS_READONLY + /* Get FSInfo if available */ + fs->last_clst = fs->free_clst = 0xFFFFFFFF; /* Initialize cluster allocation information */ + fs->fsi_flag = 0x80; +#if (FF_FS_NOFSINFO & 3) != 3 + if (fmt == FS_FAT32 /* Allow to update FSInfo only if BPB_FSInfo32 == 1 */ + && ld_word(fs->win + BPB_FSInfo32) == 1 + && move_window(fs, bsect + 1) == FR_OK) + { + fs->fsi_flag = 0; + if (ld_word(fs->win + BS_55AA) == 0xAA55 /* Load FSInfo data if available */ + && ld_dword(fs->win + FSI_LeadSig) == 0x41615252 + && ld_dword(fs->win + FSI_StrucSig) == 0x61417272) + { +#if (FF_FS_NOFSINFO & 1) == 0 + fs->free_clst = ld_dword(fs->win + FSI_Free_Count); +#endif +#if (FF_FS_NOFSINFO & 2) == 0 + fs->last_clst = ld_dword(fs->win + FSI_Nxt_Free); +#endif + } + } +#endif /* (FF_FS_NOFSINFO & 3) != 3 */ +#endif /* !FF_FS_READONLY */ + } + + fs->fs_type = (BYTE)fmt;/* FAT sub-type */ + fs->id = ++Fsid; /* Volume mount ID */ +#if FF_USE_LFN == 1 + fs->lfnbuf = LfnBuf; /* Static LFN working buffer */ +#if FF_FS_EXFAT + fs->dirbuf = DirBuf; /* Static directory block scratchpad buuffer */ +#endif +#endif +#if FF_FS_RPATH != 0 + fs->cdir = 0; /* Initialize current directory */ +#endif +#if FF_FS_LOCK != 0 /* Clear file lock semaphores */ + clear_lock(fs); +#endif + return FR_OK; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Check if the file/directory object is valid or not */ +/*-----------------------------------------------------------------------*/ + +static FRESULT validate ( /* Returns FR_OK or FR_INVALID_OBJECT */ + FFOBJID* obj, /* Pointer to the FFOBJID, the 1st member in the FIL/DIR object, to check validity */ + FATFS** rfs /* Pointer to pointer to the owner filesystem object to return */ +) +{ + FRESULT res = FR_INVALID_OBJECT; + + + if (obj && obj->fs && obj->fs->fs_type && obj->id == obj->fs->id) { /* Test if the object is valid */ +#if FF_FS_REENTRANT + if (lock_fs(obj->fs)) { /* Obtain the filesystem object */ + if (!(disk_status(obj->fs->pdrv) & STA_NOINIT)) { /* Test if the phsical drive is kept initialized */ + res = FR_OK; + } else { + unlock_fs(obj->fs, FR_OK); + } + } else { + res = FR_TIMEOUT; + } +#else + if (!(disk_status(obj->fs->pdrv) & STA_NOINIT)) { /* Test if the phsical drive is kept initialized */ + res = FR_OK; + } +#endif + } + *rfs = (res == FR_OK) ? obj->fs : 0; /* Corresponding filesystem object */ + return res; +} + + + + +/*--------------------------------------------------------------------------- + + Public Functions (FatFs API) + +----------------------------------------------------------------------------*/ + + + +/*-----------------------------------------------------------------------*/ +/* Mount/Unmount a Logical Drive */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_mount ( + FATFS* fs, /* Pointer to the filesystem object to be registered (NULL:unmount)*/ + const TCHAR* path, /* Logical drive number to be mounted/unmounted */ + BYTE opt /* Mount option: 0=Do not mount (delayed mount), 1=Mount immediately */ +) +{ + FATFS *cfs; + int vol; + FRESULT res; + const TCHAR *rp = path; + + + /* Get logical drive number */ + vol = get_ldnumber(&rp); + if (vol < 0) return FR_INVALID_DRIVE; + cfs = FatFs[vol]; /* Pointer to fs object */ + + if (cfs) { +#if FF_FS_LOCK != 0 + clear_lock(cfs); +#endif +#if FF_FS_REENTRANT /* Discard sync object of the current volume */ + if (!ff_del_syncobj(cfs->sobj)) return FR_INT_ERR; +#endif + cfs->fs_type = 0; /* Clear old fs object */ + } + + if (fs) { + fs->fs_type = 0; /* Clear new fs object */ +#if FF_FS_REENTRANT /* Create sync object for the new volume */ + if (!ff_cre_syncobj((BYTE)vol, &fs->sobj)) return FR_INT_ERR; +#endif + } + FatFs[vol] = fs; /* Register new fs object */ + + if (opt == 0) return FR_OK; /* Do not mount now, it will be mounted later */ + + res = mount_volume(&path, &fs, 0); /* Force mounted the volume */ + LEAVE_FF(fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Open or Create a File */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_open ( + FIL* fp, /* Pointer to the blank file object */ + const TCHAR* path, /* Pointer to the file name */ + BYTE mode /* Access mode and open mode flags */ +) +{ + FRESULT res; + DIR dj; + FATFS *fs; +#if !FF_FS_READONLY + DWORD cl, bcs, clst, tm; + LBA_t sc; + FSIZE_t ofs; +#endif + DEF_NAMBUF + + + if (!fp) return FR_INVALID_OBJECT; + + /* Get logical drive number */ + mode &= FF_FS_READONLY ? FA_READ : FA_READ | FA_WRITE | FA_CREATE_ALWAYS | FA_CREATE_NEW | FA_OPEN_ALWAYS | FA_OPEN_APPEND; + res = mount_volume(&path, &fs, mode); + if (res == FR_OK) { + dj.obj.fs = fs; + INIT_NAMBUF(fs); + res = follow_path(&dj, path); /* Follow the file path */ +#if !FF_FS_READONLY /* Read/Write configuration */ + if (res == FR_OK) { + if (dj.fn[NSFLAG] & NS_NONAME) { /* Origin directory itself? */ + res = FR_INVALID_NAME; + } +#if FF_FS_LOCK != 0 + else { + res = chk_lock(&dj, (mode & ~FA_READ) ? 1 : 0); /* Check if the file can be used */ + } +#endif + } + /* Create or Open a file */ + if (mode & (FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW)) { + if (res != FR_OK) { /* No file, create new */ + if (res == FR_NO_FILE) { /* There is no file to open, create a new entry */ +#if FF_FS_LOCK != 0 + res = enq_lock() ? dir_register(&dj) : FR_TOO_MANY_OPEN_FILES; +#else + res = dir_register(&dj); +#endif + } + mode |= FA_CREATE_ALWAYS; /* File is created */ + } + else { /* Any object with the same name is already existing */ + if (dj.obj.attr & (AM_RDO | AM_DIR)) { /* Cannot overwrite it (R/O or DIR) */ + res = FR_DENIED; + } else { + if (mode & FA_CREATE_NEW) res = FR_EXIST; /* Cannot create as new file */ + } + } + if (res == FR_OK && (mode & FA_CREATE_ALWAYS)) { /* Truncate the file if overwrite mode */ +#if FF_FS_EXFAT + if (fs->fs_type == FS_EXFAT) { + /* Get current allocation info */ + fp->obj.fs = fs; + init_alloc_info(fs, &fp->obj); + /* Set directory entry block initial state */ + memset(fs->dirbuf + 2, 0, 30); /* Clear 85 entry except for NumSec */ + memset(fs->dirbuf + 38, 0, 26); /* Clear C0 entry except for NumName and NameHash */ + fs->dirbuf[XDIR_Attr] = AM_ARC; + st_dword(fs->dirbuf + XDIR_CrtTime, GET_FATTIME()); + fs->dirbuf[XDIR_GenFlags] = 1; + res = store_xdir(&dj); + if (res == FR_OK && fp->obj.sclust != 0) { /* Remove the cluster chain if exist */ + res = remove_chain(&fp->obj, fp->obj.sclust, 0); + fs->last_clst = fp->obj.sclust - 1; /* Reuse the cluster hole */ + } + } else +#endif + { + /* Set directory entry initial state */ + tm = GET_FATTIME(); /* Set created time */ + st_dword(dj.dir + DIR_CrtTime, tm); + st_dword(dj.dir + DIR_ModTime, tm); + cl = ld_clust(fs, dj.dir); /* Get current cluster chain */ + dj.dir[DIR_Attr] = AM_ARC; /* Reset attribute */ + st_clust(fs, dj.dir, 0); /* Reset file allocation info */ + st_dword(dj.dir + DIR_FileSize, 0); + fs->wflag = 1; + if (cl != 0) { /* Remove the cluster chain if exist */ + sc = fs->winsect; + res = remove_chain(&dj.obj, cl, 0); + if (res == FR_OK) { + res = move_window(fs, sc); + fs->last_clst = cl - 1; /* Reuse the cluster hole */ + } + } + } + } + } + else { /* Open an existing file */ + if (res == FR_OK) { /* Is the object exsiting? */ + if (dj.obj.attr & AM_DIR) { /* File open against a directory */ + res = FR_NO_FILE; + } else { + if ((mode & FA_WRITE) && (dj.obj.attr & AM_RDO)) { /* Write mode open against R/O file */ + res = FR_DENIED; + } + } + } + } + if (res == FR_OK) { + if (mode & FA_CREATE_ALWAYS) mode |= FA_MODIFIED; /* Set file change flag if created or overwritten */ + fp->dir_sect = fs->winsect; /* Pointer to the directory entry */ + fp->dir_ptr = dj.dir; +#if FF_FS_LOCK != 0 + fp->obj.lockid = inc_lock(&dj, (mode & ~FA_READ) ? 1 : 0); /* Lock the file for this session */ + if (fp->obj.lockid == 0) res = FR_INT_ERR; +#endif + } +#else /* R/O configuration */ + if (res == FR_OK) { + if (dj.fn[NSFLAG] & NS_NONAME) { /* Is it origin directory itself? */ + res = FR_INVALID_NAME; + } else { + if (dj.obj.attr & AM_DIR) { /* Is it a directory? */ + res = FR_NO_FILE; + } + } + } +#endif + + if (res == FR_OK) { +#if FF_FS_EXFAT + if (fs->fs_type == FS_EXFAT) { + fp->obj.c_scl = dj.obj.sclust; /* Get containing directory info */ + fp->obj.c_size = ((DWORD)dj.obj.objsize & 0xFFFFFF00) | dj.obj.stat; + fp->obj.c_ofs = dj.blk_ofs; + init_alloc_info(fs, &fp->obj); + } else +#endif + { + fp->obj.sclust = ld_clust(fs, dj.dir); /* Get object allocation info */ + fp->obj.objsize = ld_dword(dj.dir + DIR_FileSize); + } +#if FF_USE_FASTSEEK + fp->cltbl = 0; /* Disable fast seek mode */ +#endif + fp->obj.fs = fs; /* Validate the file object */ + fp->obj.id = fs->id; + fp->flag = mode; /* Set file access mode */ + fp->err = 0; /* Clear error flag */ + fp->sect = 0; /* Invalidate current data sector */ + fp->fptr = 0; /* Set file pointer top of the file */ +#if !FF_FS_READONLY +#if !FF_FS_TINY + memset(fp->buf, 0, sizeof fp->buf); /* Clear sector buffer */ +#endif + if ((mode & FA_SEEKEND) && fp->obj.objsize > 0) { /* Seek to end of file if FA_OPEN_APPEND is specified */ + fp->fptr = fp->obj.objsize; /* Offset to seek */ + bcs = (DWORD)fs->csize * SS(fs); /* Cluster size in byte */ + clst = fp->obj.sclust; /* Follow the cluster chain */ + for (ofs = fp->obj.objsize; res == FR_OK && ofs > bcs; ofs -= bcs) { + clst = get_fat(&fp->obj, clst); + if (clst <= 1) res = FR_INT_ERR; + if (clst == 0xFFFFFFFF) res = FR_DISK_ERR; + } + fp->clust = clst; + if (res == FR_OK && ofs % SS(fs)) { /* Fill sector buffer if not on the sector boundary */ + sc = clst2sect(fs, clst); + if (sc == 0) { + res = FR_INT_ERR; + } else { + fp->sect = sc + (DWORD)(ofs / SS(fs)); +#if !FF_FS_TINY + if (disk_read(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) res = FR_DISK_ERR; +#endif + } + } +#if FF_FS_LOCK != 0 + if (res != FR_OK) dec_lock(fp->obj.lockid); /* Decrement file open counter if seek failed */ +#endif + } +#endif + } + + FREE_NAMBUF(); + } + + if (res != FR_OK) fp->obj.fs = 0; /* Invalidate file object on error */ + + LEAVE_FF(fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Read File */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_read ( + FIL* fp, /* Open file to be read */ + void* buff, /* Data buffer to store the read data */ + UINT btr, /* Number of bytes to read */ + UINT* br /* Number of bytes read */ +) +{ + FRESULT res; + FATFS *fs; + DWORD clst; + LBA_t sect; + FSIZE_t remain; + UINT rcnt, cc, csect; + BYTE *rbuff = (BYTE*)buff; + + + *br = 0; /* Clear read byte counter */ + res = validate(&fp->obj, &fs); /* Check validity of the file object */ + if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) LEAVE_FF(fs, res); /* Check validity */ + if (!(fp->flag & FA_READ)) LEAVE_FF(fs, FR_DENIED); /* Check access mode */ + remain = fp->obj.objsize - fp->fptr; + if (btr > remain) btr = (UINT)remain; /* Truncate btr by remaining bytes */ + + for ( ; btr > 0; btr -= rcnt, *br += rcnt, rbuff += rcnt, fp->fptr += rcnt) { /* Repeat until btr bytes read */ + if (fp->fptr % SS(fs) == 0) { /* On the sector boundary? */ + csect = (UINT)(fp->fptr / SS(fs) & (fs->csize - 1)); /* Sector offset in the cluster */ + if (csect == 0) { /* On the cluster boundary? */ + if (fp->fptr == 0) { /* On the top of the file? */ + clst = fp->obj.sclust; /* Follow cluster chain from the origin */ + } else { /* Middle or end of the file */ +#if FF_USE_FASTSEEK + if (fp->cltbl) { + clst = clmt_clust(fp, fp->fptr); /* Get cluster# from the CLMT */ + } else +#endif + { + clst = get_fat(&fp->obj, fp->clust); /* Follow cluster chain on the FAT */ + } + } + if (clst < 2) ABORT(fs, FR_INT_ERR); + if (clst == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR); + fp->clust = clst; /* Update current cluster */ + } + sect = clst2sect(fs, fp->clust); /* Get current sector */ + if (sect == 0) ABORT(fs, FR_INT_ERR); + sect += csect; + cc = btr / SS(fs); /* When remaining bytes >= sector size, */ + if (cc > 0) { /* Read maximum contiguous sectors directly */ + if (csect + cc > fs->csize) { /* Clip at cluster boundary */ + cc = fs->csize - csect; + } + if (disk_read(fs->pdrv, rbuff, sect, cc) != RES_OK) ABORT(fs, FR_DISK_ERR); +#if !FF_FS_READONLY && FF_FS_MINIMIZE <= 2 /* Replace one of the read sectors with cached data if it contains a dirty sector */ +#if FF_FS_TINY + if (fs->wflag && fs->winsect - sect < cc) { + memcpy(rbuff + ((fs->winsect - sect) * SS(fs)), fs->win, SS(fs)); + } +#else + if ((fp->flag & FA_DIRTY) && fp->sect - sect < cc) { + memcpy(rbuff + ((fp->sect - sect) * SS(fs)), fp->buf, SS(fs)); + } +#endif +#endif + rcnt = SS(fs) * cc; /* Number of bytes transferred */ + continue; + } +#if !FF_FS_TINY + if (fp->sect != sect) { /* Load data sector if not in cache */ +#if !FF_FS_READONLY + if (fp->flag & FA_DIRTY) { /* Write-back dirty sector cache */ + if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); + fp->flag &= (BYTE)~FA_DIRTY; + } +#endif + if (disk_read(fs->pdrv, fp->buf, sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); /* Fill sector cache */ + } +#endif + fp->sect = sect; + } + rcnt = SS(fs) - (UINT)fp->fptr % SS(fs); /* Number of bytes remains in the sector */ + if (rcnt > btr) rcnt = btr; /* Clip it by btr if needed */ +#if FF_FS_TINY + if (move_window(fs, fp->sect) != FR_OK) ABORT(fs, FR_DISK_ERR); /* Move sector window */ + memcpy(rbuff, fs->win + fp->fptr % SS(fs), rcnt); /* Extract partial sector */ +#else + memcpy(rbuff, fp->buf + fp->fptr % SS(fs), rcnt); /* Extract partial sector */ +#endif + } + + LEAVE_FF(fs, FR_OK); +} + + + + +#if !FF_FS_READONLY +/*-----------------------------------------------------------------------*/ +/* Write File */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_write ( + FIL* fp, /* Open file to be written */ + const void* buff, /* Data to be written */ + UINT btw, /* Number of bytes to write */ + UINT* bw /* Number of bytes written */ +) +{ + FRESULT res; + FATFS *fs; + DWORD clst; + LBA_t sect; + UINT wcnt, cc, csect; + BYTE *wbuff = (BYTE*)buff; + + + *bw = 0; /* Clear write byte counter */ + res = validate(&fp->obj, &fs); /* Check validity of the file object */ + if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) LEAVE_FF(fs, res); /* Check validity */ + if (!(fp->flag & FA_WRITE)) LEAVE_FF(fs, FR_DENIED); /* Check access mode */ + + /* Check fptr wrap-around (file size cannot reach 4 GiB at FAT volume) */ + if ((!FF_FS_EXFAT || fs->fs_type != FS_EXFAT) && (DWORD)(fp->fptr + btw) < (DWORD)fp->fptr) { + btw = (UINT)(0xFFFFFFFF - (DWORD)fp->fptr); + } + + for ( ; btw > 0; btw -= wcnt, *bw += wcnt, wbuff += wcnt, fp->fptr += wcnt, fp->obj.objsize = (fp->fptr > fp->obj.objsize) ? fp->fptr : fp->obj.objsize) { /* Repeat until all data written */ + if (fp->fptr % SS(fs) == 0) { /* On the sector boundary? */ + csect = (UINT)(fp->fptr / SS(fs)) & (fs->csize - 1); /* Sector offset in the cluster */ + if (csect == 0) { /* On the cluster boundary? */ + if (fp->fptr == 0) { /* On the top of the file? */ + clst = fp->obj.sclust; /* Follow from the origin */ + if (clst == 0) { /* If no cluster is allocated, */ + clst = create_chain(&fp->obj, 0); /* create a new cluster chain */ + } + } else { /* On the middle or end of the file */ +#if FF_USE_FASTSEEK + if (fp->cltbl) { + clst = clmt_clust(fp, fp->fptr); /* Get cluster# from the CLMT */ + } else +#endif + { + clst = create_chain(&fp->obj, fp->clust); /* Follow or stretch cluster chain on the FAT */ + } + } + if (clst == 0) break; /* Could not allocate a new cluster (disk full) */ + if (clst == 1) ABORT(fs, FR_INT_ERR); + if (clst == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR); + fp->clust = clst; /* Update current cluster */ + if (fp->obj.sclust == 0) fp->obj.sclust = clst; /* Set start cluster if the first write */ + } +#if FF_FS_TINY + if (fs->winsect == fp->sect && sync_window(fs) != FR_OK) ABORT(fs, FR_DISK_ERR); /* Write-back sector cache */ +#else + if (fp->flag & FA_DIRTY) { /* Write-back sector cache */ + if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); + fp->flag &= (BYTE)~FA_DIRTY; + } +#endif + sect = clst2sect(fs, fp->clust); /* Get current sector */ + if (sect == 0) ABORT(fs, FR_INT_ERR); + sect += csect; + cc = btw / SS(fs); /* When remaining bytes >= sector size, */ + if (cc > 0) { /* Write maximum contiguous sectors directly */ + if (csect + cc > fs->csize) { /* Clip at cluster boundary */ + cc = fs->csize - csect; + } + if (disk_write(fs->pdrv, wbuff, sect, cc) != RES_OK) ABORT(fs, FR_DISK_ERR); +#if FF_FS_MINIMIZE <= 2 +#if FF_FS_TINY + if (fs->winsect - sect < cc) { /* Refill sector cache if it gets invalidated by the direct write */ + memcpy(fs->win, wbuff + ((fs->winsect - sect) * SS(fs)), SS(fs)); + fs->wflag = 0; + } +#else + if (fp->sect - sect < cc) { /* Refill sector cache if it gets invalidated by the direct write */ + memcpy(fp->buf, wbuff + ((fp->sect - sect) * SS(fs)), SS(fs)); + fp->flag &= (BYTE)~FA_DIRTY; + } +#endif +#endif + wcnt = SS(fs) * cc; /* Number of bytes transferred */ + continue; + } +#if FF_FS_TINY + if (fp->fptr >= fp->obj.objsize) { /* Avoid silly cache filling on the growing edge */ + if (sync_window(fs) != FR_OK) ABORT(fs, FR_DISK_ERR); + fs->winsect = sect; + } +#else + if (fp->sect != sect && /* Fill sector cache with file data */ + fp->fptr < fp->obj.objsize && + disk_read(fs->pdrv, fp->buf, sect, 1) != RES_OK) { + ABORT(fs, FR_DISK_ERR); + } +#endif + fp->sect = sect; + } + wcnt = SS(fs) - (UINT)fp->fptr % SS(fs); /* Number of bytes remains in the sector */ + if (wcnt > btw) wcnt = btw; /* Clip it by btw if needed */ +#if FF_FS_TINY + if (move_window(fs, fp->sect) != FR_OK) ABORT(fs, FR_DISK_ERR); /* Move sector window */ + memcpy(fs->win + fp->fptr % SS(fs), wbuff, wcnt); /* Fit data to the sector */ + fs->wflag = 1; +#else + memcpy(fp->buf + fp->fptr % SS(fs), wbuff, wcnt); /* Fit data to the sector */ + fp->flag |= FA_DIRTY; +#endif + } + + fp->flag |= FA_MODIFIED; /* Set file change flag */ + + LEAVE_FF(fs, FR_OK); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Synchronize the File */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_sync ( + FIL* fp /* Open file to be synced */ +) +{ + FRESULT res; + FATFS *fs; + DWORD tm; + BYTE *dir; + + + res = validate(&fp->obj, &fs); /* Check validity of the file object */ + if (res == FR_OK) { + if (fp->flag & FA_MODIFIED) { /* Is there any change to the file? */ +#if !FF_FS_TINY + if (fp->flag & FA_DIRTY) { /* Write-back cached data if needed */ + if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) LEAVE_FF(fs, FR_DISK_ERR); + fp->flag &= (BYTE)~FA_DIRTY; + } +#endif + /* Update the directory entry */ + tm = GET_FATTIME(); /* Modified time */ +#if FF_FS_EXFAT + if (fs->fs_type == FS_EXFAT) { + res = fill_first_frag(&fp->obj); /* Fill first fragment on the FAT if needed */ + if (res == FR_OK) { + res = fill_last_frag(&fp->obj, fp->clust, 0xFFFFFFFF); /* Fill last fragment on the FAT if needed */ + } + if (res == FR_OK) { + DIR dj; + DEF_NAMBUF + + INIT_NAMBUF(fs); + res = load_obj_xdir(&dj, &fp->obj); /* Load directory entry block */ + if (res == FR_OK) { + fs->dirbuf[XDIR_Attr] |= AM_ARC; /* Set archive attribute to indicate that the file has been changed */ + fs->dirbuf[XDIR_GenFlags] = fp->obj.stat | 1; /* Update file allocation information */ + st_dword(fs->dirbuf + XDIR_FstClus, fp->obj.sclust); /* Update start cluster */ + st_qword(fs->dirbuf + XDIR_FileSize, fp->obj.objsize); /* Update file size */ + st_qword(fs->dirbuf + XDIR_ValidFileSize, fp->obj.objsize); /* (FatFs does not support Valid File Size feature) */ + st_dword(fs->dirbuf + XDIR_ModTime, tm); /* Update modified time */ + fs->dirbuf[XDIR_ModTime10] = 0; + st_dword(fs->dirbuf + XDIR_AccTime, 0); + res = store_xdir(&dj); /* Restore it to the directory */ + if (res == FR_OK) { + res = sync_fs(fs); + fp->flag &= (BYTE)~FA_MODIFIED; + } + } + FREE_NAMBUF(); + } + } else +#endif + { + res = move_window(fs, fp->dir_sect); + if (res == FR_OK) { + dir = fp->dir_ptr; + dir[DIR_Attr] |= AM_ARC; /* Set archive attribute to indicate that the file has been changed */ + st_clust(fp->obj.fs, dir, fp->obj.sclust); /* Update file allocation information */ + st_dword(dir + DIR_FileSize, (DWORD)fp->obj.objsize); /* Update file size */ + st_dword(dir + DIR_ModTime, tm); /* Update modified time */ + st_word(dir + DIR_LstAccDate, 0); + fs->wflag = 1; + res = sync_fs(fs); /* Restore it to the directory */ + fp->flag &= (BYTE)~FA_MODIFIED; + } + } + } + } + + LEAVE_FF(fs, res); +} + +#endif /* !FF_FS_READONLY */ + + + + +/*-----------------------------------------------------------------------*/ +/* Close File */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_close ( + FIL* fp /* Open file to be closed */ +) +{ + FRESULT res; + FATFS *fs; + +#if !FF_FS_READONLY + res = f_sync(fp); /* Flush cached data */ + if (res == FR_OK) +#endif + { + res = validate(&fp->obj, &fs); /* Lock volume */ + if (res == FR_OK) { +#if FF_FS_LOCK != 0 + res = dec_lock(fp->obj.lockid); /* Decrement file open counter */ + if (res == FR_OK) fp->obj.fs = 0; /* Invalidate file object */ +#else + fp->obj.fs = 0; /* Invalidate file object */ +#endif +#if FF_FS_REENTRANT + unlock_fs(fs, FR_OK); /* Unlock volume */ +#endif + } + } + return res; +} + + + + +#if FF_FS_RPATH >= 1 +/*-----------------------------------------------------------------------*/ +/* Change Current Directory or Current Drive, Get Current Directory */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_chdrive ( + const TCHAR* path /* Drive number to set */ +) +{ + int vol; + + + /* Get logical drive number */ + vol = get_ldnumber(&path); + if (vol < 0) return FR_INVALID_DRIVE; + CurrVol = (BYTE)vol; /* Set it as current volume */ + + return FR_OK; +} + + + +FRESULT f_chdir ( + const TCHAR* path /* Pointer to the directory path */ +) +{ +#if FF_STR_VOLUME_ID == 2 + UINT i; +#endif + FRESULT res; + DIR dj; + FATFS *fs; + DEF_NAMBUF + + + /* Get logical drive */ + res = mount_volume(&path, &fs, 0); + if (res == FR_OK) { + dj.obj.fs = fs; + INIT_NAMBUF(fs); + res = follow_path(&dj, path); /* Follow the path */ + if (res == FR_OK) { /* Follow completed */ + if (dj.fn[NSFLAG] & NS_NONAME) { /* Is it the start directory itself? */ + fs->cdir = dj.obj.sclust; +#if FF_FS_EXFAT + if (fs->fs_type == FS_EXFAT) { + fs->cdc_scl = dj.obj.c_scl; + fs->cdc_size = dj.obj.c_size; + fs->cdc_ofs = dj.obj.c_ofs; + } +#endif + } else { + if (dj.obj.attr & AM_DIR) { /* It is a sub-directory */ +#if FF_FS_EXFAT + if (fs->fs_type == FS_EXFAT) { + fs->cdir = ld_dword(fs->dirbuf + XDIR_FstClus); /* Sub-directory cluster */ + fs->cdc_scl = dj.obj.sclust; /* Save containing directory information */ + fs->cdc_size = ((DWORD)dj.obj.objsize & 0xFFFFFF00) | dj.obj.stat; + fs->cdc_ofs = dj.blk_ofs; + } else +#endif + { + fs->cdir = ld_clust(fs, dj.dir); /* Sub-directory cluster */ + } + } else { + res = FR_NO_PATH; /* Reached but a file */ + } + } + } + FREE_NAMBUF(); + if (res == FR_NO_FILE) res = FR_NO_PATH; +#if FF_STR_VOLUME_ID == 2 /* Also current drive is changed if in Unix style volume ID */ + if (res == FR_OK) { + for (i = FF_VOLUMES - 1; i && fs != FatFs[i]; i--) ; /* Set current drive */ + CurrVol = (BYTE)i; + } +#endif + } + + LEAVE_FF(fs, res); +} + + +#if FF_FS_RPATH >= 2 +FRESULT f_getcwd ( + TCHAR* buff, /* Pointer to the directory path */ + UINT len /* Size of buff in unit of TCHAR */ +) +{ + FRESULT res; + DIR dj; + FATFS *fs; + UINT i, n; + DWORD ccl; + TCHAR *tp = buff; +#if FF_VOLUMES >= 2 + UINT vl; +#if FF_STR_VOLUME_ID + const char *vp; +#endif +#endif + FILINFO fno; + DEF_NAMBUF + + + /* Get logical drive */ + buff[0] = 0; /* Set null string to get current volume */ + res = mount_volume((const TCHAR**)&buff, &fs, 0); /* Get current volume */ + if (res == FR_OK) { + dj.obj.fs = fs; + INIT_NAMBUF(fs); + + /* Follow parent directories and create the path */ + i = len; /* Bottom of buffer (directory stack base) */ + if (!FF_FS_EXFAT || fs->fs_type != FS_EXFAT) { /* (Cannot do getcwd on exFAT and returns root path) */ + dj.obj.sclust = fs->cdir; /* Start to follow upper directory from current directory */ + while ((ccl = dj.obj.sclust) != 0) { /* Repeat while current directory is a sub-directory */ + res = dir_sdi(&dj, 1 * SZDIRE); /* Get parent directory */ + if (res != FR_OK) break; + res = move_window(fs, dj.sect); + if (res != FR_OK) break; + dj.obj.sclust = ld_clust(fs, dj.dir); /* Goto parent directory */ + res = dir_sdi(&dj, 0); + if (res != FR_OK) break; + do { /* Find the entry links to the child directory */ + res = DIR_READ_FILE(&dj); + if (res != FR_OK) break; + if (ccl == ld_clust(fs, dj.dir)) break; /* Found the entry */ + res = dir_next(&dj, 0); + } while (res == FR_OK); + if (res == FR_NO_FILE) res = FR_INT_ERR;/* It cannot be 'not found'. */ + if (res != FR_OK) break; + get_fileinfo(&dj, &fno); /* Get the directory name and push it to the buffer */ + for (n = 0; fno.fname[n]; n++) ; /* Name length */ + if (i < n + 1) { /* Insufficient space to store the path name? */ + res = FR_NOT_ENOUGH_CORE; break; + } + while (n) buff[--i] = fno.fname[--n]; /* Stack the name */ + buff[--i] = '/'; + } + } + if (res == FR_OK) { + if (i == len) buff[--i] = '/'; /* Is it the root-directory? */ +#if FF_VOLUMES >= 2 /* Put drive prefix */ + vl = 0; +#if FF_STR_VOLUME_ID >= 1 /* String volume ID */ + for (n = 0, vp = (const char*)VolumeStr[CurrVol]; vp[n]; n++) ; + if (i >= n + 2) { + if (FF_STR_VOLUME_ID == 2) *tp++ = (TCHAR)'/'; + for (vl = 0; vl < n; *tp++ = (TCHAR)vp[vl], vl++) ; + if (FF_STR_VOLUME_ID == 1) *tp++ = (TCHAR)':'; + vl++; + } +#else /* Numeric volume ID */ + if (i >= 3) { + *tp++ = (TCHAR)'0' + CurrVol; + *tp++ = (TCHAR)':'; + vl = 2; + } +#endif + if (vl == 0) res = FR_NOT_ENOUGH_CORE; +#endif + /* Add current directory path */ + if (res == FR_OK) { + do *tp++ = buff[i++]; while (i < len); /* Copy stacked path string */ + } + } + FREE_NAMBUF(); + } + + *tp = 0; + LEAVE_FF(fs, res); +} + +#endif /* FF_FS_RPATH >= 2 */ +#endif /* FF_FS_RPATH >= 1 */ + + + +#if FF_FS_MINIMIZE <= 2 +/*-----------------------------------------------------------------------*/ +/* Seek File Read/Write Pointer */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_lseek ( + FIL* fp, /* Pointer to the file object */ + FSIZE_t ofs /* File pointer from top of file */ +) +{ + FRESULT res; + FATFS *fs; + DWORD clst, bcs; + LBA_t nsect; + FSIZE_t ifptr; +#if FF_USE_FASTSEEK + DWORD cl, pcl, ncl, tcl, tlen, ulen; + DWORD *tbl; + LBA_t dsc; +#endif + + res = validate(&fp->obj, &fs); /* Check validity of the file object */ + if (res == FR_OK) res = (FRESULT)fp->err; +#if FF_FS_EXFAT && !FF_FS_READONLY + if (res == FR_OK && fs->fs_type == FS_EXFAT) { + res = fill_last_frag(&fp->obj, fp->clust, 0xFFFFFFFF); /* Fill last fragment on the FAT if needed */ + } +#endif + if (res != FR_OK) LEAVE_FF(fs, res); + +#if FF_USE_FASTSEEK + if (fp->cltbl) { /* Fast seek */ + if (ofs == CREATE_LINKMAP) { /* Create CLMT */ + tbl = fp->cltbl; + tlen = *tbl++; ulen = 2; /* Given table size and required table size */ + cl = fp->obj.sclust; /* Origin of the chain */ + if (cl != 0) { + do { + /* Get a fragment */ + tcl = cl; ncl = 0; ulen += 2; /* Top, length and used items */ + do { + pcl = cl; ncl++; + cl = get_fat(&fp->obj, cl); + if (cl <= 1) ABORT(fs, FR_INT_ERR); + if (cl == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR); + } while (cl == pcl + 1); + if (ulen <= tlen) { /* Store the length and top of the fragment */ + *tbl++ = ncl; *tbl++ = tcl; + } + } while (cl < fs->n_fatent); /* Repeat until end of chain */ + } + *fp->cltbl = ulen; /* Number of items used */ + if (ulen <= tlen) { + *tbl = 0; /* Terminate table */ + } else { + res = FR_NOT_ENOUGH_CORE; /* Given table size is smaller than required */ + } + } else { /* Fast seek */ + if (ofs > fp->obj.objsize) ofs = fp->obj.objsize; /* Clip offset at the file size */ + fp->fptr = ofs; /* Set file pointer */ + if (ofs > 0) { + fp->clust = clmt_clust(fp, ofs - 1); + dsc = clst2sect(fs, fp->clust); + if (dsc == 0) ABORT(fs, FR_INT_ERR); + dsc += (DWORD)((ofs - 1) / SS(fs)) & (fs->csize - 1); + if (fp->fptr % SS(fs) && dsc != fp->sect) { /* Refill sector cache if needed */ +#if !FF_FS_TINY +#if !FF_FS_READONLY + if (fp->flag & FA_DIRTY) { /* Write-back dirty sector cache */ + if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); + fp->flag &= (BYTE)~FA_DIRTY; + } +#endif + if (disk_read(fs->pdrv, fp->buf, dsc, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); /* Load current sector */ +#endif + fp->sect = dsc; + } + } + } + } else +#endif + + /* Normal Seek */ + { +#if FF_FS_EXFAT + if (fs->fs_type != FS_EXFAT && ofs >= 0x100000000) ofs = 0xFFFFFFFF; /* Clip at 4 GiB - 1 if at FATxx */ +#endif + if (ofs > fp->obj.objsize && (FF_FS_READONLY || !(fp->flag & FA_WRITE))) { /* In read-only mode, clip offset with the file size */ + ofs = fp->obj.objsize; + } + ifptr = fp->fptr; + fp->fptr = nsect = 0; + if (ofs > 0) { + bcs = (DWORD)fs->csize * SS(fs); /* Cluster size (byte) */ + if (ifptr > 0 && + (ofs - 1) / bcs >= (ifptr - 1) / bcs) { /* When seek to same or following cluster, */ + fp->fptr = (ifptr - 1) & ~(FSIZE_t)(bcs - 1); /* start from the current cluster */ + ofs -= fp->fptr; + clst = fp->clust; + } else { /* When seek to back cluster, */ + clst = fp->obj.sclust; /* start from the first cluster */ +#if !FF_FS_READONLY + if (clst == 0) { /* If no cluster chain, create a new chain */ + clst = create_chain(&fp->obj, 0); + if (clst == 1) ABORT(fs, FR_INT_ERR); + if (clst == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR); + fp->obj.sclust = clst; + } +#endif + fp->clust = clst; + } + if (clst != 0) { + while (ofs > bcs) { /* Cluster following loop */ + ofs -= bcs; fp->fptr += bcs; +#if !FF_FS_READONLY + if (fp->flag & FA_WRITE) { /* Check if in write mode or not */ + if (FF_FS_EXFAT && fp->fptr > fp->obj.objsize) { /* No FAT chain object needs correct objsize to generate FAT value */ + fp->obj.objsize = fp->fptr; + fp->flag |= FA_MODIFIED; + } + clst = create_chain(&fp->obj, clst); /* Follow chain with forceed stretch */ + if (clst == 0) { /* Clip file size in case of disk full */ + ofs = 0; break; + } + } else +#endif + { + clst = get_fat(&fp->obj, clst); /* Follow cluster chain if not in write mode */ + } + if (clst == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR); + if (clst <= 1 || clst >= fs->n_fatent) ABORT(fs, FR_INT_ERR); + fp->clust = clst; + } + fp->fptr += ofs; + if (ofs % SS(fs)) { + nsect = clst2sect(fs, clst); /* Current sector */ + if (nsect == 0) ABORT(fs, FR_INT_ERR); + nsect += (DWORD)(ofs / SS(fs)); + } + } + } + if (!FF_FS_READONLY && fp->fptr > fp->obj.objsize) { /* Set file change flag if the file size is extended */ + fp->obj.objsize = fp->fptr; + fp->flag |= FA_MODIFIED; + } + if (fp->fptr % SS(fs) && nsect != fp->sect) { /* Fill sector cache if needed */ +#if !FF_FS_TINY +#if !FF_FS_READONLY + if (fp->flag & FA_DIRTY) { /* Write-back dirty sector cache */ + if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); + fp->flag &= (BYTE)~FA_DIRTY; + } +#endif + if (disk_read(fs->pdrv, fp->buf, nsect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); /* Fill sector cache */ +#endif + fp->sect = nsect; + } + } + + LEAVE_FF(fs, res); +} + + + +#if FF_FS_MINIMIZE <= 1 +/*-----------------------------------------------------------------------*/ +/* Create a Directory Object */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_opendir ( + DIR* dp, /* Pointer to directory object to create */ + const TCHAR* path /* Pointer to the directory path */ +) +{ + FRESULT res; + FATFS *fs; + DEF_NAMBUF + + + if (!dp) return FR_INVALID_OBJECT; + + /* Get logical drive */ + res = mount_volume(&path, &fs, 0); + if (res == FR_OK) { + dp->obj.fs = fs; + INIT_NAMBUF(fs); + res = follow_path(dp, path); /* Follow the path to the directory */ + if (res == FR_OK) { /* Follow completed */ + if (!(dp->fn[NSFLAG] & NS_NONAME)) { /* It is not the origin directory itself */ + if (dp->obj.attr & AM_DIR) { /* This object is a sub-directory */ +#if FF_FS_EXFAT + if (fs->fs_type == FS_EXFAT) { + dp->obj.c_scl = dp->obj.sclust; /* Get containing directory inforamation */ + dp->obj.c_size = ((DWORD)dp->obj.objsize & 0xFFFFFF00) | dp->obj.stat; + dp->obj.c_ofs = dp->blk_ofs; + init_alloc_info(fs, &dp->obj); /* Get object allocation info */ + } else +#endif + { + dp->obj.sclust = ld_clust(fs, dp->dir); /* Get object allocation info */ + } + } else { /* This object is a file */ + res = FR_NO_PATH; + } + } + if (res == FR_OK) { + dp->obj.id = fs->id; + res = dir_sdi(dp, 0); /* Rewind directory */ +#if FF_FS_LOCK != 0 + if (res == FR_OK) { + if (dp->obj.sclust != 0) { + dp->obj.lockid = inc_lock(dp, 0); /* Lock the sub directory */ + if (!dp->obj.lockid) res = FR_TOO_MANY_OPEN_FILES; + } else { + dp->obj.lockid = 0; /* Root directory need not to be locked */ + } + } +#endif + } + } + FREE_NAMBUF(); + if (res == FR_NO_FILE) res = FR_NO_PATH; + } + if (res != FR_OK) dp->obj.fs = 0; /* Invalidate the directory object if function faild */ + + LEAVE_FF(fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Close Directory */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_closedir ( + DIR *dp /* Pointer to the directory object to be closed */ +) +{ + FRESULT res; + FATFS *fs; + + + res = validate(&dp->obj, &fs); /* Check validity of the file object */ + if (res == FR_OK) { +#if FF_FS_LOCK != 0 + if (dp->obj.lockid) res = dec_lock(dp->obj.lockid); /* Decrement sub-directory open counter */ + if (res == FR_OK) dp->obj.fs = 0; /* Invalidate directory object */ +#else + dp->obj.fs = 0; /* Invalidate directory object */ +#endif +#if FF_FS_REENTRANT + unlock_fs(fs, FR_OK); /* Unlock volume */ +#endif + } + return res; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Read Directory Entries in Sequence */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_readdir ( + DIR* dp, /* Pointer to the open directory object */ + FILINFO* fno /* Pointer to file information to return */ +) +{ + FRESULT res; + FATFS *fs; + DEF_NAMBUF + + + res = validate(&dp->obj, &fs); /* Check validity of the directory object */ + if (res == FR_OK) { + if (!fno) { + res = dir_sdi(dp, 0); /* Rewind the directory object */ + } else { + INIT_NAMBUF(fs); + res = DIR_READ_FILE(dp); /* Read an item */ + if (res == FR_NO_FILE) res = FR_OK; /* Ignore end of directory */ + if (res == FR_OK) { /* A valid entry is found */ + get_fileinfo(dp, fno); /* Get the object information */ + res = dir_next(dp, 0); /* Increment index for next */ + if (res == FR_NO_FILE) res = FR_OK; /* Ignore end of directory now */ + } + FREE_NAMBUF(); + } + } + LEAVE_FF(fs, res); +} + + + +#if FF_USE_FIND +/*-----------------------------------------------------------------------*/ +/* Find Next File */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_findnext ( + DIR* dp, /* Pointer to the open directory object */ + FILINFO* fno /* Pointer to the file information structure */ +) +{ + FRESULT res; + + + for (;;) { + res = f_readdir(dp, fno); /* Get a directory item */ + if (res != FR_OK || !fno || !fno->fname[0]) break; /* Terminate if any error or end of directory */ + if (pattern_match(dp->pat, fno->fname, 0, FIND_RECURS)) break; /* Test for the file name */ +#if FF_USE_LFN && FF_USE_FIND == 2 + if (pattern_match(dp->pat, fno->altname, 0, FIND_RECURS)) break; /* Test for alternative name if exist */ +#endif + } + return res; +} + + + +/*-----------------------------------------------------------------------*/ +/* Find First File */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_findfirst ( + DIR* dp, /* Pointer to the blank directory object */ + FILINFO* fno, /* Pointer to the file information structure */ + const TCHAR* path, /* Pointer to the directory to open */ + const TCHAR* pattern /* Pointer to the matching pattern */ +) +{ + FRESULT res; + + + dp->pat = pattern; /* Save pointer to pattern string */ + res = f_opendir(dp, path); /* Open the target directory */ + if (res == FR_OK) { + res = f_findnext(dp, fno); /* Find the first item */ + } + return res; +} + +#endif /* FF_USE_FIND */ + + + +#if FF_FS_MINIMIZE == 0 +/*-----------------------------------------------------------------------*/ +/* Get File Status */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_stat ( + const TCHAR* path, /* Pointer to the file path */ + FILINFO* fno /* Pointer to file information to return */ +) +{ + FRESULT res; + DIR dj; + DEF_NAMBUF + + + /* Get logical drive */ + res = mount_volume(&path, &dj.obj.fs, 0); + if (res == FR_OK) { + INIT_NAMBUF(dj.obj.fs); + res = follow_path(&dj, path); /* Follow the file path */ + if (res == FR_OK) { /* Follow completed */ + if (dj.fn[NSFLAG] & NS_NONAME) { /* It is origin directory */ + res = FR_INVALID_NAME; + } else { /* Found an object */ + if (fno) get_fileinfo(&dj, fno); + } + } + FREE_NAMBUF(); + } + + LEAVE_FF(dj.obj.fs, res); +} + + + +#if !FF_FS_READONLY +/*-----------------------------------------------------------------------*/ +/* Get Number of Free Clusters */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_getfree ( + const TCHAR* path, /* Logical drive number */ + DWORD* nclst, /* Pointer to a variable to return number of free clusters */ + FATFS** fatfs /* Pointer to return pointer to corresponding filesystem object */ +) +{ + FRESULT res; + FATFS *fs; + DWORD nfree, clst, stat; + LBA_t sect; + UINT i; + FFOBJID obj; + + + /* Get logical drive */ + res = mount_volume(&path, &fs, 0); + if (res == FR_OK) { + *fatfs = fs; /* Return ptr to the fs object */ + /* If free_clst is valid, return it without full FAT scan */ + if (fs->free_clst <= fs->n_fatent - 2) { + *nclst = fs->free_clst; + } else { + /* Scan FAT to obtain number of free clusters */ + nfree = 0; + if (fs->fs_type == FS_FAT12) { /* FAT12: Scan bit field FAT entries */ + clst = 2; obj.fs = fs; + do { + stat = get_fat(&obj, clst); + if (stat == 0xFFFFFFFF) { res = FR_DISK_ERR; break; } + if (stat == 1) { res = FR_INT_ERR; break; } + if (stat == 0) nfree++; + } while (++clst < fs->n_fatent); + } else { +#if FF_FS_EXFAT + if (fs->fs_type == FS_EXFAT) { /* exFAT: Scan allocation bitmap */ + BYTE bm; + UINT b; + + clst = fs->n_fatent - 2; /* Number of clusters */ + sect = fs->bitbase; /* Bitmap sector */ + i = 0; /* Offset in the sector */ + do { /* Counts numbuer of bits with zero in the bitmap */ + if (i == 0) { + res = move_window(fs, sect++); + if (res != FR_OK) break; + } + for (b = 8, bm = fs->win[i]; b && clst; b--, clst--) { + if (!(bm & 1)) nfree++; + bm >>= 1; + } + i = (i + 1) % SS(fs); + } while (clst); + } else +#endif + { /* FAT16/32: Scan WORD/DWORD FAT entries */ + clst = fs->n_fatent; /* Number of entries */ + sect = fs->fatbase; /* Top of the FAT */ + i = 0; /* Offset in the sector */ + do { /* Counts numbuer of entries with zero in the FAT */ + if (i == 0) { + res = move_window(fs, sect++); + if (res != FR_OK) break; + } + if (fs->fs_type == FS_FAT16) { + if (ld_word(fs->win + i) == 0) nfree++; + i += 2; + } else { + if ((ld_dword(fs->win + i) & 0x0FFFFFFF) == 0) nfree++; + i += 4; + } + i %= SS(fs); + } while (--clst); + } + } + if (res == FR_OK) { /* Update parameters if succeeded */ + *nclst = nfree; /* Return the free clusters */ + fs->free_clst = nfree; /* Now free_clst is valid */ + fs->fsi_flag |= 1; /* FAT32: FSInfo is to be updated */ + } + } + } + + LEAVE_FF(fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Truncate File */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_truncate ( + FIL* fp /* Pointer to the file object */ +) +{ + FRESULT res; + FATFS *fs; + DWORD ncl; + + + res = validate(&fp->obj, &fs); /* Check validity of the file object */ + if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) LEAVE_FF(fs, res); + if (!(fp->flag & FA_WRITE)) LEAVE_FF(fs, FR_DENIED); /* Check access mode */ + + if (fp->fptr < fp->obj.objsize) { /* Process when fptr is not on the eof */ + if (fp->fptr == 0) { /* When set file size to zero, remove entire cluster chain */ + res = remove_chain(&fp->obj, fp->obj.sclust, 0); + fp->obj.sclust = 0; + } else { /* When truncate a part of the file, remove remaining clusters */ + ncl = get_fat(&fp->obj, fp->clust); + res = FR_OK; + if (ncl == 0xFFFFFFFF) res = FR_DISK_ERR; + if (ncl == 1) res = FR_INT_ERR; + if (res == FR_OK && ncl < fs->n_fatent) { + res = remove_chain(&fp->obj, ncl, fp->clust); + } + } + fp->obj.objsize = fp->fptr; /* Set file size to current read/write point */ + fp->flag |= FA_MODIFIED; +#if !FF_FS_TINY + if (res == FR_OK && (fp->flag & FA_DIRTY)) { + if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) { + res = FR_DISK_ERR; + } else { + fp->flag &= (BYTE)~FA_DIRTY; + } + } +#endif + if (res != FR_OK) ABORT(fs, res); + } + + LEAVE_FF(fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Delete a File/Directory */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_unlink ( + const TCHAR* path /* Pointer to the file or directory path */ +) +{ + FRESULT res; + DIR dj, sdj; + DWORD dclst = 0; + FATFS *fs; +#if FF_FS_EXFAT + FFOBJID obj; +#endif + DEF_NAMBUF + + + /* Get logical drive */ + res = mount_volume(&path, &fs, FA_WRITE); + if (res == FR_OK) { + dj.obj.fs = fs; + INIT_NAMBUF(fs); + res = follow_path(&dj, path); /* Follow the file path */ + if (FF_FS_RPATH && res == FR_OK && (dj.fn[NSFLAG] & NS_DOT)) { + res = FR_INVALID_NAME; /* Cannot remove dot entry */ + } +#if FF_FS_LOCK != 0 + if (res == FR_OK) res = chk_lock(&dj, 2); /* Check if it is an open object */ +#endif + if (res == FR_OK) { /* The object is accessible */ + if (dj.fn[NSFLAG] & NS_NONAME) { + res = FR_INVALID_NAME; /* Cannot remove the origin directory */ + } else { + if (dj.obj.attr & AM_RDO) { + res = FR_DENIED; /* Cannot remove R/O object */ + } + } + if (res == FR_OK) { +#if FF_FS_EXFAT + obj.fs = fs; + if (fs->fs_type == FS_EXFAT) { + init_alloc_info(fs, &obj); + dclst = obj.sclust; + } else +#endif + { + dclst = ld_clust(fs, dj.dir); + } + if (dj.obj.attr & AM_DIR) { /* Is it a sub-directory? */ +#if FF_FS_RPATH != 0 + if (dclst == fs->cdir) { /* Is it the current directory? */ + res = FR_DENIED; + } else +#endif + { + sdj.obj.fs = fs; /* Open the sub-directory */ + sdj.obj.sclust = dclst; +#if FF_FS_EXFAT + if (fs->fs_type == FS_EXFAT) { + sdj.obj.objsize = obj.objsize; + sdj.obj.stat = obj.stat; + } +#endif + res = dir_sdi(&sdj, 0); + if (res == FR_OK) { + res = DIR_READ_FILE(&sdj); /* Test if the directory is empty */ + if (res == FR_OK) res = FR_DENIED; /* Not empty? */ + if (res == FR_NO_FILE) res = FR_OK; /* Empty? */ + } + } + } + } + if (res == FR_OK) { + res = dir_remove(&dj); /* Remove the directory entry */ + if (res == FR_OK && dclst != 0) { /* Remove the cluster chain if exist */ +#if FF_FS_EXFAT + res = remove_chain(&obj, dclst, 0); +#else + res = remove_chain(&dj.obj, dclst, 0); +#endif + } + if (res == FR_OK) res = sync_fs(fs); + } + } + FREE_NAMBUF(); + } + + LEAVE_FF(fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Create a Directory */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_mkdir ( + const TCHAR* path /* Pointer to the directory path */ +) +{ + FRESULT res; + DIR dj; + FFOBJID sobj; + FATFS *fs; + DWORD dcl, pcl, tm; + DEF_NAMBUF + + + res = mount_volume(&path, &fs, FA_WRITE); /* Get logical drive */ + if (res == FR_OK) { + dj.obj.fs = fs; + INIT_NAMBUF(fs); + res = follow_path(&dj, path); /* Follow the file path */ + if (res == FR_OK) res = FR_EXIST; /* Name collision? */ + if (FF_FS_RPATH && res == FR_NO_FILE && (dj.fn[NSFLAG] & NS_DOT)) { /* Invalid name? */ + res = FR_INVALID_NAME; + } + if (res == FR_NO_FILE) { /* It is clear to create a new directory */ + sobj.fs = fs; /* New object id to create a new chain */ + dcl = create_chain(&sobj, 0); /* Allocate a cluster for the new directory */ + res = FR_OK; + if (dcl == 0) res = FR_DENIED; /* No space to allocate a new cluster? */ + if (dcl == 1) res = FR_INT_ERR; /* Any insanity? */ + if (dcl == 0xFFFFFFFF) res = FR_DISK_ERR; /* Disk error? */ + tm = GET_FATTIME(); + if (res == FR_OK) { + res = dir_clear(fs, dcl); /* Clean up the new table */ + if (res == FR_OK) { + if (!FF_FS_EXFAT || fs->fs_type != FS_EXFAT) { /* Create dot entries (FAT only) */ + memset(fs->win + DIR_Name, ' ', 11); /* Create "." entry */ + fs->win[DIR_Name] = '.'; + fs->win[DIR_Attr] = AM_DIR; + st_dword(fs->win + DIR_ModTime, tm); + st_clust(fs, fs->win, dcl); + memcpy(fs->win + SZDIRE, fs->win, SZDIRE); /* Create ".." entry */ + fs->win[SZDIRE + 1] = '.'; pcl = dj.obj.sclust; + st_clust(fs, fs->win + SZDIRE, pcl); + fs->wflag = 1; + } + res = dir_register(&dj); /* Register the object to the parent directoy */ + } + } + if (res == FR_OK) { +#if FF_FS_EXFAT + if (fs->fs_type == FS_EXFAT) { /* Initialize directory entry block */ + st_dword(fs->dirbuf + XDIR_ModTime, tm); /* Created time */ + st_dword(fs->dirbuf + XDIR_FstClus, dcl); /* Table start cluster */ + st_dword(fs->dirbuf + XDIR_FileSize, (DWORD)fs->csize * SS(fs)); /* Directory size needs to be valid */ + st_dword(fs->dirbuf + XDIR_ValidFileSize, (DWORD)fs->csize * SS(fs)); + fs->dirbuf[XDIR_GenFlags] = 3; /* Initialize the object flag */ + fs->dirbuf[XDIR_Attr] = AM_DIR; /* Attribute */ + res = store_xdir(&dj); + } else +#endif + { + st_dword(dj.dir + DIR_ModTime, tm); /* Created time */ + st_clust(fs, dj.dir, dcl); /* Table start cluster */ + dj.dir[DIR_Attr] = AM_DIR; /* Attribute */ + fs->wflag = 1; + } + if (res == FR_OK) { + res = sync_fs(fs); + } + } else { + remove_chain(&sobj, dcl, 0); /* Could not register, remove the allocated cluster */ + } + } + FREE_NAMBUF(); + } + + LEAVE_FF(fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Rename a File/Directory */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_rename ( + const TCHAR* path_old, /* Pointer to the object name to be renamed */ + const TCHAR* path_new /* Pointer to the new name */ +) +{ + FRESULT res; + DIR djo, djn; + FATFS *fs; + BYTE buf[FF_FS_EXFAT ? SZDIRE * 2 : SZDIRE], *dir; + LBA_t sect; + DEF_NAMBUF + + + get_ldnumber(&path_new); /* Snip the drive number of new name off */ + res = mount_volume(&path_old, &fs, FA_WRITE); /* Get logical drive of the old object */ + if (res == FR_OK) { + djo.obj.fs = fs; + INIT_NAMBUF(fs); + res = follow_path(&djo, path_old); /* Check old object */ + if (res == FR_OK && (djo.fn[NSFLAG] & (NS_DOT | NS_NONAME))) res = FR_INVALID_NAME; /* Check validity of name */ +#if FF_FS_LOCK != 0 + if (res == FR_OK) { + res = chk_lock(&djo, 2); + } +#endif + if (res == FR_OK) { /* Object to be renamed is found */ +#if FF_FS_EXFAT + if (fs->fs_type == FS_EXFAT) { /* At exFAT volume */ + BYTE nf, nn; + WORD nh; + + memcpy(buf, fs->dirbuf, SZDIRE * 2); /* Save 85+C0 entry of old object */ + memcpy(&djn, &djo, sizeof djo); + res = follow_path(&djn, path_new); /* Make sure if new object name is not in use */ + if (res == FR_OK) { /* Is new name already in use by any other object? */ + res = (djn.obj.sclust == djo.obj.sclust && djn.dptr == djo.dptr) ? FR_NO_FILE : FR_EXIST; + } + if (res == FR_NO_FILE) { /* It is a valid path and no name collision */ + res = dir_register(&djn); /* Register the new entry */ + if (res == FR_OK) { + nf = fs->dirbuf[XDIR_NumSec]; nn = fs->dirbuf[XDIR_NumName]; + nh = ld_word(fs->dirbuf + XDIR_NameHash); + memcpy(fs->dirbuf, buf, SZDIRE * 2); /* Restore 85+C0 entry */ + fs->dirbuf[XDIR_NumSec] = nf; fs->dirbuf[XDIR_NumName] = nn; + st_word(fs->dirbuf + XDIR_NameHash, nh); + if (!(fs->dirbuf[XDIR_Attr] & AM_DIR)) fs->dirbuf[XDIR_Attr] |= AM_ARC; /* Set archive attribute if it is a file */ +/* Start of critical section where an interruption can cause a cross-link */ + res = store_xdir(&djn); + } + } + } else +#endif + { /* At FAT/FAT32 volume */ + memcpy(buf, djo.dir, SZDIRE); /* Save directory entry of the object */ + memcpy(&djn, &djo, sizeof (DIR)); /* Duplicate the directory object */ + res = follow_path(&djn, path_new); /* Make sure if new object name is not in use */ + if (res == FR_OK) { /* Is new name already in use by any other object? */ + res = (djn.obj.sclust == djo.obj.sclust && djn.dptr == djo.dptr) ? FR_NO_FILE : FR_EXIST; + } + if (res == FR_NO_FILE) { /* It is a valid path and no name collision */ + res = dir_register(&djn); /* Register the new entry */ + if (res == FR_OK) { + dir = djn.dir; /* Copy directory entry of the object except name */ + memcpy(dir + 13, buf + 13, SZDIRE - 13); + dir[DIR_Attr] = buf[DIR_Attr]; + if (!(dir[DIR_Attr] & AM_DIR)) dir[DIR_Attr] |= AM_ARC; /* Set archive attribute if it is a file */ + fs->wflag = 1; + if ((dir[DIR_Attr] & AM_DIR) && djo.obj.sclust != djn.obj.sclust) { /* Update .. entry in the sub-directory if needed */ + sect = clst2sect(fs, ld_clust(fs, dir)); + if (sect == 0) { + res = FR_INT_ERR; + } else { +/* Start of critical section where an interruption can cause a cross-link */ + res = move_window(fs, sect); + dir = fs->win + SZDIRE * 1; /* Ptr to .. entry */ + if (res == FR_OK && dir[1] == '.') { + st_clust(fs, dir, djn.obj.sclust); + fs->wflag = 1; + } + } + } + } + } + } + if (res == FR_OK) { + res = dir_remove(&djo); /* Remove old entry */ + if (res == FR_OK) { + res = sync_fs(fs); + } + } +/* End of the critical section */ + } + FREE_NAMBUF(); + } + + LEAVE_FF(fs, res); +} + +#endif /* !FF_FS_READONLY */ +#endif /* FF_FS_MINIMIZE == 0 */ +#endif /* FF_FS_MINIMIZE <= 1 */ +#endif /* FF_FS_MINIMIZE <= 2 */ + + + +#if FF_USE_CHMOD && !FF_FS_READONLY +/*-----------------------------------------------------------------------*/ +/* Change Attribute */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_chmod ( + const TCHAR* path, /* Pointer to the file path */ + BYTE attr, /* Attribute bits */ + BYTE mask /* Attribute mask to change */ +) +{ + FRESULT res; + DIR dj; + FATFS *fs; + DEF_NAMBUF + + + res = mount_volume(&path, &fs, FA_WRITE); /* Get logical drive */ + if (res == FR_OK) { + dj.obj.fs = fs; + INIT_NAMBUF(fs); + res = follow_path(&dj, path); /* Follow the file path */ + if (res == FR_OK && (dj.fn[NSFLAG] & (NS_DOT | NS_NONAME))) res = FR_INVALID_NAME; /* Check object validity */ + if (res == FR_OK) { + mask &= AM_RDO|AM_HID|AM_SYS|AM_ARC; /* Valid attribute mask */ +#if FF_FS_EXFAT + if (fs->fs_type == FS_EXFAT) { + fs->dirbuf[XDIR_Attr] = (attr & mask) | (fs->dirbuf[XDIR_Attr] & (BYTE)~mask); /* Apply attribute change */ + res = store_xdir(&dj); + } else +#endif + { + dj.dir[DIR_Attr] = (attr & mask) | (dj.dir[DIR_Attr] & (BYTE)~mask); /* Apply attribute change */ + fs->wflag = 1; + } + if (res == FR_OK) { + res = sync_fs(fs); + } + } + FREE_NAMBUF(); + } + + LEAVE_FF(fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Change Timestamp */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_utime ( + const TCHAR* path, /* Pointer to the file/directory name */ + const FILINFO* fno /* Pointer to the timestamp to be set */ +) +{ + FRESULT res; + DIR dj; + FATFS *fs; + DEF_NAMBUF + + + res = mount_volume(&path, &fs, FA_WRITE); /* Get logical drive */ + if (res == FR_OK) { + dj.obj.fs = fs; + INIT_NAMBUF(fs); + res = follow_path(&dj, path); /* Follow the file path */ + if (res == FR_OK && (dj.fn[NSFLAG] & (NS_DOT | NS_NONAME))) res = FR_INVALID_NAME; /* Check object validity */ + if (res == FR_OK) { +#if FF_FS_EXFAT + if (fs->fs_type == FS_EXFAT) { + st_dword(fs->dirbuf + XDIR_ModTime, (DWORD)fno->fdate << 16 | fno->ftime); + res = store_xdir(&dj); + } else +#endif + { + st_dword(dj.dir + DIR_ModTime, (DWORD)fno->fdate << 16 | fno->ftime); + fs->wflag = 1; + } + if (res == FR_OK) { + res = sync_fs(fs); + } + } + FREE_NAMBUF(); + } + + LEAVE_FF(fs, res); +} + +#endif /* FF_USE_CHMOD && !FF_FS_READONLY */ + + + +#if FF_USE_LABEL +/*-----------------------------------------------------------------------*/ +/* Get Volume Label */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_getlabel ( + const TCHAR* path, /* Logical drive number */ + TCHAR* label, /* Buffer to store the volume label */ + DWORD* vsn /* Variable to store the volume serial number */ +) +{ + FRESULT res; + DIR dj; + FATFS *fs; + UINT si, di; + WCHAR wc; + + /* Get logical drive */ + res = mount_volume(&path, &fs, 0); + + /* Get volume label */ + if (res == FR_OK && label) { + dj.obj.fs = fs; dj.obj.sclust = 0; /* Open root directory */ + res = dir_sdi(&dj, 0); + if (res == FR_OK) { + res = DIR_READ_LABEL(&dj); /* Find a volume label entry */ + if (res == FR_OK) { +#if FF_FS_EXFAT + if (fs->fs_type == FS_EXFAT) { + WCHAR hs; + UINT nw; + + for (si = di = hs = 0; si < dj.dir[XDIR_NumLabel]; si++) { /* Extract volume label from 83 entry */ + wc = ld_word(dj.dir + XDIR_Label + si * 2); + if (hs == 0 && IsSurrogate(wc)) { /* Is the code a surrogate? */ + hs = wc; continue; + } + nw = put_utf((DWORD)hs << 16 | wc, &label[di], 4); /* Store it in API encoding */ + if (nw == 0) { di = 0; break; } /* Encode error? */ + di += nw; + hs = 0; + } + if (hs != 0) di = 0; /* Broken surrogate pair? */ + label[di] = 0; + } else +#endif + { + si = di = 0; /* Extract volume label from AM_VOL entry */ + while (si < 11) { + wc = dj.dir[si++]; +#if FF_USE_LFN && FF_LFN_UNICODE >= 1 /* Unicode output */ + if (dbc_1st((BYTE)wc) && si < 11) wc = wc << 8 | dj.dir[si++]; /* Is it a DBC? */ + wc = ff_oem2uni(wc, CODEPAGE); /* Convert it into Unicode */ + if (wc == 0) { di = 0; break; } /* Invalid char in current code page? */ + di += put_utf(wc, &label[di], 4); /* Store it in Unicode */ +#else /* ANSI/OEM output */ + label[di++] = (TCHAR)wc; +#endif + } + do { /* Truncate trailing spaces */ + label[di] = 0; + if (di == 0) break; + } while (label[--di] == ' '); + } + } + } + if (res == FR_NO_FILE) { /* No label entry and return nul string */ + label[0] = 0; + res = FR_OK; + } + } + + /* Get volume serial number */ + if (res == FR_OK && vsn) { + res = move_window(fs, fs->volbase); + if (res == FR_OK) { + switch (fs->fs_type) { + case FS_EXFAT: + di = BPB_VolIDEx; + break; + + case FS_FAT32: + di = BS_VolID32; + break; + + default: + di = BS_VolID; + } + *vsn = ld_dword(fs->win + di); + } + } + + LEAVE_FF(fs, res); +} + + + +#if !FF_FS_READONLY +/*-----------------------------------------------------------------------*/ +/* Set Volume Label */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_setlabel ( + const TCHAR* label /* Volume label to set with heading logical drive number */ +) +{ + FRESULT res; + DIR dj; + FATFS *fs; + BYTE dirvn[22]; + UINT di; + WCHAR wc; + static const char badchr[18] = "+.,;=[]" "/*:<>|\\\"\?\x7F"; /* [0..16] for FAT, [7..16] for exFAT */ +#if FF_USE_LFN + DWORD dc; +#endif + + /* Get logical drive */ + res = mount_volume(&label, &fs, FA_WRITE); + if (res != FR_OK) LEAVE_FF(fs, res); + +#if FF_FS_EXFAT + if (fs->fs_type == FS_EXFAT) { /* On the exFAT volume */ + memset(dirvn, 0, 22); + di = 0; + while ((UINT)*label >= ' ') { /* Create volume label */ + dc = tchar2uni(&label); /* Get a Unicode character */ + if (dc >= 0x10000) { + if (dc == 0xFFFFFFFF || di >= 10) { /* Wrong surrogate or buffer overflow */ + dc = 0; + } else { + st_word(dirvn + di * 2, (WCHAR)(dc >> 16)); di++; + } + } + if (dc == 0 || strchr(&badchr[7], (int)dc) || di >= 11) { /* Check validity of the volume label */ + LEAVE_FF(fs, FR_INVALID_NAME); + } + st_word(dirvn + di * 2, (WCHAR)dc); di++; + } + } else +#endif + { /* On the FAT/FAT32 volume */ + memset(dirvn, ' ', 11); + di = 0; + while ((UINT)*label >= ' ') { /* Create volume label */ +#if FF_USE_LFN + dc = tchar2uni(&label); + wc = (dc < 0x10000) ? ff_uni2oem(ff_wtoupper(dc), CODEPAGE) : 0; +#else /* ANSI/OEM input */ + wc = (BYTE)*label++; + if (dbc_1st((BYTE)wc)) wc = dbc_2nd((BYTE)*label) ? wc << 8 | (BYTE)*label++ : 0; + if (IsLower(wc)) wc -= 0x20; /* To upper ASCII characters */ +#if FF_CODE_PAGE == 0 + if (ExCvt && wc >= 0x80) wc = ExCvt[wc - 0x80]; /* To upper extended characters (SBCS cfg) */ +#elif FF_CODE_PAGE < 900 + if (wc >= 0x80) wc = ExCvt[wc - 0x80]; /* To upper extended characters (SBCS cfg) */ +#endif +#endif + if (wc == 0 || strchr(&badchr[0], (int)wc) || di >= (UINT)((wc >= 0x100) ? 10 : 11)) { /* Reject invalid characters for volume label */ + LEAVE_FF(fs, FR_INVALID_NAME); + } + if (wc >= 0x100) dirvn[di++] = (BYTE)(wc >> 8); + dirvn[di++] = (BYTE)wc; + } + if (dirvn[0] == DDEM) LEAVE_FF(fs, FR_INVALID_NAME); /* Reject illegal name (heading DDEM) */ + while (di && dirvn[di - 1] == ' ') di--; /* Snip trailing spaces */ + } + + /* Set volume label */ + dj.obj.fs = fs; dj.obj.sclust = 0; /* Open root directory */ + res = dir_sdi(&dj, 0); + if (res == FR_OK) { + res = DIR_READ_LABEL(&dj); /* Get volume label entry */ + if (res == FR_OK) { + if (FF_FS_EXFAT && fs->fs_type == FS_EXFAT) { + dj.dir[XDIR_NumLabel] = (BYTE)di; /* Change the volume label */ + memcpy(dj.dir + XDIR_Label, dirvn, 22); + } else { + if (di != 0) { + memcpy(dj.dir, dirvn, 11); /* Change the volume label */ + } else { + dj.dir[DIR_Name] = DDEM; /* Remove the volume label */ + } + } + fs->wflag = 1; + res = sync_fs(fs); + } else { /* No volume label entry or an error */ + if (res == FR_NO_FILE) { + res = FR_OK; + if (di != 0) { /* Create a volume label entry */ + res = dir_alloc(&dj, 1); /* Allocate an entry */ + if (res == FR_OK) { + memset(dj.dir, 0, SZDIRE); /* Clean the entry */ + if (FF_FS_EXFAT && fs->fs_type == FS_EXFAT) { + dj.dir[XDIR_Type] = ET_VLABEL; /* Create volume label entry */ + dj.dir[XDIR_NumLabel] = (BYTE)di; + memcpy(dj.dir + XDIR_Label, dirvn, 22); + } else { + dj.dir[DIR_Attr] = AM_VOL; /* Create volume label entry */ + memcpy(dj.dir, dirvn, 11); + } + fs->wflag = 1; + res = sync_fs(fs); + } + } + } + } + } + + LEAVE_FF(fs, res); +} + +#endif /* !FF_FS_READONLY */ +#endif /* FF_USE_LABEL */ + + + +#if FF_USE_EXPAND && !FF_FS_READONLY +/*-----------------------------------------------------------------------*/ +/* Allocate a Contiguous Blocks to the File */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_expand ( + FIL* fp, /* Pointer to the file object */ + FSIZE_t fsz, /* File size to be expanded to */ + BYTE opt /* Operation mode 0:Find and prepare or 1:Find and allocate */ +) +{ + FRESULT res; + FATFS *fs; + DWORD n, clst, stcl, scl, ncl, tcl, lclst; + + + res = validate(&fp->obj, &fs); /* Check validity of the file object */ + if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) LEAVE_FF(fs, res); + if (fsz == 0 || fp->obj.objsize != 0 || !(fp->flag & FA_WRITE)) LEAVE_FF(fs, FR_DENIED); +#if FF_FS_EXFAT + if (fs->fs_type != FS_EXFAT && fsz >= 0x100000000) LEAVE_FF(fs, FR_DENIED); /* Check if in size limit */ +#endif + n = (DWORD)fs->csize * SS(fs); /* Cluster size */ + tcl = (DWORD)(fsz / n) + ((fsz & (n - 1)) ? 1 : 0); /* Number of clusters required */ + stcl = fs->last_clst; lclst = 0; + if (stcl < 2 || stcl >= fs->n_fatent) stcl = 2; + +#if FF_FS_EXFAT + if (fs->fs_type == FS_EXFAT) { + scl = find_bitmap(fs, stcl, tcl); /* Find a contiguous cluster block */ + if (scl == 0) res = FR_DENIED; /* No contiguous cluster block was found */ + if (scl == 0xFFFFFFFF) res = FR_DISK_ERR; + if (res == FR_OK) { /* A contiguous free area is found */ + if (opt) { /* Allocate it now */ + res = change_bitmap(fs, scl, tcl, 1); /* Mark the cluster block 'in use' */ + lclst = scl + tcl - 1; + } else { /* Set it as suggested point for next allocation */ + lclst = scl - 1; + } + } + } else +#endif + { + scl = clst = stcl; ncl = 0; + for (;;) { /* Find a contiguous cluster block */ + n = get_fat(&fp->obj, clst); + if (++clst >= fs->n_fatent) clst = 2; + if (n == 1) { res = FR_INT_ERR; break; } + if (n == 0xFFFFFFFF) { res = FR_DISK_ERR; break; } + if (n == 0) { /* Is it a free cluster? */ + if (++ncl == tcl) break; /* Break if a contiguous cluster block is found */ + } else { + scl = clst; ncl = 0; /* Not a free cluster */ + } + if (clst == stcl) { res = FR_DENIED; break; } /* No contiguous cluster? */ + } + if (res == FR_OK) { /* A contiguous free area is found */ + if (opt) { /* Allocate it now */ + for (clst = scl, n = tcl; n; clst++, n--) { /* Create a cluster chain on the FAT */ + res = put_fat(fs, clst, (n == 1) ? 0xFFFFFFFF : clst + 1); + if (res != FR_OK) break; + lclst = clst; + } + } else { /* Set it as suggested point for next allocation */ + lclst = scl - 1; + } + } + } + + if (res == FR_OK) { + fs->last_clst = lclst; /* Set suggested start cluster to start next */ + if (opt) { /* Is it allocated now? */ + fp->obj.sclust = scl; /* Update object allocation information */ + fp->obj.objsize = fsz; + if (FF_FS_EXFAT) fp->obj.stat = 2; /* Set status 'contiguous chain' */ + fp->flag |= FA_MODIFIED; + if (fs->free_clst <= fs->n_fatent - 2) { /* Update FSINFO */ + fs->free_clst -= tcl; + fs->fsi_flag |= 1; + } + } + } + + LEAVE_FF(fs, res); +} + +#endif /* FF_USE_EXPAND && !FF_FS_READONLY */ + + + +#if FF_USE_FORWARD +/*-----------------------------------------------------------------------*/ +/* Forward Data to the Stream Directly */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_forward ( + FIL* fp, /* Pointer to the file object */ + UINT (*func)(const BYTE*,UINT), /* Pointer to the streaming function */ + UINT btf, /* Number of bytes to forward */ + UINT* bf /* Pointer to number of bytes forwarded */ +) +{ + FRESULT res; + FATFS *fs; + DWORD clst; + LBA_t sect; + FSIZE_t remain; + UINT rcnt, csect; + BYTE *dbuf; + + + *bf = 0; /* Clear transfer byte counter */ + res = validate(&fp->obj, &fs); /* Check validity of the file object */ + if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) LEAVE_FF(fs, res); + if (!(fp->flag & FA_READ)) LEAVE_FF(fs, FR_DENIED); /* Check access mode */ + + remain = fp->obj.objsize - fp->fptr; + if (btf > remain) btf = (UINT)remain; /* Truncate btf by remaining bytes */ + + for ( ; btf > 0 && (*func)(0, 0); fp->fptr += rcnt, *bf += rcnt, btf -= rcnt) { /* Repeat until all data transferred or stream goes busy */ + csect = (UINT)(fp->fptr / SS(fs) & (fs->csize - 1)); /* Sector offset in the cluster */ + if (fp->fptr % SS(fs) == 0) { /* On the sector boundary? */ + if (csect == 0) { /* On the cluster boundary? */ + clst = (fp->fptr == 0) ? /* On the top of the file? */ + fp->obj.sclust : get_fat(&fp->obj, fp->clust); + if (clst <= 1) ABORT(fs, FR_INT_ERR); + if (clst == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR); + fp->clust = clst; /* Update current cluster */ + } + } + sect = clst2sect(fs, fp->clust); /* Get current data sector */ + if (sect == 0) ABORT(fs, FR_INT_ERR); + sect += csect; +#if FF_FS_TINY + if (move_window(fs, sect) != FR_OK) ABORT(fs, FR_DISK_ERR); /* Move sector window to the file data */ + dbuf = fs->win; +#else + if (fp->sect != sect) { /* Fill sector cache with file data */ +#if !FF_FS_READONLY + if (fp->flag & FA_DIRTY) { /* Write-back dirty sector cache */ + if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); + fp->flag &= (BYTE)~FA_DIRTY; + } +#endif + if (disk_read(fs->pdrv, fp->buf, sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); + } + dbuf = fp->buf; +#endif + fp->sect = sect; + rcnt = SS(fs) - (UINT)fp->fptr % SS(fs); /* Number of bytes remains in the sector */ + if (rcnt > btf) rcnt = btf; /* Clip it by btr if needed */ + rcnt = (*func)(dbuf + ((UINT)fp->fptr % SS(fs)), rcnt); /* Forward the file data */ + if (rcnt == 0) ABORT(fs, FR_INT_ERR); + } + + LEAVE_FF(fs, FR_OK); +} +#endif /* FF_USE_FORWARD */ + + + +#if !FF_FS_READONLY && FF_USE_MKFS +/*-----------------------------------------------------------------------*/ +/* Create FAT/exFAT volume (with sub-functions) */ +/*-----------------------------------------------------------------------*/ + +#define N_SEC_TRACK 63 /* Sectors per track for determination of drive CHS */ +#define GPT_ALIGN 0x100000 /* Alignment of partitions in GPT [byte] (>=128KB) */ +#define GPT_ITEMS 128 /* Number of GPT table size (>=128, sector aligned) */ + + +/* Create partitions on the physical drive in format of MBR or GPT */ + +static FRESULT create_partition ( + BYTE drv, /* Physical drive number */ + const LBA_t plst[], /* Partition list */ + BYTE sys, /* System ID (for only MBR, temp setting) */ + BYTE* buf /* Working buffer for a sector */ +) +{ + UINT i, cy; + LBA_t sz_drv; + DWORD sz_drv32, nxt_alloc32, sz_part32; + BYTE *pte; + BYTE hd, n_hd, sc, n_sc; + + /* Get physical drive size */ + if (disk_ioctl(drv, GET_SECTOR_COUNT, &sz_drv) != RES_OK) return FR_DISK_ERR; + +#if FF_LBA64 + if (sz_drv >= FF_MIN_GPT) { /* Create partitions in GPT format */ + WORD ss; + UINT sz_ptbl, pi, si, ofs; + DWORD bcc, rnd, align; + QWORD nxt_alloc, sz_part, sz_pool, top_bpt; + static const BYTE gpt_mbr[16] = {0x00, 0x00, 0x02, 0x00, 0xEE, 0xFE, 0xFF, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF}; + +#if FF_MAX_SS != FF_MIN_SS + if (disk_ioctl(drv, GET_SECTOR_SIZE, &ss) != RES_OK) return FR_DISK_ERR; /* Get sector size */ + if (ss > FF_MAX_SS || ss < FF_MIN_SS || (ss & (ss - 1))) return FR_DISK_ERR; +#else + ss = FF_MAX_SS; +#endif + rnd = (DWORD)sz_drv + GET_FATTIME(); /* Random seed */ + align = GPT_ALIGN / ss; /* Partition alignment for GPT [sector] */ + sz_ptbl = GPT_ITEMS * SZ_GPTE / ss; /* Size of partition table [sector] */ + top_bpt = sz_drv - sz_ptbl - 1; /* Backup partiiton table start sector */ + nxt_alloc = 2 + sz_ptbl; /* First allocatable sector */ + sz_pool = top_bpt - nxt_alloc; /* Size of allocatable area */ + bcc = 0xFFFFFFFF; sz_part = 1; + pi = si = 0; /* partition table index, size table index */ + do { + if (pi * SZ_GPTE % ss == 0) memset(buf, 0, ss); /* Clean the buffer if needed */ + if (sz_part != 0) { /* Is the size table not termintated? */ + nxt_alloc = (nxt_alloc + align - 1) & ((QWORD)0 - align); /* Align partition start */ + sz_part = plst[si++]; /* Get a partition size */ + if (sz_part <= 100) { /* Is the size in percentage? */ + sz_part = sz_pool * sz_part / 100; + sz_part = (sz_part + align - 1) & ((QWORD)0 - align); /* Align partition end (only if in percentage) */ + } + if (nxt_alloc + sz_part > top_bpt) { /* Clip the size at end of the pool */ + sz_part = (nxt_alloc < top_bpt) ? top_bpt - nxt_alloc : 0; + } + } + if (sz_part != 0) { /* Add a partition? */ + ofs = pi * SZ_GPTE % ss; + memcpy(buf + ofs + GPTE_PtGuid, GUID_MS_Basic, 16); /* Set partition GUID (Microsoft Basic Data) */ + rnd = make_rand(rnd, buf + ofs + GPTE_UpGuid, 16); /* Set unique partition GUID */ + st_qword(buf + ofs + GPTE_FstLba, nxt_alloc); /* Set partition start sector */ + st_qword(buf + ofs + GPTE_LstLba, nxt_alloc + sz_part - 1); /* Set partition end sector */ + nxt_alloc += sz_part; /* Next allocatable sector */ + } + if ((pi + 1) * SZ_GPTE % ss == 0) { /* Write the buffer if it is filled up */ + for (i = 0; i < ss; bcc = crc32(bcc, buf[i++])) ; /* Calculate table check sum */ + if (disk_write(drv, buf, 2 + pi * SZ_GPTE / ss, 1) != RES_OK) return FR_DISK_ERR; /* Write to primary table */ + if (disk_write(drv, buf, top_bpt + pi * SZ_GPTE / ss, 1) != RES_OK) return FR_DISK_ERR; /* Write to secondary table */ + } + } while (++pi < GPT_ITEMS); + + /* Create primary GPT header */ + memset(buf, 0, ss); + memcpy(buf + GPTH_Sign, "EFI PART" "\0\0\1\0" "\x5C\0\0", 16); /* Signature, version (1.0) and size (92) */ + st_dword(buf + GPTH_PtBcc, ~bcc); /* Table check sum */ + st_qword(buf + GPTH_CurLba, 1); /* LBA of this header */ + st_qword(buf + GPTH_BakLba, sz_drv - 1); /* LBA of secondary header */ + st_qword(buf + GPTH_FstLba, 2 + sz_ptbl); /* LBA of first allocatable sector */ + st_qword(buf + GPTH_LstLba, top_bpt - 1); /* LBA of last allocatable sector */ + st_dword(buf + GPTH_PteSize, SZ_GPTE); /* Size of a table entry */ + st_dword(buf + GPTH_PtNum, GPT_ITEMS); /* Number of table entries */ + st_dword(buf + GPTH_PtOfs, 2); /* LBA of this table */ + rnd = make_rand(rnd, buf + GPTH_DskGuid, 16); /* Disk GUID */ + for (i = 0, bcc= 0xFFFFFFFF; i < 92; bcc = crc32(bcc, buf[i++])) ; /* Calculate header check sum */ + st_dword(buf + GPTH_Bcc, ~bcc); /* Header check sum */ + if (disk_write(drv, buf, 1, 1) != RES_OK) return FR_DISK_ERR; + + /* Create secondary GPT header */ + st_qword(buf + GPTH_CurLba, sz_drv - 1); /* LBA of this header */ + st_qword(buf + GPTH_BakLba, 1); /* LBA of primary header */ + st_qword(buf + GPTH_PtOfs, top_bpt); /* LBA of this table */ + st_dword(buf + GPTH_Bcc, 0); + for (i = 0, bcc= 0xFFFFFFFF; i < 92; bcc = crc32(bcc, buf[i++])) ; /* Calculate header check sum */ + st_dword(buf + GPTH_Bcc, ~bcc); /* Header check sum */ + if (disk_write(drv, buf, sz_drv - 1, 1) != RES_OK) return FR_DISK_ERR; + + /* Create protective MBR */ + memset(buf, 0, ss); + memcpy(buf + MBR_Table, gpt_mbr, 16); /* Create a GPT partition */ + st_word(buf + BS_55AA, 0xAA55); + if (disk_write(drv, buf, 0, 1) != RES_OK) return FR_DISK_ERR; + + } else +#endif + { /* Create partitions in MBR format */ + sz_drv32 = (DWORD)sz_drv; + n_sc = N_SEC_TRACK; /* Determine drive CHS without any consideration of the drive geometry */ + for (n_hd = 8; n_hd != 0 && sz_drv32 / n_hd / n_sc > 1024; n_hd *= 2) ; + if (n_hd == 0) n_hd = 255; /* Number of heads needs to be <256 */ + + memset(buf, 0, FF_MAX_SS); /* Clear MBR */ + pte = buf + MBR_Table; /* Partition table in the MBR */ + for (i = 0, nxt_alloc32 = n_sc; i < 4 && nxt_alloc32 != 0 && nxt_alloc32 < sz_drv32; i++, nxt_alloc32 += sz_part32) { + sz_part32 = (DWORD)plst[i]; /* Get partition size */ + if (sz_part32 <= 100) sz_part32 = (sz_part32 == 100) ? sz_drv32 : sz_drv32 / 100 * sz_part32; /* Size in percentage? */ + if (nxt_alloc32 + sz_part32 > sz_drv32 || nxt_alloc32 + sz_part32 < nxt_alloc32) sz_part32 = sz_drv32 - nxt_alloc32; /* Clip at drive size */ + if (sz_part32 == 0) break; /* End of table or no sector to allocate? */ + + st_dword(pte + PTE_StLba, nxt_alloc32); /* Start LBA */ + st_dword(pte + PTE_SizLba, sz_part32); /* Number of sectors */ + pte[PTE_System] = sys; /* System type */ + + cy = (UINT)(nxt_alloc32 / n_sc / n_hd); /* Start cylinder */ + hd = (BYTE)(nxt_alloc32 / n_sc % n_hd); /* Start head */ + sc = (BYTE)(nxt_alloc32 % n_sc + 1); /* Start sector */ + pte[PTE_StHead] = hd; + pte[PTE_StSec] = (BYTE)((cy >> 2 & 0xC0) | sc); + pte[PTE_StCyl] = (BYTE)cy; + + cy = (UINT)((nxt_alloc32 + sz_part32 - 1) / n_sc / n_hd); /* End cylinder */ + hd = (BYTE)((nxt_alloc32 + sz_part32 - 1) / n_sc % n_hd); /* End head */ + sc = (BYTE)((nxt_alloc32 + sz_part32 - 1) % n_sc + 1); /* End sector */ + pte[PTE_EdHead] = hd; + pte[PTE_EdSec] = (BYTE)((cy >> 2 & 0xC0) | sc); + pte[PTE_EdCyl] = (BYTE)cy; + + pte += SZ_PTE; /* Next entry */ + } + + st_word(buf + BS_55AA, 0xAA55); /* MBR signature */ + if (disk_write(drv, buf, 0, 1) != RES_OK) return FR_DISK_ERR; /* Write it to the MBR */ + } + + return FR_OK; +} + + + +FRESULT f_mkfs ( + const TCHAR* path, /* Logical drive number */ + const MKFS_PARM* opt, /* Format options */ + void* work, /* Pointer to working buffer (null: use heap memory) */ + UINT len /* Size of working buffer [byte] */ +) +{ + static const WORD cst[] = {1, 4, 16, 64, 256, 512, 0}; /* Cluster size boundary for FAT volume (4Ks unit) */ + static const WORD cst32[] = {1, 2, 4, 8, 16, 32, 0}; /* Cluster size boundary for FAT32 volume (128Ks unit) */ + static const MKFS_PARM defopt = {FM_ANY, 0, 0, 0, 0, 0, 0, 0}; /* Default parameter */ + BYTE fsopt, fsty, sys, *buf, *pte, pdrv, ipart; + WORD ss; /* Sector size */ + DWORD sz_buf, sz_blk, n_clst, pau, nsect, n, vsn; + LBA_t sz_vol, b_vol, b_fat, b_data; /* Size of volume, Base LBA of volume, fat, data */ + LBA_t sect, lba[2]; + DWORD sz_rsv, sz_fat, sz_dir, sz_au; /* Size of reserved, fat, dir, data, cluster */ + UINT n_fat, n_root, i; /* Index, Number of FATs and Number of roor dir entries */ + int vol; + DSTATUS ds; + FRESULT fr; + + + /* Check mounted drive and clear work area */ + vol = get_ldnumber(&path); /* Get target logical drive */ + if (vol < 0) return FR_INVALID_DRIVE; + if (FatFs[vol]) FatFs[vol]->fs_type = 0; /* Clear the fs object if mounted */ + pdrv = LD2PD(vol); /* Physical drive */ + ipart = LD2PT(vol); /* Partition (0:create as new, 1..:get from partition table) */ + if (!opt) opt = &defopt; /* Use default parameter if it is not given */ + + /* Get physical drive status (sz_drv, sz_blk, ss) */ + ds = disk_initialize(pdrv); + if (ds & STA_NOINIT) return FR_NOT_READY; + if (ds & STA_PROTECT) return FR_WRITE_PROTECTED; + sz_blk = opt->align; + if (sz_blk == 0 && disk_ioctl(pdrv, GET_BLOCK_SIZE, &sz_blk) != RES_OK) sz_blk = 1; + if (sz_blk == 0 || sz_blk > 0x8000 || (sz_blk & (sz_blk - 1))) sz_blk = 1; +#if FF_MAX_SS != FF_MIN_SS + if (disk_ioctl(pdrv, GET_SECTOR_SIZE, &ss) != RES_OK) return FR_DISK_ERR; + if (ss > FF_MAX_SS || ss < FF_MIN_SS || (ss & (ss - 1))) return FR_DISK_ERR; +#else + ss = FF_MAX_SS; +#endif + /* Options for FAT sub-type and FAT parameters */ + fsopt = opt->fmt & (FM_ANY | FM_SFD); + n_fat = (opt->n_fat >= 1 && opt->n_fat <= 2) ? opt->n_fat : 1; + n_root = (opt->n_root >= 1 && opt->n_root <= 32768 && (opt->n_root % (ss / SZDIRE)) == 0) ? opt->n_root : 512; + sz_au = (opt->au_size <= 0x1000000 && (opt->au_size & (opt->au_size - 1)) == 0) ? opt->au_size : 0; + sz_au /= ss; /* Byte --> Sector */ + + /* Get working buffer */ + sz_buf = len / ss; /* Size of working buffer [sector] */ + if (sz_buf == 0) return FR_NOT_ENOUGH_CORE; + buf = (BYTE*)work; /* Working buffer */ +#if FF_USE_LFN == 3 + if (!buf) buf = ff_memalloc(sz_buf * ss); /* Use heap memory for working buffer */ +#endif + if (!buf) return FR_NOT_ENOUGH_CORE; + + /* Determine where the volume to be located (b_vol, sz_vol) */ + b_vol = sz_vol = 0; + if (FF_MULTI_PARTITION && ipart != 0) { /* Is the volume associated with any specific partition? */ + /* Get partition location from the existing partition table */ + if (disk_read(pdrv, buf, 0, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); /* Load MBR */ + if (ld_word(buf + BS_55AA) != 0xAA55) LEAVE_MKFS(FR_MKFS_ABORTED); /* Check if MBR is valid */ +#if FF_LBA64 + if (buf[MBR_Table + PTE_System] == 0xEE) { /* GPT protective MBR? */ + DWORD n_ent, ofs; + QWORD pt_lba; + + /* Get the partition location from GPT */ + if (disk_read(pdrv, buf, 1, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); /* Load GPT header sector (next to MBR) */ + if (!test_gpt_header(buf)) LEAVE_MKFS(FR_MKFS_ABORTED); /* Check if GPT header is valid */ + n_ent = ld_dword(buf + GPTH_PtNum); /* Number of entries */ + pt_lba = ld_qword(buf + GPTH_PtOfs); /* Table start sector */ + ofs = i = 0; + while (n_ent) { /* Find MS Basic partition with order of ipart */ + if (ofs == 0 && disk_read(pdrv, buf, pt_lba++, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); /* Get PT sector */ + if (!memcmp(buf + ofs + GPTE_PtGuid, GUID_MS_Basic, 16) && ++i == ipart) { /* MS basic data partition? */ + b_vol = ld_qword(buf + ofs + GPTE_FstLba); + sz_vol = ld_qword(buf + ofs + GPTE_LstLba) - b_vol + 1; + break; + } + n_ent--; ofs = (ofs + SZ_GPTE) % ss; /* Next entry */ + } + if (n_ent == 0) LEAVE_MKFS(FR_MKFS_ABORTED); /* Partition not found */ + fsopt |= 0x80; /* Partitioning is in GPT */ + } else +#endif + { /* Get the partition location from MBR partition table */ + pte = buf + (MBR_Table + (ipart - 1) * SZ_PTE); + if (ipart > 4 || pte[PTE_System] == 0) LEAVE_MKFS(FR_MKFS_ABORTED); /* No partition? */ + b_vol = ld_dword(pte + PTE_StLba); /* Get volume start sector */ + sz_vol = ld_dword(pte + PTE_SizLba); /* Get volume size */ + } + } else { /* The volume is associated with a physical drive */ + if (disk_ioctl(pdrv, GET_SECTOR_COUNT, &sz_vol) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); + if (!(fsopt & FM_SFD)) { /* To be partitioned? */ + /* Create a single-partition on the drive in this function */ +#if FF_LBA64 + if (sz_vol >= FF_MIN_GPT) { /* Which partition type to create, MBR or GPT? */ + fsopt |= 0x80; /* Partitioning is in GPT */ + b_vol = GPT_ALIGN / ss; sz_vol -= b_vol + GPT_ITEMS * SZ_GPTE / ss + 1; /* Estimated partition offset and size */ + } else +#endif + { /* Partitioning is in MBR */ + if (sz_vol > N_SEC_TRACK) { + b_vol = N_SEC_TRACK; sz_vol -= b_vol; /* Estimated partition offset and size */ + } + } + } + } + if (sz_vol < 128) LEAVE_MKFS(FR_MKFS_ABORTED); /* Check if volume size is >=128s */ + + /* Now start to create an FAT volume at b_vol and sz_vol */ + + do { /* Pre-determine the FAT type */ + if (FF_FS_EXFAT && (fsopt & FM_EXFAT)) { /* exFAT possible? */ + if ((fsopt & FM_ANY) == FM_EXFAT || sz_vol >= 0x4000000 || sz_au > 128) { /* exFAT only, vol >= 64MS or sz_au > 128S ? */ + fsty = FS_EXFAT; break; + } + } +#if FF_LBA64 + if (sz_vol >= 0x100000000) LEAVE_MKFS(FR_MKFS_ABORTED); /* Too large volume for FAT/FAT32 */ +#endif + if (sz_au > 128) sz_au = 128; /* Invalid AU for FAT/FAT32? */ + if (fsopt & FM_FAT32) { /* FAT32 possible? */ + if (!(fsopt & FM_FAT)) { /* no-FAT? */ + fsty = FS_FAT32; break; + } + } + if (!(fsopt & FM_FAT)) LEAVE_MKFS(FR_INVALID_PARAMETER); /* no-FAT? */ + fsty = FS_FAT16; + } while (0); + + vsn = (DWORD)sz_vol + GET_FATTIME(); /* VSN generated from current time and partitiion size */ + +#if FF_FS_EXFAT + if (fsty == FS_EXFAT) { /* Create an exFAT volume */ + DWORD szb_bit, szb_case, sum, nbit, clu, clen[3]; + WCHAR ch, si; + UINT j, st; + + if (sz_vol < 0x1000) LEAVE_MKFS(FR_MKFS_ABORTED); /* Too small volume for exFAT? */ +#if FF_USE_TRIM + lba[0] = b_vol; lba[1] = b_vol + sz_vol - 1; /* Inform storage device that the volume area may be erased */ + disk_ioctl(pdrv, CTRL_TRIM, lba); +#endif + /* Determine FAT location, data location and number of clusters */ + if (sz_au == 0) { /* AU auto-selection */ + sz_au = 8; + if (sz_vol >= 0x80000) sz_au = 64; /* >= 512Ks */ + if (sz_vol >= 0x4000000) sz_au = 256; /* >= 64Ms */ + } + b_fat = b_vol + 32; /* FAT start at offset 32 */ + sz_fat = (DWORD)((sz_vol / sz_au + 2) * 4 + ss - 1) / ss; /* Number of FAT sectors */ + b_data = (b_fat + sz_fat + sz_blk - 1) & ~((LBA_t)sz_blk - 1); /* Align data area to the erase block boundary */ + if (b_data - b_vol >= sz_vol / 2) LEAVE_MKFS(FR_MKFS_ABORTED); /* Too small volume? */ + n_clst = (DWORD)(sz_vol - (b_data - b_vol)) / sz_au; /* Number of clusters */ + if (n_clst <16) LEAVE_MKFS(FR_MKFS_ABORTED); /* Too few clusters? */ + if (n_clst > MAX_EXFAT) LEAVE_MKFS(FR_MKFS_ABORTED); /* Too many clusters? */ + + szb_bit = (n_clst + 7) / 8; /* Size of allocation bitmap */ + clen[0] = (szb_bit + sz_au * ss - 1) / (sz_au * ss); /* Number of allocation bitmap clusters */ + + /* Create a compressed up-case table */ + sect = b_data + sz_au * clen[0]; /* Table start sector */ + sum = 0; /* Table checksum to be stored in the 82 entry */ + st = 0; si = 0; i = 0; j = 0; szb_case = 0; + do { + switch (st) { + case 0: + ch = (WCHAR)ff_wtoupper(si); /* Get an up-case char */ + if (ch != si) { + si++; break; /* Store the up-case char if exist */ + } + for (j = 1; (WCHAR)(si + j) && (WCHAR)(si + j) == ff_wtoupper((WCHAR)(si + j)); j++) ; /* Get run length of no-case block */ + if (j >= 128) { + ch = 0xFFFF; st = 2; break; /* Compress the no-case block if run is >= 128 chars */ + } + st = 1; /* Do not compress short run */ + /* FALLTHROUGH */ + case 1: + ch = si++; /* Fill the short run */ + if (--j == 0) st = 0; + break; + + default: + ch = (WCHAR)j; si += (WCHAR)j; /* Number of chars to skip */ + st = 0; + } + sum = xsum32(buf[i + 0] = (BYTE)ch, sum); /* Put it into the write buffer */ + sum = xsum32(buf[i + 1] = (BYTE)(ch >> 8), sum); + i += 2; szb_case += 2; + if (si == 0 || i == sz_buf * ss) { /* Write buffered data when buffer full or end of process */ + n = (i + ss - 1) / ss; + if (disk_write(pdrv, buf, sect, n) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); + sect += n; i = 0; + } + } while (si); + clen[1] = (szb_case + sz_au * ss - 1) / (sz_au * ss); /* Number of up-case table clusters */ + clen[2] = 1; /* Number of root dir clusters */ + + /* Initialize the allocation bitmap */ + sect = b_data; nsect = (szb_bit + ss - 1) / ss; /* Start of bitmap and number of bitmap sectors */ + nbit = clen[0] + clen[1] + clen[2]; /* Number of clusters in-use by system (bitmap, up-case and root-dir) */ + do { + memset(buf, 0, sz_buf * ss); /* Initialize bitmap buffer */ + for (i = 0; nbit != 0 && i / 8 < sz_buf * ss; buf[i / 8] |= 1 << (i % 8), i++, nbit--) ; /* Mark used clusters */ + n = (nsect > sz_buf) ? sz_buf : nsect; /* Write the buffered data */ + if (disk_write(pdrv, buf, sect, n) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); + sect += n; nsect -= n; + } while (nsect); + + /* Initialize the FAT */ + sect = b_fat; nsect = sz_fat; /* Start of FAT and number of FAT sectors */ + j = nbit = clu = 0; + do { + memset(buf, 0, sz_buf * ss); i = 0; /* Clear work area and reset write offset */ + if (clu == 0) { /* Initialize FAT [0] and FAT[1] */ + st_dword(buf + i, 0xFFFFFFF8); i += 4; clu++; + st_dword(buf + i, 0xFFFFFFFF); i += 4; clu++; + } + do { /* Create chains of bitmap, up-case and root dir */ + while (nbit != 0 && i < sz_buf * ss) { /* Create a chain */ + st_dword(buf + i, (nbit > 1) ? clu + 1 : 0xFFFFFFFF); + i += 4; clu++; nbit--; + } + if (nbit == 0 && j < 3) nbit = clen[j++]; /* Get next chain length */ + } while (nbit != 0 && i < sz_buf * ss); + n = (nsect > sz_buf) ? sz_buf : nsect; /* Write the buffered data */ + if (disk_write(pdrv, buf, sect, n) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); + sect += n; nsect -= n; + } while (nsect); + + /* Initialize the root directory */ + memset(buf, 0, sz_buf * ss); + buf[SZDIRE * 0 + 0] = ET_VLABEL; /* Volume label entry (no label) */ + buf[SZDIRE * 1 + 0] = ET_BITMAP; /* Bitmap entry */ + st_dword(buf + SZDIRE * 1 + 20, 2); /* cluster */ + st_dword(buf + SZDIRE * 1 + 24, szb_bit); /* size */ + buf[SZDIRE * 2 + 0] = ET_UPCASE; /* Up-case table entry */ + st_dword(buf + SZDIRE * 2 + 4, sum); /* sum */ + st_dword(buf + SZDIRE * 2 + 20, 2 + clen[0]); /* cluster */ + st_dword(buf + SZDIRE * 2 + 24, szb_case); /* size */ + sect = b_data + sz_au * (clen[0] + clen[1]); nsect = sz_au; /* Start of the root directory and number of sectors */ + do { /* Fill root directory sectors */ + n = (nsect > sz_buf) ? sz_buf : nsect; + if (disk_write(pdrv, buf, sect, n) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); + memset(buf, 0, ss); /* Rest of entries are filled with zero */ + sect += n; nsect -= n; + } while (nsect); + + /* Create two set of the exFAT VBR blocks */ + sect = b_vol; + for (n = 0; n < 2; n++) { + /* Main record (+0) */ + memset(buf, 0, ss); + memcpy(buf + BS_JmpBoot, "\xEB\x76\x90" "EXFAT ", 11); /* Boot jump code (x86), OEM name */ + st_qword(buf + BPB_VolOfsEx, b_vol); /* Volume offset in the physical drive [sector] */ + st_qword(buf + BPB_TotSecEx, sz_vol); /* Volume size [sector] */ + st_dword(buf + BPB_FatOfsEx, (DWORD)(b_fat - b_vol)); /* FAT offset [sector] */ + st_dword(buf + BPB_FatSzEx, sz_fat); /* FAT size [sector] */ + st_dword(buf + BPB_DataOfsEx, (DWORD)(b_data - b_vol)); /* Data offset [sector] */ + st_dword(buf + BPB_NumClusEx, n_clst); /* Number of clusters */ + st_dword(buf + BPB_RootClusEx, 2 + clen[0] + clen[1]); /* Root dir cluster # */ + st_dword(buf + BPB_VolIDEx, vsn); /* VSN */ + st_word(buf + BPB_FSVerEx, 0x100); /* Filesystem version (1.00) */ + for (buf[BPB_BytsPerSecEx] = 0, i = ss; i >>= 1; buf[BPB_BytsPerSecEx]++) ; /* Log2 of sector size [byte] */ + for (buf[BPB_SecPerClusEx] = 0, i = sz_au; i >>= 1; buf[BPB_SecPerClusEx]++) ; /* Log2 of cluster size [sector] */ + buf[BPB_NumFATsEx] = 1; /* Number of FATs */ + buf[BPB_DrvNumEx] = 0x80; /* Drive number (for int13) */ + st_word(buf + BS_BootCodeEx, 0xFEEB); /* Boot code (x86) */ + st_word(buf + BS_55AA, 0xAA55); /* Signature (placed here regardless of sector size) */ + for (i = sum = 0; i < ss; i++) { /* VBR checksum */ + if (i != BPB_VolFlagEx && i != BPB_VolFlagEx + 1 && i != BPB_PercInUseEx) sum = xsum32(buf[i], sum); + } + if (disk_write(pdrv, buf, sect++, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); + /* Extended bootstrap record (+1..+8) */ + memset(buf, 0, ss); + st_word(buf + ss - 2, 0xAA55); /* Signature (placed at end of sector) */ + for (j = 1; j < 9; j++) { + for (i = 0; i < ss; sum = xsum32(buf[i++], sum)) ; /* VBR checksum */ + if (disk_write(pdrv, buf, sect++, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); + } + /* OEM/Reserved record (+9..+10) */ + memset(buf, 0, ss); + for ( ; j < 11; j++) { + for (i = 0; i < ss; sum = xsum32(buf[i++], sum)) ; /* VBR checksum */ + if (disk_write(pdrv, buf, sect++, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); + } + /* Sum record (+11) */ + for (i = 0; i < ss; i += 4) st_dword(buf + i, sum); /* Fill with checksum value */ + if (disk_write(pdrv, buf, sect++, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); + } + + } else +#endif /* FF_FS_EXFAT */ + { /* Create an FAT/FAT32 volume */ + do { + pau = sz_au; + /* Pre-determine number of clusters and FAT sub-type */ + if (fsty == FS_FAT32) { /* FAT32 volume */ + if (pau == 0) { /* AU auto-selection */ + n = (DWORD)sz_vol / 0x20000; /* Volume size in unit of 128KS */ + for (i = 0, pau = 1; cst32[i] && cst32[i] <= n; i++, pau <<= 1) ; /* Get from table */ + } + n_clst = (DWORD)sz_vol / pau; /* Number of clusters */ + sz_fat = (n_clst * 4 + 8 + ss - 1) / ss; /* FAT size [sector] */ + sz_rsv = 32; /* Number of reserved sectors */ + sz_dir = 0; /* No static directory */ + if (n_clst <= MAX_FAT16 || n_clst > MAX_FAT32) LEAVE_MKFS(FR_MKFS_ABORTED); + } else { /* FAT volume */ + if (pau == 0) { /* au auto-selection */ + n = (DWORD)sz_vol / 0x1000; /* Volume size in unit of 4KS */ + for (i = 0, pau = 1; cst[i] && cst[i] <= n; i++, pau <<= 1) ; /* Get from table */ + } + n_clst = (DWORD)sz_vol / pau; + if (n_clst > MAX_FAT12) { + n = n_clst * 2 + 4; /* FAT size [byte] */ + } else { + fsty = FS_FAT12; + n = (n_clst * 3 + 1) / 2 + 3; /* FAT size [byte] */ + } + sz_fat = (n + ss - 1) / ss; /* FAT size [sector] */ + sz_rsv = 1; /* Number of reserved sectors */ + sz_dir = (DWORD)n_root * SZDIRE / ss; /* Root dir size [sector] */ + } + b_fat = b_vol + sz_rsv; /* FAT base */ + b_data = b_fat + sz_fat * n_fat + sz_dir; /* Data base */ + + /* Align data area to erase block boundary (for flash memory media) */ + n = (DWORD)(((b_data + sz_blk - 1) & ~(sz_blk - 1)) - b_data); /* Sectors to next nearest from current data base */ + if (fsty == FS_FAT32) { /* FAT32: Move FAT */ + sz_rsv += n; b_fat += n; + } else { /* FAT: Expand FAT */ + if (n % n_fat) { /* Adjust fractional error if needed */ + n--; sz_rsv++; b_fat++; + } + sz_fat += n / n_fat; + } + + /* Determine number of clusters and final check of validity of the FAT sub-type */ + if (sz_vol < b_data + pau * 16 - b_vol) LEAVE_MKFS(FR_MKFS_ABORTED); /* Too small volume? */ + n_clst = ((DWORD)sz_vol - sz_rsv - sz_fat * n_fat - sz_dir) / pau; + if (fsty == FS_FAT32) { + if (n_clst <= MAX_FAT16) { /* Too few clusters for FAT32? */ + if (sz_au == 0 && (sz_au = pau / 2) != 0) continue; /* Adjust cluster size and retry */ + LEAVE_MKFS(FR_MKFS_ABORTED); + } + } + if (fsty == FS_FAT16) { + if (n_clst > MAX_FAT16) { /* Too many clusters for FAT16 */ + if (sz_au == 0 && (pau * 2) <= 64) { + sz_au = pau * 2; continue; /* Adjust cluster size and retry */ + } + if ((fsopt & FM_FAT32)) { + fsty = FS_FAT32; continue; /* Switch type to FAT32 and retry */ + } + if (sz_au == 0 && (sz_au = pau * 2) <= 128) continue; /* Adjust cluster size and retry */ + LEAVE_MKFS(FR_MKFS_ABORTED); + } + if (n_clst <= MAX_FAT12) { /* Too few clusters for FAT16 */ + if (sz_au == 0 && (sz_au = pau * 2) <= 128) continue; /* Adjust cluster size and retry */ + LEAVE_MKFS(FR_MKFS_ABORTED); + } + } + if (fsty == FS_FAT12 && n_clst > MAX_FAT12) LEAVE_MKFS(FR_MKFS_ABORTED); /* Too many clusters for FAT12 */ + + /* Ok, it is the valid cluster configuration */ + break; + } while (1); + +#if FF_USE_TRIM + lba[0] = b_vol; lba[1] = b_vol + sz_vol - 1; /* Inform storage device that the volume area may be erased */ + disk_ioctl(pdrv, CTRL_TRIM, lba); +#endif + /* Create FAT VBR */ + memset(buf, 0, ss); + memcpy(buf + BS_JmpBoot, "\xEB\xFE\x90" "MSDOS5.0", 11); /* Boot jump code (x86), OEM name */ + st_word(buf + BPB_BytsPerSec, ss); /* Sector size [byte] */ + buf[BPB_SecPerClus] = (BYTE)pau; /* Cluster size [sector] */ + st_word(buf + BPB_RsvdSecCnt, (WORD)sz_rsv); /* Size of reserved area */ + buf[BPB_NumFATs] = (BYTE)n_fat; /* Number of FATs */ + st_word(buf + BPB_RootEntCnt, (WORD)((fsty == FS_FAT32) ? 0 : n_root)); /* Number of root directory entries */ + if (sz_vol < 0x10000) { + st_word(buf + BPB_TotSec16, (WORD)sz_vol); /* Volume size in 16-bit LBA */ + } else { + st_dword(buf + BPB_TotSec32, (DWORD)sz_vol); /* Volume size in 32-bit LBA */ + } + + buf[BPB_Media] = opt->media; /* Media descriptor byte */ + st_word(buf + BPB_SecPerTrk, opt->n_sec_track); /* Number of sectors per track (for int13) */ + st_word(buf + BPB_NumHeads, opt->n_heads); /* Number of heads (for int13) */ + st_dword(buf + BPB_HiddSec, (DWORD)b_vol); /* Volume offset in the physical drive [sector] */ + if (fsty == FS_FAT32) { + st_dword(buf + BS_VolID32, vsn); /* VSN */ + st_dword(buf + BPB_FATSz32, sz_fat); /* FAT size [sector] */ + st_dword(buf + BPB_RootClus32, 2); /* Root directory cluster # (2) */ + st_word(buf + BPB_FSInfo32, 1); /* Offset of FSINFO sector (VBR + 1) */ + st_word(buf + BPB_BkBootSec32, 6); /* Offset of backup VBR (VBR + 6) */ + buf[BS_DrvNum32] = 0x80; /* Drive number (for int13) */ + buf[BS_BootSig32] = 0x29; /* Extended boot signature */ + memcpy(buf + BS_VolLab32, "NO NAME " "FAT32 ", 19); /* Volume label, FAT signature */ + } else { + st_dword(buf + BS_VolID, vsn); /* VSN */ + st_word(buf + BPB_FATSz16, (WORD)sz_fat); /* FAT size [sector] */ + buf[BS_DrvNum] = 0x80; /* Drive number (for int13) */ + buf[BS_BootSig] = 0x29; /* Extended boot signature */ + memcpy(buf + BS_VolLab, "NO NAME " "FAT ", 19); /* Volume label, FAT signature */ + } + st_word(buf + BS_55AA, 0xAA55); /* Signature (offset is fixed here regardless of sector size) */ + if (disk_write(pdrv, buf, b_vol, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); /* Write it to the VBR sector */ + + /* Create FSINFO record if needed */ + if (fsty == FS_FAT32) { + disk_write(pdrv, buf, b_vol + 6, 1); /* Write backup VBR (VBR + 6) */ + memset(buf, 0, ss); + st_dword(buf + FSI_LeadSig, 0x41615252); + st_dword(buf + FSI_StrucSig, 0x61417272); + st_dword(buf + FSI_Free_Count, n_clst - 1); /* Number of free clusters */ + st_dword(buf + FSI_Nxt_Free, 2); /* Last allocated cluster# */ + st_word(buf + BS_55AA, 0xAA55); + disk_write(pdrv, buf, b_vol + 7, 1); /* Write backup FSINFO (VBR + 7) */ + disk_write(pdrv, buf, b_vol + 1, 1); /* Write original FSINFO (VBR + 1) */ + } + + /* Initialize FAT area */ + memset(buf, 0, sz_buf * ss); + sect = b_fat; /* FAT start sector */ + for (i = 0; i < n_fat; i++) { /* Initialize FATs each */ + if (fsty == FS_FAT32) { + st_dword(buf + 0, 0xFFFFFF00 | opt->media); /* FAT[0] */ + st_dword(buf + 4, 0xFFFFFFFF); /* FAT[1] */ + st_dword(buf + 8, 0x0FFFFFFF); /* FAT[2] (root directory) */ + } else { + st_dword(buf + 0, ((fsty == FS_FAT12) ? 0xFFFF00 : 0xFFFFFF00) | opt->media); /* FAT[0] and FAT[1] */ + } + nsect = sz_fat; /* Number of FAT sectors */ + do { /* Fill FAT sectors */ + n = (nsect > sz_buf) ? sz_buf : nsect; + if (disk_write(pdrv, buf, sect, (UINT)n) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); + memset(buf, 0, ss); /* Rest of FAT all are cleared */ + sect += n; nsect -= n; + } while (nsect); + } + + /* Initialize root directory (fill with zero) */ + nsect = (fsty == FS_FAT32) ? pau : sz_dir; /* Number of root directory sectors */ + do { + n = (nsect > sz_buf) ? sz_buf : nsect; + if (disk_write(pdrv, buf, sect, (UINT)n) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); + sect += n; nsect -= n; + } while (nsect); + } + + /* A FAT volume has been created here */ + + /* Determine system ID in the MBR partition table */ + if (FF_FS_EXFAT && fsty == FS_EXFAT) { + sys = 0x07; /* exFAT */ + } else { + if (fsty == FS_FAT32) { + sys = 0x0C; /* FAT32X */ + } else { + if (sz_vol >= 0x10000) { + sys = 0x06; /* FAT12/16 (large) */ + } else { + sys = (fsty == FS_FAT16) ? 0x04 : 0x01; /* FAT16 : FAT12 */ + } + } + } + + /* Update partition information */ + if (FF_MULTI_PARTITION && ipart != 0) { /* Volume is in the existing partition */ + if (!FF_LBA64 || !(fsopt & 0x80)) { + /* Update system ID in the partition table */ + if (disk_read(pdrv, buf, 0, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); /* Read the MBR */ + buf[MBR_Table + (ipart - 1) * SZ_PTE + PTE_System] = sys; /* Set system ID */ + if (disk_write(pdrv, buf, 0, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); /* Write it back to the MBR */ + } + } else { /* Volume as a new single partition */ + if (!(fsopt & FM_SFD)) { /* Create partition table if not in SFD */ + lba[0] = sz_vol; lba[1] = 0; + fr = create_partition(pdrv, lba, sys, buf); + if (fr != FR_OK) LEAVE_MKFS(fr); + } + } + + if (disk_ioctl(pdrv, CTRL_SYNC, 0) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); + + LEAVE_MKFS(FR_OK); +} + + + + +#if FF_MULTI_PARTITION +/*-----------------------------------------------------------------------*/ +/* Create Partition Table on the Physical Drive */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_fdisk ( + BYTE pdrv, /* Physical drive number */ + const LBA_t ptbl[], /* Pointer to the size table for each partitions */ + void* work /* Pointer to the working buffer (null: use heap memory) */ +) +{ + BYTE *buf = (BYTE*)work; + DSTATUS stat; + + + stat = disk_initialize(pdrv); + if (stat & STA_NOINIT) return FR_NOT_READY; + if (stat & STA_PROTECT) return FR_WRITE_PROTECTED; +#if FF_USE_LFN == 3 + if (!buf) buf = ff_memalloc(FF_MAX_SS); /* Use heap memory for working buffer */ +#endif + if (!buf) return FR_NOT_ENOUGH_CORE; + + LEAVE_MKFS(create_partition(pdrv, ptbl, 0x07, buf)); +} + +#endif /* FF_MULTI_PARTITION */ +#endif /* !FF_FS_READONLY && FF_USE_MKFS */ + + + + +#if FF_USE_STRFUNC +#if FF_USE_LFN && FF_LFN_UNICODE && (FF_STRF_ENCODE < 0 || FF_STRF_ENCODE > 3) +#error Wrong FF_STRF_ENCODE setting +#endif +/*-----------------------------------------------------------------------*/ +/* Get a String from the File */ +/*-----------------------------------------------------------------------*/ + +TCHAR* f_gets ( + TCHAR* buff, /* Pointer to the buffer to store read string */ + int len, /* Size of string buffer (items) */ + FIL* fp /* Pointer to the file object */ +) +{ + int nc = 0; + TCHAR *p = buff; + BYTE s[4]; + UINT rc; + DWORD dc; +#if FF_USE_LFN && FF_LFN_UNICODE && FF_STRF_ENCODE <= 2 + WCHAR wc; +#endif +#if FF_USE_LFN && FF_LFN_UNICODE && FF_STRF_ENCODE == 3 + UINT ct; +#endif + +#if FF_USE_LFN && FF_LFN_UNICODE /* With code conversion (Unicode API) */ + /* Make a room for the character and terminator */ + if (FF_LFN_UNICODE == 1) len -= (FF_STRF_ENCODE == 0) ? 1 : 2; + if (FF_LFN_UNICODE == 2) len -= (FF_STRF_ENCODE == 0) ? 3 : 4; + if (FF_LFN_UNICODE == 3) len -= 1; + while (nc < len) { +#if FF_STRF_ENCODE == 0 /* Read a character in ANSI/OEM */ + f_read(fp, s, 1, &rc); /* Get a code unit */ + if (rc != 1) break; /* EOF? */ + wc = s[0]; + if (dbc_1st((BYTE)wc)) { /* DBC 1st byte? */ + f_read(fp, s, 1, &rc); /* Get 2nd byte */ + if (rc != 1 || !dbc_2nd(s[0])) continue; /* Wrong code? */ + wc = wc << 8 | s[0]; + } + dc = ff_oem2uni(wc, CODEPAGE); /* Convert ANSI/OEM into Unicode */ + if (dc == 0) continue; /* Conversion error? */ +#elif FF_STRF_ENCODE == 1 || FF_STRF_ENCODE == 2 /* Read a character in UTF-16LE/BE */ + f_read(fp, s, 2, &rc); /* Get a code unit */ + if (rc != 2) break; /* EOF? */ + dc = (FF_STRF_ENCODE == 1) ? ld_word(s) : s[0] << 8 | s[1]; + if (IsSurrogateL(dc)) continue; /* Broken surrogate pair? */ + if (IsSurrogateH(dc)) { /* High surrogate? */ + f_read(fp, s, 2, &rc); /* Get low surrogate */ + if (rc != 2) break; /* EOF? */ + wc = (FF_STRF_ENCODE == 1) ? ld_word(s) : s[0] << 8 | s[1]; + if (!IsSurrogateL(wc)) continue; /* Broken surrogate pair? */ + dc = ((dc & 0x3FF) + 0x40) << 10 | (wc & 0x3FF); /* Merge surrogate pair */ + } +#else /* Read a character in UTF-8 */ + f_read(fp, s, 1, &rc); /* Get a code unit */ + if (rc != 1) break; /* EOF? */ + dc = s[0]; + if (dc >= 0x80) { /* Multi-byte sequence? */ + ct = 0; + if ((dc & 0xE0) == 0xC0) { dc &= 0x1F; ct = 1; } /* 2-byte sequence? */ + if ((dc & 0xF0) == 0xE0) { dc &= 0x0F; ct = 2; } /* 3-byte sequence? */ + if ((dc & 0xF8) == 0xF0) { dc &= 0x07; ct = 3; } /* 4-byte sequence? */ + if (ct == 0) continue; + f_read(fp, s, ct, &rc); /* Get trailing bytes */ + if (rc != ct) break; + rc = 0; + do { /* Merge the byte sequence */ + if ((s[rc] & 0xC0) != 0x80) break; + dc = dc << 6 | (s[rc] & 0x3F); + } while (++rc < ct); + if (rc != ct || dc < 0x80 || IsSurrogate(dc) || dc >= 0x110000) continue; /* Wrong encoding? */ + } +#endif + /* A code point is avaialble in dc to be output */ + + if (FF_USE_STRFUNC == 2 && dc == '\r') continue; /* Strip \r off if needed */ +#if FF_LFN_UNICODE == 1 || FF_LFN_UNICODE == 3 /* Output it in UTF-16/32 encoding */ + if (FF_LFN_UNICODE == 1 && dc >= 0x10000) { /* Out of BMP at UTF-16? */ + *p++ = (TCHAR)(0xD800 | ((dc >> 10) - 0x40)); nc++; /* Make and output high surrogate */ + dc = 0xDC00 | (dc & 0x3FF); /* Make low surrogate */ + } + *p++ = (TCHAR)dc; nc++; + if (dc == '\n') break; /* End of line? */ +#elif FF_LFN_UNICODE == 2 /* Output it in UTF-8 encoding */ + if (dc < 0x80) { /* Single byte? */ + *p++ = (TCHAR)dc; + nc++; + if (dc == '\n') break; /* End of line? */ + } else { + if (dc < 0x800) { /* 2-byte sequence? */ + *p++ = (TCHAR)(0xC0 | (dc >> 6 & 0x1F)); + *p++ = (TCHAR)(0x80 | (dc >> 0 & 0x3F)); + nc += 2; + } else { + if (dc < 0x10000) { /* 3-byte sequence? */ + *p++ = (TCHAR)(0xE0 | (dc >> 12 & 0x0F)); + *p++ = (TCHAR)(0x80 | (dc >> 6 & 0x3F)); + *p++ = (TCHAR)(0x80 | (dc >> 0 & 0x3F)); + nc += 3; + } else { /* 4-byte sequence? */ + *p++ = (TCHAR)(0xF0 | (dc >> 18 & 0x07)); + *p++ = (TCHAR)(0x80 | (dc >> 12 & 0x3F)); + *p++ = (TCHAR)(0x80 | (dc >> 6 & 0x3F)); + *p++ = (TCHAR)(0x80 | (dc >> 0 & 0x3F)); + nc += 4; + } + } + } +#endif + } + +#else /* Byte-by-byte read without any conversion (ANSI/OEM API) */ + len -= 1; /* Make a room for the terminator */ + while (nc < len) { + f_read(fp, s, 1, &rc); /* Get a byte */ + if (rc != 1) break; /* EOF? */ + dc = s[0]; + if (FF_USE_STRFUNC == 2 && dc == '\r') continue; + *p++ = (TCHAR)dc; nc++; + if (dc == '\n') break; + } +#endif + + *p = 0; /* Terminate the string */ + return nc ? buff : 0; /* When no data read due to EOF or error, return with error. */ +} + + + + +#if !FF_FS_READONLY +#include +#define SZ_PUTC_BUF 64 +#define SZ_NUM_BUF 32 + +/*-----------------------------------------------------------------------*/ +/* Put a Character to the File (with sub-functions) */ +/*-----------------------------------------------------------------------*/ + +/* Output buffer and work area */ + +typedef struct { + FIL *fp; /* Ptr to the writing file */ + int idx, nchr; /* Write index of buf[] (-1:error), number of encoding units written */ +#if FF_USE_LFN && FF_LFN_UNICODE == 1 + WCHAR hs; +#elif FF_USE_LFN && FF_LFN_UNICODE == 2 + BYTE bs[4]; + UINT wi, ct; +#endif + BYTE buf[SZ_PUTC_BUF]; /* Write buffer */ +} putbuff; + + +/* Buffered file write with code conversion */ + +static void putc_bfd (putbuff* pb, TCHAR c) +{ + UINT n; + int i, nc; +#if FF_USE_LFN && FF_LFN_UNICODE + WCHAR hs, wc; +#if FF_LFN_UNICODE == 2 + DWORD dc; + const TCHAR *tp; +#endif +#endif + + if (FF_USE_STRFUNC == 2 && c == '\n') { /* LF -> CRLF conversion */ + putc_bfd(pb, '\r'); + } + + i = pb->idx; /* Write index of pb->buf[] */ + if (i < 0) return; /* In write error? */ + nc = pb->nchr; /* Write unit counter */ + +#if FF_USE_LFN && FF_LFN_UNICODE +#if FF_LFN_UNICODE == 1 /* UTF-16 input */ + if (IsSurrogateH(c)) { /* High surrogate? */ + pb->hs = c; return; /* Save it for next */ + } + hs = pb->hs; pb->hs = 0; + if (hs != 0) { /* There is a leading high surrogate */ + if (!IsSurrogateL(c)) hs = 0; /* Discard high surrogate if not a surrogate pair */ + } else { + if (IsSurrogateL(c)) return; /* Discard stray low surrogate */ + } + wc = c; +#elif FF_LFN_UNICODE == 2 /* UTF-8 input */ + for (;;) { + if (pb->ct == 0) { /* Out of multi-byte sequence? */ + pb->bs[pb->wi = 0] = (BYTE)c; /* Save 1st byte */ + if ((BYTE)c < 0x80) break; /* Single byte? */ + if (((BYTE)c & 0xE0) == 0xC0) pb->ct = 1; /* 2-byte sequence? */ + if (((BYTE)c & 0xF0) == 0xE0) pb->ct = 2; /* 3-byte sequence? */ + if (((BYTE)c & 0xF1) == 0xF0) pb->ct = 3; /* 4-byte sequence? */ + return; + } else { /* In the multi-byte sequence */ + if (((BYTE)c & 0xC0) != 0x80) { /* Broken sequence? */ + pb->ct = 0; continue; + } + pb->bs[++pb->wi] = (BYTE)c; /* Save the trailing byte */ + if (--pb->ct == 0) break; /* End of multi-byte sequence? */ + return; + } + } + tp = (const TCHAR*)pb->bs; + dc = tchar2uni(&tp); /* UTF-8 ==> UTF-16 */ + if (dc == 0xFFFFFFFF) return; /* Wrong code? */ + wc = (WCHAR)dc; + hs = (WCHAR)(dc >> 16); +#elif FF_LFN_UNICODE == 3 /* UTF-32 input */ + if (IsSurrogate(c) || c >= 0x110000) return; /* Discard invalid code */ + if (c >= 0x10000) { /* Out of BMP? */ + hs = (WCHAR)(0xD800 | ((c >> 10) - 0x40)); /* Make high surrogate */ + wc = 0xDC00 | (c & 0x3FF); /* Make low surrogate */ + } else { + hs = 0; + wc = (WCHAR)c; + } +#endif + /* A code point in UTF-16 is available in hs and wc */ + +#if FF_STRF_ENCODE == 1 /* Write a code point in UTF-16LE */ + if (hs != 0) { /* Surrogate pair? */ + st_word(&pb->buf[i], hs); + i += 2; + nc++; + } + st_word(&pb->buf[i], wc); + i += 2; +#elif FF_STRF_ENCODE == 2 /* Write a code point in UTF-16BE */ + if (hs != 0) { /* Surrogate pair? */ + pb->buf[i++] = (BYTE)(hs >> 8); + pb->buf[i++] = (BYTE)hs; + nc++; + } + pb->buf[i++] = (BYTE)(wc >> 8); + pb->buf[i++] = (BYTE)wc; +#elif FF_STRF_ENCODE == 3 /* Write a code point in UTF-8 */ + if (hs != 0) { /* 4-byte sequence? */ + nc += 3; + hs = (hs & 0x3FF) + 0x40; + pb->buf[i++] = (BYTE)(0xF0 | hs >> 8); + pb->buf[i++] = (BYTE)(0x80 | (hs >> 2 & 0x3F)); + pb->buf[i++] = (BYTE)(0x80 | (hs & 3) << 4 | (wc >> 6 & 0x0F)); + pb->buf[i++] = (BYTE)(0x80 | (wc & 0x3F)); + } else { + if (wc < 0x80) { /* Single byte? */ + pb->buf[i++] = (BYTE)wc; + } else { + if (wc < 0x800) { /* 2-byte sequence? */ + nc += 1; + pb->buf[i++] = (BYTE)(0xC0 | wc >> 6); + } else { /* 3-byte sequence */ + nc += 2; + pb->buf[i++] = (BYTE)(0xE0 | wc >> 12); + pb->buf[i++] = (BYTE)(0x80 | (wc >> 6 & 0x3F)); + } + pb->buf[i++] = (BYTE)(0x80 | (wc & 0x3F)); + } + } +#else /* Write a code point in ANSI/OEM */ + if (hs != 0) return; + wc = ff_uni2oem(wc, CODEPAGE); /* UTF-16 ==> ANSI/OEM */ + if (wc == 0) return; + if (wc >= 0x100) { + pb->buf[i++] = (BYTE)(wc >> 8); nc++; + } + pb->buf[i++] = (BYTE)wc; +#endif + +#else /* ANSI/OEM input (without re-encoding) */ + pb->buf[i++] = (BYTE)c; +#endif + + if (i >= (int)(sizeof pb->buf) - 4) { /* Write buffered characters to the file */ + f_write(pb->fp, pb->buf, (UINT)i, &n); + i = (n == (UINT)i) ? 0 : -1; + } + pb->idx = i; + pb->nchr = nc + 1; +} + + +/* Flush remaining characters in the buffer */ + +static int putc_flush (putbuff* pb) +{ + UINT nw; + + if ( pb->idx >= 0 /* Flush buffered characters to the file */ + && f_write(pb->fp, pb->buf, (UINT)pb->idx, &nw) == FR_OK + && (UINT)pb->idx == nw) return pb->nchr; + return -1; +} + + +/* Initialize write buffer */ + +static void putc_init (putbuff* pb, FIL* fp) +{ + memset(pb, 0, sizeof (putbuff)); + pb->fp = fp; +} + + + +int f_putc ( + TCHAR c, /* A character to be output */ + FIL* fp /* Pointer to the file object */ +) +{ + putbuff pb; + + + putc_init(&pb, fp); + putc_bfd(&pb, c); /* Put the character */ + return putc_flush(&pb); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Put a String to the File */ +/*-----------------------------------------------------------------------*/ + +int f_puts ( + const TCHAR* str, /* Pointer to the string to be output */ + FIL* fp /* Pointer to the file object */ +) +{ + putbuff pb; + + + putc_init(&pb, fp); + while (*str) putc_bfd(&pb, *str++); /* Put the string */ + return putc_flush(&pb); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Put a Formatted String to the File (with sub-functions) */ +/*-----------------------------------------------------------------------*/ +#if FF_PRINT_FLOAT && FF_INTDEF == 2 +#include + +static int ilog10 (double n) /* Calculate log10(n) in integer output */ +{ + int rv = 0; + + while (n >= 10) { /* Decimate digit in right shift */ + if (n >= 100000) { + n /= 100000; rv += 5; + } else { + n /= 10; rv++; + } + } + while (n < 1) { /* Decimate digit in left shift */ + if (n < 0.00001) { + n *= 100000; rv -= 5; + } else { + n *= 10; rv--; + } + } + return rv; +} + + +static double i10x (int n) /* Calculate 10^n in integer input */ +{ + double rv = 1; + + while (n > 0) { /* Left shift */ + if (n >= 5) { + rv *= 100000; n -= 5; + } else { + rv *= 10; n--; + } + } + while (n < 0) { /* Right shift */ + if (n <= -5) { + rv /= 100000; n += 5; + } else { + rv /= 10; n++; + } + } + return rv; +} + + +static void ftoa ( + char* buf, /* Buffer to output the floating point string */ + double val, /* Value to output */ + int prec, /* Number of fractional digits */ + TCHAR fmt /* Notation */ +) +{ + int d; + int e = 0, m = 0; + char sign = 0; + double w; + const char *er = 0; + const char ds = FF_PRINT_FLOAT == 2 ? ',' : '.'; + + + if (isnan(val)) { /* Not a number? */ + er = "NaN"; + } else { + if (prec < 0) prec = 6; /* Default precision? (6 fractional digits) */ + if (val < 0) { /* Nagative? */ + val = 0 - val; sign = '-'; + } else { + sign = '+'; + } + if (isinf(val)) { /* Infinite? */ + er = "INF"; + } else { + if (fmt == 'f') { /* Decimal notation? */ + val += i10x(0 - prec) / 2; /* Round (nearest) */ + m = ilog10(val); + if (m < 0) m = 0; + if (m + prec + 3 >= SZ_NUM_BUF) er = "OV"; /* Buffer overflow? */ + } else { /* E notation */ + if (val != 0) { /* Not a true zero? */ + val += i10x(ilog10(val) - prec) / 2; /* Round (nearest) */ + e = ilog10(val); + if (e > 99 || prec + 7 >= SZ_NUM_BUF) { /* Buffer overflow or E > +99? */ + er = "OV"; + } else { + if (e < -99) e = -99; + val /= i10x(e); /* Normalize */ + } + } + } + } + if (!er) { /* Not error condition */ + if (sign == '-') *buf++ = sign; /* Add a - if negative value */ + do { /* Put decimal number */ + if (m == -1) *buf++ = ds; /* Insert a decimal separator when get into fractional part */ + w = i10x(m); /* Snip the highest digit d */ + d = (int)(val / w); val -= d * w; + *buf++ = (char)('0' + d); /* Put the digit */ + } while (--m >= -prec); /* Output all digits specified by prec */ + if (fmt != 'f') { /* Put exponent if needed */ + *buf++ = (char)fmt; + if (e < 0) { + e = 0 - e; *buf++ = '-'; + } else { + *buf++ = '+'; + } + *buf++ = (char)('0' + e / 10); + *buf++ = (char)('0' + e % 10); + } + } + } + if (er) { /* Error condition */ + if (sign) *buf++ = sign; /* Add sign if needed */ + do *buf++ = *er++; while (*er); /* Put error symbol */ + } + *buf = 0; /* Term */ +} +#endif /* FF_PRINT_FLOAT && FF_INTDEF == 2 */ + + + +int f_printf ( + FIL* fp, /* Pointer to the file object */ + const TCHAR* fmt, /* Pointer to the format string */ + ... /* Optional arguments... */ +) +{ + va_list arp; + putbuff pb; + UINT i, j, w, f, r; + int prec; +#if FF_PRINT_LLI && FF_INTDEF == 2 + QWORD v; +#else + DWORD v; +#endif + TCHAR tc, pad, *tp; + TCHAR nul = 0; + char d, str[SZ_NUM_BUF]; + + + putc_init(&pb, fp); + + va_start(arp, fmt); + + for (;;) { + tc = *fmt++; + if (tc == 0) break; /* End of format string */ + if (tc != '%') { /* Not an escape character (pass-through) */ + putc_bfd(&pb, tc); + continue; + } + f = w = 0; pad = ' '; prec = -1; /* Initialize parms */ + tc = *fmt++; + if (tc == '0') { /* Flag: '0' padded */ + pad = '0'; tc = *fmt++; + } else if (tc == '-') { /* Flag: Left aligned */ + f = 2; tc = *fmt++; + } + if (tc == '*') { /* Minimum width from an argument */ + w = va_arg(arp, int); + tc = *fmt++; + } else { + while (IsDigit(tc)) { /* Minimum width */ + w = w * 10 + tc - '0'; + tc = *fmt++; + } + } + if (tc == '.') { /* Precision */ + tc = *fmt++; + if (tc == '*') { /* Precision from an argument */ + prec = va_arg(arp, int); + tc = *fmt++; + } else { + prec = 0; + while (IsDigit(tc)) { /* Precision */ + prec = prec * 10 + tc - '0'; + tc = *fmt++; + } + } + } + if (tc == 'l') { /* Size: long int */ + f |= 4; tc = *fmt++; +#if FF_PRINT_LLI && FF_INTDEF == 2 + if (tc == 'l') { /* Size: long long int */ + f |= 8; tc = *fmt++; + } +#endif + } + if (tc == 0) break; /* End of format string */ + switch (tc) { /* Atgument type is... */ + case 'b': /* Unsigned binary */ + r = 2; break; + case 'o': /* Unsigned octal */ + r = 8; break; + case 'd': /* Signed decimal */ + case 'u': /* Unsigned decimal */ + r = 10; break; + case 'x': /* Unsigned hexdecimal (lower case) */ + case 'X': /* Unsigned hexdecimal (upper case) */ + r = 16; break; + case 'c': /* Character */ + putc_bfd(&pb, (TCHAR)va_arg(arp, int)); + continue; + case 's': /* String */ + tp = va_arg(arp, TCHAR*); /* Get a pointer argument */ + if (!tp) tp = &nul; /* Null ptr generates a null string */ + for (j = 0; tp[j]; j++) ; /* j = tcslen(tp) */ + if (prec >= 0 && j > (UINT)prec) j = prec; /* Limited length of string body */ + for ( ; !(f & 2) && j < w; j++) putc_bfd(&pb, pad); /* Left pads */ + while (*tp && prec--) putc_bfd(&pb, *tp++); /* Body */ + while (j++ < w) putc_bfd(&pb, ' '); /* Right pads */ + continue; +#if FF_PRINT_FLOAT && FF_INTDEF == 2 + case 'f': /* Floating point (decimal) */ + case 'e': /* Floating point (e) */ + case 'E': /* Floating point (E) */ + ftoa(str, va_arg(arp, double), prec, tc); /* Make a flaoting point string */ + for (j = strlen(str); !(f & 2) && j < w; j++) putc_bfd(&pb, pad); /* Left pads */ + for (i = 0; str[i]; putc_bfd(&pb, str[i++])) ; /* Body */ + while (j++ < w) putc_bfd(&pb, ' '); /* Right pads */ + continue; +#endif + default: /* Unknown type (pass-through) */ + putc_bfd(&pb, tc); continue; + } + + /* Get an integer argument and put it in numeral */ +#if FF_PRINT_LLI && FF_INTDEF == 2 + if (f & 8) { /* long long argument? */ + v = (QWORD)va_arg(arp, LONGLONG); + } else { + if (f & 4) { /* long argument? */ + v = (tc == 'd') ? (QWORD)(LONGLONG)va_arg(arp, long) : (QWORD)va_arg(arp, unsigned long); + } else { /* int/short/char argument */ + v = (tc == 'd') ? (QWORD)(LONGLONG)va_arg(arp, int) : (QWORD)va_arg(arp, unsigned int); + } + } + if (tc == 'd' && (v & 0x8000000000000000)) { /* Negative value? */ + v = 0 - v; f |= 1; + } +#else + if (f & 4) { /* long argument? */ + v = (DWORD)va_arg(arp, long); + } else { /* int/short/char argument */ + v = (tc == 'd') ? (DWORD)(long)va_arg(arp, int) : (DWORD)va_arg(arp, unsigned int); + } + if (tc == 'd' && (v & 0x80000000)) { /* Negative value? */ + v = 0 - v; f |= 1; + } +#endif + i = 0; + do { /* Make an integer number string */ + d = (char)(v % r); v /= r; + if (d > 9) d += (tc == 'x') ? 0x27 : 0x07; + str[i++] = d + '0'; + } while (v && i < SZ_NUM_BUF); + if (f & 1) str[i++] = '-'; /* Sign */ + /* Write it */ + for (j = i; !(f & 2) && j < w; j++) putc_bfd(&pb, pad); /* Left pads */ + do putc_bfd(&pb, (TCHAR)str[--i]); while (i); /* Body */ + while (j++ < w) putc_bfd(&pb, ' '); /* Right pads */ + } + + va_end(arp); + + return putc_flush(&pb); +} + +#endif /* !FF_FS_READONLY */ +#endif /* FF_USE_STRFUNC */ + + + +#if FF_CODE_PAGE == 0 +/*-----------------------------------------------------------------------*/ +/* Set Active Codepage for the Path Name */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_setcp ( + WORD cp /* Value to be set as active code page */ +) +{ + static const WORD validcp[22] = { 437, 720, 737, 771, 775, 850, 852, 855, 857, 860, 861, 862, 863, 864, 865, 866, 869, 932, 936, 949, 950, 0}; + static const BYTE* const tables[22] = {Ct437, Ct720, Ct737, Ct771, Ct775, Ct850, Ct852, Ct855, Ct857, Ct860, Ct861, Ct862, Ct863, Ct864, Ct865, Ct866, Ct869, Dc932, Dc936, Dc949, Dc950, 0}; + UINT i; + + + for (i = 0; validcp[i] != 0 && validcp[i] != cp; i++) ; /* Find the code page */ + if (validcp[i] != cp) return FR_INVALID_PARAMETER; /* Not found? */ + + CodePage = cp; + if (cp >= 900) { /* DBCS */ + ExCvt = 0; + DbcTbl = tables[i]; + } else { /* SBCS */ + ExCvt = tables[i]; + DbcTbl = 0; + } + return FR_OK; +} +#endif /* FF_CODE_PAGE == 0 */ + diff --git a/trunk/Arduino/ArduinoFDC/ff.h b/trunk/Arduino/ArduinoFDC/ff.h new file mode 100644 index 00000000..7794a462 --- /dev/null +++ b/trunk/Arduino/ArduinoFDC/ff.h @@ -0,0 +1,425 @@ +/*----------------------------------------------------------------------------/ +/ FatFs - Generic FAT Filesystem module R0.14b / +/-----------------------------------------------------------------------------/ +/ +/ Copyright (C) 2021, ChaN, all right reserved. +/ +/ FatFs module is an open source software. Redistribution and use of FatFs in +/ source and binary forms, with or without modification, are permitted provided +/ that the following condition is met: + +/ 1. Redistributions of source code must retain the above copyright notice, +/ this condition and the following disclaimer. +/ +/ This software is provided by the copyright holder and contributors "AS IS" +/ and any warranties related to this software are DISCLAIMED. +/ The copyright owner or contributors be NOT LIABLE for any damages caused +/ by use of this software. +/ +/----------------------------------------------------------------------------*/ + + +#ifndef FF_DEFINED +#define FF_DEFINED 86631 /* Revision ID */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "ffconf.h" /* FatFs configuration options */ + +#if FF_DEFINED != FFCONF_DEF +#error Wrong configuration file (ffconf.h). +#endif + + +/* Integer types used for FatFs API */ + +#if defined(_WIN32) /* Windows VC++ (for development only) */ +#define FF_INTDEF 2 +#include +typedef unsigned __int64 QWORD; +#include +#define isnan(v) _isnan(v) +#define isinf(v) (!_finite(v)) + +#elif (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__cplusplus) /* C99 or later */ +#define FF_INTDEF 2 +#include +typedef unsigned int UINT; /* int must be 16-bit or 32-bit */ +typedef unsigned char BYTE; /* char must be 8-bit */ +typedef uint16_t WORD; /* 16-bit unsigned integer */ +typedef uint32_t DWORD; /* 32-bit unsigned integer */ +typedef uint64_t QWORD; /* 64-bit unsigned integer */ +typedef WORD WCHAR; /* UTF-16 character type */ + +#else /* Earlier than C99 */ +#define FF_INTDEF 1 +typedef unsigned int UINT; /* int must be 16-bit or 32-bit */ +typedef unsigned char BYTE; /* char must be 8-bit */ +typedef unsigned short WORD; /* 16-bit unsigned integer */ +typedef unsigned long DWORD; /* 32-bit unsigned integer */ +typedef WORD WCHAR; /* UTF-16 character type */ +#endif + + +/* Type of file size and LBA variables */ + +#if FF_FS_EXFAT +#if FF_INTDEF != 2 +#error exFAT feature wants C99 or later +#endif +typedef QWORD FSIZE_t; +#if FF_LBA64 +typedef QWORD LBA_t; +#else +typedef DWORD LBA_t; +#endif +#else +#if FF_LBA64 +#error exFAT needs to be enabled when enable 64-bit LBA +#endif +typedef DWORD FSIZE_t; +typedef DWORD LBA_t; +#endif + + + +/* Type of path name strings on FatFs API (TCHAR) */ + +#if FF_USE_LFN && FF_LFN_UNICODE == 1 /* Unicode in UTF-16 encoding */ +typedef WCHAR TCHAR; +#define _T(x) L ## x +#define _TEXT(x) L ## x +#elif FF_USE_LFN && FF_LFN_UNICODE == 2 /* Unicode in UTF-8 encoding */ +typedef char TCHAR; +#define _T(x) u8 ## x +#define _TEXT(x) u8 ## x +#elif FF_USE_LFN && FF_LFN_UNICODE == 3 /* Unicode in UTF-32 encoding */ +typedef DWORD TCHAR; +#define _T(x) U ## x +#define _TEXT(x) U ## x +#elif FF_USE_LFN && (FF_LFN_UNICODE < 0 || FF_LFN_UNICODE > 3) +#error Wrong FF_LFN_UNICODE setting +#else /* ANSI/OEM code in SBCS/DBCS */ +typedef char TCHAR; +#define _T(x) x +#define _TEXT(x) x +#endif + + + +/* Definitions of volume management */ + +#if FF_MULTI_PARTITION /* Multiple partition configuration */ +typedef struct { + BYTE pd; /* Physical drive number */ + BYTE pt; /* Partition: 0:Auto detect, 1-4:Forced partition) */ +} PARTITION; +extern PARTITION VolToPart[]; /* Volume - Partition mapping table */ +#endif + +#if FF_STR_VOLUME_ID +#ifndef FF_VOLUME_STRS +extern const char* VolumeStr[FF_VOLUMES]; /* User defied volume ID */ +#endif +#endif + + + +/* Filesystem object structure (FATFS) */ + +typedef struct { + BYTE fs_type; /* Filesystem type (0:not mounted) */ + BYTE pdrv; /* Associated physical drive */ + BYTE n_fats; /* Number of FATs (1 or 2) */ + BYTE wflag; /* win[] flag (b0:dirty) */ + BYTE fsi_flag; /* FSINFO flags (b7:disabled, b0:dirty) */ + WORD id; /* Volume mount ID */ + WORD n_rootdir; /* Number of root directory entries (FAT12/16) */ + WORD csize; /* Cluster size [sectors] */ +#if FF_MAX_SS != FF_MIN_SS + WORD ssize; /* Sector size (512, 1024, 2048 or 4096) */ +#endif +#if FF_USE_LFN + WCHAR* lfnbuf; /* LFN working buffer */ +#endif +#if FF_FS_EXFAT + BYTE* dirbuf; /* Directory entry block scratchpad buffer for exFAT */ +#endif +#if FF_FS_REENTRANT + FF_SYNC_t sobj; /* Identifier of sync object */ +#endif +#if !FF_FS_READONLY + DWORD last_clst; /* Last allocated cluster */ + DWORD free_clst; /* Number of free clusters */ +#endif +#if FF_FS_RPATH + DWORD cdir; /* Current directory start cluster (0:root) */ +#if FF_FS_EXFAT + DWORD cdc_scl; /* Containing directory start cluster (invalid when cdir is 0) */ + DWORD cdc_size; /* b31-b8:Size of containing directory, b7-b0: Chain status */ + DWORD cdc_ofs; /* Offset in the containing directory (invalid when cdir is 0) */ +#endif +#endif + DWORD n_fatent; /* Number of FAT entries (number of clusters + 2) */ + DWORD fsize; /* Size of an FAT [sectors] */ + LBA_t volbase; /* Volume base sector */ + LBA_t fatbase; /* FAT base sector */ + LBA_t dirbase; /* Root directory base sector/cluster */ + LBA_t database; /* Data base sector */ +#if FF_FS_EXFAT + LBA_t bitbase; /* Allocation bitmap base sector */ +#endif + LBA_t winsect; /* Current sector appearing in the win[] */ + BYTE win[FF_MAX_SS+5]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */ +} FATFS; + + + +/* Object ID and allocation information (FFOBJID) */ + +typedef struct { + FATFS* fs; /* Pointer to the hosting volume of this object */ + WORD id; /* Hosting volume mount ID */ + BYTE attr; /* Object attribute */ + BYTE stat; /* Object chain status (b1-0: =0:not contiguous, =2:contiguous, =3:fragmented in this session, b2:sub-directory stretched) */ + DWORD sclust; /* Object data start cluster (0:no cluster or root directory) */ + FSIZE_t objsize; /* Object size (valid when sclust != 0) */ +#if FF_FS_EXFAT + DWORD n_cont; /* Size of first fragment - 1 (valid when stat == 3) */ + DWORD n_frag; /* Size of last fragment needs to be written to FAT (valid when not zero) */ + DWORD c_scl; /* Containing directory start cluster (valid when sclust != 0) */ + DWORD c_size; /* b31-b8:Size of containing directory, b7-b0: Chain status (valid when c_scl != 0) */ + DWORD c_ofs; /* Offset in the containing directory (valid when file object and sclust != 0) */ +#endif +#if FF_FS_LOCK + UINT lockid; /* File lock ID origin from 1 (index of file semaphore table Files[]) */ +#endif +} FFOBJID; + + + +/* File object structure (FIL) */ + +typedef struct { + FFOBJID obj; /* Object identifier (must be the 1st member to detect invalid object pointer) */ + BYTE flag; /* File status flags */ + BYTE err; /* Abort flag (error code) */ + FSIZE_t fptr; /* File read/write pointer (Zeroed on file open) */ + DWORD clust; /* Current cluster of fpter (invalid when fptr is 0) */ + LBA_t sect; /* Sector number appearing in buf[] (0:invalid) */ +#if !FF_FS_READONLY + LBA_t dir_sect; /* Sector number containing the directory entry (not used at exFAT) */ + BYTE* dir_ptr; /* Pointer to the directory entry in the win[] (not used at exFAT) */ +#endif +#if FF_USE_FASTSEEK + DWORD* cltbl; /* Pointer to the cluster link map table (nulled on open, set by application) */ +#endif +#if !FF_FS_TINY + BYTE buf[FF_MAX_SS+5]; /* File private data read/write window */ +#endif +} FIL; + + + +/* Directory object structure (DIR) */ + +typedef struct { + FFOBJID obj; /* Object identifier */ + DWORD dptr; /* Current read/write offset */ + DWORD clust; /* Current cluster */ + LBA_t sect; /* Current sector (0:Read operation has terminated) */ + BYTE* dir; /* Pointer to the directory item in the win[] */ + BYTE fn[12]; /* SFN (in/out) {body[8],ext[3],status[1]} */ +#if FF_USE_LFN + DWORD blk_ofs; /* Offset of current entry block being processed (0xFFFFFFFF:Invalid) */ +#endif +#if FF_USE_FIND + const TCHAR* pat; /* Pointer to the name matching pattern */ +#endif +} DIR; + + + +/* File information structure (FILINFO) */ + +typedef struct { + FSIZE_t fsize; /* File size */ + WORD fdate; /* Modified date */ + WORD ftime; /* Modified time */ + BYTE fattrib; /* File attribute */ +#if FF_USE_LFN + TCHAR altname[FF_SFN_BUF + 1];/* Altenative file name */ + TCHAR fname[FF_LFN_BUF + 1]; /* Primary file name */ +#else + TCHAR fname[12 + 1]; /* File name */ +#endif +} FILINFO; + + + +/* Format parameter structure (MKFS_PARM) */ + +typedef struct { + BYTE fmt; /* Format option (FM_FAT, FM_FAT32, FM_EXFAT and FM_SFD) */ + BYTE n_fat; /* Number of FATs */ + UINT align; /* Data area alignment (sector) */ + UINT n_root; /* Number of root directory entries */ + DWORD au_size; /* Cluster size (byte) */ + BYTE media; /* media descriptor */ + WORD n_sec_track; /* number of sectors per track */ + WORD n_heads; /* number of heads */ +} MKFS_PARM; + + + +/* File function return code (FRESULT) */ + +typedef enum { + FR_OK = 0, /* (0) Succeeded */ + FR_DISK_ERR, /* (1) A hard error occurred in the low level disk I/O layer */ + FR_INT_ERR, /* (2) Assertion failed */ + FR_NOT_READY, /* (3) The physical drive cannot work */ + FR_NO_FILE, /* (4) Could not find the file */ + FR_NO_PATH, /* (5) Could not find the path */ + FR_INVALID_NAME, /* (6) The path name format is invalid */ + FR_DENIED, /* (7) Access denied due to prohibited access or directory full */ + FR_EXIST, /* (8) Access denied due to prohibited access */ + FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */ + FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */ + FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */ + FR_NOT_ENABLED, /* (12) The volume has no work area */ + FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume */ + FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any problem */ + FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */ + FR_LOCKED, /* (16) The operation is rejected according to the file sharing policy */ + FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */ + FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > FF_FS_LOCK */ + FR_INVALID_PARAMETER /* (19) Given parameter is invalid */ +} FRESULT; + + + +/*--------------------------------------------------------------*/ +/* FatFs module application interface */ + +FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode); /* Open or create a file */ +FRESULT f_close (FIL* fp); /* Close an open file object */ +FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br); /* Read data from the file */ +FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw); /* Write data to the file */ +FRESULT f_lseek (FIL* fp, FSIZE_t ofs); /* Move file pointer of the file object */ +FRESULT f_truncate (FIL* fp); /* Truncate the file */ +FRESULT f_sync (FIL* fp); /* Flush cached data of the writing file */ +FRESULT f_opendir (DIR* dp, const TCHAR* path); /* Open a directory */ +FRESULT f_closedir (DIR* dp); /* Close an open directory */ +FRESULT f_readdir (DIR* dp, FILINFO* fno); /* Read a directory item */ +FRESULT f_findfirst (DIR* dp, FILINFO* fno, const TCHAR* path, const TCHAR* pattern); /* Find first file */ +FRESULT f_findnext (DIR* dp, FILINFO* fno); /* Find next file */ +FRESULT f_mkdir (const TCHAR* path); /* Create a sub directory */ +FRESULT f_unlink (const TCHAR* path); /* Delete an existing file or directory */ +FRESULT f_rename (const TCHAR* path_old, const TCHAR* path_new); /* Rename/Move a file or directory */ +FRESULT f_stat (const TCHAR* path, FILINFO* fno); /* Get file status */ +FRESULT f_chmod (const TCHAR* path, BYTE attr, BYTE mask); /* Change attribute of a file/dir */ +FRESULT f_utime (const TCHAR* path, const FILINFO* fno); /* Change timestamp of a file/dir */ +FRESULT f_chdir (const TCHAR* path); /* Change current directory */ +FRESULT f_chdrive (const TCHAR* path); /* Change current drive */ +FRESULT f_getcwd (TCHAR* buff, UINT len); /* Get current directory */ +FRESULT f_getfree (const TCHAR* path, DWORD* nclst, FATFS** fatfs); /* Get number of free clusters on the drive */ +FRESULT f_getlabel (const TCHAR* path, TCHAR* label, DWORD* vsn); /* Get volume label */ +FRESULT f_setlabel (const TCHAR* label); /* Set volume label */ +FRESULT f_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf); /* Forward data to the stream */ +FRESULT f_expand (FIL* fp, FSIZE_t fsz, BYTE opt); /* Allocate a contiguous block to the file */ +FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt); /* Mount/Unmount a logical drive */ +FRESULT f_mkfs (const TCHAR* path, const MKFS_PARM* opt, void* work, UINT len); /* Create a FAT volume */ +FRESULT f_fdisk (BYTE pdrv, const LBA_t ptbl[], void* work); /* Divide a physical drive into some partitions */ +FRESULT f_setcp (WORD cp); /* Set current code page */ +int f_putc (TCHAR c, FIL* fp); /* Put a character to the file */ +int f_puts (const TCHAR* str, FIL* cp); /* Put a string to the file */ +int f_printf (FIL* fp, const TCHAR* str, ...); /* Put a formatted string to the file */ +TCHAR* f_gets (TCHAR* buff, int len, FIL* fp); /* Get a string from the file */ + +#define f_eof(fp) ((int)((fp)->fptr == (fp)->obj.objsize)) +#define f_error(fp) ((fp)->err) +#define f_tell(fp) ((fp)->fptr) +#define f_size(fp) ((fp)->obj.objsize) +#define f_rewind(fp) f_lseek((fp), 0) +#define f_rewinddir(dp) f_readdir((dp), 0) +#define f_rmdir(path) f_unlink(path) +#define f_unmount(path) f_mount(0, path, 0) + + + + +/*--------------------------------------------------------------*/ +/* Additional user defined functions */ + +/* RTC function */ +#if !FF_FS_READONLY && !FF_FS_NORTC +DWORD get_fattime (void); +#endif + +/* LFN support functions */ +#if FF_USE_LFN >= 1 /* Code conversion (defined in unicode.c) */ +WCHAR ff_oem2uni (WCHAR oem, WORD cp); /* OEM code to Unicode conversion */ +WCHAR ff_uni2oem (DWORD uni, WORD cp); /* Unicode to OEM code conversion */ +DWORD ff_wtoupper (DWORD uni); /* Unicode upper-case conversion */ +#endif +#if FF_USE_LFN == 3 /* Dynamic memory allocation */ +void* ff_memalloc (UINT msize); /* Allocate memory block */ +void ff_memfree (void* mblock); /* Free memory block */ +#endif + +/* Sync functions */ +#if FF_FS_REENTRANT +int ff_cre_syncobj (BYTE vol, FF_SYNC_t* sobj); /* Create a sync object */ +int ff_req_grant (FF_SYNC_t sobj); /* Lock sync object */ +void ff_rel_grant (FF_SYNC_t sobj); /* Unlock sync object */ +int ff_del_syncobj (FF_SYNC_t sobj); /* Delete a sync object */ +#endif + + + + +/*--------------------------------------------------------------*/ +/* Flags and offset address */ + + +/* File access mode and open method flags (3rd argument of f_open) */ +#define FA_READ 0x01 +#define FA_WRITE 0x02 +#define FA_OPEN_EXISTING 0x00 +#define FA_CREATE_NEW 0x04 +#define FA_CREATE_ALWAYS 0x08 +#define FA_OPEN_ALWAYS 0x10 +#define FA_OPEN_APPEND 0x30 + +/* Fast seek controls (2nd argument of f_lseek) */ +#define CREATE_LINKMAP ((FSIZE_t)0 - 1) + +/* Format options (2nd argument of f_mkfs) */ +#define FM_FAT 0x01 +#define FM_FAT32 0x02 +#define FM_EXFAT 0x04 +#define FM_ANY 0x07 +#define FM_SFD 0x08 + +/* Filesystem type (FATFS.fs_type) */ +#define FS_FAT12 1 +#define FS_FAT16 2 +#define FS_FAT32 3 +#define FS_EXFAT 4 + +/* File attribute bits for directory entry (FILINFO.fattrib) */ +#define AM_RDO 0x01 /* Read only */ +#define AM_HID 0x02 /* Hidden */ +#define AM_SYS 0x04 /* System */ +#define AM_DIR 0x10 /* Directory */ +#define AM_ARC 0x20 /* Archive */ + + +#ifdef __cplusplus +} +#endif + +#endif /* FF_DEFINED */ diff --git a/trunk/Arduino/ArduinoFDC/ffconf.h b/trunk/Arduino/ArduinoFDC/ffconf.h new file mode 100644 index 00000000..dc83b03b --- /dev/null +++ b/trunk/Arduino/ArduinoFDC/ffconf.h @@ -0,0 +1,302 @@ +/*---------------------------------------------------------------------------/ +/ FatFs Functional Configurations +/---------------------------------------------------------------------------*/ + +#define FFCONF_DEF 86631 /* Revision ID */ + +/*---------------------------------------------------------------------------/ +/ Function Configurations +/---------------------------------------------------------------------------*/ + +#define FF_FS_READONLY 0 +/* This option switches read-only configuration. (0:Read/Write or 1:Read-only) +/ Read-only configuration removes writing API functions, f_write(), f_sync(), +/ f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree() +/ and optional writing functions as well. */ + + +#define FF_FS_MINIMIZE 0 +/* This option defines minimization level to remove some basic API functions. +/ +/ 0: Basic functions are fully enabled. +/ 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_truncate() and f_rename() +/ are removed. +/ 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1. +/ 3: f_lseek() function is removed in addition to 2. */ + + +#define FF_USE_FIND 0 +/* This option switches filtered directory read functions, f_findfirst() and +/ f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */ + + +#define FF_USE_MKFS 1 +/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */ + + +#define FF_USE_FASTSEEK 0 +/* This option switches fast seek function. (0:Disable or 1:Enable) */ + + +#define FF_USE_EXPAND 0 +/* This option switches f_expand function. (0:Disable or 1:Enable) */ + + +#define FF_USE_CHMOD 0 +/* This option switches attribute manipulation functions, f_chmod() and f_utime(). +/ (0:Disable or 1:Enable) Also FF_FS_READONLY needs to be 0 to enable this option. */ + + +#define FF_USE_LABEL 0 +/* This option switches volume label functions, f_getlabel() and f_setlabel(). +/ (0:Disable or 1:Enable) */ + + +#define FF_USE_FORWARD 0 +/* This option switches f_forward() function. (0:Disable or 1:Enable) */ + + +#define FF_USE_STRFUNC 0 +#define FF_PRINT_LLI 0 +#define FF_PRINT_FLOAT 0 +#define FF_STRF_ENCODE 0 +/* FF_USE_STRFUNC switches string functions, f_gets(), f_putc(), f_puts() and +/ f_printf(). +/ +/ 0: Disable. FF_PRINT_LLI, FF_PRINT_FLOAT and FF_STRF_ENCODE have no effect. +/ 1: Enable without LF-CRLF conversion. +/ 2: Enable with LF-CRLF conversion. +/ +/ FF_PRINT_LLI = 1 makes f_printf() support long long argument and FF_PRINT_FLOAT = 1/2 + makes f_printf() support floating point argument. These features want C99 or later. +/ When FF_LFN_UNICODE >= 1 with LFN enabled, string functions convert the character +/ encoding in it. FF_STRF_ENCODE selects assumption of character encoding ON THE FILE +/ to be read/written via those functions. +/ +/ 0: ANSI/OEM in current CP +/ 1: Unicode in UTF-16LE +/ 2: Unicode in UTF-16BE +/ 3: Unicode in UTF-8 +*/ + + +/*---------------------------------------------------------------------------/ +/ Locale and Namespace Configurations +/---------------------------------------------------------------------------*/ + +#define FF_CODE_PAGE -1 +/* This option specifies the OEM code page to be used on the target system. +/ Incorrect code page setting can cause a file open failure. +/ +/ -1 - do not use code pages (ASCII only) +/ 437 - U.S. +/ 720 - Arabic +/ 737 - Greek +/ 771 - KBL +/ 775 - Baltic +/ 850 - Latin 1 +/ 852 - Latin 2 +/ 855 - Cyrillic +/ 857 - Turkish +/ 860 - Portuguese +/ 861 - Icelandic +/ 862 - Hebrew +/ 863 - Canadian French +/ 864 - Arabic +/ 865 - Nordic +/ 866 - Russian +/ 869 - Greek 2 +/ 932 - Japanese (DBCS) +/ 936 - Simplified Chinese (DBCS) +/ 949 - Korean (DBCS) +/ 950 - Traditional Chinese (DBCS) +/ 0 - Include all code pages above and configured by f_setcp() +*/ + + +#define FF_USE_LFN 0 +#define FF_MAX_LFN 255 +/* The FF_USE_LFN switches the support for LFN (long file name). +/ +/ 0: Disable LFN. FF_MAX_LFN has no effect. +/ 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe. +/ 2: Enable LFN with dynamic working buffer on the STACK. +/ 3: Enable LFN with dynamic working buffer on the HEAP. +/ +/ To enable the LFN, ffunicode.c needs to be added to the project. The LFN function +/ requiers certain internal working buffer occupies (FF_MAX_LFN + 1) * 2 bytes and +/ additional (FF_MAX_LFN + 44) / 15 * 32 bytes when exFAT is enabled. +/ The FF_MAX_LFN defines size of the working buffer in UTF-16 code unit and it can +/ be in range of 12 to 255. It is recommended to be set it 255 to fully support LFN +/ specification. +/ When use stack for the working buffer, take care on stack overflow. When use heap +/ memory for the working buffer, memory management functions, ff_memalloc() and +/ ff_memfree() exemplified in ffsystem.c, need to be added to the project. */ + + +#define FF_LFN_UNICODE 0 +/* This option switches the character encoding on the API when LFN is enabled. +/ +/ 0: ANSI/OEM in current CP (TCHAR = char) +/ 1: Unicode in UTF-16 (TCHAR = WCHAR) +/ 2: Unicode in UTF-8 (TCHAR = char) +/ 3: Unicode in UTF-32 (TCHAR = DWORD) +/ +/ Also behavior of string I/O functions will be affected by this option. +/ When LFN is not enabled, this option has no effect. */ + + +#define FF_LFN_BUF 255 +#define FF_SFN_BUF 12 +/* This set of options defines size of file name members in the FILINFO structure +/ which is used to read out directory items. These values should be suffcient for +/ the file names to read. The maximum possible length of the read file name depends +/ on character encoding. When LFN is not enabled, these options have no effect. */ + + +#define FF_FS_RPATH 0 +/* This option configures support for relative path. +/ +/ 0: Disable relative path and remove related functions. +/ 1: Enable relative path. f_chdir() and f_chdrive() are available. +/ 2: f_getcwd() function is available in addition to 1. +*/ + + +/*---------------------------------------------------------------------------/ +/ Drive/Volume Configurations +/---------------------------------------------------------------------------*/ + +#define FF_VOLUMES 1 +/* Number of volumes (logical drives) to be used. (1-10) */ + + +#define FF_STR_VOLUME_ID 0 +#define FF_VOLUME_STRS "RAM","NAND","CF","SD","SD2","USB","USB2","USB3" +/* FF_STR_VOLUME_ID switches support for volume ID in arbitrary strings. +/ When FF_STR_VOLUME_ID is set to 1 or 2, arbitrary strings can be used as drive +/ number in the path name. FF_VOLUME_STRS defines the volume ID strings for each +/ logical drives. Number of items must not be less than FF_VOLUMES. Valid +/ characters for the volume ID strings are A-Z, a-z and 0-9, however, they are +/ compared in case-insensitive. If FF_STR_VOLUME_ID >= 1 and FF_VOLUME_STRS is +/ not defined, a user defined volume string table needs to be defined as: +/ +/ const char* VolumeStr[FF_VOLUMES] = {"ram","flash","sd","usb",... +*/ + + +#define FF_MULTI_PARTITION 0 +/* This option switches support for multiple volumes on the physical drive. +/ By default (0), each logical drive number is bound to the same physical drive +/ number and only an FAT volume found on the physical drive will be mounted. +/ When this function is enabled (1), each logical drive number can be bound to +/ arbitrary physical drive and partition listed in the VolToPart[]. Also f_fdisk() +/ funciton will be available. */ + + +#define FF_MIN_SS 512 +#define FF_MAX_SS 512 +/* This set of options configures the range of sector size to be supported. (512, +/ 1024, 2048 or 4096) Always set both 512 for most systems, generic memory card and +/ harddisk, but a larger value may be required for on-board flash memory and some +/ type of optical media. When FF_MAX_SS is larger than FF_MIN_SS, FatFs is configured +/ for variable sector size mode and disk_ioctl() function needs to implement +/ GET_SECTOR_SIZE command. */ + + +#define FF_LBA64 0 +/* This option switches support for 64-bit LBA. (0:Disable or 1:Enable) +/ To enable the 64-bit LBA, also exFAT needs to be enabled. (FF_FS_EXFAT == 1) */ + + +#define FF_MIN_GPT 0x10000000 +/* Minimum number of sectors to switch GPT as partitioning format in f_mkfs and +/ f_fdisk function. 0x100000000 max. This option has no effect when FF_LBA64 == 0. */ + + +#define FF_USE_TRIM 0 +/* This option switches support for ATA-TRIM. (0:Disable or 1:Enable) +/ To enable Trim function, also CTRL_TRIM command should be implemented to the +/ disk_ioctl() function. */ + + + +/*---------------------------------------------------------------------------/ +/ System Configurations +/---------------------------------------------------------------------------*/ + +#define FF_FS_TINY 0 +/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny) +/ At the tiny configuration, size of file object (FIL) is shrinked FF_MAX_SS bytes. +/ Instead of private sector buffer eliminated from the file object, common sector +/ buffer in the filesystem object (FATFS) is used for the file data transfer. */ + + +#define FF_FS_EXFAT 0 +/* This option switches support for exFAT filesystem. (0:Disable or 1:Enable) +/ To enable exFAT, also LFN needs to be enabled. (FF_USE_LFN >= 1) +/ Note that enabling exFAT discards ANSI C (C89) compatibility. */ + + +#define FF_FS_NORTC 1 +#define FF_NORTC_MON 1 +#define FF_NORTC_MDAY 1 +#define FF_NORTC_YEAR 2020 +/* The option FF_FS_NORTC switches timestamp functiton. If the system does not have +/ any RTC function or valid timestamp is not needed, set FF_FS_NORTC = 1 to disable +/ the timestamp function. Every object modified by FatFs will have a fixed timestamp +/ defined by FF_NORTC_MON, FF_NORTC_MDAY and FF_NORTC_YEAR in local time. +/ To enable timestamp function (FF_FS_NORTC = 0), get_fattime() function need to be +/ added to the project to read current time form real-time clock. FF_NORTC_MON, +/ FF_NORTC_MDAY and FF_NORTC_YEAR have no effect. +/ These options have no effect in read-only configuration (FF_FS_READONLY = 1). */ + + +#define FF_FS_NOFSINFO 0 +/* If you need to know correct free space on the FAT32 volume, set bit 0 of this +/ option, and f_getfree() function at first time after volume mount will force +/ a full FAT scan. Bit 1 controls the use of last allocated cluster number. +/ +/ bit0=0: Use free cluster count in the FSINFO if available. +/ bit0=1: Do not trust free cluster count in the FSINFO. +/ bit1=0: Use last allocated cluster number in the FSINFO if available. +/ bit1=1: Do not trust last allocated cluster number in the FSINFO. +*/ + + +#define FF_FS_LOCK 0 +/* The option FF_FS_LOCK switches file lock function to control duplicated file open +/ and illegal operation to open objects. This option must be 0 when FF_FS_READONLY +/ is 1. +/ +/ 0: Disable file lock function. To avoid volume corruption, application program +/ should avoid illegal open, remove and rename to the open objects. +/ >0: Enable file lock function. The value defines how many files/sub-directories +/ can be opened simultaneously under file lock control. Note that the file +/ lock control is independent of re-entrancy. */ + + +/* #include // O/S definitions */ +#define FF_FS_REENTRANT 0 +#define FF_FS_TIMEOUT 1000 +#define FF_SYNC_t HANDLE +/* The option FF_FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs +/ module itself. Note that regardless of this option, file access to different +/ volume is always re-entrant and volume control functions, f_mount(), f_mkfs() +/ and f_fdisk() function, are always not re-entrant. Only file/directory access +/ to the same volume is under control of this function. +/ +/ 0: Disable re-entrancy. FF_FS_TIMEOUT and FF_SYNC_t have no effect. +/ 1: Enable re-entrancy. Also user provided synchronization handlers, +/ ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj() +/ function, must be added to the project. Samples are available in +/ option/syscall.c. +/ +/ The FF_FS_TIMEOUT defines timeout period in unit of time tick. +/ The FF_SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*, +/ SemaphoreHandle_t and etc. A header file for O/S definitions needs to be +/ included somewhere in the scope of ff.h. */ + + + +/*--- End of configuration options ---*/ diff --git a/trunk/Arduino/ArduinoFDC/images/ArduDOS.png b/trunk/Arduino/ArduinoFDC/images/ArduDOS.png new file mode 100644 index 0000000000000000000000000000000000000000..d72c238b68a5ca907ee98b9c8d1ec682b843a4ac GIT binary patch literal 46331 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 P$~bRg@lWpG(8vD=eV~uf literal 0 HcmV?d00001 diff --git a/trunk/Arduino/ArduinoFDC/images/setup.jpg b/trunk/Arduino/ArduinoFDC/images/setup.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4924e0765767ee5aa69edb49de0aadef8ff2b041 GIT binary patch literal 1237219 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

{JZQZ$kTm?lPzZy5FUCYMS#t(B(P#A$^ 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

kmMI#~w}21IY3Ny5TWXR9L1Vx* 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

-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

i99E- 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

`qgo7_H~h;cHHJL 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

csszF8zqrcW=P!m8FJdIjFC zmD~XXifnf6b%M+z+;VpR02L`h!adQdl^NaG(!xH@2h6NK@aLrfO0h>L-d~rX;G003u!Se1mEG$BLDw@`^laa>E&6)3$0RR)QZb zK#!1jXEf=C=aH9kGp5}227nr|LL+EbYO{}-mz(M7w1D=5P=9sS4zg=}8Im3a6OE z7(8O3b!28mkzr>WM;`q1QO=V*h`wWNEJFgk=A>AULx$KnJ#uP*k*8Z&SjEhX#!n>E zmu!MOgS&6fp7jcWlY+?0$;je}p<>M%vll-$?@BLVB=Y>(m2>i_I3)C`B8E8%huYgm zPvNNIw_uI)^1}?nwMpcwMX^ThxH%n707fANRZi!IGIxe*YEK^ajfU9qh2o@`vmML3 zY3YHSpL%bX$IR^`j1UU<_Mim&3`qWOmb;ganDjLGODyt!?UmyrBqz$_>qna$#Ksx6 zxBAXH9@zJ#3fCT629iH4@z46ttvdihhAHG}7A7qrDxh$nidiBNB%76XfCX{iB`*LySIb4`}g zIURSqZT|pdbu~?P0#7e$sZ|QC^I)8sE%fZixHjdWt6v#eQ@Ac>T40B!1Z%ypwptU%vj!R^GM{$Wj#@hR}Og z(dGO%iLdWTa-+w^XB26^Snht2e$yZDTVIBM10}lC{1vCk<4tlDAYV*&*~I;bAH{=T zoBsf`Pwm6;C-$t>8&UDMinTV=T20VtmM`R6ucG04it>Ee%`}$#e6$U;41C6<^6hMG zRvD&MSk8A7)6l%-@M)w~cn5Nne}utvo^I$qb7o z*5F|L%kNxgi9RW5_By|lX0yyua!5JJ_r+*<7vehj$~%i$ql((;PT`Nd>t5VqlCnpW zD$|p@HHMSA=gfxcMtIwSAnFBF@n6KfE5Sigk)*j|TgZ>^F+I&`GI_T#shOE09By5s z^R8C%z-V6*Bh(hw8Kasb9{2gYw)MfPTk2=l<$GTk_@l&oCDU|Yva1qSTZj2a;nu6_ zx^Ic}G4{7FaHd#QfPW%8bFr0&T*J*r3{w$^Pf7D2gW7#?8hR^!+& zq0jhk{!LO9nWQr$j2MI1)~2iCYh4;)=Sd~b?vVkOZflqD#7*J<02EzW+&lf9foK9& zz|-yHx))Lc%-O+ipnFiIVtGxi3&rs2zGTr@wYu%vLyx^&jCOzUh)^ z7xJD==W?Evr|^4J{@U;oTH8qqURl02zwwIO(4n{S=Y+1KxmA)IgxSgE7EqS zH-i2k$zwBZ{o#m{>JJCk{iz$2e8DEqNgFh)>`Hxveh&{3q8wF8ol^d@teH z%-Zg>!X*l&mfcU@k-mf0ur*tcuxbl5UVYWn&Jq|S8=7Z40gq0V`oaGI1g`yw8}@1V zZzqmCOBzk%pA|+7NJdVb0URjwBx5zKV{J*PE=6eZ8yDqenL7Lac4onR|+CCx&KX&7Mc0sRV41uO4EKN{`~L8Rp%$%)xR( z<&>&`20PNoo1taT-XxAY(%VADHj~TpSF#S&@_%_6uinP)d(r@o9g(i(R^SpBy)qem zgmwzvV>UhM@gqbS?)Nl~-bmdfpLzaKjzv!>4f2*oUzSB=`GD+c#RST~c{essrAg&9 zcQ`ISaly|tE4DsXVYRu)>L>wBc^jAbPI(<^ge=l+-Sam%B9+F;JjPb?)Mq2skrhiv z_qVYu3G6DYPNa)I6>@OhF-&C$P6D#-+y*m)N+Jy|{ogS-$F&Wq_#+6%o z?&swnbagbPNQ)mUZs!>3K!g$Qz*XGM&PnM=-@S>lK-zygB4fKgo|KCiiJ7tPMFDbO zFMaDT%e2S1XNqiOnHA(^WgKvM6yWZGI?LuS%t-sb)W`$~`63dlKgggq z6ld>JmfD}g>4C|pn$R+qV9Z$VT%2R@sbS(W`*6hLfmOL8Gca(gf-%l%z;F4ac4iBJ zJ5W$ISLS2a(uagX<>OZQKse7@T%a}+xduK=b@!){=a!FXQ`bJfjW7W$z`xyLouZu* z82(jmGr>I7SOJ+yLGxjHj@kOsMYJ~hftBL~4yJ$&#lvmRQ>bCqoDhx+cIYXmYkZ$LZo7|qaR9{3zkD7j0mc9$ z+;;8sQ=TYS+Z!+*$_Erh5HFcFryLPT%zTo}yLkTqCV(aK8aBc&&cks5Y2IG-4BM2B zpo)$d*hafqnb>1Kf}ON0DOP3LFmQ9afE^%LK&!c!9o=d``}t$_`c!Ox+4+d-IHv{L zFoAr`aA;bSaZcC+Ki0|Reh z6;zSW%zIOo42J#?$1HQyQ#`HlR(x-L-(|XaTb(2HZ9?!!Jq-jBfYZ zeJM}wz*Xik)Czcwgk4w5Cva8kngE0lR~xzAjCQBT^OkMO8BeELYYdj%gXm~Q2jwy< z_aE(01Bx@V2inEPNEC7wHEeBB(uBYbw;Y~NwIKO}E@W-T7{?f(2QFomc*>tn)YOGk zvon0kNf+mT+_PaZF~)Ww&$2G18<2U8I~2 zds9qn2$70y-Ovv7s~mxMZBz@u9<;tv`NxIa21zHS1d*ScZ##JF*i(!PcQi1r*4}<& z+?phfCAV)gcI^DWTC3t85l7&!4&7?kNTqDyEV$!w#zjn>mCD~le9!*?1swRJ4!Po8 z7r=J2HtdORLN*s3hP=;C)1%SsQrTB)V+vIKpklextPE zYk0Bh7gCKj&0V&A+C8&X{{Up)g>rlg{g<>|Ds=wIu*BP&f-T({HyTJ zthyhKbR9vSXp+|QH;~7j&y$Q1+*j$f{*$A_;fp;=dxe@At(AfaIo*JNop8zS&Z%mX zIgg2cCmtcy?ew^AztOE+NjB5>kD;p4>M)45B$1XM!`8WdItbyuy1GE$=@S+kx#O^{ z8#`#;?W9Q8dE}he4>vQrG>mMGeLTcw%&mndEmpUp%H%OA(S55aXN*GLV&iun;-3(0 zzb`7iGJ4et=Cl`av@E$&?a`{-moZ5auFzcZlC_m?@a$Gp8;(zY{} zLgz_I)5~St z200z^QAwn#9otl@^uXy_6U(?UMf|D}F5$NXdgHxIDmN;fHZnIAQMly#)2=NeW3{%j zk5N`6f8KrGqqRm3cYMDue9>UkAca;xmujl;IL2t&p}t%R^^4=57DJ|9`O30M zEQe~wukw$=zfj3|4uvGAi+A!q7c%1N(|ovfWO@gV{{U!R zc4yOf70ln;Nq48ic`=F@=2M?9NitNki#dF z8N#Hw+T*?}?r6&cgpVyarDNvnM;VHjG~~|H!>g%$Ox4>%@NJy8mx`pd**hVF>c^n2 zuKxhxH-UZ%_+;F8&&HZ%_lTR8vb0aMY&}T&=Zu>1yRRR3g5yh)$4!~EYaHfJvo6Mz zp2Uu8KF7hbJ-W8&{$|}Yk`2%mvwzAQe&Hn&LhiD%>r|#8t z@r|ydFt@ReZA$EnDqBQk=j+FM;Xj|+aye-l0>PYT$0UDZGVP28C$@E^*(&*5ME z5zFF-#5fW4WRp*hPD)!x<>38Te=7OhZxhm|b#~8ko=Er6A221N!FIA;h~$nq@QUBU zf2A<^)5De%DO-Cnb^KBs$@&3br9TdT;NHfUW9t{im4;bonWQK6#e2uYZ}=gHf&3{N zZ?&^_U%o}MWd2~+fm4ee?@b+xCylKpemq+IMbtHyiEXCTqqk)$u-Zh*Wc*S z5@RZTv!WSo2&*Wcg_9lNapK|OeS-_OFh5#l$A(}j@~m6BoMW2ddB!Qfjhg*NoxT))H0a;( zLCt#k$e&-nnk;aJ;EsPP>ogzuH`_~8NiMIiWO4V^r!p_A_$9A^?PT1#RAG4Fs{a6meU7D-cCs%_0g7yv@Vc`!XffB0YF;LN*->`RsWtEtCb53^a{;XHgjT*XttBsFh zJ5d$7+bb0%OK@>Vw0#)8n(BPxd;1aiU1cr(gJM-k;6^%B@&3eq6lQI@MUw9WhmV0@ zLzD9Systx1ybCOCx;@*52R$kKNp)e!cvK&-hl0sgZ5vBx?}$LD6ZRnRoxEj}!}@e; zzr?VCUfMLJjdQw1siL;?#?tS%9F5&+duQE`*&YUeV!s94Wq-2t!rq1owS7org#4}dk4y>~{I$vXjxm~Qw7anOXUVre@JoM( zS5ag84%!{(?<#;#=~S-2;EsO{^)$?yTDPFx*YvNhCx}dntawwAN@QZ-g=}LLUfO*d z1w{C-RsR5jDttSQ8aVWOc*AqMt#gwT3>n3{ey$GojCo+;r^%p00gJ_w=3uE7uO1dk2Y=Cu76km0D@$E zS_g5{QstxQUObxp)L#q6o3|?b-2L8_GI&bV#;Rdf-PGV#(&L=kPv5NH&g91-!KG-^ zNc;o8{fGW5X%1tP!}Cm6?*)X`O~>q|@iBo`@a@8^f5Kxm{SHC!>r0v^ZLq~6@NzR* zH=hTzsiY-V-M1XG6cuZZb2zV$?<4(R!ruI+^TVn90P((v6zUoz(1tt*RspJs_&?%} zGv;j)X*|Q80pM5kNq6vXM=%)8t(=I%knpR2FNU!K_G0+r8(jW*=JBSNrd<{?YNvh&`m?sD9}={?xxP(K^4WS75TBd$ zuiq_K{s|}W=4NjvLA4p=<#|_1xxW~{1dCkR<^eKvv{lF&CL65bh#%i_Jg}e z>5op8`f=iK_#uzNXr4(U(Dpa3H&=#yO#c9aEqE5xU455HiCvfEK3VJasGfbyuFb-fd#cNO5v*M@x6U*Wwc*Egtv3YOh$ge({bM||*2bE#dry1*C zso$_q{1mIfKetbVS4G#B9UI10@d&TkGxPHyt)2$)rZWZGFN+iVPfSu$-teyG zMd$&o)O5MecsiVET zJ8>M_hdF)RQkdE$`Jq-(-Ay?b+%tI(CA+flN$6^>G16Pv$82D@hDa7b0Wq8p&a6Xg zC9XV~jM0IBq~wZnwcK{*8Jat&WC63rO(3<7QpHwiOCAV3nglFQ9M85(KeN6wyVshU zH<1DIs8DHe5RFDFjCp-2U?X?NcmWUj)syb zus27Q0F#4GUVc^^Uma?Ic`6tN^y^PCl}tD95b_A^NT! z*a{(Rt07&T#W+G8w;|fg)Mu>;50<`UWG`|JIgw>MljW1R9qO(CswM}JuSUhYU9IxU zoY2_0T*h|Dyki{DlKrFaF3A^;ooF*`56m_<-aX9>e7}|Px3Q%J&BLx74yKw;7i667 z=zS=-3J;K{y0@(gHa6(b$&3-&nm1eSR>MZ$r2#y+^10id2dw}pRb#nZ>M1a<$jZNO zdTv$2GGI4wDBLChV5@cJfE~LERhJ@w8a4j%H-AbDpS;@LF~%vQavr;vsn2Qva{8g@ zc@)+OGP1YI;PK5hPEX5)Iigio#^veWfEAqdZfSP;S=z;vj#T!hg=I_<8@_07pYF1$ z$4USRLPGAw?m+aX5XbL;eK@A$c-tb52Mh%{A(aQpcX8f;2+@=7zU4hedQ^&|BX7#b zy(Ca~QlW|D3Vv2lRktf=6acI|!?s2G8dW}6+TSwfg&00un~3bjhW`LZKQ>uCXeXF9 z`3EcWN9bv-6M!ax)pne+`qP~Kk(JNQ3m(3dT(|aUTc!D}+wXV91HHgO=fU=iXC89$ zR-R*D5k|Kb6|BoXrsL>r*15 zCXBxl_I6J19;9K8)*$D-?QIZx0Q8n!v;4T9xB$g z6qi;O{wUEHv&DmR2t8|^_>*h>mbU)@5WG7XVw+>uY*2r#Q~v-hG3qPlbG)Jz;m;MR z^|>Z&;?)|A>x%huaM=KKrf=GTN%@a82A`|j>soES^^B`EtxZV#32eTOje7@BY^BzSLHg>L(fF~R4pNG?$0EwuH`XL5xxaf3?5Ro6MXoVL;FP5XFsW3{+A`qSnDLZnhl zgV*m5N^9L`A1V6NTP2mS3C{+m;5EAXkL6AWJbTk#W{W3i-Rvs6NZlE-$J2^eD#*NL z%AcEQ91nVG;h64jamG8<6Bn5*Y#gj%lP2J*hArynWxhN>^wVUv!G?_c2nWoPHF5T=P-NxE`JH z>rNc-K3oj*QA&3)JkXwiAW*~Z?IZQ3n^g06ZTYe3PAz~b(Z;}T&VIB2&o3Q0KBv7r z5D@*}!k8SYwtZ=(_Yv3+N&uM`D}kPS8i}D-KR092o056{9PvgzUPn_v4Q1H9w*LSs zkJpy#`O}^E9lWj$GE8nCdVm*x4tx4j8cuTDueAkoHy^@~E)yQ7ucZJzW>gs6_q!Tv zOt@pg_N4N%{D9tum|_I|-M`j=u*uF@LFd2Hnpi0w-jyV<`GYv==}@#70~@}EsoV%< zxLJ{u{L9}pUPT5){vO93m11aqRvk0j(yH7kDo3E}QV(Oue{Ro&Q2cBCmwZX0ZH`I& zmv~HrDhOKqq5lAaKzOPhJH#IlJ{Ib7%^cd4GRXvT@gK^?TWGJ^>+LQ*Z%v-nhSi-6 zZJvi9*Wv#Fj&v!%WS{sd#ikW)tZwg&dzj%wavc8vI{Hkyue74$)ogkAh*_zhEPm7< z4WsZ6#xD?feoHeA)E7_WPaaid1mtJ8wQ?KfwOz6{Hy~1R(!R<60D`-GDt`|6{{T$! z0eH=>wINgGox?cDIUcp~yq2*|alL%ZM!c!-UuA=>?I}f{Cyt6$9gMAfeU32rW*Ose zdSp9p(iRPgBW~w`n!l)7n~P@I_gk*x(z22TRd~@)?>Nc+6I~L~+~tm_)6`&=4Z=^p zMl)4sc;vUYkwY(%_<#1Q)r{|dVYWg0$Oa8jo_0{s?Pc70c0K^Rj z=S!MGL^ntaTV4Utk@{l1^4Ux+_f)U0d95VbjAo>?0Na%D$3srW0oWYU8Q^0lr&`8wzUHxMGdn}LlTFrI zIfweeg)Qq^mr!pcv5ay<4wF{;!6)24;p+#)9j_WYuy`A6X~rYsXG)5q*(jB{7j8vW@@a*0bi~S*Hj%Z{tylkX2Y^{P1qP+I|)I2Z+vdYXxVQMaJ`!1`A|F|j&6 z^;7qcbu}p)f!oMl-jx)4R!pz)3Xz7?_il13u1i{sl&!tm$gRN`9CfQVs5K2fXbHne zryp9b$Yn-mRaFB3A6lBm@I!?=PTr*Tp^H>->u(~?$f|tETc5(Z+e!Zb;UVz&lgnlD zn_+N2)v)MuP)fG?J>1erjL=*X#fRPosrXY``#!TIDE+AZf4qBF+Fld?0D|Ox&idt* zuA?`_ABo-#nm`&|5={u-M;im285baq*&dbnpR2doBr%JIwT%}o&Iu#1ucm)uANV8J z$Di9{!9Vbnct^v!J(q`Fvjy(6I@-s00m0f^sQ1PzuAJA9KaP}_1tF+C5ZeQWze{{X=i z{{U#u+1|qERn|Nr+NP5TEc0k3FQScoeqNtZUnfnb$!P?Z^G4S4K`|4nsaIA91TZ}a zuF8{hUWRn#1nm*F((h$WyQGY6+^5!vLYs#38G~bi>Gi00skthk@}REY>sAXiaI*A~ zxzAkJGtlfC9ow{-kN1*C&|~HL(}Q_Qy-r#~h69{?(_-BdN4Lu?+>@MQrD3&pkfm|S zU*fF7!y`qCDVjACd+x&zrA=u%7XoJe;{YNH{1pUYwhi(5Xb;Nk&T75XFKc|Pjl0t$ zkya}v%6=@-mfu#6;WsxSWDIg!-m3U_Rz4E(Byz^1%A5C6CtQPD+J%VM^clA>OPGjs zlcw)#$+-AwaQ+gLSc2+1g@yLWh<=agj`f?V=$1AX&nqg%-Nxh8`VU`f z+A8w7$6AV;<$Vv|FZe9C?NjiN;r{^aod%OPigg?9b6csU!uw^R1VWkV4{x$ef zsOm9lw=Bf`sx!3x=Kla|9<_;MKA!i{%ePe2Fqly&-Or%sIIC7t$EZ%r6e2lD%PC`( z_V%x46H1>fOnr)j9QScT!rmV;Nf_>8dr+~oUpo5plg(3C{{V@G(-g7E(2R9ITD#8H z+^reMJ@H;__p#d@t|R0+wh?!5K<51(V3-oRybdmnq9yz zl+3Dr@{+%Mj+KzYAkGWeh>-?!=Vuv12mfgyVR-Fos z?#e%lJs46A&F>KS=Th-+hT0i+ywSzwtl$OUae`~iZPD#66?VKg2uW8RkJh^lB5$(! zk>OefB#gCD@fU~R^q&J;)3`_^?ip2n1|8>Vk*TJ)Ya@W+`uGhW$#?UW8& zde^`I0Kq1IZ4VcI#hEe}G_d|@nhI@s1%HZ2f2`I{S+hd3j z;|SLJHiWPXDD?)mJ|bxmcxzIPWJaFW{X~l=2g@h$;-%B(j;1vto8?FJ*YNvL*F0C^ zDK*auSlH{@KC3Ac>Yf(y8edw0k&^MY02LS%YS}*L&@v_Ip8c&II`|Hmd zNKO8ZF3IhQ5?kE@M-Lli zbH`j~uOhI1A^c_WAIDD{YMwIjrnM%w;ydXKw-e7N2njqW=m7Kry$l6aP2O7^vcjay z8<|U8%@Fd;gmIJ5Q(83wHQb~F$sV;{-hZ_jO8)G(%%>SFKdns#%E=O_+vYZN$K9;! z$x3cZW1^nAApuZ!rsBJ@MM(@{E>~)WQaK0Km@ZW|{Mp=a!3SCvPb@KAyf-61bXPQu ztj4@i$0M^x^5Fcy^ggtCBJ#k&z7W$dAoaxviti!$h;GBBIT08i-3+MPk~BYB z0D=5xH-}?=HtE`E)2lk2-B|3J zH91w!e0x{2{>NXnXNW)GoL{wNpN~8*r`hW(3N$m?T*eB|1O4Ew)mzYt`Qqz9xQ5N9 zj^0K{Nm*P1La^^%i=nii5k4F&_R*O&O$~7-)ALB9p~Yj*Hn}8iD5tDX+P?&U!BajS zf5BmNyHA9AZ^Hio5Ne(%)+dVc_xnsoC6<*OY#K)n4(twtAZD(A!Dc)S@hkR?_)n&M z7Wg;dkL{fw!zLlETtTup;Rpa&l#)3-bg#-^_$J5v6z^XD0D@%r@5G)U(EKN&_=;~4 zTANpU_B^Y>UD26~G3pV_1S4mbF#@W;muvt4*fl8W0?&z2Hg+|bzhGxmb`1LA+#{{U5c9~5|7R`AZK#9QpTPnDPq{Ehrw zJ69QHr*G4|&Awjj4DaNeb6;Nn0Kr#(;IA4_{1n&2-WStsdAMJ>BL1f%`MJ|-)333x@c3$O{&evE;>_TnPG!; zo24qi91H=Tq*HEg*5%*j`I`Xl?L^lM_Uu$|+r}5M^{+NYiY~%T15CSqSotke+sWm! z$iHz&+C5EFX?MDoY<4T_Pg!s<7%KG`sZvF9mGyb1hf-Za*Y`IN9s87Hf3%>iK zYcw(2$ESR;gn zOZX$e{vY_ksagCl@f4mT@Kk@iv$(oamjrY2ka^(O4-KRu0=e6_<{bB`vDq%2Cz%SY zd}E4|E3$!^yuXxn^{i@C=9STLj8=q;Z?Z-^Nmfo+bTktmmV!kMlgS-%Oq%LMUzK+D zz&vJ=(N;~nvgBlnN=5RdSZU*rF-E_;m#M~o3X(9EQAZp~iVq(s$2CqlWcxFH*yN1# z1FcGz3<_`lG1zo9JohJ*TkSb-qy6E?3x@7-U6;Urj3>h{CWEP6NNnUKt=>=hW`7#v zT5Z8pAC!Wm`qh0x&IxUnH&$cNFzScaw1a8fhZNE4-xmByr`dQy=JBjn;`v4(nl>mC zJa5SURp$Qy4gMfLn#(4kbhAToCzC47#f}dI{V`U5w@$6$)1^$!<+Nb|&T>Gm0xdRF zy_(%&l4%A)s;1-ht-i54*nY|u(DbhucxV0)dugWAS!S}EGsE2mM{lNoO8qwf0D?q* z!QZm~0PQ*Z6yJD8wTKZ5?$F3HYipXMcABf2HY!9wbjujOBZZ z+OD=|6?oL;YCE2}{{RIx{{VtMX}_^oz|BA6uYh%paz78>UO@@)-mIJNEsTc+20G(E zm3%AXYnJgPta@D5`i7edzn>I0F*GdSo-<#)KMel>ZNGwF6cT+)#eW^V8{*Fc2?nEK zr)ze*H4Q#N$V`702ORTW4gUZICiq?ZJb%Gh(@)nv7JOdtkB59);ppYJOBt1IBh&yN zD&XTdE5Ya8%*`XK6(4l< z&VB1^#2S6)gmv9ZOTJZ)P||K*(&9MCWoA=?!1o8&y;Xn}w>vjO_Kv3 z8|q%wb(WMYFpY|-wHU9Ar)qwf7Fv&^tsECxvn?$0Bqy$bk7UhIDG z?^%0BQ>K|bnr*gM%U#j4ZNqcAlT5q2_+78Aqig%P8Gtbd>-be)v??8|mD|pJ53M>- zx00`z-e&CbPDKuVO5{l&L0Wu3viO0b*j(96qUex>FdJ0&uQKuX#anw%6HTZ2(p)kf zjK~2^-{*?tybFYHYh;`fEFq|)JA9}ww3Gr_;*yN|v->Yu_dhRgA9;zp0*IQ5Mu!mp`ZEJo{5 zk(M}|@yY)H8smI3um1pH>bAP2tl}%ENNE!|-aC)RyHAOJ7_#vdj6NXJcPv**446E| z{r>Jnc2Z=Qp+jk?*IQsRdHBTRS*j_g85o!{X&fy_! z{xwk_&wnyUXyJu66(^}2RI*FbUJpcG+qqXI4?h%yKG6vs92W`G*UP z=K`dTBq{?(^MT06QA)rzEz%vIcWB-lG_X!C0>0PY0aNH{@mhuwc3flwL>hX*aT}Q% z=4`MBI23Y$UiRqOTW*ju20gn{TIwrz4qIz3?g=;*XZtsC+S50Zu2_@b+M6bw4clfy zL_HM(?F9PK%D{|BRJP^)+b=V+CP`O^;QS+^uWM9323GeI0O)jAcK@4rVi8(%Q~Y3^2$NHdan?+M~DA<4~c3 zpD=Pj?beP^^cqBvD=Ko?z;9}iKhdNTW#;P{Rp<>7MI;OvaLb;Du%|^DuF|Z^rHO2H zCW~kUCgEek@}+--cBexs%6ARQSEf${RIOyp>a7~EY~{a-nf54(eC+=Kx;P57a5iUnyI1{uOL!mRk!lx0%!cGf`e>wzr{G)tNfsep8>quaTiSE0v?XR#DF7$tTj5 zFP)Q?228f~IQ%NY=`b%13rXdis_w_*O_xte-FD?;R>(e{)T0}Vm~E}lXw?=*-_B5u z-t_5Y-WQ^r;1YK8Q#=vD11{_^?xUqOqAwoSP}$(;sG-Dn8jR*P3S(@2{GOkcGUn`s zRfqj!U@m%7=d@C)n_G@XIH@7EjwMg${V3%NqL=oIOdP8G(XidQNL>3GRKFW=%Ogqa zjy{#9;bq#b8igYVih^r6*^F$v*NzC=wAFIhT*FQ0lOp}y$}&cJRZ*)!aXUx3SE($g zr_|PiSV3!WIY~I@V|>*ddQ>q*C+^pDj9ZUR*`mSBR9mQKg@1h;u(^unL2nsmW4k{v^)%To8&Fm9W{+~7 zKs~)GK^$!+(yj86#1Wj-)}9_3?CP<^kw(9ML-H(R)SvOIRNK)JDW$npbx6^Qv0ch? zRMd|rm2D)`NpE9pzcWoU?2QMnHQ=AMxBL{R;OFdZ9JbSH3*zq+BA+Wyu#iXt{{XZ_ zerSHwpYT)fiJ!Hl)R5iXf5JK8_GVjMKG)SJ{x|{5nNd4a(}{U;z)8lxK8VM+uV+|`OW)C{@uS6ziYipW2|_B_eas2{Z^S} zA&xa)_Puzo3Dq^L9}7h!h^Zy?iMi0eUH-YQe)HnomngB>+fHsz-{XWG>+UlAgAImT zU7stA&MQ@Ri?TXl;XmxRl4zq?*|}+@`_1o@P-;Fkw$anc^COZ;Im#N~wG9UD@^+Hr zQ@fHG#^nY=LX$;}qX{!q4VD{{S$LxmkDj z@?B2udERnxbIl~N{nEvPu;gRCL?jRMDQ&^FkOykhnTInUVRLIVGe;b1w-263>r3HH zPyP|TePwp$akKzB{{UKQqN}iA7Gg0N9qTJt(fdkMwRUX- zYM!;3<83{)ojsW+Xk>@y+=B$;oKf)q09uR1J{VhxBX+onLNh0PahlhWAVgPf&hhm_ z+*N2sw=ujqt&LMpj!13}-@434Ppw@MO(HVyS8~_~ZWnE0X{fdutkFXpamO>62pkYk zwR8;t6Ztz?WRU}IC#_ZNDO|wu-kjQLwY-IuS{M1r9armGx>V3#vdKFvgr*b@i&_tC z*S5D7Wn#q1wS)8cisF15a<*6ZR&$S<(qb0}sHxlzg)D5W*v`(el{{nb8n0 z7tgeM^N#tfn@s}T>$6{8O(c-2<~WDlQ%8fPj^|jqzG;PwIWejO{S!dQS0-c9%@CNlg4Og>e#z`x)-9O-spRq01#mkFd zie5CaNc=aZow|GzFE_G};~(sdSLyZipJ;U<8Blzyv!btIRCI3->E09Yj+vln_OaRN z8Z1KE*4{C-6+p&u>+e@YEgCNE%ikHTypKAqZ)q!!ia2ff+*w$3KC~llbF>vIH~`df zvZPJ>pxo{q=!!zPWo^t(a0e6_iosoeW&6409N_wzmexIpy*Dt%>Q#<5`C|&Qb!_&g zMLyP$G-X!+3P4O5ijAkf7~`O&U%JdbY;l$q6EuR!m}5EMb~PZEdr9Sn+P`??f@u?W zHG;@gvNJqjfJbc63Nof2?|XKqV+;IQamf`Me&Iu9w&xVsabc0PY)nxpKv~ zDEqkk!iAK@9__g2r=>WvMnT%!v4OkNqd8;ucY5Z4vqX%mGCH#nyC)-qO<5IXJoAn- z+)^v4ELpbg7zfsrH<=f>801h$=!uW`zFt8dwAg@5DzBH3lb-YxGovrd^8CPxab=NV zExUYVepOtc5lR#0-10Cyk3mGcUD`n-a&hPdD@fM`x<(lF0+I4hJ6U>h-m2g@FO?t4 z-eYyk9x2FK5N9n=I$3>t3A2vOz&9zQ{4@z>YBs?nq z@Z~@~C{_j_zc0)=$9e|oLjM2`G5{0+Fxd*TdgCk7l?g=waJf^H+Lkb`RyNMq`5^YD ztiyOk!+OvIwCZs+Mh4OrSZ z8Ar{xg~_K$_dLlJcPQwzv8LtqVe@im+Qc^Tx4#|e0YOGp`LWJVJt-DO+RQ%pV~(_i z)VG!b@-u@@ar?#p0B87301GxGL-TyyLs2sR^J{;5sHdA zm6L{M-JD>Kl{`@@$F*KRlw|HS(s3C1moJUE?@~6gaKJfX6&AT8I zL!T|Y&zYYcLE?hABjv-lLQiT>Hwf7K*}%x_K!)#Nt+hi2<*`zi*|+$Z4u+#ye3r*O zItnFbJDWSb1pq(IXw&YmPH|1$=EkK}l~nZ|sR0>PZ@rGjngJ{PSyPU^XaY=QaP{@1 zW8~!SA1KB)=O&l#pr~9-;@^0zubIk^F3mmuQ z){|=$+%d_Z2k*fpPI5WLLlmB3ugkY?PfoO@gMqkhVtZ1n?p@32kHUZ?C|z*P$6Qk$ zQo{=&+It#N8n)644!rtMtB5(H}qFmJcm=B#J|QYA{6S%>CmsoDtflBg>q=klw^R+`u}akE;wt^;s)RT<@L$v3pt z?d6}FBj;0J3n@14&%2CltcNtG$&xW6NxX8*IM1=BX_|e`sW@1%Z@I8ZZQm&Bf1M)# z0H-9!%uyUYKf3ki-?i7qc|HdI&$_0iYU>uEt0&lOl@BV;Fj#lsW~!AZIjEyeP6Og@ zqQABm?SrIvCr!AGycggAZ!g_WW1eAxbB+llU{}(Yy4Tw#SlPDyoQNY{=%ay;!n~*U zB={q1`#$^z)Aft3vul1Zj9uMI<8z(ds^hO6YtbzAU$i-xc``}n62$dUQ;Vpa`D3yk zwjq?2QE$1TQ)r63OI43+;+?Jj>yuJ8K;rorN_KS;jX;(iglDwMuY0F-C*GsjV zYg)|e^D*Eu?%)dg`%ct0=+=>{vfC_SW5?YUc)Wzgp_Kj>ePun*%1*9-rQ=Efpr8b3Qh&>shvPZ;$v{ zvDDV)ortY=vo;!y**7iQvr4;1%kNW&S-bs5tv1Dj%fZ?`>d;RlG28~z)~J%ZSPPBc zC|%qiTmUUW(!Nl-Dwx9Mu)Q*RRpo3t_stSYrLnnxI=doyik8}Of?w}@p4D?=kCc*g z%@DTEr$0)aodEzT=BhCcVH9M0e>!r)vlZK)r7--*Z@1-5+{k`k(yWr$jKG}n>z?$$ z(YpTtwVI^2R~IbE>$QDPdbe!?i2h^GY6Yg`!92D4_cX$a=kWEQoPJpA%`i!|zHI${ zD!E0?*hPnN<9AwBkL=}{zGcrjsRSpPkQq|+Pn6+@L%j_;K$XxPk9y2q`>`` zOpU`!I}V(BX1cKWT9u@sNnM!Mtr#oRc1NP?ny#OqXwzys#-nec==STrYpa*o6nDmY z*XQ@`wf_JGx6^zuZ+tiKju`GFi!n{DOnzMFA155w#lN=y0Q?lU$6vL+w>xTAO{DmG z5L(|#wvm-F*uFZPcCVOhFQoCs{B|;GG3a*lItebP7+51GmILWuqhve>QlnLIYRj?m zd8ZT8hq*!P-0uD${8!h$Ie4n;Qr5L=ol^d1^Cd4Kk&aI|9f$OV#|?_P!De~SJQ_&?#M@SnoFR@OC3g!1qFNqn3!?jt6==U3L|gG{!IQu8ivH)P73 zes%hUF!*d8FK0?A9}iNcd_?)`JKW8mRJhV@!rKWXXF2)K?Y~b-%=-kFSN{NPy8A?u z6(J%A?;mQ{8tgOek@nle2|51&Zn?c@#PZ+YdC^GdBP2#6``s(U#%3)o&r=J5P3@^_ zCyvfWcUD=LV`1d2NhgVItgVloGRNO6es%f^(D+yTH+ZY!{<5MAeM&``^^A4TuNC)S z?63a-1Vw)om~T8m9m1;+K$K*G^di1T6~q*2yI$=2YB@yOzQ@3x6!7-F@dkE>Mbhst zl$@-rg+V^m?!O8@;F@0)zAFet;JUMk*f18*?Z`ceCckFB1b@La{0Z=@PJ{gi&A5d| z($S1&zJ>6&!+k5l@J6u13}r_^mGk(HB(Ep?y%FhC%V|gA)cm9P5B~rL{{Y+HT*W_# zqWesE4BmMzN&HSL?9YTB@JSzregd=$7K3WCE(S{f0Fhr>TH7ja5=8S>Y1j9?B0Z7Kn{ zkC~U(y)s1IxbgT3=5-vmH&E_n8wFf#jc__&YySDvDzF{F+7Q(?+cYnL%_yNTm8;R`zR^0&2GOLa!) zx#FZ|QXA$#SB|}EIfBM|M)3yo7!{{soC+O3pVjP3!dDI<)HxW^rj6)r>NAwSZi zMP@l>_NzWxyDsKcUYV(0-6P>ncXz7h3l-vmLyfuP@utn@H~#=!Rffv8)P1Macc|o? zZrkhDj$pA^Tjva9W-56U_|rRzvFEw%Q-F#o6|heO+Kypziji#}&XmNZe~X^91^K@A z?22&VhDf8Cj>v&6cDrD=JY&+GFSOr%!4|vsZlWRXwRmAxQbT^{2-ZIQ}l2Qsx&Z`0SOG z<7scD4+bOKwMnO|;dy3O9lB&R6c^fN8EW zylrEge6*52)#uj(2CJQ-xkY<*R>s~BQ&7F8$ro?anv~q+?cCI@DyQ);9GW?Um5Jr= zU979_MMd@nUX0yp%E*#qYVIt1bg6u)6P8%`_p0X5mlB|dd`E-DJ_{u)^Bup|tUI%& zepMdBtu+uy&-Z<4#-Ti=V*?3x{KOGU9i9h5D$8vR_qoL}TMkBhdeQ9|`9_;;kMXBD z+&)$E&Nw2S%(y(zZaE8q_zI6`S1KBZcYM^_m?*;J)FLot4a(D} zy%6$ub*7|CfYyRce9ql{d7>jBZ<(0(`csA2WchK|sib)u2OowidF(Y!5zQZ&78!Rh zxUOql@H`sTvow&$p4HM^Ou<>UoZ}T+%`TuE^VXNOWA(eYe(ayuY%?CjS6Y zoY%r1wTJu@8&a|HOg=a84b=J{iS)Pg5=(aS*|F|A^Vrww^};mkw`e2|rn%i`;k14% z45l<)+-K6Yr-*3J*|nlRDgAJ*W-P!*gQcFAcFo?+XkY&0mgHfrm<>NA#){B)r z8TVsr`Y*>%_?PPz=Rxsw3$&lOvatR%KJ_J!i1kkfhR{4=Zn~9@HpP34lD&f;>rv@i z{{Vvj0Ba8gL9J-Fma$(=8qEyW>@pbh!5uz^sjrOn9|;qoc-Gl(EYHaW@EkJwG4-#m zqlk@2^F;Y7*m={JEX%O?Ztub~wf==Mywc`7-rSwQ4?$1z^sgCBy4{-2{dmCnNHtzB z3*Y#3Hlg8L&$nsrxst`-aTw?2_o%J4Ef>e%=^Lcd^(fBP4yHB+y5i1WS93;PQsTlE zwbreT)w=Mq1<&hLZM5huncqpg@>P_dE<=^gEyk&>Xo}I!&}vrS!a(_mtf?<8;l6@d zEbgOeiTPD{U#=>7hsf5Zkz4IX-B$7odCX^Ub?9lb>h|%@%XbCDCjmo`x&;{i-%N45FRMaq2lOn;EvaStBDHoYOwvCQNrW%G_aFwN)Ag zy~WbpTT5{Y#!2#(@CiPmth4NsZPldP6?&3R?{Qb?Pg3M;AQ2z4w6U@0V|1%l@vi)B zkr|ln40=_4Cr`FyX)R`SJP@qi>p^5`B-=O&+4)GSKsgY`d8r~JcKF!xIrOF3<&eL7 zcY1PsxZAfKFetDBk1%z^VwDE%!G~@QI4a0KQ-&X{DlmVQzE=0|OJD?jkF~JDx-h54 zrUuUK$?54$QSy{-`~&Gu4djetE7LUZa2%_%<{Yo38-DDO{JTy_9qFSnu-nS_rxnZQTnl^54GCjf2ax=vZ{*Zjk1d|ve)~5Q0E}_5A z1zC#71vQ&``EQqCR&dC(Ac^5fEg1W`72{_TPK6H2Z2mT1`GOki=+mQrr)jm5f`X!&7DC;U!y z!*y%&+(15LJx(YAkVvyn_FIgsj6PHAL>CdmsDEZ&WlW>@Y~2kF3wXyvc`bIusM>M{ zdB~?(`9Bi;BP=t2qw89CBeP^s9%F4v=(^)+I)KD?12M7x02-3gX#63rwwI`gZp)Ba48$m50;oaDNi z!cH#hbDPp)o8Xtm2|OopCUhSWX6r|ljsmg!(Sy_QuIY5^hLO9hXOWI;&VDE9b9`+0 z5vXYY0BVlg#oiBpwQ1Kq9wtsf&!NXP;=c|*ZC{Ch8|`;A8eW2Q*$tfTk(c{Rr^;WP zbt6BGe0F7!s?|BE^*-MXokdVid!y>ft(zY*vh%^c{NaTWS{9I$Yg1GW?|dYr@2E?k1A%j;ua)hO5@h?;(jv zBlvyjNR}BJXyLlmZ8uia^^0FR#_~I*>UN%$HhjeSTD%&R5KCz+}}Vc>fhbkxa&Xwi!Hf+?HHlh58@y26HRgQ{p?Tz zNWZU9nr8n1F;64q;+-U6nRhar`_o7~@;L244nyV>^5B8_)12-DaQrF^NKRF--(C$Y zb33okv}2C66=0ACR{HT#;IAFJQ>HDq930a!+2Bspwmn)fB!=KM224433^dHPZZ9Xn^%mF{+_!t&y+nTv5zEUZk%sBW(P~`BfW`&OTfQ?N*N~oy)XT63nqSMn4*u%TZXbBYm8! zFb9xWc0AYQm;4+D@OEzu{88|)jx@9OSf#mGq@BKChpPVoBVVl-6B&uzGN-OP*UEqJ zSKor?;{O2bn|V05^S`jz-Rvu#6dLt%y0)vz_GT5S^FgEGpW1dPe`!znCw`0Kr)fmG zb+X9QM!7M(d>`dspSE)U0BCtvQOIPDNbq>-YwpkZCQpgu_`Uld_~YUI`Ho?vERL4# z%WRNmkD;%I{8{0vuZP|xztd%gNLJqJNTV4f0iHif`)t46T!{Hh$`)yqZXpB}E4zX* zn#GBJ%F3TI`EQ&t=DGrX;+B`uQX&GvtW_i z@Ts*~1*W0rXEE*QYK_5YCPsGWl z+u2WXb$&B#0*o|-@-doAt9?Vl{vg8({RdUIZ2bG7kqGV&2l1!sdey{Q&X;{-dhu!& zNUap;cCs?`$I`tcSN))5_=}@MABwd59YauuKET zXgWTd<8K#go+Y#J?0!v*S8|ye1t1J$@_6+%$=b*aY!~ki2|ep#=I_ILyv(a>HlF#z zFkieXq}G;^J0-otykPu=m-*Jxs+lpSmWdS#<3GeP`qP#zp+-Q@KT2^Zu2r3WqqQ_` zX?CkCE-{?*St^KptZdPC5~RyDfQ(oE-f-sjVb=kB%3ksEnM=h+&xh6*8hCY=v;?-VORJDNnD~mm9e=bknNzMs4#eS=Q!LWa| zL_QJtspDUSI_>*4uZgWb)26{R*^kUl8BiYOPeEUwe-j78{{V@1Q0kgpgLq2ulXR9u zk1g}ueJhjFblqd&$BOLr&kgJMI)1IExR%!X(o-Ce5z_=3?sDX39I2|2K9&Cfg2aB# za(>Mpw~vanJE&ScCt6{u>ENc#$l!(x{{RBXuacV6?9i!JVHyvWO?2NB{wH|T<5!BJ z*1T)tJzK?Ev{CtS-0BmV9TU(WO6TwHnrM`=@<13~)wNp6Niox=;;cl-KrE`Qnoluf z>Q~e#^`{n$I_+i+?af?xBEgX%{^=2J2LBJX381 zdsSb|M#yjPQSD+Jk~KA}F+PUN2?dw$3}(2ZvPFp$u48Vas5Rc{*U5VvQY$J)aJyvm zu0Oy5>fd-$r)&mALUohM~BREcX$J*nz^3G5s@NW&X-P z@KUeZL*kdfjUV=2_-CN$dbQ2fl$JJET6A*5sM?B(E%AL56J zB+&Jb6@S7mB#D~NSrhj%%h_47HvMbpkJzvFg!qO300fNvtRKeuE`y}_+S=n!mrtG_ zv=6i2K;=)%DuyV)qVfUbHFV_Fq;u3>^MU%c{{RHp{hPdb{{RHkw!ZNP?F;)uX|JZ< zS%sIv`lhCDRwq33B+O3X$ii`7nLqGVZ;PJ}e`x;z+Xuv&-@_AQ4~G;4SAro5-A{q$ zOOD{M;=Sj^Kk!`N*~8;Tzb2{iGxkNW)x1Y_^Ip2@(%cQ>jIQTSF^}ON*1U7}&Hc9j z0A(+ae+BNepN7A)j-~ML#*HF1uBjBbh75h}!_9JkD)n%arzd$HWN6h=a*{qV(xr}H zI6D6Tr70oKI6q3U6DzXFin~a5>_Tx|flem*)GU9cj{Tkt2LYs=p>1g4KgX>Om7T ztd9BH!fgQXeQ74Qm4+8?F@nwBnq@Zg?^xMG9fSjs^`|o^d=}lf9&`6-y0Kikl4z{4 z$p~fr+VO+lvix5K#f`yRTY|Q897rQL$@dj;7Bb2_ zv6QZ~2JU=E2@M3!aYB1G!s0v9`ZJzhJKcH|($CN7e7Y zY+nZW`{7eW$eKQ>aT`vl)O^n=ZNPDmwdm86PRD^#oc*SYL-4c4ehAe(J*u^h#j9Ih zY57a2bb#IJ@w5E!j(hyEI@I88p__hmH(~7~u$Bq}N1M6KFs&Udt^k{P>sT`6Jfw6=`w`u#| zT5~SY-z=FNl0_}uqR8r_=3p>;WK>1j7twkiYtPu~8ym)%EZdvVH{Ge8-wn$wio+uV z?$jkvpOkjVIO|Tgo5>5gTXS$d0I4g`Xt!CQ8EvZ@bSbg)_qth=IIefXf+Swa;&*e=L{LDRT#rIQPy52_{Panw6$0U2#MWpLd z_|w9o8JBhDpCYj5A=G!pVED^P7WWBsvF_YRbv~V_@Rp>$4%O`S4a+Pu6BMzI%EO%3 zH?)$MylE&!#_`Ick+ZV#x*Trv*5?yJ34lQIB zT1;`=8&}jN4f8&D$_|6ngI}J0B@x@paE}|bGRU$ca;qww90Tq@rGC43L;edx`zicJ z{fzu4@TbMvKg4eZS?D%UTkOyvLJ~;S4dM3<#GIa;O>0szYu!0qrONHO;lJ=&KlmnB zhreV0032xg_kk^BwD4Z6sc#Ca7FbvThtI!%eAmF|!}DoZlQhk?HatG>zhBXp!5jYo zfPe5*-`LH(E28UKw~Kr`;i#4u8lVZQT5VhgU=OE$mH21-ZF~#xKf*taTK1pdU3u@c zT{`WcL3B#Yj=U6LeGY5U!^Rb9^1ac+PufCy^*mfipyo68N2L=)v7D+dTb9A=LZc$G zwp1=Nfx-GycI;-_xG%sy)x$X1*!3dYR~U*UlkT^do{8J*OB{^^&d-(uc>(CbY%RhYY)L*F@J}iH;Vc- zXzb=YCWsyxPf=PLbf0XVI2-OUAcB7Fa-Ju*dwo%%ZdFgq^r@?T(WNM>Snhrx=y6*3 zj^0~!CeKq}v`2yRVDpOi&-f-6{1aEiU+_|Y7I>RY(EMek_(^;<0G33!-M&>P831;# zpMD-{3F8k4Txj#m-)^x6Yh3qH$x&X-{{RHB{k3jCVISKENbz8^yw)_0LppY)r@+{I zrF;x1?m;y)>q%;iYhDp{-1@V`{{Zl9&xtHynj3$QUkh(%jf$H`)e<>3{{VEUZ0`2O zd<*g0;Et>CH{u4p;XCWiKK4xp@Y+iyoT5nFfCyz_!5>cfuhwtcm-e*yAK_hbwQn1K z#-2OVH2rFSK3!^Sw}ItnGcND6X?mQ` zCK*QNL%W^B*1f87QiY~@H1RWXx%mxecrVMOpX)y2@sGx>MG~YtRF%hGe(PQh1L!Pi7Y=&DWKYNa=n&%{$ zwD<&UvMSr0N*l9#R$iB=%i--_3%gce_T)C<`iks)eWoXgJT)G=i}iNO=>W@3~0%y5t(U@YCW~h5jFS$5{A3C+#Dqd_>k`Z?Vgy`1aFktcUngY!Xg* z=BoonH6;1^9$fL$Re5c({Po8i*6h+NGg`<9MkCYu)XK(56{L-oh{CZQYwFMVC~y1| zYscTPZ;o!F@vV)Y{3CuSxt8Ne)b!$B&L?Ip5EJ)DJZ8RETUjA?Sy;%+l{r7kw8dc5 zedug@6sjre8!;yK13kIxQz+ThaIMBcs-^{20zKZ@Jk^Ll)iUsT$>zM@BWn)c%IvY^ zh2)%5*?h#>>J?n%usoVZB%-g%zr~Px)KfD`SNV3W6p660C)o=!%eMy`+qHF{3;a)O z@Y~}yhpk^Mb7`*XlkQ!>j)yhM$r?*+u*tLueGltWK+ADqC5^+!GUMewl~I?yb2^my zlT7tr+aJK1AH)9u9Kqtx4zzMw>&PykNO9%cIr@Jp<~&|w@$bXyPZ4O5`PVi-y47IM z%-Q}TJu}|C_g$A%(`@0ld#j7982)65$ss+lRz4W~L%8^L;!!bBY_EZe?gPrn8SBTW z?Oio7N?z&}I!-Z3yV$X$=ref7Q;r=M!}prC;;EVKtl()RQP7gA3C3$uUxt1td!IGD z3F6CHm3~)?O}LDyA4UCZvG5ng-x~hLe;Q%&r^DS-`!iCSAYhwf%96&!91z@g8TuOg zC&M4`a}Vt)rD*USM@sNMtsI0z4El6v@-a9Z0qTD$!cv@Hk*~Eu9)H6>3c&M$+FDj zBMg4-G3!k8m@sYM#nAdt>y4+bdS|^g)sE%kb8ru(a7#vYEs2@)Ddci9jCH1m!Z6`> zjs_{JrCC+J>W)u*(8|*SHwMp49%@PII5zF1#=mrd>J3R@aVfEq2AMp@Rv2#MwLvVS zE4cmBv;j=IiZ-&FavpT>xMx*8#Vogl;OF7Fl%N%1N zbN8vQ6EsbLGQ%Tzz{LY0pH_|~8~#y|^HZNvjE7}bWyk}K*`<3Vx!gD#fWni&KGe&N zARpZS01T^+zsjoYS`%DJFnN5q!#Pobo~Qo+)k03u9j&<^0DQfTMw(r{ml4L#vAPrU zXV#q+p@<@^n=(ma-A}a+;$w`-=Iw7WWNsDD-KRx!wcE+SC~?ThC)S%JIfNs$k}5Xf zG18hX@cWm{+D>sxQ5GKIMp?dg>yRYw4Rye@eP)ts=~QlGR8q9tlgC3rG8=l*I)2iZ;Af^w6&GSkDzYw zH-y_DEvef)>)Ug6$^NzTUZ3%@9Oov8GfWXXz21rv%D?;052SQn?UPbFYO25`>Tj7^$S?z-4;k7XDi%S z2c+sLacZpOvqnI`>J2Bkmga@jOAF0w<;l9;vVe3T_swR>Zhp%oW!pL23h`ZMiR|Kw zPqDm`K??93sq6KwXHg25Z0qw!AS4l29fx8Vyt1*g2HB2>v8ci-&9zAzxg-149P&x> zs*W?s_NOu4Rz~HQfI4D)GVH+oR>2&DVFk+K{fbDBgUB>T+UxxuCtVv*+y8r^0^{&7*5q7A)ReOmcxnE76~4%_B23tTHRc;FJ3%_6xzwMnPatQQo~z zPu7m6*0aOqgmKrX$E7%m%+B$8NeGJe1>Gb}4<41fXFQs$k<1tj#xel!P-^y4Us}w& z%PfG8-H*9hJ{P}j5+sgCW@y-ed!MaXj+$9K$KB>IJ9hFbf$?P0cu&NMdA2sQxNVQe z%nz-0hE}-wi!Uc6RbLqRd~5z6XyJxE#2hu4ub}C2Ug?V;FSqw@3G3U6xvxciW#Q%1tmE^fo&2~W3%QFP-u%%W z^eQUo-q8FVuY7aywwK`#4BNHNsjSMed58|%c*((Yk4)F?SL~JhFz6q#r@;L;!Fn(H zMf`{*)h@srr0g+ii+MFJH z)7=_I+a!#;et(c-xuj_VMpcy+m}DvR^{FLBJ21+;eR3&^!3*Lg#!nqjdW~&VTq|y7 zbvw4VLrRZ^U*Z`&1Jacpq;+ik+>C)hY7U-Z`My^lHhWW|R#YpvW<%Uk6dyKnSFSy2 z0cqdTJ-Ho-pfwgagb$4U?`nP(vUY{R>z++A2Kh6!m!31$p23gZKbY%4m_rwm-@IYS z$RN=F0K9hh6pFGweo@nqX-n;h5yAEAiUAHEG3A-L?rJuZYRFV$91NOL#E!&)oYIK* zk-KTg&HWDT}O+^h-pVd+c)Xv0agyLo(a2TF8*F>TAa zQ2eYr&|zkLmQbv`4@yRoMOFU*SIc7{^ri%cH8OqX0IvjgsN!!eS~ZcB;|F-*sU(;) zw0|>yw7sfy{mQ6kNioxZS^$bA2+F^Ep1p-ks;t3V0Q!T{g1fhFJx5jTP0KuOyOk@q zIOc#A-!d|<@vb?fRgA~8<^&EfDMFB|^8t_sd(wlq_p8p+jibE)IDE_ZfXT*Ek>T1G z=54Fkp0tVtYn`L!93u~zBmGv9Iy9!@rq9?%nTcx@-aXN z*3PN-N14|?wKz}TZy`*W#wk8f>ymlkWYd*S8_O!J+yc}9-?M=GzG25Wp=Vh4KKT_? zV;Ii*Sa}~a9Iq|zY0$RxW@RIuJ*WYpJgD*)l~7b3c{MnNqiwsl6&$yvGz{(evcUEB zr!L*B%-dCt8y)B;Rw)1sGVa~L#YR`<+cm${jrkw{MD z-+S*cjx*~?_lF;MJZ6GhyA(=E$KG7$By{{~rMWG}(0I)_0P0m$aJ-xxW`rJm zOSyLT08j#F%^!Gm;EG2~M$Nm7rRk- zyen<*O?LU0mikh@)>Y+`Kf+HYfEtOg9lN<8j2^Vr!I{S-*tz^rnDnV{+~vE=WG~ z(Y7thIH@Boxpy>sQHu&w!}9+CcUZ`#KE#uj&Ny(mPynyjjFs5dehy8PSe|* z_o&Q!8A@zluX+F_ZL#7t=dtvmp%N9`%hQz!)~r1d=IZ455se;g5c6OZKSvqJA*`*0W31rF_rvqfKAhulCE(d>3PSjimTKA$xp`G9A={ z$~$KqSG)N0$1(gO@CLKuYqqxurohh%mIXs& zE16laa^&O+^ssc_vXw)YRZ^&;ef@o^M|*gaLdrhQzFbie@<$jL7$1dV&#Hz=n`*`! z5ZD+bQ*Pu~T*LQSMg}^8P)#qEhj{9^#yb1ghbMP)sT6e&5ix63f;n1PWJXr%6a&!L z**+4~h3|tj*}3_mP3nDd*1kIM{i67T#8x_5Nx#gL85vK^2jO2-=q|c0iv%(Gixemm z=I6C}Sm}GmsfUH2cGh=stbZ#U_8IG18h)?lox4nDzD;r(R=I9lY%(J{j2!jNYDcJV zVe@B>YmyQ+a60QPV-s+#wDGuBj2Fuci;tW7*CVE1lplL4dB>$}N2=xz-Hf-tYV3te z?qMkEc3LZW*J{C-`&V6P{#};lRc>+5YUX?o2bo~AH&?Ei9a<$_+ec1&*7wlPNV68y z#@6G#TUetpVn7@*80W2KnIjIrGO8~p{i>wFo6Twrad><)ZFpnWKWhj_m=P2RFPZF zaQ;fixVXkg@Y319-fG7h{LFLgJJ`11W9qaclAK|JQeKk3&%>2(b&MIQ6a>3dr zwAb-mPDuUWxnG!(_kHTWinVw&%`G6bjV>mWYO}cGXf+S%3GnsQMJ^SD~V&HOpwZF}Mlq_&o5X6K9pUu=HG-|$LJOUJsEwdSp6$!-X3&mDb* z`xJk{EbRONV`q7)TgNTq0L-O$75B%1{u$sWF_(6XX1<2d{4Zf+YZBXt)mNYcujNloE(bDU0*M9) z9jWkGeV!$aTW-;XBD{TXd2VefHuTuKZQ3}3ovXXHDHbI|^A4QUcIAXyUA)Ev0FzQ; zLVFH5_oU|T9E8hl@)r4hsiqcb6l1UHNUYJW8x8cOhT*gA?^5JGQQ{X_IAMS~QYvqk zzx1caHbyeP<4XIG^Y~()Gb=(g8(qGgY4H4qZccsa4=bPU^UWKw*cd0RE?_3X+zR3F zaz-g|0f`8w>ljbsa&e6@ZUEUfwvUBh)T~ z50)|NH*r$iUCpy>k?s0)GzP~P>za+1@&bt;<=xFTF&nPgA8zC6(u=2|T%f_6aEjki(xo!7+PhTo*iw1oBw(@v zy)#h@q(}S9`Ow3ai@mXy+m+}5q-i#sg~_O8yhL8PUv6pzy;)`2yN4O(j$q|2qwkBA z$9hJaj#Tl*Hzf0&*c=ShaokAdw?^sp?^GP5{RnQ9zJB#PY8DLcKJGre)R9M#$KWb= zB#|FD8%NaBR%Q>iw&S)t(8G6syVDg4+Od4IZuY9X0$uq%zY0SsP&@NaNL5#^F~vk9 zUD^ID^{LbcdC13T&g1H7#^Iwpa52fK*3n{y9>nuXtiT_wBO=I7+-Df(j%y2) zmOr#012LZC*i^DRc}I46>w#5b$`6@~ZQ`W+Ln-^mZ@pJGfyyjusy&-oF}>oao4<)fL6 zM?!L_6M^|tS_N<6`U-4O;QX#~PDrU37WT(~T0F_H_}xd#>N)nP<&y|`-_$Jc#D`rH(h_2Q|)k*Wo9Jej#ad zTI!Z|*A~-)uN={aQ}`O_CM&r&DaLzLa)@O;bA!^3Zs2??@kjPH@#pMi;=7L+{2;iR z^Ge)hy72stS{W3ce829WYW5G=qxSLef9)%!oflkH(fmbjq6@7y{{ZBYHyjYT>t9Jj zGOSFp$GS7Y9@X=A?REbE1lRD_$GF>E&=340{w0NskzZMU?rq((j!14^rvbX?XQS;E~RJoYqe9CLA0NKE8)FA_RjdR z`wVL-p?pfvZ#-3?+cwDcn=||5LH*_LSH33y0KscM7|r2Zi;V``#9D^D@iM~%mMt2i z_RAg*HT0{9sJLD3c%SOsPJeaieVb<-cNX4X+9pws3XScL=Toiq<%2A3CDp>O-Q8|i zkIKIZd|UCm;&;R!9A0>kc=N>`9>2PB@xg0$RybEV+qb6`&_C^y@%HybI&J61KM@Nw zj6@hB`MAbD_gdrs09iCWAN5sQ?Vq_8w{fIfjix-qmXl{A@~aceaA5xcN4Jh-Jx+dL zJx9HM1n55%zA1Qe{{ZclUlzP%*Ac&%#%q%C$WN#>^zZD|{{RJ|@rS~Tn|nWqR;}VK zEt_G#fMMeUxfRog;#zK2na_*ic_n&Mx%!_7vAmxRG?ub`)(7P^Vk=wCA~wXIZns>p zEz1S3Irs(pReU@Bt+Z6Q@ZPa+ad9Gk^4-W1q3_39^eZp7cxvQF{=VHo8R~wO^%#6y zD#w}!$l@?{DNB~3voG13eL~-K8&TA53ywutisU*n+Fhedwdk(bW`{(}vriwGoBKISqJda9ul&%XW4eRSr15#xz<+cMKT5)Zs3@|7m zZh?)skw+8*h7rm58ekvl*BtF*`BR42TXOCz-kR^_ADiyeapa7HmG6#dvn3L4$IQHX z(^z;mA$*uS_R1+)y95p-lmx&7fr2#Gt^T9;NiIky&#ti z7d?GxT#`V+e($9tzSZSuFRXR zsRFBEWcrXQd6^_kS|-GbIp{?{Yasc4Wp7^8{CRJNPu-Kl9<=pevmNV}T=P}~Pgp}4GI?RPw+^mr9H<6NbtLPIHt5;YfmyV!bRtf^Z=fqYS=OKjO&%YIaJJWvF3%l(yg95WBy%y7PyH1mJLE2zZM z5A<81f^o++9+F`3wS~@+G4gc_ar>gjox`P9@aCXARi)i{e^OsA>eQ88-9rum6aiyW zyFLol?e2n;VRgYH?(Eo?*I2XKbo;CcLjM2`d)0px-Twf>F|5Jj z3orQdx!dP$?UUA{@T9Hf-gs|NZ!x0;Mo)D;{{RY)!WSrusQ6z{V<=T^fyY!mG4!G8 zQbfKfxo-<=7QQCaV_7Wj7%kc<#|QYTFBnVxg|6E8g2Vnjrozq#@dMDGrBU!b#9MU_ z3f{AR=r@*F{p3AADy884PCJb=Q1H$4pS+83h?CCFK%p?v8vZc8Ukd7Weju|@(A+SN z<8O66>K`9#F!)Fp#JxLI(qr?jbv0O~+t7pFv9zxVG5BX^qUv{F+KZ>j^1O$80oytBt(Vi**G`4w z17tV~qqowp*{#`!wHkC8bpHT|m)EA^Mi=NJ@`3qCu47)(t$ZEgIjo_yg4!eVwg=6V z+}CHT+q4qc+)X+|w22%s#s}8C*W(B64dBlK&f12pc@^Zt7>!?-Jm7outg2L}6RMnQ zP9~L=mBy_)$7c)7-QOQ7)qffIpTl1bETKLk)U9N=ZkEY|x9V%;f7-wP3a@$aPs6e5 z6L@n{T^8xehqM8Fy#3W~ax-5o>A&z%82%x6$+eABNolO^7YhWk@A8!NIQ6a?mE5#P zb{`7ksro(p9)8$bckLVdY&U@X6?vyy!=&3i#qvpnwMOzF8wBSP}>$(!LKp!BllUqFNtql~-Jxtmq+^&L4N~j+6;k?w0A( z+KKcV%PVD@5zlVN0%#->$NvC*DI%d6l}H>nUIl#5D^ASzuX5A4BRTvrOC+iS?fh!8 zOsv6Aan_wE+B@#=NC$bU#~&#))Rjx)raIF@e7m}K=|a9)eqN%NFcKHoq>oxs+fPoT zG@fFh`Sy(Znn(GFKY2jxXyyTvU9!53u73(saKre23PU52+irWB0Qq@8l}Kq|F}$E) z4!tN?WE{zb!QfPjxlbR7p$db$a~yim1Z=)p$j_nTnp0{LTO9B))~4NtCz@-IUi?r4 zRBStV^`^*hI2k^aHqj?c9Cb9|*C71e{pbQ9tGn+10QIR^vb~QqyFPvx(iIrzkAGSK zVPHQBPc&mb^lXuL6$*LpK~jH(N790p!%hq4fHHBZ;vC*Gm*$`^MhlR%3pyMvCD0TZVG0KDD$ihr5& z02tz9%W{zjUnnx1b*SBym0=k(L47Un>>Ir1uBJSGDow)k(TjA<* zR7{B_Ef2$g*fUMI_yPNPc&oy5L*>J%B$4@SIB*|0ABB0Z{1i{&-~2280FT<8(uRV@ z{Fx!zH*Y!Tk81kE_MiAa55rIRD*3upn$|&U{h?~a;b#mAkUti#1O5to;C9!(8t8ic zukUU&o3ka};qx?SsQqj1a_av8?F#)*p2tvb4Ic!@EUG41IrA~|dSa<~iYYFwPnWfw z26}R8)s&BLWmS!%Ss92~I*v_AJ(l3nspy#})cRM`$oXY>vz=(9eJV)VM&Owqxvgz4 zQuDNXRaN=ae)N%?cC6?o@+SS_?O=AFLsMxNX3tQP-atm+T~BJoZfUr>$A$jYD$8#& zteD6ZMte%pzTJcn}pjqAB{P_z)A`C%UHe|EF>EWT)&1H=%QKX`i5KCu?e zESpaNMnSp0QHs->M}|~g(8q@8R+!oinIS}K-MZ5Hyu+G18S(2;q1;%pBBPg8h_BxJ z$G>XQUkzA?!z&HL9ePl{8naK~X3ram=~C#_xYXifz0?`(++0+Qp4HZnbfUyWLv)Q{CeHL+2py5_2qg7 zt}yAhUK7@ox)~NToUbavy2J>ZzHVFRDmclh7Wt!y?On1+plxBh6|~};x-pGM9U07O zekO-lluW~9$S^k!-qg1qCh{O(Ch3HSj1Rg6baLp{T7h4*!lXA=jY6?CnRnoQJj^yU z(W@P!Es_mmQk>hlv}!`dZ8KPsRQc`}Zn(keQogDYm0QyX-ibU1Z)m%tyOksv9H_$@ zt8w57!mD|tvvYzurOQ&m%?pzy#_4v90oI=@DL_2v!DE7?^HmqXcTAh3xK?lO^N=dU z9}TainLN9zeZ%G(n1Vk_e*J@*n9&#Zd=hPD`HlfSs+-({<_*li_0M{}Kf|3tL1{1T z&gRG7ZcpV^+s2bj`aOu>fG_)-07M-L_`R)kEyhvI3LNZWHpyrScwu7}2+ z3!B9nXWF4xYs*x_Mn(%L^cA~jf2Z17&9lpml&D`WK3Cp@eQ$rO$K~Eh_K7(~jq$jT zZ|PpGIzHztjtOF=&2*11@YuJr)K#w)6=6R*NWXjVuS3>;C)gOGw1zndjX)8^Fp-|; z(ye%dOVfNwbhBSXzH<$`lL^z;9Ov+?4Oijbn3Ha^)vjS|^0KBv{yER-S^ZtbSsQy; zP2HBK*EHJ<-6G9#BdHvL@*luvsOoylYC=MbKbN!(#1aKU{{Rj3YY2SHZBoW%et*`G z$M7PoEuV}m?YxCpWkw-@4;z18D=SJm8aT(JEMBB`RuFIvX<2D4_DRr^2uc+9Jul4C#NP?ywhB=XIhvyQsJv$`?gix-1e%M zHKy5HM0)n4IJa$Pf{yN`p(B)v}-MHHtI|=0k%Q-*DH7MhUUfo)ui4t58+t`AFs7+>GHmG zXHK+d4oMvcjCE^29C*^_{v@!)w38&EFtWFD6mUNZ!PGoEXF7Ry%QQPrICcQz)Mm4F zCh=y3>m=6q5vraT4Z!|2M$g9cMs5Y&ZPd=^Ux%Sv9z3mIb-Z=n~Ptw`!H;}NT=?RoYdd&lUmOf=8=S%zywtNVomBl zW|_Stss`_sdth~{vRy_4ZrzM@9jhYGUxmy0vnrh6V09HO#=B;+sPnoGpmqAwc!V!x zUt7y_GRCqImB=mLnR$Aa@b2@rwtigqteLf2S*2469&aO_f|5InIbxH{k=k@0CVB%| zOA&pG_GP=>c%TipbdAwL>rjsts$E9DPnXjq)?~V>;dA@O^&P4xV4GLHSYe5pNsb13 z)^Vv)`UI)2r=?u!v3Q?AF|RT*78vS9dAr2c;%inPybL<_#d?N;;rop$!V6}Zyy%dZ zU^pJavpiGqy5q$+A8D~zyDsTH>zsanx?C9eSdLvsa{-8XP$YEUPnDxp7on;<0O_Pib zqHU4_-*oeh!ntFJlwZ1N=_k4_$11c^H1et4z{7NrzX6ySSLgz{-QgFK^sEpJPGh-L+KnoMhB(D(+;P?mq;tQS_>FU!-t(kIMAm)m!Q0 zSk;&1Rv8D|+NIVjkk*haaR98!&Bj~Op?zf_i)`Cj6d$|X)(@Eb*LB2=&f(8Wk)~N9 zCva`8$Tgg+K7}YFZ%6S3mZi2hRiU^Ikj#Gf(x2mP5^YixxR3r=t_tIleQS}DP`9Yo z`P`%tk6QGt4UNH$M~+Y5Mg)p_X1Zv%IN6!bJdWt|-7i*?L)NYCqa|gxU|0i;= z=#5w44ukO%;l;0uJPWRUmhlR;-k&_1WVf5SQaK#-HQ~M^@NLGGsJ+6*)7r?#8xBa# zZg>mDN#PATb`3qP)PSK)*b*<&u9P`0q-R<@%`@z;fxqxv-;STN?ulpN9~o)-7sSsB z>G6wEVXaz;n4sf{c_)r5(|key00%XAqr*Q8?>sBue}f(j_R*PZ-DPgVL=dz-6$Vm4Hd&2#)j{o1dsIQ$}x8k%=VlUMO(rQ(fN z^H;o)?k+W{<(}o)K-}(0B>hc83=ybBRS6*&Q`ppY7gAW6p(w8$gKiHvKGflO#nrGf zhZ|e9XFNov?;~Gkx(#@-I;@_#J5PEVWns7XgPp(;Qar6Iow2Jjsj70_$f&K|Mk_yP ztQ@77@X|9c-N!stW}lL{+yFd#)nlv3&^sb3u;6pnn3pCveq)v=B%fN%)+>~|1pfeP zRgIZrE%N1u3tCq3i&>Q;m1d9bvqo~h_0Jo<(`|ftZOLKUnV{aTg|94fO}f^9yj1kh zLquy`*d?-Xf`plS`U`Ih$sImZ>!{0r1ArtwJd{->xWpQh_yx>@ArD|rvyW9T!% zs~XOQ9=&d{$L4(Ll_&0kIOE>9YfTNmwZ6-A-)B3v?tTSyay2B;oMp`$GwIKUzBTy4 z{{RG${h@T<7P^L0(R%mkTxO|x z3QgqwmfwOx?m^Gz>soVrIeVr*SB(BNex?5a!C3zQ;ITgfemQ={aQqwa3u~S#k{IHS z*HzUZ=G9XeZRBLO1}pN8{^mJuZI;t)$r=sP4mS`nQeEh_@IHPK>qgtnr<_Y%*BxB0ALz)(y6%PaYSF2KD8R%t8V-I@s^_Y z5j0*}NxSAzj;E1LiY7)1AuR0KPAKy>1^wRTZcgFFK{ly1h-vNqS)&IBt|>WKe5Smb zb6(n9#U^2zNcMtH70FByEgBgk{q$cin0t=ct^WW9YGYWE-aE;p;zG?Q@d58m_=n-I zu;zFi%^Yo=!_d{ZwyuP?H9j5Q-h4;UKj9OO8=K8rcx@>o8=afHf7Yq|LGbU0J{tIn zEkDFsW!9akSjdtXW>TBL=Z{~nywQYrQ1Qr&cZTe1>2Hi55_NBk zz6!Ol@r|yNHT9%^Y0({%VGn?spO&aw<;2N-UBEAi!odW?|A3ha$kF$80rR*QIVOT9(3ong1Q zQMn}k`0tu*-c6WO3hnZgt3E#WzA1ZYQ-`u!8^YGPLE&i^cgjlqqyy5TNWSQ1ImySh zT;1jzv-jYrp(B#`1>2U-0~oG$(=EuWxmRlLZM^iP2(CoRra4#T2eGRYK+-nW@`30v z#t5h;k9k&X#uu^gVI(ti3;6TOCR6 zqlIQ$bN6KXty=QjMdDr3c`?G%3<%V8`c*~`SBS5d$DRnc*DR5nP_l9MsE}?d!=rFIcg=EIl0JobfH`ukT$`#Jnu zzW5>WQXNXh&fimlMKN4jTmaEc8S9XEu87L=N<_+hlmS?uZyuxws#VdbXb@?fc=IVQZrJli{zA^tB}0>ppaOoqGe% zUjG1%emMMkvhZKTxxe8hvGD8oR_wRWX#}C6pZ%eayNdIhPl-PeG^=&D(R^j%OIxC)%h8WV&eJ-{rSBQV%QjrtWJ=7%}ssW!#_&a=s(l&dnOONXJ@7kz$viQP-_Z zfQfFyNL7{9SY?)<=d*tC6Dy1WPfC_x8Gc>cvN`mom{nWl+{KSR)m)$pbk_21XqC5& zvkGn1+ZY*{H#Z06>?%i*M-7Hi$FZUk5T;exN8a1|QEq@nl1V9FEn_+7clUq#^&C#& z8~1l zK&FraDJipR`w`lkBvLwjyN=v*=}wB^XLjG4Il&!jcewrL)mBZzI9}C2RWZ2^Tju0* zoDoXW?>r=I(UInJ#t)~x5=x1?dl?U0W3>=Yg#3&IZZJVw05-^@X&Cc6DdbTkvO^r3 z6^jASJw;fC;S@8ngYw`vpr-Cv3jY9)8LF@m+leBHRlf6bpbnKcmn1N@&E0v(piBT_ zKyAaX_e}+S<{>%t!meT0pykj%l*RaIwZbz3Rs$j|5bgm%d09~*d*9UDuvZHPu1N!SeSRrRZkB`qSgCQ?yXW~_28zzMlo_u#Pp zFKW4O;hjqV04*GGq;T@{Na8r-9XVogUnTet{tI{Tv*L%v%`?I}Z-VvRFGbX+XcNR& z(+JSX(N51oM_TjW_%3nrggy-LWzL)84Pw{9x7TlJs70sFV-gln$jnDLJlCm5Dy`2L z)Kg zOp;2c?;Q6%`R`tz{{RI~{{Vuqd^r89z8+b4SHON7)t#+wlIgW;@x zaj2xVN0W}n?a1tT{{ZZ9`$J!R0{y3Sj~8ERdZwi_%l3UrTdSv)riq9RoStj+8~zIK z@WLODU$FJoy{5OHHiI-et)s7WZ@vEjj-S%M9yBi$$>Noc;@|gdqmbO>k6+5aU4LLt zj8^{uwMXoetav+Bl_u07(_Yuf-SbMD2poGF>C7;4!_|!9v>(=CiKBj~{HVGjb+foz zb2N@Nf`5Q?&2DLWS-Y8Ik~T$v6 z@YI&^%oa%_K32}v;Cd~?Ni^2$pR_J_5;2lE{*~`~RpP9xxM7MCbKCy_uU&A1teQ>Dz0{IO(k@X?A!-flHI!(IOOsJ=vO^0< zt}?8C=suL|zYX3*e|r>vD8mCF#wv9mQ$8to0Au^zNyp1j%1}Oc7Vbq)e|2YK<$l+1 z8v)90=~gbNfb!^~cOVV=KQ z!A&}QEplnT>|}Jtb6c%<3274EMsF{v#y3^D(OL-Eu&l!aZzO$ci8F2O#{U49<;vuf zRUt_=$yz@-mKes?+A)*Tv`xFkxmmt`&F%E3TMIsCU}?u<=v;G>xI6Qe-;n$ityjq z{{Z$(@gMEc@xsqQY2MSqI(vyV8Cg+d%7;*rrz0WaSh-1pEU;s0a!`7@x3r<-`Bsjq%f=yRgBZQ|c&a3ha@U>zn z{OJ}wySH-8&44Hk*uqQ-v7*11_qQ?Wj?}V0nGQD+Smf%NsKDyMcgBE={;xe9HL^ zx7L6jBUY5MuFMSQ`_$OPn{tgDgCsFLZKW^d%NnlYIL{nWvtwKc_Lg&#&)uK_*er>; zjt|N)N|A|B^2cj;G~^hG6~EVGITYV2Nn=>!Y%^yp^a+kHmm9X9e9>$Oibgz~;B(TW zL;<)NXvV@j6YWkd=PI|B+n1o|C?t~``{b`Zdek7R#scm|-I|n@10TigXjIv`vy#Ic z_Mk2-gFN%ow|a4rS1e-rw%`zXH5rpA+f}-Crz-NSKX}W=Gt#S+0PR>;DdsW98R`>yBLEyI z6adtbqdQhO*ZbbI3w4fA!Z2ihIXu$4KbX<7?Ni8O-hj(2pDTHti1eTd9mFziZN;(1 z1t>-=8HOXr=4g-Qbt)TgBcEDyZ;-6=9u5FB6U;RZ_9GuII5hpc_HD<@$piSQfHZ?V z9B=?U)1=_DDz-2e>p)yhk89`N}iOoolx;5N8rE?-4lKev=jQG2N)GRvt~o2|NUib?Hu0aOH634bZES(pJQ}g;J981a+rL3b(+p&@ z4&y!P6nU}kXw^!d#+?5E>iA!}IR=2#YAXSg^Jld^qC3@g{o&U?c9N|&0jClX z_h%y*W}r0_?5zyASKL0drB2_+7@?SszcP{4dV@?Z%n_IsTz)yC-9UV4g!xpiIOd*! zfPQ8Jp~WWUCo7y0j_dA-Ny_@F+dA}xwk74q#V&I{N8TTTNvlHM-#B!oE~t* zo+;7~EO1zQWbkMKig&>u&6eHB#XW}RWmUrVAk$Pfes9fb9a&hj5_XK>cc4pQ(Be52 z)p*V_X;?SUkGjW$O@;SI#^nxkhNpkPn=8&J814-Fl|WK4P0!2~y7r?O+NFM8xbK>2 zmj^A10FlvGZtuF>aoVAi0cFo-rp5x@yEotygzEpZ0$f| zz~xH@>0G$#%AGdO%pDh2qDPi^BTkytq}DYVn)_C}aWP@pi0hiY@jv2CpTZA>o*?ml zrpqJgcH6A&q--U`&G&QlBnr6%D;=Xl32&8oE$!G>8}ZA*I)BDbhNr`N#7r#ORhaoM zV`5jQetmhbhhMy@d7p6~-Nw=ATK$~7e{u1P;2w?QYsoEb=G26~YD70IZmvc>k50AH zPk5-szE=5m?gIqZl77bi7H@>!8u15%W@ovA#__ML-G|K4$N&KTAlIq9%LG1Tir!{$ zibo17hY=K};}g0vZYiHN{{X>M{9SdUd?WC#hiCh{T~6jnuGw?*GX2#*&c12=io8gk z5dETbc4N6(Uo4+fUtoUM-UEl?Z^HZAd&ZV;?C{rc6gb$xbo^`c{{Z3UvbqPvJvQx( zh?e(gSb}$8H#PJa8&3-2w>)aHam1$2)~!cV@~##}>oMFiI*Q5F^%BV=7TByh<2a{B ztuCXYX}7NHBF}8C7aayG2Upb^Sf*7aRlZ)hub8P0Su@^_r+ND_>FYO%FE8ZVB#4-S zPaCt}^sjoi*QA*kOakudgT;8C!W-*93)y*W#7imzy}NPRy8FM0S|)_>+sUZMCB@TY zXgnv^-n>jiT%~i@ryp@1qom(O6E~KK8~BJ7vmU0R4eEB4^gV0KEdC-`$#M2rW{x?c z`L?V5;C*X&ScX6;-0Hny_Nq1b-#;8&a4c#$P_ zRt}8E9<|(jCh+Uuc!6#unWcs^kO=8YH5f`L^}QokmK`-ARUa-t6IxdHH%2DkjnV_R z+Ow7&vZ}_o=YlIj-KA$AHvPR0I#!<2OvjZXOGc6_Wl5!Z2|Tg%siUzr@4Is!Fyv(P z6$(3fcw!%KQ;ziKmO`0tn~pi6?UJI4kUFfKw&K0bTDDd|!;YN$R$McOERD65K<2cq zE>x+=3xU?QgSjlVT5%mq_rJBmn@FEakn{a_N%5aiPv*f3iE=^BMf7JI@6wc>Peqg98|GJ zw+x~tXLH5}H3YFMA&qi#+tk<2zwlAN+lx*8i+&W%XJaICc*9qWrK}3yG&%kwUDzBP z@fB4#Zed#y8gO!v#Qy-nQ~v#^T!&xc~eSWe)49t^&B+=3YS)SUXQ=DmBfs$mxpg)6v#UsDl1UEYnJ15@O69ff zRy4KSbtEvTL_C);ev&M`sF;IOL7q)oWDOm&4kB+3ez1 zxMVxMSG8@L=Fy~@Pf{}czEj;4uJ7$U8*3uR3d?Y-wmkI=YoD;uXYobMcNc^16Y`VS zHGfXgYG17z~t#9 z+R)}dV}IChQ26EIOITpFlHW~M-tU9+SL{FRx%(Jsp9cIjZ)sy=7?T6cl&>V$U;94( z%$iTbEhgH}OS6vNC{zY;pb|i@ZM3snNPLLZaC?gRI@M)a^EP_z#+v1(in>>Z7fQ2O z;rUC*HD2q+;&GlFmesZP~ZIJIQkE zyBY26Pscw~O0c^z{o?1gds26~LlWE}W8XC+&9#^1-A*wOn@cG@$fac34$-?K6(Av- zE^!+4?NNx@Rr#Z3_XdeWDEV*>Db^9l6KitB_03OE1dC$-02blxO3ZQ8)4{`aK7iCS zNXx+c$Mve%0FB4#(trqIwXxr&ChdqaGRB-wmbq``O2ydzBsO?VL#Xr_J9sOuyyN%87if;U#yipbm2$6~8GLh+nPB9Ii zH{SN6fAMZ^oMMQ~(Mg{$H}`SID!GEfO&0JzW>NI08p#;)OJk-_TCwNO<&4`~(+4#i zgtLyg_M%IvI+bLwQ$FI)(;GqJp0+B-C(@oz$abmRYBZ3bIa-p|!~V!4T&~gWNXVnI z=d~z*HAv1IsN$ezVJiH+^Yx$$0zuOSe-4yN%v8326GU;b%YKyY>mmODSB^bt>Q17h zeq!!r83VO0H{<3UaZ06wFHW5)b0d7eD)XL{^&}VO8%G|rXLEeNtp!L2p!BA^OvCSO zC%$^nG$?~(;hS%Idi~zNjw&$|M!QU(G2~~hNT{Me-blIYPf=KE?qmIEkcj^G@gB7H zk~mW$MQ^8iN#}}a+i301YF)~(1XnzsaZNG#ic~WWdXCjz9aa+{jf8?>_f9@jQY4$7 zYP&8@PDLWQdW2RpTfXl(m>*iP%CF3KeJBzz9DLZOv2EWfj(X6fNHgplbDC0Ee+XgI znr6pSoufUfM2yY1ap~_$N*{6$ zxVY`j0~;yw$KA>3Dj%>k{{YW{R*>&ZmHDy9wMYwOZ3GeA&;?N&BMqaqPaU@9!#NrC zsmfz-${3N_p`Hb089C=X9+b)7LBD2P?cMYgBxnyOF=cAOA#k4l_e#U6P2bJBxyvo6pA^PG5I4=hLk^Gz-Yb=>$LUA<380cH#DbOP}uw(@i&BZT{d4Wnn1DmaKqd7LlyekWw;&GQdK>}ii+Br-;-s}pj_M+DW2D_g5u$G4h4 z-JvEaJy+10v@KXkwN!@A@4}~=%-fdccY!sZ5PTl-J->)N8>vmA>ejF3AV$P;p6bAM zuhPHRqy7r-p?p|dUl0633*r9&5df*@I}fwmH%x+hWY^~;mhroSxMowH4{D>UcxK;T z3eu*>1Lbu%b^03guvx8KG_Ib9osP?CVpXQK?tcDRc^B5g?@gW=?6CmfMFz$zM z_h~ZGjmmd(oEix%78fepe*P)D*5)Qjepv_Irn4-qyJ%NmLqR@j;lA)aXaUaqFdLO0 zts*wwoT=<7j?Acki;k5V9H?Z{b_-7CRK?9 zat$CHaCl#r1HCGblja{c(v=WOK4FeHr^g?W^2zfn4h`J%@i zszD1|Nzqz1T=7ca!xxylnR|?MpctE0bszH1QRz+%=eE}S-2wHcylW(DEKF6Dax>P6 zEt>Y+v~9L%`Kz%bqnIS#T#fg-6G$1YEBt7O&dwgyv_Jh>Vy6fo5*hCZ!*qeH)pnKz8jTw%X_^CQ2B0` zA{RfUSMc_vXNLE~dZPaNJnY@vb|Qh)r+a^S0pS(J8ReUXW+77jS;oJ2BHsS_9c2qy%Qz7!A z=Z&RBTVE4t?Y2m9=Y;+x>zaec*B@$v$Hf|d`sEov!bToWhcC*;q_=d-8GKDgg{x$De z{{Rs0V~*0x#aeqa8&Ev;Pvb-D^sL_p>Ivb^V^r|G?8e?qwYX!@9@UrNj}Q$b#TvJS z?~m>#jI>4g1yBC~uA05H9gVMuTGHIuX}&DdrEm0f25`LZL)3m1oACq03niYP;+r|X zYjC^3{xm$0Ym@kO;z?08&kDSIqK(`_@lEhHm3aq*buA}WZ#vziZ!c-a)%2|+ z7u1T5+Zvw}e0lagPe<_=cL8!b>VRftc+Q(hBnA)>j?PdPzGJ8Mmn0S;yr&!@WKm?R`6SS3%Q9PSI?gsf8eFQ8t`77s$FS&p5IK2y!TAGR0FBa zV^Xq-wLC23?$4tpXgoP>aV6!=y`{4a%+A4aUMumB{t5-)e}fuD!EH{)Mz;j0mO+Aj zg?umJ-`mHFCm2-`ulD=i~dIm3%|-$M%>10EE-xF0Cb{m5iEI zy~A5VE`er~X~AKN`%Gw8S9W^O_Fa|YGTBLPyn7OTEA#U} z_?Phu;#cjjVd2jf!>Vi6`c3cIj81&Ou zu@?wC44U5XU;Gr`;@87nR_jsl{pW@3FE0=8XKgKIl1z8Y3gwkcyR)m<$u3x*dVbJ9 z1}(lgXct}$zK-VJ4QFIaB1M@kTc-WK-A#Na`$vDlJUm(ZK6ut&55wZkKT@?+4HeP@ z86bgx!?CG6eg6OjH2B%^5(U&Xe-+u;TuB#^9M*btaU6HS7&-T^H_^T|>Y8P}_5QD{ z>RQy&A2La<<}OQi116?ZZ%FQEMueg9GSnZlcf}hEAGKTPjjUSm7{PF|t9?gb!k?k( znumoobERBfc!R-rlMy4?M|Ul>bLWhJtOw&=$AMq=m(z56UlnPd0r6$$gs)>42_#x9 zl3U3SuJFEtIn8}l`zK!fAN{{lKL-3<(eAWqq;Um?vYEBKvAH~L%MY6ev8<;VMmL(d z)lRZg_gTn)!8w0zf7&}_)1%7e-H2(mCSo~f80D?Gv)s{aSeivJ}#?Jyn zWj3FvTC0ZDt!-o&C1d_3UZZY)o$Ks>2LAxTMI!N*i~X@Dh5S`#YSU(D^-U^h4YAG$ zC6@;uTH}@n2UW9-_Pq!-w1>&r4&}!e;KD09d0PN3BmN zdJ*SoJGmXHSZyCKe_EDbE(P1Sb2ssNRAx=!ZI9ZYD76i^A26o8erFqpx1|rbs}1EF z*R4Z6z(5ysGady%?Q%gEmftp8aK;Bp3E9B>>6Ye2JidOtspx^949B0!saSSlra$KR?1t&ZMJ4D_pE!u{<6cvTMCk_Qy-N zMaxNZGRCSs$v73|UL^gxz6W?h=gHPSCTVcUhX?G3?HKx%$gQd2YSh*dZ{$p+82n82 zpEyeFS-x-QQOPbBuhSjt$725gf`fj~^N*L}m5T9@WQB%DdPpQb*Sc*wqPCwdHR0WUj`GlXxkU%_HF_V~ zL*X6td!hKH;h8_#`&wZBwLekBe0)&TlU=tj=V7Z^!svj{OaQP&%zR++v4vFocA~Jul1zxRsR5${lkq&io@kN z&KPv442OWbg0EAKDPP5Y8Qt>u$HMFAKeS`#^`#o_gz55lqr(inbN2Z8{b?*6Z{>e* zy|jCcc)a1bw|)ghbz|m?73t1JPMXGo$XWbV;k5^$`(knW)2**8^(p?(r|P;@^T;q3 z3$#1FoY1hfdA4NxSf3gH0Krr~3dwQthv9#YZEelOVPwrs z{6qL#tZDmUnB2fxFh^Vt)%VBkLE#y7&xUuFw+dsL-3y{W-5-T~Q>9z|siU=g$K|s| z?T$0gPipn3)|ENMwsO^{%$q+SH9Irmol5%M%S|bk80)g+u5SH^O?79a2qGBboY@dwO=kqUzZ2ox$C<|fIih5anBW1FQtMO*5^s( z{r2Q>oYwDz{s4SL_=Dkyb^Q;)ULe+Vc_nyK>dw+hqjpos`9bMi=AR^&x-!XzAy>xX(4U9bTt3c}_8In!7k% zYv6apKMvSWb*cP6@iw1lWS(Tx&8N#6M82f30=XD&E#imm4Jc6m0K$Ip{44fz{tIvM zyW%&Dz8m~3)qFGJYx|Fd{{R(I-pf+4fT&p>O{A{=qacuemDG5H{s`^+IQXl_Hh&A| z@Lr|iFA?k7H`;W)R@(Khnn?ov=IW#7#}(^+PVu^Dl}|L=+D6CW%sS*ZQbwW)5u|J@ zw*ZQ@BSuvDaz;*18RU#t?DxPg*)!osj{gAQp1%%*z+G#^SDqZVn8&GUI{YFVyG%CIjN>>X z@veWXJJ{%sI+JI?dTfgKJ0y{ncsa*D{{YgQ*X+|O$G;dLw{Sg8RsPcnaILq?Y!S%& z^<_`-D8}*ge}!|-Hg-GHzQoBZMwt7_!5sbS7JoS#8OC#iQ5oxKL z(EHYW!OBk*`(#%eeF5~Tt*$rCwU5o7O;wIf^6mMPZ$Ed6de6S)n|CUBz^W&dyifz? zF6jcWP(kTSa(s)Xk+zs~w1d|^wN5!!HyPYK&T_pfaH@AM?DLEs`R`SJgxH;Jqq&U9 z<|}z^yXG8Xq?UGBJjh$-Rly)+5mnaOIHXl(-L-iO-`bjk$YNvP8#5Jc-iC{dWLMN3 z?O{ucQqoBo=Wq3`ofh<7#FJdccJ1Tl+EuGM<~H)%%jH$ShrJp+zFG1n%E*51PH~?~ zBe6k2IP+=)TjYhT>KGRl5aN&sweVJ4}sjZ0=(v8X@Jl zBLtl1HHoBOE|IQV&9}@+xNv#SdYZbv&3Fpo*%N*qgm#WK}Z2O4nZHooY(93{2T+M{6O)qz?~n(o(b1= z>yH9C`$hNm9KS5FGUZ=#^Ry0l^{%=wQj$rWScy2hSolxkZ~Plu`%-)$(eAY!Cey*b zDz%LZ5A1DSXP)2=!8U=D>6-Y{#h(ZD--W&@pG)yahjk4H#THD$eLnKpppl0kGGyVg zo}kyLd?Ed`ekXp-8il^U;7^SHD$?2k=0~UMH_}~N+yRWCiMJ`w1MY*=WOc9B{{Y$l z0K|U|{{Z0OKiI1Jl2G(ph8<)06rFrBh_l@%H3~&Q~4OSx#;i;`TDJ=#V34_ckyQ3c}Zu`_2*dp9U z&aT4+cXAB`2;_V&84lCC?+T6Z#fH|xfI;2Y*0^OBbPI8rA}c4EBV=TfeqU;u*IJWD z)GZ+m8r#VDVnA$E0ueA~6AiMDm>z1bp<(vBR$bc)pOLY_qeKU9ai`sCURkwvb&>vl z;$l9elHB8t7>?Bc0ERybJZtfD#J8GnfV?}ec&kvikIcA> zPPc1@gl8L$(0I@5T>goy#+tfFB3OLkw1Rr(yj3aMx-#NYThj24&lx z{2Ki%{{Vu6f59{2!p`cUEx6dldGz>lwoU2sj>5qBj22)juZlE?tnSpoxWgF(o->i3%97FJMdC)=gMrs+tZPwp z<;c$X)aF+}*Xt@qCA74jHsInQ2m`ii8=V_W7anwWv6OzXkC^{{W41^2e$*Qe+lh9ntQ!53|p2d?}*aofAvb+em}RGu!?9kN1c9=8t6tuVG50 zlF^*4&%(_e3&(1=R}w1cJGuOES(=A{Ewp_-t|VQ=^aGv0T7$)&J=9~>{>^O7r^ctM zkD2|+sk|ks%c^PGhLLe_-)Oq|<99tza4Q(7Cu2{3*KDt+YIgc$O(I%Yvts~Cooh=# z@nw`(zGJPtdsjFMkH8xC@AxK`pYXMRZGQ^r{{R@Y7`5LBYm5DwVwK9r1;hNQBVdjL z8vSVfw!dWm0NA(oI!hDc&)NR~TAN9}P4Ma-A6K1lMn-w9>BTynwm9qJqX)|)@b6Lh zpA3(>-rXa4fR8(}0QIP&@ltCeSwjc0JuN1Y^?H9x^4O~eJDqG)% zSmP(S9-_ZEz9Q&a4xQr95lP`|r@Zj(t>mLgxRh;@XcY0ddgJr2R-PR+%zdv^S)azU zPZ#<@S(W}!Bwg4ajbPlJHch{2v9&v!hDE^~)eSRIH!*oK58pS;zSSg>vZu_^<$Dp< zxN36kW4br6x`&2zJBdHh;kaM#eBCOX{shzHnM7Ao#;kGkuS&Mgxm~Qv*~u&3p0^o% zz8~1vH!M3FCneO(i@64f^)+te;H}l9Xt!7P>nnV#7|AR3 zu9HsHhOAO({N<5Ue3Bo!!_u=nX|J`E5p9sI)x-5}p?m&xojOr7_O%tcsomZ30Y>E65B(Aw3dw0EF93@IBqkCR zCmzS4B7h9TsV(Y{od1C#Gxq#iT>0E1q29|S8}$NNI~7CWnf^V?nr zwJ(m@d{>(MME?MTY<@O)Uq^YoCE_mx_~zCiWNUj3QCemrpOtcRT@>iG3!{(gl<#Yw z5iYB5VS16=GNdvvWnocxmrl`qL2i8HnWR!oa>b0|ruet;TgCqX2K-rj;jb8IH~KEK zWu5l7ag}9J#^8IexUNf1y>v+}yJYD)1Dz8J$a`z`OJRFQL+ z0B75+M?b?$iv`^trw_^49Ac)Crt-G#U5wtmtwfP5a{mAm7W>4U{x!)c!RXEX;<)gB ztoExS-dn0};P1nIYM1;Yn!tdvuw^n81imtTMr(HV;iZXJaQRN$A4-y0zR(pU#DH+1 zkGqcb9?B!POHFF`iwwT8jdW>iMYiYbeccERS%x=?L z{n?;n!5QuET~ykHGs7LkD9h&owF6^s)`-!I(9Tt)wLIqA!g}LMs+O|`KQK};nwh>I z>ylqAa!2LJ+~J?4cN(vYEcDCxqPZ+5opHk-lZvSN(WB zbUfcmc;basQb{D}V(bTM(7W*Mj;E)`75$uS&Q2V*84sm&S0Au<;QuBQPNP=9-pgRCa2~}ERsbb61|+?c`|-$+ruTIIB8m#0z~U_(!V68zUYhSXI9yJ01+dtBwi#{nOn(b^%d*CWz+5?iuTUl(c_cu<^{ud!5FKW!{{1(3wbrJ zonqK55>!>*-om;*rk<^tdw$6AQ>fqHljYjT%1_D_NyS(?KDDVQmbzWipHUH7?yq&- zS#+rNYbUo|Jif8 z%&lrSXO{cp(-q&J30f_*ak|LUJ7w91V*~rO$5?o-XSR|_HCSF|QW1GW8TuN5e0Qr` zUqcnu>O&Yp!Ja%UiAACyK4iD$MMsp-gf`cUNB(uV#q!6u>_4V;J!)-bC#PDLt1j5(!CPb;a-Oe%(7eE z6;(KAlji(~6_=>^LraPc(Aar#uO;M=o!_k<#j$&6qnWhTB1vkm6bSp0t=`Cq8$qmE@5zPE?>s;O6!!2jS!|f2pw@|Mk;%wJJVd8_f;y>*9n8dgq zV`F&FYS=z3{>#$VRr4)GgXfG5)pClyn~DG;LEXL*eGWEnh_4J^XS#;s7L7htlRbWw zR@=sw!WG_GSn@@68qbZi&061O&769KN;l(X)*nMy@J->n)bl^E?#|=dOk$k5p62OA zAJZy^c}tSpP!)9PgX>IPGMxZejomqFXWxnto zYFNTFEWb32r}&3jj$gDGUEU8bYkaCtdUd7S&K5bB_mUn;^c37ckigN#>~p$82=)|t zJ5E+llnF-ZzS;ptx#~(^SBAhD?*j>aAY6`Ok z`I%dw2fw{W(@14y^3|6ZB-HWD$~NuXRCAu6oddOotYHS#=Oa1K1kj)91NU-mc+PM} zcjRrTn}v zsOw8C<#PK$Zo@Qn0k3blS~=NdEyyd;d8u9Yqb?NW_x=&;DzItUj`fWC1?@@|)aFAU z&C0fLxTXd8pkz-mhwirVj`V2u*ILcP!*6XQ%)_dwJ8HSq77J;vuV#uHJ4nmO!|tj9 zl778w^FQ|W{{Vu#c+Ehh`a9ri#2}-lH(amVitj8$DmyG>tAA#Dx{4D)8_Rmnf)U^wZKQcuP)x%7&f!#sr z_*cz5kdl@F3u)>~N>qw>Z!mBHy>r^CdN{@1_oOszso zhFk4dL(c^B>J4004NwJ$iWyx`1Q2_5uM4=-^|(AwZGEU|^4Y_ACg}4X6a(pA zg>!PlOPUzwnl_a-w29R-T~ntS{7C2a)gb-WS@CDan;l!mw_3M|HL0)lyN{M>_8AUx zPB`c@Te>{a_=iMEn(7h~7x+uAq5WBgU=p9;09ZTvW~#gnt< z!96Q_aYpERMP~ix2G1+nfWPhti<5@fX{`GseYp z$?pL(tuI#AL}??ANXn2=hX5L@D-J2Pcy_DtCRrLt;& zWliGi>xam2J%F!a@mIpn3F9+Tev>9cc ze9eZEMx3XP=@won)?#0=N2*I4#{kBywEi{FX`i!Cj5X$Fn%+BdIX`H)RX@(XQcZq+ zPT%bI(tVd}?No(!s`KqqUA^<%Y?-G#f2?LZO;ynj=L==~H(Tg#jjCKrcElXVZU*1Z zx?c_aKJfnlg>?3R?7Lf=i-Uz1BhB)~Ueqq5wP@|UyTGKSW{pwk*VcrEQ?QH`-6LHbrY-uagDLnN7zl!Dm%zQVcvU*iskrd_m6 zeAjTuIX3Zb!TORb15o()Z)J8{PSd{8#srrq{{Uqf{&bXs*|X7f%NCHVa7520z*%Ao7b->GU#r$`%e#L8XRf4Tv$CDuMRc#BCnj^&t(zleVG3MTGpMOtW~GTu6+^v6Mo5dAF*e_3oi`9;^V{@ zQHiyi^UF&s43u9$GmpZ(b!_8SjgQRa(XyY!a%ncW8%r_jcpM50%Mz-EW09Sw*VchC{{T0cmD!NK6tFpqHk=WPA#)7UdQs_cy$ud5n~Bav<-4A7m!fCoyj6%OeC0EM4$JwEXC zr!>BF&a1TJs5!#Y2v`(h@*wKn^X*S4S!7isEz2I8g#aVO%8QMqbDRPC(}S#oG4x}C zbJCi{kSc~%Uv6;#ftr%oVRtUn+4sI$3b2Wn%w;*_1FbqD zreBcl?Ah-?4Os&QBW#|^*r^0r7@v|>R`9|O`wEpV6<8}S-r)2U0HWSVvZ%pBHsHsdzSQg&<^J-XNEppFH30FL!0VIu zjS=p1nIvY~cu_zS$@|%rkKF?p&sqX+{_69`y(F=##NRRo&raf+cDY|MwyK;1>Sz-l z< z#mc&tZOWv4qLo9>C(f+6UbyQ{z>jY3cMJjQDxayCN^+fF(j^paqI7B_R6Rz7)EA2%PB z7Xb{N)Mq3N5krr?_d@5NdT5cQQ}Y$u$34Y6%VyirReAb~R@6ePVYedZo@vDx3}^2g z^GsjfJ2I}`diu~`V8aflf=y936`YUY-II(8Rm$!E0A;g}T5Dj*@}IlODtM*N3vTq! z6abUH*%?ulUH<@t`qB~S#L9O0k&M!#a=W&YPX&bzp-TXx>z?!gN4c6XRlRwqFk>lZ zk7zs$Q54MES($V9a1TmxEC)tzaX=BF-MNnAwBnuj;cf<7jFZTw$oYM%^6lgd{4^d$2sp#8@7&zX#A)ED~8>VnMVM2qzjH$1zWy)8h0rs7po4m z&>7IMKo>hn_n--g#CwbFlXeHVsAk$snApXJK|QHfPb+TWxry2+am<-i^d_%B6-Ue$ zf(qv#@M#Q)4p(xnF}KvxGpeozHshr*NCN`DC>?W22xPmqFD!>R4}66ST%{2ya7u$_#zgFiOjfDC)ri|Lke=^8z>BXd90fiZBNCGVJDc#$Rr+$Iv?d%CYKDmK2}q> zobiuJ;e1cx9aF$2ZV0J74xcHkEQl^I|uN@b{h4?)tsL!iV&Wy z!8Gl9=-Jw;NhTk#&P_Vv;KwIFB#rYn4RYQn*Q18%zGBBY70au4XGCLUaNo2~jTcP# zX{<=H2>h#e1h?^IV-@fRhQ1wmgT&SsdZwSH-(FeRk2ZOtk8p^3n);Xaqwzy)x3PGB zIT!scOp@ofpun$A{hNFYo&)f7F~+X5NTHk_c>IwUtPJp z{hmA{_L)5E#e|tmfT;tZ6nLjx5Ju4`JD6}!MXfD=#4KUVo?3Zisv;mzKPvLS75L6u zy?vo?^*F%Vc_zMoySs0>?@?Nwf#L6n`iQjqJ2vKsVOSobtZ25A>UT{v(@VQK0P|jd zq-)<~n`a7{BvhAF6M>4 zQb$o=T1lgcWkgvcR*eQ#hC5d@A#)1XMMxns6=fTKqoqlnQAC4rB!WBD#j%zzmA3hP znQEkn!M5!Al;v1Z<6|MR7|{ILGINj*8KxFtANNm6Cy?9150|{NbF_2KSGc~0-dN+3 zU9QK4^`hlOw*aR4m*dpi!w4LVELXm>1;o;V=a zbZ=vlQ91~9Pd@3Dl>EIj-lZ)YBYe&0XDR{Wxr=`pLd%_lz~hMwt+cD{{khvSW@uwfIZ> zNPf{8*X=FwcT(|}i7q6Ou3Y_|5_9E8o&X((_OjF{v4SyRbX)U$XFiK&aDLii_T7=bS~GIZ4xlFnmel zd#!fy7S`HbporsuFU*7caYA+KIFvd4LFxm#{_ z?(}?is(v1@8UkEucZ!l~m&fLIJSg_BtIY9=gf%=YzY6Qh;ig(Qhct#+w@GqF<~Zd2 zD>mBxT~GZfmt$=xBgf3#_pOO_Hn>%qO|nUx1L!NV_yh3H>*8;Y?QJb>Oulmr4Vhw1 zeodQZ(wlN;=^0*I2-!2P{gS_BeRJcti|p*|ZCRQ|0pDlIZk@^Zui5X}&)`m<@I%2i zI!2#vM9{*kBLVl@jQ;>y=6_=!*}B8vXMrI^wA-oOC^9e@AfHr_$qW3e}ewHYle(%;K)%mY3brEJH3kmH@X=aEmdiZ~_XH4A|*X!>F`)U8~cYNbMFs^_x?$08_rqvLBX38+~ZzXr5b> zCBm}f`_$md2Mf==Qn-$5M^;yjl=T#lUU`q#Z#)ucbrAVkqNf0y64fFv9DK#P)C%%O ze)_XFrCGMrJh8b#?&+F2gO!PJn}#;+OmT~5Y_Vmc1FOuA`Zvb1i# zSOlD89w=Q~E+q2ikFX3lBBr>#ks@PpBm-#6k-!vKYDuWB3-)qy-gv7NNIBpi3|P)T`~UT8~#{0twZ9K`aI zHK|^?J@R|e|pv^}d?2G&(j@{@QM5z+S{{ZUO+n$shD)z%t zp+*6`%wvKNY93g?+qnvRcBReGdV^S7%vG3`VeP=F7S=SA=5Lhu1FZ?Ob`h5g&P_cm zOww(6;9cJ^%Zgmx!6W_ooHQu5tNQh+vGq8c2Z$vErFEs@cxX=ffi7 zBnAeKWIk3f$PpXmV$??~DcqrkIv+}t?GZ&6%)@aUbJC$Vu=#)MHtp+2Fu5BYHOn_H z#+&!ouWBCV-G|=?>T0;XjZ=vi9=Yj9F580X$Fi+y$NM;+k=sM)qcAq?Pr5NcJCXv$HxaPRqX}J$F`%h0Uz6~M%S~( zhYK8=jVoB~PnXL)=OU+t?c@1n-JaV`PdQwLZ#{_{wvIbga>U>A%~+K45=JY`UCL@wgAAL^Zo~kbd;9tx+ZS zm`0fX5`B79e`Hv zyVII2nHk)D>R+|*Ok=)2wFA!VS$%lTBo4=l{BQ7LN@S7t8YaQTRlf+-#1D zpl9l9?oSxQ9NIj~G$vz?Hjb6^kHpFCZS?~R!yp~kE?(c}U;z<_LYgs3026mO;EqK?&pN6XpQcd<< z(Z|jJ`=X|JeJ+lwIH$8dT7X?_x%)&>z>zR9I&fHb%~`mfJB42^LaM_6;~B2!#U2b( zGe;urh1YVjj@8BLKVypFytXn32Ea(@YZ%j!=v_UG*)+JWnn=EBqmTf}AmDL~*SLPd zzqhWt`xtn}-p2ZAulyZ#AW0FMb6RBe1JkW|tK7s!_ub|oz`^TP=edG(+bnA$%r?Au z&TFF$iJb|lMVZ&b)2#;?qxa9iUl4Ski~bU|@dt;mAiJ}=P~gVfw&#{sHr)(Nh4KL*JtH&!I>`#3#H{W{{mTYd!o)Se0brTiBLtKt1( z-s|lM9icJ-Bu$P%75Wxeo>Q+IPvSo}&9VxVCCyJ%dOUMIsoNnFBNNE&Lr$#TWNntl zHr8+Uhmp0T+aiOU6IKPv!l?Tfb7z5HMH-QMqvl;XEg5C5)qeKnH8RV+bCqF%f-164 z=GuI*i60!}txaqeYj543E=B63RdW$*504D^Q`?h9f4!exooUFPYZQ@ux9OgkqCL?M zE`EQyEl$ zKEV53zjr5ka>xCp8HK)CJ5i@bnz53`au#(MOw}YOs~K{KNR?#!*79{UYj-kuY+LFp z^I6E-T#i8c)4V-!nvdFaJwd#?gak%U=}`Dy?U(I-AJs7;@~T*H!?DFtJ3UD}NB;m4 zk!!8kvbCg`-?x$Y)LtsPHg?wf_MP)>BhE$cJw;UTmZ&scUh~5j%DzmWGzGdkpHHPw z@TRE#9`QBThP5W$ZE(e{9PltBE6F!Uax(xu zG3{CNnx%AH@%6&%o)ok31%^J;X2H%r_6Jc^ej)3v;*SJac#BW@t}H;41E}=|vit|E z{{X^2Qf^@dAdt>V}XPGHO}}$;skyl@piG{i?)ngw1uHxRXx92T8Y^ss`!iI zHr9L%r}&!2OiN^&rd;w=brpy4FU9MvcrQrtJ(*^j)U2mxR$jQSf8p)UrKenYgGanw z_7X_O5s#EBcKvHZLh#gjMw2a=nWVQI`A4GrRmPq7Io)dv_=m3C_{jKs#5zyz?v?h= zt<{i@m2Xq<^qSv_EVWCi3eRs2-Ku`~)~zHle`c&O#Hy>)6*Shk(^aIAR|k^E0Dd*C zqaDn>q@+SN+E2YAjaasLUVgPSHun-covI`1<+@j&{80U;JP+`s?7P*i=Db{f?OYJ2 z>t7rG(?9T7yE_)Tu<-Td2gy=f$Z-7naadHvM)rx z^qXn6%W~4~7XW+uS1a)o_RsLGmxgr@0qfTG;!CSTXLBqs<|3SMNdvEX`R~Oa8a!EP z;hXEpuVjky=o0cH9m}4-;a^hz!C&w|J%9GQ_%(0w1I0c#)BGc*>tMZrc$(r_{{Y); ze=fDQMSda+%SINF0 z@Ls#&Eq3z4OADzawYYT>c|@xW{p|GTuj5~`9}E8g;Mmx_7-X71kJ??dGJWWiPLMJ8 z!OePfU+`~tgzvN|EOl>=cNa0q)WN3#`t8kprEW69Lj0F!bv&kM{0~IGw`cP$+^#m1 zU;Yv0KdOG`)gL3<2YF+NnY#0 zi%pW^OM95&Sy9zwLaIPK^Iy5&6aN6<+3yJIdVl;-elyeboBno5dhFZ%0m-kOelCB( zxZkuEpQK3@t^S9tSjYEX)?{zTZ(8)Qd|idBC2c)S>SZn}?EN_Z0D@+J!BM^!{8{~w z{0n2Dc(cR$J?@93Tj|=Kk$H0z4HU?MNGjw89DX3zxof@!_+#;2=F?ErJQv{m>zLeJ z+g;mQMvSg{NTqNO*1wyt9{&Kr7``cdFV$gR5er>D-bqztyB5;_0Hcik>?-4>eY^0R z<4?v9%+lwc++%?g9-j3K`sS#TG&gG<#k|=^j!2P}!RwKZYxAGshx`{8#GefB zTF2s-f#z#S*Ll@+G&d-Nq1>b9UVEDQtKh%<6zky6$BSr2i{lMG;%SC{%{-zx;y#5* z$gaBFHz`@b=fmdLUh%cAd>T&)c$!ZUcpZk1sVnZ9<D69ZHegHQ#(b_?KhxI?3#A zAd<&YgkoqU`_VtQ`#$x5M)7`!;;466-dfy9FjPk4KdnKid_J@mfALx4G1P$#K?QQMr zQQTg6X}KU9x*Q5GG>gkvw=^z`*pb1ivNW*+8#05`^IsEEjN+7s4AG&jhWkn&zo=uq3mLtX%c4l64>WC|~Ujr&=}D=fo&W z5uYV=_1c{2grj`ix^KK}rMuKX+TU&DJ%dd#N1s$8b;?49i%AN#q_70oUc%wzumF4@)n zv4xh3X!?4_#dRx>E=Jmb5=xG6IW_s``&0h_!E5|&@ZaK|vEko`x-OG%W24M%zgr@?=(c*ONe$LN*6{2VE)!3OP1;T?_Y#xh>t zQW50+HrJi}TK@opggklT?H)^i3wUQs@PC-wOsquHDE|OwjQOHK^ptF-YYhT>k(F0|3`8;Z?KLqS+msDq>u_OUFa$-|(%E1^5c$>N)OjrP|4Y zu`=*}mDbPUJwL<=57}4jtb{A=KY!M~voGQ778VLLsjs;CJa-ggtIG46`5tYl-f8zY z>jaU(9F3A4*X0A)W~GJ&(yYb9ExSXpw}pdoVcQ++-hKl7BKTYJ3j4*jz9f!2e-lS# zdR38KWlClFWxV>*_uIE2^d+4Xj-?_Z;-| zn%X$c{pLr*pV-slcf<`Q9al~81&lVgL1uapN^f;!aRF|_{xgcrrOI&I#q;;$BK7fLp7napxcPJNwTY9|1lmM+9VY=l#LzaVJ6vUzPA=}mpczv~5iYc_Zmum1oE7lY&f0Evf%ejzk$0c(k1lmz?%tNs}A zwf&l}*maK)X!pze$OBCxOb>1e^~HOo_r(7I89>pQH4BTIO~2_TNjGN$o+{Rx_8$<< z71Wlt^Gv`MW@OQa*^W9wcs@hZmW;r{@O^($EyY%$Eoelgy<&)Ku%CWrei-8QeRLiYMD zvQ;k{6#0Q28w1k3-}cJ=uf84l>ODdHA9bngA8L+85`CDV4t+8`Yw+CjBb^*yEEl_T z^?a8&g={Z8p0+*~{{VuE>Hh$1_>H1!nrk$+7Yge;lkzEEdF`C$zH(3V#2Vq9SS!450uyPGJdZL$L6Jx3WHl^C*#Ere=WcJq&K zty;xR2~eiG6;{)Kl2w;&y6poUYSJr!RP6^DrzA^n7SI=Ka7gVzMe_duyj5@xde%J7 zPVCfc?l@*u5%dj?^w0whyMK#09<=9^A%0D<`V-!W7tHxpnYqm;xDu9e^D|?NVv;t? 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

  • s*R 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

    y%$FZb|D{S3WVf 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

    c1?4QI+Rnu7BbI53Iywk>cytG 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 Ju9LS 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 ZZM{bW+M + +// +// WARNING!!! PSRAM IC required for UXGA resolution and high JPEG quality +// Ensure ESP32 Wrover Module or other board with PSRAM is selected +// Partial images will be transmitted if image exceeds buffer size +// + +// Select camera model +//#define CAMERA_MODEL_WROVER_KIT // Has PSRAM +//#define CAMERA_MODEL_ESP_EYE // Has PSRAM +//#define CAMERA_MODEL_M5STACK_PSRAM // Has PSRAM +//#define CAMERA_MODEL_M5STACK_V2_PSRAM // M5Camera version B Has PSRAM +//#define CAMERA_MODEL_M5STACK_WIDE // Has PSRAM +//#define CAMERA_MODEL_M5STACK_ESP32CAM // No PSRAM +#define CAMERA_MODEL_AI_THINKER // Has PSRAM +//#define CAMERA_MODEL_TTGO_T_JOURNAL // No PSRAM + +#include "camera_pins.h" + +const char* ssid = "OnDe"; +const char* password = "44444444444444444444444444"; + +void startCameraServer(); + +void setup() { + Serial.begin(115200); + Serial.setDebugOutput(true); + Serial.println(); + + camera_config_t config; + config.ledc_channel = LEDC_CHANNEL_0; + config.ledc_timer = LEDC_TIMER_0; + config.pin_d0 = Y2_GPIO_NUM; + config.pin_d1 = Y3_GPIO_NUM; + config.pin_d2 = Y4_GPIO_NUM; + config.pin_d3 = Y5_GPIO_NUM; + config.pin_d4 = Y6_GPIO_NUM; + config.pin_d5 = Y7_GPIO_NUM; + config.pin_d6 = Y8_GPIO_NUM; + config.pin_d7 = Y9_GPIO_NUM; + config.pin_xclk = XCLK_GPIO_NUM; + config.pin_pclk = PCLK_GPIO_NUM; + config.pin_vsync = VSYNC_GPIO_NUM; + config.pin_href = HREF_GPIO_NUM; + config.pin_sscb_sda = SIOD_GPIO_NUM; + config.pin_sscb_scl = SIOC_GPIO_NUM; + config.pin_pwdn = PWDN_GPIO_NUM; + config.pin_reset = RESET_GPIO_NUM; + config.xclk_freq_hz = 20000000; + config.pixel_format = PIXFORMAT_JPEG; + + // if PSRAM IC present, init with UXGA resolution and higher JPEG quality + // for larger pre-allocated frame buffer. + if(psramFound()){ + config.frame_size = FRAMESIZE_UXGA; + config.jpeg_quality = 10; + config.fb_count = 2; + } else { + config.frame_size = FRAMESIZE_SVGA; + config.jpeg_quality = 12; + config.fb_count = 1; + } + +#if defined(CAMERA_MODEL_ESP_EYE) + pinMode(13, INPUT_PULLUP); + pinMode(14, INPUT_PULLUP); +#endif + + // camera init + esp_err_t err = esp_camera_init(&config); + if (err != ESP_OK) { + Serial.printf("Camera init failed with error 0x%x", err); + return; + } + + sensor_t * s = esp_camera_sensor_get(); + // initial sensors are flipped vertically and colors are a bit saturated + if (s->id.PID == OV3660_PID) { + s->set_vflip(s, 1); // flip it back + s->set_brightness(s, 1); // up the brightness just a bit + s->set_saturation(s, -2); // lower the saturation + } + // drop down frame size for higher initial frame rate + s->set_framesize(s, FRAMESIZE_QVGA); + +#if defined(CAMERA_MODEL_M5STACK_WIDE) || defined(CAMERA_MODEL_M5STACK_ESP32CAM) + s->set_vflip(s, 1); + s->set_hmirror(s, 1); +#endif + + WiFi.begin(ssid, password); + + while (WiFi.status() != WL_CONNECTED) { + delay(500); + Serial.print("."); + } + Serial.println(""); + Serial.println("WiFi connected"); + + startCameraServer(); + + Serial.print("Camera Ready! Use 'http://"); + Serial.print(WiFi.localIP()); + Serial.println("' to connect"); +} + +void loop() { + // put your main code here, to run repeatedly: + delay(10000); +} diff --git a/trunk/Arduino/CameraWebServer/app_httpd.cpp b/trunk/Arduino/CameraWebServer/app_httpd.cpp new file mode 100644 index 00000000..5e33ec7c --- /dev/null +++ b/trunk/Arduino/CameraWebServer/app_httpd.cpp @@ -0,0 +1,662 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// 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 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#include "esp_http_server.h" +#include "esp_timer.h" +#include "esp_camera.h" +#include "img_converters.h" +#include "camera_index.h" +#include "Arduino.h" + +#include "fb_gfx.h" +#include "fd_forward.h" +#include "fr_forward.h" + +#define ENROLL_CONFIRM_TIMES 5 +#define FACE_ID_SAVE_NUMBER 7 + +#define FACE_COLOR_WHITE 0x00FFFFFF +#define FACE_COLOR_BLACK 0x00000000 +#define FACE_COLOR_RED 0x000000FF +#define FACE_COLOR_GREEN 0x0000FF00 +#define FACE_COLOR_BLUE 0x00FF0000 +#define FACE_COLOR_YELLOW (FACE_COLOR_RED | FACE_COLOR_GREEN) +#define FACE_COLOR_CYAN (FACE_COLOR_BLUE | FACE_COLOR_GREEN) +#define FACE_COLOR_PURPLE (FACE_COLOR_BLUE | FACE_COLOR_RED) + +typedef struct { + size_t size; //number of values used for filtering + size_t index; //current value index + size_t count; //value count + int sum; + int * values; //array to be filled with values +} ra_filter_t; + +typedef struct { + httpd_req_t *req; + size_t len; +} jpg_chunking_t; + +#define PART_BOUNDARY "123456789000000000000987654321" +static const char* _STREAM_CONTENT_TYPE = "multipart/x-mixed-replace;boundary=" PART_BOUNDARY; +static const char* _STREAM_BOUNDARY = "\r\n--" PART_BOUNDARY "\r\n"; +static const char* _STREAM_PART = "Content-Type: image/jpeg\r\nContent-Length: %u\r\n\r\n"; + +static ra_filter_t ra_filter; +httpd_handle_t stream_httpd = NULL; +httpd_handle_t camera_httpd = NULL; + +static mtmn_config_t mtmn_config = {0}; +static int8_t detection_enabled = 0; +static int8_t recognition_enabled = 0; +static int8_t is_enrolling = 0; +static face_id_list id_list = {0}; + +static ra_filter_t * ra_filter_init(ra_filter_t * filter, size_t sample_size){ + memset(filter, 0, sizeof(ra_filter_t)); + + filter->values = (int *)malloc(sample_size * sizeof(int)); + if(!filter->values){ + return NULL; + } + memset(filter->values, 0, sample_size * sizeof(int)); + + filter->size = sample_size; + return filter; +} + +static int ra_filter_run(ra_filter_t * filter, int value){ + if(!filter->values){ + return value; + } + filter->sum -= filter->values[filter->index]; + filter->values[filter->index] = value; + filter->sum += filter->values[filter->index]; + filter->index++; + filter->index = filter->index % filter->size; + if (filter->count < filter->size) { + filter->count++; + } + return filter->sum / filter->count; +} + +static void rgb_print(dl_matrix3du_t *image_matrix, uint32_t color, const char * str){ + fb_data_t fb; + fb.width = image_matrix->w; + fb.height = image_matrix->h; + fb.data = image_matrix->item; + fb.bytes_per_pixel = 3; + fb.format = FB_BGR888; + fb_gfx_print(&fb, (fb.width - (strlen(str) * 14)) / 2, 10, color, str); +} + +static int rgb_printf(dl_matrix3du_t *image_matrix, uint32_t color, const char *format, ...){ + char loc_buf[64]; + char * temp = loc_buf; + int len; + va_list arg; + va_list copy; + va_start(arg, format); + va_copy(copy, arg); + len = vsnprintf(loc_buf, sizeof(loc_buf), format, arg); + va_end(copy); + if(len >= sizeof(loc_buf)){ + temp = (char*)malloc(len+1); + if(temp == NULL) { + return 0; + } + } + vsnprintf(temp, len+1, format, arg); + va_end(arg); + rgb_print(image_matrix, color, temp); + if(len > 64){ + free(temp); + } + return len; +} + +static void draw_face_boxes(dl_matrix3du_t *image_matrix, box_array_t *boxes, int face_id){ + int x, y, w, h, i; + uint32_t color = FACE_COLOR_YELLOW; + if(face_id < 0){ + color = FACE_COLOR_RED; + } else if(face_id > 0){ + color = FACE_COLOR_GREEN; + } + fb_data_t fb; + fb.width = image_matrix->w; + fb.height = image_matrix->h; + fb.data = image_matrix->item; + fb.bytes_per_pixel = 3; + fb.format = FB_BGR888; + for (i = 0; i < boxes->len; i++){ + // rectangle box + x = (int)boxes->box[i].box_p[0]; + y = (int)boxes->box[i].box_p[1]; + w = (int)boxes->box[i].box_p[2] - x + 1; + h = (int)boxes->box[i].box_p[3] - y + 1; + fb_gfx_drawFastHLine(&fb, x, y, w, color); + fb_gfx_drawFastHLine(&fb, x, y+h-1, w, color); + fb_gfx_drawFastVLine(&fb, x, y, h, color); + fb_gfx_drawFastVLine(&fb, x+w-1, y, h, color); +#if 0 + // landmark + int x0, y0, j; + for (j = 0; j < 10; j+=2) { + x0 = (int)boxes->landmark[i].landmark_p[j]; + y0 = (int)boxes->landmark[i].landmark_p[j+1]; + fb_gfx_fillRect(&fb, x0, y0, 3, 3, color); + } +#endif + } +} + +static int run_face_recognition(dl_matrix3du_t *image_matrix, box_array_t *net_boxes){ + dl_matrix3du_t *aligned_face = NULL; + int matched_id = 0; + + aligned_face = dl_matrix3du_alloc(1, FACE_WIDTH, FACE_HEIGHT, 3); + if(!aligned_face){ + Serial.println("Could not allocate face recognition buffer"); + return matched_id; + } + if (align_face(net_boxes, image_matrix, aligned_face) == ESP_OK){ + if (is_enrolling == 1){ + int8_t left_sample_face = enroll_face(&id_list, aligned_face); + + if(left_sample_face == (ENROLL_CONFIRM_TIMES - 1)){ + Serial.printf("Enrolling Face ID: %d\n", id_list.tail); + } + Serial.printf("Enrolling Face ID: %d sample %d\n", id_list.tail, ENROLL_CONFIRM_TIMES - left_sample_face); + rgb_printf(image_matrix, FACE_COLOR_CYAN, "ID[%u] Sample[%u]", id_list.tail, ENROLL_CONFIRM_TIMES - left_sample_face); + if (left_sample_face == 0){ + is_enrolling = 0; + Serial.printf("Enrolled Face ID: %d\n", id_list.tail); + } + } else { + matched_id = recognize_face(&id_list, aligned_face); + if (matched_id >= 0) { + Serial.printf("Match Face ID: %u\n", matched_id); + rgb_printf(image_matrix, FACE_COLOR_GREEN, "Hello Subject %u", matched_id); + } else { + Serial.println("No Match Found"); + rgb_print(image_matrix, FACE_COLOR_RED, "Intruder Alert!"); + matched_id = -1; + } + } + } else { + Serial.println("Face Not Aligned"); + //rgb_print(image_matrix, FACE_COLOR_YELLOW, "Human Detected"); + } + + dl_matrix3du_free(aligned_face); + return matched_id; +} + +static size_t jpg_encode_stream(void * arg, size_t index, const void* data, size_t len){ + jpg_chunking_t *j = (jpg_chunking_t *)arg; + if(!index){ + j->len = 0; + } + if(httpd_resp_send_chunk(j->req, (const char *)data, len) != ESP_OK){ + return 0; + } + j->len += len; + return len; +} + +static esp_err_t capture_handler(httpd_req_t *req){ + camera_fb_t * fb = NULL; + esp_err_t res = ESP_OK; + int64_t fr_start = esp_timer_get_time(); + + fb = esp_camera_fb_get(); + if (!fb) { + Serial.println("Camera capture failed"); + httpd_resp_send_500(req); + return ESP_FAIL; + } + + httpd_resp_set_type(req, "image/jpeg"); + httpd_resp_set_hdr(req, "Content-Disposition", "inline; filename=capture.jpg"); + httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*"); + + size_t out_len, out_width, out_height; + uint8_t * out_buf; + bool s; + bool detected = false; + int face_id = 0; + if(!detection_enabled || fb->width > 400){ + size_t fb_len = 0; + if(fb->format == PIXFORMAT_JPEG){ + fb_len = fb->len; + res = httpd_resp_send(req, (const char *)fb->buf, fb->len); + } else { + jpg_chunking_t jchunk = {req, 0}; + res = frame2jpg_cb(fb, 80, jpg_encode_stream, &jchunk)?ESP_OK:ESP_FAIL; + httpd_resp_send_chunk(req, NULL, 0); + fb_len = jchunk.len; + } + esp_camera_fb_return(fb); + int64_t fr_end = esp_timer_get_time(); + Serial.printf("JPG: %uB %ums\n", (uint32_t)(fb_len), (uint32_t)((fr_end - fr_start)/1000)); + return res; + } + + dl_matrix3du_t *image_matrix = dl_matrix3du_alloc(1, fb->width, fb->height, 3); + if (!image_matrix) { + esp_camera_fb_return(fb); + Serial.println("dl_matrix3du_alloc failed"); + httpd_resp_send_500(req); + return ESP_FAIL; + } + + out_buf = image_matrix->item; + out_len = fb->width * fb->height * 3; + out_width = fb->width; + out_height = fb->height; + + s = fmt2rgb888(fb->buf, fb->len, fb->format, out_buf); + esp_camera_fb_return(fb); + if(!s){ + dl_matrix3du_free(image_matrix); + Serial.println("to rgb888 failed"); + httpd_resp_send_500(req); + return ESP_FAIL; + } + + box_array_t *net_boxes = face_detect(image_matrix, &mtmn_config); + + if (net_boxes){ + detected = true; + if(recognition_enabled){ + face_id = run_face_recognition(image_matrix, net_boxes); + } + draw_face_boxes(image_matrix, net_boxes, face_id); + free(net_boxes->score); + free(net_boxes->box); + free(net_boxes->landmark); + free(net_boxes); + } + + jpg_chunking_t jchunk = {req, 0}; + s = fmt2jpg_cb(out_buf, out_len, out_width, out_height, PIXFORMAT_RGB888, 90, jpg_encode_stream, &jchunk); + dl_matrix3du_free(image_matrix); + if(!s){ + Serial.println("JPEG compression failed"); + return ESP_FAIL; + } + + int64_t fr_end = esp_timer_get_time(); + Serial.printf("FACE: %uB %ums %s%d\n", (uint32_t)(jchunk.len), (uint32_t)((fr_end - fr_start)/1000), detected?"DETECTED ":"", face_id); + return res; +} + +static esp_err_t stream_handler(httpd_req_t *req){ + camera_fb_t * fb = NULL; + esp_err_t res = ESP_OK; + size_t _jpg_buf_len = 0; + uint8_t * _jpg_buf = NULL; + char * part_buf[64]; + dl_matrix3du_t *image_matrix = NULL; + bool detected = false; + int face_id = 0; + int64_t fr_start = 0; + int64_t fr_ready = 0; + int64_t fr_face = 0; + int64_t fr_recognize = 0; + int64_t fr_encode = 0; + + static int64_t last_frame = 0; + if(!last_frame) { + last_frame = esp_timer_get_time(); + } + + res = httpd_resp_set_type(req, _STREAM_CONTENT_TYPE); + if(res != ESP_OK){ + return res; + } + + httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*"); + + while(true){ + detected = false; + face_id = 0; + fb = esp_camera_fb_get(); + if (!fb) { + Serial.println("Camera capture failed"); + res = ESP_FAIL; + } else { + fr_start = esp_timer_get_time(); + fr_ready = fr_start; + fr_face = fr_start; + fr_encode = fr_start; + fr_recognize = fr_start; + if(!detection_enabled || fb->width > 400){ + if(fb->format != PIXFORMAT_JPEG){ + bool jpeg_converted = frame2jpg(fb, 80, &_jpg_buf, &_jpg_buf_len); + esp_camera_fb_return(fb); + fb = NULL; + if(!jpeg_converted){ + Serial.println("JPEG compression failed"); + res = ESP_FAIL; + } + } else { + _jpg_buf_len = fb->len; + _jpg_buf = fb->buf; + } + } else { + + image_matrix = dl_matrix3du_alloc(1, fb->width, fb->height, 3); + + if (!image_matrix) { + Serial.println("dl_matrix3du_alloc failed"); + res = ESP_FAIL; + } else { + if(!fmt2rgb888(fb->buf, fb->len, fb->format, image_matrix->item)){ + Serial.println("fmt2rgb888 failed"); + res = ESP_FAIL; + } else { + fr_ready = esp_timer_get_time(); + box_array_t *net_boxes = NULL; + if(detection_enabled){ + net_boxes = face_detect(image_matrix, &mtmn_config); + } + fr_face = esp_timer_get_time(); + fr_recognize = fr_face; + if (net_boxes || fb->format != PIXFORMAT_JPEG){ + if(net_boxes){ + detected = true; + if(recognition_enabled){ + face_id = run_face_recognition(image_matrix, net_boxes); + } + fr_recognize = esp_timer_get_time(); + draw_face_boxes(image_matrix, net_boxes, face_id); + free(net_boxes->score); + free(net_boxes->box); + free(net_boxes->landmark); + free(net_boxes); + } + if(!fmt2jpg(image_matrix->item, fb->width*fb->height*3, fb->width, fb->height, PIXFORMAT_RGB888, 90, &_jpg_buf, &_jpg_buf_len)){ + Serial.println("fmt2jpg failed"); + res = ESP_FAIL; + } + esp_camera_fb_return(fb); + fb = NULL; + } else { + _jpg_buf = fb->buf; + _jpg_buf_len = fb->len; + } + fr_encode = esp_timer_get_time(); + } + dl_matrix3du_free(image_matrix); + } + } + } + if(res == ESP_OK){ + res = httpd_resp_send_chunk(req, _STREAM_BOUNDARY, strlen(_STREAM_BOUNDARY)); + } + if(res == ESP_OK){ + size_t hlen = snprintf((char *)part_buf, 64, _STREAM_PART, _jpg_buf_len); + res = httpd_resp_send_chunk(req, (const char *)part_buf, hlen); + } + if(res == ESP_OK){ + res = httpd_resp_send_chunk(req, (const char *)_jpg_buf, _jpg_buf_len); + } + if(fb){ + esp_camera_fb_return(fb); + fb = NULL; + _jpg_buf = NULL; + } else if(_jpg_buf){ + free(_jpg_buf); + _jpg_buf = NULL; + } + if(res != ESP_OK){ + break; + } + int64_t fr_end = esp_timer_get_time(); + + int64_t ready_time = (fr_ready - fr_start)/1000; + int64_t face_time = (fr_face - fr_ready)/1000; + int64_t recognize_time = (fr_recognize - fr_face)/1000; + int64_t encode_time = (fr_encode - fr_recognize)/1000; + int64_t process_time = (fr_encode - fr_start)/1000; + + int64_t frame_time = fr_end - last_frame; + last_frame = fr_end; + frame_time /= 1000; + uint32_t avg_frame_time = ra_filter_run(&ra_filter, frame_time); + Serial.printf("MJPG: %uB %ums (%.1ffps), AVG: %ums (%.1ffps), %u+%u+%u+%u=%u %s%d\n", + (uint32_t)(_jpg_buf_len), + (uint32_t)frame_time, 1000.0 / (uint32_t)frame_time, + avg_frame_time, 1000.0 / avg_frame_time, + (uint32_t)ready_time, (uint32_t)face_time, (uint32_t)recognize_time, (uint32_t)encode_time, (uint32_t)process_time, + (detected)?"DETECTED ":"", face_id + ); + } + + last_frame = 0; + return res; +} + +static esp_err_t cmd_handler(httpd_req_t *req){ + char* buf; + size_t buf_len; + char variable[32] = {0,}; + char value[32] = {0,}; + + buf_len = httpd_req_get_url_query_len(req) + 1; + if (buf_len > 1) { + buf = (char*)malloc(buf_len); + if(!buf){ + httpd_resp_send_500(req); + return ESP_FAIL; + } + if (httpd_req_get_url_query_str(req, buf, buf_len) == ESP_OK) { + if (httpd_query_key_value(buf, "var", variable, sizeof(variable)) == ESP_OK && + httpd_query_key_value(buf, "val", value, sizeof(value)) == ESP_OK) { + } else { + free(buf); + httpd_resp_send_404(req); + return ESP_FAIL; + } + } else { + free(buf); + httpd_resp_send_404(req); + return ESP_FAIL; + } + free(buf); + } else { + httpd_resp_send_404(req); + return ESP_FAIL; + } + + int val = atoi(value); + sensor_t * s = esp_camera_sensor_get(); + int res = 0; + + if(!strcmp(variable, "framesize")) { + if(s->pixformat == PIXFORMAT_JPEG) res = s->set_framesize(s, (framesize_t)val); + } + else if(!strcmp(variable, "quality")) res = s->set_quality(s, val); + else if(!strcmp(variable, "contrast")) res = s->set_contrast(s, val); + else if(!strcmp(variable, "brightness")) res = s->set_brightness(s, val); + else if(!strcmp(variable, "saturation")) res = s->set_saturation(s, val); + else if(!strcmp(variable, "gainceiling")) res = s->set_gainceiling(s, (gainceiling_t)val); + else if(!strcmp(variable, "colorbar")) res = s->set_colorbar(s, val); + else if(!strcmp(variable, "awb")) res = s->set_whitebal(s, val); + else if(!strcmp(variable, "agc")) res = s->set_gain_ctrl(s, val); + else if(!strcmp(variable, "aec")) res = s->set_exposure_ctrl(s, val); + else if(!strcmp(variable, "hmirror")) res = s->set_hmirror(s, val); + else if(!strcmp(variable, "vflip")) res = s->set_vflip(s, val); + else if(!strcmp(variable, "awb_gain")) res = s->set_awb_gain(s, val); + else if(!strcmp(variable, "agc_gain")) res = s->set_agc_gain(s, val); + else if(!strcmp(variable, "aec_value")) res = s->set_aec_value(s, val); + else if(!strcmp(variable, "aec2")) res = s->set_aec2(s, val); + else if(!strcmp(variable, "dcw")) res = s->set_dcw(s, val); + else if(!strcmp(variable, "bpc")) res = s->set_bpc(s, val); + else if(!strcmp(variable, "wpc")) res = s->set_wpc(s, val); + else if(!strcmp(variable, "raw_gma")) res = s->set_raw_gma(s, val); + else if(!strcmp(variable, "lenc")) res = s->set_lenc(s, val); + else if(!strcmp(variable, "special_effect")) res = s->set_special_effect(s, val); + else if(!strcmp(variable, "wb_mode")) res = s->set_wb_mode(s, val); + else if(!strcmp(variable, "ae_level")) res = s->set_ae_level(s, val); + else if(!strcmp(variable, "face_detect")) { + detection_enabled = val; + if(!detection_enabled) { + recognition_enabled = 0; + } + } + else if(!strcmp(variable, "face_enroll")) is_enrolling = val; + else if(!strcmp(variable, "face_recognize")) { + recognition_enabled = val; + if(recognition_enabled){ + detection_enabled = val; + } + } + else { + res = -1; + } + + if(res){ + return httpd_resp_send_500(req); + } + + httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*"); + return httpd_resp_send(req, NULL, 0); +} + +static esp_err_t status_handler(httpd_req_t *req){ + static char json_response[1024]; + + sensor_t * s = esp_camera_sensor_get(); + char * p = json_response; + *p++ = '{'; + + p+=sprintf(p, "\"framesize\":%u,", s->status.framesize); + p+=sprintf(p, "\"quality\":%u,", s->status.quality); + p+=sprintf(p, "\"brightness\":%d,", s->status.brightness); + p+=sprintf(p, "\"contrast\":%d,", s->status.contrast); + p+=sprintf(p, "\"saturation\":%d,", s->status.saturation); + p+=sprintf(p, "\"sharpness\":%d,", s->status.sharpness); + p+=sprintf(p, "\"special_effect\":%u,", s->status.special_effect); + p+=sprintf(p, "\"wb_mode\":%u,", s->status.wb_mode); + p+=sprintf(p, "\"awb\":%u,", s->status.awb); + p+=sprintf(p, "\"awb_gain\":%u,", s->status.awb_gain); + p+=sprintf(p, "\"aec\":%u,", s->status.aec); + p+=sprintf(p, "\"aec2\":%u,", s->status.aec2); + p+=sprintf(p, "\"ae_level\":%d,", s->status.ae_level); + p+=sprintf(p, "\"aec_value\":%u,", s->status.aec_value); + p+=sprintf(p, "\"agc\":%u,", s->status.agc); + p+=sprintf(p, "\"agc_gain\":%u,", s->status.agc_gain); + p+=sprintf(p, "\"gainceiling\":%u,", s->status.gainceiling); + p+=sprintf(p, "\"bpc\":%u,", s->status.bpc); + p+=sprintf(p, "\"wpc\":%u,", s->status.wpc); + p+=sprintf(p, "\"raw_gma\":%u,", s->status.raw_gma); + p+=sprintf(p, "\"lenc\":%u,", s->status.lenc); + p+=sprintf(p, "\"vflip\":%u,", s->status.vflip); + p+=sprintf(p, "\"hmirror\":%u,", s->status.hmirror); + p+=sprintf(p, "\"dcw\":%u,", s->status.dcw); + p+=sprintf(p, "\"colorbar\":%u,", s->status.colorbar); + p+=sprintf(p, "\"face_detect\":%u,", detection_enabled); + p+=sprintf(p, "\"face_enroll\":%u,", is_enrolling); + p+=sprintf(p, "\"face_recognize\":%u", recognition_enabled); + *p++ = '}'; + *p++ = 0; + httpd_resp_set_type(req, "application/json"); + httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*"); + return httpd_resp_send(req, json_response, strlen(json_response)); +} + +static esp_err_t index_handler(httpd_req_t *req){ + httpd_resp_set_type(req, "text/html"); + httpd_resp_set_hdr(req, "Content-Encoding", "gzip"); + sensor_t * s = esp_camera_sensor_get(); + if (s->id.PID == OV3660_PID) { + return httpd_resp_send(req, (const char *)index_ov3660_html_gz, index_ov3660_html_gz_len); + } + return httpd_resp_send(req, (const char *)index_ov2640_html_gz, index_ov2640_html_gz_len); +} + +void startCameraServer(){ + httpd_config_t config = HTTPD_DEFAULT_CONFIG(); + + httpd_uri_t index_uri = { + .uri = "/", + .method = HTTP_GET, + .handler = index_handler, + .user_ctx = NULL + }; + + httpd_uri_t status_uri = { + .uri = "/status", + .method = HTTP_GET, + .handler = status_handler, + .user_ctx = NULL + }; + + httpd_uri_t cmd_uri = { + .uri = "/control", + .method = HTTP_GET, + .handler = cmd_handler, + .user_ctx = NULL + }; + + httpd_uri_t capture_uri = { + .uri = "/capture", + .method = HTTP_GET, + .handler = capture_handler, + .user_ctx = NULL + }; + + httpd_uri_t stream_uri = { + .uri = "/stream", + .method = HTTP_GET, + .handler = stream_handler, + .user_ctx = NULL + }; + + + ra_filter_init(&ra_filter, 20); + + mtmn_config.type = FAST; + mtmn_config.min_face = 80; + mtmn_config.pyramid = 0.707; + mtmn_config.pyramid_times = 4; + mtmn_config.p_threshold.score = 0.6; + mtmn_config.p_threshold.nms = 0.7; + mtmn_config.p_threshold.candidate_number = 20; + mtmn_config.r_threshold.score = 0.7; + mtmn_config.r_threshold.nms = 0.7; + mtmn_config.r_threshold.candidate_number = 10; + mtmn_config.o_threshold.score = 0.7; + mtmn_config.o_threshold.nms = 0.7; + mtmn_config.o_threshold.candidate_number = 1; + + face_id_init(&id_list, FACE_ID_SAVE_NUMBER, ENROLL_CONFIRM_TIMES); + + Serial.printf("Starting web server on port: '%d'\n", config.server_port); + if (httpd_start(&camera_httpd, &config) == ESP_OK) { + httpd_register_uri_handler(camera_httpd, &index_uri); + httpd_register_uri_handler(camera_httpd, &cmd_uri); + httpd_register_uri_handler(camera_httpd, &status_uri); + httpd_register_uri_handler(camera_httpd, &capture_uri); + } + + config.server_port += 1; + config.ctrl_port += 1; + Serial.printf("Starting stream server on port: '%d'\n", config.server_port); + if (httpd_start(&stream_httpd, &config) == ESP_OK) { + httpd_register_uri_handler(stream_httpd, &stream_uri); + } +} diff --git a/trunk/Arduino/CameraWebServer/camera_index.h b/trunk/Arduino/CameraWebServer/camera_index.h new file mode 100644 index 00000000..0cf2245f --- /dev/null +++ b/trunk/Arduino/CameraWebServer/camera_index.h @@ -0,0 +1,557 @@ + +//File: index_ov2640.html.gz, Size: 4316 +#define index_ov2640_html_gz_len 4316 +const uint8_t index_ov2640_html_gz[] = { + 0x1F, 0x8B, 0x08, 0x08, 0x50, 0x5C, 0xAE, 0x5C, 0x00, 0x03, 0x69, 0x6E, 0x64, 0x65, 0x78, 0x5F, + 0x6F, 0x76, 0x32, 0x36, 0x34, 0x30, 0x2E, 0x68, 0x74, 0x6D, 0x6C, 0x00, 0xE5, 0x5D, 0x7B, 0x73, + 0xD3, 0xC6, 0x16, 0xFF, 0x9F, 0x4F, 0x21, 0x04, 0x25, 0xF6, 0x34, 0x76, 0x6C, 0xC7, 0x84, 0xE0, + 0xDA, 0xE2, 0x42, 0x08, 0xD0, 0x19, 0x5E, 0x25, 0x2D, 0x74, 0xA6, 0xD3, 0x81, 0xB5, 0xB4, 0xB2, + 0x55, 0x64, 0xC9, 0x95, 0x56, 0x76, 0x52, 0x26, 0x9F, 0xE3, 0x7E, 0xA0, 0xFB, 0xC5, 0xEE, 0xD9, + 0x87, 0xA4, 0x95, 0xBC, 0x7A, 0xD8, 0x26, 0x36, 0x97, 0xEB, 0xCC, 0x14, 0xD9, 0xDA, 0x73, 0xF6, + 0x9C, 0xF3, 0x3B, 0xAF, 0x5D, 0x3D, 0x3A, 0xBC, 0x6D, 0xF9, 0x26, 0xB9, 0x9A, 0x63, 0x6D, 0x4A, + 0x66, 0xAE, 0x71, 0x6B, 0xC8, 0xFF, 0xD1, 0xE0, 0x33, 0x9C, 0x62, 0x64, 0xF1, 0x43, 0xF6, 0x75, + 0x86, 0x09, 0xD2, 0xCC, 0x29, 0x0A, 0x42, 0x4C, 0x46, 0x7A, 0x44, 0xEC, 0xD6, 0xA9, 0x9E, 0x3F, + 0xED, 0xA1, 0x19, 0x1E, 0xE9, 0x0B, 0x07, 0x2F, 0xE7, 0x7E, 0x40, 0x74, 0xCD, 0xF4, 0x3D, 0x82, + 0x3D, 0x18, 0xBE, 0x74, 0x2C, 0x32, 0x1D, 0x59, 0x78, 0xE1, 0x98, 0xB8, 0xC5, 0xBE, 0x1C, 0x3A, + 0x9E, 0x43, 0x1C, 0xE4, 0xB6, 0x42, 0x13, 0xB9, 0x78, 0xD4, 0x95, 0x79, 0x11, 0x87, 0xB8, 0xD8, + 0x38, 0xBF, 0x78, 0x7B, 0xDC, 0xD3, 0xDE, 0xBC, 0xEF, 0xF5, 0x4F, 0x3A, 0xC3, 0x23, 0xFE, 0x5B, + 0x3A, 0x26, 0x24, 0x57, 0xF2, 0x77, 0xFA, 0x19, 0xFB, 0xD6, 0x95, 0xF6, 0x25, 0xF3, 0x13, 0xFD, + 0xD8, 0x20, 0x44, 0xCB, 0x46, 0x33, 0xC7, 0xBD, 0x1A, 0x68, 0x8F, 0x03, 0x98, 0xF3, 0xF0, 0x05, + 0x76, 0x17, 0x98, 0x38, 0x26, 0x3A, 0x0C, 0x91, 0x17, 0xB6, 0x42, 0x1C, 0x38, 0xF6, 0x4F, 0x2B, + 0x84, 0x63, 0x64, 0x7E, 0x9E, 0x04, 0x7E, 0xE4, 0x59, 0x03, 0xED, 0x4E, 0xF7, 0x94, 0xFE, 0xAD, + 0x0E, 0x32, 0x7D, 0xD7, 0x0F, 0xE0, 0xFC, 0xF9, 0x33, 0xFA, 0xB7, 0x7A, 0x9E, 0xCD, 0x1E, 0x3A, + 0xFF, 0xE0, 0x81, 0xD6, 0x3D, 0x99, 0x5F, 0x66, 0xCE, 0x5F, 0xDF, 0xCA, 0x7C, 0x9D, 0xF6, 0x8A, + 0xA4, 0x17, 0xF4, 0xA7, 0xE5, 0xF4, 0x21, 0x36, 0x89, 0xE3, 0x7B, 0xED, 0x19, 0x72, 0x3C, 0x05, + 0x27, 0xCB, 0x09, 0xE7, 0x2E, 0x02, 0x1B, 0xD8, 0x2E, 0x2E, 0xE5, 0x73, 0x67, 0x86, 0xBD, 0xE8, + 0xB0, 0x82, 0x1B, 0x65, 0xD2, 0xB2, 0x9C, 0x80, 0x8F, 0x1A, 0x50, 0x3B, 0x44, 0x33, 0xAF, 0x92, + 0x6D, 0x99, 0x5C, 0x9E, 0xEF, 0x61, 0x85, 0x01, 0xE9, 0x44, 0xCB, 0x00, 0xCD, 0xE9, 0x00, 0xFA, + 0xEF, 0xEA, 0x90, 0x99, 0xE3, 0x71, 0xA7, 0x1A, 0x68, 0xC7, 0xFD, 0xCE, 0xFC, 0xB2, 0x02, 0xCA, + 0xE3, 0x13, 0xFA, 0xB7, 0x3A, 0x68, 0x8E, 0x2C, 0xCB, 0xF1, 0x26, 0x03, 0xED, 0x54, 0xC9, 0xC2, + 0x0F, 0x2C, 0x1C, 0xB4, 0x02, 0x64, 0x39, 0x51, 0x38, 0xD0, 0xFA, 0xAA, 0x31, 0x33, 0x14, 0x4C, + 0x40, 0x16, 0xE2, 0x83, 0xB0, 0xAD, 0xAE, 0x52, 0x12, 0x31, 0x24, 0x70, 0x26, 0x53, 0x02, 0x90, + 0xAE, 0x8C, 0xC9, 0x1B, 0x4D, 0x84, 0x50, 0x15, 0x9E, 0xA5, 0x76, 0x53, 0x5B, 0x0D, 0xB9, 0xCE, + 0xC4, 0x6B, 0x39, 0x04, 0xCF, 0x40, 0x9D, 0x90, 0x04, 0x98, 0x98, 0xD3, 0x32, 0x51, 0x6C, 0x67, + 0x12, 0x05, 0x58, 0x21, 0x48, 0x62, 0xB7, 0x12, 0x85, 0xE1, 0xE4, 0xEA, 0xA9, 0xD6, 0x12, 0x8F, + 0x3F, 0x3B, 0xA4, 0x25, 0x6C, 0x32, 0xC6, 0xB6, 0x1F, 0x60, 0xE5, 0xC8, 0x78, 0x84, 0xEB, 0x9B, + 0x9F, 0x5B, 0x21, 0x41, 0x01, 0xA9, 0xC3, 0x10, 0xD9, 0x04, 0x07, 0xD5, 0xFC, 0x30, 0xF5, 0x8A, + 0x6A, 0x6E, 0xC5, 0xD3, 0x8A, 0x01, 0x8E, 0xE7, 0x3A, 0x1E, 0xAE, 0x2F, 0x5E, 0xD1, 0xBC, 0x59, + 0x76, 0x7C, 0x54, 0x0D, 0x60, 0x9C, 0xD9, 0xA4, 0xCC, 0x4B, 0x98, 0xAE, 0xAB, 0x93, 0x89, 0xB8, + 0xE9, 0x76, 0x3A, 0x3F, 0xAC, 0x9E, 0x9C, 0x62, 0xEE, 0xA6, 0x28, 0x22, 0xFE, 0xF6, 0x11, 0xB1, + 0x12, 0x56, 0x39, 0x3D, 0xFE, 0x35, 0xC3, 0x96, 0x83, 0xB4, 0x86, 0x14, 0xCE, 0xA7, 0x1D, 0xF0, + 0xA9, 0xA6, 0x86, 0x3C, 0x4B, 0x6B, 0xF8, 0x81, 0x03, 0x81, 0x80, 0x58, 0xBA, 0x71, 0xE1, 0x17, + 0x28, 0x1C, 0x73, 0xDC, 0x54, 0xA8, 0x5C, 0x12, 0x33, 0xB2, 0x45, 0xD4, 0x61, 0x43, 0x3F, 0x35, + 0x52, 0x0E, 0xFD, 0x54, 0x06, 0x90, 0x42, 0x47, 0xC6, 0xBE, 0x0C, 0x2F, 0x59, 0xC2, 0x22, 0xCC, + 0xE8, 0x67, 0x86, 0x2E, 0x5B, 0xA5, 0xD8, 0xC5, 0x83, 0x62, 0x0C, 0xA1, 0xCC, 0x9A, 0x0D, 0x18, + 0xBA, 0x98, 0x6A, 0x2D, 0x8D, 0x66, 0xC9, 0xA6, 0x9A, 0x46, 0x30, 0x55, 0x43, 0x4E, 0x3F, 0xB2, + 0x53, 0xAC, 0xA1, 0xAE, 0x5A, 0xD5, 0x34, 0x77, 0xF0, 0x3F, 0x95, 0x0F, 0x71, 0x4D, 0x0A, 0xB3, + 0x08, 0xFD, 0xD4, 0xCF, 0x24, 0x29, 0xB3, 0xCA, 0x6C, 0xA2, 0x60, 0x5C, 0x9C, 0x51, 0x56, 0xF8, + 0x16, 0x45, 0xB7, 0x82, 0x6B, 0xB9, 0x08, 0x75, 0xB3, 0x8B, 0x82, 0x71, 0x99, 0x0C, 0x95, 0x59, + 0x86, 0x7E, 0xAE, 0x6B, 0xF4, 0x1B, 0x77, 0xC6, 0x11, 0x21, 0xBE, 0x17, 0x6E, 0x55, 0xA2, 0x8A, + 0xE2, 0xEC, 0xAF, 0x28, 0x24, 0x8E, 0x7D, 0xD5, 0x12, 0x21, 0x0D, 0x71, 0x36, 0x47, 0xD0, 0x42, + 0x8E, 0x31, 0x59, 0x62, 0x5C, 0xDE, 0x6E, 0x78, 0x68, 0x01, 0x79, 0x67, 0x32, 0x71, 0x55, 0xBE, + 0x67, 0x46, 0x41, 0x48, 0xFB, 0xB6, 0xB9, 0xEF, 0x00, 0xE3, 0x60, 0x75, 0xE2, 0x6C, 0x0C, 0xD6, + 0x9C, 0xA8, 0x65, 0x8E, 0x15, 0x73, 0xF9, 0x11, 0xA1, 0x36, 0x56, 0x22, 0xE1, 0x83, 0x3A, 0x0E, + 0xB9, 0x52, 0x9E, 0x13, 0x91, 0xA8, 0x38, 0x13, 0x87, 0x60, 0x69, 0x59, 0xC8, 0xCA, 0x35, 0x30, + 0xA7, 0xD8, 0xFC, 0x8C, 0xAD, 0x1F, 0x2B, 0xDB, 0xB0, 0xAA, 0xF6, 0xB0, 0xED, 0x78, 0xF3, 0x88, + 0xB4, 0x68, 0x3B, 0x35, 0xBF, 0x11, 0xCC, 0x99, 0x43, 0xC6, 0x2A, 0xF6, 0x7A, 0x65, 0x4D, 0xC5, + 0xFD, 0xF9, 0x65, 0xB9, 0x11, 0x64, 0x61, 0x0D, 0x17, 0x8D, 0xB1, 0x5B, 0x26, 0xB2, 0x08, 0x86, + 0x82, 0xB4, 0x2B, 0x72, 0x55, 0x71, 0xEF, 0xC6, 0x24, 0x4B, 0x8B, 0x57, 0xFF, 0xC1, 0x0F, 0xB5, + 0xED, 0xC8, 0x8E, 0x0F, 0x33, 0x3F, 0x85, 0xD8, 0x85, 0x00, 0x2B, 0x6A, 0xBD, 0x61, 0xCC, 0x12, + 0x64, 0x28, 0x9D, 0x20, 0x40, 0xDE, 0x04, 0x43, 0x2E, 0xB8, 0x3C, 0x8C, 0x0F, 0xCB, 0x17, 0x06, + 0xB5, 0xD4, 0xA7, 0xA9, 0xFA, 0x7E, 0xF9, 0x42, 0x84, 0x27, 0x84, 0x0D, 0x9A, 0x11, 0x09, 0xD6, + 0xD2, 0xF9, 0xBB, 0x4A, 0xA7, 0xE0, 0xFD, 0x88, 0x32, 0x60, 0xB2, 0x2E, 0xA5, 0xEC, 0xEF, 0x2B, + 0x33, 0x42, 0xBC, 0xD2, 0xB3, 0xED, 0xAA, 0xB5, 0xA2, 0x6D, 0x1F, 0x77, 0x8E, 0xFB, 0x95, 0x0D, + 0x93, 0x52, 0xCB, 0xDC, 0x7A, 0x51, 0x91, 0x31, 0x92, 0x6C, 0x52, 0x0D, 0xC1, 0x60, 0xEA, 0x2F, + 0x70, 0xA0, 0x00, 0x22, 0x27, 0x6E, 0xFF, 0x61, 0xDF, 0xAA, 0xC1, 0x0D, 0x41, 0xBE, 0x5F, 0xA8, + 0xB2, 0x69, 0x96, 0x5D, 0xAF, 0x6B, 0xF6, 0x4A, 0x1D, 0x93, 0xB3, 0x6B, 0x83, 0x37, 0xA0, 0xB1, + 0x8B, 0xAD, 0x92, 0xF4, 0x6C, 0x61, 0x1B, 0x45, 0x2E, 0xA9, 0xB0, 0x37, 0xEA, 0xD0, 0xBF, 0xB2, + 0x19, 0x59, 0x5C, 0xFD, 0x41, 0x37, 0x3A, 0x46, 0x2C, 0x12, 0xFE, 0x54, 0xCC, 0x19, 0xD7, 0x4E, + 0x34, 0x9F, 0x63, 0x04, 0xA3, 0x4C, 0x5C, 0xB4, 0x24, 0xAD, 0xD5, 0x33, 0xAB, 0x13, 0x57, 0xAD, + 0x85, 0x68, 0xA5, 0x2B, 0x26, 0xDD, 0xD0, 0x5A, 0x3A, 0x0F, 0x6C, 0xDF, 0x8C, 0x54, 0x65, 0xBA, + 0x9E, 0x4B, 0xAD, 0xF2, 0x1B, 0xC4, 0x26, 0x0B, 0x5D, 0x87, 0x39, 0x76, 0xE4, 0x79, 0x14, 0xD1, + 0x16, 0x09, 0x40, 0x4D, 0xC5, 0x44, 0xF5, 0x0C, 0xB7, 0x51, 0x74, 0x66, 0x0C, 0x5B, 0xB4, 0x19, + 0x93, 0x0B, 0x40, 0x45, 0xA2, 0x48, 0x72, 0x88, 0x16, 0xFA, 0xA0, 0x54, 0xCC, 0x6A, 0x3B, 0xBB, + 0x90, 0x69, 0x34, 0x53, 0x35, 0x06, 0xF1, 0x64, 0x5D, 0xA8, 0x62, 0x7C, 0xBA, 0x60, 0x32, 0x46, + 0x8D, 0xCE, 0x61, 0xE7, 0xF0, 0x18, 0xFE, 0xA3, 0x68, 0xD0, 0xCB, 0x9D, 0x4B, 0x98, 0xB7, 0xC0, + 0xF3, 0x72, 0xC9, 0xA7, 0x7A, 0x9F, 0xA4, 0x28, 0x8D, 0x55, 0x62, 0x51, 0x3F, 0x92, 0xB2, 0x1B, + 0x26, 0xDD, 0x76, 0x45, 0x61, 0x29, 0x70, 0xE9, 0xF5, 0x1D, 0x51, 0xE1, 0x2D, 0xEB, 0x42, 0x3C, + 0xF3, 0xFF, 0x69, 0xF1, 0xAA, 0xFA, 0x7F, 0xEF, 0xED, 0x92, 0x29, 0xBE, 0x6B, 0x4F, 0x5F, 0xDB, + 0x2E, 0xE1, 0xBE, 0x7D, 0xA3, 0x53, 0x8C, 0x7A, 0x4B, 0xF4, 0x33, 0x20, 0xA1, 0x07, 0x8B, 0xAA, + 0x00, 0x56, 0x57, 0x85, 0x3D, 0x8F, 0x34, 0x66, 0x03, 0x1B, 0xD8, 0x8E, 0xEB, 0xB6, 0x5C, 0x7F, + 0x59, 0xDD, 0x89, 0x94, 0x7B, 0xF2, 0x8A, 0x9F, 0x56, 0xBB, 0xFC, 0xA6, 0xD2, 0x46, 0x90, 0xB9, + 0xFE, 0x27, 0xA4, 0xFD, 0xBE, 0x03, 0xAE, 0x34, 0x34, 0x36, 0x2B, 0x14, 0x1B, 0xF8, 0xE3, 0x76, + 0x13, 0xD5, 0x72, 0x25, 0xDE, 0x09, 0x96, 0x2E, 0xE6, 0xC2, 0xA5, 0x43, 0xCC, 0xE9, 0x06, 0x8B, + 0xAA, 0xB9, 0x1F, 0x3A, 0xFC, 0x1A, 0x4D, 0x80, 0x5D, 0x44, 0x3B, 0xF8, 0x8D, 0x96, 0xDC, 0x95, + 0x0B, 0x13, 0x99, 0xBC, 0x8E, 0x26, 0xCC, 0x74, 0xDF, 0xCE, 0x76, 0x49, 0x9B, 0xF7, 0x0E, 0xC5, + 0xB9, 0x5A, 0xED, 0xD6, 0x15, 0xED, 0x7E, 0x36, 0x32, 0xD4, 0x83, 0xD6, 0xC8, 0xE8, 0x71, 0xD2, + 0x9E, 0x04, 0xF8, 0xAA, 0x86, 0x32, 0x87, 0xE2, 0xDF, 0x01, 0xDF, 0x10, 0xDD, 0x7C, 0xED, 0xCF, + 0x0A, 0x80, 0xF0, 0xA2, 0x76, 0x3F, 0xAC, 0x31, 0x75, 0xF1, 0x94, 0x75, 0xFC, 0x31, 0xD9, 0xEE, + 0xD3, 0xF5, 0x1A, 0xE9, 0xA6, 0xA4, 0x84, 0xAA, 0x5D, 0x35, 0xAE, 0xBE, 0xCA, 0x93, 0x2E, 0xB6, + 0x49, 0xC1, 0xD5, 0x0C, 0xD6, 0xA7, 0x1E, 0x97, 0x67, 0xB7, 0x96, 0xB4, 0x4F, 0x50, 0x99, 0x39, + 0x92, 0x5D, 0xB9, 0x62, 0xEF, 0x53, 0x72, 0xA6, 0xD9, 0x73, 0x6D, 0xE6, 0xC5, 0x90, 0xC4, 0xED, + 0x33, 0x83, 0x19, 0xC6, 0xCC, 0x44, 0xC9, 0x07, 0x78, 0xF0, 0xEF, 0x8D, 0xDE, 0x89, 0xF2, 0x62, + 0x41, 0xC9, 0xE0, 0x32, 0xD1, 0x0A, 0xB7, 0xB5, 0x56, 0x4B, 0x56, 0xE1, 0x02, 0x59, 0xCE, 0x45, + 0x4A, 0xA0, 0xCA, 0xA3, 0xB2, 0x2C, 0xC3, 0xAC, 0xEE, 0xD1, 0x94, 0x3A, 0xBB, 0x33, 0x43, 0xD0, + 0xF6, 0x52, 0x77, 0x45, 0xC0, 0x51, 0x85, 0x5F, 0x1D, 0x77, 0x97, 0x36, 0x0D, 0xBB, 0x27, 0x9D, + 0x8A, 0x29, 0x4D, 0xD7, 0x0F, 0xCB, 0xE3, 0x0A, 0x8D, 0xC1, 0x7E, 0x11, 0x51, 0x4C, 0x24, 0xB6, + 0x2E, 0x95, 0x3B, 0x4F, 0xCC, 0xB9, 0x95, 0x67, 0x6A, 0x95, 0xEE, 0xD2, 0x98, 0x2A, 0x0F, 0xC7, + 0x9C, 0xCD, 0xBB, 0x1D, 0x65, 0xA6, 0x2D, 0xDD, 0x7F, 0x23, 0xF8, 0x12, 0xD6, 0x9B, 0xF4, 0x82, + 0xDC, 0x40, 0x33, 0xB1, 0x3A, 0x8D, 0x66, 0x8A, 0x5C, 0xB7, 0xCE, 0x26, 0x60, 0x29, 0x0E, 0x53, + 0xC7, 0xB2, 0x70, 0xE9, 0x2E, 0x27, 0x5D, 0xF3, 0xE6, 0x58, 0xC4, 0x47, 0xC3, 0x23, 0xE9, 0x06, + 0x96, 0xE1, 0x51, 0x7A, 0xAF, 0xCD, 0x90, 0xDE, 0xC5, 0x22, 0xDF, 0xE7, 0xC2, 0x2F, 0xB2, 0x68, + 0xA6, 0x8B, 0xC2, 0x70, 0xA4, 0xD3, 0xBB, 0x31, 0xF4, 0xEC, 0x6D, 0x2F, 0x43, 0xCB, 0x59, 0x68, + 0x8E, 0x35, 0xD2, 0x5D, 0x7F, 0xE2, 0xE7, 0xCE, 0xB1, 0xF3, 0x7C, 0xDB, 0x1B, 0x22, 0x75, 0xA4, + 0x67, 0x2E, 0x09, 0xE8, 0x8C, 0x2A, 0xFD, 0x49, 0x37, 0xEE, 0xDD, 0x79, 0xF8, 0xE0, 0xC1, 0xC9, + 0x4F, 0xF7, 0xBC, 0x71, 0x38, 0x17, 0xFF, 0xFD, 0x95, 0x5F, 0x41, 0x79, 0xF3, 0xBE, 0x77, 0xD2, + 0x87, 0x86, 0x16, 0x13, 0xE2, 0x78, 0x93, 0x70, 0x78, 0xC4, 0x98, 0xE6, 0x04, 0x39, 0x02, 0x49, + 0x0A, 0x64, 0x13, 0x09, 0x5D, 0x25, 0x5E, 0x3C, 0x24, 0x84, 0x1C, 0x35, 0x46, 0x81, 0x62, 0x08, + 0x1B, 0xC6, 0xDB, 0x05, 0xD6, 0x69, 0xE9, 0x2C, 0xB1, 0x8D, 0xFD, 0xCB, 0xBC, 0x06, 0x4C, 0x29, + 0x91, 0xF5, 0xC4, 0x28, 0x6C, 0x15, 0x31, 0x04, 0x32, 0x46, 0x4E, 0xAF, 0x87, 0x14, 0x8C, 0x49, + 0xE4, 0x13, 0xD6, 0x97, 0xB6, 0xE7, 0xF9, 0xD4, 0x76, 0x80, 0x66, 0x98, 0x26, 0x22, 0xF1, 0x63, + 0x31, 0x9B, 0x3C, 0x12, 0x09, 0xA5, 0x6E, 0xBC, 0xC3, 0x2C, 0x5C, 0x01, 0x65, 0xA5, 0x59, 0x57, + 0xB8, 0x88, 0x0C, 0x9A, 0x99, 0x5F, 0x8F, 0x45, 0x14, 0x3B, 0xA6, 0x2D, 0xC4, 0xDC, 0xA6, 0x42, + 0x20, 0xC6, 0xCE, 0x9F, 0x33, 0x07, 0x5B, 0x20, 0x37, 0x02, 0xD3, 0x76, 0x3B, 0xBA, 0xF1, 0xDB, + 0xEF, 0xCF, 0x1F, 0x37, 0x20, 0x11, 0x75, 0x2E, 0xBB, 0xBD, 0x4E, 0xA7, 0x39, 0x3C, 0xE2, 0x43, + 0xD6, 0xE6, 0xF5, 0x50, 0x37, 0x2E, 0x18, 0xAB, 0xDE, 0x29, 0xB0, 0xEA, 0xF4, 0xFA, 0x9B, 0xB3, + 0x3A, 0xD5, 0x0D, 0xC6, 0x09, 0x98, 0x5C, 0x3E, 0x38, 0x39, 0xDD, 0x9C, 0xD1, 0x03, 0x90, 0xE9, + 0x3D, 0x70, 0x3A, 0x05, 0xED, 0x4E, 0xB6, 0x51, 0xEE, 0x44, 0x37, 0x28, 0x1F, 0x88, 0x8A, 0xCB, + 0xFE, 0xE9, 0x16, 0x7C, 0xEE, 0xEB, 0xA2, 0x24, 0x52, 0x97, 0x8D, 0x8F, 0x74, 0xE3, 0xEC, 0xE7, + 0x67, 0x8D, 0x3E, 0xC8, 0xD8, 0x7B, 0x78, 0xB2, 0x39, 0xEF, 0xBE, 0x6E, 0xFC, 0x42, 0x85, 0x3C, + 0xEE, 0x01, 0xA3, 0xFE, 0x16, 0x42, 0x1E, 0xEB, 0xC6, 0x0B, 0xC6, 0x09, 0xB8, 0x5C, 0x76, 0x1F, + 0x6C, 0x21, 0x12, 0xB8, 0xD7, 0x2F, 0x8C, 0x13, 0xF8, 0x17, 0x75, 0xAF, 0x9A, 0x9C, 0x20, 0x5F, + 0x32, 0xD3, 0x94, 0xC4, 0xE9, 0x6A, 0xF6, 0xC9, 0x9C, 0x2E, 0x0B, 0xE3, 0xBF, 0x23, 0x28, 0x1D, + 0xE4, 0x6A, 0xED, 0x20, 0x16, 0x74, 0xA0, 0x12, 0x3F, 0xA8, 0x17, 0xBF, 0x92, 0x24, 0xC9, 0x65, + 0x39, 0xDD, 0xE8, 0x76, 0x2A, 0x34, 0x60, 0xB4, 0x72, 0x16, 0x64, 0xC4, 0x19, 0x05, 0x74, 0xDA, + 0x49, 0xB0, 0x18, 0xA6, 0xB7, 0x7E, 0x80, 0x8F, 0x1E, 0xEB, 0x52, 0x5C, 0x6F, 0x94, 0x22, 0x14, + 0xD2, 0xA2, 0x4B, 0xDD, 0x38, 0x39, 0xAE, 0xB2, 0xF7, 0x16, 0x70, 0x8C, 0x59, 0x9B, 0xE2, 0xE1, + 0x30, 0x5C, 0x1B, 0x91, 0x94, 0x54, 0x37, 0x9E, 0x24, 0xC7, 0xDB, 0xE0, 0xD2, 0xEA, 0x6D, 0x81, + 0x8B, 0x24, 0x0E, 0x87, 0xA6, 0xD5, 0x13, 0xD0, 0xF4, 0xF4, 0x34, 0x22, 0xBE, 0x26, 0x30, 0x55, + 0xD2, 0x6E, 0x83, 0x0B, 0x2D, 0xE2, 0x01, 0x0A, 0xC9, 0xDA, 0xA8, 0xC4, 0x84, 0x90, 0xD6, 0xC4, + 0xD1, 0xDE, 0x10, 0x49, 0x44, 0xF9, 0x0E, 0xF0, 0x08, 0x11, 0x89, 0x02, 0x76, 0x43, 0xDC, 0xDA, + 0x88, 0xA4, 0xA4, 0x50, 0x0F, 0x93, 0xE3, 0xBD, 0xA1, 0x22, 0x89, 0xF3, 0x3D, 0xE0, 0x32, 0xC7, + 0xA6, 0x83, 0xDC, 0x8F, 0xD8, 0xB6, 0xA1, 0x64, 0xAD, 0x8F, 0x4D, 0x86, 0x1C, 0xF0, 0xE1, 0xDF, + 0xB5, 0x73, 0xF6, 0x7D, 0xED, 0x1E, 0x31, 0xC7, 0xEE, 0x6B, 0x35, 0x8A, 0x1D, 0x75, 0xDF, 0xF2, + 0xDA, 0x4F, 0xE4, 0xDC, 0xB0, 0x43, 0xE8, 0x02, 0x13, 0x3C, 0x61, 0x2B, 0xE5, 0x8D, 0x79, 0xF4, + 0x74, 0xE3, 0x79, 0x80, 0xAE, 0xD8, 0xB3, 0x05, 0xDB, 0x34, 0x3D, 0xEF, 0xB0, 0xA5, 0xFD, 0x0A, + 0x4B, 0xC1, 0x6D, 0x3A, 0xB0, 0xE7, 0x01, 0x86, 0x65, 0xE2, 0x56, 0x5C, 0xEE, 0x43, 0x31, 0x83, + 0x83, 0xED, 0x98, 0x40, 0xC3, 0x7A, 0x81, 0xE7, 0x0E, 0xFA, 0x16, 0x1A, 0x2E, 0xB4, 0x1C, 0xAF, + 0x1D, 0x16, 0x40, 0xA3, 0x1B, 0x8F, 0x3F, 0x3C, 0x59, 0x3B, 0x49, 0xF1, 0xFD, 0xE6, 0x3A, 0x1E, + 0xCE, 0xB3, 0x93, 0x10, 0x50, 0x5F, 0x59, 0x6C, 0xAA, 0x23, 0xA7, 0xEE, 0x82, 0x53, 0xA1, 0x57, + 0x2C, 0x20, 0xDB, 0x9E, 0xD3, 0x25, 0x35, 0xEB, 0xE9, 0x78, 0x73, 0x19, 0x0C, 0x84, 0xF8, 0x38, + 0x41, 0xCE, 0xFA, 0x75, 0x25, 0x26, 0x64, 0x48, 0x69, 0xCF, 0xE1, 0x68, 0x57, 0x70, 0xF1, 0x69, + 0xF7, 0x86, 0x99, 0xD0, 0x7A, 0xDF, 0xC0, 0x81, 0x20, 0x33, 0xDF, 0x5A, 0x7F, 0x3B, 0x42, 0xD0, + 0xE9, 0x06, 0xA0, 0xF6, 0x0A, 0x0E, 0xD6, 0xAE, 0x32, 0x31, 0x83, 0x1B, 0x2E, 0x2F, 0x8F, 0x23, + 0xE2, 0x6F, 0x53, 0x59, 0x2E, 0x22, 0xCF, 0xBB, 0xDA, 0xA6, 0xAC, 0x9C, 0xB9, 0x7E, 0x64, 0x6D, + 0xCE, 0x01, 0x6A, 0xCA, 0x1B, 0xDB, 0x76, 0xCC, 0xCD, 0xAB, 0x12, 0x54, 0x94, 0x17, 0xFE, 0xAC, + 0x26, 0xFD, 0x0D, 0x67, 0x71, 0x6C, 0xAE, 0x9F, 0x20, 0xB0, 0x09, 0x28, 0x9E, 0x9F, 0x69, 0x17, + 0xE7, 0xAF, 0x2F, 0xDE, 0xBC, 0xDB, 0x4D, 0x76, 0x80, 0x39, 0xF7, 0x94, 0x18, 0xA8, 0xB6, 0xFB, + 0xCE, 0x09, 0x20, 0x44, 0x6F, 0x13, 0x9C, 0x7A, 0x1C, 0xA8, 0xA7, 0x17, 0x6F, 0x77, 0x85, 0x52, + 0x6F, 0x7F, 0x30, 0xF5, 0xBE, 0x05, 0x9C, 0x3E, 0xBA, 0x78, 0x81, 0xDD, 0x0D, 0xB0, 0xE2, 0x84, + 0x14, 0x2F, 0xED, 0x25, 0x3D, 0xDA, 0xDB, 0x42, 0x2E, 0x11, 0xE5, 0x3B, 0x58, 0xC6, 0x81, 0x57, + 0x7C, 0x64, 0x42, 0x6F, 0x12, 0x3C, 0x9C, 0x52, 0x37, 0xCE, 0x2F, 0xE7, 0x7E, 0x18, 0x05, 0x35, + 0x0B, 0xAA, 0x1A, 0x91, 0x6D, 0x76, 0x06, 0x53, 0x51, 0x38, 0x22, 0xF1, 0xD6, 0x20, 0xDD, 0xD9, + 0x4F, 0x30, 0xE9, 0x75, 0xFA, 0x5F, 0x15, 0x15, 0xCA, 0xFC, 0x26, 0x81, 0x99, 0x6C, 0x50, 0x77, + 0x26, 0xB4, 0xEE, 0x3C, 0x3F, 0xDB, 0x4D, 0x2A, 0x9B, 0xEC, 0xAD, 0xE0, 0x4C, 0xF6, 0x5A, 0x70, + 0x34, 0x7E, 0x51, 0x34, 0x81, 0x69, 0xC3, 0x45, 0x84, 0x20, 0x84, 0xB5, 0xF3, 0x26, 0x0B, 0x08, + 0x79, 0x53, 0xFD, 0x72, 0x9B, 0xD0, 0x89, 0xC5, 0xC8, 0x46, 0xCE, 0x71, 0x1A, 0x37, 0xF7, 0xBF, + 0x6A, 0xD4, 0x1C, 0x57, 0x4A, 0xBB, 0x4D, 0xD0, 0x50, 0x4D, 0x4C, 0xEC, 0xB8, 0xF4, 0x09, 0xA6, + 0x75, 0x01, 0x91, 0x68, 0x39, 0x26, 0xDA, 0x19, 0xFF, 0xB6, 0x0D, 0x36, 0xBD, 0x6D, 0xB0, 0x91, + 0x25, 0xCA, 0xC2, 0x73, 0x72, 0x43, 0x95, 0xA6, 0xDB, 0x3B, 0xBD, 0x49, 0x78, 0xC6, 0xF3, 0xF5, + 0x73, 0x1A, 0xD0, 0xE8, 0xC6, 0x93, 0xB7, 0xBB, 0xC9, 0x69, 0x74, 0xB2, 0x9A, 0x39, 0x6D, 0xAB, + 0x0C, 0xC6, 0x94, 0xDA, 0x77, 0x2B, 0xB6, 0xDC, 0x00, 0x8D, 0x25, 0x15, 0xFC, 0xC3, 0x8E, 0xD0, + 0x58, 0xD6, 0x47, 0xE3, 0x2B, 0x57, 0x98, 0xE5, 0xB7, 0x80, 0x4F, 0x80, 0x96, 0x1F, 0x27, 0x33, + 0xB4, 0x36, 0x46, 0x82, 0x4E, 0x37, 0xDE, 0xA1, 0xA5, 0xF6, 0xFC, 0xD5, 0xE3, 0x9D, 0x60, 0x15, + 0x4F, 0xBA, 0x1F, 0xBC, 0x12, 0x95, 0xF7, 0x8D, 0x99, 0x8B, 0xBD, 0xF5, 0x83, 0x8A, 0x12, 0xE9, + 0xC6, 0x4B, 0xEC, 0x85, 0xDA, 0x99, 0x1F, 0x88, 0xB7, 0xCD, 0xEC, 0x04, 0x35, 0x36, 0xF3, 0x7E, + 0x20, 0xE3, 0x4A, 0xEF, 0x1B, 0xAF, 0xE9, 0xCC, 0x09, 0x02, 0x3F, 0x58, 0x1B, 0x32, 0x41, 0xA7, + 0x1B, 0x2F, 0x5A, 0xAF, 0xD8, 0xD1, 0x4E, 0xE0, 0x8A, 0x67, 0xDD, 0x0F, 0x62, 0x89, 0xCE, 0xFB, + 0x06, 0x6D, 0x61, 0xBB, 0xCE, 0x7C, 0x6D, 0xC8, 0x18, 0x95, 0x6E, 0xBC, 0x6F, 0x3D, 0x83, 0x7F, + 0x77, 0x02, 0x17, 0x9F, 0x71, 0x3F, 0x60, 0x09, 0x6D, 0xF7, 0x0D, 0x95, 0x65, 0x2E, 0xD7, 0x06, + 0x0A, 0x68, 0x74, 0xE3, 0xE9, 0xD9, 0x07, 0xAD, 0xF1, 0xD4, 0x5F, 0x7A, 0xF4, 0xC6, 0x3F, 0xED, + 0xFC, 0x75, 0x73, 0x27, 0x88, 0xD1, 0xA9, 0xF7, 0x83, 0x17, 0x53, 0x7A, 0xDF, 0x68, 0xB1, 0xBB, + 0x8F, 0xC7, 0x68, 0xFD, 0x74, 0x18, 0x13, 0xD2, 0x7B, 0x5F, 0xE0, 0x48, 0x7B, 0x82, 0x76, 0x93, + 0x10, 0x93, 0x79, 0x77, 0xD1, 0xB4, 0xA7, 0x4A, 0xEE, 0x1B, 0x27, 0x1B, 0x99, 0xF8, 0xA3, 0x85, + 0xC9, 0x26, 0x37, 0x5E, 0x48, 0xB4, 0xBA, 0xF1, 0x0C, 0xBE, 0x68, 0x4F, 0xD9, 0x97, 0x5D, 0xB5, + 0x1C, 0xF2, 0xFC, 0xBB, 0x40, 0x2D, 0xA3, 0xEF, 0x37, 0x01, 0x1C, 0x34, 0x78, 0xFE, 0xC4, 0xDB, + 0xE8, 0x7E, 0xEA, 0x0C, 0xB9, 0x80, 0xEF, 0x1D, 0xFF, 0xBE, 0x5B, 0x00, 0x53, 0x21, 0x76, 0x86, + 0xA1, 0xA4, 0xF7, 0x2E, 0x60, 0x8C, 0x9F, 0x49, 0x60, 0xDB, 0x02, 0xFC, 0xE5, 0x4F, 0x55, 0x48, + 0x89, 0x57, 0xC2, 0xB0, 0xAD, 0x1B, 0x4C, 0x5A, 0x21, 0x71, 0x5C, 0x57, 0x37, 0x9E, 0x63, 0xA2, + 0x5D, 0xD0, 0xC3, 0xE1, 0x11, 0x1F, 0x50, 0x9F, 0x8B, 0xB8, 0xE1, 0x9F, 0xBE, 0x76, 0x0D, 0xCD, + 0x74, 0xE3, 0x82, 0xBE, 0x16, 0x0B, 0x78, 0xD1, 0x6F, 0xEB, 0x33, 0x63, 0x46, 0xC4, 0x5E, 0xE0, + 0x83, 0x50, 0x09, 0x48, 0xE2, 0xED, 0x24, 0xBA, 0x16, 0x1F, 0x49, 0xBF, 0x19, 0xE7, 0x6C, 0xB0, + 0x46, 0xBD, 0xAC, 0x7A, 0x3A, 0x7A, 0x15, 0xD6, 0x2C, 0xBE, 0x58, 0x3B, 0x3C, 0xF2, 0x90, 0xC2, + 0xDC, 0x05, 0x28, 0x0C, 0xF9, 0xFB, 0xD4, 0x0A, 0x58, 0x25, 0x0F, 0x53, 0x30, 0x4B, 0xA4, 0x0F, + 0x26, 0x25, 0x6A, 0xE5, 0x1F, 0x58, 0x12, 0x1B, 0xB6, 0xF5, 0x82, 0x96, 0x3D, 0x7A, 0x24, 0xEA, + 0x21, 0x3D, 0x4C, 0xCC, 0xFF, 0x9F, 0x7F, 0x57, 0xF9, 0x0C, 0x7D, 0xDB, 0x5D, 0x2A, 0x98, 0xAE, + 0x85, 0x81, 0x39, 0xD2, 0x8B, 0x1E, 0xCD, 0x28, 0xD0, 0xFC, 0x48, 0xA5, 0x7A, 0x6E, 0xB0, 0xC2, + 0xD6, 0xC3, 0xD0, 0x0C, 0x9C, 0x39, 0x31, 0x6E, 0x59, 0xBE, 0x19, 0xCD, 0xB0, 0x47, 0xDA, 0xC8, + 0xB2, 0xCE, 0x17, 0x70, 0xF0, 0xD2, 0x09, 0x09, 0x06, 0x2B, 0x34, 0x0E, 0x9E, 0xBE, 0x79, 0x75, + 0xC6, 0x1F, 0x51, 0x79, 0xE9, 0x23, 0x0B, 0x5B, 0x07, 0x87, 0x9A, 0x1D, 0x79, 0xDC, 0xCD, 0x1B, + 0x98, 0x8E, 0xE5, 0x6F, 0x1A, 0x5C, 0xA0, 0x40, 0x1B, 0xA3, 0x10, 0xBF, 0xF0, 0x43, 0xA2, 0x8D, + 0xB4, 0x84, 0xA3, 0xEB, 0x9B, 0xEC, 0xF6, 0xC5, 0xB6, 0x1F, 0x38, 0x13, 0xC7, 0x13, 0x23, 0xB9, + 0xB2, 0xBF, 0x05, 0x2E, 0x0C, 0x4D, 0xA8, 0x7E, 0xD4, 0x0E, 0x06, 0xA7, 0xDD, 0x03, 0xFA, 0x34, + 0x11, 0xC0, 0x00, 0x3F, 0x00, 0x04, 0x18, 0x06, 0x40, 0x80, 0x8F, 0x0C, 0xF1, 0x38, 0x11, 0x76, + 0xDB, 0xCC, 0xE4, 0x54, 0x40, 0x2A, 0x6D, 0xE3, 0x80, 0xE3, 0x74, 0x40, 0x1F, 0xAD, 0xBB, 0x4E, + 0x28, 0xC3, 0xA9, 0xBF, 0x2C, 0xA3, 0x0C, 0xF0, 0xCC, 0x5F, 0xE0, 0x1C, 0x71, 0x42, 0x2D, 0xBC, + 0xB9, 0x72, 0xEA, 0xD8, 0xEB, 0x0F, 0x9A, 0xF1, 0x80, 0xE4, 0xCD, 0x3D, 0x23, 0x8D, 0x04, 0x11, + 0xCE, 0xB2, 0xC5, 0x5E, 0x15, 0xD7, 0x58, 0xAC, 0x52, 0xC6, 0x36, 0x72, 0xC3, 0x1C, 0xE7, 0x68, + 0x6E, 0x21, 0x82, 0xDF, 0xD3, 0xDD, 0x5D, 0x18, 0xD0, 0xC0, 0xEE, 0x21, 0xDF, 0xEA, 0x3D, 0x14, + 0x67, 0xDE, 0x01, 0x5F, 0x82, 0x9B, 0xE9, 0xAC, 0xF2, 0xCF, 0x40, 0x91, 0xFD, 0x3A, 0xD2, 0xBC, + 0x08, 0x42, 0xF8, 0x11, 0x53, 0x41, 0x1B, 0x64, 0xCE, 0x32, 0x6A, 0x17, 0xB2, 0x93, 0x78, 0x4B, + 0x31, 0x9B, 0x93, 0xFD, 0xE8, 0xD8, 0x74, 0xE2, 0x36, 0x7B, 0x67, 0xF2, 0x08, 0x78, 0x1C, 0xC4, + 0xD9, 0xFD, 0x20, 0x7D, 0x15, 0xA5, 0x4C, 0xC4, 0xEC, 0xD0, 0x16, 0x7D, 0xB0, 0x38, 0xBF, 0x10, + 0x27, 0x6E, 0xDF, 0x5E, 0x24, 0x7C, 0x35, 0x69, 0x18, 0x9C, 0x4A, 0x4F, 0x5C, 0xC3, 0x09, 0xE9, + 0x79, 0xBF, 0x55, 0xDE, 0x39, 0x1E, 0x31, 0x73, 0x89, 0xC3, 0xAD, 0x44, 0xF2, 0x8C, 0x05, 0xEE, + 0xDD, 0xCB, 0x72, 0xBB, 0x3D, 0x12, 0x54, 0xA9, 0x26, 0x7C, 0x3C, 0x44, 0x06, 0x44, 0x1E, 0xA8, + 0x2D, 0x9E, 0x02, 0x15, 0x22, 0x39, 0x76, 0xE3, 0x76, 0xC6, 0xF0, 0x89, 0x8C, 0x36, 0x35, 0x91, + 0x63, 0x31, 0x03, 0xB1, 0x7B, 0x20, 0x9A, 0xE9, 0x53, 0x72, 0x5C, 0xBE, 0x47, 0xCC, 0xEB, 0x1B, + 0x58, 0x5C, 0x1D, 0x6D, 0x82, 0xFD, 0xA9, 0x33, 0xA7, 0x3F, 0x88, 0xF1, 0xE9, 0x54, 0x32, 0xC7, + 0x49, 0x86, 0x23, 0x55, 0x2C, 0x27, 0x37, 0xFD, 0x30, 0x7E, 0xF4, 0x3A, 0x81, 0xB8, 0x56, 0x21, + 0x3F, 0x95, 0xCA, 0x26, 0x07, 0x36, 0xF4, 0x5A, 0x46, 0xFA, 0x7B, 0xCE, 0xD4, 0xC9, 0xC0, 0x02, + 0x26, 0x6C, 0x82, 0x55, 0x26, 0xA5, 0x92, 0xC7, 0x37, 0x8A, 0x29, 0x0C, 0xC2, 0xD8, 0x2D, 0xC7, + 0xD4, 0x14, 0x6C, 0x56, 0x38, 0x2C, 0x63, 0x95, 0x2B, 0xFC, 0x0A, 0x86, 0x3C, 0x10, 0x1B, 0xBC, + 0xAE, 0x3D, 0x61, 0x35, 0x8A, 0x32, 0x17, 0x31, 0x96, 0xFD, 0xFD, 0x96, 0x2C, 0xFC, 0x75, 0x1C, + 0x76, 0x49, 0x0A, 0x94, 0xFD, 0x80, 0xFA, 0x7F, 0x6C, 0x69, 0x1A, 0x22, 0xA9, 0xA3, 0x89, 0x07, + 0xFB, 0xE3, 0xF8, 0x48, 0xE1, 0x30, 0x21, 0xF7, 0x49, 0x91, 0x32, 0xC8, 0x89, 0x2A, 0x87, 0x08, + 0xC8, 0xDD, 0xD5, 0xE4, 0x47, 0xF5, 0xC7, 0x90, 0x42, 0x3F, 0x67, 0xF8, 0xB0, 0x8B, 0x32, 0x09, + 0x13, 0xFE, 0x1B, 0xBF, 0xCD, 0xA9, 0xE5, 0x7B, 0x58, 0xCD, 0x5D, 0x0E, 0x12, 0x15, 0x4F, 0x5E, + 0xC2, 0xF3, 0x4C, 0xA3, 0xF1, 0xCC, 0x21, 0x0A, 0x86, 0x07, 0x90, 0xBE, 0x55, 0xBC, 0x44, 0x63, + 0x97, 0x12, 0x04, 0x98, 0x44, 0x81, 0x27, 0x47, 0x21, 0xCF, 0x64, 0x7F, 0x47, 0x38, 0xB8, 0x02, + 0x46, 0x9F, 0xEE, 0x7E, 0x89, 0xEB, 0xC2, 0xF5, 0x11, 0x7B, 0x34, 0xC1, 0x77, 0x1F, 0x41, 0xE5, + 0x18, 0xDD, 0xFD, 0xC2, 0xA0, 0xBE, 0xBE, 0x07, 0x53, 0xC2, 0x17, 0x36, 0xF1, 0xF5, 0x27, 0xCE, + 0xC2, 0xA6, 0x2F, 0x9A, 0x6D, 0x30, 0x16, 0x31, 0x6E, 0x6D, 0x32, 0xC5, 0x5E, 0x23, 0xC0, 0xE1, + 0x1C, 0xD8, 0xE3, 0x34, 0x01, 0xC6, 0x33, 0xFA, 0x2E, 0x86, 0x12, 0x35, 0x69, 0x7C, 0x0A, 0x30, + 0xD0, 0x81, 0x00, 0xC4, 0xD7, 0xEE, 0x7E, 0x61, 0x2C, 0xAE, 0x35, 0x1B, 0xB2, 0x40, 0x38, 0xC5, + 0xD6, 0x21, 0xD4, 0x2B, 0x44, 0xE8, 0x13, 0xB8, 0x77, 0xBF, 0xC4, 0xAC, 0xDA, 0xFC, 0xA7, 0xEB, + 0x4F, 0x89, 0x87, 0x24, 0x45, 0x24, 0xAE, 0x7D, 0xEC, 0x44, 0x9B, 0xF1, 0xBA, 0x60, 0x28, 0xF8, + 0xC1, 0x63, 0xD7, 0x6D, 0x1C, 0xF0, 0x07, 0x95, 0x45, 0x6E, 0x6F, 0x43, 0xB3, 0x7A, 0x8E, 0x40, + 0x6C, 0xB9, 0x28, 0xB0, 0x7C, 0xE5, 0x7B, 0xA6, 0xEB, 0x98, 0x9F, 0x69, 0x42, 0x6F, 0x66, 0x05, + 0xE7, 0x19, 0xC2, 0x6D, 0xF3, 0x17, 0xCF, 0xBC, 0xF6, 0x2D, 0x9C, 0x73, 0xD3, 0x26, 0x15, 0xE3, + 0xE8, 0x08, 0xAC, 0x8C, 0xAC, 0x38, 0x95, 0x71, 0x8C, 0xE8, 0x1B, 0x0A, 0xB8, 0x99, 0x32, 0x16, + 0xE6, 0xCA, 0x08, 0x5D, 0xB8, 0xCD, 0xD2, 0x2A, 0x1F, 0xAB, 0x9C, 0xBA, 0x2D, 0x47, 0x4F, 0x4B, + 0x6C, 0xF1, 0x57, 0xE8, 0x7B, 0x8D, 0xE6, 0xAD, 0xC4, 0x0C, 0xAB, 0x3C, 0xE8, 0x04, 0x12, 0x83, + 0x8C, 0x89, 0x8A, 0xCC, 0x94, 0x5D, 0x0D, 0x1C, 0xA4, 0x99, 0xA4, 0xC0, 0x66, 0xF4, 0x23, 0x55, + 0x42, 0x56, 0x06, 0xD9, 0xBC, 0x7F, 0x30, 0x97, 0xF9, 0xF3, 0x90, 0x97, 0x4E, 0x29, 0x23, 0x35, + 0x25, 0x73, 0x71, 0xFF, 0xA3, 0xAF, 0xE8, 0x97, 0xDB, 0x17, 0xE8, 0xC9, 0xCF, 0x5D, 0x4C, 0x0F, + 0x9F, 0x5C, 0xFD, 0x0C, 0x25, 0x9F, 0x37, 0x2E, 0x4C, 0x96, 0x94, 0xE0, 0x2C, 0x69, 0x1A, 0x2B, + 0x29, 0xD3, 0x06, 0x53, 0xE2, 0xC1, 0x9A, 0x7E, 0x9E, 0x6F, 0xCA, 0x38, 0x24, 0xEB, 0x83, 0x0C, + 0x29, 0xE5, 0x5A, 0x4D, 0x9B, 0x59, 0x15, 0x48, 0xF4, 0x72, 0xAE, 0x2B, 0xA3, 0x97, 0x16, 0x02, + 0x12, 0x35, 0x73, 0xE4, 0x6A, 0x62, 0xB9, 0x25, 0x3E, 0x90, 0x8C, 0x1D, 0x12, 0x7F, 0xCE, 0x57, + 0x26, 0x39, 0x27, 0x5F, 0x3A, 0x9E, 0xE5, 0x2F, 0xDB, 0xF4, 0x7C, 0x43, 0x94, 0x56, 0x59, 0xD1, + 0xB6, 0xE3, 0x81, 0x01, 0x5F, 0xFC, 0xFA, 0xEA, 0x25, 0x4D, 0x39, 0xF2, 0x0A, 0xE7, 0x20, 0xDB, + 0x17, 0xB1, 0x77, 0x02, 0x2B, 0x67, 0xA0, 0xB0, 0xB5, 0xA1, 0xD5, 0xE6, 0xA9, 0x26, 0x69, 0x47, + 0x69, 0x24, 0xD0, 0xC3, 0x4F, 0x7C, 0x4E, 0x5A, 0x78, 0x32, 0x00, 0x37, 0x2B, 0x65, 0xF1, 0xE7, + 0x79, 0x51, 0x20, 0x0E, 0x1F, 0x13, 0x02, 0xEE, 0xAA, 0x71, 0x47, 0x0E, 0x69, 0x8E, 0x11, 0xAB, + 0xC3, 0x5B, 0x9A, 0x0C, 0x7E, 0x41, 0xC8, 0xA7, 0x66, 0x12, 0x31, 0x96, 0x15, 0x5E, 0xCA, 0x93, + 0x68, 0x0E, 0x71, 0x89, 0x1F, 0x7D, 0x34, 0xC7, 0x90, 0x1A, 0x9F, 0x82, 0xE7, 0xB7, 0x3D, 0xD0, + 0xA0, 0x79, 0x5D, 0xA6, 0x0E, 0x37, 0x57, 0x0A, 0x64, 0x5D, 0x21, 0x58, 0x12, 0x52, 0x73, 0xCB, + 0xD8, 0x47, 0xCD, 0x4E, 0xF6, 0xDE, 0x73, 0x2F, 0x6E, 0x6D, 0x8B, 0x0C, 0x3B, 0x5A, 0x35, 0x2D, + 0xEF, 0x6E, 0x32, 0x0C, 0xD2, 0xF4, 0xB2, 0x22, 0x6C, 0xAE, 0x81, 0x91, 0xFC, 0x22, 0x1E, 0x10, + 0xCB, 0x2E, 0x07, 0x44, 0x81, 0xEC, 0xD9, 0xDE, 0x2F, 0xD7, 0x2C, 0xE4, 0x20, 0x17, 0x39, 0x4C, + 0xA3, 0x2F, 0x2A, 0x98, 0xD2, 0xF2, 0x2C, 0x9C, 0xA0, 0x4E, 0x99, 0x50, 0xE6, 0xBF, 0xD2, 0x7A, + 0xC1, 0x67, 0x88, 0xA5, 0xCD, 0xF7, 0xA8, 0xD9, 0xDA, 0x70, 0x16, 0x81, 0x95, 0x66, 0xB1, 0x4F, + 0xF2, 0xDF, 0x68, 0xC3, 0x96, 0x04, 0x0F, 0x34, 0x70, 0x65, 0x41, 0x0D, 0xA7, 0xA5, 0x4C, 0x20, + 0xBA, 0xBD, 0x0A, 0x02, 0xE9, 0xAE, 0x27, 0x89, 0x56, 0xEA, 0x22, 0x4B, 0xD3, 0x5F, 0xFE, 0x3E, + 0x1D, 0xC6, 0x02, 0xB8, 0xAE, 0x6A, 0xAE, 0xC0, 0x09, 0xC6, 0x35, 0x13, 0xB7, 0xA1, 0x44, 0xA2, + 0xAD, 0x92, 0x9C, 0xA6, 0xA0, 0x2D, 0x5E, 0x6D, 0x89, 0x73, 0xDE, 0x54, 0xD4, 0x0A, 0xAF, 0xB6, + 0xC1, 0xD7, 0x92, 0x83, 0xC4, 0xF7, 0x3F, 0xA6, 0x26, 0xC4, 0xE5, 0xF6, 0xC6, 0xB2, 0xBD, 0xE3, + 0xE5, 0x40, 0x05, 0x85, 0x7C, 0x9B, 0x26, 0x37, 0x17, 0xAE, 0x69, 0x2E, 0x2C, 0xCC, 0x45, 0x09, + 0xD2, 0x0E, 0xB4, 0x7A, 0x6D, 0x92, 0xF8, 0xFF, 0x87, 0x27, 0xA9, 0x66, 0xCB, 0x71, 0xA9, 0x9C, + 0xA2, 0xF7, 0x97, 0xD4, 0x2B, 0x27, 0xC8, 0x3C, 0xCB, 0xC1, 0xD5, 0x5A, 0x8E, 0xEB, 0xA9, 0x15, + 0xAF, 0x1D, 0x28, 0x41, 0xAA, 0x96, 0x7A, 0x85, 0x11, 0xAB, 0x92, 0xEC, 0x75, 0xB3, 0xFF, 0xDD, + 0x42, 0xF2, 0x66, 0x89, 0x44, 0x58, 0xBE, 0x51, 0x5C, 0x59, 0x3D, 0xF9, 0x30, 0x49, 0xC9, 0x64, + 0x8D, 0x52, 0x49, 0x9A, 0x8C, 0x94, 0xA8, 0x13, 0x39, 0x4A, 0xA9, 0xE3, 0x41, 0xBC, 0xEC, 0x26, + 0x5F, 0x6B, 0x19, 0x2B, 0x19, 0x9D, 0x06, 0x4E, 0xCA, 0x80, 0x77, 0xFC, 0x86, 0x76, 0x3F, 0xBF, + 0x26, 0xE6, 0xBD, 0x17, 0x57, 0x36, 0xD7, 0x71, 0xC9, 0x03, 0x12, 0x95, 0x32, 0x63, 0x92, 0x00, + 0xE1, 0xF4, 0x45, 0x62, 0x56, 0x8A, 0x82, 0x5C, 0x1C, 0x90, 0x86, 0xFE, 0xD6, 0xC5, 0x74, 0xBD, + 0x22, 0x9E, 0xC6, 0x39, 0xFB, 0xF9, 0x99, 0xE6, 0x07, 0x1A, 0x7F, 0xC1, 0x5D, 0x90, 0xBC, 0x5B, + 0x44, 0x13, 0x6F, 0x7F, 0x62, 0xAB, 0x42, 0x9A, 0x83, 0xC8, 0xD4, 0x09, 0xA1, 0x49, 0xA6, 0x4F, + 0xDE, 0xE2, 0xDB, 0x7A, 0xF2, 0x82, 0xA7, 0x4A, 0xF5, 0x78, 0x57, 0xFC, 0x53, 0xA2, 0x48, 0xCE, + 0x9C, 0x9C, 0x26, 0xB5, 0xE5, 0x6D, 0xA1, 0xE3, 0x4A, 0x22, 0x2A, 0x5B, 0x87, 0xAE, 0x61, 0xC2, + 0xE4, 0xF4, 0x37, 0x6B, 0x45, 0xB5, 0x02, 0x95, 0x86, 0x4C, 0xC8, 0x52, 0x5B, 0xA6, 0xBA, 0xAE, + 0x58, 0x53, 0xB5, 0xD8, 0x2F, 0x41, 0x94, 0xEE, 0x79, 0x29, 0xB3, 0x7C, 0x31, 0x2A, 0xDC, 0xE2, + 0xBC, 0xB0, 0xF2, 0xCF, 0xF0, 0x28, 0xDE, 0x59, 0xE5, 0xDF, 0xF8, 0xAB, 0x8B, 0x86, 0x47, 0xFC, + 0x7F, 0x22, 0xF6, 0x5F, 0x04, 0x9C, 0x39, 0x76, 0x5C, 0x6C, 0x00, 0x00 +}; + + +//File: index_ov3660.html.gz, Size: 4408 +#define index_ov3660_html_gz_len 4408 +const uint8_t index_ov3660_html_gz[] = { + 0x1F, 0x8B, 0x08, 0x08, 0x28, 0x5C, 0xAE, 0x5C, 0x00, 0x03, 0x69, 0x6E, 0x64, 0x65, 0x78, 0x5F, + 0x6F, 0x76, 0x33, 0x36, 0x36, 0x30, 0x2E, 0x68, 0x74, 0x6D, 0x6C, 0x00, 0xE5, 0x5D, 0xEB, 0x92, + 0xD3, 0xC6, 0x12, 0xFE, 0xCF, 0x53, 0x08, 0x41, 0x58, 0x6F, 0x65, 0xED, 0xF5, 0x6D, 0xCD, 0xE2, + 0xD8, 0xE6, 0xC0, 0xB2, 0x84, 0x54, 0x01, 0x49, 0x20, 0x21, 0xA9, 0x4A, 0xA5, 0x60, 0x2C, 0x8D, + 0xED, 0x09, 0xB2, 0xE4, 0x48, 0x23, 0x7B, 0x37, 0xD4, 0x3E, 0xC7, 0x79, 0xA0, 0xF3, 0x62, 0xA7, + 0xE7, 0x22, 0x69, 0x24, 0x8F, 0x2E, 0xB6, 0x59, 0x9B, 0xC3, 0x31, 0x55, 0x20, 0x5B, 0xD3, 0x3D, + 0xDD, 0xFD, 0xF5, 0x6D, 0x46, 0x17, 0x06, 0x77, 0x6D, 0xCF, 0xA2, 0xD7, 0x0B, 0x6C, 0xCC, 0xE8, + 0xDC, 0x19, 0xDD, 0x19, 0x88, 0x7F, 0x0C, 0xF8, 0x0C, 0x66, 0x18, 0xD9, 0xE2, 0x90, 0x7F, 0x9D, + 0x63, 0x8A, 0x0C, 0x6B, 0x86, 0xFC, 0x00, 0xD3, 0xA1, 0x19, 0xD2, 0x49, 0xFD, 0xDC, 0xCC, 0x9E, + 0x76, 0xD1, 0x1C, 0x0F, 0xCD, 0x25, 0xC1, 0xAB, 0x85, 0xE7, 0x53, 0xD3, 0xB0, 0x3C, 0x97, 0x62, + 0x17, 0x86, 0xAF, 0x88, 0x4D, 0x67, 0x43, 0x1B, 0x2F, 0x89, 0x85, 0xEB, 0xFC, 0xCB, 0x09, 0x71, + 0x09, 0x25, 0xC8, 0xA9, 0x07, 0x16, 0x72, 0xF0, 0xB0, 0xA5, 0xF2, 0xA2, 0x84, 0x3A, 0x78, 0x74, + 0xF9, 0xF6, 0xA7, 0x4E, 0xDB, 0xF8, 0xF1, 0x5D, 0xA7, 0xD7, 0x6B, 0x0E, 0x4E, 0xC5, 0x6F, 0xC9, + 0x98, 0x80, 0x5E, 0xAB, 0xDF, 0xD9, 0x67, 0xEC, 0xD9, 0xD7, 0xC6, 0xA7, 0xD4, 0x4F, 0xEC, 0x33, + 0x01, 0x21, 0xEA, 0x13, 0x34, 0x27, 0xCE, 0x75, 0xDF, 0x78, 0xE2, 0xC3, 0x9C, 0x27, 0x2F, 0xB0, + 0xB3, 0xC4, 0x94, 0x58, 0xE8, 0x24, 0x40, 0x6E, 0x50, 0x0F, 0xB0, 0x4F, 0x26, 0xDF, 0xAD, 0x11, + 0x8E, 0x91, 0xF5, 0x71, 0xEA, 0x7B, 0xA1, 0x6B, 0xF7, 0x8D, 0x7B, 0xAD, 0x73, 0xF6, 0x67, 0x7D, + 0x90, 0xE5, 0x39, 0x9E, 0x0F, 0xE7, 0x2F, 0x9F, 0xB3, 0x3F, 0xEB, 0xE7, 0xF9, 0xEC, 0x01, 0xF9, + 0x07, 0xF7, 0x8D, 0x56, 0x6F, 0x71, 0x95, 0x3A, 0x7F, 0x73, 0x27, 0xF5, 0x75, 0xD6, 0xCE, 0x93, + 0x5E, 0xD2, 0x9F, 0x17, 0xD3, 0x07, 0xD8, 0xA2, 0xC4, 0x73, 0x1B, 0x73, 0x44, 0x5C, 0x0D, 0x27, + 0x9B, 0x04, 0x0B, 0x07, 0x81, 0x0D, 0x26, 0x0E, 0x2E, 0xE4, 0x73, 0x6F, 0x8E, 0xDD, 0xF0, 0xA4, + 0x84, 0x1B, 0x63, 0x52, 0xB7, 0x89, 0x2F, 0x46, 0xF5, 0x99, 0x1D, 0xC2, 0xB9, 0x5B, 0xCA, 0xB6, + 0x48, 0x2E, 0xD7, 0x73, 0xB1, 0xC6, 0x80, 0x6C, 0xA2, 0x95, 0x8F, 0x16, 0x6C, 0x00, 0xFB, 0x77, + 0x7D, 0xC8, 0x9C, 0xB8, 0xC2, 0xA9, 0xFA, 0x46, 0xA7, 0xDB, 0x5C, 0x5C, 0x95, 0x40, 0xD9, 0xE9, + 0xB1, 0x3F, 0xEB, 0x83, 0x16, 0xC8, 0xB6, 0x89, 0x3B, 0xED, 0x1B, 0xE7, 0x5A, 0x16, 0x9E, 0x6F, + 0x63, 0xBF, 0xEE, 0x23, 0x9B, 0x84, 0x41, 0xDF, 0xE8, 0xEA, 0xC6, 0xCC, 0x91, 0x3F, 0x05, 0x59, + 0xA8, 0x07, 0xC2, 0xD6, 0x5B, 0x5A, 0x49, 0xE4, 0x10, 0x9F, 0x4C, 0x67, 0x14, 0x20, 0x5D, 0x1B, + 0x93, 0x35, 0x9A, 0x0C, 0xA1, 0x32, 0x3C, 0x0B, 0xED, 0xA6, 0xB7, 0x1A, 0x72, 0xC8, 0xD4, 0xAD, + 0x13, 0x8A, 0xE7, 0xA0, 0x4E, 0x40, 0x7D, 0x4C, 0xAD, 0x59, 0x91, 0x28, 0x13, 0x32, 0x0D, 0x7D, + 0xAC, 0x11, 0x24, 0xB6, 0x5B, 0x81, 0xC2, 0x70, 0x72, 0xFD, 0x54, 0x7D, 0x85, 0xC7, 0x1F, 0x09, + 0xAD, 0x4B, 0x9B, 0x8C, 0xF1, 0xC4, 0xF3, 0xB1, 0x76, 0x64, 0x34, 0xC2, 0xF1, 0xAC, 0x8F, 0xF5, + 0x80, 0x22, 0x9F, 0x56, 0x61, 0x88, 0x26, 0x14, 0xFB, 0xE5, 0xFC, 0x30, 0xF3, 0x8A, 0x72, 0x6E, + 0xF9, 0xD3, 0xCA, 0x01, 0xC4, 0x75, 0x88, 0x8B, 0xAB, 0x8B, 0x97, 0x37, 0x6F, 0x9A, 0x9D, 0x18, + 0x55, 0x01, 0x18, 0x32, 0x9F, 0x16, 0x79, 0x09, 0xD7, 0x75, 0x7D, 0x32, 0x19, 0x37, 0xAD, 0x66, + 0xF3, 0x9B, 0xF5, 0x93, 0x33, 0x2C, 0xDC, 0x14, 0x85, 0xD4, 0xDB, 0x3D, 0x22, 0xD6, 0xC2, 0x2A, + 0xA3, 0xC7, 0xBF, 0xE6, 0xD8, 0x26, 0xC8, 0xA8, 0x29, 0xE1, 0x7C, 0xDE, 0x04, 0x9F, 0x3A, 0x36, + 0x90, 0x6B, 0x1B, 0x35, 0xCF, 0x27, 0x10, 0x08, 0x88, 0xA7, 0x1B, 0x07, 0x7E, 0x81, 0xC2, 0xB1, + 0xC0, 0xC7, 0x1A, 0x95, 0x0B, 0x62, 0x46, 0xB5, 0x88, 0x3E, 0x6C, 0xD8, 0xA7, 0x42, 0xCA, 0x61, + 0x9F, 0xD2, 0x00, 0xD2, 0xE8, 0xC8, 0xD9, 0x17, 0xE1, 0xA5, 0x4A, 0x98, 0x87, 0x19, 0xFB, 0xCC, + 0xD1, 0x55, 0xBD, 0x10, 0xBB, 0x68, 0x50, 0x84, 0x21, 0x94, 0x59, 0xAB, 0x06, 0x43, 0x97, 0x33, + 0xA3, 0x6E, 0xB0, 0x2C, 0x79, 0xAC, 0xA7, 0x91, 0x4C, 0xF5, 0x90, 0xB3, 0x8F, 0xEA, 0x14, 0x1B, + 0xA8, 0xAB, 0x57, 0x35, 0xC9, 0x1D, 0xE2, 0x8F, 0xCE, 0x87, 0x84, 0x26, 0xB9, 0x59, 0x84, 0x7D, + 0xAA, 0x67, 0x92, 0x84, 0x59, 0x69, 0x36, 0xD1, 0x30, 0xCE, 0xCF, 0x28, 0x6B, 0x7C, 0xF3, 0xA2, + 0x5B, 0xC3, 0xB5, 0x58, 0x84, 0xAA, 0xD9, 0x45, 0xC3, 0xB8, 0x48, 0x86, 0xD2, 0x2C, 0xC3, 0x3E, + 0x37, 0x15, 0xFA, 0x8D, 0x7B, 0xE3, 0x90, 0x52, 0xCF, 0x0D, 0x76, 0x2A, 0x51, 0x79, 0x71, 0xF6, + 0x57, 0x18, 0x50, 0x32, 0xB9, 0xAE, 0xCB, 0x90, 0x86, 0x38, 0x5B, 0x20, 0x68, 0x21, 0xC7, 0x98, + 0xAE, 0x30, 0x2E, 0x6E, 0x37, 0x5C, 0xB4, 0x84, 0xBC, 0x33, 0x9D, 0x3A, 0x3A, 0xDF, 0xB3, 0x42, + 0x3F, 0x60, 0x7D, 0xDB, 0xC2, 0x23, 0xC0, 0xD8, 0x5F, 0x9F, 0x38, 0x1D, 0x83, 0x15, 0x27, 0xAA, + 0x5B, 0x63, 0xCD, 0x5C, 0x5E, 0x48, 0x99, 0x8D, 0xB5, 0x48, 0x78, 0xA0, 0x0E, 0xA1, 0xD7, 0xDA, + 0x73, 0x32, 0x12, 0x35, 0x67, 0xA2, 0x10, 0x2C, 0x2C, 0x0B, 0x69, 0xB9, 0xFA, 0xD6, 0x0C, 0x5B, + 0x1F, 0xB1, 0xFD, 0x6D, 0x69, 0x1B, 0x56, 0xD6, 0x1E, 0x36, 0x88, 0xBB, 0x08, 0x69, 0x9D, 0xB5, + 0x53, 0x8B, 0x5B, 0xC1, 0x9C, 0x3B, 0x64, 0xA4, 0x62, 0xBB, 0x5D, 0xD4, 0x54, 0x9C, 0x2D, 0xAE, + 0x8A, 0x8D, 0xA0, 0x0A, 0x3B, 0x72, 0xD0, 0x18, 0x3B, 0x45, 0x22, 0xCB, 0x60, 0xC8, 0x49, 0xBB, + 0x32, 0x57, 0xE5, 0xF7, 0x6E, 0x5C, 0xB2, 0xA4, 0x78, 0x75, 0x1F, 0x7E, 0x53, 0xD9, 0x8E, 0xFC, + 0xF8, 0x24, 0xF5, 0x53, 0x80, 0x1D, 0x08, 0xB0, 0xBC, 0xD6, 0x1B, 0xC6, 0xAC, 0x40, 0x86, 0xC2, + 0x09, 0x7C, 0xE4, 0x4E, 0x31, 0xE4, 0x82, 0xAB, 0x93, 0xE8, 0xB0, 0x78, 0x61, 0x50, 0x49, 0x7D, + 0x96, 0xAA, 0xCF, 0x8A, 0x17, 0x22, 0x22, 0x21, 0x6C, 0xD1, 0x8C, 0x28, 0xB0, 0x16, 0xCE, 0xDF, + 0xD2, 0x3A, 0x85, 0xE8, 0x47, 0xB4, 0x01, 0x93, 0x76, 0x29, 0x6D, 0x7F, 0x5F, 0x9A, 0x11, 0xA2, + 0x95, 0xDE, 0x64, 0x52, 0xB6, 0x56, 0x9C, 0x4C, 0x3A, 0xCD, 0x4E, 0xB7, 0xB4, 0x61, 0xD2, 0x6A, + 0x99, 0x59, 0x2F, 0x6A, 0x32, 0x46, 0x9C, 0x4D, 0xCA, 0x21, 0xE8, 0xCF, 0xBC, 0x25, 0xF6, 0x35, + 0x40, 0x64, 0xC4, 0xED, 0x3E, 0xEA, 0xDA, 0x15, 0xB8, 0x21, 0xC8, 0xF7, 0x4B, 0x5D, 0x36, 0x4D, + 0xB3, 0x6B, 0xB7, 0xAC, 0x76, 0xA1, 0x63, 0x0A, 0x76, 0x0D, 0xF0, 0x06, 0x34, 0x76, 0xB0, 0x5D, + 0x90, 0x9E, 0x6D, 0x3C, 0x41, 0xA1, 0x43, 0x4B, 0xEC, 0x8D, 0x9A, 0xEC, 0x4F, 0xD1, 0x8C, 0x3C, + 0xAE, 0xFE, 0x60, 0x1B, 0x1D, 0x43, 0x1E, 0x09, 0x7F, 0x6A, 0xE6, 0x8C, 0x6A, 0x27, 0x5A, 0x2C, + 0x30, 0x82, 0x51, 0x16, 0xCE, 0x5B, 0x92, 0x56, 0xEA, 0x99, 0xF5, 0x89, 0xAB, 0xD2, 0x42, 0xB4, + 0xD4, 0x15, 0xE3, 0x6E, 0x68, 0x23, 0x9D, 0xFB, 0x13, 0xCF, 0x0A, 0x75, 0x65, 0xBA, 0x9A, 0x4B, + 0xAD, 0xF3, 0xEB, 0x47, 0x26, 0x0B, 0x1C, 0xC2, 0x1D, 0x3B, 0x74, 0x5D, 0x86, 0x68, 0x9D, 0xFA, + 0xA0, 0xA6, 0x66, 0xA2, 0x6A, 0x86, 0xDB, 0x2A, 0x3A, 0x53, 0x86, 0xCD, 0xDB, 0x8C, 0xC9, 0x04, + 0xA0, 0x26, 0x51, 0xC4, 0x39, 0xC4, 0x08, 0x3C, 0x50, 0x2A, 0x62, 0xB5, 0x9B, 0x5D, 0xE8, 0x2C, + 0x9C, 0xEB, 0x1A, 0x83, 0x68, 0xB2, 0x16, 0x54, 0x31, 0x31, 0x9D, 0x3F, 0x1D, 0xA3, 0x5A, 0xF3, + 0xA4, 0x79, 0xD2, 0x81, 0xBF, 0x34, 0x0D, 0x7A, 0xB1, 0x73, 0x49, 0xF3, 0xE6, 0x78, 0x5E, 0x26, + 0xF9, 0x94, 0xEF, 0x93, 0xE4, 0xA5, 0xB1, 0x52, 0x2C, 0xAA, 0x47, 0x52, 0x7A, 0xC3, 0xA4, 0xD5, + 0x28, 0x29, 0x2C, 0x39, 0x2E, 0xBD, 0xB9, 0x23, 0x6A, 0xBC, 0x65, 0x53, 0x88, 0xE7, 0xDE, 0x3F, + 0x75, 0x51, 0x55, 0xFF, 0xEF, 0xBD, 0x5D, 0x31, 0xC5, 0x57, 0xED, 0xE9, 0x1B, 0xDB, 0x25, 0x38, + 0xB4, 0x6F, 0x34, 0xF3, 0x51, 0xAF, 0xCB, 0x7E, 0x06, 0x24, 0x74, 0x61, 0x51, 0xE5, 0xC3, 0xEA, + 0x2A, 0xB7, 0xE7, 0x51, 0xC6, 0x6C, 0x61, 0x83, 0x09, 0x71, 0x9C, 0xBA, 0xE3, 0xAD, 0xCA, 0x3B, + 0x91, 0x62, 0x4F, 0x5E, 0xF3, 0xD3, 0x72, 0x97, 0xDF, 0x56, 0xDA, 0x10, 0x32, 0xD7, 0xFF, 0x84, + 0xB4, 0x5F, 0x77, 0xC0, 0x15, 0x86, 0xC6, 0x76, 0x85, 0x62, 0x0B, 0x7F, 0xDC, 0x6D, 0xA2, 0x4A, + 0xAE, 0x24, 0x3A, 0xC1, 0xC2, 0xC5, 0x5C, 0xB0, 0x22, 0xD4, 0x9A, 0x6D, 0xB1, 0xA8, 0x5A, 0x78, + 0x01, 0x11, 0xD7, 0x68, 0x7C, 0xEC, 0x20, 0xD6, 0xC1, 0x6F, 0xB5, 0xE4, 0x2E, 0x5D, 0x98, 0xA8, + 0xE4, 0x55, 0x34, 0xE1, 0xA6, 0xFB, 0x72, 0xB6, 0x4B, 0x1A, 0xA2, 0x77, 0xC8, 0xCF, 0xD5, 0x7A, + 0xB7, 0x2E, 0x69, 0xF7, 0xD3, 0x91, 0xA1, 0x1F, 0xB4, 0x41, 0x46, 0x8F, 0x92, 0xF6, 0xD4, 0xC7, + 0xD7, 0x15, 0x94, 0x39, 0x91, 0xFF, 0xF6, 0xC5, 0x86, 0xE8, 0xF6, 0x6B, 0x7F, 0x5E, 0x00, 0xA4, + 0x17, 0x35, 0xBA, 0x41, 0x85, 0xA9, 0xF3, 0xA7, 0xAC, 0xE2, 0x8F, 0xF1, 0x76, 0x9F, 0x69, 0x56, + 0x48, 0x37, 0x05, 0x25, 0x54, 0xEF, 0xAA, 0x51, 0xF5, 0xD5, 0x9E, 0x74, 0xF0, 0x84, 0xE6, 0x5C, + 0xCD, 0xE0, 0x7D, 0x6A, 0xA7, 0x38, 0xBB, 0xD5, 0x95, 0x7D, 0x82, 0xD2, 0xCC, 0x11, 0xEF, 0xCA, + 0xE5, 0x7B, 0x9F, 0x96, 0x33, 0xCB, 0x9E, 0x1B, 0x33, 0xCF, 0x87, 0x24, 0x6A, 0x9F, 0x39, 0xCC, + 0x30, 0x66, 0x2E, 0x4B, 0x3E, 0xC0, 0x83, 0x7F, 0xAF, 0xB5, 0x7B, 0xDA, 0x8B, 0x05, 0x05, 0x83, + 0x8B, 0x44, 0xCB, 0xDD, 0xD6, 0x5A, 0x2F, 0x59, 0xB9, 0x0B, 0x64, 0x35, 0x17, 0x69, 0x81, 0x2A, + 0x8E, 0xCA, 0xA2, 0x0C, 0xB3, 0xBE, 0x47, 0x53, 0xE8, 0xEC, 0x64, 0x8E, 0xA0, 0xED, 0x65, 0xEE, + 0x8A, 0x80, 0xA3, 0x0E, 0xBF, 0x2A, 0xEE, 0xAE, 0x6C, 0x1A, 0xB6, 0x7A, 0xCD, 0x92, 0x29, 0x2D, + 0xC7, 0x0B, 0x8A, 0xE3, 0x0A, 0x8D, 0xC1, 0x7E, 0x21, 0xD5, 0x4C, 0x24, 0xB7, 0x2E, 0xB5, 0x3B, + 0x4F, 0xDC, 0xB9, 0xB5, 0x67, 0x2A, 0x95, 0xEE, 0xC2, 0x98, 0x2A, 0x0E, 0xC7, 0x8C, 0xCD, 0x5B, + 0x4D, 0x6D, 0xA6, 0x2D, 0xDC, 0x7F, 0xA3, 0xF8, 0x0A, 0xD6, 0x9B, 0xEC, 0x82, 0x5C, 0xDF, 0xB0, + 0xB0, 0x3E, 0x8D, 0xA6, 0x8A, 0x5C, 0xAB, 0xCA, 0x26, 0x60, 0x21, 0x0E, 0x33, 0x62, 0xDB, 0xB8, + 0x70, 0x97, 0x93, 0xAD, 0x79, 0x2B, 0x36, 0x0F, 0x4C, 0x7E, 0xDD, 0xA6, 0xD4, 0xAD, 0x04, 0x45, + 0xE1, 0x75, 0xFA, 0xD6, 0x6D, 0x47, 0x8C, 0x2C, 0x34, 0x79, 0x7B, 0xC4, 0xE9, 0x56, 0xA4, 0x50, + 0x54, 0x6D, 0x70, 0xC7, 0xDB, 0xC4, 0xCC, 0x64, 0x60, 0x07, 0x36, 0x6A, 0x3D, 0x9B, 0x2B, 0x52, + 0x0D, 0x4E, 0x95, 0x7B, 0x89, 0x06, 0xA7, 0xC9, 0x6D, 0x4F, 0x03, 0x76, 0x43, 0x91, 0x7A, 0xCB, + 0x91, 0xB8, 0xDE, 0x65, 0x58, 0x0E, 0x0A, 0x82, 0xA1, 0xC9, 0x6E, 0x8C, 0x31, 0xD3, 0x77, 0x20, + 0x0D, 0x6C, 0xB2, 0x34, 0x88, 0x3D, 0x34, 0x1D, 0x6F, 0xEA, 0x65, 0xCE, 0xF1, 0xF3, 0xE2, 0x0A, + 0x04, 0x24, 0xCD, 0xA1, 0x99, 0xBA, 0x3A, 0x63, 0x72, 0xAA, 0xE4, 0x27, 0x73, 0xF4, 0xE0, 0xDE, + 0xA3, 0x87, 0x0F, 0x7B, 0xDF, 0x3D, 0x70, 0xC7, 0xC1, 0x42, 0xFE, 0xFD, 0x8B, 0xB8, 0x98, 0x25, + 0xEE, 0x88, 0x82, 0x3C, 0x4A, 0x29, 0xE8, 0x19, 0x0C, 0x4E, 0x39, 0xD3, 0x8C, 0x20, 0xA7, 0x20, + 0x49, 0x8E, 0x6C, 0xB2, 0xB6, 0xEA, 0xC4, 0x8B, 0x86, 0x04, 0x50, 0x2E, 0xC6, 0xC8, 0xD7, 0x0C, + 0xE1, 0xC3, 0x44, 0xE7, 0xC6, 0xFD, 0xD6, 0xE4, 0x35, 0x66, 0xEC, 0x5D, 0x65, 0x35, 0xE0, 0x4A, + 0xC9, 0x02, 0x24, 0x47, 0x61, 0x3B, 0x8F, 0x21, 0x90, 0x71, 0x72, 0x76, 0x69, 0x2A, 0x67, 0x4C, + 0x2C, 0x9F, 0xB4, 0xBE, 0x72, 0xA5, 0x44, 0x4C, 0x3D, 0xF1, 0xD1, 0x1C, 0x33, 0xF7, 0x97, 0x3F, + 0xE6, 0xB3, 0xC9, 0x22, 0x11, 0x53, 0x9A, 0xA3, 0x37, 0x98, 0x67, 0x4E, 0x40, 0x59, 0x6B, 0xD6, + 0x35, 0x2E, 0xB2, 0x98, 0xA5, 0xE6, 0x37, 0x23, 0x11, 0xE5, 0xE6, 0x75, 0x1D, 0x71, 0xB7, 0x29, + 0x11, 0x88, 0xB3, 0xF3, 0x16, 0xDC, 0xC1, 0x96, 0xC8, 0x09, 0xC1, 0xB4, 0xAD, 0x96, 0x39, 0xFA, + 0xF9, 0xF7, 0xEF, 0x9F, 0xD4, 0xDA, 0xCD, 0xEE, 0xF9, 0x55, 0xEB, 0xAC, 0xD7, 0x3D, 0x1E, 0x9C, + 0x8A, 0x21, 0x9B, 0xF3, 0x6A, 0x9A, 0xA3, 0x5F, 0x19, 0x2F, 0xA8, 0x2F, 0xCD, 0xAB, 0x56, 0xBB, + 0xD9, 0xDC, 0x9E, 0xD7, 0x23, 0x73, 0xF4, 0x96, 0xB3, 0x6A, 0x9F, 0x03, 0xAB, 0x66, 0x7B, 0x07, + 0xB1, 0xCE, 0xCD, 0x11, 0xE7, 0x04, 0x4C, 0xAE, 0x1E, 0xF6, 0xCE, 0xB7, 0x67, 0xF4, 0x10, 0x64, + 0x7A, 0x07, 0x9C, 0xCE, 0x41, 0xBB, 0xDE, 0x2E, 0xCA, 0xF5, 0xCC, 0x11, 0xE3, 0xD3, 0xEB, 0x36, + 0xAF, 0xBA, 0xE7, 0x3B, 0xF0, 0x39, 0x33, 0x65, 0xA7, 0xC3, 0xDC, 0x3F, 0x3A, 0x32, 0x47, 0x17, + 0x3F, 0x3C, 0xAF, 0x75, 0x41, 0xC6, 0xF6, 0xA3, 0xDE, 0xF6, 0xBC, 0xBB, 0xE0, 0x17, 0x4C, 0xC8, + 0x4E, 0x1B, 0x18, 0x75, 0x77, 0x10, 0xB2, 0x63, 0x8E, 0x5E, 0x70, 0x4E, 0xC0, 0xE5, 0xAA, 0xF5, + 0x70, 0x07, 0x91, 0xC0, 0xBD, 0x7E, 0xE6, 0x9C, 0xC0, 0xBF, 0x98, 0x7B, 0x55, 0xE4, 0x04, 0xB9, + 0x97, 0x9B, 0xA6, 0x20, 0xE6, 0xD7, 0x33, 0x59, 0xEA, 0x74, 0x51, 0x4A, 0xF8, 0x3B, 0x84, 0x8E, + 0x80, 0x5E, 0x6F, 0x9C, 0x10, 0x24, 0x1D, 0xA8, 0x24, 0x0E, 0xAA, 0xE5, 0x02, 0x45, 0x92, 0xF8, + 0x6A, 0xAB, 0x39, 0xEA, 0x96, 0x28, 0xC0, 0x49, 0xD5, 0x84, 0xCA, 0x69, 0x53, 0xF2, 0x9B, 0xAC, + 0x3F, 0x64, 0xA8, 0xB3, 0xFB, 0x79, 0xC0, 0x43, 0x3B, 0xA6, 0x12, 0xD5, 0x5B, 0x25, 0x1B, 0x8D, + 0xAC, 0xE8, 0xCA, 0x1C, 0xF5, 0x3A, 0x65, 0xD6, 0xDE, 0x01, 0x8C, 0x31, 0xEF, 0x3D, 0x5D, 0x1C, + 0x04, 0x1B, 0xE3, 0x91, 0x90, 0x9A, 0xA3, 0xA7, 0xF1, 0xF1, 0x2E, 0xA8, 0xD4, 0xCB, 0x34, 0xE5, + 0xB4, 0x39, 0xB0, 0x28, 0xE2, 0x08, 0x64, 0xEA, 0x1D, 0x09, 0x4D, 0x82, 0xCC, 0xE7, 0x05, 0xE6, + 0x36, 0x71, 0x61, 0xED, 0x80, 0x8F, 0x02, 0xBA, 0x31, 0x2A, 0x11, 0x21, 0x24, 0x35, 0x79, 0x74, + 0x30, 0x44, 0x62, 0x51, 0xBE, 0x02, 0x3C, 0x02, 0x44, 0x43, 0x9F, 0xDF, 0xE5, 0xB8, 0x31, 0x22, + 0x09, 0x29, 0x54, 0xC3, 0xF8, 0x78, 0x27, 0x54, 0x76, 0x49, 0x5F, 0x8A, 0x38, 0x12, 0x97, 0x28, + 0x85, 0x75, 0x6F, 0x09, 0x97, 0x32, 0x69, 0x77, 0xC2, 0x65, 0x86, 0xFC, 0xC5, 0x56, 0xE9, 0x2B, + 0xA6, 0x04, 0x54, 0xA2, 0xC3, 0x83, 0x85, 0x4A, 0x22, 0xCC, 0x57, 0x10, 0x2B, 0xB0, 0xFE, 0xF6, + 0x48, 0xB0, 0x79, 0xC7, 0x2F, 0xE9, 0xCC, 0xD1, 0x33, 0x5C, 0x7F, 0xCD, 0x8E, 0x76, 0x81, 0xE3, + 0x49, 0x48, 0xBD, 0x1D, 0x00, 0x89, 0x64, 0x11, 0x70, 0x34, 0x25, 0x1A, 0xE7, 0xB7, 0x84, 0xC6, + 0xF9, 0x2D, 0xA2, 0x81, 0xF0, 0x7B, 0x07, 0x2F, 0xB1, 0xB3, 0x31, 0x1C, 0x11, 0xA1, 0x39, 0xBA, + 0xBC, 0x5A, 0x78, 0x01, 0xBB, 0x5B, 0xF8, 0x25, 0xFB, 0xBE, 0x53, 0x90, 0x9C, 0xED, 0x80, 0x49, + 0x2C, 0x90, 0x8C, 0x91, 0x33, 0x89, 0xCA, 0xD9, 0x2D, 0xA1, 0x52, 0x26, 0xEB, 0x2E, 0xA8, 0x4C, + 0x11, 0x71, 0x2D, 0x4C, 0x1C, 0x76, 0xE7, 0xE2, 0xA6, 0xC0, 0x28, 0xB4, 0xE6, 0xE8, 0xFB, 0xE4, + 0xCB, 0x2E, 0xC0, 0x34, 0x77, 0xC0, 0x45, 0x95, 0x27, 0x1D, 0x2F, 0x67, 0xB0, 0x58, 0xBE, 0x25, + 0x6C, 0x5A, 0xAD, 0xDB, 0xAC, 0x2A, 0x0B, 0x6C, 0x11, 0xE4, 0xBC, 0xC7, 0x93, 0x09, 0x2C, 0x83, + 0x36, 0x2F, 0x2D, 0x29, 0x72, 0xA8, 0x2F, 0xE2, 0xBB, 0x71, 0xC9, 0xBF, 0x6F, 0xBC, 0x87, 0x91, + 0x61, 0xF7, 0xB9, 0x36, 0x32, 0x9A, 0xFA, 0xB5, 0xF0, 0x6B, 0x2F, 0x96, 0x73, 0xDB, 0x5D, 0x0D, + 0x60, 0x82, 0xA7, 0x7C, 0x53, 0x7D, 0x6B, 0x1E, 0x6D, 0xF0, 0x6C, 0x1F, 0x5D, 0xF3, 0xC7, 0x10, + 0x77, 0x59, 0x48, 0xBF, 0xC1, 0xB6, 0xF1, 0x0B, 0x71, 0xB7, 0x57, 0xA6, 0xCB, 0x04, 0xC1, 0xD8, + 0xDD, 0x8D, 0xCB, 0x19, 0x2C, 0x91, 0xE0, 0x60, 0x37, 0x26, 0x3D, 0xF0, 0x24, 0xBC, 0x20, 0xE8, + 0x4B, 0x58, 0xC4, 0xA3, 0xD5, 0x78, 0xF3, 0x82, 0xB2, 0x1A, 0x43, 0x5D, 0xFE, 0xED, 0xA9, 0x71, + 0xC9, 0x6F, 0x03, 0xDB, 0x38, 0x5D, 0x89, 0x2B, 0xD4, 0x55, 0x1C, 0x5D, 0x24, 0x2A, 0x29, 0xA7, + 0xB9, 0xB6, 0x27, 0xAA, 0x0F, 0xA0, 0xAA, 0xFB, 0xA2, 0x1A, 0xF5, 0x22, 0x01, 0xF9, 0x05, 0x3D, + 0x53, 0xD1, 0xB6, 0x9A, 0x8E, 0xB7, 0xD8, 0x8A, 0x59, 0xAB, 0xCD, 0xDB, 0x30, 0x6B, 0x05, 0x30, + 0xD9, 0x4B, 0x76, 0x87, 0xA0, 0x6D, 0x00, 0x5E, 0x7B, 0x01, 0x8A, 0xCD, 0x7A, 0x18, 0xA0, 0xB8, + 0xBE, 0x87, 0x06, 0x0A, 0xBC, 0xE5, 0x3D, 0xAB, 0xA3, 0xDB, 0x04, 0x15, 0x27, 0x34, 0x47, 0xAF, + 0x90, 0x1B, 0x42, 0x91, 0xD9, 0x17, 0x60, 0xF1, 0xC4, 0x07, 0x0B, 0x2F, 0xA9, 0xF7, 0xA1, 0xA1, + 0x03, 0x41, 0xE6, 0x9E, 0xBD, 0xF9, 0x72, 0x47, 0xD2, 0x89, 0x94, 0xF8, 0x0A, 0x8E, 0x36, 0x6E, + 0x0C, 0x22, 0x0E, 0xB7, 0xDC, 0x11, 0x88, 0xA5, 0xD4, 0xF6, 0xCD, 0xC0, 0xDB, 0xD0, 0x75, 0xAF, + 0x77, 0xE9, 0x04, 0x2E, 0x1C, 0x2F, 0xB4, 0xB7, 0xE7, 0x00, 0x6D, 0xC0, 0x8F, 0x93, 0x09, 0xB1, + 0xB6, 0x6F, 0x24, 0xA0, 0x09, 0x78, 0xE1, 0xCD, 0x2B, 0xD2, 0xDF, 0x72, 0xE1, 0xC5, 0xD6, 0x16, + 0x2B, 0x39, 0x0B, 0x50, 0xBC, 0xBC, 0xD8, 0x6B, 0xE1, 0x85, 0x39, 0x0F, 0x94, 0x19, 0x98, 0xB6, + 0x87, 0x4E, 0x0A, 0x20, 0xC4, 0x7B, 0xEE, 0x3C, 0xDB, 0x80, 0x25, 0x28, 0xE3, 0x8C, 0x1E, 0x2D, + 0xBF, 0x0F, 0xB5, 0xBE, 0x4B, 0x24, 0x4A, 0xAF, 0xEE, 0x5A, 0x67, 0x9D, 0x5E, 0xBC, 0xBC, 0xEB, + 0xB4, 0x3F, 0xEF, 0x02, 0x8F, 0x31, 0xBF, 0x5D, 0x7C, 0xDA, 0xDB, 0x40, 0x03, 0xD9, 0xE8, 0x35, + 0xBB, 0xCE, 0xB0, 0x41, 0xC2, 0xDE, 0x3D, 0x90, 0xDA, 0x87, 0x8B, 0xA4, 0xF6, 0x17, 0x10, 0x4A, + 0xD3, 0x2D, 0x32, 0xDE, 0x94, 0x65, 0xBC, 0xEF, 0x2F, 0xF6, 0x83, 0xD0, 0xF4, 0x60, 0xA9, 0x6E, + 0x7A, 0xD0, 0x54, 0x67, 0x88, 0x9B, 0xAD, 0x62, 0x98, 0xB6, 0xEC, 0x60, 0x25, 0xA1, 0xD8, 0xCB, + 0xDA, 0x25, 0xC9, 0xB5, 0xAE, 0x76, 0xC9, 0x72, 0x91, 0x18, 0xE9, 0x24, 0xD7, 0x4B, 0xAE, 0x8A, + 0x9C, 0x7D, 0xDE, 0xCB, 0xBA, 0xDD, 0x32, 0x69, 0x77, 0x09, 0x1A, 0x1F, 0xAD, 0xDE, 0x4F, 0xE7, + 0x68, 0x63, 0x30, 0x24, 0x1D, 0x60, 0xF1, 0xEA, 0xC9, 0x3E, 0xDB, 0x85, 0x68, 0xDE, 0xC3, 0xC4, + 0x51, 0xAC, 0xF5, 0xA1, 0x73, 0x9D, 0x83, 0xDD, 0xCD, 0x93, 0x1D, 0x23, 0x32, 0x47, 0x2F, 0xB1, + 0x1B, 0x18, 0x17, 0x9E, 0x2F, 0xDF, 0xFD, 0xB4, 0x17, 0xD4, 0xF8, 0xCC, 0x87, 0x81, 0x4C, 0x28, + 0x7D, 0x68, 0xBC, 0x66, 0x73, 0xE2, 0xFB, 0x9E, 0xBF, 0x31, 0x64, 0x92, 0x0E, 0x96, 0x15, 0xF5, + 0x57, 0xFC, 0x68, 0x2F, 0x70, 0x45, 0xB3, 0x1E, 0x06, 0xB1, 0x58, 0xE7, 0x43, 0x83, 0xB6, 0x9C, + 0x38, 0x64, 0xB1, 0x31, 0x64, 0x9C, 0xCA, 0x1C, 0xBD, 0xAB, 0x3F, 0x87, 0x7F, 0xF7, 0x02, 0x97, + 0x98, 0xF1, 0x30, 0x60, 0x49, 0x6D, 0x0F, 0x0D, 0xD5, 0x78, 0xB1, 0x79, 0x3A, 0x04, 0x1A, 0x73, + 0xF4, 0xF4, 0xA7, 0xFD, 0xF4, 0x7E, 0x6C, 0xB2, 0x8A, 0x08, 0xED, 0x84, 0x07, 0x57, 0xEA, 0xD0, + 0x68, 0xAC, 0xB6, 0x40, 0x63, 0xC5, 0x04, 0xFF, 0x6D, 0x4F, 0x68, 0xAC, 0xAA, 0xA3, 0xF1, 0x99, + 0xE3, 0x65, 0xF5, 0x25, 0xE0, 0xC3, 0x9F, 0xC5, 0x18, 0xA3, 0xCD, 0xCB, 0x51, 0x44, 0xC8, 0x6E, + 0x1A, 0x83, 0x23, 0xE3, 0x29, 0xDA, 0x4F, 0x41, 0x8A, 0xE7, 0xDD, 0x47, 0x08, 0x25, 0x4A, 0x1E, + 0x1A, 0xA7, 0x09, 0xB2, 0xF0, 0x7B, 0x1B, 0xD3, 0x6D, 0xAE, 0x2D, 0x2B, 0xB4, 0xE6, 0xE8, 0x39, + 0x7C, 0x31, 0x9E, 0xF1, 0x2F, 0xFB, 0x6A, 0xF9, 0xD4, 0xF9, 0xF7, 0x81, 0x5A, 0x4A, 0xDF, 0x2F, + 0x02, 0x38, 0x68, 0xB0, 0xBD, 0xA9, 0xBB, 0xD5, 0x23, 0x0D, 0x29, 0x72, 0x09, 0xDF, 0x1B, 0xF1, + 0x7D, 0xBF, 0x00, 0x26, 0x42, 0xEC, 0x0D, 0x43, 0x45, 0xEF, 0x7D, 0xC0, 0x18, 0x3D, 0x16, 0xC4, + 0x8B, 0xB4, 0x78, 0x15, 0x5E, 0x19, 0x52, 0xF2, 0xE1, 0x27, 0x7E, 0x4B, 0x0B, 0xA6, 0xF5, 0x80, + 0x12, 0xC7, 0x81, 0x85, 0x30, 0xA6, 0xC6, 0x5B, 0x76, 0x38, 0x38, 0x15, 0x03, 0xAA, 0x73, 0x91, + 0xCF, 0xDC, 0xB0, 0x97, 0x50, 0xA2, 0xB9, 0x39, 0x7A, 0xCB, 0x5E, 0x12, 0x08, 0xBC, 0xD8, 0xB7, + 0xCD, 0x99, 0x71, 0x23, 0x62, 0xD7, 0xF7, 0x40, 0xA8, 0x18, 0x24, 0xF9, 0xAE, 0x26, 0xD3, 0x88, + 0x8E, 0x94, 0xDF, 0x46, 0x97, 0x7C, 0xB0, 0xC1, 0xBC, 0xAC, 0x7C, 0x3A, 0x76, 0xD5, 0xC2, 0xCA, + 0xBF, 0xB8, 0x31, 0x38, 0x75, 0x91, 0xC6, 0xDC, 0x39, 0x28, 0x0C, 0xC4, 0xDB, 0x25, 0x73, 0x58, + 0xC5, 0xCF, 0x33, 0x71, 0x4B, 0x24, 0x8F, 0x69, 0xC6, 0x6A, 0x65, 0x1F, 0xDF, 0x94, 0xDB, 0x4C, + 0xD5, 0x82, 0x96, 0x3F, 0x88, 0x29, 0xEB, 0x21, 0x3B, 0x8C, 0xCD, 0xFF, 0x9F, 0x7F, 0x97, 0xF9, + 0x0C, 0x7B, 0xF7, 0x67, 0x22, 0x98, 0x69, 0x04, 0xBE, 0x35, 0x34, 0xF3, 0x9E, 0x8E, 0xCA, 0xD1, + 0xFC, 0x54, 0xA7, 0x7A, 0x66, 0xB0, 0xC6, 0xD6, 0x83, 0xC0, 0xF2, 0xC9, 0x82, 0x8E, 0xEE, 0xD8, + 0x9E, 0x15, 0xCE, 0xB1, 0x4B, 0x1B, 0xC8, 0xB6, 0x2F, 0x97, 0x70, 0xF0, 0x92, 0x04, 0x14, 0x83, + 0x15, 0x6A, 0x47, 0xCF, 0x7E, 0x7C, 0x75, 0x21, 0x9E, 0x12, 0x7B, 0xE9, 0x21, 0x1B, 0xDB, 0x47, + 0x27, 0xC6, 0x24, 0x74, 0x85, 0x9B, 0xD7, 0x30, 0x1B, 0x2B, 0xDE, 0xBB, 0xBA, 0x44, 0xBE, 0x31, + 0x46, 0x01, 0x7E, 0xE1, 0x05, 0xD4, 0x18, 0x1A, 0x31, 0x47, 0xC7, 0xB3, 0xF8, 0x7D, 0xBF, 0x0D, + 0xCF, 0x27, 0x53, 0xE2, 0xCA, 0x91, 0x42, 0xD9, 0x5F, 0x7D, 0x07, 0x86, 0xC6, 0x54, 0xDF, 0x1A, + 0x47, 0xFD, 0xF3, 0xD6, 0x11, 0x7B, 0x1C, 0x0F, 0x60, 0x80, 0x1F, 0x00, 0x02, 0x0C, 0x03, 0x20, + 0xC0, 0x87, 0x23, 0xF9, 0x78, 0x20, 0x76, 0x1A, 0xDC, 0xE4, 0x4C, 0x40, 0x26, 0x6D, 0xED, 0x48, + 0xE0, 0x74, 0xC4, 0x1E, 0x34, 0xBE, 0x89, 0x29, 0x83, 0x99, 0xB7, 0x2A, 0xA2, 0xF4, 0xF1, 0xDC, + 0x5B, 0xE2, 0x0C, 0x71, 0x4C, 0x2D, 0xBD, 0xB9, 0x74, 0xEA, 0xC8, 0xEB, 0x8F, 0x8E, 0xA3, 0x01, + 0xF1, 0x7B, 0xCC, 0x86, 0x06, 0xF5, 0x43, 0x9C, 0x66, 0x8B, 0xDD, 0x32, 0xAE, 0x91, 0x58, 0x85, + 0x8C, 0x27, 0xC8, 0x09, 0x32, 0x9C, 0xC3, 0x85, 0x8D, 0x28, 0x7E, 0xC7, 0x76, 0x0C, 0x61, 0x40, + 0x0D, 0x3B, 0x27, 0x62, 0xFB, 0xF0, 0x44, 0x9E, 0x79, 0x03, 0x7C, 0x29, 0x3E, 0x4E, 0x66, 0x55, + 0x7F, 0x06, 0x8A, 0xF4, 0xD7, 0xA1, 0xE1, 0x86, 0x10, 0xC2, 0x8F, 0xB9, 0x0A, 0x46, 0x3F, 0x75, + 0x96, 0x53, 0x3B, 0x90, 0x9D, 0xE4, 0x3B, 0xDB, 0xF9, 0x9C, 0xFC, 0x47, 0x32, 0x61, 0x13, 0x37, + 0xF8, 0x1B, 0xE4, 0x87, 0xC0, 0xE3, 0x28, 0xCA, 0xEE, 0x47, 0xC9, 0x8B, 0x79, 0x55, 0x22, 0x6E, + 0x87, 0x86, 0xEC, 0x83, 0xE5, 0xF9, 0xA5, 0x3C, 0x71, 0xF7, 0xEE, 0x32, 0xE6, 0x6B, 0x28, 0xC3, + 0xE0, 0x54, 0x72, 0xE2, 0x06, 0x4E, 0x28, 0x4F, 0x3F, 0xAF, 0xF3, 0xCE, 0xF0, 0x88, 0x98, 0x2B, + 0x1C, 0xEE, 0xC4, 0x92, 0xA7, 0x2C, 0xF0, 0xE0, 0x41, 0x9A, 0xDB, 0xDD, 0xA1, 0xA4, 0x4A, 0x34, + 0x11, 0xE3, 0x21, 0x32, 0x20, 0xF2, 0x40, 0x6D, 0xF9, 0x4C, 0xBC, 0x14, 0x89, 0x4C, 0x6A, 0x77, + 0x53, 0x86, 0x8F, 0x65, 0x9C, 0x30, 0x13, 0x11, 0x9B, 0x1B, 0x88, 0x5F, 0x33, 0x3C, 0x4E, 0x9E, + 0x7A, 0x15, 0xF2, 0x3D, 0xE6, 0x5E, 0x5F, 0xC3, 0xF2, 0xF2, 0xDB, 0x31, 0xD8, 0x9F, 0x39, 0x73, + 0xF2, 0x83, 0x1C, 0x9F, 0x4C, 0xA5, 0x72, 0x9C, 0xA6, 0x38, 0x32, 0xC5, 0x32, 0x72, 0xB3, 0x0F, + 0x9F, 0x00, 0x86, 0xB2, 0x9D, 0xEF, 0xE4, 0xF9, 0xFC, 0x8C, 0x39, 0xD9, 0x87, 0x4F, 0xBC, 0x3E, + 0xB0, 0x50, 0x82, 0xE8, 0x0E, 0x09, 0x8D, 0x62, 0x9C, 0xDD, 0x6A, 0xCC, 0x54, 0xE2, 0x22, 0xC0, + 0x61, 0x11, 0xAB, 0x4C, 0x01, 0xD7, 0x30, 0x14, 0x01, 0x55, 0x13, 0xF5, 0xE9, 0x29, 0xAF, 0x35, + 0x8C, 0xB9, 0x8C, 0x95, 0xF4, 0xEF, 0x77, 0x54, 0xE1, 0x6F, 0xA2, 0xF0, 0x89, 0x53, 0x99, 0x8A, + 0x27, 0xF3, 0xE3, 0xC8, 0x62, 0xCC, 0xD5, 0x13, 0x87, 0x91, 0xAF, 0x2B, 0x89, 0xFC, 0x3C, 0x31, + 0xAB, 0x05, 0x39, 0x4C, 0xF1, 0xF8, 0x7E, 0x46, 0x54, 0xD5, 0xD5, 0x41, 0xEE, 0x96, 0xA1, 0xBE, + 0x80, 0x64, 0x0C, 0xA9, 0xF0, 0x63, 0x8A, 0x0F, 0xDF, 0xB0, 0x8F, 0x99, 0x88, 0xDF, 0xC4, 0xE5, + 0xFD, 0xBA, 0xE7, 0x62, 0x3D, 0x77, 0xD5, 0xD9, 0x75, 0x3C, 0x45, 0x29, 0xCE, 0x32, 0x0D, 0xC7, + 0x73, 0x42, 0x35, 0x0C, 0x8F, 0x20, 0x0D, 0xEB, 0x78, 0xC9, 0x06, 0x2D, 0x21, 0xF0, 0x31, 0x0D, + 0x7D, 0x57, 0x8D, 0x26, 0x91, 0x91, 0xFE, 0x0E, 0xB1, 0x7F, 0x0D, 0x8C, 0x3E, 0xDC, 0xFF, 0x14, + 0xE5, 0xF7, 0x9B, 0x53, 0xFE, 0x6C, 0x8E, 0xE7, 0x3C, 0x86, 0x0A, 0x30, 0xBC, 0xFF, 0x89, 0x43, + 0x7D, 0xF3, 0x00, 0xA6, 0x84, 0x2F, 0x7C, 0xE2, 0x9B, 0x0F, 0x82, 0xC5, 0x84, 0xBD, 0x3E, 0xBB, + 0xC6, 0x59, 0x44, 0xB8, 0x35, 0xE8, 0x0C, 0xBB, 0x35, 0x1F, 0x07, 0x0B, 0x60, 0x8F, 0x93, 0x44, + 0x16, 0xCD, 0xE8, 0x39, 0x18, 0x4A, 0xCD, 0xB4, 0xF6, 0xC1, 0xC7, 0x40, 0x07, 0x02, 0x50, 0xCF, + 0xB8, 0xFF, 0x89, 0xB3, 0xB8, 0x31, 0x26, 0x10, 0xCD, 0xC1, 0x0C, 0xDB, 0x27, 0x50, 0x77, 0x10, + 0x65, 0x4F, 0xA6, 0xDF, 0xFF, 0x14, 0xB1, 0x6A, 0x88, 0x9F, 0x6E, 0x3E, 0xC4, 0x1E, 0x12, 0x17, + 0x83, 0xA8, 0x86, 0xF1, 0x13, 0x0D, 0xCE, 0xEB, 0x2D, 0x47, 0xC1, 0xF3, 0x9F, 0x38, 0x4E, 0xED, + 0x48, 0xBC, 0x7E, 0x41, 0xE6, 0xE8, 0x06, 0x34, 0x9D, 0x97, 0x08, 0xC4, 0x56, 0x93, 0x3B, 0xCF, + 0x3B, 0x9E, 0x6B, 0x39, 0xC4, 0xFA, 0xC8, 0x12, 0xF3, 0x71, 0x5A, 0x70, 0x11, 0xE9, 0x4E, 0x43, + 0xBC, 0x4E, 0xEB, 0xB5, 0x67, 0xE3, 0x8C, 0x9B, 0x1E, 0x33, 0x31, 0x4E, 0x4F, 0xC1, 0xCA, 0xC8, + 0x8E, 0x52, 0x92, 0xC0, 0x88, 0xBD, 0x77, 0x45, 0x98, 0x29, 0x65, 0x61, 0xA1, 0x8C, 0xD4, 0x45, + 0xD8, 0x2C, 0xA9, 0xD6, 0x91, 0xCA, 0x89, 0xDB, 0x0A, 0xF4, 0x8C, 0xD8, 0x16, 0x7F, 0x05, 0x9E, + 0x5B, 0x3B, 0xBE, 0x13, 0x9B, 0x61, 0x9D, 0x07, 0x9B, 0x40, 0x61, 0x90, 0x32, 0x51, 0x9E, 0x99, + 0xD2, 0x5D, 0xFD, 0x51, 0x92, 0x49, 0x72, 0x6C, 0x26, 0x3E, 0x4A, 0x4D, 0xE3, 0x05, 0x8D, 0xCF, + 0xFC, 0x07, 0x77, 0x9A, 0x3F, 0x4F, 0x44, 0x11, 0x54, 0x72, 0xD2, 0xB1, 0x62, 0x30, 0xE1, 0x81, + 0xEC, 0xBF, 0x1E, 0x51, 0x1B, 0x11, 0xE8, 0xAE, 0x2F, 0x1D, 0xCC, 0x0E, 0x9F, 0x5E, 0xFF, 0x00, + 0xC5, 0x5B, 0xB4, 0x20, 0x5C, 0x9A, 0x84, 0xE0, 0x22, 0x6E, 0xFF, 0x4A, 0x29, 0x93, 0x56, 0x51, + 0xE1, 0xC1, 0xDB, 0x77, 0x91, 0x71, 0x8A, 0x38, 0xC4, 0x9D, 0x7E, 0x8A, 0x94, 0x71, 0x2D, 0xA7, + 0x4D, 0xF5, 0xF7, 0x0A, 0xBD, 0x9A, 0xED, 0x8A, 0xE8, 0x95, 0x96, 0x5E, 0xA1, 0xE6, 0xAE, 0x5C, + 0x4E, 0xAC, 0x36, 0xB7, 0x47, 0x8A, 0xB1, 0x03, 0xEA, 0x2D, 0xC4, 0x1A, 0x23, 0xE3, 0xE6, 0x2B, + 0xE2, 0xDA, 0xDE, 0xAA, 0xC1, 0xCE, 0xD7, 0x64, 0x91, 0x54, 0x15, 0x6D, 0x10, 0x17, 0x0C, 0xF8, + 0xE2, 0x97, 0x57, 0x2F, 0x59, 0xD2, 0x51, 0xD7, 0x2A, 0x47, 0xE9, 0x0E, 0x87, 0xBF, 0xEB, 0x5C, + 0x3B, 0x03, 0x83, 0xAD, 0x01, 0x4D, 0xB3, 0x48, 0x36, 0x71, 0x63, 0xC9, 0x62, 0x81, 0x1D, 0x7E, + 0x10, 0x73, 0xB2, 0xD2, 0x93, 0x02, 0xF8, 0xB8, 0x54, 0x16, 0x6F, 0x91, 0x15, 0x05, 0x22, 0xF1, + 0x09, 0xA5, 0xE0, 0xB0, 0x86, 0x70, 0xE5, 0x80, 0x65, 0x19, 0xB9, 0xCE, 0xBB, 0x63, 0xA8, 0xE0, + 0xE7, 0x04, 0x7D, 0x62, 0x26, 0x19, 0x65, 0x69, 0xE1, 0x95, 0x4C, 0x89, 0x16, 0x10, 0x99, 0xF8, + 0xF1, 0x7B, 0x6B, 0x0C, 0xC9, 0xF1, 0x19, 0x78, 0x7E, 0xC3, 0x05, 0x0D, 0x8E, 0x6F, 0x8A, 0xD4, + 0x11, 0xE6, 0x4A, 0x80, 0xAC, 0x2A, 0x04, 0x4F, 0x43, 0x7A, 0x6E, 0x29, 0xFB, 0xE8, 0xD9, 0xA9, + 0xDE, 0x2B, 0xAE, 0xDD, 0xB2, 0x36, 0x2D, 0xCF, 0xB0, 0xC3, 0x75, 0xD3, 0x8A, 0x3E, 0x25, 0xC5, + 0x20, 0x49, 0x30, 0x6B, 0xC2, 0x66, 0xDA, 0x14, 0xC5, 0x2F, 0xA2, 0x01, 0x91, 0xEC, 0x6A, 0x40, + 0xE4, 0xC8, 0x9E, 0xEE, 0xE2, 0x32, 0xED, 0x42, 0x06, 0x72, 0x99, 0xC5, 0x0C, 0xF6, 0xD6, 0x8F, + 0x19, 0x2B, 0xD0, 0xD2, 0x09, 0xAA, 0x14, 0x0A, 0x6D, 0x06, 0x2C, 0xAC, 0x18, 0x62, 0x86, 0x48, + 0xDA, 0x6C, 0xB7, 0x99, 0xAE, 0x0E, 0x17, 0x21, 0x58, 0x69, 0x1E, 0xF9, 0xA4, 0xF8, 0x8D, 0xB5, + 0x6C, 0x71, 0xF0, 0x40, 0x0B, 0x57, 0x14, 0xD4, 0x70, 0x5A, 0xC9, 0x04, 0xB2, 0xDF, 0x2B, 0x21, + 0x50, 0xEE, 0xBA, 0xE0, 0xB4, 0xF0, 0xD3, 0xBA, 0xD8, 0x1A, 0x23, 0xC3, 0xB8, 0xE3, 0x18, 0x73, + 0x46, 0x24, 0xBB, 0xA2, 0x04, 0xF1, 0xF5, 0xEE, 0x34, 0x0B, 0xF9, 0x5A, 0x57, 0x7A, 0xA3, 0xA0, + 0x15, 0xDD, 0xB7, 0x96, 0xE8, 0x83, 0x8B, 0x95, 0xC7, 0xAA, 0xF2, 0x51, 0x97, 0x5D, 0x42, 0xA1, + 0xDE, 0x65, 0x27, 0xD4, 0xC7, 0x15, 0xD5, 0xC7, 0x52, 0x7D, 0x46, 0x90, 0x34, 0x84, 0xE5, 0x2D, + 0x7F, 0xEC, 0x8C, 0xBF, 0x3D, 0x4D, 0x34, 0x5B, 0x8D, 0x0B, 0xE5, 0x94, 0xAD, 0xB8, 0xA2, 0x5E, + 0x31, 0x41, 0xEA, 0x9E, 0x62, 0xA1, 0xD6, 0x6A, 0x5C, 0x4D, 0xAD, 0xA8, 0x95, 0x67, 0x04, 0x89, + 0x5A, 0xFA, 0x86, 0x3F, 0x52, 0x25, 0xDE, 0x42, 0xE6, 0xFF, 0xA7, 0x4B, 0xFC, 0xCE, 0x94, 0x58, + 0x58, 0xB1, 0xFF, 0x5A, 0x5A, 0xCA, 0xC4, 0x30, 0x45, 0xC9, 0x78, 0xC9, 0x50, 0x4A, 0x1A, 0x8F, + 0x54, 0xA8, 0x63, 0x39, 0x0A, 0xA9, 0xA3, 0x41, 0xA2, 0x06, 0xC6, 0x5F, 0x2B, 0x19, 0x2B, 0x1E, + 0x9D, 0x04, 0x42, 0xC2, 0x40, 0x34, 0xE0, 0x23, 0xE3, 0x2C, 0xBB, 0xD4, 0x14, 0x8D, 0x90, 0x50, + 0x36, 0xD3, 0xFE, 0xA8, 0x03, 0x62, 0x95, 0x52, 0x63, 0xE2, 0x00, 0x11, 0xF4, 0x79, 0x62, 0x96, + 0x8A, 0x82, 0x1C, 0xEC, 0xD3, 0x9A, 0xF9, 0x93, 0x83, 0xD9, 0xF2, 0x41, 0xDE, 0x14, 0x7E, 0xF1, + 0xC3, 0x73, 0xC3, 0xF3, 0x0D, 0xF1, 0x16, 0x4D, 0x3F, 0x7E, 0x6B, 0x8E, 0x21, 0x5F, 0x31, 0xC7, + 0x17, 0x69, 0xC4, 0x9D, 0x1A, 0x74, 0x46, 0x02, 0xE8, 0x59, 0xD9, 0x93, 0xE0, 0xF8, 0xAE, 0x19, + 0xBF, 0x45, 0xAE, 0x54, 0x3D, 0xD1, 0xA4, 0x7E, 0x17, 0x2B, 0x92, 0x31, 0xA7, 0xA0, 0x49, 0x6C, + 0x79, 0x57, 0xEA, 0xB8, 0x96, 0x58, 0x8A, 0x96, 0x85, 0x1B, 0x98, 0x30, 0x3E, 0xFD, 0xC5, 0x5A, + 0x51, 0xAF, 0x40, 0xA9, 0x21, 0x63, 0xB2, 0xC4, 0x96, 0x89, 0xAE, 0x6B, 0xD6, 0xD4, 0xAD, 0xBD, + 0x0B, 0x10, 0x65, 0x5B, 0x49, 0xDA, 0x6C, 0x9E, 0x8F, 0x8A, 0xB0, 0xB8, 0xA8, 0x72, 0xE2, 0x33, + 0x38, 0x8D, 0x36, 0x2C, 0xC5, 0x37, 0xF1, 0x52, 0xAE, 0xC1, 0xA9, 0xF8, 0x9F, 0x0A, 0xFF, 0x0B, + 0x9B, 0xFC, 0x8E, 0x51, 0xC1, 0x70, 0x00, 0x00 +}; diff --git a/trunk/Arduino/CameraWebServer/camera_pins.h b/trunk/Arduino/CameraWebServer/camera_pins.h new file mode 100644 index 00000000..f6ffd33b --- /dev/null +++ b/trunk/Arduino/CameraWebServer/camera_pins.h @@ -0,0 +1,156 @@ + +#if defined(CAMERA_MODEL_WROVER_KIT) +#define PWDN_GPIO_NUM -1 +#define RESET_GPIO_NUM -1 +#define XCLK_GPIO_NUM 21 +#define SIOD_GPIO_NUM 26 +#define SIOC_GPIO_NUM 27 + +#define Y9_GPIO_NUM 35 +#define Y8_GPIO_NUM 34 +#define Y7_GPIO_NUM 39 +#define Y6_GPIO_NUM 36 +#define Y5_GPIO_NUM 19 +#define Y4_GPIO_NUM 18 +#define Y3_GPIO_NUM 5 +#define Y2_GPIO_NUM 4 +#define VSYNC_GPIO_NUM 25 +#define HREF_GPIO_NUM 23 +#define PCLK_GPIO_NUM 22 + +#elif defined(CAMERA_MODEL_ESP_EYE) +#define PWDN_GPIO_NUM -1 +#define RESET_GPIO_NUM -1 +#define XCLK_GPIO_NUM 4 +#define SIOD_GPIO_NUM 18 +#define SIOC_GPIO_NUM 23 + +#define Y9_GPIO_NUM 36 +#define Y8_GPIO_NUM 37 +#define Y7_GPIO_NUM 38 +#define Y6_GPIO_NUM 39 +#define Y5_GPIO_NUM 35 +#define Y4_GPIO_NUM 14 +#define Y3_GPIO_NUM 13 +#define Y2_GPIO_NUM 34 +#define VSYNC_GPIO_NUM 5 +#define HREF_GPIO_NUM 27 +#define PCLK_GPIO_NUM 25 + +#elif defined(CAMERA_MODEL_M5STACK_PSRAM) +#define PWDN_GPIO_NUM -1 +#define RESET_GPIO_NUM 15 +#define XCLK_GPIO_NUM 27 +#define SIOD_GPIO_NUM 25 +#define SIOC_GPIO_NUM 23 + +#define Y9_GPIO_NUM 19 +#define Y8_GPIO_NUM 36 +#define Y7_GPIO_NUM 18 +#define Y6_GPIO_NUM 39 +#define Y5_GPIO_NUM 5 +#define Y4_GPIO_NUM 34 +#define Y3_GPIO_NUM 35 +#define Y2_GPIO_NUM 32 +#define VSYNC_GPIO_NUM 22 +#define HREF_GPIO_NUM 26 +#define PCLK_GPIO_NUM 21 + +#elif defined(CAMERA_MODEL_M5STACK_V2_PSRAM) +#define PWDN_GPIO_NUM -1 +#define RESET_GPIO_NUM 15 +#define XCLK_GPIO_NUM 27 +#define SIOD_GPIO_NUM 22 +#define SIOC_GPIO_NUM 23 + +#define Y9_GPIO_NUM 19 +#define Y8_GPIO_NUM 36 +#define Y7_GPIO_NUM 18 +#define Y6_GPIO_NUM 39 +#define Y5_GPIO_NUM 5 +#define Y4_GPIO_NUM 34 +#define Y3_GPIO_NUM 35 +#define Y2_GPIO_NUM 32 +#define VSYNC_GPIO_NUM 25 +#define HREF_GPIO_NUM 26 +#define PCLK_GPIO_NUM 21 + +#elif defined(CAMERA_MODEL_M5STACK_WIDE) +#define PWDN_GPIO_NUM -1 +#define RESET_GPIO_NUM 15 +#define XCLK_GPIO_NUM 27 +#define SIOD_GPIO_NUM 22 +#define SIOC_GPIO_NUM 23 + +#define Y9_GPIO_NUM 19 +#define Y8_GPIO_NUM 36 +#define Y7_GPIO_NUM 18 +#define Y6_GPIO_NUM 39 +#define Y5_GPIO_NUM 5 +#define Y4_GPIO_NUM 34 +#define Y3_GPIO_NUM 35 +#define Y2_GPIO_NUM 32 +#define VSYNC_GPIO_NUM 25 +#define HREF_GPIO_NUM 26 +#define PCLK_GPIO_NUM 21 + +#elif defined(CAMERA_MODEL_M5STACK_ESP32CAM) +#define PWDN_GPIO_NUM -1 +#define RESET_GPIO_NUM 15 +#define XCLK_GPIO_NUM 27 +#define SIOD_GPIO_NUM 25 +#define SIOC_GPIO_NUM 23 + +#define Y9_GPIO_NUM 19 +#define Y8_GPIO_NUM 36 +#define Y7_GPIO_NUM 18 +#define Y6_GPIO_NUM 39 +#define Y5_GPIO_NUM 5 +#define Y4_GPIO_NUM 34 +#define Y3_GPIO_NUM 35 +#define Y2_GPIO_NUM 17 +#define VSYNC_GPIO_NUM 22 +#define HREF_GPIO_NUM 26 +#define PCLK_GPIO_NUM 21 + +#elif defined(CAMERA_MODEL_AI_THINKER) +#define PWDN_GPIO_NUM 32 +#define RESET_GPIO_NUM -1 +#define XCLK_GPIO_NUM 0 +#define SIOD_GPIO_NUM 26 +#define SIOC_GPIO_NUM 27 + +#define Y9_GPIO_NUM 35 +#define Y8_GPIO_NUM 34 +#define Y7_GPIO_NUM 39 +#define Y6_GPIO_NUM 36 +#define Y5_GPIO_NUM 21 +#define Y4_GPIO_NUM 19 +#define Y3_GPIO_NUM 18 +#define Y2_GPIO_NUM 5 +#define VSYNC_GPIO_NUM 25 +#define HREF_GPIO_NUM 23 +#define PCLK_GPIO_NUM 22 + +#elif defined(CAMERA_MODEL_TTGO_T_JOURNAL) +#define PWDN_GPIO_NUM 0 +#define RESET_GPIO_NUM 15 +#define XCLK_GPIO_NUM 27 +#define SIOD_GPIO_NUM 25 +#define SIOC_GPIO_NUM 23 + +#define Y9_GPIO_NUM 19 +#define Y8_GPIO_NUM 36 +#define Y7_GPIO_NUM 18 +#define Y6_GPIO_NUM 39 +#define Y5_GPIO_NUM 5 +#define Y4_GPIO_NUM 34 +#define Y3_GPIO_NUM 35 +#define Y2_GPIO_NUM 17 +#define VSYNC_GPIO_NUM 22 +#define HREF_GPIO_NUM 26 +#define PCLK_GPIO_NUM 21 + +#else +#error "Camera model not selected" +#endif diff --git a/trunk/Arduino/FloppyDriveController.sketch/Amiga Floppy Disk Reader and Writer - Amiga Arduino Floppy Disk Reader and Writer.desktop b/trunk/Arduino/FloppyDriveController.sketch/Amiga Floppy Disk Reader and Writer - Amiga Arduino Floppy Disk Reader and Writer.desktop new file mode 100644 index 00000000..a73f16fd --- /dev/null +++ b/trunk/Arduino/FloppyDriveController.sketch/Amiga Floppy Disk Reader and Writer - Amiga Arduino Floppy Disk Reader and Writer.desktop @@ -0,0 +1,7 @@ +[Desktop Entry] +Version=1.0 +Type=Link +Name=Amiga Floppy Disk Reader and Writer - Amiga Arduino Floppy Disk Reader and Writer +Comment= +Icon=user-bookmarks +URL=http://amiga.robsmithdev.co.uk/ diff --git a/trunk/Arduino/FloppyDriveController.sketch/Arduino Pro Mini Amiga Disk Reader_Writer - Amiga Arduino Floppy Disk Reader and Writer.desktop b/trunk/Arduino/FloppyDriveController.sketch/Arduino Pro Mini Amiga Disk Reader_Writer - Amiga Arduino Floppy Disk Reader and Writer.desktop new file mode 100644 index 00000000..32c6eda2 --- /dev/null +++ b/trunk/Arduino/FloppyDriveController.sketch/Arduino Pro Mini Amiga Disk Reader_Writer - Amiga Arduino Floppy Disk Reader and Writer.desktop @@ -0,0 +1,7 @@ +[Desktop Entry] +Version=1.0 +Type=Link +Name=Arduino Pro Mini Amiga Disk Reader/Writer - Amiga Arduino Floppy Disk Reader and Writer +Comment= +Icon=user-bookmarks +URL=http://amiga.robsmithdev.co.uk/instructions/promini diff --git a/trunk/Arduino/FloppyDriveController.sketch/ArduinoFloppyReader.exe b/trunk/Arduino/FloppyDriveController.sketch/ArduinoFloppyReader.exe new file mode 100644 index 0000000000000000000000000000000000000000..6193de2b16671d44d3a785130906c1fce3107427 GIT binary patch literal 434176 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 Ex(aJUh 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

    ZLe1xL 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�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%0D}g5i`9c0&l9BEd-# z{Bj5^c!csu@XtbEAqQ4qR=GxkNhyS^_{;M^Q>0rFt5J$&G7A1+U&Ge39}VrlPVrq* z3Cq^U$DjzhRoUp&Uo2B{baBzg(6bvw@%=20e4rcQ(~0tXgE`jdTKuiSUbQjDT2Gv* z`Q+jZ_zPG_Ya&q4gH{6-7-IA}R%Qvht}cZw`F(=`-Wcusx4f>qm{C%osD8aLV0?Qx}UUJu;5IOubM^MtQw z5%pRcNC%Wx4mSiCXI0*1z#YE44X&sXh~F|th$OZ@y{)8t9xp&(7ULBQkWI5kcOu}6 z{2{+W9$ z8abALtA`A63kFWz)f+OZ#l0o-jN%Ud-g@#PI!s&UF0Fv6oqQq~WMw_(z}a#7f%6g! zoP~xQMdEH9w*=}G)vK2-StPwKK6)&Tjo=5)5=}RHQvF9J=s9+FgJW{5*H%+)SG-*?)y26UoZQ52R&!aCq8;ZBwCrP@5INkdt!T; z>)5!H`hC`=dWLAOf%XH&1MLM8jF~Z+A2#wB_NDH!fd5{L&u?BhC2wb zk@UD;)@PI;@sM8D>-?I%yL#k|;y%@XkZ>0E8!3K$agXzxKjBuvqcS}DBa+UtUPA0q z{V(HAopMgbbZAq%Flqjed-bv&_U>}^?hfYaS*~7COSu)*G1Bkqcc@b^i9EP>x%y!f z{`aVfV^qft4mB};$b&f!JV{j(3y0>JlZrE%PO&yZ4FvB0flQ|jwmh2g>{*@Yp zf@@VK>qtM9zPKMG<)gz{j2o;Mm*LM?W!3Yq>t{Lr2e<&}1^xbRi|=p9XV~EzU;tR; zKWSTe1I@<|`akVcD|T;E9Wnj}+j8}bcGZ#V@HeF*+3IXr`5CTz1Wi>P^te@Zfa9tT zE2ZHd?{zj-jZSaflzE;p&+6~8_>M1K|4$-g32UYv7-~}JQ@vfWV9o2%@k(S^EoC2+ zSE$?bVzLcuHe0*i%BHU;<5z$F$Cs6!=xY3WBx`Eq7sNJU{!uk6NBweO zHMG9qso)MJ6-{zMwi0fifM_Kn+ZMfTlR`Ji#~U4VlSVhG z#~V}WW-8rGIo_B}H`D1RqjvZGNYA8nR<6Gx8xt7#D{CKK-!cW83qYmjp-2P)jsGE1 zDwT46vE;!pND6PzGxdTRVjbhX)3SCX#zgfEjscA2*qu4H5Wqr!BxjBz1c)I(iZdrU z1c)U-nlmRg1h5idsxxOw2rz;G)15gPAwV1fW;%1SLV$RTn~m88{(o6i?M~2+mfLDs zx+L>2i}q7B=DCN z#?E8k;CAya+M8*B{gLRr7~ODJO^vk#Z4nm z*0q-aWsM?PZzgTJ_Ch522Q%r=wPzy9t(4TLZry07bapCh&D^6K4Y)DvV>4R~>)7=l zQO&5+L_9=@E0S1I8f(mKxk3}TNmpeaFsxUt|5)I*o4A`h1a2}bn)2oTJtH1T2p*B>LXW6TbVEW~ zC9vjXP}Sz5s+yeyAEiE$D{d(NbLt~kiW{mYL49P3xOoRR7WJWtxbd&CDa;_nQ6FoF z**&T;OWRF1+9~QPg<0zMZ3l4=^9WAo&Wtn=DV1(;{4)64inGakp|rQ^_M#YPn>S&E z=$uWyFS>2cCRMwLDhp%>M9We~G_+&LoOv)kplhOjbNpbBD(J$-gI2b>pBjc*g18nf z71i$k-%^WMn8>WpkMCy!&G$BIlEz)@#q${&k?6fi-L4TIOmqfeQs+NxHLMRi-8OIf zjtwBr*w#)6Uw`%D`fMxFJ`FZin$%ye6MYhKg=Rx2FQ&e&yy_>4()|J3EV@@NLRB_z za&$?3C@EKz)P0Vb&CT}knaCzHnKThKhW#OC(Q~ZQ5YYVSvPhjFOCYbOvj;^(?14s< zmCLTnzTBX&S&oJy@fB>1{djxYE4r}{k3DI~R%bD^L%69_+<_d+E3dqgzdVpLLeFo> ziP!mIETBnSpdDwMDGxNIMI&JaV|M$SY@-@C%(B&K2LRZba9LxWL4vNdN|x(1QZ`;l zzN^S=7*rGMt#s(ydXO^aIryb`n%Qd@bT6T78&!lt$}@NZo_d5%lxMU3ydUl*JEe=( zrCO+!jfyPZ3HXM4;_GeDE&r}mT_dHb`NR?%cq<+tT^NrIicx;QE_6`c-nZc|tm#1O zb@2tgD z-@FmO=J>V)4XOmR6@b(b-^N;`mPf|#4c2RP<7U7N`&H~{K=UF=fBrVhMIx7)e^lRA z2k81!dcK~oYJ1Q-m?#ESH@0YZ;+c{e)OPP6!D5YM#x|wv!}i2=>`FlB;1*VeVj65_`8ISY_i6^+77T9JLMJi%S&Ws_yD~hA0+=`TJmjHQXATH=)!z?PvIf-X=jmQPkaLmG4qTvPx0eIjBt5BCDLe zen>Sdvm^mbGrWq919A|7+;$iV&sGwLmhpNp zh=~|AE-VfAW3di%Y{MWp-?o@0!~HS->I{sWLBzHE)eDgNH&UJr$l`Hhj%gSx{u_m8 zHTVS#dR~i^m`H2%MBz`bL^;}Hltyu}tat$y%4)}*kLIx$n+a#0v6&vvL#!s)PF1qa zR7jn+3BNSEzLJSrA`|Q(q4M1z3X|-QtH&!FWVT&41Vt15J;`ieG4;2B1l(UhwvSxRX> zZ(BsdGm7o}giVojcp+wLduz(OeNfg(v-=}AR#U3C*7hJBT)=P}#` zazsoxkRu|(EtrAaa&M^cLgaj#8p^0jMdW?2{|Nea2bvPL-+D!*0?)%;c?nN_104a; zQh2dIHVh7ofJVQRSJ!%w;;*hjrFltM%JNw=k9SWsj5-K9pwTa|loEIFoY`{qik{n{ z75J5c_tRNXRTn;=6&&8VF1%wv@JtXK$V(!_ ziD078a<;c6Z=$k1kasayuS(%nSl^)u`7Y2yRqvh8-CJON&OL9K;>%B4{D49Od8x>) zbQcqSfxHxq5lV!{#M2hyUz4gp0+F)JylU-dup1_I|NVGKaf+6P6la>}1yY>3=OSdz z@{%`{p0@$(TB7YvwbpIkh?bgZQy-a(=d}mx?~GldyhWi?HNOQBN=?UOTpQhn)7}zYpiT%JagoxKD?1{lFFWBVG1PzH%EnW<1O!DGNHl2y`Cmm2W(T zUWurQvLWw0IlxrrdyY`)@xV~(@+O{Xz?q5)Tf`t>!C(RpUJN+cSrI+p(9kk;z@cI2 z>;{}4qBsmV_pYV^M`YWDcr6B-A;Q8iWUq94ro=<2ubcx3T;y4cG}rD3$?y&gA%-YK zj*}T~Na=DY|GYm)`KYxtGpyN3^-PAGV#&yy5I~{h+|XksV5QS zjw9_L(+~el#blj$j0KPPJ{ua7`MX>WEBh*wJ&uvXiRl<(j#5k?EC`9z>6tn#Zfh9# zcfe)aXqaa^Y1m)BNjd@iHdM%LEZdsCe`1TjFYdvs*4oyeR9>6hUj>gN;+T95Wey0( zg!(ogQ$=GD{EN+?p>Klk^_n%8DBf#j3#SciT#pCDk)Je!$Ps#dL74QbJe%;e>yoh~ z0;-O`^O-3Emcj0`R$k|69hSGAABW^{umXcD_-Uown~_`c(>5_c{HzG`vpkxgcG##W zey)T2OU)4jo<9B++6nCVu8($_Uz-$4ln~n zM0EgC^`VBAboJ~E?H6!G&;e{KsRM{?pw)HgEZb`+g8^&^I(Udx4? zyH=sjnl;H5nA$Orj_-z=HRsx@@&fTAaVIq~#p4-P_P@U^q=}o$Lbw-s>VVtz6lO)F z*@t0i^mudoQ~qmdgk+y;fj6*bXn0-&kCyO*P}&#rE(GXBX@|* zBuOU8iSK3L{4wBx^J_fq!xB^xCg@t!5SgoC{|`9SwxB<;y>9M+!JygS`Cq}gKk{TY zCh5P(rg^umGC|jlVAiW^o#L0{*U)${`G3k93z*DsM~yafU%fbKZmg zy31i~qYRlrV`&1LV>MRU)8`x;vi@ZhTGadi>+@qJ?|o)abpj{dpwgL$L`1Kb#RgRE zV^lSO-cdwv5lo$~%@)6Inwn_y@k{hxX3|R-pf>^ZTB7OA3eig$z8k$%ok=g1K0Li^ zC?amqb6$;xGX!fOB!=Hj?I)Q#N5n{;U0MG4W06s<*j&@)Mk z-s>HtMfNjm(PMWG(4x_UTjjZb4b~!B$^8FTlW0L@fF_MOvnCz6L(*(&k~&!PKkqVW z{=cG0zAH^Fx*ClUrA1S4JG>TkJ%l!t+E6~wZh2Cn8)UrF5iF1+L*m@9n!XE*C@bK5 zk?gu0W7(PYu@lp1SWeiPP7m`~|^ps@M; z&kvLRw*lSjX-BEw?tkQ=mKNa?&_oaWPsK# z7LA6HZ$!ruT&_c}d+OJMLu~o*odXtODU^B|)e$P9OZVOAk2FTogYH|*p*U}%#hmq- zb3k5(Vt_fx9FC3BROF$-*f*k{hGy2PkLtcCJP7Bd0;cc_WaY>h4|MA9a3xd?!-7(o z?ztJne!E<|F;ACrrI91il}=(#KJ-4B&Vf-|^`SoyaL^`a6~%V_0uRXG97UL$ z+=ELY#%+(GK8&=g_BTM?ZVaHgFNSpoDr53T_DruuA@kzU^H<@=(7uGj?t$?`Z0mQ3 zBOq#p$w)w(g7F87X|EWD=OMbEYTna6ZJ|e4M8Wuo%(@v8rO@UCl#{ue^@jFW7}gn? z2TzEoXU>L)vJg+Miz~p)2JN}_pN1$W^PoE@jDK(&m1f*{X$Al5Ke2!#;&j>2`a+DR ztVLGl4<@YqrR-2sJ#}cJf&H4g^a6wkWM8~)R@mtdhyXC`9UhfXF}5Z zRX?OBJp?!J{V!?R>i`^JCC8rGO1`mtfR!94tmLJr+4K)uJJGV+$c7SMa>y2}>l&>$ zID6IFL%?p)_Tdih%W0PjXp0sE3BAKw%nJ0~;5N!4fIP+vb>2y90}f*+J={@)Le)Hx z_P3;c^&&RH%51!x?k09M0{D* zGHF&O!ZM1g{T{_kU0Wx`-78g`412SQv`!Lb= zIsOKFv^e}H6V#0yn$mS2D3I39LWHawWG{xk5b;lF1_RgwBUW|6Uk8CTs_|sQs*BhhQ&u2<~4bmWP|>Pq!gqPDN9288bjM0&SrnE#kki4s};!4*rL#W z<$^8P%x~mu(etl(%$T#4FK~iK042&(*uon^IYKC`;3fI!rJF_WmqhM9JbEFLD?h4W zPPqo{34Z8%Voz|Cz)t)A1NMKfh^&VXxA*&`80{+Y`lV5b`D5wLkoeWwaqoOK*CuCs zZP9bm+gpWsJ1Jhw8q3Q2{f(2;zcjEt6|XH`!M-dh=c|^|wrG+t*31Kiq?Jmb5Z)rS ze)OAA*jdUmJLS8H)CN-i-4S~0`yPVlHsZFZ_4}S7>-YU@VOD*%fTmQ-6;)GOwC?D= zP&%LdLQLGyQONb21#O4L3wfPy#|gT!LRy&=t(90%j;0vK=*DOh?0OVV&B-Ut@5B>%~67_|Um z^8$WJFEJn^g;+AS>5kJ7*q%rwX?0Ut(groaIzJwfT>%aD+?a!`G z6hFeha|Oy%e52l`61v8t=}o`54e-q4!ZU`ayUmVUx4x4!ia&fGT3ggHZFfMk{*UyO zA?<)>GjHk)YFJP?;}0WJk%G&E$l@k)*~XLa*@LMvBuUKh&#r@au#*Hw&s6O}VET7b zF5Ild4cz>4c=`M5q(k}@J;&z3z1YgIxk1;gRQ~1$7<8*^5x8)3*Au3qsM^~=X2qn- zPGj>+psr4%UnX*4H_0=&(KYeA?FD*Z0gw`S_tl0M@YLEyG~)&>uNIB8lgO3@7*FQ| zf<0B6sd_^eY6vNnR+RH`9oX6g|8{*ddGPB4BDAa-&f2aSY|`IL1jv&heYK3eF>`nR!}SV--~wlpPI6AR86%*@mjZ9x?`p_u&0HI z+3O}BS|d$y^IH(A_V;1&DKf#J2QEbq3{h5EX^CX5if#z)+QN>w#nea8;5;nqt-snc8YS^ z()SO`tF{Ny%4{$;Q`7324J2oNs0$51ywrJ0ttHQi?GNpb&53a~d+qBR$>uxTe4lsU zhW)a)gbViv(jvS2nJ7k%53&2-rp;5#;*9ZK;%~J2o2>pXtW{qyQKcj@TV{|{bdNPD z7llZ)y!B0_NRmANH*k&@!SGR&xlZUpB22zxkiLJAG^*}nPm_}8>Eh!5X2ja%=oV7` z=p1Wghmc*w>=rFTRk3&IbiIS4cYFrv_$l#I5|f}Ivq4fWGp3)Aa{oLc7b5tfXa9rN z70u6tZOuk!TNMw7n)(pJutG_x0~Yj2v*SNiqCT<&G9)Y2R1o&Pv9N27gw0?%wRpa zDz!MQqAx7#vl_>0)6oo})-iJkA5Ow(}t{W;w7)w&le6|mk*qo z!5dTjw-kVGt?C5ksDM;J-g9sMh`gGFZ-XlCl5GjpsEx>DRI$=e#;?9#X#anw=%M+Nv&M zv!v&jXyggcFEm}LCkM7`#%T2SHTHSxBR@omo(8}Stq4`quF$(y405{YL6Pv079f=j z-#?(WB86N?@o=gqoazmy8jyMnIq+uFG9;lP7I+L)qGXYrF;4SgNE}8H`bN*FS!zd6 z$|gK50V92@gTCbhY#3A;A3K};icEM~X5q2?dW3F1Z5YTmOrQ)V0wne)LR|ql< zmyyU)r%gr*!Ak<;PfgUO3qZaJ2xvuS3cj_&5QU<+3;^fPgLJ8tTC{1nodufXcz>o4 zFPVqT54xv9!^aSr+TND-9bBMrdqVVsetKP zHmGny!u}Vb+wd~otWDRF0OUVfN4lVDkD^$%GaDRc?$!;`AOFc1)qgwi*=CYzW`qAE z&J5bz!1iPL5dbDcu4`FH^L^M>$27{0H&&U*uWOWTgQzB^A*K=8>$FVDNb_-;@`T;k zbw9yaUyuqqYHNwT0uiJ)75J9C@1(5d6LYM3PLiS7M*o|__R9$QhBP+}CUq;;=H@*$LXB%XB4WHW z=R1k<$wpYY%|wTG&|AU`;sht>?D2ne3hNly{DRQyJQ4C}3Y|rB6?LY0eEl2|dJPDP zolYR8N_r=RTc}GUMGO5B@;|LgiZT6F{2CfrEf}vXT=-=(g@c&D1Qa9p@!HY1;z68m z2HQA#6H>8<;`Jji1JV6igEkh@mX12Il#cg+@4KC%qbp~wurMG9%UXzZ~O^GT6fX562px&r=>PbD}6cA1tMr5I9l%Kle#t}70g?gkF%|K5e)${oHd~&5`%G-&ik0&e%)ez^q4VHv5 zo0bGNL|76BSrTT5{%rPbG8N;5EuY-#KM5~e7AEUDgKwDzvO!8p*uNY^E**3<0`Z9< z#bG8)G%CIa94(41^DxrUj$L+jJ5*60C3Y^}lNh0t-=i3@@hv3Px# zGORyY13|AmfPP7?V0Rr_y8hm~WYe2K(H62BhMeM1gwlm$&gT7zmg~v8k?P(wMHn>G z2L*+Q_{b-9my#J<1}@B!`KoKa(~$Mq8{v^Z1shDwk^iS6DaMroQp3~CaxxpbZ;I&g zQ?S0K%No}0x`8m^QvCrivz|*M_52-PgfT0LKl~{|Rp@)lfY3QB?nLA~m?I+RbnMx5 z90|TJ68ksf|2VG%M_gncEM@O!?k;B;I2TMWw#_KEs}IwtUg7^J{%s7nO8QB7pw-9J zKU&wt%0oWhIZ|8TP-_utOBt z1;lyaar+CB?A;^X#vBLF#pDhJE(s8$lnPK_7AbHbUf#~LvLai0kyVamT{ykN0rS15 zvFn1^JdzYFSvsMmF>yW1c*1=$SWqXXqy=>%o=}HiK`q4-7QhE*0E&1*om?N2 zD6~FS8(9RC>tk|tjn>DobQa1bqYyF|MIma@b%?vrnK?hSpD79vVF~MlB&<(HLviO= zmvr4cMu|S2=``;? zX^1q?EvmKhzlIGOWye-K{GMSn7{8qc!LzEXC%&3nl&B$4x?%!mb>#D(aYWSu)0dup^<3I@NQ$V+7XX^ zFeCt4?I=P5Xb}ADaLR3___EybIM@Nz;>3bUXsgWQ`nF_TomH5^Z?=(`u~4+1|N3q@ z>-h}|GMUSq9vVWL;QLbmoDG zD~JUy3M|<0Xy6jp4-ufy3q@?8Gt6e7P(%p03lSI@$vP`;w_{uHF@Fi1_r^47q0t)0|RP==jPK^66#q&fPw$B?euoJ2BR zGac{3jD-4O9kaQS=o+EZn75yaa^;+9&GZwWn-e6% zp3PcfcjG+Pz7f76_<*Q(Ln9Lw&VO=BiLMc8Y=5OvWwlP~j+r`%_JHvJ+#z%}xJ^Fg z|BHLJW;!#71sq{v5IkMzp}BY!MW8O8ieseoZA7515zkmDLgm;_h9WSz6zNTXYcQ#+ zFG2*@;1Yy1g6H9JYR5G?gF zCWJn1cb#zofbdFDkTc*-$|{Np9VQd-ec5ew27HwsS~@edBX9`GlFwL3yJaaG7Le<- zj{$b>q%QBh&^(ZZFmdLQsA7G9a?3XEK3A6Ft}vDNmqj5;HV8US;XD&6xCYzE9{w@S znKYu=f>m3C#vVg^2AmQRR%tP`e}UKFHbP>XNp#RwP(n+PBviv7d>#+yoYr>{PZCg)R8e+?$c{5C z(+BK1@h+6I*_jHmuyb!ST}>%?(3=sPqZZJF94DG`BpgNu+lYrG$L?{4LC_K!0+E5= zTnGsYZ4ge8ztQghEh&pdlA~&3nl1W(Y!6A^e%bY;rbcrrR{GZVqh3)yI}zMQ%9Vap zs&mwuAbZcve>sP|He2R#tdy(%*%*p%7pH`U21r=TF=ATdZ%B)kEyEX{FNS3pf2E*1 zU|L|;<=@Tz{VpuL4?iT~oz+ll*7XEj|G_!FZP-kR9yVKI&TRk4Bk6h?iYcZgL>m7y zypZ~%56JnK*>o3zaw#ZI+ZT;l4nF1sbKcRlgtChPM%tvDE`v_qkq*iPL|neZXi@iD zbH9SvAth`w8pdA2FS{C3nQf#;*erD$!Zt`r?H{1Kay^{2gu{ocMEI~J6h3?p3}eq! z?lorkkP3tdhII)B3;xWW*ym%udsB^$ZmNkmuABn-v!)O4;h;+?U0>pd3BRPE>t-xp zno@o}{X0qdqSt5@dDSv#GCo|GO&bF*x*tW%X@J>WJq2LQMLie7h@5 z-!8OQanP=vG_CrZSyl@-m5QSO(kyr zC^|rZbbzdwc`kDRXISHJNi$#c=0M(Q)+Od!R=)XCp&J*nILrcyteFk5Z9{iZl=eseL}N1mDtdHUDQR=lZb35@%8oO|O<3a*;X*FH#$;U(Pr zN8pU>CHO3ZXbO~vBZ85O72D~P53Di4lPt0?T^68AhRqW~YbWF6yN$)#+ujby0L zPjlc|lK(*vzk=Tej&NMnkHyKo!PT?*UtbsPf~rfID}}ALv*J{}Fxx1csn5-y5$8){ z71-VCPCuZJVTCEWjTKJS9c*T&4t-5h_hech ziG_QGof=koiN-?ECeMLVQdl!~F=y`M_8$nl(3C396CT1}h$j$Y%$+&I<~z?{on-NW zw=4w`#^)$p4u4C~-%cK~%K-p!4eqhAYy+sm1n{;r!T*D(74fNrM&?TL;XP@KcdWal zoaFJh?V+Yv6qZpMz6pYU3mFx%Lc6RwA{U6{|F&F?eP7BYDH3uCx4-}XEQO9O219D? zKH}2nV1I`yu&)svB(>0vs~exgg9j6|gK8~J{}CVN38Y}XtcjFEYgn82pcS3%T4%?D z_O({$sj4`3LccjJNyrIhl)G6@Dz@j|Rs>3BrzOK9Pd_!05OOju&A>BDM)$=bWR|FI zSFn#=bP@se2ZC>rx8i>%Xz_xg57kH4Kp)oHF!#{zMT+S4Inv)_O%uOj@0y2M+i|LE zDm81hL-(d7GeuvUmLfR9i)pBsiMPX_z)8)Li{RRO1s8XKpIJzK=yf^!1V3MapT8q_ zQYrd)5M}YF3d4+`pQe8`5f5YEA#Re1n`AAxHtoTY5Xq$OSUT%FXEu!eSa*4)WgdSW zALc-JP4D&pLt*(KY<^lwddtN3!emGFPtr*QXki7=8>?-g0jKvrIBqQ>A->U>4VeeS znfz#Oi3&+r97BX!QU zJX$5&YPYK0PHp9~r=wz4?3lQR9SGBpqG7Uu@12gi85~D%Is?1TMx48x+gm=bf`3oa zg~Hbg6~bZm>8DJh{A*^TgL;3AV{VPSnZojv&S$fv<;kNSmPeMy3$g59kC+Ey)M>%0 z*&a$ExWm8y`|(OTz7FGv?PdF~C8+NQ&c4-$F@}u;UIpQd1P`r5c&l1?XzL%=)x;{2w0zqdr}dWH`_Pf&Arc)4qB=8nh`PR z(vdmf>V)>-!ofXOs1M=bPZ{myE}*k^%J4O2`|sc}JTd0ub!F|&wyN_G&G4VXhi*Cz z*CBl4=1`sZ#Ek{hz@QI@>FvUIXLjMcGl#f_kfpzxJB(^bu+u05cG)4rhl}q}Y!jAF zDvavh3b0uH1ycJe+~vla?26#LWItEDBSoBGJt{X`U(9f|Qf1mBxD_Rq9b(n{sPc3i zTi@vnsJVRvrwVYGtgAEIZCI~CT>s;|@d_H0uf(bK#FB$p(!LMH^tZu|aC!@DEh|10 zIq2`!fv=0MUfVs-&trV;qFTwY`c_7FGu<;^C(*!)_oW|=?bVL2Gta+8jp|$ZV}f(s z{0E}@+wcsB813u+MBR?la397iWiP`_W1JXrE`Kq-o|7>JMl4N$OJTws^l1fp7YF(%hQmlPm*c}AGi+7g z^M4ccV%a4p=xp|#hoXbWYUxxv7ERJ;BTf$4^ zm!jxgzeB7%#h5d5#whQ!3bxK(cP@)}HhM?v1#U@kj9xHbS5f*>^v;5*SV4gjDrWgh zpwglu(S3x!64hh+P2y3#FKJ0;gL%q%!uN!b1bL|yq7O}DU3&ml$({`Y2YO zicU4hqK~SZgtL5c?7BE1eg7q)yyRP{wSOmC*4d4MnKR?b zGQ-ubYUEXcZwOf)Fn-|T5cg8va=?mr^8?R{ufc`ye=F~$J^PmTorKF9h|9++hIi7L zWm&VXNWq}o#{ZcD3l!IYm+9E5=@>sJ<75UgCm#Hz7W#_N>dR!0iOjhm^~fRmk`?hA z@^@0ic)HjgyEv&FZm#%#$Vu{H;Dy0KpwYN6RVa>a#@wu`Sbc65E41V5Fojuon3~>1 z4)GH+Fc_+j)IdX4TAdxMA7Eu^tT_Rtc+WZBWbwxPF+M5YA02Os!SOn~y$flejcuk! z=gCLoSVan~`FxbvE?wfXG{U|Z*cajqaW*%V>U6{=($K2gV)ue9Xdj%#3@9FI(kJ0F zG2NpBacIaOriAh$++*^Z<;RU!%ThSW1r9kv!7UE|h2>ESOHx6mB#YsrM;LES=I0Re za{#on#mS(hfcQ@X|0E(;62u@B^@pUWNy0EwECrM$Kf(G~Q};sF>^~AaGgfZoKi+Kd zPSD^y!5z@vCB#5_lSI7Ycyo+ei}^9WT_~TE55pQm&lAB8-hYAwiEVfUj@WAZI2U<1 z1WBgGaHx;auz<$sTfK(75*A3nWA9k1*9wg|hI~yKcIZ$LnJam>Og$HAS|Z zrw6jd)CTR5?GVmEls680Ucv59VG}@(3!e>uId5{dSH)qFhq)#%R=7jQb7oq77qfe_ z@G5(5uk*`Q=j!)nv3P8jf;&4EUj@N836?M%!>Tkd6_d$ubCdnVL#*@`~emGh4nw!O!dsuJx z-Ei%K!RxE08`kUTE1a#@ik*ZGBWJQ++z-3_@EFk5{e28wquo3&obM_eF*{AK9yF2dF6IhxuY#^n8&%?PN|F;WCE5OiJge`+5Sd zUPv&s&&B*wqxqdie58@hoezu{VBjM>zKQT=7!=GqmK9EME_JK9OWn+o{z2)y?n(GA zk1v%KP8T!r39K*;W~neA9lSBN$&C+^@_E!q!+bhyU^?_jstu;lC2VcO%x zHk(364NOj;aE0LK5mJ1aqU~lfMam*lg&z4H&+6oGFy7TmlL-DA_K5;UX%?^hIPIyi z#*1SF;>9khEqeZpey}qR`}U=kV}X#7DZo~5MZQsGFLE^eUS1ij+Wn);XYwj zZWMF=C>APA0brh&Z9Sf!VUP38VzV={jIw>$kdFB`Hlv}th>fJh`(ld^F<1LISBKm@ zdgkSUqd%p6d_t7m`6x~915JeFuR5B)i(MQBZ@EnZCb|a_8}Cb9b9`iTWl9$yW6mAXkl^lC|U<` zkQ|7@v|u~tv?H8l4)08v@k-EMX~DA z+d_+?P^9Y4u&BkFipmWd`LQVaoLease|I1aj*qA+a6i4`DYH=)*$M;cpRJ zIIskJ%5tPe*`!9{j`R&0HR_m98!69iXDiPhym{|CqOY^*>+CE}uO^)&F~REM?$HIG8* zYn~87?_t&4tlnJ6I-Ss6$OTN&3egjyc^Vp6fh!c!N|qzLrA>BA+>v~-<8hSimQub) zBJv$#iA`~p1T13D+717N|2tqgaKOY=mN&XQY#&co9=jn8jWP%OlFID!j56xM_{?@H zMX9DBDjbPY4gOGaDk4f169>mGICu$Mh;FF(;xO}wM^Z)oP61hb8uk+5hV73ik za3s$_{^3OXXV0XHTD6-*VYwk0Mmc3sEn4Yq4G@ zK8I-|v)|&f(f1{775s+p;iJr=DAY&tos;B0=~($a7MBxVdL6j9!tbU9IG30gn$?+FU{!e2I?TSdJQWh8 z*+0M!{J)HdeHhMpLI`+^v2Keo=PBWBWNZ=J7~+NLf`2pZF8J!>O1>a?6to|%cCCLRB)?F z<5|dq`0EYxmtW3X&lyG%Vg4WwgvqDNDK6~OWH$G7kAj+d6@)U$_X&=K zoZc%Ao5N=4eS)!vBO*_z^i=T2lFnBDzIDG(PM>k_052*o;zSJ^z1fG+WWcnJHpz&d z_z1VwG(b{*XW<{Pk;8a>k(tH-Cqb%4sK0zWf84ltfEOeA6Hd$^{$Bkcn!jaO{v2nj zX4I@_D1T?(Pjz%qTNVtcqzL*y_RN(G;ny9pe?$DE?IY>F>>UpVUVYz+SZ zn`KRg*qAf6*>Fn^vOX+tAA~l zT`{I-dE=)wbkY2mt(u9A8MO>a`XaBNKs5Jb`59Rh&1mp07jr{ed#CA8O?8g~lTvJ> zqNh{XV!Y`~v-~UUv2FfVtDDEw3gj4G+7X(taDD(U$)JST;pcfowIB}1g>}blwbbEt zr@`k7ijZSe<01+9uwqAgG4?mmSs=Oa1O|VvofTs*l3llm7u*Itmigs#>^Nes7bftgVGk|xlDSNKhJf$xIBfmT`7+NXh8v+i1?evTB2s|ar= z^I|;`Ux!C*sNans6fG`_1;tcaP`rTFX(rKvVsTx;we(qGx$61;NO&e#F~h>3!m2w4 zEgr_#QHQ0)!wFR9Qnay|?^!e7(rF>cqb3C9Zne<&2G^MY!I0p`+-&w|@B?R&9q?D% zEyj(>rHJaI z3Yo-v>~!K~i~HmTJ}F%#4&lOnv6tiAeSaT*s&l+@<{CT1cd<2W&G}ubyky zbCKxNb5rzO=-DwncdDM7L7RGd*yt^t%amsy!;gMrKKNd`L|-^N^DlaCb|6=(48Pwd zMLT>ZMMi^k}t| zLSyF;k5JL<*(4vmC|h^u2eJis5DQIUL`TCKl|PGCaA{lB6WGQ0#K8WCfUNl(i(A7y zhdeO8H4Lzq!&zwE*UREcWLzg;jT7!fc$k}pZfkCf4K08cS!3Jy{&@710*6uV(90+w z6tKn!7bPa-p(Kj_4tSi1=EVs(oSG~8hsLp_)d0OEti<6gNvgVl=3=xbCr3=jHei*- zn%I(`h<(k%@PSyEPt3*oaeQ$yC>h2ahV;ROATQ!wu0F92FegbbKIS~R`V#hcnyJOG zNfqu=eVv0(x{x#i6Ft1B-4dQqn(J4Oh@A`nzzk;nH#C)575^u?V43NFnA#lpS9%j> zGA7h!SVv)|liPv$O0&PgqW-M$#QO=Y=8W)SES%A*8AV~;d|XZpPJAa--0fYBC;lTx z^rHUmMBFBn@PB8Exex75rFAi=v>UWyYQ^tKMJHHH(;svoA{w)>m6sYth|!&9=6SA| zd2Sgc{Dr0ZBy43h=gR!9M{)A(-&SJMREM2^(prlCL|Z~Aicyion%G?I&BDt34-D(M zdLeebP`o6D#g`k?Z8Tplg-drXc1;K&PQq&RlBL*e5}q)#{S-PZ<>S#@@&Vc#<=Y3B z|NX(`Q$EyD&evQpv~+sd;=)F;{g{}S@??abW$BWB8h%g#P8M~rB}DF3{%;&r6I4f> zni#Jybp#5<#2M`^HsCbx5EIo_6%AC_h%p~s9TVS`=1g@~3IEacp_yvlkeOfcq2f)T{TQFY z+KC-Z!>td~_Bgzmos`}9ag4cGm{iX06|049MvgeuHj%Y0LEP$BvK(p=UM*^s_Thh{ z?So@D`#^hld{vd%5HN(z(+<#Bk1dnlrQ#4K?#0_FtYA7ixL({Nyez{-u|+a&ZeD;_ z?4jPYce@)eSRhad)lMWda;R+B3DAlS)?TizG4<$cjZ-~TIH9ya7=hm!JkRD|P`w7NfB z3<8SRTZvr{v}1>VITHq=mkh*l@A+ci#=CKq7E`=@$6g^_+P4yeH|1QtCf8tg#q?-b zYM>w0!xr}nKdL91+t8TRJIt6BnNCUDIB+NmwFkvlBK*Po8@jqCRv$u6IC$nMFaJt}%Srib zs^KMG#NuI_PCGsLY;|NM=!$)z8A2!jJ^U67aaalJ9A=^vE991JCkh8iLmcs39z190 zm*L?rWvwcmMjG(_4DaydD(|+L3Wgm1_=~o5RYNsAQT_8!0`?g zBvWJ=XP`-xRC!60mnrfxl`j0VRd}h>#_iWY%MnDjLXM`E$49jMomQ#kg{0-!?2ILr z480&LU@j`oh2iNn4G&g6#hMD<*G2JUcv_jGGL_|G=>(5p-h&%DSaGi~LW#k71B?(& z2kMq&W4Au`U$j*soQw&a3lt8LF}w}9ES|@xf8Ns)dJW0+$IfFVQ(27Gur9F(TcEJp zC%m~>2sQGBFQ!9rocg$NSb>KDyuQ)$=PwOPM_pI!?`R(Ew^ z7upXhNcryv#tiYu=Xf?17}?L$@AHIA&tJ!LnH5_Qo%h?T94yDirq^TItu>+wGGaCN zCn;VBe;;yn-e<2GgLj@yj9&qRp*DKepttL%xT{R&2d_5mqwecKhq0hn7Spu)2J)z& z>dAOVWR#JU(mkS{zSrwEiXY=+@4=gXu2%3xOD68n+h1`D?q8_zNB0Q55s~%+8&Px| zcwR{3F|H#c1X4~tlP7>eHeQTv!Fg8wN)iS{#`iS=9v#%8i6I@l-tdj+l{h{|m@2ft zzh`<_`u*gl8pRzIJk|$|n`32*J6QE$EF~^Jq*u3VyVug@jRx;^IF~y+SH;)7`N9$K z4cdajX-V&$xW{?&!LfMx;O|xT*bd|x_cii$j|sRAk=h4b?f89=?`i;fz3cvTFj(Nk zM{kHkD{DUSaqOPhUhEPd*QomrGhaKlhdW!;N1ua$*TP3V?8L5aKkYZ*e?pD0Ah)8x zCr~=JHnuTr@BSd&by#;Do><(e!{!~p7ui32A{nR1{9uG*I(Dv}V9l#0tcS?Q|8@uc zyz!UBSmhl0!N#fL!?8zMS?9Q>*pn#2`A5e+BlaD+Kp^~D_!H@H-c5{tRO!eZ0+ z=vbLXAZcxK8uKQn;!T$SL*2W_M^#-7|C3}$0z^*KfKgGY1f_;560B%I!({?0!3mfI zFI;Lh9aC*>$N*J>iIYeshoiLBr}lYlr7gC+t$j+XK&+w(&`eOuMJS@sHd<^?Or8=T zg@AdO-*@eO=8_Q5zHk5e<@3qRnZ5Vfm$lbkd+oK?<)SBsfT`#6blwy0+#`!qvX7u7 z*FHq;@E3Yoxf3`2t#bsQ-2W4|qa4EhyY}8x4DJfTn}c!TV@}J=7}ZEhpgXVPp;G1F zjJoG3b)OP8w>)?K%*?#Hg2U#_%n8oPa)enpR#B>p6r~#BP^x;*;krZ&7}^IJ8$5?m ztkz~jFyW65XtNla7<9cCZhuj=EQ$~ZrP44L`Hn__=b*m?3%fb=V7}_XT-5_9Reu+~ zC_3!)V5B-E&-R z*>1C_)f@!Fe zYpgg)y_{gpKeK+P?$-xiW5r)dO*&BhsX7l`ZA~4SyTy2Fhw8$e|1C>})2Ru!1jdbL9A-*kO^U>Z^8bX-W8D0z&z_b2}@(ncZAs z3g~x-wFqI!SCe>h4wKVI=7ttS{)Sy2IZWOj543Q_c_sF#u_{jk4M9gR$8z5&GJr+y z;^5R&`y1&BMkEHOx*ayy-u4wb|03qEPJf|ad7q1Zon%P~vp(wO~!Qc+RSP^0E+F~o|z-5@zp*IZ^4$8Mx(JdUXfR(wIF-W#0P z(bSq4^z7A#@2k}{vGG(AxrO#e*F}*{7HbS{!@vU+kT>gm4L53HOM*ZtE=DbGsbkH}Aoi4|D^>4o-x z;a@Le3T<9Nx$Jk&Zh<{V*`R-5O;v~TY32v0P7FTjAmsi$!N@%NYNb65QerEWv;(y4 zkMFb(Ent$b;|9TAUn!!6U0$#KsLk5;cR+*fj}MERlropydR{;Hi{LfY+%-pz%xWTq zQs5fy#_WAe^odWhcf`$W&zV!*=}dKrGu3kwvUfP8&NkIoJ5&7*1Y;^fFg?|X@?6&N z+nWBG*oUNaE0WUlrRXdl={3s^Nja$Vdyy2po~Avesfy!&j_oKl2!q+1x{L=d2rwel zWfVXAP!~e87^+aFc`FB!DNKVJqP{N1xDB%mKyI zwZKZd&AKfqI96sE9mTYq`N0`bl%9wnZs2^T_Ac~x><=FAJ$ah`u%2t;*Yk`h_t?kY zkHq^&*0jhq6Eu|)#+xs9_O%k#h56|-s-UI6X1}~!Lq+>FZgOW{5m+pp;D9F zM zAyR%(ln}Y7vxFVfyalW1S+ZJo#=K8K>$RVpwpiMvZ{aM$s97kBWmc-iV%Z5ra*8!b zrj*rg3nR2~@p-SWWi1Eib+gB|W2rjGjI110+luq3?VoqCRK%Y_u&MYHV71Eiv2uf0c=%2c{=ro!yv4jf(VmjjoZF41EtdzOGcFIVaV`(u zR1>{#babMBOM+R1+|x0mX&=Tmm0oDSLJ`ts6I1M0pt4(CtYApO6PK>6z98M) zQkSNyS`f_9_YG;pZ~21eEsjl?;;%&aFakfhI(8sf0x$aHH3GrMGc5Nw4xygz zzz&103&6R}BY-iaz<6?T%9{=tL&~HJFygJK&mBwzj3^_qUY@x+3dY?I7?+L={Jk|e zy(a?3hbiKKv71$c45~XgHJxjZ3}LUaoMU3gUxd+vzcWzTg=Sp$?D8Trr?|v!PL>07 zIviY>LuYpyz@h6~GucxnH{+tU|4?)@)e>ljB!Pe^GKe=0fpEHuGwq^imBseYqZLw_ zxh0qzEoi3+fH#)#Vfh8h8otU{^L-@DQ78+D#p0o;TS0kbFDUo?8=x%4iC+7QS4E-B z$s1^PTYaINOcBxrSsf^IzY52a5dp7;ZO`oTxeB&r$UiVv2B5$;Dde^9CIL$EIl;T~ zaKGTq(6v%!v7H*N@C@+&N+3J8n2&2K6cPhpm@Cb*UgPkr6UZ;LuN}p>oJ+pJ(M!I0 zTiUu74HGNGf!s9BYfGh6ywFeT6J?InD30`2B^`p)p#V0PS2zD-sH^SgR2C(EJeUI^ z0m*pHPY9>WS=0Bj$SYs`O+;Sl^jB8PlBr3Jy5l2N#~0@m+TYHKb^433PGhp68ST5t zXQt%dj9&9;-%$iGz7Xw&)IV8WVP6>$G+f;0jF0ggf(CgRQ3EDZGMMoFX?hfD{3vFp z2eui-CAn`exl9bXHk&7Q|05d`xnzjtz9qM1fib1UY=RmuFgNq5Usa#|%Rj3-ylf}x zgj|GCEfgd>G-))~D8|a?1uYlhMZkF4%_0cn_@Tg_ZN6vU&skq&ip@>kiP<}MpJq)a zbvoNP6jSeS1s%M=ejZ$;{5D^abTr<%UT!Bf7gr9&8v;IWIHrZoO4Mh%X}|q^zTtoD zJ0!KpW+9rJX(G}uOZ@odo-%4aqEpriwex#Ab2l3`yJe}iz*H3USkHWL60V`(p!Ljt z_0YOXZRtTzhuLXuT1T4R(=B;yYD-7RcJrNFFZ39JFH%imc9Yt^v3kr%RGWO;9a8&I zJ-8DD4Dh$cI2$?Hb|bg(KD0~vlk^_@E5on;M1JY!%%dVGtf!J0s%1;HjGjRc$1V>Z zL2OgbPaf{J@cVHH7c6fg@d{M-BpNH_5CCASoAg+ElsroVJkAYapgVEdY?iyzUZ-k| zw&2jZooD(aj7+ChE5pt{;Z>EGJ5R(_Lr`zqC0$WgrtRz|*(a*o6qpNos!w~71ylx< z5xhulO{86(Ryv&2baTcKR8|&c8CO)%Ul*)~?t;1N*h}@+Z)xyLQVUw{<$o2|Kb_Wk z=|#2XxD>dZIqE$2QZ5QRwYPB;jkW~-7m8r9N4(VJwp8TLG5=x}x{I^l*YZ7cN{=-= z%`ERWZ|@3C5sIGL~GM!w*U2KT_a@%_cKLZX z?=Byx@F%ys{BLjzxknaVT>ofdeR1N=`^wXn4AL>WbB~n&55CwDqVEekAX zfrW_4bpy_DR0BQMddY}3(4(V4TAL>PUC3pRvt(&olMM5yT9>$KT`wifQ*Cm>tqv(d zRM}12{zcBLU_XAsX*>NxO>m%xvWo@!?^QrRs?P@ev;M60qDClat z2BN^+>bH(sn;N;!k$fjbrm3>qS})0}jGm|X8a^gM1a~Cp(j~|_itBCpTu~YIjAI*0h&{lw?+KrS{bf~-j;c)ueo?O%jV{qi?89A z>cgdt4}~QQNo~?*y&RK1O*%%W3Lwt8P0NI?nY(hE{G(YqYZLrmc&JiC=oPhGi#k*_ zdL<@xCVhJBrJIVnE3btEu%?6~D?I5~{j5ZGu|>lkIwh@X5baW>J>ARR}RI6`v?7|fTtGR<}G{S!Vd$89ZEEmhQ`thxD?G ze52(dr7Xpl$3x6QNqO2zcG*4eF;C4(lYG^t-FdEU{J+cp0sas1|3Ca6=ReGUDnmM- z|4aBE$^RJsZ{YtH{v$wReIS235tF}FcgRg&R0P-2>-zj8M=Gm!BCMOT`oVE^aQz5= z+5bGPc2>)hJp1a+(aSyD(FD3LHC80BH-xilAKnL)XZvO_wzhwwR8f}YdqJMt4LwVjU&y#%P<@xvWe1~tTJijK-Gkq=c{404b@?{R=`Nur_WcqxM%Fpjg z*4@5td45WsXZz+}#PehFe6#OmdH#kx7x-*>zF(g2@J-0%xmcdR?5mOI+vRzRuTh?F z(dAPw=9xPnSJ^$jx$?|0kBEl8SLOKaAr{2WFR-XPk}1l~ZW(Ri|4YF5=oO+k$(=Sbph@qRdr6{|^WyIJ=GmfcRS zcmQ?qiaDYfKE>(S26Rs7*yzht#}b{6t!7{7+p+DVbjPwN+IBykDZA0vK_}ZzFy^vx zz6N=2m*+cuK6w_WDnKA`Dw*5DJfBbA;~?X5TArv|ZqzL&IW1q+Ps_8NmS2_{Y_^*i zTu-3yO7{=yO59E*9};;$cOUCe%D27P>!r>5rS!|ym^jqeZmKh6JU{>M}1yL=zzUucHfPh%QqO24COd1it?xoY{vspZqEmXCH-+)}kX z%jF;6oPTu!A#s{LpDq>ufujk%RDfE&;^qmIVHJE@=nW6O>w$aZ@I44INP^$poS!A{ znDd9rE2AjJwe=3$&&?3YlE&5j(22YQ@Ia?9*0Ig`m%2(r`OJ54{_s$8BOsQ7LwXm4 zv6`RrhkI?~{dkeM8c$}F+;y`z$Z*i|!dHUJKT<}u=(14$h=KfUkPq};x{<86?2k-_ z&w(7-ZkzeDMI&xwg6{pV4^Mf_^czsl8~I`MiL=T$OJ>E~Aj zE*KVcQa}QTSOq5pF867;Obt|aCX`Q-dakcXrY>F=BZ&M_Rsnip9V}Gzm(;uV69>VZ z{1HwMuZs4N)?sB_4f3ISKi?i0&5Y~>`WtvucVtm%6eLV>3B$Xg>?-UOAGt&gk@?C5 zL`;hEYN`CPts+PStm_nePs&7fl=psP|&^NxkxJNHwV5 zR4vNO;XOHF=e()s;4TRZ*2){9TKSas3Vq^c(6YMu9XB7>RBuux$n#&GLulfa1EfT5 zi$5K`YEsKPB<%b0pP{3aKLX8dI;;StMvyA4BYT(b2t@Ke3nIGT0ul9QZ-`KX0}Tf@ z75@(q5!X#(nj&kY{g06~qSi-NJTf2xDL7bC3eGLPRb#MGBR8jl#e$Fuc4dj6bZm7S zH8)TqP}zaQuWX)xzOqa~F$kX$7=3#>a}MbEg=#*GnjqEmu90=o6`6+<`!8)A>FE%K zunur>K~-hv_4Nf^^+m_(A3Rz=?}&d?)u+Y&5%pWgTt6{&NoLilF%<)@mK~LwO2u?@EcTnIp4sn z+0%)EIhMPqLUk|%wdmu(CB(3Ui1vq>c85sxA!f?fP56Gb^d|0gmL7z2l9#0?l@B1C zQTV+xyME99Xr)e(q9ay$f+O##Pn?3^mXjQ;EYFebedu%4!(!(&M%&u8C)!p&M79Cg z#Yn=MbC#v=Dx$YWxus6o-sDK{H@+zTb&GKYw@~7IdPj-3uIQ&h&kMnM&)a*)gI{PS z-z;p37_k|(!{EA9$S2izq1hQu8x1m*(bUuLIwM-1fge;HdXif<-tw#g#if7)BK-vC4l^Iroz%Sx`G9-hKG(-l-{U$kcO4B1@^A8^s@BA@X%?}3IuhMLr{g{ zLQq9ZN_(k-prWJ)H5H$_`=O(rR#nDxP|Acn`}uT*x!LW9e2y0KiP#U?>0!Fn+p0XC zeHGpD91^0#+xu`4eN^#3;$!R=B!ZUaq`WAq4N#~i%U`#y_oKsqj6=2Lev53^Ma;`& zOBaM1Zl;0V;9NBaJF{`i7$_P0!$8nxn} zkUKlwP}Ui=a&LrILLZZboGjX_2-cuw+Z`Os@a27(b4S&~>~%3rE80cdoES998B_84 zoR=_WEGc#QnPlmdBq!x!ol>!6hRcj4%Awy#}c{x)i| zxy89%N;mIS>MIzmDfN|WxZVFc#8RY`y&W?+`VvQXC|nSoxi8%vxnGp{2dN@OMtG#m z1Y{nyg>6~3eb4z3mdIdMg@aKN4epJrD${W8ihF;fng6lEBwh>ZN_A~Y>=Fi~}?aPbw?M_*kH@)0GMJO7|T#Q0#8myFb$ z|DsD#X&raKTQ(9J>01g5?zQtS1Ov9Fw@*QWp0n+h1R>4Cc={edFwt`9Rj%pA=?NvCj(iQRla*!BvRH zesm+%T!Nh&syLsK2w`fFkGAR21!~k>C(o0F*XCNROtasAk5mT55?7vsDTB{$)E$Vv zgVP|--vjno9fDp)gZt$K)k21}ARlcX^WjW}vvtb$^W63bI8JO|OM z{Z@zCRdX6exL-p(F4ymz>WmHU)cUvg*!TuUY&7O?d9LcPkSoJ_fl|A&uE-CZPF-e9 z&p94Rm-i#-gQMw{kM@&xA8GBg^ox~u_ER9YpR}v{NxQJ#eMMqpT0)&$_a}*V1D_x# z?J-ScstYY+c#@&8Ny1!SzphP!yd{wXYYbXkfS zygr7x$|fSctbLgnW_Bxc#(5L$SmGc82Q|xjmAp``d~$d3Ey*ByP6?IiY7w49*Hz*)E=YqdJh5fUZJ#Z->7+)#D4k! zCRSI_ATuR%WK zj0D!FO4&cmzt?VzmQon6`G?9F|4`i_2pgTrJ}kuhXs(DxP-RAN{lj2J&{GxMp?PW+ zo2#_$vWwb=x~!) zQe`lu2v&U!$*$RO=j#ZTsDvkw|7|&qBMa69J!@*W88z>))dZ~v=!L4ZMsUt7SW~b1 zUjLkQy#6KWcl~0DHjH;X-vM)Cy$Y6!{P%WfI#q@ml>| z1Jx2P-9+`onmb4tl!*d56Hr~+`6Rp#M3RthL*ZoY~90kwM+PH z5dO;ebxVVwY-!St(xeu7AqBk@mN%vz;nJWbU#2Bk=e7MfYpqx9G=7p)^%3>{R_c9Q zSG3{nNL_W$Nh7*Or;4gmN&X81p+q$?6P}ai4Ug7zQYfw411s^DQn}h5EN)?U*mn_; zyoO0#&!`J6&)Se@El(Vf{8e_#FtI-|Y6Le;&swu!V$ieJVrA4WqjH(buK^(Obhvi5 z^_-;5MkiXFu=u@d!6eIqDW6vLxROOau4Iu@kws4B=LIrfK`_wgjH+4mF0uR8KuVOuY!66^2r@!jm(-)kcI!GLv zsyGM-+07f&d3CB5cTJ6oyRyZtx#xNDcFp9;IgkWU213642|NKhjX9I4eC5wKuHrqnEe@wN)J&oV!gqm*yv0B zBcRVIK!Z=B;-FxF3E71JOSTeg3O?^04aoWjGhmMVo$G#qYAv!c5S#$$DJE{84z(LG z{^)g~!p(^g_AVY=t8&8Cr*F9dbHwulZ3#GonemSK{)s(-zb3Q~#m$AWVff{H+WF;V ziWwrI3 z?|u~6f(b|u9%fR{M_Z>LBk-xHXR20>mE%EE?DtVeojL_iR{){ScaB@fOZ0frhN2oe~%zyK^$|Mex4Wu^9sJlq|9LOS&H=6}Q^D*|!zkBQWpzN1iK* zeh=c`$Z`4Sa z?yA}LJBU47Tf;4UnL7;6W(@ZwU~>mkqIf=|cB>FUbp|qOUgnvNu=n-KQCYE?Qz9@O zCFF|5c(RJ8de6~`v;1-_;*92MkdL+s(kHT?&E{LAY+IV_)H=_nktQ%s;iM$o8_hT; zrB5TbInGIGAZ1h|wL*P(vu@s}2z87ax#m2he{%h!4p{G!t6yu;uW@B0!XTqYHkGr# zr(;JjrrK5dJ@wA&{@ytj4~ylL(6FfBsjBkW7mV8bq=teHW8u8p;(`LpCKKNTE?k3>Tg8r)90aR@X6n! zfsSm#x%5JTFkMLqJ9*J%2bv%c4$Q?6Phj5bQY|$ybHYmwRT$6-=E&h*32JV4=3B`V zdcBzzds9Sdoj6E~9~%-CC0*R`h6W*idz^lJhmM`mkNC^IMe1_z5ia*YxWqc)&k!wC z+#<6qZN$y8Zew<|4RU4Na$eC{H^yhl-q#=>k=%>pbA{`4&ieY@PhXFA9nq)=NrYC) zw>W6~Q#4n_pV9uGAD&|_aOWPYKn`y&f#L_6y}8HyN6j0>Hb!nk#5U&Mrc(nV7b5Pe zrdGGs$G*Uv)e~qOiFJ5$PvG2D)|?b)ypz!McgM67lDTyd}IqP4JPB4_%>Cirrc5b9r6G78zE->`2W-HmnyNC zsW4VC`fpR8jQ)iGXw+?Tv`Y8|q+iOPQB~7N?&?#@TJ~)IjCQ`II;;E{{c4&cf8^{R zv!71&+TR|Z%`u*w}@ZSj7I~7rz)})RYRP)TY)^ zi&)8#vc1i|j1_Y27jF`)YFKfFO4TN@NoSbEijb|)-r1!hUCUyX8-RElAY~H!Yn^{? zlh|f!Zl;*T;=*8;{T=DI(Z?S4J{X%gd)NZ`>Da^0QueUFq;WxM6_Ge%4;urEvX)GW z8Z-1~5PJ%GCIV+qyg@96u;(_2-Gc^@eK~4w_L?bhG0Grz0ldFs5G&FyIsV%_xxI>F zo01=iiled*n=STX;=KEFES783V!2aywV%ZjXwC$|f1@nKE~G<|CgboMe_ctRf!~Lr zLV!Zy_a9)+v_75^IIDY<$O>g}E>v+aa^;}l_~TC1{wPEr22;XZqL zsRM9NEcu${9;hjhApkfY2Rm}WQui$M<|Z?>fS7uNoVoZ zJ!~ZN){(~mfe*ur_-jjz`fE$=?XOLZD(bII4Wxx2hzLM(wqZXKZ|kK-vas(+?ku!_ zcqB5C>1T|jTIV@l+}!hI5ZaU5r*iw%k0-Y|S2Bbz$`E?}F&^m6pW^AwXe5)4d<*f5 z6K^K?ptw{)?KX)B67voQE5)(1xCyxlcOlEpR}M4=({66(Vt2MO;^QuSm;FDOiAF?U zm3wgu@|K&PwoPT}_U{(tJ{*n|_i@D0ZcbJfI_Gl4(XPFL^mfFdTcfY-qi41MEb0k_ z*gxV4MER_e*dU%%|2&RycNrxfG>jnsI*TJ^V*2d z{+w`VTB>k2IR8(;yFRweDV(Rr#T~7!&4u zqC>_i3wc^)7)0eR>OeII`2qx}va9y^(noR{tGCGe+54c$vZjj;m9DBEo@7l-w%iw~ zR!|VPzLjwEeXFkFdbP64@Ep;}J5cPmrjzj>*Ki)k&dBhDKuZifB=kXLmt2#mKCQzS zZ`(>bUBt;)TO!+tWF(p) z!?Qzmp;!3?`qE$dDTx%9*d8GyH9dhx4kh@XVHmlUod_)Gce63elV;2+!l0ug_ibZV zx7lRO!rBg*R;TKJ#buaL&BCN3ZwiVP0zyCfMBusctj+iCoHwd>fYee zmlUJsF?ly7IPK}t;rtP*-r<4eSnH;#XN=5c0~WQ9;e?MaU ze7sZLL)zT~QhBxy&dPKxz!Rf-h3g(}Sca%(2LxxOsV1dEM$Jxopwjcqr{#hm=UqBb z^R&Go8L??5-BH&Dc_)sT>LwxhA5ti{X;DgEP$evoTL#^)-Lz4n`dg?Ab2Ts>nMW`` z4Sb#v)>Q?cmKzEDprtf~5uLXu%m}I`%$ld9Q5k&XZU5VZ^3}}vKY0_ zOk8I7whtqMH#?-bBftvPO=ua@eaqtyTs;H&d-N#Px@QMYfeT zqx!U54KDhk;OXXFU&!8qH>jzl!MmnoDky=jkmQx81vU@N4>VoC8#xDX3o@Oz>xl;y z=1iO0z4#4WPB_(EXQdslpLTnCVq;ZhIH``Oie#=(`Nk!U86veN?d877LMvZL{ULOYk2B*ZwuX*R)2d1Pmq`<8%|1}`=WXxx zC_QjyrYndG2v3@oc8s-(N0C%>$q2Tm%@tP%HV?Ay9BpNMKVtuwXyFDg!NT*^k`YrW z=ONUIKfM%NFv?sea6;5rXc zpt;M+Pq^9OvMAu`5MqTZ)kj(rDDU6h?zI+N`=+`%=@$OP*f71vx;PUx)2&kj|48sRVHlbVtjaf}#HRmi%1G&cAn~&9-L`ZtXcHf2%Lm6v9C;N^fg{jP7;8P@# z7WiHko&zqAIw{BtFb-hCo6`suI`B_w67t=}v=|%R-)COFI320;?TN<5M1{G#;xPAM z9Omv15-&b&#;Sf$_h1Bd2?W2tH|nx*IB9{p`|I-(qqzI}=fmBD{oyX^b(P(DI6P%Y zxd8CVYzE&KcNHc|%w|?V7puP_HMgnUo!!))gmycKrLfb%t`KpW_{(mp7-=mSZIz6+ zhMQ&**b!#Uf~r$`G%h#Y_Sdh~QJ4TeN*3%2} z;!M`{`@DTAuNoVP4BYflx@>rZH}7sc_R9;ml^*-$0?19o$X)R_Y0>L)+^VH=rarI?s#LSua30_=Go6RD$8vTDrWl%9wUo|3C zf1Le-^s1y$f~&%&5;&`J1c+)DWCoLo;699a(w?r|Jr#Mm1;Z)9`cFt_eAw~t2?#= zkm!Qxt$!1=<_cT>ZMS(nH|0D6I>O{sWOB^>$q{xbE!H(RsbV)`Hh!|~0uj6UI_{h2 z3NCSnhjxlK$Nu0C@8WI6*kz!>W=^u@o~(8uiQb&!A@v~2H0Zsp_mZgZy*@(Ph=CI( zPAEv}!gInyTX{8DJ6`G&M)0Q;vaG%Q4AshK71b14mKe|AQ|XZG8cvZ>j9ve0W;(u6Gm^GwxzpxbRcDOVsl+d|4Vhezb@)_#h;CQ7flP1@>5 zn#bWuV3Twg`%{S}AWoK(zr&rYOl;FDZddVlb3yZjv9y)DwYCVkDE~|Ke*e z0FU2E{n2l!=WMcfhLQ4et^NG@DP&0aGCXY&?xyYOZ24=Ji$4BMmK7 zaF)?mZ~UZpFzF)eE{Dt^evQIQ13m_)(qOF&Sf)YQ%bayG6x6Qe3b4?(27qWViVV$u zpW~v!EUwpGme(Dsok5K}tA=Ot?BK%$9!=E~{IWbbmr-SJ4s26cDYK>EZ>jDuThbnA zDeqWroHxG0{h_&DCd{gp#J~=BV3SmyT9!_6NrDsyRSCNi`G)zNsqt=)|wry z^{kaPNTqjEsiw%9RCvuL?%XA*6?dRuwtlRX_&H840864ZYlNvuUVf%oD_{=h54UQi zYhL?F3Zd%CGewiU)~pHkH%SUicYE7Yi#d~ghsC3b8bVQFpY3NPDx{*{n!tzGkLUI9 zP&cGk11R6yi^A7lekvS>q;~;bSo;Tpa;fgRTV1P*d&a^4q82zDtw?!3v|o&8%%YaiRK@0-x2Manp2%(r7Hm~i_?OIf;IWL< z@&P6X^cI}nI3}ZS%2IcfID(!=tFjfJbWfQi!XNEOsXi_B;C)WM+6Sqd;eH*^0fi@w z6}Qn$(l&=&M%>YjClOyn??puM3Pj_F-x1Eas*7R(JZscq$EG$bxbTFMGLn|5;sfET=T;KW_O(Q^> zAwX&gD%DZ{sPNFG{1(gh3j=miMarA9W3=C_RO{Mv-V}n0>GLx`~i(k;JCr-z% z8U#A*=A3N*oZv$-Y}mfNLG!u(VFDUvM)wuS+(Tqr6vKvI>bp z?gvKAU-)Gnv+&31ImLaMGU+ll45>a@MaH55`DRo5((03q{4kze$0xM+WGml`1_fHL zc#8>iwU4Vl+3BPhT2TyPWw(=(@|FVU5Y+dpPxg>_X*duXki8Ehj@;eLCgvL(hFP~) z1y0_&q$u#wtxc`TcMjg1UmJen@ATX(=&ZWQQvCwmK@mD7%adK;_!Au6sXeDTI)QS>g>Xqx9V0zI~k~Z6W%E~!5nAqCbm`f zJ|Hqv&Wgk*EXp(o*5NvBL^#nL2c^BrnwXaq4jfK4_n13p?D?eXqg$)quBsa*eIAz| zq{tH=Q6=G63WiI66^s}Or>iSCTs_-J2q+!s&>6HdULsp@(2!G7x*TjW3F?s};UQaO zxE_v(Z^?M02$6=siE>SCPm&zLi(m5m@4*YE6vR+~xII6Z6GINKgBC zm0(C}Zwwi24#MGjAdyj+iHxIm0$4!28$T!z0fHJrHQSz?BUb!Gb50%lK8b$s|kRfnU=6UxsLjjU$W zR0!BJUn#5h4Jft6{{EG{>484){4sXk33NOh-7PwMIdAcF1U;{YJg=@kw9pkAAfGbs zSU{R7_q$v_eOWT$5@kpO8u=lAp#fWYQoS3nPSW5|2keh#9^@&7Vx>QA;YoJWvhk%q zwR!%@Cw$m$7#2Bhr{c(1Vv+trs?;8j#m=@Nl>G3M_rNE3?f+J{X?Q4XK(m36>vTnQ z;*_au$g@>Hwn+1u_Lc@cyO1sNg^2NB9ak=%LvdolDkl-$DW==U9$5g{ZB-ypz2Bs8Fv z@8At5LYDtm;izuMqDa5hr zj(WyCU0nduQ*(Oeq$)a5;eiwo;XYNx*mj2yVWaU?JDRip(AL_Z--Znzq9J+(k zi4ap^6#FFEYhUymL9{gUJQ+al&WaHd(*lKg%0y$81t&?SxzkJ`qAc2ILnXx18Kpu4 zIw&Q74T3R$^ePg)_K$W%Im{pl@eabbRh(C7FW33nLAWUMEXkn%jG~wT6m#rj zzZwc%VU?&sco4&*H5Cy7q(l|GdTA7(xQMx`eev@OoWU#N#%^C2J{`8_yI|oC4UZ$) z%r8@`(DQR@W`T#avHtt24M&Ml6tp60j7EBjR-l-!6(|@K;(l3KrNI<^7ioVb+J!#t zr|O=JbYh|w!cv|g(bwaFAt*7IXP|UYjNj+nmL*eAIz(?On2+o2 zKL^5su$NmC=dh_>9Cr^9cLzb^IonEuXx6bA}1KCvfMbMU4giiZh&m6&FOLi5LiiD68Dp)rOAaz z^5XB3rA699zL|M%RK6MLIGg?z+&@vg=|T=JB9uxl*TJHdYu@2TFE@LKqnXQ*K)Wx& z$$vy!cT!GHP7>U&9M$e1>Ld{{xD<1WHAtqE?W^ti1jR+$^F(gQn96mZs$|7ODs=;) zxljORx7HeXkpL)nkXvYf_;z&hPLtwsPPCP_XOqs?2SaK?7VoHuaXz%hS2g|3opgfp zKOwsO+pT=Bx(2ts_7BBfUV+UHoY!$k%#c?1Xk5%zM)hF_R9A<#I1LPX&C zx+D!Y=WsuKu&{)vDH%jf`447-Br3)+3j3?qu91`+cp4PI?$b96M98^7^no8bfD{42 zvA@HA1b+06m^yR}zPN{J`p_MvD#c2$c+|>QUJ5+QPx_YcsTGgfXfRj2$#{101{e5u zD7{g>`wyh@U#Flue_I3Hc{o$_MmvzjP2U6c^b<0s)qa>qk;vHJM{23@N%l+p(+e%e zvr2FO{?{@Y;+?)c0cijV4E;E!SE7NGr2ZY#YpVU%c&Z(d3+zx-+s5JpfXWFqL;~tO z@pG@d{r{dK@owtz_OHl>c&EPrSL)>pO~MFW;Dvp%x|MbT1mz}0P;L_E zl@2*S3)pX0V4wM2P0VBN>C=$fm)Lu_bSmX4R2D51D(x1i)Gdi|&glsOaK%YrUnUdK z34@~u1nV`>fp$U^#KmZE%?at|Ypf`qB)3hYejKazq2>HZ@r zXh@4)!x{UdXajid&e!=`p_;2B<)pqRsgaNh0&%Z3acsHY zyp&)FEpmb65lFz9WfF_hlM%Vu?L|?0a<(OT(t#CWvCe>fZ%yek6*_3wDk`2QCk0{y zL_#YN9iZ4Qif{7Lvp31nuqUa7OE)Hd7L((IXGq6Bcurf?i!S)I~IJRqn=M5zgik|eOtee`$k8m z{vx*AzHW}GRQc5xd0t3&tlBzi6N$hJ`f|;(B*9*e^i$_KG799m(?{6X{yb3>u?L#T z1h_?J;!z;hdYMIJF>j)<; z@>>O;h|5pylOORaA1R;MCqKdY&3wT0*&jBk>FaxYuJ}F4KY5OP@WFbzQ9%50dXmd} zTC|))2}{3A*w)Kx(K%H;*Davdd?ZxqU^1l%Io@8eq_2-KELg5 zYL9?#dqc;_zW55hJvuweul8drfNWsn^AOljN_y6OnaEjz5R(3@KjQB*h6cUsbPYmG#WS)NW7yC7j(e5AY}_ z*z3&|ULMaa>+`7-&`r7;7XFHbydryI#tGE| z0wl%)PZfmbdt7@*U@zaiFZ6d5mRP;$?_52S$ckD`HO2OI+*tIXzlHYiFmbutS^e6c z@u|InOUVnb1o;UA%~jQ!uW+IG^nO93^+8$Fjq;d$UZ3Ut&1rfCzV||O1?v8p=dAMn zSe37&^{H~Ws?x5d#$MxFx~bRxGFOf7&O6T-p90R$5?$d9GAOiD#P4)?LpMLdLtg+T z)O^L%cIdBFEd%xXx*dEjv*PfX`pQzm8wBISLpyk1D9$ao`F19S_X8dA`hp(rZjZo4 zbNwTVdWi7Ci^0)Vyb2qeSvgEy#$YomE`E}#6^@8VZioHybxABtlIPp)Rgv_DEM_G- zTaokkiTk4TjMG!UBrRCk3EGz07k|k5+Sp3}9n{C6Tgvln>IlQ_FJ73$#Am+FY;P3O zqRy$DVmoX@<*a){a$0pxqMUC#?0;S$@2vd2dM8o6lcaMFsGNlx)H^!It#g{M%9kaN!2-b$K{Chf_Db$oLl2+Yt=b} zbj~Q1qer@s{hfCP>zu)HwYBOTBG^mcju0U`l&pKO5csL)f{eix2jzDtv_f!O{(2Fyh@i`%H|yzEuk~o7W(wtu&>LZzitV@H9sAH5 z^}aGcv{tmzh}ZWCvs`Qskc~=hXI|ewRLU`-3M&NHyuPC<M||X79p_ppaFlj^G(zt@34@ z@1cptM)+-cW0!NO7V@-6Zp;;_{ zEl;y$t-;U4z#WSrR5SZExaqxn2u1k>_MwwuY*|j&&QGL-y2xo z<-!e$XS+G64vM8f>H`0Ty?c-3Vw@B^KPtf_r6Uz+?&MCa(`d?1n}KpdsyU?CloMHa zqat@V2n$e_plG3Va-U9zPpD!BRSGO}h^p{M3ld{jA5$0uS;>Q*Ip%DYo>$ca&4^6+E&3qu8dzjQ-95KP-(IjylQtH z0x2t7&?I^lC8AgH-RheuD6&yu)4rT-wT*?wj3%#dR$QuRFQEc7&MbJfuL@8`U!BFD z^B!tIf2vg2;B$SEt9X}2!;LP69p2|lJu^*)pnyXEmCI(vje;Hp6-4?#<0>R99F>HP zcDku5?!S_SXQ|}F3sfcC$8`oy&&CbWvrUD*BQjeXs{|R;%F1aZ&(yQ)LZ=@Btx70# z+2>m;b*~@=d>J|%b*UhvXN7Qx@&|5u0dRQe2$dtaniux(l9bV;Ak5!ocP8kIZS@ib zuvpk09-2iqKQ5rOH@s2mv$K`_mNA26P9Gra;eBxlRZ#WtzB3OF`rL4Mv0jC~0eP+} z`{f&{^GX_z@td4yH^r~V)c)x?r&@oiS~Js`YPbmpcNDy88^1k@Y0xf7kW8ujI&+7w zlidT?B)0z}oVBfFJPzX9-))O5UGWSgODat*+zu;x6XLa=X%z@~uT2sSiN5YmxC$^^ ztZ#E8e!f!Qei!v^xj*(o){<#1vVdC%*Vqx*+{qfA;;i98v(*|tBPfX+vl?+7sF@WF zu*b0!bYLZ4FyoQKh%mj)Psyf~z?`AZaMN+YeYf?rY`pe^kIPX+xGXzeJ+^{f_5htK zkEb4!0>aeUht;ESe)b`q3JYMruT$l5hfalguuF6e^7zm)RRf#1{VQEo9)F_CLJ{p5 zs(^6F_9R^vR>vNvQ|0k$oyvsT*L+X)S01}`4FdcZ)nlVPmW1K_O=$==uY=P=o7BdsvW@wEp*S1)&(owvUEb(1NM*i z;v`Pxuf9suza=9=-%o#!o)xs(>rcx!WPh)c7LA~Px}aVAbRxbs?H^nzN1~|YOfQff ziz0_3=2y;N;vc(0FM_SXX<3hAjr4v=c+rUP&>E<{T|)5`UE9;2x*cYweGJqRW4o@>P|M3I5Sll})LOuADGn<)MWx|0P6jI!Hsl)NB## zHmlSG`*kSOYtzQechwwdNaG7DIo&I-{p?~+bb6Dwe|9KB>u#sVakNeiuTzb_2aY1P z{osu4c;Ih|aFOPYrVr1@F2b*VWBou5+lzy6uM$5Oew zPZ339%|ZByj?v7^0CVf>GK0Z+D+@!e{SbTr8eHlQ=4Dy6QX3XsrL5NW$9nZ)QLGP# zB7LxR9}4!W4pd2U@AeD!s>ZL@je{)EMwhvj244p-(uHE(1*d(_Ua$S1V-=wQ@`&q? zZ%M2u#K=4F*Z*}mo4udO*}Mq(gtJLvV}KVIW&B7 zL9&nL^cif^6kYkxDpcix(<#P^I-nWOTEBJLWLNWw_o>(QNLd%pR1IGL8?ZEKxG{cpT(8LRD~Soyc*nLV1`+U9@>?b`;x$E*l}Wc z?1k;zYmMh>=kA~)m(A`RA_O*jR!Y-h|H?VGE1+slQ6Nk&zs^)OM#H<6p8>oFKuF=oNubJQugOr1k@o#PG&<>3U- zn};x-$)cF)@DXhn2^fd_UWG#R55{3%ivwe#0^^)#w4uiTH5f0bbHI3cA27aF&6!TH z@biFhH#5y}uVQOB1B81SPYi^g4}4GQ`u2TG)rU!1(Hh5!U{&9R*4K()4*mF%eosj9 z{oloB^_IBZI%;Kd*~9T1?FVC^c3xO7`wscYmygNvF;PBl>`i%)u(-X+=W?xP zM^_8yGT~w3cc49ecb`3a=MhP$y;_(oPe(6mU;9NW*E^1)F|y;tsC_w1d~BQ9#~M;( zJ`V{^bdQl1L#{X2UZCwh*)-W;*bwC~q`M<&Y@!flvopL0{pIJxfMUb8Le6g>l(?IP zJb3MshFW=enNTRL&bObv3uJ3T{lDMP3*~gOu|kfh5bC+NPj-!Kd?ley5$m?QNL}ar zsNdh_5!x`;w-xaFY(5kPJ}1qUu#(!zIKWR<#NsMbQ$|ZUIS*9UL}~7$Y_R6Ms$Mkr z!ZT^^$6Ox4jGakyS5~T;lg*+UhhRvJ=b(?HHO>9!BmEGJv(ntj=cc*XQV9|Iv97cI zLg3}S4tQ1Z!A5u2s3g}}39*VX9U;Uc1lZ>y#MW2hV5NDHaE)Q5TWHvb&r0%ed-2vk6!UrL@MeI{V)ljHzwRA&i%RbMmqQB{@dm5 zeA?F)U}M)4zD}?U5d&n;{#zOM8Sb&_w;Z?k@f-d5`CO!NiGAu@U{#`hj4%6yD=Ios z-DJNgoKug329%(U4WE{9;+G14^SK_xsXuE@2&FN$%hi!uf~4MHJiOgDovoUjQ-aTI6q|g zKjDXL-P(7F-d}$nzrQw8e{_GvyJY-*{`~EW!RBclQ#r%BUGY`Ks3yW9*ZA zTSRy@e+P(Gt=QWmhN%S^UlHM%Wl0K%!C->|=KJt5?i?{K6)7U5-jSPX`;p@!V34Ds z+&Idv8(jYYzwAezVCc$(G%uCQu4h?!L3NlcOQ9}0;|i;S`aV~;X@5PyzN$*anm|ev zy$n~a+iSry%eqTiIf*RW!W)>JROM4iFy@bn48q=0ndoX8#BhmM4Me>5>>5RO)J%#* zF8oUDcpMqNlyt^!cH8r}sL?ZBw3Gp4LaHh?`fvVIMlXpn`W#_<-GMM5NF#~!wKe=t zbppYK%ac$?ivvVD`3exA7J!iA5kN@m_We%^Af!~RwO)XbHtiQdAIs{I7dmkXZ&{r@ zhHB+g0iq~N`m8Ga-7+fFSRqL40^yXLr9voTOtz!A#SR2|hrgm|lXI)3@$c$|as1sI zz3{IW`W*rBF6oINp15_ddQ%~u`KI7k6#Ybo5<$P;>Fq${K?L#s+H`ir>pFG@;%!oh z*M)G-XHj)LyhVy}F2p-p^?4BQI$sp=s@nTOypOLGc+2W(dryr`K<~BxjD7*jNzX)N zY$Y$`xHL?S?Xz%c&ex*2vj>N z16$K^Y*wEzS;dcgn>I%fYA(Sy1|sfMH#$88%jkiQLBjE@2H6VF)^khHe0KR$$;5) zAOaF8yth<>+sVkyMjtvT7aM=SPXpRFAdh>XHJ34%h$h*^4@K`dG(H!~HOCP9a2xnL zL=H~&G=@9>4DHf?%Y41YXd?6V_|DHWUy6OYiTGJ^r0j3LuDtk+`I>WFwnAsJhTI4B zaVAgZ>u+3-~aP`-FR>Oe032{Gdf=neXalb zy7h2$zA|t?c=q|)7h7N4&#-f!ZHc}A+9e>IRax_9C#Zhxr5JHi+(zk3uMH>v&4t&q z4mM?gl*e9*3g|<%=_HVie7^Q-9EaFH{6l1RC&sTvRnAhM5$5c5S(0)KFbAC}pUoa` z)sChLk+j_XxZZ>cYOGpmQv6NLssEw0fV6vB(`)y{r7YQPpx1`RDgJVC z6b~X>lBS;{zY@pa2-AP=`3-rhWSZ0*GuOvnDt*a5@=j!~&WoQbPZfd7oLTZ(rdo-= zMw8l^qvsj9%+dO9>pAk&Se8nYIYQ4U^LbQ!t9&v;uvTve1kjQ%^I#tY()wp8Z|npn z!yfo_6!z2LuQcqXyuFdK0(;#B;6D`eYy9#Spkv*ZyJlf7Z62 z#kRi{a)w|djzdRhRraMji#1g3m8~!U8lIbC@Cx@dz)2`RQ7!j>uzY*12_>w^98Ub zj=6Gh8;Q-Z6U`jY!u}z~#%69Fz4mZCMzs$tmRrcl>57#Rgfso@<7SFDC%|8>S=?pL z?F!Cot$o+16ZD*2Y!5vKNO!#k;y#i6HjX<%rQCOnl|Ldk=>wzgKctcrbV#{1pV4FH zb!TrG+*CPOT=9N@0SuBd)Cy6>%WYaR$h;9FGFrs@Ve@RSnKIjQ&+ytg7f1~-)wy%K zpSV3Zw+jWK6tuq_I*rxe+%pux&JWLa_aArru{jz8+%8{iV$nQ zh0#h@qVhpp&f4>&7kJ2zmSDcnlZeL4@wG5Qul;3lE`ZkBSbN%bun-@1TZbd-p3xL> zJA1bG%LXC;-V}K`<;<7O1lZESWmp7XI9K6!tShQc`Xf>pili3Woe)GOB3@&(;n{+P zaq0xJp2I}rD@w)XHD=(p1Qb`Vq-iMV@oB-nd7B&msPVO7zjR+e^<_rt%b;$l^(mM* zrf%NmjCj~eha>gNy>!3zXPr@hpd(YP%y;AT)mDyGJhnJgNe|_Lu%K+7_87oKVc?I_ zX?N8GmpR2PA+39G1z2DM!6Y+pL|K+^8CrW1Y)eaPQSD4dlp=EW(HL>ZgzSB9!sbC< zo`oy|sQN9AKaReYPxd|Aw{qN?s>tMw24&sW}^bI%f8rPxM1P z@$_SK+-4U~ppPiK_B0K`?dJsHLGi5K9@!EXBd5}bw$s2nUab?{YgfBq#d*Gk3}48| zDct7;DqFew-Of+Q{&ufD4BZjmQm4Q`ewee|)lIUY+5SR~4cNI(k~=N0*Y_I|!y7u~ z^F77gZj4J1qT%l-CdNpf+qYRV*6EULh{VY1Uo{kG^3D`*Kl>D4&lLaWE;YsR`-ih9 z=H40EKs3=f&V{`F@cVjy1noku)n}P6=2Ps`V)KJM)tR3-Mr2+p_iE-=`N$2qWbU=X z1gaDp#kLIgM77|kQ7Bt5eBS->bQncr!qN@LmZ)NsXwQhD$=W9XunG}ZF$826=Y41Z zLaI@gMq{u!|58_JD1Q_;cKO5OGxw&>!R0L1qyVt%iE{}2igDl83*=e_}PTmgRd5-D)h|I7bUt=8(LKMbT07#{RH&q$5c_L-L6e**SMs9+N?H^DG zR_n9yB2alS!+1K17kfc3UpF82gDL-i#fzHT;_+fK+KR$|7#nfiLqveKLk}jp_zh7U z_bxobu>S*4!+yiq*yy$0te15OLTu_c$CDh&W09x*ZJ2Kp8BFuYJ?5ib3QfB4lKyxJ z(YxF^VXRbU+Z}(`n@YFlm3QXuSaxsHiKQjxg^D{ir*voE-jm%txTSJXF&d(8a8fWY z#Jd6ByK_msuBPfTSSci)a-B_Gax+?d`qIZpr$=3M%KyzZ? zaDx9Iq%`8;WV7H~=A$4raMHWvB4a~!=0j)-W!0wg)#lqkw_&K;JUpyA z?VId6$$uhQ^6yHD{Ut;n6QfT_N%7Bd$!B?t@U8Tx5Go<=-rg^dbrdpmrzVae8HCiTOA!FKuXlwB%<0(=TX~4#s+GJ zhuPd+-K?dev~qVXt$djZ3xfdDlFBvAm#o~nI_@r&DHb{Z@45GRW}bn;>bJZ9|L^nf zvn%u5w{z~fFX!BI&pk&&vuu@S1~N&mMXn7=f@G$W9rPWf7W}Rw0ne-bQfmm!dczy2 z^I_zLQ0)w;CLtvs^Yk9f5BPC0Xy;Eo=8q`{^Jg_AZ@DK*!jY-PVA|c_NsG*|<;-J$ z{EX(I+1X-S3Gb+m%0f=rb@(GkrL1ZxzRtZ$olL7dQxRlHxgi#jB{O8+R7WHwiYSFD8Q=fVcq=N;r9J6R4 zoU7D`Lw3YW{@6;r&VcJi<$(xF)rcwa8B`s7{nCCyVBoEA5lQffz=MCH{JnR*#C_ij6TJ5$7Ua*{0f&Y2fdMUJ8Qxm3*07;JW{$e)?;(5UH2n%a}Acu!KbJs~eK zb)w3T_D3x!dS&FjQfD9UAI+cJZfrAt-Zf$7&m+(!x0!#ikhu>7wgm&mPx5dl67ntP zcYO@MW&am|i&@@Zcww0r0)@-|Wdn{R&V4Z%?9JD(j|CMhZLh#kA5vUqHvBGvAA9=Iabh%R2(HzW6(8@VTX;*o zt~X|Q-sy_{a47_DzqkdAOF6L&L5OV3ic2|&+%&yv=b|#Ca!yWi$EgUwrxTop`&~)W} z6*vREk%R}PMGM{W%Erz};66~$jnrY+;j z)^zGEpWl3b#nJpCT@`saS^1a14AW<@wcg9jFu=!bnnYBSqS>JrA~8oEem>;A6@hd@kPPi*@C_4+Xl$4_lMKZ!;3|qcG)5oibeH)SLm=92SAv7b#uF|mqAa~u@-MlRwI0v?OmmdPNL z1Te_x0E6xv1703D00oMB5I~{35Kem z_Oif{Ez};(y`;H5Vm>?(;n;}r)v??5U@K~K*-l1BznLUX0v^vPXrJm!>0e%9A}OPG zp2WW%55vFQ!aA~mj>~ckoMeK{VZIOblv1Xx&{|ME80Vr?dh*5_DX73V?$^*4+%)?V z!jy2Ju#MZxA(9s{ME_0#&sIN9_c#3K7q}n`IG6GcTs}3RvdvIDEu8`Y^6G-|@=Nj9 zje@iH)#s7NmCyA%LuM{1pKpJ9IQl6Yo<8+=xMp4pQtH-71@yrl0!?tk;haQYeu?wy zf?E8pkFLhQ^k04SvB0mB$}fK}hd2fF5g`srtJgrztj0Y;tYZ@uDoDtMYpA(Xd+7w6 zLlX&(!Ap(S1n{ZCmx9l@0{UR*c{$)iUw&x-uF49U=iiJ=vS>#6Kcu2XUh+YuMM@6r zq+$Y*;Ne-L&q2H*I+w&?@W{q*!JRkja_VEKPySwU$br~GQ$ORAq1ZM*DQa<^*4cX? z(wx03{bQhiqVNxPQ}}z_2iAwuC`p0Pj99AA;y?L*L#hA%tK{zTeR_ocad&r~(5@a(9ncH+D%aRe1|ld ze=^K`5y`G%BLh9V;xre`_35+lAbUl?Y1Kl%2xMjt`clSs~iN8J0C}qNbE=WsWOQ zqIu2XAvKk(GrZP}kStB34`{R1M&Us&O|QgMWNU1_bmS{M*WS6%n9WkK4dtrTH*Dfggi={j{Pv(7f(EB(+sQ*_68_K=Zhy&_~_g~iKXYI6DTHsl`X(C9lGvZ z6R*p)ck-`@XZv=ctTP`mKw}nw3Veq}Y4#4<;?Cha7bax0S)xU8pr8o}L$7J~ML@gS znv31qEO#YX6rIt4+edQR#xdGg^Ym<_(+HH)2oz6-KlSq-5)#Lguri5qNi*Y@EZOWX zU?#WZu!rzBHe3-Ku!ELQ&%Oo=89LIt7^d{_nP^E9PyO2t3?TD5z-0)WW+ z6To`*HfAoZwv3F-9GJ3MTiA=>>p1-)Tso+nnvK9db7j33JwwNaL%P?Dg|*dBan6y^ zQ#OQ*2IZg^Z!PpMH!uk-J(rsPE1F((3*RD1hG5?ur-8wAiuQh}TZrfe*poeT1~K20 zkVJ}%Iy(usD7QaYjt6V-%o)z=Q3f$ofjag+=c+-l*z_;O(|PtJFPuk2ew~PX1$tPR zz&70*f&CBBo|`FjZYz$4P+J+;zd#074PMNNfN~F@oHC3gSHo-1SePl(j?D3POtOKl zP*N21E5cjaX!?p^kIkUX)neF01E?aEBaa6Khsm+oTAE#E{w`c3cpi;IE4vo*Q~|Ze zUclUQ4yK<(##VMaa`x4nK7z|7bRT}HbL0nx162QP|4M{l##+e)=3+izwM+qD!&rPy z%1*H;iO>jbPBZnA%Yk;w9Q1EVb#Z?vFklsk+ss59I^oBQ_1|)dFQWP5X{-dr={E33 zyj5Z#76WZLeF&iRkP{2dHr5MG$aNU-^U^<^cML%o@8L?O(Z*WFX)}k1O2GSsgv1Bi zC^uqTXj%K219&>W)Ne_Jl+zHg#Xx@|<*o)W%)u#uopj!3OlhziW#djG($ZjN((IhL zlk#=;fu$eV2XEi1&C{~k;tb5jS+OG1p#>Ln7QsrCC2#%s@ff4)!bPF?rx2hxf8)XDpMwJ<(w*eGoaOUA4}WQ}%uq)1@&DXE5og=Rw^Nzkd?N4P9|NzMBdoZ-G_W3EG3Ots4tF z`Ns)0G^XN}n9@nWfHJc)wOP_LENfpcyl(ylkb%7KGlCFUI?y5~Ri{D&$R}u-)mXA` z6)2WhQ?_@|$%)l4tD<82oS*jR1$lb&#FLVlC*ral`EJ8}p58LCS?bKwV+*5vUyuoC zG2gR*CVI&3g0GzOO;=Q3Li02{Vg(>#2oF|b^Q2vY`9F{FtA(R~tirH``k~N>A1l-i zg~&cp(-Kst!z>24t^?}0wZh(8J6qYRCEP2CEqE<191_9K^@Ux1SChzr?yZg~j>C3g z?qV@YhGbNStJ|8w81%VtruQEtQhYxK^H_pMd;?;lyDeU{=C(AH#ki$fcV1Nq#G$eV z`S64WDPsDxvd$&@Bp4o6k&}MS7g+V=am}(F z6hf4Z8%FY7!n)mUfxT_3j;)7sO8yW=v^ZAy-B|}lpGrEKUiIxA7rYB+x^n=QzPJcCd!&=rQ)#e|^o<{lHT=zI0g=rry)z~NK zj&dp`ivYN#dV|)nT$dxyGE;O^gx^?p7viXTCU(!ZAzV)jTM&dFf%dTG+z*)Lq85)8 z%ix@QIrMq~?Ovmdr{R z6&k!lZ^u$wFbdK;x5?{G4^eK|2s!oDa{S|5(u$)}GdqZowV=3-?Ro+~a59vpgTQ+E zk}n1H^;nv1ECxEW++5=2qruqRHiswoBmzN3fIs{b`Som5B8HXC z-=ION9!UbJwN&PY3PNg~2B`@uQUf|f>IjTh!yvT{6CfN?1cHz%5J+|7NY&smWq?wn z14y0y2O(8SNUhf(_3WP%N|h6KVJWpWJW^M5fE0lsq&_5o_3VBug&H=JkdiyWgJ$WM z{dGc>1B2u_ddN&&X&XL133CS5V^I{}GjN0^j!g^#{5dWM(M%qOe$4cSrC-z~1RTZ0 zW4qEZt6|)fWggZz&0~y$iS;vbc4 zfpB#t`|MFJL#q7Fo5WQH9z6e+-hK@(h!Sw(xF+SGq$Kd15YCGt8c*u>l-9W zAUEF^&r99vGiysNK`ED^4m&)Lf>l$vzg{_8>lG9hui|^;ouIJr6?y?E;o6 zk9E6$c_Mq~u}gkhpx|XTcF%PfZzu$Cb_FZ*vUiagWQKleOOPEN#tTAa!^dq17@Cgr zEbt%j@hwqxfOQ1tFn~Z?>~=I1;FjOwAfGEY)5<0|l9w$(Hk3h2<2;sX_&ig&lowpe z>P5LICZR1^s&ZL&q)1yJOo7c+C>WGA5Yr)s=`tqzVq{ANdgm-UWcEnaNS3NW-eTO! z61!hB#PmjkTr;dbrD6G1;Bv!`phtxfnQSxU76&e^*F>aIahzrHHai~}glWv&md&es z7RNXrNYJh5A}>!!XV;>J0uOE6Vu1&Z+^D<8A zxUfk&Pb8BKvP}=1-BzPrslfgETAUIMWcC!qyu7nM`>;2@L- z+j7Z(R#+x)J`u<0f$iEr11QSdxJW#-HlE{v`&n$c3JxIHG7t`Iv`V&Y9#)Sbtct3K zmJw)qER|T&Z=fm%FKy%)IDeIZ!|EWN4Pid1AC@@w9&a7PUClOh!!83KKwxIqgFC09 zUANU6V9!-x&tB{Yk6_d-Rm7gXV9!rqCzd|@>KE9Y3degl)53|t5(gqlM-gTUtT;Wn zzcd{xyy85pu;yH_l>vD$kFsA42l;IBqnGeH&sxR)hK+4{eT)nHh7&#jX{_Ai$UhsN zQdF@!z#wq$V|Fc^C-D&mPM>ga4ukD+IQIxRwc+9TkxOul9L_}VIqJ{YP&hZEKiP%x zY}*2*KW9aMMp1u$E#P=rG+LsLOa~D%u|Tlmz>J~z6le z;je!s#&;dt01AptW1Wp%dr@o}7!KsQB?tQ>vgK|x>*V|5g3H-~Uwq1=$Mj!WLMt0RPDM^$WC3s=A^r zIhkzeHzYMdte)X`fJ?Uf*(ZH;y0Yof6D&Td2jGJt$ooA@BiQfFAX@@2))@k(S1opi z4(%v5!Uy5BLbjG9RVRH=7nA7TxeDS|np>(^n@sm(uB>fvE#=PIIMbcAdGIj|h_iZ- zvk04O>1q^2_uZCCT2}P8OgFLER5BEWAgup(0RARtL7D2xdeH}&+QBvq1>dl|nDoIs z@<`d>&Vsw>V{`;@Wi_zEc#`e6&_{@tOrQx_^#MK16H5*UcusJc`r`rH$l!Tm#&4t85f#y1=3e{Lle^+6Lf2KxU(vK zFJnGN(5xeHBc_6wZfm9B@XK(rsKnN_9{w-OXzN-}TUR9{n=h{6TNj^!&o`^1^O|;a z@NyRdfTQe|X!bcMGNH*-`Y7_*$!KusymEOzXVWn>y;uuww|&K!&9^9R*`E)La(A?2 z+J#}}WBfQTKx1sd7>ADUm3(}ADdXE!Grrc1@_w2R>=6J0m~)WViRjW}fPQ*B5gr&> zO4g32d2T9s5r{gAHbM)t8NX1WMyX&QCrg_HsI7=o7TQUvuK+NIjSvuiuR{31Ep4V% zMKkdJT&$`zFo(^)xq(JTp^;$!UgPzse-qHZ6h428Od(zIk#ZaXc3y~3I`tZi(t%@t z735||(F;2JG|w8pudlnPg#8+x=*vv9Zi2yXa9m85y4A%d&P~}vi(C4{*B$-7wAW>l zTT)7SQVdp0UF;}qFJ+c(wCE;)$D{o>A>NBsNajod{O{|j5aA#8zC4lkmIZ3!SyO2X zNLUxMMBbmq%)ped>uow(*Y_wb+9w2B8>m+FNzrvN!+i09COfG)XQVE5F(atCy?6@6 z7ttWKp=ngS%(~5G-6jzphw#1-pL{nw30XqS0=HU^P9uCCH2Cz8kM%S>yg@oOP=>y?vkLiA1LXT9cs3t~FQI*@15ff@5g6K$YTg&ni6Re! zOZ@7yP89hqzdj~$RSvA%U6!XZ-8*SRcU#tBn_?qXD2oG7PJzX7D2>uA41XnBz|4(S z3nm2$zOEKLZSNJp<2f~vNu5ypHq`cEp*MB%-Pa=`8=7ViKoB>3BBTIzh%AeN@a8G zS>~W&0~e$eKl*|51x_Ryp!B%X$#=n@!BGuP4vz z&T|n?P`$b2JlBM{6gY{LegOs;-#)V^@`wqRb0)aWomK980n;{w36{I9t{@Y1f%%lf zzmb!eU^y{C7ntCuR|+P$(NXji?t`60>vU3Q+Cs!E#l$OzLm9DU(mhmQ%qDjOYvk*Y zxZ~TP7jZ{YY_hj5VF!SJ%K&%eqr*OeDC+wSTAZM?XqN-6HG|_Q8xxH`FF@lz3FEIF zdktd@jJj zfPM(b^;KcLSY~-j!@VMubW=$P_j&~!iDT{4aIYuT#4{@QT1xC@9w6`q`4s0~+rAXE z(r~XOYQ-Wcg}C3io=-WqpcsuijM2`jkRd&b=^H`}NAw8L8Bh zLbw;!R4=u`Aoto2b`+c>*Yg5IRh4@w^yJ(NFzx^h;$BZVik=YMD@JVaVkgAtfsMH# zxL2~r{iHHsBl^+7>uzr?@v#;7P&k-nJ=hmEZ164!>J{uX_9wZ;W7(W*lTF&w5>7P4 z&YVR%_%`{B&es_x&A*1u!)1BK4xwEJdtf;EavMGYtQI*P$cq&g(*ioY=3ksa7HtgsbEjxN2qr=%z zBMK_)=o!I|s@PSX1v^>^iI$W8xDC4hodz zZE_ZQ&7Q2yz%6St9FQ(To!MnqIKD5oTZlzn!FyzdQmBG>6b{)H6Z$2iwsZq{RNpYU zeUZ63-tik~=w6xT+fGE2vo=bd>LL@T@k3?OQP&lOl5%9L2y&|ma4Q_yzFHkPvQ>av zCG{e1<*{yd=N(W6)|FSqj>1Y6R&l?M$MS`S8jCfcP@WU9h4jf0!=}Q31%C%l#cK{+ zA7z&HcYHtFu6OnIb*YQEF~2@?>=*=1kQ>&1N(}C>ZV2LV8a51x7-cq@ovo4oh#q%`q9)$RXR<-u%>W~w}m#9 z0YDMfZj~4C2OCJOjqUGC0-{^0cBdI&1n7p9o&~q!$ax7lWqC$!x&;P&6vB5pRAIF+ zp|J7TP^du#Ve>kJbnTyFdZGm-X*MOjha@QP(J02#P?u&LxqUcps$-#BCaXg|{q4%e z_JK7ayynjK&d3LjMfjBSxYk?3eP4pxvc)ZJg(?uH|E98twp#DBxWPoRNqh&n3i|Gp z8d7y9b5(b8h^pJa0`mHHW`qb5&|YtYFcs8ZSHV(6tG(7-Cl^G* zYul-%y#cj!SCna^mfp%$(q2+d|J!QmE5URBJ+<_6nA#nxrK^zXto>27^liM@kEx}- zZPn7-p_aZ*1ut#sNG&~1AVF&BONi6{<7(-KRa7dVmhKFV3q;&Hc5@uDbc1&l&Fp*e zA?_82egHmPWT06H&1&)@0YwSa#fE-M_vpaU+P zVq?YNXSg}S$&6jQ=91r+FS`E=G>!XjWgW@fU~M|}nHe{b?VEwRoC*_F-%!{w&XtW` zn5n|F({1!(m+RH0$Aq{_*VW z*{_aAAJ|<$4bQ`mf}_Q=n=ND@+DsU9B|A%4h|0x49Y(%%O_>NY0vP!Dx@R(2q#{sF z4!epcna^8{22+U{T##R2vtCN8rqY){1zbPqf-QF$FkfG%BC9vqbUdpW0LCp^XzzQx>8QngJg?<=^cIloI4m~4L*ZlAW?^B4%QcqVu01P? z@Rlrb*qBVbts{A@3+)ML?1UZQkBH@8VPIts1J4y^_8|Wo z$9{vqn6=`e63T!`hLkmNE3bvmA9JRB0t)`Cam#Pafo01YGy4Fybtqn^Pr*(1Ej}1v z5``lGB3&7LSrbQiq(;+v%Rx*k>3tG*av){n;(G8{tU7Ch+=%_o zwEL|$>G58^J0e-CviHFSk51~I^3lq!j-rE5b6jXbj<1v2Y%)g&cXxepRDi-X%Gm|4 zy1cZvXPNo5Vm-P+MoJ+22Rtu*M~=&+w>v+C-q_KPwYbm^e^H2@JpjQj%&{jkJ3CEZN=f< zv*9E*I9SRI!VZ!^YiS;67gt|O$#knC=4|OHeB$mq7ZEEl0**cOt+U_h@f^YrSVxyO zQ2{*uq(6*ag&uk07=9lqrGG^_#^FfMWM0xf!nucP>ZCz32Q`Uc!Gs)@w_X08eL%Xs>h^e(J-*qmlT2S9!Ga6*M7Zo50%zQ*J`^v7~LJf zyPI(w{r&V6zEvIXu*3I28+6$Y|0N>OVQljJ`64aZ=5|Z=4CDvw;*dpQUtt+^Jf4;; zF%!OG$9R|1ioK&VX8Tu|B(%8ke5WYEzckTph5x!*ma-zaTnp$N#0N#$-m=+Wa1j%- zV27bREm-?6LYL@mquMReE_{i0!)X~yJC+6=OIscDLg+I%2~2#(w@J{EaO4{m+MVdpA>DCj=sVnW=#nG+ zf_=;o(v_3=yi8YKvR|ev*R<`*CY1h+A}Ee3qBHq!mr9;1X978kWEHk{OScE z1t9T*?c$`$K7+GjIYt%rm&SYOE=^_b)(SfC?!fA(gj5mnaUi~6Y&{j&1 zVE1E<(9yxmw$X76SmV$GbEyuSqO)_bsX|RtBhi%hn#NWbxe#1R$OG&mP7g`@usIIf zi`xi17l?6nagX!G)5U^1qt{?Y9~q8S(SROuCcNIBK$rB=6|m>r zQ0rFV(7P;w_g$vx>v z^^s4HU9}y!esc1B?NkZTaA9c9na;AU*j+3QuU6ts=wqmt^wzMq?yP=P($Qme*;*Ub z;F&u5coP(G9%~~z_XQZoO3Vv}1jGVo*Z+;v7^7QsiiVfgKqD~Vjb~=~B^da;DYQ4C zWuRsvv%q+a8jS=7e391JAqZI*qAD8M z;2PV2%i_>A7IE>Xtg!?vXB;-LqGyU_)`Rw+;EK){(Auo%>r`lC)D``Q7J{a9q{9^* zgf>G!+l;$M4K(ua)P7OF3Y2)?0?-C4(D1ZpTmcq!0)#TRwF)b`%mSlEgFA2Qg>=sJ zz^kMocstln9tDDV7{j0=GapG6{Cmiw-lHKjTke+pi)_&ji$LR~Dy>bVEn|2pUPa*$9^j5%J{j2)zoH55g=uwe zE_TUJu9z?;z;#RFD4Z3_NQ&0bLPP80Jiz@q6HE0@Rc1eP+;9KA1TV>WfVF!~s%Y;B^b$ z+q?<+`@6{BY&rg0!J(c!4|TfCyfj#V!#u) zl80mg(&hmTYKPsq7}KIQj=#eLaF{-yFB}d%(5=1sDTcjXiD@6p20x8I>3Vh^pYlut z+^z1z>o=&Dp;aB7$tFI9!W=}Ah{<;^Baq%M!j0{U) z^^sfXm63S*2Tc`5D?90Y@=}AnS3VS7uR;Bx%TIZ0_-UV-iu_qh+V|IG6fib*80goQD z^AK&&&{C5ttO9%FBCPSVHr5U5m;>G!iSQjkf)*U0?%7K>M)dBf+eu{w7HT&c#wF<}2GizQV{m>SS2R=ZBk#pi__5d(ljpX=T@A*% z+74&nD5;bC%wx@DL9tTLdO}Kq-qFw7kRPI!a&xCU>*Me&wpw~c-nAYnxC4KjHRH(| ze_)zjFdX>!do^PS<>rE!_<%Ffv-m2wiGFWNePS`PdBOsoFe8{yz!PQ$6YM-;b}(Tb zPp}0OHuHp=f(bi#!u()D15a2GOgP3976%i~@r2uh35L~#X+bby2v4{>n2^d7mIf2% z^8|Y^;clL=DwyEl39Ew%6+FQaOsL`sC4q!ZF8nNLqEv-qXL*V8K#2k!JdbB@S{F<( z^Mv)mghZaOF_+l!DZdb`v%K;kN(NUx~VpI*V$P9{$2&B%Uu zY8=O5d*uGaNFtm>m31&P#v4?Q5TiB8tKBGCb_+moJVA~adN`S3?fB!zaUO}au^sn9 zWGA9PPZg9b$&XlE4je1Sk?_a{l9zy#x?EV5u8x%9WhL1HcPwy`flM47J^Ht4OTk{7 zAfB(o|8Ef<->F10WK$rZ$;WWDe|3G-fdkMf z_O!8BM1qo=a*+rXIU(t+fuMG-^e6(kqAG590F(SdD4@uV)mZ>fsK7S|El$(DYS-e$w>;|hKF z`Q*JL?kG3=^v)$MU>hxL3XUkap;~f|`xQFJuE)1r=UH+J8#1oB#3rx`JahH_!wcaag%{=WMEg4#tRrQ{b7ufE zJ`ZsQfVpGz!A*IL#~Np2^$8fmx=1)uK+qnXr}2y^D_(P9*4}l%7)V>ncGucnL-`s?UIzcM^Nw0V$l+V>T9n2k&Hnv|aTXu$W|(4t)mjka_=e zp8;=y76G3DzrzRFg1Yfn@fl$Il#--8?lWKq_Zbkz1wb300ZlR)!Bv}fXUELLQ34lw z0c9W@4E&e<1(3(K5Pt!lle`OxzksV(VDJ@x0WZ_i`U(C5-peNWEZ{G|{4ai-fxm!7 zU&q1pLzy01@PX+8pVg{U3DfT05R;)KmERJ6CGsJs^@PL>uM$(?0cQ^Us7uWqIhH8L z-H$p+Jg(8N(@&f;kKYtBXO5i}bLIdW)~uN` zc6|IN=M33%sBObKk@NtLDsL(FN=?G-r0*_w(mW z{=ASmv*nCBXD)!_6T?^izB-DB=sb&t!+}+r5%+d!X6__>5)@|8aX^9KSTj=3jXGB% zGl6F&@Jtw+AoF^?_n7Nu9c2#UnRGkvPLD^lCVY~w9afDkBj25Fl+)tXq!*9`OHZVB zgD672oVhres1+x33cJWhJd!!rQ`Gp)vk(yIJ_6C8VtAwE4ly6z$|w>3!xT_ie0PH0 zBOZC(#GOFKDbgU0Q6RvNI%s+%hpXVor$=sK7iSIZ5_0A50mW*>E4duD=z7SeY&^9_ zo>L&Q;JyI{tn7F9QbvDdWabnkJPgN}X+}myTy&?BX69-gr87{}AEIbH@)5Q{z=2Jt z=Ye<*g*9NeL(Jn6tRpn;o^D{Lc* zvky1zhL|xbKjrYUek*&yN^}|2x%WuvN@@GfaTl(OAA~-!0z`P z-QB^h68DSc+Tr&@mjimmagh>nHJwY&!Zk}X_X8*I&&~;Y!Ws4sTwP9u<#`Kyk5tQq27m1=?hnvOSg5QJ7i55CXH96}e$)f56T+5L6FB8{Cu-pF9&btmabV254p>_d-N8p1)OolvGJ%C z>S$-hTqyo9>4j?_^6aC)UIN(Jiffg{b=V?1Z<6$q5Bo! z6emFOGDN)(^)mG95HCX?z)CrY%6^uHM)B4fu7;o+1To-nNcA=ZCqss1S8^vq`|;A( zqc7sakj-8`PekC3hF(U7*3pnz$4*%VMSccSliDEl5&---Qp-Y+x+;iNZhNHW{uHF{ z3!&5&JpI;Esvk!xUZqr=hEiDO8e;Vg!K?J!0I_s!@Pb#S-LroJu|n~hfs0}-UL^p4 ztEL~vYi&>MApYZA0IvdMXa^B^_5TTYnI7DTWf?*IRE#g=FG7<*vlCqozRo{wAwhu^hdG!A$xJ| z9BaxKanMPSy7=NIkotzR&=kFz2(>TSjgxb%mop#}kdpW@5)Q(;e0s7U33lzAV_o+= z8Vutci$D;-lLWAyJ@j|T7A)nL=zxmUUyvk_x}78CC8UOHkh)4mO5Y(;_l8I6_s@k# zia-!jvjkFKf&bUA=Wf&>)hmG1!Don42MDPG{G(FJWm711FJTv!QmNsQ`r+B|ND&A^ zY8L^lXA3w|-L*(LkR&KIfg`n%kV@4c^$l1CAHI(XyRb-E!y{GD0a65lkQyM6s{foQ zwR)z8Qa&UJq@I16C{;yB4bcqWLKP`Xhe+KV9;pvEho=;QAf(C(U_Benk@_-SgH(0^ zDKkgPMM#a&Ahi$tg;Q!fVHcKCH-txOatBBe2tw*YB}eLs&xlgnzIcj|svx9hXpnje z{Do8MA;K;!r9Ow_r!ZSWTn9)I2tw*z0$9(Me@c`ZqDAUaBne7oaHI|qQcE>Rbyku3 zihhJeYFBuqifJN;p%j52q{a)RPMjp9{$SBiDl&jn)ssZ2Naip3EDZ2)#li(E`sd~aLETtBNM=GlW zqzD8d)lDF^;}fFPom!-tkR*`${S!o~&4ko!4N|jIq(*m$)b-(!s-}q?hEfEAkh-4$ z*0cT`sYBB>l$stu>W2zK>LekxT7%RsFeOf@CkVT+l!^?G)UXbaA`pbsDFRr}%1#ia zrf89R5lMnl1sthkgw!exQUg?^3>_l%6+E7WS$%(`i5!Mf1cH#7E0Fs3I3e|yX&OrP z4IuU5pNLXh38|YjNR@*raY`*G?7~v&)9^?|bbu6rAf#R+fc0!KN2-?=sS+d!N=@cS zZ6Ty=8l*0ODRHDu5O!gaY7CFm-87NIP>MhhQiBCj`;QT&98)!v`WKP}Qh$D&C{;~J zEzlr!n~Kzp9U@g79;uILB8NeWKoC;v2w*)M%aQV>YLL1)fK(hus+^D-qe1FjFeOf@ z9fVz2O8p@`Qqwv>ia-!j-#^BYdip3)DqD-x+ei|WDyA|w)DlvQHAszDk?P+eQu*PL zdVwZ#7)lWcLMmS%W#mZh#f4Wu@=OdMb!He0y>O2q__s(zFxwVsfgs6py}a7s?8#T_E`HS{E5_Njl;Bn^WUfgq%wCxG?L z%8`oHB6S~<1f_;?q)ri14h>SLz?3*r`w6?Slxhl(RBi`I5eP!6hd|2PM3lN`l7>>p zkR*`$;~$Aq+X<=p8l>i`NR90fscqqrs-=k>hEfEAkSZd8^=u$Vs%fGIsq_F+5gaK- zNR?=idJRm8Q|f8LE-a-U3XjzF9Uw&@2r0IKBlX*lh*HzFNWF|CL8-f`%ndsTsYDG@ zgH@!A9U`?PJW`L-L=HnK0zpV+3ZyO`CZt|W0i~d4gTf54rl6zCH|y%t;$Tk>^>GZ_ zxCRIRpeJB5{X!v>ZByMh)W!#) z*&2!gC<*hN9wio`uOl`)YSnwO@8n4e@P`(#7%w^qPlpqT9kWJ@o{q z|N5A%523O#k9x~K`5SD~;6XvD65BzQvn8m~T~ygBst8BUe|!LroW;*q=;!Ho@h^Y! zX{?XgQi@u?v%+#fjhUq8Feh?Ww#jj>!Fa^zkwp=gj4X%pVK&U>ge_PL8i;};)q;cD z6vV^R`j{r_ZkKR5GYE^X;QK#-A6mH<3 zzp+lIdlj$AVC>k?#^<%LocIb(Vod(AY!2YdvF;dH+2t+@PElBI;{`Bq6-r=Z4!av5 zJ^IN|<6~OJ+gQ~AZnNvrC-E4a>HLBvjxcFoH<9WZQ8ykoE6|+BWw5Jw5AYqXx-cA< zi;Pj{v*G#aE9g-?`m4z$Hw;m1Y$`y*w$l@r9#!WtPKTOn7`_xW_`D3Z7v)2|bAvYZ zF=iU8Y4^8ry*)pheRGgsS_PLUmA28Wj0;ox?KY*`dj1}h&7Nsf1mM|>9|EDg%-PHl zro_aM5(~qW7!xcpBb!YOQz9j##1-vJ)W?+2!l`*nV59Xwe)hdEWT>TSydg~KH^PT|$g@0sa`_i|yFU`tY1N6fS`_wQc9trDU0xA&ewhDlPV2btf3gRgIueh*$ab z?!4`8>sHte|0li5fBPa`>?vO5cd+5xu>Enb@-S!G0ZXgDAs=>IaPNaxe&ki&4$e-z z&10#wvDxr(Mz7mo>{JO);A|z&WRM47pbpD#;`bP{t+=*qVz-dpPSIHmAUq&z{mNJ2 z?cCNV@+*I)8fHt&@oK}%jA#l@8ihsGm~&)k-Au0x>CK|FnRP{W7}q?TVTWnmjB-(+ zAa+G*i)nYGJF6;1+Gm>yWbzx!g08Z$^NCb;JG}y^!YhFB z`^28jTn8Y9VlCZCYw3M_{NGqhf5uBT&00E158JeB$&G}NwKQbBW-V=?w^N$6G>m6< zu$K1Is9k<7J&BpAtflI4nzd8}&k&(&X)m%bzn0#|+nM%j>D$-;vukPcYyb7NbnQ|; zi+Qw$|KVC1^s5fnQUlCXFo}P3Eq!_$$KvO&r7fuV<7;WEK!euO7h8Y&TKda~khOI7 zZDlP@#G<004bRY8%D@MIxg?(uVH>6=kCUbpj$sYoLlXhVMie;}9_V3R!`wG0!4wjb z(6Y68Iv#4}!HbLBtO?n$19^p!^V!}84HO?f!a}*NJ(Phel-EWFpp0w_WsU;n77k^B z_YC#rRRzjXI<#31A$AoG9S*UXu#XnQ$NwTQ9L_Nu?;ThO z8cxLrjg%6^V=kySt8fN;?V>_GC5XqhG#~EAAb?C&%&Z_Gzh^@%4?2ai=-H6Lw2>~V z*yAWgGvoO>F*7*4_wf-1-Y>(!>!iY~1ec&;5%B0R%Qnnv2k#dOym1OV9;D>fPIKK-Ir*k+s`#=!hpTz>s$?*O88o7m0^O?U^)1RT?;XHF84Bc*3 z;k1n8{YePlpE3o`qgpt7@ezh@6T-o{2!inbtP^lr!uRJI1BnE^Ua8m8TIBGuk8Z5~>m*-grwx2!@X^gt)a05}XhTDiXVgcR&bIUl1WaoagZohHeSr;Cupt@cyh2aMp+K zk3oUci^EaEK1~UQb2C;8g?;jV9Xd&P*r$~Oj+b=$FeZsDM7N%7HgR4zz&t zSAWIjz_UUQ97KD>S`~CWK;sn)$bd$q6jt}Z) zJ6Jchht*4kwRK1vSS4*?O;BK^b6DfOXQ*HIDXcwm+#^;5hxr3OG{dOEToDfD4Jyn7*9Bpc za$SLGZVz*w0&@|;B$H!S{0vT}&E)(t8?OjiM1Q!AU^m?W%{$&0E?S5uP0`+lV!UE6 zD2H_G9eo!FQ_hh@fJ0d2Q*bc~F_vc*A;y%z8XMgkmiiH1xlNR@op4GA&B5s{F*uOI zB?pfO!G_Z`Bt2589d&Fh<1=ym1(ih!_s+YK!3NQsX&>8#@}TPx@wh~!7ftA~ath8u z5lGnE=)3?SG)a%sMUDVK0zBME)}VwE^<@)Y78I<LsuVL?K%-1*>>4FWUvrNlJrdPf1*#9fa=3G0Q|0F}Q{D=BH#i)R-*sf4#(Gk{z2wuOksZ;>fVv>c#WDzmRC=)SWkk4b1J?hZJBvXr*Ss$HXgiLZkjY+1>=!|p<$Kq0BlDQ}* zS!g&GMCx+{9o#!WU6+lSuf`O$xJb+8fP?#ayZFhxh$dx%+Jlleu~Y*SGkzZSD;~?o zw0n6Bn}s(Q`FKPv0+XdbhUJe*w?7b=teoweh{;NU$qv>iv;3JrWBW6-LwyH_s01b} z2_0qxCc`jm;;#gT8G)We{FTK31TX~(7z#{QemV(Lg)rjrh1A$&+tDFsQ3=AaJcnPX zGe$)%S(erXup0sF@@2jT8%1<73dnLXg;$AC!8E!lTt>M}voR2zY@H@L*%vl#Cm-bX zl;~t7DSR$dbTUnU)aYbS^5|p;CGwB}`CHr$(KaC=IvK(R&GaBTSwHt4+8NoqkM`;? zK-n>0oales7-j2tjIxbNloz;-CRz+ppqNS$kq{t8g3=3YNN4O<@?_e3It7!Nsq_-a zStsI@eK3Kq1T0t{>E(mH%HRj%sk}E=v&Hd9Wg?svHT!Zf4_lfNtE^ZwnaN7k#(2O+ zgm+P+y*z+w_zVo18t=uT)|{o(l!$R_Mvxp0d2H0WyI8YFP|o3 zp0|znvKnJUP7D#SZ0BRN)Yh?dtT8S7^Wd8zZ2o-qmx71B?b+XmYeL!Imq)|1zriT? zZ?M0*0ioYu=35ER~CH8lqBlfrJO=WHb+26}n&D?0q{#K3;VSf(=%l^M* zf6==x&;CAwExLyNz4?adb{qD$8~Q5Z{9@W=a@zb1_D59yFR{O?IA-D4U*FAw{T&~x zu)ohC3Gk?0|GU{=_dX%)FLPUv{S8oi5X%1gLc6D7f3r7f+273Hw`YIv+@P?(#wul& z2if0&UuuWCfJ6L=>@P6P0rqz*0Ac&SQvvgH*xwB*Y9Z`zB(MwYq=9&3-;Lp5B2_Ry z%KpB*QQJu;uh*XaY5LQS{XHx|K7vc3j@aLOa2(cAe9oW8{)Q@0+OWR?N-x^5zs|wr zQ1QV9F|@HJ)dgY4ztOwAV8hW)(~%nPzVhiEdBJ)}0)mi?_pwQ%e&O|3awso9SG zC8yi^Q$|c>f1i!MJp0@Ad%^x@VvW@lR6--{KqW&*NEu z%@NlnIQqFuZ|A>x$WDF^gTo$o=}kyvbFWmn8)`ymZ?qa^pv`BW|)<%qkLga+=U zJQ28)!&9sU*u^V|nNf9dmV56V43|JjIm=x@31VhDYz0^09e05a|Fk{JiKu*g2>EOT z@qAFnj=_+FAMApWrJJClQx0~YA&h4|h4Jhc5T{-X=AJ|#PvlY{&s7o3Ig0!n<=4k1 zuFA&iXP3p9>E1)Y@>Ukj%Lye%G&Is8nvKYlR7z{U4{ci7lgUWnrN-6GD&)SqMzVO(tRb8`BwhQ5O0T=y<> z(0IFI)2Av#=cj6fBQ<+0h(-qU4#&jAV*6rk$|ZfGZ?0_J?#Y6W?TSF;v(Y;Hf_x{B z9IUg?BO(WmmwRRqg2Z39qegzp1|o(ulB{kk*sh98{xl5VZ?4D2!n>QviXd`%TP~;vF`!gS}=JB5EXRFR5APll5!Xw;NcN^ZJtuX&BlsMSZVw> zPNf_P986z*o^xj2Z%2_+XYc9c=N^g{8k?9dMg_C_uARz)OAXBGJEjxIrs>2FtdIYR zb8M+Ed%O(XTAWm4l@?gPktoceDD9g{$%ztL?yj~xP2OWiV}bT#(Z0eacZgG>Gh#0L za0IV)bceu4YIO5jGGDVYpI-2cQdX7*~LvbRFpE=M=vYAuTjpN7;kk2zpmtI5Z#@s9pq>ZS%ewA#Dioj zgvMULN3jr)eA_`+N6~|7m{HDx#NI5XT3sxUG+M$EWx8o+HCRqsCfsSu&tk&w^bBRf zCGUo3!f&D6PiMk*l-4rg6Qn5#VZzI(J;8)05fe`MNlZ8gzK+^3;Y=t{J7&T+1am`~ z@TH+Yg$aMTU4a*5!kJV&qtCOm3`V8Y*C z7hK*gkWv1>W5O-5VVLlk%AdxBzj#4e06`}F88nz0CfsYi%7lA4+cV)uukDBlm#Zze zWx@}l{lF&7&#J_P=b$01vTUW+&t$^=m1=F6a36pQ&fq1y&`)B*f!V8N!hapiQG8{q zAej`F32%n_G6?c(UY0<%W5QuU%oHGODu^~rc)XI{h6yJsFxwn>`v#LknebU!9x@PsVbpDKvZEpkr_*KHS!`IOuw; zrx4nSxkL47c&V~kwQv({D#WiOz48Z9!-cEvalNzUHsRzAEbs+vA-bUb7`YPyMWq7FV zQ8-gxs`1;20GxDpNkxubql5i^9PX}-Y!s@?QZurue4~P`d^C<)A@B7)Sm!Vd) zG9ij0CK}lv(F$r#FY8jW&s3TK*5ZqDnj+PPo670jh%kAGJ4N1PgJJRxKZ%EMgLEoU zFX1zUsNK70h`I)v9v;vK_rijxJ&^t1ChCm5H9x}M`yXL$(G z>yN^v5f=`)Gt>Y!A3~$4VB?h@5b^6DcJVt(_E>+~NU2+ytU{@-F$~xkta?VHq*)tG zW>Nx9_&k#R^?^wCYU?Rz-G}I;QXB=d?@7Vzl`PZ=AJ5+5-$_@D&L!KSh^Qpx%MPJ@ zsnjujIjGMC!z9RmgmfUVz39!y@KhuS5E-GlP5b~FNrj_%ZR{d1lwxr#&vX<$gvj=M zq&fZ7;PyRJczescq=K*!Vw?k!!ye`#?koBIK6EfVo)~FmDk;Q0bTB(SS(W$-=wK!Y z9Som+ZFDfn95E9A;Lx}dIv6S>bTE}{G)_;@ce3+W1&8P&E_HYZOZ%gwsD_JtM7!6* z(?q+ccFXb}b{172+Pw>CX1Nd@{WjET6YU<|z}qLQgQDF#a6iwZ-S3dbi)i=la{B`I z>MJ$T?jO?08&(tcMjr4!M&|k?HRk!p;L59HCst$6tYh~*MkmVP7O@-Om)#<4Z;JK()3=D{9&fWn?14%~-6AfC zE#lZu-6E#p;-<|OF&T={j<$$vf_d$?h%c}FceV)cGwKTYJuzS?1fdq*&$dI!+R+xV z0sz%5;(n#NW{Z%5Rkd5h!eH`cw}^PO{vX^TK7IH{wus$Ns{{zyBDO)%8QdZc^Fo>} zf{*n7lP#h*N34S_!t}7%B0lUJ9HPT;IQ0MF7IEle+byE!@562pudm`;#GDP-BJgV6 zc~%p@%vluQi2`U_;7*apyfq>s4<7!xrN-h;^_B)O4V`ZQO8ts|M$#u-;I1u-{}Q(b zrl+c%)z}^zGBZ4R$KaFU0K4-kWnoX}VWMIoTP%U16JCaQ&xO>P5h8Oo`VUVWCPlj} z$9%C9M@VM;@Z=qr4^l(j<1vELp``OUZmEg&P?|NBYz7K)USpv3SZX~gOzZn0UQ10A z6QwKC&?4G+vkz}EhrJD9hbDydnw)n45jJkBi%OjCn-geq2UL%UK%}+_fnFmg17|er znc3*L*lFd^6se(TkSoe#`97s-dBk)DQkDwo78TMau>2^{2r-;MuUZORUDz1`#&Ezn zW@ELlktGS_Fu56BW-Hg~bhkhlj3!^hkxA7a>#<~Obs&zl6t~)#EXA*m#nVXlD2V0_ zk$5A$DCymWY-bsTpD5S@8hJ0?4N-C1ABYb?Nbd(H1Mbq<;5g1D6?n|(!UJ%G7nLpX zZf;HH;iqEvo|{lYa3(qhE%yI_kd|>e`xPF}|JCqm>=5*#a+5o+(ib1dp~+!mb9e9@ zOC@xNB)71MXv4Y0t0P(G*`(?^%ku~wRV5sTShmPfXcJQjL>}(p7mva4qu85H-v}kp( z(|C-1cnt;G$4v=J+dy^h-$zBQJ7PD7A~5nUfx1}_XH4v-#W z6XaqE6;zn+peL3&h-k9a<>GgY{+)Dh$9|87VFixIbVAgt;kR@acxII z?kHbpPa}W?2ez{Z*?0vg^d9BHy0eK*K)Y!IIh1JWNy~U+4!Z<_MC|J~(rD(bg9uGe zoq6k^#CmF8wys|jmF6>Tk8oL@_jSRuV+y9c9^=GmmId?M^)RvJf3YLXp=dQYis|?T zovFlupL9uQR@;q~_fCjQl&-;gHfht$t4(s&dM^G|O+%Z$U6|-NAMX!nf`RaBV=evggQouD}TIhaOcs!jm~gX@o~8 zBfQ_mujTza>2jXEREz;W$X4`#(kzFqQQDNYf%Y^p-zY{QX`^X(GeX}fnWmCwfpR{P zwE{l^plu51{FFLV>4V5YyH}%KKC**QS(Y5Y7gyG~_MDWuqJlup-ffU}b4Y~r4Vr05 z7mj{mi}3v#%y&x(0PN|m0I1mrokk^^?M|LBVAlM61ny`h2YzExJMV|er4uEdz86)2 zq2~_#m5W@%nhO)r&Y#gDIY9qf=KJO88Zn6EoM~k*ZM%3tp-YP^J}{MjFmK%X1NMt7C_a zz;n9uHF|qD=jY$!(J*b3%W%L_c3gU~iku&?FHp{Wu@a_y;pa#8Qb$Jmg0( zN+NAfb)`1+7mB88|4#aa?Fu`g$GQbU0BFl%=|BWkSu~nFefqlqB@)6>g0|KD22jG# zmJ%r5o)SRJx!;T~bh->Bz8(~o5@zb}zZ6Ooz+xsq2?OO^P$)46Ih+#NpoAMcsD=^= zL5&%w1f97BCFmC@kq|N7S*Q%N$AB26C**+qG=1bRz36!4_BlVFF!aEgnbfq8_%%!v< z?ZK`WwiPV9=gH|aKX&;^JCLdqagOFL;Z<|2rriVH6ZrqX=CrNK3oF2FC&3QuR@mu$r= zh6vL`r5HzNQ5DFwg~){)if19Kq0=7nno?yT!fx^CXM#jyI4PZg*=Asi2hbHzI$q4g zz?AwR%K&z0-}fp3p|&m5w%SZ@S#rsB&NXoq@im4-ygHmL{ttCu0~ckL{Xf6}qm0g& zqoR_cqFGo`*ruU{;-ICYg9u0p+NMU+n=kW-mMAt*JUq@X+if>1)7s6n&E4GI#MW#S z0#s5oE6kVJvi8!DQ5j;A^Z%avJkPwq;7iv2{=eN%IL~vRd+)jDo_o%@=bn2`&%%NY zP?AdQU2NCdLSReZ$KDfZy=&HLC;=xl`{X+eC?_!8^SwDVmwM^%R zVEVDMU!eA+d6GU>^kYI=Tm5(;8opfpI9ln{Uq9}Hc76JB9Rw<0q{p97fG_^Psvm#H z0`%j=mHzti3Fu^(q94D+8}sVNUlmegs($?X|H!xs)Q?|9{CI!;xF5%;q95}a4%CmI zv~&G96G|GSU#`-oS3h1yDuSXPk5LLc(vK6AuKo4nbJ%$Dnbo3lhx&0d?1%n9-^+Va z^kXks`sv3rj|8MBW2Vou!vQr4qk4*s1i-`dJ_^0g(CP+!U z7png+*N-3iQpUtaH2J@+9}fZy-T}AOk0X>Z|El`&s8WUN`1IouFncQM>;?7XDGvnd z$E`3s2B~|o`td)YYH_9RBJ|@Y(G?MppME?WdsOJhc}gpntsnPS!3ofhqtWq2>c{)B z#|A*3lz>@sE8KriKfW7%w$YDg^$gUHZvb?^f_}VyIYxI$`tjO-x7Cl2ELHU5c$j*j zAM;QGDR;v&ObsQVXKx=rhfo5Ye#Dp3c)b!zAhr;p1b9eZL67hQl=_hJ9*&^Ahoh_v zH!CUWVOi6Sxd^3roi>}Y8cwh>xP{=oscbv^2`S?te?Q5}9^>zk>M%Kbo}{EW94G%m zT0@EfO|gHw;zmGsb^^4&4O?%D`)k+U=yHcUhG?*}N!8|-+Y-t~l5)R%8I=3O2uDHY zb~YQBa+D8~nru-#HzDgi6C)Iwq!!qHk?Iw(yi$!~s!2pzMXM)227yr7Drim=*e_Kl z?aQ(uPA+6=;c^;f>G+}Uu+s5}9qAHNkO&7Vwjj3$D~Iv6^JRV4CM_x z`iAnSf;K~$JmZ2x**PI_D2S*2ONVk*hePQSY$&dW`B3=L(ZY%VLU&Pt;&uWV?>tg!gjROnhn^#s>56c(P1) zZ%5-Wr%*xQwR(i7e%OHh>|Qo!73`?xSa3AC%D_6y0~51-1AF6=vKRTRJaw9P)`+kW$AZ^*xG*jUiAH{uFmlYzX8xi1_ z5-hU!B_LqP25^8>6Wc)bv=lj=*ZTmE9o1{0dM96!>pdXX14$uw`FHF=aHVs6Xi|B8&%#k769i-Fq>&+oXO`H*3(rg!LZueZ z;soRcXV;&g%{&Fs-C|{tu<$5>Ketd2-5Ysfo4}vxJcMpE{DKtG4HX2UK|{upItU1> zQ`;MC0>SlOz8C7h+)ect*vzY0$(z<<*{Csew}`@awj0GkPL{TNK2~Djl68tKJ+9J- zQ7i0Y5CnHL^-#WqcFqW^Tjsv1!@#&_=Ym}=578_SNtH6nr~wL$yBS6_(OgF1aW5?} z?g)w>i?JwCaVe%dB{;iaT-@mjx;UPcptxwnXr&giVYKzerG-lz*36bPDxtu*XR$$& zgL&fWl`k+ZZ-Yn0-NM`Gfi^B27q`qC7Z-tkcxc=$)+}}yRKxohHgOkE$KA0S$K5UAE%A0bM~71Z zWd1pde+ii%6)u9zOYi=z$$SwuVV6hdls3FWGB@$&DQ4|?$^1IB@k`14`=|?&`Tx*< zMh^d+n0fJJe){78G9USnLgpgqz1*fRd!ERA9Uh347Z@G&p*Bc>#u@fpo=uVUI{vd~ zWR6L=#WoJ1Ync}E21bB9}Jpju41np!$N@8EFlEXKftwZI<|&nlo>s_>`~%$ZIy;% z^`ZT8YG%INI#1@r7NW8Z*-F^lwpAz`o?2zJQiZY_vD>IhG!5wn)Zu~47z75L3Swk^ zFeu~`#^}J{k+p-zoO`#~J3LyY7@~WoJVYd>HnCg?DT3@{{?aHzR(JGgNKhL8y*R?* z<5!9~6x+PTc4Ww*;x%${dOBOO2{)1tW@nF;sz3bvz)!^)di!ji3zRufi*O|*+2DH8 z#2)&q-=y^9^TCsyWUM72FGto@XJv!}vN9_UCk~|TYpq;ou?RNMX1bYJHKre3RkLDnW9vow010ws!S(brJ#;?ws8bXvpvXvw!6uB zKPVLD&)<7IYB)}gKV{la-O0zw)A+IGPt~T`i+)XGlS)m;`8VB5ZW<9TL)eSFZ8_ek zf7@&1w%zjyk9RA0bnur(dHBWXP$sDdl_fPtDdt0+=Pm9En>)>dSt(vdm>BOZz7sZB zDjp&i^GPxqc$5&H&Wgq0Q+Y`Wk05MeCkzkat7(-$;%cxeyYMAa&3cm)0M;c(4_Z8w zE#rq$J+Y4=XKi{yef0}|WExF6M6Oni2Po$1SpJXR^@X+dgxrYxMnXiPvbG-PFO58j z6kCRtWkg8I+L|F3LojOWlX-?=mW7X$L0pX(+~WX)Lc=Qb-(clQb(t`5#3)^I8omvO zAB3JrxlNYxfFHwr01xdMCS`hMU)2RL%n#T54cd=k@({~6f(U@PA7qC4JWR=c409vQ zHUz+9{Ix&B98P#$j(*xO%zMyRzyhV9qw0FNO>Uhhnqy;7nJ=N?ZL3gRPqm6(sX`go zSXZjT8K#C0330#A!!UWI%(=edDJ$olEP05WVeV20a07p7lp)*ri8`qtDCGN?Qp}+! z@fO!XSt9h@BNu~VHsBzx9m7l}*r%eFKf}Cro!_L$43h`?j(ZviY{M`k6_6E%`Jcz+ zZksY`Br zPoE@)DTnR#XKLjcGDDa~O~3z<+Vob)CvVdoFidKiGt4C3wj7t(zwLYEwq=G{rQmTY ze`%D5KMftqeBz+8q!N{4KGd7M#gQ;6&@7mgVh(OkZ*jUJD}S8kn|hUDQmQ@XKIEN# zVwiQ$b;L0H;?$qet}@KO@)q?x4ISHnR%C|xG#cHaKP*;p8%_Dp^Uqrwg!- zMzhdtGS9oVsRq)Bd17jWI}#>R!`9S@%2aJgu41>1#t5#&1u|H2aP`m1p8EsYlT8j+ zD0ay7M`4A)-1%j8im*oOxdXNz7= z?sWul04a;A5fc>_i-Jv(Fg%`Ln=6fk1!gd;EdyXmPO4ngCoR4SJ=sDs z*^}s{a0OXf#!HqW_eTJWqhEZ>eF>ujy7h0=Wo2EIM)!8sXl^{1xVt1nN^FK3 z_Duvl+_3HA;DT+x1@71O1aiIBk?XZR!99XzN+*31pD}zaOm_zpT}f4aU8n29%)`TW zm1am`)$Sf)7UnjFS!&%;V;twg?BTD6p!HP8IqkxAGPsThlTsc`;7FaF^ z1v7;(Ou0X)*ik!{X;kS_;ttu4*|8eO>^RNTv`lsez8jMH5P*G8Lq4)_m_r^1m+CMF z2H+(8Csi%PMZ+RoG^8gh`=9s8&{6~&A}@wX@q-+)wa6=)FJ*IMm6v&L=Kzn0%4q;?^k_FD`Doi-`W0h>JRa^Z&27C@!aYUd`TpmSO<> zO5!3xX*3Uw{$Casqry0wQTfLInz(o#8xay0rz}1$EYiCU#l@qc9P-~@Tv&co8DcWY zQ$<`%^aHdWD&NJ3i!iyR-$Gp2No;eOrgH7`iVL&+xjOBaAug^zrD8|z_yXc$50~AS zEG}lf*H&Dt%eq`~5!J5EJCrtqh>Me>WpT0i&p1q|WJ~Yl;zIU8p}h>$FB2&~9~J{4 z*orirXZwP05%0vvHu}D8vunZOGSXkOD-N1)@@izA`M)L>%KwdKKOLYApE0*w`R;2x zQ_}6v`M*Z?DKFRaavUa;{OqO(WGhlqFN6mxBrTlZArieg)bTZK_>NBX^S?2%jYZg| zG7$~J|Hh>F-)tiP8~$~dX?|bFu%-O#8S>XL%Gc9Z%HBG3WRBe}0Fp9|NDN$^e;pk0 zb?MHS&RJrvQ91{g{99q_(mS>ABY5{^@aqaFt@A`J@@CJP;WnTM#jWJK^7um@4^G&5 zUfwj=VyS7gJJ}e&GpRQJ2BqC@zIL73E1St^LQ9MX}l>vo)ROcXG));!~V|U6Pb0Gv2sEfFO<=9x5X0~QodvCh+^bEF59-}^KzUf|lKu_c#1Nm^b6 zmb{b!Gf6BGz$gIbI*dWFtDxrMxEJrz-I8KS1)0N+Vvg3N` zA#AnjDr|wvF?Tz5tlP0;r?c}c76qRetk;nRW%e%6u_)4m`ORa|?(k!Ej;^>w%_A8h ziK9zQ*RrCK0J5C*$^?f&Orud{?-QK4cmy5*8y&D044n$62LRm;&Lz7DiM3!w@cc+@ z#u&IW(%KXS+^CR|!ge9t5f$prm2$RA`w=K@Pb#Dbf$zP^d#x~rUm3ax2dZ`LuM^fhF)TAF4ekA3TwHevpkbo8=8=WDKOqqcq zJYLKU?5GKxf!$*-VFpBOH7|MwLS;DrG%a8Tj^goRW}qkF3^D_KRB(gMzU90N4& z>zw9lD?p_<4M>I*vy=d<0d~X?yclVA*>QchT4RrptEf15`!+uuZ1=~(?lg`AbqvPy zkKy0%o@Wg1H`mc=Bvb;`?yGqwslu zs&7T;EHFo~{aBLOQ-M2ERWZHR?0Gf`PhjQ6C-4YkgZ+=h526d-rDu)(UZ?XAex%`p zI{HBQj{OzBqKBV9idTn=>971A^KiKPNdBe$TF1LoQzOJlysOdFmwgb9d;9OK54ENp zj)`M~rjmc@;lA#!$LbEBtfCkR8h6vNI(6ER;7pFe)-{CYtP18j(SXnzVwN`X1306y z%<%}XA(QaR#-W!v^rf(u`we}T(@8_7q0xBk9H`O~}2gOxrk(X>!yCwTI3|q&{E!<*=HFzwVmMk3? z@D)3}Y!R*4fm5(zzXOrb;)awjh^5#aNdIN2V9oFNNIj4IE%~Hysb34ubZ$!SW(gR|b9g+@ zQ10L6n~8QqS^Qd?dC0}roay|ULs^U{r#u*96j*-%{}d<5L&+=ay#N$di$~Fd0RJ(h z*cU)|j60od(m(`B6B5!y;VCCsmDd=G1njigAIj8`;hOL}3*?dD6pua<*0MkH;%b;E z%g97oLuVOQTL`R_Wo*e0P$nW2*Ia2nF2ldzJ3z9mCCAz~VU&LXCmx|>D1X5tY(YC# zcH(ee3t;d#`pId7}f z5=7m4(z~P;bt@BJU#hybfWW^@b!+0yeoG}l-O9b4Pr$FGZp}q==iwT^drQSu5OwSB zwp?QB(q)ve(-{~GGnn-k8jZmk}!47nq9>p!Et+Q;Rq zTb))1480?Di{12#)vas4y@0y4KJfwrZXV?w@UNh5y5jJFDqO8<+ z@HJnl7t~SGaI4UdVq)OYuXOwTYUYi4<)k0 zq4ZIPl2`Tssatp9@#593LEe!;-KvLI57#@q>Q)>t4z6y!|Mf3ax4zv(#{;sum5wM~ zvbxm?Z!cNhddaUT9h&M`-P)7(tEpR_4FT%bm|NSZTQjc@SU)~>YyKEcbnG90zX)~f z!;R_+QPr)dQH|5p`P8i|^RPNDUENYb>^DI%$CA$B5%w1)FfF>22_F&mkIs}K;-TQ- zbRCI8*bfp98g^KQiW$rnD)yZ2ICGcbiPg~L4Mn+ha&~5_;fa$_DiK%-e;o~D3`ME* zz5)8)80_=-k78aFVqffN(AsC=6--$TT0`+&_y7*f*sMBSTB|L|Jq1rrGqc+CHW+tg z{SfIVwsPMim?Mrw{ktJ;=hu3A%CA(MC#VHO(L4^}?+ryR8SjRoC*>dZc?9KMj)pKf zhAZGsp@-r+l&iQ2K)v;qwy2+g#(@)H|8{YLv0)@1tUQG=*1QMtNasHC3%%9W-+v-Q z(Hf?)Q$z!WInF!v*q!JVh&s`Ji2r#W&P~zh!GU!c+_6r>m2V>N+?jQ zFPno7>esHJ-fRvDc=TVt<6iMwzyGA`2G~}r>vuc~|G!wjQDAky-TM7I5(EUc{u{2} zJFfXP)^E+#|E=}A8fgUrk#jlgcPv`F$o0GIxeKh{)k80T{l5NE;OKsf_1n*U;q`mR zRUNJ02_xn88&mcoDR1-fD1C=3`DCTHFqmH1N@yFh2xeB64OHZ-grGi*w6fBMaPxa-PS#$uE!YEUX)<07X;yL3u>RQgh zo2--<2l6&hMm3{Jn6hL6BQ&~~N!=wS+KV)3{=(I~OAKPj|RT0(fm=^sVPFG6_Yx@02Vm0QG?Yd`V;C;tlb!EqZr?Z&c6M zs-p_Xzr#mm=ZSN2{)Nq>Vi01V*IhT_w}k{5{G`_(bEohcw5lQof$AKB^VhMioD zLG(gLs&ALlh~0|D{j>r&RU3-`2US2ZI403>S7FSHeJFWe55goV^W&4yG(ow@GC*rQ z(w))Kd?(=(WxoCACd50Aj^<`3E<>nu(K9Y^ZX)=z-`u>ukI-@{b5qD`v`fz9M;yt1 z0Q_lCAOOYkvkqC78ukHSzBwQ2ZMW?NVRqmK(5MymK#%EYUS3ASZaWVypcMvpgw(Ir z`;a=-(Gn(fI78dT@p z%Hw5KDcErNv8qo|23B?3U`$#EtSSy&2W3^&ifOws5)8>ufOeE4v_-_squ6yJ^L+(zw+iTWjQRkAOJV`0q_{_(C+1x zi}`aKR@KkjWZRW+X{_pxX#Db7)f;Qo3F?qlt;Q!oSXJhp3(ZYW_;RRg=Dz-cb2EcK z`^`-xZ|+j&=A+#g0^m<@k5B>lx?dmwpUTfcSXF_y-L?~SQLO4L8on^AN`h{uBK7>N zsvEw%Fsu3zz4|R8b=0S>+GIjh34ie~|BqHG$ji?An01FK{lfj6EG9$^k$ zs2l&r9XNxnD*31Qc2+sNxED-d{o>m$sXk(0>?N)4S%A}qRlfS1AFFgs3}BV7p$w<* zfIHo>Q0=(ySe8D9;*-^;XPBxy9 zL|=tg9nf>IpJV!7=1o6C6Xul^4R0`JWwQ$c9!s#LzY8Yno%|>n*`C)IG4-Knz`X zt&fIrgzTl^4{iaR9ndg&bOfVe|N1*eT~d9UuIxvm;g5%5hR*P9Nh57bzFwnFPotIX zA{z!BSd-znk)7maO(3$SOlzJ2n;##+Ww9%t1^^aL#37qP1zc=x!dyC9%mv{N*Bp0e zN6VaL;o(oU;DYHGQ{aGDZ$N>CsRA{o4Nw{90V?~vK$ZOYmjhK4ug(-4lH<)fNBuc$ zdvtm4KOeJ_t(-xmqo=@#U`J`>v+S7L0w>OB(v;w`j0i4=;er(_Mu@%KiAfnT_7rD| z4y&leiu6D6JFRI`*}zleeGK39bM_&Q7LOgV426*7kO)U)sMJg9nq)Bwm5DAMiZ2HG z&UE)F%1ZPtI+Xp3joi^1VODVE7~C&sm!5!;%k=Evbod+=n|0aQ+%H)Hlt9x<#{rs2 z%xOXDz2VZ~B*BQoB|t|W-~g@?V74MW-=jZp_z+=HFNC4%uqMa1A;JMErzQRe_@h&Z zKz>U)r{S4wj|W{-<2q_jZ|_Gvz+u|3HA32JWlQiuNhHGBk4K^KA6{GWl_pxaJ&vwi zD^AbRD|jZ)w656f}yx_(lj5 zfjgfX2p)4x{4PgJ__6^YREJAvHEaz@w@zh4hoRqsM%i>XiI9GmgtSp7q!g`auJ`{I z?vu#h7?00s*@_lcynD%hYBn-y=d#ghRP4E#J(Gk52BUI?9*KcMB9(bH6fg4N;KGF| z#^g{6soca5X0QdZbO;%P3MWLkmeh+WTB)nM4w&UgiuFU1iIDUylyQF~@t0eXs!@4~ zpk!Aq#43-wnhuY);4SU|a^F^@VuY_p87=wKPpM0Ola=i!Ct+IhEm-oK*jbd(HN0Vz zfg;Zi3uj&){&=quWiq(#PsN9ZH8(Kr6IQ~O9JJY8ID7;QRm1gbaz2~i%T z0mJ*cXtH0!iO}U}jFxJwj=SIme;2&q*CR58N7yb2Z^F_cS+;nDGOsm0let~cu~7Zr z9{_!oY|B+x=vZL0%kCy*oyMbRdFt@VV{nKUqU#R8k@B;8k#a|D(i}V7ToL|o1b&7b zu0IxDkH7(mN9qoIR^MDP=Ha+w;aeW2@EC`8uRL3Vc$|w;j{f8*?|gW7-9i4vBVQe> zOG_iK$7(nUa(vo`TG?P2dcX%n^JbWfF^Aj^Y=G-yLr>UtjvaRI<*^6XvPpkbr)sU0 z#ib}yMcjFW* z)(iVwM?nQ>1KBOr0Ek2_FQqvx)pTclm}K4@w$m!@^t+Xgc9ByHb>KZe5Qxmg6d=@} z|19(-7a)Y;vpmI}7T0*E0HKQCBg(B%{GhgY{h&69md##2s7;`d%~m$A6vHxaB0s3j z@PpbkkRQxdv6jKI)RHj4n)3Utb#e2$a|v9N92@UD{tAaOysi@ zE==SPO{QsRPvljlIFtxRQ-w_A)w974D%svRmB^0}vaSH`{<}n;JOsnL z7$U!CwK`QG@8+sY!@*?8Oxh z#B`VyEsc-KM1<$4Z_dF7I));^Ak0Sv(p1CJAdEijI{fdWR}xR=>{oyotG0px!$CV_ z56R`~Z7)0)qIrfc+3kwob+7Ab0oTe;pOGvTVb#ttHy*2_jgO_4IkcGMeE3c>yzmG$ zY{&Pc8W|z_3r-l}0!f~rwSa&(o{lSe^;R}{5Y0n$;5P{TO3_fGVY#E3z=YJWnOuyY za8$%1(cHr8B};8Gu2G1VYA+|O!30)Y+00@hk{aTK7zbN-B`1Rb?s+k5EEdaIh@lldL0)Dr zMg*+rA7g{9=s&)!^fp{w(F1vJ%0N0?(Z1fs$-N~8_V#$t-Uhep?adyt@@kt<)@uttvOx;lSrpZ;h~~G<`Q3TMSpnZNQ!E-DgoN%g zQa;WPJp!9*#ioG*Aa7?T^iQox!e(wEbKDcFaood$7^9ei!XRGDKe%|oRwaSds2f!s zDrY+sdoSlebYGAq8@Q54y$shKv$Mf3=YRo&i&U~VLGu^O^A+)8(gqM?UcX?(_>D>) zUh(p$?iWM)iX>CS%PV04UHyDzu&y3$*VQ#jS1Laoj6q(Oc-j2brSikSlwS%zj3a*& zfAKP_@xuJ@+Zaw;7ZxwKL$SOle)#k90DgE|FNH{+=o27bKE~r^p)&`WXD&@zr{lWv z#Y^jtTD|C$#fuU0>_XD|g}xVw&Yy6f;iAy_kAeVnHi19#HJ6OVcWL593)tF=7xAxc z#mf!Gi&a1%gKuuFNZvQGB6&lo(>J#+uz|Y zz(uFGw+y8>h?jH{FV^T^RlI!X@Dnfpz=47yUe56Mzp{8a^$5Aj!mg1HR9uF5*}R?8 z>?Mnrw{R)sg5qTg8mH6iixDs74+n^sa4=v_>KV{LAYQn+g_m9Pd!{Cj$DbhZuPFJUIMUO;0xUa6FwP8w1H7?e|u3p6}eu0Z{ z(0X10eZp7{C?f5E;s73h0TkQN*oB~QK-X;tMWGDEAQ=kIKBIkGdnp4(cs+I+rc6Xj z5i^=#3PwcGMrkZ8(2P(IFVj<)p@JTu%qGaS;^r0Mw$NGb8-cUQ@nOiV-5rK%L|U;l zju&xq1RrUwyGL>J@^0|Sf>k<^g~9xTO>amdcr2)k8=p^gB6hAA^o=l)0Wd#YC@ubcZBN21dOB!AZC0dft0Q{@`be<|X4M$Om?x-qHW~J2#;cOF36ot$2 zGZIt&93B!~BO`?fWY>;x)8Ei7A>N=dFdd8>V_ewFvD9Rg4uBH6iDQhF+EDC3h{V~z zsB@kg3fDu1zBsRS6!z;`ayV8HP8@B!V#%6vv+S5AO^)$~d{Ooa`#qTyJeB(82g#Yi z>%sS%_5fJdzIt?uccFUdyA=Dqm`0>ZDMyc3LUs8goZ3DJ zkt0<(&XEN@GCo7+96rIR&vj}uLa~6XnQ5#O>`6G*HD|9r7AbNG!mC=mG-Bz zJBL!x9vtoH5&y3fu!ecL>|Xx}1CQKmLr&0Mm-+R&Sn1W#ILfywI3QudEJK7YrZb=iB4`;Zk&x1iNol4<{Xx|_ z=hzUCG^Vu^g3;&@5h{&>H;qdRb$1~$6IyK{Y#(@@QWxJOjWOoyAdzmx^;?R`6hFpj zW%+P$QMkD8lRpQ1@-kAX(kDb{<6|5nH1^)o_+j{Wc{h(vni4Zh>gF69Dux)ghL%f_ znYc&ozn*e&%rL85t}E$~Fs_SIIUFZ!v*ZfCIJ8)Ras^NsuMmsEI~O#26x0cw)Zs0%Kia!9;6&h z6;>_KCr6(s$8rAEb0A(9Vs+4Eutqj)54yd{xPG=~TNA>clQ{=Y(d^57tR@RcwPp!^ z;80pfK{z?Bbk3cG8HBrmmCb_0r&B_YeS}odBo;Jf@oW8eet-revngE7J};;JSR74V zP>0>A!z#87i>#bIIR9r)jSAE;ypn->dN%=OBA`zB0cBNzy17H3?hg*s`!&IVqAm!i z<MsOcP)ywx9H@j2fTAu4sD^3|)DxWv zQ{()BdIPUyOg%u~+!RAVwfX@yL3%<;W_f|?&4C(5Khg6VZGZd74gKN)f+7#ps zy}7wO)Q;ePYaCzv%ueI$=JF6b_U?7;;f9}~_9rtvfGS7mu9rxl3{WA&wh^$62W%WumWZ3#awz2GmKf`o}1dC1JX(?3^I$)n*A>%#u%lp~R9!00Ni0SN!aKC=G z;elf!u%8=)_4C~VrJoYHpSa-t^r3#jrn9U3`$-Gl&mP1VX*V8G?I%|5XH@WhUPmeQ z^PZN*GpcNn4R~w7gWq`W2Hs}brnBFx{WQvWyM^#JK<=lEm4U+%!cu?)+C$?+h4vCM z9aGM$RZyj?BDMpL0GyVw>l7H0{9%|I2*Vt}FdHx&M;sA8Rs{ycPuH{Ofh^2j85@2+ z7?A5l!y-8lCGCND1yu8=(JUR8r}p-dHw$JYV95d)$XL~gfRWf_ z;A)4SMXNx(2Cj-7bxNkSB&QYCSjAb|e|w3jjE$zg!l$!4cwZyRzNWtHN?+KV5V59X zz*B5`_6>rL_)qRN)YoQUj1y}L`XZ!LvMb^wDUNwM=#X(3WdM?qZxmlrpC5}wJ z8uTez;55cBe8b19I~tY`&v4=UZJ5WsJ{2cO0W+ak${7lGMfZxrGlPX>*!@zFGZ(Hu z*ee^}4#S}o-PeU;jU6#Ix8&Ie{o0$Nq7lwOzKhB3-xZ#Twa@W6GD|q#l_JQIxtlcK zFZV^0=i^(#1Pi$vCw`4jgr=0zsG{A5;(V|v_XuADcc1~o+m>$7sGGGDCfMQqrDqyc z;SSIEeK^$PK}d)X+&kdwtiG&}Uk33c-xLBi9w(phPVj9q9R<;yD0hlE2Kqil(9?^S zLpV(nh1wOJs?62I)!YN{)!qD&)`9zqMAyoK=>LS_2KIWF!v$Z#>hv^c&e1F}r-to@ zE|Hy`xEr92A2CHMbdvV7Un@_-wrkxXN z3(s`QzdA{%E{H1$bDGa4)h!B1QF^;W?d|VSX?R-r^|;>{28<=TN`O5Vj$y5~&U9+& zG{bH?2!6(NcC%kDK6<{Wd^!WLZuI~qcl zk&7fxlH+vVk23LHxI=ry;wAV?ev|LrM{yfW8hamSF_o)F&20LQ;0twP&I|5nZwWWQ zun*-D^9$K>lk7RPf%u^2?PQK9v1}}{Y{1EQ37j;;&>U!robQ}Gp$k~AvcusMSV9qh zVJ)SKl@S_=gC*zNfssSZc?uwkIcr&O^x#d-qlG@z^0Si4HBA0md}}^{XWj6foPk5y zmp2J4Coh>am~lWi%(FaW1*Oq&Y(;!PN}!U5N=OQ0C>n?tJb_AM1pPn)l^#&cC_&6X zIe|(DJ}5PB^zb%{ToV7+{(8f4yoU#2q6-N@%|&chBamw@43bp#1<%JT_iB*#1Ea!_ z$VU!ZMwFrGOJG&9yucpEiBgIAWm*Xb@yb6yFLDDJ9Pi>KcMl+B!G?;32QFKOMxY;@ z#JGhuSW+woyA2{pL(#tp@i~~n)n3}K#)&MJ6jG_!F>=woihcR5>eDx>w2+V`SxQQH zDkTrk5W>!V!vzM^BgYvs+>{rNN?2i^=zBh=O>qAXZU9ESQpz=UGw)IlMv))1v#n<_(xkItT;#k(epAW%dFYh;5?RU|&N}qd6c*-2lThpk^JJBWj zd+T#P$UaIB!UoV!g9|X=ETJ0_U=d9zJXeH5{05;rmg169Cwkd%2mj3A9E*RYf|B?q zI3Vw5A!wMA0DLcTw%HIzrF6c;k zuU(A06YA%#cAwMI->U`Rq!UC=)B+Bc)`G4DmlstUh)~RMrTOKM5fOGR{?#;>YwcYf zUz`Qm5yy-~o?nIe(zXO8KV#WZ$v4PuOGIP80|R{Y-yjI{3#i0XYx!)T1bijW>%={Z z-WmrygMWc3!lNF>IpSe#A&l=0CQjabK(WEbPn>nH4&&Fg9X~#AKYk;9ZUpF^&NqID z-*)3S(kQ=G$B$8Z$FHN3)9Uz<6PJ%alg3{kF#cGtc#_9I2cwq9Proq!*ue4Q7=V`f zvuLu?ydk9F(=+F%g=89BEO60T#sy)~e!W5t!O)Rh2*HS1CUGGnU7hV@u(L1Tdj z&65lAmLx<3Zc*)L1;?-mEM@K;)HY>~Qc@D~HhM}ziByRbViNulq_0(CztFR=U<34? z5_=chwYCs!vi7meW?D+yNyLqiESr*L9aFTdlBHZC1zES| zJCd8QO|etmxwAz=*~kZ>-k!yybQrr%?w4>3eK^X8A&F%aKM!DkJ_PL-5lLF0-U&@) zj7c?$sU|TsI^F8YkAcHA>$HoXZ=g)tmxa`e(f^?X*`XSHc;^J1VJj=#>C8*9bC*WkJc{)vYd#Y3x*)o91~>z$M1=+!X#b1ghS_puC= z6c*?;_ReK-@k>dlOdK0P7KJykXZs}|=riNZgz6OyE_-RN`ety6nRT?!EN8=qDexPl`WUx{jHp>ljD?b~L zsyr9)Exsyx3YcA`A>)%;r<+oT?A@$8)#1s2!%;~#?106RV1`;c7&Dowg-ro;Mbb^N zC8Z8!$&iRu5vmynh$A}%koP9m8IZ><{Os)XiZTN<%Bl^gFWH_j6R zf8I*1tClKX>zQ)v?!0uiP??w%{>mt0z>E%Q*1lE>hbV=7s6&;))5;8VQVQuXf<-BX zW~H$4C|^-D-^c@828g*So_#S>ne&HXggQ7#HbMbmSJ0SzY15}Rz$}8v=UBmPKhK-f zbIUnfk2Y+2sgC^t^}STtM>Zn?9kL~f3`vaQ*rT0hI1{jJxefPq>1?+GWvUFN-0TE2 zOM@T7WD2`lE@X3?x@(jaG?e_QFD0^l8!|_4WnX}8;t^^;Ph-pYCYvs`sVAy=^%z&# zPFi^)n&IWhK06c3v(y|@QcS9Asd<#>q+MnS-(7na_~)Zd0Z@GJ9gvUqvoEoD+vlUr z!L;FZV1mH`gz@v_qpdyW@my3s+Gk*EaWC{|{*;gQuD}1c<)m~U_>u4b6KKw?2`onyT84#1d1&YQ^3Z0yOFGIb_8b@!%pQ6+j$U+_Rq$TgM)4%HMt+{( zaS~ehay0`jvOZm62HJ9L{bY{;|CE9);4K`)7q`x^h6b7f2@f4kkPx_pFf;3%J00JID|lJq3&}AnR<_e@KC()eBpT-vTCm z6m8XY+*ZxxwrxczZSnMhe(Z_;^8?r+k!$u9{0m)m)YnkdMvws>mUjQ-fg9h!%y*PL zQ1&}j4j&-WSY;24UUupYnuiUILk+-@g*QLiwxiTPj#zOjKD?}jL{J1^3CzCba%P-p zlmDy+9>kEo@*xU>tY96@h1G?Jp{D$2M>UlHtR5?Ye2)ui9CHy~8Lnd3hQTcu`Ogk> z$v?87g7TkL^ZaM7AoXiWevABP4L}m|pCyzHTMRgJ@d!}~*u44A;7T2fH3931 z9QOszY*yAAa7s8epj$%KzWirz!}7twrR-bPa{jYS_)qivXMfoX<-vF->W|E*r)^M8 z;fQO6L}~xXEE9GwhEns%#O4yDKf_kr`w3+}E1eYnrc@<=6JXYqV4 z@XMwVy^i)VA~Tamq?}Vt$0MA~ym5)|pXPT=W%yh^rh+5>3DMld9zr2bW&Zc$5?7L% z@tegZ&TH5DTyW&yC@%5BkDv%%c3k39hky{@@n6Gl7ngV<%o%~Gznr+HKYu~Y_M+kv z|K;-w#5FDZ5FcD-T;c}+kN@a?i@2s&Y~g(9ym5(F!T6#uHm~Z=efrq^6Ij29OB`J` zn>f-MJaQ9*@1*$^tKSlybX;D-*Z|TZ78=>#P%Q0bhL50v)M1YsW(%F69@q9jw>W~v z0ZcKeF<>7>2L*VA=-I>%QIY}gbAAGBcuzZFCkx#a!eb@+!ik=ckEW5w6nl`N2a)h6 zbcTC@<7}vafQgNA0LFGfOwat=8`KQ3?A!|}i0N4bG0l{Nn5L_ol_F|=fN$k^Q4>4p zbs&0`SArbEbdc`|`|*Q;N7y`S>1dp|s>AOI%M!5uf%+W5pM??Lm|bSH5bP8khwlhm zszcaPEy9+**#klTt` zK*-Xwa>&xD@@xc#EWNc}osL2BL>eKyr0!Do^^D63J_B`{#_CYdW@pwa*wny%c<6h*tr(&k~atu0CPvJ{>;dn!r z9&P7K!oEb8ev3!N_PKgK-XLBapMM5!6eOPCb+2O36qM=W;sL7h{Pv)^Hqq*iOjNlU zv$Exf6>cU+Y5ojl!K2k}fb9UY!$<5N&#!17;NtQ80^DGD*kOUk^ShSZI6H{vHwCTA zNDLCs@9Oh4&7;*F#Mx)Ccz!KM1DYj&2(GzN20>PM+=pStE+5EE-uMFY74U+*m;UOQX%bdQ2S@>~QgB9`;O* z>h@|E!i5^u&9i_c6Cs1 zTG<_+D1)Le`{i)2in2w4xCS%P7awD%IR#J}F1j zs`ihjr4$?9)+Sh~NoL)zIwkm`Y0>dRU%F-K)F#EBR_?w~V6B=;bB%^=#Ey*iFEBS^ z6RV-%S|{i>2vfA#7mI82uNaH#8E(EsyqUFaV{z$$9d9hImzZn3 zI?XTPWZ@%ann}@lNfcgSJ5el$DGEFpEirFG+zRqWsUSlcHg9X;^HhQ`TyH=ZK!hUL zJlcfedO;1tg_~z<+lJx7VKbr+p-wvM$0uwPVo0=^u=jbv=3sHS7Jf~$g%CwN?#vc! z^*4)_Ofj4`3OdjmQX(wA777(Nd7Nlfoh-ui9U;hCO z9)V&Ig7Lg@cTS9^@q6R$4Eb0c|6zIj+OqL9ei4s!3C(wxm8Q6)AGwoxZ?VRk_4eD; zi>&e6F)kbs%9mHA$wt8HeWYtl98%VqJOO-nSu6Nm)^Gm>peorhEFJkm6ThWbpoe`h z%vsP%T(}7qdABwdcbvc(9>Jj(F2a6S+OP2Jwf0VhXXEYKH{#tPsq*5@%49PEEu8Kl zIFoJ`w4%YSO)>~{c{Um!3z4H?j9-zjM{OZtG(Ig{d==Y+qqHi`K&ogq;iMv>3VvGT zZH2E4Pr1UWiaYdl9bF%y(*j2$Vt<+vcZ-%&_&QY7@rXKE(hqPlRUv)(VHMJd60>L2 zwf4@V;_VTYW)A_2bGc%Vp`<(6+dN1%)S3T?GdvN3AH|;Ky&N8+U@5#cL6}gQ8Zv5$ z{nk;_h0*R2r4geN>^fWLS)$P5j+TpJM@_fK*mU$Nm6x9ZVAv@f7A;LM!n@;a##y-k zOf~8;tJ}ye?wXy3*FF=?r%)bNmulESSEa8w4uGv?RBUAiFJ07>=GihIZb-bl<$t}gZSM-+5r=-1TFTOhI@WLn@J?=bxI?3E*zmnZ= z3yNKYzjEse3q02fp{I{P)Z&s|sCWY+VnxZFg^JN~*igdw`KjWTr7EsFqzVV-lN>Os zK~bD8B0(3phb!%j+9ljflwnv2t0hR|nuXzxGoJiGL?ON2BMM1uPWohFM1FMAzI@Z^ z!`(kV{i(E*lR{!MFK4Cq1|1<$sLrv^^B%Q}3$CBIcVj4^9B?*ZGt3dI2|_pzEKvso z!a3(7oO6DJbC*gu(^bNm;zu|)5aA4ysbe4rXMj5fZ|vcq8+Q-+wGKq1wdvd^W#W)3 zMd4Jb#vSHIL5x!n9I#6)IP`Y8ufwg-ch+Ls(_s$0W)F;6a1N$Ib{{wi5c{cNhuQN? zSatVLWr`9lE$m&KU4y8o8cx(2={q8;-NNf5g;VgxplLT0J;zs`P7GBdBS~(((*e+|?ko^1i#kj+5#Z_6OPJYm=%M_OxlhX`tWs12CXFAv`Ig(cYhZ zdr#1*LEu%X&TT9#IEQQ^Ekfk!I>(0^e=_{g-Nla#6A$wF&SY8n;L=S@pnt5|;)C{1 zQ`wcvFh;2s_E@4+s8IY0WjtL1FEGVprMmR<^-X@(@fUFeTC z(Y3qW7UqtGYchU>PUjpCqkjTDOWk18S40km7Sd!+^oV6W`JQPd{LJP$2k}MP;*A$;)%sSBG*zY-TRs@UMEg0Eh z0RUy_qzSmhNjFz-*NT=_ltklhxzVZZOQ@d8s$ld1Y|>fx1BelvF%5N^$o~Og=_&7- zF;4@C$j_n*|4JE>Q{E~khztY0|cy&c#H198H%i-euFW|h?oan zjH#yZ7M9j|N!4~Uiryi)B_$KeP4klWEHXI9yf@F$(mQ|XJjc#h_dxV#X-%WQy0ocQ zMyXY(9gcXr7C&3(Njqim+O>Z>p`JJ0n|GtMzn-^049VGI-9!A_&(px-Yh@+p=_8G1 z5p-pOEQlA3bX6g~0Jp7$KCHW)lNCAee6a{Wt3@P-H@8AKjL}M+@EY6&qwI^1dnKLD zH(*)t1@!Ib^1L2*kFkZMkv9yL@X55Y!~CjqEO>96RF_n>0y+&YoO^^8%(~9+yMM~x z&B~R^Re?X;cfSG>gn%Y+p<&n1o=JdhzaDbi2>s)o*NGhf*!paDCkGscR&@a)a6C|a zWOWPU#!euSY5hZGi^#0kww`<0~=LW*|VdzSXR#kf#+%K^hBV&f z&`^{*^%`fIE@@9+*Pva7BBI67w2Jb3vglf{{tD526u2K)rKzcb4;k*OAG4Bc(@}B^ z(pPDY9itB65Oq{E*HW81F?`%CA-;El<_Y7c9;xVM6anbW%=D}PSWZx(h(do@?DxrV zbZ4vg1CCbUyI)l#2co-`O$QK&6pfdisv2^BEMx|R zC*n~s41~Y*^f-i>k(%6LqHxG*ImD)Y3}YJ}YAN#Ocsxjz?oPJQhNU<|#f6W#6cHWk zE%5_3=6$--0ntG#0T))f5GAr+b2ynaVIxxPS{{Yjk7i-~9k^6~AgpiV?zA)>g_FML zP#{hRLE$#VL;fMPjJwm$bNwA(opV%%(P^PyA12<%8+W6Rq{?jP{16DCCInTsq93{( z<=J8(QqP-eMfq|w%d*+jMjuyCaP@|6zHCp3=+ykX%}RDSx=EZ%d2(QKm1 zISucCOXA0i)BvfIUFZkh70qIH=)-hN*4{%hWJ(L{{sx8IS>@0M%X!?8tYr|q16TeO z`CXXC-b;$Kg-n&UR1-n?Ss)M*g&|}szjkXM40FX6E9lYx3u*tXT%wl4T|<#z6Mxv` z8$&b{DFj=cbi^RQXr?*}bf7c65CyOz^RhINh3*tdlW7ahk`la)S&Rq(fv>M~xQx=? zEHR8tFFNM|edw|frlw{kKdg|-<@iT=;mMjp)(ao7&mTo(61WF0pnX@j8j$801O=eY zS1X(IyATb(-?rb%_7sAA2+^5}d4p{N8DYcO6SUANlaO5!bEdZ(ibWW{bJ= zs~&p+zezfY>*&r|)ni-mxBib>jktsERaNn>O#t50!v!E6@4|NLi4Y7U-^F2uXHk^$ zLMmSj%}soa9N?fpuiK7)#dQ_@FHxho!-c=B*B(9-?7QnhT%H@SL@{1kiZ)N)7eMr! z7x9(Gy0Xy(R_T>8h{KTuv&E@7f2C4!ZWBo3T?S7P@!b>nTNOzYz$pd3haqfh9Xw{% z69jg>r^lQ30;Bv%8b4DkrfQ(hUXsQZ;vZzfNd>s<_Bh97o6me#0lc4a1h@Ij7qUY6 zjNNcFL{o@8jDTQz>%k;k_AA?V+=U7}AB$Jgzb}sH=qoCqujpUL3cJRx^W@vvo7aTm zX$gN?!d}LcVe8{WGxN|@BrbE7V9xOB**34F$2pl?5dH;6K)(}=NmHysm^j@ya*3Ay z)q3)+Y+^E0=ltm`h5tK;CGmgrSR()Tein~^Vc`&G4QqH8y*oKd*r)=m-goPP>%=4J zTq`1}yCCc8f-MB|*?#C8)%;G6!`fWFH#h^JOAaS8(~8P)}uu$-DB zl2fWCn+vQ)2&~mR6oEyW5G4rFNlA`xjn1^Dq)+S#jum>%vi?#icGtZ#r?TH+4B2$= zkxfIVPPk`><+`Ih3r?ls1ocL}Ml%aamS3!ZFW}Y5V+HiZUoF%!=E5}vw?3~1Fl4gz z5^ny%Puv?`AS4?J(T>=jGVI?>m ztlv&#FadwXdFy;~T!Jmn>1@HPOg0oQf{LxS5zIUQ^jZNSZto|5h1+-3y5}wGmW2bkaFlKq;vAz#fzUNV?||}t zyc}_vng#f}N*pl9&L$SI3{%J7PK4TKr(Rj3m1I0tiKSHaSYK6@du(I`lXuJFhBi zcbCGX`6B{ew`8%$`k)C!fpQ`G78gK3F#tgl9lbr;(bCh7EW!irk&YItaD}_8EK<92 z5#)}{DVL?=84QjDv0@%cqQzqLc0}{p;!M#axYDwyq$J!Q`Ju_9ao-Gz4)rY3`Uz$} z^BDagN_>*4b*3PIvUW@wLKLSOtt|0jE|`fjX5^H!X~3Z@{Y_9FVU8M0qEqO`Ud>YX zqd5(GpvO3n+sfX6?NFF2Y3HIYOycDOfg|^E?A4%)>DWCmLtuZIQx5Syn~3ek3OMIa zWAEt^%?)P>P`0p%K_}tthYv&G%v>%zA|poAcaG&tG=`#5wC7p8#M5IH_!*isY@HD5 z)J_0{E5r-P?fcUck6;stiw@||xUV}+ch<;UJJ{r6J97>W)ug9Gd8MdY>8$yK?i#CY ztf$9IsB9He?Q*-eP+pyX@*zG!f@gaaRiBLNVy>Mwz&r7N2ES+k*s`R@h>fBvJpyG! zVn&ykBJ5YNq>mM@Phsx5!qUs!S74+&NbF)=cJ?WW(qn~qmq-!`G0uBz2Rz~qdd2R8 z!hp9r_Iv!0mgp#^9|=lDgRu_*%0Zj`kyL2RsTH`uuXAe0SlM6PWXMLvi1>&DEp%Jj z1Ma}@T}XuavR$NDkp>7M8Nd~Q#29*iwB36-y^dpa9$%4SV8DJPU1!KN(yAg_`tD| z_bEM2|5Sw&B;Z^cT)P6Ll$AN5M3lur3E*0N7Ve4s3s7b3c`Pent zvDAq(@>pV93JIP7RhiJmtXDxn;nJ9g=Yt)?W$!w2%1nqqXc1jV3QMzQ0$LM-eYP2m zJ3{O-jWl{-la81Inoo4)CeNUS@D@$S)qo%8D`C=4zy}T71c#BJ_mOl(m^~RKTZc zR+U7--#(#qsJAz<7Z)SS0Rp$&>XKLI%EmZ|Gp~}?nz=&@c%iG}EHTsSSuoDiql_<3 z`^cn9`%PJL38;MNTxe^%5iiyjzGDOg`aDr5mu3I3fuDKK+rWMgIX8|rcjT~pF zmCeRnVY3G&Q0rK7if;0U3i&&Z&dkv`3+j>J*t!A#^YqvPMI4t0*+|qzmVj@q_;Zr} zd_#X4>5rTKd`*8E=nq2*FY{OQ=LGmVnyMvbF|QspV`Z;{9O26Bs2ENi5`k(EnLlNIW*WL{rX(5hrtnbSE8x&jjHBwo}bq+Qub;4m)fnl;P-IE|aLrN#c&|^C$ z5>YZeAHvil)yaD}WH_NIC|C%!7CN;+|4wOQ58z)o3CC_%RWX_EvLAaxFM^m7`j0dl z?T}u+AT-R5GV=6sLC16D?26_K{S1Ovft?1dLazE?6^^6@J<6ZBu_EH=dtZXIXU}Zab+EJYM^FUpJa!{jT4FUYTlF#W#TkiPh>Iys$iCc$k0L|l@kr~5*Fb=DLvQna z;WLS~Jh7IFcH8?)k!g7v30s~_uQ;}17c*Sc^0-3MsQJLwuoq_y_jw2FB_S7W07iOH=bW+&tDd#rS(cnD;pC6q!P?m zPRl7izcy`}EzHU$m=yXl6p=|ei`7knfo=plfPY{_!0qo-R+#)ClWHN!@`wlLU4cJV z_I?CxvWTzS#5UmDk~y&)oG}12 z&~IYy#8KoQ(H~TeZn2tsxi4{t<>6m*;15!SN;NYj7l55SurQ*6bWS}+7)&+o_M!Onf( z*Z=E!U+?Sv|B~EMs8kFnyGvWjomTBtaeiab@G5@GNG)fa4MiV6&9ND&BDoW6C6>da zl7?hIW)8395x)}kLwWv9Kb9n`s2*O$!ekX^JJXaW5fSQ2Mh_c4Cj4>o8#m_Ngg;IP z+|rij@Fue@IiDCc=Lb3R0f02NCv4PGHU;ALav9 z18I^NMYeV$2mPAEW0EybDSwN|H|w^8WydBau0Yi24g!Uky7hsQv7^QDJ3P8RF|nIg zgh{`@fF9MAAE6`pjZZT2#Khes+0PZz)ZGZ$hR7K6H?Oy6Xu#7NfKBrbpii;v@*{KO zlfA~uch1I#K73kqa1}8(23Lf~%-9;nt^O1Exu2rS+_#5hH*oj45-$K+kq>g1)LG75 zvSA-asC>K=WNM(G`!y?rX_p8f!5H8hL*VIY?+HLyMk5v=ZymmhIOxkE9lveI=0TgJ zRUA5mJ(QDbd+D|!t_cN-8@sifUwQ_ss3Xp1;YV*;^4i-0jOZ*)MIx_#1uu0?V9;(M zgrCXLQ|pO4IG$N+0UwLs$DoG8NmWCwW@KlULqp z-^6=U@FwSZY`F-{pxT`F9sG^iLRelQmvd~_MGBUC%RQ?A<|KU9tcm(LW7Zk^$)9z) ze#S%xGs9Ukx*|6t8@J`UvgfllbUN_3rY08CTyn?3QwS$n=}QP#*wwyx{|(g4QOA-n^ldS z2n=Rx0i6IKr}D>)?T=O`F$t3BUV>t34$QB>e&z;LG_zUXI&s+caB z-MM|Y{#k^Y7H_pMDMMX}%Mt2FqNUzQB;j-cYP2Oc11ShbNh_eAPD?anYS2ja%oE7^ zF$4#qNbQ9RtNUm2eTe&I%gP1=LWZkA-uCnis4JU_op$LcV(p48DS7F)c3NSW^PL_o z^;?m#UF~`jbMA?{o%Y>Ip~-WeS0Unh&7&4QqFyggL^pKv7>LFsMF$M`+XNzgu-}xa zx~u&FKk?C51f0#i$}=&G>9@mnn z&c0m+P7_`C@mTIuNxmNd@NDibH7tKogUd6r@$+WgkGL=E+wj z4<~6qT&dG6reqf-jPyXt2{t$S^|Pt#X|w3(AFOdt zb?;0=1|BdfIONeM1dE9B+R>zIs^MdEB{Pz_DJCYE+C>E{i*ww|3y=0}%m`QT{nqE0 zx4aqux@$DrOiXOD(c>;X?hb7IOR%oS{k4f#A@=txfeQfr#o|JI&^PRa1%x1VTVPe{w zUDVAaRF=PLo1z_>EdXYm*~QN65@&X)Gkc0Ndn&g+p6b-(IyHq7UCxkz=<`n^AbMM| zW);$dK9;}QHR_=H_4OyI()s!({at+A`TEm(nA-?pGrnTt3J!(HC})~}qYsMyPJmCG zy6UdED`Bq!PTeABRfAKv#96hh>j9n0vbgSgK!pDX?9)U1l@hMY3g0g^|Z1}J%7;nanly5;HJYs$UOd9YQf4>BeEeU!iS^DJl9(|eZ%oQWO! zJFEI)2t2jvcALxoq`5N{KTetyaEeverB1OE&MP^J#ovwvp~*P=R;K?q_Uu4%)zij%a%*#l(rb54WdwY-Tl5JxmO zay<9>;YT#!Zz*@1KcyD^k@Dv@cCdVPX3dF3x<+Xh&G=8h=jl^Z-EH<7;!IeWUdksP z2wbFMZ+vQGv5Hi&Gt-N)EFc&RrnBHL&OMD)WsxGePIZoi^pD_Ks4%4AW@D+6u61fT@5UQq9@%5g73vteF=IpcgdO{g+4 zZ6$DI^&KKxU;;4M=MI-yYhR>TB79kG9nHCyHO`y{Y}fn^9n%4O-%WAiu3{7QYASHY zxj%mz)k*RQl(rMXo<{~4AXex#-RWq=FkuQ*h@OS-%d;{`Xn-Lh^%)oQb?Zcte%hqt5;^pi!sp` zg<5sF&gi<~Dl@4r&R6EZjR^UPidNY1Wg+cf(u|C!T8hoo98g_?D{U%E;z74^32d4I z3?4LBb6#qTTg|1HW2$m2^KhK{4ViL=`uN%ND8Ti+=%GWs?w-iymVd{hu^*Y7 z3}yEOLr@=u-z?j<4@u+q`5NQ$vprl|LrF4=_slg8-@TIYN^)DO@Bi3uo`}IT4y!KT zuWsQ`b$#cm29=~&m+-xw-(7rsLAxIhMft0by$R8@T-Ohp#EsaU-M#@#Zf{g}7Z-aJ z%e_ztxaM^p(&2$7=8C4w>)Kzv_pI_)%R6W6!wDvq^%5wHL6-y~lV`jZnTYqm)id_3 z%5wL`dwD-V{Py@ChBE6wiWBe=I4vYOt7&w+XegBp7Kl&M42I7jHJe)t;^T*sb$VHy z#!gn@8Zb+2aqhzEreF=sUoZPiiX1?sL{xY5UTg0&on^b4)sz({ ziYawxHw7EwW4OvKRFd~dXC;?-WtFS1SEc%zQB&vjm5S-AtuxxM8}W+VteW4>KlSJx;-258IU(D-&i#Z%fC zn6P>`8^lRk!l0{7YgI;I#`cIps)}5QkLE$skAgIkizw1PE?t$oDa`V^d)yX`p*?kn zhxnvd3cB+&uBu$rDaSe6h)0yT11zSc(7cJJE7HvQFqI>c?T&m<_2+SKh3tF;jbI6$ zo06EIB`EK--*~q}yTC$8+E;ZiUSOvjph)JmKyl(kXAYle3lngm(Qd{2ABwUg#=lU1 ziW7H$yc_7cL_AGJ9Zw5Obp1d+ng^oyvZr;$cduQNQS=vn)tiGW?Aqopj{?_2Jx~_p_J3d9;# zRueEa(VVLJLTYYR&8QHM)V-JZ+{?>_rBn%!d!RAr>ssK)u9x0T+zEcWRm>f$SXm0t zTcwqhD^MTZ433P6iI0N5T@GT#=H59q{rEH;EL|c}inxzC!d;(OkkRb} z?mV80Wkw+&tg%pdxK>Ci6H)^&&3-hjI@lc|Hp@JJz`XctMt8c40BTqpRXGfDm-z=% zgz4*7*V9uA1~OIm?og9vtdV)aoe<|2ZjbaPhchFkLm(~DoQwR!3VbY(tY=6*i3oz_ zm@+S3nu&K&ZX`=oj8@ECFfG$EGTdD@#05&S>29@{6^qtT4>sWyD{>>}nx6tt**z?2 z7=2q-Ju6aeX^H7T(jnR2)|&fXf+`OkkU>j!#fsv{1iQ^k$xv;czLNOyA?}UncUt;u zuoZS%4m&M_iDq{D0&?h#*;Q@Y&(tAwxFS?|KdMz+*#|2^MS3i9QR_F;O#1Rj6d9#U zZm{0nBt6RT#7L8?TDhy;4GlETzv%{gP+)%k7mJ>*ai^{ASteXP9+jzS2iI7M!9^9T zio+l0Y;;3PzwV~z^ZA0i1l1A)3|yAQZH^qiOixvQ zO?^F^qDL#^Vg97tW!%?Oau9kySSGK}bE6 z6DTs;-7I#=Vor+$tPnAQhajZs{O-t#Hb_Eg z9wa{!Ii#r8$P7xQD1Mq-Ss5Rne4nnVY4&gbOCOJ=szpbSg?b+6W;mGy8dKfoo*)z9 zu6}~%;D0OCkRA6r;aR%-0o%z%bT`jF6%BPa+L6p;Z6qs~k?FrB8mXM>XG-=KgWs`c zuT8p@OfT7|MZVh}>gMqpf^C%|Ol2 zmpN7{gGkhl(OYVfi?A5sLI}kXm9y(_v}R(KPSmuYK{Zj`f|2dcZ(xGwFOyeKj!7Vm zNe&R&-KOGMwnSMLamYAKaABZh2c(u}wFajysJ;3JfaitopEdu- zzBE83syNb`Z|Xzk%I%H$5GEaEUjV&Me@y80IkEAc6sZ=^n`%?@^l1Uqr~}9(dAou) zgxB8tFL4D6)YZwhF)4QH1DKiJ9Aq1Z+5k2`0kdSRS4Xz_c#Ds1+_ z#>SzqbNsJ)?YrrB^nPZy94QzzIGgpiy76!084r#(_dsZDu_MWAU$4B+D;=llhk0oX z+bV6}-+tU{C}I^-D;n1hCB2?Xl2^>q#`Qx<&n1&^Ik4ioSWNYsn~CG%J<8U`46;}1 z8lR?|pT7JJsUz+UHU)2VZ3)?e+)>R5WM@)Fxu3Rgnl`;H*4xV_=UX1vV{IA3A3lo7 zI9P*S_%Mqqq>&GIA{9%HS#7_RS{QkXx#TI1Ef9s{X zRPg}vwQ<*;SpQh_l2?KnpR-Q{zbpXue`;T*+O1>0Z(lAX`X4Flc!{l%Fe?6e^Cg?& zZ4vVY`_icPP(!~@dyBmiw0E_ATH>{LseM`IwfAxRvfOL0gqPSFi(Wz{v|pgas?zLD z^Z<0?WQe_hq~!$YPWYh-YM6l7;=zSJ4RHrl&pJ^(3KcWxBKK3c8Gp}5`!7`dk+pGE zi|NzuYI6z39^l_(hFJ?*0%h3VGI?p>=EM#M?)7X2_GMU1a z{oaZ{E;4lh8In5b7+BuZ%v|0fzd1jq$ER~%#LG>2>Qhntd=9sGF&RdiB0k3tfaC~t zWiI<`rjEZH)mGW)$z9AlgL<33-Mnod775dNOye=meeUgrjLS8XF$jv6Brd8mlLUrd z_?`JoNUl4c18GPGG%7`Lomk1wn4$QG>L7{C8?3{yTCS0fA|(}?Yb8nc3S4)!)@;V= z$M_r06;GA}zpCR2$GJS$d6MrKRgRfal@tGqX*$kEBGc+MbTg7uv09ih9Mrk!&Ti&> ztXQoA;V~7fEkl)2={cRTK8Nc}Ulp8mT?W3hAN@Rj4cE!z>eg#Sb|Pw$98Bv-zK&GB zb5i-{B=gz%Lz2YhBU7956L%NJ<{~-hx)?EgT_FyT?ytB0Aq$id?8e;{hlvd5n*8XY z{OEsY+&jQK3tZ^t@C~@)PIM;8$w|!3wSqO{{)^#xrw)g%xl}g>w4l>zK=kF)=-d=_ zpnd16iP&KVe+^k(D4TV6??UtEOXxwUm|4RyKR>t?i`Ga1iMk_TCu!p0R-Mkq!V!&P zq;k1^NwxWjO)Ir&TybEFm4)Cy0E@4x&e657Ch5R!&+AehjTWEjnlga#wCD?KnR+3l z2QbZYSCqta%}V>UWO(vt^s%`ZP+e-D8pJEY%ZE!~y)b~W{5~BGhH|aQBsL#w%}kUR z(3p5Z2Vl>Vc?yFePplHFws{D8i?2JBIXXMUIk>Ob&RWivxF5r4d@!-;MPHaLv;{?9 znPmkE_#h-EilUbx7N(>v{qx1#BtnN1AtHDWn2pjg!mO?5x6a)KF-5t43_@tllUelp z{VU%If0@ygm$zy1{R~?_bhiO4V`81Hc7pa%8GeB3>eY_8(r&DqI||a z3{lfkEU1l~ZB}7qmgJZ0?7}bI(&kx0uqtmhzd^N{%_-UdcAc7#0auE~ zN%(T4YXwR9)ioX*nS1=!Zs*r_u)*tK6*YMPBNG`bS4?( z#}`wgMTNCQ<2TY%L92m%4t6+*84IwsPAwlR?SzW!V-eJNv6fyfFs2w4S7e0?E3U|i zWLI2K5FTF#5W(wBoXYq>!!1P&vMhQZb>`wkFZ1r`UxM)uwBA?TdH1QU_np&u_qf*k z&h5M#5!;RUln#h}4skte4_3{p2mwyyfcgAAL1ycw$SOR0fbFZI_u;BDidbWT@TF${ z-?cc)O{IRT4%A7IYd6@W^5lFaH<&51d6$?1{j!i}+nUAz!M6KnnSWtSEa3Quek+%# zKCiN#Pk`F0j$0GPmM>}V+3f+^Ma02`L~<)a#qOJuITaxRb5EEo&2}P!AOhbMVec!vdfQBwxuW|a)$WwNU!EI*CF;4rkUofyMtB|-q#xp9Ll6; zl52&rQ$uBJ1uO>4Jy2*Gu8EuEpRQ%_Iet!?DzfQ!M&qacP`1NGSj4Vp8FC8l&>trke zbCH@rDAtsXcPu0u6Vh+Kn&l%1e~d!eK5{rP4>9@t2a|%NVTfNlUB?#Sra8JXdT({0 zE?mJj5UNN1hi7k7Vo3gHe)%^|#4_`9ep3?xy8jAhyEnxrnQz+kCFZNi^yK(SzflgV=&YtbeK}A>}~$^N3CQP4F!i8(E>5=~sTCDklYy@Md@M zKLrj9AYZP5-g0P<#u*m6rqfL(B`A<+ZXl5Xne$Y_L!hSPx4=nMQ~MT#-!K%-Y$nmI zd4WX1z%%@&Fe^*D?qgb78ZRE+xQY1%+Vxx65I@~^W|E26?+xZQ``zMF$P!#~Rng4{ zrJIS~Yy#CH|Fqle7>NmFLU+N8pFn_^Ti4pPZ7S_Bn$B)s5i&xtqf0#o^Bd|b$8tl0 ztK&{mc7@E%6SEO+&D}E@saU9Qa>!W0R-gGZgd_~%1Y-DT%nfFnei=f(y*E#@u*rT| zCj8L{1nxGmk0$X^Uve|7wWV)0ZTzxcyV=J!yZIz}Rp#P%nDlKf-A8Ox+EH>J-5;aw zhkQ~-^xooJcL4fl-+N8jP1&)me8g}NLdaJ4L4fpCBBPDX%|HyRj`$elG#ZR{Jjr&+ zS+&$;s~g?sHBLlOVHGg7+x+Z+MIgx-i+KJ0USSfOi_IJQh1D4Q!o0|oK*#!?*1*sp zUjr0Xyq)5QRs%93)}Tgy;1|m72;47^S-fnv9w8N|jfM8(j%9+J;1XUBa&ylZ_YQ9H z9THBzu4u@Nu@_k|!8j6;KFMt-N@Posdeep10S|TN1sj z!0@R}d0f{j4TowGX|+^DNnuBW<~Krq(KAb7@prTZIMZ$)kW0w)~U`GzH=_SyXwp=`-r60>_%-tHwaN^EdX*g;*|~~w&#;2IL!It zOTkH#__Z5TSOJpfUu8*%Oi>i?D7qr>{C9p+dzh>}CuZGivo11S$*g{@8^|h($CCUK zv@zv%ZmVUqW^jB@Fpt=h#U`fT%3?N6)P89&_t`HEusQIH`ItvEP+4MBVs2Kv+!npw zFS^iXETQOpzi6fX!jYXTo+RI#MM-*LBazr15X2|3Nxfi}{lhs|RE&9%Ald4$wR?>A zPZ>`31D(Q|aFM8-SnyH8`NJ&i9CXV@Vv3lKY}=Kxi)E_IS-ZTtYFG^b)T|?xjgFc-H+X zF}Sy|3v8)nW{xd|l5@GYu;)^01gUtA&DvnET1a2mqm#YW@{AgNp@-)vfb(P(G4e~c znhDW9*kHj7p?+n?6YU!dk40e3*KP|Y`H*4fCfpFT5gdWGQA>ZNCOQEvPCU0zu~$Pd z+DT9>wts&TE1@x95|$V?xi<+q8#y~`>0@dV5-lmtXIP7txvV!8lzo2|tU_ex zXb6-vALR1p%tdetK&L^?#Q zbfpyON_7(g#1c!3`xf+e`)CHu^M4b*?>CQ7(qvJSr;Ou@)g;J+W26Hr2EZem(Q4x?T+BY;Rym2gHi(zr?ognDtK7xjUg5{EWp;hu6 zjy}TW%k;Cb%J4D!AZ;22VYc#j#avS7yq*I1-u z$KQQuWCf;IH(fBl`;%FHe(M)xb+?x-EtQCb0Q@O*`eR#Qk$F5>z{ioRRkx+YQdwL5 ztSd%jtt0D@2*um?i^%i7WZ1>Fq6YJ^WJNv@oMJ2TF`_g~-j3mv3S;pAFEz^?*JTyW zi_Bqued4v={D$ZNLME6B*n{s4n`w#Jt6xYS>^>-bzIoApUuK?77G6Za+DAte{+7+u zV7_JxL)z7IhTSzhlO3&(jEm?bXTkeuG97_|G?|@xND>SZhI6Od@uOX`t;}otloBy; zm*Li9kPOl1tmFwa3}G_HcBBL`NkVs7R4z%S9ws$zze)D=2m92p`o9F7#HT|ai>0kx zI}f|_u*WHzN4N%20?+~upyy(s-M#t`f^3e3@CR)^40+3NoF=2PeJU**(jKSEgwG^C zU9vj19qc4FbC-De&JSSGgw3wnB$HQHf*29^VE1e$DihPRd*nG7t!7CPs7V6LPM^yewT`%fq!;!yLB{xsneY0j$ zsST_Fj^S=5OVmxi#OhYQ(F(G$Qk9Vc4hu3E+Z;fY;4JMiAEG+WUyQvs-OB91wDsD9 z{OaSt1*fn~Ir@do@YP+3;=I2pAOyGcfP35*X`Q*jz4}5j=!4Daw)DXG?@v;w2NJae z=YzvpDK+N0^d&(5s8jHO--P)l#0DzIquUkM6Q6_7VH%8I#CxUpt}`-z7VjWOrHf#U zpU!(L@Az&YBN;Tcww5LGT}E2MaW(baGz{N+w=jGf0a&8!ptvG_Es7JJz`5`a;c7fO z0Y1*#-N(@A3B|q5Z;DPJ>t3>oNb=~Zsv-{&{fbi)x@?x&W{WL1ze*Nc=C$zXi7kA? zW?f>wqF><;({8^kGcC!&e)n!TvGDaaYlB&63lFh|Q~mB0rU3A#t1OpiO34ZIB$`*6 zYyUe9;25zCJ0%A&SzaEuIh+Kt9T!_5`vjGE{vLJ2_7!_-H8|&+SAP!%ULRmd{Noxt zo??VIljt^AT8KcZ;wMR};sqvx*C^?DQfKchbrLoK3;56h!A=iVrgjyugK-|)caoC! zk4Tc#>YPw7hOh}{)ti?;M=Cz{(_X>rQ{Ze)&6rTc;JI^hl8M z+dq+F1u328c5=m6sNP|V<+XSD`}FSueLqS6CYUPP(t?EaTe$>gXomf=#FX1F@KL+9 zI6b((pM^l-sS`J~PlJDay1$i)^>=PVxoBOFFeuLRSE;q6}+fY|EMm2?lERy1j%=a4r;w@Jn zK9$Q35f~lTK84LU@w`~5quNC62em=z*}TZ`_0^-uMt=AO3uLCX4^^0yw;+J29Yrev zxSx>ZR4Kj(l%mtJ!e4|ElGoJMY-Wb!z$4EQA=ZBK6++n&CvsjG}K?cp>~5CF?D9jjR+!I zBsi$^S7o)SO1}2EyI`R`sJqSoNQpvIW?za_ywIFA^pbB*9mVzoZ=BZ@Gju8^@Jw{Lz7 zco+l81@19}ZzbWOcnBUi_5cZXpAQm=XF2wWchZ)=3_ycDlP!G-F^ySJxC}vQpLz5T z79DCmF)y|v!qbrw?>El2AOxh9;wt8VXi4Ua6wlDy zbiAEB{PvqW$xH3-QyRSa>gx)@Q?cezUcwmHE095_J8<+r9buu}PE}9!nJ9w#YO2u~ zMqeI}_Wd(AKvi5vIh}bm{95`{GNL|QEeJVl9u3>mpm81j?bxPq_wvQ5S}S%}l!p$2 zN1gAi;1qMCATjXGObq3n(7NyiM_PsbGqAT{#CCzw7)odntnDA7vs_OSz4;+aWb8k2 zS|+-ob;*h-@L00IWA8_mWLJb93!n2oNBr;_%+lXLTf|n*N3$7J%7tvfiM`P`JV^eDbnTzd~d%_KEba&0K zj z@xEcnD<>Cy8R#`c=;v|2)TtXcmWy@p7` zIBqTHoWJ?qFKNaTn*=CHZgMToO>F*)u+wbR6hHbq(l+19V=T0O2-AA0UG2(au|R$q zp^>JTi)lzR79O45P2KTqySV{ipHoSzf^%}0i4s4;j?b&QmEk2K>qxkRahOA|ik@v_ zzWvECKe_-{O$%=VBM%)Y#p%;;) zxo?A<5|FI-H6=Dc<9b|ev}G!&=fX%9G$-+o3K5!)x*FE^JvEn9ib1Jp+Dol+s-#yq z7cUA@lSf;cVrj!<5bmCRo=V(}OhH~BR($RW)nFquG}Y#NM8rI_hxzw53o5bKsM6DS z?bhLU8q-csMN59qk3(8)yD(s02W$Gqt=6z8 z`kW5`fOYG?I6U2b#-o(dh?CJaZIj|&r4AtxE&g{AGl+?v8JTXyh}I-qhC2O)*y^aE zx>$4A4b+Fvvj@9^{rkpB#X=-WlwXw#CHc8ni`meWA*8v95C8&Pt|WE$M7zdTTm7(g zx=~ggdeDoNS-~#%xK(oGdNsRJ__&)+s2epEwTYU~sWz|uAj?9v?QFDvnAV`6EL0Ta zni-(GuD%KXl64bP)Oe*8_Y_5ssf-E_%aSPI;1{pYQS7{t>^abDFll zl$WM&lJ!h3{=|4}LY1Dl@T4m31bS71D2UY3j*ql}0tTUVWT1xI6I=#XE@1NAY-ah44v2qc&NFt?kb@M*|Kjq2Yhz@=h&e|zP#(-GBkZ@3=LjC#7IoJpHcgyto6$R(G`u@ zXt|RLcoyekIPy+1zHIbB;@C#en0D}yvs?ewdH3n=_N^voX6N0fY>nsZgLTKmdsQ=H ztU1U%Vbw1QE1K{c=DL4Fb<=t5JJ=ob@fu5Zg3SLt>+>I<6a-r%#{EY7M>Zb0=AbsWE*aq7_#zw)K>l zs$@N4YS~+5sd}&+`lPnTk3P%RU{_%77a1^j8z z5Bxr24*i;rtOqbH`QWyQ<4^C)PSWvNk`TKRTZQsO#eI$8a*SCHnp>aIi7uqoB0;*( z8XWXlgYWz~$r>Cq_2i^#vr?6z01oq;5LhJoYHZd9bETiP8pEZ0Otn8u zRycjLq7h&&4RBNL!=mcs?{CtlofjbGrW`JNg9UCSNFVaFV>f#gkf6FkAaM@)@SU z3dF6R_dC2MEywUesIjJF-Go2zdRh$r_r!sb)0-0J?QYS1h|On8W?~BV!h8KL`Au^z z+2(tD#0mGCZ%|8ozA~ojm}GuN?(Fr9F-drmnq(@?*GSY#f0^I(UDG%QQen$2bbN{= z`L^Q+c}?s1M{LLQ{EnOX$xapfo%*cbsZ4chk}36DDjw0&dpWeUP%Zh&`V-B)|EKH3 zO_(GGt+}@pN7zAdh+s=_*gQ{u8F6gp*Pgf9mndf*rm56PdD&9onW1GFMHhffbzUJK zeS+1q1r2*+J?|-Rk<1b*wu_QnfEFuo?>DEDgR#!E9av&6v>m`6#6R#SXsox~?196g zj#soJw()9R7%(4`6ZF&WriVZT62OWOMQ$jwZmInjruM_@9>uIpC{-{bO(Gv~uUA=> zteM~#xBBaZ={@1=@j(qwLCVr$KKY9vdt!&bCkWEZ$7=K9Zh=pSX(08`79fQzSbtWn zpIZlS`}jWfX1yHNphpk>LCKWc=y3CFI}!=*d9@rFiCrY3X>?n-{9y8Fs{oTa;iFFT9(yOF0kaATqFrflheoGOm6K4-B!R=MObF|o~ZK%3k> z=62iY7M^bAiMG2!8}0tuV7J@)uF!f*8GoHub0#E^j5g6PU-+Q`Z$}<)ljLkg;1+Why5CfvTI!R!!J%$83 zx-}0WW2|b2Ikrjj-0RJApPet*g-h89&^NLAcXj^XIU1%{1kU_-k+MX$j!v#w)$Z^| zt7BJ5N%Y`eEyvSBW|Hqu@6%fC zk6jC&eE>JfCmF4Ik<*`#P}q?z28EKXJAz)k$7a9;?mITeZp67}seOdlG5yFFXre3h zw4LcGMZ$AC%=rw|{OD86xMyaTE`GJ*wx#*l*|eYnHpD*ggk2+O3{Q^rg%~q&GD}_v zvy*6PK>TlPXP2*7f=$3H_Nn20bN)o>XgG7s*gM$B!L^0vDs+I$Um61g%cMeB=EBC=rR+!X$f>>F71LZL+<+-HNSz60$pPJXs7gGeBNtry;@*o z;~s$UCZjdjy-ng>D_=-Casyc)kiH@9YDG(7co76akGbKeQ~(54^(4sxOB476!CK7S z%@?Rqn(90GMRWiJz+SRddd)RKOcSggt;c+riV!P@x}BD8T^Pp(-pz;!OFoY}zP5}J zSv~bI12Ms}$42?Q4};*kBG5*tuuLkK*foiLgTd}fkc72Vi=W9IZQ!^Q5~YHdJUr#W zv}3D4LPjLNvQJBfl76HQ*f{2x@7bpY+2~`qS#4S}(@urS^;&eCyl|H@>j7@ zU0BmZP`br~L>e=<%$2bnM@MzX<65P}Ou!yQ4>B1ccu~1n zIaLP%;eCTg4+If38X*z?xT*lzZ!+O0{p0E;8fa|5~K zmzdS$8InRXN9gC1XRTT8SF}VGiGuY_nl8x@u~&rBIC}Gr0GHamy47S|-WBSUPycz_ zoWk*qrQ6rY<>v8Fm0q{WzG^d748nY7cIj z5$T9zBXx}j@tFd8O)zZ;kCH!LKI3h!X8je}HRNCDm#v>~Hrg)@X1)F5TRg1}(DBHV z(VL$DZ$1&dc_RnE0&{MuPfV>ftLCszsyd=w`O(mptl9K6dMq<TFsV5~o?it+Q;_MdtKmR^J%ya3Uj({V+#g&=4BT-}H+bORFY>+E>U1 zlVUlfqoESnLCF{*GOf<+Agew>KX6q8WuH=6#7eBNwRvct4^V(FAjlaWX4F4rS zzKB6-d*YKTTBNEsuWdcm%T8Kuhe=>1tV($z6q$hqM~DqP$*1~Zeyrhv%kN?iOz8~( zBXMGKJI=hHWt_pQRj~{}?VyGJ$rkqXaxLUZw9xC>ij4&Xwc$)M2OoqZ;!tz zz&WJy^}p7dFRIC^eu+Z9mCwK~x!yYzCwFovHWo32ju$k-7~h@P)C8RhK^hlnwCywX ziUOllzngmPc>P(ADUFu%oc1CfxCg4el3%BN4u9P{AeNl=`S!yC{>E%#5>zx&Tb@2| zY88*36iy~<^-@1B5i$|W0`4;_PtvxC$!^zna^Ep0Hl22&9S<@2fyl*3A>DR;0q+O5 zLUUdNGRI0m^y=0!o8m+YA(=S_98WK@xIccOJWe9{bDhOtQf^ru3yG>iRefb%_1iF^ z=wb6B-iB1g|I(qrW`6=8RAUNtUgxx5NXzC|NM*J3+W*9^=VpO|n7x2a9zTEm4ZFnV zYswNCVi`!$=dS&T{31t6uP(B6*+SauUj2vG=W9wtbB~-jP1vVV`^gDpzxni!=?3GF z+sJVy5G;~wCj5*^smhOT&6H0xY1QWM96nw?r#+uX2o6)6o~^)U%hxeq#huW(6o!Df z+-aXe=4+S_4BnkbN_cTL7wT_J6ELGYFSeFeW3w~ecN{zCL_XWB7Sy|yYIU>Lh&PDj zTkX3F^6qtna2;yFd_6sDUA1|Dch|NtFKX+}q({Sh380Ku8e&FFxK663~avhybT#+w}1v@O;2o9u{$yxulw^doOW;UIbQFt zLC$8!X}<9yUu-TnrYy+t82W0yGB$N0HCBJ9KPJhIDa9)m-TIz4o80%NqAuy)NbR)0 zH)FuH)km(ULbX69zwI;0>b1)35K=|ONAvA{TK>3~QytP^U^(NMzWDj9jfRH-oa;=2|NfuV+acA6r4<5zQ%Q z)?Tv%QGmIEmOOoEQZs(@R`slrT(puUB=G}!=T$2-tQ}Jk>dSkOuL0N2d-Ubw8woY@ z6MdLV547prQLe>l9_VtbhKI;q0ux&dWEpl5#cq!`@_p~j`1Ps@Gq$Z7f8~4++xjK! zI#)a*z*%|L!kSonfvN|`{qPk~&Sri0YKWiXzwND#wXfha_HQ>;-X@T$QqeYt_Q&B25X6~7jSwo2XL#5*si=(SufUo@Chcfh5y52qLli68 z`_HkvtbC{Rgq>r9TW8pA<$dK{2EYPGJCDq;oz8nOt}p+#KEhjgh{;C^b~~VWZ6=WU zt=bm%yN`%|sJJSe*A@$+x?CbU!b7-wx@=E$2${U+WLllqezP)%iu2l+Xp%;~-zf6D zURhb(p>k!l&8WpwXnKroZxZdDu(#PCT+pfg`tC0%Hnd-hpC|Y8h17+%5YwU74NW-> zYeEVknb!uj4Pjj9LRDc_lVA3RQ}vKj^(d#96Ithk)kbEHhfRIFa4n5mT|~m4{Z1clg`Yt~J*L zv2dp$&1Q_w=4#tl{dG1kvVR-wUkeKsW+3H>s<%?oSPP@> z-uX_uGR4|e3}ag4I)bo0=J^f}qN2>RwR!=H4k*2Xq3ql&VswwN`} zaYL;e*bBj}*lopxKR4t(vUN71Z;Pe;J?WE{Ig?{ya>PevSbHUJ;7KE)y(Ym*$mWC< zl1e}}C(-A%vVri2MPqq2?oDhKbb$XXZ%4Qp?}NFNcQ>@g>z^;l@XxQk(5d19&0{oi z0vh|D(ZX#)V?h0=G*q^q1h%eu2ZAmZ%cWKE`I5R7J!iEvW6bYu(g0STpe2SXE!TZfV4q0f*l5y9eWy}P$Em3%eHvbfrd#Z@J-Z!IW1 zX}=6*`cPUXIdz&oW{v_jn?58@p?9@?{Mw?O+%)#A{qVF}bVHkldbQtv-{O7mpy3Dk zK=`Ny6&?{b$J;a&%`3tcF?)@&<|I?`KG8fdJVt4)JpJRZ&DNJp!QkamKAboiOYPU) zhx%Ef_L`qk}B zU%$U|{JEQj2XvcnWc<*WK1#lHc-BoH&%C5@0?d}CgV$*0g9?TzC>YXY{L?}>Q4b&j z?V?<5OA(F9et3@nW5cT{Fq7?ve9fO&lMnJb)R7I;=Up{Cmx0*kHO-uNcq{wUJSkbD zQaJT!EYqt~a9%K9>$7D${jns3Rgttwcb?q5XngXc+un-@ z-Nl7WG04{mwNj8{10vtS{4c{<+;(zFfsZrXf$&G7&kM%}!lR<0)?oZp4k=t>bx6rJ zE)i;lRgRouu7rDan{O50d{JF2b^zEnpCP(*VskH#wm?$p>ZNjf4hfd1`+X)du}NkW zRSXlo(nzvQk`y(|*<60-^4bpDrMEmHgxcDZ93gP#AJoinoe|RYQ2ysSgWrt)F&Nyo zbubfSE&I)+l&H8KZ;KL9x9JAO*bh2q6VOWO_YKx8#_CzhKj{O}{l1Y$jm?`H~yLSx9vJe*y zo6wvQ!61j|-E+Oh{>>~AS;evBgVS!Q4ogrt9tE0OE{{I9M8?R@y0!otw<1&^a;YG? z;UIGYL)piVcmYq;1+||GC`sZ41puF@Wb>CT!d!aPPCF?4Y?(d~IrbPC-nJ9P#rmbB zw#mCwPex)PM-zJ$J(dVh;L6c-2_Um(7j+e_r1j2rB%VKVxy(-p5^Fv&*NWgx?vrUo zuEmmtL+4L2&;G}V?Sv*Hxt$bPAr>06`a6X_$R$Woy?Jm7@vV-8r<#=%wJ~rIqAxL@ z=gqBLCL#JV^GW+M?@)vu@x4@z9O-``*y5lW0Q;(H{jdK#eE_4?CjnBiDxAfOFTO$m<-hWgl#}? zC|3?3J69RMVuUJ-4^UpdU!UN{Kw`pGb!)J!)^2yxmUOt5coUuYFu|tRvFXxP!&SUE zmHagVQ=E~8HUy2le)RXu-I)ozv2#F6UFX*ydPiAkt|MidHZ)i{^U(Y-n|?K)$7fwS z{PP3p^^+3CTg>fo7IUMI`|G1`p1Je9st&X;VDzev?+Yd1TpY`t4Nfl$6HCCJ}5$XFMp&#u6qR?S^tqe;T${cf;ifRLXeMn1_nT-=26Pq zjEYfFm0xGR&zTB``k^DCf(+P-#~;@zz07=DztX9(5-2h2%nERQ{CpF&=}XLg>FLW9 z|AzGFsLbfxtW3opLSrKq)%syKP4Af8%Dz7~Tl*g4SKNs6shmwOaeY;f9ILX$KEPtU z3ur}Omj6%rPHk9JP!-qA3}0`?sKu6^>^|XPsJ4|a04j@Zv?YAuJj)YqH9`Cr3vH=3 z$KY!e5o>QS)DLjm6k~qMSCo(DG76j1=nv|5rwX@zv_G%Ra<9z6lGItlDzNpOHhyDsb$e5O zQ$EJhHG-b-cfn;#-2kqP)u!|d45u^yI?W?z0Gd;jd&CL}G@T+X>RmhuWA`)KM9hvNURS(z3LnN`uGXBYd($WL|q@jImN}=`rBYiaa);Z#UKlIsmp(<{C zB6(VyiR(4b#3dV@EkA5LWcv6KZou{k$0T+&OdC2zaDdG8;Y~YeuBz}#DTCROZm%Fm5U;GWEVKgmKH`7|W7Va-0G{marl26MH4 zLR)08;w;akxkr|E$%?{e(r}FYo>lrKsyt| zlMmUaMHpgPyOXQ`gllh*E7PZ>a6G0^(fgMK!k4+BfwEA4S!giGjS}+~wR}{36K6=I zpeytw0BPstB50Oc_nBLHPt|~F*z0nPds2F6K=~H{!UzXsnV;VUc6vIwNx2cryZK-& zvCHQz=cK?(n$lC@SL)sJ!ZE~xg4kBthi2cuu(BZtVe1o}}Q8k$N zl?QpyX&GK-e)3Oo2ug{n@H+dUlR0~x9aO#((;03+kc0UXoElr4s*PYrFSwW=8tc(wSOznCP72p(PUA1%F*-J3#f++X`SBhXac*lhtICB1R9})xs9HM(hxep5j z+}VrVr9^2t9{eqPTGKVK?>$`jkGS^|aN%&-UR3AX`MhsXe*FZ&D(i+c47v-mnBykv z!;kIB@!-pe$RMVco(I2;p5xj7gNDpqK*unaJS|!YRz2x)2zi#(e-V)=53Rh6lDcH`(kAbhsz z`4(M#l=)z2%~=XBJ7lmG|2#MIN$(%Qfb6gn8B9#{0x$Ia5olFRYh7X^p|!oi&r91u z8h6Dg^`2szVLln4PyuO=?Z~LrJ{=)A!M7Y8guldp{FrB4E$zl-MZD8o@}H4w|p8%CI+T4gVbg_Kz;PN9J=D(}H4evF*YNYO=S@f4JhQ)>ACld{Z?c8BBpq@ep?$ z|7^umqJ_ezm^;Z9>kxS1U~#j3(K4pH7-0Sr!AY$c*TbND525joTsgA$nG~>42n9IiiX~N5td6BSF>q2a2q>AHw4UcEq4AY zImk2f+Cex97;wORJv!v_t{bb8F7HH(5_FoEFlJZ2DEYhysP``mL_Sp4Si+o`u9e<$ zhMT~3&`zJWQ)RC8+FI=0^{~fWX5S;Bifr8*5s}m?Gko#Uxg~+Xse$lEzrUbo8Hbnb z;uPuO`}2AALO%52(dO|8l62Rav-7e1Up)OY7aAJk67U2an*WP*ArWbJ-{g6q@Ue6!9-D)kgr`Rjc8j%g? zY1yg@pSv;u0;npu5;R)tptY09XC)yTDF9?}_MIc)2N7ZDkimLREOEzY%2T#zSe z37A6XmTmRQ6ygT%F?g!Y6w%WgFpG;9zaLUC#~u+#Hztt-Ti%0vUC_S_AqTmcv_zFGQaw2rIXR+roHRl(+;%VkxE zaVTzF#flyahrW@0o+<)MT;165Q9$;yU+|$To48T&EP^zRHKley@>4oXPpz%=79$s9 zW`9rQobRWU%K0#e{g{{&fXL0m>M(+4thrTS!~}u+vyH-HreCFCPYV)I2B%b=@w=mTe+n9 zG{hVf7~kk*&VEp|P6_b*m`WR(;C6KicZ4B;g7~CU^(XIaUfVVx$n5(XgHO#-_Ikeg zS0^TW&^Ocr^EkQLcZa@AHdWiF-(hnQw%s_%+|<*GADT)rM>d&>tE_c49S)eQ)r*!s z)c3M3zg0nRgaJ30<&SDHHko%@n4tnqZ%ZfMp`A4%AYV4mX$Y~NgG-Z z`UEyj!fE_YYU(%Ds>!pO_ZK-_NUitTTJgGDWNZB{wZ<#V&8kmRlcZwO>Pv$bd)`sG z1(QoLt5-wESK<-zImn`IQ@tA~*lF+UaXsYPD!l&Jhu(h}N&IN{^bkN%m2h0J9|CTd=hx0%N$L=8L8xc^8u2ZIPMLRPW5-K>Jb6P0%|Z27G!u-*B4&lIGBoq_!FPr3m<97A9_6(Ub89A)u~fNSlw&Tq zk!7)$w&Rj^Bs{s+y;0Y;bJ_aozp>=egvR!4s#XL$F)`Je@gtEpZ-9I+iQZov2%p7D zm_z$VW`-BEnYnxvQaC=1Fuv|Zjir-W>@VDbj9`%a1`}T4CsT!4INMUPFfDOu*P%yl z4*DFIo1r+;D|9FGVRQ5k&@%(>>#?F$Ebxqf+;!y2dEBwcd19x^y3h?)R@0E9!y+@vUbMYVF zO(^mwcOPXTW_-K8JmFqb;H=7ZR^>aZa-3CJ=D&7v+3TtTE*1kFn6L|V;$P3uWNzV2 z_>WVbWBGchCEeq6wfq!u5D#$KRg6I1vA2M`HbYu2=DEu2LvZu^{NBs@#jVwG!N-d5XrK8$`shIn_%X$O>HP!Cz|bpNLrBT z_VNOFv+K_6Jlb5;Lwa(qxne}}^7Q0FQ!*lXMS60P$sUos zHa)r6{N=jg1A8nzxx{phNZyp5TxvFsNbXKgo?@I4$-U{xI2w&eKAfI>p}BfQat@b+ zrj}&7nKB}|FgLVJl|}x$sEL|T#e{&JeTm9Eqzg2Z6Gq4n$Bkj zk4;Qmv0UO_P7F3}FE*9aKF@%UL`GxN-~DN>({0LcJfL2_@F99h2M@Z_T50~AmcEKv zbJWL)eqV{E3={JS`U=Cn;GCA@)N*=bk$O3So>?UEVaFDRg0ouMp$q9`#=C%> zBKi|<0=OMhZ*F+@w7_*x1>^8i!pBep`#Fv2jNDORK0tNbA%ovk-B+mYNIs|f9x5>h zdc3;dx}q9#!W?^@x|a^PXCYpsE%%DU1a9DP%B?d;pP}F&%BJh8YwK}}$uZXqHSx?j z-sQm%4BlKC!^9p5<#5jPH!G4;XTG`!eQR#x5~iWfH2>vz;=1dgGjsrPH`eURyhl29 z+<0si0TBq05zCr^NyD4(CJ3s=y-~Gw<^zl!g#-aRZbbPxjyLj?ExMz)+N>leyL;(& z=FwfjSnKJPZO{C!Rt`safDd3T7CO%PH>%pirD{E1?DbryJt0J7cCr;di%e`vl*348 zkGlS#0xkwBZjRqtR&T$(M44tf5UqYHw{%S={ zR%En;$9z_tJ4UYKs^9rp{;AIT4^J=OIXgYQ#+|*O{8hH`c@BDJK+g_zOh>V@2zG%5r*ZMhs#EztO9<64fdW|)kTEV?HxPVRo<<< z+$x*HrE08}clGDk&xpv0VAX^eTXjUgL~Y#J>%ZPNWwfW}aaT(KuSx_ZS=eY+aX0Rh z((7;&uGQ~k*lX-{L9QJ{cE#)k-o3f??k}H!zhsY`Z7*AYS^%4rn3`A z({|Su*8pZ`2^bq&$=-3=7XhTp&z9NBn&`dYCZNKGF>oSlolsj|+ijWR0`l5!<~O>6 z5F~9k@YJ~F;$>K!nR9Qk#N27%7%w8LjU9_!Z7MP=rWhY@1t%bCDAs&`mid-Ob)4_2 zaK{vLs?z741yV9_Ad8P9CIfzu5o`Ya5y!VGjMPPK-CCr+r<{QOnz!lHFecy#=l_0d2SQa$|Ya#KuGT>gspvu51D3E9gR{0##C*usj@YE4(K() zE3>6&{jtzG1by1aX!PJ?qb+N>P!QQI^7*pRy7^WUni1Mhz_!VrIG?ZBt4PtT7_%S` z`5foFTQN}SkYOSI|MaN`nWY>=OfhpHU3lvV{di)tot$0frEf7;RS#LAD1CcV;|?Y^ zuh7(`IeQBL_^kC!*DCWlUQk^Jeh{`eZdHutqZf=0n5&97L43{M;u3c&v4x}yjjqUt z;RU5c&cv=yIL5mBbSKNs_{iu$yvl59IYD}qCXp=$ZIo>d=ag-YjBd(Qc<<}52VG3K z4@67IbAXIH@;%7VX7aAhWy7McmOi55uAJ~S6;EkzhL^FyJ>^mpH{JOB@YU|MQZMB- zu4B)b0TS4k8FRg_<2|L*Z|&De7H5%-n=J)}#m!XcD<@2Z!3h8R^Pur-BBVuP2I?!C zb974`C>|wDu`OJ)!R@v}*4sbEJWRtAi|vBI($o6vfj$blS4&^)UnW*Z9FERWlB}T> z#x$UpEjBdXVPOa@?&T1}Hs&B(uA(L69KPSn1T!fkO+J8A*6*`K_qW!T+tk z0ETLty?Ck??MTJqqHuOo)(!DICT1KmpL!6~_UQIZnI!ddGj6l6riVH}Yi|7%l=wN( z+XjQt+YaN`je5IJ7Wmh?^NOP8G}vOe?#pEwH(wE@+Fy;F>IKW{PY#`rJHghvM!?F| zwBG#-Ynx8f&A%G;p+|&E)6>y~Gvfy(kGadA8np@L^+?i9$6`r%dBItOg9e0S5Lo_i1Wr9 zfXeb$ZZcoY_rlbe{QHyER7j=VeSm{NVN6A{W_b^@ymNNNo%!KnhD==BK}-O2eOZx$ zdD-f5Hhhok=L!E*?EX4^0ZGm=hXI|WUDR+o082iPi15L!p%_x)ByF{H z$l^Kxu3$n^W+Pw{Grb~I!l7CTtYww&j0fGTBqauipcUoTaITs5_mUbVveQ*Mc6Xg2 zN*x(Y`CIiBHx@?5nm>P;DB1`k5%qPO6;S4!UC^zFnTwsJJlR;-ii@_uk}U@(>qg7I z$?~P@jbhSU-S{R1K`poK-d$*O_jwc!U_Mq>Ztc_`zf?h1LVY&W3TC>if0tXQ%-M5i0Rk=ARw@%2)w7I0kU8kA7iFK*7n<>y%3|4f>8 zL2H`75OF51QPMGJQO&}8G+WEeRs7n)_$rlB2IE0w66Kl?+pG=d>}1v@j2o5JyU+UL zwh`3anquH+)Y3!qXrCj;Uh0XK9tds)17TCNZ&0m)y)ePMC)b^q zg;5#?9rFlUik%e!M0(Aq?v}c(2eTmKv_cd@(MZP$rL^m-R5;FF8+*slrLj8f2f%|( zK~D>*m?64q?mOgWzRV;1QeRi7$9h8j<`rzkuP*?$?7eefU3R8xZyP^1`kang#U>Gn zU`UUmql3CYzRv=51If)?+88-TP>Il{C^g@#lMGfV)RgDIM=_2 zv8L&Ct`;eP_Q(fY``0gC9~PSVpno+Zk&nWXqmBa(M)3<2TxTKk2-xN>L4Heaea%8q z#wk=|chUbI+&_#u=l>1vpN47^xZl8UI=EMCJ^|dP+pG;-qvB`v!F@bgEdure2Hu+w z248yUZJPIQeqDO#%c$y-s;%26NM=)UZ)v2|u1d+U&FTx4l2p=jmoU#^PA(~SA~yvC zk}3S`E~sf)Lgu^NJ@$VoI~%~Lsw?qN$OHxmPJjf1M2(6T1uGgvVxT5K2r3B^f=N&U zX^S|W(iUX~P)URx0z98XZKZzfqGH8LtJ~ryu_6RRNvMcuX$yjiE$!YoX*aGcMvct> zckX>NnLw=nwPo_&{l52|d+xdC^9kOFTggX`4#w(*ziPcs64nQ?Mp7yz+)V_Bb6qr| zG0j735Qcp(-U{)zlB40Ni|7V6$Nhr=TCIyC%yn*3!e0jlg%#1M)(_NILiwgwfQkpg zHV0fT^!fZ9bgP9t8$lm|W(df~G`M1F5$FbI>yE_{+jO?vs*-!$k$j=i90_NMKodEf z*jjZbPW^TRe7HR+q>5}%c>J869#~r-3h~|<92MRv%jpW8Uu8(#>MF!4#m5j4H3h%z zY~j%|PGF?GF4b76IX2YARj@fBR0nOdBqZ&BeUJZ&buVRDz#qf_xQ#tGu3 zyBX0R%jwxZu3N)XQ1wlmq;n=pAPk~l)EunjEUjXz>nl$DP&EhO=Bd!vrTyWR19s1xKPWD}fgU-!MiLodv#n8^iI_#&9fLcfghCxlf{JkMs<* zo1TS^GH3cx-E)QM8TNw<3V9!Ql!>PE1fcvdO#sC~dzt#&y9sShxtb*3i)KkUil@|d z)7S_j9shZu5x}Lk*NUImVjRu&20iAsjRhD;|bemFT3>GwQ{ z`?T?=1O_nvk=^4*cAwMuypRRw4-&c))@yjueXz0Fw2%iQwaeXO-qki=He6o_2V@mb zHX1@b>;gH>Mf2lUC$ER*hm&``lh;H0!^ykc$?M?@%*h)pd8N69z$|-LpmC6WQ%=DH znWTsMLiLal!+`ZwVN9ol`r%6@HCAd6puoyZfl{Hl(Vr8tdvT$ey{X^|U4_olA@%J! zMsWy;)xkwcbJQYA*2mSk4k;g{>^h}F$PqB=f%L(pt2C^6hv@3T7?Ae21N(9XBm`>@ z``-ZKm1A^)l0Da|;tpru0vLLaJm19>;EC0#xGyE`|LzQz;?eWr4Z~LKpsD!Q*9}ln zb%G<+h=CkB4!N9TzYY6PC}y`yE?J{=ExB;T z@rw-B`w9AzMk;-Qp-|Ee#Ve{w`sxJc7o;B=cA9iYy&xSdsWGPhziEf?lKMFrL9D>^k0-Qx$$0U<+5lIbDkM5qdxny@%`2b_0mfm%_Kc z2(CUBzO|7Pw(%+K@m>T@-SSaxCPp;AMeMpJG0YRIycfUHDvtn)+A446aq9GDm4^|@ zx{U&2nD``Hn`wKzUajU$a zPG&mVDsP{@MV0QuD(}CJLiu8qw@$x$g1re5f!yAikspjx!)J=$S&?*(?3KqzcGxF>9X5V z8iXBkBb$s8kR#k$bF>XR^i%L`%@>g{A(J(ZZkIcBdNixIWKWz2C#QPeoAcBoUk>3= z*UaB=dto=J#FdM1qC~}5WZoeET730ic2cMpl7-;xz?DZzvQznd_ zQkXhr;^-;k@~6zM8!erV*XDW$*hO+pw;e-0bkh=O|Bx}(J0Lf4jP=rPb9P`4KdtOx zU^>2cv)Q{%s2a(I=JN2}W5lkuLTvW1;lnn{qnZFR+qY;|^jdlER9p4?#OObD;ePgw zwEzIhNm$gLtsaof>5HO+(`0h(hXongZoGS#&X_>QD3VV_5EbKpiE=bSGo@w zg0af_i5$&B+(njP4yoxu7zs;ehxdpr-~UL=!Qy?Xr>r`O?}ZiDstuIKWLPscC|Edp z$pl>xzt+1(?=dEP$K`Z_@zK|=C>&ieVf63C>vi2hcwYY8m7+mE#Umy!;qS^p(JHpj zGF0GvcQ3HtB(8bmo_H~l|Ff~bMCf2kz)n2;~#0yTmvT8ou40G8Xp%0vqES zny|WuGKEgH3rB^9=HHYd?BgILN?<^=B#;vAj3>FZKp`bCFgo_DYQ>B6jSh;}8cajD z{x^q4TRB6c&3~wGe9vr9k>uvE%N#n>uuxwHs1sWK;r1k>F^)?PYMAtLCC%Ggm49PK zaB2Q}xju$|$h}iMtP^>*^n_KKFb->eR(LYW#$lp_Xsn%{CeJYrBT=l!v~d`wO~y71 zl}Sya^mM-qjTg=8zKy$aIucuP>u0jjp;KoxW`{YvpXp-`@2zn<6@f=xj(2r7 z+sROb+g$PpgrFm;*pg*K{ocQE~AUlNP^G2k3 zThxbTsV-Ruk@E?&5s$W8WW7`?R!UOfj}(wd4uu!PpeUvql+qLSp6I4Af@2hTck(#y5yzVupo+8IS@6!^)0poFOY)&Z}U~*5s9i#k>!bI^*xotnW4dVtqv; z_p8=d^b94hxApz2USE8HYi(Zf5)R7%7I)m6c9Xh&DYYf^XcOAVD-07HX9U6ohqn+? zup*tSIP#$b#1xS*V<8+M9|aN^RS(=1-YFl>#i><%FkIY@&!^*#oo#zJV>ege8MAqP z$=A?aLmcE|j*FF41I`^XDM)t0ZX~2J0daf!=H0Sc#J#ypNoBtBWh^?pN?c!{pX_W> zZPu)Q#3ohsu_2Bu(^-A3h?!#_4wi-QE_4N__YTn^txE6|YD3t&BeXOUqL7PcxYsa_L zLAVOCb^k$*zx|q8X{5;N3@S}4k9>}Up>RSdJFaPA1Q=~e>!0@AiP7EihXprTg;v{4lJ|W0ba~rW*)npn%fr`rTa*s@L30Q-E_gK<(O)y>KgpP zhH~%_vI($ZKb&rSO*93FtHsOJH~FiX<;#trEB!I7@rFw#7Le!Ih0CK^NoTr2+{gJ! z`Z{Z54COQQK@QDZh4}k&XPrYMKb^wDu{!vkkMpmD!`LT~E(Yx~$0+x6=ysz}P+@pq z{}V?9hOS293SY^g@8i@xLE2{s=-t z;1CMcjS#<8MOtWQrbzrX>FP+dGFdp7enbc&W}t+?QgRZPKYsxr>Wxf)ct{ZW_jQx*n zMSLJNwUa|K(K5D4W$mt$lJmd3fsWGm5c=3!6b;ii<;l(prbw+OY z@ZuT2(HUdAhv#H~UYgrLAEHJKOg1zv_uBmnicZ|)S!lb9M9tD)q%432Zng$Dc6lr!eKPBbeiZC>Hbie@K6|5%hT9>aPDTR$Ux3l>Foh;pXgkKtXD z|JZh(Ls^)JZ9#{Tr8=)=jU+K8SCxM?vkRnD_|t1@To{&#mSaB-#U@$dKz8Fgp}L>` zU-lTPb;_<01?AGrDyzWC&tG2cT^*(o;2$I@-oZr4+^dbF#d}!YF*M}Cj0iF%05|4u zN&;=M8{5%t&t^$z3O`{MxGQwYEHwzP+H+*Lr4m7**pzh&QXma>Y;-^@Pks0eidhBX z{^>##+uM-B<5iG$WgJ^q^A-_Jr1(zPzCDUN;%3l`aV4Ty@k;4?&)dpprKk*TCtZe!U!YNJJiNs!Om(?*FxwRRRHK5t#EgHb#SWI(0-e>*HPET0(OjyFE8qp zo%}oDqeMECx~xx?-C;gAGzsqNI-_U9riu=U-4575UdfDOSwVE@#RHTMsuYO%U*eN3 zc!CyPzQ*ia5X_8|LtF{&6WZEU(#?V=r9}A7YAr>9!wjD}lxe+o`~%ja;V8e})x?a) z1a6kPP=Q$Dc)^EG!!fCff0A!(v5-O~SPP#Aj=@7ru=J!ll5?3ZL* z;XNIds^fBi1QsPC?0#zCFS*!E7UyzJmp}^WX3#*5{#}-JN5@t3hyb)G66v6_-<1J% zSt%6AV%9a%Ac^9YY>m{!!sA4ey$alxyf@YJZE}Jeoe#upe3rZ;qO<=vim}@2Vx0N1 zUA_vx;Fk)lHIWG9*Q5t=Z=bHlu%d!b1V;ewf}jwai&B}GuI8`OTN|BfEnP?{bo92X z!ryWQXZUm2zOk$hhRXRr!|xNl+*npS?;5_YWf8}V(_#_xK}kEfy4W*v)D@A5mK+$kF;)-jT?*-7K8-xGYQlc|k-hd3hd}bzWqf z;69Ubfld)r#yLUjv8B~&n}4WaEcMXC{9U@pnpUkgOVU!GT1`@TcZM}>k?x2(<+`tv z`OB(<1$yV6Ev7V`q80iZdNGp>q&izRlPM*(tcaXZ(r#NzIpo@Tdn*EcZg%9)Ng-FV zFA@s~aM2+ys8{0k8FWxYm3!U8MtZ$3H!Vyp?pkQMU*Nq-xf2OfU+6Qf;Nv?E=QT;D z4r8AV%SieXwSDK724|?k?ohwEQ2N+&i(m;2r{VUI353w)u%m?+9j>o-1+NOYs?-%= zJPkqDOVA|rwBRTU@3*%pMlS}MgsJJ5vjnZMCWgT}lEeaIl@iNZBmf!Lidgk`*)SSi zRpjB8F2ATcxQyF7TJ6M|^mjVj<|^4Gv8)^xwK6)57jUzBs7r2PaHPeQGXr~0-j<&um2b$pis9ToHinsKAk*TY@Jo2g2xlLGWgg@-vw#%3)*?X+@D@kDeJwmd? zYoD83d!p3dGjFfJDrh{TJb}h5osZRxx7jH5xh~T!CZi+ijV*HYPX2UbD4NkTtjr_M@Xej(6!w`?=*5OB}`kOu zqV-c1epToMm;I{na_q3|8{CmSO%te~z94zDBEW~yAqR3+E`R9?_Gs2fZHGvoT;Q+% zt(YlCW~ML9uj&&T;N7-th<966X0*R|+hF@GUI%=dl9CPeHDI9}H4C}_I;0g#Xf*Ha z&#cF#zfYT)RxC6mymKXQt`JQ$TWjT6W$0m5oH-&vJ0d_R1=2OxYTy$5co@dWVf1U5 z4f|%f&=Yzp{5^dt9YT`XZ&WJL%5qu>6gHj^!f$vxgx_Z(^gv{T6Vo*`X&0uWKBVsE zG4IF)H3u)K=|WdIfYBR~j}NKicL}?z$?H<@@}x%J!_V(7_qf=ulZ4+Vd^W=TcGG8? zdmS7t+$V<0x@Y#t*5q4Aad8xf)a}p?fKQvKgExsE0pUn5bTl2bHgKq29lpW? z4oatd5lRmd?sqvU=sWPJ4O1Gg^3cR?^(&I?L(&9qG6S0g_&)={8TWw?=rlaj9}CZ{ z&8Sj$)v*A@v??5n+JFb&JQ|+v zk2PNX))ZH>NMaBwg`lYkFx)PNCoIubc3+XK+lxi)XMkK5AY9ij_Ave6+Uf;NWU_eb z+W-mE%#_v5J#DkuA+Zwlo-C=&2=y0u=HiAe(vjd<%+Am3__KgN`mp+0lUf5UV=%MG zYCN2n4!rA0htkyA9Pk7jnO|t;G_t-b^%h5k@E8pJ$r1}$s$QX7jlp)*1zR%2G&P;- z*y%`&@{q?`FO7h=BD4^1K>E#~U(?Ex_%U?t$!WD2n3(KWzh?hmESDF1{~)p8+@(A| z_1jm0#-{vfxxvAH@%O?#%qK*{!Q+&}YlDmq<>JAs0qUvDQ3JKDIl1;W+5IS;t1Vw} zZ0(fIXn_1!aHQHm8k=aFq{;@wVxuQk&OId0B5p_7# zST6#a3qtAw;rYYG4=##jsoQRL6&wnFhYxXrM|2WuNh1J)Nb0LpBfGLfZRFA>6UE zYp@R29m1C^oZ>)=dgXnF$2FQ8r5on`+zW|G$!2>s4PAxDjc30d`F~$LTQp zIYuGiI*h7P$3A6Qmb)45+4k8eMcdD}QZ5;sbaM`N3fFnWpGxq?D)n@t z;-vg#xuFT_BN9#)E=WP$7ntZetrbn347I&z8Q|yCqG|_ zuIx4PImiHUU7^@W17k1CCsU6^baJtIWdpZ?%k)k@xLxOrc1Rla!4U^wGS#amiJN@L z-Y=o3(|qbD#{?4=; za=6c_)gcA~X>M+jXpC3V$`7~z$~R=OwTm1EETVRj28A1?HAF&e??tP)Rx`KIEm&HQ zAP`TzCp9!P&>_6Yb~f}Dcd*Dm0YnrVuP!ul$1CyPB>O$XOm84Wr*kx%4XeM8U(`)? zfsGVsTLBso*2b@YZB|SBjS*sL)h5Qk=mZvVj&W=RUL>C2qlIrh&c9>0j+^>;Edv`C zcT8a%V+p^X%~~T$iq?ap^z%slEO9NY zHDmPi1pO@99M*${`gx*$p01w}VUjMCfVDzuoOA&=_1^nnAM9*?Cm+Ax2Zo{(Q9xv7M&6N@ev4(XOWf9c zk2ODC<=sgAnl5Yp$d;1aTCzAnA|+$2`J;SRwpH!6sy$XUj$w1<8emj3D!?^AxDPIQ z38)?P@ooJ)0Vf>loI<3h56c{gGWI?nNO?$USt%*}A5sW`L_)p}2N~gCpUAQ?7|Y*C zX;=tWiCiHFZq-3>E1bG9=#~;$L6?eFa3K63Jn8t@S}@20RQZzH0uwCOZr)~QsMje- zBa`jQ^wE`WyUat;(PzyPtz3A*l!`3N75shFlsm`ifa5aNp67<5$W%YLnPn*%1+RMj zd(i!cH4*+cN7pX+xGgCH;Bj`u;#uA7h^k)r5vq%i7+Ei1wo^lTzS<4jJhEN`VZPd? zUuKhS<*Q%mml@{eQT;O2yxgx}G@$3Juzq35q|Q?PGRC}oPrr;bFLU)vj(M4>Uu4_u z)cZ4EP0}gHNTHRn`bF>7e07n2k-fZANBL8bINChece^3% zMbM2*1_eQgZ8%HEdR)m-a0r%)62pMVk}-}GTl7gHQxFuWypy9#kB`3T7!7IQ+@r<1 z{#@5SxnPUh2S%OxK|6q64lrsxiz%Z3SgmXjTau~%y9$80G1tsrJ+y)KW$4GJGr(>h z7No7=vd?%2reT8ahl*kR8MW+0 ztsk6OOZ@=)Sobm@FtJkQ{CSAz;TR`5d?~p#5V$KAoTr@-R=?VDbuIU&x779vvYHpd$ zH#-rjPpMLafAVE)q3GQ)O<%fFTsIo_Z1l9=@)xV2T3f=Ah6! zT&nV6|EQ-gz@u-9dge;xi~cDZF|KOo1n8Edbs4F#cJ&hQ!_ZKF>);d`^emm_HHB|o z?J9&NwGxtrKmTU$+NCnq6>qe61w6OFu?P?>8&i_lD4Mh$UCxvBs1S1NiXUB9`dBP$ zs?b@j>xzHAt1V+)=_b2%SDR;D=@WT-?Oh{N5CZ7fSI_)v_DyNO`qfQ0SyLlNiwfRY z@fWndb+c^eqp<9q7nl=^*n;ri=jFY5i|X^1u-`SA$W1xHYk?6YM+?C8E3WgJV5?zR5ipzyt=+ma4-w?@)`W?yImhcFV6Iujc<8k$2l!g&; zvs**Qed-y26^X%8H<}~_P|Kuc<7R|tCA3djo0}R%sp3;Vt8{L6#SE0OJCjrQ$vQNv z&;O`-aRFcBbXkH6{{(nxdw4LnIJo1I?Opvx7F0EJ^va9i7D#pxUXL39G(inF6@ui6 zw;jtm0N*-qZy`dcBjenGnblxkBT!8|%+fX{te^b2>xBgzias?`Th8p&c6?iPjMaR z-zq4oLX6$X)^q%kz zunGWq9u8`d*`Dt`vKc?40F*r0MSMH(d5 zb4!B+7wt=l3cUHfrg%}AQIO8=^gwDA5qJ8)gv+Ysn3=_p&EG&OnhF#oVJ;b3b--F9 zOGPwtLE!swRmhvVVgQS`U!8F4KRfBfIi;9@M#(?gE5uEB(z+*Vxl|1I-^X9|?qyI6 ze5e5}X_8Jut|ufT&ZomI9XJ^SYjE)qybe0p8GT4ZMJLpD49e}Bx(fEpnKREGU>BXJ zciWw#zbH6V4-N;XWfyefudk@Xr*@}<1R~Qj_+EV2bM4=&n^y|0>H*PpRoSkHyP9a@ zX*5^tnGX{#U2C^}7PzvdBwa>jW*fN5TAP`edt}=po~^an{Br&r;u}}`J%679j+KSn zt)U<^u%faeFxEg2uFbaHPwB|x8~A-vrfl`KQuEi!5~46$>GSu=kj@0$v_4mcufpda zl9c9)Y}-s>Yi%pPlpjD|%i1lx@PDVK-52eQ`RUf$O{8(uG~?7JEco^H149^`+!AX# z(9Q6!evCS5!(T<5#YU;Hmm^h|y&~G?U~%=c2E@S}M1hQofCpTb-cl?Ch|7Nf3bRs; zw?tZu<06a@$HUY(W~N;9#Bm-73nrHO2eD(v`cgEj#Jii6Z7FW`(1=xs$lzE@@o}c$ zQkO5#TQ*HSQVa;~Q6F%Gb2_U1R~w{-JYO?zg#)6*nrs;ZsZd83;2y8I6ClD39x36v zbi!UUQuR7H#MJ8&Z+BfTdpx$T;<|F$iHLg|11ae6h9R{0&MJgHqxM#Cwq4p;QV|(9 zy;6PKNyD>Boyg()SE}2kL7`A1nSx zil}KV2o?)Y-GgZe`af%MaEarqLy>Wdk+Br)@rHjcRqK$fc`DR@f656&Fx3+b<(=U7 zfy+n^H~Mxi9yRUu>-MLki;t(iiz~PeFvIAMhv)I-%Cc zJEy=+Culh0K1=R0ofQkMag$R&Q|nAOD1Gl9g^AyjcIX&KSpN$3)9=Qomoo+bUIp)a z|7`(Bi^w@jF=+mGMsG8>mie*-Ms+8AvEI$i;a7wpg$`|5B@gmksb*I}Yj&tX`3NZ| zi63c#QwKdtq4$A-%+c4_Z@qo0 zQvGxFmzp2BMuvds?UrVL5X9H`s%)~KyvcX`7&0}o6748e#-XdXP<8C3btJ^Hs-feo zhD|&l(Z7cumFL6y`RLXD$8UDM_uw(s@US}c_6NsK?oPXF_GeIZVp7DabH@kzn70yTvz;z-EbcV zp;f&3-iG^mSO+cGu!4t2@?IbPdbl(Fp0vQg>S#Z4HX2Hq9)3;oTy=dug=*XoX?U17 zh=Hvfq$@Z`MG-BuXyt1Uklbh4cl|-|sedKpOLw<(=@!7t(s|uA_Z0s+EqaxI-B(qh zWT>Ccj;8q^rj*m8_CJ~Br%_S$`&FSJo()y%)1%uA%_ zt7`#1H5|BRDjdOSW=`VJ(rNGwHHQWx4V$TC)oox^TlBLmv3iV4)4dHRkj3aV>)?S^ zOd3yQy@041MiWVE>#Vkv+f)2YSeAP1k@W&}>Z9xEu6P3(E{>DU5^60`KpK3nx|(NN8aD7GES11u!#kbL zB3ccS&$hZVQo5l$Fqfs6p+8vAZ@^;b>Qs(6TzH-VHq!rY>EEi`)Ka|hK2VeaiXKZM z`$MIgX^eygHg9$w$-&4&kVm0(IG-p%>VipJchWN6{Zd5N&?W>ke zwz~Q$1=tec5tltl2a>qdp6{`*V?W)%O;6o^hrt%GOSW!df(aImxCx1c{t$`CVs$T> zdUBO0y=qMO)A4k0ZYxY}_1Wbd>Ve$G&jn$QA<6zMFw9&Gc7P%wQVRBjyaBICVi%;M zO=UL+vaGeM8D=7RaJ&e`wT={pF!nlVt<{Y5cgC?wsA?RA@rFZ7>XGtHkfT^|eYSIFEy@ zk}=NXSystJ=P}JHDRdq^R>>l(gpVXwqCkJEWU=$u&ngKzkA19?<<4WORkFf)9AOlv zoVOe%%&F(R4Y1Y8(zhfjEuNGuNux=MY!e)fp-_c5J2wmWx?&TTchD|If)Eb+R2oqNdSen)bz-uF0su_IdV zBhF`KEKwlH+}O=6UOiKk>d?a>?jjyqv3jp!6v@&--!*i5HLFwd?O5@5`m1IO*rYXB#Lv zBXy2RmHMP|rO|VZ{8+kG%Naqm#EB{$)u^vBd~3UFhp?z2$>B^XL62%C1w~sdt5$#D zH`KRe>^f7*sh`y0L-3_v_95+HOWKQXnQNa4A_h|*H4An)a;ad4*^MLDf*mIBcF3vH zO{&k8hL(zGu_8TgQYQ+5Dy^)1FQXK-I-&)GPU#!}DtUXuonG&wyRHv^_+@xkS}MA# z`&caTbAZj$CTq<>-XdDK=u^L>sa_kX>e<499xWW=P5n@+GMe8oKy|I2#4wozbgkh7 zL7GF0tGSF3AE$S8E7_tpUCAkOt*B^(2CLbXu%w2~v&O2>)S<5E#o8FJEx$N@Nq;p# z@-B@2g&Af@W7#mzxVz__tW=X|an8Ir+dR`@{{4W$Q1u&myHEysV2W-oH889i zErw=zFKQa>I%^uf4Dysgt?+z36Ksg{!T(V1e3NGnVdZ@gB{_;a@Q!|M9MO-+6^zv;Rcj! z$Kc3SP`Z8UAP6eOsL^gUh{e&{L4(TZY+%fS5{0Iwmo|#}>%#mJckuiA{z-3v@NI;> zAVRU&(`o<55(8AL{%{P+4U}tVa00GQss zz_oAQEk=Drn8WI=OAHtZTdOjii{WMAdh}H9Kp0w3mb>Ifd}0&H`OCCa4s8rm#1qse zP;|7U%C67kBj2cD>zft!{9L#=*^>eoVy=~1&A$F1w>0MFml|#4SuM>V8TXH&OIXgClQztiL60~hm71`&E! zTe1m<*Y@EWzJS>qUn;s_(W9>?Cq!SA zFP~H*dX$8=eXJ-8Da*+6yJBN0B0~5$&_`c(a$oE%w{5O45=`|6k_se@I2cLW?eQ|f zCGqBa}7zcAJ^^op=|<#)C0N*n5QSOI$B~qxA)D?_O4=b#UAZi@pqyK>}>BQ7$q>? zr$K`S$I0gPiv><%|NhdI3q3cCd~TD3DEc@#)5t!TU+AC}u`_b|u+R3{cl6juxLR3; zOSSxE8KJA~5)bODOY)vrcc4}P@hl}Yrt=mY=EDtfrC-K~KO_Sh4AN)`ssT=KAggfu zSO#5YmkTb-3yXW%NtO2Po`TzRmrT$;91h?xxe|xNV`;tx*KIO*!D%nj-n?jreZ9E3 zKp=X1uIe~9MT_~=FE23DS=D~O3~F22rg{HLYDRQu3O{EEN9r&B04<}dMoK>Cw0#?P z;jYNfR?ybY3~*r}ZC)gEa>U)=#NW6V5)V?WWZ@raqP#2n7DK|8MoG*nsvQ4!RWOct4f($h@HKIs6Rt&FXFr;%?CtJDJ+52=pbame-MI+nH95+!LX_YY`!o%Tdyt5rK`|9hZ+(&mg*pPJ3pb5zR?qQ(fU{YJ zcv!hS(-pd~QoSaL9T;RWKJ2Fa(Y{kT1zAu)%$hbPp*_h7G6{WHS1@PNCcbGO8L+T;KDo{JhYB3MHY6`RK#dw&*EiWkmS*T-er*~) z`iN#d+Vmb&>f112idCr%i5giF-DmOKp3OJUZ;R15kS9Wi`dq7iq*Xu0svoOXP|;dG z&RRY@+%$uo_%JiI>I<#NSa1ZC=zG>m2&v3%LtOp^q^ZY1A3Y*SrK!*MkpAk+ z>@ZEK;wn@|a>nU0Z@wc+!ypVQLSg#BeviG?Ph!+q-q#g?N~ZArv4?OvCP3ny-*N8JINagHOh#jQyteob(`)>Enl zEdrb)Faxb5p-N%rfhn`|s#@=5$!}{#`c?M7lUW`c|29mbPX1)bWuXhTyy z(#rkn0h$W0m&!3)D~WU4TO0j`db1^IWZ%*w3+8G^;{#RUvi``*rtr(6*Ldd7^KNXy z1e8Vp(K!a`1MTWRVco@-4EIx_{R0sW*i?zj134(=09USHa5_<3ybYho7{;r-c^aS0 z2Y);wXoTB%a2A(`qaYJjqa?g@0|i~dZ>h`w>r^a!cP>SOS5~U4*&?#>`=dVI2V@mG z7mPaXLuS!K`x_{0v#GEC`|s42YjS<~?vbwGa&Y100s-O9{>#4aU({!+>y>B6)xt3# zQEX*{^TV$elJ5$Y2Ku#xiYPeavnzlAVLbVNK{eVqwkD^d?SpAqiioXPLwb2z>JeJ@ttjsm~vIWfs zp4+UkAAT5lMv!KQI-_r(lEl{SMl;Z}guN;~L4kY<*w-(hIZccg zpTN(xZvhz+wNLkbW{=Oe;b1;yUk}eRsgfTuLF>X+sFlBS4!z4|#aDbo{hS25+Rdtt zu*DXfi^k$)9La#@MK4bJ3foWVl|5TCD}`hEUUeD}ux5VE56 zdB_S3i^bn{hV>e;0b_)~Q}gr^%WF`Y&l4oXYfjR7AC z-2*tIZ>V>7qH*bXMA7`FhPN1l-wi~eAt5zHawAnSYN&-C;#-G`O%{FiVHDD>y6|tO zVijhXBolQ**HQZ3qD$DF5;$xk!va`F$uL*NQt1T?pxFO_CqiYFv6p0Z7+3)VdzxWH zC&;R_5f_u$?IW*6uY-pyb#xdjyxTJsD=wjD&SfH4c@U&dPP*=!lRgy%7X#~3NP-0OnNN$gSRjf)v&zF78$_s z=g6ER4e~jC>P~{B5M@q7GT)s*bGMO#Mw%Uw0s<}q8W-G3P)bv32jf_Y5zkAUbq1z< z0Z&EjB^e9&!13O5tplaRBaivWl_fDiI!OR4bQY~?2(DC%XeeGl14M(Y9AnaTV;X>H zc&q@p-c_P!cK-sVq-Q5@|Hd2NM2-8kuyQjp&38xTtl^#I-hy&>9eO$_CETx1pO1%{ zY(X-?ONp6yA0P`TX*%!r+2*QzIvvKT^@>x^fjn%mKuLgJH*Mq4Y(@oCYj=K3y92^8 ziOdZLpcb8k1GQ|cDog`c|FFL+Wyfmz4(nf6{RL|NPb4IkwWt zhvJ3o(fB$eah;bv=1dfKl4hb4;)E2APe8nAWN33wy~7{~Z7l!-%9-jlLe>BN zjvsKHNqxPbb;*L3wELehZ1>0`9p?f4{p=sh%0u*T=8w9OlbH_2Iy-EX{rt4D=L$xWv&UYHS#|epq&Ua-5-IMitfAw(10xyi#+2p@ zJ^qr=AaJpbL>Zf3ZIALhaXYEfU>d7ee z>}&M5bq2k1O-Qqs=0-19B@798>6>>l50`@Q#G=CkB28)s=7DinVQ>&{qOB~Ki_l-~ zQ#j5&2}?&jmq;>|KOyk_9*7}28N?jKDa8ueG9CC82UB0fY;s`jI5vZW3r+?ia|F$Zee`5gCfCtRDOL`_9v(oXe<%D49&goV56e*Lpc={{-vDQ)Do^b(->e! zq({4h%aVSAla(5|eTDU?B(ny?(2>)FLM%jiv8p9VQeP;dlg%BW3+?9cF|QEdSd?S}hzcE&P*aCB#svGP1sj961NoflCFb)kD0) zR@(ElRt)5;A|LWqCgekB2#2&P;Dvl@>3yuq`R!2Gr-$a8(=_K44Dy6*Xm7JWtPiwa&^eMYQRJscs8mhMO3nwWzqx|qxt&`+Q*_#uZrx+ zZ7fRMfS?zQuTh z_7$K}m#}^sYwG>w?_iQXHBNTioYhUC60`06uFaBsZajG`zRai`k6L@tTyUu#pRLDN zULopC=QB0+`coRe+7TH&u=&S}G*-&iPQUQLaNKM{kG)N#e$fG}5%fy)1hdWjm18f<(34xht;&BvZsIVO8mSr&j4s7WgIX(oFHPd%e}{B6`t<^7 zamBAWjkzc5xDyxrhbY4fd2qc;!q>~5h3<(Idwh`}H&IDh-(V(qlVMlbTZLf9uhJSB zf}!d;-wn|qHQ89=2*RTlf0vqT|8y!=uxB1B#F?TH-l{%++xU4AtZ=WCxHVDYf80`{ z?aCv@w}d9nK6U`(Dn`I^>s=^O%lRsgH)$_0dc3Q4$vA7;YDa@kX!&Um+iD>?vwK?l zj%5#MX0jOMk!ezb-S&Tf)ZA;Rj3;kPLPP$svauhMjXm&5xlVhqrmD%nI^lvyE1$~T zemL%YxIdJ4eObi!pkVw1d4j)wwp*9eTkcd!sE=I$3qce2#N=6jKkF#24=EGN@=?o3 zeDsCGoS^YcKbhgz1cRU|cYr^kOMmHNhQSMMz5DU#MsNBtd@8NZox0)$H%irQ!gLNl zB^P#7xrr-r9=U{+ygM@`G_)#ySCyVEeNWQ;`-QLLpc-@eiH~BDOsv(`XS>KQFP7F{ z)2(|~9~3Zoh)o&M7{e}v*AQl54SEqo6<&VA1!0kE3aA74NOrnW3&zW>&Uth4t7bCn zmjwHmvlKy!zA{e**%e9^-*~3hu1z4oOu0nM2L<%DJL9wU7chfDpfo50F&%D7otuBA zERyc5q|khksD*LN`n#D&ud6zP3O>`Oc25+2fdk(b68YPVAds$3Wr(JGhh{!84DsV4 zQEbGkyGN#s+DC+FU7K>}qXY>F{TBpK!W}3tm#t`q&xV04aA30oNtbtBm<6gpt|j!b zfPlWV2egXJ1oRnX(y-e_MqfW$+~G-?g5r#zr=*~+bHzWR*J)^xoD6cpw`RDaW3aod z>#Dz4Y#W>k&ANQoiuR~impA?C8vjhWa}|P@y@vP}*A4nObKEynyB+rpcXA@`ZPspW zH{*Cxv((DDBILcpV)U^xX3fImgU>J90bl2{{4VYxv8*O2M=0NPy=xa*INgX|jBE+% zzrMn#+nyiFxmZ!Ab%%80$06mwi87qV3^0bF6$H`vuT=6;w7*ZRniwBaCUK1+Wcf{%{yw=f z?#+xse~B`)h~iKTkBr8%7~`}%#o3e82IEKH6^=#*3F4VcFS=vewZ z^N*qgwqLN>q{qN!b*MUdx7{TC!Tf7NMd<$TlG7`XAMfh(*gcvnz4{ZNB#ax$)qC{= z2H`L1hm7Fdu*&r|+{c^cwFsP>s%ut&GxdWgE1M>Y1x-j3nfk#aME2NFW&SdEsJwC( z!VV~UJ}k}`Kq?Kw!;I#WTB+V-W9qfIjETrX*f{H$6cDYBSxULOj2#NQ)J#eu4aMTN6cjD@sj-Lkr)$eMo#nj) z=`qVrnFS@#eY+M;fw$pODz|BsmK)uOq!{zqNbwe5BKC(Vl`7LJakD_PX4zwj3|Pj( z2+J*2nMq9HyuIb+<@Q)iQIpee)a7HL7wr^cWibRgKds$omCnLG@Z^o4f6g;rnbas)YI zM_7XL9Ue2#zav(3#(dQ9H1!{^17)8p9(n{tX_?KC*!W7!xKzoX^@omI<2y1m&=RV8 z(z)B!QY05hMj{v|L85E`lLQl&rSsSeT$V)SU8%mDmqevdr`&(&g83+0ieuksK}lbi3;Rh4@okFlE?8(9*0RBt1Qt*g^(s zW(ou(!Utg!7VE3yb>_pQhI293NO$4d51N`sB72>Kr{-yy!so#^;Io34U!AV;aujNB zq16vjsF9XS(~UV#$!$*XZ*!xdTf~_13ti`5NsF}9GEL|nPVScl?J8=vN=6{YWY8)+ebhM zf{oG|b2~r>x`@t9C(|f~y!vCIvf-=?{oHto1txysVKDJ7OB;oXOZmuA0K43WY=*yT z(^dF>c}_Zg@>YiG}CWpY1Kg5gzW+GxvD#s?AXq~ze_Zmj^!FD!@LQFy{_fG7Re3S>pQ8!a z{SMO}z_bao^J%C{GzBy5x4qlYVe0(ekq1&-DS3wrKELCi^XFkKr!QGIfW-E-QA6Le z@KFrz$QPu;UKuZ1vG$bgPY-NK2@a9i@fYzy!Yyu5PU?u_8t)CYU5*wf1rN;{f1Ly( z_dz$-2vlAAps*pZwA3F!{qqKqAwd42_*{Q28gRkue6raDJOin*tT7AZWVPR_R0~*n z!m8^mSz41PzQR5t2RYWmKV#W}U>z#qWzzOViro1KuP+6-WM|0@(c#9Z-!ntKV+9N} zH3h>9dg^0U&)1wYXVOXvEKLU{)m=Qn(5**PcP0Lzn9_~b$`}y za``tR(^9;@L8qpPJIK*t+T<}fL{0!}LQA2>4Ho(Z!sbulaMROooWlK_QTTTgj5J5{{ zVfb}hR-6TFQhxxvzIPwcn?^PC=dh!V=cJ7;5_KDZ2&=Dk%*7uyr%B)0TbK?^Rl6wH z2kyk7{qBh#2amJ8XYT*iZc4hryW&`hr6YRbBy8!sojUgP zTsZ~GEp*PaI-HKq>h37V>8J%FO-8R*;9K!V%?f153h+T%`id(jR;1fUN#E|4-ubB^ z84#0oufquvziJ)YPhW>lXLvuN1!r;Vq)}KXqoh&U3191w+pMp8hJpEFOPTZuT4iyO zbU_OxSgJ{yd0)q(#f6Sp|6sbBt((o-A}qP?#=0FMef{|4B-LNWjIP~`u8a9GNG%=j zZnx(kzeYi^rLQcgdY+bgO#B>BUD8;S+LWy@VmFElNm__v1FAhNCHOd>HETXjW~DlE zQ%?#>I6~XcD8JW~&!|+-^ip09sh;gWV#?31RCo7MK84ZuEdRa4cy3HCA6VY_h3veS z?+4;S9&yEx-l%s?=tZlz(W=>Q)ihZ(xR&n1veT;BV%0or)odjkDPaq(nge(SwrcSG za!A_>)vRkNUM*X`f}@nHlyUb~+Nl13xI<{=T24*wPfq$~^{SITy+?YhdeTW3u2-b^ zK3^akMftcLrlarwmfF)-ywsOI=G|7ju>!_)XhSS?ztN2q*6}8%ktpYZzvGuE;i5bn z@C4Y1qCSg}(IK^hGFTBhCQXsj)ha-W9XbkbJ-6Bs`XNGjq9II6Q`HMEo!3*P=@G%CcG{y zwNHJMky*trO7}l!lXHSZN?X;7gXA%jN2HrqQz;f&XP4eD(WZ`BctR-MAeF6}W4N3q zf~jFk6KAGX-9=5hYE>~B-Z9O!&{b)slo-!GXWV;S>-12!bWh32`idHM&5QOeIQ?VP z%Q->p;+1-Jx2S-;X*FzTx#y6;M|7Z2xk{kkN)I{UsXm?tC11DCwL<_L2=x$(Gw78u zzaVTgL|-gxxNeK&^|wNsC2zBOC^>ICitC!fvOZu81_=~)@pAlRIj#C;{$QDRU9e9sB?oa;W;J_4|u6-0gZJGbFPR4%muzp+M2(cwsZ9?cJk~!?%>m zp%kv7hPIJk3(z) zyS1im&5ix#qm%L{Cnac7gjSbo<8(D{GxE}oW?XaQ)?di)a{W6F!m+v0%~^u~eVtOM ze>dusefoK>{ym`CL`pw<^zS~YOXmh4C9Y(zA+E56qHDKa%v|S+{;wA-_p2AoWF;*a z5P$$dRyKc{JLr}Bvc8Ce{F$tI(R9}_URh=BNz!m7KXalGI^S(5qLd7&Am2acJ~&O^8ozv@e_EOJDi`SDbWL_N<{Z~z$=%pzq zE#4HX1=HwXHKKZH#7T=c!UCK*kK?`6bJ7y^WQ*@d%%u-Rjay{-r%FwOFqkR8sS`TP z*3-mG?<-!|OOH-kqQ|er#lA%6Nf=!cP4`B|^0lp0_tuIe{-0Wz+gmG=_!PyG%c=%anMR{iR=_ zZs>CFbxB?3s`GT0xpdjjbQ#A4NEBOA+`lrr(LBj1mJljRR&aoLI=}a>o*v12DB6W5 z?R&CT^r%7^!FuFcmp=i8%v~XM&gfmiq5Sh+elxe3pod5I=v|?k3D%2;VO($>$LFrG z!;DB6-*(><(h{NwtL}tV*C{lYDD2PRTrz%;@#xFOI=&DnKzat!QuZLJBA$NxaZBbj z6`U2jx>XXj#gmq%%~OklB2IJm0YsHMTwD8rm_9IIeRhHFz6n#A968kO!rX$^AU6Dg zLjMnFn8@~y9`SincX}=1mv|sQ#oyrKIwa$i5^*97rntSU5))M5uVi6COK75Z+sBpa zdruP1Va8G|8G@(}jL`a1iQ340huMR&|5z)G^Z}LXGx)MhRK;Zvc9zT*41cLT*-gw} z@+T39OmcD!ral@;IES396 zsLurnF^V_{-Hiupbx9C?=#=09t+&xY z{3B8<=F^YQHoQ`70wHmP!96(yQC2#c+xNr2AV@Ey2% z-Nn7DXYoqNz%u?w4?Q~AKnJ?X(oOz50-FGoHS!+EmH+k zo$xjwWyE5DSPlH;AQkTc$JhmEe+rvK-BLq^PPex~6b|h*)%=QPSG#v_@pz;toAFp)J{^xJr$Mj)j|MJKLDW8IKYe?p^xY zTlYza@tbhz32ph3fhuZM721694F+Je{XvGIqksi)<-WBL248nQ0)UaH%ZovSPkAqr zVNRdGFxz)hvI7y>$>3OL>Pk-?-?+-BYUlQMjcy5s1ZI}Y&l34rDC-}rRX@7}UPrN* zea^=J`g6UFw&3*98mB)#WnZWPVT6C;)wP16`>6bpeG|sU*4E??18;*E9jFKG!^KUxo5>s~O=B|JPoVg} z!Nb0oBYgftqrhNJnf z2C}X5ICiWWLW_2(t-s_rr@Qm5>P!={r^PklCE_F&y0_{-8N2x-z7Q!i!u|q7lG5X< z^JpyAxMi}~c!D7;^Jisc&qxN1!KEMeF ztM7tm>3-VSgU`sHanpIT$|hQ6h2gS^v2a;o%$mlrZk3H%S2ofrn_!iVvC8IJWwln> z0;|k#l`XQ$7F%UOt8BSdHr*E&rD5-pl0b@%z~v~G!?BS~zNuf$ZpR-D+Mvn<0-LA?$9%_4KfJ9cT{@Q{@ z{?`9QfK+(NJQo&Er202rJP%w}c)6%LWk)aSz0gX^6Zt|H%CujSigHj^s?@#c&|qO) zi>4u(`N^7$!mMn3Xet0~*5vElzTulK7wt#^O?-*O4!v6I3ZA)WjaxGPoUnlq)z_p-HmN_)SHni*y=SP|4Dm#2N0q2M~7 zs?K5MTGU;fb3^ADhe0s5`V|Ia2ybY-zhHTLqZ~tVhZYs3)K6hlt}7 zJc&1s?}~~2*X{8;i>~=kUcq|0rc#-Sn)}rE5;f~h&HJ31Qyb5hJ}afqVvlwjp&b|C ztX`#wVJ61lUad#Wxg1$i9q2bFQnwX3Hf|$IGbK9AL2F7i+JV-MwS?=irp&c&TtKiA zITJ6kL3gDR=zh4Jf=z2}VuO_)0@gwYrCQxltL~V&df)_qQU=&6G}uIoIEp!UW(8xY zLn@YyUYNEPv$qOH>u%~`>`$xeGNhhWd?=L9W#%a2tApx_S$xrN*u@9z(7td}HEoT+ zChYv#yy$5u!}O5H8$47B5A2 zgy|eDuTFbr_NQ-ObQpF#6p$#lRR%`oos1M8Anx1Vbwga*@xLe$vyzjfl8&$Y#PS2& zsEQFtb;3e-oor4C5;Nfc@%Aq8O;_jRe|muiD5hYM3RSCCMT@gqP`U!PKq)GPltK&2 zZ4+u1brwvZPReB|LiRE0oSXWcoA~v{HaF|MP#tPZnJtq+olHTPcCOn_O@CTv2St(m z-_QAck|v?x-1qhR&y^&f&$&M5InQ~{b8REW7fKw7-`r#8mZx$cIqbxQ>4%%MJZEnx zZ8LaFIVtdf6c}t4K-!sgxH-{to^N?u_X`ZuOjaSR?deNGN zc<)rxoi^K$?hSvt8YiE_&4t|D3eDFtDyOyDa@~pY=}Q(pQgGsMlb_J`k*+Ny8vHm2lM+x5Fat217aH3Dgkrt^0c?7)F;SDJ56ntyi2`Jd%{cI5rh zhcRATEcre(8=@^42|+S1jcx9`6Fc9t3X))Tn=^u+7L+G@4;Nf#U-@alb*Zai*X&~I z>*wlHY)6!A>9Fj|Ig#t&GpB{#LAhEjiY)6S4iFbjXG}q1lRuO*l1_7FHy3>h-&A~DXwmw z!jE@xMqzKqV~18{$eAT(Y{BA&35XJ9AQkHTbylaN zd~4U(ybjgXD*e^8OkX3oYfP`<40#8qJJTu+d5YL9+R>)3BMcyR_db;Xmq20c~kk${4(So%$K)+$hn0CjhefpCWibIZ#GY&1hq}KRZ*cb zYEgxUy@-8XW8vV`W||LFuTf+96hlm7zTJD3crAG^mt0QX9JTm3Q-DGqQ*-&oRP#dR zu4G{DUgBO_;h&(&8}OWk<+?)UMT%ami*g(RZ2tsP=v3~?2-i~Q=sMXdfpYm1JPy_S zC2i-bwJ-_`f`e5jKe;IRvG>^L6c?Rv_7*T2`fcTK*^ei>Irj=emSW_y54joV z7h%9X@YLqn^^04o~sRgFOy z1UA`yRp}svL^du2b2Imvn7g4ibty-Y8ISNvnRkW4;YMh}$o%Ro@9>BSnA7tnf*S@= zj#|Fq1W1q^I(pmS=~B&{N9@+7x{kWWbG|eanU_giGs3#{<}XTHHQVrJT#TvCqSQP> z#SplCTN}(}Xj~rA3D~BxXN^ru+4IjOY%UD}hNK^qYNPDX%$08&i+byJc}7h2y^&0F z1&h*FZWB=ei~D7M6Z&o7zme z8{8l^*PYK{=|%*h!3}nr=@gSaqtfpCe1K!q{e0)H-ko2Py6Q^&Z2YCI{^FfRajTJB zU$DdBTPbC6ze!0d-svkQiA&~l(~Z*I{%Jo`#-e=%t5a9LUGT5lM;UK4wI?T~;#g=ij^Ts#q%nV)@#d3HK53D+w~g-3 zmncQ8MDHJrQk55SC(W@~x1Y`mIp2ua*Y zi>val@MKoxg=n`@QhSAm;@G@`GG==Qc326<{DlUaTV{HU_Mb$A8a2tzGt9OJI5z%` z?M}mP`x0zH=l)E&PjhTb-0HaA@#Cf{$K!4C$Z>yTU90B?$F{-76#L<(R6@j(6H9ri?+&|U#Me>?$#4!uQSfq4JuKh_&DvkN`i8^nNB@FLQg8=}R*9Nda z{*2Ci_L({BYvjdO%=%8sn6sAtnD{X|1Dx~c#?LsLl7b43jh~ADD$5UykSFdFd}y?r zkScpJ224UW9GjnpxpBiB>|1~uioRTRkKAce5)JErq+97W|Pp zE#kX#?NG0$7K$0(X@SZfSelk9c$!oVgS=4ZlN6~c*z3hQhGSPldOBvTOR6xgs<0=$ z8$74MPVK6KR__2F1k<1~Qp#{fF zkB9}JiJb&`u;BJ`-($`w4L8BA&if-J9_%YIE_lcUfv@jbZfAg^RYq~f)N;HR8x^;Q$P|04q?tpRM&|mG7H&u-J2!JE^}dKqlPq7GP~}0S^M+{hgJ} zE4I&W)eAn zAC2Hibyi@iJ=(oe)~MzpcM@qBHO^LN_E%t_d(iwUf09XVG{U?Q9DrYN;`+$h`0@fd z8?$XjsJm>M?ZP?JY`^AjQ28|5WzL&s%j0hzf8XJ6J%2s? z-B2;j_7HzB^T%0Y>3DQx$;Vka?M&pT69tR0C>>HgSc^$JEkjK8aJoJ?M;q&sla5!$ zSh|JY@fYAMyxiAf50)4uz1jm@>}~L+`R!aQHhYed0)Hi<>%7qFV@4}>!m9Sbjarou9#@@;4JEB`3y#%{kkN6Y%7LC5DK6d0c7)CAN{vIvhN>oO7FkXHl)c zM4q$kHPI!RPWZSvjc9=RWvtf~ym5O;m2Z3T$DqJM&zU-oT)32a^`_G$l>?(VzcTW0 zYvkc+<}*@VRUj2&3yAa6yOx5_SmD!+Si0af39?hj$9AC@a-9 zx6^X3Q8JNvW%z2cY@XpFE_5Yu)I}67IzHT3W1SNQ{Q}JCM{I#Pg0HWUfM}#4sNVvZ zBH|H*i4nU|U)Qp}B|@!8cDY)+f6*iATE@dR!B@{%m$l&^;9X&GqWOt!WH_I0a0vG^ z`62f+t+yat52L%81ILQ%Wb9$&iAJw)`5`#fL%!wh$gVp0Q_NSY3JV*n?0^~3SrN&N zh-AieNoOQyySr&q!em{*aB@k7V@pF*TKvQqz6FO^Us#r0^|v2Nj4iDr#`?U>Es37S zF+@IEsUIkAK!~uLU;FqKJV(AqnCT~+?nHi^P+T-Fy7*<0>5D~wmlJfAFf>*p@)ehH zT9n}GGx!CuN-ExMcsp{uhe#nq=EyfBlgt<7D&+d0awHM^7Nku{#chGqv!w*_T((G& z5Jh?mN_*B0G8P@mS=5oVsHb32SFO%?SiB{vMKUc9GHTm%YE@EgZ$WK0ugF1I`iOgk zJLC>k5}Q};Tfjnw6+VOJ3BAJ2GP%Jcm&3M2a>;?Y(z0`;as$-e|Kv)%f#(!!NMMJf z?=p&(`r6Y3_X%%CsAPhz7B1AfL=qTr2M(d$uF1l5l-p3qn~7X6*_e@Pq~+{E!c~^D z1C~H8Hphkv8o^?T$-LZHp#VZ*(B4WsyIngnIc*z$E(5zt26lj5a_sd1jKQ&SH&yAj z{sH+63*|*Tjk3(K`8PcE-8t6g*cjlOEQ<0WNi|<$up#PE0Sp!lFf&Fj;WeDDN4Nk) zF&k``JOfLSsbf(cu1F1BH?Ayjo%q*Blp7&JKa(%u8S1IwE`eN{KY=O;qlEng;Vw3a zLA)YL9}*lHUFk13=}HVH0pH8ag#cNbJ8)T`@?c+<5DO7=s3T40B?$&R`VB&YzgTbL zS3>R-eJjBUnZbITxDv7q#-2Hmo0KLwF^izhZxC!!67N*pFFk4EEBhnl7ot(#&rJ0d zm@5vKUQm?_a5vrQ3vi~s3}>NQHj1;go|zlaA)|OKYHfD2D)}z8Me2#5H)_^0vbehq&~TR>|8M~L4&(`8R?)26wVZcHhxHnY{8mMJsKXn`DJnE+c^9%B7)| z3&RnetnEeP7@(`iUuSYsU94uM{XzMwJ)UcsXJ&<(QmAKqH9d>hK`P##W}yL6=zL?H z2f`|6aV8WkNQ6oPLPw9@=r-PvPA2P4v{if-G0}5V2HO9NrhQde{CTwZ zcC!X&!<(}0J@8YQ{2k0+yv9+tmgQG=gvvK7ZP9=ruGKGkiDvP zE5}WFX#9Q{2JOe7_40dJ`{ZBQY?D%L4{!EnnpIPtp(uoB{GsTwqR?>AmRPxPB$+|_ z3p4OH1zFLux1E z(&K!dXMunu)lk3O2}2FZUvvytNdy9X>(JWmuJAE}Wr++zd(2vu_Ww~=A{=jEqqO2w zm(nyd-}CgzW#a4gf4r)FB_V1yc&BFYsyWx5SnPtltjcF;8 zfE8L28{QBB3K$2Bsq@7G1)CGkNJH{RMR{73cEf_+IX}PF&JjLVb@?rmJV{@#gCD)~ zQ!#p=h#Ev=kiR}A%NI)WN{Bu|Bj!!WZo+Fr)oLQR#~HxR5h^Khlx|?l2M1T`6FL=4 z6~;>&9qaLvzJ2M|G*X|of8sA%Dh@`bzRp8QA-jR1F}?{lZ@N>{c=s_$qB8#5!@=Gf zV4-&bVl-=1oexFX8XOY_L-vqR5$5;RKrZ#(VhSrT8yef zt)nEJ11`JlvuhB#%B~EXVMv${Op}#!C`>2c_M$WF;Cr~4X!+jR{|k1BSp8fQcY_!H z>8{X-LwqrXl)Tn`#bUxGRHzR+Q9?U8$HYVL^M{cUud9}|!m33~Y4o_n)+V3TS}52*BSDUP zB~fl<1()&+?s<<|dLx56ods|Mc1Dk{Rjc|ysKP)j&I@}YI3~A>6w`pk&S|dsCwa-S zZlYls{54@A!iCOZaOh@3p;b!N+(>)VyZGf#QNfI3Sgb8xBGyLc?lWdc{F{^pdqTqc z;JKg-jFzZCtKqo#zd$pJnE@IZQqe3FDWN((5>xdITSF@su4b*Qeu!B*)w4?_e?$hx zB7|68D2Ic7X_{wMgE7s-df(-l;Jbq>$Q8UJJ__flQwVU>Ax6bf8n|Y~tEecH)BCo_ zOPjHsJX%33S6~7OKIBvq_*M&Aq%?3H=I%DS*)PK5J6>r&du2z3lEk=F75T9sS;wa! zS?j|Z$r_%KNtocFwwPD~1*gK_5eg}xg{*~vS8CE18_eJ4XZb>jo^uSji$;+VR2T1v zJ^ermxD%HcrK#|&WtHVE37KqgEZNDr1E541rqRsTHKy<4RKdl@_>?QfekbUqs;MDY zfOd&B!|(5bvC{VNyj?~4rQNFr6UfmhK9tl1+e}5BWazeQOwL?ydn%dnYx>BXW{W&2 zM9?5$FlujM5jZepNO2onj^>zpCUVe!d~J_aI~BsWOcJHA7pCZh9}_i)62G|2fh8ViXBFr&Yv>((S ztx;Prnm|M+Aa$B`C($AXXnM@97@@0@o+fT5SX(H1bD9FztW;%@X~%kHwt^BZNo=} zoNb;vd>^HGJo1ly!$(_~jCbv%rSf8+j+$}{qjecK5Vu|DP824KFxA~`U@`|B1@X1D zw`(|b!ep)3=_u1IL*5j=N?B@$pYU~y;AL=l6&-kWFdd=aKe|?nQe*~ZJ_8t##Jk}c zQ)dg$sQ%x#7<5gt`n!B$|8;o)87oFIRQ-6gEP--q9EEtXdBn@k#a2?uA8M=|>c*%m z;xg%_++)lZ$<{cJ;X1}+K;4gAl;s&Fo z3M7rQC9ij_rxZIccZU90KvRZ8u39T@iN-CE0wS0U1>GsgC@1{)DazG|#0lDDRD?^U zX*Blc5Mc7kL}X49n3h+X8B$MQ!@v%DudZ}G@uwR|ImB&Sg4KAx5wChQsgE4&^LoSp zwq$l9C5v9%*}+7k8fG)rd2#=sFO!JCm^1Q);I4tpaL@($i`M=GDwy$Sl( z+YdFkL~rRac##;@a-oeo&tgx!Y>{hdtEb+X;DlxM)TPc|C@>gfhLXuXv6TunnR}aQ zMYVF6wxU{31ITqzPhTODXW_+GPFZrWm+q z4;-J-wwSQpt8vcr;)Fz;Cmmy+c%(u%KVH=NNrtwI6_YQFy(%gl+rBV9Z3?Cd8N^J& zI|~4QFHqX1eg{u$T!~PFG{LZsvoP|m-Dh3JVKXXHwJ5zDK@8f#fg&$0*StTJPYYs% z6$xGyrES0OCwgu<#`=liQo-~raW-cjYR;MR0y+}%zJzduyF{U0G$__f&zcmg4Bq4z zya`Jfs*m6t;W2QUd^ z$(oazmac*H0f)}FKGq4RMCQKt2CB>u_nV>lE3yO&?5e2_KQEa3B8x72N2%U_p}3WR zG}QtviHEW(OMP;d4h)~H!%+LtjuHxQ@XHh0mXh;A0s-t%XGJyfVt-9MLlcxMWI&5e z{xN1y0VN_)?L^~<0=fiW-X0$S+O)Y+;}No^afMU&>tg1x(!Z9 z=b)p0U9~tQNSEi20Xw~KXLyx_>)D|3Q=ud($*Dd1++nVUjcGXkC*P2*n zRnm$iUFz{;Z6Q!D)$d`b%E;%O4Zeh@^VjBYFX54UalheFG!Arb(XWkbvyFP8DaI5;w%tb4hQD&OtrPXida|c| za4TwoZW|6YWqd6=(EfhYUlw)$rMUah_^g+%w;dXqrvJ6ezZYci?_V-GU3HJq_;wY~ zgcYR0kJ6{XgcEFd7S zX3q>d+_~%vOxLqeJ+PwCnICfCgz0J3FQKP-jhqYoqsbsw`J?OCW!n&1xF{IB%t#Rq z1Iez4gyc|?af_a#Z%QE19m!mp{s{dI-|h85mIh@Sf{?4gr07CVPp46Rn##6PuOQq( z>d8?!Qw>-R;SzyL5l&YTUEetOu)ZG`xyk4d)&e4gjY=FC_FIx;O>T3)>I{V>wDpnw zOBS25H_2g>syA~%f_F*OL6mZzrcyP=3{S!AEbrh@b&Xo(gi2_6a6BuDff=z>KR%D^ zvvvf_Ge}0hA}zd#tRKYaY=|v(Xsff-F6an!jzl%wC-cJR%3d{u@r75RotwSMhjTsW z3??Y1XdqJi1mYm8T6(V@=A|g9E+u5BbT7yzHsX?No)h=X$RMqM zGIg4t6TLg{ARy1nUz_EJ4j7=P0B_VGi+gMR8MFvmT=p`eZ{nF2K8K53zr^?O^bz-Wb^D*b1{~r zE(fx>!r=43oe;P>#H!L_T<%z`8JA@f!c=9rusynk5yJC)kuJkp+<6aLRDCNU?6%|e z9ThBF(?@BQe3h+tOb#!NP-1#2G~PUJa)qo%9Ra4-q;3ZxG%-XWiqw|-_dg$}s9djR zi@IDe1GOW)fa+KICXZct1?VKh(ka}HYqET^k`sKhvO|^rS$6+g&RN0gU)Zv^O{Q#^ zB}tvvL*f^c?Wr{cg|%dLsqABJO+;2bh8kj3CG^d`Y=M#V@DXOwLj-gEg|iq#QlXD} zIs-9+L4ZRrVkX15k*V}pq+CcB5IqwfzQor&hPDc7?JJ+{&J7v^%zN+y>hr5^9$AG2-Y zavlnEIeq0G@0CUeJSHE$NmAVA`5tpvmAA`iagSMipztMndluU#N$7mI98CiT#_8^Ro81FnP+LM|&{(c09R zRtAM8%Ar%;_5+S4=;7VW&LzfMvbQw_acT-;#OA1Ur(ji8d??RrpYPo8j}Ya>h@j^S zOj1e@-TX!>_xS;BkF#Zpy9#o>mlw>id&ffT+!(WUs3Kg1NS|aOk08Y#F`3?Q+|~%N ziaYP)N8X?OxdgAvALgignxAv#m~U^NT0w{sW&fi%hjjpoTd|a+(J9HQOZtv9YB-Tn zr?WDFDL{OYW7Ate8yo3Ob%gqmex#YE-2eqUfsWvLMp0URuA}ZaC$lDMQY27B67Zjy zW$0{|_dQVxXO(_(|0*&^L^(qK2a9jvuql*;!+iN~eL~ zA80LzAUO`ddfR!okH<95L?9$=bjRyQ)d#%bJnC|G%2GzH!5h4=)*$#(SqmLq=pjEr zK#RM4pXX>*soEl?w6#!sXE)Pl1EoSU8ARt#!?5H>cOJ%q z^g+?PGI~v7(oP61DuS4GiiqVus?k}4HZywJbKK>rH{@#e{<3+wp-A4YBzCX=2jK9(RUBzD!f7AI}#NTJUm$Ga5 z{uAr(4L+srXMD;yJiHILC-3&~_aT4sez0$vZ6bf~Q|9aZRZ&OU6*#Qp``!G>y#I$! z>HC*_e!!pf|Nr<*;ZypPck=frb*21;e3!9FxpVlFPnnZ^!s(jI%cDN=z9bK-`amf9 z^fBVOtX(Hlk4(=39Sc24{D+3|S9Uw=j8o)g?j{g|)d-zX(fF*6b5h9l~%*+qKC3pY#z0NJ(wSP>2a z@H}}#2m;V_Ia?w%q7LiiXSlvnj_CTkrT$Zq`nQ|)H<C7(`aaKJeU@jX zvBRfwJU5Hru}c2=mi)7je-N$lYL=H;k)chr5KSqU6#G9`tIA_E2d$THOH+S-Ljf7XvYi;Nk< zqEx_~RH!DN=^JhdN$#}?;PV6>0PK1J^%G*OsUrAK-|`3GQKSr-+hN;9-G%-8j~j!h z2}x{KXHiD>g8J)aS})D|XiV1^N#9Kq!uLo)Q_`k$31ni&VT{BV z!dO`yZcGlv#Y@PNBU{o8Zvnq$;rA<1_|?`)l_PHq~>n*<#)q1A2n!&|JJxQ>JJ!f;#hcEZWE~Sao`BdAF>k#VY#js{BicbKk7rg_BZxPHYD7LR0T~M65`V5c;b><;Nl&)`~=b@gaM&gg4 zE#1VF>bG>~y(GUl%abOqJ*% zStV45bgkoRs4JU+K~AOL=D8ZyjM#Q^y)>OM|6>IV9}#SK@BA06@D(-$sq5bTpZ;;wzfQ$IMA__Aj^=afk!Q=c>?2pCpNH5M(b8%JxkXymF z?+`md&bl!AdA@_}%nTXQC7VXJk4&P^e@3oe>dL2OIAnKpkC-zjsTr2MD+wE`IUw?O z5JY>}gq!r%8;ewM7zW&M(`ZYiyE?(5wbh{PXa=HfspOqey)c4>5SIv^U4EY6nKlX& z2BA+KpysY-TZn!9g;E^_*)mMzjrwfXgO*k%MX7R(acpVXEx>BJY6bcw)#QGr2i#FRt zB*U7Uwmf2x_5k1r^GjlgJ=Wxh!u-LYOQ4@*rXW1fYNamAXKp2OunT4y^<6?4EZhpr z-p$_C@q#vgtO@E*E)E|hU*AfS6PaV!iIt=cp_L6YGsY>*UD!&}vN=XZ_8*!guBQQ6 z2raigd2I{Sz$o6PvBqk^G!Vp24<{A!G7_1g2)5H|81P1$`@PTy-7-1VP^HV_hi!!E zWv~-@<$R_XbQ&eqZ2SryPSLI!M)lkbl%XcoU@V7$lOQmx=f$ z+q{YXf$%>OCqI!wqe48V06Zv7$0mGwjj`CnEI4kGkf~!vOb9x1f|iNiB8^ZZ)=rd| z$@kHw>@z<#X4RN64?f%s1t z^&$WjpS!-LK)@*)&Z`=B-7oQ+Y7e>WnD@DJ1s7wIIdC?-dpB{Pta1cTz;~(LulrCn z7ixAxhb(bz1^5j+Wv~zN*fcF0 z{jgkHl6xjQomw|yri(ObkJg8H&ND}))}0MM)$Z{1CJ_y`cOZUdy(to*a*#KXB(R{4 z%;N$*j~H^~(4#XO@xLlUJXQM~|17&8Ofdwn*ezEF$5)aK7K%?~Fv2dP7(gnYYLZw} z0Eb?Hd5lI&;u*>rAm_L6#NHNdW@eel2YWc5G^%Eymy&CLVRF8+8kJ;mDz5wk+>Yym zr^z%11)Tpr^4{n_osa+694zbrZBU3i-Bz!Wy%2Sh3N^9on~*Hr2QVZk#Tu^yt1uRA zkWY+7lW*kI6k@qYHQ_DBN5R{AJ@SMQa4czKQPO3w8JI_(wP*-2mRO5AS$K6FjSGkT z%^#RYNLhunX>AE%1x%v=OKv2`i?;V-8`I`FLQG`}GXDC^Xy8#mEX7f)ibBghv!O$# z@{&vi)zYGL*F@~#F)|~a7h95BzU^7Cp;Nv( zHa74tK}ZjgBggOUAR4Liu_-ZQWB-)}N)M6Q_z7+uhIc>5bDArSagkzNyQ6`N;s7h5 z)po0W2!1F;Tn zt-M_@H4ijFpl%6fl&ep6v%9zx{gY3z<8!K^6tV^d%)&!5x`PuXLW*~%zj&*V{^DnZ z^cUB|ZvMg7qi*6Q%aUWz_G_wacv-f}h6CE6MA6MsRU?t!r%pE^1ksUue0JPuZ zF-@5|>)KRPXT7llahUq_y9`Cg#1jsUD^-%AUl6HGc30^3F;G!q(f=%qYBO$6CqFC| z{Vyu1K5o3t_JhLo%^SsAUEH0AO0j^HI8u}aL<=1oZ{txNT;5H5R^^XZuP(KDZ^b65 zBCxTZa$<}0oo{Nh75|I!zNzYsSvH6^^J1OJLY?Z;&-R+c`$udea1p}lVN8Nr#r`KBB6L9d6Jc~!+RToSY z-c&Sh72$`sgi(R^q(H$NgfR|R3XN#Ph2M3{kL6Iaa46^vt;!4pK4GM4ZY}`U`;@4A zjiAlI=rb}P@Z_A-pJ)$aPfP2qbz*`|CW=my6O^>`1ARB9bNSZY-1>J!lrPHSR+2L{ zyngFnl@+oX-Pl6Nvvx-ByKxL5VpUZZNQ0F@;a%3w7kdZ0Sn+;aM*_=`I|oRI$J^RT zFwmr4;%Ig9)Tzc_D*8Up@cjA7o=dRlc$GP@LK#71TT*H!r3#uoj*^1fV{6{9%yRAU z70D`6qF_Jn z%O!H})yBP;lM>XDA!{AKH`VoBxdVx#gK)QtZ-^+@Yg3O`c$X7zF@eqE8O|4pkIk*8 zHciy=-fOY_R$c6ICOH{~IczmOns}$0S&A4|58_EdH(K>QD$}%6JxvdEGk}(}TulGN ztRWjK@34B1*hDm&B<7Fe=%yJdlZIMGE~RNiWNaN$nqJVPgSF*|m|J$GrcbynQ$5|+ zI?^3!mYBgJVTD~{2%cJDf1dmf@8vCDFLS4gz2yn`Yi@Gl|) zUblZy57DB`00*K9NGK@o0vbih1;yRoDFjXs22(CU#J_IU;2FY^e;#Yc@}H+YaI^wD z>M+AP#DfvlURCs3C=@obA2&iSKPJZv*2(;2c_pp_klb(v)TA_Ru|FZg{Ay1V|MYD2 zGTRA9eau(V5dV+3n;QP<>GV#Vjdl7OY(1(_zvko*10N1ePX1_zv`ix*zL$3|TR!M8W;GdC%GMSAEa*j9pr&KO`fM+|Js(dCns2`x0Xb+r;TEKIqOv00^Z=EZNOBMCSM?qlus6>mpgAYfw@ztA&zsI7(iER1qFptX>~h4mM|(A+s|FbmHvJiJr~e zlg!4H7ew||cn?y%->IZWrn2wM6Q|OHY$|>pZKs^al=t;2IcW^h1&FVcv()fY-6Q*y zL4_tumc-~08Rv;KslpuNGU}QqZ9g>Wlz?}BJ;3){ybtiF%N*j)hCF7{58!v7 z9Pk?sYQW!nMik)VPq$M}D);M6s^8*$lbXyp;wQBj5qLk7dgkPldgeVnsaN0(z796c z_zG;A5k`tQZ1U4jA2vOk9g9sn`^P4`ImR<&j3(ZG&22pK>jA#s;(dVsefo)j|NHs< z0>0tofX_Ri0bfL85x~b|(|CPsqkGG;dBhtrn#vcRNadps>60H_RP2}D_Z?jwr=K{% zWIe$Xj;`%`f+st=X7AT?Tts^(J-SZ0W2Sw*h3mI?-@>K#Gq17d^}BG5CttYly{jj+ zdH5+7?v#@n^YtdxZ}GlKUBx)!$w1|~{Z8tMlTYf&cl4y59~L#K|KL!`{0cIVc@i@4 zefsGm16#9V$-qN0&Jz!n1apiI8RLIN2F86o!1r6c5Ad(0oe22%5!d%af9p>U__4&i zghlx#jYY`7e*pNIUjg`;Vfe+--$63y$Z38V!;L=8Tl)w6=6!mMKXLrGfS>U70N-!% zKEM|8hmNiKWOzpW?LbXpYPrM$_f4vral}vRzO(wB zlqeTYGO73fq$kxiG-^@=Q4^=F3yw|>g$77Wn6Tzh-vr_~SXY0O>Ko-BXgGe9A7%DC z%8rwda)LR^>E|BkrlNfz>%zN*qI+g_a0IRgb)cDrQOT?7#9&hfh**$9l1!W zJFHGUgTkHS360S7fo9YugRxAIFj2jTxlr?9bD`$VV=xCjDF{Mak(J9l8f6~u1JkdV zM@5C6$A#uR!;!a!dyK>rT7_Z2|@tAL=dY{7NiTzQJxOBWtHqbao3EvnS|eC$cLuJ>RQG;B(h}fUY1D`X2-Y81 zyBPJ4$i|8ihMEQ&V$wo<2P~C}iJqe?j6!w_#+x-FN2+O!X32;vjXP*s(v#|qAvPA- zfFXFMRkd2IowO)e;*+9)6J@$)PpB!ufUw9TRWjAKA~dzCp|{giJZg-l4&Epthn6>? z*(h`pW=Yo{qANc^pG%sxsQ13O*)3io?(x<*v3D?glbB^r)s8ThETl3^OkzCIK#3^* zt(vDt*F*}9L1bi(VyJiG9IXKkB|L}BPgFbR5Ubb3cGNdM@{3zz>9d6pm}#>?v0I6> z*&W|zOr$F2j0EY$8U(*rrf?<^O@Nghq6Os=cPV&Ppp>9G+X>OK&cjzh;WDu|xH}Gb z5CUUGkFTj)4S!X~bEzMQr)IeA_xM2+%!Bz$JP`~KS^QGz;(F;~JHf-uF3Jeh*l!QS zSAtA;gFqE3c;@M>%DXQfBMXUyZyHpgZu}{+=Lq%7AQ{EoGUR4;2_2hQL|CaKQ zg6DjK%;d7+Sc-C^W}?_9jEM&HlEp!dqoR7rWQ5w9(gLW7MLm%vs@Io+82qzVNpKci z2%iK5Hmt+~lK|+laPrhtqxXXmTCrgD7u&*R@h#Mu%Mg!K(JhREHHnx?g>iGN0A4g6 z<{Q%iSB7GqT461@;I@|Fqe8f&+8Q=0bN0aeScqAw4k;!kWEOU6zuxGAeF$o9H31T^ zu)BLSnu-RyZ)-mghhyeW6H^#ttyDx?#|jA@bE>Ox5{821MLilTe#5Qm&0F;uK^B5Y z;o;_+=Xi5&O|^cpg`S=2=&xC!biqD-)reYFGj@ixD40iB)?!&O%hB*PL)?fqD>z2O zK;A|OY1m**Rv}`EAhXi)N0}I?T%^ZistUaW@~3+|moZ(cFk`YDF^MdiH%YOKbaNb( zf*mU7JEnTl8g7Jg=Ei_`OI*bWA^XZil%KW??AivmaPBXF@E&#G9zOaKKgOn^Oe>2d zBCW8LdiaT1DI^VA%J>~Ey}MPnbnpMErTXo(6fj#V{y();^D-?>HCy^3aEjTTIuqzv zB6O(QK^&re(6Q1jg8u&rn8&?F3$KW2=N`54R0H`+FfWy{RGTf0IcZDapxO^pt@AQQ zQaS!DFDjMej^BR~TCkum$|=*Bf5$1;SPqSrff^XqcGB%(1?B|8 zV>KKFEX;4L9I?Pl#`gOY##RzNwhN=jrl#U!XcB+oxRn}NPebyC>!-IdWt@;ETc}-w$+S(BHlQ2 z#l@yr{<+epQsY`YhSP6wrgoM$>Z{`##2i#SWQ1^gctw~dzTG0?#(rd%z;M}bsZV!l_dwonLLS);H0 zc0zU#4UuedM4z9-gWwFz_9%0@tbT@RJ&u7IkG!YTV7Yo(_vksdJhVDFCaEUV) z-lNX^OyYTH<3Bb0+Z?9uw1!%-ju>`qn8et-s( ztYjP|9NVTR`raVdLzmI^aze7CI%@J>-XMj+dNIkvU|(D238$G3$`VD?QTHnvNFww= z$oovEC_Y|JvZ|&uOr>hD+1O#URu#-so|j*d2UP`s@I2eF24f*frSyB>oi#S^748Y@ z-zvC+l3Jnx5hCjN(js)N}{ zh80KMdwj$AT-z!^We8B@%GgglOlOhA!^B~R36yCT(Pa0WPe2-64ewIqQi@pV>(67& zKe!#txu>xdo1R^39SO6OeXq6CxXqJv@$A%u6hbJMBp*3&WWTd4m{;cNmKK7AX3$Nn zv93$Tlky`uC9g|1x{(OI&-aAYsYl*VC_(&JA(nf&LIz9h#z^vpTxVZg(7Gyw3OJLKfm7gyB<~;-~5DfXJF$oiaFJ%2<|2R(9e4L8Q3WQVvgwQrJx(juHC>l zuu%?iEIwVtsdWZs+tszV=>@rrj)m%e^`RY@Wp7E45vUcv<(35w8GEclTo5$okZukq zn3N;>=io%_5&uMvKH}3V)LpN}@(%FPRAFsLxf96mscsj4&Q-}0O#S*lV&R@E^w%Qa zWhT=-*te8K)i&WKggIa?Wp29~L>ItK{B}~K3LuQ!)hwB_Z(h|WfW42k8azxW|DSb`XjjzxjsTmB3yH3N9ba=s{E4DS}x znjMrRmL)Dwc;`T$QW-LHn;3eL_AwT2P+$B8&-0D)%fC@9#m$D|s<@>nCb=qYAZ=rm zyKbznG1Ezak3exFIWwOyUD*J_H(m8liQGliPS%jPB(O1;R$Gdw+q19FLl8|Y+g zoFJVRZ#OoM<4bU)Z~0c6`wFr;vM=11^TPa!^)CtWa*B77S4Uh4#077=~Izn2e?T$gz>A#&;;;R>>ZB2C4{f>#zO*-xL(+$3GZ>qA}#dlD~G+xHU8gV+2 zC~1$G1*wUNJnU;qHd7%HYCEUJZA)r1iW?;5CqzDRj?Q8_;%>o&B=@lXyD~}}@IT8b z?f`>V^hne5RM}g-z8ypo%V|lH=WuC6p)=d5eWLSehOPlUeyiPcxjWqgbJ~9Z=8Xhv zl_`0u`h`vsA#M7FhdDxX!buFV8)yiA9)GKsQSz%Hi6l4Hv@80iEyHxwy(R<3>6BnM zOQDi%E~s>(QOH7gNTj-5Lempkh$EBqeZkSpD%}M}%X*rxCg1@P{F~u@B2c*%z?fLh({k?dMhh|l41`428V6lJg^bjsXz>TQO@8V0WER#Sg*EJT#n@Hx)$ zxJMADby4S+FKO|t&V=y_&!A7?Oc+=15)-n%J7PKGOEV4#lK{`H2X~8XJ6KG7Qr3>C z2&_)1P`e%hKxDxao&RlRjR3W7ec~#uOSHs)w zYfMV&R!vJlDNM7w-41h71ubg_hreSO$o%e1^WUB->v}V@R6{=1>l!v9%;TrJ25wV~ z2s7f02)oX=j0k_mmjwU{R~MixMuf?x5#c9|7!k^%z-V6o+bAQ#4D~E^Xc7(mL*2Sd zqlv@Yo!YQL*6u?3)t+cA17}h_Fl!w8tF@W_wORhP+5WX-)X!OV|Jp+T+G)O7PE=dR z{A=g>*Sh>`Z}~y7o#Mp3$O7^$)3eg~a7og2|Jsbr)6->7sy3!dc7RfabISm=umbm! zX}h%hNmm{rGbDB%`oos#(=zztUt8l}yGDKbi5{l!nrSd-zH4TNS`wxSZ&rja=nSK& zr6^UbD_V-ijO>~s>8e^1=IYnu{6%y9MKk?HPNS*0a}VB5Cbw1n?TCm3?f8j;FhUg0 zXi1UTqkkL@WliV{NF^K7j9_?~aeAO+rqfv27p^7p?sQ!#DhrTo=h+^0En_fdkMnh= zsnxQ3`b1HpCXKLeaD@NC7$>%*2pAY+I%luGxJDmE?%dGo8EQq4trvoPx7K<0=Rir-eIJtDKR*}MMO0kc+wwKN9|c>*%{s%?zMDj<_2UT8eRP7n@eb&GY7QxER4eVf zX8n5#seU{vU)Mr(A+H`wCBATTRGXu%x3|h$NYYZ#N^R*HW@Uf7gmH;#SL>i4n!{Lv zJ?drrhFS(L1iYe9hQ3Uof@D^~1;5+TRFdVLV9d^x*R#sVJv?h5Gr`FdwtJ)fY0R6Sqynu|GnIO&a-?u51^SB}ZHla}_}t7muD|EZ-lJ7}rSY-!?2 zTM}|{(Fqjh$ml3p|2w~q+Wst(RGA#E5)t9=lqy<;|5QKav%(Z9qE2`qx{KTUsj}gO zD&LB(QrJ(Ghfb*Sjp!;v`>FEm301xr6*c$wo{68kBnu)wjrMBGfDvv+Xi(u_ttAG( z+K#wl0^*8@jYO=xLP&@uuOM%YO?a%MYOK%)Of4*}gpO;VrP6HM40d7PCXGmd5x-@S z2qId7{Vc-}Y3F=MZA5v&LY01Q?mOUA7y<(GZ89$47uThBG%K=iH0 z*EO-iJ(0AP#;09l;&VH#o8O;YJxYoX z_4SOVrMO!&*QNF(;z!r+R{uaPt7rcLm%LQh?J|6x-Ez zI^e^(>pcMeG&k(l|MtEi-?z%4+^|podkf^exnVP;xVfRdS^ixJ36x`n)Ebdn!l6!y-b(Ma-f8IW1{hmSY6#1$X_DTvd>=ge1 z5Eah?#rxzQ?D|&pV(l_jlOPrYk@%{9kV~BIk*zT&qG+W{ieE_$%w3nbT6Bs>F>~E1 zqb-eXOZztTuN9l{5I4z)R!sC$(K|9)E7pJgUPA5k)sNrNk@~1XAXL?0iaQa4bQ51B z2Kv~C(KF~*qvVzFdBE8$BQjhmv-43i)r^)XpruTdxrudzEQ3=m5a}ptApP2v6#X(R zP^Jd}OjWzNgThtMj;T5*`enGP)a)m%70oHxgo}1qDV|O_Gj_SOOQv3W+N1?qLoBdUV@XbIQEmUDi<(^uZiI_^;){lF z|KtD4?f*K_wQ>8;j=TMTe7be}f0Qr%-u@qbi`&0!N^buP|2OLPpRJyw4o$+H|4+Lq za7c4KbP2YTcfqw>lX*-gUawx8OZ?-dGCo&vhEiX5 zW?a?2wqfz6i(+S{8CVh*n;hHf;Wzi=ciY;>TWMV)DcdPTJa{Rl-LcSZu z-OKrX*IziS(L3&j^@TJMe$nt|`8V#9p(gZ))dzVB;a`In}&>4-?&Fi~cF^trwvYjaX*;UTvq;z?CFJ z%N8xPf0KAr`kt=mUp~akg!9*%~AGVYZwg}N3^v>rOM%`Yv5W5j+mTq1pFmd$P(R5b2zaeAR=s99#iQj}urLaOa! zAUq@0YGH;w+`_bQ4AZ9dpl3>XV4Hwn`Kv)Y zXE~?f(_E%F7x$+ zz`h!QZhnGCrk=P(FX02Mao|x|Sf{JH4HZ{HOVTo)Rpf6ID0)&{nTr;Y&%!m9kI;x` zbTc*IG6JG%CiY8iU}Kx$fNMRKBR1d?X{n|xQm8sJut{thoFt)(5H?C&W@wGIf75ne z8oD9>rbfO82l}_k955!h{XNc(EStKi5DcBcKf7BJ>UR_6r;z<6Oga+GIT4vkze3i~ zHd$N?pU<0vSl7_hDN*~M(ld? zh}<=FFS3ulEh#cub$<}r*e4Vs#8k8T-qp+|N{QYwP#3+4qOroc1*!UmDziZT_w)E0 z>ZhuQC5WwZp;<*3lL|E;u8LUX5bGlpdTAmO8&#zc*4&dNU$V+fobr9a0`pf%RsPxD zc4HC2T^)5FK@RdHn~VMWBOgYxxx74BPCryp3#9FL0lYQOLb$Om$X;=~XlYRNbf}%s zcodONE7+*|*)79ug?YQ&iPyv9MYXw{Hn}Fq4tLbmNt2R5MW+Piq_~M%985ebb4si0 zG8qAy^%*^Z)KVs7E0bXJht#d61o*90cAD==Ky^2^PqCf$o=&Hw?UI$3{JHZE$vXJwwk8*$ zI+rM6rS0T;NOl4m^$yU;uWfgH|9#My^tC>rZL!@w-bcKaCN1yL@YpC9EalQja|Q9Kz2tDD;HoP+!pyss$aCTg&TqZqNIb53p4E zdKY?=OZaIGf8Ks(P{U259Uw|vZBuF#dRK`2JVETzc1E?CxKbd$M|#mC6%_2kAcVkg z80_cI>hYdYsm^xGiV_mBOBEmtqeR}Wz}oKo*~y++On|j=x*mawl~t&V^EhgEra`>N zh1aKD@4nnv$o&ZzF*v7@W~_{&oZ13yuj&AD##u%O0C$^D*G@|$H%OcM< z=5=qJG0u}bG{+>~T7YbV7$`(RONftV zu(5OCb%sdWTsH7Es*I!v%NF~ir~o&4x&!6^gywqo%I9O#}?bXQC4G- zLT!6vxtfm_)#zOSU8@kkwC0?qw+Jo20y^3)kzX4(F?dd$wt_vYPp=H5UdzP|H@V(9 z>hU44SLuP|tDV5B+$ii#YIM#~S7B=ovQoQJWp5V7TR`y2_m7Do4&R=a)5?qdaEow# zz#*PVtnK!-P`6F^0^+bWrY!*32P(CZalFy_P6UyT6lx@O)V;_f3*r*RRyz4<9bzd7 z#!h%!(*}0t9Vq7n#=M42`-mlR>ff$qoSG3?7;njenxY0X-e3yX(PW0p^z!HT5FJpw z@XY4EtOYOwg zk16iqM){ZHp-yDFp@xZqa@JK`>r?I!#cfJKb=Xov0)t-L zT?hNt)?AfmV#e9Gyyry5nI_5u+A{O&%2FQ1Rlu(H6EGO+vhmNd_omt>Jq8QmsC%AY zlm1tKy%CcwXGj>faYNT5)hDMkKBvVm=p@D_HiURzoy;CstIrmcw@HJu1(Fmq?q@t1Qg~ zx5-m6(+y*~Jk|0hZ6+s>j9G;Z@0kmA^j>qJ;xSjR=0XaE@k-_sZaZ+ViF2~j4K!fx zB8?7Yt?Ap1x{;AIqVp}3l5N>h_XB~HNyK~mA>uW+lJPT8+N1704s0c_tfr?Lxk&^X z3&8L=@TXa_nET-6av3@|A(%!G>w+D^J6%rz>qP%BPCem!*Q|$BG3MmRq}702lX<}{ zB|=2>u$LZ?xwo^o0`rK1-fNqqDSAd21}xo!yJa^P_xh(~grO9@0^!j~kN4jb1Es$E zvqtKk{bG-sX7dnBG0nVsqZm_n4GQ1B%c-t+Ex~TfFSAA*xwY%@*3*Wrt(S({Ga|J| z^wrioD(1FdLp|%ZUlghFx4a2Y8>U2SnPB2UUSO4}+$ zZ^#9PfS`xC6GlAcS)6`O;L1@R-J|USTssUOa~e!DGIiXz`d`m8y~I!65>m3X%}gMvR=`PXe?! zIl<+~la1-5bL@66L~ztvm7iYZO)eCrW339L7gkiGyLDpTE_14jxrWx3$KfWJW z5ivnzGmNB&`3!cd3}&~0$AO6@m`j(jPr|${*Lb^e2R0aCA%pQFxjPuwW*Jj51IaVM zdSB!5g4WwFH%hf!A_fT}wcNHP!rS}c2dxI!E#J#B=41v+LV@HdG{Dh{bU!#sKBj%| z7@|6JQ|RGW`R5iL*Qk$W*<;_+A_UMep6>>MPk7X3*qt#VTy7@fU2*(haw=k!aSY_N zsj+t)1ED%ZViOuM5rK?WXAP@R$L3oyubt{lk?N4X)D|hr4Q~u(fnrvbZ^AdcqXN~5 zXefzJ@q4Le^j0D)YgO%bArTz}&96d4XHKjtXI4*@f5rrPZU{`P3}+9EQkCQ6dD%CG z&)!ByVoUcdpGIkioNG_;RZVL)y}CFAEU(tWeWFX)wo-HnX~bhncdgGsr+3Eh(VdWq zsY4Wd?dN(AolAOdGboVGf~D>o%E-`{wsUtH38Uo7MtkR4Dst;?d4*In5&=kb^ZiAv z!JWjYZ4U=rx|o(OKx7yfZRrq3Jpbgj#hd78OIu`=)jK1a$IMe`9y<{J0_lhbb%Km? zI7gvgDm184`RnQ#{~HbJIWiBTMsb@D2QX@sd2D4_EDdVbDdv$GH;qD3;ku5n}CTmF5lzQoUL;OZKJk6zfzCfB^lebWtE3jXz@uIp=+Jj@|+wr zuEcf}xZjrBMcDjGma0d#V@q*Q0&kJDa0)Z}hX5h|J6+<`rqt)u@z?gMPu>DStCNvO z1j{PK49Og`@**;kOd0A+0mrG&*ytpYuHU4->Z<9-|p2)PRoa>8MjgzA;_%VynCWgrNOTu8y-E_0<>nzPN0+({MM_!ikXOiY+uz|wN{m$5}P;kh>IkqpX6 zs_ZxM(|L^T8F^olJV_61@Bj&x2qabu)s$gN5?FJ0i#c1bZ0{a5nmKl^qh!q3BRNnY zv?S+%#QI*>WXCHKki-8UYi9!Ae4aUT=FIsT$`lE_!C&|fE8fjX**>x{K0e2JRLbxmv%ood2;2-i^UPfb&W;56LUdQxKc zi#i@QGBg)!K$$enkTA+gjz;fHu1j0ZDgNOXPA7W`d{6W4{U)iRh_5pxX;Qh;8HU4CWJzPBlf+D zEcfs+wNMH%Kv5+z`12u}ab=?H!AN?zjYX`mf5k#l6D2#;7ma#;YGeLzB-Pxe;%v-! zvHEyQHu6(Ib?!Ift|5$TPZOtamIVn+-VSwsw7J4y4spRvoWr}d%I0j52eAj7-284a z8|S`1v^qoP!j&*y`$zD`h~E{t zo~1+|gZCpAIy*unBIzUcvw@G=A42f zD)YQ3DHnVC0cDX(4pUPUd&F#n;rY+w!5J9Bq7rnJ47iUGykYm!zUC%eR9#|TjpYXM zU!BG%WNjL~)UVR)HsT=aU)DZ^A&SU;-8_LBhfLztJR{G6GvnEk)wbghflCCiQQPfg zqV|=PS_{)KQGhNCm%$b}ttlzyQdjOLT!fc!)Y+9_d-M~LCHJkWbIb&sXOB7({H{qn z|?NWl$jR%$eQ_+<@21P)BktPakmm64O~f zT=LVc2HJUn%A+zNau2M(h)GyUK^-sz)*-W@p$#R!bFa*7KKc)M9x;xm(LASdHDj?# z6LOa(FH16tlFfl7!Q_t00T^ zKEw(r=o**D$a2bERkvZ}&a|9uj!(&%-t6?J5R)W0W{tx?N^DQM!&wreWYikX?)lTq z{$P5~GSfT~-{H`TlY=AHAol3a%Pn^;`xS$oV0|x*(d&6A>ngRTq^dd0EJ@P)$l_!h zUvMAkT_r1*9VQzY0#K6y+PWJq{`}Y~PvbgesZU?Fakk+8dK+P{5c2f8SD)y@=h56gR*f4&QkZek|26jw*dXhN#-nWAogFE zyVO;A8TT-o$#v`$tmiXL?w9Wk54mA94@lHG%vnxUw68JmD0uPo502Lr_{ZQOw=t4_$pP4`%y-1)} zTfO6JBWfFM2+%XH?2MtKRhhYqlPfRnHM{3v90|0C<}Pqmo@S2vZFCCFUEzVz$LKwk z_Qobe-aHee&ZVD4aGIx6cob0)OlN|=dNq8ZL~}9I&dNQ=4)LeZ{y=AV2zgRWr`vFz zCF+n_HhDTtMnF8L8Uf}eh9zcc%F2_lC~zflJaMl&z|g@JxAiIyg1>^9dTTx_x60*S z`9CBJ+PbU77o0dq*JLx9$cR-Hz}FdFjs4fK{e=_FV=@^=mCL9~HuHv?Q&JJ+8Vggo zlx$&gPE~T?boJ~xni9dC3CRu*RX@=Q6^Y)+A{JJSG%oil-(gO5870(`EVL#OTJumT z{+YWO33!TkQNF7rw%VW$=2QXnV0v8HU(8yaFG!#WycPwKnk^F~fJHG9v=Ob-Y>-tc9`flQiUWPJ zF`lb|Q!($*&h+W{$y4CV0}{y!YV0p{sIRfpYa_?F3*zP2Z?H>^C{Y&&>|LtYrl?I9 zb@zi~x8S4f;4<+c^3eV_Hg2tIgcNbgU{I6vpf=Ytp|O)6>wgl4dlKvb)1+=4PU*Tc zpgvi?P0X#@bX3n9C$0+mB^*ScIVvsSVj$`q2{b5tiRpDRedp7HaLJnw(*_ncamhG1 zs>7p3iI`qTVg%p}eB1Z^!5+s8(q;9yD4vAlEh`d>;H|JaIdhWz`Mt6%ie>q_&hj`} zKmw~gLsXyIf^J+-tEf{3nMnkn5*7@bY$%!L6#kB>pl#YSyT^gb-fzrydO-(KI?U`NXkVcBho-%@%>Wy-m6s75 z?GQBzUb&Irx15fdf|#!=3+U10EzmI=q+?60JPuX`nDsWP?HEnQ*4*fiSaX>86cNu& zjwN;{eylWST*lyh|g_C!DTtVh4TW;?E;7D#{}L@Y1rWiM-|F6no|QXlaW#=96DRWOF>mEII3)lL5 zr)oiR_iZ7*CV+=cYUb=%x90OIU3RKUCHI$CDxhB8Q}1tkfg{(q^;Dpi+`^k^faeIx&U3iOiPeH-~A)ZN&(?wuZc z0Hb|}Pc;C^{e^YAWG$z&okZbN*SGrHqt%c1O+HoEC3oNI#fMX-E2_wh&rhG_x4Ca4 zj%Xt{_)<^Rh~)0u2u^<~(ul36(%aXYeHZwqzAZd8(T37^U-zk?B)R*x@Rf$KHr_}d zDw6A4f2u|#ci%=%UN(K8Ve^H{R5#{e?$9ZZ9C;#HrD}NX8IFnpB&_&rgiPKd zt13aQiDgeAyR{%8njcdF&*9A1@wQx2sNUTob~&Syj>EY2ZS1yK>HVWWxAZzn_h~li zxVk7-?kAKp%MSN$Shu>gP<=aAF6lT1bS@N+9f)6oJ16SVeM1VyMrXQWg+@`xa$Yaa zg16-1CW(jWxHwPy?Vm{8pmi(bxYEoN#CPCpeIrhVijuqUjP%)VAO<_uZH?FHV^PLy zyvmn+syUY2eQOjZWe%LQ7OJlE$7?$QmuH`?`i) zn}YQ(;?r7Oq`q|>tE3A@x}#O6=N_*-1I-mClkVT@7?0MZgxDcin$l7> z!i^IqK3Y@CSUI*Y9B4ZKSWktv!i1b9*}Gr*D_<<<&0+jn-BV&1HgUF$&l!N(fIhf0t@^(>kQD}t+@IwMNY@QY0z#e5_Na{7LpQu>5}H}#|Eni zkas;|Fy(<@qj;EU-R#V5Sd8ynvbv26e1r3o9bq?th81yANt*)An>kZRNZAf`ozp(9 zOZVy3FcGg07V-Le0;G!GMhiTSCiTg6aVh5wzmWFlx~hpP&6_A+g8xbg9N}3sFrtvt z;>i^q656|G)5AiJWDNGTcAIHj zWjG-aj_k^=5}&MJ!j2#iVBb{V|A8%A3Jg%sqhJfqF7>S;1H+BW6~0~}E;!Qlidx&% z-=k6m?=jna9X7z01qiw@C59#i%@@ zO-pV8xx`8uA#Xs8e-2X`1ir8$u~*H3jmVji_ekWQsnRjr2arj3=j2I zBG~56^&|(bsu%=Z1q62ezG`Me+EBgP&<&hxi#ljedj4qdcKXCWB65YqKXR3N3rmaw z9Htd>i!NNR??IWnbgciz@O|R0MYAVEeh$K^KA;~P@3g3}Q~Xy7=*tB3Wu53>j52gD zHs}d!1LzOOLGMpAkM{-s&t{q2C}=}}-y=5kffc}pIHl5cL@+~4M`nU_bDYRY)i{T} zYBi-k2X0enWh6_8=bazoM>Ny@9I_NLo)yjLJMW_eOqW|3ko)Pv0cIm4 zHr&tLAzpEv4S!2SK>muF_H{T@LLC>olJ*(}$(fbif&Jm@DVY5w1uy>?tMd~IYE2Wq z0FxreZ5gBxn-q9z9NGO6&i+nBG3I!?cUO`&T^hMR_al0@tEYF^{?_Gi&qQT6*)s#( zfp@~0WWMb4GC##N1HCfGdeLy)?uCf=JB5~rR6i==XWESM!zEU(OT=4Ih)T|VUpZ&} zSI*h?D*rnmVIYNthLDs=rjd%tNWQO3cJCHg>ARa|SxBRbmmSHr|4{@2bu6_#}@4&j+^f zCVG_zBu)hr`jmK87*EyfzanEco@(N+y4vm~s|U@>7vEAP^QP`PTX6J9>;}~yD}paA zE|aOu|GK!$u=>S+U0kMJ4f%rN$C;#PnAJj7a+K&I^Y3*9nM|4Wl1u^ScNd85BKqa^ za|c2vI-$Lqkavo;^>s``&Qnj2F>o;QoB$eSeG<=!duG`i$0t$qU)6dhyW22`tT zjzh6vT!d&31uhAxRWG~oZJA&qhW9(Ll0w*E0TqNhs#Z$_jS!Pib| zs3_jhwO`T@*sqR!dSXbNp;A8Cw}<6ZqCPC?W!6-x&e{MEyhJwAuZczY=58_}D~#U{ zr#YpeCN`+%_eS>qFsFRG_N0W3H5=fPFks9(x?JcrI?rG8Q>tEEAFbP6Ei}Zue>P02 z=u%h7o7kU=STf!e>QNS)A2T%Zdq3js`>h)bWgRir&d)aXrhPruSQDKK%bL$KWMRjP zNfv^{5Ze{CeOv`BN}-FJgOy#5z;3gWBkvJMVC9^09fJTfiOG+!$(;i;W*$7M<3=!= z;hbUEGo|NZ*oBjp>So&%eUCV7VHY$*-6_isFRUe0S0q-d3w*-2#ydlFdP1ReN;ol9 zvRn8Z#j``G?7sYNwnXZf$;?TGDF3o0i(MV@!#OaCd(?w8YGHtQKfmSx@zv>V?X6W{ z))XgfC&aDOT`hL1>N5HTWxIqFzNuGeLSN*A&E$obu-SXmY8*IGRIL5D0nU%pGDvG743<*axxeh zY(Di!=%7DP1nESFdU1{LsvyHKGl_v0noFj~t9mu^mX>^Q?M1FRZJwVStip++IF_Rr zM!lu;!jsk2gRo%HBR0F#n<&L&W4>}k?=eq0K*N!EE4|Q5t{K1;66d391lTwpa>?#x z@<=RHT$9pxjH(q??JCV7`9xu+{sa(Y2Y_1M4l2dAVtj5--ikjq1H+jug0g4tCkP3E z#{VFI#hF%=p*|FWJ!gOc>aHhnqQgKpeJ*2^=zJHO1?hajh_wU5lh@Uy1I%k4NH?obzLg6FAu z47rS>sSe6+O`Cyuc{$=I=H`wfUKIiG99+9lq=-YWK|U>A-E@YHuWwBdeC-gNCmd6! zHO;BkP*xWBbiva2;sAA{-xpC7XvdaDtu!w>T^3W{{L#gfs0KprdzA=MLU$~=E54Zi z2L0of5ZcG8ljIlWCM&b6NL_G|U_%k`8@vBA_|r}`k>bp&dT*t+|Ki4uHw07zEg=YI zUW%N=f=h{o<5BKvafP>*I%R2gjE~a;)y6XblVLNZ9WYly3Dn!LFHDX2H$o)*V@qf@ zm)_W@*`U=DbJM(>y*2N6K4b$Fai-X z=;JTuKK*s8XUX9m1`m>uTw*;eJfK=NeIN?0a%4xgcn8$&6^7;1h^y}r5cI@kZo?sv z)3L+CqVy_&?&SWKnxmr1T zy}hP!`5&ws;&y65|Gqfg`@U2iusq8BEoBnSNhw%$1izb{U@T4v3;^B%c%Zl#D+U?i z5!IAa=6~i?`S+?H|C^2Nq{{yk&s>pFH{u7NO@CAFPisMJB6|hv$SB(ry#0U!8`Rle zbIB2P8^+^0ieW#Ia5^*lBSytlXc{Iu*tmuFeinJD1rrl^Ulymss%#VgVoZTHV5<+g z7U zg3KjUxBYslt~s*!NGWeyczfvxEtaVNiD!9QvIMw*jL={u>Ji?oX`Si?`XNj5x6+>- zYM!B~tY9==P{c7-=l_dYs3Zb{G2j?nJEz1Ha}m;T|ApqLABBgT`N_Eh0;gFXLaC?? z#HR%3-R2@hqWFW>+ujApx{mg$@diXFU$w@?pI@W7q7KN(;xkvs$u_7`ylVT7&w9eV z$V!9RxL1(mS2fU2x4-WmfR@gd)xWUk_a}a@>Lu_j1JK-Y$vanEFr$&$RhhZl{ZEnX+22}`~ zyX`aC26r>mlkyItC*&P$PId~_5JSXM=KISDbw2e4bv|e39sH24v!+*_B2WEToLlsD zii?L^lTy9vZd6@n>2O>&%vT!TbHZIFHHDL9PvOR`X({YT!S@sH{g+vu!cxB0Tt6?rhDd1t_YU8JYcXkSh)N7Io&J;jxvHwD)oK);C{*u{Ns}Upaa*$ zJ20Y6)Mj(qsLO~&|;q+EPZ z10EB$xs8jiA`86gNG(9stgO>380c#!zfVaa7!g_Rnzdb7$|b}U()&UJ6TlXcUBBYE zWOP4PAFS^W1t6rV`d`}QxZFziM{Yj^EkfH;_$^Nqzddfi9%KAYh)FZrVnDC8$ z_E&SSjzeG$x=UB>%w8Ol^0I8L?8Hqqw<;lImT z$m!v*`ZXIYKxf1QWW-O)s}7&)0={zi)=++&!vc{eBz(aA93alHri>|34~L=3l`Z|< zk8ZC?5w_|3G!r`&ERttV1vC@*u^O`6J`ofm7}gAjSSFbRlIo2Mv{`x=p>5>?au!zP zYCJ_gur04;SGq+?EK^YK@~%0ga=FXlKyYB zW5e!_Zppqe9DC|^2q#LRF2wx{Hh z^VAL0qsul&%My58D%G8$4k;0!i{0nRs?mH;N&fOV5oo&Ub>vz=Ql94feImjxq~ z34hoa5*X4qqMS(gqR@!e!7Zf2lJz9Is|x`JY?+%Rr;xDYh90J=C&Q=}$cnrNcuGh6 zz|*p1G9p>(y${G_>45;pb4C%hr@sv?Y8EeRsoBo0Iv!v)b??-(m7pDhNo+rC@$=Xs z^WB^(*P<)TF>4TJ5P1b(6gh)6X0t->N6r@brwG`a@^a_6?s?m6$R^VMw9W7}MwN4x zIW-lZBBLrr&AI^fPZjad`qVxqTKna(+RrrIQh7zZ@_+SIe#ox;!{3}#`SJ5lRe4Ud z@=Ift4~2voe+MqQ+aLDS{El7onv-i@AFnwkU3hkxa9@NSipydiWlDvtKL%BbZVO0I zTq1BuBw`pc1o)TfLM#`O!=}&(8_Jz>;u=?kpv<$M*v!mg!SG$LG8l(T?8y@AZidXI%IT>P=cE~eB< zdqf`rEsfSWt$b%5 zf=iqZBea$m?(J|`A?XN`6mzU_u7ONbe?oeHy0AXF#n@3VBCT$d{y5r+Q>Q@|CarI- zgObumgCRoqUPvAt(P$V5dqnDik@Vl%NX4*9K-i)Dk`j^>MuZ=_9#L#OavYc^LL!~P ztd-G<+{0bH4KX=m(!ebwaM&1|8~+)}R_H~tAzCR>XR%n8Z22ZtzL3j3xfw z*ef_)F<3{Q5u-lUKt2wywbHTASxIKI@g#UoTqk$+J;H`q>~InFOeTD$UY!icsah=T z=yLTM{aWU(VB7Iv*Ks^6r_IoTLSib98PE@Jw1SU+{aK{_`+|(qX7?yXX2&37w{n0? ztS$BSGq(KEKQ_9ot_60F(hq7AXsNuP>u2d2{pqKENi z{chS2-?b1u;#gm~(D!nE)F(*xALhp&}dhm1dLB{lS z`>}*m`#&d_&ap%Ssq}(`HN~&K`>u>rK&JIyzXGVhXMq)xB&J{uKcHZI{@yY}0>ntI zd;n4d7;7(`n593yWm@uCCZ+NUS#1JGdHb$@ld9$I8@#o@AdBbR&*?U}+y@9BJ@8e4 z@Y?6(Ispi#CV$}@N@R8B0*AQ%LvHkmsw2^V)Y&kZZm;e>I3r|KQvn&y4=(Sa%MZx2 zO?ccP&C|ZF+K|HmhqcuD&fJp?i z%|=;^QPzf=ECO1%eAik`OffmPt6y9ODTAY1C%^j44Lw7B6g~a@R89jZv4}HS$pxJyrRrQE z_3TEgsfxXfidBe5Iq-2t3_L446i%3dW}7n?F6ZW>-Z* zX_5NHTf$6Olbomx$Dk&%*<|7+cI4+ScHOfle5cxk-jIF$o7qQw^>>eV_*V00GJ&e( zTENZ<1Q~gEpAJ3(2~L7kQ({+%R;)<1zs>fG1oCxJ8fQYF^$z6e)HQ*_l)k%y5qT6l z)>@U!P~kCSgB``I1Vcb2hl!7wZx41R0SeUGGZ<_nhhPZR&&e2ehn414 zllY?NUe*^joLyYLCGVX)cgRItKm=W3hmt!RqR`N#Sqxrvj}NX9Fo8SqZ(cQL~bSV}&J9I{&+T<}lWG3Cxrw@DTGCT>=^_WC>`jkR_n8f+di)8Hw#hfVd)| zs8mg|JDlgF!#DgHteE8@rb>JP2v$6c1(?Q)Q!D@to(XsMSpY}gvSIKMh!#E|SkduN z*+-m1tBK>?3oB~Gwm`sp=N&dyl-XF(-ySdLD$%2@%_8 zThSoOld|?y`&CRt^(7!t&9#27mmEwe*`=E_ALu8-DLi76)s@oGXl!X2AQtj$4De4gPcz3Ku~G{$-XNGT zN0{7w3ul(zs{GZoA`yj!iaE#UdO8+PK%e_u5N2*@Qn4ZclXY`KQWFwpB=?vXT0cR& ze4W`p*L$RLxVrINcJIMnv%iio?DDE>nC9?V!NKtA>LU5bRf}j_yvlPSFQ}KUVV%%% zU#Vlja^)R?35x!QCaiV|1G$;caZ3;XLIU(d@fP$*d9c5TreSB%*(aTx`bdf7;SZ1? zHYnj(9u?-^w&+*_J$_jmRCJcAy$-WxLSQeVI?k$0CEw9>= zm>XCKEIc*2vH$R6FjMQ&^_a4E6QBt7eNI6#-YZPqJyN&Xgd7CT8e!a|fn92}RH}76 z+VV3QQBSmkUuW_A>u~K3n|Nd+^fSswr7c3D#+LlY-;ZgQ~SKZWU#I4J&R}S_?Fs7~xLBI|m z@NMb;MY374BX&rntF!5&^fzkxCgwp=V}QOG0#lx<*`NElN}`uE>0=qACz;djloS!y z(gumpVIK8*MP_Qi#49QE@f`lATN@YJ|N>(^YE+EcJXNGd7WCcc3VPRn*7Jw(0 zPA~|XF^nLq>XV;x%J^2AG=^S$ruf5|Q?im8j^+&~)5t)g*lz$v}P#(~YF+Pc@) zY@t(1DU6$VoqSu7#5oy3WV56B!xIAo)nl-0!TBR3I?Q~|d&n_GEcqv{U+!hn(kq@F z_)N(JRHRcgtnmrC`6Cy(GpCLmPgE6^$eEaAmi|KnYY5F4$%e<&g;QO^ z5*16dSUp*~oCwuXkqq{(>?&QEv!^n- zI!fIcugn}6t;!j%YGAY~>x8PVF-tP62`+nlB_o5|UAJoIV3HZ1Imo=#X}AopQ}@gj zukH_^v}1LWFfNV*%zw0^OQIFoQd&+i^DxnD<%>t@vTO?zcoo`^W| zaKdRE0CmA$3Y2}w6B!d(I1oQ3F5@Q9#V~zp~`{5oKem45`YQ9n%BF}r)U~4Qbe48XO3toI0;qJyl>+g3z za4$b{8dl8&+!73tyGulS=6aD@9i{$M2})H(NuTtK=jWti8590du2S_aUc(cL)GSHf zy8TkhFL_T0*5DA~owN-MYClW4I{);CdC!7guSrq^(p(EN; zJlK&!gdx1ngj%_)(}hSEWxyX0Msn#$b3o>HTmq92Eq4c(y0AsVct{&xFU-n))BV6} zi~(6{y4M_VYvwK(`S4m8`Gr~feuVC%UBg3NFPdbpT#ng#7JizG2|r zg@aWWG!{0dOSXp5aXb-*g4nTSX-e>PW$u%$ycqV=KahxE{c;PA+|y(hWm(Qa5ZLe} zjc`jx9BZyfc>GrLdapTkWK{C;dZc6|4Fq>&v9aKsMl(g+p``Z$F%HoJFllV4S=MF9 zz>k#A$(fSAus^fr3SVI6jm+FWi^-Swq_A6546?UXrrE?J0hQ_=9XnCrXHLoRkEBR$ zgS*-SG_;)AWH!(%^Lp;Y>Dwzhei!#L7iHzJkz9~F$Uj@M4=RjYBcK@58x-Li_Vu}UoxFa_-N&g^xn#bWL}TB>ZI?9<#X7DbQ~q^`!}IP%?=2LV94#c zn3#5p(!yup=5h3$m}_=AG1N8js7Hg)dmt+jdc~{X3fvtvG6kY^Bls_9&h!ks{vf@u0Sdt zco&nfYvQ$Ag;8Z8>76weT&!(|?Hj5-DTjfQmDQ21n-*+7EY{%n2`#}?vQ$^AGPXmAHV1p?!Rx-%tVX-3lPna2e40!Q4{BPhkC z8oQ1yOwas~9sW%t&<4W}r(hI!!8a6ZM21&56&kaGh=Q54FSAo4GG{xxXm3B*;@AgoFZ3XUQQ8eFIErXN^?J01XbVxf62X6V8YvYI+=GdjXt^A zVs6x-#RN}hW|L9eK{>s8cC&hlW%cA`Sz}U+r6a>vQiWb0n9>&uow+z>bvC&@Y(JpmN{n}!r@~G z(4@Esiy0)O_MzP}B=TNVTIH_Z&kKtQcM^PO8EPl4 zpa5PRRfP~15=UiWhI;R(UCmdzvFOgK1MGj#%Y_JkadYvCX{qKpRQ zVT?_)_~o6=<2yX*g->?o79_e*-@kRP`!}8x%+ClcyBfBg5Ci5Q*sMg^Wz^d{APjH? zrxWnFP#qw{Omi>T{=u9bzCBoMtEXO$-dP8~EuQt0#U^(+`(6c7nj&DWu7pjIB*GgN zbX)o0kH`bh(y3{bA~k6T4&)q*6Qhabb6zheniM1(|6pg=!yhgOdHP2(2OV=la^?i5 z*PP(WBu?l(&d4z^_v&gf=&8H17tsc<>xlzdv%g~f z$a;zY{i;eLKl=wIKjh}K7X`;GE)gr+r$(oW0Kds7Yf@M0$9kizUR|Ug>x{BGb(VhI zY?N(Q$vmn@ZsS0i?ofBu$M)gg5g}yte4t}hb~Ash0KICGleP5I362kig}TH_!7MvC!s0^NXj5esK`9u;HQJzfq~;tWdjg+qO69UOgzEW3Q41@Y!!u&tAag|kZ$AsLs zmbEk4bdONerPv8gmflHBR|&X2SLW^+DQ^cTnX`QCK3&*L!TtsYnN8}GKY9z42peBkt!^SX%M z`EDC8_w_%h%67CiAN;3|B6IMc(VRzj_Pa0fVB0|@#iUUG*0)WjdTbf#~T+=1tbz1wa<+pji-G$Ry z4;|e7&R-5TP~~nuzTMjV`JFjvmpP~PAf4GAZDsd6ue{UV(rC*e%tt!uGjM$?_WPXfM}6RrHGyJ z;494(*(^ogZyBPZMVt8z_e_MA9OAbZVAI>={Zvf!iIs#4UH9%CUUiP!cHEPI4K2ta zV{sh_>OhPKg1gw!9iozD$<^_da&_xmUlt}J#!|89QFGw{D3Uj}yvF`bl#fdIc7Fr& zXAGp+yP%}II3A~pH1+SY>)lZjm8QbrKYaB-9e~~3+t`0C#Z}#Pa?V?Va7Vew$7n~M z#%Qzap$NgL>5<^n5s}9J2c)O?v*)|)yCk?}g5bFGjr=qtKf}l$Y2;_A^(ly}n$#^+ zD0fQG`fWd^^>!AimgQPgCpPv^2JY(O?a)c$Ijn)BGODH`YMJrUa>@Bpwf4hy(H5r=Yc~>UpXdqzc*R ztW~0*5yW5B+j%oVFbfyVnRv7#SMsbk(?#6^Pz^YdgcdAN!_yT=4+KnMF zvK#J+SNC(263hTU`fK#iN)W`9UmOrauw4zgLMUn6UGzT)h#|{B?Y;cJEiUUr9VuYc zC$-Knt$aet3l77X=(|7m&S`)7D$x60C!rt&WBtjh`vQbO_U@sQKy0(AeJ4rnKPq#` zwg&(fgQQVc+*1d|u;xVZ7U|U>JIuG7=d70m?_gHA=}AI=i(h;2B~kV9vQA#AG8};s z)&nbf_NoWBFsl!&*3V1zvlw!E)pzAtqo*wE#socP2V=GoIO?=zQxp}5;mVbo2Gb0kR6zp1}-LuPqTGuX6GBs!E2B=mkYBZBwV!v32WzjR_;cp!Q!}5rfJX zp#{vYcwYI_A$*0AEH!7|8TK|j^EjB-3r}pf=N2&EZUumw3Ar8@y!v>jM0JuAUlPiP zs1EU@ARJdTan?Fj5RUFw_|Q8DM~6qS>iX&m;|7FKd&=$2Km$L&_ zygcmxCcJ}QDeEsiu_1rFp_2cjhBSVyz4^p|6@%jq{Uh~@N5sm518nTSRTk$(vra$Z z`hnvxuJ$E4>!TILj+hiwY_TVR@(177pu~2|e~SD#Q`q?jRgB_7gImNT4e}M;X{APd zMC=^r>brVe*l9|Q$-d!8bxPC)Cs*3oUvOP*yDSQWK^1rnHcjbOwJuxt8`-_er?Go| zY;5zhZ&;yJ{$he9F^u>bAwP1o9^0JYutI5eYO?(^-Ts)Y()rjLlGm0EQlcV#PV19n zcxcrnS~f_ftxt~BDN?v)gVf*p}smCpC<-kbh z(Nx2Gc$9=@^Mpfieq?Zy`?>z44Q?t_WpBw4K0l;GNfpJ|FGsi347P?zGN8g?ct%4GyG<(HYbSsvwso#q3Y9rU}K|7;iR-`di8C_J>a_28@aw|@6ITU)}3aKf68Zh2CmZs&E9(?y4L zcY+9MM}nHUBkQN>%>_T1rR004DR;DusPC>3d z(;7oenOp05;Y^ID1uaX|p=VKdT}q;`C?#r7^wq|w?QEe@Jb#`?_4k|Lp1GoFS>4A% zFt55<*nMQLcAg4uNPR;6?{oG-u?kimd-vS>i}9@WtXFBIviVmyYSoB4B1P7R*TqS@aZtX%J?NT2Dy713Sx ze)n%0C(JhrwrB4yENt{_$&j&eskdjX7jeiIqp}XNy?VaEr77H`Qh@LbEfm7DW}{#& zw+jJb*1(y;y^;1!lq3RabbZRILk74}4WNsWz$PkD8~-SBrS;UmHgJ`y`lUEKw{gTe z3=Q6l-wwti{p6hEPr@a_mJkM3b74C|LeujE0~sovq(7TWk<~E#j&zoWXDwfJ329?u zvYX(GDElk(+45IW@xp3-Y3sd+V3y2EUBrmVmJqs7(jkVO|cyA z>JV?xR(SVbyMzB8yK2+2E8QbiTT*rSa-&w>IH*j8u%A#Y*9^%=Q)f-m{gQ3P&LyaA z&m*XRDe|`=(2AZ4g0IGavjgCmJK7%tlvv|apDO+xe|272qH%!fZ%@1^-vk*Vwd>`t z-s6nWW}apHldERA3rT~-f0^D~WHZqX*UFG0dO(t97nco2+#>!6WcmzIY7+xMU5AJ( z`_>|}K#~BUcUAZ%^hyyDdD75hv*8~QJx7`v(b0G6UN=rk6Rc8KPXQpBik7IK{;UuE zTxq`sw{4*<^yJa~)GT*S319OSdJqMm9iv$$LWB0}fW7?=Y9u_2`sPHvq&Z;06GIXf zxl~aOn8d|;Uamcp)0)#r2q)PxoH+k1cR5P9lutTp4lX#uigHEW`85WBH+Mj zI`cZ$%X5Y5o(2py0;S+3lHge9JTX}k9PI!E{oB|!NCyYxbBX8H=ORJ0^1(~wBO$JL z#I7TP?1&p!iKThm5>-O>cUryjc&|lifI9-F-HT@?jD1sHU+@!ow}{ zI76ojPnvE_ zn_-mCHp=G;PibFN#NFyJd`MM*vq-|#Ia9eA7FvyH3t! zZR^#F>2<4xYG0ivR6F~qRj`RmLA%xczX1>hJB86x^}mLO^j^67-wB$L1*6+YYEqa>-(Pnx@4;Akd_C!uXoaYTYw%a)2bzf`Z&yEwDw$ZUQG9 z(RVT8BoqCc1O%dxy~UMaVz-l}l4UHwaC@y+WqzF{ie^%~OpDgk^6(w+X|)JjXR?S* zLEs!vcNbJF30r!pOiiE%>LEYEum$OnVJ+-Ckg4kkGwplm24?u*kIBdnL`SAx!DtIW zsIxRcHmNQAV%Iozyq5EE*}Yxf9WP%?`S2w&`i+cU-++3+&NC#Q=MnM{K> zD~mSvOCZins7W-23B@B77-0Bnq<5v1th;mx#+9s3Z6Sohn=M<+knk!o=41dvvvh`$ zKiw#qVNRN7PV*W0^NguJoAwx5goIH(B3C>qj5#Ajk~hg!4$j$E)cFno(YpPD6u%w^ zQs7B1Ts;a-5kmRpZnQJmX@f5bZi%JNUKQ$=EjyiD?8xP%k>ATFdmqYebcg;7QH#`O z@L4UmRg7!9EK5#Pratu=+q^s*wvl}Crjt%Vl2fg%1rR~0R?sOxg%IEwe2HxWvPa9O z+xS$0Gmo4FB%J!W*ndEUDu&OPpA))<#Cz_wKgtQXS3g;Hb1McB+TN;c`si7^XQK6L zGDFgFw4(FPkgx{xai8T;swynxWxo~j@hr^X&PLBpVGpBS6E@J2Z#Ekk9t!Vwm%K(h zuFqXWbaz+FMr~Q6`J|>l3l-KGWa-5>K>h8f(0uBUQ*&(Cx9~{U^Lp)68Y;B{Q@c6Y zz3d{g-$iPrNGwG*DML?WSRCs$_ipzigNcaL3RGj=mAu-^LC>8UKn62!x;aIo+SD0l z-aKKT;l=xi**#5 z05cC2fvYtrB((J@`D^CQHmA%r@@E@U=bA6>B!xZUPAk~Olc5Cz;Ib{%G;j1qk?I<( zh)heyV$W63o)zFC)1fk%GhleG{c6ik)gOp=K~PUUw?+b?0)B4V%izT}nhK|&_%?5} z#j0w57n6W4Ta3>y8LR06i!<0UU38z&cK5249HPYpk;z_lKhJ6sS76J_%^0b5^ z_x5k;*M%UdwQN(XXVW1JHVTFluBXCv8!0XD!J?q>*7T8sCz_H&40vTO@gHNOD>-))nrBE^bVw1e*fkC|-I_no%9^0=e*pdBYR z9H3Q4YqPl{bm-nej~}Z{HMbvY4!d*9QkSLZS5Io@_Q|_Ek%aJ|hYCKUPu08q=Mr(O zplea8S$rfX(YEFrAKadjThMjSzs%xJq{tO1brt8(L>4xWW&LYF8{?wWc1?bvJ}Q z9zFDwN(*sP3KHE6pA26HqCa&ScXNtfJ#ZF|g5iNB=5^{yF8t-{m%vBue_*C7GG=jG zWr=#~R**n0CFI^~bbNC2r*XbnmW-}187l*04o1%Trx{aIf?clrhxz2%87n_S$o4!+ zQY<_<_;FGok3<&e#lgzq_{{iIP+nrqgZ!2pTn~JX6v(y8Pd*|@NTi^yZA@_6^}{%y4T=n%3RKE1$vJ-8#0%Uf~%W79qANlWlM zcTGAkAzol?Pl0j0)D%%mBCVl-1OVQ%ACH4~MaOgo7`K4z1lTY*v3Tjog(b*}c8D~d zR6MGWQ-!EW#IZ&lE@fbPB65k_jK?Id%P$;weZm(u8Twnp$1eACyA4Y|UE%=7n3=c=bDZaDnWlqbc4h<8nTlZYr?V#RBt&XXqYxkrf*7(R+VgK9@ ziYXokjfvKMF7qSqE^R>aYTfUwsjmG{vhwQU`2(J7R@QdP&l9yD@sm$2xgXr~nyCk6 z>KU*?lEF)q!Piyfn)tvql(EKdQ5A>YRdP;GYplpUsDNJ ziPephUFJIVi+GvSaL)?ALMPq7(NTR&YqRu1Pjj$-K!Zv$bj%#~N*lj&%2TRtGUdnz~%lq|_v9Bh}>DMeN#g%Tt!cpr?`63TZe*2nw+Z7MW%HT_evG zu3*2kL-u$hi&GEkc%6>cN7(|Q|r%@sWJL^ zy?zw1s`ueiZ7THhU&WVkdlMuuwhl20{Qzg!Z#p6(0SwkBdd>Xl@`IJowQ~5hO}m0s zu5@I9nkB(vA7#v^KhpAMZ{%7zi`wQ(6vd{|r8zE4Jnb)wW<(ZE@2O2Vt(?ka|Ly7p zUBif2K5YOMtKk91KOJ9OLyG@mbBJ`1Zu@pQY8<7dh2y02A ziuRV^?JbC6o3%09qy#xqdaZm+Iq6=snr3zE7nt-pG0M}1cZY40KHSlzwP;y&?LR(^ z}k`3+jG~lN6a!M8g*idMY}E?%7B;VH`-&!-Ejzq41LNveXPO*OU=#J!Vb8! zQme`d4=fke2k%ZxAdc@|HRNBP!g1^S+X?@KqB(ni@Fwh7ZW<9W3Y|uw%P34X3R8^2 z;YMNVe4{XJhflcFy0tP93#eNB7glNm++?|)Q6Eb%sxxZkTwrVy{u4r1vx|6axf7gj zYa0*2O1!xwuw(mgc{6YJnG@#W0#SJw2ElT=ZG&>_zPqeI+XlqcMCmm@F-y~hT`?Y$ z)6%*1$M#+98E$xLB+Y(HH#|>JWzIBL;0jLHmj>@hho4-ZT_4;XLA_!WEawoMD_WN8 zY_Y!)*c|@4n6a)mw^Pdh7FowOi=0I#VUey?GtnI37p=t;DMBSFT2&L}oIQ_*hlr}C zSGtTD)l=9RynT(snzYPx8J3?k^Wo)y&TDA37dV4Z8zL}Riv%{3FFaT>Pj+RxjDn4b zj-na*nUiJ^(el9>3THkjRY=IDO*y6MNZl(}W7}kU(quE)%BS{q{E<{SBqMz&ZUd%9 z@nHn({ya70hphI3)wz??{MVrxl7o`UluO<8X-XTmin*eQ+wHH7A<46Z<)EH<|Ieny^P-6ob{O5lvBb*bc$RbqISgJSo)hPzj8;gAhIE~kr!JR@s7Pchr`8$C}r(1<+E zhT~ehl|uvRre}RpeMP!?OXGBNV&e>3PdCFTsG%Zv^{aHtEZCTR)bwo1uSiD&;{Hv; zd?Qdl=hj>80~Tju%d_5lE6R_kI>dV`2F~Q!ZWQk{iuV}B2(1nn#mz?X`WUZ;n?Jly z_R+?W98X1LWYo^)2_8TaMB)_Lz-qPRq^hPpp_Mr$y>vPDhsVhi(FG&5<0R)IIfYJx zAQz-+f*h$`BGq};CTW~1jFM+juWT$q3N3|fq8WTyPM#6-F*z3o&I|3Y`X-QB;nIno z^#peX&k2qi=m_8Beoo`M`?&|iZ(R=h4X7^B09Miz-Z z^|YCl=r^B0lcTjgJ>9W2Yk?Y+pOL_$7+6JyJqi($iZGRjLh!q>!vLfTI$AE^;}o6rxLZe{9f20&CfA=aMfH z?~x#<^oUgy+QaCgmG%O-U2|-c)6kBNM#{<_72GCB3$JKWL5WpRt;&`ruou|jl?nz@ zYZr{$Z}lNR<_0JpSCz{N_ep1lsJn4yL-|YaM$dAy_)*id(JWX~QpzHR5_0QWaC>6X zcHB)_(jad|1mn`A1{3>x0%%r4B{!(7^$E5JgXTZN?}r%yQ0NRMrMs&|Bdtk8sgL^} zjN-NSIt!$zf3Kop>>sq^8G|@3orG-f#sfzdOH+HTF8Kt5bMr)o*KZw%q%l>kz$wD) z&n9aw$cj5^G5(%WS=iNm1+L@3hziq&XO7a+3H?to5>tUKx99n9D%2n z+Gy0c(Ja^m92m6k<^gqZ2R1tcYg6b&p9`ztd6cfiCV|O~SAeE7uvwiW)sIW1?nx)s zeccz-eZu7St~aN$CNLzY@(Fh}E>hx)6;ZX89z#D_aNlMs=Z2v4T3P>n=WYHE3yF)h9QrY?!`r!LBb zrN|JAz+lHM@#9`MTmZ<52)FE2XF*wkdNw4hG9!3=Cpj zdpxf@v=su6(}_iNg31p09PCQ6B^d0n7#SyrzZUFD4B%Xvn(4_(qA5>D_>y2(Lf|_( zDcMftTGThXa46zyrY9rGgOk`1E6`z8*3(`x=h6=E25tbby-qlJ5D+GFZ)kT_hUv*N zi!(B}=QjD%GK=eZO?ngW&*F^Sre*!if~?F}#NCoio)NldYnXI;Mt??SdPXMU2j}Su z=R~_WGSf3E$-{!~3|}f;yxa6h5@(yt2GZ?L0*B7bf{{rDqY$8cK_9y~oyYn($}Gks z)9&L=nzs8m((dD^Xdg%Qh3q$3yfW?>YvB%gWqk+sMV{00?C2T5UVX5|K=v^G#Z{(v zJ$~-$LW$899%xo(WmYoNZGArXGplA0&$Mz>X5~m&Dvlh`tH5nGg+`tX?HXOJ%N$*p!T#DahfFyMAQ)fh3*F;U?3f`P<;^2>G7 z;j8d)&h#McqH`T))wtmNahMWB%_Hz<;-0f~jReDts&QgaY+ps`xj@dYqfiWuM(kd- z3=bnKkg)+G7f9P+4}+hU4QAy&j^fW8VaayF0y00%_)5Wkh=KXMR|wrX(T8wqF;AIx%t>Ug5Y^Z?rSu<;u3FiIf&e8c-e06;q|=r$i=N zbiUb?lh(D!9r1TL)%CYQ!}9T7Ynp_F?Vi7x4PJFIX*0`_Vi|Lsv$UHuYy26pafro* z!E0KaxXptErOjD7&Oc1ZZ}h||cvPac)<8%Wx%vQhsf*>^X)K**EcL~2TIHN(Exk(? zd_Z5~(cc!J2bZQhNFb!QLfP=duUG`9MX^R>tie-rTydW`jLauojtiJUiv#|jGKB9O|Voc1qJDgH+ zcDR4V>D+MRfG8PuP?PR^Cg!zwJ7)x+#M4o3_-*bj_%vmcRkB?^_k|SMUh{~CIlOtfN9ykfW4UdNnGIw+76L&1};#ek-y>lum{8dUGRw@nS!B_8 zcB10=lnn)+gte_Z=O+N- zuNQ;1QB`JkeRhO6Fj-8ik(ZqFqEL5t^`ALTsX?LG+05l$wSyGP8pSlIZ4aY*>m@3& zQwKc`Hy%0yGaP3_`LtT6{^r6QLb?ax*%=M@;z2t)79xan?%Un8b;eg0* zvULa2qyuB5twDyhmg5j9|Jwk?Zq_5sd5`GG@X9NN>@_6K1`=)F`D#ZhfpMaJ{{ zWQ=MOZPU+NDP-?DC^L0sQElZ6YJr7~Rwt(hGY>hd97aO*_Ybc7zK{U@iW_vgt=w~m z@|oivm2Rz8S;mE3f8!%(c?nilGuN;4gsB)6BO#ST5l5Rw{87AT@u{SBx{z_{k+JyNo{CPiGRrZl)Nu!2|3w6m{gPZNuNQBwdalW($;K-ms(M? zbK5p^+jlr1nL>6&PA5VgmkO_d?oLiKH9}jp$rP@L6x!!SW1GC%rozUy6rMSN85$sF zw~drWXgJBThp7!e!pz-n=-bke7KlY^NAf*}0D6P$jc&0OCfk>(mA!^G31A~xl3-bS zB`mPyfUMW-?L3-|+9yPqIs(^4H;M|! zGqxOBc8%azd3HP_;$dP$!2GNHN0FQC9uGAiBIV?`!6j~YY1Ur&ZixJbgDR*eH4-#8 z(MV*2F=do7Wt{nH>rdtEy`eF0dJ4adc{AMn7>eYvj!{@_ZW%qF`yh z!^j)S3lX(a^fJvG&D$7tFZ!DD#yklI?~tH8t@_HUgX-;eF{PilR8)e53A5pv3S8AM z3H;CQ_e01X_eBrT`j7C$D5YmZcX2_L_$sRNE=K`)`w<81Bs&;%-&LsI%|I2f2PR(P zLM%NDF2TrlswR?q9M#|i2{Ix(x>xlh_Jat|eKmvFDJo>Ac;P&Ir&ue2T$g5uEL|JD zh*yLVW%;!<-g(vWDuPK^)&a7rtU}RZW6z~uvDc9s%2Wp?^<|0I z$a%4EVt`oc^FJbTMO{}??8~!!@i~E>6_UWRm=6!D(@|I4)vKk#`j=&k6W{z&u53Wu z;H|(RT|tO+cJ-r?XW)`=U+o~jSVDMhC;Ad~AK!vICr7_VKk_5B*mbm_|I@8|mE)Q- z=z}D9l^5k_aA%s`SDLa@zxfSDirwm>d}*K}2@QphE-q(@O=hu~T}W~KR}g9_GR(&s zD>XYK!^ZF-H;~MYU3%OS#qWy!pGMkQxx@z=Wp2~ZICNDca_pURkD>%0=i=^3@N>nk zlyu}sxTK>%8P+6LRC@b0`hy6+v#h%S7RInMIm$%$g1``>*4So`mpZ}^GZi7Je3E6# z3Ds*X9j-2&&hTm_H8Sijy2w5BNd%I^47Z9jkh>zi98Ip|5aWS7G z9Xnl8O{+#~faFRZEOq5?XbXRBt2-mKhiBQS*++Y-X)mJ&%UaJj^&wYg*x!V%$8 z&rp_xIo)xa5Q{oT=fm5frv~wM$j?2t4C^jwIxn|**-y+TWtp40T^oZqQpcK5T2${P7cddOm$h4>>hFWX z;2QD!NA>G(d9~L8iE|=-rWPuKhVH=!~XXFczYM{sH&^se?lf?fWVA$F)C`P*kXe%6;P&u zHi!dMjRZpiC;{54O;g*V&Ty#&NGAbK4+He8w%DR#t8Z=VTVsn56(u2*fKWh7H3-qD zsoiO)jY=U(bpF4!&Y8(1*vtQUzUSk4n4HT#`?~hp>%PL@MBdiLv$w={i+XLJeJ62d zTvMKx?SWFxl!M|W_(lT=BkFLlc1Nf`8rGuIpmrRn^_gY-j1$) zSg`+^^Mt)6M)87C{_4~0nqVnfk#}SRMg;eG98`4r#-HG^Rui_R;?$8zAhLSKF>^rg9~m_hYZgcEHpFp zU11TX9k669nc_<&Pmm+|t3IY{Xhln3@7(s=CrabK#Tg7Pa*p}tlEmQrRYJdubhb#Oc1E~3tf?4R z+t+yESk%*2>xB%@HKxCD2`{h%cQ#zU-eEQCD2dhK`Pf0oj|P5{Md4HHb^_h8gRx+Nx_85J&HdAz*eC63qPp zQ(B4MT_Q3hT$c`*|NQ}21x1^l7Gt|li`%4%JPw_CT%f^6KIt%ydQ?o~p(D5#Dc)gO z<$_lCY)~{#YNo^&Z5L?kJIw2=fWC-?`$-;J1v|`WIw06EQs?q^SSr>Rmkx~V zWA60;K*vVy640kZF8NZ~IOL6cAc>J5FNeRhD_ZT>!0ul|s9fZf66_8Lp%!Qj_sw)K=r_=2cKAI?OTn70ftI(~+acFye`L6&3RG0-F`Lvo>zkH)4 zXDJ2vk!iZ4Nf`!{t1LyxkS;8JYK*a8&U(nYjNq>;9=d8U;Gn7KOU9luZ;1W)xPQ(O zUU0A3@FnmMThcxpzQ(_eOpC-D+XX{5U~m230&=%)*MPmj0$=2E|2FSGXYrALTh>2| z`CH#YA$eFLH@L{wx1Sd*_Js#bjehK1z6lXUd#3Gtk`SFhzsA(CU-q(~U-ZcunF`3H zyaX^Cdo0h}JdPT}1ExgJc$dH17G;IhtEila{v+u;^t|nDo~VTaCUdXc z4R`Lyk`(GPznvuV=PshC71h5(=231X7$b2Ww{_P4)i>Z{evHLa46g{OIiPXD{Pw|S z$K5hXPCa`~Ijs z9_{S!-%!aIpxi$uvRsHD&?DU!EAP;U9VO=6#FLwk5p(lIc5~^;=FrLJj1ES5ybZh9 z_xbzbQFFZE=zd|hkA*s#v04qCXnM2h-KGZNyRjy9Y)D^w^R*9Ns}~0R)Lo2X(JZs$ zCutm#c7q<0@RH)YJ}aj7^w=NLH+Dy#`3*4*%n+R*IT04mDm3TwCbn8IPWQ76?!YF5 zITN0%*7Gy)#N>0p6GY69WLXte)>9&tAdsEEs#rFux=M?X>FRDo@KvZ!yZTzn*|B`V zc%ggk`uk6RjBdZl(Ou55N;hKmej_ja)!9;y(vTXu}1jczT{v3fV?c-WbZ*;W4~w@-1}muBc-vcms5|F zzE4m!YFqq`iP2`MI3;~o%)2Hb8gpbkE3UMkn?p(aFjjnn$b!)~h5*zbTiGRw_`lma zDYo{`)+*5#rr#%xq?fLWwxzl46s(KfZu~eRJ-tn$oadja2Kqx)!3qAVR~c-4OxzJyDBhJLbT?0Bo`ju{d-SKmfs zc4!rZxl^r>x?^F6obl!^7s*N6Yix47JqTDB$5o+1sQ?rWJA$M8PseYMJ|~BCKtj>o>;L}y)b7G&%BMs5l(3J#y*;m5 z3j3?QQdgwLimVkz{1m{6Yz8&i#`~jhX2yp1sXvo`sv(^ul5cfI8!+BolP@gky`H%& zyMO)nWf2-rH?AV#ISC|O0;2u|Bs{0kOyo@uB+Ro>JX0jh zdBn1wojmyq|4V=V+vLetB(n!UhN_`Ed2)lDOkG?+PHby{lQjADMGh~gqC|2wf3BPW zdD*e4@?aKms(84Voz3 zzWCHEr4r04slI$d?VYk?f8U=SdsITj!qfa6U~xQZ#DOv4V(<++D!9uk@;PEaQ78^{ zC4`pasZ)GJM2W>su?V(Z$FaJ3)OE(0G7A~v9II%aRkZL?tLRp%2(h4)Uf!cLQeSb` zaJcN?u<+nuQFgfOrugqg{sIrT>;%K!Z^pwXM<TBL zC3xlv?yWBc?->(@&CcTUes8mJuKgDDOFn|h8mcxG{ZLB+R6dg3-h`;_B!<<2=uMa%gm@`F%MZ+G{GIB!JJ1=Y=nWio^$AbnHS#iwH|U zmEgund)?dZf`f?m5k1`={UGPA0f-Vx%y;N?`)D5c7Wb7#B7;m3^+#)k_DHmT-4t+{wE@jEA2^`TTsoy*yKJx zn3Fakdr9_$Iq@ZfC(QYH$sp|HuE~3O`Cr?wp~RPF$CmZc$mjlTGt$s@Y|BKGb^3jj z9hsQ*`?pOylep(<+cc0kZ`V%y5PT9jumCM%{w;zfpjfeyZ~i!dodHoLvTJ`P+u@N+ zw!^!&5^i#MucEuI@F0AStNRvq&nW@4t;msLw==thonut}g3G-AYVl->t>4VY$wyOo z6x6U?{_3l_P8h^FIJ*>WBPIrsi-Ibt=pm*6qrKc$`HSF+{BR!T-m}ZoFykW5EtVi+ zs_uldq(+hVTj?%KHpLsvQ{lg_$lM8zZ2tuoKu{H#c0r(e-^#vxY~MIXtW09_Z?&%X zTIrF#(Si;FPB~`o5Yq9*b4XXYc$WF~R>hvAVD5;A@189Hy$nA9eJ`p{ib&wG+1AvY z1e?_GC}-zC2Uk7$lxVejQMfD%92oxN%V z*u}hu@4bDuw|$W0-|~@Z=}JK*qUV37{nO@p{Kz%h=!KFws*Bfyc`Z_`{icSkC$RY! zmv>MOC`&jXId|L)XjVlh66YD>8L^g@Gy_z4841wB;ouVA;_oIBpAn}#oJf3DLmXq8 z)5K?waGl7GRnh4tJ`0-PKLS{MZo2BCx`3x5bC2^8;)^2lU9P2%Fms2@AAZLyjKMSr zC_UKSRc6o3eO<~09F|ijdmVHqraenoFwUGT$KFj;V~L#=9*K!Xs#J+Q56EYLNQ4qo z=QK_gB&@RYc(qqXRnU}oylBO4 zkAMC9Tye&%ZQc*W56&-tr6#cKRZE zwj6J8HBzuNx|dZw0id&#_qD2(#Z|`5QZ2dVIA*KC0V0Z6Y@`+z{?XF-VlmZHBL%B5 znFzSiin`VqUM=F&-z@zVZMCDSc2v}sIML;p7Q z4yKLLjz(2YOI$e1aUWJY0`T4}hrJTD3%zO*gnFbwXwXLW3vs>(Yhz3K<%>DEF2>Z{ z7|q{ejj>=JmQVKCBvVTDq1{a45)3|Yt@Yh(H=KSm=@uO2MfA2>=$5UTD~#nA=3)IJ z;iVeJo~mz2hdZ)WGjFrT#fChQ)_n`Ey3y zVTtoz@qd4)6d@=(`2~w>(~EbcBWEtIwTpMB6>qf_a?*;8h+_aGQd?Iag3+=gk7MBRp&XGB;r`~$S zWfGjiS}jZrdIVP}w_t&E6n6Y^YyCRj;DYQ%yaIK7mIGD=N{i2rPJG|9xPLtSzSqo< z4o%I|7kB-&$b4DuZO2h79{!wsBdn-=b6USS?KKy=-^h!*{)*4B+{-e-UAD7`5O*JR z1vIeP^xCU7b7qbBC;-Pknv4O_Gx2aA`wV8(uv`(Mk7c{ej~y8faTXZ|b>SVm54gFJ zoiPg2RkdXu8IR=51Scd<_GGsl| z^`bmDY+hO_=Kd#Sq!Sq@4)u|Yyij)d^C?4nUP1xF45f|^7jm)HJxrn*NR9SfEiOA~ zsy9(wrU6tcUnL8x!l4wNN5a4(xY021I4B-B58NqZZIJ`vOZ189WOA5fb2D-UWyff( zXtpqAoL5p0jw%PtMBYBn(#lkpm@VJ?IIgaks_Tx_6wMZcWjg7W-(j*uoI@a;9VO=O zL}9H{q(}j!pqMEsUM3!(@`_e_y@E!9%p=t|t6pO^KxF~*$tQ-b4Gj_5yJza~G+g=3PqR4drv~h)S#$l{;aH!jw{8SCUV>Qe zl2}$BJG7(zgN*t&`lw+hA`ARYBALO^UjIXN`Qiz11>%h9e3drU2R(7)kajG4AJ-TG zHB^gq|CzP(i5!w`%^!lbwL}t!vs*j=qOpIRe~bCJL)bef52u=DCFoC$2%O!U25n~^ zA&6#y3&c)#V(n7dkQ+Z>LlXWdC=u&~whS)G_E!z&0uZP*cit}1j>z!Sf%TCy+Xr+v zJ$jog!*Sh8_j64ij9$CtZ5U|Hj^XZ~|%&zk9cEwBVe6ZcoQE|jbN1+JVL#vXGNpi@c+RAs($vtxGP zYC*r~-m*c)GE9N^T>X2(9jj@4QedjqJk4WQH+p%egU^PP9Uiy9V{QYQexD}jMm&7g zgj;Y7(VNV#-~G^ufWIvB%42Iw-y)Gv=(zDR-_~uWJ%`n>v2?4P@R7$;hZm4t-(cTn zw50iV;9T(#WB%elXo%f*0Da!A7P@DTXRa_O3a-m?JS#HnnE|w9Ge_ml3|!}bVrCY6 zWBM+8<`5iRN$~cSk^U!MNUu-WU^4wtrg#)|t@?@;}bV!db|g zHe8A48O%VJB$oDB(;y!@*De@o%^qb<8)7bI*gUq;ms?A`W-@oy)x-i+zD%>#U@?fR z1f2l`MhVaX7PJHE6%r7`I3bD=0!h`yod!Gi_`Y54cRk&b2vj7}!-6JZ0iI=gf%&a4 zZu2pqPckDv=XtbZugA$adV4Uk$Nzni`GB}~nET18ZsRQ88NKZUAkaaKCm{$A;O0cm zD!kmjBD{{|al^8>Gv*Ci7(Phm?GtFxkMm!=ZX~}AHU)d?|Ca85;ytq1y@C1js%4p9 ziSFx))~AIt%e`}O3&PLj2rhd#rf#k)yovmCp#zL@uW1KP7R+}O(-H|5 zh>w=7A<}XZA<}#e<$8zl1D@!iIEK&m_#wzwb1v*Cs02f%U4XE*i&Y8YwM z<8IsGeu=iP0Pms!xtHKHNIHiu74a0&Z^oWt$CHWSu8LCu z)H*t>Y=$+Wq9v%KiVO|vpdtfxOz(b4#uT11qM}QOvq*;X;=%6W$jARThclWOz5jYN zpFVpug)*8a{+S$2;NOhqQfD-i5~I0RMw6ZxO|~^&K9-%;ZB6u_mxb&IpRg?dejM}B zI`mqV8X3o5PbSAP{NIe@7MX^WRjHD349zAhww>%kp1#zYkp_^5@12!o**C**Fc7PQ& zXDeXEk3jkOv0yo`IHF^#6prz zOHhm?*=ir8_CiJFW8y;(NQqNnuRV;T_fMpMih0k$4SwaI+!?;2^cQAAJ&wWQhawqv z3H~cm=A>PpyDONvd|D7ROUET>4P7MbQ60j|4TL9#VPJR#pXNvS=z% z1_ZWX{@6d>Vm@sg9Hz3uvhK;^aD&y&LAHW(8#5s@XGQjk9I+tVLVI7Z8R1jawII*2 zFExf97js!FFcS{VD&A@hcD(1x&xsG+!r*TQ<*)To)N!Yiq>Hi8Ftzrn#Sr ztg7CEuTZn2SGm~PF@7P!zuD%0u2${G2(+SISHWx{q7yG}32uxHm}TjbR!`q86}irpIQqKTLV${N#; z-u32%9udo{9Ug!6VEH`LuIXK*I`QVGFEa4F@Px9hf4N0Ow{7Ef z@kY@j=_#WS4N~fyjs*b`x`9=qd92a!4mw_Frzd@cG=k<0><~mMLEMm^revAI#$ID< z?d}@q(M#$-tDgmXB?;;(K9lNC5NV7IGdU?vk4i#_V^R~Oh%{8X8zRzZC+}xs--cm&W|qjd2kh7>h**N+O-nBxiKUi5lJnO7J@=-g-E1I zzbuSLhB#)#HQg#-I zB33}uM&zah^%N;3!X#KmSV94BZ+^Iv{b;EZ(bL5$2C>*!9pT*uWKZ z(jhz4D%3OXL~@L^-p)p-7|A4Noo@8xAbzg?1MREJHlLof#aY`)o80|@Tbk3raW9ev z$#A&GZ7tO5d{WRM&3M1S_|N)wm3(_#TWW1<<*$y|7yXB~tsm@#B;gdVaWcD7mkfdE zkMug(djtXLp%zW&++DXbkYUb1!h;&qWk5(H+KxidJN2bI^~tz;eaxT&e954~KEC8{ z`|e%?tIrMXb!M`=BcCw7!BoTe!UL#=zir=>0fkz-=Z9sH<-nsVxdsA+U!a$Kn$Of! zi4ixSbKRE5=bYTwX27MvqKO7FR?#5{XTkhv=l=lsoi~TaP1@?A%}-4l1W*u8F?5oA z?f7X;_QDlf*dG9jle0v5t@k`V+5V0`luIo@VffuH0&+JgrI3<1Q80`cN*$$*=%kH@ z7t#htSr$Fr!y|jOETN1+lu3%p7qY$B#{Gh!fWPYJ$uiJqMMdQUAh?pWmKNVkahVOL zrj)}#!vU<9>hsHo71Gt*&+DEJGhg>9Up^^tk&FHzMF=Ky38{&i*z84xX|_ zH|eX_ldl%?LED@1s`VLtwLAIharvrIUTt|^U;Qfi>M?mGvgfkw-TG>M^3^PP^+S1e z@6Q;-L36jhiriMV^oSPyx^rJ#HsO7}FLFNh#a54^FYR-mb!e?3^F`;y)RH2z@rpQN zb93S;Xh$Z%LD>HayX;;*?Kr20@ZKf?as=-B3vT8J8>F*C9yHX zbA?b@cxioJeRys;khBU&Dj#9>b*>N%63%yMd4_X)dEavP#pP4I!HdHa2@Vmyx_qAV zHmz^+YO1$AhYvG`E8|NNyGd-6R>%(P`7C?`N20kIH7COJ@)6~Ma?CT>_GIryYEgo<01hDHf*^mt zj_s3#ZOLLoa=ZE;bge_azmxB&|Kjr3w80zXypje7mcN(sz%{IIehXQmE599{!siqS zpMzMc)h08h_%8UXni)vRY=rB$IGTP_#k!N>P6(gNBz^Vx#}X9P1LpcAf67|h*iMIx z7Zn^Zw4#LTe01lDSny1-%*AeD70n#+8s_AWaJnwZkwAx$lUSfTBquLq;zutKyw#D* zGF**vVQBfS_BKHzfc~wZxD&adlZ61O1C{VR6O1) zqW-$#t6R)xUv;nG0JQ?yK%YvGofvBH%XD?9#U_42oM{ ziS^*)Tv`wA=GR=~N#`<_BV1=(Fea- zH(AUWg+Rumeb3a9X`~~WZLK~bGqActe^2Ufr~Z1V!Vzag|7Q%>^eg&5kMK(NO8I#= zmk*n3tWJ-=*?=^;-R1r@!L9X|3LdsZPuro^tVZWkL$0GZ%pCNc>L)J^$R^_s$3QB;%cH? zl{Ij6rChDr&DAKm+VlsmE|#mBJzNcutG$g}_2-KGQ7z4EZzc;dJ^PgH>26g=SdTUc zqLwh)|1O27v(HU-6BVXr3{6D;<@0CR;{Pr$>j%-Dw=#H7W2Wr-@a)){Io!f2fBFVU zZ*iC%Y!4vq%$?p;Qpo+tDI9qbW!6FS&+FX}&i{lDV%x)18{N4|+KRl$`EcDvcE$$T z8KOLMM{?sUppOl*eHznb1DUBmMgg}$HllgpTm3vV^M`xcyc?vG<{7=5D3?#@rQi-T zn!t*&4T4q7S1qYd@Qo?aOTk3udc71JW%Bh>u$LLHmx9;KXZ2Drp1DLX1r?ehT+;8F zap@de$@HwMj??*`Z3huz40W>fEb5*v4n*?vu$X7%W!>_5X8M!zvff%uQ>l4b8>dn7 zKj&qwn(UB(towhJmsL&)^Xi{_Cld_~O5|nz%$5&@+J-ex4wwM?UQYtR#6I#~>{&$Y z9ZseW&5-Z2^mHpRtq(a>U@7T(klK~`EE$wH`k7GIG$_3(u}WD*VY~~vW&(VpPypE3 zBI;7IJP{QWq8ba|zIheCaMrYFMHhDR@KeP5R<~7E5B6+h>@ixPfuPd>4tR!ekxt0hGVILS|1!I>ipeHXLS?mCT%N|4wZs6SGHXtCyYPqvKevGLypq*mQeA zPGNahQCY?+!QhWU6)wP6Q5!4~D-_@JM^xl((zhx-*K`*20@R}*Z9;)!krYP>81^G~&-5z1J&>-jPX%2ZdLsA4+1sdLsqc#OB0euu}9;7T-D zV%MA{v)>?)Zg=24&ls(OD(vMa#6netu?>o~CVvqa6jtX_9nZPZopQJV)uMKBCEpUZ z$(o)`Dk$liBV7CizPW{EH+biH%&Ln)6&>glVEIQ#M-G~cr$`(Q!mwn4%n%nienze+ zVSODlz_ut@`}7#D@X5nFiXM!%)%hzHT3c9DHe5awS*A)KrsV`h<5CsQAaKN8&3HLQ z-wp6pUXwri6y241l`m4~+FBz=bF5&Mh-7CXf$TN!!pNK`gzHG*I3%{A7?7Wk=!XCJ zxDP;q6bZKDq+Pr!x1clqaC!l~t+I-7P+OT{zbqH~xH!neht~q6n9j)n93QKqvH^6; zB7J1>futyg7NoV!v2S%x{r3 zuQSb{cR@KoN5HYcm6>`45lj0pbKTVh?z;g9a6TwBJ8r^qM-5She{7Ql5~=b=zQ)+D zCEp5dL53^+oYiX{?1BR*W%}7q&PjbyaDaSsx2@&41|Xjk%UHYOfTc0SqC17AWDfSa z;2=WaRB#ZfiOgLv;|4H=zj}+5+aMoR){FStbdd4WULz0ewOzc7ZjoQ4tXm0yD38(Y z*?sN8;kb^52cfPcg(W@6EoeoF5i+@<7RP-qu8CV+??3ecEOcgyFz;O5D!qOI5yKAR zbkIS3^?aC(unU~V*%o%eW=p$ZuaV8Grn-pN9fM|>$=?9V&i=IuHd&#~F((U_3120f z*$UN4q16KKn6NLRL07g<)W(>0+U*g6nqt+{d7tP`K`l7Sr?{^ci}vW!Y*uV*SX6C& zZH?}27hr3;_taz%-9>rDTf%;E@r?9q3<;zW8bG4wjy*LZg2D1CzPcDOK9R_AfGpl? z6+ez+X8L<+p&eH7V-n*20)RkPF!V^e6niWkt-#}2vc~?2u7qR59oj8!VQXn1?*)I= zD*g)0oV~)4GG}!$k<*nGS4jLUtAbA(zFC<~XXw*8!RaKf4?ZoHW&|33#XcRZ*cxUH z*P&VtJ-#xleS}C9_5?#UE07AWa^NE#skJKV09SK&zK=7hj+rnM|A*x{5r{<|vAaaN zEM_#Ur>Bbx~sglIQkkTKB#(m7Qe$PH}~ zZ*IRhlJ2mdJbRq%bjph=b;UgigngG?yqPHV1$Ee6-A=sE7l_a8zn2cLiiPS3mpWRY zf$j@vEMVl(r2!Alx)rO?n#2~(id7sY_V8gjZFe}ahecd*l|Un%CU8m|1`ZQ@$6xg#7%sXr z2OvOuLDp>hOORHYZw-qhd;6`-OcIY3bh1CUFVvH)5KD?9iH%!|cryO-^YN7+xX6)k zMljM8`D*;`9I-z_u}kidlh}SG4)3=yl0{NDQ_mzt@=;-0`7$yLI-5YkSf#OoBM8}i z5vsZNY$tB9TB(Hx@H7)`U5ZwkmaGalbfqJ=<4K~mrLTt z#GEMFkeOrSxoC*S&Q2;M67oG&Okl#H=#nwET`Uu#_%=F8P`M}k&Ad=k_)`oSc`fvM zj~P>XJrdNJ5sgylcwXp;qm^N}{wkqUKlvknwWx>aka&wkj<{+=g!)I&vaS4N6Jd%6&zWaj>#Pp#2C2@HOUOkWTIxzPRvls7yC`?W$=bf zLJy>&li;s@+a2rjRFHDsDFO;UE5y3L>Un;H&+gFc-|06=AWF=x0#jm1Y+K5bSQ2{5 z{NinRWcWmcwc^B-_d<98Bz|T(?n|BR7ov@lVCHahM-cyyLSR2K<{d<$7M^RSL3?j` z8g9u_p{YEK;a4%<9Y@@i_E%XvziB2;eLow?IJJ*OV2nkhl3N5SyZv@MeReN<2Zkw8 zw8D8Qfcg63kK=ibkx_zjwx-Srb(CfBpa(hLetB74aG^L$e{P6!A?Fht8?gi*FYWd5 zf`nr1^#-BYgzgt|M=PHf@`VFah4+j61@W7tien1) zw4XAguS}>`d}0F=2o_|8vq1H}MvrXz_JHM+NBzX|^=Wy6SGwyM2xEi$d2v>W|2{I( zz&l)67j5ZN9v^VnzM6>TK6_hjDv>2@N(e*Oq+4N5H~u0Gv8V;8!zwljv>wiMNhRbC z|B4J3^BH5QtNfbHtl?vQ{M9k}>kThD)!+^Hn;G9eky&gHpK9vfv|Vx z%=Y=%IuLw1oDYcM`&~%PNvq%_+IdIbXE%^Du7z|)0)P|Vhiu;;eIthhNJFFJ`r^b} z-_t(iv9!p2cEiX%gvk+mrOTulvNaqsfro%#mQuNdh8K-}@bqDh?m~!S(!?dutjrAq zSAwm-b&WSU1=qT#+R8llEQ?%8Ag0DuU5t@oC99UYQbDyxZKoRY!xz{(Khc(qi5ZcB zryBY&iaypFnHw?hWrSkkD;CC*w2^)Z%VNJT&)@E&dE+L$$M|spdJAQCM@bP$)`W4X zxBKTZW6)a!p0Ae}DLO9mD>jRs4l|@2VKg0fwiw|3 zf>+UdvQakLQ$|OZp7cZ_NFg925cI#fD z5{f^^wl2S;_I8=a9XuishQrMv=@Hw)(ydlxcVu9Z`8IWvu3ZwPAV1nfC-AAJx>@c`~JblBlxT*6ahp1CWA(c50Li@w@ptjG}& z9>``9EBDAKmzxV;BHitAl+i1Oq9JQ zMVc1Yj75H&mEEN4yEd_-3y#22I<+ACDfGhU{6ypiVlGJ529BxH1CYtfAeQ?p*Mo=S z*q72@%PT#;A{|E`J9Iexa9(i}H^og_>~hH9bgbDzhubfVdB^63q#))#6yyv%%sDRi zO?K%48LI<9{^}F30+8Oava1oE*paPVVoYO!yl}enn!2$9I_8=^>ic1aj|On;$}KWw zEqxH;2P;Lj0>v-KP11+{6ZWJ%0M5FnaV7wMY3J$JFN~jl-6nXLS|%jw_G;atK4CpI z$9r_AXfiwqx^{{h!xR3pBK|D`T?s*-AWD5p3Ome2d%r{S7w(tWgl#2GdLm%Fr9l-h zrnV9lg{n7xD_5%CctoyLz424IQuW40xl;AUYPnMN#&Wq*^~POtbqCTIvuY<-A{sOw zF74-O`*@Wa20{31v}f#zBuq28SFpS4jNLPm! z&hTQwJ#7Npa@siYw2at&gVRrva7M^95fLWg21rDYUlbpo&zi+zk5T<>vwlfGWD3sR zRLNHMy;nbq=j|a50|ZA;HHTBkG%e$cy7teyxBKLlo~3l7x^7wj#%Vt39zH>KqiNfv zh7hJup&=D);vvCMw*1YGg$Nzg=R8Q# zOnZOj8}WF)$J(%&x{*7!&_;56?2Ae=48j3NGNW1oA| zb*6eT;_@O12l3>M;23_w!MS8p_z0a`T)YmO1cyf7{U|Pej6{5(ECEfA&n$|M;q2T1 zizQCP9TLxW#!`uAt6155!~wo5M+36kYeconI#149qZ)-^bVDak;?WKAf`HR+U&0@e z1}+s!}~fX)P$2zs7Nz6l@BvzO~o+O5#QoHDv+@wQmaGHPN&c6PXj+Ku(q# zixih~&g|g(MIh*!o&=IpHmw(Jp-;gvPf1NmWjGNGkZ!6_^Cak0YTtr*0Fi)7Ww$t1 ztitc&xa1^K@AIZO=;NrXsSBdd&7(R`1XEUzQ&qJ1`NH7&oi;c@FmTrbQf3u`B zVe?r|48X1!X~M+XP{jz`ZP5#-f;-1yt?%S9ba^$6y)WGt!D@RJkyur4_zUd(6_-BJ zYZ`5pz)HfhF{X6{N9I90e^lZK(|1&+f6LR%H3%VO?1vLZwZ{?cI0iQ|_ULmXWsvsO z(3;zNlLF~thkG1;e_Id1D`1;0^)*FzE(Iz)5T$EG>EE95@EA7gQS5^v7c@7S>GTas zSawy|*StzVpPc3WV@ifWByA97sNFHMOi(%MBPPJo z{1h|GoDzVjmqKn&t!giyMTRw2`}iy8 zNn>>uS8|H9XUEovX4cYou{ENwwe+pMdL2V>f?Sxpb7aEfi-w!UD2&a;KLs+jKh8AR z`SYym0F@!nzU1L8oHzEsNBFfgEJn-;ju9I}f%ZYpozN)1CHs7H$Q*@@Xnq5V%&TY7sKHDG0tdm~Upzv=2(C&qtqT zqHx@gKP7V-t2XRm=KU#|miSZBYN2`RDP_I;wH0%e$+Wo89QHf=i^acg89?`GC+7vm z)hM#1tH*v1Pdql*PW3WRw|;cgUjGgWW$DUwY6EOt@G@d zpn>2_?+W@N^=V%Q*fGHq@;K9ew@q}56drCX7NPbP=X4jgJKFA(RunNgeQK+cw(gVR zgg<59C#WZQmv_Zb43YHVWcxi!Q`?duZ5Z)V^i!nvIw0#Q`7ZjLIH-CelaR0nPv3JhpoCYwR>Az5_C4DQq7U zpD?2$5_Or;nIbY&Q=5XW;5~(oZvzSWoJA1gni-!Hn=-3=)(d<(<;yWm;bl*;lGu>g z1C-_iqF$0BcV?e{HCQWVec}GWifq?q&ps4X1p&b>6)YkHg0(`uMA8YiJ2PIhgX`G! zn6C_(jTkh5F}*K25crS<8p&|qt|3lvwF$ygf1;2JNsVJLrhP&<4Hs$ZVb|fu#-0*k zuD|LT*3aH>fMvAT9N{;<{V>0|^Idw=>K0H>qSj2r`>-=k#H*(J@s&r@oR z)S+M6Youze0^962dcTwwbN3XQAL$FJ&)%QAXL@1EXE@jYTHbEZx7x?tgSmUY()P6U ze2x2!wy0g6p03w48Q(5#i<_@0ORfKt%SugX2IbUzAPSjme#d+4hEY%s85dk(xjchfK!?W;VS(jTkl|F-iK5h;x&@ zVo2lEY&pSbZvrVT!EF1XkuQtK&!A!Uk);wz4XT9m;DLPh@4~%MhvRH$8qat3IpH?g zvUWYjYF)GKRhtC_Dtr!`73x%lOIhk*NEcJ*Bv}eB$wI$Q)Wjse52GC*8Ik`Qfc|dc z*lZCNWMxhq9p#doh`bt<`ifwSk-@}&5fx@|9>A4=(pf)tO~O?51}3L-5U8ey6fwmXc^8=zko|L%8B5Ix);zi$KBER!8ecn^*rv3dz|}i?P^l zIeKfZWxY+_&-;-qWkEQL;yLMz{-=b#^iOq)E>!za^OOecgPNTn+m%^P*?w9T{-+Pjy zMH4!309ciqc;#AWa^G0Fg?j<#-fyf*;bq*C;N$2{q3b-6OQe=HqE^tOF{=+3DTmVh z1qPmhYj`4dFK;jr2(WvK?F*Q}_d6KNUu!;gD z{EY;x9w1zm!0HTmUupVXX?khCCz7kCiJH z`)5(Be_&1V!CRgovK~d`ZQ|iM_8HfuJ+>@vFo9Np`VAJYOM(8lBH7#Wd4$EpijDSR@K;j%zTlcW@itCnt152H}7gyxRL#@$@ z!`Me0i0qYCBgO@%@VR-<3#di<7Xi91%!11h_lrvJsz)7_p7d>py({;H+)$kkuc9@t ze#Hg$l&op!0oyT$YLxNq*BcCh?V!xADa@cJs0dDLt?|kh{+^l~b ztzKD1zGs#B?X73x2Wr>CZHPwZ;n9Cy=$Z6a@G!ef4&=+sh1jS^Yd1>8L@6K09Wv^* zqC!PoN|f0Y*2@+%S-1HBs|dydkO%obF8^tEo|B{lgy?nI z4ts;(-tal6k6ySh`bGe=IKEFm)IO+s-_wsFQ^N2-EMP@(sWGS0$sxk3)XeKeY%qbB zo2J!_q*Fx3`3zXHIi=!jL|KL2v;k>FUdR01u?45oM#N53fIsa>cW%UI^|SgkaxN=U z)^X*0kI8u*?F8w2hT8d~qb5MUfw#Njb7Rx79P?Seqzh>DX+1u|frmHI^Xj^l=c*C! zz6R-#`B2VI*M7sHi1wQoRL|R3g+REnOOYcB>qKgm&RO;A^j{)92E&~h>@&ep+njJu!FXnI4h4~O(y365qC-{B%nAMd=ilDnAq#X)J7ic!Gi1may^!?Rh~~ zE}&K|0BWV9wOE!;`qDy!+CSd#@IsbQv`aoy-=BHSA0_qKm9oN8tFV6I^XXt9ICK_^ zCgvf?io7d_vya-(>-i!eFE~2@6(v%lPpjP9{-L`CUcK<8=$nDcUD>h)UStcr^h}Lz zfoD|43QybLzR8QhOQCKoIubpR5*&bvS;q?SX80?G<_-~U;O7(>Xk}W&SeiySx-1-; z(qZz~GI}}GldH-k+ZxG0qOGYp#`hi)+zovA207bSrXZU-WwP-*clU|g-e=_Phaffv z+@rmIB^)V&)P-20wr2)9wb?^uZ_wlDhw;c@d!X*|q3d|2!)qU458Ny_iM3&@Dhr2& zlGPZPB6UWxp#pM=jex`Tjb3wJzmMVs1TXG9TWe64NK^YY^RDj`)e6U^dS^G6b{sG0 zIG)k@9uk&gzXFSQnq4Wy`#D;O=F-k%eJR@A@AuAP62Qjz`I7Ff4kH@wGo7@RFM&#HC(;8Q_E~m(1-&t42d&x@ zSl)?3I!qJqC|-Hk6@JgrCE8-Czp##i__a*q~q-e%$j~lC};mj zj#S9wF{!AF#^*uHe&=uQ`8C7#BN-WzECN4jOHNKq3^8KOPo*3L@qr|l4Hj`qsxv6x zxKsl3=1q3NiR&PfGnC2ko{|>f^^iEE~ufoa{ z_-5LRy89^dgZWZ#u2X0D(%CUPOy#ET7MCE)D zyP#XlOdqqBaLTXxIVkKXp~7_G!e0&IXgIHYk?A@D{UU50Q6jOOp^w*%7rPC>OSWPo zP$bYG1{G(|8quG@+-FZ4hq8d2X?j@Yyt*}0fFH7^PDT_Qv zxYN1mXE`;;{&9f`ZIVM%T?Z8%J}n-G<`?%6PY5-|=_dEkM3k-mLSY{wZ6P4?pt6Ma z2r69>?oWY;4?%bP2=IR1%VA&M4^QwKQq+>aXl%n?G`7$w`3d(^r@dNfZ>-y1zT2ED z@-K-LY4o7*4Px{{dOGzCwejSmM=%XBo<{|OB5GcB-M1u#JjJHKD z#fBIZTU!X=%{Ch{y`J{*C1nzJ$h`d*_q8v!b{vCle;vaW2`yv}q`Y}d-uyvGQWwRC zh+YHsAbiafOIIDM?Sd|n{w?te+LfIas}vgsLS~S@^V3+H(S-|wS7WcJ<*u%*7Xt>9 zrEelvy5z3U6C6Kb=RyyLOZbcybXM+>QY9vHK5I69B5yFe`os4m`%H8t;n~h}YFpxq zS?U!2+$wG8$>>USy@{8Bn5E9+Tb!5oMptHe!WX(k_pAaXx)@9`)#C zIpyzLhK>~hu+vM&V(?zA!(UZJn+TMhcRt64aH;#QOy3Q6-VJxG3g@}+ZqRoD=Uu?D zGt772p`M}6EazR8V|h5zeK$nk4IwcH7cw(L)E-fDIVy6^k?n?=mRa+>Od+wOhp0)m zPlP|AYy#~-vWenBf{S*^z8nXHh<-5jgcK4X+fzQIHYTErn>Gi;)DPrW7KVH+G})Vx z^X|?f?l@NRm~#_A<;s~N$-uEwvIV4-oz!y8vygS{#>AL3*sW+N=ofGMnC40jmPm)) zR04aqEI$ zsE8bI&$T}W;Z3wxB3+>W!^?6I$aA9p>J2A9M}qcf&V=?j6?suQIg(C-KaIy3hxteR zqxb>GbNF*x7|;)NKrFn%O_K{ZE%z(jKv7CMm@X(B;*ae&Km4K4YE}huuvXJ{qpVs$ zph%dz^N>q5aR`^KQ;4!}5{L@450m5=`n*P;->uJwSdrr*0FN9gPb0{=WW4TU7OfOu zYlV;yw~7>KLt+fLMaJ2shm#tGrDp-uvKazUO#)Eg;gW=@k~P5dc99gi@{Dlg~#&L@(s56^B{wQAS8!?r$w6q1!RT8|A zOR~+{)1_WVW+v7`KR@V_#G=jWkH`swR zX|4mx&K((19Rv6OUymN#oSD7YFmQ5hdU+(BNM?Ai4iaS-Bm2I z`PQ#UaRQ~}A;p1z`yQe}4;}7gm#I3J_i~@(-uIFF_|TCOj~>nlMGi~t-#(=;iKx7( z`Kh}0c8M_pgc9ziPMJRb?Ia`&84-~eAZG6?!Q41=5bUdGRSP`zPsV_<;Hig-jVF#} zOHA46F2pteMpkp92~p(i0_IrgxFde)VOIEAsPJPFd7!Jg^mudVxSA3U<)KhkCsCXb z@H^BcT?-EuvKhIxL8pJnlq{rYISxf|*%GA~&gC_QDG`sHEHvA`&J-48HHK6I5nblR z?!&s%8{H|c3?9N761XD(zaj^0>iWnW{aB`djnF2dqdJLhroh~uH>L00*CCXR75Qwu zX^YvJ0cN|8LU(N#V7Ed{R83b zMVz@t`XYcgkxqcHkvd3Ogeo|;sdpu30*eG5>^njW^Tu4>D6(y%X*d9LydKT?w3fqTmFI5#pnq{IZ)HH3yIGXX`@Mn-E`m*dgI9x zGWUtoT_wu?>c7e}=%Jqo`)L)Qj4evb>+o0Ym&dP>V_ST3j!BHcPcdLeOf7`@UymlZ z1E^JdzZ%mKf09IqU9r2jGa0S^M3g3oAzD%?=Y$_G1*YtuA zdrc=C4?1KFXbzbtDDO(fm(ZST^Kk`%q*Em0EF%z-ZLe8Jm%D8{646zyi=;hPM}1-3 z>?$)QSgc(y3TI(P*dvh(QEnrv0ZzKXLtJTcWpef!3&U@sdiuA|$nkIgQ~jHP0WaQE zb`JBZCi-Df%GKqI@MDN$`VZhOl37ow&AwW3;kMoi^!6e4wj-b$4KYC%!Cv8-FYtSb~S`5v22Ae?~Z4y(ZzWoVzd1)|4$CgEwBgf2ky3}&IEARxJJ6qL!4)v z_)8E1SvD5fKC_$lL#4X*gI7guO4L=DFQ_IdO}W(K;~`!&a9`#dB;`3fz4=;(ptLu+J$*GQl{mVc;%OP9vx+z~_&_K>`=*N8j=Yo0;D zheQD4UuQEn?YGGu_|032XXe_AMpm*Nph|{rM&Ma!D)<}^>&yO43paPSKn9iV(g;!A zdv7_MW#mo5E2SKpmb15|S`w(#?kd+r+ljMP`Ys4Fn}r?+?XhT165d&5QMEZ`BQK3T zrqOo@rB^fYPbLsoN+bu+xA1bD{-oKl)nz7cZv?sd(!NO4c#O2_kfoTyY-|O| zbzm(5eST*m{!BHqH@oa!u@(FBpB+5qulgcx5+=Q)D;})b4Cwi*F6Tjf=scFE(2SWN zlj*M>D$lkH4r1zCe=k$-UoSEMVrbFzvW!*ojYQFE`&$Nu`r0);kgC{X@JaO_yK4&E$jLxJegeF_Ol}*5pA72H*b%>Y72drTvMRS5fp)ig+&Rv!Yjw4 z2s%PMoCH$h^dM!{)f5D;(o>eY9!&-LMz9&dLd9Pdm5SY{4ui`c5l&~X*-6u!faR1q z{aSh2g{MxxJYu{cOdG+_qMYP%7PPXm;mZ>?Df2~-F zCIBbzhNu)0 zSMMxjz&;a9B|VimEoTGDtquVYt z9=+-;XuRlO465fA)YC_NE!#iux?+M5MkcW0g|3SO3Wl?>su~2$H{XP=7u|*s0Y}Yu zzRrj++Qki9pf`0L!NJic-~kBihdAMdVh;2HxROfjo>`nZ!QU_CZRB$tn>~}AC|yph zATjf-ap*!9m+=N=-2PkI_TA=jxZD7)&zzLO@e-^joE_Y*bp~9aL&wCA<86PIeraZ< zta=lW@ZX_M%ps;gWA%xgFAUPHy$FJ~pYjQ>$(buYIL;C2FcQ_=H-=8i?!+3$2^djL ze(tXDcZj>`Y&6+o)7sc#Y@H6l{}YnaQqZBadO!kV7C}GOspd8Uf86D1-ytL*jH6Gi z$ZL)}or;_!{(3hmXEGC1;4O|aw|rFXEh2V1z8c0hX-!q?3lB@I>Oexf4}Dxt>~9I( z%7E{XzbRWz4(u5`3$77j&R;!6%Y70ZwZ_FE6h`GEK@JV=OyJrIAko&}=p zLREUm{9Yan6i1u9L*a`ob-6*gGuW=wFD?1SnQtA%lF*L)V(oWWwB+eia+FGxHJmNy zE|x|MlM~{=-zA8{+!KjLzm!^A+okdi)LyqJSikXC_2-3nWgzmJ2wfeIT!nZYFKeBN zZcl5mQRIcVSo+T(HR7_MmB12@wFpOWp958sdK>*@l3yFHF5eS zVARk;c5tD25aFq!cz>0690l*5s7C68u3@04EY%ubru{g#^h#S5FNO+owD8 zA2n%9FOx|RHYs)?jZdKm)o$o`!nizHX~FSwO(OvSl=qomV!k+!o}ia5IO6u))Y=3q zdoQZ8GIO8}A{QlepLGCgoQLrzWtGg~S6BrhNxtjo=*S(oFMKgc7$O&oDMI?ZOu-%l z*-yCx`+3ZIzHE>b4O#Xiap6Z|eN}tLPI2`$Km0MUH{ENR>j{2V+9jnj?5PqJVCpy- z(>wVh6n)=ZhZ$4*Q|61(qaqMk;pK=l5jJNIsB62O)g#?mOKVpgnPjclhDAPYuBK*l zB|l}}Wz1oI7W?)v^KW;UZIrZXq@4K;m%-YT&L>{^Bz~W;n!P`X>L*gpEY(lC9=q{mL`}^ z1c+903#z1NH#5zV^GzeQ2WuBHzHnAi%-#r@VCv3gN>9E8p2DrHJdJj5CD|;t8zh8t5k4uQ2hc8y#caso&mBSC?{|d-4{JA z)~e=5|Hwp8aEqfH$5uxeRt-2|ze}bGpE(acB!Of)!xhoz1)+N)VSBwYUA= z#J)r2IYQka#}*&w=z6Wnnk2nrTu3v<{?Yt$F%*nrDwf&_ArX$2%#J>*5a+L6!fuH^ ztDW*!mve(Z{9v()u_}xNNY;Zx42%M)8$l$qoe(blQjLg|DdrPV?sGs!TYS-HMNk5P zkYz=;$R54aj_UDc>+vP$-#KEjy9bI)t$h*u49)&W~YA9dR;>>nJm5LE( z>{%&E3SA-)8(?adLunMd6KVZkW`^hDJnCA>2w^6(XrJaQcg|BLoKjJ#vrzk^(=A^( z9iub$v$`i_@q3)`9F0~~UgdSd5f3i3f7e5}!fP_6#KQw*BV@4=R8EI`){ zfgF`0vunC~)uMaeU$tHKtZ%k`=h7q)hy@o|=3-3Egs$)c42g4>u_7c@KW>Do(S^f- z1~5_>S~M#yJW1NVqDDj>C-a(M+oq@G9mPh>UuZvhL$BuZN>8pxyWZBQDtS%I`#?hx z61=pFlRm#!Q90eNS7N%S&y;I70@a9cGf)^?b5a)<+H>2GUc`b71#-vRHU?-E0uIUaJVuDg89JDBVTK`Qu$e&74$=o1v&{p9}~U znwYwRlfa4NfQ?8MmSL65eB!MDky45A=QA=m#3dz?HY&p1l-94)=B7`exzEs?wB@h* zCOs-iNj%mzhX)8&9lwYV%s4r#y(#_(YQw~ zHQin~l3}IXdo3=DD5hUd(y3G<`*FQbqopg*Z{8`UG(ma(P@Z(uR#Dw~Hyy@@HF58%mD!QyL zseW0ssPY}L0@K$7&nF_gc{CsB*weNYcx4VbwahmzNfH*3akN#YP%t7<%>cml=v|rO zTuJIrY~vU9n(3sMpPs*n>)jk`XCXVV$PF^+_YW{=1hXXGc4AgJBFBT~2HLa-2_bdo z4au2MtPzjgA@wG7=3fWI+iw=q^Eo;(qY=S$LjF3^)!F+u>!C`*-Uvgo6Uk274 znQP>#l#N(FLiW8T4u0@?cO{3VynmSYtjOfMK_I96)&^z*D`rb2_=#4(oQPO(mCHY> zXpzueip1CbIfehz7432C$Y4NZV%VLWSe`Ml=a|=N`BL{SvwR$$6=Gi#ns1Y21kDq&X14o^YYGo6`%!((Z)+ zkF|G!kFq-V{R0UQAUIJ$QPD<4MT3fs7h*(F9Kc;uCm;#da%rnHO>d|(ij^RA65&0s zqjXERwDp1&6)SB+0f`kf2pfV>pe=2oU`rMES?T2L#+G7KWX|`u);p7#5Zmtm|M1bt zds*+gKI>V}{YlSLxb7rW8u070LO(wkx~BxM!>xT(1%1s6q~1<6?4~{aT~~mL8<5xI zmGZbKnNZ{9+?78rLMGHWf@?QhScP~BkMB82>lA{hv%|jz)GIy;5;;N+dQ)&fO{_KYl>=HK>^yEbp-aFZ~C_@QNU*5V&=l7l#C58w}>JddRFq#XN5GLm847` zwEwA)B&Tf2_?>I0XHERhW@z~#OF?h~1Uroq)Wyfxo`o7-q*W3V&}1sc`@qd4)To$9 z@nZy<`Z^bWX3r?@e|euGMipwDtT&t@gkf!(OOxFvvdq2*sjjngZByBpPd^8ZlwDG@ zcc|Of$LBCX_ugGj%z|c}B~#9@ROkhYgC9LR>%}#^=&CQBcQy^C=d1bdgl<>yv>G?7 zzV_3*NZ&6vtI<${06(k9Hi~4Czdz?TAb%fUC-Qf*C4VEwlfM9evfQyZoE4YW^@_LL z>efu07?O;BLg-de!JKzL>H>}kFn~-3!ccV!&}?)~^XoqX81u9u_3MLzZQsIQi13dn7HNQi3RgkN8&4lV~%-}E43t^+&-j%aKZ*rgfe2K%>^UAB8o_xT3Mrifq z!Gk`T2gxC}a)+{-ho(_hn!C9mO)s3Mohvo?#h0`D#n)JYS{m@ol5aTa>NoZ{l0Dvz z%^yj}{CzGoQK+GvVV7HZMyTVb7<3?Edsrnhzpg2FZMEfWk+nst=h+1tror2>Vr!{ z6d$0{zb}I9-+S-Qns0R{}EE-ib*}PTIWPb)Xm%kcirHO9;ss+Z_buvutfsz%w z*hv6|m-$A-U7Fy&f{NS+HEoT0=WJJc>R+Dv_p0mPC$*7Ut!|*xu;LH%b_*~97Zhr^ zmbxt)!?}9x8u$_gPVrS(l+%RaMAlIXkHZzdy8ZKt`tL?dAnQvFF&U zadjsL>Pn$(hV#BX{0{NM_@`0?GFk z`6k`r!YRE0eU_1d1)fLS&O#CgG!D;(Mn0eA6bY(iTXaCRIW|tnAa)DGYh}g24_!8E zPjJ{JufQ3hI(>ddFW|C)$9yu3%VvmhaRkS;WOZ^u8t15A-|3tq>%Su7=;#ndQ~LXB zmMlGc!AysRNcM;2C}YmCK4Q!&e8EISb^P56&6gReTXN#S`bUMT$vWUGWoXLCn>}FN zc388_U=a~th8m~x5}j!I>Xj^6^c1HUjh#>p!)(dF#w#fhR2fuQsn;j|^t`EoRY z>*yrU&qv7PkaVT(><0466782c3C~V5f0aF3&!+7Al#QNYMX*k`^VZ47Ql(q1M^{od zkZ~&@%&R}Q{7ln2GY^Bqe5n{6ebfcbZI1ySBCmZ5CVtc5{9B7qpvgY6__lk1Uo!81cXVHa5WNZrKdE#j5G@fF7_?_jFe3F*LQfuP-V zyW|0ZE_z=1I)`-65#4Qh1f(gY6K{=w&}Z&vh_=7dybA*Nr*Mo}8aP};WKT)x->d5_ z>8|(fL##hk*yn`)Crye>npCB)K06TB8nJ<{^L|S}y%BGABYB%RW$RLjb%GyeXs7w% zDHbTN^!r-;zTsOIzxS#?&tE9eDn$%vR-_*i&BD^Aa;0y(Q$(z_UGb+l1+Q4g&lXg9 zr=+C>le&(D`0GmmDDcZ>XNDCWA|YgP8p1Z8C|k4Wg|cEZyEgY%XM>O>_cQimL6E2D zZGoLlEMoqMMSD6~@eQ9W450_nb1N1WF}u+-K%BA)sO`r9INo6fd7K(zz##G0wY_BN z0D(`!JDAX|3-yTddEOZ9g{|R(#oTNSAL3--v-Nx?e}z~pQ8wqQp^9`cs*rCfEfU=H zfgMM0P`LwCHkm@kZ&+Z>HG^S-iw{3(_n}sE-!E547H_#Pbhq9SD%W?oqbi~T&hc(BW<=~ z3u$n~lfOzkX`Y-ETZk%$Sq4 zz%29jpGz&uju51Nhq-18I_hoZi<}|nBaEZ`QO#YzaM(qIk*3RE!=)rJv%DN<9?M@8 z5gCY2@}l`LkDmkZ{1SC}3YrIABWRwW-@O&gQ>pDk53ET2 z4*43X8Y@Xau$HFde*Gd!=GVUDsM@95990XAw_u|UU_LG0o8WAP$O?4Z*0-UzvjMuM zOOxod$v7P^l-gP>f+cmwmZZ6b@_d)55f7rWBN4KnSnk>J!1xrYSK@)|aQEI(9Wm=3 z0L}Nq`2c7e$%Of{qt>p4S=$LjbYVP%zEhzjpj@g1t2bAhKApsTi&VdIs1;>H$qG<& ztiv4qeR1A1dLq;6b?W17=B~|0Q+B0 zaI=!T)P$jOm+Fwm+%;U5wV2<3f#oE0!nUm}CxJQ4ANzI5;jhf17Jf<$kU%2*@QRE? zSP{J(HSs9#*+Z93JC>U6RPs1Dy;qZXYPZ&9yZQDLY#(_;nfq+?C(ima&^F*vFW<7v zkpjNya)n4c#AvYRB#435*ukxhLMr{eIs4m|ki4XBKv^nb-=Ww~H0qm(iDFnLIy|^f ze0HR{b?H&!xx?(*YNa;YPR#_vAg-DD)(n8oWq76+HPxtpE|B`iktNYOw&^SjdI1T4 z+vMt3rGuPoPJG^hUM!pinuGfTnv>1np9|hyXz_#t%TD5Jkbm%M-2Q))eotmj2!LVi zZfx`d7*kXt=i^ar9>0q)T*oeo4u~JSlvDiJIk6J+)fUuqt>)hEI48m!rW%-ax<#o2 z*+NegWVTTBdVf$8D+md2RoYhO5*tFSM6!^b)v>%8;K>dtGfe` zuy7*~R%5;v|CniuD#PjxJ? zg18z=D%5z6x(l+9G~;+Q;qN8HN~oce7KAN+fQ0}?C>vlJ2x&;zdL}f!LA7)Gw^AtB zX+JoT{m^K8A@Ks5!Idmgu!U+eBTJ}+(`PhL6WUi`=@L<17nV;bAn!}f$Y*T)jF#xN z5OH^xS4zV)Gs&Q6!mXZ?~j@OG5ou4VzHEp#~x3_?TKvbf{rJH;DvF zY}T=u30SM)RqIGIokZ8O3V#G4?2R^VT?7zs?I8-0VjN?~R`WQ!9jSVwo`EPHls|c+ zDipRgUtHct1nMPNn&pCbLgiDx<^0YneYq_it#~c(Bf!?Y_ZLeO1hewzLM@PLb`Mgs z52F|3Vcms6iL)2bMLQUssDEZWiNs#Yo7Y2pYFCbt^)>~ZsX>QZq9d%F`y3xfag|lC z{Z(R7yO!K_)d5Fptx8q-&7wy9!@fni@sm6??CR^BAfmuzpDZUrk zu7xd{8DAWk?5~pMFw?@5nsvl#zx6Gc`U!mp`!iP3fOBDkt}l}G==wt6jz^;_(rVd- z*WEDUN4@|k6a66A~eUI@F(y;Ct|6~YyvEQIV^9Y|&ZZKY}RtyVRrex;?Jxg} zDYI@ba}Ikg;|fBgBdwxea;v|7oOm4a^zojBot2k*)`9k~MautGM(h zxcrcp*_q7&MU6RldveBVhP4V7rl&bFKdjbl*hFjPKV;<%_x`?GAwVX~`SBOi z&>$Ay$$=*)X6QH@m?|?bUu-48*W$?QJn4Bh5TkG=3QZr9=J=P12hr4`Z?m=u9L$*Aw;aB_~G4&`62{SII2a?x_9kpTL2gm0{2j3AcL|`Gq#*TOwM~us z{|5AXMi0{oISVAj+eg^BQgoUxh=8_ck<1$=Ouyb5-g^h(S(Ict-04j@$a>G31Q~Vf z3-r1b;J7S2bMqG#NtHriS{M)cG|s-+?tw4m}0tqBwW}V zFpi#5*Sk9Lkh8TP@-+_Eoo3->5>BP5^Xi%^bJZLg=zvZ^HxHOr*B(FzYo>oM;FeE} zm?2#y6u&VDWOfZDg3tlOWCzws_aQa`^K9Gfle_N#7h5&Y#Pm&npIuu;UQM!VLJ6qoQ~BnIXCNV3zWn+MD4a*h}xzGWRFdHgYanJ*h+o7M<)g zcLCdu6BCOwO|?nV<2bl0sV!owF(*@r6_A}`4aT}NVbf=1F_j$M;|s<}h8vp_pI3NB z?3VcJ67(YyGrvRElDrDd?cbgkf(bQRDHOP%yHTO=!yVl=9w?^maq6k)(;&WWpax?G z{x>zg`$_@LRcySkG#a`188vkiK0DDHC+hcF{gm6wGF@I0H&de*CMRC3HHenz(HZ(V z#TF^n4Ju19cQwU%IG} z2krDPgGf1BG!1{&GmKzuq(^)-60=hZwXsu=|Bxgg3tk)d_etE9^8cXbRy~^*U81Qp z_u^Dz7YB8~;jVxis3{1z!522##(HYWMB8}#hj3u${p-;-uFte*`qS9|yJ#Dh`NwlY z;*hJYIOK9tDGrGA&$|t@DzPA4AFj&I)#nbMNIgNO>7$bDPyH#AI}~BX)kntZxQIW%*c7uv1Hp7UiL`s7FRSi1M?J>$QzX{Mg|v$+%>Vw=wJ)w?hwrw{opl0^T6V=N`( zDmHqO`E(yeqYX7I(RTM0I_D-7HG_iKz#*%EsZq2t8{!uc-p}b23j40^Sn>$IDXTkr z$PruYobu`L9D;`m~>E+k|)%2 ze9swnlV{&li4M&%kPWG%n+^+jbUY=RRJOC zFPx(hT4%M35>G2+pga<2=zA*xU$G2hNY7J9*qQQ)CDCFFoiQ@BTXLl!uVUSNKB@mp zH4T;J+hD}+Xw=_pmP_B*mYm?)Ekqnu2f z$wO8o61x<1syLH~LD>fP4}%;}dn)|Sr*OD~?Rv7`b12CNQy;R-Hk4#km*Ea`;!Rfg z+e=p8gc6KXXVs=OCs9&suE{nOa4u1Opp&5e6 z9BHXNF`cJN4jIC87M9qx@71JUmWVlHyHb?CUxuq!S;~7&Z_UX+l3(gFc4_ni)7RcC z=O%W#vk{A(WZrubCstcx#`LydA{s~sUK-h@6aoF<_2xgSkYYrG??))ancDbrlo$mV zmbFCezg$c25ahGJDyRF};gFO$L**IMW($cY`^ zYwr8Ir6(`+uVQR+9*B6h2_N5t;7M1D=_=UxRe- zyp8S8=w-l@U4U4F!4byEug+PrHGDux7!*$W$e8pg_R1Z=84;P09FgaJ!Bp;okflhg zb8MlyD1}$FYrDSDwhw}e_WVulGKx3(^x7GN=bLVF1MJ?<1)zfm4}%*a5U;M|5_BDw+yd4F__z(shZ)* z(@f+!@aHWftd2ar?|3z$3&h)tQ2e``8r%JGL*L)+)pxGw6}=^OUy(WWU1hshP~~qa zbzqE;&G*jsClvSvP3|Z>TmHH=lg)K6qLAp7m{5SKuZ(Mg;=*Je;*1|(abMxxJCawM z8{R=Fdg(+<^&Um7I@t_x9}yC9vN?v@T7)4qG83DeC6X8vgSOxo!3kP-dGmm0*;ij? z`0$U@3MZR2x1nD<;?&2X#=*cI)Uf&E`yZx`j2qeu=@tNisl5^iI|mO>xXQ3hV}YM6 z@Uc12%-x>Uk#|TgFrLfXZcEvS_+$$~ZJd<~!G^QqM2ck75a24`QniTRP^7z6aK_bo zHowY4 zP;n(V5TO4!&Tke)dytc`hrYpisF~+h1fqms*AH-;YNk-(p!H~^sQ+^Ei}kOAvOL6b zG`rB;I9DX(A;{UcdvxvPU9uH&Tq{l!+x8N}<~??~LPWQi`JIrFb}0ai-arD*(|P1` zV==51Jc-4Ah$4TKjpS@@Scqasfz=rIZ-uzJ5Tqc0r!9cE>iy`)`1!Afd}=Xgeb|pc zDT_o%Z#Um$BD3+@K#d%}u;DL=!rdhNU6bGQC^iCd%s^^+tqyQR~|5@KM%V2 z*?pi3_X`n47EsB<@ci#I+a9BsRK1_^#|>9z4K^nBf!Dmh)#ml?yMVx(fKxuFUX!pz z8Z@nfDSY(YtQk;rGb zVdlXG?5S)P1#DH$d=4_Ub_p#t&(L;Va2?xqA7n8J5$Rl_7C7@7@36nK`DKxZMEtEA z5B5f{nJSi?In;1OkY{-a!n`KFW(&(5l^)!bvvbKz$3GGnnzfCY&FgW==3Olwgw5Ni z@3Z%>t&oo(8*{cWe)uGU{& zz~|oDDEHo4JHS-vk>3a&N09}nZnn2pm3sCA(=yxY9cJ=`fx=IOU8A*Q|T>L7}DaB?yfJEfKL zO$*~EJDUC0Yt%<>rQ?4gyj7_-=mr57qM0*gkKL2*#^(EpKTwhvY8WCY0O%gh#;dgE z$Coo_ApcWSGK+AM)dTNJd=hFn$SWw@)#4sfSIkDLY3)2@;C6fn`$v8Rf|IX!kHPf2 zg|K&gm)#w}-2;yEO4!XIvCPIN#d&!fEM#Mqmkw|LrZYCWh7+Re1l1|jYA)kdYOOxN z1cWfVU72}!pALt=b45Q)E;Ma3M4QgZ8Wu5v|?m z-)HMTtoq-j&#HglJGTC_(pF4EWMPrRJ1PVOHNN3$lajN|o(8Tm+ga;;y3>sM^s$sQ zB*oEhs1_N?X3h-tHd1?FKe~+J^L0A9h!evtFMgIKeVcL^G&LKLworHK>LsqLJ?I*k zKnslT@1JqT{<4;{&y?xaSSN`wTb^=YVV6oxq?by;e(|Muo;Y7g4apiVUIEJ0ZKtllPXenx*-hH=$kt%ET7@$>9w@$)9~A}=lCbYXs&>Q8ZYn|W{Bsg>2% zm=!?Xl`hPWg`dlUPDx0F#_R*=;77piR!DT(@do)Ww#f-l>(qhMUni(i2WRrKG<~Q8 z;G7)cXvO!BrYc57PZ{T)+KE1tkt&rxtvaHwTDy#Lflq!(SdvAq14-A^h_1=wU^wmUs@1s0x&#pNB?dkTdQYb#V^7yw$%k}LNy;ZWs z?3(|u(fon8&#vKl@)DcG^R2!9piDb9386PgmHLA+HF$$mezJe2_L>6dA7;rRVIC;- z&(KEuvo;p1a}Wz4Vae^>2N4ZI4PVyH7!5Wrv95&UIMnbr0DAvIrA5u|o12yc8~1H9 zSJOupuDoxoZvVo;wwz5#n4X=}d0)P8I4@%3_b(iJe1Q)}tH1~qIB);LVaFHPYYU9z zMX2F)ddL=cEqUqmhv~L{LP^(#XIl)iBc@+JYG11b&$gHSn%SPsYj2_2Nqzw>0DpZu z@G7wyZ^49tR6dnjr|%Pws=ujq8jg9xz6v$WXR6#6{-d^$zVJ>IAYO}a2ku(+9#s=! z6LRnja2KpY^lD4`y3_20KT1!y=3Nj+@&V5EPN?b>Vb>ApbpJfr`z=``HIh=*>3Tub zt>1UMpI|ECp``P2a`nNGyTx8yxe#!-@#40ZuWB$}Tr1^0rUmy_+fh6wK=5AGfW6h~ zy7y`k8^&8*tZft5SH5pczDkxJo-fmHT-HOLFZSPyUxRkk^T+BpzGi@~oB7>uzx@QT zdgn@(GOlXV`sHFXA_VXPLMX`MNU@6|Kq)~Z&hbX=19RG3U zA#3~<$A!&8hIVQ_FW5}PVZt$Jw~AGhSu1Z+w#%VnwutJi>yuii3X;Plm(TJ^6k#;& zs4JqJgR_Tajv-!6zkP-^^zdzV%=1#ARBE73@h503I2!Cxk#!IH_`n5>`)-SWYQ(?0 zAX6bw>)$dMR%CeUzCv@awSgCGZl<>ELQZO8%9mznlzj=wUh)$U*r4#)GATM~=?oiw z%l2ha(6_o_&Ho|RXx67C$q+hIbYf?jDgQkMhTki^K2O_A;^*u>a74_4Q71=`v|&zk zPuPAZm3?i|zZ3a#8rgjIA^|9cZ4R63OT!223hD}~#-cWeU{g0_@l3@k#OmUQFMOPW zl{{c~s^ZG>kWWqfpFd0`2L|SMdT#ExENwXCPZ_-5X4q!WA$cnHY~I;th0whrLg3yY zogem?@P-JDdqd{5=y&l({kCl4_X?dP-W575yep!5d&R?gd&PR*W?fFn#6JpH6&Qex8_T@xz7YCbH6p$y!M^0G%N#L4qVb( z_1$Oowd~uL&a8W_d7NVYAl2oM9TqX)1qw_&>(fH_X|ne|16H&J-x@aDd{~OD!>P6p z{vb`V@784EtzKlRV!`44^7MBAzO|P!YYes&?>N?c0o4yMAHUoX3MiGRmyF_o_ z5r^`@L5IX`dM1;d4paT5qp8Vt{kfElXZbwr1@LSeL8PvBfUCniG!u@T3kl)OpT5j+ zD%%%LJ1PO~=imJh_l2hwJcF`$B*2Mrt)ji{_huiG=G$&-P*yXiO1h9w0`Hi!xHPX_ zVuf0KWGh&p`g=Hxk}bx^d&hDVxDXT)we<0Ci$CG`xz=WH7%3qKv5c*RWSI_wv}jFe zCP~irAih>RW+bHiAUCx)qY$IE888v)&28;+UR%NBCb0YwUlzv_@`s9`zp zMEqspP2sXvZEDCKkO$g41h&%j9QIcQdY>+~x9mvbQAGko$kSma{QyZ80qu}i{nu$& z_jOiR*Y&X>$hr_QZPg9H(H~lx9{Rf^z7?~o=FNY8MpFNyZO^NZc_eD>(y<8nixbYl zZ9@3yg!j7s8UJa$)*U_M#v`Ihxpr1$0kG`*dT8ZMd>gTl1bXQ$J{JTD(za8pt zhs-w3>9(sK#GGIx7{=M7#hw+M8MtPbPZ%2==1mxj&Q37Yq+O5!6FQWMZkN(#D_;DaI zWP>NHvUUh*sORGs^OkY?3`!8sht+=!31aeO(>H;u-OWG;6-3Mf$Su+F2+diDWDijs zxS1SzHT57CBB91-m?TNHi~>*Bf>C(uGwCcAMM;;1Sh0%7Xp3;v#RCwwXdVO}S)w}f zx6ld&zgJcIhQI5Vos%Po$IZEvt_bg81!4y&mmG*Rx;$*6{SoC>Y?-??c`~2cUh`>W za<%y@^qEU9vm8;G;{Rl?nqQclBd3rZ|G3nYLcg#gQZVmkzz&@(Gx7kqPJ_`<@<-Xh zRFgc<#Jg2=D7QH(itVv=&3)N*)OJ(Ta}!@GF&~N1&gM+k->*y#ztcewR%A5^C@ok3yPTu{e$rDO;PrN)q49 z86d(pSW>+-fPRKI~H?6xEp_$oq1r23ciDAkX@-l{=Hi~UA* zoiApWm>GZIz}cWNb5sq|}}o)gFhL(-NvuVG=6%f%GT;W=xl72GvV_a)zPeZ zs4nrot9kPhDorx7Lac=vbxnr1({caqCIx1rw#f-QZu^;Xos3L!($lY>#CJBJKUq%F z@?DK5E#Fm3=EtuP2g`L%ZcZ6#E>)*Rpc{U!jFsgJwF1#`uF6EBn3~YzuT_nywYIJ= zWa{#F1tOn_DQaNcV0-t4nN4LWJ8rik@eNuL*6$1S#vfNyvG5L-(4h{uoLUFFl)-AS zpmNw&oH;>U!oG_n9u;(%6ENdXYi}C9&hlUwWB0*ra_n{8Jp5p01;3yoQu&?@O?_q$ ztC)u3=-{BEM8L3<-8PqQXDyutW;6DDOOlw=A9e(X2nz@UQ0&Ch^Ta(vsz8U(54=tGzZ!hVx9TB4|a|NdiQSjuJXutTfqYT}Ol7|)WH;uVD zK)twOosdlS^ClD=XS-pe3hCUTvA5PiVWq@0ZL+tqhB;-9j)| zNTsr0+-}N;IWJl9oMc@?)OR`^({#oPQ&&iM2Q!0!uk8}P6Eh;5c0Sh&n0opaYLr0& z#)<{0D^o){F};kK_)du;Y}DMDU(JXj*u*$D_|*lLslt$L3V~Y|!}&nL2+xzi%v?i| zfoCKt6k1VQ7U(gTWoFq5;V1hpzUU~Rm?982)QcWZ2F1Y6loS?WO% z1H3V+YX$~x+i*HIv%LUPF#>QAd*4HHZI*vSetMyXO$^dDyT;gmj{cti%X(0FAE z$9tHB_Yrdrl6VyruTW!td@qo)*Bc|V;qv;U(R=7i?eME+=9#~LB{S92mG54ZMjCZ_!C|;!Zk-8%M8Y@g58)~K4`^+VbBDl`<*>O$ zgB2eUb$*{;&vtN_88|ph_46%_)f5qAXYEvm+ux7RXJk;$66@LkCwrr3q&+GIQLB7L z``|NrZ#r*D1SRtxGnK9dRuSMAmuvItEa>J$d%2r&n!b7;d4u;y z31s84YX6n1#3RZmZvMBuG@ui6z+TRTA~C;I(WP+HW~;86ws5sUSFKyQT5Sv39OoH75 zNoW<#y-!LFtItyl)n$94!bT7I?T4vx6|VmekL9h|@F~PJb)Rp(OVi!Agz4S~&aE$w z-?^CxG_Ck(Ia=SVPY0(3SI6&cK|HzOzeM$WvGu5lX4MTQRkd`};g+-OrIo-NwAI}2 zvn4t)^-A`^Mza2Z`mr_K!rCd1+We$ULU zh$R!@6%ou;mvxP@axbk^7M2!zmCKWu%#fD$fEQk#wshU0@&7^~Va>u5l{-X}Rxw+$ z0@|auqU+$DCKi`h?uZqY`!Zz+H3|^RCq_aI^SPh{vxkXCUGMJ?W}ei?H>EVl8snuTtU7`M)JCkvF9&PAnQXfKX#Ouotgy!Aw^6a;@3+MIdn- zWVD;5dU*3#Q+y`$(%?Mv=Wn}HXci}YJ`_*1U$ZEpIRZKqctGg$&!;+ z6R-jI_2^{+v@WrNJuqUU0K=gKz_IqAU7jF1GBCg+z$QUE<3MUvGQ&aJbl3x|Jux0vhahGwmN_~ghz~F#`BTh7WkEl&FtJdwI-h** z{?9~Q<3o+O9qMtIzfZ!wA5g5Ur7nM#*Kg`9rHcq+31Wuantc*#i*WAkuFJoD zdg=D)XX0(WqMz2!#rnBMKOuf%Hj&q>$^+NMS>C6}ZgK_Nk$p0J zEVtf-!iqQM{W(cQ7CkGT=$N*VC=X~l)R-b9*2LhG}Af$d=U#YGE@gk^rY(Ao2O07t2-)=@kZ$LWIl~Sbz41# zCI^Wi2rp>obfkdC&xSgPP)M@7_?V8?nNYIf_?V-*n0L)9o%}W5|Lw8VDGedVh7fsDnFHC7fv>hv-f^-HA!zd!Oa zn}O^@~FHT{S%!{)~Zn=0W1Cs(=>#Jq+q!Eug9Q1 zwz(;!Z=$E_hx)susxe=mVb$ful#Q4#2&{_zsRhYCi1B6=K%fVvHq<@XA75D7xAcwg zyy$0`v3xiSRjkD1R=|30!psfAoX$UwoV2L{b4xIOQH zwG1&8LpfkO{9{@)op5ssW_Y8fV?X{F5)~0JgR}$uA=&_5p%*C-G9)RTKZk{?qa(G8 zY07j=fM!%WfDUIIwJqAmjHC;um?FYJD8_C`kB)G|nM|QU(Et9>&}COLCb4 zZ+sysX6gobaY-A!c!BzP-;REHPK98VQ!Seb)X*a3lj03G@aZhi+T<;A3|d^=ExD%b zuOQWnk5DzkZqbQa?Zunyn>G9fk(*oU?x?#X5~=axI-EVL%JJfh?ez-#E9sRN-(!DU z?C)lNQ$v;^q=@_KC1WPYtS-EGt1Yp^{_5bzG{F99`(UKNufJ(){0W|MnP;9k*-dv{ zsy0%6TizYd@GvhDh?T^<-|?)TxV12g+t@vohwtzP>EUhLHtotIcABFpq5<@Z4&}E1hfDJmfp?Sr>xNaE`M>)B+Q8qE(*>Y6 z-HCs-q2c{#=uHHkxeZ;BY3S5{(h#h=c>zRbzds}0(ZAnFM~m$CsWy9l>-y@HJO#~{ zKF3BFc#>t~>I-Yk+XF=f#2$>NPK%DN8)fG6F+5sFAa8~2QQVTV_Tj$Qf!yPWWfbl1 zs5Vt^V$nQrShAw-8Z$BYPE#0sbn5=&KZ?(~Jg<7|_+h637Uo30-#T7voM)~-(Mmc& z0BeN+zQV0_$?&&3!P@gvP z$aeFE7S1-QSWILPD6qQjL2DZ;B0f_6+I%W<@iO&5^iuYFf=*eg+`j8I+5AwwfU#>; z!)cn^GIr6+CE8Xmql3$>y?L~#JZ?qZ1$8GSNtPiwkq)iQckmcCH#~i8L59oheJb$V zRqmrY61a6Qt}0}{mR&`l$-b2_o5LYHnd~=$vPd{wW7a9oBg*tktpWaNFxUD1y(N)X zhF&={&s<5)A8%CKGxR!mGUR4LdVYud*AJaZKnE%~&vwl@V?&>rd#e#d>}4AeTwr-O zVjoss7K`&HDNYC`%saZh=Umun&I@{Uf$h;LxjkCGK|M+i47&5sXY%qURMa1x`;*&6 z*<1OWLUurI6Ld;IU`7xIC9ntEKgD$oD7nZVNXW??KSnVl%-@=B^A`j!!4#~l1=FJv zuXp)^!ZS zylH!nhac$^jg4Y2=SO@YaYa5{I%d(XnR(wUedCv%`9L#Szr*eMee?_srXLp{jZ+C= zGs}rB@TwvEBlq7R~{*fjV_N2jh?EAl~ad%6GwQFqGyVLfc!1_ zdy~UTk5$ySKZtOrT?OU@1xm-L1Zii>ryPo{^y&6?^WV481{tWWNd3PG0)I%ELuqPP zbemf6OQG8n$m@G}AIQ#!-x{!71$Fssl!B@9VTDR}Cs@YP0Y(E-KVA|Xi~)BCi=92` zI77CmJ5FI?=U$1Xt;%bCx9(|&?DDTPpD9HC-tnMZpvQ6vkX9bnRPW5+=#4{WY*_V* zjSrG-O}9`mkFMlN{=|a(%1%Grp;E($2AwHoCx~ZKJG_xEwF9n`pD;y1sMWJ4XJp!^ z$XcxX#&?h}vIp7vDhv0cUKZTj)LrjP;_LcCG(s|Q&_SM!Alw9|J5T})XTJq}&bI-; z8;PLlTl~qRlOtyLTFZXnG6g8r@)Cb!r$Yk&t;}wNjTNa~e--%TbLxmQ$h;8Ie4fAR zV7KPP*`=;n3=CT&te6^5^p1Pg@@8~0Fn|TjsMu@ljLv?Hv!QZeK*lYoEaugGSVg2b zr?YJLzwrg{I`f8mD!>mMo zyUn7UZhKU<+4>XF8SS`DB9@fD1w+1pR@+6RVoKt&hLjLIvbBa?t}wL(ZD)x_XJa3U1Lexs#V`y|DFrsF@m$ zY(!-J0aM+u4WllkE%7<%%?8Bh6d*zT6VLtlB8m|xsA6mEBHX7_t4F9|w)(Pe>yF>4 zA3NanYI~H=kS2s0{(994Dw(U9QFONbD^#=;i~JkWuZPH^Hq1_^TfhYnpYRF zT3aG#PpZ4UtkC(m=M61$PBS;1hLk~h$U&Dj5jhnp2V!EO*s^r3k7`#;ClbV<0Q1Z^ zi|yQMp8q|8wt``iF}sLT5N49}MbAsTQpl}hVqkuB*$i!eh_YQj`6yKpE+jVr`oq|t z%Z78$keWs7i-mWB)S5oB|4KID2L ztw&YjDc29kiimk}I{iREcOb&)m*v*aGy#!3mw8ia$S7b@q7dB|a(@ULJ79BYd3bMZ zEncB%%H-ywfmx?F$zQM%0MrSZ zvr0fI)HByqrN?Y1f;%$2st?AJJEuT_=G7?4qe1%V|vlZS!G)NL9hN0wjyq2 zd7;H>cn~}nSF4bv%qcc_l(vf_G!N|>J5(AwoVcb}VsJ0N5-HGu{Ks7JcCVLre}Q*b zp;v`?I-nz;`p{vEG!J+uG?V{c{56p|d9jl$Yyau#d1lmA2p7VI$%!%vzOk7QDKD#t z7T28fV@s_Jp!E5;SS>G60`kUKEs5vrT8{@B~Ej%uQ~q}7yqDlnqTr499C7P zIAY!&11FrAh|x-+hX|qIAJA^r3+2w6GPujqZr#yRvd=TM5YmuOX&NjCjk3s+y2J5x z!;ZWN$iC(k&@Gz+x^MK#k5lREkz6a3@B4e*`WN|whKpw3sE3ffvTa(c=}Z$GnB@wu+g zaOA_`TWNkS%f`_a;UX|-B?5>Ozlrl^eJ99vCNfi@o1(nt4#+1rloImJhfT!PCfOT< zhFuNQ1GPP<#9nkbgCNvb7*E`NKz)_XkSOOH*<0BSq6HJ6`H_M|(OpC$%C~AaOq33D zpZ}&evA`m_v;eY=++291j9Ig5CM;j6|Fk`t_d{hWFm9ISk$n<>K`(LrvxWVIwrET2 zhT5S#HkXz;fr@4xeAgeSya{qoODd|;Z?&ZGxT*E#&%WhvcIa3Kfbnb<<7 z*L9?yv~w7MV)3n%LC17N;?v#4&CbHq0ywi8IvRaX<5K>D3d;67XODK|p#)FzrhyHF zwk=+j4k?3ILk&tdgiWe9ZN2-Z#hbR-n?|0?xqM))V~La<6Cn*w#>h77+eQTjm%-o; zINlxJwB2bu<4xNG3*2RaT{kE-WIokdKDX`!FTB{@`<1(?mZ$y{NRmPlGlX~KD}>O> zM8Sz(xXBVM1czDUFSNL2<1aswmZv!pUYRw5`Sil-`3mcLPi=c#0KCv0LQCx-^t3yK zmI|+({sm=mdZNk(iONO8saO+HZ&EQ;ojHWK?;3DyPwed0tWU>{M*2 zeQ%E381Nk@`13mvv)cW?`&=s~$20)`{}2aFd3Z^vVV(BE6xi8zKejkgaC#(Ba9M<` zRTf=KI;?f8)LB}UK1-wh>ISv_8qyC`>4$gcZ?uHr7Jl2S^0$CBgz3|t<{rbL#(K3! z+L40O^i`y)wEG9gwRJ+=ODCgWJzUrtdt=yBpDblTz-CO!kwPe4dl})8P|8aQ+ zb)pSij-3}BqlvwA?Oz&_b+2UprgTm!{dG^%m)kR1DsIC`#0{z44rzy-#EyS9sMrI* z%uPT1m?$IKIqB&qY8{ha<>;TDCq5dIt>R03Raew@Dviq`PDF!RcH~plC$3s_AbjoJ zbpzV|VAV67d;lY`mp{R={t0dBvx>S<+Y5ZA_N;ET1KHI-hLHwr$Ka%6{pwC?gCkGX z4Q#uUKUuWf;=hU-D9Q_tyPF6ClFl@K3LD|1^qxszCk5@-dn~BWVZJPy3(|*xPs+lx z&zS5LNSf}a1}U|w(ERpxlo$Xp#nlYltCwicHRPSg?(vB#ki7~ zjU@mvhE7uC*zevGIcDjwte#{#@!Rs#8y(8TkMWwlJ32PhcHC~k8mKkNgm~Osm z+v0$LQRf}=a-!0=1Sz4O*R#CoidN|_lz9m6FT+z^G0l`SigR+|W**01(91l6Xkc~z zu(niMq|Mkv_YqdnT2g7-%ZZ$S+c%%_9R=( zbHxUz*ba&%e`n(#Q^7a0-Wa{vP`m6k`^^;lCiY)8jxr^~StWO?h6Nnr_I%W`xrjJhLz5dQkJBg1ylsC3M@^hGyFhtbJC8Dl zxbnP$DhR*G7BqNn@~2&vWB_*TV2wHUf<6C%W{C=JXL|eEphaneP?1T3tA;P@o&T!ilN;`!^AZf?@V1afD|&|-mN7g6c{vG5-b;9JDI|$w;6si5_%gLx z^t+k$j9|-3GEci!u!S}r6C6O|ZC+cbb*|qhQ?O!FsBt@wk%RO`w&OQ-stZ|gt4(4Z z)1cS-`>Td$3jmsCbK(FV|R*jT2<7IZl9i7y+bn_q$`h}W-}F? zoPIhC@Q6RF5_w=d6i0=5u?zi$0#wjm^i&|Igd&W)C}qJnHN<}Mf=c8$>n8f=z$XJL z)-k!h@QhHS9Fu#R2gz?3C?Z@GsKFeVUyo#>GF1}uudQl z9#Xwh1K;1n_qe+7IbG?B4*k@hg>cdnp0i;&hg=v`;-a`DK>$7SW_IR469XMs{5UrV zu)n`tfnMV!h(kyFQB1}Xi*epknSyT>FUSWnsQJq!`3>kq-Zu! z1zX_oXtn?vSOqhAlZo^RxK?Zr;X~QT4zwY*PfH3I$vRrp1_V$J!66n6AAkM}jHVr* z)+MY~Uy$m+Mj*x!Jyh(4cff+tAVE9rYQu2s@dGYQJlI~FoH3BjMK22A{J|es5zQIY zAc1@lxO-x^{$>J(`^FK0GIY2C??p7&v4Vju$qQI`Z1j@(q;`wEayhaN^YTh;xrmGX z&~RoeVrC5JjY?&DAhro+J$i0{V-bowfo*pjt5K4E^$4gvO)(AVBA5t7VK?pm%rX5l zFh#IwlQ^DPZO=(I>_kas#aIAqIQ*LWiH!B4?Z;9&cF)9@)7&$XWm)L@ylx;-I(HHF zx19ie=KN|WGk5W#9f5!;10z2nkn-M7i@fMt890mRU~`{h`cwt+hjsA}-ghW~_61m;n9>MXzVtZu;g`(O4-?&+}tV2eF zZOz}ep|EOaOSJk&6EQ@v#eSh}gS#E6SPR)n?d_^a_Fk@RO_rOVr$24!@zd7Kr#I(( z+M@mFD78D^)h=?(H!(dY~L7~^r9d!U@b*u=F*{h^$8`~QPT-ktqp zC;AJ;U<87MEkIV9;TlG%wYJn?JZ86>7wz@QGLyBmycwNpD9VXJ~&a|Jy6h!x1#MS=4ChSvLnvwA}LNzy{w0j$%?A=ysqJ7MD74w z@0F#@exlhCvh_usA<@1^HjRz;ns8)OK3Vu%p_te4C9yQs?>(dsDmFz=(!gs)6nBl2_2g-<+Am3pg==+aqv)fumfIn1)O3$l zAAv6Av!Bikc&KpEW@aoKHLfU*4G_}1y=}^S7Ncm96_u&TpHgh`2<*3hEU;*)Zl6yC~uDHufY~dQl z?>)VUUy5HW0`HYW4qJ(A@gKGCA8pe0uE^H01q>?B{OLRhiF@b_*fYoENO-jeTpK`# zasmg4`|Qgk)FaeO^z=Z!v334RR^C?sEH4@DNp<;?`B%I5)tO?E&llkBGN&#UEFdpo z_P{=lWwTbK=&|XX6n{bo2`Bv$!$SrhDg<={Br6X zrbj6&fwuw$^MgyBXf@P;{#4t$)x5pWt^PJ1#P96jkm^uAU-qh!RZAI9@QK6zY{jQU zb?$aB%Pz|6yL_YR$RXpHjz9-}v2Beg1=?i(UHD6YJ+JsYv;x#OmFCnJeDlF2u7`3X z>%@(W+Vi?CN5Fml=sCF0z_5V88c12q)5u=hFp(pKFL6hh0x5*DwzINEc53R+>+p#I_XP^TB@7 zMo7(B3rWH0PjTqhL*o74R5oThBjt+u$Mo+6d842Qc*^Sxl zVfqsqvMzsWQcT_7@u7FHNkRD4f(u~rkq zwsC8p(J0z%mq1TB!W$aI+%~-Q?AQ{8Mb&J0u_y3@jNai|KqoEbFoBX)k!$U7g4 zaN;F!S&2UA5O~~DbFi&b&>#zg`;|+~cR;9^9L1i1ha@DD(Gnjrc`wNFWhpWM4k8yj z$lU*Z;BQi4Ufv4qkp7LoIvgq?wwBwOhfu6s;p&aouO!hA6`p1DDGk+TCy4z++UQ%u zf^|04;$&g`&IVjw7pKzrqHLQaaZ5Lr{mQF+*qgGnd`d&8VMSkZ)u1|UT*`$XUIOjA z!sqZ=?zXuD#>ypNJ{D|^ziI{5XSR`DRI3cFB&x6VC0!$0GSo0p#b6?HV4!kM1_;iy z<(pjLGlIeoXV+cXWD!flF~JgEsz5{T`)2q45B7aijS7s;mi^Q>aefLn*=Q}PShFMP zcOMaWgc_dLcK}2Vi17hfme%Nc&WlP~Bll0#uU~_fPhJ{3l*Pd&Y_Rs0t=WASTv3F8 zLHurpURJCdE8BC*#}-KIRE$S~evQq=z4n(g@`x5~4XgRQw%_tg*Zuk>jyiETQ}#Y9 z>>7bcyYO(Z!8Tq9F@juCOM(1vwR&dl6LStTJ2!H+3Ff8w@Alw5%i3J!o_lT@8)eP* zKbtYq@M*bc`_?IxZO zk@(Vzj^ie_M3pYrjAYH5U%8^RayOA!)RN%k_;uVHw!+9Oyfu=f9CGjA1W z_DjPO`?MX05cwd>cM`RkWQ^La@i9%iW^!8gYnG&yP#N{jJ+@T&1S~PU;YzW^N5u!5 zp~OP1)mLpFX=Je_m{cZS?&R9C$t=55gG?fvNMNZOog!^qchCtnh$N%s^wi{-46-dE zj;7ms9)Q7VBfNSf8n!&!pxq+sqN5d0;Xw9`Is_a2lt!~S`-R(P>8bfw2V45IAi2l6 zi8xrk{f8FTlcVhcKc^3Fwev;>2;ewm%O`}GGZ*kpvLCGHEzj^VJ?(ye$LkyNFp!8& zi`Oq!*tq(K^YCP^T;{JE#h9ET&VT)KuBmOvV^k7e<~8Y^*Q}>)vVM%$FNM}=<|=a> zhd7Sug9$%H2iQ_7ASnaje^J0BiSCQvxd_s3QT)z_Gh}jjS=lzfevu!07-@ECvzjVx zQd3@9s*Mn`%CcdCFX>DX1lg0ok1c~R4%elmXFN!NQTklE57sBVDDm28s_;3uAF`c) zL^UGjv5*vQvUZfcIzH~vjxv6pD4@LLxPYW+oQq^4VSgRXGCv?#Ko|2J5BT3NK#ZM8m2QzpXKcCU@S_#+*Bl*WZ)2yYUT$Tv zOdACQ0`44eDBGe3L4Yib5ZSyxex|sMD7GfazjPlZ3_y<#FQn?|!N$uQai4tQYWtPR5vmU;a86cJvNpE<4T7z!_HZ z@%hw{haomGFQ#0;iNwweMAtDQprFOW87zQ49N05lrbHd5%!l`$2Isw_b_De{FOs8Q z_3uNNP-9u!q-EdMdWCWE>Up%pt6%EXKamzk+Y)IbIM5T$GV}}H1}y&mzW4W5At$Dc#b3G#X7hoF zX6q=;Z*A=4R{@q24{;Xe;V+y|dFka@r&9Nj2kYH{RM=ck6AAlWy1t5AX|%7Okk2_= zOv8gYw{Wg)1ew)sRaC^{sPMs zwLa%H4&^b3+qWL{)d7enR5pGk6T|f+o+!~DSDF845zTrDm6E}$0zf&LGwz6u z*ifVr_MPm4uPVp#a+Gg7;jKm6n)1e%l+Po8$zSLnlR37ieBRLLocM;IfngMhosy`; zdjqpaD~8ya`mUZP!->Rf{vP+jAB(MV@A5{~5PH-ekbSZ0PFOqFtT|WftdK43+0x0c z$2ZvVd5yN+(-MhDPc0th%@!d!-RcAt^Vy-ZHrOr=YOf@QGb8Zk9$ zwxxnXI!A4HfDZOSL85-X4siLb=6m5qzMYxiZoZ7!=hxI7qlL@aEWSlXwZrGr>L}hs zTqI2Y-dZ-oY@&VS_QUmOtw6%|xofv*3(*fda5=pmWUKmiS5#B7X=o2ytK6bMlHFi( zS${Ctlg?TmYkM=iQd-Mi(Hn4fiWVhs(5yeGag~85f@tccq;f3D+rhyg109E$q%U`O z4*AUi1Nbg-XA6dBa|&t#1onqa56$3jsk3>EKmoBo^S^L@P6%amVHq#>_snl?1+n;B&J6^nPz%tMz-Vk;>p zQA~npow_D~EeXJ<9QNPPs&2%^tzt|4pv2(IwuTKu&+~XCD+zr5N;eT|n72a{MP=!? zm7T=&;ytBEK8)AIc4(l|-B2c%`&U*?n(PO;P8A8;f%3FN%C=V9hsq_2wWLdgonS4w z2uXFkf3v7lOGRC^4Jv9=?ExsB<`K_BBwPkrg?;3c!;XSc$K3q-Ojb1v1<*!`c;{)@ zpl}f}&D+^7o!*8Liiz)jlc!SXte_8>9i(ZnQQcSS<9Q`;+dt&$RRzZ+LY?{JP)BGa zcvwBzT*j^6fynbAg(LGCFIU|_);D-f)cB|5Hy>)4$z39G4ez#2DA078&prekH|mKJ z5J2-aK>fHPW?+8i@(wP2TdaKQ;n>hx1N;P~+UE1aCKk}Z`)#Tb8IBwJt z+P)VEn+K}k55MTmBQ#4o^vy}X?n}?o?_S!8AwWO>Ne$4QrkM#Anp7sNRo4_`O*>CP ziHQ+#$TgFxwJv4mQNO=d6PmC?VwQwf&8fejOllP2bJ_4b=|ecc)XPS*`Wbza2*%$} zNTe_GT&vkJwY}}+s6IX_WW0(CG5jUQyEoa}|6?7^sCi!Yiy&>k{#Sh&Uc%;Fkx~6+ z+$R$H+z54hNrAjQ`@y{A*3E4B-(l?J z+kL}HN*To$Y#d=L(5(!N9s8JQ9IAVBA(QW0VDd*>wKRm8zI$Ej!g$O399;S^-f}EL z;K+1u)g`*NL4OGux^Q&JX$1XoCEkS3n-@RU)LKlxu$Hy5JEWFbNPHImC??yjwV9$v z7Dmj!X^!lU(khow#{A|Np**oQKP_{J6oxq7awOi_@4lN-!yAt!$LE>#2VtVWeY`Uw zh&Xwnc}i~^d7C_F{$1A%y53_R(sf+dt>&(KWD{GI_ZHRZ|6lU|YW{BvuJu><962^y zTTM0m)ki39;xFt5LUG#I!!N*h6=!;&za1H1@sIDN9gAmL&78rOg*`FLOvrQL?ZAvH zvtf&!6DX>mBQTURr$X=pUfY{p47^6GQX`FN1*hyXCHGst;tVc_aEan+8)+7+oL08g zET$BiP`Qo$GX?p@UG1LJvw|EWHme~2`N^17Ixl&J)-A%mfEZ?jm>wbg8?%WMhLzza zb3-GD2{mnZu~l8%j1K&Eg2V6GlQJ_fSUt(nVKW2nB(=wAm*tIPhGd~=C9n~*Xdi}H zL#km`oxxwViEp)2_NVpW&T3~`AQ7Ti?aZn4%o|xklN{eAQmZS?XKalrqt`kW76SvJ z#;X`Ft&)oWre&QeXCc9y!DQhW3429^} zCLSlWVC5k_IxyBglUsB}Yp9_GuyD>-W^GhcXX8HCo@kXkPHFR`Am@ZEO^CnB`Br93 z;w%FposW;=s1oP&(nTu;-r+-~;R81C2b}Ri`KJ&VlQ5s*X0LKtqH?kDSkvSs(c^qr>p6ZKA zsibmE-QbA&)emuALF%e%b7V8Xn5KnFTbx7*d=r?hU0l$PWa}KLQo;$ctHx$ewhrH2 zX5}|9^}Vvo7I0`FtA76O41fGbsCH~^2iEv^U6VPw>HY1QC?*6SA0wL-3GPCT?`V!6 zk{Jd;d}UC1v~0ij_M$hy_zDO;)t^v|_}%4?j1Hq0=iMc%E!ku3GN;+=E_*C|j3*RV zggZmu-Nam|^!u|vN_n<{Af%>iE!jW*yjq2ZW=<+L#tJY2K2JilA<#wAzV9?G8?BVQ zNC8VFE3Qh7A~T9ZDUaXU8Qwqh2%2&u&x&WqjHHr6cfbr20K{-C271y{?A$vyi&&rX@ZeYhUi^5SvUZXskFuReXB&zv zm{=mh!F&muvcR=np`$n~UJ=O+OINY+zS3yq;%Auc=uP6Z;aJwN7+s*)9%LSaE_FKxZ@++sd%O6kJ!`y{L`z4@EGo5?_LD!;NjI?2b*` z*uX17H<`B3(H454I;M$jYSnI@n$8tvP_&Zo_nh-4O$+Ys`|h`UrFq};_dVx1&;Rp0 z^3PQLbCUf0a!}n|c~N}Mm$ZsFUtW!sf6mZVvgPL}{WFuFgp<&|ufWQgI=bqqB{-jr zfVEBeVwC{Bmx-gBj$p#U}?lROh>!9I(>IIrxlaJ;+(mH#c>V~>09c- zI?uudb{sz)(+_uTyve8FX~XgY^~>GXWu@vZjyLnkF0aWn!WCh)MYMvKh#4pJU{CIV z=ZFoCT({wvUMrqxC|t0TrH(z5S-D%ZdjwecM1(a>0YwL31(e<-A%x^m6CIj;^^| z7I+oMOZ(yyXV4l}SmFv~64sD7IoG;~mv@z`u*5BI+`Jh{G{qY^kEgwYnZbq&{d$8docBFz5)1kT(os&Gl@&NO>~;G~)Zy`hnDHI+_Jc{^D zf+kzmVAYV&iP`y6wHp-O{9Jb_SeEO0gf{Zk5*oZV5B~Lo@vg?FElecg~^#fkwj-xuS*&8I6Pz?ntdfv z(9>VE{m_XecPRWwgcZ>Y7mnvfi~opx9w%l#0rmeA=WLssEGAZzy~5M2KtBgH>FQb< zen~OdFZ`T=lR19Lh2H*9u$(#}>rVb%IG+%Yd|~ny;xs*q_OAImQRM7UQ)#ylCmO1q z@kyO3A`kZ%*w^R=(l`}wnMaFhiFYRMaby{!wUucE;FT!CMw{L#_hWFuM9X-g?Gx|wRtUP^BKdrT&f;@3cAaUtxR9WP2X1a8TOF8{t zfUx&>e|ayVE>eP~_SM-=t)teMg}nvI$Ik}%4IUI}jEuT$=W z_h^Y!h=R4x>Qz6g6{6JQSGn_;kFSNUDu{fsa1rqltpIaT2_|Y^zH0oo#)}fbpkfE@ z`h-n*OP8CERIlj=^No6u)QVTMP+5_!rcL}9FDPt3c%fE~A{JAVYM3iqrvplQTgq2Y zTIgWOThxWGdK?lf$eGGVmu}X z%RU^ilX3y#5T8`B*3p5?7E>P)V&JL%p^T)Pl@3&~J~2`j@tMY3YoyQF zr6p?FG#EKub)crHSJ<~Ka`Fm(RZ-zgdFfbN`-e=_VwX2LGOuQ$6yO}vp#+l59%3=C_+*Bze>53%92DuRk9L1`UV1yu_LWybI3YkSrQ< z+`!qN6$}W}AprzL<)>o~Am!NS5XJWa?)lm(9B-uJ47e9`WGJvu2XRC6AbFwZs#Px_ z^(RG{Km69F0K!KfQcrA$vWv`;zjBY8{V=Wo`$RHQFW)bjUfrO=|5|p6aNxG=5$su% z_TBIWqRzyvgs7XD=ato=JVGb#tpmsHQ!g>L^}@{piAO4@TeI%ed4h0++jCQxL_6fK z=JRYOR9le)O}wb!7MqCGmFd!$Rn>5ESwiz3cM#^z@SvXRn^;`jZ_lgnRCrKIi2KJ@ zdXh6CF*VJbO}r^dtFckn2<(Fj>)Tme2&S$E3!^+aZxOUe7y8xd{4VVC)O^Z^Vbv6B zoV>~l7i$F?%=|U7M=ysHnXgv|RkB(OihDxEJHthpH-?IvF7h=oxs8Bbvgel;(sN_r z9*yFJA5G33^^^CYz8P0gUs=e1xmtoZQvcParhHTUMS@mZ`wP5H6{m}*9v}fc>=bXs zhn`1i_QPORWNhGx_^FNF7H03@$}FkDU-&yLp1%Ae7bTNw{RNT@sPbB&CEUysvLRyf z&sJlI1zBdpdsf}XvN!2BSfHBFKb=O2ctqZ&OVszbQlYHH+TC5pU==Q4;#sD_tM~~1 z0cN_)WpcSwYxx>ffwaSXSy^u1B>&zgpK>7s!tD;P@^iZ5*VvcH?@KF~%%`O8k1tFs z5LPvQrhSQgRk;yJyeCJhnArgVs+ZcR)@2?F$SFX<^ znPDe6B=_1L*~&LE)ARjm%x^hZeW9o2jagXm7rMy(p@l9r?e7#Cg&k2K!E@@Z-3_DF67<@=|qGS z6TO;vhz;VU^S#si^+h9{!p)ju#!D%N3VW+=I|-ws)hNM-NWiUAIiZW;s%{dQvzlU- z=;i#|fsF*)Bt1-IuYpUBZ%giZQ)gW_CMyb<0?R*t~&ccyMX(9nsJ}H^J?KcycLabo??vPa{c2_Hoz5b$*4~M^1i=c15mW3Qs zxSh(8oU-AeF}6Zd^C?en61XNv(45-!BAzdSZ$aH6z6QeaNkF%XT$FLw;R_=Ga~m%u zMVP009=|L?!3DMjxtmAiGs(goM&Jz)IdCMW$BL9-CsOlwXH%-QU&ndUCa~4BrI$2N zFXxl4eNTNSv3umMcCQ+}n{{r;(%$Jnqq^{HVHNs8MoC9RURGZCDYo+f4q+~F&(Xrk zD+0wNRQyMtTpPyxoRMm9P|c(Pa0k*eP0GdX$LbS&E8UkK+-PqnB*1sH9an4Has5uhh8(pLz415@$;@N(z{yn#6M}56=kLs)M&X%X`^`rWz zJk}bC+WUZ{WEPs}@)Lrl=f(Kf;1s`EDCXyhTBj`Lsito!R_yjSLTjtZ<1-m7Acv&{|-f4Z^ zg>B(ROoVd5v8a?!?&So@(umS_?P47bym=Q%VB|p79u#nRj7fyTH_2{dcH+DRHUy6+ z2#XcS_EcAAv75c&KZsLjI4u8aHsaRFynay}R|{T5DUV}YM1JdPAzV8Hn>^Lm&{TYz zX7JaT(bbf(e0_}!rEi>0cLA{a-hXm0wY6PUjuVN{Q>_yy{z5$Q9E~;8_#^(WrhQ4N zfB+!_^oQAwsZvGVZ#VuGE-r}|rLmp$IIBQhQoER^^!)B41gYaR+|O5uSyXrmoG4ZF18benofjJGwV=&>%8btS!1b{V_`V zp!VqQ$lK9fk*Bf2lz9Nin_u1K^#@~({}o1@LKC(D^Z^pBBuBYR_I zD!Q+up?zO;U+l@7<#kI(eaBuZJ#{rtp6XKItE0Q9NHQd?+CzG%AYc}&k*Zc-dyVvj zGqRLE)(FO%r*6~b`aPGcst&@6JuZ3?0^EAG90xQ}8@725#>zIwyqnv9Ass~ywKqjo z$J@~lBKiwvU`6Ht7R91^*jJmf9qm39tC1N+>mu(&_jc6Jo5!4M|O&Y4=)v-?2JbtW5Elx>&m(%XP`sc5(4Kntrm`u+q9Exa)`~GvX(aQ+F02W z?cOKU*~}!eug$yKv%Poaetm-f>W-DIYWJ>E8I*PGZSz)x2uAhR%lj2E?~0CH(Ps4* zres#a^400`_zhNZOYF@y?QzaaOIm<`fT>Zvv8T-31b3L%qk2Qd2cb@}r_3DlP01+e zK?@(xbRQ#yU~$XEyFA-lAJcg2VlNHq>fdpX;>CT`zqpN|5swaRe` zoWuP9&lbEW0O`h1&PpEV$TJU7F@kbU536xV!Z?f=&cf4*R&J>UY)Bl%#>(oeS^ zrmf_bVf-w@`?B=T{h?*6T)bcpG-3&C%m}p3*0&Yv3ja{ar+e0jV`9wPU=Hhgwx<0L zf=diWY5$F2Pua9xbs&yEz?d66DTqUgY{bz}uebCm%FQtXfePYi9Y7o$3lK*GL$&`x zTDAw&30UKi6xR5hOe8F*C04xIMqkD2WFqs-P+yUuY{a2E{m!~1u8_wVr@dK?rqWFHEyd(M---5qnT!PfMS8H)&X3xlUD|^^x{=N2Cfk3N@5Dr-kiCKGI{;M zF@47(i78ASS!0j|$N^;0(C%$ez4RRcAq+tly6hlj9YARsve55kJ}DG&BWZwRkP0Z5e9jrp$MF#S`C%dz}otMg(YNR2CxL~Uf_Y26drJqbNU3l0r1**Lx{U3NCq5z zFKe)x^=ulZutDf%hG|~{Hz50b0TqUziPQ8evy(QaNc{4I{p{h@z1@fK!XbJOafbCKBWYh@b|$?zU$=?1ubm2*q-nuS`B&5emQ|B0xSg}<~L-As8q zr>^##XOUjk@g7a(9~RTx@=hRctyPv2@>V0r6!c2G4{ufh_YSr}=R;+ig2!E+HPs{F z??2(kgZv2ln$*w67$FqbxuF6HrGF*lvxo&=X|`k|@h&!KIb^nLZi$vdMYJ*!h;M`X z*skrSb|SDb5ol3AI7b8z0S)OUTLvXa!;1pHESLNVJ#~vbs2wPULf#cpt%+-bMhJhI zUkGxD`dS)J%~1=vI4FsC(p(hZVsfC8zR}`cdo<#g+j0>E9C2QnC^jB%w$tlw^Ny3C z@4nnuNe|B@!5pVI3x*`-UDZCiwok{2w~F(maC7^mxufPgAYNQkhm^&h6c9ijK;067 z(OlIgx7T}bx9V?4_VMfhxp&39U9l&pQ!QDxYjBy)VcK3FZSHs{mN}l@+dq!(ZLfy`Zx}?K?hQFsWIPyLSz z4i)U;&bzEqyXCFs`jn^oE`${=Hr9NLU$HmC;rkdU)*fq%y%~%8V-dAs6iNWiSphf0 z`~rF%qRw#h%j#3J(G9SkC{0N(p3IhotA*_92F{4SH@FV&@@m=5$~xZ0DvS*EK&EX#|mC`*561?e|#PgQa~CRUzYASo0bEkOV>Vn z%q}3~I2}po^MO*+Qumu9{br^5%}&)@i>3+{WRvPf4S;4se?LFXLdj8T)QfW;_cm3| z%^w45WG^Y7bvqRB82KU3MEM=vm`-piH=@@nVEiR1p9%-22sW}&J0>Si; z(H10DLxR2SHhh$I#m6A&wnXWnDu($E>Bqe zVdjd8Yf~by4fUcby9gPT^H{uoy43&k{Q*6Pb#MrU$7BjJv`j&!qCR?BrqJu`V+xgD zXZWhk_VD~=_{z%*KW6C0w4py{=r;;?Rh>Q8kBTih>|fE|>S25Juu(L>n@UU2D(Xo! zQEC>?pqd0BdWiQ_)oV-dT2~-oHx$@&S#JU2>QW91D(5#V65tfCn?Hg~%mvM4BM7`X zB-8CvqK^n?g#bx~-tnH*7mK$~U|Z}>OH)evYXejw@vK;k-;wx#3XX#Q#Uh%l*wkb$ zpSd;>ctR`L%vDJtWAX@HdkIpPAbP{;nt=N@*o0Bdy9v_GG5;l`T6_-A3J;WBVV6Co z%hb<*0#zUHP~Uez)hq6-ohu~$7%x$62di>{jRhF&tg7q+$*FsIGs$B>eSs{pI~_zu z&cj3{0b*!G(Bh4iF1#RFn1F4dCLJ`2N;^Sgh?MHd zb7hE~R-kV7Ebea;f~O!*TOb#@6?Q;RbsJbf6q$eGZ`ij^-8~#FrnluYRG3uQ<}n<@ zPiPQa(gerQARGg0K~S?*WCruLpynNP{ZS4`o9u82%6*?GpaVav_ z>ho-Wb>&_M+X2ay7Q<|ARl*0Z z)*!lG<(@7ex+)2x4fal`?L`8j>y(qNRFl>LggKxm&$ATbPD@M!W>S5QqL=2ofh+oYzu1Y+tw z3t~2@hesQTxrheBW;A+hQxJ1dLrmQX5L2tx*sZ!W#Ox#xkosbdK+IZ!jK67!kt_u` zB9;-+lWmsw+j-ALTAAOk4ajV^K}OavxTGDl*c!s~(wi;X$KnRf-8=!dO({s=^#BxG zrIC$JTkAUNu!J-(A48tP<64u66Zzyd!H+YRe~sM{8xW|}+QUU0Ke=VB!bUEC8c?z}NvyovwT-RM_;XQv2?rvZ4gDm_gA z_=zL{*V=%g{&Bqk@FsN?H*wY7Pa4_ix=#dvm(}hQ0Dg#<;=-XU?>H-v3!b#R<0VIm zw@J4CS=P^p1``ksfQuS^2i=z~f>V=KJQ3g*-j`JGzD<*wYhLrLtq=KjvU(UA?+f0K zllt8pL-8uS+Xc|_!c$$&FFe&lK6HYcocn8D3%CmQ$OdLlN=S(7rXtI?5t@?aS2Lxm zkIA{MBCZqFIrmSkniv>Xut(}eN?<*6ti67fM>X)KdSES|I6)vqY@8-T>c?<*Vc%-? z4#Y#QnW2j6XD7s$&}w8<;z=j%O4K@cq#Q9x$h2Bz4HL=~e~w@zjo$TIn!~@Mc$3WI zb*J3t71PpV67bfmvvfavE2Ad@8`vE6UkIqi(j(_fg834|8aYnxs(7o# zAx>f^sOZ~r2CJn`0d<5#d8*Ij7g(De7OWktn#iiSS%>}N@gWAX)W;;{JqclemAye0 zie^UM%P;We{rKo{Aqq!4Ykn+8+_xz_?J}?qMDHTsws28KC{PFq7gQ2ny3^S$06C z;p=1>tX8Km0KJ9vRoB6$I=%VET9@7y?Prw{}XJZE6!6wLhvbx?LPt8U&Ba;aB${w@1b6fzwK)l{q zvzvNj<$NUWLa88I8?0*LzHvt7H)+DY7p1ce97ewijS$)*iWULIFQUq@yc0PN5}WFL zRQ%VtxP-_RZ5HwxR}zLK=R|u+8U!(fFiWHZ_TtzVXc#<9#IL@fhl$w3)IoXv1z61~ z5=MCtq-qJz?&Se`Nd&5s$ZfrS7FF)Gg4|ZCB@pE9<8ZEIjZ2pGU-NOITa-|0!4a?> zULE8u#|uOb%B0u$NI%P(ub;F(F;98HCNM#oL|x&ykr?EOds*U}L4LSo=9%!$Bvl+Q z(a{3#kgs2o5mzh*!g<86ML>N)AlC@GFh3JGZm3gq_`de|8Ai5Fy@$y}H_&PL=3TnwZL6)4z3s4H=_qULk6Qxzxwx>pqeg0HUBMyvZ_bCJ$4Ds_qD3$p%WaF z&tgYf)kp9v`hXoYXbI?*V>KOgr0w+vj99fhHu3*3(K zYCfm-E1OuEM&5`$zQHQXwS0Mn(ZH2+P4pl&;bXqFsv+!iCteiAbP+<19!$~;m^zJG zw$)mPr)L9Q@4#DFfqWv#>?vp@l&kP$>KmTw&B-56Cx3*KKYqlIun%(0XhMZ>YfS0s z28hsR^%KZ7usK@lKFTh1-zz;Vse|F$smV}rP650$RG3@5KKG6I*t)ciF{xnOseWv_ zIF)#zb|a-`eVmAI)*d!n)dkR}0b+Cx{fmBSv+Cx3c#Zg?*@h7!`(+zr-i=20 zXMk8NXge|e0P@PAk z$Zpm#{9EvQ*gXj&-8zmSM#fO_TF;I@d3N;H$2H6NzPtVd_jy>hx3^(qga->1ZwdvT z2$ijtuta6FS__j{F?~V7AKpG9*)D_}7Kg6-AFXADrFrdb@LJcl~t zkZ_H+)ZQ;Asfw2t8m~z3ipa~00BU5PFMy*Ab{dMr?mLUSQfpu~!c|+5iMG4D zXJzv+XY$a(Fa5DhOK<>QdM^SF1}BDeYL1Fpj);hd;g!7AqMwu$i7`M+Fy_>|j5Z!{{X>WTNW-ObXTw&&oY?WwB2q2DV88Opgr1} zh81;A6qGKrkXW@l??#!SughK%)peCox?IAVs&9ta+Hnq5_;<6lFUr>bJ1+@GR90tz z8N@u!KpVe4uU>nfYwxw2S!nk|XKKOV9+&#B+qi)W_uaorg9;~~NYqx9)`(YSsc-+I z-#Bv3OcI6xT-Tz03-t!q!Em>zpF*o)xVNWo;!IcR3HFmN^?TjQQ+*kTOK%}aKU21F zr)-tPXv7B*)jPWgU$xDzg0IU))=KFxL8eu`Y^2-=Wg}Z{!8SENL%591q|~;VP)XCR zG6F9oD$nw4-{;vOxIg0|v77j=oA{`_aeh^VCnW5=_J`!|GdQ~^SSR2P2hN2OPtBjP0R<~Bc^wf7f1nq{7M1*7B%HCP)qgZ9 j%MjcR$a<+Li`yw&=-YQS`45;1t)M>3`-Mj!1L-?5IjM z94=m1@hsfRc17zu_I132>sxVOw3$U|uZz4LEAEYX-R+sZVqIdxDV6}5yus6+Dj1N~SxY7abRuCTj$DYDE`%$2nmtJlJ~I;h1|e=PFYCy)I}JNchvVcfW# z?QO4*=M5~%2o|NdKki9im1tRidtI<6E9&j1!TXri%KBt!F386E7cDy+^&XD0H2mj^ zdi$a*!7Eti^zvkx;>RMo0__Lt{8Z{>N*8q9?sY%bm)6ywns-t2F%Hu1`cBUAflNZ6aImY%1Q~3%P}%%(~1pOhTz?ixxC?sci3ml<;Kw}&AI`Jk+E zI8sX|%OzozLQM}<$NY}6zMu?$O>&vnsjHzun!@Ygg@d&+O)3Ou29X#k?7+Rf{Rtrv zUC{YXP3LF1=4wA*jSg%o->H72+jy$0P@QNgrA19lz;_!W@E~u6L{x1C@oo;4ZS|`~ ztwJKU35mFdQbQuH8WZ@UA-3D#rNiXQTPMWG8n5Lf9A45INC~Ga2XL(y^1_9{K6-AqoqXICtSZDV~34na`~ira82TUFMs z=jq&SmZm*^s;*`iJ86u`e;jg*e$Da}1XQxntCEZAvZ8|dtYgF$2A+R=oqQ zSdc-(iRXo_;!cV*X~Z~0I-DNdHO&488%4@SRR;WdYAom;f&_j%uzYCpW*N}7AzH^n z8cbO)=J0|j;tx}_ymP(~g^!UK+l&o@>y zxs$k_D~kh9H<=rg)!&xBVf@3(kXTc^zqVnoQ{U?TObI~OSI>PY_}x=25q>3;1Ok=D z>?dRXH>p3^wZ-C!mKfu*Dmeyb*Rrm3BbF}gS)ssc=DnKO;qd=^1-Wa>)g0w8kQ9iod~6RU<1rOz6=*x zZxp;5zA8~D*5{_GGp#@qK{c-aL4Rntc=T=vUH5~2Y$R6k&KdB_v*?6&v@Y~DEJtwT zAlEtr+nngHtF{Ke)1r0y-nzgOR$zU++-hW+ulC({>m9EXV66V_VN4TkM>yvX98C6( zX}<3K({vGsk1Q{+K0!5Ybyyz~^>lb>1S-1FnDD)>U_2x6H@dS#P;4O38||D?=Np1q zi1X)d2w5g&_(XTT@a{KLo?iLpH-B_NfZt^gLHLf5zxs)!;e3qQEU3sB6Glpu;M z6Q$Ug1f@{hM+n9yvJf_S^q7d7 zx)25qfl|+>zhbd2pZDXV#}@JmUQXx!(@cAw%)#1SQdDGSpvA3o8}SkG<}gH2k)d_+ zTG;+fU6RFXy57Ezs{(oBilm@t4_&iSer&yk7hP4)t9`MuoiXpuSf(4~-F__EJP$tw@8P3SxKv4C(iba6SD9mK zi5DLp;rR2H9n|i9(zJc_D$pml3krKZkAKP}qaS#-9N}mNR2!z2z+tY%#E0SH#T6E~ zGkIzI71l@oq&>Jik4cOTkZ-i(P*G8|6Gy?~E@Al#VZ+*e2V*EjxjdAV3o{=$Q>3LX z<1KZjsWWe0JDO7O=2WEz3)3on2*>t6b+q5qu{**~e5VKkeDGLQ2fN*~3y*u&Tqb8Z z(1*K@uX9!m-`2k92Ze#do;CVHW>pUa-v?17;`Qy;tB>KEiK4YT+d5jOhSj}4tgd@l zP22Ki>^!uh&D#k($`9b)Twvi1kE!402U*>XEHXPbJkp}B;f$`Doe|yDK1N+3zehmY z#;C98*9odLs|)!Z+~Zy~dzfhc!6;jn$-{P-!cNVm8< z5tvZ!CIaRNWSBv{cX|5A2!r$p805yfXyL`XQB)V&bqluR?T$n7FUHz%gzvKy)8Pn9K?Ke<=- z@=N({_DU~)s*L4l$?I6759HHX5tit|??!h=K4h8RH5)O8)s=m~xh<;VUyc5^UG;&H z!U%S}({U_*0n7S+vUarN{f=YpdOvWDYco%J*+vUvs+TQwx*s^-Ft04z*nx3k=z+6h znNz49%S~TTe6AoA7$?QOV!U%Ncs!3A;^NNc{7{Uk5(AICA2TwzJ6-TmJkzt~kn)#(%_$pS7g<6VW^7pa3@(M>B&pN zlTS6d*NNPt6;ndp!rn-!pJ+HqX4IB{A=UNPfh2|9E9CV+io7x{$g47-aA}FcW=^O%ah2!(0yo^}D$I;fsXWopm7&P%<@zErCzoE)y0!Z{ zI}F0g>QAv2Q(ifm`5LdH}PMczet^h^dx#C zUv?_kfFKpX1(BjDsTkCK)=8gN#liVR8t9g5)@tz^M#KvCEKUy`Q6_e9Hb}B8__{EH zPMnL8P+c4o)~gQr4()L5m@M8-ds2v3|~q6 zxm(pFJJ@<+2b)a?o0Wrka&%;dPn~3j3z(uWhimw_g>Biz5XTF+C5^f{CyeRx{NxCm zP8?yQ8DV3b4zi^KfM^%0CA*8BkPpq)dezxxf8~Y~yI60!Sg+<^q$jB*edjJ%D9_{L z1?YWU8jL3$!4zugd*DKXyF5ESssB4nsst54E(25%(1h>>IO3=NDiD z-DANm?scM%Kd5b;ugY^7zL+>l9^mLXoAm4YurDH~5Qcw`yp3QirRPztH>y0o!QNW< z2k~*>f8qNxD#wG0tk=c*yo*cDa@6)?BdzZnUhpByNF*FzU%~#GW@1zqyO9SAKEwv= z*>aTeu%$Lz4nORYqi;r@Ma{GiQjSPI-+Dj$-$U6p&Z zbyG&=<-99@>8`xSjKWXu(SF?hxR4Vpq5qEFIVDBbUe!8Af-@5G!Ob;EUsgd?f8b#J zQkq@zPn&K2Zwx>~n%SYK)ZRatlR2rbF=H_l05K&rBOBo*Gy{=^yBYk*wd(DlOHym? zzf`OGU#hiH*Am%C51JaTafTb?la8JOGB)uaC$&|K#8V;s-K_8pd7*Pc3tXWE?$ClP z^)*(vB((5q6E`>L5d&aop*u8tN@(`9(Cq2>Vl8yZ_wKH6)&5M>6Q_U2=#zUZMm7%L z#vH=e<2*5cZfJRSXn9U(d2VQVp4u{Q1n;LYyJKwgsGs4=Fyijm=v*yGeKVxaQzP2tcA zdA@GodA&SOlV>mG!40)MJHo4W%ImvKwQ#6Mo{r}O<=$T6dW2Tx@*=bJ$ksQG5TGai%I76~q_uQ#jOb^j3aR1+ z9)jK3Y7`(5eq3P1%t8*WI(sn@ZXaLI%a;Wq5b8x5g)ULg5Sk?XxBwvUpwRNp((eRF zd50B4-hEfU6EIhIoX44YT+WGFq<_lsp(g%he6(J=hH1d-<8sW@6;kDfN_DCJd$anI z{yR-wp#SEpv-z90%KG4^?bFTorxv>8#05H}KXLeC`NThetv?|Vn+5_k{o6=zPWb=xMH)I1 z-#k8K=_*nKUH88pD13eTdHC`b_BM^Im{X!&xy?hM1~iic=WNi%z;LQo*h{?(WBJz= zAnsPnk6DJSa*4)TqJCX4I0%j#Gz*9r*+<(X3jbK*yB!O@ zn-|yi|N#%>q;n%CO2-YE%;a<18^Bb@<@Ia@9{BG-d zH!Km6=i^R8<&sMvU(R)YAeK_`=@_1NdeR+dks4Sk0l9K zzw1_qCx~X=jqBU>ZuQ{j`L5ZrMXu09M)|HQM5OvXsf+@_o;wHRli(Gb4lJU+*Gb0mHTa-h zJNTk>^xy=3oh`jws$&@*37l$K(x3VbcPMo9!Eur}t@51ou=c0whidx@M2AbT@>WOq z1vj&j&~)PX+o-9lOp_4N*0SOWZSoD1ewr_?kxVR(TnIL6{NYs>RXFd=HII z{skj!?%PaL8YmToBz}E-a7hdEXyrd~NsQp{BmR->=A!UD`F2qBAO1nOR|K3oYYHW^ z%I7RZL2*F+`B&P-G`oDt7jKd0KkDboX1m#we-!Rjn$d_90y@C@3VDg00sF$taTpwA z3;qhV3D3;OFfX9JKx$0Eo4;zC`rUlV3+!-Y2Nvn%ehjim4}$X&jmo>a^+c|--#sqx z?8!|rlNoQXAuvE8ki2G`-uIf@c$^v(&cstw%5S;5q{DUUsGB2Bk~^N9^gFHRg&3xv zFiBNkYdwG8kk=**^Z_nNsoy>)%T$?X0@o@Bj~vz}l|Nb%&3kI1G!=1n1de_KQ z!2<6l1Uqh5@`cvE63HaQ_K(7^Cmd*z8)kaN039MWu)Z=qW?Lz>5BSxsi1ZRSb?9eP zWu)%BrKawoFPywafcz1X))y%)SH7-=Z(BFy+i-IXSG6#@44>T3Wt;RI2t6!eBuzuD zG)P;N_;q@>OrYUwU|4r(7gm1Z3z`ZU>y;MQ4_$e}`EJTa=wzjggffjH~DtJ7H z%JS}fF1fTD3%u(y$Zzze=Nv1{a;`7%Zp`rZ#m7FET;L4_-gOydP-21C6?ivfcn<^V zQ+;)T({R8Kza(c`zKKf$z9v8$eN+us?i0FDFpU(NYH;5+ni&Oj_MRuuSvlIy++?cQ zr#2`JNl+}R0gY}-RRh1p$COTt5j8N9;J5U1`?-9weZVTesCfF&|0}m=4hng6JdUitCrm;R&1Y#>uMZZ~(=ZK@?a%)Pk zDdG3~t;>l#n+ys*uw!EWAy6*81Y4L1B%6-DrY%R7W=GGGelC{)wt`CJF9B>{{s!0? zSQd^q{e0=(c4>Z-Ig*^lik6fT5D~Zh7hKdWc%h#`)aUEybMZWDMIG-%LGpq_7s|Gv zWMUHP=qp321l*K}2p>6G@7TbaO|(i-dvKki(A&T4d|u`o5bJk}c$gKR!>bj%npsfX zA1ZOhr||6Oc@p_m3WgW%UUso$84bxcsM#f-CN6L|raO*$vov6y$tvVa#oeLdlM=J7 zMorM&x_mmFd_Z}pH5|thGQ)J}{g^&LHs=zcmJdfYtR1Ow?KlkAAlO2JM^|x4B8eJ@ zA_KvJ5$pN2EJymf8YqNeSBP<2+;V1MM{?Pi2#&E%P3hQ+c>Rh)j=tbTp9_0xO4wqo>|~ zjkvTK49w>VuhRfl#8vwr@&#oFxw#@V5zNzLIYC;3a1YVMwIe#$kU2zudw2xt)>Aq zeO6E~iDhN;uf813$8*sSEg|>T4u^{C;^QnGgBPwDlB#_&daYoNR2R1krP)5*cF=yU z{8*OBQ+Y z#Gk@c?<&CWNve0E)jL`BlSTSZhRPp%qX|K4Sy}os>bfPulKz6P@xuzrT1pl`{e(YO z_ocknXMrGfS-}4TBr>vwp@{?~UB#8mUhCQ{`CPr0*%vr^S=_*3INOjn`wFwB!irtt z$Y&Y9c?IXuQF+M~dNCi6tVn&<^;w~-+#z}yUcmDqXJbL&Fvir--7eire`r{IuGG}^ z7+w&dmYlGqQ=uVFF?eKib)EsEk{P8nBb`G7kfq~Qt{;uaal6)!d;6-cf? z#;y-tm4(p2dej$;DL}P=r5v9Ge&I85kxZcSd^5N(H0}aMqfeR4ba_V4<&?!(h=iCU zqFJzK`~V&kz8}yBmsw)y!aKBU2selM;B}I0Is6#p%BoCPTQHGNd`pOK3I?GiXV zAktYLKvRFulkx`<) za)=xg$kF@MJ}iTBH&ha=tdpSgg1_Vk_wbX)Z~gV=_-R6F%@{A_WaWGM%xEHg&)o2g ze8fWFq|cURFMl5KA{X{H-|+bR)Uv0AGYL#H{NO%yr+J=WIfF~G$kH%~&@kV^Ms)JT z5!Ny0^@IZ4@$UzT^#y)Ht~3crT`oLJ?fJh#i|j1bTI3h+6nuaU@R6Oe#!V&)sp|KW z8fs)%$KFx5jRC#ak^Ko!=?~XPJRTSgD44EWAY%OWoEf`V&K8i6N$rtT%$YT$ua{RW(DK%zAU4v<0A60Z^&E(GWvw z4k?3?X&M3>B20CorZYKo52(pc$vSf3tTK}X_Hj~Nd#YO~H(`*}zLBVmM~H5m3?K|+ z0!9sT;w$euTZ?w@GgWCVH?Yblesz(Ed#{^!H4n%vn9T-yPM@g|es1b{s;`y;PjJa9 zhxPpC6Q{gpoRn9suzag5Z?(>kDiUt0D_^x7%kdYXaBKLf+&Emu;+Zt92ia4c+6FI@ z_VJRV<*AlCh?cqgrla5RZEERtta?~3X!_MHS4vJFc24RIKlv)y-39+38|$bX7ffUX z&Q08dZ8KNrd{};(__>xl+-#t{T?I9?bR+A<`(&FFU;i{wB6;6arFurz{@^ckm#Tvb z$r=6oFp^+RWE~RROa#;it(U9>s|590{Tj;u?zrs6buPU_b66VrX+(=KhdbE zmye$IiXDePOWkt%K<@suKbbG?0tQUq9`SAbXWR3ADc9R6pL#M7{9iBr!`J=~i~mh3 zBp3gX!z}))>3n>lh8WMo!`Q>_mCQ73f-NHye<`iaSy$+!h__AES9>cj2v)857vMuf z250EqYlckEh6#$AC`wN3W|`O&ONV*mygDT1_m|va@L6GLTp|MI_fZKl@fAch@vOd$ z2TNnP#P%*GU%vE4&QJ9^lMEvnd0()WMBcB+Ol-~PZ{qZ;Mam;tj;H!(v?^5GQ@@k=R5H*zI0U|G`A+YMj}sNc;1*L;t69R9n2)nw-oUhFx&lk64XrEH+uV%y zYyFE_`y)E$4&N%BepOHP^-QKZCd>pG#YuLabo`n&)oV^Z)vu&Ybr+ZZvCM^ zh-A>=?lp>%ESpOgmPz|xR(=Jk$(qQedE$;`Te$VmkyK3b^S<`P>!d<8N)1o-%`y<& z*eWqjiS{sfzuQqcU59n~YN;9YZ%?vKwg!8X=`W?6u~WP6l`2(TqBx^Bu6#FJ4wx+D z#-+>?ZtK!pV9c1&;3?a1uv%IJ2g1-DseBNS`}r}aC|Z{432@p@;k$YMvOS~uG+?YT z$fQ%!$(nqeVA+RdmYUc41|7+YkOsl5$mRN8VVAXieL7@8xx2-u71tFLTdPx6n5rrd z78hMr@I2<@slJFhFUwAlOjT7f3nn$0jDLIA{<9_0#PM0X3T_33@w}IH9y&VtH`7T0 zozzf6cvaym)(u(b8eB80e+{g%%EH!)b>LKQ;@w>&OYv)J1@M_^YbH!kSphQAwOw;jQboPQZ(_Nrb zD21Hy=e4Aec51`}ObiYd0_9Mik~4IYWk}`Vn>~(mB^%btI%?BQE1obSzd!xkbS2yK zKQLrj3`!+Nwn&f)S)je}6Hj%G>;k(nRHMSw^JG?o-oxoKVoi~>IjKrE@L6qi#5VaH zln0&W+J+X_C2N`JD2(iGAK4lNTs^>`C6T2kr@-EoZ|nV>V$`LV0MAo>y#X!wS7 zBIc&Hxrn04LM>Hunf9u%;cEYklvWOqc!aQW5yT}=f*Q%8fz6(bWoU|n0JSmp6M6rXcwf4dd2i;&6pCpYKk>uTIi~2){N<)tEOAKlKDf$UuUHp9?Wp5 zL}}u3#GQXEVi}sAiN-3M41$uO;;`7p1osVSMF~j~BKeP}W)uC0R0$;sklrOn@UuIu zo~G|XspQKS&71Z7_;g(5%hw{+66r!Z*lNq5>3vB0z^ercH_F8LcI@|8N&q*nhDL=#!IcLeCg39H7U}tX*zxog(ojz)e8AE zTAkQoU~yuS;SVYwH%Aea>6c@;bjZgbgq|gR3_S@o-keGTCz!pEjo3OTok}q6_@$_0 zIB~eY5}ij zFEcBRs?ZaF6Q-x{l}PKn6D*Y41&t>H7s>mU6W^ce_Y=7Tk~fbaVcm*y7p?kB?{;C2ZmeOHLnLe z7=W)3PmN{q?oQeGNv4IhUALBYBrG3L4|cyKl?3CW=J!oGJ$#od4)J$~XJH9{>en*iz-a3- zir&XLxePYX+7myjbtw8XGOZco;!e~lEI~;rkaGuG6d+3qjTWVHgt}l8-VK>bJ%c)h zh0rUaE(z<^IPYXo3|<18gY8l1j?(kTkFPKOt5VanbhVsR$sQ$oHv3kR_WO00s*A7S zk;B#xAt_$=-)u(ezk>0)_!^+)V5p23pL+)xxZ8$eM}~< zgFzU1UGC9RZ>)6B*oEjAOVz8omSFW&bShudJq-ZUVDa5_^Vgy@^VjG3BHTkXNB;yJ z2)hA}yIf}d84UKfrJC6)h>E(F(OExF^_TTvnA3UZh`=5eRvUCrIf7iq+O=`oxUSKhA{c%J=y$qp{>|O6Xt+bT%=~SOx7|5=?s$5N3 z1b$G%nH=XZb81;m;7h1;Np|KR$dE0%PHoO1%nV7`i7J>ly-QzQ4dhNOQ-N?=ddDA4 z6}Ev0!h7OqzGcRoUmfA8S3H7bs^q{1#pqMq6ZZ8A7%thU7fSo|w5`%W-DiLZUx>r% zTYLa>{*HY*e@BhXZ2Ewha`5J0s30b)M`sBUZFHah{-4VC>mEbYr=ni_T$D1Gq%fjn zRxjKQou?Zg_~@!F!-2CtN8tDIE6VRgssgFLPiqFBC?Gz!s29Gg$5V4u^Ib~d+EcxjO%x7^5cRB-xI%^Dn#9pt zuTW&c+Vk*Tqb|kQJW(tq~4;IUeA>eJak=lk}vmh|q}S zBqygPskq=9$dQj#^Ed{!vy`AMJykJ57XyajdD8^)F=ns*Pw|A*Vk8|A+Dk)`7%4|;-_1+@_ z0-l<`(^t~t=TG*#HhE_|0JGJ^KeJ^dR^7pdgAm< zdg>FWhIRCR?D_$^PDhYa(-7pb4TAF1alz@}8-w;r?5TZ~_68xzX<*?!HQxhB^@gN7 z1m2ZT!>LpTc}x%vkH?GkW98XI{gnj=TR@=iKRVn2f&MLj;PM5HLh7++Xlp(q%W1*; z^Bt900L4l%R(PJQ+dZkypuD^^l;_PRVJv=aUBP?=H||O0lo~HGFpO>Q#w$#lxt-gP zQoL%?ky*c+h)w}_YBAWpkju(*=Y+`dT5F=k1Oe+Sigb#57kKNMq~%--__mjs2sB$? zFkLo>xIC5C8POGWXN2_3(t}BdJ=juGLi)mYA(qV2OctbWxdWQRO*V z^YL&QeuY~iAA`lQsh9PK%J7x?5ZjYr-gXpjFo==z$+~LOKaM4!J311(;s91?(qm)) zoM&Jgv>F8bLwt2Lu3BSw+s?FK<>=?i3C3QsU%52z*oYfxiOvJT7nP{VlC+{(6Fg)qFy zc%yp{1>j=*F4l@77h|aE{>cc(+;UM*RAhv`^4jGOYfGH^Z7b;B+r_I)8QUG!+28!B z3H!PdZ%}S(H+n_jb%fU4!XNd^SH(4h)P3~cJx-?MYfwMgAg7?KafMWo%C(f3=+A}F|7(O=FdZd(!R6VGz?Un?1fLt8m4n+~6bLTKMRdMnuRmD7)!7su zWzEVCWrVKJ4tD#wBy)eSwOp>JoewqlanUF{bb||7J>&`B;7)Mu=nle{h)bA=m&$r7 zX+_Afxp%Es6%O(SmUeE5vH5(s{L=)g-nN;NvAXg*)-&Z4#*3_b+}79+s{E?Nn!uCgxAG z?2nD#G!IzIi}0fw#~B{*a(wwMpO~d=h z%x_th;r>o857mAdL_JTcR2|lz@MUxu_)eIqR)A&u!aHQHeklEgy^?GzFiJRXU@6)v zvRSV^S5M9Lh)-JncR7MT6V&T41U)?uJ6ZvEX~n4$Ljor|G0{wFo2jidZ^0Fom?<|e zGkh+Fk4FXg$z{pnju!ZLLm@c=0fLR_fcwwU3fe5LC%C<)98a{>Rzw)FbPv*W`6Al5 zV|avg1+h?g^}tMscpyTO@YDUUH@(8o@OtSblFIBbBOMMd=_CHl>Fb!e^gT$zl)i22 z{ct`3*FU|a)5O2jQ!|n;5!>$|)gJi$^-a?~)$a=s_*#vsuAIg~5dJJLM}YYw+)%J} zn*fnUkMNbK?WNWhY9+P`xTx1Uz{kD#v)RwPcqVp-w)tbT(bAu~<3V;CYJ8B%5jOT) zLZ%)SWY5-qPBj%}J3^0+msQ^(FNuD($5V3^mDF!2D$qrRnK!|Gd)5?4+u<@nw1VsLb_?A1rP?+I z5_)QQut5zhJf3|m1&5Ayj6HHbpV)x%?v&v1VV;@|Ou=l!5BVhws8RfU`T&dJYY_)> zSCD%Flz7Z0ylYD0!>rvp?ae4auP0$XN%sezm2T~&Qw>wV zY2F5;wb{&Au-Eq}WciUhSe7TKI(E?&$ETS zm>ZuR>~jVR^_xrezP2R$tr(U>Xwq}!Br1#ec`|2T%iJPn!^t>tJ`oG1!L~Lmy2w}? zDza){5bpSkUlBj0No`Y~Zs$8p^kC}>edQ#9+t?ayYx`;^;H?$T^@^KHuI+H^L%_MK}dHIeRpcQ$*a@ zLKb8gS)r%#5kX%3KMz?J?3R0#uOAI+cKR}+!C^4_`k*}()2y6R$tjk4S1A zSgm&lnp?Hwfa>Jgrjw%)?hs^*t(z{}Y)DN2&JmFzc^dOs=dBX?WsA=I!v9J<*E6H z{^9ae_wb{{x@TNzqpm`2hk8cxd1uB8Ce@nk>@sG#hpr!~e%t}AR;6lyUMy)dZ z&uz9DkPL)_veftlq;6}xkm{i|ece+%#J|RvSEP@*(zH0B-nt+Olq}6>%wV6)zzOC| z(*ui=_~$pvrw!;~iY!|TEGoF0P>5+IurT+ifIWfoR6q1ET!rf=vmtpa&X#ZSC%eHL9pJ^Y=@Tghwg_)!#R$MyxO;)fok1V zAUd7kE8?5UvDT_b&B^2cTE6+$1mrk=m$0&e$R4JOW=qX2h))j+tH$np2M1hVME&I* zCd37LzD7`#IDq+8gi0$L1r*~K!j!95*6Fo5g_H;p^#~7;<$>D2(p_2yIOngaoesG! z#bNfVnsMdJE6%k6xJu_QHb-}y;L`8Mi>LDtsm8=a=ky26JrJn~>RNpk^=^7$& z)=X_wx{9hZrJ`DC)7pxNhpxnrFLOmVdLl{cS);QdA97!~G+S ztc6<&c_EE5>G=~zrj>lWx{;Pzuk^T81wl1PM091|L3*lt%rvyf*!>?v^i&5=Kq)BR z2=3N7sjb}M5?ZmIv7Bn>s-)Hji<7((rO!0Y|DjE_cJ}2ewP+3=~OwC0{ChDZ&s%(s#!^UNs zP8ji}D1VcLqf;}LII93gJ*AdIYq_kY;|J9Ma!S=$vZ$ib5fk0#G@(cf?7+#B*;MeA z@zc3YsLox}pQv5=J+w_|l?dT;P@Ko=dqZankg78~M3K@eij*w*31B|=#U$@F2vJTg zF<04bCCGcB0X$ju?{Yw4rXbJ4r-;M9xch2!cwhl!wAqBREwUXBxiB-^#KJi*ac`FT zM-vOreeW^o;jnO*s!Op#YxDL8@r&jvUn5Tu*r`0x)Adt+I_35}*44vW5XP^|R)~N4wDGGK&!qu#dqGve=NL>KOgBdgB6dTq1M0}E z+>A;LHv82#fWq)hB6axH4f-d>UB9}TpB35RnZS!*HPn1U6^xyJH9=RICO^;9Kc~yj zGx*spmk_P5UoAXP24|yG{qk%q#Eft@5NkcCy>ZqKIW)Lp`PHYiw#)C-W~PB7z>z%5 zE*iu-0d;XF`>b!9_|;3&!_2G058~x1z#v)#{2#<&tRh?YanIFUF<-eS%cvf-?-Om~ z8A4ZH2u(1uDmT8`ZiDA7V>r>{GSfjG&RqNNviQNbXetL zE3AD~K&0RTKm=B46;L8vE@yWG@p>gKkU(dsYW1cJPxTid@|IkU-PrvkO@%6H<9_)a zqMcZ)wG-bKoz=$lweqc%(~R4Qcdf|VE$QoQ$|@&^y&L^uuG!wcT&x~zVfbMArVql- z^b)MvC``7V0aCAb9qae`WYcdx0#D}M$dn!e*GWT-UdFZ;_3t5ut^9Q*r-uau?9t@jcu{`!5TjTaRH0bMI^z> zmo3^Du|?g*SQ8}Pd~h8uV8s?&6k4HDi+zHi#0EkllmwxI78PpLRMU3yB(2f%U{G}5 z|NqS0&2Bz?`abXbgWt{Fd*{xaIdkUBnKS2ufUgGN0`;;Us4oW8MvzSy7SJ$8tgzm= zuoUPEO@otQ2wQp=>Wtb%9MH4R;zZh~57pr@bp!Duk7{7d08Qb&n7BPNCjn}JEby)Y zyen8q9xQbP-a#0N-tbN;{nEuU%yje$zycKigbnwFKlFVR*>NVS?82rel#Dz}*A^Or z-B#qTm{fJ(U}t|Xs8Q(y7}F*A7^JvQb?Kvjz-(=w$qiE&!aI(E-{{wa9$+{+x~Tz8Nu#yWXd)zhX8eL`c%mwMs_ zEFrSGtS4<%Khh&|eQ_rn25}C7t^_^wbYx?oem#lS2|TaVEhqrNLnibPB(mSAe+uE! zRjeQ;0Xa*MHH_G^e_UqMK&7WMyM8bxqfYL%q61SZCeyQ^O0A( z!%J6t^y#fy5aO}$pW1&04(a60ghyOpiC&6koT(wbgnz9~N_@bAzcl4L6XptAJ8+l0i?iciJra~u_e}12G8X~#IcHm*Q*J#lVg*a-52%OJm&Ewk=fnG{~;U|i7V{+9^I zx^c&>J61x6z6!$ywzB*ZaA_w1b`#Xkp@dbo5?dE8xGtzq$iwv!m=q5Hu#DSi08EP* zyKGIzdG4p*!>80K{{pqKr`VERM_CdbqvflG$DD92eJC9UB4WeqI)WBS-+A;D)pcWy zfok>&H6hEczJ+fGtJ+ppgJmZ{5a0rZQHTnrYoNF&TT|#vovEk21@jB)q5&+#W{#ge z9b!;BHD7928!V&r!ufP|l^K5>ZXp-3 z`-@E|9=>~K86+#YmTLUsI<#-Eeujw-vg|x5#KIh_k&P89vjVuj0V-IG)NNnMmI1MlP6?B+FCF2=5Fe-^?SQ$j6 zVxcR8jsr)nq3=;K?7${>+e1C;**E8z^(=Hbma%uPjV)uRMW267Ev4iSjAr^@rt}X5 zw`olus-mi((-Z!UlD>9KR0ux>j{um+gH2%DO!C9|gl?M4R#Z0)$_!70+Ffln!yU&J zX*3xAgUXv_Ail&vJX5C_h=rOTlDg2JVUZePoy~gUM_vQS0eXLzkQ3f<5K1D8Lxjnd z1c>G7cZm}5TJ4x(U_CzuD^(eU^=zphacsKBH6V-)0@*;2&BRRfP4COs5Y7M)Z>7?u zMt^*O2p^3G2MPRcfe6~spblhgTV3|+}`EkoDNA)drG6cq;b zFVKtj9q2?fgw{Dy-dFKkJR3mj91g})qsLd`OUo@)gJFx!bt4hp?QEl*$N)~5(U)$Z z4_Ft}5s14qjTMiVy^jgKg!2&|y~SoD#cCAUB()}L++iL-v%wxVo!=FCTheA$9;cP) z?3SpIM~b{XD&%#=Fm(2VJ<{Z3vw?LZ>VNAij{A#I%!pe!FRRhlRJc_6JXqQKpT==$6h`7?a!pjv*6A-QI^bj(ssY?G%*X!H`W3Ey(kc| zEe`0_Cu4kRES`8O2M{q2fsnJzYE#&ItwAf%Ab@7Ak)9a9!u2O2G5^VrZX*o7iraud zY#k@yCkP%xaO0t$s4qo@X2wy|$J-OA=>z=yYHDg=iGHc613o?fHvt=;-GB)pJRB)v z)u$=4sRY+0QsHh#Ti2bqVAA*&pJ^87OvTupX{) zm?ip-a~r^xGuGZ*fZ4#FpDES{?=Q|w1a%8bdiAEo4@rd($~ zN>!&_a)VkysYvB!*yR<(RaqAXvvM3sN`@AOc1`5=2r1U3a&Lf%0>k|c+ReF3Agr&SJZbPtyuF~f>Ly(~k7K^kw1{6UIZzkOZ{peWNAo}AO zv37=%7S~~@I_9_zSBH9D7V>4^DHgt#9o-bpeHBoDi+j^Y`#9u}070Un3(RH8POIM${3QJ@aP+eCa@YJV)GBImi^x&=dMj@7Rd zXCv&SUdA(wLUw`iJ~|0MMRw=uOA?2YCKmBShPceh_-^kI?nvQo_H#scgv)dwjeZg) z{Cw2qEa4by5nXPc8jIy}x)@HP&Tkr6@?1;Gho{FVZmhL)9lrE{S{7x& zzS9I>f+cn!%>+0|4!TyK*0WMjK>L|%dQd#JcE~1d!5&WM(G+aCIashg2Bv(K#1{y^ zvJrosswKEmZ>IHlq#)&l*{uif#z8)I;=3oquwZ&2PI7RPtoQGYM1FPRb#5bC87TK^ zxtEB>oJXQRY3AL1sM2hZjALV){>{zYqKnn7uc92?;ugJuEk~yY<%ErCp(5-!$VEzf zzk`%I(tX#`_Z>M}*Yv{a{4`~X(FZnQN|9svDyMRGA@X0K75%2p z(msc4+B4F%dg4oG?ZQ^$5x~r@Iru9$KoCpd%-{eX3W5c-yaFF!VVK0;Q})mwZKZls z+}wUWjW}o(Q66q?(+eT^CBlkhSy{Uo3mYKmcvzk$EEJdHEKYc$KCVIkV5sc8_00=0 zhmns$m0;v6@vvwqc(^|4YEWI*tq^pn^9A*tjP>C)z4pyCPg80w+#5i~Fj>=xaa3L{$<;%Cu_ zp;&YNhNSA;tEn^83!D11wAe@UIRxv3OWj}6h)}xAlU33IwHWddP!3o!P+yGV0n1!T z6oDyiOUtf>O`pb#zM^piHCTKaod4K*hB*}1XSc?|0OQp1G3-`tcgAhF(ruDmWYh=% z%u`92V=@X4zcz_Buxpg%KZ-WUXi5TA{?mYp#EY-tejU*>z5AYecdCa^dD=gbA!&c*1l z)UMv8*Y_H&Sm|!Cd3@B$KOCn1i0IS9b75OIXO~R*K2=j7h#yY3>d0mSV(8}ie0FKv zUjI_+YJ962F`0xWKoNy(k@+m*>o6o?b!PP#gv!x904#vnj}E>JT~Id!YbJkElQOwA zgOf)FWNVt!2fF<$*t)OsBKCXOQj9iN(KGQ&PXI88m_>R%4Y%-+hr!5N76(&$Cv+p^ z(0%@tkq74iIJo!)i|@di3S-O5M&J>w!?A=&Zs292b{b9ow zbo;uMg3yS&!8yUo3USCp{^C`WvWh)B`2p2qZ@n*UCXM%56PTXqwK?rGYP}SH3RN9@ z%dO6{s96ZK_XcV@4mf}K4K4&N??5H~j?rpnZ6gQ3{!mMP72*cK+tL^6# zkzBb7KuuAR!&fl`j|=n#zh?)?J@n!4lBl^H{)@wlQI z+u0Y@`arRyhsTOiLWv(yWd5OiICVMfnS>aD0?$m4BN!Ez+*nx&U+A>rB%Sip z9@08vdlF0v$3+VDM~@|W>SdWLYk{{4b!Ci<+zJaksFQgn+EJH;(+G$I;luv27RDKG z(VtyLf3f^dZm!?NPDuavAgq{N1nK_;3!s?!&rqhJcyv8ZFn#*7U-M*}#xMaQYf)Nc zQF5WK#{qRLMTB_SFc(G1xj7G{m7Y`_aV8;@=V_!TI7$W5=i14ejdRqGij15tF@MnL z5fGjvRYIxCh7v@k%1~1oarB&V$1p#KPSe*BYWx0V`~GzM{xp#f)4&qoAeol|5jv-P zaSF0om7P#sjej3hpwB{aP-PG?uk;2e@aez$P#Tyt<5o4Q`_ps2L{Rd_(Cs|;^`>fu^N?wl1CxN)sxl-gT1dbc6+Vvf5ft1{;sCZ0*TzG)=Ey)1Tw; z0Y!8nzOiuhdqsh*vVZy`ySkHawc*MC8-^$-KeUto6 z*OTRMhQ3z*X6h^OmpgSE9(9w(*pn`{CyliyU20DnuRqDbws8+^aUp#baZ(LVGIDp9 z{y9LFv-TUano>8NjOkwvsKj)$W7ltzYnxm<<=Q3JZn>V2YZ~UYU8Q+nbyTh%d6LZe4hIW~xDg%0 zJyc9UoTy5dw@s-!^EQw8EE1Q+8FOI?oqa&B0*cg)8Mu2??$U9$MDEgXw@B`iakqeX z!?O>}ozs3hZZXA?%qwHsS7v!~M|aOP$xQvGD`b>)+f|_0_`E^!`Mnn2+*4yenYBJv zRYaE=eykRm{+b1FiwPH6>-ZPh*ph*Y8yBK`fVp-n`?dggzn8lr+^v_p`MCRq+|9$? zO5VMu#}K|Az=%(M@_bB{Xu2sNPJ2-(QL;ZaRwVm*1^VzSeI$E*L9~2Krr*Qz=|vot z0==Q1Pd>rOC2j*AH=kt4C-?RG1OpDkXPkO3YS3?`L*ISldj0LIf%1IparAX4&3On( z12b_AXJQ#74|PONC3O;Nrauv);+N4N|0HY}oAujI4}rwaK+$RB_(AO5^bbD+cJhk+ zB}bv!#v(&~L;NCxk1sQIKL2gE&b<>5=$w_pw6a-0f=X%Io`%ffs1&w|Y5EjYs$V)W zoaUKuq}oI9-osCZ8PJIL$Mc&Xp&{#`ERU~ZKAWswk8$Qg%gA~n_D#V}O4rwL#NX}n zRb7c+hrdZRd_o7g zuVkZ~&{iGU1LVmAxI#D2txUAFNwMZ~x=J6TB+^?nSCbc5IwPq6eL47YLk5vgW@wch z^yz&uyp8eE`XS&1ZDL0HOn>GyL#kJOi*ffS1QT?IuIxY5sLBS`Rte0l2YIAY9Q zi==@3^;0|tP*|{vxVr!bOi!s1?=CF*Mf@{5b3eWr#NVVZ`5c1)L;2=N$G`R2w}a}7 z(`vgo9yj6*LYb7&S-aGFILi}S#CCFOjvFqX-&NE!5mRsI?~YT6bSw1 zjfc7Xq({a^;h}Dr=E;y6U?m63=TiUxJeUQro|j#WL+~luz$);>X9An9mi znDKa6Q2!0Nt!SP#C>ML4*tUgSGDe=V#|?kWUrjC^zEEA^uilP3ICZ?lY1omfULtRe zFK;%iyCBXgi!28XUN7fmuGZ-)NH}sx&oSQL>*Kj|0M8inVX?$G#`#-^YwLd zUxfQ2Js$U}iZtrnw7{XLh2Rh2AK)x4@IS(2)GRaIP=>}p;U1-k-uT&I!S%Hm{Ka}Z34sIKNn z_i#@U`JJAdO%W5*w2M~4a4HL>0(=BT5RSraTJyOA2ePY<3SO`&Qu7}-WMnDCs_ zyuatm`h8A?K)O0ktpL;<(!=P!4n&2PjfXy=n6Oah_1WV9uQMeB@9Z>JeKBpC!>~V@ zA3!GZ?2XZA8xa;)9s6)TeEvlj0p3ft+jTVNW`r7ZgiD3fk%K**Z{Lu&MyEnTnzlF({-^LY=9PF}9;F5dhBMv~Sf6CD?vT%Va0A$B) zMF$N#*ROw_U%+jXY_m0}i)OpObwNpee(S@?P6ZuvXHK9Ew`e(>W;G7AhdWaS z*+}w{FT8XQcrX~|{QnV#smfQO!@%QNYUS49xO*csgb9w@{y{a*lJ$55Z4dba%A~-g zyaU06@uWhYAlk3{J$xjir3R}dSHa*kp3@#i>3#{wOwHotTcyWT{nci0kZWf_cHdRo z40)6T4xbE?nzeH~D)NMek&ekeFl9Qsk(wEoaB~36EX(9#F+@ET29W_qG}CH zNSr~WsUY@;#BwlsFWQ7yaRZ5<`lu{pkX#a`9k$2lJbZQ1in_it$D{Mc0Q-Toc1G(` zd1k4eLV?CvnBnS+tvVqjgvDNrHTy~@Zyt`&x^&~keb(qyP=;Bff4nz-jsDm9vPLV5 zm>x%}9;z&NtddoCM~1T8QAt&`#J5#PCJGU#k^Ro^)H^mFj}+3*Nsl`71eZTw1wG0O z^(pvi99~FHSNltS#&Dfqv{N=Cunm2yE>__Bm#F3cCbM zJJEKTqIXKs(0A%RpF`Hr=P!+kC+GeOWEWs)yvV|%L7jo0#a|~*<`Nnh(&TpnRtbbZ z`nTA!E$%AR|NbTr4H||B1jDFQeG*=PbbtGa2!k;q933OQp@#GTY=*K0Sx`DmI~^Ld z24R?SV(@{aC@b3MCo2*b1Xct`ZJf2b95>2@&fDfPA#vo5=V(h~)l^6|_&iPB8*>_q zR`A!C+zR9v5Ss*SID0s5I!LR4y!yhA5L`sG>y04GUd;2HSW{<8Q)41wgkp(=v*>$& zFVD2YBTPTo3!@^6wtsuH{n5~Cb3w)w=A^_QGI#uGHGlS-KQ5sSHyi-epR96AIHOfL zc|Gp@!U7QL&dkqC;}x%%s!#`h*I&&^5X$vSn3r&dznb5M)BNH;7#d?6KSFtGOBv4V zT2fftiU;LEj%%s7BFMzK?WRe5=U6^K)=8xdZI4h>&UqC$- z*v~gR@kaR|GW3OGb8jfhKSu&mIF8;qovRfFpJ8brn*m3GqhiB z&OR`ouBXpw;NZphlE;s=aC=2~>OtWl#Y5cFNF{+Yxb-*>TH2rl=Rtty5LV=lR3i-Y z^ababFu0puM3Wu#sRIu1F=g?;|8A7Upc-yM--8tffVwcQ>py<-1RtG>ULMAR5s1T97k@M}z>{njzF8-nrIeT)Us3(IF-73Qu=yP6$ zBDfP;xHfeHX%#Ww0(t|CvRY`axOo%s7b6ZDQnZU-eLdwzDBdM9y;P4)73#+N5!WP^ z@Z93hO^Z~8vprSC$sm?oIN5(q!#9Zsk|ZEOi zJ)LFH5*QLLHH;7bAb~c!oVAfg#{FrIKG=20CD zQVBO6Ya}Acf_2-e9Hv$T_t_A+KaC|2UMo7kdC-gn`ERq;hqoCIRGhD&j}8{?6Y2;~ zNlpc^O1&>+#ZP;z$#W5IF&D>$@KnFFb`jU_&pWYxBf}azXyJ~~qLz}k$tuR zQU0;>4~DK&flMcy=?!E!Weu#~4qy$0A1hGq;3OIThA{GVu}#VXX%)qfAj2TV)zM0$ z!7rp9=);ivDLhJU4OnZ5u zvsA+7>_;XgaR?u+a4ro)iv)uSK-)146Q*;@^~+yB|wiO z42Tq58Fn8NWQ>nn8D=~#E5ij=J>_R8nV=eKs^UH1#o|)T3mB z*mHl!DfeVVB3FNeZx&sEbRbwT?>`69rCl%vPQj0`7$g%U6xU@JVLNo^7!Q`6bdNrG zBXl+fjn=cRChg2Gwbtqm&Yx@*yVK@WZ zPBgC{9uw7j-tfFDl%>m&r1Mb7b%6#|PKXKHsa8prC!D3cJXR%aQQn1dAvkC7edy$( z6m**riwGP;jo`2lc#4N(7U1CCcT5a|S2wv3h-$Nq^W3X3&!O7HJcn(Be(k(3BUJLx z3RIR~FBCS@@M2LGcbYSK>UQ}Kh{^l((6fZ<*HWH7pvPmBKRxVBO=DV@zgi91cHRhQ z@`_xSRC^jrjc_WdqTP!hJRxgoV*Ej1oN_U=qNV)?IZHJ!7`oTz#Gc~g*Zv+nt^^_-% zN7`8rbgIY?)A6>NJYRG)4~&X!=tQYxgxT=@ej&ur-DqM^*&RU+0mesXT?V}kj6_Rr zRv0a61zsh5W(=9ge=i;g0nxDN9TlzI@zX6ndi3Ua=kJI;i#hUQD_Ab)#JEHHKGO&$6tiNg5%UB0X>)?JGKZ zvfD(HsA^fzXb4^YROmdo5W|{M&s}?g{@H_u4i4z8P^ZL7B7T|V46@g*K?UHzLkoe> zH%?9UbkI#9VvLRBK~yVRQIhe)VD4d8^9RCRrjJ@n8XhHadvlt>?}3y4*%(0onsAK~ z_%1V!o&Cu<5qW0hoAVGQ?*!^XcOc)0TupU_DE8dnvh2WuZY?oouO+7aYgghLzS=)K zEi6%>s1JyT8>qjtzk$N@>r6!*llY#Za^iQP^tiE*}exNqFa;!eexS4Kz3$ z=TEPwmE0OuzJUb1<-Ci>7nh9q-&|t(8^;!>{~o;d=N}lEsuLvOAUM*O7>=QJq!y@g z0AE?xbUlwCKy?!+n;XSC!9lmw@I67c6m)tC*^>^d2m4-(f?{u6oWf2j3fG}(6Y4eP@nJW)52%D>bCI7YI2D; zkZxBmK~of{#88jQItZsP(rofZfJAXo#03-6q2~~ew#RY^SB@KMd`ABayk;BMQaR$s zlTTI(qr;fabmlI=^xF&`WHl{Bm!IVwlxU%Aiicu`&lK{J`$y_kA7L=O*rLexK&@Vlo+LVabw~bewAbzHyJ7dVXAUf#Gl@Dk%FZ+u z$bj^ORK&G~p215xa@3=wO$brnmXPsZx8?!4-dpdqvAKo0AC5%RF-pdMjK;TbC- zWsGas>(+_Rl*t+I0}c93x=Zk~%pN{I zuHp=UkYUe&8E_jl zbPR2F5;pePuR!~4Ct(qvKq9?rG19;x*ZW4m5$!oFr{Ei+8M_7_4N`eikm@V%hU~oS zP(xlYJ8w!yos39KtMb&F+%gMV`lW@X|1`8P(xnBmAR3j9zy_TvMf^$M5OV~K(Z%b( zj?u+vLHr0J-raPOw|YY3Rd^&q^pXft@AT)Vhg@1YUkRVbLUlT5BfBvKc_k^7$%~Jd z8R)#M8zZ1(Lioon&VVa&hIn#wB#(UAg+WJBsp~&n1EvJy;Lx9nhs-QaLOXir=pi0^ z5;ngb+f_9QO)cFBC&iAxNL3qHRp*t+O|6q2d|9nvf%3-SDJW1k&}8{xCrJ_FvlGs6 zal~bcI09n&LCs6QilJttphgmc_lx|KPPKdQI~} zr#a<<0!&M2z6Nf4MF;zZ{CqJ!FmvVrOrULDtVeFcSiPbRr%1!@DrLfNVQNM&iNA>! zWCkPS+bvNFj+?uVTP;s8fPH}-+zQ!f)bVf-OPN^8t|zjiTNWcDU+bTl6}nQLfoP*h z0sO+IUL~BHF4gzkhqm)aa5f1oWl}J53GiQ%P%B|tpZFs>K`@mJFqJ73So-PX&B8lw_=--B(M#`*b+Y4v#aYNr*^669 zx5l{LLPllGtFI!7()Qk6n>l{~l6d{;#C~BW^HBAI=dL{-N#T;vA3=;n{ZWD_jgDy? zL6o|ck|6fSD56ju316jVWI#j`3w|Wu8v&j4*DK#xd;vDKH}~o@IHWUmtX{AXYVyHY z2Rl-PABQp<}ougFy|=ksagWo z#)t)xe-RNj^kcKw-u=~-bG=Yb-d9l0#rnn{_fXEr#b@+OIUR5^`CkZT>OcCRtz-bS zty>d^w%FLh-y-}I)18R}ETXqbcV?(l3!R6u3Zt{VM-vDooPPL6@EYj2c=5OUT`=Ld z>P`WnpL88WahEx8e=;zSyc-I*UOaNv0R3zDWn%v*%0i5FSbq;#VSjhj8!xDdGPlxuNW22{{k zfc^PtV5pJs4Fll#5`Rfn=wfv$Fx7{lQsT%TQS6<0Cq<0$a0~*FXQEaU!F4Dr4>8Mw zHuKD2v@){zFoi$nG)&;Mrn-(72bzi9ZGBK)Gyux;f02mt1Z>ry9+%hDEQwnn;t)2> z{XU8?S$fb>b^K0$fCzgB2kVkyQ{DAxXeTY*OF)VpId=_^*C(f{!Z^w|e} z`ZaHWe%-V>v0wf2-{<<&x0*_l0jfOl^Z%gA!oF3m8@S5f##c!%yW|mlyzKb+FgAg` zobRwVoyAT53vXa=3X}CN{r2k&ZQhic$vVWW%vrt$vbJ4CD>Az(Q?677+EuiYva6^g zwW~(Ub&OmumMc#^uphIl=yG9KjhE|Ha?Qn6-;84mXL${8=g@}D#N7S67pQ}6D-P<@ zZLwd{*?D}FVOL#;vN%q%tER}!2)k+-Z}#ZzuVc4wSS*zHJX*{6|F;_h^TuAt7uW$SsITXgP@r-2XO5LX%3G*~bo?;6ACsyDb6TRaas08X4pyN=etE!o} z0bd`C#VP|w=BldHJh)g@%`$f<d!yN&N63Y*Ym2X?sxBTCtm*qHfHJlJTvzdEEKsJ4dE*friRrR8U_cE8o$3z#*s6p38QQzEVB9fKrGE=mor?<{ ziF8q22y;lxqq--VT2O6{R9pIA zbCBmK<}J>J>Nw8u&{0lV(Tc?FaA<3d_75Y!4DIuwy)S1myIf{=IklU1c?Pa>J_DVG z(eGQ*fgBgk!l3>oOu7t^t5G-sNT_0@H@RQ}Ir3pCydJPQ?)q~iavQ8S={|uKYdNPi z+)J$GoYs+ew&Dm|fv3q#ys_)&w4ygt6`QQlSNN*eWCaFaz7n_wb>JXk z2#~3SGujprsf0P&mas_S4z@IF3lOS`IJ7NZm0;4gh)*TFTrJPyTg5AE$*hs`hLG6; zpWz#}0A$w@b|pUkw#A;SD#4V+s}jy^Tf`SkHgL5qUR9M~&Ei#63GOVp=AZD_*W%&g z`^tCK;IC7~D|Cqr(0e&e+(tmI92+Arig?X>-zhX4VISdpFDe<%`dH8DXdBNl^6a&t8SXwP*>5 zx%O!;$TRQ>IGGYY24_4hhGpyQ@J1>PzX3x=l{b%i1YgBD_`!hU6>yS+t(H|*;Rz45 z%9i5QAiRQ6CG_V`V0BQ>qJY`g1Q^(y15gOF%w$kR> z4s5amTS2D5uz|vvO`hkHT&z+jR=5 zb)7<OEi=ZkrUSsOho>EzEDTMfb{0);t`6T`k`yRq2Xh`feG)ay1Tg_5Qq z!mxL*JsA1)+INyPys8W#Hd{SbQ>yo&l4x(NJKAtUfe6EQbi&N5HfB7-WA9X}X%L=? zGW+0$;!!g(Xv&KnMD$}-R%@3b` z2MdBU71n;7Gz~z{&^Sh$h_BpNaRs^xWB?)r>48bs2AGz48wt@vrRsi$1&U&~W;5u$ z*-5?vc5uivltgp5FJJG@?z+(qx3+%-U@)sz$q;Ys<^}~sLC6BD+ zH4I|!!iTfN2iZGPrAt3k#KQh?_E@z?Z2hv~8`A0$&7M*c&8jHTY{O4uuoX2;dU>qsdc zHV0>ypMrPUWvhe5UQ~k!!>Vj!5C>e#Hhl@xKgREcV3NPyuMPnqJAWf%3lLHixeG-= z%hp96>xZyfYSO>^BX$Yto}!r`g4)C6vLE3IqEtL}2(%yBBF7Q|1jgq+sj?Z*^!4xq zR0r)R4&n#g(s7dW2+2@db9QXRQ}qa2cD@%<|F$3HE%f(x<$k^)<~OJpS-JY$Srn3= zF!PgG8ZWYbc~T?GZFK3{!KOsWlS-Ty*@#`un$_nl-~KiyqXa$WiBcMWh0}{OZY|E5 z2~(pC_4qvW&whfmFLHzq}wej6Lu5JC&^R-KThMapY=v{9pF~+b#_Hm7Z_Y z&9drIgBEDBQkhU^o9#&crefb zM~oC8Mm0vZP(ZPru^47kHX_4fS6+-K`u7hax_jhB4w_TB23O2uQ{#UltbI`gEff|O zLh^@{pXq*&QIsLn7q5h?sC*UuX!II9G2ahHnwj4y22U5|#!qsWk&0b!!M+B%0e%apobvhq_39)?#Ce1tkT6L2wvmEhN~xF z3SGV*ljdb~6H9hC6sYhB8jW0qIDw0vzfBX&lpR$^5#UM<7GtMJPkbhhrYgT1=DP3< zb>W9e>5Oi;f@m5l{F`nsxyclmevGaV9UjeY^zvb~vvgK*c7PeHn zo*__dX;rU9P&J-r{{UctkT*c(?b`L9JQ%pHY(XU^n8yT^C{Bq8t1~IBzzB8_RNFMw z)c#A)H5v>nF#@HzZst}J{P6Y zm9JGjaTILpFkkTd?6&paT{w`vp%tt_N%Ii3!vJE7#mGX zIzi~D-lKmC|C1)!weV*VA3Bv?s32$>LH1q1<_Jpl>=0H?dF$G)1Q~zBk%1^`IE#tj zKYQSK#Ow~Xe+&xSooQDdMs4avjtNcCK*XmPGW}FR5zR#b9wIqHI01kMl#H)kz7C)? zl}BMTMg+wX6JZgSkd#05k$)jifr|-)z=(7MRv+xAODg*Su`+{F$pOl> zc?@7@*sPDkTrj3dp{N@p5KKgTc{1$t^Kw@6OY9j-_v0}4wrEP~_=X1mZw;-CZ)n~B zyN0aJOC>ZHCKtn$AWS*FUwo}mpak`0tlH?b#At1PuiDXtKDw5@sLKnp5Qe7}6;Q0- z+&g1A3Uby)#SXI^ol4CsY(rr-Lbt#6oook1b9)s99~LNgW1Pa@_187GMEs$hm$5*sxF>$o%*~c{1W;0Qof&EA)oCWmdXl)>IG%D@P z(HT9Z;-#HH=ex7_x8(141(Xw@QBm5>`em9_7^1IyP53xAI zgVD&#LgQnz&o{S_md@j%HXNt)_x;KM^?=W1> z$Ul+qr9b|ef7CjjQI?9`g`Iy?Ss57PoaToIsb*!#WTdkiz(Dfb-cT?ll^=_vQX}z^ zlL=Wloj1u-ysvoSY&0dwd%zO*=n17bQwDnva4f05q`Uh$>ZB-n()c-{e+;4!)&E*q)qhPfoKZr~3nKNRtuJzKWls2T+(4 zAYNIIYhoE5`mr5A-sCnlwbWH0Aj;NoIMc&09uI6Ev9SbDzJ5Hr5fzi$kl%9kz(_It zUr$WPUa*MsU|BInB1$kd5lG6nAEnp^C3yq4 zf-PnPWN~OY%2`Ktc{8pM=e^A?#QELO@H9i?)qmxoESLPkXSk#n9&UPw-nCN*;&=V5 zs~4%+hgDv>H!m4@0agS*uOE*#mY3%BwhzYV2rl&8;h7`d}>mHMVwK-3t4mi4b zp);RaBGu+J`y8?WzYO5wVX?1O^Xtc5_zkK$=KEp&kCC~?pPzwXEi@-3=X3&x5|&`> zyYfQWi0IIe4E4}pgSYH}wlpX%x#Mg6`b?Eq>dg!F2ffb=W7M0{5VX#VXuCJT8~g;0 zyCgN@*M3Ly({y8%J91!#^HJvi7lu;}ijOgzpKw-VtdlwB@eDA6*j{Lhql^#t++wT8N05>xCFLB% zhX=t3aTx7AV5d1ZCV5{KEi7meNo1`$@=%W;;e?TjoU0};zQ`-Q73lGDpP!7t9hk7> zyI9(WLWlzMm0#vvDxMDVcB{w9&LQgLyn;A_2bG+MdG~r>w`U* z_iEzpwnTRGgdoqY2b>JYaw@v)bKzc`>aDv0ZAQDF9_2HFhgh$B)&RAc+@F#b>?Gg= zA61|OL+%<-OD!fM5wLrddd9use@w*nbN!Dk!?VyCYQjQ)@F+NVG-Suhw$CCRh?S70 zGq!`K0zFZ8{{X9fIm~a%TSV&y{@|kFjf>|y8 zE~e#~94RBpq(T4+1UY3utdfV2MC<{Cbac|Mz`}`5L~$giyL1?x`0jc>5^4O$ppIPc z9!Bc?9)7ABClHD<`)xdK{9w?{PO?9Uy&L|P2leJos5%BSE#=}G?b>+rWsAO~~7nXbRC z1W!U|i@PHyRSX+ggXr#740RmW>CZc4x%-v`5J(^}U>a46$JAA* zFxDoXBRa4v*g`{@hFb20{(?vU32Tw5z}HmGB?kXJqH}>XYp>-K|60!%(2OVsAx_NXd8q2SsmX(ZlMd((Ic;IUhfKs;XWBXtF1l z;~nr3&0Q~a|}AZFt1uCUKP8_|e*PzwJt z^e>cwEh%|tQ=k(+JsrsTT%6*p;AGS@{{1=E@lhhM!ea#bMJHbazX<{>uo%q+eR1tQ zRQXMO9$+8Aw1k2e>D=??A%vi>f;k+?a}q{cL?K`0X?Qp8m?ONgpaAN;c4VYM)2Cr0 z#)*tbi}Ju%>18c>^F+`2>wg$Mr;TlN7<>2@IU9A)Crew*!Dx&ATY1mHXp5eY=T;pV z3kLUG{84!e%>nf(`~i49NCK|+5BoflaxtI8q75-d0FK6}MiSc; zPdo(KAvf9fK~7Mqs3u1G{MNeT5Kg%l^86972K6K0VlW5@x7>}WPWcCOn#*oS^VS`$ zIHGJrEVN{_0p*0o&}3YM`;sC#*@9c=ftW`3Fj5IAE&>L3@P_g3&7RQ;FcDhzw7Uln zMKA&ejbinszv}QxDwUj9utvRN77xfbIE70;1+U}w1QQ|n$W{Sje15c>LA~=7aIA1k zTqm*oHWx!EsO2cdA_?tdKCos47qQCrgFji%@GXMhjo_b-Q8XArrCQQmypQ=WNRxrK zEta8o*FWbSkARYeB>B*-~IVm`WTfI<<)AAQpw)WRBwJ_BiNm@5nu;qpy-j zFpk3`H~rMJNeI(052TIrnxlLY`~VbFy&e!l)yeh-H&xDp(h=W4r_ARuurVv`%1iN1 zRa3CC#Rh(w5f7tv>gfUV^^+{_K~-#Z+-B+h}MYX%o;fn zjG_~8L6(uPA)!Qr2XV<_=8+&)XvFJ=i+DlgMM0!N#s2+3g}MFsH%XrM3)9h6IcjtP zsb;tA%9RAl1#p?%hkzTqa;e;x$bE$ic!KN$un?c6awFdPR}kRPwY1ggO+@s54qf11 zLH$5%Ug#7P8_BK~$f^kw4$?6} z5%S}ZoqrgSPTb9AzeJ2(E^1Lv@bJ$mJE%U9^B){Z5-3C-|V6Z&wzUxW-`VH>d! zi)jRjFV$etPPMD0hk{eta~69(Jq*Tw(6thP3qY!A7TaQ}P7P*sAKO`nwj4PX?!9{= z!5y<-T#o{V4TRJE+t@K*1tOVv{4eq-*;mOuv;W2Ia=!)lR0UV^m0ih)`hvkw%*km| zU;BipLO7%&sj*T$>OCBPv!ZvO+JtM1BUf|${lT+5y5>v$#{s@%2= zqa)+n8b_uQ97~Ca0W^Mk1gjd-c$r`~{f@n_;uF-P{eT4w^ndAXi9Wesm|KP&gbdcV z&-&lRdrwQs$&zKlz z)WcA()ler9so6wSNvI(jo~UqJ$6eM=t_hw{p0$%@5P1+)dy#i2-1g)o@3t(wq>{!C zx2afbqC>HEY(?Xc9a^D83Uqq+06P2$P|Jc7T_GKUA!b7S90o8_gZepJ#5UWMVPN`B zY(;+*1>lYW)`$EkGr3N^xCTv^HwjA-n+mjSHPDs{7AAb>yiBHImyf|!o*uWWb8+7! z6B0LAge>7S2-c7wEMm@J&A{qn)&^CxkiuZx%3>Hemg*tMa1OqFCwX`)Ym6&|=QmnA zI6A@(IC!4WRr-lC6NgMJIV8rFGLfnbQ`*c#4(c^nH|)j-QG)KcMs)}rreOFp!8t);fL#L;?)ANwT61v6fY$EsqRTo|;o-r!BGEJ>jveI|^%nK+okHLKT{npTyd-7FB;_zIKtRcu2o{%Xz*U*+#`Md<9x z1ptLHT5o+5q$VtycGT_5S*@ugRh5iY!p!X*#0nShi}Vu@5e7m)sNxAG+BVC=2ErYC zCMK6v*l_-K=4Mwyw$ee#skMW&!c@Dxj4D3u*sWG@!ec($friSxi!<)7=9bIrZS+DF z)zFdUQYe%kV2KH;dCY>O0M@%@M6O}8SxdkrzNaS3MkX{(i41D?G091N_A!o7FvLTS zB6l;b#EscnR%f7AY%qmMJ&4Etmr`zDL*o#;+Bi>z#+VR` z-d6yhnp~PK*hA1aC(uxo0XT!uQ|d<8Fe?E)NBZTfq@p;=RUZasYem3|4yl<1Zv&_w zxU32SmXPuWwUjcDLeS|?k9Zq4&}#PJh9K1S4AExYb9j&;yr4c0qNYNyy4>XKW~Xu% z`UtTus88Z!Lw>o*-oPPjS(Qv45DPs2Q<0c;Y>eijDEJC-$ebh@`i|jub2(hM0UW4|I68u4EOX-eZ zq;_Ncco4)PIMF}EM?GvkM0$+l*k-%nnih(TZ&$aXv#OFZzLBSu$oNL8R+Sa#gf6R_r3w@*ST|S zsn6Kb&#Qfh8^f#6Fzh_JCk$*dfmsov(E63s35!>ncq2~X8u*DJZs7)En+tCeQdagB zq02VX&eAGdcOP_}tKWi0F15 zCY)37@RhGD%2dsb?P*uOy6B`vopI$si3X3{2rzzwQRrU3EMW1+*~Zj=Ldc8L3@5P8 z&R-W)dtj1FSADCMcFZ+FXeBr4BTK$SqJwo1$JSYQtj7!qo_!3A#rpdf)*f$xDf1%A zs6YdZe5vAMjK+hQjlk;{QBgLqN#ZrCv7Dt07rCeiMBNj%F@F;jlMLIq#!xm*;Ja@^ zNSo)M1jUZ#A<_SVR$mLn)2igTj-N>g9XiJrqhO&`wn5DaN2{NWJR$~2G_{^!k&N*e z8itvme*^7y`{yLSiN66`_hBye-7j->`31@_&{%kwnp`BBw#sTeVv}wB8wVbWS8m`l znU{?3c<(5r5JAbY%Tl;YLX3F+#q>=~Eg4df^21Ej z2PV{UH9XW{i+mZ# z57heiOZ=e);LAS-vLL42-g~=wvN57Ylb-cJCK4COJkF8;OTN8v?i@jkxq<;$3KT zREHJ5sW*_sI4F#Kd~n9E!k`C<{~jP!mlg z1Mq#}LU~4^vAjYQ%x3-ZdSu^&3CngyR@*MNkq4&hyLP8wBNsf^9NVzZ3*x5@`fS}% z>tWwQ+3=~!5dg~0aVyrx{s$79M~Mk5+4AJ`yTb3NvhDV^TTrE{TgI`EgbD^=3D=ks z{k=7!{nq#aknJQ864-97WA!kw*aX7_u3==^Sb+5RhXSi=K1m~71G8}`%MSu{_%I!I zJ!T0U++lD65vUEFf@9g?IKIU(%XK~%1^aXsW`rc2{-cV@e9a+wKOzog|`b9 zey*{y{pWUth)ZC3LM+=+%Pg$%DAsG2lD}P!+^%I0@K!%J1QA)wYS1H%y}g~kHH`3l zTh)xVZ0aIl@iLOYbOH!Qi{JqF2hIgcDKQXT$uM+y6$gwn0VH+H@1~X{Q z)25+kk?{T?VmF63s+Th2i4*j|h*;ae!1dRE>KgF6#;(qm8dT+4yIxv|Ni_A}Bvm6p zp4Hn*9sPXEd@|XPcw?pm;8&MUicbz>oZOuJ0Z%?&E7M|o|q

    r)9Sb4qXOL^Uls6+ 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%0DRuN$z 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%0Da;S-|M=vL<+5-}vPi99YccdWfNz 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 z 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

    u8*c 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

    jIin7Nu>97`4j2G6Y23YZH3#+K$o)3d_YRl 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

    &>1f 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 E5mk%1-fcayR^hw4zfuwByIkin~Xt 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%0AgtF`pTc@=wF=hn#6KZleFl{S>$To?u)hCQ0_(kn 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

    @Wqqu{-*wqA%Eui)U{iRGr340Kg$)v2 z|LOZHB-jr9KqdaC2aEL9N4L01c}IpP&@m(9OrFsRK;UX5wqb(0@4RWUUf;IaS$XC? zxiwHY-%zj)+I8I2J|QtRlljvlKV#PIK7(821S#{<+^XCJN6Zpi=)$bF8AChuf~MUpimsKg}H?zybiXR6ccHS zzKzqTzy+kGDS4BilS^luDYIm^ds5_bjr_Li2tu{W68!{+&e2`QyRBm`&Y2q%1pS<>CL1WyMu{;euO z35(z#Yuwt~clY)n@!V*#%6LKp# z=ySFSF5;l`ZDG|1M(RRYr+TbbCNk2uf<3H zjtIY6V6E4Z>r@-{_h^^H_3`l)THwtt71-#OJ=qv??wcF=FYBVDDRsN>OD&Y2@1Is0 z&ER+I^>UU8i2*s*l=VzaK6;b~>r-$O-E%RFQ*r0uK-yzt@S{I9 z&zAc1*rjH>?R5VfbKkoDC-tneJI!4b8Cf`11=@zOxnj%%fMDeWvtrb$JB_&J5+8;l z_FR5yX_ZK_yz1KzyJjjQ20u0kEZYzuLKvsH&HiQ2B#gjROf3hmYk_O;$%vLl_~K&9 zi>YP8x%p&9B~vWXuiEmy8##9rG=Fktg}>ju_>CYOVxXagI5^aK4<+o^wEm5qIzs3I z7~PRp>)nwC#*MbA_N$w|^*{)JUOFI2Bmx3estOSv#-ThCNfrdBXJt8Ef0&9Ens6y@DN>{qM&G81T z1K2peK2zg1F1xSxFNfIJ$ZyR|X

    cMhyXsH4C`Irvw&iOCgjPO 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

    gBb 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μ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 I={mPQHqv)3K;{=!<>HF=f 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%0D)%e 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

    bz5adtzpix8qW0tbTR~HM7B!H_3V3VCH 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

    m5~4N-_$cE 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�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ʩo7o3yYXOPRfia0JjJU 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¨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%0DQ=s$lcgnAD?)Mv2~ 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 Tak`DIKtO+&Z8}d64y*qkUUMfS literal 0 HcmV?d00001 diff --git a/trunk/Arduino/FloppyDriveController.sketch/FloppyDriveController.sketch.ino b/trunk/Arduino/FloppyDriveController.sketch/FloppyDriveController.sketch.ino new file mode 100644 index 00000000..f3e61c8c --- /dev/null +++ b/trunk/Arduino/FloppyDriveController.sketch/FloppyDriveController.sketch.ino @@ -0,0 +1,1607 @@ +/* ArduinoFloppyReader (and writer) +* +* Copyright (C) 2017-2021 Robert Smith (@RobSmithDev) +* https://amiga.robsmithdev.co.uk +* +* This sketch is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public +* License as published by the Free Software Foundation; either +* version 3 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 +* Library General Public License for more details. +* +* You should have received a copy of the GNU Library General Public +* License along with this sketch; if not, see http://www.gnu.org/licenses +*/ + +/* Latest History: Last Modified: 22/04/2021 + Firmware V1.4: Merged with Pull Request #6 (Modified the behavior of the current track location on Arduino boot - paulofduarte) which also addresses issues with some drives + Firmware V1.5: Merged with Pull Request #9 (Detect and read out HD floppy disks 1.44M by kollokollo) + Firmware V1.6: Added experimental unbuffered writing HD disk support + Firmware V1.7: Added suggestion from GitHub user "prickle" regarding the CHECK_SERIAL function which should reoslve issues with some of the USB to SERIAL converters + Firmware V1.8: Added support for read streaming with index sync support which includes timing data (for perfect copy of flux data for SCP image files) + Changed read timings slightly which means more disks can now be recovered! + Added support for PRECOMP disk writing (using PWM in 'one-shot' mode) to improve readability as you go past track 40 + Added some new functions which allow for more direct control of the drive + Remove the Erase function as discovered you just need to write a longer track to ensure you clear the gap. Workbench writes 13630 bytes per track. The first part is filler at 0xAA + Added support for disk change notifications support (requires small hardware modification below) +*/ + +///////////////////////////////////////////////////////////////////////////////////////////////////// +// This sketch manages the interface between the floppy drive and the computer as well as the // +// low-level disk reading and writing. For more information and how to connect your Arduino // +// to a floppy drive and computer visit https://amiga.robsmithdev.co.uk // +///////////////////////////////////////////////////////////////////////////////////////////////// +// This code doesnt actually do any decoding, and is mearly reading pulses, so can be used to // +// read data from other disk formats too. // +////////////////////////////////////////////////////////////////////////////////////////////// + +// ** Hardware Modification Changes to get the best support for disk change notifications ** +// Pin 34 on the floppy drive connector (Disk Ready/Change) must be connected to Pin 10 on the Arduino +// Pin 12 on the floppy drive connector (Select Disk B) must be *disconnected* from pin 16 on the Arduino and connected to Pin 12. Note you *must* leave the connection between Arduino Pin 5 and Floppy Connector 16 in place +// On the Arduino, connect Pin 12 to GND (0v) - this enables this advanced mode automatically. +// If you can't connect pin12 to GND because you want to use the ISP headers, then see https://amiga.robsmithdev.co.uk/isp + +#define BAUDRATE 2000000 // The baudrate that we want to communicate over (2M) +#define BAUD_PRESCALLER_NORMAL_MODE (((F_CPU / (BAUDRATE * 16UL))) - 1) +#define BAUD_PRESCALLER_DOUBLESPEED_MODE (((F_CPU / (BAUDRATE * 8UL))) - 1) +#define UART_USE_DOUBLESPEED_MODE // We're using double speed mode + +#define MOTOR_TRACK_DECREASE HIGH // Motor directions for PIN settings +#define MOTOR_TRACK_INCREASE LOW + +// PIN 2 - INDEX PULSE PIN - used to detect a specific point on the track for sync. Not used by standard Amiga disks but some copy protection uses it. +#define PIN_INDEX_DETECTED 2 // Pin used to detect the index pulse +#define PIN_INDEX_PORT PIND +#define PIN_INDEX_MASK B00000100 + +// PIN 3 - WRITE DATA +#define PIN_WRITE_DATA 3 // Raw triggering of writing data to the disk +#define PIN_WRITE_DATA_PORT PORTD // The actual port the above pin is on +#define PIN_WRITE_DATA_MASK B00001000 // The mask used to set this pin high or low + +// PIN 4 - READ DATA +#define PIN_READ_DATA 4 // Reads RAW floppy data on this pin +#define PIN_READ_DATA_MASK B00010000 // The mask for the port +#define PIN_READ_DATA_PORT PIND // The port the above pin is on + +// PIN 5, 6 and 7 - DRIVE, HEAD MOTOR DIRECTION and CONTROL +#define PIN_DRIVE_ENABLE_MOTOR 5 // Turn on and off the motor on the drive +#define PIN_MOTOR_DIR 6 // Stepper motor output to choose the direction the head should move +#define PIN_MOTOR_STEP 7 // Stepper motor step line to move the head position + +// PIN 8 - Used to detect track 0 while moving the head +#define PIN_DETECT_TRACK_0 8 // Used to see if the drive is at track 0 + +// PIN 9 - HEAD SELECTION +#define PIN_HEAD_SELECT 9 // Choose upper and lower head on the drive + + +// PIN A0 - WRITE GATE (Floppy Write Enable) +#define PIN_WRITE_GATE A0 // This pin enables writing to the disk +#define PIN_WRITE_GATE_PORT PORTC // The actual port the above pin is on +#define PIN_WRITE_GATE_MASK B00000001 // The port pin mask for the gate + +// PIN A1 - CHECK WRITE PROTECTION +#define PIN_WRITE_PROTECTED A1 // To check if the disk is write protected + +// PIN A2 - CTS Pin from UART +#define PIN_CTS A2 // Pin linked to the CTS pin +#define PIN_CTS_PORT PORTC // Port the CTS pin is on +#define PIN_CTS_MASK B00000100 // Binary mask to control it with + +// Reserved for future use +#define PIN_HD A3 +#define PIN_RDY A4 + +// PIN 13 - Activity LED +#define PIN_ACTIVITY_LED 13 // Standard LED on Arduinos. We're just using this as a read/write status flag + +// ** Hardware Modification Changes to get the best support for disk change notifications ** We control these regardless +#define PIN_DISK_CHANGE 10 // This is actually disk exists pin. Some drives have a resistor that needs to be added/removed to get this operation. This is usually the default on PC drives. +#define PIN_SELECT_DRIVE 11 +#define PIN_DETECT_ADVANCED_MODE 12 + + + +// Detect advanced mode +bool advancedControllerMode = false; // DO NOT CHANGE THIS, it is automatically detected. If you can't connect pin12 to GND because you want to use the ISP headers, then see https://amiga.robsmithdev.co.uk/isp + + +// Paula on the Amiga used to find the SYNC WORDS and then read 0x1900 further WORDS. +// A dos track is 11968 bytes in size, theritical revolution is 12800 bytes. +/* The ATARI ST could format a track with up to 11 Sectors, so the AMIGA settings are OK. */ +#define RAW_TRACKDATA_LENGTH (0x1900*2+0x440) // Paula assumed it was 12868 bytes, so we read that, plus the size of a sector, to find overlap + +/* For the HD (1.4 MBytes) Disks the amount of data should be about 26688: */ +#define RAW_HD_TRACKDATA_LENGTH (0x1900*2*2+0x440) + +// The current track that the head is over. Starts with -1 to identify an unknown head position. +int currentTrack = -1; + +// If the drive has been switched on or not +bool driveEnabled = 0; + +/* Where there should be a HD Disk been read (1) or a DD and SD Disk (0).*/ +bool disktypeHD = 0; + +// The timings here could be changed. These are based on F_CPU=16Mhz, which leaves the resolution at 1 tick = 0.0625usec, hence 16=1uSec + +// There's approx 4 clock ticks on average between noticing the flux transition and the counter value being read/reset +#define TIMING_OVERHEAD -4 + +// Calculate the bit-timing windows. These are the ideal exact centre of the next flux transition since the previous. +#define TIMING_DD_MIDDLE_2us (2 * 16) +#define TIMING_DD_MIDDLE_4us (4 * 16) +#define TIMING_DD_MIDDLE_6us (6 * 16) +#define TIMING_DD_MIDDLE_8us (8 * 16) + +// Work out the upper window of the timing. Most PLL allow for about 5% drift, but we're not interested in that and just want to recover the data +#define TIMING_DD_UPPER_2us (TIMING_DD_MIDDLE_2us + 16 + TIMING_OVERHEAD) +#define TIMING_DD_UPPER_4us (TIMING_DD_MIDDLE_4us + 16 + TIMING_OVERHEAD) +#define TIMING_DD_UPPER_6us (TIMING_DD_MIDDLE_6us + 16 + TIMING_OVERHEAD) +#define TIMING_DD_UPPER_8us (TIMING_DD_MIDDLE_8us + 16 + TIMING_OVERHEAD) + +// HD versions +#define TIMING_HD_UPPER_2us ((TIMING_DD_MIDDLE_4us/2) + 8 + TIMING_OVERHEAD) +#define TIMING_HD_UPPER_4us ((TIMING_DD_MIDDLE_6us/2) + 8 + TIMING_OVERHEAD) +#define TIMING_HD_UPPER_6us ((TIMING_DD_MIDDLE_8us/2) + 8 + TIMING_OVERHEAD) + +// 256 byte circular buffer - don't change this, we abuse the unsigned char to overflow back to zero! +#define SERIAL_BUFFER_SIZE 256 +#define SERIAL_BUFFER_START (SERIAL_BUFFER_SIZE-16) +unsigned char SERIAL_BUFFER[SERIAL_BUFFER_SIZE]; + + + + +#include + +// Because we turned off interrupts delay() doesnt work! This is approx ms +void smalldelay(unsigned long delayTime) { + delayTime*=(F_CPU/(8*1000L)); + + for (unsigned long loops=0; loops>8); + UBRR0L = (uint8_t)(BAUD_PRESCALLER_DOUBLESPEED_MODE); + UCSR0A |= 1<>8); + UBRR0L = (uint8_t)(BAUD_PRESCALLER_NORMAL_MODE); + UCSR0A &= ~(1<170) { + stopDriveForOperation(); + return false; + } + } + + stopDriveForOperation(); + + currentTrack = 0; // Reset the track number + return true; +} + +// Goto to a specific track. During testing it was easier for the track number to be supplied as two ASCII characters, so I left it like this +bool gotoTrackX(bool reportDiskChange) { + // Read the bytes + byte track1 = readByteFromUART(); + byte track2 = readByteFromUART(); + byte flags = 1; // default to normal speed + + if (reportDiskChange) { + flags = readByteFromUART()-'0'; + } + + // Work so its compatiable with previous versions + const unsigned char delayTime = 4 - (flags & 3); + + // Validate + if ((track1<'0') || (track1>'9')) return false; + if ((track2<'0') || (track2>'9')) return false; + + // Calculate target track and validate + int track = ((track1-'0')*10) + (track2-'0'); + if (track<0) return false; + if (track>81) return false; // yes amiga could read track 81! + + // Exit if its already been reached + if (track == currentTrack) { + if (reportDiskChange) writeByteToUART('2'); + return true; + } + + // If current track is unknown go to track 0 first + if (currentTrack == -1) goToTrack0(); + + if (reportDiskChange) writeByteToUART('1'); + + startDriveForOperation(); + + // And step the head until we reach this track number + if (currentTrack < track) { + digitalWrite(PIN_MOTOR_DIR,MOTOR_TRACK_INCREASE); // Move IN + while (currentTrack < track) { + stepDirectionHead(); + if (delayTime) smalldelay(delayTime); + currentTrack++; + } + } else { + digitalWrite(PIN_MOTOR_DIR,MOTOR_TRACK_DECREASE); // Move OUT + while (currentTrack > track) { + stepDirectionHead(); + if (delayTime) smalldelay(delayTime); + currentTrack--; + } + } + + if (reportDiskChange) { + // Now see if there is a disk in the drive. Returning '#' means no disk in drive + if (advancedControllerMode) { + if (digitalRead(PIN_DISK_CHANGE) == HIGH) writeByteToUART('1'); else writeByteToUART('#'); + } else { + if (flags & 4) { + // We've been told to check for disk presence regardless + if (nonModCheckForDisk()) writeByteToUART('1'); else writeByteToUART('#'); + } else { + // Don't detect disk + writeByteToUART('x'); + } + } + // The second byte is '1' for write protected and '#' for not write protected + if (digitalRead(PIN_WRITE_PROTECTED) == LOW) writeByteToUART('1'); else writeByteToUART('#'); + } + + stopDriveForOperation(); + + return true; +} + +// Checks manually to see if theres a disk on un-modded hardware +bool nonModCheckForDisk() { + register unsigned char lastState = PIN_READ_DATA_PORT & PIN_READ_DATA_MASK; + const unsigned char indexPinStatus = PIN_INDEX_PORT & PIN_INDEX_MASK; + + // Configure timer 2 just as a counter in NORMAL mode, we need rto measure approx 200ms (a full rotation) before giving up + TCCR2A = 0 ; // No physical output port pins and normal operation + TCCR2B = bit(CS20) | bit(CS21) | bit(CS22); // Precale = 1024, ie: divide the clock timer by 1024, meaning each 'count' is approx 0.064ms + OCR2A = 0x00; + OCR2B = 0x00; + + // So if the disk wasnt spinning, we allow longer + const unsigned char totalLoops = 18 + (!driveEnabled ? 62 : 0); + unsigned char counter = 0; + + // We could do this with timer 1, but hey. + for (unsigned int loops=0; loops=3) { + TCCR2A = 0; // disable and reset everything + TCCR2B = 0; // Stop timer 2 + return true; + } + } + } + } + + TCCR2A = 0; // disable and reset everything + TCCR2B = 0; // Stop timer 2 + + return false; +} + +// Test if theres a disk in the drive, a '1' if yes, a '#' if not +bool testForDisk(bool sendOutput) { + if (advancedControllerMode) { + bool isDisk = digitalRead(PIN_DISK_CHANGE) == HIGH; + + if (!isDisk) { + if (currentTrack < 40) { + digitalWrite(PIN_MOTOR_DIR,MOTOR_TRACK_INCREASE); + stepDirectionHead(); + digitalWrite(PIN_MOTOR_DIR,MOTOR_TRACK_DECREASE); + stepDirectionHead(); + } else { + digitalWrite(PIN_MOTOR_DIR,MOTOR_TRACK_DECREASE); + stepDirectionHead(); + digitalWrite(PIN_MOTOR_DIR,MOTOR_TRACK_INCREASE); + stepDirectionHead(); + } + isDisk = digitalRead(PIN_DISK_CHANGE) == HIGH; + } + if (sendOutput) { + if (isDisk) writeByteToUART('1'); else writeByteToUART('#'); + if (digitalRead(PIN_WRITE_PROTECTED) == LOW) writeByteToUART('1'); else writeByteToUART('#'); + } + return isDisk; + } else { + // This is much harder + startDriveForOperation(); + + bool diskFound = nonModCheckForDisk(); + + + if (sendOutput) { + if (diskFound) writeByteToUART('1'); else writeByteToUART('#'); + if (digitalRead(PIN_WRITE_PROTECTED) == LOW) writeByteToUART('1'); else writeByteToUART('#'); + } + + stopDriveForOperation(); + return diskFound; + } +} + +// Check if the disk is write protected. Sends '#' if its write protected, or '1' if its not. If theres no disk in the drive this number is meaningless +void checkWriteProtectStatus() { + startDriveForOperation(); + if (digitalRead(PIN_WRITE_PROTECTED) == LOW) { + // Drive is write protected + writeByteToUART('1'); + } else { + // Drive can be written to + writeByteToUART('#'); + } + stopDriveForOperation(); +} + + +#define CHECKSERIAL_ONLY() if (UCSR0A & bit(RXC0)) { \ + SERIAL_BUFFER[serialWritePos++] = UDR0; \ + serialBytesInUse++; \ + } + +// 12 is the minimum number here. Any less than this and the CHECKSERIAL_ONLY() code will impact the output. The pulse width doesn't matter as long as its at least 0.125uSec (its the falling edge that triggers a bit write) +// Because only the falling edge is important we achieve precomp by shifting the pulse starting position back or forward two clock ticks +// Because it may go back 2 ticks, we increase this number here by 2. 12 ticks is 750 ns, 14 ticks is 875 ns and 16 is 1000ns (1us) +// By doing this, the bit cell timing remains constant, but the actual write position is shifted +/- 125ns as required +#define PULSE_WIDTH 14 +// This is where the above starts from the end of the timer +#define PULSE_WIDTH_VALUE (0xFF - (PULSE_WIDTH-1)) +// This is where to start the counter from compensating for code delay of 6 ticks (measured) +#define PULSE_BREAK (58-PULSE_WIDTH) + +// This makes use of the PWM output to create the wayforms for us as accurate as possible. +void writePrecompTrack() { + // Check if its write protected. You can only do this after the write gate has been pulled low + if (digitalRead(PIN_WRITE_PROTECTED) == LOW) { + writeByteToUART('N'); + return; + } else + writeByteToUART('Y'); + + // Find out how many bytes they want to send + unsigned char highByte = readByteFromUART(); + unsigned char lowByte = readByteFromUART(); + unsigned char waitForIndex = readByteFromUART(); + + unsigned short numBytes = (((unsigned short)highByte)<<8) | lowByte; + + // Setup buffer parameters + unsigned char serialReadPos = 0; + unsigned char serialWritePos = SERIAL_BUFFER_START; + unsigned char serialBytesInUse = SERIAL_BUFFER_START; + digitalWrite(PIN_ACTIVITY_LED,HIGH); + + writeByteToUART('!'); + + PIN_CTS_PORT|=PIN_CTS_MASK; // stop any more data coming in! + + // While the INDEX pin is high wait. Might as well write from the start of the track + if (waitForIndex) + while (PIN_INDEX_PORT & PIN_INDEX_MASK) {}; + + // Signal we're ready for data + PIN_CTS_PORT &= (~PIN_CTS_MASK); + + // Fill our buffer to give us a head start + for (unsigned char a=0; a0) { + if (!serialBytesInUse) break; + + // Read a byte from the buffer + register unsigned char currentByte = SERIAL_BUFFER[serialReadPos++]; + serialBytesInUse--; + register unsigned char counter = PULSE_WIDTH_VALUE - (PULSE_BREAK + ( (currentByte&0x03) *32)); + register unsigned char pulseStart = PULSE_WIDTH_VALUE; + if (currentByte & 0x04) pulseStart=PULSE_WIDTH_VALUE-2; // Pulse should be early, so just move the pulse start back + if (currentByte & 0x08) pulseStart=PULSE_WIDTH_VALUE+2; // Pulse should be late, so move the pulse start forward + + // Hardware error checks (frame error and overrun) + if (UCSR0A & (bit(FE0)|bit(DOR0))) break; + + // Run until the pulse starts. The pulse start is also timed so that its width is enough to cover the time to execute CHECKSERIAL_ONLY() + while (!(TIFR2 & bit(OCF2B))) { + CHECKSERIAL_ONLY(); + }; + + // Wait for overflow (ie: pulse finishes) + while (!(TIFR2 & bit(TOV2))); + // Set the new counter and clear all the overflows + TCNT2 = counter; + OCR2B = pulseStart; + + // Clear overflow flags + TIFR2 |= bit(TOV2); + TIFR2 |= bit(OCF2B); + + // Control I/O with the serial port + if (serialBytesInUse=240) {} + + // Now we write the data. Hopefully by the time we get back to the top everything is ready again. + WRITE_BIT(0x10,B10000000); + CHECK_SERIAL(); + WRITE_BIT(0x30,B01000000); + CHECK_SERIAL(); + WRITE_BIT(0x50,B00100000); + CHECK_SERIAL(); + WRITE_BIT(0x70,B00010000); + // Extra check for some of the other errors that can occur + if (UCSR0A & (bit(FE0)|bit(DOR0))) { + // This can't happen and causes a write failure + digitalWrite(PIN_ACTIVITY_LED,LOW); + writeByteToUART((UCSR0A & bit(FE0)) ? 'Y' : 'Z'); // Thus means buffer underflow. PC wasn't sending us data fast enough + PIN_WRITE_GATE_PORT|=PIN_WRITE_GATE_MASK; + // Need to allow data to come in again + PIN_CTS_PORT &= (~PIN_CTS_MASK); + TCCR2B = 0; // No Clock (turn off) + return; + } + WRITE_BIT(0x90,B00001000); + CHECK_SERIAL(); + WRITE_BIT(0xB0,B00000100); + CHECK_SERIAL(); + WRITE_BIT(0xD0,B00000010); + CHECK_SERIAL(); + WRITE_BIT(0xF0,B00000001); + PIN_CTS_PORT|=PIN_CTS_MASK; // Stop data coming in while we're not monitoring it + } + + // Turn off the write head + PIN_WRITE_GATE_PORT|=PIN_WRITE_GATE_MASK; + + // Done! + writeByteToUART('1'); + digitalWrite(PIN_ACTIVITY_LED,LOW); + + // Need to allow data to come in again + PIN_CTS_PORT &= (~PIN_CTS_MASK); + + TCCR2B = 0; // No Clock (turn off) +} + +// Write a track to disk from the UART - the data should be pre-MFM encoded raw track data where '1's are the pulses/phase reversals to trigger +// THIS CODE IS UNTESTED +void writeTrackFromUART_HD() { + // Configure timer 2 just as a counter in NORMAL mode + TCCR2A = 0 ; // No physical output port pins and normal operation + TCCR2B = bit(CS20); // Precale = 1 + OCR2A = 0x00; + OCR2B = 0x00; + + // Check if its write protected. You can only do this after the write gate has been pulled low + if (digitalRead(PIN_WRITE_PROTECTED) == LOW) { + writeByteToUART('N'); + return; + } else writeByteToUART('Y'); + + // Find out how many bytes they want to send + unsigned char highByte = readByteFromUART(); + unsigned char lowByte = readByteFromUART(); + unsigned char waitForIndex = readByteFromUART(); + PIN_CTS_PORT|=PIN_CTS_MASK; // stop any more data coming in! + + unsigned short numBytes = (((unsigned short)highByte)<<8) | lowByte; + + writeByteToUART('!'); + + register unsigned char currentByte; + + // Signal we're ready for another byte to come + PIN_CTS_PORT &= (~PIN_CTS_MASK); + + // Fill our buffer to give us a head start + for (int a=0; a=248) {} + + // Now we write the data. Hopefully by the time we get back to the top everything is ready again + WRITE_BIT(0x08,B10000000); + CHECK_SERIAL(); + WRITE_BIT(0x18,B01000000); + CHECK_SERIAL(); + WRITE_BIT(0x28,B00100000); + CHECK_SERIAL(); + WRITE_BIT(0x38,B00010000); + CHECK_SERIAL(); + WRITE_BIT(0x48,B00001000); + CHECK_SERIAL(); + WRITE_BIT(0x58,B00000100); + CHECK_SERIAL(); + WRITE_BIT(0x68,B00000010); + CHECK_SERIAL(); + WRITE_BIT(0x78,B00000001); + TCNT2=248; // a little cheating, but *should* work + PIN_CTS_PORT|=PIN_CTS_MASK; // Stop data coming in while we're not monitoring it + } + + // Turn off the write head + PIN_WRITE_GATE_PORT|=PIN_WRITE_GATE_MASK; + + // Done! + writeByteToUART('1'); + digitalWrite(PIN_ACTIVITY_LED,LOW); + + TCCR2B = 0; // No Clock (turn off) +} + + +// Write blank data to a disk so that no MFM track could be detected - this is no longer used +void eraseTrack() { + // Check if its write protected. You can only do this after the write gate has been pulled low + if (digitalRead(PIN_WRITE_PROTECTED) == LOW) { + writeByteToUART('N'); + return; + } else writeByteToUART('Y'); + + digitalWrite(PIN_ACTIVITY_LED,HIGH); + + // Enable writing + PIN_WRITE_GATE_PORT&=~PIN_WRITE_GATE_MASK; + + // To write the 01010101 sequence we're going to ask the Arduino to generate this from its PWM output. + TCCR2A = bit(COM2B1) | bit(WGM20) | bit(WGM21)| bit(WGM22); // (COM2B0|COM2B1) Clear OC2B. on compare match, set OC2B at BOTTOM. WGM20|WGM21|WGM22 is Fast PWM. + TCCR2B = bit(WGM22)| bit(CS20); // WGM22 enables waveform generation. CS20 starts the counter runing at maximum speed + // This generates a square wave, 3usec high, and 1usec low, 4uSec in total + OCR2A = 63; + OCR2B = 47; + TCNT2=0; + + // Now just count how many times this happens. Approx 200ms is a revolution, so we'll go 200ms + 5% to be on the safe side (210ms) + TIFR2 |= bit(TOV2); + + // 52500 is 210 / 0.004 + for (unsigned int counter=0; counter<52500; counter++) { + // Every time this loop completes, 4us have passed. + while (!(TIFR2 & bit(TOV2))) {}; + TIFR2 |= bit(TOV2); + }; + + // Turn off the write head to stop writing instantly + PIN_WRITE_GATE_PORT|=PIN_WRITE_GATE_MASK; + + TCCR2A = 0; + TCCR2B = 0; // No Clock (turn off) + + // Done! + writeByteToUART('1'); + digitalWrite(PIN_ACTIVITY_LED,LOW); +} + +// Write blank data to a disk so that no MFM track could be detected - this is no longer used +void eraseTrack_HD() { + // Check if its write protected. You can only do this after the write gate has been pulled low + if (digitalRead(PIN_WRITE_PROTECTED) == LOW) { + writeByteToUART('N'); + return; + } else writeByteToUART('Y'); + + digitalWrite(PIN_ACTIVITY_LED,HIGH); + + // Enable writing + PIN_WRITE_GATE_PORT&=~PIN_WRITE_GATE_MASK; + + // To write the 01010101 sequence we're going to ask the Arduino to generate this from its PWM output. + TCCR2A = bit(COM2B1) | bit(WGM20) | bit(WGM21)| bit(WGM22); // (COM2B0|COM2B1) Clear OC2B. on compare match, set OC2B at BOTTOM. WGM20|WGM21|WGM22 is Fast PWM. + TCCR2B = bit(WGM22)| bit(CS20); // WGM22 enables waveform generation. CS20 starts the counter runing at maximum speed + // This generates a square wave, 1.5usec high, and 0.1usec low, 4uSec in total + OCR2A = 31; + OCR2B = 15; + TCNT2=0; + + // Now just count how many times this happens. Approx 200ms is a revolution, so we'll go 200ms + 5% to be on the safe side (210ms) + TIFR2 |= bit(TOV2); + + // 52500 is 210 / 0.004, but we're tqice as quick, so do the loop twice + for (unsigned char loops=0; loops<2; loops++) + for (unsigned int counter=0; counter<52500; counter++) { + // Every time this loop completes, 4us have passed. + while (!(TIFR2 & bit(TOV2))) {}; + TIFR2 |= bit(TOV2); + }; + + // Turn off the write head to stop writing instantly + PIN_WRITE_GATE_PORT|=PIN_WRITE_GATE_MASK; + + TCCR2A = 0; + TCCR2B = 0; // No Clock (turn off) + + // Done! + writeByteToUART('1'); + digitalWrite(PIN_ACTIVITY_LED,LOW); +} + +// Read the track using a timings to calculate which MFM sequence has been triggered +void readTrackDataFast() { + // Configure timer 2 just as a counter in NORMAL mode + TCCR2A = 0 ; // No physical output port pins and normal operation + TCCR2B = bit(CS20); // Precale = 1 + OCR2A = 0x00; + OCR2B = 0x00; + // First wait for the serial port to be available + while(!(UCSR0A & (1<=TIMING_DD_UPPER_4us/2) && (lastWindow==0)) { + lastWindow = 1; + sendString("\n"); + } + if ((a>=TIMING_DD_UPPER_4us) && (lastWindow==1)) { + lastWindow = 2; + sendString("\n"); + } + if ((a>=TIMING_DD_UPPER_6us) && (lastWindow==2)) { + lastWindow = 3; + sendString("\n"); + } + if ((a>=TIMING_DD_UPPER_8us) && (lastWindow==3)) { + lastWindow = 4; + sendString("\n"); + } + if (cc[a]>1) { + sendInt(a); + sendString(", "); + sendTickAsuSec(a); + sendString(", "); + sendInt(cc[a]); + sendString(", "); + + if (a <= TIMING_DD_UPPER_2us) { + sendString("4us, (assumed) but bad"); + } else + if (a= TIMING_DD_UPPER_2us) counter -= TIMING_DD_UPPER_2us; else counter=0; \ + } else \ + if (counter=TIMING_DD_UPPER_8us is an error but some disks do this */ \ + counter=16; \ + } \ + + +// Read the track using a timings to calculate which MFM sequence has been triggered, hwoever, this keeps running until a byte is received from the serial port telling it to stop +void readContinuousStream() { + // Configure timer 2 just as a counter in NORMAL mode + TCCR2A = 0 ; // No physical output port pins and normal operation + TCCR2B = bit(CS20); // Precale = 1 (ie: no prescale) + EICRA = bit(ISC01); // falling edge of INT0 generates an interrupt, they are turned off, but its an easy way for us to detect a falling edge rather than monitoring a pin + OCR2A = 0x00; + OCR2B = 0x00; + // First wait for the serial port to be available to receive + while(!(UCSR0A & (1<250) break; // this is to stop the inteface freezing if theres no disk in the drive + }; + TCNT2 = 0; // reset + while (!(PIN_READ_DATA_PORT & PIN_READ_DATA_MASK)) {}; + + EIFR |=bit(INTF0); // clear the register saying it detected an index pulse + TIFR2 |= bit(OCF2B); // clear the overflow register + OCR2B = TIMING_DD_UPPER_8us; // This is set to the upper bound. If we exceed this we must have received a load of non-flux data, this allows us to write '0000' on the PC and loop back round + + // This sets up what would be an interrupt for when the READ PIN is signalled (unfortunatly we can't choose the direction. Its just set when it changes) + // But this allows us to make sure we dont miss a bit, although the timing might be off slightly. This is mainly used when disks have very long areas of + // no flux transitions, typilcally used for copy protection + PCMSK0 = 0; + PCMSK1 = 0; + PCMSK2 = bit(PCINT20); + PCICR = bit(PCIE2); // Enable the interrupt for this pin + + // First one will just be 01010101 and is ignored by the reader anyway + register unsigned char lastDataOutput = B01010101; + do { + + // A variable to store the data we collect + register unsigned char DataOutputByte = 0; + register unsigned char counter, average; + + // format is INDEX B1 B2 Spd + + READ_UNROLLED_LOOP(B00100000, B01000000, B01100000); + average = counter; + if ((EIFR&bit(INTF0))) { + EIFR|=bit(INTF0); + DataOutputByte|= 0x80; + }; + + READ_UNROLLED_LOOP(B00001000, B00010000, B00011000); + average += counter; + average >>= 3; + UDR0 = average | DataOutputByte; + + } while (!(UCSR0A & ( 1 << RXC0 ))); + + // Read the byte that was sent to stop us, should be a 0, although we don't care + unsigned char response = UDR0; + + // We want to make sure the PC knows we've quit, and whilst this isnt fool proof its a start. + // The chance of this exact sequence coming from MFM data from the drive is slim I guess + // A little hacky, bit without woriding another pin to something we dont have any other options + writeByteToUART('X'); + writeByteToUART('Y'); + writeByteToUART('Z'); + writeByteToUART(response); + writeByteToUART('1'); + + // turn off the status LED + digitalWrite(PIN_ACTIVITY_LED,LOW); + + // Disable the counter + TCCR2B = 0; // No Clock (turn off) + EICRA = 0; // disable monitoring + PCMSK2 = 0; + PCICR = 0; + OCR2A = 0; + OCR2B = 0; +} + +// The main command loop +void loop() { + PIN_CTS_PORT &= (~PIN_CTS_MASK); // Allow data incoming + PIN_WRITE_GATE_PORT|=PIN_WRITE_GATE_MASK; // always turn writing off + + // Read the command from the PC + byte command = readByteFromUART(); + + digitalWrite(PIN_SELECT_DRIVE, LOW); + smalldelay(1); + + switch (command) { + case 'x': break; // this is ignored. It's to help 'stop streaming' mode if it gets stuck on startup + case 'M': if (!driveEnabled) sendString("Drive motor not switched on.\n"); else measureCurrentDisk(); break; + + // Command: "?" Means information about the firmware + case '?':writeByteToUART('1'); // Success + writeByteToUART('V'); // Followed + writeByteToUART('1'); // By + writeByteToUART(advancedControllerMode ? ',' : '.'); // Advanced controller version + writeByteToUART('8'); // Number + break; + + // Command "." means go back to track 0 + case '.':if (goToTrack0()) // reset + writeByteToUART('1'); + else writeByteToUART('0'); + break; + + // Command "#" means goto track. Should be formatted as #00 or #32 etc + case '#': if (gotoTrackX(false)) { + smalldelay(1); // wait for drive + writeByteToUART('1'); + } else writeByteToUART('0'); + break; + + // Command "=" means goto track. Should be formatted as =00 or =32 etc. This also reports disk change and write protect status + case '=': if (gotoTrackX(true)) { + } else writeByteToUART('0'); + break; + + // Command "[" select LOWER disk side + case '[': digitalWrite(PIN_HEAD_SELECT,LOW); + writeByteToUART('1'); + break; + + // Command "]" select UPPER disk side + case ']': digitalWrite(PIN_HEAD_SELECT,HIGH); + writeByteToUART('1'); + break; + + // Command "{" Read data continuously from the drive until a byte is sent from the PC + case '{': if (driveEnabled) { + if(disktypeHD) + writeByteToUART('0'); // not supported + else { + writeByteToUART('1'); + readContinuousStream(); + } + } else writeByteToUART('0'); + break; + + // Command "}" Write track to the drive with precomp + case '}': if (!driveEnabled) writeByteToUART('0'); else { + if(disktypeHD) + writeByteToUART('0'); + else { + writeByteToUART('1'); + writePrecompTrack(); + } + } + break; + + // Command "<" Read track from the drive + case '<': if(!driveEnabled) writeByteToUART('0'); + else { + writeByteToUART('1'); + if(disktypeHD) + readTrackDataFast_HD(); + else + readTrackDataFast(); + } + break; + + // Command ">" Write track to the drive + case '>': if (!driveEnabled) writeByteToUART('0'); else { + if(disktypeHD) { + writeByteToUART('0'); + } else { + writeByteToUART('1'); + writeTrackFromUART(); + } + } + break; + + // Command "X" Erase current track (writes 0xAA to it) + case 'X': if (!driveEnabled) writeByteToUART('0'); else + { + writeByteToUART('1'); + if (disktypeHD) + eraseTrack_HD(); + else + eraseTrack(); + } + break; + + // Command "H" Set HD disk type + case 'H': disktypeHD = 1; + writeByteToUART('1'); + break; + + // Command "D" Set DD or SD disk type + case 'D': disktypeHD = 0; + writeByteToUART('1'); + break; + + // Turn off the drive motor + case '-': digitalWrite(PIN_WRITE_GATE,HIGH); + digitalWrite(PIN_DRIVE_ENABLE_MOTOR,HIGH); + writeByteToUART('1'); + driveEnabled = 0; + break; + + // Turn on the drive motor and setup in READ MODE, this has no delay, the computer must handle this + case '*': if (!driveEnabled) { + digitalWrite(PIN_DRIVE_ENABLE_MOTOR,LOW); + driveEnabled = 1; + } + writeByteToUART('1'); + break; + + // Turn on the drive motor and setup in READ and WRITE MODE. They both work the same now + case '+': + case '~': if (!driveEnabled) { + digitalWrite(PIN_DRIVE_ENABLE_MOTOR,LOW); + driveEnabled = 1; + smalldelay(750); // wait for drive + } + writeByteToUART('1'); + break; + + // Check write protect flag + case '$': checkWriteProtectStatus(); + break; + + // Ask if the drive is ready (has a disk in it) and if its write protected or not + case '^': testForDisk(true); + break; + + case '&': runDiagnostic(); + break; + + // We don't recognise the command! + default: + writeByteToUART('!'); // error + break; + } + + if (!driveEnabled) { + digitalWrite(PIN_SELECT_DRIVE, HIGH); + smalldelay(1); + } +} diff --git a/trunk/Arduino/FloppyDriveController.sketch/LICENSE.txt b/trunk/Arduino/FloppyDriveController.sketch/LICENSE.txt new file mode 100644 index 00000000..3d90694a --- /dev/null +++ b/trunk/Arduino/FloppyDriveController.sketch/LICENSE.txt @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + 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. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + 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 +. \ No newline at end of file diff --git a/trunk/Arduino/FloppyDriveController.sketch/V2.4/AmigaFloppyDiskReader-10.jpg b/trunk/Arduino/FloppyDriveController.sketch/V2.4/AmigaFloppyDiskReader-10.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d35866cc7756c392185e9c609952b18dcffde5fa GIT binary patch literal 98621 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 literal 0 HcmV?d00001 diff --git a/trunk/Arduino/FloppyDriveController.sketch/V2.4/ArduinoFloppyReader.exe b/trunk/Arduino/FloppyDriveController.sketch/V2.4/ArduinoFloppyReader.exe new file mode 100644 index 0000000000000000000000000000000000000000..8d5b28be4955f320638c70e4f8ae31b45a12a31d GIT binary patch literal 252416 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

    uy?6 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 literal 0 HcmV?d00001 diff --git a/trunk/Arduino/FloppyDriveController.sketch/V2.4/ArduinoFloppyReaderWin.exe b/trunk/Arduino/FloppyDriveController.sketch/V2.4/ArduinoFloppyReaderWin.exe new file mode 100644 index 0000000000000000000000000000000000000000..a292a96e8d8ab7536f7e305c842a5b0f255e3471 GIT binary patch literal 3743744 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

    RLIv~nd`mM6|k;!dq)LQ-*u%f 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%0DRVRJT;eX04)?)nBK5i=b4oHA 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%0A!jWL7d)^9%Y%sG)Fg z>9*kMr8|Qo`9HjLXQ*`ZoxB-8e)DYo$=f_de{wco!k<|#G(ukCv*bd4Au=r{K(Sec zcii~jp$Ei7pfa~goT|HHGasmQ^7j74dL_G+{E3o*TsP_dlm=W7d+K}ay}is6;S0xr z*^NmkPK1is*N1oYNV1d zNn3+C`1D3Iy~m`e^0S4}OoK!_JLGOXi%{=hYZv_GFMNU5!~_7o13m)yvUmkM13hEV zlHuud@5Nd>@)Oaqk$>bOUgWJMM*uzJu2K2gqss#-fBfk3b5*|l=yC=0DbGGBcns8} zmtAC(w2-~gbasmQWBK{JwwJ0!`)>9p<+@Ml+6AH!^FW6EF$QB5K#oiv5E1G7pfV!T z_z_W~*~du!IkBLd34@x&D;|)zDK@1*_6@oHw&rPmZ%&D9lCU=eqYf^-U7Xz{uJV^} z$$P9Ko~OIyb!Oh)o!oF70fL=Bykppo(~ID4+L4ce9y<|Z6GqnVI5FHuEDhLTa9WbD z_95c9)HNt04qZ8#9hX7WwS#`lj;Z$|p_@^A)nh~}-HCNEOM7*)Hv96ih1!?5aFCIH zTxqT?$Qu+K#cyWt1bu7n5#QSFJ+?#@&-Pzhq4df2(g=HrhL)>ru=m(g{5AN)U2eg> z%)5{O{>Rn~w5NBu(gyS0VIY6k&I93=&fk%6Z~E1abARn%t2MigKQ|mcNO#?Aa~rI# z(2xSG`qJn(gQu5YQ4%c1RcpZ(3Dv6-UoCOZASMPfvxtylE?U_cST`*cnt2(+4Q5-W zOWmv#D8y}h`C#HX*^`g~&vaWPiBdxkU9~E&as~g@hadFDm7pc4R^fyvU-WUpIkf9r z#YDQU8bAljcdbMr4+0(TAN&1nI0;Z;DvwD@eE%%Q%$?YkflAV%K>HIqptf{L1&BM~U z9Ot%K54D->mDuNYC2r?#gX4Z5oqhC2k4b)Jfj&AunR(RzCO&VzSWKTBnf&A(`sDb& zFA^fbkGsA^@-Zl>9Y|8WaChlWY}VoV;2ZK^+=)YAX?N)d$+zS#k6bQ)=^i?$FeEKl zgo($P*%o_J1e{lMfNL6U)=IN_;$toKLyzlkcBrMD;`0xM52Tt89H8+-@#nI*n6MlE zBpPnY+G27@I7l%o*{2aRTKr0LS(EpARn;2FwBb;s*g(kFVcg0ocuDI+-tJHq2M#<+ z)|SY9J#e92!7+SR4D8JIPPr9xikRebw{aDz2I@dAef-0B?(n7cbp;JS9SPiTszv7g z7RZapl#+aK+4^0-H{^3V2UZN~In`Jf>VR&sPt*T7IHR+`z^5cLI1Kr~p!`LW2u2#K z_ytg-AQ_R-vurH8~bsLGc*AMKz26bt|jQ2G1>DJS88bdtYSJRs78e-3gNY<5znUv{#W4 zs+O3rU>d@Py#9~}{$z;wTDuE={Sk3E6YJOVF82+F3aYB=rqWaj88Pp`jWy_@{s3 zv(4X!XxNU;5^QVRp|w(A@XFmj8066p-6BAksoUDD>!awex^60=J{Y)2ot}lmc!wLj zU4HOPP^RwFV*~ZNYu-gNNmsc9YVM4~bM@q3n4?mjCFag?XYvaToJgBsL~Bk8k|WI&+RO-PnHi5lYF~)J(2%-}}O$M5p)z=4MO#Ac>*q4nDa} zS@GjcAC<2O#b~u@P&~6jU0wB#2;3Ed+u(`ZCX=)q7+@cnG_;fmK{tPELLyeNNP8EO zA=jH)qz)v{;c$;^E{j}6zqXIIy0mo|odKOooW=}yA!BAELW70IaM-wae`_N?gFOxC z*pN%u-pTQ5Bd&3K+1c^1?rb=W>kL(_-_B{uF}}W;zwy%yiURPa9QfQrqX#W|FxXq) z%HNc9>TGCW=RUVJC7sHvuJfY_jNET}88@Cs@nfoWZ;7z{9VdU7a97{SS}}~#4KL~( z{R-J6J{cn@D)NVMR{CLd*)X1C7@a!MIPm?`Pb_5y>|ir=-Y$jgobj|<(xj# z#gW81Z;NkIX&T$6dx&4h%?%xq&5{#ja6}}W1GFRU%xBc`R)8Zje3pk_F9L2S2}*#!G{z1YQX{5G$#%iij?w+`qneT0s6TipXzw?}m^@EUupZm-qNP}!*-5sA^g{ueMo zJhtK99(p;H%O!$e2hR;n5Sb@XmYDo2l8ZmEKW=l^{hlJT z=52Fxcnl+koGp+y9dYjy3RhlJOyIiH5`lt5WnrQc$9PkecYEFCH7>~4@}P;^`X1Yd zT3seBDWDJ@?6Uw-7z6Dnonu4;X|+{;`h7g>-zEf6s>|`AHhWo#N;3|pp4+<_En%Q2 zK8s3aP5#Kr1I5AYx~%wMW;q9zGd=_u$pTco(`eoHrm2Eu`Al#0t(2ar13fT3rA5Xv zg^@)Z@DvRcNjM9gSlPbl?Pz6(G}78Ygq-Vg`(}fH9{7R*H3*2o_}s6!j5=@L=YSAs54j=2UaaT|IFcCj3?dJB8 z+1Gs;$gZs=eK_J+x|PHcqlF_H-!vR?8k>uw+Hk}`1o2nchIm~%1hD}S6CP*~Kq5gZ z;o>Q8{YG*FvB8*4eGrtw2DxoMHaLSv{jkA|kzj*~bC|diA9KTr8=E3oZ|^K_rE$ak z{*Glj5WZ?UbQ)^Klt$3i>sxay6t`oRLW@nxhje;lHzyuKw)}+`16gd=&8KH{XOspC zXK@087>%WV5Hb1^sjVP;0|jW#M)UB9C&kHk#t14x=-0;(f%(Yy##Ql!(!e;Ku6ExIswEyPclgIv;40mOlj{TyB z-wRte-3CB?;2vx>I2wg;LIR+E;)&;LI8i4u;C9)L88n(oqRKUN)>k+xW!~eUY$r6 zAYyg~I^^EyHa`y|dv*;w!gMA5Lfj47YZHDdLk8}B+NzHrTo>m!{G&lR{HUZew^_O85GiN-zPA}=xe-RYpQ1aLb=^z z9=tr#C`stB{6(_g^H$1+`G3)js&($-jdHt}JV-}OAWKJN!uY>vLDf1XEH2+9(QW>s z2O(HZUf2U_X$oH9EuPJwNu8FMdvERbSw!U<{7Z?niJTqiaXmb>5NE#wdvS&*S&}eS zv`Xip^Xi)my3;oo-byq1A27u#!Aix5K%;ac1MkzU87=*DuGvE6$*!V^o}rCiuuT^H zSh3B*^e)tq)#hGq5iD`(4+G<#t#4!pzj^5D(GvW4SI+RJ&PGDYS>YRf1@oqXwNeIO z?%Dr3$X#43XgR3sYVX8DB6X-Gt-$Q~s+0QmFp_q*Jr_>~-QPw7De8GFEu29Maj@}d zf_5e~DL;Nl-+?J6=8^NnxFPO9L-zkeZwTrqoQEA_yNmJr3q?GDA18s7McE4IJosH&$ z+eB?X`q=6AHTtM4=szDH-q>$G3h^G2B&xDE7Ma4i3|J0UaNy9eSfrQ1lg}bdX7wzi zUGS(+oS?6BMu_O*x|ya=*5Lh?$ydO-HW`F&n}U$ui^#L(_S<~%dt?=jbAOQGD54Nc zE>)~3WIeMYpJaxHG*sn-(T~TN?vpI+r>2}GNX)4%U@9*ulGN+M*ZqarC;;45?#(zy zE2Cv9Uxr;R=^ye7x;R_2?^A5D{bKU_wn%F3dty;lll>m-ZBJ$p9YI#`w6dlYTnZ*Q zBv@a8wAit#_}OKpKw9jz%K+OG zedEVG9~=8LSoMNWe118(MTx(tJAeh6z3$RohQ!ZG&yzCkSjhDf(1~dK@p)p)ViEbm zfJuVKMH&msm=r=uMdS!WnWtqlvbQ`?Vq;-`M44))dQ+|S%@Z?3d~zZHPJ?n~j5_-@ z>>lZsK8!RC!GCY)4au7?Oyr+thXI!gxw>B>$ordZG~zc)j-VxdIn)mqLX|t3BgT zpu{j#)eJ3Y#cV=OYhG^RUV9`m2-;l!i@KhrpLuF(eLoE|p?>x|+I0zBObW&P`1Agj zf_EAW-|*x3aYUj$Xv$q(`ld^E{=-`-!_zdNY3-$^JZYaQ(5!LZm9sl<=5=30f#wFF zz$cXmS8$=d?u?!OmXHm6ZPT}FbmLt0i~ccDNm;CquI=~}goe?zb0}wO|NlkThJVwK zuAQj9{{M-t{Yl56M0~V1$p49(*u@64a~A41@EcLTB@O=;^}BVtu~R1Ta`*q*;NKT_ zC6Pe4ww-(U571+O1u9M4b)toR1Xx73Cf2XhYMM+ivA&*k-)?nlekU2CAXtKL8CV~N z;C=8r=5{G%1vV^g*syS>!zzN$`dO^lwhwo6jljhp`ZoD}jm5A*24E1wJoiVUut08f zOH~9>+*Rd1gKSSl6cjr5u9mIH+bb@F=a9F)qz>l006P9$)b)byKJv8jB7xTPk!b zJi7QPNROlt1VzJPaHIQARtOA;8rHOzg7#;S+UCZ9bKMX_I5mrn4x;ycEn>ZU#Hbe9Y+*1vBS#V-Wf1I zjw`uHGIhBV`(H#}(gskX!kk#)sQ8ewHxYzoUg6br#KNsaf+!`hYF2E0_r1O$y%%UJ z4Yb}isrixP31N!XyR>p&DVDNZ9?3$J>#dY)oy{`$xK1tV^VvvxXQa+6$XHcG5Z!ke zes_uvL!v5-ZWw<8;P|f_#QsOIoJ8!*o(#9S+9sRBq0`0B)`2-|m%on5(r)+6TL1X^ zy9OWFAA68dnm35o&;UruJmF~5q97)?`@M#ZRER&IDgze6^wk)NQa)fx{qiD}4_F{y zzdbg6eLjRdt6{r7HP~xt;%`!ti$SV#m7!S!aC{*sAJm(WCF(E7EDht10i);j78d4cPUDen} zzG=cP_H(ToZHNflo=(r_>#<+S%fg;pYSORf zk$-eBw@2cEBm3RT`K4RDUuZ5fE1$V7EL?TdEhFEWLvJul3UH8aiSmE5f1 zEs?j3w_=76S)R9Kw&iZsZ(s?I16hHVSh!wuim;hj*9-vjVlVJ`W&kgv&<90J&mkSLRs;h){eU4~=M~u0{*c65L5s%s8 ze^5W=5#vk!n_Zng6>2Sen~_}^zsy@9H<^L0!g=^kHc8GSU3&%b*Szq)NO(UCp8Pj) zj%lKMXU!v>BQN$WED!ca8hnM!!ncHq=TGD}W{w`-(^^m_XAP3eQq=6N^c=r0)*cUx zDbbnriNMC#%M(r7(ZZ~4@Wje`^|J@jP|8A~vP-TX%f0aa$==M3cno6L{5mc-rF*=` zwChVBlROL`gJZpal)j>ptXEV*?3hS+dq!|-UDA8Y3<`i6=iycHsZM!#*L@?a?vq<& z?*GpU1)$MlHk1n58l;b?@3%Dnhe_PeuI=0@1b{$WW<7ZH*nV)2Kcrie_e-Gj6UzJh z5w#@!h(g7sp+Y&HwfhB=c7zM+;Qn>-o|!cl#)s+eR+AoQ1qw>v!0ji{QOYjE3Zgw$ zJnXRf#IVv(d(!-YnoM6Q&K|9$Z+YANI@noB-kHy{zl!Q^n zmAIul%mmN5sh()Sb2iY>jrKGxD_8t9 zbyvAtzlT_$hn=&{lSk;;jG7m@nbNbu1^-=XG!S+lVv&X;*cK z7^r;Cw?*|YQbH!9i0P9tZ9ogAR*5wIjJn#UrWDfqJ@p)?mPc`FF{1?ql|~=>-zzC^ zMdOyg&<;56fVuiW`Q!unOMk-xp<1Sr(Tiv&Z!SCNDm_1>I_>7T^9Oz-tZzU7osBIekaW3&g!m~qq^U`3~`<($Do5D-+FS-4G74?0Hduw2ovyN(azu#^XSAizm z&2`V)OZ!s;?q)LM@B{Q7n*T99WZpdN*&+>(FsWQm=mpjx`GS7o<_1otLEwyS-dy^Rlcy&+iqn%8*lrWMyDV`Hw+0dW`Uv{Zr#^CEJL1DJ&A?U80;7B0cIFE4 z!uejrj`XJBIptGIxU^am=bxLyaGrogt#UVE4&uMy;X6avDKsDt1{dv$g%M5lAnjRG zb)z<0FYY6b+kF`a+YMQi8xOB!gfP@wQNwzj@L9}?soLSCB*hLm_tTecItJ(!9JI8U z1~*Gnvy9FvhW&bzx;M&GADf?OxZPbgg#cXu_YfbD6v?gMB|N8 zsHH10y|{BV@3L4SZ}E5yd~fOEG5T9mTv}6T?pz(*4dC1hdsvs|$cM04)v`ao=$FZS zaFYLK>0))(=rK;`#LKhE(Sanh)xBmK0&mUne_BH>=Qmsmbw@T1upAK zz&pu|jp-vW-{GD&;%I4FwFcg|49>{COfL4-;5|*YB4I8QM>o{hIl7e947JhYowSB8 zimLl+Fv$<5riKV)Y;DMu7KX8C*Q2+3^98!Ga9eVOG=lIH>)jzZbM6pd&fwOF><{4& z2WtxMr%fcVm{G3rRwyI_Un}h6@(@}_Rfvj1R=e}t0g(7`1ZyU5Y~ zm^y7+`Br!z!j?qC4%W`?TW?T3f~nc-el`y=-7{OhQGbW14OGYwq7yAsG;k-+dpwZ*D{lX>$VT^Ija=dZx>_bX5QHN*^TElB( z#Oy_uFi>HK`Ij*N?6ct62j?4wjBg^SQGM(`H_Qq6?La(RH!rKg00vl-H=Ir5y_AM4 zLo(i*Y@1^OJfD`=%VsZ*(z6aNV82!2aKR`SVnd>0TT|mgyl_u~i#U=Y1&Sk^$6d{f z+!@SW4o}FXF*>sgSFx-_U>|I>_raleMjd1-BjFCFo6!u5J&+lf)l=rxm^Xv8V#`Xd z(oA$(PfF-%s`jhM+Oh)%T^Ht6E-I8v=JGNW~ zKRL4Zi68S?5G$cq=YNmlE3&=piC*Ewv>(eZ=cYL3J}#4EugCz%=h^oqF@otDQhT#k z094tF`jPS6!J8#1E2|KBrS5?Yhi-opN z^U=);3-=^#ZxT*ZpFqi?M|?>4LP3vUSQ_ZC)5WaYBVF)C_~A&)0h*|u6RtB%tCbYb#))teSBDcWb+_A!yflFlo-zT z)@30Gk)Eap?>(L}aAQk#B=XM{oQ0-l(x<$O@HD;^Wt-T^e!?W_9`&|c_DAz7N~dwe z{@^g)=`g(0?rwcCk(gc$XkzW=zWgUn&tckM2!?E*rN9?cRUZqfhhEr8VkV58zvw&s zmcMfS{UTFe)?R~FY^%$h<_)|e+-M+<@cmw>Ez)!ng!Z$FhlD&XHW})gCkL_uUC`rR zGo*TC$4DGeKYXL7wAtn%Hu+y=yQZ)IkJCKN6&iEmO0dauF$i z<&v*juSkE&e!M{CM?CKJTaKct$IS3@ zO7pI=)vTloi>Hh-Q zBaejOV3~L5{|T;>?l!yK;=gB$Z#s^nWHL#w=g_;O5{G^l`7=)Ay*@A^Bm@ZW*(tF} zWJl1$T}4sKz}jmhK;gtNGOlm2bv~pRfxL#_iV^r|Vn0zI(r`|+uoDO4zV}lf)?PJO zyGrCh{=#*FHIUeVDUz$lO2zzQjrs$eO9EVfsucm21b}|Q9l(t7@r2x&hFHK; zbb~He0Yk{Ocz$#PSq%!+_whK1_XL_HVj_=y1kQ2oMUd9XNKoUG^wR+s`A>tM0rb;J z0-zg(q!st29gMCm=7kTWsE@&kN{3;IfTvY6m_h{fktIGQJ(9y-InWb_SL~r>Fm2hv z98EhHAw@QK5G>Eod+wvBC#L{Jv^!A%pq?&3y;u$@!E$+Top(fqka^V}iJf_|MI^uk zeITBN`2pgn$2#i3lNWf;qD}X4iBEmBCs(#V^$|W0Tc&EPtlqqLByUbOaInLrRk%{> z%2)_WWIrU=ngv@F^G|w99kSH&5A1fquXgzDr}V!=OPa*NYi;rmdz-HO!$BzukC3mw z`xC2{UcSDJSK^l?nZZXcj0B1X2@+N+Xyjq&{S=skm zC)7`T1w)R{vP;Ge{K(N(EHFQ+l-j9D)~>=o4xlEaK|mrW_Sqf!v5iv_dCXzqDdcZs zpeNwAM7RqB&mQ+#2Hp9#D3Hi*sc9Fc3kC;x9|N0JNMBNBs=los z&Gw%o>wbR?U1fLD0`MMv>*`vN5P&t*i#)|wMKQme3oyfUUPl%_rct3k{YZZ>4+#2V z5rz7LxsiUL+x_N^j}wtiMqdY~s-=`r;WFJ-8H*_RUd&TuK8O}I7*Vjjm_^?cF01T7 zjkGf337*%uIQ{5N_G7QR<1LZu`HQw{-v-7pveLllSh!i!M)}g8syx&l*_0GQe@}TB zg{bn;$|m$L!z2tKhW9@9OU*tn+=0qO_qs;3Uk6AHfO~J7iF&sK{H7s(2z81tH#iQ_ z=yu4&e?Om+90dHg%ii>52jw$;gwMtEH}(k-nz^e?fCiZLNQNMT6L*(2>b7vRX?%ir zswB#Qf=}!rB4XQ0DWIdlUgMP{azIZm;)okQn?Um~FaW#I9W6)bfMQmJ_XUGVamL3f zK?n#(`x$jNk?`D)f0Y_f0m8H0?!3Oy94!Z7zaJh)zd=ZscY^?MTnIYz#w<@9Z8OD zXNSDcxNT?9|34s$6@0u&Sz>)Jzw+|_3nv529G(C;7Ed{lzwl?8sy&J7>T<6E2zls4 zIA{Kvqd;o!R9DAO>9><`jM##W`P$4-_O;QM&fk3OMC3T(&~H zwFc)@JZO(N47-zuVeMI*&Htk5={Lm&0myq#7FqLgK{roWdK6AzV?N`Qq(u@p2CzbaD1tLv{D6C=%-r8bO)ibE$ zOn~-mM-!)}V(W|M(}2&qW+`3{Pnt8~y8|s_#dNohMY|RrpOL?)l<$c)m5`VT+{d-y zN)mvIsRUi%{=LszP)Myw3uGyhzfj>s%MR`gw9LWA63w2GumIx;tFiq@nBC&O@v7`X z*rP2~?i&b=`!^U0pl2%$AU+-At(;9S4H@c8lp=AekA*b`FSI|!JE0Das;Wj>ImWAL ziz9+)kA>P};gV$4Xyuqml`eR-7s&v1Fw>=xo^LUeD_a-z9T(W9*yLvsHFFG~O7j)f z<|}oeceiDe%yC+h19fvB;?S${Li@bMHXDmI8^P-_B;tc^+iTjom>QGuE0kIVIw=Xk zR3GQxXx~q+cfV!STYT2VJ_|&dNePyq@cxiYW@G_9AzJ>r)kh!7Jt_9Ot(Nog3OkGY z8>sr{&qICYsXmi}qGyoIQzcjg$x90Xa&Z5NJl}A@VcV3$eW>BUq#Fm^wr7v-#(`8f z8h4_5pDu2ram+H2CbI}fM}qx19izw(CEA5nz-8*b!a=1wB7x#T-;Ldnu;5P36?GX| zJEBBhtn7h#!B2>H)UR#4b+})L35IgNCm1}90scjbD$YZ4lKUu!pQ}q#6jo-mT$pZ( z=ayHN;KQ_QvbR!UgHs!A8nIcY7MX{kaC?8sOafI^#hkLqkQmKj@FpH8#;%NzHdE0b{41Se(<#u0y>i(nGsEs?GJDY%t|XL zx{u@*v*MfLv>#C{KEzwrOba4ZD_e1mZ^~C(1Ll}`UR~%_xWgEm51RJ9(YMc(MOeh zGaUm4vLpCJtIm!{J$;TBdy#eeOUxo;uOenIHQ0-+rL>O&-!@ttxJmAOczAx*(c7aB z7U$!4%b^sJG!#hcvjUUdw{O{Um;XB6QNH;cQf8=Nz|q~z^2F!J^M(_7<=hKF!%c=g zeHK-A_XzLG14Vsy%SQvT-eMMHyxb#?JB*j{pv7!Y0Pm_#Pns+zt`DpPo63a4=u)Mry@D{DsG)h=9HgcVLB}I5;KJ=tpL{+*_#&Ij}KS1mogCw#B44npy<@{nX<@?|_0a z#~m02!e_)k$KE}Bg4yXVCmWv|4fIN~f3Ni;MBs-bMd*EJ{8nLr8pQsa_OVLAp@#ya zne*Jxb+hU+4->!;>{1j0HFg(_+>gQsY!u9xg#5(HODo<#|Cpq-An6m7^u7JBXZ#5Q z??xU$la+L9qcQfLWD?qaIN-t)`B%==4dM&hp`iKXj`U}tH4pv4Njwl@fYTZj)kb7L|TaQV#QP*#)+qwZQqgr~J4vL#HEy_A&3Ga-)9 zowvd^MrZCvw?*iwa1rjQ*FfZ#VjEb5|7q5iD`F34vS*?pwq95KBn3&?Qo5reYisOL zEcV)AMtKDgAtF25xV26pvFH2r`&!pXd>^l-NeokQ|G{v8SHqjs^n3*M71Sh7@I?jkwr#x*HHsuynR)7EaZ^BC%4)*Be8z65SqK|c@*f9J-y@V_&~c1#tE&tK2;7Ui<9YIcOL~{ zi@h}OH=dhp{IBXf)WhD2Dqg4UlN71L8u^Ofh#%X-#ZOe*tE$|rer;P+kG(FRBBDX_ zogdH~EW=*6^cTbeZpLCML4@N9L^ll(8gonf<`AmJHv?RoTv>N=9n5g3zVjKtDH3j= zS1q9;u+ebunI&{KI#*CsIw+-Ptf*2xTGP#$*SU z3Nd|XdoRz*H641cCPTmW(K`aRLbv%u6hPK(W*5Wm5%x!!6% zX*KWj)?3XdRWp9O+MDFp@~%>Qktu$A-bP`WNRxg;EoyR_ur1y54MyGC=g}cumi&Od z`egFe_4ewMdbREXEcJJIuhYbhN4$T}v$BF{j(qJ_kiA)0ZYT{jWd$~tPo5DzS94Vc z(ddP@%LL-(d(~JD@qBOwmq|-T61oHqLn3#zKx=LHE^_tquef1M&N!+F+k6NCvo}#a z#v)#?_9I@)a~z}2;5ilr?sO*En{uZNgD#BB8z;)#o2@B0$Mfds?`c+Hjw%$UD$LM> z!Jc<3f4w0DBR?$jVf(>A?R9_AW}ev`4J`Mr%l59#^-%7pIHK~Va+6oB+ zLdzniabG>+Ba#o-vQ(%df8memvizj32U_wMt{|84 z2o7a?JLB>S=FGtBEG2X)4;Ke7^j7LRH&CLTlxD)@dlkqwB888UnnYF2&cz-@!|S8u zrU*8Vq~sLcq(3DGezxY^m$F1?9YKlukB$Ym9i~JjOG$~C++Siw=$#ddRB+&M3XPJ- zbMORws|O57!4pRc;c)mH73a4+_)yZoqc9^C*y^28!nnxv-BQ~2!UXxrUnr4dGDKwl zqEiK+NEilCZ^r%SFG~3j4WQnV&m?EodjqJq#movO8fvWwmA|-%Gbz<$6YF1T50a4x)F+D__5XrORJf!UK-* zoq;A1$a2D#J|rcAZgM?81XEVF!~#uKu4gUjFt>2Dqrz^-%!1p0po$X@V<9XyS~6^G zyF@C(TmtTrIMg+MzzakSu~!EFNNCUM$h$ia>XiBC|c;Di>)j; zPrF`}Vc+-x{IfDv3*R+E)HcrJRPfdZ`Gu%$e8h6|^$T@eiO25OA51#-Rkn$zYp%OM z(w7L?3bejDNNr-j~#e@6ArUvaK&Qfx`wTii?c`{FZM?!_Wfuy6<^57ZLQ@0PwO z9}ww(`HFB_q(L$-1{tIweWN+)80jAQus6Y_NL)ZI7Pno7<7SAKI<2i?h+n{_{qSK8 z?yyh*~Hb?_MbED)0L7T zqZY(fjoZO(@+#Ld!JLWxrtp(iwk2YPJymWh)+R`K$3ha$Y|eV)(A&|OYe(%Wd(-=Y zrUj`k8qCn@%*u6(d?`DlW@e?ri_UC55)TiU%?-@vp8!gHrDO|_WXL8l$(?iYhe>Ax z`!gAiO){%9HqhSrJW`X|+!JpWfc^MhO)jvk{|M!}1yZdbUzJ#2%Ss@vORT?>ge|3Q%m==sjalD$N3Y%;FMYKi zewHe#V6r?*NQe_^agXi-SG64rt~#u=>?hX5*71OQIwFkZN8j0D->T~TfX`Of7DkCE zJNnCl2Av>pP*|R$_}al^%X5188yZ@E^(FZW_wm5HdNk}de0VqJxLf{qT;%;s;2JK# zj}!GyT@O7zfE?0~Zo7v(mLb~$deW7&k z*4Hqf%H8$T?gHHk2TTbhs^ySy27iI4h1;je2?DA z3PPusVR~3HDD-G7qVC2YL~&~X?EZX@jr!Y%)v*UK6A^wkXJ_}=-Xs@N?2mu2wUbwu zbvq)1y}H@sJ-Rvwmwj^yv8TiEHWur4X3sUiRIn))5#^(vGzFhg03TmP(2ut=yOb1q zlIdpLLpO?=&Y-)%dkdZIKy|GT-FZ~VbuWDJ6F5y+&o}1_gyDuZZwE&rdy?rykg$!T zGhqDJOFEZ~>A)RF$;i$fBXnfDXYAF`aOMGS%;K0}Ac@O3gWMVDVsRM&p+$q&c$2T6 zW?KRz=SI}}yCQfl>SFwh`Ym;3iHMRC`cvpdOq12Pie_j9G8FU9nLt-D1(RAs9NA9^ zeAX}LH(nNtjP5JfE8cp&9v>BpNF?Lef8NShtDM89Tl0J|K_G$`CfS*1zU;>h?7&z= zy0_ls*$#W6sdJzG51(~eNWFN`G+|399G^?{d6$M(aK^G@i~vnpEf=RWi?UjVgORaA z%{L8i;0qy630k(tCuHpmbIb3<+TnhYVQbanegs=pZS!iBdM$S|gJlQ7EMU%0T-jnM z#U^H(JYwx^1<{3|=BnF*k;on83+|?WCJ69 zWWTA1AMUwF4Pb_Im7y0=$d71dQrSy1mOqH1`*ogA(RI6!)eTwnM-(E8Gm_NzexAlU zM`(Cb`L>nq(hQe-`z`|nZ^N+NH1}jV*%Ra6IIhN1)d@hp+2Pr~3`BH?V0musO{KAJ3pqx26?f zy|CWktx@o10OQ=<_xJ$gEYPGhUUmimIr_Z&WSQW_xfxWm@R3+{MS?bC(!*zwuMPU~5hdyN;|yTklX1{-qf_~ayg63HFhwi(8S*G6la+|M4d9*nTy z9k1Vkquf=)S-jn@Z0yI}4;&;ULM;4v+1qOr^Q)$fuO#We{lH}(2t#wry5jjG{JfII z+mDWaqS{Nmm(rL|U?nojYgPqODQys~*`DTG`@EN0k0|EECJaMMdChjY+P0__ zy?woC#MEY^OYElnoluKBE`N4AzxvKblo3e{bl`cp=<{O7QSAqhr(2;BWe4fl)v}Ka z$p#ejs>dW!^Y&Wg6NqNF>Wg-i-0g=Hh;r{J^2~;{Kt_2@JwVd1PC$~+k&#ng(}G~N zp`L<7Xl<;r!TtH}j}p_TV}+zs0oMhQFpu-VmUux-z}Mh@MaU@ev%CbnG!|q}FDqCYOPoTQ0cw7|f$8bj46Q|=rd>f-JA$k$fiV&%HBds9&j<+__&qJiv_Fr}lLS#QO%&yUuy zR79nSWglw>LhBF?bMVy9=syLOO$rz=Uyl%)4-5stBO0|kdiO(tFXnPyDs;ca7{30)+qM%_~YSL(CVP$E)q!pPcmDDvAFh#Aj zZe(T2RVy*+NOC(~v$Dx)Y_dtq$|f4LFwO8K#WbZd!+aSktL;FAWr9ZC=lfmzoO91b z`_24+|L6J4g!k;d*UMge?X}i^$KpB&%r(apqyNR=6gW^~$5TR|{b1&q&Bo?v47{r} zf?t6EduVeH6n&Do7>}iK`VA9+U>;K8>C0I2U&zHvBnFXtmknP3JkYc~2<)@mN%h6rLabW+?N->V3^v#)90S;F>JdFqe zyYdTG@%jy2l6%RV0pd!n{QA0yRpMS&Leas}B#yMfQgtAG8LwmD0B?CPeVJFiu*hMl z5(&c6FL1W#JP6Km`{bz!B;l{LkFd;TrL>D~==Qt-I z6~}C$6u~E%XUgGOKBn?yXE2N#U%=Qo)-m?AKE$xWCp*FeMmI!PVv!2@FvkT|&@Q># z)|@X#_&-dY-xC~4n`t##Z#SF5`iS0*kKMVIh@jW2d!a~@gpIiZpE{org&xCtL+|9^ z18O6B1%u5!_?1u?^`)RvS8~k&wJ7AqyCd~9oA4%?OV~4e;p+$wQ^TnEA)wX%v)}I+riI`*acW^6CheQRsfJ1}JuU;>5-}jKK3^#&R3lMt(z;aAE|kRpN0!aMUUwFj8yJUI2SC#FuR;UIATqxk`NRO1uerVe zi77Qn<|fP4;1f>l0JfXKG_vkc1`n;r1?XzFMc|4#ZxMjr!7{LI?O0g0rEpgrYJod9 zu@%O#f`1IOoYP+Kuypzo9A|l7H;Hqd;8PZ!!#evEjx%U6@^r>)IturPyksv z{XpxLc{!d#`~FpZd`s*@xVWKW;F1NmBcy5(EN-|BWizWN@s5;Ie|0mKaL^UbHB)7&NKP}~)Q{*6jLNAdh_wHel? zv*0b@D^fGzC6>VgLzQ`{V{=p6<+iw1aTyaP-KULm58a_5P;_QJ)?2B)L`Q(YCf|eD z98VE;jVPy=KO-DO6@*CVi;DorrR=wbB5YClp%%OX&JOwK;}aqO757WP-5ale%gh2s z^`{KzU0ckudB*TD)|HPrmokDx_*g38BgPmh@&<#B9kFy*t6m?khc2}ox@74i3KBqy zwy0}yDUm$2+**A$6Km2L18@e4TM~MiCNFgkV6CXH^V6&VIlLep5Y$tET0Q z*5)>Qt~4K0Q>IC!!e?uX$u^E>!K@@OD6QmAR}7B9GAua;OUpnMQbv)c0}7qLocY+O zK<04vVkA2AObkkRO3^x-jgIg~dxwt&1B9RlPsjBbxUpKF7#taKOrZhj)Jsqc#4izN z2c0V=W5!|Njwy!(Xg}DpCij!V6Y$pBwEZy8(%;zBIIyQioCdA4uey{+5@&F-)O|g^ zOW!bADwotW9rf~hd|XvibA>fteft(pmhx^{dMYl{Vl%FchM{8OsAwwGutGgC)sD43D`YO5*XL*$?25h52 zW-BjZfz8U}J!XW9SYWgAOy(Jk)y-$2o*wg^WOA2@Yrm5VTH{uw)&u=1iA4|*+(>?F zT=d9uf-z^?`v5It zi(_=y^q`l_QxG$B=hz+7Ae=1|ECi##U)*F(7`l&M47|raFpB9Dd$QWq<2&90Wy9XM zgu>07pA`0FF(0p=nvEM(JKW+60(X_qLbX>!Z^l*^`^2~H3^;2Tp7+rYVqws~kN4lc zJ5?0DgBU)UoXu9(e1M4{zO8fWhHA5pd+(!8RfIcP3kC%|g(s-?!bh7i2welxCHZi6wU0eel4VbphwYGB(Kd-B^?@fo(!?^dlw zV{#ow33tf_12KrzumzZ7_eLzV1Q!k{2M=Qr4)EqWUlFJWI?4)6XReCl-rdt7Pm#mc zXAjIhmfzl22pGBc?wu6y5o$jbfQU}U@rIg-6KHvS+yzi(axUi06WTz`L!}^;z*aYKaB_*aYY1TJ054hFp_rS?3iSBZ`H zM&lFmeFd4u3LihV6-~xJ+3iG^B3HRrls)5}jbHuPiwlizAvI%nRnk)#GrJ>Xx0-3T;TX5F~+Ky!+N+M?nYbyy~tduz8-m;wP{{+m8!x|i^F*JS$YJA z=l&7=`hg9EZvnt1YFQ*uEyTq;5SL1(!A$?+`mJD|FWv^(sJbmL$i({do+!Ko;-4E# zUjh$NnuI0|`HQndYuIe4{kBn1%oo26FCs6_pBba^1JSsVV<(Kq54qN1F=iry@1>y<*t>w(gB1uA z@f#b~ql$*g4|PFNhWx0#plAes=vsT#iILp5J2$vSmtV}wY)5)!cNr?w5|f`Ap(@7K z3;dQ^?jz7&^)0lOj0KCuPntI*bN2?Vr^wV2rtKH!ITzd33_dNieTVJ;42|Um814hw zc_RzJE0K+C!{3KqsF)lc;Y5y>W;t|m0DpGEas#L4*CIEeg{k#WOA2qs#w{m^b%|##K8pf z1@4ouhts%l)M{yK?$6x_{&}vwCW}4!S4ZwGDY+oM#MQ7sg@FhZFR~>wp>o##5*+u} z4!TPrJe+veusc>;2f(WQ>5tt0zp9SI)YDyCI4+)!c9aCh7plck3FfhmyP4rdXMAFZ zEE{+*8o-#tFzYh>QtNM{qe`529zQ<43wEVK{rxf>bG1cUmK?NG*IsWe&gGOFF_9Wv7s=*)UEybG(@dx`7p}i5a0}KdnChLOv85H zA;>;*HHECdFT*#4`|OVpZi2^$=dnCxTjxN&bx1)p{d__r<`PzT@mID3GU9Q%1ZU58 zsFm+x;rMQ!$a&y2EY>2neffUKJ{xI9*(!)UK5^kfmg1= zi{bvn>}+*#I=ZQR=66lm{o5A^`-3dOM=|OsEY-XZ->2}mXUo-01HU_xL10$Gkwg6W zbSlG*U@w5E;HAeAGzW|L0nlb%Uoi++Y+Oq=)-cOT_!bXAn*vBO^k~mthFd8f)d-V_ za4-;>MUALMu#}^`ZE?vE35rMS(*WGGX{<;=QBWlWHp%%GhiUHK8;39=ab63Q3$0;+ zU~niA4?u=*xfEoR0b`762X7fHA~Jl&deNcr6IBy{DM!hyU6#z&fw#iA8%fG3NM2_JGZGLMu-);z={o-QQ6WbG(<9s2OI4=n`wd9z&O8tyGLw$#xT7y7y^%43Be#EOsr!d6y1v6LKl2q^h z;F4i;%5YWh<00QM2ZMS-L$^>v1$wj_dbR^?t7daG74R5tq^V?-4;FJ~NqsN_XV_x! zZB84l8YiP6cnD*u*o7yg#8O1N>MP`!X`=(iN&xv{ex;tWc~vXTLrYbT5=J?m><-tU z;d{FVVII^a!ozjg(g7Z(%~r+yw|FklnsHd|e^5Tl$l8Tu?Jj(qD0VCUb+aZVqQIIj zCCtp6ej?6Rst-yV<@s)A?mi7O<1{lJR5Ynh%U8eNPG&d(LS}pe!l=7x)CsBzMGQ69 zjXKFe%|>NQH3MR7C?c|QR%Ie(_&0oGB8cBlcmQHmVdP_pTy{zUc{>aysmBNVi><%jtR0>dcBa<&&v9z6vrpPWQ%PE2vVg~O7Zx=3K(ztX(XKe#V*M$w z{{XDIWfH2AHW))B8lMsP@?{9R7<`*)n3?I#3_tMpDF@E8kRnbrb5%eZIw+8!L;$ZE z12XUn!+qlg3;mNC0N}jnoKpaa8GtN<>*&u0(_Ymc@LP+bkrah+t-1c`F@@&JX8B#r zAdBNx3kw@;!?zcr3Q_=A;2}IKqp*o9NPcKKwjq1&d&G$AhEyJoc9=m{Hjpt`jmKB8 zco|?+>-*us)-Xd2L#o@DNdC9?!Q%81X!0G%Nb}7K%Y6(SX;5rAWYozm_o1q3oAm=j zzL*wHo1G=FG3C-`o!zkicC;j5bc8czbs8=JCDHC^b@8q^m&05l>`2U&g$xEB`Ph*Y z5qP}+5yYF`*hT&Ic8QzVRn?fDI&R_zGSBh)RthR{^sOvZUy1K!5o*&+;0YFu*8p9; z+vH~hv|hEq0S!a~_ns$V^8{a+prXiBZ@9}~QN9LBK}DG=ihYp?iJzd~mDOy^YL*Vb zupSoYe#l+}Vg_wQ9j?hj;+T73hPH&Ue*zZ~lqmw>IMV>G!CN^MEc=fgV6gURV8UP2M>s#&>+b zChziq(HRT|N>lLHO2hGY{VQN}m%N_%t2#}R{zqe`KI^XgA3wlIFR!mNSw}Zp_+gy% z;~OyE3$0;3USU!vx5r_OhLRTr-lHv6yCw=UT0B(@WXQT$t<{NQ(WdLfON>yI{~TX0 zU{_bpZRr_{7q~@8Qt0@V827g*>x&fZ0EjIciXR-s5iRF3D^v)CX;$W8bQxMB1{Qly z??$T6D|oCv)?1~+n+0QjqcFhCrO}%)TV~5wO>nn$Zwk2Ec?gMCB!dv>#p54iMMr-4 zCIhW%fTIc)F&DTl0~(e9LrNtJCVtuhac}iG>dNVcIiP)4s3UAruT<98bb6RO(gFkhR2Sing~;6t-N+pg+1v$@BHY!r1b0jS(GUVt zy;^CeY%#X{FSzSV?iz%<^e}gWHL3nyb-9Z>(gFhm)Fb;SI~F2$QNkS&+1&m3CyP5i z)T@4fL%17{-xQfC9V0kA;lJRnJGmR+8H<*ErP7gIPfco|S3UbcSazfZ2Ch(FR*^dv zB6qig7c)piHg_YD!uj-IXC$hA@MgYQAQ4Poh7yCkY6y^qdh3g`kuo@TR%f}mC0IlN z9J+;SnwiUpJWh}^nO_a(qS{dX%eK2gojBN+nW;Yx`h?nk6pyoU<4- z9v=`+ObJT8CfFD&pQEagV;N0hx{%JQgiPCNex+AEjy)qZn$;;Hh^x>Wg<)%+;!Qjq z7*_ZZ!WHvLfLvXH6kkdda7s5!xX^a}8o@rrL8ND-Mxirq~wb9Q6zkU|8QJSegbPgc?Whz$mDH zcm(vt6vT=$TxXr`KylX`$6s(wOL!Ker^I;@lx;)?t>+>1zwj)^MM(8c5^gO)4N=X7 zV+4e({{!_(8JEPn+E#>f5e1yIc(eyF;3=n+kS=rR#ytH`O78%M`(eS_(&o zVV6aEs6=B=Iz&Kz2&-s-gl~4Z+3o;T&^W9aOn2G`42}_4t2qRAIAIrro8v;luIsx< zDmTn&4#1uzu5hyuB2p~+-<6s7Fl_C_IK$;LBCR;=olfYylAW>Xf5=h~THVuug3%6C=g&_Y0)9hY&k{ruTHE1Gi?GNA;q_f2yv-!DZGepwj29suUd~i9+VGv z_W)`PmVt4e8@zwFkBVmVK98s~ciMRU#G4R9yvx)$;;nGw&GM?r7T%5*3*KztT_$*+ zh``$mh=|m3bX|zIn0UpNDi2W);I}Q19It9&p(C-TNOCzxFI-3HqoU%0O zdZhSjg+Nchs2AvsR=Nq?;#Dj2v`peJ6$0ZxfQ5xXWtCej_Xq)I+L9SZ0wZEs1BNQ< zDiVn2w_StrUNzhzF!wSckP8AVEClY0Adnygte{6~aPll5oGb(elfXgxo>J~e1Pc>j z$eAjbc4EClhfg+h8wfjFU>W797YQr79#LW{ zm;_j+3hZcsL7WW`WlWw2j}>_-Qhq3aN)%ak_nb2BO5_AB-1;%y&`7UiI8tkSQ5{=aZPq4p>Y|4 z%Mym*@`rK7s7$HxpBuROolCfanU@#``w)LkBV5iMm?ARH;(I3=a3k%znj^T*7*s-OKWI z1}Tfo>u^Pm-0pD5K>W`+G$6EFDYONk;0SH^&J*@WtlET+a0E0N<yD+Xg)pz?WrX@o|sJKqBR4T97BSkYT0h=F zukI7nlhD>ceRmVo;~dmvgW}5sVzYTrcE9>&2^y+VAWroFB6L+{5OhCr#QNTpO?loH@xslM!TLUh zxF*VcY&?FC9C@&F_mN&Od`}<|6X@;kJ?XA+;IXMFq-McUS(Qb}d!?J-^QkRJ0+Zc| zXg*gh)et~oD&4B%eFD{ApsXZ;x&Tm+k&N@q_YzRI!mT_=Qn)Q2e|?J~wLqL1jcN3s z;2kUj2a?kS-*-GOEU-2g`;x&$naH{?kSQD{BJcc-BKHf_TLNVz2^TLB>VQCrV|WZu zdSYLz^#eg;HrPRL5m%t@6AYH+7Yw%&L&xUqX7o5}C@=(#SpWjr=>T+`R3Cx0+>*ea zN7%W9g+FZtK%bW%w#&%(s$_0{grDxM=TrQSKbQP1+KTP@VQV*r2; zLIeyVr2zssQ5=pgdJwx{vI!)UfS$gKr!ed3eHz^a9`Y)WMIfo85O^2_SXc=3j3Dqq zI}%`~O`sGhSayQ@Qe%hHT=1xbM z9S~1#iy`b@c%EUr@Y?3MqW+>594+!{ zY2?&rV|&U(*{~bxkG02>A>QH4oC#7)X#|xhCWRu$W&g|qD)9?G_2?S6`N|>hFkf#V zmF8x|GNNmLBS!^(xW{702IhTeF_G=d$QP@%y z!mbLka;#xE;lNxPtA8dzfMJuYo&jLkSUqY3&KE$-UJ2lX05pT-0n3iGPQkZkgO%Xg zxnvTSN}Dq1&Jdss+bhFH*;i09Oe5#yr3ZO&nXDGN5|(|MX9NCT>WcUZsKc$F;@yS0DR>-2SpazNlG2nXwW@hqRW#!GJ@{j1}30o)SVLpy*CUJWk$OsqNLCzcSQ!4~OeCp^w-3qzP zQpnDwS|RUks*pt}ZrLR2Ay7Q7U0#`+L({8#6D*sG&8#T306m!ic8!Ca*mFi!7m__u zY;xFHI20RlG$A5N4tjkJq@(qDCU{}5;hwFCK)L!YFqzYW1uZ5Qs(0yKl9*Zm zoU55E?;%Vs3NtyB4Xk#!nJj8;Gl}{vB%{-j;wu+A>>MhKG<0F^<^)#W8NE$s`vMw^z`H4=U(oN%OuljYou7@v4XeBF^S>62xow5UpFx9#?Rp%EXwb1jgZY%x4fwLE z`)CP8%C=?3Ws;GMFVV#*$PCAJ%gF$Y<07Q8nP<3kQABs*&8E%#tooGhq|D9w63l;$ z)8Z+{PE!#2OOs}f!tzpB7ys7E)y&V5%LPdB4Q|CIkY>J*G#cDAp7W|%77gw#1&zNp zY3Ap#IuxdHh0w5?S!nbmjU_@unzHN0j>{EwrKES3($DJNi*LOp{{#dx|&&N zY(a|en9z`BeueI{#7*OGUR837mes6Sq47eKW^NWi;{l;TWMD^VOk#>b1B}<{@t4~` z`22}!(EMt{Te!J|In8YY+!cI;4KQX%wAQx8GX;8W!A2g<3g}pY=2d+Qmk~C=FWP`r znACM#el>o{zz<;+vRuDw5GyDx@UE__9-*D?>Z^5BdBT}i8+?H=U zY|+Un$Z(C7!1+t+YC22VALHO%9yDmRY(-S(3Cp9kAYY==bs){lCT8%zuH9pcL=y8e*w=S zc(H&>e;x#Is49O0{xzHKMFME03Sd_Pt`tD_E7eTsveJNi9dwy$ga3e46CDhZ<->7c zQL2uj(W(QgA1vKMAwE2aqNR}U=P#4;4X*P*8z^w20%fo<(X7P30dpt+8VC3{F<>6U zziN=cL-;WSF(k}1_8>>crU9dhrP`xZxT!h^jB4UA4okVkXq|x3Aio#M??(B}ooNB1 zR(>y$-*xzHH}HB0LOt=CZs2caaPMm1hF6<5@GA8QTuQis->@aMWiusZHSj7*>+RUc z2L20uQ7J_L>HPyJ*qk=Kugs)Ax@P5)2l(8IWqLR zUMSlIDfz)6OJ%k+~u+p!-hD!*FvI6#PN9=(8 zWFu>A$y{K!psKz_0!ulnSLjZ1_-*^xci{g!K(Qv5If0kYdf%U}2Nm4>s4j#gi&H-Qwv&HY){|HCG;iWp4rOyKeFP zSk5ZC#q(t|z{a$pXhl3*=**-a0(PBSJf#Bb7S9U8_7+$XPqDzV_X2jkTMjb?mW7Zb zqP>f-lLS_DafHCKSEIyxfYrK)W*H=~{Ip>&BJ2Wz6|bHISmbR88ngs}Wva+O^gip$ zPaF1V6ky8;3&;LB{1Y#gK<4{WemBd@uu8W-3m=xkJJoA+W`@!nmOC>(O9g~;JOc70 zKsa|vE9i?)q+C0LJi2Kf;9(^Ag~A(!-bCS#NmSJ_fUSwsu$=ptzXFrc)^|7rz67OQ zM*B8*A!9YjYS$Mq%Ea`RAqAdMe$zj~AL4hw*di%(6ENrUTMW3dhrgS{&1&<@FR-v$ z8(k^KJ{vH0%5V0;fKe&GwehZ!-&6v)1o=%R4j6Uvn@Sllj>&H}HjKUeX2S&xCBHdO z%vmID(s?wb7v!kkT^=WPIYyI7WRF zW&UO87klPb`py;r!tGjJWQz^>wg57fK&t>`S;NBLf1wMLExl;g54^qs(&$32xy5pG z>>04en`qYQFF8~9*ILjFm;k-a>*Fpmw*5{N+AtKT-XD)YG^x*qM>81XTr5a>u~NVP zrdi+zkZiZMp`y@y6e8$Tkf?ozN6d8H-{U-4PLT7V+6Cu=SOvv^UMP`ghu~YJCaY9yt0s|3`yk3%XU?wsH9~1W z3oGp>D0Et-9fXXq5caCGq$XQ*O+IfTgjlJGC4{|Xx*im5r9A`>g4j!gRy7gAhg<}* zouq)S2dGrbx_?UgsZgB4}maS$FBAmA#AnRLAKX$5VzawVgcQwLH`9%x6+<1 zpiCiHlEbqa4hF(XTYn;~v=<@AH7Tifc_5Q@2Q>a_*niC$?C^W<5C=c)b%1T^4Pesi z0Cj-C7_~*3YaO8AC}TW(2wW&sxy1W{dgpmiO-W)*K!hp>RDD(KF?KllCDwng)8Qmv zOa;_eVL2re<}u;No~7*u?3z1Py}f+dQ)SIb*`Dc*R#$*H`zc35Uf*EhLe`gWLk9cX zbj;t_XC8#qj-_BX!(kW9e63c{^BGgM@*Hl$+mmnGvSL|sWHdnce1d}QqwWy!X&U^S za61aUn+4o%#|(g4wxUaYgsu42>sufw1?nYmN%s4pDI#oU0x~Qoec*V6lU5N!mfI`@ zRWQ1~#Y8Nvfh#?Rhj9EKRXM^t^)gomaC9fLB!H{_aX>wjZ%X0Ou0ZAzyzzwhodTIS zxV{Cq{s%B?p1FJ^Uu6kqF2;Z5Be4V-j7;IC3Gw57L@B1APqJh7U;xl z=ci#iT0e=!1Qs_cnA7m^oOQndu6_uv;}u6-1SW1g#?~}n)9f=Z3N&r4I0{iXUHV(q z{jcsWT^<(e2xL&KX)=)O1;#X#TJxME)}mh`#QJ@NSX)^L4p6K+U1FU(%o6Jl|JTI& z%Y2tu>nPTitY)NGUlo@`u~rRqiS0CE!%%>gBT z2DsZR{eq9J-NtXx%6D6GnmtKLK#2!YvE<1_8IUPQXhDUM}FGbx#X;k_JBsa7*h1 z{1E|XicS4~f*%m@zDQQ11w2`U{|a!X+SJnooGCW=Wd!%Mqe4n7M3)ydI%@DnfLpPU zP>&LDD;5&we?AKE?gGvjNA0DPF*k$Kp!v{NvXyBn}~D7_*acS4{Dz_8K?32HB7#y28f~X55BBng!KC_;68%V=qS+=m~_8K%)4C{ajZ@+uTd!|B>`+Jz%o^4w1NW5Pn+%|gw<fbLZh7{SWV;c2pZ=L4I*P5&XO-X%4>x$C(3K4u6k1Y8FmVO^!Yps0fXnTK0gU)UzLy<4Kk2(dv!NlpKp=7 z!e@F_{$MRs&-GH_4o<^C3zuRMCoIu{wXRlc&l;bP6kpHwPOG&ffoeB_j$U0Y$O$O(*;K z=_>W`6OhVmVc3#NCpCutYyi`2HR$YB69#Fic=LqmE^etjh6R?eRJsY%Ha1G7EmC}k z!%{g$H?qV{;2f{|?Fu1KTHRgCA<6B7qX5xYvoF27&N8Wr}p? zVyyQ#D=7l?5TUdI=?jUeTskK4Ay5t;I%lfDjsPsuI)zs$uL7+4H@08nc>F)wo(PQ` zY3{=ITRhd?AZ;{hA*opnaRzxzAhi)^QZ*zuR3@lsIhTD)9YAO--fn21zgts?={?|gLxF2T2wY3a2{=;>9z z4A3IrTLVbp;czViVCX{L@J=LHc@OlRk<0l^c^xUf(H$sYsr*8sPU5$q#v$?NEYy6d z0H{-)ngjKwmmSo%32Mtw3TkkLqhf+u3}qjpp5>tKs991_CxlV20wQNip`d<_ zsFw(8iAxKJI)mRLkltPuuu$`L6`;NpsCBFgfxLw^9817%9FbM2&d%L--72^aaPh45WG0 z-hNsde8~klm+Kf8{6>Y5zDT4J>k6|^5o5=*iE*cz1&qE5q8B0b^Qw6kM!p9FjQyQe zv^TL*VoBg8!N@pRFs2EQ#Hcq-cO%jaehbn8UUi9uln>DWY9OlL*{*(e7;pVItUhyW z)ZZY**Rc~($0J!)(4$m1sITyOnyrGTeHIAeP+}S?@uLZ+vG8B!;Npp)={oZ{a!(`ycyimEg-B zKz$8Rv!tM|!J?8S5K~Yy$L9J$qOKIwy@+}|QO|Wy55fLV3w0T8GXvDMK+TeZdQlj4 zZ$Zr*8}&IvozaC{4Rc1T}MP)IOvb>jpo7z{x+( zmvIi+7aBuIqt2m`;Z-+UGp>|gIyKVPQV z=d&W<>;^aLPGQvRzM^E@?7xZ>U(c?N&=(MOwS#(uS1qwn^JNmC<{{Mqwq(k&lw(O| zlAvaeEtwmMdXb=}H&T}pbq2qMYaCC#(n3AyPC`9tqSeDec)ZjQTYoa^fQCJ4=WCix*!d_B))ZRm^C8+1a|4r&}# zUE5m=DrttG#%YbPKl_pkFFJN86x76FqrQ)*7YS%&_ zmK3fZ3#0BKsF}l%q$9o{rtcRW~Q4p^&DPhla&=_KRG)4YG7YI2ZRTc$e&ma`)e zMlN8j4pE`91lH;W0-HhD^+KB(tWpJ*vnPO^09d99-LnOjpU4r|1j1Gdtf={qa2Y{^ z^D!tf5wMm@SExf+{BZPGU@IXeYY(L8ajC$TY1m1CwR9Gj&I+uhr~@61`^ongMeL0Sj0eE1+YRB#er7N>7ixI2&FgszJ=meSpL|7 zh_HN$wfuqdiI2vKHVuo|1@~|vv`O!Rv$W|BHAV>T)CBJYr# z;HW6-EP<`mus*;t75uJJ@dC?F)c+2`o&>MfE;uTRItb5z`|dRCU4Uh(!0yEQjuY$) z>;}T>U2vjJFVd^XE;#A1d0zEKFKr8Y2Bf9$20q7VenxzmwbuSOpwjB5_rKktZbb_B zzny`ZZfpM=>#PO~gLRt0scylf3WF?USFQ^g)cfC9XXO#tV;c4zw_tw!3oGXq%$NHC ztM|W&V79<#1dS>UizAz1!ITOt3)ys65LWMh6TuV<>;VmXpIZns1(tS?hncaD!?*T8Z)$n_2s8c_vjaZ zmHltpu0@v+AOeEHxs&R2rJv+^hks*4|@eQY{Xg3`2x#cXVZNU zu-Hh3PE=Y80NEOcO>tv@0&n6jL$Q3}IFpdNs|^DPwR!FwRzgO$(B$5dTA}hJ)rwwa zM1Cf6Ht2m4)Q&9GK;v&L(){@$7be@|`@^y@!xYdK_`Um3Jv~Q34N+?ae6a?f0dS_; z;41{2DePW<1*mJjZC3#{?!^i(;jJ;%Vvm!F`A6i_+dLibOuOO5gKZN`AK?< z07tF;@L^{LHFs}>qnH;lSNJu`Q5PPMm_fY>so4BtRisE=B-E|u#KFO^pZHj)+Xcx% z8*pIP_!qh>u?MIzP7j7_d>E@Dy2gb00xW`S6q=`!K-(Gx60H)KCu`}*E_P_^>8G3B zz zSjX-JqxA&X1rFFs4fd33BVd+weS&h!CfHyBqu~VDPmkIh=4h~|)#tEDPW&QZDF6$u z|vRX_PTlxjS178Kq( zR29R7t)J*_$q!InY^{vI$lipa?34Lm+Pbe%YkS#Dc4{)BiY;i%1N}K-S)`4HfKTRx z7XTgtw6!c^_19!z#KuDf zIuj|@f(Rw7PSBr~IH+;tFxEodae<)bkwcagD|S&B^+%{$*fhM4FB-HHGaQ4q;Nu8` zwlu<^wL>i_yr&`z+8jVz%LW$D&#N4IO(W(>Vdih{dJdOm7rP)UHxOL7opWb_jn}X* zxGU01U|BE1MQQFK$fc@(BoC^Jj>%}$4jz$ygb&+-)fz{>e5Oaejas`|_=|vhGz%{} zEND$B5^$S~hXEQ^=X>PKR_BTMa$<+Y>M1`2rPnT4f7J(6eDUYm3i5Z%f1j%rWKmEA z_maanH1|%D)g$lbLWMZU{E13(Kvm~gjeJS;fUkr2!jnsoQ8RT0$uA)}(Ji%_ZZO9o zzZ|c7r3m@bio1pU3dD>g0y`?P%{N?)(Hs;B6=o7O=}t$Av2OfSs78KAbtX1%V@l(T z`UYoB=cnoJmC6#~L(s0z*IIRjEUBfj9$L`nA;Vgcv?#r-LUcjp4%4rARV&T3;k!|o z#xXvdX|WBx!%SE1cJ-^5$@B)KSer!$fUbIx*yDTHE%GYHKV5Z;RNo}naahmlSDM97 zuoz>BG!ThkpG55XQV@m^>RMvYaj?JcRX17K`3@$aRslOp+QC+S7<;l{XD0cM z!7`aW?EM4hpU%;hFS}aU zd$WmXKU?5b-oMKw+BeAJ?MU%uoKFfO+F``r;9xKDs+%qBy{{4MJf+5xcI9V=v3C&c z%p~R(_;PwxGc_1h35Vh-vLQn%KN%UUd}}!>D0&53S9w2bzDoGY0YXUepXxQZ9p5CT ziKQ;}s<*r7ntL7;-gtmeSMJByX#>WUR_z3`f$s2xEntXFVj0mEndC&6q|qB+T1aV8O9+ZL$`Cc4(~gs&SwZ>Rq_iS0FW54vCv||SjMAhRTMtH#Y zygn~=3Qc#$G~IMOz8Z1I#BAV*G*lZ@7QLEsD*nD#-PTF#RP`LGc)6ofy6NU~1F^QQ z=kIVe-3B&Yd!*xDNP6{|4-DZU0_gE`T{PR}g8x3Xsb=p~v+3445?Ct#kyjOW)RixpFYNKK7VBrX-y4rP zmCqFRtjg~si-VA2MUPVXbATPMh3Lp_H@2TJ)yCA4nC!8W z1$=-8=SeZ9+Tbe$oGGZW95Q>B;EM&E9a}vl;Da^z9)L5|2ERkVnPP+I5WGyl#Q+Qv z@H7qn8Nl70{d@tpdw3UsT84Ub9veb*6E%vF3@R^nkYX<0qxv%6NTak%=i)DK8_DOt z7~yi~b-myWKfs{q*lLp=`Q+-1Wjcx8b(dsqP+vtP`}UZ z@ew&uKcP5YdKnvXxllC`iIKyjDm4&(%+fO;*=LI`6^l|@*Vt(1eqh&~gw$x@q2iFT z*QZ3BLUp!KO`LbRC=RnNiGAa1+IhcF@6(ZZdfACT&Wm2}<%O_Zq)3m%r` zT7trX?{~VTnj_gybr0R!BuAn+=k?$jTA~$$r8+$4#m;C;<8S0g`+}>$Ot`^&JFKZYK}g@J zMxHxJ2HCQeeK_+C9;XhL_CiOZviHWnrZJvrTH#&Cte1g5H3~pf^Ch%{?zi{W-+^ka zlDd;o5c!(A{xtkjSW9svOb04ObIBVEqB-O&*vw53L8ZXcY^YlR7*+!u2Gf8e1dt_I zsUZN;8Fr-}02}5SKCXx(c=77^OZ9v;(Uj-(2$3WZa*AR&imJB?T6i{(F>9@-%gx>9 z@Q(GBcI$q(Pn?juDaJ#1yvCVr zo+vs#tH+?3@v~dyg@VJPyb6P0k9kuJ-oKm}h&gJeCk2KcjR8!8N9{g-JhT&##(5=p z#L;7>#}AC3{ zL1*Ka(IfGUJt_)L{5vro0PW4G8~Yq5gQ!DRFa|-{?tf?=Q^GuEHiCTgCh)j1kiRj; z=JDUarizIi^&gHlZy0+-<{rN}hL+BYDSM_JUKYLWVc_$}50s}n{cQ|+^D|{eES_tx zxejYxbzXI5D;$BtyWx$h|BJW)G9ND~;;mCNCt*~meax|Jnv`}b?)%?EqXL3Oy^ZPH z;btb^_EeX=4+gfWEf3*I(|EitUe@jrP_4zMc_L6yr{-?MD>voankQd07E1_Etb~F< z1cCW-Z_fPX?6dDzH->`mtb!v$=Zu2Zr*=7s$KZG2tC{-jYP`$5O-%;E%~|Hr;6j$e z3!XryKI@A2n->zL%Kx%4WbT@9q@f~CcaNiL7n<*QdVExVC;W}^$7iW=Fu^qmzGY~& zEY;&r(8jUmR=Y>Zt1te9!i^*l^2e**-A;ybQ77G7PvphcwDWDr#(ET1)b~jLXpg61 zXY$3@U+|WddbK|j{rk=N76xtX}SsR#(-BTqKgOKgrLKKiQT=60XLgL~ch;?xrM{{jnPK z9bU+xuB?HX^e2P1pAcE=g=tSFM%KM*3Qo)kV*5$11_WZPhUCwh47K zL@pkGYhGoxJ4@XLF8G==Of6d)Rm{fa=JJ>#m0;ioEJ}I&NowYHQDy0RZ^f}Z37BMiJH@yx8lg%XDYyCisqsp0ep}ly6 z$J`xQ$5N{Cf_ixBCwlVtJA+Q*LBlkaK0}+I&Sh8L4Bqa+r+HL#q7R>W{vWlXQ(s3b zp5N_gg{51bub~W&VS$2DZjE>AYN45d4NS;u8O*E-Y$!noRAcTx5rX2vhKAZtg*B)- z6NUlV>cOFCLbsJL_{45QQOJMDEI3fp&72r-UJX0D6xs?3XW-{z{2Vka#orvimoYiy z--jl-7nThe5qO~DICWQ5IRlr+9hr#NABX$3aa3)$GcwHc_-;oNXq{8BxhF%Rw<$T@ zP-}OwjuSwvIa(z4vnZHn%gWJ)z`{x|=vqf*%Wq!R%o7ULK(FC@t-kwurznr~8T5`U z^y+xq3YpUeJFVszAiI!xLS2V2$*e=5bS{}hoi3PLAKIuoo4e~Pjp`_GmYUe(H@2r% zTB~o3Vyu*4?h{HT?VUR4hf|mtZ|-248q+n(gMh+}hTfFO(xYq1(9(S|XfW=q8)0@I zXe1%azK=5Z>58n==G2^q;46Hz-E3txfZw+c1K3IDbKKhmy98uLL4qg09VDb_sD?w0 z;yqOM_d4zhXSIN@vIwJQ@pR*tpp78yKV_Ny(J1X6fsWi51IbV-4j)-D6Ka}o8{V1i zKhZWkc&{8Umis&EHlP{mug#2kBN{C}44gzemrRQmEMzSMh2!xz_ec-C+>XSNBWZ@p zJU|XhWM;(-s+>71e{|u=7eOuY(J%40@Z{g|cSg6ulP@vtv5zEe1=A9PkB)`AH5#H4 z=f91FP`||YhqXz3|HcIG$eS(m)uOR6bmR~+v#`&M%9U7T;tP+a$6F;joIr{7NGm+) z0dM&Qg(su!*=zaiu>8scV-2VTS_{Sa-D0(_;qv^S(xRkT0tJTX zNO3WO+TUp7ZczTH-`I@rP=()xP>tH;QD_8npDIJoG}awM-8_j!f5zXeY+Njg%55{4 z$R>ps_qaj^x^S~Op{MnAl#XdTRI8$2U^N>-X_#+IwL~NZJA}7>#<~NXS;)T#lSBAn zW;O;3YFFeXuUN4H0b(k`Jv04SYI?0#9<;B;D;mwv2aT76GYQE>o9%GpxzQ2}Sfh>X zEUTf$9TVelKDu%nV?#zFDT=RaZ#K^|OKMRaH_OyKtCK{=AbGHwItEF`GlvL^u4VA} z<}_OGfWHp&+7dj*RU+WY3NDlw0Kubpu)t%>Kt?^f7s2Dgm5?NZM^)DjmSL;994K_S z$eeA0K)u|a;i5zW>7Q#Ke?17Go!}Wy6E608SHi_55-!$v_=9kf1ZYvB&icb}v0D4r z$Z+wYi|laG!r*Fqh?!WMgp1GKhj5YHs9V;a8ZK^NxOgRs=x~t;a*w>y58>jZzTt3@ z$^T=xSYpMNFk^xt4gn`51jC|J!ZFMk?Mr=s5F?El)Feil2x|YU80mUk zV0dbb^g$M4q;6BK80mYIam7e%5%uM$$QbFF58N@*mpe|4k)$bp{q_%Ir1=;;h(^)6 z=opEV%;x_oM&guVM2r+Wvq_9JsLOwfk)%#*r@CXLOV9l8VU>d}hT+eGa=~B+2>)2D(X%bOk5boEYf`|NkaNBJ2NUjKrdW!W{g~J<<#@7aH>a zX^f<+{gV?TT?%^^86!!FpMU({#7M2r|F2>sQV7RLIbi0rG14U%0Q^CWw7kb3#Yh@= zgBsZ&o#r$#((jvHF_M9p!ive+67DeR)PU&Z!>0s9Q#aWGQI#DKE&J~RqN6iT8xWC; z+#`V-ng&GDD%WG`1G@SDIUr)Fof&VO&(ZujW>i+Tul5SWbG@BikD*=$9Tl0*5SdMsS0G(-WBgWKT{yHZxAto>(J}@Cco%a!ft0zXI<`P^z-2wsB z6JA6hGBt>%&GQ|1JRmq?IT4U}1`U7N@t53Fd)>T*zsoJ?$^0gJ(3 zmfF|)6u@i=T{xKcs)gN9mn*x^$2nuO!Jm$Ixvw!EN%7LizWZt+Mh$=3BEt&WYeL z(iOt1FtH&&27rS;+v%kepV=5p2x9X;_UZ0ccjV(Xt?4OQq084}F+qxEuu_~OC5*Y7 z(+)9tEoz$O#i{`)J#iePRXv2o$eArj&$Fhr6HCkJA0wzdsUDh^y|2_GbP*yET; zaxi>CUY(nD<{5;3$C%pGjnPjp#ZMU~$|JF< zo4g}2jJ(%YBnHa9B1NNMzK58#~7T1rDl#v z%EFX|$yw!Ob4Wt!kQlEyBtEs7H-vdVjJhvN9fp))@u_i`9f-jY9XdfJLqsJr7$YA~ z@5Lpj;`HAiPw!ov-ncdWH_zNhx_Atfb-malqeD_3^)|k8imq zKjz@Rnq~*94s74IT}{6o#yoDn6ajeEc09+{!ZQ(;9hMMQT^11vZ^fvP=1UEI{nSyR z2Z60RA4QzYzNQOdfD{D0p8LZ zNI#~|Knm&=&7{l(^O}UzYoLbL#HV5s?tYvGI2^h(n0X8v8d2Gh|5$xhr{lxa)4EWVI+8iEr$01wpcSQhQlwn{&_?F)GCx`Hd>R}qT0SHU@qH5XMJcQ+CH<) zTss#@Ko&^fQWQ#@cMM`cRJgDf|8mMPap70^)n|Vow>pq}IFPFXxwRB`3{oR3WL+@5 z+8gli6t6Um#(2zOB$=7j^lzL`5idodr_5_4}B7NcOj$3NA0Zx%3n%xCx-v-x2`lKD(NeqEpV<}=KQ z{@C;@bC+3AYi=`ht5bKNa>kUMp2RmRinh<`Z>H}wHbtjxZ5BeY;LR~Cw@bio@q%*P zCqkxBt1aSrMPOiydg9&H!1&ev!IL( ztc4d$uQcDM-r$=%%`vI`HYZfw3W3gWe=u{U8hX&xCNWN%tW*zui{n1;5!{o1hQ<@} zud*7YuBMs!^C({kG)NW%(WO>d3UW3lvybPugpIe#lh9>U1kLp!4EU}3;tfBj6Lp}S zt zt?~}(4uDVwOIa~xgU?1^y9$`iql}`BDRsCw@Cz)?XU2O~^b6P)r^9P=*S2&<7O=8i z;hfXs)hFY?PK>9l90B|0vhqRv+Y=$_=Cb9SZ=>x*&>}7!!H2r;Y=B|iCx4(setje; z(viTlv*_*z{hWU(q;`=p2Z7=Fw#Q$wMussR%-?Iy$cvQ;ZN1t&h(Hap0zqfP8QMPO zS$L>mSPbI-0G#Ok2sNamJ4@U;z{)*xSuYvH7_~iLJp4qir_TonHOMc<21=ceT0)YK zAfEdk^~KM8nipu}0c~UkzQC9r5l!=8X6;C`B)N%ZnRUT}D(RI43T6CN(oc0ajR@S3 zjrgo^8^d|5@=i<{rC!CvOP}(wvH*mjW8#E9AB|IYj&9+R$Uoa$IG0WEW@jgMtto{Q zM)2yynBbQlAQ`Q{TRoN#>q&i#FtF8d%M&OnL;-fBnIwiJUOk?wr!osSTD)AB(x<#= zd*UpABbH)SvbB4FR&_6A1dJUM@Rp4oBTXVR6y)PREP0fvu#RC~Ksu=lC$Rc2nqB$&OY@h8LRflW3Z48(UO3fVsgHf_N ze=-_e4`LFFdLTtqT=$EdGqKQ{jZqMTW_Don#?HZY9IcwelFh7+(Hr5k&0$GFe{J+8 z-hU0ZE%X9o>Zop9`c0ho7Nj^(s+(BEwW?s|fk455k%5Bh0E}{h3YE+Pi=p;uAb|T% zVUoFS6ey?+6zqW+b~4NzxPa+P7$(FL1z0~}nYuv1u|PqC)z9cGcVbo7^jAkCrl?DW z86I;ux=vPH_L!L}x>D9)s-i0bV-Dvf`B{3n5)60|jH}t(WiH|jEsKc#5Tn!?n=mGh&NfS` zC`NmY6AGD~9lE^xp4=BC=!md+c|FU1XN(e;4ZFDyK?gPtRG$re zGHOCc=?=9bD@QAYmG+ty4)a`_GxUgvP4qW33mREHnM`A+hdif@m##-9#!L5VT<9m0 zjk3|G1nw)chH@VD4LXV*im`7kbytxiK^gG@G8(UjA)EYmyX8`Qf5#RpbPhe$? zLqN|c^~rY-oRNZB>1_(v;G$l9m{r(9Mb$8{2Rzia74$O%+ z`(-;To@d}E`^}(hv2_5yW$VCk|GsleIq3p@sc#Vr<=^RSAlNAz2v%N=$?>=`I^ajd z>P#S9Xsk_P)wx)&-p-=g^Pj16;S&ot#v@ZD{TAb?X^xTUmNxYvgs{*J{7<$YXd9~@ z8_XRV&ISX$1IU`78N7=VG^$v`O4v*zCYyw;BExl&DXt=1RFyGzLA+_mu)v&_V@p^M z6d>g*%Q-X&tmFJsVo@yq5;OM2?8wUA7RyW|;mTkL1?KZyM|C?uzH}hbFk0TijXA94 zCwpTkKuk)|_UGg0r)V_%yi3JCgf>Zw(W|kym>9n_0H}6sn5AOHkLUL<+{&2=oEzAsUhRI8 z4V0+subz|7{Pt*#sI0Zs^PrULXJc<^3=p&e$|0J6{=^MVgzRlhsrA5;G6I6bHl`f& zn2pAi29Fti8rKbj!C3%3)Ny=<2+r+^lK#jOF=A=b(qHSAemFrCNh^b1IAI&3KmWnz zl97m9ppfPXJ$H*9{fMPnpE9?$TXooUT-MHy=bzJbiVZUit|>Nk;Vd+*c<_Go z;1TVL`pcGs_ShQY+88U2-QOH8`*}pw7*>jqWa%3!>sT(#7ijl8LcHAq%t@gIuEuWL z3$M0z+rD+0z@Rf)tA4zM0&_k7Hc;j~1nh&+=c9(jOq_t+t6J5EWUH5!ZvuN#yw#IZ zKBg@ObGuXr6hmj#TN~|W2$x*_iFC`OEv=R~E$dgiS-%Xd-*?p?u`ZE0G*cptIY16J zuy<$NktaYw;uzQ+V}lsl{QlUd*vx;aMCq1bx@Vh`2~H8O(XtyKhaxO^h)okZ+wG8nN#3I7jo?*blGb?%K%G7}geFcATxphiK(1{E7rrqLQM11JV3 z1`<#L)B?sSZBb_wDhY6Q0_?LKut%+U1q=3I%W1Jl35`f1l!QwmTB@N0i(hlv6(_CH z#t@V`|KIOjdvbx;p7TBb=kt-t-fOS>de^(&`+}(XjM~6H!w|f;e%X6E9=lt)vG-He zwstej4my>aipSdpv}T0?BOp?L^f%KcL^&DyXVPA((;jx&G}Jd|t}$*bgbl|x@otVN zuv!Pg{X-Dm3I;z3WdnI71M|Y0>BZ|mOGv<9{Z9u%eBk>|A0K*P_#u1EY<90CA$nqG z7T(=erTRfT&KEH|1J>^*9^*j%g)y42TY7D8^mm<*$o10SB&WaEp}*XaqLI=4>aZcj z6lmLsb084gelNyvtZSM_cY`~taukMu(~lRfVTbnl6n5TK*k4J$r>ksh3{v&3Z+z9R z1;m4tu_p*44;XxTA;^gv}A%VhuEVXfCB@`K%?3D zkP*}bbOt&Uv}ZKvCxHiIm-x3YMlZqxaY_N8YDMS?W6hP zC%QURW6i@n;2o2cTBz5$Q*caSJD)+Xk2HI+$D6qM|9k)3s>!m@I%sW)8M^MYBG zTT#>%9*eAFumxt|baMEchhBAH1|r^C{YsgQfz(}8O{uZ!eYMy#{GH*@>g~&Z&sR2_ zWOIU37?4m?iIEIATRTu&{;sd=AZF`y4W|Bz$kYU8GdK-XVGR2m>}6gI$9OgOf2}@p z9LP*sFzh188lhn#`>@Hr=4`Q9Gfu~MQ7Tqm9Ucm5`lW*e2d_9o zmJ8IP#T^0hb)W%~zo6NF=5Vkh=P|1h!>mT?><9#f-I>*EerK4~o;RzosbEjRmS&b5 z&WzM$&N!BtTknS0GSKdhw79F?Gr-%T6Q{te+5wFnkXHU~BozqSOD2uzF*GQ1f9Cr^ zaIZ}qW>(wz`?!hGVv)a`xTwqY{~^C)`XiWrXYxA`_WM|!E|cyn2Qay)4kJ6S-8X;r zu2VQS>`qW40K}HWdNP0-p8cnHtYMPNMw>;4+$$zMQo@R6=}_c zA^JaCxY!_T6BiJ4Hxw7NKP56VJp$#`&r~~H8E~*TYna4pN7p5k&XH@;LgHmZk_)0H(c#TQBGv<2gx2e z)=e|fsKZB@>V<;GNWMcjhEq|IYN5_&$$x`7X?JAZP7c(kC)KdtI{h)~WDky{0ElWt ziv0qxEKDHbMe$S~y1o~$w7CyrGWC-?A%#1EV>d&{-`SW~yj%#lapf76WKtw0D?S;* z_b>Fuy=`#M1gI9Rf$>YxS#ov&aCIc8U%`B$(E@&8cB30#h1#=hd9&;vi><{>?B58Afn&7lX5 z=y_kZ85sk)n@+oTvWNd8n=Wh{7!fnOUJgqZGeZ+xDO4*P9t|>Z2o*lbIswnc=t?*~ zz~;QqV}txJlSB)r`Y)v`kjR(Etvo~eBXXm)+&eUq>3^9*mhkZS;41M2dnpMUcrDX# z_L2>~T*OUe65!aTKaYF584;v+Ic=#_7i;WDkyS|osEh4WWCF;z{)LQMREAU31tWoo zj!cYJ3X6PHZyF?0fUK{u8=v||YT+GYZ-@Nodz+Ez0f-BYG5HZa`X%9!CS!)2s=`w;6&L_0f>{ML(9%3NsBuF|KbZHJ^OGyymD|bQ>np#TQ!la`?Bnq) z0YUA~6&P}{=g$z6w7x*UAuY1@TNONEUr*~=ODDd+WNCR+VF%}@< zQF16=Fq6xfj}GV)ut!Jj*R2HI1&};UJbW2GfJJj-ogLhM`}2lkhM4GG$k&1y;0Zlh z2k;iau_Xm6P={$7Vpt?#jnu*fb@sf+6X8ENA+lwZK5NFsa*6s7Zm8}pL$%`H6p_K2|mKj3d4Y2 zA2aS&6EYAJFt_L!&{R$GfSc zHLJnr2_K_Z;wS;IQg-yMM!0vf&`Wgq?&vBO$5VjYC49R+vQyg6VEegVRfl!!?&j^t{6*jlQtKa15sGl}X%|@&Dn#a73RwqlVQ74r zu3Pkm_ppBf=@4q5Zx<^Z;a;b`ho<9@OtcrxZPA~efDAktZBc$bsG@;Qe~nF_K~!tA z_wF*#eBw{$^)|kO4hEcm-Fz7e+Q*sU!e_CEKu*CSzHAV`9@05?5MMRE=E4s0mHizc z6%A<0UB=XXX*T3Ll}^Xku3!WM3HzC(_u;fY9cXmr7?aE5v)JC@+j&@XYwEc-kiO8^ zylz|#5NL$T8eFNhFCBydk9d#1DM|opBmkAKZD`tL&XD2^Fq*>RsBquruEl%l zwkM0>H0(~)YpCJG)#h2(b#D9_knq~XqF_sGNA%cqj>(tXQ z(z-PP$wnHpe#d9=tTz9)WtcEunaxdiNbkpq?@Vg)kI;Z)q)0!lpZyIRb#LU`(Oj4d z=99jMKQQbckHUri5SDWa>H|u8ei@*U&SBqR#wSe13y={2@TAaJ5qA`%5=2suWys+G zuS)@YBA^6QDyD1Vw*pxx9Jd7GVU5G^3{>a)$`Ho_W}v@&LmIsbjRNQ(@{eyPga^CG zh{15z2*_Rlf#Tv$DWhnHaAMtwVITcR$FTc7gJHJ-mfFIj0sg&>^T$>CLDN#@V# z(Kru-c)*?isWCJ+i@SXf_P@W{8U+gJn4SoJa<{I~94EvA~t*Yhh`2+QI^O^I)j3%|2J z-CcvRvR`qJlt7-dc)Kt0i3N5=gQ2~o^==#5y2R0$; zE4lx_LDT~$G(@+EPVWPilmT7@5CGJ zvbaZRm6HYpd_Ba(y^%%#1&SQn06}{l7-UbHsRHTtq}gh}J!iUInyy#)u_Xq%^i@t@ zL-FFpDTS{2uVDUN!2*Xy#71qMzlljSPG+C_2_pPemb{xzTKbM zXTfNYlrs?O2F$WpGxrV6E70E_+Xu`R3>st>7Qz!Ro|DF`c?EhV-c$>GNns69_9xV0 zH6_{8(tPFb^BE*oVfZfmiH9%K)1Go*amlS1^Z?4naSEEv^uC&wp~<>Kg|AGNh-<{{Pyd_)VXWr&h7PygUIu&tY%N^kWGprpZ8#eu#6 ziL;P;-`uP!|D?1zF#e#f8`EGlQx1nQeM?QAc)C7+XqB~mBGka`;oE6X$OXYaTy=Z* zSUna~uO`oQ2hLgr@Y@LEVB#+lCwtsz(NOK^LfbtiC^u%oI)6=$~(o z);AH0Pe9G1rDl)4Y&84|n!XDNLOwkNpSjZdhoya7x_q12WfIbWbJn)xDxkTUt=WGs z8KxT-d=_5_!^-@HcIslF@Wy2fXd}}5;zC#N6?!`o7^22;0jTLU@>W3i&Np~6PD|C{ zrRWOw??SK3T9^hm2jk!%Yt+3+S)#}|6tSjxU_zECWh`fBafT<~>}+uz`9)j2rdK`p z(jBH~n(k#<%Q_(L6sdMDJStNCxoP2k5QOR990RndTCqo*mZn$!2fDUjzjYJVNJP2V zyHT{^?A?{kgMei_n7n2jd7azXUeE$WvqQrU(B9FAUo&nlnN{kcsbrF`OtxDor5g0Q z)^y!&+RLZsfGiNKh^2M@67=GwQ+SM)H{+MWXk-kkEL7rF(^3uiK@47i5Ix~hCRebS zr)}|*nCs#xzrN2EEoWuL8+Y9Yo~8w!HJ~SA!+XxO2Kf<=OEL{oG6q6Jfqo4NP!a)Y zoJHzF7Iy}8fO@2&Y2{ScUM0gtzpSP-{bzQ*6IlT;Ku=`-RzG+>bxAczTpe{s8nQN3 zBCCVReh8*XFj;yc$jhUppf&o01{LUu4XqGoIC#zE2O>iS&Qga_P4}|j=qT&$S{5ji zD-rHbWAwo}Jca;M0LeK`RblCh7%Aga)sMqJz|pL(Y^M6VW6{q7bh$55?eZ2lvlpr_ zAxZ5Y-Q9|pN)IqNi1DJdd;}}?^l`ZsVtsu11@Rrss~?6yAO`7Hq;H{~`Ys?(jKDf1 zgp;o8P$6J@6%_7ab%nYS<13`Xu0St^b4`d6kHP}|o5ns^vs=E;g@v!i;IkMHiiL2i z<%~9LNOqsbfLU$Uatt~RM$~4|s^#%pp&w|&-vG>2 zJA`Rp64yZr7D_HCK(FdQ#W--#C!Pj3AOYz1Y8(L<(s{ZoFoSN3KhiPypMDDTA827X zrU{5hRz5E#Na{i~XqAYO)y!qimZ1x^r}f%3J^ z@HWyZeSY`1qAL#N=7St26h8uVlEQ3-A-U zvPK#Q`mBl#>3GhG_3e0G0c!u$Viajl3twurXM``b+DC``SnWA5;CLsN8cM!5);sIn z@qohLshXPd2DFlj`l@yB({=Vsr|^mxAa;2p9-t4y>5PN^=*kaW84!IyQEh#gY*i<# znyV;As6N%d{|XeQ;w;$}P9fR1f-fHDC5h7gcK>ZL1 z6s3X-v&&xu+;YRef(=i>%yZoM(e+4ui^w7`SOD&^#SHh_5KvEi2aD)uPx7?vQ_RzH zP=2AFiPZr$-jpenUiSWnFT<(uxBMDJ=)*$k|2oJ{$3DJiifIWo}H4x><*mpQ4P$l_@EMplHuwxbs8>TnTxU_7gG&ISNvOSa6` zqZ^~;hnZK`AHY;T!>^gou*dIwKFj^~E>2r^b;?@G%U+E^T#t|X%FSfO(~3ubFdGKVm}~10Scfkb!em?B z^d`gs)`C+m>$c{T@TiRpwQke$Fi>Pzw*zGZS)?pfdt-NUwgECjidT@8`1w+Dvw*J* zTWSHaFuSZ%?7UF5vlUp$qO);O6nYp|Vj(<&a$6FNv{?0}y6|zKDrt1O0i^D9}Kkx9P@ky#~JW~;dC~2=d01*!n7&m zp6lD$YhiXx_zJ7NFXTAw{UZGV-V}c?#O8?63hN2L&O-Z}NJa`h8Xdh>2xcinC6B<* z1<@~^RM^pWp126&2__fJCbkAOe+Bv2fm=~uC=LD`0l4TwR%wctx6KL9IO(PkGA|F2 z>EnYd1ZKlI3svuh*@5QBEeqA;WIX*Xavh$~>%gax;dt`msWoyjp8DdcE#kvdDxTV* z)iiz$JR4{f6TXr}e{o8VYlVIZo91vRwZi*v*ws(r%&?ZiLU1sUU2*$AkhBprD2Cib zT^XwJkMl-C`rm%ST?g&x?cXt5?kyL5>mc7Z=6^R7$j7(m6I5XRTheURv=r*%AD}8Y z{8XjQf?BATzGo2t@(-8}Hn!yH`&>GUjpa5o^5sqV7+Yn*UiM@XjvQ)H1(?#DS=l19 zvUH(td)4X7_7JXwV?QVzD$upC{FAdFb{TKs-2f+=M73g7D5{L?O<~qaOz}jO=Y?YNVyAZ zCt@fdGQyk4O(dE@p?-@KT?ZSJ>;02F^bSR2Fr2rqV_os*2C3w%s@BAb0={X;{KBGI2v-5@Gh1BO};HU-Gm+{EZtONe3-bV+i2_7{Xh^*f@tICr-)%!?p?Bhc9 zO~{5ug2K^9ps`g`y=dx_@!9V{tTVwA^*pI)w&oqr67M|xDbd1MQc2T1b8U1eO-=LK zUdmq(9r*Q^fp9BEVpbd(VIg`j23#-f|FKMkdJ$SMBjMaT0~pYC0FZL!cw?XGg{;as z%0&hgafdFL176Yv1{w~zzvm(NfX6jULgsx9fdux4JolddKfWicPap4Bo2PdngE|80 zviig1JR+V-_?h4+fw5%=!IYOrdP9P|0kM_wU?EdCMJAdywxlqG-%4{ut`DWgA5D)= z8iY94$1za_=~k8ZI|oy(>Q;ActRGy6Yzj54rc~>rq@^u*hva@zDw80)v*vlhl%X!r zS^iQ_7d3#;Y_RKtSj;t6hqDtYT78>ungm;K4eHfq}ul5Y5E&a zVSDY3d68*y?C0WIW;Q5EvBKRgwv#r z%1Dfd4TLYD?SzH?BD;uF^%EZm&ZlKfN7FzoT`FANLxo$=?am6n-nGKVdaBStRS$VW zV!bg2Rg#nxc{MxO!Zsv^bq~@3b?KNdi>R^xmWrHJk9*Znm~LW#vmuwE5EQ`&plQlc zh1S_vTHe>o z?~C%gk-v~B|9v;5v7<)MbXAN^n~Caf1>0+{9?Rbi6XiKap6`<9De^pDp6AK)B6%*x zZ*<+0_(g+Wd&4sMwnBc(RGyqekGQJ5@Yb~>l}Ur+J@2u_2J-M4i=G^w4ly+LL> z<+J~PXS@8(|Ch5}_0s?KY+pKDX8YdDAW4Ik?l2*{3@;{B3eO{DXhXROi;e)wy||uG zHz6`|-#b1>oaC_p-0%fz)foK6G1MCj)mWH;sa1?mh1{T5GGJ#|KMSDFlH!^BqVGJAF_W)Ja`GLTiy^H21WHb{`vFi)sl`h$paT8wzVjsR`X@L9x)(VH&JaZqSr|n&bS+Zcf@P}slq>teFsv-X z{z4oO57VstsJ5})XmP=)u?5D-xH;k&;rFEx{uV^xirrmM-0~Kp8okr)(~a;7i;XEL zW;AsDt8Sl${R~pBiwlYw`BJ}-_;f8R9QX$5ipZtt!oaK({tb6wW+PrAJWxSh5^*R!##6Lc7Vz`vea-0)og z%f%4eMG9ea2st1OS5{5L-}qv0aotXg>I(!-qSagE=4jN5dUYuR2C7=sD-_QIzE;~N zc0E6$()N2!*6$*#f5WW=)?W5)G-bqrp)Vhr*aKE`PFIGIVU6JT)@?{o-M~OU3&Qdq zoSrg{O9<^P z;_FO{7@S_?EioTlME0(aV(y&h(Y46<`fS1Zx7== zGPHO|Gob2`42**Ejrd?M5SG1tGd@xl83{x!_6G|@=aMD(hz^gATATtT!tEfDI8>F? z_C%Is#bdWalYj{S=yIeM1YwoB*)e-mzZy$!4yG#LVI$3$Q*nRDt;LQJ14-KoqM`Hp zkkvK`pnrvNd7*KA7_zMbC!1K?GeLdXLqDaIcuRDYlCgA@iuF>biE1Q)_YXi8q4t{y z6#snzCDo2GK$p-5Syc|h*42bmU>eR$k=jJ;0P(O}{|YS09|h&y9KRW}=S2$`ix(G( zG(jT3n{hZ|Oa?%ZU|?w%Vue7{a5aA}q(Jv(PL4o39IRp^4dA<>ZVKqwB?<v0yBMO^4R)jK2aieBd`+Jp&5M~Io&svZLEcHbJ)J z7)xD;Eujv*N(ew7_1=vzuVVFxE7Yy}lu*h{p~^9f;u84dw2mpvBUcEdN$X2vJ@o`9 z01lZotBGL&+wd(q)fL2vN{{NZ7ve(;$TWlpoJw1odgqP^vDbXA9`+|~h*c9go7EPy zck-~;KZSR5?24>5sC+iykrem%%Yd^_z?wVag}LP+y=KJectHUI6VQ#5#_n+AbQYV0 zzXY4uHy&WHHm2J{k! zxn2yg0K_t6S+)APd8EzeRSeG!k`3NyK}@V>Ki5u^u3^|{CBmY3U* zfX+H{oS%bfSGjd6aLlSsv8qz+btD90y$pw-g!DXp!d^`tL9OPup?J%YH>R!plgm{L zBAtB0%Dq^?6=DMos~6pZfH|+ZTsf|A-lEmm5U4&PN93V)>tmMac22n1Kz$Td(1axdUXgjEP z+?C9|J5c4;(z4l+Xaz#Zk1;puS+=LviK*&p?rL`(B8@ydA35RovaT3^bw78hDqn*{QK=XUiWkPg zuc;n*{se>y%1twhV(-WtDCM?goC7-8FPHXU2n1Ey%QzVzf{gEAj{r$Wu+>CqIvcBr zs5pt9u5HC=R5|-q7+(wx>` z6~XNiLQRmah94}@$5yt-K~MY2A46IYDmfO5=B^0E3-p(plYmmnfJ-YN2k=A?VD$~^ z!TVVYo`7q>8kE2`k<5sLHSwGgBVGUF)g)KbrR;bAje|jNGm6vz)3u=9vJoOvnCFE0 zIKBV#_eB3J5Q?lD(5$#5F*=;<}x*{AUizh}n7|h9gK8sJz-pw+; zCsOgNvenKi&S8SF0*+EUNl;t0V<3O)uxf+XeNRConY~;8NX%nOt^xc*w9yY2~dTD)O_Xr@q*p(%XH`9 zu>)HTQx#500`=#1RJDK0p|w*IU@5#Jm_HXg;c6 zDAk8&nd*VX?}pA|?Hg=8;9oNj2X**1zvAD>O;+V-AR13(l%9YAP-1_?Y!Mu5)Xz<`;#$5f!6fwv-CiZfh?adsbz zN9y8{C-Q$xB|f{tdgy+Fz&yDbLPPZape`9nDhpmc&%oT zQEw_VT7kUWZ=54t|I!&C3BJ4Z29(ziouSL+)~KSuMz!Zf6=gYj>J}_XXk2K1d^^`z zP0Jy|2ivp7fu5uBf*k1!Vq`JL>3TzbU>O;XQ}zS~{}T*e_eUG-4*=mTVqvQESJl*8 z(Hm8=8QfK(#@wy({9Dx@d3>MGbZ<3GH+tYO-Q*Hr+P(G!!QWv)PDM+$ag^jhZYG^D zfVaZyoIB87ASXPJb#HQ+H6&l z&&MVe*B?x74-EZy9Wu2t8cQ&!)@??S=*}|ystc=|F3$_HjYI?Lmn%5wi48?O0%U=j zIq0s*)HT3vODMA1^S*^cN_c!gM6{%iJ;%Pl3QfT#(SK+oRVF~Qkw8=H*Kp8NZLJ9@*n?e6z7b2=ssw%I3jn0~`mseq z_lC#om*DZ0pgzaMBkNV5jDc%O;^Z(wF4&SAP-&OeB2VZ8&oYkH#-=<1MBv4&cUA8C z@u7@`_KY{~&CkcI*}2;gk2bnG2+)Q>QeaC>V9Q8M3|93CkM01_f3PgJ=ZO~aW-u8nL~MS!l2 zq4_g2S8pSRKp6KiH|kN(^R(S;dv1(A>Olc3mV_%)0l+7eR3(dO)-AFgL*i;e4c@ua zu=>A!8hvQ-Z&-|K5%M?C2q7@eCE-k!@VovEi_ACpJEkzi$-yr5?j#3$52D&*pK+5B zJY*x!@ep40_fS1|`HFHJx-MAb8_A!Vk!q|Hp^|vlxXXgCv{&8=-HPG@1AxmEbZHAYNBo!(8J^0fjp_e3}Ml43pl0#^fj$qpb zi;uBuqofI}4NU%Ia11$I%)p`*_w&fAPm&{RcRehzdpxDV~#iFnrdj|JCl49S1n?%9Ix3U0u?|YFa8f9A4 zqR2E4Gct*GcaWF*%C19GE0<@aeF!KY6rDV(cs;-@sGnQZCXq=Z*Qv=Pl+*~b_;@*+ zh;3rP0{?0b7m>E0TOiNhbR+OmK~%8`efLA?*ZGbc@N@#(78GxR_}~#R#&lBjpI?Si zYH0SXh4vEx=EwuW6qsKl+bv#j z^!=2q**!tEYa&_nqo@?BEQif~-%PiuMt_U~wC%lN0_vBUP*HX#!Np(1bZHB7$AM*I zLZ0{-jI*_y^W%z4w{{aIT;Zu^L4h>JMau~oL1)=+fCG~Oiy`Pv+vE{RFqU+_E&G0t zONzL!*r%W)Zte<~*Agx*fy*}QRcRH1r5%JGxR2nMb1b}rz>9%yr!V@o$IuI}9pxZM z7sQs;yVa2&HyUEhdxQA zP;Pf~DUw7`1kyjVyv|hl%I`$=;H8H97pI0V^KTa&F{CO8=zOkFWwMHLp4B*XLiQep zSPn3X%3DzX=>f>@T4-dMrt9zflFsrk;7`^8h<Q<5YYVlAxjkj+{7)LsOY z!XSidSQUsx1XdD=94JFTK!9zsu0>|2^QJ$(^2f0;t=)u3#JTUe>s?&$ZQ0{yE^4If zm;qNT&^8Xxa0_7O`fjtj;Jg1~Rv{^+DYjXBC5vVjWHMl&JelGquweTL{#}MdfhhMW z&aQNxu2c(je3!Ee2FZe@3-vuW0auA`;wtFj4C;=`CP&OX%E}0gUFzk6Iq(2% z{eU1TG{(j1BEZKlmz>ieCE5$V@VfTu(_v64Zk!Y1Im>9c5NO{C#|lPMfK>_N744re zB1zwZqyn{K1yX19uW*m7L^@ z?Cm0+-%eeDy`3bLy`4&1{qo%Q`009kI~6>(Xvc?E+1shFu+&!k#&aw+oqrJm9)BF| zEvmzdy`B7{thBFw@h?2`mcch`e}OIH8GAcPSzS5D z=qxVLAHv=`!Mml}H*rSoN;9lwpq}mRVf+R$8TgYJ3fW(K`)E{z4;1EO((!`nmS0NB zYOG@X0#J}TU$T?ZL3~X4oh|uDGGd|Rmo%oSelBX3q%rbKo*I)Xzjw)Rjuc*u{y5h- zeHEobkv^orUc!5~Ee?3^u*3c8!d^p%c0)@}Nk@_1&HdmjtW8kKQC$y+0);c<++a=6 zrK?+ldKW&!I15{LO6R%xBfgVl>ZZd&2i#&>0J#Njkls)YbJ|3lJ=dpRUNi9(bX(Se zxpVw$?t(5vN|B0|y>@km_KrSC)%n!tezv)cm^UI^i% zQBzwa)h{+U5>D(I>IKw(31(Ci)L$zGHF+XD;PeOT(9pKwrwepCQm|FU^TbRatTfQo z$oPb=6xT_d8vzxg#ib~b%l)DprTUe7484V-!_jv$A{i`kg*i#MYo>`CgI6zyVJwQ@ zp!RTtKz&!B2{?(tYsMJ!8V9`urScwbCuiVvc9Tw^hZ##luBiH;4c=bx1NDM)0~P>K z_3l^I^bjhoptcCg$v}&K;67R8OA_O`Affy9GE)vC8~3CZUB|7X>TR_cO9NYSAp^$& zTCTAwwqc~M@MX4If^W8>BFlVNE2{9tww5s^O9fi;tlH7)S4L+QOqioM)b9ag1rRR( zJ8?2rX$6rNOkeQ}n-TeITQgD9E4AGH)@(eA^3$mK{sRvBC9X6!N4dpOunmmw6q#`?LcYC^V@dRE)_*chExu%Y^eRsVq26|r>4Z{w`JS?)Ig z^Eu#dQ7v6vU@kmZFpV4*sELd5ZDw2+5{B$HB6zfY4g7u&3kRDOwI&r)1<1eAzkXvs z5d7Ej;>%k7dq4Lx4WSd;8Ijt4B!sGL5D>HM9AkcyUnb0nj^fQd+yhI zejV*d@5gn1jSO-n7AOHD|HN`N%5tgxos#etbeg(j6W+kBC=@|CZ^ z%m7H20nIKkGlXt_5A6I~WakU?9>krJuHT#Z3bT*D$ND2jf&Q_4L|D(k^ROU6eF7mt zvRlG8B(fszOhPX3n8{jCb>X~o2}RkIz}*)yJ|B#N5tMFT$ABo~KdOI0cY(yI^Y1a9 zIygJt=ddX-6gNT`8-T904l2DwTNde;Fo zagAzLlPbXjI9LR9KdRqkoOb$^T+CTnf6lBl-N^(2Z#o#>$~R2R;;!{_Gcz=_7>T@h zJRWZv%xu+`zS>ttDL0i+_wwi39{WY|{ZAyVkLp`~+7@qmAJ3r+;)B;i7rxN<>r+0T z(Y(WLDpSG8V+9o_4<~?s2;#-BF2%dDPmt^f3kD} zPUWD0s#RiQA3p!f)gZ;UbKi!Sp~e66S1`kSBM&LXBv_t}(Ek8q9-F5kjrja9KFdsA zEz&C}&0az9IA9X6dAQStbJC?}`+{v1YVY%{(xkMdU23Thk z2iNo_QUN;%$Bu`D^acz}Ps?qUXh6fibLRFq8nAm=+-d>F#+uY zoS85!eeU#`DX|;WqdM`C>NW(e$J{eh-vM0Hd@#)6eJ>VmTqf(dNrB=>NcV*+{P{sqXx ziC17u=5UOE5}61JE&3Mu4^VQTW{je|-LGMED znWm5AO@+u{1>s5TpRele*)$|yq_6xH)`KR*3keeemv?6(h7+@P)8FER#Uk{xL}QDq7Gu0;ASyme-AZ21 zlH4^Nd(e~|LN?kcLd_-3oY@%eMP*m8bL0=g8oNS4V|kr0j+6LT=CT|0iC;wikvpun zWT%C5@(bZ$p6c5Jmf*7&D3M(9+^o}Qh#g9=^zDpCR}r+TKlXuyrfb}VFbFki)T(?m z_dfJ05vsvz?iys6E`>Pe_4GEJBK6U?$dVS)hBF6KZ%loCO#tez=Tm6`4-bo7Sm+SXI6l6fL+5t=-Md-Yi9*=(*@n>n#>_ zh5MX7G4w=q!hqNi^KbzUX#jvkHh*~p9ao&I0q<($1`zJW+GWZPh5dSeTz_5S9RRso zi8nPeR0lGsU4h4bi8n3$34SjK$MEY5|F`akNCUAy(Y=LXW^iL`JUo5na_?ziWcbNp zRaX(fgRy}~Y-8e;4#$^T8 zM}!#UFY5OnG$DDdJro4hNsyd%U|&w$bar_f+&bA zDJ+&D0m+I7;T2WV4hPBv+1hUUITFMT45Urh;}N7LHpMtS8182NinHv*WqOqFbi8;K z?2UmxX#EI7yU*Y`WXnBB`XfBX#E8I+cY8Km!ri8#mJjlsdV!Kkcn0BZD=6XE-3X29oy9zwVL7H8*C zeee=ftegD{icx1s$&zpF8WaO03MtP^H9Bt8koeB4DR@GlpW8`oe2qVY@e@H{h4#$V ztRQngeMqhcZHN~b;JfkO9=nVt_#NMyV*?W3oB6#J0KmS6r6E58rcfNDfPlw^uc{lZiBUR-$0C6aP%{_(pFd7te>+3_>X2mQ`TwB#Z?<1^LkbR?!0m`e2?b zX@o=GM+~Ejnbg%*>9-%1ZtG*{GH;PBk-x{Bf$Hk(5Hxw@pTY79AW}=oGpHw+qDI>b zOWx~fyzDDObRJTizH-{{qGPyz#ehj-L$#Qt8AMvEH)j&3X=OL3i6fj#+x3s5voTR6}D#f zr|mW(h@A+uA1`V@4u`J(wDLZY!r$@(OMBI)xE9QG;ah#Ay&CO$Ti>~uG~beI;u=lccPj+{+0 z_UXvcjV|n#gYszHcFD%u-MG9rv;bK&X zVwEp6dK%;lHLJM<=m5wVwh=}@a!o%Fa%>NU#>vJ5ar2c}?{efsWn9NavN>AC&>k?6 z^%74WT+!zUTf1EK3kz_DF$POvqOVWMh*px2fE}KR%wCw0eK33>HeV`lO!DeyA+>87 zjHcw0rEbWW94%z-r$WP^MdVf0z9C{$QxiBvzcO_+bkWS9?D|u|P_q8*CLj(Vw6_eA zUynE=0WNj-g=|2jz$-2Kk66F*s#3THl&1TBu|HEpx6hsaQbii9s-&d|iwX%GLaPVr z!OmD`dO!AXd_=VB*i_fuu@RHu_JhL!Wcn55@uio;9c?Ir{q@f*X^DB=_<=DSE`VBk z5@h`e)t)UqLfk2AtGeHQ4&AiO2n0nYSTnAw2i3m4UY3+pJLvU8x@Lbo&U>6BW=+)z zgT9}ffDTN;zasp*AO9Y3{@sDUv+$3^27>VZ@CD4pTFUUi9NZwx!L`;~6yCcc8Nfv< zC%vp{DHsDi;1kd&{kOQoo-H}y6y0y2oSw3<$|k>$3Sf-s{q@Iq#yX_9(!gTY4XsMy z9WCajQwn-1f25I#!GR7tZe$dl2#YH!;wUilgUB7N=fZbkIn`0XRnt2-;Dz9j@Dz;X zvg%0=r7C=h%-A3VVJPkm*+KkQ+mLQNt5zZi2+&ldG`dO z`(tJEHcWdLaVT!>j;W=fjLtuu11nVslDnP1# zz)PVLvux0qH}D9el~u>g8b;!x1obzdrhFb6!Q4Z074uSK$#-K6#+#uCj-soJoQfOO zU8E5teT`U)(a;a(AfU`Jd5u_ltV>!num;x0iOa%b1H_H8AT%1+;1YLWxZMaQ0>UA? zoI%C(sE+`vkp>7Aa^RKSsGj1HZ2VSlxw?uG1BZEyvN;FwweQ!8kC|A z%3WpcW*JvF-7cTa!f$8F-^~5lwaZ4R+E|7#u|{XX7mvRjsW)u-}&+A)$hnomfd&81B5s2!|C zx&Y*SD*J7esFv6Lw#60|hAKKW^%SeNcPv7F`x%x3QoY@8QTGfYu5n<#D+; z1N6Htw;HX29y5JitFT_>0{@0YVaYCK4NCiU^KLST&DZ*B|mtW$3Y9`Xm zNMosPqo$S7Tb0vUC_E~ZWqhB_B!+sqTg-cOP#^^v-0zvvO-J!!?IuWr*rJqD?IxsI zZ}&y8%@TN*x0sC4)Y~(w-TUDf3sNLH8F!krM=L2bAXA#yEX$*nf_&oO_?Bn5BHxFx z4}{v=XpGTy#=(Cl6(qECy-NzD-c({Ub=ELck``zUNyl@1T%?7^4U5#CMFtfJXH)e-Jy}MdT zNv=Yq`BnEjrZZd$v$5f_Sve6Mb4B`CugdB&7%CswRd^-i5B5lZ^e;*TAok0YtWRV> zgiFUzv2X9@7y1P_w`)KFy%^=Xt|Xb7AxMiGpB7wwl=qK#D0xoieqY&fP6|l(vNGqP z92C9Nwz-clbILrGGjp7~y2c_!g*65&3SxpSI%+lB9Qsa~91J?Q5vC9LkX`Lty8*dv z#kbg{nNiN30?#E0*|omt3VxQ%)+Sc&ianI5`zemzv=H`Y-Z|TS=XCJ)<7a1%pAOS< zsX>jOX}Xw`dFQ-D{~+^qx&)sKnZk}?xTnm_6r4BCSQOZT!>k2cad>V`xUpCZDtHbs zZh^I+)}{CDPuNeK@6v<&j?fxtn|1GDU{Lz`%62h9nzhTPW4N6ASCM8_yn$bAU+M}H z>z`iCyS9z5O@bjwdEl6PKMaop zhcovpMctl(2n_NLo!KUL_2ndNT@R}$XBGS|j9$qazp58~3#0GWaa4KORCx@-2kELZ z$FG3R>3Uq{2!UIbC-ws++Xpnp<2-cEMS<9SMaEMLf;}aB5Ml{f>6(^5op*lAxvlOa zw4!d#Jc3rDo*Nxte|uR!;E5x5m{$ZcP$doUC^qMT(|cSnS<(>h9lbjVbzJD+hHwhr zQDbLeT$5@Fz|IJJCX$+cwB%yDQZ`xN?1QEKZJ{`v9c5K65fpO+Xyeh@hKK88ZK9Qr zD|QJIhf1P5GQdg1os9gZ%;~+G2erEv$$VH5)6G`4j_!ILOqVu_c^s&~@TC zsuBMb0$}$e$@2|4l8AH#l%;lhg*H2_@?v!hQ6km0V<^pw)k)iS%JGDS;y(KYflhJ! z))^0MKAHQB+gJ81(*v!9HTd-KIxnFzQ$gK9vT7~Z=aK^@8raw6L!=f}+E=j-CkRIhrmGw=0#UJ3gV2{y8)3vtH{f7p{_25$^tNzf&(ko z7eCgkoLyKp66b>;RJeimV5Xb^2o{@R$@I9uRvF~z{?dL*s8~sl&Br}&nUzdPEQF-j zSX@8p@_2amsiWqw0z3-Q0J3tE2!At=f^^7ickh-nt)$hQg;CD{99__k+;>DR zcY|{--wIOrpB?$`nj{0CGfpX??6W^D@j26^J~h*%40Pe%JRcQ0hfJ1Jwph@zUXV* zIuVJX-LFU@hx>(w6y5`)>v$eKqoam{BAz>qYYGbQF+3eEAU}vpVMWGp|EadPw1c`Y zH!KB#v$3lp7`&roVMi!6@|9(yMsg5Y_?vLd^_3AF_@^!Ml?`KZCFSrqcBp*qbevO< zE}~OdZk3(8&(4L%+hGI_F+oF&S5x9(l9mv|6o*{(l$Zx+9`vfs46oFx0(G?43eb+4+L63DVQwl9PzdCa3pBV)-2@0!L5Oos@SMeSf`)#DWEvtkQ%p>t5|S8H zM$J+Wwv-Sqadx2&C~8&`^R83DLAUP3==q%QQREe-Usx(>%Qv(<}-vhXsT{)4^%Z ziDr!59UH*NGDt3ABj0T`c<#z-+zR@?D{ld*w*>XM(@1NCcdsLU>@xKfG!2#@e~0vf zLpbRe(sK|^WlwQlyX2%0cCXHx4DBD}Wz;dO6oPQgi>Q+8_sTr5J_Xq8pKKDNyQ^_W zbj>Q#$f(I&2Vyl(>?WIHBwFF~ePvf-`TTN@fgvI>6(7{Jf&uE3lJm0{ePnR$(SK#$TENF&rqABbkt2^G4RjOiITf zPm46bmF^FS1auK9g)=!M*B3@1gB_u6h5#*;lpj>TGRImm)(D%1E;3QY1^`sRo+Y(* z$zi*s4vrn&+56l#B?DyJ?ktgQkAQ4DL#ZH&Lc(1WsN-vo6Co#+uA{XMKO5;E#xzj5|WH$5wE z`F?n8SC|Eq8m)CcP*Qv+$pYiAwhXbd5?5RP6&+Q+0`+<~XaicxYE!iZI%`uq3@P*j zv&on1Jx7vUvn2W!rWG+wfyM2eJb%Cv_4PmGfmr*V8T`Vq37u)*M4FN?Q;7eHUMLAL z<%FREdTnJ|m(2!4tDSkLt>^Ch*rZm`8*>NO%h&7}bPDu#FC93Uy-y zw&BYl-I*{wh)DLfGjdoe5 zdK3iHuqy_YiB8;bUAYSOk+`Xuu2phfusO`lSbb%EiHZVM*HPRb9x_G5G0U)6CKu-* zwnH6)mI!Gs{oCKQIU&M8PT&}+!%PP1aGa>z_UM?!YQ`})gtf-LqnE1Ad>hQ;+dOzG z>G+V{jyT*$Ap&r6crp(PbD7%$pD%oe2FaVfe|dj|_=2A>PpQm+&bBC!j=&bbFI-B|=NI`AEdTYD5st z8EzU6$0q0y1PmrwC8vNC>%)tq60QVb(9c@RJA(9)Jb;>nF6olE3yE^9oI4(&PuqEV z3PhPA8LX!meh}DdhjjjXK%2OGcb}e=4wDhF83TGv=t#m>stZBDV@6%-m)-CPrpww$ z&;=MlyXV;Z%&sE-3XQG!4GkoIy&nb=xTCXPy-XBE)6!mqyB8==hU-2PKI0nT&<(uF zz`ubi0YEBggrm7_j1Q{ql3J)faTTI2KwJmN9|L&zl~tl-p$Rivj*wIcvLg)fpnRC9 z&xBzO!?Ep4At@L80d6#7%-JHz*U*{obYg94;kt1U^c-&$)3LGb;Q0{2)X^5W-15 z_mm2}2@F7iXLBZGo;VyCT?kQLXoUjk<#E@6Zwb-;fU>SZb8eVcFec4ek%7E^_MCi8 zQTFTgF<2cci_tmQFE~1IR1*uURa`-pGs@CwL49fnB=Wd~1Gtn5z-Vqm=xSa1a|q_C z?u8G^u|icLZ8#TTXh?um9pAiqlOl?!_uT%YA68ZZq&YvC?$l%VJ6rJL;~*LjvRyGMm=u(0f|E{ zK_miBbl=D|w)6$p6Gg5H4T2%-vfX&#YHq^a-dAyqB!fh% zm|$!=X(Dnp;0la<+zH_Fp!Ygg1rh+qTX3WSjB7L1V)C)cr6+u4@aw{q_$ycYK2S!I86|s_2zEcju z^71DAf@~&X9D&QNm~LcLzH+)OL<3JC(yh>hPuP(s?a0$M!rll?=)Z|@7D3z}taC%q zQSL=ffsBKZfRML@H2KUyp!_!c*=k4L05nu2pn+rCidIbkXkXb)+}lD#7}CM0>TFp+ z9RCg_zvhlERD_cjMj9jmHKMc_2ATmf96PWP;v33tdf4O6O4uSZtyw`U3c#Ezd;`Ti zvcqMoh$tbmrkGVaGKkC?JiHi>Y{dQGu`4Ss;}^$P!O7j3kuWS|%oo@`(a7QG?q$GK ziTK8e=||f@Bgp)YX&;P0eEzk_9BwZZ`@zuM6Hxb5y z3t=Mcj!dvh(hxMTC#Vq5nBl5llvl^Yz|^5PHUcub9#OGg)-^Or24XM5mFmDj;ABg@ zUEA{aC@GQpFG6?&^*ZGI4y{#pW70;8n)W{g;znCL|Xi%t>J<3M_Umi?P+thT9NIB zV{Lpgsh8dH*0`#Pjqgdki1P%kj8I<8PkxvAVUIe-lG_4`i*CAlKqUwy+&JIYWiH-! z;u|@uk&SyM6LE3KC_7(;yS{GGvIwuFim}KmBywmZY#B>5D3{IeKS*@knnd7z1a)uC$jl3JX1qHMIMZx^hfT42=QU(bNXnpAGMhb}uPpU&;9UC|4 z;wCfP?1U&G;|7sW8kerB9jP*NwfxIm$N#3@VS54Z$$RjB+R1y;Pu`n>yV;WL@gos^ zMCGR0<45srG-HvBAEVxOE<58L$5~aOzA(D3>2(SXMW?0VQg_^4$Xh>WV15wQN~FBF zo#i7ie9mp^1wGx)Vrq!_bOyqahQc)- zh~3)JhC{3XO}Eb9gw=!2mgPAeI?}y-qV)gh-Z{>?9)k+xN|cUE%d3-cB}$(V?wwmV z_bcz6`=8!zC!MT&<=i%kI@-wm>NaSYsz9uF@7|TB=%@nSGN=0uFA@U*h!uV_M&b^p z#F3``0D%#+PC&Tj!S!N@+?P=ZLZZhn={7wAF$P3a|gwGVDHOVg?4xMmFoo-lJ2h&PBI zJMlQ;*F56Y#Ud8*MwduDGTfI3lEq^u#oYD;&)hlo1g{`=92Qpduuf_fB)zqKn9Jy3WjtT``jx@rOwT?5^7FmzS!+4x?A5PM&-_F%}zi>pkR`Xq*orRDizktp^ z0Z{Zb_@N_3Gnj4Yf;zN7I`_BWPy(&~qUOjDtiV8jQA?!1zo;EI54dMGEyGzQvNuRg z^ofARjTE&fiyBS_8caV=rmP9!TCRYOj`KDgP%X#;;Rtdxc_z4S7rz^#>aQwK4Ze7{HAig`5!1b^ln$k9BI?X!CJkN68NkA3xLp`a9+1iIagh z)VML{WjJ&kmA{D$e>fR<^Y{Us1zJNznvWlJw?K#ly4N19FK1diRgQlJ7eaIAsQZa$I^MJ^e(WK9QJ_NOW6=lGNS=sr3E-BB>9qfsh;v^* zTH@)q=x07_HJ2mjw(OxvUZEb|-WrFGTnn@%6?_B*R}jAi3=Vc*h*Xmv`+FgnipPF7 z6Au1Aodq9B#wNI+IBnuABs}LNMAAboELepNVJ#oyD)nwjig>IC#^7vd(Tmzz5kU!k zG0Ie&WT;|*5H~y+oxVGVqPk-cum(Jva0jSY_3@{Ldm-My-;H6tppGtKZMYj%k(cM( z0Xw&uRw%ix@TBoi^F;dQVMmkuj19*aoActM9clhF4|lBYGY&KP1^7p9A(GE(uMp6) zerBMeVjGTKo0i$E4z5jied5 z8oaqu^-wT%a3IA;O!PXSSUfoq^J@b2a+>_x3z+BqM6CJ`+l;FrrU}PBE)vE0KE+c+ z`3aJ&3>WXrlvfN}uFOos1)S-L3pm>sfUa>a;7qrwb@vN6)6E5((|C8sHJ}-A6DMgB z2(41>Bvs8zIhT6vrT9&=m*TEXLX-aNT0_-X&7(RIVOAB1*+Po8&UBNq=wK~4(UN9Y zc@tk05g9RI4XX|`v z$USx<&~UPdSxy#sWz$RcNx+EpCkxVm>IQXGQh)e^kB%QWIma7IK6zYC0xEHW=k3J6>+O`0BZ1OnWI~_bZ~0$(G-GK7$`@`%&XXaWsoOi~Dx=j;7uM#d-9x_t^KMIb5tSc0+dc zatJ@0eS0P)oAee*Z!zgDNcWiZR!MI)>8(h2>S>qsc9TvU69{pv{a&lat33en(EM51 zC1)R90|DHGRK!~CAPcZl#-VChC#B(5QZMc|E`Jw>T1U={+*q%)`RQwh3M^p9Z_XC_C^~45%X`bYTiNjeqneh7F$lqfAe0|Tis4oR- z9c94+5N?DC^FMAs2*C^WVdO_Tl*}42b>ei~KIUBFX?7Gg88(${G2qR6x!Kp^U@$jK zj`$r&B~qrnj{)K7Co+jk*KOsZOloPB`yupWCXq~wzR@Hm>-$Y&1rvuMkzTh9_vqHN zh5%OZ?Zp1Z7T8aksYW+$6(7n(4^lgN@Z)zOYR7e=Y@a@*eY$jE@5fFTTE8a!k}mw* zBqr-WnndZsb4Y|IqjaE>q#fNFr<$f8MAN+R@wxwxwReG!s=E6AC&?rXFfdUAqEHC} z76mLeXo-Ougd|i6Oo${40jGyiT5Y9$tYWp5TAw~xQQ|#-HBb=H zQX54rTBtc~6UAkLoE z=7Y;PKp-%y<8H-AP!x1{HJiKCotMlT;9v1lw+?qf1FC#UcA9VaqKwnYCnf%D&aq3h zXRJQ4*PO>RJ8N#|1(2wWksAm<>fE8(P?p9Pb=i(ecYm;VT2|dXtGm7CTd#CuW84Ie z$tO2b%AFOn(02aNfdi?@e`4bgY z=B0lz)obf{N*uT0`A8z2-EKgwAQ@y%_B#_T6VDr`4i*dT}jfZ^1n9Rp$}8IqaPhmt19tnW{E&*4%@eYa>Q9Q`#r zp~T-|ej}Gbd#F3bgMwxyqHNJEeHyF#OeILCQXcBgOA^g+0NPV*K`&$sa>&m*N-u*O?+D#ECpA60vf@&q+j*YPbBQyEz zG``h=gYC&iYMFa3z^U|MUBb^49GhKuzcjqHXNao(DjcA*+OF7u(xR<;vGV;&^OFm; zwAe`4#eIyYaqn4}CKkOExXprwUCx4Cb~W8~hfHwRs=my>nrb5=aCd3bw-iO%Z@Lje zpr~zmjSC$kUjjH-{72h?40rKg%>6%Gf2`e{-Bsr2zzEQlbHOIvI~?;+_{l{S|TY6anTa;taT~_Qj2oD?XJBh{ zY>j&5zH*Am)vImSyhhSKFa!JH!~fWj8W4Ub2D{KANU0f%2!88oN>mx=b-~t7t|dlT zdp8#%AlKf@1wyTyvHUjM_4nDU{rpwiv9$;6-xmA#P5zoad)%(p-KlQKnneWZTB+|` z>Qi`d!Ca{dBboDe$nPbzOdDD(kv8=4miYu*ZPDyoh<4G)Hq%#~JVfvcY2;UE z#6isy2fdizwEnp5U_L#I`0b;e>k(8;#CS5d29aI988+n@`K_7)9&;vF=DMjgf>QQm zPpMST1;-`6W;;TSwR!DB{JoO3VNXA+Qc>Rh(!uxo4#@1Nq$v5n_g6Qkfb*SLQnU{YB$9SN%bXQ9_ry!g08< zo#x3t6t=5q>Q)0no~ z>P;Z8!5rgu&F#{8ih-!*A^6Pc3v;VYEA)!H`0+beQ?ugNDiH2xR$=|Z$z{G-j^=ZD zeruGMeZ&CAY%^va@9Q2G_$3vhug&zMAcsdb8O+4QF8shL3(5U|mmm)WvrRynGj(tL(BAidR6lO8l9FffN^e-x?&ftTq^d-HcR zUNJ>^3WDEq^Aw=XuiK`x+FVhr0Qh0A_V2OIzAMVUkfy3vmwWy%>vpX%z6=#ZfK`!&as$1Qop1QMy}6AE`0b=s}yUm>ol z(~^I8XG>Iqyy4+d()<%H>P=ZK5ayOBx5R{`F^;u7zUItpFPvuraT|KTHJqK-HgcY+ z>5n2KXsv!(vqK!_1%$mGq0?Ptk2-2aOxS85*aSbjrY82IU+1F^;gojO^sA^CxdUYf zqEDG0shMcAH=4}7>2V1_ZBr=|4>yVU-kSbYaOH8q>gsA!_8Ux(GKuoC*G#Sw9wNk5 z;qwAp*VC=*u*AvIU{@WAtvZYewA(jjLExE8xVyVYQY|Y}&oDQv1s)XIzlA8~eBeVt3LDn^U=uC^wX?$c zeB{Yrb$s(w-ts!MnwjCnPzv$$?<*8Hh%=E7!>%JCBZMScFZTDRruKTfk;q|G+*&HE zQI=nr6ArM#I=TvT0uATuX{j&!6&j7U_YAC6^3&w7hJOv3Y9qOI!(`wZhLwM;cwuhj z%xI&gmf71KbL8&(H4Ej>QDNV z>qjPOEyk76XT&qH6@I{9*Cx^>Fgzftpi6)}`Vot6Q!s|Fb(TXMoPe;L%K;4}1l||a zMWz*&4hnxu1N(wQ^aAIWd{pE$i*$~@PX(Q$C@((HrHy*8jGOK`imdaUWO9MdGg%L& zXOr^`v>8=r$=z*#6TTo^3SXrIRkVtBs+Fb;tP%5}BScc^ z+;DI1T(UiKVZpKF*e9k!7<5)?scB<_b}7zXs(4;$^fT{GFSEu+uzk1d;{zuyq-kJ1 zRY)}Oi)?RpC4oxa)@^VRXY-)0;{(bQ&oThmuitI@WK`O;rv3ok-`JqeU#795cY$p zEDfz=TWK+xkq2}f|FSqwF9w}G-m+jIaYHrd>4P27>akL9hEwa0e6uE-5VF2xKQE?9 za(jzpn=|uCTVfyjIv-}+hyDDWPd^R}v zZuzcV;ZrJ7{9(z7=teygGv;&t9owLr=rnIetk!QS8cPxY5ay@L1T!gJoh3`Et3X`0 z@fcYCZWkVO9ZQF(H_ffiC#XVXMw+WgZ&Ip_r<7ROF12r`HZz_U+yWJrE%UXSkC-Rj zqQ)$xD7q5K_bF-AA+!FS|A_8qExsbmqsQjFF(+WF>hZq5mNWZWB6@_sMp@LF=2VI+ zB7b>{Q~?klCi}1dk;2nV@*XMEt`LAs16)g;wNDf?<>hdLX@GeBCsIYTG>))B{ zF^3oneloMPAWpr!)LrrynoZ%Y4W z2XwavRHx}q4M>gr|1+S`1qWdWzjQ>oCyyvEv_vDi^hYV^)bbn}5_uE&ORWj!ohI128|ZkS{eXM70HTY(V(s0mtBvw4QHCr z{3k9YuVOPvF$(jJZDwZlyZ($=MJ}i8cWK{BtGqoy+KnqxA}zijt;Ndt{2G6Uk;Pq; zJB=*-(QQY&8(H{WBMWRRe6eY{bOGhEHRZs(BD&D$MrNi}@etGUIAUY9xv^Sbtk!F; zqv2RBh8Lm^=q07-=olxnsLG2AY^fJJ*2^%db1wB3Rr&P9$CF+ls~H?SXQz*yOMQ$0 z$)F5GnTIde#4BN-)x_tj23p`gYdAsTcciqyoPzObzUG`Qf}v8c`Qg)~P-Q>Hrwyv< zW$yeiTN>LDly(`K|Glo(ZOZ%t7K;um)E7;e>uIV*9zN+Qp-LxV3NBQ@^55kE+2k9+E$`oK;uu)y)r z3mLD;{?3Om#mdWG94o@q0(ta^UlE0{ygS}fIj|`{drfnydSc?SCh ziN2;}m4X$V_5}$stwGGoWP#mn{NGI`A-vHx-lZ8I7zZ~(8U*TBacbGaw9TBukr*;Z zXK~-AL-2%|KLJ8P0?l(mn|g3`KlU19N5ZHhTf)=}sEm;6stsA5)}dU7PPnzr@Xm@p z#%oq|R>V3aP%mLS6?c7ix*P%gJeDPUxWPJLI`+!`gF{Q`iD^BM9%E1T>-Bu? zZy#VUb5*Di2(aJp6#*uBhpGBO$BwS3aJE%~s1#&omalL{ZtVp4n%$-~6T_Hsp73zpyvdCt z9ShCoIr5C{;#aA#(FnQAidN*V{QdltH&F1|EZqI=?y9i(g#821N4E_!BR>#n8Xn}# zJOS$Kht|%y%!e6VNv<%TL?i0rE?3QNt^eR#A)AIGr(K>~J1AaeHBeJ*pJ*ss;p+pX zMay$nk{8ADnqEuP9|gs_CKKY+KHoylm$smfSH-9M%wMtFPL2s}{0hFw+ujAuw6Hl3 zhTpJxY!0{sBg8JaW1mG4;2+ZyRAwvxiprSbMDw8|4nPs3)+KGj7r3R0#KCxAulabX zWl+zKt~%ja1|I-lcOtY>(y9(VK!T$=qDmu~E;_gQ;hw);=)5M+-1e#kGhAZuhDpJ| zQ}2PX+U2@SFlliL<}T73^NV4Q{x0{LdtR5pIQDfc2fC)Nt1IT4+!34-gG?fk?TL*u zXYe(5bt({R`6apDYZeGG$?{U`>^GjftSmQYelXlW7%BriZNL}tRkC-?NSwxcGqcmW zzDcb)ZVi0TZHOk#mLH)&YP0nvY@m5Eggbl3XNCJ3L;dDbKYu-N{BQ6Z{iY{O{uZLk ztQLbBk=0;d60uf@Z@aq$9`Fz`YVsluJfWj> z=cQoog**mS{Qbt<=`&`8+URGxEq5Z$=EniIuRu_r zS?i6R;%uK041L(OU}|2(;b5Xt=!s-vD<8_GOsKezaDl(V4AIbE%u9KOP?U1vY?c`E z!OryQD&E8~Z;O9K`<=zD_CX0Z{6<<#rqF3m&1!fA+=^yWQ%F~XCO8?!lZTov9@Hew z$D5ch96VXjYSZ#BovU3uRJ0)D;mtkai#p~7TJJCGrOrIz2@kRJAvsXAmK?vQ3W0pFbXKcJbm@)UM5k+P+j2v!R=HqZjV8r%8_f$I`#!)Ppr`H`XPU!mmuC~F0-%|E^#6QQqGITK_n6yd{xpG zPCqtknQbK1%XJzCF%itI{{VIFGi{Jz2@I@H!Kh}Od5|B_LcC-EA6++aLfpp2rFX|F*# z&Q?Kmbvye|l(bW)gSg1bQ6hPo_}ZRMoi$=XyY=(`F!nmd$09xaAquh;PZ5*@>RxHA z8_Rh`u6H^l>7@J%0jvY=CQrp%eMYBYM*Q(NX$CusReo#EEs3wq-x+;jAul|U3$3d2 zWGQp>g;8|gGhbS;jM_fY7wT0QpE6ia&Wat*S`BW2I^aUqWBQEy1$TVwxTp6^+@GNP zGuQpO!u^@0A1Lc5MduYnQvBG=g>^IH$mfI0?wOg6WZYzz1Av4(8ywCRRI1fQ$2? zjsrU=^RPRb9^=`dsV(0v)E4x%^l`D0{bWmOF@GsST8W~lWRI)x2%0BQI0i#I#XVkm zkeNXPr6>`o!=IsZ5^FaBBY`{qo4d~`+I1)v>qN1Iu=FRBOnjAfQdfNF=pibl^q`r7 z0B__Q8Y7nAhujz*V&Sba-Bs7OSeE{kT#lO_sUY0thet9s_^%wm9oZQemB%dFHbIEF z_%G}k=XL;yO|d_vizX_?U3w%vRLPzKc!4?Q{hPZOf_KRx1yy41+YE()X+Q~@G*`Ru zi*KfEsZJ&_t z=|it;@howK^DlepF*!kXNTP_x@!EXS9?WUI?>!f$0ih14H@Bh#W{g(dor)ImJu^HxNjum6(1W*}hnl*s1$$P0&+i-&woZPAy;792z+i?Y^yG92E$qz#FC z;jE+K$>u?7ImJHKsLc#}MH*Y_QK^NXa~EYv=3^zI=CXaz$K~esc_-rEYBTrj;I5>N zHdy$*WCs9AE@DVwqR$W#KB6dAg$m46_qVEYNr`^45|m5pTCwpv|%Mj)9aWrm{-pb zb>5uipN8rGGg5+p`SETdSt*x2VrAY~nJ-r6H$O`xT_1?07;p#Uj^@>jegPWAsppbL z3XVw+P#TLK;=Y zrOtlG9$`3w?v6#pUdN*A?cWXd?@{}=U4I`xVgHJjk43%quh0G!^%jc?CYz%Y4=kdb z`2z>GLrBS6*t@9%_SFY~1q6AeUT1w!b*g;M`l-6;AF~-c@x_g8)|-w~mUv&y8Tm73 zBmGa_=rzT^=NR458hY3&{$U%IGUX|M>$)R(-Yzt!Xq`^sYwVgf4#+1A);O^z4)eD; zN6RA0ftk%R!^hC$0(GyY@NxAh(#LVs5%b+qKvKe4qbUS$^az?~UesB>MzbmD#Gm+8 z@E02_C%Q1-)4D^$e;AYNU_7obnk%0J%l-Tim+^)p{DtC;huAho;^UzHiF^8QdhjaHdt{>fFWZNF?!&$c?sx$IUjX*Qv>Fs{<+I?g@`XVvta zFU94Zv_tVQrX>5!q}%ak;P+-8ip>J4gVJBP4^!SpdrpK)3!CjO2J2lFpW-v62ZZ3w zsUNxQ59|)1Bf{8pRi0%L_=h(3f;E5{)cBy##EmOJ6Q5$tlU%DU8ht^3GXiV1#mx4L zW%Jr5=n@MF5-DlXCV+4gU4@MGFm_Ni+29it!;AyELyoQP31Sl=tdfy|YXT51t}<_3 zXz}eua=0|#hVTT;&b3nI{APZ%N&pMS01zoS5d0fSZ{fT_;R{TUpF;cXoO50{Z zPY3M)F)165#InM9ej5z{rLy1L*3VTc`{Q;ymHi2z5H*Ob5*?1S_IMq@f`2nef_N2^pbzHzVi!1eSWfg1k4jppekBuEe+ zM;@YH=27mPHCrezk-TdWe@Xm4VIX-S?hcx#|H(3p(;4j^=IJhzZM2c;CDPmh!TSA^ zjw1oVb+*}A^=#sD5^On_n0;RtNj>PQZ+lF|Ug3O8QlB4vW+xx;Abj0zPG!Sb1G!sC z5`E)B ztM^^ZpXpMj(}Lb<2WCl}2mfTr0ks@wO(P{!(>4qC?R9ha20$Pv_f&syMzY@+255KS z)g&^Dmu!-2*}7i>{U`>@H^D|@8=}1COBSWS2dG3>?MJ9G#+1<**cb!U{g%Z_soui< z3s)TppMpT~C|no(vT1|jlvrOrc^H52zt9C<=D5RLD`+0#2t&}~VMD^RBbCytXPK*D z0%PXPK*RI|obqEL?#xRFRa0g8(ZRGsd8vRBYMH@fc-we8#EFh{6th)U;A{GAO^JKu zV}s1=ZY(*OxYKHSRhe6#Qm`BDvI}-yE1!Hna?OEvew1i@JBnf;V9NB$|&t-Q_r`thUq5qGv}TrdoytDZXx@DkRS~mMx@eliX2J)k-khPFK+Z1t!74~x0SJIEeT6( z$#d*TMAP4{F}(x*6kP>_+mBG288V6vEn*W=$J{jQSQ3M38u7%Zw;Asih`niT<^+RB zE@9S#*0<;CXr+@?a^x)2pSk>rRL5=nvBDC+4NUvTH7B$ohC(e!yqFkA-??_f@<{}$ zyB57Ui$mfoivP+pfXdSfp-Wy2Al5uzDYi)&!L7NRcI$`cS2w5Zfx}+sGh!R=H5C`I z!z^EU7acD+2wCV4mvd6Rb_*}cecM{Ij=yqjTSoX?=4p7*XW=1r(-!IgBXoag4OJ`= zD6*&S+J#A$Cy`rO+5H6~AeXvIN=#(yu9{NkHbfJwYuoKtV zg>i2jTp=BsX#iN9`z;ne7&%L*aEait3o3LrxNp%pfR)2%*&t~HoGel@5YTsh*U}&| zCkyEHoy4c}+|HEW_UO`9H2F!h|2=ok8O?J&PSz4-H)9rJq~-_rbE&2MP^4miDirs73+ey8)yY0xN~xRxc_L{`#0 zT*y|ySUbPJehmFcNPM>L_di7)Ug;);?C8Angg%D>UBeNo;fFRoSRML`hS#C+mT#I` zl6M)nn==G7?qwsrS~F&TRlFfYz1VY7uT=)kAMfSFjH^lcEkB`mW<5bc;_(A2*3hm8 zzx^?in+81?C&o3dFOO8@j2u!5xg|+0oCUqOMJ${PDP}RYRM1bkX zAHrj&z8|KXwd6}hyz>T=Pc-puGYFAYs*uxe$|+Xkjlnjo;3Kvd?zS@r^O61A0pNFA z=~nLSe*fxpE2ig{ed@8}=|X(!-M_GpQs6Vr9N^Bezy^dj+)mFDIkBJX*RfMy8f#c* zZ?ulFh86rJSsZ^w2PFo8YR_{QSNEwmKBm$_aZmxtpV&<4WWQ02tIP%K6hPhf7=%E~ z0)Pu{$tU(u)J=(DSHNyT-J2T_Q80KH^E|2sBabE{8!OE}Dp0yxOwBS2RmTP_D|Ycv zWoijNd|ON4B60xbbZhOig7gq6@-D7w$v;mjdi$n5ZbwoTZ}^cHtSUTb3g2hbTRdo1 zap_n;iWsKPAZ za22TkFY1}g9gwG-;@kBI3em&a9cVbF@|?*hy4EXi@9;S-CYJq;W6}-k+-I84lh=mF zSu(lX3+WIMgLYP~w&k#;E8zPmp` z0?fsge}Kt|$C6eXb*lAt@Iw{<_KBm())+6DvT*c;d%5z2 zuY)vO5=xJTd9(AxKzqc?+aY}xcYVhU1hG~dH%uu}FcnuQvDch$I8WBoR%bzMa(a-I zSkzDFL(yQnFef%kiMkFW@hkK1-6KcHj`q&!7MM-?l2X}a*LeQ2)$yEHUcqS zSSC?*v)O-D2mjJx<`&rcu{m|P#rD@ntrWr&o*}>5$ke*e^$7bIcfo)XoY{Y4FGCH5pZ;COK)% ztW+_@N5Q=D6@PLJp5zo0rD?88bq9Gh@A9lEjOE1;rJ$3tbJ$?*Lx!)IgV*ExM$C8{*28HrU;T?^;*Xfa4Mta-G z;!qYdA8$Cy0U5;MZ9hSlQg;vt%vRU;fvvU@^vUOn(YV^9gub!uom`Xzu&5zTW}4bg zCjvWdwnWM{6qF0UXV`d`awNMkKlG03DCUNsO8_k^7;_)n9$Dyp5_^OP8{{h%AmlX(>jn%3R8!UvHMIb zY-Y79L=%x@E+-yH0l7VDAPxHMlxI>~?1>}HnYqpVP^_ViJC4XpLlUy3rVs(DTRN_{ zPDVVgd9J{rmyV~guzi_)tqfv?w>Ldcr5E*y4$HK^Rcp3VT9A$yX5llBl`Zs!^EgA! z4Pn{AJje{N_4k?*ZB5t8t2R zQInGrsnF+qtQ2|FT_kh-ptEn_!RTMxqC4^{&0GJ#fJMSiJ7y~%#)oi8wdn^R;iAT? z3YX_c=2e<%o*XM)ltC^%I?|17ptn}i-_IfFi*w`HbPqXB5<@UYnFJ@sn|)^UcId2= zk6gka3iibE3**af%lsOakM3k5;#niorf7|%HevjQ_nLJCXtBbr=ue8^tyxwR)Oeo6nYT>U1QqWIbTCGvP1_n!pC}y7fHeLfG25 zQ;HWW19N&rkpOO$1}0{oI-570ycns{nL3Ij#d+vU3ixn@p*b($x#FZE7NBfa1slPs zXl=)^;XqCW-8`%gA?lZ;R%TAl{Sx4CsQ1TPSf|O76dTNNS(Kw;g?HS`N|?ByZygn;}daLC8D#F;z|*n#jdeZA%H!X?d0sl zIL^iZY}i#hEXdPEJmr(h&rEngVgr`6uY5nzv&xhr^Ta&{({ZT_;?l!~7b=!JLHq%~&QP z{W+(tDAKlcqBFCFa1!NhS+69B4tj_QS1PqTpr9ob(jGfv!E zc)#W>eE#tgzbBtv?%w`yWzFSs0W6?WE-Z57ym*}ldB%hfXli+{ZN{7J`2e1}U)`r3 z=HsRwje~VdZbJz)+|dKI(J2dyovs^xXqSVfkp0UfNVslgr5)5@$Kt=eKSdI=b{6Yf z6Ad&dKI31+N(PR%)OZFq4SmUZ%#BwNbWen|;Z`U5m7?HXY%!hZEml#cTc}i!O6R5o z*Qd)Lo4Byp#+JkfM5L@st#;_jMD+qsADUe&Y0;9|V|12`H2zgQ_=Z!w2mvmicv3j7 z>yl%n|Kw(#CH`*d?;T*QYUi0$mq^)8G~Xp%%S*+cgVL^e&W;7n?m4Z48G;Cz?_p!Z ztKl6i$|*SZlLrvHa6n1ht_P>dN3z-n{>@MJx$~ITp7w^3#G+R(d;uz267X)I%a*_rSXd>>P>3J)XJYtT#n;^%AXm|qVOd0Wj44>vqBKGl6;+kM^f_}1`+%z(EaC;YUQ!SOZYoxKueS!KW`s_@~#XpId zeTTR)SNrL0f!(Z+ia~3`LX3=MZakpq3$UJ6uc$4X(kreNokt!D;PO1HzSBFKftKW~ zC&9IQ+J6RXHZ3{FqZ1l52&BMp&`W0tvSjG z85X6k+%PzIK77bl*SmCiR_1xNLZ?Q!5#==+?mF6l5m6geHC9n>ucNn+Npx)YA*|Ja zr55j-TJge z4qTIBJev+G1d}rZ?=|>fOLOQ=(?IihTiAZC{Jm%XVH*^G+k;=Q9{id8Pb+x{B_#hNsk(^_ti!vgo z^5ma9iR2!$wnG^<@QHRJ>r`TW(BhVdB7Ek5V1()005lWSkf7B6V{~Xu=EZ?OX1p{va#{^?bN7u`JCCS-XJGViAJqhd#+%s_;%nJDYt|MzjbT>m zzu4g9MQ#`|_tWwj{UJjVLch)I-<3WM-E=kK3(XBbJDP++8tj}78DayPK!rFrd1b+z zJ_Qp!n#*)PvQdQa&DvB$mL5)qFNUl$Ti>)YowKn5)7dZw%sb7CGE$1jbW2s<`JHXq zrpBk5f&&+RCD054LejS{J_)=n6NL`g*?fe4q|vA)t}v2WD<&Lohdb>q`xN67cgNd3 z);s!XW+cbmV8E|srv&Z4{k9b0s{y*{l`b6z1B&H8!pKg!r~8Fb!uTim$)b7r0%t>n zB{IQL`%Digo%wS*zhd)IR6Awf(HZaaq4Q+jaF+g@8Z}wro~e0FjH&6DK+ee^61^JN z>nE!wZx(aO+=*Iq`gWVg{@RBu#Am3RG2iNB>VC=wPBC@;n8EH$-79$Kif-LWEhjTp zH&t_dnb*0LFgii575;yRRv{@TQtkgP_Pd~%`L350)RUYRB7Mx0}MOT1D$cfHh?E8 zHX2R4vwxE}Jet=M&P9erZ}oj&I(7KNbv)<_2+m!pD#x~GhOh3ZaV|AZ#g?rA_;v&x zfxDZWCsnr?hB*b9EOO!kYRKh0GQwrcGT9Vg^qJ4)4&N{4J~iN1C$N-m>_XWWDq5?#gTrF=MddOJGSsBTR1#?!Y@>{--KW4r|*PJ zwbx@pHb0R8(FgtNL?Teoq&68=EUG8+_WlVG2H8t<)2u5%iXN!iS#m{s%)xJxU|#QWpHffoj*uYJffZte7*4WwqxfV7UDEE@C0-S~o%Ar-;h#KT0P9 z4IHV&qaHxhtZD2{J>2AtWXa3*(8n?Rq6%i=D`}?v6m7$9D}?3kzWCOAscDW@0U`T- z?a608mQ^+;Zw1~+?o@JAKJa)-p@_pt;u-N-R^*HWmD%w%30mYjv@Zz9=RPkuSZN;N zg>)K6Dp6{5ZhQbb3F$kP<|^8W+2N)|jGHH? zg=Pe`f(?j2wpkN_pZL=jU0R{d7CLHohz`}QOS;&BKmBV-VyHe9EB%IhJL#kP1J3s^tF;^uh(W_XUs5*efBCPTqZs(;f0n1 zzcV9?3-7lZNCNb4SMeB&YA|kNS5TxI$*pQEG2GHmq8d|F6GfjrsVLJe@=<+4C}LYL zPNl6h&4}7W@({g+P5_WauMlbVU-B^gS5Bm)@E#$O@Hl6?wMfeoy3URoZ)AAPzNyJf z^oZT5G8O8ia7lW<*txPpy(;w)yY45mfA$P=RYu||E>IJ@jrTR=vk^b0MeT*L z!*d?%);!A>wW2hCVwUrgB0xqDHD!x+4_4?u8o96Y9{}Y3(&6jN0zMzAk9Z{jivn>To z_){XdJK0$wyn;Zy6SJ8Oser<&{b0B(cLk z*u4;&i$!@q9CMXNkPSm;h!iOX>XtHli>gfMZ&D#)w_r>DXEkK0jWdq__2^(|6lO1& z)70b#&F<@Dp0hbAvFui6ePWKdw(zK6u#GXStP^@UqG@+h-jeoNF7brxiMQQL2LtOBkj4_*M1M-UZE_ z)T5gazIxj+6@yg&3H8kyLsmWQngaZZ88USx5Y2YOSfJ=-$u1DZJZ!gvvS{K)nZr(hHVy7u~vN01~p0UFJ1;ot39)gl^hO934x^T&dbl1z}|_^*T3^ zE=|Wzb~N9nv+{aom`CV?f@o>VY?y*BS**x)?>A%HK@?=MB7hiz57QUXjLl)ymKa)T z?l{Iv<*@2+QPeB{1HR=D&!o{P*{c4YQqvGAYWqmG`-hjJZO$`)E@MU!78Bx4Q@tzP zx6}6E7C%)X!4NOtbP`(m-dy;(ATfQE+~%SSY2;BF;e-S$1?nFGY+ZHgMy?3iL1Vp~ zGGF#aIN4Z+xu+>5Kf9uVPnOvvIPlRy^D~&g+3_X02wtMKN3Fw4WY9A?Z1+kt6>Cvu zsZS-6w{MJ-*FMB-(+vkSUxOJ|2^JE z+Xn>JwyNNhtIu6NRpFB}_#rplN4DTsmwzWve~vAfzq~+f)tQ0%zPdML6dBFM6niCy zXM1rb7p)ukQ`5Wkw`#%+3DkeXeH;FsTUf$#d)1&W)bwp_P{F1>xP=AQ&gBukD4`b| zVK+qEuUmdocyYA7Z25(OdPT>Hn&LqHH{BM=67ODwSBZEC=+APuY3bT(vJ#`CCg_?T zxZf6cBaZN}?d|b&PyWVLO|MznUXUHfpIXm7`Q&DVpNY0dmX8eoHEI@zZ&J-i^pXDh z(?@MI{6;l%5--+x6HPUJ63<4>E#WnKU8mReE7(|3L%8aYg7B`< zVnoA3qo!w|K4{DJV2o}BQ9@aX={5e=@9?0eN9#g7S&+E7t!iBA1<7xNjt|q&+FF&V8rh4+0P4&FZ@8$gdi+^SO+r+;< z{QDmNKH{IJXGUh0H=`&2WqW(}%*@Hm@b=(8AEBgGSN~L3zbdb~y4SDTb77P7og^5t z@$e&DnQA36UptYsM4~-zF5-+KR3-{>Ys%9rXqw;ROe~gE#yx`kW=Wg&#=AG$y&;SU zi88OzMV+Gl`@M)+L!XS*;12iN?3R2Qbs!1&miWzcx|<@*hQ|i!ZKlW#{l>|$iBru0 zrq}$O_w!dPjzG5g=LS;FiKe!`6Ic#FTyBdxa-b)KL|C;9w|6RqwJ@$)C}1L=R1!t#^g3C!~qAsq~8W{~$mq z4aO$rMr%W!$TZgg!f774?deV6r&rpa(gcm%8LeHC;WUS{pWedL8OZTYJE9fM{XQm& zsnHIheW;gMX^1hC-)-Lu$z8-3#PS^P{b?>P1A6KZd{IY}QFi&jd#Z(TYEi0Uh zU=nwjsZY9~(k+E2c#{(z{49IiJ-`n&FHwvWak+x2&F-_2K(2jUe!!g1xSjF?&Py?3 zYqrFu5!jM!$@9%neP=seIETO!kf+t29;?ly+m2c&uTUoP#>G8U)fd=$%C$xNm-bAR zOpKxRz}AU=0vt^2r9VFX$dg4 z=?gOl=nT$NYKlQCZ;*23^60;NFJA=MPl>jlwR}!AdHV9I=)a1VS42N8T0T|Vq2w@g zk$rbNGFb)%7hjTZnf;bvY$hoUNZddqv1%eKiWcY;|{UA>$ zyV$cjk?oGYq|P0^2us=bgr_Rh)ws|sqQzkq?QV{7p*^fE^M8PQO9h;hyr_#Ep({g5 z{xNY%lmOS^o^U70;m@)z1a7yCN@zR+o5o==4)xwe9O{Sx8k)c{7%x82$ZzbqXN7Ty z_ZE9j&tuQMX#eiCfA`qG`|V$1(7`qUtmc;>7Lg!Va}+mN>^y^#fVcA@$HpgIuUr7!ay2LE0={Y-&CH%iXCM)p{ zNqY)jo?~`=JvB-}nE5*&m5d?UH7yY^hRXQ$>d+Xb98<0;^VjPj6_d%O{&?vy7qOZV ze;4BTS(pi&qg(EN*|&e?hV^?|#FmbWB&(y(8k zzB4{CLn4Nu+YsiGZYXHl_zoC|2t>M#mv1(g16P=)6nhgGm^;m}zU+QEd>Bc0JBl{h zqWLEkot7Ib%_IL%(EPMZ*+yITD0wCDz@Fm87GR$O?@seOIlW62VE3ECXr;NmOY0Ta(Ap8cOj4^CHCxb7hy~%fP+o6y4ba_8h-h*53V%rf8scwpmSj9 zDV6csVb$hb(i}k-^asTgzNDk=x5ub$ETl>f6zJTWCf`{c^mm#k7#%@3k7F6rLxZ(*NJQ$EpzQU8J`#_0nbE^Rv(&9< zC;zamxL599T_!&@qep_KtV>xU!t;?|sOnA!OdEu0Y_gSK74i#7_f!_(t8dK0Hg zj7^?r4=ov+L*=F1Mrq1a$7wFu+Xp$>GJv8WGn6qD{W*{_v&Y z#cOj(cje}9FSGgEdk|hcz8tG_avuJ5vwLtofQP-3lBus|G)8iJM2Qp}tafU>iGVwI zU#&F7oUzU&(BuD5K=S$i*!$plE)^0$=b&Qr{r3A&vTYC*0f8$A^K z$*`EHTaku2m%4e%zrnN6Gmkv-NUx%QFYUppK^C-ZjLhbpxUS7l^4LF^A?i!HpE_B4 zW99ylt4>4?xTZ({%WAC;GlM5pvsy8DzbhYMEhJ+cQ6+rljS#EE%A0;wVP6p%HJ0!yczkYfh8H;cLHVS2kaOStiw&tQuS znz-xc`n|+p`r^qM? z%DUeRZf`b0&X(=@Vl*nmDuEeAMfZra|4GLZ!A;5n`d!fZKzS_Z2PL_)Z)b|xZ#uydY>!=jc!*6XAuL+y&0G zB_sDW=V-;uu%*Dmw8bO$nKSKGh^t(CwTP=6d$o|O6E~^cT&_N{SF^Y>_Ua0*-sUPk zt=PcAC&r1IyKt8xQO3*W3dN{F5#}w4;1F9@a3G_lG2Xsxlw^>2p=E_0XX@oW7+FRezP~ zJG#rEihbZ)g7`o25Tt}yvv!s<)9+;3jM3#{og!u8!w90GSQ6;7KifGhv)9hRliP5} zA9AsYZk^! zHYz&G4P_Zu2VWFRyGP7 zj9A$?r*tkD!zrB=D;wmLUJ)zHcd}w-L8mknD=T(N7stvbJEcovWmB9|_SOKWbVRId zDq@#8_H#Y!zT;0a&(N)91bv=@1w*{FSQz*^ZP2o@PU)0b*%)29Jz+z7i@O53%srjF7ZZeZ_Z^Hq@`k38t^9fnr$YEAZx8Obp- z6mqOz6B0pJ(Id2SvJ$12(!YH0HoDt@S@0Hvv0V9ObV*6kmJ!&y8re-ZSO9%7xM4-h zeJgvz4V7jD&6z46@n5&spEccU`oU7A2%|jp3RlqFAAm!Cc&<)O%b^Euzg1Med<<6r z{>S3y{JEzS_a~@K5(vW)amz45%W_`ioJ!6qWf_zDMyHrVO+^+dXVs zi?y*|4K&oz5fmv{FBi4cT2jG?R51CJMVK2Tz^3`?T*>pW{I4y+`ULZo<=(81P49!Jj7l0D{=KCY;S~%1F zMXv|$l$EeE-BUDs~j?8VN}UIxEMjy7pG+yR2<= zHw#L6B{&C2Fs6|1D2}ip5*UM&zbQoBb{2(*xgA|vM3+FQe5TAdk=BZKuKZo%YpX_& z++A=CpOWF%{m~zrX_!yG{s-d`<2uun^1bMGKcvS@L$c?07({EK4y-cV{vtzo`_t&V zJ+iiMYtJIM-m2^xFMH`}4<~rh_S#Hmd)79jdqpj)dZ8U!x0$ZFwAo=h;r|0(zizq@ zOx;!iNEWj@V>bX6O^-DN8B-Km(y$K9!jw3!=!nVO38vDNLE3ZN%7 z6#s+G9`0#)|}?ZRbdrFf1Nl#5CaT zO@P3Y!?hEQ)gEQ8j~aS#6*W_U5ckq)Gxw@PFPX(O293i3I#+Gq&8@R)fGp^G>-a12 z7aWVW_X@22n4zGdD!R+28J(FMyJsC^o8c@O(5i5$P)!1Zh`JxpAsTdU9MRQog|TzK z0hbGyp4MM#TjAl5ivxP=5A4lJ37eze@p@WUrrvZqwqXI&dae7EG!b{o2m-sRL9L~! zlK#X2QGL2Y2(!Q&{E;+%i0h;Rw@w9{Mx=pQTgWnc#*XMqxKVXMc4 zmUO9Ka-_8A_{vw9Z>Mam+thb$Q&-11ZPiqpn(Eo5skSQfFBZ-=^}Q}lmGj~qUhv6G z38uMyRpm1H5aVM3if5Wyy8HHHv{yG@y-r0ufxnI`G-RV}yCvkEsU5A1^p-0xP zBnb_<>fYbNk|Tk2(}g5(dCYBnUfgXD6x%MDPqX<6jM1DWqgo%-D~uc!0vglg8;5~R zJI76GoR`dHL)jsD9`nJypCs4+8N%bg`F9EbD*3mDe|Pb32mjvY-_ajU^<=Y00{r73 z)3KO~3QtZthGpa5Hz(=^-$(C4TGYa~0T{Q*f}k zr2PU-^k>Z_M+>D3q*8 z&^cM{d?T>62hD@N@1=`SRh8zabl+*GYjP#4e?VQ^Sukj}#QF-1ZC=ARk^?tBe)-6^=@uRCd2KA9+Uhom`p{D4*lq_J zt`uw$_-^OOajzt+&8d?=aa{u84tD+wY#qIlfQ{RlGd4kf!TCUviv?-U(Y>fq2%ci8 zd(o7+RwLME{+Twr^HF{d3HT_e&o_2<@8iByj087}G)3FqIVtr7Mb0%dhDLcWW-?HdZ?x{a$Txtafs9 z=@cF3vD&HTQfljaNH0GsNyo01(RE6EijOmkgKC!tQh21SKH}4{ zk;5+v#N?gJ_kVzor;V)GBf3$5Y8`+2<8R@j~W-$U+E}0;+8p)ky7HZ};{z?=0$Y3Ur2dFA^*>R3pdE1lM^rB z7`Jg^K!uWw zJd})V1naQCC|hi>Exx_mT;Zp~^PWWkfJI}4tT)GY9fGVk2ggh9jb3xFC$0piLFe)* zASUO8(qp8$xN0*Zm&z$31`a2Q`q(8P4TE&%ZHY&kWFyq*>`qrT`vZKK9l1r=?OtHU zxxBbxSLFPVuFcQECFI0wv=T?aE?{j}cbeA%nS?S$=kuuuQgY>t!A8kxCwsiJ&pdir zrYE+XWL3F!?|GV#9lbs9*zvcct2Ur>bsy%!|0K!vu+MypvMm2TzJ5208QE;6^Ta9H zVi!XZot?|alY1aJAk%ucn?YXzFN63OHXaZdUCk|erIJkoqk~q$hYi)UvGT^kSwPZ% ziSSyLSNFc$n(C4sJ{%swZ$7{I{1)@;=XW)@yx|54SIme{@tSv9kYM+6uTOcMeF1pg zT@jnNpOh&bz!jTE0+lzvJgnW_v3VO(3u6JWq%mH8FKyf#o3~LBg}Q@iFX$|wqr+O6U)QlMUjO721h>Q}qh#SCPUyI7F|y2X(Jx5l_* z<%dURuR|FTE8hd8mb^L9_WRjb$z~=nR?Y-H8Y_Q@E#CT5n&Plr?9Rc+muRDpt*Mz| zLOSY{JgV#RmgbU&?0j6wd^i)_l858|F|?cYscoN9M`EiEkhvzdY7ZYu6tYh^iCc)j zJ#w$JEpZ=n@AON3Bvtj5R8{&lb7ySke#*wmn;e>b(^++3WV17Kzw@Nj{m$OXnmp#K zW#sl?^$bXAH%^i;T1g|XROQG>bb9clEJ;Ttc9Kv)x;)^eoi7ZK-ug~t6MW@I`zlw5R7 zuk(m}1X1%h)+D)f>Qjf5HRUdXdvi|c`O7?yPx3lP<}=8HTvhQx62VeT zi|La0bbf9fpIka#)N6NA_44t`JKu)Ze|t%$2c_{|)1nJL8DHwPU#&8KDm_kIU!L5O zZ=Y0~9X!Ds*X2Iu!N3ROmwQeBAK3$X@mjjtdLuJM@+YMkh($U%* zHzJGYHMYo3vk6&6bd~W$e$D6TgEMKE`RR1)HgX`)aJ}e1yUZqVCSY>;c=K0) z1A1$|00hv8Mz2A9K1(MI2K6_!rIoS5ji<@=e5#-_9Ls zCL(Qf(!PjFBO}Pdm%=;9A)W9|#zQo1f>(+CPWO$YR-m+tXF!a`0c{E@G_7kO=Ui`i znFdJq4FJVfwNW6F3&bQwbMyjF-JwbOKHJKioz;~tzT9urcMTU|M1$`ohHc=NqWnIml?1Z3eE>;}Q=t611~!0In=fXGFhT$AAh zoX1WEtB~w-k)a}-U_&itLq%5|VbTvrwvfU?+ZyWPtAzN zQ39%i7->4M3!?Uz+I<=UCVP9Z0+QvI$q`l-{0MeptIQXHPk5Q){%ZGcskg=^*K!*= zdM7mcd&B{ABKynOX(erm%bb^(#&0u!&PDE4d`a)!R0N}K+=T3@kR_V-ifSEpzUoLe zjU|YE*Omeup6*WKE*<%udi)ViGpz1kPGfc1F7@( z0=D*--F;1<>thglfxEX=#P2vv56$iUvOGvl_n5&N8c|TWEatL`nCB%&%yX=k(^B+y z|n?f*+bSC98-ukbzawNjY#d$y9|8vgSIRoFfF5^7U z^S@ty_ltQJxZ>|f3!$`@t<4^DZPQUIS!asTRAQoeIxfEVM8=l0kSg>fouf{F>QuX+ zRe~Yg`4svSs~Sm1fI*^HN+Rp0QBtLZs$zQ1!tI-5Yg5|({j1{5NJzHNyhpI0A8{43 zA%`n6Ys}66rF%t!f{q)cKTuOZcOl)9U=#LSHmkutXQ-|3yKVIYNFI)F3$b@@w5?7l zPOW9xuO}R_ga(<<(Lr|fzbiJ zA54%~6XjV2QF>q0hMk3ua|wr1qrfG340@hc!gnV#HY?0<#1lohgwS zEs>#(#pr^$TZ4goSBXt3Bkv##yWOShm5f)w_Oo}9^c=*AK zQOQk7K^!RSoQtQEHO7hfT`O);7%Px{=9M#n@GJ5h?)u|yIE!?pGb*TYp~++F#Dx~0 zBFV^e8^!NLQHsT6P1eTiQ;u)2KB-2B^1Rg+B8{{s^nD%(I-{@}uH#m`6);LYOekgh zG`sFGmdjjBZ~pU>AhslB@HF=%(VNG)W5`#Tx#3ypd2pA$RCLRq2JQjU8cxCx(XQeE z%z39kOLUMG-H@_A(m`grWY0uqDP;`w(GZE`jG$VAq(eVJyhZ`!0Wt=&imTE+amQ6MPT>`axfy+{VVWB0f z`@tm)WK2zs3YiwIH;Xfvuu-&H0Uj z(DoGPo^U%q8;sq~$5+H|XYH*+w{vy;d9=6FN9L|U-)rv8;BJ0{S;=g?iY zlG3RJ17opKy-}wlgAtK28wwlB2W&?o=c!g&XWrz6|H7nN9e8Wu#(bU6!+AA~SkzmP zBYHeycXERDHOREO1`Yo)#A1D%w1Dq$fOP6M`3ILT;5)#Fo&bqU6jN0xK?I@2ur*vF zGg=8BQKPP%N6>pB5{@r+`o`MQ0-vBJ-|YI$b2@879LAmgQ2KSYif8!Yrs z$nx>|3fK`f82)LRYyIj>pWW_Xl}-Exwi{}d?Ux)hviTO^Ulv?t0X}@!=NUl+;44rW zw@O&~U&OJp7#<~r5c`|jaWdlV3JuVdzi<8!qYLd@^d^utE2^lk$O)j$?qrOCasH7w zEs?R-M|K3n3!4KK$O{ex7W4!b97Km3SkM<(Krq0=fd#C$mMxNm+0%TD&K^GRj}JS8 zm6nk(wUZ(18(ReeWZVoN1B=e;ZG@pmP{Lm| z<0h*PJ};L+XVKoGYDFWR$~(B7r7RvmX8^{N!rD3k}f1o=6K4eU*W z32?YVWJRK(ouz?fL^1{5!=cZ+;U!LSygdbi{O%`Ga=Cumyx$X7we1 zNKXcwiq2VTww1~DS|uIVBc;Z?m@VKeMXr1x9S?Jr1on=E^%BxTdc^-gdPtmFt!6JL zVZD$mzku*LH{oT)W?`|L<2R~ev!xMEcaRA&tBU^8RAf^Ov6WGVPIW4_6(H~P9xU*_ zkXpfl91e`0#o!q`Xl+7b>(B5udd6Q%)){xx_z+S-ab*1GB{{360#^tTU~U-#S53$4Be3nmc{OfSz_-WHk;o49MlXnN7kP$E;GIlbl0aMOeqk?gG*byJYu9eAL5*Rpu_+8DM54 zXs**V5L(rC^>!^7%pK-MZk;?MUwPFjPpnfKs}og+Ko1oiDP93{qri9PBgW1W0NbcL6;ur3kiJS>`;GO(2j00U0X z-%|d)h<{g0zJ8xB4>3g17A_cYb|A+_x#;a~^c4^sbU}aUYp9=`1>*ZNDZ>;(BT})B zSb&7LU7CsQV5K(vw*XD4fl|EXLTN+L8 zkMcgF^mq4C{i=u`Z1+%7`vok2p4$O|fvbBp{zRllP8n@rx35Z0&3vfxg zWEE{Sfyr|>n45)R83MF|H_^R?R3eWsRZk@oI+nu}F$ zIF6R&L~{!G_J|Jmb&;Krl=AV|-5#qw5apBN84ggZt^+COeNgieTHDhik&J!Ma>u{_ zo6ZBmLB65xavS2}#E!jE(KY|l7CJEwak95Z8fRY?5HVR9a7cMF)Of>9R{rD4P`AnH z-o<;jU4k$S3lpH-YQ?PK*Qny9nGNa1OVfz3F z>Rm1K#dW$Z!RdooO|3YeFi*!|W;-QqO%B1^c6KE5If)Ej-nNb;{lv3tna#siZ$(|5 z3}Xp0I=O0Hn`RDTj~(5OG1C0YQc`-+f5B!bb&J!2fms{M} z>HB`%dEW7{&U3EvAQGWl$x?MDabNKbh9+Bx2t-@#j>1y4muVF68zz5D6l{;gmORaT ze;Kn^&`V#Zvm!sC{@HQ$4}CFG{~%${BBBrK=b0}J)wd+E#VVebOA!PM6-aC$<7o+Y zD1F-<7RaJJ<>5lA`hQ^6-0pSCCc29mHBy8viQSiECDEc)*-vaeeh&h#G?1UP=~I(D z&1bO-QVI9_akw~%5SWuJ2U0ilE+NTYE3W95)QL0Z%$XQtRH`RRth6wdTYM*eHw_aa z1AT>%DPoXcVXv+A-s#2kw+IIS1j%vG-ZaGpiE#HnHlf=&1vNRsu| zf3p1ww^8Pd<=j|fH7(I|2@-W>WMNMx5uQ{Eq%1RklI#Mqlow;gRZ_upy< zIv3>I=ghF~D{lM`GhO24d!|+ivS-Fac89g!9bTSoGJXP3mb_4=9CzRofIkT^%nc>` zKXPj-WRrGeLa^W*omv^1R_)4rHW714!tbgoiIw&Y1HLpiflGQH^$;u)$Te)fM=Y{x z9?T>BfP^ew)bIPY+3_#CxlS^i(a;Dh`Z)EqGuckU-knIVht7|kudNJ2=lgZRvhvyC z&7J%(OlV5@E>fIES@>&uk!&> zcNjw#uMuMCM^nBuKemPyL{*IlYMxMJxqfZ}E?O28osA-i-QYZ67>S;cKIMh)BCP83^I71rCtH$q+d!VVDvz$B2Rme2+4h*_<=l?`w0nHPF44!>xh;WSg-90tlz_5Gji0iaCKn)WA=?~J_74o?O#O_3#{L0|2EsdvJefd-(df) zwtw6B+p$(=hQexr^*im~q1Ih?Kj7xr?Fg)Yi0`|~^OMbVFp%7Gf)8k99V0Yg^OMo! z8Q;6O*N52`>&jn2{ww^hTweg9Fuomn^Q7QQXw8-sCsV|erfE{lj? zEUpHpFw2R<*aQoS&yW~6LGlFi+-ooDNfsuu9GDB*DEDG<*T)uSpZN`0SQ*JE_14CU zhnCwF0Y<+Z_eJvD(2aII__99ki||kA8oL^NX|Z2?f3_>YvoEfsMjXnu^XJPA?w8Zm z?@qqxg2c%kB8Xjg&r&Xwx}8$-MG$U{cGhlSF2rLEEf8knVp`?RkI**Rr6M}1P}1fJ z@#|;>6aHi2`07NOh15+@HByXNQkGvO>6vB2j^Vu1NON)$jtzx!fwj6^f~e1&@I@C( zUpAlcMVIYlP&lwwS2FngCjPGJ&|g`AIdtq7{BV8oR8jktI1Fpu#TTt;;+GB7v`8+Z z1XvQ!cw|)}#K+CWn+-LFZ~=L~X<+tNKVBN})tMpiFp`0<4 zD7EHM%wv;znfJ0qxKvB;oa8-+qk`QvkypP&ju%3L%Yyc>zd$C^JN5oGqjn z#w@&4TVTJL>*k84wEIX92fq%O>E@lgf6lI${3!5&7ze8XBMHmUA<+#W97+6Kl0iRuxmv}T+t>1;+Sx_l!Y>Hz7NR)SFY1F2#@aM^6<2C?PQ&EUcira zGj|>P$c~F&pBx+H!M|&e?n%abQ4oTp;afDT(8wB7`xz$w{~&~S=fn^K^m~mdeK-Lj zY>R$Itgg?0{K*hP*f8u{-`9r_Li4b1VLaiY2%&D+w~HPgLI|_@W)XsV10mdB6-5Zn z8eQrOq&2lU(-BSCiTbMI`QPV03cH)zX_DQhCdYq&obS#b=pfZum}k;IXAR^D>YG>c zhZ}sOI?{zPxnYC_)*6zx$63?H53X|hleza2NwBr<1|)(u1s0LRBDti>)T$2P6;)fM z&==d|uh2w%r^gvMof9eMdoMJ)y2^CSww&U?4RQl?H&HqfqSg{G-DT(hCV%|8{QFQy ze#e&9$b(DsWJEqTkU3Ovr!6?~8Bq9A3c7ky-&I2ep0Wk3S;kxyKwE2NaFEs;hLP5o zx=O(mLBjKdPd*v-G@#_NO8d`2zDVTQa2{hk+gftEbGT@z=igqd8B6aXe9|g@Ta=M= zuizHd2x0aBj`#c`ITmX;`42W3q5|+Dk}Zu0i~bL?pwd;|evN)2s$w!QW;@DED7^aI z!eQvI_n&n9$yC%ke2r02f<{p)>IdpTRFs6EZsX?dhqyRDRv}AC`A<@0*^el)Rz)m9 zwIo`ECZes3CcA6sHkYU>J<0cDYxrL75>|O9`TkQ8R~Nd(RTAGBBf&8w>2|$I?x_Sc z5In{%sNH4a#@HNM5qb3gK~#p~m*Wp{%kk|mM3&<;!1B;s_CLsUUyiNF9Vah!`zA^~ z99xuYqor8dxVBPOFt4TVx=cKIk-v!^t#Fqn{p3X+)#_aAuFm_Px2rQ=Of{<$-GHyn zO;{kY(Ke8@dzfzo)zs;l!7DvU16E!3$+yFINpbqDv5S)=>>frF!PCR0_ zKmf-$((UhZ3>~nb?M6@q`#4+d(I8oY;tz2|db9FUG06!;7hmvSgsvpFsr879qbhX; zElo%M$v4VDM85%%h|kB87WUQDEd|O|n#G4W|2wg6&$3*itT9G1hp>hYpZ_5EH<8mYr7)WmKH-k(AKjvI7G0n+_~R>#JX7E< z%p7)oZjk)V2IX1U>Yu<}_&B7y;GdS0vp6YfYaV|aGSHwW;dxbqUxWE2k)w4}8A1{R za%H?UFP{gLo5Pxqv}2nX#MeqKq<@V($e*Jd3v-=AirP^0W+>IE&hu=k$o6dUW?A=A z(EPmX!dIjnU*x9!l#eMJaz3c>%S5_~a1~AC#cSXn2AH=p$Jw0&azL`%e8ihY^Z_eb zZaBmC1L((g45e;;j@<_}N~tuPU*p8_M^{H2sN|yWn57$8({bpcoS!GKqAp)>M+At~ z$U65TOn3#e1_Ygk!!4_pTv>WDz=fQ>q`&b3k(~ASSYAS-bUc;Bp5Gt8(HzlQ7za03 z5<`q&xo3zDZGQhH?sKQ9p7c>z+sm;!WM05!-+4vy9;lyFb>!o+PpC1a7K@z0Po@iw zQ9ni(^zjg-3m%veL4;=vcdagb6fD=SqLws5LhMBYw*V zE^BZx;%T2)>X9Z&&2f=p|20EsI8ZGfA9WSed zny$LWe^*{o!%BgN7dkDu_9Zs{r^JJBc9ZG;yZF7(+UKGvn67~Im}#$~vpH+nPC_n! z+8)Wr-E%&M8+Ml(LOAGy_sgW=bLnGA@h z6E?y;`#(_(Z{=B_8)x^C8M(=10CNejN;Byj919uyja)0PGZKWyjOR6hD($;!%ZgT- zPk)o5;CwsaID{woH;QlZ`FiuHc#qZpd z%gOaHOYxAel0IjG_CDf86}z*1h-!oo6Xi)KG{IW0M5TB~-&Ja1;p&r7EQ|C$0m55K z#^)9CJ(cm=yXw-#GrupV9axF}h7pRRBuu;4{O!Y!usLTKS4@Ejww$msSNGnpyd1 zt%p6$&#lpbHcqvkqNwX zLJ{aM**$I4JfbHAZ5w2vr)71dw%Qkn+l*hqP$}9E-Q+A9WT_?SOhBQ0bJewoW>DB- zV@ms0!4fYY44qeHZuy71J7j0J$xG_uyI@nD2Q5Z~_|$Hhr{IdMh}5FOd1SN1J|4%@ zL4UZw^Ix(H^M@~8ewsgA+;ECNJV#!or_i;Vu9dTe@D%CeKxGwEa$d@{vyLv9J8j=r z!0;T9dpR~LRbw|zI3BWsCVjKl++}m!HGGC2HpSg%i{31Lcr$(b3ZZ^wQgUnYDZYH$ z$KLum=0F#SVZ8sYB}qPyTj1d8;-t{;Ep}kAewd( z5o(Owf(V%nfd`|V# zl`#osxN3eV-8NyR50;J~__qJEFv-j|GnHs#GCLVbYXOLjNZ|;@VM~zNSYY%sa6%VY zOTH5(6@2iZW|X|xMi0xD_3`PHe$(CMER%8{xUC{r3j{m7^xl$K8@7!AK&1@jWbHn*@CFm-rP5~Jchw#4J{ad!q2ny{9UDWbs(*>V2 zoCCv$^Q8HLJDi_K_iMr*hW4w`-LGrR*#yzH`}J;K!hW3xHu!(`>)5$yTqieO{t3I) z727SJU7sxTG7bxoB{mCx@9x)pj)|1z)}m*tHVVn`#c@KU)4ywJ;?t|^n)iJ%sa_b% zOveU=K#ym89wByjdsO(UXtTM>Oc(`FvsrbmpYJN%FaQZ8Ys?(Qs6wA*>q9b5Epy71N5V(Dujd>l!P})v z%tFif`GziSy7=V%t1-sr7pG*)E_NySX!rI2>qeL8<~LozofbYl$*tZ`3z1vhFxE`H zH@5h0gORIjJywzrWF*x|4r6v+aH0bVj?qcxhwr)^xY7(@&t<;-o;-v)M&uJpft#d+ zwJaDQ?7Y;>4$M`1&7DfCUgv*gJW(bSh&~EV| zIGiUU8~JJJXYn+P^ZL*tKg@LfVk6RayZWncn z8AWVdH+6~R%?0zU#AfMPw1muA+$bWe46_J`idJe@O${s%QUK*#S?yvNU%yRhXFhn) z!qn3MwIdX9bjFSKY0&sz{R?arp3rVKs52+feusJXZT4g+2>07O!U8Tr&Yc_BlFcFn z*5~l|NP7zAAXsou&n!p|jXly%(j@zsRY2fmn;vw{Ze~;#UBubWn1^ui5KZ^2;7i73 zazm2~0agI0nAyd(+BVmt@P3M51wg0;6cBO#6&1?DZe=~L#(IOQT6LuA`H;run0vEP z>_*HZSiSC>w0eJ=Ygg~`GvUn0>8hi;k4r8k3b{tZg)E)v#Q9sc%WQbd z9#P}1M3PeDylhXFn{GE=?a$@HI3L2K77PBwLQCRLjVST9i>4 zctVFK@PzoDbx%yRzcsmtm)O0+9uSQCCD8O{`5(yFx4;u(v;$8}uz&OH-$MPp_h$Y| z85@DTz(`y${b~@P2(5i3%$AOjFy@?mcd4V|l)-Ry{t!TnEgo}P3^V}FWuyC3H>kNa zXzYhHJ%3+ZY6XdW1*@zS)@AlPKDd?7 zbSv-pGL`-6bW=*h7=p+jX-GNx9=9Phb`#0CzM;!;Pa4VvTYdcftXBQy;qeC*C8;wq zf0u)jAt>yosiZIl%dt2x2g8^wD|Es5J!l$mu_O>t0^_T#wXoGecVZ*Y2;fGgC_tKi z0zJfJC@LNGE&AH81ws)iqq}}UTVYPYah}aMH}d%UZaw-=tqi}U<;7s9KDpXdhX@R2 zZ5LdlwrAqewQ$$I+Qq%662!oa;SUNEU)t!l(CyV`+-wNhR;99(-y^ygUyqd9IcmeldV8>g+Z%XZ<1sA?WV&@SKZz?Qo0{NOUB<|RODV`K@DVz2 zt_u2fGb@9B-9}8VX9oScok%sJLN)T3K|<()#$PSRQ8DLXRpUtDdv_4$d;cuG^!BCh z2>2`c89EI^CcW1PQ0?jcZ2h!^4T2`1r6w9{S?6Q7ISk`!(%t}I6DXdIatjVWNN9G( z&ldBy&$LsaKABT2K|zBIvh-smKccD*w49KZ(LHGvtKh$7fO|I}6oNs@^LE7=O@xWh z8KB|ktyE{14Rr9vKabdpoI(tAlP)3|lcM3O)@YCQys1Q@P`eO`ep2L_V=risC(C*hRW=!9EgOx4r#m^brce6e{2RRi|FVxzfl1l_p9_!7i``R-mA zr24wnbML2zgFHBgh&pn=**ZtUYVc1i-hpgK%)*zFO{u36S#>jS zRd=KszD5lT(|j!}xgo=x4O@>`-Qu84$qi%7d8)cuFe&5#Kb&Gtu`dMJaJ=R4LWV>X zoCxvW@!Ly-<>O;ocVJZ_Da+0QjGJoQyA`8Gmd=W;0hh~4uXp<@-Tc+*m8S6bY@Tfx zyLDZK|I>E;9LHk`4u@z`aRg2%qdwjI`9LJjr^Vqee02|!r#a}3SoG1-$+4O`YnT}x zsSaqZl|?t_yIwHntbHj-B^?czVMJ?VYiha= zV)&mYxRSv1Fm)CuQv$8eG0sRja`t9uU9CofyN$A+!)GpfhEQ2{VTP8nG&Xd>sTdCy zd#eeFwGtiU=AgbwXX>FnI{JjsL$(zpu9kvX$gjAfRTmWJ%f>eAQO%isB>v2*Ip4Nv z)(5j{T2dZ2@zQBfAfzOimb4m-cfI2mgi0kii+2xl*3dbT7bEa1DfH&^ny0b;=g8n>B4U(^+CQ-HER+n+u9 z`7S?kKG%n$@Kw%BZluflWKgz^CB{S~8PTTVMlGrDKQvFor#&?h`RNobMUKf7%oe_6vkWqd_@ctux-a0@|d=3QrD zjLB-{iw(0^;@x!j6(Ftx!l8Sgx%*F}i z&47x%2lVrR(n@-}j=poWdmiKOVr4}v`fquG=){|sq>(hyXKjmIQ(Bo0kKcF*IzyS_ z{*lQ>?ZnnTOU7@>>rs`TbqV%sS1Cg)oUEj5KvV+=RB| zYrA%v8+fSCmQ;cjf9h_&sN#(*i`GslQ#V=SUbWv|NVGf5gSx|DT zU!6#Q+*d_aFKVkwurN>9QJ3@%uAQv$Dbt>7HcwMDgEc!=s9 zBQn2)xM%xDIqdfE0=cjM2Qnc@GE>w5EMqXffx9h)M?q-fb|t?D!61gbvAO&*l-$ZE@qE>lex?Om*(ctFiQ85A<54Iq$!$B#uC% zT|4Q~uK{8j249&M?KbGxmv4oi->-!uy3U{(Pc>u%W1vw+O0MU(pKR?o)2(Pt*^PDh za*BPKK2J^1Z?$UxkmugTLJm~aqh?bHLbX{-*(=N>l>0~hd*XQtvtsgbwxLo#ja!h#YgfhLHAELtJCi6M4DC$dpI0O~Z;#5& z|7(XXh{WKt-^ceyS^SD0c!-5=$VNemybA9H3q(TaN{oK5dmM79;L5UG(z4Pl|C1|B zKb=<05#T7obO!sfyDZMqyJK@_QSjFQvSN<9<}qf+)L`nEU7bYjYcyfbsGLwifOk() zpcXsLtIyIjF+=RGa-M6BUrw5&`WY@S82^Dak`%t|Q z*=y7eE^ip*W*B6<Tumtj}v5KN%3$2AmdcuCV`P@LqCP zgn0Ds#}diCaOQu03iMjk4eutJXs$~W*+u>987wNpr%Oyfdxj6@UEi-!#S)mxwG0yN zD9a#q^eH+rS#;iRo-c+Ns-N2WfR{r6KWM;k#dDaR|{liLL<#5O%-oi;i@7`@~xirGg+|g!D2tq!$l+!s8|XfLTnI zp;K164?1$2se6x8O5i^qQF#;#8IdPi4Md20A`9#5BsR@9lOED(-p1L#Hw7A zr`rfm2T`pFH=KjTycfUjZZcp!*JVLdC+j@;gihyw2Yl5ax!dK)Ye-?^b-QgzOA#k@s~P_tSBNH8!qO6doGAG;Rb(m z1IU=l-&^R#xnTPb^8bGR-v`lhAZTwOJPB1$-5AZx-N#~IpQl+C#>KvVPqRcG^0}3y zu{8b`2?Pz<3c8EsV%pZPbHTUh;Ml!lL!}q!i^we_3sIfVU0^YxF2ar^`)&TL6-g^9#8K1t_5t=tbtcAn9a+h@ahG@D+}Mu6+dDR`P^kn$gJh~ zTE**yE_QiSg$#0eQyYC`;&`D2mS{9bTvfdHu}MdKZ#tGUV7TiSQUd_tc@(wS3}gck zDxY#j0P+(3)m@Dq(oKYQOE_SaX8bD5YLI~{^0O}==$>8;?y)dAjs%0~k~FF`Fd|eG z@oalIM<7q|uHjQ9?}3^|*QeJw&&?WkGD15=ur2DRSdKl{k(;UYFMJK%0t^e*K>I_N zk+Rvj+O&|qEP{3}8|ooP(DcS(*G#6^tOg60(&6p0u~Y^(!m6?4U-n6HXDWYTH_Uug z6tm23l%CVP{R`GSqdr9>(B^^o(_wM92z}^lnxyfpzX>X?a@0abU<7tZ_ zfNRIs-dak?0+gS}%pW?edv_5W$cb)UZ0Q+M1RK*>M&S<_+F7%Kxwp3}&MfG9h?Yqp z4P07Az%0`|@iL*D;v}BKsJH1c>g`dynWEv8>IgdrSu-Fhcvd8iCc$Wi(4AIFgd5JD zG!EU8ndAz=9~2#mG(FvX>5b&12rseQ^lY}A#I>BE-||zde1;P(>+!EDO!AF1Rj(z3 z0(_Vy#BYkd{l1GNWPGQC^~PG@jiX_*Y3(ydyL2exSyj8(_@^-*s5vy)nK*7#zYUue z(TL^MME7672+BCd+-djaTxyR}e(QIy2Ve|r;V41J^f}LqxZ}QZiN{vCe)`uyR&o(t zn9!&&OJXg(WTuIdI4Mty#M#eHS}7vOO)(Hh=p>)wl4*jU6XNd*LqXWHo4TRTTJq?t zakX|6NX~8!*P>0J$m3p%=Z0Skn%Gfv#16KarRX>J_s}0*jvc>iX+(x?nQ<%X zHoy6uj-_>-iqMSr({~)rIEnGN3mQi=KKB$0+SrZ%%~Yp@zt?J6u69GpzCgIP2zawj zT|47}1OwTW?HdaK>HxH9OnVd(b-xKAmovY6QPW;?DbtRUz>me(wx=p;n;RExt_rIt zyjTFvoPz}Qbzo7Ot6Y&fO^Rnk$N1<6UFI_vxv{7eNoj}0)N9{)RVPNqBie3LfY89AJ*45WRzds8z!M3+XDxb^{bs@80<>)l z4x|!ha6#Xy6z4ZBukm*`hLuV+4sF(5z(GDObvx>38$Wap$vLGJt1?fw3!VoemzDso_zA17*a&Z^Uc$(K}q9-8%LQ5*m zjAb!g^D9EE!KGO&TkL#WFg;jtnD|ydkC*5~K_{q~Ja&UtrVznrY0lozxRW8dYj-fg zqv(W78mwK=S@q-C=e>w#E9+MO6K&x6ya)O}PC496b|nP~RDN}xq z<3ugoZgb^Nta6PAI?mD@nm5f zo_uN~*U3lhvtX+PU1B1^h%in2%|{S6=HRn}`p!iWWH(%{HAETRh4)&NGMYo9!zrV} zc$CM=52uXm`O$_SGVf`FIWZ9$G(M~x6(hvQ($-7Ftvt*4gb)u%!CBEvvP5sE8PCWq zNO6UGs1LhL*Cw4ZPfHP&$w9{o=P)v?XoGUrDq;;GX7%RI>MpbN@|7!@0gnN9@1}=NJhD;ZM2xir<1EmZg*+Bcie^ z%WK|#VzuimC~$RG@8NiD#SQLb7muV6{Yp0c=66a0GVj z?)cg^uoGEwNhj!RcBR5YCPY}Eb+c&WEci&2g%RBwOVXC5h#hq8HpWi{=mTgNOW1^F zbIPZ};a2b4hK-^jD6p<)4-c&03b(UQFe$pMMI;{`quVs>8p5Z}gwU z>JxLKnsAxJv?#PLir|3xj~~M^es@3&sB{G3Pjur;}@T;q7PWCa;RN$<8 ze1YVlZ)A(1)g+}gU-!2U?fD*#R0-GTMpxT>|FCPJ+puTYyHGs*&vdb4@s%izf0 zZgS-@x10x-tY6uBixAUkKLRl!O>dLN7u$DF^MxP;9#VXH5Y!XY&G4>;CX$6VToNiH zMbtaYfMu(_lESz7&JAzrWFgF=TUkbz$Ns~cD#wlSG`9_r$$A8K(}G306F2zO)>O^seu92fHJ}r8jmbd759;VvmTU{i6Jc z(?x=cmNz|a26J!sbvo|}`XhmUP5Wh5L`aI`!=X(q!l6|W#Sd^Q4w#?)JnEEuIg~wJ zC;KjP8V?Amf~XUSLk#1_R@G6Dz%={J$Ir{hH#6C{0wl++fLb3j7ty=KcRN5e5aQuIFdmh0YEkpFQf zyaL?wPGG8?`c*3iERFPO3Pg_T&oM=>;`@HHdKQ*#&^BG7ZPL^P-WK~&UkzJ%r;%v! zJ+SaSO4^x0gj|W2;#_bD>ACK4Rld#1Z5b-Cxw^d~Wco+!}XFIxH&Wb#= zHUeNV<&CG=BRxlQaIIC_0NNY2vChhw+yJAJo$On{4RsAYt!_qFi*0!1xXWidBS3r! zs+o!xSPb6_p--W8*@o7o)z!LG)mf!WbjMse=yctW1ZqWBDD)XRzqs1H#ozdsMCYAW zW^kHAn1SaKjQT4&Eow{TQtWm-9=e*i@6Oe+sWx0%ZSKD*CXAR8*D&EZhe^KGE`0kh zd;13^q6*xw#VhnGunOcd!~NJR;MG#6nKsSKkV5J*XpgI%3B- zQx%<+q399Be|1I0krpIKQat68*uThKKIX{D7}|^IX1h@3JSW$I3#o5Ox2s8p7}a0gYnSK?KUl^0xYa#dH=b- zK?V|yGv7ll!{CEjOY=$@t4QA9zo!A|58oV+0b0`a)@s7McBae0Vjg53=K?1Bg?={l zq3nNhfza6hd_K|s$FdH-tTo%!iMG)5g#lci5avs+>1@s8wa~}y`Zr#?BvLltaqRcg z0m;uzQHh_sSU*O5at0Yv7ZPq-#i#td|7RaFrFH} zP%cN$Fzte>ob_K(If#!q+$CZgGmV555T)%JK3llx#%9X)6bJ)75+wZ<`b+(qx zMhoCfSG(J0)_-|Gq7(2%c_qG35z{_@Uyio;9rJ~M$w9~61lD8el!WC~{I+-_c@1&5 z`POr21YIMhx}7})1MD=J0~Qxu>EEhwc1fgOd)`{ZR15|i`<|}P5eZ=(zu>#%@&)b( z_F?~Ng3kaf?2S=hT$+_S5OI5~Q!{i6a&-&jdFS4O$kF}R>i_F5*d>X2od53D<5E5b z%5vaV%W?x{69U+{mE}9TI!1JHV>-&T7)dsmKC02*2wYG6UIbj5$Eht??JOYPM3!5_ zmHtCBdb9nv<|fhd(eA*U31_ths`HO_oxk0G>qK7W0nLB(xJ6)Q&S~xy0H$}1h{5!e z!E^MnZYRY}`6vg!&dAVTH01=Easy2h0!?}5zcrtD*yd)r;`V+Q@L_>kE`QSin&y^2 z1Jp*=PpURWGvgqdmC_EsTCOsbJu%f6WhPy(b7Otb-wo8}1Zr~wwG#rhdBwH)4QCbC zPE@eX>hOyE;m)gp+WguZ+MVh7MQ;Y?T|M5l$R+rQddIHoo}8rR z6TtGJGb~km29BD^<+)CIE_h;jYM?yNRWjl}sTd&*ha6uHB+6fPnHA{8S3uEVR&Gh> zvO7w4FZ)`_+zHFM<9KP;#UCarQ<0*n<@u^g_?7ZpUd)}4+D_FJ939K^@evylI^X{> zQMsMk2?gEG+`M653sN+;5d|qX^xnoQo5mbA)R~@F^d^(dV>$nop}k^I841z}$u50tY5P1Pu0O5&<+SW5$;>OA##^u3^fI0BiP=8F?!v2eYP> zT${Hdt)%nLbWBGJ2Apg2tDU0M&Km1?GiOO;2)o18OOo%(bvkUybcL`W^YeYssFAm(r3d@;R^Sci1+DLO> zb=WQheSk4AK=fThkA8@i&$hHJJ8MOH$z2mp-k3BxPREK-%P5k2XKG+ZZf#&jo;$_u zr@B+r`Qnhmqc5=wxWt*88_YSQY2D0$+PRA;gCvC&kjt_3Xm~!JJ}=ClH3ms zBg1#3nTOuzDo2i*;#&;6^LOx>JD*c+t}czc^J`X3hUU5Y&g6Fg_8jxbdmn}?ahs|y zJ%YRnE6lf21i1`bf^C$kC%f0Ud}d5DpRrWTVa!+_;{=qd9G-WUN^MwL z35GExh~^Pg?lZro@jzkd5=c?b@i^$7WGB(X&wq$9xmhj5PmLpB82<#fnx{5wYY*!y9AMKcVV7je{Ubg=wB~+Ta zOT_3iJSrZ>wP^)!^LqRHDc1$lia}`u{JW;obpC~_w`+S(N+o8#sU5HuX4LB$#Pgj% z*j8#eDSffStlf40Nld~Nr$bAQ)F4ncr7FC9CLiv-gWZ@jrN(@h5`ig!#glb( zJRA&w-j(b}^`sCm=Y`y<)RjRapbKV(K}E z_F9!i#&xHc0qL@YmrpkL$@F{9RGD{H;g4)aYhI+_BhCoHdQFGdh~9uXo@~ygp>Ww` zGviUa)4@48X4?VxTz`{Lbf$Z(d!7A#uFm~Pc`n{NheU38GhYseWtmR$r&*bv=009R z4ec{G(`F>v`qkWxTTzC$hVLPmPf5Qrqa7AEbtfOlJsdjCvt^glz2;9zWWC=0r|i-E z4Bvx_>D`qW24n-1vV(JT%th{ydYkDYkc*MySNMVJmu=J2B8yt7T5HTlUdc^$!;ZK$ zKX_M@8PWR%jd%{AKz=m$lz0ak3R_-VX&c{Ti)8d(7#)8hth1uQ&YcPwY99QWZV_{k z@JbTxxl?eG53iVP&i@t5JeOrY?7!tOvejhseI1C3!xDA>i7|nhbt4t^Pvu`!yXBK* zhrP=AaLu1J5>N94{&C8u;Gj0Eq~Ei4j2_jfo4SieD{P~KYV-jbtv0i>aG9S%BECPe z&QclUC;6W7?*(|a${W@!!j=nDX9zVIJ*GH2UE z>}ejW@6%Op#po(CZM2pnx#5>AMU~lB$WqumaY`qIhlQv4`~1+2g$VDnGj4f^H=52H z@3^O$zDV)uJ+kZ3!Tpp2;@+-RlKma*@E&xp z7ln7IYI!!hZXGjww6J(=$7T2u;{{IOeY<((8}<@@GQ7sqw%XiEs2&YI#|}Qt{I!_9 zC>+gRc=;pJ2J{c7<1DQJ&)t4jGAX=ad)l{)TRY$vqCok`-+(?C%&Y+ zDcxxY_&NRC|4a(NPg4xev65&e=8~P95l;8c>_Dvoo7mHZY=1>o$sg`H&#B2Q`CZd# zPJ6))p@d-CH-r$5wF@C+Q6bbt50c-LmG3+L_cKy=Y#&G^$75r9ecHm%=$Dg_+?Q-` zA`4wA9`^%8mLFBJ%X9x`rW&$C8c?%Bli%d9Nzhi4#t>ywwcs$B%g_)W302a;DQ0j2 zvZvD)g9dZ?6)J(xgoZw)Wbd*u)nx9wrPYopv~Qk9SmTb+-$;bKUlscX?;L5iss4GP zS7@W!WbC20xtUHo(wBnm8Uv0xX%AGIv#A(fk!Fswn_NQw&YZxCv|in8bK^*NJMCUT z66;9HMGH))T?N1at;fD?Z)C4P12HHC6FtrM@&KFoE?lh8g4tci5#8%dfeg6Bg5r{a zJIAism$VuYh1tbj4wY7#SNNBANlB}ny*1{j-d=@As4cbvwc(+JV%PI%TCQ_qplA_>IMJ$fkRJ8z`>N~s2Sv;}0 zsc?CYznviY;qf;gt4S&k-jGw$RJiPe8*1fy_kDV%D;VIV#8r$4HLFjQXCA7%>*9)} zmz(cjgkV$yF*O$MHC#}#G}D*nU&3wMYrdshz1Q5rfa6$UhGq^DUcrJ9_~H4WqeOmq z0S6A+xU|}we+8HSdYekw3XLQbyzzwc7r5moSDOzfpHRNWDJv`~o9Zhsdd=T9sy^q7 zN8k56wEgHiqdVuBLmZ>8&MC~nsjF=2sCnV#6W45)&Td|f@%{d={GpdmG=Fx0CS`?C zi-D$zp;V`dSUQ+a7}i&tS~Cqp+@lY zU8ZpVAfh}w6C^z#pK3RZ*C7Na=J!OlDB|$r%NAIfZR)gm6Kom_2(tErY5DWmJG`NfEi>R z(e#46XH}tASv+z1B*juH%Of#CntL#K@VDipcEA+f$T^we@5nD%JaO5(ysyRfh7;_+ zHIGx8&;KVTU4Mi1Hv@zZ^#*9lZ~d}xc1SDe%Lep~YE3OoTHPysGZ_oLW-K8g>q`S? z1INvUvl3 z0t}?G6cv~^@H<&ovm&!R^acjP{342k3*X9sENlOuGaOUI%nJPN`zwWjPf%SJ9v!&a6R6i?>d|&*WIA{n?#Rc_Q)ivhN z@-Oio1S@h9iVGX^Dm`0LYbwoxuyRHD(qFkbDQz|Vn8wQ(@~+SqiAqpYrR_s^wRB+& zTq=L3(|`02XB|2E)|x-7Qs_0u*Hdjujw|oxK|pW@VB&1{ueJ6P?TznX=!a@JpN4HT zRWl-BH>y6n^+%fIcX%8=$=iRzBpV}>WM)dFLsVnUcb$F`28L_ue zw>|?T6{r_0Bw3AeelHj#>uzz?M9;l1FlxnYYgDu!=i0o~PC(GDB^jO;zveeRyQMt4 z;V$41DYUT_9Y|{^^shp+b+I!qOSI2h4QC<~O(&{7!Kxu)7YzDtZ#e=3;wvM?9jSd6 z43?Bp$YuWbxtYC_Ia-3&|ZcoBIkpbXNUp! z9=^ukmaidu50^0H|3dx~t_6JClS&t%1I$h?)NKB-bnQW|zbP$=#45|v%$y|jnPq9b zB#3IM1)b)%yxUWMW9xqH`joX9giGkBI!R?4vt~GD+0E^q<{xSHGR5h0@Us)1jMGNQ zF!20=VWp143 zA(xa$lc)1BaE|%8%Us=bI@Ct+7ASYnL_ZIkC?IN_S*HfF_x}lvQ2&ef00?NxkQ@)DS$)yk@@V zhPKeQ2GV6Vx+TqjPzh;@cU^}Z}F zNRy3ly^mS)aBP-pY&=De~A3P z=^r?8io~d!suxd9rIh>jsZxG+q^lZm7>hjf0qvlj7|k%+d-E8Ay*r1@czz}lO!<4G z1k*nX5(yx?B|T=#ZkO<=U)Xx)gG}u_+6+`Y&P^xE3z#6_-2mMH_iR%jhkdD-<~iOC zL9)BoPUbj`s>D`6>a)=KLGPx(qD@#OJ>yy>g?-P2eVg3B6xxJ$2*7;je}BwQHV~9~ zvSt%HgHI1hql|3vNlm&^Ev}P7?kcnH*X+ieg>mxNg_J9FDju&(>-r*L!5Dqr3j~OU z-Rw7wJSiC1qK&$mYGyWA*@gnzY>w@R)@(O@|K)67g-P7$KC#FrAt>Odlh z9yF7m25*%22>B0PxZqqopeaCq>o5M$!Y~;MSlEm@1k;j3=uu;P9v+{CFZ8V~ZL3E4 z=S)rZ&zX`E8jtcl_BxZ-DZIu-{TYscnCEV*vUdahc}hPD_sWPcJig89>W^RjQMjbT z(;{Z9KDllr1W8>Ie-s7sAPbdAcifb-^o<2p7+CzY;y$5H@S15URB5=sH`LO?F3H&|Z?R)44pOqs(rnziBco zAbLykJ}U5uW0|vvI#5DG-#Hwumg!S`r?*U>>Khx`f%If{AT)+B@FV>o1PbV>}Ys|4)D>|xU z#8U2`87H{B%WPWhQp^88-xI0#(r3{(KcJ>evYOayUOGqAXUvwtW!c28;56sn)>v%o z<*##Fv+6cbyV^{jn0R6ReUpb`BSYeVEVCg@bDU#rFaFVQvunW3(-a-(09kFPW6}uN zAGHmFd}p>f{Ra%Al*nOyN}YwwL6tBKz8suk&znq~q|Pq-^s>#zT|cqJ@C)Z1LHG=yr z*$J-3PJG_z?MV2m>z3SpJ&X0_tE@VElr4&)|IQn&Ou*htmwcC#khIk|Gu9XZih8{0 z2oU8I+y=9W1Z>W_-?o!nCfX!&v`$!f9mPZLqJN3eL>9703mG%jQXHSfrf#Kc6~G~u z$5>pfAt~lDC~=nIo)r-uXfSQHrIue3s?9X5nTiE%0h0|cQ&T_bhAINgRGXWh6PcSO zxzyR*b|vwZvy7!`6&2d)t}J)0b^>LYfu^+Dz~U?kNwSja#A3BxD_DPJ6OEuRTE}T3 zQcA#kKPs9v#|2Fq^4A>SK*5FyYmQq`k+bHwg%w$Aj%V`S)3OBH63|uzx_Q=B@Eix% zJnN?F1w2x$L;){M`%`Qy-U#;x8drx4L*tH?F5#{x`NqXLEu2-NP4FEoX>Z7pz;*`} z&n++Y&z%|WeTm zf)x)@t;74!BsPjng7d;Jsuq)eQO!h7RmD0HLXLM`z}Fm{ldNFm=XVCIWoq$?nZ6r~ z=a%|v*aZnM8?FqttfVHeUJ*PzTWm4U7W*<52;$WE>GV$EKEXJ6n#bv4dGD{RGL2~6 zdefrsm3yc@>-wPYAtDui__R~;$eKUW$JLQOaiAee$ZL80%aRm@D{EYk6g3h*>V1Ui zm2%}O)|tDnvDedEQ*@-Pdf2*p*F|T67NQNva7z3*>&9_vYxE!2`$D*h&1_ul4*7M; zI&)_^+u_~M@E1>7mV;!q&R*&0K%DYfj$Mzy+|s~`ne6(R^@YaS`C+)ekWC4c&oX;| z%D$A(0^GV2b_PCt+TZvBi-RN+Hl((bW31}-uyzbtdjanS+G#{};kME2nyNL`*% z6sBcuxUU}l@RBvhE&gA)=6I^Ee&w3umJpb==J*Ibm##UUp?{~)lKw4RbNorVZkV{{ z_*42fZ_V+I`ZssYaSFkF`eh}7zP51Ptn zSbZy%NY`7W=r5&5rRZ;_Aw@q$Mv?vVNJsXhWlqs(n9vK{e0Ae^x3S|>Xx^@=#fIL4 zwx#+}45Yu(ECT3So|c^_bDvrMU5PIv9>R^w1nN-_PyL6>J&BpsJggO9wVA>!P(uXE z3hS<*6S#yJ){PM{{=TURYaz4|E~N84^@Ww@_Seug?aWrx8(%prsIrA#4X7#!R_vS? z+_IXrmS$x>+#`pRRG0mtK0@%4h~sYQ1Wyq!#=g9sA~uX?zYJveSVnfUF0!-Ny?k-D z<}N|7{tg$B4V_g|a9gYBqBfWMmBm}8dnKcvBB%?WE-xg5qVQGDLt76^L{(itOimlF zt$|LLd8u_9%C1kTF*E*dZ@G}#B&k*@ATw%6QRvWWa}}yXTX+okrX{hjjMo!f|XIH~1c>3fs~oNk;F)W&c26!2sew|FMxPP9fX@sdMe}OAEbVz_VqqXUh(Y3uHP; zV-h;h7||--#fV5BPgnyE^C7eIyVe5(HYdwjIMuhPrD;jS?Zrz=eb|SX&*P%Xl1#U; z8B2ui_Gmj+LdZ(!46TEkf)~dPSq=;7srv|wCe8}y7cNQrarEtTo0f!fXx!&9XVYaz z>690zS0s&WTEcymU0TtvOK&i*|A%|18LEiGiY!BDDMS|RdL-mwPXmPP1oHzRjbya( z!gLH>l1zZ_aT=J85t{*1W;+m|GB_vAG;R4XY@TV$s*C^5&j*X!}cdA?aayX_hy?LTg5PE>E}HAGgCjy?9Vj)EYZ)CaU%{mIZ<|C zeraU~6ROQiXEFb%vZa1@t0U_1R^}e4*i&?bK)cmaPSqVg9F`o$tivnJY0Y6jC zo`~n=JeJD~^U#Nf!_}061D@HBQz``p@|Snb2VBRJ&+^2mN12{0NyQdGKS#>C2WQ3kSxa2R}v>+0o~-L8Jh z%BibTx?+A0V@F4rXpQY#)NCD`fe;I}(%+Pu)Nr~y@E=189k<>*U@p9IS`f3mM^y>5Pn@1&mTA=ach zjnTO*p(QY|k~q>(UKOm(L2*4cZIFA~OgxBc^WIpH3Avzmn+E}zb^30Nqi<)HIg%~YaU$RO4c!^jepw-ssK5bXRuqL`e2J%s5Cpq zXmKJ>ks+?y%`)wyBOE^|?AS@xrPEj43jo+)%Vb&t<8Y4la4I>lna(fuE<}2d;oS~s zd-p*vkV{I5k^{b`;p>9Y~hf!>5nAKjRupo$L(hFjd%E0s~=JcPXM8z;sQ;UE6g;R;C#S)f1P&PAAHY-pzJ5W{`D4Q=!i&9Qa z#L~jwG#g6@mBadX`RwrcZ3I^LH&xn4Ae{R+-#*TFA7yXxg;!!y{VgY8<~c9fL$I*g zOvs5p1p6b0fPwoBnYi?a0KBs?!kb;R$Fhlc(zU|SsQ-^)4G%xDgW_@c0E5+BFFY;<{N7*bbi+RHgxwY6{ zOHuP_nIa3MVM)a1r49=^(`;wBK&BzG?DJoREL&7YYd96dze;n6 zmwfBzpAewl?J~c37s|DU3s;<7Dkc0#XOccId@$*Jg4onp-&;eCt?9ydO?`66Z|3KSO=t1ixEjk7-w(jSq!vy>E~P4+RuIg<%=$3em9lVi1jx6C3PY zn+emDe3L1E^LF)i!pS(y9jo-zr!Z*`o#wVGAcyON+4yJp$9J!l5w!e(S)KB<-~6Qe z$sJjNDjn<1--h>J+?-44owYfQmtMkJK7A`|37a=uY@V+{>B{8n;;X-pU*?Iwd3@CL zXMxIH1!5;E&1^2hVy4q7EsOQu)0Q#38irDu8?&gH)W2vwiea>(6VjdW+~gdXELUB9 z_5DKX7+n|{(E3KN0_h=?^86u-#1+2;DKk`&llc-J;3&=ZZzh;2uE^OWrwV^pRq^aA zL$?-RqT@5zzxa~F{0(Il&mJ8-sW_Au%&P4*GnRX(bSO8cqy;nJ*v*LRH4YD53)xb9el#`&oO0ODW0$AZz|$irZ`VtSN2FaIXeD2!0XyWLwyd8ADSM@ z@EG3&dwLCH{^nCU(y=OrW;_+(SGcJItuW|q*|SiG7Bf7*Gc9zg@vp|E5FWLr>Hp~h z#CO^FECRx`v?^A~+w{$+z1D(*v^eGq}=2M!rU&>=xNTi{8a=tSo%($T(BNycrKfW)?(d4voyrjLaMonTb&%H!?F% zk#RFeM`o5rX68p`4s+9;N9JD>nIFJpadTv5O=RYkk(m=BGjAin779Wvh)qSv4WM`4 zW-r_|PjA%5A=o`0tS$NRAVP+N-zYkW(tbDY6XQ*#P2@0tlDs_2Ujy-5OR5hC%fjrn!>Vd!LsUfn4rLVuu)(yq1}D zl_JFN^2XIqvyn(@nHG{4r&~R=T1cZ4a5HP z?RJ#!1+OTc7YLqXM~8*ssL?@w*eRrU?b4|#ANuM}+5xyUb@w`Ne2U}EDxQ}IrgFt+ zbL@X>hc{j=N>_Zdq#Uh++)uCwhPc+JH8dc6u2n*0rr88Y>Kku-XB4Irgn2~n;F-d4 zB6{YHgitMCNawXVv)bm`zcbrr^Ov24rpDZJ|EHXPY$C z;)xT2=bKLgOqD2i6Hvwxu}#U{At8m_4mgDEi;-pv*?lLOGHmCW&L}n$BSHgEF+4Ky z=E%gF@I4Tj`VU!(;)(geJ8ZezBHY(bSZ{gWx6?DiW7d zu|xI;oJ-?(bWU-utx1?pT9N)CkcH*@aTerqA9@OpySaB{TusTmn-_3i0aOLBXyxRa%#-qWNMzzQ&JJ8ut+gn!VI*ZDYfE)3Jb~_8 zK`{jIHe9FI4RY0u4RYW(>o{_u_WGI#HS2q75p6NUEFW0;Zf8E@xg&WWxj=ArWKMC&ws;PE@qkzK7h8kH(<1 z&`3zefF+;ek>wV5KcChV-v3#+DI>$S2%kVb+nW2?agCkY%0uMpXNc_EAgB~_4_A8;(vkb){ccytHyk;Zj$VO@RLzwonYS=<80 zZ6}sr7^)BdkKmFK9q)q8?I&C}1if;8@G5Ltev!-BNm}9(^ATq8H3#FxbFTws4*Z@4 zZZW@MojFBMa>fnCR+XI=%5AnrR|rvBtZ(?IcA)OZ3`S1N6=tm4Na!ka8NV=QL%G`F z1Czapa)lN;8#G3C(*@(p;&ur%t4L^JFeh%;g}C9U)+g4-ElM3tA#^hLlEUZAoskw~ zG(rG7n(XjT^&1t*P!BE7NlWXUHYN>&f$liShy1-D0=mPbHGE3PZiaj(TB>0Xz!lRm z@vt@!p(JA+7pJ2_Xo4lz3JEiIlNK$*-J&F|vd|^Ax*Vxc{JtbE1M#sM}BV{rF`=t#2FH89ry&oC}H<`&8 zLkyw0K?Bj4iw?GF=OngEfK|GpEMogTc5R3hNnIBU*2Hq#HJL!TiW3$1!<#-2H-8S= zSrCwoD!f5mk~}Y5HxyB;=*=rohP)Y`XXP&M*tXzw0U-VE6qHFWRFgm@RNCSi>%Z@- ztp7X|(JqBLIXq9HtWR*@dUVWJznlkP92%0~sI>;{G0RcEH$fYVeE)1MIX5RkrmeL> zs46ml`-mRzJ*qql(bPSC7m`8BN&v z6I`m**Zq8g20?)Gw!(2YJLOzTYbjEOOW*uW(aZrEe25BMF0Jyn#BOFM-n9sKYWo^O zaLH3$$P&)O+Vm2D!~1(PlD_VS%h(gkaR-pm;%*WV@6ABT;#Rl`o~6khOaX(Dg!(J~ zrjr3Pt}BQqqy;ZCKP%I^d56exIjU0k$U~1Qqqlnxp!xlqELr19twHEoPo+i>bJ|8R zEYb3Xl_n3_pC5$bo%O0tH(Zd`KI!r?3(d-LD6J7|7n-Md7t8g|G86oTc$0;$TT0vQ zQlf_T;{;-Xu{OXeINJ#P{$a)uj+3eT-#8qxsE>PMG&7H7exq|tDPr>rZokqj3&otcap#oRP5EwT#}=qhJ;=bOW;LX-6pF%rysR9j`jjk zyJe}HVTP_^J)=63)Reft?>xbq4H^I~I7PNM!hJjG2HUuId#3HjSu6g6G=Bxm#`QC@ z2yhqi0yT(&wyaAJ$Z1jIL`PB_LkvL!8SWulXn}(tu>FgWstY2e*{~dyDQN9fc}9lM zm%f4Uc`hcR#xtYQJdrC3C!dBZX*eS)N{+{pK&tPJ2l(#a>g>w!oSy6#a~rP_o=9P~ z%N#+s>~_{{@u8G^E6w9S0x>6bn42DFB`jYWJKwRql%1(dETZL276z9oA$GT}1m0d* z5N(plv#GBWBXptk?tJ65$`#xnrU4*dMpr^XhW~P;7?c_rUVR7$a z9_0<<^4W0MK0-hGiNW4-F$^~8`~7PIX2Giv691ZL-O8Van;_zOG`5q$yEjOg%g2e% zh``9+nw$#MS^j#`^uV^KihOhD+3c(#hqV20l>U_&x+r#~mV<~8^MQgpr?zr)Ky5Fr zTPrJv_GHgbr%>Qnt%=!4d0UbiuDWH9%D1XLuINb}6U%FsQ(O)eBr87g8y?^1{e^G@MX%+g4`R7=%r89!(d0q_RTlS_E#m}s3 zF=Jl;IR1_)wu!xiBmcN?Keb{Pg>TuD2GwshFH$i)_qw#;>t-M&VQBxn*D|ylfHXzZ zVvX-K{h{qo`wwota$a8Xm{#es;OW9cwQzt#d1BATzg$8t7QDNV5W0~srg%2 ze6}Sw-XYJ9nF(~r_L=RF38N_^+)PwMQ-sm|7|UYVjx8qSxiYe1rM>#H33S#KS4aw~mmlY;zGO zN6hD3GLj3B5zVvBNu(xnIx1@xZiT7_6fx(j)K1kd?*x}*lG#Q2KTr4kcI?{9nvRVW zKD)bcUlq1E`i6|c!!fsH9rab(s@Mx&Rr743pU`hnr^&`sBkIxkp0o|GPe$8d{iXxS z9coDoVO~w8ZQCih(OyAUzPhsL-P&GK&t39r7B}>eX=F8&ozvM$Sf=Vz`pMR*nG&q+ zQmgv=X(myw-zG?Pwp)ozR2ZPT=j%1~avTT$^3~=EI>MLWoAB@zzI82?lUZ9cW-BML z+vOSma?9=ANC+13B%ootx$ZSI?U#MiYTAt%pM1h#aCyM0qRn5or>M|x=%ry)Qb`9`xn_ZJ?q|Bx5abAdI*-*%` z;o)0z)0)fV1(7B#Lui5d>~&8)|MK@ht~s81{*8L8o}cQf=fC!VRnM0t)boG&HPi_8 z{H4;e2Z*@qkcNJ9V2a3|nf(yQw;RN3&2N=IreRk%|FiF>=;nXOgBdZ&vzfbo?_j~M zgX8nlqh$rrS((9L!2BABM$3k3Z$6`+xU2B@U^LptgvoJ2M?Mp@x`w1RbHPA}ApHBClqfvEdqE7G8hIbjY`jRM9bCtM_uf*(1ih~x3gN>@1r|r^{ms0 z3cvHD3I}}&&yz{HW)g!bdb7DKzYt(uK{6Ovt*U}Z*${HO9onR9?!i8Yv)wNc%5(Z{ zcApphIgMzI=$+TOTH^X}+roY=Y>UXGA+Tq56>T-~Vhg7a?a$t%X^Q^U5kLFM8(yA%uLif4j7dDiFYfs4ibc*|KAMe8RM-t^bD%7v2 zsd#>-Z$%R!zx=>_F@Iz%qj>(Py1p2Vn#Wr*<+>`#AjC+yGK4U-YcrdBAHc|Ef(4)2 z90b;iO%WU^W22KvD?EmpQ`O7C+nlai;Z2#^IL+w~t_CS5Rf%s%25lu%G%CYuPlue% zE1+F{YKK;u2S56#+e=a-o9v0wjF3p_P?=oY5oRtYQDLyS!VG?eI{-kPi_WxZnyLcP z`I$0OU5pTa2qvK7w1a2kR=I~;cnI8>72)VV94{@n!DhNt`&Q$u{7#`9MsGeP#}3JD zWQTLc7L;UNhhdPL5oI-F1ll|#m}!a?$auFw2U7pM2-3p#V9vLjZZ3NB&|L*3EvGf% z4kM*MHRQosRtZTbor4WZLhg`NAxVmZ?4|QQ`6M38hBl5n$Yw3eBnUToYDOnzDlx8_ z!zTQZ2-@aldyhO4)frb(<{Tw%(^#{&Jx<5U- zZWudDBnp=WK0UxEyCd5JkK zx;#(LBGoyOC7ryMlgN_8_D6ngUs~!D`Edu2ktI14Gv{Txc!k=)U%AiCa> zb=}2?d$2<(o}Eup&T%{7nZJ6v0a zmO+;WS&Uq^A4Qy5KaU-;Y%UNpV~Yv-T^0bOX2ebaw@hB(<|ZZmT^7*KY4+zHP|K9_ zQ?6ByUSoY%pb87~l2ieA*kcHTbHqhPBFA@`zKz6OY+yFa zg{!8Q`&K^}*`LCCv!KeB)z3dq)lY37^EN*rA#LA=+;@{NYpHh0fa#T>V9BV{H0VE3 zrxPqxcKo9!5lir2(Isj>Q1iV~!EWab^teQOGEno7ee<$?qmcz_zHi^Ga?3F6^+8?) zDk{yxZXsR;YU*sEuv-XF25RoLZ*I45v>bt&`S#5$`$juXZM1CsoUXN$ftq*i_ZN9% zg$EMeLbf=WoW zLgL^l#T&J6v0ZP}z6kcguP3#*kne+Qlf?_1#VXD&ILWIppm^@k&{4H4I2*fb4NKNK zy?CSc+P(j-wndS9x@$8uJH(?p5mZctEoLW6)9#GiRS|6%@t)oK+00390aeju7I{vm z57D&(_E-9UK^z z1j>ve;g19`(dYyF*$~sN1BX~hk^ews?P}hc)3$IN{Irpu7;o0_MU z#M$`Z8jPC6Q7-12^QCDV%y5Mo8T4cbs^Kc<#V52hDI^8P;NIA9mNNPZ<;=&e&;$FE zWymyN|BiH_`oa~n!K=-mu&}$UWExnZsGWBA0-9h1B4bzGoW%E@v;irs=ymf-37Uc} zw4PxeqBUo^kPE}UT`u#(T$l^uweHTdaR*$EoMujc7Hxk7a`R{(h=NDB`urAompe_# z^M?w+#wQ%aF{|?iR?zO#y6iQDpkXu>4IdC1?z!T>MZ;Na_VBA}Kh5{R6do*2E){T&!b#zsS<-Y| zoD>3CoP34v@wGx}tzHr*ErR_Mab7s7uRU?{WW)>MR9C$B`PZ7>$D^)JLC+Yozg_WymbL8)V1o=eQ!QHlQC^U9`bg89r{0aYX{t{ zk$k}pxJxbkw>uzsW9+iz4*2k`9y?%GZR!rlHh&~aE;hoV@0LBevnlBK6W1Kg_1fZTu}8!<=`y_-wNtGEsAPDFEMXenlO*qqQsV z)ek`WntASrhxuTy9r4vK;I$dJ)T(vPG=2GjN;$@NvM!XSHEaqJLqK3Ot$lPgty#Jb zug!8gyEyysVZLV*YO&pBv39LRC%B)3O=LeBK`x37Wx5p%Lcvm))jW8cu#UUAFqZy^ zH)I;7;0pUqTR$y$hRaBX=Z+>zK&`G?s&L7~I*|#2dQ)GuP{XAb;a9chV7lc1PAO_? z*k0j#xXIZa&Gc(U0_KzPh%Q6r8L^axDr)ZGEkl2g*9>P@J#2H z-2CeaHb+Zzoj4M2Y)!-2g5>o5)?}1klUcK+3*D?D(kguiH5t>g8J{rmytI%<+aPyM z(B2hJx>M?@$xyamH6K(YBWQJ3)N+vlb79Z=cT+!>Bc0J8eb{a8Rrnl9#hQZWI5{3` z1BwNLdJ)A% zJ|;zudT)Zfarzg;t4ZlJ&Dm3&HH4oFdOL&lx1?nOsZgB(8Lvf_OOSDvOQ^|ci7b~u z!@%*{(n{|(v(IAyTTBTj&=&KTHBx|PHg*V)XYtB;M~R44r45I z$>LBf&j}|4p9&n(osQ!50)McY6KlE|@sfl#T!jBo_i=pVBF-+HCo4?`_jQXRUeD}Y zjplde2=#sS!Yq`SRhYRSe;Rl=LUD8IRV)b(vWMn>9B(^AMI50B67)1DENm#A+Zif1 zo7wrcw*~6$K6>+fG%L+R_Oe@Fy`9{+Wh+vD37BDTl#-5%MBu?O5~70=BNWke?A z6tA~z?CI{?%J>VKqZqp1J!&;A=ko`pzGJ!Hus)K6KJlnEt0XnOv)+Ctgr`Y;CRh&H z9Bjp?ok~EM{sLTs6SlI9e9wlt1>9ZGD+o!n-`uy9$IMOs^dNP1n04PGR<5>K06pOa z0ra-Uf!_z9n|UR5$fKC*pD;fFFwQbTk^3g5Dof>HkNu4Lp9q+WW(;Mm8s##Lxp?yE z;0+Elnw}GxoKv)YO2ofntjkB>WE7c@>uj`B^FKOyigQ_(a2HPW35>q^Ni}|DzEl3F zvqD1!gc#`3f$ddvn;b%_K>377Jh3%d}d!SSai)6FL_zQwO-g z;DEkV$>vYOC~6N=`S;p;pR3|8syt(ezi3Bew&0ZS6%U`yPu5__%dFH?4w5b5rvx%i z3t<)LmDV<#a7NvF^C7I1%NmKmg_mg`#G4ljq$-!-k4)D`;=7P$gsuzLXQ8(t`{P(G z{9t;J=H-CPa}ze>Z#M&8B0GR9wFWPVE|Cxm@jBxdo~S$UIHIms+%1f#>#8@VWja>9 zF_D9$WXpn^y|(J`MK-mw%`J;iQ%CTpgwuykDJT7u*Ez3=9~D`olEeL*JrPpL^w@(i zr&p(fsmHcb|FYy~W`Ybp9y3{oq=pKeu2rMAKy@w&kUdS*At!89w zzO%^-J5i}eZ7FVRa0@1jG>^?e(O`qVY7X!rqsO7)72;gT1gidBv#KDA*^` zpqua_Pb$NP$-Upbawh8Rrz#nxG8*Z|L?}TRgVV)J*pzg$jdr5WNB~&d*ZBErnU{LV zUm)sO<;CT9vzO2%IW-iDgs1T@&e#;ojD%1*+M4oE>h3VXAN_0&HKqqc5_O+V1gD7`TkB0ks z4S$a`9GXBRtg_)T@^QAqL5E6vkI^1}XL-ED<9VZGMlN`NL38Bmy|!xsgte1>Hqsyz zG|xtLX(TC{Za-mG-OAg}NJz%&WF^ zc+A4V48v;i8G;szAskt%0S-M$1LUn%gtvd?t@FYt)mG59b1Cn3^A4oysF?IoB)phs2xc3))lSo0fQmU*%K$Qpd4~dsQ1G#$NQs z5VPZ#n!teG(4-A^v+t-f-+z)7STC$3oSu1BpF$_UUu}n}$(e^j40D+~%mJ0=XSZ52 z+Dr}6em}wX8Z38rTQr(Or6Teakq@6MDM~(7Vtm52SqY!Hh_!P|m@7tqYMGAvSOqyc z-NRparJ)z26wTu{z+ZB>qS`|uF72CC%p9Z2bP1xlYe)|{#+o($V@(lBb9*!VSGPtn zQFA(U@#d#k6WwsA8_JI9S!d3E=Me$M*?g$AIa|b#tG4{@*p2F3d$(2y-E5 z##E-Com3+il2t#l;e0c2V8F%DNwX0y1CcddUuqjtC=qJaoq(OcnehMNTMl&Fp2j$S zQ!;kw9ha1h9X4kKcjESyPfBQ@xAQjNj$6m{3!z%MX*e^}1pGax12>j{SCY0Au;^=e zSqQZNs)h*FZbr|B+AS!sIkrv3H!Mk=fl7!^o4#e$6xX`mC++6usOx<)hL9Bnhn9K4 zp~jZ}2s0yO1?tMh9t^+rUK%dfGl8NVW+j`;G&og zbA%xw1-4xP{pOh#(#+p9%(~oIMR@&i~7e7xa}9{eDb+?D`lE1KsP(h0qV%|spj58)XygTFOgHD zJU9M(NyvVt32B+ozz(-J-dI|LTV<|ucaIDl@*s>7ntkg$QQiaE#-xaG8k;naM5{aE zzsJXvC2aTAKg|cM!_bYf?^~~?`iFQ^p&Tm@^P)}R8r<3=XXbM?9p`14cOxMx&@aFg*y!3qOL--@zWko0I<_x@>W?k zW(BX!Yqzm(wwGvwUWi=QC?^?K4mD#wMGF#swHwW&w%QW|(Pkq-TnL+O(?M?14-$w= zqTh46>=eE^1XE~y+9BZ$no(Nt%%{W(gRl9;vkM>=YwbkI#Cic;w*8HwY#xjd>I9#7 zvL%_bH?lBx1zc43)t^o=*sK|pG37d|%9TJWYcfWb2YDATs~%*`q}a4Y_>`?ZKjJ&g z)E0Rd8;T`D&G@nkd*YU=r-$~81@D4oMRf5A^H^?v%qAV=(P1del zgi8D1mR`Y=9a}5>*U!9R()Z49f6TXZt`+#}=MYWzgL#p+3UGJ~Hxv)z7K;)p(jV}h z&@Q?xB^Zo9B@F@o^*vC^h6!&F4xyL9_D~gHC$Y$NT74Xys}+aFI!j0JmLu;nV$vQI ze-pfL%9QwO@msZVbhHc2d+Vhsf#KfGtoku4^D^pleaT`_=C|is_S)Mj7V+(dxtWa> zFq_bghJPvq;P_jKxa4959iHfJnt)ldt`~1r#Bry#sbjL)3Z(3D+Ay0B91&6d1y1Q^ zMjj`HMSiBm-H!#ob-g2O3G>JMaQN6>yjN6RFv z!fu!7qw0m6MR7Cm%b4`mYB*8*mOgu#7iTIsNpvRK;1#VhFJL@LmPt2TsAxJMQQ*XF zlr+!Q0GqXZ%<;9_OeQYl<+bEf z=R|kcAa>GZPCNFi2IrM}N2NG_?^Y?hquREKe*Wf1QZLSJjEH#NbdJ~`a(AKj__}k6 zXp2JvWE%#^ejblSj0SCTz8@{eZ)H3E%x1x6=Lz)Nxl~Z}&e_4LRhd=jr!7kI>7OqP z^He!4^s@QcP|$;PN0+K^&*xy7FcB2UGcSL++hEemIa0+@@S;8@>a!}7%^S)LIN*AmH*7vtRU08K7*n{*o_OLd^;vD7!=x~{a)Mlt5{)yi*tNo)Dn zv+Y5I^tL38!t!O3mBCl9h`i_$asEhgo&-la6h9Y;N^Ubn8iLC}z6o3I=A_t1ZV`9^ zEiVCr2UfF#biKrvVGrGSeCFV{;$ElRGx0+%NV}^y|HgGHx1;{+2#T%9{b3&S_W?_dNC_znP4}ees`LHBX)e%*jFIt7#->yziP-}I1f*O6RHrvJD{7$|#bn^B-C@ z3(mBwBez6C0fn*83u6~;vKafxuPnyuCQB&BrT9#^NPC8|?76PnpA-4yxQxKug5Us) zkq4B-!um6o4v&3eS{`$C9rOURt#pK5Gs8UG-{Dvp=1llk7(4E_i*~x)So(O|UaMjv zwgW^{r=}WP?{vLd*n4l#<~^BEjoZO&CFh2KCsOyT7sa0Ilgt9lx!q;aoA*|$P498rt~M2 zh%Mm9g)~8?qa`9%@k<6_@UY1+l~Oe}!yOvqDou>*vVSwK(~{%La>sR=#&sU!;=Zk; zWzd@YmQFh_n8yYc6Kd_1cMV5)xkO$xB!q-ux$3V! zL9;wnRO3+jgESSS_=9wyhf6s8YW=x0Y-(;`GC2kJ?B@_!u@*xJq{(~ibv4qW{X)2< z?x!;If6wVNK0Q?%07b%WrXk-Au+h-}G4Jy@mlP~M&iXM!4Yl^VM&A#ht?N(MIb~jE zXsdF+gm%UU&z3p2d}m?# zR)n9z^1bjXwI>nQy(2)#RH2fpa|LLW)pz`R9dfZWWfqpV)(*B8Gc<;q4pVeD#Qocp zU{pIy38MmG`c)E~j<9&|1)pHe;+~$}=5~IXACf;C4)!@yc_Tb`sB2>z+S5vN+Y~F; z*6SFQk@Pw9_HZP#^%)K~5-h<+W-WNI&u_@D89 zraOldFAKe2isWv_Y+vL|J<#wbf9jqot}_d=iv8{Lzovh(3a7Sb?BN~1%1y@Z+H^Fw zgq8(jTz8KWQekWj+xd69drxCP&JjCIZ6OQLhaX>+)mmWVy37vqD${iQtJ+FnYFz6< zP7o6k%VAVOKOR39pM>85rA1q$hogz>v-y<8kF6@BRh>f_@d>8jVcKgk-yeKP{^C1M zYdU8Y@?BQO*N}$H{&Bt1tZj-Kmr>Qph?cLcO`q&E&Q`-IlDA^UcGM1vhn@*Had*?o zcxW#ygZU{SYLi*Y1RjPyh0oE3ORHj-N6cA}B}V(BEgva4$zUg208Y7F0b}yaSzEZ~ zX|$02vD1X?a!vZ)SOzj7(`>*m#R+ShXw%hZL1tp}h#mV%Ds{8z!2>lzzQOfAyUc|l zVMQoVGwqFOdj698Tw1dqCw89uyU!zPX52Mh&z}Wt`2w5vhUb5{&*Y$Sb{G3|2rt01 z;v818m)#RJpNO%4iXdje%h&K-ChnO{Y((7URJX!KcGisyJ2o}drgCQY$5DvAu~FVf z8vvKt{qZ?{Jk9&KdITEC_wV$YotGu&P&UgQ(WSESItzF5FJ2{5ls5%uIPbt4Nw4vK z{lR#kW+hp;%(GPXqV$Rsc(+P`O|j<(YFbtj%MkYZ2n}G~&Tc#NqM_n2NF@IYr}}^k z2}|l5k#8U}CcOh67YiVSZ`8Aw#XxfUx?!Kr1cx$y|8#+fz)jrUDX1|bG{$!X$z?XnVA3BkJv z+8dPmEl|_i$ucjz!&~Mr#aAz7T}^zHrA!0t7*L7qHuro0gD*CC-AwNQbW6TvONPo* zCC#rSn#*w(%Ip>!;(fL8kOLE6&vR_NE~`Md0g`{2rN?xeLASHWBgSl9w7gU-}ucml{6JOHy-bnNo zUSjm-liAWAI#`55w>bT0KpEh5zEoRa=25?APR>)zm+2*Tq8V~Ky3U&Y@LZ+?wI>P1 z%X49!dPgP<~Gwsn^}g1PVYz{(-|OEaqJMMw>h02;Shus?!pw$9~4wP zOA+`fhSQuxwW_L`Gl+=dmX8t4HU1TXMxl~Dx%m>orUekvNZ*q@6rLdk*`Mta-P2+hF65#}a2 zRdkQw>M8K%JE&_0h>vDrLBxA!;>@p_< zHm5hfb^2J{fhw$_X?_uzsdOFlri(k{-wYp~5jqRbzFjVDznBgvagih7cKI#TEN|E1 z{)uB6_9QsiLdu-7++){u{Bh?)D3@bJ^ZiPE@KB};?)2AX+$O_KhSFcmu;7bBO&3}j z*gcev+$G2r5XY%_7(bI3R-#7yBaSKSSC;qVYrkWJs{su-Xu@&HxXGu@b%uahpW zs|d9iTdl6EszTO(H&D3r6*f;@uDj%u1qTT!$w)TXrMEqBlmRb+;{%#=!Lfj$ zH|9R$f#de>Cl?$~L3jm@>JwdX^y;4JPR;av-v8fb`lx0qGl<1E0kS8)9Sr`PnO?IV ze9P0evPfuA?p+*xz3J7k5SpGZIlYw*(~Bjh_r2~XcY2$lsG8pV6Wr;YO#zE-*1UTY zF@w2PAi?!E*F~_R=*{TZ%&IADsmMtn+Q}T=rWKpcJSQzWhP`>Ebp>6U`KkJ zm+a@@KzuT$@`(hM(_OtluC!<91yNeVI3+0*!$kn8?Dkn0`gQX3S^E^2CfjW1S^=H3m$A9ZcV zLwDd~Xz5ZVS7U$==~DGF4|664M!PBW^hKM(mh5^Jtg)3;-< z8i`-FnLa*?bT##w@I{X>;UDtGn{a5JH`7K<^I2k2lGAMTrm0*?=Btg#9g)bbWL_iZ zGTM24F0ga+zNDKn7A0EVXkKMH{EbXC40Q)1v~xRApMFPIWOTS~fF0ZyPw?JH>;xOl zPpE+1<#o^TH-A0$seZwLu4YEA#_v>NNdHK$4> zq33lu3xJTho+8T2K3kBg=Rpe84)e)LB#Lcn&R!@km(j25q;O=3T!tb`I#lty5EXfD zT^JyJKwn~O*?<<)K4?aPqDvck8S5vEfU}DUMV1&<`xw$o0O?9?wC_)y*spqmF9{yDeQOAn^3yQLz-0NA**;_BpMWX$ga^tTBFEAa#ST0 z#JZ@<(cg^0#O6*?ruDS1K z%Vg!&#+9t7@C3A@w-wJS2=(KBxm{+Oo@a1I6+fwA1hc~1h0XyLSp zC~EB+(EyuQ=JRRv991Dv2pPc3%GthZo|_mhciRpYVPJpMHpI(6Tq7@>NyDj-VK&YqhmteK1dxw&Wxgw(|@PaXpJCxBtskjaC)0vfb5vEGpl z`s+5LF**xhp)Y~yL;8tM7%Br>RAY+RrP7x&)E4f-1x3&r$*#f?m+WDt&1XGv-LibhF)RAx-Dpdy zoOwP^yJtvyJYGeRA+0!#qZy5}yB5|@!XbN&kMZ9J`OjavLl^UhaYcr<`D+PxMQrB}GHn9WP` zdf4`9VX-9HCkxik^vydO9+hmMZg?#C+i~E5pym?!V+UazV$Jjd_3!m>1Z*guNh#m?uL(PG;*{avZM*t($=Ua;r!$EI}Y zkkeX=hMsJb&hr*06T23U+G68K+|W!m!*ZS!1{G}|3xrOHL=EpJu>CcjOwQ7P6&^dzpmad1~}LXOQV^N@KP2VwiLdO}n??}XQj;{i0g`B!p7d5-au zO9*7~R2iJ38PY;gT8ms8l8K&C*)w&;w-f%tF) zX*8RwcMQ9|=V=hS!Kp*83tkt7N10S*?jiZJWLGRg-QohX)kWDOlBsI?R+$Ii`%H5G z5O)R4lbe*Zx2om@#*(xOAnBLd3&1dyyW$Qv7wUSE;vb1o4WdEJiR4G7Ww!l=$ExW3 z;ZAn(w9e4QHFpCcQ*f!fmv->czLBbb$ru;QUer8Q+E*_Gb~bALn8;b$VAlMW*gy8v z3-wL(6`N~Df1ra>$D`@hb3ux~q%60WZ@3GE?C(*M#hxzn^XyD% zHO-g*#Zr;iDaZHg-CW?1u_HFbzCT&-QGfgMe82v^Es*g$)ZvjFt1ct#W5eBmUs6QF z1>hOXQ*@a`0kfD(gy0bhoMm<{+k+=nnz4T2z}#H-9XZ&(dobRe&q-pzjwdA>TLz#K z&2ISCoV4)IwY)eYlD3GykvX^7yX|#RFG1cL*y%Mh9>chFF6HssKdosx*AFa_*pbZ4 zb<}OfUh-OG)XJ*x`W0$DQoWUgv%UshE3J&F`;;-&F4d5<$a?L*&|p!e*-3}hwto>s!nP?y%bmXZuhFP%;bzSdn9MN(75QPpV+5--F2nQh ziRKbyN1Eq7QL^<<-OFh^)f&4k1D7_x&Iz^H6t+r-`%@B%M@N%MF_=qouEJ*WnEE?n z;7NN%Gl}#4oi?+3Mp~#(c)j$(v>VLFoZ-OwN2RHG;=l0#P6IYC;mU^Nbz?-<^>z^ zvB9&I@|z)bT}qNgdpYJLx3+#$`vC8q8*XEOeJadIeIoa&Mz@0x>s6@2d?`8P7kLRm zH~s7zk@nr@C%mgLM;=Q|>w9XEECbkKsNiN5}R$W@Mp$K>n!o66w4@R$)C z8=sTA4>u`ppRTQXbvD?K%S0OYT876gwOav0KR!3Z)|VsDyVqkstq<(Jla%c51kO#^ z-H*{|UZUn=+2M0+MVjg2?JRD^^yfUSPo=`5y8hs#xC( zXcjgHFOYZA5dI0BSy5H<9P1t*yc&<{h#fSM{-^MI1+Qc8k6-lpo@_R4cDTP>KkfHu>^Yc)&H#KEER<(h|g@hk7=P38u&wS>(HmYt&2hjBsV&dTj$u% zxeDFgPgjv~`KDnl3_@LwBo!~qc*SBk^^xIvL|L%7C{JLhzP-InHY zqKPCjpaaZX&FN||ylH6L^)%>dg1AfaC@buDuC!Lz36-YgCn;(msqWgZOzKv;Sm6p1 zvirB9WzWMnh2@UxrXtmc047a~aojLiWr(6jw5~0CQhF}tsIA^>Uy94JT zvS?>)E3EE_eZ%>8LJyv8LzV!V33?irA}3%QR2ed zoj+u3L%qP&SS_J1IkSdj{DCOu>W+-}=tu9-ik1x#v1@TcThU#U4U_R4ddIo+wC#u9 zkt@!NH`>Eln2KOV_Ia3E|5h-2Bv(E=BjTY~u$;6wFUo5Jg$cN3%T;f6#QtViIJ0j~ z1u?EPm(DmM=EkK^k&i^7?1f9=_6gl^k>P=ff!_zYa^5;~p=$4lggVIs={hLk{F?4- zxDNn%o>-C4Rur{hI?sZO1&6M^cfw*ta13+8x7iBLL1t701O{UwO)PvogyC|3JhU$ffiGJAb>z=UE`Q$-wfwF|yM0j4<;U(L%M-^Q zI%d+T_&Yfhfr+5uLf}wYsYTx}JH2uBsvC$Zyik}gx)-Q0Unag6*YRS1=lpT@Q>Xn9 zy9kejVtBrH&W9soty{d zBY406T`rmS9UAYh;FV7Gz6`u(>-KP8S@3d--NLaT&qb`R#=3*}w9##o{27S&ZVB(e`5Bwgl5oV4qw@|CI6|xu2 z><4_Y5ZM+XhZ)V76@WKZdyU)NjY0&T4ge0qHQtu87z?<)tq+^kf$cnrf8~2cDfX)L zPUpoOOCFrk(sL|<;W#U$0wiZmlCn@YpMU;a9tB@=PSO3SsYGDWEu8B3WkqNMHXTOAo3XY=8W*wU&i=E(L?)i|J)x5 z9f*XCxeXf=Ybt*0ed@T!<=by$%*_} z(9DQV-8%*8PabT^nru=|JU^cQ$J<{Cs?vp~!`o}lr2JrRArAlk_Q_njCPumAP%ChB zFY$D5qj6Wq(uhI-0ZI&@tpsd?jl#oZFQ=Av;)*lz$nqxOy-lw$^LdMt;%*bN#}NBA zz0$nJ8sX?dLQh2knZFK|9-1GMDZ}=~O6zYmt0|;&%eQQ|mZEx3EgjB3@z8ttp^7K| zA8NI&;Zud__cZKS;Wh@M4=eb9{y*}lswu2?k5s4k^F)efu87elY^{d1hq@DSd(- zpikRxj|SjtxEsDBiE0~SLN(XK+&(k~)u5v}+~(;VDV_zY)v??lI=e2AS_!0F_{}E5 zUvHN2#=`C;8G}S~f!(?RJz)2K0(K8m#)F+P-=mNVyR9sH55O6-Mu26Av?u;2O;LNdrBga+(a1#iMj+XB~9^fd&FbPmKZ>@BJ_Bwx) zKr?2icq0EkfYwhyJ0PHi79|0e`@czm5eamJ4eL5WUR^;svMb>W*6Qp|DF!P34)-N&Kp6^U9)#bS5UB$QOgwBKQJha)KodcTF;#hW3 zU0C%?WJGgmre3t|)yj<>w&*V^7MaT7+fm`XSLJ-Jh5R8Oqhr|tHdR^{LyV888TB~Y zgw_f23l!zfIm+%(e%KBf2BxccY-aE(s6>=xX70`PX;3DY(@QXVly;_el3^k*quNlX zq^^BIKH(vb2G`J(cM&f)wKH7Tq4D?{YS|Ff>C+IOpPO;_kQfP4=VxS0 zAHswqb2Dc}@|AnrJGxW&4e6t{7hgNVrq})|5m!!WPU_KZW4D!p&7KP0ne?|h$l`c= zJa9M=sKuml!+L$DDKY?7TD?W>3t6e|ttfUM?!f;jq`xjVJa0s=NZo_J2fi+i99ohd zj<4avy?hVI$U}%5OhpPy@e2Ha&P{GmDc=drPuyws0CG>288}ntoU+p{rxlubBWH#lce(=?Q z1}X7$4X-#|u72b}6t8nGJ`!KZHAcZ)n37zluD<*f}ELUDwOTs zzXG^xF{OWX>K=@a8>-nv%U3{1C|m88Jx^u92(C>$il~&=dsGDssC7d1QU7yp7Ga@1 zXNDX{J1;yE7oTLm4W4Vk7aHS%08gpVAk%EMA-Y}E|0q{vhVso??~Q+HpLnhl%uTTR zJXOZBnKnOgy0HtI&v4?Q6=sbX0QM%qXhpA=-eA6WK$Lfg^`vPZ-n~C{!H)J#t5$I* zTep&NaW7u0DDmkx{~K-_yzj@2S-$!u)RN}k&4!=2L#mGReIM!52(cstv&X*DgBCQN zSj-9bN!!lV)$SrCDc#?N!r0@iE)yU8A2=)Y8R5ECcU?A%~Jj5#EZu*o_hHP+yq3bTViZ+6rcXoel1 zJGOH7)U<=U;~W3Y;7&kyK*+7>dj`n>dkm#4uvjdeD?jl3NcG<1^`b2Qh=g;%(=fG4s&j+$!M`42M^e0A z$TXZC!D*l)`dZ`?PyJy&JYOW>D6G9SK4(OH@Bt|YbPJqL2}=x#MY8me5$`rbU?sVL zY9~~KHF@spBdDUmQL(aPQd!xL_G^E7dV$paStTEAv|dNheI@l?M$(gAkG^ogxW$uOaMfIvws6oHZ~ zoB@}&*W&VhGgFG#`@Se*kCF1O!Y#Ap658KR(&N`tCkdk_5&)wh|IWm!PZ3cc$L6ph zMewu1Z@I+DGP8>moj>Z|9qAV(j!An>N3_m@1$`26g4{C5==K+~N;>iA0E{j-mSY_^ zH1xzQujrHvCGosSu&~$jCa-F4xxYm(o-c>A&w^w>B{yWmn>o{Z8J)V7>wuN2!uamp? zi`E??(U(ZGV3zKHoD{yLU59`8mJZa0o&0|ox!Uh)n=L;)vDDSu3OTe3giJz`lEVv5 z=bhxliZ|gb>NzNoWNT)sSxAB=6Ycn$D4FN1pvjxndeM!KCQ>9o~XR8lHWwJe$ zHBV)Y8MhB9G)a=-;(KuJkPg9OB#W2Wor5Uv?t%8$sdm^0Vkf%q*bjCpOi2O=qnl}_ z+tGQ8J*)?&=URm&VuMK~A_&Yrlp9%yQtYX*!wE^KTC`2_TC}cJyIjQ4{DfzgbXG#! zgwvr$1va;8RE(sPQQ3Fk^*${yG)3ZubuQoXu1hW(n=nlzy$KS~*RgatE1r-jE9HXE zMVQ)mheM|vdwg3#EtrnI8#$8w-#io8xDjrNz2aVVi;|nRFRDCxC!#eD4oL5@Y0{6{ zGz46Y9YG+YM%%+8A{LB04kfE@<%-l{L>)xx@N{qC#!8{_LM$VE#F#lBv|0d8{9-{!I68eL=7?@-HMX*Ry6I{YNg)OVk~y*UJ2i_ zlO3^Bmw1M`=repvE7JGvo_L7U$Bv_!J+ld&VE8<)3Ad8U{Um)EUB5jz!h&&c>NyrWijer=Pj(FH5<3kzO47iRF3w5sc@Sq6xwg#e92>k%@V`wI6rb`jw?)EJyG6Uu@0cnsMP+S@bM5_AgKbvAa76x@yQg<4FWlQYwlh6>ba;R%DaXy6di-^;mLL0(K010d&kkeCZuf-8-o2M z!G(GqdJoN7tY6{*KHZ}6;0I)0n&^&sszS0Y0e1dN0UK5@1J3XL4x)rCrV{s*BPnv3}nb)h~(J1qjfufDt?f?WXg~$zDR&fxgRz;yqn(A z@bZrt9$h+9b6AzD4vn>h4O$X?OoyBEaY7H1Kw$hD14#sK_55T!d%?dD7({rji=5cW zkM^eQp%LB3tn_F0Xi#p9aP)FeH{I2im-G(MI?75Wh09qgz^tbC_`i!b(JB$2D#E>M|0jg>R4IJZqaap zXQQ<`n-Wah7V(aqhxyJ)P~5hh1}Jh85=Vj~$YLLn-#(NV`_8cyXSfxK@=TT=DsPj^ z?1{q`gD!)NP$0X>GT4;*8&=;7~y~NGmum z-;p{rCzWloyAfQkJK*VD#m4T3Uj^Cx9K&dib=*6+*C!5_nHTGD>0WZD#h&G*r)yC| zV>m7wAR_y9hHoPGd=>govwi|TAvRs`mC19CeVL#wrw|s4u`6~m<)vH2#BF}J0SEZckuz zY-=XtbCjMba|db&*Ol@%D3icMQipfO{L3|?7b?KBPlbTuFU;7>OB8oJj9rHs{$ zJiyXB9VK&e>rUm=#GX@SdPxGX;`iv#gI?wHquT)F$7k%Me z#351p7ECY?-`Gjh;>}W(sGRkr5V0D~Zrj&0)K1{Q0AODz!DS!z2Iy*?DU>*ask_6; z2;cG?R_-;a33;tyCRpQD7XwQW^5xEQIjE5F+JCs{UF3?2+LMr>tX|+mFjMdLyYIyH zao%-c%TAEuUGYa$yG9{96&2QtQ`pe(uMG*Vp!Ep4~5^Q!F-)EE&OU@*f0yUEH+Pzly4*z85>39h>53REFRGyf&@O{J)Qg z*fAe8(1?TANekYtm2Re-+u8K-&>Hh5-wOSWzF#+E{aNEo93CluMuvcC4AO4cXS88| zSqg87$3o-3(^Oo?1>WV)amPJ6zoTrWjk1+KheDj>f~x|inobpHI#mOcu~e)=qgf=i zoqu&nv#iD1thD}X)It%g4V zJv+0iO^5hAV^)Ex;kuP1Fm&oxIpwPh(FCr-)&*DI=*~{6URJIfd!=@UD?sgRxdLb? zT!Dd7u+4Xv3u4;D&JJnwMRP07?fc}c&nF+BN;)vhmp@0o&2|!n?l9N!5p*F6Zcze@ z>gVw5I9NzprY7GqUCbjccPHm^1fN`gD|{T194;R6ZV^>qt>sq?fdZ99*;fk!&nrTU z)md}w>a4M=_XR{^E705+R_-eSu&EV)_ z|IP)YxA_~>Ir85mJ6b%QNWFNkPz|<+0M}`Yy&MFZeZVivUgG*R$n57Sc13adp7~p; zn-<$li!xT6AC70Je(%t*LKqLzn5_RRul~Js-h@3PV4mQO(=i>Kh=f)Ocg1$DG4FR+ zX7fZB_`HS*U1Oew;)d&1yMW%y;W`Tr%}RHhcj!d1{JTyRou=t`!wy=FbVc-TWPeu; zb^XNd1M|W{9FJO&$KHi55pQChOA^u^bi|%E%``>eLi4QcE*THEmv$3l*PK}iWyi#Y zE4bV(>YB_$W1;RgCmOg1!X-@}gZDzVTpHYs5Q2|+isJ@6k(A#KhJvg*%W#0a62y=w z9tB%=%i#5>;-|9AH%5z)e8KkY&-TQ%u)3w~khZlLw}f0p8Z;13DEGg7Qp*lX&nB8z z<0Wq6Szp*VQUgk+0XS8K`p{GnB0=b7vQ5=LVLO6yCpxlCOYS`2Tw5AE)$_DeVls}$ zsU0OmolostP!&tKOJE;gZmPdbxLut5dUTh!db8S)2>XS%%Qx5z~uoXS1gY zLP51(1~0`;V;T#8NSI)COT)WP^;Y2GYj`D<4|`;L3Tu57EM;1dM?>A-=&Ye^_m;0E z0ND)`%b6triFZv;5SvyQ22$4vbmNntBej`U_m6~H0lJ?ny5x&I8v3J-7wB5sy0o=% znt4I;1cbvAC<#`_wO{A9U#9k{vFBLQvB#2*T=kJn+W>F9Gj)$* zW#!Re+xv|bU+}uGYZCuRH`2&V>H)$gfpBZd)WcL>a9s)rLjrEy&JuWoy1n;)^;i%# z3539Fs|Uhuf-2g)oj_Hr&~7eW{{d%hq#AP+Kp>lbD)9b5BB`XVH^nGqH)1s#evdT{ z?NoZ0`$T%*tmNDoI0Z%zPJWDq=9_qr#ZE7tnuk(yj+ByfhVw=Mlb4`Fu3aK10P9p- z(Wc@Me1HTAuDVZU3MnJ*0k3qaIrtn(~KU7;ne}Rv@bSD1JYY`qeiQ#4Iz8p0`%-? zPwr`WcP^@O%FLE!%JPJgH-S{5-7L81SVjfN?}?c=qkNrggN0l5RX5yDH(p2=vineLBjb9hu43hJ6aAxkRl4@jbYJ(Cn`k^3x{@$bCR_EfW_wM{WQp70h)U=X+Eg0zh zDdwv%Ywot{C0^Dr22ZjE!@?Ol(FCl-^`P3~GVgozV#oQ^~9;iuzF9CjLJg~Q{OldqE_ z^mfZ{9u~hjmQZLN8p>{5qJv|#Hd6u;ZtP?54CMr7eUEn3wuxhg%6++urr!8nrxH}8 z<%P(BjAz5Rp-!kX^oR{1EUxPy*(P{_0DY&Ap!? zAEvozykc{g4QE)!^u>bnGx=N+X6mW~xY1^IRx*vp@ovrW+WEag3v4sWYVtuproGE7 zz6R3LeZP;}q=FNF!q(}T;$+1Mkc-@!5p-T@W_`D3Yzz7zw5Kq~AU?+#(`L?LEkHTI)zfxj>&|94Q*#^M4CPOmQj>-s;*|K{eE{+Qv-U3V zQB~Le_=F5FNMM2n3=%bJR5WOVpfW}@5E5cBFd>kD8ld&jIBFYZ20=(5o)9?Q4BCp1 zwid9W(p&B|2$fhUBtl6P3h1>KDpuM{+no-#jfxO#%KX0Hwa-i@A@<(;|NQaej&dhC3-3$+3t%OJE$JvY|PBA{;lZ4}wvn6n5fwZ=Lufl*Z@XeLBz zg-I${M#)0ran_wI0#z70+T>K@4c&B%iYFTsVsWQEIepBp<>cZaW=}>aNPS`#H>6u) zDld7DK!r&M@;IRX69b}8*6G8rYAc-AtOuMvWF1R#LMg-Cvx`Qjy~?M0JgP%_*1ebA z4&A_IPHf%GSd?9LKpoZ(;!9u<3-nK2FlK{a*V*Jya-h!~1YI4P0$-O05JH!WF%w0s zv*#`8Yn>fZgCBQj!cScu)PVQwtjNu$Kf%Y!Pk&Sj1mt|HIcy)QOdO#>;L zi{B$tFzmoxk!|sM>zcyu<*-6=MP4owl^rpLh}qgJAA+a?&Q=VTjkBu{ww6(=%MAVl ziLtrQ7fphCvi1+{kfqh0nTNPNq00mFyXNAm!1-M_!%w$x$%3$fgOrPqct2u8p>4+P zHV?8NW1Mg2sG(#_6=wd_g%Be_4?=UeT{drBO~_bRJ9X4D^t()d7CIZPePC1+8ZM%5 znjiqGZ@mam{TWa=!$Y>0M>o@e7tsLu)g^mz*6c~a9eC`Pf_5Sf2;Xif*NeX?NH%zN zxvt_R#s&_;bM~|7F1j$5>$|$1e)iALKnrv&O4?T|8 zaDv4L7c1-C4vLp<^YSO%U-~bXmwoX?V20(1FA*?jb>}rW zFvk26)@Q4mur41zZJqqCl;5Z2ca{9Ek>5u7?Z6Ptm%{a2Jm47iG+fVxb8hUlFQP28jB8)OU;X_i z;P$rnF&OFQRMJph-3(yhLcA z+Dp^WnAE!v?8M5z{B@91N zR(UxJ3;9P(jw3{0@#~W@O+@7;e7x}|L@#G>ra-0rW9AkKTP{>WEP8vpK-Thm@X&w} z>E8{BNR3@w&S-)ZMLa(M9fRb&bOU}O)%H`C2J%ty}`Ggo6oy?4qldr z)f(LBx9Ir|*S=H-SSRO7p(UTRjbrl`MIjim&xgDkV-X;E5J;-{0CAjTD#`T*DI(mU z0?|^tdc9q}fx_+TOMR^C!sj8-h9n%)cUaWu`Qt$nRCnqZ@$tUwq$z`(epB&c z`8;QUJ8+0Ab(HhplC8MqmFSA>?Xua6>ukxX1Kx7=-vH5OM7}Kz=yE8{A66SVz{59U zqsUkl9cGs47Cca=RjNI6rSFLp7_vR#i6R1mbr_}97CE|>GcKiXJGXvttZ(}a{0&{; z+fGCUASzgvYc=s3!}UjKtJ?s+&xlkrSK8I9d{2ypE(pbZPuz+u^9Lj8;fZcYgf}86 z4<|&wmP>+jrSiPA5l)U__k`rWo9OM>Zaf^^-kHcG)8F9vFR?YmqsUgQo&0HJuo*${%Iq!jWDDEI$CQ$fNU`ietaS&R zD@Xw?^KB=}3tpA0WWdNBFGZ!k)pQniD-*L|Hc`9`W)n}K*DF~%%PF0qcZ|jK5WmLO zcRnLTp`#N~mZ%=?--?KI`8zfJa+{a*QOz*@Pu{DfFCZGt_wZ3F+>tIQbSykE)h<5H z@MT;h@?;2)_QcrGjj>2L-nyOmpl?y8x9;csGKBxthy2mUpm6yB(0LekBzo8+=wY76 zTWkB%SfM0jT}KrUx@qjzqt4d(U0E=6y$}j_nELHS3y?&%Z2EE))PU(Nq=3~CvoWS zAFgf?p7`fn2{p4$Rj-;D4J}hh72cfPFMDuyOY)%!Ns4&of!La`$>yjX;1URa|FA>s@{ic7CqnRCrhU zajj%pvSpskoc-XmAVBOoo7H4zl_vtdYHkr|LTwic%W$6MY-b-*Z#%UOya7HHF@$t9 zxm8Iuw3^$xv@d(sNvwb%_ZU-ryZPWG@WR4`4){0jq8H%UEDwmGhNO`n+fP?njU?0 zBqpMI54IZN2wGQcwP#UMo%Ssvwp|2l+t1)x1tXbfmtelk=~v*4t|$cHm?nP8byzAc1S?{fO9#PCLHpbyx5gEz2v zGnd6?Cm2LV%HVgD;0m9B)Y44fqj{kbzAeH^U!cw!Bcd<_-62?(pMXsHGXsa*q}ZO} zncSVPD5-5Gwp8DJI}U$lO(|IAoI>X*xOq8Sv3MnSl|VQUk>F|>pup?t!?dqo=@Zbb zaZkWCQWRqPdu%kpGuUYV1uhSQCE1*2XIk9L(Vz2tb`G(hKs00y32&WfP2`|}@_pss zFbH^lZzpkszylJmBaw_!mIrULtrYwwTWcz zMQh!ae+zsABsQ{(+ z?@Y*jFF3&ZvJbL|L?g)42=UfV;s-o}D1XdH)|YO(o>K*Qg@4bNeeJbeHoUXzxo*~% z{aC-hWFZ0FW7pqZ_YzrmDB1 zhLKh#2m&F08S_2_u%D8oLmCI)a{|Icea{I95Ar?7!H4>W7o|o9;Yan)tv`w{$wo@g;D!)IQpgppFT}zuz?EVC@uJO z^GOUlz6-!G#YKIm{w=PC5R++aU8`m+=y3gAG)m7-YcJc~#&+521#HzLt-jH-RalfV z3VI-|F)|yl^L_(iCpvTwV9~Eb5GW%%*)d%;nwii$UDi&D5|ToLRec)hkZh4Az~-wy zUG7rx`-1@BHQ;)$BhRl|nc)sLPmXl>y$Xhy0#N1Uqtb2~;?yZ2>@7W=c~6jKJP;iZk} zXv0q+NmvsO(onlY-lmj=l}I&y{!tQbg`UpESCUnuj4dHCnf3Ap_St&5fq#^9E@7m} z$YLfVO(@KGxpO}MEULfw4@@3%v;J^oOjVj7bT|GXbpIRom*BN3FDn^NOoG{# z!Z(WmZU7z=qe92kzB0XK7CZyL)XQZWCBC^w#b%x!VrII=84=x)nCs( zl=KW|g>nV%ulQnf6X4mg9?!(=j}mGzKBnOxq`qyx$EVcx<18CGnR~h>q7G)ag2H+` zw|VI&*{74X@Dq_ADGoq(F<9o44!5#PZP$34yQ{k9j|Fs&iYtt4H7|a`F}BKJy|vTb-vY z38UhES{0>d7o}z&OcHUzHN|=&K4L#Z7|H!`Nn_g|Azgx+GiDtBr&o;{M1S`x0}rB_ zq{B(RJGY+l<|U;7{GEh=nsMQJE^axn?Y&oG6d;a)J1&UMcSF1q9fKwG;B=+TWU?ul zEA^HfNC=Ku5jctCL|j~A{(Zy_^k~6ee`_4#&*^DD1!YvwN%c%)4siVL#*vUspM!M8 zfdWn+nBC|CcUYDpdQ-d?-ny&NeW;%;!NnK*EWyP?eU<>upfc>O*Ne|Y+mcaCiNFIu zypr>12qwQi528cBFQFG83IJB}sf3RNA2uWw+L|^>n7?UiW=A#-U>w7@h27`nc2tkg zKI47;edIKSxwH56cf7Ah!E|N64JpUL+}7$#mC$IB^RewYyZYHX;J1T`#ew&?q(yC} zXOV9p=52+txDGUos+mf2FzvHM7BmFHE|CT8r;ZPtj4p8+D{>mcDlL#z>YAU>rKY*b zxgAU1uv&36I_^yGZ7?tatyAQ$)IkulrgAqVpiYL330{TxdcJi$j)NCD#+UuwoPjCPmTyHJi)S-1zHP2Ar4jTws9Wry-9DFV4sxFgl8!YXLO-Vg zx&9Xo>>d|uAg++|>m%P13_PfE&q1gUTJ=TlFQTAf2w*sL!nNGf07eIr9Q~0=l>;4) zbtZ`f(EHXIx4puTqTV%cg8(|y*A}|fetsp^h-AQnU>2+xO>R^p3;qG> zl$Awqd=W7tJ4LCy?6BAZbpvJ0lCuD{mazvNuj_5Mgu!f)+CZ1^9 zA={cW!n0{B?uugj`jt#%n@~d!RL}}i-w=m(r5#p`2Wg$xTaM*%HFtQnp!EosQL^6@_QI6|PZ-_xdp3ok& zPfse);NLEdN+U*LsupL0s!h^kSsnHb2nVQD!wK{(zEn8hK>xpp1B`+>nx~Q67c%1P z4g6>dCly$#vMPc2|I2#rbPopMkgG-lJjj{GzTt^!k%h|Q9OMe>sjiBNbG~^gr;vwS zwoIgQCCkYp(v7_M{7K!&En!8K4VG;Xm(62umlN~~U@a(hXvzM4Odno(m)itfi)^4R zE8ui(l(WJRs|xncQ1VtCgwJIk)vBIhjof#aoTuIfO)2k~e-;8E(@MedU{$X~!9G17 z`;aE!jC?3;A}`1$Ms5o$>Yv!Zoj5k7e~3#8+oK-%P;?SOuUG-4#&-lsiSMB}a-vVO zKp_9=6_Sy_Vt&1II&gePG}M1!Q`;+0I52Q8q$G??2SJH%%Y7J)w=M*TH$s_U1vC#3 zHDD5%dheJY_|@e%32fiI533yq1W>gIt9cMPg^^Mc)SJC!4J++!v6kU4N>VwEkQ$j- zNKs#IM*dT2ocrs4)3_nXLPHHP78+!Fh)CY-5=l*{}bJ9HP=^0{H*$ zeg3P}H0<;d|A=?2KYVF5r@?6LpnmTl`+EYPYq1XF_bdDR_`Zbx#^$&f{q44p1pEI@ zzhxmW(53SATSuT07IGy1_Og%~2}EU52($m2#=m+YXJH}tmiYrrqW#+g9Qkp!iEkgm z-(J4`FuolVAMTQ+G!VQ6*ZNSVFh)mp_)ninBJ1_S2fh4Tp2FU`e@A=dg^ub$pO6>w z*8K=i5bhKoe*+)4_Vy{$3!K8s;)Rd>-W2|}DQwOMU5g4k4WE_oR4I;E`FE!ZgCZ&z zItqR))5ZJuU_ffztV zy!a_j+OV30&+6N=LH~{nxJ$!ZIxsn9dg|T|GJr$XV9;QJ3;g(3x$H|&!TAkLC|ep9 z4W(aSg>w4Niy-7^Y)3^`=qmlq7I4EA_^EU+!bkIfN!Nee!Qgv*PU|x5U!c(D{1N(3GfUGCygoGQc3Cb=NZ+|m^gzDm!9gXB%{;V zLFMv`=m(U`6>ES?t@|5X)+?0g!oYBc-W{e;H7rtJ=pq~Z*a*wvoCjG1;|#DcoVV~Sbccp4eCWZ$uqZTWy#oJlJz83hslcB?%T$3ECC&*} z!^r1d;ZRe!8qPnBdpGPDSlf(c{4Bi1s(FmX$$3VuFZee4ybp2j z2%?W$qDpfad434-0O8t%ULf&xHQkVonU0Kw)m+;!oF{0=V;X`*v^1ig;kkr}Z#00! z>-c2Rtw2i1SE@KtZ{4-{LuG9BAx;h)moDnowWA4L`vAFD;0%Qxm~c4TWwN|=$Iy^f z{WQcCAL0tk6b$D{iMGn!37RItC8>G`pZx;QDlc=jBX6b??U~cM5_rSZlXqnx;Up4t z*E?yYSevTI+?;)YW$r*g=~#707>bX9<}@voWbZ|RV_mPMR}L^q5jY(`(}BT*f6ack z#19kCuF{AvuG;YqA^%GF9mw;mcVH0C+62EAE?CAGFyDqGEE?LR5ZCWu@?NaYdcQt( z4fqUDy)Yczgih$qxQ~Wjg!Y<`Ui9nv)3I}bcg{8T2n{v`@!Ll86U)pnE&t%0CiS=a z^%&H*gpS3GU%(NB4o`K8hLW?{OTwB<9SmK8e)@ImDE0`aOcBO%NIF>}ojh9Pk7S0I zbDR40Pf!YBw(y$$gjd;h((w-%c=f*_Lu=cJZR30fv*E3K0r%0+N&o~ayx`YAEaADF z2qMyNzW%vjCPdNdS;D{#vvG96&1kvfiW6e4z@1t4{}aSuRbgCEU?8T1RS6OQ-=QV7 zJG4XwcZZNf=;;Y1MK~;aLdl`4yF-b>y>+%v%@7#6qN8S`%QlP6OHDR_Tjr$ZGGbSH zYXQ+8)K~bCuXZq1Zi#zy2>=7R-wiAzg>VAUXn;Wb7LX&d6XCtH)=hpr0iQ=CYc6Dy zjzU5Pw=~}DDe~*~_^njJli%~n&3fbc;Ebk@6tfWE1VN<-qh%v)(eshM`2`S^ID${W z6rjcesgV<{8rfAmCv5D3Xmf3K^!2X(f*_rs@sx+elyq$T6o`u1QV#ivt{g;k{{~k} z!TNdbSs2kF+CQQ<>xC34Uaz-Zj!%mvlte@TlgGVr+OT<{!7+i-VpyajGL|DvdW3ht zp-+q8?=E|b8&H@l@+$;k4(;G3!V&f@?2FiHk04Hf$LL+$T9QchX$X6WVE`-f`;#18 z0?}msJ;`fxb68@i28XmA-c`Tl2Dn)lu@h4l}hA)1?$qFazXO5z=iE2VB4!g$OLp8}r1?($H_pbhLt_5)6IkY5l;vnG0 zD*fJtAR7u+(QcKW`lk#^&>QTp6h3$`G$gtJo&t@2y(A0$C`^lZqYL0bfCmrBgA5qX zGw;Mm+(mybMjZ$BRy2h62`nuItMULkdKQT0$XrV-pIpIP*)5&{iK~T^7#VzCz*ARn z1ZMD6?^n&BGaF{P6J|q%eL2`a;o|iqgdDilAAS5;G`wX8TJB2JF|F(D$7xB_Me>6< zwfYeDJ|wlW3wSgg)ED0wL#;5862#GUXaF~#ox(%IFFmicL@ME`ncIaFHgHRe{#PBu zVInh(WE+M;foBCzwu~!KMm8pXBE#c2q|C3ADFf!= zqbn0u`2cRVb8!tVYX6u=o&L^I%r&Uhie>sfUJ5a5|Csnum*RmwxW}~6TZ#QOpv_M6GUG)2u6Ao>w{ig=oW1%PLF7n z136TLH^F@kp=*B|Hj;1jL}HPCs^`~YbPF&#yP`8Tz#o=ifFqm%PWo>dpdy073M1t> zX=)77AY#G(;4PowdyLa@FfBm{A?jXt3Fw)i!We{m%sY`}Rg@Wio?IuW&SW(`GxuG@ znLzKYT}}9fJM?F~8NUI-S5P{C!VOZfU{+EwLGfM5wHG09_$ewCz!7eyHxiu4W_nus zvM&1LQXcQN-Oa~RVHND%_Vxe-HCZ$c#*oXPjPJYb%f6uu?8^gs{S2D^W*;uCOiM)v z=wTzqzZIQu>=Y}5_%rKD=@xbH`axEM$!wqKHa|ua9l8O6Ux4DjF`*AVxs5RSPCr{O zjo!E_QJOsG?g+)eaQnkl>a*W~(DEJVngv7>T?R!xvCajJeWW-#-=jw8&S_X3QQG(L ztB!dF1^NI~#Fv~;f`U6z@d#f7if}Yo_an>0>x@5<0=4m-J!V#PA7gmlq6Qk_VAzg# zTXCv)TR}?mA5sTWf9~$&DrnN>c!GR~(6>Wk?yY06Wi$jy0=t98;L;sy##{Fv zd`p?9S&toP0K%9OtjN=eE27%N+iCMpFDqbfrb&VZD2PkPP~k!8&x<|!^9Y&)C0@Im z&I9TnrQ8pb*ELpGg#7bb69Xm1) zqino;2+)T~MJNbahGVxw61#mCr!X`v)jJ0xyov(%0+ zFG33uW~n#h(m{o@j#Cy)M~J5k@Tc)+Q0zgdQUsBGOqQb{TLJ zlOw68?!iFRih20WMtG%y&cGxl$AK~b&|9%!sy(Lm`4D!>xhlQaDg`>bd5o267S83rrfOOf}rcFT_YS=}Tx_!gj7k!`^K(u@8zJ$YcL zZEZyrXN487VOQ2%lY%5tX4PAh-%-i7yipCu@jkwOgl#W0QMs)(cOchX6CC)ZD;PU! z6rWTLJq1sB@#u1NHFPpG%6`DyJ6%myr=4t-=hpX+0pWU-w&=0?M@{6nZmJjVaFR`l z9c}w9);$Kl!@dsq-R)hz8_#-22T19JcTgK)A|X;H%pmYd^+`nFfXlw@7A3pIGP?!3 zw+`+W21n_+TQ=UouZ6BMtpW3fPU_okmEBSeDMW`JZEn1)*5f+~$n-m?*nKwu^+#`f zA#p$8+<(Lviic+E-R>NF%}T)Yf=T!%j9dMLk7nuJvvd;=kcyXL>>4g6a5Y z#MNtl0LJRwsCtTWUKAOjCS-y!Nb~gzr6!hp80FCBE-1!A1BC9sbT~;PwOg#obdnp? zWhIH0#xXwx_4fLAA?!U<9uCteS6k=dE3_98ADVKg4YumMT@Z>_?|{4xv4T32ARG)e zhF9zd_`nlIYTYvoqoI+(;Y64M@?y2%`Qa5O5(@udC=bA`dRH?f*rxvT10gs)1SC$S zH8D6-?3Vl1l6niy4DZ~5zg-6*B8GNH%S>7;hXNDU0l5NVP})!$!D0IGK8PD6vU+R^ z>>}t5BZ2Tv9(`SnPX9kOniaFQ8>EM$b+xRWFf&l6$PGpO{>b-1+WlpsIBz?oM;WMd z4@ml@49wAs&Bt62+6ax)s=xO9NkniEql_*Kg(pzUA!vhRWVRRf0LR`e^aKJfzR*}{ zcwjoxIG?M&e5DcbAGO9WLker`;PIFa1_N#>_#kWKEL?U18EnOL0R}$M5Bvng1Wt$@ z7@BuA>7SizY%n-tjYfl|H(ZzoNCb{ibm6U&3`}|Mz>Bjj4QnYs4Bqsl-+cxPTM)y# z#htZ^wTpEbAxi6gpCbcs`Ve`fex6#p z-Or+xa5n}5Izi?ZbZtBPeDF0)SoI0?=0WrqG3mfnC ztqC2D7U1;e2asQH$x9U7(K{b(*I1tH5I5#=zkNrnx*rr(^wPL08fOsD%!F8}(8$O& zY(RP?@$k^hEcU(Yt2y{;WFs04{2s`<3X}*MK^o?rd(D}-JQv<9#uCRqDxJMWCCA|iN+8Q14A>$3&Dw4lk5WvN5dG-7#>z%1&hWO z>rSjcrU_OpX}C%}7_681&Sg5b_4~9G{Q%i!G2t;_(XX$^2L5un*o{{9&2uf&m+k*7 zx*xk)s4@M??FQnzop!(vfj;b+kWLjiPs8rQv0I6>CU;@?Yr>+a#-VZCjMNT9SdFc37Ay^dxQ_PPfA zIy~3^-NqFmC#5mdK;`nj66cUC3(XywRCgT=0~{8d41G0@h}b@^uy*AMY|enq{v=$L z!4zl^1Dpd7?9+?9X4-Pl!T5?`+5j-3^Q2YWU~++2eqoXTVsc@u@aGyEpagynuCi|U zvz~#B6ss2iv%ZdpPN^RGQ>YD-N%y{ld*hTtKb5io0wjdD@ysblcAqYmPoLU|8iR2V zrO8=^bkf*dhlCt3zFdeLSE?pn&-;z&Jfmsm2 zup(u-4GyKf)ew}7+zcM17Gt%TO{LgIN?y9R_*@mbbDO;@Lb&wS(OGHyODODpvXz%V z;br|&UcM}sZ}9RJxg=&9|EgTR$V;+c-uhBra-zJ;>+u_xOi-~N7!n=&0@nEf?=Oyd zz1B!PLfj-vUxs7{8cAI*1?5)?M~hbbLJ#aAF1 zfHWsRwMXXwGgm&%b&1*ARrM%fy(X9`QZwF#H;+|}?}I-J(#KOQuwdHwzWj4u-!mYu zz^^=hn_59Q1`;3Yo0S<%Ei0|;4fbXKPCl2Bg~ z6iD!JP#?b4;jxU-dym+!42*RxqGMQ#GXW);xH3NEJvDM_AOmZjqmt(1^=k75E95kOE+yLhWz+~|aH z5pFKLox~91mR!xB0U(P$0P>3DAogcCwCNQ~_XGa~A$p!|xxi;3sBpp7#1~uff=w7B zVHgOY68?=jRTel4WJOj)okawQ>JC_7#mujs!fflu9wBiZE;tScEw!1*Fg`d!MLU=Z zzpj4*@x2DC&<3m7t;QuYi$-;aPYj_#=Z7cv3DBHW@d+FN%Rzp8pYCi61m z5r_brH3PCw7uuqhQXgiAHrV3M9D${=h@x3wYVv9GRL$Iw{Gt7f=)EQ+8KqNFl1hq- z$Ei;Y^sAB6a1$b-4#`96SYbdhz1b~Akpb~L~DIbj*!k^P=y6}<@7;mPgly~ukQ)cH!fhH#8~ zZIQZ1yhi#SPRlX9c03Y-A>+)Pjbwu`SHeX4lpMLKJ|#yk=9x!s@ESACq036j4K!f= z#gk4dIiHhHp|{Cz7oxX3+mUgNGK4eb?{$=Cw<0IQK0OdC6W)FTjS`#!eE?7ntsrw} zUa8Rf>{eSCdF1xK0f!3pm;hjbIU}n8NT&j>Luui{K2Y|d!N>r)Jc&ys3ylnl0#3nk zm=t(Eav^Og3bTpAsKt{c;&?gqS$-kz2&pI>Qtk znwt;A1_>-<-U^>gF&YFA2+;_r?~0p$M<%Ic$vLcVQNXcC>?Tv4XF38R-KZ+PtEeWV z2tZ&g0rBwJQ4A=)UxAD)i9q2BjW+tuTc2<32>5y~NJJI@hU@P=?` zzavKh8FT5mt?L9Ulw**pM1~kUgZ&OlL-bb&;LSASM5eHHhaHO#%<#SPiaHXf?YVP; z=n-K9aa`FWf)#3zc5+I07tUmS6tIicYHX;r6#q@aug(CQ7>JLg#6T*T%G`JNN>2;ctDgCKYu7rRu) z#SZtfy-D$%r^LA~yCAhF08YaRnC6Eha_BMeG1g8Z23P2OYv(Mv7+~#WU02ZLd_ok_ z)Z~JUqyi7@2hu3vh}9$^i$*vH_(LKVo;jpkFwW(4$q@l&x=Y{s`RCF7fmw~uk(d4N zMU-G5 z?fQkpsA@aKI&X68ssjmDY@n5wQ&Ng!e~}NIXyvj!(B?k-KKNu98-F0FVlsW(#^Jlc zbYBB4?U7~i#;g?;u26CzTy$6}L9n~wCbIXWtCFBUsJQ^LA!G17FixO2bYSpWYgZUECXu1X$Unm+$ z*s1Q*yH{{zzHR(+Xn;U=0~W})jWZK00rA8c+Lyh8lgbG3D^B7fTSPw)YQjLLOdqO8 zkN#Cbr`$%Ci&K4BY&eE^uu3uJ$w;>*fR0L-#tJx3`ztfx6s8BfhgKv;w6~5VHtqb5 z<4lRS1%yS8=eu~P72I3JNVez~K)_Is9Hj)LBu07ez^LQ(&!N{km%Z0+LSW!(K5AyA%VrAe*M|&h!#i_fkS|f_H5*WNVUd~g+~~<%>(+a zItb=swCw^pa;m^sF34;tI7)Df4lTlh!)oU_8BT$!asx5G>ou6orut1f$^ z=1~Ty4L$^Lg$$-Uy!uwO<9or|d?iD)H7S~#Q% zjz#*(wckh-Wr2hbvd#dvp7;mc0)canMG1YV_H!1; zZdRK|_81kS#X=lCKyBWW*bvjITgO07tjF{PM_8??wp_BU2j$bM;Up>`2JNxGcfFb_ zpHZ7T659f>w%v#qki`J2Qz^bQ6P`>2vf!m(?HTr0yifEDvul^(iNpR@v_0(;^WuuO zAKW4rXu8YS^U+MZmZ7Tb+O7CCf{-pBGxFQ^3M!F$18kF)kmp=^>>L?v?c~XXV=QpP zTp-S9crAS?%CP|-geiM?HN6zdbp@`+GzHvqeG(QfbiS{i#}Bdrif24xBDMrB^aqBb z+P&-GL?ET0CtS~-7QXj2UDzqxbTellLx!AgwG4C{^rwH~$9u&6o8JXrB8Sg|l+ zVMYBJawQz?MSo_CV$dimebt^&0FoYY#Oh`X!VT7?90Z+1H*_lg27}^3#CeO3=v4m9 z&tynkL)68{*jK+srNDk_#n&V%Z^9P)1$vA8Xjrt1&P_b@?~@Nv0%Sxv)S!M!{You_ zY;fl@kdW#?g2zBYFvYIlfZ4X|8}J*8Uum7lOb9&cWNI<7DkNg-L*;>txiD@yMpSn% zTsVyTE=*=5HNtBFGc=&goq-Fb1`qb;(Sm^C72Tc;I=$e;lJx<^ zHBD?k(uf^IXF7UkSTz(l);cJ*&^E}RHbApbL%&v(a1fqqC)n2O7+)KGE#(vkVuPC`DQ#)^(+ux zP01h(I~Qp3JWh+3sJ!&tdNLa|UQ@2fCkwU2jg-Rl@GKAS$%ibrW2nE&=h`2zbMu9|%$L zrMS)D?WxembMKzBTkq7QKAm8^x!*xZ3!H8)eYWx3kQTS`#UH-yXto$5bxc#aA7oCM zI)h!BS0g7lh4k@)_6}pPO z_o&cnj{fAnGIirv?;JwI5cL#G=-EJCV#0D+rM~wr&;xp8i|kO?h=TGk#Ks=jKdbh# z%GTe2KKS-tTD4K#H&jUV3oq>haVs0MYsX?UisT+_Qd!_8P+5-Dqu667Ay4udiJYIQHB+@4U>4{x$kM($KnhUtB^*MM0`v@7HHS?cQ>t$Xd z7{&(v;kkv?$6;fQKlxA4k5nlvKga^eL+!157gr=Ls%9mAn|S#E`&$YQ zaY!**RN#!%C=w)C$C5)>2BA?aDdCQ@KyxH>j6QH2V1e;s%B}6P{g6WljUjo=&1P-j zO4)9%kiXF#xFOOf{^q7wNb11oZe>QJ%uUY9;?!zYg(=yE?rciIU_%4)(qB3s~;4!rITtxIfs_I!N!dOHSMf^#Y ze|j(;7xYpd9_B7RGO_%0mKT5++DrN8Sia*y)BgS^!Ioc+@+JcEUtYqohET&N>Jb5X zH92BpzC6}Q11d#i_?7I&flcrYL=>cDxXH73F2NtWo`7iA*Wp_2wRduF*gF@p^eTP} zixNYQcl_`Rd}8a9h&ZsfrGBB~Lu#VI$I9FjWk~uRE3pHA^cQ}3YEaLTueKE4ilz~< zy2>tGXcs&EHxgl9th7N9Q+Vg-}f>K!h0^Pf>?@{WR6+4 z9l;LT&Ox|>7lyZU2CzA+<|Xb9r8o(UYd`GYVI8bks3nQx(Rch9GV*=;{q^7?x&qw` z$^xEOQ-i4G4C{9o4c-5Co;~Xv19}SNCfyH!@EdXfaP75B%D}O+3=PDO9qUB*^wp_6Sb>8`@LYy@3-r+|ABuw4bp=u-5{EpR}k26K+~IiT<+n}*j`L3iR3Be z16fR04BZYKSKJQ28LJsl-ur_3*hk9>dxe1XQ-p7lWWft?Qlva~GWr(a-LloY@ zXB|Su>cIu;QbO2{&VRV_L>_F&CZ{QGr*H*ifBrpc%B;Ld zf0aK&O_^7Og@SB3T%chRazYR-jS3AO`sM2Y4>SqvAOmjI4diG$C?2sFFSOTj`$y+j zsl^K+xu&v%Hb>O4#y<;gm(g$Zx9>NStBl4dNBA6WiHnX|HB~sD-e#2w(5DCgX_BC9 z#slmAqp)Wn7?aKPw@27Ri!JzSKe zCNoxD2{rY6d-tm_!4jjHWZY{#0f-$YDm04u-bP%8bR?M-r?u-^+?RoM!%m6~C1#rP zfD}DuRUe0NS<@<|!eiZ=>B2q^PZ{Ocku7K{8AhoMO&n(oLLet&u#KbEy~tzMaHz+t zaPeV1yM|2R;kd1dtc}jcQ)*nf%q#9SE)%0ZCgJwNcNxp*kj>v!B;p#Y9>A@u07x; z8!jw7jM9%-i=B-ai%SZ4cJ4a>xlx6l12R&|E5iiGA@_V7;~m3>-zh z(fLc{t%r17{=;SEFovz11cAG~c!@opMfDfIAO=tcbvu!* zdly1D%g}_k1YD8PM0^dDD{n>{vuFFNQ-Ue@s>dfJFxC=d+ov~v3G{m^=qUxd4)~z9 zp7JnkNDwX=(~~~~*F6!=6+;=rtXm$Tcoxr*n|x#Sd4CHANUvHQCgwjfCrUD8m97UP_5t# znc|@n`7n^Z==2dA`FlerM!fS%?H^nX(P(Y6YrV@~BA61IJ_J@u#@GLWq`F3$VyGb_ ztq*dwp5mz-UeS(XV@}mJH=?tJetTO3@$e_3K`l82Jg~+Bem;b9x+UQ`jW6(=>3#I; z3D3tNYXF|R@LE5g@Z1lo0ngL%S}#p_UO7OX=a8uQR{XiDP31wcq6l=7s!fyYJLNiE zuKjYIA=fkHI#aG^$#s@o-y_!}<$9i6kHU5BYad|v(de$Iz2ZJR)qlA}uzz2ue~A#y zxa}2dI7zizK?H+gN4;<@k0=P*NtEi57lGR1(YcVtV)&R^4e>>YZkxrAI1Vo<8AP{{ zWN6k&aXNxF(pzJqlglg5pNOIh9G<$o@`CQSY29y!bief`-XcwB90!nISM>xwK;AL!vz*&YpWW zHtiJb0K+wO%iRndNXbTZ3KOW|T(B!3$ANBzA*ypv5i!rPLwoeV5B~>bJW}i5{3~Sq z)*K>Zq?mn)=orKIgi~&^i(4aonLwqLBB>Z|Mj@mjXbx9@0G`o$C;DE;E7`5sK1sz# z)fAjG-a5tg&4)h{d}g=$TPz-Zc;wQbgDlW<6FPF9IW~?U1>q5Wr0K{zvBRTCk4q@l zb-L(}3buY+vFYQ2O^4t4xNrM?vs_1;kG!M5tmx@%dG?d%2zA5Q`VcnxGp$0QqnrT9u(a zw*j9Xhz!@S@X;WR3F6~V$K$cwab+6dG+OT0{SnbL8p=}EGPI)hA;Fwkw*0Y3@@40b zQ)0T`k}pSVOa3HI3(jCn_(gWUJ9?uu9@-CGnSSC7j;nj!uE-$J-5MFw8~WF?>X?{Ljy#eR(9(=Q=-vm@_74>~1^?B$Hqj;l~nqsvCO%i)E8l)r@$H zqQVS*+o}eWQfVz-=n7q}^0R&l>p)lNVyimC6`YQnp{~#r{ON-rboytL;Rl=)xqy@{ z)clJxqmefK93S?9LK5iTge+-N12KKH=1`kCVToUiBJfM`A^p9-(%!q3m-V=evo1d> zCF_#u(s}<$*2M{^{L9%S?89?LK^jl$`Pk1$Jugg!kE*yafR)6d{NPV%;cb%4QVNxs z3?j9inWNkN`cAwgg}d&@0II!uELx0t3MN?2B0Qn6E?pL|B%B-#1V?gOBx{ z=hJ)}ey?zQouiLUk83D!)^=$b*d`(x_h>T4O~xq8yU=qq3VINl598Djx`g@W`wS=2 zgW24p-N=@?k#VuAm#X@9oB^3>6Tx95p}R=;+#DGrRnmo=ja^iuj40{ zP6d_Ny=?2m8G`SwA1=h}O{!lu95nT_9`MevudKdOt#ILZ$u7V;EQ>u%RS<4t^QYQ{ z?zU^Nu>rd?Q{d}Ws@Ab@_EdL?Jxnz`oy@i&*>a55KeSiyHQDZdT*=6I%KHbR?;wn@ zORqnbmz5N{>~vlhGmTM`iHLpDMpqL+mi?`#*bKDl8}Y{#8mT5{g2N>L*|LIaEe?>xwUvyr3oK}aL!I3XKkF$CJ1(DO^RB(VCg(TOz zN_@>Uk=qQ5ZN!nvG!$_q%rhR%R1N8%pyHdD%=h)yE`Bi@y3!hdf(!-No`X6M4np9B zla7HN{3hl_$aEgLwDRBrA(K*%=|WV~cd!q2$w6-S%Err9fsgM~#_e9l5DiCu^Ev1e z0K+-j{@4c6H3zWmtLEti_=_shs{5e6^Xmr(#$py6!;Yezpq?QmXX!g*CGU}vx1%J# zb^624qdI4%5jcwJw>omVP#`aKzld_?;x`(cZK50+f&YJ=4-LnHOtq49jQ$>nw@*)n z^OM5EeX2ue4 z{~9?>gzCRJoDc7DvG+?+Z;s=E+SCbOas1b9y+npAJDnT=Vxe*$?dh=;gppZ8PJ#ZD z@TOFah$sfW3KuY7K!TVbC&wHF|G&E}(pLnK)`=Ni_)Zud5MoA?;;s7`2foD+o3Uq1 zs$=*L1jud*UKc0va{oO};-%A6xF_48V7`l}`Z4J$RN0%bU8v_xgiotrQ$Nr`RzX9* zF{kJ|zlG8`@FvkMBAgTc1iQSYVCzW11sa5LB$%V==^o$=GGgcLD2`f`1+4>i}PCa1%A ztuq*e99vlXt$^%7d3lF}Mo`m^}# zTnKce--N6d{f4r;)3+iW=S#33%+(ISti7g++v|X)s^ad*b&$q^&+eycS%@I}wX^Xr zpML;E#hd2K`a(P>a*^F6biKG6jzLtKDr+?hMUlBuzt~9pUNap}OZE5P1TJkoH34VN z095f!fSK)Nyvf%g6obpek;pahWwGl?)u6k>OvFAlVH_lA6UG`{LZly*8+ea+Z}>%Y zQtMS-7)6fshFrM*AzXTth%2z6hp7w8pwLo}VWeFr8!dBEDTIn?HlF-52~rQ|eQ!&@ zCJ4e}1B{iJhZ5EURn(3+@1Zhg!M5+?4TUpQ8S{az#RJh8q{jsRcmEI?g8_kHnZBmu zQwAK_8{^eP@(yLT-pn3AeKNVq@NqFU(+Gb*S0JeW@BEEEBk$ODCp6mA8b3G7o&2rnbJoc;<`x1MO+n(dG=cE|h6Bw`21cjyMx^-47sJ&$k z+(?wfP0oYne(ofDZjn9rPJ8Ysd+s=UZjL>7hCTOId#)cJ=Gc%E@qbbqol$fBrdPnN z*(A#6#h0D((xrZY#09E9qFYrVqh=RC^wbNP_0;t-eav}*S!H@_aX$!_oV7#L+#l!Q z=vzFMM`|ps#3d|_LaGV=_Ky= z80wTkE3hGx;P4j7m_EIP_C&s!slnvw5vGlXO%A`;8Nk8dljra$bWPd)r1o2yGAU<>>P9q8)y}s(k;H?T?)L|gI z$hUcWEqlbiFv@j_KX4uv2D7L3z!N}DD;EDDM9q=gA-PdxluwkFLTym6pIWOE@RGtU zHA@Hh%&&hJdjdY!JZZ%fyJkk5C+lCxqd=VRdZ^@%s3}F1K>P}GuWT+s84aEf149q< zJ?g;I4a*5a|q8E{m1$k5@r zp%E~|xFq0?&d+1l_i?7cfL(%~M&Ro=itW=VA$YZ%WLJ8y{`nc05iuysCr`yIm4Byo z@12k-kF)O0aY^TcXn9VkKcw{=FN4p5F~uKRU=Bb1i#^mhtbEF#Eh3~d+t)9z0FUn( zbE?#yHc4l_0yI8t5)XrtQoUpYg~ri_Rs!Q6Jur*9WBa%t&7vg?-k{K}(Z?s1>X|GC zqvbLhD|a&%6`nk_6F8yaMGPvw`H2?V%icOhmE5op*rUls*7)PN)-l1cKs17$^3D?`IEeL4}p&N%`fuSeN!&{-sQFEXk{fRL4DO4Kzqk* zyLt_T=D`3 zi3FJhm?++uJ;kjGHf85~O6+2UQeCh6e+e81BaADfq4oO9GrVc3P7ljMJ5Y3FH?r9ALYD1A?G55ZC~E4j}I0x{>p1MDNv$ncWIwmEwRwLEry zn#xawX+5r!SDch5=^&vnN*F<5avUi^njcw4!c$TZ;ZXNQt{?HkYAM)&3eX*d=ijMr zvkP8~)0r`AX|o|PGw<6oU%-YPp=!B-F|r{(Kk=$x@ahX}2J|n3{eqDSZGtBk2B*K* z|1=ZKUCNCb9G-g{`1k4;k@}tXx~~GdoDN{{(9Uq`ChIdVaehL%oJ>xx*76{DE!r~= z#^V8%4y2b?;ltg4qys~-ZgY9-s6?cVG&foFrplApojTd6i7wT!Bi_1y!&|nqu?L$2 z8AeSy`JYWaUZ86^eBQGHsKb$8Q6Bol4QgMxrkc2IFn-uYd_9=MY4I-q2l`-DZ-AM< zpr!558bLmJ6Q=0Xj%c(cpESBlbj5&Uu4`xw)>ZuI3N|uu?&1uHDFOPg*!c{FhI?2k zIsl%k>vmzwHjqBCL+c}hb&&VVc;I1=bQQcEt0s+a>;jsr=p8vf1wO^u{pgX`kqxs5 z?6B1A!2(6t1ndTiVCSEI#4v`|4|4%1X@Do^X`CSQ z^YniKj{++NMmEkSI=U7I39Q1a4_Qmc3LRT;*t?wUA?#Hvko2)s|KJR0#Xs*B4fqH8 z<&_xEv`IT(SXtpJLwF{=Z5`l4knQM_GVR43I4Du@T}#u1O=v0(GQ~&5(`N|67$A>Q z#7&{DehnzuHy3!%#>5-Ecl}fNNc(KyF*~%MdU()1UXV9${1&*cpWwc}>T_mudfcGC zl@*;d+o+(~hFx(2U^5tf(zo}$lni?H(KTIWm8liQj?1eQG}g)fp3;4IM_GK4Lg!)IA^{nMV|@| zD+pe?HBQe1HI0f5Z2V+3J5#~XupuLni!MHdBE=s-IgJMF$+yy4;9jhU_D;f@8c%#D z(uvuDwLiwU#198KB5GcUSXyFXf?Th3E@ZxPFNg zzzu{acxfV3+{09_o_Y~op~=cA+GfyYo6!~R$M3WszqMtuY&wyM2s0*uXs8thg)vag zzm?WSmjaMv2iFb7Re6~i;W{=;&tqyuy%G-&85>Jyc$YU5*G%z~6cT%yl1v2T=d=7G z^%;-TreJz}kp>gJ4j_7U7vkM?J#9Mh;wf;PQ;N#;<-q^W$buGVJ3J?0rLXpa-*;HBs=jf{y|Q!d_P_%3dm3IG z{HPv-W)pZT(+WDLUypHCapSm~6?o*7%5>B$(|y_!*kqcXxPz&FKeCb`^9&6bDEnlG ztP@Pi)7ZHZX2ZpZLU@vC;X+IWjHqg%)LqBFdlxN@foTas%%tVlFa6L^6JKDIgvtNL zU+M#F=lREkuYLL`|15wtnZYO6XAq;?RtiUEafT4B63mSPu8$YNMj>v2(7n?h2jF-# z{tjj-A3_9U6?C}sz;Rn0$u+-H6(?C?JDUWMRdp*IaL*1~9r%n1kY`GjuvkXyd(!62 zPVg=8Xzj53SZ}+*XIf`GHSd7|3{S}cVV0&(7WM@x+mi3WS6qN8$b`qg1zMJ1Vys1I za{MG-mX&K8T10+X%yj7{%dl?PWEU#9TqN?$aF%D6jh-N2(3(hpX7OgXC#H zo!;%~V0qeC_lZ9(Z~mM2iqmC*{`zkd`a(JdZ+C%}kOzz;Z1$kROMgX8NykwiJE3&6 zG#!(R_$bG%m9qEZtl^29$tZ~-6{>Smz$cqvn5vfTBEgp}RjA&d+2MQoRd0MyU zsJhpU#I;FiB=lAw+PxukCBFT-wI@9{B0{rC*f(KViaow5Dc-tG=$f?{)?DTGloZhT z(u_=9_wR$BZ8GDbt_3=*(u~t@Bl(;w=*EIvjq5yIGdpkaBHUz}n?AuoxLJmqOMxmv z7pdENX}X}3I8LyF)|TAeOY<%3TqKMb+Pr9fIH$PK`w*Zoxl+SJ9kbZf^!7A-4w)XW;*ip5@ozo zR_>eP4pxN6rowI(TZw@bi#vRSDA9t`I)+-1l3kEl=7(aSI1K?TRY7KQvmX+C%0rCg zNIncJEKDgb`E6XANXmL1IuYNzUmMHKD^`wzV#~^{#YD1M*grD!%P+zeaI~dlOm==c zf@EU)Tk>@UQA$32hG&`UM#@WWddfq0jziRe9!_A zBUtyQf;CS8UnZMRpw*o3IM*en*F0yw2-64hfY#+4cI;cr)ZucK3yjngtgJ^6r|xcd z=#Ri8cpcyG-S#OBROI}@v518McD*ArYEQrnq_iY$07+v{NQd)KNtRtQ(k^k^B_6vZ z%`Qo4nZOlv*(IY0w5&9yDOMrNo-opeQe%S0o{(lwNI`RG#hx%qH9OT}v>I@eZo({t z%W|MYz}G<2^|2?q?TH?HB0$kI-7d^|Ghx2L`qVUt?t#4w##IiwR#Xl-W%|ue z5@@NfuCUEi$Sc#!6Dz0*8T<bzB%c-|9$5fc=i) zp&@}mpmsAN{Q@K4ozr(#BFFk! zP5rxUf6Za<%TEa+coX9U!#EAGXJFK;uPTJqQVs&9V|LV(ELA$v_9P#$i(v0{q3s6< z*+nS{I1d8Gj_{*`FpPc$Vl8rF9L^MxSu?qsh(4y9#L)eUM6PDr6N zT0o_!o1r@PsHrpJ^iA0efme~jGi8Z!q2-b`fQPakfIM`s^}sl|8Xm<8wG;}Qghdn_ z7gI02{jZ900c45UfKGymcz5+u=TcegTg&vjA9r7CjF2cjbR7mW`3f_bbQuh7R~YZG z*U?nObP8j;>lB3K-7f?fd^OI{*8o9l3lM(_IFeCzDYO%Lz=}y&p2=Adpd*iRa={1S zh}Gng&<7+H9L8R^Cy%oyyBPwY2i2Px59U-^S>6@kTjkm z2{>9kjK2i7miia?0?1#sH&(k_Dct3sEm&0Dz!v9pvzD>a8{ zs(czCc15`HI9ta&T-cXa5Yrx2k9B8muo0?{fu}o>3!&SpYp^PqTpU8()eM}Np6bXk zO>MtMqaqKdu=56dcg#l=bg#wa0Lzr?<#5fMjq^VtLd*8QL$e4uP4rDd6x^`X=5F#O zehKvYGQNcfO}xHg-VCcn?9XE~$IuJe1R@F^Rt=dwrd4JDa-CQ4Vax#X(nEgLZ64Wv zs9pc?b&(~W(B(mh`HDS60hA=JJ&Cq=^5Z755s}OZV$3&J^;{_QvXKQjSv~0*_>C_O zSBWeWIjv(XKb&ch#A26Jx=_9G!MQEUM|D@bCwmmJszFPRw5n5G!9q+EouJ}#6dP3zGj9Dc0kcD)|c0K}%p=0J)kj6=D4OV$8Vd{~Qf3L5-9zF;DR zw7G7E0raTGpK^<4qdt=dYD(yOYO0(lN#C*Ku4CT1)94RRRh6HK4I5mjw#VjF0xHDd z8_VX}W$ zUtwIHOi@V>$tVSt_n)B0c`sBfV19Ki5kkcY0l1!<9guj3yf_zGh+J|GLN#FrioiOP z0_$$$fur1q077Ti8P9POrOC3-L$6z4p=`JQc37h-AD8$EZp>L49ZeRBCnAR|;o zhqsOaEfF0NE<;i8>L)q<0?Ook&p|qH&=Ps6Ye}^kPEz04&<6Zd|eywYGU(x&e<=CoH3c7EM6Ek^Iz0q@b z#OHzY47AwJwi8y*sy>O%eisvJ!g(*l73Ob=sYj|-X0WFq8#93k>SgZvtlI|Tn)in> zAV}Ya4*58AWHCczh(i(ivHB!VyZ->?8gRAkqmN@j2hL1LFFK9z&};tV?!P4vD;!Zd6JcT z9tT~`*7fL=v*^H=J-Za>gR!4`?n|m2P8ZU=cwou%rST1NOvY0rOyNi6%$8hFQj%h$ zR&Xc!&o_Y#l*5%B?75==96%RWC@d#7=2P4prFzKz4yX+lcmVbx)XvYXIJxA%Vw`S? z930J%VHI>PsqQ)nd$#N=@Kn!%h>eGs+1&ViPnhM=s@j7$?8^Es>^KgT>u*{@LtF;l zpOoekl%y%lVIQ2bIuw zB&h^F6b{JZiTr-RA;QFM!>`lfw?g!_@T3d6cflax;&$YGLK0)uu%ie30vW)s1QAX> z`dx%kH02=-Hsv8OQw=?l0}x{pMcnMPa7f|_7NgSuCx(>%6=TvF@l{%HbcVsN&tb4s z{L$K@_X+hIRkaSGJ)Fma(MKr6EZ96Faf_42ZzJ)nEI&GiaovU)Hn!2hG0|9VlwA76_!y*FJlwnGC(xReFKa1jMFAqa2(|=nEJzaI0i}k&0n$-o6 z@M2EAZ@z;mON~Q`dV_+5I08bO5w{RQ#qA^+AK{`EoX|;E#Yjd(E-AOpi^d2?37mBy zh{x%wf$`1aEn(Lf(y?*l8e>6ajUNZ&Au-N80?JlaoJ;)`G~jg@fU_>cp#cYkZ?5X` zfe7ptk)wDXMu50E)_wdtfucFbjvmolaB{$UIj}Sy@P$!iLN}JGwFC>8U|ypxP;YeW zg3N1h2n}^nF9t8F7@uw! z$H2e^)-DP^p!+83IjH?NphG6Z`UyNwTp0(rgL4ga+6~+C067d$8%Chm-*dZN#~Q@Y z-8d=K*-3*xuEpiWUqtzL7&38!>!CHqZ!i)BM+jUl_80~jV}rT~_^F#B6oau|iVxYBa3)8~>2- zu2oU1;B0{(Ez%2BJ1wJV-Fo$Osjeu4qG*2a=X{bjY0LC}zuy-xn$Mr}Ie(t>oaa2} z`J1BHkbQ|%NamC&+Z6Ff9$>X}VW%-&FU~j#yau0w&fLQy3&6kzMI4fKGPK2G*~5+< z$nkbnX0Zo}5o}>`ak09MF5D^-uUtIaO2>-8%YkSV75*|3Rhi5Ps@(yjtP)yL_R*A6 ziJ3vtBv6{O?|Uj?zlROn@OOczNyb3pz6=Q+@-#Rj+B{YlsvM*%>$^?$62iVU2*WN> z^yJW0os4fLb}p6Y6@Adj$gPw;CBt|zFL{yh1@03srl2LyL<&XbNZIyQCRZdF+n*&& z@E(TX5=OHRTyBQx_z(zcEl9Z?g_V(?d7_C>Y%6<(3yZZYdf(xhykN0-Z~m~6n&emo zXHnG40-c5~oV8rb-3Wh7z%}`N0-pnJeJJuBTlvcT1qrcwoIy%tfE4af-Tm3uAyIR` z7Kz%htcOIAJ3EO)O-hD7;ABo*noMm=a7qpd?jTHDc}K@dEi&x|7)fokG-fe8aqlt3 z+)pcSt7#M|%%O9IzY^8L8M3dEx&aLZUc%ytiPJHGjl8u+-H8@*L5!^pEo`!!Xu6>8 zaVgr1as7Bcji};v&RXp|Um`u(f>Yb!7TJ0@?^lXRg?XST>glHtn}v;XjI7$%u~3jo z*Qrsz|9ooENd8iQ7;hPFMJQ}*|2!sU30{T0&C0)1@CwULIs0#)1zE+QKPhdEfl+pAUhW*5r7TcCqXZYXsq4g12NUbvRnDnSY zt}I|<>@K@u(JU`rRtE!uxHuz--j;~+0Mip}3JebgYf<&XSaaOjhw?*Uwi7a=$qy3U z-ZQgAfwQRtN9?e)>G0HzCTl@iXJ{#8(yEqHOl`p0Lf4m zY-`lY8^hZy#BL6}1hwA8`(gFEB!xxM=xsx82vaT61Ax<4_JiJxP^)@o`z*Uqu+g$= ziaGuAet@(34e_J#0P+x{yn$_7(lm+Jvm`|EZP6=8eeq{zVz-Ko(QI*V{e2gdI5%^e zZz0CfzdX&iNay}voaSSJTH(bSm^Ct$tM49%*0pq84Pe#ZA4r%~nY*2qz?pj;n`Q4R z?YrBVuX5i+ZjGmpagFoAUAM?7?L||}oH!rKo)KTf-6G=Y3+mi`RkaJ8kJUjlh*Goa zd_!*|>V^xC#RxHAaRtsWpI~En?Zuj&o6`9rz`qFs$<_c>kK4N>9luX=_)f5zv%ZRs zYZ6p@cMlyO@DQj;_Y3SX>g|{*36UU+Cxs55^9|^*D6G_hg>WwMbYu|W3NTHRqJ@$=d-`CnXMI9KU)+TA^^bVh7<0cqH z@Fi0fb4abZ3-Fmnx5dU8gn?y=JJ%j$TGe`96;@376DI$+N-6WCeW_;VOSSc3O2&o2 zMFa4pM7@E#)A5p*o@wecg-JXv3SAtElKhEG1~;nQH(?-+T!LN}nf}xGK#`~-PU6_d$|8nLp_;rNK-PEYH11DsjxQo(%}(Bd zeAz< zl1fw3$lt^aUJC(x4Ne$;qV6T9tJ@`Y`$wRBjJ_a$(h1)zA&L@{^}4fH`P>69EdOM1 zRDM}8z9pw*uD-830IkK@y#Luntd-xMe=CQV(7G?kVy@385C<51|C~=nPE#kpo)Ed7N_A$y6c(@K(#tD@L4=bu!?v z_vwhQTEOk!B;eNOLN?>`Xs)o@{Qxf&N7(4u9&2RlNV0|$7AsiIe)M$Uk8GC%BSp&h zV#FW->e;;|JL|Zc@y@(1L#t;(FUu0K_|G(_$;h(2W(m*b%3 z(YP;GojOp5JF-RwNb;Eh30u%YSHL8W z_IOn%n_vPqc(>5+q=3cDJ(H4SV}9s&LWzkHB?uPk%!0y2@a;Tah#5%$3r`NA;*-WR zQ&TO`rbt99;rx!N@$}MYala&05QAh+wuIrSUoW@9#1KLrgGz}*B27qOOdW$nVo8cV z!2ObJ3(l%-TpRflwbbc0s%MXO8|yW_UoR!3DqsQ47gf2?{L-<;#wjg}W{{UobYqHexz+%Kg(hy0hDYp>VF)C5>qLv#Rm>Eob2XcI?U zx=15u_I51vJ9#D|hmn61U4H7ihFgdqy^GeM8K(2tlLUS$-l^T3{yFg@T}r?^HTSPf ze7D+;KUM5SX#!gzi3cLU2>(j=BSwm{UkSMU&hQGcppyPsN zk%v~Bw&>~4?6oV3)9BtYiXD-(7kbzO1Ng!yzl|o!i4}_5EH-DAIV_dnp6Jy^J>+Xyj8pEnOdmk^ zkK$fk;A*Bp!o_DdC-+DErE-rWzuk*JBB5S!xM~OL65GS{Xw-l>-C02TpG+^#4k?=8PC?oZ-=p1h)fU7gbzK*zyJX9g>pnp8cmW@O29_L2EbI{ zc1z!cG0_}~Njro$3135yrlmIH?d1LV(g?AN;&VM0H!D2=yQ;hc2F4zC5)2eWG&(pbnW3904uxi{zBEh zUSen2O?o{sdB~b|ITV-sXepy6F+!P)gGQH@{u+-7Ize$ShghZ28G?-9uMLYo2CpJk zT5g%~;@0G8q?;mTRP)xyc`2zGdlIBS4uX;l!@M@Kf}^D?vgF(NK8h$KUo1?+vs~d> z8R1!(;aQXFtxar7*bIlA;W@VO9D8_tqIta_jK|dO@RF%`qhw#nhlwKxZ23<>_uGHXGfN>I z9?-E!`lJ>?=m|ctX*DJD!}F&Kr|??)kLFs!ZdH1M>79K$W98;XZjv~20kdXp;A`&d z$D8jc)x5dL154Gq?Ww#uz%hz!9^A?@JUEy+VXW<*#WsJMXR$qS(R>2UpCvETcuCf& z@8PL2%@rLI`ktMOjPT4%?LPi`l{p=2IycZrFZB~%pXu>FB0en}j1^h3t^1SFMB9PO zKC@Asxd=(#n^m<41~?~bi?myKQ?iwOhw3WaWQ{Id`&lExq>?=}m3`NK`iSH^OH<4p zHC}I&kCgM5>?QlvU0G1M6`5i0>Tqx~L}V27yqsrjK|_ptGa(Tl^CI^+Sy5StPZM7v z9M~QX)R?o(2je9H*wd-a$O+a*Gfx+)ZNGpeId00B!`=t0YVRc`%=R2|ta=|rbDb0H z3J14T#dsR5$q81=jYPusw&zGxp9g85H!3IC#vAE(!f_WbL!rh9Ji4N1OG`a3KyWJO zMK#h6pcjeAc_aLS`FADPMPlBQq5|_hLXWGYgxmXI&?bDNS z-d%b7Tu(P19kGCwBul{X(y;EBC9Xc`n}p%Ujg6GX_~IZ|9PfewadZ z<Z=WaWh~Lg>!lgZDvxt6jO1g4B zp(qqPTBQC#Z*+}hnB{cVnW(Xq8W}-!q7gVI^>zM>`Z}e)2gTjCWD6PDt-G`V6n4B1 zLOs0LF||v8v*06zq}e5A1bm>FaZXMqLQFP(*Ww8sXpIoK!~29rNOX6-Q96{wjub9_ zIioOUxnMu>!+1o!1FzT7U;}I`Z2s?ugCyVGCau9v4#t>piOqQN=45%jAXdpXR^jCa z!3}2wj0EUy#QQ`c-l#oF>G*c$Tia2j0iS_1p(=!Q)4js(FX|6( zEH?*)w{z_d5sA*Sn=mIYrrbg)K8*v|-tmjL%oOn20k6#j?-lM9t`zWIV61R4#*2Ff zm=zMTxfi!y-#ccP#XnPyAQdI7iunI&83NHXOin@v0eC-+E? z1YB~$eZt^CsOL5nx`62s8AU#Fe<^yg@fA>w70)z;kV~(wkPNK;^W$^ZD43I4JGjf- z5gAH2`P%CVL6R)Pgp@c|XVE;A$8^Eua;`Y^F*l*134G>iI8l8FN5^ z)nVUe`kD`;ceyds#g?(pe`ck%SiLNg)+Rgx@rzn*%w+2Q!{qs|)bzCtE!+(HHJUOs z;n0kA=8UX1(v8((Q6T%;hB!tZh?Q&z1vit$jlPdYv=sI=nIBl|#LU^dMNATqFE#c) zZ8p3QS{bi*YxH_!lT^;PV<~DC<&1YLTY(@#yxFEGg!aLnSL_wdiC2jFfpcS_8vY^d^4mbu(g++<LFg$UT*_PKqbcrHc3pmaqP!$F=k`kdvn8`Q8KFE~{mvn|py22&L@IuwG6?HC=V1|&P)iR`V(p9iYC)`5} zU%UEkhMuS^StDtK0^L#TAWQ(Pgfxdr!Jr$bie$gQJ}-Gw0qD{B<`>80i_Wk0g_oJk zS69)XF+5Z^oj|~42D#n+-#~!DK_|i8W8=F&<|0jC6gM9vXDz8O@HB$=#|>V1|H4x; zk6KtB>YUok%jpS4OoH~#bTY)fM7tU4^PdnkJR^E>L=1>@Cciy;u)!w(7&dLI*I^Ap zY+zPc8{qdI5Evsu@uG3)Wzb+1B_wa4VU%i%_}W7Y+X?KWpf3nzde2q9HugquYYvMC zhsF|DcsSdh$J-v1hF}76*l(=M(?S<;?h;dAmJAZHW}`l*&f`_VZ{)yboeZzAEl(Hs zxZGIPo6FNqyvG9p206b382O(k0b_0wFbG%$B`Yh0yOjta94X~E89z(T%2I9kD`T_K z4X_DJ)=-%2EYDQS*AmStSpcnLA294dBQKiFFiD9D*<7kM8@dgal$DUDypDwOgEi%! zB-KIjd$wDanid&yE>Ge6gr5jDz@KWCOcaVQ>(|Wdk-65RwELq*(QttsYXs(SKu7oLx z6Q};Y;f<~qWZ#Gi}B{SsuxW2}&>-PB_??Q>?*<$_7S@lu;{>}LP5$-ix{5LKr z_Ylts!A_ud-L!M}YV0r+(E^3IE+ydF4F5@ze*d0hV;c zZfp>mLE`az2oQSVnc2=~P8#*XP?sp!=Dj&3ZB|(3I(8mkL-aCtaA#m5BToI+#cev@ zQl#heCO(72!Ec94b{_WbJW^hB#9MRNyXQ!GZEK*m<9XfV<{TKfV0%sw?)exz2CGbZ zyptXWrN^E0^*XSk^2)hPflzE?O}xi?iqnm0*}UK!U>wk$ZqI4TDQUHqbmsVUk0-l> zdk9Oy9OFQ!hATK%$5c)`(sCHASQ^8V8AB5RNqV?O zI%h70;VM(auy8`lvU5(D@a{noLC@jpgyb872}K^BP*YrR0{XC9y?#$z9HE0xp3FU* zdpsX;l`)5W>3*krnD9Y}B~4wWRqUPT$ii_D2s^QG1{?1hbL5oZQrkI(ajo7U(yC}E z=Sb^ksz>$X4D||+jV8h?5sJsbn@R3Kx1a3hfwSR!&O&9$mcZx&f-plQPaN@`PrN(! zc<6()Qg!WBUut9Q-C81Jws?X1hg7}5#fJkbQGV#Mn4P#lk%E+x8K*6Y(dYui@o9{m<1kG(|!zhE%t6_8N(6(+|?V!5}GOH z0)Lr*t4@DtdY&VHG4ivFnR%%FFRc&(hx!liCn!+5=P~-TV?-}$AoQ6ee_WEK8b6}* z-7pwm60`A=5;ThVfOm)IWO1}Y5(M5N4B}9OJV>5k*tpN1p<2`9bL3A8FR>9>78#tT zdl{-O`ITK>A#t*Y3oh!wX>KZy$Q=TN!})oU{OP@+=3&i6l&iVVBmtyOqePI4{K?qp0(uejB@CTHol}xF zHZz=n1n#va_W8w*q>cVSxV$C4%gdaQ7KK@7r6A_4E_=j#kpRbgxw1!Iq!c%rnx}Q_73+J zp_}p0U~@8sHIdL@MnRTm=G1s}!Xg)xeyDq1hI6f0h+!%94onY1hj}h&(7X&9MH@RO zla**w4_p9|SYV6NJb_isr*;+8Pwml5q*L*yE_JVd>WWfB2Epuf4H@c3`e}wq*w5A> z-BZ*$LQm$GykAf1o(o_HQP%p^u(vwm@2B+U-%N zXPOB`%#09fGYcigrKC>i$G?w!y9#jKJ7Qy`N9BC4G;$wB0JFxz6yQ=(m%bCe8%;JbLOPuZIb%3^my7 zC{pZpDWdc%VQn(hhiRG=@~Tx{weiZ_ozz`FP8`oO#cixin5x-X>SrR^oNdF30H;<7 zttSB$_xZ0-m&ZPhn}o@UW}LB#QxJA4r2;%3dTsCD>*Zhe=`{%WuX~-5 z((B&=4vkE@*PM?2&wC9GJ_*BUa)x#V#}tb!9%QnAL)5$6TDukyBwR#15@CekKL=ro z5jA4h?kA8MNk~%mX)zOk-?p0tt~6Z6bNvcYCOpZ>=)%Q;& z&|)ZIy)~^MM@ehSIp3^oGu#$1m_d+mRMi|IA$$X4y|3M<%kj1b(yf%^hHw&foRV|A zZSrUj0wm=9nl1*^Uq4T@56OY|7Gkx)6g2dn?9DO6J1{M&1NPH&;FxrvGu{D~QMcT8 z#aq|0R`i%KLLH?g#Bo8zZlD8>I|!{4h)WqJYI>^$n0;jgTK>Si0BBuFLdM`xE6jR^ zNs= z3ruh?wFfRR(QBw`2fZkGmbt)&s%G1PalX=)b@!D}MJgYz7AKx$o6Ofx z)o9k~GUd4=)J_vX0$J0m)-<@nsTfNP2dXZ@^sxsKp%O!%8}>oHa7q&sle^bo2P}a+ zh^{o^Va|TRQ>BC&$9r{8pPA#0@%(t9)d%>pJF;F3TgY*RQ#NEjFDthA=8Enwu;1!2 z?*K0ejO!Qk0MaDIV__b@C&I8ozi~#~5 zCDf`b!dv&#s|#sf;fjCC>YJ2|`}o7NuCbGaWypaR5)W9;GyW9=o@M03jg9*i@eY~& zpfrj_>~1Bc9;76(vUCVy7#Ux)b%XFSxv?l3C^7M{)))3GX06d>@M>t*Taa`j$CyOL zI4_MdO?Rzz;>g6@;xI!U@b>1s>XvR5QOCJvN3drK*sUiB(Q% z)S1^iXMA3ag<}iS3aBMQUlAI2VW`%eunjatzo(fzGDniz5wS2*Vfueb--*Q3b3js? zn7+$SJALslQ^lyJ=xYM;qmt1Dj-+wGRv@3?`{mLG%JRO-W0SbbhkYAy^bF%cHm^dp ziy$8ysVkTBL!QJ$>*mWR&6hr2_U<>#1`BT*Jn&Tr=73C=X=h;FYm}f|=tj)HD|mjy zb|%+R(Fwqz$vadIhNX=Up*d@aCaTM(aOAKywKR2s=v_MjpXjms ziV$kG2%%XRq~v;A|5d#(Ma|TkE%nN@3{-Ek)QhTvc!2*6wNYh%O+w!!GjrMdMO=8u zS@jR0O#@i*h^8Z9EvPjeVkxf!r$II2>xq@Z+=nSlHu9OQ4&c1qum@eouq2ouOVN8X}PxWnvOXs{@U=J$jiIxhcwj zQ_gbn^6jT7PXt?mkf{oq^1cb4*o~8nX_GMP8KOpai5hXY-W^3&kfx5ZJ(*ion))Ao zon_3(^h}$IxP|~{|AVA;zAyviu8B@Ve1X*B9-EwKo_hNWkuZ?Aid(ZT5jr5|kRn9n z%TgP9ir7s#M4Ee5R^S!W7FIaXZ*u$V>qypZD?~i zfThirgc2)Dy?&gYA-e1izgoekfGk_BJepu71S4F041??F-Kj)JooZ|aCTZ;(E%a5r zVHbshj2G3(Mq6;z;TQ6xuP;p3e<$m|Q_L>RP$#>RyKr@19vfVZMC9{<37{Sd(9w+Q zG&Kg@GBYWInXDPqR(ju;Kb03fRrVo`n){xvZtv;TFyjRct>b<&zCYbhuNINf4BR#S zohfp-L9GG!x?{)vS82NZw9xDRJ|v+-a*YkzWa3s1tsek zLs^-emq~XglQk@UKQ=zD&+ORsnyx^AL|^R`;OMJIT;h^WzYqUN+7%<(oMA-O1Jza5!u$>>~LOFfj8k6{Tp7&c)D zS$XArvu;m!pvWk;qtvn+&&BnM#Tnd=mJE2WN=G~=P=1k-fp0(p{mA*u-iJ@bNK{gv z<7=|AlkY`dh%=Y&ZnP+;q}tOIxCt5oIU-U>LSHFF_m{$E|dJW<>-+# zQDL_3JM#W}ZO8XaUorg9$4CCIFMm4h$e|-?Qy!jYIkYcyT@CVAycR@YI2y(nb*IMs zy2N^L8I#U zy;&Hq`waaSjKgEKJ7*UOr!I>)u8dv;(*PgZ0N3~_FRVv%_J#wsWT485*sjO=Dgko5VsTI&qG+2*`1{fYGAQ}Xn_`-w2Q=+bu?dT)7mpQp|ld7i}> zu|aN*k&|4i-P57hr*C_X?`csS1u=;cUiS4IZzJpTl9cs1I(dDlu~Qh0t%31^UY!S6Kl@~L&ST~1N7@2`K8QKMJ7NvcXf0{Y zIT|i$k1x<$>89r(3tx-^;)FoAq0KkM7Q)5txp=9?*Ql;muhXGDA2^@+Qp_YYJut9! zXr+D`xUUiOgPem5B*$mB`dr~xdqEq1=yv8Kv0!I%eWXhM9$896uw3G(OjN8t$W4H zmgV_K&+_|YG%vOI;j$?}wyF3XeTbFwrcnYFSs8>03jEz!Y8{zBJR*wpK- zz^B2)Kv<}6nM{qGqRxg7dM<7#t=XW&DNC53hrUhihTdqxgGDxPS`DSgUkFbmJ!I9m zds&ChTja#lmmiXHatPAI$E=d|7G^!KuwSfqzTSQ%GiN&oV$S0I(%UKhviI#58)g4~ z?fg3Zk}Bn7N55t{)FuBDXXlaitU#3Ti1Da~$dFiWe7yQNp29hbX<+=IH|H%m=w({e zv0D<#r=-)cPPrhtaTLe6pxDg(hzU8JLpg_QcK}_gJCKPjC~}CA7vsKhM*LO`J-wY0 zd6z>@dnps3O&*Gb)iSD6>>W7sM6-c)mT?Wf0+N4aHY#@9mF+zu#L~$b{GN>a=~=8X}kU9f6X`J@x6kme?*9 zP>FgsweK}b_x&7tZS}E1cC#h2@1p`m%bvqHO1h$BMf4;ukC`t~)wYYgs2%g-f#fOD zJT$v}kyyoJ9W_Z7owt=0J1#CMiUryRa(ie+!m+{@y+VsQq&%sQwPfjZ$f?wK=u^4%R!%TGcB0-%bW}w6>dm>r94f4Vk&C%u^ z2P(+FPvkXj*C)!R2+XNb3oYUTauNTF$6L*y|=Pnd4ccm~_PMx*4fGnEJafG2A;17?AhmXNA}3aAUJb{OAbPWvj8%`9M5g zPl=QKK@>J>nM7^GnlCSpb?gqD^8Wy7#bu^dU+p@-Ui4 zY!nne`L5__o)*zR-8;6aEDhvSeE}?*<9rv&qPYkQ(G(H3@Sr+L2t~21@R#F;0h4;M z+42nC^0CyGe@4qZeJ=Jq(@Zl!@w7Cto!45679`(Y78`;V7Y=0=mZ>AM4{95wG~Pwq zO;ab+8^d8Pk)zRb-K!=bu-BgrCnbV>1f-qjha=sq#s`j&-&}N;rpE+|tACR1Jo=H= z`Ri&Vde=dfyG}v`u?1dv+U&Fv8l*Z!H>!z2;9O&UJ2)$rRHu@x%_H~AQ@yx*Y$#H) zbcjJkz$FnRao+Z}s=-;P+z3O`3U}*s{N7^8v-pRzLWh7{C*F$^=F(2~^zud^1j)q3O>qbR0I)VhQ`n9&Sv5tQ;UkF4n`>I_* zajkB5R*5Q*!UGq=0E{FvYg<{vnt_NdaT&oTA#UOsn21mfu;uOW7)a^mt=+gQ^=+a0 zbTwZ1FFBc>Ljq_HQZp<)1l-WKunz|d7V zt>$>3!aHS{Nn3|Og7;Qq@l@l0jvnuKpwuH9aRwcV4i_BY#wAv|5=dT$3>KpHg&te0 zkt;(8wo}TOJ=HAOJHFDXQneIGyq8*&-%J0TYpaFWB)K66p-ZWIR(=pY8rM zAO`{@w3N6tuyV(uXTiHgMavA66lR0@(b0oOZmm6fuji=#}pi!sP{@o{Iq2CsQC6a^Zx8IhF`t%B9AU% zFeic@J;=iz^rYqAOA@fagn?gW^XiOWOOxRO(v0OrhxOis3$mj_jnE{iZ<#QOK2%Ra zO%`WWVt|vh0xHw!!J|+qx@dM*Wztb;vM-;XP^7U7vI&D5rgxbRxFHViXcJRHZD`QN z&n^$_H5s#-J0Fp_J2SzB-4#y*iJC_w;znB|2g*a?M@7g{9EphhT>TfZe2ODltHV}| z&!3=Hs3k~gl6D}9WS z>(~p@V39FvvOG%2+C`QUE1pb?>J2N+ncexlkI+JY-ESh1PEM%j(BiK!;mlO#*}*tt zirP6H+OLD}s%PbL&cs-CjZ8&I)`WF$VkHqBVt=fREUk#sd0f*k@YTG0btGQpFF|-8coIwDBNCgSQSYt z9W|~F)rgrssl1D%=Mgx4QXv?I*(Qsr+sDUm1$ zls_R5oj`dV^e#6>Eb517ns|2`_#TIg z`t%Lpt=hhp#?GE8p_ey3Ej7R4fc^WEK2s0|Z<{>&gVYH_LUfJQu74d}<7E91sWzGo zc;35~sS=ijsObGXOd>ByKSHlP$X`p~4dZ@kJk;UBgBbKWpl+aF%+hsq`ZU2e?qC8_ z3GMY~X+kRiDpf=8N+q;K*oniSAo-Cg{UP?^TV#-datXFn-6*)6pdk`(No>l7vm=zL zCk`BsMcoyrHj<0rpnB(gZLywRv3Q-nuQ%^q6{H)N_b=&tJb@19n_Ah)5Hr7==< zLe+K~YwqMmAc~`BmRM6|hyL~@VRtI?MA|?!<_!3xxW$ipsPZ$BAKiX@w@u<!<_5|sZ=(x1fvAucDyV>snzCBbfkGlDe+y(;M~UDMJly&{FnS0#cJ;&7?8r^ zhz7h0jn_$sG#9GVO=^2nA(>i$oq!DVudw2_vEQ+%tHznQEkTK&?$Z~^BR+~jNQleC zC^kOETG6=~(0|80UXyk$vpF4@QW!R!)e?rSZ_UC|NOYgxP@YfpXwNN9fx)u~aR=$PL%f|~M9FpX&8ri}nC$BhMmb4r_F z6Zm$KnGb`ta;1d&)yMACIM$Slj;2N(Y)H0Dsr{h3n_z$DVW>i4rqvWZ3MCrKW=VXu zAe^I%bg+!uuIBxk6^stl+fva&?+ewK2FU9khZt?2LLg0WmV>JKAlzG*3P1*-|E=mu zJHg?DE_TdT*)jD>X{qSe-={;mLVH|MaL+{xEfv|nmTLboTpnkH%bUXG4dL=e@^Inl z#Mgt>>_D!1kvU!JpL7Q0sf2p}JC`J;5iSZF zeFHvI;x9B68ndTY+)Ov(J24UEN~cpX;t?? zaHna~z_|c-AckU9_HTX}E3Odks&Y`IO62D}wiQMqqNh;hKZb?y?%`2d{86}kkGkvM zSj5=mw|TsKoDuEgR^G0L-k@P!tM;Z72FcsbN9l=rzQq?3BP?F+$Jc)vt7toiJ>ovd z_B_By;UQoT&VZ_QLN_vlPGkl&0Z8EK2_ydE6tsKBfeQPCJWeJ`D%Y`K%TS!Du!(IQf5S~#qL`JpC5C+6 zPkfv@$hIxqnmtpgoa zKhbBV$)|96oyi-$b}hV7#e+g*ej`NY37*4pmvemWAu_*$$QYrGAO@(&;HE`Ff+a=^ z^jV^+ZMqhaPJz(eL0CcKY^>NJV$V%VZWKBv>8=9*ZIrh|yEMsajgzb&?lwu5Boi@7 z)_yfkYU)zESR0V6PIa#}L9%3Zm?Wz;PO^%@wj`3(8Yfv(_2Y~R3u^@jd_Ehjy3YSH zR;Cv?rmgbG3QCHWUakHSRwd61CuKh1olU)RCwLkkxDrw$xpB-8c6ymSVrFEk?Ar2TnLfA6iBEVKmefB zr16Bl@of`CFKJhv3n1^pf!-n6UWoG5UPkCsIclXV_wQKRPzFgnml}eBM#spOr;4@h zUNZRx6^d13fk<)MgsmUQ_FTHrGLDALbdGNb5Q+ZI@)dZ(|Ecf%Nv~fPwYq5v6vEc6 zDMYiH+H)tlpSS)-l0}pC*`-rH!@Fwp#~HTzba_QLClcJ%J>R}63)dJd{VOe2g!oKz zeyHBznQvbi#aVIz8IIYT=G{7fcgL#$JG9)6*sjtRyFy+1Y8o;q;S6wm@VxH-M(C$x ze;n+$hR&BvJvY#_&A5S_(=^@d4}o8Q-?YL1ALvT#p^Q@Xz`|6n8|i6iRlLEg)y|#L zpk~^KRXR%5)A}A4r+DqKErJ`Dqa)r@aTx(9N(ssnq$>G{;`s^|1}puOGDGw(AEQpBu#F z^ETsi6h#c#=zK{VkYH$*XRm9s6{@v~7POm{etsQ*8{%C51Dd3WNHmWL>E1(|a4QH6 ziwo7i|0B%;4^&pFrr;mP&KRn7Y2oMOM1A9>$9!AEwDeM>kvKMiW;J%dc#m%nm()aICVL*+^y9W@KF`>1o7JbU+bl=Q_Z*R+ z7Tcp2Cmy%tc-FwPL*)&JybXuSx6^PuX*Sw5Zw7nUr|!9S=ek)!evq8DAZ^@u ztjsbaRPXXEu{*UqDEfCkqckP&8EfDk-A&9$DU~1E>+&qH-`&LoNs;nu00uc2rk+2A z@uAp%s9dSp2Zq!mSo4Q!zg!e{d-gilBi|+s*XjeOW?N$8tNy@`QPQ@d$ZooDmb5J* zb9={H3LWxpKQzxCT}k9YSt;HcR%`SpN4(pQ@N`jb?IO3g4I|E(i+CF?HBLqX+eI`J zoke}r5zP-NyMMCyT@MQ>tN&bazP_BPq&pJ~?Ad$OPr`3Avz#epaG2wiv=ImW5w01Q zYQr*LR)_2RN1-xN=Z+DUA*(hYYa{ve~rPH9pt&Rr#f&O5D5g zi&$ui#Xm)EUY46>L_)tr?w;a~U$(?wb7hPmQmQfZ#G$eK@)w2eOwY>Kh}61U9les> z95UH4XVB*{(%M%;8mwS^hC}yTU~b=RwN*iB~B2<=?oHz zz<0Fe^H_!d;CJA9)gxRdNG4&vz4l61#duzEN(lbq(G|NQ z;_Frqvp?bmR;qr1ueagL3J(%q_7eSdC^qOGM`Stv9vL^n+f31nb z+3~u(K-z1|xVo=y{A*K3FB#)}vF^gxfRHs~{fzrYtlbxQbAho7m=nz4#!05B3b3MP zN10KWX??@_(o6^8RZcqmLl%WcIA2=k0A(O1q3*MmmO?)wmN}OD25%rbMC;tI%N)9pYv|^NJh4u4WyQdH+cgmuIr+U@q%IM@Fj#H{yb!UtFo zYJ_~v$aUu~3VT;ayqj@#YgPO2V|2E;>^xLkBK(4{x^gJ@L~iNkEB8F20&263qvZC9 z1XpV_DD|Lx=8AZ?!iNkaP=FD{HEpZm-2g*kOk%$u9}83$8M8AbLofDFu41+#Ik(43 zGi6*#h_IwmK-b1;a?O`A#CU4(auo`;lFN=7%1$J!6XByrKLaaDghgg+^ zi8--b1MTth+Xmp1@WO?Cx-4tekYd?pPN5nv^18+9)BfAt2 z1cp`bb5WBP7*pHiR0@q=8m_=M7NOQKN)>whCsJ1$TUx)qnHx zT?CI=I=4mdjXm2@w(sB9ITQN^7;&3hs$e>-F$ITB)B;o z%#NOmB>A4vi$cLB3wC|;T!CRQHI#i;m|dyL6&Q&yZG`MvvHwd4Y_8JXZYIG5>9VN)8-)G39t@Nq0TXaXz&!(z*|=i{f?NF9CucI0lNtc z?P2wKgdcckctFP9+5j=W7t;{@on~;^v@|%w)Lm@swp~y5k-9e;Pj)m zy(wmD@5cz_&0iL*NZgUMvUjf7E-Mh5{*NoqIIV!_NgV1QGe7OmFd^ zU%zEcq|}xogT$0c+jz$`y1YXWrQ;f|geQ~Kq5)1|Wpr+ptyEorCzb)IF{l>>%Rc|a zI1g6l@Pj^%*fr|q(of9<>gU5LuzQE>i?-4Bnoc_ut=G^J9g1mhQ<+^!%+jL2YEm9~;gq1l{)*M?_-fox z(S(?W;1~*otGao)2qVNr;UQwTM7Ue*rV6lO%8*RQ{`26Y3RTu1&drg<$dX5G6()Oj zSGd5TET6(o=VvCBJ7(!$&Zb&Eq1+47P-!G0KkDU^_$*E`D>L+?aDhJX{*j_)$bw7N zJdE6sH;fi+CM4e+5@0KPGKP?L z@h|tb)O*GHiX;opwO4Q<2zN2RkR5Ee@UR_^sncS+YUY^`3%wzpDfGBm{pKl=jIcv3 z5c}HjxgBCSBb^y-+~gp-6#*?f3q-0F?9vBNNLtl@QUs6-6siolh6#AQaMXOuYx1W) zZ7zRpELv7j5+~{zKF8wxQ-M7?-T5MauXn!2-zmc z+~_$+3hYPDjebNo-dyA^vqMaYXMR0$eJL(e8|;#)Ey+Y*?&!Ee=zKY*o2$-zS*W$R zvJx`VWz2qWd4^vxJ0LB!;tmdf2%^fgqe-s%n>6g))`d zID}5ey!K816&Q>V)MV9p62j6}YTd84P#N?zwA-PHX@Py^2Yhggy7CyPO8ms|QU{?D z<7AasWbrjxF=P0%ADpa-N zS+N`5DyM)w1>@vm@Wv`dtOd4d;Ys1eHe)yMJPj*9h+Y%CitqO`Oz`KDJKk~-C{>U2 zb@g9SMv5(DN%u4=2<>v@;0|(%_k7q&hdR!NFflq9f^ighIP}*c)?IboR)kx@G`QjD z@K;2f?%B0!u(3-#K)O9G!E{gE%9W;us#}9126en+jvc21j=@U>9ve?0z?D%I*!8dq z?2L=EuKMt>Ik0Tr=z)Rfr)XJ^ZCZG;E9`gm4DCY+5cjB%UZ7WC<0w3@<3(1A`fMC1 zP?=RTLkQ{8ZE4Uwm@xua6k-6R2Hh(xfCJ<(Sfd2vXb5#X{8uh=5Ak1GD2cBmytJll z@ZX(P$Cr;lmc=$a$k^M_!K^r6n&pTDsm-`G(^{^aFV)3K!AcILE1eul3+x-L(Vs4& z--{q;ck#wM&tlPE)_XhcnliY;lguHAKnrK2s@Ss0!dKL~XJq&9IVv(bo=A580CLE z9*b7;^`2@?E0b}*v>V>BnYYE{u~oC5J1z`eT$UvUW@2=4${i9-^Q!AhBZhoX zR;a$j@LTk5l8Uanjb}ZoU6J#7PniWZfz#ivY}5ozlWenE3HjVpv$r(zfLSvFl;7yO zwfTas-ru+S2D32DBsK8=k@c=F5f!L!&po|8pHA&&x7YTqcYtmmly1v}$MbL_+9TE0 zF;)4Bo~ozGc#sUC#cTG;FwD_o=nkZs#Rgjpy?cddKputd-Y-}ogw4ksM_d0VbmJO; z-9|&1a2~H#YXhM8P|bQhCPbegpUZ;CIzghsh@o*Qa1R)^PEeR9@}qvBp9uQ#L}OtQ zPt5p%2^+QTk7J`ID5REtB-~P}-Rd)(AJlg!q9waUB#0F~JJ~tiTQpKkP188!Wh4#i z!?8(d@kk%|LgtYgoXYp;522?k8{=YD6D_`?ZX>zw{zgRqS9M>WT=&-hxBY%=OcG4C z{qO2dEMd6U9F7|=X^4-DtQU}%0`H~N?auUnV}|+2qYJG3AM;oytC*A#k_sJ}bKiM$ zC(qmE)MGA+Jzv?ugXW}Zbm&7Mru8nfBj1ow_by`1A*G;re;Tn*(+Dkd|EdnJqI$E# za&+xWkN!&g+>ggv;~+lK#5waBZDH*)v6?;Foo_Y&4MI>NY5 zs3F3(`S7x2A=Q)nK~8%v;J ze#BmUO!zxC_pf9;&P`#8M%KkiSDB0_hxRdg)mx4jFDLgv+tV4OX^~lj!^7qqyYv=Tqk2?n zr`>{Aj82-@uD(4RU@uGBg2f|{NTzXulG{sAF4C3iWt$nv_rt2jjUh8rNz7Y%UPYph z&8$$EP^X`1I8^U#p(mEI*z>(}vGcfyk&NLeL}Dl2GoCF>Mi*^_M2tm4%B%a9o7)ew$-VJA|3qq^@mCt4~8kFA||0f+o!V(NqNn($CW)*GNK722@;khqS9v6^Zl zOZ+*rmPLX)pA^sfVRboJhAe{6v{hMTxZZP!L%ZX^pOmiB1V%jY> zMiK;0qfb9%@a@SFL7`-FmZUE266`pMZ*Xqz2O)4hBgl zvJJBIR8MD1@4+|8-^nP`$LXTxyv2i#xW|u7MT+{yzAul+?Ptr~GNwl4H?9 zH;O7CK$y8uu#Leyp}qUJMGE}kz#}4DYKjCN(HRY!<9)+%ibga0G%Blwxiqb6+ud_k z-fQC##s^)}6rs*GGT@DpfGV``LCz@6p@mz}zO+$|C0;RpDUwvDQKlNZA$xxiAp6xv zR}FE`>j6jo`YrKkz||acN%J05wnRC;d0t1x5~{U^bt!QJ8-TJpHpqfbdwzGmlzIN@w zEBdrT9E|Tu;Wb5gci8=yN%utQVJ>%}dDn~t)h6NF9+@F)J<)tf3eEVgK*thN$Tasv zkH%1RKt)wyJ+9De-)1pc{6lJlL5}9g;&19-Zbay{sWRO)!dM5= zYO)zgBx{JI8+UH{xs>PB?{np8fqIvkdM2RVFB*W2Km8{jB=QftRIyR z`?F&vrfJ`RzUQH&liXxi(l&A|d3L_;Nv`)8msIT$XHvBj{_m=t-pf|5)784zbB!s2 zQILlTdO^e`45#Tc*}K?RwFpu4AcwHNi##uzzk7$E@2bgVoVzcfZUed`7PVvgnRqi9 z<|hRn{msfoqTYf_%J;ZFGwV~L*0M{n&xq31;f=I8MScg9ak?78Kz9AIfhGF-uCbTnn^2eeW-C=4xtZ1l+zBV==j zJ`Z4#PDB88_b%ez1?&~VZ>Y2W5!d%DGz5Gi}!BUX9jbhLK=t3+i~&z z@pYHta2AzI{56f|7AJR0W(0pQEjXA#HJ<0C(v^GkjKt*uW?#Zf{;6H-2M{;hPu)^T z@2>qep?}Tm6vc=7`?}+&tA0{)^>_B|{Z~~l9GZxc!JM#Wd*b4f>&!tT18Bl*91sb% zPCi}jRFFpv@x%T8IC#XWblH>rtV%h$|5G-PlMf^$T!A+d60SY8P@g_w8xy*s>A3h5 z42t|oxH9$EGqD@Syld;*M`JsFalI+%DpoHvXw&^snED@77P!wY-UYtn4+NZWEPU z2q}-u&QQA#BHoa9q2)G@Bv{OPIR&9j(Ko%$&qF*eD7#QALeJ4fk` zj9HBW1QJK|0)B~5`~AFwH+z%K0L!l;UiwkcgM@`kn$uHVKs3oV~j{FlU44A z2-08<*vc52=~XfxgdrH`ks;_gP;jFta(j;j(%jx|zlXz84`Uj*)EyG%jlhM5b|$gr zFT*p}ckE&70m6Zi9?aMMMmJfGuaSDl69!X5DlM@S%M6=dZvuN$s3lwY$zq%^)HMVO zHeS-WcR+3Uk(>bi#i7?^n;5j}CS|Nd@~)35;#JVoX(pyJeICl7bJUMcTf%5y?-?}Q z(2@b!;;H>a%Yw1BM7n@mAC!-_#|$N3V~1ewu2~DM5CjqWA>_JU@H^>PPuE7Ggw!GK z)h`bTXKRmM8hWi!rrQ*E9aP`^2>;U$jP;sE3Hw~t2L48767CcwYLDtM)S2BoLBg$; zmPx7%Z<~5rAhKV*4=$UFi%E#=5E3iL0JPMb+Gs9u1XXw8WE7iJAtO+8KGcWphKNL# zZx7Y^Lz-I|goH#Nai0`rwXub&R;@7fZUtD*s?b267y47pXc@-@HF|{xIs~I1(2*pI zN#LlB_z$X&f0`&ax6kBoNFEdVao6COuRD4s%x`+{S23(ggNn#Y#9d09Yk>9mWSrFN zF7CH~c%2|moUfnI3o~&+m30R9AY}ipaziW%GBWXF!+IXxvm^6U??tCi$ec|Rp&t(K;XWVd$n~rZb8^0 z!B5fMyguDsz4oK9na zd_yv4HVeK6+nzLo#W2OnIZCXcS~(*rVj+0jLOb+|5wXpkFs0#88$Ai@J_%!6lZ*<& z*zQ=%dl)%=T*no!1^Em|qU70RSyb(%6vi2t*n^y6%^@L{Lyx!d*V6HO{#4{;vp?M5 z%zDHXM69WW*~kCV5Ei1y6kD-pe*7Dpd%F=a09-ke8r6Lzx7f$muWm#CBQR9|v6C{_ zg+eGF z4(=p*=MdY`PNE?Jg{u z=FP)KqeiBSBZzjQ-~SNs+$5jp9=;JPgek@5w`wk*>Jwe4wpYC2KSQD_9YiUv7RZOX z-TaxJmX!_Yq(U_sF;``T{v&4K(eR6yr3rI0k?1M4AYHo{cB!oWNL0j_|MQ_shDY)T6;|Y(G1n3u z9{PObl8n-dZpci;i$z=e0m|)hL@%lw6UqOW{VtgG@QIV5+DVa{zE=b#?y9gnB`(uD zbvYNLAkak?YokV!sDp9D!w2~tL1PT!)F-rz<5WJ9xY_j2SS^5K_^e9j#@TS4>dy5h zm&Du!9i*gzc~swg22kDe-O#FImcW&Na?xg~y6PecNFY(-j{ogwtSo}1%(bxNp&w?! zBi0vW%3ea4ERhmpEQlH=`ep*1^JqdG#JaFNvs8+EjbM1tb4WET^4e>H}VdE=)2+^slJ~M{E1aFfOCiXpHIQX_;Iv?TEQ!tZ= zjs-X86inyig2J4FnbBH}q;dw(yRdha?84cW%84~T!Gs^LjiWR|$J~9D)% zVlJ(b`zcxztZvW~Dv8fp!a=+dn)8zlk_2arlLNm7hJgBLUB>(LJls5oXCMN5|`6c%DRJ`go5qD*@TD0KNCQFXFk31KO2X zioXX$v}sX~0OWCAn*xx#E~enTxX&-91;UlYkLb(SaO4)wNKKX6QcOpN6c(!KRIARR zkesQs(ot29qPIgrziWZ*f%lx!hl|tB-&YvJLytG|9+|oEtahJGEK}iD24E0H!J!$c zt3&t8FA|>cW7CmCgddy9Uv=iRPh;+KJ2t=#%5gs-Fl0Fu7i&LwVYhn46`{^ay(bJ! znu#1?rl>OVve^+`f|RTI{JM`@z}g`-7rf62f5LSinRn;Q-I(h-&ASWb&T(B-?$T;5 z;ZC0qluq2*!pTJlpST+-2iD)lYQ-f)QhnKd6d`VCtK7o~v>L+;jb~+}?x9y2?O>=& z+Q2EOXd4AF;>&TmeXY*>-;}!o3^;9`Cg=ToxFdvk&aQ`z6FIv$sJzilD&r@OIvvCC zNv`Eo@+85>HUJBOZ;B#9U_KnD2jf}YNb*#av`A3q7Ex0X`s9>x6AnksYu>k5a5~=5 zES6Bt3##J-s|j_tHGa23=;_sK7Y5 ztH_RR93-SmTa)2Jm*6Ls8b-BvR|X}v?irdH`~Hd(q9!j#ga3Rp?^azM2{rO7CPBAj z@eTow`O`zoD=hI3t}s8CIKwRG(O<1>(oN^d3LKzmy(IKrt{1LY3)D(m<0FsZB}ZHM z9{f`#2)&+rgAf7#$Qd48X60Yw<^k~k6njI8S#*R{sVYctSuu$oFP!5Gyh9Wu^2t<# z1Lq8}$0q1gydOPw1~(^7uXiHsL^fpA5z4lpc9BF&1Pwy58*Cvv)T&XU*SUozFp|nD z;Gt&~F&2^#XZ1aTI1?-t>H+Od@rSoR#U&{0ZGbHu>a4nlQH98+Ug?UB+Co&QMPy`j zIzz%ZL>9!V4lmCX&jV-GQD7JfPT=a0Ky$u*mghbH7U7lrnZL>au|VTqN!5VaK_BZTi?P1%z{8| zkdPZ4zt#O5B!MMHo86nJJ1Sky;41g9=RN1zk5EeYc6EGGS0DLvZ&w{(-PI2KZ2os$ z&6lp0)73(N@dt6!$uxF%%ol$I_#%+vrZ%YPPsH>2oAd@}8Ahk#nD}83DZCI%G zb8rZuBRLEjJw8|P3{Od>^L`28iD7>wkS;AOQkNo8mhCDq5|=KlAX?Pe_!I0FprI*K zDl|0EEIz>(!0I<5f04d;8v{c;-mH5^MAJOpjFp7QY~slB8-uXAxOLI7j>P6UQRz21OW^!+W9a>1p}Nn*zU}fXaIVLj zxoV1u0}}+PHQKrax?Wc_%j0zg$C%G9(r*QoN9ebi)aTi?(oTehP2UyB`*z|w$5ACz zOUK&8yc@o64@(C6s?yKXl<8a}9TOG#KCxM_h#+Q?EmB1h0FnQvt@4X`9A(KVX+~s| zttWRMhr*=Lvxt)1bL^|;h-S(-DpZ7a#Ec*Xwm!mdQTI0hm{cXU46>i0dLmg5>tlrB zZO%j7B#kj*t><2_xhjGM_Nh76Fptj=;jaiNL7Jg$Le-`IoFL#W?(ovtd z6TYS6W%Dj%k9GVPmvWvdn}EB=*~Z|~TMYao;^Su43nq{&7BVI*5NL~_CDXG;sCLj* zxTa3XwyN&Z1QN%ZxXuJJiCFItP5?ffJ)&!2`Sd2h4lvxLmg>*07eb^}ZpZ0b-{w5e$5%($8cr(uFLz?;Fr$%ZL6 zmFZemsOKmqL*{{vZ(j~jnm1*NscGd^5Gvz>aNNXZZ~>MXCfV|$`p}`Sp7y=R`ySi`$Ng?V*u)Ao^zIJT$7fRWhStmPn> z2wkv4fxlW`b*6^*!AWFgAM4W zY&#}(%AGD3p0>cDD6*bm3mg)Jk$HsCZ4CDepkOl|jgKL3ZtR5kMw3TG8xrdZz~cR# zno|CAUz~0Ni&GNoM&cr;S3WhsA2?OIT?&(#CwGp;sQ)l*`UE%#m>zg{kE=Gpt$2w& zV7_x8nAAcpd0wQYGp&Sk-oQE0sCFhcs!V!p*J&tu(&*8*HR>%R1B(gd0SpdU$S0Cm zn``m0v9=F?K0tVpquv#r;5FOQFtCWA*3&&`cp9BdFIsxJ@W1svRuZ2&>A`&QiR~xP z(Vi_tn(&#@gIc>ns!zY%46{Y;$cR26P{t9ZyO*VgCO zJ)u1FIR&aG+0e7;F9;SU2c;vF=1d7^%_j2ptSW2g*?#jkYKyVH6WS`>dt^zV3MiJ# zHT~cY9Y0gE=z5P{AxEz*t^-NlUgY_;TaS<8_uFFs*{Bf@wy9Wt~M9=q9DB zx$K^jevRKO)&oz)Ea7_bBkE2fA(A{VU}M@I3iesfC*MI^Dl3zHn@Z2(&$Lqz0vxsi zH)J33t>4;CV{QF%JR=*RdGR>M4#y^e-G2<%^K8%pZ=+y$a&p-I#y)GyD~J$ji|dQF z7|O=Q_NS8s;Nm=BK+oJ4iYo#fZm|h47+!I#Xvr~h0^2^Nlb?b5SH@S{Py$E~=i+#< z-T*jYEFc*b0NAz&dn8J;@h1h}q4n5-MN67_445+iVr9PKr7sl#?Z3EIXsZ0>i8F#b zh;jSY0TB{?8V>rL-thE$ME@?yu^y0K!Kk>5$8!o@snXaSdWT2TNb1f~Z+53Q z`-nH2SdR1AescY~JKmaaSZrs!^;F8}HgMCqSRhJrSdY5Xg%;e&3PSD6LAmaZJrh1tz&rNuN1K8R?$4_@j~1W zjSN2~E?7fJb)D9ycK`ye2ssXlWy)#G;8NE8lQ}(i!!~Fr)Bui7#&&3WP*UC^HFWzF z&UEGz>P#D5iwgqCUkNBFzD-wA~$9$fSTNZH2pn*jzPGbuunuQ382Qu$3q9o%RA7Jd9 z&&B-0!;RvcwhrQB!cE9HJKZ1G2NF0v|HnTlfWrDzV%rogS*KDDi9spG+9SNh-_0pn z@hA^P>v6kSv{dT8IFQP%s46I0x}}CbCNYnUtUnF zK2;S&&rSEiok-JZ6u4;l-$1vq*M9^s4-Xm_7z|`Oi%%hMrH1J5sSml>U>>SEog;VV?T85xc*&33fxE=U?wnHbe!~EKza%@#QDjh_5BWg;$+-R8=N_Vf zXueKn;*+*nhzI4*pVvD}(l=+}`a5JMnW`85N8k=;5N4Rq!=HBFsqc|&8VzwBn{H91 z6p|9n*YK>(b1rQnZx#{ba<->6Vo!w3&o6(O-E(!Rw@lX__An|@v0im7+ySYPrrr8d z8>pz%!aNiJ?_j=qIu5GDSs{RIr9Wvj;MwloAfL3%`{euo!(;sUmjo42{J5lLua;~G zBbJBVeTW{UmaLOrwB!MP(^z)V(q>-54TZR@dt0&RcRD%tf$Z6+?cr@SF8aEuoLILL zS2a-n831t6$H@*BU$o?NR1v?ol$t-o6O*okFAVYkPy-6Q2!E>nl+uccrA15C19{l_ zERzVwZleHIc%!I;=w)>eGe@rT7p#?e>g*PBfiaQ3vNXS7n?k?0*-rPhzapu1+K%qK zF}BmO@J6FEzue0WtwF2M9~ZwDB6C7e`Tgn2)8~!`fIo?qt7urUx~5wb<*nIGU>JQV z_4j3-J`vEe-I`)9offM>)Wue+HanquJ`$tSgAC=|H+RVIoTQ=ks*1C+7{nP zHT*wx@OP>&uAxif(8gQaVhKg;qcmhBrfLnuRPbMn?OEAgQ@8KoS>QC?Ol!zZ*z!)Q zrf$r4qz!^AcHU6i*bcLPKLbBMzESrMOyYRU1bmmWeDCv{sA|)G)g3z3MYh2Uu}D!UVcalaQ=Me#51=aOp= zEgF|tXX`q9KP+V=>aDKuPk7u2c(or{=-8{1DrUDY{JlTh9B?b(NLyU{T1%B)Bgq7} zyDDJw^#S7{hZ#34iEC2Wm99xQ@MhpN^0o0T#jANejaRO}*#+UpwVp*wZsb?8uD$$S zbZug#K#<=o5HvLcm~=P4834>fOi{^4pdwca!d0ZVR?gjj`%!Fc?76~fT=+bc3^j9t zC0JeZJpGsN|GGm}0K+4j)4=egc#FtLOsP(F{rG5+| zBUkm1`M_$cY#BotqSv%lZqnv~J6fl5GVmFGNicx}k5+C+Wu~o3GAd<~jHR%r7pz_U znQ=PT@n=MZqi3zXqa$0azghTG8cAo-GI*Ms&;1clVl$u!<1ck;3`I+#+6hRVoAar$ zx<;Ert@|sV7xWujpX;u?8RE=d%ioAhs&?U?cgEn#^tR$gEkTbi+=F^Wmuuw_>L5@4 zd<-;T>=_Kl_Dd|y#N+y?YkBz_!OreBjv*{}!nF}J>Kj5My5sZebRnxmnp?O_;ar;4 zJ8xE<-<*cCFiEIt_98lCNkNCb=I4}er7|VwmcNl`R-@%dCxzE{^RVdSYQK>7(fLb_ zaoU13raTpvVd0;GH!}!ocjMJ3Yg*m%SN2v8({o_8d$WP&|5vLqM@~{rUWnO{QRq`f zd#fb2ga{c6a!R;NyomSAXifgVz(S;W;J*$CoC~&5lbSy-HN52=b4vPIVJ9`mgXjML z0`2HgNga1XfOfb){^4yi7cmI3U}T!pU6SE+?~uwg%0PwQ#5(f_n&0wW>H3fP0)Xx? z2+C$%=Zh94ngo7@4?aMN_-3IZA%sKm#r%yp8iot3!;NFute%WHYriF;st&1m^*ZWn< z(jhH#Ae+XTNMTxGYJNWM{4{I}Ua}`ugJvby&l_i%2^6$psRZ~aUBLh)E3V#@`FT2s z?xzrZ7SLZ|(B$RlDA2^s!k}{S79Mef79I=qN{lhA-snmXG+Zer<(zyeo)zh*ppGH^<{zuSvvfuk};_lc^>s>`wdO?S8(1-hRd`iiAPq zPk#WnVn%1DWx-kmGL!`XjEXNR4Moqg$x82NwDXyQv%bchVLkOA|5@Slo|r9M#rvgnv})7w>b~(uw2;tpO;`jy-1HO9?xOFI)__s^Z1Z@J zI{55o{c=}`QJOz(^Z-frGIzwzRL$rhh8}zPUXv#L_@A0Vsn*JSEJ|5e4|kxV%WNy4 zk^hoSV8Rr|2Bp?&5+S+a9qgrEe>c>0dgW0gO1+>cdloVxoebw*U7Y&>>d!&My|Hh; zopSSUglu%VuL0WX>src%nXMxUi26qKjQBlF=y0U0p;%FUzI*MfXb`|*nIH(T(Ru@{ ze~Nx&-@IPsY90L3$P^s>BA%c_s+POoyb;Wqd+*i5DVq*bBkuV_3iA7uO8rAav8of5 z%LyYw-4TDR=D~k)pAEBjl&RQLs`O4u+eG!)ct5C&RjZZgZu^VAKHFCL>}b^`XTb-` z0guq}dre0XO+~0aC#(*dE&znZnSe>D;rmEQ4#T(E-biiznAGqNtwiO%aHU%`pbUZU z5VR8Tsozk9)R#@51vBdi@a}Nsp+$qr;K$Y`ha#p8qk>MZ1KGK1ar+#)*MuJXsW?&> z0{*(+^{Hs3Cj z^yn0~M$ZMjyWgK`K2YFFw?rnj^!whqYIKOD%#woo@O=eXT@S0~p-Q z2jvG%8%G+QE(HykSaFC~H_E<%YzIEjetD`Kn2CNTBRidpfCG!#yTgs85y=lTdWr`q zE8U>VLc***j{>O~X?jgk6ao(_^c%G~*S2zxIoton;M^i8cavLW;>aGIj0uv^;gE}`oB6c+QgM`~Snx87^hvpJ29 z*qhCG2j3DaY{s8C{|I3zMS*ymMSFRh)lnq!ac?RQg5nnT+_Nrujk-v^#&PyL%YLnF zqm^y^oTZ3j@EYgYuewY?FMit^#UvTXNWDhQUt41xzsxc3xANrKV7*4Q?=|ZB(xPG? zDYO_Wr$$zYFFbq{RF3n&h@V;$;AK+(Qap@Ljbv2K8dW4cxFHt+Hk#B;qzuja>o-{! zoAv8ASx1}o>o-|({q6_nI{zzsZK!tlxy09M(gppp4VysmX^-)q&-$|Gu#7 zi!mPo@4@Yyyv{8`WSd#v624&6kDns@bP*MRE$eJnY*sxBTYZ?l%_C^OrO<3A11PHa8uKSk1dg`hlc~Ye1jfd zvtWpCde2xO+w(pxcC&s13J5!sPJzCC*9j@X$@ez@9e55X+=d_5tQD;&qg+Mv5q^sj zFHtU%SQ)@Px>zx$XsOioja8zdx?!ZIeWA4ch?94aw5EvN5V2cqgmrN1CQQcEN znFT%n$Yd_@?S&vb7D3FN0|9_4>$2J1A_u9*6e@q|RHs4} z>$OE=gWDEsx)>Zox9WqsucmGYCtNkSiuE>C%YO$yIHt-Y38D5IVJ1}}9B7_56twe-2XLN~oJJO59W-}?IXkK~s&`&l&U zrmI96z>g_lADZF^I@q8KZs${2{tj@3Khqo*WZ*GNut8IzXo%9Md7vMrLDpc`Dnw6@ zIqJnVQxhv~Cf%xEvtLHw&13BW=AZ{j0b5nj+W~Wlrm_u}1~(ks`jw;R>>bNkcRvI) zUrzwVm{Cu+P<5;!Y$o0{bk#1Z2uvO$u3VLyg`XX(J{VAp=neSpP%kE!a|#t*xYLw! z?Pk;!v{>b^rjB>z-gT-!alUyB`p%Qgc*f*8DR0h!&GaqIEaMgJubT=*uWw(c>F{Rp z>lLRx+OdMh7C3E&j;|Uq`%724=WRvkLwI+8K{1?5unB3ihVUdja1{1RfokwM!){;N5K|RGSJS=$?Bv%}2gG-lDDZ0qQMj#je-|0;3s6R59$9j-bYcTLCHXcE0jq ze9H&wD`7=Y;oUF)V)W_#yd4P=2^CR!KwhHv3EfT(@yfkB^1V9>ygSSh!M4C^Yvt4) zt$`T^Lh%dDu?!HN+pgwTuk21=Jpkgvuwwi_g*Ug*OMHBr!J5GilpX1* zH;9pLpDG?x-i3dpoT0P?2xB5H;5OAEayuxc+cd4;_~z$zsp(KnA!9|?!r!Nr961~E zB?LUcE5!_`m&a#mTd!HpDd{=?tlhCU=E_99YffTP0WPlbRZFMio3A4?e%oQH)?tJh zpdE9z1<2i;ZE0|XBF6}S5TUdoR{B(mzUthAC3OKP>EqhcAV+wBh5~}2Y51RCF%1Si zT1m|A8t7!&-K$E0TP(~t;`AF;0h@G?zgTS(Ufcc{QZ^zz>Q0UNBjfc~ie9KMo&^bU zvNVUgBJR*N@KXzjQO3T*CvN%6Uv15+&%434XhmnyV_V996_IQ@xUB#T!Sz;6yvfwCCeS#y!5*~b#8ZxdQ27|dY zE2Kv3NYF!^B)(&L*g@u_N)9)Sr-FtjKCB)mrrYqMuiF;us2# z@AFw4WP3X5L(2$95 zDa>o9i}>T21y4BRtwatJWI*C?)B+rLeht=Ba_*e?2J7Puu|e@rL3~2K!R!`c$lF?U zj_nfcceAbP-<8bGh6}0iTA{kp6Wo9LNcdav$0!w(IjBa54Kpu#yfr|}`v(~(D3tU^ z`;hNkeeAEhxZ5O&(tK%kEH3vpHZENJm)Q+r-!^O{alh@@nfrC{&(KH6>Q5hKgmXZ{db46`;#MCwNi-s)*g`e)rd{9EVV{!*8@p zu`3llA>Q?&g2ThY9CL58a$%?~`tCU_4Obe&N!ZIiq!gl+NuZDEWa(3U5g-nYIC&N8l{`)N-{?=+$JnvGNuG=C~;*!Vf*7uU{`r+hPQD7i<&v7o~eEIFhgDo6J>MB{j?Bn*ju#ZTWV^jQ}8EU zXZPrpb?vi##elmb8gCt#K$|3hNObv=$BRQJNBkuwd;(d zENdB-34iS(7zR#hj$vg?Y{|Ucex-x;gtdWZ5^pd;e;obB+xrm*qtbk`2yN|aZNz{$r4gq7fyNgK?eV~iDCRcE5%skqDas-V7(*nQMh zw&m&iyhpA-_AcR^w!;#;pc3Dfx^VY}*J&>mt!QSg{f72LTpLWN|C6n~S7qZ9>8tXx z;HnHYT;k8%?%TG``~8&_hvA+QZUKiIvFEWtPb`RH@ZncI=T&X;X13}cRCuiS&|I(s z5ZhN_tuA~hd9oBdjN~>ILU+4q0HsZv>n8@%ocM-U>0L;!Q@3UIje+H5{dSz~8tpDQ z8bnvChA>SAW2&{smh{Ul9_D5Z+h5KvfHK$L8Du|x=&`TS;K$Gu?HJQ@jgj|Ybyl=RbDOiq5FDN1Cdvu9Ek4CJ=94+JXmny-hzD2mOW^%(dHMX&`SS7!&m1l|DY5+#w|UwT zlU2Ah$@Q5G$zT2Ly}3~EZ&Owm$-B|op$UlZ-u(82%Ui<>n@O#Q&=)57c=I@#$%iamDypc|5d z6SHyyH&15*D$`_0yz2uLie?@undQXjhQgo5{`wsH zkH9t~(oiVpSBX5xCqyT>dcx||EeOlS>n?qP?J2Jh`@#lWCBYZTg9oVVEKeE&yNaIW zG~y2EBDkU9$F2&m*Nqq(R^MIU9q9X;+4dmw3tLkIM$mupxG@O=n^>uR6DVI3*rn7w z#LnJYDoR|WMg}r1`Xn(P0qHIh|EdvE%0%NjIg3h5VgzohrW8|@CZHpG2lZEDX zMuwN1(z{^|DrLdvzSY~lrW%S1>|B)H6uTl)XQb(g-%G9x@Y*S6}3c`mEd_?4^;64Fn7K z5wQD`T|V@9e7_#gnJXSj;}!!2Pfj?JZmh;%tIH++&zuF-)rm(`x>iuKs-^dKDSHIb zS=aT~GrK2bdNzm>cfXcAQ$$0vU5>{A&S@Dqx}_ygz+COtcq+3K zh&P97o_4xxZUl8iXjinPTb*1~ips;=8rV*E5w|w{!m(GqlR7UHn!q&)pbC(r*dV@N zD81*nZgabY;%YMDF2z$G7L|Ct-sukJTSec;-i+-v$bTPzmqcYm^ASMQsS#Hx$sn$n zcGc9l2U2gR%pn*?rS6_(@M%EW>3sg;tGuD3 ztts-cfP;!y5U3{Gt*70ncAPzd9=G}%bxdKn^uI*#wsY)HXQbkPBcftKUK@I%ny(b< ziZO1t{qQy<-rf&~7$gm|;;(Dgh}8-WYPsyI`UE|L5PTnF{}CD=%*zPA56G@U(dhG( zB`({NpRkWgkl3M`|hmbEK%{6z0tng=f2E5ulQ6_}4h z23KK3NbH32)MU*$!>QcYgZ}Ib(4V5^OQ9KiP@P?ua5oyU5pc+m-uaI|%0SV^m@H_d z$?XBkKqC&$#r{jmA<*CFE1=($Aj{vt8H`k}q_UHoAQf8;7RMTf9jBRH1?w`*u8+WJ zi)&=_1EcG=x&{JrDC2BgfH-VU4+Cf8zeEjPmJI?n|H9e0ir{QqmG(Fr@0i@{Y&@XI zCEWs68ags7NZkS!0I)Q2Wmxc(!!ze$kNxc}eZ z!zN(N@lbgtA#D-?@?I!oVi)D!L;q>=h|jPX;xnM?T+ni*E|ZJHc9}F3nun9C$(X^^ zAg7)r`=SC+&}DD))HY>gC^W`U23?>1mO4K^edIuGgO1~WD;98uySS#c-*=o0q&0rs z9b5)k>U%FOJeA`J-i1F6emUTcD|AzCjHzMdk;fUisc22lkGOl9HSR;Q z1KN3y*#Wt^V>1fDW)6PXP5cr-{YUcwGoiL7F;v-~QauRtR2xOoi&*p4UdK0vb!x=K z>h6VA>FqbrTcb~zA{qbexwbcY1yl+qVCYN4t->Zrw7AhrH_=|tk_(|fj)W=`>L$&@ z#6-?i1mazJiwdTC_Pnjlv;x$5JE`!^rJ?tU=+RW$z-w4x^Gl8(>Q?Q}RiBn1ide3$ zkPMnHVS{ahlrcJ5TYL2Hv|>CZrq6SK{SNbpl52A()f4LQbc(ar-Ag|Yq&GAcG~({0 zy1qIh7cMrn5)Hk^{m&med-eD-a?Lzy3uMPT?v-$2ioo8>i+B)8XG%5Soy&E9euO`D~FY5`1D_eX;wS#&ag zrHcCxsd%Drs?f>;e`PUmbLS)qXPBI?Ak=aZ^S7;jOv^!e)SOGFWvjFoL5rxSJFBG- zF2Zvo&4t%#GK-d&D9V=@AVI)xVznN+1fF{3u5hefQrJK-J+GC^(4REVWRU~e)q%u* zd;Q?@H)bKP7kYI$`hy^Db;S%O;!m%G&+N@UAZy@{LnYmL1dXZ;AzE7}S<~LKs*Z}8 zuil$q@#}_@(Om;^i?|Bx&BCAgxE?ak=!!dizsBm8E?_YygP{H7TASH3{ju(x ze`j-`>39(txCzs=OwDM&Q_f+Zd60}p@iKjCjeq;-?A3Ay%S{{1Nc=1}$hrsQH~IkL z-PyuJYmnXdlK88%0&*|l$F(HK_C0MBXNGwhCwLIe4i5Tvb^L2xxo*VS(9bbv)VYwy z5l{P9Ut{RNfh_90`Wj-J5{#u%mi<|gSU8i+N%CU%3KV9h8u45@(qU}YE?^@OskWh~ zHW7Pp`FF;@>_YC|88%gCF;&NYdi<$k<>+&bWsD8oTnsZQ9M|@U4cI(NoTZ&E9DE!b zq~r9Vs;kV`nv_*_rX8Q%E!cTN`UNLwVk`IHkS8Z5&8ttw`f zQ773f^jR>WT+C1KWlZ)`_TVz1i+bq%o=bAm^+1@LM=E9kH{}J4%I&`0fN^kP=C`y7 zBz^F28IV+hcR6m=LERfrvlDM{A>h?(Ud*riClCkKmL+7Y=xLYh^^c(hux|mJ!?jXzO>vk*4 z=YlNP*c(}F%6}SU85;ohf81@D%rxwA~$vhK-_`w#6YXW@R zNOR|SaZQAwbeW6jo3vb~sdksCzx^(vYIIp$sXCX*f0gptJ*NWyeQ~g} zfNK7?t$k1J_Na!m>}S_(Yk7+Ov<=*`^>U8F+myju66UQ!^0AfFCaol%ij5U#*;HUR zK{t16a1&svt$BcUfGEBQ)sfhViMZCvR4(pV#4b7+<5De+`C-11&4)r4yuj2tH4>O3 z{<%4g(^LlLh`@o0TDKb)ohYWWa2NXpHU5U@)tw$!%!g9HmxtOMTr@KiebaZk^C09i zs$Ek#^}4xtx(lYE+w{9nWWYc7ZroG%_1V4ioukA@w@aKmT>2%N9QP;sMikN2a-)4S0_~P>rWxq9-tGxC!MKpoU{)-LYIo#9I4y zuyP$mkG7%))V3h-HjD*sO? z-JtsrO77Tsnwrv3{pgmz3%Y-divfh}6s~1>u`6{Ds;fQI0&#gwZ?m#ROGeoKamS{L zsfIkZ#y$8`cu%_l8twz49kG>nxrLk1?O$(@i~xC$KTJi7t_n`RcwCpFmZnMvU0xnhP7xLxauVk{ylEqcMqrB#%Fb9 zu5f&Cv9EFQzTrJ~h!^iMVHn#|o`&p*K?YNSi5X1YDfK z=-hh@Mc3!wp8X&b_UN^bT%Z4bhh3lASv79KE62G$n=Sx`>$|&>ynSIlF#KUIDOW}w zDI&SCD8FT**Yw81ar=ils9aZ2HXsyk(opX$@GTarbd+omY4(mnYkB5w(=&!|IIckl z>S*EkYCRiopaupFm=BT$$zcNTM_nMi%F!!g*l4dkGJxRn>p{R@^L>4fxIZV5W?G|j zrCvEXNRMw=fC>N%OjkUuD}|%}1^F1xKjA)@P237CUGmH}``Z3w0cosB zFNWwMT?vb!GUzL^TeL@8KBtldA*JMT;yD@rEerC!acMzI zOY0V41M@k)+ji|zoHA{@pLPHM;H>5kX-&?h1lE*=?%4wz>$*crFl@LGi^}WqJ<+t9 zcCV)kr_{}Fnl01dpYVnEf!=0)s>R?jw3z91-z>*}w84t#klOkQ;`-b|QsB|XI3I*J zZWLtDMfONd+16UW>lLK_FOcLn3Rt977_s)`McSEFh3wb7Ju@V`xP2XfyRt+YOvPnw z$SE$egkpbZ-i`<#NIBh7M)*6+c1%qt4ay{0f|Wb+3spoeB^BniMciAN6qN&WaIaWG zP_^E-*t=;@6|2Bn-jnE$jzqSo4voY>?2UJVXp$o&&|;`~#AckJ8*B-Jn5=AJOrZZ) z=N}Y-P~(qr<56oDl{<<(kfCzfSdh7Fqb~O*UNgbGM*9!x{Kwxbz4y#KLIhNfSo)hq zAB(>vlqnQFrL0*1wrnd@nhB+XEPiFFzf!>M*gi}K2+9-U!Wba9fuU!jvN)3Jb5mpG zS?AB}_Sq0!{z=(HwQcmO5oJ}y-aYwqP^0#S06i^YCJ2%LZJjx7IPUDqBOunO1YPeN zhaT(#_CB9O!hasIjAZIc1sd9b`y)m$t`Ygua~y>l&=Ew+_t|ka580q%2PJx!Vwiw` zde3;lnJ8NF3~7XwG4;V)1Cf9EZ?3rZTHkWZ))a@MqkN9ZtimU{0Y~xk^b4-k6=aFe z!-CB+dlAg8)JA;XDA3x%)LJ#-drD$!9C5$i@&Ue3yZ!r=;!*3j?BQ{bu;zQh9g#up_C1mvWZ`df{736t!mP55Z!tKR2LJoiNH+Atn>?b3^ej<)b+9 zL|T*kkP) zn%#-XLH@5_(l!HU39o8Zwi5v+L)`{6tP{(`W=Rfl&)JJ*8wk6imr$3ZC1w#k0#V-q z_Zopy0XktqPM~XfjK~0o&UhIY=J~L9w_w!A9-EPoiU?oUU0aZTJm zs{smfw97aqdE&ht$R35T%Rrg@Bqr3~=AJnlY9R>zirqm8WC75I;~sGXA@qY3fQ{Ss zv$s<(6Ys>hO4;r_Su(}7JPaj+*#L8cN*n5|ffKdZfwaBtK<$GW87_$k0OWNGvNt^l zwI~4Xjq?ATaDy9qMnD9xN5*K6TuMj9^+WPgDkYzWk>c*eb+|BD6c{ge&FnDHa!#GU zuU03H(56z~0RvQnYh~M?eaez|#W(Jwf>i86aM1nkGpjY^4z@hzB^Y!sLCQlqQ6?h! zARIK zYj~7H`V?%J9Mt?OANH0i#)TAsFd&s856;eG`;hhqO98%(=dDOh-5G3E%W(icpsbY4 zkEdTrceTu@;eW}-llSrs_zdQAU zrplZQqh*zt7d*Xg63pl?5hmHw|s1~eWp3;a4D;JnRtZ*A7--Llz0 z#>&Dp0hT7eyv=qMZ$6+=f>w$lQm1KZc~qx&CzZ;pL6q)L7Fuv=9gp6K@Z;@dihjl= zPk_svuTXXCly2l~7)xHWwyrK36F(&?*F>rVpm0}dn;}#(cxY?Z za?>>Ci)*~u&wI05yxE%qSdmz|z}L(!NYix+2 zjr6@g>xkUZX0;bI<#(&GdE^fo>$9nP8$+FMjE;p3-Akx`?*+A$$e-w2(|PR`uicyL zzvkQ2RkZWm?yuK;EiA7n^II(b%*h^pYMS7({Ra zGIMvJ%$6WMGvC#*ZOdhho|uY zO}X8v6Kt~}TK`NAg7rjxWeK%KQZHzw0fbr{v$;DL&nV`SWH}0ttdz`=>dPT79zUWX zHh1ys?;(^Dcs#;POWq2>!?vbJ z`Ay*-#9OhLr@&!@yfPKnhHiR-ln~0bwP_VIHu#a7o>U?_na?cNgL|Ga`$oV*Gz_eD zTXv$~_joIx;?L+;YDFjG?LEhzkGqAetF2jGW_9r{`qjq~{=3!VVG=Be#0ui`BBA)y zYuF6#wimP#J^myzib4L&Vt=c2ZsQ%fk@#CV*ZO0{y?OB_btcn@;A3DwWnp+SKET#% z^v8Axd`Aa8(K&2RC?}U!COca2#1Xw-k zCQ@Fr)`5b4v(}0dfq@)Z{bsdyUQTF2=rWXBLb1xk#6eyz44j}$Zn~DM^1Z7lu2r?- zK|LQWK2XK4Fi&NH;sN{mM_TA^x1v;0VhcjiV*K%iiesn7Z3pBghuJ$u5cZy9sv}(U z=F8~g?x82U4IYXs^Qj-QdWv*@+q~>~#O;K5pReqGTfEQsp*}%`3Pf-;+MXiXR3%AF44mq6xCqH^nlMMX>vf65@&-5-MqhcdyP1-RBajPD(4 zki77jT{xN67i1XcX(KX&GLXasx5M9E))uMHsRdClC0o2FeA-=~gVR1SEZiVI zG=6!X?a@=Ri-GqOg3#>@q6J4wf^sR!5o?lyyY0*NQ1teAg9|-T%%VWFM^9l`y$$EM zXUN8wtnCx&jGP71JQXCYf_?CoL_lW>(d-=s?lzUG+7B2wRUdaF(x%-z3Mp0-d{U!x z=VVS@p4Fc|bCdGp4OE*xaRerOIei*0m?ZmS1wlW#P?WE2dhK#fKk>%;pRV!9>!k3G zX3dfS7{r+TjKVuQzUCXflj!)-cQ?z|DPMl`G0EU$hUeMk>3LB``CBK zY&fCSY|z<-(F%5DnLz}LB^+1#ZfAq%PG8%331-QxQK81=WcA!H#!Q zbCP4z87CD46$Cl`hpgOIe@NMu`n(8RUqur6MEWdmu>uq*1M#D3AaacL<7JMmst!_SZiY7;6$R!jNvM*aC zz&z4t(l=z{v(&nFs=cr%}`)jox(M~p_% z**d*+6V*r41-_iyXaw3$+$m*kL<7#5S{6j{%OmWv-{#M5@mFY$d^%sbKM(u)s{s!O zv=HV|4vlBds@H&h;C8R7HF;ZN=8?8a-GQNNgN8XRJuSlsyT`vbKWKBWRA~N1n-8i@ zd1Y&8%{$q@x}a=@?twf>Wq=V(;(p}1-poy2)pnHa1J7amnV2=&>d(v9-iw<54BS~T z0IsOy)0~{ZZvXcMIy;3Sw{RKzu6|t0e+w=8M3Ja7T!n9PPp*U-tlW$9QNyFV6$h>t zo7R$vK{C4|_}m9oC*MPJ7Q$SA#=WfeOAo6uP!$88-oj^13LW z%`uD2XLDiR-*B3_R16hI|G|`D8vL&N_qIU#F=$BZ!EclOsGZ5;wEy^7D?dn82afpz zXNfoOWKjF$TqKg+12_m=A}7@*eC<)s$S`+bLwCyVBruzMZ{eKY06;3P8~Mf0OM3b> zQYdp4cZJ;^1XLPRFe`8_yO0#GS!>J*4Ny@qMr8Dr-Sk;^%5DE6sWy_I%I@U2v|?+X zKe;q@X$deQb!onSW5sNm0``krwpZEl-Mq(b+JV4gz!SCJ*NV_}wk>Ed!IMQ}Jq+Fq1MkNho6bR_t#(PoHL>G7A**bH%?}QRPo>OkkU zV(-EMKJXmJ2r|{crg(tVzCg8J4MqPgXZi?#N=e05*d|-ODJ3*nN|OU}rWYiy;bk!| zpEDDj3#J!yc_zn_7$NbKIkhGJlo1tMD7eL&GJ@n{D_EPKJeijXyx>IgNZHm4YQb~y z8+0fSGt490uX$VImvi%UMT<2z@UB5^YhBA)Rx%@WxWPS=8(>~F0bn@nwtg`iFzj}} zu=nVB88iT*E;U>*A%I|V=4uekZf+@01*=@bWsP>V#dx_{cl07=4O`9!FIJ$0ZZvm- zxHANu$*3i;e%j4u^Eim>pfi1zVAE%iJRRktWv_$;Slp6dGZI9mN8GqQ!1djNk*6>f zA_#_SjR=cSVuP{3hTZ;z@oe}3XIFMXL`*1UW>Ujj@n0Kp4V*yYwVcK0Ae6<_(u%6C z=rC&d7>!g^9>Ea*O}G@Qe8FtnYMFyaKT{@2peC(%7a-^Ye_O@$(&*e7HlTE*hZ)Se zKVv+SQrvlVg|8@$UJju^+MC{O*Wd`Ws+%Ds-{EigwrgU;>INU;)>kWvFJr1|{ef=F z31lG(Z|vM)=9F>i8w-Y8%!U4$(;l;3&Ehn6dZ?dBtERSEex_^dCmSl)&Ph5tX+%!Z z(j?QZ)oNgYh!WJ$>4A+k^h60dqNCQ(cMLJU3jA~k7i+;3r zC@5EUSvnh3*zt3*00CmPD3uRll`m=}{*ow530b-RV0ZLHu|)a^ZDE%I5<2Wj-*uP$ z#cu0ajnhggf)g9ToFy+W_?*AxyikhZ*r5_?I`^{BXjOPwXkzf^K3GX-w=8Bb$-SjM5=^Cr~{cu)rajfzrO{d(gfY+vLu%E)*>-q8fh=VTfD_J3PR4 z*!OE*WqjHDnoI;-jhXZW+*EAF@^ zdP|)I<#jr26sT8$>yCRKlVh`r-%YqEsBuEt9k&mCPdB}X1AWIe#NDNdIV={i3`=W~ z3Zd8(fA$(8$K_!KT}bOacdsF$u}`2RbImqDA!PxNvELiec$DKy9ZXWc|7%$>HvV}r8PSV6E#845r{;4mhC-$lP3qr4<;s84cvO{zPmUe{lOx}ZYxN%; z4hrB(b@*O@n3tE_=KlSj08oLh*xVab5{L^Rqb?r38AkxD%|0uLm&vIDOzN;3xs{3O za;2lizbL@wAXXt32k9AI0R@~%mb@` z+6Glo@oubGr2>}%>S6LL@B?$U7}14Qp*UVj=0>FD*fov!6m+3*9=(`{fASFf3|c1l z3;e{!_*W~~`hc6mC&oruS9aG=bG84?_8K0)XC98egA4~2heOFfa?j1VA;}&TR$A-E zkd3enhUfNIt1dx{M^ul3prde8;4aiyh->m9$|nPhUaUO4<akk_v?CtsX-ph~Q}ZQ!erMTu!+yvh0A z!xjP$g5 zElMirso#z3x9-Fp`QpO*lS;gaCH|z5-o%mqq*8BUsXu9yH*u6dX@oa%ggx4INI?hj!QR{xQ%vbEvS3E zH*q|3@UlZpGHIlU+MC|S3bT@h%y_jCS@LIeWc%9ueR`^?-9As#H7@5zS!%aB;uLAm z6d6Ime0e#_Q;`$uC)BuCp3cgjx^1-EyiuBt`8UEko=__T1w&TFS0CU{{2XXuqwe`$ z0g!pt+7gX-wB~K;o7%WVhb{YqvFE9#PSuEXP8Z0e->P(h9i`XQf4%GjMC=NWCnVd|!Q`PRW-u@t~Ken&tjMl{3%m@@o>XUy9EGl-pot^KdGB8wi_^;H| zMo$$(;+tc1_g_)s)3GZ?Cnk?co+eezZ{{a%3pN-#=bQ7rD=tb*obR6+@oz8gxvDsN zfdT;?%h=)g)5i&vxZJJ}Q~uS#^J^s%6ejM;_a}~{R&P?UohFuelS=$6$6Nm298><_ z`A5o+^U146`cuYxlg7JS{>l!UGBQGn%V8vT*iF8NS8F*@AZD5%S>3G)rByLg>~!KT z;`4){faULT-~Blo6VEC@Lx1gP9oj5XTG+}Fj1ccg-Eondzd^fc^-?N&`#LU|>iO4S zFX%k2)W6+~wY{q^QWW^KTb9Jt^Pv@EN93D|8D9@cogmuo+T@r!xU-PKl4ZTP-@(zR zlzNj!D^DLvo5f*zlV|vo=F@PkdOaUkfazgdx9ylBbj@!mc@oaR!1wdhLRTgq&l;u7 zTg6e9Wp=T@2X0GVwe)_Vfnj~;ttH; z&V>{q9k?qlfvaX1CRkY?-dr`Jju{!6dtbO_IRz_L|4# zczfCVADEri>_U0j>yE#lG8Win(XQmrTXIRDa#w@0;67=exhFeNnT>T~fp7>Xq<6D3GUy71UPfxa zk(}#p2^w~86b*CXOKY+&LcP?Hhvxr+Yx9>7y5DEpb-S+6(ccHbM zUF?zf$xi>=@v3kin<J;U9u792iFD^s? zhPrG|)?|OKDgcPDlvs%C*Z5L9QxEA?8oImd#(f`*Y|(VFouZ=}cRUQ-No>@w(4yo? zsdWMe+3n9QZ=EwCg9C9#1#Ewzz=`RlZsmPe)0JRa-9nGKdcyJZL;jRvLrv~2=9=n` zo-e`x1rGk9Bs)Fd{bKHsRCsn*v>@Kl9g6)qIRO078#V`T=-}Ug@xqoL$U5}ZBig4B zMy_Nl{NTwKS*43EqS8arDQ?&8=`HDvW!r&pYI^_|_=iXTX{GLg-?G7^KHV8{|9puW zdgFTiXqkHfWaiIOSgDCB{XT5JkJ|5Qe#L$;`<5W^l-DG+8qc(NmQ5aog3e|k zr`~4M#o4@A&yQ*I1S3k1W%DxCxA|2|7c%B;7WUQ3vYtMYT_4cTlcF)k6Iu1pgn3SozEi`otVp?UK#~mBrKHQ&~}K>L(ZAq z2d&9DMeA{b7M&}t@iW#Uv_`-4P_2a_S(LP+fHlG)cR>RL=lSlG5!5=Nkg}Hg+y$im zM;#7uuurP3;e74~UXb7KbgTG=XZoKWw!P>gU(Ikq1Ef$E(wfx3D=9kSnSg0u{5j>? zu|Scr%MonKOvN0O?l!VafDImTmy?B4Sh1~WiF_gKVZT?g*k{7yVz9gUt5-mJO- zhP&Oby5E);x6lYQh7e7D5)w#5CsLC_tYL=(PIJU?nxOKxFha1(W6x02?231y*M~Q^ zQZ_aN4tw2Uo(zE${Z92);keD-0}19+lm-yx`3p)(tv_O)TFF|pzI{fWm;!T8Fcsb@OWM*JCTO8ljBcQ$TOU-I_2Td2U_ok`S= zBk@`ikG+{#sZN}6^xSvycDu_-O5^_-gzv5Y2H{hXI`=d;USAu{0q%NCuiP@S7{Z4S zEwKk`xlqIzv7?<=wB&APEj(Ze;jN;TVG9ZryUd0D7@#5h1f)^+4a_hKj22$Ioe~*r z8nZEI0MzKF*SdT`y+p0g#edR^G8*?y-xw@_M~cS3Gim72~8?Y`@@Jz5j!W{X7n`o zw3RP)KTvrUzNFgSPhmiGG37%_}Wa}F~S|Z`)yp2Du&&!&OutF+bs6HqU~Wp5_=Y=gcn=Q z#nu7TFd?F;Ex>W@ud|T4qd3q_NX1tBYXb9$G$H^U)%R;!O{qtGb#zj3F>wZ8dVtP_ zQ!5JlpCA z%+mfvDH27>ct=s~)cTw`ahDT4yKG1FRQ?T#y8*G&y|s3KtQBZV7G~bI^9C^7puad; z-(Z02(v}dX>fF7J?}gaP(Ng|$=%U3Hdt;}!8OwxM;@o*_m+0?6Z-f4ZFI&cf#?B7g z!p2T^x10n(e>uFM5aFsfRIBY>sw{y-1K!-4sFBOM3rxv)CxnOlx z()V%t;?;#2h>r}sEdb_+H|thhIIM2yp)`CHs~A;BPIPe5McjiY>57|kaP*4^zUQ@+ zJ;fF}mShXP&KxHQ?^n4Ra?+O>)zdf;Xs}pyuH`F+6K!&_i>2|qshr?YJ3&?4MnG+N zV+YL^Eg7W)U%4r~;7HLDyounCExb`jD0*2x${S#iXXe0pa#xAg)T=%o(E1SPWVxVn z|G^ciCM|joZ(OFzuIRx(u_D`NwkOB-mBl;wMu>wvuWBDEO_?&idD9tlh(0*JH`Vu5 zE--MRa1P$#`wIH$hkeaKB?z@8$grwIW&QyQl_BpAG_CH|J(lG*2x2YhPZ=)e%eKDK zWx7K;VuD0CJhbB`hldQiVKrWhm-hpeUgZNq=D)@ED?jS*nOx(xA{OxDhNM-tNVj5$ zOMVfEHDNUJD0Y`Gkcj9uE)0(EQJj3X%z_5aoP92|1)be}u&cIwBW&;+!Z8><*sF1xB2PydMUqF;@hOP5ge zi+F=N_yuNQ+86+S4=Ab`gSl6EYoeib!qX7|TdRDq1}a%1*2>wt$l{oFLSsr>QZ@~! z3HR;@_kb#$FplYyO=U~ACl4T9U`9wlJ~@Z3+*F2h>pe8{D4bnDeR#~GA@PQ%#8<7{ zB+P^Q;nwf$^R)Q~3 z<|s+Tzf1(xs^{WgUK5&;S|_|)P&QKQZhI4B+|#HBX~xVo(X+z$KT1!crx0x;eE+SW zCefjZxKI?P7jfI$;rneX4Q&wy6TY8#X*khp5oVKzCcqldv7+$(qu80~EeY#Lo}MYO zK{!eH{z86Z12zb2@v2(#c82e7RfAWBBl*!vt*v@Vek^kC-7)#vuS0mBgN%MlsX!gNZkDAA+zS11w zK#+*FT*cB0uW|yRhJ&OJkeE1YL|auH`Qmwh&WB#FH!K+99iR495H%nZ}((XoTG z1Se@{#C`C6^%}JS3s)@YkrCPN{FB5%rbjFwKC|%J$PBk@4)wRYA93x^#sZtGF@C6| zR|$zD1&Lsy4EpVZ5ywj8AII#a$}winGB=iMo1VtzSYuY9xve-HZYYSIpRt--L;nNP zFnybWwCFYq?lE(%TC004aI6aIUW`_3a1%lr4IR#Hbm?D2p5t-#u~nK3qHYyb*Vedh z8SAyX*UpC8`K;fhc@!Kx&;1u420Tnw=!tDf=!tw|oPaLfmA33n4kLwgD&Fh|KR~7L zu~yYQCH$C*MK2FOrt39Y5PnQsKlVvjNr&9HD{#@yidG?ZQEd;_CIYS_#zTL_j214ZV8&}bBLsTjYu*Qsz5Q-v>&+vNe z$#rO4?p~DXkzNSPlE@DC+N*R;kE9tiEiU?^-NmoEgXf#@B2oFOlw7fMwD-0Oiwt++7uR=!I2y_JI3 zZVM+K9gB8Bts*TNsH7U#n-m{0gnCdW z-Q$YbonT8Ep+Kq6h=UI@fkbCU;V0^*s*BnmAG~D?i(<9d?G@ zCq565H>CVdl)HP7@;+cJgPLn~|F1~-+&L0_g5{T|rl5UgIDP+u{qT6e;=9=V1-8nR zFSG~>_;n6HzM3YZmzd5*!0TxF0f?bgeed<}l053>zrUTT>EUx2OGliJ(F7vmXrSZ5>jhAwCj&&+ zxAG+KM$LLio*7A_&aU`YkMA!9=scjzcI`lC!9nQyhLt0vHsmrrmSn)$F)NisQz!l6k+_b9mV>@B=r z)3qo~k@cuGHjC*|X-AM4Oo`%yDzFpb<)D;5{98H_3HU3{Y#0qO#%wuds zz?umhM+NMeqNNA;g4ZFVu+Rg}a@Ude)q&U$OAvY4aR|%;k*u_;K~q6AB<4ZchzP854=+el7mA&3m_e`)|D@xm>h#GXf1DzF6w6^-Qb>fhqBpP>AJsw)3|J0$4F@9l$T^~s&gy9 zYg0G3{6FWo`+gTpo%kq~c&b!rc_CC%7Vw&cxkUfPB4ma^vGU)PZH<=b);m*bZr2Ly zLfslh$+cJ%1@B)2Zzylo(ETj7j?1Gj0rY5WC=e3^9%(FN2_C&X;|A)}0bmLa^mg|3S!RVzUmUkMTuxh8@YPkw;I6R=U<% zh5&TBhBLWj2)5KoV1Sy4Fs;E~_#lP0O|2W3!rfvKRM-$g1|ax#t3EIJkljKLo@JLy z8Lco@+ff!_oL%gu|AYH+GB7*d@nO7ua1H7&?id2dG+zj|&`L%kor&|vi3!FKWQx08 z=x>Y{22QfEQ~YF$HOBQqupUfx83kh)6P{m+lIuPBrtNwX4^nrHp1^~UH>B7#b%U}2 zjy`~h6)k;$jT^tGU}$Vo_|oks!^Wz}x@xK(%7D)Ef|-8rzy2lYWOG%gYmHrzhUTBi zsw;=O=;_C0w%S!1y*S=A>dw>SUFY9Pc*N0n71!q^b7buj`J06?StER6lFf~A>eJW4 zK?BN}yTO2S&jk?>7+Ec@1Vq?&MswmW2?Yd=1ED}`#DoGh2QLThNgsRPwmSvz`Z|0` zCu&Mv1F<*$kq!aIf%*e(R0v^FeA= ztVh!-2RfH(OcIdx<}?~2Z-i7Nj=0;?^%X7oA`34;&&X;(7uJ&~E_C8#{b+0ege(gB zvy0;&VqfOZ9vN>K5yD#FXl#(N1CpOiOioF3dY-he28dmd9BE%g#UxMc^VP%^ZHRQl zrEcXrWJsib1lMOBbBjZ}`cnMv#ZJCC-thN=I|tqzuKN4!0~IVPIi#(!i~2R&B}$GB zbFC3`usi_x4UIFALq&%;tJQ8XzI=jAQYONmnRmr?-c_@r zgIZc!TXANuAUTLdaSHa(bdEXx&L)hE_`i1l)q)CRRky165`h*XtPbl9B zB+j`Z`f-#-I9bekYWOA$q7h&R5AlYPmOe6gMF2e_RDWyBIuUZs+)z@2#rZ2{%n-Q6 z{_GK6)vFj%H0*W1XBqvOuPTPj-xxRs$lNP$1dF2}Na%Y*>Apuy9@Zt-e?Q((^8dCh z3X!}N*Mw7OEm65Tf^h62E(rXEutKTWn)Dj|f1JGwcvRKZ|34uCA_OKX2q;QWtk7UZ zgF+fFU<_a}Ix&)f8qij48f`_H5mbWUB*1tawXId!(ux%=_Qe_nB^HE4D2YM|Dz&jv zjV*0=oU{f-h!UOO=ey6$WD?^0f1ke(PR?bYeO-I)bzg;e6g?PPrs;JG9tkb8Gkn-v z{YM^z3pbkkW_=PJ9q1%V{$(sFY|}=wc`hako-6?v79+N*;m{74(~G27%7;9xjSk(& z2crWmqXP#*c(O7tkEn8IWedLuQV0ZNzATJ!`Sw6UUJW#wONW4Om+Qo~mW@S4Lh~}*xJ_V@#5Bte!aTQ!uB3+^*4UN% zc!ixp^d>7LJ`|O=LefInimi}%(DjT2@mLQ+|3yFw)7;gbG3_oZiRK$8Hp>$*haEFDN)rMC>eBn6V<`UE89;QW5=@jg< z(lg}8^ULF_L@g*lm7csUyRaqOX6XtQ?sxSg-l`Y1X2BMIA=XJNh!&%*Hz7HJEb!q* zxLDZ+3pS#+BB>p`Uf%PF4*)^)4xL9mIajYvZT%R)T;O zsqK;S-kNuNxLHFppz$nf6WjSisNZ}&;P2LCIs#SbY z!e(Av>{>zmbsUJmwSu@JXssYT{(NY+t?zvj#jylQN4>I@<3_>5b7&@(XNYrnc^!2T zf3`1s9F&O$&_0RDOA9)n5irw`^{3m3+ORsF_d#H(jGpHDAtK7v0&~=4_U(t9jAx$W zjKSFrDP|axEjP*LK{MfPK5rzO;WZC zurV`~Po5a39$IV&sJ$U&2Qr!v@x`WQhNfnOrsCnTJ$gr)``lEFz~n#@Pf!~HMM(WX zX>$!vW%N16pRiz`$|Ee;hm;ua!eo=rwUm#WCb+o_z*Z|Cr*lpq6Q9+G9@J%idN^Ye z3se!!>sah90zxu{CY$O%>=P+T-6;t=o;*7JiHa~YE&DI^E$FH`QtRvg-sfr}N2F&r zWbfn|(IX~>)0X*6U=&lclL~l7UxX0bfh0!jx(-NglLRNlh$#RCbF zHH{QFLp9Q?(m?j}LTN8p=FAkwJ^=z;4+cKNt@LKiQUTUPi&8_=Ghu^IL2hnd8YaeN zPH1{sXnICyI?HX_bxIWjdX)2N{lEH@n4eLI*d#tmnbn@Y9{L%Ymk}A`EX>Gz|Gv|m ztJ3q{1p{o)u6O740ZrcmTQDOuFFo=*4EiAJMmf{de;)jM|BAG5MxXl6Q)lBuJg`>y z)W%z@R|>w4yynUQc{{xiDx5HeecRcps+0vcgXxB|FrB{9E2!7dtV7rzA$>m_@lpNp zX3?C!o{E#^h9;OtXZQ6)@}TMPM?F4o&z*xxt|q=Wrg`}6MVgA#zqj#!5;9}QDTDWw02dxvt4Om?Z8lyragrJA0KM!?m3A9*thH$5?YwXFqy#C zS0Mw;TLnM`+huA7Q*QT5in~|bymX>@q;1Du)Uqiu;vnY$^^IS40ATg6gX|x0&^sZFY znB21c{_|{fI;Fw9!##@|ecnxk*80N~%g0@>htZ+e^INcubrXa@j)}vwVCOvtTmg(>AFQS{G&JQ*-&HAmF>DF+?GduDo$&+I0X}TQjrj-qjEW&#+#e!iR5t7GT$fm(uiV9!9qdh^)<6u z$l5digOdT}A!=lG{+uSfp|uG(2bx`&3oZd#2YELUn=U$ZGDd@u$u95>u*bQSUS}l$ zFvHYM6@2)Loa3E4hjc-oILs-)osEwaCgg#+{X`OuO5k!z@IIoJo#3RD5WpETi zGdFmaC;0tz&paiXnKueh{jgD>D(loVosSx(jU^VN z$NVFFG#b2Ul`OLYGb#p_Z>03LDt_RN)_sC;&UxjJ>h7rrDUx`!&pvu2@#v{XxoqgG zYP91k(oB?kvBx}x?r2YApE_m0*So!$0c@=#`%$}}`Q}D;Uo4c}vbG`M$%I;0#5`nc zET&!P=5_}ClEJ<&^wI%--C@fLOp(&G_HJ$*a~Im5)>rAH*#naDg~R&BtQ^3i{;Gw` zaCIBMA}zo$J|~AyQxh8(<34R&|2VgluOh$P(?r1T8GpFW6RuWG{M09i{l=ShzA zxGyb4V)&~}w6+V|LZ_M5p!z>V!hk|V0?n`_HkKt}ENqAfZQ6yq(eO&nb7i?C@)mi9 zui7moJyyhvriTl6n4f*F<$^=nL5qFNFSvC-4Hppk)BXAyP=E60*C=U>%BPwicLI22 zBcnNlu7Fp>Gns(l`_0@-*!iOlYQo`z3Jx%Q^SvM9&0cUIGDtTi+|-tO`Y$z;|7h9S ziXpWdHD5PyE5nGwPooQrS&Ixax}eP*y`Qx$Y-z|pq+N#y>-`ROJA7|@bduDr|KQfi z-(BL&zbU@E!!vhB-zhb>dcSb387U>mregE%ZS8Drvvmh8vr^-0KTyj>@s>YU%ipAB z%P8hn4i602rmnUsBoDo5AP`<`h0J&9m_rtT!e+Y|`|&O5u?+j21uO%cKaOun%Ruj9 z%P>RvUIsG&Ldh|&jdmSQ;9jch1-nsi#y=;Tcw!y&{cNp+%BPy+7#eiD)?u(rbW$V7 zgN4mI7qJe%{lsEmy9n>!$|5wF?b{hT(e@|S4tR#4moO79kOmueM;DGX;|Zou#Nx8f z+_DUB)%hT$+%iCPJQr{`L_d#DK*Mww4_>>Bd7w9V3mY@_NL2BvFo~$MgDK!1$(_xj zOjv|{)>KSd8CU(V&zXc~7Z%NeYSJL_s9}saHIIx=C^F=(s)yQ zSPYgcJ}>&@2AM#mIql?l$Bd^x;D_Ie#*Ig4s*&wn01oevRth`l=%OqyZUG#G6;p zytsdD3b&DuZB)D=d4>Bb`+8rliww#u+`o7rSA%pKOVAh~$2XQmH$ZYCRxRZSI~g%g zk0Est)%&@#yVC}KBGVRv^E4V+C-8E7XbL|#;d8xa0 zz0_jU)zEb-c+b$m-q=qEyQ^v`DL>Fe;JSn6OCBOXX-4voG~4o6)<)~ww)=a^cTmhU zQ^@tto8p$hdzvHH{Q%lF!?`Mp4RK}Gl+eQ4AVgx@HAYa}Yum*#Bo?)Hf>mr^NKMjm zyB*nM{I(6-1*r^oVFet#;Wkh3mMm8$47-Q}cXfT>Eb%jg_z9eHxSp#ik)em{`}q4- z^qCzQ$oBT9Ris4@xhhvCQbHU5n-ba}u0d#%ZlyOk5_2)!i97wP)Bz|t`_e6#DAF)B z{dnNq(nM*szZVu+{3=+)=0tw^+L*7w!%HdC(EkvXn6q&N4L`h=2p60lDQ4;c4A2K$ zR~&wLJ&#PwrAK(%=)O%gzvMe!b?DXG3p+7edw57T*S7$HTwlmFwe&Tcc$cH&s9$)~ zO+4hCpFg2~iC7e7>WN$81H)E9bUwf$XVelvuwE;={P8T@bDgu9mJ z;zlVc5&@{=U%t)?#&`-FGN9K8+1t{XgV=id&kwKA^1xO0U4#>)Y>-ZLq@%v08-X5l zKXMBP-VAP=p*sARhF542`MQB6#2RriAo3dmmpRRNk9}QL_FMPMz>eUyEL+u;L0opj zn*<-ho7-XD<*I40?iF)sesv~#k+OEGL|)#Vd4_$6eI}PpA~KrM4cORP2r|Q}(F|EY zGmA(O=fa=RVQd}`%ZS(o(AoCAz&M8Y8d7Gg$07D@TSO3Vp8gO@_u-|C-2CKo)E`Zz ze2z%W#5zd87F+(YCnlDnpbPb(pLVaAzt$C^cF9n`Otp;6$P%;bMwgLEY9k)I z1s3xE)Q0xH8O$KMGfO{DwDJ9~Z$mPt-w;K|etHVOHb}`_eVS3eilr(s<6>VU=!%7^ z$VxD>of1)^`m^Hp>!BYYs?hgfoOwtqEk5zXD!UI65RGJKle&V}AJqZZWS(7wKq56N%k*v(kH%VQ@;bZ^9)ej$*zZQHzVQVa2-($& z%aEZgHtiOO2L}-eBQ?57I2;GEo>RVJpPugu1VZ}+F6P5W&j zGpz_Or4+=Vg3F5|Ypcn|5_q zXv0VzMmHHso8fs-tK>PK4hG+>zT#5Pule)6N21EQKH}1^qM^-I%xlQ{FoiZx=HsqY zJlJ+qGOThMh%^XQuFDPTZytz#-c@Rj;!V}sz&#MWR80id z2&~Sc1G!kzRh_1bpw239)egNcSdZrgjx{)?gbUV_d}<9(V`(j>BdN`vo>no$hZsE@ z%`#T+lb~zO?{|Q53icBlA@%`^OU%UpdY2*(Z@7&vge$i^9d?#dUxoZOoyv7Yn#XY| zWjfk}#_R%=V2JQl}^EwpKU83*f{)_l$j5?gicgSF9j(6qS|T>Sz=hgp%{ zpvy#3$U|HUZT*{I5fy!-HgO-85VCXy3HU3W%GDL^7(2xGeM;c_?)EPd7qmaY2(bh{ ziYZnLmr_G*M1G1TuwKN1MHjT>6|`3(_oojn6+;yV2eNv95#P1YU_~D;;w=Y4tWgY* zUi?1OQMRUc6c@aC9Rpj_JBFK~O;xzgNyP@gM%Qt3f&`LFNW$CcKZJ66ctLy#m;Rb|n6S zPlbVP7Ua6=>D+l16oUMU>H6eE*UyLs*8XpJ`PO;{1$JE53wA7Am)Gcha5G3t$Px3& z>rDQ7VMlA{*Da$2)S|FMaI?rsa6_q}(auE$;j8079-UO~IZ9Ba!*w+3h|*Fl`fQaA zc7h8^u=fvK8l9i+(n@y?R3tB_y#m3vxkDYj3ISv`O25+d>|qr{imt}whF8C(x)R{{ zmx!KP_p_+7AtFoM77mY_WQ7%WM8=uv+1Tq(aO*zV)}8Zue2oqf;8mxp)jQj{cSJF( zL+S2uhN9kv8%}Lk)`P%r-7eD#FA`<@qovE9#FK>?*$W9d8w%8h@VIm=-CYQFlhr|$ z5N$Z9K1u2Zf%qIwSn-}M9bltzve_y56|*UGO>fm9uGHNwU?Q7eS9gP()m_`!1Hgb-(}MMZxrtNU9)-FpRFxY!@4+dn9?a<=DhBgdFw<$XQx71Yj|qZfsB`_I=4 zbK{F>2pOeAGJt}8Se-RyzmdAf-{0Ap{TdIP!i~h??<)hZees3|2XEdDt?MpdVM z2kP1MY_IZw%-R96LwJS#LgUpHtUurh5=<>bN{gL_JR(1UjRqTAqX03Pb{%Aeu5P$< z<*nY642reSx}ZpGp2-v8&03y^H#-PT1syzF_~Mw;zB!T$`&Zm+W1x>RVQ$ZYbXw-_nk&!W?=8g2&hsXI;;)+q71TnE2Sy;_y zKD~`0gH;1f%60M$XD0}DB9QJ};5Ph#{azzaYLw#dsJ6fUpfhS-|GgFZnjejIHSfW; zBwCVjp*)2qLcbd$**`n2Qxu?}sGrbZ|6&x`PR&iaj-x{OG$(KX)n*x?`w(e)AKji` zZ0`Ry^Nek^CH*yx%jeIvTh=ck>}OD2^JN#gZ+VoV(eQIupW_Vh~-v?o}Do0vyMUvk_;&MF@++~Yk0ufp~h*npO#6pgmRC84Rzv02=4yQLf+ z1M2UurXPt0ZF?T%!Jp!Ky~|Afp&%$&x!)7GgWQ}H4&L0tLDCZ4AbK=-^8u*c;LV1s zHuCY|x3s|$t-psE<5(CQ4lbqsybk}cuTg;J)U|#a;0SJ(*udleQNs$uE&n``?_adjUE=KgL6dl1Zko;wPPZ6ku2NYa%oQ*iSt zHP4wV;{D#ufQvg3fzxcVj?w1NxHCm-hSM?g2A5$+>}MpPh0{Su`UdgI=J9n__C|VH z3}^k~SH?BtSb2U$y1D-|cQInTY-~M#@|Gr;^*9`q$)v5N)O>jx=y*b`>1(^1zKTos zkxe6Re(?^UHkiEsv0JoaM(r8D1*-1nR>7mnQ2*}$hxp8Y%B}W(y)oHR(ny_vMIR=y zp~`)3kS|vh!>Y;#&!uIphI}92GmN3Q%Az!|)L%G&6Zl@s7ry5oiq~Ve7dEPa#V2WV zii)TZXJfU82esL91B^X?pBzshisiqf)3{(xsP(DSKj&7tX`y^`H%N>m)8C8|^CwQ} z5|@lN|HMumGs$s0vP`HDq~mCNh(mzXYw}jfr!Qnzj=+IYZ*@KQ?vW`>(=N0mhZ`5Q zgShZn)Jgc%8C@sgUAQyb^B;sI?aYs8))}1hUJrT?78hW`5^tJ~kKT>e6M`Gm4oh7z zX4&fmg7#nlLo2_2nVS0N_c$XcoY%bg4+O7<@;czH{sEFW@DvOeY6CmGkOfYNmg*J_ zXO|%fnrN=UC01=LBBYwCA*MxMyO{rT0(|J$*nuVcO%e3efzHUxQWxt#O7tWqLub8z z46N)62Y~7Xb}nq!un4snKtF}TbD;ub*`4Uttk5BH8w$MO1a>!Au1vcXFgY2gZ0E{! z=dQGhvxu0a#8mfh!l>kMpf&iExHtOFvv1{y0@)E4=@jg+B9||JaxmKZj>@12+brBt zkum4frx_cpu^lZL{4Be%%RK%PU9hy9T~q%BRy5_3Tg{`pmhyjyg_j`Zo}nw6s-NQ} zsmTt!fzWD~IrnUuOsXqC0UHival816>ZB@XE4-eM%&*44*bg4@of zH4M(RvDB@URwAz?l#5MBa(~_ zMAwX$mzC`miN-jHbl>6zkpY%?vL@)AMIzQ)_$pRbXjTN7tovNaR=7}wnvC?-R@^!n zpGERZPVp6+33?_9YIMZQ?0F2S%|~hlwqD&9liVF zoM`0Ry-L1fB%p`!#VlKox3fQxUVmq%BvXOYr}su!VvYHGn+M){d+m&ThWepMHfWft z_^(M!D`T7<{&{>>f#yxPPQ|JI2fkuf0cY&Uw5%hU+yovF5-ZFIp+dXcYo~jgZB6S& zSQgtFQ)nuo+GLsmW_@1MLi6Ct?qo1C{!XwXg~Xp$W}UKRP;i@N9K1iO4SknT$2j9URkQ%4qU#L zao0Yk!}jr~+`|@yFu@j^bE4(VOo7k5^t6pA3RW^%qbpi3~aHO`Z1Tlpck zY-_t>w<7d%=?L7S!i9US`N9_uD9HN(WIqyDdoH06$7qvL-vkLN&_NJG`!-&Fi_~OSkaygv^iffQ8EsEgvDW^bXl#-26OV0_LOlrxCf~D1w(1RbupuHdxF`} z7J>3{d5MNNya1N z951rKo+MCge}3Z&c{f^WBS6lGRx9;_0BAu%Cb3Bud_Z`(Nugvznb}LM)xvft;%MmS zuH>4-l`0-gu0ldKy4j5fr<*{=cmPyZl}+Y0FQi2Z7n9Buko2&-poYl6SjqZ-p%bOx zEBu8Ugx;H=NV%|~pPN9{oEIwWNh^6-xS@Ijq6A+Y& z834z*=XSRcJvvU&O93o7uQPWUxep0dd8=?V_T)Y!iJP~og=>2h{{%}4Av|x@pLj%! zriSGb-)X?+le6im72t`pCfTT!;kk^rx!^fhY}t!Q+2#7%L^M246~V3cbO{WUJ^3t{ z`!;yl(hMvXL$eTOc2o?>e$A?j>V2^FqNxA6o`xam31YMhYcZLau4gP! z3@x@6ErU2>s|L_Ljp8GZCy6YRJkYIz8}cum6lDisFJh{UQ4qJ?7#qN8ARO2AGywE2 zri+`(5)k+HVS4N8vPL*wjA}ZM0gb@rlJNF2RgwdnH4hNQu?>fnHX=)6YlkPjI6CJA z1vXE>7<++k*zi$ULmV)#me6cGHq!HtX@D{P;@B>o4RRG17NE|6h4kFzE-XCE`sOZo zVIjyhN5FkV(W(Lf?eTYK_x^U5^tZXZzPrpw_r>SLZ={T7rq+vWb=TclF2QFY9TE1p zf47B|eDXOtq4d+@d)K=jy`0LPeU1;Zr^_VTLZJ(Ha zi(e10w*Y{69xIln--W?54$}RvYvIz)99& zy7H|R*#)U$I4i3 zCL6z-pN+#q;-1@%LvAywx7jA#9}GCbBoWGQUP`aEG>QWxHpyEhEmUux*)#J0ut;c? z7hV3pos^xQ#14`HUF#?cfHS4{b?6B$8h~*Jz(5BVOX!JTcI6?&ouVX;i9QuG>16J<+F&EOH~6Q{h+JY`6OGjD z*5uz)5|=(NOozAIixbnV&e*$`oQDN@$am%U-JeDxPftNpwpDg9ur^o8A8E-rdHuvB z*yX9%wTQ?M^mCaIps~czpJ*DfB;tj>+JKacKhO-LC$)XUq(`W5o)@(Dg=Z zt{B8V=pKbwsA`2!PjK56mf0fc8qFP;LCJ^p#AiOvw&o7otu2-$AoZp2L*_%kCPqhn zNj|5Tk1f)1~mkv&Rv$r^%fmnEN5 z&@83lpWkGmW1sV>)S#97i**j-j%}X%NJiO~=)n@e=$nVb>JfXa`{yR@pBe1d*hC!q zFH4Sk7B%}EAF4jG(YbMG*p}6>W1z?}PT_9if|2CdfsNS0!JRznLQMHll7%<5F(b0# z(HW`p9YgRvrtLK0g?*mD_npe-yst2;iI$YMK0(iV!|m|x-iJcGbX9JB0w)2^Bws9O zx3NsKfj!jCk)hJ7@U$)IY1B9k*w&3iL698uphd_ z*%kAnt=wB`RuHzKLh(168UBTkq8!?yQl%LF=0jb_c4fL8VFM?bWp;{4#ao!+q?{Rr z8O6?$aer0#Ni-f#C)jpF7bu8cAuKmB4eG4c>{Wc5A)RG7_k;fkCPQUw*q7}5kC;z_ zW8`iXPJtyN32--F1E9=n@K$XXAjToZyKS$NdUXhIy|@}IG;3YLuvZk;D6<+FbGhd} z3F?5k{Xhp3reH#?A8A=+pt9a6SckESHT@9zqj*w8;)Ee4NFgELkliIRamTg&yG0Ox zITCUEundBzt`cPsxXOHs*339H`S_*OJ_Xg4Z4(K~$2bFpET>`8RVr1bR`o3Px-FF^ zkYm;YbPAV^_0-}9wIYTB8^L?0MvP1Z)+LK14pfjr$V3XC20R2TV0N_Cw z@s8}m8mmiRpI2Wp+q+ukrIC!B*K_Ko<{c!gjsI*~9!EJ*!}Xwm?E7V@`gEwE&IR+Q z6>2!U@#&{AsECYn$_}aE_T++FaK#1k-Ga>&EZgtAYv+Zaxbb-*HZBd#$*tU|fPw3s zN){C(iJDNsx^Tf-m%x>Shj=;cP}atwrOTJ0x=#DXKN&^1yS1GT4c43jrym(h#mGN; z;eOe{Bs8#lP%IoXj1E6st0^v(@?*Q=qVO=V|LM>wZNi+or>Brz1YR&fAJ;$NZZx>T z+aU~c6mnCixp{Rma))8z6-$9rpY!5Pf{7$OFEO%_g!RbMtW5*s4& zz6Yz-rHkGVwo7m*TuL83U=)3d*)3Km?^KfIB2#?DuU!T5ly~GPfF%O<8gWDI3m&uz z#_0zMQh(X6u0R%=SHnzBDy2$PAuz3E8S%+U(NE>_E`sOc+bNU z4qD0Jfw*K4J)v3k6|?E4NbVe&4-gEZ(C#Le5yb*Yh-#e ztA#XxfRd!C^D)munW^kWigeo7+;o?ulB|+}OPHVV!bZ+ux!h53{~R&Jqxm(KRiD50JU_nL5jgl}o%B>OAeZSG6l#hz7S%+e;Q&>m(m zCd}Ke%LX$$+)Ynp4V+LeOABPyK!uUL`^esP_?Jq?8MV4nD6N0zaxiWXUCqs3?aeB_ z;O0;EMv%-+oxKrv%*_USBV5PLGu+5_Pb9g2sLxf~qx>p08`E)N9YxDAQN^{+25lzv zBjyf1Qk;ks^(&@BvzmZ*4nRxjx;nYb`gN%shT$qVXATA<;>BiDx797Y)%q%*=uwEe zT5GsDJe_RORnKrG+tU*B08Vsa$4}Gdr8%s*?P{0)QRM9wASrBZL$%3%Z|~e`@R>Eb zW6Sa4X974~hJu=xa8MKCGfQlFcRqY(K6f!y^qD0|)A2NJo8h3AgW0J_G1-WTTCG#6 zoqliCUs)H%4i}>?jk9ej;|Cg&hgR^;Cf@CaC!rb~6pa-r*vtkxO+GE)&)=Q05UR%quQ#qs)w9k{^E^;X}_PRq5cxa3qPC`C&G zk1oP{WX_xt@Zl#XeZ^#U4YUY9+X!U%F7q$2bZCQQ)w!`TOQ%i`cA0-5T$W3qy&&Lz&KZoFV&2ZP?^3Y;N3tdo?UK}=awb+YE1 z4&YewdIo2nU@UIV+k+-DxN zm(=bv%j_l9`^;Tj#s*Vf#q!nW>s-hVaW3HLUjr|OId%dKUBNtKXb_$+RK6^qL$@!a zsC9;o+ammMnv}@isx?&Rbi|AhynmNyr_PFYe&C>o+6Wc9(RpDw^>qPv9YSn{8~XX% zAjg7@U~;+ixe54^PrZ%61Nj?>>r60CEL7a?yi9jQ+01BPNnpwE?r!gH$?#`f@+AxN zR+rOxS!f4p(3^KtB1d16@&r^-u-@Fy#5mQ0pVo^7BaIr=!{Dpv9VB*hMS}(F%=sT$ zQlxAPQNu*AZ$UTGeN;7eRCQ+iTkYT^d07z&r^#fdA>e+`Y053zf?~AToIraVWn;wP zHJOqQ22-|$2PgKT+9Id7*ip9N_X))$PPECql>>|gc5v0m6$FEZ@gR||LIsb63m&W> zc1T*DUhLJ2N3rq^6|4#uJgOIwZ)5h6i2;ug=KI{pjtZRC@2dp`~2M+*SVp-EnNGemJ!=+M1_5 zE6T|gDV={=f+ha&1DCwplJg!D7AmV#&3`(VmIK_a50$MB1s>5+)WO1-?=q2q%~~_+ zbxrVEG;XXC^l6hRO_5PxtOfwitfZ1)Wu1p8qr83-`T<@9CvuJZHr_F-y1bFg3TaDq z^QTTAi5uq4XXLwUSeGy>pv$VxOWT zuXSqcx_!Nduf@Ujk{WZPDz2johym{03Y&Yv0p(TI#NDAB2TYWkJ1MfsbClXw}pvJ}W@r2{%+$v}%LV?zQd5~Cl z^J{-9#C0bR;l4pz=r%)@YeQ_zI1Ob}Z}(!f%Mvlc=EoBNFnIiKXAh^fRxrT3=mrV1 zxhdyHX3{%y3pwQ#@3B`wT}&T0 z-Dp1s$M?`=bVJ8DJJ9=RPcG0qdgyLrlX8Pz7p?&jI3Zz#By{kNu!{~ZvPE_a6TGQz z6t1-^&FyRUcE?nvF^_3{@D&z2x?#TsMbnSZ!W$axP4upGbNE|qAmZRGk?|9U;yYhZ zS5uUHWxUAGo14D4l@UfaJmM};15cwHtlqfE{DB({c!u634OkQWYu<^Si#bNX^2vPB zk^qu2Xru4d?%u^A+zPA2!qnld1H1(4%!OxbldoZuuTfoRbF1|YH0o{?ci5T(yJFyt z=RMiYY~l7BoD($`kh%j};TBPL?CQI}Y5lLLDQJt~BrcG5k!0p22_(7Yui9C4V4WR7qq%3i@X|W4p$vkz|3?_3 z(VXDcu-Y_jR}HIym{bjEfc<=x=3^=!MgyxjfBt}TSQ4fis~QnV0!{j41h=?5If2#o zu)c$-P<{@P^?0t-m>*mL2p6uG?>j)23(0$~vu%uB#5kR|9*hEF+bzlJ00D%u*X;0_ z%`-Vd6eGad)*W5OKWP1##WB12?k%pYXTW+>F)4vF?|s+Bnd^izy;aYtt|oI)ShG;W zO7(&_*9pDh+O@tHylLB&gonP?k)Mqg*Y(7lHTs^R5XKOmQj%Dw_CXiQSNbug`?tgc`t;qvM8qEx3AhJl>g=3U;0g&GdLTZEv zEhWZzkhi^@D@dSb^!6N_IfL+|!+Luco)L9UEOK5P(gRxsD_1gPyBIPhT4}Crz?8_G zT^YA83AQEM9mwWD8u`z2SBP`-R+lkZxho_x@Kz1vy2SkP+d?JQBjt{FM4cN^=iaIu z-Z~b*Bm+NFcc6#v)`A=WSPxNpWnbPS=8_BJf-EL6$$!!HL2H9!izz_HB7QMjFSc#5 zMMgN8@K!H&vo4ihgv7Ugg3OQ7kr5lN+3J)OrVJ!bD+UuOL~J+sORKq zqK`e*(V6mbWLoYDNe%oLJ1ds*H8En6HSVsrxp>V*r#g?T0CLad`r`!>Qnspqq->To zM4OMYA$R$F7L$O3HvGT69%+p}|38udbT_(*8O|EiSj^q5@GH{2i$2CO-Dma!x^Xkl zr}jZTCGZG;NRHJCC zzuzNaVbI#G0aDX20k&4?c!85HK4yykqseTBc8PV7z9C5UR^1M&hesrkRttf#)^PV2kxhpyS}8SuZpGI- z&`x~LU1r?dE|dmFxnhunU}Y2mVKGw`yIJ)OhJ*jKwF5yh50XT|Z?QfK5#k=l0~1<% z>6i)7arh%PnGaVoWYA6kR|YHUU`AU%)es8WI4l2GGZA_7HZuJy>r@``?aC_G@ifyv z-<)&A5()cF+h$G$vPj`1YYD^dWFfPQDX34{1oPyO4n|Z}=O3-|2OuR0vQx*jC9egB zHn?UuRtW16(YJp~do(gt<_PSo|C@11;5aKR+<-C&-Hml?CB{&@ypCiG8h5=J84&Ga zKxbNYXwcy1z3d2%wr1!#+`!efem&I4@^*+#4Dm1v_ZFc)kYv^D@k`DgI1>l15>{w_ zni=<79cPV%?Xo4%QkW71prHwJdxTzW7A#(vjHLyOxUSXv2`@?9-eUud!v_I#XRBlV z$!y^w8e)Ja&ma~f=z@<`xMTQ9&BL(>5+PI5*kj_I%68yo(y6lb^H#l~C2umHk92Q0 z>lQr|3)bG_JF5s5kS^1UCX+FlbJ|f14s(5w!?e;w24LVpJl5abNJKCGp7Jxz)O{a8 zg*V#z{d2f{$i2Msm>E~Um=|Irqd?td>e%GK@;7|1v{d1w``@Q%gLnR+*3_wI?_%Io z&<3Iq4eYw4WK3jNkT$ekqz(8&aOVF*yJXYVk1EnzWlLNrDf&AbqCD=M`|QVEXmW9r zwy0z%4O`?R(&!2Nne*nGJoxqnwwI&0JcrA#lK~<^q5gDLaW95#HnGG+Zcc2X6H-f@ z<>d7cWpZ#jn=FC5Coak4ktyQL5G#B5zhY%4)E*VOUBE+mjqFDL58X zZN7_jW$O?gy0$bru=}Y5y+rmFZ&XN0NT$d!Z;(co^lvE;swyokmD@T&;oh3^GCsn*}pUg+Y z?-D9iIt3I4GQ3I9Ei2f+&bNF1TJSMje$zSueGULA{EYipi@61^&%v!eJ@zu|C!ieE ztKSN*kUL-(22Qj5|82>8i&Yh(K*omM{ejk>XbVDx_hm<;)1#C zHTQD;kL`9lpfljG{}#G^^$2UwdmWd<-AiAuQyJTHh~&<<6Zy^9p1WsFY|o7-l9@B) zQnziVRUqk{Js*tO{gNw?pd@QC$zci`d$Z(*<1{)z%prmK57yrKu{+B7PP`BAf zPkJ0(iky&4Z^_bLkas{w*WWa299@5^j2&IxD#e*F^V@Crn$6jCPiYI9?eW#8H>rl< z_-girSQkGrAZq>l@g7}5^@ z1A5oG)K+-x`6mFm!JXFQg0&(?Jb_Z1*0D&uA&i9#b&sJFG(8}d^*#HxNi^vUz&b`x zs9fdl_<(wBp*Oz8I*>*o8H1ijXN5se=tNr-*bg3TGUuHe!-GxcEH1we4_d_cf5mmd z${nQZ>oL?S}TK$y5LF@N(WQDGica z3eSrLnEUxp&t8z06P;Flc**c^er75B>CS&s&tx)JPv=42SBoRouz!1LcxI;g9q$@s zh~pv3eriMHU-6EfNcEDF_IDFxR#U>-@%`OF>iGK9Tk`4yeh8H*hh`8*pB}KTl08=a!Z7NntOW_4UtF&2`F^Toe7`!Syp>z;Q<+MO5Y-I2a9H~WsX z((v7xlFxnkPkc&V&n?U-!RR-fQOHNp6tM}7ykPY!trTywZn8W|e}=<#Yy!vr&~k3L z3wo;r3Ywk_I_NSeO{~1)9l29PTob0q`w$s6JS1x5acq3vYT1q0Nphc;GthNe{##AU zN3qHL)$=_jQ~iEd;t@A(?Bd0@1ShBX&t@-w1IZKfGgm&@qM%*{?7{n#tssW6J5L;(m```$WLs9hm7V0PIh@a7op`H_E*#A>}=?_jt$(fypw0zTKEFm zxU)raj6th^Uf>8}!c_(w@%r|L6kWD1=c!%cgYG*M;6eA$Zb8s6q21D`w8UI_ViJ~# zfd)}kKR55BARt?={)JZP*I6#-o6rjVI&ODYsMF4Jg>(t6(68eTV1lYLTwBcXa?UfM`U$g5Q-#vW^F#jhW%X zqcpf#z4G7yth5c` z8yE}RZK)3E)ahf)0)52>vFGEePv@Qy$5G=*hr_`=%cPU@JA`^Y%olgK2)Q@fJ2 z-cFXXi=Sl@Km38VUa0I*N#xiE5JQ>HEWm9Irhr7`3e8%ZyIE^RblZy?rlmn_12e4; za-8RG)|&VSU0vjpjs7nlL0WYneD8P{V+Zav<^Q((ZoN5kJ*aa*mhftcxe%K#_Qf^W z$rFF!cTaP!*ZHS$G!h_Sy(xTML~PW5z7trFJB2gtPkQ(uImo~x!<_RcdWirWsF9PV zIpLc+L8J{h>@R|Zi<#q^(_i_V&IHb~g!g>LkpS94tL!gWFKMVbTB~CIVRowij-#gx zL2)ZQFl)N_CCR_cH#r4 zn&8*gmD-FFnAH!Zhi0dl?YDqXV;K;~Bw167I6(kdw%>(fZ}s^sNbY7~7H`!!acB!} zbIJLtv$@mhTK7LL2%eg|ynP@5J`@bg-*EmlGIE!cQkiLE&_C80vL(F@;Om}D+ekx43?2AR0LP-yQQXk>BcmDXV%3KE(Sq4SkcB{CWz&q+- z^*taTu-jyK0-((b8>nAVM}jdsR~j%w##Fm_YjZfJ5O4V+{9UONf~F!cJr_O zE}0T+^LK4IvTJxVz-XN209?Z6B^&tFA>0YjPc-2>%66=i2r54@3ah zzg#DMBn37Y_LnjV=(30Hm{8$vtZq{&#ld<^fgDtpy8$gcE*qVoHUguv8;39=-^=g> zXHFy*O59CRT>woz#jjJgHXK;X)PWt{E@C!RYi_zKK8MOqm*|R1oP2v(4i{K{u81d5TLq~$9SSFIVS51N@+nGcA}80bKN?$Zp@yz{~%$<1lxWmv~Q z>NB6QcWp;)v|h90%6R{Jwu|6oYAVt5+RU1-Et85JnBoF72J1=71~Eo>Nld-bfFR>& z?hz4}POv;M?nZF%3gO4Jn8A&9R~0-7C?}BK{d%LqEOh zia%ZXtQ9oii8!-=5(`k_uf0_?Wq2N-UzTpl|7IziDs$#d@}~_@Zu<1RC5INbL{4=Img=4P55E zzh+?**{Cu(K@$kSmuytnL|Ji?@<6Iavyczw%t0DqE~WK3xaZvz()xMkVB5i2g*9|We#@})N%TbR!a4X=Fh^_?^CpX6`Q=2)sp4nsP9fXn z=(MDrV$0i{j<`IY0!fAu*)KU3_$!eOdaRQKmz_b&&LbC9I6E%HsXbug#2wY%NQTDxV3bd{a`PP{Bo5DO14@e+0+4C*4)GKK&g zdF_icNpp#0=}w4&Ww`|zcaF9hFvZc`OvThFn}LiP^TO}iEwJNJ{GEMn=esJLl$<;B zZ1=nHg*8m3e3S`TL@K}8pIeN?ejTwXQC0M9w<>_kDZ8t}uozOWontnVxrWNhZN*>q%|; zfX}Ss>&W2B!P$FAG+M;D%sr-f3({K`A{cS*&8$Ws=;Yg!oT;x>q}6w%&dY09Ja8Ll zC)E6XeMsS$mJ6Q9BV=`6{o+}qi@3 zHI{{(Io|2Wo;ju>t;m@14YCMd*nL zq~N_HVZLRcN##?WO)}Ug=DoDdRXntvf-Y(@C#QErrQPfRXTX(-r|f?JzG-Ye1*iN{fV7H~t- z8SxP`4z$xZC~N)uPI#6crUVA+PnN%bMW09?qW($7vHU$qyggV zsPL|3o^6r#@(McqcSAPLj=Sk>(j2%jl{YObAOLuiroZO(#i(PlT%UoY4;z+i{xpS= zQ*(c0nmx|w4A7p6g1M6O#cj64h0>hDHl9!a;-sU@-hXAb*ZP`4AZgn&l^ea0Npv_S`%cxtW^Fi08{eNwa)4mqnpd7%geiuRZBb9VJqpqz}x%al??s$*MzS)%-9y_A<`-khcK zz+^&KWd%;xz+c7EuXVk!t6^XJx?Y!{^higS3bd^20WHCYhw~(*i+imZyNG~qg^A7$bx*cNZ?|_u6H0o(pNDzYB8T-+| z)Ml|>+iPpUliO<>L5ACf2j^y5em)0GQ_Lj{+Ja&B$!M{EQ}oE{qLwCilCzg;o#p$O z0UP6>C>DFwuVAXK;*=OXGpc5K`fq$}_SOHTLkR65m*CVYsx zqyI&h@aL}KkZ)5&4i-pxukhBtRoU5WnWzf3nhoc5~#%kZ`Dq%vkqHoB1bCtO2Nr zk~x>kMoW3rZhq)k<0(53!OIe%D9SwX&fT0Y$j|6Giv;Q zvo=pBSdwCkjJlR7=TyvW3SvDVrdjnaowwV zI#JDN;k~%qnOn^=%`Q+nmp1aV-kS1BXckw!#mYO;n1qk>y?;CKko zwa0YKju|zf7d#Bb(P#9ec`<_$i|=G57)|Qo_KJ+!Ln588D-`Jr{U+N13uc!gaWQ7g zn;1VbZ&<@;TIm33l5FS$fn+SRB&i+@{T*PIyzPd79BCDE^SRTfOh%?OVCtBb7 zf}}|C6!))3QWd9A#)3T$4{LmOK8>Fn9lFtOw>IK$5L2q%Y{iN)ZzuL0{pl5?SevZ=*QEwyTa^AYM z_8V;ANJg#lkwyAipWX`3)xP8{4gQJ&Oz@Q!M(y!4;PkWYf!o(ynEHv$scPx)bGVV3 zF_q?`X(0PO<^ybw0rOLs@J91}HZU18`t$t13b{(WXauC@X+r18s0iNFwDqyO=bMD2 zutHPOket(T%n)5TzM{<<&*>=FncO8af@sJTKDNks)nQA+-$3(mi@_( z0+;8OrDLF4hP8(C!fna$Cn8+d*eB~v8?&4My4ah*i4y#*(#D_|=qlagKh5TO*pXZh z-Sr{Y)N+onD2?MVx=DL3(%MC#Cb1e_&|+hQA2hE4OXBYRBZ;ghFV7f58Z zJyM7YXpcBTr}VOKV^FiKZ35JBLQvc(mhD~BK$;`%t_}$odaeu*eIEfBpM}sy@%6lB z12tRE`O*}4tA5N|FlM?F1ao^h@<|IB^=(UI2Ex^Q0XP&2`5kGTa4+4@0UoTPRB*=- zRN6Cr<>P0~L0`~ZalFs8-|Dgu=DL4!a<#kP`b;5rB)Zx$JnzVYlf_~rDjghAr8iJ1 z^3qsw8C3M&41mN{MI)z3RYZpR7;SXfG#!iP$)d#Qtf$Nq!aOW1X-l2?<;hEr46s_X zlhYp`>+Vy)QakMesA&olFi?;#2%607O||uN)&#!EnRIe*vuDrx3?X6C&U|$=8u_8w zx;;jF-MiAIy{PR{YWvjZ5&yG(G*r9Wd{k>1CnDTG7Z+ceI{0CdA=wXkO(4DMjx@(fvZm-sUBo`H z14)skVuH{jv2)$PLUW=?nB?S-EiHypRlN84i3zPl5@18JoaqcBSAx&E)1P?9i^yQ& zI(y2G!>-31Mi8#OAwDM9HY5ptkt~2M4(AU~34FIiIS$)=D9sZ-h2~s950qEHh+nxX zHgj}{Ko8tuB-LboqYHf(9l97a=FEb#J;XG@TIXjXiO=2{Do#hR8_FLtm*UOD4iH2s zyx^{jT!5liWv%ahW)D6Iw}VT@dIEzh(##SJiW;Vk%^Ep7MtNE%KT=DefqHk@eQ7E5 z&VL*iPXbke{+Ps`yUAr@_ncu-uO){rL7ILxqzWdZ$1R*-;{&ZvMl&F#xuRZ5r8qxI zbPs#_47c1=U@LezF3GnNny+p8<(J*2i*3{1>UDy2dkl*Uu@1_m&irc4W9m{D@ySLQ!qK$R?ThuqYM7%^` zRPMqwJ4tDL7C62%E>Q4uyz*LVf>h2$i#y{^lp#xQ!)t^rKNF+8g0HCMK7oG9$DQUW zYrU<*u9?o9K$;$zXEw(L1Bo-^S>hXTY{}Uvhg47&q)*k!(9@ouQP}mOdZ7OJys}Pj z^;#xJleAis)E155dU3*%g>Vev^1}&)OVJgAPT&Du^DZ-}Fb=Ef%l@Shm63kS_ULVH zpu=BWzKq%=4U5+&328}J^*WBrCoxosArgg@(NY*n2TA-xdE7F0vAFIr>z}ZWj1bJ>gB|RM*h|K#P^U6X0+UQgpNG4jjJwJp%76x1AMR2E#h8*l2%i?eA{; z+sLoe5PD*r?w(k0e{1aT4*OfjZ^MeqXn}to697+Zr=#OsnwijXf^K5_p51!rrl%-L z2ZLwVU}=@&_AD^jv28G`r%JX4`jD9*Vy1rj@$Zx`uhxMCPHX;!K=9q&J|uJsB4BHC9Iz~q>}ECMq%H>8b` zhc@wQ%TS6-+&1s$7L~wdnFU1nka=Qfc|XIv>@n|MF0-cz&!ceo^(rJ(D>N_G_-Q1@ zSh?q`Zg2Ht%#A{R-TvNJ(bkYA>ffm1cyR6HL!=N1KcUHU29|rM^pv{t^s!TLt<{{L zdC{fxaMOM*0+Jq5)W&H?snb+bG|=JX2oSw5(fS zXNHQ-mj&-iQhWV~ zy{@v?kLtR~+^*Rw>?}`V*3Ahsw2=D_pkw*-V=QvByW3bw0z|p%i0$4$#^7!VyF3Y0 zt`j7u?z(wG06;kb3hp`>ofC8as`|dQc^Pa+fQF&bEX(=~nf%<=3;u*MIiq&wSn$P> z3&9r$gIjN6RiFg_&TomijB3dDkn>(JiY~y+AtsIa=N~L#(`J5iA276B<;CVz3@DDy zAE|TLjD?pLd^pr$UUrLvhA1u)hpGZYKw)@WAUpDznL!bK8Icj#`-G=QQ?X6vId6St zf_;_g{91^IBb~XB7$K#^or7A77LvkcD8D1#yq@y!GPU*)l{iLJ(zKlg9yti98G4lPus#o5X9y&lZdi z50si8lnOzi{}B~ZaDIXcK~mAhb#1wpLVL^%COFOrbqQ;_v&)_~)+kIGfc%g=;)p zt0t4g8tzMpbZXVLq&E?Ky@iXw?1eVW*!1WIix?hzf{oun{S3^}CTC!dP=fU$uItf2 zMM`-3HDsz>NmZ_CF~mij?{1rrOn$ygo{qiY&9+e#xr6w^%?6OlRf#hxT(FOG2-EnN zZ|Kv#uf^sY3xu$94ij`?KS?P> zsh)Y)NhTFs;!BedVD9$dl5&rKSoE&)xI!UdbD-~}XygMPo3B1Q7_~B4D<=6FDjWh# zEJ=ffIm3B;2DQUZhf30&heeQt28S$Rf;CvEMla(MS2j*u+d2iKoZvG{>6X>Dim8#JOv?}4=923@D#17dr%g*wB> z8g!+8y+PMS<(_}`X3+I&rLghvNLIzMC0v89U)mDg47%=q!Zqk>QD=HF=o+z9fpYE0 zL1@2ay1P?nuDRMph&Gt@6ldv!nv3sM_47nqSSD+3guGTl&bU(Oi%+SeqkJt$2Qa$m z5lbO`%gSiRLR)%8JaA)-cm^ z7Z`T-=TUU(ED zzsMEy<%w|>fC%Pwi23E}m^QGEv}Xkb!lcPT&Wtp0biWca0U;*(-@!v#81~{x z3^;2>yTq}m0PSv1`RHhLp6HGPUmc9~Naa3y@-x`kKNaH=9$Nd9&Zt`RC9cA)YPBPKaGXZ>eBLHR{^VJMU6w={gqjmfZQL z%?E{XFM6&wg;6aeuRv8Zlw;PJSz!38!<9Xt_H)nGA4t3RP4v$ReHt z3pUQYfX0A&`xGo&&%{O2x#YMkr6d4s<%FgT6T~g{B+NO|Nf^D=u1Sj6%x6abQN?Cg zBR1n6Z;U>w(!&1PV~2?V1Z$H=;?AgCnF9qC&l2JRuz$r6b2&#ycMh9F5jiE_bwhxZ zge(4ZHhAgITu$t!UduSjl6Ft_)%5%E-fo7&CsH+Z$B;5(K1kv68)kZzz$(?VkwYV= z2=y5`!M(Cf-M0XTqK@(5B5AqOU{Z1MTZjeI06F1p$7F z5I|41y{0}PkVqOhZ}|zwMBj>GWu_>#pJk!#b-}cii|DQCnQ(N^b;l0Hy)io!qzmTv ze}?OGMhz9?gPKiK{f{@UGmpP)4>v(0D``uh3A$D^U~-hWW1%z!$%3%%p^hXiSvFn< znJtzrW5qT2gL7G*VdhvmCz3A>Zor}J=Rn^zKEs;?&X4`>1`{T)u9etUs})Wba7=V| zu_?M3I!S?EHdLzZOoUP)aqlpf%s3nfl=2xQ71N_v zpJyaa{Q~N8>KE$oBK>_zez|^1uPt`!pVve|9ZtO{4NM>8)Z7!*AkXWj6Xl?9Y`&aE zN~`4{Y?K5!Gfe#n5Wj(JIQiV5Q#Y3+j5ENpJsX~o=WWjD>E=0H95HgZ^Bg@-6WyN2 zs};Fu^A?Po@2Zm??}xtn1!7?;UV8CTuTOlL^aWS+}Ylbt*=Zwl! zd`T-zwz|NGSKD8xF1A z`netL#PZlYfp7B!^TG~_%~Rl>eSl3~D{BX~h^Qab56fBbiJ-xxSVicOI4Dx{aq5MN zyMDDFxCJIOHuVFo*e|7_ajEI}`m5`ywzT{Ff-!~eo~l>;X`#}{mEJVBURH{5(re>S z+Qz|Hy{sL>&Z6%!%UEZJS!Vjz6zE_OX|2(+(6y;^P7}~KwnvArlD3I0U$=FdpIoOw zm~cw(&`fSnLIbmqI+@8at?lNdXYGoql{^3&O$_^3hyXk6K0L)99*>mFh70xAd`0i@ z4!&-tzq*abg8pxE+Hpw;brxKg6V7srhZT(3XYI&sjS7y|3heJh_)tacLuH{hi8VKO zwy*>o%ZxL@IIh)9X#aui9TEzQv#WDSg^+Tuo0xaqw2ZY}bmq3dd+0%qG(?KA=u$cX ztvi=fOWzlCd1nyv1s&>W9|Yt5GxFA|q0jvjVs*XiBuM5MH@c9IPVq!Hs;5-(G?xpE*-)FpL7SAPIo#68QPV50j5#56Lf!|_#ts~# z+~SGRM(zh1ohfs21u?=}PmD#q3Ee>tlCv!@0$M^%0MpPZrr~{Y*YHStfiAgjsub#G z`I|(Ish4fXCb;hl5Ph^!I;m?tBo@^#JH>zs12l)no~G+a_D+=dqM+s(;3hVdqY)xF@t^xR_owS6-$D}A;GqpO00gG zdS{bqhuY`6~>*PxH>0on3vO!g6xC%W(fuXI5= zY8L$f`V8Z7^*#jz`wGf@Qw<4dT3QvmLZ2>JwyC{Xq%%0`9@&w_YpzI|L)_unc7(J! zGXpH5cBvQM#i*&9Q@zYwKS||16RpYW@208A>b2}B;+?dcDb+UEL;)Iu)OaUcOUT#O zJ6K3G4Jayvs*7DS%xt}%x(Qf^a^U0;r@L6Xiqha{USLzq3#ZdHC3@5bm_UZJ8<_^o z6@V>?%{w%|zjkxG(xi!ldA8tN)M?jSf*~G8{#y&yVaf=dAh+6iWub;9g5>iW8 z36TA;T^ehC7erk&^x;af2z?9EXP{pOHc{_?`qAr=P>*D z1Qoy^E9OWdvQ3igt;f@_k_pd!a(KfHjV)HHW!_q<6CE@U-NEz*e8TKCJSDsqrfJMw zdBJkQis6T>&?0EgY))V`x1+2qRG!)>@Ka(jUf}^ksc!(5GEgU4q~{4ZhN0G=LZ4 zjPXdkOeY-*Z*(RUo)t$_6gBJ-2IuxuWy>W%!e70TqspF~zm_M9=Ai_`w+SV95osxB z#LiDtI5^rCPx-Kh4_v{hLzU<&_cA#ep+gC|l#EZ1QC~%3h4-JodM5{VMUR{FzVTPz z&8%qJ8adA8;|~)lztofre@!2HWScK9?+V1us4%3}979eEZxg>}0xW`lpC;(C+-H*4WOwR+j;`8B#WUiEN zH}ef=;Q&`s_q4}aa+XWl-PuxSO73&Wot$U}P;((%hXyuc)FVFRAoC`~Uo9lFS$Gcj zDeEO9N;Ai58>la6LVuyrTDt}8ZPpf8mhjb__q2yd+iqnyYJH+&6(f-0Qf{%1^P}*c zQDQQMry+v!mP}$Rs_Zh-UKF$(0Ab$)M6s4sL0TtRB~|Ep`lgB_??X7dJZP!PlsaHa zenIzBBIEtyHs!OqGUId{)(D4$K`?;BHe->ug3GZkoIr&C*6ZCSfpZZA$m(8cSNEj{ zsEvzO;1lx-KS5Gv>7q?|D6Wus;nEJ=d+Zd&Tuu4p`y3c@eJ5@H2@g8K1-IqL3v|PW z_nHjwGG_(%A9AvE2Vl=!*$$sf<17?0{pZWQOl@{<&4ytzNIg^DVa8jZM6f>PBt1t= zkDr3~D+V`QGJ;M12#MJC1K~T(Y2wbu2`8qJ$Q;e~sA}%T(F#8jX5WzBK&W`PL2X^6u5E9Gj?QF9t5cY2U+>*F&K--6Q74liUS%Of0C_}0!D2Ab?%Z&@ zGdd(UQV^TKErq&QN?~Y|DH8WS5VbZ{r!}jdC z2TM0MvNJETz4Z(l$E3hxx(Khw&E-JZ=Khlwha7_kxo?B-(bNCEx_!K(@=JhkJ zZCN%~AS-vvB)lSV%WeoU-i)nIhI3sek!HKk^n;X3ET=cq_erq?hn!f>aVhzv11#sY zlQFNc1kQKt_t*nv~J)xwh7p2mgXfrBu8+!i&h+lgm z)3l4@u?(fT8P`BnN#^iZl(tywd7e^mWFNft1%KbhDnfy0!SrA@&ehwps;gu;(&V(% zCT;S!P@U1|q>R`p@JpTxk5JtEbR_TV=yURsMcplc`g`z|_|0J^Ay1d@6PuvO35mEl z*-e3+fC^5CdOvt8zM(s@nc0yRyMKJFvYFevo1ya#34i7>V8t_HCCwT5YjVjcrU4n_ zxZGriw3m?hBieV8lQv2kMUWt#cRQfOCt?6{iSDI-< zK93K{xU7f2W_@SkbtJm|;PBJa`d4MA1u@!dc3+k&~0m<(azqb0vz*JdF``QKp3MI=n}aoulZr&X$~FLSO8mbZnI}kK4>3 zWGhH9yK;#vM$DC&F*!ZxzpjhOq`TKOYo>YmaXnggn>%ijd6J%CJR&$hSZ2-ylkq10 z)!Y6e?5lhhrzxes6Ygk4w%4|H|BdmN>{dDf&gJ%-sZdKu;K#JCZ4>XKI;CG-7z(F2 z+#=h~ey7*hrOtrmq1{!&`EmsU1kYV^2!Es<$AI6Ji7~|sXgn=yh?Dyln5Idw>DgX& z^rVYikSHham52yrXk7(M!f`EOR-%nl*zuu8D62GZP^}gYo z;NUz5)$MfPI`{G_j6y+qxuOM9)%@5j#EE#{WZjq~F3Pf6hvH*nnabi^QGDs1nftju zEeMnG%I zf>`BlD=d_T&9BJb)tMTx_uq&i-D4?UpMm5W54HMiSzyHVNNHkSE6cyd)n%Y4Nux4a;8LXXwhZj0B$ zsGjy1M5|2H9)8~?p4-dA{ngowsA4!l5&?D78-E&i!lGDYi-ZSUpXFYaNoWSQI9Db? z#6C-tc&7_4wYbIIPKaN$vOOihY%g~t?9#H?C9h#nlvZ}5B6IG;1TH&eD#V2-h%5|e zMoV7Hv}6lL52|?%31lQreL(D6ra~mN{^|`f3D*saKDdt;ESMNW73*gOvhL@3#UXdf zqKvDuUO=|}ZpRB1M*~Xv1c%Ty>_QN4h8}KxNE*A?titI1@Xf5O6jnCOQeaDHh))={ zd-u5)q*B$3gsPsfsNC(5x^h&?Kw5;!?H)SvMp0VL`;`)xmb4t&S4hiT(KtriMx-DE z35hu+OH5z0osu1;LAeEJ$`-R}C55l^vCZ=OxnD#Z`&JCd+xWswEL-6_Gkdu2;v1Cr zb_MbPER4}%dVpa*nA0BbL_qEoPBz(3_v5Bp&6YCte2-6`XnxIK+~229)GhMd@7W@R z?}zIn^kL=hypoP+V~-ay*2>0E;IlCgb$gh8{}Bd}`$4wHBD>ujF`5r1Kp%oeKr6AS zw+rN#Y(WZ)$zfhPq&DH)PU<65ktMzY_!{qDrA7$}7U8Ud>AB${#xMO-f<9wiBokUk z@M$+nC&A8~Aw_b{ZqX4cuaL10^gEsGWhtZ@eOMCTiEdf56A|@rcHm~jfg<&Mv6}2@2^rvNTQI=dfPI-7KT^x?zMeb{3_*5t zf||%`6X|9RAEPRIOXCu+QS3AH9PPoTTB(zb1I69WrsK~(5VABPCap4uRt5vY@2lKK zP3hm_@pTn58@?+HO72nY{=JUg3{9A-r)L1D=HGb3A{3}LzX-~mfz?P(M1Szbb|xiI zT`+N9WW1{q!B|O^?%Xz7Or4{q8mUKm<*GdaMZ$v;<34*c)o6o^zTccFF1CaEx*_1E z@3$psF^s8JRSatHN8{S#Rh4cUj1X6cH|>qLD49xV+$qf>I3e~rfp57G&Kjzh#Y*Oy zyx3kb!0%!HSsDy3+a$2WSzShbE|b^<0U@*67yROJk4?`CO}7G(0m_( z5>bTFr!*(Gkv9Q>s-QTccAo&bN~T#c#W=c=AyKhiuB+~J(Uisru3jabltDhqOqWV` z(rHWne!&Rbl4|)D;hQ-%%gQ~h0sH~;>Zg34U&Rzxq?>0!N!I?cBI5|~C*o+33R@}3 zC|{!lUa=T)hA)af0+}~l%%ZxU@z02I%@z^g%4qY!Xk#Wm4}-ARY!!E;lX*(=)F)|` z$7_{+waUzjOkyM9Z*k)1akZ7B6B1EiI+)z$>C3RO)^g276-A3H`AVw;5Y z_C(5xA;M?y^=gRPk;hr~Fmf@|xJ(#hJR7?q2NM`m#+U*IME?DSExsqasqcvhbPl`!OSs zm9`NAZRTVSnr-<3by20@0e{UTUMh}>56nUmb0@Uo9K!q%D>NlRcq*^qIl`QX;q`h+ zEA~Y@`r{+sk?XI;1RIg(kRKft?Kl(P|Bj*lnx!NqI+&0k3o$x}boQnp)Qqh*K?|uw zIoVUP)(i(PScK;~(zJPelNENz5$W}5Yfqtdf+h-r?AlFm_Jg_p`sul5D#gl^5ju$T z3QBI-i+h@k!SwN0AH!Tk%`yJ!KT%iI^b7YLL;M1NO(E%BX6I~4NS&P%Nbs8VB;x*R zku4-fo?uR8IFCq+x;DgMP#&n;>ZDeb!qS|%!H)XMWcieG3mHq$WRS%>8q#O4wQQ6$ zE&7X=-rdRpnc4KOD-*WWh;b92u4QqC@Ys4G=rUm)@Z9h9+qo%83rJGSb7^Op_M(y` z_CGQp1pCah8Rw4e_zhv4E#VdQF2SmrZ!J-kA z!2)cX<>P}QL|V&JY>BKl_9cBv%S?YzN^5UOBmWpS>6&GHNeh>ln`^wCo^x&D)MqoR zFu~l+(0D7Dn|Ea24&|I8`%2jlxk<)p`or^g<~b=+V50pkjq_g|-X z#rP>_pe`?-98(YDpjkt*m@d`xH>Q-oFfn&w1{y1#A&-mogWY#Qvq0Xg*hX-;FBNCO z1b&+Yr>tEWoK+j?%B(Y3I|x0gd?eM0Tbh-l!k)T$YX>y_-2>od^IX!t)d$0^8oB3&uh@;vQGM>wb z|6uC^#~e{2buCw*rhwIZ0IMx9s(afik791WZGBYSq>@|o=pr#}XT zjhr2b8?ta2;8Zaie`_yusFIb?fuNztHr0L<5zQHwWkfP7&g0-cccL>or)l(Haqm!1 z{O7x^9H=2Pdc)w%P{UkI2cLXajLGylcEbQuE(#$PD0wF0#J8QHS;}HJWSUF(4BSr@ zhkX@c`0FQR`RfC|wSUR(xBW&K{j0#4Nha9KWEJ%ViZR2td)AiSm9c%+DrO2Crp|3| zgbqu}loH7Buxy*irnpwUx;)~CmMt^!5%=H}oFrmvE=27vM;AQ$)#xD_0=~CZpJ%#X zxa*R1)2RiMa>Ijzra6oCS3IH;Sv=RJJ0f*X(nB_Dnfa||6-3rOtA|8c-GqDAGZ3Gc z$@bcUWr0&GNZ-zpQ(LXivPYa+-By#=`##e>Goz{MCV8p(8MD%YNzYAzy& zGN^EMP0H1YK)#bh&Ht!Cxeq*aYGfJydgT<&Bl7OzgW{m zNXRC^-2U&+2{47X_YOD51Z17uMxZtpXFs~9X2iq2G=$<@%xY+cDQo^Zl#JdmNxHETUv zia4_sxNKxSjX_}+lONVmatII>Xue2Jf#!^47iivyuRwE$2POk%K+R8S^Hs2+JvU_EWA9`nDSuZ4a8m-%YX2z2~k^CeyAGGDT1Y&^m6F|MmU zR2JXPB4=D}1M?WzSg5^^^dr(}q4qy~Os8TdaYJKNO$&uvFNRxxQ!YPhQo}zW2R8kU zZ2i*!wVr0V_2dGb(qR`Uw2*HN`9EjR%{YXEG~PwAX~LjiKMRKtQJ&YxYdI{?8>UY_ zX_arnc&>-3Opj!^B@OB^d=Kp<&ugSnlKD3mLQ2@We)5R$zyHbT4Ai-kmyoz%C8OqBSo`3z+Mh&3wj&%fvZZA_bHs2=`=WD=JVG_0-Z!72h%$y%hM6JjU z;fx>nGW%6drG|!ogLxYo#ZHX5oYHd2NqVKmI8>kq+`23(vId<~OJj9XEuxKs<7kiT zed75a6^j!SaaoK*9|=%HxW+mG7!8B8{q&vgMHr;xuQxVZ)ENm|3iR(~*;v<+8kyXs7!Z%$uGG{n!)Ders!bZ~;hTITO$5l*bw6P`H(c^&u zYH{s@5>nj^qp7)(znMBR7wUDJ(#@uh4Lj*Al|ieEc?D2Y5B2UKYR` z$zQV@FlfzMvqk>&T+_&(a&y$rgcvJdxgPzM*+OukXXMEl#eD!s8Nl}LHVO4;iZ9~G zWYl6!M?}2G?zg%;C3XInRh&}FS!XSY?!-bg+H!pO+GtC9xR9U7_=*#lfJ-xF$Aw2X z)ycNzKcc3T6D#F4<}e8tkpIz_blbNQt%CT4e8g&#r={Jp*)96W#WJhO_yjApXoMRG z)!f-Xav#DUr6x7}(*bj7fW?^N+rO?yxctb&SziurnMcq!08Q;r&%@5UYq%q^bY~>T zVgEb8T_z#!lKlrA?q8R#pZXl>Q>K2xE4ON@_2sX0eXJ>l@w=;rCTPAyr_#F}B( zD$HF5id42#04wQ;$$ZHMjoQibR~L=nhy2!aB^<_45t1X?d^Yl1aP@m%b;Z>iVz`a< z%KeOa>q*R$U~KG6^Y*3ezO7B8!c`!|rcu^oYKzR2keMln{+x<*#lJ7^piM~8?feSH zPiybuF7K4;I{z6P{2oUx>4d@QqH-mZ+%lif!!L-Tnw8qv!SW=x!%F=Lv$?q?Z?L}%xuL-jiMW;!E%?po); zted%NJ>ZKyFy8GD!r2;^H~2o6Gjz9{q3$&^;DZOM7}{@sl;)X^VF%sF?LDws$ExgducJPH^-sxeg;g=0@Ct|MN6cEqOYHucWoCCh zlY~v<4m0-G37f_pLhPG^H>pME)dVDIEfkB+@I-6PDcv=@N|Ls^;gbs25yKG!#@BU2 zC6u5gTvtyU9Dr-3{sGjF`JdAHc%=*8H~YR&BE$Ub`xf(ejqVf3%74$ZjO1D%fAflFiJIwj%2KLMgJ|OSuzV=4%Xa2Q`v3=NryDAQmeINh~7FiTm)3!{ia9sc7hM&z0zR zXNaAp5G7&{U`_Hq<|)O{E?)7UPD4BMX@xM}&3gA;)fO7Z=uR!}++|y2Z4*ET{&i$1 z{_1&>3~uf;{NS7UDfQ6rt~PIS9cHSHnRyi)0bjD)+%-b8!>w9r?JwUD7HW6wx|!-; zbwd1nDsz@s(UzIXo{c^yk3`K8O}#l8q>bg5sKI`4A!@J__gZj&wL(ykZusMM!yj#G zh$w>pJ-0997SkVTN2c#Xz$Y>$gUSMSOiHM66Mn+NuBO@vE|C^D~kXKWU zjG}FqbTZDJR?fPYr|jSsNJIf_XF*fHuwpPcB#@7?aSCU$hSNWM$zuJ+sf&6##j!}o4$rx#RH-eT0u^67Kn8O-% zlp4Vso>50m>SCrCbp#B`i?4r5u`cEuz9X1(9P-RL4$&8}L^3``mtxKlG1i!MiVgeU`G~L1YrcQJl1Sh(qrsa(a z<*mzWf-rHnzxy>lvF{N$!W}gk>zcLYczEW6*D{X{#zqoyY6f>FR>tPkJ4ThiQc>{d?IJ)MyZgE+KF~yQ(8se{ww_= z6(4ql*)SbUA_{h)#N5%MWG{ydoqSkbNfK05cP*`YlIclvn{pkVeai&%x4S)+$+PD& zM;YIuUl)SC1R+C(2w8ffw!rE*Fd#m>+`Rfd*$Jv4Uv{4A3zTLlqD89_r>DgD-Ahzq zSwer!C$iZe@%3R}KjIq{DL3E$rRoC4BD=kf$JUEd)RliG+y^aQkdm~OB%~c^IXhLD zzatF+!?g!Qx?R)~rHKS6F5weFo4%LS|Kc;?zkf1*%~5l1_?oC07%qsKW5c>99M5(~<5 z5MTe?Qxd{C+%nVM8oq$o;(V?PSbTl}$H4Daxks z_@>c0XOs88(kEqSqffeSj_Q--S@cQ0;e%qu!?^4&(~K$TraWScie@V|Yi7BrepMt) z)s2y}1kkZVC$rtZIq{2|YOCmkY@(%A9ViA8+`yA+F%L2K!zQxc+jG}lZD={H6Z=2f0g1UAQ_jGdOGtJuU6 z`udoJ&qV*k;h7L_u~b1*_c`akpa{H!cfAIFzm@|8Q{XA>6_)^Gy{=^BPhaZs8Os|P zCwzOxaJV2sFPd9n*w#!OIx)?;BDTDUX%bPeND14_C_YJQqfO=JS4kc2r53^Ki=~oH zJu#8jrgCMeKbw1*524p zsI2AFvxx$T>nPC2rq0z=-uu#fzL>FhfR+H-EFhWWez8^SCHZ1a-e$f$OOvzAnUWB5 zH_FFm5`hkPb4adJq*Q-r_HI6C-0gPB@nns{t9+*JiN)>l)$&|seykrP{(3QqW#&Hn z?p1sqY0vC9cB(|~oxO#Mo(XX?yEA(`kD@=>!Cz-~v;OYU-<|r~roV0v+aPeH8F9y=`$np$m z9wAEyeJV5e#10d(xV18Rw!z54fG;w#++3B-G~tgZ$>B3lo~!G_ie|d+XrlE#BzQ}s z^gZ+$fVNs@&F*>g%v2bGgf!*kzab5iw#}b8u)1n4dI!1IR4y5NdykceS;Xreh}Fq1 z3Wk;xNuNLcT9B&DUNE#*Q~sbSjm%Ln^tq<2vU%uFFf>O~Ua=|6STIzlDL=KPG|y+6 zQe#sz&rD6Z-==6=|JIaSZ9Ur7!Q0nWsrUb86Cnd^Sf;vpGilb z<OZD72wk&itwVK^Hvv8rVt;3tE z$Yi`|TUY1DW3KG!a`SK-_E@2ImYDAD<^?k5F8-{pyFx(qeC+L15F`7q{>gY6=2lpR8B?IUyvG1ig# zgas`6Qh!raju)1KJs>^PP7>nMVpko66O}DyXVDy-qP=T3D^H_$?_Z_IFBdg$9bmh5 zrPsA~bBWirb4Y>Ik8VXIr$%2XC?WI#6`23=$_m}9DGaUMbPTdX`xiKl@<%AVQwmS; z3U44=NK&-$DzEUeZ!Nq_3g>u*9Vsj+T6mUM`2KGzy!u13mYEOr9yWjVb>y>ASFZL- z7LY=`lrq9sbszHVRe}Wt|3wC;0%{UXj&Y)rgJs)net^Luf9iT8tsC2J9%s%KaBgTf z4$t{Y?BL<8LrwjLVSwCl6xvu`zFIbMSv;jP`J190>HZ~a$AQH7W`2x?X*m+4 zZ^=Sm%q?WmG0@osFL4dgWyDk0!j51~o+VeMeO6NDUhkP{GwZeY3%13=i15i?B(>xF;X{xU{0l+mzo*LkyM$YeqJlmdc0LxP7~Y> z#bLghAe2g0L;QFSk}yf`E=>1t+ejYF9p&irSO1cVp@GyaH3ik6C&vO6fvmI}yh&lB z&GbJ7$8kDe?ZE}2xo0ZulS8+Tc*v^^I?vBZ_=!8oW{Pm;82ghO5go~udY}vB~ zI9I=j!_MePTbarFKG#%7h4=2DjI>y$+8jR86Kw-W9I2LNF(IPpYb(*3 zQion<{x#wNXR+XV&WZMLFK4+P=30#PVIBu@8KF(=YSB?*P>K_H8dAhVD&TTk13>Sz#02C9plH)KcLpP+CM1x5X!r$|dZZ{QU*Xh0^j@i`K)$ z%Dv;}T27Prav@x?zQw4<1L2=tjyci#EF>fC0>VA7N&(@!P6CAYFkl7YNxXS@Dk@w7 zHz7!E=AFMD!Xls@4Q2m|I38PKG_Uu;DUm31-JL)LGjnkgn*m|3z2kP?C9HL)$oC0( zO~UP0o+F;8TA-yA2?>uY#B z57bdW5?sp?;fM4%8Bb7~wZSB=4CUw#8SY%jHCS8< zbzUd4k>EJaJVwZm@Q=(!&LbX3#Md6dO3>)7`d&RUq+YZ zRw)-(D~O+(t@uQm^gv>(IR(cIF&kScP+l>>{2rVs)>4!flSmj;`kmh>|2L)Qe2FA+ zBt{q6&d4k^z2KhmOq*`jQF4+D5kVE<-I{tyZu3i0#bRbsI2qUb=OnS$29%l5!znVL zhD>HytwmJ$A~zsxbw}lVwf*Jv@DRM)%=kI#{PD1F)-`T1V#oN126NWc2XR1o*f;ZE zts~5 zDPu03P6)|fS4-!6fLaOiSH&clHwPk5tF7h{9glN~Gb7WP;d5qWC4%5B;tQsutDoZU zElsrx`GZ%kSh}jIGc z2+aUV7B3&2KJ*}4S@wPJaAOgcqb1l?s z1`fk+{OK#a(nm0I?4P z(62;HG=ynf$F}aTdMr^>^#;AJ3%w>;MvK&B)w@CvsC(=GFx_J5jp=8zSfd0mX2(6f zImI|WHb(g6zL%lxU%wjKtRq$1GBZ*k zQ6ohE*)o@IMBkdOnJ$U{R&vK;Gx;@>K>hJZmA0Pn3AUe_Y9vE26D`Kj99HPMSYR$Z zWVIQ6E{1wFAwD8OP8VdJQE}76pjU0AIsRK|h@9#*AnI;2Yur9bAb*-UNs9kge4}xV zi}bBHK0a`UOlZ6Nme{K~m2;x>s9z$TC>~{H(minqJ`KpXacVi#vMP?2v}CX$aWo%F*t_%pcJr&ul$J^o+7$T>XuNdNL z6Ka8SWOr!p&cOef5y;;!SR6BKn;g-r$5;$+l{@rS9R0-^ Fi89q)4RPk&Sy^U(% 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 *N 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%0A26JMKbjBO|aD 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�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 sX58zpJlSeT%O4F;oQAHXID;3&MGoBFYn0l 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

    ?AyHE+T^}b&}jgSiHCb}SIyYM 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

    ~j;QREEbICzr)7TkScflIV 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 oO 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�yL6Vc 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

    jwQA4(?5F0enor-5 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�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

    v}UaCB7d|%5Y@! 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%0A}-U?(YbqGR1|Kn-*77T>EDM3Pn&_s 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

    F7A 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

    _TSt}m? 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 z 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

  • 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�$J(R73PO7e<(Amn;)-aMn6oe zR&{8Py=;i^7A3QVa?xksVT@iqw`(40n<+(jtN2PC#?ryUERK z=y~q4_?1D`ln;1rcQ_n_6?=(r0Y_+?D@{ZFCCn@BS!A|cz+t0&cT3e2m!0Qbmr>$H zOy&xQT~1%0l#5*T1y_ACq&Le{NZo4W$uzDp^F@;-#qPl=dZu=DZs0JHS2JGm?-uGc ziK8G(eW=rfHd(6p9O^F8HV14Lh`mgxk9l@!ibm?ob&G4yY2W>gp8%~ZG`;f_=etJs ztL?px&#gNZ4%_6JIG2WI+U%$e&COm=C#xA#h1oXgE7CM3B)aCNd&j{h4wal)z1$fN zQN2w6c7QwWIIYt(+B>&n#yDiLJ^FWKT;flxp$d8Q`}`m1p1XG;syp{xp6MC;szeMo zPye{|7hRetU!y%YTry;YFTYhhR5#MY=IG&RtC)=%+C>kQ0ygt~B_x}X+oOWNv(IwC zTsndGo}z)DQ!%%2->xO+g+^2_X zUIR(eOY*2*;=6Smkw>(Tk-1{Czr;yMNE0pD-KPfko(5koJsp@PstUQFm(q#iB=0?EqY|sTntca&(xDD*Cu{mFNS9Ec4|Kk;5lW6&;y-lK#R=Z!EQ- zPSZCgI%g9^eMWwXQ$+6f`X$$>qfRd$p^7=ADvk8i^m0v_N8GSi>SV$Fh74+0&i50i zk#@}wduPTh%@0e{M}$!?P($u*598TTs&8n^`<`Z*Hlc1D>>E#uaGVz#}Z4JHJC8_{N<=AddRnaM$OdjcF6T2^!0+F0D zag>^FeRD}_nUikrxXc;q`8ArUoc6ZenGqU!x7i~$qn)3ezY(?3%vM+=wAoYGx&!6v zKS+R3suMj2PKAD>Sjv8|I+3eRia!~ZGADWV>jda z9+4>9KV9F8TRAM!(#53ZvffiKZsN>wS(Pe2hSyZk(UtUgS~KHUDrJhdasY-6!LO3MdL9M+UfMCP)HHQO1UOYm8r4UqP_nJq%p-Kk!xB8T{KM(RSHQ6W8l^C zrLk5a&tppHpycKqvqO367Cfb6yW~%McJ!1un=)IJI#cE>X_!ME?1^R1N^38+W{K-N z<21qjQSbu%C|Itnw6zO+VHvYc%{NJ9bS+U`r+@V5AWDmgy(GXKSyYe_ih7wOV1o`T zPb%PB)AyyE(i1axN*$z`x58t0r1#`D9fG+k=02-SDvcNNMk@U6ALxy5Hb;-aRPvbn zY;crt3?kA4Z_LS{a}-SZe?K5sbVicsfywyBWIP}@RDf&U(CPYYvZvwY6}FTQ^2{Vz{yhX`T#~tosQbmQL%6G+Ga{il1xsW}BZ{f^@zMe^6$LPZHeC9o>SJs` zm%#~lyxk$bsdBg%Y=5cK^MKu>V8TBc-q96r;R$`>lMSxWo-txWlio3e z#U=2dOXfB8=>ru~n@`~FPxj11HWV6s!9&!YR6e(UpHsfNko3SMxTuGE6Su^G+~L_j zHPgdzTroj`G7DX4fp6fiu@geY{X>3*KXa_jt{wS&w%agAtc;Z#$q9 z;ntA7l}np2Bf4Yzi-@$&f}~Ck|E-Sh^~^i{Bng{E1-++3%4-jC zS1&;ck$LO^xZng-Amlipg5&hB3vyF0^rXPvX#&OT*Z%+CfB6^q7t1JVC;$Ke literal 0 HcmV?d00001 diff --git a/trunk/Arduino/FloppyDriveController.sketch/V2.4/FloppyDriveController.sketch/FloppyDriveController.sketch.ino b/trunk/Arduino/FloppyDriveController.sketch/V2.4/FloppyDriveController.sketch/FloppyDriveController.sketch.ino new file mode 100644 index 00000000..c9de96c2 --- /dev/null +++ b/trunk/Arduino/FloppyDriveController.sketch/V2.4/FloppyDriveController.sketch/FloppyDriveController.sketch.ino @@ -0,0 +1,1083 @@ +/* ArduinoFloppyReader (and writer) +* +* Copyright (C) 2017-2020 Robert Smith (@RobSmithDev) +* https://amiga.robsmithdev.co.uk +* +* This sketch is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public +* License as published by the Free Software Foundation; either +* version 3 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 +* Library General Public License for more details. +* +* You should have received a copy of the GNU Library General Public +* License along with this sketch; if not, see http://www.gnu.org/licenses +*/ + +/* Latest History: + Firmware V1.4: Merged with Pull Request #6 (Modified the behavior of the current track location on Arduino boot - paulofduarte) which also addresses issues with some drives + Firmware V1.5: Merged with Pull Request #9 (Detect and read out HD floppy disks 1.44M by kollokollo) + Firmware V1.6: Added experimental unbuffered writing HD disk support + Firmware V1.7: Added suggestion from GitHub user "prickle" regarding the CHECK_SERIAL function which should reoslve issues with some of the USB to SERIAL converters +*/ + +///////////////////////////////////////////////////////////////////////////////////////////////////// +// This sketch manages the interface between the floppy drive and the computer as well as the // +// low-level disk reading and writing. For more information and how to connect your Arduino // +// to a floppy drive and computer visit https://amiga.robsmithdev.co.uk // +///////////////////////////////////////////////////////////////////////////////////////////////// +// This code doesnt actually do any decoding, and is mearly reading pulses, so can be used to // +// Read data from other disk formats too. // +////////////////////////////////////////////////////////////////////////////////////////////// + +#define BAUDRATE 2000000 // The baudrate that we want to communicate over (2M) +#define BAUD_PRESCALLER_NORMAL_MODE (((F_CPU / (BAUDRATE * 16UL))) - 1) +#define BAUD_PRESCALLER_DOUBLESPEED_MODE (((F_CPU / (BAUDRATE * 8UL))) - 1) +#define UART_USE_DOUBLESPEED_MODE // We're using double speed mode + +#define MOTOR_TRACK_DECREASE HIGH // Motor directions for PIN settings +#define MOTOR_TRACK_INCREASE LOW + +// PIN 2 - INDEX PULSE PIN - used to detect a specific point on the track for sync. Not used by standard Amiga disks but some copy protection uses it. +#define PIN_INDEX_DETECTED 2 // Pin used to detect the index pulse +#define PIN_INDEX_PORT PIND +#define PIN_INDEX_MASK B00000100 + +// PIN 3 - WRITE DATA +#define PIN_WRITE_DATA 3 // Raw triggering of writing data to the disk +#define PIN_WRITE_DATA_PORT PORTD // The actual port the above pin is on +#define PIN_WRITE_DATA_MASK B00001000 // The mask used to set this pin high or low + +// PIN 4 - READ DATA +#define PIN_READ_DATA 4 // Reads RAW floppy data on this pin +#define PIN_READ_DATA_MASK B00010000 // The mask for the port +#define PIN_READ_DATA_PORT PIND // The port the above pin is on + +// PIN 5, 6 and 7 - DRIVE, HEAD MOTOR DIRECTION and CONTROL +#define PIN_DRIVE_ENABLE_MOTOR 5 // Turn on and off the motor on the drive +#define PIN_MOTOR_DIR 6 // Stepper motor output to choose the direction the head should move +#define PIN_MOTOR_STEP 7 // Stepper motor step line to move the head position + +// PIN 8 - Used to detect track 0 while moving the head +#define PIN_DETECT_TRACK_0 8 // Used to see if the drive is at track 0 + +// PIN 9 - HEAD SELECTION +#define PIN_HEAD_SELECT 9 // Choose upper and lower head on the drive + + +// PIN A0 - WRITE GATE (Floppy Write Enable) +#define PIN_WRITE_GATE A0 // This pin enables writing to the disk +#define PIN_WRITE_GATE_PORT PORTC // The actual port the above pin is on +#define PIN_WRITE_GATE_MASK B00000001 // The port pin mask for the gate + +// PIN A1 - CHECK WRITE PROTECTION +#define PIN_WRITE_PROTECTED A1 // To check if the disk is write protected + +// PIN A2 - CTS Pin from UART +#define PIN_CTS A2 // Pin linked to the CTS pin +#define PIN_CTS_PORT PORTC // Port the CTS pin is on +#define PIN_CTS_MASK B00000100 // Binary mask to control it with + +// PIN 13 - Activity LED +#define PIN_ACTIVITY_LED 13 // Standard LED on Arduinos. We're just using this as a read/write status flag + + + + +// Paula on the Amiga used to find the SYNC WORDS and then read 0x1900 further WORDS. +// A dos track is 11968 bytes in size, theritical revolution is 12800 bytes. +/* The ATARI ST could format a track with up to 11 Sectors, so the AMIGA settings are OK. */ +#define RAW_TRACKDATA_LENGTH (0x1900*2+0x440) // Paula assumed it was 12868 bytes, so we read that, plus the size of a sector, to find overlap + +/* For the HD (1.4 MBytes) Disks the amount of data should be about 26688: */ +#define RAW_HD_TRACKDATA_LENGTH (0x1900*2*2+0x440) + +// The current track that the head is over. Starts with -1 to identify an unknown head position. +int currentTrack = -1; + +// If the drive has been switched on or not +bool driveEnabled = 0; + +// If we're in WRITING mode or not +bool inWriteMode = 0; + +/* Where there should be a HD Disk been read (1) or a DD and SD Disk (0).*/ +bool disktypeHD = 0; + + + + +// Because we turned off interrupts delay() doesnt work! +void smalldelay(unsigned long delayTime) { + delayTime*=(F_CPU/(9*1000L)); + + for (unsigned long loops=0; loops>8); + UBRR0L = (uint8_t)(BAUD_PRESCALLER_DOUBLESPEED_MODE); + UCSR0A |= 1<>8); + UBRR0L = (uint8_t)(BAUD_PRESCALLER_NORMAL_MODE); + UCSR0A &= ~(1<170) { + return false; + } + } + + currentTrack = 0; // Reset the track number + return true; +} + +// Goto to a specific track. During testing it was easier for the track number to be supplied as two ASCII characters, so I left it like this +bool gotoTrackX() { + // Read the bytes + byte track1 = readByteFromUART(); + byte track2 = readByteFromUART(); + + // Validate + if ((track1<'0') || (track1>'9')) return false; + if ((track2<'0') || (track2>'9')) return false; + + // Calculate target track and validate + int track = ((track1-'0')*10) + (track2-'0'); + if (track<0) return false; + if (track>81) return false; // yes amiga could read track 81! + + // Exit if its already been reached + if (track == currentTrack) return true; + + // If current track is unknown go to track 0 first + if (currentTrack == -1) goToTrack0(); + + // And step the head until we reach this track number + if (currentTrack < track) { + digitalWrite(PIN_MOTOR_DIR,MOTOR_TRACK_INCREASE); // Move OUT + while (currentTrack < track) { + stepDirectionHead(); + currentTrack++; + } + } else { + digitalWrite(PIN_MOTOR_DIR,MOTOR_TRACK_DECREASE); // Move IN + while (currentTrack > track) { + stepDirectionHead(); + currentTrack--; + } + } + + return true; +} + + +// 256 byte circular buffer - don't change this, we abuse the unsigned char to overflow back to zero! +#define SERIAL_BUFFER_SIZE 256 +#define SERIAL_BUFFER_START (SERIAL_BUFFER_SIZE-16) +unsigned char SERIAL_BUFFER[SERIAL_BUFFER_SIZE]; + + +#define CHECK_SERIAL() if (UCSR0A & ( 1 << RXC0 )) { \ + SERIAL_BUFFER[serialWritePos++] = UDR0; \ + serialBytesInUse++; \ + } \ + if (serialBytesInUse=240) {} + + // Now we write the data. Hopefully by the time we get back to the top everything is ready again + WRITE_BIT(0x10,B10000000); + CHECK_SERIAL(); + WRITE_BIT(0x30,B01000000); + CHECK_SERIAL(); + WRITE_BIT(0x50,B00100000); + CHECK_SERIAL(); + WRITE_BIT(0x70,B00010000); + CHECK_SERIAL(); + WRITE_BIT(0x90,B00001000); + CHECK_SERIAL(); + WRITE_BIT(0xB0,B00000100); + CHECK_SERIAL(); + WRITE_BIT(0xD0,B00000010); + CHECK_SERIAL(); + WRITE_BIT(0xF0,B00000001); + } + + // Turn off the write head + PIN_WRITE_GATE_PORT|=PIN_WRITE_GATE_MASK; + + // Done! + writeByteToUART('1'); + digitalWrite(PIN_ACTIVITY_LED,LOW); + + // Disable the 500khz signal + TCCR2B = 0; // No Clock (turn off) +} + + +// Write a track to disk from the UART - the data should be pre-MFM encoded raw track data where '1's are the pulses/phase reversals to trigger +// THIS CODE IS UNTESTED +void writeTrackFromUART_HD() { + // Configure timer 2 just as a counter in NORMAL mode + TCCR2A = 0 ; // No physical output port pins and normal operation + TCCR2B = bit(CS20); // Precale = 1 + + // Check if its write protected. You can only do this after the write gate has been pulled low + if (digitalRead(PIN_WRITE_PROTECTED) == LOW) { + writeByteToUART('N'); + digitalWrite(PIN_WRITE_GATE,HIGH); + return; + } else writeByteToUART('Y'); + + // Find out how many bytes they want to send + unsigned char highByte = readByteFromUART(); + unsigned char lowByte = readByteFromUART(); + unsigned char waitForIndex = readByteFromUART(); + PIN_CTS_PORT|=PIN_CTS_MASK; // stop any more data coming in! + + unsigned short numBytes = (((unsigned short)highByte)<<8) | lowByte; + + writeByteToUART('!'); + + register unsigned char currentByte; + + // Signal we're ready for another byte to come + PIN_CTS_PORT &= (~PIN_CTS_MASK); + + // Fill our buffer to give us a head start + for (int a=0; a=248) {} + + // Now we write the data. Hopefully by the time we get back to the top everything is ready again + WRITE_BIT(0x08,B10000000); + CHECK_SERIAL(); + WRITE_BIT(0x18,B01000000); + CHECK_SERIAL(); + WRITE_BIT(0x28,B00100000); + CHECK_SERIAL(); + WRITE_BIT(0x38,B00010000); + CHECK_SERIAL(); + WRITE_BIT(0x48,B00001000); + CHECK_SERIAL(); + WRITE_BIT(0x58,B00000100); + CHECK_SERIAL(); + WRITE_BIT(0x68,B00000010); + CHECK_SERIAL(); + WRITE_BIT(0x78,B00000001); + TCNT2=248; // a little cheating, but *should* work + } + + // Turn off the write head + PIN_WRITE_GATE_PORT|=PIN_WRITE_GATE_MASK; + + // Done! + writeByteToUART('1'); + digitalWrite(PIN_ACTIVITY_LED,LOW); + + // Disable the 500khz signal + TCCR2B = 0; // No Clock (turn off) +} + + + + + +// Write blank data to a disk so that no MFM track could be detected +void eraseTrack() { + // Configure timer 2 just as a counter in NORMAL mode + TCCR2A = 0 ; // No physical output port pins and normal operation + TCCR2B = bit(CS20); // Precale = 1 + + // Check if its write protected. You can only do this after the write gate has been pulled low + if (digitalRead(PIN_WRITE_PROTECTED) == LOW) { + writeByteToUART('N'); + digitalWrite(PIN_WRITE_GATE,HIGH); + return; + } else writeByteToUART('Y'); + + register unsigned char currentByte; + + digitalWrite(PIN_ACTIVITY_LED,HIGH); + + // Enable writing + PIN_WRITE_GATE_PORT&=~PIN_WRITE_GATE_MASK; + + // Reset the counter, ready for writing + TCNT2=0; + currentByte = 0xAA; + + // Write complete blank track - at 300rpm, 500kbps, a track takes approx 1/5 second to write. This is roughly 12500 bytes. Our RAW read is 13888 bytes, so we'll use that just to make sure we get every last bit. + for (register unsigned int counter=0; counter=240) {} + } + + // Turn off the write head + PIN_WRITE_GATE_PORT|=PIN_WRITE_GATE_MASK; + + // Done! + writeByteToUART('1'); + digitalWrite(PIN_ACTIVITY_LED,LOW); + + // Disable the 500khz signal + TCCR2B = 0; // No Clock (turn off) +} + + + +// Write blank data to a disk so that no MFM track could be detected +// THIS IS UNTESTED +void eraseTrack_HD() { + // Configure timer 2 just as a counter in NORMAL mode + TCCR2A = 0 ; // No physical output port pins and normal operation + TCCR2B = bit(CS20); // Precale = 1 + + // Check if its write protected. You can only do this after the write gate has been pulled low + if (digitalRead(PIN_WRITE_PROTECTED) == LOW) { + writeByteToUART('N'); + digitalWrite(PIN_WRITE_GATE,HIGH); + return; + } else writeByteToUART('Y'); + + register unsigned char currentByte; + + digitalWrite(PIN_ACTIVITY_LED,HIGH); + + // Enable writing + PIN_WRITE_GATE_PORT&=~PIN_WRITE_GATE_MASK; + + // Reset the counter, ready for writing + TCNT2=0; + currentByte = 0xAA; + + // Write complete blank track - at 300rpm, 500kbps, a track takes approx 1/5 second to write. This is roughly 12500 bytes. Our RAW read is 13888 bytes, so we'll use that just to make sure we get every last bit. + for (register unsigned int counter=0; counter=248) {} + } + + // Turn off the write head + PIN_WRITE_GATE_PORT|=PIN_WRITE_GATE_MASK; + + // Done! + writeByteToUART('1'); + digitalWrite(PIN_ACTIVITY_LED,LOW); + + // Disable the 500khz signal + TCCR2B = 0; // No Clock (turn off) +} + + +// Read the track using a timings to calculate which MFM sequence has been triggered +void readTrackDataFast() { + // Configure timer 2 just as a counter in NORMAL mode + TCCR2A = 0 ; // No physical output port pins and normal operation + TCCR2B = bit(CS20); // Precale = 1 + + // First wait for the serial port to be available + while(!(UCSR0A & (1<111) DataOutputByte|=B00000011,totalBits+=4; else DataOutputByte|=B00000010,totalBits+=3; + + // Wait until pin is high again + while (!(PIN_READ_DATA_PORT & PIN_READ_DATA_MASK)) {}; + } + UDR0 = DataOutputByte; + } + // Because of the above rules the actual valid two-bit sequences output are 01, 10 and 11, so we use 00 to say "END OF DATA" + writeByteToUART(0); + + // turn off the status LED + digitalWrite(PIN_ACTIVITY_LED,LOW); + + // Disable the counter + TCCR2B = 0; // No Clock (turn off) +} + +// Read the track for a HD disk +void readTrackDataFast_HD() { + // Configure timer 2 just as a counter in NORMAL mode + TCCR2A = 0 ; // No physical output port pins and normal operation + TCCR2B = bit(CS20); // Precale = 1 + + // First wait for the serial port to be available + while(!(UCSR0A & (1<55) DataOutputByte|=B00000011,totalBits+=4; else DataOutputByte|=B00000010,totalBits+=3; + + // Wait until pin is high again + while (!(PIN_READ_DATA_PORT & PIN_READ_DATA_MASK)) {}; + } + UDR0 = DataOutputByte; + } + // Because of the above rules the actual valid two-bit sequences output are 01, 10 and 11, so we use 00 to say "END OF DATA" + writeByteToUART(0); + + // turn off the status LED + digitalWrite(PIN_ACTIVITY_LED,LOW); + + // Disable the counter + TCCR2B = 0; // No Clock (turn off) +} + +static char *i2a(unsigned int i, char *a, unsigned r) { + if(i/r>0) a=i2a(i/r,a,r); + *a = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz@$!?"[i % r]; + return a+1; +} + +/* Make a statistics of the data seen on a track to determine the density of the media */ +void measureTrackData() { + /* for the statistics */ + int t1=0; + int t2=0; + int t3=0; + int t4=0; + int t5=0; + int t6=0; + // Configure timer 2 just as a counter in NORMAL mode + TCCR2A = 0 ; // No physical output port pins and normal operation + TCCR2B = bit(CS20); // Precale = 1 + + // Signal we're active + digitalWrite(PIN_ACTIVITY_LED,HIGH); + + // Force data to be stored in a register + register unsigned char DataOutputByte = 0; + + // While the INDEX pin is high wait + while (PIN_INDEX_PORT & PIN_INDEX_MASK) {}; + + // Prepare the two counter values as follows: + TCNT2=0; // Reset the counter + + register unsigned char counter; + long totalBits=0; + long target = ((long)RAW_TRACKDATA_LENGTH/4)*(long)8; + + while (totalBits" Write track to the drive + case '>': if (!driveEnabled) writeByteToUART('0'); else + if (!inWriteMode) writeByteToUART('0'); else { + writeByteToUART('1'); + if(disktypeHD) + writeTrackFromUART_HD(); + else + writeTrackFromUART(); + } + break; + + // Command "X" Erase current track (writes 0xAA to it) + case 'X': if (!driveEnabled) writeByteToUART('0'); else + if (!inWriteMode) writeByteToUART('0'); else { + writeByteToUART('1'); + if (disktypeHD) + eraseTrack_HD(); + else + eraseTrack(); + } + break; + + // Command "H" Set HD disk type + case 'H': + disktypeHD = 1; + writeByteToUART('1'); + break; + + // Command "D" Set DD or SD disk type + case 'D': + disktypeHD = 0; + writeByteToUART('1'); + break; + + // Command "M" measure data timings + case 'M': if(!driveEnabled) writeByteToUART('0'); + else { + writeByteToUART('1'); + measureTrackData(); + } + break; + + // Turn off the drive motor + case '-': digitalWrite(PIN_DRIVE_ENABLE_MOTOR,HIGH); + digitalWrite(PIN_WRITE_GATE,HIGH); + driveEnabled = 0; + writeByteToUART('1'); + inWriteMode = 0; + break; + + // Turn on the drive motor and setup in READ MODE + case '+': if (inWriteMode) { + // Ensure writing is turned off + digitalWrite(PIN_DRIVE_ENABLE_MOTOR,HIGH); + digitalWrite(PIN_WRITE_GATE,HIGH); + smalldelay(100); + driveEnabled = 0; + inWriteMode = 0; + } + + if (!driveEnabled) { + digitalWrite(PIN_DRIVE_ENABLE_MOTOR,LOW); + driveEnabled = 1; + smalldelay(750); // wait for drive + } + writeByteToUART('1'); + break; + + // Turn on the drive motor and setup in WRITE MODE + case '~': if (driveEnabled) { + digitalWrite(PIN_WRITE_GATE,HIGH); + digitalWrite(PIN_DRIVE_ENABLE_MOTOR,HIGH); + driveEnabled = 0; + smalldelay(100); + } + // We're writing! + digitalWrite(PIN_WRITE_GATE,LOW); + // Gate has to be pulled LOW BEFORE we turn the drive on + digitalWrite(PIN_DRIVE_ENABLE_MOTOR,LOW); + // Raise the write gate again + digitalWrite(PIN_WRITE_GATE,HIGH); + smalldelay(750); // wait for drive + + // At this point we can see the status of the write protect flag + if (digitalRead(PIN_WRITE_PROTECTED) == LOW) { + writeByteToUART('0'); + inWriteMode = 0; + digitalWrite(PIN_DRIVE_ENABLE_MOTOR,HIGH); + //digitalWrite(PIN_WRITE_GATE,HIGH); + } else { + inWriteMode = 1; + driveEnabled = 1; + writeByteToUART('1'); + } + break; + + case '&': runDiagnostic(); + break; + + + // We don't recognise the command! + default: + writeByteToUART('!'); // error + break; + } +} diff --git a/trunk/Arduino/FloppyDriveController.sketch/V2.4/FloppyDriveController.sketch/LICENSE.txt b/trunk/Arduino/FloppyDriveController.sketch/V2.4/FloppyDriveController.sketch/LICENSE.txt new file mode 100644 index 00000000..3d90694a --- /dev/null +++ b/trunk/Arduino/FloppyDriveController.sketch/V2.4/FloppyDriveController.sketch/LICENSE.txt @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + 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. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + 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 +. \ No newline at end of file diff --git a/trunk/Arduino/FloppyDriveController.sketch/V2.4/LICENSE.txt b/trunk/Arduino/FloppyDriveController.sketch/V2.4/LICENSE.txt new file mode 100644 index 00000000..3d90694a --- /dev/null +++ b/trunk/Arduino/FloppyDriveController.sketch/V2.4/LICENSE.txt @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + 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. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + 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 +. \ No newline at end of file diff --git a/trunk/Arduino/FloppyDriveController.sketch/V2.4/Mingos Commodorepage.desktop b/trunk/Arduino/FloppyDriveController.sketch/V2.4/Mingos Commodorepage.desktop new file mode 100644 index 00000000..14012633 --- /dev/null +++ b/trunk/Arduino/FloppyDriveController.sketch/V2.4/Mingos Commodorepage.desktop @@ -0,0 +1,7 @@ +[Desktop Entry] +Version=1.0 +Type=Link +Name=Mingos Commodorepage +Comment= +Icon=user-bookmarks +URL=https://mingos-commodorepage.com/tutorials/amardAmFlopReader.php?title=Amiga-Disketten%20lesen%20und%20beschreiben%20mit%20Amiga%20Floppy%20Disk%20Reader diff --git a/trunk/Arduino/FloppyDriveController.sketch/V2.4/encryptable b/trunk/Arduino/FloppyDriveController.sketch/V2.4/encryptable new file mode 100644 index 00000000..e69de29b diff --git a/trunk/Arduino/FloppyDriveController.sketch/V2.4/readme.txt b/trunk/Arduino/FloppyDriveController.sketch/V2.4/readme.txt new file mode 100644 index 00000000..50546e33 --- /dev/null +++ b/trunk/Arduino/FloppyDriveController.sketch/V2.4/readme.txt @@ -0,0 +1,80 @@ +# Arduino Powered Floppy Disk Reader and Writer +Created by Robert Smith @RobSmithDev +...with interfaces for Amiga, ATARI ST and DOS/PC Disk formats + +# What is it? +This project uses an Arduino to interface with a floppy disk drive and +communicate with a PC in order to recover the data from any formatted +disks. + +The drive can be either a 8", 5 1/4" or 3 1/2" standard floppy drive. +It was tested on a 3 1/2" standard PC floppy drive. Others (like the +5 1/4" standard PC floppy drive) my also work without modifications. + +This configration can read SD, DD and HD floppy disk formats +(AMIGA, ATARI ST, PC DOS, COMMODORE C64) +and maybe more. + +The Arduino firmware allows to read the raw data from each track of the +floppy. Decoding of the sector data is done on the PC. Usually a floppy image +file is created (ADF for AMIGA, .img for ATARI ST and PC/DOS). + +It also allows you to write a backed up ADF file back onto a floppy disk! + +# ArduinoFloppyReader +This Visual Studio 2019 project contains two applications, a command line, +and a Windows dialog based application allow reading and writing of Amiga +formatted DD floppy disks. + +# Scripts for linux +The above application apparently works under WINE, however, +Github user "kollokollo" made some scripts for reading other formats on Linux +too as follows: + The ATARI ST and DOS/PC floppy formats can be decoded whith these scripts. + 9,10,11 or 18 Sectors per track. Up to 82 tracks, DD (ca. 800 kBytes) or + HD (1.4 MBytes). The images usually contain a FAT12 file system which can be + directly mounted by linuy without any additional driver. + For more information see + https://github.com/kollokollo/ArduinoFloppyDiskReader/tree/new/for_linux + They need the X11-Basic interpreter from http://x11-basic.sourceforge.net/ + +# Commodore 1581 Disks + To read commodore 1581 disks, check out the project at: + https://github.com/hpingel/pyAccess1581 + +# FloppyDriverController.sketch +This is the Ardunio source code/sketch for all Floppy formats. +* Detect disk density (SD/DD or HD) +* Motor ON/OFF +* Seek to Track 0 +* Seek to any track (up to 82 - be careful, this can damage some drives!) +* read write protection status +* Read index pulse +* read raw track data (its, RAW, so FM, MFM; SD, DD or HD) +* write track data (unbuffered, DD, untested HD) + +# AVR Firmware +If you want to use the AVR directly instead of within the Arduino environment, +then jump to [https://github.com/jtsiomb/usbamigafloppy] where John Tsiombikas +has ported the code. + +# Help and Instructions +For further details including how to wire this up please visit +[https://amiga.robsmithdev.co.uk] + +# Whats changed? +v2.4 Improved support for Usb to Serial devices based on findings from GitHub user "prickle" - firmware is now V1.7 +v2.33 Merged with Pull Request #9 (Detect and read out HD floppy disks 1.44M by kollokollo) - firmware is now V1.6 +v2.32 Merged with Pull Request #6 (Modified the behavior of the current track location on Arduino boot - paulofduarte) which also addresses issues with some drives and updated firmware to 1.4 + Made a small change to the diagnostics code to also erase the track before writing it +v2.31 Upgraded the PC code side to work with Visual Studio 2019 resolving issue #11 (ourIThome) and merging pull request #13 (bassclefstudio) + Fixed a few typos in ArduinoInterface.cpp from pull request #12 (Crkk) +V2.2 Fixed 99% of checksum errors when writing by erasing the track first +V2.1 Diagnostics and potential write bug fixed +V2.0 Disk reading has been vastly improved and you can now also write disks! +V1.0 Initial release, can read disks fairly well + +# Licence +This entire project is available under the GNU General Public License v3 +licence. See licence.txt for more details. + diff --git a/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/.github/FUNDING.yml b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/.github/FUNDING.yml new file mode 100644 index 00000000..1e54bf18 --- /dev/null +++ b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/.github/FUNDING.yml @@ -0,0 +1 @@ +custom: ["https://paypal.me/RobSmithDev"] \ No newline at end of file diff --git a/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/.gitattributes b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/.gitattributes new file mode 100644 index 00000000..1ff0c423 --- /dev/null +++ b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/.gitattributes @@ -0,0 +1,63 @@ +############################################################################### +# Set default behavior to automatically normalize line endings. +############################################################################### +* text=auto + +############################################################################### +# Set default behavior for command prompt diff. +# +# This is need for earlier builds of msysgit that does not have it on by +# default for csharp files. +# Note: This is only used by command line +############################################################################### +#*.cs diff=csharp + +############################################################################### +# Set the merge driver for project and solution files +# +# Merging from the command prompt will add diff markers to the files if there +# are conflicts (Merging from VS is not affected by the settings below, in VS +# the diff markers are never inserted). Diff markers may cause the following +# file extensions to fail to load in VS. An alternative would be to treat +# these files as binary and thus will always conflict and require user +# intervention with every merge. To do so, just uncomment the entries below +############################################################################### +#*.sln merge=binary +#*.csproj merge=binary +#*.vbproj merge=binary +#*.vcxproj merge=binary +#*.vcproj merge=binary +#*.dbproj merge=binary +#*.fsproj merge=binary +#*.lsproj merge=binary +#*.wixproj merge=binary +#*.modelproj merge=binary +#*.sqlproj merge=binary +#*.wwaproj merge=binary + +############################################################################### +# behavior for image files +# +# image files are treated as binary by default. +############################################################################### +#*.jpg binary +#*.png binary +#*.gif binary + +############################################################################### +# diff behavior for common document formats +# +# Convert binary document formats to text before diffing them. This feature +# is only available from the command line. Turn it on by uncommenting the +# entries below. +############################################################################### +#*.doc diff=astextplain +#*.DOC diff=astextplain +#*.docx diff=astextplain +#*.DOCX diff=astextplain +#*.dot diff=astextplain +#*.DOT diff=astextplain +#*.pdf diff=astextplain +#*.PDF diff=astextplain +#*.rtf diff=astextplain +#*.RTF diff=astextplain diff --git a/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/.gitignore b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/.gitignore new file mode 100644 index 00000000..4ce6fdde --- /dev/null +++ b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/.gitignore @@ -0,0 +1,340 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- Backup*.rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# JetBrains Rider +.idea/ +*.sln.iml + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb \ No newline at end of file diff --git a/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReader.sln b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReader.sln new file mode 100644 index 00000000..dcf423a6 --- /dev/null +++ b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReader.sln @@ -0,0 +1,41 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30711.63 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ArduinoFloppyReader", "ArduinoFloppyReader\ArduinoFloppyReader.vcxproj", "{17585290-34DC-42A1-9747-37198CE4AD1A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ArduinoFloppyReaderWin", "ArduinoFloppyReaderWin\ArduinoFloppyReaderWin.vcxproj", "{37EEB775-8CC2-40F8-A3CD-40C955E11F0F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {17585290-34DC-42A1-9747-37198CE4AD1A}.Debug|x64.ActiveCfg = Debug|x64 + {17585290-34DC-42A1-9747-37198CE4AD1A}.Debug|x64.Build.0 = Debug|x64 + {17585290-34DC-42A1-9747-37198CE4AD1A}.Debug|x86.ActiveCfg = Debug|Win32 + {17585290-34DC-42A1-9747-37198CE4AD1A}.Debug|x86.Build.0 = Debug|Win32 + {17585290-34DC-42A1-9747-37198CE4AD1A}.Release|x64.ActiveCfg = Release|x64 + {17585290-34DC-42A1-9747-37198CE4AD1A}.Release|x64.Build.0 = Release|x64 + {17585290-34DC-42A1-9747-37198CE4AD1A}.Release|x86.ActiveCfg = Release|Win32 + {17585290-34DC-42A1-9747-37198CE4AD1A}.Release|x86.Build.0 = Release|Win32 + {37EEB775-8CC2-40F8-A3CD-40C955E11F0F}.Debug|x64.ActiveCfg = Debug|x64 + {37EEB775-8CC2-40F8-A3CD-40C955E11F0F}.Debug|x64.Build.0 = Debug|x64 + {37EEB775-8CC2-40F8-A3CD-40C955E11F0F}.Debug|x86.ActiveCfg = Debug|Win32 + {37EEB775-8CC2-40F8-A3CD-40C955E11F0F}.Debug|x86.Build.0 = Debug|Win32 + {37EEB775-8CC2-40F8-A3CD-40C955E11F0F}.Release|x64.ActiveCfg = Release|x64 + {37EEB775-8CC2-40F8-A3CD-40C955E11F0F}.Release|x64.Build.0 = Release|x64 + {37EEB775-8CC2-40F8-A3CD-40C955E11F0F}.Release|x86.ActiveCfg = Release|Win32 + {37EEB775-8CC2-40F8-A3CD-40C955E11F0F}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {5EB7CD8D-2E07-4E69-9F3B-EEFF510CF5E4} + EndGlobalSection +EndGlobal diff --git a/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReader/ArduinoFloppyReader.vcxproj b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReader/ArduinoFloppyReader.vcxproj new file mode 100644 index 00000000..627195d4 --- /dev/null +++ b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReader/ArduinoFloppyReader.vcxproj @@ -0,0 +1,185 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + {17585290-34DC-42A1-9747-37198CE4AD1A} + Win32Proj + ArduinoFloppyReader + 10.0.18362.0 + ArduinoFloppyReader + + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + $(SolutionPath)\..\lib;$(IncludePath) + + + true + $(SolutionPath)\..\lib;$(IncludePath) + + + false + $(SolutionPath)\..\lib;$(IncludePath) + + + false + $(SolutionPath)\..\lib;$(IncludePath) + + + + NotUsing + Level3 + Disabled + _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + false + + + Console + true + + + + + NotUsing + Level3 + Disabled + _DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + NotUsing + MaxSpeed + true + true + _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreaded + + + Console + true + true + true + + + + + Level3 + NotUsing + MaxSpeed + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + + + + + NotUsing + NotUsing + NotUsing + NotUsing + + + NotUsing + NotUsing + NotUsing + NotUsing + + + NotUsing + NotUsing + + + NotUsing + NotUsing + NotUsing + NotUsing + + + + + + + \ No newline at end of file diff --git a/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReader/ArduinoFloppyReader.vcxproj.filters b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReader/ArduinoFloppyReader.vcxproj.filters new file mode 100644 index 00000000..cc35ade0 --- /dev/null +++ b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReader/ArduinoFloppyReader.vcxproj.filters @@ -0,0 +1,51 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReader/ArduinoReaderWriter b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReader/ArduinoReaderWriter new file mode 100644 index 0000000000000000000000000000000000000000..6b5f9a3aa0b678e57cc1ff5bf5396afdf8d62c18 GIT binary patch literal 204320 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

    w{7FqyM8w7d*A~JSxLMmf?c%F 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

    |+!wD;z>c-e}4Z4fmv_eAcd60H+u50&Vo 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 literal 0 HcmV?d00001 diff --git a/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReader/Main.cpp b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReader/Main.cpp new file mode 100644 index 00000000..6765fe64 --- /dev/null +++ b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReader/Main.cpp @@ -0,0 +1,304 @@ +/* ArduinoFloppyReader (and writer) +* +* Copyright (C) 2017-2021 Robert Smith (@RobSmithDev) +* https://amiga.robsmithdev.co.uk +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU Library General Public +* License as published by the Free Software Foundation; either +* version 3 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 +* Library General Public License for more details. +* +* You should have received a copy of the GNU Library General Public +* License along with this program; if not see http://www.gnu.org/licenses/ +*/ + +//////////////////////////////////////////////////////////////////////////////////////////// +// Example console application for reading and writing floppy disks to and from ADF files // +//////////////////////////////////////////////////////////////////////////////////////////// + +#include "ADFWriter.h" +#include "ArduinoInterface.h" +#ifdef _WIN32 +#include +#else +#include +#include + +#ifndef _wcsupr +#include +void _wcsupr(wchar_t* str) { + while (*str) { + *str = towupper(*str); + str++; + } +} +#endif +static struct termios old, current; + +/* Initialize new terminal i/o settings */ +void initTermios(int echo) +{ + tcgetattr(0, &old); /* grab old terminal i/o settings */ + current = old; /* make new settings same as old settings */ + current.c_lflag &= ~ICANON; /* disable buffered i/o */ + if (echo) { + current.c_lflag |= ECHO; /* set echo mode */ + } else { + current.c_lflag &= ~ECHO; /* set no echo mode */ + } + tcsetattr(0, TCSANOW, ¤t); /* use these new terminal i/o settings now */ +} + +/* Restore old terminal i/o settings */ +void resetTermios(void) +{ + tcsetattr(0, TCSANOW, &old); +} + +char _getChar() +{ + char ch; + initTermios(0); + ch = getchar(); + resetTermios(); + return ch; +} + +std::wstring atw(const std::string& str) { + std::wstring ws(str.size(), L' '); + ws.resize(::mbstowcs((wchar_t*)ws.data(), str.c_str(), str.size())); + return ws; +} +#endif + +using namespace ArduinoFloppyReader; + +ADFWriter writer; + + +// Read an ADF file and write it to disk +void adf2Disk(const std::wstring& filename, bool verify) { + printf("\nWrite disk from ADF mode\n\n"); + if (!verify) printf("WARNING: It is STRONGLY recommended to write with verify support turned on.\r\n\r\n"); + + ADFResult result = writer.ADFToDisk(filename,verify,true, [](const int currentTrack, const DiskSurface currentSide, bool isVerifyError) ->WriteResponse { + if (isVerifyError) { + char input; + do { + printf("\rDisk write verify error on track %i, %s side. [R]etry, [S]kip, [A]bort? ", currentTrack, (currentSide == DiskSurface::dsUpper) ? "Upper" : "Lower"); +#ifdef _WIN32 + input = toupper(_getch()); +#else + input = toupper(_getChar()); +#endif + } while ((input != 'R') && (input != 'S') && (input != 'A')); + + switch (input) { + case 'R': return WriteResponse::wrRetry; + case 'I': return WriteResponse::wrSkipBadChecksums; + case 'A': return WriteResponse::wrAbort; + } + } + printf("\rWriting Track %i, %s side ", currentTrack, (currentSide == DiskSurface::dsUpper) ? "Upper" : "Lower"); +#ifndef _WIN32 + fflush(stdout); +#endif + return WriteResponse::wrContinue; + }); + + switch (result) { + case ADFResult::adfrComplete: printf("\rADF file written to disk "); break; + case ADFResult::adfrCompletedWithErrors: printf("\rADF file written to disk but there were errors during verification "); break; + case ADFResult::adfrAborted: printf("\rWriting ADF file to disk "); break; + case ADFResult::adfrFileError: printf("\rError opening ADF file. "); break; + case ADFResult::adfrDriveError: printf("\rError communicating with the Arduino interface. "); + printf("\n%s ", writer.getLastError().c_str()); break; + case ADFResult::adfrDiskWriteProtected: printf("\rError, disk is write protected! "); break; + default: printf("\rAn unknown error occured "); break; + } +} + +// Stolen from https://stackoverflow.com/questions/11635/case-insensitive-string-comparison-in-c +// A wide-string case insensative compare of strings +bool iequals(const std::wstring& a, const std::wstring& b) { + return std::equal(a.begin(), a.end(),b.begin(), b.end(),[](wchar_t a, wchar_t b) { + return tolower(a) == tolower(b); + }); +} +bool iequals(const std::string& a, const std::string& b) { + return std::equal(a.begin(), a.end(),b.begin(), b.end(),[](char a, char b) { + return tolower(a) == tolower(b); + }); +} + +// Read a disk and save it to ADF or SCP files +void disk2ADF(const std::wstring& filename) { + const wchar_t* extension = wcsrchr(filename.c_str(), L'.'); + bool isADF = true; + + if (extension) { + extension++; + isADF = !iequals(extension, L"SCP"); + } + + if (isADF) printf("\nCreate ADF from disk mode\n\n"); else printf("\nCreate SCP file from disk mode\n\n"); + + // Get the current firmware version. Only valid if openDevice is successful + const ArduinoFloppyReader::FirmwareVersion v = writer.getFirwareVersion(); + if ((v.major == 1) && (v.minor < 8)) { + if (!isADF) { + printf("This requires firmware V1.8 or newer.\n"); + return; + } + else { + // improved disk timings in 1.8, so make them aware + printf("Rob strongly recommends updating the firmware on your Arduino to at least V1.8.\n"); + printf("That version is even better at reading old disks.\n"); + } + } + + auto callback = [isADF](const int currentTrack, const DiskSurface currentSide, const int retryCounter, const int sectorsFound, const int badSectorsFound) ->WriteResponse { + if (retryCounter > 20) { + char input; + do { + printf("\rDisk has checksum errors/missing data. [R]etry, [I]gnore, [A]bort? "); +#ifdef _WIN32 + input = toupper(_getch()); +#else + input = toupper(_getChar()); +#endif + } while ((input != 'R') && (input != 'I') && (input != 'A')); + switch (input) { + case 'R': return WriteResponse::wrRetry; + case 'I': return WriteResponse::wrSkipBadChecksums; + case 'A': return WriteResponse::wrAbort; + } + } + if (isADF) { + printf("\rReading Track %i, %s side (retry: %i) - Got %i/11 sectors (%i bad found) ", currentTrack, (currentSide == DiskSurface::dsUpper) ? "Upper" : "Lower", retryCounter, sectorsFound, badSectorsFound); + } + else { + printf("\rReading Track %i, %s side ", currentTrack, (currentSide == DiskSurface::dsUpper) ? "Upper" : "Lower"); + } +#ifndef _WIN32 + fflush(stdout); +#endif + return WriteResponse::wrContinue; + }; + + ADFResult result; + + if (isADF) result = writer.DiskToADF(filename, 80, callback); else result = writer.DiskToSCP(filename, 80, 3, callback); + + switch (result) { + case ADFResult::adfrComplete: printf("\rFile created successfully. "); break; + case ADFResult::adfrAborted: printf("\rFile aborted. "); break; + case ADFResult::adfrFileError: printf("\rError creating file. "); break; + case ADFResult::adfrFileIOError: printf("\rError writing to file. "); break; + case ADFResult::adfrFirmwareTooOld: printf("\rThis requires firmware V1.8 or newer. "); break; + case ADFResult::adfrCompletedWithErrors: printf("\rFile created with partial success. "); break; + case ADFResult::adfrDriveError: printf("\rError communicating with the Arduino interface. "); + printf("\n%s ", writer.getLastError().c_str()); break; + default: printf("\rAn unknown error occured. "); break; + } +} + +// Run the diagnostics module +void runDiagnostics(const std::wstring& port) { + printf("\rRunning diagnostics on COM port: %ls\n",port.c_str()); + + writer.runDiagnostics(port, [](bool isError, const std::string message)->void { + if (isError) + printf("DIAGNOSTICS FAILED: %s\n",message.c_str()); + else + printf("%s\n", message.c_str()); + }, [](bool isQuestion, const std::string question)->bool { + if (isQuestion) + printf("%s [Y/N]: ", question.c_str()); + else + printf("%s [Enter/ESC]: ", question.c_str()); + + char c; + do { +#ifdef _WIN32 + c = toupper(_getch()); +#else + c = toupper(_getChar()); +#endif + } while ((c != 'Y') && (c != 'N') && (c != '\n') && (c != '\r') && (c != '\x1B')); + printf("%c\n", c); + + return (c == 'Y') || (c == '\n') || (c == '\r') || (c == '\x1B'); + }); + + writer.closeDevice(); +} + +#ifdef _WIN32 +int wmain(int argc, wchar_t* argv[], wchar_t *envp[]) +#else +int main(int argc, char* argv[], char *envp[]) +#endif +{ + printf("Arduino Amiga ADF & SCP Floppy Disk Reader/Writer V2.6, Copyright (C) 2017-2021 Robert Smith\r\n"); + printf("Full sourcecode and documentation at https://amiga.robsmithdev.co.uk\r\n"); + printf("This is free software licenced under the GNU General Public Licence V3\r\n\r\n"); + + if (argc < 3) { + printf("Usage:\r\n\n"); + printf("To read a disk to an ADF file:\r\n"); + printf("ArduinoFloppyReader OutputFilename.ADF [READ]\r\n\r\n"); + printf("To read a disk to an SCP file:\r\n"); + printf("ArduinoFloppyReader OutputFilename.SCP [READ]\r\n\r\n"); + printf("To write an ADF file to disk:\r\n"); + printf("ArduinoFloppyReader InputFilename.ADF WRITE [VERIFY]\r\n\r\n"); + printf("To start interface diagnostics:\r\n"); + printf("ArduinoFloppyReader DIAGNOSTIC\r\n\r\n"); + printf("Detected Serial Devices:\r\n"); + + std::vector portList; + ArduinoFloppyReader::ArduinoInterface::enumeratePorts(portList); + for (const std::wstring& port : portList) + printf(" %ls\n", port.c_str()); + printf("\r\n"); + + return 0; + } + +#ifdef _WIN32 + bool writeMode = (argc > 3) && (iequals(argv[3], L"WRITE")); + bool verify = (argc > 4) && (iequals(argv[4], L"VERIFY")); + if (argc >= 2) { + std::wstring port = argv[1]; + std::wstring filename = argv[2]; + int i = _wtoi(argv[1]); + if (i) port = L"COM" + std::to_wstring(i); else port = argv[1]; +#else + bool writeMode = (argc > 3) && (iequals(argv[3], "WRITE")); + bool verify = (argc > 4) && (iequals(argv[4], "VERIFY")); + if (argc >= 2) { + std::wstring port = atw(argv[1]); + std::wstring filename = atw(argv[2]); +#endif + if (iequals(filename, L"DIAGNOSTIC")) { + runDiagnostics(port); + } else + if (!writer.openDevice(port)) { + printf("\rError opening COM port: %s ", writer.getLastError().c_str()); + } + else { + if (writeMode) adf2Disk(filename.c_str(), verify); else disk2ADF(filename.c_str()); + writer.closeDevice(); + } + } + + printf("\r\n\r\n"); + + return 0; +} + diff --git a/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReader/makefile b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReader/makefile new file mode 100644 index 00000000..1569cfdb --- /dev/null +++ b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReader/makefile @@ -0,0 +1,196 @@ +# +# 'make depend' uses makedepend to automatically generate dependencies +# (dependencies are added to end of Makefile) +# 'make' build executable file +# 'make clean' removes all .o and executable files +# + +# define the C compiler to use +CC = g++ + +# define any compile-time flags +CFLAGS = -Wall -std=c++14 -Wno-psabi -O3 + +# define any directories containing header files other than /usr/include +# +INCLUDES = -I../lib + +# define library paths in addition to /usr/lib +# if I wanted to include libraries not in /usr/lib I'd specify +# their path using -Lpath, something like: +LFLAGS = -L../lib + +# define any libraries to link into executable: +# if I want to link in libraries (libx.so or libx.a) I use the -llibname +# option, something like (this will link in libmylib.so and libm.so: +LIBS = + +# define the C source files +SRCS = Main.cpp ../lib/SerialIO.cpp ../lib/RotationExtractor.cpp ../lib/ArduinoInterface.cpp ../lib/ADFWriter.cpp + +# define the C object files +# +# This uses Suffix Replacement within a macro: +# $(name:string1=string2) +# For each word in 'name' replace 'string1' with 'string2' +# Below we are replacing the suffix .c of all words in the macro SRCS +# with the .o suffix +# +OBJS = $(SRCS:.c=.o) + +# define the executable file +MAIN = ArduinoReaderWriter + +# +# The following part of the makefile is generic; it can be used to +# build any executable just by changing the definitions above and by +# deleting dependencies appended to the file from 'make depend' +# + +.PHONY: depend clean + +all: $(MAIN) + @echo ArduinoReaderWriter ready + +$(MAIN): $(OBJS) + $(CC) $(CFLAGS) $(INCLUDES) -o $(MAIN) $(OBJS) $(LFLAGS) $(LIBS) + +# this is a suffix replacement rule for building .o's from .c's +# it uses automatic variables $<: the name of the prerequisite of +# the rule(a .c file) and $@: the name of the target of the rule (a .o file) +# (see the gnu make manual section about automatic variables) +.c.o: + $(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@ + +clean: + $(RM) *.o *~ $(MAIN) + +depend: $(SRCS) + makedepend $(INCLUDES) $^ + +# DO NOT DELETE THIS LINE -- make depend needs it +Main.o: ../lib/ADFWriter.h ../lib/RotationExtractor.h +Main.o: ../lib/ArduinoInterface.h ../lib/SerialIO.h /usr/include/termios.h +Main.o: /usr/include/features.h /usr/include/stdc-predef.h +Main.o: /usr/include/sys/cdefs.h /usr/include/bits/wordsize.h +Main.o: /usr/include/bits/long-double.h /usr/include/gnu/stubs.h +Main.o: /usr/include/bits/types.h /usr/include/bits/timesize.h +Main.o: /usr/include/bits/typesizes.h /usr/include/bits/time64.h +Main.o: /usr/include/bits/termios.h /usr/include/bits/termios-struct.h +Main.o: /usr/include/bits/termios-c_cc.h /usr/include/bits/termios-c_iflag.h +Main.o: /usr/include/bits/termios-c_oflag.h /usr/include/bits/termios-baud.h +Main.o: /usr/include/bits/termios-c_cflag.h +Main.o: /usr/include/bits/termios-c_lflag.h +Main.o: /usr/include/bits/termios-tcflow.h /usr/include/bits/termios-misc.h +Main.o: /usr/include/sys/ttydefaults.h /usr/include/stdio.h +Main.o: /usr/include/bits/libc-header-start.h +Main.o: /usr/include/bits/types/__fpos_t.h +Main.o: /usr/include/bits/types/__mbstate_t.h +Main.o: /usr/include/bits/types/__fpos64_t.h /usr/include/bits/types/__FILE.h +Main.o: /usr/include/bits/types/FILE.h /usr/include/bits/types/struct_FILE.h +Main.o: /usr/include/bits/stdio_lim.h /usr/include/bits/sys_errlist.h +Main.o: /usr/include/wctype.h /usr/include/bits/types/wint_t.h +Main.o: /usr/include/bits/wctype-wchar.h /usr/include/bits/endian.h +Main.o: /usr/include/bits/endianness.h /usr/include/bits/types/locale_t.h +Main.o: /usr/include/bits/types/__locale_t.h +../lib/SerialIO.o: ../lib/SerialIO.h /usr/include/termios.h +../lib/SerialIO.o: /usr/include/features.h /usr/include/stdc-predef.h +../lib/SerialIO.o: /usr/include/sys/cdefs.h /usr/include/bits/wordsize.h +../lib/SerialIO.o: /usr/include/bits/long-double.h /usr/include/gnu/stubs.h +../lib/SerialIO.o: /usr/include/bits/types.h /usr/include/bits/timesize.h +../lib/SerialIO.o: /usr/include/bits/typesizes.h /usr/include/bits/time64.h +../lib/SerialIO.o: /usr/include/bits/termios.h +../lib/SerialIO.o: /usr/include/bits/termios-struct.h +../lib/SerialIO.o: /usr/include/bits/termios-c_cc.h +../lib/SerialIO.o: /usr/include/bits/termios-c_iflag.h +../lib/SerialIO.o: /usr/include/bits/termios-c_oflag.h +../lib/SerialIO.o: /usr/include/bits/termios-baud.h +../lib/SerialIO.o: /usr/include/bits/termios-c_cflag.h +../lib/SerialIO.o: /usr/include/bits/termios-c_lflag.h +../lib/SerialIO.o: /usr/include/bits/termios-tcflow.h +../lib/SerialIO.o: /usr/include/bits/termios-misc.h +../lib/SerialIO.o: /usr/include/sys/ttydefaults.h /usr/include/sys/stat.h +../lib/SerialIO.o: /usr/include/bits/types/struct_timespec.h +../lib/SerialIO.o: /usr/include/bits/endian.h /usr/include/bits/endianness.h +../lib/SerialIO.o: /usr/include/bits/types/time_t.h /usr/include/bits/stat.h +../lib/SerialIO.o: /usr/include/dirent.h /usr/include/bits/dirent.h +../lib/SerialIO.o: /usr/include/bits/posix1_lim.h +../lib/SerialIO.o: /usr/include/bits/local_lim.h /usr/include/linux/limits.h +../lib/SerialIO.o: /usr/include/bits/dirent_ext.h /usr/include/fcntl.h +../lib/SerialIO.o: /usr/include/bits/fcntl.h /usr/include/bits/fcntl-linux.h +../lib/SerialIO.o: /usr/include/unistd.h /usr/include/bits/posix_opt.h +../lib/SerialIO.o: /usr/include/bits/environments.h +../lib/SerialIO.o: /usr/include/bits/confname.h +../lib/SerialIO.o: /usr/include/bits/getopt_posix.h +../lib/SerialIO.o: /usr/include/bits/getopt_core.h +../lib/SerialIO.o: /usr/include/bits/unistd_ext.h /usr/include/sys/ioctl.h +../lib/SerialIO.o: /usr/include/bits/ioctls.h /usr/include/asm/ioctls.h +../lib/SerialIO.o: /usr/include/asm-generic/ioctls.h +../lib/SerialIO.o: /usr/include/linux/ioctl.h /usr/include/asm/ioctl.h +../lib/SerialIO.o: /usr/include/asm-generic/ioctl.h +../lib/SerialIO.o: /usr/include/bits/ioctl-types.h /usr/include/errno.h +../lib/SerialIO.o: /usr/include/bits/errno.h /usr/include/linux/errno.h +../lib/SerialIO.o: /usr/include/asm/errno.h /usr/include/asm-generic/errno.h +../lib/SerialIO.o: /usr/include/asm-generic/errno-base.h +../lib/SerialIO.o: /usr/include/linux/serial.h /usr/include/linux/types.h +../lib/SerialIO.o: /usr/include/asm/types.h /usr/include/asm-generic/types.h +../lib/SerialIO.o: /usr/include/asm-generic/int-ll64.h +../lib/SerialIO.o: /usr/include/asm/bitsperlong.h +../lib/SerialIO.o: /usr/include/asm-generic/bitsperlong.h +../lib/SerialIO.o: /usr/include/linux/posix_types.h +../lib/SerialIO.o: /usr/include/linux/stddef.h /usr/include/asm/posix_types.h +../lib/SerialIO.o: /usr/include/asm/posix_types_64.h +../lib/SerialIO.o: /usr/include/asm-generic/posix_types.h +../lib/SerialIO.o: /usr/include/linux/tty_flags.h +../lib/RotationExtractor.o: ../lib/RotationExtractor.h +../lib/ArduinoInterface.o: ../lib/ArduinoInterface.h +../lib/ArduinoInterface.o: ../lib/RotationExtractor.h ../lib/SerialIO.h +../lib/ArduinoInterface.o: /usr/include/termios.h /usr/include/features.h +../lib/ArduinoInterface.o: /usr/include/stdc-predef.h +../lib/ArduinoInterface.o: /usr/include/sys/cdefs.h +../lib/ArduinoInterface.o: /usr/include/bits/wordsize.h +../lib/ArduinoInterface.o: /usr/include/bits/long-double.h +../lib/ArduinoInterface.o: /usr/include/gnu/stubs.h /usr/include/bits/types.h +../lib/ArduinoInterface.o: /usr/include/bits/timesize.h +../lib/ArduinoInterface.o: /usr/include/bits/typesizes.h +../lib/ArduinoInterface.o: /usr/include/bits/time64.h +../lib/ArduinoInterface.o: /usr/include/bits/termios.h +../lib/ArduinoInterface.o: /usr/include/bits/termios-struct.h +../lib/ArduinoInterface.o: /usr/include/bits/termios-c_cc.h +../lib/ArduinoInterface.o: /usr/include/bits/termios-c_iflag.h +../lib/ArduinoInterface.o: /usr/include/bits/termios-c_oflag.h +../lib/ArduinoInterface.o: /usr/include/bits/termios-baud.h +../lib/ArduinoInterface.o: /usr/include/bits/termios-c_cflag.h +../lib/ArduinoInterface.o: /usr/include/bits/termios-c_lflag.h +../lib/ArduinoInterface.o: /usr/include/bits/termios-tcflow.h +../lib/ArduinoInterface.o: /usr/include/bits/termios-misc.h +../lib/ArduinoInterface.o: /usr/include/sys/ttydefaults.h +../lib/ArduinoInterface.o: /usr/include/string.h +../lib/ArduinoInterface.o: /usr/include/bits/libc-header-start.h +../lib/ArduinoInterface.o: /usr/include/bits/types/locale_t.h +../lib/ArduinoInterface.o: /usr/include/bits/types/__locale_t.h +../lib/ArduinoInterface.o: /usr/include/strings.h +../lib/ADFWriter.o: ../lib/ADFWriter.h ../lib/RotationExtractor.h +../lib/ADFWriter.o: ../lib/ArduinoInterface.h ../lib/SerialIO.h +../lib/ADFWriter.o: /usr/include/termios.h /usr/include/features.h +../lib/ADFWriter.o: /usr/include/stdc-predef.h /usr/include/sys/cdefs.h +../lib/ADFWriter.o: /usr/include/bits/wordsize.h +../lib/ADFWriter.o: /usr/include/bits/long-double.h /usr/include/gnu/stubs.h +../lib/ADFWriter.o: /usr/include/bits/types.h /usr/include/bits/timesize.h +../lib/ADFWriter.o: /usr/include/bits/typesizes.h /usr/include/bits/time64.h +../lib/ADFWriter.o: /usr/include/bits/termios.h +../lib/ADFWriter.o: /usr/include/bits/termios-struct.h +../lib/ADFWriter.o: /usr/include/bits/termios-c_cc.h +../lib/ADFWriter.o: /usr/include/bits/termios-c_iflag.h +../lib/ADFWriter.o: /usr/include/bits/termios-c_oflag.h +../lib/ADFWriter.o: /usr/include/bits/termios-baud.h +../lib/ADFWriter.o: /usr/include/bits/termios-c_cflag.h +../lib/ADFWriter.o: /usr/include/bits/termios-c_lflag.h +../lib/ADFWriter.o: /usr/include/bits/termios-tcflow.h +../lib/ADFWriter.o: /usr/include/bits/termios-misc.h +../lib/ADFWriter.o: /usr/include/sys/ttydefaults.h /usr/include/assert.h +../lib/ADFWriter.o: /usr/include/string.h +../lib/ADFWriter.o: /usr/include/bits/libc-header-start.h +../lib/ADFWriter.o: /usr/include/bits/types/locale_t.h +../lib/ADFWriter.o: /usr/include/bits/types/__locale_t.h +../lib/ADFWriter.o: /usr/include/strings.h diff --git a/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReader/makefile.bak b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReader/makefile.bak new file mode 100644 index 00000000..94534250 --- /dev/null +++ b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReader/makefile.bak @@ -0,0 +1,71 @@ +# +# 'make depend' uses makedepend to automatically generate dependencies +# (dependencies are added to end of Makefile) +# 'make' build executable file +# 'make clean' removes all .o and executable files +# + +# define the C compiler to use +CC = g++ + +# define any compile-time flags +CFLAGS = -Wall -std=c++14 -Wno-psabi -O3 + +# define any directories containing header files other than /usr/include +# +INCLUDES = -I../lib + +# define library paths in addition to /usr/lib +# if I wanted to include libraries not in /usr/lib I'd specify +# their path using -Lpath, something like: +LFLAGS = -L../lib + +# define any libraries to link into executable: +# if I want to link in libraries (libx.so or libx.a) I use the -llibname +# option, something like (this will link in libmylib.so and libm.so: +LIBS = + +# define the C source files +SRCS = Main.cpp ../lib/SerialIO.cpp ../lib/RotationExtractor.cpp ../lib/ArduinoInterface.cpp ../lib/ADFWriter.cpp + +# define the C object files +# +# This uses Suffix Replacement within a macro: +# $(name:string1=string2) +# For each word in 'name' replace 'string1' with 'string2' +# Below we are replacing the suffix .c of all words in the macro SRCS +# with the .o suffix +# +OBJS = $(SRCS:.c=.o) + +# define the executable file +MAIN = ArduinoReaderWriter + +# +# The following part of the makefile is generic; it can be used to +# build any executable just by changing the definitions above and by +# deleting dependencies appended to the file from 'make depend' +# + +.PHONY: depend clean + +all: $(MAIN) + @echo ArduinoReaderWriter ready + +$(MAIN): $(OBJS) + $(CC) $(CFLAGS) $(INCLUDES) -o $(MAIN) $(OBJS) $(LFLAGS) $(LIBS) + +# this is a suffix replacement rule for building .o's from .c's +# it uses automatic variables $<: the name of the prerequisite of +# the rule(a .c file) and $@: the name of the target of the rule (a .o file) +# (see the gnu make manual section about automatic variables) +.c.o: + $(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@ + +clean: + $(RM) *.o *~ $(MAIN) + +depend: $(SRCS) + makedepend $(INCLUDES) $^ + +# DO NOT DELETE THIS LINE -- make depend needs it \ No newline at end of file diff --git a/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReader/readme.txt b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReader/readme.txt new file mode 100644 index 00000000..2d2a3bd7 --- /dev/null +++ b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReader/readme.txt @@ -0,0 +1,10 @@ +ArduinoReaderWriter +https://amiga.robsmithdev.co.uk + +This is a console application + +It should build with Visual Studio 2019 + +It will also compile on some distros of Linux. + +It has been tested on Raspberry Pi OS (Raspbian - Debian-based) and can be compiled using the provided makefile \ No newline at end of file diff --git a/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReader/targetver.h b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReader/targetver.h new file mode 100644 index 00000000..87c0086d --- /dev/null +++ b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReader/targetver.h @@ -0,0 +1,8 @@ +#pragma once + +// Including SDKDDKVer.h defines the highest available Windows platform. + +// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and +// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. + +#include diff --git a/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/ArduinoFloppyReaderWin.aps b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/ArduinoFloppyReaderWin.aps new file mode 100644 index 0000000000000000000000000000000000000000..c3908e0f126f9e59dc760339ec61a4b22869c418 GIT binary patch literal 426764 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 b`#Q=5t(Y zQ-;2sEe!p{xi2j`{x-j8{c_yMYc1fDx>U8z5%8ra2yHSIz{2`OL9pmV={oNdm&^iD z6H$4Z{MdcqVRKg(SgYme$e$F4^BG0!=9+3fYVIV^)=1n^=J%a`L{7R@zy6K3a(fOP zamdK{Z?b}0#m4Wnx4XRp_L4!N{^<4dNU6h-Z<9KPip*3Wsb0x(KmFV_WcO7WX&e7^ z8R2{Tb_3f5*1)CQq2lL)_NGpP(bxR1Pf|uoHWy@HpFQ-xe6l}f>)&NX3f;R-$WQlo zdw%-xY@Nw-J%sk?PzvKy517pV>=_x}SuxVhwrmU|{6S8q=lUYywE*Se^fX~GRmd}) zpa&@9*Nm6FB#-wF51-vO_!N~hEInW2wDfx@Jp58PA6W7^Gjzzz}zP_B_-v9gS+cP$D^5Q zU)p=GCiwaJH9o%)RAK+V@HVv=Sh2qSUMe$vdipAmL?WbRdAg(s8&DP&eaWsIO+F0i zWyb^4Kd^=?TL6!&KCBdy1e~mtoWs+yGRs=@QIj3;9sgNg=d(DKA(8df!P<-MW*ATV z;_mkZ|5N(n_%UeVFMDNqxt5TG#I%68c+Dpy(tkXJnD!e8*>9%{q7#xF9FMQ1keDiX z@#bo>3-It=f53AumR>;Uk&utGP^sTTY8=8)uEK$c(@nw$8}DQc@ULf=m%_Wl!>jkY zyQ}lZ#u@;e$G2uqwRmEZ3vDbtobBEry}++H2Yjx_1yfX5)B4&iEG$G2k&#<;OpLSX zDtDCmT->+m80oEb)6?mE4TxfY&#mn+93SQl||&N|@#K;`@+#rt^l zdm)P&?h41`ByDZp_{0R>`1piAofq04M1}9CmvHhiSz6mm(W|rHDJ(2f4`GWr)s>VA zyP(3eaY-1Whw6ymJAX4DT9X$^`(Q4Z;_=q$`<)E6jwBjd8yZ>~>!F^WwvY3@t@085 zVm)yXT~K?n;WO<~awu$Q=+{&BA9Q4)&vzFWzw7dd+z3-Zwd4$Ha^5sFLloCP*v0}E zwXpuDV}662k$X1f3N|jngY?kXU-b2%pa;e*Kg_ipV6Ye1g=hUy?)tqFaEK$#G1OQk2(E(@z=mVHufsO(~a8W?<0C{2*kQ@OW*q08XprZq! z^XVXc0Mje5&_Ol;&H&z5;GzS^0SM4R@c`*p5W6~#1=0l22QUSoV*xg<0Hy#o0L}p3 zTr5y90OAS)EZ}$+hztA)0Ehu-(s6-fxxld?2e1Kf24LX=djXgNI0GQWu8t7^#|VIW z3qVQ~0^nEyAX@+&F941Q;1U4GfxQI4egtA*KL83bu&)^C2LL)CQ9uk569c6X$bo(2 zz&-#JauAo893%iBCkK{64+9BcyAmWvrvxdnfMq$5D=9(2nqZrpCM2Mw37G6j_h&nE(sSoMv>qEf+Hu|O@_O~hI4WKDt11Xu>KsHyfv4Ok+G?kn|?hH9QgB&0j zARR#8#v3eqL*CvX2QYOGh7jJtP;fBF0W?h!kiItpG6k@?LNEey20$PXP%%ISfT?CY zWU3zz%8CcuebWo3UunoXD9dbqh#HT~?>FH29fWC7cC_4{)4-lUR zc>@$*<>`44xC?{&6oc)>U|TWRRt(vsgJl43fZ(enf$JZtze0UI)D93_(GJA}w70iIV*t*Gez4vTwFC6`_d|04 zsIh)%d#)eI9fQWk#-KR>@ANrnZf*`j0R-ovK=~*Lg+f8w0EpskXnT7bItD-#A47%_TDsRU?c>wJIsBH|m=Kt5& zImbY`+1cPa1{X4rbM+4n`ez0{!Qwy4F#5lmAn5<9IHUhx-v8PD{*V0$W)T0C6#whV z=-@4v7n#S6Owh9WmuPRbIwpFlIHV2j_%eJ<?tKvecTdH@3abRd!XwLx3ZBv^`mzP0sSaBBc!o+}{z z{~+)F{rf`yqdce#8WL=JU0{E5Vs%yMV^Vt{@2Y*w16xhd)|S`vp|LXN|9yGlLPA1( z;{QW`77zh>_(0zK_y3YddL?gQ?n)m1l{^S~-Ugca?fX9_&#n93lUmDb_qpAD zZ=I^|RMn|d=bXE}+fNHa_P@IZ=95q0-;*cSP5^!aN4%}M{&?Pd^+%gegr&8o&w)1D zjs_ahgO5EL!lQ`iIW+#(KL4?+A2@+*#U1#=YgdQCwKs($Yt4^tz}_88A3gVpaO9b_ zklDN9DAeA2_1e=X9t}^1JFXye$kO(`Z#@3=+8ymj+K->}csPL*owaj6vH^Q{U-8j% zo(NA2o(Ne$m;UkUXV&gMvW8~d{bXp07w6u4&eO-kxo=zx=U(yHIVWImFq}B&`5Ulz zZ#W0>eEQrI7zn&AJ#_T=+TDlO9vyrV6WH-*m^p|L9)9ETE7nfj+kEVtH8lK*@Z>os z4nO*Pz0IG+c(}WH$KVt2^+Z0bVDF7&?}>B5BWO6!pKIsd-TcRogzz}}@7}dRxOO$V zoQ}V{UVG164PVc__sCk-ytOOtMr2PQj30gI#N%O2mV@x*6?d;a`Vdx#M}7}0MOb_M zk;m4a|HwzypP!G>bJTzV7Q(r_3N0b?)*d*{VSFri0wO2m$l)F#`emux)I7&x-__(vaq0*mou2n0|^z}Zkd*RFmVXI}xyM)7^y{-u(bm&pdz-7UKbD zF0x)=vLQ40ub%R=feqP1{z?6h+;N!m?!*=7pu!%;2pUbBoS34w&yn(m`j5r{Ul6T* z1ZFs}SHrHchh7!^=Sn*zyNI=+_N_e-9$|ftpNrL(C}c=(kEfFp;?Uvjq~i$YHQ6?1 z4+(3QM1;bICA7D&67`DedNeto=D!f^rp8g9nDsd=V#&FX#4CcL+0F#PQvp| z1_MePY+tUYa{QCOsIW?m&9?W6PyE3jl?+6MO}6)EpZLTl{wy+4Dn7lA^Uu*&ej!a_ zowh%Oy-xCXzVwwn-Jf94=qo>~lP;G1<)8dk^QiOvp3JH2Ueu`^GEH6XFXgDsJNDGR%`=zUSBWKF)$ehu zR0X4_{u|k)+gI+vBdOlDTgNY~TI|8z?$KA$jXT+<@uP(vw;%nMy&JM;&7FVC2j5$_ zsT(=qr(aiXU=QsZ&D)0K`8U_vd&g(vVJx;6o&RH*!4DqWN_*e?l04+eUiJ*4{QM!G z(tGT`Esf^~vXsb=C~m2}Jmt+X*`wKJ^TvCMXNo61jvL>;`Q=r+Mlh*upS{tM;n8ih zmpyOXzV?m3@|C@}FJIqZ(rJBv)p*C})9cBX_ulo6Y|AI{>iNXWC(P6L)zbSK-!%Vn z%ywvAulbT&DUKC;ubMbeYj1UKH_ZpwdhEZ#PEJ+q?Jij>w+}BoydtxA!OQdvt;6|Q zZlySW@Yt7#2HC&r71wmKx4L?8{N=dhd&T6TL&Fzj7Qg70hac>Dd-&T|@^>Og&z^&k zxl;d;>;P~3S6BDv+w65Wtz)|`)1Z1HgZ6wW66M8jURlSMSE@T^_LlKR-d1lb0f8RG0_WsvXTfTkro<6eo@ju1(`_vw%ms9^_tdBUH?|F#d+K99wE=sshrKaB z_ER7KnAtx5E59T4I<~Jj)h_DeANrNj_MvR7ZJoUjmAA~Rt+Myj$D?hl?YU8Y>ZvVj zU;o-OX}qZ<&r_9ne(EcDR@sW(_h9O%+FRTTQ>^m`&PaP-zGd-r`|qhwetN66k7G<$ z@}*{+ZWg;_?3T^}>&XREK?hK-t6xn3dOR&G69uWYLM zXTQCdTpsX>DE*d&eg{XdM^t|Y_jzaGf1(GUepN@?j~^(02ZtZo1^P$ZFWh+z|AwgB zZ)-gHkf`X3eLwlqI8SeF>?qMdC-;{x&A!+qE`8xjQ+&CgFSh>krJwq!pM2?ybh#kq zi=Pu|e)01&P5E*f<;#xV*(Ku_6!%~H#+PPu;QSrlE@)==RQt)73oh9CxD@%)Kfd%+AN7+j zDPKyn2$oA(8~dq``pK7+FDYM25%3GTHl}4AwXkrh(u=A(ri|L~{E?L_V4n&{h zf>=;Lz%`N)lSwcT2kE~eE+p(}E9VPa5G|<97DP4iU>ugo7qZS#f)HI7`(m_EAFbb) z?3x4>E55)!`$CGL8E%MmxJ#BO5)6TqyRoS*75ig}06PQe4CCoG*DFZGkTw$@Rn~_eJuB!n$d3S+_6wJ&(c{ z>F2H3cS$+T-J*}S!VA$km?yMvB3h5aKsKA9r?}z(58q<)Ko`;om%$E|XetIen1k8a zl~Uf(S&3F{Vu>#_LGj!Wxu(8wACVE%!(l*tp-GKPBw$?x2~Y+Iao~%TXyzdX_#^|I z%2Hx?2U)d1WTF-_c7z{!69LW`^ z68;Sa90?-65Y}$$3+D@Tl5VPq7SXY1U*P;8DP|{Xe1S57)cBH*>5?xLWUj`(WP#2M zu`CM~w-#7*BwCRfLPH8)D6EVE7k&yvVx5)9JK3UqffnH50eYGMg9EU@)(5Bv9%KXf z#}Q-z@=JWl8;wexeaWg=`0NW+^uKJ3w;mLBrVq2f&~pk}L>BO2o`m5hSY)2$hOW z`zXp63IR~i4}z=@P#w~lm540)GC0Vp2?+?qFv<0#RPrU0)%lW*=|QqUTZ9v)-7}Ic z*M!`F39Fh5eq=-YsF+^_8{rBCIVHLSqLBMCn2RdMb^0QGgm`8VS%)vu9Tf)*qeoxL z^9!1}K3`xZ%MfF_Lax&n?xTv5ZDo}6Wm`>GjHxf2FBS2&GRpJIwwkUOQ(scPlwy6+G>mxdQmqrf`;7`B_ZE+IG z=kyTcDg;p>f=)`a!>PupoG)aZEEm3rA7JwNuUy%XZH9=CaF;GWx?eeT^HuvuuaEee zj;pa})Ot85mf!(O?2A|@mzdejPA_uxMX!(e5~Ic!w7&2K(IG!J(U)qzWF0_8==zT@ zSF^a}z6?n4=(;crP+V}3$o10xI*gMq#upesU%*h=7jlqX*lb^->mxQx8G#M0g*lEz ztuJti;v$~aHMmE9lrIv3!WRr6iVY5M>3sGJB;8qHfw+rql1%Q=W*toXs3v#GEf`{B z>*o)J-(#t=_2l+%JWM}wCx2Q)BSX9 zpYo-Y2PR*_PH$%y^UF@V64V#}_dwgt&EGxWZo8hn{`-v>CYnCjBrZFix#|G<(=S`& zMSZf-_sIIhl^1QYFX2?$wb{O$bqda~FM*m9UWCsFo`*l6>2O{+i#aSr{IU`qsDz3n zMm35pRYxuQOVq};%ok`O)xr2ep3%n*#TPB*PUJFjgT2F%wVbLiS&Lo-U$|A|5;v3% z%)vpKS<@v3o$?7qng- z1Pzy^*C=X5TnIv(jcwK!)}Hx7Da!W95N%{8>p1oW70I0~^M%92hRG0_(LO?ITVE(j z6cGMLNGWb^T+ZT7LZdN&C^q>xf-Uw%2Xht|K5T(6G;2_YXC1=6$mGGzCz(t$V3MD7 z*b-l;YsiW0kP%eke1Tz>RCbb0Ss$@9<5ZAc8E98SI-j8(e5o<9>AoQ3;zjNYB}=}s zHOt5ad_-5#Min!+vIDc%wUfA@dhAP~g>_SgxElr-ZJXwcYh?SG9GC4k>sstHUv~U+ z2xbXrPBrg5r%l7AnXEEiApA#uxylg3+d-~Gt<@R46`MI>+-2NNW+nX14)>6Ls znV9m$&zO`iDPR1|@VO~pQoi_^;d4{Iqr`+wQKFWNdAA<2u z^9JcBEclC`_{cAA=s?Ut`BhZ()1OkXH(1cQPWlLj_z!ksHv760w8M`9V)9>hcY`Kt ztLd1|d_ffG5AP@@DDaQsC_wm)6ia!x6>-U*O-LV6kI?VK#O!waQeKaYFVshsxNyL@ z|7s(>aY39f8W&E}*cW0_KI5NFO<9Wpe4 z19=q&vV(}grv?B*6;R;njKxlvgJ6%w*s!h775?Rk>w3K5* zxj2$A1JMeCKNL4&$y`3bOfX2s5|ZYd_L1icDK)Rf&o&2T^C=lv9DcT0XA}>r_1W95bNr1m}03*{vvSL$Tiur{r0F9R8 zkN85Ln#D#XQ45`{76;kj#sK*O2+1feIM6??M`&9iD`l1CP|g?P<;r1sKroxJ7neFK zR9|#G+Cg9PYm!az#YD1b5{I>?xa7V_zMx*A#AxoZn@o*DP4B*x&tH19xe-|8oTH+e zFAiu^SYe=>8XeP;F9xC0sl%aILe3?&PA)Ms_9cU470_BjW>^!K+?S${sHq4~AhkH;CFmy(w*ny$ z&**@E5*LaWLFhpC1Ol1_xot25S05lS|Kkd%=gcpF4B{`VC0JIv1A$2kw}wROi^&(_7hBd@ zg0P~e5#<4OmO{uS%PXW2#h@J7V_X!bebi6B==n?3(rqk8`Ld0ctESW!nO~}aZRC{m zWg87Urqq{|FQw?Dd?|%P3n^bT6eS|%ODP;$Ncp0nC=t)Te96zAO3hq%VRQ0jlYGgq zNqB7}ojA{A)d6&Niq2<&BBN7xobn3?5C%&H0Qj^%JFGh_mH$`geCT74{f>6D0+DCG}I{=lUn$+VTO6J@f25=!XKul~>VqeHP z0iq676$GJr-_#fFqYe5(Zj%$I;!7o8@;(y1)E(ST-jfVH6UAi!eFO}E)N6a67hIrRqAV%<0_G<9lHc>luaDp+tIqw&LQlSAi4y0F@dXg_pLQGA zqI{tsXZ;XJDMg76*g#?6{|TSj=k)R@?GUuec;cXD6sJi*p1BlBAh+3ZFYGq-A-F4b}i(nqKs`%<7;clvI0 z5s>YsxR18mXpKGivg4maPzUQr+lfT3Nuo^`1zRfCFP5s z89q1VOUf5NGkk8!my|DlX87EcFDYOA%<#D>UsAsKnc;I&zI4eKy|cMfMDd>A1v}+} z+Rc4Q?}gUA7dlW9>_7p-T*h=iz0;iXrIZQgJ>rxvCNi44DPK%fD&G|;$+o+oeU#>x zQs{L|_fzinQy=w{Fa6X<{p3qO^-(|h(ocQVPrme1AN7+j{nSVO)vu z<`Bt|K=ZTpk8upq^#L^y8SGgGk|L2o5D6)<%#Ta%i_9+oX4swZrIat^i1@;7kh6r0 zDXr!IQUb{$Q9|@MN{AL!020(d6qh`Z-Q$w`BJ)et7q%eoke9hHFiCOVTwn4&@_dog zm?$n(xi5LXAjo8dbfO=)#F2*!5*H$fGr%x`6iAV=3WScT z=Q8Ll>QUXwrenIFe2Mxfa+(_&@ybQ?NS^oEk^86&>Ri$_pr3rL^(Ey?DKsfxO5xB#$`=hq ziAecU3WpX_zGx^)M9LQpN9nw6hx4WEOMXqlYa^~h2I#_JfF0)p?er1^S30=p0E7X> zbq}9|f{D7>MI%A*Z%~*x&;XKIxNsL}Xrg=(WmJda zLI<&e&LIY@Qv%{|R?3wL%J>3E*%!$2+^zMcoG)YuajE)3K2fK!QKF?3`2zc72pi+5 zM3qqD2$BTGz7*DT)$F3&z1(zPiut8Hj^Hn~q01)G>jGjikhDo$n9Mlloi^hO1&+4dhy2J) zf48~56#0UlmQLqG4^{x_0hKjk5KwGxTuSo`B?ISJ7$7{k)Pt2x_a$9VQ+MfBUXPT$ zBSd+A*%24isQQxfMPovQ$(OLx+u6nZveT}l??(H-JtA)Y8x9Pq9pC!TmmSYsb%0{i zFI%JL6MNgv?z8U;ZcSXWuWYU-xLX#Njrzjh{lr&m=^L}GgT7qLpXbDmz9)*Z$^b)& z(8Qzz)uR%9HZ=SCDAmiq{n>M9I4-P#bmrfUCdE7D3z{VH$X&oEc*&QHpSO}R6gv1# zv^Jdy24g4O+7F)Ahe_hXUmOM~|86uq*)d5jAa*hFYBC|0qE@QR!_XJI^xf#{fNjv+ zlD->VxgjKR+3{OI>_GqdQVG|NF#0cdQ@+Fz=)XSNkyNc1?Y}V{_uS5uQ@&JEg&8Sd z{CrILlJdpR44<3wCFP5s89q1VOUf5NGkk8!my|DlX87EcFDYOA%<#D>U%KQ=^%mzg zbBg!;(s!fH+nD+;WUCwG9vFqbjiPrme1AN7+j{nSVOlCl3VG#6ONFDe1VC^JRy9DdkJ%3o;~25^hvoT#zW})GSm{Tp-J0 zg4!C*j$yICgBqZ4avzBiu1EpKA8a^~PO_Pmd|&uy!tilm{l0kl0xjM1B@0L;F5(M( z-ncJ1rqS@hkOzPU7D^lm98f}oO^Ia6;d&WF>Sg0nqe(UEHyzXc5paPhKWRyaXxdCQYBDD-5Eo?+e zxh6TPFFLm&5%~f^{iSO9yH&n!7dU3`Mo73UD^p zm(uyJbPCyzETb54072iAFBL)If0gnS<*0JL?65CUzT`gU$8~o?UeP<2hhYT~=SvLO zR$t2b0@FMtz$Kn(@?;PuWd@ITLV@NIRREJX(xm!730&Zbs%GeROV|+n(kUcs0zG!tA%aI_U zBrCa2WK8X&{9G!tN7eZ+c9aE$6PYhkpDmEt2tv}0`=aMBG7`xVM2MVVy- zlrN=lXd&f`hN48Id?|%P3*~&F(?TrH`7(>;6{lj^*%+Usp&pon01yoD3@atlN@$$U z6*ANVmnzU%oow{Fkky9KbL|y)6bVaP)*vgZKE&w`3s+9lWjPiKiH%=NeKis zkz2(r62C!ajphU62RI;Hk78gUxdv1gkZ939>L*{ckI;kEE^0ambP)BLl+ZRC7wSK0 zk!>_+3LRAiTC}hnBr8CKQ4b~3#c>e}#WP{?CBKYNEmSX{7VFGAKs1TY%%B<~dvuY) z&B*GJUH*$5G_fz7e(Vd{9*AG~B7Ic$g&GJX;Yb%(CmyrGAsI`JAuz$iE=z^HScc?I zh)%H(-QQJ6Zk+->7@(N6(*-Iyk~do04iu!Kkx8J)OX5&H-ce`g5UM~WsLl>#P;=MI z7gD#KzLf62a9pH4L)Oh-sl+$vwH_g|>%%WX1l zAQSj+xsA32T51~|;K|>Trnpef7tW=f^QDw8v8UTxF6Ybk+K#PhA93!+((Ns)FFe0& zukF~H_EA6ia=`@{$veB9UCb{#>jVqx+JxL$9lKr-2$1_(Q zpxE@w*6_dfxBc8c`@Z1T#ATh|3#DGzvbb#27yb$;eKof9T~~4yAMm8_iQ>DRDwB`P z+HcI}pP{9%i)LRRrF!}`R8rK-#&KZ{q&@$>E`2i;x^~1D1e9Y6U&MtS{8n@NZgiYO zk}pU!^ih_BlqMjNKg6WIqfFFXA{b;DAN9}5>MY_C(fgRLZ|OW+qe{S z2#;x*D)J7%{30JC-s*2yr|(9`c`SXD&D=U`^9TZzhX#)$Q!jlt+5}@eNbaNUFw}#M zKJ#UpKg7_%Tz`Ex`ra20(4FLP^5g*i-3_YKccWjz@|#fSMW2Pyjeq%e^5n^!Ove;~ z6oGX_AdQ`M1S>&P1WW`lc7EZ`Yw#C5&}mB%ND=590XtqS-MLnhrU;}6*zscNANi3V zL2%MOMIc3>E&_JESh^0M_$dM@0uli`UX)J3NfAg9=o|r@mFak~bmv-0nj(-QV8=^D zr{JUrqzH75fV=Ks9Cfahq$vU^0`AyJVM!545$GI&=sZowQRiAonj(-QP&ancIa`WA zia^&0=vo7$rPIWcB9J1`IRbXPDBZbAlBNix2t;d58arK=>69}m0uq6`v6E6LMIc3> zYXo$y0n*ZGdPxyT5$GHNJ6@FTTqQ|U1X2W|wI+?7uFG`FnG^wuK;76$DU>3RBG5Gg zy4C<`=`_8h2&4#fj({C6N_Vc3q$vU^0?}HN#!lB|I^|4?fJC5f?4%S*5l9i}8UbBv zfV6a)UQz^71Ug5+ju)jnS4q+offRvgtx032>oT2kCPhFZP&al`3Z)372y~5rt~Eef zI!!Mr0x1HWBVfmi(w(a$X^KFKK(yARvD0;#PC1hzAQ7k=J1K=y1X2XLMnKmZAT6Dy zmlS~%fzA=I<3;JtRgyGCAVnZrYtq>1x=g2>NfD3;)Qz2#LMZ|%0$n4ZYYmW=PSZ<@ zK#D-;2-xwWbmuBbnj(-Q5Un+7>~vkGQ_iFaNCfJ}PD-H^ffRwR5zw^;NK2>bB}E`b zpmPN5cu~4q1tTkMDFSDB1njs#D0IA7+G2!0!-JNZpCW(=*l~fPJ9aEAgn%k(OA$E3 zBOtQ}f}o=#jh!<*B~tTyj6jcL#}2Nv?(`Vj1bcQzK$jaC9Voi%j!0#n#?G@lB~t5p zj6jcL$HLOs=`pqm_Uw)T28A6Lpxt%HV$#@ocBe#YU5^oyE{wv2$AYcyfNT zB0wW&+pl*p`qBX0tR75yb}9nVz(LVnci^5PPd)8<=%g2WcB;>l-OY)BjtChYbz{fE z>c)GL>*e9+CT^_($j&dR%{hZt6gF0Uino*t1BTGtqa0(>NG^v>tJ>K zsCv~pDpr|MEmdxjpoMRlosnuwVP^<|L1D)QXm{PQ7!7X}A{%YN2uEO+1}7>;szO3SFNLBl^NAiZKag}zDiq8Rbf;`0dB3XOa&;R3L~Ne zKt$30)cuSckfQ6x#+X`532V_Zl~$rFvV*s_?z58C5rNi$#^#P4@CAT90_%oC0O zDp>e+%w80VD%E4FbY&_)30qygs*?&>r69D55+b!2fk|DfAwpV!(yB)}AZ$eiC{aZU zM*&Loh!nimQbIkkdd@(ahf6UoPOq_}y{Uxl*7Y(4k9}Pls6xTmqR_gxZdh6YN_4f= zwYsQ^^jN0SN>p`9bp;4v_qIwzOWiYY-{aUpWOV64NIM5A>H-0GX1WTs3ZzOau|-VR z6Jc7@n`qs&Xl*I2M4fe2)fK4#CF*o4KnaUfi)SFABLZ!gapaz}iB$H8p&KZPZ8gHm zms(YTtIdL|Ra~7B6B?8QqN-4tE>iGzFWQu2i$d3Nz>jKKq>3zI6?Uy|!K$Rnw46Gf z%C}%wry^B)rV%}k9Sf@qS~c31qqT%7akjJ@d8@%zQGN#|L<$43UZmjdUbHF47B|-r zOjw1WBcs-I1nz+BMW@=bU{|LiReGioveuy0Iy&5SN2NffpgmiYM8-=mt?M1xi?-7g z)8p7d>vZ^}v2&XCbyv509}&GHyBa-x0Xibk1Q|!}x+7BAr?GSTc6Vpbdmj zt))GV9Scii=d|we4$k*JB6>%5Fn79(WUWCfbac4uj!J<{W9M}5^j`c=qoZq-dK^2@ zqr)eSovu-R768)N>Dq}pB4l)+=&m~=mAyN5Y^aqMLiZh`Vi9<6J2C92gSQqvJk`Bg%Y)w(@uSXXsdr^~GR z2~LEJif)xUW{+dX!eFkd&HA9U5W26{QjTJ@u83T|Wm;I3R{as78md*S0}2CCMOvLz zq?K0bIxA|ZS_PbHErIoDU8^fmtqzfzj$q2K5`wJO?NP(Js=GQ}X4Ow{B4ku_tJEG}fkrrU-ss_tZT8Yked$DLWbjG_zwYrrmtwb-H z1+4q1N>!ERs2dSc#aND|ql!|j0;(LX=!#sXR;%KXIe)DV4$&W?${CEdhxJ| zw6&C0!nVsYEp0JMR{@rzv=DX=4JuV_%8ZZ}5Ybg7J=V1ql~zJMiOfk+VIU%;h;;8t zU7e9;#i*@Fl>#hb!NONhluCW#!Dwe1ss~n5(Ok=PBp!>S9qX2+muBuafuzNv9 zoN7hkSQu!_jA%hddMwk@5iC-rQd>o7A?zM_m0H?jEI{=~M1+Z|M_^mD6_r*3NK4y_ zRs@VKDlK*Eq>(mTtQxf(OWRsXR{_GY`wn1;su~m@5mjWB6IJO@#GtU_0<^pCSPaZn z6^ajb4@~clxk$@YS_$ieWm?)|l&%6SM`wUn*`EXUHQ5*4fFRIN)?t5-R0MVCn zIn}zt5sXE4rmIrbP-g;s#q?6$f~!tKs)nja6;%mqx~jH{SB|x^Uh9!jTeNDeKUG>i zQNq>*?edjbCDvPA@R1&u8DXRtA?vKWb*oGr5fITRs#$kLDtlP0>aku`Y0IhB6^>vm zvNK(ks)jlf;47w=>K0se5>ho(MXIPuSkqOtRlIVnmGxSWjM}1AYyGLx>WLDzE@+pp z%qp?o>Vl8-xXcJ6#Ryqv-K|??Vz7Xz`?|5C0Dxh!s>ga|=_+z7IP0=l1y?y+;pDSb z=P5>SUDaK%%j_}Qr&1S#!j22j?m3&qz+BZa>w~4M$gSY4%VHH= zcfl^R$7r8QT^c#%rNYjFyG+-47b#5a-6|cJIwF9fQBYjFyG+-A7b#5a-6|cJ7%Y(LzHaO&0N@Q+>EJ*Tr3jp+5x}6Z;{vpM z&So)b?3|{3o!s8s2++tWFFo$qfl-CkjUDiHvrZ}#1o%?4fDUvAuq%p~QnXCV0o}p0 zx~f%_Q>~?#&N>Cwxw>djq!QIy%IScKL{g0Qz335)ThV0#ulz`Vm9K!)i_j4Pw`mmB ztUDr=J=$JvqXt9>1yuPFK#?xd0qlw*rW7sHazMLAm01N_RSE-Pk(M9Py;KKA6Q znGr2Y>X0Hm9rqX%c3gmV&)F;nL8!LWjf`b#6_=^fh^Pa*{D>J9Bh4sw23V=mN?2_! z(*l%sk(Md6yH_Pu!fLS6h;NHZR|%`Z(uxFAX(cQ(qD4s^QlzKjo<>f2>2b#nnx-%W zp>s<$N=jI~%d`MX*MVJr#FV1li{>iFTC}u9f`&*q7NblHjsRM8tGgQ1oJv(mmFTQi z@fKF4#iD|%M74@wgs*$cjFc$Gs){hDQBg+(e5O%Uv+jsg_GoyA2HLP#TC2EBl}1Dz z*yTq|DcU`h+al=5TvV)rg(EPfBN&R29xZAWaH@2qM=%jmRawHS>cF=!rK?7*21{!d zFsrockt!CTN)+Qt6?VE17%XsA_jO}O0RW@nZtFBMDs@AoFjuN|g{Z^0{D^6bN-Gf= z>Ri-XN&v645|-&I?1~hCg>}{00nkB@imHU`d1OUvS+HeV+G2$6EUn`ElY>EF#|3Ej zoXuj;aJMbhfK)lCC``L|wN;T8)7J+*)ElR3L%K@#nEMJ*b!ooUK7noL$ipm$F zPA8;MMO(DBRG|eZ(-O88Xc1Xvm7_3-sz|H+w4-U{l$RcN?4Vr=v(eD@N?5cgL|3K@ zP$eSOz4Af06{}3G3qq^AOqE)qinN>!=6=yr!S|j z;dT5|Z)sP}T>+==!;Wjfps?ctw0q8GF$hc5ZHblc6`&j;z>hd6D%d3yZ>6fOE7Jm= z#dPmc+LR!;@wb}00xbA6rD^1pmmYWQpmhpESlq^H_eFq+Z;KJKvsx<^C6)u)Wk#51 zYf+8iOa!1{Tb(mEpGKaHZAbw{MKM_5kN#wNE@1U4}O7%b4H`?|5C0D#lj z*~IuKRi|$RFevP}0PUW$Sxg!`r*C&B&o?mwG;+#Ik2`i?QDJH9Y-0SAs?#?DIwE9r zpqR$a>D!yh^X-g4k7LKe(z>&q9h7YKZ3HkV?6?5!t~(Z!#!lb%W^!yhBS0f3UGHpX z#FMROO9Y~UgQC0cpt*`n>&~;K^HV!cDFQkoWOUSx9Scii=aeFzDnDByfI(r$1!#BO zv6wV=o-Li9+Hpz|pplcVcTOpUsqz^bfoR~M=&n16jv~{#bB5+hYIZpSIwE9r)Quer zOJk=T!c;m#BY;6+#|3D2-LaT7cA{KCKvGPin4Aek8ae5D=hS*Sjh$1A-|1RA8aODr z>kgWy$htXJQmC3p5x)wki=9PQY0H5IDe7KyYB2)47A?41T}^0R)v1JvED=eoRs^hk zt*aam$^;>N%SrT(L_kLbtb@kpjvep?fPK`J;8iAIV{Kif zm9TX!Q)wlDw6v|LbQNGZLR*g2X{Df5r^N^}(xAvHzsgZ?BKjl(J&qlCt4mLm9?}ro z*Gem48|yMHKxvCqS_y@LuuP?uhyb>t&=#pu%M{vjtWGPf!*noYRk_xcnTWoMfQ|@w zCF96FXA`OHksh6!p!uVO#k))kP+E~nKqR!?cV>zBBJYxk+v#K zIaQ>JK%{MFBhcg6u`qOK2cM<81z>5d;xbig2}OcXzA)`xM3y6X;aI6Ei3p2Sk!1?) z?t!l&T_uXNdIV`TSWXqGN(7enI~W03Yv6#64tL#ADUj$;*J15wl~z+isw=Wim1wXq zMGDgb)Lg{uiqwi0=`sc2?t!<}EggxXqD5L-9IzZqM@j^o_B#@R9>)%R)8T`zbX|?Q z7?>(YnIduls@!4}88Pd?8!)7*goq5;qE&8b#i%ObM8ycEMGJPBqQ}Bib0W4s0y-jK zTE>yP?ub{JAL96J^krH6PPC5d1nW)&*rt6H}mT1QK*&QhzncciW5(pJ^R0B)_W%&vAtLyxcx zfV+B_02_`#k7Eb=b@-s8tLCKlb*}*B2myY?K~cdG(K|A#SS_mcsz^AItvc9x`CaW= z>pd#(QD=|Z5^Tc}&=CO*GLGDJN2Ibx-?`>&`dL84x5YYDQoVPiHRsZz$`vWonp5T} z61~`ki5_9%%(}p*=zpr-Ap$*)9ScL>bx@c@DFSCm1Z1s2V|8@6>yAo+Ok?K^$&J*^ z&JpNw>_CYQpEPzlhcrpgkO=6AkkNsnyY7fo_G#>#A-R#7**O9|jvWh2W2bXSlk^OU z00xB}7ogpB$70ghIYV+IHM4UBXylmRgo1X*4wNViV<&AX0x1GIB4l)=v6E6FMWDwB z^f-1Rm|cbvog$DTAQ5oS+0xia5l9i}8Uc6gq=_X(AVr{a1TeDF*y%dGbdF(?o|zG- z8#_H-JtbI*K#Bk&V8>AkNQyv;K<^RIu_I@3X`dpHBG5|&FvQZ>=_ODJlOhmBAdQ_U zAg6Cp&NNP6|4%#5)7Uxfx~$G&89Uh50TO?6BM^-pjlbIkA{7TLQo&U~ows#Jt5)k; zCg=_hXcbG?>dLoFSEq~Y!0f6}tw4!@Rhtm51}k#$mf1nAg(Z4ZB7kVy>z%IM2Y}d( zkir+H1=Km|A|stvj}?J$i&jD@dwUl;|U72q6&P7rf)~W(5$I`uMQ;bxMs$0hry@?S(oHsmnY)^rXda$#T+P_Lf)s-)V-78W| zD6+FfTgz5aS_!MC15-p6U^$?zdn&TbIzv_`Fj3LfU@?}it8PsvdSekloHsUhq=R%X z*0l(tvp<3a#v*NX1qjB9lp`iAQaJA3!d%)iRYM1+h!kLppsjBz>Y!Hj0AuND(Q0-T z_EKFdCSt=8K%7ry>_m2@*K{9AZBa2oh^UU%iV9EyB1GNe{c1!?Po?(C8}pr)(%2;=%6RZqoJj{xG_&sQLNLmo&3nF&Zb?k%XIbhj&!RhW?cjjSa`1h+x3zldf?hD9Q%xvgZLN#$Y*h7k zhONuuse`RoUA4KMyG&PA??|_LV%9|ffvp=mQI%f0pcjm&6{PMXTk9%zHL6xXtV{Ej zg4L_8R@?@~U?~Do z1Z3>sv@LBZ0x1G10x1G10^1XTpS&;x{0;jvfcjX|N7yY?bepRz0b%0ppR}n z;KOUQ{|6uaW?%VjKKgbaeZP<1t) zdb^8#lc)B>KK51@>jtY;GbY{6YPH_)YX0z~>$00KAO7$MTyX1~ebs)_wpv~~K!e+R zFz73cijUqi^@ox2+3ZeID{wPv>Z}h=eyI|jqqb~NlT*bZ<-|u1X zcGbEryxD`^;3;*x+6~w{J)LeJ-{c{^CiQOIZToFrgKqPTyA8VkDi8V&PwD$S0W-7VT>lE<( z_+5FW+llvI=WTc1=Wg%tu;AV0qVK!Shu`X>Z}-u+tqWb_$zfObQD5~@7ktbIzt#o& z@jLEf-|i|t=3>9s!`|gW-AKIIgMOQ*)a`0FVBh8GbbIY)59u|jcjI?@DqZ7lGP(`A z&(nFG-=!|p*XlZOoj(|StlO^p++fv>Nk3QW2C$#pZob@ipPL8QUFQemz8Xia^U?wN z=?CPx>%7$M0QWobzU$rXZTGm_oi6zL>ucb*`S4p^-S^a>Z(A3-#*-tiC&zu&$JYbC z!3Fznyxzrrr|X69#JfD~+g!D-3%7gFn?0p>dPp~5Z}*UHuf5JgdQIxxxZ8HuxSL*X zgYNO%tjTc~>T7i!xZWQOKGtp5J#Mh-#-!U>*I)m3F9q(o$4_oIU+%f5MztS|d)$sg zG`)0ybACXszuxz|7VZv;d+xc(-R`*C-QMPcZ@Q@lewz=!)zy7>4f?iqp=&%j>U#2e zU-j!<@Ed&ax4B^7jayvoTV2I(aIx?3uy?pn*M-|X=<7VCZdbbj`%X`%+iPx{ye7FS zUE^-sUE^+gxjOIm8dQ_xF4WiRI&hOe7<{bTuDjh})s4w@f$#Q{+izZ-A2n#V;}A_R z9gv@XKyJFpOWh7|Z%`cbx9_;i-R|(w$KL9q@4C&0-?}dJZRUQa!UfYlPT3rW@xxUtn93Sfj>sZa0To>36#4$Ht?z*c+wI7VT+>S#uy>vi+`oTMP z%uC%4aJLf)?`=!1mBm54f7rOVaq-Z_L-{L;mE%!x2J!FY$>-tU^I1N0-V2|@L}_h6*t1aiN&PT$Ul$d?CYMn z`K9HV$t7rQhR>I3OOp!}M6gD}7Z7W5l>#!qxQtjLm|rNorG=TfCUHi>OA5{~adw3- z63+C@YnWamXW~Ru4Ml&EQsfByy z=ckt1lgsmqh{aH2IGiv1iI!!LgbRedwA@-=VdO5#d(yDnzKjCY*cHA~7}BLP`&xV0 z)F=ic1M{Fz!y2REt5u_ffZ4n0?PZSq-uC1r+}N>jQG}#eH^#%uh25T-S!UpPz{|^8 zm((?f!YeY+Vv9o$&es?aX=*mY#loThP0ugxYf*ceO-umNz{N|(hKMtaSE!Z4`bR<| zgw@u<(&`+du!;_vUs;@NuU^`kU7?KK6?R)W(rI67ZYmQGH+S!Dgt0PUZh3KjHm^U_ z90}uAzI0$;JFkuygjWUXM{F+*SH0#9m|%ErIqRk2^@op0X&{_+>C)<@?Zu^;`MFh0 z1M_hC#o;W96LsdyWVrBa8W$ldsD*jytkr$fldE}GQN?gRM&9{I;Osn!U~zP==zm|tF=-v{9s3;%sd*qS>4 z$uvt^nPg&q5%XQ{2*v~)nJml16J!BIQ)N-^$`E{+#e4G7woIq`G6ZL4u|kxj;>-}d znGJg~(enKK?DEXQ61=2|d^XHvg6Y`<6XZMQ4{*Ohx$~{%)qN|d!?F>`E-70Xo?^)u zB(s@hFUBrT>gf<22f3k&Fd;!}rFa~Ct&{NhY|Zh3X@{Nm-|LX#B;__v#)#POoA zT&{+kS}s+iWU}?Rb1n)i^UxdGyKxqAT_l>soF%eG!0AY-8kP`F$$!kYH-@uX)0eF- z&+NlchirOgaf#bBi8kFE2{C-Z-l#aW@%<(W_D)zfW%F3qv3rKt~EK?o^5laSLf!JXQmHW`@6&a5neihPcCG> zfc3HPfQ#DSn#p269^UUFxHaNhEBrtVX)Pgmb2x=4LN*aT;GvL_h=?ef3?Gaj)B)L| zE0C%1gE0g#SYDl+onLCNF3c~i(Bg%bwZjj&z{soV@SqFJ`hRkH=2CP7tHfE`LlJg) zVs&Zn{QlLc#rcJ)`Tdd{IAQxxgxlAiTM=Xny^oXOeLQ$4aT@o-5fqs@JCAebiPqvO zjn>tyK{&JfFWsP1nFAx?MhM(f=?FjD%4WUBbod#O@ipPX0*3hVEQbXvS@@+wHZwKb-iPZ2ItfQY z<+yTp5b))iy39rlztXKZJ?@u>wWcM_89v`C5m~jD%k= z#Pbv1kSQrnTj0vB@EZk&49(Da2?V3zH+c!5(@&gH?bL z9X=lMaiNP2gF)lqXoyl7~9zIdXR~DvPxcuc%w89@00%{wsP#3V`Wi6Qq ze`v&Qtb(}m=gF}#G#UP=kRi6KazlXCPK7@%WcwCZigmVuS?f<@*=)PP?m+fuRasMH zjqu5;Y*=K?@Tsb7L}bI^&#SUsA{z;xuF6J5wk!Pas%*E&M#EoJWn&`S9saT^8yDGF zSgXp=Y6=?WmA`U?S!7z_uN`3)nu+i?jxdYOWcXW0m<4Al{GB7rqSFqaafDfTro-Qt zh54M)z?||AETRi(EQIYApT{+Dsr*k79~Xa;O}J+MKSqWegq8cxQ-rG@q+Zh46u*V|{&StK`RvAxj7 z#XNNv?t7h85@c6Vkc@|cLb8N&qRHi=p{;OsAzYc8nip*o;W-6+v7NIg!*iL9+i+OV zbqX6E3NNty*5YDoPA2BYa3j3X$|hS&lem+|W`>*L94lL`qRxh$cnmv2F`G2CAJd}X&U%fKUz@CD4JC4;Ul+H|+FO}EXyu;5dt z^0gua!{H@`U}Y&=IOwL@7cn2F!gR}Ml@yAqUEzzhhHys1mojInJ>9}pvcc{SU&a!? z-$IKrSJ*Wa2ANIM=xV`kgqJc~?&_>g!!+YZhr-KPFpq%F%q`I=V7A`iZbA5Jm2nzT z_VEnc#G-RyS%%i+A#dUy;YE>jFZJ{43{YgZiPiJvWd!c);VOH1rkxoW3IA3BP&`pg z#Z62+uPDp(%&CdNI&>CaDKBgIlF;*qesBEEcne%}noWEe~Am@CJrtSA@_9ATZcl6v1H=oE7A`F^+_v zCqemUohwp;8*1T7E67jyr(yQ0l7O16wVL7Tl8~CJ!r^d@6_Ud;H;cuQ zaIF=S+g7|Q9I|3P$(+WS>T9e7H-2%$LYjdtzs|~*aWOla<-;_3{k4T~AMVubotfqJ za2o6Iw-lnO_R=MEg}$^jzsQU0^i(TcU&!e^m`;%bI-H`)gB>X3ffJ@n$D?=NIUEw=?geVvdZ;iwz!$x+8J0dCWJZcY(jD_!v#LM%V zB_reEZG{xql5}E5cOvKp2ph*^neQqPyjIhiDY8a*M3F!ekaEq|k`cGUeUUi3PBfT_@a_Ub=X*vr8NRQO zv2mQn>5V6NJ{8_m0QO;7qgLVkiXWbF+uGs11!8IjCo)Dj9o|<6<*Bfhj}L|W3pt;D z$#XTMW4sX_C@_4JqNJi3-d~9M>VovNrsZc^sY@v-nw6++kfbeEO8czis3s2;L}b6kP7 z!Vl*#IzN}Whk7GBZJb*s=%{3tePAEY4KEew2Z)G`uyRpAll*Q z3j`jd;I6iuh)>h4oDat`bPZiNL)Zwv7zZD2vGc1jV9yHQqJ;WZ__bJ=57|azB0LrgvwL@_IT`+EAL-_qdo<$v#7B0x=?hjRoZ;}TERjj?9@iHaw~zeHl1Kz07a4Ee8-ygffHezn8NLeyHsw50t! zF%-@k$nM19_A1G2KTkBmKqRL5bAE1CrkjaoI6IOfyXL1g@)N`1IT3(o)f^o_ImY|m3LHKBrBz!#Ol?R^V) zyJB*Fc4Z%4g_C2jN2#KP{e9aH~2*9?(pRmoTF|md_@^n z#K)#<6N|=R8A$Pl?dADpIkRkzwZcowkol>J$@tv1i3Q{QGK}74a~Fl?*krh%j9r?; z3r%}5VOCa|CazUqRtD3|kF|;~+2;6NI&@w;d}SGxB~BSN9lolJLQ`>y*Fx506Lk|y z$yb*#h%a8lpff?oJzU3LScY?WE^VUQzHtQ)jiuwp@ob?CgXM+!C4Q+0*K?wuM{si- zPZ`Qsn)f)fJO}W|p^WAREid9K3NB~ncZFA!LDZ<}cAn4Uqv31H@|ig#9kOP5mD(;5t^OQxX8wR$t*;ZVK~PwtxA(J$y6B4B@0LwoH)+_hR~fR+|Q#Y!#7j_7>k*7I2@@+v)lMhyq{0ee?CUKm|& zP0*4^KRyuYPg~o+>EjC zu0llT*VzwrsM>h=?n1`*0>H&7>pcZm{5H?;3DFGyxj;w@9y5ie|fZz1KA$n4iu zBpeCv&V}^DBYsJO-;o#|8sEJ;ytfeImo;;ET^B0HcaMel6#{<#i>KK*J!Ii{xW5qY zj=H}_;)XBvqsn!fXP{`zmM)aE|(l{JG5R2MN`&l#+ zJ{XJGK|D42!AP)Ql#PZTiUcG3TijyY?s%{e(KBL|;HJ8j;7J|53bH!KPT-dNkGN9u z5I5U@)D^-T%o9W5$2=+YLf8mD?g{r^%F<@|2~R3|hr`33kfH{~BjFKO%EDdYCtaZ^ z9t}U`N%_?wQoTF;v?s@MvCP`X!q3F=c|6Y4`s3l}Jb7LpcbXsdxMV_})9)7L(G+#mNchDhu#iWX5lmB}>Z( z=-D4c&G1Ad!Yd0b84kZ)NS1K({E{}k2!lE!;dcrNt~T0>n9KP0guBB3DkMuSIw7H7 zm7>mQc(Rb-1P*7;6L|9tKiz~doQP%n_wp|-X%YOrSVmVOsMQR=A4~AVM4V?qHXJ?{ z%O?1TaP*Sx$79ifHlCa8r+T}>)3K0#Jvg_Fll2DL@QGMDc>s^UAle=NAQtUe#5@7f zSop(OgkP@hUC!m>;g4eZ6s`iKl}O+}_M~}Bk-~rC$+OlXi~lqhvvFEs$Z@;|@@FxC ztQW1uW0FsLh^*y!K=P?bEcr-JNB+E!EFHl8-F@8g$S!(1^65fIHTVn!4;>oeFO6Vk za+w~Df!_>k1wa13IZd-6iT zcz8|>;I|mE7uleq6`mU-X67QyM0j3|5kz5VGCV(qw?7hwxAqCA-3TF$g!2`KCajX*9ej21ROihZol(3O!@t-xMf3 zky*hrb8%xld|n}$nCCaj5XV;d{DM7$8*=inp^XQXUr-1LZ-tZL3k#vFCWQ}E;U$HT z9?IbtceG03^^pADZM)G9UsMN@$$&;8-go=rI#fR935N%wUsB*Q2~O9u=T>c8j(llZ zj!P9>YV-RX93DIg{jw?|zhmFVMah>}#qw5))E^07Q3d30y$EDi7_36Fw?ol}(eTnj zEECGY0{!R~vaxW!BU?2uO0{u4azTNiK(A``R(M%eRIWV{zOsO15iAr;hOcs^WgS!D zt1Bp35AvTNP2)Y|aA5(GAFG9Jle;)aEZ{)|uVIrdyksZ88Jce68l~YP=tT>*GBy&L6$D+t(#yVrz-eX$ zLHERqyO(X;jUOp6xX&l|_NQ_Ghu(d|(-MB9*v2!#-4;jpYw&|?nV|4QaI7T6jh$(E zxG!1E?b zhvLC*8@GjLEQlI|JD40@b_REazrh0N;WEdLUqmkAJ24V2iE&U=bTe)W&ssqC{22P^ ze#F&f}J~ zh2dvn^lLD>hmY6zakavq!@$#3+^{~IK8u3il)W^(?$FVr$BtfOzOZuDO^07|)eVQQ zzXd#eXGOlBlEcFvpQMV|K7%h*mA?`7Ys|Obh|2$W&=fDGrM}fS7zk_uIrGxke$_=n`C|rv_v?sgrEiC(mtSQ(!hVMIE%=<&oc@4fF zaWMMAmaUO%p)YFnirddEI*1yFV24_B6m|~5>T40XB34rzt4s0S7d*AVcWuUDfl3GQ z$&nlJ=X!4OzOa;W@gpbbz`BV&o?hV3Fh0<85RteU*c-xYVC5j&z6Ryv90`)XCcGi@ zCH6pis~l7Mrr2TBC*KG0J)<|^8$YA?h|xiOBaC|LT6p$)mR*9f^a{>@AfJKMS|;wr z{Exm9gr8Z#cPby`K0OF6q)(#MU!GBZ9>t$y_;(F_F8A9`MeP{;xQgRN`7P1A3SWLZ zj2@=ZK)rU0diy!ZwA=66WR($G-LAW8Zq{=4)Piuyyp>Z zNq;^l@yqT*{?*wOSvm*cyO?WS> zGx#|PezISd4u^j(q{HD~a%mACzS@yj)Bm+9rH_Bm`y`*PikA74c_&#wbTfqKltuxi zGVWA2Li};Me$U%gOj##S;*K)Dg2(U5&`$%}^dM%5CohuHjpOXQmbg16Pj8+LWA*`V zyVttYY>NItZV0AQe5^G4ASit?wcm5^qr6bq&uh|n=M^Md8t_$ytUdaH(|&K%Z*ZgN z&5Q=-qYVwN)2kOhQ#XoE!_NCBZVO#t<8{y375cWU&VrVU`5zl~uH_CZ7Y|$L3oYeu z7597QHqN33;XAN+ZNPp|x!?UBSHDNu?`)~UJksx;|2y@3+EGAlQ~Bk42Xe>2-c$VmYEI!_@ooOIGF>mkckyNW z=Cg4f3iip9&&9uMnQ8w|fs65F{5zhL%U@HG|19c1h40;;Jb51eiGKKi8nXQ?4!?u1 z)=%O7>Jskn?ZG#hXYg+t_ih79D=3kSz8F2n7^!DwC~j>^~6-iIz`R`%G+a5^9LR4AmOl4o-={ng%ijR{Ko?)PoAxQoM-yy zL4240^A6^6v00MiKHSG{&*h@u$}hwK`M|q!xumw0zZR^&c=uVEeGE)&RzCdx5N>{7 zE`MG{emOY5+M>Ipa>tbbL&pD4jUtW{B$qp>EH~|c2^7rUlFRQPaVb6|f6H&@^0&M4 zpZ^+)9bxWt<)3+LF2AcHzxTxh;T324dz5y$6qfV=}k1A!OO%DQ~*mq2#}oe(A24h#sgWO3pKHuFkyoSy#upZt0HJJ{Fg%Ggn5)X6(M_d(O)K*utcFH{pV>l7jPHW#k z(zDU8ImBA;im%|XSl4m(@TdwzK=(*|J`B^N@b1GOC8KSLS1!a2XQFvee9$T$ zizhF1=W?Q>E0Y?%;-?BO?FEb(*5I2~@uzI=pQy$8VntkUbG{=E-Pi12RL_Uv(+wT8 z`%fLM+Bf&q#;)erq2Aik`#*(VH&nW%(tVv*^`xb?tiV8eKP&T z=+E?jspFd z5UvXTt#H>;J&rX&Ya{ZK{0s$mh3ieh&ASnw6S`m0+t7je0d5x6|Fmf5|1$v={=tj4 zyrH_LhrA>|gRc}v;Ot!Z_#o`GGK?Ab^@@L}JjEVzyn2akmyGTZV%)Pxi0^H~2a%{FY$dVGSvxiIz_y*pjPX7dQqXY_HV8Qs$L zQLuN+&H}2B;htw-bJA1H5aJ z!fVCfH3HY7XtZHk>p=B8`eApt2DJKvIx4nQ)@R7-bfne-rD%4rYxu;QdKK_8*!o>a zbe96J#7{2I?_WQfcH9e6ZbR4}Jm9+p;lV7K?LI#0bWB@#GyWyIePN%Buncx)})@@l?=gRGI^3pj+Ued z-jZpO7*9Y7A(5ISCz2j}6Ku~2)2Ytf9oted=}q4kI^K)Q?#WQ{%Mdw-u7&2NxzV$^ z{%(e)bFE{p)ckC=7rJ07!P0LeZ6yBTLK+tnJ^fw=Doo!h?9dR%A z3SM8@d-Isxf{PYsI)1Z&p%7PCiZ+X(qQUhnV5A8PP12^FVI6xE{|T!UIWnQA=hDaU z+?mdY(%b0h4`IgkR5B}y0JlkSvX(=x@xH(69;?otpX;@ZEyWzpC~-oqb-zj|+mRr53R!u!+sr=bqL-2HWp_ zh8?4cdnGUX_)U|V6Vhbde)fgoOO22F$Q4bl7 zhhvfw>SAe@=a$nE{zNx=&vU`!8F!pJeaqA0)T8%~X100a)HG>5-WiE}M3#s*)Xy#8d>-Va%YUTRxNt`MJVF*> zF^Gv7TGZxo5}#>?j%XmW-{E^E8mI6zbE@OYAsQxYjECmb8?p`THMSl=6YoyUcs3&1Cq9F(&YFS9a4u&}vu>cq z3Ze_aZ!z}|y2kz?hH|WPI+n6U3KvfcpYWGiA$XO|yw+@!?yGO)OvEbjxM=5LQCz4_ zDlH#tt#Ddi#EY;(j706qV)Phb9;c0%W(?_k&n0&G?rv%Lv~NS2Hi4FSIfGPemO+c+ zK_Zp5#@B7Icc53acFIx+`q;X)^I?t$_nh2{V>Mwn#2WV0vPm8DQOw@3`M21YK1BcV zXDqhES~<4ho~RwU{XiwruS%cf^B|>MGnPh?&=waoU)DUATtbhE8>`344{#Yx%|b!j zJQMys_I=-YY4$-}zY{gKwVxPUhO1a9@t6a1koY>86CP=8h1p1Cnw5w=LW?ZPS6fch z8k)MNxtj9Tp62V3qz+Gp=};o2;FDQmHf`BcXqGT9^mZ!U@PO7OJ7}wEj^iuA``hB^ zxaI*YF8>TRyYcU>H zH1G{adBa<0?Ss68PLTEZ@2m{}CTsSzAN?Y)>NLbJ$eUm_gq4MTy_3TkTe23Wuit+! z$%5`5UVkd7kItjl{EclvX>FsAIOh8AL~OD8zat297~*rwugGh8&(&++tcq+0dk?RO z$UG|xRM%``VJuGi7e;5tK^&k$p!gRAo%*^3q< zYlN2baH4U2RgdT)qEXct8xC_mchMZcIwKu6)&D&kt6lg2o!Zrzn9(4%b1bAd@Ms0^ z+W02b&TsmSGp-HQC;QC-9b=>?U@q37ynq+hS z%+L7@&SAMZ&qh7#y_HLHS$80;cdu!16DgOE#H>Mlyfd}zmZotgI>%%n+(iTj`JQ4a zLL0Am&hJOE7|@^C0_3Em8sF^-#*^#ZQL<>sFSNKjzSmah1757|t6DelepMbG6u~z3 zOuUpT)h#)Pu?Dvyi-f!|G9!VE*7EgJuf411tBS6a>sv%L?bqM2*vV+^H zBh7u!F-~U_St0YXTFH;I)$UXh+@9aSre!t{@3nd+n+%RL1LF}UW>lK5d)GbvX!K3J z1NKoI^;evI9Gv+P8$;TW7jDrnBqdL(sQ||DB+D7nK5z1KyZE!})@2jJ5p|iesU=!v zv*esmKZEZkWB*~#ZKvkLh7#zScTlYNeOmmg^RNQwQ9;j@`W|~IRs{)I_8k*{k9~1N~eNVEK=m$8W2C7B7$Mt8hgw^Q8iWc7>KxcRw8)jWr@ zYOT>~4DO0d*CF$_%6w1BkEJiFy?@5QSonS4NJAJwL^lv61ek2*` zI|nr&hL_27L!S83ZgB@D+C5E=zsB6da^;y5IufqyY{;iI-EZ)JdHVo^fss$_|GVjx` zIn=jNM~T@RQ-Uo2)8I*CkrA)4$Qu?iJD_)h)nfZs*e`8+GUB%eIzuovylr-?@U4Qo zYccL0Aba61TefTkR_V#3;;Sm7Lp_Y6e!uTJ)Im{>Q;^q$e64$f*;}3o7JGTCw{mMf zU1>}sb-rfIH%!PgYOBvykYFvfPG-u_@@B~YWL?wuQrCTnhn3rMc36x9jW?EjRs*5K z=av*0^rz{* zdm?XN#fd#pk{xSA6uyX(^Z=TOy0)JI>afR+*$r=yw_@KSh^yi3 zSu<{N8^pMTy{t$IvMlU5IcKzPGlP8{)%nXCdvdKMm7I86nbsLz-9=xo;jL))% zCkKGYq4P8OiSr=?*Go9_bLs252(Z_4&dRar?c}BPcc~oc1y5=+?3D3*PGG3l^2?g7 z!@jUK>iXcrq>@w0X<@j)Lml03=ADN6@LmSLp6PbBeFbYY zZ`bH>Q_pskx0}7#QCbfkUl??+)8QHPFx^hOnRkf{G9J5o-?9$kDlamX zg$7SYdcN6*^ggPoKUHk MB->RsTISz>0dN}j@Bjb+ literal 0 HcmV?d00001 diff --git a/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/ArduinoFloppyReaderWin.vcxproj b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/ArduinoFloppyReaderWin.vcxproj new file mode 100644 index 00000000..121242c4 --- /dev/null +++ b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/ArduinoFloppyReaderWin.vcxproj @@ -0,0 +1,269 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + {37EEB775-8CC2-40F8-A3CD-40C955E11F0F} + ArduinoFloppyReaderWin + 10.0.18362.0 + MFCProj + + + + Application + true + v142 + Unicode + Dynamic + false + + + Application + false + v142 + true + Unicode + Static + false + + + Application + true + v142 + Unicode + Dynamic + false + + + Application + false + v142 + true + Unicode + Static + false + + + + + + + + + + + + + + + + + + + + + true + $(SolutionPath)\..\lib;$(IncludePath) + + + true + $(SolutionPath)\..\lib;$(IncludePath) + + + false + $(SolutionPath)\..\lib;$(IncludePath) + + + false + $(SolutionPath)\..\lib;$(IncludePath) + + + + Use + Level3 + Disabled + USING_MFC;WIN32;_WINDOWS;_DEBUG;%(PreprocessorDefinitions);_WIN32_WINNT=0x0601 + true + + + Windows + Winmm.lib + + + false + true + _DEBUG;%(PreprocessorDefinitions) + + + 0x0409 + _DEBUG;%(PreprocessorDefinitions) + $(IntDir);%(AdditionalIncludeDirectories) + + + + + Use + Level3 + Disabled + _WINDOWS;_DEBUG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions);_WIN32_WINNT=0x0601 + true + + + Windows + + + false + true + _DEBUG;%(PreprocessorDefinitions) + + + 0x0409 + _DEBUG;%(PreprocessorDefinitions) + $(IntDir);%(AdditionalIncludeDirectories) + + + + + Level3 + Use + MaxSpeed + true + true + USING_MFC;WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions);_WIN32_WINNT=0x0601 + true + + + Windows + true + true + Winmm.lib + + + false + true + NDEBUG;%(PreprocessorDefinitions) + + + 0x0409 + NDEBUG;%(PreprocessorDefinitions) + $(IntDir);%(AdditionalIncludeDirectories) + + + + + Level3 + Use + MaxSpeed + true + true + _WINDOWS;NDEBUG;%(PreprocessorDefinitions);_WIN32_WINNT=0x0601 + true + + + Windows + true + true + + + false + true + NDEBUG;%(PreprocessorDefinitions) + + + 0x0409 + NDEBUG;%(PreprocessorDefinitions) + $(IntDir);%(AdditionalIncludeDirectories) + + + + + + + + + + + + + + + + + + + NotUsing + NotUsing + NotUsing + NotUsing + + + NotUsing + NotUsing + NotUsing + NotUsing + + + NotUsing + NotUsing + + + NotUsing + NotUsing + NotUsing + NotUsing + + + + + Create + Create + Create + Create + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/ArduinoFloppyReaderWin.vcxproj.filters b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/ArduinoFloppyReaderWin.vcxproj.filters new file mode 100644 index 00000000..e17fb4fa --- /dev/null +++ b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/ArduinoFloppyReaderWin.vcxproj.filters @@ -0,0 +1,119 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Resource Files + + + + + Resource Files + + + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + + + Resource Files + + + \ No newline at end of file diff --git a/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/ArduinoFloppyReaderWinDlg.cpp b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/ArduinoFloppyReaderWinDlg.cpp new file mode 100644 index 00000000..95254723 --- /dev/null +++ b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/ArduinoFloppyReaderWinDlg.cpp @@ -0,0 +1,850 @@ +/* ArduinoFloppyReaderWin +* +* Copyright (C) 2017-2021 Robert Smith (@RobSmithDev) +* https://amiga.robsmithdev.co.uk +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU Library General Public +* License as published by the Free Software Foundation; either +* version 3 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 +* Library General Public License for more details. +* +* You should have received a copy of the GNU Library General Public +* License along with this program; if not see http://www.gnu.org/licenses/ +*/ + +////////////////////////////////////////////////////////////////////////////////////////// +// Simple Windows application using the libraries used in the console app // +////////////////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include +#include "ArduinoFloppyReaderWin.h" +#include "ArduinoFloppyReaderWinDlg.h" +#include "afxdialogex.h" +#include +#include "..\lib\ADFWriter.h" +#include + +#ifdef _DEBUG +#define new DEBUG_NEW +#endif + + +#pragma region ABOUT_DIALOG + +// CAboutDlg dialog used for App About +class CAboutDlg : public CDialogEx +{ +public: + CAboutDlg() : CDialogEx(IDD_ABOUTBOX) {}; + + // Dialog Data +#ifdef AFX_DESIGN_TIME + enum { IDD = IDD_ABOUTBOX }; +#endif +protected: + virtual void DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); }; + +protected: + DECLARE_MESSAGE_MAP() +}; + +BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx) +END_MESSAGE_MAP() + +#pragma endregion ABOUT_DIALOG + + +#pragma region DIAGNOSTICS_DIALOG + +// CDiagnosticsDialog dialog used diagnostics status window +class CDiagnosticsDialog : public CDialogEx +{ +public: + CDiagnosticsDialog(const std::wstring& comport) : CDialogEx(IDD_DIAGNOSTICS), m_comPort(comport), m_mainThread(nullptr) {}; + virtual ~CDiagnosticsDialog() { + if (m_mainThread) { + if (m_mainThread->joinable()) m_mainThread->join(); + delete m_mainThread; + } + } + +public: + CEdit m_results; + + // Dialog Data +#ifdef AFX_DESIGN_TIME + enum { IDD = IDD_DIAGNOSTICS }; +#endif + +protected: + virtual void DoDataExchange(CDataExchange* pDX) { + CDialogEx::DoDataExchange(pDX); + DDX_Control(pDX, IDC_EDIT1, m_results); + }; + + + BOOL OnInitDialog() + { + CDialogEx::OnInitDialog(); + m_threadRunning = true; + + WCHAR buffer[200]; + swprintf_s(buffer, L"Running Diagnostics on %s", m_comPort.c_str()); + SetWindowText(buffer); + + CMenu* mnu = this->GetSystemMenu(FALSE); + mnu->EnableMenuItem(SC_CLOSE, MF_BYCOMMAND | MF_GRAYED | MF_DISABLED); + + // Main processing thread + m_mainThread = new std::thread([this]()->void { + runDiagnostics(); + m_threadRunning = false; + }); + + return true; + } + +protected: + DECLARE_MESSAGE_MAP() + +private: + const std::wstring m_comPort; + bool m_threadRunning = true; + ArduinoFloppyReader::ADFWriter writer; + std::thread* m_mainThread; + + // This is ran under a thread + void runDiagnostics() { + writer.runDiagnostics(m_comPort, [this](bool isError, const std::string message)->void { + CString strLine; + + if (isError) strLine = "DIAGNOSTICS FAILED: "; + strLine += message.c_str(); + strLine += "\r\n"; + + // get the initial text length + int nLength = m_results.GetWindowTextLength(); + // put the selection at the end of text + m_results.SetSel(nLength, nLength); + // replace the selection + m_results.ReplaceSel(strLine); + + }, [this](bool isQuestion, const std::string question)->bool { + if (isQuestion) + return MessageBoxA(GetSafeHwnd(), (LPCSTR)question.c_str(), "Diagnostics Question", MB_YESNO | MB_ICONQUESTION) == IDYES; + else + return MessageBoxA(GetSafeHwnd(), (LPCSTR)question.c_str(), "Diagnostics Prompt", MB_OKCANCEL | MB_ICONINFORMATION) == IDOK; + }); + + writer.closeDevice(); + + CMenu* mnu = this->GetSystemMenu(FALSE); + mnu->EnableMenuItem(SC_CLOSE, MF_BYCOMMAND | MF_ENABLED); + } + + // Prevent Enter and ESC closing the dialog + BOOL PreTranslateMessage(MSG* pMsg) + { + if (pMsg->message == WM_KEYDOWN) + { + if (pMsg->wParam == VK_RETURN || pMsg->wParam == VK_ESCAPE) + { + return !m_threadRunning; // Do not process further + } + } + + return CWnd::PreTranslateMessage(pMsg); + } + +}; + +BEGIN_MESSAGE_MAP(CDiagnosticsDialog, CDialogEx) +END_MESSAGE_MAP() + +#pragma endregion DIAGNOSTICS_DIALOG + + +#pragma region COMPLETE_DIALOG + +// CCompleteDialog dialog used to show copy/write completion +class CCompleteDialog : public CDialogEx +{ +private: + void* m_sfx; + HBITMAP m_currentBitmap; +public: + CCompleteDialog(void* sfx, bool partial, bool writeMode, bool SCPMode); + virtual ~CCompleteDialog(); + + // Dialog Data +#ifdef AFX_DESIGN_TIME + enum { IDD = IDD_DIALOG }; +#endif + +protected: + virtual BOOL OnInitDialog(); + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + LRESULT OnNcHitTest(CPoint point); + // Implementation +protected: + DECLARE_MESSAGE_MAP() +public: + + virtual INT_PTR DoModal() override; + CStatic m_dialogImage; +}; + +CCompleteDialog::~CCompleteDialog() { + if (m_currentBitmap) DeleteObject(m_currentBitmap); +} + +CCompleteDialog::CCompleteDialog(void* sfx, bool partial, bool writeMode, bool SCPMode) : CDialogEx(IDD_DIALOG) +{ + m_sfx = sfx; + int id; + if (SCPMode) id = IDB_SCPREAD; else + if (writeMode) + id = partial ? IDB_DIALOG_WARNING_WRITE : IDB_DIALOG_OK_WRITE; + else id = partial ? IDB_DIALOG_WARNING : IDB_DIALOG_OK; + m_currentBitmap = LoadBitmap(AfxGetInstanceHandle(), MAKEINTRESOURCE(id)); +} + +BOOL CCompleteDialog::OnInitDialog() +{ + CDialogEx::OnInitDialog(); + m_dialogImage.SetBitmap(m_currentBitmap); + return true; +} + +void CCompleteDialog::DoDataExchange(CDataExchange* pDX) +{ + CDialogEx::DoDataExchange(pDX); + DDX_Control(pDX, IDC_DIALOGIMAGE, m_dialogImage); +} + +INT_PTR CCompleteDialog::DoModal() +{ + sndPlaySound((LPCWSTR)m_sfx, SND_ASYNC | SND_MEMORY | SND_NODEFAULT); + return CDialogEx::DoModal(); +} + +LRESULT CCompleteDialog::OnNcHitTest(CPoint point) +{ + CPoint pt = point; + ScreenToClient(&pt); + + if (pt.y < 24) return HTCAPTION; + return CDialog::OnNcHitTest(point); +} +BEGIN_MESSAGE_MAP(CCompleteDialog, CDialogEx) + ON_WM_NCHITTEST() +END_MESSAGE_MAP() + + +#pragma endregion COMPLETE_DIALOG + +#pragma region MAIN_DIALOG + + +// CArduinoFloppyReaderWinDlg dialog +CArduinoFloppyReaderWinDlg::CArduinoFloppyReaderWinDlg(CWnd* pParent /*=NULL*/) + : CDialogEx(IDD_ARDUINOFLOPPYREADERWIN_DIALOG, pParent) +{ + m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); + m_iothread = nullptr; +} + +void CArduinoFloppyReaderWinDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialogEx::DoDataExchange(pDX); + DDX_Control(pDX, IDC_COMPORT, m_comport); + DDX_Control(pDX, IDC_FILENAME, m_outputADF); + DDX_Control(pDX, IDC_PROGRESS, m_progressbar); + DDX_Control(pDX, IDC_TRACKNUMBER, m_statusTrack); + DDX_Control(pDX, IDC_DISKSIDE, m_statusSide); + DDX_Control(pDX, IDC_GOODSECTORS, m_statusGood); + DDX_Control(pDX, IDC_BADSECTORS, m_statusPartial); + DDX_Control(pDX, IDC_BROWSE, m_browseButton); + DDX_Control(pDX, IDC_STARTSTOP, m_copyButton); + DDX_Control(pDX, IDC_STATUS, m_statusText); + DDX_Control(pDX, IDC_FILENAME2, m_inputADF); + DDX_Control(pDX, IDC_BROWSE2, m_browseButton2); + DDX_Control(pDX, IDC_STARTSTOP2, m_writeButton); + DDX_Control(pDX, IDC_CHECK1, m_verify); + DDX_Control(pDX, IDC_CHECK3, m_precomp); + DDX_Control(pDX, IDC_STARTSTOP3, m_diagnostics); + DDX_Control(pDX, IDC_DISKFORMAT, m_fileFormat); + DDX_Control(pDX, IDC_TRK80, m_trk80); + DDX_Control(pDX, IDC_TRK82, m_trk82); +} + +BEGIN_MESSAGE_MAP(CArduinoFloppyReaderWinDlg, CDialogEx) + ON_WM_SYSCOMMAND() + ON_WM_PAINT() + ON_WM_QUERYDRAGICON() + ON_BN_CLICKED(IDC_STARTSTOP, &CArduinoFloppyReaderWinDlg::OnBnClickedStartstop) + ON_BN_CLICKED(IDC_BROWSE, &CArduinoFloppyReaderWinDlg::OnBnClickedBrowse) + ON_MESSAGE(WM_USER, &CArduinoFloppyReaderWinDlg::OnUserMessage) + ON_BN_CLICKED(IDC_BROWSE2, &CArduinoFloppyReaderWinDlg::OnBnClickedBrowse2) + ON_BN_CLICKED(IDC_STARTSTOP2, &CArduinoFloppyReaderWinDlg::OnBnClickedStartstop2) + ON_BN_CLICKED(IDC_STARTSTOP3, &CArduinoFloppyReaderWinDlg::OnBnClickedStartstop3) + ON_MESSAGE(WM_DEVICECHANGE, &CArduinoFloppyReaderWinDlg::OnDevicechange) + ON_CBN_SELCHANGE(IDC_DISKFORMAT, &CArduinoFloppyReaderWinDlg::OnCbnSelchangeDiskformat) +END_MESSAGE_MAP() + + +// CArduinoFloppyReaderWinDlg message handlers + +void CArduinoFloppyReaderWinDlg::enumComPorts() { + std::vector portList; + ArduinoFloppyReader::ArduinoInterface::enumeratePorts(portList); + + m_comport.ResetContent(); + for (const std::wstring& port : portList) + m_comport.AddString(port.c_str()); +} + +BOOL CArduinoFloppyReaderWinDlg::OnInitDialog() +{ + CDialogEx::OnInitDialog(); + + // Add "About..." menu item to system menu. + + // IDM_ABOUTBOX must be in the system command range. + ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); + ASSERT(IDM_ABOUTBOX < 0xF000); + + CMenu* pSysMenu = GetSystemMenu(FALSE); + if (pSysMenu != NULL) + { + BOOL bNameValid; + CString strAboutMenu; + bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX); + ASSERT(bNameValid); + if (!strAboutMenu.IsEmpty()) + { + pSysMenu->AppendMenu(MF_SEPARATOR); + pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); + } + } + + // Set the icon for this dialog. The framework does this automatically + // when the application's main window is not a dialog + SetIcon(m_hIcon, TRUE); // Set big icon + SetIcon(m_hIcon, FALSE); // Set small icon + + enumComPorts(); + + WCHAR buf[10]; + buf[0] = '\0'; + LONG len = 10; + memset(buf, 0, len * 2); + RegQueryValueW(HKEY_CURRENT_USER, L"Software\\ArduinoFloppyReader\\ComPort", buf, &len); + int port = wcstol(buf, nullptr, 10); + swprintf_s(buf, L"COM%i", port); + setComPort(buf); + + m_fileFormat.AddString(L"ADF"); + m_fileFormat.AddString(L"SCP"); + buf[0] = '\0'; + len = 10; + RegQueryValueW(HKEY_CURRENT_USER, L"Software\\ArduinoFloppyReader\\fileFormat", buf, &len); + int index = wcstol(buf, nullptr, 10); + m_fileFormat.SetCurSel(index); + + buf[0] = '\0'; + len = 10; + RegQueryValueW(HKEY_CURRENT_USER, L"Software\\ArduinoFloppyReader\\tracks", buf, &len); + int numTracks = wcstol(buf, nullptr, 10); + m_trk82.SetCheck(numTracks == 82); + m_trk80.SetCheck(numTracks != 82); + + + HRSRC res = FindResource(NULL, MAKEINTRESOURCE(IDR_COMPLETE), L"WAVE"); + m_sfx = nullptr; + if (res) { + HGLOBAL resource = LoadResource(NULL, res); + if (resource) { + int resSize = SizeofResource(NULL, res); + m_sfx = malloc(resSize); + + if (m_sfx) { + void* mem = LockResource(resource); + if (mem) memcpy(m_sfx, mem, resSize); + UnlockResource(resource); + } + } + FreeResource(resource); + } + m_precomp.SetCheck(TRUE); + m_verify.SetCheck(TRUE); + + + return TRUE; // return TRUE unless you set the focus to a control +} + +std::wstring CArduinoFloppyReaderWinDlg::getComPort() { + int index = m_comport.GetCurSel(); + if (index < 0) return L""; + CString buf; + + m_comport.GetWindowTextW(buf); + + return std::wstring(buf); +} + +void CArduinoFloppyReaderWinDlg::setComPort(const std::wstring& comport) { + int index = m_comport.FindString(0, comport.c_str()); + if (index < 0) index = 0; + m_comport.SetCurSel(index); +} + + +CArduinoFloppyReaderWinDlg::~CArduinoFloppyReaderWinDlg() { + m_cancelButtonPressed = true; + + if (m_sfx) free(m_sfx); +} + +// On Sys command +void CArduinoFloppyReaderWinDlg::OnSysCommand(UINT nID, LPARAM lParam) +{ + if ((nID & 0xFFF0) == IDM_ABOUTBOX) + { + CAboutDlg dlgAbout; + dlgAbout.DoModal(); + } + else + { + CDialogEx::OnSysCommand(nID, lParam); + } +} + +// If you add a minimize button to your dialog, you will need the code below +// to draw the icon. For MFC applications using the document/view model, +// this is automatically done for you by the framework. +void CArduinoFloppyReaderWinDlg::OnPaint() +{ + if (IsIconic()) + { + CPaintDC dc(this); // device context for painting + + SendMessage(WM_ICONERASEBKGND, reinterpret_cast(dc.GetSafeHdc()), 0); + + // Center icon in client rectangle + int cxIcon = GetSystemMetrics(SM_CXICON); + int cyIcon = GetSystemMetrics(SM_CYICON); + CRect rect; + GetClientRect(&rect); + int x = (rect.Width() - cxIcon + 1) / 2; + int y = (rect.Height() - cyIcon + 1) / 2; + + // Draw the icon + dc.DrawIcon(x, y, m_hIcon); + } + else + { + CDialogEx::OnPaint(); + } +} + +// The system calls this function to obtain the cursor to display while the user drags +// the minimized window. +HCURSOR CArduinoFloppyReaderWinDlg::OnQueryDragIcon() +{ + return static_cast(m_hIcon); +} + +// Main thread +bool CArduinoFloppyReaderWinDlg::runThreadRead() { + ArduinoFloppyReader::ADFWriter writer; + + const std::wstring comPort = getComPort(); + bool isSCP = m_fileFormat.GetCurSel() == 1; + + // Try to open the com port and talk to the device + m_statusText.SetWindowText(L"Opening COM port and setting up device..."); + if (!writer.openDevice(comPort)) { + std::string msg = "Unable to open COM port:\r\n\r\n"; + msg += writer.getLastError(); + MessageBoxA(GetSafeHwnd(), msg.c_str(), "Error", MB_OK | MB_ICONEXCLAMATION); + return false; + } + + // Get the current firmware version. Only valid if openDevice is successful + const ArduinoFloppyReader::FirmwareVersion v = writer.getFirwareVersion(); + if ((v.major == 1) && (v.minor < 8)) { + static bool hasBeenWarnedAboutVersion = false; + // improved disk timings in 1.8, so make them aware + if (!hasBeenWarnedAboutVersion) { + hasBeenWarnedAboutVersion = true; + MessageBox(L"Rob strongly recommends updating the firmware on your Arduino to at least V1.8.\nThat version is even better at reading old disks.", L"Firmware Upgrade Note", MB_OK | MB_ICONINFORMATION); + } + } + + // Analysis was complete and found some data. Run the reader + m_statusText.SetWindowText(isSCP ? L"Reading disk to SCP file..." : L"Reading disk to ADF file..."); + CString filename; + const unsigned int lastTrack = m_trk82.GetCheck() ? 82 : 80; + m_progressbar.SetRange(0, lastTrack * 2); + m_progressbar.SetPos(0); + + auto callback = [this](const int currentTrack, const ArduinoFloppyReader::DiskSurface currentSide, const int retryCounter, const int sectorsFound, const int badSectorsFound) -> ArduinoFloppyReader::WriteResponse { + + if (m_cancelButtonPressed) return ArduinoFloppyReader::WriteResponse::wrAbort; + + CString str; + str.Format(L"%i", currentTrack); + m_statusTrack.SetWindowText(str); + m_statusSide.SetWindowText((currentSide == ArduinoFloppyReader::DiskSurface::dsUpper) ? L"Upper" : L"Lower"); + str.Format(L"%i", sectorsFound); + m_statusGood.SetWindowText(str); + str.Format(L"%i", badSectorsFound); + m_statusPartial.SetWindowText(str); + + m_progressbar.SetPos((currentTrack * 2) + ((currentSide == ArduinoFloppyReader::DiskSurface::dsUpper) ? 1 : 0)); + + if (retryCounter > 20) { + switch (MessageBox(L"Disk has checksum errors/missing/damaged data.\r\n\r\n", L"Disk Read Errors", MB_ABORTRETRYIGNORE)) { + case IDABORT: return ArduinoFloppyReader::WriteResponse::wrAbort; + case IDRETRY: return ArduinoFloppyReader::WriteResponse::wrRetry; + case IDIGNORE: return ArduinoFloppyReader::WriteResponse::wrSkipBadChecksums; + } + } + + // Just continue + return ArduinoFloppyReader::WriteResponse::wrContinue; + }; + + m_outputADF.GetWindowText(filename); + + ArduinoFloppyReader::ADFResult readerResult; + + + readerResult = isSCP ? writer.DiskToSCP(filename.GetBuffer(), lastTrack, 3, callback) : writer.DiskToADF(filename.GetBuffer(), lastTrack, callback); + + // Handle the result + switch (readerResult) { + case ArduinoFloppyReader::ADFResult::adfrComplete: m_partial = false; return true; + case ArduinoFloppyReader::ADFResult::adfrAborted: return false; + case ArduinoFloppyReader::ADFResult::adfrFileError: MessageBox(L"Unable to open the specified file to write to it.", L"Output File Error", MB_OK | MB_ICONEXCLAMATION); return false; + case ArduinoFloppyReader::ADFResult::adfrFileIOError: MessageBox(L"An error occured writing to the specified file.", L"Output File Error", MB_OK | MB_ICONEXCLAMATION); return false; + case ArduinoFloppyReader::ADFResult::adfrFirmwareTooOld: MessageBox(L"This requires firmware V1.8 or newer.", L"Firmware out of date", MB_OK | MB_ICONEXCLAMATION); return false; + case ArduinoFloppyReader::ADFResult::adfrCompletedWithErrors: m_partial = true; return true; + case ArduinoFloppyReader::ADFResult::adfrDriveError: { + std::string msg = "An error occured communicating with the Arduino interface:\r\n\r\n"; + msg += writer.getLastError(); + MessageBoxA(GetSafeHwnd(), msg.c_str(), "I/O Error", MB_OK | MB_ICONEXCLAMATION); + return false; + } + } + + return false; +} + + + +// Main thread +bool CArduinoFloppyReaderWinDlg::runThreadWrite() { + ArduinoFloppyReader::ADFWriter writer; + + const std::wstring comPort = getComPort(); + + // Try to open the com port and talk to the device + m_statusText.SetWindowText(L"Opening COM port and setting up device..."); + if (!writer.openDevice(comPort)) { + std::string msg = "Unable to open COM port:\r\n\r\n"; + msg += writer.getLastError(); + MessageBoxA(GetSafeHwnd(), msg.c_str(), "Error", MB_OK | MB_ICONEXCLAMATION); + return false; + } + + // Analysis was complete and found some data. Run the reader + m_statusText.SetWindowText(L"Writing ADF file to disk..."); + CString filename; + const unsigned int lastTrack = 80; + m_progressbar.SetRange(0, lastTrack * 2); + m_progressbar.SetPos(0); + + m_inputADF.GetWindowText(filename); + + ArduinoFloppyReader::ADFResult readerResult = writer.ADFToDisk(filename.GetBuffer(), m_verify.GetCheck() != 0, m_precomp.GetCheck() != 0, + [this](const int currentTrack, const ArduinoFloppyReader::DiskSurface currentSide, const bool isVerifyError) -> ArduinoFloppyReader::WriteResponse { + + if (m_cancelButtonPressed) return ArduinoFloppyReader::WriteResponse::wrAbort; + + CString str; + str.Format(L"%i", currentTrack); + m_statusTrack.SetWindowText(str); + m_statusSide.SetWindowText((currentSide == ArduinoFloppyReader::DiskSurface::dsUpper) ? L"Upper" : L"Lower"); + + m_progressbar.SetPos((currentTrack * 2) + ((currentSide == ArduinoFloppyReader::DiskSurface::dsUpper) ? 1 : 0)); + + if (isVerifyError) { + switch (MessageBox(L"Verify error writing track.", L"Disk Write Error", MB_ABORTRETRYIGNORE)) { + case IDABORT: return ArduinoFloppyReader::WriteResponse::wrAbort; + case IDRETRY: return ArduinoFloppyReader::WriteResponse::wrRetry; + case IDIGNORE: return ArduinoFloppyReader::WriteResponse::wrSkipBadChecksums; + } + } + + // Just continue + return ArduinoFloppyReader::WriteResponse::wrContinue; + }); + + + switch (readerResult) { + case ArduinoFloppyReader::ADFResult::adfrComplete: m_partial = false; return true; + case ArduinoFloppyReader::ADFResult::adfrCompletedWithErrors: m_partial = true; return true; + case ArduinoFloppyReader::ADFResult::adfrAborted: return false; + case ArduinoFloppyReader::ADFResult::adfrFileError: MessageBox(L"Unable to open the specified file to read from it.", L"Input File Error", MB_OK | MB_ICONEXCLAMATION); return false; + case ArduinoFloppyReader::ADFResult::adfrDriveError: { + std::string msg = "An error occured communicating with the Arduino interface:\r\n\r\n"; + msg += writer.getLastError(); + MessageBoxA(GetSafeHwnd(), msg.c_str(), "I/O Error", MB_OK | MB_ICONEXCLAMATION); + return false; + } + case ArduinoFloppyReader::ADFResult::adfrDiskWriteProtected: MessageBox(L"Unable to write to the disk. Disk is write protected.", L"Write Protection Error", MB_OK | MB_ICONEXCLAMATION); return false; + } + + return false; +} + +afx_msg LRESULT CArduinoFloppyReaderWinDlg::OnUserMessage(WPARAM wparam, LPARAM lparam) { + if (m_iothread) { + if (m_iothread->joinable()) m_iothread->join(); + delete m_iothread; + m_iothread = nullptr; + } + m_copyButton.SetWindowText(L"Copy Disk"); + m_writeButton.SetWindowText(L"Write Disk"); + return 0; +} + +// Enabel the selectable items on the dialog +void CArduinoFloppyReaderWinDlg::enableDialog(bool enable) { + m_browseButton.EnableWindow(enable); + m_browseButton2.EnableWindow(enable); + m_outputADF.EnableWindow(enable); + m_inputADF.EnableWindow(enable); + m_comport.EnableWindow(enable); + m_verify.EnableWindow(enable); + m_precomp.EnableWindow(enable); + m_diagnostics.EnableWindow(enable); + m_fileFormat.EnableWindow(enable); + m_precomp.EnableWindow(enable); + m_trk80.EnableWindow(enable); + m_trk82.EnableWindow(enable); + + if (enable) { + m_statusText.SetWindowText(L"Ready"); + m_progressbar.SetPos(0); + m_statusTrack.SetWindowText(L"0"); + m_statusSide.SetWindowText(L"Upper"); + m_statusGood.SetWindowText(L"0"); + m_statusPartial.SetWindowText(L"0"); + m_copyButton.EnableWindow(true); + m_writeButton.EnableWindow(true); + } +} + +// Called when the thread for reading ifinishes +void CArduinoFloppyReaderWinDlg::threadFinishedReading(bool successful) { + enableDialog(true); + + if (successful) { + if (m_partial) { + CCompleteDialog dlg(m_sfx, true, false, false); + dlg.DoModal(); + } + else { + CCompleteDialog dlg(m_sfx, false, false, m_fileFormat.GetCurSel() == 1); + dlg.DoModal(); + } + } + + // Free the thread + PostMessage(WM_USER, 0, 0); +} + + +// Called when the thread for reading ifinishes +void CArduinoFloppyReaderWinDlg::threadFinishedWriting(bool successful) { + enableDialog(true); + + if (successful) { + if (m_partial) { + CCompleteDialog dlg(m_sfx, true, true, false); + dlg.DoModal(); + } + else { + CCompleteDialog dlg(m_sfx, false, true, false); + dlg.DoModal(); + } + } + + // Free the thread + PostMessage(WM_USER, 0, 0); +} + + +// Save the comp port to the registry +void CArduinoFloppyReaderWinDlg::saveComPort() { + const std::wstring port = getComPort(); + + char buffer[20]; + + if (port.length() > 3) { + RegSetValueW(HKEY_CURRENT_USER, L"Software\\ArduinoFloppyReader\\ComPort", REG_SZ, (LPCWSTR)&port[3], port.length()-3); + } + + _itoa_s(m_fileFormat.GetCurSel(), buffer, 10); + RegSetValueA(HKEY_CURRENT_USER, "Software\\ArduinoFloppyReader\\fileFormat", REG_SZ, buffer, strlen(buffer)); + + _itoa_s(m_trk82.GetCheck() ? 82 : 80, buffer, 10); + RegSetValueA(HKEY_CURRENT_USER, "Software\\ArduinoFloppyReader\\tracks", REG_SZ, buffer, strlen(buffer)); +} + +// Disk to ADF file start and stop button +void CArduinoFloppyReaderWinDlg::OnBnClickedStartstop() +{ + if (m_iothread) { + m_cancelButtonPressed = true; + } + else { + saveComPort(); + + CString filename; + m_outputADF.GetWindowText(filename); + if (filename.GetLength() < 1) { + MessageBox(L"You need to specify an ADF filename first", L"Error", MB_OK | MB_ICONEXCLAMATION); + return; + } + + m_cancelButtonPressed = false; + enableDialog(false); + + m_copyButton.SetWindowText(L"Abort!"); + m_writeButton.EnableWindow(false); + + m_iothread = new std::thread([this]() { + this->threadFinishedReading(this->runThreadRead()); + }); + } +} + +// ADF to Disk write button +void CArduinoFloppyReaderWinDlg::OnBnClickedStartstop2() +{ + if (m_iothread) { + m_cancelButtonPressed = true; + } + else { + saveComPort(); + + CString filename; + m_inputADF.GetWindowText(filename); + if (filename.GetLength() < 1) { + MessageBox(L"You need to specify an ADF filename first", L"Error", MB_OK | MB_ICONEXCLAMATION); + return; + } + + m_cancelButtonPressed = false; + enableDialog(false); + + m_copyButton.EnableWindow(false); + m_writeButton.SetWindowText(L"Abort!"); + + m_iothread = new std::thread([this]() { + this->threadFinishedWriting(this->runThreadWrite()); + }); + } +} + + +// Browse to select ADF file to save to +void CArduinoFloppyReaderWinDlg::OnBnClickedBrowse() +{ + // szFilters is a text string that includes two file name filters: + TCHAR szFilters[] = _T("Amiga Disk Files (*.adf)|*.adf|All Files (*.*)|*.*||"); + TCHAR szFiltersSCP[] = _T("Supercard Pro Files (*.scp)|*.scp|All Files (*.*)|*.*||"); + + bool isSCP = m_fileFormat.GetCurSel() == 1; + + // Create an Save dialog + CString oldFileName; + m_outputADF.GetWindowText(oldFileName); + + CFileDialog fileDlg(FALSE, isSCP ? _T("scp") : _T("adf"), oldFileName, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST | OFN_NODEREFERENCELINKS | OFN_ENABLESIZING | OFN_DONTADDTORECENT | OFN_EXPLORER, isSCP ? szFiltersSCP : szFilters, this); + if (isSCP) fileDlg.m_ofn.lpstrTitle = L"Save Disk to SCP File"; else fileDlg.m_ofn.lpstrTitle = L"Save Disk to ADF File"; + + // Display it + if (fileDlg.DoModal() == IDOK) + m_outputADF.SetWindowText(fileDlg.GetPathName()); +} + +// Browse to load and copy to disk +void CArduinoFloppyReaderWinDlg::OnBnClickedBrowse2() +{ + // szFilters is a text string that includes two file name filters: + TCHAR szFilters[] = _T("Amiga Disk Files (*.adf)|*.adf|All Files (*.*)|*.*||"); + + // Create an Save dialog + CString oldFileName; + m_inputADF.GetWindowText(oldFileName); + + CFileDialog fileDlg(TRUE, _T("adf"), oldFileName, OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_NODEREFERENCELINKS | OFN_ENABLESIZING | OFN_EXPLORER, szFilters, this); + fileDlg.m_ofn.lpstrTitle = L"Select an ADF File to Write To Disk"; + + // Display it + if (fileDlg.DoModal() == IDOK) + m_inputADF.SetWindowText(fileDlg.GetPathName()); +} + + +#pragma endregion MAIN_DIALOG + +// The Run Diagnostics button +void CArduinoFloppyReaderWinDlg::OnBnClickedStartstop3() +{ + std::wstring comPort = getComPort(); + saveComPort(); + + CDiagnosticsDialog dlgDiagnostics(comPort); + dlgDiagnostics.DoModal(); +} + + +afx_msg LRESULT CArduinoFloppyReaderWinDlg::OnDevicechange(WPARAM wParam, LPARAM lParam) +{ + std::wstring port = getComPort(); + enumComPorts(); + setComPort(port); + return 0; +} + + +void CArduinoFloppyReaderWinDlg::OnCbnSelchangeDiskformat() +{ + // Correct the file extension + bool isSCP = m_fileFormat.GetCurSel() == 1; + CString filename; + + m_outputADF.GetWindowText(filename); + + int pos = filename.ReverseFind(_T('.')); + if (pos > 0) { + filename = filename.Left(pos); + + if (isSCP) filename += _T(".scp"); else filename += _T(".adf"); + + m_outputADF.SetWindowText(filename); + + } +} diff --git a/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/ArduinoFloppyReaderWinDlg.h b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/ArduinoFloppyReaderWinDlg.h new file mode 100644 index 00000000..98480b5f --- /dev/null +++ b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/ArduinoFloppyReaderWinDlg.h @@ -0,0 +1,108 @@ +/* ArduinoFloppyReaderWin +* +* Copyright (C) 2017-2018 Robert Smith (@RobSmithDev) +* http://amiga.robsmithdev.co.uk +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU Library General Public +* License as published by the Free Software Foundation; either +* version 3 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 +* Library General Public License for more details. +* +* You should have received a copy of the GNU Library General Public +* License along with this program; if not see http://www.gnu.org/licenses/ +*/ + +////////////////////////////////////////////////////////////////////////////////////////// +// Simple Windows application using the libraries used in the console app // +////////////////////////////////////////////////////////////////////////////////////////// + +#pragma once +#include "afxwin.h" +#include "afxcmn.h" +#include +#include + + +// CArduinoFloppyReaderWinDlg dialog +class CArduinoFloppyReaderWinDlg : public CDialogEx +{ +// Construction +public: + CArduinoFloppyReaderWinDlg(CWnd* pParent = NULL); // standard constructor + ~CArduinoFloppyReaderWinDlg(); + std::thread* m_iothread; + void* m_sfx; + bool m_cancelButtonPressed; + bool m_partial; + + void enumComPorts(); + std::wstring getComPort(); + void setComPort(const std::wstring& comport); + +// Dialog Data +#ifdef AFX_DESIGN_TIME + enum { IDD = IDD_ARDUINOFLOPPYREADERWIN_DIALOG }; +#endif + + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + + +// Implementation +protected: + HICON m_hIcon; + + // Generated message map functions + virtual BOOL OnInitDialog(); + afx_msg void OnSysCommand(UINT nID, LPARAM lParam); + afx_msg void OnPaint(); + afx_msg HCURSOR OnQueryDragIcon(); + DECLARE_MESSAGE_MAP() +public: + afx_msg void OnBnClickedStartstop(); + afx_msg void OnBnClickedBrowse(); + void enableDialog(bool enable); + + afx_msg LRESULT OnUserMessage(WPARAM wparam, LPARAM lparam); + + CComboBox m_comport; + CEdit m_outputADF; + CProgressCtrl m_progressbar; + CStatic m_statusTrack; + CStatic m_statusSide; + CStatic m_statusGood; + CStatic m_statusPartial; + CButton m_browseButton; + CButton m_copyButton; + CStatic m_statusText; + CEdit m_inputADF; + CButton m_browseButton2; + CButton m_writeButton; + CButton m_verify; + CButton m_trk80; + CButton m_trk82; + CButton m_precomp; + + // Main thread loop + bool runThreadRead(); + void threadFinishedReading(bool successful); + bool runThreadWrite(); + void threadFinishedWriting(bool successful); + afx_msg void OnBnClickedBrowse2(); + afx_msg void OnBnClickedStartstop2(); + void saveComPort(); + afx_msg void OnBnClickedStartstop3(); + CButton m_diagnostics; +// CButton m_precomp; + CComboBox m_fileFormat; +protected: + afx_msg LRESULT OnDevicechange(WPARAM wParam, LPARAM lParam); +public: + + afx_msg void OnCbnSelchangeDiskformat(); +}; diff --git a/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/ReadMe.txt b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/ReadMe.txt new file mode 100644 index 00000000..47ee0ddc --- /dev/null +++ b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/ReadMe.txt @@ -0,0 +1,118 @@ +================================================================================ + MICROSOFT FOUNDATION CLASS LIBRARY : ArduinoFloppyReaderWin Project Overview +=============================================================================== + +The application wizard has created this ArduinoFloppyReaderWin application for +you. This application not only demonstrates the basics of using the Microsoft +Foundation Classes but is also a starting point for writing your application. + +This file contains a summary of what you will find in each of the files that +make up your ArduinoFloppyReaderWin application. + +ArduinoFloppyReaderWin.vcxproj + This is the main project file for VC++ projects generated using an application wizard. + It contains information about the version of Visual C++ that generated the file, and + information about the platforms, configurations, and project features selected with the + application wizard. + +ArduinoFloppyReaderWin.vcxproj.filters + This is the filters file for VC++ projects generated using an Application Wizard. + It contains information about the assciation between the files in your project + and the filters. This association is used in the IDE to show grouping of files with + similar extensions under a specific node (for e.g. ".cpp" files are associated with the + "Source Files" filter). + +ArduinoFloppyReaderWin.h + This is the main header file for the application. It includes other + project specific headers (including Resource.h) and declares the + CArduinoFloppyReaderWinApp application class. + +ArduinoFloppyReaderWin.cpp + This is the main application source file that contains the application + class CArduinoFloppyReaderWinApp. + +ArduinoFloppyReaderWin.rc + This is a listing of all of the Microsoft Windows resources that the + program uses. It includes the icons, bitmaps, and cursors that are stored + in the RES subdirectory. This file can be directly edited in Microsoft + Visual C++. Your project resources are in 1033. + +res\ArduinoFloppyReaderWin.ico + This is an icon file, which is used as the application's icon. This + icon is included by the main resource file ArduinoFloppyReaderWin.rc. + +res\ArduinoFloppyReaderWin.rc2 + This file contains resources that are not edited by Microsoft + Visual C++. You should place all resources not editable by + the resource editor in this file. + + +///////////////////////////////////////////////////////////////////////////// + +The application wizard creates one dialog class: + +ArduinoFloppyReaderWinDlg.h, ArduinoFloppyReaderWinDlg.cpp - the dialog + These files contain your CArduinoFloppyReaderWinDlg class. This class defines + the behavior of your application's main dialog. The dialog's template is + in ArduinoFloppyReaderWin.rc, which can be edited in Microsoft Visual C++. + +///////////////////////////////////////////////////////////////////////////// + +Help Support: + +hlp\ArduinoFloppyReaderWin.hhp + This file is a help project file. It contains the data needed to + compile the help files into a .chm file. + +hlp\ArduinoFloppyReaderWin.hhc + This file lists the contents of the help project. + +hlp\ArduinoFloppyReaderWin.hhk + This file contains an index of the help topics. + +hlp\afxcore.htm + This file contains the standard help topics for standard MFC + commands and screen objects. Add your own help topics to this file. + +makehtmlhelp.bat + This file is used by the build system to compile the help files. + +hlp\Images\*.gif + These are bitmap files required by the standard help file topics for + Microsoft Foundation Class Library standard commands. + + +///////////////////////////////////////////////////////////////////////////// + +Other standard files: + +StdAfx.h, StdAfx.cpp + These files are used to build a precompiled header (PCH) file + named ArduinoFloppyReaderWin.pch and a precompiled types file named StdAfx.obj. + +Resource.h + This is the standard header file, which defines new resource IDs. + Microsoft Visual C++ reads and updates this file. + +ArduinoFloppyReaderWin.manifest + Application manifest files are used by Windows XP to describe an applications + dependency on specific versions of Side-by-Side assemblies. The loader uses this + information to load the appropriate assembly from the assembly cache or private + from the application. The Application manifest maybe included for redistribution + as an external .manifest file that is installed in the same folder as the application + executable or it may be included in the executable in the form of a resource. +///////////////////////////////////////////////////////////////////////////// + +Other notes: + +The application wizard uses "TODO:" to indicate parts of the source code you +should add to or customize. + +If your application uses MFC in a shared DLL, you will need +to redistribute the MFC DLLs. If your application is in a language +other than the operating system's locale, you will also have to +redistribute the corresponding localized resources MFC100XXX.DLL. +For more information on both of these topics, please see the section on +redistributing Visual C++ applications in MSDN documentation. + +///////////////////////////////////////////////////////////////////////////// diff --git a/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/res/ArduinoFloppyReaderWin.ico b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/res/ArduinoFloppyReaderWin.ico new file mode 100644 index 0000000000000000000000000000000000000000..57ba92e0940f9be688b34ec330190b3252e23f44 GIT binary patch literal 141217 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 TBTrPp`vm~XgB8ma%tHSUR8zAB literal 0 HcmV?d00001 diff --git a/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/res/ArduinoFloppyReaderWin.rc2 b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/res/ArduinoFloppyReaderWin.rc2 new file mode 100644 index 0000000000000000000000000000000000000000..54a57d05afb5f4b6ed1bc0608cd3a0eb8ff1d01c GIT binary patch literal 828 zcmdUt%Syvw5QWcL@Ev||DK_966fYoBE7r?W(lnugHj%Vl`0~~7j0w7M(WNr{x0y3D zXJ-D7eWpyuI%3b1G*+jDcB<8=)wNdaZ^*kIR4T_-f_Mr02;GIw@j7F5ST>+{+={p- zO~4hr+ptvHf_p}{0hJRw;eU!G;4yKtHWcfWpGMFsmV~HGshG?_{k;LytmKcad>@0&L(Oy tOLzMarbCU!|4lJNGjrz`NYa|wHvNP>ukTrUroaD`C0+N7MQ8zTZkzxB literal 0 HcmV?d00001 diff --git a/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/res/fin.bmp b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/res/fin.bmp new file mode 100644 index 0000000000000000000000000000000000000000..df49821391d89fbe07ca40a937579702e67a05c3 GIT binary patch literal 23078 zcmeI4Pjc)u5XKe5j!i;w0M|?v#gc>@u;&1<}0E zq{)n>R;&A`?zYEHy_cVV`Tn=0_6I(H!27$0l>Wl;A$=|R-@m5x?Kk#*goJOlfByVE zy}rJtFJHb~{Ql8Qbn)2}%k$$;U9@K;xi6NNE}F%q3zQdQId;+dW9cbJJ+X9AF2_+X z?V1?Zmv()QdKvZ7u8g*H)XS)sc4f4sqh3b6v@4@69rZHmrCk|q>8O`cFYU@`OGmwo zdTCciTRQ6HKU6Qf|AzOt{QjjImY0|5uyZ@U`0rGEVmTi7kIPao{jl_uqn=nsy;N5b zd|ldiV^2BiiDlHwsFx}N?LmAuj(VvAG_EgIIASpBB|=ekM!i(wh{33r2u0Ny^-_f+ z2CI5WX*$f);gF<|5;}OL!5U2!`;YJ;;rPBkD*K-X^?^g<`ZBBWcJAl&@gXJtqBeWB8<5e3C^6j0lJkyoC-S^HIa;2l zH)ByGFNsTLv3g-x_hZSw^H^Av=DU1+P;ybbOOEb>A)|9H=(da1_Yu!ao~67-X`!9I z%f$mJUbrG!uqa1#f^|4d#=?u5Mx2l> zsw5bL3MBxr5mre6Ip?6xv5f>c%QV+;0km=8XlaonW1$UdKvSk+R_jd4DS5D~KCNH~ zHkgLqOo3FeJZowJ7vVi89I0X~)Gb@ERQC*6h#f)id=|ie$bya0_nR#FoUT|HWGxem z2U=E0$LKQ1w2M!SXWyu+U=FLPAWiF1(<0%^eMBqPR`o&;xi+aVPp~TQ6NmI*WDSsu zFbz{&Czc{Ea?9A@2lmke>(}XZhDbEFq&v}$+nJrkB9NEN5&xGYCY&%P&qnxh#)RlfEwJ0s3 zb-e^abQayZXSS1eYw4eBg<^Cei{%Jmb=nJ9EFFdGlkS-;_4NhYyo?22ye3Wn3c-ae zs+VH<4&Az5b^s_`28-&YnAo8k=X6gjqh6{?81+(xBL-2sqh2B=?2LM;!V!Z}FA<8W z^M9xp-jQtGuC155uvEW)(S0lK-fhzy*-e}7+ZhJjgW`b#_qbAFhc~5uxHV37y%-A+ zWHyiRe39srxBYywp>L@qF#;DtAZgJJACaSYK7yN)g%1;Y3=|9QZsC|L=AD{&`+^%d zxHMSe`3PBX(*{BBlRxoc>kA8r1hE~Q{MB(GAQ84^Sv?=gEh_>In}$2Z;!PGHDMupXq8r+(UMvI)3r--$1_zxbN`)awq?2VFwrTzbbK3kgq?fGZ> zZTai(|A^t_?x0y*cCXw3AWtvt`Kgn}zem;y%G1Uy>6U$M&GK*qj93!4lb-PB10V51 zpNGfvAc-asKOgbH5f*Y9%NScO$147?cU^N9SfS}uu#k*@+|XEJlp*pQF+_)>tlY}t zJ9+|(c10v@lm|(02%&G?Vn7zWJRk;sU04|3=P(9;W-Q!Z$iiS<34&!M3;HYzN*NCQ zmB}0z>^=a|2eM_2QCs3d6-usaC5x;(3rke~=!lJOJaJ;dLgL(wMPZU-I-;A%5lXvc zVU!pUy{T!#ZR7HwBw^Dyff$>79>JGb;$-%?=x_%XUNx9-Pl#CT;-T$x&Mq?$l9PwK zurM`*@Pl_aQoX>jW==k=nmk9Eb;*h5hXU;D*^)2ScUazVu{jGuZWNh?#gd!6m4ZB> zBT~i2g^uM1i7)!FxM2C3Ww9dLtdM5I3C6Y=OVi2c3l*2ociZ&X8O!c}4j}+iitg^6 Gl>P-LH3LZi literal 0 HcmV?d00001 diff --git a/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/res/fin2.bmp b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/res/fin2.bmp new file mode 100644 index 0000000000000000000000000000000000000000..0fd7f63bef04b5772d48d8508b830de245f98269 GIT binary patch literal 23078 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 CUDTie literal 0 HcmV?d00001 diff --git a/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/res/finpartial2.bmp b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/res/finpartial2.bmp new file mode 100644 index 0000000000000000000000000000000000000000..2f106657babb2330cb3526fa399e7090c2310e7b GIT binary patch literal 23078 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 ZhfYDbc|D(3c-|ysh|eoyrT^dO`!BzzM`Qp1 literal 0 HcmV?d00001 diff --git a/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/res/scp.bmp b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/res/scp.bmp new file mode 100644 index 0000000000000000000000000000000000000000..2b5633b98ad217afe7508b30f5ce38381a985d35 GIT binary patch literal 135846 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 PZCzkjY4%|Kr`LZ0BCajF literal 0 HcmV?d00001 diff --git a/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/stdafx.cpp b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/stdafx.cpp new file mode 100644 index 00000000..959ea889 --- /dev/null +++ b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/stdafx.cpp @@ -0,0 +1,8 @@ + +// stdafx.cpp : source file that includes just the standard includes +// ArduinoFloppyReaderWin.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + + diff --git a/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/stdafx.h b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/stdafx.h new file mode 100644 index 00000000..581c05d5 --- /dev/null +++ b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/stdafx.h @@ -0,0 +1,53 @@ + +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, +// but are changed infrequently + +#pragma once + +#ifndef VC_EXTRALEAN +#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers +#endif + +#include "targetver.h" + +#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit + +// turns off MFC's hiding of some common and often safely ignored warning messages +#define _AFX_ALL_WARNINGS + +#include // MFC core and standard components +#include // MFC extensions + + + + + +#ifndef _AFX_NO_OLE_SUPPORT +#include // MFC support for Internet Explorer 4 Common Controls +#endif +#ifndef _AFX_NO_AFXCMN_SUPPORT +#include // MFC support for Windows Common Controls +#endif // _AFX_NO_AFXCMN_SUPPORT + +#include // MFC support for ribbons and control bars + + + + + + + + + +#ifdef _UNICODE +#if defined _M_IX86 +#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"") +#elif defined _M_X64 +#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"") +#else +#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") +#endif +#endif + + diff --git a/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/targetver.h b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/targetver.h new file mode 100644 index 00000000..87c0086d --- /dev/null +++ b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/ArduinoFloppyReaderWin/targetver.h @@ -0,0 +1,8 @@ +#pragma once + +// Including SDKDDKVer.h defines the highest available Windows platform. + +// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and +// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. + +#include diff --git a/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/LICENSE.txt b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/LICENSE.txt new file mode 100644 index 00000000..20d40b6b --- /dev/null +++ b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/LICENSE.txt @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + 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. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + 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 +. \ No newline at end of file diff --git a/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/lib/ADFWriter.cpp b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/lib/ADFWriter.cpp new file mode 100644 index 00000000..3b39bf7c --- /dev/null +++ b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/lib/ADFWriter.cpp @@ -0,0 +1,1654 @@ +/* ArduinoFloppyReader (and writer) +* +* Copyright (C) 2017-2021 Robert Smith (@RobSmithDev) +* https://amiga.robsmithdev.co.uk +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Library General Public +* License as published by the Free Software Foundation; either +* version 3 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 +* Library General Public License for more details. +* +* You should have received a copy of the GNU Library General Public +* License along with this library; if not, see http://www.gnu.org/licenses/ +*/ + +////////////////////////////////////////////////////////////////////////////////////////// +// Class that reads reads the MFM data, decodes it, and then writes an ADF file to disk // +////////////////////////////////////////////////////////////////////////////////////////// +// +// Purpose: +// This class reads the raw data from the device and attemps to check for errors. +// Once all errors have been corrected the class will save the tracks to disk as an ADF file +// +// The class also handles writing an ADF file back to disk and optionally verifying the write. +// +// The MFM decoding algorithm and information regarding finding the start of a sector +// were taken from the excellent documentation by Laurent Cl�vy at http://lclevy.free.fr/adflib/adf_info.html +// Also credits to Keith Monahan https://www.techtravels.org/tag/mfm/ regarding a bug in the MFM sector start data +// +// V2.5 + +#include +#include +#include "ADFWriter.h" +#include "ArduinoInterface.h" +#include "RotationExtractor.h" +#include +#include +#include +#include +#include +#include +#include +#ifndef _WIN32 +#include +#include +#endif + +using namespace ArduinoFloppyReader; + +#ifndef OUTPUT_TIME_IN_NS +WARNING: OUTPUT_TIME_IN_NS MUST BE DEFINED IN REVOLUTIONEXTRACTOR.H FOR THIS CLASS TO WORK CORRECTLY +#endif + + +#define MFM_MASK 0x55555555L +#define AMIGA_WORD_SYNC 0x4489 // Disk SYNC code for the Amiga start of sector +#define SECTOR_BYTES 512 // Number of bytes in a decoded sector +#define NUM_SECTORS_PER_TRACK 11 // Number of sectors per track +#define RAW_SECTOR_SIZE (8+56+SECTOR_BYTES+SECTOR_BYTES) // Size of a sector, *Including* the sector sync word longs +#define ADF_TRACK_SIZE (SECTOR_BYTES*NUM_SECTORS_PER_TRACK) // Bytes required for a single track + + +const char* TEST_BYTE_SEQUENCE = "amiga.robsmithdev.co.uk"; + +// Buffer to hold raw data for just a single sector +typedef unsigned char RawEncodedSector[RAW_SECTOR_SIZE]; +typedef unsigned char RawDecodedSector[SECTOR_BYTES]; +typedef RawDecodedSector RawDecodedTrack[NUM_SECTORS_PER_TRACK]; +typedef unsigned char RawMFMData[SECTOR_BYTES + SECTOR_BYTES]; + +// When workbench formats a disk, it write 13630 bytes of mfm data to the disk. So we're going to write this amount, and then we dont need an erase first +typedef struct alignas(1) { + unsigned char filler1[1654]; // Padding at the start of the track. This will be set to 0xaa + // Raw sector data + RawEncodedSector sectors[NUM_SECTORS_PER_TRACK]; // 11968 bytes + // Blank "Filler" gap content. (this may get overwritten by the sectors a little) + unsigned char filler2[8]; +} FullDiskTrack; + +// Structure to hold data while we decode it +typedef struct alignas(8) { + unsigned char trackFormat; // This will be 0xFF for Amiga + unsigned char trackNumber; // Current track number (this is actually (tracknumber*2) + side + unsigned char sectorNumber; // The sector we just read (0 to 11) + unsigned char sectorsRemaining; // How many more sectors remain until the gap (0 to 10) + + unsigned long sectorLabel[4]; // OS Recovery Data, we ignore this + + unsigned long headerChecksum; // Read from the header, header checksum + unsigned long dataChecksum; // Read from the header, data checksum + + unsigned long headerChecksumCalculated; // The header checksum we calculate + unsigned long dataChecksumCalculated; // The data checksum we calculate + + RawDecodedSector data; // decoded sector data + + RawMFMData rawSector; // raw track data, for analysis of invalid sectors +} DecodedSector; + +// To hold a list of valid and checksum failed sectors +struct DecodedTrack { + // A list of valid sectors where the checksums are OK + std::vector validSectors; + // A list of sectors found with invalid checksums. These are used if ignore errors is triggered + // We keep copies of each one so we can perform a statistical analysis to see if we can get a working one based on which bits are mostly set the same + std::vector invalidSectors[NUM_SECTORS_PER_TRACK]; +}; + + +// MFM decoding algorithm +// *input; MFM coded data buffer (size == 2*data_size) +// *output; decoded data buffer (size == data_size) +// Returns the checksum calculated over the data +unsigned long decodeMFMdata(const unsigned long* input, unsigned long* output, const unsigned int data_size) { + unsigned long odd_bits, even_bits; + unsigned long chksum = 0L; + unsigned int count; + + // the decoding is made here long by long : with data_size/4 iterations + for (count = 0; count < data_size / 4; count++) { + odd_bits = *input; // longs with odd bits + even_bits = *(unsigned long*)(((unsigned char*)input) + data_size); // longs with even bits - located 'data_size' bytes after the odd bits + + chksum ^= odd_bits; // XOR Checksum + chksum ^= even_bits; + + *output = (even_bits & MFM_MASK) | ((odd_bits & MFM_MASK) << 1); + input++; /* next 'odd' long and 'even bits' long */ + output++; /* next location of the future decoded long */ + } + return chksum & MFM_MASK; +} + +// MFM encoding algorithm part 1 - this just writes the actual data bits in the right places +// *input; RAW data buffer (size == data_size) +// *output; MFM encoded buffer (size == data_size*2) +// Returns the checksum calculated over the data +unsigned long encodeMFMdataPart1(const unsigned long* input, unsigned long* output, const unsigned int data_size) { + unsigned long chksum = 0L; + unsigned int count; + + unsigned long* outputOdd = output; + unsigned long* outputEven = (unsigned long*)(((unsigned char*)output) + data_size); + + // Encode over two passes. First split out the odd and even data, then encode the MFM values, the /4 is because we're working in longs, not bytes + for (count = 0; count < data_size / 4; count++) { + *outputEven = *input & MFM_MASK; + *outputOdd = ((*input)>>1) & MFM_MASK; + outputEven++; + outputOdd++; + input++; + } + + // Checksum calculator + // Encode over two passes. First split out the odd and even data, then encode the MFM values, the /4 is because we're working in longs, not bytes + for (count = 0; count < (data_size / 4) * 2; count++) { + chksum ^= *output; + output++; + } + + return chksum & MFM_MASK; +} + +// Copys the data from inTrack into outTrack but fixes the bit/byte alignment so its aligned on the start of a byte +void alignSectorToByte(const RawTrackData& inTrack, int byteStart, int bitStart, RawEncodedSector& outSector) { + unsigned char byteOut = 0; + unsigned int byteOutPosition = 0; + + // Bit counter output + unsigned int counter = 0; + + // The position supplied is the last bit of the track sync. + bitStart--; // goto the next bit + if (bitStart < 0) { + // Could do a MEMCPY here, but for now just let the code below run + bitStart = 7; + byteStart++; + } + byteStart -= 8; // wind back 8 bytes + + // This is mis-aligned. So we need to shift the data into byte boundarys + for (;;) { + for (int bitCounter = bitStart; bitCounter >= 0; bitCounter--) { + byteOut <<= 1; + if (inTrack[byteStart%RAW_TRACKDATA_LENGTH] & (1 << bitCounter)) byteOut |= 1; + + if (++counter >= 8) { + outSector[byteOutPosition] = byteOut; + byteOutPosition++; + if (byteOutPosition >= RAW_SECTOR_SIZE) return; + counter = 0; + } + } + + // Move along and reset + byteStart++; + bitStart = 7; + } +} + +// Attempt to repair the MFM data. Returns TRUE if errors are detected +bool repairMFMData(unsigned char* data, const unsigned int dataLength) { + bool errors = false; + // Only certain bit-patterns are allowed. So if we come across an invalid one we will try to repair it. + // You cannot have two '1's together, and a max of three '0' in a row + // Allowed combinations: (note the SYNC WORDS and TRACK START are designed to break these rules, but we shouldn't encounter them) + // + // 00010 + // 00100 + // 00101 + // 01000 + // 01001 + // 01010 + // 10001 + // 10010 + // 10100 + // 10101 + // + unsigned char testByte = 0; + int counter = 0; + for (unsigned int position = 0; position < dataLength; position++) { + // Fixed: This was the wrong way around + for (int bitIndex = 7; bitIndex >= 0; bitIndex--) { + testByte <<= 1; // shift off one bit to make room for the new bit + if (*data & (1 << bitIndex)) { + // Make sure two '1's dont come in together as this is not allowed! This filters out a lot of BAD combinations + if ((testByte & 0x2) != 0x2) { + testByte |= 1; + } + else { + // We detected two '1's in a row, which isnt allowed. From reading this most likely means this was a weak bit, so we change it to zero. + errors = true; + } + } + + // We're only interested in the last so many bits, and only when we have received that many + if (++counter > 4) { + switch (testByte & 0x1F) { + // These are the only possible invalid combinations left + case 0x00: + case 0x01: + case 0x10: + // No idea how to repair these + errors = true; + break; + } + } + } + data++; + } + + return errors; + +} + +// Looks at the history for this sector number and creates a new sector where the bits are set to whatever occurs more. We then do a checksum and if it succeeds we use it +bool attemptFixSector(const DecodedTrack& decodedTrack, DecodedSector& outputSector) { + int sectorNumber = outputSector.sectorNumber; + + if (decodedTrack.invalidSectors[sectorNumber].size() < 2) return false; + + typedef struct { + int zeros = 0; + int ones = 0; + } SectorCounter[8]; + + SectorCounter sectorSum[SECTOR_BYTES + SECTOR_BYTES]; + + memset(sectorSum, 0, sizeof(sectorSum)); + + // Calculate the number of '1's and '0's in each block + for (const DecodedSector& sec : decodedTrack.invalidSectors[sectorNumber]) + for (int byteNumber = 0; byteNumber < SECTOR_BYTES + SECTOR_BYTES; byteNumber++) + for (int bit = 0; bit <= 7; bit++) + if (sec.rawSector[byteNumber] & (1 << bit)) + sectorSum[byteNumber][bit].ones++; else sectorSum[byteNumber][bit].zeros++; + + // Now create a sector based on this data + memset(outputSector.rawSector, 0, sizeof(outputSector.rawSector)); + for (int byteNumber = 0; byteNumber < SECTOR_BYTES + SECTOR_BYTES; byteNumber++) + for (int bit = 0; bit <= 7; bit++) + if (sectorSum[byteNumber][bit].ones >= sectorSum[byteNumber][bit].zeros) + outputSector.rawSector[byteNumber] |= (1 << bit); + + return true; +} + +// Extract and convert the sector. This may be a duplicate so we may reject it. Returns TRUE if it was valid, or false if not +bool decodeSector(const RawEncodedSector& rawSector, const unsigned int trackNumber, const DiskSurface surface, DecodedTrack& decodedTrack, bool ignoreHeaderChecksum, int& lastSectorNumber) { + DecodedSector sector; + + lastSectorNumber = -1; + memcpy(sector.rawSector, rawSector, sizeof(RawMFMData)); + + // Easier to operate on + unsigned char* sectorData = (unsigned char*)rawSector; + + // Read the first 4 bytes (8). This is the track header data + sector.headerChecksumCalculated = decodeMFMdata((unsigned long*)(sectorData + 8), (unsigned long*)§or, 4); + // Decode the label data and update the checksum + sector.headerChecksumCalculated ^= decodeMFMdata((unsigned long*)(sectorData + 16), (unsigned long*)§or.sectorLabel[0], 16); + // Get the checksum for the header + decodeMFMdata((unsigned long*)(sectorData + 48), (unsigned long*)§or.headerChecksum, 4); // (computed on mfm longs, longs between offsets 8 and 44 == 2 * (1 + 4) longs) + // If the header checksum fails we just cant trust anything we received, so we just drop it + if ((sector.headerChecksum != sector.headerChecksumCalculated) && (!ignoreHeaderChecksum)) { + return false; + } + + // Check if the header contains valid fields + if (sector.trackFormat != 0xFF) + return false; // not valid + if (sector.sectorNumber > 10) + return false; + if (sector.trackNumber > 162) + return false; // 81 tracks * 2 for both sides + if (sector.sectorsRemaining > 11) + return false; // this isnt possible either + if (sector.sectorsRemaining < 1) + return false; // or this + + // And is it from the track we expected? + const unsigned char targetTrackNumber = (trackNumber << 1) | ((surface == DiskSurface::dsUpper) ? 1 : 0); + + if (sector.trackNumber != targetTrackNumber) return false; // this'd be weird + + // Get the checksum for the data + decodeMFMdata((unsigned long*)(sectorData + 56), (unsigned long*)§or.dataChecksum, 4); + + + // Lets see if we already have this one + const int searchSector = sector.sectorNumber; + auto index = std::find_if(decodedTrack.validSectors.begin(), decodedTrack.validSectors.end(), [searchSector](const DecodedSector& sector) -> bool { + return (sector.sectorNumber == searchSector); + }); + + // We already have it as a GOOD VALID sector, so skip, we don't need it. + if (index != decodedTrack.validSectors.end()) return true; + + // Decode the data and receive it's checksum + sector.dataChecksumCalculated = decodeMFMdata((unsigned long*)(sectorData + 64), (unsigned long*)§or.data[0], SECTOR_BYTES); // (from 64 to 1088 == 2*512 bytes) + + // Is the data valid? + if (sector.dataChecksum != sector.dataChecksumCalculated) { + // Keep a copy + decodedTrack.invalidSectors[sector.sectorNumber].push_back(sector); + return false; + } + else { + // Its a good sector, and we dont have it yet + decodedTrack.validSectors.push_back(sector); + + // Lets delete it from invalid sectors list + decodedTrack.invalidSectors[sector.sectorNumber].clear(); + + return true; + } +} + +// Encode a sector into the correct format for disk +void encodeSector(const unsigned int trackNumber, const DiskSurface surface, const unsigned int sectorNumber, const RawDecodedSector& input, RawEncodedSector& encodedSector, unsigned char& lastByte) { + // Sector Start + encodedSector[0] = (lastByte & 1) ? 0x2A : 0xAA; + encodedSector[1] = 0xAA; + encodedSector[2] = 0xAA; + encodedSector[3] = 0xAA; + // Sector Sync + encodedSector[4] = 0x44; + encodedSector[5] = 0x89; + encodedSector[6] = 0x44; + encodedSector[7] = 0x89; + + // MFM Encoded header + DecodedSector header; + memset(&header, 0, sizeof(header)); + + header.trackFormat = 0xFF; + header.trackNumber = (trackNumber << 1) | ((surface == DiskSurface::dsUpper) ? 1 : 0); + header.sectorNumber = sectorNumber; + header.sectorsRemaining = NUM_SECTORS_PER_TRACK - sectorNumber; //1..11 + + + header.headerChecksumCalculated = encodeMFMdataPart1((const unsigned long*)&header, (unsigned long*)&encodedSector[8], 4); + // Then theres the 16 bytes of the volume label that isnt used anyway + header.headerChecksumCalculated ^= encodeMFMdataPart1((const unsigned long*)&header.sectorLabel, (unsigned long*)&encodedSector[16], 16); + // Thats 40 bytes written as everything doubles (8+4+4+16+16). - Encode the header checksum + encodeMFMdataPart1((const unsigned long*)&header.headerChecksumCalculated, (unsigned long*)&encodedSector[48], 4); + // And move on to the data section. Next should be the checksum, but we cant encode that until we actually know its value! + header.dataChecksumCalculated = encodeMFMdataPart1((const unsigned long*)&input, (unsigned long*)&encodedSector[64], SECTOR_BYTES); + // And add the checksum + encodeMFMdataPart1( (const unsigned long*)&header.dataChecksumCalculated, (unsigned long*)&encodedSector[56], 4); + + // Now fill in the MFM clock bits + bool lastBit = encodedSector[7] & (1 << 0); + bool thisBit = lastBit; + + // Clock bits are bits 7, 5, 3 and 1 + // Data is 6, 4, 2, 0 + for (int count = 8; count < RAW_SECTOR_SIZE; count++) { + for (int bit = 7; bit >= 1; bit -= 2) { + lastBit = thisBit; + thisBit = encodedSector[count] & (1 << (bit-1)); + + if (!(lastBit || thisBit)) { + // Encode a 1! + encodedSector[count] |= (1 << bit); + } + } + } + + lastByte = encodedSector[RAW_SECTOR_SIZE - 1]; +} + +// Find sectors within raw data read from the drive by searching bit-by-bit for the SYNC bytes +void findSectors(const RawTrackData& track, unsigned int trackNumber, DiskSurface side, unsigned short trackSync, DecodedTrack& decodedTrack, bool ignoreHeaderChecksum) { + // Work out what we need to search for which is 2AAAAAAAsyncsync + //const unsigned long long search = (trackSync | (((DWORD)trackSync) << 16)) | (((long long)0x2AAAAAAA) << 32); + // For speed and to ignore some data errors, we now just search for syncsync and ignore the 2AAAAAAA part + + // Work out what we need to search for which is syncsync + const unsigned long search = (trackSync | (((unsigned long)trackSync) << 16)); + + // Prepare our test buffer + unsigned long decoded = 0; + + // Keep runnign until we run out of data + unsigned int byteIndex = 0; + + int nextTrackBitCount = 0; + + // run the entire track length + while (byteIndex < RAW_TRACKDATA_LENGTH) { + + // Check each bit, the "decoded" variable slowly slides left providing a 64-bit wide "window" into the bitstream + for (int bitIndex = 7; bitIndex >= 0; bitIndex--) { + decoded <<= 1; // shift off one bit to make room for the new bit + if (track[byteIndex] & (1 << bitIndex)) decoded |= 1; + + // Have we matched the sync words correctly + ++nextTrackBitCount; + int lastSectorNumber = -1; + if (decoded == search) { + RawEncodedSector alignedSector; + + // We extract ALL of the track data from this BIT to byte align it properly, then pass it onto the code to read the sector (from the start of the sync code) + alignSectorToByte(track, byteIndex, bitIndex, alignedSector); + + // Now see if there's a valid sector there. We now only skip the sector if its valid, incase rogue data gets in there + if (decodeSector(alignedSector, trackNumber, side, decodedTrack, ignoreHeaderChecksum, lastSectorNumber)) { + // We know the size of this buffer, so we can skip by exactly this amount + byteIndex += RAW_SECTOR_SIZE - 8; // skip this many bytes as we know this is part of the track! minus 8 for the SYNC + if (byteIndex >= RAW_TRACKDATA_LENGTH) break; + // We know that 8 bytes from here should be another track. - we allow 1 bit either way for slippage, but this allows an extra check incase the SYNC pattern is damaged + nextTrackBitCount = 0; + } + else { + + // Decode failed. Lets try a "homemade" one + DecodedSector newTrack; + if ((lastSectorNumber >= 0) && (lastSectorNumber < NUM_SECTORS_PER_TRACK)) { + newTrack.sectorNumber = lastSectorNumber; + if (attemptFixSector(decodedTrack, newTrack)) { + memcpy(newTrack.rawSector, alignedSector, sizeof(newTrack.rawSector)); + // See if our makeshift data will decode or not + if (decodeSector(alignedSector, trackNumber, side, decodedTrack, ignoreHeaderChecksum, lastSectorNumber)) { + // We know the size of this buffer, so we can skip by exactly this amount + byteIndex += RAW_SECTOR_SIZE - 8; // skip this many bytes as we know this is part of the track! minus 8 for the SYNC + if (byteIndex >= RAW_TRACKDATA_LENGTH) break; + } + } + } + if (decoded == search) nextTrackBitCount = 0; + } + } + } + byteIndex++; + } +} + +// Merges any invalid sectors into the valid ones as a last resort +void mergeInvalidSectors(DecodedTrack& track) { + for (unsigned char sector = 0; sector < NUM_SECTORS_PER_TRACK; sector++) { + if (track.invalidSectors[sector].size()) { + // Lets try to make the best sector we can + DecodedSector sec = track.invalidSectors[sector][0]; + // Repair maybe!? + attemptFixSector(track, sec); + + track.validSectors.push_back(sec); + } + track.invalidSectors[sector].clear(); + } +} + +// Open the device we want to use. Returns TRUE if it worked +bool ADFWriter::openDevice(const std::wstring& portName) { + if (m_device.openPort(portName) != DiagnosticResponse::drOK) return false; + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + return m_device.enableReading(true, true)== DiagnosticResponse::drOK; +} + +// Close the device when we've finished +void ADFWriter::closeDevice() { + m_device.closePort(); +} + +// Run diagnostics on the system. You do not need to call openDevice first. Return TRUE if everything passed +bool ADFWriter::runDiagnostics(const std::wstring& portName, std::function messageOutput, std::function askQuestion) { + std::stringstream msg; + if (!messageOutput) return false; + if (!askQuestion) return false; + + if (!askQuestion(false, "Please insert a *write protected* disk in the drive.\r\nUse a disk that you don't mind being erased.\nThis disk must contain data/formatted as an AmigaDOS disk")) { + messageOutput(true, "Diagnostics aborted"); + return false; + } + + msg << "Attempting to open and use "; + char convert[20]; +#ifdef _WIN32 + sprintf_s(convert, "%ls", portName.c_str()); +#else + sprintf(convert, "%ls", portName.c_str()); +#endif + msg << convert << " without CTS"; + messageOutput(false,msg.str()); + + // Step 1 is to check the com port stuff + DiagnosticResponse r = m_device.openPort(portName, false); + + // Check response + if (r != DiagnosticResponse::drOK) { + messageOutput(true,m_device.getLastErrorStr()); + messageOutput(true, "Please check Arduino power and the TXD/RXD on the USB->Serial board are connected to the right pins on the Arduino"); + return false; + } + + // Step 2: This has been setup with CTS stuff disabled, but the port opened. So lets validate CTS *is* working as we expect it to + messageOutput(false, "Testing CTS pin"); + r = m_device.testCTS(); + + // Check response + if (r != DiagnosticResponse::drOK) { + messageOutput(true, m_device.getLastErrorStr()); + messageOutput(true, "Please check the following PINS on the Arduino: A2"); + return false; + } + + // Step 3: CTS is working correctly, so re-open the port in normal mode + messageOutput(false, "CTS OK. Reconnecting with CTS enabled"); + m_device.closePort(); + r = m_device.openPort(portName, true); + + // Check response + if (r != DiagnosticResponse::drOK) { + messageOutput(true, m_device.getLastErrorStr()); + return false; + } + + FirmwareVersion version = m_device.getFirwareVersion(); + if ((version.major < 1) || (version.major > 9)) { + messageOutput(true, "Error reading firmware version. Something is wrong with the communication between the PC and the Arduino."); + return false; + } + + char buffer[250]; +#ifdef _WIN32 + sprintf_s(buffer, "Board is running firmware version %i.%i%s\n", version.major, version.minor, version.fullControlMod ? " (modded for DiskChange support)" : ""); +#else + sprintf(buffer, "Board is running firmware version %i.%i%s\n", version.major, version.minor, version.fullControlMod ? " (modded for DiskChange support)" : ""); +#endif + messageOutput(false, buffer); + + if ((version.major == 1) && (version.minor < 8)) { + messageOutput(false, "This firmware is out of date. Please update it!"); + } + + if ((version.major > 1) || ((version.major == 1) && (version.minor >= 8))) { + messageOutput(false, "Testing USB->Serial transfer speed (read)"); + if (m_device.testTransferSpeed() != DiagnosticResponse::drOK) { + messageOutput(false, "The USB->Serial adapter in use is not suitable."); + messageOutput(false, "Arduino UNO: The on-board adapter is not able to sustain large data transfers"); + messageOutput(false, "Arduino Pro Mini: The USB-Serial board is not able to sustain large data transfers"); + messageOutput(false, "Arduino Nano: The USB-Serial on this board is not fast enough to sustain large data transfers"); + messageOutput(false, ""); + messageOutput(false, "If you are using any of the devices with a CH340 converter then swap it for an FTDI one."); + messageOutput(false, "If you still have problems after switching, connect the Arduino using a shorter cable"); + messageOutput(false, "and if possible directly (ie: not via a USB hub)"); + messageOutput(true, "Diagnostics failed."); + return false; + } + messageOutput(false, "Read speed test passed. USB to serial converter is functioning correctly!"); + } + + + if ((version.major > 1) || ((version.major == 1) && (version.minor >= 8))) { + messageOutput(false, "Testing write-protect signal"); + for (;;) { + + if (m_device.checkIfDiskIsWriteProtected(true) == DiagnosticResponse::drWriteProtected) break; + + if (!askQuestion(false, "Inserted disk is not write protected. If it is, then check Arduino Pin A0. Please insert a write protected AmigaDOS disk in the drive")) { + messageOutput(true, "Diagnostics aborted"); + return false; + } + } + } + + // Functions to test + messageOutput(false, "Enabling the drive (please listen and watch the drive)"); + r = m_device.enableReading(true, false); + if (r != DiagnosticResponse::drOK) { + messageOutput(true, m_device.getLastErrorStr()); + return false; + } + + // Ask the user for verification of the result + if (!askQuestion(true,"Did the floppy disk start spinning, and did the drive LED switch on?")) { + messageOutput(true, "Please check the drive has power and the following PINS on the Arduino: 5 and 11"); + messageOutput(true, "It's possible you may also need need to provide a seperate 5V power supply for this drive."); + return false; + } + + // Now see if we can find track 0 + messageOutput(false, "Asking the Arduino to find Track 0"); + r = m_device.findTrack0(); + if (r == DiagnosticResponse::drRewindFailure) { + messageOutput(true, "Unable to find track 0"); + if (askQuestion(true,"Could you hear the drive head moving?")) { + messageOutput(true, "Please check the following PINS on the Arduino: 6, 8"); + } + else { + messageOutput(true, "Please check the following PINS on the Arduino: 7"); + messageOutput(true, "It's possible you may also need need to provide a seperate 5V power supply for this drive."); + } + return false; + } + else + if (r != DiagnosticResponse::drOK) { + messageOutput(true, m_device.getLastErrorStr()); + return false; + } + + // Track 0 found. Lets see if we can seek to track 70 + messageOutput(false, "Track 0 was found. Asking the Arduino to find Track 70"); + r = m_device.selectTrack(70); + if (r != DiagnosticResponse::drOK) { + messageOutput(true, m_device.getLastErrorStr()); + messageOutput(true, "There is also a strong possability that you may also need need to provide a seperate 5V power supply for this drive."); + return false; + } + + if (!askQuestion(true,"Could you hear the head moving quite a distance?")) { + messageOutput(true, "As we successfully found track 0, please check the following PINS on the Arduino: 6, 7"); + messageOutput(true, "It's possible you may also need need to provide a seperate 5V power supply for this drive."); + return false; + } + + // Test DiskChange + if (version.fullControlMod) { + // Goto track 3, just like the Amiga + m_device.selectTrack(3); + + std::chrono::time_point start = std::chrono::steady_clock::now(); + messageOutput(false, "Testing Disk Change pin."); + messageOutput(false, "*** Please remove disk from drive *** (you have 30 seconds)"); + while (std::chrono::duration_cast(std::chrono::steady_clock::now() - start).count() < 30000) { + std::this_thread::sleep_for(std::chrono::milliseconds(250)); + if (m_device.checkForDisk(true) == DiagnosticResponse::drNoDiskInDrive) break; + } + + if (m_device.isDiskInDrive()) { + messageOutput(true, "Disk change is NOT working correctly"); + messageOutput(true, "Please check the following pins on the Arduino: 10, 11"); + return false; + } + + start = std::chrono::steady_clock::now(); + messageOutput(false, "*** Please re-insert disk into drive *** (you have 30 seconds)"); + while (std::chrono::duration_cast(std::chrono::steady_clock::now() - start).count() < 30000) { + std::this_thread::sleep_for(std::chrono::milliseconds(2000)); + m_device.selectTrack(2); + if (m_device.isDiskInDrive()) break; + std::this_thread::sleep_for(std::chrono::milliseconds(2000)); + m_device.selectTrack(3); + if (m_device.isDiskInDrive()) break; + } + + if (m_device.isDiskInDrive()) { + messageOutput(false, "Disk change is working correctly"); + } + else { + messageOutput(true, "Disk change is NOT working correctly"); + messageOutput(true, "Please check the following pins on the Arduino: 10, 11"); + return false; + } + } + + // So we can open the drive and move the head. We're going to turn the drive off + r = m_device.enableReading(false, false); + if (r != DiagnosticResponse::drOK) { + messageOutput(true, m_device.getLastErrorStr()); + return false; + } + + messageOutput(false, "Starting drive, and seeking to track 40."); + // Re-open the drive + r = m_device.enableReading(true, true); + if (r != DiagnosticResponse::drOK) { + messageOutput(true, m_device.getLastErrorStr()); + return false; + } + + // Goto 40, this is where the root block is, although we wont be decoding it + r = m_device.selectTrack(40); + if (r != DiagnosticResponse::drOK) { + messageOutput(true, m_device.getLastErrorStr()); + return false; + } + + messageOutput(false, "Checking for INDEX pulse from drive"); + r = m_device.testIndexPulse(); + if (r != DiagnosticResponse::drOK) { + messageOutput(true, m_device.getLastErrorStr()); + messageOutput(true, "Please check that a disk is inserted and the following PINS on the Arduino: 2"); + return false; + } + + messageOutput(false, "Checking for DATA from drive"); + r = m_device.testDataPulse(); + if (r != DiagnosticResponse::drOK) { + messageOutput(true, m_device.getLastErrorStr()); + messageOutput(true, "Please check that a disk is inserted and following PINS on the Arduino: 4 (and the 1K resistor)"); + return false; + } + + r = m_device.selectSurface(ArduinoFloppyReader::DiskSurface::dsUpper); + if (r != DiagnosticResponse::drOK) { + messageOutput(true, m_device.getLastErrorStr()); + return false; + } + + messageOutput(false, "Attempting to read a track from the UPPER side of the disk"); + ArduinoFloppyReader::RawTrackData data; + int counter; + bool tracksFound = false; + + for (int a = 0; a < 10; a++) { + r = m_device.readCurrentTrack(data, true); + if (r != DiagnosticResponse::drOK) { + messageOutput(true, m_device.getLastErrorStr()); + return false; + } + + // Data read. See if any tracks were detected + DecodedTrack trk1; + findSectors(data, 40, ArduinoFloppyReader::DiskSurface::dsUpper, AMIGA_WORD_SYNC, trk1, true); + + counter=0; + for (int sec=0; sec 0) { + messageOutput(false, "Tracks found!"); + tracksFound = true; + break; + } + // Nothing found? + DecodedTrack trk2; + findSectors(data, 40, ArduinoFloppyReader::DiskSurface::dsLower, AMIGA_WORD_SYNC, trk2, true); + + counter = 0; + for (int sec = 0; sec 0) { + messageOutput(false, "Tracks found but on the wrong side. Please check the following PINS on the Arduino: 9"); + return false; + } + if (tracksFound) break; + } + + + messageOutput(false, "Attempting to read a track from the LOWER side of the disk"); + r = m_device.selectSurface(ArduinoFloppyReader::DiskSurface::dsLower); + if (r != DiagnosticResponse::drOK) { + messageOutput(true, m_device.getLastErrorStr()); + return false; + } + tracksFound = false; + + for (int a = 0; a < 10; a++) { + r = m_device.readCurrentTrack(data, true); + if (r != DiagnosticResponse::drOK) { + messageOutput(true, m_device.getLastErrorStr()); + return false; + } + + // Data read. See if any tracks were detected + DecodedTrack trk1; + findSectors(data, 40, ArduinoFloppyReader::DiskSurface::dsLower, AMIGA_WORD_SYNC, trk1, true); + + counter = 0; + for (int sec = 0; sec 0) { + messageOutput(false, "Tracks found!"); + tracksFound = true; + break; + } + // Nothing found? + DecodedTrack trk2; + findSectors(data, 40, ArduinoFloppyReader::DiskSurface::dsUpper, AMIGA_WORD_SYNC, trk2, true); + + counter = 0; + for (int sec = 0; sec 0) { + messageOutput(false, "Tracks found but on the wrong side. Please check the following PINS on the Arduino: 9"); + return false; + } + if (tracksFound) break; + } + + messageOutput(false, "Reading was successful!"); + + // Turn the drive off again + r = m_device.enableReading(false,false); + if (r != DiagnosticResponse::drOK) { + messageOutput(true, m_device.getLastErrorStr()); + return false; + } + + // Now ask. + if (!askQuestion(true,"Would you like to test writing to a disk? Please insert a WRITE ENABLED disk that you *do not mind* being overwritten")) { + messageOutput(true, "Diagnostic aborted."); + return false; + } + + // Try to enable the write head + do { + r = m_device.enableWriting(true, true); + + if (r == DiagnosticResponse::drWriteProtected) { + if (!askQuestion(false,"Please write-enable the disk and try again.")) { + messageOutput(true, "Diagnostic aborted."); + return false; + } + } else + if (r != DiagnosticResponse::drOK) { + messageOutput(true, m_device.getLastErrorStr()); + return false; + } + + } while (r == DiagnosticResponse::drWriteProtected); + // Writing is enabled. + + if ((version.major > 1) || ((version.major == 1) && (version.minor >= 8))) { + for (;;) { + + if (m_device.checkIfDiskIsWriteProtected(true) == DiagnosticResponse::drOK) break; + + if (!askQuestion(false, "Inserted disk is write protected. If it isn't, then check Arduino Pin A0. Please insert a write *enabled* disk in the drive")) { + messageOutput(true, "Diagnostics aborted"); + return false; + } + } + } + + + // Goto 41, we'll write some stuff + r = m_device.selectTrack(41); + if (r != DiagnosticResponse::drOK) { + messageOutput(true, m_device.getLastErrorStr()); + return false; + } + + // Upper side + r = m_device.selectSurface(ArduinoFloppyReader::DiskSurface::dsUpper); + if (r != DiagnosticResponse::drOK) { + messageOutput(true, m_device.getLastErrorStr()); + return false; + } + + // We're gonna write a test track out + + RawDecodedSector track[NUM_SECTORS_PER_TRACK]; + FullDiskTrack disktrack; + memset(disktrack.filler1, 0xAA, sizeof(disktrack.filler1)); // Pad with "0"s which as an MFM encoded byte is 0xAA + memset(disktrack.filler2, 0xAA, sizeof(disktrack.filler2)); // Pad with "0"s which as an MFM encoded byte is 0xAA + + // Get length + int sequenceLength = strlen(TEST_BYTE_SEQUENCE); + unsigned char lastByte = 0; + + for (unsigned int sector = 0; sector < NUM_SECTORS_PER_TRACK; sector++) { + + // Invent some track data + for (int bytePos = 0; bytePos < SECTOR_BYTES; bytePos++) + track[sector][bytePos] = TEST_BYTE_SEQUENCE[(sector + bytePos) % sequenceLength]; + + encodeSector(41, ArduinoFloppyReader::DiskSurface::dsUpper, sector, track[sector], disktrack.sectors[sector], lastByte); + } + + // Attempt to write, with verify + messageOutput(false, "Writing and Verifying Track 41 (Upper Side)."); + bool writtenOK = false; + for (int a = 1; a <= 10; a++) { + + r = m_device.eraseCurrentTrack(); + if (r != DiagnosticResponse::drOK) { + messageOutput(true, m_device.getLastErrorStr()); + messageOutput(true, "This can also be caused by insufficient power to the drive"); + return false; + } + + r = m_device.writeCurrentTrack((const unsigned char*)(&disktrack), sizeof(disktrack), false); + if (r != DiagnosticResponse::drOK) { + messageOutput(true, m_device.getLastErrorStr()); + messageOutput(true, "This can also be caused by insufficient power to the drive"); + return false; + } + r = m_device.readCurrentTrack(data, false); + if (r != DiagnosticResponse::drOK) { + messageOutput(true, m_device.getLastErrorStr()); + messageOutput(true, "This can also be caused by insufficient power to the drive"); + return false; + } + + // Data read. See if any tracks were detected + DecodedTrack trk; + findSectors(data, 41, ArduinoFloppyReader::DiskSurface::dsUpper, AMIGA_WORD_SYNC, trk, true); + // Have a look at any of the found sectors and see if any are valid and matched the phrase we wrote onto the disk + for (const DecodedSector& sec : trk.validSectors) { + // See if we can find the sequence in here somewhere + std::string s; + s.resize(SECTOR_BYTES); + memcpy(&s[0], sec.data, SECTOR_BYTES); + + if (s.find(TEST_BYTE_SEQUENCE) != std::string::npos) { + // Excellent + writtenOK = true; + break; + } + } + if (!writtenOK) { + // See if we can find the sequence in one of the partial sectors + for (int sector = 0; sector < NUM_SECTORS_PER_TRACK; sector++) { + for (const DecodedSector& sec : trk.invalidSectors[sector]) { + // See if we can find the sequence in here somewhere + std::string s; + s.resize(SECTOR_BYTES); + memcpy(&s[0], sec.data, SECTOR_BYTES); + + if (s.find(TEST_BYTE_SEQUENCE) != std::string::npos) { + // Excellent + writtenOK = true; + break; + } + } + if (writtenOK) break; + } + if (writtenOK) break; + } + if (writtenOK) break; + } + + // Final results + if (!writtenOK) { + messageOutput(true, "Unable to detect written track. This could be for one of the following reasons:"); + messageOutput(true, "1. Please check the following PINS on the Arduino: 3, A0, A1"); + messageOutput(true, "2. Please check the Arduino IDE config has not been modified from stock. This was tested using 1.8.4, compiler settings may affect performance"); + messageOutput(true, "3. Check for poor connections, typically on a breadboard they may be intermittent which may pass the above results but still not work."); + messageOutput(true, "4. Check for an electrically noisy environment. It is possible that electronic noise (eg: from a cell phone) may cause errors reading and writing to the disk"); + messageOutput(true, "5. Shorten the floppy disk cable to help reduce noise."); + messageOutput(true, "6. Ensure your power supply is strong enough to power the floppy drive. This drive may need too much power for the USB port"); + messageOutput(true, "7. You can contact me for help, but some basic electronics diagnostics will help, checkout YouTube for guides."); + + m_device.enableWriting(false); + return false; + } + + // Attempt to write, with verify + messageOutput(false, "Writing (Precomp) and Verifying Track 41 (Upper Side)."); + writtenOK = false; + for (int a = 1; a <= 10; a++) { + + r = m_device.eraseCurrentTrack(); + if (r != DiagnosticResponse::drOK) { + messageOutput(true, m_device.getLastErrorStr()); + return false; + } + + r = m_device.writeCurrentTrackPrecomp((const unsigned char*)(&disktrack), sizeof(disktrack), false, true); + if (r != DiagnosticResponse::drOK) { + messageOutput(true, m_device.getLastErrorStr()); + return false; + } + r = m_device.readCurrentTrack(data, false); + if (r != DiagnosticResponse::drOK) { + messageOutput(true, m_device.getLastErrorStr()); + return false; + } + + // Data read. See if any tracks were detected + DecodedTrack trk; + findSectors(data, 41, ArduinoFloppyReader::DiskSurface::dsUpper, AMIGA_WORD_SYNC, trk, true); + // Have a look at any of the found sectors and see if any are valid and matched the phrase we wrote onto the disk + for (const DecodedSector& sec : trk.validSectors) { + // See if we can find the sequence in here somewhere + std::string s; + s.resize(SECTOR_BYTES); + memcpy(&s[0], sec.data, SECTOR_BYTES); + + if (s.find(TEST_BYTE_SEQUENCE) != std::string::npos) { + // Excellent + writtenOK = true; + break; + } + } + if (!writtenOK) { + // See if we can find the sequence in one of the partial sectors + for (int sector = 0; sector < NUM_SECTORS_PER_TRACK; sector++) { + for (const DecodedSector& sec : trk.invalidSectors[sector]) { + // See if we can find the sequence in here somewhere + std::string s; + s.resize(SECTOR_BYTES); + memcpy(&s[0], sec.data, SECTOR_BYTES); + + if (s.find(TEST_BYTE_SEQUENCE) != std::string::npos) { + // Excellent + writtenOK = true; + break; + } + } + if (writtenOK) break; + } + if (writtenOK) break; + } + if (writtenOK) break; + } + + // Final results + if (!writtenOK) { + messageOutput(true, "Unable to detect written track. This could be for one of the following reasons:"); + messageOutput(true, "1. Please check the following PINS on the Arduino: 3, A0, A1"); + messageOutput(true, "2. Please check the Arduino IDE config has not been modified from stock. This was tested using 1.8.4, compiler settings may affect performance"); + messageOutput(true, "3. Check for poor connections, typically on a breadboard they may be intermittent which may pass the above results but still not work."); + messageOutput(true, "4. Check for an electrically noisy environment. It is possible that electronic noise (eg: from a cell phone) may cause errors reading and writing to the disk"); + messageOutput(true, "5. Shorten the floppy disk cable to help reduce electrical noise."); + messageOutput(true, "6. Ensure your power supply is strong enough to power the floppy drive. This drive may need too much power for the USB port"); + messageOutput(true, "7. If you are using a USB hub, try connecting directly to the computer or a different USB port"); + messageOutput(true, "8. You can contact me for help, but some basic electronics diagnostics will help, checkout YouTube for guides."); + + m_device.enableWriting(false); + return false; + } + + messageOutput(false, "Hurray! Writing was successful. Your Arduino is ready for use! - Send us a photo"); + messageOutput(false, "or join my Discord server at https://discord.gg/HctVgSFEXu"); + m_device.enableWriting(false); + return true; +} + +// Get the current firmware version. Only valid if openPort is successful +const FirmwareVersion ADFWriter::getFirwareVersion() const { + return m_device.getFirwareVersion(); +}; + +// Writes an ADF file back to a floppy disk. Return FALSE in the callback to abort this operation +// IF using precomp mode then DO NOT connect the Arduino via a USB hub, and try to plug it into a USB2 port +ADFResult ADFWriter::ADFToDisk(const std::wstring& inputFile, bool verify, bool usePrecompMode, std::function < WriteResponse(const int currentTrack, const DiskSurface currentSide, const bool isVerifyError) > callback) { + if (!m_device.isOpen()) return ADFResult::adfrDriveError; + + // Upgrade to writing mode + if (m_device.enableWriting(true, true)!=DiagnosticResponse::drOK) return ADFResult::adfrDriveError; + + // Attempt to open the file +#ifdef _WIN32 + std::ifstream hADFFile(inputFile, std::ifstream::in | std::ifstream::binary); +#else + std::string inputFileA; + quickw2a(inputFile,inputFileA); + std::ifstream hADFFile(inputFileA, std::ifstream::in | std::ifstream::binary); +#endif + if (!hADFFile.is_open()) return ADFResult::adfrFileError; + + unsigned int currentTrack = 0; + unsigned int surfaceIndex = 0; + + // Buffer to hold the track + RawDecodedTrack track; + FullDiskTrack disktrack; + memset(disktrack.filler1, 0xAA, sizeof(disktrack.filler1)); // Pad with "0"s which as an MFM encoded byte is 0xAA + memset(disktrack.filler2, 0xAA, sizeof(disktrack.filler2)); // Pad with "0"s which as an MFM encoded byte is 0xAA + + // Just make sure nothing weird is going on + assert(sizeof(track) == ADF_TRACK_SIZE); + bool errors = false; + + + while (hADFFile.good()) { + hADFFile.read((char*)&track, ADF_TRACK_SIZE); + std::streamsize bytesRead = hADFFile.gcount(); + + // Stop if we didnt read a full track + if (bytesRead != ADF_TRACK_SIZE) break; + + // Select the track we're working on + if (m_device.selectTrack(currentTrack)!= DiagnosticResponse::drOK) { + hADFFile.close(); + return ADFResult::adfrDriveError; + } + + DiskSurface surface = (surfaceIndex == 1) ? DiskSurface::dsUpper : DiskSurface::dsLower; + // Change the surface we're targeting + if (m_device.selectSurface(surface) != DiagnosticResponse::drOK) { + hADFFile.close(); + return ADFResult::adfrDriveError; + } + + // Handle callback + if (callback) + if (callback(currentTrack, surface, false) == WriteResponse::wrAbort) { + hADFFile.close(); + return ADFResult::adfrAborted; + } + + unsigned char lastByte = disktrack.filler1[sizeof(disktrack.filler1)-1]; + // Now encode the sector into the output buffer + for (unsigned int sector = 0; sector < NUM_SECTORS_PER_TRACK; sector++) + encodeSector(currentTrack, surface, sector, track[sector], disktrack.sectors[sector], lastByte); + if (lastByte & 1) disktrack.filler2[7] = 0x2F; else disktrack.filler2[7] = 0xFF; + + // Keep looping until it wrote correctly + DecodedTrack trackRead; + trackRead.validSectors.clear(); + for (unsigned int a = 0; a < NUM_SECTORS_PER_TRACK; a++) trackRead.invalidSectors[a].clear(); + + int failCount = 0; + while (trackRead.validSectors.size()= 40) && usePrecompMode); + if (resp == DiagnosticResponse::drOldFirmware) resp = m_device.writeCurrentTrack((const unsigned char*)(&disktrack), sizeof(disktrack), false); + + switch (resp) { + case DiagnosticResponse::drWriteProtected: hADFFile.close(); + return ADFResult::adfrDiskWriteProtected; + case DiagnosticResponse::drOK: break; + default: hADFFile.close(); + return ADFResult::adfrDriveError; + } + + if (verify) { + for (int retries=0; retries<10; retries++) { + RawTrackData data; + // Read the track back + if (m_device.readCurrentTrack(data, false) == DiagnosticResponse::drOK) { + // Find hopefully all sectors + findSectors(data, currentTrack, surface, AMIGA_WORD_SYNC, trackRead, false); + } + if (trackRead.validSectors.size() == NUM_SECTORS_PER_TRACK) break; + } + + // So we found all 11 sectors, but were they the ones we actually wrote!? + if (trackRead.validSectors.size() == NUM_SECTORS_PER_TRACK) { + int sectorsGood = 0; + for (int sector = 0; sector < NUM_SECTORS_PER_TRACK; sector++) { + auto index = std::find_if(trackRead.validSectors.begin(), trackRead.validSectors.end(), [sector](const DecodedSector& sectorfound) -> bool { + return (sectorfound.sectorNumber == sector); + }); + + // We found this sector. + if (index != trackRead.validSectors.end()) { + DecodedSector& rec = trackRead.validSectors[index - trackRead.validSectors.begin()]; + if (memcmp(rec.data, track[sector], SECTOR_BYTES) == 0) { + sectorsGood++; // this one matches on read! + } + } + } + if (sectorsGood != NUM_SECTORS_PER_TRACK) { + // Something went wrong, so we clear them all so it gets reported as an error + trackRead.validSectors.clear(); + } + } + + + // We failed to verify this track. + if (trackRead.validSectors.size() < NUM_SECTORS_PER_TRACK) { + failCount++; + if (failCount >= 5) { + if (!callback) break; + bool breakOut = false; + + switch (callback(currentTrack, surface, true)) { + case WriteResponse::wrAbort: hADFFile.close(); + return ADFResult::adfrAborted; + case WriteResponse::wrSkipBadChecksums: breakOut = true; errors = true; break; + case WriteResponse::wrContinue: break; + default: break; + } + if (breakOut) break; + failCount = 0; + } + } + } + else break; + } + + // Goto the next surface/track + surfaceIndex++; + if (surfaceIndex > 1) { + surfaceIndex = 0; + currentTrack++; + } + // But there is a physical limit + if (currentTrack > 81) break; + } + + return errors? ADFResult::adfrCompletedWithErrors: ADFResult::adfrComplete; +} + +#pragma pack(1) + +/* Taken from https://www.cbmstuff.com/downloads/scp/scp_image_specs.txt +This information is copyright(C) 2012 - 2020 By Jim Drew.Permission is granted +for inclusion with any source code when keeping this copyright notice. +*/ +struct SCPFileHeader { + char headerSCP[3]; + unsigned char version; + unsigned char diskType; + unsigned char numRevolutions; + unsigned char startTrack; + unsigned char endTrack; + unsigned char flags; + unsigned char bitcellEncoding; + unsigned char numHeads; + unsigned char timeBase; + unsigned long checksum; +}; + +struct SCPTrackHeader { + char headerTRK[3]; + unsigned char trackNumber; +}; + +struct SCPTrackRevolution { + unsigned long indexTime; // Time in NS/25 for this revolution + unsigned long trackLength; // Number of bit-cells in this revolution + unsigned long dataOffset; // From the start of SCPTrackHeader +}; + +// Track data is 16-bit value in NS/25. If =0 means no flux transition for max time +#pragma pack() + +#define BITFLAG_INDEX 0 +#define BITFLAG_NORMALISED 3 + +typedef std::vector SCPTrackData; + +struct SCPTrackInMemory { + SCPTrackHeader header; + std::vector revolution; + std::vector revolutionData; +}; + +// Reads the disk and write the data to the SCP file supplied. The callback is for progress, and you can returns FALSE to abort the process +// numTracks is the number of tracks to read. Usually 80 (0..79), sometimes track 80 and 81 are needed. revolutions is hwo many revolutions of the disk to save (1-5) +// SCP files are a low level flux record of the disk and usually can backup copy protected disks to. Without special hardware they can't usually be written back to disks. +ADFResult ADFWriter::DiskToSCP(const std::wstring& outputFile, const unsigned int numTracks, const unsigned char revolutions, std::function < WriteResponse(const int currentTrack, const DiskSurface currentSide, const int retryCounter, const int sectorsFound, const int badSectorsFound)> callback) { + if (!m_device.isOpen()) return ADFResult::adfrDriveError; + + FirmwareVersion v = m_device.getFirwareVersion(); + if ((v.major == 1) && (v.minor < 8)) return ADFResult::adfrFirmwareTooOld; + + // Higher than this is not supported + if (numTracks > 82) return ADFResult::adfrDriveError; + if (revolutions < 1) return ADFResult::adfrDriveError; + if (revolutions > 5) return ADFResult::adfrDriveError; + + // Attempt ot open the file +#ifdef _WIN32 + std::fstream hADFFile = std::fstream(outputFile, std::ofstream::out | std::ofstream::in | std::ofstream::binary | std::ofstream::trunc); +#else + std::string outputFileA; + quickw2a(outputFile,outputFileA); + std::fstream hADFFile = std::fstream(outputFileA, std::ofstream::out | std::ofstream::in | std::ofstream::binary | std::ofstream::trunc); +#endif + if (!hADFFile.is_open()) return ADFResult::adfrFileError; + + SCPFileHeader header; + header.headerSCP[0] = 'S'; + header.headerSCP[1] = 'C'; + header.headerSCP[2] = 'P'; + header.version = 2 | (2 << 4); // CHECK + header.diskType = 0x80; + header.numRevolutions = revolutions; + header.startTrack = 0; + header.numHeads = 0; // both heads + header.timeBase = 0; + header.endTrack = (numTracks*2) - 1; + header.flags = (1 << BITFLAG_INDEX) | (1 << BITFLAG_NORMALISED); + header.bitcellEncoding = 0; // 25ns + // to be calculated + header.checksum = 0; + + SCPTrackInMemory track; + track.header.headerTRK[0] = 'T'; + track.header.headerTRK[1] = 'R'; + track.header.headerTRK[2] = 'K'; + + try { + hADFFile.write((const char*)&header, sizeof(header)); + } catch (...) { + hADFFile.close(); + return ADFResult::adfrFileIOError; + } + + // Pad out the records. Theres 4 bytes for each track + unsigned long notPresent = 0; + for (unsigned int a = 0; a <168; a++) { + try { + hADFFile.write((const char*)¬Present, sizeof(notPresent)); + } catch (...) { + hADFFile.close(); + return ADFResult::adfrFileIOError; + } + } + + RotationExtractor extractor; + extractor.setAlwaysUseIndex(true); + RotationExtractor::MFMSample samples[RAW_TRACKDATA_LENGTH]; + + // Do all tracks + for (unsigned int currentTrack = 0; currentTrack < numTracks; currentTrack++) { + + // Select the track we're working on + if (m_device.selectTrack(currentTrack) != DiagnosticResponse::drOK) { + hADFFile.close(); + return ADFResult::adfrCompletedWithErrors; + } + + // Now select the side + for (unsigned int surfaceIndex = 0; surfaceIndex < 2; surfaceIndex++) { + // Surface + const DiskSurface surface = (surfaceIndex == 1) ? DiskSurface::dsUpper : DiskSurface::dsLower; + track.revolution.clear(); + track.revolutionData.clear(); + track.header.trackNumber = (currentTrack * 2) + surfaceIndex; + + // Change the surface we're looking at + if (m_device.selectSurface(surface) != DiagnosticResponse::drOK) { + hADFFile.close(); + return ADFResult::adfrCompletedWithErrors; + } + + if (callback) { + switch (callback(currentTrack, surface, 0, 0, 0)) { + case WriteResponse::wrContinue: break; // do nothing + case WriteResponse::wrAbort: hADFFile.close(); + return ADFResult::adfrAborted; + default: break; + } + } + + // Read in the data in 'raw' mode + RotationExtractor::IndexSequenceMarker startPatterns; + SCPTrackRevolution currentRev; + currentRev.indexTime = 0; + currentRev.trackLength = 0; + + SCPTrackData currentRevData; + + if (m_device.readRotation(extractor, RAW_TRACKDATA_LENGTH, samples, startPatterns, [this, &track, ¤tRev, ¤tRevData, revolutions](RotationExtractor::MFMSample** _mfmData, unsigned int dataLengthInBits)->bool { + RotationExtractor::MFMSample* mfmData = *_mfmData; + unsigned int currentTime = 0; + unsigned int numBits = 0; + + for (unsigned int a = 0; a < dataLengthInBits; a++) { + const unsigned int bit = 7 - (a & 7); + + currentTime += (unsigned int)mfmData->bittime[bit]; + numBits++; + + // Bit found? + if (mfmData->mfmData & (1 << bit)) { + + // Convert to 25ns times + currentTime /= 25; + + // Keep track of time + currentRev.indexTime += currentTime; + + // Handle data too big + while (currentTime > 65535) { + currentRevData.push_back(0); + currentTime -= 65536; + } + + // Save + currentRevData.push_back((unsigned short)(((currentTime & 0xFF) << 8) | ((currentTime >> 8) & 0xFF))); + currentRev.trackLength++; + + // Reset + numBits = 0; + currentTime = 0; + } + + // Skip to next bit of data + if (bit == 0) mfmData++; + } + + track.revolution.push_back(currentRev); + track.revolutionData.push_back(currentRevData); + + currentRev.indexTime = 0; + currentRev.trackLength = 0; + currentRevData.clear(); + + // Stop when we have enough data + return track.revolution.size() < revolutions; + + }) != DiagnosticResponse::drOK) { + hADFFile.close(); + return ADFResult::adfrDriveError; + } + + // Get the current position + unsigned long currentPosition = (unsigned long)hADFFile.tellp(); + + // Move to the beginning of the file, and write the offset for where this starts + hADFFile.seekp(sizeof(header) + (track.header.trackNumber * 4), std::fstream::beg); + try { + hADFFile.write((const char*)¤tPosition, 4); + } catch (...) { + hADFFile.close(); + return ADFResult::adfrFileIOError; + } + + // Restore position and save data + hADFFile.seekp(currentPosition, std::fstream::beg); + + // Write the header + try { + hADFFile.write((const char*)&track.header, sizeof(track.header)); + } catch (...) { + hADFFile.close(); + return ADFResult::adfrFileIOError; + } + + // Write out the revolution headers + unsigned int dataPos = sizeof(track.header) + (track.revolution.size() * sizeof(SCPTrackRevolution)); + for (unsigned int a = 0; a < track.revolution.size(); a++) { + track.revolution[a].dataOffset = dataPos; + try { + hADFFile.write((const char*)&track.revolution[a], sizeof(track.revolution[a])); + } catch (...) { + hADFFile.close(); + return ADFResult::adfrFileIOError; + } + dataPos += track.revolutionData[a].size() * 2; + } + + // Now write out the data + for (unsigned int a = 0; a < track.revolutionData.size(); a++) { + try { + hADFFile.write((const char*)track.revolutionData[a].data(), track.revolutionData[a].size() * 2); + } catch (...) { + hADFFile.close(); + return ADFResult::adfrFileIOError; + } + } + } + } + + // Compute the checksum + hADFFile.seekg(sizeof(header), std::fstream::beg); + unsigned int buffer[128]; + + while (hADFFile.good()) { + try { + hADFFile.read((char*)buffer, sizeof(buffer)); + const unsigned long read = sizeof(buffer) / 4; + for (size_t pos = 0; pos < read; pos++) + header.checksum += buffer[pos]; + } + catch (...) { + } + } + hADFFile.clear(); + hADFFile.seekp(0, std::fstream::beg); + + // Write the header again with the checksum in it + try { + hADFFile.write((const char*)&header, sizeof(header)); + } catch (...) { + hADFFile.close(); + return ADFResult::adfrFileIOError; + } + + hADFFile.close(); + + return ADFResult::adfrComplete; +} + + +// Reads the disk and write the data to the ADF file supplied. The callback is for progress, and you can returns FALSE to abort the process +ADFResult ADFWriter::DiskToADF(const std::wstring& outputFile, const unsigned int numTracks, std::function < WriteResponse(const int currentTrack, const DiskSurface currentSide, const int retryCounter, const int sectorsFound, const int badSectorsFound)> callback) { + if (!m_device.isOpen()) return ADFResult::adfrDriveError; + + // Higher than this is not supported + if (numTracks>82) return ADFResult::adfrDriveError; + + // Attempt ot open the file +#ifdef _WIN32 + std::ofstream hADFFile = std::ofstream(outputFile, std::ofstream::out | std::ofstream::binary | std::ofstream::trunc); +#else + std::string outputFileA; + quickw2a(outputFile,outputFileA); + std::ofstream hADFFile = std::ofstream(outputFileA, std::ofstream::out | std::ofstream::binary | std::ofstream::trunc); +#endif + if (!hADFFile.is_open()) return ADFResult::adfrFileError; + + // To hold a raw track + RawTrackData data; + DecodedTrack track; + bool includesBadSectors = false; + + // Do all tracks + for (unsigned int currentTrack = 0; currentTrack < numTracks; currentTrack++) { + + // Select the track we're working on + if (m_device.selectTrack(currentTrack) != DiagnosticResponse::drOK) { + hADFFile.close(); + return ADFResult::adfrCompletedWithErrors; + } + + // Now select the side + for (unsigned int surfaceIndex = 0; surfaceIndex < 2; surfaceIndex++) { + // Surface + const DiskSurface surface = (surfaceIndex == 1) ? DiskSurface::dsUpper : DiskSurface::dsLower; + + // Change the surface we're looking at + if (m_device.selectSurface(surface) != DiagnosticResponse::drOK) { + hADFFile.close(); + return ADFResult::adfrCompletedWithErrors; + } + + // Reset the sectors list + for (unsigned int sector=0; sector bool { + return (sector.sectorNumber == sectornumber); + }); + // Not found. Lets add it + if (index == track.validSectors.end()) { + DecodedSector sector; + memset(§or, 0, sizeof(sector)); + sector.sectorNumber = sectornumber; + track.validSectors.push_back(sector); + } + } + } + ignoreChecksums = true; + failureTotal = 0; + break; + } + } + + if (m_device.readCurrentTrack(data, false) == DiagnosticResponse::drOK) { + findSectors(data, currentTrack, surface, AMIGA_WORD_SYNC, track, ignoreChecksums); + failureTotal++; + } + else { + hADFFile.close(); + return ADFResult::adfrDriveError; + } + + // If the user wants to skip invalid sectors and save them + if (ignoreChecksums) { + for (unsigned int sector = 0; sector < NUM_SECTORS_PER_TRACK; sector++) + if (track.invalidSectors[sector].size()) { + includesBadSectors = true; + break; + } + mergeInvalidSectors(track); + } + } + + // Sort the sectors in order + std::sort(track.validSectors.begin(), track.validSectors.end(), [](const DecodedSector & a, const DecodedSector & b) -> bool { + return a.sectorNumber < b.sectorNumber; + }); + + // Now write all of them to disk + for (unsigned int sector = 0; sector < 11; sector++) { + try { + hADFFile.write((const char*)track.validSectors[sector].data, 512); + } + catch (...) { + hADFFile.close(); + return ADFResult::adfrFileIOError; + } + } + } + } + + hADFFile.close(); + + return includesBadSectors ? ADFResult::adfrCompletedWithErrors : ADFResult::adfrComplete; +} \ No newline at end of file diff --git a/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/lib/ADFWriter.h b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/lib/ADFWriter.h new file mode 100644 index 00000000..e9408925 --- /dev/null +++ b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/lib/ADFWriter.h @@ -0,0 +1,109 @@ +/* ArduinoFloppyReader (and writer) +* +* Copyright (C) 2017-2021 Robert Smith (@RobSmithDev) +* http://amiga.robsmithdev.co.uk +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Library General Public +* License as published by the Free Software Foundation; either +* version 3 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 +* Library General Public License for more details. +* +* You should have received a copy of the GNU Library General Public +* License along with this library; if not, see http://www.gnu.org/licenses/ +*/ + +////////////////////////////////////////////////////////////////////////////////////////// +// Class that reads reads the MFM data, decodes it, and then writes an ADF file to disk // +////////////////////////////////////////////////////////////////////////////////////////// +// +// Purpose: +// This class reads the raw data from the device and attemps to check for errors. +// Once all errors have been corrected the class will save the tracks to disk as an ADF file +// +// The class also handles writing an ADF file back to disk and optionally verifying the write. +// +// The MFM decoding algorithm and information regarding finding the start of a sector +// were taken from the excellent documentation by Laurent Clvy at http://lclevy.free.fr/adflib/adf_info.html +// Also credits to Keith Monahan https://www.techtravels.org/tag/mfm/ regarding a bug in the MFM sector start data +// +// V2.5 + +#pragma once +#include + +#include "RotationExtractor.h" +#include "ArduinoInterface.h" + + +namespace ArduinoFloppyReader { + + // Optional how to respond to the callback from the writeADF command. + enum class WriteResponse { + wrContinue, // Continue working as normal + wrAbort, // Abort thr process and stop + wrSkipBadChecksums, // Request that the process ignores bad checksums (not recommended unless the retryCounter gets beyond RETRYS_PER_PHASE*16) + wrRetry // Retry! + }; + + enum class ADFResult { + adfrComplete, // Process completed successfully + adfrAborted, // Process was aborted + adfrFileError, // Error opening the file to write to + adfrFileIOError, // Error writing to the ADF file + adfrCompletedWithErrors, // Completed but with sector errors + adfrDiskWriteProtected, // Disk is write protected! + adfrDriveError, // Something wrong with reading the disk + adfrFirmwareTooOld // Firmware is too old + }; + + enum class AnalysisResult { + arComplete, // Anaysis is complete and ready for use + arFailed, // Anaysis failed to read a disk + arAborted, // Analysis was aborted + arDriveError // Something wrong talking to thre drive + }; + + // Main writer class + class ADFWriter { + private: + // The Arduino device + ArduinoInterface m_device; + + public: + // Open the device we want to use. Returns TRUE if it worked + bool openDevice(const std::wstring& portName); + + // Close the device when we've finished + void closeDevice(); + + // Get the current firmware version. Only valid if openDevice is successful + const FirmwareVersion getFirwareVersion() const; + + std::string getLastError() { return m_device.getLastErrorStr(); }; + + // Reads the disk and write the data to the ADF file supplied. The callback is for progress, and you can returns FALSE to abort the process + // numTracks is the number of tracks to read. Usually 80 (0..79), sometimes track 80 and 81 are needed + ADFResult DiskToADF(const std::wstring& outputFile, const unsigned int numTracks, std::function < WriteResponse(const int currentTrack, const DiskSurface currentSide, const int retryCounter, const int sectorsFound, const int badSectorsFound)> callback); + + // Reads the disk and write the data to the SCP file supplied. The callback is for progress, and you can returns FALSE to abort the process + // numTracks is the number of tracks to read. Usually 80 (0..79), sometimes track 80 and 81 are needed. revolutions is hwo many revolutions of the disk to save (1-5) + // SCP files are a low level flux record of the disk and usually can backup copy protected disks to. Without special hardware they can't usually be written back to disks. + ADFResult DiskToSCP(const std::wstring& outputFile, const unsigned int numTracks, const unsigned char revolutions, std::function < WriteResponse(const int currentTrack, const DiskSurface currentSide, const int retryCounter, const int sectorsFound, const int badSectorsFound)> callback); + + // Writes an ADF file back to a floppy disk. Return FALSE in the callback to abort this operation. If verify is set then the track isread back and and sector checksums are checked for 11 valid sectors + // IF using precomp mode then DO NOT connect the Arduino via a USB hub, and try to plug it into a USB2 port + ADFResult ADFToDisk(const std::wstring& inputFile, bool verify, bool usePrecompMode, std::function < WriteResponse(const int currentTrack, const DiskSurface currentSide, const bool isVerifyError) > callback); + + // Run diagnostics on the system. You do not need to call openDevice first. Return TRUE if everything passed + bool runDiagnostics(const std::wstring& portName, std::function messageOutput, std::function askQuestion); + + }; + + + +}; diff --git a/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/lib/ArduinoInterface.cpp b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/lib/ArduinoInterface.cpp new file mode 100644 index 00000000..18431720 --- /dev/null +++ b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/lib/ArduinoInterface.cpp @@ -0,0 +1,1346 @@ +/* ArduinoFloppyReader (and writer) +* +* Copyright (C) 2017-2021 Robert Smith (@RobSmithDev) +* https://amiga.robsmithdev.co.uk +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Library General Public +* License as published by the Free Software Foundation; either +* version 3 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 +* Library General Public License for more details. +* +* You should have received a copy of the GNU Library General Public +* License along with this library; if not, see http://www.gnu.org/licenses/ +*/ + +//////////////////////////////////////////////////////////////////////////////////////// +// Class to manage the communication between the computer and the Arduino V2.5 // +//////////////////////////////////////////////////////////////////////////////////////// +// +// Purpose: +// The class handles the command interface to the arduino. It doesn't do any decoding +// Just open ports, switch motors on and off, seek to tracks etc. +// +// +// + +#include "ArduinoInterface.h" +#include +#include +#include +#include +#include "RotationExtractor.h" +#ifndef _WIN32 +#include +#endif + +using namespace ArduinoFloppyReader; + +// Command that the ARDUINO Sketch understands +#define COMMAND_VERSION '?' +#define COMMAND_REWIND '.' +#define COMMAND_GOTOTRACK '#' +#define COMMAND_HEAD0 '[' +#define COMMAND_HEAD1 ']' +#define COMMAND_READTRACK '<' +#define COMMAND_ENABLE '+' +#define COMMAND_DISABLE '-' +#define COMMAND_WRITETRACK '>' +#define COMMAND_ENABLEWRITE '~' +#define COMMAND_DIAGNOSTICS '&' +#define COMMAND_ERASETRACK 'X' +#define COMMAND_SWITCHTO_DD 'D' // Requires Firmware V1.6 +#define COMMAND_SWITCHTO_HD 'H' // Requires Firmware V1.6 +#define COMMAND_DETECT_DISK_TYPE 'M' // currently not implemented here + +// New commands for more direct control of the drive. Some of these are more efficient or dont turn the disk motor on for modded hardware +#define COMMAND_READTRACKSTREAM '{' // Requires Firmware V1.8 +#define COMMAND_WRITETRACKPRECOMP '}' // Requires Firmware V1.8 +#define COMMAND_CHECKDISKEXISTS '^' // Requires Firmware V1.8 (and modded hardware for fast version) +#define COMMAND_ISWRITEPROTECTED '$' // Requires Firmware V1.8 +#define COMMAND_ENABLE_NOWAIT '*' // Requires Firmware V1.8 +#define COMMAND_GOTOTRACK_REPORT '=' // Requires Firmware V1.8 +#define COMMAND_DO_NOCLICK_SEEK 'O' // Requires Firmware V1.8a + +#define SPECIAL_ABORT_CHAR 'x' + +// Convert the last executed command that had an error to a string +std::string lastCommandToName(LastCommand cmd) { + switch (cmd) { + case LastCommand::lcOpenPort: return "OpenPort"; + case LastCommand::lcGetVersion: return "GetVersion"; + case LastCommand::lcEnableWrite: return "EnableWrite"; + case LastCommand::lcRewind: return "Rewind"; + case LastCommand::lcDisableMotor: return "DisableMotor"; + case LastCommand::lcEnableMotor: return "EnableMotor"; + case LastCommand::lcGotoTrack: return "GotoTrack"; + case LastCommand::lcSelectSurface: return "SelectSurface"; + case LastCommand::lcReadTrack: return "ReadTrack"; + case LastCommand::lcWriteTrack: return "WriteTrack"; + case LastCommand::lcRunDiagnostics: return "RunDiagnostics"; + case LastCommand::lcSwitchDiskMode: return "SetCapacity"; + case LastCommand::lcReadTrackStream: return "ReadTrackStream"; + case LastCommand::lcCheckDiskInDrive: return "CheckDiskInDrive"; + case LastCommand::lcCheckDiskWriteProtected: return "CheckDiskWriteProtected"; + case LastCommand::lcEraseTrack: return "EraseTrack"; + + default: return "Unknown"; + } +} + +// Uses the above fields to constructr a suitable error message, hopefully useful in diagnosing the issue +const std::string ArduinoInterface::getLastErrorStr() const { + std::stringstream tmp; + switch (m_lastError) { + case DiagnosticResponse::drOldFirmware: return "The Arduino is running an older version of the firmware/sketch. Please re-upload."; + case DiagnosticResponse::drOK: return "Last command completed successfully."; + case DiagnosticResponse::drPortInUse: return "The specified COM port is currently in use by another application."; + case DiagnosticResponse::drPortNotFound: return "The specified COM port was not found."; + case DiagnosticResponse::drAccessDenied: return "The operating system denied access to the specified COM port."; + case DiagnosticResponse::drComportConfigError: return "We were unable to configure the COM port using the SetCommConfig() command."; + case DiagnosticResponse::drBaudRateNotSupported: return "The COM port does not support the 2M baud rate required by this application."; + case DiagnosticResponse::drErrorReadingVersion: return "An error occured attempting to read the version of the sketch running on the Arduino."; + case DiagnosticResponse::drErrorMalformedVersion: return "The Arduino returned an unexpected string when version was requested. This could be a baud rate mismatch or incorrect loaded sketch."; + case DiagnosticResponse::drCTSFailure: return "Diagnostics reports the CTS line is not connected correctly or is not behaving correctly."; + case DiagnosticResponse::drTrackRangeError: return "An error occured attempting to go to a track number that was out of allowed range."; + case DiagnosticResponse::drWriteProtected: return "Unable to write to the disk. The disk is write protected."; + case DiagnosticResponse::drPortError: return "An unknown error occured attempting to open access to the specified COM port."; + case DiagnosticResponse::drDiagnosticNotAvailable: return "CTS diagnostic not available, command GetCommModemStatus failed to execute."; + case DiagnosticResponse::drSelectTrackError: return "Arduino reported an error seeking to a specific track."; + case DiagnosticResponse::drTrackWriteResponseError: return "Error receiving status from Arduino after a track write operation."; + case DiagnosticResponse::drSendDataFailed: return "Error sending track data to be written to disk. This could be a COM timeout."; + case DiagnosticResponse::drRewindFailure: return "Arduino was unable to find track 0. This could be a wiring fault or power supply failure."; + case DiagnosticResponse::drNoDiskInDrive: return "No disk in drive"; + case DiagnosticResponse::drWriteTimeout: return "The Arduino could not receive the data quick enough to write to disk. Try connecting via USB2 and not using a USB hub.\n\nIf this still does not work, turn off precomp if you are using it."; + case DiagnosticResponse::drFramingError: return "The Arduino received bad data from the PC. This could indicate poor connectivity, bad baud rate matching or damaged cables."; + case DiagnosticResponse::drSerialOverrun: return "The Arduino received data faster than it could handle. This could either be a fault with the CTS connection or the USB/serial interface is faulty"; + case DiagnosticResponse::drUSBSerialBad: return "The USB->Serial converter being used isn't suitable and doesnt run consistantly fast enough. Please ensure you use a genuine FTDI adapter."; + case DiagnosticResponse::drError: tmp << "Arduino responded with an error running the " << lastCommandToName(m_lastCommand) << " command."; + return tmp.str(); + + case DiagnosticResponse::drReadResponseFailed: + switch (m_lastCommand) { + case LastCommand::lcGotoTrack: return "Unable to read response from Arduino after requesting to go to a specific track"; + case LastCommand::lcReadTrack: return "Gave up trying to read a full track from the disk."; + case LastCommand::lcWriteTrack: return "Unable to read response to requesting to write a track."; + default: tmp << "Error reading response from the Arduino while running command " << lastCommandToName(m_lastCommand) << "."; + return tmp.str(); + } + + case DiagnosticResponse::drSendFailed: + if (m_lastCommand == LastCommand::lcGotoTrack) + return "Unable to send the complete select track command to the Arduino."; + else { + tmp << "Error sending the command " << lastCommandToName(m_lastCommand) << " to the Arduino."; + return tmp.str(); + } + + case DiagnosticResponse::drSendParameterFailed: tmp << "Unable to send a parameter while executing the " << lastCommandToName(m_lastCommand) << " command."; + return tmp.str(); + case DiagnosticResponse::drStatusError: tmp << "An unknown response was was received from the Arduino while executing the " << lastCommandToName(m_lastCommand) << " command."; + return tmp.str(); + + default: return "Unknown error."; + } +} + +// Constructor for this class +ArduinoInterface::ArduinoInterface() { + m_abortStreaming = true; + m_version = { 0,0,false }; + m_lastError = DiagnosticResponse::drOK; + m_lastCommand = LastCommand::lcGetVersion; + m_inWriteMode = false; + m_isWriteProtected = false; + m_diskInDrive = false; + m_abortSignalled = false; + m_isStreaming = false; +} + +// Free me +ArduinoInterface::~ArduinoInterface() { + abortReadStreaming(); + closePort(); +} + +// Checks if the disk is write protected. If forceCheck=false then the last cached version is returned. This is also updated by checkForDisk() as well as this function +DiagnosticResponse ArduinoInterface::checkIfDiskIsWriteProtected(bool forceCheck) { + if (!forceCheck) { + return m_isWriteProtected ? DiagnosticResponse::drWriteProtected : DiagnosticResponse::drOK; + } + + // Test manually + m_lastCommand = LastCommand::lcCheckDiskWriteProtected; + + // If no hardware support then return no change + if ((m_version.major == 1) && (m_version.minor < 8)) { + m_lastError = DiagnosticResponse::drOldFirmware; + return m_lastError; + } + + // Send and update flag + m_lastError = checkForDisk(true); + if ((m_lastError == DiagnosticResponse::drStatusError) || (m_lastError == DiagnosticResponse::drOK)) { + m_lastCommand = LastCommand::lcCheckDiskWriteProtected; + + if (m_isWriteProtected) m_lastError = DiagnosticResponse::drWriteProtected; + } + + return m_lastError; +} + +// This only works normally after the motor has been stepped in one direction or another. This requires the 'advanced' configuration +DiagnosticResponse ArduinoInterface::checkForDisk(bool forceCheck) { + if (!forceCheck) { + return m_diskInDrive ? DiagnosticResponse::drOK : DiagnosticResponse::drNoDiskInDrive; + } + + // Test manually + m_lastCommand = LastCommand::lcCheckDiskInDrive; + + // If no hardware support then return no change + if ((m_version.major == 1) && (m_version.minor < 8)) { + m_lastError = DiagnosticResponse::drOldFirmware; + return m_lastError; + } + + char response; + m_lastError = runCommand(COMMAND_CHECKDISKEXISTS, '\0', &response); + if ((m_lastError == DiagnosticResponse::drStatusError) || (m_lastError == DiagnosticResponse::drOK)) { + if (response == '#') { + m_lastError = DiagnosticResponse::drNoDiskInDrive; + m_diskInDrive = false; + } + else { + if (response == '1') m_diskInDrive = true; + } + + // Also read the write protect status + if (!deviceRead(&response, 1, true)) { + m_lastError = DiagnosticResponse::drReadResponseFailed; + return m_lastError; + } + + if ((response == '1') || (response == '#')) m_isWriteProtected = response == '1'; + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } + return m_lastError; +} + +// Check if an index pulse can be detected from the drive +DiagnosticResponse ArduinoInterface::testIndexPulse() { + // Port opned. We need to check what happens as the pin is toggled + m_lastError = runCommand(COMMAND_DIAGNOSTICS, '3'); + if (m_lastError != DiagnosticResponse::drOK) { + m_lastCommand = LastCommand::lcRunDiagnostics; + return m_lastError; + } + return m_lastError; +} + +// Check if data can be detected from the drive +DiagnosticResponse ArduinoInterface::testDataPulse() { + // Port opned. We need to check what happens as the pin is toggled + m_lastError = runCommand(COMMAND_DIAGNOSTICS, '4'); + if (m_lastError != DiagnosticResponse::drOK) { + m_lastCommand = LastCommand::lcRunDiagnostics; + return m_lastError; + } + return m_lastError; +} + +// Check if the USB to Serial device can keep up properly +DiagnosticResponse ArduinoInterface::testTransferSpeed() { + // Port opned. We need to receive about 10 * 256 bytes of data and verify its all valid + m_lastError = runCommand(COMMAND_DIAGNOSTICS, '5'); + if (m_lastError != DiagnosticResponse::drOK) { + m_lastCommand = LastCommand::lcRunDiagnostics; + return m_lastError; + } + applyCommTimeouts(true); + + unsigned char buffer[256]; + for (int a = 0; a <= 10; a++) { + unsigned long read; + + read = m_comPort.read(buffer, sizeof(buffer)); + + // With the timeouts we have this shouldn't happen + if (read != sizeof(buffer)) { + m_lastCommand = LastCommand::lcRunDiagnostics; + m_lastError = DiagnosticResponse::drUSBSerialBad; + applyCommTimeouts(false); + return m_lastError; + } + + for (size_t c = 0; c < read; c++) { + if (buffer[c] != c) { + m_lastCommand = LastCommand::lcRunDiagnostics; + m_lastError = DiagnosticResponse::drUSBSerialBad; + applyCommTimeouts(false); + return m_lastError; + } + } + } + + applyCommTimeouts(false); + return m_lastError; +} + +// Check CTS status by asking the device to set it and then checking what happened +DiagnosticResponse ArduinoInterface::testCTS() { + + for (int a = 1; a <= 10; a++) { + // Port opned. We need to check what happens as the pin is toggled + m_lastError = runCommand(COMMAND_DIAGNOSTICS, (a & 1) ? '1' : '2'); + if (m_lastError != DiagnosticResponse::drOK) { + m_lastCommand = LastCommand::lcRunDiagnostics; + closePort(); + return m_lastError; + } + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + + bool ctsStatus = m_comPort.getCTSStatus(); + + // This doesnt actually run a command, this switches the CTS line back to its default setting + m_lastError = runCommand(COMMAND_DIAGNOSTICS); + + if (ctsStatus ^ ((a & 1) != 0)) { + // If we get here then the CTS value isn't what it should be + closePort(); + m_lastError = DiagnosticResponse::drCTSFailure; + return m_lastError; + } + // Pass. Try the other state + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } + + return DiagnosticResponse::drOK; +} + +// Attempts to verify if the reader/writer is running on this port +bool ArduinoInterface::isPortCorrect(const std::wstring& portName) { + // Attempts to verify if the reader/writer is running on this port + SerialIO port; + std::string version; + DiagnosticResponse dr = internalOpenPort(portName, false, true, version, port); + port.closePort(); + return dr == DiagnosticResponse::drOK; +} + +// Attempt to sync and get version +DiagnosticResponse ArduinoInterface::attemptToSync(std::string& versionString, SerialIO& port) { + char buffer[10]; + + // Send 'Version' Request + buffer[0] = SPECIAL_ABORT_CHAR; + buffer[1] = COMMAND_VERSION; + + unsigned long size = port.write(&buffer[0], 2); + if (size != 2) { + // Couldn't write to device + port.closePort(); + return DiagnosticResponse::drPortError; + } + + memset(buffer, 0, sizeof(buffer)); + int counterNoData = 0; + int counterData = 0; + int bytesRead = 0; + + // Keep a rolling buffer looking for the 1Vxxx response + for (;;) { + size = port.read(&buffer[4], 1); + bytesRead += size; + // Was something read? + if (size) { + if ((buffer[0] == '1') && (buffer[1] == 'V') && ((buffer[2] >= '1') && (buffer[2] <= '9')) && ((buffer[3] == ',') || (buffer[3] == '.')) && ((buffer[4] >= '0') && (buffer[4] <= '9'))) { + + // Success + port.purgeBuffers(); + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + port.purgeBuffers(); + versionString = &buffer[1]; + return DiagnosticResponse::drOK; + } + + // Move backwards + for (int a = 0; a < 4; a++) buffer[a] = buffer[a + 1]; + + if (counterData++ > 2048) { + port.closePort(); + return DiagnosticResponse::drErrorMalformedVersion; + } + } + else { + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + if (counterNoData++ > 120) { + port.closePort(); + return DiagnosticResponse::drErrorReadingVersion; + } + if (((counterNoData % 10) == 9) && (bytesRead == 0)) { + // Give it a kick + buffer[0] = COMMAND_VERSION; + size = port.write(&buffer[0], 1); + if (size != 1) { + // Couldn't write to device + port.closePort(); + return DiagnosticResponse::drPortError; + } + } + } + } +} + +// Attempts to verify if the reader/writer is running on this port +DiagnosticResponse ArduinoInterface::internalOpenPort(const std::wstring& portName, bool enableCTSflowcontrol, bool triggerReset, std::string& versionString, SerialIO& port) { + + switch (port.openPort(portName)) { + case SerialIO::Response::rInUse:return DiagnosticResponse::drPortInUse; + case SerialIO::Response::rNotFound:return DiagnosticResponse::drPortNotFound; + case SerialIO::Response::rOK: break; + default: return DiagnosticResponse::drPortError; + } + + // Configure the port + SerialIO::Configuration config; + config.baudRate = 2000000; + config.ctsFlowControl = enableCTSflowcontrol; + + if (port.configurePort(config) != SerialIO::Response::rOK) return DiagnosticResponse::drPortError; + + port.setBufferSizes(16, 16); + port.setReadTimeouts(10, 250); + port.setWriteTimeouts(2000, 200); + + // Try to get the version + DiagnosticResponse response = attemptToSync(versionString, port); + if (response != DiagnosticResponse::drOK) { + // It failed. Issue a reset if we're allowed and try again + if (triggerReset) { + port.setDTR(true); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + port.setDTR(false); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + port.closePort(); + std::this_thread::sleep_for(std::chrono::milliseconds(250)); + + // Now re-connect and try again + if (port.openPort(portName) != SerialIO::Response::rOK) return DiagnosticResponse::drPortError; + + response = attemptToSync(versionString, port); + if (response != DiagnosticResponse::drOK) { + port.closePort(); + return response; + } + } + else { + port.closePort(); + return response; + } + } + return response; +} + +// Attempts to open the reader running on the COM port number provided. Port MUST support 2M baud +DiagnosticResponse ArduinoInterface::openPort(const std::wstring& portName, bool enableCTSflowcontrol) { + m_lastCommand = LastCommand::lcOpenPort; + closePort(); + + // Quickly force streaming to be aborted + m_abortStreaming = true; + + std::string versionString; + m_lastError = internalOpenPort(portName, enableCTSflowcontrol, true, versionString, m_comPort); + if (m_lastError != DiagnosticResponse::drOK) return m_lastError; + + // it's possible theres still redundant data in the buffer + char buffer[2]; + int counter = 0; + for (;;) { + unsigned long size = m_comPort.read(buffer, 1); + if (size < 1) + if (counter++>=10) break; + } + + // Possibly a bit overkill + m_comPort.setBufferSizes(RAW_TRACKDATA_LENGTH * 2, RAW_TRACKDATA_LENGTH); + + m_version.major = versionString[1] - '0'; + m_version.minor = versionString[3] - '0'; + m_version.fullControlMod = versionString[2] == ','; + + // Switch to normal timeouts + applyCommTimeouts(false); + + // Ok, success + return m_lastError; +} + +// Apply and change the timeouts on the com port +void ArduinoInterface::applyCommTimeouts(bool shortTimeouts) { + if (shortTimeouts) { + m_comPort.setReadTimeouts(5, 12); + } + else { + m_comPort.setReadTimeouts(2000, 200); + } + m_comPort.setWriteTimeouts(2000, 200); +} + +// Closes the port down +void ArduinoInterface::closePort() { + LastCommand old = m_lastCommand; + if (m_comPort.isPortOpen()) { + // Force the drive to power down + enableReading(false); + // And close the handle + m_comPort.closePort(); + } + m_inWriteMode = false; + m_isWriteProtected = false; + m_diskInDrive = false; + m_lastCommand = old; +} + +// Returns true if the track actually contains some data, else its considered blank or unformatted +bool ArduinoInterface::trackContainsData(const RawTrackData& trackData) const { + int zerocount = 0, ffcount = 0; + unsigned char lastByte = trackData[0]; + for (unsigned int counter = 1; counter < RAW_TRACKDATA_LENGTH; counter++) { + if (trackData[counter] == lastByte) { + switch (lastByte) { + case 0xFF: ffcount++; zerocount = 0; break; + case 0x00: ffcount = 0; zerocount++; break; + default: zerocount = 0; ffcount = 0; + } + } + else { + lastByte = trackData[counter]; + zerocount = 0; ffcount = 0; + } + } + + // More than this in a row and its bad + return ((ffcount < 20) && (zerocount < 20)); +} + +// Turns on and off the writing interface. If irError is returned the disk is write protected +DiagnosticResponse ArduinoInterface::enableWriting(const bool enable, const bool reset) { + if (enable) { + // Enable the device + m_lastError = runCommand(COMMAND_ENABLEWRITE); + if (m_lastError == DiagnosticResponse::drError) { + m_lastCommand = LastCommand::lcEnableWrite; + m_lastError = DiagnosticResponse::drWriteProtected; + return m_lastError; + } + if (m_lastError != DiagnosticResponse::drOK) { + m_lastCommand = LastCommand::lcEnableWrite; + return m_lastError; + } + m_inWriteMode = true; + + // Reset? + if (reset) { + // And rewind to the first track + m_lastError = findTrack0(); + if (m_lastError != DiagnosticResponse::drOK) return m_lastError; + + // Lets know where we are + return selectSurface(DiskSurface::dsUpper); + } + m_lastError = DiagnosticResponse::drOK; + return m_lastError; + } + else { + // Disable the device + m_lastError = runCommand(COMMAND_DISABLE); + if (m_lastError != DiagnosticResponse::drOK) { + m_lastCommand = LastCommand::lcDisableMotor; + return m_lastError; + } + m_inWriteMode = false; + + return m_lastError; + } +} + +DiagnosticResponse ArduinoInterface::findTrack0() { + // And rewind to the first track + char status = '0'; + m_lastError = runCommand(COMMAND_REWIND, '\000', &status); + if (m_lastError != DiagnosticResponse::drOK) { + m_lastCommand = LastCommand::lcRewind; + if (status == '#') return DiagnosticResponse::drRewindFailure; + return m_lastError; + } + return m_lastError; +} + +// Turns on and off the reading interface +DiagnosticResponse ArduinoInterface::enableReading(const bool enable, const bool reset, const bool dontWait) { + m_inWriteMode = false; + if (enable) { + // Enable the device + m_lastError = runCommand(dontWait ? COMMAND_ENABLE_NOWAIT : COMMAND_ENABLE); + if (m_lastError != DiagnosticResponse::drOK) { + m_lastCommand = LastCommand::lcEnableMotor; + return m_lastError; + } + + // Reset? + if (reset) { + m_lastError = findTrack0(); + if (m_lastError != DiagnosticResponse::drOK) return m_lastError; + + // Lets know where we are + return selectSurface(DiskSurface::dsUpper); + } + m_lastError = DiagnosticResponse::drOK; + m_inWriteMode = m_version.fullControlMod; + return m_lastError; + + } + else { + // Disable the device + m_lastError = runCommand(COMMAND_DISABLE); + if (m_lastError != DiagnosticResponse::drOK) { + m_lastCommand = LastCommand::lcDisableMotor; + return m_lastError; + } + + return m_lastError; + } +} + +// Check and switch to HD disk +DiagnosticResponse ArduinoInterface::setDiskCapacity(bool switchToHD_Disk) { + // Disable the device + m_lastError = runCommand(switchToHD_Disk ? COMMAND_SWITCHTO_HD : COMMAND_SWITCHTO_DD); + if (m_lastError != DiagnosticResponse::drOK) { + m_lastCommand = LastCommand::lcSwitchDiskMode; + return m_lastError; + } + + return m_lastError; +} + +// If the drive is on track 0, this does a test seek to -1 if supported +DiagnosticResponse ArduinoInterface::performNoClickSeek() { + // And send the command and track. This is sent as ASCII text as a result of terminal testing. Easier to see whats going on + bool isV18 = (m_version.major > 1) || ((m_version.major == 1) && (m_version.minor >= 8)); + if (!isV18) return DiagnosticResponse::drOldFirmware; + if (!m_version.fullControlMod) return DiagnosticResponse::drOldFirmware; + + m_lastError = runCommand(COMMAND_DO_NOCLICK_SEEK); + if (m_lastError == DiagnosticResponse::drOK) { + // Read extended data + char status; + if (!deviceRead(&status, 1, true)) { + m_lastError = DiagnosticResponse::drReadResponseFailed; + return m_lastError; + } + // 'x' means we didnt check it + if (status != 'x') m_diskInDrive = status == '1'; + + // Also read the write protect status + if (!deviceRead(&status, 1, true)) { + m_lastError = DiagnosticResponse::drReadResponseFailed; + return m_lastError; + } + m_isWriteProtected = status == '1'; + } + + return m_lastError; +} + + +// Select the track, this makes the motor seek to this position +DiagnosticResponse ArduinoInterface::selectTrack(const unsigned char trackIndex, const TrackSearchSpeed searchSpeed, bool ignoreDiskInsertCheck) { + if (trackIndex > 81) { + m_lastError = DiagnosticResponse::drTrackRangeError; + return m_lastError; // no chance, it can't be done. + } + + // And send the command and track. This is sent as ASCII text as a result of terminal testing. Easier to see whats going on + bool isV18 = (m_version.major > 1) || ((m_version.major == 1) && (m_version.minor >= 8)); + char buf[8]; + if (isV18) { + char flags = 0; + switch (searchSpeed) { + case TrackSearchSpeed::tssNormal: flags = 1; break; // Speed - 1 + case TrackSearchSpeed::tssFast: flags = 2; break; // Speed - 2 + case TrackSearchSpeed::tssVeryFast: flags = 3; break; // Speed - 3 + default: break; + } + if (!ignoreDiskInsertCheck) flags |= 4; +#ifdef _WIN32 + sprintf_s(buf, "%c%02i%c", COMMAND_GOTOTRACK_REPORT, trackIndex, flags); +#else + sprintf(buf, "%c%02i%c", COMMAND_GOTOTRACK_REPORT, trackIndex, flags); +#endif + } + else { +#ifdef _WIN32 + sprintf_s(buf, "%c%02i", COMMAND_GOTOTRACK, trackIndex); +#else + sprintf(buf, "%c%02i", COMMAND_GOTOTRACK, trackIndex); +#endif + } + + // Send track number. + if (!deviceWrite(buf, strlen(buf))) { + m_lastCommand = LastCommand::lcGotoTrack; + m_lastError = DiagnosticResponse::drSendFailed; + return m_lastError; + } + + // Get result + char result; + + if (!deviceRead(&result, 1, true)) { + m_lastCommand = LastCommand::lcGotoTrack; + m_lastError = DiagnosticResponse::drReadResponseFailed; + return m_lastError; + } + + switch (result) { + case '2': m_lastError = DiagnosticResponse::drOK; break; // already at track. No op needed. V1.8 only + case '1': m_lastError = DiagnosticResponse::drOK; + if (isV18) { + // Read extended data + char status; + if (!deviceRead(&status, 1, true)) { + m_lastError = DiagnosticResponse::drReadResponseFailed; + return m_lastError; + } + // 'x' means we didnt check it + if (status != 'x') m_diskInDrive = status == '1'; + + // Also read the write protect status + if (!deviceRead(&status, 1, true)) { + m_lastError = DiagnosticResponse::drReadResponseFailed; + return m_lastError; + } + m_isWriteProtected = status == '1'; + } + break; + case '0': m_lastCommand = LastCommand::lcGotoTrack; + m_lastError = DiagnosticResponse::drSelectTrackError; + break; + default: m_lastCommand = LastCommand::lcGotoTrack; + m_lastError = DiagnosticResponse::drStatusError; + break; + } + + return m_lastError; +} + +// Erases the current track by writing 0xAA to it +DiagnosticResponse ArduinoInterface::eraseCurrentTrack() { + m_lastError = runCommand(COMMAND_ERASETRACK); + if (m_lastError != DiagnosticResponse::drOK) { + m_lastCommand = LastCommand::lcEraseTrack; + return m_lastError; + } + + char result; + if (!deviceRead(&result, 1, true)) { + m_lastCommand = LastCommand::lcEraseTrack; + m_lastError = DiagnosticResponse::drReadResponseFailed; + return m_lastError; + } + + if (result == 'N') { + m_lastCommand = LastCommand::lcEraseTrack; + m_lastError = DiagnosticResponse::drWriteProtected; + return m_lastError; + } + + // Check result + if (!deviceRead(&result, 1, true)) { + m_lastCommand = LastCommand::lcEraseTrack; + m_lastError = DiagnosticResponse::drReadResponseFailed; + return m_lastError; + } + + if (result != '1') { + m_lastCommand = LastCommand::lcEraseTrack; + m_lastError = DiagnosticResponse::drError; + return m_lastError; + } + + return m_lastError; +} + +// Choose which surface of the disk to read from +DiagnosticResponse ArduinoInterface::selectSurface(const DiskSurface side) { + m_lastError = runCommand((side == DiskSurface::dsUpper) ? COMMAND_HEAD0 : COMMAND_HEAD1); + if (m_lastError != DiagnosticResponse::drOK) { + m_lastCommand = LastCommand::lcSelectSurface; + return m_lastError; + } + return m_lastError; +} + +void writeBit(RawTrackData& output, int& pos, int& bit, int value) { + if (pos >= RAW_TRACKDATA_LENGTH) return; + + output[pos] <<= 1; + output[pos] |= value; + bit++; + if (bit >= 8) { + pos++; + bit = 0; + } +} + +void unpack(const RawTrackData& data, RawTrackData& output) { + int pos = 0; + size_t index = 0; + int p2 = 0; + memset(output, 0, sizeof(output)); + while (pos < RAW_TRACKDATA_LENGTH) { + // Each byte contains four pairs of bits that identify an MFM sequence to be encoded + + for (int b = 6; b >= 0; b -= 2) { + unsigned char value = (data[index] >> b) & 3; + switch (value) { + case 0: + // This can't happen, its invalid data but we account for 4 '0' bits + writeBit(output, pos, p2, 0); + writeBit(output, pos, p2, 0); + writeBit(output, pos, p2, 0); + writeBit(output, pos, p2, 0); + break; + case 1: // This is an '01' + writeBit(output, pos, p2, 0); + writeBit(output, pos, p2, 1); + break; + case 2: // This is an '001' + writeBit(output, pos, p2, 0); + writeBit(output, pos, p2, 0); + writeBit(output, pos, p2, 1); + break; + case 3: // this is an '0001' + writeBit(output, pos, p2, 0); + writeBit(output, pos, p2, 0); + writeBit(output, pos, p2, 0); + writeBit(output, pos, p2, 1); + break; + } + } + index++; + if (index >= sizeof(data)) return; + } + // There will be left-over data +} + +// Read RAW data from the current track and surface +DiagnosticResponse ArduinoInterface::readCurrentTrack(RawTrackData& trackData, const bool readFromIndexPulse) { + m_lastError = runCommand(COMMAND_READTRACK); + + RawTrackData tmp; + + // Allow command retry + if (m_lastError != DiagnosticResponse::drOK) { + // Clear the buffer + deviceRead(&tmp, RAW_TRACKDATA_LENGTH); + m_lastError = runCommand(COMMAND_READTRACK); + if (m_lastError != DiagnosticResponse::drOK) { + m_lastCommand = LastCommand::lcReadTrack; + return m_lastError; + } + } + + unsigned char signalPulse = readFromIndexPulse ? 1 : 0; + if (!deviceWrite(&signalPulse, 1)) { + m_lastCommand = LastCommand::lcReadTrack; + m_lastError = DiagnosticResponse::drSendParameterFailed; + return m_lastError; + } + + // Keep reading until he hit RAW_TRACKDATA_LENGTH or a null byte is recieved + int bytePos = 0; + int readFail = 0; + for (;;) { + unsigned char value; + if (deviceRead(&value, 1, true)) { + if (value == 0) break; else + if (bytePos < RAW_TRACKDATA_LENGTH) tmp[bytePos++] = value; + } + else { + readFail++; + if (readFail > 4) { + m_lastCommand = LastCommand::lcReadTrack; + m_lastError = DiagnosticResponse::drReadResponseFailed; + return m_lastError; + } + } + } + unpack(tmp, trackData); + m_lastError = DiagnosticResponse::drOK; + return m_lastError; +} + +// Reads a complete rotation of the disk, and returns it using the callback function whcih can return FALSE to stop +// An instance of RotationExtractor is required. This is purely to save on re-allocations. It is internally reset each time +DiagnosticResponse ArduinoInterface::readRotation(RotationExtractor& extractor, const unsigned int maxOutputSize, RotationExtractor::MFMSample* firstOutputBuffer, RotationExtractor::IndexSequenceMarker& startBitPatterns, std::function onRotation) { + if ((m_version.major == 1) && (m_version.minor < 8)) { + m_lastCommand = LastCommand::lcReadTrackStream; + m_lastError = DiagnosticResponse::drOldFirmware; + return m_lastError; + } + + // Who would do this, right? + if ((maxOutputSize < 1) || (!firstOutputBuffer)) { + m_lastError = DiagnosticResponse::drError; + m_lastCommand = LastCommand::lcReadTrackStream; + return m_lastError; + } + + m_lastError = runCommand(COMMAND_READTRACKSTREAM); + + // Let the class know we're doing some streaming stuff + m_isStreaming = true; + m_abortStreaming = false; + m_abortSignalled = false; + + // Number of times we failed to read anything + int readFail = 0; + + // Buffer to read into + unsigned char tempReadBuffer[64] = { 0 }; + + // Reset ready for extraction + extractor.reset(); + + // Remind it if the 'index' data we want to sync to + extractor.setIndexSequence(startBitPatterns); + + // Sliding window for abort + char slidingWindow[5] = { 0,0,0,0,0 }; + int noDataCounter = 0; + bool timeout = false; + + for (;;) { + + // More efficient to read several bytes in one go + unsigned long bytesAvailable = m_comPort.getBytesWaiting(); + if (bytesAvailable < 1) bytesAvailable = 1; + if (bytesAvailable > sizeof(tempReadBuffer)) bytesAvailable = sizeof(tempReadBuffer); + unsigned long bytesRead = m_comPort.read(tempReadBuffer, m_abortSignalled ? 1 : bytesAvailable); + + + for (size_t a = 0; a < bytesRead; a++) { + if (m_abortSignalled) { + // Make space + for (int s = 0; s < 4; s++) slidingWindow[s] = slidingWindow[s + 1]; + // Append the new byte + slidingWindow[4] = tempReadBuffer[a]; + + // Watch the sliding window for the pattern we need + if ((slidingWindow[0] == 'X') && (slidingWindow[1] == 'Y') && (slidingWindow[2] == 'Z') && (slidingWindow[3] == SPECIAL_ABORT_CHAR) && (slidingWindow[4] == '1')) { + m_isStreaming = false; + m_comPort.purgeBuffers(); + m_lastCommand = LastCommand::lcReadTrackStream; + m_lastError = timeout ? DiagnosticResponse::drNoDiskInDrive : DiagnosticResponse::drOK; + applyCommTimeouts(false); + return m_lastError; + } + } + else { + unsigned char byteRead = tempReadBuffer[a]; + unsigned short readSpeed = (((unsigned long long)(64 + ((unsigned int)((byteRead & 0x07) * 16)) * 2000) / 128)); + + unsigned char tmp; + RotationExtractor::MFMSequenceInfo sequence; + + // Now packet up the data in the format the rotation extractor expects it to be in + tmp = (byteRead >> 5) & 0x03; + sequence.mfm = (tmp == 0) ? RotationExtractor::MFMSequence::mfm0000 : (RotationExtractor::MFMSequence)(tmp - 1); + sequence.timeNS = 3000 + ((unsigned int)sequence.mfm * 2000) + readSpeed; + if (sequence.mfm == RotationExtractor::MFMSequence::mfm0000) noDataCounter++; else noDataCounter = 0; + + extractor.submitSequence(sequence, (byteRead & 0x80) != 0); + + tmp = (byteRead >> 3) & 0x03; + sequence.mfm = (tmp == 0) ? RotationExtractor::MFMSequence::mfm0000 : (RotationExtractor::MFMSequence)(tmp - 1); + sequence.timeNS = 3000 + ((unsigned int)sequence.mfm * 2000) + readSpeed; + if (sequence.mfm == RotationExtractor::MFMSequence::mfm0000) noDataCounter++; else noDataCounter = 0; + + extractor.submitSequence(sequence, false); + + // Is it ready to extract? + if (extractor.canExtract()) { + unsigned int bits = 0; + // Go! + if (extractor.extractRotation(firstOutputBuffer, bits, maxOutputSize)) { + m_diskInDrive = true; + + if (!onRotation(&firstOutputBuffer, bits)) { + // And if the callback says so we stop. + abortReadStreaming(); + } + // Always save this back + extractor.getIndexSequence(startBitPatterns); + } + } else + if ((extractor.totalTimeReceived() > 300000000) && (noDataCounter > 100)) { + // No data, stop + abortReadStreaming(); + noDataCounter = 0; + timeout = true; + m_diskInDrive = false; // probably no disk + } + } + } + if (bytesRead < 1) { + readFail++; + if (readFail > 20) { + m_abortStreaming = false; // force the 'abort' command to be sent + abortReadStreaming(); + m_lastCommand = LastCommand::lcReadTrackStream; + m_lastError = DiagnosticResponse::drReadResponseFailed; + m_isStreaming = false; + applyCommTimeouts(false); + return m_lastError; + } + else std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } + } +} + +// Stops the read streamming immediately and any data in the buffer will be discarded. +bool ArduinoInterface::abortReadStreaming() { + if ((m_version.major == 1) && (m_version.minor < 8)) { + return false; + } + + if (!m_isStreaming) return true; + + if (!m_abortStreaming) { + // We know what this is, but the Arduino doesn't + unsigned char command = SPECIAL_ABORT_CHAR; + + m_abortSignalled = true; + + // Send a byte. This triggers the 'abort' on the Arduino + if (!deviceWrite(&command, 1)) { + return false; + } + + } + m_abortStreaming = true; + return true; +} + +// Read a bit from the data provided +inline int readBit(const unsigned char* buffer, const unsigned int maxLength, int& pos, int& bit) { + if (pos >= (int)maxLength) { + bit--; + if (bit < 0) { + bit = 7; + pos++; + } + return (bit & 1) ? 0 : 1; + } + + int ret = (buffer[pos] >> bit) & 1; + bit--; + if (bit < 0) { + bit = 7; + pos++; + } + + return ret; +} + +#define PRECOMP_NONE 0x00 +#define PRECOMP_ERLY 0x04 +#define PRECOMP_LATE 0x08 + +/* If we have a look at the previous and next three bits, assume the current is a '1', then these are the only valid combinations that coudl be allowed + I have chosen the PRECOMP rule based on trying to get the current '1' as far away as possible from the nearest '1' + + LAST CURRENT NEXT PRECOMP Hex Value + 0 0 0 1 0 0 0 Normal + 0 0 0 1 0 0 1 Early 0x09 + 0 0 0 1 0 1 0 Early 0x0A + 0 1 0 1 0 0 0 Late 0x28 + 0 1 0 1 0 0 1 Late 0x29 + 0 1 0 1 0 1 0 Normal + 1 0 0 1 0 0 0 Late 0x48 + 1 0 0 1 0 0 1 Normal + 1 0 0 1 0 1 0 Early 0x4A +*/ + +// The precomp version of the above. Dont use the above function directly to write precomp mode, it wont work. Data must be passed with an 0xAA each side at least +DiagnosticResponse ArduinoInterface::writeCurrentTrackPrecomp(const unsigned char* mfmData, const unsigned short numBytes, const bool writeFromIndexPulse, bool usePrecomp) { + m_lastCommand = LastCommand::lcWriteTrack; + if ((m_version.major == 1) && (m_version.minor < 8)) return DiagnosticResponse::drOldFirmware; + + // First step is we need to re-encode the supplied buffer into a packed format with precomp pre-calculated. + // Each nybble looks like: xxyy + // where xx is: 0=no precomp, 1=-ve, 2=+ve + // yy is: 0: 4us, 1: 6us, 2: 8us, 3: 10us + + // *4 is a worse case situation, ie: if everything was a 01. The +128 is for any extra padding + const unsigned int maxOutSize = (numBytes * 4) + 16; + unsigned char* outputBuffer = (unsigned char*)malloc(maxOutSize); + + if (!outputBuffer) { + m_lastError = DiagnosticResponse::drSendParameterFailed; + return m_lastError; + } + + // Original data was written from MSB downto LSB + int pos = 0; + int bit = 7; + unsigned int outputPos = 0; + unsigned char sequence = 0xAA; // start at 10101010 + unsigned char* output = outputBuffer; + int lastCount = 2; + + // Re-encode the data into our format and apply precomp. The +8 is to ensure theres some padding around the edge which will come out as 010101 etc + while (pos < numBytes + 8) { + *output = 0; + + for (int i = 0; i < 2; i++) { + int b, count = 0; + + // See how many zero bits there are before we hit a 1 + do { + b = readBit(mfmData, numBytes, pos, bit); + sequence = ((sequence << 1) & 0x7F) | b; + count++; + } while (((sequence & 0x08) == 0) && (pos < numBytes + 8)); + + // Validate range + if (count < 2) count = 2; // <2 would be a 11 sequence, not allowed + if (count > 5) count = 5; // max we support 01, 001, 0001, 00001 + + // Write to stream. Based on the rules above we apply some precomp + int precomp = 0; + if (usePrecomp) { + switch (sequence) { + case 0x09: + case 0x0A: + case 0x4A: // early; + precomp = PRECOMP_ERLY; + break; + + case 0x28: + case 0x29: + case 0x48: // late + precomp = PRECOMP_LATE; + break; + + default: + precomp = PRECOMP_NONE; + break; + } + } + else precomp = PRECOMP_NONE; + + *output |= ((lastCount - 2) | precomp) << (i * 4); + lastCount = count; + } + + output++; + outputPos++; + if (outputPos >= maxOutSize) { + // should never happen + free(outputBuffer); + m_lastError = DiagnosticResponse::drSendParameterFailed; + return m_lastError; + } + } + + m_lastError = internalWriteTrack(outputBuffer, outputPos, writeFromIndexPulse, true); + + free(outputBuffer); + + return m_lastError; +} + +// Writes RAW data onto the current track +DiagnosticResponse ArduinoInterface::writeCurrentTrack(const unsigned char* data, const unsigned short numBytes, const bool writeFromIndexPulse) { + return internalWriteTrack(data, numBytes, writeFromIndexPulse, false); +} + +// Writes RAW data onto the current track +DiagnosticResponse ArduinoInterface::internalWriteTrack(const unsigned char* data, const unsigned short numBytes, const bool writeFromIndexPulse, bool usePrecomp) { + // Fall back if older firmware + if ((m_version.major == 1) && (m_version.minor < 8) && usePrecomp) { + return DiagnosticResponse::drOldFirmware; + } + m_lastError = runCommand(usePrecomp ? COMMAND_WRITETRACKPRECOMP : COMMAND_WRITETRACK); + if (m_lastError != DiagnosticResponse::drOK) { + m_lastCommand = LastCommand::lcWriteTrack; + return m_lastError; + } + unsigned char chr; + if (!deviceRead(&chr, 1, true)) { + m_lastCommand = LastCommand::lcWriteTrack; + m_lastError = DiagnosticResponse::drReadResponseFailed; + return m_lastError; + } + + // 'N' means NO Writing, aka write protected + if (chr == 'N') { + m_lastCommand = LastCommand::lcWriteTrack; + m_lastError = DiagnosticResponse::drWriteProtected; + return m_lastError; + } + if (chr != 'Y') { + m_lastCommand = LastCommand::lcWriteTrack; + m_lastError = DiagnosticResponse::drStatusError; + return m_lastError; + } + + // Now we send the number of bytes we're planning on transmitting + unsigned char b = (numBytes >> 8); + if (!deviceWrite(&b, 1)) { + m_lastCommand = LastCommand::lcWriteTrack; + m_lastError = DiagnosticResponse::drSendParameterFailed; + return m_lastError; + } + b = numBytes & 0xFF; + if (!deviceWrite(&b, 1)) { + m_lastCommand = LastCommand::lcWriteTrack; + m_lastError = DiagnosticResponse::drSendParameterFailed; + return m_lastError; + } + + // Explain if we want index pulse sync writing (slower and not required by normal AmigaDOS disks) + b = writeFromIndexPulse ? 1 : 0; + if (!deviceWrite(&b, 1)) { + m_lastCommand = LastCommand::lcWriteTrack; + m_lastError = DiagnosticResponse::drSendParameterFailed; + return m_lastError; + } + + unsigned char response; + if (!deviceRead(&response, 1, true)) { + m_lastCommand = LastCommand::lcWriteTrack; + m_lastError = DiagnosticResponse::drReadResponseFailed; + return m_lastError; + } + + if (response != '!') { + m_lastCommand = LastCommand::lcWriteTrack; + m_lastError = DiagnosticResponse::drStatusError; + + return m_lastError; + } + + if (!deviceWrite((const void*)data, numBytes)) { + m_lastCommand = LastCommand::lcWriteTrack; + m_lastError = DiagnosticResponse::drSendDataFailed; + return m_lastError; + } + + if (!deviceRead(&response, 1, true)) { + m_lastCommand = LastCommand::lcWriteTrack; + m_lastError = DiagnosticResponse::drTrackWriteResponseError; + return m_lastError; + } + + // If this is a '1' then the Arduino didn't miss a single bit! + if (response != '1') { + m_lastCommand = LastCommand::lcWriteTrack; + switch (response) { + case 'X': m_lastError = DiagnosticResponse::drWriteTimeout; break; + case 'Y': m_lastError = DiagnosticResponse::drFramingError; break; + case 'Z': m_lastError = DiagnosticResponse::drSerialOverrun; break; + default: + m_lastError = DiagnosticResponse::drStatusError; + break; + } + return m_lastError; + } + + m_lastError = DiagnosticResponse::drOK; + return m_lastError; +} + +// Returns a list of ports this coudl be available on +void ArduinoInterface::enumeratePorts(std::vector& portList) { + portList.clear(); + std::vector prts; + + SerialIO prt; + prt.enumSerialPorts(prts); + + for (const SerialIO::SerialPortInformation& port : prts) + portList.push_back(port.portName); +} + + +// Run a command that returns 1 or 0 for its response +DiagnosticResponse ArduinoInterface::runCommand(const char command, const char parameter, char* actualResponse) { + unsigned char response; + + // Pause for I/O + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + + // Send the command + if (!deviceWrite(&command, 1)) { + m_lastError = DiagnosticResponse::drSendFailed; + return m_lastError; + } + + // Only send the parameter if its not NULL + if (parameter != '\0') + if (!deviceWrite(¶meter, 1)) { + m_lastError = DiagnosticResponse::drSendParameterFailed; + return m_lastError; + } + + // And read the response + if (!deviceRead(&response, 1, true)) { + m_lastError = DiagnosticResponse::drReadResponseFailed; + return m_lastError; + } + + if (actualResponse) *actualResponse = response; + + // Evaluate the response + switch (response) { + case '1': m_lastError = DiagnosticResponse::drOK; + break; + case '0': m_lastError = DiagnosticResponse::drError; + break; + default: m_lastError = DiagnosticResponse::drStatusError; + break; + } + return m_lastError; +} + +// Read a desired number of bytes into the target pointer +bool ArduinoInterface::deviceRead(void* target, const unsigned int numBytes, const bool failIfNotAllRead) { + if (!m_comPort.isPortOpen()) return false; + + unsigned long read = m_comPort.read(target, numBytes); + + if (read < numBytes) { + if (failIfNotAllRead) return false; + + // Clear the unread bytes + char* target2 = ((char*)target) + read; + memset(target2, 0, numBytes - read); + } + + return true; +} + +// Writes a desired number of bytes from the the pointer +bool ArduinoInterface::deviceWrite(const void* source, const unsigned int numBytes) { + return m_comPort.write(source, numBytes) == numBytes; +} diff --git a/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/lib/ArduinoInterface.h b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/lib/ArduinoInterface.h new file mode 100644 index 00000000..b21a3ea1 --- /dev/null +++ b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/lib/ArduinoInterface.h @@ -0,0 +1,269 @@ +#ifndef ARDUINO_FLOPPY_READER_WRITER_INTERFACE +#define ARDUINO_FLOPPY_READER_WRITER_INTERFACE +/* ArduinoFloppyReader (and writer) +* +* Copyright (C) 2017-2021 Robert Smith (@RobSmithDev) +* https://amiga.robsmithdev.co.uk +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Library General Public +* License as published by the Free Software Foundation; either +* version 3 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 +* Library General Public License for more details. +* +* You should have received a copy of the GNU Library General Public +* License along with this library; if not, see http://www.gnu.org/licenses/ +*/ + +//////////////////////////////////////////////////////////////////////////////////////// +// Class to manage the communication between the computer and the Arduino V2.5 // +//////////////////////////////////////////////////////////////////////////////////////// +// +// Purpose: +// The class handles the command interface to the arduino. It doesn't do any decoding +// Just open ports, switch motors on and off, seek to tracks etc. +// +// +// + +#include +#include +#include + +#include "RotationExtractor.h" +#include "SerialIO.h" + +// Paula on the Amiga used to find the SYNC then read 1900 WORDS. (12868 bytes) +// As the PC is doing the SYNC we need to read more than this to allow a further overlap +// This number must match what the sketch in the Arduino is set to. +#define RAW_TRACKDATA_LENGTH (0x1900*2+0x440) +// With the disk spinning at 300rpm, and data rate of 500kbps, for a full revolution we should receive 12500 bytes of data (12.5k) +// The above buffer assumes a full Paula data capture plsu the size of a sector. + + +namespace ArduinoFloppyReader { + + // Array to hold data from a floppy disk read + typedef unsigned char RawTrackData[RAW_TRACKDATA_LENGTH]; + + // Sketch firmware version + struct FirmwareVersion { + unsigned char major, minor; + bool fullControlMod; + }; + + + // Represent which side of the disk we're looking at + enum class DiskSurface { + dsUpper, // The upper side of the disk + dsLower // The lower side of the disk + }; + + // Speed at which the head will seek to a track + enum class TrackSearchSpeed { + tssSlow, + tssNormal, + tssFast, + tssVeryFast + }; + + // Diagnostic responses from the interface + enum class DiagnosticResponse { + drOK, + + // Responses from openPort + drPortInUse, + drPortNotFound, + drPortError, + drAccessDenied, + drComportConfigError, + drBaudRateNotSupported, + drErrorReadingVersion, + drErrorMalformedVersion, + drOldFirmware, + + // Responses from commands + drSendFailed, + drSendParameterFailed, + drReadResponseFailed, + drWriteTimeout, + drSerialOverrun, + drFramingError, + drError, + + // Response from selectTrack + drTrackRangeError, + drSelectTrackError, + drWriteProtected, + drStatusError, + drSendDataFailed, + drTrackWriteResponseError, + + // Returned if there is no disk in the drive + drNoDiskInDrive, + + drDiagnosticNotAvailable, + drUSBSerialBad, + drCTSFailure, + drRewindFailure + }; + + enum class LastCommand { + lcOpenPort, + lcGetVersion, + lcEnableWrite, + lcRewind, + lcDisableMotor, + lcEnableMotor, + lcGotoTrack, + lcSelectSurface, + lcReadTrack, + lcWriteTrack, + lcRunDiagnostics, + lcSwitchDiskMode, + lcReadTrackStream, + lcCheckDiskInDrive, + lcCheckDiskWriteProtected, + lcEraseTrack + }; + + class ArduinoInterface { + private: + // Windows handle to the serial port device + SerialIO m_comPort; + FirmwareVersion m_version; + bool m_inWriteMode; + LastCommand m_lastCommand; + DiagnosticResponse m_lastError; + bool m_abortStreaming; + bool m_isWriteProtected; + bool m_diskInDrive; + bool m_abortSignalled; + bool m_isStreaming; + + // Read a desired number of bytes into the target pointer + bool deviceRead(void* target, const unsigned int numBytes, const bool failIfNotAllRead = false); + // Writes a desired number of bytes from the the pointer + bool deviceWrite(const void* source, const unsigned int numBytes); + + // Version of the above where the command has a parameter on the end (as long as its not char 0) + DiagnosticResponse runCommand(const char command, const char parameter = '\0', char* actualResponse = nullptr); + + // Apply and change the timeouts on the com port + void applyCommTimeouts(bool shortTimeouts); + + // Attempts to write a sector back to the disk. This must be pre-formatted and MFM encoded correctly depending on usePrecomp + DiagnosticResponse internalWriteTrack(const unsigned char* data, const unsigned short numBytes, const bool writeFromIndexPulse, bool usePrecomp); + + // Attempts to verify if the reader/writer is running on this port + static DiagnosticResponse internalOpenPort(const std::wstring& portName, bool enableCTSflowcontrol, bool triggerReset, std::string& versionString, SerialIO& port); + + // Attempt to sync and get version + static DiagnosticResponse attemptToSync(std::string& versionString, SerialIO& port); + + public: + // Constructor for this class + ArduinoInterface(); + + // Free me + ~ArduinoInterface(); + + const LastCommand getLastFailedCommand() const { return m_lastCommand; }; + const DiagnosticResponse getLastError() const { return m_lastError; }; + + // Uses the above fields to constructr a suitable error message, hopefully useful in diagnosing the issue + const std::string getLastErrorStr() const; + + const bool isOpen() const { return m_comPort.isPortOpen(); }; + const bool isInWriteMode() const { return m_inWriteMode; }; + + // Returns a list of ports this coudl be available on + static void enumeratePorts(std::vector& portList); + + // Returns TRUE if there is a disk in the drive. This is ONLY updated by checkForDisk or checkIfDiskIsWriteProtected + inline bool isDiskInDrive() const { return m_diskInDrive; }; + + // Get the current firmware version. Only valid if openPort is successful + const FirmwareVersion getFirwareVersion() const { return m_version; }; + + // Turns on and off the reading interface. For the new modded firmware this also allows writing as such the function below is no longer needed + DiagnosticResponse enableReading(const bool enable, const bool reset = true, const bool dontWait = false); + + // Turns on and off the reading interface. If irError is returned the disk is write protected. This is no longer needed if you are using the new modded firmware + DiagnosticResponse enableWriting(const bool enable, const bool reset = true); + + // Attempts to open the reader running on the COM port number provided. Port MUST support 2M baud + DiagnosticResponse openPort(const std::wstring& portName, bool enableCTSflowcontrol = true); + + // Attempts to verify if the reader/writer is running on this port + static bool isPortCorrect(const std::wstring& portName); + + // Checks if the disk is write protected. If forceCheck=false then the last cached version is returned. This is also updated by checkForDisk() as well as this function + DiagnosticResponse checkIfDiskIsWriteProtected(bool forceCheck); + + // Seek to track 0 + DiagnosticResponse findTrack0(); + + // Check to see if a disk is inserted in the drive. If forceCheck then the last cached verson is returned, which is also updated by diskStepOnce. + DiagnosticResponse checkForDisk(bool forceCheck); + + // Reads a complete rotation of the disk, and returns it using the callback function whcih can return FALSE to stop + // An instance of RotationExtractor is required. This is purely to save on re-allocations. It is internally reset each time + DiagnosticResponse readRotation(RotationExtractor& extractor, const unsigned int maxOutputSize, RotationExtractor::MFMSample* firstOutputBuffer, RotationExtractor::IndexSequenceMarker& startBitPatterns, std::function onRotation); + + // Stops the read streamming immediately and any data in the buffer will be discarded. The above function will exit when the Arduino has also stopped streaming data + bool abortReadStreaming(); + + // Returns TURE if the disk si currently streaming data + inline bool isStreaming() { return m_isStreaming; }; + + // Check if an index pulse can be detected from the drive + DiagnosticResponse testIndexPulse(); + + // Check if data can be detected from the drive + DiagnosticResponse testDataPulse(); + + // Check and switch to HD disk + DiagnosticResponse setDiskCapacity(bool switchToHD_Disk); + + // Select the track, this makes the motor seek to this position + DiagnosticResponse selectTrack(const unsigned char trackIndex, const TrackSearchSpeed searchSpeed = TrackSearchSpeed::tssNormal, bool ignoreDiskInsertCheck = false); + + // If the drive is on track 0, this does a test seek to -1 if supported + DiagnosticResponse performNoClickSeek(); + + // Choose which surface of the disk to read from + DiagnosticResponse selectSurface(const DiskSurface side); + + // Read RAW data from the current track and surface selected + DiagnosticResponse readCurrentTrack(RawTrackData& trackData, const bool readFromIndexPulse); + + // Attempts to write a sector back to the disk. This must be pre-formatted and MFM encoded correctly + DiagnosticResponse writeCurrentTrack(const unsigned char* data, const unsigned short numBytes, const bool writeFromIndexPulse); + // The precomp version of the above. + DiagnosticResponse writeCurrentTrackPrecomp(const unsigned char* mfmData, const unsigned short numBytes, const bool writeFromIndexPulse, bool usePrecomp); + + // Erases the current track by writing 0xAA to it + DiagnosticResponse eraseCurrentTrack(); + + // Check CTS status - you must open with CTS disabled for this to work + DiagnosticResponse testCTS(); + + // Check if the USB to Serial device can keep up properly + DiagnosticResponse testTransferSpeed(); + + // Returns true if the track actually contains some data, else its considered blank or unformatted + bool trackContainsData(const RawTrackData& trackData) const; + + // Closes the port down + void closePort(); + }; + +}; + + +#endif \ No newline at end of file diff --git a/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/lib/RotationExtractor.cpp b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/lib/RotationExtractor.cpp new file mode 100644 index 00000000..7400baaa --- /dev/null +++ b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/lib/RotationExtractor.cpp @@ -0,0 +1,401 @@ +/* ArduinoFloppyReader (and writer) - Rotation Extractor +* +* Copyright (C) 2017-2021 Robert Smith (@RobSmithDev) +* https://amiga.robsmithdev.co.uk +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Library General Public +* License as published by the Free Software Foundation; either +* version 3 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 +* Library General Public License for more details. +* +* You should have received a copy of the GNU Library General Public +* License along with this library; if not, see http://www.gnu.org/licenses/ +*/ + +//////////////////////////////////////////////////////////////////////////////////////// +// Class to manage finding *exact* disk revolutions // +//////////////////////////////////////////////////////////////////////////////////////// +// +// Purpose: +// The class attempts to guess where an exact disk revolution occurs, and then re-aligns +// it such that it starts at the index pulse. This means we dont need to wait for an index +// pulse to work out a revolution of the disk. The first time a disk is used we calculate +// the time of a single revolution and then use that as a guide to how long a revolution will +// take in the future. +// +// This isn't 100% perfect but does seem to work. + +#include "RotationExtractor.h" + +// Finds the overlap between the start of the data and where we currently are. The returned position is where the NEXT revolution starts +unsigned int RotationExtractor::getOverlapPosition() const { + int bestScore = OVERLAP_SEQUENCE_MATCHES / 4; // must have *some* kind of match to be worthy + unsigned int bestScoreIndex = m_revolutionReadyAt; + + // Working back from the mid-point + for (unsigned int midPoint = 0; midPoint < OVERLAP_SEQUENCE_MATCHES * (OVERLAP_EXTRA_BUFFER - 1); midPoint++) { + + // Count the number of matching sequences + int scoreL = 0; + int scoreR = 0; + const int startPositionR = m_revolutionReadyAt + midPoint; + const int startPositionL = m_revolutionReadyAt - midPoint; + + if (startPositionL >= 0) { + for (unsigned int pos = 0; pos < OVERLAP_SEQUENCE_MATCHES; pos++) { + if (m_sequences[pos].mfm == m_sequences[startPositionR + pos].mfm) scoreR++; + if (m_sequences[pos].mfm == m_sequences[startPositionL + pos].mfm) scoreL++; + } + } + else { + for (unsigned int pos = 0; pos < OVERLAP_SEQUENCE_MATCHES; pos++) { + if (m_sequences[pos].mfm == m_sequences[startPositionR + pos].mfm) scoreR++; + } + } + + // A perfect score short-circuits the rest of the loop + if (scoreL > bestScore) { + bestScore = scoreL; + bestScoreIndex = startPositionL; + } + if (scoreR > bestScore) { + bestScore = scoreR; + bestScoreIndex = startPositionR; + } + + if (bestScore == OVERLAP_SEQUENCE_MATCHES) return bestScoreIndex; + } + + // If we got here then there wasnt a perfect match. This would only happen if: + // 1. The drive speed is broken! + // 2. The overlap is unformatted, in which case it doesn't really matter anyway + // 3. The disk/head is damaged or dirty, so then there's no hope anyway + return bestScoreIndex; +} + +// Finds the true start position of the INDEX pulse based on previous revolutions. This is a lot like the above function +const unsigned int RotationExtractor::getTrueIndexPosition(const unsigned int nextRevolutionStart, const unsigned int startingPoint) { + // Where to start from + const int firstPoint = (startingPoint == INDEX_NOT_FOUND) ? m_sequenceIndex : startingPoint; + + // First. Do we actually have a 'index marker' buffer? + if (!m_indexSequence.valid) { + // Not valid means we make it, and take our index as "true" + m_indexSequence.valid = true; + for (unsigned int pos = 0; pos < OVERLAP_SEQUENCE_MATCHES; pos++) + m_indexSequence.sequences[pos] = m_sequences[(firstPoint + pos) % nextRevolutionStart].mfm; + + return firstPoint; + } + + int bestScore = OVERLAP_SEQUENCE_MATCHES / 4; // must have *some* kind of match to be worthy + unsigned int bestScoreIndex = firstPoint; + + // Working back from the mid-point + for (unsigned int midPoint = 0; midPoint < OVERLAP_SEQUENCE_MATCHES * (OVERLAP_EXTRA_BUFFER - 1); midPoint++) { + + // Count the number of matching sequences + int scoreL = 0; + int scoreR = 0; + const int startPositionR = firstPoint + midPoint; + const int startPositionL = firstPoint - midPoint; + + if (startPositionL >= 0) { + for (unsigned int pos = 0; pos < OVERLAP_SEQUENCE_MATCHES; pos++) { + if (m_indexSequence.sequences[pos] == m_sequences[(startPositionR + pos) % nextRevolutionStart].mfm) scoreR++; + if (m_indexSequence.sequences[pos] == m_sequences[(startPositionL + pos) % nextRevolutionStart].mfm) scoreL++; + } + } + else { + for (unsigned int pos = 0; pos < OVERLAP_SEQUENCE_MATCHES; pos++) { + if (m_indexSequence.sequences[pos] == m_sequences[(startPositionR + pos) % nextRevolutionStart].mfm) scoreR++; + } + } + + // A perfect score short-circuits the rest of the loop + if (scoreL > bestScore) { + bestScore = scoreL; + bestScoreIndex = startPositionL; + } + if (scoreR > bestScore) { + bestScore = scoreR; + bestScoreIndex = startPositionR; + } + + if (bestScore == OVERLAP_SEQUENCE_MATCHES) return bestScoreIndex; + } + + // If we got here then there wasnt a perfect match. This would only happen if: + // 1. The drive speed is broken! + // 2. The overlap is unformatted, in which case it doesn't really matter anyway + // 3. The disk/head is damaged or dirty, so then there's no hope anyway + return bestScoreIndex; +} + +// Write a bit into the stream +inline void writeStreamBit(RotationExtractor::MFMSample* output, unsigned int& pos, unsigned int& bit, bool value, const unsigned short valuespeed, const unsigned int maxLength) { + if (pos >= maxLength) return; + + output[pos].mfmData <<= 1; + if (value) output[pos].mfmData |= 1; + +#ifdef OUTPUT_TIME_IN_NS + output[pos].bittime[7 - bit] = valuespeed; +#else +#ifdef HIGH_RESOLUTION_MODE + output[pos].speed[7 - bit] = valuespeed; +#else + if (bit == 0) output[pos].speed = valuespeed; else output[pos].speed += valuespeed; +#endif +#endif + + bit++; + if (bit >= 8) { +#ifndef OUTPUT_TIME_IN_NS +#ifndef HIGH_RESOLUTION_MODE + output[pos].speed /= 8; +#endif +#endif + pos++; + bit = 0; + } +} + +// Submit a single sequence to the list +void RotationExtractor::submitSequence(const MFMSequenceInfo& sequence, const bool isIndex) { + // we reject the first 20uSec of data. Makes things so much more stable + m_timeReceived += sequence.timeNS; + if (m_timeReceived < 20000) return; + + // And stop if we have too much. Shouldn't happen + if (m_sequencePos >= MAX_REVOLUTION_SEQUENCES) return; + + // See if we can calculate the time it takes to get a single revolution from the disk + if ((m_revolutionTime == 0) && (!m_useIndex)) { + if (isIndex) { + if (m_sequenceIndex == INDEX_NOT_FOUND) m_sequenceIndex = 0; else m_nextSequenceIndex = m_sequencePos; + } + + if (m_sequenceIndex != INDEX_NOT_FOUND) { + // Store the sequence only if we found the first index + m_sequences[m_sequencePos++] = sequence; + m_currentTime += sequence.timeNS; + + if (m_nextSequenceIndex == INDEX_NOT_FOUND) + m_revolutionTimeCounting += sequence.timeNS; + else { + m_revolutionTime = m_revolutionTimeCounting; + + // Set the nearly complete marker to be at 90%. That would only need approx another 20ms to complete + m_revolutionTimeNearlyComplete = (unsigned int)(m_revolutionTime * 0.9f); + } + } + return; + } + + // Handle index search + if (isIndex) { + if (m_sequenceIndex == INDEX_NOT_FOUND) m_sequenceIndex = m_sequencePos; else m_nextSequenceIndex = m_sequencePos; + } + + // Do different things depending on the mode in use + if (m_useIndex) { + if (m_sequenceIndex == INDEX_NOT_FOUND) { + // Store the data in the circular buffer + m_initialSequences[m_initialSequencesWritePos] = sequence; + m_initialSequencesWritePos = (m_initialSequencesWritePos + 1) % (OVERLAP_SEQUENCE_MATCHES * OVERLAP_EXTRA_BUFFER); + if (m_initialSequencesLength < OVERLAP_SEQUENCE_MATCHES * OVERLAP_EXTRA_BUFFER) m_initialSequencesLength++; + m_revolutionReady = false; + } + else { + // Was the FIRST index detected? + if ((isIndex) && (m_nextSequenceIndex == INDEX_NOT_FOUND) && (m_initialSequencesLength)) { + // Ok, shunt the buffer we have onto the output + m_sequencePos = m_initialSequencesLength; + m_sequenceIndex = m_initialSequencesLength; + + // Go through all of them + while (m_initialSequencesLength) { + // Wind back one + m_initialSequencesLength--; + // Handle wrap-around buffer + if (m_initialSequencesWritePos == 0) m_initialSequencesWritePos = (OVERLAP_SEQUENCE_MATCHES * OVERLAP_EXTRA_BUFFER) - 1; else m_initialSequencesWritePos--; + // Save it + m_sequences[m_initialSequencesLength] = m_initialSequences[m_initialSequencesWritePos]; + } + m_initialSequencesLength = 0; + } + + // Store as normal + m_sequences[m_sequencePos++] = sequence; + + // Check if ready + if (m_nextSequenceIndex != INDEX_NOT_FOUND) { + if (m_sequencePos > m_nextSequenceIndex + (OVERLAP_SEQUENCE_MATCHES * OVERLAP_EXTRA_BUFFER)) { + m_revolutionReadyAt = m_nextSequenceIndex; + m_revolutionReady = true; + } + } + } + } + else { + m_sequences[m_sequencePos++] = sequence; + m_currentTime += (unsigned int)sequence.timeNS; + + // This is a sneaky check-ahead for a full rotation, like a virtual index marker + if (m_currentTime >= m_revolutionTime) { + if (m_revolutionReadyAt == INDEX_NOT_FOUND) m_revolutionReadyAt = m_sequencePos; else + if (m_sequencePos > m_revolutionReadyAt + (OVERLAP_SEQUENCE_MATCHES * OVERLAP_EXTRA_BUFFER)) + m_revolutionReady = true; + } + } +} + +// Extracts a single rotation and updates the buffer to remove it. Returns FALSE if no rotation is available +bool RotationExtractor::extractRotation(MFMSample* output, unsigned int& outputBits, const unsigned int maxBufferSizeBytes) { + // Step 0: check if we're possibly ready + if (!canExtract()) return false; + + if (m_useIndex) { + if (m_sequenceIndex == INDEX_NOT_FOUND) return false; + if (m_nextSequenceIndex == INDEX_NOT_FOUND) return false; + if (m_sequenceIndex > m_nextSequenceIndex) { + unsigned int s = m_sequenceIndex; + m_sequenceIndex = m_nextSequenceIndex; + m_nextSequenceIndex = s; + } + + // Step 1: Find where the first index position is + const unsigned int revolutionStart = getTrueIndexPosition(INDEX_NOT_FOUND, m_sequenceIndex); + + // Step 2: find out where the next one is + const unsigned int nextRevolutionStart = getTrueIndexPosition(INDEX_NOT_FOUND, m_nextSequenceIndex); + + // Markers + unsigned int outputStreamPos = 0; + unsigned int outputStreamBit = 0; + unsigned int totalSamples = nextRevolutionStart - revolutionStart; + // Work out revolution time anyway + unsigned int rTime = 0; + + // Step 3: output. Data goes from 0 to nextRevolutionStart-1, but we need to output from indexPosition + for (unsigned int pos = 0; pos < totalSamples; pos++) { + const MFMSequenceInfo& sequence = m_sequences[pos + revolutionStart]; + rTime += sequence.timeNS; + +#ifdef OUTPUT_TIME_IN_NS + const unsigned int bitTime = sequence.timeNS / ((unsigned int)sequence.mfm + 2); + + // And write the output stream + for (unsigned int s = 0; s <= (unsigned int)sequence.mfm; s++) + writeStreamBit(output, outputStreamPos, outputStreamBit, false, bitTime, maxBufferSizeBytes); + writeStreamBit(output, outputStreamPos, outputStreamBit, (sequence.mfm != MFMSequence::mfm0000), bitTime, maxBufferSizeBytes); +#else + const unsigned int speed = ((unsigned int)sequence.timeNS * 100) / (((unsigned int)sequence.mfm + 2) * 2000); + + // And write the output stream + for (unsigned int s = 0; s <= (unsigned int)sequence.mfm; s++) + writeStreamBit(output, outputStreamPos, outputStreamBit, false, speed, maxBufferSizeBytes); + writeStreamBit(output, outputStreamPos, outputStreamBit, (sequence.mfm != MFMSequence::mfm0000), speed, maxBufferSizeBytes); +#endif + } + // Need to shift the last ones onto place + if (outputStreamBit) { + output[outputStreamPos].mfmData <<= (8 - outputStreamBit); +#ifndef OUTPUT_TIME_IN_NS +#ifndef HIGH_RESOLUTION_MODE + output[outputStreamPos].speed /= outputStreamBit; +#endif +#endif + } + if (m_revolutionTime == 0) { + m_revolutionTime = rTime; + m_revolutionTimeNearlyComplete = (unsigned int)(m_revolutionTime * 0.9f); + } + + // Calculate how much we wrote + outputBits = (outputStreamPos * 8) + outputStreamBit; + + // Now shift the remaining data so that the next revolution starts at 0 + for (unsigned int pos = 0; pos < m_sequencePos - nextRevolutionStart; pos++) + m_sequences[pos] = m_sequences[pos + nextRevolutionStart]; + + // And mark it + if (m_nextSequenceIndex > nextRevolutionStart) m_sequenceIndex = m_nextSequenceIndex - nextRevolutionStart; else m_sequenceIndex = 0; + m_nextSequenceIndex = INDEX_NOT_FOUND; + + // And account for the shift + m_sequencePos -= nextRevolutionStart; + } + else { + + // Step 1: Find the overlap between the start of the data and the end of the data + const unsigned int nextRevolutionStart = getOverlapPosition(); + if (nextRevolutionStart < 1) return false; + + // Step 2: wind it back to the INDEX position + const unsigned int indexPosition = getTrueIndexPosition(nextRevolutionStart); + + // Markers + unsigned int outputStreamPos = 0; + unsigned int outputStreamBit = 0; + + // Step 3: output. Data goes from 0 to nextRevolutionStart-1, but we need to output from indexPosition + for (unsigned int pos = 0; pos < nextRevolutionStart; pos++) { + const MFMSequenceInfo& sequence = m_sequences[(pos + indexPosition) % nextRevolutionStart]; + m_currentTime -= (unsigned int)sequence.timeNS; + +#ifdef OUTPUT_TIME_IN_NS + const unsigned int bitTime = sequence.timeNS / ((unsigned int)sequence.mfm + 2); + + // And write the output stream + for (unsigned int s = 0; s <= (unsigned int)sequence.mfm; s++) + writeStreamBit(output, outputStreamPos, outputStreamBit, false, bitTime, maxBufferSizeBytes); + writeStreamBit(output, outputStreamPos, outputStreamBit, (sequence.mfm != MFMSequence::mfm0000), bitTime, maxBufferSizeBytes); +#else + const unsigned int speed = ((unsigned int)sequence.timeNS * 100) / (((unsigned int)sequence.mfm + 2) * 2000); + + // And write the output stream + for (unsigned int s = 0; s <= (unsigned int)sequence.mfm; s++) + writeStreamBit(output, outputStreamPos, outputStreamBit, false, speed, maxBufferSizeBytes); + writeStreamBit(output, outputStreamPos, outputStreamBit, (sequence.mfm != MFMSequence::mfm0000), speed, maxBufferSizeBytes); +#endif + } + // Need to shift the last ones onto place + if (outputStreamBit) { + output[outputStreamPos].mfmData <<= (8 - outputStreamBit); +#ifndef OUTPUT_TIME_IN_NS +#ifndef HIGH_RESOLUTION_MODE + output[outputStreamPos].speed /= outputStreamBit; +#endif +#endif + } + + // Calculate how much we wrote + outputBits = (outputStreamPos * 8) + outputStreamBit; + + // Now it's extracted we need to remove it. First. Shift or reset the index marker + if ((m_nextSequenceIndex != INDEX_NOT_FOUND) && (m_nextSequenceIndex >= nextRevolutionStart)) m_sequenceIndex = m_nextSequenceIndex - nextRevolutionStart; else m_sequenceIndex = INDEX_NOT_FOUND; + m_nextSequenceIndex = INDEX_NOT_FOUND; + + // Now shift the remaining data + for (unsigned int pos = 0; pos < m_sequencePos - nextRevolutionStart; pos++) + m_sequences[pos] = m_sequences[pos + nextRevolutionStart]; + + // And account for the shift + m_sequencePos -= nextRevolutionStart; + } + + m_revolutionReadyAt = INDEX_NOT_FOUND; + m_revolutionReady = false; + m_initialSequencesLength = 0; + m_initialSequencesWritePos = 0; + + // and success! + return true; +} \ No newline at end of file diff --git a/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/lib/RotationExtractor.h b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/lib/RotationExtractor.h new file mode 100644 index 00000000..0ac36c05 --- /dev/null +++ b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/lib/RotationExtractor.h @@ -0,0 +1,200 @@ +#ifndef READERWRITER_ROTATION_EXTRACTOR +#define READERWRITER_ROTATION_EXTRACTOR +/* ArduinoFloppyReader (and writer) - Rotation Extractor +* +* Copyright (C) 2017-2021 Robert Smith (@RobSmithDev) +* https://amiga.robsmithdev.co.uk +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Library General Public +* License as published by the Free Software Foundation; either +* version 3 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 +* Library General Public License for more details. +* +* You should have received a copy of the GNU Library General Public +* License along with this library; if not, see http://www.gnu.org/licenses/ +*/ + +//////////////////////////////////////////////////////////////////////////////////////// +// Class to manage finding *exact* disk revolutions // +//////////////////////////////////////////////////////////////////////////////////////// +// +// Purpose: +// The class attempts to guess where an exact disk revolution occurs, and then re-aligns +// it such that it starts at the index pulse. This means we dont need to wait for an index +// pulse to work out a revolution of the disk. The first time a disk is used we calculate +// the time of a single revolution and then use that as a guide to how long a revolution will +// take in the future. +// +// This isn't 100% perfect but does seem to work. + +// With this defined you get speed data per bit. Undefined, per 8 bits. Nothing seems to notice much +// Inside *UAE it uses one speed value for 16 bits of MFM data so that's probably why. +// and besides, with this *undefined* we save about 700k of ram +#define HIGH_RESOLUTION_MODE + +// Instead of outputting "speed" values this will output bit-times in ns +#define OUTPUT_TIME_IN_NS + +// So worse case is the disk takes 210ms to spin, and every sequence is VERY fast, and every sequence is 01, this number is highly unlikely though +#define MAX_REVOLUTION_SEQUENCES 110000 + +// Number of sequences to match to find the index overlap position or the rotation overlap position +// The higher the number, the more chance of perfect revolution alignment, but higher processing required at the end of each revolution +#define OVERLAP_SEQUENCE_MATCHES 1024 + +// Extra window either side. this allows more of a search range +#define OVERLAP_EXTRA_BUFFER 6 + +// Signal for index was not found +#define INDEX_NOT_FOUND 0xFFFFFFFF + + +// Class to extract a single rotation from an incoming mfm data sequence. +class RotationExtractor { +public: + + // Enum for the possible sequences we support + enum class MFMSequence : unsigned char { mfm01 = 0, mfm001 = 1, mfm0001 = 2, mfm0000 = 3 }; + + // A single sequence of MFM data + struct MFMSequenceInfo { + // Total time it took to read this in NS + unsigned short timeNS; + + // The MFM sequence discovered + MFMSequence mfm; + }; + + // Decoded version of the above + struct MFMSample { +#ifdef OUTPUT_TIME_IN_NS + // This is the time for each 'bit' + unsigned short bittime[8]; +#else +#ifdef HIGH_RESOLUTION_MODE + // This is the speed of each 'bit' as a % + unsigned short speed[8]; +#else + // This is the average speed of all 8 bits as a % + unsigned short speed; +#endif +#endif + + // This is the raw MFM bit-data + unsigned char mfmData; + }; + + // Struct for tracking what the index start looks like so we get it perfect (or at least consistant) + struct IndexSequenceMarker { + // Sequences found + MFMSequence sequences[OVERLAP_SEQUENCE_MATCHES]; + + // If this is actually valid + bool valid = false; + }; + +private: + // How long a revolution is + unsigned int m_revolutionTime = 0; + // An amount of time whereby we 'nearly' have a complete revolution of data + unsigned int m_revolutionTimeNearlyComplete = 0; + // Used while working out the above + unsigned int m_revolutionTimeCounting = 0; + // Where the first index pulse was discovered + unsigned int m_sequenceIndex = INDEX_NOT_FOUND; + // Where the second index pulse was discovered + unsigned int m_nextSequenceIndex = INDEX_NOT_FOUND; + // Where we were when we reached m_revolutionTime worth of data + unsigned int m_revolutionReadyAt = INDEX_NOT_FOUND; + // And a flag to set this as good + bool m_revolutionReady = false; + // If we should always use the index marker when finding revolutions + bool m_useIndex = false; + // Current amount of data in the buffer in ns + unsigned int m_currentTime = 0; + // Current position of the buffer + unsigned int m_sequencePos = 0; + // Used to track exactly how much data has been submitted + unsigned int m_timeReceived = 0; + // Sequences received thus far + MFMSequenceInfo m_sequences[MAX_REVOLUTION_SEQUENCES]; + // In index mode, this holds the initial sequences before the first index marker + MFMSequenceInfo m_initialSequences[OVERLAP_SEQUENCE_MATCHES * OVERLAP_EXTRA_BUFFER]; + // Length of the above datat in use + unsigned int m_initialSequencesLength = 0; + // Where we're writing to as its a circular buffer + unsigned int m_initialSequencesWritePos = 0; + // Sequences discovered around the index marker + IndexSequenceMarker m_indexSequence; + + // Finds the overlap between the start of the data and where we currently are + unsigned int getOverlapPosition() const; + + // is almost identical + const unsigned int getTrueIndexPosition(const unsigned int revolutionEnd, const unsigned int startingPoint = INDEX_NOT_FOUND); +public: + // Get and set the sequence identified as data round the INDEX pulse so that next time we get consistant revolution starting points + void setIndexSequence(const IndexSequenceMarker& sequence) { m_indexSequence = sequence; } + void getIndexSequence(IndexSequenceMarker& sequence) const { sequence = m_indexSequence; } + + // Reset this back to "empty" + inline void reset() { + m_indexSequence.valid = false; + m_revolutionReadyAt = INDEX_NOT_FOUND; + m_sequencePos = 0; + m_sequenceIndex = INDEX_NOT_FOUND; + m_nextSequenceIndex = INDEX_NOT_FOUND; + m_currentTime = 0; + m_revolutionReady = false; + m_initialSequencesLength = 0; + m_initialSequencesWritePos = 0; + m_timeReceived = 0; + } + + // Signal new disk, or maybe a motor restarted. Need to re-calculate rotation speed + inline void newDisk() { + reset(); + m_revolutionTime = 0; + m_revolutionTimeCounting = 0; + m_revolutionTimeNearlyComplete = 0; + } + + // Return the current revolution time + inline unsigned int getRevolutionTime() const { return m_revolutionTime; }; + + // Set the current revolution time + inline void setRevolutionTime(const unsigned int time) { m_revolutionTime = time; m_revolutionTimeNearlyComplete = (unsigned int)(time * 0.9f); }; + + // Return the total amount of time data received so far + inline unsigned int totalTimeReceived() const { return m_timeReceived; }; + + // Returns TRUE if this has learnt the time of a disk revolution + inline bool hasLearntRotationSpeed() const { return m_revolutionTime > 150000000; }; + + // Returns TRUE if we're in INDEX mode + inline bool isInIndexMode() const { return m_useIndex; }; + + // Sets the code so it always uses the index marker when finding revolutions + void setAlwaysUseIndex(bool useIndex) { m_useIndex = useIndex; }; + + // If this is about to spit out a revolution in a very small amount of time + inline bool isNearlyReady() const { return (m_revolutionTimeNearlyComplete) && (m_currentTime >= m_revolutionTimeNearlyComplete) && (!m_useIndex); } + + // Submit a single sequence to the list + void submitSequence(const MFMSequenceInfo& sequence, const bool isIndex); + + // Returns TRUE if we should be able to extract a revolution + inline bool canExtract() const { return (m_revolutionReadyAt != INDEX_NOT_FOUND) && (m_revolutionReady); }; + + // Extracts a single rotation and updates the buffer to remove it. Returns FALSE if no rotation is available + // If calculateSpeedFactor is true, we're in INDEX mode, and HIGH_RESOLUTION_MODE is defined then this will output time in NS rather than the speed factor value + bool extractRotation(MFMSample* output, unsigned int& outputBits, const unsigned int maxBufferSizeBytes); +}; + + +#endif \ No newline at end of file diff --git a/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/lib/SerialIO.cpp b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/lib/SerialIO.cpp new file mode 100644 index 00000000..488ef59d --- /dev/null +++ b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/lib/SerialIO.cpp @@ -0,0 +1,620 @@ +/* ArduinoFloppyReader (and writer) +* +* Copyright (C) 2017-2021 Robert Smith (@RobSmithDev) +* https://amiga.robsmithdev.co.uk +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Library General Public +* License as published by the Free Software Foundation; either +* version 3 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 +* Library General Public License for more details. +* +* You should have received a copy of the GNU Library General Public +* License along with this library; if not, see http://www.gnu.org/licenses/ +*/ + +//////////////////////////////////////////////////////////////////////////////////////// +// Class to manage the communication between the computer and a serial port // +//////////////////////////////////////////////////////////////////////////////////////// +// +// +#include "SerialIO.h" + +#ifdef _WIN32 +#include +#include +#include "RotationExtractor.h" +#pragma comment(lib, "setupapi.lib") +static const DEVPROPKEY DEVPKEY_Device_BusReportedDeviceDesc2 = { {0x540b947e, 0x8b40, 0x45bc, 0xa8, 0xa2, 0x6a, 0x0b, 0x89, 0x4c, 0xbd, 0xa2}, 4 }; +static const DEVPROPKEY DEVPKEY_Device_InstanceId2 = { {0x78c34fc8, 0x104a, 0x4aca, 0x9e, 0xa4, 0x52, 0x4d, 0x52, 0x99, 0x6e, 0x57}, 256 }; +#ifndef GUID_DEVINTERFACE_COMPORT +DEFINE_GUID(GUID_DEVINTERFACE_COMPORT,0x86e0d1e0, 0x8089, 0x11d0, 0x9c, 0xe4, 0x08, 0x00, 0x3e, 0x30, 0x1f, 0x73); +#endif + +#else + +#include +#include +#include +#include +#include +#include +#include +#include + +#endif + +#include +#include +#include + +using convert_t = std::codecvt_utf8; +static std::wstring_convert strconverter; + +void quickw2a(const std::wstring& wstr, std::string& str) { + str = strconverter.to_bytes(wstr); +} +void quicka2w(const std::string& str, std::wstring& wstr) { + wstr = strconverter.from_bytes(str); +} + +// Constructor etc +SerialIO::SerialIO() { +} + +SerialIO::~SerialIO() { + closePort(); +} + +// Returns TRUE if the port is open +bool SerialIO::isPortOpen() const { +#ifdef _WIN32 + return m_portHandle != INVALID_HANDLE_VALUE; +#else + return m_portHandle != -1; +#endif + + return false; +} + +// Purge any data left in the buffer +void SerialIO::purgeBuffers() { + if (!isPortOpen()) return; + +#ifdef _WIN32 + PurgeComm(m_portHandle, PURGE_RXCLEAR | PURGE_TXCLEAR); +#else + tcflush(m_portHandle, TCIOFLUSH); +#endif +} + +// Sets the status of the DTR line +void SerialIO::setDTR(bool enableDTR) { + if (!isPortOpen()) return; + +#ifdef _WIN32 + EscapeCommFunction(m_portHandle, enableDTR ? SETDTR : CLRDTR); +#else + int pinToControl = TIOCM_DTR; + ioctl(m_portHandle, enableDTR ? TIOCMBIS : TIOCMBIC, &pinToControl); +#endif +} + +// Returns the status of the CTS pin +bool SerialIO::getCTSStatus() { + if (!isPortOpen()) return false; + +#ifdef _WIN32 + DWORD mask = 0; + if (!GetCommModemStatus(m_portHandle, &mask)) return false; + return (mask & MS_CTS_ON) != 0; +#else + int status; + ioctl(m_portHandle, TIOCMGET, &status); + return (status & TIOCM_CTS) != 0; +#endif + + return false; +} + +// Returns a list of serial ports discovered on the system +void SerialIO::enumSerialPorts(std::vector& serialPorts) { + serialPorts.clear(); + +#ifdef _WIN32 + // Query for hardware + HDEVINFO hDevInfoSet = SetupDiGetClassDevs(&GUID_DEVINTERFACE_COMPORT, nullptr, nullptr, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); + if (hDevInfoSet == INVALID_HANDLE_VALUE) return; + + // Scan for items + DWORD devIndex = 0; + SP_DEVINFO_DATA devInfo; + devInfo.cbSize = sizeof(SP_DEVINFO_DATA); + + // Enum devices + while (SetupDiEnumDeviceInfo(hDevInfoSet, devIndex, &devInfo)) { + HKEY key = SetupDiOpenDevRegKey(hDevInfoSet, &devInfo, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_QUERY_VALUE); + if (key != INVALID_HANDLE_VALUE) { + + WCHAR name[128]; + DWORD nameLength = 128; + + // Get the COM Port Name + if (RegQueryValueExW(key, L"PortName", NULL, NULL, (LPBYTE)name, &nameLength) == ERROR_SUCCESS) { + SerialPortInformation port; + port.portName = name; + + // Check it starts with COM + if ((port.portName.length() >= 4) && (port.portName.substr(0, 3) == L"COM")) { + // Get the hardware ID + nameLength = 128; + DWORD dwType; + if (SetupDiGetDeviceRegistryPropertyW(hDevInfoSet, &devInfo, SPDRP_HARDWAREID, &dwType, (LPBYTE)name, 128, &nameLength)) { + std::wstring deviceString = name; + int a = (int)deviceString.find(L"VID_"); + if (a != std::wstring::npos) port.vid = wcstol(deviceString.substr(a + 4).c_str(), NULL, 16); + a = (int)deviceString.find(L"PID_"); + if (a != std::wstring::npos) port.pid = wcstol(deviceString.substr(a + 4).c_str(), NULL, 16); + } + + // Description + DWORD type; + if (SetupDiGetDeviceProperty(hDevInfoSet, &devInfo, &DEVPKEY_Device_BusReportedDeviceDesc2, &type, (PBYTE)name, 128, 0, 0)) port.productName = name; + + // Instance + if (SetupDiGetDeviceProperty(hDevInfoSet, &devInfo, &DEVPKEY_Device_InstanceId2, &type, (PBYTE)name, 128, 0, 0)) port.instanceID = name; + + serialPorts.push_back(port); + } + } + RegCloseKey(key); + } + + devIndex++; + } + + SetupDiDestroyDeviceInfoList(hDevInfoSet); + +#else + + DIR* dir = opendir("/sys/class/tty"); + if (!dir) return; + + struct dirent* entry; + struct stat statbuf; + + while ((entry = readdir(dir))) { + std::string deviceRoot = "/sys/class/tty/" + std::string(entry->d_name); + if (lstat(deviceRoot.c_str(), &statbuf) == -1) continue; + if (!S_ISLNK(statbuf.st_mode)) deviceRoot += "/device"; + + char target[PATH_MAX]; + int len = readlink(deviceRoot.c_str(), target, sizeof(target)); + if ((len <= 0) || (len >= PATH_MAX-1)) continue; + target[len] = '\0'; + + if (strstr(target, "virtual")) continue; + if (strstr(target, "bluetooth")) continue; + + if (strstr(target, "usb")) { + std::string name = "/dev/" + std::string(entry->d_name); + + SerialPortInformation prt; + quicka2w(name, prt.portName); + + std::string dirName = "/sys/class/tty/" + std::string(entry->d_name) + "/device/"; + std::string subDir = ""; + + for (int i=0; i<5; i++) { + subDir += "../"; + std::string vidPath = dirName + "/"+subDir+"/idVendor"; + + int file = open(vidPath.c_str(), O_RDONLY | O_CLOEXEC); + if (file == -1) continue; + FILE* fle = fdopen(file, "r"); + int count = fscanf(fle, "%4x", &prt.vid); + fclose(fle); + if (count !=1) continue; + + vidPath = dirName + "/"+subDir+"/idProduct"; + file = open(vidPath.c_str(), O_RDONLY | O_CLOEXEC); + if (file == -1) continue; + fle = fdopen(file, "r"); + count = fscanf(fle, "%4x", &prt.pid); + fclose(fle); + if (count !=1) continue; + + vidPath = dirName + "/"+subDir+"/product"; + file = open(vidPath.c_str(), O_RDONLY | O_CLOEXEC); + if (file == -1) continue; + fle = fdopen(file, "r"); + char* p; + if ((p = fgets(target, sizeof(target), fle))) { + if (p[strlen(p)-1] == '\n') p[strlen(p)-1] = '\0'; + quicka2w(target, prt.productName); + } + fclose(fle); + + vidPath = dirName + "/"+subDir+"/serial"; + file = open(vidPath.c_str(), O_RDONLY | O_CLOEXEC); + if (file == -1) continue; + fle = fdopen(file, "r"); + if ((p = fgets(target, sizeof(target), fle))) quicka2w(target, prt.instanceID); + fclose(fle); + + serialPorts.push_back(prt); + break; + } + } + } + closedir(dir); +#endif +} + +// Attempt ot change the size of the buffers used by the OS +void SerialIO::setBufferSizes(const unsigned int rxSize, const unsigned int txSize) { + if (!isPortOpen()) return; + +#ifdef _WIN32 + SetupComm(m_portHandle, rxSize, txSize); +#endif +} + +// Open a port by name +SerialIO::Response SerialIO::openPort(const std::wstring& portName) { + closePort(); + +#ifdef _WIN32 + std::wstring path = L"\\\\.\\" + portName; + m_portHandle = CreateFileW(path.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0); + if (m_portHandle == INVALID_HANDLE_VALUE) { + switch (GetLastError()) { + case ERROR_FILE_NOT_FOUND: return Response::rNotFound; + case ERROR_ACCESS_DENIED: return Response::rInUse; + default: return Response::rUnknownError; + } + } + updateTimeouts(); + return Response::rOK; +#else + std::string apath; + quickw2a(portName, apath); + m_portHandle = open(apath.c_str(), O_RDWR | O_NOCTTY | O_NDELAY); + if (m_portHandle == -1) { + switch (errno) { + case ENOENT: return Response::rNotFound; + case EBUSY: return Response::rInUse; + default: return Response::rUnknownError; + } + } + +#ifdef HAVE_FLOCK + flock(m_portHandle, LOCK_EX | LOCK_NB); +#endif +#ifdef TIOCEXCL + ioctl(m_portHandle, TIOCEXCL); +#endif + + updateTimeouts(); + return Response::rOK; +#endif + + return Response::rNotImplemented; +} + +// Shuts the port down +void SerialIO::closePort() { + if (!isPortOpen()) return; + +#ifdef _WIN32 + CloseHandle(m_portHandle); + m_portHandle = INVALID_HANDLE_VALUE; + +#else + close(m_portHandle); + m_portHandle = -1; +#endif +} + +// Changes the configuration on the port +SerialIO::Response SerialIO::configurePort(const Configuration& configuration) { + if (!isPortOpen()) return Response::rUnknownError; + +#ifdef _WIN32 + // Configure the port + COMMCONFIG config; + DWORD comConfigSize = sizeof(config); + memset(&config, 0, sizeof(config)); + + GetCommConfig(m_portHandle, &config, &comConfigSize); + config.dwSize = sizeof(config); + config.dcb.DCBlength = sizeof(config.dcb); + config.dcb.BaudRate = configuration.baudRate; + config.dcb.ByteSize = 8; + config.dcb.fBinary = true; + config.dcb.Parity = false; + config.dcb.fOutxCtsFlow = configuration.ctsFlowControl; + config.dcb.fOutxDsrFlow = false; + config.dcb.fDtrControl = DTR_CONTROL_DISABLE; + config.dcb.fDsrSensitivity = false; + config.dcb.fNull = false; + config.dcb.fTXContinueOnXoff = false; + config.dcb.fRtsControl = RTS_CONTROL_DISABLE; + config.dcb.fAbortOnError = false; + config.dcb.StopBits = 0; + config.dcb.fOutX = 0; + config.dcb.fInX = 0; + config.dcb.fErrorChar = 0; + config.dcb.fAbortOnError = 0; + config.dcb.fInX = 0; + return SetCommConfig(m_portHandle, &config, sizeof(config)) ? Response::rOK : Response::rUnknownError; + +#else + if (tcgetattr(m_portHandle, &term) < 0) return Response::rUnknownError; +#ifdef cfmakeraw + cfmakeraw(&term); +#endif + + term.c_iflag &= ~ (IXON | IXOFF | IXANY | IGNBRK | BRKINT | PARMRK | INPCK | ISTRIP | INLCR | IGNCR | ICRNL); + term.c_lflag &= ~ (ISIG | ICANON | ECHO | ECHOE | ECHONL | IEXTEN); + term.c_oflag &= ~ (OPOST | ONLCR | OCRNL | ONOCR | ONLRET); + term.c_cflag &= ~(HUPCL | CSIZE | PARENB | PARODD | CSTOPB); + term.c_cflag |= CREAD | CLOCAL | CS8; + term.c_iflag |= IGNPAR; + +#ifdef XCASE + term.c_lflag &= ~XCASE; +#endif +#ifdef IUTF8 + term.c_iflag &= ~IUTF8; +#endif +#ifdef CMSPAR + term.c_cflag &= ~CMSPAR; +#endif +#ifdef IMAXBEL + term.c_iflag &= ~IMAXBEL; +#endif +#ifdef IUCLC + term.c_iflag &= ~IUCLC; +#endif +#ifdef OLCUC + term.c_oflag &= ~OLCUC; +#endif +#ifdef NLDLY + term.c_oflag &= ~NLDLY; +#endif +#ifdef CRDLY + term.c_oflag &= ~CRDLY; +#endif +#ifdef TABDLY + term.c_oflag &= ~TABDLY; +#endif +#ifdef BSDLY + term.c_oflag &= ~BSDLY; +#endif +#ifdef VTDLY + term.c_oflag &= ~VTDLY; +#endif +#ifdef FFDLY + term.c_oflag &= ~FFDLY; +#endif +#ifdef OFILL + term.c_oflag &= ~OFILL; +#endif + + term.c_cc[VMIN] = 0; + term.c_cc[VTIME] = 0; + + int ctsRtsFlags = 0; +#ifdef CRTSCTS + ctsRtsFlags = CRTSCTS; +#else +#ifdef CNEW_RTSCTS + ctsRtsFlags = CNEW_RTSCTS; +#else + ctsRtsFlags = CCTS_OFLOW; +#endif +#endif + + if (configuration.ctsFlowControl) term.c_cflag |= ctsRtsFlags; else term.c_cflag &= ~ctsRtsFlags; + + // Now try to set the baud rate + int baud = configuration.baudRate; +#ifdef __APPLE__ + if (ioctl(m_portHandle, IOSSIOSPEED, &baud) == -1) return Response::rUnknownError; +#else +if (baud == 9600) { + term.c_cflag &= ~CBAUD; + term.c_cflag |= B9600; +} else { +#if defined(BOTHER) && defined(HAVE_STRUCT_TERMIOS2) + term.c_cflag &= ~CBAUD; + term.c_cflag |= BOTHER; + term.c_ispeed = configuration.baudRate; + term.c_ospeed = configuration.baudRate; + if (ioctl(m_portHandle, TCSETS2, &term) < 0) return Response::rUnknownError; +#else + term.c_cflag &= ~CBAUD; + term.c_cflag |= CBAUDEX; + if (cfsetspeed(&term, baud) < 0) return Response::rUnknownError; +#endif +#endif +} + // Apply that nonsense + tcflush (m_portHandle, TCIFLUSH); + if (tcsetattr(m_portHandle, TCSANOW, &term) != 0) return Response::rUnknownError; +#ifdef ASYNC_LOW_LATENCY + struct serial_struct serial; + ioctl(m_portHandle, TIOCGSERIAL, &serial); + serial.flags |= ASYNC_LOW_LATENCY; + ioctl(m_portHandle, TIOCSSERIAL, &serial); +#endif + + setDTR(false); + + + return Response::rOK; +#endif + + return Response::rNotImplemented; +} + +// Returns the number of bytes waiting to be read +unsigned int SerialIO::getBytesWaiting() { + if (!isPortOpen()) return 0; +#ifdef _WIN32 + DWORD errors; + COMSTAT comstatbuffer; + + if (!ClearCommError(m_portHandle, &errors, &comstatbuffer)) return 0; + return comstatbuffer.cbInQue; +#else + int waiting; + if (ioctl(m_portHandle, TIOCINQ, &waiting) < 0) return 0; + return (unsigned int)waiting; +#endif +} + +// Attempts to write some data to the port. Returns how much it actually wrote. +// If writeAll is not TRUE then it will write what it can until it times out +unsigned int SerialIO::write(const void* data, unsigned int dataLength) { + if ((data == nullptr) || (dataLength == 0)) return 0; + if (!isPortOpen()) return 0; + +#ifdef _WIN32 + DWORD written = 0; + if (!WriteFile(m_portHandle, data, dataLength, &written, NULL)) written = 0; + return written; +#else + unsigned int totalTime = m_writeTimeout + (m_writeTimeoutMultiplier * dataLength); + + struct timeval timeout; + timeout.tv_sec = totalTime / 1000; + timeout.tv_usec = (totalTime - (timeout.tv_sec * 1000)) * 1000; + + size_t written = 0; + unsigned char* buffer = (unsigned char*)data; + + fd_set fds; + + FD_ZERO(&fds); + FD_SET(m_portHandle, &fds); + + // Write with a timeout + while (written < dataLength) { + if ((timeout.tv_sec < 1) && (timeout.tv_usec < 1)) break; + + int result = select(m_portHandle + 1, NULL, &fds, NULL, &timeout); + if (result < 0) { + if (errno == EINTR) continue; else { + return 0; + } + + } + else if (result == 0) break; + + result = ::write(m_portHandle, buffer, dataLength - written); + + if (result < 0) { + if (errno == EAGAIN) continue; else { + return 0; + } + } + + written += result; + buffer += result; + } + + return written; +#endif + + return 0; +} + +// Attempts to read some data from the port. Returns how much it actually read. +// If readAll is TRUE then it will wait until all data has been read or an error occurs +// Returns how mcuh it actually read +unsigned int SerialIO::read(void* data, unsigned int dataLength) { + if ((data == nullptr) || (dataLength == 0)) return 0; + if (!isPortOpen()) return 0; + +#ifdef _WIN32 + DWORD read = 0; + if (!ReadFile(m_portHandle, data, dataLength, &read, NULL)) read = 0; + return read; +#else + unsigned int totalTime = m_readTimeout + (m_readTimeoutMultiplier * dataLength); + + struct timeval timeout; + timeout.tv_sec = totalTime / 1000; + timeout.tv_usec = (totalTime - (timeout.tv_sec * 1000)) * 1000; + + size_t read = 0; + unsigned char* buffer = (unsigned char*)data; + + fd_set fds; + FD_ZERO(&fds); + FD_SET(m_portHandle, &fds); + + while (read < dataLength) { + if ((timeout.tv_sec < 1) && (timeout.tv_usec < 1)) { + break; + } + + int result = select(m_portHandle + 1, &fds, NULL, NULL, &timeout); + + if (result < 0) { + if (errno == EINTR) continue; else break; + } + else if (result == 0) break; + result = ::read(m_portHandle, buffer, dataLength - read); + + if (result < 0) { + if (errno == EAGAIN) continue; else break; + } + read += result; + buffer += result; + } + + return read; + + +#endif + + return 0; +} + +// Update timeouts +void SerialIO::updateTimeouts() { + if (!isPortOpen()) return; + +#ifdef _WIN32 + COMMTIMEOUTS tm; + tm.ReadTotalTimeoutConstant = m_readTimeout; + tm.ReadTotalTimeoutMultiplier = m_readTimeoutMultiplier; + tm.ReadIntervalTimeout = 0; + tm.WriteTotalTimeoutConstant = m_writeTimeout; + tm.WriteTotalTimeoutMultiplier = m_writeTimeoutMultiplier; + SetCommTimeouts(m_portHandle, &tm); +#endif +} + +// Sets the read timeouts. The actual timeout is calculated as waitTimetimeout + (multiplier * num bytes) +void SerialIO::setReadTimeouts(unsigned int waitTimetimeout, unsigned int multiplier) { + m_readTimeout = waitTimetimeout; + m_readTimeoutMultiplier = multiplier; + + updateTimeouts(); +} + +// Sets the write timeouts. The actual timeout is calculated as waitTimetimeout + (multiplier * num bytes) +void SerialIO::setWriteTimeouts(unsigned int waitTimetimeout, unsigned int multiplier) { + m_writeTimeout = waitTimetimeout; + m_writeTimeoutMultiplier = multiplier; + + updateTimeouts(); +} \ No newline at end of file diff --git a/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/lib/SerialIO.h b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/lib/SerialIO.h new file mode 100644 index 00000000..1663d88a --- /dev/null +++ b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/ArduinoFloppyReader/lib/SerialIO.h @@ -0,0 +1,134 @@ +#ifndef DISKREADERWRITER_SERIAL_IO +#define DISKREADERWRITER_SERIAL_IO +/* ArduinoFloppyReader (and writer) +* +* Copyright (C) 2017-2021 Robert Smith (@RobSmithDev) +* https://amiga.robsmithdev.co.uk +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Library General Public +* License as published by the Free Software Foundation; either +* version 3 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 +* Library General Public License for more details. +* +* You should have received a copy of the GNU Library General Public +* License along with this library; if not, see http://www.gnu.org/licenses/ +*/ + +//////////////////////////////////////////////////////////////////////////////////////// +// Class to manage the communication between the computer and a serial port // +//////////////////////////////////////////////////////////////////////////////////////// +// +// + +#include +#include + +#ifdef _WIN32 +#ifdef USING_MFC +#include +#else +#include +#endif +#else +#include +#endif + +extern void quickw2a(const std::wstring& wstr, std::string& str); +extern void quicka2w(const std::string& str, std::wstring& wstr); + + +class SerialIO { +private: + unsigned int m_readTimeout = 0, m_readTimeoutMultiplier = 0; + unsigned int m_writeTimeout = 0, m_writeTimeoutMultiplier = 0; + +#ifdef _WIN32 + HANDLE m_portHandle = INVALID_HANDLE_VALUE; +#else + int m_portHandle = -1; +#ifdef HAVE_STRUCT_TERMIOS2 + struct termios2 term; +#else + struct termios term; +#endif +#endif + + // Update timeouts + void updateTimeouts(); + +public: + // Definition of a serial port + struct SerialPortInformation { + // The "file" name of the port + std::wstring portName; + // Port details + unsigned int vid = 0, pid = 0; + // Product name + std::wstring productName; + // Instance ID + std::wstring instanceID; + }; + + // Configuration settings for the port + struct Configuration { + unsigned int baudRate = 9600; + bool ctsFlowControl = false; + }; + + enum class Response { rOK, rInUse, rNotFound, rUnknownError, rNotImplemented }; + + // Constructor etc + SerialIO(); + virtual ~SerialIO(); + + // Sets the status of the DTR line + void setDTR(bool enableDTR); + + // Returns the status of the CTS pin + bool getCTSStatus(); + + // Returns TRUE if the port is open + bool isPortOpen() const; + + // Returns a list of serial ports discovered on the system + static void enumSerialPorts(std::vector& serialPorts); + + // Purge any data left in the buffer + void purgeBuffers(); + + // Returns the number of bytes waiting to be read + unsigned int getBytesWaiting(); + + // Open a port by name + Response openPort(const std::wstring& portName); + + // Shuts the port down + void closePort(); + + // Attempt ot change the size of the buffers used by the OS + void setBufferSizes(const unsigned int rxSize, const unsigned int txSize); + + // Changes the configuration on the port + Response configurePort(const Configuration& configuration); + + // Attempts to write some data to the port. Returns how much it actually wrote. + unsigned int write(const void* data, unsigned int dataLength); + + // Attempts to read some data from the port. Returns how much it actually read. + // Returns how mcuh it actually read + unsigned int read(void* data, unsigned int dataLength); + + // Sets the read timeouts. The actual timeout is calculated as waitTimetimeout + (multiplier * num bytes) + void setReadTimeouts(unsigned int waitTimetimeout, unsigned int multiplier); + + // Sets the write timeouts. The actual timeout is calculated as waitTimetimeout + (multiplier * num bytes) + void setWriteTimeouts(unsigned int waitTimetimeout, unsigned int multiplier); +}; + + +#endif \ No newline at end of file diff --git a/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/FloppyDriveController.sketch/FloppyDriveController.sketch.ino b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/FloppyDriveController.sketch/FloppyDriveController.sketch.ino new file mode 100644 index 00000000..9de2b0dc --- /dev/null +++ b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/FloppyDriveController.sketch/FloppyDriveController.sketch.ino @@ -0,0 +1,1640 @@ +/* ArduinoFloppyReader (and writer) +* +* Copyright (C) 2017-2021 Robert Smith (@RobSmithDev) +* https://amiga.robsmithdev.co.uk +* +* This sketch is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public +* License as published by the Free Software Foundation; either +* version 3 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 +* Library General Public License for more details. +* +* You should have received a copy of the GNU Library General Public +* License along with this sketch; if not, see http://www.gnu.org/licenses +*/ + +/* Latest History: Last Modified: 22/04/2021 + Firmware V1.4: Merged with Pull Request #6 (Modified the behavior of the current track location on Arduino boot - paulofduarte) which also addresses issues with some drives + Firmware V1.5: Merged with Pull Request #9 (Detect and read out HD floppy disks 1.44M by kollokollo) + Firmware V1.6: Added experimental unbuffered writing HD disk support + Firmware V1.7: Added suggestion from GitHub user "prickle" regarding the CHECK_SERIAL function which should reoslve issues with some of the USB to SERIAL converters + Firmware V1.8: Added support for read streaming with index sync support which includes timing data (for perfect copy of flux data for SCP image files) + Changed read timings slightly which means more disks can now be recovered! + Added support for PRECOMP disk writing (using PWM in 'one-shot' mode) to improve readability as you go past track 40 + Added some new functions which allow for more direct control of the drive + Remove the Erase function as discovered you just need to write a longer track to ensure you clear the gap. Workbench writes 13630 bytes per track. The first part is filler at 0xAA + Added support for disk change notifications support (requires small hardware modification below) + Firmware V1.8a: Added 'no-click' support +*/ + +///////////////////////////////////////////////////////////////////////////////////////////////////// +// This sketch manages the interface between the floppy drive and the computer as well as the // +// low-level disk reading and writing. For more information and how to connect your Arduino // +// to a floppy drive and computer visit https://amiga.robsmithdev.co.uk // +///////////////////////////////////////////////////////////////////////////////////////////////// +// This code doesnt actually do any decoding, and is mearly reading pulses, so can be used to // +// read data from other disk formats too. // +////////////////////////////////////////////////////////////////////////////////////////////// + +// ** Hardware Modification Changes to get the best support for disk change notifications ** +// Pin 34 on the floppy drive connector (Disk Ready/Change) must be connected to Pin 10 on the Arduino +// Pin 12 on the floppy drive connector (Select Disk B) must be *disconnected* from pin 5 on the Arduino and connected to Pin 11 on the Arduino. Note you *must* leave the connection between Arduino Pin 5 and Floppy Connector 16 in place +// On the Arduino, connect Pin 12 to GND (0v) - this enables this advanced mode automatically. +// If you can't connect pin12 to GND because you want to use the ISP headers, then see https://amiga.robsmithdev.co.uk/isp + +#define BAUDRATE 2000000 // The baudrate that we want to communicate over (2M) +#define BAUD_PRESCALLER_NORMAL_MODE (((F_CPU / (BAUDRATE * 16UL))) - 1) +#define BAUD_PRESCALLER_DOUBLESPEED_MODE (((F_CPU / (BAUDRATE * 8UL))) - 1) +#define UART_USE_DOUBLESPEED_MODE // We're using double speed mode + +#define MOTOR_TRACK_DECREASE HIGH // Motor directions for PIN settings +#define MOTOR_TRACK_INCREASE LOW + +// PIN 2 - INDEX PULSE PIN - used to detect a specific point on the track for sync. Not used by standard Amiga disks but some copy protection uses it. +#define PIN_INDEX_DETECTED 2 // Pin used to detect the index pulse +#define PIN_INDEX_PORT PIND +#define PIN_INDEX_MASK B00000100 + +// PIN 3 - WRITE DATA +#define PIN_WRITE_DATA 3 // Raw triggering of writing data to the disk +#define PIN_WRITE_DATA_PORT PORTD // The actual port the above pin is on +#define PIN_WRITE_DATA_MASK B00001000 // The mask used to set this pin high or low + +// PIN 4 - READ DATA +#define PIN_READ_DATA 4 // Reads RAW floppy data on this pin +#define PIN_READ_DATA_MASK B00010000 // The mask for the port +#define PIN_READ_DATA_PORT PIND // The port the above pin is on + +// PIN 5, 6 and 7 - DRIVE, HEAD MOTOR DIRECTION and CONTROL +#define PIN_DRIVE_ENABLE_MOTOR 5 // Turn on and off the motor on the drive +#define PIN_MOTOR_DIR 6 // Stepper motor output to choose the direction the head should move +#define PIN_MOTOR_STEP 7 // Stepper motor step line to move the head position + +// PIN 8 - Used to detect track 0 while moving the head +#define PIN_DETECT_TRACK_0 8 // Used to see if the drive is at track 0 + +// PIN 9 - HEAD SELECTION +#define PIN_HEAD_SELECT 9 // Choose upper and lower head on the drive + + +// PIN A0 - WRITE GATE (Floppy Write Enable) +#define PIN_WRITE_GATE A0 // This pin enables writing to the disk +#define PIN_WRITE_GATE_PORT PORTC // The actual port the above pin is on +#define PIN_WRITE_GATE_MASK B00000001 // The port pin mask for the gate + +// PIN A1 - CHECK WRITE PROTECTION +#define PIN_WRITE_PROTECTED A1 // To check if the disk is write protected + +// PIN A2 - CTS Pin from UART +#define PIN_CTS A2 // Pin linked to the CTS pin +#define PIN_CTS_PORT PORTC // Port the CTS pin is on +#define PIN_CTS_MASK B00000100 // Binary mask to control it with + +// Reserved for future use +#define PIN_HD A3 +#define PIN_RDY A4 + +// PIN 13 - Activity LED +#define PIN_ACTIVITY_LED 13 // Standard LED on Arduinos. We're just using this as a read/write status flag + +// ** Hardware Modification Changes to get the best support for disk change notifications ** We control these regardless +#define PIN_DISK_CHANGE 10 // This is actually disk exists pin. Some drives have a resistor that needs to be added/removed to get this operation. This is usually the default on PC drives. +#define PIN_SELECT_DRIVE 11 +#define PIN_DETECT_ADVANCED_MODE 12 + + + +// Detect advanced mode +bool advancedControllerMode = false; // DO NOT CHANGE THIS, it is automatically detected. If you can't connect pin12 to GND because you want to use the ISP headers, then see https://amiga.robsmithdev.co.uk/isp + + +// Paula on the Amiga used to find the SYNC WORDS and then read 0x1900 further WORDS. +// A dos track is 11968 bytes in size, theritical revolution is 12800 bytes. +/* The ATARI ST could format a track with up to 11 Sectors, so the AMIGA settings are OK. */ +#define RAW_TRACKDATA_LENGTH (0x1900*2+0x440) // Paula assumed it was 12868 bytes, so we read that, plus the size of a sector, to find overlap + +/* For the HD (1.4 MBytes) Disks the amount of data should be about 26688: */ +#define RAW_HD_TRACKDATA_LENGTH (0x1900*2*2+0x440) + +// The current track that the head is over. Starts with -1 to identify an unknown head position. +int currentTrack = -1; + +// If the drive has been switched on or not +bool driveEnabled = 0; + +/* Where there should be a HD Disk been read (1) or a DD and SD Disk (0).*/ +bool disktypeHD = 0; + +// The timings here could be changed. These are based on F_CPU=16Mhz, which leaves the resolution at 1 tick = 0.0625usec, hence 16=1uSec + +// There's approx 4 clock ticks on average between noticing the flux transition and the counter value being read/reset +#define TIMING_OVERHEAD -4 + +// Calculate the bit-timing windows. These are the ideal exact centre of the next flux transition since the previous. +#define TIMING_DD_MIDDLE_2us (2 * 16) +#define TIMING_DD_MIDDLE_4us (4 * 16) +#define TIMING_DD_MIDDLE_6us (6 * 16) +#define TIMING_DD_MIDDLE_8us (8 * 16) + +// Work out the upper window of the timing. Most PLL allow for about 5% drift, but we're not interested in that and just want to recover the data +#define TIMING_DD_UPPER_2us (TIMING_DD_MIDDLE_2us + 16 + TIMING_OVERHEAD) +#define TIMING_DD_UPPER_4us (TIMING_DD_MIDDLE_4us + 16 + TIMING_OVERHEAD) +#define TIMING_DD_UPPER_6us (TIMING_DD_MIDDLE_6us + 16 + TIMING_OVERHEAD) +#define TIMING_DD_UPPER_8us (TIMING_DD_MIDDLE_8us + 16 + TIMING_OVERHEAD) + +// HD versions +#define TIMING_HD_UPPER_2us ((TIMING_DD_MIDDLE_4us/2) + 8 + TIMING_OVERHEAD) +#define TIMING_HD_UPPER_4us ((TIMING_DD_MIDDLE_6us/2) + 8 + TIMING_OVERHEAD) +#define TIMING_HD_UPPER_6us ((TIMING_DD_MIDDLE_8us/2) + 8 + TIMING_OVERHEAD) + +// 256 byte circular buffer - don't change this, we abuse the unsigned char to overflow back to zero! +#define SERIAL_BUFFER_SIZE 256 +#define SERIAL_BUFFER_START (SERIAL_BUFFER_SIZE-16) +unsigned char SERIAL_BUFFER[SERIAL_BUFFER_SIZE]; + + + + +#include + +// Because we turned off interrupts delay() doesnt work! This is approx ms +void smalldelay(unsigned long delayTime) { + delayTime*=(F_CPU/(8*1000L)); + + for (unsigned long loops=0; loops>8); + UBRR0L = (uint8_t)(BAUD_PRESCALLER_DOUBLESPEED_MODE); + UCSR0A |= 1<>8); + UBRR0L = (uint8_t)(BAUD_PRESCALLER_NORMAL_MODE); + UCSR0A &= ~(1<170) { + stopDriveForOperation(); + return false; + } + } + + stopDriveForOperation(); + + currentTrack = 0; // Reset the track number + return true; +} + +// Handle a no-click seeking operation +void handleNoClickSeek() { + if (currentTrack != 0) { + // Not allowed. + writeByteToUART('0'); + return; + } + + startDriveForOperation(); + + digitalWrite(PIN_MOTOR_DIR,MOTOR_TRACK_DECREASE); // Move OUT + stepDirectionHead(); + smalldelay(1); + + writeByteToUART('1'); + + // Now see if there is a disk in the drive. Returning '#' means no disk in drive + if (advancedControllerMode) { + if (digitalRead(PIN_DISK_CHANGE) == HIGH) writeByteToUART('1'); else writeByteToUART('#'); + } else { + // Don't detect disk + writeByteToUART('x'); + } + if (digitalRead(PIN_WRITE_PROTECTED) == LOW) writeByteToUART('1'); else writeByteToUART('#'); + + stopDriveForOperation(); +} + + +// Goto to a specific track. During testing it was easier for the track number to be supplied as two ASCII characters, so I left it like this +bool gotoTrackX(bool reportDiskChange) { + // Read the bytes + byte track1 = readByteFromUART(); + byte track2 = readByteFromUART(); + byte flags = 1; // default to normal speed + + if (reportDiskChange) { + flags = readByteFromUART()-'0'; + } + + // Work so its compatiable with previous versions + const unsigned char delayTime = 4 - (flags & 3); + + // Validate + if ((track1<'0') || (track1>'9')) return false; + if ((track2<'0') || (track2>'9')) return false; + + // Calculate target track and validate + int track = ((track1-'0')*10) + (track2-'0'); + if (track<0) return false; + if (track>81) return false; // yes amiga could read track 81! + + // Exit if its already been reached + if (track == currentTrack) { + if (reportDiskChange) writeByteToUART('2'); + return true; + } + + // If current track is unknown go to track 0 first + if (currentTrack == -1) goToTrack0(); + + if (reportDiskChange) writeByteToUART('1'); + + startDriveForOperation(); + + // And step the head until we reach this track number + if (currentTrack < track) { + digitalWrite(PIN_MOTOR_DIR,MOTOR_TRACK_INCREASE); // Move IN + while (currentTrack < track) { + stepDirectionHead(); + if (delayTime) smalldelay(delayTime); + currentTrack++; + } + } else { + digitalWrite(PIN_MOTOR_DIR,MOTOR_TRACK_DECREASE); // Move OUT + while (currentTrack > track) { + stepDirectionHead(); + if (delayTime) smalldelay(delayTime); + currentTrack--; + } + } + + if (reportDiskChange) { + // Now see if there is a disk in the drive. Returning '#' means no disk in drive + if (advancedControllerMode) { + if (digitalRead(PIN_DISK_CHANGE) == HIGH) writeByteToUART('1'); else writeByteToUART('#'); + } else { + if (flags & 4) { + // We've been told to check for disk presence regardless + if (nonModCheckForDisk()) writeByteToUART('1'); else writeByteToUART('#'); + } else { + // Don't detect disk + writeByteToUART('x'); + } + } + // The second byte is '1' for write protected and '#' for not write protected + if (digitalRead(PIN_WRITE_PROTECTED) == LOW) writeByteToUART('1'); else writeByteToUART('#'); + } + + stopDriveForOperation(); + + return true; +} + +// Checks manually to see if theres a disk on un-modded hardware +bool nonModCheckForDisk() { + register unsigned char lastState = PIN_READ_DATA_PORT & PIN_READ_DATA_MASK; + const unsigned char indexPinStatus = PIN_INDEX_PORT & PIN_INDEX_MASK; + + // Configure timer 2 just as a counter in NORMAL mode, we need rto measure approx 200ms (a full rotation) before giving up + TCCR2A = 0 ; // No physical output port pins and normal operation + TCCR2B = bit(CS20) | bit(CS21) | bit(CS22); // Precale = 1024, ie: divide the clock timer by 1024, meaning each 'count' is approx 0.064ms + OCR2A = 0x00; + OCR2B = 0x00; + + // So if the disk wasnt spinning, we allow longer + const unsigned char totalLoops = 18 + (!driveEnabled ? 62 : 0); + unsigned char counter = 0; + + // We could do this with timer 1, but hey. + for (unsigned int loops=0; loops=3) { + TCCR2A = 0; // disable and reset everything + TCCR2B = 0; // Stop timer 2 + return true; + } + } + } + } + + TCCR2A = 0; // disable and reset everything + TCCR2B = 0; // Stop timer 2 + + return false; +} + +// Test if theres a disk in the drive, a '1' if yes, a '#' if not +bool testForDisk(bool sendOutput) { + if (advancedControllerMode) { + bool isDisk = digitalRead(PIN_DISK_CHANGE) == HIGH; + + if (!isDisk) { + if (currentTrack < 40) { + digitalWrite(PIN_MOTOR_DIR,MOTOR_TRACK_INCREASE); + stepDirectionHead(); + digitalWrite(PIN_MOTOR_DIR,MOTOR_TRACK_DECREASE); + stepDirectionHead(); + } else { + digitalWrite(PIN_MOTOR_DIR,MOTOR_TRACK_DECREASE); + stepDirectionHead(); + digitalWrite(PIN_MOTOR_DIR,MOTOR_TRACK_INCREASE); + stepDirectionHead(); + } + isDisk = digitalRead(PIN_DISK_CHANGE) == HIGH; + } + if (sendOutput) { + if (isDisk) writeByteToUART('1'); else writeByteToUART('#'); + if (digitalRead(PIN_WRITE_PROTECTED) == LOW) writeByteToUART('1'); else writeByteToUART('#'); + } + return isDisk; + } else { + // This is much harder + startDriveForOperation(); + + bool diskFound = nonModCheckForDisk(); + + + if (sendOutput) { + if (diskFound) writeByteToUART('1'); else writeByteToUART('#'); + if (digitalRead(PIN_WRITE_PROTECTED) == LOW) writeByteToUART('1'); else writeByteToUART('#'); + } + + stopDriveForOperation(); + return diskFound; + } +} + +// Check if the disk is write protected. Sends '#' if its write protected, or '1' if its not. If theres no disk in the drive this number is meaningless +void checkWriteProtectStatus() { + startDriveForOperation(); + if (digitalRead(PIN_WRITE_PROTECTED) == LOW) { + // Drive is write protected + writeByteToUART('1'); + } else { + // Drive can be written to + writeByteToUART('#'); + } + stopDriveForOperation(); +} + + +#define CHECKSERIAL_ONLY() if (UCSR0A & bit(RXC0)) { \ + SERIAL_BUFFER[serialWritePos++] = UDR0; \ + serialBytesInUse++; \ + } + +// 14 is the minimum number here. Any less than this and the CHECKSERIAL_ONLY() code will impact the output. The pulse width doesn't matter as long as its at least 0.125uSec (its the falling edge that triggers a bit write) +// Because only the falling edge is important we achieve precomp by shifting the pulse starting position back or forward two clock ticks +// Because it may go back 2 ticks, we increase this number here by 2. 12 ticks is 750 ns, 14 ticks is 875 ns and 16 is 1000ns (1us) +// By doing this, the bit cell timing remains constant, but the actual write position is shifted +/- 125ns as required +#define PULSE_WIDTH 14 +// This is where the above starts from the end of the timer +#define PULSE_WIDTH_VALUE (0xFF - (PULSE_WIDTH-1)) +// This is where to start the counter from compensating for code delay of 6 ticks (measured) +#define PULSE_BREAK (58-PULSE_WIDTH) + +// This makes use of the PWM output to create the wayforms for us as accurate as possible. +void writePrecompTrack() { + // Check if its write protected. You can only do this after the write gate has been pulled low + if (digitalRead(PIN_WRITE_PROTECTED) == LOW) { + writeByteToUART('N'); + return; + } else + writeByteToUART('Y'); + + // Find out how many bytes they want to send + unsigned char highByte = readByteFromUART(); + unsigned char lowByte = readByteFromUART(); + unsigned char waitForIndex = readByteFromUART(); + + unsigned short numBytes = (((unsigned short)highByte)<<8) | lowByte; + + // Setup buffer parameters + unsigned char serialReadPos = 0; + unsigned char serialWritePos = SERIAL_BUFFER_START; + unsigned char serialBytesInUse = SERIAL_BUFFER_START; + digitalWrite(PIN_ACTIVITY_LED,HIGH); + + writeByteToUART('!'); + + PIN_CTS_PORT|=PIN_CTS_MASK; // stop any more data coming in! + + // Signal we're ready for data + PIN_CTS_PORT &= (~PIN_CTS_MASK); + + // Fill our buffer to give us a head start + for (unsigned char a=0; a0) { + if (!serialBytesInUse) break; + + // Read a byte from the buffer + register unsigned char currentByte = SERIAL_BUFFER[serialReadPos++]; + serialBytesInUse--; + register unsigned char counter = PULSE_WIDTH_VALUE - (PULSE_BREAK + ( (currentByte&0x03) *32)); + register unsigned char pulseStart = PULSE_WIDTH_VALUE; + if (currentByte & 0x04) pulseStart=PULSE_WIDTH_VALUE-2; // Pulse should be early, so just move the pulse start back + if (currentByte & 0x08) pulseStart=PULSE_WIDTH_VALUE+2; // Pulse should be late, so move the pulse start forward + + // Hardware error checks (frame error and overrun) + if (UCSR0A & (bit(FE0)|bit(DOR0))) break; + + // Run until the pulse starts. The pulse start is also timed so that its width is enough to cover the time to execute CHECKSERIAL_ONLY() + while (!(TIFR2 & bit(OCF2B))) { + CHECKSERIAL_ONLY(); + }; + + // Wait for overflow (ie: pulse finishes) + while (!(TIFR2 & bit(TOV2))); + // Set the new counter and clear all the overflows + TCNT2 = counter; + OCR2B = pulseStart; + + // Clear overflow flags + TIFR2 |= bit(TOV2); + TIFR2 |= bit(OCF2B); + + // Control I/O with the serial port + if (serialBytesInUse=240) {} + + // Now we write the data. Hopefully by the time we get back to the top everything is ready again. + WRITE_BIT(0x10,B10000000); + CHECK_SERIAL(); + WRITE_BIT(0x30,B01000000); + CHECK_SERIAL(); + WRITE_BIT(0x50,B00100000); + CHECK_SERIAL(); + WRITE_BIT(0x70,B00010000); + // Extra check for some of the other errors that can occur + if (UCSR0A & (bit(FE0)|bit(DOR0))) { + // This can't happen and causes a write failure + digitalWrite(PIN_ACTIVITY_LED,LOW); + writeByteToUART((UCSR0A & bit(FE0)) ? 'Y' : 'Z'); // Thus means buffer underflow. PC wasn't sending us data fast enough + PIN_WRITE_GATE_PORT|=PIN_WRITE_GATE_MASK; + // Need to allow data to come in again + PIN_CTS_PORT &= (~PIN_CTS_MASK); + TCCR2B = 0; // No Clock (turn off) + return; + } + WRITE_BIT(0x90,B00001000); + CHECK_SERIAL(); + WRITE_BIT(0xB0,B00000100); + CHECK_SERIAL(); + WRITE_BIT(0xD0,B00000010); + CHECK_SERIAL(); + WRITE_BIT(0xF0,B00000001); + PIN_CTS_PORT|=PIN_CTS_MASK; // Stop data coming in while we're not monitoring it + } + + // Turn off the write head + PIN_WRITE_GATE_PORT|=PIN_WRITE_GATE_MASK; + + // Done! + writeByteToUART('1'); + digitalWrite(PIN_ACTIVITY_LED,LOW); + + // Need to allow data to come in again + PIN_CTS_PORT &= (~PIN_CTS_MASK); + + TCCR2B = 0; // No Clock (turn off) +} + +// Write a track to disk from the UART - the data should be pre-MFM encoded raw track data where '1's are the pulses/phase reversals to trigger +// THIS CODE IS UNTESTED +void writeTrackFromUART_HD() { + // Configure timer 2 just as a counter in NORMAL mode + TCCR2A = 0 ; // No physical output port pins and normal operation + TCCR2B = bit(CS20); // Precale = 1 + OCR2A = 0x00; + OCR2B = 0x00; + + // Check if its write protected. You can only do this after the write gate has been pulled low + if (digitalRead(PIN_WRITE_PROTECTED) == LOW) { + writeByteToUART('N'); + return; + } else writeByteToUART('Y'); + + // Find out how many bytes they want to send + unsigned char highByte = readByteFromUART(); + unsigned char lowByte = readByteFromUART(); + unsigned char waitForIndex = readByteFromUART(); + PIN_CTS_PORT|=PIN_CTS_MASK; // stop any more data coming in! + + unsigned short numBytes = (((unsigned short)highByte)<<8) | lowByte; + + writeByteToUART('!'); + + register unsigned char currentByte; + + // Signal we're ready for another byte to come + PIN_CTS_PORT &= (~PIN_CTS_MASK); + + // Fill our buffer to give us a head start + for (int a=0; a=248) {} + + // Now we write the data. Hopefully by the time we get back to the top everything is ready again + WRITE_BIT(0x08,B10000000); + CHECK_SERIAL(); + WRITE_BIT(0x18,B01000000); + CHECK_SERIAL(); + WRITE_BIT(0x28,B00100000); + CHECK_SERIAL(); + WRITE_BIT(0x38,B00010000); + CHECK_SERIAL(); + WRITE_BIT(0x48,B00001000); + CHECK_SERIAL(); + WRITE_BIT(0x58,B00000100); + CHECK_SERIAL(); + WRITE_BIT(0x68,B00000010); + CHECK_SERIAL(); + WRITE_BIT(0x78,B00000001); + TCNT2=248; // a little cheating, but *should* work + PIN_CTS_PORT|=PIN_CTS_MASK; // Stop data coming in while we're not monitoring it + } + + // Turn off the write head + PIN_WRITE_GATE_PORT|=PIN_WRITE_GATE_MASK; + + // Done! + writeByteToUART('1'); + digitalWrite(PIN_ACTIVITY_LED,LOW); + + TCCR2B = 0; // No Clock (turn off) +} + + +// Write blank data to a disk so that no MFM track could be detected - this is no longer used +void eraseTrack() { + // Check if its write protected. You can only do this after the write gate has been pulled low + if (digitalRead(PIN_WRITE_PROTECTED) == LOW) { + writeByteToUART('N'); + return; + } else writeByteToUART('Y'); + + digitalWrite(PIN_ACTIVITY_LED,HIGH); + + // Enable writing + PIN_WRITE_GATE_PORT&=~PIN_WRITE_GATE_MASK; + + // To write the 01010101 sequence we're going to ask the Arduino to generate this from its PWM output. + TCCR2A = bit(COM2B1) | bit(WGM20) | bit(WGM21)| bit(WGM22); // (COM2B0|COM2B1) Clear OC2B. on compare match, set OC2B at BOTTOM. WGM20|WGM21|WGM22 is Fast PWM. + TCCR2B = bit(WGM22)| bit(CS20); // WGM22 enables waveform generation. CS20 starts the counter runing at maximum speed + // This generates a square wave, 3usec high, and 1usec low, 4uSec in total + OCR2A = 63; + OCR2B = 47; + TCNT2=0; + + // Now just count how many times this happens. Approx 200ms is a revolution, so we'll go 200ms + 5% to be on the safe side (210ms) + TIFR2 |= bit(TOV2); + + // 52500 is 210 / 0.004 + for (unsigned int counter=0; counter<52500; counter++) { + // Every time this loop completes, 4us have passed. + while (!(TIFR2 & bit(TOV2))) {}; + TIFR2 |= bit(TOV2); + }; + + // Turn off the write head to stop writing instantly + PIN_WRITE_GATE_PORT|=PIN_WRITE_GATE_MASK; + + TCCR2A = 0; + TCCR2B = 0; // No Clock (turn off) + + // Done! + writeByteToUART('1'); + digitalWrite(PIN_ACTIVITY_LED,LOW); +} + +// Write blank data to a disk so that no MFM track could be detected - this is no longer used +void eraseTrack_HD() { + // Check if its write protected. You can only do this after the write gate has been pulled low + if (digitalRead(PIN_WRITE_PROTECTED) == LOW) { + writeByteToUART('N'); + return; + } else writeByteToUART('Y'); + + digitalWrite(PIN_ACTIVITY_LED,HIGH); + + // Enable writing + PIN_WRITE_GATE_PORT&=~PIN_WRITE_GATE_MASK; + + // To write the 01010101 sequence we're going to ask the Arduino to generate this from its PWM output. + TCCR2A = bit(COM2B1) | bit(WGM20) | bit(WGM21)| bit(WGM22); // (COM2B0|COM2B1) Clear OC2B. on compare match, set OC2B at BOTTOM. WGM20|WGM21|WGM22 is Fast PWM. + TCCR2B = bit(WGM22)| bit(CS20); // WGM22 enables waveform generation. CS20 starts the counter runing at maximum speed + // This generates a square wave, 1.5usec high, and 0.1usec low, 4uSec in total + OCR2A = 31; + OCR2B = 15; + TCNT2=0; + + // Now just count how many times this happens. Approx 200ms is a revolution, so we'll go 200ms + 5% to be on the safe side (210ms) + TIFR2 |= bit(TOV2); + + // 52500 is 210 / 0.004, but we're tqice as quick, so do the loop twice + for (unsigned char loops=0; loops<2; loops++) + for (unsigned int counter=0; counter<52500; counter++) { + // Every time this loop completes, 4us have passed. + while (!(TIFR2 & bit(TOV2))) {}; + TIFR2 |= bit(TOV2); + }; + + // Turn off the write head to stop writing instantly + PIN_WRITE_GATE_PORT|=PIN_WRITE_GATE_MASK; + + TCCR2A = 0; + TCCR2B = 0; // No Clock (turn off) + + // Done! + writeByteToUART('1'); + digitalWrite(PIN_ACTIVITY_LED,LOW); +} + +// Read the track using a timings to calculate which MFM sequence has been triggered +void readTrackDataFast() { + // Configure timer 2 just as a counter in NORMAL mode + TCCR2A = 0 ; // No physical output port pins and normal operation + TCCR2B = bit(CS20); // Precale = 1 + OCR2A = 0x00; + OCR2B = 0x00; + // First wait for the serial port to be available + while(!(UCSR0A & (1<=TIMING_DD_UPPER_4us/2) && (lastWindow==0)) { + lastWindow = 1; + sendString("\n"); + } + if ((a>=TIMING_DD_UPPER_4us) && (lastWindow==1)) { + lastWindow = 2; + sendString("\n"); + } + if ((a>=TIMING_DD_UPPER_6us) && (lastWindow==2)) { + lastWindow = 3; + sendString("\n"); + } + if ((a>=TIMING_DD_UPPER_8us) && (lastWindow==3)) { + lastWindow = 4; + sendString("\n"); + } + if (cc[a]>1) { + sendInt(a); + sendString(", "); + sendTickAsuSec(a); + sendString(", "); + sendInt(cc[a]); + sendString(", "); + + if (a <= TIMING_DD_UPPER_2us) { + sendString("4us, (assumed) but bad"); + } else + if (a= TIMING_DD_UPPER_2us) counter -= TIMING_DD_UPPER_2us; else counter=0; \ + } else \ + if (counter=TIMING_DD_UPPER_8us is an error but some disks do this */ \ + counter=16; \ + } \ + + +// Read the track using a timings to calculate which MFM sequence has been triggered, hwoever, this keeps running until a byte is received from the serial port telling it to stop +void readContinuousStream() { + // Configure timer 2 just as a counter in NORMAL mode + TCCR2A = 0 ; // No physical output port pins and normal operation + TCCR2B = bit(CS20); // Precale = 1 (ie: no prescale) + EICRA = bit(ISC01); // falling edge of INT0 generates an interrupt, they are turned off, but its an easy way for us to detect a falling edge rather than monitoring a pin + OCR2A = 0x00; + OCR2B = 0x00; + // First wait for the serial port to be available to receive + while(!(UCSR0A & (1<250) break; // this is to stop the inteface freezing if theres no disk in the drive + }; + TCNT2 = 0; // reset + while (!(PIN_READ_DATA_PORT & PIN_READ_DATA_MASK)) {}; + + EIFR |=bit(INTF0); // clear the register saying it detected an index pulse + TIFR2 |= bit(OCF2B); // clear the overflow register + OCR2B = TIMING_DD_UPPER_8us; // This is set to the upper bound. If we exceed this we must have received a load of non-flux data, this allows us to write '0000' on the PC and loop back round + + // This sets up what would be an interrupt for when the READ PIN is signalled (unfortunatly we can't choose the direction. Its just set when it changes) + // But this allows us to make sure we dont miss a bit, although the timing might be off slightly. This is mainly used when disks have very long areas of + // no flux transitions, typilcally used for copy protection + PCMSK0 = 0; + PCMSK1 = 0; + PCMSK2 = bit(PCINT20); + PCICR = bit(PCIE2); // Enable the interrupt for this pin + + // First one will just be 01010101 and is ignored by the reader anyway + register unsigned char lastDataOutput = B01010101; + do { + + // A variable to store the data we collect + register unsigned char DataOutputByte = 0; + register unsigned char counter, average; + + // format is INDEX B1 B2 Spd + + READ_UNROLLED_LOOP(B00100000, B01000000, B01100000); + average = counter; + if ((EIFR&bit(INTF0))) { + EIFR|=bit(INTF0); + DataOutputByte|= 0x80; + }; + + READ_UNROLLED_LOOP(B00001000, B00010000, B00011000); + average += counter; + average >>= 3; + UDR0 = average | DataOutputByte; + + } while (!(UCSR0A & ( 1 << RXC0 ))); + + // Read the byte that was sent to stop us, should be a 0, although we don't care + unsigned char response = UDR0; + + // We want to make sure the PC knows we've quit, and whilst this isnt fool proof its a start. + // The chance of this exact sequence coming from MFM data from the drive is slim I guess + // A little hacky, bit without woriding another pin to something we dont have any other options + writeByteToUART('X'); + writeByteToUART('Y'); + writeByteToUART('Z'); + writeByteToUART(response); + writeByteToUART('1'); + + // turn off the status LED + digitalWrite(PIN_ACTIVITY_LED,LOW); + + // Disable the counter + TCCR2B = 0; // No Clock (turn off) + EICRA = 0; // disable monitoring + PCMSK2 = 0; + PCICR = 0; + OCR2A = 0; + OCR2B = 0; +} + +// The main command loop +void loop() { + PIN_CTS_PORT &= (~PIN_CTS_MASK); // Allow data incoming + PIN_WRITE_GATE_PORT|=PIN_WRITE_GATE_MASK; // always turn writing off + + // Read the command from the PC + byte command = readByteFromUART(); + + digitalWrite(PIN_SELECT_DRIVE, LOW); + smalldelay(1); + + switch (command) { + case 'x': break; // this is ignored. It's to help 'stop streaming' mode if it gets stuck on startup + case 'M': if (!driveEnabled) sendString("Drive motor not switched on.\n"); else measureCurrentDisk(); break; + + // Command: "?" Means information about the firmware + case '?':writeByteToUART('1'); // Success + writeByteToUART('V'); // Followed + writeByteToUART('1'); // By + writeByteToUART(advancedControllerMode ? ',' : '.'); // Advanced controller version + writeByteToUART('8'); // Number + break; + + // Command "." means go back to track 0 + case '.':if (goToTrack0()) // reset + writeByteToUART('1'); + else writeByteToUART('0'); + break; + + // Command "#" means goto track. Should be formatted as #00 or #32 etc + case '#': if (gotoTrackX(false)) { + smalldelay(1); // wait for drive + writeByteToUART('1'); + } else writeByteToUART('0'); + break; + + // Command "=" means goto track. Should be formatted as =00 or =32 etc. This also reports disk change and write protect status + case '=': if (gotoTrackX(true)) { + } else writeByteToUART('0'); + break; + + case 'O': handleNoClickSeek(); + break; + + // Command "[" select LOWER disk side + case '[': digitalWrite(PIN_HEAD_SELECT,LOW); + writeByteToUART('1'); + break; + + // Command "]" select UPPER disk side + case ']': digitalWrite(PIN_HEAD_SELECT,HIGH); + writeByteToUART('1'); + break; + + // Command "{" Read data continuously from the drive until a byte is sent from the PC + case '{': if (driveEnabled) { + if(disktypeHD) + writeByteToUART('0'); // not supported + else { + writeByteToUART('1'); + readContinuousStream(); + } + } else writeByteToUART('0'); + break; + + // Command "}" Write track to the drive with precomp + case '}': if (!driveEnabled) writeByteToUART('0'); else { + if(disktypeHD) + writeByteToUART('0'); + else { + writeByteToUART('1'); + writePrecompTrack(); + } + } + break; + + // Command "<" Read track from the drive + case '<': if(!driveEnabled) writeByteToUART('0'); + else { + writeByteToUART('1'); + if(disktypeHD) + readTrackDataFast_HD(); + else + readTrackDataFast(); + } + break; + + // Command ">" Write track to the drive + case '>': if (!driveEnabled) writeByteToUART('0'); else { + if(disktypeHD) { + writeByteToUART('0'); + } else { + writeByteToUART('1'); + writeTrackFromUART(); + } + } + break; + + // Command "X" Erase current track (writes 0xAA to it) + case 'X': if (!driveEnabled) writeByteToUART('0'); else + { + writeByteToUART('1'); + if (disktypeHD) + eraseTrack_HD(); + else + eraseTrack(); + } + break; + + // Command "H" Set HD disk type + case 'H': disktypeHD = 1; + writeByteToUART('1'); + break; + + // Command "D" Set DD or SD disk type + case 'D': disktypeHD = 0; + writeByteToUART('1'); + break; + + // Turn off the drive motor + case '-': digitalWrite(PIN_WRITE_GATE,HIGH); + digitalWrite(PIN_DRIVE_ENABLE_MOTOR,HIGH); + writeByteToUART('1'); + driveEnabled = 0; + break; + + // Turn on the drive motor and setup in READ MODE, this has no delay, the computer must handle this + case '*': if (!driveEnabled) { + digitalWrite(PIN_DRIVE_ENABLE_MOTOR,LOW); + driveEnabled = 1; + } + writeByteToUART('1'); + break; + + // Turn on the drive motor and setup in READ and WRITE MODE. They both work the same now + case '+': + case '~': if (!driveEnabled) { + digitalWrite(PIN_DRIVE_ENABLE_MOTOR,LOW); + driveEnabled = 1; + smalldelay(750); // wait for drive + } + writeByteToUART('1'); + break; + + // Check write protect flag + case '$': checkWriteProtectStatus(); + break; + + // Ask if the drive is ready (has a disk in it) and if its write protected or not + case '^': testForDisk(true); + break; + + case '&': runDiagnostic(); + break; + + // We don't recognise the command! + default: + writeByteToUART('!'); // error + break; + } + + if (!driveEnabled) { + digitalWrite(PIN_SELECT_DRIVE, HIGH); + smalldelay(1); + } +} diff --git a/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/FloppyDriveController.sketch/LICENSE.txt b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/FloppyDriveController.sketch/LICENSE.txt new file mode 100644 index 00000000..20d40b6b --- /dev/null +++ b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/FloppyDriveController.sketch/LICENSE.txt @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + 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. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + 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 +. \ No newline at end of file diff --git a/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/LICENSE.txt b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/LICENSE.txt new file mode 100644 index 00000000..20d40b6b --- /dev/null +++ b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/LICENSE.txt @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + 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. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + 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 +. \ No newline at end of file diff --git a/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/readme.md b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/readme.md new file mode 100644 index 00000000..d18e1b09 --- /dev/null +++ b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyDiskReader-master/readme.md @@ -0,0 +1,89 @@ +# Arduino Powered Floppy Disk Reader and Writer +...with 3rd party interfaces for Amiga, ATARI ST and DOS/PC Disk formats + +Created by Robert Smith @RobSmithDev +https://amiga.robsmithdev.co.uk + + +# What is it? +This project uses an Arduino to interface with a floppy disk drive and +communicate with a PC in order to recover the data from any formatted +disks. This includes Windows software to copy from and to ADF files. + +# WinUAE +This release added support for WinUAE, and hopefully could be ported to other +UAE's in the future. + +# Formats +The Arduino firmware allows to read the raw MFM data from each track of the +floppy. Decoding of the sector data is done on the PC. Usually a floppy image +file is created (ADF for AMIGA, .img for ATARI ST and PC/DOS). + +The 'firmware' can read MFM data from SD, DD and HD disks, although HD is untested. +This would therefore be able to read data from AMIGA, ATARI ST, PC DOS, COMMODORE C64 etc. + +# ArduinoFloppyReader +This **Visual Studio 2019** and **Linux** project contains two applications, a command line, +and a Windows dialog based application allow reading and writing of Amiga +formatted DD floppy disks. +Using the supplied makefile you should be able to **compile this on Linux**. It has +been tested with Raspberry Pi OS (Raspbian - Debian-based) + +# Scripts for linux +The above application apparently works under WINE, however, +Github user "kollokollo" made some scripts for reading other formats on Linux +too as follows: + The ATARI ST and DOS/PC floppy formats can be decoded whit these scripts. + 9,10,11 or 18 Sectors per track. Up to 82 tracks, DD (ca. 800 kBytes) or + HD (1.4 MBytes). The images usually contain a FAT12 file system which can be + directly mounted by linux without any additional driver. + For more information see + https://github.com/kollokollo/ArduinoFloppyDiskReader/tree/new/for_linux + They need the X11-Basic interpreter from http://x11-basic.sourceforge.net/ + +# Commodore 1581 Disks + To read commodore 1581 disks, check out the project at: + https://github.com/hpingel/pyAccess1581 + +# FloppyDriverController.sketch +This is the Arduino source code/sketch for all Floppy formats. +* Detect disk density (SD/DD or HD) +* Motor ON/OFF +* Seek to Track 0 +* Seek to any track (up to 82 - be careful, this can damage some drives!) +* read write protection status +* Read index pulse +* read raw track data (its, RAW, so FM, MFM; SD, DD or HD) +* write track data (un-buffered, DD, untested HD) with precompensation + +# AVR Firmware +If you want to use the AVR directly instead of within the Arduino environment, +then jump to [https://github.com/jtsiomb/usbamigafloppy] where John Tsiombikas +has ported the code. + +# Help and Instructions +For further details including how to wire this up please visit +[https://amiga.robsmithdev.co.uk] + +# Whats changed? +* v2.5 (firmware 1.8a) - Add support for 'noclick' +* v2.5 A whole load of changes including: + Fixed an encoding issue which prevented disks being read under Kickstart 1.3 or lower. + Added support for read "streaming" with index sync support + Changed read timings slightly which means more disks can now be recovered! + Added support for PRECOMP disk writing to improve readability as you go past track 40 + Added some new functions which allow for more direct control of the drive +* v2.4 Improved support for Usb to Serial devices based on findings from GitHub user "prickle" - firmware is now V1.7 +* v2.33 Merged with Pull Request #9 (Detect and read out HD floppy disks 1.44M by kollokollo) - firmware is now V1.6 +* v2.32 Merged with Pull Request #6 (Modified the behavior of the current track location on Arduino boot - paulofduarte) which also addresses issues with some drives and updated firmware to 1.4 + Made a small change to the diagnostics code to also erase the track before writing it +* v2.31 Upgraded the PC code side to work with Visual Studio 2019 resolving issue #11 (ourIThome) and merging pull request #13 (bassclefstudio) + Fixed a few typos in ArduinoInterface.cpp from pull request #12 (Crkk) +* V2.2 Fixed 99% of checksum errors when writing by erasing the track first +* V2.1 Diagnostics and potential write bug fixed +* V2.0 Disk reading has been vastly improved and you can now also write disks! +* V1.0 Initial release, can read disks fairly well + +# Licence +This entire project is available under the GNU General Public License v3 +licence. See licence.txt for more details. diff --git a/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyReader.exe b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyReader.exe new file mode 100644 index 0000000000000000000000000000000000000000..4d21884ea0bcc9da6bf0f88f9b995f30b54b3385 GIT binary patch literal 436736 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ⓈhB;q_33KlFpv<#84^L*m{9j(%WdVh(rbcQ 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

    ?B^dzgzGD<~k67g#? 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 literal 0 HcmV?d00001 diff --git a/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyReaderWin.exe b/trunk/Arduino/FloppyDriveController.sketch/V2.6/ArduinoFloppyReaderWin.exe new file mode 100644 index 0000000000000000000000000000000000000000..bd3ebd4f7583938c48973cdbf58e511bd549a679 GIT binary patch literal 4069888 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

    Ek4K(u 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èm~P|6Tmt) zm?M>~MamvP%EXb{N=V(RL29ImRG&7H^5akxX7-I~11SPQNS$5Fky?9*C{;B?L#cO> zBq;R&l^Iq}NKMxuwGl#zQ>u)x3rnf*!Xver7èm~SZ2Z2-!M{1xJsVf3Vef?)b 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

    5Zs~{9G-j)4!HlJAo_>pnnBdq< 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

    V*uQ)bSL{!2KgvYW_)cwE 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
    +d`T68+x;JA;7<9_Uf|Er_w9ny%(sW@b7AxMdBY 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

    y>Yc@p&H{b3RrkjioeoijD)^sqS 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

    wnoZkF7*Er2t@ugjey<&H?U>_&zG)zLx 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±~q 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͍EYc;~7 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

    BvP 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%0AW`qo}XiMS(omR$hg)W%KfM*Mkhj>&M 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%0A(vKALi*+LY)~N)6@(je??-KHrljfRQl} znSwPLOqf+$DkISRi{iSVb6S57K~BV0H*L7A6ZuSaV2U%TJNR@Y=1~#UbOWjTeEs2f zt?m=t@zsXFeM#rT&IW+jWq#{dBf?FOFTa@uX-UCkOdhrb%N8r)Xg7Q*tv}gf7M~Jz!!#|5T3dIClinr)XVx~QB6o>P01p~k z#uWzP;NYORs;y_!5yguV07h=gw9`xK(aSs1>v40l=Og0m} zMdq8;z*h=Dv?X={MN_*@uOmpS81}LIFEk^ly10RXhTRyh@ zp!gtL5rr6Z{0yE4#N+#u{9tjk{Q^C0`I|nXcd6#ydhUzO9etW=<-6$p;Yr80^+k}U z%qPTME4GO7kk>;^tsL%EY%YOR3Ntwb-tfZ$|K@Z)5B_GJ_@Cj9+<)SZAOC_oF1XXT z%7dPe5x|1MF`yO5%q^ZkpXsMarEtk-5)AxI*>Srh9oe~mEWS&rdx zJCHx4Yz;9pwQKgg%UW)|Y&Fw;-dm~A3Bp4sZ1%Y9lj<7YMdV8#K845*k}CjDdzM zpI?iRqI2jF@GpB6@u-m$bPW&!F4UT+{mdHU)Zrn!};nDQK7RCy}60hq^`BU@Pb>wGT28YA45_kG@YYK88>>@hA3)Nh4iP{3{7?#|J| zqO6Hyo;>2BN98;_y!!^-jHNT-o8*rBc^wTd{%puaFB7?I=E>IK;~azP?tFZ1=y)H{ zg4bI}IIW6tDnW=?-teHAz&&!tvq>=2`!Q%p8e$|Bs{5Z8B;jb*D5OPaWo2he; zqH?<>yetfvIo^D((?*1ow6ypGzEW1Ozm3RRUnd#(Ax=T>JXPhPjS9~&H_%_Bh>UJF zHA$qMkmsIrd>DkB9ujX!LI1jm)!2RT7tj#krxWfJ;9UD;p7tw-Ugth0d*u<(V&NJR z7LeT#W3;oG#wR*(8~rBgMX2qmEF0yfzugp%>AxJrHZzl@Iz!s^zCO~?Ymh`khy|6l z32lHYZ;BMjkV4Ca)GlPxh<#`EK!KU-p=qrO-?O8+DrA?>&VY{8ArCvnTEC9k^*mx5 z=b!$rAvp>)^x;sQ0z7`YzwkT4+FW0&)Tz09Pu`VK3w^M;roBA!}E+oEUlb}SFA9ao42a(TGb|`)y-Tf7JN!H1ZW$pWlrWtz2^gFdu zqZ`5>GNT(itYx2#eaa<;#D-~Th5f%acGBTYJrKny!H zyVSGQiy>kxm>f1=U(lIES5W%}P8){dmP0!&v$HG2N`V9q#hIe%2kj@!kQNqZMJDev z{+jG0n|)F0$V_G4CkXkXv&4jtd%)Xv_+Hvk#h}-8wLF=v@7XiX6Lw!sL~lQyl=?3A z&?OSyhsHaiQ<%aTo+vH`7BWR z3n=qX@Y#=`-dH=j<3J@oFveZ@@bR^^xvXI3tq@2(|H2qze>yFc2yHisEZGZ^M;9;iVmjJ(c%B6wSD_AVuGA(yDW}hSqqF$D zM!*ExoctSPQ&gK<`7Gl{uOkCt_@bBLVi=SL97OLQI0)T6U<_c*86XUB8B9`0G*h*a z!Y7pI48bALc>5!dcqK@G&=^**bVG?+(M)}hG1o$CdujN@7z#fKCs!Nt949|9hR4sV zkHKV{A0D2M`_uiD@V)w6sLh`DG@1;_nDe`wg!P)su1*Y1D$PU}mNs~UDD;?cdV*%P zsR*`O=<}LBR|eSfOzRrK$lfDH(fs?W?oz|>jrC|!{QL3pUtJoC5~m&>8X$b_?fq@n zo3>Y9{XR~MqP~}yTpYi=?rVu2)0e90_+&yPK)>MMzB6Ba&Fk#!>I50|0LGl?eGPm%0;>Le{8+l_Y_RmQAKD~XV|dINqpXSLA|)MMqzI+v1xt^41g z;_q<<>}T;m;~BrhTQEKk{wtmV_c;@SLjwg#%fSBBbMXDIct*;&9fk__fZySmmuXSE zptS;^8-m#q439ZCqB0tfqei}Qrm45HJA}@8FtqQ-^sm17rZ{YqexjUj5K>)%3!3m0 zl1g9DUmOm1GjrvB79q2 z{I+Ly2FiI)R`u(XbyM8;i=XQ?rlp`lD5n!mB65`FQ^?bNHHc{x73zvM8Bw6s<}?vB z(X#*OsfOQfyB+b(iA7l3*+GT8|H&B9ET}xqsV=uFuMhtgpJUI9VUMW5{WkZ$l3Vw) zQzC@&8+slY?Jj6Sio4Y%$vCR$sl8Pdx<(r6yXRFT9h+o)uvR|tq!W3>SV?Hb<3)VV z)yufwLCqYoUS@W7M7PUH-&`H_@R8$}%Zg%M8;p$fb4G2=wUqfMFuhH$n{)ch@2P5$ zd7@nbWm(!26@fB{@>hs^Gav{SpF1}pO6 zw7tTa?C3jElCBUmrUj|uR}@FOIfmj%rQOlr+z03&K;b;;IE}Kb!0m)IHDfyA1(Pg; z`NDEJreA*PG`Z?CNZaM}b2(91I%NB}8*66i@w&WSNbzV7r)N)s3|WQ!jJ?#eW^D9* zarZe;+v^8R=BXn#FtAG*8@l~G4l$!!lp^OKRL1z+{{<%GaiwLj9V>ih+T_Bu_T@w( zZUJNbpy|U*UR_|ri*N%LmevZYCw!3=-4iN4RIk7Z8VR#&Z+l(U3Vfd!FA84}9gNMm zeaN93p5|az$RLdZdPJPo)FLv6&)7rM92vDMxSewHR!A%kvEuR#8(n9~&*Ag#$u>W( zWtUhNRS)DcQ_@sBGk`OL_LOK+n zjR0Y5HhcEaD@Rq$~cRI#_Kq zs2MWai*}49;LID>;WE|H+IZNBlt!6TS_-?v?d5X(!T>y~Sy@|yhyB64*5v6TUS1#P zVymm8eAIqP={&(#$b>mT2>1H#>zoN{Y(;xE->z!}p7vACEVm@Q_5+9!*6C)u-fl=I z$nSGX9$ytkU}9)UO5N6|s||?VFD#@EsUqa#rr&(u@QTzvTJ2qK&Q^1EB&pmVxcC{*V%Xj`v9n z)f@{v5MKWPLR*q!H82;U=SVo_#>X1{+!Ou<-jhl=95MnvZPzxHoZ|+iNd;iMQ^|2r za@Y#Ngq~b-&uz@n%Hm$;Gwk(346=MYg>y354WXK>biL{E1D*0FT$z0*Q~KX7?Qd`s z!lzBfKi1OW0ivJ+APPB#^YUH7(z$i5 z(yt9Z0uzg4?hYFlu3Tn~L=h2=@d<8^K8GB)V`D(x+ib3ybEGP-iJPw=+1jl~(E)?H z8ABxg1Tg|invxO7;Au=uYgg0tEcBUesydwfaM00|OrcCuZ7r8uXICRu9Lit`K>?IZ zE%=I3xxaeM#VA;ng@dMXD=>aBQ40^4ml_Bz{pi$$VHzMN1^N6Qh*7hqX|m;@;`R^| zLxa_2!TeS&OKL=i4DG_MTQILskRl;mnaK^8Of8ncO9XczlW)2W=0cwIqaO(J>E)WZ)bqNzT0hh4s`Jec$*i=?Ivud z=BN125T`YUUeL!)PqjQIE)qkE?&3~PGOEY6Re#ly4=QOU{spAAgv^6G%0iW7EzzeW z$MCNtF$59nfiQ_Z5r$NTVD`x=U9aXvg-;TcngnSbj9s_j7p}>$z72z){I;tk%^Ppxfbl6EaHg9KZWs@SEn&7*1 z^j5f&8L-dh=R~&6XJ@2%9|fw7isbOzDpOl6bwDdT9+W1NhRjC~yaQEIVv;Jy*E)S; zHK{3l(%`0C9%ikpJEwj-p)mGuSocGYAybXfr^pSas6W5508%+s?Q06w|x=MEalMD z3S7j2C2tIZq|aYd0W&)Mt+CLhbo5csEqIZrLZ_+s>~c{Qv5JAJu!Zx^=Tsz@@8wBz zXR=rU3E9OD-!d&75^2DSL-lZVYnM*~YiU!^G&y;_UB7x7ALg4C^YPeUH^aE{BYDkq zXjnN+WN!3+k|T{}0T6Uo1-dh{*Sq5TgKoXlQ4E$LjNZ%#**9$Jmb~;M;lx7^9;0Pp4mFh?!-jd)_QzTYeeKwXI&aSaKYNnNH>uv&Q+xFIlY$4-ey&#ueWzXY2)c>t}5 zbNI-3W>Pb4c>D~f?ltYvm&zz?I3Z#wEvR-iPhst6$dS|Z9Lm;obe>0Aa47sBL%)UP zXG>gf!uvksi`c$uYJJUwx1bHKQA-|jU$NJH&UkZkidL@4KGHz-0YkG@bXq0&jL1N( zv94pq=(gDaBkFMZ9^`nrp9Rw0a%llHy`-UEwo7pmXycGT}#f zp%I*hmk?)ISVc_llqWQleGuN#$6lu(j_pPbrkA;!!`;|SnMbn|LQLBnQg6EZ%cY&e zk$KP2kRf}yMu^pSOe!_T&Lk)zpNQng?=_bF->toFJmggxbUP7E@Jc@Z7)rYWS-j65 z#)(6{F1<1UVRF^>=KkMLKNXEg>T^+#hICKvaTj%5hVR(#2fim8nIEKAuLw5l_v#=y zp0a5vI0V9$u2mm^%>aO4W^vWVkIh!Qc8*A8A#&aaioDgYB@{J_&OGlQSJeT`ZG0Zl zM&pQOYSCY7%%AQE*_lFhst8GC=?2qL$f9I-4SulWXYh(=sK30H(&3-bKUP!m5pCqx z@7xDn=G9d@9+S4+QUtPvn(`cU}&vM|x6(E!}49y)*ib%dpS*c>1=hKclPR|XmnYo*hYj87y32y6?Z%QF` z+{O+##`FsD`m^w61R9p#@)KEQhtp6js2GIVN5faXd`mQ#jb@#Y%nvR|KqjzDXc*05 z&0SaRt4RDTJUG7j+YDPAEmDz!Z@`vKecsT0`dM@2h3pRox z3=}q=J}Pce1>r>X9dg=FZX?|hC$FCg4XdA8r|jRaeO+Ox1y?)%Z2Pz&wiaANaHc|e zGtia?jqS2PrS6{>B4I$#-v7{7YWp5bH(-XcA^ubVSWY(ygs1`E^u^48I=xQqr@|zn z2TA``9=srgD{^qPAYyv$fY>aH_s4`rjzBU4YmAOuhkE2n0nSdEU8ex^lKV-PTZvQl zc5+V0LRtZ`^oJFtN4G4u4rqK}J%zk=0HQG*iOp^T`w}#Hj~NVUOSv58rU$~N)b%-f z_KH$p>8OhDQDmlBd8E@#wdo{Y*yQ(5!l*}DGx)XpbE51W13x!)0>MD4;aLe#Sd5kqTxJ>~uFOt3 zkru>5bURiAzQxDdWu?mll(WLdx2Wn;I6eU%f$D_oy`92uH~8}{0R+v%*&e|cb;_)J;eP((G62~vtqlpUe5#QDjr2X zA;O}1L|VebE-t++y6dcbrAue1uJO|5Po+Gf*DDI(y3-O6L}|fF-f>T-=|8}gV4pS| z|G<@$py}NIgDVmLb=@BX=Pz7|J!|v<1Oj(y;Z@&c;N_V{um|8lAUPmxpoh(Q|E;RO z!LNVC`TwbxiD~uc_J8X6H+@A=wZH1&9IZ$km+BQn51DKqrh&_?B59&~!Vbh+kIF$Z z?rw3TxJPM0k!mf=L0^+vWQhD@eBlx|X6%cK+YQ$nd^OHRm6|FIVh^lqB0InnEhJ4i zy`9yn>6%~WG`+fN3yhRu%A}uPcs*>yYbdHMtkJ1oP9pC5G2Y-D+3YifEpJm19xL2h z!wrv<4M2IBINHZ5Zs3GRasgZRRWpz90syh`m98XWi-pyH6AP^4{A$aood{wI?pk1S3x^3;1gsr%=Aa7vz zTJx5rD3*=?)=Pi89s}`d0s;Nkr~pIwQ}ciH6A0N~{RF*e^acb908sS}^z~C}w^@S| zQ1wUp{9&h_qs?DHJ8)qj1c_@5|5u%V9sbSuVE-%@`^Pv0y~X&KdjCy74s`CH^PBUf zPH8X$e8{WAcAi_=TD=?*`d{yw+N}6D1Cd>0I*VRjG~;Tlg+BZgvoRe)zyrapQ_o2~TrgHXdd`aqhQCfHh9gX= zU+MUIukZUp3G0!#f^mYw?^DRP4-klwWp9bH`}t0z(OHtLl0ZnQh4yt?$aZBT^_mQq z%iLDOiP{j1&&MP8%%~>hE{~|^GB|1eHW0}5)nqip>e3 zWJ;3g1h0ppJI@7H4hx$Rm^b8Z!NS7MC_qr5lv9G=IJJg_iA;j={{#sxJI6PMe^M_f zjeyq6Pd-fjENGiAk%Nk%Z%ebWg8+YSn zC*4uO@1>xxK99###s_TS*{%_^Az+(%MCjEwzL%1WN-MKDpd`JD+&#=$&DyNwYADnI ze;|{=fkH2~%F*Aei1LmOV;gYcLS6#H8pWCNAHqofqxSiWuN(Ux?L&6~_1CVC|8Adu zjeGvHeK<$!6G#xjn32VRiIm{o2*?@v)T|{4m|{H;_WDft{s8^1coohX#FOeZ5O~Ol zG$CvDb!+n!j8~QZ(^I=53Xl|AS(pfiClr#0uz5}h5Sp%g@1;vunJQSuhULN~{n4%W z>*3NX>#toG?k=QY01)PC)KA(>5SEXDP>NH7kS61W1!UWijM@=6DVdH9lcrIUiEG>Jx=Jbv z{@1eB6@ON?x;flmMY?^XSaFOjnj4-^ea!=hP@5g}C|kc)9Wbtfkg|W;@pQeZ%%CVrO0PYTCoUAl5>Z>}~ z%(z^JHdB*-(GIRv>%3KpXdQQbI(W~vG2O1rTi67?K@z=vB(Km_LxGB``?a zEwUx>3koOM-{NbD(RJDR{IjwUXJqcAauF%T@ci>*A`nL#c%!udBOf~ef1FYli{xI6*Q!?ib z=Lw?iirW-9DyLR3cWNp=AL_>YPaQm>gP;1*x8d^Qt}je;{;pT>()Z2f{1?du zItp4)SA+!>sqK)%A)u@8n9(L^AS)tg0Wb3x@(gA0#&r5$z{Ex19mHf|RR}Eo4?q?) zt?-0giGPw{ijn6RRklYy5c5ekf~c)r?EL`H8vaJl(HuVkNF(HFD%Cl6drjw~{mt#U{Ge7k70Ytt|k<+3qc3uZW5p(Kw} z#2O_mVs=v+@yR-?*`N=3zIRP`>!XYhHasSFD^rnyq5U58wP;*TyEsL|aWe+? zxZ+C`+%eF?_Q)9WRX7mI@ocSR4NW+b8*z=PGL)?PLh^bk(DP*D!)QxQAYLuxm-tFT zaW5Sgi!k~Z{hU;T1N$gEHq`{5oc=;OBcX;Q892IpQw>pM3&jWxF1*wXn%vWoig{sx zUbH9U&nqM}>}Bd#2*hZF$c~PA1eVA4^6O6IsDh2D+-6j31J1iw{S4B> z#k!Rxe`k&dBBTH2iC>4-8sva%Q}24VLrUd8IkJU#3nguzsZ(ThyJtyGKOpYMAFrNsv z2>cEaCIr*#?@GTy;|yxZ*^&@x3NFEyZ_xwu#-VWaS)M8ipHHsT5wAjGLMBc%#-iIt*KF5@{45O<}xA z$m`TdIpk@j9h!ut?T&va`(yC^Wed(}wA1y{CC|mp0sy7l!Z=3ci~OeGuG zCU9YK1p4hhc|sLb;Q4O&X{%jgAN?|H`y@XH+O6a0+$<*h*KMEbnDT+FI%1v`W%~Y{ zR|U!wG#%|HM{oeJYRpRD!WX2t&K6wu3lT3}dYl@3zLN!+AQ~CgA(k3sr@d!QPUbDm z%Bfs(3gYww=n%kQU<~N6NBL&?RDPj2_+qB2{Av)aw02C8 zGI?{b1vW3+eO#&XUJru^c&BmzfFBL<6yJRg3*OGSEnqrYIweq-$6hATYEH=;{5zym z*zmj7Ievd8Ch{U=tTSxQ4$g1Yffd^XeuEGDV?_>0R_`wRg zh`P<=-Ks_i)a0b|qWf#op|O@(WS#r(z^2Bxo67GY`1R|gxtyUMEtyDMPC7Neya48s z^fE0r6>+Dm<8eQI1P|zN^a6~Ua|{%~0v+l0ENF84pFmE!S*W`ei%qTlAxea0a&i)d z8I(Zlan2w#p%#QjvDlGoLB1nP$mh$3tVsn?Pi+La3L-6Z6g~`Vp!Jc7=KhkhEo5M) zkky=Zx4d>C5uXW!`r%B0##`MyIAT%p=obZht~Sq`8|8I{MPd z?Dq?{symWP%P9mHcwYJ$)wzYwtyInmeZ`$X@1NaB9UL>i#5bwN%&If<^oz?gj(;l&S9Ska0j$0LEQut;&Zik!w7JFP4+S zXX1-`0mm6`v7S8|;EH^L+9bq*1-Mn&R!*Z;K>72)t|0F;$GLdA&}G!o1wTh)DLgL! z8oDB(j7AgcneR(o+($x@&31)YDvzNIy8boc?R9dF(Q8M)uiLB$)B^;TYF{69CF-FA zR6v(p!28?UBQ-^IaA^Wh^+B?#3ix0sp%^dt9ULcLD~UiW$-1$1@>TbriAkqI7&<8T zE%0v$BNm9OTo(9O9YOpCnMOKk?JjvG5R}`~lC#dB#nY0z;YfhrZrG>=T-FW7p&Gr& zm62Fs5<~HOMzJpnCthDnu0-8?;u-hQXJ)GMcJjxqz^1&RXKc+au+w4)7EHY3ymums zA-}}3&D1CvyN!BS-!T>+oSQss{9!G#;b-Xs|4gOGgdBrI(q0ss*h@hYb#nDi)c$kEq3Da#4((MM!IC z(wmsBKG5hfnsnft$t7E#8t{>_>r7d;`dd|icYtcEdHv!+ig_*T<`C)BMavOetzIve zX54z3ZK6LOA@O5t)x(_rL09XN-|OJDqg!9JMww3WeWt;a*!kOVVn+IUb!r|Ebi<`W z*H@DEQ~mc}c9Z|@eEu(-E&mU{JAlY&{(t%1kpK3(lTpTM7=r?bYp=d@&X3Lm%u!DO zVe%Z%2wK3fs`DWw?ILNoU!WHd%H^=IqXf(2!pk#DJJ~<~jU*<)r=i`Qx z_L`PTl|d{5>Wg@a%444Zjp|1AU zg(ylyCZzVy*%X8qY~(N0{-t!cY}A4fQ1fD2>yH@t{4u5;U+uxE`!xdPe&ctgCk{D! zR~DZ;gFs>Mw=Cf!bg+zo(m|h6o>O1ZjCr%mbMfmeo7U^VnS5(AGv&#Fb3C8Gr;Bnt zCv~bd$$r|M`d-^=HmIR!^m9`4D|m;yEAP|zD^k(yY%M?7+UwSI-U>e--)ZM#MJuV_ z>ntPxGL;~w9`bcm3j69UmhK1h9&qj=RzBT^(B~180^mgDD|7+eK0IVDhPTx}m1bS5 zgpsFV9Hwi7M89&3SUt~R`BN}QZi`PUX<_rhxkS4Z9~4(CDx(C(sBd)zjoS?{=S;DI zG~B|W3&K(y>0{kLNzhTzKNjSszLrN&cNzZ#+7~KL!_D8c)qdQ?q;|0Is8!2trN)2# zQvjBgcAx?{`nj>v3Q&5rMaZIVK4bNwcUlZei@*kAJ`0=Abg-)WeS@XiI}WNpENCu+YfHcLF#}OIQf!;Q=F&LcD!nc=Co$j zE|QC|+Ktk*dvH!r)$ch3D;thpRU3ot(%f_Ar?B4O$LXea!cz7A;~i0kHeiAh;bc>U z1c=8qrU5b-bU%FHnfoxBRld)wpiL2UtvK4C4Po{%_vMA7&&|0gPk##E;FxZiHt-yU zztUr{i5B!}4r!5ZaEqwUYaiQMQYu$hA>ZIwqtuldz`HTJzo<-IduLm5S%9@+hWcp| zwRSumbrVfy`(10~k#)YFSLu~~&C76RuIxo_@WHB)9FM|4vY-(eF`*l-%zhn6{!|FE z1B&hy3%pE-i-uCI^okn0-xp$WGLt!jy0V78F~)8E`V)U!#&J16^E{&j@S$0)L<%y` z)T$v9T#kzf;?X6h5Qt7sVCrUPaTi4n3@Y*WoTYA3uIMLVPDgmGDYS+S5kBe)%;Db! z#T`#oLS147cy$z66MUlRhxUv2V5!BV?gXP*@1|n51_(HP(h})&7}EfjUc4X6rU$j3 zg${p#=%``K0#T%lOB`Mt_VKPg1QS~IDrDo!va^-uYrbZOE#4JfRP+$khZ`x-dK&#? zHbxxU?^A?r&)`}Tbg)Ij6YrIqFhX$)%GOj%oE_|2zZ<09Pw8h~0lk_2*)(5ibQp;P zCGn_-4Xl>x6BrR*)M(Vz$PBb|jYPxz?;_m-8~DWVMG=?^u+!k92{@4lK+k!O04rZs zLRvDum3?LIBcKn7MJ;!0J(Pke!{EL%uVMlZ&rNNY))2CvgG+04szwV#A%LojQL%y^ z@@;n%g~t#X4$ixB&?%%OfaR{FJod`Hyka0F*`o0}5SL=%%NIMPDWvhy#t1E@T6An& z6pEW-wfbJenFBE&hmi#*3}`vRBH?jb-!!C z7ZEHdx;_#lkd0gxD~7WhPTvaYhP~BN#I)RK{_R4hn`D`u;4Ag}B2$7W&x4&=xmmX= z2J+Ft6)_T8NlGFptO2br6G_^3*wJWe*cy{D+;vUN>)WsOCJHg*xMd#N$Hu+9mxsZN zL*y*^+R|#=*Ze=1?LhrNb-Url&3F4Rp!Zd6PZ@7mC<>__nI$G7|I4fYtzZ8uHIVKf ze%(Mt^6G#5`oG0#A-MnY>ym>NNt2}}5}zA(>PsK8SH+`qXHx?#BJ<8!%y$gUME30(pJ=2vMvH>I!FRdjXp{S#ii@bteko zu9gAG`AXL~zX7QxDb8iH=Lp+>e}GE!MKV|0csefP z(#4lnDZ>X?TkB%sN-Y~bO=?OAUXGHOBzrhp{p(kQCDoyN^lEza7)z(Ny$2!3(LjEw zHuL;B;mSgGyE7&b7D<~)!qz3Zi!WO>le#5Z6pOeYOJ6|#h<%kDThb59HfjI`oIn&* zSh3Zl_Fkj8KT*X(s0&thExKoQw^HcTfl_Tj`+_%HY>$8*Bs;j(JYL29MmR9w3mDt- z2;UE1zKD(vS5#iy4a+gFUA{95px}YyA-1lYgL&0*k38Pd)SV4+E{+hHNWU!tAxi{WZfuczWqPm z-ZDC_URfJ#Gc(4_cFfEiW6aF#n3)483H`QtLw7SXoIoOt3Kb_9!_b55WzTl1IgGU!M`R%oFnZxp9-Ae0%U}LV65v@7040 zoDAZjfZ*!I$eBGWN!HMB?u%?ruN2qz~ zl$hR7bIvwxl4~cgbp$GQ%Y%dI1kHZ$-*>OKx}E<_A#N$(0&~g@qsS6sSv@qJu?eFK zH9!iXgqcnd#neMCynt%1n*ES{xQR$pkpwbnk$ksXM1r6%4q^ml$!>#6sG2Tbu7u{QN;^V5j?jh(7mrO|NmnO(l!5P}J`E|I?=rdxBViGN zM;7{Zu#|$SpinRRDe)z>0sBJN|EuS%6M>{8F+I`Q5^Iz`p{l`f=wSHOebUtYz?fBUKr!fA9b&$VyeujU^VGpgizncU9$<7ac z`d1Efk8S*vlfpE@1^Hi&pM@Ro?k-wc8xtQ$dYzH%i;#iynTnc*k->t;5VpY*7V?|Y zXK})hkmQArN8#j)O*4w3N?k~x+ooXy#ar9>PCE#P2;I{*B7vR7p2U7rH*d*@Ao$PU zxcoiY141WH1z_&aE#C>bu?76q$MhuZGU(vl^jfx6>W5(ML`PA2X~h08yqXupH-8r3udVRML$0hj~q~~P;05#Kc*Bhu9ej;a(^k3 zZ*j?5iRx$lm|A959{mV>;{G~f&GZ~f^=sBjdy=VotZ<>>3_tDX9d&i*FiTbF+m7^; zi2&V87(zg6!j{9$=76qJjp7$lMH`W?`scEn59IimeIGG%(QGdJDvz>tfid?(XNBVe zU7GWULvvp+fJnv_WNg{%o*nI(EC5ppkSrxwidgC{WW~-1Q^gJ#j8nhG!!{^a>($j<-Sir!YpJjuBlM zWSTJDh9Ca}3%427ydm9JEesHT!p{OKrQk|LU@F{8;W{)vZ}o#NFIuFoAXZg!=|ec7 zcZA?;MvFjG9WL>CG!~}C_Tq-e{TLgM!>Qe$YD~fwXQ8+E&#Ue^EqNMSuX!b9WH@H) zo@FTQTq*u$-O#95F9`295WjaQJNyhkr*#U;X!ezR*H{8_!6VCvteuMBMhjh;3TVnu z_;o@nAtFI-G~hIsB$P9xj_=@73VAF_7rpj5%Gz^1zamT^%W4Q;w`7iz%y%}-;$ov!k z!1??e$22BcI;byv0=*xu-)+=)Xi4cqfx|h9_Ta=aPz)%-VG%fr)T&!m%9Q2jH#ROL z$%A-#Rg{D*pvp}eRVC4eGDqX#r9!hgJoi904WMpj8vV~eh!=1t{gbq8LgHX|aT~yk%UEIZVF$(y#d9QqF#!7ixmvwGq;(-KA z*miziKsrx&>-tsxZ2_b+cB#`zk{IsBGK2>Rh!(HwJ{d^UXeQ9rX?rZ|&`F+vUp=Qa zo%{kAj}o-PhZkRgX}2QaqXjMrd939`#>_wZc)1PfqMZ}?`uQHB-e%w|VBVvm_4 zIEUWJdUyjSWg?O;`jaj)!{t=LtPq~mN5^e`v&O|v9w*>|2knW=W|ObnpS!~)La4ko z-@L?=#D)k#a!^af&|#3l9rV?{i_Z!UQOtOE-eI1b7nk(}=Rkpn0~3gCyWHW9jrPP7 zkTKfER z1QQlE%Bnx@$Q)uJ1un(j0+T%s;m*d;!q~##L6F>ghO+2E1#gP7XFRjB-v*75Q|lWX zNn=#3iQ&aFKaaREnagfmFP4Xv4a**6RBCAy1%?wbz9hCA&UE@tkLA1 zp)IjtIDPDNTnXp_W1pDH*1cJnNkCRhycH`>+np{b2%nq<5;}6UIA#s&Jn<+O7(1*4o2FnJDvO{wG@K}fh%RnR+BYp6V@$VkE}io_ zR;49*S!&Hd$01s&#iPnn!!r_c=d+MYpVr2-oAEcJO>^gKDu3=Q@<~r>v~yr;Qk|!_ z+WX@5Y7mT_R>6xiYiwdFBy>(;C5{@>xyP?ph&Y?GXowv@w z%lw@Zj)!Puvp+g!{eD0P>(ZvWz|bOG3RjGRYFv?9?9#5ffY0y!ptmy&pBPP4wvD^> zLytUL%v^I*i~n>%#x^U{hp2#AXG}4Unz}>uY;ox4_1Nm}jxlo%K$RR;?uIZcz^D-= zL4zI^UCCF-JDZ^fs}m-JuL~lvhNXPMqo_B}h`q)oC4MW-Q{J+RJ%TA^WM%~0{3d)v z0RRu$0`F`W5hEc-l)m0Qgi`u7@vcq}8EFlIY`IH3E${0Lc;|BobtJon&<+qULD)uZ(>xp(7Vy*pkDB1EY(sFg>O= zURP7wx?m8wXII5wR5e%M?*L$ZtVXG%s7uVaz@Eai9d1##?<#ejrN|*ue-P5vV8mTT zud4vdnm|*{jqIKu$fUgM$VDD#ux=znorim{t>;ofq%9D#a$tv?0eq5T64ZONDf^Hu z$VCNxAxM(i^mD1)m7KuX7>>)QvabA24@WQPlmqBJNM@*XeJ?M5$!$(%Js4`PvKS`Z{Z(k7$%Mwh+wsTlF8R@g@&BG6;uHj#12hsBx|x+I=3rVXtTxtY#!QS;_pV z<#F!~2dBv+IV{?wP5NbXO)>G@1@fw~bfM&xC5D7@lKvLFg@qZor`$0{^keFr1743nAQjDhz zFnkw7c{=qBJ(=fWH|xzxL6!`{sVn-T#6c4YEk3jJ+rvmfDmavezzyFoPN;%&i2(Qz zyRs?9%mzN*?tV)j(-d0(K>-+q{)n;?mx zx9FOrP?wQy$B?s_-)HRUFx#x0wwfr+$f&tz?o$9+!?~?2@W4Q+fN|U$N)pthZT0*s zqHELP#LT25L;^pE8cIMs`2PD@pMjXNh?;#bYhF!|uW(I^YxPQOm@RRlMm^>=F~GE`U(;g8w~ zk4m7)Udewgts8bhg(ITuMA=X7TF?=;@2u`l*|gG8c}b~NC<{L2<-I3H&Ox0fJvZmz%-cgSV9CBBB%qoTcv2mp2skDJrr0^hTb)2=4!OUG+Ef z{|V3i=e`~|uK&Sv$<_{P3!g%_8t?CPoq4En;+JEk7&$3CrX@s43}a=WBrOtWb5}nV z%M8N_ z@+6Q}?=5EcXPt|iryE=PTg_RXT>T7qXi$KkyNe9NxTh_iie0tjA)0--?FEtqp{d9s@Lu7ku}Q#upbq}T>j{j zl@()~om|f2{_x|OTJjo;u}CBzrdi5*6Spw9VNw7A*Th(DNoseQljW`0i||I)t6ZfR z=1;JnO>PF-wfS8q#ul6>9HcRtb>~f~ipEqiGKftBMl0a)a-zUbO`Q0gyXYcX{!?{y z#C~2)crm#$&;fr35WPEjwJbLGS zJi0Ht;WY87#0~Y1L9$NzEEBO{IYuhL#eJ1(*~3kQR+)$6^_{Y6@goW7cIg=eZHJ zw6pc#M0YoTVy$CO#V}EPzk3$cImoy&jYjQ}B~7tRr6+1;Pp&dW`EJJFMm9B$fVFQ5 zNzUTznx=E-Nl-S!$IEvlesUKD%iisZ!FgWbd38>6l_<8tRx`0^JfBH%er@R+>$9?}{(;y+c*2#Qx0^C_fK!xrHzgdwQlJ zSG~iocGIa%D52gG+Bvs;eQa}%J|aFWPvF9V#-BTpiop%;kr=!A323u2kf%)cf&5#o z!k%v{)J+>}0vPppGVngZrLAXfhV`~TMZhTx{pMDiCPGkO%gUNw6>2t?DUREE?pPuy zq|uwb-cG6a>)TIn+huMPe`do0TA2B@uD>}H?8j7RwosBDl3Vg_Jd95oymme{eyPL+ zj-$gRgb(DAqeoAlhG`$abo&(+9=mL@iH1|&pcTSCbw+PhczVc@_8`W__CCrzk$~xe zxosLC78B?!I215skWqBU#im0rYSt?C00YD@Q5^%Sh$(hS_z>&Nl?+Nn>V{75&+N;{ z@_P75{hw{c3rF%vSfG@34dcO$A!DJ00a6YD;lgH^@%tbYtG!V=P?`qVX*EV24IN=k zUcgD<&l?f|H1t;h3Yp4(xYtC>NVR?v@$YQ@MT_;)qSpb+A zB4ppDKsQ(me6osY5r0Z2$!qRr=QIa&aWiUUF{Y_J#dk4L8Z6=!)VMKN10O=A;M{4x z32anWf_fR34FqHO9?CQCod+&hI8>7leAZ;BgZ6>XFrs_&wP&D02%^jqAM5oD;~@@~ zy%pJ+xFLk0g{ffCLr`mW>%*szf8<5X19pV?T*a6!2TmTGOsBW%kv zkHAs2_OwuYx`FG$sMHzt1~!4MIhn7oGzP>@W%0dfO%4BkUTF0+OvCws(c?+>x-O4h z1Xsk@I}!zCo0EEInW`*byB+}-wexmx@82OZ&`^m9r?wN&KPXl%&~@B9Y>7+Yg&wp^Q2)VlU=|AEmq{$e!7XKlCdX8$!LU*na{@V3=>v9PA|S;OB%_O7|QbE*U~x;bDN<_dg)FQ)>#Hv-x(pU zav8&;B9gHSf93gkVi7T!Kf^!_E&3u&q{@P0h{`fu$Hrjmm9KQsgF7<7vN#g)t^`<7 zi$>~0LPO`iTnw0uec-|l<(tL0``-)#`v)($6|JZ?;57BPHMX%e@yPLDy5J#zm=HyS zioNBL(m|r@RJ`0aSL6^|5&=GznI;S!F$!4ejNl$&H-fUcKw|aDQh!?ky=agfiD`ro z#CT+&u9l(uxl|#^NS@fxCzBDz-m@1}sAD3{+_&#UtaA)tN`$gE;E}*$zbD-?ssp9; zvdQj0JIw(V{ihDSCi)XvijsLRB&hA+7Ir-b@Z&&A^16g9PB?!N)PzH$hIa@h2AJ0P z5gb$}+94Syf>eMxAo(i!&_DT+-e`)6^Di8uhnSv4i~Rb#?CLwwwa8&2HzY&@1QEw?Kj=yJx7u_=M+k(q!E#yvD{wTE1C1xp z^ZO|k5SCEPsSwc+eYd|h_DTKUvYF(Y5Tor%5HP{}z<+27qmraXOqoOop&yJwo4^YS z_`Wi7O8Xr}X{{zWxJ>{exXi`=iFc_vi2WmmPg%{*PVl zKXDi!{x1&G>_1QNBG2g-tv_?!N$ zV&{K$@gMr9{_#8PzwCx4v#<{TrGMZY|Hhe#Npiq>W>kr-hr|SzDH7y>*p_#WWd}%M zdd;43bX+({a#w}g@VNwe>SNi0VYk;oPsZfRDR<)dLF($ro5C)-rq-E@GqjSX{+8rl z&fO;kwSEOE_qz%5Qld^<#udV>MNRNxhKX;KWpdLeSij~rUIrr$$;LaL_loroeyC;X z{6gOz@foT$+a~F8JriqW(%@UtP&+)k!^osO6J6H)?m%h*+Z>`TT6oWgcS*CUG_SOd z))2C(!b9v=l~-lV|{pmhU-Hn_M+zk=p9|_rBGe&yhD#n5Ot#xBru*25N zLF7@iIiJloaI&fTx}ZdK@d^20Z~~sX;F7%(zoyTOA^3ergM`t%UtOqkki7BiJa*&e z1INizC8y&IC7-VE_L|a~0G#GM70FRD%RHaqbiN{)PD~QP=i6476q58b64uQrv2h8{ zm{(atqi9*DqkrEGMaQz)xRyJ!=qUD3z;ABo%Du7H-kKd^h`#Uev>ttqV*xKj!ZKN; zY9_YP=AJh*mTo=DcFvtdZW&?38!~^+h%*?PJ?bGq9`+A|iEOxTX9DMDnTgca*gb60 z+-tR-6P*}tz~26@5Pfxe=|1Y=mNvgUk3LqryP7CF=H6hGcp4Up?f{;O|JLW}_&tqc zhSRS9eES(^sW2!EWd8@of@Hjt_sh=z%N@i&={tYVY5jX1vRrZS{g-(N5dS+5VV9yK z+pz)wsC~a-&xE2f@mmtH{b&&^uVLv=n~3jeG`FJyn<+{}DA0%sm5AZ69XjzEXO@!$ z`W|5MeD}Ng!LkM*U41@X{XL@fpWOeCde~q7`28>bNW(~g{4aFDUH_%aWA%K)KxIt| z8|t^Sj={gBhmA11Mv7oCcbz6mVx_uo zv;}AV3+LHs&|~edT<~^uTW7@7_Nk)8y;*vMEZ_ZtGFiV125n?_n8W)*A~>9#n6UlG zDUQT4YVx(YzU(K)Dyt=>`I%|Nfz|$SOkF~YDY$M8o1*i%xvE(4&QXI##*L#l%RnJl ze`f*WWarbFRggf+S+DmNd{U*MIM9|;t{E{2xUm?iMnh7oY?3?MMCWjJ3G!dkhJc4U zh&f*Ch}?L;cE;3b#61xa zu#3UzY=$Vq`S)gTX|NZ}p#UbZOE1EtP)X!4rHjF#A_N}|x{epL*dR)fW865~{2loE z`>FUyQ|M3w%2!9RcJ9Vtr!%-LOa&#=9LF~u=d5{cDo(RfPp{x3M|k#YA{loRagv8y zNXBTk8LF2^UZ}4f^=y1%`;{KD?Bn0z)Z=xmp~g|{Z*8+o#7SbemkrC*OKxr75|i7Q zNg4%70=%A^hHE7cFB@!^d&6R}a%pL5Yi{sSopmF46wy+`jQs3Y-))sii|3GwP8(|aAHH!nI_gUd*dg!0sz5y$D z@IH#ZVc|=-!hA;{_flo>)j3+88{5M2uvr9s3~C|m{U0;`$#UDV+2)nrO@3Vpi3NRE z*YI0gznW$g1Bl$!ou?+td$xlspJkM@Vk*{vAZt!=MQ1zNa9IP}-T zC5f#h-bJxyJY2D{NHAX=&02l)oq1K5uq1=yHCB-RI^h5tO9X4D!*f%PaW%1gJSmpN z6=<%RvUjt+T;263A4h8I0Q$6=uh{HG{O?^~@M12dQ{~92`?xhe6|iEMiV=G1L2}1y z%Ag?>xOEoeJe}jUz9-G4+?X(!Z4;CN`+CBcMmL+65EWb6sIH0fTE5{t0gvVZn%k2IX& zR$T?b_w)dM?}BlVI+gP@DW9d3C)oAfpoul8fom<6Y)+|HNyNM$IgDH``2!v5|~gN)q0iRvc7lpN#D0 zv3c7Vn=or4%(UME7$*f?gvt#!J2 zjPL&TM2NOD4bM)x*y(7kknaBMp8Q7&a{#528uKxT?bcSkh70AeL>9_~7PhZ5jy6Q@ z@4Rdm{zj{5@}&qHA=iF=XV8k!=+ zx&S%4i$Pms8w(ZJg9&wSTTJou(Hc5Pp3!g7EKx?Ub>b`TGiSZALbV@4Lm8!^EMCje zT99G&DyPV<3B>!g z^Wu^KUQK*i9T?dyv#OBRmyDoF=BkgUNo{6>kf*QA6#O_ci)`QZCO^Q=}TBX+pN{q_~QRc7h);v zRLU|jEWdT|w5abRge;PVYRX(LUGyHiN@$2EWz@fxbnc*=D8}w_Fn( z4SL@fye&qTGv~^HF5i`APV?TprYyI$awL1x*RGAayAO6t>hevrKXTgZzSP;X zeN3{h{k6ourO$4zz(RYzBE8fPMyRsaIM94<`WQH%5TGrp>wK%0??k74v^(?b7H5}U z?MD@yCD8pQoW#Z28)18X*ZD?m`^nlSVS9O3W4cd%5zC94Gmx;={+xGn&kD!4oeFf3 zWzTi6T>C%e|4y0!3ES<@?>lymT724lfrJqs^|#7hlYQEaK)|JDox|nYN4FOOKJ+cS zOcT)VTBY-urcZk!kTBRjY;QU6$t@p9Sa07vU)%q1Zb-n#zJ&~`g}C{j1xLkT+}BPS$q#++=+DJV17p_F)&xws+?=1ntpXgw-Zo zXKNxnZi-!mVJ6K}&H1ipMZSFcAiL%NNos@aR-5zP&ZvCby@7fO_L4ixwzucQgzY?A z7a1l?zt%RK&(eI_oq>AE_U@Cl);H&jyl#YDg(lwD=Ou*g(pwiLCNB>Rglh@*$IDqh zGNAi?9o{DDt=U?ErzGI{NHgE@vg_l&QZ6VLtHkcI!&9~)ET>JK-no|jr@=%Ef_PE;)^Zc+G;D-q@>S^1$uw8hEeA(@-x4)K6eEdeT zJ7kSt;jR;qf$wqYFwDgFUbAXRn(bF#dAZRhQNGhxedvx0nWr?mB*Z^}lm}_e;HV9C zHBixrm2N<%Nesf-yh_tgd(r>CnyeU&~xFt_nDd_4MGeHyu9nxh>BXq34&Bs zP`MX%mic78M~uLBP(J=pY_K6bQzWa(5h3InUxgQekOS~s*wMX^0jQ*D= zgx`$)-i7O6bEPy$!2b^>U#gsRticr79r}!vO z$7VK|Gv5+D_L!>{)yZi%%zH8wZ{!e1lN3uo!%|>f%NU|Ad9MkI2UbUMYzTZHLe>p@ zN(5-9v*Us0m-jE5lQsofN@=u@P_klu$C98=!8D|Ji0}qi4TMBQSCpbRuTA67)joH4$xjz4G-&NW^gyO7b8&A?H3{^&+q?97pApQQM4xP9 zYgU;v`!Rib*V42yDBx2!b@CO*8Y#1oio+Z}y@S>JF3rR_f9!ROXy;i;w%NL6+Ono& zegO9~l=9F0G>jAZBS}Y86}qqWcBM;YcMX$4Z0G}+NVT<3Wsvk#h8BV{IvDbGW}%4k z=0##EutNv+w;lnvNAx#I0NUq_99oeZ%$lV2Q!9uFj-X7Ma9W9;NJBbg3NTGWei;OG zbWJQxNR#6IEj;GDL%35Lzi)jvq(fvz%q&=Awm~H(?5eiD!obG)r9b^zDC#9FlB(fu?mtD|-}FD}^DrO9F#nQ!1IikIulPs1 znft%>dEZF}@D2=65!TPitPZB6GX31K%q?SummWrVQg#xkzyJD6_)iPKKgjQY_v5es7#ZfCkpI>X&42epZ;}P6 zhZzxS#(I9@8CSI5A{Yb^?ZKtL+{kO<>N>7!#8y<>ur-Shz)x{*;{%9^nE}gqAzQrF zqAw0~+)>zGN>h=f(Hv>WC^m%6E;_eRP)2^zuwH$h|9^Ns`Ug7yo=-#hm!F%425`dv zMyJVNI%%dB;%kutm{B26em0_#6^!;=1YFKCqbn?vkU>FFCnrTEz_29@AUI8mD1Wt# zux|G{OD{l6Iq>kbHBTc)1$5J0!uI^qJFl{RKX%JbsP>8J(Hg&8ozz0aZ4-P1bX#~p z#xXGkf6(xsWBWJz4|F2~0AQH^nkV>9Fex8({?9!5U;aHvOr(_M001va03hI_;ivbH z?+;_FD+>T{q6+}51EBmog^-#v7U-MnFU9*tGFHs1@HkDZbR+ zSLwNyO?G|?hlzAn*wFUwT+%;X6MvlQm(1>Rd;g_FEF{DO5??aeDuxPx>3%v*UyAv4 z)oie_UG8qT?LnRZ*&G8&>~oFM0C*hj)QQ>hILFg(^@VgrekA~rM-V(2dk1Am26L)yK&!GdhRg*EYIvy2NE#UM#3IsN~Pyr4A7qG&zzEWg$H6*U2h|-e{u%d;e za6BGX2R*CQ;hE}&VQwpKX#KWn!ZcX0;xTT~F!QxPS&X+P4j_0!XLpa*WOUy0e5X=k z4lZDjrbRkM8LeZR^U>skxnH-6OD9<&Z|wy@JiJ2~(A?=fo=YASPP6M*_DH7Op6{6A>mVxnQ%OC6> ztn*-fX_3V*GLk>k^oCfNVq8Im=$PFyLP={$*r&Do+=;^(zyW@Mhwx3#=r^5AreEbZ zj-rx`^80Q-Sr?($Y$f@QhkiwLjB~elg|%!v2kGAJ%}#!i*%NMwJyUf5IT*>Eqj@X} zlqZB`n6t9oe}pqkRBK*i$bjKdH^tf?k-W^#$mZite`V8H2H&6h2#2x6H`ofk8wza? zbnAe61T41*B+7^4t$QKD`u}-78_}}f>ulwK4M3TjZ zzb-IRHXsbo68^x5qGyUhA@+Tq2(ATXcU%#DxP1&*&!+Tx@As!XyQ<{M?jh_(E&*Iv ziW|dN#3V#jA1<3X``{QJBGHvT0pm6x&gho&`Cw??wC*~aDA&PGXqWR(0W16G9_w4K z+pt_iM7bL^v^yHu7z@b4C>BCPL@-KjS@{JP$fe~10eVp0E`$M-&Y0Og@fcQrD<1~f z`N(tZDb2ganPkOW^t}fIGO3$%mh7hEDDRIL0lJ8k0OOWW1uooJsC(GX-^n zk455LBu)fFFR$uBus-g#Hj&k45Tap=~b!%~Bhr3o}8L89VGeB3o$` z!^=av+zoNRte!ph^qsxhX?@HVU9U7|PveKc*Ty(gcf;6IGy7z(*0W)lL^woc=d;>O z`xNTm>I`#{>_jx9`8-)PRO&3RK9yBp@7pJEvKf0)X)};`>flXD zpRjZ$dnk`n@Ts+;CCf4POSN4&`_IJFkDG{zD&8x^Ha`9J$B`>YS{+_lX{v7QNPH& zlMW}SB0V%xBgv`XfC{S&2Pid)`JQ4ktB5VOP}Fn`nYr3m_B1`IBxt|F9OnhU@sJ$>mr-DS5z&C`|gIfRDFiPaXu{IJp z`PLnghvS{D*{KOCToq6xu$@)O|B8I+$_?;1R1jjFvJ~mp4SttAyK47;e*(S0PTKjv z_Q5-EOn;l~)R=qSL7ptg7PuBlffb z<1+~v&?4CR2e%C)`4<0zPw^!qzYM=8kr|%%=KL(&18lYJ>qcQ>BS9s59@9Lb7{xf@ zZ3{tsi?-%Bfci%yGlAUj0Ef9t<{=y*tZigd4DL}wRxTEyG!hbCDGYJjjuPHS6{FuK zN9cpe%sVtPm;g@DNDLVj%FE{Xh=innIu7+9>5KUx_wy)*p`<}_ z)EAB7?b5#27e;vn{dwW|R+akOAAp|YktinQ)9u6n3KJ68ly~3HSC<=0(0G_UZ2$L%~8Y*Y5gFKtALJ9!cwpw7>TqDR~gQTKkp zx-Q5_)h$0|Odzu{sl&B`2oW^ZgLHAwnp6&mo@&E0n$iSK8@~}!MQQJc#O~TuBgjX# zg)#S9qs6C1xkO(W3f4H}#Z{LYb1in(6;&94qmGl9RhJFMxtTg4W-kP@f$3XHGPa^6 z5TK=p$qKL;Bxb^RD~2{tLKBMf=jZ%Uz4ai(kfgFxcA!^C>F|Ka#Y9=14#vikR}TJZ z#I1}E1{UsRX^{>yf;MFXP;>rJ&{=`{h;e_&ZZ;S2S&)~=uz7#t#;A=avJ(V9NfJaQ z;KUJ3p`mRpO*_zS#Jy$fsKIxTM_TQ1Fr!*8u<9d-TK$m8&*uoA-w=s@NYP59X~DY4 z0lJzZo)xvgvPZ^MI};vzt9|0+3S`U{X=5`SMGDm^C7M7EsDzkHxaVcZ2$ zMO9XN0lP5{7*8&xtnK<}uo088OCv4$NnC!9E(@xQ;CiqUNIDgQ759aWskC>>W&HM5 zGvAhDP`s)YXegl1rX+xu;=GTWS)9Va-`Y1&hABP@?nTKN0WYauCLD@6i_?Y%s&kRL zd$c?QovC#g2Xl0b4_tb2#+8SRH+cY!7b2r}e@Lp}W56h^It>RcM~*7(v+uze7h5Q8 zC{jYzZP+E;ef@((&r4gKKO7)1MBCg@iT$ZYawztT(cq{(QQ++bYTV$Z`K&;Ux~p7$ zufdzNF5d?D@&#DCzNoW(!gl||=947|e;uXz4%vL`dFLJd{&5Qoz&0?VYqtBn>@V{C zk466fzi_DBzj5fij!X=pyH0{Im5W`AU#A=9u z`vJmTDIm=zLd8wVb1Q;ODDaKwpiL!5JouN`=9*7yN+h$(s=AtA{S&FOA}cAW(~-vV(#B zlii_$>onUD_Y}9AG`@HSgB6K=CN#`cPCc|updrEduN1LNG$#qE#-UU>3+%=+_`!~0 zCG5NtT_NKfn|A#fd(6{%KkA*6X%Pq=Ez_@Nj_u<}ahlk1j)tERUhOLIXj)Z4-%eO& z^o3QS(aeU+UZTZSl|b(|<=S22zB1_cL>pHEIcKs9GTw`GkT1D;pk*Xr+hV9Z1bYFb;{(XMh;QW8pTn4xUHpLd0A*9|vJXDr`7Iin7_`40Gva@)Am zB?78A>N^n|%_)O}rSFWbi6DQmDUMMvmd z+J_n|BdvV$WN4nKObcRW$=oDY*1dsEf4pV zRne`jPHS3rrpAVzmkw!1ieNmvpsn|N3h52Ows+L-&Uc3-BO*b+_r|S`t9&7F2S^9c zqSI$XVwj#r04Ez<=6Al9oP}=ysE0u!$Cr(;vS;I$g)I%=d+OJP4};=FGm#IS>;55= zcFSA0!v$Q%OHNBxpCy9(uk^=}hqq{^b&n@bK+_knkIgTZ@Y70Qy!P`lOO8HHStco-nR(s1#r&fR+pUzZ7lb&=RqlWswl8Zx2<-6($KwcQH+~-_jqAS zZU|i2KJa3jF#8XLEE05gv*;1zqgDf&asrzWuP7^+qmQOS?%!+$qOccG^4e}bni7Dh zDGM7keRm#*T9w5q(sUzfLe`H1-;=uO4wU4SPP5~UT?fs~cyv_XV zPVZ9Tbi172Y-N7ECLw39uV@%E?Ht^J9fFwGHpg-w9`gpjjULc1IvLr}Rb!>c1=C$}kZPtg#BKo^{9vvqp95BOX{W}Vi2d%jZJKyo?0V+Ve|&f$4- zVloBnLo_B(dM7O1XQUSC4Qa%Q488wz~?w~ zY=dGi3g-BtZCQ#iXcKG5DXV;xqSZ*jUPbdq05L1|mu8EI!~@Kk661?6G719FPv#t_ zQx!w4&#dcnq(us!i?ZY=mmend!AA2Zf^}AGy7VRssfYQ)EL1oV_1=!%mAAkW;&c%T z*27^u$x#RK^4X*0Tl!kbI4?l#rY5FvI{ZDZxDkddF%`ILFJYmhGQVc|S0g2)^o^pV zVXQuGmooMBIPjKFdDNeJ<$p&LIz$7}H)+1}p)X-OOyGJG6elA6c&zwj5+lf(M-+dF zyF6c+_MIR)Khe{yhR`G?RXjn;QJX`M=#(Z@Dzu^Q^PsjiC0cqO)G~oB?M7tuXDL=p znwr=mdUd6+1`=+4uRZwB+B{KWO~;9_@IW;0jH>-2b~93Qa%#Tq{Limggjk7bZ16ng z(AKUT`iV)B-BiXgtPKGl`>%!Yjbc3QX$&YzH$LEOhE8;B2{BAPc*Cp>B;23p%**1d zB>T5Frh0ehZ1uCNiFBbkCjSd~P=*d|*|CGk5nrWBLsIpLCI^we(MWy9;Zl#rYtVa?IxTOicVVc9f z@_=||K{1n$iZDtGU{>N-afTVjkQGN#8x-f-%EB%p1)~pX$7@31tHHYBebC|IuDSz# z9f7e9u{C+W?X*{K^U~3?PMW`z#K--73;0UHAjDVo|v2sycvA< zkZpmyZ|N!F!>1H&fYw z>rPH1delp$GpfpwyduL47=H#jpGY-6ynHBt70pK81m{cuO{m~nWk7`VttpCo zi%R`o!!wr~)@WjUru}vY)Z1n8%#vKzq+DR}iFxtAw6IQHL%ReJgU#1FFy^+Psgx{v zCIc47UmqjB$VArae*b82j%L|RI9ZjOb*ljdH4hi4R?b=v1_LzOliXK9mb=Gz^O^Mf zI`D%$st%V0{oNJ;BPBi-2IB^bv?RCFT65GW_$RF9CtaIdGLbm`VNx`wU9syG=i6bW zf&f%GiDhhIM0^U(!a|aUcWW^U6dq}=lzyyI(w72%h0-^vy zD4I6mAgBb>LxR&Ax@3Z27)l7wj$D*O>6=SIYbt)&mtr8nM3gfj!`V-?HcYMWz(7sB z9836RxQLVknJ!W%3PW|{-(@NNyB%Pb6{9InGcPEo;GaJl{DT?TPKAkzDjzyBy#-W zg}Wy;tpdH5qR9|#!rg~eGAkvyhmK2_FpNfRK7xi-K9u~aDu-~?rkNIwqx!erSkCtMc-cN+w$H!3_xi_b850>~Bn_6t1r;;i_h+u{s>NS(n{D$R+L2*`tLZ5PqCOn|3&8SpuAIy7Uo-@MTJ zab;&>ZeLu%9Vj(4wte5aV6_1mUjYClNhcMc0{U)eq|(@>6#xKq2~oH!V<|#x8d4%e z7PfeH; zzsrO^N)LN$?W`fn#FGnr3Rv&jG*(I?jweS74*S0tdkd&Io~_Y$aQ9$A2MO-(?!n#N zH3Zke3C`de2=498D|9t1Z`+e`8yVmQ~)2q9xyH{7&?CPq$f3^2C-7sOQ zLCSBuSZQMRjPZtF)QB>-7e%-2>kd_b!`0p}EC3yt8o`&X4b}3on0tNGZY?(8xkgQ< z=bYEc?@kR89>2kW2VeI_1vk5q{uufXIZ%}(5#1d@S$GckXA%`dkT?I!ODD5_XB+95 zMGEq_X<%KjnGF^R!ef?!wwQ^BRXj5t7XF|7IRqaCP$;s@z=7GhG+^pv!1y4)V_r)? znVV+paKIQL2kxuCQkH?B0pL(N+w67%ttpl=NX!pl9-Sw#=0XnosI~t&VEMn)bNIjN z8N*DW;{Q_5P{IE-206q zM5I}%xetY@{=g*0WQ7Mt2m!M@2zU9U6bU{-W_QFL;9E44Y&0xvJWgyR=dZ7?pENp( z|3(WWUfWz*c~S+pcXj#8&Fn=-NBb`>F8bHM5}nlPprWD{Ry268uCDT7$z*&iXbTGq zolPCK&lqy`UibI+Z*lclX`aTsSq6>1aQLs)L}{LUc7x2whH_p#wYTJKVqnpkZs$ZJ zVd)BRNE{ep_-n8lripj2PNI>hs5E>WIwmAVa5T_o;v*Mwj1C(i*Q`f|exi1Nuycwi zX0wdbwGM})^ur5fV)4E>1`Ee~k6de*?!2fxCWirS${!W|0{o?J;;|Qg+Y_YQI z>3D7VXLd*Cy1%E(Z7`({L)VL&>O23-v%3sm!dN@AfdBo>>_M2fqs8NhDSlAW#T+@C zqoQ3{!O^xdF|YOYy2ZwoWXq2jCc}F3gJ1?3sZevEhSk6YGGB5zC2(g`EA<=!|AMfo zVrUnype^p|6@79SFBAS~aMvHf`d65mO!(NaV@WW(wxm>2@RC$AB&7r-F}P zx7KGo??`r6J~Q2@j;ykeR}UN}%yRizi$f^~?!^(vA8`|)lw&v*mWBbE4u4ib0jdWd z{yo78o|@3Nt@tSQMkyb`91-%y6Hl`vUESgzrysCN5nO9Q=6Q z0glTt! zg3-r}42`=51w*TCUJTuk>$V12B7OiuwuAdj-qr(IH|Up1(CwF*al^7H0tQeVAp`{k z5IcMXH^7agW&(v@Unf>T<=d^JI08bs6gjyp)`=Q&f9<=L5alp7c*{eT4Y%qxUXkkF zR69ciCn3q4uxk-D7ag3934-2`9qaUEkD7-%{tp)=|DnBN|0v4Kzskkk7smR(%k@9L zOIU{g)n2XZ%U4khs|y@hw0o`3ek}Gi!cmmF0mi?>mb!bd2O1?IwRcF2%o>MG`bmtS z{2_jjfckq0g87M;!8J=j2);VJSau_N-QLvmwCp#pq_l5nk>Nv8Awj{pNPxhhMoM-h3JL@cRB6n(7h$l{39&-mNC+K7xLLdsJO$Ke%@%s1xUZOG z)%M!5rId;44s=F#+M?iAgg6itq?dG!a-pycgfKifaE%0^*{Q@)MfjXE#x(8|!7GsjTHGBA!a*cJRpRZon5?@m-Z>X-?hSX00EkhVmHYzA<7fAC z^g!+nUY=a7FnGZ=whjG!5KqWTMRdkhI)DNSfCS_hg-7!)ks&xwR5}ty$TAMEslw5>jXYL~F>Imdz!`q45&Yz&AEx4rW zR<~c;hd+s)FHUe~=wgwAx!NkdJ?oa)5rztE3F=^SY%ScNfFJWvU1xYq+gTu-w_5WF z@^85L089%GtI|4ON*OeKku5Y<(EV+qh$}vjY`zdcfd;c^0OmX2be=`m8+^P zjCoPfyde${)bAKN4Y@OKywx%1#FQK|z9vyl56y9LX<11@D6&@SdlSsj9gTOabrULx zf^GI-ON#{xQg<}{MFu-+z>@ShYM48C0+BRL+v&l`!bVLrS>B>Nt#@Eu8-Jzei1KGW zg{N0(q`44tGQ;P)n&5}?08w?=<((XPkL&oBH2Ua~YH>)g=l65vs<_LX=- zcrV(6GlM!pK9}gx#-1@*1mk$Y;zJ;y<+*NY)PQMmQM=6ow$4U(-aW-yOp}5f{Dp=e zMs@2u`*ExfiOg5gUp5HaV7JRLqw7o>0Y_l~^$#r7V#2^|l@1pKx_yN8xp)G-k^Y3> zGz^d^_K&tAnEbxz?VD?>c4%fWRt9|9z!Ie%QyJZnaNp0AlLgsPTfbjoiS&Abj0~X5 zBhVp!2Sw~l_S&PM96Y$&Ge0b$J&Ui3D)V$~wOFFTg2k|Ps=8a4C&&GwfbCgE{(J_v}T$ zSLiu^C%cl@JstgLmAgz(X69#^5Pk&T-?hkNc{#NqB>-Rw>B1+**+;A`oGj8G6b*~U zQg}+rEy^>g{w_+aSfEGPVFo!J_SEl@IMI7+Sl%!}ci#(mA?N{`apJ=O`G(VgU9AH# zRj8Xbm0O*G)5k2xdQCg-Pvw!~whiV5o&_I9>au5sXv<@0m1CuvGYDZc*7I6HA_qK8 z!k)dlMa1rji~2ty^)}oRji7+j910)=9)-O-1d);s6sgd{p$>;46rUA&I@A|;y@weB z>3x-A%6gbf3O=}F017Yob=l@3VNetlQ);2&ewGt=_QFZfkwk+aax|aNj*gDz#N{;) zlroW5PE!SM$MZ|m(ef1SwGe5*Xut(R5nv<4uR%6n@*mhSOnhs^KcC50H%gJ;w`Xcn zxtnLSs;EJOB?ECCCR5q zAnVB?&eg(ftgC0-4FUz_RkVuZ4{q#D=6JWL3oD&U;R zjVp_U`ZWt?4a?FrnPyXRgy2mC0DFuniD^3?R`ojZe#FZ5)YX{T0%o0Q!4BCMUz_!* zj$fQA@j589g%5)F8;(uiX*>uAJ1?FisdhZ#+nO6w@>PzS87QQ{)sK3k?4q;fmDk(o zIW$hPacR&}Z*cI8ayfaR-NIbZF zSgQFEY+rCAQj8NMQ5)*lg1vIk;{#0o{Aoua$0K$fttYe_K`cCivURPNo^)|L6bMah z@!^%bWbOH)>%Fec{lX8u(y$8woNd!Lhg=LIU&e6qTC9A?^sqeSwdKl5# zFHMyOxB6)v2EbAVwv?d}MHoe;9%jR7HNzWZj>(G)1HK3P&J_MDy}%NneHQQgt%|xqmNl2%gR7qgvTIPJOwLb0bpX&dZB5`m67$#C9AbY*ei9f1%CV+ zq&LeUlJHp|tY<>luw_>2fm?*un5LT93nbt1%an_@T7FkB?t1+u-4dw-%~0r!a{g8j zCRx8|LZp_2DKKk5A{$>P88H6)tqj!oszn@8`^#CEB-F4T(F$+J60jzV=?pEq>PPrq zr7ir;=eL?FG7ydLUNB}{wwUCPSV60($tpB)L%Fl>EgUrCSUD0PdRKbOq0L}|WKa2p zu~|4SkE4|s0f0O~B@M!p#v6u+u9SiV@IovqK9*dv-3{IW!>_uLcv4 zPRau6ZDqq$qw=P$rY=8bD3`t=x%~|Gbv5o}h1mMk-^K!Hi zBdCxv;Nk7#=Z;rOfxpZoc1N&w)J)$=gHdWsbpk0MMjBeCXi2GBW%fkV&5e=gR z$m5CIOqJ4+`;#dta!2vBvKP4GGAy#zUJ}{GvZL1PQTAHs>Q*(P;amKwUfjQP}uoG2yFx8cW6^GA-@xjoM5mc4z)%+g=_1b$x5fHGx9kno13LWn;}0c z6T(`VtTGJdI>g#H*@>n9H2*nlJ&Jh@inGjDmOKU8Pr}zha8cs*`lbWhO0rsItE7Dcndh(SPqovmJ}7-gv#Q@#e`yxQVUM&-I8E>w@ye6`J-fvbO!WmC|G zTj+3=(V1rAdW_7ye9d^ROHiPHf&?#_uuP8q6#M|Ivc1VmhPX zi^0~fb28*o+q1z!qeuD1p1G}-2ZsVtYcA*z?gW?^8Pj3rVofi6g>XN2Ts&^|1i3+= zh+X(92FHcobzDpv>aolDHuiCQYzA3cA}`XTUbrtFp%JqWH@?66zeMX2yfqE5M5A@g z-K}n0zDN3_bY1u3Ky-NQzu$!{3O)Dcxxc|QyGHsvpEbQBb}#y$90nkp>;FTqHNRbtOEu*%l1eKLsfRu;mS-Qoyl3jLf@iS z#sotnZ#da|%kMSXwK(fQjqFt5f;rHvuAND}nhk+TL5y=w^OpUgr-9*`gP~TGvJDeL`te{;&aa7HLP;u1kg^Dh+Z$o1R(^XL;7~vK;Rmh}q%Ju(T z+Z_5lO^6Ds2eV%0WGmG|ln zcz0HOF=&-hBRo?)RdFe%Cy~AtUM(IW?Sw}}Rcc1AaqXf86FrQ6fuND|Iua@#%Bz=5 zNOvo>4W`;t0`0~OwFXL?4lZt?5d}Uhp1nalt(LB!?GH1nzfi*n!r@D*>e8MkZQF|9 z*KB1zOtR+Yq6JFsqOE5IWBb+VC*9}NXgd;Ab>3Fit@ajE;+eD~9NzsHy;n}vg9rm`BQtbIa0@Ea=*%HJ0V6{@8;v90ih z1z^RL5r!yup6F7hWRme&mV&v=er}wMtMizX;^&Z7HZL^ncn_+%ea#$@D4iJLoai&v zPD;s}7QwF{{0uKTce_D^cH9!s_AH~o!0$%?>Sn%koN5|Ry38wICV6S}iN0>2gVVxV z-NE!-eZ)xP0{`t36Q8+I3)UXGVu_vx7vB{62r0K6@NgMUK>#lBEvkO#L~>!#0Pccn zxP)BBD&?+_(&9dUphI!g-Jq9_!TtNe2#;P@=m|7WK_6>M85hlB0R6qu=kQ`nV)3ynx#6Yd zXsh)pJ>aIwa#?NRv*SYA?v+`B%+#fgc(&PUZcnYBxv_|YvM_LufVj-d*iOcemfY8> z$I{$q=6HBRvtP>Bl={+r4YAh)x>Pa(PF15UoQ7bzSo$T&x7`$c!B<-v5fn~Wx ze6_l#Ec`frd|1hvXzX=Np>^Q$`}XU&bJk6U%agEVuwy>C)Q(J3r{kDz>y!qa)l93a z^X=Cz9y>`<_U~QQe&fj+EQvklR%5H1LDxNVJx}AUziXLk6Q3SaiU;+VhEqn$S@ zQ*93{m}ppkcmVI@hB& zR71MUQZ_fI5n}Vp!Sd`I@yHgi=UGn$lF+qA3c)$f!}>DuC%4< zi(vD~bFI@tLPoiXYxN%4!k55qj(y)^XB*6~W`lR97FEa@cHyIv7uB%3dbZe#%3Z@` zMGo zxo(2VsfVaMM~iwAx3ZF!644+TqqXH%MG)!YMxF?o-xGIz{xy=9eT^yb-b)9-}`9uHq-z^OPL0|WempYGs>FcBkb-sQa{F}@FANo3^ zum83$q_0MrExHbLIaV|%s=H6hCrgSpqSuo1Bui40nk7J|K}!I8SP=q{DI7hoP2WO* z{-B@8q5RN7A?PQR=wg^AFt_MK(ME|{1Gs;fYwSj6th^+T<>r@deLcC=^RnaZsL*WM zypMxsi`>Pq4>V6|7vD+)qB&Qr^8WMY$v;90m+5W1%lGMJ;m;Ao4msc)=!x2m4>$|H zJdHi7I^DmVxp?0%>U<&|>Uw(i_cG4dG3|SV>wL4FF8JR|x(24Bw@u=pd@owikMFdK(jUy(=}XVQzC{sP4MpZ{J=z>FFf7-;z4_KVSUWb@`Nm*7

    ^DciagbXM>PB6Zkq9X2iXAARxvxIv(cSqy7570uTNBPZ~(^tKQbWi-eSQ$dW zcW(Q>(qMF9+=4r0j6SL*u-RRM_H^I0$@3D))N$ACYf19$7(?bpH=cqg!G#IXSFC-0 z+U(db{nHh>Zo+uMT$jjXq&$yShS;0EW5js>6IA0K;ip4CZT$fJg+o%c=EG;q+8@eoLk<@H%0&}?S| zV$f#Rxnoc>c=nH`(3v^BxKDEmyp61SHcaQK7xgYAF##0g)eXJ@IP3creL7MEya)E; zcCK1-&~1b;8owSyg9V+sHxQD0wvj(Sq2nDgL!(xRz>|<2J0aH-gB^BS?IB3HfBp<= ziV2TdC>-s`)0PtN73kv^k&B}|f(oOMnW7&P=pY2b&E(>wYIoB!d&OZ4v7GO=+KYhk z_W7I?C0y7q_NVuGbVIgko)Ys!eJe0mTq zBs97A#M0o>3;&Dfh(nyd)Qg3^@Lbo&DV7XZ@lQH(^~p}}TR=9HokKh+sf*BlveeOT zXXGf;K5kgA*yGWG4RYeH+v)kCC&v8zJAgrp_bd9wfE^3jFY-|3I=t}%q8sDiJyRSR zuE=7!4Rb8Q&L}NKcTz#p*zBZ8`0 z{={eqB!8k7Mu3z7C;t+0l55s6$CghhQ`5rKPLYP_aZtX0CL|+nq!5?pPf@MB6H zDyghgZO<}fsdsUq3u*nKsh$YMmTO_|&n^WiM7le%)S zlqMqIOqd5LhBhcd09za%8qVpCdNC`m3fm?|bVNy-PFpej7d-^Fbgpc=Wa|!RJ|QM0 z2DNIE7#R|3V$BG1(vs~3T#LdYiJE#4o(i^BNG-S~4l^EW_gj>+5M#PJ><>s}bZu67 z4EAK?PY^F#sFl&2ohJkC>whZ=HeGkx9DEj|FIunkx&ECfB)5sZ*~a@=*~k3h(-@z8 zWr_uvh~+l3!8!8x2ZpiOH(l3i%JTV%wOS8$z})B*We2aExFOR=^NoE|z0HxZcSURZ z%jUfAoE>Lxn0REtq(zDG;kv#RgKveg+&Y&Rs+K*v&#Wm0yAYrJ4o?Vz~ZCRIVP^trO&%dce2!d&?v2~>S6Huc z(1sc&zq&QZ9m>}WxmP%ShLIz@(5(YY9h9!UpT2>;?$6rzGm$nEsdb)*4A-*XGY7e?-y?0V6_s4Cdtg+>)~jvHHWFj1Eerh$h>*p_srkVxQ`!92UdH$#2bp zDG*n;(etrP+Tdamyn^2OgQbW*y0>dXMA#0TS3QKsheMDr$fBPpi$HKqR7vmEz@(Tz zE`yX0bl5J2Ru)PE>+~(g39Ownp36_n86Vg{Dlpl|`d zE}is^C>vE~BnN!@@RiMab`OYVo`K)J<)h|Zw}J^oWz+fWE{qC7{b~bFe!M@wL%1G@ z{(dmwiA?f@e)4pe0m$L?P9N3o}kw&rGn3VI3=&@6Pfb_=ntucArT0if2J z=fL{&eFSq>`|5o}xwM;gI`Cp)Q)pyu;$zN|Iz|JDQcXBm; z0N#&=ZwYyDVY+dem3lP?+1`~?C0ByPPl72 zrq>(XiKiYCeua%etjrEyf0E7galgL`ByZ;-n}3spc)jLo*=qid?QEQ{w!Z&CU=sd= zySd`Kl@a#LRPLn!1JLXA;feaY^zQS>^zCZdQqd>xN1f$xR@O74VJ9I|=ifi9g(3%} z3qK*p75H~Oc3`XP>h{w~Cw~fc32Fuw8F3x8wQ-MdyoOiL|9DXo*0|svaXk>C%R(G_ zm^;kMI%1#ORSeF@chVGhPN*!R&{q_ra9u1q(XR;^I%O;#Zp*y_L6a+ZQYc!trc?M| z4^zR()EWcE6kg147^F+(QW(c6J=?FN9baZtCtr@Sb1obNZl?r_a@!n)uHgZC{>N#S zUDZuZ4}(6BdntS%cR{zCv+sPd0wbh~eqIL6aEpeX67L-KO%R#=>p9UEUSPmSGuf)~ zv60De`d2e5z_apCLwcts@y`?X<1hWKECPZ*64)i2ciOU(&;P4wos2%0-MsUMV0NP_ zk9fZPu$lgk&iTjDf9RhpeI#T3tA7r+9^v?L@SpnUP+$J(pMUrzOl5JP;6j&pXHuDo zGKbe;Ahg>Zg1ZzUeB|v6L^JN5hK%un*t8(;TlyVW*!Je$ZGpxCuFjU>Jc?MFpO;uD z+uXfH2iU=J@~uiobosqBzaPy~*>g`c2?_axdp$hvSDw1X62#n`o!^XC8jxJ~jCFAl z9<1JFqH$c^p36MB_kHW6{JEhHx;SBft=n!E5A-nv3ILjyt@Mm$#IQYn&em^Q>2+6K zcaC%(u%B@f;sVwlJ6BrA`;5Iqn3#2&=6g3{V>JycA}N?W8SVUCLA{+S+RoXNP}CjN ztx-+(kiyY_$ui$i(yDfS#$|uM!*a>l+Qq?wd|WZUDYF&RbFfCDg|+gg{86kQ*;|b* z@?(tS|7-F?^-J6`?l9L48tJpt{xJXGtz(HXL@;VaB1e(^!*f~H;N3y!lImvN%T79* zoJ6Tnc9jgK*thz{6I29FsqjRTL$Wqj{44rJnr6HKFQ`M@ByW|tWLx(o6~|BkY7C6? zIQhzIUhWtt2yW4jxD@xiQl)C#NJU4Xa^Ix~5a?MG4ngF?e7_h#Wq(*ja{8s^EAzlH zRflXGDI(jJFDNGT9JeMWpANOGn3C%u$g!#`8skD+#2h@^bTXXy#yH~#VY{_$;%%0^ z0X?wckvf5xXkSoJtARtCV|%|I=@E|}QveF$ zQ9((gy*M`x>8SB81yR0vM&q1m%AA8|$k&>yPX#(9?X=xoMCfPXU$U9er`4qg$TILg zdRK)C;2QRBUmr*(n9tK{?ug&o-(RMVW$z+8YWjF^T4)Q^Wo8Z3$%V^CbjnFv=&R)s zQSzmAFn*aquo^9~lCC0_EtnYk@(I17I|22Kl11U7W!nNPjn$@-gmcwV7C>@%^BNDh z1R+iZ`T*ROem8VRc1WjyG0s>7?x~l2ksO)_mnvWLAotAzh|j?Q#C&8#ae|B=Mv#d; z;-n~r!}w;9nJ^SR%Tdesr(1TUJ*noCq*Ot5+uFjAECkv16B4C&ZeB0v&zpYlp3mAo zov&A;vHq`cgvj!blvCiO4>9`h!{Yy&-0A&G?jC1Z7yfT@hx_kwah8zcC*@E5lfE~} z`dXZ_=mf|=SSWD(pyUt{v5<}!%IjoM%E}6pP;Pgf=un!6%c+!Be}M3ziTJa# zva%uwfCt#w+gD6XOmuqJ*Wb49tPy2qX}h8x3zR^B;3*#zD!ol#Z-@iu=q@n;mW^|iIwOB?4G_FEpCt6_;NE|*qBjJD`0HzG+68TtKSir!9 z1T53A=-q25TCHz{1ga3y(G1?!g0)t#aaWYxU9=Y+8W5-lgf^^jw7?jy0lgp00Q0E6 zzw>U!y|%EIWIa(%TeO<0P!iloq1kkE5T7tSc$uXOQFAmy4j^p$7{9V_vuJd1_y76A zN(qMuz!T#(jbU-wswXTaBP=9{X0anPmGH3Ql=QfUmzxh5VD8O*kxZ}XsN_}&&_&pm z|Bgx_J`vE=iiAaGyTz~|96!Q?>xv~L`4>$*HC;Lh{yUa6y0Q9RlXJl5J#jcr7gF0T z_6&G(eghv{BI)q$%gV8U@__AzSPrKZj<|DE+|G6RV8&g>uW)aXu5qYl!AHUi!jh?E zA3xNWNh0ZoE9L-b zyJC0#&hZp&cpGqNW*_)5;hJ;RlUP~XqAPI@@-7_sqV#PI#;Koq_!CbTJW=ArYpfXO#y^X~wc;QPzXr2ifkN$1TV1Ju*D zV%7WG^XB_ol1hT zS-#R1F@SQ-!$@hqf}r)pHXy!6O9Evh049l_w!NT@$Tb)9V{go?rIl5pD8!uo0R>HK zzN==(Tg1p=beI28`JENptE-PzFI*)S+NAn{WQXfzV>eRT4C; zrvVO#ez0N*p9X@?=0EYrA#>zdS+Ep*B1oF*4=>PYahDU#ER}yA{3%O{20Sg%qo!8P zQvlKfl7vjkIN2M!P|JhbsAS|-ekNkB2{2HYS>W#Uz*5$iI^$AL-s!B4(Wfr&_1Y)2 zGuM5AXz@k{(%Vr(HYd&{44h0J zivFK<&xux8aX!KeqAOmoBx|upld|Y`c&UIx(9eOw!9q#|13O8!|{KV$$L!Bb;`BCY2j%?jZ_g^9k3eovwHxjV)quu<7 zrCOHM(mQ~oGtWE2FB}wegGqqI!&Rhy=b$?;{k7?=%aTE0E2M69K%!K{00jjVsT)HRw5crD^l} zeAH%qT?~?r^zH1ljzq)JAQw>EbQvlSrmbXBiwrA27|vRP@}R!GzOS_VSlDGtB`;Xo z0m6=db;c%h$Bu2SK&Gr);eWzn0Vbs-lf}-j{|y%V?ZPWJ`~X-G=mHd+LNu7{izI$0 zo(?}p&mlr^D&kd>3rgy|fqr6_G0v4Vm}vT;d;-c#ZS5_H3!*rW{%WlH_5ha&aDSUL zn4ogflS%UwOG->nkYuPe4vX+Oe!9i`JE#D{PLcz_w6(>>)gIT_=$&0jf;1dFK4!Z^ zKgQEqM{n4HlUI=kj=wfABe?6yLT*2h15o;=3KBV?3PtLXICPcy2zd=s$8=2G${Pie zq0L%?20B*#N^?ex;X$G79-9w|+V{@-i>`glc3w1cLp)qwerU_3yN(Vnu+?R5{NQir z=0A0~T&jwr*<~wWlde1EvfNkC^bmsO!Q%%yxftn^ zuF)i@5b2Ob&}lMGiTn`#naF!=qmOi8UQP>nYdAfLxDe=J#GGsGj~G~mYyomKB`1w3JAEd0O{*tmWo6@E z3W!^Jv>Rk4e&(MAl4lAV!5c9$;KI;%k%;JwZ`kUnHma!&V^yzuP)JLU1oh8|itZ2t z+AqXDikt6T)%Et|FW_;x742~_!A5%2!ufR^BTuBC9k|3nhCU7{ZAE0f+RFCJx4JJ`OATT?eMUCRA27vz6Aw z>|Bg0e}U1WI$}G2W1X-k2fXZzZa!lD`01&G>$>8b&~T;Q#&yx9hL- zOPJ&9&Cj=y59sV*(tr1QR`7J`**`KzjU%w^8W_giIIv` zt~$+DkE}y}Q!dGb6Nbhi8<2HdZY5C{&dfRqI%)eDJ-Lnu)#W{k^Hd(tc3ihZ(n z>JZ3(ld6DRxrN$7T&5BJVw5p+S*HPU=lc`~vaAax#JE12LVI7N&jAVq`XG@GydY!i zU)#4~etv2Kx?ruk{fTckP9k{8#Ufxs!pMmyOuWod7tY#I_KYC;g~aY;%JL?Aqlqo)Qcj(6> zK%08*eX-ytp89xzbg{>K@&xjoeCM&C+>AybCNQ>=&Vk@?`q+n};5cERCbECD=N~AI)D&NwO%~p6 zH56SbltKbB*e5eKM_CwWM0ny)BTd3wWpJ<-b5yoGVNtv_W*p1JH|bsc-??c|R>?|r zoD{5y+neO84!WX1rn~C;Tvj68GF~oO_+@*s1y<6)Tq7eFKw{nzx7i0%oJWPrcNSTcHUho{WSY)dBB z@1FjTki&Ii?0l01x=e(0VuKQ z$x7fx{61fCbTzNwe=%ZDf_EcyRWX>Ye=O>(ag?}_i9*X-rixwq!_Y_?k%}+)3d*dn zP0934Kjsj8AY!jmp|%Z`dmZ!_2gKCo-Y2E zj>!i2Lnz$0zDdFNnzpw-5(vQKj2zP|HmJ(yP0at{sz~F*CH3gkeC#G4qx-9>&%-g3 zAM}<4WVaks$L%7ZGqAABSrx)U@gM%mXH|#gEQE0DugiR~Fy)8x{?o>oy{V!YKs@ktdG|2&Lo!&(W=^u)b-~35) z6}nAL8{9dpMWO~KzeB_wo1J+Pe-so78==qdAU9s2RH0fKieizX>sMxGMh8!coh>vz z05I0R{N1Mq?76Qt0Lwjv6H>6IT26e_Q2)Tr&GYbtpy>KNRojY5I?V7aD+M-UR!&Op z@jt#Jzh3U+FQa?oKiAddQrw@fWk;i=r4^a^335UgyjZ>HHD}Tf+i?>RIHyAOOb&!X zf4Al)A%M&Y&Z$%8(E>H_AMI9-KuB8t;VB_p@l!Qg9A&}V;wMiELhscsA=D+-HguH4 zl;%ca{!Ww1jLc1!l#%Q#M9_4`jfEgj7leMW(+Kk!mrkys(m7b&_FF@h^J|XOs$aPeEW)QF=3^Xurxhd}~`{#%U=6tHS)?l~U zVYhiLzm!t>q@kz8{W5SzT;Y)sR^z%>&q1K|Tb}m3}?5BVBUggzWSmdwoMiQ*2 zOe_(I0ROj(^Oy(4L3IVQOFjEB1FEVc>8Iy9CzTa(xvPq}&!6;s78w1n7L~^yA3oDiYDH8fbDi3&C zxlP)(UBYD^)udX|=lUvK&Ar5cPoTi&KRSys7eu4BE9wtQ^VM!vJe`l+xObduo*R(R4SpgPkXW#uc+|20`pN}$0SmSTSx805`l^r{EQ>? z->NQ$l1O!9mgQN(i+*E{GcY`8Cxv`@@Q$L%(J9wMM`O?Db%->zy*m09cSUN}>hF>ooZ9#8MmhH-2b|uJ zglZV>CcRG&^WEQC|2rDyM0isCZLB1o66fr963^Fh0ipFJk*1?12j0T|&0;T~vkM}o z1JIUvm&*#-x7cg9;>$d4;4o*X8=A$FPFtmCpR`GOuVWMm66DQHWFk}dI&nEm z4C6@ez*vbd{!L&P-Vl6zX#H%nn?AXtVDQKM?v{pbHCArU#>-gcaV0_{THY-sc9B_u zu9l=~v_)2F+**9yqwMe!GjsgB)9L^(xXz`)AZAyVOnorlncc@TH0ya8+j`v@~Zui*GH z-M8t1qllYer2!g;z5bd(+4a9|++^T=)_|M+cv#iJuZX3y9HHLGK{F6THK&%KtNw!k5fQ0$ zN9#A`8UO5P*?mR(^y8(_`wrUqX4kttWOv!e9V#kM421hu_xARhgzicdU*F!L%t%=r zYA*bx{)dL{Kj`QF|M6j^|JH-2%axlgs)u&@SNN8m=e4c7wb~~%(qsPN?u8XGBO~s$ zr;kI2Qp6L6MaDP#od`i~28oGjN#z}Z;yA9nr3XOD;L zCIz3dWx9}Gke#aXzjx#3@KN%^bw{Q>Dk=)x&C!tr_`E$Hbm3sc>bJTaHAoSA?)q5x zL2#2>!!5y%ynpZJxja6p>hil=ci;5oC+mE^omKQtnGdntuM&9syR+HiwB7q!ckzA} zFkbZ{w^IM-z&5$=!<}8^`AyQSY^jMFMIq?$L}}7*QMSs%euwV zT3mN!WM;=+2#xAfb$Bk0Wc^KCf8{-H2mFK+q_S@PTsbQdkC3t9%~)YO;{tE5{_`vCN{Lljuba9{QlVrQ$yYbU ziHz4y?F5XhJ~xq1B{+rJIzluS`aK6(CQe&~)lh^%YdUIEMDi0^QU$-P`x{GJ*MZ|1 zcJAFxv<9Cg``RI>;H({3GgS!BxN8F?ic(vbF2XD05`LAND^sWFx%0PB3#z)@w?{CM z7Gc|~Ke}``(sJ4_}Ilz)d0qfVqxrd95smJ?}M z8~=zv2ChESUrSG&o69%RPm(1N(?Vf^l!RX3AXUuS4KI!vLyy@l=C+}SM;8CS1#9qd~j|2a^*{iWYCp zYYK8}hn(W@qz&=z!ZMm!co0pRgON+LM}Uy@6j|a|Ebupp{mrmc>Tzx69@I!jrZJeE zV9|9cQcCmFj>niebst`%0#5l-YhI;7>~VwR;#_h(am6LNhXSAG7@9C04ICE zaR_70mDYX|Q(r0<|9==e2jIw}eP4HM+qUhAJ;7vRXJTh!+qNf8Cbn(cw(U&(dd|7G z?tQP$sduWnclF-YsIKm{_F8*=|L^w|>gpxk9AXqkNHsyknw!4Aoh&^rOO2gPVz;i?;I>iE^zEes#9+o4Qxjn66cYj->RpNeeH>Zyh;T*iwGW6Ih@QiPv z=Np}{(+_pu#yo7^T1@G_Q&)A>LuTJI6w#1E`d%d)>P&o@$fU+)W?M6*>-dsBNH@^f zc-Bl+@ka{QOsg-z!9W0=7S>8;F+_8x*%_iLi7i94TGa9ICRqom%l8TzTQln7`dF^i zAaN`azZDp6R^R&J9snLlS;9op1X;cjCzmD;9gCWutZXI4{=>ixRN5U=oa#69F%o}P zVz>m{Q_XNd#5BLqNZ14^4J&+aA~uh!k-JIiw>H3-734QxF25?qmgHC>;1n6{;kUFy ziNt8xyv#02Zg6lgdN38)ISisENEn1%nz<3Lj2h?IR~ju6oH@8n-Gf%VTPU#&P!7dd z1|d0Wl&Je|*6&$v{$JV?(wb|-Vinm?L(mIEab;cq^b83z_C3f*Z27^C#_~&n(nyU> zBQGXWi&C8qsMwB*(7?fq7~yILT8v7VRjv;-)I?pj&ggKpo=LcD99QCPIOVt5I4=Fq z!S|Yz%Ef8t7`fHrHu-pZge%Z=vjAj&&Qi;IalQ5EG8>o7y7;j%=(~XiMrqWm!8=Tm z1@jJxjRu!nJCX4SO@c3em+s3HAeVU@Bq_T&`nq+F1adeNr5UJ&)nAJx=6`DbhD}E) zL7{cB;#&Y^j}fLc`avP-O0fcw*v%iBH;=!LvsXMY@uuEA#(v>2Z1(|(!00v?tK zHlrY>KFTjZF&*t&0X}hC9Gr}Q=rYlnWE&1kM*1;& znyZO~{t7&v<35E7ndOKof(6c%&0VCbA{&Z)kwgatcqn`YVpU5y)sH|lKYBFV0$f_Z z_BdmqLIRa%bs7$I7=)jPaHY$^2iqy#01mFVB1F`vX`l-*~ctXOkK zViRTLOU2F8bVL&%qelW#z4UPzdv*wYVlW6r_dhBMa9W;pYoClGXxY(IU2r-?yNuK2 z!n|b$u^Dq^Q1x-7BP|=qhxriv?MnnVC`8JyS9b~VgKC-Cb-x-6ql-Af1+y*t?a;7X zh$i5CJz_4|U(7t$WHqnXvJIzA-Pk3i)fSsyTha-zZ+`4F{;VrzV$O)YlgGc5sbiqc zD?wdkLT0&Mu2et}fFOIDV5C6ogsv%UC~0rstKQ z?pcF98)^=$Sm5g+W`&8zmDij;{F1F53Y~U;s3liq>~4i+zZF)t%jgO^flUd)B{C-a zg4Gx~7JE#89)z@JtdT4PG^xWnCM%jTJ%~dggf@5~!)0)EW%Q0kK><2sQO#a|I$45S zxXEx|^>d|0M!_vJ8LwE?%b`=BSi3`lgR6mm@u!pQSMkqVgn0!v6Rp}6=u{cnG&#)N zoOIGCae+~(VRmr~N3v1);h8o#ETW(*3lYMgT9;+dUnFouU-UD3^kYoB+*&d{ zZe2b}RlF5$Jj!M=-CJhbl>8-miWN zq&<_eye(9HdC2f-;^jt{fhOuYSx?ZrBH|Y0Yj?fbw4S4a3*YM&RKn_1WH8CLs%~U> zG`Wdj+WKh8cE5SH6@+>FnDKbN1#4SJGtKrnBl13y{fO~-M2mS_aeKZ!5ac=4+3GMSIl)8neonJ)B;r4q66iPl*ctHY=;89U1<`1}ve5Rj#zvVF$ZPsQTc#P{YKlzUByg zBYfTjUOq4v=zYkK-6H+O*^No5nCA^XeNycJ-v$G#aj*rp?h z7}tme=h*_)iW$ff7tl*5BQz&aTq=wkG56f|cC5`VW`Z6O(PgGHZ7Ert|i)_{swB#$DGL8c!7u`;|NA zHsJfY+iM(nmw0=0?z;McZZKK)TGm#`{-N+7Zm-On63%L<7xVYmxtccy{f-Tp!)85W<$ zG`~p5ipWNGy1zKG5hxm!{NaH({o8MY@A)Uki0@NC;8(maK`>TC7xW3pq63q!()d&* zDVitZo4@>usOEP8z34eoVYA{O6F#QsoeI5vr}y}|0uookUaEo7rwLUv<@odyibs|#k&nDt4X8W0i|2r! zrsePo(-BF{OPcj-#pk*h_WmYN;{Jrmh9KnC;@pGEK}Q})>X>1QG9@51A*_WbypPlP z)*-zw*?lLjZmZx~SV$x99|z3(A##JdVG=EBd*CkqN$G<><}1)yRW$Gu^hN_w6)5r+ zH1n))9}oG?K|5%5(6EFd)MizhS2cPDcpBia&Mn&FHDX8EAu-yp!;9QqwI#c{jf>eN zG{_BTXZwt;*Cb2RWkJId$2@kT^YE1N44p&>%%liP{93<#Z{9JZwLm6VkHn>Q2~5xR zYt3U<1Z$w~SY-Qf`#c>I^wt%OP-xn!wDtZ(@+NA*o?T}z`rj?;@8f^VbN>IiGS>g* z%2@t#WkEo$%-J9g0XdR0-OLXH_tTdGA}B2A9#d6Q;}z;_c~dpp2e_;Vd`G-Gwl%XO zI(jWcngQi_y9+}qL@>_%1mhs~lr*IgmzEdLQM*UTc{#whbQGv(yU3%~m(eCR-3K@(qY-fDg01+axP>zJUhJ+N3yHvosAT|;>}(7n zwx1&wyt=}E{ts>@AO*$R>qyKOi&6v)yn}r@K+Sr!r*%W45i1xx5)%yTq#}|Fg#%z> zfj3g1SV0K10Q&D^K*`ZJNq}#2L0z&eqnJPm1x11^!>0*Zwo!O!~ihv;XpwNwmAa7YRhRA;6Jq5%TxqY7lc02Sys< zMS-g~g3FTCiDT0BXCb^nkb46#rRs#u1_KyyA_(Bx+2A}1FdK~n<4&?-mfm$$R0jp< zSy|aw>B@8;hU%$k7b;3qRFZJ0t~!pg@Nj^JGS|H*t}jF)f1H%t3llq^4w!tNxBeVv z*n00QsOi0*(q;31CZvOGyv`gFb$-5I`3R)1*tXx^%IbmSq=R(40j2Qm?~PtldMQmoByo%|h4OGTs5x9Axc&f=_M(kyQ7YSyonV^yc+L7odmkH8w;zr>lh zeOI>9Yw_&vW%)*9lk|r@I5KtT(dMSYs~?g@@B1^3=u} zq)=#lOvlxl;;7!pCgVWZ`iMs(4*FtCyG1IFZl6`gKi4oS&(CmJ!0YUZA9N!11P{C z-e1CPg6@`q3wrw~mxp69!QpDnESSD3ukySWVomhTOB+a3DxViI6-b^v_(Ba=qi_uO znk`KV#Lb$uhpE3879dml-V)U;VxO+*Q7$fSBoxpVD#*ZGW>I3Y*425N24QMCwy>dZ z{Nb=R!5p{Z$o*?3Q~k~D6hjgy4KEI$JMh@!sLd>>Ba9uVZ}nhjQ?Vc!BbiHe>Hn`+B ze(6*k5NgacZhl7M3tRYXjQksDeR3!cl)A_ovf`A1xcc8aQ{k-*)3-|5X4&KslEZ~C z$X^JN1xRFXyRSx8j#fl+a6E!0yr35Codp+%p279q=3J7x`gAO5FTYRnuD{n`8F`98 zww<^-^eXkF_n9sxh~(C`8F9UoMWg?66^VVt^_lyr?2Z6eIFo`z+cW-x$vx2OdL6Ls znCTYScX{ElD=Y5mO5a(I2b#c@X-7lt8ffkqNaHljH-Dfc@`DH{CabJ}oNMm)-mWn5 zLCTKFbWA-7zbgH-`LY=Y!V`;oXNP*gOMOv;h!w_WNgaC%9`)!)RJSEp`1(iZVTh{a z7o4*Y$OGe&jKy8dqoxUfIV&gMSULgH!D^Ij6*E}~GPU=r9) zvugc}7=iQ<9$+aAzgU3vSm?ntLM@v=5!7*-gU@9NKFI2E4gY?yTsFV8f}{mA_R);X z{iiVEe)^`dO)Wgqys)O-NDckeMKx&+FEW98NfYu2f^UOMO?~PS_aOWct2xSY%|QFb zyejRN^nk_q7kw_E5q9>sOUp%8nJy~8RG%A-ioZ7VvV5NpFh(Z`QWy==fDDAq>WF5b zb5@|tOh6{xLu4$guU!a9vLWfdt`FZmSu4)3ilX-w+R->lqc(XIR!@F5c}V%zeUgnm z1ES$5*ldp}3J3GPC0H!yT4mMxv?{#4i~Aa<0BJK1gC8VLl|y+yDfS)!4B2+sXE!jX zWEhL5D^}IXYtVzEG8}X;F6HEY*KH`itBux5GG~~5#H(Q$49x_O7gI7OCCq&DO&cyS z!>w@hU9A_%u(Z&kfcc_DU}%}~VvY73yWCpiS;f4@Fb^j$JXK@fA3VGbkkmE;B;`!L zh2P0w8*t`i52|#+g_jM|QCt}l%NXm8)^qF=FRj)~&!{Okvn|R^Ta?LU(#wBz##lxA ziYq@Rz6go#CK9v3M86>+YcKlYew3k=(B3J|v75JTMu$1IZP)-S4Y<^-*U;5cDY#9E z;R_O=-Lex%x=cSl{0kAIG`^?%(Sg^-5^F#vZqfCKs-3`ZE6G@-Pn33PL{6AEcsV&W z=>D!3U)r8*u#fp7oe}U);B2WOlYsfN6Uw~Moyk~kQ^}b^p}YM?DmHc=0aF$Y?x6~> zy=HBeUPPdM`O9VV`ReuQstb>aQ5RhL>Ls`YMG-05h* zgMor~#IsIrL@h&peO<`>Uzm@6CH7-hZYJmn?xvPAUxXQ(P|Meyu2yzX0+ zG2y3TH0ww=u5{PlaG9CW5Qne=uOHd&`8enk2$^^GKo6M; z-qAG){xVi^B9pe!%iP;>>eFlQ+aiC~io>VX_Ic#0%|>HE7a?vP#2aWp^`AEvmBzdS z!Zl#Dq!eP#BibAadvOC5QkwJXf+}#s9LGXzz90<>JGr@F&Z))FNdc#DXUHTt>Mrmt zE=}-KnqpkXy%3dj(YX$e0oZk8FbpMU;fA5esZ_7=Aj_?G8gx1H2zd?oqVR|uGVWEH zLL>PuF889!T=nM$YmI{C7}M@+q=M7ND6u0o=5vpx4WO%yCx-Uzz`q{~$yUAft4{-{ zMbin&J|2L@Ip2Gl+`6-jeN>*61~ z(vJItXZ+dz*&9B}N1o&Wp_S2%DF8bPI7KDB&UyugBJ|oCs#<&_3bFzB(dpwaO^{y$ zWoyit3GLx-%Yz!wHv^g=IC~ZRXX4&6tS9Bx-&ly(l}@wc&tLG>3RKSQO?Ds@=>U;# z?7ACuyl4WDgFnU08t&p8!OU;TxKIEfNX3p{;u-&9XkI@kh|B(op}{j^@vPTWVoq0F zF19&oR^s^&rZbR}7{Lob;?_(v%D-u1cI zgxfIo%Wo*ihKtLE@Hu{^Rw4~1PyHb_Ymbx= zv1xEx1y9WqCFZfFpjs9Fj0)Y&NrfY3T0zfYq!D~eg<#WuJ5-b2&0)0kxJC}C>{bSLilDPrhW%A%Y?}vPLKW*=a%*0A z7i3{%_rM90?-fCfYxNTnINH%?53QO)a%-H^PBSybbh^5_i*ROb);VPcw}v81>Qze% zGT9T28zM`;lG}{UU+2d3b`K7WlPq4_1Rs`kHE$%RTkEEo0!<7*I6vO0^!|88`F^nn z8p&4F1aClRkwAR^x`;n;yVX9gn?7$2Or4XjrHS8&aO<2*-(GllOH1 z(VGtWbA#YV{?tawQcJ2**G7xS(Z`x?*Lwpr01FE%s$ba+KI*%4#UvBwM!OcqkfL|g z#`kQQ%5V?)JBh-|FyX= zlAm-x9e7#5@5t{Ge)6Qm(=uI~90X8|tR{q!gzzB0IsO1jOFej5<{wzVe?^WtB>+UI z_UwIU;#_4ILt3-ZQ|s^pR0LUFPwkPBxr~ zZa`aPqJyaRfIKpS<;SI>lU=y955%zixo~B_rW(U(?cv7C_?I(79;BQ7v{Du6N zGgAr!a%O?*lRdFnWI5gsD@aP2@vhDV-D#1dXX1}%5|3kYrRt~++IX1?b6qT<-@Sdq zlG^C7FTJ|%pA6eFTXiM)_Q_Ip?HMk8R5MI4Nx6A`Co^y-Z?_dx*Poj`mw0sxH^SAl zyFxJ<5sBu?mdomBkbudaZ+`N(wY}V3U7-`8(Zw6MgndH?{JHaSZW8q2J+~(f02^$# zGS{7pyGJq|0(!_0I==GDw8odRA zW^K>X;JyPM+%66hY2+N0EN}D4^f3+hgn+Ny=l1CSx3f*B)GcG@_=PgMv0knWK+sIl z&j<*b3026xx;(<9XNe9BjIzi-qtHv{2e6t+av%p5?{MJD107^{59A@3gsV&M&IUWD zi4H&qS?yQ4*TyJ+)y*M~&&a1i%d*qlA z3S6!9sX8+_gnJJunjCc?Y4*fkuxy*)CHs8xGyd9sk_9o5ts&8-G=%pIyS%>FCMiv{ z)+)AWKnw*Nif-x_blHC;PK}6uvgD(&Hf2?G@V?p=NhxL^U48t1TH`gCf8-qzSrU$8%KKaeNvOZJllOR2J zXNmRVtppgNowB{DP@YwwnRSDc3t za#T4?Xx>@=J6LGyRZLyO5@Tx*bT7$#UqbD23~FxJzT$l~iK>3&RsOj-MRNGLJWK7z+-xsZMmT!cnPGJF}1O*4}VhqVxlm{^k z9t+G|xkoS_tj$&feed>_naXXfc~ zi%U%ear4csIEKWTOS!m&qPYN(I~xAS6=&s)msu(k#FU2Zx!B`0v6C>}I z)t?)FN`i;O?7cMbbxoI`B*o^FxZI1c>eZx+kaMfiZPAez`LCL$EDpme{W{LFhu|4U z%UeuUeRMANzuz+rU?DQ3BS1HefBex%S}jrUi?K3pHK0gQriTFMbe#eKo!h|NFAszpA(X z&p0#A|GF-oE>~=eAeEbzZ6hXjo znv4oDi4zT?r)FCW1(%!*N(8AuT4eSI^EYN1a#UngB|&M5hlEzaqw|K&sh-uN#SWE| zAC+CUnbnH;l^L?sk79q~!sL?{w>f#7#4_LWEy2ZIbRo%8$Wx z@9323_ktEoC7v@&-Ll+qUtp!_DCwNn&CU?fX9tu*_Lq*k)3T}$Rk3p^cLuQLSEjB% zyAgW)Znyhj+MjnsiYXrZHX;|1?bd(VO-Wcb{G=u)U&EgRy!RU#Ui~1WqKR= z!cDExG}@gbZUsAA9)|S5CCZI#)X zvNV2S`Fom#w!qe}E29M$@W~?)h>xt-(ATjACq0h85akA?siM(zC^+4f)b#W9=S0S3 zn3-xTeQC$6O>5m8Ef|{+5`8ntuahjvo6sGH8^tK5R@pu#X26Lhrdr__p4cYfl#As(X8VfkYMDq^xh8`+VM=Rl zl`Bm`Nx{zWLutAm$wa(hRW~6(jT({XQosPE*$*`x`xbvZJ~R?jM_)tJXx>=;FqFIB z=@@d@Y>)dZY;r_u3NenJ0NO0WB^{%L-Zv3|5gV$A_91^H%QAZ?_A%N8g{Qz_aleGA0O1{`w& zTib{!Al`lS#O6SCV&q`={S{vIHI3>(6Z{o^&8wW&a~fYcDF=w>-NRr)j^THv43MHl zAj$xV-!#gQf1=XC_NmxiFXjsjhZUKpL8RzaNMdR??u_nPRZo zSAeWTNg&+1$UG01jHBm>;Jy;XRIAKJ&-N`nZ^i{>M@aMML0^TY*DFYfoq>uNi-xI~ zv{-iaM)(wh5>|5Q`lXu-Ld!l!L;c2uoq}0fVf^)%{Pdgjj64di=(V9f&ux52yQpFU zl-~90d6Vz+Ukm&h*k%?& zZ_cu7T7(N7f@k}NmqqH7Nb@Cum(7K7nBic8GH??8>dcb@&*4b?&0tjdqhK+fGbUi*$W-l&yPJsaH4NxbP!7QOKML}#Uq8+8}MV~Tfe})lCK^GE3RO_1%)ey zhJO7Do5(m!qK8foHA+e!izg+VdcA`Jp;SkSsKohaTVJgas30e?^8M~WNs2FB9jG~f zXn?dyWj>Qjs_rN@0d_3;T8X04gt%)#0wLRUN)Wkh38EFFu;R&GNa#FEkwo!v#owxx7 z!}V|ooE6H^kINNv>b2r*yz`GjX zG_#qZ$UI^h!F+V_%xo2WmxH(~ex-n*dc>-2`fD`_GwIh0H&JpwXbog@8v7U}qL27NvRA@+BAkcICImL
    XhQZNbr!p4$MB$%aotAY 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
    (s$L>&1H+n6I?xr!^_2bn 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%0Ad^O^1e>& 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%0D_Uo-kv->Vg0lGg*Z!nFVv`%zh{>)f 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�{*+=U9bFu0sMgZcMJF{)BH~FYiHj5 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
    yEppP8=MCmKt`oY(P&y2PD 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 + +// Because we turned off interrupts delay() doesnt work! This is approx ms +void smalldelay(unsigned long delayTime) { + delayTime*=(F_CPU/(8*1000L)); + + for (unsigned long loops=0; loops>8); + UBRR0L = (uint8_t)(BAUD_PRESCALLER_DOUBLESPEED_MODE); + UCSR0A |= 1<>8); + UBRR0L = (uint8_t)(BAUD_PRESCALLER_NORMAL_MODE); + UCSR0A &= ~(1<170) { + stopDriveForOperation(); + return false; + } + } + + stopDriveForOperation(); + + currentTrack = 0; // Reset the track number + return true; +} + +// Handle a no-click seeking operation +void handleNoClickSeek() { + if (currentTrack != 0) { + // Not allowed. + writeByteToUART('0'); + return; + } + + startDriveForOperation(); + + digitalWrite(PIN_MOTOR_DIR,MOTOR_TRACK_DECREASE); // Move OUT + stepDirectionHead(); + smalldelay(1); + + writeByteToUART('1'); + + // Now see if there is a disk in the drive. Returning '#' means no disk in drive + if (advancedControllerMode) { + if (digitalRead(PIN_DISK_CHANGE) == HIGH) writeByteToUART('1'); else writeByteToUART('#'); + } else { + // Don't detect disk + writeByteToUART('x'); + } + if (digitalRead(PIN_WRITE_PROTECTED) == LOW) writeByteToUART('1'); else writeByteToUART('#'); + + stopDriveForOperation(); +} + + +// Goto to a specific track. During testing it was easier for the track number to be supplied as two ASCII characters, so I left it like this +bool gotoTrackX(bool reportDiskChange) { + // Read the bytes + byte track1 = readByteFromUART(); + byte track2 = readByteFromUART(); + byte flags = 1; // default to normal speed + + if (reportDiskChange) { + flags = readByteFromUART()-'0'; + } + + // Work so its compatiable with previous versions + const unsigned char delayTime = 4 - (flags & 3); + + // Validate + if ((track1<'0') || (track1>'9')) return false; + if ((track2<'0') || (track2>'9')) return false; + + // Calculate target track and validate + int track = ((track1-'0')*10) + (track2-'0'); + if (track<0) return false; + if (track>81) return false; // yes amiga could read track 81! + + // Exit if its already been reached + if (track == currentTrack) { + if (reportDiskChange) writeByteToUART('2'); + return true; + } + + // If current track is unknown go to track 0 first + if (currentTrack == -1) goToTrack0(); + + if (reportDiskChange) writeByteToUART('1'); + + startDriveForOperation(); + + // And step the head until we reach this track number + if (currentTrack < track) { + digitalWrite(PIN_MOTOR_DIR,MOTOR_TRACK_INCREASE); // Move IN + while (currentTrack < track) { + stepDirectionHead(); + if (delayTime) smalldelay(delayTime); + currentTrack++; + } + } else { + digitalWrite(PIN_MOTOR_DIR,MOTOR_TRACK_DECREASE); // Move OUT + while (currentTrack > track) { + stepDirectionHead(); + if (delayTime) smalldelay(delayTime); + currentTrack--; + } + } + + if (reportDiskChange) { + // Now see if there is a disk in the drive. Returning '#' means no disk in drive + if (advancedControllerMode) { + if (digitalRead(PIN_DISK_CHANGE) == HIGH) writeByteToUART('1'); else writeByteToUART('#'); + } else { + if (flags & 4) { + // We've been told to check for disk presence regardless + if (nonModCheckForDisk()) writeByteToUART('1'); else writeByteToUART('#'); + } else { + // Don't detect disk + writeByteToUART('x'); + } + } + // The second byte is '1' for write protected and '#' for not write protected + if (digitalRead(PIN_WRITE_PROTECTED) == LOW) writeByteToUART('1'); else writeByteToUART('#'); + } + + stopDriveForOperation(); + + return true; +} + +// Checks manually to see if theres a disk on un-modded hardware +bool nonModCheckForDisk() { + register unsigned char lastState = PIN_READ_DATA_PORT & PIN_READ_DATA_MASK; + const unsigned char indexPinStatus = PIN_INDEX_PORT & PIN_INDEX_MASK; + + // Configure timer 2 just as a counter in NORMAL mode, we need rto measure approx 200ms (a full rotation) before giving up + TCCR2A = 0 ; // No physical output port pins and normal operation + TCCR2B = bit(CS20) | bit(CS21) | bit(CS22); // Precale = 1024, ie: divide the clock timer by 1024, meaning each 'count' is approx 0.064ms + OCR2A = 0x00; + OCR2B = 0x00; + + // So if the disk wasnt spinning, we allow longer + const unsigned char totalLoops = 18 + (!driveEnabled ? 62 : 0); + unsigned char counter = 0; + + // We could do this with timer 1, but hey. + for (unsigned int loops=0; loops=3) { + TCCR2A = 0; // disable and reset everything + TCCR2B = 0; // Stop timer 2 + return true; + } + } + } + } + + TCCR2A = 0; // disable and reset everything + TCCR2B = 0; // Stop timer 2 + + return false; +} + +// Test if theres a disk in the drive, a '1' if yes, a '#' if not +bool testForDisk(bool sendOutput) { + if (advancedControllerMode) { + bool isDisk = digitalRead(PIN_DISK_CHANGE) == HIGH; + + if (!isDisk) { + if (currentTrack < 40) { + digitalWrite(PIN_MOTOR_DIR,MOTOR_TRACK_INCREASE); + stepDirectionHead(); + digitalWrite(PIN_MOTOR_DIR,MOTOR_TRACK_DECREASE); + stepDirectionHead(); + } else { + digitalWrite(PIN_MOTOR_DIR,MOTOR_TRACK_DECREASE); + stepDirectionHead(); + digitalWrite(PIN_MOTOR_DIR,MOTOR_TRACK_INCREASE); + stepDirectionHead(); + } + isDisk = digitalRead(PIN_DISK_CHANGE) == HIGH; + } + if (sendOutput) { + if (isDisk) writeByteToUART('1'); else writeByteToUART('#'); + if (digitalRead(PIN_WRITE_PROTECTED) == LOW) writeByteToUART('1'); else writeByteToUART('#'); + } + return isDisk; + } else { + // This is much harder + startDriveForOperation(); + + bool diskFound = nonModCheckForDisk(); + + + if (sendOutput) { + if (diskFound) writeByteToUART('1'); else writeByteToUART('#'); + if (digitalRead(PIN_WRITE_PROTECTED) == LOW) writeByteToUART('1'); else writeByteToUART('#'); + } + + stopDriveForOperation(); + return diskFound; + } +} + +// Check if the disk is write protected. Sends '#' if its write protected, or '1' if its not. If theres no disk in the drive this number is meaningless +void checkWriteProtectStatus() { + startDriveForOperation(); + if (digitalRead(PIN_WRITE_PROTECTED) == LOW) { + // Drive is write protected + writeByteToUART('1'); + } else { + // Drive can be written to + writeByteToUART('#'); + } + stopDriveForOperation(); +} + + +#define CHECKSERIAL_ONLY() if (UCSR0A & bit(RXC0)) { \ + SERIAL_BUFFER[serialWritePos++] = UDR0; \ + serialBytesInUse++; \ + } + +// 14 is the minimum number here. Any less than this and the CHECKSERIAL_ONLY() code will impact the output. The pulse width doesn't matter as long as its at least 0.125uSec (its the falling edge that triggers a bit write) +// Because only the falling edge is important we achieve precomp by shifting the pulse starting position back or forward two clock ticks +// Because it may go back 2 ticks, we increase this number here by 2. 12 ticks is 750 ns, 14 ticks is 875 ns and 16 is 1000ns (1us) +// By doing this, the bit cell timing remains constant, but the actual write position is shifted +/- 125ns as required +#define PULSE_WIDTH 14 +// This is where the above starts from the end of the timer +#define PULSE_WIDTH_VALUE (0xFF - (PULSE_WIDTH-1)) +// This is where to start the counter from compensating for code delay of 6 ticks (measured) +#define PULSE_BREAK (58-PULSE_WIDTH) + +// This makes use of the PWM output to create the wayforms for us as accurate as possible. +void writePrecompTrack() { + // Check if its write protected. You can only do this after the write gate has been pulled low + if (digitalRead(PIN_WRITE_PROTECTED) == LOW) { + writeByteToUART('N'); + return; + } else + writeByteToUART('Y'); + + // Find out how many bytes they want to send + unsigned char highByte = readByteFromUART(); + unsigned char lowByte = readByteFromUART(); + unsigned char waitForIndex = readByteFromUART(); + + unsigned short numBytes = (((unsigned short)highByte)<<8) | lowByte; + + // Setup buffer parameters + unsigned char serialReadPos = 0; + unsigned char serialWritePos = SERIAL_BUFFER_START; + unsigned char serialBytesInUse = SERIAL_BUFFER_START; + digitalWrite(PIN_ACTIVITY_LED,HIGH); + + writeByteToUART('!'); + + PIN_CTS_PORT|=PIN_CTS_MASK; // stop any more data coming in! + + // Signal we're ready for data + PIN_CTS_PORT &= (~PIN_CTS_MASK); + + // Fill our buffer to give us a head start + for (unsigned char a=0; a0) { + if (!serialBytesInUse) break; + + // Read a byte from the buffer + register unsigned char currentByte = SERIAL_BUFFER[serialReadPos++]; + serialBytesInUse--; + register unsigned char counter = PULSE_WIDTH_VALUE - (PULSE_BREAK + ( (currentByte&0x03) *32)); + register unsigned char pulseStart = PULSE_WIDTH_VALUE; + if (currentByte & 0x04) pulseStart=PULSE_WIDTH_VALUE-2; // Pulse should be early, so just move the pulse start back + if (currentByte & 0x08) pulseStart=PULSE_WIDTH_VALUE+2; // Pulse should be late, so move the pulse start forward + + // Hardware error checks (frame error and overrun) + if (UCSR0A & (bit(FE0)|bit(DOR0))) break; + + // Run until the pulse starts. The pulse start is also timed so that its width is enough to cover the time to execute CHECKSERIAL_ONLY() + while (!(TIFR2 & bit(OCF2B))) { + CHECKSERIAL_ONLY(); + }; + + // Wait for overflow (ie: pulse finishes) + while (!(TIFR2 & bit(TOV2))); + // Set the new counter and clear all the overflows + TCNT2 = counter; + OCR2B = pulseStart; + + // Clear overflow flags + TIFR2 |= bit(TOV2); + TIFR2 |= bit(OCF2B); + + // Control I/O with the serial port + if (serialBytesInUse=240) {} + + // Now we write the data. Hopefully by the time we get back to the top everything is ready again. + WRITE_BIT(0x10,B10000000); + CHECK_SERIAL(); + WRITE_BIT(0x30,B01000000); + CHECK_SERIAL(); + WRITE_BIT(0x50,B00100000); + CHECK_SERIAL(); + WRITE_BIT(0x70,B00010000); + // Extra check for some of the other errors that can occur + if (UCSR0A & (bit(FE0)|bit(DOR0))) { + // This can't happen and causes a write failure + digitalWrite(PIN_ACTIVITY_LED,LOW); + writeByteToUART((UCSR0A & bit(FE0)) ? 'Y' : 'Z'); // Thus means buffer underflow. PC wasn't sending us data fast enough + PIN_WRITE_GATE_PORT|=PIN_WRITE_GATE_MASK; + // Need to allow data to come in again + PIN_CTS_PORT &= (~PIN_CTS_MASK); + TCCR2B = 0; // No Clock (turn off) + return; + } + WRITE_BIT(0x90,B00001000); + CHECK_SERIAL(); + WRITE_BIT(0xB0,B00000100); + CHECK_SERIAL(); + WRITE_BIT(0xD0,B00000010); + CHECK_SERIAL(); + WRITE_BIT(0xF0,B00000001); + PIN_CTS_PORT|=PIN_CTS_MASK; // Stop data coming in while we're not monitoring it + } + + // Turn off the write head + PIN_WRITE_GATE_PORT|=PIN_WRITE_GATE_MASK; + + // Done! + writeByteToUART('1'); + digitalWrite(PIN_ACTIVITY_LED,LOW); + + // Need to allow data to come in again + PIN_CTS_PORT &= (~PIN_CTS_MASK); + + TCCR2B = 0; // No Clock (turn off) +} + +// Write a track to disk from the UART - the data should be pre-MFM encoded raw track data where '1's are the pulses/phase reversals to trigger +// THIS CODE IS UNTESTED +void writeTrackFromUART_HD() { + // Configure timer 2 just as a counter in NORMAL mode + TCCR2A = 0 ; // No physical output port pins and normal operation + TCCR2B = bit(CS20); // Precale = 1 + OCR2A = 0x00; + OCR2B = 0x00; + + // Check if its write protected. You can only do this after the write gate has been pulled low + if (digitalRead(PIN_WRITE_PROTECTED) == LOW) { + writeByteToUART('N'); + return; + } else writeByteToUART('Y'); + + // Find out how many bytes they want to send + unsigned char highByte = readByteFromUART(); + unsigned char lowByte = readByteFromUART(); + unsigned char waitForIndex = readByteFromUART(); + PIN_CTS_PORT|=PIN_CTS_MASK; // stop any more data coming in! + + unsigned short numBytes = (((unsigned short)highByte)<<8) | lowByte; + + writeByteToUART('!'); + + register unsigned char currentByte; + + // Signal we're ready for another byte to come + PIN_CTS_PORT &= (~PIN_CTS_MASK); + + // Fill our buffer to give us a head start + for (int a=0; a=248) {} + + // Now we write the data. Hopefully by the time we get back to the top everything is ready again + WRITE_BIT(0x08,B10000000); + CHECK_SERIAL(); + WRITE_BIT(0x18,B01000000); + CHECK_SERIAL(); + WRITE_BIT(0x28,B00100000); + CHECK_SERIAL(); + WRITE_BIT(0x38,B00010000); + CHECK_SERIAL(); + WRITE_BIT(0x48,B00001000); + CHECK_SERIAL(); + WRITE_BIT(0x58,B00000100); + CHECK_SERIAL(); + WRITE_BIT(0x68,B00000010); + CHECK_SERIAL(); + WRITE_BIT(0x78,B00000001); + TCNT2=248; // a little cheating, but *should* work + PIN_CTS_PORT|=PIN_CTS_MASK; // Stop data coming in while we're not monitoring it + } + + // Turn off the write head + PIN_WRITE_GATE_PORT|=PIN_WRITE_GATE_MASK; + + // Done! + writeByteToUART('1'); + digitalWrite(PIN_ACTIVITY_LED,LOW); + + TCCR2B = 0; // No Clock (turn off) +} + + +// Write blank data to a disk so that no MFM track could be detected - this is no longer used +void eraseTrack() { + // Check if its write protected. You can only do this after the write gate has been pulled low + if (digitalRead(PIN_WRITE_PROTECTED) == LOW) { + writeByteToUART('N'); + return; + } else writeByteToUART('Y'); + + digitalWrite(PIN_ACTIVITY_LED,HIGH); + + // Enable writing + PIN_WRITE_GATE_PORT&=~PIN_WRITE_GATE_MASK; + + // To write the 01010101 sequence we're going to ask the Arduino to generate this from its PWM output. + TCCR2A = bit(COM2B1) | bit(WGM20) | bit(WGM21)| bit(WGM22); // (COM2B0|COM2B1) Clear OC2B. on compare match, set OC2B at BOTTOM. WGM20|WGM21|WGM22 is Fast PWM. + TCCR2B = bit(WGM22)| bit(CS20); // WGM22 enables waveform generation. CS20 starts the counter runing at maximum speed + // This generates a square wave, 3usec high, and 1usec low, 4uSec in total + OCR2A = 63; + OCR2B = 47; + TCNT2=0; + + // Now just count how many times this happens. Approx 200ms is a revolution, so we'll go 200ms + 5% to be on the safe side (210ms) + TIFR2 |= bit(TOV2); + + // 52500 is 210 / 0.004 + for (unsigned int counter=0; counter<52500; counter++) { + // Every time this loop completes, 4us have passed. + while (!(TIFR2 & bit(TOV2))) {}; + TIFR2 |= bit(TOV2); + }; + + // Turn off the write head to stop writing instantly + PIN_WRITE_GATE_PORT|=PIN_WRITE_GATE_MASK; + + TCCR2A = 0; + TCCR2B = 0; // No Clock (turn off) + + // Done! + writeByteToUART('1'); + digitalWrite(PIN_ACTIVITY_LED,LOW); +} + +// Write blank data to a disk so that no MFM track could be detected - this is no longer used +void eraseTrack_HD() { + // Check if its write protected. You can only do this after the write gate has been pulled low + if (digitalRead(PIN_WRITE_PROTECTED) == LOW) { + writeByteToUART('N'); + return; + } else writeByteToUART('Y'); + + digitalWrite(PIN_ACTIVITY_LED,HIGH); + + // Enable writing + PIN_WRITE_GATE_PORT&=~PIN_WRITE_GATE_MASK; + + // To write the 01010101 sequence we're going to ask the Arduino to generate this from its PWM output. + TCCR2A = bit(COM2B1) | bit(WGM20) | bit(WGM21)| bit(WGM22); // (COM2B0|COM2B1) Clear OC2B. on compare match, set OC2B at BOTTOM. WGM20|WGM21|WGM22 is Fast PWM. + TCCR2B = bit(WGM22)| bit(CS20); // WGM22 enables waveform generation. CS20 starts the counter runing at maximum speed + // This generates a square wave, 1.5usec high, and 0.1usec low, 4uSec in total + OCR2A = 31; + OCR2B = 15; + TCNT2=0; + + // Now just count how many times this happens. Approx 200ms is a revolution, so we'll go 200ms + 5% to be on the safe side (210ms) + TIFR2 |= bit(TOV2); + + // 52500 is 210 / 0.004, but we're tqice as quick, so do the loop twice + for (unsigned char loops=0; loops<2; loops++) + for (unsigned int counter=0; counter<52500; counter++) { + // Every time this loop completes, 4us have passed. + while (!(TIFR2 & bit(TOV2))) {}; + TIFR2 |= bit(TOV2); + }; + + // Turn off the write head to stop writing instantly + PIN_WRITE_GATE_PORT|=PIN_WRITE_GATE_MASK; + + TCCR2A = 0; + TCCR2B = 0; // No Clock (turn off) + + // Done! + writeByteToUART('1'); + digitalWrite(PIN_ACTIVITY_LED,LOW); +} + +// Read the track using a timings to calculate which MFM sequence has been triggered +void readTrackDataFast() { + // Configure timer 2 just as a counter in NORMAL mode + TCCR2A = 0 ; // No physical output port pins and normal operation + TCCR2B = bit(CS20); // Precale = 1 + OCR2A = 0x00; + OCR2B = 0x00; + // First wait for the serial port to be available + while(!(UCSR0A & (1<=TIMING_DD_UPPER_4us/2) && (lastWindow==0)) { + lastWindow = 1; + sendString("\n"); + } + if ((a>=TIMING_DD_UPPER_4us) && (lastWindow==1)) { + lastWindow = 2; + sendString("\n"); + } + if ((a>=TIMING_DD_UPPER_6us) && (lastWindow==2)) { + lastWindow = 3; + sendString("\n"); + } + if ((a>=TIMING_DD_UPPER_8us) && (lastWindow==3)) { + lastWindow = 4; + sendString("\n"); + } + if (cc[a]>1) { + sendInt(a); + sendString(", "); + sendTickAsuSec(a); + sendString(", "); + sendInt(cc[a]); + sendString(", "); + + if (a <= TIMING_DD_UPPER_2us) { + sendString("4us, (assumed) but bad"); + } else + if (a= TIMING_DD_UPPER_2us) counter -= TIMING_DD_UPPER_2us; else counter=0; \ + } else \ + if (counter=TIMING_DD_UPPER_8us is an error but some disks do this */ \ + counter=16; \ + } \ + + +// Read the track using a timings to calculate which MFM sequence has been triggered, hwoever, this keeps running until a byte is received from the serial port telling it to stop +void readContinuousStream() { + // Configure timer 2 just as a counter in NORMAL mode + TCCR2A = 0 ; // No physical output port pins and normal operation + TCCR2B = bit(CS20); // Precale = 1 (ie: no prescale) + EICRA = bit(ISC01); // falling edge of INT0 generates an interrupt, they are turned off, but its an easy way for us to detect a falling edge rather than monitoring a pin + OCR2A = 0x00; + OCR2B = 0x00; + // First wait for the serial port to be available to receive + while(!(UCSR0A & (1<250) break; // this is to stop the inteface freezing if theres no disk in the drive + }; + TCNT2 = 0; // reset + while (!(PIN_READ_DATA_PORT & PIN_READ_DATA_MASK)) {}; + + EIFR |=bit(INTF0); // clear the register saying it detected an index pulse + TIFR2 |= bit(OCF2B); // clear the overflow register + OCR2B = TIMING_DD_UPPER_8us; // This is set to the upper bound. If we exceed this we must have received a load of non-flux data, this allows us to write '0000' on the PC and loop back round + + // This sets up what would be an interrupt for when the READ PIN is signalled (unfortunatly we can't choose the direction. Its just set when it changes) + // But this allows us to make sure we dont miss a bit, although the timing might be off slightly. This is mainly used when disks have very long areas of + // no flux transitions, typilcally used for copy protection + PCMSK0 = 0; + PCMSK1 = 0; + PCMSK2 = bit(PCINT20); + PCICR = bit(PCIE2); // Enable the interrupt for this pin + + // First one will just be 01010101 and is ignored by the reader anyway + register unsigned char lastDataOutput = B01010101; + do { + + // A variable to store the data we collect + register unsigned char DataOutputByte = 0; + register unsigned char counter, average; + + // format is INDEX B1 B2 Spd + + READ_UNROLLED_LOOP(B00100000, B01000000, B01100000); + average = counter; + if ((EIFR&bit(INTF0))) { + EIFR|=bit(INTF0); + DataOutputByte|= 0x80; + }; + + READ_UNROLLED_LOOP(B00001000, B00010000, B00011000); + average += counter; + average >>= 3; + UDR0 = average | DataOutputByte; + + } while (!(UCSR0A & ( 1 << RXC0 ))); + + // Read the byte that was sent to stop us, should be a 0, although we don't care + unsigned char response = UDR0; + + // We want to make sure the PC knows we've quit, and whilst this isnt fool proof its a start. + // The chance of this exact sequence coming from MFM data from the drive is slim I guess + // A little hacky, bit without woriding another pin to something we dont have any other options + writeByteToUART('X'); + writeByteToUART('Y'); + writeByteToUART('Z'); + writeByteToUART(response); + writeByteToUART('1'); + + // turn off the status LED + digitalWrite(PIN_ACTIVITY_LED,LOW); + + // Disable the counter + TCCR2B = 0; // No Clock (turn off) + EICRA = 0; // disable monitoring + PCMSK2 = 0; + PCICR = 0; + OCR2A = 0; + OCR2B = 0; +} + +// The main command loop +void loop() { + PIN_CTS_PORT &= (~PIN_CTS_MASK); // Allow data incoming + PIN_WRITE_GATE_PORT|=PIN_WRITE_GATE_MASK; // always turn writing off + + // Read the command from the PC + byte command = readByteFromUART(); + + digitalWrite(PIN_SELECT_DRIVE, LOW); + smalldelay(1); + + switch (command) { + case 'x': break; // this is ignored. It's to help 'stop streaming' mode if it gets stuck on startup + case 'M': if (!driveEnabled) sendString("Drive motor not switched on.\n"); else measureCurrentDisk(); break; + + // Command: "?" Means information about the firmware + case '?':writeByteToUART('1'); // Success + writeByteToUART('V'); // Followed + writeByteToUART('1'); // By + writeByteToUART(advancedControllerMode ? ',' : '.'); // Advanced controller version + writeByteToUART('8'); // Number + break; + + // Command "." means go back to track 0 + case '.':if (goToTrack0()) // reset + writeByteToUART('1'); + else writeByteToUART('0'); + break; + + // Command "#" means goto track. Should be formatted as #00 or #32 etc + case '#': if (gotoTrackX(false)) { + smalldelay(1); // wait for drive + writeByteToUART('1'); + } else writeByteToUART('0'); + break; + + // Command "=" means goto track. Should be formatted as =00 or =32 etc. This also reports disk change and write protect status + case '=': if (gotoTrackX(true)) { + } else writeByteToUART('0'); + break; + + case 'O': handleNoClickSeek(); + break; + + // Command "[" select LOWER disk side + case '[': digitalWrite(PIN_HEAD_SELECT,LOW); + writeByteToUART('1'); + break; + + // Command "]" select UPPER disk side + case ']': digitalWrite(PIN_HEAD_SELECT,HIGH); + writeByteToUART('1'); + break; + + // Command "{" Read data continuously from the drive until a byte is sent from the PC + case '{': if (driveEnabled) { + if(disktypeHD) + writeByteToUART('0'); // not supported + else { + writeByteToUART('1'); + readContinuousStream(); + } + } else writeByteToUART('0'); + break; + + // Command "}" Write track to the drive with precomp + case '}': if (!driveEnabled) writeByteToUART('0'); else { + if(disktypeHD) + writeByteToUART('0'); + else { + writeByteToUART('1'); + writePrecompTrack(); + } + } + break; + + // Command "<" Read track from the drive + case '<': if(!driveEnabled) writeByteToUART('0'); + else { + writeByteToUART('1'); + if(disktypeHD) + readTrackDataFast_HD(); + else + readTrackDataFast(); + } + break; + + // Command ">" Write track to the drive + case '>': if (!driveEnabled) writeByteToUART('0'); else { + if(disktypeHD) { + writeByteToUART('0'); + } else { + writeByteToUART('1'); + writeTrackFromUART(); + } + } + break; + + // Command "X" Erase current track (writes 0xAA to it) + case 'X': if (!driveEnabled) writeByteToUART('0'); else + { + writeByteToUART('1'); + if (disktypeHD) + eraseTrack_HD(); + else + eraseTrack(); + } + break; + + // Command "H" Set HD disk type + case 'H': disktypeHD = 1; + writeByteToUART('1'); + break; + + // Command "D" Set DD or SD disk type + case 'D': disktypeHD = 0; + writeByteToUART('1'); + break; + + // Turn off the drive motor + case '-': digitalWrite(PIN_WRITE_GATE,HIGH); + digitalWrite(PIN_DRIVE_ENABLE_MOTOR,HIGH); + writeByteToUART('1'); + driveEnabled = 0; + break; + + // Turn on the drive motor and setup in READ MODE, this has no delay, the computer must handle this + case '*': if (!driveEnabled) { + digitalWrite(PIN_DRIVE_ENABLE_MOTOR,LOW); + driveEnabled = 1; + } + writeByteToUART('1'); + break; + + // Turn on the drive motor and setup in READ and WRITE MODE. They both work the same now + case '+': + case '~': if (!driveEnabled) { + digitalWrite(PIN_DRIVE_ENABLE_MOTOR,LOW); + driveEnabled = 1; + smalldelay(750); // wait for drive + } + writeByteToUART('1'); + break; + + // Check write protect flag + case '$': checkWriteProtectStatus(); + break; + + // Ask if the drive is ready (has a disk in it) and if its write protected or not + case '^': testForDisk(true); + break; + + case '&': runDiagnostic(); + break; + + // We don't recognise the command! + default: + writeByteToUART('!'); // error + break; + } + + if (!driveEnabled) { + digitalWrite(PIN_SELECT_DRIVE, HIGH); + smalldelay(1); + } +} diff --git a/trunk/Arduino/FloppyDriveController.sketch/V2.6/FloppyDriveController.sketch/LICENSE.txt b/trunk/Arduino/FloppyDriveController.sketch/V2.6/FloppyDriveController.sketch/LICENSE.txt new file mode 100644 index 00000000..3d90694a --- /dev/null +++ b/trunk/Arduino/FloppyDriveController.sketch/V2.6/FloppyDriveController.sketch/LICENSE.txt @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + 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. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + 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 +. \ No newline at end of file diff --git a/trunk/Arduino/FloppyDriveController.sketch/V2.6/LICENSE.txt b/trunk/Arduino/FloppyDriveController.sketch/V2.6/LICENSE.txt new file mode 100644 index 00000000..3d90694a --- /dev/null +++ b/trunk/Arduino/FloppyDriveController.sketch/V2.6/LICENSE.txt @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + 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. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + 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 +. \ No newline at end of file diff --git a/trunk/Arduino/FloppyDriveController.sketch/V2.6/readme.txt b/trunk/Arduino/FloppyDriveController.sketch/V2.6/readme.txt new file mode 100644 index 00000000..093806ff --- /dev/null +++ b/trunk/Arduino/FloppyDriveController.sketch/V2.6/readme.txt @@ -0,0 +1,41 @@ +# Arduino Powered Amiga Floppy Disk Reader and Writer +Created by Robert Smith @RobSmithDev + +# What is it? +This project uses an Arduino to interface with a floppy disk drive and communicate with a PC in order to recover the data from Amiga formatted AmigaDOS disks. +It also allows you to write a backed up ADF file back onto a floppy disk! + +# ArduinoFloppyReader +This Visual Studio 2019 project contains two applications, a command line, and a Windows dialog based application +The commandline application can also be built under Linux + +#FloppyDriverController.sketch +This is the Ardunio source code/sketch + +# Help and Instructions +For further details including how to wire this up please visit [https://amiga.robsmithdev.co.uk] + +# Source Code +The source code for these are available on GitHub at +https://github.com/RobSmithDev/ArduinoFloppyDiskReader + +# Whats changed? +* v2.6 Fixed isues with switching between ADF and SCP where the file extension didn't automatically change + Added some extra tests and information to the diagnostics option + Firmware supports 'No-Click' within *UAE +* v2.5 A whole load of changes including: + Fixed an encoding issue which prevented disks being read under Kickstart 1.3 or lower. + Added support for read "streaming" with index sync support + Changed read timings slightly which means more disks can now be recovered! + Added support for PRECOMP disk writing to improve readability as you go past track 40 + Added some new functions which allow for more direct control of the drive +* v2.4 Improved support for Usb to Serial devices based on findings from GitHub user "prickle" - firmware is now V1.7 +* v2.33 Merged with Pull Request #9 (Detect and read out HD floppy disks 1.44M by kollokollo) - firmware is now V1.6 +* v2.32 Merged with Pull Request #6 (Modified the behavior of the current track location on Arduino boot - paulofduarte) which also addresses issues with some drives and updated firmware to 1.4 + Made a small change to the diagnostics code to also erase the track before writing it +* v2.31 Upgraded the PC code side to work with Visual Studio 2019 resolving issue #11 (ourIThome) and merging pull request #13 (bassclefstudio) + Fixed a few typos in ArduinoInterface.cpp from pull request #12 (Crkk) +* V2.2 Fixed 99% of checksum errors when writing by erasing the track first +* V2.1 Diagnostics and potential write bug fixed +* V2.0 Disk reading has been vastly improved and you can now also write disks! +* V1.0 Initial release, can read disks fairly well \ No newline at end of file diff --git a/trunk/Arduino/FloppyDriveController.sketch/promini_writer.gif b/trunk/Arduino/FloppyDriveController.sketch/promini_writer.gif new file mode 100644 index 0000000000000000000000000000000000000000..23393e8ca1f158e53af554421028f4734bca6a8f GIT binary patch literal 53313 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. +*/ + +// This file contains compile-time configurations for Grbl's internal system. For the most part, +// users will not need to directly modify these, but they are here for specific needs, i.e. +// performance tuning or adjusting to non-typical machines. + +// IMPORTANT: Any changes here requires a full re-compiling of the source code to propagate them. + +#ifndef config_h +#define config_h +#include "grbl.h" // For Arduino IDE compatibility. + + +// Define CPU pin map and default settings. +// NOTE: OEMs can avoid the need to maintain/update the defaults.h and cpu_map.h files and use only +// one configuration file by placing their specific defaults and pin map at the bottom of this file. +// If doing so, simply comment out these two defines and see instructions below. +#define DEFAULTS_GENERIC +#define CPU_MAP_ATMEGA328P // Arduino Uno CPU + +// Serial baud rate +// #define BAUD_RATE 230400 +#define BAUD_RATE 115200 + +// Define realtime command special characters. These characters are 'picked-off' directly from the +// serial read data stream and are not passed to the grbl line execution parser. Select characters +// that do not and must not exist in the streamed g-code program. ASCII control characters may be +// used, if they are available per user setup. Also, extended ASCII codes (>127), which are never in +// g-code programs, maybe selected for interface programs. +// NOTE: If changed, manually update help message in report.c. + +#define CMD_RESET 0x18 // ctrl-x. +#define CMD_STATUS_REPORT '?' +#define CMD_CYCLE_START '~' +#define CMD_FEED_HOLD '!' + +// NOTE: All override realtime commands must be in the extended ASCII character set, starting +// at character value 128 (0x80) and up to 255 (0xFF). If the normal set of realtime commands, +// such as status reports, feed hold, reset, and cycle start, are moved to the extended set +// space, serial.c's RX ISR will need to be modified to accomodate the change. +// #define CMD_RESET 0x80 +// #define CMD_STATUS_REPORT 0x81 +// #define CMD_CYCLE_START 0x82 +// #define CMD_FEED_HOLD 0x83 +#define CMD_SAFETY_DOOR 0x84 +#define CMD_JOG_CANCEL 0x85 +#define CMD_DEBUG_REPORT 0x86 // Only when DEBUG enabled, sends debug report in '{}' braces. +#define CMD_FEED_OVR_RESET 0x90 // Restores feed override value to 100%. +#define CMD_FEED_OVR_COARSE_PLUS 0x91 +#define CMD_FEED_OVR_COARSE_MINUS 0x92 +#define CMD_FEED_OVR_FINE_PLUS 0x93 +#define CMD_FEED_OVR_FINE_MINUS 0x94 +#define CMD_RAPID_OVR_RESET 0x95 // Restores rapid override value to 100%. +#define CMD_RAPID_OVR_MEDIUM 0x96 +#define CMD_RAPID_OVR_LOW 0x97 +// #define CMD_RAPID_OVR_EXTRA_LOW 0x98 // *NOT SUPPORTED* +#define CMD_SPINDLE_OVR_RESET 0x99 // Restores spindle override value to 100%. +#define CMD_SPINDLE_OVR_COARSE_PLUS 0x9A +#define CMD_SPINDLE_OVR_COARSE_MINUS 0x9B +#define CMD_SPINDLE_OVR_FINE_PLUS 0x9C +#define CMD_SPINDLE_OVR_FINE_MINUS 0x9D +#define CMD_SPINDLE_OVR_STOP 0x9E +#define CMD_COOLANT_FLOOD_OVR_TOGGLE 0xA0 +#define CMD_COOLANT_MIST_OVR_TOGGLE 0xA1 + +// If homing is enabled, homing init lock sets Grbl into an alarm state upon power up. This forces +// the user to perform the homing cycle (or override the locks) before doing anything else. This is +// mainly a safety feature to remind the user to home, since position is unknown to Grbl. +#define HOMING_INIT_LOCK // Comment to disable + +// Define the homing cycle patterns with bitmasks. The homing cycle first performs a search mode +// to quickly engage the limit switches, followed by a slower locate mode, and finished by a short +// pull-off motion to disengage the limit switches. The following HOMING_CYCLE_x defines are executed +// in order starting with suffix 0 and completes the homing routine for the specified-axes only. If +// an axis is omitted from the defines, it will not home, nor will the system update its position. +// Meaning that this allows for users with non-standard cartesian machines, such as a lathe (x then z, +// with no y), to configure the homing cycle behavior to their needs. +// NOTE: The homing cycle is designed to allow sharing of limit pins, if the axes are not in the same +// cycle, but this requires some pin settings changes in cpu_map.h file. For example, the default homing +// cycle can share the Z limit pin with either X or Y limit pins, since they are on different cycles. +// By sharing a pin, this frees up a precious IO pin for other purposes. In theory, all axes limit pins +// may be reduced to one pin, if all axes are homed with seperate cycles, or vice versa, all three axes +// on separate pin, but homed in one cycle. Also, it should be noted that the function of hard limits +// will not be affected by pin sharing. +// NOTE: Defaults are set for a traditional 3-axis CNC machine. Z-axis first to clear, followed by X & Y. +#define HOMING_CYCLE_0 (1< 3us, and, when added with the +// user-supplied step pulse time, the total time must not exceed 127us. Reported successful +// values for certain setups have ranged from 5 to 20us. +// #define STEP_PULSE_DELAY 10 // Step pulse delay in microseconds. Default disabled. + +// The number of linear motions in the planner buffer to be planned at any give time. The vast +// majority of RAM that Grbl uses is based on this buffer size. Only increase if there is extra +// available RAM, like when re-compiling for a Mega2560. Or decrease if the Arduino begins to +// crash due to the lack of available RAM or if the CPU is having trouble keeping up with planning +// new incoming motions as they are executed. +// #define BLOCK_BUFFER_SIZE 16 // Uncomment to override default in planner.h. + +// Governs the size of the intermediary step segment buffer between the step execution algorithm +// and the planner blocks. Each segment is set of steps executed at a constant velocity over a +// fixed time defined by ACCELERATION_TICKS_PER_SECOND. They are computed such that the planner +// block velocity profile is traced exactly. The size of this buffer governs how much step +// execution lead time there is for other Grbl processes have to compute and do their thing +// before having to come back and refill this buffer, currently at ~50msec of step moves. +// #define SEGMENT_BUFFER_SIZE 6 // Uncomment to override default in stepper.h. + +// Line buffer size from the serial input stream to be executed. Also, governs the size of +// each of the startup blocks, as they are each stored as a string of this size. Make sure +// to account for the available EEPROM at the defined memory address in settings.h and for +// the number of desired startup blocks. +// NOTE: 80 characters is not a problem except for extreme cases, but the line buffer size +// can be too small and g-code blocks can get truncated. Officially, the g-code standards +// support up to 256 characters. In future versions, this default will be increased, when +// we know how much extra memory space we can re-invest into this. +// #define LINE_BUFFER_SIZE 80 // Uncomment to override default in protocol.h + +// Serial send and receive buffer size. The receive buffer is often used as another streaming +// buffer to store incoming blocks to be processed by Grbl when its ready. Most streaming +// interfaces will character count and track each block send to each block response. So, +// increase the receive buffer if a deeper receive buffer is needed for streaming and avaiable +// memory allows. The send buffer primarily handles messages in Grbl. Only increase if large +// messages are sent and Grbl begins to stall, waiting to send the rest of the message. +// NOTE: Grbl generates an average status report in about 0.5msec, but the serial TX stream at +// 115200 baud will take 5 msec to transmit a typical 55 character report. Worst case reports are +// around 90-100 characters. As long as the serial TX buffer doesn't get continually maxed, Grbl +// will continue operating efficiently. Size the TX buffer around the size of a worst-case report. +// #define RX_BUFFER_SIZE 128 // (1-254) Uncomment to override defaults in serial.h +// #define TX_BUFFER_SIZE 100 // (1-254) + +// A simple software debouncing feature for hard limit switches. When enabled, the interrupt +// monitoring the hard limit switch pins will enable the Arduino's watchdog timer to re-check +// the limit pin state after a delay of about 32msec. This can help with CNC machines with +// problematic false triggering of their hard limit switches, but it WILL NOT fix issues with +// electrical interference on the signal cables from external sources. It's recommended to first +// use shielded signal cables with their shielding connected to ground (old USB/computer cables +// work well and are cheap to find) and wire in a low-pass circuit into each limit pin. +// #define ENABLE_SOFTWARE_DEBOUNCE // Default disabled. Uncomment to enable. + +// Configures the position after a probing cycle during Grbl's check mode. Disabled sets +// the position to the probe target, when enabled sets the position to the start position. +// #define SET_CHECK_MODE_PROBE_TO_START // Default disabled. Uncomment to enable. + +// Force Grbl to check the state of the hard limit switches when the processor detects a pin +// change inside the hard limit ISR routine. By default, Grbl will trigger the hard limits +// alarm upon any pin change, since bouncing switches can cause a state check like this to +// misread the pin. When hard limits are triggered, they should be 100% reliable, which is the +// reason that this option is disabled by default. Only if your system/electronics can guarantee +// that the switches don't bounce, we recommend enabling this option. This will help prevent +// triggering a hard limit when the machine disengages from the switch. +// NOTE: This option has no effect if SOFTWARE_DEBOUNCE is enabled. +// #define HARD_LIMIT_FORCE_STATE_CHECK // Default disabled. Uncomment to enable. + +// Adjusts homing cycle search and locate scalars. These are the multipliers used by Grbl's +// homing cycle to ensure the limit switches are engaged and cleared through each phase of +// the cycle. The search phase uses the axes max-travel setting times the SEARCH_SCALAR to +// determine distance to look for the limit switch. Once found, the locate phase begins and +// uses the homing pull-off distance setting times the LOCATE_SCALAR to pull-off and re-engage +// the limit switch. +// NOTE: Both of these values must be greater than 1.0 to ensure proper function. +// #define HOMING_AXIS_SEARCH_SCALAR 1.5 // Uncomment to override defaults in limits.c. +// #define HOMING_AXIS_LOCATE_SCALAR 10.0 // Uncomment to override defaults in limits.c. + +// Enable the '$RST=*', '$RST=$', and '$RST=#' eeprom restore commands. There are cases where +// these commands may be undesirable. Simply comment the desired macro to disable it. +// NOTE: See SETTINGS_RESTORE_ALL macro for customizing the `$RST=*` command. +#define ENABLE_RESTORE_EEPROM_WIPE_ALL // '$RST=*' Default enabled. Comment to disable. +#define ENABLE_RESTORE_EEPROM_DEFAULT_SETTINGS // '$RST=$' Default enabled. Comment to disable. +#define ENABLE_RESTORE_EEPROM_CLEAR_PARAMETERS // '$RST=#' Default enabled. Comment to disable. + +// Defines the EEPROM data restored upon a settings version change and `$RST=*` command. Whenever the +// the settings or other EEPROM data structure changes between Grbl versions, Grbl will automatically +// wipe and restore the EEPROM. This macro controls what data is wiped and restored. This is useful +// particularily for OEMs that need to retain certain data. For example, the BUILD_INFO string can be +// written into the Arduino EEPROM via a seperate .INO sketch to contain product data. Altering this +// macro to not restore the build info EEPROM will ensure this data is retained after firmware upgrades. +// NOTE: Uncomment to override defaults in settings.h +// #define SETTINGS_RESTORE_ALL (SETTINGS_RESTORE_DEFAULTS | SETTINGS_RESTORE_PARAMETERS | SETTINGS_RESTORE_STARTUP_LINES | SETTINGS_RESTORE_BUILD_INFO) + +// Enable the '$I=(string)' build info write command. If disabled, any existing build info data must +// be placed into EEPROM via external means with a valid checksum value. This macro option is useful +// to prevent this data from being over-written by a user, when used to store OEM product data. +// NOTE: If disabled and to ensure Grbl can never alter the build info line, you'll also need to enable +// the SETTING_RESTORE_ALL macro above and remove SETTINGS_RESTORE_BUILD_INFO from the mask. +// NOTE: See the included grblWrite_BuildInfo.ino example file to write this string seperately. +#define ENABLE_BUILD_INFO_WRITE_COMMAND // '$I=' Default enabled. Comment to disable. + +// AVR processors require all interrupts to be disabled during an EEPROM write. This includes both +// the stepper ISRs and serial comm ISRs. In the event of a long EEPROM write, this ISR pause can +// cause active stepping to lose position and serial receive data to be lost. This configuration +// option forces the planner buffer to completely empty whenever the EEPROM is written to prevent +// any chance of lost steps. +// However, this doesn't prevent issues with lost serial RX data during an EEPROM write, especially +// if a GUI is premptively filling up the serial RX buffer simultaneously. It's highly advised for +// GUIs to flag these gcodes (G10,G28.1,G30.1) to always wait for an 'ok' after a block containing +// one of these commands before sending more data to eliminate this issue. +// NOTE: Most EEPROM write commands are implicitly blocked during a job (all '$' commands). However, +// coordinate set g-code commands (G10,G28/30.1) are not, since they are part of an active streaming +// job. At this time, this option only forces a planner buffer sync with these g-code commands. +#define FORCE_BUFFER_SYNC_DURING_EEPROM_WRITE // Default enabled. Comment to disable. + +// In Grbl v0.9 and prior, there is an old outstanding bug where the `WPos:` work position reported +// may not correlate to what is executing, because `WPos:` is based on the g-code parser state, which +// can be several motions behind. This option forces the planner buffer to empty, sync, and stop +// motion whenever there is a command that alters the work coordinate offsets `G10,G43.1,G92,G54-59`. +// This is the simplest way to ensure `WPos:` is always correct. Fortunately, it's exceedingly rare +// that any of these commands are used need continuous motions through them. +#define FORCE_BUFFER_SYNC_DURING_WCO_CHANGE // Default enabled. Comment to disable. + +// By default, Grbl disables feed rate overrides for all G38.x probe cycle commands. Although this +// may be different than some pro-class machine control, it's arguable that it should be this way. +// Most probe sensors produce different levels of error that is dependent on rate of speed. By +// keeping probing cycles to their programmed feed rates, the probe sensor should be a lot more +// repeatable. If needed, you can disable this behavior by uncommenting the define below. +// #define ALLOW_FEED_OVERRIDE_DURING_PROBE_CYCLES // Default disabled. Uncomment to enable. + +// Enables and configures parking motion methods upon a safety door state. Primarily for OEMs +// that desire this feature for their integrated machines. At the moment, Grbl assumes that +// the parking motion only involves one axis, although the parking implementation was written +// to be easily refactored for any number of motions on different axes by altering the parking +// source code. At this time, Grbl only supports parking one axis (typically the Z-axis) that +// moves in the positive direction upon retracting and negative direction upon restoring position. +// The motion executes with a slow pull-out retraction motion, power-down, and a fast park. +// Restoring to the resume position follows these set motions in reverse: fast restore to +// pull-out position, power-up with a time-out, and plunge back to the original position at the +// slower pull-out rate. +// NOTE: Still a work-in-progress. Machine coordinates must be in all negative space and +// does not work with HOMING_FORCE_SET_ORIGIN enabled. Parking motion also moves only in +// positive direction. +// #define PARKING_ENABLE // Default disabled. Uncomment to enable + +// Configure options for the parking motion, if enabled. +#define PARKING_AXIS Z_AXIS // Define which axis that performs the parking motion +#define PARKING_TARGET -5.0 // Parking axis target. In mm, as machine coordinate [-max_travel,0]. +#define PARKING_RATE 500.0 // Parking fast rate after pull-out in mm/min. +#define PARKING_PULLOUT_RATE 100.0 // Pull-out/plunge slow feed rate in mm/min. +#define PARKING_PULLOUT_INCREMENT 5.0 // Spindle pull-out and plunge distance in mm. Incremental distance. + // Must be positive value or equal to zero. + +// Enables a special set of M-code commands that enables and disables the parking motion. +// These are controlled by `M56`, `M56 P1`, or `M56 Px` to enable and `M56 P0` to disable. +// The command is modal and will be set after a planner sync. Since it is g-code, it is +// executed in sync with g-code commands. It is not a real-time command. +// NOTE: PARKING_ENABLE is required. By default, M56 is active upon initialization. Use +// DEACTIVATE_PARKING_UPON_INIT to set M56 P0 as the power-up default. +// #define ENABLE_PARKING_OVERRIDE_CONTROL // Default disabled. Uncomment to enable +// #define DEACTIVATE_PARKING_UPON_INIT // Default disabled. Uncomment to enable. + +// This option will automatically disable the laser during a feed hold by invoking a spindle stop +// override immediately after coming to a stop. However, this also means that the laser still may +// be reenabled by disabling the spindle stop override, if needed. This is purely a safety feature +// to ensure the laser doesn't inadvertently remain powered while at a stop and cause a fire. +#define DISABLE_LASER_DURING_HOLD // Default enabled. Comment to disable. + +// Enables a piecewise linear model of the spindle PWM/speed output. Requires a solution by the +// 'fit_nonlinear_spindle.py' script in the /doc/script folder of the repo. See file comments +// on how to gather spindle data and run the script to generate a solution. +// #define ENABLE_PIECEWISE_LINEAR_SPINDLE // Default disabled. Uncomment to enable. + +// N_PIECES, RPM_MAX, RPM_MIN, RPM_POINTxx, and RPM_LINE_XX constants are all set and given by +// the 'fit_nonlinear_spindle.py' script solution. Used only when ENABLE_PIECEWISE_LINEAR_SPINDLE +// is enabled. Make sure the constant values are exactly the same as the script solution. +// NOTE: When N_PIECES < 4, unused RPM_LINE and RPM_POINT defines are not required and omitted. +#define N_PIECES 4 // Integer (1-4). Number of piecewise lines used in script solution. +#define RPM_MAX 11686.4 // Max RPM of model. $30 > RPM_MAX will be limited to RPM_MAX. +#define RPM_MIN 202.5 // Min RPM of model. $31 < RPM_MIN will be limited to RPM_MIN. +#define RPM_POINT12 6145.4 // Used N_PIECES >=2. Junction point between lines 1 and 2. +#define RPM_POINT23 9627.8 // Used N_PIECES >=3. Junction point between lines 2 and 3. +#define RPM_POINT34 10813.9 // Used N_PIECES = 4. Junction point between lines 3 and 4. +#define RPM_LINE_A1 3.197101e-03 // Used N_PIECES >=1. A and B constants of line 1. +#define RPM_LINE_B1 -3.526076e-1 +#define RPM_LINE_A2 1.722950e-2 // Used N_PIECES >=2. A and B constants of line 2. +#define RPM_LINE_B2 8.588176e+01 +#define RPM_LINE_A3 5.901518e-02 // Used N_PIECES >=3. A and B constants of line 3. +#define RPM_LINE_B3 4.881851e+02 +#define RPM_LINE_A4 1.203413e-01 // Used N_PIECES = 4. A and B constants of line 4. +#define RPM_LINE_B4 1.151360e+03 + + +/* --------------------------------------------------------------------------------------- + OEM Single File Configuration Option + + Instructions: Paste the cpu_map and default setting definitions below without an enclosing + #ifdef. Comment out the CPU_MAP_xxx and DEFAULT_xxx defines at the top of this file, and + the compiler will ignore the contents of defaults.h and cpu_map.h and use the definitions + below. +*/ + +// Paste CPU_MAP definitions here. + +// Paste default settings definitions here. + + +#endif diff --git a/trunk/Arduino/GRBL_1.1f/coolant_control.c b/trunk/Arduino/GRBL_1.1f/coolant_control.c new file mode 100644 index 00000000..1eebfc0c --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f/coolant_control.c @@ -0,0 +1,126 @@ +/* + coolant_control.c - coolant control methods + Part of Grbl + + Copyright (c) 2012-2016 Sungeun K. Jeon for Gnea Research LLC + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +#include "grbl.h" + + +void coolant_init() +{ + COOLANT_FLOOD_DDR |= (1 << COOLANT_FLOOD_BIT); // Configure as output pin + #ifdef ENABLE_M7 + COOLANT_MIST_DDR |= (1 << COOLANT_MIST_BIT); + #endif + coolant_stop(); +} + + +// Returns current coolant output state. Overrides may alter it from programmed state. +uint8_t coolant_get_state() +{ + uint8_t cl_state = COOLANT_STATE_DISABLE; + #ifdef INVERT_COOLANT_FLOOD_PIN + if (bit_isfalse(COOLANT_FLOOD_PORT,(1 << COOLANT_FLOOD_BIT))) { + #else + if (bit_istrue(COOLANT_FLOOD_PORT,(1 << COOLANT_FLOOD_BIT))) { + #endif + cl_state |= COOLANT_STATE_FLOOD; + } + #ifdef ENABLE_M7 + #ifdef INVERT_COOLANT_MIST_PIN + if (bit_isfalse(COOLANT_MIST_PORT,(1 << COOLANT_MIST_BIT))) { + #else + if (bit_istrue(COOLANT_MIST_PORT,(1 << COOLANT_MIST_BIT))) { + #endif + cl_state |= COOLANT_STATE_MIST; + } + #endif + return(cl_state); +} + + +// Directly called by coolant_init(), coolant_set_state(), and mc_reset(), which can be at +// an interrupt-level. No report flag set, but only called by routines that don't need it. +void coolant_stop() +{ + #ifdef INVERT_COOLANT_FLOOD_PIN + COOLANT_FLOOD_PORT |= (1 << COOLANT_FLOOD_BIT); + #else + COOLANT_FLOOD_PORT &= ~(1 << COOLANT_FLOOD_BIT); + #endif + #ifdef ENABLE_M7 + #ifdef INVERT_COOLANT_MIST_PIN + COOLANT_MIST_PORT |= (1 << COOLANT_MIST_BIT); + #else + COOLANT_MIST_PORT &= ~(1 << COOLANT_MIST_BIT); + #endif + #endif +} + + +// Main program only. Immediately sets flood coolant running state and also mist coolant, +// if enabled. Also sets a flag to report an update to a coolant state. +// Called by coolant toggle override, parking restore, parking retract, sleep mode, g-code +// parser program end, and g-code parser coolant_sync(). +void coolant_set_state(uint8_t mode) +{ + if (sys.abort) { return; } // Block during abort. + + if (mode & COOLANT_FLOOD_ENABLE) { + #ifdef INVERT_COOLANT_FLOOD_PIN + COOLANT_FLOOD_PORT &= ~(1 << COOLANT_FLOOD_BIT); + #else + COOLANT_FLOOD_PORT |= (1 << COOLANT_FLOOD_BIT); + #endif + } else { + #ifdef INVERT_COOLANT_FLOOD_PIN + COOLANT_FLOOD_PORT |= (1 << COOLANT_FLOOD_BIT); + #else + COOLANT_FLOOD_PORT &= ~(1 << COOLANT_FLOOD_BIT); + #endif + } + + #ifdef ENABLE_M7 + if (mode & COOLANT_MIST_ENABLE) { + #ifdef INVERT_COOLANT_MIST_PIN + COOLANT_MIST_PORT &= ~(1 << COOLANT_MIST_BIT); + #else + COOLANT_MIST_PORT |= (1 << COOLANT_MIST_BIT); + #endif + } else { + #ifdef INVERT_COOLANT_MIST_PIN + COOLANT_MIST_PORT |= (1 << COOLANT_MIST_BIT); + #else + COOLANT_MIST_PORT &= ~(1 << COOLANT_MIST_BIT); + #endif + } + #endif + + sys.report_ovr_counter = 0; // Set to report change immediately +} + + +// G-code parser entry-point for setting coolant state. Forces a planner buffer sync and bails +// if an abort or check-mode is active. +void coolant_sync(uint8_t mode) +{ + if (sys.state == STATE_CHECK_MODE) { return; } + protocol_buffer_synchronize(); // Ensure coolant turns on when specified in program. + coolant_set_state(mode); +} diff --git a/trunk/Arduino/GRBL_1.1f/coolant_control.h b/trunk/Arduino/GRBL_1.1f/coolant_control.h new file mode 100644 index 00000000..49b85f00 --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f/coolant_control.h @@ -0,0 +1,47 @@ +/* + coolant_control.h - spindle control methods + Part of Grbl + + Copyright (c) 2012-2016 Sungeun K. Jeon for Gnea Research LLC + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +#ifndef coolant_control_h +#define coolant_control_h + +#define COOLANT_NO_SYNC false +#define COOLANT_FORCE_SYNC true + +#define COOLANT_STATE_DISABLE 0 // Must be zero +#define COOLANT_STATE_FLOOD PL_COND_FLAG_COOLANT_FLOOD +#define COOLANT_STATE_MIST PL_COND_FLAG_COOLANT_MIST + + +// Initializes coolant control pins. +void coolant_init(); + +// Returns current coolant output state. Overrides may alter it from programmed state. +uint8_t coolant_get_state(); + +// Immediately disables coolant pins. +void coolant_stop(); + +// Sets the coolant pins according to state specified. +void coolant_set_state(uint8_t mode); + +// G-code parser entry-point for setting coolant states. Checks for and executes additional conditions. +void coolant_sync(uint8_t mode); + +#endif diff --git a/trunk/Arduino/GRBL_1.1f/cpu_map.h b/trunk/Arduino/GRBL_1.1f/cpu_map.h new file mode 100644 index 00000000..0e2b25e5 --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f/cpu_map.h @@ -0,0 +1,160 @@ +/* + cpu_map.h - CPU and pin mapping configuration file + Part of Grbl + + Copyright (c) 2012-2016 Sungeun K. Jeon for Gnea Research LLC + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +/* The cpu_map.h files serve as a central pin mapping selection file for different + processor types or alternative pin layouts. This version of Grbl officially supports + only the Arduino Mega328p. */ + + +#ifndef cpu_map_h +#define cpu_map_h + + +#ifdef CPU_MAP_ATMEGA328P // (Arduino Uno) Officially supported by Grbl. + + // Define serial port pins and interrupt vectors. + #define SERIAL_RX USART_RX_vect + #define SERIAL_UDRE USART_UDRE_vect + + // Define step pulse output pins. NOTE: All step bit pins must be on the same port. + #define STEP_DDR DDRD + #define STEP_PORT PORTD + #define X_STEP_BIT 2 // Uno Digital Pin 2 + #define Y_STEP_BIT 3 // Uno Digital Pin 3 + #define Z_STEP_BIT 4 // Uno Digital Pin 4 + #define STEP_MASK ((1< 62.5kHz + // #define SPINDLE_TCCRB_INIT_MASK (1< 7.8kHz (Used in v0.9) + // #define SPINDLE_TCCRB_INIT_MASK ((1< 1.96kHz + #define SPINDLE_TCCRB_INIT_MASK (1< 0.98kHz (J-tech laser) + + // NOTE: On the 328p, these must be the same as the SPINDLE_ENABLE settings. + #define SPINDLE_PWM_DDR DDRB + #define SPINDLE_PWM_PORT PORTB + #define SPINDLE_PWM_BIT 3 // Uno Digital Pin 11 + +#endif + +/* +#ifdef CPU_MAP_CUSTOM_PROC + // For a custom pin map or different processor, copy and edit one of the available cpu + // map files and modify it to your needs. Make sure the defined name is also changed in + // the config.h file. +#endif +*/ + +#endif diff --git a/trunk/Arduino/GRBL_1.1f/defaults.h b/trunk/Arduino/GRBL_1.1f/defaults.h new file mode 100644 index 00000000..dbbbb934 --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f/defaults.h @@ -0,0 +1,493 @@ +/* + defaults.h - defaults settings configuration file + Part of Grbl + + Copyright (c) 2012-2016 Sungeun K. Jeon for Gnea Research LLC + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +/* The defaults.h file serves as a central default settings selector for different machine + types, from DIY CNC mills to CNC conversions of off-the-shelf machines. The settings + files listed here are supplied by users, so your results may vary. However, this should + give you a good starting point as you get to know your machine and tweak the settings for + your nefarious needs. + NOTE: Ensure one and only one of these DEFAULTS_XXX values is defined in config.h */ + +#ifndef defaults_h + +#ifdef DEFAULTS_GENERIC + // Grbl generic default settings. Should work across different machines. + #define DEFAULT_X_STEPS_PER_MM 250.0 + #define DEFAULT_Y_STEPS_PER_MM 250.0 + #define DEFAULT_Z_STEPS_PER_MM 250.0 + #define DEFAULT_X_MAX_RATE 500.0 // mm/min + #define DEFAULT_Y_MAX_RATE 500.0 // mm/min + #define DEFAULT_Z_MAX_RATE 500.0 // mm/min + #define DEFAULT_X_ACCELERATION (10.0*60*60) // 10*60*60 mm/min^2 = 10 mm/sec^2 + #define DEFAULT_Y_ACCELERATION (10.0*60*60) // 10*60*60 mm/min^2 = 10 mm/sec^2 + #define DEFAULT_Z_ACCELERATION (10.0*60*60) // 10*60*60 mm/min^2 = 10 mm/sec^2 + #define DEFAULT_X_MAX_TRAVEL 200.0 // mm NOTE: Must be a positive value. + #define DEFAULT_Y_MAX_TRAVEL 200.0 // mm NOTE: Must be a positive value. + #define DEFAULT_Z_MAX_TRAVEL 200.0 // mm NOTE: Must be a positive value. + #define DEFAULT_SPINDLE_RPM_MAX 1000.0 // rpm + #define DEFAULT_SPINDLE_RPM_MIN 0.0 // rpm + #define DEFAULT_STEP_PULSE_MICROSECONDS 10 + #define DEFAULT_STEPPING_INVERT_MASK 0 + #define DEFAULT_DIRECTION_INVERT_MASK 0 + #define DEFAULT_STEPPER_IDLE_LOCK_TIME 25 // msec (0-254, 255 keeps steppers enabled) + #define DEFAULT_STATUS_REPORT_MASK 1 // MPos enabled + #define DEFAULT_JUNCTION_DEVIATION 0.01 // mm + #define DEFAULT_ARC_TOLERANCE 0.002 // mm + #define DEFAULT_REPORT_INCHES 0 // false + #define DEFAULT_INVERT_ST_ENABLE 0 // false + #define DEFAULT_INVERT_LIMIT_PINS 0 // false + #define DEFAULT_SOFT_LIMIT_ENABLE 0 // false + #define DEFAULT_HARD_LIMIT_ENABLE 0 // false + #define DEFAULT_INVERT_PROBE_PIN 0 // false + #define DEFAULT_LASER_MODE 0 // false + #define DEFAULT_HOMING_ENABLE 0 // false + #define DEFAULT_HOMING_DIR_MASK 0 // move positive dir + #define DEFAULT_HOMING_FEED_RATE 25.0 // mm/min + #define DEFAULT_HOMING_SEEK_RATE 500.0 // mm/min + #define DEFAULT_HOMING_DEBOUNCE_DELAY 250 // msec (0-65k) + #define DEFAULT_HOMING_PULLOFF 1.0 // mm +#endif + +#ifdef DEFAULTS_SHERLINE_5400 + // Description: Sherline 5400 mill with three NEMA 23 Keling KL23H256-21-8B 185 oz-in stepper motors, + // driven by three Pololu A4988 stepper drivers with a 30V, 6A power supply at 1.5A per winding. + #define MICROSTEPS 2 + #define STEPS_PER_REV 200.0 + #define MM_PER_REV (0.050*MM_PER_INCH) // 0.050 inch/rev leadscrew + #define DEFAULT_X_STEPS_PER_MM (STEPS_PER_REV*MICROSTEPS/MM_PER_REV) + #define DEFAULT_Y_STEPS_PER_MM (STEPS_PER_REV*MICROSTEPS/MM_PER_REV) + #define DEFAULT_Z_STEPS_PER_MM (STEPS_PER_REV*MICROSTEPS/MM_PER_REV) + #define DEFAULT_X_MAX_RATE 635.0 // mm/min (25 ipm) + #define DEFAULT_Y_MAX_RATE 635.0 // mm/min + #define DEFAULT_Z_MAX_RATE 635.0 // mm/min + #define DEFAULT_X_ACCELERATION (50.0*60*60) // 50*60*60 mm/min^2 = 50 mm/sec^2 + #define DEFAULT_Y_ACCELERATION (50.0*60*60) // 50*60*60 mm/min^2 = 50 mm/sec^2 + #define DEFAULT_Z_ACCELERATION (50.0*60*60) // 50*60*60 mm/min^2 = 50 mm/sec^2 + #define DEFAULT_X_MAX_TRAVEL 225.0 // mm NOTE: Must be a positive value. + #define DEFAULT_Y_MAX_TRAVEL 125.0 // mm NOTE: Must be a positive value. + #define DEFAULT_Z_MAX_TRAVEL 170.0 // mm NOTE: Must be a positive value. + #define DEFAULT_SPINDLE_RPM_MAX 2800.0 // rpm + #define DEFAULT_SPINDLE_RPM_MIN 0.0 // rpm + #define DEFAULT_STEP_PULSE_MICROSECONDS 10 + #define DEFAULT_STEPPING_INVERT_MASK 0 + #define DEFAULT_DIRECTION_INVERT_MASK ((1< +#include + +/* These EEPROM bits have different names on different devices. */ +#ifndef EEPE + #define EEPE EEWE //!< EEPROM program/write enable. + #define EEMPE EEMWE //!< EEPROM master program/write enable. +#endif + +/* These two are unfortunately not defined in the device include files. */ +#define EEPM1 5 //!< EEPROM Programming Mode Bit 1. +#define EEPM0 4 //!< EEPROM Programming Mode Bit 0. + +/* Define to reduce code size. */ +#define EEPROM_IGNORE_SELFPROG //!< Remove SPM flag polling. + +/*! \brief Read byte from EEPROM. + * + * This function reads one byte from a given EEPROM address. + * + * \note The CPU is halted for 4 clock cycles during EEPROM read. + * + * \param addr EEPROM address to read from. + * \return The byte read from the EEPROM address. + */ +unsigned char eeprom_get_char( unsigned int addr ) +{ + do {} while( EECR & (1< 0; size--) { + checksum = (checksum << 1) || (checksum >> 7); + checksum += *source; + eeprom_put_char(destination++, *(source++)); + } + eeprom_put_char(destination, checksum); +} + +int memcpy_from_eeprom_with_checksum(char *destination, unsigned int source, unsigned int size) { + unsigned char data, checksum = 0; + for(; size > 0; size--) { + data = eeprom_get_char(source++); + checksum = (checksum << 1) || (checksum >> 7); + checksum += data; + *(destination++) = data; + } + return(checksum == eeprom_get_char(source)); +} + +// end of file diff --git a/trunk/Arduino/GRBL_1.1f/eeprom.h b/trunk/Arduino/GRBL_1.1f/eeprom.h new file mode 100644 index 00000000..c9718a2b --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f/eeprom.h @@ -0,0 +1,29 @@ +/* + eeprom.h - EEPROM methods + Part of Grbl + + Copyright (c) 2009-2011 Simen Svale Skogsrud + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +#ifndef eeprom_h +#define eeprom_h + +unsigned char eeprom_get_char(unsigned int addr); +void eeprom_put_char(unsigned int addr, unsigned char new_value); +void memcpy_to_eeprom_with_checksum(unsigned int destination, char *source, unsigned int size); +int memcpy_from_eeprom_with_checksum(char *destination, unsigned int source, unsigned int size); + +#endif diff --git a/trunk/Arduino/GRBL_1.1f/examples/grblUpload/grblUpload.ino b/trunk/Arduino/GRBL_1.1f/examples/grblUpload/grblUpload.ino new file mode 100644 index 00000000..581b6b3d --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f/examples/grblUpload/grblUpload.ino @@ -0,0 +1,29 @@ +/*********************************************************************** +This sketch compiles and uploads Grbl to your 328p-based Arduino! + +To use: +- First make sure you have imported Grbl source code into your Arduino + IDE. There are details on our Github website on how to do this. + +- Select your Arduino Board and Serial Port in the Tools drop-down menu. + NOTE: Grbl only officially supports 328p-based Arduinos, like the Uno. + Using other boards will likely not work! + +- Then just click 'Upload'. That's it! + +For advanced users: + If you'd like to see what else Grbl can do, there are some additional + options for customization and features you can enable or disable. + Navigate your file system to where the Arduino IDE has stored the Grbl + source code files, open the 'config.h' file in your favorite text + editor. Inside are dozens of feature descriptions and #defines. Simply + comment or uncomment the #defines or alter their assigned values, save + your changes, and then click 'Upload' here. + +Copyright (c) 2015 Sungeun K. Jeon +Released under the MIT-license. See license.txt for details. +***********************************************************************/ + +#include + +// Do not alter this file! diff --git a/trunk/Arduino/GRBL_1.1f/examples/grblUpload/license.txt b/trunk/Arduino/GRBL_1.1f/examples/grblUpload/license.txt new file mode 100644 index 00000000..1abcdb95 --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f/examples/grblUpload/license.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015 Sungeun K. Jeon + +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. \ No newline at end of file diff --git a/trunk/Arduino/GRBL_1.1f/examples/grblWrite_BuildInfo/grblWrite_BuildInfo.ino b/trunk/Arduino/GRBL_1.1f/examples/grblWrite_BuildInfo/grblWrite_BuildInfo.ino new file mode 100644 index 00000000..2759d474 --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f/examples/grblWrite_BuildInfo/grblWrite_BuildInfo.ino @@ -0,0 +1,109 @@ +/*********************************************************************** +This sketch writes a `$I` build info string directly into Arduino EEPROM + +To use: +- Just alter the "build_info_line" string to whatever you'd like. Then + compile and upload this sketch to your Arduino. + +- If your Arduino is blinking slowly, your string has already been + written to your EEPROM and been verified by checksums! That's it! + +- If you Arduino LED is blinking fast, something went wrong and the + checksums don't match. You can optionally connect to the Arduino via + the serial monitor, and the sketch will show what its doing. + +NOTE: This sketch is provided as a tool template for OEMs who may need +to restrict users from altering their build info, so they can place +important product information here when enabling the restriction. + +NOTE: When uploading Grbl to the Arduino with this sketch on it, make +sure you see the slow blink before you start the upload process. This +ensures you aren't flashing Grbl when it's in mid-write of the EEPROM. + +Copyright (c) 2016 Sungeun K. Jeon for Gnea Research LLC +Released under the MIT-license. See license.txt for details. +***********************************************************************/ + +#include +#include + +#define SERIAL_BAUD_RATE 115200 +#define LINE_LENGTH 80U // Grbl line length +#define BYTE_LOCATION 942U // Grbl build info EEPROM address. + + +// ----- CHANGE THIS LINE ----- + +char build_info_line[LINE_LENGTH] = "Testing123."; + +// ----------------------------- + + +uint8_t status = false; +int ledPin = 13; // LED connected to digital pin 13 + +void setup() { + Serial.begin(SERIAL_BAUD_RATE); + delay(500); + + uint32_t address = BYTE_LOCATION; + uint32_t size = LINE_LENGTH; + char *write_pointer = (char*)build_info_line; + uint8_t write_checksum = 0; + for (; size>0; size--) { + write_checksum = (write_checksum << 1) || (write_checksum >> 7); + write_checksum += *write_pointer; + EEPROM.put(address++, *(write_pointer++)); + } + EEPROM.put(address,write_checksum); + + Serial.print(F("-> Writing line to EEPROM: '")); + Serial.print(build_info_line); + Serial.print(F("'\n\r-> Write checksum: ")); + Serial.println(write_checksum,DEC); + + size = LINE_LENGTH; + address = BYTE_LOCATION; + uint8_t data = 0; + char read_line[LINE_LENGTH]; + char *read_pointer = (char*)read_line; + uint8_t read_checksum = 0; + uint8_t stored_checksum = 0; + for(; size > 0; size--) { + data = EEPROM.read(address++); + read_checksum = (read_checksum << 1) || (read_checksum >> 7); + read_checksum += data; + *(read_pointer++) = data; + } + stored_checksum = EEPROM.read(address); + + Serial.print(F("<- Reading line from EEPROM: '")); + Serial.print(read_line); + Serial.print("'\n\r<- Read checksum: "); + Serial.println(read_checksum,DEC); + + if ((read_checksum == write_checksum) && (read_checksum == stored_checksum)) { + status = true; + Serial.print(F("SUCCESS! All checksums match!\r\n")); + } else { + if (write_checksum != stored_checksum) { + Serial.println(F("ERROR! Write and stored EEPROM checksums don't match!")); + } else { + Serial.println(F("ERROR! Read and stored checksums don't match!")); + } + } + pinMode(ledPin, OUTPUT); // sets the digital pin as output +} + +void loop() { + // Blink to let user know EEPROM write status. + // Slow blink is 'ok'. Fast blink is an 'error'. + digitalWrite(ledPin, HIGH); // sets the LED on + if (status) { delay(1500); } // Slow blink + else { delay(100); } // Rapid blink + digitalWrite(ledPin, LOW); // sets the LED off + if (status) { delay(1500); } + else { delay(100); } +} + + diff --git a/trunk/Arduino/GRBL_1.1f/examples/grblWrite_BuildInfo/license.txt b/trunk/Arduino/GRBL_1.1f/examples/grblWrite_BuildInfo/license.txt new file mode 100644 index 00000000..0da8f39f --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f/examples/grblWrite_BuildInfo/license.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Sungeun K. Jeon for Gnea Research 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. \ No newline at end of file diff --git a/trunk/Arduino/GRBL_1.1f/gcode.c b/trunk/Arduino/GRBL_1.1f/gcode.c new file mode 100644 index 00000000..13ebbee4 --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f/gcode.c @@ -0,0 +1,1159 @@ +/* + gcode.c - rs274/ngc parser. + Part of Grbl + + Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC + Copyright (c) 2009-2011 Simen Svale Skogsrud + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +#include "grbl.h" + +// NOTE: Max line number is defined by the g-code standard to be 99999. It seems to be an +// arbitrary value, and some GUIs may require more. So we increased it based on a max safe +// value when converting a float (7.2 digit precision)s to an integer. +#define MAX_LINE_NUMBER 10000000 +#define MAX_TOOL_NUMBER 255 // Limited by max unsigned 8-bit value + +#define AXIS_COMMAND_NONE 0 +#define AXIS_COMMAND_NON_MODAL 1 +#define AXIS_COMMAND_MOTION_MODE 2 +#define AXIS_COMMAND_TOOL_LENGTH_OFFSET 3 // *Undefined but required + +// Declare gc extern struct +parser_state_t gc_state; +parser_block_t gc_block; + +#define FAIL(status) return(status); + + +void gc_init() +{ + memset(&gc_state, 0, sizeof(parser_state_t)); + + // Load default G54 coordinate system. + if (!(settings_read_coord_data(gc_state.modal.coord_select,gc_state.coord_system))) { + report_status_message(STATUS_SETTING_READ_FAIL); + } +} + + +// Sets g-code parser position in mm. Input in steps. Called by the system abort and hard +// limit pull-off routines. +void gc_sync_position() +{ + system_convert_array_steps_to_mpos(gc_state.position,sys_position); +} + + +// Executes one line of 0-terminated G-Code. The line is assumed to contain only uppercase +// characters and signed floating point values (no whitespace). Comments and block delete +// characters have been removed. In this function, all units and positions are converted and +// exported to grbl's internal functions in terms of (mm, mm/min) and absolute machine +// coordinates, respectively. +uint8_t gc_execute_line(char *line) +{ + /* ------------------------------------------------------------------------------------- + STEP 1: Initialize parser block struct and copy current g-code state modes. The parser + updates these modes and commands as the block line is parser and will only be used and + executed after successful error-checking. The parser block struct also contains a block + values struct, word tracking variables, and a non-modal commands tracker for the new + block. This struct contains all of the necessary information to execute the block. */ + + memset(&gc_block, 0, sizeof(parser_block_t)); // Initialize the parser block struct. + memcpy(&gc_block.modal,&gc_state.modal,sizeof(gc_modal_t)); // Copy current modes + + uint8_t axis_command = AXIS_COMMAND_NONE; + uint8_t axis_0, axis_1, axis_linear; + uint8_t coord_select = 0; // Tracks G10 P coordinate selection for execution + + // Initialize bitflag tracking variables for axis indices compatible operations. + uint8_t axis_words = 0; // XYZ tracking + uint8_t ijk_words = 0; // IJK tracking + + // Initialize command and value words and parser flags variables. + uint16_t command_words = 0; // Tracks G and M command words. Also used for modal group violations. + uint16_t value_words = 0; // Tracks value words. + uint8_t gc_parser_flags = GC_PARSER_NONE; + + // Determine if the line is a jogging motion or a normal g-code block. + if (line[0] == '$') { // NOTE: `$J=` already parsed when passed to this function. + // Set G1 and G94 enforced modes to ensure accurate error checks. + gc_parser_flags |= GC_PARSER_JOG_MOTION; + gc_block.modal.motion = MOTION_MODE_LINEAR; + gc_block.modal.feed_rate = FEED_RATE_MODE_UNITS_PER_MIN; + #ifdef USE_LINE_NUMBERS + gc_block.values.n = JOG_LINE_NUMBER; // Initialize default line number reported during jog. + #endif + } + + /* ------------------------------------------------------------------------------------- + STEP 2: Import all g-code words in the block line. A g-code word is a letter followed by + a number, which can either be a 'G'/'M' command or sets/assigns a command value. Also, + perform initial error-checks for command word modal group violations, for any repeated + words, and for negative values set for the value words F, N, P, T, and S. */ + + uint8_t word_bit; // Bit-value for assigning tracking variables + uint8_t char_counter; + char letter; + float value; + uint8_t int_value = 0; + uint16_t mantissa = 0; + if (gc_parser_flags & GC_PARSER_JOG_MOTION) { char_counter = 3; } // Start parsing after `$J=` + else { char_counter = 0; } + + while (line[char_counter] != 0) { // Loop until no more g-code words in line. + + // Import the next g-code word, expecting a letter followed by a value. Otherwise, error out. + letter = line[char_counter]; + if((letter < 'A') || (letter > 'Z')) { FAIL(STATUS_EXPECTED_COMMAND_LETTER); } // [Expected word letter] + char_counter++; + if (!read_float(line, &char_counter, &value)) { FAIL(STATUS_BAD_NUMBER_FORMAT); } // [Expected word value] + + // Convert values to smaller uint8 significand and mantissa values for parsing this word. + // NOTE: Mantissa is multiplied by 100 to catch non-integer command values. This is more + // accurate than the NIST gcode requirement of x10 when used for commands, but not quite + // accurate enough for value words that require integers to within 0.0001. This should be + // a good enough comprimise and catch most all non-integer errors. To make it compliant, + // we would simply need to change the mantissa to int16, but this add compiled flash space. + // Maybe update this later. + int_value = trunc(value); + mantissa = round(100*(value - int_value)); // Compute mantissa for Gxx.x commands. + // NOTE: Rounding must be used to catch small floating point errors. + + // Check if the g-code word is supported or errors due to modal group violations or has + // been repeated in the g-code block. If ok, update the command or record its value. + switch(letter) { + + /* 'G' and 'M' Command Words: Parse commands and check for modal group violations. + NOTE: Modal group numbers are defined in Table 4 of NIST RS274-NGC v3, pg.20 */ + + case 'G': + // Determine 'G' command and its modal group + switch(int_value) { + case 10: case 28: case 30: case 92: + // Check for G10/28/30/92 being called with G0/1/2/3/38 on same block. + // * G43.1 is also an axis command but is not explicitly defined this way. + if (mantissa == 0) { // Ignore G28.1, G30.1, and G92.1 + if (axis_command) { FAIL(STATUS_GCODE_AXIS_COMMAND_CONFLICT); } // [Axis word/command conflict] + axis_command = AXIS_COMMAND_NON_MODAL; + } + // No break. Continues to next line. + case 4: case 53: + word_bit = MODAL_GROUP_G0; + gc_block.non_modal_command = int_value; + if ((int_value == 28) || (int_value == 30) || (int_value == 92)) { + if (!((mantissa == 0) || (mantissa == 10))) { FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); } + gc_block.non_modal_command += mantissa; + mantissa = 0; // Set to zero to indicate valid non-integer G command. + } + break; + case 0: case 1: case 2: case 3: case 38: + // Check for G0/1/2/3/38 being called with G10/28/30/92 on same block. + // * G43.1 is also an axis command but is not explicitly defined this way. + if (axis_command) { FAIL(STATUS_GCODE_AXIS_COMMAND_CONFLICT); } // [Axis word/command conflict] + axis_command = AXIS_COMMAND_MOTION_MODE; + // No break. Continues to next line. + case 80: + word_bit = MODAL_GROUP_G1; + gc_block.modal.motion = int_value; + if (int_value == 38){ + if (!((mantissa == 20) || (mantissa == 30) || (mantissa == 40) || (mantissa == 50))) { + FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); // [Unsupported G38.x command] + } + gc_block.modal.motion += (mantissa/10)+100; + mantissa = 0; // Set to zero to indicate valid non-integer G command. + } + break; + case 17: case 18: case 19: + word_bit = MODAL_GROUP_G2; + gc_block.modal.plane_select = int_value - 17; + break; + case 90: case 91: + if (mantissa == 0) { + word_bit = MODAL_GROUP_G3; + gc_block.modal.distance = int_value - 90; + } else { + word_bit = MODAL_GROUP_G4; + if ((mantissa != 10) || (int_value == 90)) { FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); } // [G90.1 not supported] + mantissa = 0; // Set to zero to indicate valid non-integer G command. + // Otherwise, arc IJK incremental mode is default. G91.1 does nothing. + } + break; + case 93: case 94: + word_bit = MODAL_GROUP_G5; + gc_block.modal.feed_rate = 94 - int_value; + break; + case 20: case 21: + word_bit = MODAL_GROUP_G6; + gc_block.modal.units = 21 - int_value; + break; + case 40: + word_bit = MODAL_GROUP_G7; + // NOTE: Not required since cutter radius compensation is always disabled. Only here + // to support G40 commands that often appear in g-code program headers to setup defaults. + // gc_block.modal.cutter_comp = CUTTER_COMP_DISABLE; // G40 + break; + case 43: case 49: + word_bit = MODAL_GROUP_G8; + // NOTE: The NIST g-code standard vaguely states that when a tool length offset is changed, + // there cannot be any axis motion or coordinate offsets updated. Meaning G43, G43.1, and G49 + // all are explicit axis commands, regardless if they require axis words or not. + if (axis_command) { FAIL(STATUS_GCODE_AXIS_COMMAND_CONFLICT); } // [Axis word/command conflict] } + axis_command = AXIS_COMMAND_TOOL_LENGTH_OFFSET; + if (int_value == 49) { // G49 + gc_block.modal.tool_length = TOOL_LENGTH_OFFSET_CANCEL; + } else if (mantissa == 10) { // G43.1 + gc_block.modal.tool_length = TOOL_LENGTH_OFFSET_ENABLE_DYNAMIC; + } else { FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); } // [Unsupported G43.x command] + mantissa = 0; // Set to zero to indicate valid non-integer G command. + break; + case 54: case 55: case 56: case 57: case 58: case 59: + // NOTE: G59.x are not supported. (But their int_values would be 60, 61, and 62.) + word_bit = MODAL_GROUP_G12; + gc_block.modal.coord_select = int_value - 54; // Shift to array indexing. + break; + case 61: + word_bit = MODAL_GROUP_G13; + if (mantissa != 0) { FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); } // [G61.1 not supported] + // gc_block.modal.control = CONTROL_MODE_EXACT_PATH; // G61 + break; + default: FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); // [Unsupported G command] + } + if (mantissa > 0) { FAIL(STATUS_GCODE_COMMAND_VALUE_NOT_INTEGER); } // [Unsupported or invalid Gxx.x command] + // Check for more than one command per modal group violations in the current block + // NOTE: Variable 'word_bit' is always assigned, if the command is valid. + if ( bit_istrue(command_words,bit(word_bit)) ) { FAIL(STATUS_GCODE_MODAL_GROUP_VIOLATION); } + command_words |= bit(word_bit); + break; + + case 'M': + + // Determine 'M' command and its modal group + if (mantissa > 0) { FAIL(STATUS_GCODE_COMMAND_VALUE_NOT_INTEGER); } // [No Mxx.x commands] + switch(int_value) { + case 0: case 1: case 2: case 30: + word_bit = MODAL_GROUP_M4; + switch(int_value) { + case 0: gc_block.modal.program_flow = PROGRAM_FLOW_PAUSED; break; // Program pause + case 1: break; // Optional stop not supported. Ignore. + default: gc_block.modal.program_flow = int_value; // Program end and reset + } + break; + case 3: case 4: case 5: + word_bit = MODAL_GROUP_M7; + switch(int_value) { + case 3: gc_block.modal.spindle = SPINDLE_ENABLE_CW; break; + case 4: gc_block.modal.spindle = SPINDLE_ENABLE_CCW; break; + case 5: gc_block.modal.spindle = SPINDLE_DISABLE; break; + } + break; + #ifdef ENABLE_M7 + case 7: case 8: case 9: + #else + case 8: case 9: + #endif + word_bit = MODAL_GROUP_M8; + switch(int_value) { + #ifdef ENABLE_M7 + case 7: gc_block.modal.coolant |= COOLANT_MIST_ENABLE; break; + #endif + case 8: gc_block.modal.coolant |= COOLANT_FLOOD_ENABLE; break; + case 9: gc_block.modal.coolant = COOLANT_DISABLE; break; // M9 disables both M7 and M8. + } + break; + #ifdef ENABLE_PARKING_OVERRIDE_CONTROL + case 56: + word_bit = MODAL_GROUP_M9; + gc_block.modal.override = OVERRIDE_PARKING_MOTION; + break; + #endif + default: FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); // [Unsupported M command] + } + + // Check for more than one command per modal group violations in the current block + // NOTE: Variable 'word_bit' is always assigned, if the command is valid. + if ( bit_istrue(command_words,bit(word_bit)) ) { FAIL(STATUS_GCODE_MODAL_GROUP_VIOLATION); } + command_words |= bit(word_bit); + break; + + // NOTE: All remaining letters assign values. + default: + + /* Non-Command Words: This initial parsing phase only checks for repeats of the remaining + legal g-code words and stores their value. Error-checking is performed later since some + words (I,J,K,L,P,R) have multiple connotations and/or depend on the issued commands. */ + switch(letter){ + // case 'A': // Not supported + // case 'B': // Not supported + // case 'C': // Not supported + // case 'D': // Not supported + case 'F': word_bit = WORD_F; gc_block.values.f = value; break; + // case 'H': // Not supported + case 'I': word_bit = WORD_I; gc_block.values.ijk[X_AXIS] = value; ijk_words |= (1< MAX_TOOL_NUMBER) { FAIL(STATUS_GCODE_MAX_VALUE_EXCEEDED); } + gc_block.values.t = int_value; + break; + case 'X': word_bit = WORD_X; gc_block.values.xyz[X_AXIS] = value; axis_words |= (1< MAX_LINE_NUMBER) { FAIL(STATUS_GCODE_INVALID_LINE_NUMBER); } // [Exceeds max line number] + } + // bit_false(value_words,bit(WORD_N)); // NOTE: Single-meaning value word. Set at end of error-checking. + + // Track for unused words at the end of error-checking. + // NOTE: Single-meaning value words are removed all at once at the end of error-checking, because + // they are always used when present. This was done to save a few bytes of flash. For clarity, the + // single-meaning value words may be removed as they are used. Also, axis words are treated in the + // same way. If there is an explicit/implicit axis command, XYZ words are always used and are + // are removed at the end of error-checking. + + // [1. Comments ]: MSG's NOT SUPPORTED. Comment handling performed by protocol. + + // [2. Set feed rate mode ]: G93 F word missing with G1,G2/3 active, implicitly or explicitly. Feed rate + // is not defined after switching to G94 from G93. + // NOTE: For jogging, ignore prior feed rate mode. Enforce G94 and check for required F word. + if (gc_parser_flags & GC_PARSER_JOG_MOTION) { + if (bit_isfalse(value_words,bit(WORD_F))) { FAIL(STATUS_GCODE_UNDEFINED_FEED_RATE); } + if (gc_block.modal.units == UNITS_MODE_INCHES) { gc_block.values.f *= MM_PER_INCH; } + } else { + if (gc_block.modal.feed_rate == FEED_RATE_MODE_INVERSE_TIME) { // = G93 + // NOTE: G38 can also operate in inverse time, but is undefined as an error. Missing F word check added here. + if (axis_command == AXIS_COMMAND_MOTION_MODE) { + if ((gc_block.modal.motion != MOTION_MODE_NONE) && (gc_block.modal.motion != MOTION_MODE_SEEK)) { + if (bit_isfalse(value_words,bit(WORD_F))) { FAIL(STATUS_GCODE_UNDEFINED_FEED_RATE); } // [F word missing] + } + } + // NOTE: It seems redundant to check for an F word to be passed after switching from G94 to G93. We would + // accomplish the exact same thing if the feed rate value is always reset to zero and undefined after each + // inverse time block, since the commands that use this value already perform undefined checks. This would + // also allow other commands, following this switch, to execute and not error out needlessly. This code is + // combined with the above feed rate mode and the below set feed rate error-checking. + + // [3. Set feed rate ]: F is negative (done.) + // - In inverse time mode: Always implicitly zero the feed rate value before and after block completion. + // NOTE: If in G93 mode or switched into it from G94, just keep F value as initialized zero or passed F word + // value in the block. If no F word is passed with a motion command that requires a feed rate, this will error + // out in the motion modes error-checking. However, if no F word is passed with NO motion command that requires + // a feed rate, we simply move on and the state feed rate value gets updated to zero and remains undefined. + } else { // = G94 + // - In units per mm mode: If F word passed, ensure value is in mm/min, otherwise push last state value. + if (gc_state.modal.feed_rate == FEED_RATE_MODE_UNITS_PER_MIN) { // Last state is also G94 + if (bit_istrue(value_words,bit(WORD_F))) { + if (gc_block.modal.units == UNITS_MODE_INCHES) { gc_block.values.f *= MM_PER_INCH; } + } else { + gc_block.values.f = gc_state.feed_rate; // Push last state feed rate + } + } // Else, switching to G94 from G93, so don't push last state feed rate. Its undefined or the passed F word value. + } + } + // bit_false(value_words,bit(WORD_F)); // NOTE: Single-meaning value word. Set at end of error-checking. + + // [4. Set spindle speed ]: S is negative (done.) + if (bit_isfalse(value_words,bit(WORD_S))) { gc_block.values.s = gc_state.spindle_speed; } + // bit_false(value_words,bit(WORD_S)); // NOTE: Single-meaning value word. Set at end of error-checking. + + // [5. Select tool ]: NOT SUPPORTED. Only tracks value. T is negative (done.) Not an integer. Greater than max tool value. + // bit_false(value_words,bit(WORD_T)); // NOTE: Single-meaning value word. Set at end of error-checking. + + // [6. Change tool ]: N/A + // [7. Spindle control ]: N/A + // [8. Coolant control ]: N/A + // [9. Override control ]: Not supported except for a Grbl-only parking motion override control. + #ifdef ENABLE_PARKING_OVERRIDE_CONTROL + if (bit_istrue(command_words,bit(MODAL_GROUP_M9))) { // Already set as enabled in parser. + if (bit_istrue(value_words,bit(WORD_P))) { + if (gc_block.values.p == 0.0) { gc_block.modal.override = OVERRIDE_DISABLED; } + bit_false(value_words,bit(WORD_P)); + } + } + #endif + + // [10. Dwell ]: P value missing. P is negative (done.) NOTE: See below. + if (gc_block.non_modal_command == NON_MODAL_DWELL) { + if (bit_isfalse(value_words,bit(WORD_P))) { FAIL(STATUS_GCODE_VALUE_WORD_MISSING); } // [P word missing] + bit_false(value_words,bit(WORD_P)); + } + + // [11. Set active plane ]: N/A + switch (gc_block.modal.plane_select) { + case PLANE_SELECT_XY: + axis_0 = X_AXIS; + axis_1 = Y_AXIS; + axis_linear = Z_AXIS; + break; + case PLANE_SELECT_ZX: + axis_0 = Z_AXIS; + axis_1 = X_AXIS; + axis_linear = Y_AXIS; + break; + default: // case PLANE_SELECT_YZ: + axis_0 = Y_AXIS; + axis_1 = Z_AXIS; + axis_linear = X_AXIS; + } + + // [12. Set length units ]: N/A + // Pre-convert XYZ coordinate values to millimeters, if applicable. + uint8_t idx; + if (gc_block.modal.units == UNITS_MODE_INCHES) { + for (idx=0; idx N_COORDINATE_SYSTEM) { FAIL(STATUS_GCODE_UNSUPPORTED_COORD_SYS); } // [Greater than N sys] + if (gc_state.modal.coord_select != gc_block.modal.coord_select) { + if (!(settings_read_coord_data(gc_block.modal.coord_select,block_coord_system))) { FAIL(STATUS_SETTING_READ_FAIL); } + } + } + + // [16. Set path control mode ]: N/A. Only G61. G61.1 and G64 NOT SUPPORTED. + // [17. Set distance mode ]: N/A. Only G91.1. G90.1 NOT SUPPORTED. + // [18. Set retract mode ]: NOT SUPPORTED. + + // [19. Remaining non-modal actions ]: Check go to predefined position, set G10, or set axis offsets. + // NOTE: We need to separate the non-modal commands that are axis word-using (G10/G28/G30/G92), as these + // commands all treat axis words differently. G10 as absolute offsets or computes current position as + // the axis value, G92 similarly to G10 L20, and G28/30 as an intermediate target position that observes + // all the current coordinate system and G92 offsets. + switch (gc_block.non_modal_command) { + case NON_MODAL_SET_COORDINATE_DATA: + // [G10 Errors]: L missing and is not 2 or 20. P word missing. (Negative P value done.) + // [G10 L2 Errors]: R word NOT SUPPORTED. P value not 0 to nCoordSys(max 9). Axis words missing. + // [G10 L20 Errors]: P must be 0 to nCoordSys(max 9). Axis words missing. + if (!axis_words) { FAIL(STATUS_GCODE_NO_AXIS_WORDS) }; // [No axis words] + if (bit_isfalse(value_words,((1< N_COORDINATE_SYSTEM) { FAIL(STATUS_GCODE_UNSUPPORTED_COORD_SYS); } // [Greater than N sys] + if (gc_block.values.l != 20) { + if (gc_block.values.l == 2) { + if (bit_istrue(value_words,bit(WORD_R))) { FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); } // [G10 L2 R not supported] + } else { FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); } // [Unsupported L] + } + bit_false(value_words,(bit(WORD_L)|bit(WORD_P))); + + // Determine coordinate system to change and try to load from EEPROM. + if (coord_select > 0) { coord_select--; } // Adjust P1-P6 index to EEPROM coordinate data indexing. + else { coord_select = gc_block.modal.coord_select; } // Index P0 as the active coordinate system + + // NOTE: Store parameter data in IJK values. By rule, they are not in use with this command. + if (!settings_read_coord_data(coord_select,gc_block.values.ijk)) { FAIL(STATUS_SETTING_READ_FAIL); } // [EEPROM read fail] + + // Pre-calculate the coordinate data changes. + for (idx=0; idx WCS = MPos - G92 - TLO - WPos + gc_block.values.ijk[idx] = gc_state.position[idx]-gc_state.coord_offset[idx]-gc_block.values.xyz[idx]; + if (idx == TOOL_LENGTH_OFFSET_AXIS) { gc_block.values.ijk[idx] -= gc_state.tool_length_offset; } + } else { + // L2: Update coordinate system axis to programmed value. + gc_block.values.ijk[idx] = gc_block.values.xyz[idx]; + } + } // Else, keep current stored value. + } + break; + case NON_MODAL_SET_COORDINATE_OFFSET: + // [G92 Errors]: No axis words. + if (!axis_words) { FAIL(STATUS_GCODE_NO_AXIS_WORDS); } // [No axis words] + + // Update axes defined only in block. Offsets current system to defined value. Does not update when + // active coordinate system is selected, but is still active unless G92.1 disables it. + for (idx=0; idx G92 = MPos - WCS - TLO - WPos + gc_block.values.xyz[idx] = gc_state.position[idx]-block_coord_system[idx]-gc_block.values.xyz[idx]; + if (idx == TOOL_LENGTH_OFFSET_AXIS) { gc_block.values.xyz[idx] -= gc_state.tool_length_offset; } + } else { + gc_block.values.xyz[idx] = gc_state.coord_offset[idx]; + } + } + break; + + default: + + // At this point, the rest of the explicit axis commands treat the axis values as the traditional + // target position with the coordinate system offsets, G92 offsets, absolute override, and distance + // modes applied. This includes the motion mode commands. We can now pre-compute the target position. + // NOTE: Tool offsets may be appended to these conversions when/if this feature is added. + if (axis_command != AXIS_COMMAND_TOOL_LENGTH_OFFSET ) { // TLO block any axis command. + if (axis_words) { + for (idx=0; idx C -----------------+--------------- T <- [x,y] + | <------ d/2 ---->| + + C - Current position + T - Target position + O - center of circle that pass through both C and T + d - distance from C to T + r - designated radius + h - distance from center of CT to O + + Expanding the equations: + + d -> sqrt(x^2 + y^2) + h -> sqrt(4 * r^2 - x^2 - y^2)/2 + i -> (x - (y * sqrt(4 * r^2 - x^2 - y^2)) / sqrt(x^2 + y^2)) / 2 + j -> (y + (x * sqrt(4 * r^2 - x^2 - y^2)) / sqrt(x^2 + y^2)) / 2 + + Which can be written: + + i -> (x - (y * sqrt(4 * r^2 - x^2 - y^2))/sqrt(x^2 + y^2))/2 + j -> (y + (x * sqrt(4 * r^2 - x^2 - y^2))/sqrt(x^2 + y^2))/2 + + Which we for size and speed reasons optimize to: + + h_x2_div_d = sqrt(4 * r^2 - x^2 - y^2)/sqrt(x^2 + y^2) + i = (x - (y * h_x2_div_d))/2 + j = (y + (x * h_x2_div_d))/2 + */ + + // First, use h_x2_div_d to compute 4*h^2 to check if it is negative or r is smaller + // than d. If so, the sqrt of a negative number is complex and error out. + float h_x2_div_d = 4.0 * gc_block.values.r*gc_block.values.r - x*x - y*y; + + if (h_x2_div_d < 0) { FAIL(STATUS_GCODE_ARC_RADIUS_ERROR); } // [Arc radius error] + + // Finish computing h_x2_div_d. + h_x2_div_d = -sqrt(h_x2_div_d)/hypot_f(x,y); // == -(h * 2 / d) + // Invert the sign of h_x2_div_d if the circle is counter clockwise (see sketch below) + if (gc_block.modal.motion == MOTION_MODE_CCW_ARC) { h_x2_div_d = -h_x2_div_d; } + + /* The counter clockwise circle lies to the left of the target direction. When offset is positive, + the left hand circle will be generated - when it is negative the right hand circle is generated. + + T <-- Target position + + ^ + Clockwise circles with this center | Clockwise circles with this center will have + will have > 180 deg of angular travel | < 180 deg of angular travel, which is a good thing! + \ | / + center of arc when h_x2_div_d is positive -> x <----- | -----> x <- center of arc when h_x2_div_d is negative + | + | + + C <-- Current position + */ + // Negative R is g-code-alese for "I want a circle with more than 180 degrees of travel" (go figure!), + // even though it is advised against ever generating such circles in a single line of g-code. By + // inverting the sign of h_x2_div_d the center of the circles is placed on the opposite side of the line of + // travel and thus we get the unadvisably long arcs as prescribed. + if (gc_block.values.r < 0) { + h_x2_div_d = -h_x2_div_d; + gc_block.values.r = -gc_block.values.r; // Finished with r. Set to positive for mc_arc + } + // Complete the operation by calculating the actual center of the arc + gc_block.values.ijk[axis_0] = 0.5*(x-(y*h_x2_div_d)); + gc_block.values.ijk[axis_1] = 0.5*(y+(x*h_x2_div_d)); + + } else { // Arc Center Format Offset Mode + if (!(ijk_words & (bit(axis_0)|bit(axis_1)))) { FAIL(STATUS_GCODE_NO_OFFSETS_IN_PLANE); } // [No offsets in plane] + bit_false(value_words,(bit(WORD_I)|bit(WORD_J)|bit(WORD_K))); + + // Convert IJK values to proper units. + if (gc_block.modal.units == UNITS_MODE_INCHES) { + for (idx=0; idx 0.005) { + if (delta_r > 0.5) { FAIL(STATUS_GCODE_INVALID_TARGET); } // [Arc definition error] > 0.5mm + if (delta_r > (0.001*gc_block.values.r)) { FAIL(STATUS_GCODE_INVALID_TARGET); } // [Arc definition error] > 0.005mm AND 0.1% radius + } + } + break; + case MOTION_MODE_PROBE_TOWARD_NO_ERROR: case MOTION_MODE_PROBE_AWAY_NO_ERROR: + gc_parser_flags |= GC_PARSER_PROBE_IS_NO_ERROR; // No break intentional. + case MOTION_MODE_PROBE_TOWARD: case MOTION_MODE_PROBE_AWAY: + if ((gc_block.modal.motion == MOTION_MODE_PROBE_AWAY) || + (gc_block.modal.motion == MOTION_MODE_PROBE_AWAY_NO_ERROR)) { gc_parser_flags |= GC_PARSER_PROBE_IS_AWAY; } + // [G38 Errors]: Target is same current. No axis words. Cutter compensation is enabled. Feed rate + // is undefined. Probe is triggered. NOTE: Probe check moved to probe cycle. Instead of returning + // an error, it issues an alarm to prevent further motion to the probe. It's also done there to + // allow the planner buffer to empty and move off the probe trigger before another probing cycle. + if (!axis_words) { FAIL(STATUS_GCODE_NO_AXIS_WORDS); } // [No axis words] + if (isequal_position_vector(gc_state.position, gc_block.values.xyz)) { FAIL(STATUS_GCODE_INVALID_TARGET); } // [Invalid target] + break; + } + } + } + + // [21. Program flow ]: No error checks required. + + // [0. Non-specific error-checks]: Complete unused value words check, i.e. IJK used when in arc + // radius mode, or axis words that aren't used in the block. + if (gc_parser_flags & GC_PARSER_JOG_MOTION) { + // Jogging only uses the F feed rate and XYZ value words. N is valid, but S and T are invalid. + bit_false(value_words,(bit(WORD_N)|bit(WORD_F))); + } else { + bit_false(value_words,(bit(WORD_N)|bit(WORD_F)|bit(WORD_S)|bit(WORD_T))); // Remove single-meaning value words. + } + if (axis_command) { bit_false(value_words,(bit(WORD_X)|bit(WORD_Y)|bit(WORD_Z))); } // Remove axis words. + if (value_words) { FAIL(STATUS_GCODE_UNUSED_WORDS); } // [Unused words] + + /* ------------------------------------------------------------------------------------- + STEP 4: EXECUTE!! + Assumes that all error-checking has been completed and no failure modes exist. We just + need to update the state and execute the block according to the order-of-execution. + */ + + // Initialize planner data struct for motion blocks. + plan_line_data_t plan_data; + plan_line_data_t *pl_data = &plan_data; + memset(pl_data,0,sizeof(plan_line_data_t)); // Zero pl_data struct + + // Intercept jog commands and complete error checking for valid jog commands and execute. + // NOTE: G-code parser state is not updated, except the position to ensure sequential jog + // targets are computed correctly. The final parser position after a jog is updated in + // protocol_execute_realtime() when jogging completes or is canceled. + if (gc_parser_flags & GC_PARSER_JOG_MOTION) { + // Only distance and unit modal commands and G53 absolute override command are allowed. + // NOTE: Feed rate word and axis word checks have already been performed in STEP 3. + if (command_words & ~(bit(MODAL_GROUP_G3) | bit(MODAL_GROUP_G6 | bit(MODAL_GROUP_G0))) ) { FAIL(STATUS_INVALID_JOG_COMMAND) }; + if (!(gc_block.non_modal_command == NON_MODAL_ABSOLUTE_OVERRIDE || gc_block.non_modal_command == NON_MODAL_NO_ACTION)) { FAIL(STATUS_INVALID_JOG_COMMAND); } + + // Initialize planner data to current spindle and coolant modal state. + pl_data->spindle_speed = gc_state.spindle_speed; + plan_data.condition = (gc_state.modal.spindle | gc_state.modal.coolant); + + uint8_t status = jog_execute(&plan_data, &gc_block); + if (status == STATUS_OK) { memcpy(gc_state.position, gc_block.values.xyz, sizeof(gc_block.values.xyz)); } + return(status); + } + + // If in laser mode, setup laser power based on current and past parser conditions. + if (bit_istrue(settings.flags,BITFLAG_LASER_MODE)) { + if ( !((gc_block.modal.motion == MOTION_MODE_LINEAR) || (gc_block.modal.motion == MOTION_MODE_CW_ARC) + || (gc_block.modal.motion == MOTION_MODE_CCW_ARC)) ) { + gc_parser_flags |= GC_PARSER_LASER_DISABLE; + } + + // Any motion mode with axis words is allowed to be passed from a spindle speed update. + // NOTE: G1 and G0 without axis words sets axis_command to none. G28/30 are intentionally omitted. + // TODO: Check sync conditions for M3 enabled motions that don't enter the planner. (zero length). + if (axis_words && (axis_command == AXIS_COMMAND_MOTION_MODE)) { + gc_parser_flags |= GC_PARSER_LASER_ISMOTION; + } else { + // M3 constant power laser requires planner syncs to update the laser when changing between + // a G1/2/3 motion mode state and vice versa when there is no motion in the line. + if (gc_state.modal.spindle == SPINDLE_ENABLE_CW) { + if ((gc_state.modal.motion == MOTION_MODE_LINEAR) || (gc_state.modal.motion == MOTION_MODE_CW_ARC) + || (gc_state.modal.motion == MOTION_MODE_CCW_ARC)) { + if (bit_istrue(gc_parser_flags,GC_PARSER_LASER_DISABLE)) { + gc_parser_flags |= GC_PARSER_LASER_FORCE_SYNC; // Change from G1/2/3 motion mode. + } + } else { + // When changing to a G1 motion mode without axis words from a non-G1/2/3 motion mode. + if (bit_isfalse(gc_parser_flags,GC_PARSER_LASER_DISABLE)) { + gc_parser_flags |= GC_PARSER_LASER_FORCE_SYNC; + } + } + } + } + } + + // [0. Non-specific/common error-checks and miscellaneous setup]: + // NOTE: If no line number is present, the value is zero. + gc_state.line_number = gc_block.values.n; + #ifdef USE_LINE_NUMBERS + pl_data->line_number = gc_state.line_number; // Record data for planner use. + #endif + + // [1. Comments feedback ]: NOT SUPPORTED + + // [2. Set feed rate mode ]: + gc_state.modal.feed_rate = gc_block.modal.feed_rate; + if (gc_state.modal.feed_rate) { pl_data->condition |= PL_COND_FLAG_INVERSE_TIME; } // Set condition flag for planner use. + + // [3. Set feed rate ]: + gc_state.feed_rate = gc_block.values.f; // Always copy this value. See feed rate error-checking. + pl_data->feed_rate = gc_state.feed_rate; // Record data for planner use. + + // [4. Set spindle speed ]: + if ((gc_state.spindle_speed != gc_block.values.s) || bit_istrue(gc_parser_flags,GC_PARSER_LASER_FORCE_SYNC)) { + if (gc_state.modal.spindle != SPINDLE_DISABLE) { + #ifdef VARIABLE_SPINDLE + if (bit_isfalse(gc_parser_flags,GC_PARSER_LASER_ISMOTION)) { + if (bit_istrue(gc_parser_flags,GC_PARSER_LASER_DISABLE)) { + spindle_sync(gc_state.modal.spindle, 0.0); + } else { spindle_sync(gc_state.modal.spindle, gc_block.values.s); } + } + #else + spindle_sync(gc_state.modal.spindle, 0.0); + #endif + } + gc_state.spindle_speed = gc_block.values.s; // Update spindle speed state. + } + // NOTE: Pass zero spindle speed for all restricted laser motions. + if (bit_isfalse(gc_parser_flags,GC_PARSER_LASER_DISABLE)) { + pl_data->spindle_speed = gc_state.spindle_speed; // Record data for planner use. + } // else { pl_data->spindle_speed = 0.0; } // Initialized as zero already. + + // [5. Select tool ]: NOT SUPPORTED. Only tracks tool value. + gc_state.tool = gc_block.values.t; + + // [6. Change tool ]: NOT SUPPORTED + + // [7. Spindle control ]: + if (gc_state.modal.spindle != gc_block.modal.spindle) { + // Update spindle control and apply spindle speed when enabling it in this block. + // NOTE: All spindle state changes are synced, even in laser mode. Also, pl_data, + // rather than gc_state, is used to manage laser state for non-laser motions. + spindle_sync(gc_block.modal.spindle, pl_data->spindle_speed); + gc_state.modal.spindle = gc_block.modal.spindle; + } + pl_data->condition |= gc_state.modal.spindle; // Set condition flag for planner use. + + // [8. Coolant control ]: + if (gc_state.modal.coolant != gc_block.modal.coolant) { + // NOTE: Coolant M-codes are modal. Only one command per line is allowed. But, multiple states + // can exist at the same time, while coolant disable clears all states. + coolant_sync(gc_block.modal.coolant); + gc_state.modal.coolant = gc_block.modal.coolant; + } + pl_data->condition |= gc_state.modal.coolant; // Set condition flag for planner use. + + // [9. Override control ]: NOT SUPPORTED. Always enabled. Except for a Grbl-only parking control. + #ifdef ENABLE_PARKING_OVERRIDE_CONTROL + if (gc_state.modal.override != gc_block.modal.override) { + gc_state.modal.override = gc_block.modal.override; + mc_override_ctrl_update(gc_state.modal.override); + } + #endif + + // [10. Dwell ]: + if (gc_block.non_modal_command == NON_MODAL_DWELL) { mc_dwell(gc_block.values.p); } + + // [11. Set active plane ]: + gc_state.modal.plane_select = gc_block.modal.plane_select; + + // [12. Set length units ]: + gc_state.modal.units = gc_block.modal.units; + + // [13. Cutter radius compensation ]: G41/42 NOT SUPPORTED + // gc_state.modal.cutter_comp = gc_block.modal.cutter_comp; // NOTE: Not needed since always disabled. + + // [14. Cutter length compensation ]: G43.1 and G49 supported. G43 NOT SUPPORTED. + // NOTE: If G43 were supported, its operation wouldn't be any different from G43.1 in terms + // of execution. The error-checking step would simply load the offset value into the correct + // axis of the block XYZ value array. + if (axis_command == AXIS_COMMAND_TOOL_LENGTH_OFFSET ) { // Indicates a change. + gc_state.modal.tool_length = gc_block.modal.tool_length; + if (gc_state.modal.tool_length == TOOL_LENGTH_OFFSET_CANCEL) { // G49 + gc_block.values.xyz[TOOL_LENGTH_OFFSET_AXIS] = 0.0; + } // else G43.1 + if ( gc_state.tool_length_offset != gc_block.values.xyz[TOOL_LENGTH_OFFSET_AXIS] ) { + gc_state.tool_length_offset = gc_block.values.xyz[TOOL_LENGTH_OFFSET_AXIS]; + system_flag_wco_change(); + } + } + + // [15. Coordinate system selection ]: + if (gc_state.modal.coord_select != gc_block.modal.coord_select) { + gc_state.modal.coord_select = gc_block.modal.coord_select; + memcpy(gc_state.coord_system,block_coord_system,N_AXIS*sizeof(float)); + system_flag_wco_change(); + } + + // [16. Set path control mode ]: G61.1/G64 NOT SUPPORTED + // gc_state.modal.control = gc_block.modal.control; // NOTE: Always default. + + // [17. Set distance mode ]: + gc_state.modal.distance = gc_block.modal.distance; + + // [18. Set retract mode ]: NOT SUPPORTED + + // [19. Go to predefined position, Set G10, or Set axis offsets ]: + switch(gc_block.non_modal_command) { + case NON_MODAL_SET_COORDINATE_DATA: + settings_write_coord_data(coord_select,gc_block.values.ijk); + // Update system coordinate system if currently active. + if (gc_state.modal.coord_select == coord_select) { + memcpy(gc_state.coord_system,gc_block.values.ijk,N_AXIS*sizeof(float)); + system_flag_wco_change(); + } + break; + case NON_MODAL_GO_HOME_0: case NON_MODAL_GO_HOME_1: + // Move to intermediate position before going home. Obeys current coordinate system and offsets + // and absolute and incremental modes. + pl_data->condition |= PL_COND_FLAG_RAPID_MOTION; // Set rapid motion condition flag. + if (axis_command) { mc_line(gc_block.values.xyz, pl_data); } + mc_line(gc_block.values.ijk, pl_data); + memcpy(gc_state.position, gc_block.values.ijk, N_AXIS*sizeof(float)); + break; + case NON_MODAL_SET_HOME_0: + settings_write_coord_data(SETTING_INDEX_G28,gc_state.position); + break; + case NON_MODAL_SET_HOME_1: + settings_write_coord_data(SETTING_INDEX_G30,gc_state.position); + break; + case NON_MODAL_SET_COORDINATE_OFFSET: + memcpy(gc_state.coord_offset,gc_block.values.xyz,sizeof(gc_block.values.xyz)); + system_flag_wco_change(); + break; + case NON_MODAL_RESET_COORDINATE_OFFSET: + clear_vector(gc_state.coord_offset); // Disable G92 offsets by zeroing offset vector. + system_flag_wco_change(); + break; + } + + + // [20. Motion modes ]: + // NOTE: Commands G10,G28,G30,G92 lock out and prevent axis words from use in motion modes. + // Enter motion modes only if there are axis words or a motion mode command word in the block. + gc_state.modal.motion = gc_block.modal.motion; + if (gc_state.modal.motion != MOTION_MODE_NONE) { + if (axis_command == AXIS_COMMAND_MOTION_MODE) { + uint8_t gc_update_pos = GC_UPDATE_POS_TARGET; + if (gc_state.modal.motion == MOTION_MODE_LINEAR) { + mc_line(gc_block.values.xyz, pl_data); + } else if (gc_state.modal.motion == MOTION_MODE_SEEK) { + pl_data->condition |= PL_COND_FLAG_RAPID_MOTION; // Set rapid motion condition flag. + mc_line(gc_block.values.xyz, pl_data); + } else if ((gc_state.modal.motion == MOTION_MODE_CW_ARC) || (gc_state.modal.motion == MOTION_MODE_CCW_ARC)) { + mc_arc(gc_block.values.xyz, pl_data, gc_state.position, gc_block.values.ijk, gc_block.values.r, + axis_0, axis_1, axis_linear, bit_istrue(gc_parser_flags,GC_PARSER_ARC_IS_CLOCKWISE)); + } else { + // NOTE: gc_block.values.xyz is returned from mc_probe_cycle with the updated position value. So + // upon a successful probing cycle, the machine position and the returned value should be the same. + #ifndef ALLOW_FEED_OVERRIDE_DURING_PROBE_CYCLES + pl_data->condition |= PL_COND_FLAG_NO_FEED_OVERRIDE; + #endif + gc_update_pos = mc_probe_cycle(gc_block.values.xyz, pl_data, gc_parser_flags); + } + + // As far as the parser is concerned, the position is now == target. In reality the + // motion control system might still be processing the action and the real tool position + // in any intermediate location. + if (gc_update_pos == GC_UPDATE_POS_TARGET) { + memcpy(gc_state.position, gc_block.values.xyz, sizeof(gc_block.values.xyz)); // gc_state.position[] = gc_block.values.xyz[] + } else if (gc_update_pos == GC_UPDATE_POS_SYSTEM) { + gc_sync_position(); // gc_state.position[] = sys_position + } // == GC_UPDATE_POS_NONE + } + } + + // [21. Program flow ]: + // M0,M1,M2,M30: Perform non-running program flow actions. During a program pause, the buffer may + // refill and can only be resumed by the cycle start run-time command. + gc_state.modal.program_flow = gc_block.modal.program_flow; + if (gc_state.modal.program_flow) { + protocol_buffer_synchronize(); // Sync and finish all remaining buffered motions before moving on. + if (gc_state.modal.program_flow == PROGRAM_FLOW_PAUSED) { + if (sys.state != STATE_CHECK_MODE) { + system_set_exec_state_flag(EXEC_FEED_HOLD); // Use feed hold for program pause. + protocol_execute_realtime(); // Execute suspend. + } + } else { // == PROGRAM_FLOW_COMPLETED + // Upon program complete, only a subset of g-codes reset to certain defaults, according to + // LinuxCNC's program end descriptions and testing. Only modal groups [G-code 1,2,3,5,7,12] + // and [M-code 7,8,9] reset to [G1,G17,G90,G94,G40,G54,M5,M9,M48]. The remaining modal groups + // [G-code 4,6,8,10,13,14,15] and [M-code 4,5,6] and the modal words [F,S,T,H] do not reset. + gc_state.modal.motion = MOTION_MODE_LINEAR; + gc_state.modal.plane_select = PLANE_SELECT_XY; + gc_state.modal.distance = DISTANCE_MODE_ABSOLUTE; + gc_state.modal.feed_rate = FEED_RATE_MODE_UNITS_PER_MIN; + // gc_state.modal.cutter_comp = CUTTER_COMP_DISABLE; // Not supported. + gc_state.modal.coord_select = 0; // G54 + gc_state.modal.spindle = SPINDLE_DISABLE; + gc_state.modal.coolant = COOLANT_DISABLE; + #ifdef ENABLE_PARKING_OVERRIDE_CONTROL + #ifdef DEACTIVATE_PARKING_UPON_INIT + gc_state.modal.override = OVERRIDE_DISABLED; + #else + gc_state.modal.override = OVERRIDE_PARKING_MOTION; + #endif + #endif + + #ifdef RESTORE_OVERRIDES_AFTER_PROGRAM_END + sys.f_override = DEFAULT_FEED_OVERRIDE; + sys.r_override = DEFAULT_RAPID_OVERRIDE; + sys.spindle_speed_ovr = DEFAULT_SPINDLE_SPEED_OVERRIDE; + #endif + + // Execute coordinate change and spindle/coolant stop. + if (sys.state != STATE_CHECK_MODE) { + if (!(settings_read_coord_data(gc_state.modal.coord_select,gc_state.coord_system))) { FAIL(STATUS_SETTING_READ_FAIL); } + system_flag_wco_change(); // Set to refresh immediately just in case something altered. + spindle_set_state(SPINDLE_DISABLE,0.0); + coolant_set_state(COOLANT_DISABLE); + } + report_feedback_message(MESSAGE_PROGRAM_END); + } + gc_state.modal.program_flow = PROGRAM_FLOW_RUNNING; // Reset program flow. + } + + // TODO: % to denote start of program. + + return(STATUS_OK); +} + + +/* + Not supported: + + - Canned cycles + - Tool radius compensation + - A,B,C-axes + - Evaluation of expressions + - Variables + - Override control (TBD) + - Tool changes + - Switches + + (*) Indicates optional parameter, enabled through config.h and re-compile + group 0 = {G92.2, G92.3} (Non modal: Cancel and re-enable G92 offsets) + group 1 = {G81 - G89} (Motion modes: Canned cycles) + group 4 = {M1} (Optional stop, ignored) + group 6 = {M6} (Tool change) + group 7 = {G41, G42} cutter radius compensation (G40 is supported) + group 8 = {G43} tool length offset (G43.1/G49 are supported) + group 8 = {M7*} enable mist coolant (* Compile-option) + group 9 = {M48, M49, M56*} enable/disable override switches (* Compile-option) + group 10 = {G98, G99} return mode canned cycles + group 13 = {G61.1, G64} path control mode (G61 is supported) +*/ diff --git a/trunk/Arduino/GRBL_1.1f/gcode.h b/trunk/Arduino/GRBL_1.1f/gcode.h new file mode 100644 index 00000000..6cdc61b4 --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f/gcode.h @@ -0,0 +1,248 @@ +/* + gcode.h - rs274/ngc parser. + Part of Grbl + + Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC + Copyright (c) 2009-2011 Simen Svale Skogsrud + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +#ifndef gcode_h +#define gcode_h + + +// Define modal group internal numbers for checking multiple command violations and tracking the +// type of command that is called in the block. A modal group is a group of g-code commands that are +// mutually exclusive, or cannot exist on the same line, because they each toggle a state or execute +// a unique motion. These are defined in the NIST RS274-NGC v3 g-code standard, available online, +// and are similar/identical to other g-code interpreters by manufacturers (Haas,Fanuc,Mazak,etc). +// NOTE: Modal group define values must be sequential and starting from zero. +#define MODAL_GROUP_G0 0 // [G4,G10,G28,G28.1,G30,G30.1,G53,G92,G92.1] Non-modal +#define MODAL_GROUP_G1 1 // [G0,G1,G2,G3,G38.2,G38.3,G38.4,G38.5,G80] Motion +#define MODAL_GROUP_G2 2 // [G17,G18,G19] Plane selection +#define MODAL_GROUP_G3 3 // [G90,G91] Distance mode +#define MODAL_GROUP_G4 4 // [G91.1] Arc IJK distance mode +#define MODAL_GROUP_G5 5 // [G93,G94] Feed rate mode +#define MODAL_GROUP_G6 6 // [G20,G21] Units +#define MODAL_GROUP_G7 7 // [G40] Cutter radius compensation mode. G41/42 NOT SUPPORTED. +#define MODAL_GROUP_G8 8 // [G43.1,G49] Tool length offset +#define MODAL_GROUP_G12 9 // [G54,G55,G56,G57,G58,G59] Coordinate system selection +#define MODAL_GROUP_G13 10 // [G61] Control mode + +#define MODAL_GROUP_M4 11 // [M0,M1,M2,M30] Stopping +#define MODAL_GROUP_M7 12 // [M3,M4,M5] Spindle turning +#define MODAL_GROUP_M8 13 // [M7,M8,M9] Coolant control +#define MODAL_GROUP_M9 14 // [M56] Override control + +// Define command actions for within execution-type modal groups (motion, stopping, non-modal). Used +// internally by the parser to know which command to execute. +// NOTE: Some macro values are assigned specific values to make g-code state reporting and parsing +// compile a litte smaller. Necessary due to being completely out of flash on the 328p. Although not +// ideal, just be careful with values that state 'do not alter' and check both report.c and gcode.c +// to see how they are used, if you need to alter them. + +// Modal Group G0: Non-modal actions +#define NON_MODAL_NO_ACTION 0 // (Default: Must be zero) +#define NON_MODAL_DWELL 4 // G4 (Do not alter value) +#define NON_MODAL_SET_COORDINATE_DATA 10 // G10 (Do not alter value) +#define NON_MODAL_GO_HOME_0 28 // G28 (Do not alter value) +#define NON_MODAL_SET_HOME_0 38 // G28.1 (Do not alter value) +#define NON_MODAL_GO_HOME_1 30 // G30 (Do not alter value) +#define NON_MODAL_SET_HOME_1 40 // G30.1 (Do not alter value) +#define NON_MODAL_ABSOLUTE_OVERRIDE 53 // G53 (Do not alter value) +#define NON_MODAL_SET_COORDINATE_OFFSET 92 // G92 (Do not alter value) +#define NON_MODAL_RESET_COORDINATE_OFFSET 102 //G92.1 (Do not alter value) + +// Modal Group G1: Motion modes +#define MOTION_MODE_SEEK 0 // G0 (Default: Must be zero) +#define MOTION_MODE_LINEAR 1 // G1 (Do not alter value) +#define MOTION_MODE_CW_ARC 2 // G2 (Do not alter value) +#define MOTION_MODE_CCW_ARC 3 // G3 (Do not alter value) +#define MOTION_MODE_PROBE_TOWARD 140 // G38.2 (Do not alter value) +#define MOTION_MODE_PROBE_TOWARD_NO_ERROR 141 // G38.3 (Do not alter value) +#define MOTION_MODE_PROBE_AWAY 142 // G38.4 (Do not alter value) +#define MOTION_MODE_PROBE_AWAY_NO_ERROR 143 // G38.5 (Do not alter value) +#define MOTION_MODE_NONE 80 // G80 (Do not alter value) + +// Modal Group G2: Plane select +#define PLANE_SELECT_XY 0 // G17 (Default: Must be zero) +#define PLANE_SELECT_ZX 1 // G18 (Do not alter value) +#define PLANE_SELECT_YZ 2 // G19 (Do not alter value) + +// Modal Group G3: Distance mode +#define DISTANCE_MODE_ABSOLUTE 0 // G90 (Default: Must be zero) +#define DISTANCE_MODE_INCREMENTAL 1 // G91 (Do not alter value) + +// Modal Group G4: Arc IJK distance mode +#define DISTANCE_ARC_MODE_INCREMENTAL 0 // G91.1 (Default: Must be zero) + +// Modal Group M4: Program flow +#define PROGRAM_FLOW_RUNNING 0 // (Default: Must be zero) +#define PROGRAM_FLOW_PAUSED 3 // M0 +#define PROGRAM_FLOW_OPTIONAL_STOP 1 // M1 NOTE: Not supported, but valid and ignored. +#define PROGRAM_FLOW_COMPLETED_M2 2 // M2 (Do not alter value) +#define PROGRAM_FLOW_COMPLETED_M30 30 // M30 (Do not alter value) + +// Modal Group G5: Feed rate mode +#define FEED_RATE_MODE_UNITS_PER_MIN 0 // G94 (Default: Must be zero) +#define FEED_RATE_MODE_INVERSE_TIME 1 // G93 (Do not alter value) + +// Modal Group G6: Units mode +#define UNITS_MODE_MM 0 // G21 (Default: Must be zero) +#define UNITS_MODE_INCHES 1 // G20 (Do not alter value) + +// Modal Group G7: Cutter radius compensation mode +#define CUTTER_COMP_DISABLE 0 // G40 (Default: Must be zero) + +// Modal Group G13: Control mode +#define CONTROL_MODE_EXACT_PATH 0 // G61 (Default: Must be zero) + +// Modal Group M7: Spindle control +#define SPINDLE_DISABLE 0 // M5 (Default: Must be zero) +#define SPINDLE_ENABLE_CW PL_COND_FLAG_SPINDLE_CW // M3 (NOTE: Uses planner condition bit flag) +#define SPINDLE_ENABLE_CCW PL_COND_FLAG_SPINDLE_CCW // M4 (NOTE: Uses planner condition bit flag) + +// Modal Group M8: Coolant control +#define COOLANT_DISABLE 0 // M9 (Default: Must be zero) +#define COOLANT_FLOOD_ENABLE PL_COND_FLAG_COOLANT_FLOOD // M8 (NOTE: Uses planner condition bit flag) +#define COOLANT_MIST_ENABLE PL_COND_FLAG_COOLANT_MIST // M7 (NOTE: Uses planner condition bit flag) + +// Modal Group G8: Tool length offset +#define TOOL_LENGTH_OFFSET_CANCEL 0 // G49 (Default: Must be zero) +#define TOOL_LENGTH_OFFSET_ENABLE_DYNAMIC 1 // G43.1 + +// Modal Group M9: Override control +#ifdef DEACTIVATE_PARKING_UPON_INIT + #define OVERRIDE_DISABLED 0 // (Default: Must be zero) + #define OVERRIDE_PARKING_MOTION 1 // M56 +#else + #define OVERRIDE_PARKING_MOTION 0 // M56 (Default: Must be zero) + #define OVERRIDE_DISABLED 1 // Parking disabled. +#endif + +// Modal Group G12: Active work coordinate system +// N/A: Stores coordinate system value (54-59) to change to. + +// Define parameter word mapping. +#define WORD_F 0 +#define WORD_I 1 +#define WORD_J 2 +#define WORD_K 3 +#define WORD_L 4 +#define WORD_N 5 +#define WORD_P 6 +#define WORD_R 7 +#define WORD_S 8 +#define WORD_T 9 +#define WORD_X 10 +#define WORD_Y 11 +#define WORD_Z 12 + +// Define g-code parser position updating flags +#define GC_UPDATE_POS_TARGET 0 // Must be zero +#define GC_UPDATE_POS_SYSTEM 1 +#define GC_UPDATE_POS_NONE 2 + +// Define probe cycle exit states and assign proper position updating. +#define GC_PROBE_FOUND GC_UPDATE_POS_SYSTEM +#define GC_PROBE_ABORT GC_UPDATE_POS_NONE +#define GC_PROBE_FAIL_INIT GC_UPDATE_POS_NONE +#define GC_PROBE_FAIL_END GC_UPDATE_POS_TARGET +#ifdef SET_CHECK_MODE_PROBE_TO_START + #define GC_PROBE_CHECK_MODE GC_UPDATE_POS_NONE +#else + #define GC_PROBE_CHECK_MODE GC_UPDATE_POS_TARGET +#endif + +// Define gcode parser flags for handling special cases. +#define GC_PARSER_NONE 0 // Must be zero. +#define GC_PARSER_JOG_MOTION bit(0) +#define GC_PARSER_CHECK_MANTISSA bit(1) +#define GC_PARSER_ARC_IS_CLOCKWISE bit(2) +#define GC_PARSER_PROBE_IS_AWAY bit(3) +#define GC_PARSER_PROBE_IS_NO_ERROR bit(4) +#define GC_PARSER_LASER_FORCE_SYNC bit(5) +#define GC_PARSER_LASER_DISABLE bit(6) +#define GC_PARSER_LASER_ISMOTION bit(7) + + +// NOTE: When this struct is zeroed, the above defines set the defaults for the system. +typedef struct { + uint8_t motion; // {G0,G1,G2,G3,G38.2,G80} + uint8_t feed_rate; // {G93,G94} + uint8_t units; // {G20,G21} + uint8_t distance; // {G90,G91} + // uint8_t distance_arc; // {G91.1} NOTE: Don't track. Only default supported. + uint8_t plane_select; // {G17,G18,G19} + // uint8_t cutter_comp; // {G40} NOTE: Don't track. Only default supported. + uint8_t tool_length; // {G43.1,G49} + uint8_t coord_select; // {G54,G55,G56,G57,G58,G59} + // uint8_t control; // {G61} NOTE: Don't track. Only default supported. + uint8_t program_flow; // {M0,M1,M2,M30} + uint8_t coolant; // {M7,M8,M9} + uint8_t spindle; // {M3,M4,M5} + uint8_t override; // {M56} +} gc_modal_t; + +typedef struct { + float f; // Feed + float ijk[3]; // I,J,K Axis arc offsets + uint8_t l; // G10 or canned cycles parameters + int32_t n; // Line number + float p; // G10 or dwell parameters + // float q; // G82 peck drilling + float r; // Arc radius + float s; // Spindle speed + uint8_t t; // Tool selection + float xyz[3]; // X,Y,Z Translational axes +} gc_values_t; + + +typedef struct { + gc_modal_t modal; + + float spindle_speed; // RPM + float feed_rate; // Millimeters/min + uint8_t tool; // Tracks tool number. NOT USED. + int32_t line_number; // Last line number sent + + float position[N_AXIS]; // Where the interpreter considers the tool to be at this point in the code + + float coord_system[N_AXIS]; // Current work coordinate system (G54+). Stores offset from absolute machine + // position in mm. Loaded from EEPROM when called. + float coord_offset[N_AXIS]; // Retains the G92 coordinate offset (work coordinates) relative to + // machine zero in mm. Non-persistent. Cleared upon reset and boot. + float tool_length_offset; // Tracks tool length offset value when enabled. +} parser_state_t; +extern parser_state_t gc_state; + + +typedef struct { + uint8_t non_modal_command; + gc_modal_t modal; + gc_values_t values; +} parser_block_t; + + +// Initialize the parser +void gc_init(); + +// Execute one block of rs275/ngc/g-code +uint8_t gc_execute_line(char *line); + +// Set g-code parser position. Input in steps. +void gc_sync_position(); + +#endif diff --git a/trunk/Arduino/GRBL_1.1f/grbl.h b/trunk/Arduino/GRBL_1.1f/grbl.h new file mode 100644 index 00000000..f64f19e2 --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f/grbl.h @@ -0,0 +1,116 @@ +/* + grbl.h - main Grbl include file + Part of Grbl + + Copyright (c) 2015-2016 Sungeun K. Jeon for Gnea Research LLC + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +#ifndef grbl_h +#define grbl_h + +// Grbl versioning system +#define GRBL_VERSION "1.1g" +#define GRBL_VERSION_BUILD "20180614" + +// Define standard libraries used by Grbl. +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Define the Grbl system include files. NOTE: Do not alter organization. +#include "config.h" +#include "nuts_bolts.h" +#include "settings.h" +#include "system.h" +#include "defaults.h" +#include "cpu_map.h" +#include "planner.h" +#include "coolant_control.h" +#include "eeprom.h" +#include "gcode.h" +#include "limits.h" +#include "motion_control.h" +#include "planner.h" +#include "print.h" +#include "probe.h" +#include "protocol.h" +#include "report.h" +#include "serial.h" +#include "spindle_control.h" +#include "stepper.h" +#include "jog.h" + +// --------------------------------------------------------------------------------------- +// COMPILE-TIME ERROR CHECKING OF DEFINE VALUES: + +#ifndef HOMING_CYCLE_0 + #error "Required HOMING_CYCLE_0 not defined." +#endif + +#if defined(USE_SPINDLE_DIR_AS_ENABLE_PIN) && !defined(VARIABLE_SPINDLE) + #error "USE_SPINDLE_DIR_AS_ENABLE_PIN may only be used with VARIABLE_SPINDLE enabled" +#endif + +#if defined(USE_SPINDLE_DIR_AS_ENABLE_PIN) && !defined(CPU_MAP_ATMEGA328P) + #error "USE_SPINDLE_DIR_AS_ENABLE_PIN may only be used with a 328p processor" +#endif + +#if !defined(USE_SPINDLE_DIR_AS_ENABLE_PIN) && defined(SPINDLE_ENABLE_OFF_WITH_ZERO_SPEED) + #error "SPINDLE_ENABLE_OFF_WITH_ZERO_SPEED may only be used with USE_SPINDLE_DIR_AS_ENABLE_PIN enabled" +#endif + +#if defined(PARKING_ENABLE) + #if defined(HOMING_FORCE_SET_ORIGIN) + #error "HOMING_FORCE_SET_ORIGIN is not supported with PARKING_ENABLE at this time." + #endif +#endif + +#if defined(ENABLE_PARKING_OVERRIDE_CONTROL) + #if !defined(PARKING_ENABLE) + #error "ENABLE_PARKING_OVERRIDE_CONTROL must be enabled with PARKING_ENABLE." + #endif +#endif + +#if defined(SPINDLE_PWM_MIN_VALUE) + #if !(SPINDLE_PWM_MIN_VALUE > 0) + #error "SPINDLE_PWM_MIN_VALUE must be greater than zero." + #endif +#endif + +#if (REPORT_WCO_REFRESH_BUSY_COUNT < REPORT_WCO_REFRESH_IDLE_COUNT) + #error "WCO busy refresh is less than idle refresh." +#endif +#if (REPORT_OVR_REFRESH_BUSY_COUNT < REPORT_OVR_REFRESH_IDLE_COUNT) + #error "Override busy refresh is less than idle refresh." +#endif +#if (REPORT_WCO_REFRESH_IDLE_COUNT < 2) + #error "WCO refresh must be greater than one." +#endif +#if (REPORT_OVR_REFRESH_IDLE_COUNT < 1) + #error "Override refresh must be greater than zero." +#endif + +// --------------------------------------------------------------------------------------- + +#endif diff --git a/trunk/Arduino/GRBL_1.1f/jog.c b/trunk/Arduino/GRBL_1.1f/jog.c new file mode 100644 index 00000000..553af77e --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f/jog.c @@ -0,0 +1,50 @@ +/* + jog.h - Jogging methods + Part of Grbl + + Copyright (c) 2016 Sungeun K. Jeon for Gnea Research LLC + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +#include "grbl.h" + + +// Sets up valid jog motion received from g-code parser, checks for soft-limits, and executes the jog. +uint8_t jog_execute(plan_line_data_t *pl_data, parser_block_t *gc_block) +{ + // Initialize planner data struct for jogging motions. + // NOTE: Spindle and coolant are allowed to fully function with overrides during a jog. + pl_data->feed_rate = gc_block->values.f; + pl_data->condition |= PL_COND_FLAG_NO_FEED_OVERRIDE; + #ifdef USE_LINE_NUMBERS + pl_data->line_number = gc_block->values.n; + #endif + + if (bit_istrue(settings.flags,BITFLAG_SOFT_LIMIT_ENABLE)) { + if (system_check_travel_limits(gc_block->values.xyz)) { return(STATUS_TRAVEL_EXCEEDED); } + } + + // Valid jog command. Plan, set state, and execute. + mc_line(gc_block->values.xyz,pl_data); + if (sys.state == STATE_IDLE) { + if (plan_get_current_block() != NULL) { // Check if there is a block to execute. + sys.state = STATE_JOG; + st_prep_buffer(); + st_wake_up(); // NOTE: Manual start. No state machine required. + } + } + + return(STATUS_OK); +} diff --git a/trunk/Arduino/GRBL_1.1f/jog.h b/trunk/Arduino/GRBL_1.1f/jog.h new file mode 100644 index 00000000..c7262463 --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f/jog.h @@ -0,0 +1,32 @@ +/* + jog.h - Jogging methods + Part of Grbl + + Copyright (c) 2016 Sungeun K. Jeon for Gnea Research LLC + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +#ifndef jog_h +#define jog_h + +#include "gcode.h" + +// System motion line numbers must be zero. +#define JOG_LINE_NUMBER 0 + +// Sets up valid jog motion received from g-code parser, checks for soft-limits, and executes the jog. +uint8_t jog_execute(plan_line_data_t *pl_data, parser_block_t *gc_block); + +#endif diff --git a/trunk/Arduino/GRBL_1.1f/limits.c b/trunk/Arduino/GRBL_1.1f/limits.c new file mode 100644 index 00000000..3cc2556b --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f/limits.c @@ -0,0 +1,360 @@ +/* + limits.c - code pertaining to limit-switches and performing the homing cycle + Part of Grbl + + Copyright (c) 2012-2016 Sungeun K. Jeon for Gnea Research LLC + Copyright (c) 2009-2011 Simen Svale Skogsrud + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +#include "grbl.h" + + +// Homing axis search distance multiplier. Computed by this value times the cycle travel. +#ifndef HOMING_AXIS_SEARCH_SCALAR + #define HOMING_AXIS_SEARCH_SCALAR 1.5 // Must be > 1 to ensure limit switch will be engaged. +#endif +#ifndef HOMING_AXIS_LOCATE_SCALAR + #define HOMING_AXIS_LOCATE_SCALAR 5.0 // Must be > 1 to ensure limit switch is cleared. +#endif + +void limits_init() +{ + LIMIT_DDR &= ~(LIMIT_MASK); // Set as input pins + + #ifdef DISABLE_LIMIT_PIN_PULL_UP + LIMIT_PORT &= ~(LIMIT_MASK); // Normal low operation. Requires external pull-down. + #else + LIMIT_PORT |= (LIMIT_MASK); // Enable internal pull-up resistors. Normal high operation. + #endif + + if (bit_istrue(settings.flags,BITFLAG_HARD_LIMIT_ENABLE)) { + LIMIT_PCMSK |= LIMIT_MASK; // Enable specific pins of the Pin Change Interrupt + PCICR |= (1 << LIMIT_INT); // Enable Pin Change Interrupt + } else { + limits_disable(); + } + + #ifdef ENABLE_SOFTWARE_DEBOUNCE + MCUSR &= ~(1<condition = (PL_COND_FLAG_SYSTEM_MOTION|PL_COND_FLAG_NO_FEED_OVERRIDE); + #ifdef USE_LINE_NUMBERS + pl_data->line_number = HOMING_CYCLE_LINE_NUMBER; + #endif + + // Initialize variables used for homing computations. + uint8_t n_cycle = (2*N_HOMING_LOCATE_CYCLE+1); + uint8_t step_pin[N_AXIS]; + float target[N_AXIS]; + float max_travel = 0.0; + uint8_t idx; + for (idx=0; idxfeed_rate = homing_rate; // Set current homing rate. + plan_buffer_line(target, pl_data); // Bypass mc_line(). Directly plan homing motion. + + sys.step_control = STEP_CONTROL_EXECUTE_SYS_MOTION; // Set to execute homing motion and clear existing flags. + st_prep_buffer(); // Prep and fill segment buffer from newly planned block. + st_wake_up(); // Initiate motion + do { + if (approach) { + // Check limit state. Lock out cycle axes when they change. + limit_state = limits_get_state(); + for (idx=0; idx 0); + + // The active cycle axes should now be homed and machine limits have been located. By + // default, Grbl defines machine space as all negative, as do most CNCs. Since limit switches + // can be on either side of an axes, check and set axes machine zero appropriately. Also, + // set up pull-off maneuver from axes limit switches that have been homed. This provides + // some initial clearance off the switches and should also help prevent them from falsely + // triggering when hard limits are enabled or when more than one axes shares a limit pin. + int32_t set_axis_position; + // Set machine positions for homed limit switches. Don't update non-homed axes. + for (idx=0; idx. +*/ + +#ifndef limits_h +#define limits_h + + +// Initialize the limits module +void limits_init(); + +// Disables hard limits. +void limits_disable(); + +// Returns limit state as a bit-wise uint8 variable. +uint8_t limits_get_state(); + +// Perform one portion of the homing cycle based on the input settings. +void limits_go_home(uint8_t cycle_mask); + +// Check for soft limit violations +void limits_soft_check(float *target); + +#endif diff --git a/trunk/Arduino/GRBL_1.1f/main.c b/trunk/Arduino/GRBL_1.1f/main.c new file mode 100644 index 00000000..96f2abae --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f/main.c @@ -0,0 +1,109 @@ +/* + main.c - An embedded CNC Controller with rs274/ngc (g-code) support + Part of Grbl + + Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC + Copyright (c) 2009-2011 Simen Svale Skogsrud + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +#include "grbl.h" + + +// Declare system global variable structure +system_t sys; +int32_t sys_position[N_AXIS]; // Real-time machine (aka home) position vector in steps. +int32_t sys_probe_position[N_AXIS]; // Last probe position in machine coordinates and steps. +volatile uint8_t sys_probe_state; // Probing state value. Used to coordinate the probing cycle with stepper ISR. +volatile uint8_t sys_rt_exec_state; // Global realtime executor bitflag variable for state management. See EXEC bitmasks. +volatile uint8_t sys_rt_exec_alarm; // Global realtime executor bitflag variable for setting various alarms. +volatile uint8_t sys_rt_exec_motion_override; // Global realtime executor bitflag variable for motion-based overrides. +volatile uint8_t sys_rt_exec_accessory_override; // Global realtime executor bitflag variable for spindle/coolant overrides. +#ifdef DEBUG + volatile uint8_t sys_rt_exec_debug; +#endif + + +int main(void) +{ + // Initialize system upon power-up. + serial_init(); // Setup serial baud rate and interrupts + settings_init(); // Load Grbl settings from EEPROM + stepper_init(); // Configure stepper pins and interrupt timers + system_init(); // Configure pinout pins and pin-change interrupt + + memset(sys_position,0,sizeof(sys_position)); // Clear machine position. + sei(); // Enable interrupts + + // Initialize system state. + #ifdef FORCE_INITIALIZATION_ALARM + // Force Grbl into an ALARM state upon a power-cycle or hard reset. + sys.state = STATE_ALARM; + #else + sys.state = STATE_IDLE; + #endif + + // Check for power-up and set system alarm if homing is enabled to force homing cycle + // by setting Grbl's alarm state. Alarm locks out all g-code commands, including the + // startup scripts, but allows access to settings and internal commands. Only a homing + // cycle '$H' or kill alarm locks '$X' will disable the alarm. + // NOTE: The startup script will run after successful completion of the homing cycle, but + // not after disabling the alarm locks. Prevents motion startup blocks from crashing into + // things uncontrollably. Very bad. + #ifdef HOMING_INIT_LOCK + if (bit_istrue(settings.flags,BITFLAG_HOMING_ENABLE)) { sys.state = STATE_ALARM; } + #endif + + // Grbl initialization loop upon power-up or a system abort. For the latter, all processes + // will return to this loop to be cleanly re-initialized. + for(;;) { + + // Reset system variables. + uint8_t prior_state = sys.state; + memset(&sys, 0, sizeof(system_t)); // Clear system struct variable. + sys.state = prior_state; + sys.f_override = DEFAULT_FEED_OVERRIDE; // Set to 100% + sys.r_override = DEFAULT_RAPID_OVERRIDE; // Set to 100% + sys.spindle_speed_ovr = DEFAULT_SPINDLE_SPEED_OVERRIDE; // Set to 100% + memset(sys_probe_position,0,sizeof(sys_probe_position)); // Clear probe position. + sys_probe_state = 0; + sys_rt_exec_state = 0; + sys_rt_exec_alarm = 0; + sys_rt_exec_motion_override = 0; + sys_rt_exec_accessory_override = 0; + + // Reset Grbl primary systems. + serial_reset_read_buffer(); // Clear serial read buffer + gc_init(); // Set g-code parser to default state + spindle_init(); + coolant_init(); + limits_init(); + probe_init(); + plan_reset(); // Clear block buffer and planner variables + st_reset(); // Clear stepper subsystem variables. + + // Sync cleared gcode and planner positions to current system position. + plan_sync_position(); + gc_sync_position(); + + // Print welcome message. Indicates an initialization has occured at power-up or with a reset. + report_init_message(); + + // Start Grbl main loop. Processes program inputs and executes them. + protocol_main_loop(); + + } + return 0; /* Never reached */ +} diff --git a/trunk/Arduino/GRBL_1.1f/makefile b/trunk/Arduino/GRBL_1.1f/makefile new file mode 100644 index 00000000..d0170a5a --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f/makefile @@ -0,0 +1,130 @@ +# Arduino Make file. Refer to https://github.com/sudar/Arduino-Makefile +# + +BOARD_TAG = uno +include ../paths.mk +include ../Arduino.mk + +# --- leonardo (or pro micro w/leo bootloader) +#BOARD_TAG = leonardo +#MONITOR_PORT = /dev/ttyACM0 +#include /usr/share/arduino/Arduino.mk + +# --- mega2560 ide 1.0 +#BOARD_TAG = mega2560 +#ARDUINO_PORT = /dev/ttyACM0 +#include /usr/share/arduino/Arduino.mk + +# --- mega2560 ide 1.6 +#BOARD_TAG = mega +#BOARD_SUB = atmega2560 +#MONITOR_PORT = /dev/ttyACM0 +#ARDUINO_DIR = /where/you/installed/arduino-1.6.5 +#include /usr/share/arduino/Arduino.mk + +# --- nano ide 1.0 +#BOARD_TAG = nano328 +#MONITOR_PORT = /dev/ttyUSB0 +#include /usr/share/arduino/Arduino.mk + +# --- nano ide 1.6 +#BOARD_TAG = nano +#BOARD_SUB = atmega328 +#ARDUINO_DIR = /where/you/installed/arduino-1.6.5 +#include /usr/share/arduino/Arduino.mk + +# --- pro mini +#BOARD_TAG = pro5v328 +#MONITOR_PORT = /dev/ttyUSB0 +#include /usr/share/arduino/Arduino.mk + +# --- sparkfun pro micro +#BOARD_TAG = promicro16 +#ALTERNATE_CORE = promicro +#BOARDS_TXT = $(HOME)/arduino/hardware/promicro/boards.txt +#BOOTLOADER_PARENT = $(HOME)/arduino/hardware/promicro/bootloaders +#BOOTLOADER_PATH = caterina +#BOOTLOADER_FILE = Caterina-promicro16.hex +#ISP_PROG = usbasp +#AVRDUDE_OPTS = -v +#include /usr/share/arduino/Arduino.mk + +# --- chipkit +#BOARD_TAG = mega_pic32 +#MPIDE_DIR = /where/you/installed/mpide-0023-linux64-20130817-test +#include /usr/share/arduino/chipKIT.mk + +# --- pinoccio +#BOARD_TAG = pinoccio256 +#ALTERNATE_CORE = pinoccio +#BOOTLOADER_PARENT = $(HOME)/arduino/hardware/pinoccio/bootloaders +#BOOTLOADER_PATH = STK500RFR2/release_0.51 +#BOOTLOADER_FILE = boot_pinoccio.hex +#CFLAGS_STD = -std=gnu99 +#CXXFLAGS_STD = -std=gnu++11 +#include /usr/share/arduino/Arduino.mk + +# --- fio +#BOARD_TAG = fio +#include /usr/share/arduino/Arduino.mk + +# --- atmega-ng ide 1.6 +#BOARD_TAG = atmegang +#BOARD_SUB = atmega168 +#MONITOR_PORT = /dev/ttyACM0 +#ARDUINO_DIR = /where/you/installed/arduino-1.6.5 +#include /usr/share/arduino/Arduino.mk + +# --- arduino-tiny ide 1.0 +#ISP_PROG = usbasp +#BOARD_TAG = attiny85at8 +#ALTERNATE_CORE = tiny +#ARDUINO_VAR_PATH = $(HOME)/arduino/hardware/tiny/cores/tiny +#ARDUINO_CORE_PATH = $(HOME)/arduino/hardware/tiny/cores/tiny +#AVRDUDE_OPTS = -v +#include /usr/share/arduino/Arduino.mk + +# --- arduino-tiny ide 1.6 +#ISP_PROG = usbasp +#BOARD_TAG = attiny85at8 +#ALTERNATE_CORE = tiny +#ARDUINO_DIR = /where/you/installed/arduino-1.6.5 +#include /usr/share/arduino/Arduino.mk + +# --- damellis attiny ide 1.0 +#ISP_PROG = usbasp +#BOARD_TAG = attiny85 +#ALTERNATE_CORE = attiny-master +#AVRDUDE_OPTS = -v +#include /usr/share/arduino/Arduino.mk + +# --- damellis attiny ide 1.6 +#ISP_PROG = usbasp +#BOARD_TAG = attiny +#BOARD_SUB = attiny85 +#ALTERNATE_CORE = attiny +#F_CPU = 16000000L +#ARDUINO_DIR = /where/you/installed/arduino-1.6.5 +#include /usr/share/arduino/Arduino.mk + +# --- teensy3 +#BOARD_TAG = teensy31 +#ARDUINO_DIR = /where/you/installed/the/patched/teensy/arduino-1.0.6 +#include /usr/share/arduino/Teensy.mk + +# --- mighty 1284p +#BOARD_TAG = mighty_opt +#BOARDS_TXT = $(HOME)/arduino/hardware/mighty-1284p/boards.txt +#BOOTLOADER_PARENT = $(HOME)/arduino/hardware/mighty-1284p/bootloaders +#BOOTLOADER_PATH = optiboot +#BOOTLOADER_FILE = optiboot_atmega1284p.hex +#ISP_PROG = usbasp +#AVRDUDE_OPTS = -v +#include /usr/share/arduino/Arduino.mk + +# --- atmega328p on breadboard +#BOARD_TAG = atmega328bb +#ISP_PROG = usbasp +#AVRDUDE_OPTS = -v +#BOARDS_TXT = $(HOME)/arduino/hardware/breadboard/boards.txt +#include /usr/share/arduino/Arduino.mk diff --git a/trunk/Arduino/GRBL_1.1f/motion_control.c b/trunk/Arduino/GRBL_1.1f/motion_control.c new file mode 100644 index 00000000..6e11e35c --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f/motion_control.c @@ -0,0 +1,388 @@ +/* + motion_control.c - high level interface for issuing motion commands + Part of Grbl + + Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC + Copyright (c) 2009-2011 Simen Svale Skogsrud + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +#include "grbl.h" + + +// Execute linear motion in absolute millimeter coordinates. Feed rate given in millimeters/second +// unless invert_feed_rate is true. Then the feed_rate means that the motion should be completed in +// (1 minute)/feed_rate time. +// NOTE: This is the primary gateway to the grbl planner. All line motions, including arc line +// segments, must pass through this routine before being passed to the planner. The seperation of +// mc_line and plan_buffer_line is done primarily to place non-planner-type functions from being +// in the planner and to let backlash compensation or canned cycle integration simple and direct. +void mc_line(float *target, plan_line_data_t *pl_data) +{ + // If enabled, check for soft limit violations. Placed here all line motions are picked up + // from everywhere in Grbl. + if (bit_istrue(settings.flags,BITFLAG_SOFT_LIMIT_ENABLE)) { + // NOTE: Block jog state. Jogging is a special case and soft limits are handled independently. + if (sys.state != STATE_JOG) { limits_soft_check(target); } + } + + // If in check gcode mode, prevent motion by blocking planner. Soft limits still work. + if (sys.state == STATE_CHECK_MODE) { return; } + + // NOTE: Backlash compensation may be installed here. It will need direction info to track when + // to insert a backlash line motion(s) before the intended line motion and will require its own + // plan_check_full_buffer() and check for system abort loop. Also for position reporting + // backlash steps will need to be also tracked, which will need to be kept at a system level. + // There are likely some other things that will need to be tracked as well. However, we feel + // that backlash compensation should NOT be handled by Grbl itself, because there are a myriad + // of ways to implement it and can be effective or ineffective for different CNC machines. This + // would be better handled by the interface as a post-processor task, where the original g-code + // is translated and inserts backlash motions that best suits the machine. + // NOTE: Perhaps as a middle-ground, all that needs to be sent is a flag or special command that + // indicates to Grbl what is a backlash compensation motion, so that Grbl executes the move but + // doesn't update the machine position values. Since the position values used by the g-code + // parser and planner are separate from the system machine positions, this is doable. + + // If the buffer is full: good! That means we are well ahead of the robot. + // Remain in this loop until there is room in the buffer. + do { + protocol_execute_realtime(); // Check for any run-time commands + if (sys.abort) { return; } // Bail, if system abort. + if ( plan_check_full_buffer() ) { protocol_auto_cycle_start(); } // Auto-cycle start when buffer is full. + else { break; } + } while (1); + + // Plan and queue motion into planner buffer + if (plan_buffer_line(target, pl_data) == PLAN_EMPTY_BLOCK) { + if (bit_istrue(settings.flags,BITFLAG_LASER_MODE)) { + // Correctly set spindle state, if there is a coincident position passed. Forces a buffer + // sync while in M3 laser mode only. + if (pl_data->condition & PL_COND_FLAG_SPINDLE_CW) { + spindle_sync(PL_COND_FLAG_SPINDLE_CW, pl_data->spindle_speed); + } + } + } +} + + +// Execute an arc in offset mode format. position == current xyz, target == target xyz, +// offset == offset from current xyz, axis_X defines circle plane in tool space, axis_linear is +// the direction of helical travel, radius == circle radius, isclockwise boolean. Used +// for vector transformation direction. +// The arc is approximated by generating a huge number of tiny, linear segments. The chordal tolerance +// of each segment is configured in settings.arc_tolerance, which is defined to be the maximum normal +// distance from segment to the circle when the end points both lie on the circle. +void mc_arc(float *target, plan_line_data_t *pl_data, float *position, float *offset, float radius, + uint8_t axis_0, uint8_t axis_1, uint8_t axis_linear, uint8_t is_clockwise_arc) +{ + float center_axis0 = position[axis_0] + offset[axis_0]; + float center_axis1 = position[axis_1] + offset[axis_1]; + float r_axis0 = -offset[axis_0]; // Radius vector from center to current location + float r_axis1 = -offset[axis_1]; + float rt_axis0 = target[axis_0] - center_axis0; + float rt_axis1 = target[axis_1] - center_axis1; + + // CCW angle between position and target from circle center. Only one atan2() trig computation required. + float angular_travel = atan2(r_axis0*rt_axis1-r_axis1*rt_axis0, r_axis0*rt_axis0+r_axis1*rt_axis1); + if (is_clockwise_arc) { // Correct atan2 output per direction + if (angular_travel >= -ARC_ANGULAR_TRAVEL_EPSILON) { angular_travel -= 2*M_PI; } + } else { + if (angular_travel <= ARC_ANGULAR_TRAVEL_EPSILON) { angular_travel += 2*M_PI; } + } + + // NOTE: Segment end points are on the arc, which can lead to the arc diameter being smaller by up to + // (2x) settings.arc_tolerance. For 99% of users, this is just fine. If a different arc segment fit + // is desired, i.e. least-squares, midpoint on arc, just change the mm_per_arc_segment calculation. + // For the intended uses of Grbl, this value shouldn't exceed 2000 for the strictest of cases. + uint16_t segments = floor(fabs(0.5*angular_travel*radius)/ + sqrt(settings.arc_tolerance*(2*radius - settings.arc_tolerance)) ); + + if (segments) { + // Multiply inverse feed_rate to compensate for the fact that this movement is approximated + // by a number of discrete segments. The inverse feed_rate should be correct for the sum of + // all segments. + if (pl_data->condition & PL_COND_FLAG_INVERSE_TIME) { + pl_data->feed_rate *= segments; + bit_false(pl_data->condition,PL_COND_FLAG_INVERSE_TIME); // Force as feed absolute mode over arc segments. + } + + float theta_per_segment = angular_travel/segments; + float linear_per_segment = (target[axis_linear] - position[axis_linear])/segments; + + /* Vector rotation by transformation matrix: r is the original vector, r_T is the rotated vector, + and phi is the angle of rotation. Solution approach by Jens Geisler. + r_T = [cos(phi) -sin(phi); + sin(phi) cos(phi] * r ; + + For arc generation, the center of the circle is the axis of rotation and the radius vector is + defined from the circle center to the initial position. Each line segment is formed by successive + vector rotations. Single precision values can accumulate error greater than tool precision in rare + cases. So, exact arc path correction is implemented. This approach avoids the problem of too many very + expensive trig operations [sin(),cos(),tan()] which can take 100-200 usec each to compute. + + Small angle approximation may be used to reduce computation overhead further. A third-order approximation + (second order sin() has too much error) holds for most, if not, all CNC applications. Note that this + approximation will begin to accumulate a numerical drift error when theta_per_segment is greater than + ~0.25 rad(14 deg) AND the approximation is successively used without correction several dozen times. This + scenario is extremely unlikely, since segment lengths and theta_per_segment are automatically generated + and scaled by the arc tolerance setting. Only a very large arc tolerance setting, unrealistic for CNC + applications, would cause this numerical drift error. However, it is best to set N_ARC_CORRECTION from a + low of ~4 to a high of ~20 or so to avoid trig operations while keeping arc generation accurate. + + This approximation also allows mc_arc to immediately insert a line segment into the planner + without the initial overhead of computing cos() or sin(). By the time the arc needs to be applied + a correction, the planner should have caught up to the lag caused by the initial mc_arc overhead. + This is important when there are successive arc motions. + */ + // Computes: cos_T = 1 - theta_per_segment^2/2, sin_T = theta_per_segment - theta_per_segment^3/6) in ~52usec + float cos_T = 2.0 - theta_per_segment*theta_per_segment; + float sin_T = theta_per_segment*0.16666667*(cos_T + 4.0); + cos_T *= 0.5; + + float sin_Ti; + float cos_Ti; + float r_axisi; + uint16_t i; + uint8_t count = 0; + + for (i = 1; i. +*/ + +#ifndef motion_control_h +#define motion_control_h + + +// System motion commands must have a line number of zero. +#define HOMING_CYCLE_LINE_NUMBER 0 +#define PARKING_MOTION_LINE_NUMBER 0 + +#define HOMING_CYCLE_ALL 0 // Must be zero. +#define HOMING_CYCLE_X bit(X_AXIS) +#define HOMING_CYCLE_Y bit(Y_AXIS) +#define HOMING_CYCLE_Z bit(Z_AXIS) + + +// Execute linear motion in absolute millimeter coordinates. Feed rate given in millimeters/second +// unless invert_feed_rate is true. Then the feed_rate means that the motion should be completed in +// (1 minute)/feed_rate time. +void mc_line(float *target, plan_line_data_t *pl_data); + +// Execute an arc in offset mode format. position == current xyz, target == target xyz, +// offset == offset from current xyz, axis_XXX defines circle plane in tool space, axis_linear is +// the direction of helical travel, radius == circle radius, is_clockwise_arc boolean. Used +// for vector transformation direction. +void mc_arc(float *target, plan_line_data_t *pl_data, float *position, float *offset, float radius, + uint8_t axis_0, uint8_t axis_1, uint8_t axis_linear, uint8_t is_clockwise_arc); + +// Dwell for a specific number of seconds +void mc_dwell(float seconds); + +// Perform homing cycle to locate machine zero. Requires limit switches. +void mc_homing_cycle(uint8_t cycle_mask); + +// Perform tool length probe cycle. Requires probe switch. +uint8_t mc_probe_cycle(float *target, plan_line_data_t *pl_data, uint8_t parser_flags); + +// Handles updating the override control state. +void mc_override_ctrl_update(uint8_t override_state); + +// Plans and executes the single special motion case for parking. Independent of main planner buffer. +void mc_parking_motion(float *parking_target, plan_line_data_t *pl_data); + +// Performs system reset. If in motion state, kills all motion and sets system alarm. +void mc_reset(); + +#endif diff --git a/trunk/Arduino/GRBL_1.1f/nuts_bolts.c b/trunk/Arduino/GRBL_1.1f/nuts_bolts.c new file mode 100644 index 00000000..9d89a8d0 --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f/nuts_bolts.c @@ -0,0 +1,190 @@ +/* + nuts_bolts.c - Shared functions + Part of Grbl + + Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC + Copyright (c) 2009-2011 Simen Svale Skogsrud + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +#include "grbl.h" + + +#define MAX_INT_DIGITS 8 // Maximum number of digits in int32 (and float) + + +// Extracts a floating point value from a string. The following code is based loosely on +// the avr-libc strtod() function by Michael Stumpf and Dmitry Xmelkov and many freely +// available conversion method examples, but has been highly optimized for Grbl. For known +// CNC applications, the typical decimal value is expected to be in the range of E0 to E-4. +// Scientific notation is officially not supported by g-code, and the 'E' character may +// be a g-code word on some CNC systems. So, 'E' notation will not be recognized. +// NOTE: Thanks to Radu-Eosif Mihailescu for identifying the issues with using strtod(). +uint8_t read_float(char *line, uint8_t *char_counter, float *float_ptr) +{ + char *ptr = line + *char_counter; + unsigned char c; + + // Grab first character and increment pointer. No spaces assumed in line. + c = *ptr++; + + // Capture initial positive/minus character + bool isnegative = false; + if (c == '-') { + isnegative = true; + c = *ptr++; + } else if (c == '+') { + c = *ptr++; + } + + // Extract number into fast integer. Track decimal in terms of exponent value. + uint32_t intval = 0; + int8_t exp = 0; + uint8_t ndigit = 0; + bool isdecimal = false; + while(1) { + c -= '0'; + if (c <= 9) { + ndigit++; + if (ndigit <= MAX_INT_DIGITS) { + if (isdecimal) { exp--; } + intval = (((intval << 2) + intval) << 1) + c; // intval*10 + c + } else { + if (!(isdecimal)) { exp++; } // Drop overflow digits + } + } else if (c == (('.'-'0') & 0xff) && !(isdecimal)) { + isdecimal = true; + } else { + break; + } + c = *ptr++; + } + + // Return if no digits have been read. + if (!ndigit) { return(false); }; + + // Convert integer into floating point. + float fval; + fval = (float)intval; + + // Apply decimal. Should perform no more than two floating point multiplications for the + // expected range of E0 to E-4. + if (fval != 0) { + while (exp <= -2) { + fval *= 0.01; + exp += 2; + } + if (exp < 0) { + fval *= 0.1; + } else if (exp > 0) { + do { + fval *= 10.0; + } while (--exp > 0); + } + } + + // Assign floating point value with correct sign. + if (isnegative) { + *float_ptr = -fval; + } else { + *float_ptr = fval; + } + + *char_counter = ptr - line - 1; // Set char_counter to next statement + + return(true); +} + + +// Non-blocking delay function used for general operation and suspend features. +void delay_sec(float seconds, uint8_t mode) +{ + uint16_t i = ceil(1000/DWELL_TIME_STEP*seconds); + while (i-- > 0) { + if (sys.abort) { return; } + if (mode == DELAY_MODE_DWELL) { + protocol_execute_realtime(); + } else { // DELAY_MODE_SYS_SUSPEND + // Execute rt_system() only to avoid nesting suspend loops. + protocol_exec_rt_system(); + if (sys.suspend & SUSPEND_RESTART_RETRACT) { return; } // Bail, if safety door reopens. + } + _delay_ms(DWELL_TIME_STEP); // Delay DWELL_TIME_STEP increment + } +} + + +// Delays variable defined milliseconds. Compiler compatibility fix for _delay_ms(), +// which only accepts constants in future compiler releases. +void delay_ms(uint16_t ms) +{ + while ( ms-- ) { _delay_ms(1); } +} + + +// Delays variable defined microseconds. Compiler compatibility fix for _delay_us(), +// which only accepts constants in future compiler releases. Written to perform more +// efficiently with larger delays, as the counter adds parasitic time in each iteration. +void delay_us(uint32_t us) +{ + while (us) { + if (us < 10) { + _delay_us(1); + us--; + } else if (us < 100) { + _delay_us(10); + us -= 10; + } else if (us < 1000) { + _delay_us(100); + us -= 100; + } else { + _delay_ms(1); + us -= 1000; + } + } +} + + +// Simple hypotenuse computation function. +float hypot_f(float x, float y) { return(sqrt(x*x + y*y)); } + + +float convert_delta_vector_to_unit_vector(float *vector) +{ + uint8_t idx; + float magnitude = 0.0; + for (idx=0; idx. +*/ + +#ifndef nuts_bolts_h +#define nuts_bolts_h + +#define false 0 +#define true 1 + +#define SOME_LARGE_VALUE 1.0E+38 + +// Axis array index values. Must start with 0 and be continuous. +#define N_AXIS 3 // Number of axes +#define X_AXIS 0 // Axis indexing value. +#define Y_AXIS 1 +#define Z_AXIS 2 +// #define A_AXIS 3 + +// CoreXY motor assignments. DO NOT ALTER. +// NOTE: If the A and B motor axis bindings are changed, this effects the CoreXY equations. +#ifdef COREXY + #define A_MOTOR X_AXIS // Must be X_AXIS + #define B_MOTOR Y_AXIS // Must be Y_AXIS +#endif + +// Conversions +#define MM_PER_INCH (25.40) +#define INCH_PER_MM (0.0393701) +#define TICKS_PER_MICROSECOND (F_CPU/1000000) + +#define DELAY_MODE_DWELL 0 +#define DELAY_MODE_SYS_SUSPEND 1 + +// Useful macros +#define clear_vector(a) memset(a, 0, sizeof(a)) +#define clear_vector_float(a) memset(a, 0.0, sizeof(float)*N_AXIS) +// #define clear_vector_long(a) memset(a, 0.0, sizeof(long)*N_AXIS) +#define max(a,b) (((a) > (b)) ? (a) : (b)) +#define min(a,b) (((a) < (b)) ? (a) : (b)) +#define isequal_position_vector(a,b) !(memcmp(a, b, sizeof(float)*N_AXIS)) + +// Bit field and masking macros +#define bit(n) (1 << n) +#define bit_true(x,mask) (x) |= (mask) +#define bit_false(x,mask) (x) &= ~(mask) +#define bit_istrue(x,mask) ((x & mask) != 0) +#define bit_isfalse(x,mask) ((x & mask) == 0) + +// Read a floating point value from a string. Line points to the input buffer, char_counter +// is the indexer pointing to the current character of the line, while float_ptr is +// a pointer to the result variable. Returns true when it succeeds +uint8_t read_float(char *line, uint8_t *char_counter, float *float_ptr); + +// Non-blocking delay function used for general operation and suspend features. +void delay_sec(float seconds, uint8_t mode); + +// Delays variable-defined milliseconds. Compiler compatibility fix for _delay_ms(). +void delay_ms(uint16_t ms); + +// Delays variable-defined microseconds. Compiler compatibility fix for _delay_us(). +void delay_us(uint32_t us); + +// Computes hypotenuse, avoiding avr-gcc's bloated version and the extra error checking. +float hypot_f(float x, float y); + +float convert_delta_vector_to_unit_vector(float *vector); +float limit_value_by_axis_maximum(float *max_value, float *unit_vec); + +#endif diff --git a/trunk/Arduino/GRBL_1.1f/planner.c b/trunk/Arduino/GRBL_1.1f/planner.c new file mode 100644 index 00000000..4839bbf4 --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f/planner.c @@ -0,0 +1,522 @@ +/* + planner.c - buffers movement commands and manages the acceleration profile plan + Part of Grbl + + Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC + Copyright (c) 2009-2011 Simen Svale Skogsrud + Copyright (c) 2011 Jens Geisler + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +#include "grbl.h" + + +static plan_block_t block_buffer[BLOCK_BUFFER_SIZE]; // A ring buffer for motion instructions +static uint8_t block_buffer_tail; // Index of the block to process now +static uint8_t block_buffer_head; // Index of the next block to be pushed +static uint8_t next_buffer_head; // Index of the next buffer head +static uint8_t block_buffer_planned; // Index of the optimally planned block + +// Define planner variables +typedef struct { + int32_t position[N_AXIS]; // The planner position of the tool in absolute steps. Kept separate + // from g-code position for movements requiring multiple line motions, + // i.e. arcs, canned cycles, and backlash compensation. + float previous_unit_vec[N_AXIS]; // Unit vector of previous path line segment + float previous_nominal_speed; // Nominal speed of previous path line segment +} planner_t; +static planner_t pl; + + +// Returns the index of the next block in the ring buffer. Also called by stepper segment buffer. +uint8_t plan_next_block_index(uint8_t block_index) +{ + block_index++; + if (block_index == BLOCK_BUFFER_SIZE) { block_index = 0; } + return(block_index); +} + + +// Returns the index of the previous block in the ring buffer +static uint8_t plan_prev_block_index(uint8_t block_index) +{ + if (block_index == 0) { block_index = BLOCK_BUFFER_SIZE; } + block_index--; + return(block_index); +} + + +/* PLANNER SPEED DEFINITION + +--------+ <- current->nominal_speed + / \ + current->entry_speed -> + \ + | + <- next->entry_speed (aka exit speed) + +-------------+ + time --> + + Recalculates the motion plan according to the following basic guidelines: + + 1. Go over every feasible block sequentially in reverse order and calculate the junction speeds + (i.e. current->entry_speed) such that: + a. No junction speed exceeds the pre-computed maximum junction speed limit or nominal speeds of + neighboring blocks. + b. A block entry speed cannot exceed one reverse-computed from its exit speed (next->entry_speed) + with a maximum allowable deceleration over the block travel distance. + c. The last (or newest appended) block is planned from a complete stop (an exit speed of zero). + 2. Go over every block in chronological (forward) order and dial down junction speed values if + a. The exit speed exceeds the one forward-computed from its entry speed with the maximum allowable + acceleration over the block travel distance. + + When these stages are complete, the planner will have maximized the velocity profiles throughout the all + of the planner blocks, where every block is operating at its maximum allowable acceleration limits. In + other words, for all of the blocks in the planner, the plan is optimal and no further speed improvements + are possible. If a new block is added to the buffer, the plan is recomputed according to the said + guidelines for a new optimal plan. + + To increase computational efficiency of these guidelines, a set of planner block pointers have been + created to indicate stop-compute points for when the planner guidelines cannot logically make any further + changes or improvements to the plan when in normal operation and new blocks are streamed and added to the + planner buffer. For example, if a subset of sequential blocks in the planner have been planned and are + bracketed by junction velocities at their maximums (or by the first planner block as well), no new block + added to the planner buffer will alter the velocity profiles within them. So we no longer have to compute + them. Or, if a set of sequential blocks from the first block in the planner (or a optimal stop-compute + point) are all accelerating, they are all optimal and can not be altered by a new block added to the + planner buffer, as this will only further increase the plan speed to chronological blocks until a maximum + junction velocity is reached. However, if the operational conditions of the plan changes from infrequently + used feed holds or feedrate overrides, the stop-compute pointers will be reset and the entire plan is + recomputed as stated in the general guidelines. + + Planner buffer index mapping: + - block_buffer_tail: Points to the beginning of the planner buffer. First to be executed or being executed. + - block_buffer_head: Points to the buffer block after the last block in the buffer. Used to indicate whether + the buffer is full or empty. As described for standard ring buffers, this block is always empty. + - next_buffer_head: Points to next planner buffer block after the buffer head block. When equal to the + buffer tail, this indicates the buffer is full. + - block_buffer_planned: Points to the first buffer block after the last optimally planned block for normal + 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 plan_discard_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 + enough combined distance traveled in the entire buffer to accelerate up to the nominal speed and then + decelerate to a complete stop at the end of the buffer, as stated by the guidelines. If this happens and + becomes an annoyance, there are a few simple solutions: (1) Maximize the machine acceleration. The planner + will be able to compute higher velocity profiles within the same combined distance. (2) Maximize line + motion(s) distance per block to a desired tolerance. The more combined distance the planner has to use, + the faster it can go. (3) Maximize the planner buffer size. This also will increase the combined distance + for the planner to compute over. It also increases the number of computations the planner has to perform + to compute an optimal plan, so select carefully. The Arduino 328p memory is already maxed out, but future + ARM versions should have enough memory and speed for look-ahead blocks numbering up to a hundred or more. + +*/ +static void planner_recalculate() +{ + // Initialize block index to the last block in the planner buffer. + uint8_t block_index = plan_prev_block_index(block_buffer_head); + + // Bail. Can't do anything with one only one plan-able block. + if (block_index == block_buffer_planned) { return; } + + // Reverse Pass: Coarsely maximize all possible deceleration curves back-planning from the last + // block in buffer. Cease planning when the last optimal planned or tail pointer is reached. + // NOTE: Forward pass will later refine and correct the reverse pass to create an optimal plan. + float entry_speed_sqr; + plan_block_t *next; + plan_block_t *current = &block_buffer[block_index]; + + // Calculate maximum entry speed for last block in buffer, where the exit speed is always zero. + current->entry_speed_sqr = min( current->max_entry_speed_sqr, 2*current->acceleration*current->millimeters); + + block_index = plan_prev_block_index(block_index); + if (block_index == block_buffer_planned) { // Only two plannable blocks in buffer. Reverse pass complete. + // Check if the first block is the tail. If so, notify stepper to update its current parameters. + if (block_index == block_buffer_tail) { st_update_plan_block_parameters(); } + } else { // Three or more plan-able blocks + while (block_index != block_buffer_planned) { + next = current; + current = &block_buffer[block_index]; + block_index = plan_prev_block_index(block_index); + + // Check if next block is the tail block(=planned block). If so, update current stepper parameters. + if (block_index == block_buffer_tail) { st_update_plan_block_parameters(); } + + // Compute maximum entry speed decelerating over the current block from its exit speed. + if (current->entry_speed_sqr != current->max_entry_speed_sqr) { + entry_speed_sqr = next->entry_speed_sqr + 2*current->acceleration*current->millimeters; + if (entry_speed_sqr < current->max_entry_speed_sqr) { + current->entry_speed_sqr = entry_speed_sqr; + } else { + current->entry_speed_sqr = current->max_entry_speed_sqr; + } + } + } + } + + // Forward Pass: Forward plan the acceleration curve from the planned pointer onward. + // Also scans for optimal plan breakpoints and appropriately updates the planned pointer. + next = &block_buffer[block_buffer_planned]; // Begin at buffer planned pointer + block_index = plan_next_block_index(block_buffer_planned); + while (block_index != block_buffer_head) { + current = next; + next = &block_buffer[block_index]; + + // Any acceleration detected in the forward pass automatically moves the optimal planned + // pointer forward, since everything before this is all optimal. In other words, nothing + // can improve the plan from the buffer tail to the planned pointer by logic. + if (current->entry_speed_sqr < next->entry_speed_sqr) { + entry_speed_sqr = current->entry_speed_sqr + 2*current->acceleration*current->millimeters; + // If true, current block is full-acceleration and we can move the planned pointer forward. + if (entry_speed_sqr < next->entry_speed_sqr) { + next->entry_speed_sqr = entry_speed_sqr; // Always <= max_entry_speed_sqr. Backward pass sets this. + block_buffer_planned = block_index; // Set optimal plan pointer. + } + } + + // Any block set at its maximum entry speed also creates an optimal plan up to this + // point in the buffer. When the plan is bracketed by either the beginning of the + // buffer and a maximum entry speed or two maximum entry speeds, every block in between + // cannot logically be further improved. Hence, we don't have to recompute them anymore. + if (next->entry_speed_sqr == next->max_entry_speed_sqr) { block_buffer_planned = block_index; } + block_index = plan_next_block_index( block_index ); + } +} + + +void plan_reset() +{ + memset(&pl, 0, sizeof(planner_t)); // Clear planner struct + plan_reset_buffer(); +} + + +void plan_reset_buffer() +{ + block_buffer_tail = 0; + block_buffer_head = 0; // Empty = tail + next_buffer_head = 1; // plan_next_block_index(block_buffer_head) + block_buffer_planned = 0; // = block_buffer_tail; +} + + +void plan_discard_current_block() +{ + if (block_buffer_head != block_buffer_tail) { // Discard non-empty buffer. + uint8_t block_index = plan_next_block_index( block_buffer_tail ); + // Push block_buffer_planned pointer, if encountered. + if (block_buffer_tail == block_buffer_planned) { block_buffer_planned = block_index; } + block_buffer_tail = block_index; + } +} + + +// Returns address of planner buffer block used by system motions. Called by segment generator. +plan_block_t *plan_get_system_motion_block() +{ + return(&block_buffer[block_buffer_head]); +} + + +// Returns address of first planner block, if available. Called by various main program functions. +plan_block_t *plan_get_current_block() +{ + if (block_buffer_head == block_buffer_tail) { return(NULL); } // Buffer empty + return(&block_buffer[block_buffer_tail]); +} + + +float plan_get_exec_block_exit_speed_sqr() +{ + uint8_t block_index = plan_next_block_index(block_buffer_tail); + if (block_index == block_buffer_head) { return( 0.0 ); } + return( block_buffer[block_index].entry_speed_sqr ); +} + + +// Returns the availability status of the block ring buffer. True, if full. +uint8_t plan_check_full_buffer() +{ + if (block_buffer_tail == next_buffer_head) { return(true); } + return(false); +} + + +// Computes and returns block nominal speed based on running condition and override values. +// NOTE: All system motion commands, such as homing/parking, are not subject to overrides. +float plan_compute_profile_nominal_speed(plan_block_t *block) +{ + float nominal_speed = block->programmed_rate; + if (block->condition & PL_COND_FLAG_RAPID_MOTION) { nominal_speed *= (0.01*sys.r_override); } + else { + if (!(block->condition & PL_COND_FLAG_NO_FEED_OVERRIDE)) { nominal_speed *= (0.01*sys.f_override); } + if (nominal_speed > block->rapid_rate) { nominal_speed = block->rapid_rate; } + } + if (nominal_speed > MINIMUM_FEED_RATE) { return(nominal_speed); } + return(MINIMUM_FEED_RATE); +} + + +// Computes and updates the max entry speed (sqr) of the block, based on the minimum of the junction's +// previous and current nominal speeds and max junction speed. +static void plan_compute_profile_parameters(plan_block_t *block, float nominal_speed, float prev_nominal_speed) +{ + // Compute the junction maximum entry based on the minimum of the junction speed and neighboring nominal speeds. + if (nominal_speed > prev_nominal_speed) { block->max_entry_speed_sqr = prev_nominal_speed*prev_nominal_speed; } + else { block->max_entry_speed_sqr = nominal_speed*nominal_speed; } + if (block->max_entry_speed_sqr > block->max_junction_speed_sqr) { block->max_entry_speed_sqr = block->max_junction_speed_sqr; } +} + + +// Re-calculates buffered motions profile parameters upon a motion-based override change. +void plan_update_velocity_profile_parameters() +{ + uint8_t block_index = block_buffer_tail; + plan_block_t *block; + float nominal_speed; + float prev_nominal_speed = SOME_LARGE_VALUE; // Set high for first block nominal speed calculation. + while (block_index != block_buffer_head) { + block = &block_buffer[block_index]; + nominal_speed = plan_compute_profile_nominal_speed(block); + plan_compute_profile_parameters(block, nominal_speed, prev_nominal_speed); + prev_nominal_speed = nominal_speed; + block_index = plan_next_block_index(block_index); + } + pl.previous_nominal_speed = prev_nominal_speed; // Update prev nominal speed for next incoming block. +} + + +/* Add a new linear movement to the buffer. target[N_AXIS] is the signed, absolute target position + in millimeters. Feed rate specifies the speed of the motion. If feed rate is inverted, the feed + rate is taken to mean "frequency" and would complete the operation in 1/feed_rate minutes. + All position data passed to the planner must be in terms of machine position to keep the planner + independent of any coordinate system changes and offsets, which are handled by the g-code parser. + NOTE: Assumes buffer is available. Buffer checks are handled at a higher level by motion_control. + In other words, the buffer head is never equal to the buffer tail. Also the feed rate input value + is used in three ways: as a normal feed rate if invert_feed_rate is false, as inverse time if + invert_feed_rate is true, or as seek/rapids rate if the feed_rate value is negative (and + invert_feed_rate always false). + The system motion condition tells the planner to plan a motion in the always unused block buffer + head. It avoids changing the planner state and preserves the buffer to ensure subsequent gcode + motions are still planned correctly, while the stepper module only points to the block buffer head + to execute the special system motion. */ +uint8_t plan_buffer_line(float *target, plan_line_data_t *pl_data) +{ + // Prepare and initialize new block. Copy relevant pl_data for block execution. + plan_block_t *block = &block_buffer[block_buffer_head]; + memset(block,0,sizeof(plan_block_t)); // Zero all block values. + block->condition = pl_data->condition; + #ifdef VARIABLE_SPINDLE + block->spindle_speed = pl_data->spindle_speed; + #endif + #ifdef USE_LINE_NUMBERS + block->line_number = pl_data->line_number; + #endif + + // Compute and store initial move distance data. + int32_t target_steps[N_AXIS], position_steps[N_AXIS]; + float unit_vec[N_AXIS], delta_mm; + uint8_t idx; + + // Copy position data based on type of motion being planned. + if (block->condition & PL_COND_FLAG_SYSTEM_MOTION) { + #ifdef COREXY + position_steps[X_AXIS] = system_convert_corexy_to_x_axis_steps(sys_position); + position_steps[Y_AXIS] = system_convert_corexy_to_y_axis_steps(sys_position); + position_steps[Z_AXIS] = sys_position[Z_AXIS]; + #else + memcpy(position_steps, sys_position, sizeof(sys_position)); + #endif + } else { memcpy(position_steps, pl.position, sizeof(pl.position)); } + + #ifdef COREXY + target_steps[A_MOTOR] = lround(target[A_MOTOR]*settings.steps_per_mm[A_MOTOR]); + target_steps[B_MOTOR] = lround(target[B_MOTOR]*settings.steps_per_mm[B_MOTOR]); + block->steps[A_MOTOR] = labs((target_steps[X_AXIS]-position_steps[X_AXIS]) + (target_steps[Y_AXIS]-position_steps[Y_AXIS])); + block->steps[B_MOTOR] = labs((target_steps[X_AXIS]-position_steps[X_AXIS]) - (target_steps[Y_AXIS]-position_steps[Y_AXIS])); + #endif + + for (idx=0; idxsteps[idx] = labs(target_steps[idx]-position_steps[idx]); + } + block->step_event_count = max(block->step_event_count, block->steps[idx]); + if (idx == A_MOTOR) { + delta_mm = (target_steps[X_AXIS]-position_steps[X_AXIS] + target_steps[Y_AXIS]-position_steps[Y_AXIS])/settings.steps_per_mm[idx]; + } else if (idx == B_MOTOR) { + delta_mm = (target_steps[X_AXIS]-position_steps[X_AXIS] - target_steps[Y_AXIS]+position_steps[Y_AXIS])/settings.steps_per_mm[idx]; + } else { + delta_mm = (target_steps[idx] - position_steps[idx])/settings.steps_per_mm[idx]; + } + #else + target_steps[idx] = lround(target[idx]*settings.steps_per_mm[idx]); + block->steps[idx] = labs(target_steps[idx]-position_steps[idx]); + block->step_event_count = max(block->step_event_count, block->steps[idx]); + delta_mm = (target_steps[idx] - position_steps[idx])/settings.steps_per_mm[idx]; + #endif + unit_vec[idx] = delta_mm; // Store unit vector numerator + + // Set direction bits. Bit enabled always means direction is negative. + if (delta_mm < 0.0 ) { block->direction_bits |= get_direction_pin_mask(idx); } + } + + // Bail if this is a zero-length block. Highly unlikely to occur. + if (block->step_event_count == 0) { return(PLAN_EMPTY_BLOCK); } + + // Calculate the unit vector of the line move and the block maximum feed rate and acceleration scaled + // down such that no individual axes maximum values are exceeded with respect to the line direction. + // NOTE: This calculation assumes all axes are orthogonal (Cartesian) and works with ABC-axes, + // if they are also orthogonal/independent. Operates on the absolute value of the unit vector. + block->millimeters = convert_delta_vector_to_unit_vector(unit_vec); + block->acceleration = limit_value_by_axis_maximum(settings.acceleration, unit_vec); + block->rapid_rate = limit_value_by_axis_maximum(settings.max_rate, unit_vec); + + // Store programmed rate. + if (block->condition & PL_COND_FLAG_RAPID_MOTION) { block->programmed_rate = block->rapid_rate; } + else { + block->programmed_rate = pl_data->feed_rate; + if (block->condition & PL_COND_FLAG_INVERSE_TIME) { block->programmed_rate *= block->millimeters; } + } + + // TODO: Need to check this method handling zero junction speeds when starting from rest. + if ((block_buffer_head == block_buffer_tail) || (block->condition & PL_COND_FLAG_SYSTEM_MOTION)) { + + // Initialize block entry speed as zero. Assume it will be starting from rest. Planner will correct this later. + // If system motion, the system motion block always is assumed to start from rest and end at a complete stop. + block->entry_speed_sqr = 0.0; + block->max_junction_speed_sqr = 0.0; // Starting from rest. Enforce start from zero velocity. + + } else { + // 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 + // deviation is defined as the distance from the junction to the closest edge of the circle, + // colinear with the circle center. The circular segment joining the two paths represents the + // path of centripetal acceleration. Solve for max velocity based on max acceleration about the + // radius of the circle, defined indirectly by junction deviation. This may be also viewed as + // path width or max_jerk in the previous Grbl version. This approach does not actually deviate + // from path, but used as a robust way to compute cornering speeds, as it takes into account the + // nonlinearities of both the junction angle and junction velocity. + // + // NOTE: If the junction deviation value is finite, Grbl executes the motions in an exact path + // mode (G61). If the junction deviation value is zero, Grbl will execute the motion in an exact + // stop mode (G61.1) manner. In the future, if continuous mode (G64) is desired, the math here + // is exactly the same. Instead of motioning all the way to junction point, the machine will + // just follow the arc circle defined here. The Arduino doesn't have the CPU cycles to perform + // a continuous mode path, but ARM-based microcontrollers most certainly do. + // + // NOTE: The max junction speed is a fixed value, since machine acceleration limits cannot be + // changed dynamically during operation nor can the line move geometry. This must be kept in + // memory in the event of a feedrate override changing the nominal speeds of blocks, which can + // change the overall maximum entry speed conditions of all blocks. + + float junction_unit_vec[N_AXIS]; + float junction_cos_theta = 0.0; + for (idx=0; idx 0.999999) { + // For a 0 degree acute junction, just set minimum junction speed. + block->max_junction_speed_sqr = MINIMUM_JUNCTION_SPEED*MINIMUM_JUNCTION_SPEED; + } else { + if (junction_cos_theta < -0.999999) { + // Junction is a straight line or 180 degrees. Junction speed is infinite. + block->max_junction_speed_sqr = SOME_LARGE_VALUE; + } else { + convert_delta_vector_to_unit_vector(junction_unit_vec); + float junction_acceleration = limit_value_by_axis_maximum(settings.acceleration, junction_unit_vec); + float sin_theta_d2 = sqrt(0.5*(1.0-junction_cos_theta)); // Trig half angle identity. Always positive. + block->max_junction_speed_sqr = max( MINIMUM_JUNCTION_SPEED*MINIMUM_JUNCTION_SPEED, + (junction_acceleration * settings.junction_deviation * sin_theta_d2)/(1.0-sin_theta_d2) ); + } + } + } + + // Block system motion from updating this data to ensure next g-code motion is computed correctly. + if (!(block->condition & PL_COND_FLAG_SYSTEM_MOTION)) { + float nominal_speed = plan_compute_profile_nominal_speed(block); + plan_compute_profile_parameters(block, nominal_speed, pl.previous_nominal_speed); + pl.previous_nominal_speed = nominal_speed; + + // Update previous path unit_vector and planner position. + memcpy(pl.previous_unit_vec, unit_vec, sizeof(unit_vec)); // pl.previous_unit_vec[] = unit_vec[] + memcpy(pl.position, target_steps, sizeof(target_steps)); // pl.position[] = target_steps[] + + // New block is all set. Update buffer head and next buffer head indices. + block_buffer_head = next_buffer_head; + next_buffer_head = plan_next_block_index(block_buffer_head); + + // Finish up by recalculating the plan with the new block. + planner_recalculate(); + } + return(PLAN_OK); +} + + +// Reset the planner position vectors. Called by the system abort/initialization routine. +void plan_sync_position() +{ + // TODO: For motor configurations not in the same coordinate frame as the machine position, + // this function needs to be updated to accomodate the difference. + uint8_t idx; + for (idx=0; idx= block_buffer_tail) { return((BLOCK_BUFFER_SIZE-1)-(block_buffer_head-block_buffer_tail)); } + return((block_buffer_tail-block_buffer_head-1)); +} + + +// Returns the number of active blocks are in the planner buffer. +// NOTE: Deprecated. Not used unless classic status reports are enabled in config.h +uint8_t plan_get_block_buffer_count() +{ + if (block_buffer_head >= block_buffer_tail) { return(block_buffer_head-block_buffer_tail); } + return(BLOCK_BUFFER_SIZE - (block_buffer_tail-block_buffer_head)); +} + + +// Re-initialize buffer plan with a partially completed block, assumed to exist at the buffer tail. +// Called after a steppers have come to a complete stop for a feed hold and the cycle is stopped. +void plan_cycle_reinitialize() +{ + // Re-plan from a complete stop. Reset planner entry speeds and buffer planned pointer. + st_update_plan_block_parameters(); + block_buffer_planned = block_buffer_tail; + planner_recalculate(); +} diff --git a/trunk/Arduino/GRBL_1.1f/planner.h b/trunk/Arduino/GRBL_1.1f/planner.h new file mode 100644 index 00000000..e3751e16 --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f/planner.h @@ -0,0 +1,150 @@ +/* + planner.h - buffers movement commands and manages the acceleration profile plan + Part of Grbl + + Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC + Copyright (c) 2009-2011 Simen Svale Skogsrud + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +#ifndef planner_h +#define planner_h + + +// The number of linear motions that can be in the plan at any give time +#ifndef BLOCK_BUFFER_SIZE + #ifdef USE_LINE_NUMBERS + #define BLOCK_BUFFER_SIZE 15 + #else + #define BLOCK_BUFFER_SIZE 16 + #endif +#endif + +// Returned status message from planner. +#define PLAN_OK true +#define PLAN_EMPTY_BLOCK false + +// Define planner data condition flags. Used to denote running conditions of a block. +#define PL_COND_FLAG_RAPID_MOTION bit(0) +#define PL_COND_FLAG_SYSTEM_MOTION bit(1) // Single motion. Circumvents planner state. Used by home/park. +#define PL_COND_FLAG_NO_FEED_OVERRIDE bit(2) // Motion does not honor feed override. +#define PL_COND_FLAG_INVERSE_TIME bit(3) // Interprets feed rate value as inverse time when set. +#define PL_COND_FLAG_SPINDLE_CW bit(4) +#define PL_COND_FLAG_SPINDLE_CCW bit(5) +#define PL_COND_FLAG_COOLANT_FLOOD bit(6) +#define PL_COND_FLAG_COOLANT_MIST bit(7) +#define PL_COND_MOTION_MASK (PL_COND_FLAG_RAPID_MOTION|PL_COND_FLAG_SYSTEM_MOTION|PL_COND_FLAG_NO_FEED_OVERRIDE) +#define PL_COND_SPINDLE_MASK (PL_COND_FLAG_SPINDLE_CW|PL_COND_FLAG_SPINDLE_CCW) +#define PL_COND_ACCESSORY_MASK (PL_COND_FLAG_SPINDLE_CW|PL_COND_FLAG_SPINDLE_CCW|PL_COND_FLAG_COOLANT_FLOOD|PL_COND_FLAG_COOLANT_MIST) + + +// This struct stores a linear movement of a g-code block motion with its critical "nominal" values +// are as specified in the source g-code. +typedef struct { + // Fields used by the bresenham algorithm for tracing the line + // NOTE: Used by stepper algorithm to execute the block correctly. Do not alter these values. + uint32_t steps[N_AXIS]; // Step count along each axis + uint32_t step_event_count; // The maximum step axis count and number of steps required to complete this block. + uint8_t direction_bits; // The direction bit set for this block (refers to *_DIRECTION_BIT in config.h) + + // Block condition data to ensure correct execution depending on states and overrides. + uint8_t condition; // Block bitflag variable defining block run conditions. Copied from pl_line_data. + #ifdef USE_LINE_NUMBERS + int32_t line_number; // Block line number for real-time reporting. Copied from pl_line_data. + #endif + + // Fields used by the motion planner to manage acceleration. Some of these values may be updated + // by the stepper module during execution of special motion cases for replanning purposes. + float entry_speed_sqr; // The current planned entry speed at block junction in (mm/min)^2 + float max_entry_speed_sqr; // Maximum allowable entry speed based on the minimum of junction limit and + // neighboring nominal speeds with overrides in (mm/min)^2 + float acceleration; // Axis-limit adjusted line acceleration in (mm/min^2). Does not change. + float millimeters; // The remaining distance for this block to be executed in (mm). + // NOTE: This value may be altered by stepper algorithm during execution. + + // Stored rate limiting data used by planner when changes occur. + float max_junction_speed_sqr; // Junction entry speed limit based on direction vectors in (mm/min)^2 + float rapid_rate; // Axis-limit adjusted maximum rate for this block direction in (mm/min) + float programmed_rate; // Programmed rate of this block (mm/min). + + #ifdef VARIABLE_SPINDLE + // Stored spindle speed data used by spindle overrides and resuming methods. + float spindle_speed; // Block spindle speed. Copied from pl_line_data. + #endif +} plan_block_t; + + +// Planner data prototype. Must be used when passing new motions to the planner. +typedef struct { + float feed_rate; // Desired feed rate for line motion. Value is ignored, if rapid motion. + float spindle_speed; // Desired spindle speed through line motion. + uint8_t condition; // Bitflag variable to indicate planner conditions. See defines above. + #ifdef USE_LINE_NUMBERS + int32_t line_number; // Desired line number to report when executing. + #endif +} plan_line_data_t; + + +// Initialize and reset the motion plan subsystem +void plan_reset(); // Reset all +void plan_reset_buffer(); // Reset buffer only. + +// Add a new linear movement to the buffer. target[N_AXIS] is the signed, absolute target position +// in millimeters. Feed rate specifies the speed of the motion. If feed rate is inverted, the feed +// rate is taken to mean "frequency" and would complete the operation in 1/feed_rate minutes. +uint8_t plan_buffer_line(float *target, plan_line_data_t *pl_data); + +// Called when the current block is no longer needed. Discards the block and makes the memory +// availible for new blocks. +void plan_discard_current_block(); + +// Gets the planner block for the special system motion cases. (Parking/Homing) +plan_block_t *plan_get_system_motion_block(); + +// Gets the current block. Returns NULL if buffer empty +plan_block_t *plan_get_current_block(); + +// Called periodically by step segment buffer. Mostly used internally by planner. +uint8_t plan_next_block_index(uint8_t block_index); + +// Called by step segment buffer when computing executing block velocity profile. +float plan_get_exec_block_exit_speed_sqr(); + +// Called by main program during planner calculations and step segment buffer during initialization. +float plan_compute_profile_nominal_speed(plan_block_t *block); + +// Re-calculates buffered motions profile parameters upon a motion-based override change. +void plan_update_velocity_profile_parameters(); + +// Reset the planner position vector (in steps) +void plan_sync_position(); + +// Reinitialize plan with a partially completed block +void plan_cycle_reinitialize(); + +// Returns the number of available blocks are in the planner buffer. +uint8_t plan_get_block_buffer_available(); + +// Returns the number of active blocks are in the planner buffer. +// NOTE: Deprecated. Not used unless classic status reports are enabled in config.h +uint8_t plan_get_block_buffer_count(); + +// Returns the status of the block ring buffer. True, if buffer is full. +uint8_t plan_check_full_buffer(); + +void plan_get_planner_mpos(float *target); + + +#endif diff --git a/trunk/Arduino/GRBL_1.1f/print.c b/trunk/Arduino/GRBL_1.1f/print.c new file mode 100644 index 00000000..771e3996 --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f/print.c @@ -0,0 +1,200 @@ +/* + print.c - Functions for formatting output strings + Part of Grbl + + Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC + Copyright (c) 2009-2011 Simen Svale Skogsrud + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +#include "grbl.h" + + +void printString(const char *s) +{ + while (*s) + serial_write(*s++); +} + + +// Print a string stored in PGM-memory +void printPgmString(const char *s) +{ + char c; + while ((c = pgm_read_byte_near(s++))) + serial_write(c); +} + + +// void printIntegerInBase(unsigned long n, unsigned long base) +// { +// unsigned char buf[8 * sizeof(long)]; // Assumes 8-bit chars. +// unsigned long i = 0; +// +// if (n == 0) { +// serial_write('0'); +// return; +// } +// +// while (n > 0) { +// buf[i++] = n % base; +// n /= base; +// } +// +// for (; i > 0; i--) +// serial_write(buf[i - 1] < 10 ? +// '0' + buf[i - 1] : +// 'A' + buf[i - 1] - 10); +// } + + +// Prints an uint8 variable in base 10. +void print_uint8_base10(uint8_t n) +{ + uint8_t digit_a = 0; + uint8_t digit_b = 0; + if (n >= 100) { // 100-255 + digit_a = '0' + n % 10; + n /= 10; + } + if (n >= 10) { // 10-99 + digit_b = '0' + n % 10; + n /= 10; + } + serial_write('0' + n); + if (digit_b) { serial_write(digit_b); } + if (digit_a) { serial_write(digit_a); } +} + + +// Prints an uint8 variable in base 2 with desired number of desired digits. +void print_uint8_base2_ndigit(uint8_t n, uint8_t digits) { + unsigned char buf[digits]; + uint8_t i = 0; + + for (; i < digits; i++) { + buf[i] = n % 2 ; + n /= 2; + } + + for (; i > 0; i--) + serial_write('0' + buf[i - 1]); +} + + +void print_uint32_base10(uint32_t n) +{ + if (n == 0) { + serial_write('0'); + return; + } + + unsigned char buf[10]; + uint8_t i = 0; + + while (n > 0) { + buf[i++] = n % 10; + n /= 10; + } + + for (; i > 0; i--) + serial_write('0' + buf[i-1]); +} + + +void printInteger(long n) +{ + if (n < 0) { + serial_write('-'); + print_uint32_base10(-n); + } else { + print_uint32_base10(n); + } +} + + +// Convert float to string by immediately converting to a long integer, which contains +// more digits than a float. Number of decimal places, which are tracked by a counter, +// may be set by the user. The integer is then efficiently converted to a string. +// NOTE: AVR '%' and '/' integer operations are very efficient. Bitshifting speed-up +// techniques are actually just slightly slower. Found this out the hard way. +void printFloat(float n, uint8_t decimal_places) +{ + if (n < 0) { + serial_write('-'); + n = -n; + } + + uint8_t decimals = decimal_places; + while (decimals >= 2) { // Quickly convert values expected to be E0 to E-4. + n *= 100; + decimals -= 2; + } + if (decimals) { n *= 10; } + n += 0.5; // Add rounding factor. Ensures carryover through entire value. + + // Generate digits backwards and store in string. + unsigned char buf[13]; + uint8_t i = 0; + uint32_t a = (long)n; + while(a > 0) { + buf[i++] = (a % 10) + '0'; // Get digit + a /= 10; + } + while (i < decimal_places) { + buf[i++] = '0'; // Fill in zeros to decimal point for (n < 1) + } + if (i == decimal_places) { // Fill in leading zero, if needed. + buf[i++] = '0'; + } + + // Print the generated string. + for (; i > 0; i--) { + if (i == decimal_places) { serial_write('.'); } // Insert decimal point in right place. + serial_write(buf[i-1]); + } +} + + +// Floating value printing handlers for special variables types used in Grbl and are defined +// in the config.h. +// - CoordValue: Handles all position or coordinate values in inches or mm reporting. +// - RateValue: Handles feed rate and current velocity in inches or mm reporting. +void printFloat_CoordValue(float n) { + if (bit_istrue(settings.flags,BITFLAG_REPORT_INCHES)) { + printFloat(n*INCH_PER_MM,N_DECIMAL_COORDVALUE_INCH); + } else { + printFloat(n,N_DECIMAL_COORDVALUE_MM); + } +} + +void printFloat_RateValue(float n) { + if (bit_istrue(settings.flags,BITFLAG_REPORT_INCHES)) { + printFloat(n*INCH_PER_MM,N_DECIMAL_RATEVALUE_INCH); + } else { + printFloat(n,N_DECIMAL_RATEVALUE_MM); + } +} + +// Debug tool to print free memory in bytes at the called point. +// NOTE: Keep commented unless using. Part of this function always gets compiled in. +// void printFreeMemory() +// { +// extern int __heap_start, *__brkval; +// uint16_t free; // Up to 64k values. +// free = (int) &free - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); +// printInteger((int32_t)free); +// printString(" "); +// } diff --git a/trunk/Arduino/GRBL_1.1f/print.h b/trunk/Arduino/GRBL_1.1f/print.h new file mode 100644 index 00000000..31e0a576 --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f/print.h @@ -0,0 +1,51 @@ +/* + print.h - Functions for formatting output strings + Part of Grbl + + Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC + Copyright (c) 2009-2011 Simen Svale Skogsrud + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +#ifndef print_h +#define print_h + + +void printString(const char *s); + +void printPgmString(const char *s); + +void printInteger(long n); + +void print_uint32_base10(uint32_t n); + +// Prints an uint8 variable in base 10. +void print_uint8_base10(uint8_t n); + +// Prints an uint8 variable in base 2 with desired number of desired digits. +void print_uint8_base2_ndigit(uint8_t n, uint8_t digits); + +void printFloat(float n, uint8_t decimal_places); + +// Floating value printing handlers for special variables types used in Grbl. +// - CoordValue: Handles all position or coordinate values in inches or mm reporting. +// - RateValue: Handles feed rate and current velocity in inches or mm reporting. +void printFloat_CoordValue(float n); +void printFloat_RateValue(float n); + +// Debug tool to print free memory in bytes at the called point. Not used otherwise. +void printFreeMemory(); + +#endif diff --git a/trunk/Arduino/GRBL_1.1f/probe.c b/trunk/Arduino/GRBL_1.1f/probe.c new file mode 100644 index 00000000..60c9073a --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f/probe.c @@ -0,0 +1,66 @@ +/* + probe.c - code pertaining to probing methods + Part of Grbl + + Copyright (c) 2014-2016 Sungeun K. Jeon for Gnea Research LLC + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +#include "grbl.h" + + +// Inverts the probe pin state depending on user settings and probing cycle mode. +uint8_t probe_invert_mask; + + +// Probe pin initialization routine. +void probe_init() +{ + PROBE_DDR &= ~(PROBE_MASK); // Configure as input pins + #ifdef DISABLE_PROBE_PIN_PULL_UP + PROBE_PORT &= ~(PROBE_MASK); // Normal low operation. Requires external pull-down. + #else + PROBE_PORT |= PROBE_MASK; // Enable internal pull-up resistors. Normal high operation. + #endif + probe_configure_invert_mask(false); // Initialize invert mask. +} + + +// Called by probe_init() and the mc_probe() routines. Sets up the probe pin invert mask to +// appropriately set the pin logic according to setting for normal-high/normal-low operation +// and the probing cycle modes for toward-workpiece/away-from-workpiece. +void probe_configure_invert_mask(uint8_t is_probe_away) +{ + probe_invert_mask = 0; // Initialize as zero. + if (bit_isfalse(settings.flags,BITFLAG_INVERT_PROBE_PIN)) { probe_invert_mask ^= PROBE_MASK; } + if (is_probe_away) { probe_invert_mask ^= PROBE_MASK; } +} + + +// Returns the probe pin state. Triggered = true. Called by gcode parser and probe state monitor. +uint8_t probe_get_state() { return((PROBE_PIN & PROBE_MASK) ^ probe_invert_mask); } + + +// Monitors probe pin state and records the system position when detected. Called by the +// stepper ISR per ISR tick. +// NOTE: This function must be extremely efficient as to not bog down the stepper ISR. +void probe_state_monitor() +{ + if (probe_get_state()) { + sys_probe_state = PROBE_OFF; + memcpy(sys_probe_position, sys_position, sizeof(sys_position)); + bit_true(sys_rt_exec_state, EXEC_MOTION_CANCEL); + } +} diff --git a/trunk/Arduino/GRBL_1.1f/probe.h b/trunk/Arduino/GRBL_1.1f/probe.h new file mode 100644 index 00000000..03d5fd32 --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f/probe.h @@ -0,0 +1,43 @@ +/* + probe.h - code pertaining to probing methods + Part of Grbl + + Copyright (c) 2014-2016 Sungeun K. Jeon for Gnea Research LLC + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +#ifndef probe_h +#define probe_h + +// Values that define the probing state machine. +#define PROBE_OFF 0 // Probing disabled or not in use. (Must be zero.) +#define PROBE_ACTIVE 1 // Actively watching the input pin. + +// Probe pin initialization routine. +void probe_init(); + +// Called by probe_init() and the mc_probe() routines. Sets up the probe pin invert mask to +// appropriately set the pin logic according to setting for normal-high/normal-low operation +// and the probing cycle modes for toward-workpiece/away-from-workpiece. +void probe_configure_invert_mask(uint8_t is_probe_away); + +// Returns probe pin state. Triggered = true. Called by gcode parser and probe state monitor. +uint8_t probe_get_state(); + +// Monitors probe pin state and records the system position when detected. Called by the +// stepper ISR per ISR tick. +void probe_state_monitor(); + +#endif diff --git a/trunk/Arduino/GRBL_1.1f/protocol.c b/trunk/Arduino/GRBL_1.1f/protocol.c new file mode 100644 index 00000000..08ea48bf --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f/protocol.c @@ -0,0 +1,765 @@ +/* + protocol.c - controls Grbl execution protocol and procedures + Part of Grbl + + Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC + Copyright (c) 2009-2011 Simen Svale Skogsrud + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +#include "grbl.h" + +// Define line flags. Includes comment type tracking and line overflow detection. +#define LINE_FLAG_OVERFLOW bit(0) +#define LINE_FLAG_COMMENT_PARENTHESES bit(1) +#define LINE_FLAG_COMMENT_SEMICOLON bit(2) + + +static char line[LINE_BUFFER_SIZE]; // Line to be executed. Zero-terminated. + +static void protocol_exec_rt_suspend(); + + +/* + GRBL PRIMARY LOOP: +*/ +void protocol_main_loop() +{ + // Perform some machine checks to make sure everything is good to go. + #ifdef CHECK_LIMITS_AT_INIT + if (bit_istrue(settings.flags, BITFLAG_HARD_LIMIT_ENABLE)) { + if (limits_get_state()) { + sys.state = STATE_ALARM; // Ensure alarm state is active. + report_feedback_message(MESSAGE_CHECK_LIMITS); + } + } + #endif + // Check for and report alarm state after a reset, error, or an initial power up. + // NOTE: Sleep mode disables the stepper drivers and position can't be guaranteed. + // Re-initialize the sleep state as an ALARM mode to ensure user homes or acknowledges. + if (sys.state & (STATE_ALARM | STATE_SLEEP)) { + report_feedback_message(MESSAGE_ALARM_LOCK); + sys.state = STATE_ALARM; // Ensure alarm state is set. + } else { + // Check if the safety door is open. + sys.state = STATE_IDLE; + if (system_check_safety_door_ajar()) { + bit_true(sys_rt_exec_state, EXEC_SAFETY_DOOR); + protocol_execute_realtime(); // Enter safety door mode. Should return as IDLE state. + } + // All systems go! + system_execute_startup(line); // Execute startup script. + } + + // --------------------------------------------------------------------------------- + // Primary loop! Upon a system abort, this exits back to main() to reset the system. + // This is also where Grbl idles while waiting for something to do. + // --------------------------------------------------------------------------------- + + uint8_t line_flags = 0; + uint8_t char_counter = 0; + uint8_t c; + for (;;) { + + // Process one line of incoming serial data, as the data becomes available. Performs an + // initial filtering by removing spaces and comments and capitalizing all letters. + while((c = serial_read()) != SERIAL_NO_DATA) { + if ((c == '\n') || (c == '\r')) { // End of line reached + + protocol_execute_realtime(); // Runtime command check point. + if (sys.abort) { return; } // Bail to calling function upon system abort + + line[char_counter] = 0; // Set string termination character. + #ifdef REPORT_ECHO_LINE_RECEIVED + report_echo_line_received(line); + #endif + + // Direct and execute one line of formatted input, and report status of execution. + if (line_flags & LINE_FLAG_OVERFLOW) { + // Report line overflow error. + report_status_message(STATUS_OVERFLOW); + } else if (line[0] == 0) { + // Empty or comment line. For syncing purposes. + report_status_message(STATUS_OK); + } else if (line[0] == '$') { + // Grbl '$' system command + report_status_message(system_execute_line(line)); + } else if (sys.state & (STATE_ALARM | STATE_JOG)) { + // Everything else is gcode. Block if in alarm or jog mode. + report_status_message(STATUS_SYSTEM_GC_LOCK); + } else { + // Parse and execute g-code block. + report_status_message(gc_execute_line(line)); + } + + // Reset tracking data for next line. + line_flags = 0; + char_counter = 0; + + } else { + + if (line_flags) { + // Throw away all (except EOL) comment characters and overflow characters. + if (c == ')') { + // End of '()' comment. Resume line allowed. + if (line_flags & LINE_FLAG_COMMENT_PARENTHESES) { line_flags &= ~(LINE_FLAG_COMMENT_PARENTHESES); } + } + } else { + if (c <= ' ') { + // Throw away whitepace and control characters + } else if (c == '/') { + // Block delete NOT SUPPORTED. Ignore character. + // NOTE: If supported, would simply need to check the system if block delete is enabled. + } else if (c == '(') { + // Enable comments flag and ignore all characters until ')' or EOL. + // NOTE: This doesn't follow the NIST definition exactly, but is good enough for now. + // In the future, we could simply remove the items within the comments, but retain the + // comment control characters, so that the g-code parser can error-check it. + line_flags |= LINE_FLAG_COMMENT_PARENTHESES; + } else if (c == ';') { + // NOTE: ';' comment to EOL is a LinuxCNC definition. Not NIST. + line_flags |= LINE_FLAG_COMMENT_SEMICOLON; + // TODO: Install '%' feature + // } else if (c == '%') { + // Program start-end percent sign NOT SUPPORTED. + // NOTE: This maybe installed to tell Grbl when a program is running vs manual input, + // where, during a program, the system auto-cycle start will continue to execute + // everything until the next '%' sign. This will help fix resuming issues with certain + // functions that empty the planner buffer to execute its task on-time. + } else if (char_counter >= (LINE_BUFFER_SIZE-1)) { + // Detect line buffer overflow and set flag. + line_flags |= LINE_FLAG_OVERFLOW; + } else if (c >= 'a' && c <= 'z') { // Upcase lowercase + line[char_counter++] = c-'a'+'A'; + } else { + line[char_counter++] = c; + } + } + + } + } + + // If there are no more characters in the serial read buffer to be processed and executed, + // this indicates that g-code streaming has either filled the planner buffer or has + // completed. In either case, auto-cycle start, if enabled, any queued moves. + protocol_auto_cycle_start(); + + protocol_execute_realtime(); // Runtime command check point. + if (sys.abort) { return; } // Bail to main() program loop to reset system. + } + + return; /* Never reached */ +} + + +// Block until all buffered steps are executed or in a cycle state. Works with feed hold +// during a synchronize call, if it should happen. Also, waits for clean cycle end. +void protocol_buffer_synchronize() +{ + // If system is queued, ensure cycle resumes if the auto start flag is present. + protocol_auto_cycle_start(); + do { + protocol_execute_realtime(); // Check and execute run-time commands + if (sys.abort) { return; } // Check for system abort + } while (plan_get_current_block() || (sys.state == STATE_CYCLE)); +} + + +// Auto-cycle start triggers when there is a motion ready to execute and if the main program is not +// actively parsing commands. +// NOTE: This function is called from the main loop, buffer sync, and mc_line() only and executes +// when one of these conditions exist respectively: There are no more blocks sent (i.e. streaming +// is finished, single commands), a command that needs to wait for the motions in the buffer to +// execute calls a buffer sync, or the planner buffer is full and ready to go. +void protocol_auto_cycle_start() +{ + if (plan_get_current_block() != NULL) { // Check if there are any blocks in the buffer. + system_set_exec_state_flag(EXEC_CYCLE_START); // If so, execute them! + } +} + + +// This function is the general interface to Grbl's real-time command execution system. It is called +// from various check points in the main program, primarily where there may be a while loop waiting +// for a buffer to clear space or any point where the execution time from the last check point may +// be more than a fraction of a second. This is a way to execute realtime commands asynchronously +// (aka multitasking) with grbl's g-code parsing and planning functions. This function also serves +// as an interface for the interrupts to set the system realtime flags, where only the main program +// handles them, removing the need to define more computationally-expensive volatile variables. This +// also provides a controlled way to execute certain tasks without having two or more instances of +// the same task, such as the planner recalculating the buffer upon a feedhold or overrides. +// NOTE: The sys_rt_exec_state variable flags are set by any process, step or serial interrupts, pinouts, +// limit switches, or the main program. +void protocol_execute_realtime() +{ + protocol_exec_rt_system(); + if (sys.suspend) { protocol_exec_rt_suspend(); } +} + + +// Executes run-time commands, when required. This function primarily operates as Grbl's state +// machine and controls the various real-time features Grbl has to offer. +// NOTE: Do not alter this unless you know exactly what you are doing! +void protocol_exec_rt_system() +{ + uint8_t rt_exec; // Temp variable to avoid calling volatile multiple times. + rt_exec = sys_rt_exec_alarm; // Copy volatile sys_rt_exec_alarm. + if (rt_exec) { // Enter only if any bit flag is true + // System alarm. Everything has shutdown by something that has gone severely wrong. Report + // the source of the error to the user. If critical, Grbl disables by entering an infinite + // loop until system reset/abort. + sys.state = STATE_ALARM; // Set system alarm state + report_alarm_message(rt_exec); + // Halt everything upon a critical event flag. Currently hard and soft limits flag this. + if ((rt_exec == EXEC_ALARM_HARD_LIMIT) || (rt_exec == EXEC_ALARM_SOFT_LIMIT)) { + report_feedback_message(MESSAGE_CRITICAL_EVENT); + system_clear_exec_state_flag(EXEC_RESET); // Disable any existing reset + do { + // Block everything, except reset and status reports, until user issues reset or power + // cycles. Hard limits typically occur while unattended or not paying attention. Gives + // the user and a GUI time to do what is needed before resetting, like killing the + // incoming stream. The same could be said about soft limits. While the position is not + // lost, continued streaming could cause a serious crash if by chance it gets executed. + } while (bit_isfalse(sys_rt_exec_state,EXEC_RESET)); + } + system_clear_exec_alarm(); // Clear alarm + } + + rt_exec = sys_rt_exec_state; // Copy volatile sys_rt_exec_state. + if (rt_exec) { + + // Execute system abort. + if (rt_exec & EXEC_RESET) { + sys.abort = true; // Only place this is set true. + return; // Nothing else to do but exit. + } + + // Execute and serial print status + if (rt_exec & EXEC_STATUS_REPORT) { + report_realtime_status(); + system_clear_exec_state_flag(EXEC_STATUS_REPORT); + } + + // NOTE: Once hold is initiated, the system immediately enters a suspend state to block all + // main program processes until either reset or resumed. This ensures a hold completes safely. + if (rt_exec & (EXEC_MOTION_CANCEL | EXEC_FEED_HOLD | EXEC_SAFETY_DOOR | EXEC_SLEEP)) { + + // State check for allowable states for hold methods. + if (!(sys.state & (STATE_ALARM | STATE_CHECK_MODE))) { + + // If in CYCLE or JOG states, immediately initiate a motion HOLD. + if (sys.state & (STATE_CYCLE | STATE_JOG)) { + if (!(sys.suspend & (SUSPEND_MOTION_CANCEL | SUSPEND_JOG_CANCEL))) { // Block, if already holding. + st_update_plan_block_parameters(); // Notify stepper module to recompute for hold deceleration. + sys.step_control = STEP_CONTROL_EXECUTE_HOLD; // Initiate suspend state with active flag. + if (sys.state == STATE_JOG) { // Jog cancelled upon any hold event, except for sleeping. + if (!(rt_exec & EXEC_SLEEP)) { sys.suspend |= SUSPEND_JOG_CANCEL; } + } + } + } + // If IDLE, Grbl is not in motion. Simply indicate suspend state and hold is complete. + if (sys.state == STATE_IDLE) { sys.suspend = SUSPEND_HOLD_COMPLETE; } + + // Execute and flag a motion cancel with deceleration and return to idle. Used primarily by probing cycle + // to halt and cancel the remainder of the motion. + if (rt_exec & EXEC_MOTION_CANCEL) { + // MOTION_CANCEL only occurs during a CYCLE, but a HOLD and SAFETY_DOOR may been initiated beforehand + // to hold the CYCLE. Motion cancel is valid for a single planner block motion only, while jog cancel + // will handle and clear multiple planner block motions. + if (!(sys.state & STATE_JOG)) { sys.suspend |= SUSPEND_MOTION_CANCEL; } // NOTE: State is STATE_CYCLE. + } + + // Execute a feed hold with deceleration, if required. Then, suspend system. + if (rt_exec & EXEC_FEED_HOLD) { + // Block SAFETY_DOOR, JOG, and SLEEP states from changing to HOLD state. + if (!(sys.state & (STATE_SAFETY_DOOR | STATE_JOG | STATE_SLEEP))) { sys.state = STATE_HOLD; } + } + + // Execute a safety door stop with a feed hold and disable spindle/coolant. + // NOTE: Safety door differs from feed holds by stopping everything no matter state, disables powered + // devices (spindle/coolant), and blocks resuming until switch is re-engaged. + if (rt_exec & EXEC_SAFETY_DOOR) { + report_feedback_message(MESSAGE_SAFETY_DOOR_AJAR); + // If jogging, block safety door methods until jog cancel is complete. Just flag that it happened. + if (!(sys.suspend & SUSPEND_JOG_CANCEL)) { + // Check if the safety re-opened during a restore parking motion only. Ignore if + // already retracting, parked or in sleep state. + if (sys.state == STATE_SAFETY_DOOR) { + if (sys.suspend & SUSPEND_INITIATE_RESTORE) { // Actively restoring + #ifdef PARKING_ENABLE + // Set hold and reset appropriate control flags to restart parking sequence. + if (sys.step_control & STEP_CONTROL_EXECUTE_SYS_MOTION) { + st_update_plan_block_parameters(); // Notify stepper module to recompute for hold deceleration. + sys.step_control = (STEP_CONTROL_EXECUTE_HOLD | STEP_CONTROL_EXECUTE_SYS_MOTION); + sys.suspend &= ~(SUSPEND_HOLD_COMPLETE); + } // else NO_MOTION is active. + #endif + sys.suspend &= ~(SUSPEND_RETRACT_COMPLETE | SUSPEND_INITIATE_RESTORE | SUSPEND_RESTORE_COMPLETE); + sys.suspend |= SUSPEND_RESTART_RETRACT; + } + } + if (sys.state != STATE_SLEEP) { sys.state = STATE_SAFETY_DOOR; } + } + // NOTE: This flag doesn't change when the door closes, unlike sys.state. Ensures any parking motions + // are executed if the door switch closes and the state returns to HOLD. + sys.suspend |= SUSPEND_SAFETY_DOOR_AJAR; + } + + } + + if (rt_exec & EXEC_SLEEP) { + if (sys.state == STATE_ALARM) { sys.suspend |= (SUSPEND_RETRACT_COMPLETE|SUSPEND_HOLD_COMPLETE); } + sys.state = STATE_SLEEP; + } + + system_clear_exec_state_flag((EXEC_MOTION_CANCEL | EXEC_FEED_HOLD | EXEC_SAFETY_DOOR | EXEC_SLEEP)); + } + + // Execute a cycle start by starting the stepper interrupt to begin executing the blocks in queue. + if (rt_exec & EXEC_CYCLE_START) { + // Block if called at same time as the hold commands: feed hold, motion cancel, and safety door. + // Ensures auto-cycle-start doesn't resume a hold without an explicit user-input. + if (!(rt_exec & (EXEC_FEED_HOLD | EXEC_MOTION_CANCEL | EXEC_SAFETY_DOOR))) { + // Resume door state when parking motion has retracted and door has been closed. + if ((sys.state == STATE_SAFETY_DOOR) && !(sys.suspend & SUSPEND_SAFETY_DOOR_AJAR)) { + if (sys.suspend & SUSPEND_RESTORE_COMPLETE) { + sys.state = STATE_IDLE; // Set to IDLE to immediately resume the cycle. + } else if (sys.suspend & SUSPEND_RETRACT_COMPLETE) { + // Flag to re-energize powered components and restore original position, if disabled by SAFETY_DOOR. + // NOTE: For a safety door to resume, the switch must be closed, as indicated by HOLD state, and + // the retraction execution is complete, which implies the initial feed hold is not active. To + // restore normal operation, the restore procedures must be initiated by the following flag. Once, + // they are complete, it will call CYCLE_START automatically to resume and exit the suspend. + sys.suspend |= SUSPEND_INITIATE_RESTORE; + } + } + // Cycle start only when IDLE or when a hold is complete and ready to resume. + if ((sys.state == STATE_IDLE) || ((sys.state & STATE_HOLD) && (sys.suspend & SUSPEND_HOLD_COMPLETE))) { + if (sys.state == STATE_HOLD && sys.spindle_stop_ovr) { + sys.spindle_stop_ovr |= SPINDLE_STOP_OVR_RESTORE_CYCLE; // Set to restore in suspend routine and cycle start after. + } else { + // Start cycle only if queued motions exist in planner buffer and the motion is not canceled. + sys.step_control = STEP_CONTROL_NORMAL_OP; // Restore step control to normal operation + if (plan_get_current_block() && bit_isfalse(sys.suspend,SUSPEND_MOTION_CANCEL)) { + sys.suspend = SUSPEND_DISABLE; // Break suspend state. + sys.state = STATE_CYCLE; + st_prep_buffer(); // Initialize step segment buffer before beginning cycle. + st_wake_up(); + } else { // Otherwise, do nothing. Set and resume IDLE state. + sys.suspend = SUSPEND_DISABLE; // Break suspend state. + sys.state = STATE_IDLE; + } + } + } + } + system_clear_exec_state_flag(EXEC_CYCLE_START); + } + + if (rt_exec & EXEC_CYCLE_STOP) { + // Reinitializes the cycle plan and stepper system after a feed hold for a resume. Called by + // realtime command execution in the main program, ensuring that the planner re-plans safely. + // NOTE: Bresenham algorithm variables are still maintained through both the planner and stepper + // cycle reinitializations. The stepper path should continue exactly as if nothing has happened. + // NOTE: EXEC_CYCLE_STOP is set by the stepper subsystem when a cycle or feed hold completes. + if ((sys.state & (STATE_HOLD|STATE_SAFETY_DOOR|STATE_SLEEP)) && !(sys.soft_limit) && !(sys.suspend & SUSPEND_JOG_CANCEL)) { + // Hold complete. Set to indicate ready to resume. Remain in HOLD or DOOR states until user + // has issued a resume command or reset. + plan_cycle_reinitialize(); + if (sys.step_control & STEP_CONTROL_EXECUTE_HOLD) { sys.suspend |= SUSPEND_HOLD_COMPLETE; } + bit_false(sys.step_control,(STEP_CONTROL_EXECUTE_HOLD | STEP_CONTROL_EXECUTE_SYS_MOTION)); + } else { + // Motion complete. Includes CYCLE/JOG/HOMING states and jog cancel/motion cancel/soft limit events. + // NOTE: Motion and jog cancel both immediately return to idle after the hold completes. + if (sys.suspend & SUSPEND_JOG_CANCEL) { // For jog cancel, flush buffers and sync positions. + sys.step_control = STEP_CONTROL_NORMAL_OP; + plan_reset(); + st_reset(); + gc_sync_position(); + plan_sync_position(); + } + if (sys.suspend & SUSPEND_SAFETY_DOOR_AJAR) { // Only occurs when safety door opens during jog. + sys.suspend &= ~(SUSPEND_JOG_CANCEL); + sys.suspend |= SUSPEND_HOLD_COMPLETE; + sys.state = STATE_SAFETY_DOOR; + } else { + sys.suspend = SUSPEND_DISABLE; + sys.state = STATE_IDLE; + } + } + system_clear_exec_state_flag(EXEC_CYCLE_STOP); + } + } + + // Execute overrides. + rt_exec = sys_rt_exec_motion_override; // Copy volatile sys_rt_exec_motion_override + if (rt_exec) { + system_clear_exec_motion_overrides(); // Clear all motion override flags. + + uint8_t new_f_override = sys.f_override; + if (rt_exec & EXEC_FEED_OVR_RESET) { new_f_override = DEFAULT_FEED_OVERRIDE; } + if (rt_exec & EXEC_FEED_OVR_COARSE_PLUS) { new_f_override += FEED_OVERRIDE_COARSE_INCREMENT; } + if (rt_exec & EXEC_FEED_OVR_COARSE_MINUS) { new_f_override -= FEED_OVERRIDE_COARSE_INCREMENT; } + if (rt_exec & EXEC_FEED_OVR_FINE_PLUS) { new_f_override += FEED_OVERRIDE_FINE_INCREMENT; } + if (rt_exec & EXEC_FEED_OVR_FINE_MINUS) { new_f_override -= FEED_OVERRIDE_FINE_INCREMENT; } + new_f_override = min(new_f_override,MAX_FEED_RATE_OVERRIDE); + new_f_override = max(new_f_override,MIN_FEED_RATE_OVERRIDE); + + uint8_t new_r_override = sys.r_override; + if (rt_exec & EXEC_RAPID_OVR_RESET) { new_r_override = DEFAULT_RAPID_OVERRIDE; } + if (rt_exec & EXEC_RAPID_OVR_MEDIUM) { new_r_override = RAPID_OVERRIDE_MEDIUM; } + if (rt_exec & EXEC_RAPID_OVR_LOW) { new_r_override = RAPID_OVERRIDE_LOW; } + + if ((new_f_override != sys.f_override) || (new_r_override != sys.r_override)) { + sys.f_override = new_f_override; + sys.r_override = new_r_override; + sys.report_ovr_counter = 0; // Set to report change immediately + plan_update_velocity_profile_parameters(); + plan_cycle_reinitialize(); + } + } + + rt_exec = sys_rt_exec_accessory_override; + if (rt_exec) { + system_clear_exec_accessory_overrides(); // Clear all accessory override flags. + + // NOTE: Unlike motion overrides, spindle overrides do not require a planner reinitialization. + uint8_t last_s_override = sys.spindle_speed_ovr; + if (rt_exec & EXEC_SPINDLE_OVR_RESET) { last_s_override = DEFAULT_SPINDLE_SPEED_OVERRIDE; } + if (rt_exec & EXEC_SPINDLE_OVR_COARSE_PLUS) { last_s_override += SPINDLE_OVERRIDE_COARSE_INCREMENT; } + if (rt_exec & EXEC_SPINDLE_OVR_COARSE_MINUS) { last_s_override -= SPINDLE_OVERRIDE_COARSE_INCREMENT; } + if (rt_exec & EXEC_SPINDLE_OVR_FINE_PLUS) { last_s_override += SPINDLE_OVERRIDE_FINE_INCREMENT; } + if (rt_exec & EXEC_SPINDLE_OVR_FINE_MINUS) { last_s_override -= SPINDLE_OVERRIDE_FINE_INCREMENT; } + last_s_override = min(last_s_override,MAX_SPINDLE_SPEED_OVERRIDE); + last_s_override = max(last_s_override,MIN_SPINDLE_SPEED_OVERRIDE); + + if (last_s_override != sys.spindle_speed_ovr) { + sys.spindle_speed_ovr = last_s_override; + // NOTE: Spindle speed overrides during HOLD state are taken care of by suspend function. + if (sys.state == STATE_IDLE) { spindle_set_state(gc_state.modal.spindle, gc_state.spindle_speed); } + else { bit_true(sys.step_control, STEP_CONTROL_UPDATE_SPINDLE_PWM); } + sys.report_ovr_counter = 0; // Set to report change immediately + } + + if (rt_exec & EXEC_SPINDLE_OVR_STOP) { + // Spindle stop override allowed only while in HOLD state. + // NOTE: Report counters are set in spindle_set_state() when spindle stop is executed. + if (sys.state == STATE_HOLD) { + if (!(sys.spindle_stop_ovr)) { sys.spindle_stop_ovr = SPINDLE_STOP_OVR_INITIATE; } + else if (sys.spindle_stop_ovr & SPINDLE_STOP_OVR_ENABLED) { sys.spindle_stop_ovr |= SPINDLE_STOP_OVR_RESTORE; } + } + } + + // NOTE: Since coolant state always performs a planner sync whenever it changes, the current + // run state can be determined by checking the parser state. + // NOTE: Coolant overrides only operate during IDLE, CYCLE, HOLD, and JOG states. Ignored otherwise. + if (rt_exec & (EXEC_COOLANT_FLOOD_OVR_TOGGLE | EXEC_COOLANT_MIST_OVR_TOGGLE)) { + if ((sys.state == STATE_IDLE) || (sys.state & (STATE_CYCLE | STATE_HOLD | STATE_JOG))) { + uint8_t coolant_state = gc_state.modal.coolant; + #ifdef ENABLE_M7 + if (rt_exec & EXEC_COOLANT_MIST_OVR_TOGGLE) { + if (coolant_state & COOLANT_MIST_ENABLE) { bit_false(coolant_state,COOLANT_MIST_ENABLE); } + else { coolant_state |= COOLANT_MIST_ENABLE; } + } + if (rt_exec & EXEC_COOLANT_FLOOD_OVR_TOGGLE) { + if (coolant_state & COOLANT_FLOOD_ENABLE) { bit_false(coolant_state,COOLANT_FLOOD_ENABLE); } + else { coolant_state |= COOLANT_FLOOD_ENABLE; } + } + #else + if (coolant_state & COOLANT_FLOOD_ENABLE) { bit_false(coolant_state,COOLANT_FLOOD_ENABLE); } + else { coolant_state |= COOLANT_FLOOD_ENABLE; } + #endif + coolant_set_state(coolant_state); // Report counter set in coolant_set_state(). + gc_state.modal.coolant = coolant_state; + } + } + } + + #ifdef DEBUG + if (sys_rt_exec_debug) { + report_realtime_debug(); + sys_rt_exec_debug = 0; + } + #endif + + // Reload step segment buffer + if (sys.state & (STATE_CYCLE | STATE_HOLD | STATE_SAFETY_DOOR | STATE_HOMING | STATE_SLEEP| STATE_JOG)) { + st_prep_buffer(); + } + +} + + +// Handles Grbl system suspend procedures, such as feed hold, safety door, and parking motion. +// The system will enter this loop, create local variables for suspend tasks, and return to +// whatever function that invoked the suspend, such that Grbl resumes normal operation. +// This function is written in a way to promote custom parking motions. Simply use this as a +// template +static void protocol_exec_rt_suspend() +{ + #ifdef PARKING_ENABLE + // Declare and initialize parking local variables + float restore_target[N_AXIS]; + float parking_target[N_AXIS]; + float retract_waypoint = PARKING_PULLOUT_INCREMENT; + plan_line_data_t plan_data; + plan_line_data_t *pl_data = &plan_data; + memset(pl_data,0,sizeof(plan_line_data_t)); + pl_data->condition = (PL_COND_FLAG_SYSTEM_MOTION|PL_COND_FLAG_NO_FEED_OVERRIDE); + #ifdef USE_LINE_NUMBERS + pl_data->line_number = PARKING_MOTION_LINE_NUMBER; + #endif + #endif + + plan_block_t *block = plan_get_current_block(); + uint8_t restore_condition; + #ifdef VARIABLE_SPINDLE + float restore_spindle_speed; + if (block == NULL) { + restore_condition = (gc_state.modal.spindle | gc_state.modal.coolant); + restore_spindle_speed = gc_state.spindle_speed; + } else { + restore_condition = (block->condition & PL_COND_SPINDLE_MASK) | coolant_get_state(); + restore_spindle_speed = block->spindle_speed; + } + #ifdef DISABLE_LASER_DURING_HOLD + if (bit_istrue(settings.flags,BITFLAG_LASER_MODE)) { + system_set_exec_accessory_override_flag(EXEC_SPINDLE_OVR_STOP); + } + #endif + #else + if (block == NULL) { restore_condition = (gc_state.modal.spindle | gc_state.modal.coolant); } + else { restore_condition = (block->condition & PL_COND_SPINDLE_MASK) | coolant_get_state(); } + #endif + + while (sys.suspend) { + + if (sys.abort) { return; } + + // Block until initial hold is complete and the machine has stopped motion. + if (sys.suspend & SUSPEND_HOLD_COMPLETE) { + + // Parking manager. Handles de/re-energizing, switch state checks, and parking motions for + // the safety door and sleep states. + if (sys.state & (STATE_SAFETY_DOOR | STATE_SLEEP)) { + + // Handles retraction motions and de-energizing. + if (bit_isfalse(sys.suspend,SUSPEND_RETRACT_COMPLETE)) { + + // Ensure any prior spindle stop override is disabled at start of safety door routine. + sys.spindle_stop_ovr = SPINDLE_STOP_OVR_DISABLED; + + #ifndef PARKING_ENABLE + + spindle_set_state(SPINDLE_DISABLE,0.0); // De-energize + coolant_set_state(COOLANT_DISABLE); // De-energize + + #else + + // Get current position and store restore location and spindle retract waypoint. + system_convert_array_steps_to_mpos(parking_target,sys_position); + if (bit_isfalse(sys.suspend,SUSPEND_RESTART_RETRACT)) { + memcpy(restore_target,parking_target,sizeof(parking_target)); + retract_waypoint += restore_target[PARKING_AXIS]; + retract_waypoint = min(retract_waypoint,PARKING_TARGET); + } + + // Execute slow pull-out parking retract motion. Parking requires homing enabled, the + // current location not exceeding the parking target location, and laser mode disabled. + // NOTE: State is will remain DOOR, until the de-energizing and retract is complete. + #ifdef ENABLE_PARKING_OVERRIDE_CONTROL + if ((bit_istrue(settings.flags,BITFLAG_HOMING_ENABLE)) && + (parking_target[PARKING_AXIS] < PARKING_TARGET) && + bit_isfalse(settings.flags,BITFLAG_LASER_MODE) && + (sys.override_ctrl == OVERRIDE_PARKING_MOTION)) { + #else + if ((bit_istrue(settings.flags,BITFLAG_HOMING_ENABLE)) && + (parking_target[PARKING_AXIS] < PARKING_TARGET) && + bit_isfalse(settings.flags,BITFLAG_LASER_MODE)) { + #endif + // Retract spindle by pullout distance. Ensure retraction motion moves away from + // the workpiece and waypoint motion doesn't exceed the parking target location. + if (parking_target[PARKING_AXIS] < retract_waypoint) { + parking_target[PARKING_AXIS] = retract_waypoint; + pl_data->feed_rate = PARKING_PULLOUT_RATE; + pl_data->condition |= (restore_condition & PL_COND_ACCESSORY_MASK); // Retain accessory state + pl_data->spindle_speed = restore_spindle_speed; + mc_parking_motion(parking_target, pl_data); + } + + // NOTE: Clear accessory state after retract and after an aborted restore motion. + pl_data->condition = (PL_COND_FLAG_SYSTEM_MOTION|PL_COND_FLAG_NO_FEED_OVERRIDE); + pl_data->spindle_speed = 0.0; + spindle_set_state(SPINDLE_DISABLE,0.0); // De-energize + coolant_set_state(COOLANT_DISABLE); // De-energize + + // Execute fast parking retract motion to parking target location. + if (parking_target[PARKING_AXIS] < PARKING_TARGET) { + parking_target[PARKING_AXIS] = PARKING_TARGET; + pl_data->feed_rate = PARKING_RATE; + mc_parking_motion(parking_target, pl_data); + } + + } else { + + // Parking motion not possible. Just disable the spindle and coolant. + // NOTE: Laser mode does not start a parking motion to ensure the laser stops immediately. + spindle_set_state(SPINDLE_DISABLE,0.0); // De-energize + coolant_set_state(COOLANT_DISABLE); // De-energize + + } + + #endif + + sys.suspend &= ~(SUSPEND_RESTART_RETRACT); + sys.suspend |= SUSPEND_RETRACT_COMPLETE; + + } else { + + + if (sys.state == STATE_SLEEP) { + report_feedback_message(MESSAGE_SLEEP_MODE); + // Spindle and coolant should already be stopped, but do it again just to be sure. + spindle_set_state(SPINDLE_DISABLE,0.0); // De-energize + coolant_set_state(COOLANT_DISABLE); // De-energize + st_go_idle(); // Disable steppers + while (!(sys.abort)) { protocol_exec_rt_system(); } // Do nothing until reset. + return; // Abort received. Return to re-initialize. + } + + // Allows resuming from parking/safety door. Actively checks if safety door is closed and ready to resume. + if (sys.state == STATE_SAFETY_DOOR) { + if (!(system_check_safety_door_ajar())) { + sys.suspend &= ~(SUSPEND_SAFETY_DOOR_AJAR); // Reset door ajar flag to denote ready to resume. + } + } + + // Handles parking restore and safety door resume. + if (sys.suspend & SUSPEND_INITIATE_RESTORE) { + + #ifdef PARKING_ENABLE + // Execute fast restore motion to the pull-out position. Parking requires homing enabled. + // NOTE: State is will remain DOOR, until the de-energizing and retract is complete. + #ifdef ENABLE_PARKING_OVERRIDE_CONTROL + if (((settings.flags & (BITFLAG_HOMING_ENABLE|BITFLAG_LASER_MODE)) == BITFLAG_HOMING_ENABLE) && + (sys.override_ctrl == OVERRIDE_PARKING_MOTION)) { + #else + if ((settings.flags & (BITFLAG_HOMING_ENABLE|BITFLAG_LASER_MODE)) == BITFLAG_HOMING_ENABLE) { + #endif + // Check to ensure the motion doesn't move below pull-out position. + if (parking_target[PARKING_AXIS] <= PARKING_TARGET) { + parking_target[PARKING_AXIS] = retract_waypoint; + pl_data->feed_rate = PARKING_RATE; + mc_parking_motion(parking_target, pl_data); + } + } + #endif + + // Delayed Tasks: Restart spindle and coolant, delay to power-up, then resume cycle. + if (gc_state.modal.spindle != SPINDLE_DISABLE) { + // Block if safety door re-opened during prior restore actions. + if (bit_isfalse(sys.suspend,SUSPEND_RESTART_RETRACT)) { + if (bit_istrue(settings.flags,BITFLAG_LASER_MODE)) { + // When in laser mode, ignore spindle spin-up delay. Set to turn on laser when cycle starts. + bit_true(sys.step_control, STEP_CONTROL_UPDATE_SPINDLE_PWM); + } else { + spindle_set_state((restore_condition & (PL_COND_FLAG_SPINDLE_CW | PL_COND_FLAG_SPINDLE_CCW)), restore_spindle_speed); + delay_sec(SAFETY_DOOR_SPINDLE_DELAY, DELAY_MODE_SYS_SUSPEND); + } + } + } + if (gc_state.modal.coolant != COOLANT_DISABLE) { + // Block if safety door re-opened during prior restore actions. + if (bit_isfalse(sys.suspend,SUSPEND_RESTART_RETRACT)) { + // NOTE: Laser mode will honor this delay. An exhaust system is often controlled by this pin. + coolant_set_state((restore_condition & (PL_COND_FLAG_COOLANT_FLOOD | PL_COND_FLAG_COOLANT_MIST))); + delay_sec(SAFETY_DOOR_COOLANT_DELAY, DELAY_MODE_SYS_SUSPEND); + } + } + + #ifdef PARKING_ENABLE + // Execute slow plunge motion from pull-out position to resume position. + #ifdef ENABLE_PARKING_OVERRIDE_CONTROL + if (((settings.flags & (BITFLAG_HOMING_ENABLE|BITFLAG_LASER_MODE)) == BITFLAG_HOMING_ENABLE) && + (sys.override_ctrl == OVERRIDE_PARKING_MOTION)) { + #else + if ((settings.flags & (BITFLAG_HOMING_ENABLE|BITFLAG_LASER_MODE)) == BITFLAG_HOMING_ENABLE) { + #endif + // Block if safety door re-opened during prior restore actions. + if (bit_isfalse(sys.suspend,SUSPEND_RESTART_RETRACT)) { + // Regardless if the retract parking motion was a valid/safe motion or not, the + // restore parking motion should logically be valid, either by returning to the + // original position through valid machine space or by not moving at all. + pl_data->feed_rate = PARKING_PULLOUT_RATE; + pl_data->condition |= (restore_condition & PL_COND_ACCESSORY_MASK); // Restore accessory state + pl_data->spindle_speed = restore_spindle_speed; + mc_parking_motion(restore_target, pl_data); + } + } + #endif + + if (bit_isfalse(sys.suspend,SUSPEND_RESTART_RETRACT)) { + sys.suspend |= SUSPEND_RESTORE_COMPLETE; + system_set_exec_state_flag(EXEC_CYCLE_START); // Set to resume program. + } + } + + } + + + } else { + + // Feed hold manager. Controls spindle stop override states. + // NOTE: Hold ensured as completed by condition check at the beginning of suspend routine. + if (sys.spindle_stop_ovr) { + // Handles beginning of spindle stop + if (sys.spindle_stop_ovr & SPINDLE_STOP_OVR_INITIATE) { + if (gc_state.modal.spindle != SPINDLE_DISABLE) { + spindle_set_state(SPINDLE_DISABLE,0.0); // De-energize + sys.spindle_stop_ovr = SPINDLE_STOP_OVR_ENABLED; // Set stop override state to enabled, if de-energized. + } else { + sys.spindle_stop_ovr = SPINDLE_STOP_OVR_DISABLED; // Clear stop override state + } + // Handles restoring of spindle state + } else if (sys.spindle_stop_ovr & (SPINDLE_STOP_OVR_RESTORE | SPINDLE_STOP_OVR_RESTORE_CYCLE)) { + if (gc_state.modal.spindle != SPINDLE_DISABLE) { + report_feedback_message(MESSAGE_SPINDLE_RESTORE); + if (bit_istrue(settings.flags,BITFLAG_LASER_MODE)) { + // When in laser mode, ignore spindle spin-up delay. Set to turn on laser when cycle starts. + bit_true(sys.step_control, STEP_CONTROL_UPDATE_SPINDLE_PWM); + } else { + spindle_set_state((restore_condition & (PL_COND_FLAG_SPINDLE_CW | PL_COND_FLAG_SPINDLE_CCW)), restore_spindle_speed); + } + } + if (sys.spindle_stop_ovr & SPINDLE_STOP_OVR_RESTORE_CYCLE) { + system_set_exec_state_flag(EXEC_CYCLE_START); // Set to resume program. + } + sys.spindle_stop_ovr = SPINDLE_STOP_OVR_DISABLED; // Clear stop override state + } + } else { + // Handles spindle state during hold. NOTE: Spindle speed overrides may be altered during hold state. + // NOTE: STEP_CONTROL_UPDATE_SPINDLE_PWM is automatically reset upon resume in step generator. + if (bit_istrue(sys.step_control, STEP_CONTROL_UPDATE_SPINDLE_PWM)) { + spindle_set_state((restore_condition & (PL_COND_FLAG_SPINDLE_CW | PL_COND_FLAG_SPINDLE_CCW)), restore_spindle_speed); + bit_false(sys.step_control, STEP_CONTROL_UPDATE_SPINDLE_PWM); + } + } + + } + } + + protocol_exec_rt_system(); + + } +} diff --git a/trunk/Arduino/GRBL_1.1f/protocol.h b/trunk/Arduino/GRBL_1.1f/protocol.h new file mode 100644 index 00000000..7bc6e92b --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f/protocol.h @@ -0,0 +1,49 @@ +/* + protocol.h - controls Grbl execution protocol and procedures + Part of Grbl + + Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC + Copyright (c) 2009-2011 Simen Svale Skogsrud + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +#ifndef protocol_h +#define protocol_h + +// Line buffer size from the serial input stream to be executed. +// NOTE: Not a problem except for extreme cases, but the line buffer size can be too small +// and g-code blocks can get truncated. Officially, the g-code standards support up to 256 +// characters. In future versions, this will be increased, when we know how much extra +// memory space we can invest into here or we re-write the g-code parser not to have this +// buffer. +#ifndef LINE_BUFFER_SIZE + #define LINE_BUFFER_SIZE 80 +#endif + +// Starts Grbl main loop. It handles all incoming characters from the serial port and executes +// them as they complete. It is also responsible for finishing the initialization procedures. +void protocol_main_loop(); + +// Checks and executes a realtime command at various stop points in main program +void protocol_execute_realtime(); +void protocol_exec_rt_system(); + +// Executes the auto cycle feature, if enabled. +void protocol_auto_cycle_start(); + +// Block until all buffered steps are executed +void protocol_buffer_synchronize(); + +#endif diff --git a/trunk/Arduino/GRBL_1.1f/report.c b/trunk/Arduino/GRBL_1.1f/report.c new file mode 100644 index 00000000..3e78b471 --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f/report.c @@ -0,0 +1,647 @@ +/* + report.c - reporting and messaging methods + Part of Grbl + + Copyright (c) 2012-2016 Sungeun K. Jeon for Gnea Research LLC + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +/* + This file functions as the primary feedback interface for Grbl. Any outgoing data, such + as the protocol status messages, feedback messages, and status reports, are stored here. + For the most part, these functions primarily are called from protocol.c methods. If a + different style feedback is desired (i.e. JSON), then a user can change these following + methods to accomodate their needs. +*/ + +#include "grbl.h" + + +// Internal report utilities to reduce flash with repetitive tasks turned into functions. +void report_util_setting_prefix(uint8_t n) { serial_write('$'); print_uint8_base10(n); serial_write('='); } +static void report_util_line_feed() { printPgmString(PSTR("\r\n")); } +static void report_util_feedback_line_feed() { serial_write(']'); report_util_line_feed(); } +static void report_util_gcode_modes_G() { printPgmString(PSTR(" G")); } +static void report_util_gcode_modes_M() { printPgmString(PSTR(" M")); } +// static void report_util_comment_line_feed() { serial_write(')'); report_util_line_feed(); } +static void report_util_axis_values(float *axis_value) { + uint8_t idx; + for (idx=0; idx= AXIS_SETTINGS_INCREMENT) { + n -= AXIS_SETTINGS_INCREMENT; + idx++; + } + serial_write(n+'x'); + switch (idx) { + case 0: printPgmString(PSTR(":stp/mm")); break; + case 1: printPgmString(PSTR(":mm/min")); break; + case 2: printPgmString(PSTR(":mm/s^2")); break; + case 3: printPgmString(PSTR(":mm max")); break; + } + break; + } + report_util_comment_line_feed(); +} +*/ + +static void report_util_uint8_setting(uint8_t n, int val) { + report_util_setting_prefix(n); + print_uint8_base10(val); + report_util_line_feed(); // report_util_setting_string(n); +} +static void report_util_float_setting(uint8_t n, float val, uint8_t n_decimal) { + report_util_setting_prefix(n); + printFloat(val,n_decimal); + report_util_line_feed(); // report_util_setting_string(n); +} + + +// Handles the primary confirmation protocol response for streaming interfaces and human-feedback. +// For every incoming line, this method responds with an 'ok' for a successful command or an +// 'error:' to indicate some error event with the line or some critical system error during +// operation. Errors events can originate from the g-code parser, settings module, or asynchronously +// from a critical error, such as a triggered hard limit. Interface should always monitor for these +// responses. +void report_status_message(uint8_t status_code) +{ + switch(status_code) { + case STATUS_OK: // STATUS_OK + printPgmString(PSTR("ok\r\n")); break; + default: + printPgmString(PSTR("error:")); + print_uint8_base10(status_code); + report_util_line_feed(); + } +} + +// Prints alarm messages. +void report_alarm_message(uint8_t alarm_code) +{ + printPgmString(PSTR("ALARM:")); + print_uint8_base10(alarm_code); + report_util_line_feed(); + delay_ms(500); // Force delay to ensure message clears serial write buffer. +} + +// Prints feedback messages. This serves as a centralized method to provide additional +// user feedback for things that are not of the status/alarm message protocol. These are +// messages such as setup warnings, switch toggling, and how to exit alarms. +// NOTE: For interfaces, messages are always placed within brackets. And if silent mode +// is installed, the message number codes are less than zero. +void report_feedback_message(uint8_t message_code) +{ + printPgmString(PSTR("[MSG:")); + switch(message_code) { + case MESSAGE_CRITICAL_EVENT: + printPgmString(PSTR("Reset to continue")); break; + case MESSAGE_ALARM_LOCK: + printPgmString(PSTR("'$H'|'$X' to unlock")); break; + case MESSAGE_ALARM_UNLOCK: + printPgmString(PSTR("Caution: Unlocked")); break; + case MESSAGE_ENABLED: + printPgmString(PSTR("Enabled")); break; + case MESSAGE_DISABLED: + printPgmString(PSTR("Disabled")); break; + case MESSAGE_SAFETY_DOOR_AJAR: + printPgmString(PSTR("Check Door")); break; + case MESSAGE_CHECK_LIMITS: + printPgmString(PSTR("Check Limits")); break; + case MESSAGE_PROGRAM_END: + printPgmString(PSTR("Pgm End")); break; + case MESSAGE_RESTORE_DEFAULTS: + printPgmString(PSTR("Restoring defaults")); break; + case MESSAGE_SPINDLE_RESTORE: + printPgmString(PSTR("Restoring spindle")); break; + case MESSAGE_SLEEP_MODE: + printPgmString(PSTR("Sleeping")); break; + } + report_util_feedback_line_feed(); +} + + +// Welcome message +void report_init_message() +{ + printPgmString(PSTR("\r\nGrbl " GRBL_VERSION " ['$' for help]\r\n")); +} + +// Grbl help message +void report_grbl_help() { + printPgmString(PSTR("[HLP:$$ $# $G $I $N $x=val $Nx=line $J=line $SLP $C $X $H ~ ! ? ctrl-x]\r\n")); +} + + +// Grbl global settings print out. +// NOTE: The numbering scheme here must correlate to storing in settings.c +void report_grbl_settings() { + // Print Grbl settings. + report_util_uint8_setting(0,settings.pulse_microseconds); + report_util_uint8_setting(1,settings.stepper_idle_lock_time); + report_util_uint8_setting(2,settings.step_invert_mask); + report_util_uint8_setting(3,settings.dir_invert_mask); + report_util_uint8_setting(4,bit_istrue(settings.flags,BITFLAG_INVERT_ST_ENABLE)); + report_util_uint8_setting(5,bit_istrue(settings.flags,BITFLAG_INVERT_LIMIT_PINS)); + report_util_uint8_setting(6,bit_istrue(settings.flags,BITFLAG_INVERT_PROBE_PIN)); + report_util_uint8_setting(10,settings.status_report_mask); + report_util_float_setting(11,settings.junction_deviation,N_DECIMAL_SETTINGVALUE); + report_util_float_setting(12,settings.arc_tolerance,N_DECIMAL_SETTINGVALUE); + report_util_uint8_setting(13,bit_istrue(settings.flags,BITFLAG_REPORT_INCHES)); + report_util_uint8_setting(20,bit_istrue(settings.flags,BITFLAG_SOFT_LIMIT_ENABLE)); + report_util_uint8_setting(21,bit_istrue(settings.flags,BITFLAG_HARD_LIMIT_ENABLE)); + report_util_uint8_setting(22,bit_istrue(settings.flags,BITFLAG_HOMING_ENABLE)); + report_util_uint8_setting(23,settings.homing_dir_mask); + report_util_float_setting(24,settings.homing_feed_rate,N_DECIMAL_SETTINGVALUE); + report_util_float_setting(25,settings.homing_seek_rate,N_DECIMAL_SETTINGVALUE); + report_util_uint8_setting(26,settings.homing_debounce_delay); + report_util_float_setting(27,settings.homing_pulloff,N_DECIMAL_SETTINGVALUE); + report_util_float_setting(30,settings.rpm_max,N_DECIMAL_RPMVALUE); + report_util_float_setting(31,settings.rpm_min,N_DECIMAL_RPMVALUE); + #ifdef VARIABLE_SPINDLE + report_util_uint8_setting(32,bit_istrue(settings.flags,BITFLAG_LASER_MODE)); + #else + report_util_uint8_setting(32,0); + #endif + // Print axis settings + uint8_t idx, set_idx; + uint8_t val = AXIS_SETTINGS_START_VAL; + for (set_idx=0; set_idx= MOTION_MODE_PROBE_TOWARD) { + printPgmString(PSTR("38.")); + print_uint8_base10(gc_state.modal.motion - (MOTION_MODE_PROBE_TOWARD-2)); + } else { + print_uint8_base10(gc_state.modal.motion); + } + + report_util_gcode_modes_G(); + print_uint8_base10(gc_state.modal.coord_select+54); + + report_util_gcode_modes_G(); + print_uint8_base10(gc_state.modal.plane_select+17); + + report_util_gcode_modes_G(); + print_uint8_base10(21-gc_state.modal.units); + + report_util_gcode_modes_G(); + print_uint8_base10(gc_state.modal.distance+90); + + report_util_gcode_modes_G(); + print_uint8_base10(94-gc_state.modal.feed_rate); + + if (gc_state.modal.program_flow) { + report_util_gcode_modes_M(); + switch (gc_state.modal.program_flow) { + case PROGRAM_FLOW_PAUSED : serial_write('0'); break; + // case PROGRAM_FLOW_OPTIONAL_STOP : serial_write('1'); break; // M1 is ignored and not supported. + case PROGRAM_FLOW_COMPLETED_M2 : + case PROGRAM_FLOW_COMPLETED_M30 : + print_uint8_base10(gc_state.modal.program_flow); + break; + } + } + + report_util_gcode_modes_M(); + switch (gc_state.modal.spindle) { + case SPINDLE_ENABLE_CW : serial_write('3'); break; + case SPINDLE_ENABLE_CCW : serial_write('4'); break; + case SPINDLE_DISABLE : serial_write('5'); break; + } + + #ifdef ENABLE_M7 + if (gc_state.modal.coolant) { // Note: Multiple coolant states may be active at the same time. + if (gc_state.modal.coolant & PL_COND_FLAG_COOLANT_MIST) { report_util_gcode_modes_M(); serial_write('7'); } + if (gc_state.modal.coolant & PL_COND_FLAG_COOLANT_FLOOD) { report_util_gcode_modes_M(); serial_write('8'); } + } else { report_util_gcode_modes_M(); serial_write('9'); } + #else + report_util_gcode_modes_M(); + if (gc_state.modal.coolant) { serial_write('8'); } + else { serial_write('9'); } + #endif + + #ifdef ENABLE_PARKING_OVERRIDE_CONTROL + if (sys.override_ctrl == OVERRIDE_PARKING_MOTION) { + report_util_gcode_modes_M(); + print_uint8_base10(56); + } + #endif + + printPgmString(PSTR(" T")); + print_uint8_base10(gc_state.tool); + + printPgmString(PSTR(" F")); + printFloat_RateValue(gc_state.feed_rate); + + #ifdef VARIABLE_SPINDLE + printPgmString(PSTR(" S")); + printFloat(gc_state.spindle_speed,N_DECIMAL_RPMVALUE); + #endif + + report_util_feedback_line_feed(); +} + +// Prints specified startup line +void report_startup_line(uint8_t n, char *line) +{ + printPgmString(PSTR("$N")); + print_uint8_base10(n); + serial_write('='); + printString(line); + report_util_line_feed(); +} + +void report_execute_startup_message(char *line, uint8_t status_code) +{ + serial_write('>'); + printString(line); + serial_write(':'); + report_status_message(status_code); +} + +// Prints build info line +void report_build_info(char *line) +{ + printPgmString(PSTR("[VER:" GRBL_VERSION "." GRBL_VERSION_BUILD ":")); + printString(line); + report_util_feedback_line_feed(); + printPgmString(PSTR("[OPT:")); // Generate compile-time build option list + #ifdef VARIABLE_SPINDLE + serial_write('V'); + #endif + #ifdef USE_LINE_NUMBERS + serial_write('N'); + #endif + #ifdef ENABLE_M7 + serial_write('M'); + #endif + #ifdef COREXY + serial_write('C'); + #endif + #ifdef PARKING_ENABLE + serial_write('P'); + #endif + #ifdef HOMING_FORCE_SET_ORIGIN + serial_write('Z'); + #endif + #ifdef HOMING_SINGLE_AXIS_COMMANDS + serial_write('H'); + #endif + #ifdef LIMITS_TWO_SWITCHES_ON_AXES + serial_write('T'); + #endif + #ifdef ALLOW_FEED_OVERRIDE_DURING_PROBE_CYCLES + serial_write('A'); + #endif + #ifdef USE_SPINDLE_DIR_AS_ENABLE_PIN + serial_write('D'); + #endif + #ifdef SPINDLE_ENABLE_OFF_WITH_ZERO_SPEED + serial_write('0'); + #endif + #ifdef ENABLE_SOFTWARE_DEBOUNCE + serial_write('S'); + #endif + #ifdef ENABLE_PARKING_OVERRIDE_CONTROL + serial_write('R'); + #endif + #ifndef HOMING_INIT_LOCK + serial_write('L'); + #endif + #ifdef ENABLE_SAFETY_DOOR_INPUT_PIN + serial_write('+'); + #endif + #ifndef ENABLE_RESTORE_EEPROM_WIPE_ALL // NOTE: Shown when disabled. + serial_write('*'); + #endif + #ifndef ENABLE_RESTORE_EEPROM_DEFAULT_SETTINGS // NOTE: Shown when disabled. + serial_write('$'); + #endif + #ifndef ENABLE_RESTORE_EEPROM_CLEAR_PARAMETERS // NOTE: Shown when disabled. + serial_write('#'); + #endif + #ifndef ENABLE_BUILD_INFO_WRITE_COMMAND // NOTE: Shown when disabled. + serial_write('I'); + #endif + #ifndef FORCE_BUFFER_SYNC_DURING_EEPROM_WRITE // NOTE: Shown when disabled. + serial_write('E'); + #endif + #ifndef FORCE_BUFFER_SYNC_DURING_WCO_CHANGE // NOTE: Shown when disabled. + serial_write('W'); + #endif + // NOTE: Compiled values, like override increments/max/min values, may be added at some point later. + serial_write(','); + print_uint8_base10(BLOCK_BUFFER_SIZE-1); + serial_write(','); + print_uint8_base10(RX_BUFFER_SIZE); + + report_util_feedback_line_feed(); +} + + +// Prints the character string line Grbl has received from the user, which has been pre-parsed, +// and has been sent into protocol_execute_line() routine to be executed by Grbl. +void report_echo_line_received(char *line) +{ + printPgmString(PSTR("[echo: ")); printString(line); + report_util_feedback_line_feed(); +} + + + // Prints real-time data. This function grabs a real-time snapshot of the stepper subprogram + // and the actual location of the CNC machine. Users may change the following function to their + // specific needs, but the desired real-time data report must be as short as possible. This is + // requires as it minimizes the computational overhead and allows grbl to keep running smoothly, + // especially during g-code programs with fast, short line segments and high frequency reports (5-20Hz). +void report_realtime_status() +{ + uint8_t idx; + int32_t current_position[N_AXIS]; // Copy current state of the system position variable + memcpy(current_position,sys_position,sizeof(sys_position)); + float print_position[N_AXIS]; + system_convert_array_steps_to_mpos(print_position,current_position); + + // Report current machine state and sub-states + serial_write('<'); + switch (sys.state) { + case STATE_IDLE: printPgmString(PSTR("Idle")); break; + case STATE_CYCLE: printPgmString(PSTR("Run")); break; + case STATE_HOLD: + if (!(sys.suspend & SUSPEND_JOG_CANCEL)) { + printPgmString(PSTR("Hold:")); + if (sys.suspend & SUSPEND_HOLD_COMPLETE) { serial_write('0'); } // Ready to resume + else { serial_write('1'); } // Actively holding + break; + } // Continues to print jog state during jog cancel. + case STATE_JOG: printPgmString(PSTR("Jog")); break; + case STATE_HOMING: printPgmString(PSTR("Home")); break; + case STATE_ALARM: printPgmString(PSTR("Alarm")); break; + case STATE_CHECK_MODE: printPgmString(PSTR("Check")); break; + case STATE_SAFETY_DOOR: + printPgmString(PSTR("Door:")); + if (sys.suspend & SUSPEND_INITIATE_RESTORE) { + serial_write('3'); // Restoring + } else { + if (sys.suspend & SUSPEND_RETRACT_COMPLETE) { + if (sys.suspend & SUSPEND_SAFETY_DOOR_AJAR) { + serial_write('1'); // Door ajar + } else { + serial_write('0'); + } // Door closed and ready to resume + } else { + serial_write('2'); // Retracting + } + } + break; + case STATE_SLEEP: printPgmString(PSTR("Sleep")); break; + } + + float wco[N_AXIS]; + if (bit_isfalse(settings.status_report_mask,BITFLAG_RT_STATUS_POSITION_TYPE) || + (sys.report_wco_counter == 0) ) { + for (idx=0; idx< N_AXIS; idx++) { + // Apply work coordinate offsets and tool length offset to current position. + wco[idx] = gc_state.coord_system[idx]+gc_state.coord_offset[idx]; + if (idx == TOOL_LENGTH_OFFSET_AXIS) { wco[idx] += gc_state.tool_length_offset; } + if (bit_isfalse(settings.status_report_mask,BITFLAG_RT_STATUS_POSITION_TYPE)) { + print_position[idx] -= wco[idx]; + } + } + } + + // Report machine position + if (bit_istrue(settings.status_report_mask,BITFLAG_RT_STATUS_POSITION_TYPE)) { + printPgmString(PSTR("|MPos:")); + } else { + printPgmString(PSTR("|WPos:")); + } + report_util_axis_values(print_position); + + // Returns planner and serial read buffer states. + #ifdef REPORT_FIELD_BUFFER_STATE + if (bit_istrue(settings.status_report_mask,BITFLAG_RT_STATUS_BUFFER_STATE)) { + printPgmString(PSTR("|Bf:")); + print_uint8_base10(plan_get_block_buffer_available()); + serial_write(','); + print_uint8_base10(serial_get_rx_buffer_available()); + } + #endif + + #ifdef USE_LINE_NUMBERS + #ifdef REPORT_FIELD_LINE_NUMBERS + // Report current line number + plan_block_t * cur_block = plan_get_current_block(); + if (cur_block != NULL) { + uint32_t ln = cur_block->line_number; + if (ln > 0) { + printPgmString(PSTR("|Ln:")); + printInteger(ln); + } + } + #endif + #endif + + // Report realtime feed speed + #ifdef REPORT_FIELD_CURRENT_FEED_SPEED + #ifdef VARIABLE_SPINDLE + printPgmString(PSTR("|FS:")); + printFloat_RateValue(st_get_realtime_rate()); + serial_write(','); + printFloat(sys.spindle_speed,N_DECIMAL_RPMVALUE); + #else + printPgmString(PSTR("|F:")); + printFloat_RateValue(st_get_realtime_rate()); + #endif + #endif + + #ifdef REPORT_FIELD_PIN_STATE + uint8_t lim_pin_state = limits_get_state(); + uint8_t ctrl_pin_state = system_control_get_state(); + uint8_t prb_pin_state = probe_get_state(); + if (lim_pin_state | ctrl_pin_state | prb_pin_state) { + printPgmString(PSTR("|Pn:")); + if (prb_pin_state) { serial_write('P'); } + if (lim_pin_state) { + if (bit_istrue(lim_pin_state,bit(X_AXIS))) { serial_write('X'); } + if (bit_istrue(lim_pin_state,bit(Y_AXIS))) { serial_write('Y'); } + if (bit_istrue(lim_pin_state,bit(Z_AXIS))) { serial_write('Z'); } + } + if (ctrl_pin_state) { + #ifdef ENABLE_SAFETY_DOOR_INPUT_PIN + if (bit_istrue(ctrl_pin_state,CONTROL_PIN_INDEX_SAFETY_DOOR)) { serial_write('D'); } + #endif + if (bit_istrue(ctrl_pin_state,CONTROL_PIN_INDEX_RESET)) { serial_write('R'); } + if (bit_istrue(ctrl_pin_state,CONTROL_PIN_INDEX_FEED_HOLD)) { serial_write('H'); } + if (bit_istrue(ctrl_pin_state,CONTROL_PIN_INDEX_CYCLE_START)) { serial_write('S'); } + } + } + #endif + + #ifdef REPORT_FIELD_WORK_COORD_OFFSET + if (sys.report_wco_counter > 0) { sys.report_wco_counter--; } + else { + if (sys.state & (STATE_HOMING | STATE_CYCLE | STATE_HOLD | STATE_JOG | STATE_SAFETY_DOOR)) { + sys.report_wco_counter = (REPORT_WCO_REFRESH_BUSY_COUNT-1); // Reset counter for slow refresh + } else { sys.report_wco_counter = (REPORT_WCO_REFRESH_IDLE_COUNT-1); } + if (sys.report_ovr_counter == 0) { sys.report_ovr_counter = 1; } // Set override on next report. + printPgmString(PSTR("|WCO:")); + report_util_axis_values(wco); + } + #endif + + #ifdef REPORT_FIELD_OVERRIDES + if (sys.report_ovr_counter > 0) { sys.report_ovr_counter--; } + else { + if (sys.state & (STATE_HOMING | STATE_CYCLE | STATE_HOLD | STATE_JOG | STATE_SAFETY_DOOR)) { + sys.report_ovr_counter = (REPORT_OVR_REFRESH_BUSY_COUNT-1); // Reset counter for slow refresh + } else { sys.report_ovr_counter = (REPORT_OVR_REFRESH_IDLE_COUNT-1); } + printPgmString(PSTR("|Ov:")); + print_uint8_base10(sys.f_override); + serial_write(','); + print_uint8_base10(sys.r_override); + serial_write(','); + print_uint8_base10(sys.spindle_speed_ovr); + + uint8_t sp_state = spindle_get_state(); + uint8_t cl_state = coolant_get_state(); + if (sp_state || cl_state) { + printPgmString(PSTR("|A:")); + if (sp_state) { // != SPINDLE_STATE_DISABLE + #ifdef VARIABLE_SPINDLE + #ifdef USE_SPINDLE_DIR_AS_ENABLE_PIN + serial_write('S'); // CW + #else + if (sp_state == SPINDLE_STATE_CW) { serial_write('S'); } // CW + else { serial_write('C'); } // CCW + #endif + #else + if (sp_state & SPINDLE_STATE_CW) { serial_write('S'); } // CW + else { serial_write('C'); } // CCW + #endif + } + if (cl_state & COOLANT_STATE_FLOOD) { serial_write('F'); } + #ifdef ENABLE_M7 + if (cl_state & COOLANT_STATE_MIST) { serial_write('M'); } + #endif + } + } + #endif + + serial_write('>'); + report_util_line_feed(); +} + + +#ifdef DEBUG + void report_realtime_debug() + { + + } +#endif diff --git a/trunk/Arduino/GRBL_1.1f/report.h b/trunk/Arduino/GRBL_1.1f/report.h new file mode 100644 index 00000000..f1480026 --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f/report.h @@ -0,0 +1,131 @@ +/* + report.h - reporting and messaging methods + Part of Grbl + + Copyright (c) 2012-2016 Sungeun K. Jeon for Gnea Research LLC + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ +#ifndef report_h +#define report_h + +// Define Grbl status codes. Valid values (0-255) +#define STATUS_OK 0 +#define STATUS_EXPECTED_COMMAND_LETTER 1 +#define STATUS_BAD_NUMBER_FORMAT 2 +#define STATUS_INVALID_STATEMENT 3 +#define STATUS_NEGATIVE_VALUE 4 +#define STATUS_SETTING_DISABLED 5 +#define STATUS_SETTING_STEP_PULSE_MIN 6 +#define STATUS_SETTING_READ_FAIL 7 +#define STATUS_IDLE_ERROR 8 +#define STATUS_SYSTEM_GC_LOCK 9 +#define STATUS_SOFT_LIMIT_ERROR 10 +#define STATUS_OVERFLOW 11 +#define STATUS_MAX_STEP_RATE_EXCEEDED 12 +#define STATUS_CHECK_DOOR 13 +#define STATUS_LINE_LENGTH_EXCEEDED 14 +#define STATUS_TRAVEL_EXCEEDED 15 +#define STATUS_INVALID_JOG_COMMAND 16 +#define STATUS_SETTING_DISABLED_LASER 17 + +#define STATUS_GCODE_UNSUPPORTED_COMMAND 20 +#define STATUS_GCODE_MODAL_GROUP_VIOLATION 21 +#define STATUS_GCODE_UNDEFINED_FEED_RATE 22 +#define STATUS_GCODE_COMMAND_VALUE_NOT_INTEGER 23 +#define STATUS_GCODE_AXIS_COMMAND_CONFLICT 24 +#define STATUS_GCODE_WORD_REPEATED 25 +#define STATUS_GCODE_NO_AXIS_WORDS 26 +#define STATUS_GCODE_INVALID_LINE_NUMBER 27 +#define STATUS_GCODE_VALUE_WORD_MISSING 28 +#define STATUS_GCODE_UNSUPPORTED_COORD_SYS 29 +#define STATUS_GCODE_G53_INVALID_MOTION_MODE 30 +#define STATUS_GCODE_AXIS_WORDS_EXIST 31 +#define STATUS_GCODE_NO_AXIS_WORDS_IN_PLANE 32 +#define STATUS_GCODE_INVALID_TARGET 33 +#define STATUS_GCODE_ARC_RADIUS_ERROR 34 +#define STATUS_GCODE_NO_OFFSETS_IN_PLANE 35 +#define STATUS_GCODE_UNUSED_WORDS 36 +#define STATUS_GCODE_G43_DYNAMIC_AXIS_ERROR 37 +#define STATUS_GCODE_MAX_VALUE_EXCEEDED 38 + +// Define Grbl alarm codes. Valid values (1-255). 0 is reserved. +#define ALARM_HARD_LIMIT_ERROR EXEC_ALARM_HARD_LIMIT +#define ALARM_SOFT_LIMIT_ERROR EXEC_ALARM_SOFT_LIMIT +#define ALARM_ABORT_CYCLE EXEC_ALARM_ABORT_CYCLE +#define ALARM_PROBE_FAIL_INITIAL EXEC_ALARM_PROBE_FAIL_INITIAL +#define ALARM_PROBE_FAIL_CONTACT EXEC_ALARM_PROBE_FAIL_CONTACT +#define ALARM_HOMING_FAIL_RESET EXEC_ALARM_HOMING_FAIL_RESET +#define ALARM_HOMING_FAIL_DOOR EXEC_ALARM_HOMING_FAIL_DOOR +#define ALARM_HOMING_FAIL_PULLOFF EXEC_ALARM_HOMING_FAIL_PULLOFF +#define ALARM_HOMING_FAIL_APPROACH EXEC_ALARM_HOMING_FAIL_APPROACH + +// Define Grbl feedback message codes. Valid values (0-255). +#define MESSAGE_CRITICAL_EVENT 1 +#define MESSAGE_ALARM_LOCK 2 +#define MESSAGE_ALARM_UNLOCK 3 +#define MESSAGE_ENABLED 4 +#define MESSAGE_DISABLED 5 +#define MESSAGE_SAFETY_DOOR_AJAR 6 +#define MESSAGE_CHECK_LIMITS 7 +#define MESSAGE_PROGRAM_END 8 +#define MESSAGE_RESTORE_DEFAULTS 9 +#define MESSAGE_SPINDLE_RESTORE 10 +#define MESSAGE_SLEEP_MODE 11 + +// Prints system status messages. +void report_status_message(uint8_t status_code); + +// Prints system alarm messages. +void report_alarm_message(uint8_t alarm_code); + +// Prints miscellaneous feedback messages. +void report_feedback_message(uint8_t message_code); + +// Prints welcome message +void report_init_message(); + +// Prints Grbl help and current global settings +void report_grbl_help(); + +// Prints Grbl global settings +void report_grbl_settings(); + +// Prints an echo of the pre-parsed line received right before execution. +void report_echo_line_received(char *line); + +// Prints realtime status report +void report_realtime_status(); + +// Prints recorded probe position +void report_probe_parameters(); + +// Prints Grbl NGC parameters (coordinate offsets, probe) +void report_ngc_parameters(); + +// Prints current g-code parser mode state +void report_gcode_modes(); + +// Prints startup line when requested and executed. +void report_startup_line(uint8_t n, char *line); +void report_execute_startup_message(char *line, uint8_t status_code); + +// Prints build info and user info +void report_build_info(char *line); + +#ifdef DEBUG + void report_realtime_debug(); +#endif + +#endif diff --git a/trunk/Arduino/GRBL_1.1f/serial.c b/trunk/Arduino/GRBL_1.1f/serial.c new file mode 100644 index 00000000..cf5f35e2 --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f/serial.c @@ -0,0 +1,204 @@ +/* + serial.c - Low level functions for sending and recieving bytes via the serial port + Part of Grbl + + Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC + Copyright (c) 2009-2011 Simen Svale Skogsrud + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +#include "grbl.h" + +#define RX_RING_BUFFER (RX_BUFFER_SIZE+1) +#define TX_RING_BUFFER (TX_BUFFER_SIZE+1) + +uint8_t serial_rx_buffer[RX_RING_BUFFER]; +uint8_t serial_rx_buffer_head = 0; +volatile uint8_t serial_rx_buffer_tail = 0; + +uint8_t serial_tx_buffer[TX_RING_BUFFER]; +uint8_t serial_tx_buffer_head = 0; +volatile uint8_t serial_tx_buffer_tail = 0; + + +// Returns the number of bytes available in the RX serial buffer. +uint8_t serial_get_rx_buffer_available() +{ + uint8_t rtail = serial_rx_buffer_tail; // Copy to limit multiple calls to volatile + if (serial_rx_buffer_head >= rtail) { return(RX_BUFFER_SIZE - (serial_rx_buffer_head-rtail)); } + return((rtail-serial_rx_buffer_head-1)); +} + + +// Returns the number of bytes used in the RX serial buffer. +// NOTE: Deprecated. Not used unless classic status reports are enabled in config.h. +uint8_t serial_get_rx_buffer_count() +{ + uint8_t rtail = serial_rx_buffer_tail; // Copy to limit multiple calls to volatile + if (serial_rx_buffer_head >= rtail) { return(serial_rx_buffer_head-rtail); } + return (RX_BUFFER_SIZE - (rtail-serial_rx_buffer_head)); +} + + +// Returns the number of bytes used in the TX serial buffer. +// NOTE: Not used except for debugging and ensuring no TX bottlenecks. +uint8_t serial_get_tx_buffer_count() +{ + uint8_t ttail = serial_tx_buffer_tail; // Copy to limit multiple calls to volatile + if (serial_tx_buffer_head >= ttail) { return(serial_tx_buffer_head-ttail); } + return (TX_RING_BUFFER - (ttail-serial_tx_buffer_head)); +} + + +void serial_init() +{ + // Set baud rate + #if BAUD_RATE < 57600 + uint16_t UBRR0_value = ((F_CPU / (8L * BAUD_RATE)) - 1)/2 ; + UCSR0A &= ~(1 << U2X0); // baud doubler off - Only needed on Uno XXX + #else + uint16_t UBRR0_value = ((F_CPU / (4L * BAUD_RATE)) - 1)/2; + UCSR0A |= (1 << U2X0); // baud doubler on for high baud rates, i.e. 115200 + #endif + UBRR0H = UBRR0_value >> 8; + UBRR0L = UBRR0_value; + + // enable rx, tx, and interrupt on complete reception of a byte + UCSR0B |= (1< 0x7F) { // Real-time control characters are extended ACSII only. + switch(data) { + case CMD_SAFETY_DOOR: system_set_exec_state_flag(EXEC_SAFETY_DOOR); break; // Set as true + case CMD_JOG_CANCEL: + if (sys.state & STATE_JOG) { // Block all other states from invoking motion cancel. + system_set_exec_state_flag(EXEC_MOTION_CANCEL); + } + break; + #ifdef DEBUG + case CMD_DEBUG_REPORT: {uint8_t sreg = SREG; cli(); bit_true(sys_rt_exec_debug,EXEC_DEBUG_REPORT); SREG = sreg;} break; + #endif + case CMD_FEED_OVR_RESET: system_set_exec_motion_override_flag(EXEC_FEED_OVR_RESET); break; + case CMD_FEED_OVR_COARSE_PLUS: system_set_exec_motion_override_flag(EXEC_FEED_OVR_COARSE_PLUS); break; + case CMD_FEED_OVR_COARSE_MINUS: system_set_exec_motion_override_flag(EXEC_FEED_OVR_COARSE_MINUS); break; + case CMD_FEED_OVR_FINE_PLUS: system_set_exec_motion_override_flag(EXEC_FEED_OVR_FINE_PLUS); break; + case CMD_FEED_OVR_FINE_MINUS: system_set_exec_motion_override_flag(EXEC_FEED_OVR_FINE_MINUS); break; + case CMD_RAPID_OVR_RESET: system_set_exec_motion_override_flag(EXEC_RAPID_OVR_RESET); break; + case CMD_RAPID_OVR_MEDIUM: system_set_exec_motion_override_flag(EXEC_RAPID_OVR_MEDIUM); break; + case CMD_RAPID_OVR_LOW: system_set_exec_motion_override_flag(EXEC_RAPID_OVR_LOW); break; + case CMD_SPINDLE_OVR_RESET: system_set_exec_accessory_override_flag(EXEC_SPINDLE_OVR_RESET); break; + case CMD_SPINDLE_OVR_COARSE_PLUS: system_set_exec_accessory_override_flag(EXEC_SPINDLE_OVR_COARSE_PLUS); break; + case CMD_SPINDLE_OVR_COARSE_MINUS: system_set_exec_accessory_override_flag(EXEC_SPINDLE_OVR_COARSE_MINUS); break; + case CMD_SPINDLE_OVR_FINE_PLUS: system_set_exec_accessory_override_flag(EXEC_SPINDLE_OVR_FINE_PLUS); break; + case CMD_SPINDLE_OVR_FINE_MINUS: system_set_exec_accessory_override_flag(EXEC_SPINDLE_OVR_FINE_MINUS); break; + case CMD_SPINDLE_OVR_STOP: system_set_exec_accessory_override_flag(EXEC_SPINDLE_OVR_STOP); break; + case CMD_COOLANT_FLOOD_OVR_TOGGLE: system_set_exec_accessory_override_flag(EXEC_COOLANT_FLOOD_OVR_TOGGLE); break; + #ifdef ENABLE_M7 + case CMD_COOLANT_MIST_OVR_TOGGLE: system_set_exec_accessory_override_flag(EXEC_COOLANT_MIST_OVR_TOGGLE); break; + #endif + } + // Throw away any unfound extended-ASCII character by not passing it to the serial buffer. + } else { // Write character to buffer + next_head = serial_rx_buffer_head + 1; + if (next_head == RX_RING_BUFFER) { next_head = 0; } + + // Write data to buffer unless it is full. + if (next_head != serial_rx_buffer_tail) { + serial_rx_buffer[serial_rx_buffer_head] = data; + serial_rx_buffer_head = next_head; + } + } + } +} + + +void serial_reset_read_buffer() +{ + serial_rx_buffer_tail = serial_rx_buffer_head; +} diff --git a/trunk/Arduino/GRBL_1.1f/serial.h b/trunk/Arduino/GRBL_1.1f/serial.h new file mode 100644 index 00000000..5a3f7761 --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f/serial.h @@ -0,0 +1,62 @@ +/* + serial.c - Low level functions for sending and recieving bytes via the serial port + Part of Grbl + + Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC + Copyright (c) 2009-2011 Simen Svale Skogsrud + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +#ifndef serial_h +#define serial_h + + +#ifndef RX_BUFFER_SIZE + #define RX_BUFFER_SIZE 128 +#endif +#ifndef TX_BUFFER_SIZE + #ifdef USE_LINE_NUMBERS + #define TX_BUFFER_SIZE 112 + #else + #define TX_BUFFER_SIZE 104 + #endif +#endif + +#define SERIAL_NO_DATA 0xff + + +void serial_init(); + +// Writes one byte to the TX serial buffer. Called by main program. +void serial_write(uint8_t data); + +// Fetches the first byte in the serial read buffer. Called by main program. +uint8_t serial_read(); + +// Reset and empty data in read buffer. Used by e-stop and reset. +void serial_reset_read_buffer(); + +// Returns the number of bytes available in the RX serial buffer. +uint8_t serial_get_rx_buffer_available(); + +// Returns the number of bytes used in the RX serial buffer. +// NOTE: Deprecated. Not used unless classic status reports are enabled in config.h. +uint8_t serial_get_rx_buffer_count(); + +// Returns the number of bytes used in the TX serial buffer. +// NOTE: Not used except for debugging and ensuring no TX bottlenecks. +uint8_t serial_get_tx_buffer_count(); + +#endif diff --git a/trunk/Arduino/GRBL_1.1f/settings.c b/trunk/Arduino/GRBL_1.1f/settings.c new file mode 100644 index 00000000..a9c830e7 --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f/settings.c @@ -0,0 +1,340 @@ +/* + settings.c - eeprom configuration handling + Part of Grbl + + Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC + Copyright (c) 2009-2011 Simen Svale Skogsrud + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +#include "grbl.h" + +settings_t settings; + +const __flash settings_t defaults = {\ + .pulse_microseconds = DEFAULT_STEP_PULSE_MICROSECONDS, + .stepper_idle_lock_time = DEFAULT_STEPPER_IDLE_LOCK_TIME, + .step_invert_mask = DEFAULT_STEPPING_INVERT_MASK, + .dir_invert_mask = DEFAULT_DIRECTION_INVERT_MASK, + .status_report_mask = DEFAULT_STATUS_REPORT_MASK, + .junction_deviation = DEFAULT_JUNCTION_DEVIATION, + .arc_tolerance = DEFAULT_ARC_TOLERANCE, + .rpm_max = DEFAULT_SPINDLE_RPM_MAX, + .rpm_min = DEFAULT_SPINDLE_RPM_MIN, + .homing_dir_mask = DEFAULT_HOMING_DIR_MASK, + .homing_feed_rate = DEFAULT_HOMING_FEED_RATE, + .homing_seek_rate = DEFAULT_HOMING_SEEK_RATE, + .homing_debounce_delay = DEFAULT_HOMING_DEBOUNCE_DELAY, + .homing_pulloff = DEFAULT_HOMING_PULLOFF, + .flags = (DEFAULT_REPORT_INCHES << BIT_REPORT_INCHES) | \ + (DEFAULT_LASER_MODE << BIT_LASER_MODE) | \ + (DEFAULT_INVERT_ST_ENABLE << BIT_INVERT_ST_ENABLE) | \ + (DEFAULT_HARD_LIMIT_ENABLE << BIT_HARD_LIMIT_ENABLE) | \ + (DEFAULT_HOMING_ENABLE << BIT_HOMING_ENABLE) | \ + (DEFAULT_SOFT_LIMIT_ENABLE << BIT_SOFT_LIMIT_ENABLE) | \ + (DEFAULT_INVERT_LIMIT_PINS << BIT_INVERT_LIMIT_PINS) | \ + (DEFAULT_INVERT_PROBE_PIN << BIT_INVERT_PROBE_PIN), + .steps_per_mm[X_AXIS] = DEFAULT_X_STEPS_PER_MM, + .steps_per_mm[Y_AXIS] = DEFAULT_Y_STEPS_PER_MM, + .steps_per_mm[Z_AXIS] = DEFAULT_Z_STEPS_PER_MM, + .max_rate[X_AXIS] = DEFAULT_X_MAX_RATE, + .max_rate[Y_AXIS] = DEFAULT_Y_MAX_RATE, + .max_rate[Z_AXIS] = DEFAULT_Z_MAX_RATE, + .acceleration[X_AXIS] = DEFAULT_X_ACCELERATION, + .acceleration[Y_AXIS] = DEFAULT_Y_ACCELERATION, + .acceleration[Z_AXIS] = DEFAULT_Z_ACCELERATION, + .max_travel[X_AXIS] = (-DEFAULT_X_MAX_TRAVEL), + .max_travel[Y_AXIS] = (-DEFAULT_Y_MAX_TRAVEL), + .max_travel[Z_AXIS] = (-DEFAULT_Z_MAX_TRAVEL)}; + + +// Method to store startup lines into EEPROM +void settings_store_startup_line(uint8_t n, char *line) +{ + #ifdef FORCE_BUFFER_SYNC_DURING_EEPROM_WRITE + protocol_buffer_synchronize(); // A startup line may contain a motion and be executing. + #endif + uint32_t addr = n*(LINE_BUFFER_SIZE+1)+EEPROM_ADDR_STARTUP_BLOCK; + memcpy_to_eeprom_with_checksum(addr,(char*)line, LINE_BUFFER_SIZE); +} + + +// Method to store build info into EEPROM +// NOTE: This function can only be called in IDLE state. +void settings_store_build_info(char *line) +{ + // Build info can only be stored when state is IDLE. + memcpy_to_eeprom_with_checksum(EEPROM_ADDR_BUILD_INFO,(char*)line, LINE_BUFFER_SIZE); +} + + +// Method to store coord data parameters into EEPROM +void settings_write_coord_data(uint8_t coord_select, float *coord_data) +{ + #ifdef FORCE_BUFFER_SYNC_DURING_EEPROM_WRITE + protocol_buffer_synchronize(); + #endif + uint32_t addr = coord_select*(sizeof(float)*N_AXIS+1) + EEPROM_ADDR_PARAMETERS; + memcpy_to_eeprom_with_checksum(addr,(char*)coord_data, sizeof(float)*N_AXIS); +} + + +// Method to store Grbl global settings struct and version number into EEPROM +// NOTE: This function can only be called in IDLE state. +void write_global_settings() +{ + eeprom_put_char(0, SETTINGS_VERSION); + memcpy_to_eeprom_with_checksum(EEPROM_ADDR_GLOBAL, (char*)&settings, sizeof(settings_t)); +} + + +// Method to restore EEPROM-saved Grbl global settings back to defaults. +void settings_restore(uint8_t restore_flag) { + if (restore_flag & SETTINGS_RESTORE_DEFAULTS) { + settings = defaults; + write_global_settings(); + } + + if (restore_flag & SETTINGS_RESTORE_PARAMETERS) { + uint8_t idx; + float coord_data[N_AXIS]; + memset(&coord_data, 0, sizeof(coord_data)); + for (idx=0; idx <= SETTING_INDEX_NCOORD; idx++) { settings_write_coord_data(idx, coord_data); } + } + + if (restore_flag & SETTINGS_RESTORE_STARTUP_LINES) { + #if N_STARTUP_LINE > 0 + eeprom_put_char(EEPROM_ADDR_STARTUP_BLOCK, 0); + eeprom_put_char(EEPROM_ADDR_STARTUP_BLOCK+1, 0); // Checksum + #endif + #if N_STARTUP_LINE > 1 + eeprom_put_char(EEPROM_ADDR_STARTUP_BLOCK+(LINE_BUFFER_SIZE+1), 0); + eeprom_put_char(EEPROM_ADDR_STARTUP_BLOCK+(LINE_BUFFER_SIZE+2), 0); // Checksum + #endif + } + + if (restore_flag & SETTINGS_RESTORE_BUILD_INFO) { + eeprom_put_char(EEPROM_ADDR_BUILD_INFO , 0); + eeprom_put_char(EEPROM_ADDR_BUILD_INFO+1 , 0); // Checksum + } +} + + +// Reads startup line from EEPROM. Updated pointed line string data. +uint8_t settings_read_startup_line(uint8_t n, char *line) +{ + uint32_t addr = n*(LINE_BUFFER_SIZE+1)+EEPROM_ADDR_STARTUP_BLOCK; + if (!(memcpy_from_eeprom_with_checksum((char*)line, addr, LINE_BUFFER_SIZE))) { + // Reset line with default value + line[0] = 0; // Empty line + settings_store_startup_line(n, line); + return(false); + } + return(true); +} + + +// Reads startup line from EEPROM. Updated pointed line string data. +uint8_t settings_read_build_info(char *line) +{ + if (!(memcpy_from_eeprom_with_checksum((char*)line, EEPROM_ADDR_BUILD_INFO, LINE_BUFFER_SIZE))) { + // Reset line with default value + line[0] = 0; // Empty line + settings_store_build_info(line); + return(false); + } + return(true); +} + + +// Read selected coordinate data from EEPROM. Updates pointed coord_data value. +uint8_t settings_read_coord_data(uint8_t coord_select, float *coord_data) +{ + uint32_t addr = coord_select*(sizeof(float)*N_AXIS+1) + EEPROM_ADDR_PARAMETERS; + if (!(memcpy_from_eeprom_with_checksum((char*)coord_data, addr, sizeof(float)*N_AXIS))) { + // Reset with default zero vector + clear_vector_float(coord_data); + settings_write_coord_data(coord_select,coord_data); + return(false); + } + return(true); +} + + +// Reads Grbl global settings struct from EEPROM. +uint8_t read_global_settings() { + // Check version-byte of eeprom + uint8_t version = eeprom_get_char(0); + if (version == SETTINGS_VERSION) { + // Read settings-record and check checksum + if (!(memcpy_from_eeprom_with_checksum((char*)&settings, EEPROM_ADDR_GLOBAL, sizeof(settings_t)))) { + return(false); + } + } else { + return(false); + } + return(true); +} + + +// A helper method to set settings from command line +uint8_t settings_store_global_setting(uint8_t parameter, float value) { + if (value < 0.0) { return(STATUS_NEGATIVE_VALUE); } + if (parameter >= AXIS_SETTINGS_START_VAL) { + // Store axis configuration. Axis numbering sequence set by AXIS_SETTING defines. + // NOTE: Ensure the setting index corresponds to the report.c settings printout. + parameter -= AXIS_SETTINGS_START_VAL; + uint8_t set_idx = 0; + while (set_idx < AXIS_N_SETTINGS) { + if (parameter < N_AXIS) { + // Valid axis setting found. + switch (set_idx) { + case 0: + #ifdef MAX_STEP_RATE_HZ + if (value*settings.max_rate[parameter] > (MAX_STEP_RATE_HZ*60.0)) { return(STATUS_MAX_STEP_RATE_EXCEEDED); } + #endif + settings.steps_per_mm[parameter] = value; + break; + case 1: + #ifdef MAX_STEP_RATE_HZ + if (value*settings.steps_per_mm[parameter] > (MAX_STEP_RATE_HZ*60.0)) { return(STATUS_MAX_STEP_RATE_EXCEEDED); } + #endif + settings.max_rate[parameter] = value; + break; + case 2: settings.acceleration[parameter] = value*60*60; break; // Convert to mm/min^2 for grbl internal use. + case 3: settings.max_travel[parameter] = -value; break; // Store as negative for grbl internal use. + } + break; // Exit while-loop after setting has been configured and proceed to the EEPROM write call. + } else { + set_idx++; + // If axis index greater than N_AXIS or setting index greater than number of axis settings, error out. + if ((parameter < AXIS_SETTINGS_INCREMENT) || (set_idx == AXIS_N_SETTINGS)) { return(STATUS_INVALID_STATEMENT); } + parameter -= AXIS_SETTINGS_INCREMENT; + } + } + } else { + // Store non-axis Grbl settings + uint8_t int_value = trunc(value); + switch(parameter) { + case 0: + if (int_value < 3) { return(STATUS_SETTING_STEP_PULSE_MIN); } + settings.pulse_microseconds = int_value; break; + case 1: settings.stepper_idle_lock_time = int_value; break; + case 2: + settings.step_invert_mask = int_value; + st_generate_step_dir_invert_masks(); // Regenerate step and direction port invert masks. + break; + case 3: + settings.dir_invert_mask = int_value; + st_generate_step_dir_invert_masks(); // Regenerate step and direction port invert masks. + break; + case 4: // Reset to ensure change. Immediate re-init may cause problems. + if (int_value) { settings.flags |= BITFLAG_INVERT_ST_ENABLE; } + else { settings.flags &= ~BITFLAG_INVERT_ST_ENABLE; } + break; + case 5: // Reset to ensure change. Immediate re-init may cause problems. + if (int_value) { settings.flags |= BITFLAG_INVERT_LIMIT_PINS; } + else { settings.flags &= ~BITFLAG_INVERT_LIMIT_PINS; } + break; + case 6: // Reset to ensure change. Immediate re-init may cause problems. + if (int_value) { settings.flags |= BITFLAG_INVERT_PROBE_PIN; } + else { settings.flags &= ~BITFLAG_INVERT_PROBE_PIN; } + probe_configure_invert_mask(false); + break; + case 10: settings.status_report_mask = int_value; break; + case 11: settings.junction_deviation = value; break; + case 12: settings.arc_tolerance = value; break; + case 13: + if (int_value) { settings.flags |= BITFLAG_REPORT_INCHES; } + else { settings.flags &= ~BITFLAG_REPORT_INCHES; } + system_flag_wco_change(); // Make sure WCO is immediately updated. + break; + case 20: + if (int_value) { + if (bit_isfalse(settings.flags, BITFLAG_HOMING_ENABLE)) { return(STATUS_SOFT_LIMIT_ERROR); } + settings.flags |= BITFLAG_SOFT_LIMIT_ENABLE; + } else { settings.flags &= ~BITFLAG_SOFT_LIMIT_ENABLE; } + break; + case 21: + if (int_value) { settings.flags |= BITFLAG_HARD_LIMIT_ENABLE; } + else { settings.flags &= ~BITFLAG_HARD_LIMIT_ENABLE; } + limits_init(); // Re-init to immediately change. NOTE: Nice to have but could be problematic later. + break; + case 22: + if (int_value) { settings.flags |= BITFLAG_HOMING_ENABLE; } + else { + settings.flags &= ~BITFLAG_HOMING_ENABLE; + settings.flags &= ~BITFLAG_SOFT_LIMIT_ENABLE; // Force disable soft-limits. + } + break; + case 23: settings.homing_dir_mask = int_value; break; + case 24: settings.homing_feed_rate = value; break; + case 25: settings.homing_seek_rate = value; break; + case 26: settings.homing_debounce_delay = int_value; break; + case 27: settings.homing_pulloff = value; break; + case 30: settings.rpm_max = value; spindle_init(); break; // Re-initialize spindle rpm calibration + case 31: settings.rpm_min = value; spindle_init(); break; // Re-initialize spindle rpm calibration + case 32: + #ifdef VARIABLE_SPINDLE + if (int_value) { settings.flags |= BITFLAG_LASER_MODE; } + else { settings.flags &= ~BITFLAG_LASER_MODE; } + #else + return(STATUS_SETTING_DISABLED_LASER); + #endif + break; + default: + return(STATUS_INVALID_STATEMENT); + } + } + write_global_settings(); + return(STATUS_OK); +} + + +// Initialize the config subsystem +void settings_init() { + if(!read_global_settings()) { + report_status_message(STATUS_SETTING_READ_FAIL); + settings_restore(SETTINGS_RESTORE_ALL); // Force restore all EEPROM data. + report_grbl_settings(); + } +} + + +// Returns step pin mask according to Grbl internal axis indexing. +uint8_t get_step_pin_mask(uint8_t axis_idx) +{ + if ( axis_idx == X_AXIS ) { return((1<. +*/ + +#ifndef settings_h +#define settings_h + +#include "grbl.h" + + +// Version of the EEPROM data. Will be used to migrate existing data from older versions of Grbl +// when firmware is upgraded. Always stored in byte 0 of eeprom +#define SETTINGS_VERSION 10 // NOTE: Check settings_reset() when moving to next version. + +// Define bit flag masks for the boolean settings in settings.flag. +#define BIT_REPORT_INCHES 0 +#define BIT_LASER_MODE 1 +#define BIT_INVERT_ST_ENABLE 2 +#define BIT_HARD_LIMIT_ENABLE 3 +#define BIT_HOMING_ENABLE 4 +#define BIT_SOFT_LIMIT_ENABLE 5 +#define BIT_INVERT_LIMIT_PINS 6 +#define BIT_INVERT_PROBE_PIN 7 + +#define BITFLAG_REPORT_INCHES bit(BIT_REPORT_INCHES) +#define BITFLAG_LASER_MODE bit(BIT_LASER_MODE) +#define BITFLAG_INVERT_ST_ENABLE bit(BIT_INVERT_ST_ENABLE) +#define BITFLAG_HARD_LIMIT_ENABLE bit(BIT_HARD_LIMIT_ENABLE) +#define BITFLAG_HOMING_ENABLE bit(BIT_HOMING_ENABLE) +#define BITFLAG_SOFT_LIMIT_ENABLE bit(BIT_SOFT_LIMIT_ENABLE) +#define BITFLAG_INVERT_LIMIT_PINS bit(BIT_INVERT_LIMIT_PINS) +#define BITFLAG_INVERT_PROBE_PIN bit(BIT_INVERT_PROBE_PIN) + +// Define status reporting boolean enable bit flags in settings.status_report_mask +#define BITFLAG_RT_STATUS_POSITION_TYPE bit(0) +#define BITFLAG_RT_STATUS_BUFFER_STATE bit(1) + +// Define settings restore bitflags. +#define SETTINGS_RESTORE_DEFAULTS bit(0) +#define SETTINGS_RESTORE_PARAMETERS bit(1) +#define SETTINGS_RESTORE_STARTUP_LINES bit(2) +#define SETTINGS_RESTORE_BUILD_INFO bit(3) +#ifndef SETTINGS_RESTORE_ALL + #define SETTINGS_RESTORE_ALL 0xFF // All bitflags +#endif + +// Define EEPROM memory address location values for Grbl settings and parameters +// NOTE: The Atmega328p has 1KB EEPROM. The upper half is reserved for parameters and +// the startup script. The lower half contains the global settings and space for future +// developments. +#define EEPROM_ADDR_GLOBAL 1U +#define EEPROM_ADDR_PARAMETERS 512U +#define EEPROM_ADDR_STARTUP_BLOCK 768U +#define EEPROM_ADDR_BUILD_INFO 942U + +// Define EEPROM address indexing for coordinate parameters +#define N_COORDINATE_SYSTEM 6 // Number of supported work coordinate systems (from index 1) +#define SETTING_INDEX_NCOORD N_COORDINATE_SYSTEM+1 // Total number of system stored (from index 0) +// NOTE: Work coordinate indices are (0=G54, 1=G55, ... , 6=G59) +#define SETTING_INDEX_G28 N_COORDINATE_SYSTEM // Home position 1 +#define SETTING_INDEX_G30 N_COORDINATE_SYSTEM+1 // Home position 2 +// #define SETTING_INDEX_G92 N_COORDINATE_SYSTEM+2 // Coordinate offset (G92.2,G92.3 not supported) + +// Define Grbl axis settings numbering scheme. Starts at START_VAL, every INCREMENT, over N_SETTINGS. +#define AXIS_N_SETTINGS 4 +#define AXIS_SETTINGS_START_VAL 100 // NOTE: Reserving settings values >= 100 for axis settings. Up to 255. +#define AXIS_SETTINGS_INCREMENT 10 // Must be greater than the number of axis settings + +// Global persistent settings (Stored from byte EEPROM_ADDR_GLOBAL onwards) +typedef struct { + // Axis settings + float steps_per_mm[N_AXIS]; + float max_rate[N_AXIS]; + float acceleration[N_AXIS]; + float max_travel[N_AXIS]; + + // Remaining Grbl settings + uint8_t pulse_microseconds; + uint8_t step_invert_mask; + uint8_t dir_invert_mask; + uint8_t stepper_idle_lock_time; // If max value 255, steppers do not disable. + uint8_t status_report_mask; // Mask to indicate desired report data. + float junction_deviation; + float arc_tolerance; + + float rpm_max; + float rpm_min; + + uint8_t flags; // Contains default boolean settings + + uint8_t homing_dir_mask; + float homing_feed_rate; + float homing_seek_rate; + uint16_t homing_debounce_delay; + float homing_pulloff; +} settings_t; +extern settings_t settings; + +// Initialize the configuration subsystem (load settings from EEPROM) +void settings_init(); + +// Helper function to clear and restore EEPROM defaults +void settings_restore(uint8_t restore_flag); + +// A helper method to set new settings from command line +uint8_t settings_store_global_setting(uint8_t parameter, float value); + +// Stores the protocol line variable as a startup line in EEPROM +void settings_store_startup_line(uint8_t n, char *line); + +// Reads an EEPROM startup line to the protocol line variable +uint8_t settings_read_startup_line(uint8_t n, char *line); + +// Stores build info user-defined string +void settings_store_build_info(char *line); + +// Reads build info user-defined string +uint8_t settings_read_build_info(char *line); + +// Writes selected coordinate data to EEPROM +void settings_write_coord_data(uint8_t coord_select, float *coord_data); + +// Reads selected coordinate data from EEPROM +uint8_t settings_read_coord_data(uint8_t coord_select, float *coord_data); + +// Returns the step pin mask according to Grbl's internal axis numbering +uint8_t get_step_pin_mask(uint8_t i); + +// Returns the direction pin mask according to Grbl's internal axis numbering +uint8_t get_direction_pin_mask(uint8_t i); + +// Returns the limit pin mask according to Grbl's internal axis numbering +uint8_t get_limit_pin_mask(uint8_t i); + + +#endif diff --git a/trunk/Arduino/GRBL_1.1f/spindle_control.c b/trunk/Arduino/GRBL_1.1f/spindle_control.c new file mode 100644 index 00000000..61cb90b8 --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f/spindle_control.c @@ -0,0 +1,283 @@ +/* + spindle_control.c - spindle control methods + Part of Grbl + + Copyright (c) 2012-2017 Sungeun K. Jeon for Gnea Research LLC + Copyright (c) 2009-2011 Simen Svale Skogsrud + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +#include "grbl.h" + + +#ifdef VARIABLE_SPINDLE + static float pwm_gradient; // Precalulated value to speed up rpm to PWM conversions. +#endif + + +void spindle_init() +{ + #ifdef VARIABLE_SPINDLE + + // Configure variable spindle PWM and enable pin, if requried. On the Uno, PWM and enable are + // combined unless configured otherwise. + SPINDLE_PWM_DDR |= (1<= settings.rpm_max) || (rpm >= RPM_MAX)) { + rpm = RPM_MAX; + pwm_value = SPINDLE_PWM_MAX_VALUE; + } else if (rpm <= RPM_MIN) { + if (rpm == 0.0) { // S0 disables spindle + pwm_value = SPINDLE_PWM_OFF_VALUE; + } else { + rpm = RPM_MIN; + pwm_value = SPINDLE_PWM_MIN_VALUE; + } + } else { + // Compute intermediate PWM value with linear spindle speed model via piecewise linear fit model. + #if (N_PIECES > 3) + if (rpm > RPM_POINT34) { + pwm_value = floor(RPM_LINE_A4*rpm - RPM_LINE_B4); + } else + #endif + #if (N_PIECES > 2) + if (rpm > RPM_POINT23) { + pwm_value = floor(RPM_LINE_A3*rpm - RPM_LINE_B3); + } else + #endif + #if (N_PIECES > 1) + if (rpm > RPM_POINT12) { + pwm_value = floor(RPM_LINE_A2*rpm - RPM_LINE_B2); + } else + #endif + { + pwm_value = floor(RPM_LINE_A1*rpm - RPM_LINE_B1); + } + } + sys.spindle_speed = rpm; + return(pwm_value); + } + + #else + + // Called by spindle_set_state() and step segment generator. Keep routine small and efficient. + uint8_t spindle_compute_pwm_value(float rpm) // 328p PWM register is 8-bit. + { + uint8_t pwm_value; + rpm *= (0.010*sys.spindle_speed_ovr); // Scale by spindle speed override value. + // Calculate PWM register value based on rpm max/min settings and programmed rpm. + if ((settings.rpm_min >= settings.rpm_max) || (rpm >= settings.rpm_max)) { + // No PWM range possible. Set simple on/off spindle control pin state. + sys.spindle_speed = settings.rpm_max; + pwm_value = SPINDLE_PWM_MAX_VALUE; + } else if (rpm <= settings.rpm_min) { + if (rpm == 0.0) { // S0 disables spindle + sys.spindle_speed = 0.0; + pwm_value = SPINDLE_PWM_OFF_VALUE; + } else { // Set minimum PWM output + sys.spindle_speed = settings.rpm_min; + pwm_value = SPINDLE_PWM_MIN_VALUE; + } + } else { + // Compute intermediate PWM value with linear spindle speed model. + // NOTE: A nonlinear model could be installed here, if required, but keep it VERY light-weight. + sys.spindle_speed = rpm; + pwm_value = floor((rpm-settings.rpm_min)*pwm_gradient) + SPINDLE_PWM_MIN_VALUE; + } + return(pwm_value); + } + + #endif +#endif + + +// Immediately sets spindle running state with direction and spindle rpm via PWM, if enabled. +// Called by g-code parser spindle_sync(), parking retract and restore, g-code program end, +// sleep, and spindle stop override. +#ifdef VARIABLE_SPINDLE + void spindle_set_state(uint8_t state, float rpm) +#else + void _spindle_set_state(uint8_t state) +#endif +{ + if (sys.abort) { return; } // Block during abort. + if (state == SPINDLE_DISABLE) { // Halt or set spindle direction and rpm. + + #ifdef VARIABLE_SPINDLE + sys.spindle_speed = 0.0; + #endif + spindle_stop(); + + } else { + + #ifndef USE_SPINDLE_DIR_AS_ENABLE_PIN + if (state == SPINDLE_ENABLE_CW) { + SPINDLE_DIRECTION_PORT &= ~(1<. +*/ + +#ifndef spindle_control_h +#define spindle_control_h + +#define SPINDLE_NO_SYNC false +#define SPINDLE_FORCE_SYNC true + +#define SPINDLE_STATE_DISABLE 0 // Must be zero. +#define SPINDLE_STATE_CW bit(0) +#define SPINDLE_STATE_CCW bit(1) + + +// Initializes spindle pins and hardware PWM, if enabled. +void spindle_init(); + +// Returns current spindle output state. Overrides may alter it from programmed states. +uint8_t spindle_get_state(); + +// Called by g-code parser when setting spindle state and requires a buffer sync. +// Immediately sets spindle running state with direction and spindle rpm via PWM, if enabled. +// Called by spindle_sync() after sync and parking motion/spindle stop override during restore. +#ifdef VARIABLE_SPINDLE + + // Called by g-code parser when setting spindle state and requires a buffer sync. + void spindle_sync(uint8_t state, float rpm); + + // Sets spindle running state with direction, enable, and spindle PWM. + void spindle_set_state(uint8_t state, float rpm); + + // Sets spindle PWM quickly for stepper ISR. Also called by spindle_set_state(). + // NOTE: 328p PWM register is 8-bit. + void spindle_set_speed(uint8_t pwm_value); + + // Computes 328p-specific PWM register value for the given RPM for quick updating. + uint8_t spindle_compute_pwm_value(float rpm); + +#else + + // Called by g-code parser when setting spindle state and requires a buffer sync. + #define spindle_sync(state, rpm) _spindle_sync(state) + void _spindle_sync(uint8_t state); + + // Sets spindle running state with direction and enable. + #define spindle_set_state(state, rpm) _spindle_set_state(state) + void _spindle_set_state(uint8_t state); + +#endif + +// Stop and start spindle routines. Called by all spindle routines and stepper ISR. +void spindle_stop(); + + +#endif diff --git a/trunk/Arduino/GRBL_1.1f/stepper.c b/trunk/Arduino/GRBL_1.1f/stepper.c new file mode 100644 index 00000000..3bfccd49 --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f/stepper.c @@ -0,0 +1,1022 @@ +/* + stepper.c - stepper motor driver: executes motion plans using stepper motors + Part of Grbl + + Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC + Copyright (c) 2009-2011 Simen Svale Skogsrud + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +#include "grbl.h" + + +// Some useful constants. +#define DT_SEGMENT (1.0/(ACCELERATION_TICKS_PER_SECOND*60.0)) // min/segment +#define REQ_MM_INCREMENT_SCALAR 1.25 +#define RAMP_ACCEL 0 +#define RAMP_CRUISE 1 +#define RAMP_DECEL 2 +#define RAMP_DECEL_OVERRIDE 3 + +#define PREP_FLAG_RECALCULATE bit(0) +#define PREP_FLAG_HOLD_PARTIAL_BLOCK bit(1) +#define PREP_FLAG_PARKING bit(2) +#define PREP_FLAG_DECEL_OVERRIDE bit(3) + +// Define Adaptive Multi-Axis Step-Smoothing(AMASS) levels and cutoff frequencies. The highest level +// frequency bin starts at 0Hz and ends at its cutoff frequency. The next lower level frequency bin +// starts at the next higher cutoff frequency, and so on. The cutoff frequencies for each level must +// be considered carefully against how much it over-drives the stepper ISR, the accuracy of the 16-bit +// timer, and the CPU overhead. Level 0 (no AMASS, normal operation) frequency bin starts at the +// Level 1 cutoff frequency and up to as fast as the CPU allows (over 30kHz in limited testing). +// NOTE: AMASS cutoff frequency multiplied by ISR overdrive factor must not exceed maximum step frequency. +// NOTE: Current settings are set to overdrive the ISR to no more than 16kHz, balancing CPU overhead +// and timer accuracy. Do not alter these settings unless you know what you are doing. +#ifdef ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING + #define MAX_AMASS_LEVEL 3 + // AMASS_LEVEL0: Normal operation. No AMASS. No upper cutoff frequency. Starts at LEVEL1 cutoff frequency. + #define AMASS_LEVEL1 (F_CPU/8000) // Over-drives ISR (x2). Defined as F_CPU/(Cutoff frequency in Hz) + #define AMASS_LEVEL2 (F_CPU/4000) // Over-drives ISR (x4) + #define AMASS_LEVEL3 (F_CPU/2000) // Over-drives ISR (x8) + + #if MAX_AMASS_LEVEL <= 0 + error "AMASS must have 1 or more levels to operate correctly." + #endif +#endif + + +// Stores the planner block Bresenham algorithm execution data for the segments in the segment +// buffer. Normally, this buffer is partially in-use, but, for the worst case scenario, it will +// never exceed the number of accessible stepper buffer segments (SEGMENT_BUFFER_SIZE-1). +// NOTE: This data is copied from the prepped planner blocks so that the planner blocks may be +// discarded when entirely consumed and completed by the segment buffer. Also, AMASS alters this +// data for its own use. +typedef struct { + uint32_t steps[N_AXIS]; + uint32_t step_event_count; + uint8_t direction_bits; + #ifdef VARIABLE_SPINDLE + uint8_t is_pwm_rate_adjusted; // Tracks motions that require constant laser power/rate + #endif +} st_block_t; +static st_block_t st_block_buffer[SEGMENT_BUFFER_SIZE-1]; + +// Primary stepper segment ring buffer. Contains small, short line segments for the stepper +// algorithm to execute, which are "checked-out" incrementally from the first block in the +// planner buffer. Once "checked-out", the steps in the segments buffer cannot be modified by +// the planner, where the remaining planner block steps still can. +typedef struct { + uint16_t n_step; // Number of step events to be executed for this segment + uint16_t cycles_per_tick; // Step distance traveled per ISR tick, aka step rate. + uint8_t st_block_index; // Stepper block data index. Uses this information to execute this segment. + #ifdef ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING + uint8_t amass_level; // Indicates AMASS level for the ISR to execute this segment + #else + uint8_t prescaler; // Without AMASS, a prescaler is required to adjust for slow timing. + #endif + #ifdef VARIABLE_SPINDLE + uint8_t spindle_pwm; + #endif +} segment_t; +static segment_t segment_buffer[SEGMENT_BUFFER_SIZE]; + +// Stepper ISR data struct. Contains the running data for the main stepper ISR. +typedef struct { + // Used by the bresenham line algorithm + uint32_t counter_x, // Counter variables for the bresenham line tracer + counter_y, + counter_z; + #ifdef STEP_PULSE_DELAY + uint8_t step_bits; // Stores out_bits output to complete the step pulse delay + #endif + + uint8_t execute_step; // Flags step execution for each interrupt. + uint8_t step_pulse_time; // Step pulse reset time after step rise + uint8_t step_outbits; // The next stepping-bits to be output + uint8_t dir_outbits; + #ifdef ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING + uint32_t steps[N_AXIS]; + #endif + + uint16_t step_count; // Steps remaining in line segment motion + uint8_t exec_block_index; // Tracks the current st_block index. Change indicates new block. + st_block_t *exec_block; // Pointer to the block data for the segment being executed + segment_t *exec_segment; // Pointer to the segment being executed +} stepper_t; +static stepper_t st; + +// Step segment ring buffer indices +static volatile uint8_t segment_buffer_tail; +static uint8_t segment_buffer_head; +static uint8_t segment_next_head; + +// Step and direction port invert masks. +static uint8_t step_port_invert_mask; +static uint8_t dir_port_invert_mask; + +// Used to avoid ISR nesting of the "Stepper Driver Interrupt". Should never occur though. +static volatile uint8_t busy; + +// Pointers for the step segment being prepped from the planner buffer. Accessed only by the +// main program. Pointers may be planning segments or planner blocks ahead of what being executed. +static plan_block_t *pl_block; // Pointer to the planner block being prepped +static st_block_t *st_prep_block; // Pointer to the stepper block data being prepped + +// Segment preparation data struct. Contains all the necessary information to compute new segments +// based on the current executing planner block. +typedef struct { + uint8_t st_block_index; // Index of stepper common data block being prepped + uint8_t recalculate_flag; + + float dt_remainder; + float steps_remaining; + float step_per_mm; + float req_mm_increment; + + #ifdef PARKING_ENABLE + uint8_t last_st_block_index; + float last_steps_remaining; + float last_step_per_mm; + float last_dt_remainder; + #endif + + uint8_t ramp_type; // Current segment ramp state + float mm_complete; // End of velocity profile from end of current planner block in (mm). + // NOTE: This value must coincide with a step(no mantissa) when converted. + float current_speed; // Current speed at the end of the segment buffer (mm/min) + float maximum_speed; // Maximum speed of executing block. Not always nominal speed. (mm/min) + float exit_speed; // Exit speed of executing block (mm/min) + float accelerate_until; // Acceleration ramp end measured from end of block (mm) + float decelerate_after; // Deceleration ramp start measured from end of block (mm) + + #ifdef VARIABLE_SPINDLE + float inv_rate; // Used by PWM laser mode to speed up segment calculations. + uint8_t current_spindle_pwm; + #endif +} st_prep_t; +static st_prep_t prep; + + +/* BLOCK VELOCITY PROFILE DEFINITION + __________________________ + /| |\ _________________ ^ + / | | \ /| |\ | + / | | \ / | | \ s + / | | | | | \ p + / | | | | | \ e + +-----+------------------------+---+--+---------------+----+ e + | BLOCK 1 ^ BLOCK 2 | d + | + time -----> EXAMPLE: Block 2 entry speed is at max junction velocity + + The planner block buffer is planned assuming constant acceleration velocity profiles and are + continuously joined at block junctions as shown above. However, the planner only actively computes + the block entry speeds for an optimal velocity plan, but does not compute the block internal + velocity profiles. These velocity profiles are computed ad-hoc as they are executed by the + stepper algorithm and consists of only 7 possible types of profiles: cruise-only, cruise- + deceleration, acceleration-cruise, acceleration-only, deceleration-only, full-trapezoid, and + triangle(no cruise). + + maximum_speed (< nominal_speed) -> + + +--------+ <- maximum_speed (= nominal_speed) /|\ + / \ / | \ + current_speed -> + \ / | + <- exit_speed + | + <- exit_speed / | | + +-------------+ current_speed -> +----+--+ + time --> ^ ^ ^ ^ + | | | | + decelerate_after(in mm) decelerate_after(in mm) + ^ ^ ^ ^ + | | | | + accelerate_until(in mm) accelerate_until(in mm) + + The step segment buffer computes the executing block velocity profile and tracks the critical + parameters for the stepper algorithm to accurately trace the profile. These critical parameters + are shown and defined in the above illustration. +*/ + + +// Stepper state initialization. Cycle should only start if the st.cycle_start flag is +// enabled. Startup init and limits call this function but shouldn't start the cycle. +void st_wake_up() +{ + // Enable stepper drivers. + if (bit_istrue(settings.flags,BITFLAG_INVERT_ST_ENABLE)) { STEPPERS_DISABLE_PORT |= (1<> 3); + // Set delay between direction pin write and step command. + OCR0A = -(((settings.pulse_microseconds)*TICKS_PER_MICROSECOND) >> 3); + #else // Normal operation + // Set step pulse time. Ad hoc computation from oscilloscope. Uses two's complement. + st.step_pulse_time = -(((settings.pulse_microseconds-2)*TICKS_PER_MICROSECOND) >> 3); + #endif + + // Enable Stepper Driver Interrupt + TIMSK1 |= (1<prescaler<cycles_per_tick; + st.step_count = st.exec_segment->n_step; // NOTE: Can sometimes be zero when moving slow. + // If the new segment starts a new planner block, initialize stepper variables and counters. + // NOTE: When the segment data index changes, this indicates a new planner block. + if ( st.exec_block_index != st.exec_segment->st_block_index ) { + st.exec_block_index = st.exec_segment->st_block_index; + st.exec_block = &st_block_buffer[st.exec_block_index]; + + // Initialize Bresenham line and distance counters + st.counter_x = st.counter_y = st.counter_z = (st.exec_block->step_event_count >> 1); + } + st.dir_outbits = st.exec_block->direction_bits ^ dir_port_invert_mask; + + #ifdef ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING + // With AMASS enabled, adjust Bresenham axis increment counters according to AMASS level. + st.steps[X_AXIS] = st.exec_block->steps[X_AXIS] >> st.exec_segment->amass_level; + st.steps[Y_AXIS] = st.exec_block->steps[Y_AXIS] >> st.exec_segment->amass_level; + st.steps[Z_AXIS] = st.exec_block->steps[Z_AXIS] >> st.exec_segment->amass_level; + #endif + + #ifdef VARIABLE_SPINDLE + // Set real-time spindle output as segment is loaded, just prior to the first step. + spindle_set_speed(st.exec_segment->spindle_pwm); + #endif + + } else { + // Segment buffer empty. Shutdown. + st_go_idle(); + #ifdef VARIABLE_SPINDLE + // Ensure pwm is set properly upon completion of rate-controlled motion. + if (st.exec_block->is_pwm_rate_adjusted) { spindle_set_speed(SPINDLE_PWM_OFF_VALUE); } + #endif + system_set_exec_state_flag(EXEC_CYCLE_STOP); // Flag main program for cycle end + return; // Nothing to do but exit. + } + } + + + // Check probing state. + if (sys_probe_state == PROBE_ACTIVE) { probe_state_monitor(); } + + // Reset step out bits. + st.step_outbits = 0; + + // Execute step displacement profile by Bresenham line algorithm + #ifdef ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING + st.counter_x += st.steps[X_AXIS]; + #else + st.counter_x += st.exec_block->steps[X_AXIS]; + #endif + if (st.counter_x > st.exec_block->step_event_count) { + st.step_outbits |= (1<step_event_count; + if (st.exec_block->direction_bits & (1<steps[Y_AXIS]; + #endif + if (st.counter_y > st.exec_block->step_event_count) { + st.step_outbits |= (1<step_event_count; + if (st.exec_block->direction_bits & (1<steps[Z_AXIS]; + #endif + if (st.counter_z > st.exec_block->step_event_count) { + st.step_outbits |= (1<step_event_count; + if (st.exec_block->direction_bits & (1<entry_speed_sqr = prep.current_speed*prep.current_speed; // Update entry speed. + pl_block = NULL; // Flag st_prep_segment() to load and check active velocity profile. + } +} + + +// Increments the step segment buffer block data ring buffer. +static uint8_t st_next_block_index(uint8_t block_index) +{ + block_index++; + if ( block_index == (SEGMENT_BUFFER_SIZE-1) ) { return(0); } + return(block_index); +} + + +#ifdef PARKING_ENABLE + // Changes the run state of the step segment buffer to execute the special parking motion. + void st_parking_setup_buffer() + { + // Store step execution data of partially completed block, if necessary. + if (prep.recalculate_flag & PREP_FLAG_HOLD_PARTIAL_BLOCK) { + prep.last_st_block_index = prep.st_block_index; + prep.last_steps_remaining = prep.steps_remaining; + prep.last_dt_remainder = prep.dt_remainder; + prep.last_step_per_mm = prep.step_per_mm; + } + // Set flags to execute a parking motion + prep.recalculate_flag |= PREP_FLAG_PARKING; + prep.recalculate_flag &= ~(PREP_FLAG_RECALCULATE); + pl_block = NULL; // Always reset parking motion to reload new block. + } + + + // Restores the step segment buffer to the normal run state after a parking motion. + void st_parking_restore_buffer() + { + // Restore step execution data and flags of partially completed block, if necessary. + if (prep.recalculate_flag & PREP_FLAG_HOLD_PARTIAL_BLOCK) { + st_prep_block = &st_block_buffer[prep.last_st_block_index]; + prep.st_block_index = prep.last_st_block_index; + prep.steps_remaining = prep.last_steps_remaining; + prep.dt_remainder = prep.last_dt_remainder; + prep.step_per_mm = prep.last_step_per_mm; + prep.recalculate_flag = (PREP_FLAG_HOLD_PARTIAL_BLOCK | PREP_FLAG_RECALCULATE); + prep.req_mm_increment = REQ_MM_INCREMENT_SCALAR/prep.step_per_mm; // Recompute this value. + } else { + prep.recalculate_flag = false; + } + pl_block = NULL; // Set to reload next block. + } +#endif + + +/* Prepares step segment buffer. Continuously called from main program. + + The segment buffer is an intermediary buffer interface between the execution of steps + by the stepper algorithm and the velocity profiles generated by the planner. The stepper + algorithm only executes steps within the segment buffer and is filled by the main program + when steps are "checked-out" from the first block in the planner buffer. This keeps the + step execution and planning optimization processes atomic and protected from each other. + The number of steps "checked-out" from the planner buffer and the number of segments in + the segment buffer is sized and computed such that no operation in the main program takes + longer than the time it takes the stepper algorithm to empty it before refilling it. + Currently, the segment buffer conservatively holds roughly up to 40-50 msec of steps. + NOTE: Computation units are in steps, millimeters, and minutes. +*/ +void st_prep_buffer() +{ + // Block step prep buffer, while in a suspend state and there is no suspend motion to execute. + if (bit_istrue(sys.step_control,STEP_CONTROL_END_MOTION)) { return; } + + while (segment_buffer_tail != segment_next_head) { // Check if we need to fill the buffer. + + // Determine if we need to load a new planner block or if the block needs to be recomputed. + if (pl_block == NULL) { + + // Query planner for a queued block + if (sys.step_control & STEP_CONTROL_EXECUTE_SYS_MOTION) { pl_block = plan_get_system_motion_block(); } + else { pl_block = plan_get_current_block(); } + if (pl_block == NULL) { return; } // No planner blocks. Exit. + + // Check if we need to only recompute the velocity profile or load a new block. + if (prep.recalculate_flag & PREP_FLAG_RECALCULATE) { + + #ifdef PARKING_ENABLE + if (prep.recalculate_flag & PREP_FLAG_PARKING) { prep.recalculate_flag &= ~(PREP_FLAG_RECALCULATE); } + else { prep.recalculate_flag = false; } + #else + prep.recalculate_flag = false; + #endif + + } else { + + // Load the Bresenham stepping data for the block. + prep.st_block_index = st_next_block_index(prep.st_block_index); + + // Prepare and copy Bresenham algorithm segment data from the new planner block, so that + // when the segment buffer completes the planner block, it may be discarded when the + // segment buffer finishes the prepped block, but the stepper ISR is still executing it. + st_prep_block = &st_block_buffer[prep.st_block_index]; + st_prep_block->direction_bits = pl_block->direction_bits; + uint8_t idx; + #ifndef ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING + for (idx=0; idxsteps[idx] = (pl_block->steps[idx] << 1); } + st_prep_block->step_event_count = (pl_block->step_event_count << 1); + #else + // With AMASS enabled, simply bit-shift multiply all Bresenham data by the max AMASS + // level, such that we never divide beyond the original data anywhere in the algorithm. + // If the original data is divided, we can lose a step from integer roundoff. + for (idx=0; idxsteps[idx] = pl_block->steps[idx] << MAX_AMASS_LEVEL; } + st_prep_block->step_event_count = pl_block->step_event_count << MAX_AMASS_LEVEL; + #endif + + // Initialize segment buffer data for generating the segments. + prep.steps_remaining = (float)pl_block->step_event_count; + prep.step_per_mm = prep.steps_remaining/pl_block->millimeters; + prep.req_mm_increment = REQ_MM_INCREMENT_SCALAR/prep.step_per_mm; + prep.dt_remainder = 0.0; // Reset for new segment block + + if ((sys.step_control & STEP_CONTROL_EXECUTE_HOLD) || (prep.recalculate_flag & PREP_FLAG_DECEL_OVERRIDE)) { + // New block loaded mid-hold. Override planner block entry speed to enforce deceleration. + prep.current_speed = prep.exit_speed; + pl_block->entry_speed_sqr = prep.exit_speed*prep.exit_speed; + prep.recalculate_flag &= ~(PREP_FLAG_DECEL_OVERRIDE); + } else { + prep.current_speed = sqrt(pl_block->entry_speed_sqr); + } + + #ifdef VARIABLE_SPINDLE + // Setup laser mode variables. PWM rate adjusted motions will always complete a motion with the + // spindle off. + st_prep_block->is_pwm_rate_adjusted = false; + if (settings.flags & BITFLAG_LASER_MODE) { + if (pl_block->condition & PL_COND_FLAG_SPINDLE_CCW) { + // Pre-compute inverse programmed rate to speed up PWM updating per step segment. + prep.inv_rate = 1.0/pl_block->programmed_rate; + st_prep_block->is_pwm_rate_adjusted = true; + } + } + #endif + } + + /* --------------------------------------------------------------------------------- + Compute the velocity profile of a new planner block based on its entry and exit + speeds, or recompute the profile of a partially-completed planner block if the + planner has updated it. For a commanded forced-deceleration, such as from a feed + hold, override the planner velocities and decelerate to the target exit speed. + */ + prep.mm_complete = 0.0; // Default velocity profile complete at 0.0mm from end of block. + float inv_2_accel = 0.5/pl_block->acceleration; + if (sys.step_control & STEP_CONTROL_EXECUTE_HOLD) { // [Forced Deceleration to Zero Velocity] + // Compute velocity profile parameters for a feed hold in-progress. This profile overrides + // the planner block profile, enforcing a deceleration to zero speed. + prep.ramp_type = RAMP_DECEL; + // Compute decelerate distance relative to end of block. + float decel_dist = pl_block->millimeters - inv_2_accel*pl_block->entry_speed_sqr; + if (decel_dist < 0.0) { + // Deceleration through entire planner block. End of feed hold is not in this block. + prep.exit_speed = sqrt(pl_block->entry_speed_sqr-2*pl_block->acceleration*pl_block->millimeters); + } else { + prep.mm_complete = decel_dist; // End of feed hold. + prep.exit_speed = 0.0; + } + } else { // [Normal Operation] + // Compute or recompute velocity profile parameters of the prepped planner block. + prep.ramp_type = RAMP_ACCEL; // Initialize as acceleration ramp. + prep.accelerate_until = pl_block->millimeters; + + float exit_speed_sqr; + float nominal_speed; + if (sys.step_control & STEP_CONTROL_EXECUTE_SYS_MOTION) { + prep.exit_speed = exit_speed_sqr = 0.0; // Enforce stop at end of system motion. + } else { + exit_speed_sqr = plan_get_exec_block_exit_speed_sqr(); + prep.exit_speed = sqrt(exit_speed_sqr); + } + + nominal_speed = plan_compute_profile_nominal_speed(pl_block); + float nominal_speed_sqr = nominal_speed*nominal_speed; + float intersect_distance = + 0.5*(pl_block->millimeters+inv_2_accel*(pl_block->entry_speed_sqr-exit_speed_sqr)); + + if (pl_block->entry_speed_sqr > nominal_speed_sqr) { // Only occurs during override reductions. + prep.accelerate_until = pl_block->millimeters - inv_2_accel*(pl_block->entry_speed_sqr-nominal_speed_sqr); + if (prep.accelerate_until <= 0.0) { // Deceleration-only. + prep.ramp_type = RAMP_DECEL; + // prep.decelerate_after = pl_block->millimeters; + // prep.maximum_speed = prep.current_speed; + + // Compute override block exit speed since it doesn't match the planner exit speed. + prep.exit_speed = sqrt(pl_block->entry_speed_sqr - 2*pl_block->acceleration*pl_block->millimeters); + prep.recalculate_flag |= PREP_FLAG_DECEL_OVERRIDE; // Flag to load next block as deceleration override. + + // TODO: Determine correct handling of parameters in deceleration-only. + // Can be tricky since entry speed will be current speed, as in feed holds. + // Also, look into near-zero speed handling issues with this. + + } else { + // Decelerate to cruise or cruise-decelerate types. Guaranteed to intersect updated plan. + prep.decelerate_after = inv_2_accel*(nominal_speed_sqr-exit_speed_sqr); // Should always be >= 0.0 due to planner reinit. + prep.maximum_speed = nominal_speed; + prep.ramp_type = RAMP_DECEL_OVERRIDE; + } + } else if (intersect_distance > 0.0) { + if (intersect_distance < pl_block->millimeters) { // Either trapezoid or triangle types + // NOTE: For acceleration-cruise and cruise-only types, following calculation will be 0.0. + prep.decelerate_after = inv_2_accel*(nominal_speed_sqr-exit_speed_sqr); + if (prep.decelerate_after < intersect_distance) { // Trapezoid type + prep.maximum_speed = nominal_speed; + if (pl_block->entry_speed_sqr == nominal_speed_sqr) { + // Cruise-deceleration or cruise-only type. + prep.ramp_type = RAMP_CRUISE; + } else { + // Full-trapezoid or acceleration-cruise types + prep.accelerate_until -= inv_2_accel*(nominal_speed_sqr-pl_block->entry_speed_sqr); + } + } else { // Triangle type + prep.accelerate_until = intersect_distance; + prep.decelerate_after = intersect_distance; + prep.maximum_speed = sqrt(2.0*pl_block->acceleration*intersect_distance+exit_speed_sqr); + } + } else { // Deceleration-only type + prep.ramp_type = RAMP_DECEL; + // prep.decelerate_after = pl_block->millimeters; + // prep.maximum_speed = prep.current_speed; + } + } else { // Acceleration-only type + prep.accelerate_until = 0.0; + // prep.decelerate_after = 0.0; + prep.maximum_speed = prep.exit_speed; + } + } + + #ifdef VARIABLE_SPINDLE + bit_true(sys.step_control, STEP_CONTROL_UPDATE_SPINDLE_PWM); // Force update whenever updating block. + #endif + } + + // Initialize new segment + segment_t *prep_segment = &segment_buffer[segment_buffer_head]; + + // Set new segment to point to the current segment data block. + prep_segment->st_block_index = prep.st_block_index; + + /*------------------------------------------------------------------------------------ + Compute the average velocity of this new segment by determining the total distance + traveled over the segment time DT_SEGMENT. The following code first attempts to create + a full segment based on the current ramp conditions. If the segment time is incomplete + when terminating at a ramp state change, the code will continue to loop through the + progressing ramp states to fill the remaining segment execution time. However, if + an incomplete segment terminates at the end of the velocity profile, the segment is + considered completed despite having a truncated execution time less than DT_SEGMENT. + The velocity profile is always assumed to progress through the ramp sequence: + acceleration ramp, cruising state, and deceleration ramp. Each ramp's travel distance + may range from zero to the length of the block. Velocity profiles can end either at + the end of planner block (typical) or mid-block at the end of a forced deceleration, + such as from a feed hold. + */ + float dt_max = DT_SEGMENT; // Maximum segment time + float dt = 0.0; // Initialize segment time + float time_var = dt_max; // Time worker variable + float mm_var; // mm-Distance worker variable + float speed_var; // Speed worker variable + float mm_remaining = pl_block->millimeters; // New segment distance from end of block. + float minimum_mm = mm_remaining-prep.req_mm_increment; // Guarantee at least one step. + if (minimum_mm < 0.0) { minimum_mm = 0.0; } + + do { + switch (prep.ramp_type) { + case RAMP_DECEL_OVERRIDE: + speed_var = pl_block->acceleration*time_var; + if (prep.current_speed-prep.maximum_speed <= speed_var) { + // Cruise or cruise-deceleration types only for deceleration override. + mm_remaining = prep.accelerate_until; + time_var = 2.0*(pl_block->millimeters-mm_remaining)/(prep.current_speed+prep.maximum_speed); + prep.ramp_type = RAMP_CRUISE; + prep.current_speed = prep.maximum_speed; + } else { // Mid-deceleration override ramp. + mm_remaining -= time_var*(prep.current_speed - 0.5*speed_var); + prep.current_speed -= speed_var; + } + break; + case RAMP_ACCEL: + // NOTE: Acceleration ramp only computes during first do-while loop. + speed_var = pl_block->acceleration*time_var; + mm_remaining -= time_var*(prep.current_speed + 0.5*speed_var); + if (mm_remaining < prep.accelerate_until) { // End of acceleration ramp. + // Acceleration-cruise, acceleration-deceleration ramp junction, or end of block. + mm_remaining = prep.accelerate_until; // NOTE: 0.0 at EOB + time_var = 2.0*(pl_block->millimeters-mm_remaining)/(prep.current_speed+prep.maximum_speed); + if (mm_remaining == prep.decelerate_after) { prep.ramp_type = RAMP_DECEL; } + else { prep.ramp_type = RAMP_CRUISE; } + prep.current_speed = prep.maximum_speed; + } else { // Acceleration only. + prep.current_speed += speed_var; + } + break; + case RAMP_CRUISE: + // NOTE: mm_var used to retain the last mm_remaining for incomplete segment time_var calculations. + // NOTE: If maximum_speed*time_var value is too low, round-off can cause mm_var to not change. To + // prevent this, simply enforce a minimum speed threshold in the planner. + mm_var = mm_remaining - prep.maximum_speed*time_var; + if (mm_var < prep.decelerate_after) { // End of cruise. + // Cruise-deceleration junction or end of block. + time_var = (mm_remaining - prep.decelerate_after)/prep.maximum_speed; + mm_remaining = prep.decelerate_after; // NOTE: 0.0 at EOB + prep.ramp_type = RAMP_DECEL; + } else { // Cruising only. + mm_remaining = mm_var; + } + break; + default: // case RAMP_DECEL: + // NOTE: mm_var used as a misc worker variable to prevent errors when near zero speed. + speed_var = pl_block->acceleration*time_var; // Used as delta speed (mm/min) + if (prep.current_speed > speed_var) { // Check if at or below zero speed. + // Compute distance from end of segment to end of block. + mm_var = mm_remaining - time_var*(prep.current_speed - 0.5*speed_var); // (mm) + if (mm_var > prep.mm_complete) { // Typical case. In deceleration ramp. + mm_remaining = mm_var; + prep.current_speed -= speed_var; + break; // Segment complete. Exit switch-case statement. Continue do-while loop. + } + } + // Otherwise, at end of block or end of forced-deceleration. + time_var = 2.0*(mm_remaining-prep.mm_complete)/(prep.current_speed+prep.exit_speed); + mm_remaining = prep.mm_complete; + prep.current_speed = prep.exit_speed; + } + dt += time_var; // Add computed ramp time to total segment time. + if (dt < dt_max) { time_var = dt_max - dt; } // **Incomplete** At ramp junction. + else { + if (mm_remaining > minimum_mm) { // Check for very slow segments with zero steps. + // Increase segment time to ensure at least one step in segment. Override and loop + // through distance calculations until minimum_mm or mm_complete. + dt_max += DT_SEGMENT; + time_var = dt_max - dt; + } else { + break; // **Complete** Exit loop. Segment execution time maxed. + } + } + } while (mm_remaining > prep.mm_complete); // **Complete** Exit loop. Profile complete. + + #ifdef VARIABLE_SPINDLE + /* ----------------------------------------------------------------------------------- + Compute spindle speed PWM output for step segment + */ + + if (st_prep_block->is_pwm_rate_adjusted || (sys.step_control & STEP_CONTROL_UPDATE_SPINDLE_PWM)) { + if (pl_block->condition & (PL_COND_FLAG_SPINDLE_CW | PL_COND_FLAG_SPINDLE_CCW)) { + float rpm = pl_block->spindle_speed; + // NOTE: Feed and rapid overrides are independent of PWM value and do not alter laser power/rate. + if (st_prep_block->is_pwm_rate_adjusted) { rpm *= (prep.current_speed * prep.inv_rate); } + // If current_speed is zero, then may need to be rpm_min*(100/MAX_SPINDLE_SPEED_OVERRIDE) + // but this would be instantaneous only and during a motion. May not matter at all. + prep.current_spindle_pwm = spindle_compute_pwm_value(rpm); + } else { + sys.spindle_speed = 0.0; + prep.current_spindle_pwm = SPINDLE_PWM_OFF_VALUE; + } + bit_false(sys.step_control,STEP_CONTROL_UPDATE_SPINDLE_PWM); + } + prep_segment->spindle_pwm = prep.current_spindle_pwm; // Reload segment PWM value + + #endif + + /* ----------------------------------------------------------------------------------- + Compute segment step rate, steps to execute, and apply necessary rate corrections. + NOTE: Steps are computed by direct scalar conversion of the millimeter distance + remaining in the block, rather than incrementally tallying the steps executed per + segment. This helps in removing floating point round-off issues of several additions. + However, since floats have only 7.2 significant digits, long moves with extremely + high step counts can exceed the precision of floats, which can lead to lost steps. + Fortunately, this scenario is highly unlikely and unrealistic in CNC machines + supported by Grbl (i.e. exceeding 10 meters axis travel at 200 step/mm). + */ + float step_dist_remaining = prep.step_per_mm*mm_remaining; // Convert mm_remaining to steps + float n_steps_remaining = ceil(step_dist_remaining); // Round-up current steps remaining + float last_n_steps_remaining = ceil(prep.steps_remaining); // Round-up last steps remaining + prep_segment->n_step = last_n_steps_remaining-n_steps_remaining; // Compute number of steps to execute. + + // Bail if we are at the end of a feed hold and don't have a step to execute. + if (prep_segment->n_step == 0) { + if (sys.step_control & STEP_CONTROL_EXECUTE_HOLD) { + // Less than one step to decelerate to zero speed, but already very close. AMASS + // requires full steps to execute. So, just bail. + bit_true(sys.step_control,STEP_CONTROL_END_MOTION); + #ifdef PARKING_ENABLE + if (!(prep.recalculate_flag & PREP_FLAG_PARKING)) { prep.recalculate_flag |= PREP_FLAG_HOLD_PARTIAL_BLOCK; } + #endif + return; // Segment not generated, but current step data still retained. + } + } + + // Compute segment step rate. Since steps are integers and mm distances traveled are not, + // the end of every segment can have a partial step of varying magnitudes that are not + // executed, because the stepper ISR requires whole steps due to the AMASS algorithm. To + // compensate, we track the time to execute the previous segment's partial step and simply + // apply it with the partial step distance to the current segment, so that it minutely + // adjusts the whole segment rate to keep step output exact. These rate adjustments are + // typically very small and do not adversely effect performance, but ensures that Grbl + // outputs the exact acceleration and velocity profiles as computed by the planner. + dt += prep.dt_remainder; // Apply previous segment partial step execute time + float inv_rate = dt/(last_n_steps_remaining - step_dist_remaining); // Compute adjusted step rate inverse + + // Compute CPU cycles per step for the prepped segment. + uint32_t cycles = ceil( (TICKS_PER_MICROSECOND*1000000*60)*inv_rate ); // (cycles/step) + + #ifdef ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING + // Compute step timing and multi-axis smoothing level. + // NOTE: AMASS overdrives the timer with each level, so only one prescalar is required. + if (cycles < AMASS_LEVEL1) { prep_segment->amass_level = 0; } + else { + if (cycles < AMASS_LEVEL2) { prep_segment->amass_level = 1; } + else if (cycles < AMASS_LEVEL3) { prep_segment->amass_level = 2; } + else { prep_segment->amass_level = 3; } + cycles >>= prep_segment->amass_level; + prep_segment->n_step <<= prep_segment->amass_level; + } + if (cycles < (1UL << 16)) { prep_segment->cycles_per_tick = cycles; } // < 65536 (4.1ms @ 16MHz) + else { prep_segment->cycles_per_tick = 0xffff; } // Just set the slowest speed possible. + #else + // Compute step timing and timer prescalar for normal step generation. + if (cycles < (1UL << 16)) { // < 65536 (4.1ms @ 16MHz) + prep_segment->prescaler = 1; // prescaler: 0 + prep_segment->cycles_per_tick = cycles; + } else if (cycles < (1UL << 19)) { // < 524288 (32.8ms@16MHz) + prep_segment->prescaler = 2; // prescaler: 8 + prep_segment->cycles_per_tick = cycles >> 3; + } else { + prep_segment->prescaler = 3; // prescaler: 64 + if (cycles < (1UL << 22)) { // < 4194304 (262ms@16MHz) + prep_segment->cycles_per_tick = cycles >> 6; + } else { // Just set the slowest speed possible. (Around 4 step/sec.) + prep_segment->cycles_per_tick = 0xffff; + } + } + #endif + + // Segment complete! Increment segment buffer indices, so stepper ISR can immediately execute it. + segment_buffer_head = segment_next_head; + if ( ++segment_next_head == SEGMENT_BUFFER_SIZE ) { segment_next_head = 0; } + + // Update the appropriate planner and segment data. + pl_block->millimeters = mm_remaining; + prep.steps_remaining = n_steps_remaining; + prep.dt_remainder = (n_steps_remaining - step_dist_remaining)*inv_rate; + + // Check for exit conditions and flag to load next planner block. + if (mm_remaining == prep.mm_complete) { + // End of planner block or forced-termination. No more distance to be executed. + if (mm_remaining > 0.0) { // At end of forced-termination. + // Reset prep parameters for resuming and then bail. Allow the stepper ISR to complete + // the segment queue, where realtime protocol will set new state upon receiving the + // cycle stop flag from the ISR. Prep_segment is blocked until then. + bit_true(sys.step_control,STEP_CONTROL_END_MOTION); + #ifdef PARKING_ENABLE + if (!(prep.recalculate_flag & PREP_FLAG_PARKING)) { prep.recalculate_flag |= PREP_FLAG_HOLD_PARTIAL_BLOCK; } + #endif + return; // Bail! + } else { // End of planner block + // The planner block is complete. All steps are set to be executed in the segment buffer. + if (sys.step_control & STEP_CONTROL_EXECUTE_SYS_MOTION) { + bit_true(sys.step_control,STEP_CONTROL_END_MOTION); + return; + } + pl_block = NULL; // Set pointer to indicate check and load next planner block. + plan_discard_current_block(); + } + } + + } +} + + +// Called by realtime status reporting to fetch the current speed being executed. This value +// however is not exactly the current speed, but the speed computed in the last step segment +// in the segment buffer. It will always be behind by up to the number of segment blocks (-1) +// divided by the ACCELERATION TICKS PER SECOND in seconds. +float st_get_realtime_rate() +{ + if (sys.state & (STATE_CYCLE | STATE_HOMING | STATE_HOLD | STATE_JOG | STATE_SAFETY_DOOR)){ + return prep.current_speed; + } + return 0.0f; +} diff --git a/trunk/Arduino/GRBL_1.1f/stepper.h b/trunk/Arduino/GRBL_1.1f/stepper.h new file mode 100644 index 00000000..41871a66 --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f/stepper.h @@ -0,0 +1,59 @@ +/* + stepper.h - stepper motor driver: executes motion plans of planner.c using the stepper motors + Part of Grbl + + Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC + Copyright (c) 2009-2011 Simen Svale Skogsrud + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +#ifndef stepper_h +#define stepper_h + +#ifndef SEGMENT_BUFFER_SIZE + #define SEGMENT_BUFFER_SIZE 6 +#endif + +// Initialize and setup the stepper motor subsystem +void stepper_init(); + +// Enable steppers, but cycle does not start unless called by motion control or realtime command. +void st_wake_up(); + +// Immediately disables steppers +void st_go_idle(); + +// Generate the step and direction port invert masks. +void st_generate_step_dir_invert_masks(); + +// Reset the stepper subsystem variables +void st_reset(); + +// Changes the run state of the step segment buffer to execute the special parking motion. +void st_parking_setup_buffer(); + +// Restores the step segment buffer to the normal run state after a parking motion. +void st_parking_restore_buffer(); + +// Reloads step segment buffer. Called continuously by realtime execution system. +void st_prep_buffer(); + +// Called by planner_recalculate() when the executing block is updated by the new plan. +void st_update_plan_block_parameters(); + +// Called by realtime status reporting if realtime rate reporting is enabled in config.h. +float st_get_realtime_rate(); + +#endif diff --git a/trunk/Arduino/GRBL_1.1f/system.c b/trunk/Arduino/GRBL_1.1f/system.c new file mode 100644 index 00000000..d1665fff --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f/system.c @@ -0,0 +1,407 @@ +/* + system.c - Handles system level commands and real-time processes + Part of Grbl + + Copyright (c) 2014-2016 Sungeun K. Jeon for Gnea Research LLC + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +#include "grbl.h" + + +void system_init() +{ + CONTROL_DDR &= ~(CONTROL_MASK); // Configure as input pins + #ifdef DISABLE_CONTROL_PIN_PULL_UP + CONTROL_PORT &= ~(CONTROL_MASK); // Normal low operation. Requires external pull-down. + #else + CONTROL_PORT |= CONTROL_MASK; // Enable internal pull-up resistors. Normal high operation. + #endif + CONTROL_PCMSK |= CONTROL_MASK; // Enable specific pins of the Pin Change Interrupt + PCICR |= (1 << CONTROL_INT); // Enable Pin Change Interrupt +} + + +// Returns control pin state as a uint8 bitfield. Each bit indicates the input pin state, where +// triggered is 1 and not triggered is 0. Invert mask is applied. Bitfield organization is +// defined by the CONTROL_PIN_INDEX in the header file. +uint8_t system_control_get_state() +{ + uint8_t control_state = 0; + uint8_t pin = (CONTROL_PIN & CONTROL_MASK); + #ifdef INVERT_CONTROL_PIN_MASK + pin ^= INVERT_CONTROL_PIN_MASK; + #endif + if (pin) { + #ifdef ENABLE_SAFETY_DOOR_INPUT_PIN + if (bit_isfalse(pin,(1< 255)) { return(STATUS_INVALID_STATEMENT); } + return(settings_store_global_setting((uint8_t)parameter, value)); + } + } + } + return(STATUS_OK); // If '$' command makes it to here, then everything's ok. +} + + + +void system_flag_wco_change() +{ + #ifdef FORCE_BUFFER_SYNC_DURING_WCO_CHANGE + protocol_buffer_synchronize(); + #endif + sys.report_wco_counter = 0; +} + + +// Returns machine position of axis 'idx'. Must be sent a 'step' array. +// NOTE: If motor steps and machine position are not in the same coordinate frame, this function +// serves as a central place to compute the transformation. +float system_convert_axis_steps_to_mpos(int32_t *steps, uint8_t idx) +{ + float pos; + #ifdef COREXY + if (idx==X_AXIS) { + pos = (float)system_convert_corexy_to_x_axis_steps(steps) / settings.steps_per_mm[idx]; + } else if (idx==Y_AXIS) { + pos = (float)system_convert_corexy_to_y_axis_steps(steps) / settings.steps_per_mm[idx]; + } else { + pos = steps[idx]/settings.steps_per_mm[idx]; + } + #else + pos = steps[idx]/settings.steps_per_mm[idx]; + #endif + return(pos); +} + + +void system_convert_array_steps_to_mpos(float *position, int32_t *steps) +{ + uint8_t idx; + for (idx=0; idx -settings.max_travel[idx]) { return(true); } + } else { + if (target[idx] > 0 || target[idx] < settings.max_travel[idx]) { return(true); } + } + #else + // NOTE: max_travel is stored as negative + if (target[idx] > 0 || target[idx] < settings.max_travel[idx]) { return(true); } + #endif + } + return(false); +} + + +// Special handlers for setting and clearing Grbl's real-time execution flags. +void system_set_exec_state_flag(uint8_t mask) { + uint8_t sreg = SREG; + cli(); + sys_rt_exec_state |= (mask); + SREG = sreg; +} + +void system_clear_exec_state_flag(uint8_t mask) { + uint8_t sreg = SREG; + cli(); + sys_rt_exec_state &= ~(mask); + SREG = sreg; +} + +void system_set_exec_alarm(uint8_t code) { + uint8_t sreg = SREG; + cli(); + sys_rt_exec_alarm = code; + SREG = sreg; +} + +void system_clear_exec_alarm() { + uint8_t sreg = SREG; + cli(); + sys_rt_exec_alarm = 0; + SREG = sreg; +} + +void system_set_exec_motion_override_flag(uint8_t mask) { + uint8_t sreg = SREG; + cli(); + sys_rt_exec_motion_override |= (mask); + SREG = sreg; +} + +void system_set_exec_accessory_override_flag(uint8_t mask) { + uint8_t sreg = SREG; + cli(); + sys_rt_exec_accessory_override |= (mask); + SREG = sreg; +} + +void system_clear_exec_motion_overrides() { + uint8_t sreg = SREG; + cli(); + sys_rt_exec_motion_override = 0; + SREG = sreg; +} + +void system_clear_exec_accessory_overrides() { + uint8_t sreg = SREG; + cli(); + sys_rt_exec_accessory_override = 0; + SREG = sreg; +} diff --git a/trunk/Arduino/GRBL_1.1f/system.h b/trunk/Arduino/GRBL_1.1f/system.h new file mode 100644 index 00000000..4d4f6128 --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f/system.h @@ -0,0 +1,208 @@ +/* + system.h - Header for system level commands and real-time processes + Part of Grbl + + Copyright (c) 2014-2016 Sungeun K. Jeon for Gnea Research LLC + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +#ifndef system_h +#define system_h + +#include "grbl.h" + +// Define system executor bit map. Used internally by realtime protocol as realtime command flags, +// which notifies the main program to execute the specified realtime command asynchronously. +// NOTE: The system executor uses an unsigned 8-bit volatile variable (8 flag limit.) The default +// flags are always false, so the realtime protocol only needs to check for a non-zero value to +// know when there is a realtime command to execute. +#define EXEC_STATUS_REPORT bit(0) // bitmask 00000001 +#define EXEC_CYCLE_START bit(1) // bitmask 00000010 +#define EXEC_CYCLE_STOP bit(2) // bitmask 00000100 +#define EXEC_FEED_HOLD bit(3) // bitmask 00001000 +#define EXEC_RESET bit(4) // bitmask 00010000 +#define EXEC_SAFETY_DOOR bit(5) // bitmask 00100000 +#define EXEC_MOTION_CANCEL bit(6) // bitmask 01000000 +#define EXEC_SLEEP bit(7) // bitmask 10000000 + +// Alarm executor codes. Valid values (1-255). Zero is reserved. +#define EXEC_ALARM_HARD_LIMIT 1 +#define EXEC_ALARM_SOFT_LIMIT 2 +#define EXEC_ALARM_ABORT_CYCLE 3 +#define EXEC_ALARM_PROBE_FAIL_INITIAL 4 +#define EXEC_ALARM_PROBE_FAIL_CONTACT 5 +#define EXEC_ALARM_HOMING_FAIL_RESET 6 +#define EXEC_ALARM_HOMING_FAIL_DOOR 7 +#define EXEC_ALARM_HOMING_FAIL_PULLOFF 8 +#define EXEC_ALARM_HOMING_FAIL_APPROACH 9 + +// Override bit maps. Realtime bitflags to control feed, rapid, spindle, and coolant overrides. +// Spindle/coolant and feed/rapids are separated into two controlling flag variables. +#define EXEC_FEED_OVR_RESET bit(0) +#define EXEC_FEED_OVR_COARSE_PLUS bit(1) +#define EXEC_FEED_OVR_COARSE_MINUS bit(2) +#define EXEC_FEED_OVR_FINE_PLUS bit(3) +#define EXEC_FEED_OVR_FINE_MINUS bit(4) +#define EXEC_RAPID_OVR_RESET bit(5) +#define EXEC_RAPID_OVR_MEDIUM bit(6) +#define EXEC_RAPID_OVR_LOW bit(7) +// #define EXEC_RAPID_OVR_EXTRA_LOW bit(*) // *NOT SUPPORTED* + +#define EXEC_SPINDLE_OVR_RESET bit(0) +#define EXEC_SPINDLE_OVR_COARSE_PLUS bit(1) +#define EXEC_SPINDLE_OVR_COARSE_MINUS bit(2) +#define EXEC_SPINDLE_OVR_FINE_PLUS bit(3) +#define EXEC_SPINDLE_OVR_FINE_MINUS bit(4) +#define EXEC_SPINDLE_OVR_STOP bit(5) +#define EXEC_COOLANT_FLOOD_OVR_TOGGLE bit(6) +#define EXEC_COOLANT_MIST_OVR_TOGGLE bit(7) + +// Define system state bit map. The state variable primarily tracks the individual functions +// of Grbl to manage each without overlapping. It is also used as a messaging flag for +// critical events. +#define STATE_IDLE 0 // Must be zero. No flags. +#define STATE_ALARM bit(0) // In alarm state. Locks out all g-code processes. Allows settings access. +#define STATE_CHECK_MODE bit(1) // G-code check mode. Locks out planner and motion only. +#define STATE_HOMING bit(2) // Performing homing cycle +#define STATE_CYCLE bit(3) // Cycle is running or motions are being executed. +#define STATE_HOLD bit(4) // Active feed hold +#define STATE_JOG bit(5) // Jogging mode. +#define STATE_SAFETY_DOOR bit(6) // Safety door is ajar. Feed holds and de-energizes system. +#define STATE_SLEEP bit(7) // Sleep state. + +// Define system suspend flags. Used in various ways to manage suspend states and procedures. +#define SUSPEND_DISABLE 0 // Must be zero. +#define SUSPEND_HOLD_COMPLETE bit(0) // Indicates initial feed hold is complete. +#define SUSPEND_RESTART_RETRACT bit(1) // Flag to indicate a retract from a restore parking motion. +#define SUSPEND_RETRACT_COMPLETE bit(2) // (Safety door only) Indicates retraction and de-energizing is complete. +#define SUSPEND_INITIATE_RESTORE bit(3) // (Safety door only) Flag to initiate resume procedures from a cycle start. +#define SUSPEND_RESTORE_COMPLETE bit(4) // (Safety door only) Indicates ready to resume normal operation. +#define SUSPEND_SAFETY_DOOR_AJAR bit(5) // Tracks safety door state for resuming. +#define SUSPEND_MOTION_CANCEL bit(6) // Indicates a canceled resume motion. Currently used by probing routine. +#define SUSPEND_JOG_CANCEL bit(7) // Indicates a jog cancel in process and to reset buffers when complete. + +// Define step segment generator state flags. +#define STEP_CONTROL_NORMAL_OP 0 // Must be zero. +#define STEP_CONTROL_END_MOTION bit(0) +#define STEP_CONTROL_EXECUTE_HOLD bit(1) +#define STEP_CONTROL_EXECUTE_SYS_MOTION bit(2) +#define STEP_CONTROL_UPDATE_SPINDLE_PWM bit(3) + +// Define control pin index for Grbl internal use. Pin maps may change, but these values don't. +#ifdef ENABLE_SAFETY_DOOR_INPUT_PIN + #define N_CONTROL_PIN 4 + #define CONTROL_PIN_INDEX_SAFETY_DOOR bit(0) + #define CONTROL_PIN_INDEX_RESET bit(1) + #define CONTROL_PIN_INDEX_FEED_HOLD bit(2) + #define CONTROL_PIN_INDEX_CYCLE_START bit(3) +#else + #define N_CONTROL_PIN 3 + #define CONTROL_PIN_INDEX_RESET bit(0) + #define CONTROL_PIN_INDEX_FEED_HOLD bit(1) + #define CONTROL_PIN_INDEX_CYCLE_START bit(2) +#endif + +// Define spindle stop override control states. +#define SPINDLE_STOP_OVR_DISABLED 0 // Must be zero. +#define SPINDLE_STOP_OVR_ENABLED bit(0) +#define SPINDLE_STOP_OVR_INITIATE bit(1) +#define SPINDLE_STOP_OVR_RESTORE bit(2) +#define SPINDLE_STOP_OVR_RESTORE_CYCLE bit(3) + + +// Define global system variables +typedef struct { + uint8_t state; // Tracks the current system state of Grbl. + uint8_t abort; // System abort flag. Forces exit back to main loop for reset. + uint8_t suspend; // System suspend bitflag variable that manages holds, cancels, and safety door. + uint8_t soft_limit; // Tracks soft limit errors for the state machine. (boolean) + uint8_t step_control; // Governs the step segment generator depending on system state. + uint8_t probe_succeeded; // Tracks if last probing cycle was successful. + uint8_t homing_axis_lock; // Locks axes when limits engage. Used as an axis motion mask in the stepper ISR. + uint8_t f_override; // Feed rate override value in percent + uint8_t r_override; // Rapids override value in percent + uint8_t spindle_speed_ovr; // Spindle speed value in percent + uint8_t spindle_stop_ovr; // Tracks spindle stop override states + uint8_t report_ovr_counter; // Tracks when to add override data to status reports. + uint8_t report_wco_counter; // Tracks when to add work coordinate offset data to status reports. + #ifdef ENABLE_PARKING_OVERRIDE_CONTROL + uint8_t override_ctrl; // Tracks override control states. + #endif + #ifdef VARIABLE_SPINDLE + float spindle_speed; + #endif +} system_t; +extern system_t sys; + +// NOTE: These position variables may need to be declared as volatiles, if problems arise. +extern int32_t sys_position[N_AXIS]; // Real-time machine (aka home) position vector in steps. +extern int32_t sys_probe_position[N_AXIS]; // Last probe position in machine coordinates and steps. + +extern volatile uint8_t sys_probe_state; // Probing state value. Used to coordinate the probing cycle with stepper ISR. +extern volatile uint8_t sys_rt_exec_state; // Global realtime executor bitflag variable for state management. See EXEC bitmasks. +extern volatile uint8_t sys_rt_exec_alarm; // Global realtime executor bitflag variable for setting various alarms. +extern volatile uint8_t sys_rt_exec_motion_override; // Global realtime executor bitflag variable for motion-based overrides. +extern volatile uint8_t sys_rt_exec_accessory_override; // Global realtime executor bitflag variable for spindle/coolant overrides. + +#ifdef DEBUG + #define EXEC_DEBUG_REPORT bit(0) + extern volatile uint8_t sys_rt_exec_debug; +#endif + +// Initialize the serial protocol +void system_init(); + +// Returns bitfield of control pin states, organized by CONTROL_PIN_INDEX. (1=triggered, 0=not triggered). +uint8_t system_control_get_state(); + +// Returns if safety door is open or closed, based on pin state. +uint8_t system_check_safety_door_ajar(); + +// Executes an internal system command, defined as a string starting with a '$' +uint8_t system_execute_line(char *line); + +// Execute the startup script lines stored in EEPROM upon initialization +void system_execute_startup(char *line); + + +void system_flag_wco_change(); + +// Returns machine position of axis 'idx'. Must be sent a 'step' array. +float system_convert_axis_steps_to_mpos(int32_t *steps, uint8_t idx); + +// Updates a machine 'position' array based on the 'step' array sent. +void system_convert_array_steps_to_mpos(float *position, int32_t *steps); + +// CoreXY calculation only. Returns x or y-axis "steps" based on CoreXY motor steps. +#ifdef COREXY + int32_t system_convert_corexy_to_x_axis_steps(int32_t *steps); + int32_t system_convert_corexy_to_y_axis_steps(int32_t *steps); +#endif + +// Checks and reports if target array exceeds machine travel limits. +uint8_t system_check_travel_limits(float *target); + +// Special handlers for setting and clearing Grbl's real-time execution flags. +void system_set_exec_state_flag(uint8_t mask); +void system_clear_exec_state_flag(uint8_t mask); +void system_set_exec_alarm(uint8_t code); +void system_clear_exec_alarm(); +void system_set_exec_motion_override_flag(uint8_t mask); +void system_set_exec_accessory_override_flag(uint8_t mask); +void system_clear_exec_motion_overrides(); +void system_clear_exec_accessory_overrides(); + + +#endif diff --git a/trunk/Arduino/GRBL_1.1f_Nano/GRBL_1.1f_Nano.ino b/trunk/Arduino/GRBL_1.1f_Nano/GRBL_1.1f_Nano.ino new file mode 100644 index 00000000..4789c0db --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f_Nano/GRBL_1.1f_Nano.ino @@ -0,0 +1,29 @@ +/*********************************************************************** +This sketch compiles and uploads Grbl to your 328p-based Arduino! + +To use: +- First make sure you have imported Grbl source code into your Arduino + IDE. There are details on our Github website on how to do this. + +- Select your Arduino Board and Serial Port in the Tools drop-down menu. + NOTE: Grbl only officially supports 328p-based Arduinos, like the Uno. + Using other boards will likely not work! + +- Then just click 'Upload'. That's it! + +For advanced users: + If you'd like to see what else Grbl can do, there are some additional + options for customization and features you can enable or disable. + Navigate your file system to where the Arduino IDE has stored the Grbl + source code files, open the 'config.h' file in your favorite text + editor. Inside are dozens of feature descriptions and #defines. Simply + comment or uncomment the #defines or alter their assigned values, save + your changes, and then click 'Upload' here. + +Copyright (c) 2015 Sungeun K. Jeon +Released under the MIT-license. See license.txt for details. +***********************************************************************/ + +#include "grbl.h" + +// Do not alter this file! diff --git a/trunk/Arduino/GRBL_1.1f_Nano/config.h b/trunk/Arduino/GRBL_1.1f_Nano/config.h new file mode 100644 index 00000000..4d36b54e --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f_Nano/config.h @@ -0,0 +1,628 @@ +/* + config.h - compile time configuration + Part of Grbl + + Copyright (c) 2012-2016 Sungeun K. Jeon for Gnea Research LLC + Copyright (c) 2009-2011 Simen Svale Skogsrud + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +// This file contains compile-time configurations for Grbl's internal system. For the most part, +// users will not need to directly modify these, but they are here for specific needs, i.e. +// performance tuning or adjusting to non-typical machines. + +// IMPORTANT: Any changes here requires a full re-compiling of the source code to propagate them. + +#ifndef config_h +#define config_h +#include "grbl.h" // For Arduino IDE compatibility. + + +// Define CPU pin map and default settings. +// NOTE: OEMs can avoid the need to maintain/update the defaults.h and cpu_map.h files and use only +// one configuration file by placing their specific defaults and pin map at the bottom of this file. +// If doing so, simply comment out these two defines and see instructions below. +#define DEFAULTS_GENERIC +#define CPU_MAP_ATMEGA328P // Arduino Uno CPU + +// Serial baud rate +// #define BAUD_RATE 230400 +#define BAUD_RATE 115200 + +// Define realtime command special characters. These characters are 'picked-off' directly from the +// serial read data stream and are not passed to the grbl line execution parser. Select characters +// that do not and must not exist in the streamed g-code program. ASCII control characters may be +// used, if they are available per user setup. Also, extended ASCII codes (>127), which are never in +// g-code programs, maybe selected for interface programs. +// NOTE: If changed, manually update help message in report.c. + +#define CMD_RESET 0x18 // ctrl-x. +#define CMD_STATUS_REPORT '?' +#define CMD_CYCLE_START '~' +#define CMD_FEED_HOLD '!' + +// NOTE: All override realtime commands must be in the extended ASCII character set, starting +// at character value 128 (0x80) and up to 255 (0xFF). If the normal set of realtime commands, +// such as status reports, feed hold, reset, and cycle start, are moved to the extended set +// space, serial.c's RX ISR will need to be modified to accomodate the change. +// #define CMD_RESET 0x80 +// #define CMD_STATUS_REPORT 0x81 +// #define CMD_CYCLE_START 0x82 +// #define CMD_FEED_HOLD 0x83 +#define CMD_SAFETY_DOOR 0x84 +#define CMD_JOG_CANCEL 0x85 +#define CMD_DEBUG_REPORT 0x86 // Only when DEBUG enabled, sends debug report in '{}' braces. +#define CMD_FEED_OVR_RESET 0x90 // Restores feed override value to 100%. +#define CMD_FEED_OVR_COARSE_PLUS 0x91 +#define CMD_FEED_OVR_COARSE_MINUS 0x92 +#define CMD_FEED_OVR_FINE_PLUS 0x93 +#define CMD_FEED_OVR_FINE_MINUS 0x94 +#define CMD_RAPID_OVR_RESET 0x95 // Restores rapid override value to 100%. +#define CMD_RAPID_OVR_MEDIUM 0x96 +#define CMD_RAPID_OVR_LOW 0x97 +// #define CMD_RAPID_OVR_EXTRA_LOW 0x98 // *NOT SUPPORTED* +#define CMD_SPINDLE_OVR_RESET 0x99 // Restores spindle override value to 100%. +#define CMD_SPINDLE_OVR_COARSE_PLUS 0x9A +#define CMD_SPINDLE_OVR_COARSE_MINUS 0x9B +#define CMD_SPINDLE_OVR_FINE_PLUS 0x9C +#define CMD_SPINDLE_OVR_FINE_MINUS 0x9D +#define CMD_SPINDLE_OVR_STOP 0x9E +#define CMD_COOLANT_FLOOD_OVR_TOGGLE 0xA0 +#define CMD_COOLANT_MIST_OVR_TOGGLE 0xA1 + +// If homing is enabled, homing init lock sets Grbl into an alarm state upon power up. This forces +// the user to perform the homing cycle (or override the locks) before doing anything else. This is +// mainly a safety feature to remind the user to home, since position is unknown to Grbl. +#define HOMING_INIT_LOCK // Comment to disable + +// Define the homing cycle patterns with bitmasks. The homing cycle first performs a search mode +// to quickly engage the limit switches, followed by a slower locate mode, and finished by a short +// pull-off motion to disengage the limit switches. The following HOMING_CYCLE_x defines are executed +// in order starting with suffix 0 and completes the homing routine for the specified-axes only. If +// an axis is omitted from the defines, it will not home, nor will the system update its position. +// Meaning that this allows for users with non-standard cartesian machines, such as a lathe (x then z, +// with no y), to configure the homing cycle behavior to their needs. +// NOTE: The homing cycle is designed to allow sharing of limit pins, if the axes are not in the same +// cycle, but this requires some pin settings changes in cpu_map.h file. For example, the default homing +// cycle can share the Z limit pin with either X or Y limit pins, since they are on different cycles. +// By sharing a pin, this frees up a precious IO pin for other purposes. In theory, all axes limit pins +// may be reduced to one pin, if all axes are homed with seperate cycles, or vice versa, all three axes +// on separate pin, but homed in one cycle. Also, it should be noted that the function of hard limits +// will not be affected by pin sharing. +// NOTE: Defaults are set for a traditional 3-axis CNC machine. Z-axis first to clear, followed by X & Y. +#define HOMING_CYCLE_0 (1< 3us, and, when added with the +// user-supplied step pulse time, the total time must not exceed 127us. Reported successful +// values for certain setups have ranged from 5 to 20us. +// #define STEP_PULSE_DELAY 10 // Step pulse delay in microseconds. Default disabled. + +// The number of linear motions in the planner buffer to be planned at any give time. The vast +// majority of RAM that Grbl uses is based on this buffer size. Only increase if there is extra +// available RAM, like when re-compiling for a Mega2560. Or decrease if the Arduino begins to +// crash due to the lack of available RAM or if the CPU is having trouble keeping up with planning +// new incoming motions as they are executed. +// #define BLOCK_BUFFER_SIZE 16 // Uncomment to override default in planner.h. + +// Governs the size of the intermediary step segment buffer between the step execution algorithm +// and the planner blocks. Each segment is set of steps executed at a constant velocity over a +// fixed time defined by ACCELERATION_TICKS_PER_SECOND. They are computed such that the planner +// block velocity profile is traced exactly. The size of this buffer governs how much step +// execution lead time there is for other Grbl processes have to compute and do their thing +// before having to come back and refill this buffer, currently at ~50msec of step moves. +// #define SEGMENT_BUFFER_SIZE 6 // Uncomment to override default in stepper.h. + +// Line buffer size from the serial input stream to be executed. Also, governs the size of +// each of the startup blocks, as they are each stored as a string of this size. Make sure +// to account for the available EEPROM at the defined memory address in settings.h and for +// the number of desired startup blocks. +// NOTE: 80 characters is not a problem except for extreme cases, but the line buffer size +// can be too small and g-code blocks can get truncated. Officially, the g-code standards +// support up to 256 characters. In future versions, this default will be increased, when +// we know how much extra memory space we can re-invest into this. +// #define LINE_BUFFER_SIZE 80 // Uncomment to override default in protocol.h + +// Serial send and receive buffer size. The receive buffer is often used as another streaming +// buffer to store incoming blocks to be processed by Grbl when its ready. Most streaming +// interfaces will character count and track each block send to each block response. So, +// increase the receive buffer if a deeper receive buffer is needed for streaming and avaiable +// memory allows. The send buffer primarily handles messages in Grbl. Only increase if large +// messages are sent and Grbl begins to stall, waiting to send the rest of the message. +// NOTE: Grbl generates an average status report in about 0.5msec, but the serial TX stream at +// 115200 baud will take 5 msec to transmit a typical 55 character report. Worst case reports are +// around 90-100 characters. As long as the serial TX buffer doesn't get continually maxed, Grbl +// will continue operating efficiently. Size the TX buffer around the size of a worst-case report. +// #define RX_BUFFER_SIZE 128 // (1-254) Uncomment to override defaults in serial.h +// #define TX_BUFFER_SIZE 100 // (1-254) + +// A simple software debouncing feature for hard limit switches. When enabled, the interrupt +// monitoring the hard limit switch pins will enable the Arduino's watchdog timer to re-check +// the limit pin state after a delay of about 32msec. This can help with CNC machines with +// problematic false triggering of their hard limit switches, but it WILL NOT fix issues with +// electrical interference on the signal cables from external sources. It's recommended to first +// use shielded signal cables with their shielding connected to ground (old USB/computer cables +// work well and are cheap to find) and wire in a low-pass circuit into each limit pin. +// #define ENABLE_SOFTWARE_DEBOUNCE // Default disabled. Uncomment to enable. + +// Configures the position after a probing cycle during Grbl's check mode. Disabled sets +// the position to the probe target, when enabled sets the position to the start position. +// #define SET_CHECK_MODE_PROBE_TO_START // Default disabled. Uncomment to enable. + +// Force Grbl to check the state of the hard limit switches when the processor detects a pin +// change inside the hard limit ISR routine. By default, Grbl will trigger the hard limits +// alarm upon any pin change, since bouncing switches can cause a state check like this to +// misread the pin. When hard limits are triggered, they should be 100% reliable, which is the +// reason that this option is disabled by default. Only if your system/electronics can guarantee +// that the switches don't bounce, we recommend enabling this option. This will help prevent +// triggering a hard limit when the machine disengages from the switch. +// NOTE: This option has no effect if SOFTWARE_DEBOUNCE is enabled. +// #define HARD_LIMIT_FORCE_STATE_CHECK // Default disabled. Uncomment to enable. + +// Adjusts homing cycle search and locate scalars. These are the multipliers used by Grbl's +// homing cycle to ensure the limit switches are engaged and cleared through each phase of +// the cycle. The search phase uses the axes max-travel setting times the SEARCH_SCALAR to +// determine distance to look for the limit switch. Once found, the locate phase begins and +// uses the homing pull-off distance setting times the LOCATE_SCALAR to pull-off and re-engage +// the limit switch. +// NOTE: Both of these values must be greater than 1.0 to ensure proper function. +// #define HOMING_AXIS_SEARCH_SCALAR 1.5 // Uncomment to override defaults in limits.c. +// #define HOMING_AXIS_LOCATE_SCALAR 10.0 // Uncomment to override defaults in limits.c. + +// Enable the '$RST=*', '$RST=$', and '$RST=#' eeprom restore commands. There are cases where +// these commands may be undesirable. Simply comment the desired macro to disable it. +// NOTE: See SETTINGS_RESTORE_ALL macro for customizing the `$RST=*` command. +#define ENABLE_RESTORE_EEPROM_WIPE_ALL // '$RST=*' Default enabled. Comment to disable. +#define ENABLE_RESTORE_EEPROM_DEFAULT_SETTINGS // '$RST=$' Default enabled. Comment to disable. +#define ENABLE_RESTORE_EEPROM_CLEAR_PARAMETERS // '$RST=#' Default enabled. Comment to disable. + +// Defines the EEPROM data restored upon a settings version change and `$RST=*` command. Whenever the +// the settings or other EEPROM data structure changes between Grbl versions, Grbl will automatically +// wipe and restore the EEPROM. This macro controls what data is wiped and restored. This is useful +// particularily for OEMs that need to retain certain data. For example, the BUILD_INFO string can be +// written into the Arduino EEPROM via a seperate .INO sketch to contain product data. Altering this +// macro to not restore the build info EEPROM will ensure this data is retained after firmware upgrades. +// NOTE: Uncomment to override defaults in settings.h +// #define SETTINGS_RESTORE_ALL (SETTINGS_RESTORE_DEFAULTS | SETTINGS_RESTORE_PARAMETERS | SETTINGS_RESTORE_STARTUP_LINES | SETTINGS_RESTORE_BUILD_INFO) + +// Enable the '$I=(string)' build info write command. If disabled, any existing build info data must +// be placed into EEPROM via external means with a valid checksum value. This macro option is useful +// to prevent this data from being over-written by a user, when used to store OEM product data. +// NOTE: If disabled and to ensure Grbl can never alter the build info line, you'll also need to enable +// the SETTING_RESTORE_ALL macro above and remove SETTINGS_RESTORE_BUILD_INFO from the mask. +// NOTE: See the included grblWrite_BuildInfo.ino example file to write this string seperately. +#define ENABLE_BUILD_INFO_WRITE_COMMAND // '$I=' Default enabled. Comment to disable. + +// AVR processors require all interrupts to be disabled during an EEPROM write. This includes both +// the stepper ISRs and serial comm ISRs. In the event of a long EEPROM write, this ISR pause can +// cause active stepping to lose position and serial receive data to be lost. This configuration +// option forces the planner buffer to completely empty whenever the EEPROM is written to prevent +// any chance of lost steps. +// However, this doesn't prevent issues with lost serial RX data during an EEPROM write, especially +// if a GUI is premptively filling up the serial RX buffer simultaneously. It's highly advised for +// GUIs to flag these gcodes (G10,G28.1,G30.1) to always wait for an 'ok' after a block containing +// one of these commands before sending more data to eliminate this issue. +// NOTE: Most EEPROM write commands are implicitly blocked during a job (all '$' commands). However, +// coordinate set g-code commands (G10,G28/30.1) are not, since they are part of an active streaming +// job. At this time, this option only forces a planner buffer sync with these g-code commands. +#define FORCE_BUFFER_SYNC_DURING_EEPROM_WRITE // Default enabled. Comment to disable. + +// In Grbl v0.9 and prior, there is an old outstanding bug where the `WPos:` work position reported +// may not correlate to what is executing, because `WPos:` is based on the g-code parser state, which +// can be several motions behind. This option forces the planner buffer to empty, sync, and stop +// motion whenever there is a command that alters the work coordinate offsets `G10,G43.1,G92,G54-59`. +// This is the simplest way to ensure `WPos:` is always correct. Fortunately, it's exceedingly rare +// that any of these commands are used need continuous motions through them. +#define FORCE_BUFFER_SYNC_DURING_WCO_CHANGE // Default enabled. Comment to disable. + +// By default, Grbl disables feed rate overrides for all G38.x probe cycle commands. Although this +// may be different than some pro-class machine control, it's arguable that it should be this way. +// Most probe sensors produce different levels of error that is dependent on rate of speed. By +// keeping probing cycles to their programmed feed rates, the probe sensor should be a lot more +// repeatable. If needed, you can disable this behavior by uncommenting the define below. +// #define ALLOW_FEED_OVERRIDE_DURING_PROBE_CYCLES // Default disabled. Uncomment to enable. + +// Enables and configures parking motion methods upon a safety door state. Primarily for OEMs +// that desire this feature for their integrated machines. At the moment, Grbl assumes that +// the parking motion only involves one axis, although the parking implementation was written +// to be easily refactored for any number of motions on different axes by altering the parking +// source code. At this time, Grbl only supports parking one axis (typically the Z-axis) that +// moves in the positive direction upon retracting and negative direction upon restoring position. +// The motion executes with a slow pull-out retraction motion, power-down, and a fast park. +// Restoring to the resume position follows these set motions in reverse: fast restore to +// pull-out position, power-up with a time-out, and plunge back to the original position at the +// slower pull-out rate. +// NOTE: Still a work-in-progress. Machine coordinates must be in all negative space and +// does not work with HOMING_FORCE_SET_ORIGIN enabled. Parking motion also moves only in +// positive direction. +// #define PARKING_ENABLE // Default disabled. Uncomment to enable + +// Configure options for the parking motion, if enabled. +#define PARKING_AXIS Z_AXIS // Define which axis that performs the parking motion +#define PARKING_TARGET -5.0 // Parking axis target. In mm, as machine coordinate [-max_travel,0]. +#define PARKING_RATE 500.0 // Parking fast rate after pull-out in mm/min. +#define PARKING_PULLOUT_RATE 100.0 // Pull-out/plunge slow feed rate in mm/min. +#define PARKING_PULLOUT_INCREMENT 5.0 // Spindle pull-out and plunge distance in mm. Incremental distance. + // Must be positive value or equal to zero. + +// Enables a special set of M-code commands that enables and disables the parking motion. +// These are controlled by `M56`, `M56 P1`, or `M56 Px` to enable and `M56 P0` to disable. +// The command is modal and will be set after a planner sync. Since it is g-code, it is +// executed in sync with g-code commands. It is not a real-time command. +// NOTE: PARKING_ENABLE is required. By default, M56 is active upon initialization. Use +// DEACTIVATE_PARKING_UPON_INIT to set M56 P0 as the power-up default. +// #define ENABLE_PARKING_OVERRIDE_CONTROL // Default disabled. Uncomment to enable +// #define DEACTIVATE_PARKING_UPON_INIT // Default disabled. Uncomment to enable. + +// This option will automatically disable the laser during a feed hold by invoking a spindle stop +// override immediately after coming to a stop. However, this also means that the laser still may +// be reenabled by disabling the spindle stop override, if needed. This is purely a safety feature +// to ensure the laser doesn't inadvertently remain powered while at a stop and cause a fire. +#define DISABLE_LASER_DURING_HOLD // Default enabled. Comment to disable. + +// Enables a piecewise linear model of the spindle PWM/speed output. Requires a solution by the +// 'fit_nonlinear_spindle.py' script in the /doc/script folder of the repo. See file comments +// on how to gather spindle data and run the script to generate a solution. +// #define ENABLE_PIECEWISE_LINEAR_SPINDLE // Default disabled. Uncomment to enable. + +// N_PIECES, RPM_MAX, RPM_MIN, RPM_POINTxx, and RPM_LINE_XX constants are all set and given by +// the 'fit_nonlinear_spindle.py' script solution. Used only when ENABLE_PIECEWISE_LINEAR_SPINDLE +// is enabled. Make sure the constant values are exactly the same as the script solution. +// NOTE: When N_PIECES < 4, unused RPM_LINE and RPM_POINT defines are not required and omitted. +#define N_PIECES 4 // Integer (1-4). Number of piecewise lines used in script solution. +#define RPM_MAX 11686.4 // Max RPM of model. $30 > RPM_MAX will be limited to RPM_MAX. +#define RPM_MIN 202.5 // Min RPM of model. $31 < RPM_MIN will be limited to RPM_MIN. +#define RPM_POINT12 6145.4 // Used N_PIECES >=2. Junction point between lines 1 and 2. +#define RPM_POINT23 9627.8 // Used N_PIECES >=3. Junction point between lines 2 and 3. +#define RPM_POINT34 10813.9 // Used N_PIECES = 4. Junction point between lines 3 and 4. +#define RPM_LINE_A1 3.197101e-03 // Used N_PIECES >=1. A and B constants of line 1. +#define RPM_LINE_B1 -3.526076e-1 +#define RPM_LINE_A2 1.722950e-2 // Used N_PIECES >=2. A and B constants of line 2. +#define RPM_LINE_B2 8.588176e+01 +#define RPM_LINE_A3 5.901518e-02 // Used N_PIECES >=3. A and B constants of line 3. +#define RPM_LINE_B3 4.881851e+02 +#define RPM_LINE_A4 1.203413e-01 // Used N_PIECES = 4. A and B constants of line 4. +#define RPM_LINE_B4 1.151360e+03 + + +/* --------------------------------------------------------------------------------------- + OEM Single File Configuration Option + + Instructions: Paste the cpu_map and default setting definitions below without an enclosing + #ifdef. Comment out the CPU_MAP_xxx and DEFAULT_xxx defines at the top of this file, and + the compiler will ignore the contents of defaults.h and cpu_map.h and use the definitions + below. +*/ + +// Paste CPU_MAP definitions here. + +// Paste default settings definitions here. + + +#endif diff --git a/trunk/Arduino/GRBL_1.1f_Nano/coolant_control.c b/trunk/Arduino/GRBL_1.1f_Nano/coolant_control.c new file mode 100644 index 00000000..1eebfc0c --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f_Nano/coolant_control.c @@ -0,0 +1,126 @@ +/* + coolant_control.c - coolant control methods + Part of Grbl + + Copyright (c) 2012-2016 Sungeun K. Jeon for Gnea Research LLC + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +#include "grbl.h" + + +void coolant_init() +{ + COOLANT_FLOOD_DDR |= (1 << COOLANT_FLOOD_BIT); // Configure as output pin + #ifdef ENABLE_M7 + COOLANT_MIST_DDR |= (1 << COOLANT_MIST_BIT); + #endif + coolant_stop(); +} + + +// Returns current coolant output state. Overrides may alter it from programmed state. +uint8_t coolant_get_state() +{ + uint8_t cl_state = COOLANT_STATE_DISABLE; + #ifdef INVERT_COOLANT_FLOOD_PIN + if (bit_isfalse(COOLANT_FLOOD_PORT,(1 << COOLANT_FLOOD_BIT))) { + #else + if (bit_istrue(COOLANT_FLOOD_PORT,(1 << COOLANT_FLOOD_BIT))) { + #endif + cl_state |= COOLANT_STATE_FLOOD; + } + #ifdef ENABLE_M7 + #ifdef INVERT_COOLANT_MIST_PIN + if (bit_isfalse(COOLANT_MIST_PORT,(1 << COOLANT_MIST_BIT))) { + #else + if (bit_istrue(COOLANT_MIST_PORT,(1 << COOLANT_MIST_BIT))) { + #endif + cl_state |= COOLANT_STATE_MIST; + } + #endif + return(cl_state); +} + + +// Directly called by coolant_init(), coolant_set_state(), and mc_reset(), which can be at +// an interrupt-level. No report flag set, but only called by routines that don't need it. +void coolant_stop() +{ + #ifdef INVERT_COOLANT_FLOOD_PIN + COOLANT_FLOOD_PORT |= (1 << COOLANT_FLOOD_BIT); + #else + COOLANT_FLOOD_PORT &= ~(1 << COOLANT_FLOOD_BIT); + #endif + #ifdef ENABLE_M7 + #ifdef INVERT_COOLANT_MIST_PIN + COOLANT_MIST_PORT |= (1 << COOLANT_MIST_BIT); + #else + COOLANT_MIST_PORT &= ~(1 << COOLANT_MIST_BIT); + #endif + #endif +} + + +// Main program only. Immediately sets flood coolant running state and also mist coolant, +// if enabled. Also sets a flag to report an update to a coolant state. +// Called by coolant toggle override, parking restore, parking retract, sleep mode, g-code +// parser program end, and g-code parser coolant_sync(). +void coolant_set_state(uint8_t mode) +{ + if (sys.abort) { return; } // Block during abort. + + if (mode & COOLANT_FLOOD_ENABLE) { + #ifdef INVERT_COOLANT_FLOOD_PIN + COOLANT_FLOOD_PORT &= ~(1 << COOLANT_FLOOD_BIT); + #else + COOLANT_FLOOD_PORT |= (1 << COOLANT_FLOOD_BIT); + #endif + } else { + #ifdef INVERT_COOLANT_FLOOD_PIN + COOLANT_FLOOD_PORT |= (1 << COOLANT_FLOOD_BIT); + #else + COOLANT_FLOOD_PORT &= ~(1 << COOLANT_FLOOD_BIT); + #endif + } + + #ifdef ENABLE_M7 + if (mode & COOLANT_MIST_ENABLE) { + #ifdef INVERT_COOLANT_MIST_PIN + COOLANT_MIST_PORT &= ~(1 << COOLANT_MIST_BIT); + #else + COOLANT_MIST_PORT |= (1 << COOLANT_MIST_BIT); + #endif + } else { + #ifdef INVERT_COOLANT_MIST_PIN + COOLANT_MIST_PORT |= (1 << COOLANT_MIST_BIT); + #else + COOLANT_MIST_PORT &= ~(1 << COOLANT_MIST_BIT); + #endif + } + #endif + + sys.report_ovr_counter = 0; // Set to report change immediately +} + + +// G-code parser entry-point for setting coolant state. Forces a planner buffer sync and bails +// if an abort or check-mode is active. +void coolant_sync(uint8_t mode) +{ + if (sys.state == STATE_CHECK_MODE) { return; } + protocol_buffer_synchronize(); // Ensure coolant turns on when specified in program. + coolant_set_state(mode); +} diff --git a/trunk/Arduino/GRBL_1.1f_Nano/coolant_control.h b/trunk/Arduino/GRBL_1.1f_Nano/coolant_control.h new file mode 100644 index 00000000..49b85f00 --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f_Nano/coolant_control.h @@ -0,0 +1,47 @@ +/* + coolant_control.h - spindle control methods + Part of Grbl + + Copyright (c) 2012-2016 Sungeun K. Jeon for Gnea Research LLC + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +#ifndef coolant_control_h +#define coolant_control_h + +#define COOLANT_NO_SYNC false +#define COOLANT_FORCE_SYNC true + +#define COOLANT_STATE_DISABLE 0 // Must be zero +#define COOLANT_STATE_FLOOD PL_COND_FLAG_COOLANT_FLOOD +#define COOLANT_STATE_MIST PL_COND_FLAG_COOLANT_MIST + + +// Initializes coolant control pins. +void coolant_init(); + +// Returns current coolant output state. Overrides may alter it from programmed state. +uint8_t coolant_get_state(); + +// Immediately disables coolant pins. +void coolant_stop(); + +// Sets the coolant pins according to state specified. +void coolant_set_state(uint8_t mode); + +// G-code parser entry-point for setting coolant states. Checks for and executes additional conditions. +void coolant_sync(uint8_t mode); + +#endif diff --git a/trunk/Arduino/GRBL_1.1f_Nano/cpu_map.h b/trunk/Arduino/GRBL_1.1f_Nano/cpu_map.h new file mode 100644 index 00000000..2ea7bba3 --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f_Nano/cpu_map.h @@ -0,0 +1,160 @@ +/* + cpu_map.h - CPU and pin mapping configuration file + Part of Grbl + + Copyright (c) 2012-2016 Sungeun K. Jeon for Gnea Research LLC + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +/* The cpu_map.h files serve as a central pin mapping selection file for different + processor types or alternative pin layouts. This version of Grbl officially supports + only the Arduino Mega328p. */ + + +#ifndef cpu_map_h +#define cpu_map_h + + +#ifdef CPU_MAP_ATMEGA328P // (Arduino Uno) Officially supported by Grbl. + + // Define serial port pins and interrupt vectors. + #define SERIAL_RX USART_RX_vect + #define SERIAL_UDRE USART_UDRE_vect + + // Define step pulse output pins. NOTE: All step bit pins must be on the same port. + #define STEP_DDR DDRD + #define STEP_PORT PORTD + #define X_STEP_BIT 5 //2 // Uno Digital Pin 2 + #define Y_STEP_BIT 6 //3 // Uno Digital Pin 3 + #define Z_STEP_BIT 7 //4 // Uno Digital Pin 4 + #define STEP_MASK ((1< 62.5kHz + // #define SPINDLE_TCCRB_INIT_MASK (1< 7.8kHz (Used in v0.9) + // #define SPINDLE_TCCRB_INIT_MASK ((1< 1.96kHz + #define SPINDLE_TCCRB_INIT_MASK (1< 0.98kHz (J-tech laser) + + // NOTE: On the 328p, these must be the same as the SPINDLE_ENABLE settings. + #define SPINDLE_PWM_DDR DDRB + #define SPINDLE_PWM_PORT PORTB + #define SPINDLE_PWM_BIT 3 // Uno Digital Pin 11 + +#endif + +/* +#ifdef CPU_MAP_CUSTOM_PROC + // For a custom pin map or different processor, copy and edit one of the available cpu + // map files and modify it to your needs. Make sure the defined name is also changed in + // the config.h file. +#endif +*/ + +#endif diff --git a/trunk/Arduino/GRBL_1.1f_Nano/defaults.h b/trunk/Arduino/GRBL_1.1f_Nano/defaults.h new file mode 100644 index 00000000..dbbbb934 --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f_Nano/defaults.h @@ -0,0 +1,493 @@ +/* + defaults.h - defaults settings configuration file + Part of Grbl + + Copyright (c) 2012-2016 Sungeun K. Jeon for Gnea Research LLC + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +/* The defaults.h file serves as a central default settings selector for different machine + types, from DIY CNC mills to CNC conversions of off-the-shelf machines. The settings + files listed here are supplied by users, so your results may vary. However, this should + give you a good starting point as you get to know your machine and tweak the settings for + your nefarious needs. + NOTE: Ensure one and only one of these DEFAULTS_XXX values is defined in config.h */ + +#ifndef defaults_h + +#ifdef DEFAULTS_GENERIC + // Grbl generic default settings. Should work across different machines. + #define DEFAULT_X_STEPS_PER_MM 250.0 + #define DEFAULT_Y_STEPS_PER_MM 250.0 + #define DEFAULT_Z_STEPS_PER_MM 250.0 + #define DEFAULT_X_MAX_RATE 500.0 // mm/min + #define DEFAULT_Y_MAX_RATE 500.0 // mm/min + #define DEFAULT_Z_MAX_RATE 500.0 // mm/min + #define DEFAULT_X_ACCELERATION (10.0*60*60) // 10*60*60 mm/min^2 = 10 mm/sec^2 + #define DEFAULT_Y_ACCELERATION (10.0*60*60) // 10*60*60 mm/min^2 = 10 mm/sec^2 + #define DEFAULT_Z_ACCELERATION (10.0*60*60) // 10*60*60 mm/min^2 = 10 mm/sec^2 + #define DEFAULT_X_MAX_TRAVEL 200.0 // mm NOTE: Must be a positive value. + #define DEFAULT_Y_MAX_TRAVEL 200.0 // mm NOTE: Must be a positive value. + #define DEFAULT_Z_MAX_TRAVEL 200.0 // mm NOTE: Must be a positive value. + #define DEFAULT_SPINDLE_RPM_MAX 1000.0 // rpm + #define DEFAULT_SPINDLE_RPM_MIN 0.0 // rpm + #define DEFAULT_STEP_PULSE_MICROSECONDS 10 + #define DEFAULT_STEPPING_INVERT_MASK 0 + #define DEFAULT_DIRECTION_INVERT_MASK 0 + #define DEFAULT_STEPPER_IDLE_LOCK_TIME 25 // msec (0-254, 255 keeps steppers enabled) + #define DEFAULT_STATUS_REPORT_MASK 1 // MPos enabled + #define DEFAULT_JUNCTION_DEVIATION 0.01 // mm + #define DEFAULT_ARC_TOLERANCE 0.002 // mm + #define DEFAULT_REPORT_INCHES 0 // false + #define DEFAULT_INVERT_ST_ENABLE 0 // false + #define DEFAULT_INVERT_LIMIT_PINS 0 // false + #define DEFAULT_SOFT_LIMIT_ENABLE 0 // false + #define DEFAULT_HARD_LIMIT_ENABLE 0 // false + #define DEFAULT_INVERT_PROBE_PIN 0 // false + #define DEFAULT_LASER_MODE 0 // false + #define DEFAULT_HOMING_ENABLE 0 // false + #define DEFAULT_HOMING_DIR_MASK 0 // move positive dir + #define DEFAULT_HOMING_FEED_RATE 25.0 // mm/min + #define DEFAULT_HOMING_SEEK_RATE 500.0 // mm/min + #define DEFAULT_HOMING_DEBOUNCE_DELAY 250 // msec (0-65k) + #define DEFAULT_HOMING_PULLOFF 1.0 // mm +#endif + +#ifdef DEFAULTS_SHERLINE_5400 + // Description: Sherline 5400 mill with three NEMA 23 Keling KL23H256-21-8B 185 oz-in stepper motors, + // driven by three Pololu A4988 stepper drivers with a 30V, 6A power supply at 1.5A per winding. + #define MICROSTEPS 2 + #define STEPS_PER_REV 200.0 + #define MM_PER_REV (0.050*MM_PER_INCH) // 0.050 inch/rev leadscrew + #define DEFAULT_X_STEPS_PER_MM (STEPS_PER_REV*MICROSTEPS/MM_PER_REV) + #define DEFAULT_Y_STEPS_PER_MM (STEPS_PER_REV*MICROSTEPS/MM_PER_REV) + #define DEFAULT_Z_STEPS_PER_MM (STEPS_PER_REV*MICROSTEPS/MM_PER_REV) + #define DEFAULT_X_MAX_RATE 635.0 // mm/min (25 ipm) + #define DEFAULT_Y_MAX_RATE 635.0 // mm/min + #define DEFAULT_Z_MAX_RATE 635.0 // mm/min + #define DEFAULT_X_ACCELERATION (50.0*60*60) // 50*60*60 mm/min^2 = 50 mm/sec^2 + #define DEFAULT_Y_ACCELERATION (50.0*60*60) // 50*60*60 mm/min^2 = 50 mm/sec^2 + #define DEFAULT_Z_ACCELERATION (50.0*60*60) // 50*60*60 mm/min^2 = 50 mm/sec^2 + #define DEFAULT_X_MAX_TRAVEL 225.0 // mm NOTE: Must be a positive value. + #define DEFAULT_Y_MAX_TRAVEL 125.0 // mm NOTE: Must be a positive value. + #define DEFAULT_Z_MAX_TRAVEL 170.0 // mm NOTE: Must be a positive value. + #define DEFAULT_SPINDLE_RPM_MAX 2800.0 // rpm + #define DEFAULT_SPINDLE_RPM_MIN 0.0 // rpm + #define DEFAULT_STEP_PULSE_MICROSECONDS 10 + #define DEFAULT_STEPPING_INVERT_MASK 0 + #define DEFAULT_DIRECTION_INVERT_MASK ((1< +#include + +/* These EEPROM bits have different names on different devices. */ +#ifndef EEPE + #define EEPE EEWE //!< EEPROM program/write enable. + #define EEMPE EEMWE //!< EEPROM master program/write enable. +#endif + +/* These two are unfortunately not defined in the device include files. */ +#define EEPM1 5 //!< EEPROM Programming Mode Bit 1. +#define EEPM0 4 //!< EEPROM Programming Mode Bit 0. + +/* Define to reduce code size. */ +#define EEPROM_IGNORE_SELFPROG //!< Remove SPM flag polling. + +/*! \brief Read byte from EEPROM. + * + * This function reads one byte from a given EEPROM address. + * + * \note The CPU is halted for 4 clock cycles during EEPROM read. + * + * \param addr EEPROM address to read from. + * \return The byte read from the EEPROM address. + */ +unsigned char eeprom_get_char( unsigned int addr ) +{ + do {} while( EECR & (1< 0; size--) { + checksum = (checksum << 1) || (checksum >> 7); + checksum += *source; + eeprom_put_char(destination++, *(source++)); + } + eeprom_put_char(destination, checksum); +} + +int memcpy_from_eeprom_with_checksum(char *destination, unsigned int source, unsigned int size) { + unsigned char data, checksum = 0; + for(; size > 0; size--) { + data = eeprom_get_char(source++); + checksum = (checksum << 1) || (checksum >> 7); + checksum += data; + *(destination++) = data; + } + return(checksum == eeprom_get_char(source)); +} + +// end of file diff --git a/trunk/Arduino/GRBL_1.1f_Nano/eeprom.h b/trunk/Arduino/GRBL_1.1f_Nano/eeprom.h new file mode 100644 index 00000000..c9718a2b --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f_Nano/eeprom.h @@ -0,0 +1,29 @@ +/* + eeprom.h - EEPROM methods + Part of Grbl + + Copyright (c) 2009-2011 Simen Svale Skogsrud + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +#ifndef eeprom_h +#define eeprom_h + +unsigned char eeprom_get_char(unsigned int addr); +void eeprom_put_char(unsigned int addr, unsigned char new_value); +void memcpy_to_eeprom_with_checksum(unsigned int destination, char *source, unsigned int size); +int memcpy_from_eeprom_with_checksum(char *destination, unsigned int source, unsigned int size); + +#endif diff --git a/trunk/Arduino/GRBL_1.1f_Nano/gcode.c b/trunk/Arduino/GRBL_1.1f_Nano/gcode.c new file mode 100644 index 00000000..13ebbee4 --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f_Nano/gcode.c @@ -0,0 +1,1159 @@ +/* + gcode.c - rs274/ngc parser. + Part of Grbl + + Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC + Copyright (c) 2009-2011 Simen Svale Skogsrud + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +#include "grbl.h" + +// NOTE: Max line number is defined by the g-code standard to be 99999. It seems to be an +// arbitrary value, and some GUIs may require more. So we increased it based on a max safe +// value when converting a float (7.2 digit precision)s to an integer. +#define MAX_LINE_NUMBER 10000000 +#define MAX_TOOL_NUMBER 255 // Limited by max unsigned 8-bit value + +#define AXIS_COMMAND_NONE 0 +#define AXIS_COMMAND_NON_MODAL 1 +#define AXIS_COMMAND_MOTION_MODE 2 +#define AXIS_COMMAND_TOOL_LENGTH_OFFSET 3 // *Undefined but required + +// Declare gc extern struct +parser_state_t gc_state; +parser_block_t gc_block; + +#define FAIL(status) return(status); + + +void gc_init() +{ + memset(&gc_state, 0, sizeof(parser_state_t)); + + // Load default G54 coordinate system. + if (!(settings_read_coord_data(gc_state.modal.coord_select,gc_state.coord_system))) { + report_status_message(STATUS_SETTING_READ_FAIL); + } +} + + +// Sets g-code parser position in mm. Input in steps. Called by the system abort and hard +// limit pull-off routines. +void gc_sync_position() +{ + system_convert_array_steps_to_mpos(gc_state.position,sys_position); +} + + +// Executes one line of 0-terminated G-Code. The line is assumed to contain only uppercase +// characters and signed floating point values (no whitespace). Comments and block delete +// characters have been removed. In this function, all units and positions are converted and +// exported to grbl's internal functions in terms of (mm, mm/min) and absolute machine +// coordinates, respectively. +uint8_t gc_execute_line(char *line) +{ + /* ------------------------------------------------------------------------------------- + STEP 1: Initialize parser block struct and copy current g-code state modes. The parser + updates these modes and commands as the block line is parser and will only be used and + executed after successful error-checking. The parser block struct also contains a block + values struct, word tracking variables, and a non-modal commands tracker for the new + block. This struct contains all of the necessary information to execute the block. */ + + memset(&gc_block, 0, sizeof(parser_block_t)); // Initialize the parser block struct. + memcpy(&gc_block.modal,&gc_state.modal,sizeof(gc_modal_t)); // Copy current modes + + uint8_t axis_command = AXIS_COMMAND_NONE; + uint8_t axis_0, axis_1, axis_linear; + uint8_t coord_select = 0; // Tracks G10 P coordinate selection for execution + + // Initialize bitflag tracking variables for axis indices compatible operations. + uint8_t axis_words = 0; // XYZ tracking + uint8_t ijk_words = 0; // IJK tracking + + // Initialize command and value words and parser flags variables. + uint16_t command_words = 0; // Tracks G and M command words. Also used for modal group violations. + uint16_t value_words = 0; // Tracks value words. + uint8_t gc_parser_flags = GC_PARSER_NONE; + + // Determine if the line is a jogging motion or a normal g-code block. + if (line[0] == '$') { // NOTE: `$J=` already parsed when passed to this function. + // Set G1 and G94 enforced modes to ensure accurate error checks. + gc_parser_flags |= GC_PARSER_JOG_MOTION; + gc_block.modal.motion = MOTION_MODE_LINEAR; + gc_block.modal.feed_rate = FEED_RATE_MODE_UNITS_PER_MIN; + #ifdef USE_LINE_NUMBERS + gc_block.values.n = JOG_LINE_NUMBER; // Initialize default line number reported during jog. + #endif + } + + /* ------------------------------------------------------------------------------------- + STEP 2: Import all g-code words in the block line. A g-code word is a letter followed by + a number, which can either be a 'G'/'M' command or sets/assigns a command value. Also, + perform initial error-checks for command word modal group violations, for any repeated + words, and for negative values set for the value words F, N, P, T, and S. */ + + uint8_t word_bit; // Bit-value for assigning tracking variables + uint8_t char_counter; + char letter; + float value; + uint8_t int_value = 0; + uint16_t mantissa = 0; + if (gc_parser_flags & GC_PARSER_JOG_MOTION) { char_counter = 3; } // Start parsing after `$J=` + else { char_counter = 0; } + + while (line[char_counter] != 0) { // Loop until no more g-code words in line. + + // Import the next g-code word, expecting a letter followed by a value. Otherwise, error out. + letter = line[char_counter]; + if((letter < 'A') || (letter > 'Z')) { FAIL(STATUS_EXPECTED_COMMAND_LETTER); } // [Expected word letter] + char_counter++; + if (!read_float(line, &char_counter, &value)) { FAIL(STATUS_BAD_NUMBER_FORMAT); } // [Expected word value] + + // Convert values to smaller uint8 significand and mantissa values for parsing this word. + // NOTE: Mantissa is multiplied by 100 to catch non-integer command values. This is more + // accurate than the NIST gcode requirement of x10 when used for commands, but not quite + // accurate enough for value words that require integers to within 0.0001. This should be + // a good enough comprimise and catch most all non-integer errors. To make it compliant, + // we would simply need to change the mantissa to int16, but this add compiled flash space. + // Maybe update this later. + int_value = trunc(value); + mantissa = round(100*(value - int_value)); // Compute mantissa for Gxx.x commands. + // NOTE: Rounding must be used to catch small floating point errors. + + // Check if the g-code word is supported or errors due to modal group violations or has + // been repeated in the g-code block. If ok, update the command or record its value. + switch(letter) { + + /* 'G' and 'M' Command Words: Parse commands and check for modal group violations. + NOTE: Modal group numbers are defined in Table 4 of NIST RS274-NGC v3, pg.20 */ + + case 'G': + // Determine 'G' command and its modal group + switch(int_value) { + case 10: case 28: case 30: case 92: + // Check for G10/28/30/92 being called with G0/1/2/3/38 on same block. + // * G43.1 is also an axis command but is not explicitly defined this way. + if (mantissa == 0) { // Ignore G28.1, G30.1, and G92.1 + if (axis_command) { FAIL(STATUS_GCODE_AXIS_COMMAND_CONFLICT); } // [Axis word/command conflict] + axis_command = AXIS_COMMAND_NON_MODAL; + } + // No break. Continues to next line. + case 4: case 53: + word_bit = MODAL_GROUP_G0; + gc_block.non_modal_command = int_value; + if ((int_value == 28) || (int_value == 30) || (int_value == 92)) { + if (!((mantissa == 0) || (mantissa == 10))) { FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); } + gc_block.non_modal_command += mantissa; + mantissa = 0; // Set to zero to indicate valid non-integer G command. + } + break; + case 0: case 1: case 2: case 3: case 38: + // Check for G0/1/2/3/38 being called with G10/28/30/92 on same block. + // * G43.1 is also an axis command but is not explicitly defined this way. + if (axis_command) { FAIL(STATUS_GCODE_AXIS_COMMAND_CONFLICT); } // [Axis word/command conflict] + axis_command = AXIS_COMMAND_MOTION_MODE; + // No break. Continues to next line. + case 80: + word_bit = MODAL_GROUP_G1; + gc_block.modal.motion = int_value; + if (int_value == 38){ + if (!((mantissa == 20) || (mantissa == 30) || (mantissa == 40) || (mantissa == 50))) { + FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); // [Unsupported G38.x command] + } + gc_block.modal.motion += (mantissa/10)+100; + mantissa = 0; // Set to zero to indicate valid non-integer G command. + } + break; + case 17: case 18: case 19: + word_bit = MODAL_GROUP_G2; + gc_block.modal.plane_select = int_value - 17; + break; + case 90: case 91: + if (mantissa == 0) { + word_bit = MODAL_GROUP_G3; + gc_block.modal.distance = int_value - 90; + } else { + word_bit = MODAL_GROUP_G4; + if ((mantissa != 10) || (int_value == 90)) { FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); } // [G90.1 not supported] + mantissa = 0; // Set to zero to indicate valid non-integer G command. + // Otherwise, arc IJK incremental mode is default. G91.1 does nothing. + } + break; + case 93: case 94: + word_bit = MODAL_GROUP_G5; + gc_block.modal.feed_rate = 94 - int_value; + break; + case 20: case 21: + word_bit = MODAL_GROUP_G6; + gc_block.modal.units = 21 - int_value; + break; + case 40: + word_bit = MODAL_GROUP_G7; + // NOTE: Not required since cutter radius compensation is always disabled. Only here + // to support G40 commands that often appear in g-code program headers to setup defaults. + // gc_block.modal.cutter_comp = CUTTER_COMP_DISABLE; // G40 + break; + case 43: case 49: + word_bit = MODAL_GROUP_G8; + // NOTE: The NIST g-code standard vaguely states that when a tool length offset is changed, + // there cannot be any axis motion or coordinate offsets updated. Meaning G43, G43.1, and G49 + // all are explicit axis commands, regardless if they require axis words or not. + if (axis_command) { FAIL(STATUS_GCODE_AXIS_COMMAND_CONFLICT); } // [Axis word/command conflict] } + axis_command = AXIS_COMMAND_TOOL_LENGTH_OFFSET; + if (int_value == 49) { // G49 + gc_block.modal.tool_length = TOOL_LENGTH_OFFSET_CANCEL; + } else if (mantissa == 10) { // G43.1 + gc_block.modal.tool_length = TOOL_LENGTH_OFFSET_ENABLE_DYNAMIC; + } else { FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); } // [Unsupported G43.x command] + mantissa = 0; // Set to zero to indicate valid non-integer G command. + break; + case 54: case 55: case 56: case 57: case 58: case 59: + // NOTE: G59.x are not supported. (But their int_values would be 60, 61, and 62.) + word_bit = MODAL_GROUP_G12; + gc_block.modal.coord_select = int_value - 54; // Shift to array indexing. + break; + case 61: + word_bit = MODAL_GROUP_G13; + if (mantissa != 0) { FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); } // [G61.1 not supported] + // gc_block.modal.control = CONTROL_MODE_EXACT_PATH; // G61 + break; + default: FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); // [Unsupported G command] + } + if (mantissa > 0) { FAIL(STATUS_GCODE_COMMAND_VALUE_NOT_INTEGER); } // [Unsupported or invalid Gxx.x command] + // Check for more than one command per modal group violations in the current block + // NOTE: Variable 'word_bit' is always assigned, if the command is valid. + if ( bit_istrue(command_words,bit(word_bit)) ) { FAIL(STATUS_GCODE_MODAL_GROUP_VIOLATION); } + command_words |= bit(word_bit); + break; + + case 'M': + + // Determine 'M' command and its modal group + if (mantissa > 0) { FAIL(STATUS_GCODE_COMMAND_VALUE_NOT_INTEGER); } // [No Mxx.x commands] + switch(int_value) { + case 0: case 1: case 2: case 30: + word_bit = MODAL_GROUP_M4; + switch(int_value) { + case 0: gc_block.modal.program_flow = PROGRAM_FLOW_PAUSED; break; // Program pause + case 1: break; // Optional stop not supported. Ignore. + default: gc_block.modal.program_flow = int_value; // Program end and reset + } + break; + case 3: case 4: case 5: + word_bit = MODAL_GROUP_M7; + switch(int_value) { + case 3: gc_block.modal.spindle = SPINDLE_ENABLE_CW; break; + case 4: gc_block.modal.spindle = SPINDLE_ENABLE_CCW; break; + case 5: gc_block.modal.spindle = SPINDLE_DISABLE; break; + } + break; + #ifdef ENABLE_M7 + case 7: case 8: case 9: + #else + case 8: case 9: + #endif + word_bit = MODAL_GROUP_M8; + switch(int_value) { + #ifdef ENABLE_M7 + case 7: gc_block.modal.coolant |= COOLANT_MIST_ENABLE; break; + #endif + case 8: gc_block.modal.coolant |= COOLANT_FLOOD_ENABLE; break; + case 9: gc_block.modal.coolant = COOLANT_DISABLE; break; // M9 disables both M7 and M8. + } + break; + #ifdef ENABLE_PARKING_OVERRIDE_CONTROL + case 56: + word_bit = MODAL_GROUP_M9; + gc_block.modal.override = OVERRIDE_PARKING_MOTION; + break; + #endif + default: FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); // [Unsupported M command] + } + + // Check for more than one command per modal group violations in the current block + // NOTE: Variable 'word_bit' is always assigned, if the command is valid. + if ( bit_istrue(command_words,bit(word_bit)) ) { FAIL(STATUS_GCODE_MODAL_GROUP_VIOLATION); } + command_words |= bit(word_bit); + break; + + // NOTE: All remaining letters assign values. + default: + + /* Non-Command Words: This initial parsing phase only checks for repeats of the remaining + legal g-code words and stores their value. Error-checking is performed later since some + words (I,J,K,L,P,R) have multiple connotations and/or depend on the issued commands. */ + switch(letter){ + // case 'A': // Not supported + // case 'B': // Not supported + // case 'C': // Not supported + // case 'D': // Not supported + case 'F': word_bit = WORD_F; gc_block.values.f = value; break; + // case 'H': // Not supported + case 'I': word_bit = WORD_I; gc_block.values.ijk[X_AXIS] = value; ijk_words |= (1< MAX_TOOL_NUMBER) { FAIL(STATUS_GCODE_MAX_VALUE_EXCEEDED); } + gc_block.values.t = int_value; + break; + case 'X': word_bit = WORD_X; gc_block.values.xyz[X_AXIS] = value; axis_words |= (1< MAX_LINE_NUMBER) { FAIL(STATUS_GCODE_INVALID_LINE_NUMBER); } // [Exceeds max line number] + } + // bit_false(value_words,bit(WORD_N)); // NOTE: Single-meaning value word. Set at end of error-checking. + + // Track for unused words at the end of error-checking. + // NOTE: Single-meaning value words are removed all at once at the end of error-checking, because + // they are always used when present. This was done to save a few bytes of flash. For clarity, the + // single-meaning value words may be removed as they are used. Also, axis words are treated in the + // same way. If there is an explicit/implicit axis command, XYZ words are always used and are + // are removed at the end of error-checking. + + // [1. Comments ]: MSG's NOT SUPPORTED. Comment handling performed by protocol. + + // [2. Set feed rate mode ]: G93 F word missing with G1,G2/3 active, implicitly or explicitly. Feed rate + // is not defined after switching to G94 from G93. + // NOTE: For jogging, ignore prior feed rate mode. Enforce G94 and check for required F word. + if (gc_parser_flags & GC_PARSER_JOG_MOTION) { + if (bit_isfalse(value_words,bit(WORD_F))) { FAIL(STATUS_GCODE_UNDEFINED_FEED_RATE); } + if (gc_block.modal.units == UNITS_MODE_INCHES) { gc_block.values.f *= MM_PER_INCH; } + } else { + if (gc_block.modal.feed_rate == FEED_RATE_MODE_INVERSE_TIME) { // = G93 + // NOTE: G38 can also operate in inverse time, but is undefined as an error. Missing F word check added here. + if (axis_command == AXIS_COMMAND_MOTION_MODE) { + if ((gc_block.modal.motion != MOTION_MODE_NONE) && (gc_block.modal.motion != MOTION_MODE_SEEK)) { + if (bit_isfalse(value_words,bit(WORD_F))) { FAIL(STATUS_GCODE_UNDEFINED_FEED_RATE); } // [F word missing] + } + } + // NOTE: It seems redundant to check for an F word to be passed after switching from G94 to G93. We would + // accomplish the exact same thing if the feed rate value is always reset to zero and undefined after each + // inverse time block, since the commands that use this value already perform undefined checks. This would + // also allow other commands, following this switch, to execute and not error out needlessly. This code is + // combined with the above feed rate mode and the below set feed rate error-checking. + + // [3. Set feed rate ]: F is negative (done.) + // - In inverse time mode: Always implicitly zero the feed rate value before and after block completion. + // NOTE: If in G93 mode or switched into it from G94, just keep F value as initialized zero or passed F word + // value in the block. If no F word is passed with a motion command that requires a feed rate, this will error + // out in the motion modes error-checking. However, if no F word is passed with NO motion command that requires + // a feed rate, we simply move on and the state feed rate value gets updated to zero and remains undefined. + } else { // = G94 + // - In units per mm mode: If F word passed, ensure value is in mm/min, otherwise push last state value. + if (gc_state.modal.feed_rate == FEED_RATE_MODE_UNITS_PER_MIN) { // Last state is also G94 + if (bit_istrue(value_words,bit(WORD_F))) { + if (gc_block.modal.units == UNITS_MODE_INCHES) { gc_block.values.f *= MM_PER_INCH; } + } else { + gc_block.values.f = gc_state.feed_rate; // Push last state feed rate + } + } // Else, switching to G94 from G93, so don't push last state feed rate. Its undefined or the passed F word value. + } + } + // bit_false(value_words,bit(WORD_F)); // NOTE: Single-meaning value word. Set at end of error-checking. + + // [4. Set spindle speed ]: S is negative (done.) + if (bit_isfalse(value_words,bit(WORD_S))) { gc_block.values.s = gc_state.spindle_speed; } + // bit_false(value_words,bit(WORD_S)); // NOTE: Single-meaning value word. Set at end of error-checking. + + // [5. Select tool ]: NOT SUPPORTED. Only tracks value. T is negative (done.) Not an integer. Greater than max tool value. + // bit_false(value_words,bit(WORD_T)); // NOTE: Single-meaning value word. Set at end of error-checking. + + // [6. Change tool ]: N/A + // [7. Spindle control ]: N/A + // [8. Coolant control ]: N/A + // [9. Override control ]: Not supported except for a Grbl-only parking motion override control. + #ifdef ENABLE_PARKING_OVERRIDE_CONTROL + if (bit_istrue(command_words,bit(MODAL_GROUP_M9))) { // Already set as enabled in parser. + if (bit_istrue(value_words,bit(WORD_P))) { + if (gc_block.values.p == 0.0) { gc_block.modal.override = OVERRIDE_DISABLED; } + bit_false(value_words,bit(WORD_P)); + } + } + #endif + + // [10. Dwell ]: P value missing. P is negative (done.) NOTE: See below. + if (gc_block.non_modal_command == NON_MODAL_DWELL) { + if (bit_isfalse(value_words,bit(WORD_P))) { FAIL(STATUS_GCODE_VALUE_WORD_MISSING); } // [P word missing] + bit_false(value_words,bit(WORD_P)); + } + + // [11. Set active plane ]: N/A + switch (gc_block.modal.plane_select) { + case PLANE_SELECT_XY: + axis_0 = X_AXIS; + axis_1 = Y_AXIS; + axis_linear = Z_AXIS; + break; + case PLANE_SELECT_ZX: + axis_0 = Z_AXIS; + axis_1 = X_AXIS; + axis_linear = Y_AXIS; + break; + default: // case PLANE_SELECT_YZ: + axis_0 = Y_AXIS; + axis_1 = Z_AXIS; + axis_linear = X_AXIS; + } + + // [12. Set length units ]: N/A + // Pre-convert XYZ coordinate values to millimeters, if applicable. + uint8_t idx; + if (gc_block.modal.units == UNITS_MODE_INCHES) { + for (idx=0; idx N_COORDINATE_SYSTEM) { FAIL(STATUS_GCODE_UNSUPPORTED_COORD_SYS); } // [Greater than N sys] + if (gc_state.modal.coord_select != gc_block.modal.coord_select) { + if (!(settings_read_coord_data(gc_block.modal.coord_select,block_coord_system))) { FAIL(STATUS_SETTING_READ_FAIL); } + } + } + + // [16. Set path control mode ]: N/A. Only G61. G61.1 and G64 NOT SUPPORTED. + // [17. Set distance mode ]: N/A. Only G91.1. G90.1 NOT SUPPORTED. + // [18. Set retract mode ]: NOT SUPPORTED. + + // [19. Remaining non-modal actions ]: Check go to predefined position, set G10, or set axis offsets. + // NOTE: We need to separate the non-modal commands that are axis word-using (G10/G28/G30/G92), as these + // commands all treat axis words differently. G10 as absolute offsets or computes current position as + // the axis value, G92 similarly to G10 L20, and G28/30 as an intermediate target position that observes + // all the current coordinate system and G92 offsets. + switch (gc_block.non_modal_command) { + case NON_MODAL_SET_COORDINATE_DATA: + // [G10 Errors]: L missing and is not 2 or 20. P word missing. (Negative P value done.) + // [G10 L2 Errors]: R word NOT SUPPORTED. P value not 0 to nCoordSys(max 9). Axis words missing. + // [G10 L20 Errors]: P must be 0 to nCoordSys(max 9). Axis words missing. + if (!axis_words) { FAIL(STATUS_GCODE_NO_AXIS_WORDS) }; // [No axis words] + if (bit_isfalse(value_words,((1< N_COORDINATE_SYSTEM) { FAIL(STATUS_GCODE_UNSUPPORTED_COORD_SYS); } // [Greater than N sys] + if (gc_block.values.l != 20) { + if (gc_block.values.l == 2) { + if (bit_istrue(value_words,bit(WORD_R))) { FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); } // [G10 L2 R not supported] + } else { FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); } // [Unsupported L] + } + bit_false(value_words,(bit(WORD_L)|bit(WORD_P))); + + // Determine coordinate system to change and try to load from EEPROM. + if (coord_select > 0) { coord_select--; } // Adjust P1-P6 index to EEPROM coordinate data indexing. + else { coord_select = gc_block.modal.coord_select; } // Index P0 as the active coordinate system + + // NOTE: Store parameter data in IJK values. By rule, they are not in use with this command. + if (!settings_read_coord_data(coord_select,gc_block.values.ijk)) { FAIL(STATUS_SETTING_READ_FAIL); } // [EEPROM read fail] + + // Pre-calculate the coordinate data changes. + for (idx=0; idx WCS = MPos - G92 - TLO - WPos + gc_block.values.ijk[idx] = gc_state.position[idx]-gc_state.coord_offset[idx]-gc_block.values.xyz[idx]; + if (idx == TOOL_LENGTH_OFFSET_AXIS) { gc_block.values.ijk[idx] -= gc_state.tool_length_offset; } + } else { + // L2: Update coordinate system axis to programmed value. + gc_block.values.ijk[idx] = gc_block.values.xyz[idx]; + } + } // Else, keep current stored value. + } + break; + case NON_MODAL_SET_COORDINATE_OFFSET: + // [G92 Errors]: No axis words. + if (!axis_words) { FAIL(STATUS_GCODE_NO_AXIS_WORDS); } // [No axis words] + + // Update axes defined only in block. Offsets current system to defined value. Does not update when + // active coordinate system is selected, but is still active unless G92.1 disables it. + for (idx=0; idx G92 = MPos - WCS - TLO - WPos + gc_block.values.xyz[idx] = gc_state.position[idx]-block_coord_system[idx]-gc_block.values.xyz[idx]; + if (idx == TOOL_LENGTH_OFFSET_AXIS) { gc_block.values.xyz[idx] -= gc_state.tool_length_offset; } + } else { + gc_block.values.xyz[idx] = gc_state.coord_offset[idx]; + } + } + break; + + default: + + // At this point, the rest of the explicit axis commands treat the axis values as the traditional + // target position with the coordinate system offsets, G92 offsets, absolute override, and distance + // modes applied. This includes the motion mode commands. We can now pre-compute the target position. + // NOTE: Tool offsets may be appended to these conversions when/if this feature is added. + if (axis_command != AXIS_COMMAND_TOOL_LENGTH_OFFSET ) { // TLO block any axis command. + if (axis_words) { + for (idx=0; idx C -----------------+--------------- T <- [x,y] + | <------ d/2 ---->| + + C - Current position + T - Target position + O - center of circle that pass through both C and T + d - distance from C to T + r - designated radius + h - distance from center of CT to O + + Expanding the equations: + + d -> sqrt(x^2 + y^2) + h -> sqrt(4 * r^2 - x^2 - y^2)/2 + i -> (x - (y * sqrt(4 * r^2 - x^2 - y^2)) / sqrt(x^2 + y^2)) / 2 + j -> (y + (x * sqrt(4 * r^2 - x^2 - y^2)) / sqrt(x^2 + y^2)) / 2 + + Which can be written: + + i -> (x - (y * sqrt(4 * r^2 - x^2 - y^2))/sqrt(x^2 + y^2))/2 + j -> (y + (x * sqrt(4 * r^2 - x^2 - y^2))/sqrt(x^2 + y^2))/2 + + Which we for size and speed reasons optimize to: + + h_x2_div_d = sqrt(4 * r^2 - x^2 - y^2)/sqrt(x^2 + y^2) + i = (x - (y * h_x2_div_d))/2 + j = (y + (x * h_x2_div_d))/2 + */ + + // First, use h_x2_div_d to compute 4*h^2 to check if it is negative or r is smaller + // than d. If so, the sqrt of a negative number is complex and error out. + float h_x2_div_d = 4.0 * gc_block.values.r*gc_block.values.r - x*x - y*y; + + if (h_x2_div_d < 0) { FAIL(STATUS_GCODE_ARC_RADIUS_ERROR); } // [Arc radius error] + + // Finish computing h_x2_div_d. + h_x2_div_d = -sqrt(h_x2_div_d)/hypot_f(x,y); // == -(h * 2 / d) + // Invert the sign of h_x2_div_d if the circle is counter clockwise (see sketch below) + if (gc_block.modal.motion == MOTION_MODE_CCW_ARC) { h_x2_div_d = -h_x2_div_d; } + + /* The counter clockwise circle lies to the left of the target direction. When offset is positive, + the left hand circle will be generated - when it is negative the right hand circle is generated. + + T <-- Target position + + ^ + Clockwise circles with this center | Clockwise circles with this center will have + will have > 180 deg of angular travel | < 180 deg of angular travel, which is a good thing! + \ | / + center of arc when h_x2_div_d is positive -> x <----- | -----> x <- center of arc when h_x2_div_d is negative + | + | + + C <-- Current position + */ + // Negative R is g-code-alese for "I want a circle with more than 180 degrees of travel" (go figure!), + // even though it is advised against ever generating such circles in a single line of g-code. By + // inverting the sign of h_x2_div_d the center of the circles is placed on the opposite side of the line of + // travel and thus we get the unadvisably long arcs as prescribed. + if (gc_block.values.r < 0) { + h_x2_div_d = -h_x2_div_d; + gc_block.values.r = -gc_block.values.r; // Finished with r. Set to positive for mc_arc + } + // Complete the operation by calculating the actual center of the arc + gc_block.values.ijk[axis_0] = 0.5*(x-(y*h_x2_div_d)); + gc_block.values.ijk[axis_1] = 0.5*(y+(x*h_x2_div_d)); + + } else { // Arc Center Format Offset Mode + if (!(ijk_words & (bit(axis_0)|bit(axis_1)))) { FAIL(STATUS_GCODE_NO_OFFSETS_IN_PLANE); } // [No offsets in plane] + bit_false(value_words,(bit(WORD_I)|bit(WORD_J)|bit(WORD_K))); + + // Convert IJK values to proper units. + if (gc_block.modal.units == UNITS_MODE_INCHES) { + for (idx=0; idx 0.005) { + if (delta_r > 0.5) { FAIL(STATUS_GCODE_INVALID_TARGET); } // [Arc definition error] > 0.5mm + if (delta_r > (0.001*gc_block.values.r)) { FAIL(STATUS_GCODE_INVALID_TARGET); } // [Arc definition error] > 0.005mm AND 0.1% radius + } + } + break; + case MOTION_MODE_PROBE_TOWARD_NO_ERROR: case MOTION_MODE_PROBE_AWAY_NO_ERROR: + gc_parser_flags |= GC_PARSER_PROBE_IS_NO_ERROR; // No break intentional. + case MOTION_MODE_PROBE_TOWARD: case MOTION_MODE_PROBE_AWAY: + if ((gc_block.modal.motion == MOTION_MODE_PROBE_AWAY) || + (gc_block.modal.motion == MOTION_MODE_PROBE_AWAY_NO_ERROR)) { gc_parser_flags |= GC_PARSER_PROBE_IS_AWAY; } + // [G38 Errors]: Target is same current. No axis words. Cutter compensation is enabled. Feed rate + // is undefined. Probe is triggered. NOTE: Probe check moved to probe cycle. Instead of returning + // an error, it issues an alarm to prevent further motion to the probe. It's also done there to + // allow the planner buffer to empty and move off the probe trigger before another probing cycle. + if (!axis_words) { FAIL(STATUS_GCODE_NO_AXIS_WORDS); } // [No axis words] + if (isequal_position_vector(gc_state.position, gc_block.values.xyz)) { FAIL(STATUS_GCODE_INVALID_TARGET); } // [Invalid target] + break; + } + } + } + + // [21. Program flow ]: No error checks required. + + // [0. Non-specific error-checks]: Complete unused value words check, i.e. IJK used when in arc + // radius mode, or axis words that aren't used in the block. + if (gc_parser_flags & GC_PARSER_JOG_MOTION) { + // Jogging only uses the F feed rate and XYZ value words. N is valid, but S and T are invalid. + bit_false(value_words,(bit(WORD_N)|bit(WORD_F))); + } else { + bit_false(value_words,(bit(WORD_N)|bit(WORD_F)|bit(WORD_S)|bit(WORD_T))); // Remove single-meaning value words. + } + if (axis_command) { bit_false(value_words,(bit(WORD_X)|bit(WORD_Y)|bit(WORD_Z))); } // Remove axis words. + if (value_words) { FAIL(STATUS_GCODE_UNUSED_WORDS); } // [Unused words] + + /* ------------------------------------------------------------------------------------- + STEP 4: EXECUTE!! + Assumes that all error-checking has been completed and no failure modes exist. We just + need to update the state and execute the block according to the order-of-execution. + */ + + // Initialize planner data struct for motion blocks. + plan_line_data_t plan_data; + plan_line_data_t *pl_data = &plan_data; + memset(pl_data,0,sizeof(plan_line_data_t)); // Zero pl_data struct + + // Intercept jog commands and complete error checking for valid jog commands and execute. + // NOTE: G-code parser state is not updated, except the position to ensure sequential jog + // targets are computed correctly. The final parser position after a jog is updated in + // protocol_execute_realtime() when jogging completes or is canceled. + if (gc_parser_flags & GC_PARSER_JOG_MOTION) { + // Only distance and unit modal commands and G53 absolute override command are allowed. + // NOTE: Feed rate word and axis word checks have already been performed in STEP 3. + if (command_words & ~(bit(MODAL_GROUP_G3) | bit(MODAL_GROUP_G6 | bit(MODAL_GROUP_G0))) ) { FAIL(STATUS_INVALID_JOG_COMMAND) }; + if (!(gc_block.non_modal_command == NON_MODAL_ABSOLUTE_OVERRIDE || gc_block.non_modal_command == NON_MODAL_NO_ACTION)) { FAIL(STATUS_INVALID_JOG_COMMAND); } + + // Initialize planner data to current spindle and coolant modal state. + pl_data->spindle_speed = gc_state.spindle_speed; + plan_data.condition = (gc_state.modal.spindle | gc_state.modal.coolant); + + uint8_t status = jog_execute(&plan_data, &gc_block); + if (status == STATUS_OK) { memcpy(gc_state.position, gc_block.values.xyz, sizeof(gc_block.values.xyz)); } + return(status); + } + + // If in laser mode, setup laser power based on current and past parser conditions. + if (bit_istrue(settings.flags,BITFLAG_LASER_MODE)) { + if ( !((gc_block.modal.motion == MOTION_MODE_LINEAR) || (gc_block.modal.motion == MOTION_MODE_CW_ARC) + || (gc_block.modal.motion == MOTION_MODE_CCW_ARC)) ) { + gc_parser_flags |= GC_PARSER_LASER_DISABLE; + } + + // Any motion mode with axis words is allowed to be passed from a spindle speed update. + // NOTE: G1 and G0 without axis words sets axis_command to none. G28/30 are intentionally omitted. + // TODO: Check sync conditions for M3 enabled motions that don't enter the planner. (zero length). + if (axis_words && (axis_command == AXIS_COMMAND_MOTION_MODE)) { + gc_parser_flags |= GC_PARSER_LASER_ISMOTION; + } else { + // M3 constant power laser requires planner syncs to update the laser when changing between + // a G1/2/3 motion mode state and vice versa when there is no motion in the line. + if (gc_state.modal.spindle == SPINDLE_ENABLE_CW) { + if ((gc_state.modal.motion == MOTION_MODE_LINEAR) || (gc_state.modal.motion == MOTION_MODE_CW_ARC) + || (gc_state.modal.motion == MOTION_MODE_CCW_ARC)) { + if (bit_istrue(gc_parser_flags,GC_PARSER_LASER_DISABLE)) { + gc_parser_flags |= GC_PARSER_LASER_FORCE_SYNC; // Change from G1/2/3 motion mode. + } + } else { + // When changing to a G1 motion mode without axis words from a non-G1/2/3 motion mode. + if (bit_isfalse(gc_parser_flags,GC_PARSER_LASER_DISABLE)) { + gc_parser_flags |= GC_PARSER_LASER_FORCE_SYNC; + } + } + } + } + } + + // [0. Non-specific/common error-checks and miscellaneous setup]: + // NOTE: If no line number is present, the value is zero. + gc_state.line_number = gc_block.values.n; + #ifdef USE_LINE_NUMBERS + pl_data->line_number = gc_state.line_number; // Record data for planner use. + #endif + + // [1. Comments feedback ]: NOT SUPPORTED + + // [2. Set feed rate mode ]: + gc_state.modal.feed_rate = gc_block.modal.feed_rate; + if (gc_state.modal.feed_rate) { pl_data->condition |= PL_COND_FLAG_INVERSE_TIME; } // Set condition flag for planner use. + + // [3. Set feed rate ]: + gc_state.feed_rate = gc_block.values.f; // Always copy this value. See feed rate error-checking. + pl_data->feed_rate = gc_state.feed_rate; // Record data for planner use. + + // [4. Set spindle speed ]: + if ((gc_state.spindle_speed != gc_block.values.s) || bit_istrue(gc_parser_flags,GC_PARSER_LASER_FORCE_SYNC)) { + if (gc_state.modal.spindle != SPINDLE_DISABLE) { + #ifdef VARIABLE_SPINDLE + if (bit_isfalse(gc_parser_flags,GC_PARSER_LASER_ISMOTION)) { + if (bit_istrue(gc_parser_flags,GC_PARSER_LASER_DISABLE)) { + spindle_sync(gc_state.modal.spindle, 0.0); + } else { spindle_sync(gc_state.modal.spindle, gc_block.values.s); } + } + #else + spindle_sync(gc_state.modal.spindle, 0.0); + #endif + } + gc_state.spindle_speed = gc_block.values.s; // Update spindle speed state. + } + // NOTE: Pass zero spindle speed for all restricted laser motions. + if (bit_isfalse(gc_parser_flags,GC_PARSER_LASER_DISABLE)) { + pl_data->spindle_speed = gc_state.spindle_speed; // Record data for planner use. + } // else { pl_data->spindle_speed = 0.0; } // Initialized as zero already. + + // [5. Select tool ]: NOT SUPPORTED. Only tracks tool value. + gc_state.tool = gc_block.values.t; + + // [6. Change tool ]: NOT SUPPORTED + + // [7. Spindle control ]: + if (gc_state.modal.spindle != gc_block.modal.spindle) { + // Update spindle control and apply spindle speed when enabling it in this block. + // NOTE: All spindle state changes are synced, even in laser mode. Also, pl_data, + // rather than gc_state, is used to manage laser state for non-laser motions. + spindle_sync(gc_block.modal.spindle, pl_data->spindle_speed); + gc_state.modal.spindle = gc_block.modal.spindle; + } + pl_data->condition |= gc_state.modal.spindle; // Set condition flag for planner use. + + // [8. Coolant control ]: + if (gc_state.modal.coolant != gc_block.modal.coolant) { + // NOTE: Coolant M-codes are modal. Only one command per line is allowed. But, multiple states + // can exist at the same time, while coolant disable clears all states. + coolant_sync(gc_block.modal.coolant); + gc_state.modal.coolant = gc_block.modal.coolant; + } + pl_data->condition |= gc_state.modal.coolant; // Set condition flag for planner use. + + // [9. Override control ]: NOT SUPPORTED. Always enabled. Except for a Grbl-only parking control. + #ifdef ENABLE_PARKING_OVERRIDE_CONTROL + if (gc_state.modal.override != gc_block.modal.override) { + gc_state.modal.override = gc_block.modal.override; + mc_override_ctrl_update(gc_state.modal.override); + } + #endif + + // [10. Dwell ]: + if (gc_block.non_modal_command == NON_MODAL_DWELL) { mc_dwell(gc_block.values.p); } + + // [11. Set active plane ]: + gc_state.modal.plane_select = gc_block.modal.plane_select; + + // [12. Set length units ]: + gc_state.modal.units = gc_block.modal.units; + + // [13. Cutter radius compensation ]: G41/42 NOT SUPPORTED + // gc_state.modal.cutter_comp = gc_block.modal.cutter_comp; // NOTE: Not needed since always disabled. + + // [14. Cutter length compensation ]: G43.1 and G49 supported. G43 NOT SUPPORTED. + // NOTE: If G43 were supported, its operation wouldn't be any different from G43.1 in terms + // of execution. The error-checking step would simply load the offset value into the correct + // axis of the block XYZ value array. + if (axis_command == AXIS_COMMAND_TOOL_LENGTH_OFFSET ) { // Indicates a change. + gc_state.modal.tool_length = gc_block.modal.tool_length; + if (gc_state.modal.tool_length == TOOL_LENGTH_OFFSET_CANCEL) { // G49 + gc_block.values.xyz[TOOL_LENGTH_OFFSET_AXIS] = 0.0; + } // else G43.1 + if ( gc_state.tool_length_offset != gc_block.values.xyz[TOOL_LENGTH_OFFSET_AXIS] ) { + gc_state.tool_length_offset = gc_block.values.xyz[TOOL_LENGTH_OFFSET_AXIS]; + system_flag_wco_change(); + } + } + + // [15. Coordinate system selection ]: + if (gc_state.modal.coord_select != gc_block.modal.coord_select) { + gc_state.modal.coord_select = gc_block.modal.coord_select; + memcpy(gc_state.coord_system,block_coord_system,N_AXIS*sizeof(float)); + system_flag_wco_change(); + } + + // [16. Set path control mode ]: G61.1/G64 NOT SUPPORTED + // gc_state.modal.control = gc_block.modal.control; // NOTE: Always default. + + // [17. Set distance mode ]: + gc_state.modal.distance = gc_block.modal.distance; + + // [18. Set retract mode ]: NOT SUPPORTED + + // [19. Go to predefined position, Set G10, or Set axis offsets ]: + switch(gc_block.non_modal_command) { + case NON_MODAL_SET_COORDINATE_DATA: + settings_write_coord_data(coord_select,gc_block.values.ijk); + // Update system coordinate system if currently active. + if (gc_state.modal.coord_select == coord_select) { + memcpy(gc_state.coord_system,gc_block.values.ijk,N_AXIS*sizeof(float)); + system_flag_wco_change(); + } + break; + case NON_MODAL_GO_HOME_0: case NON_MODAL_GO_HOME_1: + // Move to intermediate position before going home. Obeys current coordinate system and offsets + // and absolute and incremental modes. + pl_data->condition |= PL_COND_FLAG_RAPID_MOTION; // Set rapid motion condition flag. + if (axis_command) { mc_line(gc_block.values.xyz, pl_data); } + mc_line(gc_block.values.ijk, pl_data); + memcpy(gc_state.position, gc_block.values.ijk, N_AXIS*sizeof(float)); + break; + case NON_MODAL_SET_HOME_0: + settings_write_coord_data(SETTING_INDEX_G28,gc_state.position); + break; + case NON_MODAL_SET_HOME_1: + settings_write_coord_data(SETTING_INDEX_G30,gc_state.position); + break; + case NON_MODAL_SET_COORDINATE_OFFSET: + memcpy(gc_state.coord_offset,gc_block.values.xyz,sizeof(gc_block.values.xyz)); + system_flag_wco_change(); + break; + case NON_MODAL_RESET_COORDINATE_OFFSET: + clear_vector(gc_state.coord_offset); // Disable G92 offsets by zeroing offset vector. + system_flag_wco_change(); + break; + } + + + // [20. Motion modes ]: + // NOTE: Commands G10,G28,G30,G92 lock out and prevent axis words from use in motion modes. + // Enter motion modes only if there are axis words or a motion mode command word in the block. + gc_state.modal.motion = gc_block.modal.motion; + if (gc_state.modal.motion != MOTION_MODE_NONE) { + if (axis_command == AXIS_COMMAND_MOTION_MODE) { + uint8_t gc_update_pos = GC_UPDATE_POS_TARGET; + if (gc_state.modal.motion == MOTION_MODE_LINEAR) { + mc_line(gc_block.values.xyz, pl_data); + } else if (gc_state.modal.motion == MOTION_MODE_SEEK) { + pl_data->condition |= PL_COND_FLAG_RAPID_MOTION; // Set rapid motion condition flag. + mc_line(gc_block.values.xyz, pl_data); + } else if ((gc_state.modal.motion == MOTION_MODE_CW_ARC) || (gc_state.modal.motion == MOTION_MODE_CCW_ARC)) { + mc_arc(gc_block.values.xyz, pl_data, gc_state.position, gc_block.values.ijk, gc_block.values.r, + axis_0, axis_1, axis_linear, bit_istrue(gc_parser_flags,GC_PARSER_ARC_IS_CLOCKWISE)); + } else { + // NOTE: gc_block.values.xyz is returned from mc_probe_cycle with the updated position value. So + // upon a successful probing cycle, the machine position and the returned value should be the same. + #ifndef ALLOW_FEED_OVERRIDE_DURING_PROBE_CYCLES + pl_data->condition |= PL_COND_FLAG_NO_FEED_OVERRIDE; + #endif + gc_update_pos = mc_probe_cycle(gc_block.values.xyz, pl_data, gc_parser_flags); + } + + // As far as the parser is concerned, the position is now == target. In reality the + // motion control system might still be processing the action and the real tool position + // in any intermediate location. + if (gc_update_pos == GC_UPDATE_POS_TARGET) { + memcpy(gc_state.position, gc_block.values.xyz, sizeof(gc_block.values.xyz)); // gc_state.position[] = gc_block.values.xyz[] + } else if (gc_update_pos == GC_UPDATE_POS_SYSTEM) { + gc_sync_position(); // gc_state.position[] = sys_position + } // == GC_UPDATE_POS_NONE + } + } + + // [21. Program flow ]: + // M0,M1,M2,M30: Perform non-running program flow actions. During a program pause, the buffer may + // refill and can only be resumed by the cycle start run-time command. + gc_state.modal.program_flow = gc_block.modal.program_flow; + if (gc_state.modal.program_flow) { + protocol_buffer_synchronize(); // Sync and finish all remaining buffered motions before moving on. + if (gc_state.modal.program_flow == PROGRAM_FLOW_PAUSED) { + if (sys.state != STATE_CHECK_MODE) { + system_set_exec_state_flag(EXEC_FEED_HOLD); // Use feed hold for program pause. + protocol_execute_realtime(); // Execute suspend. + } + } else { // == PROGRAM_FLOW_COMPLETED + // Upon program complete, only a subset of g-codes reset to certain defaults, according to + // LinuxCNC's program end descriptions and testing. Only modal groups [G-code 1,2,3,5,7,12] + // and [M-code 7,8,9] reset to [G1,G17,G90,G94,G40,G54,M5,M9,M48]. The remaining modal groups + // [G-code 4,6,8,10,13,14,15] and [M-code 4,5,6] and the modal words [F,S,T,H] do not reset. + gc_state.modal.motion = MOTION_MODE_LINEAR; + gc_state.modal.plane_select = PLANE_SELECT_XY; + gc_state.modal.distance = DISTANCE_MODE_ABSOLUTE; + gc_state.modal.feed_rate = FEED_RATE_MODE_UNITS_PER_MIN; + // gc_state.modal.cutter_comp = CUTTER_COMP_DISABLE; // Not supported. + gc_state.modal.coord_select = 0; // G54 + gc_state.modal.spindle = SPINDLE_DISABLE; + gc_state.modal.coolant = COOLANT_DISABLE; + #ifdef ENABLE_PARKING_OVERRIDE_CONTROL + #ifdef DEACTIVATE_PARKING_UPON_INIT + gc_state.modal.override = OVERRIDE_DISABLED; + #else + gc_state.modal.override = OVERRIDE_PARKING_MOTION; + #endif + #endif + + #ifdef RESTORE_OVERRIDES_AFTER_PROGRAM_END + sys.f_override = DEFAULT_FEED_OVERRIDE; + sys.r_override = DEFAULT_RAPID_OVERRIDE; + sys.spindle_speed_ovr = DEFAULT_SPINDLE_SPEED_OVERRIDE; + #endif + + // Execute coordinate change and spindle/coolant stop. + if (sys.state != STATE_CHECK_MODE) { + if (!(settings_read_coord_data(gc_state.modal.coord_select,gc_state.coord_system))) { FAIL(STATUS_SETTING_READ_FAIL); } + system_flag_wco_change(); // Set to refresh immediately just in case something altered. + spindle_set_state(SPINDLE_DISABLE,0.0); + coolant_set_state(COOLANT_DISABLE); + } + report_feedback_message(MESSAGE_PROGRAM_END); + } + gc_state.modal.program_flow = PROGRAM_FLOW_RUNNING; // Reset program flow. + } + + // TODO: % to denote start of program. + + return(STATUS_OK); +} + + +/* + Not supported: + + - Canned cycles + - Tool radius compensation + - A,B,C-axes + - Evaluation of expressions + - Variables + - Override control (TBD) + - Tool changes + - Switches + + (*) Indicates optional parameter, enabled through config.h and re-compile + group 0 = {G92.2, G92.3} (Non modal: Cancel and re-enable G92 offsets) + group 1 = {G81 - G89} (Motion modes: Canned cycles) + group 4 = {M1} (Optional stop, ignored) + group 6 = {M6} (Tool change) + group 7 = {G41, G42} cutter radius compensation (G40 is supported) + group 8 = {G43} tool length offset (G43.1/G49 are supported) + group 8 = {M7*} enable mist coolant (* Compile-option) + group 9 = {M48, M49, M56*} enable/disable override switches (* Compile-option) + group 10 = {G98, G99} return mode canned cycles + group 13 = {G61.1, G64} path control mode (G61 is supported) +*/ diff --git a/trunk/Arduino/GRBL_1.1f_Nano/gcode.h b/trunk/Arduino/GRBL_1.1f_Nano/gcode.h new file mode 100644 index 00000000..6cdc61b4 --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f_Nano/gcode.h @@ -0,0 +1,248 @@ +/* + gcode.h - rs274/ngc parser. + Part of Grbl + + Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC + Copyright (c) 2009-2011 Simen Svale Skogsrud + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +#ifndef gcode_h +#define gcode_h + + +// Define modal group internal numbers for checking multiple command violations and tracking the +// type of command that is called in the block. A modal group is a group of g-code commands that are +// mutually exclusive, or cannot exist on the same line, because they each toggle a state or execute +// a unique motion. These are defined in the NIST RS274-NGC v3 g-code standard, available online, +// and are similar/identical to other g-code interpreters by manufacturers (Haas,Fanuc,Mazak,etc). +// NOTE: Modal group define values must be sequential and starting from zero. +#define MODAL_GROUP_G0 0 // [G4,G10,G28,G28.1,G30,G30.1,G53,G92,G92.1] Non-modal +#define MODAL_GROUP_G1 1 // [G0,G1,G2,G3,G38.2,G38.3,G38.4,G38.5,G80] Motion +#define MODAL_GROUP_G2 2 // [G17,G18,G19] Plane selection +#define MODAL_GROUP_G3 3 // [G90,G91] Distance mode +#define MODAL_GROUP_G4 4 // [G91.1] Arc IJK distance mode +#define MODAL_GROUP_G5 5 // [G93,G94] Feed rate mode +#define MODAL_GROUP_G6 6 // [G20,G21] Units +#define MODAL_GROUP_G7 7 // [G40] Cutter radius compensation mode. G41/42 NOT SUPPORTED. +#define MODAL_GROUP_G8 8 // [G43.1,G49] Tool length offset +#define MODAL_GROUP_G12 9 // [G54,G55,G56,G57,G58,G59] Coordinate system selection +#define MODAL_GROUP_G13 10 // [G61] Control mode + +#define MODAL_GROUP_M4 11 // [M0,M1,M2,M30] Stopping +#define MODAL_GROUP_M7 12 // [M3,M4,M5] Spindle turning +#define MODAL_GROUP_M8 13 // [M7,M8,M9] Coolant control +#define MODAL_GROUP_M9 14 // [M56] Override control + +// Define command actions for within execution-type modal groups (motion, stopping, non-modal). Used +// internally by the parser to know which command to execute. +// NOTE: Some macro values are assigned specific values to make g-code state reporting and parsing +// compile a litte smaller. Necessary due to being completely out of flash on the 328p. Although not +// ideal, just be careful with values that state 'do not alter' and check both report.c and gcode.c +// to see how they are used, if you need to alter them. + +// Modal Group G0: Non-modal actions +#define NON_MODAL_NO_ACTION 0 // (Default: Must be zero) +#define NON_MODAL_DWELL 4 // G4 (Do not alter value) +#define NON_MODAL_SET_COORDINATE_DATA 10 // G10 (Do not alter value) +#define NON_MODAL_GO_HOME_0 28 // G28 (Do not alter value) +#define NON_MODAL_SET_HOME_0 38 // G28.1 (Do not alter value) +#define NON_MODAL_GO_HOME_1 30 // G30 (Do not alter value) +#define NON_MODAL_SET_HOME_1 40 // G30.1 (Do not alter value) +#define NON_MODAL_ABSOLUTE_OVERRIDE 53 // G53 (Do not alter value) +#define NON_MODAL_SET_COORDINATE_OFFSET 92 // G92 (Do not alter value) +#define NON_MODAL_RESET_COORDINATE_OFFSET 102 //G92.1 (Do not alter value) + +// Modal Group G1: Motion modes +#define MOTION_MODE_SEEK 0 // G0 (Default: Must be zero) +#define MOTION_MODE_LINEAR 1 // G1 (Do not alter value) +#define MOTION_MODE_CW_ARC 2 // G2 (Do not alter value) +#define MOTION_MODE_CCW_ARC 3 // G3 (Do not alter value) +#define MOTION_MODE_PROBE_TOWARD 140 // G38.2 (Do not alter value) +#define MOTION_MODE_PROBE_TOWARD_NO_ERROR 141 // G38.3 (Do not alter value) +#define MOTION_MODE_PROBE_AWAY 142 // G38.4 (Do not alter value) +#define MOTION_MODE_PROBE_AWAY_NO_ERROR 143 // G38.5 (Do not alter value) +#define MOTION_MODE_NONE 80 // G80 (Do not alter value) + +// Modal Group G2: Plane select +#define PLANE_SELECT_XY 0 // G17 (Default: Must be zero) +#define PLANE_SELECT_ZX 1 // G18 (Do not alter value) +#define PLANE_SELECT_YZ 2 // G19 (Do not alter value) + +// Modal Group G3: Distance mode +#define DISTANCE_MODE_ABSOLUTE 0 // G90 (Default: Must be zero) +#define DISTANCE_MODE_INCREMENTAL 1 // G91 (Do not alter value) + +// Modal Group G4: Arc IJK distance mode +#define DISTANCE_ARC_MODE_INCREMENTAL 0 // G91.1 (Default: Must be zero) + +// Modal Group M4: Program flow +#define PROGRAM_FLOW_RUNNING 0 // (Default: Must be zero) +#define PROGRAM_FLOW_PAUSED 3 // M0 +#define PROGRAM_FLOW_OPTIONAL_STOP 1 // M1 NOTE: Not supported, but valid and ignored. +#define PROGRAM_FLOW_COMPLETED_M2 2 // M2 (Do not alter value) +#define PROGRAM_FLOW_COMPLETED_M30 30 // M30 (Do not alter value) + +// Modal Group G5: Feed rate mode +#define FEED_RATE_MODE_UNITS_PER_MIN 0 // G94 (Default: Must be zero) +#define FEED_RATE_MODE_INVERSE_TIME 1 // G93 (Do not alter value) + +// Modal Group G6: Units mode +#define UNITS_MODE_MM 0 // G21 (Default: Must be zero) +#define UNITS_MODE_INCHES 1 // G20 (Do not alter value) + +// Modal Group G7: Cutter radius compensation mode +#define CUTTER_COMP_DISABLE 0 // G40 (Default: Must be zero) + +// Modal Group G13: Control mode +#define CONTROL_MODE_EXACT_PATH 0 // G61 (Default: Must be zero) + +// Modal Group M7: Spindle control +#define SPINDLE_DISABLE 0 // M5 (Default: Must be zero) +#define SPINDLE_ENABLE_CW PL_COND_FLAG_SPINDLE_CW // M3 (NOTE: Uses planner condition bit flag) +#define SPINDLE_ENABLE_CCW PL_COND_FLAG_SPINDLE_CCW // M4 (NOTE: Uses planner condition bit flag) + +// Modal Group M8: Coolant control +#define COOLANT_DISABLE 0 // M9 (Default: Must be zero) +#define COOLANT_FLOOD_ENABLE PL_COND_FLAG_COOLANT_FLOOD // M8 (NOTE: Uses planner condition bit flag) +#define COOLANT_MIST_ENABLE PL_COND_FLAG_COOLANT_MIST // M7 (NOTE: Uses planner condition bit flag) + +// Modal Group G8: Tool length offset +#define TOOL_LENGTH_OFFSET_CANCEL 0 // G49 (Default: Must be zero) +#define TOOL_LENGTH_OFFSET_ENABLE_DYNAMIC 1 // G43.1 + +// Modal Group M9: Override control +#ifdef DEACTIVATE_PARKING_UPON_INIT + #define OVERRIDE_DISABLED 0 // (Default: Must be zero) + #define OVERRIDE_PARKING_MOTION 1 // M56 +#else + #define OVERRIDE_PARKING_MOTION 0 // M56 (Default: Must be zero) + #define OVERRIDE_DISABLED 1 // Parking disabled. +#endif + +// Modal Group G12: Active work coordinate system +// N/A: Stores coordinate system value (54-59) to change to. + +// Define parameter word mapping. +#define WORD_F 0 +#define WORD_I 1 +#define WORD_J 2 +#define WORD_K 3 +#define WORD_L 4 +#define WORD_N 5 +#define WORD_P 6 +#define WORD_R 7 +#define WORD_S 8 +#define WORD_T 9 +#define WORD_X 10 +#define WORD_Y 11 +#define WORD_Z 12 + +// Define g-code parser position updating flags +#define GC_UPDATE_POS_TARGET 0 // Must be zero +#define GC_UPDATE_POS_SYSTEM 1 +#define GC_UPDATE_POS_NONE 2 + +// Define probe cycle exit states and assign proper position updating. +#define GC_PROBE_FOUND GC_UPDATE_POS_SYSTEM +#define GC_PROBE_ABORT GC_UPDATE_POS_NONE +#define GC_PROBE_FAIL_INIT GC_UPDATE_POS_NONE +#define GC_PROBE_FAIL_END GC_UPDATE_POS_TARGET +#ifdef SET_CHECK_MODE_PROBE_TO_START + #define GC_PROBE_CHECK_MODE GC_UPDATE_POS_NONE +#else + #define GC_PROBE_CHECK_MODE GC_UPDATE_POS_TARGET +#endif + +// Define gcode parser flags for handling special cases. +#define GC_PARSER_NONE 0 // Must be zero. +#define GC_PARSER_JOG_MOTION bit(0) +#define GC_PARSER_CHECK_MANTISSA bit(1) +#define GC_PARSER_ARC_IS_CLOCKWISE bit(2) +#define GC_PARSER_PROBE_IS_AWAY bit(3) +#define GC_PARSER_PROBE_IS_NO_ERROR bit(4) +#define GC_PARSER_LASER_FORCE_SYNC bit(5) +#define GC_PARSER_LASER_DISABLE bit(6) +#define GC_PARSER_LASER_ISMOTION bit(7) + + +// NOTE: When this struct is zeroed, the above defines set the defaults for the system. +typedef struct { + uint8_t motion; // {G0,G1,G2,G3,G38.2,G80} + uint8_t feed_rate; // {G93,G94} + uint8_t units; // {G20,G21} + uint8_t distance; // {G90,G91} + // uint8_t distance_arc; // {G91.1} NOTE: Don't track. Only default supported. + uint8_t plane_select; // {G17,G18,G19} + // uint8_t cutter_comp; // {G40} NOTE: Don't track. Only default supported. + uint8_t tool_length; // {G43.1,G49} + uint8_t coord_select; // {G54,G55,G56,G57,G58,G59} + // uint8_t control; // {G61} NOTE: Don't track. Only default supported. + uint8_t program_flow; // {M0,M1,M2,M30} + uint8_t coolant; // {M7,M8,M9} + uint8_t spindle; // {M3,M4,M5} + uint8_t override; // {M56} +} gc_modal_t; + +typedef struct { + float f; // Feed + float ijk[3]; // I,J,K Axis arc offsets + uint8_t l; // G10 or canned cycles parameters + int32_t n; // Line number + float p; // G10 or dwell parameters + // float q; // G82 peck drilling + float r; // Arc radius + float s; // Spindle speed + uint8_t t; // Tool selection + float xyz[3]; // X,Y,Z Translational axes +} gc_values_t; + + +typedef struct { + gc_modal_t modal; + + float spindle_speed; // RPM + float feed_rate; // Millimeters/min + uint8_t tool; // Tracks tool number. NOT USED. + int32_t line_number; // Last line number sent + + float position[N_AXIS]; // Where the interpreter considers the tool to be at this point in the code + + float coord_system[N_AXIS]; // Current work coordinate system (G54+). Stores offset from absolute machine + // position in mm. Loaded from EEPROM when called. + float coord_offset[N_AXIS]; // Retains the G92 coordinate offset (work coordinates) relative to + // machine zero in mm. Non-persistent. Cleared upon reset and boot. + float tool_length_offset; // Tracks tool length offset value when enabled. +} parser_state_t; +extern parser_state_t gc_state; + + +typedef struct { + uint8_t non_modal_command; + gc_modal_t modal; + gc_values_t values; +} parser_block_t; + + +// Initialize the parser +void gc_init(); + +// Execute one block of rs275/ngc/g-code +uint8_t gc_execute_line(char *line); + +// Set g-code parser position. Input in steps. +void gc_sync_position(); + +#endif diff --git a/trunk/Arduino/GRBL_1.1f_Nano/grbl.h b/trunk/Arduino/GRBL_1.1f_Nano/grbl.h new file mode 100644 index 00000000..f64f19e2 --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f_Nano/grbl.h @@ -0,0 +1,116 @@ +/* + grbl.h - main Grbl include file + Part of Grbl + + Copyright (c) 2015-2016 Sungeun K. Jeon for Gnea Research LLC + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +#ifndef grbl_h +#define grbl_h + +// Grbl versioning system +#define GRBL_VERSION "1.1g" +#define GRBL_VERSION_BUILD "20180614" + +// Define standard libraries used by Grbl. +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Define the Grbl system include files. NOTE: Do not alter organization. +#include "config.h" +#include "nuts_bolts.h" +#include "settings.h" +#include "system.h" +#include "defaults.h" +#include "cpu_map.h" +#include "planner.h" +#include "coolant_control.h" +#include "eeprom.h" +#include "gcode.h" +#include "limits.h" +#include "motion_control.h" +#include "planner.h" +#include "print.h" +#include "probe.h" +#include "protocol.h" +#include "report.h" +#include "serial.h" +#include "spindle_control.h" +#include "stepper.h" +#include "jog.h" + +// --------------------------------------------------------------------------------------- +// COMPILE-TIME ERROR CHECKING OF DEFINE VALUES: + +#ifndef HOMING_CYCLE_0 + #error "Required HOMING_CYCLE_0 not defined." +#endif + +#if defined(USE_SPINDLE_DIR_AS_ENABLE_PIN) && !defined(VARIABLE_SPINDLE) + #error "USE_SPINDLE_DIR_AS_ENABLE_PIN may only be used with VARIABLE_SPINDLE enabled" +#endif + +#if defined(USE_SPINDLE_DIR_AS_ENABLE_PIN) && !defined(CPU_MAP_ATMEGA328P) + #error "USE_SPINDLE_DIR_AS_ENABLE_PIN may only be used with a 328p processor" +#endif + +#if !defined(USE_SPINDLE_DIR_AS_ENABLE_PIN) && defined(SPINDLE_ENABLE_OFF_WITH_ZERO_SPEED) + #error "SPINDLE_ENABLE_OFF_WITH_ZERO_SPEED may only be used with USE_SPINDLE_DIR_AS_ENABLE_PIN enabled" +#endif + +#if defined(PARKING_ENABLE) + #if defined(HOMING_FORCE_SET_ORIGIN) + #error "HOMING_FORCE_SET_ORIGIN is not supported with PARKING_ENABLE at this time." + #endif +#endif + +#if defined(ENABLE_PARKING_OVERRIDE_CONTROL) + #if !defined(PARKING_ENABLE) + #error "ENABLE_PARKING_OVERRIDE_CONTROL must be enabled with PARKING_ENABLE." + #endif +#endif + +#if defined(SPINDLE_PWM_MIN_VALUE) + #if !(SPINDLE_PWM_MIN_VALUE > 0) + #error "SPINDLE_PWM_MIN_VALUE must be greater than zero." + #endif +#endif + +#if (REPORT_WCO_REFRESH_BUSY_COUNT < REPORT_WCO_REFRESH_IDLE_COUNT) + #error "WCO busy refresh is less than idle refresh." +#endif +#if (REPORT_OVR_REFRESH_BUSY_COUNT < REPORT_OVR_REFRESH_IDLE_COUNT) + #error "Override busy refresh is less than idle refresh." +#endif +#if (REPORT_WCO_REFRESH_IDLE_COUNT < 2) + #error "WCO refresh must be greater than one." +#endif +#if (REPORT_OVR_REFRESH_IDLE_COUNT < 1) + #error "Override refresh must be greater than zero." +#endif + +// --------------------------------------------------------------------------------------- + +#endif diff --git a/trunk/Arduino/GRBL_1.1f_Nano/jog.c b/trunk/Arduino/GRBL_1.1f_Nano/jog.c new file mode 100644 index 00000000..553af77e --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f_Nano/jog.c @@ -0,0 +1,50 @@ +/* + jog.h - Jogging methods + Part of Grbl + + Copyright (c) 2016 Sungeun K. Jeon for Gnea Research LLC + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +#include "grbl.h" + + +// Sets up valid jog motion received from g-code parser, checks for soft-limits, and executes the jog. +uint8_t jog_execute(plan_line_data_t *pl_data, parser_block_t *gc_block) +{ + // Initialize planner data struct for jogging motions. + // NOTE: Spindle and coolant are allowed to fully function with overrides during a jog. + pl_data->feed_rate = gc_block->values.f; + pl_data->condition |= PL_COND_FLAG_NO_FEED_OVERRIDE; + #ifdef USE_LINE_NUMBERS + pl_data->line_number = gc_block->values.n; + #endif + + if (bit_istrue(settings.flags,BITFLAG_SOFT_LIMIT_ENABLE)) { + if (system_check_travel_limits(gc_block->values.xyz)) { return(STATUS_TRAVEL_EXCEEDED); } + } + + // Valid jog command. Plan, set state, and execute. + mc_line(gc_block->values.xyz,pl_data); + if (sys.state == STATE_IDLE) { + if (plan_get_current_block() != NULL) { // Check if there is a block to execute. + sys.state = STATE_JOG; + st_prep_buffer(); + st_wake_up(); // NOTE: Manual start. No state machine required. + } + } + + return(STATUS_OK); +} diff --git a/trunk/Arduino/GRBL_1.1f_Nano/jog.h b/trunk/Arduino/GRBL_1.1f_Nano/jog.h new file mode 100644 index 00000000..c7262463 --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f_Nano/jog.h @@ -0,0 +1,32 @@ +/* + jog.h - Jogging methods + Part of Grbl + + Copyright (c) 2016 Sungeun K. Jeon for Gnea Research LLC + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +#ifndef jog_h +#define jog_h + +#include "gcode.h" + +// System motion line numbers must be zero. +#define JOG_LINE_NUMBER 0 + +// Sets up valid jog motion received from g-code parser, checks for soft-limits, and executes the jog. +uint8_t jog_execute(plan_line_data_t *pl_data, parser_block_t *gc_block); + +#endif diff --git a/trunk/Arduino/GRBL_1.1f_Nano/limits.c b/trunk/Arduino/GRBL_1.1f_Nano/limits.c new file mode 100644 index 00000000..3cc2556b --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f_Nano/limits.c @@ -0,0 +1,360 @@ +/* + limits.c - code pertaining to limit-switches and performing the homing cycle + Part of Grbl + + Copyright (c) 2012-2016 Sungeun K. Jeon for Gnea Research LLC + Copyright (c) 2009-2011 Simen Svale Skogsrud + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +#include "grbl.h" + + +// Homing axis search distance multiplier. Computed by this value times the cycle travel. +#ifndef HOMING_AXIS_SEARCH_SCALAR + #define HOMING_AXIS_SEARCH_SCALAR 1.5 // Must be > 1 to ensure limit switch will be engaged. +#endif +#ifndef HOMING_AXIS_LOCATE_SCALAR + #define HOMING_AXIS_LOCATE_SCALAR 5.0 // Must be > 1 to ensure limit switch is cleared. +#endif + +void limits_init() +{ + LIMIT_DDR &= ~(LIMIT_MASK); // Set as input pins + + #ifdef DISABLE_LIMIT_PIN_PULL_UP + LIMIT_PORT &= ~(LIMIT_MASK); // Normal low operation. Requires external pull-down. + #else + LIMIT_PORT |= (LIMIT_MASK); // Enable internal pull-up resistors. Normal high operation. + #endif + + if (bit_istrue(settings.flags,BITFLAG_HARD_LIMIT_ENABLE)) { + LIMIT_PCMSK |= LIMIT_MASK; // Enable specific pins of the Pin Change Interrupt + PCICR |= (1 << LIMIT_INT); // Enable Pin Change Interrupt + } else { + limits_disable(); + } + + #ifdef ENABLE_SOFTWARE_DEBOUNCE + MCUSR &= ~(1<condition = (PL_COND_FLAG_SYSTEM_MOTION|PL_COND_FLAG_NO_FEED_OVERRIDE); + #ifdef USE_LINE_NUMBERS + pl_data->line_number = HOMING_CYCLE_LINE_NUMBER; + #endif + + // Initialize variables used for homing computations. + uint8_t n_cycle = (2*N_HOMING_LOCATE_CYCLE+1); + uint8_t step_pin[N_AXIS]; + float target[N_AXIS]; + float max_travel = 0.0; + uint8_t idx; + for (idx=0; idxfeed_rate = homing_rate; // Set current homing rate. + plan_buffer_line(target, pl_data); // Bypass mc_line(). Directly plan homing motion. + + sys.step_control = STEP_CONTROL_EXECUTE_SYS_MOTION; // Set to execute homing motion and clear existing flags. + st_prep_buffer(); // Prep and fill segment buffer from newly planned block. + st_wake_up(); // Initiate motion + do { + if (approach) { + // Check limit state. Lock out cycle axes when they change. + limit_state = limits_get_state(); + for (idx=0; idx 0); + + // The active cycle axes should now be homed and machine limits have been located. By + // default, Grbl defines machine space as all negative, as do most CNCs. Since limit switches + // can be on either side of an axes, check and set axes machine zero appropriately. Also, + // set up pull-off maneuver from axes limit switches that have been homed. This provides + // some initial clearance off the switches and should also help prevent them from falsely + // triggering when hard limits are enabled or when more than one axes shares a limit pin. + int32_t set_axis_position; + // Set machine positions for homed limit switches. Don't update non-homed axes. + for (idx=0; idx. +*/ + +#ifndef limits_h +#define limits_h + + +// Initialize the limits module +void limits_init(); + +// Disables hard limits. +void limits_disable(); + +// Returns limit state as a bit-wise uint8 variable. +uint8_t limits_get_state(); + +// Perform one portion of the homing cycle based on the input settings. +void limits_go_home(uint8_t cycle_mask); + +// Check for soft limit violations +void limits_soft_check(float *target); + +#endif diff --git a/trunk/Arduino/GRBL_1.1f_Nano/main.c b/trunk/Arduino/GRBL_1.1f_Nano/main.c new file mode 100644 index 00000000..96f2abae --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f_Nano/main.c @@ -0,0 +1,109 @@ +/* + main.c - An embedded CNC Controller with rs274/ngc (g-code) support + Part of Grbl + + Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC + Copyright (c) 2009-2011 Simen Svale Skogsrud + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +#include "grbl.h" + + +// Declare system global variable structure +system_t sys; +int32_t sys_position[N_AXIS]; // Real-time machine (aka home) position vector in steps. +int32_t sys_probe_position[N_AXIS]; // Last probe position in machine coordinates and steps. +volatile uint8_t sys_probe_state; // Probing state value. Used to coordinate the probing cycle with stepper ISR. +volatile uint8_t sys_rt_exec_state; // Global realtime executor bitflag variable for state management. See EXEC bitmasks. +volatile uint8_t sys_rt_exec_alarm; // Global realtime executor bitflag variable for setting various alarms. +volatile uint8_t sys_rt_exec_motion_override; // Global realtime executor bitflag variable for motion-based overrides. +volatile uint8_t sys_rt_exec_accessory_override; // Global realtime executor bitflag variable for spindle/coolant overrides. +#ifdef DEBUG + volatile uint8_t sys_rt_exec_debug; +#endif + + +int main(void) +{ + // Initialize system upon power-up. + serial_init(); // Setup serial baud rate and interrupts + settings_init(); // Load Grbl settings from EEPROM + stepper_init(); // Configure stepper pins and interrupt timers + system_init(); // Configure pinout pins and pin-change interrupt + + memset(sys_position,0,sizeof(sys_position)); // Clear machine position. + sei(); // Enable interrupts + + // Initialize system state. + #ifdef FORCE_INITIALIZATION_ALARM + // Force Grbl into an ALARM state upon a power-cycle or hard reset. + sys.state = STATE_ALARM; + #else + sys.state = STATE_IDLE; + #endif + + // Check for power-up and set system alarm if homing is enabled to force homing cycle + // by setting Grbl's alarm state. Alarm locks out all g-code commands, including the + // startup scripts, but allows access to settings and internal commands. Only a homing + // cycle '$H' or kill alarm locks '$X' will disable the alarm. + // NOTE: The startup script will run after successful completion of the homing cycle, but + // not after disabling the alarm locks. Prevents motion startup blocks from crashing into + // things uncontrollably. Very bad. + #ifdef HOMING_INIT_LOCK + if (bit_istrue(settings.flags,BITFLAG_HOMING_ENABLE)) { sys.state = STATE_ALARM; } + #endif + + // Grbl initialization loop upon power-up or a system abort. For the latter, all processes + // will return to this loop to be cleanly re-initialized. + for(;;) { + + // Reset system variables. + uint8_t prior_state = sys.state; + memset(&sys, 0, sizeof(system_t)); // Clear system struct variable. + sys.state = prior_state; + sys.f_override = DEFAULT_FEED_OVERRIDE; // Set to 100% + sys.r_override = DEFAULT_RAPID_OVERRIDE; // Set to 100% + sys.spindle_speed_ovr = DEFAULT_SPINDLE_SPEED_OVERRIDE; // Set to 100% + memset(sys_probe_position,0,sizeof(sys_probe_position)); // Clear probe position. + sys_probe_state = 0; + sys_rt_exec_state = 0; + sys_rt_exec_alarm = 0; + sys_rt_exec_motion_override = 0; + sys_rt_exec_accessory_override = 0; + + // Reset Grbl primary systems. + serial_reset_read_buffer(); // Clear serial read buffer + gc_init(); // Set g-code parser to default state + spindle_init(); + coolant_init(); + limits_init(); + probe_init(); + plan_reset(); // Clear block buffer and planner variables + st_reset(); // Clear stepper subsystem variables. + + // Sync cleared gcode and planner positions to current system position. + plan_sync_position(); + gc_sync_position(); + + // Print welcome message. Indicates an initialization has occured at power-up or with a reset. + report_init_message(); + + // Start Grbl main loop. Processes program inputs and executes them. + protocol_main_loop(); + + } + return 0; /* Never reached */ +} diff --git a/trunk/Arduino/GRBL_1.1f_Nano/makefile b/trunk/Arduino/GRBL_1.1f_Nano/makefile new file mode 100644 index 00000000..d0170a5a --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f_Nano/makefile @@ -0,0 +1,130 @@ +# Arduino Make file. Refer to https://github.com/sudar/Arduino-Makefile +# + +BOARD_TAG = uno +include ../paths.mk +include ../Arduino.mk + +# --- leonardo (or pro micro w/leo bootloader) +#BOARD_TAG = leonardo +#MONITOR_PORT = /dev/ttyACM0 +#include /usr/share/arduino/Arduino.mk + +# --- mega2560 ide 1.0 +#BOARD_TAG = mega2560 +#ARDUINO_PORT = /dev/ttyACM0 +#include /usr/share/arduino/Arduino.mk + +# --- mega2560 ide 1.6 +#BOARD_TAG = mega +#BOARD_SUB = atmega2560 +#MONITOR_PORT = /dev/ttyACM0 +#ARDUINO_DIR = /where/you/installed/arduino-1.6.5 +#include /usr/share/arduino/Arduino.mk + +# --- nano ide 1.0 +#BOARD_TAG = nano328 +#MONITOR_PORT = /dev/ttyUSB0 +#include /usr/share/arduino/Arduino.mk + +# --- nano ide 1.6 +#BOARD_TAG = nano +#BOARD_SUB = atmega328 +#ARDUINO_DIR = /where/you/installed/arduino-1.6.5 +#include /usr/share/arduino/Arduino.mk + +# --- pro mini +#BOARD_TAG = pro5v328 +#MONITOR_PORT = /dev/ttyUSB0 +#include /usr/share/arduino/Arduino.mk + +# --- sparkfun pro micro +#BOARD_TAG = promicro16 +#ALTERNATE_CORE = promicro +#BOARDS_TXT = $(HOME)/arduino/hardware/promicro/boards.txt +#BOOTLOADER_PARENT = $(HOME)/arduino/hardware/promicro/bootloaders +#BOOTLOADER_PATH = caterina +#BOOTLOADER_FILE = Caterina-promicro16.hex +#ISP_PROG = usbasp +#AVRDUDE_OPTS = -v +#include /usr/share/arduino/Arduino.mk + +# --- chipkit +#BOARD_TAG = mega_pic32 +#MPIDE_DIR = /where/you/installed/mpide-0023-linux64-20130817-test +#include /usr/share/arduino/chipKIT.mk + +# --- pinoccio +#BOARD_TAG = pinoccio256 +#ALTERNATE_CORE = pinoccio +#BOOTLOADER_PARENT = $(HOME)/arduino/hardware/pinoccio/bootloaders +#BOOTLOADER_PATH = STK500RFR2/release_0.51 +#BOOTLOADER_FILE = boot_pinoccio.hex +#CFLAGS_STD = -std=gnu99 +#CXXFLAGS_STD = -std=gnu++11 +#include /usr/share/arduino/Arduino.mk + +# --- fio +#BOARD_TAG = fio +#include /usr/share/arduino/Arduino.mk + +# --- atmega-ng ide 1.6 +#BOARD_TAG = atmegang +#BOARD_SUB = atmega168 +#MONITOR_PORT = /dev/ttyACM0 +#ARDUINO_DIR = /where/you/installed/arduino-1.6.5 +#include /usr/share/arduino/Arduino.mk + +# --- arduino-tiny ide 1.0 +#ISP_PROG = usbasp +#BOARD_TAG = attiny85at8 +#ALTERNATE_CORE = tiny +#ARDUINO_VAR_PATH = $(HOME)/arduino/hardware/tiny/cores/tiny +#ARDUINO_CORE_PATH = $(HOME)/arduino/hardware/tiny/cores/tiny +#AVRDUDE_OPTS = -v +#include /usr/share/arduino/Arduino.mk + +# --- arduino-tiny ide 1.6 +#ISP_PROG = usbasp +#BOARD_TAG = attiny85at8 +#ALTERNATE_CORE = tiny +#ARDUINO_DIR = /where/you/installed/arduino-1.6.5 +#include /usr/share/arduino/Arduino.mk + +# --- damellis attiny ide 1.0 +#ISP_PROG = usbasp +#BOARD_TAG = attiny85 +#ALTERNATE_CORE = attiny-master +#AVRDUDE_OPTS = -v +#include /usr/share/arduino/Arduino.mk + +# --- damellis attiny ide 1.6 +#ISP_PROG = usbasp +#BOARD_TAG = attiny +#BOARD_SUB = attiny85 +#ALTERNATE_CORE = attiny +#F_CPU = 16000000L +#ARDUINO_DIR = /where/you/installed/arduino-1.6.5 +#include /usr/share/arduino/Arduino.mk + +# --- teensy3 +#BOARD_TAG = teensy31 +#ARDUINO_DIR = /where/you/installed/the/patched/teensy/arduino-1.0.6 +#include /usr/share/arduino/Teensy.mk + +# --- mighty 1284p +#BOARD_TAG = mighty_opt +#BOARDS_TXT = $(HOME)/arduino/hardware/mighty-1284p/boards.txt +#BOOTLOADER_PARENT = $(HOME)/arduino/hardware/mighty-1284p/bootloaders +#BOOTLOADER_PATH = optiboot +#BOOTLOADER_FILE = optiboot_atmega1284p.hex +#ISP_PROG = usbasp +#AVRDUDE_OPTS = -v +#include /usr/share/arduino/Arduino.mk + +# --- atmega328p on breadboard +#BOARD_TAG = atmega328bb +#ISP_PROG = usbasp +#AVRDUDE_OPTS = -v +#BOARDS_TXT = $(HOME)/arduino/hardware/breadboard/boards.txt +#include /usr/share/arduino/Arduino.mk diff --git a/trunk/Arduino/GRBL_1.1f_Nano/motion_control.c b/trunk/Arduino/GRBL_1.1f_Nano/motion_control.c new file mode 100644 index 00000000..6e11e35c --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f_Nano/motion_control.c @@ -0,0 +1,388 @@ +/* + motion_control.c - high level interface for issuing motion commands + Part of Grbl + + Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC + Copyright (c) 2009-2011 Simen Svale Skogsrud + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +#include "grbl.h" + + +// Execute linear motion in absolute millimeter coordinates. Feed rate given in millimeters/second +// unless invert_feed_rate is true. Then the feed_rate means that the motion should be completed in +// (1 minute)/feed_rate time. +// NOTE: This is the primary gateway to the grbl planner. All line motions, including arc line +// segments, must pass through this routine before being passed to the planner. The seperation of +// mc_line and plan_buffer_line is done primarily to place non-planner-type functions from being +// in the planner and to let backlash compensation or canned cycle integration simple and direct. +void mc_line(float *target, plan_line_data_t *pl_data) +{ + // If enabled, check for soft limit violations. Placed here all line motions are picked up + // from everywhere in Grbl. + if (bit_istrue(settings.flags,BITFLAG_SOFT_LIMIT_ENABLE)) { + // NOTE: Block jog state. Jogging is a special case and soft limits are handled independently. + if (sys.state != STATE_JOG) { limits_soft_check(target); } + } + + // If in check gcode mode, prevent motion by blocking planner. Soft limits still work. + if (sys.state == STATE_CHECK_MODE) { return; } + + // NOTE: Backlash compensation may be installed here. It will need direction info to track when + // to insert a backlash line motion(s) before the intended line motion and will require its own + // plan_check_full_buffer() and check for system abort loop. Also for position reporting + // backlash steps will need to be also tracked, which will need to be kept at a system level. + // There are likely some other things that will need to be tracked as well. However, we feel + // that backlash compensation should NOT be handled by Grbl itself, because there are a myriad + // of ways to implement it and can be effective or ineffective for different CNC machines. This + // would be better handled by the interface as a post-processor task, where the original g-code + // is translated and inserts backlash motions that best suits the machine. + // NOTE: Perhaps as a middle-ground, all that needs to be sent is a flag or special command that + // indicates to Grbl what is a backlash compensation motion, so that Grbl executes the move but + // doesn't update the machine position values. Since the position values used by the g-code + // parser and planner are separate from the system machine positions, this is doable. + + // If the buffer is full: good! That means we are well ahead of the robot. + // Remain in this loop until there is room in the buffer. + do { + protocol_execute_realtime(); // Check for any run-time commands + if (sys.abort) { return; } // Bail, if system abort. + if ( plan_check_full_buffer() ) { protocol_auto_cycle_start(); } // Auto-cycle start when buffer is full. + else { break; } + } while (1); + + // Plan and queue motion into planner buffer + if (plan_buffer_line(target, pl_data) == PLAN_EMPTY_BLOCK) { + if (bit_istrue(settings.flags,BITFLAG_LASER_MODE)) { + // Correctly set spindle state, if there is a coincident position passed. Forces a buffer + // sync while in M3 laser mode only. + if (pl_data->condition & PL_COND_FLAG_SPINDLE_CW) { + spindle_sync(PL_COND_FLAG_SPINDLE_CW, pl_data->spindle_speed); + } + } + } +} + + +// Execute an arc in offset mode format. position == current xyz, target == target xyz, +// offset == offset from current xyz, axis_X defines circle plane in tool space, axis_linear is +// the direction of helical travel, radius == circle radius, isclockwise boolean. Used +// for vector transformation direction. +// The arc is approximated by generating a huge number of tiny, linear segments. The chordal tolerance +// of each segment is configured in settings.arc_tolerance, which is defined to be the maximum normal +// distance from segment to the circle when the end points both lie on the circle. +void mc_arc(float *target, plan_line_data_t *pl_data, float *position, float *offset, float radius, + uint8_t axis_0, uint8_t axis_1, uint8_t axis_linear, uint8_t is_clockwise_arc) +{ + float center_axis0 = position[axis_0] + offset[axis_0]; + float center_axis1 = position[axis_1] + offset[axis_1]; + float r_axis0 = -offset[axis_0]; // Radius vector from center to current location + float r_axis1 = -offset[axis_1]; + float rt_axis0 = target[axis_0] - center_axis0; + float rt_axis1 = target[axis_1] - center_axis1; + + // CCW angle between position and target from circle center. Only one atan2() trig computation required. + float angular_travel = atan2(r_axis0*rt_axis1-r_axis1*rt_axis0, r_axis0*rt_axis0+r_axis1*rt_axis1); + if (is_clockwise_arc) { // Correct atan2 output per direction + if (angular_travel >= -ARC_ANGULAR_TRAVEL_EPSILON) { angular_travel -= 2*M_PI; } + } else { + if (angular_travel <= ARC_ANGULAR_TRAVEL_EPSILON) { angular_travel += 2*M_PI; } + } + + // NOTE: Segment end points are on the arc, which can lead to the arc diameter being smaller by up to + // (2x) settings.arc_tolerance. For 99% of users, this is just fine. If a different arc segment fit + // is desired, i.e. least-squares, midpoint on arc, just change the mm_per_arc_segment calculation. + // For the intended uses of Grbl, this value shouldn't exceed 2000 for the strictest of cases. + uint16_t segments = floor(fabs(0.5*angular_travel*radius)/ + sqrt(settings.arc_tolerance*(2*radius - settings.arc_tolerance)) ); + + if (segments) { + // Multiply inverse feed_rate to compensate for the fact that this movement is approximated + // by a number of discrete segments. The inverse feed_rate should be correct for the sum of + // all segments. + if (pl_data->condition & PL_COND_FLAG_INVERSE_TIME) { + pl_data->feed_rate *= segments; + bit_false(pl_data->condition,PL_COND_FLAG_INVERSE_TIME); // Force as feed absolute mode over arc segments. + } + + float theta_per_segment = angular_travel/segments; + float linear_per_segment = (target[axis_linear] - position[axis_linear])/segments; + + /* Vector rotation by transformation matrix: r is the original vector, r_T is the rotated vector, + and phi is the angle of rotation. Solution approach by Jens Geisler. + r_T = [cos(phi) -sin(phi); + sin(phi) cos(phi] * r ; + + For arc generation, the center of the circle is the axis of rotation and the radius vector is + defined from the circle center to the initial position. Each line segment is formed by successive + vector rotations. Single precision values can accumulate error greater than tool precision in rare + cases. So, exact arc path correction is implemented. This approach avoids the problem of too many very + expensive trig operations [sin(),cos(),tan()] which can take 100-200 usec each to compute. + + Small angle approximation may be used to reduce computation overhead further. A third-order approximation + (second order sin() has too much error) holds for most, if not, all CNC applications. Note that this + approximation will begin to accumulate a numerical drift error when theta_per_segment is greater than + ~0.25 rad(14 deg) AND the approximation is successively used without correction several dozen times. This + scenario is extremely unlikely, since segment lengths and theta_per_segment are automatically generated + and scaled by the arc tolerance setting. Only a very large arc tolerance setting, unrealistic for CNC + applications, would cause this numerical drift error. However, it is best to set N_ARC_CORRECTION from a + low of ~4 to a high of ~20 or so to avoid trig operations while keeping arc generation accurate. + + This approximation also allows mc_arc to immediately insert a line segment into the planner + without the initial overhead of computing cos() or sin(). By the time the arc needs to be applied + a correction, the planner should have caught up to the lag caused by the initial mc_arc overhead. + This is important when there are successive arc motions. + */ + // Computes: cos_T = 1 - theta_per_segment^2/2, sin_T = theta_per_segment - theta_per_segment^3/6) in ~52usec + float cos_T = 2.0 - theta_per_segment*theta_per_segment; + float sin_T = theta_per_segment*0.16666667*(cos_T + 4.0); + cos_T *= 0.5; + + float sin_Ti; + float cos_Ti; + float r_axisi; + uint16_t i; + uint8_t count = 0; + + for (i = 1; i. +*/ + +#ifndef motion_control_h +#define motion_control_h + + +// System motion commands must have a line number of zero. +#define HOMING_CYCLE_LINE_NUMBER 0 +#define PARKING_MOTION_LINE_NUMBER 0 + +#define HOMING_CYCLE_ALL 0 // Must be zero. +#define HOMING_CYCLE_X bit(X_AXIS) +#define HOMING_CYCLE_Y bit(Y_AXIS) +#define HOMING_CYCLE_Z bit(Z_AXIS) + + +// Execute linear motion in absolute millimeter coordinates. Feed rate given in millimeters/second +// unless invert_feed_rate is true. Then the feed_rate means that the motion should be completed in +// (1 minute)/feed_rate time. +void mc_line(float *target, plan_line_data_t *pl_data); + +// Execute an arc in offset mode format. position == current xyz, target == target xyz, +// offset == offset from current xyz, axis_XXX defines circle plane in tool space, axis_linear is +// the direction of helical travel, radius == circle radius, is_clockwise_arc boolean. Used +// for vector transformation direction. +void mc_arc(float *target, plan_line_data_t *pl_data, float *position, float *offset, float radius, + uint8_t axis_0, uint8_t axis_1, uint8_t axis_linear, uint8_t is_clockwise_arc); + +// Dwell for a specific number of seconds +void mc_dwell(float seconds); + +// Perform homing cycle to locate machine zero. Requires limit switches. +void mc_homing_cycle(uint8_t cycle_mask); + +// Perform tool length probe cycle. Requires probe switch. +uint8_t mc_probe_cycle(float *target, plan_line_data_t *pl_data, uint8_t parser_flags); + +// Handles updating the override control state. +void mc_override_ctrl_update(uint8_t override_state); + +// Plans and executes the single special motion case for parking. Independent of main planner buffer. +void mc_parking_motion(float *parking_target, plan_line_data_t *pl_data); + +// Performs system reset. If in motion state, kills all motion and sets system alarm. +void mc_reset(); + +#endif diff --git a/trunk/Arduino/GRBL_1.1f_Nano/nuts_bolts.c b/trunk/Arduino/GRBL_1.1f_Nano/nuts_bolts.c new file mode 100644 index 00000000..9d89a8d0 --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f_Nano/nuts_bolts.c @@ -0,0 +1,190 @@ +/* + nuts_bolts.c - Shared functions + Part of Grbl + + Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC + Copyright (c) 2009-2011 Simen Svale Skogsrud + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +#include "grbl.h" + + +#define MAX_INT_DIGITS 8 // Maximum number of digits in int32 (and float) + + +// Extracts a floating point value from a string. The following code is based loosely on +// the avr-libc strtod() function by Michael Stumpf and Dmitry Xmelkov and many freely +// available conversion method examples, but has been highly optimized for Grbl. For known +// CNC applications, the typical decimal value is expected to be in the range of E0 to E-4. +// Scientific notation is officially not supported by g-code, and the 'E' character may +// be a g-code word on some CNC systems. So, 'E' notation will not be recognized. +// NOTE: Thanks to Radu-Eosif Mihailescu for identifying the issues with using strtod(). +uint8_t read_float(char *line, uint8_t *char_counter, float *float_ptr) +{ + char *ptr = line + *char_counter; + unsigned char c; + + // Grab first character and increment pointer. No spaces assumed in line. + c = *ptr++; + + // Capture initial positive/minus character + bool isnegative = false; + if (c == '-') { + isnegative = true; + c = *ptr++; + } else if (c == '+') { + c = *ptr++; + } + + // Extract number into fast integer. Track decimal in terms of exponent value. + uint32_t intval = 0; + int8_t exp = 0; + uint8_t ndigit = 0; + bool isdecimal = false; + while(1) { + c -= '0'; + if (c <= 9) { + ndigit++; + if (ndigit <= MAX_INT_DIGITS) { + if (isdecimal) { exp--; } + intval = (((intval << 2) + intval) << 1) + c; // intval*10 + c + } else { + if (!(isdecimal)) { exp++; } // Drop overflow digits + } + } else if (c == (('.'-'0') & 0xff) && !(isdecimal)) { + isdecimal = true; + } else { + break; + } + c = *ptr++; + } + + // Return if no digits have been read. + if (!ndigit) { return(false); }; + + // Convert integer into floating point. + float fval; + fval = (float)intval; + + // Apply decimal. Should perform no more than two floating point multiplications for the + // expected range of E0 to E-4. + if (fval != 0) { + while (exp <= -2) { + fval *= 0.01; + exp += 2; + } + if (exp < 0) { + fval *= 0.1; + } else if (exp > 0) { + do { + fval *= 10.0; + } while (--exp > 0); + } + } + + // Assign floating point value with correct sign. + if (isnegative) { + *float_ptr = -fval; + } else { + *float_ptr = fval; + } + + *char_counter = ptr - line - 1; // Set char_counter to next statement + + return(true); +} + + +// Non-blocking delay function used for general operation and suspend features. +void delay_sec(float seconds, uint8_t mode) +{ + uint16_t i = ceil(1000/DWELL_TIME_STEP*seconds); + while (i-- > 0) { + if (sys.abort) { return; } + if (mode == DELAY_MODE_DWELL) { + protocol_execute_realtime(); + } else { // DELAY_MODE_SYS_SUSPEND + // Execute rt_system() only to avoid nesting suspend loops. + protocol_exec_rt_system(); + if (sys.suspend & SUSPEND_RESTART_RETRACT) { return; } // Bail, if safety door reopens. + } + _delay_ms(DWELL_TIME_STEP); // Delay DWELL_TIME_STEP increment + } +} + + +// Delays variable defined milliseconds. Compiler compatibility fix for _delay_ms(), +// which only accepts constants in future compiler releases. +void delay_ms(uint16_t ms) +{ + while ( ms-- ) { _delay_ms(1); } +} + + +// Delays variable defined microseconds. Compiler compatibility fix for _delay_us(), +// which only accepts constants in future compiler releases. Written to perform more +// efficiently with larger delays, as the counter adds parasitic time in each iteration. +void delay_us(uint32_t us) +{ + while (us) { + if (us < 10) { + _delay_us(1); + us--; + } else if (us < 100) { + _delay_us(10); + us -= 10; + } else if (us < 1000) { + _delay_us(100); + us -= 100; + } else { + _delay_ms(1); + us -= 1000; + } + } +} + + +// Simple hypotenuse computation function. +float hypot_f(float x, float y) { return(sqrt(x*x + y*y)); } + + +float convert_delta_vector_to_unit_vector(float *vector) +{ + uint8_t idx; + float magnitude = 0.0; + for (idx=0; idx. +*/ + +#ifndef nuts_bolts_h +#define nuts_bolts_h + +#define false 0 +#define true 1 + +#define SOME_LARGE_VALUE 1.0E+38 + +// Axis array index values. Must start with 0 and be continuous. +#define N_AXIS 3 // Number of axes +#define X_AXIS 0 // Axis indexing value. +#define Y_AXIS 1 +#define Z_AXIS 2 +// #define A_AXIS 3 + +// CoreXY motor assignments. DO NOT ALTER. +// NOTE: If the A and B motor axis bindings are changed, this effects the CoreXY equations. +#ifdef COREXY + #define A_MOTOR X_AXIS // Must be X_AXIS + #define B_MOTOR Y_AXIS // Must be Y_AXIS +#endif + +// Conversions +#define MM_PER_INCH (25.40) +#define INCH_PER_MM (0.0393701) +#define TICKS_PER_MICROSECOND (F_CPU/1000000) + +#define DELAY_MODE_DWELL 0 +#define DELAY_MODE_SYS_SUSPEND 1 + +// Useful macros +#define clear_vector(a) memset(a, 0, sizeof(a)) +#define clear_vector_float(a) memset(a, 0.0, sizeof(float)*N_AXIS) +// #define clear_vector_long(a) memset(a, 0.0, sizeof(long)*N_AXIS) +#define max(a,b) (((a) > (b)) ? (a) : (b)) +#define min(a,b) (((a) < (b)) ? (a) : (b)) +#define isequal_position_vector(a,b) !(memcmp(a, b, sizeof(float)*N_AXIS)) + +// Bit field and masking macros +#define bit(n) (1 << n) +#define bit_true(x,mask) (x) |= (mask) +#define bit_false(x,mask) (x) &= ~(mask) +#define bit_istrue(x,mask) ((x & mask) != 0) +#define bit_isfalse(x,mask) ((x & mask) == 0) + +// Read a floating point value from a string. Line points to the input buffer, char_counter +// is the indexer pointing to the current character of the line, while float_ptr is +// a pointer to the result variable. Returns true when it succeeds +uint8_t read_float(char *line, uint8_t *char_counter, float *float_ptr); + +// Non-blocking delay function used for general operation and suspend features. +void delay_sec(float seconds, uint8_t mode); + +// Delays variable-defined milliseconds. Compiler compatibility fix for _delay_ms(). +void delay_ms(uint16_t ms); + +// Delays variable-defined microseconds. Compiler compatibility fix for _delay_us(). +void delay_us(uint32_t us); + +// Computes hypotenuse, avoiding avr-gcc's bloated version and the extra error checking. +float hypot_f(float x, float y); + +float convert_delta_vector_to_unit_vector(float *vector); +float limit_value_by_axis_maximum(float *max_value, float *unit_vec); + +#endif diff --git a/trunk/Arduino/GRBL_1.1f_Nano/planner.c b/trunk/Arduino/GRBL_1.1f_Nano/planner.c new file mode 100644 index 00000000..4839bbf4 --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f_Nano/planner.c @@ -0,0 +1,522 @@ +/* + planner.c - buffers movement commands and manages the acceleration profile plan + Part of Grbl + + Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC + Copyright (c) 2009-2011 Simen Svale Skogsrud + Copyright (c) 2011 Jens Geisler + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +#include "grbl.h" + + +static plan_block_t block_buffer[BLOCK_BUFFER_SIZE]; // A ring buffer for motion instructions +static uint8_t block_buffer_tail; // Index of the block to process now +static uint8_t block_buffer_head; // Index of the next block to be pushed +static uint8_t next_buffer_head; // Index of the next buffer head +static uint8_t block_buffer_planned; // Index of the optimally planned block + +// Define planner variables +typedef struct { + int32_t position[N_AXIS]; // The planner position of the tool in absolute steps. Kept separate + // from g-code position for movements requiring multiple line motions, + // i.e. arcs, canned cycles, and backlash compensation. + float previous_unit_vec[N_AXIS]; // Unit vector of previous path line segment + float previous_nominal_speed; // Nominal speed of previous path line segment +} planner_t; +static planner_t pl; + + +// Returns the index of the next block in the ring buffer. Also called by stepper segment buffer. +uint8_t plan_next_block_index(uint8_t block_index) +{ + block_index++; + if (block_index == BLOCK_BUFFER_SIZE) { block_index = 0; } + return(block_index); +} + + +// Returns the index of the previous block in the ring buffer +static uint8_t plan_prev_block_index(uint8_t block_index) +{ + if (block_index == 0) { block_index = BLOCK_BUFFER_SIZE; } + block_index--; + return(block_index); +} + + +/* PLANNER SPEED DEFINITION + +--------+ <- current->nominal_speed + / \ + current->entry_speed -> + \ + | + <- next->entry_speed (aka exit speed) + +-------------+ + time --> + + Recalculates the motion plan according to the following basic guidelines: + + 1. Go over every feasible block sequentially in reverse order and calculate the junction speeds + (i.e. current->entry_speed) such that: + a. No junction speed exceeds the pre-computed maximum junction speed limit or nominal speeds of + neighboring blocks. + b. A block entry speed cannot exceed one reverse-computed from its exit speed (next->entry_speed) + with a maximum allowable deceleration over the block travel distance. + c. The last (or newest appended) block is planned from a complete stop (an exit speed of zero). + 2. Go over every block in chronological (forward) order and dial down junction speed values if + a. The exit speed exceeds the one forward-computed from its entry speed with the maximum allowable + acceleration over the block travel distance. + + When these stages are complete, the planner will have maximized the velocity profiles throughout the all + of the planner blocks, where every block is operating at its maximum allowable acceleration limits. In + other words, for all of the blocks in the planner, the plan is optimal and no further speed improvements + are possible. If a new block is added to the buffer, the plan is recomputed according to the said + guidelines for a new optimal plan. + + To increase computational efficiency of these guidelines, a set of planner block pointers have been + created to indicate stop-compute points for when the planner guidelines cannot logically make any further + changes or improvements to the plan when in normal operation and new blocks are streamed and added to the + planner buffer. For example, if a subset of sequential blocks in the planner have been planned and are + bracketed by junction velocities at their maximums (or by the first planner block as well), no new block + added to the planner buffer will alter the velocity profiles within them. So we no longer have to compute + them. Or, if a set of sequential blocks from the first block in the planner (or a optimal stop-compute + point) are all accelerating, they are all optimal and can not be altered by a new block added to the + planner buffer, as this will only further increase the plan speed to chronological blocks until a maximum + junction velocity is reached. However, if the operational conditions of the plan changes from infrequently + used feed holds or feedrate overrides, the stop-compute pointers will be reset and the entire plan is + recomputed as stated in the general guidelines. + + Planner buffer index mapping: + - block_buffer_tail: Points to the beginning of the planner buffer. First to be executed or being executed. + - block_buffer_head: Points to the buffer block after the last block in the buffer. Used to indicate whether + the buffer is full or empty. As described for standard ring buffers, this block is always empty. + - next_buffer_head: Points to next planner buffer block after the buffer head block. When equal to the + buffer tail, this indicates the buffer is full. + - block_buffer_planned: Points to the first buffer block after the last optimally planned block for normal + 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 plan_discard_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 + enough combined distance traveled in the entire buffer to accelerate up to the nominal speed and then + decelerate to a complete stop at the end of the buffer, as stated by the guidelines. If this happens and + becomes an annoyance, there are a few simple solutions: (1) Maximize the machine acceleration. The planner + will be able to compute higher velocity profiles within the same combined distance. (2) Maximize line + motion(s) distance per block to a desired tolerance. The more combined distance the planner has to use, + the faster it can go. (3) Maximize the planner buffer size. This also will increase the combined distance + for the planner to compute over. It also increases the number of computations the planner has to perform + to compute an optimal plan, so select carefully. The Arduino 328p memory is already maxed out, but future + ARM versions should have enough memory and speed for look-ahead blocks numbering up to a hundred or more. + +*/ +static void planner_recalculate() +{ + // Initialize block index to the last block in the planner buffer. + uint8_t block_index = plan_prev_block_index(block_buffer_head); + + // Bail. Can't do anything with one only one plan-able block. + if (block_index == block_buffer_planned) { return; } + + // Reverse Pass: Coarsely maximize all possible deceleration curves back-planning from the last + // block in buffer. Cease planning when the last optimal planned or tail pointer is reached. + // NOTE: Forward pass will later refine and correct the reverse pass to create an optimal plan. + float entry_speed_sqr; + plan_block_t *next; + plan_block_t *current = &block_buffer[block_index]; + + // Calculate maximum entry speed for last block in buffer, where the exit speed is always zero. + current->entry_speed_sqr = min( current->max_entry_speed_sqr, 2*current->acceleration*current->millimeters); + + block_index = plan_prev_block_index(block_index); + if (block_index == block_buffer_planned) { // Only two plannable blocks in buffer. Reverse pass complete. + // Check if the first block is the tail. If so, notify stepper to update its current parameters. + if (block_index == block_buffer_tail) { st_update_plan_block_parameters(); } + } else { // Three or more plan-able blocks + while (block_index != block_buffer_planned) { + next = current; + current = &block_buffer[block_index]; + block_index = plan_prev_block_index(block_index); + + // Check if next block is the tail block(=planned block). If so, update current stepper parameters. + if (block_index == block_buffer_tail) { st_update_plan_block_parameters(); } + + // Compute maximum entry speed decelerating over the current block from its exit speed. + if (current->entry_speed_sqr != current->max_entry_speed_sqr) { + entry_speed_sqr = next->entry_speed_sqr + 2*current->acceleration*current->millimeters; + if (entry_speed_sqr < current->max_entry_speed_sqr) { + current->entry_speed_sqr = entry_speed_sqr; + } else { + current->entry_speed_sqr = current->max_entry_speed_sqr; + } + } + } + } + + // Forward Pass: Forward plan the acceleration curve from the planned pointer onward. + // Also scans for optimal plan breakpoints and appropriately updates the planned pointer. + next = &block_buffer[block_buffer_planned]; // Begin at buffer planned pointer + block_index = plan_next_block_index(block_buffer_planned); + while (block_index != block_buffer_head) { + current = next; + next = &block_buffer[block_index]; + + // Any acceleration detected in the forward pass automatically moves the optimal planned + // pointer forward, since everything before this is all optimal. In other words, nothing + // can improve the plan from the buffer tail to the planned pointer by logic. + if (current->entry_speed_sqr < next->entry_speed_sqr) { + entry_speed_sqr = current->entry_speed_sqr + 2*current->acceleration*current->millimeters; + // If true, current block is full-acceleration and we can move the planned pointer forward. + if (entry_speed_sqr < next->entry_speed_sqr) { + next->entry_speed_sqr = entry_speed_sqr; // Always <= max_entry_speed_sqr. Backward pass sets this. + block_buffer_planned = block_index; // Set optimal plan pointer. + } + } + + // Any block set at its maximum entry speed also creates an optimal plan up to this + // point in the buffer. When the plan is bracketed by either the beginning of the + // buffer and a maximum entry speed or two maximum entry speeds, every block in between + // cannot logically be further improved. Hence, we don't have to recompute them anymore. + if (next->entry_speed_sqr == next->max_entry_speed_sqr) { block_buffer_planned = block_index; } + block_index = plan_next_block_index( block_index ); + } +} + + +void plan_reset() +{ + memset(&pl, 0, sizeof(planner_t)); // Clear planner struct + plan_reset_buffer(); +} + + +void plan_reset_buffer() +{ + block_buffer_tail = 0; + block_buffer_head = 0; // Empty = tail + next_buffer_head = 1; // plan_next_block_index(block_buffer_head) + block_buffer_planned = 0; // = block_buffer_tail; +} + + +void plan_discard_current_block() +{ + if (block_buffer_head != block_buffer_tail) { // Discard non-empty buffer. + uint8_t block_index = plan_next_block_index( block_buffer_tail ); + // Push block_buffer_planned pointer, if encountered. + if (block_buffer_tail == block_buffer_planned) { block_buffer_planned = block_index; } + block_buffer_tail = block_index; + } +} + + +// Returns address of planner buffer block used by system motions. Called by segment generator. +plan_block_t *plan_get_system_motion_block() +{ + return(&block_buffer[block_buffer_head]); +} + + +// Returns address of first planner block, if available. Called by various main program functions. +plan_block_t *plan_get_current_block() +{ + if (block_buffer_head == block_buffer_tail) { return(NULL); } // Buffer empty + return(&block_buffer[block_buffer_tail]); +} + + +float plan_get_exec_block_exit_speed_sqr() +{ + uint8_t block_index = plan_next_block_index(block_buffer_tail); + if (block_index == block_buffer_head) { return( 0.0 ); } + return( block_buffer[block_index].entry_speed_sqr ); +} + + +// Returns the availability status of the block ring buffer. True, if full. +uint8_t plan_check_full_buffer() +{ + if (block_buffer_tail == next_buffer_head) { return(true); } + return(false); +} + + +// Computes and returns block nominal speed based on running condition and override values. +// NOTE: All system motion commands, such as homing/parking, are not subject to overrides. +float plan_compute_profile_nominal_speed(plan_block_t *block) +{ + float nominal_speed = block->programmed_rate; + if (block->condition & PL_COND_FLAG_RAPID_MOTION) { nominal_speed *= (0.01*sys.r_override); } + else { + if (!(block->condition & PL_COND_FLAG_NO_FEED_OVERRIDE)) { nominal_speed *= (0.01*sys.f_override); } + if (nominal_speed > block->rapid_rate) { nominal_speed = block->rapid_rate; } + } + if (nominal_speed > MINIMUM_FEED_RATE) { return(nominal_speed); } + return(MINIMUM_FEED_RATE); +} + + +// Computes and updates the max entry speed (sqr) of the block, based on the minimum of the junction's +// previous and current nominal speeds and max junction speed. +static void plan_compute_profile_parameters(plan_block_t *block, float nominal_speed, float prev_nominal_speed) +{ + // Compute the junction maximum entry based on the minimum of the junction speed and neighboring nominal speeds. + if (nominal_speed > prev_nominal_speed) { block->max_entry_speed_sqr = prev_nominal_speed*prev_nominal_speed; } + else { block->max_entry_speed_sqr = nominal_speed*nominal_speed; } + if (block->max_entry_speed_sqr > block->max_junction_speed_sqr) { block->max_entry_speed_sqr = block->max_junction_speed_sqr; } +} + + +// Re-calculates buffered motions profile parameters upon a motion-based override change. +void plan_update_velocity_profile_parameters() +{ + uint8_t block_index = block_buffer_tail; + plan_block_t *block; + float nominal_speed; + float prev_nominal_speed = SOME_LARGE_VALUE; // Set high for first block nominal speed calculation. + while (block_index != block_buffer_head) { + block = &block_buffer[block_index]; + nominal_speed = plan_compute_profile_nominal_speed(block); + plan_compute_profile_parameters(block, nominal_speed, prev_nominal_speed); + prev_nominal_speed = nominal_speed; + block_index = plan_next_block_index(block_index); + } + pl.previous_nominal_speed = prev_nominal_speed; // Update prev nominal speed for next incoming block. +} + + +/* Add a new linear movement to the buffer. target[N_AXIS] is the signed, absolute target position + in millimeters. Feed rate specifies the speed of the motion. If feed rate is inverted, the feed + rate is taken to mean "frequency" and would complete the operation in 1/feed_rate minutes. + All position data passed to the planner must be in terms of machine position to keep the planner + independent of any coordinate system changes and offsets, which are handled by the g-code parser. + NOTE: Assumes buffer is available. Buffer checks are handled at a higher level by motion_control. + In other words, the buffer head is never equal to the buffer tail. Also the feed rate input value + is used in three ways: as a normal feed rate if invert_feed_rate is false, as inverse time if + invert_feed_rate is true, or as seek/rapids rate if the feed_rate value is negative (and + invert_feed_rate always false). + The system motion condition tells the planner to plan a motion in the always unused block buffer + head. It avoids changing the planner state and preserves the buffer to ensure subsequent gcode + motions are still planned correctly, while the stepper module only points to the block buffer head + to execute the special system motion. */ +uint8_t plan_buffer_line(float *target, plan_line_data_t *pl_data) +{ + // Prepare and initialize new block. Copy relevant pl_data for block execution. + plan_block_t *block = &block_buffer[block_buffer_head]; + memset(block,0,sizeof(plan_block_t)); // Zero all block values. + block->condition = pl_data->condition; + #ifdef VARIABLE_SPINDLE + block->spindle_speed = pl_data->spindle_speed; + #endif + #ifdef USE_LINE_NUMBERS + block->line_number = pl_data->line_number; + #endif + + // Compute and store initial move distance data. + int32_t target_steps[N_AXIS], position_steps[N_AXIS]; + float unit_vec[N_AXIS], delta_mm; + uint8_t idx; + + // Copy position data based on type of motion being planned. + if (block->condition & PL_COND_FLAG_SYSTEM_MOTION) { + #ifdef COREXY + position_steps[X_AXIS] = system_convert_corexy_to_x_axis_steps(sys_position); + position_steps[Y_AXIS] = system_convert_corexy_to_y_axis_steps(sys_position); + position_steps[Z_AXIS] = sys_position[Z_AXIS]; + #else + memcpy(position_steps, sys_position, sizeof(sys_position)); + #endif + } else { memcpy(position_steps, pl.position, sizeof(pl.position)); } + + #ifdef COREXY + target_steps[A_MOTOR] = lround(target[A_MOTOR]*settings.steps_per_mm[A_MOTOR]); + target_steps[B_MOTOR] = lround(target[B_MOTOR]*settings.steps_per_mm[B_MOTOR]); + block->steps[A_MOTOR] = labs((target_steps[X_AXIS]-position_steps[X_AXIS]) + (target_steps[Y_AXIS]-position_steps[Y_AXIS])); + block->steps[B_MOTOR] = labs((target_steps[X_AXIS]-position_steps[X_AXIS]) - (target_steps[Y_AXIS]-position_steps[Y_AXIS])); + #endif + + for (idx=0; idxsteps[idx] = labs(target_steps[idx]-position_steps[idx]); + } + block->step_event_count = max(block->step_event_count, block->steps[idx]); + if (idx == A_MOTOR) { + delta_mm = (target_steps[X_AXIS]-position_steps[X_AXIS] + target_steps[Y_AXIS]-position_steps[Y_AXIS])/settings.steps_per_mm[idx]; + } else if (idx == B_MOTOR) { + delta_mm = (target_steps[X_AXIS]-position_steps[X_AXIS] - target_steps[Y_AXIS]+position_steps[Y_AXIS])/settings.steps_per_mm[idx]; + } else { + delta_mm = (target_steps[idx] - position_steps[idx])/settings.steps_per_mm[idx]; + } + #else + target_steps[idx] = lround(target[idx]*settings.steps_per_mm[idx]); + block->steps[idx] = labs(target_steps[idx]-position_steps[idx]); + block->step_event_count = max(block->step_event_count, block->steps[idx]); + delta_mm = (target_steps[idx] - position_steps[idx])/settings.steps_per_mm[idx]; + #endif + unit_vec[idx] = delta_mm; // Store unit vector numerator + + // Set direction bits. Bit enabled always means direction is negative. + if (delta_mm < 0.0 ) { block->direction_bits |= get_direction_pin_mask(idx); } + } + + // Bail if this is a zero-length block. Highly unlikely to occur. + if (block->step_event_count == 0) { return(PLAN_EMPTY_BLOCK); } + + // Calculate the unit vector of the line move and the block maximum feed rate and acceleration scaled + // down such that no individual axes maximum values are exceeded with respect to the line direction. + // NOTE: This calculation assumes all axes are orthogonal (Cartesian) and works with ABC-axes, + // if they are also orthogonal/independent. Operates on the absolute value of the unit vector. + block->millimeters = convert_delta_vector_to_unit_vector(unit_vec); + block->acceleration = limit_value_by_axis_maximum(settings.acceleration, unit_vec); + block->rapid_rate = limit_value_by_axis_maximum(settings.max_rate, unit_vec); + + // Store programmed rate. + if (block->condition & PL_COND_FLAG_RAPID_MOTION) { block->programmed_rate = block->rapid_rate; } + else { + block->programmed_rate = pl_data->feed_rate; + if (block->condition & PL_COND_FLAG_INVERSE_TIME) { block->programmed_rate *= block->millimeters; } + } + + // TODO: Need to check this method handling zero junction speeds when starting from rest. + if ((block_buffer_head == block_buffer_tail) || (block->condition & PL_COND_FLAG_SYSTEM_MOTION)) { + + // Initialize block entry speed as zero. Assume it will be starting from rest. Planner will correct this later. + // If system motion, the system motion block always is assumed to start from rest and end at a complete stop. + block->entry_speed_sqr = 0.0; + block->max_junction_speed_sqr = 0.0; // Starting from rest. Enforce start from zero velocity. + + } else { + // 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 + // deviation is defined as the distance from the junction to the closest edge of the circle, + // colinear with the circle center. The circular segment joining the two paths represents the + // path of centripetal acceleration. Solve for max velocity based on max acceleration about the + // radius of the circle, defined indirectly by junction deviation. This may be also viewed as + // path width or max_jerk in the previous Grbl version. This approach does not actually deviate + // from path, but used as a robust way to compute cornering speeds, as it takes into account the + // nonlinearities of both the junction angle and junction velocity. + // + // NOTE: If the junction deviation value is finite, Grbl executes the motions in an exact path + // mode (G61). If the junction deviation value is zero, Grbl will execute the motion in an exact + // stop mode (G61.1) manner. In the future, if continuous mode (G64) is desired, the math here + // is exactly the same. Instead of motioning all the way to junction point, the machine will + // just follow the arc circle defined here. The Arduino doesn't have the CPU cycles to perform + // a continuous mode path, but ARM-based microcontrollers most certainly do. + // + // NOTE: The max junction speed is a fixed value, since machine acceleration limits cannot be + // changed dynamically during operation nor can the line move geometry. This must be kept in + // memory in the event of a feedrate override changing the nominal speeds of blocks, which can + // change the overall maximum entry speed conditions of all blocks. + + float junction_unit_vec[N_AXIS]; + float junction_cos_theta = 0.0; + for (idx=0; idx 0.999999) { + // For a 0 degree acute junction, just set minimum junction speed. + block->max_junction_speed_sqr = MINIMUM_JUNCTION_SPEED*MINIMUM_JUNCTION_SPEED; + } else { + if (junction_cos_theta < -0.999999) { + // Junction is a straight line or 180 degrees. Junction speed is infinite. + block->max_junction_speed_sqr = SOME_LARGE_VALUE; + } else { + convert_delta_vector_to_unit_vector(junction_unit_vec); + float junction_acceleration = limit_value_by_axis_maximum(settings.acceleration, junction_unit_vec); + float sin_theta_d2 = sqrt(0.5*(1.0-junction_cos_theta)); // Trig half angle identity. Always positive. + block->max_junction_speed_sqr = max( MINIMUM_JUNCTION_SPEED*MINIMUM_JUNCTION_SPEED, + (junction_acceleration * settings.junction_deviation * sin_theta_d2)/(1.0-sin_theta_d2) ); + } + } + } + + // Block system motion from updating this data to ensure next g-code motion is computed correctly. + if (!(block->condition & PL_COND_FLAG_SYSTEM_MOTION)) { + float nominal_speed = plan_compute_profile_nominal_speed(block); + plan_compute_profile_parameters(block, nominal_speed, pl.previous_nominal_speed); + pl.previous_nominal_speed = nominal_speed; + + // Update previous path unit_vector and planner position. + memcpy(pl.previous_unit_vec, unit_vec, sizeof(unit_vec)); // pl.previous_unit_vec[] = unit_vec[] + memcpy(pl.position, target_steps, sizeof(target_steps)); // pl.position[] = target_steps[] + + // New block is all set. Update buffer head and next buffer head indices. + block_buffer_head = next_buffer_head; + next_buffer_head = plan_next_block_index(block_buffer_head); + + // Finish up by recalculating the plan with the new block. + planner_recalculate(); + } + return(PLAN_OK); +} + + +// Reset the planner position vectors. Called by the system abort/initialization routine. +void plan_sync_position() +{ + // TODO: For motor configurations not in the same coordinate frame as the machine position, + // this function needs to be updated to accomodate the difference. + uint8_t idx; + for (idx=0; idx= block_buffer_tail) { return((BLOCK_BUFFER_SIZE-1)-(block_buffer_head-block_buffer_tail)); } + return((block_buffer_tail-block_buffer_head-1)); +} + + +// Returns the number of active blocks are in the planner buffer. +// NOTE: Deprecated. Not used unless classic status reports are enabled in config.h +uint8_t plan_get_block_buffer_count() +{ + if (block_buffer_head >= block_buffer_tail) { return(block_buffer_head-block_buffer_tail); } + return(BLOCK_BUFFER_SIZE - (block_buffer_tail-block_buffer_head)); +} + + +// Re-initialize buffer plan with a partially completed block, assumed to exist at the buffer tail. +// Called after a steppers have come to a complete stop for a feed hold and the cycle is stopped. +void plan_cycle_reinitialize() +{ + // Re-plan from a complete stop. Reset planner entry speeds and buffer planned pointer. + st_update_plan_block_parameters(); + block_buffer_planned = block_buffer_tail; + planner_recalculate(); +} diff --git a/trunk/Arduino/GRBL_1.1f_Nano/planner.h b/trunk/Arduino/GRBL_1.1f_Nano/planner.h new file mode 100644 index 00000000..e3751e16 --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f_Nano/planner.h @@ -0,0 +1,150 @@ +/* + planner.h - buffers movement commands and manages the acceleration profile plan + Part of Grbl + + Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC + Copyright (c) 2009-2011 Simen Svale Skogsrud + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +#ifndef planner_h +#define planner_h + + +// The number of linear motions that can be in the plan at any give time +#ifndef BLOCK_BUFFER_SIZE + #ifdef USE_LINE_NUMBERS + #define BLOCK_BUFFER_SIZE 15 + #else + #define BLOCK_BUFFER_SIZE 16 + #endif +#endif + +// Returned status message from planner. +#define PLAN_OK true +#define PLAN_EMPTY_BLOCK false + +// Define planner data condition flags. Used to denote running conditions of a block. +#define PL_COND_FLAG_RAPID_MOTION bit(0) +#define PL_COND_FLAG_SYSTEM_MOTION bit(1) // Single motion. Circumvents planner state. Used by home/park. +#define PL_COND_FLAG_NO_FEED_OVERRIDE bit(2) // Motion does not honor feed override. +#define PL_COND_FLAG_INVERSE_TIME bit(3) // Interprets feed rate value as inverse time when set. +#define PL_COND_FLAG_SPINDLE_CW bit(4) +#define PL_COND_FLAG_SPINDLE_CCW bit(5) +#define PL_COND_FLAG_COOLANT_FLOOD bit(6) +#define PL_COND_FLAG_COOLANT_MIST bit(7) +#define PL_COND_MOTION_MASK (PL_COND_FLAG_RAPID_MOTION|PL_COND_FLAG_SYSTEM_MOTION|PL_COND_FLAG_NO_FEED_OVERRIDE) +#define PL_COND_SPINDLE_MASK (PL_COND_FLAG_SPINDLE_CW|PL_COND_FLAG_SPINDLE_CCW) +#define PL_COND_ACCESSORY_MASK (PL_COND_FLAG_SPINDLE_CW|PL_COND_FLAG_SPINDLE_CCW|PL_COND_FLAG_COOLANT_FLOOD|PL_COND_FLAG_COOLANT_MIST) + + +// This struct stores a linear movement of a g-code block motion with its critical "nominal" values +// are as specified in the source g-code. +typedef struct { + // Fields used by the bresenham algorithm for tracing the line + // NOTE: Used by stepper algorithm to execute the block correctly. Do not alter these values. + uint32_t steps[N_AXIS]; // Step count along each axis + uint32_t step_event_count; // The maximum step axis count and number of steps required to complete this block. + uint8_t direction_bits; // The direction bit set for this block (refers to *_DIRECTION_BIT in config.h) + + // Block condition data to ensure correct execution depending on states and overrides. + uint8_t condition; // Block bitflag variable defining block run conditions. Copied from pl_line_data. + #ifdef USE_LINE_NUMBERS + int32_t line_number; // Block line number for real-time reporting. Copied from pl_line_data. + #endif + + // Fields used by the motion planner to manage acceleration. Some of these values may be updated + // by the stepper module during execution of special motion cases for replanning purposes. + float entry_speed_sqr; // The current planned entry speed at block junction in (mm/min)^2 + float max_entry_speed_sqr; // Maximum allowable entry speed based on the minimum of junction limit and + // neighboring nominal speeds with overrides in (mm/min)^2 + float acceleration; // Axis-limit adjusted line acceleration in (mm/min^2). Does not change. + float millimeters; // The remaining distance for this block to be executed in (mm). + // NOTE: This value may be altered by stepper algorithm during execution. + + // Stored rate limiting data used by planner when changes occur. + float max_junction_speed_sqr; // Junction entry speed limit based on direction vectors in (mm/min)^2 + float rapid_rate; // Axis-limit adjusted maximum rate for this block direction in (mm/min) + float programmed_rate; // Programmed rate of this block (mm/min). + + #ifdef VARIABLE_SPINDLE + // Stored spindle speed data used by spindle overrides and resuming methods. + float spindle_speed; // Block spindle speed. Copied from pl_line_data. + #endif +} plan_block_t; + + +// Planner data prototype. Must be used when passing new motions to the planner. +typedef struct { + float feed_rate; // Desired feed rate for line motion. Value is ignored, if rapid motion. + float spindle_speed; // Desired spindle speed through line motion. + uint8_t condition; // Bitflag variable to indicate planner conditions. See defines above. + #ifdef USE_LINE_NUMBERS + int32_t line_number; // Desired line number to report when executing. + #endif +} plan_line_data_t; + + +// Initialize and reset the motion plan subsystem +void plan_reset(); // Reset all +void plan_reset_buffer(); // Reset buffer only. + +// Add a new linear movement to the buffer. target[N_AXIS] is the signed, absolute target position +// in millimeters. Feed rate specifies the speed of the motion. If feed rate is inverted, the feed +// rate is taken to mean "frequency" and would complete the operation in 1/feed_rate minutes. +uint8_t plan_buffer_line(float *target, plan_line_data_t *pl_data); + +// Called when the current block is no longer needed. Discards the block and makes the memory +// availible for new blocks. +void plan_discard_current_block(); + +// Gets the planner block for the special system motion cases. (Parking/Homing) +plan_block_t *plan_get_system_motion_block(); + +// Gets the current block. Returns NULL if buffer empty +plan_block_t *plan_get_current_block(); + +// Called periodically by step segment buffer. Mostly used internally by planner. +uint8_t plan_next_block_index(uint8_t block_index); + +// Called by step segment buffer when computing executing block velocity profile. +float plan_get_exec_block_exit_speed_sqr(); + +// Called by main program during planner calculations and step segment buffer during initialization. +float plan_compute_profile_nominal_speed(plan_block_t *block); + +// Re-calculates buffered motions profile parameters upon a motion-based override change. +void plan_update_velocity_profile_parameters(); + +// Reset the planner position vector (in steps) +void plan_sync_position(); + +// Reinitialize plan with a partially completed block +void plan_cycle_reinitialize(); + +// Returns the number of available blocks are in the planner buffer. +uint8_t plan_get_block_buffer_available(); + +// Returns the number of active blocks are in the planner buffer. +// NOTE: Deprecated. Not used unless classic status reports are enabled in config.h +uint8_t plan_get_block_buffer_count(); + +// Returns the status of the block ring buffer. True, if buffer is full. +uint8_t plan_check_full_buffer(); + +void plan_get_planner_mpos(float *target); + + +#endif diff --git a/trunk/Arduino/GRBL_1.1f_Nano/print.c b/trunk/Arduino/GRBL_1.1f_Nano/print.c new file mode 100644 index 00000000..771e3996 --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f_Nano/print.c @@ -0,0 +1,200 @@ +/* + print.c - Functions for formatting output strings + Part of Grbl + + Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC + Copyright (c) 2009-2011 Simen Svale Skogsrud + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +#include "grbl.h" + + +void printString(const char *s) +{ + while (*s) + serial_write(*s++); +} + + +// Print a string stored in PGM-memory +void printPgmString(const char *s) +{ + char c; + while ((c = pgm_read_byte_near(s++))) + serial_write(c); +} + + +// void printIntegerInBase(unsigned long n, unsigned long base) +// { +// unsigned char buf[8 * sizeof(long)]; // Assumes 8-bit chars. +// unsigned long i = 0; +// +// if (n == 0) { +// serial_write('0'); +// return; +// } +// +// while (n > 0) { +// buf[i++] = n % base; +// n /= base; +// } +// +// for (; i > 0; i--) +// serial_write(buf[i - 1] < 10 ? +// '0' + buf[i - 1] : +// 'A' + buf[i - 1] - 10); +// } + + +// Prints an uint8 variable in base 10. +void print_uint8_base10(uint8_t n) +{ + uint8_t digit_a = 0; + uint8_t digit_b = 0; + if (n >= 100) { // 100-255 + digit_a = '0' + n % 10; + n /= 10; + } + if (n >= 10) { // 10-99 + digit_b = '0' + n % 10; + n /= 10; + } + serial_write('0' + n); + if (digit_b) { serial_write(digit_b); } + if (digit_a) { serial_write(digit_a); } +} + + +// Prints an uint8 variable in base 2 with desired number of desired digits. +void print_uint8_base2_ndigit(uint8_t n, uint8_t digits) { + unsigned char buf[digits]; + uint8_t i = 0; + + for (; i < digits; i++) { + buf[i] = n % 2 ; + n /= 2; + } + + for (; i > 0; i--) + serial_write('0' + buf[i - 1]); +} + + +void print_uint32_base10(uint32_t n) +{ + if (n == 0) { + serial_write('0'); + return; + } + + unsigned char buf[10]; + uint8_t i = 0; + + while (n > 0) { + buf[i++] = n % 10; + n /= 10; + } + + for (; i > 0; i--) + serial_write('0' + buf[i-1]); +} + + +void printInteger(long n) +{ + if (n < 0) { + serial_write('-'); + print_uint32_base10(-n); + } else { + print_uint32_base10(n); + } +} + + +// Convert float to string by immediately converting to a long integer, which contains +// more digits than a float. Number of decimal places, which are tracked by a counter, +// may be set by the user. The integer is then efficiently converted to a string. +// NOTE: AVR '%' and '/' integer operations are very efficient. Bitshifting speed-up +// techniques are actually just slightly slower. Found this out the hard way. +void printFloat(float n, uint8_t decimal_places) +{ + if (n < 0) { + serial_write('-'); + n = -n; + } + + uint8_t decimals = decimal_places; + while (decimals >= 2) { // Quickly convert values expected to be E0 to E-4. + n *= 100; + decimals -= 2; + } + if (decimals) { n *= 10; } + n += 0.5; // Add rounding factor. Ensures carryover through entire value. + + // Generate digits backwards and store in string. + unsigned char buf[13]; + uint8_t i = 0; + uint32_t a = (long)n; + while(a > 0) { + buf[i++] = (a % 10) + '0'; // Get digit + a /= 10; + } + while (i < decimal_places) { + buf[i++] = '0'; // Fill in zeros to decimal point for (n < 1) + } + if (i == decimal_places) { // Fill in leading zero, if needed. + buf[i++] = '0'; + } + + // Print the generated string. + for (; i > 0; i--) { + if (i == decimal_places) { serial_write('.'); } // Insert decimal point in right place. + serial_write(buf[i-1]); + } +} + + +// Floating value printing handlers for special variables types used in Grbl and are defined +// in the config.h. +// - CoordValue: Handles all position or coordinate values in inches or mm reporting. +// - RateValue: Handles feed rate and current velocity in inches or mm reporting. +void printFloat_CoordValue(float n) { + if (bit_istrue(settings.flags,BITFLAG_REPORT_INCHES)) { + printFloat(n*INCH_PER_MM,N_DECIMAL_COORDVALUE_INCH); + } else { + printFloat(n,N_DECIMAL_COORDVALUE_MM); + } +} + +void printFloat_RateValue(float n) { + if (bit_istrue(settings.flags,BITFLAG_REPORT_INCHES)) { + printFloat(n*INCH_PER_MM,N_DECIMAL_RATEVALUE_INCH); + } else { + printFloat(n,N_DECIMAL_RATEVALUE_MM); + } +} + +// Debug tool to print free memory in bytes at the called point. +// NOTE: Keep commented unless using. Part of this function always gets compiled in. +// void printFreeMemory() +// { +// extern int __heap_start, *__brkval; +// uint16_t free; // Up to 64k values. +// free = (int) &free - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); +// printInteger((int32_t)free); +// printString(" "); +// } diff --git a/trunk/Arduino/GRBL_1.1f_Nano/print.h b/trunk/Arduino/GRBL_1.1f_Nano/print.h new file mode 100644 index 00000000..31e0a576 --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f_Nano/print.h @@ -0,0 +1,51 @@ +/* + print.h - Functions for formatting output strings + Part of Grbl + + Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC + Copyright (c) 2009-2011 Simen Svale Skogsrud + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +#ifndef print_h +#define print_h + + +void printString(const char *s); + +void printPgmString(const char *s); + +void printInteger(long n); + +void print_uint32_base10(uint32_t n); + +// Prints an uint8 variable in base 10. +void print_uint8_base10(uint8_t n); + +// Prints an uint8 variable in base 2 with desired number of desired digits. +void print_uint8_base2_ndigit(uint8_t n, uint8_t digits); + +void printFloat(float n, uint8_t decimal_places); + +// Floating value printing handlers for special variables types used in Grbl. +// - CoordValue: Handles all position or coordinate values in inches or mm reporting. +// - RateValue: Handles feed rate and current velocity in inches or mm reporting. +void printFloat_CoordValue(float n); +void printFloat_RateValue(float n); + +// Debug tool to print free memory in bytes at the called point. Not used otherwise. +void printFreeMemory(); + +#endif diff --git a/trunk/Arduino/GRBL_1.1f_Nano/probe.c b/trunk/Arduino/GRBL_1.1f_Nano/probe.c new file mode 100644 index 00000000..60c9073a --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f_Nano/probe.c @@ -0,0 +1,66 @@ +/* + probe.c - code pertaining to probing methods + Part of Grbl + + Copyright (c) 2014-2016 Sungeun K. Jeon for Gnea Research LLC + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +#include "grbl.h" + + +// Inverts the probe pin state depending on user settings and probing cycle mode. +uint8_t probe_invert_mask; + + +// Probe pin initialization routine. +void probe_init() +{ + PROBE_DDR &= ~(PROBE_MASK); // Configure as input pins + #ifdef DISABLE_PROBE_PIN_PULL_UP + PROBE_PORT &= ~(PROBE_MASK); // Normal low operation. Requires external pull-down. + #else + PROBE_PORT |= PROBE_MASK; // Enable internal pull-up resistors. Normal high operation. + #endif + probe_configure_invert_mask(false); // Initialize invert mask. +} + + +// Called by probe_init() and the mc_probe() routines. Sets up the probe pin invert mask to +// appropriately set the pin logic according to setting for normal-high/normal-low operation +// and the probing cycle modes for toward-workpiece/away-from-workpiece. +void probe_configure_invert_mask(uint8_t is_probe_away) +{ + probe_invert_mask = 0; // Initialize as zero. + if (bit_isfalse(settings.flags,BITFLAG_INVERT_PROBE_PIN)) { probe_invert_mask ^= PROBE_MASK; } + if (is_probe_away) { probe_invert_mask ^= PROBE_MASK; } +} + + +// Returns the probe pin state. Triggered = true. Called by gcode parser and probe state monitor. +uint8_t probe_get_state() { return((PROBE_PIN & PROBE_MASK) ^ probe_invert_mask); } + + +// Monitors probe pin state and records the system position when detected. Called by the +// stepper ISR per ISR tick. +// NOTE: This function must be extremely efficient as to not bog down the stepper ISR. +void probe_state_monitor() +{ + if (probe_get_state()) { + sys_probe_state = PROBE_OFF; + memcpy(sys_probe_position, sys_position, sizeof(sys_position)); + bit_true(sys_rt_exec_state, EXEC_MOTION_CANCEL); + } +} diff --git a/trunk/Arduino/GRBL_1.1f_Nano/probe.h b/trunk/Arduino/GRBL_1.1f_Nano/probe.h new file mode 100644 index 00000000..03d5fd32 --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f_Nano/probe.h @@ -0,0 +1,43 @@ +/* + probe.h - code pertaining to probing methods + Part of Grbl + + Copyright (c) 2014-2016 Sungeun K. Jeon for Gnea Research LLC + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +#ifndef probe_h +#define probe_h + +// Values that define the probing state machine. +#define PROBE_OFF 0 // Probing disabled or not in use. (Must be zero.) +#define PROBE_ACTIVE 1 // Actively watching the input pin. + +// Probe pin initialization routine. +void probe_init(); + +// Called by probe_init() and the mc_probe() routines. Sets up the probe pin invert mask to +// appropriately set the pin logic according to setting for normal-high/normal-low operation +// and the probing cycle modes for toward-workpiece/away-from-workpiece. +void probe_configure_invert_mask(uint8_t is_probe_away); + +// Returns probe pin state. Triggered = true. Called by gcode parser and probe state monitor. +uint8_t probe_get_state(); + +// Monitors probe pin state and records the system position when detected. Called by the +// stepper ISR per ISR tick. +void probe_state_monitor(); + +#endif diff --git a/trunk/Arduino/GRBL_1.1f_Nano/protocol.c b/trunk/Arduino/GRBL_1.1f_Nano/protocol.c new file mode 100644 index 00000000..08ea48bf --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f_Nano/protocol.c @@ -0,0 +1,765 @@ +/* + protocol.c - controls Grbl execution protocol and procedures + Part of Grbl + + Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC + Copyright (c) 2009-2011 Simen Svale Skogsrud + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +#include "grbl.h" + +// Define line flags. Includes comment type tracking and line overflow detection. +#define LINE_FLAG_OVERFLOW bit(0) +#define LINE_FLAG_COMMENT_PARENTHESES bit(1) +#define LINE_FLAG_COMMENT_SEMICOLON bit(2) + + +static char line[LINE_BUFFER_SIZE]; // Line to be executed. Zero-terminated. + +static void protocol_exec_rt_suspend(); + + +/* + GRBL PRIMARY LOOP: +*/ +void protocol_main_loop() +{ + // Perform some machine checks to make sure everything is good to go. + #ifdef CHECK_LIMITS_AT_INIT + if (bit_istrue(settings.flags, BITFLAG_HARD_LIMIT_ENABLE)) { + if (limits_get_state()) { + sys.state = STATE_ALARM; // Ensure alarm state is active. + report_feedback_message(MESSAGE_CHECK_LIMITS); + } + } + #endif + // Check for and report alarm state after a reset, error, or an initial power up. + // NOTE: Sleep mode disables the stepper drivers and position can't be guaranteed. + // Re-initialize the sleep state as an ALARM mode to ensure user homes or acknowledges. + if (sys.state & (STATE_ALARM | STATE_SLEEP)) { + report_feedback_message(MESSAGE_ALARM_LOCK); + sys.state = STATE_ALARM; // Ensure alarm state is set. + } else { + // Check if the safety door is open. + sys.state = STATE_IDLE; + if (system_check_safety_door_ajar()) { + bit_true(sys_rt_exec_state, EXEC_SAFETY_DOOR); + protocol_execute_realtime(); // Enter safety door mode. Should return as IDLE state. + } + // All systems go! + system_execute_startup(line); // Execute startup script. + } + + // --------------------------------------------------------------------------------- + // Primary loop! Upon a system abort, this exits back to main() to reset the system. + // This is also where Grbl idles while waiting for something to do. + // --------------------------------------------------------------------------------- + + uint8_t line_flags = 0; + uint8_t char_counter = 0; + uint8_t c; + for (;;) { + + // Process one line of incoming serial data, as the data becomes available. Performs an + // initial filtering by removing spaces and comments and capitalizing all letters. + while((c = serial_read()) != SERIAL_NO_DATA) { + if ((c == '\n') || (c == '\r')) { // End of line reached + + protocol_execute_realtime(); // Runtime command check point. + if (sys.abort) { return; } // Bail to calling function upon system abort + + line[char_counter] = 0; // Set string termination character. + #ifdef REPORT_ECHO_LINE_RECEIVED + report_echo_line_received(line); + #endif + + // Direct and execute one line of formatted input, and report status of execution. + if (line_flags & LINE_FLAG_OVERFLOW) { + // Report line overflow error. + report_status_message(STATUS_OVERFLOW); + } else if (line[0] == 0) { + // Empty or comment line. For syncing purposes. + report_status_message(STATUS_OK); + } else if (line[0] == '$') { + // Grbl '$' system command + report_status_message(system_execute_line(line)); + } else if (sys.state & (STATE_ALARM | STATE_JOG)) { + // Everything else is gcode. Block if in alarm or jog mode. + report_status_message(STATUS_SYSTEM_GC_LOCK); + } else { + // Parse and execute g-code block. + report_status_message(gc_execute_line(line)); + } + + // Reset tracking data for next line. + line_flags = 0; + char_counter = 0; + + } else { + + if (line_flags) { + // Throw away all (except EOL) comment characters and overflow characters. + if (c == ')') { + // End of '()' comment. Resume line allowed. + if (line_flags & LINE_FLAG_COMMENT_PARENTHESES) { line_flags &= ~(LINE_FLAG_COMMENT_PARENTHESES); } + } + } else { + if (c <= ' ') { + // Throw away whitepace and control characters + } else if (c == '/') { + // Block delete NOT SUPPORTED. Ignore character. + // NOTE: If supported, would simply need to check the system if block delete is enabled. + } else if (c == '(') { + // Enable comments flag and ignore all characters until ')' or EOL. + // NOTE: This doesn't follow the NIST definition exactly, but is good enough for now. + // In the future, we could simply remove the items within the comments, but retain the + // comment control characters, so that the g-code parser can error-check it. + line_flags |= LINE_FLAG_COMMENT_PARENTHESES; + } else if (c == ';') { + // NOTE: ';' comment to EOL is a LinuxCNC definition. Not NIST. + line_flags |= LINE_FLAG_COMMENT_SEMICOLON; + // TODO: Install '%' feature + // } else if (c == '%') { + // Program start-end percent sign NOT SUPPORTED. + // NOTE: This maybe installed to tell Grbl when a program is running vs manual input, + // where, during a program, the system auto-cycle start will continue to execute + // everything until the next '%' sign. This will help fix resuming issues with certain + // functions that empty the planner buffer to execute its task on-time. + } else if (char_counter >= (LINE_BUFFER_SIZE-1)) { + // Detect line buffer overflow and set flag. + line_flags |= LINE_FLAG_OVERFLOW; + } else if (c >= 'a' && c <= 'z') { // Upcase lowercase + line[char_counter++] = c-'a'+'A'; + } else { + line[char_counter++] = c; + } + } + + } + } + + // If there are no more characters in the serial read buffer to be processed and executed, + // this indicates that g-code streaming has either filled the planner buffer or has + // completed. In either case, auto-cycle start, if enabled, any queued moves. + protocol_auto_cycle_start(); + + protocol_execute_realtime(); // Runtime command check point. + if (sys.abort) { return; } // Bail to main() program loop to reset system. + } + + return; /* Never reached */ +} + + +// Block until all buffered steps are executed or in a cycle state. Works with feed hold +// during a synchronize call, if it should happen. Also, waits for clean cycle end. +void protocol_buffer_synchronize() +{ + // If system is queued, ensure cycle resumes if the auto start flag is present. + protocol_auto_cycle_start(); + do { + protocol_execute_realtime(); // Check and execute run-time commands + if (sys.abort) { return; } // Check for system abort + } while (plan_get_current_block() || (sys.state == STATE_CYCLE)); +} + + +// Auto-cycle start triggers when there is a motion ready to execute and if the main program is not +// actively parsing commands. +// NOTE: This function is called from the main loop, buffer sync, and mc_line() only and executes +// when one of these conditions exist respectively: There are no more blocks sent (i.e. streaming +// is finished, single commands), a command that needs to wait for the motions in the buffer to +// execute calls a buffer sync, or the planner buffer is full and ready to go. +void protocol_auto_cycle_start() +{ + if (plan_get_current_block() != NULL) { // Check if there are any blocks in the buffer. + system_set_exec_state_flag(EXEC_CYCLE_START); // If so, execute them! + } +} + + +// This function is the general interface to Grbl's real-time command execution system. It is called +// from various check points in the main program, primarily where there may be a while loop waiting +// for a buffer to clear space or any point where the execution time from the last check point may +// be more than a fraction of a second. This is a way to execute realtime commands asynchronously +// (aka multitasking) with grbl's g-code parsing and planning functions. This function also serves +// as an interface for the interrupts to set the system realtime flags, where only the main program +// handles them, removing the need to define more computationally-expensive volatile variables. This +// also provides a controlled way to execute certain tasks without having two or more instances of +// the same task, such as the planner recalculating the buffer upon a feedhold or overrides. +// NOTE: The sys_rt_exec_state variable flags are set by any process, step or serial interrupts, pinouts, +// limit switches, or the main program. +void protocol_execute_realtime() +{ + protocol_exec_rt_system(); + if (sys.suspend) { protocol_exec_rt_suspend(); } +} + + +// Executes run-time commands, when required. This function primarily operates as Grbl's state +// machine and controls the various real-time features Grbl has to offer. +// NOTE: Do not alter this unless you know exactly what you are doing! +void protocol_exec_rt_system() +{ + uint8_t rt_exec; // Temp variable to avoid calling volatile multiple times. + rt_exec = sys_rt_exec_alarm; // Copy volatile sys_rt_exec_alarm. + if (rt_exec) { // Enter only if any bit flag is true + // System alarm. Everything has shutdown by something that has gone severely wrong. Report + // the source of the error to the user. If critical, Grbl disables by entering an infinite + // loop until system reset/abort. + sys.state = STATE_ALARM; // Set system alarm state + report_alarm_message(rt_exec); + // Halt everything upon a critical event flag. Currently hard and soft limits flag this. + if ((rt_exec == EXEC_ALARM_HARD_LIMIT) || (rt_exec == EXEC_ALARM_SOFT_LIMIT)) { + report_feedback_message(MESSAGE_CRITICAL_EVENT); + system_clear_exec_state_flag(EXEC_RESET); // Disable any existing reset + do { + // Block everything, except reset and status reports, until user issues reset or power + // cycles. Hard limits typically occur while unattended or not paying attention. Gives + // the user and a GUI time to do what is needed before resetting, like killing the + // incoming stream. The same could be said about soft limits. While the position is not + // lost, continued streaming could cause a serious crash if by chance it gets executed. + } while (bit_isfalse(sys_rt_exec_state,EXEC_RESET)); + } + system_clear_exec_alarm(); // Clear alarm + } + + rt_exec = sys_rt_exec_state; // Copy volatile sys_rt_exec_state. + if (rt_exec) { + + // Execute system abort. + if (rt_exec & EXEC_RESET) { + sys.abort = true; // Only place this is set true. + return; // Nothing else to do but exit. + } + + // Execute and serial print status + if (rt_exec & EXEC_STATUS_REPORT) { + report_realtime_status(); + system_clear_exec_state_flag(EXEC_STATUS_REPORT); + } + + // NOTE: Once hold is initiated, the system immediately enters a suspend state to block all + // main program processes until either reset or resumed. This ensures a hold completes safely. + if (rt_exec & (EXEC_MOTION_CANCEL | EXEC_FEED_HOLD | EXEC_SAFETY_DOOR | EXEC_SLEEP)) { + + // State check for allowable states for hold methods. + if (!(sys.state & (STATE_ALARM | STATE_CHECK_MODE))) { + + // If in CYCLE or JOG states, immediately initiate a motion HOLD. + if (sys.state & (STATE_CYCLE | STATE_JOG)) { + if (!(sys.suspend & (SUSPEND_MOTION_CANCEL | SUSPEND_JOG_CANCEL))) { // Block, if already holding. + st_update_plan_block_parameters(); // Notify stepper module to recompute for hold deceleration. + sys.step_control = STEP_CONTROL_EXECUTE_HOLD; // Initiate suspend state with active flag. + if (sys.state == STATE_JOG) { // Jog cancelled upon any hold event, except for sleeping. + if (!(rt_exec & EXEC_SLEEP)) { sys.suspend |= SUSPEND_JOG_CANCEL; } + } + } + } + // If IDLE, Grbl is not in motion. Simply indicate suspend state and hold is complete. + if (sys.state == STATE_IDLE) { sys.suspend = SUSPEND_HOLD_COMPLETE; } + + // Execute and flag a motion cancel with deceleration and return to idle. Used primarily by probing cycle + // to halt and cancel the remainder of the motion. + if (rt_exec & EXEC_MOTION_CANCEL) { + // MOTION_CANCEL only occurs during a CYCLE, but a HOLD and SAFETY_DOOR may been initiated beforehand + // to hold the CYCLE. Motion cancel is valid for a single planner block motion only, while jog cancel + // will handle and clear multiple planner block motions. + if (!(sys.state & STATE_JOG)) { sys.suspend |= SUSPEND_MOTION_CANCEL; } // NOTE: State is STATE_CYCLE. + } + + // Execute a feed hold with deceleration, if required. Then, suspend system. + if (rt_exec & EXEC_FEED_HOLD) { + // Block SAFETY_DOOR, JOG, and SLEEP states from changing to HOLD state. + if (!(sys.state & (STATE_SAFETY_DOOR | STATE_JOG | STATE_SLEEP))) { sys.state = STATE_HOLD; } + } + + // Execute a safety door stop with a feed hold and disable spindle/coolant. + // NOTE: Safety door differs from feed holds by stopping everything no matter state, disables powered + // devices (spindle/coolant), and blocks resuming until switch is re-engaged. + if (rt_exec & EXEC_SAFETY_DOOR) { + report_feedback_message(MESSAGE_SAFETY_DOOR_AJAR); + // If jogging, block safety door methods until jog cancel is complete. Just flag that it happened. + if (!(sys.suspend & SUSPEND_JOG_CANCEL)) { + // Check if the safety re-opened during a restore parking motion only. Ignore if + // already retracting, parked or in sleep state. + if (sys.state == STATE_SAFETY_DOOR) { + if (sys.suspend & SUSPEND_INITIATE_RESTORE) { // Actively restoring + #ifdef PARKING_ENABLE + // Set hold and reset appropriate control flags to restart parking sequence. + if (sys.step_control & STEP_CONTROL_EXECUTE_SYS_MOTION) { + st_update_plan_block_parameters(); // Notify stepper module to recompute for hold deceleration. + sys.step_control = (STEP_CONTROL_EXECUTE_HOLD | STEP_CONTROL_EXECUTE_SYS_MOTION); + sys.suspend &= ~(SUSPEND_HOLD_COMPLETE); + } // else NO_MOTION is active. + #endif + sys.suspend &= ~(SUSPEND_RETRACT_COMPLETE | SUSPEND_INITIATE_RESTORE | SUSPEND_RESTORE_COMPLETE); + sys.suspend |= SUSPEND_RESTART_RETRACT; + } + } + if (sys.state != STATE_SLEEP) { sys.state = STATE_SAFETY_DOOR; } + } + // NOTE: This flag doesn't change when the door closes, unlike sys.state. Ensures any parking motions + // are executed if the door switch closes and the state returns to HOLD. + sys.suspend |= SUSPEND_SAFETY_DOOR_AJAR; + } + + } + + if (rt_exec & EXEC_SLEEP) { + if (sys.state == STATE_ALARM) { sys.suspend |= (SUSPEND_RETRACT_COMPLETE|SUSPEND_HOLD_COMPLETE); } + sys.state = STATE_SLEEP; + } + + system_clear_exec_state_flag((EXEC_MOTION_CANCEL | EXEC_FEED_HOLD | EXEC_SAFETY_DOOR | EXEC_SLEEP)); + } + + // Execute a cycle start by starting the stepper interrupt to begin executing the blocks in queue. + if (rt_exec & EXEC_CYCLE_START) { + // Block if called at same time as the hold commands: feed hold, motion cancel, and safety door. + // Ensures auto-cycle-start doesn't resume a hold without an explicit user-input. + if (!(rt_exec & (EXEC_FEED_HOLD | EXEC_MOTION_CANCEL | EXEC_SAFETY_DOOR))) { + // Resume door state when parking motion has retracted and door has been closed. + if ((sys.state == STATE_SAFETY_DOOR) && !(sys.suspend & SUSPEND_SAFETY_DOOR_AJAR)) { + if (sys.suspend & SUSPEND_RESTORE_COMPLETE) { + sys.state = STATE_IDLE; // Set to IDLE to immediately resume the cycle. + } else if (sys.suspend & SUSPEND_RETRACT_COMPLETE) { + // Flag to re-energize powered components and restore original position, if disabled by SAFETY_DOOR. + // NOTE: For a safety door to resume, the switch must be closed, as indicated by HOLD state, and + // the retraction execution is complete, which implies the initial feed hold is not active. To + // restore normal operation, the restore procedures must be initiated by the following flag. Once, + // they are complete, it will call CYCLE_START automatically to resume and exit the suspend. + sys.suspend |= SUSPEND_INITIATE_RESTORE; + } + } + // Cycle start only when IDLE or when a hold is complete and ready to resume. + if ((sys.state == STATE_IDLE) || ((sys.state & STATE_HOLD) && (sys.suspend & SUSPEND_HOLD_COMPLETE))) { + if (sys.state == STATE_HOLD && sys.spindle_stop_ovr) { + sys.spindle_stop_ovr |= SPINDLE_STOP_OVR_RESTORE_CYCLE; // Set to restore in suspend routine and cycle start after. + } else { + // Start cycle only if queued motions exist in planner buffer and the motion is not canceled. + sys.step_control = STEP_CONTROL_NORMAL_OP; // Restore step control to normal operation + if (plan_get_current_block() && bit_isfalse(sys.suspend,SUSPEND_MOTION_CANCEL)) { + sys.suspend = SUSPEND_DISABLE; // Break suspend state. + sys.state = STATE_CYCLE; + st_prep_buffer(); // Initialize step segment buffer before beginning cycle. + st_wake_up(); + } else { // Otherwise, do nothing. Set and resume IDLE state. + sys.suspend = SUSPEND_DISABLE; // Break suspend state. + sys.state = STATE_IDLE; + } + } + } + } + system_clear_exec_state_flag(EXEC_CYCLE_START); + } + + if (rt_exec & EXEC_CYCLE_STOP) { + // Reinitializes the cycle plan and stepper system after a feed hold for a resume. Called by + // realtime command execution in the main program, ensuring that the planner re-plans safely. + // NOTE: Bresenham algorithm variables are still maintained through both the planner and stepper + // cycle reinitializations. The stepper path should continue exactly as if nothing has happened. + // NOTE: EXEC_CYCLE_STOP is set by the stepper subsystem when a cycle or feed hold completes. + if ((sys.state & (STATE_HOLD|STATE_SAFETY_DOOR|STATE_SLEEP)) && !(sys.soft_limit) && !(sys.suspend & SUSPEND_JOG_CANCEL)) { + // Hold complete. Set to indicate ready to resume. Remain in HOLD or DOOR states until user + // has issued a resume command or reset. + plan_cycle_reinitialize(); + if (sys.step_control & STEP_CONTROL_EXECUTE_HOLD) { sys.suspend |= SUSPEND_HOLD_COMPLETE; } + bit_false(sys.step_control,(STEP_CONTROL_EXECUTE_HOLD | STEP_CONTROL_EXECUTE_SYS_MOTION)); + } else { + // Motion complete. Includes CYCLE/JOG/HOMING states and jog cancel/motion cancel/soft limit events. + // NOTE: Motion and jog cancel both immediately return to idle after the hold completes. + if (sys.suspend & SUSPEND_JOG_CANCEL) { // For jog cancel, flush buffers and sync positions. + sys.step_control = STEP_CONTROL_NORMAL_OP; + plan_reset(); + st_reset(); + gc_sync_position(); + plan_sync_position(); + } + if (sys.suspend & SUSPEND_SAFETY_DOOR_AJAR) { // Only occurs when safety door opens during jog. + sys.suspend &= ~(SUSPEND_JOG_CANCEL); + sys.suspend |= SUSPEND_HOLD_COMPLETE; + sys.state = STATE_SAFETY_DOOR; + } else { + sys.suspend = SUSPEND_DISABLE; + sys.state = STATE_IDLE; + } + } + system_clear_exec_state_flag(EXEC_CYCLE_STOP); + } + } + + // Execute overrides. + rt_exec = sys_rt_exec_motion_override; // Copy volatile sys_rt_exec_motion_override + if (rt_exec) { + system_clear_exec_motion_overrides(); // Clear all motion override flags. + + uint8_t new_f_override = sys.f_override; + if (rt_exec & EXEC_FEED_OVR_RESET) { new_f_override = DEFAULT_FEED_OVERRIDE; } + if (rt_exec & EXEC_FEED_OVR_COARSE_PLUS) { new_f_override += FEED_OVERRIDE_COARSE_INCREMENT; } + if (rt_exec & EXEC_FEED_OVR_COARSE_MINUS) { new_f_override -= FEED_OVERRIDE_COARSE_INCREMENT; } + if (rt_exec & EXEC_FEED_OVR_FINE_PLUS) { new_f_override += FEED_OVERRIDE_FINE_INCREMENT; } + if (rt_exec & EXEC_FEED_OVR_FINE_MINUS) { new_f_override -= FEED_OVERRIDE_FINE_INCREMENT; } + new_f_override = min(new_f_override,MAX_FEED_RATE_OVERRIDE); + new_f_override = max(new_f_override,MIN_FEED_RATE_OVERRIDE); + + uint8_t new_r_override = sys.r_override; + if (rt_exec & EXEC_RAPID_OVR_RESET) { new_r_override = DEFAULT_RAPID_OVERRIDE; } + if (rt_exec & EXEC_RAPID_OVR_MEDIUM) { new_r_override = RAPID_OVERRIDE_MEDIUM; } + if (rt_exec & EXEC_RAPID_OVR_LOW) { new_r_override = RAPID_OVERRIDE_LOW; } + + if ((new_f_override != sys.f_override) || (new_r_override != sys.r_override)) { + sys.f_override = new_f_override; + sys.r_override = new_r_override; + sys.report_ovr_counter = 0; // Set to report change immediately + plan_update_velocity_profile_parameters(); + plan_cycle_reinitialize(); + } + } + + rt_exec = sys_rt_exec_accessory_override; + if (rt_exec) { + system_clear_exec_accessory_overrides(); // Clear all accessory override flags. + + // NOTE: Unlike motion overrides, spindle overrides do not require a planner reinitialization. + uint8_t last_s_override = sys.spindle_speed_ovr; + if (rt_exec & EXEC_SPINDLE_OVR_RESET) { last_s_override = DEFAULT_SPINDLE_SPEED_OVERRIDE; } + if (rt_exec & EXEC_SPINDLE_OVR_COARSE_PLUS) { last_s_override += SPINDLE_OVERRIDE_COARSE_INCREMENT; } + if (rt_exec & EXEC_SPINDLE_OVR_COARSE_MINUS) { last_s_override -= SPINDLE_OVERRIDE_COARSE_INCREMENT; } + if (rt_exec & EXEC_SPINDLE_OVR_FINE_PLUS) { last_s_override += SPINDLE_OVERRIDE_FINE_INCREMENT; } + if (rt_exec & EXEC_SPINDLE_OVR_FINE_MINUS) { last_s_override -= SPINDLE_OVERRIDE_FINE_INCREMENT; } + last_s_override = min(last_s_override,MAX_SPINDLE_SPEED_OVERRIDE); + last_s_override = max(last_s_override,MIN_SPINDLE_SPEED_OVERRIDE); + + if (last_s_override != sys.spindle_speed_ovr) { + sys.spindle_speed_ovr = last_s_override; + // NOTE: Spindle speed overrides during HOLD state are taken care of by suspend function. + if (sys.state == STATE_IDLE) { spindle_set_state(gc_state.modal.spindle, gc_state.spindle_speed); } + else { bit_true(sys.step_control, STEP_CONTROL_UPDATE_SPINDLE_PWM); } + sys.report_ovr_counter = 0; // Set to report change immediately + } + + if (rt_exec & EXEC_SPINDLE_OVR_STOP) { + // Spindle stop override allowed only while in HOLD state. + // NOTE: Report counters are set in spindle_set_state() when spindle stop is executed. + if (sys.state == STATE_HOLD) { + if (!(sys.spindle_stop_ovr)) { sys.spindle_stop_ovr = SPINDLE_STOP_OVR_INITIATE; } + else if (sys.spindle_stop_ovr & SPINDLE_STOP_OVR_ENABLED) { sys.spindle_stop_ovr |= SPINDLE_STOP_OVR_RESTORE; } + } + } + + // NOTE: Since coolant state always performs a planner sync whenever it changes, the current + // run state can be determined by checking the parser state. + // NOTE: Coolant overrides only operate during IDLE, CYCLE, HOLD, and JOG states. Ignored otherwise. + if (rt_exec & (EXEC_COOLANT_FLOOD_OVR_TOGGLE | EXEC_COOLANT_MIST_OVR_TOGGLE)) { + if ((sys.state == STATE_IDLE) || (sys.state & (STATE_CYCLE | STATE_HOLD | STATE_JOG))) { + uint8_t coolant_state = gc_state.modal.coolant; + #ifdef ENABLE_M7 + if (rt_exec & EXEC_COOLANT_MIST_OVR_TOGGLE) { + if (coolant_state & COOLANT_MIST_ENABLE) { bit_false(coolant_state,COOLANT_MIST_ENABLE); } + else { coolant_state |= COOLANT_MIST_ENABLE; } + } + if (rt_exec & EXEC_COOLANT_FLOOD_OVR_TOGGLE) { + if (coolant_state & COOLANT_FLOOD_ENABLE) { bit_false(coolant_state,COOLANT_FLOOD_ENABLE); } + else { coolant_state |= COOLANT_FLOOD_ENABLE; } + } + #else + if (coolant_state & COOLANT_FLOOD_ENABLE) { bit_false(coolant_state,COOLANT_FLOOD_ENABLE); } + else { coolant_state |= COOLANT_FLOOD_ENABLE; } + #endif + coolant_set_state(coolant_state); // Report counter set in coolant_set_state(). + gc_state.modal.coolant = coolant_state; + } + } + } + + #ifdef DEBUG + if (sys_rt_exec_debug) { + report_realtime_debug(); + sys_rt_exec_debug = 0; + } + #endif + + // Reload step segment buffer + if (sys.state & (STATE_CYCLE | STATE_HOLD | STATE_SAFETY_DOOR | STATE_HOMING | STATE_SLEEP| STATE_JOG)) { + st_prep_buffer(); + } + +} + + +// Handles Grbl system suspend procedures, such as feed hold, safety door, and parking motion. +// The system will enter this loop, create local variables for suspend tasks, and return to +// whatever function that invoked the suspend, such that Grbl resumes normal operation. +// This function is written in a way to promote custom parking motions. Simply use this as a +// template +static void protocol_exec_rt_suspend() +{ + #ifdef PARKING_ENABLE + // Declare and initialize parking local variables + float restore_target[N_AXIS]; + float parking_target[N_AXIS]; + float retract_waypoint = PARKING_PULLOUT_INCREMENT; + plan_line_data_t plan_data; + plan_line_data_t *pl_data = &plan_data; + memset(pl_data,0,sizeof(plan_line_data_t)); + pl_data->condition = (PL_COND_FLAG_SYSTEM_MOTION|PL_COND_FLAG_NO_FEED_OVERRIDE); + #ifdef USE_LINE_NUMBERS + pl_data->line_number = PARKING_MOTION_LINE_NUMBER; + #endif + #endif + + plan_block_t *block = plan_get_current_block(); + uint8_t restore_condition; + #ifdef VARIABLE_SPINDLE + float restore_spindle_speed; + if (block == NULL) { + restore_condition = (gc_state.modal.spindle | gc_state.modal.coolant); + restore_spindle_speed = gc_state.spindle_speed; + } else { + restore_condition = (block->condition & PL_COND_SPINDLE_MASK) | coolant_get_state(); + restore_spindle_speed = block->spindle_speed; + } + #ifdef DISABLE_LASER_DURING_HOLD + if (bit_istrue(settings.flags,BITFLAG_LASER_MODE)) { + system_set_exec_accessory_override_flag(EXEC_SPINDLE_OVR_STOP); + } + #endif + #else + if (block == NULL) { restore_condition = (gc_state.modal.spindle | gc_state.modal.coolant); } + else { restore_condition = (block->condition & PL_COND_SPINDLE_MASK) | coolant_get_state(); } + #endif + + while (sys.suspend) { + + if (sys.abort) { return; } + + // Block until initial hold is complete and the machine has stopped motion. + if (sys.suspend & SUSPEND_HOLD_COMPLETE) { + + // Parking manager. Handles de/re-energizing, switch state checks, and parking motions for + // the safety door and sleep states. + if (sys.state & (STATE_SAFETY_DOOR | STATE_SLEEP)) { + + // Handles retraction motions and de-energizing. + if (bit_isfalse(sys.suspend,SUSPEND_RETRACT_COMPLETE)) { + + // Ensure any prior spindle stop override is disabled at start of safety door routine. + sys.spindle_stop_ovr = SPINDLE_STOP_OVR_DISABLED; + + #ifndef PARKING_ENABLE + + spindle_set_state(SPINDLE_DISABLE,0.0); // De-energize + coolant_set_state(COOLANT_DISABLE); // De-energize + + #else + + // Get current position and store restore location and spindle retract waypoint. + system_convert_array_steps_to_mpos(parking_target,sys_position); + if (bit_isfalse(sys.suspend,SUSPEND_RESTART_RETRACT)) { + memcpy(restore_target,parking_target,sizeof(parking_target)); + retract_waypoint += restore_target[PARKING_AXIS]; + retract_waypoint = min(retract_waypoint,PARKING_TARGET); + } + + // Execute slow pull-out parking retract motion. Parking requires homing enabled, the + // current location not exceeding the parking target location, and laser mode disabled. + // NOTE: State is will remain DOOR, until the de-energizing and retract is complete. + #ifdef ENABLE_PARKING_OVERRIDE_CONTROL + if ((bit_istrue(settings.flags,BITFLAG_HOMING_ENABLE)) && + (parking_target[PARKING_AXIS] < PARKING_TARGET) && + bit_isfalse(settings.flags,BITFLAG_LASER_MODE) && + (sys.override_ctrl == OVERRIDE_PARKING_MOTION)) { + #else + if ((bit_istrue(settings.flags,BITFLAG_HOMING_ENABLE)) && + (parking_target[PARKING_AXIS] < PARKING_TARGET) && + bit_isfalse(settings.flags,BITFLAG_LASER_MODE)) { + #endif + // Retract spindle by pullout distance. Ensure retraction motion moves away from + // the workpiece and waypoint motion doesn't exceed the parking target location. + if (parking_target[PARKING_AXIS] < retract_waypoint) { + parking_target[PARKING_AXIS] = retract_waypoint; + pl_data->feed_rate = PARKING_PULLOUT_RATE; + pl_data->condition |= (restore_condition & PL_COND_ACCESSORY_MASK); // Retain accessory state + pl_data->spindle_speed = restore_spindle_speed; + mc_parking_motion(parking_target, pl_data); + } + + // NOTE: Clear accessory state after retract and after an aborted restore motion. + pl_data->condition = (PL_COND_FLAG_SYSTEM_MOTION|PL_COND_FLAG_NO_FEED_OVERRIDE); + pl_data->spindle_speed = 0.0; + spindle_set_state(SPINDLE_DISABLE,0.0); // De-energize + coolant_set_state(COOLANT_DISABLE); // De-energize + + // Execute fast parking retract motion to parking target location. + if (parking_target[PARKING_AXIS] < PARKING_TARGET) { + parking_target[PARKING_AXIS] = PARKING_TARGET; + pl_data->feed_rate = PARKING_RATE; + mc_parking_motion(parking_target, pl_data); + } + + } else { + + // Parking motion not possible. Just disable the spindle and coolant. + // NOTE: Laser mode does not start a parking motion to ensure the laser stops immediately. + spindle_set_state(SPINDLE_DISABLE,0.0); // De-energize + coolant_set_state(COOLANT_DISABLE); // De-energize + + } + + #endif + + sys.suspend &= ~(SUSPEND_RESTART_RETRACT); + sys.suspend |= SUSPEND_RETRACT_COMPLETE; + + } else { + + + if (sys.state == STATE_SLEEP) { + report_feedback_message(MESSAGE_SLEEP_MODE); + // Spindle and coolant should already be stopped, but do it again just to be sure. + spindle_set_state(SPINDLE_DISABLE,0.0); // De-energize + coolant_set_state(COOLANT_DISABLE); // De-energize + st_go_idle(); // Disable steppers + while (!(sys.abort)) { protocol_exec_rt_system(); } // Do nothing until reset. + return; // Abort received. Return to re-initialize. + } + + // Allows resuming from parking/safety door. Actively checks if safety door is closed and ready to resume. + if (sys.state == STATE_SAFETY_DOOR) { + if (!(system_check_safety_door_ajar())) { + sys.suspend &= ~(SUSPEND_SAFETY_DOOR_AJAR); // Reset door ajar flag to denote ready to resume. + } + } + + // Handles parking restore and safety door resume. + if (sys.suspend & SUSPEND_INITIATE_RESTORE) { + + #ifdef PARKING_ENABLE + // Execute fast restore motion to the pull-out position. Parking requires homing enabled. + // NOTE: State is will remain DOOR, until the de-energizing and retract is complete. + #ifdef ENABLE_PARKING_OVERRIDE_CONTROL + if (((settings.flags & (BITFLAG_HOMING_ENABLE|BITFLAG_LASER_MODE)) == BITFLAG_HOMING_ENABLE) && + (sys.override_ctrl == OVERRIDE_PARKING_MOTION)) { + #else + if ((settings.flags & (BITFLAG_HOMING_ENABLE|BITFLAG_LASER_MODE)) == BITFLAG_HOMING_ENABLE) { + #endif + // Check to ensure the motion doesn't move below pull-out position. + if (parking_target[PARKING_AXIS] <= PARKING_TARGET) { + parking_target[PARKING_AXIS] = retract_waypoint; + pl_data->feed_rate = PARKING_RATE; + mc_parking_motion(parking_target, pl_data); + } + } + #endif + + // Delayed Tasks: Restart spindle and coolant, delay to power-up, then resume cycle. + if (gc_state.modal.spindle != SPINDLE_DISABLE) { + // Block if safety door re-opened during prior restore actions. + if (bit_isfalse(sys.suspend,SUSPEND_RESTART_RETRACT)) { + if (bit_istrue(settings.flags,BITFLAG_LASER_MODE)) { + // When in laser mode, ignore spindle spin-up delay. Set to turn on laser when cycle starts. + bit_true(sys.step_control, STEP_CONTROL_UPDATE_SPINDLE_PWM); + } else { + spindle_set_state((restore_condition & (PL_COND_FLAG_SPINDLE_CW | PL_COND_FLAG_SPINDLE_CCW)), restore_spindle_speed); + delay_sec(SAFETY_DOOR_SPINDLE_DELAY, DELAY_MODE_SYS_SUSPEND); + } + } + } + if (gc_state.modal.coolant != COOLANT_DISABLE) { + // Block if safety door re-opened during prior restore actions. + if (bit_isfalse(sys.suspend,SUSPEND_RESTART_RETRACT)) { + // NOTE: Laser mode will honor this delay. An exhaust system is often controlled by this pin. + coolant_set_state((restore_condition & (PL_COND_FLAG_COOLANT_FLOOD | PL_COND_FLAG_COOLANT_MIST))); + delay_sec(SAFETY_DOOR_COOLANT_DELAY, DELAY_MODE_SYS_SUSPEND); + } + } + + #ifdef PARKING_ENABLE + // Execute slow plunge motion from pull-out position to resume position. + #ifdef ENABLE_PARKING_OVERRIDE_CONTROL + if (((settings.flags & (BITFLAG_HOMING_ENABLE|BITFLAG_LASER_MODE)) == BITFLAG_HOMING_ENABLE) && + (sys.override_ctrl == OVERRIDE_PARKING_MOTION)) { + #else + if ((settings.flags & (BITFLAG_HOMING_ENABLE|BITFLAG_LASER_MODE)) == BITFLAG_HOMING_ENABLE) { + #endif + // Block if safety door re-opened during prior restore actions. + if (bit_isfalse(sys.suspend,SUSPEND_RESTART_RETRACT)) { + // Regardless if the retract parking motion was a valid/safe motion or not, the + // restore parking motion should logically be valid, either by returning to the + // original position through valid machine space or by not moving at all. + pl_data->feed_rate = PARKING_PULLOUT_RATE; + pl_data->condition |= (restore_condition & PL_COND_ACCESSORY_MASK); // Restore accessory state + pl_data->spindle_speed = restore_spindle_speed; + mc_parking_motion(restore_target, pl_data); + } + } + #endif + + if (bit_isfalse(sys.suspend,SUSPEND_RESTART_RETRACT)) { + sys.suspend |= SUSPEND_RESTORE_COMPLETE; + system_set_exec_state_flag(EXEC_CYCLE_START); // Set to resume program. + } + } + + } + + + } else { + + // Feed hold manager. Controls spindle stop override states. + // NOTE: Hold ensured as completed by condition check at the beginning of suspend routine. + if (sys.spindle_stop_ovr) { + // Handles beginning of spindle stop + if (sys.spindle_stop_ovr & SPINDLE_STOP_OVR_INITIATE) { + if (gc_state.modal.spindle != SPINDLE_DISABLE) { + spindle_set_state(SPINDLE_DISABLE,0.0); // De-energize + sys.spindle_stop_ovr = SPINDLE_STOP_OVR_ENABLED; // Set stop override state to enabled, if de-energized. + } else { + sys.spindle_stop_ovr = SPINDLE_STOP_OVR_DISABLED; // Clear stop override state + } + // Handles restoring of spindle state + } else if (sys.spindle_stop_ovr & (SPINDLE_STOP_OVR_RESTORE | SPINDLE_STOP_OVR_RESTORE_CYCLE)) { + if (gc_state.modal.spindle != SPINDLE_DISABLE) { + report_feedback_message(MESSAGE_SPINDLE_RESTORE); + if (bit_istrue(settings.flags,BITFLAG_LASER_MODE)) { + // When in laser mode, ignore spindle spin-up delay. Set to turn on laser when cycle starts. + bit_true(sys.step_control, STEP_CONTROL_UPDATE_SPINDLE_PWM); + } else { + spindle_set_state((restore_condition & (PL_COND_FLAG_SPINDLE_CW | PL_COND_FLAG_SPINDLE_CCW)), restore_spindle_speed); + } + } + if (sys.spindle_stop_ovr & SPINDLE_STOP_OVR_RESTORE_CYCLE) { + system_set_exec_state_flag(EXEC_CYCLE_START); // Set to resume program. + } + sys.spindle_stop_ovr = SPINDLE_STOP_OVR_DISABLED; // Clear stop override state + } + } else { + // Handles spindle state during hold. NOTE: Spindle speed overrides may be altered during hold state. + // NOTE: STEP_CONTROL_UPDATE_SPINDLE_PWM is automatically reset upon resume in step generator. + if (bit_istrue(sys.step_control, STEP_CONTROL_UPDATE_SPINDLE_PWM)) { + spindle_set_state((restore_condition & (PL_COND_FLAG_SPINDLE_CW | PL_COND_FLAG_SPINDLE_CCW)), restore_spindle_speed); + bit_false(sys.step_control, STEP_CONTROL_UPDATE_SPINDLE_PWM); + } + } + + } + } + + protocol_exec_rt_system(); + + } +} diff --git a/trunk/Arduino/GRBL_1.1f_Nano/protocol.h b/trunk/Arduino/GRBL_1.1f_Nano/protocol.h new file mode 100644 index 00000000..7bc6e92b --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f_Nano/protocol.h @@ -0,0 +1,49 @@ +/* + protocol.h - controls Grbl execution protocol and procedures + Part of Grbl + + Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC + Copyright (c) 2009-2011 Simen Svale Skogsrud + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +#ifndef protocol_h +#define protocol_h + +// Line buffer size from the serial input stream to be executed. +// NOTE: Not a problem except for extreme cases, but the line buffer size can be too small +// and g-code blocks can get truncated. Officially, the g-code standards support up to 256 +// characters. In future versions, this will be increased, when we know how much extra +// memory space we can invest into here or we re-write the g-code parser not to have this +// buffer. +#ifndef LINE_BUFFER_SIZE + #define LINE_BUFFER_SIZE 80 +#endif + +// Starts Grbl main loop. It handles all incoming characters from the serial port and executes +// them as they complete. It is also responsible for finishing the initialization procedures. +void protocol_main_loop(); + +// Checks and executes a realtime command at various stop points in main program +void protocol_execute_realtime(); +void protocol_exec_rt_system(); + +// Executes the auto cycle feature, if enabled. +void protocol_auto_cycle_start(); + +// Block until all buffered steps are executed +void protocol_buffer_synchronize(); + +#endif diff --git a/trunk/Arduino/GRBL_1.1f_Nano/report.c b/trunk/Arduino/GRBL_1.1f_Nano/report.c new file mode 100644 index 00000000..3e78b471 --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f_Nano/report.c @@ -0,0 +1,647 @@ +/* + report.c - reporting and messaging methods + Part of Grbl + + Copyright (c) 2012-2016 Sungeun K. Jeon for Gnea Research LLC + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +/* + This file functions as the primary feedback interface for Grbl. Any outgoing data, such + as the protocol status messages, feedback messages, and status reports, are stored here. + For the most part, these functions primarily are called from protocol.c methods. If a + different style feedback is desired (i.e. JSON), then a user can change these following + methods to accomodate their needs. +*/ + +#include "grbl.h" + + +// Internal report utilities to reduce flash with repetitive tasks turned into functions. +void report_util_setting_prefix(uint8_t n) { serial_write('$'); print_uint8_base10(n); serial_write('='); } +static void report_util_line_feed() { printPgmString(PSTR("\r\n")); } +static void report_util_feedback_line_feed() { serial_write(']'); report_util_line_feed(); } +static void report_util_gcode_modes_G() { printPgmString(PSTR(" G")); } +static void report_util_gcode_modes_M() { printPgmString(PSTR(" M")); } +// static void report_util_comment_line_feed() { serial_write(')'); report_util_line_feed(); } +static void report_util_axis_values(float *axis_value) { + uint8_t idx; + for (idx=0; idx= AXIS_SETTINGS_INCREMENT) { + n -= AXIS_SETTINGS_INCREMENT; + idx++; + } + serial_write(n+'x'); + switch (idx) { + case 0: printPgmString(PSTR(":stp/mm")); break; + case 1: printPgmString(PSTR(":mm/min")); break; + case 2: printPgmString(PSTR(":mm/s^2")); break; + case 3: printPgmString(PSTR(":mm max")); break; + } + break; + } + report_util_comment_line_feed(); +} +*/ + +static void report_util_uint8_setting(uint8_t n, int val) { + report_util_setting_prefix(n); + print_uint8_base10(val); + report_util_line_feed(); // report_util_setting_string(n); +} +static void report_util_float_setting(uint8_t n, float val, uint8_t n_decimal) { + report_util_setting_prefix(n); + printFloat(val,n_decimal); + report_util_line_feed(); // report_util_setting_string(n); +} + + +// Handles the primary confirmation protocol response for streaming interfaces and human-feedback. +// For every incoming line, this method responds with an 'ok' for a successful command or an +// 'error:' to indicate some error event with the line or some critical system error during +// operation. Errors events can originate from the g-code parser, settings module, or asynchronously +// from a critical error, such as a triggered hard limit. Interface should always monitor for these +// responses. +void report_status_message(uint8_t status_code) +{ + switch(status_code) { + case STATUS_OK: // STATUS_OK + printPgmString(PSTR("ok\r\n")); break; + default: + printPgmString(PSTR("error:")); + print_uint8_base10(status_code); + report_util_line_feed(); + } +} + +// Prints alarm messages. +void report_alarm_message(uint8_t alarm_code) +{ + printPgmString(PSTR("ALARM:")); + print_uint8_base10(alarm_code); + report_util_line_feed(); + delay_ms(500); // Force delay to ensure message clears serial write buffer. +} + +// Prints feedback messages. This serves as a centralized method to provide additional +// user feedback for things that are not of the status/alarm message protocol. These are +// messages such as setup warnings, switch toggling, and how to exit alarms. +// NOTE: For interfaces, messages are always placed within brackets. And if silent mode +// is installed, the message number codes are less than zero. +void report_feedback_message(uint8_t message_code) +{ + printPgmString(PSTR("[MSG:")); + switch(message_code) { + case MESSAGE_CRITICAL_EVENT: + printPgmString(PSTR("Reset to continue")); break; + case MESSAGE_ALARM_LOCK: + printPgmString(PSTR("'$H'|'$X' to unlock")); break; + case MESSAGE_ALARM_UNLOCK: + printPgmString(PSTR("Caution: Unlocked")); break; + case MESSAGE_ENABLED: + printPgmString(PSTR("Enabled")); break; + case MESSAGE_DISABLED: + printPgmString(PSTR("Disabled")); break; + case MESSAGE_SAFETY_DOOR_AJAR: + printPgmString(PSTR("Check Door")); break; + case MESSAGE_CHECK_LIMITS: + printPgmString(PSTR("Check Limits")); break; + case MESSAGE_PROGRAM_END: + printPgmString(PSTR("Pgm End")); break; + case MESSAGE_RESTORE_DEFAULTS: + printPgmString(PSTR("Restoring defaults")); break; + case MESSAGE_SPINDLE_RESTORE: + printPgmString(PSTR("Restoring spindle")); break; + case MESSAGE_SLEEP_MODE: + printPgmString(PSTR("Sleeping")); break; + } + report_util_feedback_line_feed(); +} + + +// Welcome message +void report_init_message() +{ + printPgmString(PSTR("\r\nGrbl " GRBL_VERSION " ['$' for help]\r\n")); +} + +// Grbl help message +void report_grbl_help() { + printPgmString(PSTR("[HLP:$$ $# $G $I $N $x=val $Nx=line $J=line $SLP $C $X $H ~ ! ? ctrl-x]\r\n")); +} + + +// Grbl global settings print out. +// NOTE: The numbering scheme here must correlate to storing in settings.c +void report_grbl_settings() { + // Print Grbl settings. + report_util_uint8_setting(0,settings.pulse_microseconds); + report_util_uint8_setting(1,settings.stepper_idle_lock_time); + report_util_uint8_setting(2,settings.step_invert_mask); + report_util_uint8_setting(3,settings.dir_invert_mask); + report_util_uint8_setting(4,bit_istrue(settings.flags,BITFLAG_INVERT_ST_ENABLE)); + report_util_uint8_setting(5,bit_istrue(settings.flags,BITFLAG_INVERT_LIMIT_PINS)); + report_util_uint8_setting(6,bit_istrue(settings.flags,BITFLAG_INVERT_PROBE_PIN)); + report_util_uint8_setting(10,settings.status_report_mask); + report_util_float_setting(11,settings.junction_deviation,N_DECIMAL_SETTINGVALUE); + report_util_float_setting(12,settings.arc_tolerance,N_DECIMAL_SETTINGVALUE); + report_util_uint8_setting(13,bit_istrue(settings.flags,BITFLAG_REPORT_INCHES)); + report_util_uint8_setting(20,bit_istrue(settings.flags,BITFLAG_SOFT_LIMIT_ENABLE)); + report_util_uint8_setting(21,bit_istrue(settings.flags,BITFLAG_HARD_LIMIT_ENABLE)); + report_util_uint8_setting(22,bit_istrue(settings.flags,BITFLAG_HOMING_ENABLE)); + report_util_uint8_setting(23,settings.homing_dir_mask); + report_util_float_setting(24,settings.homing_feed_rate,N_DECIMAL_SETTINGVALUE); + report_util_float_setting(25,settings.homing_seek_rate,N_DECIMAL_SETTINGVALUE); + report_util_uint8_setting(26,settings.homing_debounce_delay); + report_util_float_setting(27,settings.homing_pulloff,N_DECIMAL_SETTINGVALUE); + report_util_float_setting(30,settings.rpm_max,N_DECIMAL_RPMVALUE); + report_util_float_setting(31,settings.rpm_min,N_DECIMAL_RPMVALUE); + #ifdef VARIABLE_SPINDLE + report_util_uint8_setting(32,bit_istrue(settings.flags,BITFLAG_LASER_MODE)); + #else + report_util_uint8_setting(32,0); + #endif + // Print axis settings + uint8_t idx, set_idx; + uint8_t val = AXIS_SETTINGS_START_VAL; + for (set_idx=0; set_idx= MOTION_MODE_PROBE_TOWARD) { + printPgmString(PSTR("38.")); + print_uint8_base10(gc_state.modal.motion - (MOTION_MODE_PROBE_TOWARD-2)); + } else { + print_uint8_base10(gc_state.modal.motion); + } + + report_util_gcode_modes_G(); + print_uint8_base10(gc_state.modal.coord_select+54); + + report_util_gcode_modes_G(); + print_uint8_base10(gc_state.modal.plane_select+17); + + report_util_gcode_modes_G(); + print_uint8_base10(21-gc_state.modal.units); + + report_util_gcode_modes_G(); + print_uint8_base10(gc_state.modal.distance+90); + + report_util_gcode_modes_G(); + print_uint8_base10(94-gc_state.modal.feed_rate); + + if (gc_state.modal.program_flow) { + report_util_gcode_modes_M(); + switch (gc_state.modal.program_flow) { + case PROGRAM_FLOW_PAUSED : serial_write('0'); break; + // case PROGRAM_FLOW_OPTIONAL_STOP : serial_write('1'); break; // M1 is ignored and not supported. + case PROGRAM_FLOW_COMPLETED_M2 : + case PROGRAM_FLOW_COMPLETED_M30 : + print_uint8_base10(gc_state.modal.program_flow); + break; + } + } + + report_util_gcode_modes_M(); + switch (gc_state.modal.spindle) { + case SPINDLE_ENABLE_CW : serial_write('3'); break; + case SPINDLE_ENABLE_CCW : serial_write('4'); break; + case SPINDLE_DISABLE : serial_write('5'); break; + } + + #ifdef ENABLE_M7 + if (gc_state.modal.coolant) { // Note: Multiple coolant states may be active at the same time. + if (gc_state.modal.coolant & PL_COND_FLAG_COOLANT_MIST) { report_util_gcode_modes_M(); serial_write('7'); } + if (gc_state.modal.coolant & PL_COND_FLAG_COOLANT_FLOOD) { report_util_gcode_modes_M(); serial_write('8'); } + } else { report_util_gcode_modes_M(); serial_write('9'); } + #else + report_util_gcode_modes_M(); + if (gc_state.modal.coolant) { serial_write('8'); } + else { serial_write('9'); } + #endif + + #ifdef ENABLE_PARKING_OVERRIDE_CONTROL + if (sys.override_ctrl == OVERRIDE_PARKING_MOTION) { + report_util_gcode_modes_M(); + print_uint8_base10(56); + } + #endif + + printPgmString(PSTR(" T")); + print_uint8_base10(gc_state.tool); + + printPgmString(PSTR(" F")); + printFloat_RateValue(gc_state.feed_rate); + + #ifdef VARIABLE_SPINDLE + printPgmString(PSTR(" S")); + printFloat(gc_state.spindle_speed,N_DECIMAL_RPMVALUE); + #endif + + report_util_feedback_line_feed(); +} + +// Prints specified startup line +void report_startup_line(uint8_t n, char *line) +{ + printPgmString(PSTR("$N")); + print_uint8_base10(n); + serial_write('='); + printString(line); + report_util_line_feed(); +} + +void report_execute_startup_message(char *line, uint8_t status_code) +{ + serial_write('>'); + printString(line); + serial_write(':'); + report_status_message(status_code); +} + +// Prints build info line +void report_build_info(char *line) +{ + printPgmString(PSTR("[VER:" GRBL_VERSION "." GRBL_VERSION_BUILD ":")); + printString(line); + report_util_feedback_line_feed(); + printPgmString(PSTR("[OPT:")); // Generate compile-time build option list + #ifdef VARIABLE_SPINDLE + serial_write('V'); + #endif + #ifdef USE_LINE_NUMBERS + serial_write('N'); + #endif + #ifdef ENABLE_M7 + serial_write('M'); + #endif + #ifdef COREXY + serial_write('C'); + #endif + #ifdef PARKING_ENABLE + serial_write('P'); + #endif + #ifdef HOMING_FORCE_SET_ORIGIN + serial_write('Z'); + #endif + #ifdef HOMING_SINGLE_AXIS_COMMANDS + serial_write('H'); + #endif + #ifdef LIMITS_TWO_SWITCHES_ON_AXES + serial_write('T'); + #endif + #ifdef ALLOW_FEED_OVERRIDE_DURING_PROBE_CYCLES + serial_write('A'); + #endif + #ifdef USE_SPINDLE_DIR_AS_ENABLE_PIN + serial_write('D'); + #endif + #ifdef SPINDLE_ENABLE_OFF_WITH_ZERO_SPEED + serial_write('0'); + #endif + #ifdef ENABLE_SOFTWARE_DEBOUNCE + serial_write('S'); + #endif + #ifdef ENABLE_PARKING_OVERRIDE_CONTROL + serial_write('R'); + #endif + #ifndef HOMING_INIT_LOCK + serial_write('L'); + #endif + #ifdef ENABLE_SAFETY_DOOR_INPUT_PIN + serial_write('+'); + #endif + #ifndef ENABLE_RESTORE_EEPROM_WIPE_ALL // NOTE: Shown when disabled. + serial_write('*'); + #endif + #ifndef ENABLE_RESTORE_EEPROM_DEFAULT_SETTINGS // NOTE: Shown when disabled. + serial_write('$'); + #endif + #ifndef ENABLE_RESTORE_EEPROM_CLEAR_PARAMETERS // NOTE: Shown when disabled. + serial_write('#'); + #endif + #ifndef ENABLE_BUILD_INFO_WRITE_COMMAND // NOTE: Shown when disabled. + serial_write('I'); + #endif + #ifndef FORCE_BUFFER_SYNC_DURING_EEPROM_WRITE // NOTE: Shown when disabled. + serial_write('E'); + #endif + #ifndef FORCE_BUFFER_SYNC_DURING_WCO_CHANGE // NOTE: Shown when disabled. + serial_write('W'); + #endif + // NOTE: Compiled values, like override increments/max/min values, may be added at some point later. + serial_write(','); + print_uint8_base10(BLOCK_BUFFER_SIZE-1); + serial_write(','); + print_uint8_base10(RX_BUFFER_SIZE); + + report_util_feedback_line_feed(); +} + + +// Prints the character string line Grbl has received from the user, which has been pre-parsed, +// and has been sent into protocol_execute_line() routine to be executed by Grbl. +void report_echo_line_received(char *line) +{ + printPgmString(PSTR("[echo: ")); printString(line); + report_util_feedback_line_feed(); +} + + + // Prints real-time data. This function grabs a real-time snapshot of the stepper subprogram + // and the actual location of the CNC machine. Users may change the following function to their + // specific needs, but the desired real-time data report must be as short as possible. This is + // requires as it minimizes the computational overhead and allows grbl to keep running smoothly, + // especially during g-code programs with fast, short line segments and high frequency reports (5-20Hz). +void report_realtime_status() +{ + uint8_t idx; + int32_t current_position[N_AXIS]; // Copy current state of the system position variable + memcpy(current_position,sys_position,sizeof(sys_position)); + float print_position[N_AXIS]; + system_convert_array_steps_to_mpos(print_position,current_position); + + // Report current machine state and sub-states + serial_write('<'); + switch (sys.state) { + case STATE_IDLE: printPgmString(PSTR("Idle")); break; + case STATE_CYCLE: printPgmString(PSTR("Run")); break; + case STATE_HOLD: + if (!(sys.suspend & SUSPEND_JOG_CANCEL)) { + printPgmString(PSTR("Hold:")); + if (sys.suspend & SUSPEND_HOLD_COMPLETE) { serial_write('0'); } // Ready to resume + else { serial_write('1'); } // Actively holding + break; + } // Continues to print jog state during jog cancel. + case STATE_JOG: printPgmString(PSTR("Jog")); break; + case STATE_HOMING: printPgmString(PSTR("Home")); break; + case STATE_ALARM: printPgmString(PSTR("Alarm")); break; + case STATE_CHECK_MODE: printPgmString(PSTR("Check")); break; + case STATE_SAFETY_DOOR: + printPgmString(PSTR("Door:")); + if (sys.suspend & SUSPEND_INITIATE_RESTORE) { + serial_write('3'); // Restoring + } else { + if (sys.suspend & SUSPEND_RETRACT_COMPLETE) { + if (sys.suspend & SUSPEND_SAFETY_DOOR_AJAR) { + serial_write('1'); // Door ajar + } else { + serial_write('0'); + } // Door closed and ready to resume + } else { + serial_write('2'); // Retracting + } + } + break; + case STATE_SLEEP: printPgmString(PSTR("Sleep")); break; + } + + float wco[N_AXIS]; + if (bit_isfalse(settings.status_report_mask,BITFLAG_RT_STATUS_POSITION_TYPE) || + (sys.report_wco_counter == 0) ) { + for (idx=0; idx< N_AXIS; idx++) { + // Apply work coordinate offsets and tool length offset to current position. + wco[idx] = gc_state.coord_system[idx]+gc_state.coord_offset[idx]; + if (idx == TOOL_LENGTH_OFFSET_AXIS) { wco[idx] += gc_state.tool_length_offset; } + if (bit_isfalse(settings.status_report_mask,BITFLAG_RT_STATUS_POSITION_TYPE)) { + print_position[idx] -= wco[idx]; + } + } + } + + // Report machine position + if (bit_istrue(settings.status_report_mask,BITFLAG_RT_STATUS_POSITION_TYPE)) { + printPgmString(PSTR("|MPos:")); + } else { + printPgmString(PSTR("|WPos:")); + } + report_util_axis_values(print_position); + + // Returns planner and serial read buffer states. + #ifdef REPORT_FIELD_BUFFER_STATE + if (bit_istrue(settings.status_report_mask,BITFLAG_RT_STATUS_BUFFER_STATE)) { + printPgmString(PSTR("|Bf:")); + print_uint8_base10(plan_get_block_buffer_available()); + serial_write(','); + print_uint8_base10(serial_get_rx_buffer_available()); + } + #endif + + #ifdef USE_LINE_NUMBERS + #ifdef REPORT_FIELD_LINE_NUMBERS + // Report current line number + plan_block_t * cur_block = plan_get_current_block(); + if (cur_block != NULL) { + uint32_t ln = cur_block->line_number; + if (ln > 0) { + printPgmString(PSTR("|Ln:")); + printInteger(ln); + } + } + #endif + #endif + + // Report realtime feed speed + #ifdef REPORT_FIELD_CURRENT_FEED_SPEED + #ifdef VARIABLE_SPINDLE + printPgmString(PSTR("|FS:")); + printFloat_RateValue(st_get_realtime_rate()); + serial_write(','); + printFloat(sys.spindle_speed,N_DECIMAL_RPMVALUE); + #else + printPgmString(PSTR("|F:")); + printFloat_RateValue(st_get_realtime_rate()); + #endif + #endif + + #ifdef REPORT_FIELD_PIN_STATE + uint8_t lim_pin_state = limits_get_state(); + uint8_t ctrl_pin_state = system_control_get_state(); + uint8_t prb_pin_state = probe_get_state(); + if (lim_pin_state | ctrl_pin_state | prb_pin_state) { + printPgmString(PSTR("|Pn:")); + if (prb_pin_state) { serial_write('P'); } + if (lim_pin_state) { + if (bit_istrue(lim_pin_state,bit(X_AXIS))) { serial_write('X'); } + if (bit_istrue(lim_pin_state,bit(Y_AXIS))) { serial_write('Y'); } + if (bit_istrue(lim_pin_state,bit(Z_AXIS))) { serial_write('Z'); } + } + if (ctrl_pin_state) { + #ifdef ENABLE_SAFETY_DOOR_INPUT_PIN + if (bit_istrue(ctrl_pin_state,CONTROL_PIN_INDEX_SAFETY_DOOR)) { serial_write('D'); } + #endif + if (bit_istrue(ctrl_pin_state,CONTROL_PIN_INDEX_RESET)) { serial_write('R'); } + if (bit_istrue(ctrl_pin_state,CONTROL_PIN_INDEX_FEED_HOLD)) { serial_write('H'); } + if (bit_istrue(ctrl_pin_state,CONTROL_PIN_INDEX_CYCLE_START)) { serial_write('S'); } + } + } + #endif + + #ifdef REPORT_FIELD_WORK_COORD_OFFSET + if (sys.report_wco_counter > 0) { sys.report_wco_counter--; } + else { + if (sys.state & (STATE_HOMING | STATE_CYCLE | STATE_HOLD | STATE_JOG | STATE_SAFETY_DOOR)) { + sys.report_wco_counter = (REPORT_WCO_REFRESH_BUSY_COUNT-1); // Reset counter for slow refresh + } else { sys.report_wco_counter = (REPORT_WCO_REFRESH_IDLE_COUNT-1); } + if (sys.report_ovr_counter == 0) { sys.report_ovr_counter = 1; } // Set override on next report. + printPgmString(PSTR("|WCO:")); + report_util_axis_values(wco); + } + #endif + + #ifdef REPORT_FIELD_OVERRIDES + if (sys.report_ovr_counter > 0) { sys.report_ovr_counter--; } + else { + if (sys.state & (STATE_HOMING | STATE_CYCLE | STATE_HOLD | STATE_JOG | STATE_SAFETY_DOOR)) { + sys.report_ovr_counter = (REPORT_OVR_REFRESH_BUSY_COUNT-1); // Reset counter for slow refresh + } else { sys.report_ovr_counter = (REPORT_OVR_REFRESH_IDLE_COUNT-1); } + printPgmString(PSTR("|Ov:")); + print_uint8_base10(sys.f_override); + serial_write(','); + print_uint8_base10(sys.r_override); + serial_write(','); + print_uint8_base10(sys.spindle_speed_ovr); + + uint8_t sp_state = spindle_get_state(); + uint8_t cl_state = coolant_get_state(); + if (sp_state || cl_state) { + printPgmString(PSTR("|A:")); + if (sp_state) { // != SPINDLE_STATE_DISABLE + #ifdef VARIABLE_SPINDLE + #ifdef USE_SPINDLE_DIR_AS_ENABLE_PIN + serial_write('S'); // CW + #else + if (sp_state == SPINDLE_STATE_CW) { serial_write('S'); } // CW + else { serial_write('C'); } // CCW + #endif + #else + if (sp_state & SPINDLE_STATE_CW) { serial_write('S'); } // CW + else { serial_write('C'); } // CCW + #endif + } + if (cl_state & COOLANT_STATE_FLOOD) { serial_write('F'); } + #ifdef ENABLE_M7 + if (cl_state & COOLANT_STATE_MIST) { serial_write('M'); } + #endif + } + } + #endif + + serial_write('>'); + report_util_line_feed(); +} + + +#ifdef DEBUG + void report_realtime_debug() + { + + } +#endif diff --git a/trunk/Arduino/GRBL_1.1f_Nano/report.h b/trunk/Arduino/GRBL_1.1f_Nano/report.h new file mode 100644 index 00000000..f1480026 --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f_Nano/report.h @@ -0,0 +1,131 @@ +/* + report.h - reporting and messaging methods + Part of Grbl + + Copyright (c) 2012-2016 Sungeun K. Jeon for Gnea Research LLC + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ +#ifndef report_h +#define report_h + +// Define Grbl status codes. Valid values (0-255) +#define STATUS_OK 0 +#define STATUS_EXPECTED_COMMAND_LETTER 1 +#define STATUS_BAD_NUMBER_FORMAT 2 +#define STATUS_INVALID_STATEMENT 3 +#define STATUS_NEGATIVE_VALUE 4 +#define STATUS_SETTING_DISABLED 5 +#define STATUS_SETTING_STEP_PULSE_MIN 6 +#define STATUS_SETTING_READ_FAIL 7 +#define STATUS_IDLE_ERROR 8 +#define STATUS_SYSTEM_GC_LOCK 9 +#define STATUS_SOFT_LIMIT_ERROR 10 +#define STATUS_OVERFLOW 11 +#define STATUS_MAX_STEP_RATE_EXCEEDED 12 +#define STATUS_CHECK_DOOR 13 +#define STATUS_LINE_LENGTH_EXCEEDED 14 +#define STATUS_TRAVEL_EXCEEDED 15 +#define STATUS_INVALID_JOG_COMMAND 16 +#define STATUS_SETTING_DISABLED_LASER 17 + +#define STATUS_GCODE_UNSUPPORTED_COMMAND 20 +#define STATUS_GCODE_MODAL_GROUP_VIOLATION 21 +#define STATUS_GCODE_UNDEFINED_FEED_RATE 22 +#define STATUS_GCODE_COMMAND_VALUE_NOT_INTEGER 23 +#define STATUS_GCODE_AXIS_COMMAND_CONFLICT 24 +#define STATUS_GCODE_WORD_REPEATED 25 +#define STATUS_GCODE_NO_AXIS_WORDS 26 +#define STATUS_GCODE_INVALID_LINE_NUMBER 27 +#define STATUS_GCODE_VALUE_WORD_MISSING 28 +#define STATUS_GCODE_UNSUPPORTED_COORD_SYS 29 +#define STATUS_GCODE_G53_INVALID_MOTION_MODE 30 +#define STATUS_GCODE_AXIS_WORDS_EXIST 31 +#define STATUS_GCODE_NO_AXIS_WORDS_IN_PLANE 32 +#define STATUS_GCODE_INVALID_TARGET 33 +#define STATUS_GCODE_ARC_RADIUS_ERROR 34 +#define STATUS_GCODE_NO_OFFSETS_IN_PLANE 35 +#define STATUS_GCODE_UNUSED_WORDS 36 +#define STATUS_GCODE_G43_DYNAMIC_AXIS_ERROR 37 +#define STATUS_GCODE_MAX_VALUE_EXCEEDED 38 + +// Define Grbl alarm codes. Valid values (1-255). 0 is reserved. +#define ALARM_HARD_LIMIT_ERROR EXEC_ALARM_HARD_LIMIT +#define ALARM_SOFT_LIMIT_ERROR EXEC_ALARM_SOFT_LIMIT +#define ALARM_ABORT_CYCLE EXEC_ALARM_ABORT_CYCLE +#define ALARM_PROBE_FAIL_INITIAL EXEC_ALARM_PROBE_FAIL_INITIAL +#define ALARM_PROBE_FAIL_CONTACT EXEC_ALARM_PROBE_FAIL_CONTACT +#define ALARM_HOMING_FAIL_RESET EXEC_ALARM_HOMING_FAIL_RESET +#define ALARM_HOMING_FAIL_DOOR EXEC_ALARM_HOMING_FAIL_DOOR +#define ALARM_HOMING_FAIL_PULLOFF EXEC_ALARM_HOMING_FAIL_PULLOFF +#define ALARM_HOMING_FAIL_APPROACH EXEC_ALARM_HOMING_FAIL_APPROACH + +// Define Grbl feedback message codes. Valid values (0-255). +#define MESSAGE_CRITICAL_EVENT 1 +#define MESSAGE_ALARM_LOCK 2 +#define MESSAGE_ALARM_UNLOCK 3 +#define MESSAGE_ENABLED 4 +#define MESSAGE_DISABLED 5 +#define MESSAGE_SAFETY_DOOR_AJAR 6 +#define MESSAGE_CHECK_LIMITS 7 +#define MESSAGE_PROGRAM_END 8 +#define MESSAGE_RESTORE_DEFAULTS 9 +#define MESSAGE_SPINDLE_RESTORE 10 +#define MESSAGE_SLEEP_MODE 11 + +// Prints system status messages. +void report_status_message(uint8_t status_code); + +// Prints system alarm messages. +void report_alarm_message(uint8_t alarm_code); + +// Prints miscellaneous feedback messages. +void report_feedback_message(uint8_t message_code); + +// Prints welcome message +void report_init_message(); + +// Prints Grbl help and current global settings +void report_grbl_help(); + +// Prints Grbl global settings +void report_grbl_settings(); + +// Prints an echo of the pre-parsed line received right before execution. +void report_echo_line_received(char *line); + +// Prints realtime status report +void report_realtime_status(); + +// Prints recorded probe position +void report_probe_parameters(); + +// Prints Grbl NGC parameters (coordinate offsets, probe) +void report_ngc_parameters(); + +// Prints current g-code parser mode state +void report_gcode_modes(); + +// Prints startup line when requested and executed. +void report_startup_line(uint8_t n, char *line); +void report_execute_startup_message(char *line, uint8_t status_code); + +// Prints build info and user info +void report_build_info(char *line); + +#ifdef DEBUG + void report_realtime_debug(); +#endif + +#endif diff --git a/trunk/Arduino/GRBL_1.1f_Nano/serial.c b/trunk/Arduino/GRBL_1.1f_Nano/serial.c new file mode 100644 index 00000000..cf5f35e2 --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f_Nano/serial.c @@ -0,0 +1,204 @@ +/* + serial.c - Low level functions for sending and recieving bytes via the serial port + Part of Grbl + + Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC + Copyright (c) 2009-2011 Simen Svale Skogsrud + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +#include "grbl.h" + +#define RX_RING_BUFFER (RX_BUFFER_SIZE+1) +#define TX_RING_BUFFER (TX_BUFFER_SIZE+1) + +uint8_t serial_rx_buffer[RX_RING_BUFFER]; +uint8_t serial_rx_buffer_head = 0; +volatile uint8_t serial_rx_buffer_tail = 0; + +uint8_t serial_tx_buffer[TX_RING_BUFFER]; +uint8_t serial_tx_buffer_head = 0; +volatile uint8_t serial_tx_buffer_tail = 0; + + +// Returns the number of bytes available in the RX serial buffer. +uint8_t serial_get_rx_buffer_available() +{ + uint8_t rtail = serial_rx_buffer_tail; // Copy to limit multiple calls to volatile + if (serial_rx_buffer_head >= rtail) { return(RX_BUFFER_SIZE - (serial_rx_buffer_head-rtail)); } + return((rtail-serial_rx_buffer_head-1)); +} + + +// Returns the number of bytes used in the RX serial buffer. +// NOTE: Deprecated. Not used unless classic status reports are enabled in config.h. +uint8_t serial_get_rx_buffer_count() +{ + uint8_t rtail = serial_rx_buffer_tail; // Copy to limit multiple calls to volatile + if (serial_rx_buffer_head >= rtail) { return(serial_rx_buffer_head-rtail); } + return (RX_BUFFER_SIZE - (rtail-serial_rx_buffer_head)); +} + + +// Returns the number of bytes used in the TX serial buffer. +// NOTE: Not used except for debugging and ensuring no TX bottlenecks. +uint8_t serial_get_tx_buffer_count() +{ + uint8_t ttail = serial_tx_buffer_tail; // Copy to limit multiple calls to volatile + if (serial_tx_buffer_head >= ttail) { return(serial_tx_buffer_head-ttail); } + return (TX_RING_BUFFER - (ttail-serial_tx_buffer_head)); +} + + +void serial_init() +{ + // Set baud rate + #if BAUD_RATE < 57600 + uint16_t UBRR0_value = ((F_CPU / (8L * BAUD_RATE)) - 1)/2 ; + UCSR0A &= ~(1 << U2X0); // baud doubler off - Only needed on Uno XXX + #else + uint16_t UBRR0_value = ((F_CPU / (4L * BAUD_RATE)) - 1)/2; + UCSR0A |= (1 << U2X0); // baud doubler on for high baud rates, i.e. 115200 + #endif + UBRR0H = UBRR0_value >> 8; + UBRR0L = UBRR0_value; + + // enable rx, tx, and interrupt on complete reception of a byte + UCSR0B |= (1< 0x7F) { // Real-time control characters are extended ACSII only. + switch(data) { + case CMD_SAFETY_DOOR: system_set_exec_state_flag(EXEC_SAFETY_DOOR); break; // Set as true + case CMD_JOG_CANCEL: + if (sys.state & STATE_JOG) { // Block all other states from invoking motion cancel. + system_set_exec_state_flag(EXEC_MOTION_CANCEL); + } + break; + #ifdef DEBUG + case CMD_DEBUG_REPORT: {uint8_t sreg = SREG; cli(); bit_true(sys_rt_exec_debug,EXEC_DEBUG_REPORT); SREG = sreg;} break; + #endif + case CMD_FEED_OVR_RESET: system_set_exec_motion_override_flag(EXEC_FEED_OVR_RESET); break; + case CMD_FEED_OVR_COARSE_PLUS: system_set_exec_motion_override_flag(EXEC_FEED_OVR_COARSE_PLUS); break; + case CMD_FEED_OVR_COARSE_MINUS: system_set_exec_motion_override_flag(EXEC_FEED_OVR_COARSE_MINUS); break; + case CMD_FEED_OVR_FINE_PLUS: system_set_exec_motion_override_flag(EXEC_FEED_OVR_FINE_PLUS); break; + case CMD_FEED_OVR_FINE_MINUS: system_set_exec_motion_override_flag(EXEC_FEED_OVR_FINE_MINUS); break; + case CMD_RAPID_OVR_RESET: system_set_exec_motion_override_flag(EXEC_RAPID_OVR_RESET); break; + case CMD_RAPID_OVR_MEDIUM: system_set_exec_motion_override_flag(EXEC_RAPID_OVR_MEDIUM); break; + case CMD_RAPID_OVR_LOW: system_set_exec_motion_override_flag(EXEC_RAPID_OVR_LOW); break; + case CMD_SPINDLE_OVR_RESET: system_set_exec_accessory_override_flag(EXEC_SPINDLE_OVR_RESET); break; + case CMD_SPINDLE_OVR_COARSE_PLUS: system_set_exec_accessory_override_flag(EXEC_SPINDLE_OVR_COARSE_PLUS); break; + case CMD_SPINDLE_OVR_COARSE_MINUS: system_set_exec_accessory_override_flag(EXEC_SPINDLE_OVR_COARSE_MINUS); break; + case CMD_SPINDLE_OVR_FINE_PLUS: system_set_exec_accessory_override_flag(EXEC_SPINDLE_OVR_FINE_PLUS); break; + case CMD_SPINDLE_OVR_FINE_MINUS: system_set_exec_accessory_override_flag(EXEC_SPINDLE_OVR_FINE_MINUS); break; + case CMD_SPINDLE_OVR_STOP: system_set_exec_accessory_override_flag(EXEC_SPINDLE_OVR_STOP); break; + case CMD_COOLANT_FLOOD_OVR_TOGGLE: system_set_exec_accessory_override_flag(EXEC_COOLANT_FLOOD_OVR_TOGGLE); break; + #ifdef ENABLE_M7 + case CMD_COOLANT_MIST_OVR_TOGGLE: system_set_exec_accessory_override_flag(EXEC_COOLANT_MIST_OVR_TOGGLE); break; + #endif + } + // Throw away any unfound extended-ASCII character by not passing it to the serial buffer. + } else { // Write character to buffer + next_head = serial_rx_buffer_head + 1; + if (next_head == RX_RING_BUFFER) { next_head = 0; } + + // Write data to buffer unless it is full. + if (next_head != serial_rx_buffer_tail) { + serial_rx_buffer[serial_rx_buffer_head] = data; + serial_rx_buffer_head = next_head; + } + } + } +} + + +void serial_reset_read_buffer() +{ + serial_rx_buffer_tail = serial_rx_buffer_head; +} diff --git a/trunk/Arduino/GRBL_1.1f_Nano/serial.h b/trunk/Arduino/GRBL_1.1f_Nano/serial.h new file mode 100644 index 00000000..5a3f7761 --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f_Nano/serial.h @@ -0,0 +1,62 @@ +/* + serial.c - Low level functions for sending and recieving bytes via the serial port + Part of Grbl + + Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC + Copyright (c) 2009-2011 Simen Svale Skogsrud + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +#ifndef serial_h +#define serial_h + + +#ifndef RX_BUFFER_SIZE + #define RX_BUFFER_SIZE 128 +#endif +#ifndef TX_BUFFER_SIZE + #ifdef USE_LINE_NUMBERS + #define TX_BUFFER_SIZE 112 + #else + #define TX_BUFFER_SIZE 104 + #endif +#endif + +#define SERIAL_NO_DATA 0xff + + +void serial_init(); + +// Writes one byte to the TX serial buffer. Called by main program. +void serial_write(uint8_t data); + +// Fetches the first byte in the serial read buffer. Called by main program. +uint8_t serial_read(); + +// Reset and empty data in read buffer. Used by e-stop and reset. +void serial_reset_read_buffer(); + +// Returns the number of bytes available in the RX serial buffer. +uint8_t serial_get_rx_buffer_available(); + +// Returns the number of bytes used in the RX serial buffer. +// NOTE: Deprecated. Not used unless classic status reports are enabled in config.h. +uint8_t serial_get_rx_buffer_count(); + +// Returns the number of bytes used in the TX serial buffer. +// NOTE: Not used except for debugging and ensuring no TX bottlenecks. +uint8_t serial_get_tx_buffer_count(); + +#endif diff --git a/trunk/Arduino/GRBL_1.1f_Nano/settings.c b/trunk/Arduino/GRBL_1.1f_Nano/settings.c new file mode 100644 index 00000000..a9c830e7 --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f_Nano/settings.c @@ -0,0 +1,340 @@ +/* + settings.c - eeprom configuration handling + Part of Grbl + + Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC + Copyright (c) 2009-2011 Simen Svale Skogsrud + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +#include "grbl.h" + +settings_t settings; + +const __flash settings_t defaults = {\ + .pulse_microseconds = DEFAULT_STEP_PULSE_MICROSECONDS, + .stepper_idle_lock_time = DEFAULT_STEPPER_IDLE_LOCK_TIME, + .step_invert_mask = DEFAULT_STEPPING_INVERT_MASK, + .dir_invert_mask = DEFAULT_DIRECTION_INVERT_MASK, + .status_report_mask = DEFAULT_STATUS_REPORT_MASK, + .junction_deviation = DEFAULT_JUNCTION_DEVIATION, + .arc_tolerance = DEFAULT_ARC_TOLERANCE, + .rpm_max = DEFAULT_SPINDLE_RPM_MAX, + .rpm_min = DEFAULT_SPINDLE_RPM_MIN, + .homing_dir_mask = DEFAULT_HOMING_DIR_MASK, + .homing_feed_rate = DEFAULT_HOMING_FEED_RATE, + .homing_seek_rate = DEFAULT_HOMING_SEEK_RATE, + .homing_debounce_delay = DEFAULT_HOMING_DEBOUNCE_DELAY, + .homing_pulloff = DEFAULT_HOMING_PULLOFF, + .flags = (DEFAULT_REPORT_INCHES << BIT_REPORT_INCHES) | \ + (DEFAULT_LASER_MODE << BIT_LASER_MODE) | \ + (DEFAULT_INVERT_ST_ENABLE << BIT_INVERT_ST_ENABLE) | \ + (DEFAULT_HARD_LIMIT_ENABLE << BIT_HARD_LIMIT_ENABLE) | \ + (DEFAULT_HOMING_ENABLE << BIT_HOMING_ENABLE) | \ + (DEFAULT_SOFT_LIMIT_ENABLE << BIT_SOFT_LIMIT_ENABLE) | \ + (DEFAULT_INVERT_LIMIT_PINS << BIT_INVERT_LIMIT_PINS) | \ + (DEFAULT_INVERT_PROBE_PIN << BIT_INVERT_PROBE_PIN), + .steps_per_mm[X_AXIS] = DEFAULT_X_STEPS_PER_MM, + .steps_per_mm[Y_AXIS] = DEFAULT_Y_STEPS_PER_MM, + .steps_per_mm[Z_AXIS] = DEFAULT_Z_STEPS_PER_MM, + .max_rate[X_AXIS] = DEFAULT_X_MAX_RATE, + .max_rate[Y_AXIS] = DEFAULT_Y_MAX_RATE, + .max_rate[Z_AXIS] = DEFAULT_Z_MAX_RATE, + .acceleration[X_AXIS] = DEFAULT_X_ACCELERATION, + .acceleration[Y_AXIS] = DEFAULT_Y_ACCELERATION, + .acceleration[Z_AXIS] = DEFAULT_Z_ACCELERATION, + .max_travel[X_AXIS] = (-DEFAULT_X_MAX_TRAVEL), + .max_travel[Y_AXIS] = (-DEFAULT_Y_MAX_TRAVEL), + .max_travel[Z_AXIS] = (-DEFAULT_Z_MAX_TRAVEL)}; + + +// Method to store startup lines into EEPROM +void settings_store_startup_line(uint8_t n, char *line) +{ + #ifdef FORCE_BUFFER_SYNC_DURING_EEPROM_WRITE + protocol_buffer_synchronize(); // A startup line may contain a motion and be executing. + #endif + uint32_t addr = n*(LINE_BUFFER_SIZE+1)+EEPROM_ADDR_STARTUP_BLOCK; + memcpy_to_eeprom_with_checksum(addr,(char*)line, LINE_BUFFER_SIZE); +} + + +// Method to store build info into EEPROM +// NOTE: This function can only be called in IDLE state. +void settings_store_build_info(char *line) +{ + // Build info can only be stored when state is IDLE. + memcpy_to_eeprom_with_checksum(EEPROM_ADDR_BUILD_INFO,(char*)line, LINE_BUFFER_SIZE); +} + + +// Method to store coord data parameters into EEPROM +void settings_write_coord_data(uint8_t coord_select, float *coord_data) +{ + #ifdef FORCE_BUFFER_SYNC_DURING_EEPROM_WRITE + protocol_buffer_synchronize(); + #endif + uint32_t addr = coord_select*(sizeof(float)*N_AXIS+1) + EEPROM_ADDR_PARAMETERS; + memcpy_to_eeprom_with_checksum(addr,(char*)coord_data, sizeof(float)*N_AXIS); +} + + +// Method to store Grbl global settings struct and version number into EEPROM +// NOTE: This function can only be called in IDLE state. +void write_global_settings() +{ + eeprom_put_char(0, SETTINGS_VERSION); + memcpy_to_eeprom_with_checksum(EEPROM_ADDR_GLOBAL, (char*)&settings, sizeof(settings_t)); +} + + +// Method to restore EEPROM-saved Grbl global settings back to defaults. +void settings_restore(uint8_t restore_flag) { + if (restore_flag & SETTINGS_RESTORE_DEFAULTS) { + settings = defaults; + write_global_settings(); + } + + if (restore_flag & SETTINGS_RESTORE_PARAMETERS) { + uint8_t idx; + float coord_data[N_AXIS]; + memset(&coord_data, 0, sizeof(coord_data)); + for (idx=0; idx <= SETTING_INDEX_NCOORD; idx++) { settings_write_coord_data(idx, coord_data); } + } + + if (restore_flag & SETTINGS_RESTORE_STARTUP_LINES) { + #if N_STARTUP_LINE > 0 + eeprom_put_char(EEPROM_ADDR_STARTUP_BLOCK, 0); + eeprom_put_char(EEPROM_ADDR_STARTUP_BLOCK+1, 0); // Checksum + #endif + #if N_STARTUP_LINE > 1 + eeprom_put_char(EEPROM_ADDR_STARTUP_BLOCK+(LINE_BUFFER_SIZE+1), 0); + eeprom_put_char(EEPROM_ADDR_STARTUP_BLOCK+(LINE_BUFFER_SIZE+2), 0); // Checksum + #endif + } + + if (restore_flag & SETTINGS_RESTORE_BUILD_INFO) { + eeprom_put_char(EEPROM_ADDR_BUILD_INFO , 0); + eeprom_put_char(EEPROM_ADDR_BUILD_INFO+1 , 0); // Checksum + } +} + + +// Reads startup line from EEPROM. Updated pointed line string data. +uint8_t settings_read_startup_line(uint8_t n, char *line) +{ + uint32_t addr = n*(LINE_BUFFER_SIZE+1)+EEPROM_ADDR_STARTUP_BLOCK; + if (!(memcpy_from_eeprom_with_checksum((char*)line, addr, LINE_BUFFER_SIZE))) { + // Reset line with default value + line[0] = 0; // Empty line + settings_store_startup_line(n, line); + return(false); + } + return(true); +} + + +// Reads startup line from EEPROM. Updated pointed line string data. +uint8_t settings_read_build_info(char *line) +{ + if (!(memcpy_from_eeprom_with_checksum((char*)line, EEPROM_ADDR_BUILD_INFO, LINE_BUFFER_SIZE))) { + // Reset line with default value + line[0] = 0; // Empty line + settings_store_build_info(line); + return(false); + } + return(true); +} + + +// Read selected coordinate data from EEPROM. Updates pointed coord_data value. +uint8_t settings_read_coord_data(uint8_t coord_select, float *coord_data) +{ + uint32_t addr = coord_select*(sizeof(float)*N_AXIS+1) + EEPROM_ADDR_PARAMETERS; + if (!(memcpy_from_eeprom_with_checksum((char*)coord_data, addr, sizeof(float)*N_AXIS))) { + // Reset with default zero vector + clear_vector_float(coord_data); + settings_write_coord_data(coord_select,coord_data); + return(false); + } + return(true); +} + + +// Reads Grbl global settings struct from EEPROM. +uint8_t read_global_settings() { + // Check version-byte of eeprom + uint8_t version = eeprom_get_char(0); + if (version == SETTINGS_VERSION) { + // Read settings-record and check checksum + if (!(memcpy_from_eeprom_with_checksum((char*)&settings, EEPROM_ADDR_GLOBAL, sizeof(settings_t)))) { + return(false); + } + } else { + return(false); + } + return(true); +} + + +// A helper method to set settings from command line +uint8_t settings_store_global_setting(uint8_t parameter, float value) { + if (value < 0.0) { return(STATUS_NEGATIVE_VALUE); } + if (parameter >= AXIS_SETTINGS_START_VAL) { + // Store axis configuration. Axis numbering sequence set by AXIS_SETTING defines. + // NOTE: Ensure the setting index corresponds to the report.c settings printout. + parameter -= AXIS_SETTINGS_START_VAL; + uint8_t set_idx = 0; + while (set_idx < AXIS_N_SETTINGS) { + if (parameter < N_AXIS) { + // Valid axis setting found. + switch (set_idx) { + case 0: + #ifdef MAX_STEP_RATE_HZ + if (value*settings.max_rate[parameter] > (MAX_STEP_RATE_HZ*60.0)) { return(STATUS_MAX_STEP_RATE_EXCEEDED); } + #endif + settings.steps_per_mm[parameter] = value; + break; + case 1: + #ifdef MAX_STEP_RATE_HZ + if (value*settings.steps_per_mm[parameter] > (MAX_STEP_RATE_HZ*60.0)) { return(STATUS_MAX_STEP_RATE_EXCEEDED); } + #endif + settings.max_rate[parameter] = value; + break; + case 2: settings.acceleration[parameter] = value*60*60; break; // Convert to mm/min^2 for grbl internal use. + case 3: settings.max_travel[parameter] = -value; break; // Store as negative for grbl internal use. + } + break; // Exit while-loop after setting has been configured and proceed to the EEPROM write call. + } else { + set_idx++; + // If axis index greater than N_AXIS or setting index greater than number of axis settings, error out. + if ((parameter < AXIS_SETTINGS_INCREMENT) || (set_idx == AXIS_N_SETTINGS)) { return(STATUS_INVALID_STATEMENT); } + parameter -= AXIS_SETTINGS_INCREMENT; + } + } + } else { + // Store non-axis Grbl settings + uint8_t int_value = trunc(value); + switch(parameter) { + case 0: + if (int_value < 3) { return(STATUS_SETTING_STEP_PULSE_MIN); } + settings.pulse_microseconds = int_value; break; + case 1: settings.stepper_idle_lock_time = int_value; break; + case 2: + settings.step_invert_mask = int_value; + st_generate_step_dir_invert_masks(); // Regenerate step and direction port invert masks. + break; + case 3: + settings.dir_invert_mask = int_value; + st_generate_step_dir_invert_masks(); // Regenerate step and direction port invert masks. + break; + case 4: // Reset to ensure change. Immediate re-init may cause problems. + if (int_value) { settings.flags |= BITFLAG_INVERT_ST_ENABLE; } + else { settings.flags &= ~BITFLAG_INVERT_ST_ENABLE; } + break; + case 5: // Reset to ensure change. Immediate re-init may cause problems. + if (int_value) { settings.flags |= BITFLAG_INVERT_LIMIT_PINS; } + else { settings.flags &= ~BITFLAG_INVERT_LIMIT_PINS; } + break; + case 6: // Reset to ensure change. Immediate re-init may cause problems. + if (int_value) { settings.flags |= BITFLAG_INVERT_PROBE_PIN; } + else { settings.flags &= ~BITFLAG_INVERT_PROBE_PIN; } + probe_configure_invert_mask(false); + break; + case 10: settings.status_report_mask = int_value; break; + case 11: settings.junction_deviation = value; break; + case 12: settings.arc_tolerance = value; break; + case 13: + if (int_value) { settings.flags |= BITFLAG_REPORT_INCHES; } + else { settings.flags &= ~BITFLAG_REPORT_INCHES; } + system_flag_wco_change(); // Make sure WCO is immediately updated. + break; + case 20: + if (int_value) { + if (bit_isfalse(settings.flags, BITFLAG_HOMING_ENABLE)) { return(STATUS_SOFT_LIMIT_ERROR); } + settings.flags |= BITFLAG_SOFT_LIMIT_ENABLE; + } else { settings.flags &= ~BITFLAG_SOFT_LIMIT_ENABLE; } + break; + case 21: + if (int_value) { settings.flags |= BITFLAG_HARD_LIMIT_ENABLE; } + else { settings.flags &= ~BITFLAG_HARD_LIMIT_ENABLE; } + limits_init(); // Re-init to immediately change. NOTE: Nice to have but could be problematic later. + break; + case 22: + if (int_value) { settings.flags |= BITFLAG_HOMING_ENABLE; } + else { + settings.flags &= ~BITFLAG_HOMING_ENABLE; + settings.flags &= ~BITFLAG_SOFT_LIMIT_ENABLE; // Force disable soft-limits. + } + break; + case 23: settings.homing_dir_mask = int_value; break; + case 24: settings.homing_feed_rate = value; break; + case 25: settings.homing_seek_rate = value; break; + case 26: settings.homing_debounce_delay = int_value; break; + case 27: settings.homing_pulloff = value; break; + case 30: settings.rpm_max = value; spindle_init(); break; // Re-initialize spindle rpm calibration + case 31: settings.rpm_min = value; spindle_init(); break; // Re-initialize spindle rpm calibration + case 32: + #ifdef VARIABLE_SPINDLE + if (int_value) { settings.flags |= BITFLAG_LASER_MODE; } + else { settings.flags &= ~BITFLAG_LASER_MODE; } + #else + return(STATUS_SETTING_DISABLED_LASER); + #endif + break; + default: + return(STATUS_INVALID_STATEMENT); + } + } + write_global_settings(); + return(STATUS_OK); +} + + +// Initialize the config subsystem +void settings_init() { + if(!read_global_settings()) { + report_status_message(STATUS_SETTING_READ_FAIL); + settings_restore(SETTINGS_RESTORE_ALL); // Force restore all EEPROM data. + report_grbl_settings(); + } +} + + +// Returns step pin mask according to Grbl internal axis indexing. +uint8_t get_step_pin_mask(uint8_t axis_idx) +{ + if ( axis_idx == X_AXIS ) { return((1<. +*/ + +#ifndef settings_h +#define settings_h + +#include "grbl.h" + + +// Version of the EEPROM data. Will be used to migrate existing data from older versions of Grbl +// when firmware is upgraded. Always stored in byte 0 of eeprom +#define SETTINGS_VERSION 10 // NOTE: Check settings_reset() when moving to next version. + +// Define bit flag masks for the boolean settings in settings.flag. +#define BIT_REPORT_INCHES 0 +#define BIT_LASER_MODE 1 +#define BIT_INVERT_ST_ENABLE 2 +#define BIT_HARD_LIMIT_ENABLE 3 +#define BIT_HOMING_ENABLE 4 +#define BIT_SOFT_LIMIT_ENABLE 5 +#define BIT_INVERT_LIMIT_PINS 6 +#define BIT_INVERT_PROBE_PIN 7 + +#define BITFLAG_REPORT_INCHES bit(BIT_REPORT_INCHES) +#define BITFLAG_LASER_MODE bit(BIT_LASER_MODE) +#define BITFLAG_INVERT_ST_ENABLE bit(BIT_INVERT_ST_ENABLE) +#define BITFLAG_HARD_LIMIT_ENABLE bit(BIT_HARD_LIMIT_ENABLE) +#define BITFLAG_HOMING_ENABLE bit(BIT_HOMING_ENABLE) +#define BITFLAG_SOFT_LIMIT_ENABLE bit(BIT_SOFT_LIMIT_ENABLE) +#define BITFLAG_INVERT_LIMIT_PINS bit(BIT_INVERT_LIMIT_PINS) +#define BITFLAG_INVERT_PROBE_PIN bit(BIT_INVERT_PROBE_PIN) + +// Define status reporting boolean enable bit flags in settings.status_report_mask +#define BITFLAG_RT_STATUS_POSITION_TYPE bit(0) +#define BITFLAG_RT_STATUS_BUFFER_STATE bit(1) + +// Define settings restore bitflags. +#define SETTINGS_RESTORE_DEFAULTS bit(0) +#define SETTINGS_RESTORE_PARAMETERS bit(1) +#define SETTINGS_RESTORE_STARTUP_LINES bit(2) +#define SETTINGS_RESTORE_BUILD_INFO bit(3) +#ifndef SETTINGS_RESTORE_ALL + #define SETTINGS_RESTORE_ALL 0xFF // All bitflags +#endif + +// Define EEPROM memory address location values for Grbl settings and parameters +// NOTE: The Atmega328p has 1KB EEPROM. The upper half is reserved for parameters and +// the startup script. The lower half contains the global settings and space for future +// developments. +#define EEPROM_ADDR_GLOBAL 1U +#define EEPROM_ADDR_PARAMETERS 512U +#define EEPROM_ADDR_STARTUP_BLOCK 768U +#define EEPROM_ADDR_BUILD_INFO 942U + +// Define EEPROM address indexing for coordinate parameters +#define N_COORDINATE_SYSTEM 6 // Number of supported work coordinate systems (from index 1) +#define SETTING_INDEX_NCOORD N_COORDINATE_SYSTEM+1 // Total number of system stored (from index 0) +// NOTE: Work coordinate indices are (0=G54, 1=G55, ... , 6=G59) +#define SETTING_INDEX_G28 N_COORDINATE_SYSTEM // Home position 1 +#define SETTING_INDEX_G30 N_COORDINATE_SYSTEM+1 // Home position 2 +// #define SETTING_INDEX_G92 N_COORDINATE_SYSTEM+2 // Coordinate offset (G92.2,G92.3 not supported) + +// Define Grbl axis settings numbering scheme. Starts at START_VAL, every INCREMENT, over N_SETTINGS. +#define AXIS_N_SETTINGS 4 +#define AXIS_SETTINGS_START_VAL 100 // NOTE: Reserving settings values >= 100 for axis settings. Up to 255. +#define AXIS_SETTINGS_INCREMENT 10 // Must be greater than the number of axis settings + +// Global persistent settings (Stored from byte EEPROM_ADDR_GLOBAL onwards) +typedef struct { + // Axis settings + float steps_per_mm[N_AXIS]; + float max_rate[N_AXIS]; + float acceleration[N_AXIS]; + float max_travel[N_AXIS]; + + // Remaining Grbl settings + uint8_t pulse_microseconds; + uint8_t step_invert_mask; + uint8_t dir_invert_mask; + uint8_t stepper_idle_lock_time; // If max value 255, steppers do not disable. + uint8_t status_report_mask; // Mask to indicate desired report data. + float junction_deviation; + float arc_tolerance; + + float rpm_max; + float rpm_min; + + uint8_t flags; // Contains default boolean settings + + uint8_t homing_dir_mask; + float homing_feed_rate; + float homing_seek_rate; + uint16_t homing_debounce_delay; + float homing_pulloff; +} settings_t; +extern settings_t settings; + +// Initialize the configuration subsystem (load settings from EEPROM) +void settings_init(); + +// Helper function to clear and restore EEPROM defaults +void settings_restore(uint8_t restore_flag); + +// A helper method to set new settings from command line +uint8_t settings_store_global_setting(uint8_t parameter, float value); + +// Stores the protocol line variable as a startup line in EEPROM +void settings_store_startup_line(uint8_t n, char *line); + +// Reads an EEPROM startup line to the protocol line variable +uint8_t settings_read_startup_line(uint8_t n, char *line); + +// Stores build info user-defined string +void settings_store_build_info(char *line); + +// Reads build info user-defined string +uint8_t settings_read_build_info(char *line); + +// Writes selected coordinate data to EEPROM +void settings_write_coord_data(uint8_t coord_select, float *coord_data); + +// Reads selected coordinate data from EEPROM +uint8_t settings_read_coord_data(uint8_t coord_select, float *coord_data); + +// Returns the step pin mask according to Grbl's internal axis numbering +uint8_t get_step_pin_mask(uint8_t i); + +// Returns the direction pin mask according to Grbl's internal axis numbering +uint8_t get_direction_pin_mask(uint8_t i); + +// Returns the limit pin mask according to Grbl's internal axis numbering +uint8_t get_limit_pin_mask(uint8_t i); + + +#endif diff --git a/trunk/Arduino/GRBL_1.1f_Nano/spindle_control.c b/trunk/Arduino/GRBL_1.1f_Nano/spindle_control.c new file mode 100644 index 00000000..61cb90b8 --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f_Nano/spindle_control.c @@ -0,0 +1,283 @@ +/* + spindle_control.c - spindle control methods + Part of Grbl + + Copyright (c) 2012-2017 Sungeun K. Jeon for Gnea Research LLC + Copyright (c) 2009-2011 Simen Svale Skogsrud + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +#include "grbl.h" + + +#ifdef VARIABLE_SPINDLE + static float pwm_gradient; // Precalulated value to speed up rpm to PWM conversions. +#endif + + +void spindle_init() +{ + #ifdef VARIABLE_SPINDLE + + // Configure variable spindle PWM and enable pin, if requried. On the Uno, PWM and enable are + // combined unless configured otherwise. + SPINDLE_PWM_DDR |= (1<= settings.rpm_max) || (rpm >= RPM_MAX)) { + rpm = RPM_MAX; + pwm_value = SPINDLE_PWM_MAX_VALUE; + } else if (rpm <= RPM_MIN) { + if (rpm == 0.0) { // S0 disables spindle + pwm_value = SPINDLE_PWM_OFF_VALUE; + } else { + rpm = RPM_MIN; + pwm_value = SPINDLE_PWM_MIN_VALUE; + } + } else { + // Compute intermediate PWM value with linear spindle speed model via piecewise linear fit model. + #if (N_PIECES > 3) + if (rpm > RPM_POINT34) { + pwm_value = floor(RPM_LINE_A4*rpm - RPM_LINE_B4); + } else + #endif + #if (N_PIECES > 2) + if (rpm > RPM_POINT23) { + pwm_value = floor(RPM_LINE_A3*rpm - RPM_LINE_B3); + } else + #endif + #if (N_PIECES > 1) + if (rpm > RPM_POINT12) { + pwm_value = floor(RPM_LINE_A2*rpm - RPM_LINE_B2); + } else + #endif + { + pwm_value = floor(RPM_LINE_A1*rpm - RPM_LINE_B1); + } + } + sys.spindle_speed = rpm; + return(pwm_value); + } + + #else + + // Called by spindle_set_state() and step segment generator. Keep routine small and efficient. + uint8_t spindle_compute_pwm_value(float rpm) // 328p PWM register is 8-bit. + { + uint8_t pwm_value; + rpm *= (0.010*sys.spindle_speed_ovr); // Scale by spindle speed override value. + // Calculate PWM register value based on rpm max/min settings and programmed rpm. + if ((settings.rpm_min >= settings.rpm_max) || (rpm >= settings.rpm_max)) { + // No PWM range possible. Set simple on/off spindle control pin state. + sys.spindle_speed = settings.rpm_max; + pwm_value = SPINDLE_PWM_MAX_VALUE; + } else if (rpm <= settings.rpm_min) { + if (rpm == 0.0) { // S0 disables spindle + sys.spindle_speed = 0.0; + pwm_value = SPINDLE_PWM_OFF_VALUE; + } else { // Set minimum PWM output + sys.spindle_speed = settings.rpm_min; + pwm_value = SPINDLE_PWM_MIN_VALUE; + } + } else { + // Compute intermediate PWM value with linear spindle speed model. + // NOTE: A nonlinear model could be installed here, if required, but keep it VERY light-weight. + sys.spindle_speed = rpm; + pwm_value = floor((rpm-settings.rpm_min)*pwm_gradient) + SPINDLE_PWM_MIN_VALUE; + } + return(pwm_value); + } + + #endif +#endif + + +// Immediately sets spindle running state with direction and spindle rpm via PWM, if enabled. +// Called by g-code parser spindle_sync(), parking retract and restore, g-code program end, +// sleep, and spindle stop override. +#ifdef VARIABLE_SPINDLE + void spindle_set_state(uint8_t state, float rpm) +#else + void _spindle_set_state(uint8_t state) +#endif +{ + if (sys.abort) { return; } // Block during abort. + if (state == SPINDLE_DISABLE) { // Halt or set spindle direction and rpm. + + #ifdef VARIABLE_SPINDLE + sys.spindle_speed = 0.0; + #endif + spindle_stop(); + + } else { + + #ifndef USE_SPINDLE_DIR_AS_ENABLE_PIN + if (state == SPINDLE_ENABLE_CW) { + SPINDLE_DIRECTION_PORT &= ~(1<. +*/ + +#ifndef spindle_control_h +#define spindle_control_h + +#define SPINDLE_NO_SYNC false +#define SPINDLE_FORCE_SYNC true + +#define SPINDLE_STATE_DISABLE 0 // Must be zero. +#define SPINDLE_STATE_CW bit(0) +#define SPINDLE_STATE_CCW bit(1) + + +// Initializes spindle pins and hardware PWM, if enabled. +void spindle_init(); + +// Returns current spindle output state. Overrides may alter it from programmed states. +uint8_t spindle_get_state(); + +// Called by g-code parser when setting spindle state and requires a buffer sync. +// Immediately sets spindle running state with direction and spindle rpm via PWM, if enabled. +// Called by spindle_sync() after sync and parking motion/spindle stop override during restore. +#ifdef VARIABLE_SPINDLE + + // Called by g-code parser when setting spindle state and requires a buffer sync. + void spindle_sync(uint8_t state, float rpm); + + // Sets spindle running state with direction, enable, and spindle PWM. + void spindle_set_state(uint8_t state, float rpm); + + // Sets spindle PWM quickly for stepper ISR. Also called by spindle_set_state(). + // NOTE: 328p PWM register is 8-bit. + void spindle_set_speed(uint8_t pwm_value); + + // Computes 328p-specific PWM register value for the given RPM for quick updating. + uint8_t spindle_compute_pwm_value(float rpm); + +#else + + // Called by g-code parser when setting spindle state and requires a buffer sync. + #define spindle_sync(state, rpm) _spindle_sync(state) + void _spindle_sync(uint8_t state); + + // Sets spindle running state with direction and enable. + #define spindle_set_state(state, rpm) _spindle_set_state(state) + void _spindle_set_state(uint8_t state); + +#endif + +// Stop and start spindle routines. Called by all spindle routines and stepper ISR. +void spindle_stop(); + + +#endif diff --git a/trunk/Arduino/GRBL_1.1f_Nano/stepper.c b/trunk/Arduino/GRBL_1.1f_Nano/stepper.c new file mode 100644 index 00000000..3bfccd49 --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f_Nano/stepper.c @@ -0,0 +1,1022 @@ +/* + stepper.c - stepper motor driver: executes motion plans using stepper motors + Part of Grbl + + Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC + Copyright (c) 2009-2011 Simen Svale Skogsrud + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +#include "grbl.h" + + +// Some useful constants. +#define DT_SEGMENT (1.0/(ACCELERATION_TICKS_PER_SECOND*60.0)) // min/segment +#define REQ_MM_INCREMENT_SCALAR 1.25 +#define RAMP_ACCEL 0 +#define RAMP_CRUISE 1 +#define RAMP_DECEL 2 +#define RAMP_DECEL_OVERRIDE 3 + +#define PREP_FLAG_RECALCULATE bit(0) +#define PREP_FLAG_HOLD_PARTIAL_BLOCK bit(1) +#define PREP_FLAG_PARKING bit(2) +#define PREP_FLAG_DECEL_OVERRIDE bit(3) + +// Define Adaptive Multi-Axis Step-Smoothing(AMASS) levels and cutoff frequencies. The highest level +// frequency bin starts at 0Hz and ends at its cutoff frequency. The next lower level frequency bin +// starts at the next higher cutoff frequency, and so on. The cutoff frequencies for each level must +// be considered carefully against how much it over-drives the stepper ISR, the accuracy of the 16-bit +// timer, and the CPU overhead. Level 0 (no AMASS, normal operation) frequency bin starts at the +// Level 1 cutoff frequency and up to as fast as the CPU allows (over 30kHz in limited testing). +// NOTE: AMASS cutoff frequency multiplied by ISR overdrive factor must not exceed maximum step frequency. +// NOTE: Current settings are set to overdrive the ISR to no more than 16kHz, balancing CPU overhead +// and timer accuracy. Do not alter these settings unless you know what you are doing. +#ifdef ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING + #define MAX_AMASS_LEVEL 3 + // AMASS_LEVEL0: Normal operation. No AMASS. No upper cutoff frequency. Starts at LEVEL1 cutoff frequency. + #define AMASS_LEVEL1 (F_CPU/8000) // Over-drives ISR (x2). Defined as F_CPU/(Cutoff frequency in Hz) + #define AMASS_LEVEL2 (F_CPU/4000) // Over-drives ISR (x4) + #define AMASS_LEVEL3 (F_CPU/2000) // Over-drives ISR (x8) + + #if MAX_AMASS_LEVEL <= 0 + error "AMASS must have 1 or more levels to operate correctly." + #endif +#endif + + +// Stores the planner block Bresenham algorithm execution data for the segments in the segment +// buffer. Normally, this buffer is partially in-use, but, for the worst case scenario, it will +// never exceed the number of accessible stepper buffer segments (SEGMENT_BUFFER_SIZE-1). +// NOTE: This data is copied from the prepped planner blocks so that the planner blocks may be +// discarded when entirely consumed and completed by the segment buffer. Also, AMASS alters this +// data for its own use. +typedef struct { + uint32_t steps[N_AXIS]; + uint32_t step_event_count; + uint8_t direction_bits; + #ifdef VARIABLE_SPINDLE + uint8_t is_pwm_rate_adjusted; // Tracks motions that require constant laser power/rate + #endif +} st_block_t; +static st_block_t st_block_buffer[SEGMENT_BUFFER_SIZE-1]; + +// Primary stepper segment ring buffer. Contains small, short line segments for the stepper +// algorithm to execute, which are "checked-out" incrementally from the first block in the +// planner buffer. Once "checked-out", the steps in the segments buffer cannot be modified by +// the planner, where the remaining planner block steps still can. +typedef struct { + uint16_t n_step; // Number of step events to be executed for this segment + uint16_t cycles_per_tick; // Step distance traveled per ISR tick, aka step rate. + uint8_t st_block_index; // Stepper block data index. Uses this information to execute this segment. + #ifdef ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING + uint8_t amass_level; // Indicates AMASS level for the ISR to execute this segment + #else + uint8_t prescaler; // Without AMASS, a prescaler is required to adjust for slow timing. + #endif + #ifdef VARIABLE_SPINDLE + uint8_t spindle_pwm; + #endif +} segment_t; +static segment_t segment_buffer[SEGMENT_BUFFER_SIZE]; + +// Stepper ISR data struct. Contains the running data for the main stepper ISR. +typedef struct { + // Used by the bresenham line algorithm + uint32_t counter_x, // Counter variables for the bresenham line tracer + counter_y, + counter_z; + #ifdef STEP_PULSE_DELAY + uint8_t step_bits; // Stores out_bits output to complete the step pulse delay + #endif + + uint8_t execute_step; // Flags step execution for each interrupt. + uint8_t step_pulse_time; // Step pulse reset time after step rise + uint8_t step_outbits; // The next stepping-bits to be output + uint8_t dir_outbits; + #ifdef ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING + uint32_t steps[N_AXIS]; + #endif + + uint16_t step_count; // Steps remaining in line segment motion + uint8_t exec_block_index; // Tracks the current st_block index. Change indicates new block. + st_block_t *exec_block; // Pointer to the block data for the segment being executed + segment_t *exec_segment; // Pointer to the segment being executed +} stepper_t; +static stepper_t st; + +// Step segment ring buffer indices +static volatile uint8_t segment_buffer_tail; +static uint8_t segment_buffer_head; +static uint8_t segment_next_head; + +// Step and direction port invert masks. +static uint8_t step_port_invert_mask; +static uint8_t dir_port_invert_mask; + +// Used to avoid ISR nesting of the "Stepper Driver Interrupt". Should never occur though. +static volatile uint8_t busy; + +// Pointers for the step segment being prepped from the planner buffer. Accessed only by the +// main program. Pointers may be planning segments or planner blocks ahead of what being executed. +static plan_block_t *pl_block; // Pointer to the planner block being prepped +static st_block_t *st_prep_block; // Pointer to the stepper block data being prepped + +// Segment preparation data struct. Contains all the necessary information to compute new segments +// based on the current executing planner block. +typedef struct { + uint8_t st_block_index; // Index of stepper common data block being prepped + uint8_t recalculate_flag; + + float dt_remainder; + float steps_remaining; + float step_per_mm; + float req_mm_increment; + + #ifdef PARKING_ENABLE + uint8_t last_st_block_index; + float last_steps_remaining; + float last_step_per_mm; + float last_dt_remainder; + #endif + + uint8_t ramp_type; // Current segment ramp state + float mm_complete; // End of velocity profile from end of current planner block in (mm). + // NOTE: This value must coincide with a step(no mantissa) when converted. + float current_speed; // Current speed at the end of the segment buffer (mm/min) + float maximum_speed; // Maximum speed of executing block. Not always nominal speed. (mm/min) + float exit_speed; // Exit speed of executing block (mm/min) + float accelerate_until; // Acceleration ramp end measured from end of block (mm) + float decelerate_after; // Deceleration ramp start measured from end of block (mm) + + #ifdef VARIABLE_SPINDLE + float inv_rate; // Used by PWM laser mode to speed up segment calculations. + uint8_t current_spindle_pwm; + #endif +} st_prep_t; +static st_prep_t prep; + + +/* BLOCK VELOCITY PROFILE DEFINITION + __________________________ + /| |\ _________________ ^ + / | | \ /| |\ | + / | | \ / | | \ s + / | | | | | \ p + / | | | | | \ e + +-----+------------------------+---+--+---------------+----+ e + | BLOCK 1 ^ BLOCK 2 | d + | + time -----> EXAMPLE: Block 2 entry speed is at max junction velocity + + The planner block buffer is planned assuming constant acceleration velocity profiles and are + continuously joined at block junctions as shown above. However, the planner only actively computes + the block entry speeds for an optimal velocity plan, but does not compute the block internal + velocity profiles. These velocity profiles are computed ad-hoc as they are executed by the + stepper algorithm and consists of only 7 possible types of profiles: cruise-only, cruise- + deceleration, acceleration-cruise, acceleration-only, deceleration-only, full-trapezoid, and + triangle(no cruise). + + maximum_speed (< nominal_speed) -> + + +--------+ <- maximum_speed (= nominal_speed) /|\ + / \ / | \ + current_speed -> + \ / | + <- exit_speed + | + <- exit_speed / | | + +-------------+ current_speed -> +----+--+ + time --> ^ ^ ^ ^ + | | | | + decelerate_after(in mm) decelerate_after(in mm) + ^ ^ ^ ^ + | | | | + accelerate_until(in mm) accelerate_until(in mm) + + The step segment buffer computes the executing block velocity profile and tracks the critical + parameters for the stepper algorithm to accurately trace the profile. These critical parameters + are shown and defined in the above illustration. +*/ + + +// Stepper state initialization. Cycle should only start if the st.cycle_start flag is +// enabled. Startup init and limits call this function but shouldn't start the cycle. +void st_wake_up() +{ + // Enable stepper drivers. + if (bit_istrue(settings.flags,BITFLAG_INVERT_ST_ENABLE)) { STEPPERS_DISABLE_PORT |= (1<> 3); + // Set delay between direction pin write and step command. + OCR0A = -(((settings.pulse_microseconds)*TICKS_PER_MICROSECOND) >> 3); + #else // Normal operation + // Set step pulse time. Ad hoc computation from oscilloscope. Uses two's complement. + st.step_pulse_time = -(((settings.pulse_microseconds-2)*TICKS_PER_MICROSECOND) >> 3); + #endif + + // Enable Stepper Driver Interrupt + TIMSK1 |= (1<prescaler<cycles_per_tick; + st.step_count = st.exec_segment->n_step; // NOTE: Can sometimes be zero when moving slow. + // If the new segment starts a new planner block, initialize stepper variables and counters. + // NOTE: When the segment data index changes, this indicates a new planner block. + if ( st.exec_block_index != st.exec_segment->st_block_index ) { + st.exec_block_index = st.exec_segment->st_block_index; + st.exec_block = &st_block_buffer[st.exec_block_index]; + + // Initialize Bresenham line and distance counters + st.counter_x = st.counter_y = st.counter_z = (st.exec_block->step_event_count >> 1); + } + st.dir_outbits = st.exec_block->direction_bits ^ dir_port_invert_mask; + + #ifdef ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING + // With AMASS enabled, adjust Bresenham axis increment counters according to AMASS level. + st.steps[X_AXIS] = st.exec_block->steps[X_AXIS] >> st.exec_segment->amass_level; + st.steps[Y_AXIS] = st.exec_block->steps[Y_AXIS] >> st.exec_segment->amass_level; + st.steps[Z_AXIS] = st.exec_block->steps[Z_AXIS] >> st.exec_segment->amass_level; + #endif + + #ifdef VARIABLE_SPINDLE + // Set real-time spindle output as segment is loaded, just prior to the first step. + spindle_set_speed(st.exec_segment->spindle_pwm); + #endif + + } else { + // Segment buffer empty. Shutdown. + st_go_idle(); + #ifdef VARIABLE_SPINDLE + // Ensure pwm is set properly upon completion of rate-controlled motion. + if (st.exec_block->is_pwm_rate_adjusted) { spindle_set_speed(SPINDLE_PWM_OFF_VALUE); } + #endif + system_set_exec_state_flag(EXEC_CYCLE_STOP); // Flag main program for cycle end + return; // Nothing to do but exit. + } + } + + + // Check probing state. + if (sys_probe_state == PROBE_ACTIVE) { probe_state_monitor(); } + + // Reset step out bits. + st.step_outbits = 0; + + // Execute step displacement profile by Bresenham line algorithm + #ifdef ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING + st.counter_x += st.steps[X_AXIS]; + #else + st.counter_x += st.exec_block->steps[X_AXIS]; + #endif + if (st.counter_x > st.exec_block->step_event_count) { + st.step_outbits |= (1<step_event_count; + if (st.exec_block->direction_bits & (1<steps[Y_AXIS]; + #endif + if (st.counter_y > st.exec_block->step_event_count) { + st.step_outbits |= (1<step_event_count; + if (st.exec_block->direction_bits & (1<steps[Z_AXIS]; + #endif + if (st.counter_z > st.exec_block->step_event_count) { + st.step_outbits |= (1<step_event_count; + if (st.exec_block->direction_bits & (1<entry_speed_sqr = prep.current_speed*prep.current_speed; // Update entry speed. + pl_block = NULL; // Flag st_prep_segment() to load and check active velocity profile. + } +} + + +// Increments the step segment buffer block data ring buffer. +static uint8_t st_next_block_index(uint8_t block_index) +{ + block_index++; + if ( block_index == (SEGMENT_BUFFER_SIZE-1) ) { return(0); } + return(block_index); +} + + +#ifdef PARKING_ENABLE + // Changes the run state of the step segment buffer to execute the special parking motion. + void st_parking_setup_buffer() + { + // Store step execution data of partially completed block, if necessary. + if (prep.recalculate_flag & PREP_FLAG_HOLD_PARTIAL_BLOCK) { + prep.last_st_block_index = prep.st_block_index; + prep.last_steps_remaining = prep.steps_remaining; + prep.last_dt_remainder = prep.dt_remainder; + prep.last_step_per_mm = prep.step_per_mm; + } + // Set flags to execute a parking motion + prep.recalculate_flag |= PREP_FLAG_PARKING; + prep.recalculate_flag &= ~(PREP_FLAG_RECALCULATE); + pl_block = NULL; // Always reset parking motion to reload new block. + } + + + // Restores the step segment buffer to the normal run state after a parking motion. + void st_parking_restore_buffer() + { + // Restore step execution data and flags of partially completed block, if necessary. + if (prep.recalculate_flag & PREP_FLAG_HOLD_PARTIAL_BLOCK) { + st_prep_block = &st_block_buffer[prep.last_st_block_index]; + prep.st_block_index = prep.last_st_block_index; + prep.steps_remaining = prep.last_steps_remaining; + prep.dt_remainder = prep.last_dt_remainder; + prep.step_per_mm = prep.last_step_per_mm; + prep.recalculate_flag = (PREP_FLAG_HOLD_PARTIAL_BLOCK | PREP_FLAG_RECALCULATE); + prep.req_mm_increment = REQ_MM_INCREMENT_SCALAR/prep.step_per_mm; // Recompute this value. + } else { + prep.recalculate_flag = false; + } + pl_block = NULL; // Set to reload next block. + } +#endif + + +/* Prepares step segment buffer. Continuously called from main program. + + The segment buffer is an intermediary buffer interface between the execution of steps + by the stepper algorithm and the velocity profiles generated by the planner. The stepper + algorithm only executes steps within the segment buffer and is filled by the main program + when steps are "checked-out" from the first block in the planner buffer. This keeps the + step execution and planning optimization processes atomic and protected from each other. + The number of steps "checked-out" from the planner buffer and the number of segments in + the segment buffer is sized and computed such that no operation in the main program takes + longer than the time it takes the stepper algorithm to empty it before refilling it. + Currently, the segment buffer conservatively holds roughly up to 40-50 msec of steps. + NOTE: Computation units are in steps, millimeters, and minutes. +*/ +void st_prep_buffer() +{ + // Block step prep buffer, while in a suspend state and there is no suspend motion to execute. + if (bit_istrue(sys.step_control,STEP_CONTROL_END_MOTION)) { return; } + + while (segment_buffer_tail != segment_next_head) { // Check if we need to fill the buffer. + + // Determine if we need to load a new planner block or if the block needs to be recomputed. + if (pl_block == NULL) { + + // Query planner for a queued block + if (sys.step_control & STEP_CONTROL_EXECUTE_SYS_MOTION) { pl_block = plan_get_system_motion_block(); } + else { pl_block = plan_get_current_block(); } + if (pl_block == NULL) { return; } // No planner blocks. Exit. + + // Check if we need to only recompute the velocity profile or load a new block. + if (prep.recalculate_flag & PREP_FLAG_RECALCULATE) { + + #ifdef PARKING_ENABLE + if (prep.recalculate_flag & PREP_FLAG_PARKING) { prep.recalculate_flag &= ~(PREP_FLAG_RECALCULATE); } + else { prep.recalculate_flag = false; } + #else + prep.recalculate_flag = false; + #endif + + } else { + + // Load the Bresenham stepping data for the block. + prep.st_block_index = st_next_block_index(prep.st_block_index); + + // Prepare and copy Bresenham algorithm segment data from the new planner block, so that + // when the segment buffer completes the planner block, it may be discarded when the + // segment buffer finishes the prepped block, but the stepper ISR is still executing it. + st_prep_block = &st_block_buffer[prep.st_block_index]; + st_prep_block->direction_bits = pl_block->direction_bits; + uint8_t idx; + #ifndef ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING + for (idx=0; idxsteps[idx] = (pl_block->steps[idx] << 1); } + st_prep_block->step_event_count = (pl_block->step_event_count << 1); + #else + // With AMASS enabled, simply bit-shift multiply all Bresenham data by the max AMASS + // level, such that we never divide beyond the original data anywhere in the algorithm. + // If the original data is divided, we can lose a step from integer roundoff. + for (idx=0; idxsteps[idx] = pl_block->steps[idx] << MAX_AMASS_LEVEL; } + st_prep_block->step_event_count = pl_block->step_event_count << MAX_AMASS_LEVEL; + #endif + + // Initialize segment buffer data for generating the segments. + prep.steps_remaining = (float)pl_block->step_event_count; + prep.step_per_mm = prep.steps_remaining/pl_block->millimeters; + prep.req_mm_increment = REQ_MM_INCREMENT_SCALAR/prep.step_per_mm; + prep.dt_remainder = 0.0; // Reset for new segment block + + if ((sys.step_control & STEP_CONTROL_EXECUTE_HOLD) || (prep.recalculate_flag & PREP_FLAG_DECEL_OVERRIDE)) { + // New block loaded mid-hold. Override planner block entry speed to enforce deceleration. + prep.current_speed = prep.exit_speed; + pl_block->entry_speed_sqr = prep.exit_speed*prep.exit_speed; + prep.recalculate_flag &= ~(PREP_FLAG_DECEL_OVERRIDE); + } else { + prep.current_speed = sqrt(pl_block->entry_speed_sqr); + } + + #ifdef VARIABLE_SPINDLE + // Setup laser mode variables. PWM rate adjusted motions will always complete a motion with the + // spindle off. + st_prep_block->is_pwm_rate_adjusted = false; + if (settings.flags & BITFLAG_LASER_MODE) { + if (pl_block->condition & PL_COND_FLAG_SPINDLE_CCW) { + // Pre-compute inverse programmed rate to speed up PWM updating per step segment. + prep.inv_rate = 1.0/pl_block->programmed_rate; + st_prep_block->is_pwm_rate_adjusted = true; + } + } + #endif + } + + /* --------------------------------------------------------------------------------- + Compute the velocity profile of a new planner block based on its entry and exit + speeds, or recompute the profile of a partially-completed planner block if the + planner has updated it. For a commanded forced-deceleration, such as from a feed + hold, override the planner velocities and decelerate to the target exit speed. + */ + prep.mm_complete = 0.0; // Default velocity profile complete at 0.0mm from end of block. + float inv_2_accel = 0.5/pl_block->acceleration; + if (sys.step_control & STEP_CONTROL_EXECUTE_HOLD) { // [Forced Deceleration to Zero Velocity] + // Compute velocity profile parameters for a feed hold in-progress. This profile overrides + // the planner block profile, enforcing a deceleration to zero speed. + prep.ramp_type = RAMP_DECEL; + // Compute decelerate distance relative to end of block. + float decel_dist = pl_block->millimeters - inv_2_accel*pl_block->entry_speed_sqr; + if (decel_dist < 0.0) { + // Deceleration through entire planner block. End of feed hold is not in this block. + prep.exit_speed = sqrt(pl_block->entry_speed_sqr-2*pl_block->acceleration*pl_block->millimeters); + } else { + prep.mm_complete = decel_dist; // End of feed hold. + prep.exit_speed = 0.0; + } + } else { // [Normal Operation] + // Compute or recompute velocity profile parameters of the prepped planner block. + prep.ramp_type = RAMP_ACCEL; // Initialize as acceleration ramp. + prep.accelerate_until = pl_block->millimeters; + + float exit_speed_sqr; + float nominal_speed; + if (sys.step_control & STEP_CONTROL_EXECUTE_SYS_MOTION) { + prep.exit_speed = exit_speed_sqr = 0.0; // Enforce stop at end of system motion. + } else { + exit_speed_sqr = plan_get_exec_block_exit_speed_sqr(); + prep.exit_speed = sqrt(exit_speed_sqr); + } + + nominal_speed = plan_compute_profile_nominal_speed(pl_block); + float nominal_speed_sqr = nominal_speed*nominal_speed; + float intersect_distance = + 0.5*(pl_block->millimeters+inv_2_accel*(pl_block->entry_speed_sqr-exit_speed_sqr)); + + if (pl_block->entry_speed_sqr > nominal_speed_sqr) { // Only occurs during override reductions. + prep.accelerate_until = pl_block->millimeters - inv_2_accel*(pl_block->entry_speed_sqr-nominal_speed_sqr); + if (prep.accelerate_until <= 0.0) { // Deceleration-only. + prep.ramp_type = RAMP_DECEL; + // prep.decelerate_after = pl_block->millimeters; + // prep.maximum_speed = prep.current_speed; + + // Compute override block exit speed since it doesn't match the planner exit speed. + prep.exit_speed = sqrt(pl_block->entry_speed_sqr - 2*pl_block->acceleration*pl_block->millimeters); + prep.recalculate_flag |= PREP_FLAG_DECEL_OVERRIDE; // Flag to load next block as deceleration override. + + // TODO: Determine correct handling of parameters in deceleration-only. + // Can be tricky since entry speed will be current speed, as in feed holds. + // Also, look into near-zero speed handling issues with this. + + } else { + // Decelerate to cruise or cruise-decelerate types. Guaranteed to intersect updated plan. + prep.decelerate_after = inv_2_accel*(nominal_speed_sqr-exit_speed_sqr); // Should always be >= 0.0 due to planner reinit. + prep.maximum_speed = nominal_speed; + prep.ramp_type = RAMP_DECEL_OVERRIDE; + } + } else if (intersect_distance > 0.0) { + if (intersect_distance < pl_block->millimeters) { // Either trapezoid or triangle types + // NOTE: For acceleration-cruise and cruise-only types, following calculation will be 0.0. + prep.decelerate_after = inv_2_accel*(nominal_speed_sqr-exit_speed_sqr); + if (prep.decelerate_after < intersect_distance) { // Trapezoid type + prep.maximum_speed = nominal_speed; + if (pl_block->entry_speed_sqr == nominal_speed_sqr) { + // Cruise-deceleration or cruise-only type. + prep.ramp_type = RAMP_CRUISE; + } else { + // Full-trapezoid or acceleration-cruise types + prep.accelerate_until -= inv_2_accel*(nominal_speed_sqr-pl_block->entry_speed_sqr); + } + } else { // Triangle type + prep.accelerate_until = intersect_distance; + prep.decelerate_after = intersect_distance; + prep.maximum_speed = sqrt(2.0*pl_block->acceleration*intersect_distance+exit_speed_sqr); + } + } else { // Deceleration-only type + prep.ramp_type = RAMP_DECEL; + // prep.decelerate_after = pl_block->millimeters; + // prep.maximum_speed = prep.current_speed; + } + } else { // Acceleration-only type + prep.accelerate_until = 0.0; + // prep.decelerate_after = 0.0; + prep.maximum_speed = prep.exit_speed; + } + } + + #ifdef VARIABLE_SPINDLE + bit_true(sys.step_control, STEP_CONTROL_UPDATE_SPINDLE_PWM); // Force update whenever updating block. + #endif + } + + // Initialize new segment + segment_t *prep_segment = &segment_buffer[segment_buffer_head]; + + // Set new segment to point to the current segment data block. + prep_segment->st_block_index = prep.st_block_index; + + /*------------------------------------------------------------------------------------ + Compute the average velocity of this new segment by determining the total distance + traveled over the segment time DT_SEGMENT. The following code first attempts to create + a full segment based on the current ramp conditions. If the segment time is incomplete + when terminating at a ramp state change, the code will continue to loop through the + progressing ramp states to fill the remaining segment execution time. However, if + an incomplete segment terminates at the end of the velocity profile, the segment is + considered completed despite having a truncated execution time less than DT_SEGMENT. + The velocity profile is always assumed to progress through the ramp sequence: + acceleration ramp, cruising state, and deceleration ramp. Each ramp's travel distance + may range from zero to the length of the block. Velocity profiles can end either at + the end of planner block (typical) or mid-block at the end of a forced deceleration, + such as from a feed hold. + */ + float dt_max = DT_SEGMENT; // Maximum segment time + float dt = 0.0; // Initialize segment time + float time_var = dt_max; // Time worker variable + float mm_var; // mm-Distance worker variable + float speed_var; // Speed worker variable + float mm_remaining = pl_block->millimeters; // New segment distance from end of block. + float minimum_mm = mm_remaining-prep.req_mm_increment; // Guarantee at least one step. + if (minimum_mm < 0.0) { minimum_mm = 0.0; } + + do { + switch (prep.ramp_type) { + case RAMP_DECEL_OVERRIDE: + speed_var = pl_block->acceleration*time_var; + if (prep.current_speed-prep.maximum_speed <= speed_var) { + // Cruise or cruise-deceleration types only for deceleration override. + mm_remaining = prep.accelerate_until; + time_var = 2.0*(pl_block->millimeters-mm_remaining)/(prep.current_speed+prep.maximum_speed); + prep.ramp_type = RAMP_CRUISE; + prep.current_speed = prep.maximum_speed; + } else { // Mid-deceleration override ramp. + mm_remaining -= time_var*(prep.current_speed - 0.5*speed_var); + prep.current_speed -= speed_var; + } + break; + case RAMP_ACCEL: + // NOTE: Acceleration ramp only computes during first do-while loop. + speed_var = pl_block->acceleration*time_var; + mm_remaining -= time_var*(prep.current_speed + 0.5*speed_var); + if (mm_remaining < prep.accelerate_until) { // End of acceleration ramp. + // Acceleration-cruise, acceleration-deceleration ramp junction, or end of block. + mm_remaining = prep.accelerate_until; // NOTE: 0.0 at EOB + time_var = 2.0*(pl_block->millimeters-mm_remaining)/(prep.current_speed+prep.maximum_speed); + if (mm_remaining == prep.decelerate_after) { prep.ramp_type = RAMP_DECEL; } + else { prep.ramp_type = RAMP_CRUISE; } + prep.current_speed = prep.maximum_speed; + } else { // Acceleration only. + prep.current_speed += speed_var; + } + break; + case RAMP_CRUISE: + // NOTE: mm_var used to retain the last mm_remaining for incomplete segment time_var calculations. + // NOTE: If maximum_speed*time_var value is too low, round-off can cause mm_var to not change. To + // prevent this, simply enforce a minimum speed threshold in the planner. + mm_var = mm_remaining - prep.maximum_speed*time_var; + if (mm_var < prep.decelerate_after) { // End of cruise. + // Cruise-deceleration junction or end of block. + time_var = (mm_remaining - prep.decelerate_after)/prep.maximum_speed; + mm_remaining = prep.decelerate_after; // NOTE: 0.0 at EOB + prep.ramp_type = RAMP_DECEL; + } else { // Cruising only. + mm_remaining = mm_var; + } + break; + default: // case RAMP_DECEL: + // NOTE: mm_var used as a misc worker variable to prevent errors when near zero speed. + speed_var = pl_block->acceleration*time_var; // Used as delta speed (mm/min) + if (prep.current_speed > speed_var) { // Check if at or below zero speed. + // Compute distance from end of segment to end of block. + mm_var = mm_remaining - time_var*(prep.current_speed - 0.5*speed_var); // (mm) + if (mm_var > prep.mm_complete) { // Typical case. In deceleration ramp. + mm_remaining = mm_var; + prep.current_speed -= speed_var; + break; // Segment complete. Exit switch-case statement. Continue do-while loop. + } + } + // Otherwise, at end of block or end of forced-deceleration. + time_var = 2.0*(mm_remaining-prep.mm_complete)/(prep.current_speed+prep.exit_speed); + mm_remaining = prep.mm_complete; + prep.current_speed = prep.exit_speed; + } + dt += time_var; // Add computed ramp time to total segment time. + if (dt < dt_max) { time_var = dt_max - dt; } // **Incomplete** At ramp junction. + else { + if (mm_remaining > minimum_mm) { // Check for very slow segments with zero steps. + // Increase segment time to ensure at least one step in segment. Override and loop + // through distance calculations until minimum_mm or mm_complete. + dt_max += DT_SEGMENT; + time_var = dt_max - dt; + } else { + break; // **Complete** Exit loop. Segment execution time maxed. + } + } + } while (mm_remaining > prep.mm_complete); // **Complete** Exit loop. Profile complete. + + #ifdef VARIABLE_SPINDLE + /* ----------------------------------------------------------------------------------- + Compute spindle speed PWM output for step segment + */ + + if (st_prep_block->is_pwm_rate_adjusted || (sys.step_control & STEP_CONTROL_UPDATE_SPINDLE_PWM)) { + if (pl_block->condition & (PL_COND_FLAG_SPINDLE_CW | PL_COND_FLAG_SPINDLE_CCW)) { + float rpm = pl_block->spindle_speed; + // NOTE: Feed and rapid overrides are independent of PWM value and do not alter laser power/rate. + if (st_prep_block->is_pwm_rate_adjusted) { rpm *= (prep.current_speed * prep.inv_rate); } + // If current_speed is zero, then may need to be rpm_min*(100/MAX_SPINDLE_SPEED_OVERRIDE) + // but this would be instantaneous only and during a motion. May not matter at all. + prep.current_spindle_pwm = spindle_compute_pwm_value(rpm); + } else { + sys.spindle_speed = 0.0; + prep.current_spindle_pwm = SPINDLE_PWM_OFF_VALUE; + } + bit_false(sys.step_control,STEP_CONTROL_UPDATE_SPINDLE_PWM); + } + prep_segment->spindle_pwm = prep.current_spindle_pwm; // Reload segment PWM value + + #endif + + /* ----------------------------------------------------------------------------------- + Compute segment step rate, steps to execute, and apply necessary rate corrections. + NOTE: Steps are computed by direct scalar conversion of the millimeter distance + remaining in the block, rather than incrementally tallying the steps executed per + segment. This helps in removing floating point round-off issues of several additions. + However, since floats have only 7.2 significant digits, long moves with extremely + high step counts can exceed the precision of floats, which can lead to lost steps. + Fortunately, this scenario is highly unlikely and unrealistic in CNC machines + supported by Grbl (i.e. exceeding 10 meters axis travel at 200 step/mm). + */ + float step_dist_remaining = prep.step_per_mm*mm_remaining; // Convert mm_remaining to steps + float n_steps_remaining = ceil(step_dist_remaining); // Round-up current steps remaining + float last_n_steps_remaining = ceil(prep.steps_remaining); // Round-up last steps remaining + prep_segment->n_step = last_n_steps_remaining-n_steps_remaining; // Compute number of steps to execute. + + // Bail if we are at the end of a feed hold and don't have a step to execute. + if (prep_segment->n_step == 0) { + if (sys.step_control & STEP_CONTROL_EXECUTE_HOLD) { + // Less than one step to decelerate to zero speed, but already very close. AMASS + // requires full steps to execute. So, just bail. + bit_true(sys.step_control,STEP_CONTROL_END_MOTION); + #ifdef PARKING_ENABLE + if (!(prep.recalculate_flag & PREP_FLAG_PARKING)) { prep.recalculate_flag |= PREP_FLAG_HOLD_PARTIAL_BLOCK; } + #endif + return; // Segment not generated, but current step data still retained. + } + } + + // Compute segment step rate. Since steps are integers and mm distances traveled are not, + // the end of every segment can have a partial step of varying magnitudes that are not + // executed, because the stepper ISR requires whole steps due to the AMASS algorithm. To + // compensate, we track the time to execute the previous segment's partial step and simply + // apply it with the partial step distance to the current segment, so that it minutely + // adjusts the whole segment rate to keep step output exact. These rate adjustments are + // typically very small and do not adversely effect performance, but ensures that Grbl + // outputs the exact acceleration and velocity profiles as computed by the planner. + dt += prep.dt_remainder; // Apply previous segment partial step execute time + float inv_rate = dt/(last_n_steps_remaining - step_dist_remaining); // Compute adjusted step rate inverse + + // Compute CPU cycles per step for the prepped segment. + uint32_t cycles = ceil( (TICKS_PER_MICROSECOND*1000000*60)*inv_rate ); // (cycles/step) + + #ifdef ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING + // Compute step timing and multi-axis smoothing level. + // NOTE: AMASS overdrives the timer with each level, so only one prescalar is required. + if (cycles < AMASS_LEVEL1) { prep_segment->amass_level = 0; } + else { + if (cycles < AMASS_LEVEL2) { prep_segment->amass_level = 1; } + else if (cycles < AMASS_LEVEL3) { prep_segment->amass_level = 2; } + else { prep_segment->amass_level = 3; } + cycles >>= prep_segment->amass_level; + prep_segment->n_step <<= prep_segment->amass_level; + } + if (cycles < (1UL << 16)) { prep_segment->cycles_per_tick = cycles; } // < 65536 (4.1ms @ 16MHz) + else { prep_segment->cycles_per_tick = 0xffff; } // Just set the slowest speed possible. + #else + // Compute step timing and timer prescalar for normal step generation. + if (cycles < (1UL << 16)) { // < 65536 (4.1ms @ 16MHz) + prep_segment->prescaler = 1; // prescaler: 0 + prep_segment->cycles_per_tick = cycles; + } else if (cycles < (1UL << 19)) { // < 524288 (32.8ms@16MHz) + prep_segment->prescaler = 2; // prescaler: 8 + prep_segment->cycles_per_tick = cycles >> 3; + } else { + prep_segment->prescaler = 3; // prescaler: 64 + if (cycles < (1UL << 22)) { // < 4194304 (262ms@16MHz) + prep_segment->cycles_per_tick = cycles >> 6; + } else { // Just set the slowest speed possible. (Around 4 step/sec.) + prep_segment->cycles_per_tick = 0xffff; + } + } + #endif + + // Segment complete! Increment segment buffer indices, so stepper ISR can immediately execute it. + segment_buffer_head = segment_next_head; + if ( ++segment_next_head == SEGMENT_BUFFER_SIZE ) { segment_next_head = 0; } + + // Update the appropriate planner and segment data. + pl_block->millimeters = mm_remaining; + prep.steps_remaining = n_steps_remaining; + prep.dt_remainder = (n_steps_remaining - step_dist_remaining)*inv_rate; + + // Check for exit conditions and flag to load next planner block. + if (mm_remaining == prep.mm_complete) { + // End of planner block or forced-termination. No more distance to be executed. + if (mm_remaining > 0.0) { // At end of forced-termination. + // Reset prep parameters for resuming and then bail. Allow the stepper ISR to complete + // the segment queue, where realtime protocol will set new state upon receiving the + // cycle stop flag from the ISR. Prep_segment is blocked until then. + bit_true(sys.step_control,STEP_CONTROL_END_MOTION); + #ifdef PARKING_ENABLE + if (!(prep.recalculate_flag & PREP_FLAG_PARKING)) { prep.recalculate_flag |= PREP_FLAG_HOLD_PARTIAL_BLOCK; } + #endif + return; // Bail! + } else { // End of planner block + // The planner block is complete. All steps are set to be executed in the segment buffer. + if (sys.step_control & STEP_CONTROL_EXECUTE_SYS_MOTION) { + bit_true(sys.step_control,STEP_CONTROL_END_MOTION); + return; + } + pl_block = NULL; // Set pointer to indicate check and load next planner block. + plan_discard_current_block(); + } + } + + } +} + + +// Called by realtime status reporting to fetch the current speed being executed. This value +// however is not exactly the current speed, but the speed computed in the last step segment +// in the segment buffer. It will always be behind by up to the number of segment blocks (-1) +// divided by the ACCELERATION TICKS PER SECOND in seconds. +float st_get_realtime_rate() +{ + if (sys.state & (STATE_CYCLE | STATE_HOMING | STATE_HOLD | STATE_JOG | STATE_SAFETY_DOOR)){ + return prep.current_speed; + } + return 0.0f; +} diff --git a/trunk/Arduino/GRBL_1.1f_Nano/stepper.h b/trunk/Arduino/GRBL_1.1f_Nano/stepper.h new file mode 100644 index 00000000..41871a66 --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f_Nano/stepper.h @@ -0,0 +1,59 @@ +/* + stepper.h - stepper motor driver: executes motion plans of planner.c using the stepper motors + Part of Grbl + + Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC + Copyright (c) 2009-2011 Simen Svale Skogsrud + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +#ifndef stepper_h +#define stepper_h + +#ifndef SEGMENT_BUFFER_SIZE + #define SEGMENT_BUFFER_SIZE 6 +#endif + +// Initialize and setup the stepper motor subsystem +void stepper_init(); + +// Enable steppers, but cycle does not start unless called by motion control or realtime command. +void st_wake_up(); + +// Immediately disables steppers +void st_go_idle(); + +// Generate the step and direction port invert masks. +void st_generate_step_dir_invert_masks(); + +// Reset the stepper subsystem variables +void st_reset(); + +// Changes the run state of the step segment buffer to execute the special parking motion. +void st_parking_setup_buffer(); + +// Restores the step segment buffer to the normal run state after a parking motion. +void st_parking_restore_buffer(); + +// Reloads step segment buffer. Called continuously by realtime execution system. +void st_prep_buffer(); + +// Called by planner_recalculate() when the executing block is updated by the new plan. +void st_update_plan_block_parameters(); + +// Called by realtime status reporting if realtime rate reporting is enabled in config.h. +float st_get_realtime_rate(); + +#endif diff --git a/trunk/Arduino/GRBL_1.1f_Nano/system.c b/trunk/Arduino/GRBL_1.1f_Nano/system.c new file mode 100644 index 00000000..d1665fff --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f_Nano/system.c @@ -0,0 +1,407 @@ +/* + system.c - Handles system level commands and real-time processes + Part of Grbl + + Copyright (c) 2014-2016 Sungeun K. Jeon for Gnea Research LLC + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +#include "grbl.h" + + +void system_init() +{ + CONTROL_DDR &= ~(CONTROL_MASK); // Configure as input pins + #ifdef DISABLE_CONTROL_PIN_PULL_UP + CONTROL_PORT &= ~(CONTROL_MASK); // Normal low operation. Requires external pull-down. + #else + CONTROL_PORT |= CONTROL_MASK; // Enable internal pull-up resistors. Normal high operation. + #endif + CONTROL_PCMSK |= CONTROL_MASK; // Enable specific pins of the Pin Change Interrupt + PCICR |= (1 << CONTROL_INT); // Enable Pin Change Interrupt +} + + +// Returns control pin state as a uint8 bitfield. Each bit indicates the input pin state, where +// triggered is 1 and not triggered is 0. Invert mask is applied. Bitfield organization is +// defined by the CONTROL_PIN_INDEX in the header file. +uint8_t system_control_get_state() +{ + uint8_t control_state = 0; + uint8_t pin = (CONTROL_PIN & CONTROL_MASK); + #ifdef INVERT_CONTROL_PIN_MASK + pin ^= INVERT_CONTROL_PIN_MASK; + #endif + if (pin) { + #ifdef ENABLE_SAFETY_DOOR_INPUT_PIN + if (bit_isfalse(pin,(1< 255)) { return(STATUS_INVALID_STATEMENT); } + return(settings_store_global_setting((uint8_t)parameter, value)); + } + } + } + return(STATUS_OK); // If '$' command makes it to here, then everything's ok. +} + + + +void system_flag_wco_change() +{ + #ifdef FORCE_BUFFER_SYNC_DURING_WCO_CHANGE + protocol_buffer_synchronize(); + #endif + sys.report_wco_counter = 0; +} + + +// Returns machine position of axis 'idx'. Must be sent a 'step' array. +// NOTE: If motor steps and machine position are not in the same coordinate frame, this function +// serves as a central place to compute the transformation. +float system_convert_axis_steps_to_mpos(int32_t *steps, uint8_t idx) +{ + float pos; + #ifdef COREXY + if (idx==X_AXIS) { + pos = (float)system_convert_corexy_to_x_axis_steps(steps) / settings.steps_per_mm[idx]; + } else if (idx==Y_AXIS) { + pos = (float)system_convert_corexy_to_y_axis_steps(steps) / settings.steps_per_mm[idx]; + } else { + pos = steps[idx]/settings.steps_per_mm[idx]; + } + #else + pos = steps[idx]/settings.steps_per_mm[idx]; + #endif + return(pos); +} + + +void system_convert_array_steps_to_mpos(float *position, int32_t *steps) +{ + uint8_t idx; + for (idx=0; idx -settings.max_travel[idx]) { return(true); } + } else { + if (target[idx] > 0 || target[idx] < settings.max_travel[idx]) { return(true); } + } + #else + // NOTE: max_travel is stored as negative + if (target[idx] > 0 || target[idx] < settings.max_travel[idx]) { return(true); } + #endif + } + return(false); +} + + +// Special handlers for setting and clearing Grbl's real-time execution flags. +void system_set_exec_state_flag(uint8_t mask) { + uint8_t sreg = SREG; + cli(); + sys_rt_exec_state |= (mask); + SREG = sreg; +} + +void system_clear_exec_state_flag(uint8_t mask) { + uint8_t sreg = SREG; + cli(); + sys_rt_exec_state &= ~(mask); + SREG = sreg; +} + +void system_set_exec_alarm(uint8_t code) { + uint8_t sreg = SREG; + cli(); + sys_rt_exec_alarm = code; + SREG = sreg; +} + +void system_clear_exec_alarm() { + uint8_t sreg = SREG; + cli(); + sys_rt_exec_alarm = 0; + SREG = sreg; +} + +void system_set_exec_motion_override_flag(uint8_t mask) { + uint8_t sreg = SREG; + cli(); + sys_rt_exec_motion_override |= (mask); + SREG = sreg; +} + +void system_set_exec_accessory_override_flag(uint8_t mask) { + uint8_t sreg = SREG; + cli(); + sys_rt_exec_accessory_override |= (mask); + SREG = sreg; +} + +void system_clear_exec_motion_overrides() { + uint8_t sreg = SREG; + cli(); + sys_rt_exec_motion_override = 0; + SREG = sreg; +} + +void system_clear_exec_accessory_overrides() { + uint8_t sreg = SREG; + cli(); + sys_rt_exec_accessory_override = 0; + SREG = sreg; +} diff --git a/trunk/Arduino/GRBL_1.1f_Nano/system.h b/trunk/Arduino/GRBL_1.1f_Nano/system.h new file mode 100644 index 00000000..4d4f6128 --- /dev/null +++ b/trunk/Arduino/GRBL_1.1f_Nano/system.h @@ -0,0 +1,208 @@ +/* + system.h - Header for system level commands and real-time processes + Part of Grbl + + Copyright (c) 2014-2016 Sungeun K. Jeon for Gnea Research LLC + + Grbl is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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 . +*/ + +#ifndef system_h +#define system_h + +#include "grbl.h" + +// Define system executor bit map. Used internally by realtime protocol as realtime command flags, +// which notifies the main program to execute the specified realtime command asynchronously. +// NOTE: The system executor uses an unsigned 8-bit volatile variable (8 flag limit.) The default +// flags are always false, so the realtime protocol only needs to check for a non-zero value to +// know when there is a realtime command to execute. +#define EXEC_STATUS_REPORT bit(0) // bitmask 00000001 +#define EXEC_CYCLE_START bit(1) // bitmask 00000010 +#define EXEC_CYCLE_STOP bit(2) // bitmask 00000100 +#define EXEC_FEED_HOLD bit(3) // bitmask 00001000 +#define EXEC_RESET bit(4) // bitmask 00010000 +#define EXEC_SAFETY_DOOR bit(5) // bitmask 00100000 +#define EXEC_MOTION_CANCEL bit(6) // bitmask 01000000 +#define EXEC_SLEEP bit(7) // bitmask 10000000 + +// Alarm executor codes. Valid values (1-255). Zero is reserved. +#define EXEC_ALARM_HARD_LIMIT 1 +#define EXEC_ALARM_SOFT_LIMIT 2 +#define EXEC_ALARM_ABORT_CYCLE 3 +#define EXEC_ALARM_PROBE_FAIL_INITIAL 4 +#define EXEC_ALARM_PROBE_FAIL_CONTACT 5 +#define EXEC_ALARM_HOMING_FAIL_RESET 6 +#define EXEC_ALARM_HOMING_FAIL_DOOR 7 +#define EXEC_ALARM_HOMING_FAIL_PULLOFF 8 +#define EXEC_ALARM_HOMING_FAIL_APPROACH 9 + +// Override bit maps. Realtime bitflags to control feed, rapid, spindle, and coolant overrides. +// Spindle/coolant and feed/rapids are separated into two controlling flag variables. +#define EXEC_FEED_OVR_RESET bit(0) +#define EXEC_FEED_OVR_COARSE_PLUS bit(1) +#define EXEC_FEED_OVR_COARSE_MINUS bit(2) +#define EXEC_FEED_OVR_FINE_PLUS bit(3) +#define EXEC_FEED_OVR_FINE_MINUS bit(4) +#define EXEC_RAPID_OVR_RESET bit(5) +#define EXEC_RAPID_OVR_MEDIUM bit(6) +#define EXEC_RAPID_OVR_LOW bit(7) +// #define EXEC_RAPID_OVR_EXTRA_LOW bit(*) // *NOT SUPPORTED* + +#define EXEC_SPINDLE_OVR_RESET bit(0) +#define EXEC_SPINDLE_OVR_COARSE_PLUS bit(1) +#define EXEC_SPINDLE_OVR_COARSE_MINUS bit(2) +#define EXEC_SPINDLE_OVR_FINE_PLUS bit(3) +#define EXEC_SPINDLE_OVR_FINE_MINUS bit(4) +#define EXEC_SPINDLE_OVR_STOP bit(5) +#define EXEC_COOLANT_FLOOD_OVR_TOGGLE bit(6) +#define EXEC_COOLANT_MIST_OVR_TOGGLE bit(7) + +// Define system state bit map. The state variable primarily tracks the individual functions +// of Grbl to manage each without overlapping. It is also used as a messaging flag for +// critical events. +#define STATE_IDLE 0 // Must be zero. No flags. +#define STATE_ALARM bit(0) // In alarm state. Locks out all g-code processes. Allows settings access. +#define STATE_CHECK_MODE bit(1) // G-code check mode. Locks out planner and motion only. +#define STATE_HOMING bit(2) // Performing homing cycle +#define STATE_CYCLE bit(3) // Cycle is running or motions are being executed. +#define STATE_HOLD bit(4) // Active feed hold +#define STATE_JOG bit(5) // Jogging mode. +#define STATE_SAFETY_DOOR bit(6) // Safety door is ajar. Feed holds and de-energizes system. +#define STATE_SLEEP bit(7) // Sleep state. + +// Define system suspend flags. Used in various ways to manage suspend states and procedures. +#define SUSPEND_DISABLE 0 // Must be zero. +#define SUSPEND_HOLD_COMPLETE bit(0) // Indicates initial feed hold is complete. +#define SUSPEND_RESTART_RETRACT bit(1) // Flag to indicate a retract from a restore parking motion. +#define SUSPEND_RETRACT_COMPLETE bit(2) // (Safety door only) Indicates retraction and de-energizing is complete. +#define SUSPEND_INITIATE_RESTORE bit(3) // (Safety door only) Flag to initiate resume procedures from a cycle start. +#define SUSPEND_RESTORE_COMPLETE bit(4) // (Safety door only) Indicates ready to resume normal operation. +#define SUSPEND_SAFETY_DOOR_AJAR bit(5) // Tracks safety door state for resuming. +#define SUSPEND_MOTION_CANCEL bit(6) // Indicates a canceled resume motion. Currently used by probing routine. +#define SUSPEND_JOG_CANCEL bit(7) // Indicates a jog cancel in process and to reset buffers when complete. + +// Define step segment generator state flags. +#define STEP_CONTROL_NORMAL_OP 0 // Must be zero. +#define STEP_CONTROL_END_MOTION bit(0) +#define STEP_CONTROL_EXECUTE_HOLD bit(1) +#define STEP_CONTROL_EXECUTE_SYS_MOTION bit(2) +#define STEP_CONTROL_UPDATE_SPINDLE_PWM bit(3) + +// Define control pin index for Grbl internal use. Pin maps may change, but these values don't. +#ifdef ENABLE_SAFETY_DOOR_INPUT_PIN + #define N_CONTROL_PIN 4 + #define CONTROL_PIN_INDEX_SAFETY_DOOR bit(0) + #define CONTROL_PIN_INDEX_RESET bit(1) + #define CONTROL_PIN_INDEX_FEED_HOLD bit(2) + #define CONTROL_PIN_INDEX_CYCLE_START bit(3) +#else + #define N_CONTROL_PIN 3 + #define CONTROL_PIN_INDEX_RESET bit(0) + #define CONTROL_PIN_INDEX_FEED_HOLD bit(1) + #define CONTROL_PIN_INDEX_CYCLE_START bit(2) +#endif + +// Define spindle stop override control states. +#define SPINDLE_STOP_OVR_DISABLED 0 // Must be zero. +#define SPINDLE_STOP_OVR_ENABLED bit(0) +#define SPINDLE_STOP_OVR_INITIATE bit(1) +#define SPINDLE_STOP_OVR_RESTORE bit(2) +#define SPINDLE_STOP_OVR_RESTORE_CYCLE bit(3) + + +// Define global system variables +typedef struct { + uint8_t state; // Tracks the current system state of Grbl. + uint8_t abort; // System abort flag. Forces exit back to main loop for reset. + uint8_t suspend; // System suspend bitflag variable that manages holds, cancels, and safety door. + uint8_t soft_limit; // Tracks soft limit errors for the state machine. (boolean) + uint8_t step_control; // Governs the step segment generator depending on system state. + uint8_t probe_succeeded; // Tracks if last probing cycle was successful. + uint8_t homing_axis_lock; // Locks axes when limits engage. Used as an axis motion mask in the stepper ISR. + uint8_t f_override; // Feed rate override value in percent + uint8_t r_override; // Rapids override value in percent + uint8_t spindle_speed_ovr; // Spindle speed value in percent + uint8_t spindle_stop_ovr; // Tracks spindle stop override states + uint8_t report_ovr_counter; // Tracks when to add override data to status reports. + uint8_t report_wco_counter; // Tracks when to add work coordinate offset data to status reports. + #ifdef ENABLE_PARKING_OVERRIDE_CONTROL + uint8_t override_ctrl; // Tracks override control states. + #endif + #ifdef VARIABLE_SPINDLE + float spindle_speed; + #endif +} system_t; +extern system_t sys; + +// NOTE: These position variables may need to be declared as volatiles, if problems arise. +extern int32_t sys_position[N_AXIS]; // Real-time machine (aka home) position vector in steps. +extern int32_t sys_probe_position[N_AXIS]; // Last probe position in machine coordinates and steps. + +extern volatile uint8_t sys_probe_state; // Probing state value. Used to coordinate the probing cycle with stepper ISR. +extern volatile uint8_t sys_rt_exec_state; // Global realtime executor bitflag variable for state management. See EXEC bitmasks. +extern volatile uint8_t sys_rt_exec_alarm; // Global realtime executor bitflag variable for setting various alarms. +extern volatile uint8_t sys_rt_exec_motion_override; // Global realtime executor bitflag variable for motion-based overrides. +extern volatile uint8_t sys_rt_exec_accessory_override; // Global realtime executor bitflag variable for spindle/coolant overrides. + +#ifdef DEBUG + #define EXEC_DEBUG_REPORT bit(0) + extern volatile uint8_t sys_rt_exec_debug; +#endif + +// Initialize the serial protocol +void system_init(); + +// Returns bitfield of control pin states, organized by CONTROL_PIN_INDEX. (1=triggered, 0=not triggered). +uint8_t system_control_get_state(); + +// Returns if safety door is open or closed, based on pin state. +uint8_t system_check_safety_door_ajar(); + +// Executes an internal system command, defined as a string starting with a '$' +uint8_t system_execute_line(char *line); + +// Execute the startup script lines stored in EEPROM upon initialization +void system_execute_startup(char *line); + + +void system_flag_wco_change(); + +// Returns machine position of axis 'idx'. Must be sent a 'step' array. +float system_convert_axis_steps_to_mpos(int32_t *steps, uint8_t idx); + +// Updates a machine 'position' array based on the 'step' array sent. +void system_convert_array_steps_to_mpos(float *position, int32_t *steps); + +// CoreXY calculation only. Returns x or y-axis "steps" based on CoreXY motor steps. +#ifdef COREXY + int32_t system_convert_corexy_to_x_axis_steps(int32_t *steps); + int32_t system_convert_corexy_to_y_axis_steps(int32_t *steps); +#endif + +// Checks and reports if target array exceeds machine travel limits. +uint8_t system_check_travel_limits(float *target); + +// Special handlers for setting and clearing Grbl's real-time execution flags. +void system_set_exec_state_flag(uint8_t mask); +void system_clear_exec_state_flag(uint8_t mask); +void system_set_exec_alarm(uint8_t code); +void system_clear_exec_alarm(); +void system_set_exec_motion_override_flag(uint8_t mask); +void system_set_exec_accessory_override_flag(uint8_t mask); +void system_clear_exec_motion_overrides(); +void system_clear_exec_accessory_overrides(); + + +#endif diff --git a/trunk/Arduino/GRBL_Adafruit_motor_driverV2/GRBL_Adafruit_motor_driverV2.ino b/trunk/Arduino/GRBL_Adafruit_motor_driverV2/GRBL_Adafruit_motor_driverV2.ino new file mode 100644 index 00000000..ab0ecc38 --- /dev/null +++ b/trunk/Arduino/GRBL_Adafruit_motor_driverV2/GRBL_Adafruit_motor_driverV2.ino @@ -0,0 +1,58 @@ +/** + * Part of Grbl interpreter modified to work with Adafruit Motor Driver V2 + * File modified by Catalin Vasiliu + * email + * + * + * + * Original license:*********************************************************** + * Copyright (c) 2009-2011 Simen Svale Skogsrud + * Copyright (c) 2011 Sungeun K. Jeon + * + * Grbl is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Grbl is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +#include +#include +#include "utility/Adafruit_PWMServoDriver.h" +//#include + +#include +#include +#include + +#include "config.h" +#include "stepper_control.h" +#include "gcode.h" +#include "protocol.h" +#include "settings.h" +#include "serial.h" + + +void setup(void) +{ + shield_begin(); + + serial_init(BAUD_RATE); + protocol_init(); + settings_init(); + gc_init(); + motors_init(); + + + +} + +void loop() { + //process the serial protocol + protocol_process(); +} diff --git a/trunk/Arduino/GRBL_Adafruit_motor_driverV2/config.h b/trunk/Arduino/GRBL_Adafruit_motor_driverV2/config.h new file mode 100644 index 00000000..4d48d4a2 --- /dev/null +++ b/trunk/Arduino/GRBL_Adafruit_motor_driverV2/config.h @@ -0,0 +1,69 @@ +/* + * config.h - compile time configuration + */ +/** + * Part of Grbl interpreter modified to work with Adafruit Motor Driver V2 + * File created by Catalin Vasiliu + * email + */ + +#ifndef config_h +#define config_h + + #define BAUD_RATE 115200 + #define SPINDLE_PORT 1 //on adafruit motor shield + + + //limit swtch pins + #define X_LIMIT_START_PIN 2 + #define X_LIMIT_END_PIN 3 + #define Y_LIMIT_START_PIN 4 + #define Y_LIMIT_END_PIN 5 + #define Z_LIMIT_START_PIN 6 + #define Z_LIMIT_END_PIN 7 + + #define DEFAULT_WORK_AREA_X_AXIS 474.956 + #define DEFAULT_WORK_AREA_Y_AXIS 375.208 + #define DEFAULT_WORK_AREA_Z_AXIS 277.031 + + + + /* + * Number of arc generation iterations by small angle approximation before + * exact arc trajectory correction. This parameter maybe decreased if there + * are issues with the accuracy of the arc generations. In general, the + * default value is more than enough for the intended CNC applications of + * grbl, and should be on the order or greater than the size of the buffer + * to help with the computational efficiency of generating arcs. + */ + #define N_ARC_CORRECTION 25 // Integer (1-255) + + + //Default settings (used when resetting eeprom-settings) + #define DEFAULT_ROD_STEP 1.25 // mm per turn + #define DEFAULT_X_STEPS_PER_TURN 48 + #define DEFAULT_Y_STEPS_PER_TURN 48 + #define DEFAULT_Z_STEPS_PER_TURN 48 + + #define DEFAULT_MM_PER_ARC_SEGMENT 0.1 + #define DEFAULT_RAPID_FEEDRATE 500.0 // mm/min + #define DEFAULT_FEEDRATE 500.0 + #define DEFAULT_STEPPING_INVERT_MASK 1 + #define DEFAULT_SPINDLE_SPEED 255; + + /** + * default to zero for safety + */ + #define DEFAULT_LIMIT_SWITCH 0; + /* + * Some times motor can get very hot because the driver keep one coil + * energized to keep the motor blocked, so if you use rod transmission you + * don't need that holding torque and you can release the motors so they + * will be used only to move + * It can be changed from settings + */ + #define RELEASE_AFTER_MOVE 1; + + +#endif + diff --git a/trunk/Arduino/GRBL_Adafruit_motor_driverV2/eeprom.cpp b/trunk/Arduino/GRBL_Adafruit_motor_driverV2/eeprom.cpp new file mode 100644 index 00000000..4b37222b --- /dev/null +++ b/trunk/Arduino/GRBL_Adafruit_motor_driverV2/eeprom.cpp @@ -0,0 +1,174 @@ +/** + * Part of Grbl interpreter modified to work with Adafruit Motor Driver V2 + * File modified by Catalin Vasiliu + * email + * + * + * + * Original license:*********************************************************** + * Copyright (c) 2009-2011 Simen Svale Skogsrud + * Copyright (c) 2011 Sungeun K. Jeon + * + * Grbl is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Grbl is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +// This file has been prepared for Doxygen automatic documentation generation. +/*! \file ******************************************************************** + * + * Atmel Corporation + * + * \li File: eeprom.cpp + * \li Compiler: IAR EWAAVR 3.10c + * \li Support mail: avr@atmel.com + * + * \li Supported devices: All devices with split EEPROM erase/write + * capabilities can be used. + * The example is written for ATmega48. + * + * \li AppNote: AVR103 - Using the EEPROM Programming Modes. + * + * \li Description: Example on how to use the split EEPROM erase/write + * capabilities in e.g. ATmega48. All EEPROM + * programming modes are tested, i.e. Erase+Write, + * Erase-only and Write-only. + * + * $Revision: 1.6 $ + * $Date: Friday, February 11, 2005 07:16:44 UTC $ + ****************************************************************************/ + +#include +#include + +/* These EEPROM bits have different names on different devices. */ +#ifndef EEPE +#define EEPE EEWE //!< EEPROM program/write enable. +#define EEMPE EEMWE //!< EEPROM master program/write enable. +#endif + +/* These two are unfortunately not defined in the device include files. */ +#define EEPM1 5 //!< EEPROM Programming Mode Bit 1. +#define EEPM0 4 //!< EEPROM Programming Mode Bit 0. + +/* Define to reduce code size. */ +#define EEPROM_IGNORE_SELFPROG //!< Remove SPM flag polling. + +/*! \brief Read byte from EEPROM. + * + * This function reads one byte from a given EEPROM address. + * + * \note The CPU is halted for 4 clock cycles during EEPROM read. + * + * \param addr EEPROM address to read from. + * \return The byte read from the EEPROM address. + */ +unsigned char eeprom_get_char(unsigned int addr) { + do { + } while (EECR & (1 << EEPE)); // Wait for completion of previous write. + EEAR = addr; // Set EEPROM address register. + EECR = (1 << EERE); // Start EEPROM read operation. + return EEDR; // Return the byte read from EEPROM. +} + +/*! \brief Write byte to EEPROM. + * + * This function writes one byte to a given EEPROM address. + * The differences between the existing byte and the new value is used + * to select the most efficient EEPROM programming mode. + * + * \note The CPU is halted for 2 clock cycles during EEPROM programming. + * + * \note When this function returns, the new EEPROM value is not available + * until the EEPROM programming time has passed. The EEPE bit in EECR + * should be polled to check whether the programming is finished. + * + * \note The EEPROM_GetChar() function checks the EEPE bit automatically. + * + * \param addr EEPROM address to write to. + * \param new_value New EEPROM value. + */ +void eeprom_put_char(unsigned int addr, unsigned char new_value) { + char old_value; // Old EEPROM value. + char diff_mask; // Difference mask, i.e. old value XOR new value. + + cli(); // Ensure atomic operation for the write operation. + + do { + } while (EECR & (1 << EEPE)); // Wait for completion of previous write. +#ifndef EEPROM_IGNORE_SELFPROG + do { + } while (SPMCSR & (1 << SELFPRGEN)); // Wait for completion of SPM. +#endif + + EEAR = addr; // Set EEPROM address register. + EECR = (1 << EERE); // Start EEPROM read operation. + old_value = EEDR; // Get old EEPROM value. + diff_mask = old_value ^ new_value; // Get bit differences. + + // Check if any bits are changed to '1' in the new value. + if (diff_mask & new_value) { + // Now we know that _some_ bits need to be erased to '1'. + + // Check if any bits in the new value are '0'. + if (new_value != 0xff) { + // Now we know that some bits need to be programmed to '0' also. + + EEDR = new_value; // Set EEPROM data register. + EECR = (1 << EEMPE) | // Set Master Write Enable bit... + (0 << EEPM1) | (0 << EEPM0); // ...and Erase+Write mode. + EECR |= (1 << EEPE); // Start Erase+Write operation. + } else { + // Now we know that all bits should be erased. + + EECR = (1 << EEMPE) | // Set Master Write Enable bit... + (1 << EEPM0); // ...and Erase-only mode. + EECR |= (1 << EEPE); // Start Erase-only operation. + } + } else { + // Now we know that _no_ bits need to be erased to '1'. + + // Check if any bits are changed from '1' in the old value. + if (diff_mask) { + // Now we know that _some_ bits need to the programmed to '0'. + + EEDR = new_value; // Set EEPROM data register. + EECR = (1 << EEMPE) | // Set Master Write Enable bit... + (1 << EEPM1); // ...and Write-only mode. + EECR |= (1 << EEPE); // Start Write-only operation. + } + } + + sei(); // Restore interrupt flag state. +} + +// Extensions added as part of Grbl + +void memcpy_to_eeprom_with_checksum(unsigned int destination, unsigned char *source, unsigned int size) { + unsigned char checksum = 0; + for (; size > 0; size--) { + checksum = (checksum << 1) || (checksum >> 7); + checksum += *source; + eeprom_put_char(destination++, *(source++)); + } + eeprom_put_char(destination, checksum); +} + +int memcpy_from_eeprom_with_checksum(unsigned char *destination, unsigned int source, unsigned int size) { + unsigned char data, checksum = 0; + for (; size > 0; size--) { + data = eeprom_get_char(source++); + checksum = (checksum << 1) || (checksum >> 7); + checksum += data; + *(destination++) = data; + } + return (checksum == eeprom_get_char(source)); +} + +// end of file diff --git a/trunk/Arduino/GRBL_Adafruit_motor_driverV2/eeprom.h b/trunk/Arduino/GRBL_Adafruit_motor_driverV2/eeprom.h new file mode 100644 index 00000000..dadc466d --- /dev/null +++ b/trunk/Arduino/GRBL_Adafruit_motor_driverV2/eeprom.h @@ -0,0 +1,31 @@ +/** + * Part of Grbl interpreter modified to work with Adafruit Motor Driver V2 + * File modified by Catalin Vasiliu + * email + * + * + * + * Original license:*********************************************************** + * Copyright (c) 2009-2011 Simen Svale Skogsrud + * Copyright (c) 2011 Sungeun K. Jeon + * + * Grbl is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Grbl is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef eeprom_h +#define eeprom_h + +char eeprom_get_char(unsigned int addr); +void eeprom_put_char(unsigned int addr, unsigned char new_value); +void memcpy_to_eeprom_with_checksum(unsigned int destination, unsigned char *source, unsigned int size); +int memcpy_from_eeprom_with_checksum(unsigned char *destination, unsigned int source, unsigned int size); + +#endif diff --git a/trunk/Arduino/GRBL_Adafruit_motor_driverV2/g_print.cpp b/trunk/Arduino/GRBL_Adafruit_motor_driverV2/g_print.cpp new file mode 100644 index 00000000..04e41120 --- /dev/null +++ b/trunk/Arduino/GRBL_Adafruit_motor_driverV2/g_print.cpp @@ -0,0 +1,99 @@ +/* + print.cpp - Functions for formatting output strings + */ +/** + * Part of Grbl interpreter modified to work with Adafruit Motor Driver V2 + * File modified by Catalin Vasiliu + * email + * + * + * + * Original license:*********************************************************** + * Copyright (c) 2009-2011 Simen Svale Skogsrud + * Copyright (c) 2011 Sungeun K. Jeon + * + * Grbl is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Grbl is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include "serial.h" + +#ifndef DECIMAL_PLACES +#define DECIMAL_PLACES 3 +#define DECIMAL_MULTIPLIER 1000 +#endif + +void printString(const char *s) { + while (*s) + serial_write(*s++); +} + +// Print a string stored in PGM-memory + +void printPgmString(const char *s) { + char c; + while ((c = pgm_read_byte_near(s++))) + serial_write(c); +} + +void printIntegerInBase(unsigned long n, unsigned long base) { + // Assumes 8-bit chars. + unsigned char buf[8 * sizeof (long)]; + unsigned long i = 0; + if (n == 0) { + serial_write('0'); + return; + } + while (n > 0) { + buf[i++] = n % base; + n /= base; + } + for (; i > 0; i--) + serial_write(buf[i - 1] < 10 ? + '0' + buf[i - 1] : + 'A' + buf[i - 1] - 10); +} + +void printInteger(long n) { + if (n < 0) { + serial_write('-'); + n = -n; + } + printIntegerInBase(n, 10); +} + +// A very simple + +void printFloat(double n) { + if (n < 0) { + serial_write('-'); + n = -n; + } + //Add rounding factor + n += 0.5 / DECIMAL_MULTIPLIER; + + long integer_part; + integer_part = (int) n; + printIntegerInBase(integer_part, 10); + + serial_write('.'); + + n -= integer_part; + int decimals = DECIMAL_PLACES; + uint8_t decimal_part; + while (decimals-- > 0) { + n *= 10; + decimal_part = (int) n; + serial_write('0' + decimal_part); + n -= decimal_part; + } +} diff --git a/trunk/Arduino/GRBL_Adafruit_motor_driverV2/g_print.h b/trunk/Arduino/GRBL_Adafruit_motor_driverV2/g_print.h new file mode 100644 index 00000000..40ec7258 --- /dev/null +++ b/trunk/Arduino/GRBL_Adafruit_motor_driverV2/g_print.h @@ -0,0 +1,35 @@ +/* + print.h - Functions for formatting output strings +*/ +/** + * Part of Grbl interpreter modified to work with Adafruit Motor Driver V2 + * File modified by Catalin Vasiliu + * email + * + * + * + * Original license:*********************************************************** + * Copyright (c) 2009-2011 Simen Svale Skogsrud + * Copyright (c) 2011 Sungeun K. Jeon + * + * Grbl is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Grbl is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef g_print_h +#define g_print_h + +void printString(const char *s); +void printPgmString(const char *s); +void printInteger(long n); +void printIntegerInBase(unsigned long n, unsigned long base); +void printFloat(double n); + +#endif diff --git a/trunk/Arduino/GRBL_Adafruit_motor_driverV2/gcode.cpp b/trunk/Arduino/GRBL_Adafruit_motor_driverV2/gcode.cpp new file mode 100644 index 00000000..7e2bae9e --- /dev/null +++ b/trunk/Arduino/GRBL_Adafruit_motor_driverV2/gcode.cpp @@ -0,0 +1,390 @@ +/** + * gcode.cpp - rs274/ngc parser. + * This code is inspired by the Arduino GCode Interpreter by Mike Ellery and the NIST RS274/NGC Interpreter + * by Kramer, Proctor and Messina. + */ + +/** + * Part of Grbl interpreter modified to work with Adafruit Motor Driver V2 + * File created by Catalin Vasiliu + * email + */ + + +#include "gcode.h" +#include +#include "nuts_bolts.h" +#include +#include "settings.h" +#include "stepper_control.h" +#include "errno.h" +#include "protocol.h" +#include + +#define MM_PER_INCH (25.4) + +#define NEXT_ACTION_DEFAULT 0 +#define NEXT_ACTION_DWELL 1 +#define NEXT_ACTION_GO_HOME 2 +#define NEXT_ACTION_SET_COORDINATE_OFFSET 3 +#define NEXT_ACTION_MACHINE_ZERO 4 +#define NEXT_ACTION_MACHINE_ZERO_EXCEPT_Z 5 +#define NEXT_ACTION_MACHINE_PARK 6 + +#define MOTION_MODE_SEEK 0 // G0 +#define MOTION_MODE_LINEAR 1 // G1 +#define MOTION_MODE_CW_ARC 2 // G2 +#define MOTION_MODE_CCW_ARC 3 // G3 +#define MOTION_MODE_CANCEL 4 // G80 + +#define PROGRAM_FLOW_RUNNING 0 +#define PROGRAM_FLOW_PAUSED 1 +#define PROGRAM_FLOW_COMPLETED 2 + +#define SPINDLE_DIRECTION_CW 0 +#define SPINDLE_DIRECTION_CCW 1 + +typedef struct { + uint8_t status_code; + uint8_t motion_mode; /* {G0, G1, G2, G3, G80} */ + uint8_t inverse_feed_rate_mode; /* G93, G94 */ + uint8_t inches_mode; /* 0 = millimeter mode, 1 = inches mode {G20, G21} */ + uint8_t absolute_mode; /* 0 = relative motion, 1 = absolute motion {G90, G91} */ + uint8_t program_flow; + double feed_rate, seek_rate; /* Millimeters/second */ + double position[3]; /* Where the interpreter considers the tool to be at this point in the code */ + uint8_t tool; + int16_t spindle_speed; /* RPM/100 */ + int8_t spindle_direction; + uint8_t plane_axis_0, + plane_axis_1, + plane_axis_2; // The axes of the selected plane +} parser_state_t; + +static parser_state_t gc; + +#define FAIL(status) gc.status_code = status; + +static int next_statement(char *letter, double *double_ptr, char *line, uint8_t *char_counter); + +static void select_plane(uint8_t axis_0, uint8_t axis_1, uint8_t axis_2) { + gc.plane_axis_0 = axis_0; + gc.plane_axis_1 = axis_1; + gc.plane_axis_2 = axis_2; +} + +/** + * + */ +void gc_init() { + memset(&gc, 0, sizeof (gc)); + gc.feed_rate = settings.default_feed_rate; + gc.seek_rate = settings.default_seek_rate; + select_plane(X_AXIS, Y_AXIS, Z_AXIS); + gc.absolute_mode = true; + gc.spindle_speed = settings.default_spindle_speed; +} + +/** + * Convert value from mm to inch if gc.inches_mode is active + * + * @param double value + * @return float converted value + */ +static float to_millimeters(double value) { + return (gc.inches_mode ? (value * MM_PER_INCH) : value); +} + +/** + * Executes one line of 0-terminated G-Code. The line is assumed to contain only uppercase + * characters and signed floating point values (no whitespace). Comments and block delete + * + * @param char array + * @return uint8_t status code + */ +uint8_t gc_execute_line(char *line) { + uint8_t char_counter = 0; + char letter; + double value; + + double unit_converted_value; + // negative inverse_feed_rate means no inverse_feed_rate specified + double inverse_feed_rate = -1; + + uint8_t radius_mode = false; + /* 1 = absolute motion for this block only {G53} */ + uint8_t absolute_override = false; + /* The action that will be taken by the parsed line */ + uint8_t next_action = NEXT_ACTION_DEFAULT; + + double target[3], offset[3]; + + double p = 0, r = 0; + int int_value; + + gc.status_code = STATUS_OK; + + //Commands + while (next_statement(&letter, &value, line, &char_counter)) { + int_value = trunc(value); + switch (letter) { + case 'G': + switch (int_value) { + case 0: gc.motion_mode = MOTION_MODE_SEEK; + break; + case 1: gc.motion_mode = MOTION_MODE_LINEAR; + break; + case 2: gc.motion_mode = MOTION_MODE_CW_ARC; + break; + case 3: gc.motion_mode = MOTION_MODE_CCW_ARC; + break; + case 4: next_action = NEXT_ACTION_DWELL; + break; + case 17: select_plane(X_AXIS, Y_AXIS, Z_AXIS); + break; + case 18: select_plane(X_AXIS, Z_AXIS, Y_AXIS); + break; + case 19: select_plane(Y_AXIS, Z_AXIS, X_AXIS); + break; + case 20: gc.inches_mode = true; + break; + case 21: gc.inches_mode = false; + break; + case 28: case 30: next_action = NEXT_ACTION_GO_HOME; + break; + case 53: absolute_override = true; + break; + case 80: gc.motion_mode = MOTION_MODE_CANCEL; + break; + case 90: gc.absolute_mode = true; + break; + case 91: gc.absolute_mode = false; + break; + case 92: next_action = NEXT_ACTION_SET_COORDINATE_OFFSET; + break; + case 93: gc.inverse_feed_rate_mode = true; + break; + case 94: gc.inverse_feed_rate_mode = false; + break; + default: FAIL(STATUS_UNSUPPORTED_STATEMENT); + } + break; + + case 'M': + switch (int_value) { + case 0: case 1: gc.program_flow = PROGRAM_FLOW_PAUSED; + break; + case 2: case 30: case 60: gc.program_flow = PROGRAM_FLOW_COMPLETED; + break; + case 3: gc.spindle_direction = 1; + break; + case 4: gc.spindle_direction = -1; + break; + case 5: gc.spindle_direction = 0; + break; + //non standard commands implemented to ease the manual controll + //available only with limit switch + case 100: next_action = NEXT_ACTION_MACHINE_ZERO; + break; + //available only with limit switch + case 101: next_action = NEXT_ACTION_MACHINE_ZERO_EXCEPT_Z; + break; + case 102: next_action = NEXT_ACTION_MACHINE_PARK; + break; + default: FAIL(STATUS_UNSUPPORTED_STATEMENT); + } + break; + + case 'T': gc.tool = trunc(value); + break; + } + if (gc.status_code) { + break; + } + } + + // If there were any errors parsing this line, return the bad news + if (gc.status_code) { + return (gc.status_code); + } + + char_counter = 0; + clear_vector_double(target); + clear_vector_double(offset); + + //i.e. target = gc.position + memcpy(target, gc.position, sizeof (target)); + + //Parameters + while (next_statement(&letter, &value, line, &char_counter)) { + int_value = trunc(value); + unit_converted_value = to_millimeters(value); + switch (letter) { + case 'F': + // Must be greater than zero + if (unit_converted_value <= 0) { + FAIL(STATUS_BAD_NUMBER_FORMAT); + } + if (gc.inverse_feed_rate_mode) { + // seconds per motion for this motion only + inverse_feed_rate = unit_converted_value; + } else { + if (gc.motion_mode == MOTION_MODE_SEEK) { + // millimeters or inch per minute + gc.seek_rate = unit_converted_value; + } else { + gc.feed_rate = unit_converted_value; + } + } + break; + case 'I': case 'J': case 'K': offset[letter - 'I'] = unit_converted_value; + break; + case 'P': p = value; + break; + case 'R': r = unit_converted_value; + radius_mode = true; + break; + case 'S': gc.spindle_speed = value; + break; + case 'X': case 'Y': case 'Z': + if (gc.absolute_mode || absolute_override) { + target[letter - 'X'] = unit_converted_value; + } else { + target[letter - 'X'] += unit_converted_value; + } + break; + } + } + + // If there were any errors parsing this line, return the bad news + if (gc.status_code) { + return (gc.status_code); + } + + // Update spindle state + spindle_run(gc.spindle_direction, gc.spindle_speed); + + // Perform any physical actions + switch (next_action) { + case NEXT_ACTION_GO_HOME: + st_go_home(gc.position); +// clear_vector_double(target); + break; + case NEXT_ACTION_DWELL: + st_dwell(p); + break; + case NEXT_ACTION_SET_COORDINATE_OFFSET: + gc.position[X_AXIS] = target[X_AXIS]; + gc.position[Y_AXIS] = target[Y_AXIS]; + gc.position[Z_AXIS] = target[Z_AXIS]; + clear_vector_double(target); + break; + case NEXT_ACTION_MACHINE_ZERO: + st_go_to_zero(true); + gc.position[X_AXIS] = 0; + gc.position[Y_AXIS] = 0; + gc.position[Z_AXIS] = 0; + break; + case NEXT_ACTION_MACHINE_ZERO_EXCEPT_Z: + st_go_to_zero(false); + gc.position[X_AXIS] = 0; + gc.position[Y_AXIS] = 0; +// gc.position[Z_AXIS] = 0; + break; + case NEXT_ACTION_MACHINE_PARK : + st_machine_park(); + break; + case NEXT_ACTION_DEFAULT: + switch (gc.motion_mode) { + case MOTION_MODE_CANCEL: break; + case MOTION_MODE_SEEK: + gc.status_code = st_line(gc.position, target[X_AXIS], + target[Y_AXIS], target[Z_AXIS], gc.seek_rate, false); + break; + case MOTION_MODE_LINEAR: + gc.status_code = st_line(gc.position, target[X_AXIS], target[Y_AXIS], target[Z_AXIS], + (gc.inverse_feed_rate_mode) ? inverse_feed_rate : gc.feed_rate, gc.inverse_feed_rate_mode); + break; + case MOTION_MODE_CW_ARC: case MOTION_MODE_CCW_ARC: + if (radius_mode) { + // Calculate the change in position along each selected axis + double x = target[gc.plane_axis_0] - gc.position[gc.plane_axis_0]; + double y = target[gc.plane_axis_1] - gc.position[gc.plane_axis_1]; + + clear_vector(offset); + double h_x2_div_d = -sqrt(4 * r * r - x * x - y * y) / hypot(x, y); // == -(h * 2 / d) + // If r is smaller than d, the arc is now traversing the complex plane beyond the reach of any + // real CNC, and thus - for practical reasons - we will terminate promptly: + if (isnan(h_x2_div_d)) { + FAIL(STATUS_FLOATING_POINT_ERROR); + return (gc.status_code); + } + // Invert the sign of h_x2_div_d if the circle is counter clockwise (see sketch below) + if (gc.motion_mode == MOTION_MODE_CCW_ARC) { + h_x2_div_d = -h_x2_div_d; + } + if (r < 0) { + h_x2_div_d = -h_x2_div_d; + r = -r; // Finished with r. Set to positive for mc_arc + } + // Complete the operation by calculating the actual center of the arc + offset[gc.plane_axis_0] = 0.5 * (x - (y * h_x2_div_d)); + offset[gc.plane_axis_1] = 0.5 * (y + (x * h_x2_div_d)); + + } else { + // Offset mode specific computations + // Compute arc radius for mc_arc + r = hypot(offset[gc.plane_axis_0], offset[gc.plane_axis_1]); + } + + // Set clockwise/counter-clockwise sign for st_arc computations + uint8_t isclockwise = false; + if (gc.motion_mode == MOTION_MODE_CW_ARC) { + isclockwise = true; + } + + // Trace the arc + gc.status_code = st_arc(gc.position, target, offset, gc.plane_axis_0, gc.plane_axis_1, gc.plane_axis_2, + (gc.inverse_feed_rate_mode) ? inverse_feed_rate : gc.feed_rate, gc.inverse_feed_rate_mode, + r, isclockwise); + + break; + } + } + //gc.position[] = target[]; + memcpy(gc.position, target, sizeof (double)*3); + clear_vector_double(target); + clear_vector_double(offset); + + return (gc.status_code); +} + +/** + * Parses the next statement and leaves the counter on the first character following + * the statement. Returns 1 if there was a statements, 0 if end of string was reached + * or there was an error (check state.status_code). + * + * @param char letter + * @param double double_ptr + * @param char array line + * @param uint8_t char_counter + * @return int + */ +static int next_statement(char *letter, double *double_ptr, char *line, uint8_t *char_counter) { + if (line[*char_counter] == 0) { + return (0); // No more statements + } + + *letter = line[*char_counter]; + if ((*letter < 'A') || (*letter > 'Z')) { + FAIL(STATUS_EXPECTED_COMMAND_LETTER); + return (0); + } + (*char_counter)++; + if (!read_double(line, char_counter, double_ptr)) { + FAIL(STATUS_BAD_NUMBER_FORMAT); + return (0); + }; + return (1); +} + diff --git a/trunk/Arduino/GRBL_Adafruit_motor_driverV2/gcode.h b/trunk/Arduino/GRBL_Adafruit_motor_driverV2/gcode.h new file mode 100644 index 00000000..dc35c1e0 --- /dev/null +++ b/trunk/Arduino/GRBL_Adafruit_motor_driverV2/gcode.h @@ -0,0 +1,22 @@ +/** + * gcode.cpp - rs274/ngc parser. + * This code is inspired by the Arduino GCode Interpreter by Mike Ellery and the NIST RS274/NGC Interpreter + * by Kramer, Proctor and Messina. +*/ +/** + * Part of Grbl interpreter modified to work with Adafruit Motor Driver V2 + * File created by Catalin Vasiliu + * email + */ + +#ifndef gcode_h +#define gcode_h +#include + +// Initialize the parser +void gc_init(); + +// Execute one block of rs275/ngc/g-code +uint8_t gc_execute_line(char *line); + +#endif diff --git a/trunk/Arduino/GRBL_Adafruit_motor_driverV2/limit_switch.h b/trunk/Arduino/GRBL_Adafruit_motor_driverV2/limit_switch.h new file mode 100644 index 00000000..5e9463ea --- /dev/null +++ b/trunk/Arduino/GRBL_Adafruit_motor_driverV2/limit_switch.h @@ -0,0 +1,45 @@ +/* + * File: limit_switch.h + */ +/** + * Part of Grbl interpreter modified to work with Adafruit Motor Driver V2 + * File modified by Catalin Vasiliu + * email + * + * + * + * Original license:*********************************************************** + * Copyright (c) 2009-2011 Simen Svale Skogsrud + * Copyright (c) 2011 Sungeun K. Jeon + * + * Grbl is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Grbl is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef LIMIT_SWITCH_H +#define LIMIT_SWITCH_H + +#define X_LIMIT_END_ENABLE 21 +#define X_LIMIT_START_ENABLE 31 +#define Y_LIMIT_END_ENABLE 41 +#define Y_LIMIT_START_ENABLE 51 +#define Z_LIMIT_END_ENABLE 61 +#define Z_LIMIT_START_ENABLE 71 +#define NO_SWTCH_ENABLE 0 + +#define X_motor 0 +#define Y_motor 1 +#define Z_motor 2 + +//check for enabled limit swith +int ls_check(int motor, int dir); + +#endif /* LIMIT_SWITCH_H */ + diff --git a/trunk/Arduino/GRBL_Adafruit_motor_driverV2/limit_swtch.cpp b/trunk/Arduino/GRBL_Adafruit_motor_driverV2/limit_swtch.cpp new file mode 100644 index 00000000..6a8bfe93 --- /dev/null +++ b/trunk/Arduino/GRBL_Adafruit_motor_driverV2/limit_swtch.cpp @@ -0,0 +1,60 @@ +/** + * Part of Grbl interpreter modified to work with Adafruit Motor Driver V2 + * File modified by Catalin Vasiliu + * email + * + * + * + * Original license:*********************************************************** + * Copyright (c) 2009-2011 Simen Svale Skogsrud + * Copyright (c) 2011 Sungeun K. Jeon + * + * Grbl is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Grbl is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "config.h" +#include +#include "limit_switch.h" + +/** + * Check the limit switch according to axis and direction + * + * @param int motor -- axis + * @param int direction + * @return int status + */ +int ls_check(int motor, int direction) { + if (motor == X_motor) { + if (digitalRead(X_LIMIT_END_PIN) && direction > 0) { + return X_LIMIT_END_ENABLE; + } + if (digitalRead(X_LIMIT_START_PIN) && direction < 0) { + return X_LIMIT_START_ENABLE; + } + } + if (motor == Y_motor) { + if (digitalRead(Y_LIMIT_END_PIN) && direction > 0) { + return Y_LIMIT_END_ENABLE; + } + if (digitalRead(Y_LIMIT_START_PIN) && direction < 0) { + return Y_LIMIT_START_ENABLE; + } + } + if (motor == Z_motor) { + if (digitalRead(Z_LIMIT_END_PIN) && direction > 0) { + return Z_LIMIT_END_ENABLE; + } + if (digitalRead(Z_LIMIT_START_PIN) && direction < 0) { + return Z_LIMIT_START_ENABLE; + } + } + return NO_SWTCH_ENABLE; +} diff --git a/trunk/Arduino/GRBL_Adafruit_motor_driverV2/makefile b/trunk/Arduino/GRBL_Adafruit_motor_driverV2/makefile new file mode 100644 index 00000000..d0170a5a --- /dev/null +++ b/trunk/Arduino/GRBL_Adafruit_motor_driverV2/makefile @@ -0,0 +1,130 @@ +# Arduino Make file. Refer to https://github.com/sudar/Arduino-Makefile +# + +BOARD_TAG = uno +include ../paths.mk +include ../Arduino.mk + +# --- leonardo (or pro micro w/leo bootloader) +#BOARD_TAG = leonardo +#MONITOR_PORT = /dev/ttyACM0 +#include /usr/share/arduino/Arduino.mk + +# --- mega2560 ide 1.0 +#BOARD_TAG = mega2560 +#ARDUINO_PORT = /dev/ttyACM0 +#include /usr/share/arduino/Arduino.mk + +# --- mega2560 ide 1.6 +#BOARD_TAG = mega +#BOARD_SUB = atmega2560 +#MONITOR_PORT = /dev/ttyACM0 +#ARDUINO_DIR = /where/you/installed/arduino-1.6.5 +#include /usr/share/arduino/Arduino.mk + +# --- nano ide 1.0 +#BOARD_TAG = nano328 +#MONITOR_PORT = /dev/ttyUSB0 +#include /usr/share/arduino/Arduino.mk + +# --- nano ide 1.6 +#BOARD_TAG = nano +#BOARD_SUB = atmega328 +#ARDUINO_DIR = /where/you/installed/arduino-1.6.5 +#include /usr/share/arduino/Arduino.mk + +# --- pro mini +#BOARD_TAG = pro5v328 +#MONITOR_PORT = /dev/ttyUSB0 +#include /usr/share/arduino/Arduino.mk + +# --- sparkfun pro micro +#BOARD_TAG = promicro16 +#ALTERNATE_CORE = promicro +#BOARDS_TXT = $(HOME)/arduino/hardware/promicro/boards.txt +#BOOTLOADER_PARENT = $(HOME)/arduino/hardware/promicro/bootloaders +#BOOTLOADER_PATH = caterina +#BOOTLOADER_FILE = Caterina-promicro16.hex +#ISP_PROG = usbasp +#AVRDUDE_OPTS = -v +#include /usr/share/arduino/Arduino.mk + +# --- chipkit +#BOARD_TAG = mega_pic32 +#MPIDE_DIR = /where/you/installed/mpide-0023-linux64-20130817-test +#include /usr/share/arduino/chipKIT.mk + +# --- pinoccio +#BOARD_TAG = pinoccio256 +#ALTERNATE_CORE = pinoccio +#BOOTLOADER_PARENT = $(HOME)/arduino/hardware/pinoccio/bootloaders +#BOOTLOADER_PATH = STK500RFR2/release_0.51 +#BOOTLOADER_FILE = boot_pinoccio.hex +#CFLAGS_STD = -std=gnu99 +#CXXFLAGS_STD = -std=gnu++11 +#include /usr/share/arduino/Arduino.mk + +# --- fio +#BOARD_TAG = fio +#include /usr/share/arduino/Arduino.mk + +# --- atmega-ng ide 1.6 +#BOARD_TAG = atmegang +#BOARD_SUB = atmega168 +#MONITOR_PORT = /dev/ttyACM0 +#ARDUINO_DIR = /where/you/installed/arduino-1.6.5 +#include /usr/share/arduino/Arduino.mk + +# --- arduino-tiny ide 1.0 +#ISP_PROG = usbasp +#BOARD_TAG = attiny85at8 +#ALTERNATE_CORE = tiny +#ARDUINO_VAR_PATH = $(HOME)/arduino/hardware/tiny/cores/tiny +#ARDUINO_CORE_PATH = $(HOME)/arduino/hardware/tiny/cores/tiny +#AVRDUDE_OPTS = -v +#include /usr/share/arduino/Arduino.mk + +# --- arduino-tiny ide 1.6 +#ISP_PROG = usbasp +#BOARD_TAG = attiny85at8 +#ALTERNATE_CORE = tiny +#ARDUINO_DIR = /where/you/installed/arduino-1.6.5 +#include /usr/share/arduino/Arduino.mk + +# --- damellis attiny ide 1.0 +#ISP_PROG = usbasp +#BOARD_TAG = attiny85 +#ALTERNATE_CORE = attiny-master +#AVRDUDE_OPTS = -v +#include /usr/share/arduino/Arduino.mk + +# --- damellis attiny ide 1.6 +#ISP_PROG = usbasp +#BOARD_TAG = attiny +#BOARD_SUB = attiny85 +#ALTERNATE_CORE = attiny +#F_CPU = 16000000L +#ARDUINO_DIR = /where/you/installed/arduino-1.6.5 +#include /usr/share/arduino/Arduino.mk + +# --- teensy3 +#BOARD_TAG = teensy31 +#ARDUINO_DIR = /where/you/installed/the/patched/teensy/arduino-1.0.6 +#include /usr/share/arduino/Teensy.mk + +# --- mighty 1284p +#BOARD_TAG = mighty_opt +#BOARDS_TXT = $(HOME)/arduino/hardware/mighty-1284p/boards.txt +#BOOTLOADER_PARENT = $(HOME)/arduino/hardware/mighty-1284p/bootloaders +#BOOTLOADER_PATH = optiboot +#BOOTLOADER_FILE = optiboot_atmega1284p.hex +#ISP_PROG = usbasp +#AVRDUDE_OPTS = -v +#include /usr/share/arduino/Arduino.mk + +# --- atmega328p on breadboard +#BOARD_TAG = atmega328bb +#ISP_PROG = usbasp +#AVRDUDE_OPTS = -v +#BOARDS_TXT = $(HOME)/arduino/hardware/breadboard/boards.txt +#include /usr/share/arduino/Arduino.mk diff --git a/trunk/Arduino/GRBL_Adafruit_motor_driverV2/nuts_bolts.cpp b/trunk/Arduino/GRBL_Adafruit_motor_driverV2/nuts_bolts.cpp new file mode 100644 index 00000000..427479d1 --- /dev/null +++ b/trunk/Arduino/GRBL_Adafruit_motor_driverV2/nuts_bolts.cpp @@ -0,0 +1,70 @@ +/* + nuts_bolts.c - Shared functions +*/ +/** + * Part of Grbl interpreter modified to work with Adafruit Motor Driver V2 + * File modified by Catalin Vasiliu + * email + * + * + * + * Original license:*********************************************************** + * Copyright (c) 2009-2011 Simen Svale Skogsrud + * Copyright (c) 2011 Sungeun K. Jeon + * + * Grbl is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Grbl is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "nuts_bolts.h" +#include +#include +#include + +/** + * Read a floating point value from a string. Line points to the input buffer, char_counter + * is the indexer pointing to the current character of the line, while double_ptr is + * a pointer to the result variable. Returns true when it succeeds + * + */ +int read_double(char *line, uint8_t *char_counter, double *double_ptr) +{ + char *start = line + *char_counter; + char *end; + + *double_ptr = strtod(start, &end); + if(end == start) { + return(false); + }; + + *char_counter = end - line; + return(true); +} + +/** + * Delays variable defined milliseconds. Compiler compatibility fix for _delay_ms(), + * which only accepts constants in future compiler releases. + * + * @param us + */ +void delay_ms(uint16_t ms) +{ + while ( ms-- ) { _delay_ms(1); } +} + +/** + * Delays variable defined microseconds. Compiler compatibility fix for _delay_us(), + * which only accepts constants in future compiler releases. + * + */ +void delay_us(uint16_t us) +{ + while ( us-- ) { _delay_us(1); } +} diff --git a/trunk/Arduino/GRBL_Adafruit_motor_driverV2/nuts_bolts.h b/trunk/Arduino/GRBL_Adafruit_motor_driverV2/nuts_bolts.h new file mode 100644 index 00000000..e8a3d1f8 --- /dev/null +++ b/trunk/Arduino/GRBL_Adafruit_motor_driverV2/nuts_bolts.h @@ -0,0 +1,53 @@ +/* + nuts_bolts.h - Header file for shared definitions, variables, and functions +*/ +/** + * Part of Grbl interpreter modified to work with Adafruit Motor Driver V2 + * File modified by Catalin Vasiliu + * email + * + * + * + * Original license:*********************************************************** + * Copyright (c) 2009-2011 Simen Svale Skogsrud + * Copyright (c) 2011 Sungeun K. Jeon + * + * Grbl is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Grbl is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef nuts_bolts_h +#define nuts_bolts_h +#include +#include +#include + +#define false 0 +#define true 1 + +#define X_AXIS 0 +#define Y_AXIS 1 +#define Z_AXIS 2 + +#define clear_vector(a) memset(a, 0, sizeof(a)) +#define clear_vector_double(a) memset(a, 0.0, sizeof(a)) + +// Read a floating point value from a string. Line points to the input buffer, char_counter +// is the indexer pointing to the current character of the line, while double_ptr is +// a pointer to the result variable. Returns true when it succeeds +int read_double(char *line, uint8_t *char_counter, double *double_ptr); + +// Delays variable-defined milliseconds. Compiler compatibility fix for _delay_ms(). +void delay_ms(uint16_t ms); + +// Delays variable-defined microseconds. Compiler compatibility fix for _delay_us(). +void delay_us(uint16_t us); + +#endif diff --git a/trunk/Arduino/GRBL_Adafruit_motor_driverV2/protocol.cpp b/trunk/Arduino/GRBL_Adafruit_motor_driverV2/protocol.cpp new file mode 100644 index 00000000..25e36e7a --- /dev/null +++ b/trunk/Arduino/GRBL_Adafruit_motor_driverV2/protocol.cpp @@ -0,0 +1,180 @@ +/* + protocol.c - the serial protocol master control unit + */ +/** + * Part of Grbl interpreter modified to work with Adafruit Motor Driver V2 + * File modified by Catalin Vasiliu + * email + * + * + * + * Original license:*********************************************************** + * Copyright (c) 2009-2011 Simen Svale Skogsrud + * Copyright (c) 2011 Sungeun K. Jeon + * + * Grbl is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Grbl is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include "protocol.h" +#include "gcode.h" +#include "serial.h" +#include "print.h" +#include "settings.h" +#include "config.h" +#include +#include "nuts_bolts.h" +#include +#include "limit_switch.h" +#include "g_print.h" + + +#define LINE_BUFFER_SIZE 50 + +// Line to be executed. Zero-terminated. +static char line[LINE_BUFFER_SIZE]; +// Last character counter in line variable. +static uint8_t char_counter; +// Comment/block delete flag for processor to ignore comment characters. +static uint8_t iscomment; + +/** + * Process status_code and print to serial bus the error or ok + * + * @param int status_code + */ +static void status_message(int status_code) { + if (status_code == STATUS_OK) { + printPgmString(PSTR(" ")); + printPgmString(PSTR("ok\r\n")); + } else { + printPgmString(PSTR("error: ")); + switch (status_code) { + case STATUS_BAD_NUMBER_FORMAT: + printPgmString(PSTR("Bad number format\r\n")); + break; + case STATUS_EXPECTED_COMMAND_LETTER: + printPgmString(PSTR("Expected command letter\r\n")); + break; + case STATUS_UNSUPPORTED_STATEMENT: + printPgmString(PSTR("Unsupported statement\r\n")); + break; + case STATUS_FLOATING_POINT_ERROR: + printPgmString(PSTR("Floating point error\r\n")); + break; + //limit swtch error + case X_LIMIT_END_ENABLE: + printPgmString(PSTR("End limit switch on X axis enabled\r\n")); + break; + case X_LIMIT_START_ENABLE: + printPgmString(PSTR("Start limit switch on X axis enabled\r\n")); + break; + case Y_LIMIT_END_ENABLE: + printPgmString(PSTR("End limit switch on Y axis enabled\r\n")); + break; + case Y_LIMIT_START_ENABLE: + printPgmString(PSTR("Start limit switch on Y axis enabled\r\n")); + break; + case Z_LIMIT_END_ENABLE: + printPgmString(PSTR("End limit switch on Z axis enabled\r\n")); + break; + case Z_LIMIT_START_ENABLE: + printPgmString(PSTR("Start limit switch on Z axis enabled\r\n")); + break; + default: + printPgmString(PSTR("Unknown error ")); + printInteger(status_code); + printPgmString(PSTR("\r\n")); + } + } +} + +/** + * Initiate the protocol and send version number to gcode sender + */ +void protocol_init() { + // Reset line input + char_counter = 0; + iscomment = false; + printPgmString(PSTR("\r\nGrbl " GRBL_VERSION)); + printPgmString(PSTR("\r\n")); + +} + + +/** + * Executes one line of input according to protocol + * + * @param char array line + * @return int status message + */ +uint8_t protocol_execute_line(char *line) { + if (line[0] == '$') { + //Delegate lines starting with '$' to the settings module + return (settings_execute_line(line)); + } else { + //Everything else is gcode + return (gc_execute_line(line)); + } +} + +/** + * Process one line of incoming serial data. Remove unneeded characters and capitalize. + */ +void protocol_process() { + char c; + while ((c = serial_read()) != SERIAL_NO_DATA) { + //End of line reached + if ((c == '\n') || (c == '\r')) { + //Line is complete. Then execute! + if (char_counter > 0) { + //Terminate string + line[char_counter] = 0; + status_message(protocol_execute_line(line)); + } else { + //Empty or comment line. Skip block. + //Send status message for syncing purposes. + status_message(STATUS_OK); + } + //Reset line buffer index + char_counter = 0; + //Reset comment flag + iscomment = false; + } else { + if (iscomment) { + //Throw away all comment characters + if (c == ')') { + //End of comment. Resume line. + iscomment = false; + } + + } else { + if (c <= ' ') { + //Throw away whitepace and control characters + } else if (c == '/') { + //Disable block delete and throw away character + //To enable block delete, uncomment following line. Will ignore until EOL. + //iscomment = true; + } else if (c == '(') { + //Enable comments flag and ignore all characters until ')' or EOL. + iscomment = true; + } else if (char_counter >= LINE_BUFFER_SIZE - 1) { + //Throw away any characters beyond the end of the line buffer + } else if (c >= 'a' && c <= 'z') { + //Upcase lowercase + line[char_counter++] = c - 'a' + 'A'; + } else { + line[char_counter++] = c; + } + } + } + } +} diff --git a/trunk/Arduino/GRBL_Adafruit_motor_driverV2/protocol.h b/trunk/Arduino/GRBL_Adafruit_motor_driverV2/protocol.h new file mode 100644 index 00000000..5775b4ad --- /dev/null +++ b/trunk/Arduino/GRBL_Adafruit_motor_driverV2/protocol.h @@ -0,0 +1,43 @@ +/** + * Part of Grbl interpreter modified to work with Adafruit Motor Driver V2 + * File modified by Catalin Vasiliu + * email + * + * + * + * Original license:*********************************************************** + * Copyright (c) 2009-2011 Simen Svale Skogsrud + * Copyright (c) 2011 Sungeun K. Jeon + * + * Grbl is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Grbl is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef protocol_h +#define protocol_h + +#define STATUS_OK 0 +#define STATUS_BAD_NUMBER_FORMAT 1 +#define STATUS_EXPECTED_COMMAND_LETTER 2 +#define STATUS_UNSUPPORTED_STATEMENT 3 +#define STATUS_FLOATING_POINT_ERROR 4 +#define STATUS_SETINGS_RESETED 5 + +//Initialize the serial protocol +void protocol_init(); + +//Read command lines from the serial port and execute them as they come in. +//Blocks until the serial buffer is emptied. +void protocol_process(); + +//Executes one line of input according to protocol +uint8_t protocol_execute_line(char *line); + +#endif diff --git a/trunk/Arduino/GRBL_Adafruit_motor_driverV2/serial.cpp b/trunk/Arduino/GRBL_Adafruit_motor_driverV2/serial.cpp new file mode 100644 index 00000000..30a86692 --- /dev/null +++ b/trunk/Arduino/GRBL_Adafruit_motor_driverV2/serial.cpp @@ -0,0 +1,43 @@ +/** + * Part of Grbl interpreter modified to work with Adafruit Motor Driver V2 + * File modified by Catalin Vasiliu + * email + * + * + * + * Original license:*********************************************************** + * Copyright (c) 2009-2011 Simen Svale Skogsrud + * Copyright (c) 2011 Sungeun K. Jeon + * + * Grbl is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Grbl is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include "serial.h" + +/** + * Initiate the serial bus with the specified boundrate + * + * @param long baudrate + */ +void serial_init(long baudrate) { + Serial.begin(baudrate); +} + +void serial_write(unsigned char data) { + Serial.write(data); +} + +unsigned char serial_read() { + int result = Serial.read(); + return (result == -1)?SERIAL_NO_DATA : result; +} + diff --git a/trunk/Arduino/GRBL_Adafruit_motor_driverV2/serial.h b/trunk/Arduino/GRBL_Adafruit_motor_driverV2/serial.h new file mode 100644 index 00000000..f232f67b --- /dev/null +++ b/trunk/Arduino/GRBL_Adafruit_motor_driverV2/serial.h @@ -0,0 +1,34 @@ +/** + * Part of Grbl interpreter modified to work with Adafruit Motor Driver V2 + * File modified by Catalin Vasiliu + * email + * + * + * + * Original license:*********************************************************** + * Copyright (c) 2009-2011 Simen Svale Skogsrud + * Copyright (c) 2011 Sungeun K. Jeon + * + * Grbl is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Grbl is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef serial_h +#define serial_h + +#define SERIAL_NO_DATA 0xff + +void serial_init(long baud); + +void serial_write(unsigned char data); + +unsigned char serial_read(); + +#endif diff --git a/trunk/Arduino/GRBL_Adafruit_motor_driverV2/settings.cpp b/trunk/Arduino/GRBL_Adafruit_motor_driverV2/settings.cpp new file mode 100644 index 00000000..7326b08b --- /dev/null +++ b/trunk/Arduino/GRBL_Adafruit_motor_driverV2/settings.cpp @@ -0,0 +1,358 @@ +/** + * settings.c - eeprom configuration handling + * migration from older version of setting not supported because this grbl interpreter + * have different settings and functionality + */ +/** + * Part of Grbl interpreter modified to work with Adafruit Motor Driver V2 + * File modified by Catalin Vasiliu + * email + * + * + * + * Original license:*********************************************************** + * Copyright (c) 2009-2011 Simen Svale Skogsrud + * Copyright (c) 2011 Sungeun K. Jeon + * + * Grbl is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Grbl is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include "nuts_bolts.h" +#include "settings.h" +#include "eeprom.h" +#include "g_print.h" +#include +#include "protocol.h" +#include "config.h" +#include "stepper_control.h" + + +settings_t settings; + +typedef struct { + double steps_per_mm[3]; + float rod_step; + double default_feed_rate; + double default_seek_rate; + uint8_t invert_mask; + double mm_per_arc_segment; +} settings_v1_t; + + + +/** + * Set settings values to default + */ +void settings_reset() { + settings.rod_step = DEFAULT_ROD_STEP; + settings.steps_per_turn[X_AXIS] = DEFAULT_X_STEPS_PER_TURN; + settings.steps_per_turn[Y_AXIS] = DEFAULT_Y_STEPS_PER_TURN; + settings.steps_per_turn[Z_AXIS] = DEFAULT_Z_STEPS_PER_TURN; + settings.steps_per_mm[X_AXIS] = settings.steps_per_turn[X_AXIS] / settings.rod_step; + settings.steps_per_mm[Y_AXIS] = settings.steps_per_turn[Y_AXIS] / settings.rod_step; + settings.steps_per_mm[Z_AXIS] = settings.steps_per_turn[Z_AXIS] / settings.rod_step; + + settings.default_feed_rate = DEFAULT_FEEDRATE; + settings.default_seek_rate = DEFAULT_RAPID_FEEDRATE; + settings.mm_per_arc_segment = DEFAULT_MM_PER_ARC_SEGMENT; + settings.invert_mask = DEFAULT_STEPPING_INVERT_MASK; + settings.default_spindle_speed = DEFAULT_SPINDLE_SPEED; + + settings.work_area[X_AXIS] = DEFAULT_WORK_AREA_X_AXIS; + settings.work_area[Y_AXIS] = DEFAULT_WORK_AREA_Y_AXIS; + settings.work_area[Z_AXIS] = DEFAULT_WORK_AREA_Z_AXIS; + + settings.limit_switch = DEFAULT_LIMIT_SWITCH; + settings.release_after_move = RELEASE_AFTER_MOVE; +} + +/** + * Print to serial bus settings data and infos + * Modifying the format of these strings may cause the settings window in + * grbl sender to stop working!!! + */ +void settings_dump() { + printPgmString(PSTR("$0 = ")); + printFloat(settings.rod_step); + printPgmString(PSTR(" (mm/turn ...rod step)\r\n")); + + printPgmString(PSTR("\r\n $1 = ")); + printInteger(settings.steps_per_turn[X_AXIS]); + printPgmString(PSTR(" (steps/turn x motor)\r\n")); + + printPgmString(PSTR("\r\n $2 = ")); + printInteger(settings.steps_per_turn[Y_AXIS]); + printPgmString(PSTR(" (steps/turn y motor)\r\n")); + + printPgmString(PSTR("\r\n $3 = ")); + printInteger(settings.steps_per_turn[Z_AXIS]); + printPgmString(PSTR(" (steps/turn z motor)\r\n")); + + printPgmString(PSTR("\r\n $4 = ")); + printFloat(settings.steps_per_mm[X_AXIS]); + printPgmString(PSTR(" (steps/mm x)\r\n")); + + printPgmString(PSTR("\r\n $5 = ")); + printFloat(settings.steps_per_mm[Y_AXIS]); + printPgmString(PSTR(" (steps/mm y)\r\n")); + + printPgmString(PSTR("\r\n $6 = ")); + printFloat(settings.steps_per_mm[Z_AXIS]); + printPgmString(PSTR(" (steps/mm z)\r")); + + printPgmString(PSTR("\n $7 = ")); + printFloat(settings.default_feed_rate); + printPgmString(PSTR(" (mm/min default feed rate)\r\n")); + + printPgmString(PSTR("\r\n $8 = ")); + printFloat(settings.default_seek_rate); + printPgmString(PSTR(" (mm/min default seek rate)\r\n")); + + printPgmString(PSTR("\r\n $9 = ")); + printFloat(settings.mm_per_arc_segment); + printPgmString(PSTR(" (mm/arc segment)\r\n")); + + printPgmString(PSTR("\r\n $10 = ")); + printInteger(settings.invert_mask); + printPgmString(PSTR(" (step port invert mask. binary = ")); + printIntegerInBase(settings.invert_mask, 2); + printPgmString(PSTR(")\r\n")); + + printPgmString(PSTR("\r\n $11 = ")); + printFloat(settings.default_spindle_speed); + printPgmString(PSTR(" (default spindle speed in pwm)\r\n")); + + printPgmString(PSTR("\r\n $12 = ")); + printFloat(settings.limit_switch); + printPgmString(PSTR(" (limit switch enable/disable, 1/0)\r\n")); + + printPgmString(PSTR("\r\n $13 = ")); + printFloat(settings.release_after_move); + printPgmString(PSTR(" (release motors after move enable/disable, 1/0)\r\n")); + + //Work area + printPgmString(PSTR("\r\n $14 = ")); + printFloat(settings.work_area[X_AXIS]); + printPgmString(PSTR(" (mm on X axis workin area)\r\n")); + + printPgmString(PSTR("\r\n $15 = ")); + printFloat(settings.work_area[Y_AXIS]); + printPgmString(PSTR(" (mm on Y axis workin area)\r\n")); + + printPgmString(PSTR("\r\n $16 = ")); + printFloat(settings.work_area[Z_AXIS]); + printPgmString(PSTR(" (mm on Z axis workin area)\r\n")); + + //Recalibrate + if(settings.limit_switch == 1){ + printPgmString(PSTR("\r\n $17 = ")); + printInteger(0); + printPgmString(PSTR(" (recalibrate workin area)\r\n")); + }else{ + printPgmString(PSTR("\r\n $17 = ")); + printInteger(0); + printPgmString(PSTR(" (Recalibrate not available with limit switch disable)\r\n")); + } + + //Reset...manual + printPgmString(PSTR("\r\n $18 = ")); + printInteger(0); + printPgmString(PSTR(" (1 to reset setings)\r\n")); + printPgmString(PSTR("\r\n'$x=value' to set parameter or just '$' to dump current settings\r\n")); +} + +/** + * Process the settings line + * Parameter lines are on the form '$4=374.3' or '$' to dump current settings + * + * @param char array line + * @return int status + */ +uint8_t settings_execute_line(char *line) { + uint8_t char_counter = 1; + double parameter, value; + if(line[0] != '$') { + return(STATUS_UNSUPPORTED_STATEMENT); + } + + if(GRBL_VERSION == "0.7") { + if(line[char_counter] == 0) { + settings_dump(); return(STATUS_OK); + } + } else if (GRBL_VERSION == "0.9") { + if(line[char_counter] == '$') { + settings_dump(); return(STATUS_OK); + } + } + + if(!read_double(line, &char_counter, ¶meter)) { + return(STATUS_BAD_NUMBER_FORMAT); + }; + + if(line[char_counter++] != '=') { + return(STATUS_UNSUPPORTED_STATEMENT); + } + + if(!read_double(line, &char_counter, &value)) { + return(STATUS_BAD_NUMBER_FORMAT); + } + + if(line[char_counter] != 0) { + return(STATUS_UNSUPPORTED_STATEMENT); + } + //Send option and value so save + settings_store_setting(parameter, value); + return(STATUS_OK); +} + +/** + * Write all settings to eprom + */ +void write_settings() { + eeprom_put_char(0, SETTINGS_VERSION); + memcpy_to_eeprom_with_checksum(1, (unsigned char*)&settings, sizeof(settings_t)); +} + +/** + * Read seting from eprom + * Check settings version and try to migrate to current settings version + * + * @return bool + */ +int read_settings() { + //Check version-byte of eeprom + uint8_t version = eeprom_get_char(0); + + if (version == SETTINGS_VERSION) { + //Read settings-record and check checksum + if(!(memcpy_from_eeprom_with_checksum((unsigned char*)&settings, 1, sizeof(settings_t)))) { + return(false); + } + } else if (version == 1) { + //Migrate from settings version 1 + if (!(memcpy_from_eeprom_with_checksum((unsigned char*)&settings, 1, sizeof(settings_v1_t)))) { + return(false); + } + write_settings(); + } else if ((version == 2) || (version == 3)) { + //Migrate from settings version 2 and 3 + if (!(memcpy_from_eeprom_with_checksum((unsigned char*)&settings, 1, sizeof(settings_t)))) { + return(false); + } + write_settings(); + } else { + return(false); + } + return(true); +} + +/** + * A helper method to set settings from command line + * + * @param parameter + * @param value + */ +void settings_store_setting(int parameter, double value) { + switch(parameter) { + case 0: + settings.rod_step = value; + settings.steps_per_mm[X_AXIS] = settings.steps_per_turn[X_AXIS] / settings.rod_step; + settings.steps_per_mm[Y_AXIS] = settings.steps_per_turn[Y_AXIS] / settings.rod_step; + settings.steps_per_mm[Z_AXIS] = settings.steps_per_turn[Z_AXIS] / settings.rod_step; + break; + case 1: case 2: case 3: + if (value <= 0.0) { + printPgmString(PSTR("Steps/turn must be > 0.0\r\n")); + return; + } + settings.steps_per_turn[parameter] = value; + settings.steps_per_mm[parameter] = settings.steps_per_turn[parameter] / settings.rod_step; + break; + case 4: case 5: case 6: + if (value <= 0.0) { + printPgmString(PSTR("Steps/mm must be > 0.0\r\n")); + return; + } + settings.steps_per_mm[parameter] = value; + break; + case 7: + settings.default_feed_rate = value; + break; + case 8: + settings.default_seek_rate = value; + break; + case 9: + settings.mm_per_arc_segment = value; + break; + case 10: + settings.invert_mask = trunc(value); + break; + case 11: + settings.default_spindle_speed = value; + break; + case 12: + settings.limit_switch = value; + break; + case 13: + settings.release_after_move = value; + break; + + case 14: + printPgmString(PSTR("\r\nWork area on X axis\r\n")); + break; + case 15: + printPgmString(PSTR("\r\nWork area on Y axis\r\n")); + break; + case 16: + printPgmString(PSTR("\r\nWork area on Z axis\r\n")); + break; + + case 17: + if(settings.limit_switch == 1){ + printPgmString(PSTR("\r\nCalibrating... please wait\r\n")); + st_calibrate(); + }else{ + printPgmString(PSTR("\r\n Not available if no limit switch!!!\r\n")); + } + break; + case 18: + if(value == 1){ + settings_reset(); + write_settings(); + settings_dump(); + printPgmString(PSTR("\r\nSetings reseted\r\n")); + } + break; + default: + printPgmString(PSTR("\r\nUnknown parameter\r\n")); + return; + } + + write_settings(); + printPgmString(PSTR("\r\nStored new setting\r\n")); + +} + +/** + * Initialize the config subsystem + */ +void settings_init() { + if(read_settings()) { + printPgmString(PSTR("\r\n'$' to dump current settings\r\n")); + } else { + printPgmString(PSTR("\r\nWarning: Failed to read EEPROM settings. Using defaults.\r\n")); + settings_reset(); + write_settings(); + settings_dump(); + } +} diff --git a/trunk/Arduino/GRBL_Adafruit_motor_driverV2/settings.h b/trunk/Arduino/GRBL_Adafruit_motor_driverV2/settings.h new file mode 100644 index 00000000..19b47212 --- /dev/null +++ b/trunk/Arduino/GRBL_Adafruit_motor_driverV2/settings.h @@ -0,0 +1,64 @@ +/** + * Part of Grbl interpreter modified to work with Adafruit Motor Driver V2 + * File modified by Catalin Vasiliu + * email + * + * + * + * Original license:*********************************************************** + * Copyright (c) 2009-2011 Simen Svale Skogsrud + * Copyright (c) 2011 Sungeun K. Jeon + * + * Grbl is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Grbl is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef settings_h +#define settings_h + +#include +#include + +#define GRBL_VERSION "0.9j" + +//Version of the EEPROM data. Will be used to migrate existing data from older versions of Grbl +//When firmware is upgraded. Always stored in byte 0 of eeprom +#define SETTINGS_VERSION 4 + +//Current global settings (persisted in EEPROM from byte 1 onwards) +typedef struct { + float rod_step; + int steps_per_turn[3]; + double steps_per_mm[3]; + double default_feed_rate; + double default_seek_rate; + uint8_t invert_mask; + double mm_per_arc_segment; + int default_spindle_speed; + double work_area[3]; + bool limit_switch; + bool release_after_move; +} settings_t; + +extern settings_t settings; + +//Initialize the configuration subsystem (load settings from EEPROM) +void settings_init(); + +//Print current settings +void settings_dump(); + +//Handle settings command +uint8_t settings_execute_line(char *line); + +//A helper method to set new settings from command line +void settings_store_setting(int parameter, double value); + +#endif diff --git a/trunk/Arduino/GRBL_Adafruit_motor_driverV2/stepper_control.cpp b/trunk/Arduino/GRBL_Adafruit_motor_driverV2/stepper_control.cpp new file mode 100644 index 00000000..b20cccb9 --- /dev/null +++ b/trunk/Arduino/GRBL_Adafruit_motor_driverV2/stepper_control.cpp @@ -0,0 +1,416 @@ +/** + * This file initially contained methods that handle motor control + * I combined the motor control with motion control + * + * File contains methods for linear movement, arc generator and motor control + * + */ + +/** + * Part of Grbl interpreter modified to work with Adafruit Motor Driver V2 + * File created by Catalin Vasiliu + * email + */ + +#include +#include +#include "utility/Adafruit_PWMServoDriver.h" +//#include + +#include + +#include "config.h" +#include "nuts_bolts.h" +#include "settings.h" +#include "limit_switch.h" +#include "protocol.h" +#include "gcode.h" + +#define X_motor 0 +#define Y_motor 1 +#define Z_motor 2 +#define NUM_AXIES 3 + +Adafruit_MotorShield YZ_shield = Adafruit_MotorShield(0x60); +Adafruit_MotorShield XSpindle_shield = Adafruit_MotorShield(0x61); + +Adafruit_StepperMotor *Motor[3]; +Adafruit_DCMotor *spindle = XSpindle_shield.getMotor(SPINDLE_PORT); + +static int current_direction; + +typedef struct { + long steps_to_travel; + long abs_steps_to_travel; + int dir; + long step_counter; +} Axis; + +Axis axis[3]; + +/** + * Change I2C clock to 400 KHz + * Initialize Adafruit Motor Shields + */ +void shield_begin() { + //Change the i2c clock to 400KHz + TWBR = ((F_CPU / 400000l) - 16) / 2; + + YZ_shield.begin(); + XSpindle_shield.begin(); + + +} + +/** + * Initialize motors + */ +void motors_init(){ + Motor[X_motor] = XSpindle_shield.getStepper(settings.steps_per_turn[X_AXIS], 2); //x + Motor[Y_motor] = YZ_shield.getStepper(settings.steps_per_turn[Y_AXIS], 2); //y + Motor[Z_motor] = YZ_shield.getStepper(settings.steps_per_turn[Z_AXIS], 1); //z +} + +/** + * Turn ON/OFF spindle motor + * Set direction and speed + * RPM not implemented use values for pwm (0-255) + * + * @param int direction + * @param 32bit int rpm + */ +void spindle_run(int direction, uint32_t rpm) { + if (direction != current_direction) { + spindle->setSpeed(rpm); + if (direction > 0) { + spindle->run(FORWARD); + } else if (direction < 0) { + spindle->run(BACKWARD); + } else { + spindle->run(RELEASE); + } + } + current_direction = direction; +} + +/** + * Stop spindle + */ +void spindle_stop() { + spindle_run(0, 0); +} + +/** + * Check the limit switch according to axis and direction + * Move the motor one step in the direction...motors are define Motor[] + * Return status ok or limit switch error + * + * @param int motor + * @param int direction + * @return int status + */ +uint8_t st_onestep(int motor, int direction) { + if(settings.limit_switch == 1){ + uint8_t switchCheck = ls_check(motor, direction); + if (switchCheck > 0) { + return switchCheck; + } + } + Motor[motor]->onestep(direction > 0 ? FORWARD : BACKWARD, DOUBLE); + return STATUS_OK; +} + +/** + * Pause for the @param seconds ... just delay + * + * @param double seconds + */ +void st_dwell(double seconds) { + delay_ms(seconds * 1000); +} + +/** + * Move the tool from current position to xyz position in a straight line + * Uses oneStep() function to move motors + * Calculate the time that took to travel one step on every axes + * (eg x1, y1, z0 steps is approx 1.4/step_per_mm and it takes about 8ms to travel) + * Calculate the time that the action should take according to feed_rate and pause the diference + * Return status + * + * @param double[3] position current position (gc.position) + * @param double x + * @param double y + * @param double z + * @param double feed_rate / seek_rate + * @param invert_feed_rate + * @return int status ...from oneStep / ls_check + */ +uint8_t st_line(double *position, double x, double y, double z, double feed_rate, uint8_t invert_feed_rate) { + uint8_t status = STATUS_OK; + //calculate steps to make on each axis + axis[X_AXIS].steps_to_travel = lround((x - position[X_AXIS]) * settings.steps_per_mm[X_AXIS]); + axis[Y_AXIS].steps_to_travel = lround((y - position[Y_AXIS]) * settings.steps_per_mm[Y_AXIS]); + axis[Z_AXIS].steps_to_travel = lround((z - position[Z_AXIS]) * settings.steps_per_mm[Z_AXIS]); + + long i, j, maxsteps = 0; + + for (i = 0; i < NUM_AXIES; ++i) { + //do not take minus vall + axis[i].abs_steps_to_travel = abs(axis[i].steps_to_travel); + //calculate dir + axis[i].dir = axis[i].steps_to_travel > 0 ? 1 : -1; + //get the longest distance + if (maxsteps < axis[i].abs_steps_to_travel) { + maxsteps = axis[i].abs_steps_to_travel; + } + axis[i].step_counter = 0; + } + //store here if a step was made on a axis, need to calculate time + bool axis_step[3]; + + for (i = 0; i < maxsteps; ++i) { + //get the start time + unsigned long start_step_time = millis(); + for (j = 0; j < NUM_AXIES; ++j) { + axis[j].step_counter += axis[j].abs_steps_to_travel; + if (axis[j].step_counter >= maxsteps) { + axis[j].step_counter -= maxsteps; + status = st_onestep(j, axis[j].dir); + //check status and return if limit reach + if (status != STATUS_OK) { + return status; + } + axis_step[j] = 1; + } else { + axis_step[j] = 0; + } + } + + //calculate distance traveled + float distance_traveled_mm = sqrt( + ((axis_step[X_AXIS] / settings.steps_per_mm[X_AXIS]) * (axis_step[X_AXIS] / settings.steps_per_mm[X_AXIS])) + + ((axis_step[Y_AXIS] / settings.steps_per_mm[Y_AXIS]) * (axis_step[Y_AXIS] / settings.steps_per_mm[Y_AXIS])) + + ((axis_step[Z_AXIS] / settings.steps_per_mm[Z_AXIS]) * (axis_step[Z_AXIS] / settings.steps_per_mm[Z_AXIS])) + ); + + //calculate how much time(in milliseconds) should take to travel distance_traveled_mm according to feed rate + double time_should_take = distance_traveled_mm * 60000 / feed_rate; + //time that actualy take to travel + unsigned long step_time = millis() - start_step_time; + //calculate time to pause, do not accept val < 0 + if (time_should_take - step_time > 0) { + delay_ms(time_should_take - step_time); + } + } + //release motors...see config.h comments for more info + if(settings.release_after_move == 1){ + for (int j = 0; j < 3; j++) { + Motor[j]->release(); + } + } + return status; +} + +/** + * Move tool to program Zero position + * + * @param double[3] position + */ +void st_go_home(double *position) { + st_line(position, 0, 0, 0, settings.default_feed_rate, false); +} + + +float atan3(float dy, float dx) { + float a = atan2(dy, dx); + if (a < 0) a = (PI * 2.0) + a; + return a; +} + +/** + * This method assumes the limits have already been checked. + * This method assumes the start and end radius match. + * This method assumes arcs are not >180 degrees (PI radians) + * + * Calculates the length of the arc according to start and end coordinates + * Brake the arc in segments (segment length defined in settings) + * Uses the st_line() function to draw each segment according to feed_rate + * + * + * @param double[3] position current position array[x, y, z] also the start of the arc + * @param double[3] target end at the arc array[x, y, z] + * @param double[3] offset the center of the circle array[x, y, z] + * @param uint8_t axis_0 contain 0, 1 or 2 and is the first axis on the selected plan + * the value represent the physical axis (ex 0 is X_AXIS, 1 is Y_AXIS..) + * @param uint8_t axis_1 the second axis on the selected plan + * @param uint8_t axis_linear the third axis on the selected plan, this one does not move + * @param double feed_rate in mm/minute or inch/minute + * @param uint8_t invert_feed_rate + * @param double radius the radius of the arc calculated in gcode.cpp + * @param bool isclockwise direction to draw the circle + * @return uint8_t status + */ +uint8_t st_arc(double *position, double *target, double *offset, uint8_t axis_0, uint8_t axis_1, + uint8_t axis_linear, double feed_rate, uint8_t invert_feed_rate, double radius, uint8_t isclockwise) { + + uint8_t status = STATUS_OK; + + // find angle of arc (sweep) + double angle1 = atan3(position[axis_1] - offset[axis_1], position[axis_0] - offset[axis_0]); + double angle2 = atan3( target[axis_1] - offset[axis_1], target[axis_0] - offset[axis_0]); + double theta = angle2 - angle1; + + if (isclockwise == 1 && theta < 0){ + angle2 += 2 * PI; + } + else if (isclockwise == 0 && theta > 0) { + angle1 += 2 * PI; + } + + theta = angle2 - angle1; + + // get length of arc + double len = abs(theta) * radius; + + int i, segments = ceil(len * settings.mm_per_arc_segment); + + double nx, ny, angle3, scale; + double arc_target[3]; + + for (i = 0; i < segments; ++i) { + // interpolate around the arc + scale = ((double) i) / ((double) segments); + + angle3 = (theta * scale) + angle1; + + //update arc target + arc_target[axis_0] = offset[axis_0] + cos(angle3) * radius; + arc_target[axis_1] = offset[axis_1] + sin(angle3) * radius; + arc_target[axis_linear] = position[axis_linear]; + + // make a line to that intermediate position + status = st_line(position, arc_target[X_AXIS], arc_target[Y_AXIS], arc_target[Z_AXIS], feed_rate, 0); + //check the status + if (status != STATUS_OK) { + return status; + } + //update new position + position[X_AXIS] = arc_target[X_AXIS]; + position[Y_AXIS] = arc_target[Y_AXIS]; + position[Z_AXIS] = arc_target[Z_AXIS]; + } + //draw the last segment + status = st_line(position, target[X_AXIS], target[Y_AXIS], target[Z_AXIS], feed_rate, 0); + return status; + +} + +/** + * put all motors to mechanical zero except the z axis witch is optional + * be aware of the tool on z axis, it may be lower so it can not reach the limit + * switch this will stall the motor and also can cause damages + * + * Works only with limit switch !!! + * + * @param bool zero_Z_axis + */ +void st_go_to_zero(bool zero_Z_axis) { + if(settings.limit_switch == 1){ + uint8_t xLimit = 0; + uint8_t yLimit = 0; + uint8_t zLimit = 0; + + while (true) { + if (st_onestep(X_AXIS, -1) == X_LIMIT_START_ENABLE) { + xLimit = 1; + } + if (st_onestep(Y_AXIS, -1) == Y_LIMIT_START_ENABLE) { + yLimit = 1; + } + if (zero_Z_axis) { + if (st_onestep(Z_AXIS, -1) == Z_LIMIT_START_ENABLE) { + zLimit = 1; + } + if (xLimit + yLimit + zLimit == 3) { + break; + } + } else { + if (xLimit + yLimit == 2) { + break; + } + } + } + } +} + +/** + * Count steps from mechanical zero to mechanical max + * Set values in settings.work_area[X_AXIS] + * Values in mm + * + * Works only with limit switch !!! + */ +void st_calibrate() { + if(settings.limit_switch == 1){ + //Go all to 0 + st_go_to_zero(true); + + uint8_t xLimit = 0; + uint8_t yLimit = 0; + uint8_t zLimit = 0; + + double xCounter = 0; + double yCounter = 0; + double zCounter = 0; + + while (true) { + if (st_onestep(X_AXIS, 1) == X_LIMIT_END_ENABLE) { + xLimit = 1; + } else { + xCounter++; + } + if (st_onestep(Y_AXIS, 1) == Y_LIMIT_END_ENABLE) { + yLimit = 1; + } else { + yCounter++; + } + if (st_onestep(Z_AXIS, 1) == Z_LIMIT_END_ENABLE) { + zLimit = 1; + } else { + zCounter++; + } + if (xLimit + yLimit + zLimit == 3) { + break; + } + } + settings.work_area[X_AXIS] = xCounter / settings.steps_per_mm[X_AXIS]; + settings.work_area[Y_AXIS] = yCounter / settings.steps_per_mm[Y_AXIS]; + settings.work_area[Z_AXIS] = zCounter / settings.steps_per_mm[Z_AXIS]; + } +} + +/** + * Works with M102 and limit swiths + * Put jogs to a compact position for storage + * Park it :P + * In my configuration is easyer to store the machine with + * x axis to minimum ad y axis to maximum + */ +void st_machine_park(){ + if(settings.limit_switch == 1){ + uint8_t xLimit = 0; + uint8_t yLimit = 0; + + while (true) { + if (st_onestep(X_AXIS, -1) == X_LIMIT_START_ENABLE) { + xLimit = 1; + } + if (st_onestep(Y_AXIS, 1) == Y_LIMIT_END_ENABLE) { + yLimit = 1; + } + if (xLimit + yLimit == 2) { + break; + } + } + } +} \ No newline at end of file diff --git a/trunk/Arduino/GRBL_Adafruit_motor_driverV2/stepper_control.h b/trunk/Arduino/GRBL_Adafruit_motor_driverV2/stepper_control.h new file mode 100644 index 00000000..dda4d37e --- /dev/null +++ b/trunk/Arduino/GRBL_Adafruit_motor_driverV2/stepper_control.h @@ -0,0 +1,37 @@ +/** + * Part of Grbl interpreter modified to work with Adafruit Motor Driver V2 + * File created by Catalin Vasiliu + * email + */ + +#ifndef STEPPER_H +#define STEPPER_H + + +void shield_begin(); +void motors_init(); +void spindle_run(int direction, uint32_t rpm); +void spindle_stop(); + +uint8_t st_onestep(int motor, int direction); + +void st_go_home(double *position); + +void st_dwell(double seconds); + +double st_set_current_position(double x, double y, double z); + +uint8_t st_line(double *position, double x, double y, double z, double feed_rate, uint8_t invert_feed_rate); + +uint8_t st_arc(double *position, double *target, double *offset, uint8_t axis_0, uint8_t axis_1, + uint8_t axis_linear, double feed_rate, uint8_t invert_feed_rate, double radius, uint8_t isclockwise); + + +void st_machine_park(); +//Put all motors to lowest val on axes +void st_go_to_zero(bool zAxis); +void st_calibrate(); + + +#endif /* STEPPER_H */ + diff --git a/trunk/Arduino/Marlin_1.1.6/Conditionals.h b/trunk/Arduino/Marlin_1.1.6/Conditionals.h new file mode 100644 index 00000000..ff6c6b18 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/Conditionals.h @@ -0,0 +1,27 @@ +/** + * 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 . + * + */ + +/** + * Conditionals.h + * OBSOLETE: Replaced by Conditionals_LCD.h and Conditionals_post.h + */ +#error "Old configurations? Please delete all #include lines from Configuration.h and Configuration_adv.h." diff --git a/trunk/Arduino/Marlin_1.1.6/Conditionals_LCD.h b/trunk/Arduino/Marlin_1.1.6/Conditionals_LCD.h new file mode 100644 index 00000000..b5b476a6 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/Conditionals_LCD.h @@ -0,0 +1,480 @@ +/** + * 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 . + * + */ + +/** + * Conditionals_LCD.h + * Conditionals that need to be set before Configuration_adv.h or pins.h + */ + +#ifndef CONDITIONALS_LCD_H // Get the LCD defines which are needed first +#define CONDITIONALS_LCD_H + + #define LCD_HAS_DIRECTIONAL_BUTTONS (BUTTON_EXISTS(UP) || BUTTON_EXISTS(DWN) || BUTTON_EXISTS(LFT) || BUTTON_EXISTS(RT)) + + #if ENABLED(CARTESIO_UI) + + #define DOGLCD + #define ULTIPANEL + #define DEFAULT_LCD_CONTRAST 90 + #define LCD_CONTRAST_MIN 60 + #define LCD_CONTRAST_MAX 140 + + #elif ENABLED(MAKRPANEL) + + #define U8GLIB_ST7565_64128N + + #elif ENABLED(ANET_KEYPAD_LCD) + + #define REPRAPWORLD_KEYPAD + #define REPRAPWORLD_KEYPAD_MOVE_STEP 10.0 + #define ADC_KEYPAD + #define ADC_KEY_NUM 8 + #define ULTIPANEL + + // this helps to implement ADC_KEYPAD menus + #define ENCODER_PULSES_PER_STEP 1 + #define ENCODER_STEPS_PER_MENU_ITEM 1 + #define REVERSE_MENU_DIRECTION + + #elif ENABLED(ANET_FULL_GRAPHICS_LCD) + + #define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER + + #elif ENABLED(BQ_LCD_SMART_CONTROLLER) + + #define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER + #define LONG_FILENAME_HOST_SUPPORT + + #elif ENABLED(miniVIKI) || ENABLED(VIKI2) || ENABLED(ELB_FULL_GRAPHIC_CONTROLLER) + + #define ULTRA_LCD //general LCD support, also 16x2 + #define DOGLCD // Support for SPI LCD 128x64 (Controller ST7565R graphic Display Family) + #define ULTIMAKERCONTROLLER //as available from the Ultimaker online store. + + #if ENABLED(miniVIKI) + #define LCD_CONTRAST_MIN 75 + #define LCD_CONTRAST_MAX 115 + #define DEFAULT_LCD_CONTRAST 95 + #define U8GLIB_ST7565_64128N + #elif ENABLED(VIKI2) + #define LCD_CONTRAST_MIN 0 + #define LCD_CONTRAST_MAX 255 + #define DEFAULT_LCD_CONTRAST 140 + #define U8GLIB_ST7565_64128N + #elif ENABLED(ELB_FULL_GRAPHIC_CONTROLLER) + #define LCD_CONTRAST_MIN 90 + #define LCD_CONTRAST_MAX 130 + #define DEFAULT_LCD_CONTRAST 110 + #define U8GLIB_LM6059_AF + #define SD_DETECT_INVERTED + #endif + + #elif ENABLED(OLED_PANEL_TINYBOY2) + + #define U8GLIB_SSD1306 + #define ULTIPANEL + #define REVERSE_ENCODER_DIRECTION + #define REVERSE_MENU_DIRECTION + + #elif ENABLED(RA_CONTROL_PANEL) + + #define LCD_I2C_TYPE_PCA8574 + #define LCD_I2C_ADDRESS 0x27 // I2C Address of the port expander + #define ULTIPANEL + + #elif ENABLED(REPRAPWORLD_GRAPHICAL_LCD) + + #define DOGLCD + #define U8GLIB_ST7920 + #define ULTIPANEL + + #elif ENABLED(CR10_STOCKDISPLAY) + + #define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER + #ifndef ST7920_DELAY_1 + #define ST7920_DELAY_1 DELAY_2_NOP + #endif + #ifndef ST7920_DELAY_2 + #define ST7920_DELAY_2 DELAY_2_NOP + #endif + #ifndef ST7920_DELAY_3 + #define ST7920_DELAY_3 DELAY_2_NOP + #endif + + #elif ENABLED(MKS_12864OLED) + + #define REPRAP_DISCOUNT_SMART_CONTROLLER + #define U8GLIB_SH1106 + + #elif ENABLED(MKS_MINI_12864) + + #define MINIPANEL + + #endif + + #if ENABLED(MAKRPANEL) || ENABLED(MINIPANEL) + #define DOGLCD + #define ULTIPANEL + #define DEFAULT_LCD_CONTRAST 17 + #endif + + // Generic support for SSD1306 / SH1106 OLED based LCDs. + #if ENABLED(U8GLIB_SSD1306) || ENABLED(U8GLIB_SH1106) + #define ULTRA_LCD //general LCD support, also 16x2 + #define DOGLCD // Support for I2C LCD 128x64 (Controller SSD1306 / SH1106 graphic Display Family) + #endif + + #if ENABLED(PANEL_ONE) || ENABLED(U8GLIB_SH1106) + + #define ULTIMAKERCONTROLLER + + #elif ENABLED(MAKEBOARD_MINI_2_LINE_DISPLAY_1602) + + #define REPRAP_DISCOUNT_SMART_CONTROLLER + #define LCD_WIDTH 16 + #define LCD_HEIGHT 2 + + #endif + + #if ENABLED(REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER) || ENABLED(LCD_FOR_MELZI) + #define DOGLCD + #define U8GLIB_ST7920 + #define REPRAP_DISCOUNT_SMART_CONTROLLER + #endif + + #if ENABLED(ULTIMAKERCONTROLLER) \ + || ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER) \ + || ENABLED(G3D_PANEL) \ + || ENABLED(RIGIDBOT_PANEL) + #define ULTIPANEL + #endif + + #if ENABLED(REPRAPWORLD_KEYPAD) + #define NEWPANEL + #if ENABLED(ULTIPANEL) && !defined(REPRAPWORLD_KEYPAD_MOVE_STEP) + #define REPRAPWORLD_KEYPAD_MOVE_STEP 1.0 + #endif + #endif + + /** + * I2C PANELS + */ + + #if ENABLED(LCD_I2C_SAINSMART_YWROBOT) + + // Note: This controller requires F.Malpartida's LiquidCrystal_I2C library + // https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home + + #define LCD_I2C_TYPE_PCF8575 + #define LCD_I2C_ADDRESS 0x27 // I2C Address of the port expander + #define ULTIPANEL + + #elif ENABLED(LCD_I2C_PANELOLU2) + + // PANELOLU2 LCD with status LEDs, separate encoder and click inputs + + #define LCD_I2C_TYPE_MCP23017 + #define LCD_I2C_ADDRESS 0x20 // I2C Address of the port expander + #define LCD_USE_I2C_BUZZER //comment out to disable buzzer on LCD + #define ULTIPANEL + + #elif ENABLED(LCD_I2C_VIKI) + + /** + * Panucatt VIKI LCD with status LEDs, integrated click & L/R/U/P buttons, separate encoder inputs + * + * This uses the LiquidTWI2 library v1.2.3 or later ( https://github.com/lincomatic/LiquidTWI2 ) + * Make sure the LiquidTWI2 directory is placed in the Arduino or Sketchbook libraries subdirectory. + * Note: The pause/stop/resume LCD button pin should be connected to the Arduino + * BTN_ENC pin (or set BTN_ENC to -1 if not used) + */ + #define LCD_I2C_TYPE_MCP23017 + #define LCD_I2C_ADDRESS 0x20 // I2C Address of the port expander + #define LCD_USE_I2C_BUZZER //comment out to disable buzzer on LCD (requires LiquidTWI2 v1.2.3 or later) + #define ULTIPANEL + + #define ENCODER_FEEDRATE_DEADZONE 4 + + #define STD_ENCODER_PULSES_PER_STEP 1 + #define STD_ENCODER_STEPS_PER_MENU_ITEM 2 + + #elif ENABLED(G3D_PANEL) + + #define STD_ENCODER_PULSES_PER_STEP 2 + #define STD_ENCODER_STEPS_PER_MENU_ITEM 1 + + #elif ENABLED(miniVIKI) || ENABLED(VIKI2) \ + || ENABLED(ELB_FULL_GRAPHIC_CONTROLLER) \ + || ENABLED(OLED_PANEL_TINYBOY2) \ + || ENABLED(BQ_LCD_SMART_CONTROLLER) \ + || ENABLED(LCD_I2C_PANELOLU2) \ + || ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER) + #define STD_ENCODER_PULSES_PER_STEP 4 + #define STD_ENCODER_STEPS_PER_MENU_ITEM 1 + #endif + + #ifndef STD_ENCODER_PULSES_PER_STEP + #define STD_ENCODER_PULSES_PER_STEP 5 + #endif + #ifndef STD_ENCODER_STEPS_PER_MENU_ITEM + #define STD_ENCODER_STEPS_PER_MENU_ITEM 1 + #endif + #ifndef ENCODER_PULSES_PER_STEP + #define ENCODER_PULSES_PER_STEP STD_ENCODER_PULSES_PER_STEP + #endif + #ifndef ENCODER_STEPS_PER_MENU_ITEM + #define ENCODER_STEPS_PER_MENU_ITEM STD_ENCODER_STEPS_PER_MENU_ITEM + #endif + #ifndef ENCODER_FEEDRATE_DEADZONE + #define ENCODER_FEEDRATE_DEADZONE 6 + #endif + + // Shift register panels + // --------------------- + // 2 wire Non-latching LCD SR from: + // https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/schematics#!shiftregister-connection + + #if ENABLED(SAV_3DLCD) + #define SR_LCD_2W_NL // Non latching 2 wire shift register + #define ULTIPANEL + #endif + + #if ENABLED(DOGLCD) // Change number of lines to match the DOG graphic display + #ifndef LCD_WIDTH + #define LCD_WIDTH 22 + #endif + #ifndef LCD_HEIGHT + #define LCD_HEIGHT 5 + #endif + #endif + + #if ENABLED(ULTIPANEL) + #define NEWPANEL // Disable this if you actually have no click-encoder panel + #define ULTRA_LCD + #ifndef LCD_WIDTH + #define LCD_WIDTH 20 + #endif + #ifndef LCD_HEIGHT + #define LCD_HEIGHT 4 + #endif + #elif ENABLED(ULTRA_LCD) // no panel but just LCD + #ifndef LCD_WIDTH + #define LCD_WIDTH 16 + #endif + #ifndef LCD_HEIGHT + #define LCD_HEIGHT 2 + #endif + #endif + + #if ENABLED(DOGLCD) + /* Custom characters defined in font dogm_font_data_Marlin_symbols.h / Marlin_symbols.fon */ + // \x00 intentionally skipped to avoid problems in strings + #define LCD_STR_REFRESH "\x01" + #define LCD_STR_FOLDER "\x02" + #define LCD_STR_ARROW_RIGHT "\x03" + #define LCD_STR_UPLEVEL "\x04" + #define LCD_STR_CLOCK "\x05" + #define LCD_STR_FEEDRATE "\x06" + #define LCD_STR_BEDTEMP "\x07" + #define LCD_STR_THERMOMETER "\x08" + #define LCD_STR_DEGREE "\x09" + + #define LCD_STR_SPECIAL_MAX '\x09' + // Maximum here is 0x1F because 0x20 is ' ' (space) and the normal charsets begin. + // Better stay below 0x10 because DISPLAY_CHARSET_HD44780_WESTERN begins here. + + // Symbol characters + #define LCD_STR_FILAM_DIA "\xf8" + #define LCD_STR_FILAM_MUL "\xa4" + #else + /* Custom characters defined in the first 8 characters of the LCD */ + #define LCD_BEDTEMP_CHAR 0x00 // Print only as a char. This will have 'unexpected' results when used in a string! + #define LCD_DEGREE_CHAR 0x01 + #define LCD_STR_THERMOMETER "\x02" // Still used with string concatenation + #define LCD_UPLEVEL_CHAR 0x03 + #define LCD_STR_REFRESH "\x04" + #define LCD_STR_FOLDER "\x05" + #define LCD_FEEDRATE_CHAR 0x06 + #define LCD_CLOCK_CHAR 0x07 + #define LCD_STR_ARROW_RIGHT ">" /* from the default character set */ + #endif + + /** + * Default LCD contrast for dogm-like LCD displays + */ + #if ENABLED(DOGLCD) + + #define HAS_LCD_CONTRAST ( \ + ENABLED(MAKRPANEL) \ + || ENABLED(CARTESIO_UI) \ + || ENABLED(VIKI2) \ + || ENABLED(miniVIKI) \ + || ENABLED(ELB_FULL_GRAPHIC_CONTROLLER) \ + ) + + #if HAS_LCD_CONTRAST + #ifndef LCD_CONTRAST_MIN + #define LCD_CONTRAST_MIN 0 + #endif + #ifndef LCD_CONTRAST_MAX + #define LCD_CONTRAST_MAX 63 + #endif + #ifndef DEFAULT_LCD_CONTRAST + #define DEFAULT_LCD_CONTRAST 32 + #endif + #endif + #endif + + // Boot screens + #if DISABLED(ULTRA_LCD) + #undef SHOW_BOOTSCREEN + #elif !defined(BOOTSCREEN_TIMEOUT) + #define BOOTSCREEN_TIMEOUT 2500 + #endif + + #define HAS_DEBUG_MENU ENABLED(LCD_PROGRESS_BAR_TEST) + + // MK2 Multiplexer forces SINGLENOZZLE to be enabled + #if ENABLED(MK2_MULTIPLEXER) + #define SINGLENOZZLE + #endif + + /** + * Extruders have some combination of stepper motors and hotends + * so we separate these concepts into the defines: + * + * EXTRUDERS - Number of Selectable Tools + * 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 + * TOOL_E_INDEX - Index to use when getting/setting the tool state + * + */ + #if ENABLED(SINGLENOZZLE) || ENABLED(MIXING_EXTRUDER) // One hotend, one thermistor, no XY offset + #define HOTENDS 1 + #undef TEMP_SENSOR_1_AS_REDUNDANT + #undef HOTEND_OFFSET_X + #undef HOTEND_OFFSET_Y + #else // Two hotends + #define HOTENDS EXTRUDERS + #if ENABLED(SWITCHING_NOZZLE) && !defined(HOTEND_OFFSET_Z) + #define HOTEND_OFFSET_Z { 0 } + #endif + #endif + + #if ENABLED(SWITCHING_EXTRUDER) || ENABLED(MIXING_EXTRUDER) // Unified E axis + #if ENABLED(MIXING_EXTRUDER) + #define E_STEPPERS MIXING_STEPPERS + #else + #define E_STEPPERS 1 // One E stepper + #endif + #define E_MANUAL 1 + #define TOOL_E_INDEX 0 + #else + #define E_STEPPERS EXTRUDERS + #define E_MANUAL EXTRUDERS + #define TOOL_E_INDEX current_block->active_extruder + #endif + + /** + * DISTINCT_E_FACTORS affects how some E factors are accessed + */ + #if ENABLED(DISTINCT_E_FACTORS) && E_STEPPERS > 1 + #define XYZE_N (XYZ + E_STEPPERS) + #define E_AXIS_N (E_AXIS + extruder) + #else + #undef DISTINCT_E_FACTORS + #define XYZE_N XYZE + #define E_AXIS_N E_AXIS + #endif + + /** + * The BLTouch Probe emulates a servo probe + * and uses "special" angles for its state. + */ + #if ENABLED(BLTOUCH) + #ifndef Z_ENDSTOP_SERVO_NR + #define Z_ENDSTOP_SERVO_NR 0 + #endif + #ifndef NUM_SERVOS + #define NUM_SERVOS (Z_ENDSTOP_SERVO_NR + 1) + #endif + #undef DEACTIVATE_SERVOS_AFTER_MOVE + #if NUM_SERVOS == 1 + #undef SERVO_DELAY + #define SERVO_DELAY { 50 } + #endif + #ifndef BLTOUCH_DELAY + #define BLTOUCH_DELAY 375 + #endif + #undef Z_SERVO_ANGLES + #define Z_SERVO_ANGLES { BLTOUCH_DEPLOY, BLTOUCH_STOW } + + #define BLTOUCH_DEPLOY 10 + #define BLTOUCH_STOW 90 + #define BLTOUCH_SELFTEST 120 + #define BLTOUCH_RESET 160 + #define _TEST_BLTOUCH(P) (READ(P##_PIN) != P##_ENDSTOP_INVERTING) + + // Always disable probe pin inverting for BLTouch + #undef Z_MIN_PROBE_ENDSTOP_INVERTING + #define Z_MIN_PROBE_ENDSTOP_INVERTING false + + #if ENABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN) + #undef Z_MIN_ENDSTOP_INVERTING + #define Z_MIN_ENDSTOP_INVERTING false + #define TEST_BLTOUCH() _TEST_BLTOUCH(Z_MIN) + #else + #define TEST_BLTOUCH() _TEST_BLTOUCH(Z_MIN_PROBE) + #endif + #endif + + /** + * Set a flag for a servo probe + */ + #define HAS_Z_SERVO_ENDSTOP (defined(Z_ENDSTOP_SERVO_NR) && Z_ENDSTOP_SERVO_NR >= 0) + + /** + * UBL has its own manual probing, so this just causes trouble. + */ + #if ENABLED(AUTO_BED_LEVELING_UBL) + #undef PROBE_MANUALLY + #endif + + /** + * Set a flag for any enabled probe + */ + #define PROBE_SELECTED (ENABLED(PROBE_MANUALLY) || ENABLED(FIX_MOUNTED_PROBE) || ENABLED(Z_PROBE_ALLEN_KEY) || HAS_Z_SERVO_ENDSTOP || ENABLED(Z_PROBE_SLED) || ENABLED(SOLENOID_PROBE)) + + /** + * Clear probe pin settings when no probe is selected + */ + #if !PROBE_SELECTED || ENABLED(PROBE_MANUALLY) + #undef Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + #undef Z_MIN_PROBE_ENDSTOP + #endif + + #define HAS_SOFTWARE_ENDSTOPS (ENABLED(MIN_SOFTWARE_ENDSTOPS) || ENABLED(MAX_SOFTWARE_ENDSTOPS)) + #define HAS_RESUME_CONTINUE (ENABLED(NEWPANEL) || ENABLED(EMERGENCY_PARSER)) + #define HAS_COLOR_LEDS (ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_LED)) + +#endif // CONDITIONALS_LCD_H diff --git a/trunk/Arduino/Marlin_1.1.6/Conditionals_post.h b/trunk/Arduino/Marlin_1.1.6/Conditionals_post.h new file mode 100644 index 00000000..dc6f2123 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/Conditionals_post.h @@ -0,0 +1,926 @@ +/** + * 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 . + * + */ + +/** + * Conditionals_post.h + * Defines that depend on configuration but are not editable. + */ + +#ifndef CONDITIONALS_POST_H +#define CONDITIONALS_POST_H + + #define IS_SCARA (ENABLED(MORGAN_SCARA) || ENABLED(MAKERARM_SCARA)) + #define IS_KINEMATIC (ENABLED(DELTA) || IS_SCARA) + #define IS_CARTESIAN !IS_KINEMATIC + + /** + * Axis lengths and center + */ + #define X_MAX_LENGTH (X_MAX_POS - (X_MIN_POS)) + #define Y_MAX_LENGTH (Y_MAX_POS - (Y_MIN_POS)) + #define Z_MAX_LENGTH (Z_MAX_POS - (Z_MIN_POS)) + + // Defined only if the sanity-check is bypassed + #ifndef X_BED_SIZE + #define X_BED_SIZE X_MAX_LENGTH + #endif + #ifndef Y_BED_SIZE + #define Y_BED_SIZE Y_MAX_LENGTH + #endif + + // Require 0,0 bed center for Delta and SCARA + #if IS_KINEMATIC + #define BED_CENTER_AT_0_0 + #endif + + // Define center values for future use + #if ENABLED(BED_CENTER_AT_0_0) + #define X_CENTER 0 + #define Y_CENTER 0 + #else + #define X_CENTER ((X_BED_SIZE) / 2) + #define Y_CENTER ((Y_BED_SIZE) / 2) + #endif + #define Z_CENTER ((Z_MIN_POS + Z_MAX_POS) / 2) + + // Get the linear boundaries of the bed + #define X_MIN_BED (X_CENTER - (X_BED_SIZE) / 2) + #define X_MAX_BED (X_CENTER + (X_BED_SIZE) / 2) + #define Y_MIN_BED (Y_CENTER - (Y_BED_SIZE) / 2) + #define Y_MAX_BED (Y_CENTER + (Y_BED_SIZE) / 2) + + /** + * CoreXY, CoreXZ, and CoreYZ - and their reverse + */ + #define CORE_IS_XY (ENABLED(COREXY) || ENABLED(COREYX)) + #define CORE_IS_XZ (ENABLED(COREXZ) || ENABLED(COREZX)) + #define CORE_IS_YZ (ENABLED(COREYZ) || ENABLED(COREZY)) + #define IS_CORE (CORE_IS_XY || CORE_IS_XZ || CORE_IS_YZ) + #if IS_CORE + #if CORE_IS_XY + #define CORE_AXIS_1 A_AXIS + #define CORE_AXIS_2 B_AXIS + #define NORMAL_AXIS Z_AXIS + #elif CORE_IS_XZ + #define CORE_AXIS_1 A_AXIS + #define NORMAL_AXIS Y_AXIS + #define CORE_AXIS_2 C_AXIS + #elif CORE_IS_YZ + #define NORMAL_AXIS X_AXIS + #define CORE_AXIS_1 B_AXIS + #define CORE_AXIS_2 C_AXIS + #endif + #if (ENABLED(COREYX) || ENABLED(COREZX) || ENABLED(COREZY)) + #define CORESIGN(n) (-(n)) + #else + #define CORESIGN(n) (n) + #endif + #endif + + /** + * No adjustable bed on non-cartesians + */ + #if IS_KINEMATIC + #undef LEVEL_BED_CORNERS + #endif + + /** + * SCARA cannot use SLOWDOWN and requires QUICKHOME + */ + #if IS_SCARA + #undef SLOWDOWN + #define QUICK_HOME + #endif + + /** + * Set the home position based on settings or manual overrides + */ + #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_BED_SIZE) * (X_HOME_DIR) * 0.5) + #endif + #else + #if ENABLED(DELTA) + #define X_HOME_POS (X_MIN_POS + (X_BED_SIZE) * 0.5) + #else + #define X_HOME_POS (X_HOME_DIR < 0 ? X_MIN_POS : X_MAX_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_BED_SIZE) * (Y_HOME_DIR) * 0.5) + #endif + #else + #if ENABLED(DELTA) + #define Y_HOME_POS (Y_MIN_POS + (Y_BED_SIZE) * 0.5) + #else + #define Y_HOME_POS (Y_HOME_DIR < 0 ? Y_MIN_POS : Y_MAX_POS) + #endif + #endif + + #ifdef MANUAL_Z_HOME_POS + #define Z_HOME_POS MANUAL_Z_HOME_POS + #else + #define Z_HOME_POS (Z_HOME_DIR < 0 ? Z_MIN_POS : Z_MAX_POS) + #endif + + /** + * If DELTA_HEIGHT isn't defined use the old setting + */ + #if ENABLED(DELTA) && !defined(DELTA_HEIGHT) + #define DELTA_HEIGHT Z_HOME_POS + #endif + + /** + * Auto Bed Leveling and Z Probe Repeatability Test + */ + #define HOMING_Z_WITH_PROBE (HAS_BED_PROBE && Z_HOME_DIR < 0 && ENABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN)) + + /** + * Z Sled Probe requires Z_SAFE_HOMING + */ + #if ENABLED(Z_PROBE_SLED) + #define Z_SAFE_HOMING + #endif + + /** + * DELTA should ignore Z_SAFE_HOMING and SLOWDOWN + */ + #if ENABLED(DELTA) + #undef Z_SAFE_HOMING + #undef SLOWDOWN + #endif + + /** + * Safe Homing Options + */ + #if ENABLED(Z_SAFE_HOMING) + #ifndef Z_SAFE_HOMING_X_POINT + #define Z_SAFE_HOMING_X_POINT X_CENTER + #endif + #ifndef Z_SAFE_HOMING_Y_POINT + #define Z_SAFE_HOMING_Y_POINT Y_CENTER + #endif + #define X_TILT_FULCRUM Z_SAFE_HOMING_X_POINT + #define Y_TILT_FULCRUM Z_SAFE_HOMING_Y_POINT + #else + #define X_TILT_FULCRUM X_HOME_POS + #define Y_TILT_FULCRUM Y_HOME_POS + #endif + + /** + * Host keep alive + */ + #ifndef DEFAULT_KEEPALIVE_INTERVAL + #define DEFAULT_KEEPALIVE_INTERVAL 2 + #endif + + /** + * Provide a MAX_AUTORETRACT for older configs + */ + #if ENABLED(FWRETRACT) && !defined(MAX_AUTORETRACT) + #define MAX_AUTORETRACT 99 + #endif + + /** + * MAX_STEP_FREQUENCY differs for TOSHIBA + */ + #if ENABLED(CONFIG_STEPPERS_TOSHIBA) + #define MAX_STEP_FREQUENCY 10000 // Max step frequency for Toshiba Stepper Controllers + #else + #define MAX_STEP_FREQUENCY 40000 // Max step frequency for Ultimaker (5000 pps / half step) + #endif + + // MS1 MS2 Stepper Driver Microstepping mode table + #define MICROSTEP1 LOW,LOW + #define MICROSTEP2 HIGH,LOW + #define MICROSTEP4 LOW,HIGH + #define MICROSTEP8 HIGH,HIGH + #define MICROSTEP16 HIGH,HIGH + + /** + * Override here because this is set in Configuration_adv.h + */ + #if ENABLED(ULTIPANEL) && DISABLED(ELB_FULL_GRAPHIC_CONTROLLER) + #undef SD_DETECT_INVERTED + #endif + + /** + * Set defaults for missing (newer) options + */ + #ifndef DISABLE_INACTIVE_X + #define DISABLE_INACTIVE_X DISABLE_X + #endif + #ifndef DISABLE_INACTIVE_Y + #define DISABLE_INACTIVE_Y DISABLE_Y + #endif + #ifndef DISABLE_INACTIVE_Z + #define DISABLE_INACTIVE_Z DISABLE_Z + #endif + #ifndef DISABLE_INACTIVE_E + #define DISABLE_INACTIVE_E DISABLE_E + #endif + + // Power Signal Control Definitions + // By default use ATX definition + #ifndef POWER_SUPPLY + #define POWER_SUPPLY 1 + #endif + #if (POWER_SUPPLY == 1) // 1 = ATX + #define PS_ON_AWAKE LOW + #define PS_ON_ASLEEP HIGH + #elif (POWER_SUPPLY == 2) // 2 = X-Box 360 203W + #define PS_ON_AWAKE HIGH + #define PS_ON_ASLEEP LOW + #endif + #define HAS_POWER_SWITCH (POWER_SUPPLY > 0 && PIN_EXISTS(PS_ON)) + + /** + * Temp Sensor defines + */ + #if TEMP_SENSOR_0 == -3 + #define HEATER_0_USES_MAX6675 + #define MAX6675_IS_MAX31855 + #define MAX6675_TMIN -270 + #define MAX6675_TMAX 1800 + #elif TEMP_SENSOR_0 == -2 + #define HEATER_0_USES_MAX6675 + #define MAX6675_TMIN 0 + #define MAX6675_TMAX 1024 + #elif TEMP_SENSOR_0 == -1 + #define HEATER_0_USES_AD595 + #elif TEMP_SENSOR_0 == 0 + #undef HEATER_0_MINTEMP + #undef HEATER_0_MAXTEMP + #elif TEMP_SENSOR_0 > 0 + #define THERMISTORHEATER_0 TEMP_SENSOR_0 + #define HEATER_0_USES_THERMISTOR + #endif + + #if TEMP_SENSOR_1 <= -2 + #error "MAX6675 / MAX31855 Thermocouples not supported for TEMP_SENSOR_1" + #elif TEMP_SENSOR_1 == -1 + #define HEATER_1_USES_AD595 + #elif TEMP_SENSOR_1 == 0 + #undef HEATER_1_MINTEMP + #undef HEATER_1_MAXTEMP + #elif TEMP_SENSOR_1 > 0 + #define THERMISTORHEATER_1 TEMP_SENSOR_1 + #define HEATER_1_USES_THERMISTOR + #endif + + #if TEMP_SENSOR_2 <= -2 + #error "MAX6675 / MAX31855 Thermocouples not supported for TEMP_SENSOR_2" + #elif TEMP_SENSOR_2 == -1 + #define HEATER_2_USES_AD595 + #elif TEMP_SENSOR_2 == 0 + #undef HEATER_2_MINTEMP + #undef HEATER_2_MAXTEMP + #elif TEMP_SENSOR_2 > 0 + #define THERMISTORHEATER_2 TEMP_SENSOR_2 + #define HEATER_2_USES_THERMISTOR + #endif + + #if TEMP_SENSOR_3 <= -2 + #error "MAX6675 / MAX31855 Thermocouples not supported for TEMP_SENSOR_3" + #elif TEMP_SENSOR_3 == -1 + #define HEATER_3_USES_AD595 + #elif TEMP_SENSOR_3 == 0 + #undef HEATER_3_MINTEMP + #undef HEATER_3_MAXTEMP + #elif TEMP_SENSOR_3 > 0 + #define THERMISTORHEATER_3 TEMP_SENSOR_3 + #define HEATER_3_USES_THERMISTOR + #endif + + #if TEMP_SENSOR_4 <= -2 + #error "MAX6675 / MAX31855 Thermocouples not supported for TEMP_SENSOR_4" + #elif TEMP_SENSOR_4 == -1 + #define HEATER_4_USES_AD595 + #elif TEMP_SENSOR_4 == 0 + #undef HEATER_4_MINTEMP + #undef HEATER_4_MAXTEMP + #elif TEMP_SENSOR_4 > 0 + #define THERMISTORHEATER_4 TEMP_SENSOR_4 + #define HEATER_4_USES_THERMISTOR + #endif + + #if TEMP_SENSOR_BED <= -2 + #error "MAX6675 / MAX31855 Thermocouples not supported for TEMP_SENSOR_BED" + #elif TEMP_SENSOR_BED == -1 + #define BED_USES_AD595 + #elif TEMP_SENSOR_BED == 0 + #undef BED_MINTEMP + #undef BED_MAXTEMP + #elif TEMP_SENSOR_BED > 0 + #define THERMISTORBED TEMP_SENSOR_BED + #define BED_USES_THERMISTOR + #endif + + /** + * Flags for PID handling + */ + #define HAS_PID_HEATING (ENABLED(PIDTEMP) || ENABLED(PIDTEMPBED)) + #define HAS_PID_FOR_BOTH (ENABLED(PIDTEMP) && ENABLED(PIDTEMPBED)) + + /** + * Default hotend offsets, if not defined + */ + #if HOTENDS > 1 + #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 + #if !defined(HOTEND_OFFSET_Z) && (ENABLED(DUAL_X_CARRIAGE) || ENABLED(SWITCHING_NOZZLE)) + #define HOTEND_OFFSET_Z { 0 } + #endif + #endif + + /** + * ARRAY_BY_EXTRUDERS based on EXTRUDERS + */ + #define ARRAY_BY_EXTRUDERS(...) ARRAY_N(EXTRUDERS, __VA_ARGS__) + #define ARRAY_BY_EXTRUDERS1(v1) ARRAY_BY_EXTRUDERS(v1, v1, v1, v1, v1, v1) + + /** + * ARRAY_BY_HOTENDS based on HOTENDS + */ + #define ARRAY_BY_HOTENDS(...) ARRAY_N(HOTENDS, __VA_ARGS__) + #define ARRAY_BY_HOTENDS1(v1) ARRAY_BY_HOTENDS(v1, v1, v1, v1, v1, v1) + + /** + * Z_DUAL_ENDSTOPS endstop reassignment + */ + #if ENABLED(Z_DUAL_ENDSTOPS) + #define _XMIN_ 100 + #define _YMIN_ 200 + #define _ZMIN_ 300 + #define _XMAX_ 101 + #define _YMAX_ 201 + #define _ZMAX_ 301 + #if Z2_USE_ENDSTOP == _XMIN_ + #define USE_XMIN_PLUG + #elif Z2_USE_ENDSTOP == _XMAX_ + #define USE_XMAX_PLUG + #elif Z2_USE_ENDSTOP == _YMIN_ + #define USE_YMIN_PLUG + #elif Z2_USE_ENDSTOP == _YMAX_ + #define USE_YMAX_PLUG + #elif Z2_USE_ENDSTOP == _ZMIN_ + #define USE_ZMIN_PLUG + #elif Z2_USE_ENDSTOP == _ZMAX_ + #define USE_ZMAX_PLUG + #endif + #if Z_HOME_DIR > 0 + #if Z2_USE_ENDSTOP == _XMIN_ + #define Z2_MAX_ENDSTOP_INVERTING X_MIN_ENDSTOP_INVERTING + #define Z2_MAX_PIN X_MIN_PIN + #elif Z2_USE_ENDSTOP == _XMAX_ + #define Z2_MAX_ENDSTOP_INVERTING X_MAX_ENDSTOP_INVERTING + #define Z2_MAX_PIN X_MAX_PIN + #elif Z2_USE_ENDSTOP == _YMIN_ + #define Z2_MAX_ENDSTOP_INVERTING Y_MIN_ENDSTOP_INVERTING + #define Z2_MAX_PIN Y_MIN_PIN + #elif Z2_USE_ENDSTOP == _YMAX_ + #define Z2_MAX_ENDSTOP_INVERTING Y_MAX_ENDSTOP_INVERTING + #define Z2_MAX_PIN Y_MAX_PIN + #elif Z2_USE_ENDSTOP == _ZMIN_ + #define Z2_MAX_ENDSTOP_INVERTING Z_MIN_ENDSTOP_INVERTING + #define Z2_MAX_PIN Z_MIN_PIN + #elif Z2_USE_ENDSTOP == _ZMAX_ + #define Z2_MAX_ENDSTOP_INVERTING Z_MAX_ENDSTOP_INVERTING + #define Z2_MAX_PIN Z_MAX_PIN + #else + #define Z2_MAX_ENDSTOP_INVERTING false + #endif + #else + #if Z2_USE_ENDSTOP == _XMIN_ + #define Z2_MIN_ENDSTOP_INVERTING X_MIN_ENDSTOP_INVERTING + #define Z2_MIN_PIN X_MIN_PIN + #elif Z2_USE_ENDSTOP == _XMAX_ + #define Z2_MIN_ENDSTOP_INVERTING X_MAX_ENDSTOP_INVERTING + #define Z2_MIN_PIN X_MAX_PIN + #elif Z2_USE_ENDSTOP == _YMIN_ + #define Z2_MIN_ENDSTOP_INVERTING Y_MIN_ENDSTOP_INVERTING + #define Z2_MIN_PIN Y_MIN_PIN + #elif Z2_USE_ENDSTOP == _YMAX_ + #define Z2_MIN_ENDSTOP_INVERTING Y_MAX_ENDSTOP_INVERTING + #define Z2_MIN_PIN Y_MAX_PIN + #elif Z2_USE_ENDSTOP == _ZMIN_ + #define Z2_MIN_ENDSTOP_INVERTING Z_MIN_ENDSTOP_INVERTING + #define Z2_MIN_PIN Z_MIN_PIN + #elif Z2_USE_ENDSTOP == _ZMAX_ + #define Z2_MIN_ENDSTOP_INVERTING Z_MAX_ENDSTOP_INVERTING + #define Z2_MIN_PIN Z_MAX_PIN + #else + #define Z2_MIN_ENDSTOP_INVERTING false + #endif + #endif + #endif + + // Is an endstop plug used for the Z2 endstop or the bed probe? + #define IS_Z2_OR_PROBE(A,M) ( \ + (ENABLED(Z_DUAL_ENDSTOPS) && Z2_USE_ENDSTOP == _##A##M##_) \ + || (ENABLED(Z_MIN_PROBE_ENDSTOP) && Z_MIN_PROBE_PIN == A##_##M##_PIN ) ) + + /** + * Set ENDSTOPPULLUPS for active endstop switches + */ + #if ENABLED(ENDSTOPPULLUPS) + #if ENABLED(USE_XMAX_PLUG) + #define ENDSTOPPULLUP_XMAX + #endif + #if ENABLED(USE_YMAX_PLUG) + #define ENDSTOPPULLUP_YMAX + #endif + #if ENABLED(USE_ZMAX_PLUG) + #define ENDSTOPPULLUP_ZMAX + #endif + #if ENABLED(USE_XMIN_PLUG) + #define ENDSTOPPULLUP_XMIN + #endif + #if ENABLED(USE_YMIN_PLUG) + #define ENDSTOPPULLUP_YMIN + #endif + #if ENABLED(USE_ZMIN_PLUG) + #define ENDSTOPPULLUP_ZMIN + #endif + #endif + + /** + * Shorthand for pin tests, used wherever needed + */ + + // Steppers + #define HAS_X_ENABLE (PIN_EXISTS(X_ENABLE)) + #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)) + #define HAS_X2_DIR (PIN_EXISTS(X2_DIR)) + #define HAS_X2_STEP (PIN_EXISTS(X2_STEP)) + #define HAS_Y_MICROSTEPS (PIN_EXISTS(Y_MS1)) + + #define HAS_Y_ENABLE (PIN_EXISTS(Y_ENABLE)) + #define HAS_Y_DIR (PIN_EXISTS(Y_DIR)) + #define HAS_Y_STEP (PIN_EXISTS(Y_STEP)) + #define HAS_Z_MICROSTEPS (PIN_EXISTS(Z_MS1)) + + #define HAS_Y2_ENABLE (PIN_EXISTS(Y2_ENABLE)) + #define HAS_Y2_DIR (PIN_EXISTS(Y2_DIR)) + #define HAS_Y2_STEP (PIN_EXISTS(Y2_STEP)) + + #define HAS_Z_ENABLE (PIN_EXISTS(Z_ENABLE)) + #define HAS_Z_DIR (PIN_EXISTS(Z_DIR)) + #define HAS_Z_STEP (PIN_EXISTS(Z_STEP)) + + #define HAS_Z2_ENABLE (PIN_EXISTS(Z2_ENABLE)) + #define HAS_Z2_DIR (PIN_EXISTS(Z2_DIR)) + #define HAS_Z2_STEP (PIN_EXISTS(Z2_STEP)) + + // Extruder steppers and solenoids + #define HAS_E0_ENABLE (PIN_EXISTS(E0_ENABLE)) + #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)) + #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)) + #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)) + #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)) + #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)) + + // Endstops and bed probe + #define HAS_X_MIN (PIN_EXISTS(X_MIN) && !IS_Z2_OR_PROBE(X,MIN)) + #define HAS_X_MAX (PIN_EXISTS(X_MAX) && !IS_Z2_OR_PROBE(X,MAX)) + #define HAS_Y_MIN (PIN_EXISTS(Y_MIN) && !IS_Z2_OR_PROBE(Y,MIN)) + #define HAS_Y_MAX (PIN_EXISTS(Y_MAX) && !IS_Z2_OR_PROBE(Y,MAX)) + #define HAS_Z_MIN (PIN_EXISTS(Z_MIN) && !IS_Z2_OR_PROBE(Z,MIN)) + #define HAS_Z_MAX (PIN_EXISTS(Z_MAX) && !IS_Z2_OR_PROBE(Z,MAX)) + #define HAS_Z2_MIN (PIN_EXISTS(Z2_MIN)) + #define HAS_Z2_MAX (PIN_EXISTS(Z2_MAX)) + #define HAS_Z_MIN_PROBE_PIN (PIN_EXISTS(Z_MIN_PROBE)) + + // Thermistors + #define HAS_TEMP_0 (PIN_EXISTS(TEMP_0) && TEMP_SENSOR_0 != 0 && TEMP_SENSOR_0 > -2) + #define HAS_TEMP_1 (PIN_EXISTS(TEMP_1) && TEMP_SENSOR_1 != 0 && TEMP_SENSOR_1 > -2) + #define HAS_TEMP_2 (PIN_EXISTS(TEMP_2) && TEMP_SENSOR_2 != 0 && TEMP_SENSOR_2 > -2) + #define HAS_TEMP_3 (PIN_EXISTS(TEMP_3) && TEMP_SENSOR_3 != 0 && TEMP_SENSOR_3 > -2) + #define HAS_TEMP_4 (PIN_EXISTS(TEMP_4) && TEMP_SENSOR_4 != 0 && TEMP_SENSOR_4 > -2) + #define HAS_TEMP_HOTEND (HAS_TEMP_0 || ENABLED(HEATER_0_USES_MAX6675)) + #define HAS_TEMP_BED (PIN_EXISTS(TEMP_BED) && TEMP_SENSOR_BED != 0 && TEMP_SENSOR_BED > -2) + + // 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_BED (PIN_EXISTS(HEATER_BED)) + + // Thermal protection + #define HAS_THERMALLY_PROTECTED_BED (ENABLED(THERMAL_PROTECTION_BED) && HAS_TEMP_BED && HAS_HEATER_BED) + #define WATCH_HOTENDS (ENABLED(THERMAL_PROTECTION_HOTENDS) && WATCH_TEMP_PERIOD > 0) + #define WATCH_THE_BED (HAS_THERMALLY_PROTECTED_BED && WATCH_BED_TEMP_PERIOD > 0) + + // Auto fans + #define HAS_AUTO_FAN_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 (HAS_AUTO_FAN_0 || HAS_AUTO_FAN_1 || HAS_AUTO_FAN_2 || HAS_AUTO_FAN_3) + #define AUTO_1_IS_0 (E1_AUTO_FAN_PIN == E0_AUTO_FAN_PIN) + #define AUTO_2_IS_0 (E2_AUTO_FAN_PIN == E0_AUTO_FAN_PIN) + #define AUTO_2_IS_1 (E2_AUTO_FAN_PIN == E1_AUTO_FAN_PIN) + #define AUTO_3_IS_0 (E3_AUTO_FAN_PIN == E0_AUTO_FAN_PIN) + #define AUTO_3_IS_1 (E3_AUTO_FAN_PIN == E1_AUTO_FAN_PIN) + #define AUTO_3_IS_2 (E3_AUTO_FAN_PIN == E2_AUTO_FAN_PIN) + #define AUTO_4_IS_0 (E4_AUTO_FAN_PIN == E0_AUTO_FAN_PIN) + #define AUTO_4_IS_1 (E4_AUTO_FAN_PIN == E1_AUTO_FAN_PIN) + #define AUTO_4_IS_2 (E4_AUTO_FAN_PIN == E2_AUTO_FAN_PIN) + #define AUTO_4_IS_3 (E4_AUTO_FAN_PIN == E3_AUTO_FAN_PIN) + + // Other fans + #define HAS_FAN0 (PIN_EXISTS(FAN)) + #define HAS_FAN1 (PIN_EXISTS(FAN1) && CONTROLLER_FAN_PIN != FAN1_PIN && E0_AUTO_FAN_PIN != FAN1_PIN && E1_AUTO_FAN_PIN != FAN1_PIN && E2_AUTO_FAN_PIN != FAN1_PIN && E3_AUTO_FAN_PIN != FAN1_PIN) + #define HAS_FAN2 (PIN_EXISTS(FAN2) && CONTROLLER_FAN_PIN != FAN2_PIN && E0_AUTO_FAN_PIN != FAN2_PIN && E1_AUTO_FAN_PIN != FAN2_PIN && E2_AUTO_FAN_PIN != FAN2_PIN && E3_AUTO_FAN_PIN != FAN2_PIN) + #define HAS_CONTROLLER_FAN (PIN_EXISTS(CONTROLLER_FAN)) + + // Servos + #define HAS_SERVOS (defined(NUM_SERVOS) && NUM_SERVOS > 0) + #define HAS_SERVO_0 (PIN_EXISTS(SERVO0)) + #define HAS_SERVO_1 (PIN_EXISTS(SERVO1)) + #define HAS_SERVO_2 (PIN_EXISTS(SERVO2)) + #define HAS_SERVO_3 (PIN_EXISTS(SERVO3)) + + // Sensors + #define HAS_FILAMENT_WIDTH_SENSOR (PIN_EXISTS(FILWIDTH)) + #define HAS_FIL_RUNOUT (PIN_EXISTS(FIL_RUNOUT)) + + // 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) || ENABLED(LCD_USE_I2C_BUZZER)) + #define HAS_CASE_LIGHT (PIN_EXISTS(CASE_LIGHT) && ENABLED(CASE_LIGHT_ENABLE)) + + // Digital control + #define HAS_MICROSTEPS (HAS_X_MICROSTEPS || HAS_Y_MICROSTEPS || HAS_Z_MICROSTEPS || HAS_E0_MICROSTEPS || HAS_E1_MICROSTEPS || HAS_E2_MICROSTEPS || HAS_E3_MICROSTEPS || HAS_E4_MICROSTEPS) + #define HAS_STEPPER_RESET (PIN_EXISTS(STEPPER_RESET)) + #define HAS_DIGIPOTSS (PIN_EXISTS(DIGIPOTSS)) + #define HAS_MOTOR_CURRENT_PWM (PIN_EXISTS(MOTOR_CURRENT_PWM_XY) || PIN_EXISTS(MOTOR_CURRENT_PWM_Z) || PIN_EXISTS(MOTOR_CURRENT_PWM_E)) + + /** + * 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 + + /** + * Helper Macros for heaters and extruder fan + */ + #define WRITE_HEATER_0P(v) WRITE(HEATER_0_PIN, v) + #if HOTENDS > 1 || ENABLED(HEATERS_PARALLEL) + #define WRITE_HEATER_1(v) WRITE(HEATER_1_PIN, v) + #if HOTENDS > 2 + #define WRITE_HEATER_2(v) WRITE(HEATER_2_PIN, v) + #if HOTENDS > 3 + #define WRITE_HEATER_3(v) WRITE(HEATER_3_PIN, v) + #if HOTENDS > 4 + #define WRITE_HEATER_4(v) WRITE(HEATER_4_PIN, v) + #endif // HOTENDS > 4 + #endif // HOTENDS > 3 + #endif // HOTENDS > 2 + #endif // HOTENDS > 1 + #if ENABLED(HEATERS_PARALLEL) + #define WRITE_HEATER_0(v) { WRITE_HEATER_0P(v); WRITE_HEATER_1(v); } + #else + #define WRITE_HEATER_0(v) WRITE_HEATER_0P(v) + #endif + + /** + * Heated bed requires settings + */ + #if HAS_HEATER_BED + #ifndef MAX_BED_POWER + #define MAX_BED_POWER 255 + #endif + #ifndef HEATER_BED_INVERTING + #define HEATER_BED_INVERTING false + #endif + #define WRITE_HEATER_BED(v) WRITE(HEATER_BED_PIN, (v) ^ HEATER_BED_INVERTING) + #endif + + /** + * Up to 3 PWM fans + */ + #if HAS_FAN2 + #define FAN_COUNT 3 + #elif HAS_FAN1 + #define FAN_COUNT 2 + #elif HAS_FAN0 + #define FAN_COUNT 1 + #else + #define FAN_COUNT 0 + #endif + + #if HAS_FAN0 + #define WRITE_FAN(v) WRITE(FAN_PIN, v) + #define WRITE_FAN0(v) WRITE_FAN(v) + #endif + #if HAS_FAN1 + #define WRITE_FAN1(v) WRITE(FAN1_PIN, v) + #endif + #if HAS_FAN2 + #define WRITE_FAN2(v) WRITE(FAN2_PIN, v) + #endif + #define WRITE_FAN_N(n, v) WRITE_FAN##n(v) + + /** + * Part Cooling fan multipliexer + */ + #define HAS_FANMUX PIN_EXISTS(FANMUX0) + + /** + * Servos and probes + */ + + #if HAS_SERVOS + #ifndef Z_ENDSTOP_SERVO_NR + #define Z_ENDSTOP_SERVO_NR -1 + #endif + #endif + + #define PROBE_PIN_CONFIGURED (HAS_Z_MIN_PROBE_PIN || (HAS_Z_MIN && ENABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN))) + #define HAS_BED_PROBE (PROBE_SELECTED && PROBE_PIN_CONFIGURED && DISABLED(PROBE_MANUALLY)) + + #if ENABLED(Z_PROBE_ALLEN_KEY) + #define PROBE_IS_TRIGGERED_WHEN_STOWED_TEST + #endif + + /** + * Bed Probe dependencies + */ + #if HAS_BED_PROBE + #if ENABLED(ENDSTOPPULLUPS) && HAS_Z_MIN_PROBE_PIN + #define ENDSTOPPULLUP_ZMIN_PROBE + #endif + #ifndef Z_PROBE_OFFSET_RANGE_MIN + #define Z_PROBE_OFFSET_RANGE_MIN -20 + #endif + #ifndef Z_PROBE_OFFSET_RANGE_MAX + #define Z_PROBE_OFFSET_RANGE_MAX 20 + #endif + #ifndef XY_PROBE_SPEED + #ifdef HOMING_FEEDRATE_XY + #define XY_PROBE_SPEED HOMING_FEEDRATE_XY + #else + #define XY_PROBE_SPEED 4000 + #endif + #endif + #if Z_CLEARANCE_BETWEEN_PROBES > Z_CLEARANCE_DEPLOY_PROBE + #define _Z_CLEARANCE_DEPLOY_PROBE Z_CLEARANCE_BETWEEN_PROBES + #else + #define _Z_CLEARANCE_DEPLOY_PROBE Z_CLEARANCE_DEPLOY_PROBE + #endif + #else + #undef X_PROBE_OFFSET_FROM_EXTRUDER + #undef Y_PROBE_OFFSET_FROM_EXTRUDER + #undef Z_PROBE_OFFSET_FROM_EXTRUDER + #define X_PROBE_OFFSET_FROM_EXTRUDER 0 + #define Y_PROBE_OFFSET_FROM_EXTRUDER 0 + #define Z_PROBE_OFFSET_FROM_EXTRUDER 0 + #endif + + /** + * Heater & Fan Pausing + */ + #if FAN_COUNT == 0 + #undef PROBING_FANS_OFF + #endif + #define QUIET_PROBING (HAS_BED_PROBE && (ENABLED(PROBING_HEATERS_OFF) || ENABLED(PROBING_FANS_OFF) || DELAY_BEFORE_PROBING > 0)) + #define HEATER_IDLE_HANDLER (ENABLED(ADVANCED_PAUSE_FEATURE) || ENABLED(PROBING_HEATERS_OFF)) + + /** + * Delta radius/rod trimmers/angle trimmers + */ + #if ENABLED(DELTA) + #ifndef DELTA_CALIBRATION_RADIUS + #define DELTA_CALIBRATION_RADIUS DELTA_PRINTABLE_RADIUS - 10 + #endif + #ifndef DELTA_ENDSTOP_ADJ + #define DELTA_ENDSTOP_ADJ { 0, 0, 0 } + #endif + #ifndef DELTA_TOWER_ANGLE_TRIM + #define DELTA_TOWER_ANGLE_TRIM {0, 0, 0} + #endif + #ifndef DELTA_RADIUS_TRIM_TOWER + #define DELTA_RADIUS_TRIM_TOWER {0, 0, 0} + #endif + #ifndef DELTA_DIAGONAL_ROD_TRIM_TOWER + #define DELTA_DIAGONAL_ROD_TRIM_TOWER {0, 0, 0} + #endif + #endif + + /** + * Set granular options based on the specific type of leveling + */ + + #define UBL_DELTA (ENABLED(AUTO_BED_LEVELING_UBL) && (ENABLED(DELTA) || ENABLED(UBL_GRANULAR_SEGMENTATION_FOR_CARTESIAN))) + #define ABL_PLANAR (ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_3POINT)) + #define ABL_GRID (ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR)) + #define HAS_ABL (ABL_PLANAR || ABL_GRID || ENABLED(AUTO_BED_LEVELING_UBL)) + #define HAS_LEVELING (HAS_ABL || ENABLED(MESH_BED_LEVELING)) + #define PLANNER_LEVELING (ABL_PLANAR || ABL_GRID || ENABLED(MESH_BED_LEVELING) || UBL_DELTA) + #define HAS_PROBING_PROCEDURE (HAS_ABL || ENABLED(Z_MIN_PROBE_REPEATABILITY_TEST)) + #if HAS_PROBING_PROCEDURE + #define PROBE_BED_WIDTH abs(RIGHT_PROBE_BED_POSITION - (LEFT_PROBE_BED_POSITION)) + #define PROBE_BED_HEIGHT abs(BACK_PROBE_BED_POSITION - (FRONT_PROBE_BED_POSITION)) + #endif + + /** + * Buzzer/Speaker + */ + #if ENABLED(LCD_USE_I2C_BUZZER) + #ifndef LCD_FEEDBACK_FREQUENCY_HZ + #define LCD_FEEDBACK_FREQUENCY_HZ 1000 + #endif + #ifndef LCD_FEEDBACK_FREQUENCY_DURATION_MS + #define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 + #endif + #else + #ifndef LCD_FEEDBACK_FREQUENCY_HZ + #define LCD_FEEDBACK_FREQUENCY_HZ 5000 + #endif + #ifndef LCD_FEEDBACK_FREQUENCY_DURATION_MS + #define LCD_FEEDBACK_FREQUENCY_DURATION_MS 2 + #endif + #endif + + /** + * Z_HOMING_HEIGHT / Z_CLEARANCE_BETWEEN_PROBES + */ + #ifndef Z_HOMING_HEIGHT + #ifndef Z_CLEARANCE_BETWEEN_PROBES + #define Z_HOMING_HEIGHT 0 + #else + #define Z_HOMING_HEIGHT Z_CLEARANCE_BETWEEN_PROBES + #endif + #endif + #ifndef Z_CLEARANCE_BETWEEN_PROBES + #define Z_CLEARANCE_BETWEEN_PROBES Z_HOMING_HEIGHT + #endif + #if Z_CLEARANCE_BETWEEN_PROBES > Z_HOMING_HEIGHT + #define MANUAL_PROBE_HEIGHT Z_CLEARANCE_BETWEEN_PROBES + #else + #define MANUAL_PROBE_HEIGHT Z_HOMING_HEIGHT + #endif + + /** + * Bed Probing rectangular bounds + * These can be further constrained in code for Delta and SCARA + */ + #if ENABLED(DELTA) + #ifndef DELTA_PROBEABLE_RADIUS + #define DELTA_PROBEABLE_RADIUS DELTA_PRINTABLE_RADIUS + #endif + // Probing points may be verified at compile time within the radius + // using static_assert(HYPOT2(X2-X1,Y2-Y1)<=sq(DELTA_PRINTABLE_RADIUS),"bad probe point!") + // so that may be added to SanityCheck.h in the future. + #define MIN_PROBE_X (X_CENTER - (DELTA_PROBEABLE_RADIUS)) + #define MIN_PROBE_Y (Y_CENTER - (DELTA_PROBEABLE_RADIUS)) + #define MAX_PROBE_X (X_CENTER + DELTA_PROBEABLE_RADIUS) + #define MAX_PROBE_Y (Y_CENTER + DELTA_PROBEABLE_RADIUS) + #elif IS_SCARA + #define SCARA_PRINTABLE_RADIUS (SCARA_LINKAGE_1 + SCARA_LINKAGE_2) + #define MIN_PROBE_X (X_CENTER - (SCARA_PRINTABLE_RADIUS)) + #define MIN_PROBE_Y (Y_CENTER - (SCARA_PRINTABLE_RADIUS)) + #define MAX_PROBE_X (X_CENTER + SCARA_PRINTABLE_RADIUS) + #define MAX_PROBE_Y (Y_CENTER + SCARA_PRINTABLE_RADIUS) + #else + // Boundaries for Cartesian probing based on set limits + #if ENABLED(BED_CENTER_AT_0_0) + #define MIN_PROBE_X (max(X_PROBE_OFFSET_FROM_EXTRUDER, 0) - (X_BED_SIZE) / 2) + #define MIN_PROBE_Y (max(Y_PROBE_OFFSET_FROM_EXTRUDER, 0) - (Y_BED_SIZE) / 2) + #define MAX_PROBE_X (min(X_BED_SIZE + X_PROBE_OFFSET_FROM_EXTRUDER, X_BED_SIZE) - (X_BED_SIZE) / 2) + #define MAX_PROBE_Y (min(Y_BED_SIZE + Y_PROBE_OFFSET_FROM_EXTRUDER, Y_BED_SIZE) - (Y_BED_SIZE) / 2) + #else + #define MIN_PROBE_X (max(X_MIN_POS + X_PROBE_OFFSET_FROM_EXTRUDER, 0)) + #define MIN_PROBE_Y (max(Y_MIN_POS + Y_PROBE_OFFSET_FROM_EXTRUDER, 0)) + #define MAX_PROBE_X (min(X_MAX_POS + X_PROBE_OFFSET_FROM_EXTRUDER, X_BED_SIZE)) + #define MAX_PROBE_Y (min(Y_MAX_POS + Y_PROBE_OFFSET_FROM_EXTRUDER, Y_BED_SIZE)) + #endif + #endif + + // Stepper pulse duration, in cycles + #define STEP_PULSE_CYCLES ((MINIMUM_STEPPER_PULSE) * CYCLES_PER_MICROSECOND) + + #if ENABLED(SDCARD_SORT_ALPHA) + #define HAS_FOLDER_SORTING (FOLDER_SORTING || ENABLED(SDSORT_GCODE)) + #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) || ENABLED(DELTA)) + // Either offset yields extra calculations on all moves + #define HAS_WORKSPACE_OFFSET (HAS_POSITION_SHIFT || HAS_HOME_OFFSET) + // M206 doesn't apply to DELTA + #define HAS_M206_COMMAND (HAS_HOME_OFFSET && DISABLED(DELTA)) + + // LCD timeout to status screen default is 15s + #ifndef LCD_TIMEOUT_TO_STATUS + #define LCD_TIMEOUT_TO_STATUS 15000 + #endif + + /** + * DELTA_SEGMENT_MIN_LENGTH for UBL_DELTA + */ + #if UBL_DELTA + #ifndef DELTA_SEGMENT_MIN_LENGTH + #if IS_SCARA + #define DELTA_SEGMENT_MIN_LENGTH 0.25 // SCARA minimum segment size is 0.25mm + #elif ENABLED(DELTA) + #define DELTA_SEGMENT_MIN_LENGTH 0.10 // mm (still subject to DELTA_SEGMENTS_PER_SECOND) + #else // CARTESIAN + #define DELTA_SEGMENT_MIN_LENGTH 1.00 // mm (similar to G2/G3 arc segmentation) + #endif + #endif + #endif + + // Shorthand + #define GRID_MAX_POINTS ((GRID_MAX_POINTS_X) * (GRID_MAX_POINTS_Y)) + + // Add commands that need sub-codes to this list + #define USE_GCODE_SUBCODES ENABLED(G38_PROBE_TARGET) + + // MESH_BED_LEVELING overrides PROBE_MANUALLY + #if ENABLED(MESH_BED_LEVELING) + #undef PROBE_MANUALLY + #endif + + // Parking Extruder + #if ENABLED(PARKING_EXTRUDER) + #ifndef PARKING_EXTRUDER_GRAB_DISTANCE + #define PARKING_EXTRUDER_GRAB_DISTANCE 0 + #endif + #ifndef PARKING_EXTRUDER_SOLENOIDS_PINS_ACTIVE + #define PARKING_EXTRUDER_SOLENOIDS_PINS_ACTIVE HIGH + #endif + #endif + +#endif // CONDITIONALS_POST_H diff --git a/trunk/Arduino/Marlin_1.1.6/Configuration.h b/trunk/Arduino/Marlin_1.1.6/Configuration.h new file mode 100644 index 00000000..e53fb1c4 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/Configuration.h @@ -0,0 +1,1701 @@ +/** + * 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 . + * + */ + +/** + * Configuration.h + * + * Basic settings such as: + * + * - Type of electronics + * - Type of temperature sensor + * - Printer geometry + * - Endstop configuration + * - LCD controller + * - Extra features + * + * Advanced settings can be found in Configuration_adv.h + * + */ +#ifndef CONFIGURATION_H +#define CONFIGURATION_H +#define CONFIGURATION_H_VERSION 010100 + +//=========================================================================== +//============================= Getting Started ============================= +//=========================================================================== + +/** + * Here are some standard links for getting your machine calibrated: + * + * http://reprap.org/wiki/Calibration + * http://youtu.be/wAL9d7FgInk + * http://calculator.josefprusa.cz + * http://reprap.org/wiki/Triffid_Hunter%27s_Calibration_Guide + * http://www.thingiverse.com/thing:5573 + * https://sites.google.com/site/repraplogphase/calibration-of-your-reprap + * http://www.thingiverse.com/thing:298812 + */ + +//=========================================================================== +//============================= DELTA Printer =============================== +//=========================================================================== +// For a Delta printer start with one of the configuration files in the +// example_configurations/delta directory and customize for your machine. +// + +//=========================================================================== +//============================= SCARA Printer =============================== +//=========================================================================== +// For a SCARA printer start with the configuration files in +// example_configurations/SCARA and customize for your machine. +// + +// @section info + +// User-specified version info of this build to display in [Pronterface, etc] terminal window during +// startup. Implementation of an idea by Prof Braino to inform user that any changes made to this +// build by the user have been successfully uploaded into firmware. +#define STRING_CONFIG_H_AUTHOR "(none, default config)" // Who made the changes. +#define SHOW_BOOTSCREEN +#define STRING_SPLASH_LINE1 SHORT_BUILD_VERSION // will be shown during bootup in line 1 +#define STRING_SPLASH_LINE2 WEBSITE_URL // will be shown during bootup in line 2 + +// +// *** VENDORS PLEASE READ ***************************************************** +// +// Marlin now allow you to have a vendor boot image to be displayed on machine +// start. When SHOW_CUSTOM_BOOTSCREEN is defined Marlin will first show your +// custom boot image and then the default Marlin boot image is shown. +// +// We suggest for you to take advantage of this new feature and keep the Marlin +// boot image unmodified. For an example have a look at the bq Hephestos 2 +// example configuration folder. +// +//#define SHOW_CUSTOM_BOOTSCREEN +// @section machine + +/** + * Select which serial port on the board will be used for communication with the host. + * This allows the connection of wireless adapters (for instance) to non-default port pins. + * Serial port 0 is always used by the Arduino bootloader regardless of this setting. + * + * :[0, 1, 2, 3, 4, 5, 6, 7] + */ +#define SERIAL_PORT 0 + +/** + * This setting determines the communication speed of the printer. + * + * 250000 works in most cases, but you might try a lower speed if + * you commonly experience drop-outs during host printing. + * You may try up to 1000000 to speed up SD file transfer. + * + * :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000] + */ +#define BAUDRATE 115200 + +// Enable the Bluetooth serial interface on AT90USB devices +//#define BLUETOOTH + +// The following define selects which electronics board you have. +// Please choose the name from boards.h that matches your setup +#ifndef MOTHERBOARD + #define MOTHERBOARD BOARD_RAMPS_14_SF +#endif + +// Optional custom name for your RepStrap or other custom machine +// Displayed in the LCD "Ready" message +//#define CUSTOM_MACHINE_NAME "3D Printer" + +// Define this to set a unique identifier for this printer, (Used by some programs to differentiate between machines) +// You can use an online service to generate a random UUID. (eg http://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] +#define EXTRUDERS 1 + +// For Cyclops or any "multi-extruder" that shares a single nozzle. +//#define SINGLENOZZLE + +/** + * Průša MK2 Single Nozzle Multi-Material Multiplexer, and variants. + * + * This device allows one stepper driver on a control board to drive + * two to eight stepper motors, one at a time, in a manner suitable + * for extruders. + * + * This option only allows the multiplexer to switch on tool-change. + * Additional options to configure custom E moves are pending. + */ +//#define MK2_MULTIPLEXER +#if ENABLED(MK2_MULTIPLEXER) + // Override the default DIO selector pins here, if needed. + // Some pins files may provide defaults for these pins. + //#define E_MUX0_PIN 40 // Always Required + //#define E_MUX1_PIN 42 // Needed for 3 to 8 steppers + //#define E_MUX2_PIN 44 // Needed for 5 to 8 steppers +#endif + +// A dual extruder that uses a single stepper motor +//#define SWITCHING_EXTRUDER +#if ENABLED(SWITCHING_EXTRUDER) + #define SWITCHING_EXTRUDER_SERVO_NR 0 + #define SWITCHING_EXTRUDER_SERVO_ANGLES { 0, 90 } // Angles for E0, E1[, E2, E3] + #if EXTRUDERS > 3 + #define SWITCHING_EXTRUDER_E23_SERVO_NR 1 + #endif +#endif + +// A dual-nozzle that uses a servomotor to raise/lower one of the nozzles +//#define SWITCHING_NOZZLE +#if ENABLED(SWITCHING_NOZZLE) + #define SWITCHING_NOZZLE_SERVO_NR 0 + #define SWITCHING_NOZZLE_SERVO_ANGLES { 0, 90 } // Angles for E0, E1 + //#define HOTEND_OFFSET_Z { 0.0, 0.0 } +#endif + +/** + * Two separate X-carriages with extruders that connect to a moving part + * via a magnetic docking mechanism. Requires SOL1_PIN and SOL2_PIN. + */ +//#define PARKING_EXTRUDER +#if ENABLED(PARKING_EXTRUDER) + #define PARKING_EXTRUDER_SOLENOIDS_INVERT // If enabled, the solenoid is NOT magnetized with applied voltage + #define PARKING_EXTRUDER_SOLENOIDS_PINS_ACTIVE LOW // LOW or HIGH pin signal energizes the coil + #define PARKING_EXTRUDER_SOLENOIDS_DELAY 250 // Delay (ms) for magnetic field. No delay if 0 or not defined. + #define PARKING_EXTRUDER_PARKING_X { -78, 184 } // X positions for parking the extruders + #define PARKING_EXTRUDER_GRAB_DISTANCE 1 // mm to move beyond the parking point to grab the extruder + #define PARKING_EXTRUDER_SECURITY_RAISE 5 // Z-raise before parking + #define HOTEND_OFFSET_Z { 0.0, 1.3 } // Z-offsets of the two hotends. The first must be 0. +#endif + +/** + * "Mixing Extruder" + * - Adds a new code, M165, to set the current mix factors. + * - Extends the stepping routines to move multiple steppers in proportion to the mix. + * - Optional support for Repetier Firmware M163, M164, and virtual extruder. + * - This implementation supports only a single extruder. + * - Enable DIRECT_MIXING_IN_G1 for Pia Taubert's reference implementation + */ +//#define MIXING_EXTRUDER +#if ENABLED(MIXING_EXTRUDER) + #define MIXING_STEPPERS 2 // Number of steppers in your mixing extruder + #define MIXING_VIRTUAL_TOOLS 16 // Use the Virtual Tool method with M163 and M164 + //#define DIRECT_MIXING_IN_G1 // Allow ABCDHI mix factors in G1 movement commands +#endif + +// Offset of the extruders (uncomment if using more than one and relying on firmware to position when changing). +// The offset has to be X=0, Y=0 for the extruder 0 hotend (default extruder). +// For the other hotends it is their distance from the extruder 0 hotend. +//#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis +//#define HOTEND_OFFSET_Y {0.0, 5.00} // (in mm) for each extruder, offset of the hotend on the Y axis + +// @section machine + +/** + * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN + * + * 0 = No Power Switch + * 1 = ATX + * 2 = X-Box 360 203Watts (the blue wire connected to PS_ON and the red wire to VCC) + * + * :{ 0:'No power switch', 1:'ATX', 2:'X-Box 360' } + */ +#define POWER_SUPPLY 0 + +#if POWER_SUPPLY > 0 + // Enable this option to leave the PSU off at startup. + // Power to steppers and heaters will need to be turned on with M80. + //#define PS_DEFAULT_OFF +#endif + +// @section temperature + +//=========================================================================== +//============================= Thermal Settings ============================ +//=========================================================================== + +/** + * --NORMAL IS 4.7kohm PULLUP!-- 1kohm pullup can be used on hotend sensor, using correct resistor and table + * + * Temperature sensors available: + * + * -3 : thermocouple with MAX31855 (only for sensor 0) + * -2 : thermocouple with MAX6675 (only for sensor 0) + * -1 : thermocouple with AD595 + * 0 : not used + * 1 : 100k thermistor - best choice for EPCOS 100k (4.7k pullup) + * 2 : 200k thermistor - ATC Semitec 204GT-2 (4.7k pullup) + * 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 (Used in ParCan & J-Head) (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) + * 71 : 100k Honeywell thermistor 135-104LAF-J01 (4.7k pullup) + * 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) + * 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" + * 20 : the PT100 circuit found in the Ultimainboard V2.x + * 60 : 100k Maker's Tool Works Kapton Bed Thermistor beta=3950 + * 66 : 4.7M High Temperature thermistor from Dyze Design + * 70 : the 100K thermistor found in the bq Hephestos 2 + * 75 : 100k Generic Silicon Heat Pad with NTC 100K MGB18-104F39050L32 thermistor + * + * 1k ohm pullup tables - This is atypical, and requires changing out the 4.7k pullup for 1k. + * (but gives greater accuracy and more stable PID) + * 51 : 100k thermistor - EPCOS (1k pullup) + * 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 + * 1010 : Pt1000 with 1k pullup (non standard) + * 147 : Pt100 with 4k7 pullup + * 110 : Pt100 with 1k pullup (non standard) + * + * Use these for Testing or Development purposes. NEVER for production machine. + * 998 : Dummy Table that ALWAYS reads 25°C or the temperature defined below. + * 999 : Dummy Table that ALWAYS reads 100°C or the temperature defined below. + * + * :{ '0': "Not used", '1':"100k / 4.7k - EPCOS", '2':"200k / 4.7k - ATC Semitec 204GT-2", '3':"Mendel-parts / 4.7k", '4':"10k !! do not use for a hotend. Bad resolution at high temp. !!", '5':"100K / 4.7k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '6':"100k / 4.7k EPCOS - Not as accurate as Table 1", '7':"100k / 4.7k Honeywell 135-104LAG-J01", '8':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT", '9':"100k / 4.7k GE Sensing AL03006-58.2K-97-G1", '10':"100k / 4.7k RS 198-961", '11':"100k / 4.7k beta 3950 1%", '12':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT (calibrated for Makibox hot bed)", '13':"100k Hisens 3950 1% up to 300°C for hotend 'Simple ONE ' & hotend 'All In ONE'", '20':"PT100 (Ultimainboard V2.x)", '51':"100k / 1k - EPCOS", '52':"200k / 1k - ATC Semitec 204GT-2", '55':"100k / 1k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '60':"100k Maker's Tool Works Kapton Bed Thermistor beta=3950", '66':"Dyze Design 4.7M High Temperature thermistor", '70':"the 100K thermistor found in the bq Hephestos 2", '71':"100k / 4.7k Honeywell 135-104LAF-J01", '147':"Pt100 / 4.7k", '1047':"Pt1000 / 4.7k", '110':"Pt100 / 1k (non-standard)", '1010':"Pt1000 / 1k (non standard)", '-3':"Thermocouple + MAX31855 (only for sensor 0)", '-2':"Thermocouple + MAX6675 (only for sensor 0)", '-1':"Thermocouple + AD595",'998':"Dummy 1", '999':"Dummy 2" } + */ +#define TEMP_SENSOR_0 1 +#define TEMP_SENSOR_1 0 +#define TEMP_SENSOR_2 0 +#define TEMP_SENSOR_3 0 +#define TEMP_SENSOR_4 0 +#define TEMP_SENSOR_BED 0 + +// Dummy thermistor constant temperature readings, for use with 998 and 999 +#define DUMMY_THERMISTOR_998_VALUE 25 +#define DUMMY_THERMISTOR_999_VALUE 100 + +// 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 +#define MAX_REDUNDANT_TEMP_SENSOR_DIFF 10 + +// Extruder temperature must be close to target for this long before M109 returns success +#define TEMP_RESIDENCY_TIME 10 // (seconds) +#define TEMP_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// Bed temperature must be close to target for this long before M190 returns success +#define TEMP_BED_RESIDENCY_TIME 10 // (seconds) +#define TEMP_BED_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_BED_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// The minimal temperature defines the temperature below which the heater will not be enabled It is used +// to check that the wiring to the thermistor is not broken. +// Otherwise this would lead to the heater being powered on all the time. +#define HEATER_0_MINTEMP 5 +#define HEATER_1_MINTEMP 5 +#define HEATER_2_MINTEMP 5 +#define HEATER_3_MINTEMP 5 +#define HEATER_4_MINTEMP 5 +#define BED_MINTEMP 5 + +// When temperature exceeds max temp, your heater will be switched off. +// This feature exists to protect your hotend from overheating accidentally, but *NOT* from thermistor short/failure! +// You should use MINTEMP for thermistor short/failure protection. +#define HEATER_0_MAXTEMP 275 +#define HEATER_1_MAXTEMP 275 +#define HEATER_2_MAXTEMP 275 +#define HEATER_3_MAXTEMP 275 +#define HEATER_4_MAXTEMP 275 +#define BED_MAXTEMP 150 + +//=========================================================================== +//============================= PID Settings ================================ +//=========================================================================== +// PID Tuning Guide here: http://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 +#if ENABLED(PIDTEMP) + //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. + //#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. + #define K1 0.95 //smoothing factor within the PID + + // 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 + +#endif // PIDTEMP + +//=========================================================================== +//============================= PID > Bed Temperature Control =============== +//=========================================================================== +// Select PID or bang-bang with PIDTEMPBED. If bang-bang, BED_LIMIT_SWITCHING will enable hysteresis +// +// Uncomment this to enable PID on the bed. It uses the same frequency PWM as the extruder. +// If your PID_dT is the default, and correct for your hardware/configuration, that means 7.689Hz, +// which is fine for driving a square wave into a resistive load and does not significantly impact you FET heating. +// This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W heater. +// If your configuration is significantly different than this and you don't understand the issues involved, you probably +// shouldn't use bed PID until someone else verifies your hardware works. +// If this is enabled, find your own PID constants below. +//#define PIDTEMPBED + +//#define BED_LIMIT_SWITCHING + +// This sets the max power delivered to the bed, and replaces the HEATER_BED_DUTY_CYCLE_DIVIDER option. +// all forms of bed control obey this (PID, bang-bang, bang-bang with hysteresis) +// setting this to anything other than 255 enables a form of PWM to the bed just like HEATER_BED_DUTY_CYCLE_DIVIDER did, +// so you shouldn't use it unless you are OK with PWM on your bed. (see the comment on enabling PIDTEMPBED) +#define MAX_BED_POWER 255 // limits duty cycle to bed; 255=full current + +#if ENABLED(PIDTEMPBED) + + //#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) + #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 + +// @section extruder + +// This option prevents extrusion if the temperature is below EXTRUDE_MINTEMP. +// It also enables the M302 command to set the minimum extrusion temperature +// or to allow moving the extruder regardless of the hotend temperature. +// *** IT IS HIGHLY RECOMMENDED TO LEAVE THIS OPTION ENABLED! *** +#define PREVENT_COLD_EXTRUSION +#define EXTRUDE_MINTEMP 170 + +// This option prevents a single extrusion longer than EXTRUDE_MAXLENGTH. +// Note that for Bowden Extruders a too-small value here may prevent loading. +#define PREVENT_LENGTHY_EXTRUDE +#define EXTRUDE_MAXLENGTH 200 + +//=========================================================================== +//======================== Thermal Runaway Protection ======================= +//=========================================================================== + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * If you get "Thermal Runaway" or "Heating failed" errors the + * details can be tuned in Configuration_adv.h + */ + +#define THERMAL_PROTECTION_HOTENDS // Enable thermal protection for all extruders +#define THERMAL_PROTECTION_BED // Enable thermal protection for the heated bed + +//=========================================================================== +//============================= Mechanical Settings ========================= +//=========================================================================== + +// @section machine + +// Uncomment one of these options to enable CoreXY, CoreXZ, or CoreYZ kinematics +// either in the usual order or reversed +//#define COREXY +//#define COREXZ +//#define COREYZ +//#define COREYX +//#define COREZX +//#define COREZY + +//=========================================================================== +//============================== Endstop Settings =========================== +//=========================================================================== + +// @section homing + +// Specify here all the endstop connectors that are connected to any endstop or probe. +// Almost all printers will be using one per axis. Probes will use one or more of the +// extra connectors. Leave undefined any used for non-endstop and non-probe purposes. +#define USE_XMIN_PLUG +#define USE_YMIN_PLUG +#define USE_ZMIN_PLUG +//#define USE_XMAX_PLUG +//#define USE_YMAX_PLUG +//#define USE_ZMAX_PLUG + +// coarse Endstop Settings +#define ENDSTOPPULLUPS // Comment this out (using // at the start of the line) to disable the endstop pullup resistors + +#if DISABLED(ENDSTOPPULLUPS) + // fine endstop settings: Individual pullups. will be ignored if ENDSTOPPULLUPS is defined + //#define ENDSTOPPULLUP_XMAX + //#define ENDSTOPPULLUP_YMAX + //#define ENDSTOPPULLUP_ZMAX + //#define ENDSTOPPULLUP_XMIN + //#define ENDSTOPPULLUP_YMIN + //#define ENDSTOPPULLUP_ZMIN + //#define ENDSTOPPULLUP_ZMIN_PROBE +#endif + +// Mechanical endstop with COM to ground and NC to Signal uses "false" here (most common setup). +#define X_MIN_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Y_MIN_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MIN_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define X_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Y_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MIN_PROBE_ENDSTOP_INVERTING false // set to true to invert the logic of the probe. + +// Enable this feature if all enabled endstop pins are interrupt-capable. +// This will remove the need to poll the interrupt pins, saving many CPU cycles. +//#define ENDSTOP_INTERRUPTS_FEATURE + +//============================================================================= +//============================== Movement Settings ============================ +//============================================================================= +// @section motion + +/** + * Default Settings + * + * These settings can be reset by M502 + * + * Note that if EEPROM is enabled, saved values will override these. + */ + +/** + * With this option each E stepper can have its own factors for the + * following movement settings. If fewer factors are given than the + * total number of extruders, the last value applies to the rest. + */ +//#define DISTINCT_E_FACTORS + +/** + * Default Axis Steps Per Unit (steps/mm) + * Override with M92 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_AXIS_STEPS_PER_UNIT { 80, 80, 4000, 500 } + +/** + * Default Max Feed Rate (mm/s) + * Override with M203 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_FEEDRATE { 300, 300, 5, 25 } + +/** + * Default Max Acceleration (change/s) change = mm/s + * (Maximum start speed for accelerated moves) + * Override with M201 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_ACCELERATION { 3000, 3000, 100, 10000 } + +/** + * Default Acceleration (change/s) change = mm/s + * Override with M204 + * + * M204 P Acceleration + * M204 R Retract Acceleration + * M204 T Travel Acceleration + */ +#define DEFAULT_ACCELERATION 3000 // X, Y, Z and E acceleration for printing moves +#define DEFAULT_RETRACT_ACCELERATION 3000 // E acceleration for retracts +#define DEFAULT_TRAVEL_ACCELERATION 3000 // X, Y, Z acceleration for travel (non printing) moves + +/** + * Default Jerk (mm/s) + * Override with M205 X Y Z E + * + * "Jerk" specifies the minimum speed change that requires acceleration. + * When changing speed and direction, if the difference is less than the + * value set here, it may happen instantaneously. + */ +#define DEFAULT_XJERK 20.0 +#define DEFAULT_YJERK 20.0 +#define DEFAULT_ZJERK 0.4 +#define DEFAULT_EJERK 5.0 + +//=========================================================================== +//============================= Z Probe Options ============================= +//=========================================================================== +// @section probes + +// +// See http://marlinfw.org/configuration/probes.html +// + +/** + * Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + * + * Enable this option for a probe connected to the Z Min endstop pin. + */ +#define Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + +/** + * Z_MIN_PROBE_ENDSTOP + * + * Enable this option for a probe connected to any pin except Z-Min. + * (By default Marlin assumes the Z-Max endstop pin.) + * To use a custom Z Probe pin, set Z_MIN_PROBE_PIN below. + * + * - The simplest option is to use a free endstop connector. + * - Use 5V for powered (usually inductive) sensors. + * + * - RAMPS 1.3/1.4 boards may use the 5V, GND, and Aux4->D32 pin: + * - For simple switches connect... + * - normally-closed switches to GND and D32. + * - normally-open switches to 5V and D32. + * + * WARNING: Setting the wrong pin may have unexpected and potentially + * disastrous consequences. Use with caution and do your homework. + * + */ +//#define Z_MIN_PROBE_ENDSTOP + +/** + * Probe Type + * + * Allen Key Probes, Servo Probes, Z-Sled Probes, FIX_MOUNTED_PROBE, etc. + * Activate one of these to use Auto Bed Leveling below. + */ + +/** + * The "Manual Probe" provides a means to do "Auto" Bed Leveling without a probe. + * Use G29 repeatedly, adjusting the Z height at each point with movement commands + * or (with LCD_BED_LEVELING) the LCD controller. + */ +//#define PROBE_MANUALLY + +/** + * A Fix-Mounted Probe either doesn't deploy or needs manual deployment. + * (e.g., an inductive probe or a nozzle-based probe-switch.) + */ +//#define FIX_MOUNTED_PROBE + +/** + * Z Servo Probe, such as an endstop switch on a rotating arm. + */ +//#define Z_ENDSTOP_SERVO_NR 0 // Defaults to SERVO 0 connector. +//#define Z_SERVO_ANGLES {70,0} // Z Servo Deploy and Stow angles + +/** + * The BLTouch probe uses a Hall effect sensor and emulates a servo. + */ +//#define BLTOUCH +#if ENABLED(BLTOUCH) + //#define BLTOUCH_DELAY 375 // (ms) Enable and increase if needed +#endif + +/** + * Enable one or more of the following if probing seems unreliable. + * Heaters and/or fans can be disabled during probing to minimize electrical + * noise. A delay can also be added to allow noise and vibration to settle. + * These options are most useful for the BLTouch probe, but may also improve + * readings with inductive probes and piezo sensors. + */ +//#define PROBING_HEATERS_OFF // Turn heaters off when probing +//#define PROBING_FANS_OFF // Turn fans off when probing +//#define DELAY_BEFORE_PROBING 200 // (ms) To prevent vibrations from triggering piezo sensors + +// A probe that is deployed and stowed with a solenoid pin (SOL1_PIN) +//#define SOLENOID_PROBE + +// A sled-mounted probe like those designed by Charles Bell. +//#define Z_PROBE_SLED +//#define SLED_DOCKING_OFFSET 5 // The extra distance the X axis must travel to pickup the sled. 0 should be fine but you can push it further if you'd like. + +// +// For Z_PROBE_ALLEN_KEY see the Delta example configurations. +// + +/** + * Z Probe to nozzle (X,Y) offset, relative to (0, 0). + * X and Y offsets must be integers. + * + * In the following example the X and Y offsets are both positive: + * #define X_PROBE_OFFSET_FROM_EXTRUDER 10 + * #define Y_PROBE_OFFSET_FROM_EXTRUDER 10 + * + * +-- BACK ---+ + * | | + * L | (+) P | R <-- probe (20,20) + * E | | I + * F | (-) N (+) | G <-- nozzle (10,10) + * T | | H + * | (-) | T + * | | + * O-- FRONT --+ + * (0,0) + */ +#define X_PROBE_OFFSET_FROM_EXTRUDER 10 // X offset: -left +right [of the nozzle] +#define Y_PROBE_OFFSET_FROM_EXTRUDER 10 // Y offset: -front +behind [the nozzle] +#define Z_PROBE_OFFSET_FROM_EXTRUDER 0 // Z offset: -below +above [the nozzle] + +// X and Y axis travel speed (mm/m) between probes +#define XY_PROBE_SPEED 8000 + +// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +#define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z + +// Speed for the "accurate" probe of each point +#define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) + +// Use double touch for probing +//#define PROBE_DOUBLE_TOUCH + +/** + * Z probes require clearance when deploying, stowing, and moving between + * probe points to avoid hitting the bed and other hardware. + * Servo-mounted probes require extra space for the arm to rotate. + * Inductive probes need space to keep from triggering early. + * + * Use these settings to specify the distance (mm) to raise the probe (or + * lower the bed). The values set here apply over and above any (negative) + * probe Z Offset set with Z_PROBE_OFFSET_FROM_EXTRUDER, M851, or the LCD. + * Only integer values >= 1 are valid here. + * + * Example: `M851 Z-5` with a CLEARANCE of 4 => 9mm from bed to nozzle. + * But: `M851 Z+1` with a CLEARANCE of 2 => 2mm from bed to nozzle. + */ +#define Z_CLEARANCE_DEPLOY_PROBE 10 // Z Clearance for Deploy/Stow +#define Z_CLEARANCE_BETWEEN_PROBES 5 // Z Clearance between probe points + +// For M851 give a range for adjusting the Z probe offset +#define Z_PROBE_OFFSET_RANGE_MIN -20 +#define Z_PROBE_OFFSET_RANGE_MAX 20 + +// Enable the M48 repeatability test to test probe accuracy +//#define Z_MIN_PROBE_REPEATABILITY_TEST + +// For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1 +// :{ 0:'Low', 1:'High' } +#define X_ENABLE_ON 0 +#define Y_ENABLE_ON 0 +#define Z_ENABLE_ON 0 +#define E_ENABLE_ON 0 // For all extruders + +// Disables axis stepper immediately when it's not being used. +// 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 +//#define DISABLE_REDUCED_ACCURACY_WARNING + +// @section extruder + +#define DISABLE_E false // For all extruders +#define DISABLE_INACTIVE_EXTRUDER true // Keep only the active extruder enabled. + +// @section machine + +// Invert the stepper direction. Change (or reverse the motor connector) if an axis goes the wrong way. +#define INVERT_X_DIR false +#define INVERT_Y_DIR true +#define INVERT_Z_DIR false + +// Enable this option for Toshiba stepper drivers +//#define CONFIG_STEPPERS_TOSHIBA + +// @section extruder + +// For direct drive extruder v9 set to true, for geared extruder set to false. +#define INVERT_E0_DIR false +#define INVERT_E1_DIR false +#define INVERT_E2_DIR false +#define INVERT_E3_DIR false +#define INVERT_E4_DIR false + +// @section homing + +//#define NO_MOTION_BEFORE_HOMING // Inhibit movement until all axes have been homed + +//#define Z_HOMING_HEIGHT 4 // (in mm) Minimal z height before homing (G28) for Z clearance above the bed, clamps, ... + // Be sure you have this distance over your Z_MAX_POS in case. + +// Direction of endstops when homing; 1=MAX, -1=MIN +// :[-1,1] +#define X_HOME_DIR -1 +#define Y_HOME_DIR -1 +#define Z_HOME_DIR -1 + +// @section machine + +// The size of the print bed +#define X_BED_SIZE 200 +#define Y_BED_SIZE 200 + +// Travel limits (mm) after homing, corresponding to endstop positions. +#define X_MIN_POS 0 +#define Y_MIN_POS 0 +#define Z_MIN_POS 0 +#define X_MAX_POS X_BED_SIZE +#define Y_MAX_POS Y_BED_SIZE +#define Z_MAX_POS 200 + +// If enabled, axes won't move below MIN_POS in response to movement commands. +#define MIN_SOFTWARE_ENDSTOPS +// If enabled, axes won't move above MAX_POS in response to movement commands. +#define MAX_SOFTWARE_ENDSTOPS + +/** + * Filament Runout Sensor + * A mechanical or opto endstop is used to check for the presence of filament. + * + * RAMPS-based boards use SERVO3_PIN. + * For other boards you may need to define FIL_RUNOUT_PIN. + * By default the firmware assumes HIGH = has filament, LOW = ran out + */ +//#define FILAMENT_RUNOUT_SENSOR +#if ENABLED(FILAMENT_RUNOUT_SENSOR) + #define FIL_RUNOUT_INVERTING false // set to true to invert the logic of the sensor. + #define ENDSTOPPULLUP_FIL_RUNOUT // Uncomment to use internal pullup for filament runout pins if the sensor is defined. + #define FILAMENT_RUNOUT_SCRIPT "M600" +#endif + +//=========================================================================== +//=============================== Bed Leveling ============================== +//=========================================================================== +// @section bedlevel + +/** + * Choose one of the options below to enable G29 Bed Leveling. The parameters + * and behavior of G29 will change depending on your selection. + * + * If using a Probe for Z Homing, enable Z_SAFE_HOMING also! + * + * - AUTO_BED_LEVELING_3POINT + * Probe 3 arbitrary points on the bed (that aren't collinear) + * You specify the XY coordinates of all 3 points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_LINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_BILINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a mesh, best for large or uneven beds. + * + * - AUTO_BED_LEVELING_UBL (Unified Bed Leveling) + * A comprehensive bed leveling system combining the features and benefits + * of other systems. UBL also includes integrated Mesh Generation, Mesh + * Validation and Mesh Editing systems. Currently, UBL is only checked out + * for Cartesian Printers. That said, it was primarily designed to correct + * poor quality Delta Printers. If you feel adventurous and have a Delta, + * please post an issue if something doesn't work correctly. Initially, + * you will need to set a reduced bed size so you have a rectangular area + * to test on. + * + * - MESH_BED_LEVELING + * Probe a grid manually + * The result is a mesh, suitable for large or uneven beds. (See BILINEAR.) + * For machines without a probe, Mesh Bed Leveling provides a method to perform + * leveling in steps so you can manually adjust the Z height at each grid-point. + * With an LCD controller the process is guided step-by-step. + */ +//#define AUTO_BED_LEVELING_3POINT +//#define AUTO_BED_LEVELING_LINEAR +//#define AUTO_BED_LEVELING_BILINEAR +//#define AUTO_BED_LEVELING_UBL +//#define MESH_BED_LEVELING + +/** + * Enable detailed logging of G28, G29, M48, etc. + * Turn on with the command 'M111 S32'. + * NOTE: Requires a lot of PROGMEM! + */ +//#define DEBUG_LEVELING_FEATURE + +#if ENABLED(MESH_BED_LEVELING) || ENABLED(AUTO_BED_LEVELING_BILINEAR) || ENABLED(AUTO_BED_LEVELING_UBL) + // Gradually reduce leveling correction until a set height is reached, + // at which point movement will be level to the machine's XY plane. + // The height can be set with M420 Z + #define ENABLE_LEVELING_FADE_HEIGHT +#endif + +#if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Set the number of grid points per dimension. + #define GRID_MAX_POINTS_X 3 + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + // Set the boundaries for probing (where the probe can reach). + #define LEFT_PROBE_BED_POSITION 15 + #define RIGHT_PROBE_BED_POSITION 170 + #define FRONT_PROBE_BED_POSITION 20 + #define BACK_PROBE_BED_POSITION 170 + + // The Z probe minimum outer margin (to validate G29 parameters). + #define MIN_PROBE_EDGE 10 + + // Probe along the Y axis, advancing X after each column + //#define PROBE_Y_FIRST + + #if ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Beyond the probed grid, continue the implied tilt? + // Default is to maintain the height of the nearest edge. + //#define EXTRAPOLATE_BEYOND_GRID + + // + // Experimental Subdivision of the grid by Catmull-Rom method. + // Synthesizes intermediate points to produce a more detailed mesh. + // + //#define ABL_BILINEAR_SUBDIVISION + #if ENABLED(ABL_BILINEAR_SUBDIVISION) + // Number of subdivisions between probe points + #define BILINEAR_SUBDIVISIONS 3 + #endif + + #endif + +#elif ENABLED(AUTO_BED_LEVELING_3POINT) + + // 3 arbitrary points to probe. + // A simple cross-product is used to estimate the plane of the bed. + #define ABL_PROBE_PT_1_X 15 + #define ABL_PROBE_PT_1_Y 180 + #define ABL_PROBE_PT_2_X 15 + #define ABL_PROBE_PT_2_Y 20 + #define ABL_PROBE_PT_3_X 170 + #define ABL_PROBE_PT_3_Y 20 + +#elif ENABLED(AUTO_BED_LEVELING_UBL) + + //=========================================================================== + //========================= Unified Bed Leveling ============================ + //=========================================================================== + + #define UBL_MESH_INSET 1 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 10 // Don't use more than 15 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + #define UBL_PROBE_PT_1_X 39 // Probing points for 3-Point leveling of the mesh + #define UBL_PROBE_PT_1_Y 180 + #define UBL_PROBE_PT_2_X 39 + #define UBL_PROBE_PT_2_Y 20 + #define UBL_PROBE_PT_3_X 180 + #define UBL_PROBE_PT_3_Y 20 + + //#define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation + #define UBL_MESH_EDIT_MOVES_Z // Sophisticated users prefer no movement of nozzle + +#elif ENABLED(MESH_BED_LEVELING) + + //=========================================================================== + //=================================== Mesh ================================== + //=========================================================================== + + #define MESH_INSET 10 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 3 // Don't use more than 7 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + //#define MESH_G28_REST_ORIGIN // After homing all axes ('G28' or 'G28 XYZ') rest Z at Z_MIN_POS + +#endif // BED_LEVELING + +/** + * Use the LCD controller for bed leveling + * Requires MESH_BED_LEVELING or PROBE_MANUALLY + */ +//#define LCD_BED_LEVELING + +#if ENABLED(LCD_BED_LEVELING) + #define MBL_Z_STEP 0.025 // Step size while manually probing Z axis. + #define LCD_PROBE_Z_RANGE 4 // Z Range centered on Z_MIN_POS for LCD Z adjustment +#endif + +// Add a menu item to move between bed corners for manual bed adjustment +//#define LEVEL_BED_CORNERS + +/** + * Commands to execute at the end of G29 probing. + * Useful to retract or move the Z probe out of the way. + */ +//#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) +//#define BED_CENTER_AT_0_0 + +// Manually set the home position. Leave these undefined for automatic settings. +// For DELTA this is the top-center of the Cartesian print volume. +//#define MANUAL_X_HOME_POS 0 +//#define MANUAL_Y_HOME_POS 0 +//#define MANUAL_Z_HOME_POS 0 + +// Use "Z Safe Homing" to avoid homing with a Z probe outside the bed area. +// +// With this feature enabled: +// +// - 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). +// - 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 axis (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). +#endif + +// Homing speeds (mm/m) +#define HOMING_FEEDRATE_XY (50*60) +#define HOMING_FEEDRATE_Z (4*60) + +//============================================================================= +//============================= Additional Features =========================== +//============================================================================= + +// @section extras + +// +// EEPROM +// +// The microcontroller can store settings in the EEPROM, e.g. max velocity... +// M500 - stores parameters in EEPROM +// M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily). +// M502 - reverts to the default "factory settings". You still need to store them in EEPROM afterwards if you want to. +// +#define EEPROM_SETTINGS // Enable for M500 and M501 commands +//#define DISABLE_M503 // Saves ~2700 bytes of PROGMEM. Disable for release! +#define EEPROM_CHITCHAT // Give feedback on EEPROM commands. Disable to save PROGMEM. + +// +// Host Keepalive +// +// When enabled Marlin will send a busy status message to the host +// every couple of seconds when it can't accept commands. +// +#define HOST_KEEPALIVE_FEATURE // Disable this if your host doesn't like keepalive messages +#define DEFAULT_KEEPALIVE_INTERVAL 2 // Number of seconds between "busy" messages. Set with M113. +#define BUSY_WHILE_HEATING // Some hosts require "busy" messages even during heating + +// +// M100 Free Memory Watcher +// +//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose + +// +// G20/G21 Inch mode support +// +//#define INCH_MODE_SUPPORT + +// +// M149 Set temperature units support +// +//#define TEMPERATURE_UNITS_SUPPORT + +// @section temperature + +// Preheat Constants +#define PREHEAT_1_TEMP_HOTEND 180 +#define PREHEAT_1_TEMP_BED 70 +#define PREHEAT_1_FAN_SPEED 0 // Value from 0 to 255 + +#define PREHEAT_2_TEMP_HOTEND 240 +#define PREHEAT_2_TEMP_BED 110 +#define PREHEAT_2_FAN_SPEED 0 // Value from 0 to 255 + +/** + * Nozzle Park -- EXPERIMENTAL + * + * Park the nozzle at the given XYZ position on idle or G27. + * + * The "P" parameter controls the action applied to the Z axis: + * + * P0 (Default) If Z is below park Z raise the nozzle. + * P1 Raise the nozzle always to Z-park height. + * P2 Raise the nozzle by Z-park amount, limited to Z_MAX_POS. + */ +//#define NOZZLE_PARK_FEATURE + +#if ENABLED(NOZZLE_PARK_FEATURE) + // Specify a park position as { X, Y, Z } + #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 } +#endif + +/** + * Clean Nozzle Feature -- EXPERIMENTAL + * + * Adds the G12 command to perform a nozzle cleaning process. + * + * Parameters: + * P Pattern + * S Strokes / Repetitions + * T Triangles (P1 only) + * + * Patterns: + * P0 Straight line (default). This process requires a sponge type material + * at a fixed bed location. "S" specifies strokes (i.e. back-forth motions) + * between the start / end points. + * + * P1 Zig-zag pattern between (X0, Y0) and (X1, Y1), "T" specifies the + * number of zig-zag triangles to do. "S" defines the number of strokes. + * Zig-zags are done in whichever is the narrower dimension. + * For example, "G12 P1 S1 T3" will execute: + * + * -- + * | (X0, Y1) | /\ /\ /\ | (X1, Y1) + * | | / \ / \ / \ | + * A | | / \ / \ / \ | + * | | / \ / \ / \ | + * | (X0, Y0) | / \/ \/ \ | (X1, Y0) + * -- +--------------------------------+ + * |________|_________|_________| + * T1 T2 T3 + * + * P2 Circular pattern with middle at NOZZLE_CLEAN_CIRCLE_MIDDLE. + * "R" specifies the radius. "S" specifies the stroke count. + * Before starting, the nozzle moves to NOZZLE_CLEAN_START_POINT. + * + * Caveats: The ending Z should be the same as starting Z. + * Attention: EXPERIMENTAL. G-code arguments may change. + * + */ +//#define NOZZLE_CLEAN_FEATURE + +#if ENABLED(NOZZLE_CLEAN_FEATURE) + // Default number of pattern repetitions + #define NOZZLE_CLEAN_STROKES 12 + + // Default number of triangles + #define NOZZLE_CLEAN_TRIANGLES 3 + + // Specify positions as { X, Y, Z } + #define NOZZLE_CLEAN_START_POINT { 30, 30, (Z_MIN_POS + 1)} + #define NOZZLE_CLEAN_END_POINT {100, 60, (Z_MIN_POS + 1)} + + // Circular pattern radius + #define NOZZLE_CLEAN_CIRCLE_RADIUS 6.5 + // Circular pattern circle fragments number + #define NOZZLE_CLEAN_CIRCLE_FN 10 + // Middle point of circle + #define NOZZLE_CLEAN_CIRCLE_MIDDLE NOZZLE_CLEAN_START_POINT + + // Moves the nozzle to the initial position + #define NOZZLE_CLEAN_GOBACK +#endif + +/** + * Print Job Timer + * + * Automatically start and stop the print job timer on M104/M109/M190. + * + * M104 (hotend, no wait) - high temp = none, low temp = stop timer + * M109 (hotend, wait) - high temp = start timer, low temp = stop timer + * M190 (bed, wait) - high temp = start timer, low temp = none + * + * The timer can also be controlled with the following commands: + * + * M75 - Start the print job timer + * M76 - Pause the print job timer + * M77 - Stop the print job timer + */ +#define PRINTJOB_TIMER_AUTOSTART + +/** + * Print Counter + * + * Track statistical data such as: + * + * - Total print jobs + * - Total successful print jobs + * - Total failed print jobs + * - Total time printing + * + * View the current statistics with M78. + */ +//#define PRINTCOUNTER + +//============================================================================= +//============================= LCD and SD support ============================ +//============================================================================= + +// @section lcd + +/** + * LCD LANGUAGE + * + * Select the language to display on the LCD. These languages are available: + * + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, + * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * tr, uk, zh_CN, zh_TW, test + * + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + */ +#define LCD_LANGUAGE en + +/** + * LCD Character Set + * + * Note: This option is NOT applicable to Graphical Displays. + * + * All character-based LCDs provide ASCII plus one of these + * language extensions: + * + * - JAPANESE ... the most common + * - WESTERN ... with more accented characters + * - CYRILLIC ... for the Russian language + * + * To determine the language extension installed on your controller: + * + * - Compile and upload with LCD_LANGUAGE set to 'test' + * - 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 + * + * :['JAPANESE', 'WESTERN', 'CYRILLIC'] + */ +//#define DISPLAY_CHARSET_HD44780 JAPANESE +#define DISPLAY_CHARSET_HD44780 WESTERN + +/** + * LCD TYPE + * + * Enable ULTRA_LCD for a 16x2, 16x4, 20x2, or 20x4 character-based LCD. + * Enable DOGLCD for a 128x64 (ST7565R) Full Graphical Display. + * (These options will be enabled automatically for most displays.) + * + * IMPORTANT: The U8glib library is required for Full Graphic Display! + * https://github.com/olikraus/U8glib_Arduino + */ +//#define ULTRA_LCD // Character based +//#define DOGLCD // Full graphics display + +/** + * SD CARD + * + * 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 + +/** + * SD CARD: SPI SPEED + * + * Enable one of the following items for a slower SPI transfer speed. + * This may be required to resolve "volume init" errors. + */ +#define SPI_SPEED SPI_HALF_SPEED +//#define SPI_SPEED SPI_QUARTER_SPEED +//#define SPI_SPEED SPI_EIGHTH_SPEED + +/** + * SD CARD: ENABLE CRC + * + * Use CRC checks and retries on the SD communication. + */ +//#define SD_CHECK_AND_RETRY + +// +// ENCODER SETTINGS +// +// This option overrides the default number of encoder pulses needed to +// produce one step. Should be increased for high-resolution encoders. +// +//#define ENCODER_PULSES_PER_STEP 1 + +// +// Use this option to override the number of step signals required to +// move between next/prev menu items. +// +//#define ENCODER_STEPS_PER_MENU_ITEM 5 + +/** + * Encoder Direction Options + * + * Test your encoder's behavior first with both options disabled. + * + * Reversed Value Edit and Menu Nav? Enable REVERSE_ENCODER_DIRECTION. + * Reversed Menu Navigation only? Enable REVERSE_MENU_DIRECTION. + * Reversed Value Editing only? Enable BOTH options. + */ + +// +// This option reverses the encoder direction everywhere. +// +// Set this option if CLOCKWISE causes values to DECREASE +// +//#define REVERSE_ENCODER_DIRECTION + +// +// This option reverses the encoder direction for navigating LCD menus. +// +// If CLOCKWISE normally moves DOWN this makes it go UP. +// If CLOCKWISE normally moves UP this makes it go DOWN. +// +//#define REVERSE_MENU_DIRECTION + +// +// Individual Axis Homing +// +// Add individual axis homing items (Home X, Home Y, and Home Z) to the LCD menu. +// +//#define INDIVIDUAL_AXIS_HOMING_MENU + +// +// SPEAKER/BUZZER +// +// If you have a speaker that can produce tones, enable it here. +// By default Marlin assumes you have a buzzer with a fixed frequency. +// +//#define SPEAKER + +// +// The duration and frequency for the UI feedback sound. +// Set these to 0 to disable audio feedback in the LCD menus. +// +// Note: Test audio output with the G-Code: +// M300 S P +// +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 +//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 + +// +// CONTROLLER TYPE: Standard +// +// Marlin supports a wide variety of controllers. +// Enable one of the following options to specify your controller. +// + +// +// ULTIMAKER Controller. +// +//#define ULTIMAKERCONTROLLER + +// +// ULTIPANEL as seen on Thingiverse. +// +//#define ULTIPANEL + +// +// PanelOne from T3P3 (via RAMPS 1.4 AUX2/AUX3) +// http://reprap.org/wiki/PanelOne +// +//#define PANEL_ONE + +// +// MaKr3d Makr-Panel with graphic controller and SD support. +// http://reprap.org/wiki/MaKr3d_MaKrPanel +// +//#define MAKRPANEL + +// +// ReprapWorld Graphical LCD +// https://reprapworld.com/?products_details&products_id/1218 +// +//#define REPRAPWORLD_GRAPHICAL_LCD + +// +// Activate one of these if you have a Panucatt Devices +// Viki 2.0 or mini Viki with Graphic LCD +// http://panucatt.com +// +//#define VIKI2 +//#define miniVIKI + +// +// Adafruit ST7565 Full Graphic Controller. +// https://github.com/eboston/Adafruit-ST7565-Full-Graphic-Controller/ +// +//#define ELB_FULL_GRAPHIC_CONTROLLER + +// +// RepRapDiscount Smart Controller. +// http://reprap.org/wiki/RepRapDiscount_Smart_Controller +// +// Note: Usually sold with a white PCB. +// +#define REPRAP_DISCOUNT_SMART_CONTROLLER + +// +// GADGETS3D G3D LCD/SD Controller +// http://reprap.org/wiki/RAMPS_1.3/1.4_GADGETS3D_Shield_with_Panel +// +// Note: Usually sold with a blue PCB. +// +//#define G3D_PANEL + +// +// RepRapDiscount FULL GRAPHIC Smart Controller +// http://reprap.org/wiki/RepRapDiscount_Full_Graphic_Smart_Controller +// +//#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER + +// +// MakerLab Mini Panel with graphic +// controller and SD support - http://reprap.org/wiki/Mini_panel +// +//#define MINIPANEL + +// +// RepRapWorld REPRAPWORLD_KEYPAD v1.1 +// http://reprapworld.com/?products_details&products_id=202&cPath=1591_1626 +// +// REPRAPWORLD_KEYPAD_MOVE_STEP sets how much should the robot move when a key +// is pressed, a value of 10.0 means 10mm per click. +// +//#define REPRAPWORLD_KEYPAD +//#define REPRAPWORLD_KEYPAD_MOVE_STEP 1.0 + +// +// RigidBot Panel V1.0 +// http://www.inventapart.com/ +// +//#define RIGIDBOT_PANEL + +// +// BQ LCD Smart Controller shipped by +// default with the BQ Hephestos 2 and Witbox 2. +// +//#define BQ_LCD_SMART_CONTROLLER + +// +// Cartesio UI +// http://mauk.cc/webshop/cartesio-shop/electronics/user-interface +// +//#define CARTESIO_UI + +// +// ANET_10 Controller supported displays. +// +//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. + // This LCD is known to be susceptible to electrical interference + // which scrambles the display. Pressing any button clears it up. +//#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 + // A clone of the RepRapDiscount full graphics display but with + // different pins/wiring (see pins_ANET_10.h). + +// +// LCD for Melzi Card with Graphical LCD +// +//#define LCD_FOR_MELZI + +// +// CONTROLLER TYPE: I2C +// +// Note: These controllers require the installation of Arduino's LiquidCrystal_I2C +// library. For more info: https://github.com/kiyoshigawa/LiquidCrystal_I2C +// + +// +// Elefu RA Board Control Panel +// http://www.elefu.com/index.php?route=product/product&product_id=53 +// +//#define RA_CONTROL_PANEL + +// +// Sainsmart YW Robot (LCM1602) LCD Display +// +// Note: This controller requires F.Malpartida's LiquidCrystal_I2C library +// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home +// +//#define LCD_I2C_SAINSMART_YWROBOT + +// +// Generic LCM1602 LCD adapter +// +//#define LCM1602 + +// +// PANELOLU2 LCD with status LEDs, +// separate encoder and click inputs. +// +// Note: This controller requires Arduino's LiquidTWI2 library v1.2.3 or later. +// For more info: https://github.com/lincomatic/LiquidTWI2 +// +// Note: The PANELOLU2 encoder click input can either be directly connected to +// a pin (if BTN_ENC defined to != -1) or read through I2C (when BTN_ENC == -1). +// +//#define LCD_I2C_PANELOLU2 + +// +// Panucatt VIKI LCD with status LEDs, +// integrated click & L/R/U/D buttons, separate encoder inputs. +// +//#define LCD_I2C_VIKI + +// +// SSD1306 OLED full graphics generic display +// +//#define U8GLIB_SSD1306 + +// +// SAV OLEd LCD module support using either SSD1306 or SH1106 based LCD modules +// +//#define SAV_3DGLCD +#if ENABLED(SAV_3DGLCD) + //#define U8GLIB_SSD1306 + #define U8GLIB_SH1106 +#endif + +// +// CONTROLLER TYPE: Shift register panels +// +// 2 wire Non-latching LCD SR from https://goo.gl/aJJ4sH +// LCD configuration: http://reprap.org/wiki/SAV_3D_LCD +// +//#define SAV_3DLCD + +// +// TinyBoy2 128x64 OLED / Encoder Panel +// +//#define OLED_PANEL_TINYBOY2 + +// +// Makeboard 3D Printer Parts 3D Printer Mini Display 1602 Mini Controller +// https://www.aliexpress.com/item/Micromake-Makeboard-3D-Printer-Parts-3D-Printer-Mini-Display-1602-Mini-Controller-Compatible-with-Ramps-1/32765887917.html +// +//#define MAKEBOARD_MINI_2_LINE_DISPLAY_1602 + +// +// MKS MINI12864 with graphic controller and SD support +// http://reprap.org/wiki/MKS_MINI_12864 +// +//#define MKS_MINI_12864 + +// +// Factory display for Creality CR-10 +// https://www.aliexpress.com/item/Universal-LCD-12864-3D-Printer-Display-Screen-With-Encoder-For-CR-10-CR-7-Model/32833148327.html +// +// This is RAMPS-compatible using a single 10-pin connector. +// (For CR-10 owners who want to replace the Melzi Creality board but retain the display) +// +//#define CR10_STOCKDISPLAY + +// +// MKS OLED 1.3" 128 × 64 FULL GRAPHICS CONTROLLER +// http://reprap.org/wiki/MKS_12864OLED +// +// Tiny, but very sharp OLED display +// +//#define MKS_12864OLED + +//============================================================================= +//=============================== Extra Features ============================== +//============================================================================= + +// @section extras + +// Increase the FAN PWM frequency. Removes the PWM noise but increases heating in the FET/Arduino +//#define FAST_PWM_FAN + +// Use software PWM to drive the fan, as for the heaters. This uses a very low frequency +// which is not as annoying as with the hardware PWM. On the other hand, if this frequency +// is too low, you should also increment SOFT_PWM_SCALE. +//#define FAN_SOFT_PWM + +// Incrementing this by 1 will double the software PWM frequency, +// affecting heaters, and the fan if FAN_SOFT_PWM is enabled. +// However, control resolution will be halved for each increment; +// at zero value, there are 128 effective control positions. +#define SOFT_PWM_SCALE 0 + +// If SOFT_PWM_SCALE is set to a value higher than 0, dithering can +// be used to mitigate the associated resolution loss. If enabled, +// some of the PWM cycles are stretched so on average the desired +// duty cycle is attained. +//#define SOFT_PWM_DITHER + +// Temperature status LEDs that display the hotend and bed temperature. +// If all hotends, bed temperature, and target temperature are under 54C +// then the BLUE led is on. Otherwise the RED led is on. (1C hysteresis) +//#define TEMP_STAT_LEDS + +// M240 Triggers a camera by emulating a Canon RC-1 Remote +// Data from: http://www.doc-diy.net/photo/rc-1_hacked/ +//#define PHOTOGRAPH_PIN 23 + +// 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 + +// Support for BlinkM/CyzRgb +//#define BLINKM + +// Support for PCA9632 PWM LED driver +//#define PCA9632 + +/** + * RGB LED / LED Strip Control + * + * Enable support for an RGB LED connected to 5V digital pins, or + * an RGB Strip connected to MOSFETs controlled by digital pins. + * + * 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 overall brightness parameters is also available + * + * *** CAUTION *** + * LED Strips require a MOFSET 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! + * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino + * cannot handle such current, separate 5V power supply must be used + * *** CAUTION *** + * + * LED type. This options are mutualy exclusive. Uncomment only one. + * + */ +//#define RGB_LED +//#define RGBW_LED + +#if ENABLED(RGB_LED) || ENABLED(RGBW_LED) + #define RGB_LED_R_PIN 34 + #define RGB_LED_G_PIN 43 + #define RGB_LED_B_PIN 35 + #define RGB_LED_W_PIN -1 +#endif + +// 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 (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) + #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip + #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time + #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + //#define NEOPIXEL_STARTUP_TEST // Cycle through colors at startup +#endif + +/** + * Printer Event LEDs + * + * During printing, the LEDs will reflect the printer status: + * + * - Gradually change from blue to violet as the heated bed gets to target temp + * - Gradually change from violet to red as the hotend gets to temperature + * - Change to white to illuminate work surface + * - Change to green once print has finished + * - Turn off after the print has finished and the user has pushed a button + */ +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_LED) + #define PRINTER_EVENT_LEDS +#endif + +/*********************************************************************\ +* R/C SERVO support +* Sponsored by TrinityLabs, Reworked by codexmas +**********************************************************************/ + +// Number of servos +// +// If you select a configuration below, this will receive a default value and does not need to be set manually +// set it manually if you have more servos than extruders and wish to manually control some +// leaving it undefined or defining as 0 will disable the servo subsystem +// If unsure, leave commented / disabled +// +//#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command + +// Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. +// 300ms is a good value but you can try less delay. +// If the servo can't reach the requested position, increase it. +#define SERVO_DELAY { 300 } + +// Servo deactivation +// +// With this option servos are powered only during movement, then turned off to prevent jitter. +//#define DEACTIVATE_SERVOS_AFTER_MOVE + +/** + * Filament Width Sensor + * + * Measures the filament width in real-time and adjusts + * flow rate to compensate for any irregularities. + * + * Also allows the measured filament diameter to set the + * extrusion rate, so the slicer only has to specify the + * volume. + * + * Only a single extruder is supported at this time. + * + * 34 RAMPS_14 : Analog input 5 on the AUX2 connector + * 81 PRINTRBOARD : Analog input 2 on the Exp1 connector (version B,C,D,E) + * 301 RAMBO : Analog input 3 + * + * Note: May require analog pins to be defined for other boards. + */ +//#define FILAMENT_WIDTH_SENSOR + +#define DEFAULT_NOMINAL_FILAMENT_DIA 3.00 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. + +#if ENABLED(FILAMENT_WIDTH_SENSOR) + #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) + #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber + + #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading + #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading + #define MAX_MEASUREMENT_DELAY 20 // (bytes) Buffer size for stored measurements (1 byte per cm). Must be larger than MEASUREMENT_DELAY_CM. + + #define DEFAULT_MEASURED_FILAMENT_DIA DEFAULT_NOMINAL_FILAMENT_DIA // Set measured to nominal initially + + // Display filament width on the LCD status line. Status messages will expire after 5 seconds. + //#define FILAMENT_LCD_DISPLAY +#endif + +#endif // CONFIGURATION_H diff --git a/trunk/Arduino/Marlin_1.1.6/Configuration_adv.h b/trunk/Arduino/Marlin_1.1.6/Configuration_adv.h new file mode 100644 index 00000000..3ed2a44b --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/Configuration_adv.h @@ -0,0 +1,1424 @@ +/** + * 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 . + * + */ + +/** + * Configuration_adv.h + * + * Advanced settings. + * Only change these if you know exactly what you're doing. + * Some of these settings can damage your printer if improperly set! + * + * Basic settings can be found in Configuration.h + * + */ +#ifndef CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H_VERSION 010100 + +// @section temperature + +//=========================================================================== +//=============================Thermal Settings ============================ +//=========================================================================== + +#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 + #endif +#endif + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * The solution: Once the temperature reaches the target, start observing. + * If the temperature stays too far below the target (hysteresis) for too long (period), + * the firmware will halt the machine as a safety precaution. + * + * If you get false positives for "Thermal Runaway" increase THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD + */ +#if ENABLED(THERMAL_PROTECTION_HOTENDS) + #define THERMAL_PROTECTION_PERIOD 40 // Seconds + #define THERMAL_PROTECTION_HYSTERESIS 4 // Degrees Celsius + + /** + * Whenever an M104 or M109 increases the target temperature the firmware will wait for the + * WATCH_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get false positives for "Heating failed" increase WATCH_TEMP_PERIOD and/or decrease WATCH_TEMP_INCREASE + * WATCH_TEMP_INCREASE should not be below 2. + */ + #define WATCH_TEMP_PERIOD 20 // Seconds + #define WATCH_TEMP_INCREASE 2 // Degrees Celsius +#endif + +/** + * Thermal Protection parameters for the bed are just as above for hotends. + */ +#if ENABLED(THERMAL_PROTECTION_BED) + #define THERMAL_PROTECTION_BED_PERIOD 20 // Seconds + #define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius + + /** + * Whenever an M140 or M190 increases the target temperature the firmware will wait for the + * WATCH_BED_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_BED_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get too many "Heating failed" errors, increase WATCH_BED_TEMP_PERIOD and/or decrease + * WATCH_BED_TEMP_INCREASE. (WATCH_BED_TEMP_INCREASE should not be below 2.) + */ + #define WATCH_BED_TEMP_PERIOD 60 // Seconds + #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius +#endif + +#if ENABLED(PIDTEMP) + // this adds an experimental additional term to the heating power, proportional to the extrusion speed. + // if Kc is chosen well, the additional required power due to increased melting should be compensated. + //#define PID_EXTRUSION_SCALING + #if ENABLED(PID_EXTRUSION_SCALING) + #define DEFAULT_Kc (100) //heating power=Kc*(e_speed) + #define LPQ_MAX_LEN 50 + #endif +#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 + */ +#define AUTOTEMP +#if ENABLED(AUTOTEMP) + #define AUTOTEMP_OLDWEIGHT 0.98 +#endif + +// Show Temperature ADC value +// Enable for M105 to include ADC values read from temperature sensors. +//#define SHOW_TEMP_ADC_VALUES + +/** + * High Temperature Thermistor Support + * + * Thermistors able to support high temperature tend to have a hard time getting + * good readings at room and lower temperatures. This means HEATER_X_RAW_LO_TEMP + * will probably be caught when the heating element first turns on during the + * preheating process, which will trigger a min_temp_error as a safety measure + * and force stop everything. + * To circumvent this limitation, we allow for a preheat time (during which, + * min_temp_error won't be triggered) and add a min_temp buffer to handle + * aberrant readings. + * + * If you want to enable this feature for your hotend thermistor(s) + * uncomment and set values > 0 in the constants below + */ + +// The number of consecutive low temperature errors that can occur +// before a min_temp_error is triggered. (Shouldn't be more than 10.) +//#define MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED 0 + +// The number of milliseconds a hotend will preheat before starting to check +// the temperature. This value should NOT be set to the time it takes the +// hot end to reach the target temperature, but the time it takes to reach +// the minimum temperature your thermistor can read. The lower the better/safer. +// This shouldn't need to be more than 30 seconds (30000) +//#define MILLISECONDS_PREHEAT_TIME 0 + +// @section extruder + +// Extruder runout prevention. +// If the machine is idle and the temperature over MINTEMP +// then extrude some filament every couple of SECONDS. +//#define EXTRUDER_RUNOUT_PREVENT +#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_EXTRUDE 5 // mm +#endif + +// @section temperature + +//These defines help to calibrate the AD595 sensor in case you get wrong temperature measurements. +//The measured temperature is defined as "actualTemp = (measuredTemp * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET" +#define TEMP_SENSOR_AD595_OFFSET 0.0 +#define TEMP_SENSOR_AD595_GAIN 1.0 + +/** + * 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. + */ +//#define USE_CONTROLLER_FAN +#if ENABLED(USE_CONTROLLER_FAN) + //#define CONTROLLER_FAN_PIN FAN1_PIN // 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 +#endif + +// When first starting the main fan, run it at full speed for the +// given number of milliseconds. This gets the fan spinning reliably +// before setting a PWM value. (Does not work with software PWM for fan on Sanguinololu) +//#define FAN_KICKSTART_TIME 100 + +// This defines the minimal speed for the main fan, run in PWM mode +// to enable uncomment and set minimal PWM speed for reliable running (1-255) +// if fan speed is [1 - (FAN_MIN_PWM-1)] it is set to FAN_MIN_PWM +//#define FAN_MIN_PWM 50 + +// @section extruder + +/** + * Extruder cooling fans + * + * Extruder auto fans automatically turn on when their extruders' + * temperatures go above EXTRUDER_AUTO_FAN_TEMPERATURE. + * + * Your board's pins file specifies the recommended pins. Override those here + * or set to -1 to disable completely. + * + * Multiple extruders can be assigned to the same pin in which case + * the fan will turn on when any selected extruder is above the threshold. + */ +#define E0_AUTO_FAN_PIN -1 +#define E1_AUTO_FAN_PIN -1 +#define E2_AUTO_FAN_PIN -1 +#define E3_AUTO_FAN_PIN -1 +#define E4_AUTO_FAN_PIN -1 +#define EXTRUDER_AUTO_FAN_TEMPERATURE 50 +#define EXTRUDER_AUTO_FAN_SPEED 255 // == full speed + +/** + * Part-Cooling Fan Multiplexer + * + * This feature allows you to digitally multiplex the fan output. + * The multiplexer is automatically switched at tool-change. + * Set FANMUX[012]_PINs below for up to 2, 4, or 8 multiplexed fans. + */ +#define FANMUX0_PIN -1 +#define FANMUX1_PIN -1 +#define FANMUX2_PIN -1 + +/** + * M355 Case Light on-off / brightness + */ +//#define CASE_LIGHT_ENABLE +#if ENABLED(CASE_LIGHT_ENABLE) + //#define CASE_LIGHT_PIN 4 // Override the default pin if needed + #define INVERT_CASE_LIGHT false // Set true if Case Light is ON when pin is LOW + #define CASE_LIGHT_DEFAULT_ON true // Set default power-up state on + #define CASE_LIGHT_DEFAULT_BRIGHTNESS 105 // Set default power-up brightness (0-255, requires PWM pin) + //#define MENU_ITEM_CASE_LIGHT // Add a Case Light option to the LCD main menu +#endif + +//=========================================================================== +//============================ Mechanical Settings ========================== +//=========================================================================== + +// @section homing + +// If you want endstops to stay on (by default) even when not homing +// enable this option. Override at any time with M120, M121. +//#define ENDSTOPS_ALWAYS_ON_DEFAULT + +// @section extras + +//#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. + +// Dual X Steppers +// Uncomment this option to drive two X axis motors. +// The next unused E driver will be assigned to the second X stepper. +//#define X_DUAL_STEPPER_DRIVERS +#if ENABLED(X_DUAL_STEPPER_DRIVERS) + // Set true if the two X motors need to rotate in opposite directions + #define INVERT_X2_VS_X_DIR true +#endif + +// Dual Y Steppers +// Uncomment this option to drive two Y axis motors. +// The next unused E driver will be assigned to the second Y stepper. +//#define Y_DUAL_STEPPER_DRIVERS +#if ENABLED(Y_DUAL_STEPPER_DRIVERS) + // Set true if the two Y motors need to rotate in opposite directions + #define INVERT_Y2_VS_Y_DIR true +#endif + +// A single Z stepper driver is usually used to drive 2 stepper motors. +// Uncomment this option to use a separate stepper driver for each Z axis motor. +// The next unused E driver will be assigned to the second Z stepper. +//#define Z_DUAL_STEPPER_DRIVERS + +#if ENABLED(Z_DUAL_STEPPER_DRIVERS) + + // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper. + // That way the machine is capable to align the bed during home, since both Z steppers are homed. + // There is also an implementation of M666 (software endstops adjustment) to this feature. + // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed. + // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2. + // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive. + // Play a little bit with small adjustments (0.5mm) and check the behaviour. + // The M119 (endstops report) will start reporting the Z2 Endstop as well. + + //#define Z_DUAL_ENDSTOPS + + #if ENABLED(Z_DUAL_ENDSTOPS) + #define Z2_USE_ENDSTOP _XMAX_ + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 // Use M666 to determine/test this value + #endif + +#endif // Z_DUAL_STEPPER_DRIVERS + +// Enable this for dual x-carriage printers. +// A dual x-carriage design has the advantage that the inactive extruder can be parked which +// prevents hot-end ooze contaminating the print. It also reduces the weight of each x-carriage +// allowing faster printing speeds. Connect your X2 stepper to the first unused E plug. +//#define DUAL_X_CARRIAGE +#if ENABLED(DUAL_X_CARRIAGE) + // Configuration for second X-carriage + // Note: the first x-carriage is defined as the x-carriage which homes to the minimum endstop; + // the second x-carriage always homes to the maximum endstop. + #define X2_MIN_POS 80 // set minimum to ensure second x-carriage doesn't hit the parked first X-carriage + #define X2_MAX_POS 353 // set maximum to the distance between toolheads when both heads are homed + #define X2_HOME_DIR 1 // the second X-carriage always homes to the maximum endstop position + #define X2_HOME_POS X2_MAX_POS // default home position is the maximum carriage position + // However: In this mode the HOTEND_OFFSET_X value for the second extruder provides a software + // override for X2_HOME_POS. This also allow recalibration of the distance between the two endstops + // without modifying the firmware (through the "M218 T1 X???" command). + // Remember: you should set the second extruder x-offset to 0 in your slicer. + + // There are a few selectable movement modes for dual x-carriages using M605 S + // Mode 0 (DXC_FULL_CONTROL_MODE): Full control. The slicer has full control over both x-carriages and can achieve optimal travel results + // as long as it supports dual x-carriages. (M605 S0) + // Mode 1 (DXC_AUTO_PARK_MODE) : Auto-park mode. The firmware will automatically park and unpark the x-carriages on tool changes so + // that additional slicer support is not required. (M605 S1) + // Mode 2 (DXC_DUPLICATION_MODE) : Duplication mode. The firmware will transparently make the second x-carriage and extruder copy all + // actions of the first x-carriage. This allows the printer to print 2 arbitrary items at + // once. (2nd extruder x offset and temp offset are set using: M605 S2 [Xnnn] [Rmmm]) + + // This is the default power-up mode which can be later using M605. + #define DEFAULT_DUAL_X_CARRIAGE_MODE DXC_FULL_CONTROL_MODE + + // Default settings in "Auto-park Mode" + #define TOOLCHANGE_PARK_ZLIFT 0.2 // the distance to raise Z axis when parking an extruder + #define TOOLCHANGE_UNPARK_ZLIFT 1 // the distance to raise Z axis when unparking an extruder + + // Default x offset in duplication mode (typically set to half print bed width) + #define DEFAULT_DUPLICATION_X_OFFSET 100 + +#endif // DUAL_X_CARRIAGE + +// 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. +//#define EXT_SOLENOID + +// @section homing + +//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +#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 this is defined, if both x and y are to be homed, a diagonal move will be performed initially. + +// When G28 is called, this option will make Y home before X +//#define HOME_Y_BEFORE_X + +// @section machine + +#define AXIS_RELATIVE_MODES {false, false, false, false} + +// Allow duplication mode with a basic dual-nozzle extruder +//#define DUAL_NOZZLE_DUPLICATION_MODE + +// By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step. +#define INVERT_X_STEP_PIN false +#define INVERT_Y_STEP_PIN false +#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. +#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_E true + +#define DEFAULT_MINIMUMFEEDRATE 0.0 // minimum feedrate +#define DEFAULT_MINTRAVELFEEDRATE 0.0 + +//#define HOME_AFTER_DEACTIVATE // Require rehoming after steppers are deactivated + +// @section lcd + +#if ENABLED(ULTIPANEL) + #define MANUAL_FEEDRATE {50*60, 50*60, 4*60, 60} // Feedrates for manual moves along X, Y, Z, E from panel + #define ULTIPANEL_FEEDMULTIPLY // Comment to disable setting feedrate multiplier via encoder +#endif + +// @section extras + +// minimum time in microseconds that a movement needs to take if the buffer is emptied. +#define DEFAULT_MINSEGMENTTIME 20000 + +// If defined the movements slow down when the look ahead buffer is only half full +#define SLOWDOWN + +// Frequency limit +// See nophead's blog for more info +// Not working O +//#define XY_FREQUENCY_LIMIT 15 + +// 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 +// if unwanted behavior is observed on a user's machine when running at very slow speeds. +#define MINIMUM_PLANNER_SPEED 0.05 // (mm/sec) + +// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU. +#define MICROSTEP_MODES {16,16,16,16,16} // [1,2,4,8,16] + +/** + * @section stepper motor current + * + * Some boards have a means of setting the stepper motor current via firmware. + * + * The power on motor currents are set by: + * PWM_MOTOR_CURRENT - used by MINIRAMBO & ULTIMAIN_2 + * known compatible chips: A4982 + * DIGIPOT_MOTOR_CURRENT - used by BQ_ZUM_MEGA_3D, RAMBO & SCOOVO_X9H + * known compatible chips: AD5206 + * DAC_MOTOR_CURRENT_DEFAULT - used by PRINTRBOARD_REVF & RIGIDBOARD_V2 + * known compatible chips: MCP4728 + * DIGIPOT_I2C_MOTOR_CURRENTS - used by 5DPRINT, AZTEEG_X3_PRO, MIGHTYBOARD_REVE + * known compatible chips: MCP4451, MCP4018 + * + * Motor currents can also be set by M907 - M910 and by the LCD. + * M907 - applies to all. + * M908 - BQ_ZUM_MEGA_3D, RAMBO, PRINTRBOARD_REVF, RIGIDBOARD_V2 & SCOOVO_X9H + * M909, M910 & LCD - only PRINTRBOARD_REVF & RIGIDBOARD_V2 + */ +//#define PWM_MOTOR_CURRENT { 1300, 1300, 1250 } // Values in milliamps +//#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 + +// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +//#define DIGIPOT_I2C +//#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster +#define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 +// Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS +#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=========================== +//=========================================================================== + +#define ENCODER_RATE_MULTIPLIER // If defined, certain menu edit operations automatically multiply the steps when the encoder is moved quickly +#define ENCODER_10X_STEPS_PER_SEC 75 // If the encoder steps per sec exceeds this value, multiply steps moved x10 to quickly advance the value +#define ENCODER_100X_STEPS_PER_SEC 160 // If the encoder steps per sec exceeds this value, multiply steps moved x100 to really quickly advance the value + +//#define CHDK 4 //Pin for triggering CHDK to take a picture see how to use it here http://captain-slow.dk/2014/03/09/3d-printing-timelapses/ +#define CHDK_DELAY 50 //How long in ms the pin should stay HIGH before going LOW again + +// @section lcd + +// Include a page of printer information in the LCD Main Menu +//#define LCD_INFO_MENU + +// Scroll a longer status message into view +//#define STATUS_MESSAGE_SCROLLING + +// On the Info Screen, display XY with one decimal place when possible +//#define LCD_DECIMAL_SMALL_XY + +// The timeout (in ms) to return to the status screen from sub-menus +//#define LCD_TIMEOUT_TO_STATUS 15000 + +#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 + + #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? + #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. + + #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. + // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. + // using: + //#define MENU_ADDAUTOSTART + + /** + * Sort SD file listings in alphabetical order. + * + * With this option enabled, items on SD cards will be sorted + * by name for easier navigation. + * + * By default... + * + * - Use the slowest -but safest- method for sorting. + * - Folders are sorted to the top. + * - The sort key is statically allocated. + * - No added G-code (M34) support. + * - 40 item sorting limit. (Items after the first 40 are unsorted.) + * + * SD sorting uses static allocation (as set by SDSORT_LIMIT), allowing the + * compiler to calculate the worst-case usage and throw an error if the SRAM + * limit is exceeded. + * + * - SDSORT_USES_RAM provides faster sorting via a static directory buffer. + * - SDSORT_USES_STACK does the same, but uses a local stack-based buffer. + * - SDSORT_CACHE_NAMES will retain the sorted file listing in RAM. (Expensive!) + * - SDSORT_DYNAMIC_RAM only uses RAM when the SD menu is visible. (Use with caution!) + */ + //#define SDCARD_SORT_ALPHA + + // SD Card Sorting options + #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_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. + #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #endif + + // Show a progress bar on HD44780 LCDs for SD printing + //#define LCD_PROGRESS_BAR + + #if ENABLED(LCD_PROGRESS_BAR) + // Amount of time (ms) to show the bar + #define PROGRESS_BAR_BAR_TIME 2000 + // Amount of time (ms) to show the status message + #define PROGRESS_BAR_MSG_TIME 3000 + // Amount of time (ms) to retain the status message (0=forever) + #define PROGRESS_MSG_EXPIRE 0 + // Enable this to show messages for MSG_TIME then hide them + //#define PROGRESS_MSG_ONCE + // Add a menu item to test the progress bar: + //#define LCD_PROGRESS_BAR_TEST + #endif + + // This allows hosts to request long names for files and folders with M33 + //#define LONG_FILENAME_HOST_SUPPORT + + // This option allows you to abort SD printing when any endstop is triggered. + // This feature must be enabled with "M540 S1" or from the LCD menu. + // To have any effect, endstops must be enabled during SD printing. + //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + +#endif // SDSUPPORT + +/** + * Additional options for Graphical Displays + * + * Use the optimizations here to improve printing performance, + * which can be adversely affected by graphical display drawing, + * especially when doing several short moves, and when printing + * on DELTA and SCARA machines. + * + * Some of these options may result in the display lagging behind + * controller events, as there is a trade-off between reliable + * printing performance versus fast display updates. + */ +#if ENABLED(DOGLCD) + // Enable to save many cycles by drawing a hollow frame on the Info Screen + #define XYZ_HOLLOW_FRAME + + // Enable to save many cycles by drawing a hollow frame on Menu Screens + #define MENU_HOLLOW_FRAME + + // A bigger font is available for edit items. Costs 3120 bytes of PROGMEM. + // 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. + // 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 +#endif // DOGLCD + +// @section safety + +// The hardware watchdog should reset the microcontroller disabling all outputs, +// in case the firmware gets stuck and doesn't do temperature regulation. +#define USE_WATCHDOG + +#if ENABLED(USE_WATCHDOG) + // If you have a watchdog reboot in an ArduinoMega2560 then the device will hang forever, as a watchdog reset will leave the watchdog on. + // The "WATCHDOG_RESET_MANUAL" goes around this by not using the hardware reset. + // However, THIS FEATURE IS UNSAFE!, as it will only work if interrupts are disabled. And the code could hang in an interrupt routine with interrupts disabled. + //#define WATCHDOG_RESET_MANUAL +#endif + +// @section lcd + +/** + * Babystepping enables movement of the axes by tiny increments without changing + * the current position values. This feature is used primarily to adjust the Z + * axis in the first layer of a print in real-time. + * + * Warning: Does not respect endstops! + */ +//#define BABYSTEPPING +#if ENABLED(BABYSTEPPING) + //#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 100 // Babysteps are very small. Increase for faster motion. + //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping + //#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen 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_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor + //#define BABYSTEP_ZPROBE_GFX_REVERSE // Reverses the direction of the CW/CCW indicators +#endif + +// @section extruder + +/** + * Implementation of linear pressure control + * + * Assumption: advance = k * (delta velocity) + * K=0 means advance disabled. + * See Marlin documentation for calibration instructions. + */ +//#define LIN_ADVANCE + +#if ENABLED(LIN_ADVANCE) + #define LIN_ADVANCE_K 75 + + /** + * Some Slicers produce Gcode with randomly jumping extrusion widths occasionally. + * For example within a 0.4mm perimeter it may produce a single segment of 0.05mm width. + * While this is harmless for normal printing (the fluid nature of the filament will + * close this very, very tiny gap), it throws off the LIN_ADVANCE pressure adaption. + * + * For this case LIN_ADVANCE_E_D_RATIO can be used to set the extrusion:distance ratio + * to a fixed value. Note that using a fixed ratio will lead to wrong nozzle pressures + * if the slicer is using variable widths or layer heights within one print! + * + * This option sets the default E:D ratio at startup. Use `M900` to override this value. + * + * Example: `M900 W0.4 H0.2 D1.75`, where: + * - W is the extrusion width in mm + * - H is the layer height in mm + * - D is the filament diameter in mm + * + * Example: `M900 R0.0458` to set the ratio directly. + * + * Set to 0 to auto-detect the ratio based on given Gcode G1 print moves. + * + * Slic3r (including Průša Control) produces Gcode compatible with the automatic mode. + * Cura (as of this writing) may produce Gcode incompatible with the automatic mode. + */ + #define LIN_ADVANCE_E_D_RATIO 0 // The calculated ratio (or 0) according to the formula W * H / ((D / 2) ^ 2 * PI) + // Example: 0.4 * 0.2 / ((1.75 / 2) ^ 2 * PI) = 0.033260135 +#endif + +// @section leveling + +// Default mesh area is an area with an inset margin on the print area. +// Below are the macros that are used to define the borders for the mesh area, +// made available here for specialized needs, ie dual extruder setup. +#if ENABLED(MESH_BED_LEVELING) + #define MESH_MIN_X MESH_INSET + #define MESH_MAX_X (X_BED_SIZE - (MESH_INSET)) + #define MESH_MIN_Y MESH_INSET + #define MESH_MAX_Y (Y_BED_SIZE - (MESH_INSET)) +#elif ENABLED(AUTO_BED_LEVELING_UBL) + #define UBL_MESH_MIN_X UBL_MESH_INSET + #define UBL_MESH_MAX_X (X_BED_SIZE - (UBL_MESH_INSET)) + #define UBL_MESH_MIN_Y UBL_MESH_INSET + #define UBL_MESH_MAX_Y (Y_BED_SIZE - (UBL_MESH_INSET)) + + // If this is defined, the currently active mesh will be saved in the + // current slot on M500. + #define UBL_SAVE_ACTIVE_ON_M500 +#endif + +// @section extras + +// +// G2/G3 Arc Support +// +#define ARC_SUPPORT // Disable this feature to save ~3226 bytes +#if ENABLED(ARC_SUPPORT) + #define MM_PER_ARC_SEGMENT 1 // Length of each arc segment + #define N_ARC_CORRECTION 25 // Number of intertpolated 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 +#endif + +// Support for G5 with XYZE destination and IJPQ offsets. Requires ~2666 bytes. +//#define BEZIER_CURVE_SUPPORT + +// G38.2 and G38.3 Probe Target +// Enable PROBE_DOUBLE_TOUCH if you want G38 to double touch +//#define G38_PROBE_TARGET +#if ENABLED(G38_PROBE_TARGET) + #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) +#endif + +// Moves (or segments) with fewer steps than this will be joined with the next move +#define MIN_STEPS_PER_SEGMENT 6 + +// The minimum pulse width (in µs) for stepping a stepper. +// Set this if you find stepping unreliable, or if using a very fast CPU. +#define MINIMUM_STEPPER_PULSE 0 // (µs) The smallest stepper pulse allowed + +// @section temperature + +// Control heater 0 and heater 1 in parallel. +//#define HEATERS_PARALLEL + +//=========================================================================== +//================================= Buffers ================================= +//=========================================================================== + +// @section hidden + +// 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, i.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 +#else + #define BLOCK_BUFFER_SIZE 16 // maximize block buffer +#endif + +// @section serial + +// The ASCII buffer for serial input +#define MAX_CMD_SIZE 96 +#define BUFSIZE 4 + +// Transmission to Host Buffer Size +// To save 386 bytes of PROGMEM (and TX_BUFFER_SIZE+3 bytes of RAM) set to 0. +// To buffer a simple "ok" you need 4 bytes. +// For ADVANCED_OK (M105) you need 32 bytes. +// For debug-echo: 128 bytes for the optimal speed. +// Other output doesn't need to be that speedy. +// :[0, 2, 4, 8, 16, 32, 64, 128, 256] +#define TX_BUFFER_SIZE 0 + +// Host Receive Buffer Size +// Without XON/XOFF flow control (see SERIAL_XON_XOFF below) 32 bytes should be enough. +// To use flow control, set this buffer size to at least 1024 bytes. +// :[0, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048] +//#define RX_BUFFER_SIZE 1024 + +#if RX_BUFFER_SIZE >= 1024 + // Enable to have the controller send XON/XOFF control characters to + // the host to signal the RX buffer is becoming full. + //#define SERIAL_XON_XOFF +#endif + +#if ENABLED(SDSUPPORT) + // Enable this option to collect and display the maximum + // RX queue usage after transferring a file to SD. + //#define SERIAL_STATS_MAX_RX_QUEUED + + // Enable this option to collect and display the number + // of dropped bytes after a file transfer to SD. + //#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! +//#define EMERGENCY_PARSER + +// Bad Serial-connections can miss a received command by sending an 'ok' +// Therefore some clients abort after 30 seconds in a timeout. +// Some other clients start sending commands while receiving a 'wait'. +// This "wait" is only sent when the buffer is empty. 1 second is a good value here. +//#define NO_TIMEOUTS 1000 // Milliseconds + +// Some clients will have this feature soon. This could make the NO_TIMEOUTS unnecessary. +//#define ADVANCED_OK + +// @section extras + +/** + * Firmware-based and LCD-controlled retract + * + * Add G10 / G11 commands for automatic firmware-based retract / recover. + * Use M207 and M208 to define parameters for retract / recover. + * + * Use M209 to enable or disable auto-retract. + * With auto-retract enabled, all G1 E moves within the set range + * will be converted to firmware-based retract/recover moves. + * + * Be sure to turn off auto-retract during filament change. + * + * Note that M207 / M208 / M209 settings are saved to EEPROM. + * + */ +//#define FWRETRACT // ONLY PARTIALLY TESTED +#if ENABLED(FWRETRACT) + #define MIN_AUTORETRACT 0.1 // When auto-retract is on, convert E moves of this length and over + #define MAX_AUTORETRACT 10.0 // Upper limit for auto-retract conversion + #define RETRACT_LENGTH 3 // Default retract length (positive mm) + #define RETRACT_LENGTH_SWAP 13 // Default swap retract length (positive mm), for extruder change + #define RETRACT_FEEDRATE 45 // Default feedrate for retracting (mm/s) + #define RETRACT_ZLIFT 0 // Default retract Z-lift + #define RETRACT_RECOVER_LENGTH 0 // Default additional recover length (mm, added to retract length when recovering) + #define RETRACT_RECOVER_LENGTH_SWAP 0 // Default additional swap recover length (mm, added to retract length when recovering from extruder change) + #define RETRACT_RECOVER_FEEDRATE 8 // Default feedrate for recovering from retraction (mm/s) + #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) +#endif + +/** + * Advanced Pause + * Experimental feature for filament change support and for parking the nozzle when paused. + * Adds the GCode M600 for initiating filament change. + * If PARK_HEAD_ON_PAUSE enabled, adds the GCode M125 to pause printing and park the nozzle. + * + * Requires an LCD display. + * This feature is required for the default FILAMENT_RUNOUT_SCRIPT. + */ +//#define ADVANCED_PAUSE_FEATURE +#if ENABLED(ADVANCED_PAUSE_FEATURE) + #define PAUSE_PARK_X_POS 3 // X position of hotend + #define PAUSE_PARK_Y_POS 3 // Y position of hotend + #define PAUSE_PARK_Z_ADD 10 // Z addition of hotend (lift) + #define PAUSE_PARK_XY_FEEDRATE 100 // X and Y axes feedrate in mm/s (also used for delta printers Z axis) + #define PAUSE_PARK_Z_FEEDRATE 5 // Z axis feedrate in mm/s (not used for delta printers) + #define PAUSE_PARK_RETRACT_FEEDRATE 60 // Initial retract feedrate in mm/s + #define PAUSE_PARK_RETRACT_LENGTH 2 // Initial retract in mm + // It is a short retract used immediately after print interrupt before move to filament exchange position + #define FILAMENT_CHANGE_UNLOAD_FEEDRATE 10 // Unload filament feedrate in mm/s - filament unloading can be fast + #define FILAMENT_CHANGE_UNLOAD_LENGTH 100 // Unload filament length from hotend in mm + // Longer length for bowden printers to unload filament from whole bowden tube, + // shorter length for printers without bowden to unload filament from extruder only, + // 0 to disable unloading for manual unloading + #define FILAMENT_CHANGE_LOAD_FEEDRATE 6 // Load filament feedrate in mm/s - filament loading into the bowden tube can be fast + #define FILAMENT_CHANGE_LOAD_LENGTH 0 // Load filament length over hotend in mm + // Longer length for bowden printers to fast load filament into whole bowden tube over the hotend, + // Short or zero length for printers without bowden where loading is not used + #define ADVANCED_PAUSE_EXTRUDE_FEEDRATE 3 // Extrude filament feedrate in mm/s - must be slower than load feedrate + #define ADVANCED_PAUSE_EXTRUDE_LENGTH 50 // Extrude filament length in mm after filament is loaded over the hotend, + // 0 to disable for manual extrusion + // Filament can be extruded repeatedly from the filament exchange menu to fill the hotend, + // or until outcoming filament color is not clear for filament color change + #define PAUSE_PARK_NOZZLE_TIMEOUT 45 // Turn off nozzle if user doesn't change filament within this time limit in seconds + #define FILAMENT_CHANGE_NUMBER_OF_ALERT_BEEPS 5 // Number of alert beeps before printer goes quiet + #define PAUSE_PARK_NO_STEPPER_TIMEOUT // Enable to have stepper motors hold position during filament change + // even if it takes longer than DEFAULT_STEPPER_DEACTIVE_TIME. + //#define PARK_HEAD_ON_PAUSE // Go to filament change position on pause, return to print position on resume + //#define HOME_BEFORE_FILAMENT_CHANGE // Ensure homing has been completed prior to parking for filament change +#endif + +// @section tmc + +/** + * Enable this section if you have TMC26X motor drivers. + * You will need to import the TMC26XStepper library into the Arduino IDE for this + * (https://github.com/trinamic/TMC26XStepper.git) + */ +//#define HAVE_TMCDRIVER + +#if ENABLED(HAVE_TMCDRIVER) + + //#define X_IS_TMC + //#define X2_IS_TMC + //#define Y_IS_TMC + //#define Y2_IS_TMC + //#define Z_IS_TMC + //#define Z2_IS_TMC + //#define E0_IS_TMC + //#define E1_IS_TMC + //#define E2_IS_TMC + //#define E3_IS_TMC + //#define E4_IS_TMC + + #define X_MAX_CURRENT 1000 // in mA + #define X_SENSE_RESISTOR 91 // in mOhms + #define X_MICROSTEPS 16 // number of microsteps + + #define X2_MAX_CURRENT 1000 + #define X2_SENSE_RESISTOR 91 + #define X2_MICROSTEPS 16 + + #define Y_MAX_CURRENT 1000 + #define Y_SENSE_RESISTOR 91 + #define Y_MICROSTEPS 16 + + #define Y2_MAX_CURRENT 1000 + #define Y2_SENSE_RESISTOR 91 + #define Y2_MICROSTEPS 16 + + #define Z_MAX_CURRENT 1000 + #define Z_SENSE_RESISTOR 91 + #define Z_MICROSTEPS 16 + + #define Z2_MAX_CURRENT 1000 + #define Z2_SENSE_RESISTOR 91 + #define Z2_MICROSTEPS 16 + + #define E0_MAX_CURRENT 1000 + #define E0_SENSE_RESISTOR 91 + #define E0_MICROSTEPS 16 + + #define E1_MAX_CURRENT 1000 + #define E1_SENSE_RESISTOR 91 + #define E1_MICROSTEPS 16 + + #define E2_MAX_CURRENT 1000 + #define E2_SENSE_RESISTOR 91 + #define E2_MICROSTEPS 16 + + #define E3_MAX_CURRENT 1000 + #define E3_SENSE_RESISTOR 91 + #define E3_MICROSTEPS 16 + + #define E4_MAX_CURRENT 1000 + #define E4_SENSE_RESISTOR 91 + #define E4_MICROSTEPS 16 + +#endif + +// @section TMC2130 + +/** + * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. + * + * You'll also need the TMC2130Stepper Arduino library + * (https://github.com/teemuatlut/TMC2130Stepper). + * + * To use TMC2130 stepper drivers in SPI mode connect your SPI2130 pins to + * the hardware SPI interface on your board and define the required CS pins + * in your `pins_MYBOARD.h` file. (e.g., RAMPS 1.4 uses AUX3 pins `X_CS_PIN 53`, `Y_CS_PIN 49`, etc.). + */ +//#define HAVE_TMC2130 + +#if ENABLED(HAVE_TMC2130) + + // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY + //#define X_IS_TMC2130 + //#define X2_IS_TMC2130 + //#define Y_IS_TMC2130 + //#define Y2_IS_TMC2130 + //#define Z_IS_TMC2130 + //#define Z2_IS_TMC2130 + //#define E0_IS_TMC2130 + //#define E1_IS_TMC2130 + //#define E2_IS_TMC2130 + //#define E3_IS_TMC2130 + //#define E4_IS_TMC2130 + + /** + * Stepper driver settings + */ + + #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 + #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current + #define INTERPOLATE 1 // Interpolate X/Y/Z_MICROSTEPS to 256 + + #define X_CURRENT 1000 // rms current in mA. Multiply by 1.41 for peak current. + #define X_MICROSTEPS 16 // 0..256 + + #define Y_CURRENT 1000 + #define Y_MICROSTEPS 16 + + #define Z_CURRENT 1000 + #define Z_MICROSTEPS 16 + + //#define X2_CURRENT 1000 + //#define X2_MICROSTEPS 16 + + //#define Y2_CURRENT 1000 + //#define Y2_MICROSTEPS 16 + + //#define Z2_CURRENT 1000 + //#define Z2_MICROSTEPS 16 + + //#define E0_CURRENT 1000 + //#define E0_MICROSTEPS 16 + + //#define E1_CURRENT 1000 + //#define E1_MICROSTEPS 16 + + //#define E2_CURRENT 1000 + //#define E2_MICROSTEPS 16 + + //#define E3_CURRENT 1000 + //#define E3_MICROSTEPS 16 + + //#define E4_CURRENT 1000 + //#define E4_MICROSTEPS 16 + + /** + * Use Trinamic's ultra quiet stepping mode. + * When disabled, Marlin will use spreadCycle stepping mode. + */ + #define STEALTHCHOP + + /** + * Let Marlin automatically control stepper current. + * This is still an experimental feature. + * Increase current every 5s by CURRENT_STEP until stepper temperature prewarn gets triggered, + * then decrease current by CURRENT_STEP until temperature prewarn is cleared. + * Adjusting starts from X/Y/Z/E_CURRENT but will not increase over AUTO_ADJUST_MAX + * 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. + * M906 S1 - Start adjusting current + * M906 S0 - Stop adjusting current + * M911 - Report stepper driver overtemperature pre-warn condition. + * M912 - Clear stepper driver overtemperature pre-warn condition flag. + */ + //#define AUTOMATIC_CURRENT_CONTROL + + #if ENABLED(AUTOMATIC_CURRENT_CONTROL) + #define CURRENT_STEP 50 // [mA] + #define AUTO_ADJUST_MAX 1300 // [mA], 1300mA_rms = 1840mA_peak + #define REPORT_CURRENT_CHANGE + #endif + + /** + * The driver will switch to spreadCycle when stepper speed is over HYBRID_THRESHOLD. + * This mode allows for faster movements at the expense of higher noise levels. + * STEALTHCHOP needs to be enabled. + * M913 X/Y/Z/E to live tune the setting + */ + //#define HYBRID_THRESHOLD + + #define X_HYBRID_THRESHOLD 100 // [mm/s] + #define X2_HYBRID_THRESHOLD 100 + #define Y_HYBRID_THRESHOLD 100 + #define Y2_HYBRID_THRESHOLD 100 + #define Z_HYBRID_THRESHOLD 4 + #define Z2_HYBRID_THRESHOLD 4 + #define E0_HYBRID_THRESHOLD 30 + #define E1_HYBRID_THRESHOLD 30 + #define E2_HYBRID_THRESHOLD 30 + #define E3_HYBRID_THRESHOLD 30 + #define E4_HYBRID_THRESHOLD 30 + + /** + * Use stallGuard2 to sense an obstacle and trigger an endstop. + * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. + * If used along with STEALTHCHOP, the movement will be louder when homing. This is normal. + * + * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. + * Higher values make the system LESS sensitive. + * Lower value make the system MORE sensitive. + * Too low values can lead to false positives, while too high values will collide the axis without triggering. + * It is advised to set X/Y_HOME_BUMP_MM to 0. + * M914 X/Y to live tune the setting + */ + //#define SENSORLESS_HOMING + + #if ENABLED(SENSORLESS_HOMING) + #define X_HOMING_SENSITIVITY 19 + #define Y_HOMING_SENSITIVITY 19 + #endif + + /** + * You can set your own advanced settings by filling in predefined functions. + * A list of available functions can be found on the library github page + * https://github.com/teemuatlut/TMC2130Stepper + * + * Example: + * #define TMC2130_ADV() { \ + * stepperX.diag0_temp_prewarn(1); \ + * stepperX.interpolate(0); \ + * } + */ + #define TMC2130_ADV() { } + +#endif // HAVE_TMC2130 + +// @section L6470 + +/** + * Enable this section if you have L6470 motor drivers. + * You need to import the L6470 library into the Arduino IDE for this. + * (https://github.com/ameyer/Arduino-L6470) + */ + +//#define HAVE_L6470DRIVER +#if ENABLED(HAVE_L6470DRIVER) + + //#define X_IS_L6470 + //#define X2_IS_L6470 + //#define Y_IS_L6470 + //#define Y2_IS_L6470 + //#define Z_IS_L6470 + //#define Z2_IS_L6470 + //#define E0_IS_L6470 + //#define E1_IS_L6470 + //#define E2_IS_L6470 + //#define E3_IS_L6470 + //#define E4_IS_L6470 + + #define X_MICROSTEPS 16 // number of microsteps + #define X_K_VAL 50 // 0 - 255, Higher values, are higher power. Be careful not to go too high + #define X_OVERCURRENT 2000 // maxc current in mA. If the current goes over this value, the driver will switch off + #define X_STALLCURRENT 1500 // current in mA where the driver will detect a stall + + #define X2_MICROSTEPS 16 + #define X2_K_VAL 50 + #define X2_OVERCURRENT 2000 + #define X2_STALLCURRENT 1500 + + #define Y_MICROSTEPS 16 + #define Y_K_VAL 50 + #define Y_OVERCURRENT 2000 + #define Y_STALLCURRENT 1500 + + #define Y2_MICROSTEPS 16 + #define Y2_K_VAL 50 + #define Y2_OVERCURRENT 2000 + #define Y2_STALLCURRENT 1500 + + #define Z_MICROSTEPS 16 + #define Z_K_VAL 50 + #define Z_OVERCURRENT 2000 + #define Z_STALLCURRENT 1500 + + #define Z2_MICROSTEPS 16 + #define Z2_K_VAL 50 + #define Z2_OVERCURRENT 2000 + #define Z2_STALLCURRENT 1500 + + #define E0_MICROSTEPS 16 + #define E0_K_VAL 50 + #define E0_OVERCURRENT 2000 + #define E0_STALLCURRENT 1500 + + #define E1_MICROSTEPS 16 + #define E1_K_VAL 50 + #define E1_OVERCURRENT 2000 + #define E1_STALLCURRENT 1500 + + #define E2_MICROSTEPS 16 + #define E2_K_VAL 50 + #define E2_OVERCURRENT 2000 + #define E2_STALLCURRENT 1500 + + #define E3_MICROSTEPS 16 + #define E3_K_VAL 50 + #define E3_OVERCURRENT 2000 + #define E3_STALLCURRENT 1500 + + #define E4_MICROSTEPS 16 + #define E4_K_VAL 50 + #define E4_OVERCURRENT 2000 + #define E4_STALLCURRENT 1500 + +#endif + +/** + * TWI/I2C BUS + * + * This feature is an EXPERIMENTAL feature so it shall not be used on production + * machines. Enabling this will allow you to send and receive I2C data from slave + * devices on the bus. + * + * ; Example #1 + * ; This macro send the string "Marlin" to the slave device with address 0x63 (99) + * ; It uses multiple M260 commands with one B arg + * M260 A99 ; Target slave address + * M260 B77 ; M + * M260 B97 ; a + * M260 B114 ; r + * M260 B108 ; l + * M260 B105 ; i + * M260 B110 ; n + * M260 S1 ; Send the current buffer + * + * ; Example #2 + * ; Request 6 bytes from slave device with address 0x63 (99) + * M261 A99 B5 + * + * ; Example #3 + * ; Example serial output of a M261 request + * echo:i2c-reply: from:99 bytes:5 data:hello + */ + +// @section i2cbus + +//#define EXPERIMENTAL_I2CBUS +#define I2C_SLAVE_ADDRESS 0 // Set a value from 8 to 127 to act as a slave + +// @section extras + +/** + * Spindle & Laser control + * + * Add the M3, M4, and M5 commands to turn the spindle/laser on and off, and + * to set spindle speed, spindle direction, and laser power. + * + * SuperPid is a router/spindle speed controller used in the CNC milling community. + * Marlin can be used to turn the spindle on and off. It can also be used to set + * the spindle speed from 5,000 to 30,000 RPM. + * + * 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. + */ +//#define SPINDLE_LASER_ENABLE +#if ENABLED(SPINDLE_LASER_ENABLE) + + #define SPINDLE_LASER_ENABLE_INVERT false // set to "true" if the on/off function is reversed + #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 // delay in milliseconds to allow the spindle/laser to come up to speed/power + #define SPINDLE_LASER_POWERDOWN_DELAY 5000 // delay in milliseconds to allow the spindle to stop + #define SPINDLE_DIR_CHANGE true // set to true if your spindle controller supports changing spindle direction + #define SPINDLE_INVERT_DIR false + #define SPINDLE_STOP_ON_DIR_CHANGE true // set to true if Marlin should stop the spindle before changing rotation direction + + /** + * The M3 & M4 commands use the following equation to convert PWM duty cycle to speed/power + * + * SPEED/POWER = PWM duty cycle * SPEED_POWER_SLOPE + SPEED_POWER_INTERCEPT + * where PWM duty cycle varies from 0 to 255 + * + * set the following for your controller (ALL MUST BE SET) + */ + + #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_SLOPE 0.3922 + //#define SPEED_POWER_INTERCEPT 0 + //#define SPEED_POWER_MIN 10 + //#define SPEED_POWER_MAX 100 // 0-100% +#endif + +/** + * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins + */ +//#define PINS_DEBUGGING + +/** + * Auto-report temperatures with M155 S + */ +#define AUTO_REPORT_TEMPERATURES + +/** + * Include capabilities in M115 output + */ +#define EXTENDED_CAPABILITIES_REPORT + +/** + * Volumetric extrusion default state + * 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. + */ +//#define VOLUMETRIC_DEFAULT_ON + +/** + * Enable this option for a leaner build of Marlin that removes all + * workspace offsets, simplifying coordinate transformations, leveling, etc. + * + * - M206 and M428 are disabled. + * - G92 will revert to its behavior from Marlin 1.0. + */ +//#define NO_WORKSPACE_OFFSETS + +/** + * 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. + * + * For clients that use a fixed-width font (like OctoPrint), leave this set to 1.0. + * Otherwise, adjust according to your client and font. + */ +#define PROPORTIONAL_FONT_RATIO 1.0 + +/** + * Spend 28 bytes of SRAM to optimize the GCode parser + */ +#define FASTER_GCODE_PARSER + +/** + * User-defined menu items that execute custom GCode + */ +//#define CUSTOM_USER_MENUS +#if ENABLED(CUSTOM_USER_MENUS) + #define USER_SCRIPT_DONE "M117 User Script Done" + #define USER_SCRIPT_AUDIBLE_FEEDBACK + //#define USER_SCRIPT_RETURN // Return to status screen after a script + + #define USER_DESC_1 "Home & UBL Info" + #define USER_GCODE_1 "G28\nG29 W" + + #define USER_DESC_2 "Preheat for PLA" + #define USER_GCODE_2 "M140 S" STRINGIFY(PREHEAT_1_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND) + + #define USER_DESC_3 "Preheat for ABS" + #define USER_GCODE_3 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND) + + #define USER_DESC_4 "Heat Bed/Home/Level" + #define USER_GCODE_4 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nG28\nG29" + + #define USER_DESC_5 "Home & Info" + #define USER_GCODE_5 "G28\nM503" +#endif + +/** + * Specify an action command to send to the host when the printer is killed. + * Will be sent in the form '//action:ACTION_ON_KILL', e.g. '//action:poweroff'. + * The host must be configured to handle the action command. + */ +//#define ACTION_ON_KILL "poweroff" + +//=========================================================================== +//====================== I2C Position Encoder Settings ====================== +//=========================================================================== + +/** + * I2C position encoders for closed loop control. + * Developed by Chris Barr at Aus3D. + * + * Wiki: http://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/ + * + * Reilabuild encoders have been modified to improve reliability. + */ + +//#define I2C_POSITION_ENCODERS +#if ENABLED(I2C_POSITION_ENCODERS) + + #define I2CPE_ENCODER_CNT 1 // The number of encoders installed; max of 5 + // encoders supported currently. + + #define I2CPE_ENC_1_ADDR I2CPE_PRESET_ADDR_X // I2C address of the encoder. 30-200. + #define I2CPE_ENC_1_AXIS X_AXIS // Axis the encoder module is installed on. _AXIS. + #define I2CPE_ENC_1_TYPE I2CPE_ENC_TYPE_LINEAR // Type of encoder: I2CPE_ENC_TYPE_LINEAR -or- + // I2CPE_ENC_TYPE_ROTARY. + #define I2CPE_ENC_1_TICKS_UNIT 2048 // 1024 for magnetic strips with 2mm poles; 2048 for + // 1mm poles. For linear encoders this is ticks / mm, + // for rotary encoders this is ticks / revolution. + //#define I2CPE_ENC_1_TICKS_REV (16 * 200) // Only needed for rotary encoders; number of stepper + // steps per full revolution (motor steps/rev * microstepping) + //#define I2CPE_ENC_1_INVERT // Invert the direction of axis travel. + #define I2CPE_ENC_1_EC_METHOD I2CPE_ECM_NONE // Type of error error correction. + #define I2CPE_ENC_1_EC_THRESH 0.10 // Threshold size for error (in mm) above which the + // printer will attempt to correct the error; errors + // smaller than this are ignored to minimize effects of + // measurement noise / latency (filter). + + #define I2CPE_ENC_2_ADDR I2CPE_PRESET_ADDR_Y // Same as above, but for encoder 2. + #define I2CPE_ENC_2_AXIS Y_AXIS + #define I2CPE_ENC_2_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_ENC_2_TICKS_UNIT 2048 + //#define I2CPE_ENC_2_TICKS_REV (16 * 200) + //#define I2CPE_ENC_2_INVERT + #define I2CPE_ENC_2_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_ENC_2_EC_THRESH 0.10 + + #define I2CPE_ENC_3_ADDR I2CPE_PRESET_ADDR_Z // Encoder 3. Add additional configuration options + #define I2CPE_ENC_3_AXIS Z_AXIS // as above, or use defaults below. + + #define I2CPE_ENC_4_ADDR I2CPE_PRESET_ADDR_E // Encoder 4. + #define I2CPE_ENC_4_AXIS E_AXIS + + #define I2CPE_ENC_5_ADDR 34 // Encoder 5. + #define I2CPE_ENC_5_AXIS E_AXIS + + // Default settings for encoders which are enabled, but without settings configured above. + #define I2CPE_DEF_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_DEF_ENC_TICKS_UNIT 2048 + #define I2CPE_DEF_TICKS_REV (16 * 200) + #define I2CPE_DEF_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_DEF_EC_THRESH 0.1 + + //#define I2CPE_ERR_THRESH_ABORT 100.0 // Threshold size for error (in mm) error on any given + // axis after which the printer will abort. Comment out to + // disable abort behaviour. + + #define I2CPE_TIME_TRUSTED 10000 // After an encoder fault, there must be no further fault + // for this amount of time (in ms) before the encoder + // is trusted again. + + /** + * Position is checked every time a new command is executed from the buffer but during long moves, + * this setting determines the minimum update time between checks. A value of 100 works well with + * error rolling average when attempting to correct only for skips and not for vibration. + */ + #define I2CPE_MIN_UPD_TIME_MS 100 // Minimum time in miliseconds between encoder checks. + + // Use a rolling average to identify persistant errors that indicate skips, as opposed to vibration and noise. + #define I2CPE_ERR_ROLLING_AVERAGE + +#endif // I2C_POSITION_ENCODERS + +/** + * MAX7219 Debug Matrix + * + * Add support for a low-cost 8x8 LED Matrix based on the Max7219 chip, which can be used as a status + * display. Requires 3 signal wires. Some useful debug options are included to demonstrate its usage. + * + * Fully assembled MAX7219 boards can be found on the internet for under $2(US). + * For example, see https://www.ebay.com/sch/i.html?_nkw=332349290049 + */ +//#define MAX7219_DEBUG +#if ENABLED(MAX7219_DEBUG) + #define MAX7219_CLK_PIN 64 // 77 on Re-ARM // Configuration of the 3 pins to control the display + #define MAX7219_DIN_PIN 57 // 78 on Re-ARM + #define MAX7219_LOAD_PIN 44 // 79 on Re-ARM + + /** + * Sample debug features + * If you add more debug displays, be careful to avoid conflicts! + */ + #define MAX7219_DEBUG_PRINTER_ALIVE // Blink corner LED of 8x8 matrix to show that the firmware is functioning + #define MAX7219_DEBUG_STEPPER_HEAD 3 // Show the stepper queue head position on this and the next LED matrix row + #define MAX7219_DEBUG_STEPPER_TAIL 5 // Show the stepper queue tail position on this and the next LED matrix row + + #define MAX7219_DEBUG_STEPPER_QUEUE 0 // Show the current stepper queue depth on this and the next LED matrix row + // If you experience stuttering, reboots, etc. this option can reveal how + // tweaks made to the configuration are affecting the printer in real-time. +#endif + +#endif // CONFIGURATION_ADV_H diff --git a/trunk/Arduino/Marlin_1.1.6/G26_Mesh_Validation_Tool.cpp b/trunk/Arduino/Marlin_1.1.6/G26_Mesh_Validation_Tool.cpp new file mode 100644 index 00000000..92c86b7f --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/G26_Mesh_Validation_Tool.cpp @@ -0,0 +1,887 @@ +/** + * 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 . + * + */ + +/** + * Marlin Firmware -- G26 - Mesh Validation Tool + */ + +#include "MarlinConfig.h" + +#if ENABLED(AUTO_BED_LEVELING_UBL) && ENABLED(UBL_G26_MESH_VALIDATION) + + #include "ubl.h" + #include "Marlin.h" + #include "planner.h" + #include "stepper.h" + #include "temperature.h" + #include "ultralcd.h" + #include "gcode.h" + + #define EXTRUSION_MULTIPLIER 1.0 + #define RETRACTION_MULTIPLIER 1.0 + #define NOZZLE 0.4 + #define FILAMENT 1.75 + #define LAYER_HEIGHT 0.2 + #define PRIME_LENGTH 10.0 + #define BED_TEMP 60.0 + #define HOTEND_TEMP 205.0 + #define OOZE_AMOUNT 0.3 + + #define SIZE_OF_INTERSECTION_CIRCLES 5 + #define SIZE_OF_CROSSHAIRS 3 + + #if SIZE_OF_CROSSHAIRS >= SIZE_OF_INTERSECTION_CIRCLES + #error "SIZE_OF_CROSSHAIRS must be less than SIZE_OF_INTERSECTION_CIRCLES." + #endif + + /** + * G26 Mesh Validation Tool + * + * G26 is a Mesh Validation Tool intended to provide support for the Marlin Unified Bed Leveling System. + * In order to fully utilize and benefit from the Marlin Unified Bed Leveling System an accurate Mesh must + * be defined. G29 is designed to allow the user to quickly validate the correctness of her Mesh. It will + * first heat the bed and nozzle. It will then print lines and circles along the Mesh Cell boundaries and + * the intersections of those lines (respectively). + * + * This action allows the user to immediately see where the Mesh is properly defined and where it needs to + * be edited. The command will generate the Mesh lines closest to the nozzle's starting position. Alternatively + * the user can specify the X and Y position of interest with command parameters. This allows the user to + * focus on a particular area of the Mesh where attention is needed. + * + * B # Bed Set the Bed Temperature. If not specified, a default of 60 C. will be assumed. + * + * C Current When searching for Mesh Intersection points to draw, use the current nozzle location + * as the base for any distance comparison. + * + * D Disable Disable the Unified Bed Leveling System. In the normal case the user is invoking this + * command to see how well a Mesh as been adjusted to match a print surface. In order to do + * this the Unified Bed Leveling System is turned on by the G26 command. The D parameter + * alters the command's normal behaviour and disables the Unified Bed Leveling System even if + * it is on. + * + * H # Hotend Set the Nozzle Temperature. If not specified, a default of 205 C. will be assumed. + * + * 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 + * of filament that is being extruded during the printing of the various lines on the bed. + * + * K Keep-On Keep the heaters turned on at the end of the command. + * + * L # Layer Layer height. (Height of nozzle above bed) If not specified .20mm will be used. + * + * O # Ooooze How much your nozzle will Ooooze filament while getting in position to print. This + * is over kill, but using this parameter will let you get the very first 'circle' perfect + * so you have a trophy to peel off of the bed and hang up to show how perfectly you have your + * Mesh calibrated. If not specified, a filament length of .3mm is assumed. + * + * P # Prime Prime the nozzle with specified length of filament. If this parameter is not + * given, no prime action will take place. If the parameter specifies an amount, that much + * will be purged before continuing. If no amount is specified the command will start + * purging filament until the user provides an LCD Click and then it will continue with + * printing the Mesh. You can carefully remove the spent filament with a needle nose + * pliers while holding the LCD Click wheel in a depressed state. If you do not have + * an LCD, you must specify a value if you use P. + * + * Q # Multiplier Retraction Multiplier. Normally not needed. Retraction defaults to 1.0mm and + * un-retraction is at 1.2mm These numbers will be scaled by the specified amount + * + * R # Repeat Prints the number of patterns given as a parameter, starting at the current location. + * If a parameter isn't given, every point will be printed unless G26 is interrupted. + * This works the same way that the UBL G29 P4 R parameter works. + * + * NOTE: If you do not have an LCD, you -must- specify R. This is to ensure that you are + * aware that there's some risk associated with printing without the ability to abort in + * cases where mesh point Z value may be inaccurate. As above, if you do not include a + * parameter, every point will be printed. + * + * S # Nozzle Used to control the size of nozzle diameter. If not specified, a .4mm nozzle is assumed. + * + * U # Random Randomize the order that the circles are drawn on the bed. The search for the closest + * undrawn cicle is still done. But the distance to the location for each circle has a + * random number of the size specified added to it. Specifying S50 will give an interesting + * deviation from the normal behaviour on a 10 x 10 Mesh. + * + * X # X Coord. Specify the starting location of the drawing activity. + * + * Y # Y Coord. Specify the starting location of the drawing activity. + */ + + // External references + + extern float feedrate_mm_s; // must set before calling prepare_move_to_destination + extern Planner planner; + #if ENABLED(ULTRA_LCD) + extern char lcd_status_message[]; + #endif + extern float destination[XYZE]; + void set_destination_to_current(); + void prepare_move_to_destination(); + inline void sync_plan_position_e() { planner.set_e_position_mm(current_position[E_AXIS]); } + inline void set_current_to_destination() { COPY(current_position, destination); } + #if ENABLED(NEWPANEL) + void lcd_setstatusPGM(const char* const message, const int8_t level); + void chirp_at_user(); + #endif + + // Private functions + + static uint16_t circle_flags[16], horizontal_mesh_line_flags[16], vertical_mesh_line_flags[16]; + float g26_e_axis_feedrate = 0.020, + 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. + + float valid_trig_angle(float); + + float unified_bed_leveling::g26_extrusion_multiplier, + unified_bed_leveling::g26_retraction_multiplier, + unified_bed_leveling::g26_nozzle, + unified_bed_leveling::g26_filament_diameter, + unified_bed_leveling::g26_layer_height, + unified_bed_leveling::g26_prime_length, + unified_bed_leveling::g26_x_pos, + unified_bed_leveling::g26_y_pos, + unified_bed_leveling::g26_ooze_amount; + + int16_t unified_bed_leveling::g26_bed_temp, + unified_bed_leveling::g26_hotend_temp; + + int8_t unified_bed_leveling::g26_prime_flag; + + bool unified_bed_leveling::g26_continue_with_closest, + unified_bed_leveling::g26_keep_heaters_on; + + int16_t unified_bed_leveling::g26_repeats; + + void unified_bed_leveling::G26_line_to_destination(const float &feed_rate) { + const float save_feedrate = feedrate_mm_s; + feedrate_mm_s = feed_rate; // use specified feed rate + prepare_move_to_destination(); // will ultimately call ubl.line_to_destination_cartesian or ubl.prepare_linear_move_to for UBL_DELTA + feedrate_mm_s = save_feedrate; // restore global feed rate + } + + #if ENABLED(NEWPANEL) + /** + * Detect ubl_lcd_clicked, debounce it, and return true for cancel + */ + bool user_canceled() { + if (!ubl_lcd_clicked()) return false; + safe_delay(10); // Wait for click to settle + + #if ENABLED(ULTRA_LCD) + lcd_setstatusPGM(PSTR("Mesh Validation Stopped."), 99); + lcd_quick_feedback(); + #endif + + while (!ubl_lcd_clicked()) idle(); // Wait for button release + + // If the button is suddenly pressed again, + // ask the user to resolve the issue + lcd_setstatusPGM(PSTR("Release button"), 99); // will never appear... + while (ubl_lcd_clicked()) idle(); // unless this loop happens + lcd_reset_status(); + + return true; + } + #endif + + /** + * G26: Mesh Validation Pattern generation. + * + * Used to interactively edit UBL's Mesh by placing the + * nozzle in a problem area and doing a G29 P4 R command. + */ + void unified_bed_leveling::G26() { + SERIAL_ECHOLNPGM("G26 command started. Waiting for heater(s)."); + float tmp, start_angle, end_angle; + int i, xi, yi; + mesh_index_pair location; + + // Don't allow Mesh Validation without homing first, + // or if the parameter parsing did not go OK, abort + if (axis_unhomed_error() || parse_G26_parameters()) return; + + if (current_position[Z_AXIS] < Z_CLEARANCE_BETWEEN_PROBES) { + do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES); + stepper.synchronize(); + set_current_to_destination(); + } + + if (turn_on_heaters()) goto LEAVE; + + current_position[E_AXIS] = 0.0; + sync_plan_position_e(); + + if (g26_prime_flag && prime_nozzle()) goto LEAVE; + + /** + * Bed is preheated + * + * Nozzle is at temperature + * + * Filament is primed! + * + * It's "Show Time" !!! + */ + + ZERO(circle_flags); + ZERO(horizontal_mesh_line_flags); + ZERO(vertical_mesh_line_flags); + + // Move nozzle to the specified height for the first layer + set_destination_to_current(); + destination[Z_AXIS] = g26_layer_height; + move_to(destination, 0.0); + move_to(destination, g26_ooze_amount); + + has_control_of_lcd_panel = true; + //debug_current_and_destination(PSTR("Starting G26 Mesh Validation Pattern.")); + + /** + * Declare and generate a sin() & cos() table to be used during the circle drawing. This will lighten + * the CPU load and make the arc drawing faster and more smooth + */ + float sin_table[360 / 30 + 1], cos_table[360 / 30 + 1]; + for (i = 0; i <= 360 / 30; i++) { + cos_table[i] = SIZE_OF_INTERSECTION_CIRCLES * cos(RADIANS(valid_trig_angle(i * 30.0))); + sin_table[i] = SIZE_OF_INTERSECTION_CIRCLES * sin(RADIANS(valid_trig_angle(i * 30.0))); + } + + do { + location = g26_continue_with_closest + ? find_closest_circle_to_print(current_position[X_AXIS], current_position[Y_AXIS]) + : find_closest_circle_to_print(g26_x_pos, g26_y_pos); // Find the closest Mesh Intersection to where we are now. + + if (location.x_index >= 0 && location.y_index >= 0) { + const float circle_x = mesh_index_to_xpos(location.x_index), + circle_y = mesh_index_to_ypos(location.y_index); + + // If this mesh location is outside the printable_radius, skip it. + + if (!position_is_reachable_raw_xy(circle_x, circle_y)) continue; + + xi = location.x_index; // Just to shrink the next few lines and make them easier to understand + yi = location.y_index; + + if (g26_debug_flag) { + SERIAL_ECHOPAIR(" Doing circle at: (xi=", xi); + SERIAL_ECHOPAIR(", yi=", yi); + SERIAL_CHAR(')'); + SERIAL_EOL(); + } + + start_angle = 0.0; // assume it is going to be a full circle + end_angle = 360.0; + if (xi == 0) { // Check for bottom edge + start_angle = -90.0; + end_angle = 90.0; + if (yi == 0) // it is an edge, check for the two left corners + start_angle = 0.0; + else if (yi == GRID_MAX_POINTS_Y - 1) + end_angle = 0.0; + } + else if (xi == GRID_MAX_POINTS_X - 1) { // Check for top edge + start_angle = 90.0; + end_angle = 270.0; + if (yi == 0) // it is an edge, check for the two right corners + end_angle = 180.0; + else if (yi == GRID_MAX_POINTS_Y - 1) + start_angle = 180.0; + } + else if (yi == 0) { + start_angle = 0.0; // only do the top side of the cirlce + end_angle = 180.0; + } + else if (yi == GRID_MAX_POINTS_Y - 1) { + start_angle = 180.0; // only do the bottom side of the cirlce + end_angle = 360.0; + } + + for (tmp = start_angle; tmp < end_angle - 0.1; tmp += 30.0) { + + #if ENABLED(NEWPANEL) + if (user_canceled()) goto LEAVE; // Check if the user wants to stop the Mesh Validation + #endif + + int tmp_div_30 = tmp / 30.0; + if (tmp_div_30 < 0) tmp_div_30 += 360 / 30; + if (tmp_div_30 > 11) tmp_div_30 -= 360 / 30; + + float x = circle_x + cos_table[tmp_div_30], // for speed, these are now a lookup table entry + y = circle_y + sin_table[tmp_div_30], + xe = circle_x + cos_table[tmp_div_30 + 1], + ye = circle_y + sin_table[tmp_div_30 + 1]; + #if IS_KINEMATIC + // Check to make sure this segment is entirely on the bed, skip if not. + if (!position_is_reachable_raw_xy(x, y) || !position_is_reachable_raw_xy(xe, ye)) continue; + #else // not, we need to skip + x = constrain(x, X_MIN_POS + 1, X_MAX_POS - 1); // This keeps us from bumping the endstops + y = constrain(y, Y_MIN_POS + 1, Y_MAX_POS - 1); + xe = constrain(xe, X_MIN_POS + 1, X_MAX_POS - 1); + ye = constrain(ye, Y_MIN_POS + 1, Y_MAX_POS - 1); + #endif + + //if (g26_debug_flag) { + // char ccc, *cptr, seg_msg[50], seg_num[10]; + // strcpy(seg_msg, " segment: "); + // strcpy(seg_num, " \n"); + // cptr = (char*) "01234567890ABCDEF????????"; + // ccc = cptr[tmp_div_30]; + // seg_num[1] = ccc; + // strcat(seg_msg, seg_num); + // debug_current_and_destination(seg_msg); + //} + + print_line_from_here_to_there(LOGICAL_X_POSITION(x), LOGICAL_Y_POSITION(y), g26_layer_height, LOGICAL_X_POSITION(xe), LOGICAL_Y_POSITION(ye), g26_layer_height); + + } + if (look_for_lines_to_connect()) + goto LEAVE; + } + } while (--g26_repeats && location.x_index >= 0 && location.y_index >= 0); + + LEAVE: + lcd_setstatusPGM(PSTR("Leaving G26"), -1); + + retract_filament(destination); + destination[Z_AXIS] = Z_CLEARANCE_BETWEEN_PROBES; + + //debug_current_and_destination(PSTR("ready to do Z-Raise.")); + move_to(destination, 0); // Raise the nozzle + //debug_current_and_destination(PSTR("done doing Z-Raise.")); + + destination[X_AXIS] = g26_x_pos; // Move back to the starting position + destination[Y_AXIS] = g26_y_pos; + //destination[Z_AXIS] = Z_CLEARANCE_BETWEEN_PROBES; // Keep the nozzle where it is + + move_to(destination, 0); // Move back to the starting position + //debug_current_and_destination(PSTR("done doing X/Y move.")); + + has_control_of_lcd_panel = false; // Give back control of the LCD Panel! + + if (!g26_keep_heaters_on) { + #if HAS_TEMP_BED + thermalManager.setTargetBed(0); + #endif + thermalManager.setTargetHotend(0, 0); + } + } + + float valid_trig_angle(float d) { + while (d > 360.0) d -= 360.0; + while (d < 0.0) d += 360.0; + return d; + } + + mesh_index_pair unified_bed_leveling::find_closest_circle_to_print(const float &X, const float &Y) { + float closest = 99999.99; + mesh_index_pair return_val; + + return_val.x_index = return_val.y_index = -1; + + for (uint8_t i = 0; i < GRID_MAX_POINTS_X; i++) { + for (uint8_t j = 0; j < GRID_MAX_POINTS_Y; j++) { + if (!is_bit_set(circle_flags, i, j)) { + const float mx = mesh_index_to_xpos(i), // We found a circle that needs to be printed + my = mesh_index_to_ypos(j); + + // Get the distance to this intersection + float f = HYPOT(X - mx, Y - my); + + // 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 += HYPOT(g26_x_pos - mx, g26_y_pos - my) / 15.0; + + // Add in the specified amount of Random Noise to our search + if (random_deviation > 1.0) + f += random(0.0, random_deviation); + + if (f < closest) { + closest = f; // We found a closer location that is still + return_val.x_index = i; // un-printed --- save the data for it + return_val.y_index = j; + return_val.distance = closest; + } + } + } + } + bit_set(circle_flags, return_val.x_index, return_val.y_index); // Mark this location as done. + return return_val; + } + + bool unified_bed_leveling::look_for_lines_to_connect() { + float sx, sy, ex, ey; + + for (uint8_t i = 0; i < GRID_MAX_POINTS_X; i++) { + for (uint8_t j = 0; j < GRID_MAX_POINTS_Y; j++) { + + #if ENABLED(NEWPANEL) + if (user_canceled()) return true; // Check if the user wants to stop the Mesh Validation + #endif + + if (i < GRID_MAX_POINTS_X) { // We can't connect to anything to the right than GRID_MAX_POINTS_X. + // This is already a half circle because we are at the edge of the bed. + + if (is_bit_set(circle_flags, i, j) && is_bit_set(circle_flags, i + 1, j)) { // check if we can do a line to the left + if (!is_bit_set(horizontal_mesh_line_flags, i, j)) { + + // + // We found two circles that need a horizontal line to connect them + // Print it! + // + sx = mesh_index_to_xpos( i ) + (SIZE_OF_INTERSECTION_CIRCLES - (SIZE_OF_CROSSHAIRS)); // right edge + ex = mesh_index_to_xpos(i + 1) - (SIZE_OF_INTERSECTION_CIRCLES - (SIZE_OF_CROSSHAIRS)); // left edge + + sx = constrain(sx, X_MIN_POS + 1, X_MAX_POS - 1); + sy = ey = constrain(mesh_index_to_ypos(j), Y_MIN_POS + 1, Y_MAX_POS - 1); + ex = constrain(ex, X_MIN_POS + 1, X_MAX_POS - 1); + + if (position_is_reachable_raw_xy(sx, sy) && position_is_reachable_raw_xy(ex, ey)) { + + if (g26_debug_flag) { + SERIAL_ECHOPAIR(" Connecting with horizontal line (sx=", sx); + SERIAL_ECHOPAIR(", sy=", sy); + SERIAL_ECHOPAIR(") -> (ex=", ex); + SERIAL_ECHOPAIR(", ey=", ey); + SERIAL_CHAR(')'); + SERIAL_EOL(); + //debug_current_and_destination(PSTR("Connecting horizontal line.")); + } + + print_line_from_here_to_there(LOGICAL_X_POSITION(sx), LOGICAL_Y_POSITION(sy), g26_layer_height, LOGICAL_X_POSITION(ex), LOGICAL_Y_POSITION(ey), g26_layer_height); + } + bit_set(horizontal_mesh_line_flags, i, j); // Mark it as done so we don't do it again, even if we skipped it + } + } + + if (j < GRID_MAX_POINTS_Y) { // We can't connect to anything further back than GRID_MAX_POINTS_Y. + // This is already a half circle because we are at the edge of the bed. + + if (is_bit_set(circle_flags, i, j) && is_bit_set(circle_flags, i, j + 1)) { // check if we can do a line straight down + if (!is_bit_set( vertical_mesh_line_flags, i, j)) { + // + // We found two circles that need a vertical line to connect them + // Print it! + // + sy = mesh_index_to_ypos( j ) + (SIZE_OF_INTERSECTION_CIRCLES - (SIZE_OF_CROSSHAIRS)); // top edge + ey = mesh_index_to_ypos(j + 1) - (SIZE_OF_INTERSECTION_CIRCLES - (SIZE_OF_CROSSHAIRS)); // bottom edge + + sx = ex = constrain(mesh_index_to_xpos(i), X_MIN_POS + 1, X_MAX_POS - 1); + sy = constrain(sy, Y_MIN_POS + 1, Y_MAX_POS - 1); + ey = constrain(ey, Y_MIN_POS + 1, Y_MAX_POS - 1); + + if (position_is_reachable_raw_xy(sx, sy) && position_is_reachable_raw_xy(ex, ey)) { + + if (g26_debug_flag) { + SERIAL_ECHOPAIR(" Connecting with vertical line (sx=", sx); + SERIAL_ECHOPAIR(", sy=", sy); + SERIAL_ECHOPAIR(") -> (ex=", ex); + SERIAL_ECHOPAIR(", ey=", ey); + SERIAL_CHAR(')'); + SERIAL_EOL(); + debug_current_and_destination(PSTR("Connecting vertical line.")); + } + print_line_from_here_to_there(LOGICAL_X_POSITION(sx), LOGICAL_Y_POSITION(sy), g26_layer_height, LOGICAL_X_POSITION(ex), LOGICAL_Y_POSITION(ey), g26_layer_height); + } + bit_set(vertical_mesh_line_flags, i, j); // Mark it as done so we don't do it again, even if skipped + } + } + } + } + } + } + return false; + } + + void unified_bed_leveling::move_to(const float &x, const float &y, const float &z, const float &e_delta) { + float feed_value; + static float last_z = -999.99; + + bool has_xy_component = (x != current_position[X_AXIS] || y != current_position[Y_AXIS]); // Check if X or Y is involved in the movement. + + if (z != last_z) { + last_z = z; + feed_value = planner.max_feedrate_mm_s[Z_AXIS]/(3.0); // Base the feed rate off of the configured Z_AXIS feed rate + + destination[X_AXIS] = current_position[X_AXIS]; + destination[Y_AXIS] = current_position[Y_AXIS]; + destination[Z_AXIS] = z; // We know the last_z==z or we wouldn't be in this block of code. + destination[E_AXIS] = current_position[E_AXIS]; + + G26_line_to_destination(feed_value); + + stepper.synchronize(); + set_destination_to_current(); + } + + // Check if X or Y is involved in the movement. + // Yes: a 'normal' movement. No: a retract() or recover() + feed_value = has_xy_component ? PLANNER_XY_FEEDRATE() / 10.0 : planner.max_feedrate_mm_s[E_AXIS] / 1.5; + + if (g26_debug_flag) SERIAL_ECHOLNPAIR("in move_to() feed_value for XY:", feed_value); + + destination[X_AXIS] = x; + destination[Y_AXIS] = y; + destination[E_AXIS] += e_delta; + + G26_line_to_destination(feed_value); + + stepper.synchronize(); + set_destination_to_current(); + + } + + void unified_bed_leveling::retract_filament(const float where[XYZE]) { + if (!g26_retracted) { // Only retract if we are not already retracted! + g26_retracted = true; + move_to(where, -1.0 * g26_retraction_multiplier); + } + } + + void unified_bed_leveling::recover_filament(const float where[XYZE]) { + if (g26_retracted) { // Only un-retract if we are retracted. + move_to(where, 1.2 * g26_retraction_multiplier); + g26_retracted = false; + } + } + + /** + * print_line_from_here_to_there() takes two cartesian coordinates and draws a line from one + * to the other. But there are really three sets of coordinates involved. The first coordinate + * is the present location of the nozzle. We don't necessarily want to print from this location. + * We first need to move the nozzle to the start of line segment where we want to print. Once + * there, we can use the two coordinates supplied to draw the line. + * + * Note: Although we assume the first set of coordinates is the start of the line and the second + * set of coordinates is the end of the line, it does not always work out that way. This function + * optimizes the movement to minimize the travel distance before it can start printing. This saves + * a lot of time and eliminates a lot of nonsensical movement of the nozzle. However, it does + * cause a lot of very little short retracement of th nozzle when it draws the very first line + * segment of a 'circle'. The time this requires is very short and is easily saved by the other + * cases where the optimization comes into play. + */ + void unified_bed_leveling::print_line_from_here_to_there(const float &sx, const float &sy, const float &sz, const float &ex, const float &ey, const float &ez) { + const float dx_s = current_position[X_AXIS] - sx, // find our distance from the start of the actual line segment + dy_s = current_position[Y_AXIS] - sy, + dist_start = HYPOT2(dx_s, dy_s), // We don't need to do a sqrt(), we can compare the distance^2 + // to save computation time + dx_e = current_position[X_AXIS] - ex, // find our distance from the end of the actual line segment + dy_e = current_position[Y_AXIS] - ey, + dist_end = HYPOT2(dx_e, dy_e), + + line_length = HYPOT(ex - sx, ey - sy); + + // If the end point of the line is closer to the nozzle, flip the direction, + // moving from the end to the start. On very small lines the optimization isn't worth it. + if (dist_end < dist_start && (SIZE_OF_INTERSECTION_CIRCLES) < FABS(line_length)) { + return print_line_from_here_to_there(ex, ey, ez, sx, sy, sz); + } + + // Decide whether to retract & bump + + if (dist_start > 2.0) { + retract_filament(destination); + //todo: parameterize the bump height with a define + move_to(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS] + 0.500, 0.0); // Z bump to minimize scraping + move_to(sx, sy, sz + 0.500, 0.0); // Get to the starting point with no extrusion while bumped + } + + move_to(sx, sy, sz, 0.0); // Get to the starting point with no extrusion / un-Z bump + + const float e_pos_delta = line_length * g26_e_axis_feedrate * g26_extrusion_multiplier; + + recover_filament(destination); + move_to(ex, ey, ez, e_pos_delta); // Get to the ending point with an appropriate amount of extrusion + } + + /** + * This function used to be inline code in G26. But there are so many + * parameters it made sense to turn them into static globals and get + * this code out of sight of the main routine. + */ + bool unified_bed_leveling::parse_G26_parameters() { + + g26_extrusion_multiplier = EXTRUSION_MULTIPLIER; + g26_retraction_multiplier = RETRACTION_MULTIPLIER; + g26_nozzle = NOZZLE; + g26_filament_diameter = FILAMENT; + g26_layer_height = LAYER_HEIGHT; + g26_prime_length = PRIME_LENGTH; + g26_bed_temp = BED_TEMP; + g26_hotend_temp = HOTEND_TEMP; + g26_prime_flag = 0; + + g26_ooze_amount = parser.linearval('O', OOZE_AMOUNT); + g26_keep_heaters_on = parser.boolval('K'); + g26_continue_with_closest = parser.boolval('C'); + + if (parser.seenval('B')) { + g26_bed_temp = parser.value_celsius(); + if (!WITHIN(g26_bed_temp, 15, 140)) { + SERIAL_PROTOCOLLNPGM("?Specified bed temperature not plausible."); + return UBL_ERR; + } + } + + if (parser.seenval('L')) { + g26_layer_height = parser.value_linear_units(); + if (!WITHIN(g26_layer_height, 0.0, 2.0)) { + SERIAL_PROTOCOLLNPGM("?Specified layer height not plausible."); + return UBL_ERR; + } + } + + if (parser.seen('Q')) { + if (parser.has_value()) { + g26_retraction_multiplier = parser.value_float(); + if (!WITHIN(g26_retraction_multiplier, 0.05, 15.0)) { + SERIAL_PROTOCOLLNPGM("?Specified Retraction Multiplier not plausible."); + return UBL_ERR; + } + } + else { + SERIAL_PROTOCOLLNPGM("?Retraction Multiplier must be specified."); + return UBL_ERR; + } + } + + if (parser.seenval('S')) { + g26_nozzle = parser.value_float(); + if (!WITHIN(g26_nozzle, 0.1, 1.0)) { + SERIAL_PROTOCOLLNPGM("?Specified nozzle size not plausible."); + return UBL_ERR; + } + } + + if (parser.seen('P')) { + if (!parser.has_value()) { + #if ENABLED(NEWPANEL) + g26_prime_flag = -1; + #else + SERIAL_PROTOCOLLNPGM("?Prime length must be specified when not using an LCD."); + return UBL_ERR; + #endif + } + else { + g26_prime_flag++; + g26_prime_length = parser.value_linear_units(); + if (!WITHIN(g26_prime_length, 0.0, 25.0)) { + SERIAL_PROTOCOLLNPGM("?Specified prime length not plausible."); + return UBL_ERR; + } + } + } + + if (parser.seenval('F')) { + g26_filament_diameter = parser.value_linear_units(); + if (!WITHIN(g26_filament_diameter, 1.0, 4.0)) { + SERIAL_PROTOCOLLNPGM("?Specified filament size not plausible."); + return UBL_ERR; + } + } + g26_extrusion_multiplier *= sq(1.75) / sq(g26_filament_diameter); // If we aren't using 1.75mm filament, we need to + // scale up or down the length needed to get the + // same volume of filament + + 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, 280)) { + SERIAL_PROTOCOLLNPGM("?Specified nozzle temperature not plausible."); + return UBL_ERR; + } + } + + if (parser.seen('U')) { + randomSeed(millis()); + // This setting will persist for the next G26 + random_deviation = parser.has_value() ? parser.value_float() : 50.0; + } + + #if ENABLED(NEWPANEL) + g26_repeats = parser.intval('R', GRID_MAX_POINTS + 1); + #else + if (!parser.seen('R')) { + SERIAL_PROTOCOLLNPGM("?(R)epeat must be specified when not using an LCD."); + return UBL_ERR; + } + else + g26_repeats = parser.has_value() ? parser.value_int() : GRID_MAX_POINTS + 1; + #endif + if (g26_repeats < 1) { + SERIAL_PROTOCOLLNPGM("?(R)epeat value not plausible; must be at least 1."); + return UBL_ERR; + } + + g26_x_pos = parser.linearval('X', current_position[X_AXIS]); + g26_y_pos = parser.linearval('Y', current_position[Y_AXIS]); + if (!position_is_reachable_xy(g26_x_pos, g26_y_pos)) { + SERIAL_PROTOCOLLNPGM("?Specified X,Y coordinate out of bounds."); + return UBL_ERR; + } + + /** + * Wait until all parameters are verified before altering the state! + */ + set_bed_leveling_enabled(!parser.seen('D')); + + return UBL_OK; + } + + #if ENABLED(NEWPANEL) + bool unified_bed_leveling::exit_from_g26() { + lcd_setstatusPGM(PSTR("Leaving G26"), -1); + while (ubl_lcd_clicked()) idle(); + return UBL_ERR; + } + #endif + + /** + * Turn on the bed and nozzle heat and + * wait for them to get up to temperature. + */ + bool unified_bed_leveling::turn_on_heaters() { + millis_t next = millis() + 5000UL; + #if HAS_TEMP_BED + #if ENABLED(ULTRA_LCD) + if (g26_bed_temp > 25) { + lcd_setstatusPGM(PSTR("G26 Heating Bed."), 99); + lcd_quick_feedback(); + #endif + has_control_of_lcd_panel = true; + thermalManager.setTargetBed(g26_bed_temp); + while (abs(thermalManager.degBed() - g26_bed_temp) > 3) { + + #if ENABLED(NEWPANEL) + if (ubl_lcd_clicked()) return exit_from_g26(); + #endif + + if (ELAPSED(millis(), next)) { + next = millis() + 5000UL; + print_heaterstates(); + SERIAL_EOL(); + } + idle(); + } + #if ENABLED(ULTRA_LCD) + } + lcd_setstatusPGM(PSTR("G26 Heating Nozzle."), 99); + lcd_quick_feedback(); + #endif + #endif + + // Start heating the nozzle and wait for it to reach temperature. + thermalManager.setTargetHotend(g26_hotend_temp, 0); + while (abs(thermalManager.degHotend(0) - g26_hotend_temp) > 3) { + + #if ENABLED(NEWPANEL) + if (ubl_lcd_clicked()) return exit_from_g26(); + #endif + + if (ELAPSED(millis(), next)) { + next = millis() + 5000UL; + print_heaterstates(); + SERIAL_EOL(); + } + idle(); + } + + #if ENABLED(ULTRA_LCD) + lcd_reset_status(); + lcd_quick_feedback(); + #endif + + return UBL_OK; + } + + /** + * Prime the nozzle if needed. Return true on error. + */ + bool unified_bed_leveling::prime_nozzle() { + + #if ENABLED(NEWPANEL) + float Total_Prime = 0.0; + + if (g26_prime_flag == -1) { // The user wants to control how much filament gets purged + + has_control_of_lcd_panel = true; + lcd_setstatusPGM(PSTR("User-Controlled Prime"), 99); + chirp_at_user(); + + set_destination_to_current(); + + recover_filament(destination); // Make sure G26 doesn't think the filament is retracted(). + + while (!ubl_lcd_clicked()) { + chirp_at_user(); + destination[E_AXIS] += 0.25; + #ifdef PREVENT_LENGTHY_EXTRUDE + Total_Prime += 0.25; + if (Total_Prime >= EXTRUDE_MAXLENGTH) return UBL_ERR; + #endif + G26_line_to_destination(planner.max_feedrate_mm_s[E_AXIS] / 15.0); + + stepper.synchronize(); // Without this synchronize, the purge is more consistent, + // but because the planner has a buffer, we won't be able + // to stop as quickly. So we put up with the less smooth + // action to give the user a more responsive 'Stop'. + set_destination_to_current(); + idle(); + } + + while (ubl_lcd_clicked()) idle(); // Debounce Encoder Wheel + + #if ENABLED(ULTRA_LCD) + strcpy_P(lcd_status_message, PSTR("Done Priming")); // We can't do lcd_setstatusPGM() without having it continue; + // So... We cheat to get a message up. + lcd_setstatusPGM(PSTR("Done Priming"), 99); + lcd_quick_feedback(); + #endif + + has_control_of_lcd_panel = false; + + } + else { + #else + { + #endif + #if ENABLED(ULTRA_LCD) + lcd_setstatusPGM(PSTR("Fixed Length Prime."), 99); + lcd_quick_feedback(); + #endif + set_destination_to_current(); + destination[E_AXIS] += g26_prime_length; + G26_line_to_destination(planner.max_feedrate_mm_s[E_AXIS] / 15.0); + stepper.synchronize(); + set_destination_to_current(); + retract_filament(destination); + } + + return UBL_OK; + } + +#endif // AUTO_BED_LEVELING_UBL && UBL_G26_MESH_VALIDATION diff --git a/trunk/Arduino/Marlin_1.1.6/I2CPositionEncoder.cpp b/trunk/Arduino/Marlin_1.1.6/I2CPositionEncoder.cpp new file mode 100644 index 00000000..84334812 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/I2CPositionEncoder.cpp @@ -0,0 +1,1132 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2016, 2017 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +//todo: add support for multiple encoders on a single axis +//todo: add z axis auto-leveling +//todo: consolidate some of the related M codes? +//todo: add endstop-replacement mode? +//todo: try faster I2C speed; tweak TWI_FREQ (400000L, or faster?); or just TWBR = ((CPU_FREQ / 400000L) - 16) / 2; +//todo: consider Marlin-optimized Wire library; i.e. MarlinWire, like MarlinSerial + + +#include "MarlinConfig.h" + +#if ENABLED(I2C_POSITION_ENCODERS) + + #include "Marlin.h" + #include "temperature.h" + #include "stepper.h" + #include "I2CPositionEncoder.h" + #include "gcode.h" + + #include + + + void I2CPositionEncoder::init(const uint8_t address, const AxisEnum axis) { + encoderAxis = axis; + i2cAddress = address; + + initialised++; + + SERIAL_ECHOPAIR("Setting up encoder on ", axis_codes[encoderAxis]); + SERIAL_ECHOLNPAIR(" axis, addr = ", address); + + position = get_position(); + } + + void I2CPositionEncoder::update() { + if (!initialised || !homed || !active) return; //check encoder is set up and active + + position = get_position(); + + //we don't want to stop things just because the encoder missed a message, + //so we only care about responses that indicate bad magnetic strength + + if (!passes_test(false)) { //check encoder data is good + lastErrorTime = millis(); + /* + if (trusted) { //commented out as part of the note below + trusted = false; + SERIAL_ECHOPGM("Fault detected on "); + SERIAL_ECHO(axis_codes[encoderAxis]); + SERIAL_ECHOLNPGM(" axis encoder. Disengaging error correction until module is trusted again."); + } + */ + return; + } + + if (!trusted) { + /** + * This is commented out because it introduces error and can cause bad print quality. + * + * This code is intended to manage situations where the encoder has reported bad magnetic strength. + * This indicates that the magnetic strip was too far away from the sensor to reliably track position. + * When this happens, this code resets the offset based on where the printer thinks it is. This has been + * shown to introduce errors in actual position which result in drifting prints and poor print quality. + * Perhaps a better method would be to disable correction on the axis with a problem, report it to the + * user via the status leds on the encoder module and prompt the user to re-home the axis at which point + * the encoder would be re-enabled. + */ + + /* + // If the magnetic strength has been good for a certain time, start trusting the module again + + if (millis() - lastErrorTime > I2CPE_TIME_TRUSTED) { + trusted = true; + + SERIAL_ECHOPGM("Untrusted encoder module on "); + SERIAL_ECHO(axis_codes[encoderAxis]); + SERIAL_ECHOLNPGM(" axis has been fault-free for set duration, reinstating error correction."); + + //the encoder likely lost its place when the error occured, so we'll reset and use the printer's + //idea of where it the axis is to re-initialise + float position = stepper.get_axis_position_mm(encoderAxis); + int32_t positionInTicks = position * get_ticks_unit(); + + //shift position from previous to current position + zeroOffset -= (positionInTicks - get_position()); + + #ifdef I2CPE_DEBUG + SERIAL_ECHOPGM("Current position is "); + SERIAL_ECHOLN(position); + + SERIAL_ECHOPGM("Position in encoder ticks is "); + SERIAL_ECHOLN(positionInTicks); + + SERIAL_ECHOPGM("New zero-offset of "); + SERIAL_ECHOLN(zeroOffset); + + SERIAL_ECHOPGM("New position reads as "); + SERIAL_ECHO(get_position()); + SERIAL_ECHOPGM("("); + SERIAL_ECHO(mm_from_count(get_position())); + SERIAL_ECHOLNPGM(")"); + #endif + } + */ + return; + } + + lastPosition = position; + const millis_t positionTime = millis(); + + //only do error correction if setup and enabled + if (ec && ecMethod != I2CPE_ECM_NONE) { + + #ifdef I2CPE_EC_THRESH_PROPORTIONAL + const millis_t deltaTime = positionTime - lastPositionTime; + const uint32_t distance = abs(position - lastPosition), + speed = distance / deltaTime; + const float threshold = constrain((speed / 50), 1, 50) * ecThreshold; + #else + const float threshold = get_error_correct_threshold(); + #endif + + //check error + #if ENABLED(I2CPE_ERR_ROLLING_AVERAGE) + float sum = 0, diffSum = 0; + + errIdx = (errIdx >= I2CPE_ERR_ARRAY_SIZE - 1) ? 0 : errIdx + 1; + err[errIdx] = get_axis_error_steps(false); + + LOOP_L_N(i, I2CPE_ERR_ARRAY_SIZE) { + sum += err[i]; + if (i) diffSum += abs(err[i-1] - err[i]); + } + + const int32_t error = int32_t(sum / (I2CPE_ERR_ARRAY_SIZE + 1)); //calculate average for error + + #else + const int32_t error = get_axis_error_steps(false); + #endif + + //SERIAL_ECHOPGM("Axis error steps: "); + //SERIAL_ECHOLN(error); + + #ifdef I2CPE_ERR_THRESH_ABORT + if (labs(error) > I2CPE_ERR_THRESH_ABORT * planner.axis_steps_per_mm[encoderAxis]) { + //kill("Significant Error"); + SERIAL_ECHOPGM("Axis error greater than set threshold, aborting!"); + SERIAL_ECHOLN(error); + safe_delay(5000); + } + #endif + + #if ENABLED(I2CPE_ERR_ROLLING_AVERAGE) + if (errIdx == 0) { + // in order to correct for "error" but avoid correcting for noise and non skips + // it must be > threshold and have a difference average of < 10 and be < 2000 steps + if (labs(error) > threshold * planner.axis_steps_per_mm[encoderAxis] && + diffSum < 10 * (I2CPE_ERR_ARRAY_SIZE - 1) && labs(error) < 2000) { //Check for persistent error (skip) + SERIAL_ECHO(axis_codes[encoderAxis]); + SERIAL_ECHOPAIR(" diffSum: ", diffSum / (I2CPE_ERR_ARRAY_SIZE - 1)); + SERIAL_ECHOPAIR(" - err detected: ", error / planner.axis_steps_per_mm[encoderAxis]); + SERIAL_ECHOLNPGM("mm; correcting!"); + thermalManager.babystepsTodo[encoderAxis] = -LROUND(error); + } + } + #else + if (labs(error) > threshold * planner.axis_steps_per_mm[encoderAxis]) { + //SERIAL_ECHOLN(error); + //SERIAL_ECHOLN(position); + thermalManager.babystepsTodo[encoderAxis] = -LROUND(error/2); + } + #endif + + if (labs(error) > I2CPE_ERR_CNT_THRESH * planner.axis_steps_per_mm[encoderAxis]) { + const millis_t ms = millis(); + if (ELAPSED(ms, nextErrorCountTime)) { + SERIAL_ECHOPAIR("Large error on ", axis_codes[encoderAxis]); + SERIAL_ECHOPAIR(" axis. error: ", (int)error); + SERIAL_ECHOLNPAIR("; diffSum: ", diffSum); + errorCount++; + nextErrorCountTime = ms + I2CPE_ERR_CNT_DEBOUNCE_MS; + } + } + } + + lastPositionTime = positionTime; + } + + void I2CPositionEncoder::set_homed() { + if (active) { + reset(); // Reset module's offset to zero (so current position is homed / zero) + delay(10); + + zeroOffset = get_raw_count(); + homed++; + trusted++; + + #ifdef I2CPE_DEBUG + SERIAL_ECHO(axis_codes[encoderAxis]); + SERIAL_ECHOPAIR(" axis encoder homed, offset of ", zeroOffset); + SERIAL_ECHOLNPGM(" ticks."); + #endif + } + } + + bool I2CPositionEncoder::passes_test(const bool report) { + if (report) { + if (H != I2CPE_MAG_SIG_GOOD) SERIAL_ECHOPGM("Warning. "); + SERIAL_ECHO(axis_codes[encoderAxis]); + SERIAL_ECHOPGM(" axis "); + serialprintPGM(H == I2CPE_MAG_SIG_BAD ? PSTR("magnetic strip ") : PSTR("encoder ")); + switch (H) { + case I2CPE_MAG_SIG_GOOD: + case I2CPE_MAG_SIG_MID: + SERIAL_ECHOLNPGM("passes test; field strength "); + serialprintPGM(H == I2CPE_MAG_SIG_GOOD ? PSTR("good.\n") : PSTR("fair.\n")); + break; + default: + SERIAL_ECHOLNPGM("not detected!"); + } + } + return (H == I2CPE_MAG_SIG_GOOD || H == I2CPE_MAG_SIG_MID); + } + + float I2CPositionEncoder::get_axis_error_mm(const bool report) { + float target, actual, error; + + target = stepper.get_axis_position_mm(encoderAxis); + actual = mm_from_count(position); + error = actual - target; + + if (labs(error) > 10000) error = 0; // ? + + if (report) { + SERIAL_ECHO(axis_codes[encoderAxis]); + SERIAL_ECHOPAIR(" axis target: ", target); + SERIAL_ECHOPAIR(", actual: ", actual); + SERIAL_ECHOLNPAIR(", error : ",error); + } + + return error; + } + + int32_t I2CPositionEncoder::get_axis_error_steps(const bool report) { + if (!active) { + if (report) { + SERIAL_ECHO(axis_codes[encoderAxis]); + SERIAL_ECHOLNPGM(" axis encoder not active!"); + } + return 0; + } + + float stepperTicksPerUnit; + int32_t encoderTicks = position, encoderCountInStepperTicksScaled; + //int32_t stepperTicks = stepper.position(encoderAxis); + + // With a rotary encoder we're concerned with ticks/rev; whereas with a linear we're concerned with ticks/mm + stepperTicksPerUnit = (type == I2CPE_ENC_TYPE_ROTARY) ? stepperTicks : planner.axis_steps_per_mm[encoderAxis]; + + //convert both 'ticks' into same units / base + encoderCountInStepperTicksScaled = LROUND((stepperTicksPerUnit * encoderTicks) / encoderTicksPerUnit); + + int32_t target = stepper.position(encoderAxis), + error = (encoderCountInStepperTicksScaled - target); + + //suppress discontinuities (might be caused by bad I2C readings...?) + bool suppressOutput = (labs(error - errorPrev) > 100); + + if (report) { + SERIAL_ECHO(axis_codes[encoderAxis]); + SERIAL_ECHOPAIR(" axis target: ", target); + SERIAL_ECHOPAIR(", actual: ", encoderCountInStepperTicksScaled); + SERIAL_ECHOLNPAIR(", error : ", error); + + if (suppressOutput) SERIAL_ECHOLNPGM("Discontinuity detected, suppressing error."); + } + + errorPrev = error; + + return (suppressOutput ? 0 : error); + } + + int32_t I2CPositionEncoder::get_raw_count() { + uint8_t index = 0; + i2cLong encoderCount; + + encoderCount.val = 0x00; + + if (Wire.requestFrom((int)i2cAddress, 3) != 3) { + //houston, we have a problem... + H = I2CPE_MAG_SIG_NF; + return 0; + } + + while (Wire.available()) + encoderCount.bval[index++] = (uint8_t)Wire.read(); + + //extract the magnetic strength + H = (B00000011 & (encoderCount.bval[2] >> 6)); + + //extract sign bit; sign = (encoderCount.bval[2] & B00100000); + //set all upper bits to the sign value to overwrite H + encoderCount.val = (encoderCount.bval[2] & B00100000) ? (encoderCount.val | 0xFFC00000) : (encoderCount.val & 0x003FFFFF); + + if (invert) encoderCount.val *= -1; + + return encoderCount.val; + } + + bool I2CPositionEncoder::test_axis() { + //only works on XYZ cartesian machines for the time being + if (!(encoderAxis == X_AXIS || encoderAxis == Y_AXIS || encoderAxis == Z_AXIS)) return false; + + float startCoord[NUM_AXIS] = { 0 }, endCoord[NUM_AXIS] = { 0 }; + + const float startPosition = soft_endstop_min[encoderAxis] + 10, + endPosition = soft_endstop_max[encoderAxis] - 10, + feedrate = FLOOR(MMM_TO_MMS((encoderAxis == Z_AXIS) ? HOMING_FEEDRATE_Z : HOMING_FEEDRATE_XY)); + + ec = false; + + LOOP_NA(i) { + startCoord[i] = stepper.get_axis_position_mm((AxisEnum)i); + endCoord[i] = stepper.get_axis_position_mm((AxisEnum)i); + } + + startCoord[encoderAxis] = startPosition; + endCoord[encoderAxis] = endPosition; + + stepper.synchronize(); + + planner.buffer_line(startCoord[X_AXIS],startCoord[Y_AXIS],startCoord[Z_AXIS], + stepper.get_axis_position_mm(E_AXIS), feedrate, 0); + stepper.synchronize(); + + // if the module isn't currently trusted, wait until it is (or until it should be if things are working) + if (!trusted) { + int32_t startWaitingTime = millis(); + while (!trusted && millis() - startWaitingTime < I2CPE_TIME_TRUSTED) + safe_delay(500); + } + + if (trusted) { // if trusted, commence test + planner.buffer_line(endCoord[X_AXIS], endCoord[Y_AXIS], endCoord[Z_AXIS], + stepper.get_axis_position_mm(E_AXIS), feedrate, 0); + stepper.synchronize(); + } + + return trusted; + } + + void I2CPositionEncoder::calibrate_steps_mm(const uint8_t iter) { + if (type != I2CPE_ENC_TYPE_LINEAR) { + SERIAL_ECHOLNPGM("Steps per mm calibration is only available using linear encoders."); + return; + } + + if (!(encoderAxis == X_AXIS || encoderAxis == Y_AXIS || encoderAxis == Z_AXIS)) { + SERIAL_ECHOLNPGM("Automatic steps / mm calibration not supported for this axis."); + return; + } + + float old_steps_mm, new_steps_mm, + startDistance, endDistance, + travelDistance, travelledDistance, total = 0, + startCoord[NUM_AXIS] = { 0 }, endCoord[NUM_AXIS] = { 0 }; + + float feedrate; + + int32_t startCount, stopCount; + + feedrate = MMM_TO_MMS((encoderAxis == Z_AXIS) ? HOMING_FEEDRATE_Z : HOMING_FEEDRATE_XY); + + bool oldec = ec; + ec = false; + + startDistance = 20; + endDistance = soft_endstop_max[encoderAxis] - 20; + travelDistance = endDistance - startDistance; + + LOOP_NA(i) { + startCoord[i] = stepper.get_axis_position_mm((AxisEnum)i); + endCoord[i] = stepper.get_axis_position_mm((AxisEnum)i); + } + + startCoord[encoderAxis] = startDistance; + endCoord[encoderAxis] = endDistance; + + LOOP_L_N(i, iter) { + stepper.synchronize(); + + planner.buffer_line(startCoord[X_AXIS],startCoord[Y_AXIS],startCoord[Z_AXIS], + stepper.get_axis_position_mm(E_AXIS), feedrate, 0); + stepper.synchronize(); + + delay(250); + startCount = get_position(); + + //do_blocking_move_to(endCoord[X_AXIS],endCoord[Y_AXIS],endCoord[Z_AXIS]); + + planner.buffer_line(endCoord[X_AXIS],endCoord[Y_AXIS],endCoord[Z_AXIS], + stepper.get_axis_position_mm(E_AXIS), feedrate, 0); + stepper.synchronize(); + + //Read encoder distance + delay(250); + stopCount = get_position(); + + travelledDistance = mm_from_count(abs(stopCount - startCount)); + + SERIAL_ECHOPAIR("Attempted to travel: ", travelDistance); + SERIAL_ECHOLNPGM("mm."); + + SERIAL_ECHOPAIR("Actually travelled: ", travelledDistance); + SERIAL_ECHOLNPGM("mm."); + + //Calculate new axis steps per unit + old_steps_mm = planner.axis_steps_per_mm[encoderAxis]; + new_steps_mm = (old_steps_mm * travelDistance) / travelledDistance; + + SERIAL_ECHOLNPAIR("Old steps per mm: ", old_steps_mm); + SERIAL_ECHOLNPAIR("New steps per mm: ", new_steps_mm); + + //Save new value + planner.axis_steps_per_mm[encoderAxis] = new_steps_mm; + + if (iter > 1) { + total += new_steps_mm; + + // swap start and end points so next loop runs from current position + float tempCoord = startCoord[encoderAxis]; + startCoord[encoderAxis] = endCoord[encoderAxis]; + endCoord[encoderAxis] = tempCoord; + } + } + + if (iter > 1) { + total /= (float)iter; + SERIAL_ECHOLNPAIR("Average steps per mm: ", total); + } + + ec = oldec; + + SERIAL_ECHOLNPGM("Calculated steps per mm has been set. Please save to EEPROM (M500) if you wish to keep these values."); + } + + void I2CPositionEncoder::reset() { + Wire.beginTransmission(i2cAddress); + Wire.write(I2CPE_RESET_COUNT); + Wire.endTransmission(); + + #if ENABLED(I2CPE_ERR_ROLLING_AVERAGE) + ZERO(err); + #endif + } + + + bool I2CPositionEncodersMgr::I2CPE_anyaxis; + uint8_t I2CPositionEncodersMgr::I2CPE_addr, + I2CPositionEncodersMgr::I2CPE_idx; + I2CPositionEncoder I2CPositionEncodersMgr::encoders[I2CPE_ENCODER_CNT]; + + void I2CPositionEncodersMgr::init() { + Wire.begin(); + + #if I2CPE_ENCODER_CNT > 0 + uint8_t i = 0; + + encoders[i].init(I2CPE_ENC_1_ADDR, I2CPE_ENC_1_AXIS); + + #ifdef I2CPE_ENC_1_TYPE + encoders[i].set_type(I2CPE_ENC_1_TYPE); + #endif + #ifdef I2CPE_ENC_1_TICKS_UNIT + encoders[i].set_ticks_unit(I2CPE_ENC_1_TICKS_UNIT); + #endif + #ifdef I2CPE_ENC_1_TICKS_REV + encoders[i].set_stepper_ticks(I2CPE_ENC_1_TICKS_REV); + #endif + #ifdef I2CPE_ENC_1_INVERT + encoders[i].set_inverted(I2CPE_ENC_1_INVERT); + #endif + #ifdef I2CPE_ENC_1_EC_METHOD + encoders[i].set_ec_method(I2CPE_ENC_1_EC_METHOD); + #endif + #ifdef I2CPE_ENC_1_EC_THRESH + encoders[i].set_ec_threshold(I2CPE_ENC_1_EC_THRESH); + #endif + + encoders[i].set_active(encoders[i].passes_test(true)); + + #if I2CPE_ENC_1_AXIS == E_AXIS + encoders[i].set_homed(); + #endif + #endif + + #if I2CPE_ENCODER_CNT > 1 + i++; + + encoders[i].init(I2CPE_ENC_2_ADDR, I2CPE_ENC_2_AXIS); + + #ifdef I2CPE_ENC_2_TYPE + encoders[i].set_type(I2CPE_ENC_2_TYPE); + #endif + #ifdef I2CPE_ENC_2_TICKS_UNIT + encoders[i].set_ticks_unit(I2CPE_ENC_2_TICKS_UNIT); + #endif + #ifdef I2CPE_ENC_2_TICKS_REV + encoders[i].set_stepper_ticks(I2CPE_ENC_2_TICKS_REV); + #endif + #ifdef I2CPE_ENC_2_INVERT + encoders[i].set_inverted(I2CPE_ENC_2_INVERT); + #endif + #ifdef I2CPE_ENC_2_EC_METHOD + encoders[i].set_ec_method(I2CPE_ENC_2_EC_METHOD); + #endif + #ifdef I2CPE_ENC_2_EC_THRESH + encoders[i].set_ec_threshold(I2CPE_ENC_2_EC_THRESH); + #endif + + encoders[i].set_active(encoders[i].passes_test(true)); + + #if I2CPE_ENC_2_AXIS == E_AXIS + encoders[i].set_homed(); + #endif + #endif + + #if I2CPE_ENCODER_CNT > 2 + i++; + + encoders[i].init(I2CPE_ENC_3_ADDR, I2CPE_ENC_3_AXIS); + + #ifdef I2CPE_ENC_3_TYPE + encoders[i].set_type(I2CPE_ENC_3_TYPE); + #endif + #ifdef I2CPE_ENC_3_TICKS_UNIT + encoders[i].set_ticks_unit(I2CPE_ENC_3_TICKS_UNIT); + #endif + #ifdef I2CPE_ENC_3_TICKS_REV + encoders[i].set_stepper_ticks(I2CPE_ENC_3_TICKS_REV); + #endif + #ifdef I2CPE_ENC_3_INVERT + encoders[i].set_inverted(I2CPE_ENC_3_INVERT); + #endif + #ifdef I2CPE_ENC_3_EC_METHOD + encoders[i].set_ec_method(I2CPE_ENC_3_EC_METHOD); + #endif + #ifdef I2CPE_ENC_3_EC_THRESH + encoders[i].set_ec_threshold(I2CPE_ENC_3_EC_THRESH); + #endif + + encoders[i].set_active(encoders[i].passes_test(true)); + + #if I2CPE_ENC_3_AXIS == E_AXIS + encoders[i].set_homed(); + #endif + #endif + + #if I2CPE_ENCODER_CNT > 3 + i++; + + encoders[i].init(I2CPE_ENC_4_ADDR, I2CPE_ENC_4_AXIS); + + #ifdef I2CPE_ENC_4_TYPE + encoders[i].set_type(I2CPE_ENC_4_TYPE); + #endif + #ifdef I2CPE_ENC_4_TICKS_UNIT + encoders[i].set_ticks_unit(I2CPE_ENC_4_TICKS_UNIT); + #endif + #ifdef I2CPE_ENC_4_TICKS_REV + encoders[i].set_stepper_ticks(I2CPE_ENC_4_TICKS_REV); + #endif + #ifdef I2CPE_ENC_4_INVERT + encoders[i].set_inverted(I2CPE_ENC_4_INVERT); + #endif + #ifdef I2CPE_ENC_4_EC_METHOD + encoders[i].set_ec_method(I2CPE_ENC_4_EC_METHOD); + #endif + #ifdef I2CPE_ENC_4_EC_THRESH + encoders[i].set_ec_threshold(I2CPE_ENC_4_EC_THRESH); + #endif + + encoders[i].set_active(encoders[i].passes_test(true)); + + #if I2CPE_ENC_4_AXIS == E_AXIS + encoders[i].set_homed(); + #endif + #endif + + #if I2CPE_ENCODER_CNT > 4 + i++; + + encoders[i].init(I2CPE_ENC_5_ADDR, I2CPE_ENC_5_AXIS); + + #ifdef I2CPE_ENC_5_TYPE + encoders[i].set_type(I2CPE_ENC_5_TYPE); + #endif + #ifdef I2CPE_ENC_5_TICKS_UNIT + encoders[i].set_ticks_unit(I2CPE_ENC_5_TICKS_UNIT); + #endif + #ifdef I2CPE_ENC_5_TICKS_REV + encoders[i].set_stepper_ticks(I2CPE_ENC_5_TICKS_REV); + #endif + #ifdef I2CPE_ENC_5_INVERT + encoders[i].set_inverted(I2CPE_ENC_5_INVERT); + #endif + #ifdef I2CPE_ENC_5_EC_METHOD + encoders[i].set_ec_method(I2CPE_ENC_5_EC_METHOD); + #endif + #ifdef I2CPE_ENC_5_EC_THRESH + encoders[i].set_ec_threshold(I2CPE_ENC_5_EC_THRESH); + #endif + + encoders[i].set_active(encoders[i].passes_test(true)); + + #if I2CPE_ENC_5_AXIS == E_AXIS + encoders[i].set_homed(); + #endif + #endif + } + + void I2CPositionEncodersMgr::report_position(const int8_t idx, const bool units, const bool noOffset) { + CHECK_IDX(); + + if (units) + SERIAL_ECHOLN(noOffset ? encoders[idx].mm_from_count(encoders[idx].get_raw_count()) : encoders[idx].get_position_mm()); + else { + if (noOffset) { + const int32_t raw_count = encoders[idx].get_raw_count(); + SERIAL_ECHO(axis_codes[encoders[idx].get_axis()]); + SERIAL_CHAR(' '); + + for (uint8_t j = 31; j > 0; j--) + SERIAL_ECHO((bool)(0x00000001 & (raw_count >> j))); + + SERIAL_ECHO((bool)(0x00000001 & raw_count)); + SERIAL_CHAR(' '); + SERIAL_ECHOLN(raw_count); + } + else + SERIAL_ECHOLN(encoders[idx].get_position()); + } + } + + void I2CPositionEncodersMgr::change_module_address(const uint8_t oldaddr, const uint8_t newaddr) { + // First check 'new' address is not in use + Wire.beginTransmission(newaddr); + if (!Wire.endTransmission()) { + SERIAL_ECHOPAIR("?There is already a device with that address on the I2C bus! (", newaddr); + SERIAL_ECHOLNPGM(")"); + return; + } + + // Now check that we can find the module on the oldaddr address + Wire.beginTransmission(oldaddr); + if (Wire.endTransmission()) { + SERIAL_ECHOPAIR("?No module detected at this address! (", oldaddr); + SERIAL_ECHOLNPGM(")"); + return; + } + + SERIAL_ECHOPAIR("Module found at ", oldaddr); + SERIAL_ECHOLNPAIR(", changing address to ", newaddr); + + // Change the modules address + Wire.beginTransmission(oldaddr); + Wire.write(I2CPE_SET_ADDR); + Wire.write(newaddr); + Wire.endTransmission(); + + SERIAL_ECHOLNPGM("Address changed, resetting and waiting for confirmation.."); + + // Wait for the module to reset (can probably be improved by polling address with a timeout). + safe_delay(I2CPE_REBOOT_TIME); + + // Look for the module at the new address. + Wire.beginTransmission(newaddr); + if (Wire.endTransmission()) { + SERIAL_ECHOLNPGM("Address change failed! Check encoder module."); + return; + } + + SERIAL_ECHOLNPGM("Address change successful!"); + + // Now, if this module is configured, find which encoder instance it's supposed to correspond to + // and enable it (it will likely have failed initialisation on power-up, before the address change). + const int8_t idx = idx_from_addr(newaddr); + if (idx >= 0 && !encoders[idx].get_active()) { + SERIAL_ECHO(axis_codes[encoders[idx].get_axis()]); + SERIAL_ECHOLNPGM(" axis encoder was not detected on printer startup. Trying again."); + encoders[idx].set_active(encoders[idx].passes_test(true)); + } + } + + void I2CPositionEncodersMgr::report_module_firmware(const uint8_t address) { + // First check there is a module + Wire.beginTransmission(address); + if (Wire.endTransmission()) { + SERIAL_ECHOPAIR("?No module detected at this address! (", address); + SERIAL_ECHOLNPGM(")"); + return; + } + + SERIAL_ECHOPAIR("Requesting version info from module at address ", address); + SERIAL_ECHOLNPGM(":"); + + Wire.beginTransmission(address); + Wire.write(I2CPE_SET_REPORT_MODE); + Wire.write(I2CPE_REPORT_VERSION); + Wire.endTransmission(); + + // Read value + if (Wire.requestFrom((int)address, 32)) { + char c; + while (Wire.available() > 0 && (c = (char)Wire.read()) > 0) + SERIAL_ECHO(c); + SERIAL_EOL(); + } + + // Set module back to normal (distance) mode + Wire.beginTransmission(address); + Wire.write(I2CPE_SET_REPORT_MODE); + Wire.write(I2CPE_REPORT_DISTANCE); + Wire.endTransmission(); + } + + int8_t I2CPositionEncodersMgr::parse() { + I2CPE_addr = 0; + + if (parser.seen('A')) { + + if (!parser.has_value()) { + SERIAL_PROTOCOLLNPGM("?A seen, but no address specified! [30-200]"); + return I2CPE_PARSE_ERR; + }; + + I2CPE_addr = parser.value_byte(); + if (!WITHIN(I2CPE_addr, 30, 200)) { // reserve the first 30 and last 55 + SERIAL_PROTOCOLLNPGM("?Address out of range. [30-200]"); + return I2CPE_PARSE_ERR; + } + + I2CPE_idx = idx_from_addr(I2CPE_addr); + if (I2CPE_idx >= I2CPE_ENCODER_CNT) { + SERIAL_PROTOCOLLNPGM("?No device with this address!"); + return I2CPE_PARSE_ERR; + } + } + else if (parser.seenval('I')) { + + if (!parser.has_value()) { + SERIAL_PROTOCOLLNPAIR("?I seen, but no index specified! [0-", I2CPE_ENCODER_CNT - 1); + SERIAL_PROTOCOLLNPGM("]"); + return I2CPE_PARSE_ERR; + }; + + I2CPE_idx = parser.value_byte(); + if (I2CPE_idx >= I2CPE_ENCODER_CNT) { + SERIAL_PROTOCOLLNPAIR("?Index out of range. [0-", I2CPE_ENCODER_CNT - 1); + SERIAL_ECHOLNPGM("]"); + return I2CPE_PARSE_ERR; + } + + I2CPE_addr = encoders[I2CPE_idx].get_address(); + } + else + I2CPE_idx = 0xFF; + + I2CPE_anyaxis = parser.seen_axis(); + + return I2CPE_PARSE_OK; + }; + + /** + * M860: Report the position(s) of position encoder module(s). + * + * A Module I2C address. [30, 200]. + * I Module index. [0, I2CPE_ENCODER_CNT - 1] + * O Include homed zero-offset in returned position. + * U Units in mm or raw step count. + * + * If A or I not specified: + * X Report on X axis encoder, if present. + * 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; + + const bool hasU = parser.seen('U'), hasO = parser.seen('O'); + + if (I2CPE_idx == 0xFF) { + LOOP_XYZE(i) { + if (!I2CPE_anyaxis || parser.seen(axis_codes[i])) { + const uint8_t idx = idx_from_axis(AxisEnum(i)); + if ((int8_t)idx >= 0) report_position(idx, hasU, hasO); + } + } + } + else + report_position(I2CPE_idx, hasU, hasO); + } + + /** + * M861: Report the status of position encoder modules. + * + * A Module I2C address. [30, 200]. + * I Module index. [0, I2CPE_ENCODER_CNT - 1] + * + * If A or I not specified: + * X Report on X axis encoder, if present. + * 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; + + if (I2CPE_idx == 0xFF) { + LOOP_XYZE(i) { + if (!I2CPE_anyaxis || parser.seen(axis_codes[i])) { + const uint8_t idx = idx_from_axis(AxisEnum(i)); + if ((int8_t)idx >= 0) report_status(idx); + } + } + } + else + report_status(I2CPE_idx); + } + + /** + * M862: Perform an axis continuity test for position encoder + * modules. + * + * A Module I2C address. [30, 200]. + * I Module index. [0, I2CPE_ENCODER_CNT - 1] + * + * If A or I not specified: + * X Report on X axis encoder, if present. + * 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; + + if (I2CPE_idx == 0xFF) { + LOOP_XYZE(i) { + if (!I2CPE_anyaxis || parser.seen(axis_codes[i])) { + const uint8_t idx = idx_from_axis(AxisEnum(i)); + if ((int8_t)idx >= 0) test_axis(idx); + } + } + } + else + test_axis(I2CPE_idx); + } + + /** + * M863: Perform steps-per-mm calibration for + * position encoder modules. + * + * A Module I2C address. [30, 200]. + * I Module index. [0, I2CPE_ENCODER_CNT - 1] + * P Number of rePeats/iterations. + * + * If A or I not specified: + * X Report on X axis encoder, if present. + * 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; + + const uint8_t iterations = constrain(parser.byteval('P', 1), 1, 10); + + if (I2CPE_idx == 0xFF) { + LOOP_XYZE(i) { + if (!I2CPE_anyaxis || parser.seen(axis_codes[i])) { + const uint8_t idx = idx_from_axis(AxisEnum(i)); + if ((int8_t)idx >= 0) calibrate_steps_mm(idx, iterations); + } + } + } + else + calibrate_steps_mm(I2CPE_idx, iterations); + } + + /** + * M864: Change position encoder module I2C address. + * + * A Module current/old I2C address. If not present, + * assumes default address (030). [30, 200]. + * S Module new I2C address. [30, 200]. + * + * If S is not specified: + * X Use I2CPE_PRESET_ADDR_X (030). + * Y Use I2CPE_PRESET_ADDR_Y (031). + * Z Use I2CPE_PRESET_ADDR_Z (032). + * E Use I2CPE_PRESET_ADDR_E (033). + */ + void I2CPositionEncodersMgr::M864() { + uint8_t newAddress; + + if (parse()) return; + + if (!I2CPE_addr) I2CPE_addr = I2CPE_PRESET_ADDR_X; + + if (parser.seen('S')) { + if (!parser.has_value()) { + SERIAL_PROTOCOLLNPGM("?S seen, but no address specified! [30-200]"); + return; + }; + + newAddress = parser.value_byte(); + if (!WITHIN(newAddress, 30, 200)) { + SERIAL_PROTOCOLLNPGM("?New address out of range. [30-200]"); + return; + } + } + else if (!I2CPE_anyaxis) { + SERIAL_PROTOCOLLNPGM("?You must specify S or [XYZE]."); + return; + } + else { + if (parser.seen('X')) newAddress = I2CPE_PRESET_ADDR_X; + else if (parser.seen('Y')) newAddress = I2CPE_PRESET_ADDR_Y; + else if (parser.seen('Z')) newAddress = I2CPE_PRESET_ADDR_Z; + else if (parser.seen('E')) newAddress = I2CPE_PRESET_ADDR_E; + else return; + } + + SERIAL_ECHOPAIR("Changing module at address ", I2CPE_addr); + SERIAL_ECHOLNPAIR(" to address ", newAddress); + + change_module_address(I2CPE_addr, newAddress); + } + + /** + * M865: Check position encoder module firmware version. + * + * A Module I2C address. [30, 200]. + * I Module index. [0, I2CPE_ENCODER_CNT - 1]. + * + * If A or I not specified: + * X Check X axis encoder, if present. + * Y Check Y axis encoder, if present. + * Z Check Z axis encoder, if present. + * E Check E axis encoder, if present. + */ + void I2CPositionEncodersMgr::M865() { + if (parse()) return; + + if (!I2CPE_addr) { + LOOP_XYZE(i) { + if (!I2CPE_anyaxis || parser.seen(axis_codes[i])) { + const uint8_t idx = idx_from_axis(AxisEnum(i)); + if ((int8_t)idx >= 0) report_module_firmware(encoders[idx].get_address()); + } + } + } + else + report_module_firmware(I2CPE_addr); + } + + /** + * M866: Report or reset position encoder module error + * count. + * + * A Module I2C address. [30, 200]. + * I Module index. [0, I2CPE_ENCODER_CNT - 1]. + * R Reset error counter. + * + * If A or I not specified: + * X Act on X axis encoder, if present. + * Y Act on Y axis encoder, if present. + * Z Act on Z axis encoder, if present. + * E Act on E axis encoder, if present. + */ + void I2CPositionEncodersMgr::M866() { + if (parse()) return; + + const bool hasR = parser.seen('R'); + + if (I2CPE_idx == 0xFF) { + LOOP_XYZE(i) { + if (!I2CPE_anyaxis || parser.seen(axis_codes[i])) { + const uint8_t idx = idx_from_axis(AxisEnum(i)); + if ((int8_t)idx >= 0) { + if (hasR) + reset_error_count(idx, AxisEnum(i)); + else + report_error_count(idx, AxisEnum(i)); + } + } + } + } + else if (hasR) + reset_error_count(I2CPE_idx, encoders[I2CPE_idx].get_axis()); + else + report_error_count(I2CPE_idx, encoders[I2CPE_idx].get_axis()); + } + + /** + * M867: Enable/disable or toggle error correction for position encoder modules. + * + * A Module I2C address. [30, 200]. + * I Module index. [0, I2CPE_ENCODER_CNT - 1]. + * S<1|0> Enable/disable error correction. 1 enables, 0 disables. If not + * supplied, toggle. + * + * If A or I not specified: + * X Act on X axis encoder, if present. + * Y Act on Y axis encoder, if present. + * Z Act on Z axis encoder, if present. + * E Act on E axis encoder, if present. + */ + void I2CPositionEncodersMgr::M867() { + if (parse()) return; + + const int8_t onoff = parser.seenval('S') ? parser.value_int() : -1; + + if (I2CPE_idx == 0xFF) { + LOOP_XYZE(i) { + if (!I2CPE_anyaxis || parser.seen(axis_codes[i])) { + const uint8_t idx = idx_from_axis(AxisEnum(i)); + if ((int8_t)idx >= 0) { + const bool ena = onoff == -1 ? !encoders[I2CPE_idx].get_ec_enabled() : !!onoff; + enable_ec(idx, ena, AxisEnum(i)); + } + } + } + } + else { + const bool ena = onoff == -1 ? !encoders[I2CPE_idx].get_ec_enabled() : !!onoff; + enable_ec(I2CPE_idx, ena, encoders[I2CPE_idx].get_axis()); + } + } + + /** + * M868: Report or set position encoder module error correction + * threshold. + * + * A Module I2C address. [30, 200]. + * I Module index. [0, I2CPE_ENCODER_CNT - 1]. + * T New error correction threshold. + * + * If A not specified: + * X Act on X axis encoder, if present. + * Y Act on Y axis encoder, if present. + * Z Act on Z axis encoder, if present. + * E Act on E axis encoder, if present. + */ + void I2CPositionEncodersMgr::M868() { + if (parse()) return; + + const float newThreshold = parser.seenval('T') ? parser.value_float() : -9999; + + if (I2CPE_idx == 0xFF) { + LOOP_XYZE(i) { + if (!I2CPE_anyaxis || parser.seen(axis_codes[i])) { + const uint8_t idx = idx_from_axis(AxisEnum(i)); + if ((int8_t)idx >= 0) { + if (newThreshold != -9999) + set_ec_threshold(idx, newThreshold, encoders[idx].get_axis()); + else + get_ec_threshold(idx, encoders[idx].get_axis()); + } + } + } + } + else if (newThreshold != -9999) + set_ec_threshold(I2CPE_idx, newThreshold, encoders[I2CPE_idx].get_axis()); + else + get_ec_threshold(I2CPE_idx, encoders[I2CPE_idx].get_axis()); + } + + /** + * M869: Report position encoder module error. + * + * A Module I2C address. [30, 200]. + * I Module index. [0, I2CPE_ENCODER_CNT - 1]. + * + * If A not specified: + * X Act on X axis encoder, if present. + * Y Act on Y axis encoder, if present. + * Z Act on Z axis encoder, if present. + * E Act on E axis encoder, if present. + */ + void I2CPositionEncodersMgr::M869() { + if (parse()) return; + + if (I2CPE_idx == 0xFF) { + LOOP_XYZE(i) { + if (!I2CPE_anyaxis || parser.seen(axis_codes[i])) { + const uint8_t idx = idx_from_axis(AxisEnum(i)); + if ((int8_t)idx >= 0) report_error(idx); + } + } + } + else + report_error(I2CPE_idx); + } + +#endif // I2C_POSITION_ENCODERS diff --git a/trunk/Arduino/Marlin_1.1.6/I2CPositionEncoder.h b/trunk/Arduino/Marlin_1.1.6/I2CPositionEncoder.h new file mode 100644 index 00000000..a582a87b --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/I2CPositionEncoder.h @@ -0,0 +1,359 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2016, 2017 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#ifndef I2CPOSENC_H +#define I2CPOSENC_H + +#include "MarlinConfig.h" + +#if ENABLED(I2C_POSITION_ENCODERS) + + #include "enum.h" + #include "macros.h" + #include "types.h" + #include + + //=========== Advanced / Less-Common Encoder Configuration Settings ========== + + #define I2CPE_EC_THRESH_PROPORTIONAL // if enabled adjusts the error correction threshold + // proportional to the current speed of the axis allows + // for very small error margin at low speeds without + // stuttering due to reading latency at high speeds + + #define I2CPE_DEBUG // enable encoder-related debug serial echos + + #define I2CPE_REBOOT_TIME 5000 // time we wait for an encoder module to reboot + // after changing address. + + #define I2CPE_MAG_SIG_GOOD 0 + #define I2CPE_MAG_SIG_MID 1 + #define I2CPE_MAG_SIG_BAD 2 + #define I2CPE_MAG_SIG_NF 255 + + #define I2CPE_REQ_REPORT 0 + #define I2CPE_RESET_COUNT 1 + #define I2CPE_SET_ADDR 2 + #define I2CPE_SET_REPORT_MODE 3 + #define I2CPE_CLEAR_EEPROM 4 + + #define I2CPE_LED_PAR_MODE 10 + #define I2CPE_LED_PAR_BRT 11 + #define I2CPE_LED_PAR_RATE 14 + + #define I2CPE_REPORT_DISTANCE 0 + #define I2CPE_REPORT_STRENGTH 1 + #define I2CPE_REPORT_VERSION 2 + + // Default I2C addresses + #define I2CPE_PRESET_ADDR_X 30 + #define I2CPE_PRESET_ADDR_Y 31 + #define I2CPE_PRESET_ADDR_Z 32 + #define I2CPE_PRESET_ADDR_E 33 + + #define I2CPE_DEF_AXIS X_AXIS + #define I2CPE_DEF_ADDR I2CPE_PRESET_ADDR_X + + // Error event counter; tracks how many times there is an error exceeding a certain threshold + #define I2CPE_ERR_CNT_THRESH 3.00 + #define I2CPE_ERR_CNT_DEBOUNCE_MS 2000 + + #if ENABLED(I2CPE_ERR_ROLLING_AVERAGE) + #define I2CPE_ERR_ARRAY_SIZE 32 + #endif + + // Error Correction Methods + #define I2CPE_ECM_NONE 0 + #define I2CPE_ECM_MICROSTEP 1 + #define I2CPE_ECM_PLANNER 2 + #define I2CPE_ECM_STALLDETECT 3 + + // Encoder types + #define I2CPE_ENC_TYPE_ROTARY 0 + #define I2CPE_ENC_TYPE_LINEAR 1 + + // Parser + #define I2CPE_PARSE_ERR 1 + #define I2CPE_PARSE_OK 0 + + #define LOOP_PE(VAR) LOOP_L_N(VAR, I2CPE_ENCODER_CNT) + #define CHECK_IDX() do{ if (!WITHIN(idx, 0, I2CPE_ENCODER_CNT - 1)) return; }while(0) + + extern const char axis_codes[XYZE]; + + typedef union { + volatile int32_t val = 0; + uint8_t bval[4]; + } i2cLong; + + class I2CPositionEncoder { + private: + AxisEnum encoderAxis = I2CPE_DEF_AXIS; + + uint8_t i2cAddress = I2CPE_DEF_ADDR, + ecMethod = I2CPE_DEF_EC_METHOD, + type = I2CPE_DEF_TYPE, + H = I2CPE_MAG_SIG_NF; // Magnetic field strength + + int encoderTicksPerUnit = I2CPE_DEF_ENC_TICKS_UNIT, + stepperTicks = I2CPE_DEF_TICKS_REV, + errorCount = 0, + errorPrev = 0; + + float ecThreshold = I2CPE_DEF_EC_THRESH; + + bool homed = false, + trusted = false, + initialised = false, + active = false, + invert = false, + ec = true; + + float axisOffset = 0; + + int32_t axisOffsetTicks = 0, + zeroOffset = 0, + lastPosition = 0, + position; + + millis_t lastPositionTime = 0, + nextErrorCountTime = 0, + lastErrorTime; + + //double positionMm; //calculate + + #if ENABLED(I2CPE_ERR_ROLLING_AVERAGE) + uint8_t errIdx = 0; + int err[I2CPE_ERR_ARRAY_SIZE] = { 0 }; + #endif + + //float positionMm; //calculate + + public: + void init(const uint8_t address, const AxisEnum axis); + void reset(); + + void update(); + + void set_homed(); + + int32_t get_raw_count(); + + FORCE_INLINE float mm_from_count(const int32_t count) { + switch (type) { + default: return -1; + case I2CPE_ENC_TYPE_LINEAR: + return count / encoderTicksPerUnit; + case I2CPE_ENC_TYPE_ROTARY: + return (count * stepperTicks) / (encoderTicksPerUnit * planner.axis_steps_per_mm[encoderAxis]); + } + } + + FORCE_INLINE float get_position_mm() { return mm_from_count(get_position()); } + FORCE_INLINE int32_t get_position() { return get_raw_count() - zeroOffset - axisOffsetTicks; } + + int32_t get_axis_error_steps(const bool report); + float get_axis_error_mm(const bool report); + + void calibrate_steps_mm(const uint8_t iter); + + bool passes_test(const bool report); + + bool test_axis(void); + + FORCE_INLINE int get_error_count(void) { return errorCount; } + FORCE_INLINE void set_error_count(const int newCount) { errorCount = newCount; } + + FORCE_INLINE uint8_t get_address() { return i2cAddress; } + FORCE_INLINE void set_address(const uint8_t addr) { i2cAddress = addr; } + + FORCE_INLINE bool get_active(void) { return active; } + FORCE_INLINE void set_active(const bool a) { active = a; } + + FORCE_INLINE void set_inverted(const bool i) { invert = i; } + + FORCE_INLINE AxisEnum get_axis() { return encoderAxis; } + + FORCE_INLINE bool get_ec_enabled() { return ec; } + FORCE_INLINE void set_ec_enabled(const bool enabled) { ec = enabled; } + + FORCE_INLINE uint8_t get_ec_method() { return ecMethod; } + FORCE_INLINE void set_ec_method(const byte method) { ecMethod = method; } + + FORCE_INLINE float get_ec_threshold() { return ecThreshold; } + FORCE_INLINE void set_ec_threshold(const float newThreshold) { ecThreshold = newThreshold; } + + FORCE_INLINE int get_encoder_ticks_mm() { + switch (type) { + default: return 0; + case I2CPE_ENC_TYPE_LINEAR: + return encoderTicksPerUnit; + case I2CPE_ENC_TYPE_ROTARY: + return (int)((encoderTicksPerUnit / stepperTicks) * planner.axis_steps_per_mm[encoderAxis]); + } + } + + FORCE_INLINE int get_ticks_unit() { return encoderTicksPerUnit; } + FORCE_INLINE void set_ticks_unit(const int ticks) { encoderTicksPerUnit = ticks; } + + FORCE_INLINE uint8_t get_type() { return type; } + FORCE_INLINE void set_type(const byte newType) { type = newType; } + + FORCE_INLINE int get_stepper_ticks() { return stepperTicks; } + FORCE_INLINE void set_stepper_ticks(const int ticks) { stepperTicks = ticks; } + + FORCE_INLINE float get_axis_offset() { return axisOffset; } + FORCE_INLINE void set_axis_offset(const float newOffset) { + axisOffset = newOffset; + axisOffsetTicks = int32_t(axisOffset * get_encoder_ticks_mm()); + } + + FORCE_INLINE void set_current_position(const float newPositionMm) { + set_axis_offset(get_position_mm() - newPositionMm + axisOffset); + } + }; + + class I2CPositionEncodersMgr { + private: + static bool I2CPE_anyaxis; + static uint8_t I2CPE_addr, I2CPE_idx; + + public: + + static void init(void); + + // consider only updating one endoder per call / tick if encoders become too time intensive + static void update(void) { LOOP_PE(i) encoders[i].update(); } + + static void homed(const AxisEnum axis) { + LOOP_PE(i) + if (encoders[i].get_axis() == axis) encoders[i].set_homed(); + } + + static void report_position(const int8_t idx, const bool units, const bool noOffset); + + static void report_status(const int8_t idx) { + CHECK_IDX(); + SERIAL_ECHOPAIR("Encoder ",idx); + SERIAL_ECHOPGM(": "); + encoders[idx].get_raw_count(); + encoders[idx].passes_test(true); + } + + static void report_error(const int8_t idx) { + CHECK_IDX(); + encoders[idx].get_axis_error_steps(true); + } + + static void test_axis(const int8_t idx) { + CHECK_IDX(); + encoders[idx].test_axis(); + } + + static void calibrate_steps_mm(const int8_t idx, const int iterations) { + CHECK_IDX(); + encoders[idx].calibrate_steps_mm(iterations); + } + + static void change_module_address(const uint8_t oldaddr, const uint8_t newaddr); + static void report_module_firmware(const uint8_t address); + + static void report_error_count(const int8_t idx, const AxisEnum axis) { + CHECK_IDX(); + SERIAL_ECHOPAIR("Error count on ", axis_codes[axis]); + SERIAL_ECHOLNPAIR(" axis is ", encoders[idx].get_error_count()); + } + + static void reset_error_count(const int8_t idx, const AxisEnum axis) { + CHECK_IDX(); + encoders[idx].set_error_count(0); + SERIAL_ECHOPAIR("Error count on ", axis_codes[axis]); + SERIAL_ECHOLNPGM(" axis has been reset."); + } + + static void enable_ec(const int8_t idx, const bool enabled, const AxisEnum axis) { + CHECK_IDX(); + encoders[idx].set_ec_enabled(enabled); + SERIAL_ECHOPAIR("Error correction on ", axis_codes[axis]); + SERIAL_ECHOPGM(" axis is "); + serialprintPGM(encoders[idx].get_ec_enabled() ? PSTR("en") : PSTR("dis")); + SERIAL_ECHOLNPGM("abled."); + } + + static void set_ec_threshold(const int8_t idx, const float newThreshold, const AxisEnum axis) { + CHECK_IDX(); + encoders[idx].set_ec_threshold(newThreshold); + SERIAL_ECHOPAIR("Error correct threshold for ", axis_codes[axis]); + SERIAL_ECHOPAIR_F(" axis set to ", newThreshold); + SERIAL_ECHOLNPGM("mm."); + } + + static void get_ec_threshold(const int8_t idx, const AxisEnum axis) { + CHECK_IDX(); + const float threshold = encoders[idx].get_ec_threshold(); + SERIAL_ECHOPAIR("Error correct threshold for ", axis_codes[axis]); + SERIAL_ECHOPAIR_F(" axis is ", threshold); + SERIAL_ECHOLNPGM("mm."); + } + + static int8_t idx_from_axis(const AxisEnum axis) { + LOOP_PE(i) + if (encoders[i].get_axis() == axis) return i; + return -1; + } + + static int8_t idx_from_addr(const uint8_t addr) { + LOOP_PE(i) + if (encoders[i].get_address() == addr) return i; + return -1; + } + + static int8_t parse(); + + static void M860(); + static void M861(); + static void M862(); + static void M863(); + static void M864(); + static void M865(); + static void M866(); + static void M867(); + static void M868(); + static void M869(); + + static I2CPositionEncoder encoders[I2CPE_ENCODER_CNT]; + }; + + extern I2CPositionEncodersMgr I2CPEM; + + FORCE_INLINE static void gcode_M860() { I2CPEM.M860(); } + FORCE_INLINE static void gcode_M861() { I2CPEM.M861(); } + FORCE_INLINE static void gcode_M862() { I2CPEM.M862(); } + FORCE_INLINE static void gcode_M863() { I2CPEM.M863(); } + FORCE_INLINE static void gcode_M864() { I2CPEM.M864(); } + FORCE_INLINE static void gcode_M865() { I2CPEM.M865(); } + FORCE_INLINE static void gcode_M866() { I2CPEM.M866(); } + FORCE_INLINE static void gcode_M867() { I2CPEM.M867(); } + FORCE_INLINE static void gcode_M868() { I2CPEM.M868(); } + FORCE_INLINE static void gcode_M869() { I2CPEM.M869(); } + +#endif //I2C_POSITION_ENCODERS +#endif //I2CPOSENC_H diff --git a/trunk/Arduino/Marlin_1.1.6/M100_Free_Mem_Chk.cpp b/trunk/Arduino/Marlin_1.1.6/M100_Free_Mem_Chk.cpp new file mode 100644 index 00000000..6620b0a1 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/M100_Free_Mem_Chk.cpp @@ -0,0 +1,333 @@ +/** + * 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 . + * + */ + +/** + * M100 Free Memory Watcher + * + * This code watches the free memory block between the bottom of the heap and the top of the stack. + * This memory block is initialized and watched via the M100 command. + * + * M100 I Initializes the free memory block and prints vitals statistics about the area + * + * M100 F Identifies how much of the free memory block remains free and unused. It also + * detects and reports any corruption within the free memory block that may have + * happened due to errant firmware. + * + * M100 D Does a hex display of the free memory block along with a flag for any errant + * data that does not match the expected value. + * + * M100 C x Corrupts x locations within the free memory block. This is useful to check the + * correctness of the M100 F and M100 D commands. + * + * Also, there are two support functions that can be called from a developer's C code. + * + * uint16_t check_for_free_memory_corruption(const char * const ptr); + * void M100_dump_routine(const char * const title, const char *start, const char *end); + * + * Initial version by Roxy-3D + */ +#define M100_FREE_MEMORY_DUMPER // Enable for the `M110 D` Dump sub-command +#define M100_FREE_MEMORY_CORRUPTOR // Enable for the `M100 C` Corrupt sub-command + +#include "MarlinConfig.h" + +#if ENABLED(M100_FREE_MEMORY_WATCHER) + +#define TEST_BYTE ((char) 0xE5) + +extern char command_queue[BUFSIZE][MAX_CMD_SIZE]; + +extern char* __brkval; +extern size_t __heap_start, __heap_end, __flp; +extern char __bss_end; + +#include "Marlin.h" +#include "gcode.h" +#include "hex_print_routines.h" + +// +// Utility functions +// + +#define END_OF_HEAP() (__brkval ? __brkval : &__bss_end) +int check_for_free_memory_corruption(const char * const title); + +// 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() { + char x; + return &x + 1; // x is pulled on return; +} + +// Count the number of test bytes at the specified location. +int16_t count_test_bytes(const char * const ptr) { + for (uint16_t i = 0; i < 32000; i++) + if (((char) ptr[i]) != TEST_BYTE) + return i - 1; + + return -1; +} + +// +// M100 sub-commands +// + +#if ENABLED(M100_FREE_MEMORY_DUMPER) + /** + * M100 D + * Dump the free memory block from __brkval to the stack pointer. + * malloc() eats memory from the start of the block and the stack grows + * up from the bottom of the block. Solid test bytes indicate nothing has + * used that memory yet. There should not be anything but test bytes within + * the block. If so, it may indicate memory corruption due to a bad pointer. + * Unexpected bytes are flagged in the right column. + */ + void dump_free_memory(const char *ptr, const char *sp) { + // + // Start and end the dump on a nice 16 byte boundary + // (even though the values are not 16-byte aligned). + // + ptr = (char *)((uint16_t)ptr & 0xFFF0); // Align to 16-byte boundary + sp = (char *)((uint16_t)sp | 0x000F); // Align sp to the 15th byte (at or above sp) + + // Dump command main loop + while (ptr < sp) { + print_hex_word((uint16_t)ptr); // Print the address + SERIAL_CHAR(':'); + for (uint8_t i = 0; i < 16; i++) { // and 16 data bytes + if (i == 8) SERIAL_CHAR('-'); + print_hex_byte(ptr[i]); + SERIAL_CHAR(' '); + } + safe_delay(25); + SERIAL_CHAR('|'); // Point out non test bytes + for (uint8_t i = 0; i < 16; i++) { + char ccc = (char)ptr[i]; // cast to char before automatically casting to char on assignment, in case the compiler is broken + if (&ptr[i] >= (const char*)command_queue && &ptr[i] < (const char*)(command_queue + sizeof(command_queue))) { // Print out ASCII in the command buffer area + if (!WITHIN(ccc, ' ', 0x7E)) ccc = ' '; + } + else { // If not in the command buffer area, flag bytes that don't match the test byte + ccc = (ccc == TEST_BYTE) ? ' ' : '?'; + } + SERIAL_CHAR(ccc); + } + SERIAL_EOL(); + ptr += 16; + safe_delay(25); + idle(); + } + } + +void M100_dump_routine(const char * const title, const char *start, const char *end) { + SERIAL_ECHOLN(title); + // + // Round the start and end locations to produce full lines of output + // + start = (char*)((uint16_t) start & 0xFFF0); + end = (char*)((uint16_t) end | 0x000F); + dump_free_memory(start, end); +} + +#endif // M100_FREE_MEMORY_DUMPER + +/** + * M100 F + * Return the number of free bytes in the memory pool, + * with other vital statistics defining the pool. + */ +void free_memory_pool_report(char * const ptr, const int16_t size) { + int16_t max_cnt = -1, block_cnt = 0; + char *max_addr = NULL; + // Find the longest block of test bytes in the buffer + for (int16_t i = 0; i < size; i++) { + char *addr = ptr + i; + if (*addr == TEST_BYTE) { + const int16_t j = count_test_bytes(addr); + if (j > 8) { + SERIAL_ECHOPAIR("Found ", j); + SERIAL_ECHOLNPAIR(" bytes free at ", hex_address(addr)); + if (j > max_cnt) { + max_cnt = j; + max_addr = addr; + } + i += j; + block_cnt++; + } + } + } + if (block_cnt > 1) { + SERIAL_ECHOLNPGM("\nMemory Corruption detected in free memory area."); + SERIAL_ECHOPAIR("\nLargest free block is ", max_cnt); + SERIAL_ECHOLNPAIR(" bytes at ", hex_address(max_addr)); + } + SERIAL_ECHOLNPAIR("check_for_free_memory_corruption() = ", check_for_free_memory_corruption("M100 F ")); +} + +#if ENABLED(M100_FREE_MEMORY_CORRUPTOR) + /** + * M100 C + * Corrupt locations in the free memory pool and report the corrupt addresses. + * This is useful to check the correctness of the M100 D and the M100 F commands. + */ + void corrupt_free_memory(char *ptr, const uint16_t size) { + ptr += 8; + const uint16_t near_top = top_of_stack() - ptr - 250, // -250 to avoid interrupt activity that's altered the stack. + j = near_top / (size + 1); + + SERIAL_ECHOLNPGM("Corrupting free memory block.\n"); + for (uint16_t i = 1; i <= size; i++) { + char * const addr = ptr + i * j; + *addr = i; + SERIAL_ECHOPAIR("\nCorrupting address: ", hex_address(addr)); + } + SERIAL_EOL(); + } +#endif // M100_FREE_MEMORY_CORRUPTOR + +/** + * M100 I + * Init memory for the M100 tests. (Automatically applied on the first M100.) + */ +void init_free_memory(char *ptr, int16_t size) { + SERIAL_ECHOLNPGM("Initializing free memory block.\n\n"); + + size -= 250; // -250 to avoid interrupt activity that's altered the stack. + if (size < 0) { + SERIAL_ECHOLNPGM("Unable to initialize.\n"); + return; + } + + ptr += 8; // move a few bytes away from the heap just because we don't want + // to be altering memory that close to it. + memset(ptr, TEST_BYTE, size); + + SERIAL_ECHO(size); + SERIAL_ECHOLNPGM(" bytes of memory initialized.\n"); + + for (int16_t i = 0; i < size; i++) { + if (ptr[i] != TEST_BYTE) { + SERIAL_ECHOPAIR("? address : ", hex_address(ptr + i)); + SERIAL_ECHOLNPAIR("=", hex_byte(ptr[i])); + SERIAL_EOL(); + } + } +} + +/** + * M100: Free Memory Check + */ +void gcode_M100() { + SERIAL_ECHOPAIR("\n__brkval : ", hex_address(__brkval)); + SERIAL_ECHOPAIR("\n__bss_end : ", hex_address(&__bss_end)); + + char *ptr = END_OF_HEAP(), *sp = top_of_stack(); + + SERIAL_ECHOPAIR("\nstart of free space : ", hex_address(ptr)); + SERIAL_ECHOLNPAIR("\nStack Pointer : ", hex_address(sp)); + + // Always init on the first invocation of M100 + static bool m100_not_initialized = true; + if (m100_not_initialized || parser.seen('I')) { + m100_not_initialized = false; + init_free_memory(ptr, sp - ptr); + } + + #if ENABLED(M100_FREE_MEMORY_DUMPER) + if (parser.seen('D')) + return dump_free_memory(ptr, sp); + #endif + + if (parser.seen('F')) + return free_memory_pool_report(ptr, sp - ptr); + + #if ENABLED(M100_FREE_MEMORY_CORRUPTOR) + + if (parser.seen('C')) + return corrupt_free_memory(ptr, parser.value_int()); + + #endif +} + +int check_for_free_memory_corruption(const char * const title) { + SERIAL_ECHO(title); + + char *ptr = END_OF_HEAP(), *sp = top_of_stack(); + int n = sp - ptr; + + SERIAL_ECHOPAIR("\nfmc() n=", n); + SERIAL_ECHOPAIR("\n&__brkval: ", hex_address(&__brkval)); + SERIAL_ECHOPAIR("=", hex_address(__brkval)); + SERIAL_ECHOPAIR("\n__bss_end: ", hex_address(&__bss_end)); + SERIAL_ECHOPAIR(" sp=", hex_address(sp)); + + if (sp < ptr) { + SERIAL_ECHOPGM(" sp < Heap "); + // SET_INPUT_PULLUP(63); // if the developer has a switch wired up to their controller board + // safe_delay(5); // this code can be enabled to pause the display as soon as the + // while ( READ(63)) // malfunction is detected. It is currently defaulting to a switch + // idle(); // being on pin-63 which is unassigend and available on most controller + // safe_delay(20); // boards. + // while ( !READ(63)) + // idle(); + safe_delay(20); + #ifdef M100_FREE_MEMORY_DUMPER + M100_dump_routine(" Memory corruption detected with sp 8) { + // SERIAL_ECHOPAIR("Found ", j); + // SERIAL_ECHOLNPAIR(" bytes free at ", hex_address(ptr + i)); + i += j; + block_cnt++; + SERIAL_ECHOPAIR(" (", block_cnt); + SERIAL_ECHOPAIR(") found=", j); + SERIAL_ECHOPGM(" "); + } + } + } + SERIAL_ECHOPAIR(" block_found=", block_cnt); + + if (block_cnt != 1 || __brkval != 0x0000) + SERIAL_ECHOLNPGM("\nMemory Corruption detected in free memory area."); + + if (block_cnt == 0) // Make sure the special case of no free blocks shows up as an + block_cnt = -1; // error to the calling code! + + SERIAL_ECHOPGM(" return="); + if (block_cnt == 1) { + SERIAL_CHAR('0'); // if the block_cnt is 1, nothing has broken up the free memory + SERIAL_EOL(); // area and it is appropriate to say 'no corruption'. + return 0; + } + SERIAL_ECHOLNPGM("true"); + return block_cnt; +} + +#endif // M100_FREE_MEMORY_WATCHER + + diff --git a/trunk/Arduino/Marlin_1.1.6/Makefile b/trunk/Arduino/Marlin_1.1.6/Makefile new file mode 100644 index 00000000..150f0743 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/Makefile @@ -0,0 +1,544 @@ +# Sprinter Arduino Project Makefile +# +# Makefile Based on: +# Arduino 0011 Makefile +# Arduino adaptation by mellis, eighthave, oli.keller +# Marlin adaption by Daid +# +# This has been tested with Arduino 0022. +# +# This makefile allows you to build sketches from the command line +# without the Arduino environment (or Java). +# +# 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 +# might be /Applications/Arduino.app/Contents/Resources/Java). +# +# 2. Modify the line containing "UPLOAD_PORT" to refer to the filename +# representing the USB or serial connection to your Arduino board +# (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 +# 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 +# the speed lookup table with create_speed_lookuptable.py. +# +# 4. Type "make" and press enter to compile/verify your program. +# +# 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 +# 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 +# +# 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 +# +# If uploading doesn't work try adding the parameter "AVRDUDE_PROGRAMMER=wiring" or +# start upload manually (using stk500) like so: +# +# avrdude -C /root/arduino/hardware/tools/avr/etc/avrdude.conf -v -p m2560 -c stk500 \ +# -U flash:w:applet/Marlin.hex:i -P /dev/ttyUSB0 +# +# Or, try disconnecting USB to power down and then reconnecting before running avrdude. +# + +# This defines the board to compile for (see boards.h for your board's ID) +HARDWARE_MOTHERBOARD ?= 11 + +# Arduino source install directory, and version number +# On most linuxes this will be /usr/share/arduino +ARDUINO_INSTALL_DIR ?= ${HOME}/Arduino +ARDUINO_VERSION ?= 106 + +# You can optionally set a path to the avr-gcc tools. Requires a trailing slash. (ex: /usr/local/avr-gcc/bin) +AVR_TOOLS_PATH ?= + +#Programmer configuration +UPLOAD_RATE ?= 57600 +AVRDUDE_PROGRAMMER ?= arduino +# 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 . +BUILD_DIR ?= applet + +# This defines whether Liquid_TWI2 support will be built +LIQUID_TWI2 ?= 0 + +# this defines if Wire is needed +WIRE ?= 0 + +# this defines if U8GLIB is needed (may require RELOC_WORKAROUND) +U8GLIB ?= 1 + +# this defines whether to add a workaround for the avr-gcc relocation bug +# https://www.stix.id.au/wiki/AVR_relocation_truncations_workaround +RELOC_WORKAROUND ?= 1 + +############################################################################ +# Below here nothing should be changed... + +# Here the Arduino variant is selected by the board type +# HARDWARE_VARIANT = "arduino", "Sanguino", "Gen7", ... +# MCU = "atmega1280", "Mega2560", "atmega2560", "atmega644p", ... + +#Gen7 +ifeq ($(HARDWARE_MOTHERBOARD),10) +HARDWARE_VARIANT ?= Gen7 +MCU ?= atmega644 +F_CPU ?= 20000000 +else ifeq ($(HARDWARE_MOTHERBOARD),11) +HARDWARE_VARIANT ?= Gen7 +MCU ?= atmega644p +F_CPU ?= 20000000 +else ifeq ($(HARDWARE_MOTHERBOARD),12) +HARDWARE_VARIANT ?= Gen7 +MCU ?= atmega644p +F_CPU ?= 20000000 +else ifeq ($(HARDWARE_MOTHERBOARD),13) +HARDWARE_VARIANT ?= Gen7 +MCU ?= atmega1284p +F_CPU ?= 20000000 + +#RAMPS +else ifeq ($(HARDWARE_MOTHERBOARD),3) +HARDWARE_VARIANT ?= arduino +MCU ?= atmega2560 +else ifeq ($(HARDWARE_MOTHERBOARD),33) +HARDWARE_VARIANT ?= arduino +MCU ?= atmega2560 +else ifeq ($(HARDWARE_MOTHERBOARD),34) +HARDWARE_VARIANT ?= arduino +MCU ?= atmega2560 +else ifeq ($(HARDWARE_MOTHERBOARD),35) +HARDWARE_VARIANT ?= arduino +MCU ?= atmega2560 +else ifeq ($(HARDWARE_MOTHERBOARD),36) +HARDWARE_VARIANT ?= arduino +MCU ?= atmega2560 +else ifeq ($(HARDWARE_MOTHERBOARD),38) +HARDWARE_VARIANT ?= arduino +MCU ?= atmega2560 +else ifeq ($(HARDWARE_MOTHERBOARD),43) +HARDWARE_VARIANT ?= arduino +MCU ?= atmega2560 +else ifeq ($(HARDWARE_MOTHERBOARD),44) +HARDWARE_VARIANT ?= arduino +MCU ?= atmega2560 +else ifeq ($(HARDWARE_MOTHERBOARD),45) +HARDWARE_VARIANT ?= arduino +MCU ?= atmega2560 +else ifeq ($(HARDWARE_MOTHERBOARD),46) +HARDWARE_VARIANT ?= arduino +MCU ?= atmega2560 +else ifeq ($(HARDWARE_MOTHERBOARD),48) +HARDWARE_VARIANT ?= arduino +MCU ?= atmega2560 + +#Gen6 +else ifeq ($(HARDWARE_MOTHERBOARD),5) +HARDWARE_VARIANT ?= Gen6 +MCU ?= atmega644p +else ifeq ($(HARDWARE_MOTHERBOARD),51) +HARDWARE_VARIANT ?= Gen6 +MCU ?= atmega644p + +#Sanguinololu +else ifeq ($(HARDWARE_MOTHERBOARD),6) +HARDWARE_VARIANT ?= Sanguino +MCU ?= atmega644p +else ifeq ($(HARDWARE_MOTHERBOARD),62) +HARDWARE_VARIANT ?= Sanguino +MCU ?= atmega644p +else ifeq ($(HARDWARE_MOTHERBOARD),63) +HARDWARE_VARIANT ?= Sanguino +MCU ?= atmega644p +else ifeq ($(HARDWARE_MOTHERBOARD),65) +HARDWARE_VARIANT ?= Sanguino +MCU ?= atmega1284p +else ifeq ($(HARDWARE_MOTHERBOARD),66) +HARDWARE_VARIANT ?= Sanguino +MCU ?= atmega1284p +else ifeq ($(HARDWARE_MOTHERBOARD),69) +HARDWARE_VARIANT ?= Sanguino +MCU ?= atmega1284p + +#Ultimaker +else ifeq ($(HARDWARE_MOTHERBOARD),7) +HARDWARE_VARIANT ?= arduino +MCU ?= atmega2560 +else ifeq ($(HARDWARE_MOTHERBOARD),71) +HARDWARE_VARIANT ?= arduino +MCU ?= atmega1280 + +#Teensylu +else ifeq ($(HARDWARE_MOTHERBOARD),8) +HARDWARE_VARIANT ?= Teensy +MCU ?= at90usb1286 +else ifeq ($(HARDWARE_MOTHERBOARD),81) +HARDWARE_VARIANT ?= Teensy +MCU ?= at90usb1286 +else ifeq ($(HARDWARE_MOTHERBOARD),811) +HARDWARE_VARIANT ?= Teensy +MCU ?= at90usb1286 +else ifeq ($(HARDWARE_MOTHERBOARD),82) +HARDWARE_VARIANT ?= Teensy +MCU ?= at90usb646 +else ifeq ($(HARDWARE_MOTHERBOARD),83) +HARDWARE_VARIANT ?= Teensy +MCU ?= at90usb1286 +else ifeq ($(HARDWARE_MOTHERBOARD),84) +HARDWARE_VARIANT ?= Teensy +MCU ?= at90usb1286 + +#Gen3+ +else ifeq ($(HARDWARE_MOTHERBOARD),9) +HARDWARE_VARIANT ?= Sanguino +MCU ?= atmega644p + +#Gen3 Monolithic Electronics +else ifeq ($(HARDWARE_MOTHERBOARD),22) +HARDWARE_VARIANT ?= Sanguino +MCU ?= atmega644p + +#Megatronics +else ifeq ($(HARDWARE_MOTHERBOARD),70) +HARDWARE_VARIANT ?= arduino +MCU ?= atmega2560 + +#Alpha OMCA board +else ifeq ($(HARDWARE_MOTHERBOARD),90) +HARDWARE_VARIANT ?= SanguinoA +MCU ?= atmega644 + +#Final OMCA board +else ifeq ($(HARDWARE_MOTHERBOARD),91) +HARDWARE_VARIANT ?= Sanguino +MCU ?= atmega644p + +#Rambo +else ifeq ($(HARDWARE_MOTHERBOARD),301) +HARDWARE_VARIANT ?= arduino +MCU ?= atmega2560 + +# Azteeg +else ifeq ($(HARDWARE_MOTHERBOARD),67) +HARDWARE_VARIANT ?= arduino +MCU ?= atmega2560 +else ifeq ($(HARDWARE_MOTHERBOARD),68) +HARDWARE_VARIANT ?= arduino +MCU ?= atmega2560 + +endif + +# Be sure to regenerate speed_lookuptable.h with create_speed_lookuptable.py +# if you are setting this to something other than 16MHz +# Set to 16Mhz if not yet set. +F_CPU ?= 16000000 + +# Arduino contained the main source code for the Arduino +# Libraries, the "hardware variant" are for boards +# that derives from that, and their source are present in +# the main Marlin source directory + +TARGET = $(notdir $(CURDIR)) + +# VPATH tells make to look into these directory for source files, +# there is no need to specify explicit pathnames as long as the +# directory is added here + +VPATH = . +VPATH += $(BUILD_DIR) +VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/cores/arduino + +VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/SPI +VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/SPI/src +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 +endif +ifeq ($(WIRE), 1) +VPATH += $(ARDUINO_INSTALL_DIR)/libraries/Wire +VPATH += $(ARDUINO_INSTALL_DIR)/libraries/Wire/utility +endif +ifeq ($(NEOPIXEL), 1) +VPATH += $(ARDUINO_INSTALL_DIR)/libraries/Adafruit_NeoPixel +endif +ifeq ($(U8GLIB), 1) +VPATH += $(ARDUINO_INSTALL_DIR)/libraries/U8glib +VPATH += $(ARDUINO_INSTALL_DIR)/libraries/U8glib/utility +endif + +ifeq ($(HARDWARE_VARIANT), arduino) +HARDWARE_SUB_VARIANT ?= mega +VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/variants/$(HARDWARE_SUB_VARIANT) +else +ifeq ($(HARDWARE_VARIANT), Sanguino) +VPATH += $(HARDWARE_DIR)/marlin/avr/variants/sanguino +else +HARDWARE_SUB_VARIANT ?= standard +VPATH += $(HARDWARE_DIR)/$(HARDWARE_VARIANT)/variants/$(HARDWARE_SUB_VARIANT) +endif +endif +SRC = wiring.c \ + wiring_analog.c wiring_digital.c \ + wiring_pulse.c \ + wiring_shift.c WInterrupts.c hooks.c +ifeq ($(HARDWARE_VARIANT), Teensy) +SRC = wiring.c +VPATH += $(ARDUINO_INSTALL_DIR)/hardware/teensy/cores/teensy +endif +CXXSRC = WMath.cpp WString.cpp Print.cpp Marlin_main.cpp \ + MarlinSerial.cpp Sd2Card.cpp SdBaseFile.cpp SdFatUtil.cpp \ + SdFile.cpp SdVolume.cpp planner.cpp stepper.cpp \ + temperature.cpp cardreader.cpp configuration_store.cpp \ + watchdog.cpp SPI.cpp servo.cpp Tone.cpp ultralcd.cpp digipot_mcp4451.cpp \ + dac_mcp4728.cpp vector_3.cpp least_squares_fit.cpp endstops.cpp stopwatch.cpp utility.cpp \ + printcounter.cpp nozzle.cpp serial.cpp gcode.cpp Max7219_Debug_LEDs.cpp +ifeq ($(NEOPIXEL), 1) +CXXSRC += Adafruit_NeoPixel.cpp +endif +ifeq ($(LIQUID_TWI2), 0) +CXXSRC += LiquidCrystal.cpp +else +SRC += twi.c +CXXSRC += Wire.cpp LiquidTWI2.cpp +endif + +ifeq ($(WIRE), 1) +SRC += twi.c +CXXSRC += Wire.cpp +endif + +ifeq ($(U8GLIB), 1) +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_data.c +endif + +ifeq ($(RELOC_WORKAROUND), 1) +LD_PREFIX=-nodefaultlibs +LD_SUFFIX=-lm -lgcc -lc -lgcc +endif + +#Check for Arduino 1.0.0 or higher and use the correct source files for that version +ifeq ($(shell [ $(ARDUINO_VERSION) -ge 100 ] && echo true), true) +CXXSRC += main.cpp +else +SRC += pins_arduino.c main.c +endif + +FORMAT = ihex + +# Name of this Makefile (used for "make depend"). +MAKEFILE = Makefile + +# Debugging format. +# Native formats for AVR-GCC's -g are stabs [default], or dwarf-2. +# AVR (extended) COFF requires stabs, plus an avr-objcopy run. +DEBUG = stabs + +OPT = s + +DEFINES ?= + +# Program settings +CC = $(AVR_TOOLS_PATH)avr-gcc +CXX = $(AVR_TOOLS_PATH)avr-g++ +OBJCOPY = $(AVR_TOOLS_PATH)avr-objcopy +OBJDUMP = $(AVR_TOOLS_PATH)avr-objdump +AR = $(AVR_TOOLS_PATH)avr-ar +SIZE = $(AVR_TOOLS_PATH)avr-size +NM = $(AVR_TOOLS_PATH)avr-nm +AVRDUDE = avrdude +REMOVE = rm -f +MV = mv -f + +# Place -D or -U options here +CDEFS = -DF_CPU=$(F_CPU) ${addprefix -D , $(DEFINES)} +CXXDEFS = $(CDEFS) + +ifeq ($(HARDWARE_VARIANT), Teensy) +CDEFS += -DUSB_SERIAL +SRC += usb.c pins_teensy.c +CXXSRC += usb_api.cpp +endif + +# Add all the source directories as include directories too +CINCS = ${addprefix -I ,${VPATH}} +CXXINCS = ${addprefix -I ,${VPATH}} + +# Compiler flag to set the C/CPP Standard level. +CSTANDARD = -std=gnu99 +CXXSTANDARD = -std=gnu++11 +CDEBUG = -g$(DEBUG) +CWARN = -Wall -Wstrict-prototypes +CTUNING = -funsigned-char -funsigned-bitfields -fpack-struct \ + -fshort-enums -w -ffunction-sections -fdata-sections \ + -flto \ + -DARDUINO=$(ARDUINO_VERSION) +ifneq ($(HARDWARE_MOTHERBOARD),) +CTUNING += -DMOTHERBOARD=${HARDWARE_MOTHERBOARD} +endif +#CEXTRA = -Wa,-adhlns=$(<:.c=.lst) +CEXTRA = -fno-use-cxa-atexit -fno-threadsafe-statics + +CFLAGS := $(CDEBUG) $(CDEFS) $(CINCS) -O$(OPT) $(CWARN) $(CEXTRA) $(CTUNING) $(CSTANDARD) +CXXFLAGS := $(CDEFS) $(CINCS) -O$(OPT) -Wall $(CEXTRA) $(CTUNING) $(CXXSTANDARD) +#ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs +LDFLAGS = -lm + + +# Programming support using avrdude. Settings and variables. +AVRDUDE_PORT = $(UPLOAD_PORT) +AVRDUDE_WRITE_FLASH = -Uflash:w:$(BUILD_DIR)/$(TARGET).hex:i +ifeq ($(shell uname -s), Linux) +AVRDUDE_CONF = /etc/avrdude/avrdude.conf +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) \ + -b$(UPLOAD_RATE) + +# Define all object files. +OBJ = ${patsubst %.c, $(BUILD_DIR)/%.o, ${SRC}} +OBJ += ${patsubst %.cpp, $(BUILD_DIR)/%.o, ${CXXSRC}} +OBJ += ${patsubst %.S, $(BUILD_DIR)/%.o, ${ASRC}} + +# Define all listing files. +LST = $(ASRC:.S=.lst) $(CXXSRC:.cpp=.lst) $(SRC:.c=.lst) + +# Combine all necessary flags and optional flags. +# Add target processor to flags. +ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) +ALL_CXXFLAGS = -mmcu=$(MCU) $(CXXFLAGS) +ALL_ASFLAGS = -mmcu=$(MCU) -x assembler-with-cpp $(ASFLAGS) + +# set V=1 (eg, "make V=1") to print the full commands etc. +ifneq ($V,1) + Pecho=@echo + P=@ +else + Pecho=@: + P= +endif + +# Default target. +all: sizeafter + +build: $(BUILD_DIR) elf hex + +# Creates the object directory +$(BUILD_DIR): + $P mkdir -p $(BUILD_DIR) + +elf: $(BUILD_DIR)/$(TARGET).elf +hex: $(BUILD_DIR)/$(TARGET).hex +eep: $(BUILD_DIR)/$(TARGET).eep +lss: $(BUILD_DIR)/$(TARGET).lss +sym: $(BUILD_DIR)/$(TARGET).sym + +# Program the device. +# Do not try to reset an Arduino if it's not one +upload: $(BUILD_DIR)/$(TARGET).hex +ifeq (${AVRDUDE_PROGRAMMER}, arduino) + stty hup < $(UPLOAD_PORT); true +endif + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) +ifeq (${AVRDUDE_PROGRAMMER}, arduino) + stty -hup < $(UPLOAD_PORT); true +endif + + # Display size of file. +HEXSIZE = $(SIZE) --target=$(FORMAT) $(BUILD_DIR)/$(TARGET).hex +ELFSIZE = $(SIZE) --mcu=$(MCU) -C $(BUILD_DIR)/$(TARGET).elf; \ + $(SIZE) $(BUILD_DIR)/$(TARGET).elf +sizebefore: + $P if [ -f $(BUILD_DIR)/$(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(HEXSIZE); echo; fi + +sizeafter: build + $P if [ -f $(BUILD_DIR)/$(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); echo; fi + + +# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB. +COFFCONVERT=$(OBJCOPY) --debugging \ + --change-section-address .data-0x800000 \ + --change-section-address .bss-0x800000 \ + --change-section-address .noinit-0x800000 \ + --change-section-address .eeprom-0x810000 + + +coff: $(BUILD_DIR)/$(TARGET).elf + $(COFFCONVERT) -O coff-avr $(BUILD_DIR)/$(TARGET).elf $(TARGET).cof + + +extcoff: $(TARGET).elf + $(COFFCONVERT) -O coff-ext-avr $(BUILD_DIR)/$(TARGET).elf $(TARGET).cof + + +.SUFFIXES: .elf .hex .eep .lss .sym +.PRECIOUS: .o + +.elf.hex: + $(Pecho) " COPY $@" + $P $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@ + +.elf.eep: + -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ + --change-section-lma .eeprom=0 -O $(FORMAT) $< $@ + +# Create extended listing file from ELF output file. +.elf.lss: + $(OBJDUMP) -h -S $< > $@ + +# Create a symbol table from ELF output file. +.elf.sym: + $(NM) -n $< > $@ + + # Link: create ELF output file from library. +$(BUILD_DIR)/$(TARGET).elf: $(OBJ) Configuration.h + $(Pecho) " CXX $@" + $P $(CC) $(LD_PREFIX) $(ALL_CXXFLAGS) -Wl,--gc-sections,--relax -o $@ -L. $(OBJ) $(LDFLAGS) $(LD_SUFFIX) + +$(BUILD_DIR)/%.o: %.c Configuration.h Configuration_adv.h $(MAKEFILE) + $(Pecho) " CC $<" + $P $(CC) -MMD -c $(ALL_CFLAGS) $< -o $@ + +$(BUILD_DIR)/%.o: $(BUILD_DIR)/%.cpp Configuration.h Configuration_adv.h $(MAKEFILE) + $(Pecho) " CXX $<" + $P $(CXX) -MMD -c $(ALL_CXXFLAGS) $< -o $@ + +$(BUILD_DIR)/%.o: %.cpp Configuration.h Configuration_adv.h $(MAKEFILE) + $(Pecho) " CXX $<" + $P $(CXX) -MMD -c $(ALL_CXXFLAGS) $< -o $@ + + +# Target: clean project. +clean: + $(Pecho) " RM $(BUILD_DIR)/*" + $P $(REMOVE) $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).eep $(BUILD_DIR)/$(TARGET).cof $(BUILD_DIR)/$(TARGET).elf \ + $(BUILD_DIR)/$(TARGET).map $(BUILD_DIR)/$(TARGET).sym $(BUILD_DIR)/$(TARGET).lss $(BUILD_DIR)/$(TARGET).cpp \ + $(OBJ) $(LST) $(SRC:.c=.s) $(SRC:.c=.d) $(CXXSRC:.cpp=.s) $(CXXSRC:.cpp=.d) + $(Pecho) " RMDIR $(BUILD_DIR)/" + $P rm -rf $(BUILD_DIR) + + +.PHONY: all build elf hex eep lss sym program coff extcoff clean depend sizebefore sizeafter + +# Automaticaly include the dependency files created by gcc +-include ${wildcard $(BUILD_DIR)/*.d} diff --git a/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/.gitattributes b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/.gitattributes new file mode 100644 index 00000000..d511b4ea --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/.gitattributes @@ -0,0 +1,20 @@ +# Set the default behavior, in case people don't have core.autocrlf set. +* text=auto + +# Files with Unix line endings +*.c text eol=lf +*.cpp text eol=lf +*.h text eol=lf +*.ino text eol=lf +*.py text eol=lf +*.sh text eol=lf +*.scad text eol=lf + +# Files with native line endings +# *.sln text + +# Binary files +*.png binary +*.jpg binary +*.fon binary + diff --git a/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/.github/issue_template.md b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/.github/issue_template.md new file mode 100644 index 00000000..17f680d5 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/.github/issue_template.md @@ -0,0 +1,36 @@ +Thank you for submitting your feedback to the Marlin project. +Please use one of the templates below to fill out this box. + +------------------------------------------------------------ +### Feature Request +Please put [FR] in the issue title: `[FR] Add-on that goes 'ping'` + +------------------------------------------------------------ +### Compile Error +When I compile with `FEATURE_X` I get an error: +``` +Paste_the_error_text_here +``` + +------------------------------------------------------------ +### Bug Report +- Description: --- +- Expected behaviour: --- +- Actual behaviour: --- +- Steps to reproduce: + - Do this + - Do that + +Attach a ZIP of `Configuration.h` and `Configuration_adv.h` by dropping here. + +------------------------------------------------------------ +### Bug Report Tips +- When troubleshooting, use `M502` followed by `M500` to reset EEPROM to defaults. +- Use `DEBUG_LEVELING_FEATURE` with `M111 S247` for detailed logging of homing/leveling. +- Format text with: **bold**, _italic_, `code`. +- Format C++ with three backticks, plus "cpp": +```cpp +void my_function(bool do_it) { + // Hold this spot +} +``` diff --git a/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/.gitignore b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/.gitignore new file mode 100644 index 00000000..8c705382 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/.gitignore @@ -0,0 +1,141 @@ +# +# Marlin 3D Printer Firmware +# Copyright (C) 2017 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] +# +# Based on Sprinter and grbl. +# Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +# Our automatic versioning scheme generates the following file +# NEVER put it in the repository +_Version.h + +# +# OS +# +applet/ +*.DS_Store + + +# +# Misc +# +*~ +*.orig +*.rej +*.bak +*.idea +*.s +*.i +*.ii +*.swp +tags + +# +# C++ +# +# Compiled Object files +*.slo +*.lo +*.o +*.obj +*.ino.cpp + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod +*.smod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app + + +# +# C +# +# Object files +*.o +*.ko +*.obj +*.elf + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su + +# PlatformIO files/dirs +.pio* +lib/readme.txt + +#Visual Studio +*.sln +*.vcxproj +*.vcxproj.filters +Marlin/Release/ +Marlin/Debug/ +Marlin/__vm/ +Marlin/.vs/ + +#VScode +.vscode + +#cmake +CMakeLists.txt +Marlin/CMakeLists.txt +CMakeListsPrivate.txt + +#CLion +cmake-build-* diff --git a/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/.travis.yml b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/.travis.yml new file mode 100644 index 00000000..93a365a7 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/.travis.yml @@ -0,0 +1,359 @@ +dist: trusty +sudo: true + # +language: c + # +notifications: + email: false + # +before_install: + # + # Fetch the tag information for the current branch + - git fetch origin --tags + # + # Publish the buildroot script folder + - chmod +x ${TRAVIS_BUILD_DIR}/buildroot/bin/* + - export PATH=${TRAVIS_BUILD_DIR}/buildroot/bin/:${PATH} + # + # Start fb X server + - "/sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_1.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :1 -ac -screen 0 1280x1024x16" + - sleep 3 + - export DISPLAY=:1.0 + # +install: + # + # Install arduino 1.6.10 + - wget http://downloads-02.arduino.cc/arduino-1.6.10-linux64.tar.xz + - tar xf arduino-1.6.10-linux64.tar.xz + - sudo mv arduino-1.6.10 /usr/local/share/arduino + - ln -s /usr/local/share/arduino/arduino ${TRAVIS_BUILD_DIR}/buildroot/bin/arduino + # + # Install: LiquidCrystal_I2C library + - git clone https://github.com/kiyoshigawa/LiquidCrystal_I2C.git + - mv LiquidCrystal_I2C/LiquidCrystal_I2C /usr/local/share/arduino/libraries/LiquidCrystal_I2C + # + # Install: LiquidTWI2 library + - git clone https://github.com/lincomatic/LiquidTWI2.git + - sudo mv LiquidTWI2 /usr/local/share/arduino/libraries/LiquidTWI2 + # + # Install: Monochrome Graphics Library for LCDs and OLEDs + - git clone https://github.com/olikraus/U8glib_Arduino.git + - sudo mv U8glib_Arduino /usr/local/share/arduino/libraries/U8glib + # + # Install: L6470 Stepper Motor Driver library + # - git clone https://github.com/ameyer/Arduino-L6470.git + # - sudo mv Arduino-L6470/L6470 /usr/local/share/arduino/libraries/L6470 + # + # Install: TMC26X Stepper Motor Controller library + # - git clone https://github.com/trinamic/TMC26XStepper.git + # - sudo mv TMC26XStepper /usr/local/share/arduino/libraries/TMC26XStepper + # + # Install: TMC2130 Stepper Motor Controller library + - git clone https://github.com/teemuatlut/TMC2130Stepper.git + - sudo mv TMC2130Stepper /usr/local/share/arduino/libraries/TMC2130Stepper + # + # Install: Adafruit Neopixel library + - git clone https://github.com/adafruit/Adafruit_NeoPixel.git + - sudo mv Adafruit_NeoPixel /usr/local/share/arduino/libraries/Adafruit_NeoPixel + # +before_script: + # + # Change current working directory to the build dir + - cd ${TRAVIS_BUILD_DIR} + # + # Generate custom version include + - generate_version_header_for_marlin ${TRAVIS_BUILD_DIR}/Marlin + - cat ${TRAVIS_BUILD_DIR}/Marlin/_Version.h + # +script: + # + # Backup Configuration.h, Configuration_adv.h, and pins_RAMPS.h + # + - cp Marlin/Configuration.h Marlin/Configuration.h.backup + - cp Marlin/Configuration_adv.h Marlin/Configuration_adv.h.backup + - cp Marlin/pins_RAMPS.h Marlin/pins_RAMPS.h.backup + # + # Build with the default configurations + # + - build_marlin + # + # 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. + # + - 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 1 + - opt_enable PIDTEMPBED FIX_MOUNTED_PROBE Z_SAFE_HOMING ARC_P_CIRCLES CNC_WORKSPACE_PLANES + - opt_enable REPRAP_DISCOUNT_SMART_CONTROLLER SDSUPPORT EEPROM_SETTINGS + - opt_enable BLINKM PCA9632 RGB_LED NEOPIXEL_RGBW_LED + - opt_enable AUTO_BED_LEVELING_LINEAR Z_MIN_PROBE_REPEATABILITY_TEST DEBUG_LEVELING_FEATURE + - opt_enable_adv FWRETRACT MAX7219_DEBUG + - opt_set ABL_GRID_POINTS_X 16 + - opt_set ABL_GRID_POINTS_Y 16 + - opt_set_adv FANMUX0_PIN 53 + - build_marlin + # + # Test a probeless build of AUTO_BED_LEVELING_UBL + # + - restore_configs + - opt_enable AUTO_BED_LEVELING_UBL UBL_G26_MESH_EDITING ENABLE_LEVELING_FADE_HEIGHT EEPROM_SETTINGS G3D_PANEL + - opt_enable_adv CUSTOM_USER_MENUS I2C_POSITION_ENCODERS BABYSTEPPING + - build_marlin + # + # And with a probe... + # + - opt_enable FIX_MOUNTED_PROBE + - build_marlin + # + # Test a Sled Z Probe + # ...with AUTO_BED_LEVELING_LINEAR, DEBUG_LEVELING_FEATURE, EEPROM_SETTINGS, and EEPROM_CHITCHAT + # + - restore_configs + - opt_enable Z_PROBE_SLED AUTO_BED_LEVELING_LINEAR DEBUG_LEVELING_FEATURE EEPROM_SETTINGS EEPROM_CHITCHAT + - build_marlin + # + # Test a Servo Probe + # ...with AUTO_BED_LEVELING_3POINT, DEBUG_LEVELING_FEATURE, EEPROM_SETTINGS, EEPROM_CHITCHAT, EXTENDED_CAPABILITIES_REPORT, and AUTO_REPORT_TEMPERATURES + # + - restore_configs + - opt_enable NUM_SERVOS Z_ENDSTOP_SERVO_NR Z_SERVO_ANGLES DEACTIVATE_SERVOS_AFTER_MOVE + - opt_set NUM_SERVOS 1 + - opt_enable AUTO_BED_LEVELING_3POINT DEBUG_LEVELING_FEATURE EEPROM_SETTINGS EEPROM_CHITCHAT + - opt_enable_adv EXTENDED_CAPABILITIES_REPORT AUTO_REPORT_TEMPERATURES AUTOTEMP G38_PROBE_TARGET + - build_marlin + # + # Test MESH_BED_LEVELING feature, with LCD + # + - restore_configs + - opt_enable MESH_BED_LEVELING MESH_G28_REST_ORIGIN LCD_BED_LEVELING ULTIMAKERCONTROLLER + - build_marlin + # + # Test PROBE_MANUALLY feature, with LCD support, + # EEPROM_SETTINGS, EEPROM_CHITCHAT, M100_FREE_MEMORY_WATCHER, + # INCH_MODE_SUPPORT, TEMPERATURE_UNITS_SUPPORT + # + - restore_configs + - opt_set MOTHERBOARD BOARD_MINIRAMBO + - opt_enable PROBE_MANUALLY AUTO_BED_LEVELING_BILINEAR LCD_BED_LEVELING ULTIMAKERCONTROLLER + - opt_enable EEPROM_SETTINGS EEPROM_CHITCHAT M100_FREE_MEMORY_WATCHER M100_FREE_MEMORY_DUMPER M100_FREE_MEMORY_CORRUPTOR INCH_MODE_SUPPORT TEMPERATURE_UNITS_SUPPORT + - build_marlin + # + # Test 5 extruders on AZTEEG_X3_PRO (can use any board with >=5 extruders defined) + # Include a test for LIN_ADVANCE here also + # + - opt_set MOTHERBOARD BOARD_AZTEEG_X3_PRO + - opt_set EXTRUDERS 5 + - opt_set TEMP_SENSOR_1 1 + - opt_set TEMP_SENSOR_2 5 + - opt_set TEMP_SENSOR_3 20 + - opt_set TEMP_SENSOR_4 999 + - opt_set TEMP_SENSOR_BED 1 + - opt_enable_adv LIN_ADVANCE + - build_marlin + # + # Mixing Extruder with 5 steppers + # + - restore_configs + - opt_set MOTHERBOARD BOARD_AZTEEG_X3_PRO + - opt_enable MIXING_EXTRUDER + - opt_set MIXING_STEPPERS 5 + - build_marlin + # + # Test DUAL_X_CARRIAGE + # + - restore_configs + - opt_set MOTHERBOARD BOARD_RUMBA + - opt_set EXTRUDERS 2 + - opt_set TEMP_SENSOR_1 1 + - opt_enable USE_XMAX_PLUG + - opt_enable_adv DUAL_X_CARRIAGE + - build_marlin + # + # Test SPEAKER with BOARD_BQ_ZUM_MEGA_3D and BQ_LCD_SMART_CONTROLLER + # + - restore_configs + - opt_set MOTHERBOARD BOARD_BQ_ZUM_MEGA_3D + - opt_set LCD_FEEDBACK_FREQUENCY_DURATION_MS 10 + - opt_set LCD_FEEDBACK_FREQUENCY_HZ 100 + - opt_enable BQ_LCD_SMART_CONTROLLER SPEAKER + # + # Test SWITCHING_EXTRUDER + # + - restore_configs + - opt_set MOTHERBOARD BOARD_RUMBA + - opt_set EXTRUDERS 2 + - opt_enable NUM_SERVOS + - opt_set NUM_SERVOS 1 + - opt_set TEMP_SENSOR_1 1 + - opt_enable SWITCHING_EXTRUDER ULTIMAKERCONTROLLER + - build_marlin + # + # Test MINIRAMBO for PWM_MOTOR_CURRENT + # ULTIMAKERCONTROLLER, FILAMENT_LCD_DISPLAY, FILAMENT_WIDTH_SENSOR, + # PRINTCOUNTER, NOZZLE_PARK_FEATURE, NOZZLE_CLEAN_FEATURE, PCA9632, + # Z_DUAL_STEPPER_DRIVERS, Z_DUAL_ENDSTOPS, BEZIER_CURVE_SUPPORT, EXPERIMENTAL_I2CBUS, + # ADVANCED_PAUSE_FEATURE, PARK_HEAD_ON_PAUSE, LCD_INFO_MENU, + # + - restore_configs + - opt_enable ULTIMAKERCONTROLLER FILAMENT_LCD_DISPLAY FILAMENT_WIDTH_SENSOR SDSUPPORT + - opt_enable PRINTCOUNTER NOZZLE_PARK_FEATURE NOZZLE_CLEAN_FEATURE PCA9632 + - opt_enable_adv Z_DUAL_STEPPER_DRIVERS Z_DUAL_ENDSTOPS BEZIER_CURVE_SUPPORT EXPERIMENTAL_I2CBUS + - opt_set_adv I2C_SLAVE_ADDRESS 63 + - opt_enable_adv ADVANCED_PAUSE_FEATURE PARK_HEAD_ON_PAUSE LCD_INFO_MENU + - pins_set RAMPS X_MAX_PIN -1 + - opt_set_adv Z2_MAX_PIN 2 + - build_marlin + # + # Enable COREXY + # + - restore_configs + - opt_enable COREXY + - build_marlin + # + # Enable COREYX (swapped) + # + #- restore_configs + #- opt_enable COREYX + #- build_marlin + # + # + ######## Other Standard LCD/Panels ############## + # + # ULTRA_LCD + # + - restore_configs + - opt_enable ULTRA_LCD + - build_marlin + # + # DOGLCD + # + - restore_configs + - opt_enable DOGLCD + - build_marlin + # + # MAKRPANEL + # Needs to use Melzi and Sanguino hardware + # + #- restore_configs + #- opt_enable MAKRPANEL + #- build_marlin + # + # REPRAP_DISCOUNT_SMART_CONTROLLER, SDSUPPORT, BABYSTEPPING, RIGIDBOARD_V2, and DAC_MOTOR_CURRENT_DEFAULT + # + - restore_configs + - opt_set MOTHERBOARD BOARD_RIGIDBOARD_V2 + - opt_enable REPRAP_DISCOUNT_SMART_CONTROLLER SDSUPPORT BABYSTEPPING DAC_MOTOR_CURRENT_DEFAULT + - build_marlin + # + # G3D_PANEL with SDCARD_SORT_ALPHA and STATUS_MESSAGE_SCROLLING + # + - restore_configs + - opt_enable G3D_PANEL SDSUPPORT + - opt_enable_adv SDCARD_SORT_ALPHA STATUS_MESSAGE_SCROLLING + - opt_set_adv SDSORT_GCODE true + - opt_set_adv SDSORT_USES_RAM true + - opt_set_adv SDSORT_USES_STACK true + - opt_set_adv SDSORT_CACHE_NAMES true + - build_marlin + # + # REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER with SDCARD_SORT_ALPHA and STATUS_MESSAGE_SCROLLING + # + - restore_configs + - opt_enable REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER SDSUPPORT + - opt_enable_adv SDCARD_SORT_ALPHA STATUS_MESSAGE_SCROLLING + - build_marlin + # + # REPRAPWORLD_KEYPAD + # + # Cant find configuration details to get it to compile + #- restore_configs + #- opt_enable ULTRA_LCD REPRAPWORLD_KEYPAD REPRAPWORLD_KEYPAD_MOVE_STEP + #- build_marlin + # + # RA_CONTROL_PANEL + # + - restore_configs + - opt_enable RA_CONTROL_PANEL PINS_DEBUGGING + - build_marlin + # + ######## I2C LCD/PANELS ############## + # + # !!!ATTENTION!!! + # Most I2C configurations are failing at the moment because they require + # a different Liquid Crystal library "LiquidTWI2". + # + # LCD_I2C_SAINSMART_YWROBOT + # + #- restore_configs + #- opt_enable LCD_I2C_SAINSMART_YWROBOT + #- build_marlin + # + # LCD_I2C_PANELOLU2 + # + #- restore_configs + #- opt_enable LCD_I2C_PANELOLU2 + #- build_marlin + # + # LCD_I2C_VIKI + # + #- restore_configs + #- opt_enable LCD_I2C_VIKI + #- build_marlin + # + # LCM1602 + # + - restore_configs + - opt_enable LCM1602 + - build_marlin + # + # + ######## Example Configurations ############## + # + # BQ Hephestos 2 + #- restore_configs + #- use_example_configs Hephestos_2 + #- build_marlin + # + # Delta Config (generic) + ABL bilinear + PROBE_MANUALLY + - use_example_configs delta/generic + - opt_enable REPRAP_DISCOUNT_SMART_CONTROLLER DELTA_CALIBRATION_MENU AUTO_BED_LEVELING_BILINEAR PROBE_MANUALLY + - build_marlin + # + # Delta Config (generic) + UBL + ALLEN_KEY + OLED_PANEL_TINYBOY2 + EEPROM_SETTINGS + # + - use_example_configs delta/generic + - opt_disable DISABLE_MIN_ENDSTOPS + - opt_enable AUTO_BED_LEVELING_UBL Z_PROBE_ALLEN_KEY EEPROM_SETTINGS EEPROM_CHITCHAT OLED_PANEL_TINYBOY2 + - build_marlin + # + # Delta Config (FLSUN AC because it's complex) + # + - use_example_configs delta/FLSUN/auto_calibrate + - build_marlin + # + # Makibox Config need to check board type for Teensy++ 2.0 + # + #- use_example_configs makibox + #- build_marlin + # + # SCARA with TMC2130 + # + - use_example_configs SCARA + - opt_enable AUTO_BED_LEVELING_BILINEAR FIX_MOUNTED_PROBE USE_ZMIN_PLUG EEPROM_SETTINGS EEPROM_CHITCHAT ULTIMAKERCONTROLLER + - opt_enable_adv HAVE_TMC2130 X_IS_TMC2130 Y_IS_TMC2130 Z_IS_TMC2130 + - opt_enable_adv AUTOMATIC_CURRENT_CONTROL STEALTHCHOP HYBRID_THRESHOLD SENSORLESS_HOMING + - build_marlin + # + # tvrrug Config need to check board type for sanguino atmega644p + # + #- use_example_configs tvrrug/Round2 + #- build_marlin + # + # + ######## Board Types ############# + # + # To be added in nightly test branch + # diff --git a/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/LICENSE b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/LICENSE new file mode 100644 index 00000000..f27031ae --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/LICENSE @@ -0,0 +1,677 @@ + + + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + 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. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + {project} Copyright (C) {year} {fullname} + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + 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/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/README.md b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/README.md new file mode 100644 index 00000000..af5d9732 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/README.md @@ -0,0 +1,86 @@ +# Marlin 3D Printer Firmware + + +## Marlin 1.1 + +Marlin 1.1 represents an evolutionary leap over Marlin 1.0.2. It is the result of over two years of effort by several volunteers around the world who have paid meticulous and sometimes obsessive attention to every detail. For this release we focused on code quality, performance, stability, and overall user experience. Several new features have also been added, many of which require no extra hardware. + +For complete Marlin documentation click over to the [Marlin Homepage ](http://marlinfw.org/), where you will find in-depth articles, how-to videos, and tutorials on every aspect of Marlin, as the site develops. For release notes, see the [Releases](https://github.com/MarlinFirmware/Marlin/releases) page. + +## Stable Release Branch + +This Release branch contains the latest tagged version of Marlin (currently 1.1.6 – October 2017). + +Previous releases of Marlin include [1.0.2-2](https://github.com/MarlinFirmware/Marlin/tree/1.0.2-2) (December 2016) and [1.0.1](https://github.com/MarlinFirmware/Marlin/tree/1.0.1) (December 2014). Any version of Marlin prior to 1.0.1 (when we started tagging versions) can be collectively referred to as Marlin 1.0.0. + +## Contributing to Marlin + +Click on the [Issue Queue](https://github.com/MarlinFirmware/Marlin/issues) and [Pull Requests](https://github.com/MarlinFirmware/Marlin/pulls) links above at any time to see what we're currently working on. + +To submit patches and new features for Marlin 1.1 check out the [bugfix-1.1.x](https://github.com/MarlinFirmware/Marlin/tree/bugfix-1.1.x) branch, add your commits, and submit a Pull Request back to the `bugfix-1.1.x` branch. Periodically that branch will form the basis for the next minor release. + +Note that our "bugfix" branch will always contain the latest patches to the current release version. These patches may not be widely tested. As always, when using "nightly" builds of Marlin, proceed with full caution. + +## Current Status: In Development + +Marlin development has reached an important milestone with its first stable release in over 2 years. During this period we focused on cleaning up the code and making it more modern, consistent, readable, and sensible. + +## Future Development + +Marlin 1.1 is the last "flat" version of Marlin! + +Arduino IDE now has support for folder hierarchies, so Marlin 1.2 will have a [hierarchical file structure](https://github.com/MarlinFirmware/Marlin/tree/breakup-marlin-idea). Marlin's newly reorganized code will be easier to work with and form a stronger starting-point as we get into [32-bit CPU support](https://github.com/MarlinFirmware/Marlin/tree/32-Bit-RCBugFix-new) and the Hardware Access Layer (HAL). + +[![Coverity Scan Build Status](https://scan.coverity.com/projects/2224/badge.svg)](https://scan.coverity.com/projects/2224) +[![Travis Build Status](https://travis-ci.org/MarlinFirmware/Marlin.svg)](https://travis-ci.org/MarlinFirmware/Marlin) + +## Marlin Resources + +- [Marlin Home Page](http://marlinfw.org/) - The Marlin Documentation Project. Join us! +- [RepRap.org Wiki Page](http://reprap.org/wiki/Marlin) - An overview of Marlin and its role in RepRap. +- [Marlin Firmware Forum](http://forums.reprap.org/list.php?415) - Find help with configuration, get up and running. +- [@MarlinFirmware](https://twitter.com/MarlinFirmware) on Twitter - Follow for news, release alerts, and tips & tricks. (Maintained by [@thinkyhead](https://github.com/thinkyhead).) + +## Credits + +The current Marlin dev team consists of: + - Roxanne Neufeld [[@Roxy-3D](https://github.com/Roxy-3D)] - English + - Scott Lahteine [[@thinkyhead](https://github.com/thinkyhead)] - English + - Bob Kuhn [[@Bob-the-Kuhn](https://github.com/Bob-the-Kuhn)] - English + - Andreas Hardtung [[@AnHardt](https://github.com/AnHardt)] - Deutsch, English + - Nico Tonnhofer [[@Wurstnase](https://github.com/Wurstnase)] - Deutsch, English + - Jochen Groppe [[@CONSULitAS](https://github.com/CONSULitAS)] - Deutsch, English + - João Brazio [[@jbrazio](https://github.com/jbrazio)] - Portuguese, English + - Bo Hermannsen [[@boelle](https://github.com/boelle)] - Danish, English + - Bob Cousins [[@bobc](https://github.com/bobc)] - English + - [[@maverikou](https://github.com/maverikou)] + - Chris Palmer [[@nophead](https://github.com/nophead)] + - [[@paclema](https://github.com/paclema)] + - Erik van der Zalm [[@ErikZalm](https://github.com/ErikZalm)] + - David Braam [[@daid](https://github.com/daid)] + - Bernhard Kubicek [[@bkubicek](https://github.com/bkubicek)] + +More features have been added by: + - Alberto Cotronei [[@MagoKimbra](https://github.com/MagoKimbra)] - English, Italian + - Thomas Moore [[@tcm0116](https://github.com/tcm0116)] + - Ernesto Martinez [[@emartinez167](https://github.com/emartinez167)] + - Petr Zahradnik [[@clexpert](https://github.com/clexpert)] + - Kai [[@Kaibob2](https://github.com/Kaibob2)] + - Edward Patel [[@epatel](https://github.com/epatel)] + - F. Malpartida [[@fmalpartida](https://github.com/fmalpartida)] - English, Spanish + - [[@esenapaj](https://github.com/esenapaj)] - English, Japanese + - [[@benlye](https://github.com/benlye)] + - [[@Tannoo](https://github.com/Tannoo)] + - [[@teemuatlut](https://github.com/teemuatlut)] + - [[@bgort](https://github.com/bgort)] + - Luc Van Daele[[@LVD-AC](https://github.com/LVD-AC)] - Dutch, French, English + - [[@paulusjacobus](https://github.com/paulusjacobus)] + - ...and many others + +## License + +Marlin is published under the [GPL license](https://github.com/COPYING.md) because we believe in open development. The GPL comes with both rights and obligations. Whether you use Marlin firmware as the driver for your open or closed-source product, you must keep Marlin open, and you must provide your compatible Marlin source code to end users upon request. The most straightforward way to comply with the Marlin license is to make a fork of Marlin on Github, perform your modifications, and direct users to your modified fork. + +While we can't prevent the use of this code in products (3D printers, CNC, etc.) that are closed source or crippled by a patent, we would prefer that you choose another firmware or, better yet, make your own. + +[![Flattr this git repo](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) diff --git a/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/bin/build_marlin b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/bin/build_marlin new file mode 100644 index 00000000..32553462 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/bin/build_marlin @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +case "$#" in + 0 ) BOARD=arduino:avr:mega:cpu=atmega2560 ;; + * ) BOARD=arduino:avr:$1 ;; +esac + +arduino --verify --board $BOARD Marlin/Marlin.ino diff --git a/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/bin/build_marlin_fail b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/bin/build_marlin_fail new file mode 100644 index 00000000..e18105cd --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/bin/build_marlin_fail @@ -0,0 +1,4 @@ +#!/usr/bin/env bash + +build_marlin $@ && exit 0 +exit 1 diff --git a/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/bin/generate_version_header_for_marlin b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/bin/generate_version_header_for_marlin new file mode 100644 index 00000000..43100846 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/bin/generate_version_header_for_marlin @@ -0,0 +1,55 @@ +#!/usr/bin/env bash +# generate_version_header_for_marlin + +DIR="${1}" + +BUILDATE=$(date '+%s') +DISTDATE=$(date '+%Y-%m-%d %H:%M') + +BRANCH=$(git -C "${DIR}" symbolic-ref -q --short HEAD) +VERSION=$(git -C "${DIR}" describe --tags --first-parent 2>/dev/null) + +if [ -z "${BRANCH}" ]; then + BRANCH=$(echo "${TRAVIS_BRANCH}") +fi + +if [ -z "${VERSION}" ]; then + VERSION=$(git -C "${DIR}" describe --tags --first-parent --always 2>/dev/null) +fi + +SHORT_BUILD_VERSION=$(echo "${BRANCH}") +DETAILED_BUILD_VERSION=$(echo "${BRANCH}-${VERSION}") + +# Gets some misc options from their defaults +DEFAULT_MACHINE_UUID=$(awk -F'"' \ + '/#define DEFAULT_MACHINE_UUID/{ print $2 }' < "${DIR}/Version.h") +MACHINE_NAME=$(awk -F'"' \ + '/#define MACHINE_NAME/{ print $2 }' < "${DIR}/Version.h") +PROTOCOL_VERSION=$(awk -F'"' \ + '/#define PROTOCOL_VERSION/{ print $2 }' < "${DIR}/Version.h") +SOURCE_CODE_URL=$(awk -F'"' \ + '/#define SOURCE_CODE_URL/{ print $2 }' < "${DIR}/Version.h") +WEBSITE_URL=$(awk -F'"' \ + '/#define WEBSITE_URL/{ print $2 }' < "${DIR}/Version.h") + +cat > "${DIR}/_Version.h" <rpB4N3PU~fZ^sf}S;VmicNLy-0+uJNwK-RWkN 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 kg9N&hixKUU5~-KOikD<>QAR!Nv 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 AaR2}S literal 0 HcmV?d00001 diff --git a/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/fonts/ISO10646-5_Cyrillic.fon b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/fonts/ISO10646-5_Cyrillic.fon new file mode 100644 index 0000000000000000000000000000000000000000..f52970cbc7712b5ee871c78a93d4575fd77cf827 GIT binary patch literal 4224 zcmeH{VTe^l7=~xn){~jsN2eGXL6 zRKz7BmWa4S#33RiLKcZwB4UvY2?>#qB_gCkwum@HWbgOPxoRZ-ihebB_qpHw=FH4{ z-kJIC+4i&Ran8-t|LN1tP3qfP3@?mK-HWb0xX68U@!{(xdo~=tZp+Z{9-oelJ~FoB zF+cY3<9mn49^T{c8GdMNbkFFnaex2t$l&M`d-^Y3u&kPTj(V475z6cX^&~2 z``#kwZtM4r9b<#zdq*Bw?$fa}`YyQinuEpV<^AAj2U zg3(7WswO#)sP6RtwU!@D(`DV&&->l$?4e%wEBq5iy_UHgE`>M1I$Q(S!HsY$+zEHX zeK3PB!q?ziuz(-JkKyO=2s{qIgQs8#=gc=%3*nW}!yDl$cq?qcO>jHh1ylGGd>+06 zC*a%geRu#)!9(yUJONL_U*I3GSBIn5)!iyj z*bfKb?QjFU4>sYWa2!4ZbNDKJ6TS=g!-McM_$53BzlA@+-=I_F*ZGHw;We-iu7qph zdYHg%a1f5b7JL@I3}1&G@dDL8)LU=OdHqO|ZUs(~QXl*2Tb;CT)_SL=Yd)S>qNv&K z#6^3^A|H#^)ECFTrbw*mmnD6X7TyBqeW^vdtzHXp*-hxXUbi2SMrIbI`9v|Dr;2>j z1X`5lQJQ5osI2)~6wNBC)suEvt646ajUqMu~!@9OS zs%-u69-2`fYx-@v6iI=kdqoxw6+u;A=6SA^7PUV*vn)fwOj~{J8Rg0>o2}FnW#PHW zph{0wvzTBt^$y6$TDz$zZ+E6TZCgY0s+q3*SfN3d%k$}Cf=KVCW~xkx9#mwxuv?Z3 zv$V1-4gP6cs?`|ESfa#hEK!jVB|fQE%afqb+>OzaYV+gR)^+AyWI<}`YnIbMOPpz@ zo}*G_(x{cU6ldA~>ENG6SN=uOkY3Gt?M=$e=BqbmY&lEW+qEJk!&qBK`%}G9&6xsw zku1YN^)~55sXJ1rDd(K68#J0*q1W8PK-aQ0qVQbs)bypCzc`kbMx9wSbYiF*;h#BJ z;GZHhu-l7f&T(vR=#<7DOOVIzTS93@47K_CAODsE@tND0oQa%vGHo=p`!!$Y+UQKH z)f?GN#{QIyi}xfSk(j57jA`pg(%3&v_`A1udks;&#f;y)oD1{s)*G+*U?lx4XaHQ3N`j@ zRk2z6iiYLRsVZFs(xPT>X_C|wnULU+e5vm0-)cz`3b{8WskfQA0IbU-WyJeV3~{ye zl$zazDpK!McR#ESO-rz?WW2OMRKsJDodI+!qhuA)7FOw z2Z?Ne`DdPo`eGU+o8H-|&OMh_Gf+8gR~0$ettxV+@~?7`v1}ocIT#e+V3-*PE$r4h z&0;5uUJVE}!VJVe&3tYJ$<04=uneUM-^{<@VCbFFfe!1Mfz$NHaWiQWrTIXmsx1S} zKXXui*y%juh7Nh~#VTE^(P*fwdYy!@`{r7+nx$J4&sN~X*$a8id$tzay_n>FSX72c Zb8Bk5A6-wSpz=9U)OEum?uTi0e*rCh@7@3a literal 0 HcmV?d00001 diff --git a/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/fonts/ISO10646_CN.fon b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/fonts/ISO10646_CN.fon new file mode 100644 index 0000000000000000000000000000000000000000..6c77eeccd8dea480f2759b0b987b777c34b48083 GIT binary patch literal 6192 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 EC&lG;=Kufz literal 0 HcmV?d00001 diff --git a/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/fonts/ISO10646_SK.fon b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/fonts/ISO10646_SK.fon new file mode 100644 index 0000000000000000000000000000000000000000..76bfcc9e1751f754759c1630e13a326ee626849c GIT binary patch literal 4224 zcmeIze`r%z6u|LYt?}u!yp1A7oV$uhky=ub;zZ<4RI2#nQHvWQl4`7po6TEVT_z$A zrxJ!pkRe561Q7`$qYRNEB4x-ZGDSp&3=t6#*+eoK5=7?C`M#GyH}KEFz?=HX$^Cim zeK&FamfuZ-F{V-ey?$-Xh`ej@@XdtM-1NcaCUbGhjX5I?>u${H$z%s?kk9SP_wKRz zouBW`=64R*_1PWy+(52x(0-ilPv^cEXrDfHUOe@NRg;z-Ap>Kaul~K>0?EWPgXW05 z5}GKPPH^I$6C2IskZRLxrWk)(8x2le_rCefBxf~*QSZsCH*V-zxu$#inoS!!lAVh? z7j`Th_*C2GYfJa4O|~PMZ2PcN{_Ijau9w}{(VmQ^8E1p$KJjdmF(0+tuHJllaBu&v zHoGU6&h}+@rtS7GZFg=@Z@*oi%lGcvk!87YGejR8lag0`Tc*^|kT6q?Nyy8-Hnu{q zJCov(<5C+x+kc(QBhBgE@j3kCQ^IJcgn5QFoRH9(X*dHdF2KdO9J{a^w_+a#xE~MW zaU8-kcmXfrC|<`qcpsnOb9{w~$(oysGjSfa;}Tqf>u@usa5oO(K`i14JdNjY7%$^B zyoq=5AwIi@8M&t;!A9t zqPaC;3(mzh>_iXOVh?V^4Ce6w9>o%#!n61tj^GdY6aI`3@K^i;|3rtc(R(-x=VKC= z;!50rpWt@<4EJG(U*k9UEmrV*yn;XCE&K%^;WMn^gm<|AI0G#%z{R*6yRaL#Vjl*$ z9}nYk9Kthr0WaYwUdKClAD`fJe1(Z=+<%;j^ROM4;0j!an=ysEaS#t;5l`T0Jcq-0 z8L#0@yo(R-+UzUEi*$zky`dI~Ql+w2DP=UWo~T9IJkPokiLQLoN?QpkRs&;gO%|z_q#MPxdWF0v`LEHD zk)hTGMJ<6uHl+z_6cn8x40TY=wXWk-C32H~sph&`7gimI5z?s|jjhRiQlwSp)4wPx zIF3dv8m+6#la;O??L%gimlpY~c}XN0Na{9NgT)C7t3~G+`;yx#WPJ93R?pc@H84p3TCG?J;gRgoff#^}0Hj(S>AtDY7IXbQT96ZMPERPzhC zf1angB$-8q4rS^Q=cgxF;rt}h1FW}_Gxylj(~w*0S&oGCc=}o))r>HiQuJQewUVe@ z82Qrb5fC{pS4`%UR-H%oK|gk6echVw&9xfTqv%=6t*$=>nJ{`DS{I$TL^_|X7l>01WQ?i8CmCA8lW4cwB zl{(+n@3_ntKP}f*-2N9ZT9_sPm3}fd++Y^efNHT-j~Z9e*gyn9`X){09|rYNiv)c1__5& z9z*cp?}xkGK|frqNg67ue6E%nsEQYtk}7JLk;Zo-#HM7%U z3;=xBlk?UIlO*WSA?l?>8B>>Ul*I;f~06*k{Q5Nuxe9OcuEOCaD?M)wMi+lU| zP^P5TrRIs&Zk)+=jRs>hlus2fE(p=B4f5bN78J28mFie<@~|qa=#)DBC~}m$J3(Mq z6-&BU!Iq@gFfBLR7>^}lo8PHZEgzf`9j^s99LGZdfG5iN=?9hPaf`_X#*u&L@sV#VRZtFh|6+EK?!>_+64z{*+Jfs(i=* literal 0 HcmV?d00001 diff --git a/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/fonts/README.md b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/fonts/README.md new file mode 100644 index 00000000..ee9d8e00 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/fonts/README.md @@ -0,0 +1,23 @@ +# 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/ + + - HD44780_C.fon ([fe2bd23](https://github.com/MarlinFirmware/Marlin/commit/fe2bd237d556439499dfdee852c1550c7a16430a)) + - HD44780_J.fon ([fe2bd23](https://github.com/MarlinFirmware/Marlin/commit/fe2bd237d556439499dfdee852c1550c7a16430a)) + - HD44780_W.fon ([fe2bd23](https://github.com/MarlinFirmware/Marlin/commit/fe2bd237d556439499dfdee852c1550c7a16430a)) + - ISO10646-1.fon ([be79235](https://github.com/MarlinFirmware/Marlin/commit/be79235ef255a5c42fd385820447ec351f23b9b1)) + - ISO10646_5_Cyrillic.fon ([fe2bd23](https://github.com/MarlinFirmware/Marlin/commit/fe2bd237d556439499dfdee852c1550c7a16430a)) + - ISO10646_CN.fon ([6b1b718](https://github.com/MarlinFirmware/Marlin/commit/6b1b71837c98ceab55db7433357a13cd829d1ede)) + - 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 being distritubted with Marlin are copyrighted under the terms of the [GPLv3](http://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. diff --git a/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/fonts/make_fonts.bat b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/fonts/make_fonts.bat new file mode 100644 index 00000000..fffd90a6 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/fonts/make_fonts.bat @@ -0,0 +1,10 @@ +.\bdf2u8g.exe -b 1 -e 9 Marlin_symbols.bdf Marlin_symbols dogm_font_data_Marlin_symbols.h +.\bdf2u8g.exe -b 16 -e 255 HD44780_W.bdf HD44780_W_5x7 dogm_font_data_HD44780_W.h +.\bdf2u8g.exe -b 32 -e 255 HD44780_C.bdf HD44780_C_5x7 dogm_font_data_HD44780_C.h +.\bdf2u8g.exe -b 32 -e 255 HD44780_J.bdf HD44780_J_5x7 dogm_font_data_HD44780_J.h +.\bdf2u8g.exe -b 32 -e 255 ISO10646-1.bdf ISO10646_1_5x7 dogm_font_data_ISO10646_1.h +.\bdf2u8g.exe -b 32 -e 255 ISO10646-1-tr.bdf ISO10646_1_tr_5x7 dogm_font_data_ISO10646_1-tr.h +.\bdf2u8g.exe -b 32 -e 255 ISO10646_5_Cyrillic.bdf ISO10646_5_Cyrillic_5x7 dogm_font_data_ISO10646_5_Cyrillic.h +.\bdf2u8g.exe -b 32 -e 255 ISO10646_Kana.bdf ISO10646_Kana_5x7 dogm_font_data_ISO10646_Kana.h +.\bdf2u8g.exe -b 32 -e 255 ISO10646_CN.bdf ISO10646_CN dogm_font_data_ISO10646_CN.h +.\bdf2u8g.exe -b 32 -e 255 ISO10646_4_Greek.bdf ISO10646_Greek_5x7 dogm_font_data_ISO10646_Greek.h diff --git a/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/git/README.md b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/git/README.md new file mode 100644 index 00000000..8d985242 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/git/README.md @@ -0,0 +1,60 @@ +## Marlin Github Helper Scripts + +### Introduction + +A Pull Request is often just the start of a longer process of patching and refining the code until it's ready to merge. In that process it's common to accumulate a lot of commits, some of which are non-functional. Before merging any PR, excess commits need to be "squashed" and sometimes rearranged or reworked to produce a well-packaged set of changes and keep the commit history relatively clean. + +In addition, while a PR is being worked on other commits may be merged, leading to conflicts that need resolution. For this reason, it's a best practice to periodically refresh the PR so the working copy closely reflects the final merge. + +#### Merge vs Rebase + +I recommend not using Github Desktop to sync and merge. Use the command line instead. Github Desktop provides a "merge" option, but for best results "`git rebase`" is recommended. Merge applies new work after your commits. This buries them and makes it hard to bring them together as a final packaged unit. Rebase moves your commits to the end of the branch, ensuring that your commits will be adapted to the current code. This makes it easier to keep revising the commits in-place. + +### The Scripts + +The following scripts can be used on macOS or Linux to speed up the process of working with Marlin and submitting changes to the project. + +#### Remotes + +File|Description +----|----------- +mfadd [user]|Add Remote - Add another Github user's fork of Marlin as a remote, then fetch it. After this you can check out one of their branches and either make a PR targeted at their fork or targeted at `bugfix-1.1.x`. +mfinit|Init Working Copy - Creates a remote named '`upstream`' (for use by the other scripts) pointing to the '`MarlinFirmware`' fork. Use once after checking out your fork. + + +#### Branches + +File|Description +----|----------- +mfnew [branch]|New Branch - Creates a new branch based on `upstream/[PR-target]`. All new work should start here. +firstpush|Push the current branch to 'origin' -your fork on Github- and set it to track '`origin`'. The branch needs to reside on Github before you can use it to make a PR. + + +#### Making / Amending PRs + +File|Description +----|----------- +mfpr|Pull Request - Open the Compare / Pull Request page on Github for the current branch. +mfrb|Do a `git rebase` then `git rebase -i` of the current branch onto `upstream/[PR-target]`. Use this to edit your commits anytime. +mfqp|Quick Patch - Commit all current changes as "patch", `mfrb`, and `git push -f`. + +#### Documentation + +File|Description +----|----------- +mfdoc|Build the documentation and preview it locally. +mfpub|Build the documentation and publish it to marlinfw.org via Github. + +#### Utilities + +File|Description +----|----------- +ghtp -[h/s]|Set the protocol to use for all remotes. -h for HTTPS, -s for SSL. +mfinfo|This utility script is used by the other scripts to get:
    - The upstream project ('`MarlinFirmware`')
    - the '`origin`' project (i.e., your Github username),
    - the repository name ('`Marlin`'),
    - the PR target branch ('`bugfix-1.1.x`'), and
    - the current branch (or the first command-line argument).

    By itself, `mfinfo` simply prints these values to the console. +mfclean     |Prune your merged and remotely-deleted branches. + +--- + +### Examples + +Coming Soon! diff --git a/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/git/firstpush b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/git/firstpush new file mode 100644 index 00000000..60767f04 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/git/firstpush @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +# +# firstpush +# +# Push a branch to 'origin' and open the +# commit log to watch Travis CI progress. +# + +[[ $# == 0 ]] || { echo "Usage: `basename $0`" 1>&2 ; exit 1; } + +MFINFO=$(mfinfo) || exit 1 +IFS=' ' read -a INFO <<< "$MFINFO" +FORK=${INFO[1]} +REPO=${INFO[2]} +BRANCH=${INFO[5]} + +git push --set-upstream origin $BRANCH + +TOOL=$(which gnome-open xdg-open open | awk '{ print $1 }') +URL="https://github.com/$FORK/$REPO/commits/$BRANCH" + +if [ -z "$TOOL" ]; then + echo "Can't find a tool to open the URL:" + echo $URL +else + echo "Viewing commits on $BRANCH..." + "$TOOL" "$URL" +fi diff --git a/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/git/ghtp b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/git/ghtp new file mode 100644 index 00000000..83f461ef --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/git/ghtp @@ -0,0 +1,33 @@ +#!/usr/bin/env bash +# +# ghtp (GitHub Transport Protocol) +# +# Set all remotes in the current repo to HTTPS or SSH connection. +# Useful when switching environments, using public wifi, etc. +# + +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" ;; + *) + 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/") + +if [[ -z $REMOTES ]]; then + echo "Nothing to do." ; exit +fi + +echo "$REMOTES" | xargs -n2 git remote set-url + +echo -n "Remotes set to $TYPE: " +echo "$REMOTES" | gawk '{printf "%s ", $1}' +echo diff --git a/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/git/mfadd b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/git/mfadd new file mode 100644 index 00000000..8b6ded36 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/git/mfadd @@ -0,0 +1,20 @@ +#!/usr/bin/env bash +# +# mfadd +# +# Add a remote and fetch it +# + +[[ $# == 1 ]] || { echo "Usage: `basename $0` user" 1>&2 ; exit 1; } + +USER=$1 + +MFINFO=$(mfinfo) || exit 1 +IFS=' ' read -a INFO <<< "$MFINFO" +REPO=${INFO[2]} + +set -e + +echo "Adding and fetching $USER..." +git remote add "$USER" "git@github.com:$USER/$REPO.git" +git fetch "$USER" diff --git a/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/git/mfclean b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/git/mfclean new file mode 100644 index 00000000..99fd227d --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/git/mfclean @@ -0,0 +1,30 @@ +#!/usr/bin/env bash +# +# mfclean +# +# Prune all your merged branches and any branches whose remotes are gone +# Great way to clean up your branches after messing around a lot +# + +KEEP="RC|RCBugFix|dev|master|bugfix-1" + +echo "Fetching latest upstream and origin..." +git fetch upstream +git fetch origin +echo + +echo "Pruning Merged Branches..." +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 +echo + +# List fork branches that don't match local branches +echo "You may want to remove (or checkout) these refs..." +comm -23 \ + <(git branch --all | sed 's/^[\* ] //' | grep origin/ | grep -v "\->" | awk '{ print $1; }' | sed 's/remotes\/origin\///') \ + <(git branch --all | sed 's/^[\* ] //' | grep -v remotes/ | awk '{ print $1; }') \ + | awk '{ print "git branch -d -r origin/" $1; print "git checkout origin/" $1 " -b " $1; print ""; }' +echo diff --git a/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/git/mfdoc b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/git/mfdoc new file mode 100644 index 00000000..dde571dd --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/git/mfdoc @@ -0,0 +1,35 @@ +#!/usr/bin/env bash +# +# mfdoc +# +# Start Jekyll in watch mode to work on Marlin Documentation and preview locally +# + +[[ $# == 0 ]] || { echo "Usage: `basename $0`" 1>&2 ; exit 1; } + +MFINFO=$(mfinfo "$@") || exit 1 +IFS=' ' read -a INFO <<< "$MFINFO" +ORG=${INFO[0]} +REPO=${INFO[2]} +BRANCH=${INFO[5]} + +[[ $ORG == "MarlinFirmware" && $REPO == "MarlinDocumentation" ]] || { echo "Wrong repository." 1>&2; exit 1; } + +opensite() { + TOOL=$(which gnome-open xdg-open open | awk '{ print $1 }') + URL="http://127.0.0.1:4000/" + if [ -z "$TOOL" ]; then + echo "Can't find a tool to open the URL:" + echo $URL + else + echo "Opening preview site in the browser..." + "$TOOL" "$URL" + fi +} + +echo "Previewing MarlinDocumentation..." + +# wait to open the url for about 8s +( sleep 45; opensite ) & + +bundle exec jekyll serve --watch --incremental diff --git a/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/git/mfinfo b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/git/mfinfo new file mode 100644 index 00000000..febbcc3e --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/git/mfinfo @@ -0,0 +1,39 @@ +#!/usr/bin/env bash +# +# mfinfo +# +# Provide the following info about the working directory: +# +# - Remote (upstream) Org name (MarlinFirmware) +# - Remote (origin) Org name (your Github username) +# - Repo Name (Marlin, MarlinDev, MarlinDocumentation) +# - PR Target branch (bugfix-1.1.x, dev, or master) +# - Branch Arg (the branch argument or current branch) +# - Current Branch +# + +CURR=$(git branch 2>/dev/null | grep ^* | sed 's/\* //g') +[[ -z $CURR ]] && { echo "No git repository here!" 1>&2 ; exit 1; } +[[ $CURR == "(no"* ]] && { echo "Git is busy with merge, rebase, etc." 1>&2 ; exit 1; } + +REPO=$(git remote get-url upstream 2>/dev/null | sed -E 's/.*\/(.*)\.git/\1/') +[[ -z $REPO ]] && { echo "`basename $0`: No 'upstream' remote found. (Did you run mfinit?)" 1>&2 ; exit 1; } + +ORG=$(git remote get-url upstream 2>/dev/null | sed -E 's/.*[\/:](.*)\/.*$/\1/') +[[ $ORG == MarlinFirmware ]] || { echo "`basename $0`: Not a Marlin repository." 1>&2 ; exit 1; } + +case "$REPO" in + Marlin ) TARG=bugfix-1.1.x ;; + MarlinDev ) TARG=dev ;; + MarlinDocumentation ) TARG=master ;; +esac + +FORK=$(git remote get-url origin 2>/dev/null | sed -E 's/.*[\/:](.*)\/.*$/\1/') + +case "$#" in + 0 ) BRANCH=$CURR ;; + 1 ) BRANCH=$1 ;; + * ) echo "Usage: `basename $0` [branch]" 1>&2 ; exit 1 ;; +esac + +echo "$ORG $FORK $REPO $TARG $BRANCH $CURR" diff --git a/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/git/mfinit b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/git/mfinit new file mode 100644 index 00000000..05bab876 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/git/mfinit @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +# +# mfinit +# +# Create the upstream remote for a forked repository +# + +[[ $# == 0 ]] || { echo "Usage: `basename $0`" 1>&2 ; exit 1; } + +[[ -z $(git branch 2>/dev/null | grep ^* | sed 's/\* //g') ]] && { echo "No git repository here!" 1>&2 ; exit 1; } + +REPO=$(git remote get-url origin 2>/dev/null | sed -E 's/.*\/(.*)\.git/\1/') +[[ -z $REPO ]] && { echo "`basename $0`: No 'origin' remote found." 1>&2 ; exit 1; } + +echo "Adding 'upstream' remote for convenience." +git remote add upstream "git@github.com:MarlinFirmware/$REPO.git" +git fetch upstream diff --git a/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/git/mfnew b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/git/mfnew new file mode 100644 index 00000000..f1e495cb --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/git/mfnew @@ -0,0 +1,20 @@ +#!/usr/bin/env bash +# +# mfnew +# +# Create a new branch from the default target with the given name +# + +[[ $# < 2 ]] || { echo "Usage: `basename $0` [branch]" 1>&2 ; exit 1; } + +MFINFO=$(mfinfo) || exit 1 +IFS=' ' read -a INFO <<< "$MFINFO" +TARG=${INFO[3]} + +case "$#" in + 0 ) BRANCH=pr_for_$TARG-$(date +"%G-%m-%d_%H.%M.%S") ;; + 1 ) BRANCH=$1 ;; +esac + +git fetch upstream +git checkout upstream/$TARG -b $BRANCH diff --git a/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/git/mfpr b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/git/mfpr new file mode 100644 index 00000000..025b6869 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/git/mfpr @@ -0,0 +1,37 @@ +#!/usr/bin/env bash +# +# mfpr +# +# Make a PR of the current branch against RCBugFix or dev +# + +[[ $# < 2 ]] || { echo "Usage: `basename $0` [branch]" 1>&2 ; exit 1; } + +MFINFO=$(mfinfo "$@") || exit 1 +IFS=' ' read -a INFO <<< "$MFINFO" +ORG=${INFO[0]} +FORK=${INFO[1]} +REPO=${INFO[2]} +TARG=${INFO[3]} +BRANCH=${INFO[4]} +OLDBRANCH=${INFO[5]} + +[[ $BRANCH == $TARG ]] && { echo "Can't create a PR from the PR Target ($BRANCH). Make a copy first." 1>&2 ; exit 1; } + +[[ $BRANCH != $OLDBRANCH ]] && { git checkout $BRANCH || exit 1; } + +# See if it's been pushed yet +if [ -z "$(git branch -vv | grep ^\* | grep \\[origin)" ]; then firstpush; fi + +TOOL=$(which gnome-open xdg-open open | awk '{ print $1 }') +URL="https://github.com/$ORG/$REPO/compare/$TARG...$FORK:$BRANCH?expand=1" + +if [ -z "$TOOL" ]; then + echo "Can't find a tool to open the URL:" + echo $URL +else + echo "Opening a New PR Form..." + "$TOOL" "$URL" +fi + +[[ $BRANCH != $OLDBRANCH ]] && git checkout $OLDBRANCH diff --git a/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/git/mfpub b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/git/mfpub new file mode 100644 index 00000000..9b48480d --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/git/mfpub @@ -0,0 +1,116 @@ +#!/usr/bin/env bash +# +# mfpub +# +# Use Jekyll to generate Marlin Documentation, which is then +# git-pushed to Github to publish it to the live site. +# This publishes the current branch, and doesn't force +# changes to be pushed to the 'master' branch. Be sure to push +# any permanent changes to 'master'. +# + +[[ $# < 2 ]] || { echo "Usage: `basename $0` [branch]" 1>&2 ; exit 1; } + +MFINFO=$(mfinfo "$@") || exit 1 +IFS=' ' read -a INFO <<< "$MFINFO" +ORG=${INFO[0]} +FORK=${INFO[1]} +REPO=${INFO[2]} +TARG=${INFO[3]} +BRANCH=${INFO[4]} + +if [[ $ORG != "MarlinFirmware" || $REPO != "MarlinDocumentation" ]]; then + echo "Wrong repository." + exit +fi + +# Check out the named branch (or stay in current) +git checkout $BRANCH + +if [[ $BRANCH == "gh-pages" ]]; then + echo "Can't build from 'gh-pages.' Only the Jekyll branches (based on 'master')." + exit +fi + +echo "Stashing any changes to files..." +echo "Don't forget to update and push 'master'!" +# GOJF Card +git stash + +COMMIT=$( git log --format="%H" -n 1 ) + +# Clean out changes and other junk in the branch +git clean -d -f + +# Push 'master' to the fork and make a proper PR... +if [[ $BRANCH == "master" ]]; then + + # Allow working directly with the main fork + echo + echo -n "Pushing to origin/master... " + git push -f origin + + echo + echo -n "Pushing to upstream/master... " + git push -f upstream + +else + + if [ -z "$(git branch -vv | grep ^\* | grep \\[origin)" ]; then + firstpush + else + echo + echo -n "Pushing to origin/$BRANCH... " + git push -f origin + fi + + TOOL=$(which gnome-open xdg-open open | awk '{ print $1 }') + URL="https://github.com/$ORG/$REPO/compare/$TARG...$FORK:$BRANCH?expand=1" + + if [ -z "$TOOL" ]; then + echo "Can't find a tool to open the URL:" + echo $URL + else + echo "Opening a New PR Form..." + "$TOOL" "$URL" + fi + +fi + +# Uncomment to compress the final html files +# mv ./_plugins/jekyll-press.rb-disabled ./_plugins/jekyll-press.rb +# bundle install + +echo +echo "Generating MarlinDocumentation..." + +# build the site statically and proof it +bundle exec jekyll build --profile --trace --no-watch +bundle exec htmlproofer ./_site --only-4xx --allow-hash-href --check-favicon --check-html --url-swap ".*marlinfw.org/:/" + +# Sync the built site into a temporary folder +TMPFOLDER=$( mktemp -d ) +rsync -av _site/ ${TMPFOLDER}/ + +# Clean out changes and other junk in the branch +git reset --hard +git clean -d -f + +# Copy built-site into the gh-pages branch +git checkout gh-pages +rsync -av ${TMPFOLDER}/ ./ + +# Commit and push the new live site directly +git add --all +git commit --message "Built from ${COMMIT}" +git push upstream + +# remove the temporary folder +rm -rf ${TMPFOLDER} + +# Go back to the branch we started from +git checkout $BRANCH + +if [[ $BRANCH != "master" ]]; then + git stash pop +fi diff --git a/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/git/mfqp b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/git/mfqp new file mode 100644 index 00000000..97cac5db --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/git/mfqp @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +# +# mfqp +# +# Add all changed files, commit as "patch", do `mfrb` and `git push -f` +# + +[[ $# == 0 ]] || { echo "Usage: `basename $0`" 1>&2 ; exit 1; } + +MFINFO=$(mfinfo) || exit 1 +IFS=' ' read -a INFO <<< "$MFINFO" +REPO=${INFO[2]} +TARG=${INFO[3]} +BRANCH=${INFO[5]} + +git add . +git commit -m "patch" + +if [[ $BRANCH == $TARG ]]; then + if [[ $REPO == "MarlinDocumentation" ]]; then + git rebase -i HEAD~2 + else + echo "Don't alter the PR Target branch."; exit 1 + fi +else + mfrb + git push -f +fi diff --git a/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/git/mfrb b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/git/mfrb new file mode 100644 index 00000000..b376b407 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/git/mfrb @@ -0,0 +1,19 @@ +#!/usr/bin/env bash +# +# mfrb +# +# Do "git rebase -i" against the "target" branch (RCBugFix or dev) +# + +[[ $# == 0 ]] || { echo "Usage: `basename $0`" 1>&2 ; exit 1; } + +MFINFO=$(mfinfo) || exit 1 +IFS=' ' read -a INFO <<< "$MFINFO" +TARG=${INFO[3]} +BRANCH=${INFO[5]} + +# If the branch isn't currently the PR target +if [[ $TARG != $BRANCH ]]; then + git fetch upstream + git rebase upstream/$TARG && git rebase -i upstream/$TARG +fi diff --git a/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/git/mfup b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/git/mfup new file mode 100644 index 00000000..df2da87b --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/git/mfup @@ -0,0 +1,56 @@ +#!/usr/bin/env bash +# +# mfup +# +# - Fetch latest upstream and replace the PR Target branch with +# - Rebase the (current or specified) branch on the PR Target +# - Force-push the branch to 'origin' +# - +# + +[[ $# < 2 ]] || { echo "Usage: `basename $0` [branch]" 1>&2 ; exit 1; } + +MFINFO=$(mfinfo "$@") || exit 1 +IFS=' ' read -a INFO <<< "$MFINFO" +ORG=${INFO[0]} +FORK=${INFO[1]} +REPO=${INFO[2]} +TARG=${INFO[3]} +BRANCH=${INFO[4]} +OLDBRANCH=${INFO[5]} + +set -e + +# Prevent accidental loss of current changes +[[ $(git stash) != "No local "* ]] && HAS_STASH=1 + +echo "Fetching upstream ($ORG/$REPO)..." +git fetch upstream + +echo ; echo "Bringing $TARG up to date..." +if [[ ! $(git checkout -q $TARG) ]]; then + git reset --hard upstream/$TARG + git push -f origin +else + git checkout upstream/$TARG -b $TARG + git push --set-upstream origin $TARG +fi + +if [[ $BRANCH != $TARG ]]; then + echo ; echo "Rebasing $BRANCH on $TARG..." + if git checkout $BRANCH; then + echo + if git rebase $TARG; then + git push -f + else + echo "Looks like merge conflicts. Stopping here." ; exit + fi + else + echo "No such branch!" + fi +fi + +echo +[[ $BRANCH != $OLDBRANCH ]] && git checkout $OLDBRANCH + +[[ $HAS_STASH == 1 ]] && git stash pop diff --git a/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/pin_interrupt_test/pin_interrupt_test.ino b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/pin_interrupt_test/pin_interrupt_test.ino new file mode 100644 index 00000000..9702d9d9 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/pin_interrupt_test/pin_interrupt_test.ino @@ -0,0 +1,32 @@ +// Search pins usable for endstop-interrupts +// Compile with the same build settings you'd use for Marlin. + +#if defined(ARDUINO_AVR_MEGA2560) || defined(ARDUINO_AVR_MEGA) + #undef digitalPinToPCICR + #define digitalPinToPCICR(p) ( ((p) >= 10 && (p) <= 15) || \ + ((p) >= 50 && (p) <= 53) || \ + ((p) >= 62 && (p) <= 69) ? &PCICR : (uint8_t *)0) +#endif + +void setup() { + Serial.begin(9600); + Serial.println("PINs causing interrups are:"); + for (int i = 2; i < NUM_DIGITAL_PINS; i++) { + if (digitalPinToPCICR(i) || (int)digitalPinToInterrupt(i) != -1) { + for (int j = 0; j < NUM_ANALOG_INPUTS; j++) { + if (analogInputToDigitalPin(j) == i) { + Serial.print('A'); + Serial.print(j); + Serial.print(" = "); + } + } + Serial.print('D'); + Serial.println(i); + } + } + Serial.println("Arduino pin numbering!"); +} + +void loop() { + // put your main code here, to run repeatedly: +} diff --git a/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/pixmaps/logo/marlin-1080.png b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/pixmaps/logo/marlin-1080.png new file mode 100644 index 0000000000000000000000000000000000000000..b21d0ca80e8e2b2f101c481de3da91327b407092 GIT binary patch literal 56379 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 literal 0 HcmV?d00001 diff --git a/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/pixmaps/logo/marlin-old-250.png b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/pixmaps/logo/marlin-old-250.png new file mode 100644 index 0000000000000000000000000000000000000000..64f9902fde21167a9b50393277532c5e91f2e507 GIT binary patch literal 4172 zcmV-S5VP-zP)K4!X>x6MVRB_utr*|{000(rMObt} zb#!QNasWYSZDn*ILuG9sR8>+zPPUk&a{vGjhDk(0RCt{2ookRBRTY50nca=ak{AMs zyh#EPP#zKjVgP|4f(n$pLjgf7P##e%v_ugB<)r}%uy})52q?Jy z1OppFNJuu%O|seD@yD5FW+%Jd=XT$|-7|Z?s;+Ei@7#0yZl6B)an88~;xQhW3>*Qp z#;n5y!+~PfjqoI*3HWH%ji`4D24x2WQ-HI83F$P)1OU=A8TaRBqkl8CaY{zLXt+ zua*C^5Ez=yeS16uj&G75Wd~qx`9Bw@b;lmh0OfqLSMm~wD_;qjn{S!s9eX?jlncmM z(VG!BK7hXhi&DHw%mxf(!Iw}nvu9;SF*g%e*Iz+TAeq3Oh#6{2#jzjZ#Zx=@C#rj@IKIi z_z8C*>jX=IXMn4KNyPudHUWnK*8oo=)?#^CRy*>hTMos_UUvYS)W|9T-^G4F!MjMvuE!0U z=Vhj{uJaUiywse{_Kl~1G>WcO z&WjawttR`$y#jCxb*Sja<0e$^MMT*jbs%d46@LRydT12=pUS$fQq)yK;ykjZ0Nh5( zioOPWiarssfN3jUa4mBvYmKEo^7M~J(O*>7b)BNF5|xo*))awzNa^`4VsGfODR4h- zw=G<54YmRglAi}-prXywuYInwTzRji2ly&*UmBI$Jlx2*gXMe1Mmd0h}VWZEL$T(@q;mY ztDlT)8ES`+9=kNMqJ!wg6vPNmwpnrD#FAwGc`ashhWiN54L<^L7fd?e-+=5@hDGIV zgDixY#0~#0x=TDU(9F?iE9=@0$&?gzWow?ESkZ?fuA~}aYcYFEO+ega z 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 C@9QN1 literal 0 HcmV?d00001 diff --git a/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/pixmaps/logo/marlin-old.svg b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/pixmaps/logo/marlin-old.svg new file mode 100644 index 00000000..d621d3ab --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/pixmaps/logo/marlin-old.svg @@ -0,0 +1,106 @@ + + + + + Marlin Firmware + + + + + + image/svg+xml + + Marlin Firmware + + + Ahmet Cem TURAN + + + + + MarlinFirmware + + + + + João Brázio + + + marlin-logo-old + + + + + + + + + + + + + + diff --git a/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/pixmaps/logo/marlin.svg b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/pixmaps/logo/marlin.svg new file mode 100644 index 00000000..e608a7ee --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/pixmaps/logo/marlin.svg @@ -0,0 +1,131 @@ + + + +Marlin Firmware image/svg+xmlMarlin Firmware Ahmet Cem TURANJoão BrázioMarlinFirmwaremarlin-logo-new \ No newline at end of file diff --git a/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/scripts/MarlinMesh.scad b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/scripts/MarlinMesh.scad new file mode 100644 index 00000000..7616ded6 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/scripts/MarlinMesh.scad @@ -0,0 +1,256 @@ + /**************************************\ + * * + * OpenSCAD Mesh Display * + * by Thinkyhead - April 2017 * + * * + * Copy the grid output from Marlin, * + * paste below as shown, and use * + * OpenSCAD to see a visualization * + * of your mesh. * + * * + \**************************************/ + +//$t = 0.15; // comment out during animation + +// +// Mesh info and points +// + +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 ], + [ -1.13, -1.26, -1.39, -1.31, -1.18 ], + [ -1.09, -1.20, -1.26, -1.21, -1.18 ], + [ -1.13, -0.99, -1.03, -1.06, -1.32 ] +]; + +// +// Geometry +// + +max_z_scale = 100; // Scale at Time 0.5 +min_z_scale = 10; // Scale at Time 0.0 and 1.0 +thickness = 0.5; // thickness of the mesh triangles +tesselation = 1; // levels of tesselation from 0-2 +alternation = 2; // direction change modulus (try it) + +// +// Appearance +// + +show_plane = true; +show_labels = true; +arrow_length = 5; + +label_font_lg = "Arial"; +label_font_sm = "Arial"; +mesh_color = [1,1,1,0.5]; +plane_color = [0.4,0.6,0.9,0.6]; + +//================================================ Derive useful values + +big_z = max_2D(measured_z,0); +lil_z = min_2D(measured_z,0); + +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); + +// 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; + +// +// Min and max recursive functions for 1D and 2D arrays +// Return the smallest or largest value in the array +// +function min_1D(b,i) = (i low_bound else low_bound) + max_temp = int(TMAX if TMAX < up_bound else up_bound) + temps = range(max_temp, TMIN+step, step); + + print "// Thermistor lookup table for Marlin" + print "// ./createTemperatureLookupMarlin.py --rp=%s --t1=%s:%s --t2=%s:%s --t3=%s:%s --num-temps=%s" % (rp, t1, r1, t2, r2, t3, r3, num_temps) + print "// Steinhart-Hart Coefficients: a=%.15g, b=%.15g, c=%.15g " % (t.c1, t.c2, t.c3) + print "// Theoretical limits of termistor: %.2f to %.2f degC" % (low_bound, up_bound) + print + print "#define NUMTEMPS %s" % (len(temps)) + print "const short temptable[NUMTEMPS][2] PROGMEM = {" + + for temp in temps: + adc = t.adc(temp) + print " { (short) (%7.2f * OVERSAMPLENR ), %4s }%s // v=%.3f\tr=%.3f\tres=%.3f degC/count" % (adc , temp, \ + ',' if temp != temps[-1] else ' ', \ + t.voltage(adc), \ + t.resist( adc), \ + t.resol( adc) \ + ) + print "};" + +def usage(): + print __doc__ + +if __name__ == "__main__": + main(sys.argv[1:]) diff --git a/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/scripts/findMissingTranslations.sh b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/scripts/findMissingTranslations.sh new file mode 100644 index 00000000..2ef9c146 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/scripts/findMissingTranslations.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash +# +# findMissingTranslations.sh +# +# Locate all language strings needing an update based on English +# +# Usage: findMissingTranslations.sh [language codes] +# +# If no language codes are specified then all languages will be checked +# + +[ -d "Marlin" ] && cd "Marlin" + +FILES=$(ls language_*.h | grep -v -E "(_en|_test)\.h" | sed -E 's/language_([^\.]+)\.h/\1/') +declare -A STRING_MAP + +# Get files matching the given arguments +TEST_LANGS=$FILES +if [[ -n $@ ]]; then + TEST_LANGS="" + for K in "$@"; do + for F in $FILES; do + [[ "$F" != "${F%$K*}" ]] && TEST_LANGS="$TEST_LANGS $F" + done + done +fi + +echo -n "Building list of missing strings..." + +for i in $(awk '/#ifndef/{print $2}' language_en.h); do + [[ $i == "LANGUAGE_EN_H" ]] && continue + LANG_LIST="" + for j in $TEST_LANGS; do + [[ $(grep -c " ${i} " language_${j}.h) -eq 0 ]] && LANG_LIST="$LANG_LIST $j" + done + [[ -z $LANG_LIST ]] && continue + STRING_MAP[$i]=$LANG_LIST +done + +echo + +for K in $( printf "%s\n" "${!STRING_MAP[@]}" | sort ); do + printf "%-35s :%s\n" "$K" "${STRING_MAP[$K]}" +done diff --git a/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/scripts/g29_auto.py b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/scripts/g29_auto.py new file mode 100644 index 00000000..884e62b2 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/buildroot/share/scripts/g29_auto.py @@ -0,0 +1,186 @@ +#!/usr/bin/python3 + +# This file is for preprocessing gcode and the new G29 Autobedleveling from Marlin +# It will analyse the first 2 Layer and return the maximum size for this part +# After this it will replace with g29_keyword = ';MarlinG29Script' with the new G29 LRFB +# the new file will be created in the same folder. + +# your gcode-file/folder +folder = './' +my_file = 'test.gcode' + +# this is the minimum of G1 instructions which should be between 2 different heights +min_g1 = 3 + +# maximum number of lines to parse, I don't want to parse the complete file +# only the first plane is we are interested in +max_g1 = 100000000 + +# g29 keyword +g29_keyword = 'g29' +g29_keyword = g29_keyword.upper() + +# output filename +output_file = folder + 'g29_' + my_file +# input filename +input_file = folder + my_file + +# minimum scan size +min_size = 40 +probing_points = 3 # points x points + +# other stuff +min_x = 500 +min_y = min_x +max_x = -500 +max_y = max_x +last_z = 0.001 + +layer = 0 +lines_of_g1 = 0 + +gcode = [] + + +# return only g1-lines +def has_g1(line): + return line[:2].upper() == "G1" + + +# find position in g1 (x,y,z) +def find_axis(line, axis): + found = False + number = "" + for char in line: + if found: + if char == ".": + number += char + elif char == "-": + number += char + else: + try: + int(char) + number += char + except ValueError: + break + else: + found = char.upper() == axis.upper() + try: + return float(number) + except ValueError: + return None + + +# save the min or max-values for each axis +def set_mima(line): + global min_x, max_x, min_y, max_y, last_z + + current_x = find_axis(line, 'x') + current_y = find_axis(line, 'y') + + if current_x is not None: + min_x = min(current_x, min_x) + max_x = max(current_x, max_x) + if current_y is not None: + min_y = min(current_y, min_y) + max_y = max(current_y, max_y) + + return min_x, max_x, min_y, max_y + + +# find z in the code and return it +def find_z(gcode, start_at_line=0): + for i in range(start_at_line, len(gcode)): + my_z = find_axis(gcode[i], 'Z') + if my_z is not None: + return my_z, i + + +def z_parse(gcode, start_at_line=0, end_at_line=0): + i = start_at_line + all_z = [] + line_between_z = [] + z_at_line = [] + # last_z = 0 + last_i = -1 + + while len(gcode) > i: + try: + z, i = find_z(gcode, i + 1) + except TypeError: + break + + all_z.append(z) + z_at_line.append(i) + temp_line = i - last_i -1 + line_between_z.append(i - last_i - 1) + # last_z = z + last_i = i + if 0 < end_at_line <= i or temp_line >= min_g1: + # print('break at line {} at heigth {}'.format(i, z)) + break + + line_between_z = line_between_z[1:] + return all_z, line_between_z, z_at_line + + +# get the lines which should be the first layer +def get_lines(gcode, minimum): + i = 0 + all_z, line_between_z, z_at_line = z_parse(gcode, end_at_line=max_g1) + for count in line_between_z: + i += 1 + if count > minimum: + # print('layer: {}:{}'.format(z_at_line[i-1], z_at_line[i])) + return z_at_line[i - 1], z_at_line[i] + + +with open(input_file, 'r') as file: + lines = 0 + for line in file: + lines += 1 + if lines > 1000: + break + if has_g1(line): + gcode.append(line) +file.close() + +start, end = get_lines(gcode, min_g1) +for i in range(start, end): + set_mima(gcode[i]) + +print('x_min:{} x_max:{}\ny_min:{} y_max:{}'.format(min_x, max_x, min_y, max_y)) + +# resize min/max - values for minimum scan +if max_x - min_x < min_size: + offset_x = int((min_size - (max_x - min_x)) / 2 + 0.5) # int round up + # print('min_x! with {}'.format(int(max_x - min_x))) + min_x = int(min_x) - offset_x + max_x = int(max_x) + offset_x +if max_y - min_y < min_size: + offset_y = int((min_size - (max_y - min_y)) / 2 + 0.5) # int round up + # print('min_y! with {}'.format(int(max_y - min_y))) + min_y = int(min_y) - offset_y + max_y = int(max_y) + offset_y + + +new_command = 'G29 L{0} R{1} F{2} B{3} P{4}\n'.format(min_x, + max_x, + min_y, + max_y, + probing_points) + +out_file = open(output_file, 'w') +in_file = open(input_file, 'r') + +for line in in_file: + if line[:len(g29_keyword)].upper() == g29_keyword: + out_file.write(new_command) + print('write G29') + else: + out_file.write(line) + +file.close() +out_file.close() + +print('auto G29 finished') diff --git a/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/platformio.ini b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/platformio.ini new file mode 100644 index 00000000..3d7cff48 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/Marlin-1.1.x/platformio.ini @@ -0,0 +1,82 @@ +# +# Project Configuration File +# +# A detailed documentation with the EXAMPLES is located here: +# http://docs.platformio.org/en/latest/projectconf.html +# + +# A sign `#` at the beginning of the line indicates a comment +# Comment lines are ignored. + +# Automatic targets - enable auto-uploading +# targets = upload + +[platformio] +src_dir = Marlin +envs_dir = .pioenvs +lib_dir = .piolib +libdeps_dir = .piolibdeps +env_default = megaatmega2560 + +[common] +lib_deps = U8glib@1.19.1 + +[env:megaatmega2560] +platform = atmelavr +framework = arduino +board = megaatmega2560 +build_flags = -I $BUILDSRC_DIR +board_f_cpu = 16000000L +lib_deps = ${common.lib_deps} + +[env:megaatmega1280] +platform = atmelavr +framework = arduino +board = megaatmega1280 +build_flags = -I $BUILDSRC_DIR +board_f_cpu = 16000000L +lib_deps = ${common.lib_deps} + +[env:printrboard] +platform = teensy +framework = arduino +board = teensy20pp +build_flags = -I $BUILDSRC_DIR -D MOTHERBOARD=BOARD_PRINTRBOARD +# Bug in arduino framework does not allow boards running at 20Mhz +#board_f_cpu = 20000000L +lib_deps = ${common.lib_deps} + +[env:printrboard_revf] +platform = teensy +framework = arduino +board = teensy20pp +build_flags = -I $BUILDSRC_DIR -D MOTHERBOARD=BOARD_PRINTRBOARD_REVF +lib_deps = ${common.lib_deps} + +[env:brainwavepro] +platform = teensy +framework = arduino +board = teensy20pp +build_flags = -I $BUILDSRC_DIR -D MOTHERBOARD=BOARD_BRAINWAVE_PRO +lib_deps = ${common.lib_deps} + +[env:rambo] +platform = atmelavr +framework = arduino +board = reprap_rambo +build_flags = -I $BUILDSRC_DIR +board_f_cpu = 16000000L +lib_deps = ${common.lib_deps} + +[env:anet10] +platform = atmelavr +framework = arduino +board = sanguino_atmega1284p +upload_speed = 57600 +lib_deps = ${common.lib_deps} + +[env:sanguino_atmega644p] +platform = atmelavr +framework = arduino +board = sanguino_atmega644p +lib_deps = ${common.lib_deps} diff --git a/trunk/Arduino/Marlin_1.1.6/Marlin.h b/trunk/Arduino/Marlin_1.1.6/Marlin.h new file mode 100644 index 00000000..c341d98f --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/Marlin.h @@ -0,0 +1,497 @@ +/** + * 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 . + * + */ +#ifndef MARLIN_H +#define MARLIN_H + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "MarlinConfig.h" + +#ifdef DEBUG_GCODE_PARSER + #include "gcode.h" +#endif + +#include "enum.h" +#include "types.h" +#include "fastio.h" +#include "utility.h" +#include "serial.h" + +#if ENABLED(PRINTCOUNTER) + #include "printcounter.h" +#else + #include "stopwatch.h" +#endif + +void idle( + #if ENABLED(ADVANCED_PAUSE_FEATURE) + bool no_stepper_sleep = false // pass true to keep steppers from disabling on timeout + #endif +); + +void manage_inactivity(bool ignore_stepper_queue = false); + +#if ENABLED(DUAL_X_CARRIAGE) || ENABLED(DUAL_NOZZLE_DUPLICATION_MODE) + extern bool extruder_duplication_enabled; +#endif + +#if HAS_X2_ENABLE + #define enable_X() do{ X_ENABLE_WRITE( X_ENABLE_ON); X2_ENABLE_WRITE( X_ENABLE_ON); }while(0) + #define disable_X() do{ X_ENABLE_WRITE(!X_ENABLE_ON); X2_ENABLE_WRITE(!X_ENABLE_ON); axis_known_position[X_AXIS] = false; }while(0) +#elif HAS_X_ENABLE + #define enable_X() X_ENABLE_WRITE( X_ENABLE_ON) + #define disable_X() do{ X_ENABLE_WRITE(!X_ENABLE_ON); axis_known_position[X_AXIS] = false; }while(0) +#else + #define enable_X() NOOP + #define disable_X() NOOP +#endif + +#if HAS_Y2_ENABLE + #define enable_Y() do{ Y_ENABLE_WRITE( Y_ENABLE_ON); Y2_ENABLE_WRITE(Y_ENABLE_ON); }while(0) + #define disable_Y() do{ Y_ENABLE_WRITE(!Y_ENABLE_ON); Y2_ENABLE_WRITE(!Y_ENABLE_ON); axis_known_position[Y_AXIS] = false; }while(0) +#elif HAS_Y_ENABLE + #define enable_Y() Y_ENABLE_WRITE( Y_ENABLE_ON) + #define disable_Y() do{ Y_ENABLE_WRITE(!Y_ENABLE_ON); axis_known_position[Y_AXIS] = false; }while(0) +#else + #define enable_Y() NOOP + #define disable_Y() NOOP +#endif + +#if HAS_Z2_ENABLE + #define enable_Z() do{ Z_ENABLE_WRITE( Z_ENABLE_ON); Z2_ENABLE_WRITE(Z_ENABLE_ON); }while(0) + #define disable_Z() do{ Z_ENABLE_WRITE(!Z_ENABLE_ON); Z2_ENABLE_WRITE(!Z_ENABLE_ON); axis_known_position[Z_AXIS] = false; }while(0) +#elif HAS_Z_ENABLE + #define enable_Z() Z_ENABLE_WRITE( Z_ENABLE_ON) + #define disable_Z() do{ Z_ENABLE_WRITE(!Z_ENABLE_ON); axis_known_position[Z_AXIS] = false; }while(0) +#else + #define enable_Z() NOOP + #define disable_Z() NOOP +#endif + +#if ENABLED(MIXING_EXTRUDER) + + /** + * Mixing steppers synchronize their enable (and direction) together + */ + #if MIXING_STEPPERS > 3 + #define enable_E0() { E0_ENABLE_WRITE( E_ENABLE_ON); E1_ENABLE_WRITE( E_ENABLE_ON); E2_ENABLE_WRITE( E_ENABLE_ON); E3_ENABLE_WRITE( E_ENABLE_ON); } + #define disable_E0() { E0_ENABLE_WRITE(!E_ENABLE_ON); E1_ENABLE_WRITE(!E_ENABLE_ON); E2_ENABLE_WRITE(!E_ENABLE_ON); E3_ENABLE_WRITE(!E_ENABLE_ON); } + #elif MIXING_STEPPERS > 2 + #define enable_E0() { E0_ENABLE_WRITE( E_ENABLE_ON); E1_ENABLE_WRITE( E_ENABLE_ON); E2_ENABLE_WRITE( E_ENABLE_ON); } + #define disable_E0() { E0_ENABLE_WRITE(!E_ENABLE_ON); E1_ENABLE_WRITE(!E_ENABLE_ON); E2_ENABLE_WRITE(!E_ENABLE_ON); } + #else + #define enable_E0() { E0_ENABLE_WRITE( E_ENABLE_ON); E1_ENABLE_WRITE( E_ENABLE_ON); } + #define disable_E0() { E0_ENABLE_WRITE(!E_ENABLE_ON); E1_ENABLE_WRITE(!E_ENABLE_ON); } + #endif + #define enable_E1() NOOP + #define disable_E1() NOOP + #define enable_E2() NOOP + #define disable_E2() NOOP + #define enable_E3() NOOP + #define disable_E3() NOOP + #define enable_E4() NOOP + #define disable_E4() NOOP + +#else // !MIXING_EXTRUDER + + #if HAS_E0_ENABLE + #define enable_E0() E0_ENABLE_WRITE( E_ENABLE_ON) + #define disable_E0() E0_ENABLE_WRITE(!E_ENABLE_ON) + #else + #define enable_E0() NOOP + #define disable_E0() NOOP + #endif + + #if E_STEPPERS > 1 && HAS_E1_ENABLE + #define enable_E1() E1_ENABLE_WRITE( E_ENABLE_ON) + #define disable_E1() E1_ENABLE_WRITE(!E_ENABLE_ON) + #else + #define enable_E1() NOOP + #define disable_E1() NOOP + #endif + + #if E_STEPPERS > 2 && HAS_E2_ENABLE + #define enable_E2() E2_ENABLE_WRITE( E_ENABLE_ON) + #define disable_E2() E2_ENABLE_WRITE(!E_ENABLE_ON) + #else + #define enable_E2() NOOP + #define disable_E2() NOOP + #endif + + #if E_STEPPERS > 3 && HAS_E3_ENABLE + #define enable_E3() E3_ENABLE_WRITE( E_ENABLE_ON) + #define disable_E3() E3_ENABLE_WRITE(!E_ENABLE_ON) + #else + #define enable_E3() NOOP + #define disable_E3() NOOP + #endif + + #if E_STEPPERS > 4 && HAS_E4_ENABLE + #define enable_E4() E4_ENABLE_WRITE( E_ENABLE_ON) + #define disable_E4() E4_ENABLE_WRITE(!E_ENABLE_ON) + #else + #define enable_E4() NOOP + #define disable_E4() NOOP + #endif + +#endif // !MIXING_EXTRUDER + +#if ENABLED(G38_PROBE_TARGET) + extern bool G38_move, // flag to tell the interrupt handler that a G38 command is being run + G38_endstop_hit; // flag from the interrupt handler to indicate if the endstop went active +#endif + +/** + * The axis order in all axis related arrays is X, Y, Z, E + */ +#define _AXIS(AXIS) AXIS ##_AXIS + +void enable_all_steppers(); +void disable_e_steppers(); +void disable_all_steppers(); + +void FlushSerialRequestResend(); +void ok_to_send(); + +void kill(const char*); + +void quickstop_stepper(); + +#if ENABLED(FILAMENT_RUNOUT_SENSOR) + void handle_filament_runout(); +#endif + +extern uint8_t marlin_debug_flags; +#define DEBUGGING(F) (marlin_debug_flags & (DEBUG_## F)) + +extern bool Running; +inline bool IsRunning() { return Running; } +inline bool IsStopped() { return !Running; } + +bool enqueue_and_echo_command(const char* cmd, bool say_ok=false); // Add a single command to the end of the buffer. Return false on failure. +void enqueue_and_echo_commands_P(const char * const cmd); // Set one or more commands to be prioritized over the next Serial/SD command. +void clear_command_queue(); + +extern millis_t previous_cmd_ms; +inline void refresh_cmd_timeout() { previous_cmd_ms = millis(); } + +#if ENABLED(FAST_PWM_FAN) + void setPwmFrequency(uint8_t pin, int val); +#endif + +/** + * Feedrate scaling and conversion + */ +extern int16_t feedrate_percentage; + +#define MMM_TO_MMS(MM_M) ((MM_M)/60.0) +#define MMS_TO_MMM(MM_S) ((MM_S)*60.0) +#define MMS_SCALED(MM_S) ((MM_S)*feedrate_percentage*0.01) + +extern bool axis_relative_modes[]; +extern bool volumetric_enabled; +extern int16_t flow_percentage[EXTRUDERS]; // Extrusion factor for each extruder +extern float filament_size[EXTRUDERS]; // cross-sectional area of filament (in millimeters), typically around 1.75 or 2.85, 0 disables the volumetric calculations for the extruder. +extern float volumetric_multiplier[EXTRUDERS]; // reciprocal of cross-sectional area of filament (in square millimeters), stored this way to reduce computational burden in planner +extern bool axis_known_position[XYZ]; +extern bool axis_homed[XYZ]; +extern volatile bool wait_for_heatup; + +#if HAS_RESUME_CONTINUE + extern volatile bool wait_for_user; +#endif + +extern float current_position[NUM_AXIS]; + +// Workspace offsets +#if HAS_WORKSPACE_OFFSET + #if HAS_HOME_OFFSET + extern float home_offset[XYZ]; + #endif + #if HAS_POSITION_SHIFT + extern float position_shift[XYZ]; + #endif +#endif + +#if HAS_HOME_OFFSET && HAS_POSITION_SHIFT + extern float workspace_offset[XYZ]; + #define WORKSPACE_OFFSET(AXIS) workspace_offset[AXIS] +#elif HAS_HOME_OFFSET + #define WORKSPACE_OFFSET(AXIS) home_offset[AXIS] +#elif HAS_POSITION_SHIFT + #define WORKSPACE_OFFSET(AXIS) position_shift[AXIS] +#else + #define WORKSPACE_OFFSET(AXIS) 0 +#endif + +#define LOGICAL_POSITION(POS, AXIS) ((POS) + WORKSPACE_OFFSET(AXIS)) +#define RAW_POSITION(POS, AXIS) ((POS) - WORKSPACE_OFFSET(AXIS)) + +#if HAS_POSITION_SHIFT || DISABLED(DELTA) + #define LOGICAL_X_POSITION(POS) LOGICAL_POSITION(POS, X_AXIS) + #define LOGICAL_Y_POSITION(POS) LOGICAL_POSITION(POS, Y_AXIS) + #define RAW_X_POSITION(POS) RAW_POSITION(POS, X_AXIS) + #define RAW_Y_POSITION(POS) RAW_POSITION(POS, Y_AXIS) +#else + #define LOGICAL_X_POSITION(POS) (POS) + #define LOGICAL_Y_POSITION(POS) (POS) + #define RAW_X_POSITION(POS) (POS) + #define RAW_Y_POSITION(POS) (POS) +#endif + +#define LOGICAL_Z_POSITION(POS) LOGICAL_POSITION(POS, Z_AXIS) +#define RAW_Z_POSITION(POS) RAW_POSITION(POS, Z_AXIS) +#define RAW_CURRENT_POSITION(A) RAW_##A##_POSITION(current_position[A##_AXIS]) + +// Hotend Offsets +#if HOTENDS > 1 + extern float hotend_offset[XYZ][HOTENDS]; +#endif + +// Software Endstops +extern float soft_endstop_min[XYZ], soft_endstop_max[XYZ]; + +#if HAS_SOFTWARE_ENDSTOPS + extern bool soft_endstops_enabled; + void clamp_to_software_endstops(float target[XYZ]); +#else + #define soft_endstops_enabled false + #define clamp_to_software_endstops(x) NOOP +#endif + +#if HAS_WORKSPACE_OFFSET || ENABLED(DUAL_X_CARRIAGE) + void update_software_endstops(const AxisEnum axis); +#endif + +#if IS_KINEMATIC + extern float delta[ABC]; + void inverse_kinematics(const float logical[XYZ]); +#endif + +#if ENABLED(DELTA) + extern float endstop_adj[ABC], + delta_radius, + delta_diagonal_rod, + delta_calibration_radius, + delta_segments_per_second, + delta_tower_angle_trim[ABC], + delta_clip_start_height; + void recalc_delta_settings(float radius, float diagonal_rod, float tower_angle_trim[ABC]); +#elif IS_SCARA + void forward_kinematics_SCARA(const float &a, const float &b); +#endif + +#if ENABLED(AUTO_BED_LEVELING_BILINEAR) + extern int bilinear_grid_spacing[2], bilinear_start[2]; + extern float bilinear_grid_factor[2], + z_values[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y]; + float bilinear_z_offset(const float logical[XYZ]); +#endif + +#if ENABLED(AUTO_BED_LEVELING_UBL) + typedef struct { double A, B, D; } linear_fit; + linear_fit* lsf_linear_fit(double x[], double y[], double z[], const int); +#endif + +#if HAS_LEVELING + bool leveling_is_valid(); + bool leveling_is_active(); + void set_bed_leveling_enabled(const bool enable=true); + void reset_bed_level(); +#endif + +#if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) + void set_z_fade_height(const float zfh); +#endif + +#if ENABLED(Z_DUAL_ENDSTOPS) + extern float z_endstop_adj; +#endif + +#if HAS_BED_PROBE + extern float zprobe_zoffset; + void refresh_zprobe_zoffset(const bool no_babystep=false); + #define DEPLOY_PROBE() set_probe_deployed(true) + #define STOW_PROBE() set_probe_deployed(false) +#else + #define DEPLOY_PROBE() + #define STOW_PROBE() +#endif + +#if ENABLED(HOST_KEEPALIVE_FEATURE) + extern MarlinBusyState busy_state; + #define KEEPALIVE_STATE(n) do{ busy_state = n; }while(0) +#else + #define KEEPALIVE_STATE(n) NOOP +#endif + +#if FAN_COUNT > 0 + extern int16_t fanSpeeds[FAN_COUNT]; + #if ENABLED(PROBING_FANS_OFF) + extern bool fans_paused; + extern int16_t paused_fanSpeeds[FAN_COUNT]; + #endif +#endif + +#if ENABLED(BARICUDA) + extern uint8_t baricuda_valve_pressure, baricuda_e_to_p_pressure; +#endif + +#if ENABLED(FILAMENT_WIDTH_SENSOR) + extern bool filament_sensor; // Flag that filament sensor readings should control extrusion + extern float filament_width_nominal, // Theoretical filament diameter i.e., 3.00 or 1.75 + filament_width_meas; // Measured filament diameter + extern uint8_t meas_delay_cm, // Delay distance + measurement_delay[]; // Ring buffer to delay measurement + extern int8_t filwidth_delay_index[2]; // Ring buffer indexes. Used by planner, temperature, and main code +#endif + +#if ENABLED(ADVANCED_PAUSE_FEATURE) + extern AdvancedPauseMenuResponse advanced_pause_menu_response; +#endif + +#if ENABLED(PID_EXTRUSION_SCALING) + extern int lpq_len; +#endif + +#if ENABLED(FWRETRACT) + extern bool autoretract_enabled; // M209 S - Autoretract switch + extern float retract_length, // M207 S - G10 Retract length + retract_feedrate_mm_s, // M207 F - G10 Retract feedrate + retract_zlift, // M207 Z - G10 Retract hop size + retract_recover_length, // M208 S - G11 Recover length + retract_recover_feedrate_mm_s, // M208 F - G11 Recover feedrate + swap_retract_length, // M207 W - G10 Swap Retract length + swap_retract_recover_length, // M208 W - G11 Swap Recover length + swap_retract_recover_feedrate_mm_s; // M208 R - G11 Swap Recover feedrate +#endif + +// Print job timer +#if ENABLED(PRINTCOUNTER) + extern PrintCounter print_job_timer; +#else + extern Stopwatch print_job_timer; +#endif + +// Handling multiple extruders pins +extern uint8_t active_extruder; + +#if HAS_TEMP_HOTEND || HAS_TEMP_BED + void print_heaterstates(); +#endif + +#if ENABLED(MIXING_EXTRUDER) + extern float mixing_factor[MIXING_STEPPERS]; +#endif + +void calculate_volumetric_multipliers(); + +/** + * Blocking movement and shorthand functions + */ +void do_blocking_move_to(const float &x, const float &y, const float &z, const float &fr_mm_s=0.0); +void do_blocking_move_to_x(const float &x, const float &fr_mm_s=0.0); +void do_blocking_move_to_z(const float &z, const float &fr_mm_s=0.0); +void do_blocking_move_to_xy(const float &x, const float &y, const float &fr_mm_s=0.0); + +#define HAS_AXIS_UNHOMED_ERR ( \ + ENABLED(Z_PROBE_ALLEN_KEY) \ + || ENABLED(Z_PROBE_SLED) \ + || HAS_PROBING_PROCEDURE \ + || HOTENDS > 1 \ + || ENABLED(NOZZLE_CLEAN_FEATURE) \ + || ENABLED(NOZZLE_PARK_FEATURE) \ + || (ENABLED(ADVANCED_PAUSE_FEATURE) && ENABLED(HOME_BEFORE_FILAMENT_CHANGE)) \ + ) || ENABLED(NO_MOTION_BEFORE_HOMING) + +#if HAS_AXIS_UNHOMED_ERR + bool axis_unhomed_error(const bool x=true, const bool y=true, const bool z=true); +#endif + +/** + * position_is_reachable family of functions + */ + +#if IS_KINEMATIC // (DELTA or SCARA) + + #if IS_SCARA + extern const float L1, L2; + #endif + + inline bool position_is_reachable_raw_xy(const float &rx, const float &ry) { + #if ENABLED(DELTA) + return HYPOT2(rx, ry) <= sq(DELTA_PRINTABLE_RADIUS); + #elif IS_SCARA + #if MIDDLE_DEAD_ZONE_R > 0 + const float R2 = HYPOT2(rx - SCARA_OFFSET_X, ry - SCARA_OFFSET_Y); + return R2 >= sq(float(MIDDLE_DEAD_ZONE_R)) && R2 <= sq(L1 + L2); + #else + return HYPOT2(rx - SCARA_OFFSET_X, ry - SCARA_OFFSET_Y) <= sq(L1 + L2); + #endif + #else // CARTESIAN + // To be migrated from MakerArm branch in future + #endif + } + + inline bool position_is_reachable_by_probe_raw_xy(const float &rx, const float &ry) { + + // Both the nozzle and the probe must be able to reach the point. + // This won't work on SCARA since the probe offset rotates with the arm. + + return position_is_reachable_raw_xy(rx, ry) + && position_is_reachable_raw_xy(rx - X_PROBE_OFFSET_FROM_EXTRUDER, ry - Y_PROBE_OFFSET_FROM_EXTRUDER); + } + +#else // CARTESIAN + + inline bool position_is_reachable_raw_xy(const float &rx, const float &ry) { + // Add 0.001 margin to deal with float imprecision + return WITHIN(rx, X_MIN_POS - 0.001, X_MAX_POS + 0.001) + && WITHIN(ry, Y_MIN_POS - 0.001, Y_MAX_POS + 0.001); + } + + inline bool position_is_reachable_by_probe_raw_xy(const float &rx, const float &ry) { + // Add 0.001 margin to deal with float imprecision + return WITHIN(rx, MIN_PROBE_X - 0.001, MAX_PROBE_X + 0.001) + && WITHIN(ry, MIN_PROBE_Y - 0.001, MAX_PROBE_Y + 0.001); + } + +#endif // CARTESIAN + +FORCE_INLINE bool position_is_reachable_by_probe_xy(const float &lx, const float &ly) { + return position_is_reachable_by_probe_raw_xy(RAW_X_POSITION(lx), RAW_Y_POSITION(ly)); +} + +FORCE_INLINE bool position_is_reachable_xy(const float &lx, const float &ly) { + return position_is_reachable_raw_xy(RAW_X_POSITION(lx), RAW_Y_POSITION(ly)); +} + +#endif // MARLIN_H diff --git a/trunk/Arduino/Marlin_1.1.6/MarlinConfig.h b/trunk/Arduino/Marlin_1.1.6/MarlinConfig.h new file mode 100644 index 00000000..64e0bac5 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/MarlinConfig.h @@ -0,0 +1,41 @@ +/** + * 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 . + * + */ + +#ifndef MARLIN_CONFIG_H +#define MARLIN_CONFIG_H + +#include "fastio.h" +#include "macros.h" +#include "boards.h" +#include "Version.h" +#include "Configuration.h" +#include "Conditionals_LCD.h" +#include "Configuration_adv.h" +#include "pins.h" +#ifndef USBCON + #define HardwareSerial_h // trick to disable the standard HWserial +#endif +#include "Arduino.h" +#include "Conditionals_post.h" +#include "SanityCheck.h" + +#endif // MARLIN_CONFIG_H diff --git a/trunk/Arduino/Marlin_1.1.6/MarlinSerial.cpp b/trunk/Arduino/Marlin_1.1.6/MarlinSerial.cpp new file mode 100644 index 00000000..896db69c --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/MarlinSerial.cpp @@ -0,0 +1,654 @@ +/** + * 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 . + * + */ + +/** + * 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) + */ + +// Disable HardwareSerial.cpp to support chips without a UART (Attiny, etc.) + +#include "MarlinConfig.h" + +#if !defined(USBCON) && (defined(UBRRH) || defined(UBRR0H) || defined(UBRR1H) || defined(UBRR2H) || defined(UBRR3H)) + + #include "MarlinSerial.h" + #include "Marlin.h" + + struct ring_buffer_r { + unsigned char buffer[RX_BUFFER_SIZE]; + volatile ring_buffer_pos_t head, tail; + }; + + #if TX_BUFFER_SIZE > 0 + struct ring_buffer_t { + unsigned char buffer[TX_BUFFER_SIZE]; + volatile uint8_t head, tail; + }; + #endif + + #if UART_PRESENT(SERIAL_PORT) + ring_buffer_r rx_buffer = { { 0 }, 0, 0 }; + #if TX_BUFFER_SIZE > 0 + ring_buffer_t tx_buffer = { { 0 }, 0, 0 }; + static bool _written; + #endif + #endif + + #if ENABLED(SERIAL_XON_XOFF) + constexpr uint8_t XON_XOFF_CHAR_SENT = 0x80; // XON / XOFF Character was sent + constexpr uint8_t XON_XOFF_CHAR_MASK = 0x1F; // XON / XOFF character to send + // XON / XOFF character definitions + constexpr uint8_t XON_CHAR = 17; + constexpr uint8_t XOFF_CHAR = 19; + uint8_t xon_xoff_state = XON_XOFF_CHAR_SENT | XON_CHAR; + #endif + + #if ENABLED(SERIAL_STATS_DROPPED_RX) + uint8_t rx_dropped_bytes = 0; + #endif + + #if ENABLED(SERIAL_STATS_MAX_RX_QUEUED) + ring_buffer_pos_t rx_max_enqueued = 0; + #endif + + #if ENABLED(EMERGENCY_PARSER) + + #include "stepper.h" + #include "language.h" + + // Currently looking for: M108, M112, M410 + // If you alter the parser please don't forget to update the capabilities in Conditionals_post.h + + FORCE_INLINE void emergency_parser(const unsigned char c) { + + static e_parser_state state = state_RESET; + + switch (state) { + case state_RESET: + switch (c) { + case ' ': break; + case 'N': state = state_N; break; + case 'M': state = state_M; break; + default: state = state_IGNORE; + } + break; + + case state_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 'M': state = state_M; break; + default: state = state_IGNORE; + } + break; + + case state_M: + switch (c) { + case ' ': break; + case '1': state = state_M1; break; + case '4': state = state_M4; break; + default: state = state_IGNORE; + } + break; + + case state_M1: + switch (c) { + case '0': state = state_M10; break; + case '1': state = state_M11; break; + default: state = state_IGNORE; + } + break; + + case state_M10: + state = (c == '8') ? state_M108 : state_IGNORE; + break; + + case state_M11: + state = (c == '2') ? state_M112 : state_IGNORE; + break; + + case state_M4: + state = (c == '1') ? state_M41 : state_IGNORE; + break; + + case state_M41: + state = (c == '0') ? state_M410 : state_IGNORE; + break; + + case state_IGNORE: + if (c == '\n') state = state_RESET; + break; + + default: + if (c == '\n') { + switch (state) { + case state_M108: + wait_for_user = wait_for_heatup = false; + break; + case state_M112: + kill(PSTR(MSG_KILLED)); + break; + case state_M410: + quickstop_stepper(); + break; + default: + break; + } + state = state_RESET; + } + } + } + + #endif // EMERGENCY_PARSER + + FORCE_INLINE void store_rxd_char() { + const ring_buffer_pos_t h = rx_buffer.head, + i = (ring_buffer_pos_t)(h + 1) & (ring_buffer_pos_t)(RX_BUFFER_SIZE - 1); + + // 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 buffer is + // critical, so don't write the character or advance the head. + const char c = M_UDRx; + if (i != rx_buffer.tail) { + rx_buffer.buffer[h] = c; + rx_buffer.head = i; + } + else { + #if ENABLED(SERIAL_STATS_DROPPED_RX) + if (!++rx_dropped_bytes) ++rx_dropped_bytes; + #endif + } + + #if ENABLED(SERIAL_STATS_MAX_RX_QUEUED) + // calculate count of bytes stored into the RX buffer + ring_buffer_pos_t rx_count = (ring_buffer_pos_t)(rx_buffer.head - rx_buffer.tail) & (ring_buffer_pos_t)(RX_BUFFER_SIZE - 1); + // Keep track of the maximum count of enqueued bytes + NOLESS(rx_max_enqueued, rx_count); + #endif + + #if ENABLED(SERIAL_XON_XOFF) + + // for high speed transfers, we can use XON/XOFF protocol to do + // software handshake and avoid overruns. + if ((xon_xoff_state & XON_XOFF_CHAR_MASK) == XON_CHAR) { + + // calculate count of bytes stored into the RX buffer + ring_buffer_pos_t rx_count = (ring_buffer_pos_t)(rx_buffer.head - rx_buffer.tail) & (ring_buffer_pos_t)(RX_BUFFER_SIZE - 1); + + // if we are above 12.5% of RX buffer capacity, send XOFF before + // we run out of RX buffer space .. We need 325 bytes @ 250kbits/s to + // let the host react and stop sending bytes. This translates to 13mS + // propagation time. + if (rx_count >= (RX_BUFFER_SIZE) / 8) { + // If TX interrupts are disabled and 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. + if (!TEST(M_UCSRxB, M_UDRIEx) && TEST(M_UCSRxA, M_UDREx)) { + // Send an XOFF character + M_UDRx = 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 + SBI(M_UCSRxA, M_TXCx); + // And remember it was sent + xon_xoff_state = XOFF_CHAR | XON_XOFF_CHAR_SENT; + } + else { + // TX interrupts disabled, but buffer still not empty ... or + // TX interrupts enabled. Reenable TX ints and schedule XOFF + // character to be sent + #if TX_BUFFER_SIZE > 0 + SBI(M_UCSRxB, M_UDRIEx); + xon_xoff_state = XOFF_CHAR; + #else + // We are not using TX interrupts, we will have to send this manually + while (!TEST(M_UCSRxA, M_UDREx)) {/* nada */} + M_UDRx = XOFF_CHAR; + // And remember we already sent it + xon_xoff_state = XOFF_CHAR | XON_XOFF_CHAR_SENT; + #endif + } + } + } + #endif // SERIAL_XON_XOFF + + #if ENABLED(EMERGENCY_PARSER) + emergency_parser(c); + #endif + } + + #if TX_BUFFER_SIZE > 0 + + FORCE_INLINE void _tx_udr_empty_irq(void) { + // If interrupts are enabled, there must be more data in the output + // buffer. + + #if ENABLED(SERIAL_XON_XOFF) + // Do a priority insertion of an XON/XOFF char, if needed. + const uint8_t state = xon_xoff_state; + if (!(state & XON_XOFF_CHAR_SENT)) { + M_UDRx = state & XON_XOFF_CHAR_MASK; + xon_xoff_state = state | XON_XOFF_CHAR_SENT; + } + else + #endif + { // Send the next byte + const uint8_t t = tx_buffer.tail, c = tx_buffer.buffer[t]; + tx_buffer.tail = (t + 1) & (TX_BUFFER_SIZE - 1); + M_UDRx = 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 + SBI(M_UCSRxA, M_TXCx); + + // Disable interrupts if the buffer is empty + if (tx_buffer.head == tx_buffer.tail) + CBI(M_UCSRxB, M_UDRIEx); + } + + #ifdef M_USARTx_UDRE_vect + ISR(M_USARTx_UDRE_vect) { _tx_udr_empty_irq(); } + #endif + + #endif // TX_BUFFER_SIZE + + #ifdef M_USARTx_RX_vect + ISR(M_USARTx_RX_vect) { store_rxd_char(); } + #endif + + // Public Methods + + 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 + + if (useU2X) { + M_UCSRxA = _BV(M_U2Xx); + baud_setting = (F_CPU / 4 / baud - 1) / 2; + } + else { + M_UCSRxA = 0; + baud_setting = (F_CPU / 8 / baud - 1) / 2; + } + + // assign the baud_setting, a.k.a. ubbr (USART Baud Rate Register) + M_UBRRxH = baud_setting >> 8; + M_UBRRxL = baud_setting; + + SBI(M_UCSRxB, M_RXENx); + SBI(M_UCSRxB, M_TXENx); + SBI(M_UCSRxB, M_RXCIEx); + #if TX_BUFFER_SIZE > 0 + CBI(M_UCSRxB, M_UDRIEx); + _written = false; + #endif + } + + void MarlinSerial::end() { + CBI(M_UCSRxB, M_RXENx); + CBI(M_UCSRxB, M_TXENx); + CBI(M_UCSRxB, M_RXCIEx); + CBI(M_UCSRxB, M_UDRIEx); + } + + void MarlinSerial::checkRx(void) { + if (TEST(M_UCSRxA, M_RXCx)) { + CRITICAL_SECTION_START; + store_rxd_char(); + CRITICAL_SECTION_END; + } + } + + int MarlinSerial::peek(void) { + CRITICAL_SECTION_START; + const int v = rx_buffer.head == rx_buffer.tail ? -1 : rx_buffer.buffer[rx_buffer.tail]; + CRITICAL_SECTION_END; + return v; + } + + int MarlinSerial::read(void) { + int v; + CRITICAL_SECTION_START; + const ring_buffer_pos_t t = rx_buffer.tail; + if (rx_buffer.head == t) + v = -1; + else { + v = rx_buffer.buffer[t]; + rx_buffer.tail = (ring_buffer_pos_t)(t + 1) & (RX_BUFFER_SIZE - 1); + + #if ENABLED(SERIAL_XON_XOFF) + if ((xon_xoff_state & XON_XOFF_CHAR_MASK) == XOFF_CHAR) { + // Get count of bytes in the RX buffer + ring_buffer_pos_t rx_count = (ring_buffer_pos_t)(rx_buffer.head - rx_buffer.tail) & (ring_buffer_pos_t)(RX_BUFFER_SIZE - 1); + // When below 10% of RX buffer capacity, send XON before + // running out of RX buffer bytes + if (rx_count < (RX_BUFFER_SIZE) / 10) { + xon_xoff_state = XON_CHAR | XON_XOFF_CHAR_SENT; + CRITICAL_SECTION_END; // End critical section before returning! + writeNoHandshake(XON_CHAR); + return v; + } + } + #endif + } + CRITICAL_SECTION_END; + return v; + } + + ring_buffer_pos_t MarlinSerial::available(void) { + CRITICAL_SECTION_START; + const ring_buffer_pos_t h = rx_buffer.head, t = rx_buffer.tail; + CRITICAL_SECTION_END; + return (ring_buffer_pos_t)(RX_BUFFER_SIZE + h - t) & (RX_BUFFER_SIZE - 1); + } + + void MarlinSerial::flush(void) { + // Don't change this order of operations. If the RX interrupt occurs between + // reading rx_buffer_head and updating rx_buffer_tail, the previous rx_buffer_head + // may be written to rx_buffer_tail, making the buffer appear full rather than empty. + CRITICAL_SECTION_START; + rx_buffer.head = rx_buffer.tail; + CRITICAL_SECTION_END; + + #if ENABLED(SERIAL_XON_XOFF) + if ((xon_xoff_state & XON_XOFF_CHAR_MASK) == XOFF_CHAR) { + xon_xoff_state = XON_CHAR | XON_XOFF_CHAR_SENT; + writeNoHandshake(XON_CHAR); + } + #endif + } + + #if TX_BUFFER_SIZE > 0 + uint8_t MarlinSerial::availableForWrite(void) { + CRITICAL_SECTION_START; + const uint8_t h = tx_buffer.head, t = tx_buffer.tail; + CRITICAL_SECTION_END; + return (uint8_t)(TX_BUFFER_SIZE + h - t) & (TX_BUFFER_SIZE - 1); + } + + void MarlinSerial::write(const uint8_t c) { + #if ENABLED(SERIAL_XON_XOFF) + const uint8_t state = xon_xoff_state; + if (!(state & XON_XOFF_CHAR_SENT)) { + // Send 2 chars: XON/XOFF, then a user-specified char + writeNoHandshake(state & XON_XOFF_CHAR_MASK); + xon_xoff_state = state | XON_XOFF_CHAR_SENT; + } + #endif + writeNoHandshake(c); + } + + void MarlinSerial::writeNoHandshake(const uint8_t c) { + _written = true; + CRITICAL_SECTION_START; + bool emty = (tx_buffer.head == tx_buffer.tail); + CRITICAL_SECTION_END; + + // If the buffer 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. + if (emty && TEST(M_UCSRxA, M_UDREx)) { + CRITICAL_SECTION_START; + M_UDRx = c; + SBI(M_UCSRxA, M_TXCx); + CRITICAL_SECTION_END; + return; + } + const uint8_t i = (tx_buffer.head + 1) & (TX_BUFFER_SIZE - 1); + + // If the output buffer is full, there's nothing for it other than to + // wait for the interrupt handler to empty it a bit + while (i == tx_buffer.tail) { + if (!TEST(SREG, SREG_I)) { + // Interrupts are disabled, so we'll have to poll the data + // register empty flag ourselves. If it is set, pretend an + // interrupt has happened and call the handler to free up + // space for us. + if (TEST(M_UCSRxA, M_UDREx)) + _tx_udr_empty_irq(); + } + else { + // nop, the interrupt handler will free up space for us + } + } + + tx_buffer.buffer[tx_buffer.head] = c; + { CRITICAL_SECTION_START; + tx_buffer.head = i; + SBI(M_UCSRxB, M_UDRIEx); + CRITICAL_SECTION_END; + } + return; + } + + void MarlinSerial::flushTX(void) { + // TX + // If we have never written a byte, no need to flush. This special + // case is needed since there is no way to force the TXC (transmit + // complete) bit to 1 during initialization + if (!_written) + return; + + while (TEST(M_UCSRxB, M_UDRIEx) || !TEST(M_UCSRxA, M_TXCx)) { + if (!TEST(SREG, SREG_I) && TEST(M_UCSRxB, M_UDRIEx)) + // Interrupts are globally disabled, but the DR empty + // interrupt should be enabled, so poll the DR empty flag to + // prevent deadlock + if (TEST(M_UCSRxA, M_UDREx)) + _tx_udr_empty_irq(); + } + // If we get here, nothing is queued anymore (DRIE is disabled) and + // the hardware finished tranmission (TXC is set). + } + + #else // TX_BUFFER_SIZE == 0 + + void MarlinSerial::write(const uint8_t c) { + #if ENABLED(SERIAL_XON_XOFF) + // Do a priority insertion of an XON/XOFF char, if needed. + const uint8_t state = xon_xoff_state; + if (!(state & XON_XOFF_CHAR_SENT)) { + writeNoHandshake(state & XON_XOFF_CHAR_MASK); + xon_xoff_state = state | XON_XOFF_CHAR_SENT; + } + #endif + writeNoHandshake(c); + } + + void MarlinSerial::writeNoHandshake(uint8_t c) { + while (!TEST(M_UCSRxA, M_UDREx)) {/* nada */} + M_UDRx = c; + } + + #endif // TX_BUFFER_SIZE == 0 + + /** + * Imports from print.h + */ + + void MarlinSerial::print(char c, int base) { + print((long)c, base); + } + + void MarlinSerial::print(unsigned char b, int base) { + print((unsigned long)b, base); + } + + void MarlinSerial::print(int n, int base) { + print((long)n, base); + } + + void MarlinSerial::print(unsigned int n, int base) { + print((unsigned long)n, base); + } + + 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); + } + + void MarlinSerial::print(unsigned long n, int base) { + if (base == 0) write(n); + else printNumber(n, base); + } + + void MarlinSerial::print(double n, int digits) { + printFloat(n, digits); + } + + void MarlinSerial::println(void) { + print('\r'); + print('\n'); + } + + void MarlinSerial::println(const String& s) { + print(s); + println(); + } + + void MarlinSerial::println(const char c[]) { + print(c); + println(); + } + + void MarlinSerial::println(char c, int base) { + print(c, base); + println(); + } + + void MarlinSerial::println(unsigned char b, int base) { + print(b, base); + println(); + } + + void MarlinSerial::println(int n, int base) { + print(n, base); + println(); + } + + void MarlinSerial::println(unsigned int n, int base) { + print(n, base); + println(); + } + + void MarlinSerial::println(long n, int base) { + print(n, base); + println(); + } + + void MarlinSerial::println(unsigned long n, int base) { + print(n, base); + println(); + } + + void MarlinSerial::println(double n, int digits) { + print(n, digits); + println(); + } + + // Private Methods + + 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'); + } + + 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; + } + } + } + + // Preinstantiate + MarlinSerial customizedSerial; + +#endif // !USBCON && (UBRRH || UBRR0H || UBRR1H || UBRR2H || UBRR3H) + +// For AT90USB targets use the UART for BT interfacing +#if defined(USBCON) && ENABLED(BLUETOOTH) + HardwareSerial bluetoothSerial; +#endif diff --git a/trunk/Arduino/Marlin_1.1.6/MarlinSerial.h b/trunk/Arduino/Marlin_1.1.6/MarlinSerial.h new file mode 100644 index 00000000..6282c894 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/MarlinSerial.h @@ -0,0 +1,180 @@ +/** + * 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 . + * + */ + +/** + MarlinSerial.h - Hardware serial library for Wiring + Copyright (c) 2006 Nicholas Zambetti. All right reserved. + + Modified 28 September 2010 by Mark Sproul + Modified 14 February 2016 by Andreas Hardtung (added tx buffer) + +*/ + +#ifndef MARLINSERIAL_H +#define MARLINSERIAL_H + +#include "MarlinConfig.h" + +#ifndef SERIAL_PORT + #define SERIAL_PORT 0 +#endif + +// The presence of the UBRRH register is used to detect a UART. +#define UART_PRESENT(port) ((port == 0 && (defined(UBRRH) || defined(UBRR0H))) || \ + (port == 1 && defined(UBRR1H)) || (port == 2 && defined(UBRR2H)) || \ + (port == 3 && defined(UBRR3H))) + +// 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) +#if SERIAL_PORT == 0 && (!defined(UBRR0H) || !defined(UDR0)) // use un-numbered registers if necessary + #define SERIAL_REGNAME_INTERNAL(registerbase,number,suffix) registerbase##suffix +#else + #define SERIAL_REGNAME_INTERNAL(registerbase,number,suffix) registerbase##number##suffix +#endif + +// Registers used by MarlinSerial class (expanded depending on selected serial port) +#define M_UCSRxA SERIAL_REGNAME(UCSR,SERIAL_PORT,A) // defines M_UCSRxA to be UCSRnA where n is the serial port number +#define M_UCSRxB SERIAL_REGNAME(UCSR,SERIAL_PORT,B) +#define M_RXENx SERIAL_REGNAME(RXEN,SERIAL_PORT,) +#define M_TXENx SERIAL_REGNAME(TXEN,SERIAL_PORT,) +#define M_TXCx SERIAL_REGNAME(TXC,SERIAL_PORT,) +#define M_RXCIEx SERIAL_REGNAME(RXCIE,SERIAL_PORT,) +#define M_UDREx SERIAL_REGNAME(UDRE,SERIAL_PORT,) +#define M_UDRIEx SERIAL_REGNAME(UDRIE,SERIAL_PORT,) +#define M_UDRx SERIAL_REGNAME(UDR,SERIAL_PORT,) +#define M_UBRRxH SERIAL_REGNAME(UBRR,SERIAL_PORT,H) +#define M_UBRRxL SERIAL_REGNAME(UBRR,SERIAL_PORT,L) +#define M_RXCx SERIAL_REGNAME(RXC,SERIAL_PORT,) +#define M_USARTx_RX_vect SERIAL_REGNAME(USART,SERIAL_PORT,_RX_vect) +#define M_U2Xx SERIAL_REGNAME(U2X,SERIAL_PORT,) +#define M_USARTx_UDRE_vect SERIAL_REGNAME(USART,SERIAL_PORT,_UDRE_vect) + +#define DEC 10 +#define HEX 16 +#define OCT 8 +#define BIN 2 +#define BYTE 0 + +#ifndef USBCON + // Define constants and variables for buffering incoming serial data. We're + // using a ring buffer (I think), in which rx_buffer_head is the index of the + // location to which to write the next incoming character and rx_buffer_tail + // is the index of the location from which to read. + // 256 is the max limit due to uint8_t head and tail. Use only powers of 2. (...,16,32,64,128,256) + #ifndef RX_BUFFER_SIZE + #define RX_BUFFER_SIZE 128 + #endif + #ifndef TX_BUFFER_SIZE + #define TX_BUFFER_SIZE 32 + #endif + + #if ENABLED(SERIAL_XON_XOFF) && RX_BUFFER_SIZE < 1024 + #error "XON/XOFF requires RX_BUFFER_SIZE >= 1024 for reliable transfers without drops." + #endif + #if !IS_POWER_OF_2(RX_BUFFER_SIZE) || RX_BUFFER_SIZE < 2 + #error "RX_BUFFER_SIZE must be a power of 2 greater than 1." + #endif + #if TX_BUFFER_SIZE && (TX_BUFFER_SIZE < 2 || TX_BUFFER_SIZE > 256 || !IS_POWER_OF_2(TX_BUFFER_SIZE)) + #error "TX_BUFFER_SIZE must be 0 or a power of 2 greater than 1." + #endif + + #if RX_BUFFER_SIZE > 256 + typedef uint16_t ring_buffer_pos_t; + #else + typedef uint8_t ring_buffer_pos_t; + #endif + + #if ENABLED(SERIAL_STATS_DROPPED_RX) + extern uint8_t rx_dropped_bytes; + #endif + + #if ENABLED(SERIAL_STATS_MAX_RX_QUEUED) + extern ring_buffer_pos_t rx_max_enqueued; + #endif + + class MarlinSerial { //: public Stream + + public: + MarlinSerial() {}; + static void begin(const long); + static void end(); + static int peek(void); + static int read(void); + static void flush(void); + static ring_buffer_pos_t available(void); + static void checkRx(void); + static void write(const uint8_t c); + #if TX_BUFFER_SIZE > 0 + static uint8_t availableForWrite(void); + static void flushTX(void); + #endif + static void writeNoHandshake(const uint8_t c); + + #if ENABLED(SERIAL_STATS_DROPPED_RX) + FORCE_INLINE static uint32_t dropped() { return rx_dropped_bytes; } + #endif + + #if ENABLED(SERIAL_STATS_MAX_RX_QUEUED) + FORCE_INLINE static ring_buffer_pos_t rxMaxEnqueued() { return rx_max_enqueued; } + #endif + + private: + static void printNumber(unsigned long, const uint8_t); + static void printFloat(double, uint8_t); + + public: + static FORCE_INLINE void write(const char* str) { while (*str) write(*str++); } + static FORCE_INLINE void write(const uint8_t* buffer, size_t size) { while (size--) write(*buffer++); } + static FORCE_INLINE void print(const String& s) { for (int i = 0; i < (int)s.length(); i++) write(s[i]); } + static FORCE_INLINE void print(const char* str) { write(str); } + + static void print(char, int = BYTE); + static void print(unsigned char, int = BYTE); + static void print(int, int = DEC); + static void print(unsigned int, int = DEC); + static void print(long, int = DEC); + static void print(unsigned long, int = DEC); + static void print(double, int = 2); + + static void println(const String& s); + static void println(const char[]); + static void println(char, int = BYTE); + static void println(unsigned char, int = BYTE); + static void println(int, int = DEC); + static void println(unsigned int, int = DEC); + static void println(long, int = DEC); + static void println(unsigned long, int = DEC); + static void println(double, int = 2); + static void println(void); + }; + + extern MarlinSerial customizedSerial; + +#endif // !USBCON + +// Use the UART for Bluetooth in AT90USB configurations +#if defined(USBCON) && ENABLED(BLUETOOTH) + extern HardwareSerial bluetoothSerial; +#endif + +#endif // MARLINSERIAL_H diff --git a/trunk/Arduino/Marlin_1.1.6/Marlin_1.1.6.ino b/trunk/Arduino/Marlin_1.1.6/Marlin_1.1.6.ino new file mode 100644 index 00000000..49b6fd14 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/Marlin_1.1.6.ino @@ -0,0 +1,72 @@ +/** + * 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 . + * + */ + +/** + * About Marlin + * + * This firmware is a mashup between Sprinter and grbl. + * - https://github.com/kliment/Sprinter + * - https://github.com/simen/grbl/tree + */ + +#include "MarlinConfig.h" + +#if ENABLED(ULTRA_LCD) + #if ENABLED(LCD_I2C_TYPE_PCF8575) + #include + #include + #elif ENABLED(LCD_I2C_TYPE_MCP23017) || ENABLED(LCD_I2C_TYPE_MCP23008) + #include + #include + #elif ENABLED(LCM1602) + #include + #include + #include + #elif ENABLED(DOGLCD) + #include // library for graphics LCD by Oli Kraus (https://github.com/olikraus/U8glib_Arduino) + #else + #include // library for character LCD + #endif +#endif + +#if HAS_DIGIPOTSS + #include +#endif + +#if ENABLED(DIGIPOT_I2C) + #include +#endif + +#if ENABLED(HAVE_TMCDRIVER) + #include + #include +#endif + +#if ENABLED(HAVE_TMC2130) + #include + #include +#endif + +#if ENABLED(HAVE_L6470DRIVER) + #include + #include +#endif diff --git a/trunk/Arduino/Marlin_1.1.6/Marlin_main.cpp b/trunk/Arduino/Marlin_1.1.6/Marlin_main.cpp new file mode 100644 index 00000000..3ac04338 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/Marlin_main.cpp @@ -0,0 +1,13689 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2016, 2017 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** + * About Marlin + * + * This firmware is a mashup between Sprinter and grbl. + * - https://github.com/kliment/Sprinter + * - https://github.com/simen/grbl/tree + */ + +/** + * ----------------- + * G-Codes in Marlin + * ----------------- + * + * Helpful G-code references: + * - http://linuxcnc.org/handbook/gcode/g-code.html + * - http://objects.reprap.org/wiki/Mendel_User_Manual:_RepRapGCodes + * + * Help to document Marlin's G-codes online: + * - http://reprap.org/wiki/G-code + * - https://github.com/MarlinFirmware/MarlinDocumentation + * + * ----------------- + * + * "G" Codes + * + * G0 -> G1 + * G1 - Coordinated Movement X Y Z E + * G2 - CW ARC + * G3 - CCW ARC + * G4 - Dwell S or P + * G5 - Cubic B-spline with XYZE destination and IJPQ offsets + * G10 - Retract filament according to settings of M207 (Requires FWRETRACT) + * G11 - Retract recover filament according to settings of M208 (Requires FWRETRACT) + * G12 - Clean tool (Requires NOZZLE_CLEAN_FEATURE) + * G17 - Select Plane XY (Requires CNC_WORKSPACE_PLANES) + * G18 - Select Plane ZX (Requires CNC_WORKSPACE_PLANES) + * G19 - Select Plane YZ (Requires CNC_WORKSPACE_PLANES) + * G20 - Set input units to inches (Requires INCH_MODE_SUPPORT) + * G21 - Set input units to millimeters (Requires INCH_MODE_SUPPORT) + * G26 - Mesh Validation Pattern (Requires UBL_G26_MESH_VALIDATION) + * G27 - Park Nozzle (Requires NOZZLE_PARK_FEATURE) + * G28 - Home one or more axes + * G29 - Start or continue the bed leveling probe procedure (Requires bed leveling) + * G30 - Single Z probe, probes bed at X Y location (defaults to current XY location) + * G31 - Dock sled (Z_PROBE_SLED only) + * G32 - Undock sled (Z_PROBE_SLED only) + * G33 - Delta Auto-Calibration (Requires DELTA_AUTO_CALIBRATION) + * G38 - Probe in any direction using the Z_MIN_PROBE (Requires G38_PROBE_TARGET) + * G42 - Coordinated move to a mesh point (Requires AUTO_BED_LEVELING_UBL) + * G90 - Use Absolute Coordinates + * G91 - Use Relative Coordinates + * G92 - Set current position to coordinates given + * + * "M" Codes + * + * M0 - Unconditional stop - Wait for user to press a button on the LCD (Only if ULTRA_LCD is enabled) + * M1 -> M0 + * M3 - Turn laser/spindle on, set spindle/laser speed/power, set rotation to clockwise + * M4 - Turn laser/spindle on, set spindle/laser speed/power, set rotation to counter-clockwise + * M5 - Turn laser/spindle off + * M17 - Enable/Power all stepper motors + * M18 - Disable all stepper motors; same as M84 + * M20 - List SD card. (Requires SDSUPPORT) + * M21 - Init SD card. (Requires SDSUPPORT) + * M22 - Release SD card. (Requires SDSUPPORT) + * M23 - Select SD file: "M23 /path/file.gco". (Requires SDSUPPORT) + * M24 - Start/resume SD print. (Requires SDSUPPORT) + * M25 - Pause SD print. (Requires SDSUPPORT) + * M26 - Set SD position in bytes: "M26 S12345". (Requires SDSUPPORT) + * M27 - Report SD print status. (Requires SDSUPPORT) + * M28 - Start SD write: "M28 /path/file.gco". (Requires SDSUPPORT) + * M29 - Stop SD write. (Requires SDSUPPORT) + * M30 - Delete file from SD: "M30 /path/file.gco" + * M31 - Report time since last M109 or SD card start to serial. + * M32 - Select file and start SD print: "M32 [S] !/path/file.gco#". (Requires SDSUPPORT) + * Use P to run other files as sub-programs: "M32 P !filename#" + * 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. + * 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. (Requires Z_MIN_PROBE_REPEATABILITY_TEST) + * M75 - Start the print job timer. + * M76 - Pause the print job timer. + * M77 - Stop the print job timer. + * M78 - Show statistical information about the print jobs. (Requires PRINTCOUNTER) + * M80 - Turn on Power Supply. (Requires POWER_SUPPLY > 0) + * M81 - Turn off Power Supply. (Requires POWER_SUPPLY > 0) + * M82 - Set E codes absolute (default). + * M83 - Set E codes relative while in Absolute (G90) mode. + * M84 - Disable steppers until next move, or use S to specify an idle + * duration after which steppers should turn off. S0 disables the timeout. + * M85 - Set inactivity shutdown timer with parameter S. To disable set zero (default) + * M92 - Set planner.axis_steps_per_mm for one or more axes. + * M100 - Watch Free Memory (for debugging) (Requires M100_FREE_MEMORY_WATCHER) + * M104 - Set extruder target temp. + * M105 - Report current temperatures. + * M106 - Fan on. + * M107 - Fan off. + * M108 - Break out of heating loops (M109, M190, M303). With no controller, breaks out of M0/M1. (Requires EMERGENCY_PARSER) + * M109 - Sxxx Wait for extruder current temp to reach target temp. Waits only when heating + * Rxxx Wait for extruder current temp to reach target temp. Waits when heating and cooling + * If AUTOTEMP is enabled, S B F. Exit autotemp by any M109 without F + * M110 - Set the current line number. (Used by host printing) + * M111 - Set debug flags: "M111 S". See flag bits defined in enum.h. + * M112 - Emergency stop. + * M113 - Get or set the timeout interval for Host Keepalive "busy" messages. (Requires HOST_KEEPALIVE_FEATURE) + * M114 - Report current position. + * M115 - Report capabilities. (Extended capabilities requires EXTENDED_CAPABILITIES_REPORT) + * M117 - Display a message on the controller screen. (Requires an LCD) + * M118 - Display a message in the host console. + * M119 - Report endstops status. + * M120 - Enable endstops detection. + * M121 - Disable endstops detection. + * M125 - Save current position and move to filament change position. (Requires PARK_HEAD_ON_PAUSE) + * M126 - Solenoid Air Valve Open. (Requires BARICUDA) + * M127 - Solenoid Air Valve Closed. (Requires BARICUDA) + * M128 - EtoP Open. (Requires BARICUDA) + * M129 - EtoP Closed. (Requires BARICUDA) + * M140 - Set bed target temp. S + * 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, 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 - Save the mix as a virtual extruder. (Requires MIXING_EXTRUDER and MIXING_VIRTUAL_TOOLS) + * M165 - Set the proportions for a mixing extruder. Use parameters ABCDHI to set the mixing factors. (Requires MIXING_EXTRUDER) + * 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 for heating or cooling. ** + * M200 - Set filament diameter, D, setting E axis units to cubic. (Use S0 to revert to linear units.) + * M201 - Set max acceleration in units/s^2 for print moves: "M201 X Y Z E" + * M202 - Set max acceleration in units/s^2 for travel moves: "M202 X Y Z E" ** UNUSED IN MARLIN! ** + * M203 - Set maximum feedrate: "M203 X Y Z E" in units/sec. + * M204 - Set default acceleration in units/sec^2: P R T + * M205 - Set advanced settings. Current units apply: + S T minimum speeds + B + X, Y, Z, E + * M206 - Set additional homing offset. (Disabled by NO_WORKSPACE_OFFSETS or DELTA) + * M207 - Set Retract Length: S, Feedrate: F, and Z lift: Z. (Requires FWRETRACT) + * M208 - Set Recover (unretract) Additional (!) Length: S and Feedrate: F. (Requires FWRETRACT) + * M209 - Turn Automatic Retract Detection on/off: S<0|1> (For slicers that don't support G10/11). (Requires FWRETRACT) + Every normal extrude-only move will be classified as retract depending on the direction. + * M211 - Enable, Disable, and/or Report software endstops: S<0|1> (Requires MIN_SOFTWARE_ENDSTOPS or MAX_SOFTWARE_ENDSTOPS) + * M218 - Set a tool offset: "M218 T X Y". (Requires 2 or more extruders) + * M220 - Set Feedrate Percentage: "M220 S" (i.e., "FR" on the LCD) + * M221 - Set Flow Percentage: "M221 S" + * M226 - Wait until a pin is in a given state: "M226 P S" + * M240 - Trigger a camera to take a photograph. (Requires CHDK or PHOTOGRAPH_PIN) + * M250 - Set LCD contrast: "M250 C" (0-63). (Requires LCD support) + * M260 - i2c Send Data (Requires EXPERIMENTAL_I2CBUS) + * M261 - i2c Request Data (Requires EXPERIMENTAL_I2CBUS) + * M280 - Set servo position absolute: "M280 P S". (Requires servos) + * M300 - Play beep sound S P + * M301 - Set PID parameters P I and D. (Requires PIDTEMP) + * M302 - Allow cold extrudes, or set the minimum extrude S. (Requires PREVENT_COLD_EXTRUSION) + * M303 - PID relay autotune S sets the target temperature. Default 150C. (Requires PIDTEMP) + * M304 - Set bed PID parameters P I and D. (Requires PIDTEMPBED) + * M350 - Set microstepping mode. (Requires digital microstepping pins.) + * M351 - Toggle MS1 MS2 pins directly. (Requires digital microstepping pins.) + * M355 - Set Case Light on/off and set brightness. (Requires CASE_LIGHT_PIN) + * M380 - Activate solenoid on active extruder. (Requires EXT_SOLENOID) + * M381 - Disable all solenoids. (Requires EXT_SOLENOID) + * M400 - Finish all moves. + * M401 - Lower Z probe. (Requires a probe) + * M402 - Raise Z probe. (Requires a probe) + * M404 - Display or set the Nominal Filament Width: "W". (Requires FILAMENT_WIDTH_SENSOR) + * M405 - Enable Filament Sensor flow control. "M405 D". (Requires FILAMENT_WIDTH_SENSOR) + * M406 - Disable Filament Sensor flow control. (Requires FILAMENT_WIDTH_SENSOR) + * M407 - Display measured filament diameter in millimeters. (Requires FILAMENT_WIDTH_SENSOR) + * M410 - Quickstop. Abort all planned moves. + * M420 - Enable/Disable Leveling (with current values) S1=enable S0=disable (Requires MESH_BED_LEVELING or ABL) + * M421 - Set a single Z coordinate in the Mesh Leveling grid. X Y Z (Requires MESH_BED_LEVELING or AUTO_BED_LEVELING_UBL) + * M428 - Set the home_offset based on the current_position. Nearest edge applies. (Disabled by NO_WORKSPACE_OFFSETS or DELTA) + * 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. + * M540 - Enable/disable SD card abort on endstop hit: "M540 S". (Requires ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED) + * M600 - Pause for filament change: "M600 X Y Z E L". (Requires ADVANCED_PAUSE_FEATURE) + * M665 - Set delta configurations: "M665 L R S A B C I J K" (Requires DELTA) + * M666 - Set delta endstop adjustment. (Requires DELTA) + * M605 - Set dual x-carriage movement mode: "M605 S [X] [R]". (Requires DUAL_X_CARRIAGE) + * M851 - Set Z probe's Z offset in current units. (Negative = below the nozzle.) + * M860 - Report the position of position encoder modules. + * M861 - Report the status of position encoder modules. + * M862 - Perform an axis continuity test for position encoder modules. + * M863 - Perform steps-per-mm calibration for position encoder modules. + * M864 - Change position encoder module I2C address. + * M865 - Check position encoder module firmware version. + * M866 - Report or reset position encoder module error count. + * M867 - Enable/disable or toggle error correction for position encoder modules. + * M868 - Report or set position encoder module error correction threshold. + * M869 - Report position encoder module error. + * M900 - Get and/or Set advance K factor and WH/D ratio. (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 HAVE_TMC2130) + * 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) + * M911 - Report stepper driver overtemperature pre-warn condition. (Requires HAVE_TMC2130) + * M912 - Clear stepper driver overtemperature pre-warn condition flag. (Requires HAVE_TMC2130) + * M913 - Set HYBRID_THRESHOLD speed. (Requires HYBRID_THRESHOLD) + * M914 - Set SENSORLESS_HOMING sensitivity. (Requires SENSORLESS_HOMING) + * + * M360 - SCARA calibration: Move to cal-position ThetaA (0 deg calibration) + * M361 - SCARA calibration: Move to cal-position ThetaB (90 deg calibration - steps per degree) + * M362 - SCARA calibration: Move to cal-position PsiA (0 deg calibration) + * M363 - SCARA calibration: Move to cal-position PsiB (90 deg calibration - steps per degree) + * M364 - SCARA calibration: Move to cal-position PSIC (90 deg to Theta calibration position) + * + * ************ Custom codes - This can change to suit future G-code regulations + * M928 - Start SD logging: "M928 filename.gco". Stop with M29. (Requires SDSUPPORT) + * M999 - Restart after being stopped by error + * + * "T" Codes + * + * T0-T3 - Select an extruder (tool) by index: "T F" + * + */ + +#include "Marlin.h" + +#include "ultralcd.h" +#include "planner.h" +#include "stepper.h" +#include "endstops.h" +#include "temperature.h" +#include "cardreader.h" +#include "configuration_store.h" +#include "language.h" +#include "pins_arduino.h" +#include "math.h" +#include "nozzle.h" +#include "duration_t.h" +#include "types.h" +#include "gcode.h" + +#if HAS_ABL + #include "vector_3.h" + #if ENABLED(AUTO_BED_LEVELING_LINEAR) + #include "least_squares_fit.h" + #endif +#elif ENABLED(MESH_BED_LEVELING) + #include "mesh_bed_leveling.h" +#endif + +#if ENABLED(BEZIER_CURVE_SUPPORT) + #include "planner_bezier.h" +#endif + +#if HAS_BUZZER && DISABLED(LCD_USE_I2C_BUZZER) + #include "buzzer.h" +#endif + +#if ENABLED(USE_WATCHDOG) + #include "watchdog.h" +#endif + +#if ENABLED(MAX7219_DEBUG) + #include "Max7219_Debug_LEDs.h" +#endif + +#if ENABLED(NEOPIXEL_LED) + #include +#endif + +#if ENABLED(BLINKM) + #include "blinkm.h" + #include "Wire.h" +#endif + +#if ENABLED(PCA9632) + #include "pca9632.h" +#endif + +#if HAS_SERVOS + #include "servo.h" +#endif + +#if HAS_DIGIPOTSS + #include +#endif + +#if ENABLED(DAC_STEPPER_CURRENT) + #include "stepper_dac.h" +#endif + +#if ENABLED(EXPERIMENTAL_I2CBUS) + #include "twibus.h" +#endif + +#if ENABLED(I2C_POSITION_ENCODERS) + #include "I2CPositionEncoder.h" +#endif + +#if ENABLED(ENDSTOP_INTERRUPTS_FEATURE) + #include "endstop_interrupts.h" +#endif + +#if ENABLED(M100_FREE_MEMORY_WATCHER) + void gcode_M100(); + void M100_dump_routine(const char * const title, const char *start, const char *end); +#endif + +#if ENABLED(SDSUPPORT) + CardReader card; +#endif + +#if ENABLED(EXPERIMENTAL_I2CBUS) + TWIBus i2c; +#endif + +#if ENABLED(G38_PROBE_TARGET) + bool G38_move = false, + G38_endstop_hit = false; +#endif + +#if ENABLED(AUTO_BED_LEVELING_UBL) + #include "ubl.h" + extern bool defer_return_to_status; + unified_bed_leveling ubl; + #define UBL_MESH_VALID !( ( ubl.z_values[0][0] == ubl.z_values[0][1] && ubl.z_values[0][1] == ubl.z_values[0][2] \ + && ubl.z_values[1][0] == ubl.z_values[1][1] && ubl.z_values[1][1] == ubl.z_values[1][2] \ + && ubl.z_values[2][0] == ubl.z_values[2][1] && ubl.z_values[2][1] == ubl.z_values[2][2] \ + && ubl.z_values[0][0] == 0 && ubl.z_values[1][0] == 0 && ubl.z_values[2][0] == 0 ) \ + || isnan(ubl.z_values[0][0])) +#endif + +#if ENABLED(NEOPIXEL_LED) + #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 NEO_WHITE 255, 255, 255 + #else + #define NEO_WHITE 0, 0, 0, 255 + #endif +#endif + +#if ENABLED(RGB_LED) || ENABLED(BLINKM) || ENABLED(PCA9632) + #define LED_WHITE 255, 255, 255 +#elif ENABLED(RGBW_LED) + #define LED_WHITE 0, 0, 0, 255 +#endif + +bool Running = true; + +uint8_t marlin_debug_flags = DEBUG_NONE; + +/** + * Cartesian Current Position + * Used to track the logical position as moves are queued. + * Used by 'line_to_current_position' to do a move after changing it. + * Used by 'SYNC_PLAN_POSITION_KINEMATIC' to update 'planner.position'. + */ +float current_position[XYZE] = { 0.0 }; + +/** + * Cartesian Destination + * A temporary position, usually applied to 'current_position'. + * Set with 'gcode_get_destination' or 'set_destination_to_current'. + * 'line_to_destination' sets 'current_position' to 'destination'. + */ +float destination[XYZE] = { 0.0 }; + +/** + * axis_homed + * Flags that each linear axis was homed. + * XYZ on cartesian, ABC on delta, ABZ on SCARA. + * + * axis_known_position + * Flags that the position is known in each linear axis. Set when homed. + * Cleared whenever a stepper powers off, potentially losing its position. + */ +bool axis_homed[XYZ] = { false }, axis_known_position[XYZ] = { false }; + +/** + * GCode line number handling. Hosts may opt to include line numbers when + * sending commands to Marlin, and lines will be checked for sequentiality. + * M110 N sets the current line number. + */ +static long gcode_N, gcode_LastN, Stopped_gcode_LastN = 0; + +/** + * GCode Command Queue + * A simple ring buffer of BUFSIZE command strings. + * + * Commands are copied into this buffer by the command injectors + * (immediate, serial, sd card) and they are processed sequentially by + * the main loop. The process_next_command function parses the next + * command and hands off execution to individual handler functions. + */ +uint8_t commands_in_queue = 0; // Count of commands in the queue +static uint8_t cmd_queue_index_r = 0, // Ring buffer read position + cmd_queue_index_w = 0; // Ring buffer write position +#if ENABLED(M100_FREE_MEMORY_WATCHER) + char command_queue[BUFSIZE][MAX_CMD_SIZE]; // Necessary so M100 Free Memory Dumper can show us the commands and any corruption +#else // This can be collapsed back to the way it was soon. +static char command_queue[BUFSIZE][MAX_CMD_SIZE]; +#endif + +/** + * Next Injected Command pointer. NULL 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. + */ +static const char *injected_commands_P = NULL; + +#if ENABLED(TEMPERATURE_UNITS_SUPPORT) + TempUnit input_temp_units = TEMPUNIT_C; +#endif + +/** + * Feed rates are often configured with mm/m + * but the planner and stepper like mm/s units. + */ +static const float homing_feedrate_mm_s[] PROGMEM = { + #if ENABLED(DELTA) + MMM_TO_MMS(HOMING_FEEDRATE_Z), MMM_TO_MMS(HOMING_FEEDRATE_Z), + #else + MMM_TO_MMS(HOMING_FEEDRATE_XY), MMM_TO_MMS(HOMING_FEEDRATE_XY), + #endif + MMM_TO_MMS(HOMING_FEEDRATE_Z), 0 +}; +FORCE_INLINE float homing_feedrate(const AxisEnum a) { return pgm_read_float(&homing_feedrate_mm_s[a]); } + +float feedrate_mm_s = MMM_TO_MMS(1500.0); +static float saved_feedrate_mm_s; +int16_t feedrate_percentage = 100, saved_feedrate_percentage, + flow_percentage[EXTRUDERS] = ARRAY_BY_EXTRUDERS1(100); + +// Initialized by settings.load() +bool axis_relative_modes[] = AXIS_RELATIVE_MODES, + volumetric_enabled; +float filament_size[EXTRUDERS], volumetric_multiplier[EXTRUDERS]; + +#if HAS_WORKSPACE_OFFSET + #if HAS_POSITION_SHIFT + // The distance that XYZ has been offset by G92. Reset by G28. + float position_shift[XYZ] = { 0 }; + #endif + #if HAS_HOME_OFFSET + // This offset is added to the configured home position. + // Set by M206, M428, or menu item. Saved to EEPROM. + float home_offset[XYZ] = { 0 }; + #endif + #if HAS_HOME_OFFSET && HAS_POSITION_SHIFT + // The above two are combined to save on computes + float workspace_offset[XYZ] = { 0 }; + #endif +#endif + +// Software Endstops are based on the configured limits. +#if HAS_SOFTWARE_ENDSTOPS + bool soft_endstops_enabled = true; +#endif +float soft_endstop_min[XYZ] = { X_MIN_BED, Y_MIN_BED, Z_MIN_POS }, + soft_endstop_max[XYZ] = { X_MAX_BED, Y_MAX_BED, Z_MAX_POS }; + +#if FAN_COUNT > 0 + int16_t fanSpeeds[FAN_COUNT] = { 0 }; + #if ENABLED(PROBING_FANS_OFF) + bool fans_paused = false; + int16_t paused_fanSpeeds[FAN_COUNT] = { 0 }; + #endif +#endif + +// The active extruder (tool). Set with T command. +uint8_t active_extruder = 0; + +// Relative Mode. Enable with G91, disable with G90. +static bool relative_mode = false; + +// For M109 and M190, this flag may be cleared (by M108) to exit the wait loop +volatile 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 + volatile bool wait_for_user = false; +#endif + +const char axis_codes[XYZE] = { 'X', 'Y', 'Z', 'E' }; + +// Number of characters read in the current line of serial input +static int serial_count = 0; + +// Inactivity shutdown +millis_t previous_cmd_ms = 0; +static millis_t max_inactive_time = 0; +static millis_t stepper_inactive_time = (DEFAULT_STEPPER_DEACTIVE_TIME) * 1000UL; + +// Print Job Timer +#if ENABLED(PRINTCOUNTER) + PrintCounter print_job_timer = PrintCounter(); +#else + Stopwatch print_job_timer = Stopwatch(); +#endif + +// Buzzer - I2C on the LCD or a BEEPER_PIN +#if ENABLED(LCD_USE_I2C_BUZZER) + #define BUZZ(d,f) lcd_buzz(d, f) +#elif PIN_EXISTS(BEEPER) + Buzzer buzzer; + #define BUZZ(d,f) buzzer.tone(d, f) +#else + #define BUZZ(d,f) NOOP +#endif + +static uint8_t target_extruder; + +#if HAS_BED_PROBE + float zprobe_zoffset; // Initialized by settings.load() +#endif + +#if HAS_ABL + float xy_probe_feedrate_mm_s = MMM_TO_MMS(XY_PROBE_SPEED); + #define XY_PROBE_FEEDRATE_MM_S xy_probe_feedrate_mm_s +#elif defined(XY_PROBE_SPEED) + #define XY_PROBE_FEEDRATE_MM_S MMM_TO_MMS(XY_PROBE_SPEED) +#else + #define XY_PROBE_FEEDRATE_MM_S PLANNER_XY_FEEDRATE() +#endif + +#if ENABLED(AUTO_BED_LEVELING_BILINEAR) + #if ENABLED(DELTA) + #define ADJUST_DELTA(V) \ + if (planner.abl_enabled) { \ + const float zadj = bilinear_z_offset(V); \ + delta[A_AXIS] += zadj; \ + delta[B_AXIS] += zadj; \ + delta[C_AXIS] += zadj; \ + } + #else + #define ADJUST_DELTA(V) if (planner.abl_enabled) { delta[Z_AXIS] += bilinear_z_offset(V); } + #endif +#elif IS_KINEMATIC + #define ADJUST_DELTA(V) NOOP +#endif + +#if ENABLED(Z_DUAL_ENDSTOPS) + float z_endstop_adj; +#endif + +// Extruder offsets +#if HOTENDS > 1 + float hotend_offset[XYZ][HOTENDS]; // Initialized by settings.load() +#endif + +#if HAS_Z_SERVO_ENDSTOP + const int z_servo_angle[2] = Z_SERVO_ANGLES; +#endif + +#if ENABLED(BARICUDA) + uint8_t baricuda_valve_pressure = 0, + baricuda_e_to_p_pressure = 0; +#endif + +#if ENABLED(FWRETRACT) // Initialized by settings.load()... + bool autoretract_enabled, // M209 S - Autoretract switch + retracted[EXTRUDERS] = { false }; // Which extruders are currently retracted + float retract_length, // M207 S - G10 Retract length + retract_feedrate_mm_s, // M207 F - G10 Retract feedrate + retract_zlift, // M207 Z - G10 Retract hop size + retract_recover_length, // M208 S - G11 Recover length + retract_recover_feedrate_mm_s, // M208 F - G11 Recover feedrate + swap_retract_length, // M207 W - G10 Swap Retract length + swap_retract_recover_length, // M208 W - G11 Swap Recover length + swap_retract_recover_feedrate_mm_s; // M208 R - G11 Swap Recover feedrate + #if EXTRUDERS > 1 + bool retracted_swap[EXTRUDERS] = { false }; // Which extruders are swap-retracted + #else + constexpr bool retracted_swap[1] = { false }; + #endif +#endif // FWRETRACT + +#if HAS_POWER_SWITCH + bool powersupply_on = + #if ENABLED(PS_DEFAULT_OFF) + false + #else + true + #endif + ; +#endif + +#if ENABLED(DELTA) + + float delta[ABC], + endstop_adj[ABC] = { 0 }; + + // Initialized by settings.load() + float delta_radius, + delta_tower_angle_trim[ABC], + delta_tower[ABC][2], + delta_diagonal_rod, + delta_calibration_radius, + delta_diagonal_rod_2_tower[ABC], + delta_segments_per_second, + delta_clip_start_height = Z_MAX_POS; + + float delta_safe_distance_from_top(); + +#endif + +#if ENABLED(AUTO_BED_LEVELING_BILINEAR) + int bilinear_grid_spacing[2], bilinear_start[2]; + float bilinear_grid_factor[2], + z_values[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y]; +#endif + +#if IS_SCARA + // Float constants for SCARA calculations + const float L1 = SCARA_LINKAGE_1, L2 = SCARA_LINKAGE_2, + L1_2 = sq(float(L1)), L1_2_2 = 2.0 * L1_2, + L2_2 = sq(float(L2)); + + float delta_segments_per_second = SCARA_SEGMENTS_PER_SECOND, + delta[ABC]; +#endif + +float cartes[XYZ] = { 0 }; + +#if ENABLED(FILAMENT_WIDTH_SENSOR) + bool filament_sensor = false; // M405 turns on filament sensor control. M406 turns it off. + float filament_width_nominal = DEFAULT_NOMINAL_FILAMENT_DIA, // Nominal filament width. Change with M404. + filament_width_meas = DEFAULT_MEASURED_FILAMENT_DIA; // Measured filament diameter + uint8_t meas_delay_cm = MEASUREMENT_DELAY_CM, // Distance delay setting + measurement_delay[MAX_MEASUREMENT_DELAY + 1]; // Ring buffer to delayed measurement. Store extruder factor after subtracting 100 + int8_t filwidth_delay_index[2] = { 0, -1 }; // Indexes into ring buffer +#endif + +#if ENABLED(FILAMENT_RUNOUT_SENSOR) + static bool filament_ran_out = false; +#endif + +#if ENABLED(ADVANCED_PAUSE_FEATURE) + AdvancedPauseMenuResponse advanced_pause_menu_response; +#endif + +#if ENABLED(MIXING_EXTRUDER) + float mixing_factor[MIXING_STEPPERS]; // Reciprocal of mix proportion. 0.0 = off, otherwise >= 1.0. + #if MIXING_VIRTUAL_TOOLS > 1 + float mixing_virtual_tool_mix[MIXING_VIRTUAL_TOOLS][MIXING_STEPPERS]; + #endif +#endif + +static bool send_ok[BUFSIZE]; + +#if HAS_SERVOS + Servo servo[NUM_SERVOS]; + #define MOVE_SERVO(I, P) servo[I].move(P) + #if HAS_Z_SERVO_ENDSTOP + #define DEPLOY_Z_SERVO() MOVE_SERVO(Z_ENDSTOP_SERVO_NR, z_servo_angle[0]) + #define STOW_Z_SERVO() MOVE_SERVO(Z_ENDSTOP_SERVO_NR, z_servo_angle[1]) + #endif +#endif + +#ifdef CHDK + millis_t chdkHigh = 0; + bool chdkActive = false; +#endif + +#ifdef AUTOMATIC_CURRENT_CONTROL + bool auto_current_control = 0; +#endif + +#if ENABLED(PID_EXTRUSION_SCALING) + int lpq_len = 20; +#endif + +#if ENABLED(HOST_KEEPALIVE_FEATURE) + MarlinBusyState busy_state = NOT_BUSY; + static millis_t next_busy_signal_ms = 0; + uint8_t host_keepalive_interval = DEFAULT_KEEPALIVE_INTERVAL; +#else + #define host_keepalive() NOOP +#endif + +#if ENABLED(I2C_POSITION_ENCODERS) + I2CPositionEncodersMgr I2CPEM; + uint8_t blockBufferIndexRef = 0; + millis_t lastUpdateMillis; +#endif + +#if ENABLED(CNC_WORKSPACE_PLANES) + static WorkspacePlane workspace_plane = PLANE_XY; +#endif + +FORCE_INLINE float pgm_read_any(const float *p) { return pgm_read_float_near(p); } +FORCE_INLINE signed char pgm_read_any(const signed char *p) { return pgm_read_byte_near(p); } + +#define XYZ_CONSTS_FROM_CONFIG(type, array, CONFIG) \ + static const PROGMEM type array##_P[XYZ] = { X_##CONFIG, Y_##CONFIG, Z_##CONFIG }; \ + static inline type array(AxisEnum axis) { return pgm_read_any(&array##_P[axis]); } \ + typedef void __void_##CONFIG##__ + +XYZ_CONSTS_FROM_CONFIG(float, base_min_pos, MIN_POS); +XYZ_CONSTS_FROM_CONFIG(float, base_max_pos, MAX_POS); +XYZ_CONSTS_FROM_CONFIG(float, base_home_pos, HOME_POS); +XYZ_CONSTS_FROM_CONFIG(float, max_length, MAX_LENGTH); +XYZ_CONSTS_FROM_CONFIG(float, home_bump_mm, HOME_BUMP_MM); +XYZ_CONSTS_FROM_CONFIG(signed char, home_dir, HOME_DIR); + +/** + * *************************************************************************** + * ******************************** FUNCTIONS ******************************** + * *************************************************************************** + */ + +void stop(); + +void get_available_commands(); +void process_next_command(); +void prepare_move_to_destination(); + +void get_cartesian_from_steppers(); +void set_current_from_steppers_for_axis(const AxisEnum axis); + +#if ENABLED(ARC_SUPPORT) + void plan_arc(float target[XYZE], float* offset, uint8_t clockwise); +#endif + +#if ENABLED(BEZIER_CURVE_SUPPORT) + void plan_cubic_move(const float offset[4]); +#endif + +void tool_change(const uint8_t tmp_extruder, const float fr_mm_s=0.0, bool no_move=false); +void report_current_position(); +void report_current_position_detail(); + +#if ENABLED(DEBUG_LEVELING_FEATURE) + void print_xyz(const char* prefix, const char* suffix, const float x, const float y, const float z) { + serialprintPGM(prefix); + SERIAL_CHAR('('); + SERIAL_ECHO(x); + SERIAL_ECHOPAIR(", ", y); + SERIAL_ECHOPAIR(", ", z); + SERIAL_CHAR(')'); + if (suffix) serialprintPGM(suffix); else SERIAL_EOL(); + } + + void print_xyz(const char* prefix, const char* suffix, const float xyz[]) { + print_xyz(prefix, suffix, xyz[X_AXIS], xyz[Y_AXIS], xyz[Z_AXIS]); + } + + #if HAS_ABL + void print_xyz(const char* prefix, const char* suffix, const vector_3 &xyz) { + print_xyz(prefix, suffix, xyz.x, xyz.y, xyz.z); + } + #endif + + #define DEBUG_POS(SUFFIX,VAR) do { \ + print_xyz(PSTR(" " STRINGIFY(VAR) "="), PSTR(" : " SUFFIX "\n"), VAR); }while(0) +#endif + +/** + * sync_plan_position + * + * Set the planner/stepper positions directly from current_position with + * no kinematic translation. Used for homing axes and cartesian/core syncing. + */ +void sync_plan_position() { + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("sync_plan_position", current_position); + #endif + planner.set_position_mm(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); +} +inline void sync_plan_position_e() { planner.set_e_position_mm(current_position[E_AXIS]); } + +#if IS_KINEMATIC + + inline void sync_plan_position_kinematic() { + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("sync_plan_position_kinematic", current_position); + #endif + planner.set_position_mm_kinematic(current_position); + } + #define SYNC_PLAN_POSITION_KINEMATIC() sync_plan_position_kinematic() + +#else + + #define SYNC_PLAN_POSITION_KINEMATIC() sync_plan_position() + +#endif + +#if ENABLED(SDSUPPORT) + #include "SdFatUtil.h" + int freeMemory() { return SdFatUtil::FreeRam(); } +#else +extern "C" { + extern char __bss_end; + extern char __heap_start; + extern void* __brkval; + + int freeMemory() { + int free_memory; + if ((int)__brkval == 0) + free_memory = ((int)&free_memory) - ((int)&__bss_end); + else + free_memory = ((int)&free_memory) - ((int)__brkval); + return free_memory; + } +} +#endif // !SDSUPPORT + +#if ENABLED(DIGIPOT_I2C) + extern void digipot_i2c_set_current(uint8_t channel, float current); + extern void digipot_i2c_init(); +#endif + +/** + * Inject the next "immediate" command, when possible, onto the front of the queue. + * Return true if any immediate commands remain to inject. + */ +static bool drain_injected_commands_P() { + if (injected_commands_P != NULL) { + size_t i = 0; + char c, cmd[30]; + strncpy_P(cmd, injected_commands_P, sizeof(cmd) - 1); + cmd[sizeof(cmd) - 1] = '\0'; + while ((c = cmd[i]) && c != '\n') i++; // find the end of this gcode command + cmd[i] = '\0'; + if (enqueue_and_echo_command(cmd)) // success? + injected_commands_P = c ? injected_commands_P + i + 1 : NULL; // next command or done + } + return (injected_commands_P != NULL); // return whether any more remain +} + +/** + * Record one or many commands to run from program memory. + * Aborts the current queue, if any. + * Note: drain_injected_commands_P() must be called repeatedly to drain the commands afterwards + */ +void enqueue_and_echo_commands_P(const char * const pgcode) { + injected_commands_P = pgcode; + drain_injected_commands_P(); // first command executed asap (when possible) +} + +/** + * Clear the Marlin command queue + */ +void clear_command_queue() { + cmd_queue_index_r = cmd_queue_index_w; + commands_in_queue = 0; +} + +/** + * Once a new command is in the ring buffer, call this to commit it + */ +inline void _commit_command(bool say_ok) { + send_ok[cmd_queue_index_w] = say_ok; + if (++cmd_queue_index_w >= BUFSIZE) cmd_queue_index_w = 0; + commands_in_queue++; +} + +/** + * Copy a command from RAM into the main command buffer. + * Return true if the command was successfully added. + * Return false for a full buffer, or if the 'command' is a comment. + */ +inline bool _enqueuecommand(const char* cmd, bool say_ok=false) { + if (*cmd == ';' || commands_in_queue >= BUFSIZE) return false; + strcpy(command_queue[cmd_queue_index_w], cmd); + _commit_command(say_ok); + return true; +} + +/** + * Enqueue with Serial Echo + */ +bool enqueue_and_echo_command(const char* cmd, bool say_ok/*=false*/) { + if (_enqueuecommand(cmd, say_ok)) { + SERIAL_ECHO_START(); + SERIAL_ECHOPAIR(MSG_ENQUEUEING, cmd); + SERIAL_CHAR('"'); + SERIAL_EOL(); + return true; + } + return false; +} + +void setup_killpin() { + #if HAS_KILL + SET_INPUT_PULLUP(KILL_PIN); + #endif +} + +#if ENABLED(FILAMENT_RUNOUT_SENSOR) + + void setup_filrunoutpin() { + #if ENABLED(ENDSTOPPULLUP_FIL_RUNOUT) + SET_INPUT_PULLUP(FIL_RUNOUT_PIN); + #else + SET_INPUT(FIL_RUNOUT_PIN); + #endif + } + +#endif + +void setup_powerhold() { + #if HAS_SUICIDE + OUT_WRITE(SUICIDE_PIN, HIGH); + #endif + #if HAS_POWER_SWITCH + #if ENABLED(PS_DEFAULT_OFF) + OUT_WRITE(PS_ON_PIN, PS_ON_ASLEEP); + #else + OUT_WRITE(PS_ON_PIN, PS_ON_AWAKE); + #endif + #endif +} + +void suicide() { + #if HAS_SUICIDE + OUT_WRITE(SUICIDE_PIN, LOW); + #endif +} + +void servo_init() { + #if NUM_SERVOS >= 1 && HAS_SERVO_0 + servo[0].attach(SERVO0_PIN); + servo[0].detach(); // Just set up the pin. We don't have a position yet. Don't move to a random position. + #endif + #if NUM_SERVOS >= 2 && HAS_SERVO_1 + servo[1].attach(SERVO1_PIN); + servo[1].detach(); + #endif + #if NUM_SERVOS >= 3 && HAS_SERVO_2 + servo[2].attach(SERVO2_PIN); + servo[2].detach(); + #endif + #if NUM_SERVOS >= 4 && HAS_SERVO_3 + servo[3].attach(SERVO3_PIN); + servo[3].detach(); + #endif + + #if HAS_Z_SERVO_ENDSTOP + /** + * Set position of Z Servo Endstop + * + * The servo might be deployed and positioned too low to stow + * 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(); + #endif +} + +/** + * Stepper Reset (RigidBoard, et.al.) + */ +#if HAS_STEPPER_RESET + void disableStepperDrivers() { + OUT_WRITE(STEPPER_RESET_PIN, LOW); // drive it down to hold in reset motor driver chips + } + void enableStepperDrivers() { SET_INPUT(STEPPER_RESET_PIN); } // set to input, which allows it to be pulled high by pullups +#endif + +#if ENABLED(EXPERIMENTAL_I2CBUS) && I2C_SLAVE_ADDRESS > 0 + + void i2c_on_receive(int bytes) { // just echo all bytes received to serial + i2c.receive(bytes); + } + + void i2c_on_request() { // just send dummy data for now + i2c.reply("Hello World!\n"); + } + +#endif + +#if HAS_COLOR_LEDS + + #if ENABLED(NEOPIXEL_LED) + + Adafruit_NeoPixel pixels(NEOPIXEL_PIXELS, NEOPIXEL_PIN, NEOPIXEL_TYPE + NEO_KHZ800); + + void set_neopixel_color(const uint32_t color) { + for (uint16_t i = 0; i < pixels.numPixels(); ++i) + pixels.setPixelColor(i, color); + pixels.show(); + } + + void setup_neopixel() { + pixels.setBrightness(NEOPIXEL_BRIGHTNESS); // 0 - 255 range + pixels.begin(); + pixels.show(); // initialize to all off + + #if ENABLED(NEOPIXEL_STARTUP_TEST) + delay(2000); + set_neopixel_color(pixels.Color(255, 0, 0, 0)); // red + delay(2000); + set_neopixel_color(pixels.Color(0, 255, 0, 0)); // green + delay(2000); + set_neopixel_color(pixels.Color(0, 0, 255, 0)); // blue + delay(2000); + #endif + set_neopixel_color(pixels.Color(NEO_WHITE)); // white + } + + #endif // NEOPIXEL_LED + + void set_led_color( + const uint8_t r, const uint8_t g, const uint8_t b + #if ENABLED(RGBW_LED) || ENABLED(NEOPIXEL_LED) + , const uint8_t w = 0 + #if ENABLED(NEOPIXEL_LED) + , const uint8_t p = NEOPIXEL_BRIGHTNESS + , bool isSequence = false + #endif + #endif + ) { + + #if ENABLED(NEOPIXEL_LED) + + const uint32_t color = pixels.Color(r, g, b, w); + static uint16_t nextLed = 0; + + pixels.setBrightness(p); + if (!isSequence) + set_neopixel_color(color); + else { + pixels.setPixelColor(nextLed, color); + pixels.show(); + if (++nextLed >= pixels.numPixels()) nextLed = 0; + return; + } + + #endif + + #if ENABLED(BLINKM) + + // This variant uses i2c to send the RGB components to the device. + SendColors(r, g, b); + + #endif + + #if ENABLED(RGB_LED) || ENABLED(RGBW_LED) + + // This variant uses 3 separate pins for the RGB components. + // If the pins can do PWM then their intensity will be set. + WRITE(RGB_LED_R_PIN, r ? HIGH : LOW); + WRITE(RGB_LED_G_PIN, g ? HIGH : LOW); + WRITE(RGB_LED_B_PIN, b ? HIGH : LOW); + analogWrite(RGB_LED_R_PIN, r); + analogWrite(RGB_LED_G_PIN, g); + analogWrite(RGB_LED_B_PIN, b); + + #if ENABLED(RGBW_LED) + WRITE(RGB_LED_W_PIN, w ? HIGH : LOW); + analogWrite(RGB_LED_W_PIN, w); + #endif + + #endif + + #if ENABLED(PCA9632) + // Update I2C LED driver + PCA9632_SetColor(r, g, b); + #endif + } + +#endif // HAS_COLOR_LEDS + +void gcode_line_error(const char* err, bool doFlush = true) { + SERIAL_ERROR_START(); + serialprintPGM(err); + SERIAL_ERRORLN(gcode_LastN); + //Serial.println(gcode_N); + if (doFlush) FlushSerialRequestResend(); + serial_count = 0; +} + +/** + * Get all commands waiting on the serial port and queue them. + * Exit when the buffer is full or when no more characters are + * left on the serial port. + */ +inline void get_serial_commands() { + static char serial_line_buffer[MAX_CMD_SIZE]; + static bool serial_comment_mode = false; + + // If the command buffer is empty for too long, + // send "wait" to indicate Marlin is still waiting. + #if defined(NO_TIMEOUTS) && NO_TIMEOUTS > 0 + static millis_t last_command_time = 0; + const millis_t ms = millis(); + if (commands_in_queue == 0 && !MYSERIAL.available() && ELAPSED(ms, last_command_time + NO_TIMEOUTS)) { + SERIAL_ECHOLNPGM(MSG_WAIT); + last_command_time = ms; + } + #endif + + /** + * Loop while serial characters are incoming and the queue is not full + */ + int c; + while (commands_in_queue < BUFSIZE && (c = MYSERIAL.read()) >= 0) { + + char serial_char = c; + + /** + * If the character ends the line + */ + if (serial_char == '\n' || serial_char == '\r') { + + serial_comment_mode = false; // end of line == end of comment + + if (!serial_count) continue; // skip empty lines + + serial_line_buffer[serial_count] = 0; // terminate string + serial_count = 0; //reset buffer + + char* command = serial_line_buffer; + + while (*command == ' ') command++; // skip any leading spaces + char *npos = (*command == 'N') ? command : NULL, // Require the N parameter to start the line + *apos = strchr(command, '*'); + + if (npos) { + + bool M110 = strstr_P(command, PSTR("M110")) != NULL; + + if (M110) { + char* n2pos = strchr(command + 4, 'N'); + if (n2pos) npos = n2pos; + } + + gcode_N = strtol(npos + 1, NULL, 10); + + if (gcode_N != gcode_LastN + 1 && !M110) { + gcode_line_error(PSTR(MSG_ERR_LINE_NO)); + return; + } + + if (apos) { + byte checksum = 0, count = 0; + while (command[count] != '*') checksum ^= command[count++]; + + if (strtol(apos + 1, NULL, 10) != checksum) { + gcode_line_error(PSTR(MSG_ERR_CHECKSUM_MISMATCH)); + return; + } + // if no errors, continue parsing + } + else { + gcode_line_error(PSTR(MSG_ERR_NO_CHECKSUM)); + return; + } + + gcode_LastN = gcode_N; + // if no errors, continue parsing + } + else if (apos) { // No '*' without 'N' + gcode_line_error(PSTR(MSG_ERR_NO_LINENUMBER_WITH_CHECKSUM), false); + return; + } + + // Movement commands alert when stopped + if (IsStopped()) { + char* gpos = strchr(command, 'G'); + if (gpos) { + const int codenum = strtol(gpos + 1, NULL, 10); + switch (codenum) { + case 0: + case 1: + case 2: + case 3: + SERIAL_ERRORLNPGM(MSG_ERR_STOPPED); + LCD_MESSAGEPGM(MSG_STOPPED); + break; + } + } + } + + #if DISABLED(EMERGENCY_PARSER) + // If command was e-stop process now + if (strcmp(command, "M108") == 0) { + wait_for_heatup = false; + #if ENABLED(ULTIPANEL) + wait_for_user = false; + #endif + } + if (strcmp(command, "M112") == 0) kill(PSTR(MSG_KILLED)); + if (strcmp(command, "M410") == 0) { quickstop_stepper(); } + #endif + + #if defined(NO_TIMEOUTS) && NO_TIMEOUTS > 0 + last_command_time = ms; + #endif + + // Add the command to the queue + _enqueuecommand(serial_line_buffer, true); + } + else if (serial_count >= MAX_CMD_SIZE - 1) { + // Keep fetching, but ignore normal characters beyond the max length + // The command will be injected when EOL is reached + } + else if (serial_char == '\\') { // Handle escapes + if ((c = MYSERIAL.read()) >= 0) { + // if we have one more character, copy it over + serial_char = c; + if (!serial_comment_mode) serial_line_buffer[serial_count++] = serial_char; + } + // otherwise do nothing + } + else { // it's not a newline, carriage return or escape char + if (serial_char == ';') serial_comment_mode = true; + if (!serial_comment_mode) serial_line_buffer[serial_count++] = serial_char; + } + + } // queue has space, serial has data +} + +#if ENABLED(SDSUPPORT) + + /** + * Get commands from the SD Card until the command buffer is full + * or until the end of the file is reached. The special character '#' + * can also interrupt buffering. + */ + inline void get_sdcard_commands() { + static bool stop_buffering = false, + sd_comment_mode = false; + + if (!card.sdprinting) return; + + /** + * '#' stops reading from SD to the buffer prematurely, so procedural + * macro calls are possible. If it occurs, stop_buffering is triggered + * and the buffer is run dry; this character _can_ occur in serial com + * due to checksums, however, no checksums are used in SD printing. + */ + + if (commands_in_queue == 0) stop_buffering = false; + + uint16_t sd_count = 0; + bool card_eof = card.eof(); + while (commands_in_queue < BUFSIZE && !card_eof && !stop_buffering) { + const int16_t n = card.get(); + char sd_char = (char)n; + card_eof = card.eof(); + if (card_eof || n == -1 + || sd_char == '\n' || sd_char == '\r' + || ((sd_char == '#' || sd_char == ':') && !sd_comment_mode) + ) { + if (card_eof) { + SERIAL_PROTOCOLLNPGM(MSG_FILE_PRINTED); + card.printingHasFinished(); + #if ENABLED(PRINTER_EVENT_LEDS) + LCD_MESSAGEPGM(MSG_INFO_COMPLETED_PRINTS); + set_led_color(0, 255, 0); // Green + #if HAS_RESUME_CONTINUE + enqueue_and_echo_commands_P(PSTR("M0")); // end of the queue! + #else + safe_delay(1000); + #endif + set_led_color(0, 0, 0); // OFF + #endif + card.checkautostart(true); + } + else if (n == -1) { + SERIAL_ERROR_START(); + SERIAL_ECHOLNPGM(MSG_SD_ERR_READ); + } + if (sd_char == '#') stop_buffering = true; + + sd_comment_mode = false; // for new command + + if (!sd_count) continue; // skip empty lines (and comment lines) + + command_queue[cmd_queue_index_w][sd_count] = '\0'; // terminate string + sd_count = 0; // clear sd line buffer + + _commit_command(false); + } + else if (sd_count >= MAX_CMD_SIZE - 1) { + /** + * Keep fetching, but ignore normal characters beyond the max length + * The command will be injected when EOL is reached + */ + } + else { + if (sd_char == ';') sd_comment_mode = true; + if (!sd_comment_mode) command_queue[cmd_queue_index_w][sd_count++] = sd_char; + } + } + } + +#endif // SDSUPPORT + +/** + * Add to the circular command queue the next command from: + * - The command-injection queue (injected_commands_P) + * - The active serial input (usually USB) + * - The SD card file being actively printed + */ +void get_available_commands() { + + // if any immediate commands remain, don't get other commands yet + if (drain_injected_commands_P()) return; + + get_serial_commands(); + + #if ENABLED(SDSUPPORT) + get_sdcard_commands(); + #endif +} + +/** + * Set target_extruder from the T parameter or the active_extruder + * + * Returns TRUE if the target is invalid + */ +bool get_target_extruder_from_command(const uint16_t code) { + if (parser.seenval('T')) { + const int8_t e = parser.value_byte(); + if (e >= EXTRUDERS) { + SERIAL_ECHO_START(); + SERIAL_CHAR('M'); + SERIAL_ECHO(code); + SERIAL_ECHOLNPAIR(" " MSG_INVALID_EXTRUDER " ", e); + return true; + } + target_extruder = e; + } + else + target_extruder = active_extruder; + + return false; +} + +#if ENABLED(DUAL_X_CARRIAGE) || ENABLED(DUAL_NOZZLE_DUPLICATION_MODE) + bool extruder_duplication_enabled = false; // Used in Dual X mode 2 +#endif + +#if ENABLED(DUAL_X_CARRIAGE) + + static DualXMode dual_x_carriage_mode = DEFAULT_DUAL_X_CARRIAGE_MODE; + + static float x_home_pos(const int extruder) { + if (extruder == 0) + return LOGICAL_X_POSITION(base_home_pos(X_AXIS)); + else + /** + * In dual carriage mode the extruder offset provides an override of the + * second X-carriage position when homed - otherwise X2_HOME_POS is used. + * This allows soft recalibration of the second extruder home position + * without firmware reflash (through the M218 command). + */ + return LOGICAL_X_POSITION(hotend_offset[X_AXIS][1] > 0 ? hotend_offset[X_AXIS][1] : X2_HOME_POS); + } + + static int x_home_dir(const int extruder) { return extruder ? X2_HOME_DIR : X_HOME_DIR; } + + static float inactive_extruder_x_pos = X2_MAX_POS; // used in mode 0 & 1 + static bool active_extruder_parked = false; // used in mode 1 & 2 + static float raised_parked_position[XYZE]; // used in mode 1 + static millis_t delayed_move_time = 0; // used in mode 1 + static float duplicate_extruder_x_offset = DEFAULT_DUPLICATION_X_OFFSET; // used in mode 2 + static int16_t duplicate_extruder_temp_offset = 0; // used in mode 2 + +#endif // DUAL_X_CARRIAGE + +#if HAS_WORKSPACE_OFFSET || ENABLED(DUAL_X_CARRIAGE) + + /** + * Software endstops can be used to monitor the open end of + * an axis that has a hardware endstop on the other end. Or + * they can prevent axes from moving past endstops and grinding. + * + * To keep doing their job as the coordinate system changes, + * the software endstop positions must be refreshed to remain + * at the same positions relative to the machine. + */ + void update_software_endstops(const AxisEnum axis) { + const float offs = 0.0 + #if HAS_HOME_OFFSET + + home_offset[axis] + #endif + #if HAS_POSITION_SHIFT + + position_shift[axis] + #endif + ; + + #if HAS_HOME_OFFSET && HAS_POSITION_SHIFT + workspace_offset[axis] = offs; + #endif + + #if ENABLED(DUAL_X_CARRIAGE) + if (axis == X_AXIS) { + + // In Dual X mode hotend_offset[X] is T1's home position + float dual_max_x = max(hotend_offset[X_AXIS][1], X2_MAX_POS); + + if (active_extruder != 0) { + // T1 can move from X2_MIN_POS to X2_MAX_POS or X2 home position (whichever is larger) + soft_endstop_min[X_AXIS] = X2_MIN_POS + offs; + soft_endstop_max[X_AXIS] = dual_max_x + offs; + } + else if (dual_x_carriage_mode == DXC_DUPLICATION_MODE) { + // In Duplication Mode, T0 can move as far left as X_MIN_POS + // but not so far to the right that T1 would move past the end + soft_endstop_min[X_AXIS] = base_min_pos(X_AXIS) + offs; + soft_endstop_max[X_AXIS] = min(base_max_pos(X_AXIS), dual_max_x - duplicate_extruder_x_offset) + offs; + } + else { + // In other modes, T0 can move from X_MIN_POS to X_MAX_POS + soft_endstop_min[axis] = base_min_pos(axis) + offs; + soft_endstop_max[axis] = base_max_pos(axis) + offs; + } + } + #elif ENABLED(DELTA) + soft_endstop_min[axis] = base_min_pos(axis) + (axis == Z_AXIS ? 0 : offs); + soft_endstop_max[axis] = base_max_pos(axis) + offs; + #else + soft_endstop_min[axis] = base_min_pos(axis) + offs; + soft_endstop_max[axis] = base_max_pos(axis) + offs; + #endif + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOPAIR("For ", axis_codes[axis]); + #if HAS_HOME_OFFSET + SERIAL_ECHOPAIR(" axis:\n home_offset = ", home_offset[axis]); + #endif + #if HAS_POSITION_SHIFT + SERIAL_ECHOPAIR("\n position_shift = ", position_shift[axis]); + #endif + SERIAL_ECHOPAIR("\n soft_endstop_min = ", soft_endstop_min[axis]); + SERIAL_ECHOLNPAIR("\n soft_endstop_max = ", soft_endstop_max[axis]); + } + #endif + + #if ENABLED(DELTA) + if (axis == Z_AXIS) + delta_clip_start_height = soft_endstop_max[axis] - delta_safe_distance_from_top(); + #endif + } + +#endif // HAS_WORKSPACE_OFFSET || DUAL_X_CARRIAGE + +#if HAS_M206_COMMAND + /** + * Change the home offset for an axis, update the current + * position and the software endstops to retain the same + * relative distance to the new home. + * + * Since this changes the current_position, code should + * call sync_plan_position soon after this. + */ + static void set_home_offset(const AxisEnum axis, const float v) { + current_position[axis] += v - home_offset[axis]; + home_offset[axis] = v; + update_software_endstops(axis); + } +#endif // HAS_M206_COMMAND + +/** + * Set an axis' current position to its home position (after homing). + * + * For Core and Cartesian robots this applies one-to-one when an + * individual axis has been homed. + * + * DELTA should wait until all homing is done before setting the XYZ + * current_position to home, because homing is a single operation. + * In the case where the axis positions are already known and previously + * homed, DELTA could home to X or Y individually by moving either one + * to the center. However, homing Z always homes XY and Z. + * + * SCARA should wait until all XY homing is done before setting the XY + * current_position to home, because neither X nor Y is at home until + * both are at home. Z can however be homed individually. + * + * Callers must sync the planner position after calling this! + */ +static void set_axis_is_at_home(const AxisEnum axis) { + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOPAIR(">>> set_axis_is_at_home(", axis_codes[axis]); + SERIAL_CHAR(')'); + SERIAL_EOL(); + } + #endif + + axis_known_position[axis] = axis_homed[axis] = true; + + #if HAS_POSITION_SHIFT + position_shift[axis] = 0; + update_software_endstops(axis); + #endif + + #if ENABLED(DUAL_X_CARRIAGE) + if (axis == X_AXIS && (active_extruder == 1 || dual_x_carriage_mode == DXC_DUPLICATION_MODE)) { + current_position[X_AXIS] = x_home_pos(active_extruder); + return; + } + #endif + + #if ENABLED(MORGAN_SCARA) + + /** + * Morgan SCARA homes XY at the same time + */ + if (axis == X_AXIS || axis == Y_AXIS) { + + float homeposition[XYZ]; + LOOP_XYZ(i) homeposition[i] = LOGICAL_POSITION(base_home_pos((AxisEnum)i), i); + + // SERIAL_ECHOPAIR("homeposition X:", homeposition[X_AXIS]); + // SERIAL_ECHOLNPAIR(" Y:", homeposition[Y_AXIS]); + + /** + * Get Home position SCARA arm angles using inverse kinematics, + * and calculate homing offset using forward kinematics + */ + inverse_kinematics(homeposition); + forward_kinematics_SCARA(delta[A_AXIS], delta[B_AXIS]); + + // SERIAL_ECHOPAIR("Cartesian X:", cartes[X_AXIS]); + // SERIAL_ECHOLNPAIR(" Y:", cartes[Y_AXIS]); + + current_position[axis] = LOGICAL_POSITION(cartes[axis], axis); + + /** + * SCARA home positions are based on configuration since the actual + * limits are determined by the inverse kinematic transform. + */ + soft_endstop_min[axis] = base_min_pos(axis); // + (cartes[axis] - base_home_pos(axis)); + soft_endstop_max[axis] = base_max_pos(axis); // + (cartes[axis] - base_home_pos(axis)); + } + else + #endif + { + current_position[axis] = LOGICAL_POSITION(base_home_pos(axis), axis); + } + + /** + * Z Probe Z Homing? Account for the probe's Z offset. + */ + #if HAS_BED_PROBE && Z_HOME_DIR < 0 + if (axis == Z_AXIS) { + #if HOMING_Z_WITH_PROBE + + current_position[Z_AXIS] -= zprobe_zoffset; + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOLNPGM("*** Z HOMED WITH PROBE (Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN) ***"); + SERIAL_ECHOLNPAIR("> zprobe_zoffset = ", zprobe_zoffset); + } + #endif + + #elif ENABLED(DEBUG_LEVELING_FEATURE) + + if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("*** Z HOMED TO ENDSTOP (Z_MIN_PROBE_ENDSTOP) ***"); + + #endif + } + #endif + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + #if HAS_HOME_OFFSET + SERIAL_ECHOPAIR("> home_offset[", axis_codes[axis]); + SERIAL_ECHOLNPAIR("] = ", home_offset[axis]); + #endif + DEBUG_POS("", current_position); + SERIAL_ECHOPAIR("<<< set_axis_is_at_home(", axis_codes[axis]); + SERIAL_CHAR(')'); + SERIAL_EOL(); + } + #endif + + #if ENABLED(I2C_POSITION_ENCODERS) + I2CPEM.homed(axis); + #endif +} + +/** + * Some planner shorthand inline functions + */ +inline float get_homing_bump_feedrate(const AxisEnum axis) { + static const uint8_t homing_bump_divisor[] PROGMEM = HOMING_BUMP_DIVISOR; + uint8_t hbd = pgm_read_byte(&homing_bump_divisor[axis]); + if (hbd < 1) { + hbd = 10; + SERIAL_ECHO_START(); + SERIAL_ECHOLNPGM("Warning: Homing Bump Divisor < 1"); + } + return homing_feedrate(axis) / hbd; +} + +/** + * Move the planner to the current position from wherever it last moved + * (or from wherever it has been told it is located). + */ +inline void line_to_current_position() { + planner.buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], feedrate_mm_s, active_extruder); +} + +/** + * Move the planner to the position stored in the destination array, which is + * used by G0/G1/G2/G3/G5 and many other functions to set a destination. + */ +inline void line_to_destination(const float fr_mm_s) { + planner.buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], fr_mm_s, active_extruder); +} +inline void line_to_destination() { line_to_destination(feedrate_mm_s); } + +inline void set_current_to_destination() { COPY(current_position, destination); } +inline void set_destination_to_current() { COPY(destination, current_position); } + +#if IS_KINEMATIC + /** + * Calculate delta, start a line, and set current_position to destination + */ + void prepare_uninterpolated_move_to_destination(const float fr_mm_s=0.0) { + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("prepare_uninterpolated_move_to_destination", destination); + #endif + + refresh_cmd_timeout(); + + #if UBL_DELTA + // ubl segmented line will do z-only moves in single segment + ubl.prepare_segmented_line_to(destination, MMS_SCALED(fr_mm_s ? fr_mm_s : feedrate_mm_s)); + #else + if ( current_position[X_AXIS] == destination[X_AXIS] + && current_position[Y_AXIS] == destination[Y_AXIS] + && current_position[Z_AXIS] == destination[Z_AXIS] + && current_position[E_AXIS] == destination[E_AXIS] + ) return; + + planner.buffer_line_kinematic(destination, MMS_SCALED(fr_mm_s ? fr_mm_s : feedrate_mm_s), active_extruder); + #endif + + set_current_to_destination(); + } +#endif // IS_KINEMATIC + +/** + * Plan a move to (X, Y, Z) and set the current_position + * The final current_position may not be the one that was requested + */ +void do_blocking_move_to(const float &lx, const float &ly, const float &lz, const float &fr_mm_s/*=0.0*/) { + const float old_feedrate_mm_s = feedrate_mm_s; + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) print_xyz(PSTR(">>> do_blocking_move_to"), NULL, lx, ly, lz); + #endif + + #if ENABLED(DELTA) + + if (!position_is_reachable_xy(lx, ly)) return; + + feedrate_mm_s = fr_mm_s ? fr_mm_s : XY_PROBE_FEEDRATE_MM_S; + + set_destination_to_current(); // sync destination at the start + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("set_destination_to_current", destination); + #endif + + // when in the danger zone + if (current_position[Z_AXIS] > delta_clip_start_height) { + if (lz > delta_clip_start_height) { // staying in the danger zone + destination[X_AXIS] = lx; // move directly (uninterpolated) + destination[Y_AXIS] = ly; + destination[Z_AXIS] = lz; + prepare_uninterpolated_move_to_destination(); // set_current_to_destination + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("danger zone move", current_position); + #endif + return; + } + else { + destination[Z_AXIS] = delta_clip_start_height; + prepare_uninterpolated_move_to_destination(); // set_current_to_destination + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("zone border move", current_position); + #endif + } + } + + if (lz > current_position[Z_AXIS]) { // raising? + destination[Z_AXIS] = lz; + prepare_uninterpolated_move_to_destination(); // set_current_to_destination + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("z raise move", current_position); + #endif + } + + destination[X_AXIS] = lx; + destination[Y_AXIS] = ly; + prepare_move_to_destination(); // set_current_to_destination + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("xy move", current_position); + #endif + + if (lz < current_position[Z_AXIS]) { // lowering? + destination[Z_AXIS] = lz; + prepare_uninterpolated_move_to_destination(); // set_current_to_destination + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("z lower move", current_position); + #endif + } + + #elif IS_SCARA + + if (!position_is_reachable_xy(lx, ly)) return; + + set_destination_to_current(); + + // If Z needs to raise, do it before moving XY + if (destination[Z_AXIS] < lz) { + destination[Z_AXIS] = lz; + prepare_uninterpolated_move_to_destination(fr_mm_s ? fr_mm_s : homing_feedrate(Z_AXIS)); + } + + destination[X_AXIS] = lx; + destination[Y_AXIS] = ly; + prepare_uninterpolated_move_to_destination(fr_mm_s ? fr_mm_s : XY_PROBE_FEEDRATE_MM_S); + + // If Z needs to lower, do it after moving XY + if (destination[Z_AXIS] > lz) { + destination[Z_AXIS] = lz; + prepare_uninterpolated_move_to_destination(fr_mm_s ? fr_mm_s : homing_feedrate(Z_AXIS)); + } + + #else + + // If Z needs to raise, do it before moving XY + if (current_position[Z_AXIS] < lz) { + feedrate_mm_s = fr_mm_s ? fr_mm_s : homing_feedrate(Z_AXIS); + current_position[Z_AXIS] = lz; + line_to_current_position(); + } + + feedrate_mm_s = fr_mm_s ? fr_mm_s : XY_PROBE_FEEDRATE_MM_S; + current_position[X_AXIS] = lx; + current_position[Y_AXIS] = ly; + line_to_current_position(); + + // If Z needs to lower, do it after moving XY + if (current_position[Z_AXIS] > lz) { + feedrate_mm_s = fr_mm_s ? fr_mm_s : homing_feedrate(Z_AXIS); + current_position[Z_AXIS] = lz; + line_to_current_position(); + } + + #endif + + stepper.synchronize(); + + feedrate_mm_s = old_feedrate_mm_s; + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("<<< do_blocking_move_to"); + #endif +} +void do_blocking_move_to_x(const float &lx, const float &fr_mm_s/*=0.0*/) { + do_blocking_move_to(lx, current_position[Y_AXIS], current_position[Z_AXIS], fr_mm_s); +} +void do_blocking_move_to_z(const float &lz, const float &fr_mm_s/*=0.0*/) { + do_blocking_move_to(current_position[X_AXIS], current_position[Y_AXIS], lz, fr_mm_s); +} +void do_blocking_move_to_xy(const float &lx, const float &ly, const float &fr_mm_s/*=0.0*/) { + do_blocking_move_to(lx, ly, current_position[Z_AXIS], fr_mm_s); +} + +// +// Prepare to do endstop or probe moves +// with custom feedrates. +// +// - Save current feedrates +// - Reset the rate multiplier +// - Reset the command timeout +// - Enable the endstops (for endstop moves) +// +static void setup_for_endstop_or_probe_move() { + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("setup_for_endstop_or_probe_move", current_position); + #endif + saved_feedrate_mm_s = feedrate_mm_s; + saved_feedrate_percentage = feedrate_percentage; + feedrate_percentage = 100; + refresh_cmd_timeout(); +} + +static void clean_up_after_endstop_or_probe_move() { + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("clean_up_after_endstop_or_probe_move", current_position); + #endif + feedrate_mm_s = saved_feedrate_mm_s; + feedrate_percentage = saved_feedrate_percentage; + refresh_cmd_timeout(); +} + +#if HAS_BED_PROBE + /** + * Raise Z to a minimum height to make room for a probe to move + */ + inline void do_probe_raise(const float z_raise) { + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOPAIR("do_probe_raise(", z_raise); + SERIAL_CHAR(')'); + SERIAL_EOL(); + } + #endif + + float z_dest = z_raise; + if (zprobe_zoffset < 0) z_dest -= zprobe_zoffset; + + if (z_dest > current_position[Z_AXIS]) + do_blocking_move_to_z(z_dest); + } + +#endif // HAS_BED_PROBE + +#if HAS_AXIS_UNHOMED_ERR + + bool axis_unhomed_error(const bool x/*=true*/, const bool y/*=true*/, const bool z/*=true*/) { + #if ENABLED(HOME_AFTER_DEACTIVATE) + const bool xx = x && !axis_known_position[X_AXIS], + yy = y && !axis_known_position[Y_AXIS], + zz = z && !axis_known_position[Z_AXIS]; + #else + const bool xx = x && !axis_homed[X_AXIS], + yy = y && !axis_homed[Y_AXIS], + zz = z && !axis_homed[Z_AXIS]; + #endif + if (xx || yy || zz) { + SERIAL_ECHO_START(); + SERIAL_ECHOPGM(MSG_HOME " "); + if (xx) SERIAL_ECHOPGM(MSG_X); + if (yy) SERIAL_ECHOPGM(MSG_Y); + if (zz) SERIAL_ECHOPGM(MSG_Z); + SERIAL_ECHOLNPGM(" " MSG_FIRST); + + #if ENABLED(ULTRA_LCD) + lcd_status_printf_P(0, PSTR(MSG_HOME " %s%s%s " MSG_FIRST), xx ? MSG_X : "", yy ? MSG_Y : "", zz ? MSG_Z : ""); + #endif + return true; + } + return false; + } + +#endif // HAS_AXIS_UNHOMED_ERR + +#if ENABLED(Z_PROBE_SLED) + + #ifndef SLED_DOCKING_OFFSET + #define SLED_DOCKING_OFFSET 0 + #endif + + /** + * Method to dock/undock a sled designed by Charles Bell. + * + * stow[in] If false, move to MAX_X and engage the solenoid + * If true, move to MAX_X and release the solenoid + */ + static void dock_sled(bool stow) { + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOPAIR("dock_sled(", stow); + SERIAL_CHAR(')'); + SERIAL_EOL(); + } + #endif + + // Dock sled a bit closer to ensure proper capturing + do_blocking_move_to_x(X_MAX_POS + SLED_DOCKING_OFFSET - ((stow) ? 1 : 0)); + + #if HAS_SOLENOID_1 && DISABLED(EXT_SOLENOID) + WRITE(SOL1_PIN, !stow); // switch solenoid + #endif + } + +#elif ENABLED(Z_PROBE_ALLEN_KEY) + + FORCE_INLINE void do_blocking_move_to(const float logical[XYZ], const float &fr_mm_s) { + do_blocking_move_to(logical[X_AXIS], logical[Y_AXIS], logical[Z_AXIS], fr_mm_s); + } + + void run_deploy_moves_script() { + #if defined(Z_PROBE_ALLEN_KEY_DEPLOY_1_X) || defined(Z_PROBE_ALLEN_KEY_DEPLOY_1_Y) || defined(Z_PROBE_ALLEN_KEY_DEPLOY_1_Z) + #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_1_X + #define Z_PROBE_ALLEN_KEY_DEPLOY_1_X current_position[X_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_1_Y + #define Z_PROBE_ALLEN_KEY_DEPLOY_1_Y current_position[Y_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_1_Z + #define Z_PROBE_ALLEN_KEY_DEPLOY_1_Z current_position[Z_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_1_FEEDRATE + #define Z_PROBE_ALLEN_KEY_DEPLOY_1_FEEDRATE 0.0 + #endif + const float deploy_1[] = { Z_PROBE_ALLEN_KEY_DEPLOY_1_X, Z_PROBE_ALLEN_KEY_DEPLOY_1_Y, Z_PROBE_ALLEN_KEY_DEPLOY_1_Z }; + do_blocking_move_to(deploy_1, MMM_TO_MMS(Z_PROBE_ALLEN_KEY_DEPLOY_1_FEEDRATE)); + #endif + #if defined(Z_PROBE_ALLEN_KEY_DEPLOY_2_X) || defined(Z_PROBE_ALLEN_KEY_DEPLOY_2_Y) || defined(Z_PROBE_ALLEN_KEY_DEPLOY_2_Z) + #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_2_X + #define Z_PROBE_ALLEN_KEY_DEPLOY_2_X current_position[X_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_2_Y + #define Z_PROBE_ALLEN_KEY_DEPLOY_2_Y current_position[Y_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_2_Z + #define Z_PROBE_ALLEN_KEY_DEPLOY_2_Z current_position[Z_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_2_FEEDRATE + #define Z_PROBE_ALLEN_KEY_DEPLOY_2_FEEDRATE 0.0 + #endif + const float deploy_2[] = { Z_PROBE_ALLEN_KEY_DEPLOY_2_X, Z_PROBE_ALLEN_KEY_DEPLOY_2_Y, Z_PROBE_ALLEN_KEY_DEPLOY_2_Z }; + do_blocking_move_to(deploy_2, MMM_TO_MMS(Z_PROBE_ALLEN_KEY_DEPLOY_2_FEEDRATE)); + #endif + #if defined(Z_PROBE_ALLEN_KEY_DEPLOY_3_X) || defined(Z_PROBE_ALLEN_KEY_DEPLOY_3_Y) || defined(Z_PROBE_ALLEN_KEY_DEPLOY_3_Z) + #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_3_X + #define Z_PROBE_ALLEN_KEY_DEPLOY_3_X current_position[X_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_3_Y + #define Z_PROBE_ALLEN_KEY_DEPLOY_3_Y current_position[Y_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_3_Z + #define Z_PROBE_ALLEN_KEY_DEPLOY_3_Z current_position[Z_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_3_FEEDRATE + #define Z_PROBE_ALLEN_KEY_DEPLOY_3_FEEDRATE 0.0 + #endif + const float deploy_3[] = { Z_PROBE_ALLEN_KEY_DEPLOY_3_X, Z_PROBE_ALLEN_KEY_DEPLOY_3_Y, Z_PROBE_ALLEN_KEY_DEPLOY_3_Z }; + do_blocking_move_to(deploy_3, MMM_TO_MMS(Z_PROBE_ALLEN_KEY_DEPLOY_3_FEEDRATE)); + #endif + #if defined(Z_PROBE_ALLEN_KEY_DEPLOY_4_X) || defined(Z_PROBE_ALLEN_KEY_DEPLOY_4_Y) || defined(Z_PROBE_ALLEN_KEY_DEPLOY_4_Z) + #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_4_X + #define Z_PROBE_ALLEN_KEY_DEPLOY_4_X current_position[X_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_4_Y + #define Z_PROBE_ALLEN_KEY_DEPLOY_4_Y current_position[Y_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_4_Z + #define Z_PROBE_ALLEN_KEY_DEPLOY_4_Z current_position[Z_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_4_FEEDRATE + #define Z_PROBE_ALLEN_KEY_DEPLOY_4_FEEDRATE 0.0 + #endif + const float deploy_4[] = { Z_PROBE_ALLEN_KEY_DEPLOY_4_X, Z_PROBE_ALLEN_KEY_DEPLOY_4_Y, Z_PROBE_ALLEN_KEY_DEPLOY_4_Z }; + do_blocking_move_to(deploy_4, MMM_TO_MMS(Z_PROBE_ALLEN_KEY_DEPLOY_4_FEEDRATE)); + #endif + #if defined(Z_PROBE_ALLEN_KEY_DEPLOY_5_X) || defined(Z_PROBE_ALLEN_KEY_DEPLOY_5_Y) || defined(Z_PROBE_ALLEN_KEY_DEPLOY_5_Z) + #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_5_X + #define Z_PROBE_ALLEN_KEY_DEPLOY_5_X current_position[X_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_5_Y + #define Z_PROBE_ALLEN_KEY_DEPLOY_5_Y current_position[Y_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_5_Z + #define Z_PROBE_ALLEN_KEY_DEPLOY_5_Z current_position[Z_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_5_FEEDRATE + #define Z_PROBE_ALLEN_KEY_DEPLOY_5_FEEDRATE 0.0 + #endif + const float deploy_5[] = { Z_PROBE_ALLEN_KEY_DEPLOY_5_X, Z_PROBE_ALLEN_KEY_DEPLOY_5_Y, Z_PROBE_ALLEN_KEY_DEPLOY_5_Z }; + do_blocking_move_to(deploy_5, MMM_TO_MMS(Z_PROBE_ALLEN_KEY_DEPLOY_5_FEEDRATE)); + #endif + } + + void run_stow_moves_script() { + #if defined(Z_PROBE_ALLEN_KEY_STOW_1_X) || defined(Z_PROBE_ALLEN_KEY_STOW_1_Y) || defined(Z_PROBE_ALLEN_KEY_STOW_1_Z) + #ifndef Z_PROBE_ALLEN_KEY_STOW_1_X + #define Z_PROBE_ALLEN_KEY_STOW_1_X current_position[X_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_STOW_1_Y + #define Z_PROBE_ALLEN_KEY_STOW_1_Y current_position[Y_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_STOW_1_Z + #define Z_PROBE_ALLEN_KEY_STOW_1_Z current_position[Z_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_STOW_1_FEEDRATE + #define Z_PROBE_ALLEN_KEY_STOW_1_FEEDRATE 0.0 + #endif + const float stow_1[] = { Z_PROBE_ALLEN_KEY_STOW_1_X, Z_PROBE_ALLEN_KEY_STOW_1_Y, Z_PROBE_ALLEN_KEY_STOW_1_Z }; + do_blocking_move_to(stow_1, MMM_TO_MMS(Z_PROBE_ALLEN_KEY_STOW_1_FEEDRATE)); + #endif + #if defined(Z_PROBE_ALLEN_KEY_STOW_2_X) || defined(Z_PROBE_ALLEN_KEY_STOW_2_Y) || defined(Z_PROBE_ALLEN_KEY_STOW_2_Z) + #ifndef Z_PROBE_ALLEN_KEY_STOW_2_X + #define Z_PROBE_ALLEN_KEY_STOW_2_X current_position[X_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_STOW_2_Y + #define Z_PROBE_ALLEN_KEY_STOW_2_Y current_position[Y_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_STOW_2_Z + #define Z_PROBE_ALLEN_KEY_STOW_2_Z current_position[Z_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_STOW_2_FEEDRATE + #define Z_PROBE_ALLEN_KEY_STOW_2_FEEDRATE 0.0 + #endif + const float stow_2[] = { Z_PROBE_ALLEN_KEY_STOW_2_X, Z_PROBE_ALLEN_KEY_STOW_2_Y, Z_PROBE_ALLEN_KEY_STOW_2_Z }; + do_blocking_move_to(stow_2, MMM_TO_MMS(Z_PROBE_ALLEN_KEY_STOW_2_FEEDRATE)); + #endif + #if defined(Z_PROBE_ALLEN_KEY_STOW_3_X) || defined(Z_PROBE_ALLEN_KEY_STOW_3_Y) || defined(Z_PROBE_ALLEN_KEY_STOW_3_Z) + #ifndef Z_PROBE_ALLEN_KEY_STOW_3_X + #define Z_PROBE_ALLEN_KEY_STOW_3_X current_position[X_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_STOW_3_Y + #define Z_PROBE_ALLEN_KEY_STOW_3_Y current_position[Y_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_STOW_3_Z + #define Z_PROBE_ALLEN_KEY_STOW_3_Z current_position[Z_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_STOW_3_FEEDRATE + #define Z_PROBE_ALLEN_KEY_STOW_3_FEEDRATE 0.0 + #endif + const float stow_3[] = { Z_PROBE_ALLEN_KEY_STOW_3_X, Z_PROBE_ALLEN_KEY_STOW_3_Y, Z_PROBE_ALLEN_KEY_STOW_3_Z }; + do_blocking_move_to(stow_3, MMM_TO_MMS(Z_PROBE_ALLEN_KEY_STOW_3_FEEDRATE)); + #endif + #if defined(Z_PROBE_ALLEN_KEY_STOW_4_X) || defined(Z_PROBE_ALLEN_KEY_STOW_4_Y) || defined(Z_PROBE_ALLEN_KEY_STOW_4_Z) + #ifndef Z_PROBE_ALLEN_KEY_STOW_4_X + #define Z_PROBE_ALLEN_KEY_STOW_4_X current_position[X_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_STOW_4_Y + #define Z_PROBE_ALLEN_KEY_STOW_4_Y current_position[Y_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_STOW_4_Z + #define Z_PROBE_ALLEN_KEY_STOW_4_Z current_position[Z_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_STOW_4_FEEDRATE + #define Z_PROBE_ALLEN_KEY_STOW_4_FEEDRATE 0.0 + #endif + const float stow_4[] = { Z_PROBE_ALLEN_KEY_STOW_4_X, Z_PROBE_ALLEN_KEY_STOW_4_Y, Z_PROBE_ALLEN_KEY_STOW_4_Z }; + do_blocking_move_to(stow_4, MMM_TO_MMS(Z_PROBE_ALLEN_KEY_STOW_4_FEEDRATE)); + #endif + #if defined(Z_PROBE_ALLEN_KEY_STOW_5_X) || defined(Z_PROBE_ALLEN_KEY_STOW_5_Y) || defined(Z_PROBE_ALLEN_KEY_STOW_5_Z) + #ifndef Z_PROBE_ALLEN_KEY_STOW_5_X + #define Z_PROBE_ALLEN_KEY_STOW_5_X current_position[X_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_STOW_5_Y + #define Z_PROBE_ALLEN_KEY_STOW_5_Y current_position[Y_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_STOW_5_Z + #define Z_PROBE_ALLEN_KEY_STOW_5_Z current_position[Z_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_STOW_5_FEEDRATE + #define Z_PROBE_ALLEN_KEY_STOW_5_FEEDRATE 0.0 + #endif + const float stow_5[] = { Z_PROBE_ALLEN_KEY_STOW_5_X, Z_PROBE_ALLEN_KEY_STOW_5_Y, Z_PROBE_ALLEN_KEY_STOW_5_Z }; + do_blocking_move_to(stow_5, MMM_TO_MMS(Z_PROBE_ALLEN_KEY_STOW_5_FEEDRATE)); + #endif + } + +#endif // Z_PROBE_ALLEN_KEY + +#if ENABLED(PROBING_FANS_OFF) + + void fans_pause(const bool p) { + if (p != fans_paused) { + fans_paused = p; + if (p) + for (uint8_t x = 0; x < FAN_COUNT; x++) { + paused_fanSpeeds[x] = fanSpeeds[x]; + fanSpeeds[x] = 0; + } + else + for (uint8_t x = 0; x < FAN_COUNT; x++) + fanSpeeds[x] = paused_fanSpeeds[x]; + } + } + +#endif // PROBING_FANS_OFF + +#if HAS_BED_PROBE + + // TRIGGERED_WHEN_STOWED_TEST can easily be extended to servo probes, ... if needed. + #if ENABLED(PROBE_IS_TRIGGERED_WHEN_STOWED_TEST) + #if ENABLED(Z_MIN_PROBE_ENDSTOP) + #define _TRIGGERED_WHEN_STOWED_TEST (READ(Z_MIN_PROBE_PIN) != Z_MIN_PROBE_ENDSTOP_INVERTING) + #else + #define _TRIGGERED_WHEN_STOWED_TEST (READ(Z_MIN_PIN) != Z_MIN_ENDSTOP_INVERTING) + #endif + #endif + + #if QUIET_PROBING + void probing_pause(const bool p) { + #if ENABLED(PROBING_HEATERS_OFF) + thermalManager.pause(p); + #endif + #if ENABLED(PROBING_FANS_OFF) + fans_pause(p); + #endif + if (p) safe_delay( + #if DELAY_BEFORE_PROBING > 25 + DELAY_BEFORE_PROBING + #else + 25 + #endif + ); + } + #endif // QUIET_PROBING + + #if ENABLED(BLTOUCH) + + void bltouch_command(int angle) { + MOVE_SERVO(Z_ENDSTOP_SERVO_NR, angle); // Give the BL-Touch the command and wait + safe_delay(BLTOUCH_DELAY); + } + + bool set_bltouch_deployed(const bool deploy) { + if (deploy && TEST_BLTOUCH()) { // If BL-Touch says it's triggered + bltouch_command(BLTOUCH_RESET); // try to reset it. + bltouch_command(BLTOUCH_DEPLOY); // Also needs to deploy and stow to + bltouch_command(BLTOUCH_STOW); // clear the triggered condition. + safe_delay(1500); // Wait for internal self-test to complete. + // (Measured completion time was 0.65 seconds + // after reset, deploy, and stow sequence) + if (TEST_BLTOUCH()) { // If it still claims to be triggered... + SERIAL_ERROR_START(); + SERIAL_ERRORLNPGM(MSG_STOP_BLTOUCH); + stop(); // punt! + return true; + } + } + + bltouch_command(deploy ? BLTOUCH_DEPLOY : BLTOUCH_STOW); + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOPAIR("set_bltouch_deployed(", deploy); + SERIAL_CHAR(')'); + SERIAL_EOL(); + } + #endif + + return false; + } + + #endif // BLTOUCH + + // returns false for ok and true for failure + bool set_probe_deployed(bool deploy) { + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + DEBUG_POS("set_probe_deployed", current_position); + SERIAL_ECHOLNPAIR("deploy: ", deploy); + } + #endif + + if (endstops.z_probe_enabled == deploy) return false; + + // Make room for probe + do_probe_raise(_Z_CLEARANCE_DEPLOY_PROBE); + + #if ENABLED(Z_PROBE_SLED) || ENABLED(Z_PROBE_ALLEN_KEY) + #if ENABLED(Z_PROBE_SLED) + #define _AUE_ARGS true, false, false + #else + #define _AUE_ARGS + #endif + if (axis_unhomed_error(_AUE_ARGS)) { + SERIAL_ERROR_START(); + SERIAL_ERRORLNPGM(MSG_STOP_UNHOMED); + stop(); + return true; + } + #endif + + const float oldXpos = current_position[X_AXIS], + oldYpos = current_position[Y_AXIS]; + + #ifdef _TRIGGERED_WHEN_STOWED_TEST + + // If endstop is already false, the Z probe is deployed + if (_TRIGGERED_WHEN_STOWED_TEST == deploy) { // closed after the probe specific actions. + // Would a goto be less ugly? + //while (!_TRIGGERED_WHEN_STOWED_TEST) idle(); // would offer the opportunity + // for a triggered when stowed manual probe. + + if (!deploy) endstops.enable_z_probe(false); // Switch off triggered when stowed probes early + // otherwise an Allen-Key probe can't be stowed. + #endif + + #if ENABLED(SOLENOID_PROBE) + + #if HAS_SOLENOID_1 + WRITE(SOL1_PIN, deploy); + #endif + + #elif ENABLED(Z_PROBE_SLED) + + dock_sled(!deploy); + + #elif HAS_Z_SERVO_ENDSTOP && DISABLED(BLTOUCH) + + MOVE_SERVO(Z_ENDSTOP_SERVO_NR, z_servo_angle[deploy ? 0 : 1]); + + #elif ENABLED(Z_PROBE_ALLEN_KEY) + + deploy ? run_deploy_moves_script() : run_stow_moves_script(); + + #endif + + #ifdef _TRIGGERED_WHEN_STOWED_TEST + } // _TRIGGERED_WHEN_STOWED_TEST == deploy + + if (_TRIGGERED_WHEN_STOWED_TEST == deploy) { // State hasn't changed? + + if (IsRunning()) { + SERIAL_ERROR_START(); + SERIAL_ERRORLNPGM("Z-Probe failed"); + LCD_ALERTMESSAGEPGM("Err: ZPROBE"); + } + stop(); + return true; + + } // _TRIGGERED_WHEN_STOWED_TEST == deploy + + #endif + + do_blocking_move_to(oldXpos, oldYpos, current_position[Z_AXIS]); // return to position before deploy + endstops.enable_z_probe(deploy); + return false; + } + + /** + * @brief Used by run_z_probe to do a single Z probe move. + * + * @param z Z destination + * @param fr_mm_s Feedrate in mm/s + * @return true to indicate an error + */ + static bool do_probe_move(const float z, const float fr_mm_m) { + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS(">>> do_probe_move", current_position); + #endif + + // Deploy BLTouch at the start of any probe + #if ENABLED(BLTOUCH) + if (set_bltouch_deployed(true)) return true; + #endif + + #if QUIET_PROBING + probing_pause(true); + #endif + + // Move down until probe triggered + do_blocking_move_to_z(z, MMM_TO_MMS(fr_mm_m)); + + // Check to see if the probe was triggered + const bool probe_triggered = TEST(Endstops::endstop_hit_bits, + #if ENABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN) + Z_MIN + #else + Z_MIN_PROBE + #endif + ); + + #if QUIET_PROBING + probing_pause(false); + #endif + + // Retract BLTouch immediately after a probe if it was triggered + #if ENABLED(BLTOUCH) + if (probe_triggered && set_bltouch_deployed(false)) return true; + #endif + + // Clear endstop flags + endstops.hit_on_purpose(); + + // Get Z where the steppers were interrupted + set_current_from_steppers_for_axis(Z_AXIS); + + // Tell the planner where we actually are + SYNC_PLAN_POSITION_KINEMATIC(); + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("<<< do_probe_move", current_position); + #endif + + return !probe_triggered; + } + + /** + * @details Used by probe_pt to do a single Z probe. + * Leaves current_position[Z_AXIS] at the height where the probe triggered. + * + * @param short_move Flag for a shorter probe move towards the bed + * @return The raw Z position where the probe was triggered + */ + static float run_z_probe(const bool short_move=true) { + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS(">>> run_z_probe", current_position); + #endif + + // Prevent stepper_inactive_time from running out and EXTRUDER_RUNOUT_PREVENT from extruding + refresh_cmd_timeout(); + + #if ENABLED(PROBE_DOUBLE_TOUCH) + + // Do a first probe at the fast speed + if (do_probe_move(-10, Z_PROBE_SPEED_FAST)) return NAN; + + #if ENABLED(DEBUG_LEVELING_FEATURE) + float first_probe_z = current_position[Z_AXIS]; + if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPAIR("1st Probe Z:", first_probe_z); + #endif + + // move up to make clearance for the probe + do_blocking_move_to_z(current_position[Z_AXIS] + Z_CLEARANCE_BETWEEN_PROBES, MMM_TO_MMS(Z_PROBE_SPEED_FAST)); + + #else + + // If the nozzle is above the travel height then + // move down quickly before doing the slow probe + float z = Z_CLEARANCE_DEPLOY_PROBE; + if (zprobe_zoffset < 0) z -= zprobe_zoffset; + + if (z < current_position[Z_AXIS]) { + + // If we don't make it to the z position (i.e. the probe triggered), move up to make clearance for the probe + if (!do_probe_move(z, Z_PROBE_SPEED_FAST)) + do_blocking_move_to_z(current_position[Z_AXIS] + Z_CLEARANCE_BETWEEN_PROBES, MMM_TO_MMS(Z_PROBE_SPEED_FAST)); + } + #endif + + // move down slowly to find bed + if (do_probe_move(-10 + (short_move ? 0 : -(Z_MAX_LENGTH)), Z_PROBE_SPEED_SLOW)) return NAN; + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("<<< run_z_probe", current_position); + #endif + + // Debug: compare probe heights + #if ENABLED(PROBE_DOUBLE_TOUCH) && ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOPAIR("2nd Probe Z:", current_position[Z_AXIS]); + SERIAL_ECHOLNPAIR(" Discrepancy:", first_probe_z - current_position[Z_AXIS]); + } + #endif + + return RAW_CURRENT_POSITION(Z) + zprobe_zoffset + #if ENABLED(DELTA) + + home_offset[Z_AXIS] // Account for delta height adjustment + #endif + ; + } + + /** + * - Move to the given XY + * - Deploy the probe, if not already deployed + * - Probe the bed, get the Z position + * - Depending on the 'stow' flag + * - Stow the probe, or + * - Raise to the BETWEEN height + * - Return the probed Z position + */ + float probe_pt(const float &lx, const float &ly, const bool stow, const uint8_t verbose_level, const bool printable=true) { + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOPAIR(">>> probe_pt(", lx); + SERIAL_ECHOPAIR(", ", ly); + SERIAL_ECHOPAIR(", ", stow ? "" : "no "); + SERIAL_ECHOLNPGM("stow)"); + DEBUG_POS("", current_position); + } + #endif + + const float nx = lx - (X_PROBE_OFFSET_FROM_EXTRUDER), ny = ly - (Y_PROBE_OFFSET_FROM_EXTRUDER); + + if (printable + ? !position_is_reachable_xy(nx, ny) + : !position_is_reachable_by_probe_xy(lx, ly) + ) return NAN; + + + const float old_feedrate_mm_s = feedrate_mm_s; + + #if ENABLED(DELTA) + if (current_position[Z_AXIS] > delta_clip_start_height) + do_blocking_move_to_z(delta_clip_start_height); + #endif + + #if HAS_SOFTWARE_ENDSTOPS + // Store the status of the soft endstops and disable if we're probing a non-printable location + static bool enable_soft_endstops = soft_endstops_enabled; + if (!printable) soft_endstops_enabled = false; + #endif + + feedrate_mm_s = XY_PROBE_FEEDRATE_MM_S; + + // Move the probe to the given XY + do_blocking_move_to_xy(nx, ny); + + float measured_z = NAN; + if (!DEPLOY_PROBE()) { + measured_z = run_z_probe(printable); + + if (!stow) + do_blocking_move_to_z(current_position[Z_AXIS] + Z_CLEARANCE_BETWEEN_PROBES, MMM_TO_MMS(Z_PROBE_SPEED_FAST)); + else + if (STOW_PROBE()) measured_z = NAN; + } + + #if HAS_SOFTWARE_ENDSTOPS + // Restore the soft endstop status + soft_endstops_enabled = enable_soft_endstops; + #endif + + if (verbose_level > 2) { + SERIAL_PROTOCOLPGM("Bed X: "); + SERIAL_PROTOCOL_F(lx, 3); + SERIAL_PROTOCOLPGM(" Y: "); + SERIAL_PROTOCOL_F(ly, 3); + SERIAL_PROTOCOLPGM(" Z: "); + SERIAL_PROTOCOL_F(measured_z, 3); + SERIAL_EOL(); + } + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("<<< probe_pt"); + #endif + + feedrate_mm_s = old_feedrate_mm_s; + + if (isnan(measured_z)) { + LCD_MESSAGEPGM(MSG_ERR_PROBING_FAILED); + SERIAL_ERROR_START(); + SERIAL_ERRORLNPGM(MSG_ERR_PROBING_FAILED); + } + + return measured_z; + } + +#endif // HAS_BED_PROBE + +#if HAS_LEVELING + + bool leveling_is_valid() { + return + #if ENABLED(MESH_BED_LEVELING) + mbl.has_mesh() + #elif ENABLED(AUTO_BED_LEVELING_BILINEAR) + !!bilinear_grid_spacing[X_AXIS] + #elif ENABLED(AUTO_BED_LEVELING_UBL) + true + #else // 3POINT, LINEAR + true + #endif + ; + } + + bool leveling_is_active() { + return + #if ENABLED(MESH_BED_LEVELING) + mbl.active() + #elif ENABLED(AUTO_BED_LEVELING_UBL) + ubl.state.active + #else + planner.abl_enabled + #endif + ; + } + + /** + * Turn bed leveling on or off, fixing the current + * position as-needed. + * + * Disable: Current position = physical position + * Enable: Current position = "unleveled" physical position + */ + 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 + + if (can_change && enable != leveling_is_active()) { + + #if ENABLED(MESH_BED_LEVELING) + + if (!enable) + planner.apply_leveling(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS]); + + const bool enabling = enable && leveling_is_valid(); + mbl.set_active(enabling); + if (enabling) planner.unapply_leveling(current_position); + + #elif ENABLED(AUTO_BED_LEVELING_UBL) + #if PLANNER_LEVELING + if (ubl.state.active) { // leveling from on to off + // change unleveled current_position to physical current_position without moving steppers. + planner.apply_leveling(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS]); + ubl.state.active = false; // disable only AFTER calling apply_leveling + } + else { // leveling from off to on + ubl.state.active = true; // enable BEFORE calling unapply_leveling, otherwise ignored + // change physical current_position to unleveled current_position without moving steppers. + planner.unapply_leveling(current_position); + } + #else + ubl.state.active = enable; // just flip the bit, current_position will be wrong until next move. + #endif + + #else // ABL + + #if ENABLED(AUTO_BED_LEVELING_BILINEAR) + // Force bilinear_z_offset to re-calculate next time + const float reset[XYZ] = { -9999.999, -9999.999, 0 }; + (void)bilinear_z_offset(reset); + #endif + + // Enable or disable leveling compensation in the planner + planner.abl_enabled = enable; + + if (!enable) + // When disabling just get the current position from the steppers. + // This will yield the smallest error when first converted back to steps. + set_current_from_steppers_for_axis( + #if ABL_PLANAR + ALL_AXES + #else + Z_AXIS + #endif + ); + else + // When enabling, remove compensation from the current position, + // so compensation will give the right stepper counts. + planner.unapply_leveling(current_position); + + #endif // ABL + } + } + + #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) + + void set_z_fade_height(const float zfh) { + + const bool level_active = leveling_is_active(); + + #if ENABLED(AUTO_BED_LEVELING_UBL) + + if (level_active) + set_bed_leveling_enabled(false); // turn off before changing fade height for proper apply/unapply leveling to maintain current_position + planner.z_fade_height = zfh; + planner.inverse_z_fade_height = RECIPROCAL(zfh); + if (level_active) + set_bed_leveling_enabled(true); // turn back on after changing fade height + + #else + + planner.z_fade_height = zfh; + planner.inverse_z_fade_height = RECIPROCAL(zfh); + + if (level_active) { + set_current_from_steppers_for_axis( + #if ABL_PLANAR + ALL_AXES + #else + Z_AXIS + #endif + ); + } + #endif + } + + #endif // LEVELING_FADE_HEIGHT + + /** + * Reset calibration results to zero. + */ + void reset_bed_level() { + set_bed_leveling_enabled(false); + #if ENABLED(MESH_BED_LEVELING) + if (leveling_is_valid()) { + mbl.reset(); + mbl.set_has_mesh(false); + } + #else + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("reset_bed_level"); + #endif + #if ABL_PLANAR + planner.bed_level_matrix.set_to_identity(); + #elif ENABLED(AUTO_BED_LEVELING_BILINEAR) + bilinear_start[X_AXIS] = bilinear_start[Y_AXIS] = + bilinear_grid_spacing[X_AXIS] = bilinear_grid_spacing[Y_AXIS] = 0; + 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; + #elif ENABLED(AUTO_BED_LEVELING_UBL) + ubl.reset(); + #endif + #endif + } + +#endif // HAS_LEVELING + +#if ENABLED(AUTO_BED_LEVELING_BILINEAR) || ENABLED(MESH_BED_LEVELING) + + /** + * Enable to produce output in JSON format suitable + * for SCAD or JavaScript mesh visualizers. + * + * Visualize meshes in OpenSCAD using the included script. + * + * buildroot/shared/scripts/MarlinMesh.scad + */ + //#define SCAD_MESH_OUTPUT + + /** + * Print calibration results for plotting or manual frame adjustment. + */ + static void print_2d_array(const uint8_t sx, const uint8_t sy, const uint8_t precision, float (*fn)(const uint8_t, const uint8_t)) { + #ifndef SCAD_MESH_OUTPUT + for (uint8_t x = 0; x < sx; x++) { + for (uint8_t i = 0; i < precision + 2 + (x < 10 ? 1 : 0); i++) + SERIAL_PROTOCOLCHAR(' '); + SERIAL_PROTOCOL((int)x); + } + SERIAL_EOL(); + #endif + #ifdef SCAD_MESH_OUTPUT + SERIAL_PROTOCOLLNPGM("measured_z = ["); // open 2D array + #endif + for (uint8_t y = 0; y < sy; y++) { + #ifdef SCAD_MESH_OUTPUT + SERIAL_PROTOCOLPGM(" ["); // open sub-array + #else + if (y < 10) SERIAL_PROTOCOLCHAR(' '); + SERIAL_PROTOCOL((int)y); + #endif + for (uint8_t x = 0; x < sx; x++) { + SERIAL_PROTOCOLCHAR(' '); + const float offset = fn(x, y); + if (!isnan(offset)) { + if (offset >= 0) SERIAL_PROTOCOLCHAR('+'); + SERIAL_PROTOCOL_F(offset, precision); + } + else { + #ifdef SCAD_MESH_OUTPUT + for (uint8_t i = 3; i < precision + 3; i++) + SERIAL_PROTOCOLCHAR(' '); + SERIAL_PROTOCOLPGM("NAN"); + #else + for (uint8_t i = 0; i < precision + 3; i++) + SERIAL_PROTOCOLCHAR(i ? '=' : ' '); + #endif + } + #ifdef SCAD_MESH_OUTPUT + if (x < sx - 1) SERIAL_PROTOCOLCHAR(','); + #endif + } + #ifdef SCAD_MESH_OUTPUT + SERIAL_PROTOCOLCHAR(' '); + SERIAL_PROTOCOLCHAR(']'); // close sub-array + if (y < sy - 1) SERIAL_PROTOCOLCHAR(','); + #endif + SERIAL_EOL(); + } + #ifdef SCAD_MESH_OUTPUT + SERIAL_PROTOCOLPGM("];"); // close 2D array + #endif + SERIAL_EOL(); + } + +#endif + +#if ENABLED(AUTO_BED_LEVELING_BILINEAR) + + /** + * Extrapolate a single point from its neighbors + */ + static void extrapolate_one_point(const uint8_t x, const uint8_t y, const int8_t xdir, const int8_t ydir) { + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOPGM("Extrapolate ["); + if (x < 10) SERIAL_CHAR(' '); + SERIAL_ECHO((int)x); + SERIAL_CHAR(xdir ? (xdir > 0 ? '+' : '-') : ' '); + SERIAL_CHAR(' '); + if (y < 10) SERIAL_CHAR(' '); + SERIAL_ECHO((int)y); + SERIAL_CHAR(ydir ? (ydir > 0 ? '+' : '-') : ' '); + SERIAL_CHAR(']'); + } + #endif + if (!isnan(z_values[x][y])) { + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM(" (done)"); + #endif + return; // Don't overwrite good values. + } + SERIAL_EOL(); + + // Get X neighbors, Y neighbors, and XY neighbors + const uint8_t x1 = x + xdir, y1 = y + ydir, x2 = x1 + xdir, y2 = y1 + ydir; + float a1 = z_values[x1][y ], a2 = z_values[x2][y ], + b1 = z_values[x ][y1], b2 = z_values[x ][y2], + c1 = z_values[x1][y1], c2 = z_values[x2][y2]; + + // Treat far unprobed points as zero, near as equal to far + if (isnan(a2)) a2 = 0.0; if (isnan(a1)) a1 = a2; + if (isnan(b2)) b2 = 0.0; if (isnan(b1)) b1 = b2; + if (isnan(c2)) c2 = 0.0; if (isnan(c1)) c1 = c2; + + const float a = 2 * a1 - a2, b = 2 * b1 - b2, c = 2 * c1 - c2; + + // Take the average instead of the median + z_values[x][y] = (a + b + c) / 3.0; + + // Median is robust (ignores outliers). + // z_values[x][y] = (a < b) ? ((b < c) ? b : (c < a) ? a : c) + // : ((c < b) ? b : (a < c) ? a : c); + } + + //Enable this if your SCARA uses 180° of total area + //#define EXTRAPOLATE_FROM_EDGE + + #if ENABLED(EXTRAPOLATE_FROM_EDGE) + #if GRID_MAX_POINTS_X < GRID_MAX_POINTS_Y + #define HALF_IN_X + #elif GRID_MAX_POINTS_Y < GRID_MAX_POINTS_X + #define HALF_IN_Y + #endif + #endif + + /** + * Fill in the unprobed points (corners of circular print surface) + * using linear extrapolation, away from the center. + */ + static void extrapolate_unprobed_bed_level() { + #ifdef HALF_IN_X + constexpr uint8_t ctrx2 = 0, xlen = GRID_MAX_POINTS_X - 1; + #else + constexpr uint8_t ctrx1 = (GRID_MAX_POINTS_X - 1) / 2, // left-of-center + ctrx2 = (GRID_MAX_POINTS_X) / 2, // right-of-center + xlen = ctrx1; + #endif + + #ifdef HALF_IN_Y + constexpr uint8_t ctry2 = 0, ylen = GRID_MAX_POINTS_Y - 1; + #else + constexpr uint8_t ctry1 = (GRID_MAX_POINTS_Y - 1) / 2, // top-of-center + ctry2 = (GRID_MAX_POINTS_Y) / 2, // bottom-of-center + ylen = ctry1; + #endif + + for (uint8_t xo = 0; xo <= xlen; xo++) + for (uint8_t yo = 0; yo <= ylen; yo++) { + uint8_t x2 = ctrx2 + xo, y2 = ctry2 + yo; + #ifndef HALF_IN_X + const uint8_t x1 = ctrx1 - xo; + #endif + #ifndef HALF_IN_Y + const uint8_t y1 = ctry1 - yo; + #ifndef HALF_IN_X + extrapolate_one_point(x1, y1, +1, +1); // left-below + + + #endif + extrapolate_one_point(x2, y1, -1, +1); // right-below - + + #endif + #ifndef HALF_IN_X + extrapolate_one_point(x1, y2, +1, -1); // left-above + - + #endif + extrapolate_one_point(x2, y2, -1, -1); // right-above - - + } + + } + + static void print_bilinear_leveling_grid() { + SERIAL_ECHOLNPGM("Bilinear Leveling Grid:"); + print_2d_array(GRID_MAX_POINTS_X, GRID_MAX_POINTS_Y, 3, + [](const uint8_t ix, const uint8_t iy) { return z_values[ix][iy]; } + ); + } + + #if ENABLED(ABL_BILINEAR_SUBDIVISION) + + #define ABL_GRID_POINTS_VIRT_X (GRID_MAX_POINTS_X - 1) * (BILINEAR_SUBDIVISIONS) + 1 + #define ABL_GRID_POINTS_VIRT_Y (GRID_MAX_POINTS_Y - 1) * (BILINEAR_SUBDIVISIONS) + 1 + #define ABL_TEMP_POINTS_X (GRID_MAX_POINTS_X + 2) + #define ABL_TEMP_POINTS_Y (GRID_MAX_POINTS_Y + 2) + float z_values_virt[ABL_GRID_POINTS_VIRT_X][ABL_GRID_POINTS_VIRT_Y]; + int bilinear_grid_spacing_virt[2] = { 0 }; + float bilinear_grid_factor_virt[2] = { 0 }; + + static void print_bilinear_leveling_grid_virt() { + SERIAL_ECHOLNPGM("Subdivided with CATMULL ROM Leveling Grid:"); + print_2d_array(ABL_GRID_POINTS_VIRT_X, ABL_GRID_POINTS_VIRT_Y, 5, + [](const uint8_t ix, const uint8_t iy) { return z_values_virt[ix][iy]; } + ); + } + + #define LINEAR_EXTRAPOLATION(E, I) ((E) * 2 - (I)) + float bed_level_virt_coord(const uint8_t x, const uint8_t y) { + uint8_t ep = 0, ip = 1; + if (!x || x == ABL_TEMP_POINTS_X - 1) { + if (x) { + ep = GRID_MAX_POINTS_X - 1; + ip = GRID_MAX_POINTS_X - 2; + } + if (WITHIN(y, 1, ABL_TEMP_POINTS_Y - 2)) + return LINEAR_EXTRAPOLATION( + z_values[ep][y - 1], + z_values[ip][y - 1] + ); + else + return LINEAR_EXTRAPOLATION( + bed_level_virt_coord(ep + 1, y), + bed_level_virt_coord(ip + 1, y) + ); + } + if (!y || y == ABL_TEMP_POINTS_Y - 1) { + if (y) { + ep = GRID_MAX_POINTS_Y - 1; + ip = GRID_MAX_POINTS_Y - 2; + } + if (WITHIN(x, 1, ABL_TEMP_POINTS_X - 2)) + return LINEAR_EXTRAPOLATION( + z_values[x - 1][ep], + z_values[x - 1][ip] + ); + else + return LINEAR_EXTRAPOLATION( + bed_level_virt_coord(x, ep + 1), + bed_level_virt_coord(x, ip + 1) + ); + } + return z_values[x - 1][y - 1]; + } + + static float bed_level_virt_cmr(const float p[4], const uint8_t i, const float t) { + return ( + p[i-1] * -t * sq(1 - t) + + p[i] * (2 - 5 * sq(t) + 3 * t * sq(t)) + + p[i+1] * t * (1 + 4 * t - 3 * sq(t)) + - p[i+2] * sq(t) * (1 - t) + ) * 0.5; + } + + 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++) { + column[j] = bed_level_virt_coord(i + x - 1, j + y - 1); + } + row[i] = bed_level_virt_cmr(column, 1, ty); + } + return bed_level_virt_cmr(row, 1, tx); + } + + void bed_level_virt_interpolate() { + bilinear_grid_spacing_virt[X_AXIS] = bilinear_grid_spacing[X_AXIS] / (BILINEAR_SUBDIVISIONS); + bilinear_grid_spacing_virt[Y_AXIS] = bilinear_grid_spacing[Y_AXIS] / (BILINEAR_SUBDIVISIONS); + bilinear_grid_factor_virt[X_AXIS] = RECIPROCAL(bilinear_grid_spacing_virt[X_AXIS]); + bilinear_grid_factor_virt[Y_AXIS] = RECIPROCAL(bilinear_grid_spacing_virt[Y_AXIS]); + 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)) + continue; + z_values_virt[x * (BILINEAR_SUBDIVISIONS) + tx][y * (BILINEAR_SUBDIVISIONS) + ty] = + bed_level_virt_2cmr( + x + 1, + y + 1, + (float)tx / (BILINEAR_SUBDIVISIONS), + (float)ty / (BILINEAR_SUBDIVISIONS) + ); + } + } + #endif // ABL_BILINEAR_SUBDIVISION + + // Refresh after other values have been updated + void refresh_bed_level() { + bilinear_grid_factor[X_AXIS] = RECIPROCAL(bilinear_grid_spacing[X_AXIS]); + bilinear_grid_factor[Y_AXIS] = RECIPROCAL(bilinear_grid_spacing[Y_AXIS]); + #if ENABLED(ABL_BILINEAR_SUBDIVISION) + bed_level_virt_interpolate(); + #endif + } + +#endif // AUTO_BED_LEVELING_BILINEAR + +/** + * Home an individual linear axis + */ +static void do_homing_move(const AxisEnum axis, const float distance, const float fr_mm_s=0.0) { + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOPAIR(">>> do_homing_move(", axis_codes[axis]); + SERIAL_ECHOPAIR(", ", distance); + SERIAL_ECHOPAIR(", ", fr_mm_s); + SERIAL_CHAR(')'); + SERIAL_EOL(); + } + #endif + + #if HOMING_Z_WITH_PROBE && ENABLED(BLTOUCH) + const bool deploy_bltouch = (axis == Z_AXIS && distance < 0); + if (deploy_bltouch) set_bltouch_deployed(true); + #endif + + #if QUIET_PROBING + if (axis == Z_AXIS) probing_pause(true); + #endif + + // Tell the planner we're at Z=0 + current_position[axis] = 0; + + #if IS_SCARA + SYNC_PLAN_POSITION_KINEMATIC(); + current_position[axis] = distance; + inverse_kinematics(current_position); + planner.buffer_line(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], current_position[E_AXIS], fr_mm_s ? fr_mm_s : homing_feedrate(axis), active_extruder); + #else + sync_plan_position(); + current_position[axis] = distance; + planner.buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], fr_mm_s ? fr_mm_s : homing_feedrate(axis), active_extruder); + #endif + + stepper.synchronize(); + + #if QUIET_PROBING + if (axis == Z_AXIS) probing_pause(false); + #endif + + #if HOMING_Z_WITH_PROBE && ENABLED(BLTOUCH) + if (deploy_bltouch) set_bltouch_deployed(false); + #endif + + endstops.hit_on_purpose(); + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOPAIR("<<< do_homing_move(", axis_codes[axis]); + SERIAL_CHAR(')'); + SERIAL_EOL(); + } + #endif +} + +/** + * TMC2130 specific sensorless homing using stallGuard2. + * stallGuard2 only works when in spreadCycle mode. + * spreadCycle and stealthChop are mutually exclusive. + */ +#if ENABLED(SENSORLESS_HOMING) + void tmc2130_sensorless_homing(TMC2130Stepper &st, bool enable=true) { + #if ENABLED(STEALTHCHOP) + if (enable) { + st.coolstep_min_speed(1024UL * 1024UL - 1UL); + st.stealthChop(0); + } + else { + st.coolstep_min_speed(0); + st.stealthChop(1); + } + #endif + + st.diag1_stall(enable ? 1 : 0); + } +#endif + +/** + * Home an individual "raw axis" to its endstop. + * This applies to XYZ on Cartesian and Core robots, and + * to the individual ABC steppers on DELTA and SCARA. + * + * At the end of the procedure the axis is marked as + * homed and the current position of that axis is updated. + * Kinematic robots should wait till all axes are homed + * before updating the current position. + */ + +#define HOMEAXIS(LETTER) homeaxis(LETTER##_AXIS) + +static void homeaxis(const AxisEnum axis) { + + #if IS_SCARA + // Only Z homing (with probe) is permitted + if (axis != Z_AXIS) { BUZZ(100, 880); return; } + #else + #define CAN_HOME(A) \ + (axis == A##_AXIS && ((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 ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOPAIR(">>> homeaxis(", axis_codes[axis]); + SERIAL_CHAR(')'); + SERIAL_EOL(); + } + #endif + + const int axis_home_dir = + #if ENABLED(DUAL_X_CARRIAGE) + (axis == X_AXIS) ? x_home_dir(active_extruder) : + #endif + home_dir(axis); + + // Homing Z towards the bed? Deploy the Z probe or endstop. + #if HOMING_Z_WITH_PROBE + if (axis == Z_AXIS && DEPLOY_PROBE()) return; + #endif + + // Set a flag for Z motor locking + #if ENABLED(Z_DUAL_ENDSTOPS) + if (axis == Z_AXIS) stepper.set_homing_flag(true); + #endif + + // Disable stealthChop if used. Enable diag1 pin on driver. + #if ENABLED(SENSORLESS_HOMING) + #if ENABLED(X_IS_TMC2130) + if (axis == X_AXIS) tmc2130_sensorless_homing(stepperX); + #endif + #if ENABLED(Y_IS_TMC2130) + if (axis == Y_AXIS) tmc2130_sensorless_homing(stepperY); + #endif + #endif + + // Fast move towards endstop until triggered + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("Home 1 Fast:"); + #endif + do_homing_move(axis, 1.5 * max_length(axis) * axis_home_dir); + + // When homing Z with probe respect probe clearance + const float bump = axis_home_dir * ( + #if HOMING_Z_WITH_PROBE + (axis == Z_AXIS) ? max(Z_CLEARANCE_BETWEEN_PROBES, home_bump_mm(Z_AXIS)) : + #endif + home_bump_mm(axis) + ); + + // If a second homing move is configured... + if (bump) { + // Move away from the endstop by the axis HOME_BUMP_MM + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("Move Away:"); + #endif + do_homing_move(axis, -bump); + + // Slow move towards endstop until triggered + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("Home 2 Slow:"); + #endif + do_homing_move(axis, 2 * bump, get_homing_bump_feedrate(axis)); + } + + #if ENABLED(Z_DUAL_ENDSTOPS) + if (axis == Z_AXIS) { + float adj = FABS(z_endstop_adj); + bool lockZ1; + if (axis_home_dir > 0) { + adj = -adj; + lockZ1 = (z_endstop_adj > 0); + } + else + lockZ1 = (z_endstop_adj < 0); + + if (lockZ1) stepper.set_z_lock(true); else stepper.set_z2_lock(true); + + // Move to the adjusted endstop height + do_homing_move(axis, adj); + + if (lockZ1) stepper.set_z_lock(false); else stepper.set_z2_lock(false); + stepper.set_homing_flag(false); + } // Z_AXIS + #endif + + #if IS_SCARA + + set_axis_is_at_home(axis); + SYNC_PLAN_POSITION_KINEMATIC(); + + #elif ENABLED(DELTA) + + // Delta has already moved all three towers up in G28 + // so here it re-homes each tower in turn. + // Delta homing treats the axes as normal linear axes. + + // retrace by the amount specified in endstop_adj + additional 0.1mm in order to have minimum steps + if (endstop_adj[axis] * Z_HOME_DIR <= 0) { + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("endstop_adj:"); + #endif + do_homing_move(axis, endstop_adj[axis] - 0.1 * Z_HOME_DIR); + } + + #else + + // For cartesian/core machines, + // set the axis to its home position + set_axis_is_at_home(axis); + sync_plan_position(); + + destination[axis] = current_position[axis]; + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("> AFTER set_axis_is_at_home", current_position); + #endif + + #endif + + // Re-enable stealthChop if used. Disable diag1 pin on driver. + #if ENABLED(SENSORLESS_HOMING) + #if ENABLED(X_IS_TMC2130) + if (axis == X_AXIS) tmc2130_sensorless_homing(stepperX, false); + #endif + #if ENABLED(Y_IS_TMC2130) + if (axis == Y_AXIS) tmc2130_sensorless_homing(stepperY, false); + #endif + #endif + + // Put away the Z probe + #if HOMING_Z_WITH_PROBE + if (axis == Z_AXIS && STOW_PROBE()) return; + #endif + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOPAIR("<<< homeaxis(", axis_codes[axis]); + SERIAL_CHAR(')'); + SERIAL_EOL(); + } + #endif +} // homeaxis() + +#if ENABLED(FWRETRACT) + + /** + * Retract or recover according to firmware settings + * + * This function handles retract/recover moves for G10 and G11, + * plus auto-retract moves sent from G0/G1 when E-only moves are done. + * + * To simplify the logic, doubled retract/recover moves are ignored. + * + * Note: Z lift is done transparently to the planner. Aborting + * a print between G10 and G11 may corrupt the Z position. + * + * Note: Auto-retract will apply the set Z hop in addition to any Z hop + * included in the G-code. Use M207 Z0 to to prevent double hop. + */ + void retract(const bool retracting + #if EXTRUDERS > 1 + , bool swapping = false + #endif + ) { + + static float hop_height, // Remember where the Z height started + hop_amount = 0.0; // Total amount lifted, for use in recover + + // Simply never allow two retracts or recovers in a row + if (retracted[active_extruder] == retracting) return; + + #if EXTRUDERS < 2 + bool swapping = false; + #endif + if (!retracting) swapping = retracted_swap[active_extruder]; + + /* // debugging + SERIAL_ECHOLNPAIR("retracting ", retracting); + SERIAL_ECHOLNPAIR("swapping ", swapping); + SERIAL_ECHOLNPAIR("active extruder ", active_extruder); + for (uint8_t i = 0; i < EXTRUDERS; ++i) { + SERIAL_ECHOPAIR("retracted[", i); + SERIAL_ECHOLNPAIR("] ", retracted[i]); + SERIAL_ECHOPAIR("retracted_swap[", i); + SERIAL_ECHOLNPAIR("] ", retracted_swap[i]); + } + SERIAL_ECHOLNPAIR("current_position[z] ", current_position[Z_AXIS]); + SERIAL_ECHOLNPAIR("hop_amount ", hop_amount); + //*/ + + const bool has_zhop = retract_zlift > 0.01; // Is there a hop set? + + const float old_feedrate_mm_s = feedrate_mm_s; + const int16_t old_flow = flow_percentage[active_extruder]; + + // Don't apply flow multiplication to retract/recover + flow_percentage[active_extruder] = 100; + + // The current position will be the destination for E and Z moves + set_destination_to_current(); + + stepper.synchronize(); // Wait for all moves to finish + + if (retracting) { + // Remember the Z height since G-code may include its own Z-hop + // For best results turn off Z hop if G-code already includes it + hop_height = destination[Z_AXIS]; + + // Retract by moving from a faux E position back to the current E position + feedrate_mm_s = retract_feedrate_mm_s; + current_position[E_AXIS] += (swapping ? swap_retract_length : retract_length) / volumetric_multiplier[active_extruder]; + sync_plan_position_e(); + prepare_move_to_destination(); + + // Is a Z hop set, and has the hop not yet been done? + if (has_zhop) { + hop_amount += retract_zlift; // Carriage is raised for retraction hop + current_position[Z_AXIS] -= retract_zlift; // Pretend current pos is lower. Next move raises Z. + SYNC_PLAN_POSITION_KINEMATIC(); // Set the planner to the new position + prepare_move_to_destination(); // Raise up to the old current pos + } + } + else { + // If a hop was done and Z hasn't changed, undo the Z hop + if (hop_amount && NEAR(hop_height, destination[Z_AXIS])) { + current_position[Z_AXIS] += hop_amount; // Pretend current pos is higher. Next move lowers Z. + SYNC_PLAN_POSITION_KINEMATIC(); // Set the planner to the new position + prepare_move_to_destination(); // Lower to the old current pos + hop_amount = 0.0; + } + + // A retract multiplier has been added here to get faster swap recovery + feedrate_mm_s = swapping ? swap_retract_recover_feedrate_mm_s : retract_recover_feedrate_mm_s; + + const float move_e = swapping ? swap_retract_length + swap_retract_recover_length : retract_length + retract_recover_length; + current_position[E_AXIS] -= move_e / volumetric_multiplier[active_extruder]; + sync_plan_position_e(); + + prepare_move_to_destination(); // Recover E + } + + // Restore flow and feedrate + flow_percentage[active_extruder] = old_flow; + feedrate_mm_s = old_feedrate_mm_s; + + // The active extruder is now retracted or recovered + retracted[active_extruder] = retracting; + + // If swap retract/recover then update the retracted_swap flag too + #if EXTRUDERS > 1 + if (swapping) retracted_swap[active_extruder] = retracting; + #endif + + /* // debugging + SERIAL_ECHOLNPAIR("retracting ", retracting); + SERIAL_ECHOLNPAIR("swapping ", swapping); + SERIAL_ECHOLNPAIR("active_extruder ", active_extruder); + for (uint8_t i = 0; i < EXTRUDERS; ++i) { + SERIAL_ECHOPAIR("retracted[", i); + SERIAL_ECHOLNPAIR("] ", retracted[i]); + SERIAL_ECHOPAIR("retracted_swap[", i); + SERIAL_ECHOLNPAIR("] ", retracted_swap[i]); + } + SERIAL_ECHOLNPAIR("current_position[z] ", current_position[Z_AXIS]); + SERIAL_ECHOLNPAIR("hop_amount ", hop_amount); + //*/ + + } // retract() + +#endif // FWRETRACT + +#if ENABLED(MIXING_EXTRUDER) + + void normalize_mix() { + float mix_total = 0.0; + for (uint8_t i = 0; i < MIXING_STEPPERS; i++) mix_total += RECIPROCAL(mixing_factor[i]); + // Scale all values if they don't add up to ~1.0 + if (!NEAR(mix_total, 1.0)) { + SERIAL_PROTOCOLLNPGM("Warning: Mix factors must add up to 1.0. Scaling."); + for (uint8_t i = 0; i < MIXING_STEPPERS; i++) mixing_factor[i] *= mix_total; + } + } + + #if ENABLED(DIRECT_MIXING_IN_G1) + // Get mixing parameters from the GCode + // The total "must" be 1.0 (but it will be normalized) + // If no mix factors are given, the old mix is preserved + void gcode_get_mix() { + const char* mixing_codes = "ABCDHI"; + byte mix_bits = 0; + for (uint8_t i = 0; i < MIXING_STEPPERS; i++) { + if (parser.seenval(mixing_codes[i])) { + SBI(mix_bits, i); + float v = parser.value_float(); + NOLESS(v, 0.0); + mixing_factor[i] = RECIPROCAL(v); + } + } + // If any mixing factors were included, clear the rest + // If none were included, preserve the last mix + if (mix_bits) { + for (uint8_t i = 0; i < MIXING_STEPPERS; i++) + if (!TEST(mix_bits, i)) mixing_factor[i] = 0.0; + normalize_mix(); + } + } + #endif + +#endif + +/** + * *************************************************************************** + * ***************************** G-CODE HANDLING ***************************** + * *************************************************************************** + */ + +/** + * Set XYZE destination and feedrate from the current GCode command + * + * - Set destination from included axis codes + * - Set to current for missing axis codes + * - Set the feedrate, if included + */ +void gcode_get_destination() { + LOOP_XYZE(i) { + if (parser.seen(axis_codes[i])) + destination[i] = parser.value_axis_units((AxisEnum)i) + (axis_relative_modes[i] || relative_mode ? current_position[i] : 0); + else + destination[i] = current_position[i]; + } + + if (parser.linearval('F') > 0.0) + feedrate_mm_s = MMM_TO_MMS(parser.value_feedrate()); + + #if ENABLED(PRINTCOUNTER) + if (!DEBUGGING(DRYRUN)) + print_job_timer.incFilamentUsed(destination[E_AXIS] - current_position[E_AXIS]); + #endif + + // Get ABCDHI mixing factors + #if ENABLED(MIXING_EXTRUDER) && ENABLED(DIRECT_MIXING_IN_G1) + gcode_get_mix(); + #endif +} + +#if ENABLED(HOST_KEEPALIVE_FEATURE) + + /** + * Output a "busy" message at regular intervals + * while the machine is not accepting commands. + */ + void host_keepalive() { + const millis_t ms = millis(); + if (host_keepalive_interval && busy_state != NOT_BUSY) { + if (PENDING(ms, next_busy_signal_ms)) return; + switch (busy_state) { + case IN_HANDLER: + case IN_PROCESS: + SERIAL_ECHO_START(); + SERIAL_ECHOLNPGM(MSG_BUSY_PROCESSING); + break; + case PAUSED_FOR_USER: + SERIAL_ECHO_START(); + SERIAL_ECHOLNPGM(MSG_BUSY_PAUSED_FOR_USER); + break; + case PAUSED_FOR_INPUT: + SERIAL_ECHO_START(); + SERIAL_ECHOLNPGM(MSG_BUSY_PAUSED_FOR_INPUT); + break; + default: + break; + } + } + next_busy_signal_ms = ms + host_keepalive_interval * 1000UL; + } + +#endif // HOST_KEEPALIVE_FEATURE + + +/************************************************** + ***************** GCode Handlers ***************** + **************************************************/ + +/** + * G0, G1: Coordinated movement of X Y Z E axes + */ +inline void gcode_G0_G1( + #if IS_SCARA + bool fast_move=false + #endif +) { + #if ENABLED(NO_MOTION_BEFORE_HOMING) + if (axis_unhomed_error()) return; + #endif + + if (IsRunning()) { + gcode_get_destination(); // For X Y Z E F + + #if ENABLED(FWRETRACT) + if (MIN_AUTORETRACT <= MAX_AUTORETRACT) { + // When M209 Autoretract is enabled, convert E-only moves to firmware retract/recover moves + if (autoretract_enabled && parser.seen('E') && !(parser.seen('X') || parser.seen('Y') || parser.seen('Z'))) { + const float echange = destination[E_AXIS] - current_position[E_AXIS]; + // Is this a retract or recover move? + if (WITHIN(FABS(echange), MIN_AUTORETRACT, MAX_AUTORETRACT) && retracted[active_extruder] == (echange > 0.0)) { + current_position[E_AXIS] = destination[E_AXIS]; // Hide a G1-based retract/recover from calculations + sync_plan_position_e(); // AND from the planner + return retract(echange < 0.0); // Firmware-based retract/recover (double-retract ignored) + } + } + } + #endif // FWRETRACT + + #if IS_SCARA + fast_move ? prepare_uninterpolated_move_to_destination() : prepare_move_to_destination(); + #else + prepare_move_to_destination(); + #endif + } +} + +/** + * G2: Clockwise Arc + * G3: Counterclockwise Arc + * + * This command has two forms: IJ-form and R-form. + * + * - I specifies an X offset. J specifies a Y offset. + * At least one of the IJ parameters is required. + * X and Y can be omitted to do a complete circle. + * The given XY is not error-checked. The arc ends + * based on the angle of the destination. + * Mixing I or J with R will throw an error. + * + * - R specifies the radius. X or Y is required. + * Omitting both X and Y will throw an error. + * X or Y must differ from the current XY. + * Mixing R with I or J will throw an error. + * + * - P specifies the number of full circles to do + * before the specified arc move. + * + * Examples: + * + * G2 I10 ; CW circle centered at X+10 + * G3 X20 Y12 R14 ; CCW circle with r=14 ending at X20 Y12 + */ +#if ENABLED(ARC_SUPPORT) + + inline void gcode_G2_G3(bool clockwise) { + #if ENABLED(NO_MOTION_BEFORE_HOMING) + if (axis_unhomed_error()) return; + #endif + + if (IsRunning()) { + + #if ENABLED(SF_ARC_FIX) + const bool relative_mode_backup = relative_mode; + relative_mode = true; + #endif + + gcode_get_destination(); + + #if ENABLED(SF_ARC_FIX) + relative_mode = relative_mode_backup; + #endif + + float arc_offset[2] = { 0.0, 0.0 }; + if (parser.seenval('R')) { + const float r = parser.value_linear_units(), + p1 = current_position[X_AXIS], q1 = current_position[Y_AXIS], + p2 = destination[X_AXIS], q2 = destination[Y_AXIS]; + if (r && (p2 != p1 || q2 != q1)) { + const float e = clockwise ^ (r < 0) ? -1 : 1, // clockwise -1/1, counterclockwise 1/-1 + dx = p2 - p1, dy = q2 - q1, // X and Y differences + d = HYPOT(dx, dy), // Linear distance between the points + h = SQRT(sq(r) - sq(d * 0.5)), // Distance to the arc pivot-point + mx = (p1 + p2) * 0.5, my = (q1 + q2) * 0.5, // Point between the two points + sx = -dy / d, sy = dx / d, // Slope of the perpendicular bisector + cx = mx + e * h * sx, cy = my + e * h * sy; // Pivot-point of the arc + arc_offset[0] = cx - p1; + arc_offset[1] = cy - q1; + } + } + else { + if (parser.seenval('I')) arc_offset[0] = parser.value_linear_units(); + if (parser.seenval('J')) arc_offset[1] = parser.value_linear_units(); + } + + if (arc_offset[0] || arc_offset[1]) { + + #if ENABLED(ARC_P_CIRCLES) + // P indicates number of circles to do + int8_t circles_to_do = parser.byteval('P'); + if (!WITHIN(circles_to_do, 0, 100)) { + SERIAL_ERROR_START(); + SERIAL_ERRORLNPGM(MSG_ERR_ARC_ARGS); + } + while (circles_to_do--) + plan_arc(current_position, arc_offset, clockwise); + #endif + + // Send the arc to the planner + plan_arc(destination, arc_offset, clockwise); + refresh_cmd_timeout(); + } + else { + // Bad arguments + SERIAL_ERROR_START(); + SERIAL_ERRORLNPGM(MSG_ERR_ARC_ARGS); + } + } + } + +#endif // ARC_SUPPORT + +void dwell(millis_t time) { + refresh_cmd_timeout(); + time += previous_cmd_ms; + while (PENDING(millis(), time)) idle(); +} + +/** + * G4: Dwell S or P + */ +inline void gcode_G4() { + millis_t dwell_ms = 0; + + if (parser.seenval('P')) dwell_ms = parser.value_millis(); // milliseconds to wait + if (parser.seenval('S')) dwell_ms = parser.value_millis_from_seconds(); // seconds to wait + + stepper.synchronize(); + + if (!lcd_hasstatus()) LCD_MESSAGEPGM(MSG_DWELL); + + dwell(dwell_ms); +} + +#if ENABLED(BEZIER_CURVE_SUPPORT) + + /** + * Parameters interpreted according to: + * http://linuxcnc.org/docs/2.6/html/gcode/gcode.html#sec:G5-Cubic-Spline + * However I, J omission is not supported at this point; all + * parameters can be omitted and default to zero. + */ + + /** + * G5: Cubic B-spline + */ + inline void gcode_G5() { + #if ENABLED(NO_MOTION_BEFORE_HOMING) + if (axis_unhomed_error()) return; + #endif + + if (IsRunning()) { + + #if ENABLED(CNC_WORKSPACE_PLANES) + if (workspace_plane != PLANE_XY) { + SERIAL_ERROR_START(); + SERIAL_ERRORLNPGM(MSG_ERR_BAD_PLANE_MODE); + return; + } + #endif + + gcode_get_destination(); + + const float offset[] = { + parser.linearval('I'), + parser.linearval('J'), + parser.linearval('P'), + parser.linearval('Q') + }; + + plan_cubic_move(offset); + } + } + +#endif // BEZIER_CURVE_SUPPORT + +#if ENABLED(FWRETRACT) + + /** + * G10 - Retract filament according to settings of M207 + */ + inline void gcode_G10() { + #if EXTRUDERS > 1 + const bool rs = parser.boolval('S'); + retracted_swap[active_extruder] = rs; // Use 'S' for swap, default to false + #endif + retract(true + #if EXTRUDERS > 1 + , rs + #endif + ); + } + + /** + * G11 - Recover filament according to settings of M208 + */ + inline void gcode_G11() { retract(false); } + +#endif // FWRETRACT + +#if ENABLED(NOZZLE_CLEAN_FEATURE) + /** + * G12: Clean the nozzle + */ + inline void gcode_G12() { + // Don't allow nozzle cleaning without homing first + if (axis_unhomed_error()) return; + + 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); + + Nozzle::clean(pattern, strokes, radius, objects); + } +#endif + +#if ENABLED(CNC_WORKSPACE_PLANES) + + void report_workspace_plane() { + SERIAL_ECHO_START(); + SERIAL_ECHOPGM("Workspace Plane "); + serialprintPGM(workspace_plane == PLANE_YZ ? PSTR("YZ\n") : workspace_plane == PLANE_ZX ? PSTR("ZX\n") : PSTR("XY\n")); + } + + /** + * G17: Select Plane XY + * G18: Select Plane ZX + * G19: Select Plane YZ + */ + inline void gcode_G17() { workspace_plane = PLANE_XY; } + inline void gcode_G18() { workspace_plane = PLANE_ZX; } + inline void gcode_G19() { workspace_plane = PLANE_YZ; } + +#endif // CNC_WORKSPACE_PLANES + +#if ENABLED(INCH_MODE_SUPPORT) + /** + * G20: Set input mode to inches + */ + inline void gcode_G20() { parser.set_input_linear_units(LINEARUNIT_INCH); } + + /** + * G21: Set input mode to millimeters + */ + inline void gcode_G21() { parser.set_input_linear_units(LINEARUNIT_MM); } +#endif + +#if ENABLED(NOZZLE_PARK_FEATURE) + /** + * G27: Park the nozzle + */ + inline void gcode_G27() { + // Don't allow nozzle parking without homing first + if (axis_unhomed_error()) return; + Nozzle::park(parser.ushortval('P')); + } +#endif // NOZZLE_PARK_FEATURE + +#if ENABLED(QUICK_HOME) + + static void quick_home_xy() { + + // Pretend the current position is 0,0 + current_position[X_AXIS] = current_position[Y_AXIS] = 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 float mlx = max_length(X_AXIS), + mly = max_length(Y_AXIS), + mlratio = mlx > mly ? mly / mlx : mlx / mly, + fr_mm_s = min(homing_feedrate(X_AXIS), homing_feedrate(Y_AXIS)) * SQRT(sq(mlratio) + 1.0); + + do_blocking_move_to_xy(1.5 * mlx * x_axis_home_dir, 1.5 * mly * home_dir(Y_AXIS), fr_mm_s); + endstops.hit_on_purpose(); // clear endstop hit flags + current_position[X_AXIS] = current_position[Y_AXIS] = 0.0; + } + +#endif // QUICK_HOME + +#if ENABLED(DEBUG_LEVELING_FEATURE) + + void log_machine_info() { + SERIAL_ECHOPGM("Machine Type: "); + #if ENABLED(DELTA) + SERIAL_ECHOLNPGM("Delta"); + #elif IS_SCARA + SERIAL_ECHOLNPGM("SCARA"); + #elif IS_CORE + SERIAL_ECHOLNPGM("Core"); + #else + SERIAL_ECHOLNPGM("Cartesian"); + #endif + + SERIAL_ECHOPGM("Probe: "); + #if ENABLED(PROBE_MANUALLY) + SERIAL_ECHOLNPGM("PROBE_MANUALLY"); + #elif ENABLED(FIX_MOUNTED_PROBE) + SERIAL_ECHOLNPGM("FIX_MOUNTED_PROBE"); + #elif ENABLED(BLTOUCH) + SERIAL_ECHOLNPGM("BLTOUCH"); + #elif HAS_Z_SERVO_ENDSTOP + SERIAL_ECHOLNPGM("SERVO PROBE"); + #elif ENABLED(Z_PROBE_SLED) + SERIAL_ECHOLNPGM("Z_PROBE_SLED"); + #elif ENABLED(Z_PROBE_ALLEN_KEY) + SERIAL_ECHOLNPGM("Z_PROBE_ALLEN_KEY"); + #else + SERIAL_ECHOLNPGM("NONE"); + #endif + + #if HAS_BED_PROBE + SERIAL_ECHOPAIR("Probe Offset X:", X_PROBE_OFFSET_FROM_EXTRUDER); + SERIAL_ECHOPAIR(" Y:", Y_PROBE_OFFSET_FROM_EXTRUDER); + SERIAL_ECHOPAIR(" Z:", zprobe_zoffset); + #if X_PROBE_OFFSET_FROM_EXTRUDER > 0 + SERIAL_ECHOPGM(" (Right"); + #elif X_PROBE_OFFSET_FROM_EXTRUDER < 0 + SERIAL_ECHOPGM(" (Left"); + #elif Y_PROBE_OFFSET_FROM_EXTRUDER != 0 + SERIAL_ECHOPGM(" (Middle"); + #else + SERIAL_ECHOPGM(" (Aligned With"); + #endif + #if Y_PROBE_OFFSET_FROM_EXTRUDER > 0 + SERIAL_ECHOPGM("-Back"); + #elif Y_PROBE_OFFSET_FROM_EXTRUDER < 0 + SERIAL_ECHOPGM("-Front"); + #elif X_PROBE_OFFSET_FROM_EXTRUDER != 0 + SERIAL_ECHOPGM("-Center"); + #endif + if (zprobe_zoffset < 0) + SERIAL_ECHOPGM(" & Below"); + else if (zprobe_zoffset > 0) + SERIAL_ECHOPGM(" & Above"); + else + SERIAL_ECHOPGM(" & Same Z as"); + SERIAL_ECHOLNPGM(" Nozzle)"); + #endif + + #if HAS_ABL + SERIAL_ECHOPGM("Auto Bed Leveling: "); + #if ENABLED(AUTO_BED_LEVELING_LINEAR) + SERIAL_ECHOPGM("LINEAR"); + #elif ENABLED(AUTO_BED_LEVELING_BILINEAR) + SERIAL_ECHOPGM("BILINEAR"); + #elif ENABLED(AUTO_BED_LEVELING_3POINT) + SERIAL_ECHOPGM("3POINT"); + #elif ENABLED(AUTO_BED_LEVELING_UBL) + SERIAL_ECHOPGM("UBL"); + #endif + if (leveling_is_active()) { + SERIAL_ECHOLNPGM(" (enabled)"); + #if ABL_PLANAR + const float diff[XYZ] = { + stepper.get_axis_position_mm(X_AXIS) - current_position[X_AXIS], + stepper.get_axis_position_mm(Y_AXIS) - current_position[Y_AXIS], + stepper.get_axis_position_mm(Z_AXIS) - current_position[Z_AXIS] + }; + SERIAL_ECHOPGM("ABL Adjustment X"); + if (diff[X_AXIS] > 0) SERIAL_CHAR('+'); + SERIAL_ECHO(diff[X_AXIS]); + SERIAL_ECHOPGM(" Y"); + if (diff[Y_AXIS] > 0) SERIAL_CHAR('+'); + SERIAL_ECHO(diff[Y_AXIS]); + SERIAL_ECHOPGM(" Z"); + if (diff[Z_AXIS] > 0) SERIAL_CHAR('+'); + SERIAL_ECHO(diff[Z_AXIS]); + #elif ENABLED(AUTO_BED_LEVELING_UBL) + SERIAL_ECHOPAIR("UBL Adjustment Z", stepper.get_axis_position_mm(Z_AXIS) - current_position[Z_AXIS]); + #elif ENABLED(AUTO_BED_LEVELING_BILINEAR) + SERIAL_ECHOPAIR("ABL Adjustment Z", bilinear_z_offset(current_position)); + #endif + } + else + SERIAL_ECHOLNPGM(" (disabled)"); + + SERIAL_EOL(); + + #elif ENABLED(MESH_BED_LEVELING) + + SERIAL_ECHOPGM("Mesh Bed Leveling"); + if (leveling_is_active()) { + float lz = current_position[Z_AXIS]; + planner.apply_leveling(current_position[X_AXIS], current_position[Y_AXIS], lz); + SERIAL_ECHOLNPGM(" (enabled)"); + SERIAL_ECHOPAIR("MBL Adjustment Z", lz); + } + else + SERIAL_ECHOPGM(" (disabled)"); + + SERIAL_EOL(); + + #endif // MESH_BED_LEVELING + } + +#endif // DEBUG_LEVELING_FEATURE + +#if ENABLED(DELTA) + + /** + * A delta can only safely home all axes at the same time + * This is like quick_home_xy() but for 3 towers. + */ + inline bool home_delta() { + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS(">>> home_delta", current_position); + #endif + // Init the current position of all carriages to 0,0,0 + ZERO(current_position); + sync_plan_position(); + + // Move all carriages together linearly until an endstop is hit. + current_position[X_AXIS] = current_position[Y_AXIS] = current_position[Z_AXIS] = (DELTA_HEIGHT + home_offset[Z_AXIS] + 10); + feedrate_mm_s = homing_feedrate(X_AXIS); + line_to_current_position(); + stepper.synchronize(); + + // If an endstop was not hit, then damage can occur if homing is continued. + // This can occur if the delta height (DELTA_HEIGHT + home_offset[Z_AXIS]) is + // not set correctly. + if (!(Endstops::endstop_hit_bits & (_BV(X_MAX) | _BV(Y_MAX) | _BV(Z_MAX)))) { + LCD_MESSAGEPGM(MSG_ERR_HOMING_FAILED); + SERIAL_ERROR_START(); + SERIAL_ERRORLNPGM(MSG_ERR_HOMING_FAILED); + return false; + } + + endstops.hit_on_purpose(); // clear endstop hit flags + + // At least one carriage has reached the top. + // Now re-home each carriage separately. + HOMEAXIS(A); + HOMEAXIS(B); + HOMEAXIS(C); + + // Set all carriages to their home positions + // Do this here all at once for Delta, because + // XYZ isn't ABC. Applying this per-tower would + // give the impression that they are the same. + LOOP_XYZ(i) set_axis_is_at_home((AxisEnum)i); + + SYNC_PLAN_POSITION_KINEMATIC(); + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("<<< home_delta", current_position); + #endif + + return true; + } + +#endif // DELTA + +#if ENABLED(Z_SAFE_HOMING) + + inline void home_z_safely() { + + // Disallow Z homing if X or Y are unknown + if (!axis_known_position[X_AXIS] || !axis_known_position[Y_AXIS]) { + LCD_MESSAGEPGM(MSG_ERR_Z_HOMING); + SERIAL_ECHO_START(); + SERIAL_ECHOLNPGM(MSG_ERR_Z_HOMING); + return; + } + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("Z_SAFE_HOMING >>>"); + #endif + + SYNC_PLAN_POSITION_KINEMATIC(); + + /** + * Move the Z probe (or just the nozzle) to the safe homing point + */ + destination[X_AXIS] = LOGICAL_X_POSITION(Z_SAFE_HOMING_X_POINT); + destination[Y_AXIS] = LOGICAL_Y_POSITION(Z_SAFE_HOMING_Y_POINT); + destination[Z_AXIS] = current_position[Z_AXIS]; // Z is already at the right height + + #if HOMING_Z_WITH_PROBE + destination[X_AXIS] -= X_PROBE_OFFSET_FROM_EXTRUDER; + destination[Y_AXIS] -= Y_PROBE_OFFSET_FROM_EXTRUDER; + #endif + + if (position_is_reachable_xy(destination[X_AXIS], destination[Y_AXIS])) { + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("Z_SAFE_HOMING", destination); + #endif + + // This causes the carriage on Dual X to unpark + #if ENABLED(DUAL_X_CARRIAGE) + active_extruder_parked = false; + #endif + + do_blocking_move_to_xy(destination[X_AXIS], destination[Y_AXIS]); + HOMEAXIS(Z); + } + else { + LCD_MESSAGEPGM(MSG_ZPROBE_OUT); + SERIAL_ECHO_START(); + SERIAL_ECHOLNPGM(MSG_ZPROBE_OUT); + } + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("<<< Z_SAFE_HOMING"); + #endif + } + +#endif // Z_SAFE_HOMING + +#if ENABLED(PROBE_MANUALLY) + bool g29_in_progress = false; +#else + constexpr bool g29_in_progress = false; +#endif + +/** + * G28: Home all axes according to settings + * + * Parameters + * + * None Home to all axes with no parameters. + * With QUICK_HOME enabled XY will home together, then Z. + * + * Cartesian parameters + * + * X Home to the X endstop + * Y Home to the Y endstop + * Z Home to the Z endstop + * + */ +inline void gcode_G28(const bool always_home_all) { + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOLNPGM(">>> gcode_G28"); + log_machine_info(); + } + #endif + + // Wait for planner moves to finish! + stepper.synchronize(); + + // Cancel the active G29 session + #if ENABLED(PROBE_MANUALLY) + g29_in_progress = false; + #endif + + // Disable the leveling matrix before homing + #if HAS_LEVELING + #if ENABLED(AUTO_BED_LEVELING_UBL) + const bool ubl_state_at_entry = leveling_is_active(); + #endif + set_bed_leveling_enabled(false); + #endif + + #if ENABLED(CNC_WORKSPACE_PLANES) + workspace_plane = PLANE_XY; + #endif + + // Always home with tool 0 active + #if HOTENDS > 1 + const uint8_t old_tool_index = active_extruder; + tool_change(0, 0, true); + #endif + + #if ENABLED(DUAL_X_CARRIAGE) || ENABLED(DUAL_NOZZLE_DUPLICATION_MODE) + extruder_duplication_enabled = false; + #endif + + setup_for_endstop_or_probe_move(); + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("> endstops.enable(true)"); + #endif + endstops.enable(true); // Enable endstops for next homing move + + #if ENABLED(DELTA) + + home_delta(); + UNUSED(always_home_all); + + #else // NOT DELTA + + const bool homeX = always_home_all || parser.seen('X'), + homeY = always_home_all || parser.seen('Y'), + homeZ = always_home_all || parser.seen('Z'), + home_all = (!homeX && !homeY && !homeZ) || (homeX && homeY && homeZ); + + set_destination_to_current(); + + #if Z_HOME_DIR > 0 // If homing away from BED do Z first + + if (home_all || homeZ) { + HOMEAXIS(Z); + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("> HOMEAXIS(Z)", current_position); + #endif + } + + #else + + if (home_all || homeX || homeY) { + // Raise Z before homing any other axes and z is not already high enough (never lower z) + destination[Z_AXIS] = LOGICAL_Z_POSITION(Z_HOMING_HEIGHT); + if (destination[Z_AXIS] > current_position[Z_AXIS]) { + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) + SERIAL_ECHOLNPAIR("Raise Z (before homing) to ", destination[Z_AXIS]); + #endif + + do_blocking_move_to_z(destination[Z_AXIS]); + } + } + + #endif + + #if ENABLED(QUICK_HOME) + + if (home_all || (homeX && homeY)) quick_home_xy(); + + #endif + + #if ENABLED(HOME_Y_BEFORE_X) + + // Home Y + if (home_all || homeY) { + HOMEAXIS(Y); + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("> homeY", current_position); + #endif + } + + #endif + + // Home X + if (home_all || homeX) { + + #if ENABLED(DUAL_X_CARRIAGE) + + // Always home the 2nd (right) extruder first + active_extruder = 1; + HOMEAXIS(X); + + // Remember this extruder's position for later tool change + inactive_extruder_x_pos = RAW_X_POSITION(current_position[X_AXIS]); + + // Home the 1st (left) extruder + active_extruder = 0; + HOMEAXIS(X); + + // Consider the active extruder to be parked + COPY(raised_parked_position, current_position); + delayed_move_time = 0; + active_extruder_parked = true; + + #else + + HOMEAXIS(X); + + #endif + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("> homeX", current_position); + #endif + } + + #if DISABLED(HOME_Y_BEFORE_X) + // Home Y + if (home_all || homeY) { + HOMEAXIS(Y); + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("> homeY", current_position); + #endif + } + #endif + + // Home Z last if homing towards the bed + #if Z_HOME_DIR < 0 + if (home_all || homeZ) { + #if ENABLED(Z_SAFE_HOMING) + home_z_safely(); + #else + HOMEAXIS(Z); + #endif + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("> (home_all || homeZ) > final", current_position); + #endif + } // home_all || homeZ + #endif // Z_HOME_DIR < 0 + + SYNC_PLAN_POSITION_KINEMATIC(); + + #endif // !DELTA (gcode_G28) + + endstops.not_homing(); + + #if ENABLED(DELTA) && ENABLED(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 ENABLED(AUTO_BED_LEVELING_UBL) + set_bed_leveling_enabled(ubl_state_at_entry); + #endif + + clean_up_after_endstop_or_probe_move(); + + // Restore the active tool after homing + #if HOTENDS > 1 + tool_change(old_tool_index, 0, + #if ENABLED(PARKING_EXTRUDER) + false // fetch the previous toolhead + #else + true + #endif + ); + #endif + + lcd_refresh(); + + report_current_position(); + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("<<< gcode_G28"); + #endif +} // G28 + +void home_all_axes() { gcode_G28(true); } + +#if HAS_PROBING_PROCEDURE + + void out_of_range_error(const char* p_edge) { + SERIAL_PROTOCOLPGM("?Probe "); + serialprintPGM(p_edge); + SERIAL_PROTOCOLLNPGM(" position out of range."); + } + +#endif + +#if ENABLED(MESH_BED_LEVELING) || ENABLED(PROBE_MANUALLY) + + #if ENABLED(PROBE_MANUALLY) && ENABLED(LCD_BED_LEVELING) + extern bool lcd_wait_for_move; + #endif + + inline void _manual_goto_xy(const float &x, const float &y) { + const float old_feedrate_mm_s = feedrate_mm_s; + #if MANUAL_PROBE_HEIGHT > 0 + const float prev_z = current_position[Z_AXIS]; + feedrate_mm_s = homing_feedrate(Z_AXIS); + current_position[Z_AXIS] = LOGICAL_Z_POSITION(MANUAL_PROBE_HEIGHT); + line_to_current_position(); + #endif + + feedrate_mm_s = MMM_TO_MMS(XY_PROBE_SPEED); + current_position[X_AXIS] = LOGICAL_X_POSITION(x); + current_position[Y_AXIS] = LOGICAL_Y_POSITION(y); + line_to_current_position(); + + #if MANUAL_PROBE_HEIGHT > 0 + feedrate_mm_s = homing_feedrate(Z_AXIS); + current_position[Z_AXIS] = prev_z; // move back to the previous Z. + line_to_current_position(); + #endif + + feedrate_mm_s = old_feedrate_mm_s; + stepper.synchronize(); + + #if ENABLED(PROBE_MANUALLY) && ENABLED(LCD_BED_LEVELING) + lcd_wait_for_move = false; + #endif + } + +#endif + +#if ENABLED(MESH_BED_LEVELING) + + // Save 130 bytes with non-duplication of PSTR + void echo_not_entered() { SERIAL_PROTOCOLLNPGM(" not entered."); } + + void mbl_mesh_report() { + SERIAL_PROTOCOLLNPGM("Num X,Y: " STRINGIFY(GRID_MAX_POINTS_X) "," STRINGIFY(GRID_MAX_POINTS_Y)); + SERIAL_PROTOCOLPGM("Z offset: "); SERIAL_PROTOCOL_F(mbl.z_offset, 5); + SERIAL_PROTOCOLLNPGM("\nMeasured points:"); + print_2d_array(GRID_MAX_POINTS_X, GRID_MAX_POINTS_Y, 5, + [](const uint8_t ix, const uint8_t iy) { return mbl.z_values[ix][iy]; } + ); + } + + void mesh_probing_done() { + mbl.set_has_mesh(true); + home_all_axes(); + set_bed_leveling_enabled(true); + #if ENABLED(MESH_G28_REST_ORIGIN) + current_position[Z_AXIS] = LOGICAL_Z_POSITION(Z_MIN_POS); + set_destination_to_current(); + line_to_destination(homing_feedrate(Z_AXIS)); + stepper.synchronize(); + #endif + } + + /** + * G29: Mesh-based Z probe, probes a grid and produces a + * mesh to compensate for variable bed height + * + * Parameters With MESH_BED_LEVELING: + * + * S0 Produce a mesh report + * S1 Start probing mesh points + * S2 Probe the next mesh point + * S3 Xn Yn 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 + * + * The S0 report the points as below + * + * +----> X-axis 1-n + * | + * | + * v Y-axis 1-n + * + */ + inline void gcode_G29() { + + static int mbl_probe_index = -1; + #if HAS_SOFTWARE_ENDSTOPS + static bool enable_soft_endstops; + #endif + + const MeshLevelingState state = (MeshLevelingState)parser.byteval('S', (int8_t)MeshReport); + if (!WITHIN(state, 0, 5)) { + SERIAL_PROTOCOLLNPGM("S out of range (0-5)."); + return; + } + + int8_t px, py; + + switch (state) { + case MeshReport: + if (leveling_is_valid()) { + SERIAL_PROTOCOLLNPAIR("State: ", leveling_is_active() ? MSG_ON : MSG_OFF); + mbl_mesh_report(); + } + else + SERIAL_PROTOCOLLNPGM("Mesh bed leveling has no data."); + break; + + case MeshStart: + mbl.reset(); + mbl_probe_index = 0; + enqueue_and_echo_commands_P(PSTR("G28\nG29 S2")); + break; + + case MeshNext: + if (mbl_probe_index < 0) { + SERIAL_PROTOCOLLNPGM("Start mesh probing with \"G29 S1\" first."); + return; + } + // For each G29 S2... + if (mbl_probe_index == 0) { + #if HAS_SOFTWARE_ENDSTOPS + // For the initial G29 S2 save software endstop state + enable_soft_endstops = soft_endstops_enabled; + #endif + } + else { + // For G29 S2 after adjusting Z. + mbl.set_zigzag_z(mbl_probe_index - 1, current_position[Z_AXIS]); + #if HAS_SOFTWARE_ENDSTOPS + soft_endstops_enabled = enable_soft_endstops; + #endif + } + // If there's another point to sample, move there with optional lift. + if (mbl_probe_index < GRID_MAX_POINTS) { + mbl.zigzag(mbl_probe_index, px, py); + _manual_goto_xy(mbl.index_to_xpos[px], mbl.index_to_ypos[py]); + + #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 + + mbl_probe_index++; + } + else { + // One last "return to the bed" (as originally coded) at completion + current_position[Z_AXIS] = LOGICAL_Z_POSITION(Z_MIN_POS) + MANUAL_PROBE_HEIGHT; + line_to_current_position(); + stepper.synchronize(); + + // After recording the last point, activate home and activate + mbl_probe_index = -1; + SERIAL_PROTOCOLLNPGM("Mesh probing done."); + BUZZ(100, 659); + BUZZ(100, 698); + mesh_probing_done(); + } + break; + + case MeshSet: + if (parser.seenval('X')) { + px = parser.value_int() - 1; + if (!WITHIN(px, 0, GRID_MAX_POINTS_X - 1)) { + SERIAL_PROTOCOLLNPGM("X out of range (1-" STRINGIFY(GRID_MAX_POINTS_X) ")."); + return; + } + } + else { + SERIAL_CHAR('X'); echo_not_entered(); + return; + } + + if (parser.seenval('Y')) { + py = parser.value_int() - 1; + if (!WITHIN(py, 0, GRID_MAX_POINTS_Y - 1)) { + SERIAL_PROTOCOLLNPGM("Y out of range (1-" STRINGIFY(GRID_MAX_POINTS_Y) ")."); + return; + } + } + else { + SERIAL_CHAR('Y'); echo_not_entered(); + return; + } + + if (parser.seenval('Z')) { + mbl.z_values[px][py] = parser.value_linear_units(); + } + else { + SERIAL_CHAR('Z'); echo_not_entered(); + return; + } + break; + + case MeshSetZOffset: + if (parser.seenval('Z')) { + mbl.z_offset = parser.value_linear_units(); + } + else { + SERIAL_CHAR('Z'); echo_not_entered(); + return; + } + break; + + case MeshReset: + reset_bed_level(); + break; + + } // switch(state) + + report_current_position(); + } + +#elif HAS_ABL && DISABLED(AUTO_BED_LEVELING_UBL) + + #if ABL_GRID + #if ENABLED(PROBE_Y_FIRST) + #define PR_OUTER_VAR xCount + #define PR_OUTER_END abl_grid_points_x + #define PR_INNER_VAR yCount + #define PR_INNER_END abl_grid_points_y + #else + #define PR_OUTER_VAR yCount + #define PR_OUTER_END abl_grid_points_y + #define PR_INNER_VAR xCount + #define PR_INNER_END abl_grid_points_x + #endif + #endif + + /** + * G29: Detailed Z probe, probes the bed at 3 or more points. + * Will fail if the printer has not been homed with G28. + * + * Enhanced G29 Auto Bed Leveling Probe Routine + * + * D Dry-Run mode. Just evaluate the bed Topology - Don't apply + * or alter the bed level data. Useful to check the topology + * after a first run of G29. + * + * J Jettison current bed leveling data + * + * V Set the verbose level (0-4). Example: "G29 V3" + * + * Parameters With LINEAR leveling only: + * + * P Set the size of the grid that will be probed (P x P points). + * Example: "G29 P4" + * + * X Set the X size of the grid that will be probed (X x Y points). + * Example: "G29 X7 Y5" + * + * Y Set the Y size of the grid that will be probed (X x Y points). + * + * T Generate a Bed Topology Report. Example: "G29 P5 T" for a detailed report. + * This is useful for manual bed leveling and finding flaws in the bed (to + * assist with part placement). + * Not supported by non-linear delta printer bed leveling. + * + * Parameters With LINEAR and BILINEAR leveling only: + * + * S Set the XY travel speed between probe points (in units/min) + * + * F Set the Front limit of the probing grid + * B Set the Back limit of the probing grid + * L Set the Left limit of the probing grid + * R Set the Right limit of the probing grid + * + * Parameters with DEBUG_LEVELING_FEATURE only: + * + * C Make a totally fake grid with no actual probing. + * For use in testing when no probing is possible. + * + * Parameters with BILINEAR leveling only: + * + * Z Supply an additional Z probe offset + * + * Extra parameters with PROBE_MANUALLY: + * + * To do manual probing simply repeat G29 until the procedure is complete. + * The first G29 accepts parameters. 'G29 Q' for status, 'G29 A' to abort. + * + * Q Query leveling and G29 state + * + * A Abort current leveling procedure + * + * Extra parameters with BILINEAR only: + * + * W Write a mesh point. (If G29 is idle.) + * I X index for mesh point + * J Y index for mesh point + * X X for mesh point, overrides I + * Y Y for mesh point, overrides J + * Z Z for mesh point. Otherwise, raw current Z. + * + * Without PROBE_MANUALLY: + * + * 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. + * + */ + inline void gcode_G29() { + + // G29 Q is also available if debugging + #if ENABLED(DEBUG_LEVELING_FEATURE) + const bool query = parser.seen('Q'); + const uint8_t old_debug_flags = marlin_debug_flags; + if (query) marlin_debug_flags |= DEBUG_LEVELING; + if (DEBUGGING(LEVELING)) { + DEBUG_POS(">>> gcode_G29", current_position); + log_machine_info(); + } + marlin_debug_flags = old_debug_flags; + #if DISABLED(PROBE_MANUALLY) + if (query) return; + #endif + #endif + + #if ENABLED(PROBE_MANUALLY) + const bool seenA = parser.seen('A'), seenQ = parser.seen('Q'), no_action = seenA || seenQ; + #endif + + #if ENABLED(DEBUG_LEVELING_FEATURE) && DISABLED(PROBE_MANUALLY) + const bool faux = parser.boolval('C'); + #elif ENABLED(PROBE_MANUALLY) + const bool faux = no_action; + #else + bool constexpr faux = false; + #endif + + // Don't allow auto-leveling without homing first + if (axis_unhomed_error()) return; + + // Define local vars 'static' for manual probing, 'auto' otherwise + #if ENABLED(PROBE_MANUALLY) + #define ABL_VAR static + #else + #define ABL_VAR + #endif + + ABL_VAR int verbose_level; + ABL_VAR float xProbe, yProbe, measured_z; + ABL_VAR bool dryrun, abl_should_enable; + + #if ENABLED(PROBE_MANUALLY) || ENABLED(AUTO_BED_LEVELING_LINEAR) + ABL_VAR int abl_probe_index; + #endif + + #if HAS_SOFTWARE_ENDSTOPS && ENABLED(PROBE_MANUALLY) + ABL_VAR bool enable_soft_endstops = true; + #endif + + #if ABL_GRID + + #if ENABLED(PROBE_MANUALLY) + ABL_VAR uint8_t PR_OUTER_VAR; + ABL_VAR int8_t PR_INNER_VAR; + #endif + + ABL_VAR int left_probe_bed_position, right_probe_bed_position, front_probe_bed_position, back_probe_bed_position; + ABL_VAR float xGridSpacing = 0, yGridSpacing = 0; + + #if ENABLED(AUTO_BED_LEVELING_LINEAR) + ABL_VAR uint8_t abl_grid_points_x = GRID_MAX_POINTS_X, + abl_grid_points_y = GRID_MAX_POINTS_Y; + ABL_VAR bool do_topography_map; + #else // Bilinear + uint8_t constexpr abl_grid_points_x = GRID_MAX_POINTS_X, + abl_grid_points_y = GRID_MAX_POINTS_Y; + #endif + + #if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(PROBE_MANUALLY) + #if ENABLED(AUTO_BED_LEVELING_LINEAR) + ABL_VAR int abl2; + #else // Bilinear + int constexpr abl2 = GRID_MAX_POINTS; + #endif + #endif + + #if ENABLED(AUTO_BED_LEVELING_BILINEAR) + + ABL_VAR float zoffset; + + #elif ENABLED(AUTO_BED_LEVELING_LINEAR) + + ABL_VAR int indexIntoAB[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y]; + + ABL_VAR float eqnAMatrix[GRID_MAX_POINTS * 3], // "A" matrix of the linear system of equations + eqnBVector[GRID_MAX_POINTS], // "B" vector of Z points + mean; + #endif + + #elif ENABLED(AUTO_BED_LEVELING_3POINT) + + int constexpr abl2 = 3; + + // Probe at 3 arbitrary points + ABL_VAR vector_3 points[3] = { + vector_3(ABL_PROBE_PT_1_X, ABL_PROBE_PT_1_Y, 0), + vector_3(ABL_PROBE_PT_2_X, ABL_PROBE_PT_2_Y, 0), + vector_3(ABL_PROBE_PT_3_X, ABL_PROBE_PT_3_Y, 0) + }; + + #endif // AUTO_BED_LEVELING_3POINT + + #if ENABLED(AUTO_BED_LEVELING_LINEAR) + struct linear_fit_data lsf_results; + incremental_LSF_reset(&lsf_results); + #endif + + /** + * On the initial G29 fetch command parameters. + */ + if (!g29_in_progress) { + + #if ENABLED(PROBE_MANUALLY) || ENABLED(AUTO_BED_LEVELING_LINEAR) + abl_probe_index = -1; + #endif + + abl_should_enable = leveling_is_active(); + + #if ENABLED(AUTO_BED_LEVELING_BILINEAR) + + if (parser.seen('W')) { + if (!leveling_is_valid()) { + SERIAL_ERROR_START(); + SERIAL_ERRORLNPGM("No bilinear grid"); + return; + } + + const float z = parser.floatval('Z', RAW_CURRENT_POSITION(Z)); + if (!WITHIN(z, -10, 10)) { + SERIAL_ERROR_START(); + SERIAL_ERRORLNPGM("Bad Z value"); + return; + } + + const float x = parser.floatval('X', NAN), + y = parser.floatval('Y', NAN); + int8_t i = parser.byteval('I', -1), + j = parser.byteval('J', -1); + + if (!isnan(x) && !isnan(y)) { + // Get nearest i / j from x / y + i = (x - LOGICAL_X_POSITION(bilinear_start[X_AXIS]) + 0.5 * xGridSpacing) / xGridSpacing; + j = (y - LOGICAL_Y_POSITION(bilinear_start[Y_AXIS]) + 0.5 * yGridSpacing) / yGridSpacing; + i = constrain(i, 0, GRID_MAX_POINTS_X - 1); + j = constrain(j, 0, GRID_MAX_POINTS_Y - 1); + } + 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] = z; + #if ENABLED(ABL_BILINEAR_SUBDIVISION) + bed_level_virt_interpolate(); + #endif + set_bed_leveling_enabled(abl_should_enable); + } + return; + } // parser.seen('W') + + #endif + + #if HAS_LEVELING + + // Jettison bed leveling data + if (parser.seen('J')) { + reset_bed_level(); + return; + } + + #endif + + verbose_level = parser.intval('V'); + if (!WITHIN(verbose_level, 0, 4)) { + SERIAL_PROTOCOLLNPGM("?(V)erbose level is implausible (0-4)."); + return; + } + + dryrun = parser.boolval('D') + #if ENABLED(PROBE_MANUALLY) + || no_action + #endif + ; + + #if ENABLED(AUTO_BED_LEVELING_LINEAR) + + do_topography_map = verbose_level > 2 || parser.boolval('T'); + + // X and Y specify points in each direction, overriding the default + // These values may be saved with the completed mesh + abl_grid_points_x = parser.intval('X', GRID_MAX_POINTS_X); + abl_grid_points_y = parser.intval('Y', GRID_MAX_POINTS_Y); + if (parser.seenval('P')) abl_grid_points_x = abl_grid_points_y = parser.value_int(); + + if (abl_grid_points_x < 2 || abl_grid_points_y < 2) { + SERIAL_PROTOCOLLNPGM("?Number of probe points is implausible (2 minimum)."); + return; + } + + abl2 = abl_grid_points_x * abl_grid_points_y; + + #elif ENABLED(AUTO_BED_LEVELING_BILINEAR) + + zoffset = parser.linearval('Z'); + + #endif + + #if ABL_GRID + + xy_probe_feedrate_mm_s = MMM_TO_MMS(parser.linearval('S', XY_PROBE_SPEED)); + + left_probe_bed_position = (int)parser.linearval('L', LOGICAL_X_POSITION(LEFT_PROBE_BED_POSITION)); + right_probe_bed_position = (int)parser.linearval('R', LOGICAL_X_POSITION(RIGHT_PROBE_BED_POSITION)); + front_probe_bed_position = (int)parser.linearval('F', LOGICAL_Y_POSITION(FRONT_PROBE_BED_POSITION)); + back_probe_bed_position = (int)parser.linearval('B', LOGICAL_Y_POSITION(BACK_PROBE_BED_POSITION)); + + const bool left_out_l = left_probe_bed_position < LOGICAL_X_POSITION(MIN_PROBE_X), + left_out = left_out_l || left_probe_bed_position > right_probe_bed_position - (MIN_PROBE_EDGE), + right_out_r = right_probe_bed_position > LOGICAL_X_POSITION(MAX_PROBE_X), + right_out = right_out_r || right_probe_bed_position < left_probe_bed_position + MIN_PROBE_EDGE, + front_out_f = front_probe_bed_position < LOGICAL_Y_POSITION(MIN_PROBE_Y), + front_out = front_out_f || front_probe_bed_position > back_probe_bed_position - (MIN_PROBE_EDGE), + back_out_b = back_probe_bed_position > LOGICAL_Y_POSITION(MAX_PROBE_Y), + back_out = back_out_b || back_probe_bed_position < front_probe_bed_position + MIN_PROBE_EDGE; + + if (left_out || right_out || front_out || back_out) { + if (left_out) { + out_of_range_error(PSTR("(L)eft")); + left_probe_bed_position = left_out_l ? LOGICAL_X_POSITION(MIN_PROBE_X) : right_probe_bed_position - (MIN_PROBE_EDGE); + } + if (right_out) { + out_of_range_error(PSTR("(R)ight")); + right_probe_bed_position = right_out_r ? LOGICAL_Y_POSITION(MAX_PROBE_X) : left_probe_bed_position + MIN_PROBE_EDGE; + } + if (front_out) { + out_of_range_error(PSTR("(F)ront")); + front_probe_bed_position = front_out_f ? LOGICAL_Y_POSITION(MIN_PROBE_Y) : back_probe_bed_position - (MIN_PROBE_EDGE); + } + if (back_out) { + out_of_range_error(PSTR("(B)ack")); + back_probe_bed_position = back_out_b ? LOGICAL_Y_POSITION(MAX_PROBE_Y) : front_probe_bed_position + MIN_PROBE_EDGE; + } + return; + } + + // probe at the points of a lattice grid + xGridSpacing = (right_probe_bed_position - left_probe_bed_position) / (abl_grid_points_x - 1); + yGridSpacing = (back_probe_bed_position - front_probe_bed_position) / (abl_grid_points_y - 1); + + #endif // ABL_GRID + + if (verbose_level > 0) { + SERIAL_PROTOCOLLNPGM("G29 Auto Bed Leveling"); + if (dryrun) SERIAL_PROTOCOLLNPGM("Running in DRY-RUN mode"); + } + + stepper.synchronize(); + + // Disable auto bed leveling during G29 + planner.abl_enabled = false; + + if (!dryrun) { + // Re-orient the current position without leveling + // based on where the steppers are positioned. + set_current_from_steppers_for_axis(ALL_AXES); + + // Sync the planner to where the steppers stopped + SYNC_PLAN_POSITION_KINEMATIC(); + } + + #if HAS_BED_PROBE + // Deploy the probe. Probe will raise if needed. + if (DEPLOY_PROBE()) { + planner.abl_enabled = abl_should_enable; + return; + } + #endif + + if (!faux) setup_for_endstop_or_probe_move(); + + #if ENABLED(AUTO_BED_LEVELING_BILINEAR) + + #if ENABLED(PROBE_MANUALLY) + if (!no_action) + #endif + if ( xGridSpacing != bilinear_grid_spacing[X_AXIS] + || yGridSpacing != bilinear_grid_spacing[Y_AXIS] + || left_probe_bed_position != LOGICAL_X_POSITION(bilinear_start[X_AXIS]) + || front_probe_bed_position != LOGICAL_Y_POSITION(bilinear_start[Y_AXIS]) + ) { + if (dryrun) { + // Before reset bed level, re-enable to correct the position + planner.abl_enabled = abl_should_enable; + } + // Reset grid to 0.0 or "not probed". (Also disables ABL) + reset_bed_level(); + + // Initialize a grid with the given dimensions + bilinear_grid_spacing[X_AXIS] = xGridSpacing; + bilinear_grid_spacing[Y_AXIS] = yGridSpacing; + bilinear_start[X_AXIS] = RAW_X_POSITION(left_probe_bed_position); + bilinear_start[Y_AXIS] = RAW_Y_POSITION(front_probe_bed_position); + + // Can't re-enable (on error) until the new grid is written + abl_should_enable = false; + } + + #endif // AUTO_BED_LEVELING_BILINEAR + + #if ENABLED(AUTO_BED_LEVELING_3POINT) + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("> 3-point Leveling"); + #endif + + // Probe at 3 arbitrary points + points[0].z = points[1].z = points[2].z = 0; + + #endif // AUTO_BED_LEVELING_3POINT + + } // !g29_in_progress + + #if ENABLED(PROBE_MANUALLY) + + // For manual probing, get the next index to probe now. + // On the first probe this will be incremented to 0. + if (!no_action) { + ++abl_probe_index; + g29_in_progress = true; + } + + // Abort current G29 procedure, go back to idle state + if (seenA && g29_in_progress) { + SERIAL_PROTOCOLLNPGM("Manual G29 aborted"); + #if HAS_SOFTWARE_ENDSTOPS + soft_endstops_enabled = enable_soft_endstops; + #endif + planner.abl_enabled = abl_should_enable; + g29_in_progress = false; + #if ENABLED(LCD_BED_LEVELING) + lcd_wait_for_move = false; + #endif + } + + // Query G29 status + if (verbose_level || seenQ) { + SERIAL_PROTOCOLPGM("Manual G29 "); + if (g29_in_progress) { + SERIAL_PROTOCOLPAIR("point ", min(abl_probe_index + 1, abl2)); + SERIAL_PROTOCOLLNPAIR(" of ", abl2); + } + else + SERIAL_PROTOCOLLNPGM("idle"); + } + + if (no_action) return; + + if (abl_probe_index == 0) { + // For the initial G29 save software endstop state + #if HAS_SOFTWARE_ENDSTOPS + enable_soft_endstops = soft_endstops_enabled; + #endif + } + else { + // For G29 after adjusting Z. + // Save the previous Z before going to the next point + measured_z = current_position[Z_AXIS]; + + #if ENABLED(AUTO_BED_LEVELING_LINEAR) + + mean += measured_z; + eqnBVector[abl_probe_index] = measured_z; + eqnAMatrix[abl_probe_index + 0 * abl2] = xProbe; + eqnAMatrix[abl_probe_index + 1 * abl2] = yProbe; + eqnAMatrix[abl_probe_index + 2 * abl2] = 1; + + incremental_LSF(&lsf_results, xProbe, yProbe, measured_z); + + #elif ENABLED(AUTO_BED_LEVELING_BILINEAR) + + z_values[xCount][yCount] = measured_z + zoffset; + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_PROTOCOLPAIR("Save X", xCount); + SERIAL_PROTOCOLPAIR(" Y", yCount); + SERIAL_PROTOCOLLNPAIR(" Z", measured_z + zoffset); + } + #endif + + #elif ENABLED(AUTO_BED_LEVELING_3POINT) + + points[abl_probe_index].z = measured_z; + + #endif + } + + // + // If there's another point to sample, move there with optional lift. + // + + #if ABL_GRID + + // Skip any unreachable points + while (abl_probe_index < abl2) { + + // Set xCount, yCount based on abl_probe_index, with zig-zag + PR_OUTER_VAR = abl_probe_index / PR_INNER_END; + 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); + + if (zig) PR_INNER_VAR = (PR_INNER_END - 1) - PR_INNER_VAR; + + const float xBase = xCount * xGridSpacing + left_probe_bed_position, + yBase = yCount * yGridSpacing + front_probe_bed_position; + + xProbe = FLOOR(xBase + (xBase < 0 ? 0 : 0.5)); + yProbe = FLOOR(yBase + (yBase < 0 ? 0 : 0.5)); + + #if ENABLED(AUTO_BED_LEVELING_LINEAR) + indexIntoAB[xCount][yCount] = abl_probe_index; + #endif + + // Keep looping till a reachable point is found + if (position_is_reachable_xy(xProbe, yProbe)) break; + ++abl_probe_index; + } + + // Is there a next point to move to? + if (abl_probe_index < abl2) { + _manual_goto_xy(xProbe, yProbe); // 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 + return; + } + else { + + // Leveling done! Fall through to G29 finishing code below + + SERIAL_PROTOCOLLNPGM("Grid probing done."); + + // Re-enable software endstops, if needed + #if HAS_SOFTWARE_ENDSTOPS + soft_endstops_enabled = enable_soft_endstops; + #endif + } + + #elif ENABLED(AUTO_BED_LEVELING_3POINT) + + // Probe at 3 arbitrary points + if (abl_probe_index < 3) { + xProbe = LOGICAL_X_POSITION(points[abl_probe_index].x); + yProbe = LOGICAL_Y_POSITION(points[abl_probe_index].y); + #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 + return; + } + else { + + SERIAL_PROTOCOLLNPGM("3-point probing done."); + + // Re-enable software endstops, if needed + #if HAS_SOFTWARE_ENDSTOPS + soft_endstops_enabled = enable_soft_endstops; + #endif + + if (!dryrun) { + vector_3 planeNormal = vector_3::cross(points[0] - points[1], points[2] - points[1]).get_normal(); + if (planeNormal.z < 0) { + planeNormal.x *= -1; + planeNormal.y *= -1; + planeNormal.z *= -1; + } + planner.bed_level_matrix = matrix_3x3::create_look_at(planeNormal); + + // Can't re-enable (on error) until the new grid is written + abl_should_enable = false; + } + + } + + #endif // AUTO_BED_LEVELING_3POINT + + #else // !PROBE_MANUALLY + { + const bool stow_probe_after_each = parser.boolval('E'); + + #if ABL_GRID + + bool zig = PR_OUTER_END & 1; // Always end at RIGHT and BACK_PROBE_BED_POSITION + + // Outer loop is Y with PROBE_Y_FIRST disabled + for (uint8_t PR_OUTER_VAR = 0; PR_OUTER_VAR < PR_OUTER_END && !isnan(measured_z); PR_OUTER_VAR++) { + + int8_t inStart, inStop, inInc; + + if (zig) { // away from origin + inStart = 0; + inStop = PR_INNER_END; + inInc = 1; + } + else { // towards origin + inStart = PR_INNER_END - 1; + inStop = -1; + inInc = -1; + } + + zig ^= true; // zag + + // Inner loop is Y with PROBE_Y_FIRST enabled + for (int8_t PR_INNER_VAR = inStart; PR_INNER_VAR != inStop; PR_INNER_VAR += inInc) { + + float xBase = left_probe_bed_position + xGridSpacing * xCount, + yBase = front_probe_bed_position + yGridSpacing * yCount; + + xProbe = FLOOR(xBase + (xBase < 0 ? 0 : 0.5)); + yProbe = FLOOR(yBase + (yBase < 0 ? 0 : 0.5)); + + #if ENABLED(AUTO_BED_LEVELING_LINEAR) + indexIntoAB[xCount][yCount] = ++abl_probe_index; // 0... + #endif + + #if IS_KINEMATIC + // Avoid probing outside the round or hexagonal area + if (!position_is_reachable_by_probe_xy(xProbe, yProbe)) continue; + #endif + + measured_z = faux ? 0.001 * random(-100, 101) : probe_pt(xProbe, yProbe, stow_probe_after_each, verbose_level); + + if (isnan(measured_z)) { + planner.abl_enabled = abl_should_enable; + break; + } + + #if ENABLED(AUTO_BED_LEVELING_LINEAR) + + mean += measured_z; + eqnBVector[abl_probe_index] = measured_z; + eqnAMatrix[abl_probe_index + 0 * abl2] = xProbe; + eqnAMatrix[abl_probe_index + 1 * abl2] = yProbe; + eqnAMatrix[abl_probe_index + 2 * abl2] = 1; + + incremental_LSF(&lsf_results, xProbe, yProbe, measured_z); + + #elif ENABLED(AUTO_BED_LEVELING_BILINEAR) + + z_values[xCount][yCount] = measured_z + zoffset; + + #endif + + abl_should_enable = false; + idle(); + + } // inner + } // outer + + #elif ENABLED(AUTO_BED_LEVELING_3POINT) + + // Probe at 3 arbitrary points + + for (uint8_t i = 0; i < 3; ++i) { + // Retain the last probe position + xProbe = LOGICAL_X_POSITION(points[i].x); + yProbe = LOGICAL_Y_POSITION(points[i].y); + measured_z = faux ? 0.001 * random(-100, 101) : probe_pt(xProbe, yProbe, stow_probe_after_each, verbose_level); + if (isnan(measured_z)) { + planner.abl_enabled = abl_should_enable; + break; + } + points[i].z = measured_z; + } + + if (!dryrun && !isnan(measured_z)) { + vector_3 planeNormal = vector_3::cross(points[0] - points[1], points[2] - points[1]).get_normal(); + if (planeNormal.z < 0) { + planeNormal.x *= -1; + planeNormal.y *= -1; + planeNormal.z *= -1; + } + planner.bed_level_matrix = matrix_3x3::create_look_at(planeNormal); + + // Can't re-enable (on error) until the new grid is written + abl_should_enable = false; + } + + #endif // AUTO_BED_LEVELING_3POINT + + // Raise to _Z_CLEARANCE_DEPLOY_PROBE. Stow the probe. + if (STOW_PROBE()) { + planner.abl_enabled = abl_should_enable; + measured_z = NAN; + } + } + #endif // !PROBE_MANUALLY + + // + // G29 Finishing Code + // + // Unless this is a dry run, auto bed leveling will + // definitely be enabled after this point. + // + // If code above wants to continue leveling, it should + // return or loop before this point. + // + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("> probing complete", current_position); + #endif + + #if ENABLED(PROBE_MANUALLY) + g29_in_progress = false; + #if ENABLED(LCD_BED_LEVELING) + lcd_wait_for_move = false; + #endif + #endif + + // Calculate leveling, print reports, correct the position + if (!isnan(measured_z)) { + #if ENABLED(AUTO_BED_LEVELING_BILINEAR) + + if (!dryrun) extrapolate_unprobed_bed_level(); + print_bilinear_leveling_grid(); + + refresh_bed_level(); + + #if ENABLED(ABL_BILINEAR_SUBDIVISION) + print_bilinear_leveling_grid_virt(); + #endif + + #elif ENABLED(AUTO_BED_LEVELING_LINEAR) + + // For LINEAR leveling calculate matrix, print reports, correct the position + + /** + * solve the plane equation ax + by + d = z + * A is the matrix with rows [x y 1] for all the probed points + * B is the vector of the Z positions + * the normal vector to the plane is formed by the coefficients of the + * plane equation in the standard form, which is Vx*x+Vy*y+Vz*z+d = 0 + * so Vx = -a Vy = -b Vz = 1 (we want the vector facing towards positive Z + */ + float plane_equation_coefficients[3]; + + finish_incremental_LSF(&lsf_results); + plane_equation_coefficients[0] = -lsf_results.A; // We should be able to eliminate the '-' on these three lines and down below + plane_equation_coefficients[1] = -lsf_results.B; // but that is not yet tested. + plane_equation_coefficients[2] = -lsf_results.D; + + mean /= abl2; + + if (verbose_level) { + SERIAL_PROTOCOLPGM("Eqn coefficients: a: "); + SERIAL_PROTOCOL_F(plane_equation_coefficients[0], 8); + SERIAL_PROTOCOLPGM(" b: "); + SERIAL_PROTOCOL_F(plane_equation_coefficients[1], 8); + SERIAL_PROTOCOLPGM(" d: "); + SERIAL_PROTOCOL_F(plane_equation_coefficients[2], 8); + SERIAL_EOL(); + if (verbose_level > 2) { + SERIAL_PROTOCOLPGM("Mean of sampled points: "); + SERIAL_PROTOCOL_F(mean, 8); + SERIAL_EOL(); + } + } + + // Create the matrix but don't correct the position yet + if (!dryrun) + planner.bed_level_matrix = matrix_3x3::create_look_at( + vector_3(-plane_equation_coefficients[0], -plane_equation_coefficients[1], 1) // We can eliminate the '-' here and up above + ); + + // Show the Topography map if enabled + if (do_topography_map) { + + SERIAL_PROTOCOLLNPGM("\nBed Height Topography:\n" + " +--- BACK --+\n" + " | |\n" + " L | (+) | R\n" + " E | | I\n" + " F | (-) N (+) | G\n" + " T | | H\n" + " | (-) | T\n" + " | |\n" + " O-- FRONT --+\n" + " (0,0)"); + + float min_diff = 999; + + for (int8_t yy = abl_grid_points_y - 1; yy >= 0; yy--) { + for (uint8_t xx = 0; xx < abl_grid_points_x; xx++) { + int ind = indexIntoAB[xx][yy]; + float diff = eqnBVector[ind] - mean, + x_tmp = eqnAMatrix[ind + 0 * abl2], + y_tmp = eqnAMatrix[ind + 1 * abl2], + z_tmp = 0; + + apply_rotation_xyz(planner.bed_level_matrix, x_tmp, y_tmp, z_tmp); + + NOMORE(min_diff, eqnBVector[ind] - z_tmp); + + if (diff >= 0.0) + SERIAL_PROTOCOLPGM(" +"); // Include + for column alignment + else + SERIAL_PROTOCOLCHAR(' '); + SERIAL_PROTOCOL_F(diff, 5); + } // xx + SERIAL_EOL(); + } // yy + SERIAL_EOL(); + + if (verbose_level > 3) { + SERIAL_PROTOCOLLNPGM("\nCorrected Bed Height vs. Bed Topology:"); + + for (int8_t yy = abl_grid_points_y - 1; yy >= 0; yy--) { + for (uint8_t xx = 0; xx < abl_grid_points_x; xx++) { + int ind = indexIntoAB[xx][yy]; + float x_tmp = eqnAMatrix[ind + 0 * abl2], + y_tmp = eqnAMatrix[ind + 1 * abl2], + z_tmp = 0; + + apply_rotation_xyz(planner.bed_level_matrix, x_tmp, y_tmp, z_tmp); + + float diff = eqnBVector[ind] - z_tmp - min_diff; + if (diff >= 0.0) + SERIAL_PROTOCOLPGM(" +"); + // Include + for column alignment + else + SERIAL_PROTOCOLCHAR(' '); + SERIAL_PROTOCOL_F(diff, 5); + } // xx + SERIAL_EOL(); + } // yy + SERIAL_EOL(); + } + } //do_topography_map + + #endif // AUTO_BED_LEVELING_LINEAR + + #if ABL_PLANAR + + // For LINEAR and 3POINT leveling correct the current position + + if (verbose_level > 0) + planner.bed_level_matrix.debug(PSTR("\n\nBed Level Correction Matrix:")); + + if (!dryrun) { + // + // Correct the current XYZ position based on the tilted plane. + // + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("G29 uncorrected XYZ", current_position); + #endif + + float converted[XYZ]; + COPY(converted, current_position); + + planner.abl_enabled = true; + planner.unapply_leveling(converted); // use conversion machinery + planner.abl_enabled = false; + + // Use the last measured distance to the bed, if possible + if ( NEAR(current_position[X_AXIS], xProbe - (X_PROBE_OFFSET_FROM_EXTRUDER)) + && NEAR(current_position[Y_AXIS], yProbe - (Y_PROBE_OFFSET_FROM_EXTRUDER)) + ) { + const float simple_z = current_position[Z_AXIS] - measured_z; + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOPAIR("Z from Probe:", simple_z); + SERIAL_ECHOPAIR(" Matrix:", converted[Z_AXIS]); + SERIAL_ECHOLNPAIR(" Discrepancy:", simple_z - converted[Z_AXIS]); + } + #endif + converted[Z_AXIS] = simple_z; + } + + // The rotated XY and corrected Z are now current_position + COPY(current_position, converted); + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("G29 corrected XYZ", current_position); + #endif + } + + #elif ENABLED(AUTO_BED_LEVELING_BILINEAR) + + if (!dryrun) { + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPAIR("G29 uncorrected Z:", current_position[Z_AXIS]); + #endif + + // Unapply the offset because it is going to be immediately applied + // and cause compensation movement in Z + current_position[Z_AXIS] -= bilinear_z_offset(current_position); + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPAIR(" corrected Z:", current_position[Z_AXIS]); + #endif + } + + #endif // ABL_PLANAR + + #ifdef Z_PROBE_END_SCRIPT + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPAIR("Z Probe End Script: ", Z_PROBE_END_SCRIPT); + #endif + enqueue_and_echo_commands_P(PSTR(Z_PROBE_END_SCRIPT)); + stepper.synchronize(); + #endif + + // Auto Bed Leveling is complete! Enable if possible. + planner.abl_enabled = dryrun ? abl_should_enable : true; + } // !isnan(measured_z) + + // Restore state after probing + if (!faux) clean_up_after_endstop_or_probe_move(); + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("<<< gcode_G29"); + #endif + + report_current_position(); + + KEEPALIVE_STATE(IN_HANDLER); + + if (planner.abl_enabled) + SYNC_PLAN_POSITION_KINEMATIC(); + } + +#endif // HAS_ABL && !AUTO_BED_LEVELING_UBL + +#if HAS_BED_PROBE + + /** + * G30: Do a single Z probe at the current XY + * + * Parameters: + * + * X Probe X position (default current X) + * Y Probe Y position (default current Y) + * S0 Leave the probe deployed + */ + inline void gcode_G30() { + const float xpos = parser.linearval('X', current_position[X_AXIS] + X_PROBE_OFFSET_FROM_EXTRUDER), + ypos = parser.linearval('Y', current_position[Y_AXIS] + Y_PROBE_OFFSET_FROM_EXTRUDER); + + if (!position_is_reachable_by_probe_xy(xpos, ypos)) return; + + // Disable leveling so the planner won't mess with us + #if HAS_LEVELING + set_bed_leveling_enabled(false); + #endif + + setup_for_endstop_or_probe_move(); + + const float measured_z = probe_pt(xpos, ypos, parser.boolval('S', true), 1); + + if (!isnan(measured_z)) { + SERIAL_PROTOCOLPAIR("Bed X: ", FIXFLOAT(xpos)); + SERIAL_PROTOCOLPAIR(" Y: ", FIXFLOAT(ypos)); + SERIAL_PROTOCOLLNPAIR(" Z: ", FIXFLOAT(measured_z)); + } + + clean_up_after_endstop_or_probe_move(); + + report_current_position(); + } + + #if ENABLED(Z_PROBE_SLED) + + /** + * G31: Deploy the Z probe + */ + inline void gcode_G31() { DEPLOY_PROBE(); } + + /** + * G32: Stow the Z probe + */ + inline void gcode_G32() { STOW_PROBE(); } + + #endif // Z_PROBE_SLED + +#endif // HAS_BED_PROBE + +#if PROBE_SELECTED + + #if ENABLED(DELTA_AUTO_CALIBRATION) + /** + * G33 - Delta '1-4-7-point' Auto-Calibration + * Calibrate height, endstops, delta radius, and tower angles. + * + * Parameters: + * + * Pn Number of probe points: + * + * P0 No probe. Normalize only. + * P1 Probe center and set height only. + * P2 Probe center and towers. Set height, endstops, and delta radius. + * P3 Probe all positions: center, towers and opposite towers. Set all. + * P4-P7 Probe all positions at different locations and average them. + * + * T0 Don't calibrate tower angle corrections + * + * Cn.nn Calibration precision; when omitted calibrates to maximum precision + * + * Fn Force to run at least n iterations and takes the best result + * + * Vn Verbose level: + * + * V0 Dry-run mode. Report settings and probe results. No calibration. + * V1 Report settings + * V2 Report settings and probe results + * + * E Engage the probe for each point + */ + + void print_signed_float(const char * const prefix, const float &f) { + SERIAL_PROTOCOLPGM(" "); + serialprintPGM(prefix); + SERIAL_PROTOCOLCHAR(':'); + if (f >= 0) SERIAL_CHAR('+'); + SERIAL_PROTOCOL_F(f, 2); + } + + void print_G33_settings(const bool end_stops, const bool tower_angles) { + SERIAL_PROTOCOLPAIR(".Height:", DELTA_HEIGHT + home_offset[Z_AXIS]); + if (end_stops) { + print_signed_float(PSTR(" Ex"), endstop_adj[A_AXIS]); + print_signed_float(PSTR("Ey"), endstop_adj[B_AXIS]); + print_signed_float(PSTR("Ez"), endstop_adj[C_AXIS]); + SERIAL_PROTOCOLPAIR(" Radius:", delta_radius); + } + SERIAL_EOL(); + if (tower_angles) { + SERIAL_PROTOCOLPGM(".Tower angle : "); + print_signed_float(PSTR("Tx"), delta_tower_angle_trim[A_AXIS]); + print_signed_float(PSTR("Ty"), delta_tower_angle_trim[B_AXIS]); + print_signed_float(PSTR("Tz"), delta_tower_angle_trim[C_AXIS]); + SERIAL_EOL(); + } + } + + void G33_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 + STOW_PROBE(); + clean_up_after_endstop_or_probe_move(); + #if HOTENDS > 1 + tool_change(old_tool_index, 0, true); + #endif + } + + inline void gcode_G33() { + + const int8_t probe_points = parser.intval('P', DELTA_CALIBRATION_DEFAULT_POINTS); + if (!WITHIN(probe_points, 0, 7)) { + SERIAL_PROTOCOLLNPGM("?(P)oints is implausible (0-7)."); + return; + } + + const int8_t verbose_level = parser.byteval('V', 1); + if (!WITHIN(verbose_level, 0, 2)) { + SERIAL_PROTOCOLLNPGM("?(V)erbose level is implausible (0-2)."); + return; + } + + const float calibration_precision = parser.floatval('C'); + if (calibration_precision < 0) { + SERIAL_PROTOCOLLNPGM("?(C)alibration precision is implausible (>0)."); + return; + } + + const int8_t force_iterations = parser.intval('F', 0); + if (!WITHIN(force_iterations, 0, 30)) { + SERIAL_PROTOCOLLNPGM("?(F)orce iteration is implausible (0-30)."); + return; + } + + const bool towers_set = parser.boolval('T', true), + stow_after_each = parser.boolval('E'), + _0p_calibration = probe_points == 0, + _1p_calibration = probe_points == 1, + _4p_calibration = probe_points == 2, + _4p_towers_points = _4p_calibration && towers_set, + _4p_opposite_points = _4p_calibration && !towers_set, + _7p_calibration = probe_points >= 3 || _0p_calibration, + _7p_half_circle = probe_points == 3, + _7p_double_circle = probe_points == 5, + _7p_triple_circle = probe_points == 6, + _7p_quadruple_circle = probe_points == 7, + _7p_multi_circle = _7p_double_circle || _7p_triple_circle || _7p_quadruple_circle, + _7p_intermed_points = _7p_calibration && !_7p_half_circle; + const static char save_message[] PROGMEM = "Save with M500 and/or copy to Configuration.h"; + const float dx = (X_PROBE_OFFSET_FROM_EXTRUDER), + dy = (Y_PROBE_OFFSET_FROM_EXTRUDER); + int8_t iterations = 0; + float test_precision, + zero_std_dev = (verbose_level ? 999.0 : 0.0), // 0.0 in dry-run mode : forced end + zero_std_dev_old = zero_std_dev, + zero_std_dev_min = zero_std_dev, + e_old[ABC] = { + endstop_adj[A_AXIS], + endstop_adj[B_AXIS], + endstop_adj[C_AXIS] + }, + dr_old = delta_radius, + zh_old = home_offset[Z_AXIS], + ta_old[ABC] = { + delta_tower_angle_trim[A_AXIS], + delta_tower_angle_trim[B_AXIS], + delta_tower_angle_trim[C_AXIS] + }; + + if (!_1p_calibration && !_0p_calibration) { // test if the outer radius is reachable + const float circles = (_7p_quadruple_circle ? 1.5 : + _7p_triple_circle ? 1.0 : + _7p_double_circle ? 0.5 : 0), + r = (1 + circles * 0.1) * delta_calibration_radius; + for (uint8_t axis = 1; axis < 13; ++axis) { + const float a = RADIANS(180 + 30 * axis); + if (!position_is_reachable_xy(cos(a) * r, sin(a) * r)) { + SERIAL_PROTOCOLLNPGM("?(M665 B)ed radius is implausible."); + return; + } + } + } + SERIAL_PROTOCOLLNPGM("G33 Auto Calibrate"); + + stepper.synchronize(); + #if HAS_LEVELING + reset_bed_level(); // After calibration bed-level data is no longer valid + #endif + + #if HOTENDS > 1 + const uint8_t old_tool_index = active_extruder; + tool_change(0, 0, true); + #define G33_CLEANUP() G33_cleanup(old_tool_index) + #else + #define G33_CLEANUP() G33_cleanup() + #endif + + setup_for_endstop_or_probe_move(); + endstops.enable(true); + if (!_0p_calibration) { + if (!home_delta()) + return; + endstops.not_homing(); + } + + // print settings + + const char *checkingac = PSTR("Checking... AC"); // TODO: Make translatable string + serialprintPGM(checkingac); + if (verbose_level == 0) SERIAL_PROTOCOLPGM(" (DRY-RUN)"); + SERIAL_EOL(); + lcd_setstatusPGM(checkingac); + + print_G33_settings(!_1p_calibration, _7p_calibration && towers_set); + + do { + + float z_at_pt[13] = { 0.0 }; + + test_precision = zero_std_dev_old != 999.0 ? (zero_std_dev + zero_std_dev_old) / 2 : zero_std_dev; + iterations++; + + // Probe the points + + if (!_0p_calibration){ + if (!_7p_half_circle && !_7p_triple_circle) { // probe the center + #if ENABLED(PROBE_MANUALLY) + z_at_pt[0] += lcd_probe_pt(0, 0); + #else + z_at_pt[0] += probe_pt(dx, dy, stow_after_each, 1, false); + if (isnan(z_at_pt[0])) return G33_CLEANUP(); + #endif + } + if (_7p_calibration) { // probe extra center points + for (int8_t axis = _7p_multi_circle ? 11 : 9; axis > 0; axis -= _7p_multi_circle ? 2 : 4) { + const float a = RADIANS(180 + 30 * axis), r = delta_calibration_radius * 0.1; + #if ENABLED(PROBE_MANUALLY) + z_at_pt[0] += lcd_probe_pt(cos(a) * r, sin(a) * r); + #else + z_at_pt[0] += probe_pt(cos(a) * r + dx, sin(a) * r + dy, stow_after_each, 1); + if (isnan(z_at_pt[0])) return G33_CLEANUP(); + #endif + } + z_at_pt[0] /= float(_7p_double_circle ? 7 : probe_points); + } + if (!_1p_calibration) { // probe the radius + bool zig_zag = true; + const uint8_t start = _4p_opposite_points ? 3 : 1, + step = _4p_calibration ? 4 : _7p_half_circle ? 2 : 1; + for (uint8_t axis = start; axis < 13; axis += step) { + const float zigadd = (zig_zag ? 0.5 : 0.0), + offset_circles = _7p_quadruple_circle ? zigadd + 1.0 : + _7p_triple_circle ? zigadd + 0.5 : + _7p_double_circle ? zigadd : 0; + for (float circles = -offset_circles ; circles <= offset_circles; circles++) { + const float a = RADIANS(180 + 30 * axis), + r = delta_calibration_radius * (1 + circles * (zig_zag ? 0.1 : -0.1)); + #if ENABLED(PROBE_MANUALLY) + z_at_pt[axis] += lcd_probe_pt(cos(a) * r, sin(a) * r); + #else + z_at_pt[axis] += probe_pt(cos(a) * r + dx, sin(a) * r + dy, stow_after_each, 1); + if (isnan(z_at_pt[axis])) return G33_CLEANUP(); + #endif + } + zig_zag = !zig_zag; + z_at_pt[axis] /= (2 * offset_circles + 1); + } + } + if (_7p_intermed_points) // average intermediates to tower and opposites + for (uint8_t axis = 1; axis < 13; axis += 2) + z_at_pt[axis] = (z_at_pt[axis] + (z_at_pt[axis + 1] + z_at_pt[(axis + 10) % 12 + 1]) / 2.0) / 2.0; + + } + float S1 = z_at_pt[0], + S2 = sq(z_at_pt[0]); + int16_t N = 1; + if (!_1p_calibration) // std dev from zero plane + for (uint8_t axis = (_4p_opposite_points ? 3 : 1); axis < 13; axis += (_4p_calibration ? 4 : 2)) { + S1 += z_at_pt[axis]; + S2 += sq(z_at_pt[axis]); + N++; + } + zero_std_dev_old = zero_std_dev; + zero_std_dev = round(SQRT(S2 / N) * 1000.0) / 1000.0 + 0.00001; + + // Solve matrices + + if ((zero_std_dev < test_precision || iterations <= force_iterations) && zero_std_dev > calibration_precision) { + if (zero_std_dev < zero_std_dev_min) { + COPY(e_old, endstop_adj); + dr_old = delta_radius; + zh_old = home_offset[Z_AXIS]; + COPY(ta_old, delta_tower_angle_trim); + } + + float e_delta[ABC] = { 0.0 }, r_delta = 0.0, t_delta[ABC] = { 0.0 }; + + const float r_diff = delta_radius - delta_calibration_radius, + h_factor = (1.00 + r_diff * 0.001) / 6.0, // 1.02 for r_diff = 20mm + r_factor = (-(1.75 + 0.005 * r_diff + 0.001 * sq(r_diff))) / 6.0, // 2.25 for r_diff = 20mm + a_factor = (66.66 / delta_calibration_radius) / (iterations == 1 ? 16.0 : 2.0); // 0.83 for cal_rd = 80mm (Slow down on 1st iteration) + + #define ZP(N,I) ((N) * z_at_pt[I]) + #define Z6(I) ZP(6, I) + #define Z4(I) ZP(4, I) + #define Z2(I) ZP(2, I) + #define Z1(I) ZP(1, I) + + #if ENABLED(PROBE_MANUALLY) + test_precision = 0.00; // forced end + #endif + + switch (probe_points) { + case 0: + #if DISABLED(PROBE_MANUALLY) + test_precision = 0.00; // forced end + #endif + break; + + case 1: + #if DISABLED(PROBE_MANUALLY) + test_precision = 0.00; // forced end + #endif + LOOP_XYZ(axis) e_delta[axis] = Z1(0); + break; + + case 2: + if (towers_set) { + e_delta[A_AXIS] = (Z6(0) + Z4(1) - Z2(5) - Z2(9)) * h_factor; + e_delta[B_AXIS] = (Z6(0) - Z2(1) + Z4(5) - Z2(9)) * h_factor; + e_delta[C_AXIS] = (Z6(0) - Z2(1) - Z2(5) + Z4(9)) * h_factor; + r_delta = (Z6(0) - Z2(1) - Z2(5) - Z2(9)) * r_factor; + } + else { + e_delta[A_AXIS] = (Z6(0) - Z4(7) + Z2(11) + Z2(3)) * h_factor; + e_delta[B_AXIS] = (Z6(0) + Z2(7) - Z4(11) + Z2(3)) * h_factor; + e_delta[C_AXIS] = (Z6(0) + Z2(7) + Z2(11) - Z4(3)) * h_factor; + r_delta = (Z6(0) - Z2(7) - Z2(11) - Z2(3)) * r_factor; + } + break; + + default: + e_delta[A_AXIS] = (Z6(0) + Z2(1) - Z1(5) - Z1(9) - Z2(7) + Z1(11) + Z1(3)) * h_factor; + e_delta[B_AXIS] = (Z6(0) - Z1(1) + Z2(5) - Z1(9) + Z1(7) - Z2(11) + Z1(3)) * h_factor; + e_delta[C_AXIS] = (Z6(0) - Z1(1) - Z1(5) + Z2(9) + Z1(7) + Z1(11) - Z2(3)) * h_factor; + r_delta = (Z6(0) - Z1(1) - Z1(5) - Z1(9) - Z1(7) - Z1(11) - Z1(3)) * r_factor; + + if (towers_set) { + t_delta[A_AXIS] = ( - Z2(5) + Z2(9) - Z2(11) + Z2(3)) * a_factor; + t_delta[B_AXIS] = ( Z2(1) - Z2(9) + Z2(7) - Z2(3)) * a_factor; + t_delta[C_AXIS] = (-Z2(1) + Z2(5) - Z2(7) + Z2(11) ) * a_factor; + e_delta[A_AXIS] += (t_delta[B_AXIS] - t_delta[C_AXIS]) / 4.5; + e_delta[B_AXIS] += (t_delta[C_AXIS] - t_delta[A_AXIS]) / 4.5; + e_delta[C_AXIS] += (t_delta[A_AXIS] - t_delta[B_AXIS]) / 4.5; + } + break; + } + + LOOP_XYZ(axis) endstop_adj[axis] += e_delta[axis]; + delta_radius += r_delta; + LOOP_XYZ(axis) delta_tower_angle_trim[axis] += t_delta[axis]; + } + else if (zero_std_dev >= test_precision) { // step one back + COPY(endstop_adj, e_old); + delta_radius = dr_old; + home_offset[Z_AXIS] = zh_old; + COPY(delta_tower_angle_trim, ta_old); + } + + if (verbose_level != 0) { // !dry run + // normalise angles to least squares + float a_sum = 0.0; + LOOP_XYZ(axis) a_sum += delta_tower_angle_trim[axis]; + LOOP_XYZ(axis) delta_tower_angle_trim[axis] -= a_sum / 3.0; + + // adjust delta_height and endstops by the max amount + const float z_temp = MAX3(endstop_adj[A_AXIS], endstop_adj[B_AXIS], endstop_adj[C_AXIS]); + home_offset[Z_AXIS] -= z_temp; + LOOP_XYZ(axis) endstop_adj[axis] -= z_temp; + } + recalc_delta_settings(delta_radius, delta_diagonal_rod, delta_tower_angle_trim); + NOMORE(zero_std_dev_min, zero_std_dev); + + // print report + + if (verbose_level != 1) { + SERIAL_PROTOCOLPGM(". "); + print_signed_float(PSTR("c"), z_at_pt[0]); + if (_4p_towers_points || _7p_calibration) { + print_signed_float(PSTR(" x"), z_at_pt[1]); + print_signed_float(PSTR(" y"), z_at_pt[5]); + print_signed_float(PSTR(" z"), z_at_pt[9]); + } + if (!_4p_opposite_points) SERIAL_EOL(); + if ((_4p_opposite_points) || _7p_calibration) { + if (_7p_calibration) { + SERIAL_CHAR('.'); + SERIAL_PROTOCOL_SP(13); + } + print_signed_float(PSTR(" yz"), z_at_pt[7]); + print_signed_float(PSTR("zx"), z_at_pt[11]); + print_signed_float(PSTR("xy"), z_at_pt[3]); + SERIAL_EOL(); + } + } + if (verbose_level != 0) { // !dry run + if ((zero_std_dev >= test_precision && iterations > force_iterations) || zero_std_dev <= calibration_precision) { // end iterations + SERIAL_PROTOCOLPGM("Calibration OK"); + SERIAL_PROTOCOL_SP(36); + #if DISABLED(PROBE_MANUALLY) + if (zero_std_dev >= test_precision && !_1p_calibration) + SERIAL_PROTOCOLPGM("rolling back."); + else + #endif + { + SERIAL_PROTOCOLPGM("std dev:"); + SERIAL_PROTOCOL_F(zero_std_dev_min, 3); + } + SERIAL_EOL(); + char mess[21]; + sprintf_P(mess, PSTR("Calibration sd:")); + if (zero_std_dev_min < 1) + sprintf_P(&mess[15], PSTR("0.%03i"), (int)round(zero_std_dev_min * 1000.0)); + else + sprintf_P(&mess[15], PSTR("%03i.x"), (int)round(zero_std_dev_min)); + lcd_setstatus(mess); + print_G33_settings(!_1p_calibration, _7p_calibration && towers_set); + serialprintPGM(save_message); + SERIAL_EOL(); + } + else { // !end iterations + char mess[15]; + if (iterations < 31) + sprintf_P(mess, PSTR("Iteration : %02i"), (int)iterations); + else + sprintf_P(mess, PSTR("No convergence")); + SERIAL_PROTOCOL(mess); + SERIAL_PROTOCOL_SP(36); + SERIAL_PROTOCOLPGM("std dev:"); + SERIAL_PROTOCOL_F(zero_std_dev, 3); + SERIAL_EOL(); + lcd_setstatus(mess); + print_G33_settings(!_1p_calibration, _7p_calibration && towers_set); + } + } + else { // dry run + const char *enddryrun = PSTR("End DRY-RUN"); + serialprintPGM(enddryrun); + SERIAL_PROTOCOL_SP(39); + SERIAL_PROTOCOLPGM("std dev:"); + SERIAL_PROTOCOL_F(zero_std_dev, 3); + SERIAL_EOL(); + + char mess[21]; + sprintf_P(mess, enddryrun); + sprintf_P(&mess[11], PSTR(" sd:")); + if (zero_std_dev < 1) + sprintf_P(&mess[15], PSTR("0.%03i"), (int)round(zero_std_dev * 1000.0)); + else + sprintf_P(&mess[15], PSTR("%03i.x"), (int)round(zero_std_dev)); + lcd_setstatus(mess); + } + + endstops.enable(true); + home_delta(); + endstops.not_homing(); + + } + while (((zero_std_dev < test_precision && iterations < 31) || iterations <= force_iterations) && zero_std_dev > calibration_precision); + + G33_CLEANUP(); + } + + #endif // DELTA_AUTO_CALIBRATION + +#endif // PROBE_SELECTED + +#if ENABLED(G38_PROBE_TARGET) + + static bool G38_run_probe() { + + bool G38_pass_fail = false; + + #if ENABLED(PROBE_DOUBLE_TOUCH) + // Get direction of move and retract + float retract_mm[XYZ]; + LOOP_XYZ(i) { + float dist = destination[i] - current_position[i]; + retract_mm[i] = FABS(dist) < G38_MINIMUM_MOVE ? 0 : home_bump_mm((AxisEnum)i) * (dist > 0 ? -1 : 1); + } + #endif + + stepper.synchronize(); // wait until the machine is idle + + // Move until destination reached or target hit + endstops.enable(true); + G38_move = true; + G38_endstop_hit = false; + prepare_move_to_destination(); + stepper.synchronize(); + G38_move = false; + + endstops.hit_on_purpose(); + set_current_from_steppers_for_axis(ALL_AXES); + SYNC_PLAN_POSITION_KINEMATIC(); + + if (G38_endstop_hit) { + + G38_pass_fail = true; + + #if ENABLED(PROBE_DOUBLE_TOUCH) + // Move away by the retract distance + set_destination_to_current(); + LOOP_XYZ(i) destination[i] += retract_mm[i]; + endstops.enable(false); + prepare_move_to_destination(); + stepper.synchronize(); + + feedrate_mm_s /= 4; + + // Bump the target more slowly + LOOP_XYZ(i) destination[i] -= retract_mm[i] * 2; + + endstops.enable(true); + G38_move = true; + prepare_move_to_destination(); + stepper.synchronize(); + G38_move = false; + + set_current_from_steppers_for_axis(ALL_AXES); + SYNC_PLAN_POSITION_KINEMATIC(); + #endif + } + + endstops.hit_on_purpose(); + endstops.not_homing(); + return G38_pass_fail; + } + + /** + * G38.2 - probe toward workpiece, stop on contact, signal error if failure + * G38.3 - probe toward workpiece, stop on contact + * + * Like G28 except uses Z min probe for all axes + */ + inline void gcode_G38(bool is_38_2) { + // Get X Y Z E F + gcode_get_destination(); + + setup_for_endstop_or_probe_move(); + + // If any axis has enough movement, do the move + LOOP_XYZ(i) + if (FABS(destination[i] - current_position[i]) >= G38_MINIMUM_MOVE) { + if (!parser.seenval('F')) feedrate_mm_s = homing_feedrate((AxisEnum)i); + // If G38.2 fails throw an error + if (!G38_run_probe() && is_38_2) { + SERIAL_ERROR_START(); + SERIAL_ERRORLNPGM("Failed to reach target"); + } + break; + } + + clean_up_after_endstop_or_probe_move(); + } + +#endif // G38_PROBE_TARGET + +#if ENABLED(AUTO_BED_LEVELING_BILINEAR) || ENABLED(AUTO_BED_LEVELING_UBL) || ENABLED(MESH_BED_LEVELING) + + /** + * G42: Move X & Y axes to mesh coordinates (I & J) + */ + inline void gcode_G42() { + #if ENABLED(NO_MOTION_BEFORE_HOMING) + if (axis_unhomed_error()) return; + #endif + + if (IsRunning()) { + const bool hasI = parser.seenval('I'); + const int8_t ix = hasI ? parser.value_int() : 0; + const bool hasJ = parser.seenval('J'); + const int8_t iy = hasJ ? parser.value_int() : 0; + + if ((hasI && !WITHIN(ix, 0, GRID_MAX_POINTS_X - 1)) || (hasJ && !WITHIN(iy, 0, GRID_MAX_POINTS_Y - 1))) { + SERIAL_ECHOLNPGM(MSG_ERR_MESH_XY); + return; + } + + #if ENABLED(AUTO_BED_LEVELING_BILINEAR) + #define _GET_MESH_X(I) bilinear_start[X_AXIS] + I * bilinear_grid_spacing[X_AXIS] + #define _GET_MESH_Y(J) bilinear_start[Y_AXIS] + J * bilinear_grid_spacing[Y_AXIS] + #elif ENABLED(AUTO_BED_LEVELING_UBL) + #define _GET_MESH_X(I) ubl.mesh_index_to_xpos(I) + #define _GET_MESH_Y(J) ubl.mesh_index_to_ypos(J) + #elif ENABLED(MESH_BED_LEVELING) + #define _GET_MESH_X(I) mbl.index_to_xpos[I] + #define _GET_MESH_Y(J) mbl.index_to_ypos[J] + #endif + + set_destination_to_current(); + if (hasI) destination[X_AXIS] = LOGICAL_X_POSITION(_GET_MESH_X(ix)); + if (hasJ) destination[Y_AXIS] = LOGICAL_Y_POSITION(_GET_MESH_Y(iy)); + if (parser.boolval('P')) { + if (hasI) destination[X_AXIS] -= X_PROBE_OFFSET_FROM_EXTRUDER; + if (hasJ) destination[Y_AXIS] -= Y_PROBE_OFFSET_FROM_EXTRUDER; + } + + const float fval = parser.linearval('F'); + if (fval > 0.0) feedrate_mm_s = MMM_TO_MMS(fval); + + // SCARA kinematic has "safe" XY raw moves + #if IS_SCARA + prepare_uninterpolated_move_to_destination(); + #else + prepare_move_to_destination(); + #endif + } + } + +#endif // AUTO_BED_LEVELING_UBL + +/** + * G92: Set current position to given X Y Z E + */ +inline void gcode_G92() { + bool didXYZ = false, + didE = parser.seenval('E'); + + if (!didE) stepper.synchronize(); + + LOOP_XYZE(i) { + if (parser.seenval(axis_codes[i])) { + #if IS_SCARA + current_position[i] = parser.value_axis_units((AxisEnum)i); + if (i != E_AXIS) didXYZ = true; + #else + #if HAS_POSITION_SHIFT + const float p = current_position[i]; + #endif + const float v = parser.value_axis_units((AxisEnum)i); + + current_position[i] = v; + + if (i != E_AXIS) { + didXYZ = true; + #if HAS_POSITION_SHIFT + position_shift[i] += v - p; // Offset the coordinate space + update_software_endstops((AxisEnum)i); + + #if ENABLED(I2C_POSITION_ENCODERS) + I2CPEM.encoders[I2CPEM.idx_from_axis((AxisEnum)i)].set_axis_offset(position_shift[i]); + #endif + + #endif + } + #endif + } + } + if (didXYZ) + SYNC_PLAN_POSITION_KINEMATIC(); + else if (didE) + sync_plan_position_e(); + + report_current_position(); +} + +#if HAS_RESUME_CONTINUE + + /** + * M0: Unconditional stop - Wait for user button press on LCD + * M1: Conditional stop - Wait for user button press on LCD + */ + inline void gcode_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; + } + + #if ENABLED(ULTIPANEL) + + if (!hasP && !hasS && args && *args) + lcd_setstatus(args, true); + else { + LCD_MESSAGEPGM(MSG_USERWAIT); + #if ENABLED(LCD_PROGRESS_BAR) && PROGRESS_MSG_EXPIRE > 0 + dontExpireStatus(); + #endif + } + + #else + + if (!hasP && !hasS && args && *args) { + SERIAL_ECHO_START(); + SERIAL_ECHOLN(args); + } + + #endif + + KEEPALIVE_STATE(PAUSED_FOR_USER); + wait_for_user = true; + + stepper.synchronize(); + refresh_cmd_timeout(); + + if (ms > 0) { + ms += previous_cmd_ms; // wait until this time for a click + while (PENDING(millis(), ms) && wait_for_user) idle(); + } + else { + #if ENABLED(ULTIPANEL) + if (lcd_detected()) { + while (wait_for_user) idle(); + IS_SD_PRINTING ? LCD_MESSAGEPGM(MSG_RESUMING) : LCD_MESSAGEPGM(WELCOME_MSG); + } + #else + while (wait_for_user) idle(); + #endif + } + + wait_for_user = false; + KEEPALIVE_STATE(IN_HANDLER); + } + +#endif // HAS_RESUME_CONTINUE + +#if ENABLED(SPINDLE_LASER_ENABLE) + /** + * M3: Spindle Clockwise + * M4: Spindle Counter-clockwise + * + * S0 turns off spindle. + * + * If no speed PWM output is defined then M3/M4 just turns it on. + * + * At least 12.8KHz (50Hz * 256) is needed for spindle PWM. + * Hardware PWM is required. ISRs are too slow. + * + * NOTE: WGM for timers 3, 4, and 5 must be either Mode 1 or Mode 5. + * No other settings give a PWM signal that goes from 0 to 5 volts. + * + * The system automatically sets WGM to Mode 1, so no special + * initialization is needed. + * + * WGM bits for timer 2 are automatically set by the system to + * Mode 1. This produces an acceptable 0 to 5 volt signal. + * No special initialization is needed. + * + * NOTE: A minimum PWM frequency of 50 Hz is needed. All prescaler + * factors for timers 2, 3, 4, and 5 are acceptable. + * + * SPINDLE_LASER_ENABLE_PIN needs an external pullup or it may power on + * the spindle/laser during power-up or when connecting to the host + * (usually goes through a reset which sets all I/O pins to tri-state) + * + * PWM duty cycle goes from 0 (off) to 255 (always on). + */ + + // Wait for spindle to come up to speed + inline void delay_for_power_up() { dwell(SPINDLE_LASER_POWERUP_DELAY); } + + // Wait for spindle to stop turning + inline void delay_for_power_down() { dwell(SPINDLE_LASER_POWERDOWN_DELAY); } + + /** + * 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 + */ + + inline void ocr_val_mode() { + uint8_t spindle_laser_power = parser.value_byte(); + WRITE(SPINDLE_LASER_ENABLE_PIN, SPINDLE_LASER_ENABLE_INVERT); // turn spindle on (active low) + if (SPINDLE_LASER_PWM_INVERT) spindle_laser_power = 255 - spindle_laser_power; + analogWrite(SPINDLE_LASER_PWM_PIN, spindle_laser_power); + } + + inline void gcode_M3_M4(bool is_M3) { + + stepper.synchronize(); // wait until previous movement commands (G0/G0/G2/G3) have completed before playing with the spindle + #if SPINDLE_DIR_CHANGE + const bool rotation_dir = (is_M3 && !SPINDLE_INVERT_DIR || !is_M3 && SPINDLE_INVERT_DIR) ? HIGH : LOW; + if (SPINDLE_STOP_ON_DIR_CHANGE \ + && READ(SPINDLE_LASER_ENABLE_PIN) == SPINDLE_LASER_ENABLE_INVERT \ + && READ(SPINDLE_DIR_PIN) != rotation_dir + ) { + WRITE(SPINDLE_LASER_ENABLE_PIN, !SPINDLE_LASER_ENABLE_INVERT); // turn spindle off + delay_for_power_down(); + } + WRITE(SPINDLE_DIR_PIN, rotation_dir); + #endif + + /** + * Our final value for ocr_val is an unsigned 8 bit value between 0 and 255 which usually means uint8_t. + * Went to uint16_t because some of the uint8_t calculations would sometimes give 1000 0000 rather than 1111 1111. + * Then needed to AND the uint16_t result with 0x00FF to make sure we only wrote the byte of interest. + */ + #if ENABLED(SPINDLE_LASER_PWM) + if (parser.seen('O')) ocr_val_mode(); + else { + const float spindle_laser_power = parser.floatval('S'); + if (spindle_laser_power == 0) { + WRITE(SPINDLE_LASER_ENABLE_PIN, !SPINDLE_LASER_ENABLE_INVERT); // turn spindle off (active low) + delay_for_power_down(); + } + else { + int16_t ocr_val = (spindle_laser_power - (SPEED_POWER_INTERCEPT)) * (1.0 / (SPEED_POWER_SLOPE)); // convert RPM to PWM duty cycle + NOMORE(ocr_val, 255); // limit to max the Atmel PWM will support + if (spindle_laser_power <= SPEED_POWER_MIN) + ocr_val = (SPEED_POWER_MIN - (SPEED_POWER_INTERCEPT)) * (1.0 / (SPEED_POWER_SLOPE)); // minimum setting + if (spindle_laser_power >= SPEED_POWER_MAX) + ocr_val = (SPEED_POWER_MAX - (SPEED_POWER_INTERCEPT)) * (1.0 / (SPEED_POWER_SLOPE)); // limit to max RPM + if (SPINDLE_LASER_PWM_INVERT) ocr_val = 255 - ocr_val; + WRITE(SPINDLE_LASER_ENABLE_PIN, SPINDLE_LASER_ENABLE_INVERT); // turn spindle on (active low) + analogWrite(SPINDLE_LASER_PWM_PIN, ocr_val & 0xFF); // only write low byte + delay_for_power_up(); + } + } + #else + WRITE(SPINDLE_LASER_ENABLE_PIN, SPINDLE_LASER_ENABLE_INVERT); // turn spindle on (active low) if spindle speed option not enabled + delay_for_power_up(); + #endif + } + + /** + * M5 turn off spindle + */ + inline void gcode_M5() { + stepper.synchronize(); + WRITE(SPINDLE_LASER_ENABLE_PIN, !SPINDLE_LASER_ENABLE_INVERT); + delay_for_power_down(); + } + +#endif // SPINDLE_LASER_ENABLE + +/** + * M17: Enable power on all stepper motors + */ +inline void gcode_M17() { + LCD_MESSAGEPGM(MSG_NO_MOVE); + enable_all_steppers(); +} + +#if IS_KINEMATIC + #define RUNPLAN(RATE_MM_S) planner.buffer_line_kinematic(destination, RATE_MM_S, active_extruder) +#else + #define RUNPLAN(RATE_MM_S) line_to_destination(RATE_MM_S) +#endif + +#if ENABLED(ADVANCED_PAUSE_FEATURE) + + static float resume_position[XYZE]; + static bool move_away_flag = false; + #if ENABLED(SDSUPPORT) + static bool sd_print_paused = false; + #endif + + static void filament_change_beep(const int8_t max_beep_count, const bool init=false) { + static millis_t next_buzz = 0; + static int8_t runout_beep = 0; + + if (init) next_buzz = runout_beep = 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) ? 2500 : 400); + BUZZ(300, 2000); + runout_beep++; + } + } + } + + static void ensure_safe_temperature() { + bool heaters_heating = true; + + wait_for_heatup = true; // M108 will clear this + while (wait_for_heatup && heaters_heating) { + idle(); + heaters_heating = false; + HOTEND_LOOP() { + if (thermalManager.degTargetHotend(e) && abs(thermalManager.degHotend(e) - thermalManager.degTargetHotend(e)) > TEMP_HYSTERESIS) { + heaters_heating = true; + #if ENABLED(ULTIPANEL) + lcd_advanced_pause_show_message(ADVANCED_PAUSE_MESSAGE_WAIT_FOR_NOZZLES_TO_HEAT); + #endif + break; + } + } + } + } + + static bool pause_print(const float &retract, const float &z_lift, const float &x_pos, const float &y_pos, + const float &unload_length = 0 , const int8_t max_beep_count = 0, const bool show_lcd = false + ) { + if (move_away_flag) return false; // already paused + + if (!DEBUGGING(DRYRUN) && (unload_length != 0 || retract != 0)) { + #if ENABLED(PREVENT_COLD_EXTRUSION) + if (!thermalManager.allow_cold_extrude && + thermalManager.degTargetHotend(active_extruder) < thermalManager.extrude_min_temp) { + SERIAL_ERROR_START(); + SERIAL_ERRORLNPGM(MSG_TOO_COLD_FOR_M600); + return false; + } + #endif + + ensure_safe_temperature(); // wait for extruder to heat up before unloading + } + + // Indicate that the printer is paused + move_away_flag = true; + + // Pause the print job and timer + #if ENABLED(SDSUPPORT) + if (card.sdprinting) { + card.pauseSDPrint(); + sd_print_paused = true; + } + #endif + print_job_timer.pause(); + + // Show initial message and wait for synchronize steppers + if (show_lcd) { + #if ENABLED(ULTIPANEL) + lcd_advanced_pause_show_message(ADVANCED_PAUSE_MESSAGE_INIT); + #endif + } + + // Save current position + stepper.synchronize(); + COPY(resume_position, current_position); + + if (retract) { + // Initial retract before move to filament change position + set_destination_to_current(); + destination[E_AXIS] += retract; + RUNPLAN(PAUSE_PARK_RETRACT_FEEDRATE); + stepper.synchronize(); + } + + // Lift Z axis + if (z_lift > 0) + do_blocking_move_to_z(current_position[Z_AXIS] + z_lift, PAUSE_PARK_Z_FEEDRATE); + + // Move XY axes to filament exchange position + do_blocking_move_to_xy(x_pos, y_pos, PAUSE_PARK_XY_FEEDRATE); + + if (unload_length != 0) { + if (show_lcd) { + #if ENABLED(ULTIPANEL) + lcd_advanced_pause_show_message(ADVANCED_PAUSE_MESSAGE_UNLOAD); + idle(); + #endif + } + + // Unload filament + set_destination_to_current(); + destination[E_AXIS] += unload_length; + RUNPLAN(FILAMENT_CHANGE_UNLOAD_FEEDRATE); + stepper.synchronize(); + } + + if (show_lcd) { + #if ENABLED(ULTIPANEL) + lcd_advanced_pause_show_message(ADVANCED_PAUSE_MESSAGE_INSERT); + #endif + } + + #if HAS_BUZZER + filament_change_beep(max_beep_count, true); + #endif + + idle(); + + // Disable extruders steppers for manual filament changing (only on boards that have separate ENABLE_PINS) + #if E0_ENABLE_PIN != X_ENABLE_PIN && E1_ENABLE_PIN != Y_ENABLE_PIN + disable_e_steppers(); + safe_delay(100); + #endif + + // Start the heater idle timers + const millis_t nozzle_timeout = (millis_t)(PAUSE_PARK_NOZZLE_TIMEOUT) * 1000UL; + + HOTEND_LOOP() + thermalManager.start_heater_idle_timer(e, nozzle_timeout); + + return true; + } + + static void wait_for_filament_reload(const int8_t max_beep_count = 0) { + bool nozzle_timed_out = false; + + // Wait for filament insert by user and press button + KEEPALIVE_STATE(PAUSED_FOR_USER); + wait_for_user = true; // LCD click or M108 will clear this + while (wait_for_user) { + #if HAS_BUZZER + filament_change_beep(max_beep_count); + #endif + + // If the nozzle has timed out, wait for the user to press the button to re-heat the nozzle, then + // re-heat the nozzle, re-show the insert screen, restart the idle timers, and start over + if (!nozzle_timed_out) + HOTEND_LOOP() + nozzle_timed_out |= thermalManager.is_heater_idle(e); + + if (nozzle_timed_out) { + #if ENABLED(ULTIPANEL) + lcd_advanced_pause_show_message(ADVANCED_PAUSE_MESSAGE_CLICK_TO_HEAT_NOZZLE); + #endif + + // Wait for LCD click or M108 + while (wait_for_user) idle(true); + + // Re-enable the heaters if they timed out + HOTEND_LOOP() thermalManager.reset_heater_idle_timer(e); + + // Wait for the heaters to reach the target temperatures + ensure_safe_temperature(); + + #if ENABLED(ULTIPANEL) + lcd_advanced_pause_show_message(ADVANCED_PAUSE_MESSAGE_INSERT); + #endif + + // Start the heater idle timers + const millis_t nozzle_timeout = (millis_t)(PAUSE_PARK_NOZZLE_TIMEOUT) * 1000UL; + + HOTEND_LOOP() + thermalManager.start_heater_idle_timer(e, nozzle_timeout); + + wait_for_user = true; /* Wait for user to load filament */ + nozzle_timed_out = false; + + #if HAS_BUZZER + filament_change_beep(max_beep_count, true); + #endif + } + + idle(true); + } + KEEPALIVE_STATE(IN_HANDLER); + } + + static void resume_print(const float &load_length = 0, const float &initial_extrude_length = 0, const int8_t max_beep_count = 0) { + bool nozzle_timed_out = false; + + if (!move_away_flag) return; + + // Re-enable the heaters if they timed out + HOTEND_LOOP() { + nozzle_timed_out |= thermalManager.is_heater_idle(e); + thermalManager.reset_heater_idle_timer(e); + } + + if (nozzle_timed_out) ensure_safe_temperature(); + + #if HAS_BUZZER + filament_change_beep(max_beep_count, true); + #endif + + set_destination_to_current(); + + if (load_length != 0) { + #if ENABLED(ULTIPANEL) + // Show "insert filament" + if (nozzle_timed_out) + lcd_advanced_pause_show_message(ADVANCED_PAUSE_MESSAGE_INSERT); + #endif + + KEEPALIVE_STATE(PAUSED_FOR_USER); + wait_for_user = true; // LCD click or M108 will clear this + while (wait_for_user && nozzle_timed_out) { + #if HAS_BUZZER + filament_change_beep(max_beep_count); + #endif + idle(true); + } + KEEPALIVE_STATE(IN_HANDLER); + + #if ENABLED(ULTIPANEL) + // Show "load" message + lcd_advanced_pause_show_message(ADVANCED_PAUSE_MESSAGE_LOAD); + #endif + + // Load filament + destination[E_AXIS] += load_length; + RUNPLAN(FILAMENT_CHANGE_LOAD_FEEDRATE); + stepper.synchronize(); + } + + #if ENABLED(ULTIPANEL) && ADVANCED_PAUSE_EXTRUDE_LENGTH > 0 + + float extrude_length = initial_extrude_length; + + do { + if (extrude_length > 0) { + // "Wait for filament extrude" + lcd_advanced_pause_show_message(ADVANCED_PAUSE_MESSAGE_EXTRUDE); + + // Extrude filament to get into hotend + destination[E_AXIS] += extrude_length; + RUNPLAN(ADVANCED_PAUSE_EXTRUDE_FEEDRATE); + stepper.synchronize(); + } + + // Show "Extrude More" / "Resume" menu and wait for reply + KEEPALIVE_STATE(PAUSED_FOR_USER); + wait_for_user = false; + lcd_advanced_pause_show_message(ADVANCED_PAUSE_MESSAGE_OPTION); + while (advanced_pause_menu_response == ADVANCED_PAUSE_RESPONSE_WAIT_FOR) idle(true); + KEEPALIVE_STATE(IN_HANDLER); + + extrude_length = ADVANCED_PAUSE_EXTRUDE_LENGTH; + + // Keep looping if "Extrude More" was selected + } while (advanced_pause_menu_response == ADVANCED_PAUSE_RESPONSE_EXTRUDE_MORE); + + #endif + + #if ENABLED(ULTIPANEL) + // "Wait for print to resume" + lcd_advanced_pause_show_message(ADVANCED_PAUSE_MESSAGE_RESUME); + #endif + + // Set extruder to saved position + destination[E_AXIS] = current_position[E_AXIS] = resume_position[E_AXIS]; + planner.set_e_position_mm(current_position[E_AXIS]); + + // Move XY to starting position, then Z + do_blocking_move_to_xy(resume_position[X_AXIS], resume_position[Y_AXIS], PAUSE_PARK_XY_FEEDRATE); + do_blocking_move_to_z(resume_position[Z_AXIS], PAUSE_PARK_Z_FEEDRATE); + + #if ENABLED(FILAMENT_RUNOUT_SENSOR) + filament_ran_out = false; + #endif + + #if ENABLED(ULTIPANEL) + // Show status screen + lcd_advanced_pause_show_message(ADVANCED_PAUSE_MESSAGE_STATUS); + #endif + + #if ENABLED(SDSUPPORT) + if (sd_print_paused) { + card.startFileprint(); + sd_print_paused = false; + } + #endif + + move_away_flag = false; + } +#endif // ADVANCED_PAUSE_FEATURE + +#if ENABLED(SDSUPPORT) + + /** + * M20: List SD card to serial output + */ + inline void gcode_M20() { + SERIAL_PROTOCOLLNPGM(MSG_BEGIN_FILE_LIST); + card.ls(); + SERIAL_PROTOCOLLNPGM(MSG_END_FILE_LIST); + } + + /** + * M21: Init SD Card + */ + inline void gcode_M21() { card.initsd(); } + + /** + * M22: Release SD Card + */ + inline void gcode_M22() { card.release(); } + + /** + * M23: Open a file + */ + inline void gcode_M23() { + // Simplify3D includes the size, so zero out all spaces (#7227) + for (char *fn = parser.string_arg; *fn; ++fn) if (*fn == ' ') *fn = '\0'; + card.openFile(parser.string_arg, true); + } + + /** + * M24: Start or Resume SD Print + */ + inline void gcode_M24() { + #if ENABLED(PARK_HEAD_ON_PAUSE) + resume_print(); + #endif + + card.startFileprint(); + print_job_timer.start(); + } + + /** + * M25: Pause SD Print + */ + inline void gcode_M25() { + card.pauseSDPrint(); + print_job_timer.pause(); + + #if ENABLED(PARK_HEAD_ON_PAUSE) + enqueue_and_echo_commands_P(PSTR("M125")); // Must be enqueued with pauseSDPrint set to be last in the buffer + #endif + } + + /** + * M26: Set SD Card file index + */ + inline void gcode_M26() { + if (card.cardOK && parser.seenval('S')) + card.setIndex(parser.value_long()); + } + + /** + * M27: Get SD Card status + */ + inline void gcode_M27() { card.getStatus(); } + + /** + * M28: Start SD Write + */ + inline void gcode_M28() { card.openFile(parser.string_arg, false); } + + /** + * M29: Stop SD Write + * Processed in write to file routine above + */ + inline void gcode_M29() { + // card.saving = false; + } + + /** + * M30 : Delete SD Card file + */ + inline void gcode_M30() { + if (card.cardOK) { + card.closefile(); + card.removeFile(parser.string_arg); + } + } + +#endif // SDSUPPORT + +/** + * M31: Get the time since the start of SD Print (or last M109) + */ +inline void gcode_M31() { + char buffer[21]; + duration_t elapsed = print_job_timer.duration(); + elapsed.toString(buffer); + lcd_setstatus(buffer); + + SERIAL_ECHO_START(); + SERIAL_ECHOLNPAIR("Print time: ", buffer); +} + +#if ENABLED(SDSUPPORT) + + /** + * M32: Select file and start SD Print + */ + inline void gcode_M32() { + if (card.sdprinting) + stepper.synchronize(); + + char* namestartpos = parser.string_arg; + const bool call_procedure = parser.boolval('P'); + + if (card.cardOK) { + card.openFile(namestartpos, true, call_procedure); + + if (parser.seenval('S')) + card.setIndex(parser.value_long()); + + card.startFileprint(); + + // Procedure calls count as normal print time. + if (!call_procedure) print_job_timer.start(); + } + } + + #if ENABLED(LONG_FILENAME_HOST_SUPPORT) + + /** + * M33: Get the long full path of a file or folder + * + * Parameters: + * Case-insensitive DOS-style path to a file or folder + * + * Example: + * M33 miscel~1/armchair/armcha~1.gco + * + * Output: + * /Miscellaneous/Armchair/Armchair.gcode + */ + inline void gcode_M33() { + card.printLongPath(parser.string_arg); + } + + #endif + + #if ENABLED(SDCARD_SORT_ALPHA) && ENABLED(SDSORT_GCODE) + /** + * M34: Set SD Card Sorting Options + */ + inline void gcode_M34() { + if (parser.seen('S')) card.setSortOn(parser.value_bool()); + if (parser.seenval('F')) { + const int v = parser.value_long(); + card.setSortFolders(v < 0 ? -1 : v > 0 ? 1 : 0); + } + //if (parser.seen('R')) card.setSortReverse(parser.value_bool()); + } + #endif // SDCARD_SORT_ALPHA && SDSORT_GCODE + + /** + * M928: Start SD Write + */ + inline void gcode_M928() { + card.openLogFile(parser.string_arg); + } + +#endif // SDSUPPORT + +/** + * Sensitive pin test for M42, M226 + */ +static bool pin_is_protected(const int8_t pin) { + static const int8_t sensitive_pins[] PROGMEM = SENSITIVE_PINS; + for (uint8_t i = 0; i < COUNT(sensitive_pins); i++) + if (pin == (int8_t)pgm_read_byte(&sensitive_pins[i])) return true; + return false; +} + +/** + * M42: Change pin status via GCode + * + * P Pin number (LED if omitted) + * S Pin status from 0 - 255 + */ +inline void gcode_M42() { + if (!parser.seenval('S')) return; + const byte pin_status = parser.value_byte(); + + const int pin_number = parser.intval('P', LED_PIN); + if (pin_number < 0) return; + + if (pin_is_protected(pin_number)) { + SERIAL_ERROR_START(); + SERIAL_ERRORLNPGM(MSG_ERR_PROTECTED_PIN); + return; + } + + pinMode(pin_number, OUTPUT); + digitalWrite(pin_number, pin_status); + analogWrite(pin_number, pin_status); + + #if FAN_COUNT > 0 + switch (pin_number) { + #if HAS_FAN0 + case FAN_PIN: fanSpeeds[0] = pin_status; break; + #endif + #if HAS_FAN1 + case FAN1_PIN: fanSpeeds[1] = pin_status; break; + #endif + #if HAS_FAN2 + case FAN2_PIN: fanSpeeds[2] = pin_status; break; + #endif + } + #endif +} + +#if ENABLED(PINS_DEBUGGING) + + #include "pinsDebug.h" + + inline void toggle_pins() { + const bool I_flag = parser.boolval('I'); + const int repeat = parser.intval('R', 1), + start = parser.intval('S'), + end = parser.intval('E', NUM_DIGITAL_PINS - 1), + wait = parser.intval('W', 500); + + for (uint8_t pin = start; pin <= end; pin++) { + //report_pin_state_extended(pin, I_flag, false); + + if (!I_flag && pin_is_protected(pin)) { + report_pin_state_extended(pin, I_flag, true, "Untouched "); + SERIAL_EOL(); + } + else { + report_pin_state_extended(pin, I_flag, true, "Pulsing "); + #if AVR_AT90USB1286_FAMILY // Teensy IDEs don't know about these pins so must use FASTIO + if (pin == TEENSY_E2) { + SET_OUTPUT(TEENSY_E2); + for (int16_t j = 0; j < repeat; j++) { + WRITE(TEENSY_E2, LOW); safe_delay(wait); + WRITE(TEENSY_E2, HIGH); safe_delay(wait); + WRITE(TEENSY_E2, LOW); safe_delay(wait); + } + } + else if (pin == TEENSY_E3) { + SET_OUTPUT(TEENSY_E3); + for (int16_t j = 0; j < repeat; j++) { + WRITE(TEENSY_E3, LOW); safe_delay(wait); + WRITE(TEENSY_E3, HIGH); safe_delay(wait); + WRITE(TEENSY_E3, LOW); safe_delay(wait); + } + } + else + #endif + { + pinMode(pin, OUTPUT); + for (int16_t j = 0; j < repeat; j++) { + digitalWrite(pin, 0); safe_delay(wait); + digitalWrite(pin, 1); safe_delay(wait); + digitalWrite(pin, 0); safe_delay(wait); + } + } + + } + SERIAL_EOL(); + } + SERIAL_ECHOLNPGM("Done."); + + } // toggle_pins + + inline void servo_probe_test() { + #if !(NUM_SERVOS > 0 && HAS_SERVO_0) + + SERIAL_ERROR_START(); + SERIAL_ERRORLNPGM("SERVO not setup"); + + #elif !HAS_Z_SERVO_ENDSTOP + + SERIAL_ERROR_START(); + SERIAL_ERRORLNPGM("Z_ENDSTOP_SERVO_NR not setup"); + + #else // HAS_Z_SERVO_ENDSTOP + + const uint8_t probe_index = parser.byteval('P', Z_ENDSTOP_SERVO_NR); + + SERIAL_PROTOCOLLNPGM("Servo probe test"); + SERIAL_PROTOCOLLNPAIR(". using index: ", probe_index); + SERIAL_PROTOCOLLNPAIR(". deploy angle: ", z_servo_angle[0]); + SERIAL_PROTOCOLLNPAIR(". stow angle: ", z_servo_angle[1]); + + bool probe_inverting; + + #if ENABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN) + + #define PROBE_TEST_PIN Z_MIN_PIN + + SERIAL_PROTOCOLLNPAIR(". probe uses Z_MIN pin: ", PROBE_TEST_PIN); + SERIAL_PROTOCOLLNPGM(". uses Z_MIN_ENDSTOP_INVERTING (ignores Z_MIN_PROBE_ENDSTOP_INVERTING)"); + SERIAL_PROTOCOLPGM(". Z_MIN_ENDSTOP_INVERTING: "); + + #if Z_MIN_ENDSTOP_INVERTING + SERIAL_PROTOCOLLNPGM("true"); + #else + SERIAL_PROTOCOLLNPGM("false"); + #endif + + probe_inverting = Z_MIN_ENDSTOP_INVERTING; + + #elif ENABLED(Z_MIN_PROBE_ENDSTOP) + + #define PROBE_TEST_PIN Z_MIN_PROBE_PIN + SERIAL_PROTOCOLLNPAIR(". probe uses Z_MIN_PROBE_PIN: ", PROBE_TEST_PIN); + SERIAL_PROTOCOLLNPGM(". uses Z_MIN_PROBE_ENDSTOP_INVERTING (ignores Z_MIN_ENDSTOP_INVERTING)"); + SERIAL_PROTOCOLPGM(". Z_MIN_PROBE_ENDSTOP_INVERTING: "); + + #if Z_MIN_PROBE_ENDSTOP_INVERTING + SERIAL_PROTOCOLLNPGM("true"); + #else + SERIAL_PROTOCOLLNPGM("false"); + #endif + + probe_inverting = Z_MIN_PROBE_ENDSTOP_INVERTING; + + #endif + + SERIAL_PROTOCOLLNPGM(". deploy & stow 4 times"); + SET_INPUT_PULLUP(PROBE_TEST_PIN); + bool deploy_state, stow_state; + for (uint8_t i = 0; i < 4; i++) { + MOVE_SERVO(probe_index, z_servo_angle[0]); //deploy + safe_delay(500); + deploy_state = READ(PROBE_TEST_PIN); + MOVE_SERVO(probe_index, z_servo_angle[1]); //stow + safe_delay(500); + stow_state = READ(PROBE_TEST_PIN); + } + if (probe_inverting != deploy_state) SERIAL_PROTOCOLLNPGM("WARNING - INVERTING setting probably backwards"); + + refresh_cmd_timeout(); + + if (deploy_state != stow_state) { + SERIAL_PROTOCOLLNPGM("BLTouch clone detected"); + if (deploy_state) { + SERIAL_PROTOCOLLNPGM(". DEPLOYED state: HIGH (logic 1)"); + SERIAL_PROTOCOLLNPGM(". STOWED (triggered) state: LOW (logic 0)"); + } + else { + SERIAL_PROTOCOLLNPGM(". DEPLOYED state: LOW (logic 0)"); + SERIAL_PROTOCOLLNPGM(". STOWED (triggered) state: HIGH (logic 1)"); + } + #if ENABLED(BLTOUCH) + SERIAL_PROTOCOLLNPGM("ERROR: BLTOUCH enabled - set this device up as a Z Servo Probe with inverting as true."); + #endif + + } + else { // measure active signal length + MOVE_SERVO(probe_index, z_servo_angle[0]); // deploy + safe_delay(500); + SERIAL_PROTOCOLLNPGM("please trigger probe"); + uint16_t probe_counter = 0; + + // Allow 30 seconds max for operator to trigger probe + for (uint16_t j = 0; j < 500 * 30 && probe_counter == 0 ; j++) { + + safe_delay(2); + + if (0 == j % (500 * 1)) // keep cmd_timeout happy + refresh_cmd_timeout(); + + if (deploy_state != READ(PROBE_TEST_PIN)) { // probe triggered + + for (probe_counter = 1; probe_counter < 50 && deploy_state != READ(PROBE_TEST_PIN); ++probe_counter) + safe_delay(2); + + if (probe_counter == 50) + SERIAL_PROTOCOLLNPGM("Z Servo Probe detected"); // >= 100mS active time + else if (probe_counter >= 2) + SERIAL_PROTOCOLLNPAIR("BLTouch compatible probe detected - pulse width (+/- 4mS): ", probe_counter * 2); // allow 4 - 100mS pulse + else + SERIAL_PROTOCOLLNPGM("noise detected - please re-run test"); // less than 2mS pulse + + MOVE_SERVO(probe_index, z_servo_angle[1]); //stow + + } // pulse detected + + } // for loop waiting for trigger + + if (probe_counter == 0) SERIAL_PROTOCOLLNPGM("trigger not detected"); + + } // measure active signal length + + #endif + + } // servo_probe_test + + /** + * M43: Pin debug - report pin state, watch pins, toggle pins and servo probe test/report + * + * M43 - report name and state of pin(s) + * P Pin to read or watch. If omitted, reads all pins. + * I Flag to ignore Marlin's pin protection. + * + * M43 W - Watch pins -reporting changes- until reset, click, or M108. + * P Pin to read or watch. If omitted, read/watch all pins. + * I Flag to ignore Marlin's pin protection. + * + * M43 E - Enable / disable background endstop monitoring + * - Machine continues to operate + * - Reports changes to endstops + * - Toggles LED_PIN when an endstop changes + * - Can not reliably catch the 5mS pulse from BLTouch type probes + * + * M43 T - Toggle pin(s) and report which pin is being toggled + * S - Start Pin number. If not given, will default to 0 + * L - End Pin number. If not given, will default to last pin defined for this board + * I - Flag to ignore Marlin's pin protection. Use with caution!!!! + * R - Repeat pulses on each pin this number of times before continueing to next pin + * W - Wait time (in miliseconds) between pulses. If not given will default to 500 + * + * M43 S - Servo probe test + * P - Probe index (optional - defaults to 0 + */ + inline void gcode_M43() { + + if (parser.seen('T')) { // must be first or else its "S" and "E" parameters will execute endstop or servo test + toggle_pins(); + return; + } + + // Enable or disable endstop monitoring + if (parser.seen('E')) { + endstop_monitor_flag = parser.value_bool(); + SERIAL_PROTOCOLPGM("endstop monitor "); + serialprintPGM(endstop_monitor_flag ? PSTR("en") : PSTR("dis")); + SERIAL_PROTOCOLLNPGM("abled"); + return; + } + + if (parser.seen('S')) { + servo_probe_test(); + return; + } + + // Get the range of pins to test or watch + const uint8_t first_pin = parser.byteval('P'), + last_pin = parser.seenval('P') ? first_pin : NUM_DIGITAL_PINS - 1; + + if (first_pin > last_pin) return; + + const bool ignore_protection = parser.boolval('I'); + + // Watch until click, M108, or reset + if (parser.boolval('W')) { + SERIAL_PROTOCOLLNPGM("Watching pins"); + byte pin_state[last_pin - first_pin + 1]; + for (int8_t pin = first_pin; pin <= last_pin; pin++) { + if (pin_is_protected(pin) && !ignore_protection) continue; + pinMode(pin, INPUT_PULLUP); + delay(1); + /* + if (IS_ANALOG(pin)) + pin_state[pin - first_pin] = analogRead(pin - analogInputToDigitalPin(0)); // int16_t pin_state[...] + else + //*/ + pin_state[pin - first_pin] = digitalRead(pin); + } + + #if HAS_RESUME_CONTINUE + wait_for_user = true; + KEEPALIVE_STATE(PAUSED_FOR_USER); + #endif + + for (;;) { + for (int8_t pin = first_pin; pin <= last_pin; pin++) { + if (pin_is_protected(pin) && !ignore_protection) continue; + const byte val = + /* + IS_ANALOG(pin) + ? analogRead(pin - analogInputToDigitalPin(0)) : // int16_t val + : + //*/ + digitalRead(pin); + if (val != pin_state[pin - first_pin]) { + report_pin_state_extended(pin, ignore_protection, false); + pin_state[pin - first_pin] = val; + } + } + + #if HAS_RESUME_CONTINUE + if (!wait_for_user) { + KEEPALIVE_STATE(IN_HANDLER); + break; + } + #endif + + safe_delay(200); + } + return; + } + + // Report current state of selected pin(s) + for (uint8_t pin = first_pin; pin <= last_pin; pin++) + report_pin_state_extended(pin, ignore_protection, true); + } + +#endif // PINS_DEBUGGING + +#if ENABLED(Z_MIN_PROBE_REPEATABILITY_TEST) + + /** + * M48: Z probe repeatability measurement function. + * + * Usage: + * M48 + * P = Number of sampled points (4-50, default 10) + * X = Sample X position + * Y = Sample Y position + * V = Verbose level (0-4, default=1) + * E = Engage Z probe for each reading + * L = Number of legs of movement before probe + * S = Schizoid (Or Star if you prefer) + * + * This function assumes the bed has been homed. Specifically, that a G28 command + * as been issued prior to invoking the M48 Z probe repeatability measurement function. + * Any information generated by a prior G29 Bed leveling command will be lost and need to be + * regenerated. + */ + inline void gcode_M48() { + + if (axis_unhomed_error()) return; + + const int8_t verbose_level = parser.byteval('V', 1); + if (!WITHIN(verbose_level, 0, 4)) { + SERIAL_PROTOCOLLNPGM("?(V)erbose level is implausible (0-4)."); + return; + } + + if (verbose_level > 0) + SERIAL_PROTOCOLLNPGM("M48 Z-Probe Repeatability Test"); + + const int8_t n_samples = parser.byteval('P', 10); + if (!WITHIN(n_samples, 4, 50)) { + SERIAL_PROTOCOLLNPGM("?Sample size not plausible (4-50)."); + return; + } + + const bool stow_probe_after_each = parser.boolval('E'); + + float X_current = current_position[X_AXIS], + Y_current = current_position[Y_AXIS]; + + const float X_probe_location = parser.linearval('X', X_current + X_PROBE_OFFSET_FROM_EXTRUDER), + Y_probe_location = parser.linearval('Y', Y_current + Y_PROBE_OFFSET_FROM_EXTRUDER); + + #if DISABLED(DELTA) + if (!WITHIN(X_probe_location, LOGICAL_X_POSITION(MIN_PROBE_X), LOGICAL_X_POSITION(MAX_PROBE_X))) { + out_of_range_error(PSTR("X")); + return; + } + if (!WITHIN(Y_probe_location, LOGICAL_Y_POSITION(MIN_PROBE_Y), LOGICAL_Y_POSITION(MAX_PROBE_Y))) { + out_of_range_error(PSTR("Y")); + return; + } + #else + if (!position_is_reachable_by_probe_xy(X_probe_location, Y_probe_location)) { + SERIAL_PROTOCOLLNPGM("? (X,Y) location outside of probeable radius."); + return; + } + #endif + + bool seen_L = parser.seen('L'); + uint8_t n_legs = seen_L ? parser.value_byte() : 0; + if (n_legs > 15) { + SERIAL_PROTOCOLLNPGM("?Number of legs in movement not plausible (0-15)."); + return; + } + if (n_legs == 1) n_legs = 2; + + 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_PROTOCOLLNPGM("Positioning the probe..."); + + // Disable bed level correction in M48 because we want the raw data when we probe + + #if HAS_LEVELING + const bool was_enabled = leveling_is_active(); + set_bed_leveling_enabled(false); + #endif + + setup_for_endstop_or_probe_move(); + + double mean = 0.0, sigma = 0.0, min = 99999.9, max = -99999.9, sample_set[n_samples]; + + // Move to the first point, deploy, and probe + const float t = probe_pt(X_probe_location, Y_probe_location, stow_probe_after_each, verbose_level); + bool probing_good = !isnan(t); + + if (probing_good) { + randomSeed(millis()); + + for (uint8_t n = 0; n < n_samples; n++) { + if (n_legs) { + const int dir = (random(0, 10) > 5.0) ? -1 : 1; // clockwise or counter clockwise + float angle = random(0.0, 360.0); + const float radius = random( + #if ENABLED(DELTA) + 0.1250000000 * (DELTA_PROBEABLE_RADIUS), + 0.3333333333 * (DELTA_PROBEABLE_RADIUS) + #else + 5.0, 0.125 * min(X_BED_SIZE, Y_BED_SIZE) + #endif + ); + + if (verbose_level > 3) { + SERIAL_ECHOPAIR("Starting radius: ", radius); + SERIAL_ECHOPAIR(" angle: ", angle); + SERIAL_ECHOPGM(" Direction: "); + if (dir > 0) SERIAL_ECHOPGM("Counter-"); + SERIAL_ECHOLNPGM("Clockwise"); + } + + for (uint8_t l = 0; l < n_legs - 1; l++) { + double 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. + 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); + + angle += delta_angle; + + while (angle > 360.0) // We probably do not need to keep the angle between 0 and 2*PI, but the + angle -= 360.0; // Arduino documentation says the trig functions should not be given values + while (angle < 0.0) // outside of this range. It looks like they behave correctly with + angle += 360.0; // numbers outside of the range, but just to be safe we clamp them. + + X_current = X_probe_location - (X_PROBE_OFFSET_FROM_EXTRUDER) + cos(RADIANS(angle)) * radius; + Y_current = Y_probe_location - (Y_PROBE_OFFSET_FROM_EXTRUDER) + sin(RADIANS(angle)) * radius; + + #if DISABLED(DELTA) + X_current = constrain(X_current, X_MIN_POS, X_MAX_POS); + Y_current = constrain(Y_current, 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_xy(X_current, Y_current)) { + X_current *= 0.8; + Y_current *= 0.8; + if (verbose_level > 3) { + SERIAL_ECHOPAIR("Pulling point towards center:", X_current); + SERIAL_ECHOLNPAIR(", ", Y_current); + } + } + #endif + if (verbose_level > 3) { + SERIAL_PROTOCOLPGM("Going to:"); + SERIAL_ECHOPAIR(" X", X_current); + SERIAL_ECHOPAIR(" Y", Y_current); + SERIAL_ECHOLNPAIR(" Z", current_position[Z_AXIS]); + } + do_blocking_move_to_xy(X_current, Y_current); + } // n_legs loop + } // n_legs + + // Probe a single point + sample_set[n] = probe_pt(X_probe_location, Y_probe_location, stow_probe_after_each, 0); + + // Break the loop if the probe fails + probing_good = !isnan(sample_set[n]); + if (!probing_good) break; + + /** + * Get the current mean for the data points we have so far + */ + double 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_PROTOCOL(n + 1); + SERIAL_PROTOCOLPGM(" of "); + SERIAL_PROTOCOL((int)n_samples); + SERIAL_PROTOCOLPGM(": z: "); + SERIAL_PROTOCOL_F(sample_set[n], 3); + if (verbose_level > 2) { + SERIAL_PROTOCOLPGM(" mean: "); + SERIAL_PROTOCOL_F(mean, 4); + SERIAL_PROTOCOLPGM(" sigma: "); + SERIAL_PROTOCOL_F(sigma, 6); + SERIAL_PROTOCOLPGM(" min: "); + SERIAL_PROTOCOL_F(min, 3); + SERIAL_PROTOCOLPGM(" max: "); + SERIAL_PROTOCOL_F(max, 3); + SERIAL_PROTOCOLPGM(" range: "); + SERIAL_PROTOCOL_F(max-min, 3); + } + SERIAL_EOL(); + } + } + + } // n_samples loop + } + + STOW_PROBE(); + + if (probing_good) { + SERIAL_PROTOCOLLNPGM("Finished!"); + + if (verbose_level > 0) { + SERIAL_PROTOCOLPGM("Mean: "); + SERIAL_PROTOCOL_F(mean, 6); + SERIAL_PROTOCOLPGM(" Min: "); + SERIAL_PROTOCOL_F(min, 3); + SERIAL_PROTOCOLPGM(" Max: "); + SERIAL_PROTOCOL_F(max, 3); + SERIAL_PROTOCOLPGM(" Range: "); + SERIAL_PROTOCOL_F(max-min, 3); + SERIAL_EOL(); + } + + SERIAL_PROTOCOLPGM("Standard Deviation: "); + SERIAL_PROTOCOL_F(sigma, 6); + SERIAL_EOL(); + SERIAL_EOL(); + } + + clean_up_after_endstop_or_probe_move(); + + // Re-enable bed level correction if it had been on + #if HAS_LEVELING + set_bed_leveling_enabled(was_enabled); + #endif + + report_current_position(); + } + +#endif // Z_MIN_PROBE_REPEATABILITY_TEST + +#if ENABLED(AUTO_BED_LEVELING_UBL) && ENABLED(UBL_G26_MESH_VALIDATION) + + inline void gcode_M49() { + ubl.g26_debug_flag ^= true; + SERIAL_PROTOCOLPGM("UBL Debug Flag turned "); + serialprintPGM(ubl.g26_debug_flag ? PSTR("on.") : PSTR("off.")); + } + +#endif // AUTO_BED_LEVELING_UBL && UBL_G26_MESH_VALIDATION + +/** + * M75: Start print timer + */ +inline void gcode_M75() { print_job_timer.start(); } + +/** + * M76: Pause print timer + */ +inline void gcode_M76() { print_job_timer.pause(); } + +/** + * M77: Stop print timer + */ +inline void gcode_M77() { print_job_timer.stop(); } + +#if ENABLED(PRINTCOUNTER) + /** + * M78: Show print statistics + */ + inline void gcode_M78() { + // "M78 S78" will reset the statistics + if (parser.intval('S') == 78) + print_job_timer.initStats(); + else + print_job_timer.showStats(); + } +#endif + +/** + * M104: Set hot end temperature + */ +inline void gcode_M104() { + if (get_target_extruder_from_command(104)) return; + if (DEBUGGING(DRYRUN)) return; + + #if ENABLED(SINGLENOZZLE) + if (target_extruder != active_extruder) return; + #endif + + if (parser.seenval('S')) { + const int16_t temp = parser.value_celsius(); + thermalManager.setTargetHotend(temp, target_extruder); + + #if ENABLED(DUAL_X_CARRIAGE) + if (dual_x_carriage_mode == DXC_DUPLICATION_MODE && target_extruder == 0) + thermalManager.setTargetHotend(temp ? temp + duplicate_extruder_temp_offset : 0, 1); + #endif + + #if ENABLED(PRINTJOB_TIMER_AUTOSTART) + /** + * Stop the timer at the end of print. Start is managed by 'heat and wait' M109. + * We use half EXTRUDE_MINTEMP here to allow nozzles to be put into hot + * standby mode, for instance in a dual extruder setup, without affecting + * the running print timer. + */ + if (parser.value_celsius() <= (EXTRUDE_MINTEMP) / 2) { + print_job_timer.stop(); + LCD_MESSAGEPGM(WELCOME_MSG); + } + #endif + + if (parser.value_celsius() > thermalManager.degHotend(target_extruder)) + lcd_status_printf_P(0, PSTR("E%i %s"), target_extruder + 1, MSG_HEATING); + } + + #if ENABLED(AUTOTEMP) + planner.autotemp_M104_M109(); + #endif +} + +#if HAS_TEMP_HOTEND || HAS_TEMP_BED + + void print_heater_state(const float &c, const float &t, + #if ENABLED(SHOW_TEMP_ADC_VALUES) + const float r, + #endif + const int8_t e=-2 + ) { + #if !(HAS_TEMP_BED && HAS_TEMP_HOTEND) && HOTENDS <= 1 + UNUSED(e); + #endif + + SERIAL_PROTOCOLCHAR(' '); + SERIAL_PROTOCOLCHAR( + #if HAS_TEMP_BED && HAS_TEMP_HOTEND + e == -1 ? 'B' : 'T' + #elif HAS_TEMP_HOTEND + 'T' + #else + 'B' + #endif + ); + #if HOTENDS > 1 + if (e >= 0) SERIAL_PROTOCOLCHAR('0' + e); + #endif + SERIAL_PROTOCOLCHAR(':'); + SERIAL_PROTOCOL(c); + SERIAL_PROTOCOLPAIR(" /" , t); + #if ENABLED(SHOW_TEMP_ADC_VALUES) + SERIAL_PROTOCOLPAIR(" (", r / OVERSAMPLENR); + SERIAL_PROTOCOLCHAR(')'); + #endif + } + + void print_heaterstates() { + #if HAS_TEMP_HOTEND + print_heater_state(thermalManager.degHotend(target_extruder), thermalManager.degTargetHotend(target_extruder) + #if ENABLED(SHOW_TEMP_ADC_VALUES) + , thermalManager.rawHotendTemp(target_extruder) + #endif + ); + #endif + #if HAS_TEMP_BED + print_heater_state(thermalManager.degBed(), thermalManager.degTargetBed(), + #if ENABLED(SHOW_TEMP_ADC_VALUES) + thermalManager.rawBedTemp(), + #endif + -1 // BED + ); + #endif + #if HOTENDS > 1 + HOTEND_LOOP() print_heater_state(thermalManager.degHotend(e), thermalManager.degTargetHotend(e), + #if ENABLED(SHOW_TEMP_ADC_VALUES) + thermalManager.rawHotendTemp(e), + #endif + e + ); + #endif + SERIAL_PROTOCOLPGM(" @:"); + SERIAL_PROTOCOL(thermalManager.getHeaterPower(target_extruder)); + #if HAS_TEMP_BED + SERIAL_PROTOCOLPGM(" B@:"); + SERIAL_PROTOCOL(thermalManager.getHeaterPower(-1)); + #endif + #if HOTENDS > 1 + HOTEND_LOOP() { + SERIAL_PROTOCOLPAIR(" @", e); + SERIAL_PROTOCOLCHAR(':'); + SERIAL_PROTOCOL(thermalManager.getHeaterPower(e)); + } + #endif + } +#endif + +/** + * M105: Read hot end and bed temperature + */ +inline void gcode_M105() { + if (get_target_extruder_from_command(105)) return; + + #if HAS_TEMP_HOTEND || HAS_TEMP_BED + SERIAL_PROTOCOLPGM(MSG_OK); + print_heaterstates(); + #else // !HAS_TEMP_HOTEND && !HAS_TEMP_BED + SERIAL_ERROR_START(); + SERIAL_ERRORLNPGM(MSG_ERR_NO_THERMISTORS); + #endif + + SERIAL_EOL(); +} + +#if ENABLED(AUTO_REPORT_TEMPERATURES) && (HAS_TEMP_HOTEND || HAS_TEMP_BED) + + static uint8_t auto_report_temp_interval; + static millis_t next_temp_report_ms; + + /** + * M155: Set temperature auto-report interval. M155 S + */ + inline void gcode_M155() { + if (parser.seenval('S')) { + auto_report_temp_interval = parser.value_byte(); + NOMORE(auto_report_temp_interval, 60); + next_temp_report_ms = millis() + 1000UL * auto_report_temp_interval; + } + } + + inline void auto_report_temperatures() { + if (auto_report_temp_interval && ELAPSED(millis(), next_temp_report_ms)) { + next_temp_report_ms = millis() + 1000UL * auto_report_temp_interval; + print_heaterstates(); + SERIAL_EOL(); + } + } + +#endif // AUTO_REPORT_TEMPERATURES + +#if FAN_COUNT > 0 + + /** + * M106: Set Fan Speed + * + * S Speed between 0-255 + * P Fan index, if more than one fan + */ + inline void gcode_M106() { + uint16_t s = parser.ushortval('S', 255); + NOMORE(s, 255); + const uint8_t p = parser.byteval('P', 0); + if (p < FAN_COUNT) fanSpeeds[p] = s; + } + + /** + * M107: Fan Off + */ + inline void gcode_M107() { + const uint16_t p = parser.ushortval('P'); + if (p < FAN_COUNT) fanSpeeds[p] = 0; + } + +#endif // FAN_COUNT > 0 + +#if DISABLED(EMERGENCY_PARSER) + + /** + * M108: Stop the waiting for heaters in M109, M190, M303. Does not affect the target temperature. + */ + inline void gcode_M108() { wait_for_heatup = false; } + + + /** + * M112: Emergency Stop + */ + inline void gcode_M112() { kill(PSTR(MSG_KILLED)); } + + + /** + * M410: Quickstop - Abort all planned moves + * + * This will stop the carriages mid-move, so most likely they + * will be out of sync with the stepper position after this. + */ + inline void gcode_M410() { quickstop_stepper(); } + +#endif + +/** + * M109: Sxxx Wait for extruder(s) to reach temperature. Waits only when heating. + * Rxxx Wait for extruder(s) to reach temperature. Waits when heating and cooling. + */ + +#ifndef MIN_COOLING_SLOPE_DEG + #define MIN_COOLING_SLOPE_DEG 1.50 +#endif +#ifndef MIN_COOLING_SLOPE_TIME + #define MIN_COOLING_SLOPE_TIME 60 +#endif + +inline void gcode_M109() { + + if (get_target_extruder_from_command(109)) return; + if (DEBUGGING(DRYRUN)) return; + + #if ENABLED(SINGLENOZZLE) + if (target_extruder != active_extruder) return; + #endif + + const bool no_wait_for_cooling = parser.seenval('S'); + if (no_wait_for_cooling || parser.seenval('R')) { + const int16_t temp = parser.value_celsius(); + thermalManager.setTargetHotend(temp, target_extruder); + + #if ENABLED(DUAL_X_CARRIAGE) + if (dual_x_carriage_mode == DXC_DUPLICATION_MODE && target_extruder == 0) + thermalManager.setTargetHotend(temp ? temp + duplicate_extruder_temp_offset : 0, 1); + #endif + + #if ENABLED(PRINTJOB_TIMER_AUTOSTART) + /** + * Use half EXTRUDE_MINTEMP to allow nozzles to be put into hot + * standby mode, (e.g., in a dual extruder setup) without affecting + * the running print timer. + */ + if (parser.value_celsius() <= (EXTRUDE_MINTEMP) / 2) { + print_job_timer.stop(); + LCD_MESSAGEPGM(WELCOME_MSG); + } + else + print_job_timer.start(); + #endif + + if (thermalManager.isHeatingHotend(target_extruder)) lcd_status_printf_P(0, PSTR("E%i %s"), target_extruder + 1, MSG_HEATING); + } + else return; + + #if ENABLED(AUTOTEMP) + planner.autotemp_M104_M109(); + #endif + + #if TEMP_RESIDENCY_TIME > 0 + millis_t residency_start_ms = 0; + // Loop until the temperature has stabilized + #define TEMP_CONDITIONS (!residency_start_ms || PENDING(now, residency_start_ms + (TEMP_RESIDENCY_TIME) * 1000UL)) + #else + // Loop until the temperature is very close target + #define TEMP_CONDITIONS (wants_to_cool ? thermalManager.isCoolingHotend(target_extruder) : thermalManager.isHeatingHotend(target_extruder)) + #endif + + float target_temp = -1.0, old_temp = 9999.0; + 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) + KEEPALIVE_STATE(NOT_BUSY); + #endif + + #if ENABLED(PRINTER_EVENT_LEDS) + const float start_temp = thermalManager.degHotend(target_extruder); + uint8_t old_blue = 0; + #endif + + do { + // Target temperature might be changed during the loop + if (target_temp != thermalManager.degTargetHotend(target_extruder)) { + wants_to_cool = thermalManager.isCoolingHotend(target_extruder); + target_temp = thermalManager.degTargetHotend(target_extruder); + + // Exit if S, continue if S, R, or R + if (no_wait_for_cooling && wants_to_cool) break; + } + + now = millis(); + if (ELAPSED(now, next_temp_ms)) { //Print temp & remaining time every 1s while waiting + next_temp_ms = now + 1000UL; + print_heaterstates(); + #if TEMP_RESIDENCY_TIME > 0 + SERIAL_PROTOCOLPGM(" W:"); + if (residency_start_ms) + SERIAL_PROTOCOL(long((((TEMP_RESIDENCY_TIME) * 1000UL) - (now - residency_start_ms)) / 1000UL)); + else + SERIAL_PROTOCOLCHAR('?'); + #endif + SERIAL_EOL(); + } + + idle(); + refresh_cmd_timeout(); // to prevent stepper_inactive_time from running out + + const float temp = thermalManager.degHotend(target_extruder); + + #if ENABLED(PRINTER_EVENT_LEDS) + // Gradually change LED strip from violet to red as nozzle heats up + if (!wants_to_cool) { + const uint8_t blue = map(constrain(temp, start_temp, target_temp), start_temp, target_temp, 255, 0); + if (blue != old_blue) { + old_blue = blue; + set_led_color(255, 0, blue + #if ENABLED(NEOPIXEL_LED) + , 0 + , pixels.getBrightness() + #if ENABLED(NEOPIXEL_IS_SEQUENTIAL) + , true + #endif + #endif + ); + } + } + #endif + + #if TEMP_RESIDENCY_TIME > 0 + + const float temp_diff = FABS(target_temp - temp); + + 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; + } + else if (temp_diff > TEMP_HYSTERESIS) { + // Restart the timer whenever the temperature falls outside the hysteresis. + residency_start_ms = now; + } + + #endif + + // Prevent a wait-forever situation if R is misused i.e. M109 R0 + if (wants_to_cool) { + // break after MIN_COOLING_SLOPE_TIME seconds + // if the temperature did not drop at least MIN_COOLING_SLOPE_DEG + if (!next_cool_check_ms || ELAPSED(now, next_cool_check_ms)) { + if (old_temp - temp < MIN_COOLING_SLOPE_DEG) break; + next_cool_check_ms = now + 1000UL * MIN_COOLING_SLOPE_TIME; + old_temp = temp; + } + } + + } while (wait_for_heatup && TEMP_CONDITIONS); + + if (wait_for_heatup) { + LCD_MESSAGEPGM(MSG_HEATING_COMPLETE); + #if ENABLED(PRINTER_EVENT_LEDS) + #if ENABLED(RGB_LED) || ENABLED(BLINKM) || ENABLED(PCA9632) || ENABLED(RGBW_LED) + set_led_color(LED_WHITE); + #endif + #if ENABLED(NEOPIXEL_LED) + set_neopixel_color(pixels.Color(NEO_WHITE)); + #endif + #endif + } + + #if DISABLED(BUSY_WHILE_HEATING) + KEEPALIVE_STATE(IN_HANDLER); + #endif +} + +#if HAS_TEMP_BED + + #ifndef MIN_COOLING_SLOPE_DEG_BED + #define MIN_COOLING_SLOPE_DEG_BED 1.50 + #endif + #ifndef MIN_COOLING_SLOPE_TIME_BED + #define MIN_COOLING_SLOPE_TIME_BED 60 + #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 + */ + inline void gcode_M190() { + if (DEBUGGING(DRYRUN)) return; + + LCD_MESSAGEPGM(MSG_BED_HEATING); + 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) + if (parser.value_celsius() > BED_MINTEMP) + print_job_timer.start(); + #endif + } + else return; + + #if TEMP_BED_RESIDENCY_TIME > 0 + millis_t residency_start_ms = 0; + // Loop until the temperature has stabilized + #define TEMP_BED_CONDITIONS (!residency_start_ms || PENDING(now, residency_start_ms + (TEMP_BED_RESIDENCY_TIME) * 1000UL)) + #else + // Loop until the temperature is very close target + #define TEMP_BED_CONDITIONS (wants_to_cool ? thermalManager.isCoolingBed() : thermalManager.isHeatingBed()) + #endif + + float target_temp = -1.0, old_temp = 9999.0; + 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) + KEEPALIVE_STATE(NOT_BUSY); + #endif + + target_extruder = active_extruder; // for print_heaterstates + + #if ENABLED(PRINTER_EVENT_LEDS) + const float start_temp = thermalManager.degBed(); + uint8_t old_red = 255; + #endif + + do { + // Target temperature might be changed during the loop + if (target_temp != thermalManager.degTargetBed()) { + wants_to_cool = thermalManager.isCoolingBed(); + target_temp = thermalManager.degTargetBed(); + + // Exit if S, continue if S, R, or R + if (no_wait_for_cooling && wants_to_cool) break; + } + + now = millis(); + if (ELAPSED(now, next_temp_ms)) { //Print Temp Reading every 1 second while heating up. + next_temp_ms = now + 1000UL; + print_heaterstates(); + #if TEMP_BED_RESIDENCY_TIME > 0 + SERIAL_PROTOCOLPGM(" W:"); + if (residency_start_ms) + SERIAL_PROTOCOL(long((((TEMP_BED_RESIDENCY_TIME) * 1000UL) - (now - residency_start_ms)) / 1000UL)); + else + SERIAL_PROTOCOLCHAR('?'); + #endif + SERIAL_EOL(); + } + + idle(); + refresh_cmd_timeout(); // to prevent stepper_inactive_time from running out + + const float temp = thermalManager.degBed(); + + #if ENABLED(PRINTER_EVENT_LEDS) + // Gradually change LED strip from blue to violet as bed heats up + if (!wants_to_cool) { + const uint8_t red = map(constrain(temp, start_temp, target_temp), start_temp, target_temp, 0, 255); + if (red != old_red) { + old_red = red; + set_led_color(red, 0, 255 + #if ENABLED(NEOPIXEL_LED) + , 0, pixels.getBrightness() + #if ENABLED(NEOPIXEL_IS_SEQUENTIAL) + , true + #endif + #endif + ); + } + } + #endif + + #if TEMP_BED_RESIDENCY_TIME > 0 + + const float temp_diff = FABS(target_temp - temp); + + 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; + } + else if (temp_diff > TEMP_BED_HYSTERESIS) { + // Restart the timer whenever the temperature falls outside the hysteresis. + residency_start_ms = now; + } + + #endif // TEMP_BED_RESIDENCY_TIME > 0 + + // Prevent a wait-forever situation if R is misused i.e. M190 R0 + if (wants_to_cool) { + // Break after MIN_COOLING_SLOPE_TIME_BED seconds + // if the temperature did not drop at least MIN_COOLING_SLOPE_DEG_BED + if (!next_cool_check_ms || ELAPSED(now, next_cool_check_ms)) { + if (old_temp - temp < MIN_COOLING_SLOPE_DEG_BED) break; + next_cool_check_ms = now + 1000UL * MIN_COOLING_SLOPE_TIME_BED; + old_temp = temp; + } + } + + } while (wait_for_heatup && TEMP_BED_CONDITIONS); + + if (wait_for_heatup) LCD_MESSAGEPGM(MSG_BED_DONE); + #if DISABLED(BUSY_WHILE_HEATING) + KEEPALIVE_STATE(IN_HANDLER); + #endif + } + +#endif // HAS_TEMP_BED + +/** + * M110: Set Current Line Number + */ +inline void gcode_M110() { + if (parser.seenval('N')) gcode_LastN = parser.value_long(); +} + +/** + * M111: Set the debug level + */ +inline void gcode_M111() { + if (parser.seen('S')) marlin_debug_flags = parser.byteval('S'); + + const static char str_debug_1[] PROGMEM = MSG_DEBUG_ECHO, + str_debug_2[] PROGMEM = MSG_DEBUG_INFO, + str_debug_4[] PROGMEM = MSG_DEBUG_ERRORS, + str_debug_8[] PROGMEM = MSG_DEBUG_DRYRUN, + str_debug_16[] PROGMEM = MSG_DEBUG_COMMUNICATION + #if ENABLED(DEBUG_LEVELING_FEATURE) + , str_debug_32[] PROGMEM = MSG_DEBUG_LEVELING + #endif + ; + + const static char* 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_32 + #endif + }; + + SERIAL_ECHO_START(); + SERIAL_ECHOPGM(MSG_DEBUG_PREFIX); + if (marlin_debug_flags) { + uint8_t comma = 0; + for (uint8_t i = 0; i < COUNT(debug_strings); i++) { + if (TEST(marlin_debug_flags, i)) { + if (comma++) SERIAL_CHAR(','); + serialprintPGM((char*)pgm_read_word(&debug_strings[i])); + } + } + } + else { + SERIAL_ECHOPGM(MSG_DEBUG_OFF); + } + SERIAL_EOL(); +} + +#if ENABLED(HOST_KEEPALIVE_FEATURE) + + /** + * M113: Get or set Host Keepalive interval (0 to disable) + * + * S Optional. Set the keepalive interval. + */ + inline void gcode_M113() { + if (parser.seenval('S')) { + host_keepalive_interval = parser.value_byte(); + NOMORE(host_keepalive_interval, 60); + } + else { + SERIAL_ECHO_START(); + SERIAL_ECHOLNPAIR("M113 S", (unsigned long)host_keepalive_interval); + } + } + +#endif + +#if ENABLED(BARICUDA) + + #if HAS_HEATER_1 + /** + * M126: Heater 1 valve open + */ + inline void gcode_M126() { baricuda_valve_pressure = parser.byteval('S', 255); } + /** + * M127: Heater 1 valve close + */ + inline void gcode_M127() { baricuda_valve_pressure = 0; } + #endif + + #if HAS_HEATER_2 + /** + * M128: Heater 2 valve open + */ + inline void gcode_M128() { baricuda_e_to_p_pressure = parser.byteval('S', 255); } + /** + * M129: Heater 2 valve close + */ + inline void gcode_M129() { baricuda_e_to_p_pressure = 0; } + #endif + +#endif // BARICUDA + +/** + * M140: Set bed temperature + */ +inline void gcode_M140() { + if (DEBUGGING(DRYRUN)) return; + if (parser.seenval('S')) thermalManager.setTargetBed(parser.value_celsius()); +} + +#if ENABLED(ULTIPANEL) + + /** + * M145: Set the heatup state for a material in the LCD menu + * + * S (0=PLA, 1=ABS) + * H + * B + * F + */ + inline void gcode_M145() { + const uint8_t material = (uint8_t)parser.intval('S'); + if (material >= COUNT(lcd_preheat_hotend_temp)) { + SERIAL_ERROR_START(); + SERIAL_ERRORLNPGM(MSG_ERR_MATERIAL_INDEX); + } + else { + int v; + if (parser.seenval('H')) { + v = parser.value_int(); + lcd_preheat_hotend_temp[material] = constrain(v, EXTRUDE_MINTEMP, HEATER_0_MAXTEMP - 15); + } + if (parser.seenval('F')) { + v = parser.value_int(); + lcd_preheat_fan_speed[material] = constrain(v, 0, 255); + } + #if TEMP_SENSOR_BED != 0 + if (parser.seenval('B')) { + v = parser.value_int(); + lcd_preheat_bed_temp[material] = constrain(v, BED_MINTEMP, BED_MAXTEMP - 15); + } + #endif + } + } + +#endif // ULTIPANEL + +#if ENABLED(TEMPERATURE_UNITS_SUPPORT) + /** + * M149: Set temperature units + */ + inline void gcode_M149() { + if (parser.seenval('C')) parser.set_input_temp_units(TEMPUNIT_C); + else if (parser.seenval('K')) parser.set_input_temp_units(TEMPUNIT_K); + else if (parser.seenval('F')) parser.set_input_temp_units(TEMPUNIT_F); + } +#endif + +#if HAS_POWER_SWITCH + + /** + * M80 : Turn on the Power Supply + * M80 S : Report the current state and exit + */ + inline void gcode_M80() { + + // S: Report the current power supply state and exit + if (parser.seen('S')) { + serialprintPGM(powersupply_on ? PSTR("PS:1\n") : PSTR("PS:0\n")); + return; + } + + OUT_WRITE(PS_ON_PIN, PS_ON_AWAKE); // GND + + /** + * If you have a switch on suicide pin, this is useful + * if you want to start another print with suicide feature after + * a print without suicide... + */ + #if HAS_SUICIDE + OUT_WRITE(SUICIDE_PIN, HIGH); + #endif + + #if ENABLED(HAVE_TMC2130) + delay(100); + tmc2130_init(); // Settings only stick when the driver has power + #endif + + powersupply_on = true; + + #if ENABLED(ULTIPANEL) + LCD_MESSAGEPGM(WELCOME_MSG); + #endif + } + +#endif // HAS_POWER_SWITCH + +/** + * M81: Turn off Power, including Power Supply, if there is one. + * + * This code should ALWAYS be available for EMERGENCY SHUTDOWN! + */ +inline void gcode_M81() { + thermalManager.disable_all_heaters(); + stepper.finish_and_disable(); + + #if FAN_COUNT > 0 + for (uint8_t i = 0; i < FAN_COUNT; i++) fanSpeeds[i] = 0; + #if ENABLED(PROBING_FANS_OFF) + fans_paused = false; + ZERO(paused_fanSpeeds); + #endif + #endif + + safe_delay(1000); // Wait 1 second before switching off + + #if HAS_SUICIDE + stepper.synchronize(); + suicide(); + #elif HAS_POWER_SWITCH + OUT_WRITE(PS_ON_PIN, PS_ON_ASLEEP); + powersupply_on = false; + #endif + + #if ENABLED(ULTIPANEL) + LCD_MESSAGEPGM(MACHINE_NAME " " MSG_OFF "."); + #endif +} + +/** + * M82: Set E codes absolute (default) + */ +inline void gcode_M82() { axis_relative_modes[E_AXIS] = false; } + +/** + * M83: Set E codes relative while in Absolute Coordinates (G90) mode + */ +inline void gcode_M83() { axis_relative_modes[E_AXIS] = true; } + +/** + * M18, M84: Disable stepper motors + */ +inline void gcode_M18_M84() { + if (parser.seenval('S')) { + stepper_inactive_time = parser.value_millis_from_seconds(); + } + else { + bool all_axis = !((parser.seen('X')) || (parser.seen('Y')) || (parser.seen('Z')) || (parser.seen('E'))); + if (all_axis) { + stepper.finish_and_disable(); + } + else { + stepper.synchronize(); + if (parser.seen('X')) disable_X(); + if (parser.seen('Y')) disable_Y(); + if (parser.seen('Z')) disable_Z(); + #if E0_ENABLE_PIN != X_ENABLE_PIN && E1_ENABLE_PIN != Y_ENABLE_PIN // Only enable on boards that have separate ENABLE_PINS + if (parser.seen('E')) disable_e_steppers(); + #endif + } + + #if ENABLED(AUTO_BED_LEVELING_UBL) && ENABLED(ULTRA_LCD) // Only needed with an LCD + ubl_lcd_map_control = defer_return_to_status = false; + #endif + } +} + +/** + * M85: Set inactivity shutdown timer with parameter S. To disable set zero (default) + */ +inline void gcode_M85() { + if (parser.seen('S')) max_inactive_time = parser.value_millis_from_seconds(); +} + +/** + * Multi-stepper support for M92, M201, M203 + */ +#if ENABLED(DISTINCT_E_FACTORS) + #define GET_TARGET_EXTRUDER(CMD) if (get_target_extruder_from_command(CMD)) return + #define TARGET_EXTRUDER target_extruder +#else + #define GET_TARGET_EXTRUDER(CMD) NOOP + #define TARGET_EXTRUDER 0 +#endif + +/** + * M92: Set axis steps-per-unit for one or more axes, X, Y, Z, and E. + * (Follows the same syntax as G92) + * + * With multiple extruders use T to specify which one. + */ +inline void gcode_M92() { + + GET_TARGET_EXTRUDER(92); + + LOOP_XYZE(i) { + if (parser.seen(axis_codes[i])) { + if (i == E_AXIS) { + const float value = parser.value_per_axis_unit((AxisEnum)(E_AXIS + TARGET_EXTRUDER)); + if (value < 20.0) { + float factor = planner.axis_steps_per_mm[E_AXIS + TARGET_EXTRUDER] / value; // increase e constants if M92 E14 is given for netfab. + planner.max_jerk[E_AXIS] *= factor; + planner.max_feedrate_mm_s[E_AXIS + TARGET_EXTRUDER] *= factor; + planner.max_acceleration_steps_per_s2[E_AXIS + TARGET_EXTRUDER] *= factor; + } + planner.axis_steps_per_mm[E_AXIS + TARGET_EXTRUDER] = value; + } + else { + planner.axis_steps_per_mm[i] = parser.value_per_axis_unit((AxisEnum)i); + } + } + } + planner.refresh_positioning(); +} + +/** + * Output the current position to serial + */ +void report_current_position() { + SERIAL_PROTOCOLPGM("X:"); + SERIAL_PROTOCOL(current_position[X_AXIS]); + SERIAL_PROTOCOLPGM(" Y:"); + SERIAL_PROTOCOL(current_position[Y_AXIS]); + SERIAL_PROTOCOLPGM(" Z:"); + SERIAL_PROTOCOL(current_position[Z_AXIS]); + SERIAL_PROTOCOLPGM(" E:"); + SERIAL_PROTOCOL(current_position[E_AXIS]); + + stepper.report_positions(); + + #if IS_SCARA + SERIAL_PROTOCOLPAIR("SCARA Theta:", stepper.get_axis_position_degrees(A_AXIS)); + SERIAL_PROTOCOLLNPAIR(" Psi+Theta:", stepper.get_axis_position_degrees(B_AXIS)); + SERIAL_EOL(); + #endif +} + +#ifdef M114_DETAIL + + void report_xyze(const float pos[XYZE], const uint8_t n = 4, const uint8_t precision = 3) { + char str[12]; + for (uint8_t i = 0; i < n; i++) { + SERIAL_CHAR(' '); + SERIAL_CHAR(axis_codes[i]); + SERIAL_CHAR(':'); + SERIAL_PROTOCOL(dtostrf(pos[i], 8, precision, str)); + } + SERIAL_EOL(); + } + + inline void report_xyz(const float pos[XYZ]) { report_xyze(pos, 3); } + + void report_current_position_detail() { + + stepper.synchronize(); + + SERIAL_PROTOCOLPGM("\nLogical:"); + report_xyze(current_position); + + SERIAL_PROTOCOLPGM("Raw: "); + const float raw[XYZ] = { RAW_X_POSITION(current_position[X_AXIS]), RAW_Y_POSITION(current_position[Y_AXIS]), RAW_Z_POSITION(current_position[Z_AXIS]) }; + report_xyz(raw); + + SERIAL_PROTOCOLPGM("Leveled:"); + float leveled[XYZ] = { current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS] }; + planner.apply_leveling(leveled); + report_xyz(leveled); + + SERIAL_PROTOCOLPGM("UnLevel:"); + float unleveled[XYZ] = { leveled[X_AXIS], leveled[Y_AXIS], leveled[Z_AXIS] }; + planner.unapply_leveling(unleveled); + report_xyz(unleveled); + + #if IS_KINEMATIC + #if IS_SCARA + SERIAL_PROTOCOLPGM("ScaraK: "); + #else + SERIAL_PROTOCOLPGM("DeltaK: "); + #endif + inverse_kinematics(leveled); // writes delta[] + report_xyz(delta); + #endif + + SERIAL_PROTOCOLPGM("Stepper:"); + const float step_count[XYZE] = { stepper.position(X_AXIS), stepper.position(Y_AXIS), stepper.position(Z_AXIS), stepper.position(E_AXIS) }; + report_xyze(step_count, 4, 0); + + #if IS_SCARA + const float deg[XYZ] = { + stepper.get_axis_position_degrees(A_AXIS), + stepper.get_axis_position_degrees(B_AXIS) + }; + SERIAL_PROTOCOLPGM("Degrees:"); + report_xyze(deg, 2); + #endif + + SERIAL_PROTOCOLPGM("FromStp:"); + get_cartesian_from_steppers(); // writes cartes[XYZ] (with forward kinematics) + const float from_steppers[XYZE] = { cartes[X_AXIS], cartes[Y_AXIS], cartes[Z_AXIS], stepper.get_axis_position_mm(E_AXIS) }; + report_xyze(from_steppers); + + const float diff[XYZE] = { + from_steppers[X_AXIS] - leveled[X_AXIS], + from_steppers[Y_AXIS] - leveled[Y_AXIS], + from_steppers[Z_AXIS] - leveled[Z_AXIS], + from_steppers[E_AXIS] - current_position[E_AXIS] + }; + SERIAL_PROTOCOLPGM("Differ: "); + report_xyze(diff); + } +#endif // M114_DETAIL + +/** + * M114: Report current position to host + */ +inline void gcode_M114() { + + #ifdef M114_DETAIL + if (parser.seen('D')) { + report_current_position_detail(); + return; + } + #endif + + stepper.synchronize(); + report_current_position(); +} + +/** + * M115: Capabilities string + */ +inline void gcode_M115() { + SERIAL_PROTOCOLLNPGM(MSG_M115_REPORT); + + #if ENABLED(EXTENDED_CAPABILITIES_REPORT) + + // EEPROM (M500, M501) + #if ENABLED(EEPROM_SETTINGS) + SERIAL_PROTOCOLLNPGM("Cap:EEPROM:1"); + #else + SERIAL_PROTOCOLLNPGM("Cap:EEPROM:0"); + #endif + + // AUTOREPORT_TEMP (M155) + #if ENABLED(AUTO_REPORT_TEMPERATURES) + SERIAL_PROTOCOLLNPGM("Cap:AUTOREPORT_TEMP:1"); + #else + SERIAL_PROTOCOLLNPGM("Cap:AUTOREPORT_TEMP:0"); + #endif + + // PROGRESS (M530 S L, M531 , M532 X L) + SERIAL_PROTOCOLLNPGM("Cap:PROGRESS:0"); + + // Print Job timer M75, M76, M77 + SERIAL_PROTOCOLLNPGM("Cap:PRINT_JOB:1"); + + // AUTOLEVEL (G29) + #if HAS_ABL + SERIAL_PROTOCOLLNPGM("Cap:AUTOLEVEL:1"); + #else + SERIAL_PROTOCOLLNPGM("Cap:AUTOLEVEL:0"); + #endif + + // Z_PROBE (G30) + #if HAS_BED_PROBE + SERIAL_PROTOCOLLNPGM("Cap:Z_PROBE:1"); + #else + SERIAL_PROTOCOLLNPGM("Cap:Z_PROBE:0"); + #endif + + // MESH_REPORT (M420 V) + #if HAS_LEVELING + SERIAL_PROTOCOLLNPGM("Cap:LEVELING_DATA:1"); + #else + SERIAL_PROTOCOLLNPGM("Cap:LEVELING_DATA:0"); + #endif + + // SOFTWARE_POWER (M80, M81) + #if HAS_POWER_SWITCH + SERIAL_PROTOCOLLNPGM("Cap:SOFTWARE_POWER:1"); + #else + SERIAL_PROTOCOLLNPGM("Cap:SOFTWARE_POWER:0"); + #endif + + // CASE LIGHTS (M355) + #if HAS_CASE_LIGHT + SERIAL_PROTOCOLLNPGM("Cap:TOGGLE_LIGHTS:1"); + if (USEABLE_HARDWARE_PWM(CASE_LIGHT_PIN)) { + SERIAL_PROTOCOLLNPGM("Cap:CASE_LIGHT_BRIGHTNESS:1"); + } + else + SERIAL_PROTOCOLLNPGM("Cap:CASE_LIGHT_BRIGHTNESS:0"); + #else + SERIAL_PROTOCOLLNPGM("Cap:TOGGLE_LIGHTS:0"); + SERIAL_PROTOCOLLNPGM("Cap:CASE_LIGHT_BRIGHTNESS:0"); + #endif + + // EMERGENCY_PARSER (M108, M112, M410) + #if ENABLED(EMERGENCY_PARSER) + SERIAL_PROTOCOLLNPGM("Cap:EMERGENCY_PARSER:1"); + #else + SERIAL_PROTOCOLLNPGM("Cap:EMERGENCY_PARSER:0"); + #endif + + #endif // EXTENDED_CAPABILITIES_REPORT +} + +/** + * M117: Set LCD Status Message + */ +inline void gcode_M117() { lcd_setstatus(parser.string_arg); } + +/** + * M118: Display a message in the host console. + * + * A Append '// ' for an action command, as in OctoPrint + * E Have the host 'echo:' the text + */ +inline void gcode_M118() { + if (parser.boolval('E')) SERIAL_ECHO_START(); + if (parser.boolval('A')) SERIAL_ECHOPGM("// "); + SERIAL_ECHOLN(parser.string_arg); +} + +/** + * M119: Output endstop states to serial output + */ +inline void gcode_M119() { endstops.M119(); } + +/** + * M120: Enable endstops and set non-homing endstop state to "enabled" + */ +inline void gcode_M120() { endstops.enable_globally(true); } + +/** + * M121: Disable endstops and set non-homing endstop state to "disabled" + */ +inline void gcode_M121() { endstops.enable_globally(false); } + +#if ENABLED(PARK_HEAD_ON_PAUSE) + + /** + * M125: Store current position and move to filament change position. + * Called on pause (by M25) to prevent material leaking onto the + * object. On resume (M24) the head will be moved back and the + * print will resume. + * + * If Marlin is compiled without SD Card support, M125 can be + * used directly to pause the print and move to park position, + * resuming with a button click or M108. + * + * L = override retract length + * X = override X + * Y = override Y + * Z = override Z raise + */ + inline void gcode_M125() { + + // Initial retract before move to filament change position + const float retract = parser.seen('L') ? parser.value_axis_units(E_AXIS) : 0 + #ifdef PAUSE_PARK_RETRACT_LENGTH + - (PAUSE_PARK_RETRACT_LENGTH) + #endif + ; + + // Lift Z axis + const float z_lift = parser.linearval('Z') + #ifdef PAUSE_PARK_Z_ADD + + PAUSE_PARK_Z_ADD + #endif + ; + + // Move XY axes to filament change position or given position + const float x_pos = parser.linearval('X') + #ifdef PAUSE_PARK_X_POS + + PAUSE_PARK_X_POS + #endif + #if HOTENDS > 1 && DISABLED(DUAL_X_CARRIAGE) + + (active_extruder ? hotend_offset[X_AXIS][active_extruder] : 0) + #endif + ; + const float y_pos = parser.linearval('Y') + #ifdef PAUSE_PARK_Y_POS + + PAUSE_PARK_Y_POS + #endif + #if HOTENDS > 1 && DISABLED(DUAL_X_CARRIAGE) + + (active_extruder ? hotend_offset[Y_AXIS][active_extruder] : 0) + #endif + ; + + #if DISABLED(SDSUPPORT) + const bool job_running = print_job_timer.isRunning(); + #endif + + if (pause_print(retract, z_lift, x_pos, y_pos)) { + #if DISABLED(SDSUPPORT) + // Wait for lcd click or M108 + wait_for_filament_reload(); + + // Return to print position and continue + resume_print(); + + if (job_running) print_job_timer.start(); + #endif + } + } + +#endif // PARK_HEAD_ON_PAUSE + +#if HAS_COLOR_LEDS + + /** + * M150: Set Status LED Color - Use R-U-B-W for R-G-B-W + * and Brightness - Use P (for NEOPIXEL only) + * + * Always sets all 3 or 4 components. If a component is left out, set to 0. + * If brightness is left out, no value changed + * + * Examples: + * + * M150 R255 ; Turn LED red + * M150 R255 U127 ; Turn LED orange (PWM only) + * M150 ; Turn LED off + * M150 R U B ; Turn LED white + * M150 W ; Turn LED white using a white LED + * M150 P127 ; Set LED 50% brightness + * M150 P ; Set LED full brightness + */ + inline void gcode_M150() { + set_led_color( + 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 + #if ENABLED(RGBW_LED) || ENABLED(NEOPIXEL_LED) + , parser.seen('W') ? (parser.has_value() ? parser.value_byte() : 255) : 0 + #if ENABLED(NEOPIXEL_LED) + , parser.seen('P') ? (parser.has_value() ? parser.value_byte() : 255) : pixels.getBrightness() + #endif + #endif + ); + } + +#endif // HAS_COLOR_LEDS + +/** + * 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. + */ +inline void gcode_M200() { + + if (get_target_extruder_from_command(200)) 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 + volumetric_enabled = (parser.value_linear_units() != 0.0); + if (volumetric_enabled) { + filament_size[target_extruder] = parser.value_linear_units(); + // make sure all extruders have some sane value for the filament size + for (uint8_t i = 0; i < COUNT(filament_size); i++) + if (! filament_size[i]) filament_size[i] = DEFAULT_NOMINAL_FILAMENT_DIA; + } + } + calculate_volumetric_multipliers(); +} + +/** + * M201: Set max acceleration in units/s^2 for print moves (M201 X1000 Y1000) + * + * With multiple extruders use T to specify which one. + */ +inline void gcode_M201() { + + GET_TARGET_EXTRUDER(201); + + LOOP_XYZE(i) { + if (parser.seen(axis_codes[i])) { + const uint8_t a = i + (i == E_AXIS ? TARGET_EXTRUDER : 0); + planner.max_acceleration_mm_per_s2[a] = parser.value_axis_units((AxisEnum)a); + } + } + // steps per sq second need to be updated to agree with the units per sq second (as they are what is used in the planner) + planner.reset_acceleration_rates(); +} + +#if 0 // Not used for Sprinter/grbl gen6 + inline void gcode_M202() { + LOOP_XYZE(i) { + if (parser.seen(axis_codes[i])) axis_travel_steps_per_sqr_second[i] = parser.value_axis_units((AxisEnum)i) * planner.axis_steps_per_mm[i]; + } + } +#endif + + +/** + * M203: Set maximum feedrate that your machine can sustain (M203 X200 Y200 Z300 E10000) in units/sec + * + * With multiple extruders use T to specify which one. + */ +inline void gcode_M203() { + + GET_TARGET_EXTRUDER(203); + + LOOP_XYZE(i) + if (parser.seen(axis_codes[i])) { + const uint8_t a = i + (i == E_AXIS ? TARGET_EXTRUDER : 0); + planner.max_feedrate_mm_s[a] = parser.value_axis_units((AxisEnum)a); + } +} + +/** + * M204: Set Accelerations in units/sec^2 (M204 P1200 R3000 T3000) + * + * P = Printing moves + * R = Retract only (no X, Y, Z) moves + * T = Travel (non printing) moves + * + * Also sets minimum segment time in ms (B20000) to prevent buffer under-runs and M20 minimum feedrate + */ +inline void gcode_M204() { + if (parser.seen('S')) { // Kept for legacy compatibility. Should NOT BE USED for new developments. + planner.travel_acceleration = planner.acceleration = parser.value_linear_units(); + SERIAL_ECHOLNPAIR("Setting Print and Travel Acceleration: ", planner.acceleration); + } + if (parser.seen('P')) { + planner.acceleration = parser.value_linear_units(); + SERIAL_ECHOLNPAIR("Setting Print Acceleration: ", planner.acceleration); + } + if (parser.seen('R')) { + planner.retract_acceleration = parser.value_linear_units(); + SERIAL_ECHOLNPAIR("Setting Retract Acceleration: ", planner.retract_acceleration); + } + if (parser.seen('T')) { + planner.travel_acceleration = parser.value_linear_units(); + SERIAL_ECHOLNPAIR("Setting Travel Acceleration: ", planner.travel_acceleration); + } +} + +/** + * M205: Set Advanced Settings + * + * S = Min Feed Rate (units/s) + * T = Min Travel Feed Rate (units/s) + * B = Min Segment Time (µs) + * X = Max X Jerk (units/sec^2) + * Y = Max Y Jerk (units/sec^2) + * Z = Max Z Jerk (units/sec^2) + * E = Max E Jerk (units/sec^2) + */ +inline void gcode_M205() { + if (parser.seen('S')) planner.min_feedrate_mm_s = parser.value_linear_units(); + if (parser.seen('T')) planner.min_travel_feedrate_mm_s = parser.value_linear_units(); + if (parser.seen('B')) planner.min_segment_time = parser.value_millis(); + if (parser.seen('X')) planner.max_jerk[X_AXIS] = parser.value_linear_units(); + if (parser.seen('Y')) planner.max_jerk[Y_AXIS] = parser.value_linear_units(); + if (parser.seen('Z')) planner.max_jerk[Z_AXIS] = parser.value_linear_units(); + if (parser.seen('E')) planner.max_jerk[E_AXIS] = parser.value_linear_units(); +} + +#if HAS_M206_COMMAND + + /** + * M206: Set Additional Homing Offset (X Y Z). SCARA aliases T=X, P=Y + * + * *** @thinkyhead: I recommend deprecating M206 for SCARA in favor of M665. + * *** M206 for SCARA will remain enabled in 1.1.x for compatibility. + * *** In the next 1.2 release, it will simply be disabled by default. + */ + inline void gcode_M206() { + LOOP_XYZ(i) + if (parser.seen(axis_codes[i])) + set_home_offset((AxisEnum)i, parser.value_linear_units()); + + #if ENABLED(MORGAN_SCARA) + if (parser.seen('T')) set_home_offset(A_AXIS, parser.value_linear_units()); // Theta + if (parser.seen('P')) set_home_offset(B_AXIS, parser.value_linear_units()); // Psi + #endif + + SYNC_PLAN_POSITION_KINEMATIC(); + report_current_position(); + } + +#endif // HAS_M206_COMMAND + +#if ENABLED(DELTA) + /** + * M665: Set delta configurations + * + * H = delta height + * L = diagonal rod + * R = delta radius + * S = segments per second + * B = delta calibration radius + * X = Alpha (Tower 1) angle trim + * Y = Beta (Tower 2) angle trim + * Z = Rotate A and B by this angle + */ + inline void gcode_M665() { + if (parser.seen('H')) { + home_offset[Z_AXIS] = parser.value_linear_units() - DELTA_HEIGHT; + update_software_endstops(Z_AXIS); + } + if (parser.seen('L')) delta_diagonal_rod = parser.value_linear_units(); + if (parser.seen('R')) delta_radius = parser.value_linear_units(); + if (parser.seen('S')) delta_segments_per_second = parser.value_float(); + if (parser.seen('B')) delta_calibration_radius = parser.value_float(); + if (parser.seen('X')) delta_tower_angle_trim[A_AXIS] = parser.value_float(); + if (parser.seen('Y')) delta_tower_angle_trim[B_AXIS] = parser.value_float(); + if (parser.seen('Z')) delta_tower_angle_trim[C_AXIS] = parser.value_float(); + recalc_delta_settings(delta_radius, delta_diagonal_rod, delta_tower_angle_trim); + } + /** + * M666: Set delta endstop adjustment + */ + inline void gcode_M666() { + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOLNPGM(">>> gcode_M666"); + } + #endif + LOOP_XYZ(i) { + if (parser.seen(axis_codes[i])) { + if (parser.value_linear_units() * Z_HOME_DIR <= 0) + endstop_adj[i] = parser.value_linear_units(); + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOPAIR("endstop_adj[", axis_codes[i]); + SERIAL_ECHOLNPAIR("] = ", endstop_adj[i]); + } + #endif + } + } + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOLNPGM("<<< gcode_M666"); + } + #endif + } + +#elif IS_SCARA + + /** + * M665: Set SCARA settings + * + * Parameters: + * + * S[segments-per-second] - Segments-per-second + * P[theta-psi-offset] - Theta-Psi offset, added to the shoulder (A/X) angle + * T[theta-offset] - Theta offset, added to the elbow (B/Y) angle + * + * A, P, and X are all aliases for the shoulder angle + * B, T, and Y are all aliases for the elbow angle + */ + inline void gcode_M665() { + if (parser.seen('S')) delta_segments_per_second = parser.value_float(); + + const bool hasA = parser.seen('A'), hasP = parser.seen('P'), hasX = parser.seen('X'); + const uint8_t sumAPX = hasA + hasP + hasX; + if (sumAPX == 1) + home_offset[A_AXIS] = parser.value_float(); + else if (sumAPX > 1) { + SERIAL_ERROR_START(); + SERIAL_ERRORLNPGM("Only one of A, P, or X is allowed."); + return; + } + + const bool hasB = parser.seen('B'), hasT = parser.seen('T'), hasY = parser.seen('Y'); + const uint8_t sumBTY = hasB + hasT + hasY; + if (sumBTY == 1) + home_offset[B_AXIS] = parser.value_float(); + else if (sumBTY > 1) { + SERIAL_ERROR_START(); + SERIAL_ERRORLNPGM("Only one of B, T, or Y is allowed."); + return; + } + } + +#elif ENABLED(Z_DUAL_ENDSTOPS) // !DELTA && ENABLED(Z_DUAL_ENDSTOPS) + + /** + * M666: For Z Dual Endstop setup, set z axis offset to the z2 axis. + */ + inline void gcode_M666() { + if (parser.seen('Z')) z_endstop_adj = parser.value_linear_units(); + SERIAL_ECHOLNPAIR("Z Endstop Adjustment set to (mm):", z_endstop_adj); + } + +#endif // !DELTA && Z_DUAL_ENDSTOPS + +#if ENABLED(FWRETRACT) + + /** + * M207: Set firmware retraction values + * + * S[+units] retract_length + * W[+units] swap_retract_length (multi-extruder) + * F[units/min] retract_feedrate_mm_s + * Z[units] retract_zlift + */ + inline void gcode_M207() { + if (parser.seen('S')) retract_length = parser.value_axis_units(E_AXIS); + if (parser.seen('F')) retract_feedrate_mm_s = MMM_TO_MMS(parser.value_axis_units(E_AXIS)); + if (parser.seen('Z')) retract_zlift = parser.value_linear_units(); + if (parser.seen('W')) swap_retract_length = parser.value_axis_units(E_AXIS); + } + + /** + * M208: Set firmware un-retraction values + * + * S[+units] retract_recover_length (in addition to M207 S*) + * W[+units] swap_retract_recover_length (multi-extruder) + * F[units/min] retract_recover_feedrate_mm_s + * R[units/min] swap_retract_recover_feedrate_mm_s + */ + inline void gcode_M208() { + if (parser.seen('S')) retract_recover_length = parser.value_axis_units(E_AXIS); + if (parser.seen('F')) retract_recover_feedrate_mm_s = MMM_TO_MMS(parser.value_axis_units(E_AXIS)); + if (parser.seen('R')) swap_retract_recover_feedrate_mm_s = MMM_TO_MMS(parser.value_axis_units(E_AXIS)); + if (parser.seen('W')) swap_retract_recover_length = parser.value_axis_units(E_AXIS); + } + + /** + * M209: Enable automatic retract (M209 S1) + * For slicers that don't support G10/11, reversed extrude-only + * moves will be classified as retraction. + */ + inline void gcode_M209() { + if (MIN_AUTORETRACT <= MAX_AUTORETRACT) { + if (parser.seen('S')) { + autoretract_enabled = parser.value_bool(); + for (uint8_t i = 0; i < EXTRUDERS; i++) retracted[i] = false; + } + } + } + +#endif // FWRETRACT + +/** + * M211: Enable, Disable, and/or Report software endstops + * + * Usage: M211 S1 to enable, M211 S0 to disable, M211 alone for report + */ +inline void gcode_M211() { + SERIAL_ECHO_START(); + #if HAS_SOFTWARE_ENDSTOPS + if (parser.seen('S')) soft_endstops_enabled = parser.value_bool(); + SERIAL_ECHOPGM(MSG_SOFT_ENDSTOPS); + serialprintPGM(soft_endstops_enabled ? PSTR(MSG_ON) : PSTR(MSG_OFF)); + #else + SERIAL_ECHOPGM(MSG_SOFT_ENDSTOPS); + SERIAL_ECHOPGM(MSG_OFF); + #endif + SERIAL_ECHOPGM(MSG_SOFT_MIN); + SERIAL_ECHOPAIR( MSG_X, soft_endstop_min[X_AXIS]); + SERIAL_ECHOPAIR(" " MSG_Y, soft_endstop_min[Y_AXIS]); + SERIAL_ECHOPAIR(" " MSG_Z, soft_endstop_min[Z_AXIS]); + SERIAL_ECHOPGM(MSG_SOFT_MAX); + SERIAL_ECHOPAIR( MSG_X, soft_endstop_max[X_AXIS]); + SERIAL_ECHOPAIR(" " MSG_Y, soft_endstop_max[Y_AXIS]); + SERIAL_ECHOLNPAIR(" " MSG_Z, soft_endstop_max[Z_AXIS]); +} + +#if HOTENDS > 1 + + /** + * M218 - set hotend offset (in linear units) + * + * T + * X + * Y + * Z - Available with DUAL_X_CARRIAGE and SWITCHING_NOZZLE + */ + inline void gcode_M218() { + if (get_target_extruder_from_command(218) || target_extruder == 0) return; + + if (parser.seenval('X')) hotend_offset[X_AXIS][target_extruder] = parser.value_linear_units(); + if (parser.seenval('Y')) hotend_offset[Y_AXIS][target_extruder] = parser.value_linear_units(); + + #if ENABLED(DUAL_X_CARRIAGE) || ENABLED(SWITCHING_NOZZLE) || ENABLED(PARKING_EXTRUDER) + if (parser.seenval('Z')) hotend_offset[Z_AXIS][target_extruder] = parser.value_linear_units(); + #endif + + SERIAL_ECHO_START(); + SERIAL_ECHOPGM(MSG_HOTEND_OFFSET); + HOTEND_LOOP() { + SERIAL_CHAR(' '); + SERIAL_ECHO(hotend_offset[X_AXIS][e]); + SERIAL_CHAR(','); + SERIAL_ECHO(hotend_offset[Y_AXIS][e]); + #if ENABLED(DUAL_X_CARRIAGE) || ENABLED(SWITCHING_NOZZLE) || ENABLED(PARKING_EXTRUDER) + SERIAL_CHAR(','); + SERIAL_ECHO(hotend_offset[Z_AXIS][e]); + #endif + } + SERIAL_EOL(); + } + +#endif // HOTENDS > 1 + +/** + * M220: Set speed percentage factor, aka "Feed Rate" (M220 S95) + */ +inline void gcode_M220() { + if (parser.seenval('S')) feedrate_percentage = parser.value_int(); +} + +/** + * M221: Set extrusion percentage (M221 T0 S95) + */ +inline void gcode_M221() { + if (get_target_extruder_from_command(221)) return; + if (parser.seenval('S')) + flow_percentage[target_extruder] = parser.value_int(); +} + +/** + * M226: Wait until the specified pin reaches the state required (M226 P S) + */ +inline void gcode_M226() { + if (parser.seen('P')) { + const int pin_number = parser.value_int(), + pin_state = parser.intval('S', -1); // required pin state - default is inverted + + if (WITHIN(pin_state, -1, 1) && pin_number > -1 && !pin_is_protected(pin_number)) { + + int target = LOW; + + stepper.synchronize(); + + pinMode(pin_number, INPUT); + switch (pin_state) { + case 1: + target = HIGH; + break; + case 0: + target = LOW; + break; + case -1: + target = !digitalRead(pin_number); + break; + } + + while (digitalRead(pin_number) != target) idle(); + + } // pin_state -1 0 1 && pin_number > -1 + } // parser.seen('P') +} + +#if ENABLED(EXPERIMENTAL_I2CBUS) + + /** + * M260: Send data to a I2C slave device + * + * This is a PoC, the formating 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 + * + * M260 B + * M260 B + * M260 B + * + * M260 S1 ; Send the buffered data and reset the buffer + * M260 R1 ; Reset the buffer without sending data + * + */ + inline void gcode_M260() { + // Set the target address + if (parser.seen('A')) i2c.address(parser.value_byte()); + + // Add a new byte to the buffer + if (parser.seen('B')) i2c.addbyte(parser.value_byte()); + + // Flush the buffer to the bus + if (parser.seen('S')) i2c.send(); + + // Reset and rewind the buffer + else if (parser.seen('R')) i2c.reset(); + } + + /** + * M261: Request X bytes from I2C slave device + * + * Usage: M261 A B + */ + inline void gcode_M261() { + if (parser.seen('A')) i2c.address(parser.value_byte()); + + uint8_t bytes = parser.byteval('B', 1); + + if (i2c.addr && bytes && bytes <= TWIBUS_BUFFER_SIZE) { + i2c.relay(bytes); + } + else { + SERIAL_ERROR_START(); + SERIAL_ERRORLN("Bad i2c request"); + } + } + +#endif // EXPERIMENTAL_I2CBUS + +#if HAS_SERVOS + + /** + * M280: Get or set servo position. P [S] + */ + inline void gcode_M280() { + if (!parser.seen('P')) return; + const int servo_index = parser.value_int(); + if (WITHIN(servo_index, 0, NUM_SERVOS - 1)) { + if (parser.seen('S')) + MOVE_SERVO(servo_index, parser.value_int()); + else { + SERIAL_ECHO_START(); + SERIAL_ECHOPAIR(" Servo ", servo_index); + SERIAL_ECHOLNPAIR(": ", servo[servo_index].read()); + } + } + else { + SERIAL_ERROR_START(); + SERIAL_ECHOPAIR("Servo ", servo_index); + SERIAL_ECHOLNPGM(" out of range"); + } + } + +#endif // HAS_SERVOS + +#if HAS_BUZZER + + /** + * M300: Play beep sound S P + */ + inline void gcode_M300() { + uint16_t const frequency = parser.ushortval('S', 260); + uint16_t duration = parser.ushortval('P', 1000); + + // Limits the tone duration to 0-5 seconds. + NOMORE(duration, 5000); + + BUZZ(duration, frequency); + } + +#endif // HAS_BUZZER + +#if ENABLED(PIDTEMP) + + /** + * M301: Set PID parameters P I D (and optionally C, L) + * + * P[float] Kp term + * I[float] Ki term (unscaled) + * D[float] Kd term (unscaled) + * + * With PID_EXTRUSION_SCALING: + * + * C[float] Kc term + * L[float] LPQ length + */ + inline void gcode_M301() { + + // multi-extruder PID patch: M301 updates or prints a single extruder's PID values + // default behaviour (omitting E parameter) is to update for extruder 0 only + const uint8_t e = parser.byteval('E'); // extruder being updated + + if (e < HOTENDS) { // catch bad input value + if (parser.seen('P')) PID_PARAM(Kp, e) = parser.value_float(); + if (parser.seen('I')) PID_PARAM(Ki, e) = scalePID_i(parser.value_float()); + if (parser.seen('D')) PID_PARAM(Kd, e) = scalePID_d(parser.value_float()); + #if ENABLED(PID_EXTRUSION_SCALING) + if (parser.seen('C')) PID_PARAM(Kc, e) = parser.value_float(); + if (parser.seen('L')) lpq_len = parser.value_float(); + NOMORE(lpq_len, LPQ_MAX_LEN); + #endif + + thermalManager.updatePID(); + SERIAL_ECHO_START(); + #if ENABLED(PID_PARAMS_PER_HOTEND) + SERIAL_ECHOPAIR(" e:", e); // specify extruder in serial output + #endif // PID_PARAMS_PER_HOTEND + SERIAL_ECHOPAIR(" p:", PID_PARAM(Kp, e)); + SERIAL_ECHOPAIR(" i:", unscalePID_i(PID_PARAM(Ki, e))); + SERIAL_ECHOPAIR(" d:", unscalePID_d(PID_PARAM(Kd, e))); + #if ENABLED(PID_EXTRUSION_SCALING) + //Kc does not have scaling applied above, or in resetting defaults + SERIAL_ECHOPAIR(" c:", PID_PARAM(Kc, e)); + #endif + SERIAL_EOL(); + } + else { + SERIAL_ERROR_START(); + SERIAL_ERRORLN(MSG_INVALID_EXTRUDER); + } + } + +#endif // PIDTEMP + +#if ENABLED(PIDTEMPBED) + + inline void gcode_M304() { + if (parser.seen('P')) thermalManager.bedKp = parser.value_float(); + if (parser.seen('I')) thermalManager.bedKi = scalePID_i(parser.value_float()); + if (parser.seen('D')) thermalManager.bedKd = scalePID_d(parser.value_float()); + + thermalManager.updatePID(); + + SERIAL_ECHO_START(); + SERIAL_ECHOPAIR(" p:", thermalManager.bedKp); + SERIAL_ECHOPAIR(" i:", unscalePID_i(thermalManager.bedKi)); + SERIAL_ECHOLNPAIR(" d:", unscalePID_d(thermalManager.bedKd)); + } + +#endif // PIDTEMPBED + +#if defined(CHDK) || HAS_PHOTOGRAPH + + /** + * M240: Trigger a camera by emulating a Canon RC-1 + * See http://www.doc-diy.net/photo/rc-1_hacked/ + */ + inline void gcode_M240() { + #ifdef CHDK + + OUT_WRITE(CHDK, HIGH); + chdkHigh = millis(); + chdkActive = true; + + #elif HAS_PHOTOGRAPH + + const uint8_t NUM_PULSES = 16; + const float PULSE_LENGTH = 0.01524; + for (int i = 0; i < NUM_PULSES; i++) { + WRITE(PHOTOGRAPH_PIN, HIGH); + _delay_ms(PULSE_LENGTH); + WRITE(PHOTOGRAPH_PIN, LOW); + _delay_ms(PULSE_LENGTH); + } + delay(7.33); + for (int i = 0; i < NUM_PULSES; i++) { + WRITE(PHOTOGRAPH_PIN, HIGH); + _delay_ms(PULSE_LENGTH); + WRITE(PHOTOGRAPH_PIN, LOW); + _delay_ms(PULSE_LENGTH); + } + + #endif // !CHDK && HAS_PHOTOGRAPH + } + +#endif // CHDK || PHOTOGRAPH_PIN + +#if HAS_LCD_CONTRAST + + /** + * M250: Read and optionally set the LCD contrast + */ + inline void gcode_M250() { + if (parser.seen('C')) set_lcd_contrast(parser.value_int()); + SERIAL_PROTOCOLPGM("lcd contrast value: "); + SERIAL_PROTOCOL(lcd_contrast); + SERIAL_EOL(); + } + +#endif // HAS_LCD_CONTRAST + +#if ENABLED(PREVENT_COLD_EXTRUSION) + + /** + * M302: Allow cold extrudes, or set the minimum extrude temperature + * + * S sets the minimum extrude temperature + * P enables (1) or disables (0) cold extrusion + * + * Examples: + * + * M302 ; report current cold extrusion state + * M302 P0 ; enable cold extrusion checking + * M302 P1 ; disables 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 + */ + inline void gcode_M302() { + const bool seen_S = parser.seen('S'); + if (seen_S) { + thermalManager.extrude_min_temp = parser.value_celsius(); + thermalManager.allow_cold_extrude = (thermalManager.extrude_min_temp == 0); + } + + if (parser.seen('P')) + thermalManager.allow_cold_extrude = (thermalManager.extrude_min_temp == 0) || parser.value_bool(); + else if (!seen_S) { + // Report current state + SERIAL_ECHO_START(); + SERIAL_ECHOPAIR("Cold extrudes are ", (thermalManager.allow_cold_extrude ? "en" : "dis")); + SERIAL_ECHOPAIR("abled (min temp ", thermalManager.extrude_min_temp); + SERIAL_ECHOLNPGM("C)"); + } + } + +#endif // PREVENT_COLD_EXTRUSION + +/** + * M303: PID relay autotune + * + * S sets the target temperature. (default 150C) + * E (-1 for the bed) (default 0) + * C + * U with a non-zero value will apply the result to current settings + */ +inline void gcode_M303() { + #if HAS_PID_HEATING + const int e = parser.intval('E'), c = parser.intval('C', 5); + const bool u = parser.boolval('U'); + + int16_t temp = parser.celsiusval('S', e < 0 ? 70 : 150); + + if (WITHIN(e, 0, HOTENDS - 1)) + target_extruder = e; + + #if DISABLED(BUSY_WHILE_HEATING) + KEEPALIVE_STATE(NOT_BUSY); + #endif + + thermalManager.PID_autotune(temp, e, c, u); + + #if DISABLED(BUSY_WHILE_HEATING) + KEEPALIVE_STATE(IN_HANDLER); + #endif + #else + SERIAL_ERROR_START(); + SERIAL_ERRORLNPGM(MSG_ERR_M303_DISABLED); + #endif +} + +#if ENABLED(MORGAN_SCARA) + + bool SCARA_move_to_cal(uint8_t delta_a, uint8_t delta_b) { + if (IsRunning()) { + forward_kinematics_SCARA(delta_a, delta_b); + destination[X_AXIS] = LOGICAL_X_POSITION(cartes[X_AXIS]); + destination[Y_AXIS] = LOGICAL_Y_POSITION(cartes[Y_AXIS]); + destination[Z_AXIS] = current_position[Z_AXIS]; + prepare_move_to_destination(); + return true; + } + return false; + } + + /** + * M360: SCARA calibration: Move to cal-position ThetaA (0 deg calibration) + */ + inline bool gcode_M360() { + SERIAL_ECHOLNPGM(" Cal: Theta 0"); + return SCARA_move_to_cal(0, 120); + } + + /** + * M361: SCARA calibration: Move to cal-position ThetaB (90 deg calibration - steps per degree) + */ + inline bool gcode_M361() { + SERIAL_ECHOLNPGM(" Cal: Theta 90"); + return SCARA_move_to_cal(90, 130); + } + + /** + * M362: SCARA calibration: Move to cal-position PsiA (0 deg calibration) + */ + inline bool gcode_M362() { + SERIAL_ECHOLNPGM(" Cal: Psi 0"); + return SCARA_move_to_cal(60, 180); + } + + /** + * M363: SCARA calibration: Move to cal-position PsiB (90 deg calibration - steps per degree) + */ + inline bool gcode_M363() { + SERIAL_ECHOLNPGM(" Cal: Psi 90"); + return SCARA_move_to_cal(50, 90); + } + + /** + * M364: SCARA calibration: Move to cal-position PsiC (90 deg to Theta calibration position) + */ + inline bool gcode_M364() { + SERIAL_ECHOLNPGM(" Cal: Theta-Psi 90"); + return SCARA_move_to_cal(45, 135); + } + +#endif // SCARA + +#if ENABLED(EXT_SOLENOID) + + void enable_solenoid(const uint8_t num) { + switch (num) { + case 0: + OUT_WRITE(SOL0_PIN, HIGH); + break; + #if HAS_SOLENOID_1 && EXTRUDERS > 1 + case 1: + OUT_WRITE(SOL1_PIN, HIGH); + break; + #endif + #if HAS_SOLENOID_2 && EXTRUDERS > 2 + case 2: + OUT_WRITE(SOL2_PIN, HIGH); + break; + #endif + #if HAS_SOLENOID_3 && EXTRUDERS > 3 + case 3: + OUT_WRITE(SOL3_PIN, HIGH); + break; + #endif + #if HAS_SOLENOID_4 && EXTRUDERS > 4 + case 4: + OUT_WRITE(SOL4_PIN, HIGH); + break; + #endif + default: + SERIAL_ECHO_START(); + SERIAL_ECHOLNPGM(MSG_INVALID_SOLENOID); + break; + } + } + + void enable_solenoid_on_active_extruder() { enable_solenoid(active_extruder); } + + void disable_all_solenoids() { + OUT_WRITE(SOL0_PIN, LOW); + #if HAS_SOLENOID_1 && EXTRUDERS > 1 + OUT_WRITE(SOL1_PIN, LOW); + #endif + #if HAS_SOLENOID_2 && EXTRUDERS > 2 + OUT_WRITE(SOL2_PIN, LOW); + #endif + #if HAS_SOLENOID_3 && EXTRUDERS > 3 + OUT_WRITE(SOL3_PIN, LOW); + #endif + #if HAS_SOLENOID_4 && EXTRUDERS > 4 + OUT_WRITE(SOL4_PIN, LOW); + #endif + } + + /** + * M380: Enable solenoid on the active extruder + */ + inline void gcode_M380() { enable_solenoid_on_active_extruder(); } + + /** + * M381: Disable all solenoids + */ + inline void gcode_M381() { disable_all_solenoids(); } + +#endif // EXT_SOLENOID + +/** + * M400: Finish all moves + */ +inline void gcode_M400() { stepper.synchronize(); } + +#if HAS_BED_PROBE + + /** + * M401: Engage Z Servo endstop if available + */ + inline void gcode_M401() { DEPLOY_PROBE(); } + + /** + * M402: Retract Z Servo endstop if enabled + */ + inline void gcode_M402() { STOW_PROBE(); } + +#endif // HAS_BED_PROBE + +#if ENABLED(FILAMENT_WIDTH_SENSOR) + + /** + * M404: Display or set (in current units) the nominal filament width (3mm, 1.75mm ) W<3.0> + */ + inline void gcode_M404() { + if (parser.seen('W')) { + filament_width_nominal = parser.value_linear_units(); + } + else { + SERIAL_PROTOCOLPGM("Filament dia (nominal mm):"); + SERIAL_PROTOCOLLN(filament_width_nominal); + } + } + + /** + * M405: Turn on filament sensor for control + */ + inline void gcode_M405() { + // This is technically a linear measurement, but since it's quantized to centimeters and is a different + // unit than everything else, it uses parser.value_byte() instead of parser.value_linear_units(). + if (parser.seen('D')) { + meas_delay_cm = parser.value_byte(); + NOMORE(meas_delay_cm, MAX_MEASUREMENT_DELAY); + } + + if (filwidth_delay_index[1] == -1) { // Initialize the ring buffer if not done since startup + const uint8_t temp_ratio = thermalManager.widthFil_to_size_ratio() - 100; // -100 to scale within a signed byte + + for (uint8_t i = 0; i < COUNT(measurement_delay); ++i) + measurement_delay[i] = temp_ratio; + + filwidth_delay_index[0] = filwidth_delay_index[1] = 0; + } + + filament_sensor = true; + + //SERIAL_PROTOCOLPGM("Filament dia (measured mm):"); + //SERIAL_PROTOCOL(filament_width_meas); + //SERIAL_PROTOCOLPGM("Extrusion ratio(%):"); + //SERIAL_PROTOCOL(flow_percentage[active_extruder]); + } + + /** + * M406: Turn off filament sensor for control + */ + inline void gcode_M406() { + filament_sensor = false; + calculate_volumetric_multipliers(); // Restore correct 'volumetric_multiplier' value + } + + /** + * M407: Get measured filament diameter on serial output + */ + inline void gcode_M407() { + SERIAL_PROTOCOLPGM("Filament dia (measured mm):"); + SERIAL_PROTOCOLLN(filament_width_meas); + } + +#endif // FILAMENT_WIDTH_SENSOR + +void quickstop_stepper() { + stepper.quick_stop(); + stepper.synchronize(); + set_current_from_steppers_for_axis(ALL_AXES); + SYNC_PLAN_POSITION_KINEMATIC(); +} + +#if HAS_LEVELING + /** + * M420: Enable/Disable Bed Leveling and/or set the Z fade height. + * + * S[bool] Turns leveling on or off + * Z[height] Sets the Z fade height (0 or none to disable) + * V[bool] Verbose - Print the leveling grid + * + * With AUTO_BED_LEVELING_UBL only: + * + * L[index] Load UBL mesh from index (0 is default) + */ + inline void gcode_M420() { + + #if ENABLED(AUTO_BED_LEVELING_UBL) + + // L to load a mesh from the EEPROM + if (parser.seen('L')) { + + #if ENABLED(EEPROM_SETTINGS) + const int8_t storage_slot = parser.has_value() ? parser.value_int() : ubl.state.storage_slot; + const int16_t a = settings.calc_num_meshes(); + + if (!a) { + SERIAL_PROTOCOLLNPGM("?EEPROM storage not available."); + return; + } + + if (!WITHIN(storage_slot, 0, a - 1)) { + SERIAL_PROTOCOLLNPGM("?Invalid storage slot."); + SERIAL_PROTOCOLLNPAIR("?Use 0 to ", a - 1); + return; + } + + settings.load_mesh(storage_slot); + ubl.state.storage_slot = storage_slot; + + #else + + SERIAL_PROTOCOLLNPGM("?EEPROM storage not available."); + return; + + #endif + } + + // L to load a mesh from the EEPROM + if (parser.seen('L') || parser.seen('V')) { + ubl.display_map(0); // Currently only supports one map type + SERIAL_ECHOLNPAIR("UBL_MESH_VALID = ", UBL_MESH_VALID); + SERIAL_ECHOLNPAIR("ubl.state.storage_slot = ", ubl.state.storage_slot); + } + + #endif // AUTO_BED_LEVELING_UBL + + // V to print the matrix or mesh + if (parser.seen('V')) { + #if ABL_PLANAR + planner.bed_level_matrix.debug(PSTR("Bed Level Correction Matrix:")); + #else + 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 + #elif ENABLED(MESH_BED_LEVELING) + SERIAL_ECHOLNPGM("Mesh Bed Level data:"); + mbl_mesh_report(); + #endif + } + #endif + } + + const bool to_enable = parser.boolval('S'); + if (parser.seen('S')) + set_bed_leveling_enabled(to_enable); + + #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) + if (parser.seen('Z')) set_z_fade_height(parser.value_linear_units()); + #endif + + const bool new_status = leveling_is_active(); + + if (to_enable && !new_status) { + SERIAL_ERROR_START(); + SERIAL_ERRORLNPGM(MSG_ERR_M420_FAILED); + } + + SERIAL_ECHO_START(); + SERIAL_ECHOLNPAIR("Bed Leveling ", new_status ? MSG_ON : MSG_OFF); + + #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) + SERIAL_ECHO_START(); + SERIAL_ECHOPGM("Fade Height "); + if (planner.z_fade_height > 0.0) + SERIAL_ECHOLN(planner.z_fade_height); + else + SERIAL_ECHOLNPGM(MSG_OFF); + #endif + } +#endif + +#if ENABLED(MESH_BED_LEVELING) + + /** + * M421: Set a single Mesh Bed Leveling Z coordinate + * + * Usage: + * M421 X Y Z + * M421 X Y Q + * M421 I J Z + * M421 I J Q + */ + inline void gcode_M421() { + const bool hasX = parser.seen('X'), hasI = parser.seen('I'); + const int8_t ix = hasI ? parser.value_int() : hasX ? mbl.probe_index_x(RAW_X_POSITION(parser.value_linear_units())) : -1; + const bool hasY = parser.seen('Y'), hasJ = parser.seen('J'); + const int8_t iy = hasJ ? parser.value_int() : hasY ? mbl.probe_index_y(RAW_Y_POSITION(parser.value_linear_units())) : -1; + const bool hasZ = parser.seen('Z'), hasQ = !hasZ && parser.seen('Q'); + + if (int(hasI && hasJ) + int(hasX && hasY) != 1 || !(hasZ || hasQ)) { + SERIAL_ERROR_START(); + SERIAL_ERRORLNPGM(MSG_ERR_M421_PARAMETERS); + } + else if (ix < 0 || iy < 0) { + SERIAL_ERROR_START(); + SERIAL_ERRORLNPGM(MSG_ERR_MESH_XY); + } + else + mbl.set_z(ix, iy, parser.value_linear_units() + (hasQ ? mbl.z_values[ix][iy] : 0)); + } + +#elif ENABLED(AUTO_BED_LEVELING_BILINEAR) + + /** + * M421: Set a single Mesh Bed Leveling Z coordinate + * + * Usage: + * M421 I J Z + * M421 I J Q + */ + inline void gcode_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'); + + if (!hasI || !hasJ || !(hasZ || hasQ)) { + SERIAL_ERROR_START(); + SERIAL_ERRORLNPGM(MSG_ERR_M421_PARAMETERS); + } + else if (!WITHIN(ix, 0, GRID_MAX_POINTS_X - 1) || !WITHIN(iy, 0, GRID_MAX_POINTS_Y - 1)) { + SERIAL_ERROR_START(); + SERIAL_ERRORLNPGM(MSG_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 + } + } + +#elif ENABLED(AUTO_BED_LEVELING_UBL) + + /** + * M421: Set a single Mesh Bed Leveling Z coordinate + * + * Usage: + * M421 I J Z + * M421 I J Q + * M421 C Z + * M421 C Q + */ + inline void gcode_M421() { + int8_t ix = parser.intval('I', -1), iy = parser.intval('J', -1); + const bool hasI = ix >= 0, + hasJ = iy >= 0, + hasC = parser.seen('C'), + hasZ = parser.seen('Z'), + hasQ = !hasZ && parser.seen('Q'); + + if (hasC) { + const mesh_index_pair location = ubl.find_closest_mesh_point_of_type(REAL, current_position[X_AXIS], current_position[Y_AXIS], USE_NOZZLE_AS_REFERENCE, NULL, false); + ix = location.x_index; + iy = location.y_index; + } + + if (int(hasC) + int(hasI && hasJ) != 1 || !(hasZ || hasQ)) { + SERIAL_ERROR_START(); + SERIAL_ERRORLNPGM(MSG_ERR_M421_PARAMETERS); + } + else if (!WITHIN(ix, 0, GRID_MAX_POINTS_X - 1) || !WITHIN(iy, 0, GRID_MAX_POINTS_Y - 1)) { + SERIAL_ERROR_START(); + SERIAL_ERRORLNPGM(MSG_ERR_MESH_XY); + } + else + ubl.z_values[ix][iy] = parser.value_linear_units() + (hasQ ? ubl.z_values[ix][iy] : 0); + } + +#endif // AUTO_BED_LEVELING_UBL + +#if HAS_M206_COMMAND + + /** + * M428: Set home_offset based on the distance between the + * current_position and the nearest "reference point." + * If an axis is past center its endstop position + * is the reference-point. Otherwise it uses 0. This allows + * the Z offset to be set near the bed when using a max endstop. + * + * M428 can't be used more than 2cm away from 0 or an endstop. + * + * Use M206 to set these values directly. + */ + inline void gcode_M428() { + bool err = false; + LOOP_XYZ(i) { + if (axis_homed[i]) { + const float base = (current_position[i] > (soft_endstop_min[i] + soft_endstop_max[i]) * 0.5) ? base_home_pos((AxisEnum)i) : 0, + diff = base - RAW_POSITION(current_position[i], i); + if (WITHIN(diff, -20, 20)) { + set_home_offset((AxisEnum)i, diff); + } + else { + SERIAL_ERROR_START(); + SERIAL_ERRORLNPGM(MSG_ERR_M428_TOO_FAR); + LCD_ALERTMESSAGEPGM("Err: Too far!"); + BUZZ(200, 40); + err = true; + break; + } + } + } + + if (!err) { + SYNC_PLAN_POSITION_KINEMATIC(); + report_current_position(); + LCD_MESSAGEPGM(MSG_HOME_OFFSETS_APPLIED); + BUZZ(100, 659); + BUZZ(100, 698); + } + } + +#endif // HAS_M206_COMMAND + +/** + * M500: Store settings in EEPROM + */ +inline void gcode_M500() { + (void)settings.save(); +} + +/** + * M501: Read settings from EEPROM + */ +inline void gcode_M501() { + (void)settings.load(); +} + +/** + * M502: Revert to default settings + */ +inline void gcode_M502() { + (void)settings.reset(); +} + +#if DISABLED(DISABLE_M503) + /** + * M503: print settings currently in memory + */ + inline void gcode_M503() { + (void)settings.report(!parser.boolval('S', true)); + } +#endif + +#if ENABLED(ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED) + + /** + * M540: Set whether SD card print should abort on endstop hit (M540 S<0|1>) + */ + inline void gcode_M540() { + if (parser.seen('S')) stepper.abort_on_endstop_hit = parser.value_bool(); + } + +#endif // ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + +#if HAS_BED_PROBE + + void refresh_zprobe_zoffset(const bool no_babystep/*=false*/) { + static float last_zoffset = NAN; + + if (!isnan(last_zoffset)) { + + #if ENABLED(AUTO_BED_LEVELING_BILINEAR) || ENABLED(BABYSTEP_ZPROBE_OFFSET) || ENABLED(DELTA) + const float diff = zprobe_zoffset - last_zoffset; + #endif + + #if ENABLED(AUTO_BED_LEVELING_BILINEAR) + // Correct bilinear grid for new probe offset + if (diff) { + 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] -= diff; + } + #if ENABLED(ABL_BILINEAR_SUBDIVISION) + bed_level_virt_interpolate(); + #endif + #endif + + #if ENABLED(BABYSTEP_ZPROBE_OFFSET) + if (!no_babystep && leveling_is_active()) + thermalManager.babystep_axis(Z_AXIS, -LROUND(diff * planner.axis_steps_per_mm[Z_AXIS])); + #else + UNUSED(no_babystep); + #endif + + #if ENABLED(DELTA) // correct the delta_height + home_offset[Z_AXIS] -= diff; + #endif + } + + last_zoffset = zprobe_zoffset; + } + + inline void gcode_M851() { + SERIAL_ECHO_START(); + SERIAL_ECHOPGM(MSG_ZPROBE_ZOFFSET " "); + if (parser.seen('Z')) { + const float value = parser.value_linear_units(); + if (WITHIN(value, Z_PROBE_OFFSET_RANGE_MIN, Z_PROBE_OFFSET_RANGE_MAX)) { + zprobe_zoffset = value; + refresh_zprobe_zoffset(); + SERIAL_ECHO(zprobe_zoffset); + } + else + SERIAL_ECHOPGM(MSG_Z_MIN " " STRINGIFY(Z_PROBE_OFFSET_RANGE_MIN) " " MSG_Z_MAX " " STRINGIFY(Z_PROBE_OFFSET_RANGE_MAX)); + } + else + SERIAL_ECHOPAIR(": ", zprobe_zoffset); + + SERIAL_EOL(); + } + +#endif // HAS_BED_PROBE + +#if ENABLED(ADVANCED_PAUSE_FEATURE) + + /** + * M600: Pause for filament change + * + * E[distance] - Retract the filament this far (negative value) + * Z[distance] - Move the Z axis by this distance + * X[position] - Move to this X position, with Y + * Y[position] - Move to this Y position, with X + * U[distance] - Retract distance for removal (negative value) (manual reload) + * L[distance] - Extrude distance for insertion (positive value) (manual reload) + * B[count] - Number of times to beep, -1 for indefinite (if equipped with a buzzer) + * + * Default values are used for omitted arguments. + * + */ + inline void gcode_M600() { + + #if ENABLED(HOME_BEFORE_FILAMENT_CHANGE) + // Don't allow filament change without homing first + if (axis_unhomed_error()) home_all_axes(); + #endif + + // Initial retract before move to filament change position + const float retract = parser.seen('E') ? parser.value_axis_units(E_AXIS) : 0 + #ifdef PAUSE_PARK_RETRACT_LENGTH + - (PAUSE_PARK_RETRACT_LENGTH) + #endif + ; + + // Lift Z axis + const float z_lift = parser.linearval('Z', 0 + #ifdef PAUSE_PARK_Z_ADD + + PAUSE_PARK_Z_ADD + #endif + ); + + // Move XY axes to filament exchange position + const float x_pos = parser.linearval('X', 0 + #ifdef PAUSE_PARK_X_POS + + PAUSE_PARK_X_POS + #endif + ); + const float y_pos = parser.linearval('Y', 0 + #ifdef PAUSE_PARK_Y_POS + + PAUSE_PARK_Y_POS + #endif + ); + + // Unload filament + const float unload_length = parser.seen('U') ? parser.value_axis_units(E_AXIS) : 0 + #if defined(FILAMENT_CHANGE_UNLOAD_LENGTH) && FILAMENT_CHANGE_UNLOAD_LENGTH > 0 + - (FILAMENT_CHANGE_UNLOAD_LENGTH) + #endif + ; + + // Load filament + const float load_length = parser.seen('L') ? parser.value_axis_units(E_AXIS) : 0 + #ifdef FILAMENT_CHANGE_LOAD_LENGTH + + FILAMENT_CHANGE_LOAD_LENGTH + #endif + ; + + const int beep_count = parser.intval('B', + #ifdef FILAMENT_CHANGE_NUMBER_OF_ALERT_BEEPS + FILAMENT_CHANGE_NUMBER_OF_ALERT_BEEPS + #else + -1 + #endif + ); + + const bool job_running = print_job_timer.isRunning(); + + if (pause_print(retract, z_lift, x_pos, y_pos, unload_length, beep_count, true)) { + wait_for_filament_reload(beep_count); + resume_print(load_length, ADVANCED_PAUSE_EXTRUDE_LENGTH, beep_count); + } + + // Resume the print job timer if it was running + if (job_running) print_job_timer.start(); + } + +#endif // ADVANCED_PAUSE_FEATURE + +#if ENABLED(MK2_MULTIPLEXER) + + inline void select_multiplexed_stepper(const uint8_t e) { + stepper.synchronize(); + disable_e_steppers(); + WRITE(E_MUX0_PIN, TEST(e, 0) ? HIGH : LOW); + WRITE(E_MUX1_PIN, TEST(e, 1) ? HIGH : LOW); + WRITE(E_MUX2_PIN, TEST(e, 2) ? HIGH : LOW); + safe_delay(100); + } + + /** + * M702: Unload all extruders + */ + inline void gcode_M702() { + for (uint8_t s = 0; s < E_STEPPERS; s++) { + select_multiplexed_stepper(e); + // TODO: standard unload filament function + // MK2 firmware behavior: + // - Make sure temperature is high enough + // - Raise Z to at least 15 to make room + // - Extrude 1cm of filament in 1 second + // - Under 230C quickly purge ~12mm, over 230C purge ~10mm + // - Change E max feedrate to 80, eject the filament from the tube. Sync. + // - Restore E max feedrate to 50 + } + // Go back to the last active extruder + select_multiplexed_stepper(active_extruder); + disable_e_steppers(); + } + +#endif // MK2_MULTIPLEXER + +#if ENABLED(DUAL_X_CARRIAGE) + + /** + * M605: Set dual x-carriage movement mode + * + * M605 S0: Full control mode. The slicer has full control over x-carriage movement + * M605 S1: Auto-park mode. The inactive head will auto park/unpark without slicer involvement + * M605 S2 [Xnnn] [Rmmm]: Duplication mode. The second extruder will duplicate the first with nnn + * units x-offset and an optional differential hotend temperature of + * mmm degrees. E.g., with "M605 S2 X100 R2" the second extruder will duplicate + * the first with a spacing of 100mm in the x direction and 2 degrees hotter. + * + * Note: the X axis should be homed after changing dual x-carriage mode. + */ + inline void gcode_M605() { + stepper.synchronize(); + if (parser.seen('S')) dual_x_carriage_mode = (DualXMode)parser.value_byte(); + switch (dual_x_carriage_mode) { + case DXC_FULL_CONTROL_MODE: + 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)); + if (parser.seen('R')) duplicate_extruder_temp_offset = parser.value_celsius_diff(); + SERIAL_ECHO_START(); + SERIAL_ECHOPGM(MSG_HOTEND_OFFSET); + SERIAL_CHAR(' '); + SERIAL_ECHO(hotend_offset[X_AXIS][0]); + SERIAL_CHAR(','); + SERIAL_ECHO(hotend_offset[Y_AXIS][0]); + SERIAL_CHAR(' '); + SERIAL_ECHO(duplicate_extruder_x_offset); + SERIAL_CHAR(','); + SERIAL_ECHOLN(hotend_offset[Y_AXIS][1]); + break; + default: + dual_x_carriage_mode = DEFAULT_DUAL_X_CARRIAGE_MODE; + break; + } + active_extruder_parked = false; + extruder_duplication_enabled = false; + delayed_move_time = 0; + } + +#elif ENABLED(DUAL_NOZZLE_DUPLICATION_MODE) + + inline void gcode_M605() { + stepper.synchronize(); + extruder_duplication_enabled = parser.intval('S') == (int)DXC_DUPLICATION_MODE; + SERIAL_ECHO_START(); + SERIAL_ECHOLNPAIR(MSG_DUPLICATION_MODE, extruder_duplication_enabled ? MSG_ON : MSG_OFF); + } + +#endif // DUAL_NOZZLE_DUPLICATION_MODE + +#if ENABLED(LIN_ADVANCE) + /** + * M900: Set and/or Get advance K factor and WH/D ratio + * + * K Set advance K factor + * R Set ratio directly (overrides WH/D) + * W H D Set ratio from WH/D + */ + inline void gcode_M900() { + stepper.synchronize(); + + const float newK = parser.floatval('K', -1); + if (newK >= 0) planner.extruder_advance_k = newK; + + float newR = parser.floatval('R', -1); + if (newR < 0) { + const float newD = parser.floatval('D', -1), + newW = parser.floatval('W', -1), + newH = parser.floatval('H', -1); + if (newD >= 0 && newW >= 0 && newH >= 0) + newR = newD ? (newW * newH) / (sq(newD * 0.5) * M_PI) : 0; + } + if (newR >= 0) planner.advance_ed_ratio = newR; + + SERIAL_ECHO_START(); + SERIAL_ECHOPAIR("Advance K=", planner.extruder_advance_k); + SERIAL_ECHOPGM(" E/D="); + const float ratio = planner.advance_ed_ratio; + if (ratio) SERIAL_ECHO(ratio); else SERIAL_ECHOPGM("Auto"); + SERIAL_EOL(); + } +#endif // LIN_ADVANCE + +#if ENABLED(HAVE_TMC2130) + + static void tmc2130_get_current(TMC2130Stepper &st, const char name) { + SERIAL_CHAR(name); + SERIAL_ECHOPGM(" axis driver current: "); + SERIAL_ECHOLN(st.getCurrent()); + } + static void tmc2130_set_current(TMC2130Stepper &st, const char name, const int mA) { + st.setCurrent(mA, R_SENSE, HOLD_MULTIPLIER); + tmc2130_get_current(st, name); + } + + static void tmc2130_report_otpw(TMC2130Stepper &st, const char name) { + SERIAL_CHAR(name); + SERIAL_ECHOPGM(" axis temperature prewarn triggered: "); + serialprintPGM(st.getOTPW() ? PSTR("true") : PSTR("false")); + SERIAL_EOL(); + } + static void tmc2130_clear_otpw(TMC2130Stepper &st, const char name) { + st.clear_otpw(); + SERIAL_CHAR(name); + SERIAL_ECHOLNPGM(" prewarn flag cleared"); + } + + static void tmc2130_get_pwmthrs(TMC2130Stepper &st, const char name, const uint16_t spmm) { + SERIAL_CHAR(name); + SERIAL_ECHOPGM(" stealthChop max speed set to "); + SERIAL_ECHOLN(12650000UL * st.microsteps() / (256 * st.stealth_max_speed() * spmm)); + } + static void tmc2130_set_pwmthrs(TMC2130Stepper &st, const char name, const int32_t thrs, const uint32_t spmm) { + st.stealth_max_speed(12650000UL * st.microsteps() / (256 * thrs * spmm)); + tmc2130_get_pwmthrs(st, name, spmm); + } + + static void tmc2130_get_sgt(TMC2130Stepper &st, const char name) { + SERIAL_CHAR(name); + SERIAL_ECHOPGM(" driver homing sensitivity set to "); + SERIAL_ECHOLN(st.sgt()); + } + static void tmc2130_set_sgt(TMC2130Stepper &st, const char name, const int8_t sgt_val) { + st.sgt(sgt_val); + tmc2130_get_sgt(st, name); + } + + /** + * M906: Set motor current in milliamps using axis codes X, Y, Z, E + * Report driver currents when no axis specified + * + * S1: Enable automatic current control + * S0: Disable + */ + inline void gcode_M906() { + uint16_t values[XYZE]; + LOOP_XYZE(i) + values[i] = parser.intval(axis_codes[i]); + + #if ENABLED(X_IS_TMC2130) + if (values[X_AXIS]) tmc2130_set_current(stepperX, 'X', values[X_AXIS]); + else tmc2130_get_current(stepperX, 'X'); + #endif + #if ENABLED(Y_IS_TMC2130) + if (values[Y_AXIS]) tmc2130_set_current(stepperY, 'Y', values[Y_AXIS]); + else tmc2130_get_current(stepperY, 'Y'); + #endif + #if ENABLED(Z_IS_TMC2130) + if (values[Z_AXIS]) tmc2130_set_current(stepperZ, 'Z', values[Z_AXIS]); + else tmc2130_get_current(stepperZ, 'Z'); + #endif + #if ENABLED(E0_IS_TMC2130) + if (values[E_AXIS]) tmc2130_set_current(stepperE0, 'E', values[E_AXIS]); + else tmc2130_get_current(stepperE0, 'E'); + #endif + + #if ENABLED(AUTOMATIC_CURRENT_CONTROL) + if (parser.seen('S')) auto_current_control = parser.value_bool(); + #endif + } + + /** + * M911: Report TMC2130 stepper driver overtemperature pre-warn flag + * The flag is held by the library and persist until manually cleared by M912 + */ + inline void gcode_M911() { + const bool reportX = parser.seen('X'), reportY = parser.seen('Y'), reportZ = parser.seen('Z'), reportE = parser.seen('E'), + reportAll = (!reportX && !reportY && !reportZ && !reportE) || (reportX && reportY && reportZ && reportE); + #if ENABLED(X_IS_TMC2130) + if (reportX || reportAll) tmc2130_report_otpw(stepperX, 'X'); + #endif + #if ENABLED(Y_IS_TMC2130) + if (reportY || reportAll) tmc2130_report_otpw(stepperY, 'Y'); + #endif + #if ENABLED(Z_IS_TMC2130) + if (reportZ || reportAll) tmc2130_report_otpw(stepperZ, 'Z'); + #endif + #if ENABLED(E0_IS_TMC2130) + if (reportE || reportAll) tmc2130_report_otpw(stepperE0, 'E'); + #endif + } + + /** + * M912: Clear TMC2130 stepper driver overtemperature pre-warn flag held by the library + */ + inline void gcode_M912() { + const bool clearX = parser.seen('X'), clearY = parser.seen('Y'), clearZ = parser.seen('Z'), clearE = parser.seen('E'), + clearAll = (!clearX && !clearY && !clearZ && !clearE) || (clearX && clearY && clearZ && clearE); + #if ENABLED(X_IS_TMC2130) + if (clearX || clearAll) tmc2130_clear_otpw(stepperX, 'X'); + #endif + #if ENABLED(Y_IS_TMC2130) + if (clearY || clearAll) tmc2130_clear_otpw(stepperY, 'Y'); + #endif + #if ENABLED(Z_IS_TMC2130) + if (clearZ || clearAll) tmc2130_clear_otpw(stepperZ, 'Z'); + #endif + #if ENABLED(E0_IS_TMC2130) + if (clearE || clearAll) tmc2130_clear_otpw(stepperE0, 'E'); + #endif + } + + /** + * M913: Set HYBRID_THRESHOLD speed. + */ + #if ENABLED(HYBRID_THRESHOLD) + inline void gcode_M913() { + uint16_t values[XYZE]; + LOOP_XYZE(i) + values[i] = parser.intval(axis_codes[i]); + + #if ENABLED(X_IS_TMC2130) + if (values[X_AXIS]) tmc2130_set_pwmthrs(stepperX, 'X', values[X_AXIS], planner.axis_steps_per_mm[X_AXIS]); + else tmc2130_get_pwmthrs(stepperX, 'X', planner.axis_steps_per_mm[X_AXIS]); + #endif + #if ENABLED(Y_IS_TMC2130) + if (values[Y_AXIS]) tmc2130_set_pwmthrs(stepperY, 'Y', values[Y_AXIS], planner.axis_steps_per_mm[Y_AXIS]); + else tmc2130_get_pwmthrs(stepperY, 'Y', planner.axis_steps_per_mm[Y_AXIS]); + #endif + #if ENABLED(Z_IS_TMC2130) + if (values[Z_AXIS]) tmc2130_set_pwmthrs(stepperZ, 'Z', values[Z_AXIS], planner.axis_steps_per_mm[Z_AXIS]); + else tmc2130_get_pwmthrs(stepperZ, 'Z', planner.axis_steps_per_mm[Z_AXIS]); + #endif + #if ENABLED(E0_IS_TMC2130) + if (values[E_AXIS]) tmc2130_set_pwmthrs(stepperE0, 'E', values[E_AXIS], planner.axis_steps_per_mm[E_AXIS]); + else tmc2130_get_pwmthrs(stepperE0, 'E', planner.axis_steps_per_mm[E_AXIS]); + #endif + } + #endif // HYBRID_THRESHOLD + + /** + * M914: Set SENSORLESS_HOMING sensitivity. + */ + #if ENABLED(SENSORLESS_HOMING) + inline void gcode_M914() { + #if ENABLED(X_IS_TMC2130) + if (parser.seen(axis_codes[X_AXIS])) tmc2130_set_sgt(stepperX, 'X', parser.value_int()); + else tmc2130_get_sgt(stepperX, 'X'); + #endif + #if ENABLED(Y_IS_TMC2130) + if (parser.seen(axis_codes[Y_AXIS])) tmc2130_set_sgt(stepperY, 'Y', parser.value_int()); + else tmc2130_get_sgt(stepperY, 'Y'); + #endif + } + #endif // SENSORLESS_HOMING + +#endif // HAVE_TMC2130 + +/** + * M907: Set digital trimpot motor current using axis codes X, Y, Z, E, B, S + */ +inline void gcode_M907() { + #if HAS_DIGIPOTSS + + LOOP_XYZE(i) if (parser.seen(axis_codes[i])) stepper.digipot_current(i, parser.value_int()); + if (parser.seen('B')) stepper.digipot_current(4, parser.value_int()); + if (parser.seen('S')) for (uint8_t i = 0; i <= 4; i++) stepper.digipot_current(i, parser.value_int()); + + #elif HAS_MOTOR_CURRENT_PWM + + #if PIN_EXISTS(MOTOR_CURRENT_PWM_XY) + if (parser.seen('X')) stepper.digipot_current(0, parser.value_int()); + #endif + #if PIN_EXISTS(MOTOR_CURRENT_PWM_Z) + if (parser.seen('Z')) stepper.digipot_current(1, parser.value_int()); + #endif + #if PIN_EXISTS(MOTOR_CURRENT_PWM_E) + if (parser.seen('E')) stepper.digipot_current(2, parser.value_int()); + #endif + + #endif + + #if ENABLED(DIGIPOT_I2C) + // this one uses actual amps in floating point + LOOP_XYZE(i) if (parser.seen(axis_codes[i])) digipot_i2c_set_current(i, parser.value_float()); + // for each additional extruder (named B,C,D,E..., channels 4,5,6,7...) + for (uint8_t i = NUM_AXIS; i < DIGIPOT_I2C_NUM_CHANNELS; i++) if (parser.seen('B' + i - (NUM_AXIS))) digipot_i2c_set_current(i, parser.value_float()); + #endif + + #if ENABLED(DAC_STEPPER_CURRENT) + if (parser.seen('S')) { + const float dac_percent = parser.value_float(); + for (uint8_t i = 0; i <= 4; i++) dac_current_percent(i, dac_percent); + } + LOOP_XYZE(i) if (parser.seen(axis_codes[i])) dac_current_percent(i, parser.value_float()); + #endif +} + +#if HAS_DIGIPOTSS || ENABLED(DAC_STEPPER_CURRENT) + + /** + * M908: Control digital trimpot directly (M908 P S) + */ + inline void gcode_M908() { + #if HAS_DIGIPOTSS + stepper.digitalPotWrite( + parser.intval('P'), + parser.intval('S') + ); + #endif + #ifdef DAC_STEPPER_CURRENT + dac_current_raw( + parser.byteval('P', -1), + parser.ushortval('S', 0) + ); + #endif + } + + #if ENABLED(DAC_STEPPER_CURRENT) // As with Printrbot RevF + + inline void gcode_M909() { dac_print_values(); } + + inline void gcode_M910() { dac_commit_eeprom(); } + + #endif + +#endif // HAS_DIGIPOTSS || DAC_STEPPER_CURRENT + +#if HAS_MICROSTEPS + + // M350 Set microstepping mode. Warning: Steps per unit remains unchanged. S code sets stepping mode for all drivers. + inline void gcode_M350() { + if (parser.seen('S')) for (int i = 0; i <= 4; i++) 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(); + } + + /** + * M351: Toggle MS1 MS2 pins directly with axis codes X Y Z E B + * S# determines MS1 or MS2, X# sets the pin high/low. + */ + inline void gcode_M351() { + if (parser.seenval('S')) switch (parser.value_byte()) { + case 1: + LOOP_XYZE(i) if (parser.seenval(axis_codes[i])) stepper.microstep_ms(i, parser.value_byte(), -1); + if (parser.seenval('B')) stepper.microstep_ms(4, parser.value_byte(), -1); + break; + case 2: + LOOP_XYZE(i) if (parser.seenval(axis_codes[i])) stepper.microstep_ms(i, -1, parser.value_byte()); + if (parser.seenval('B')) stepper.microstep_ms(4, -1, parser.value_byte()); + break; + } + stepper.microstep_readings(); + } + +#endif // HAS_MICROSTEPS + +#if HAS_CASE_LIGHT + #ifndef INVERT_CASE_LIGHT + #define INVERT_CASE_LIGHT false + #endif + uint8_t case_light_brightness; // LCD routine wants INT + bool case_light_on; + + void update_case_light() { + pinMode(CASE_LIGHT_PIN, OUTPUT); // digitalWrite doesn't set the port mode + if (case_light_on) { + if (USEABLE_HARDWARE_PWM(CASE_LIGHT_PIN)) { + analogWrite(CASE_LIGHT_PIN, INVERT_CASE_LIGHT ? 255 - case_light_brightness : case_light_brightness); + } + else WRITE(CASE_LIGHT_PIN, INVERT_CASE_LIGHT ? LOW : HIGH); + } + else WRITE(CASE_LIGHT_PIN, INVERT_CASE_LIGHT ? HIGH : LOW); + } +#endif // HAS_CASE_LIGHT + +/** + * 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) + */ +inline void gcode_M355() { + #if HAS_CASE_LIGHT + uint8_t args = 0; + if (parser.seenval('P')) ++args, case_light_brightness = parser.value_byte(); + if (parser.seenval('S')) ++args, case_light_on = parser.value_bool(); + if (args) update_case_light(); + + // always report case light status + SERIAL_ECHO_START(); + if (!case_light_on) { + SERIAL_ECHOLN("Case light: off"); + } + else { + if (!USEABLE_HARDWARE_PWM(CASE_LIGHT_PIN)) SERIAL_ECHOLN("Case light: on"); + else SERIAL_ECHOLNPAIR("Case light: ", (int)case_light_brightness); + } + + #else + SERIAL_ERROR_START(); + SERIAL_ERRORLNPGM(MSG_ERR_M355_NONE); + #endif // HAS_CASE_LIGHT +} + +#if ENABLED(MIXING_EXTRUDER) + + /** + * M163: Set a single mix factor for a mixing extruder + * This is called "weight" by some systems. + * + * S[index] The channel index to set + * P[float] The mix value + * + */ + inline void gcode_M163() { + const int mix_index = parser.intval('S'); + if (mix_index < MIXING_STEPPERS) { + float mix_value = parser.floatval('P'); + NOLESS(mix_value, 0.0); + mixing_factor[mix_index] = RECIPROCAL(mix_value); + } + } + + #if MIXING_VIRTUAL_TOOLS > 1 + + /** + * M164: Store the current mix factors as a virtual tool. + * + * S[index] The virtual tool to store + * + */ + inline void gcode_M164() { + const int tool_index = parser.intval('S'); + if (tool_index < MIXING_VIRTUAL_TOOLS) { + normalize_mix(); + for (uint8_t i = 0; i < MIXING_STEPPERS; i++) + mixing_virtual_tool_mix[tool_index][i] = mixing_factor[i]; + } + } + + #endif + + #if ENABLED(DIRECT_MIXING_IN_G1) + /** + * M165: Set multiple mix factors for a mixing extruder. + * Factors that are left out will be set to 0. + * All factors together must add up to 1.0. + * + * A[factor] Mix factor for extruder stepper 1 + * B[factor] Mix factor for extruder stepper 2 + * C[factor] Mix factor for extruder stepper 3 + * D[factor] Mix factor for extruder stepper 4 + * H[factor] Mix factor for extruder stepper 5 + * I[factor] Mix factor for extruder stepper 6 + * + */ + inline void gcode_M165() { gcode_get_mix(); } + #endif + +#endif // MIXING_EXTRUDER + +/** + * M999: Restart after being stopped + * + * Default behaviour is to flush the serial buffer and request + * a resend to the host starting on the last N line received. + * + * Sending "M999 S1" will resume printing without flushing the + * existing command buffer. + * + */ +inline void gcode_M999() { + Running = true; + lcd_reset_alert_level(); + + if (parser.boolval('S')) return; + + // gcode_LastN = Stopped_gcode_LastN; + FlushSerialRequestResend(); +} + +#if ENABLED(SWITCHING_EXTRUDER) + #if EXTRUDERS > 3 + #define REQ_ANGLES 4 + #define _SERVO_NR (e < 2 ? SWITCHING_EXTRUDER_SERVO_NR : SWITCHING_EXTRUDER_E23_SERVO_NR) + #else + #define REQ_ANGLES 2 + #define _SERVO_NR SWITCHING_EXTRUDER_SERVO_NR + #endif + inline void move_extruder_servo(const uint8_t e) { + constexpr int16_t angles[] = SWITCHING_EXTRUDER_SERVO_ANGLES; + static_assert(COUNT(angles) == REQ_ANGLES, "SWITCHING_EXTRUDER_SERVO_ANGLES needs " STRINGIFY(REQ_ANGLES) " angles."); + stepper.synchronize(); + #if EXTRUDERS & 1 + if (e < EXTRUDERS - 1) + #endif + { + MOVE_SERVO(_SERVO_NR, angles[e]); + safe_delay(500); + } + } +#endif // SWITCHING_EXTRUDER + +#if ENABLED(SWITCHING_NOZZLE) + inline void move_nozzle_servo(const uint8_t e) { + const int16_t angles[2] = SWITCHING_NOZZLE_SERVO_ANGLES; + stepper.synchronize(); + MOVE_SERVO(SWITCHING_NOZZLE_SERVO_NR, angles[e]); + safe_delay(500); + } +#endif + +inline void invalid_extruder_error(const uint8_t e) { + SERIAL_ECHO_START(); + SERIAL_CHAR('T'); + SERIAL_ECHO_F(e, DEC); + SERIAL_CHAR(' '); + SERIAL_ECHOLN(MSG_INVALID_EXTRUDER); +} + +#if ENABLED(PARKING_EXTRUDER) + + #if ENABLED(PARKING_EXTRUDER_SOLENOIDS_INVERT) + #define PE_MAGNET_ON_STATE !PARKING_EXTRUDER_SOLENOIDS_PINS_ACTIVE + #else + #define PE_MAGNET_ON_STATE PARKING_EXTRUDER_SOLENOIDS_PINS_ACTIVE + #endif + + void pe_set_magnet(const uint8_t extruder_num, const uint8_t state) { + switch (extruder_num) { + case 1: OUT_WRITE(SOL1_PIN, state); break; + default: OUT_WRITE(SOL0_PIN, state); break; + } + #if PARKING_EXTRUDER_SOLENOIDS_DELAY > 0 + dwell(PARKING_EXTRUDER_SOLENOIDS_DELAY); + #endif + } + + inline void pe_activate_magnet(const uint8_t extruder_num) { pe_set_magnet(extruder_num, PE_MAGNET_ON_STATE); } + inline void pe_deactivate_magnet(const uint8_t extruder_num) { pe_set_magnet(extruder_num, !PE_MAGNET_ON_STATE); } + +#endif // PARKING_EXTRUDER + +#if HAS_FANMUX + + void fanmux_switch(const uint8_t e) { + WRITE(FANMUX0_PIN, TEST(e, 0) ? HIGH : LOW); + #if PIN_EXISTS(FANMUX1) + WRITE(FANMUX1_PIN, TEST(e, 1) ? HIGH : LOW); + #if PIN_EXISTS(FANMUX2) + WRITE(FANMUX2, TEST(e, 2) ? HIGH : LOW); + #endif + #endif + } + + FORCE_INLINE void fanmux_init(void){ + SET_OUTPUT(FANMUX0_PIN); + #if PIN_EXISTS(FANMUX1) + SET_OUTPUT(FANMUX1_PIN); + #if PIN_EXISTS(FANMUX2) + SET_OUTPUT(FANMUX2_PIN); + #endif + #endif + fanmux_switch(0); + } + +#endif // HAS_FANMUX + +/** + * 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 tmp_extruder, const float fr_mm_s/*=0.0*/, bool no_move/*=false*/) { + #if ENABLED(MIXING_EXTRUDER) && MIXING_VIRTUAL_TOOLS > 1 + + if (tmp_extruder >= MIXING_VIRTUAL_TOOLS) + return invalid_extruder_error(tmp_extruder); + + // T0-Tnnn: Switch virtual tool by changing the mix + for (uint8_t j = 0; j < MIXING_STEPPERS; j++) + mixing_factor[j] = mixing_virtual_tool_mix[tmp_extruder][j]; + + #else // !MIXING_EXTRUDER || MIXING_VIRTUAL_TOOLS <= 1 + + if (tmp_extruder >= EXTRUDERS) + return invalid_extruder_error(tmp_extruder); + + #if HOTENDS > 1 + + const float old_feedrate_mm_s = fr_mm_s > 0.0 ? fr_mm_s : feedrate_mm_s; + + feedrate_mm_s = fr_mm_s > 0.0 ? fr_mm_s : XY_PROBE_FEEDRATE_MM_S; + + if (tmp_extruder != active_extruder) { + if (!no_move && axis_unhomed_error()) { + no_move = true; + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("No move on toolchange"); + #endif + } + + // Save current position to destination, for use later + set_destination_to_current(); + + #if ENABLED(DUAL_X_CARRIAGE) + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOPGM("Dual X Carriage Mode "); + switch (dual_x_carriage_mode) { + case DXC_FULL_CONTROL_MODE: SERIAL_ECHOLNPGM("DXC_FULL_CONTROL_MODE"); break; + case DXC_AUTO_PARK_MODE: SERIAL_ECHOLNPGM("DXC_AUTO_PARK_MODE"); break; + case DXC_DUPLICATION_MODE: SERIAL_ECHOLNPGM("DXC_DUPLICATION_MODE"); break; + } + } + #endif + + const float xhome = x_home_pos(active_extruder); + if (dual_x_carriage_mode == DXC_AUTO_PARK_MODE + && IsRunning() + && (delayed_move_time || current_position[X_AXIS] != xhome) + ) { + float raised_z = current_position[Z_AXIS] + TOOLCHANGE_PARK_ZLIFT; + #if ENABLED(MAX_SOFTWARE_ENDSTOPS) + NOMORE(raised_z, soft_endstop_max[Z_AXIS]); + #endif + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOLNPAIR("Raise to ", raised_z); + SERIAL_ECHOLNPAIR("MoveX to ", xhome); + SERIAL_ECHOLNPAIR("Lower to ", current_position[Z_AXIS]); + } + #endif + // Park old head: 1) raise 2) move to park position 3) lower + for (uint8_t i = 0; i < 3; i++) + planner.buffer_line( + i == 0 ? current_position[X_AXIS] : xhome, + current_position[Y_AXIS], + i == 2 ? current_position[Z_AXIS] : raised_z, + current_position[E_AXIS], + planner.max_feedrate_mm_s[i == 1 ? X_AXIS : Z_AXIS], + active_extruder + ); + stepper.synchronize(); + } + + // Apply Y & Z extruder offset (X offset is used as home pos with Dual X) + current_position[Y_AXIS] -= hotend_offset[Y_AXIS][active_extruder] - hotend_offset[Y_AXIS][tmp_extruder]; + current_position[Z_AXIS] -= hotend_offset[Z_AXIS][active_extruder] - hotend_offset[Z_AXIS][tmp_extruder]; + + // Activate the new extruder ahead of calling set_axis_is_at_home! + active_extruder = tmp_extruder; + + // This function resets the max/min values - the current position may be overwritten below. + set_axis_is_at_home(X_AXIS); + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("New Extruder", current_position); + #endif + + // Only when auto-parking are carriages safe to move + if (dual_x_carriage_mode != DXC_AUTO_PARK_MODE) no_move = true; + + switch (dual_x_carriage_mode) { + case DXC_FULL_CONTROL_MODE: + // New current position is the position of the activated extruder + current_position[X_AXIS] = LOGICAL_X_POSITION(inactive_extruder_x_pos); + // Save the inactive extruder's position (from the old current_position) + inactive_extruder_x_pos = RAW_X_POSITION(destination[X_AXIS]); + break; + case DXC_AUTO_PARK_MODE: + // record raised toolhead position for use by unpark + COPY(raised_parked_position, current_position); + raised_parked_position[Z_AXIS] += TOOLCHANGE_UNPARK_ZLIFT; + #if ENABLED(MAX_SOFTWARE_ENDSTOPS) + NOMORE(raised_parked_position[Z_AXIS], soft_endstop_max[Z_AXIS]); + #endif + active_extruder_parked = true; + delayed_move_time = 0; + break; + case DXC_DUPLICATION_MODE: + // If the new extruder is the left one, set it "parked" + // This triggers the second extruder to move into the duplication position + active_extruder_parked = (active_extruder == 0); + + if (active_extruder_parked) + current_position[X_AXIS] = LOGICAL_X_POSITION(inactive_extruder_x_pos); + else + current_position[X_AXIS] = destination[X_AXIS] + duplicate_extruder_x_offset; + inactive_extruder_x_pos = RAW_X_POSITION(destination[X_AXIS]); + extruder_duplication_enabled = false; + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOLNPAIR("Set inactive_extruder_x_pos=", inactive_extruder_x_pos); + SERIAL_ECHOLNPGM("Clear extruder_duplication_enabled"); + } + #endif + break; + } + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOLNPAIR("Active extruder parked: ", active_extruder_parked ? "yes" : "no"); + DEBUG_POS("New extruder (parked)", current_position); + } + #endif + + // No extra case for HAS_ABL in DUAL_X_CARRIAGE. Does that mean they don't work together? + + #else // !DUAL_X_CARRIAGE + + #if ENABLED(PARKING_EXTRUDER) // Dual Parking extruder + const float z_diff = hotend_offset[Z_AXIS][active_extruder] - hotend_offset[Z_AXIS][tmp_extruder]; + float z_raise = 0; + if (!no_move) { + + const float parkingposx[] = PARKING_EXTRUDER_PARKING_X, + midpos = ((parkingposx[1] - parkingposx[0])/2) + parkingposx[0] + hotend_offset[X_AXIS][active_extruder], + grabpos = parkingposx[tmp_extruder] + hotend_offset[X_AXIS][active_extruder] + + (tmp_extruder == 0 ? -(PARKING_EXTRUDER_GRAB_DISTANCE) : PARKING_EXTRUDER_GRAB_DISTANCE); + /** + * Steps: + * 1. raise Z-Axis to have enough clearance + * 2. move to park poition of old extruder + * 3. disengage magnetc field, wait for delay + * 4. move near new extruder + * 5. engage magnetic field for new extruder + * 6. move to parking incl. offset of new extruder + * 7. lower Z-Axis + */ + + // STEP 1 + #if ENABLED(DEBUG_LEVELING_FEATURE) + SERIAL_ECHOLNPGM("Starting Autopark"); + if (DEBUGGING(LEVELING)) DEBUG_POS("current position:", current_position); + #endif + z_raise = PARKING_EXTRUDER_SECURITY_RAISE; + current_position[Z_AXIS] += z_raise; + #if ENABLED(DEBUG_LEVELING_FEATURE) + SERIAL_ECHOLNPGM("(1) Raise Z-Axis "); + if (DEBUGGING(LEVELING)) DEBUG_POS("Moving to Raised Z-Position", current_position); + #endif + planner.buffer_line_kinematic(current_position, planner.max_feedrate_mm_s[Z_AXIS], active_extruder); + stepper.synchronize(); + + // STEP 2 + current_position[X_AXIS] = parkingposx[active_extruder] + hotend_offset[X_AXIS][active_extruder]; + #if ENABLED(DEBUG_LEVELING_FEATURE) + SERIAL_ECHOLNPAIR("(2) Park extruder ", active_extruder); + if (DEBUGGING(LEVELING)) DEBUG_POS("Moving ParkPos", current_position); + #endif + planner.buffer_line_kinematic(current_position, planner.max_feedrate_mm_s[X_AXIS], active_extruder); + stepper.synchronize(); + + // STEP 3 + #if ENABLED(DEBUG_LEVELING_FEATURE) + SERIAL_ECHOLNPGM("(3) Disengage magnet "); + #endif + pe_deactivate_magnet(active_extruder); + + // STEP 4 + #if ENABLED(DEBUG_LEVELING_FEATURE) + SERIAL_ECHOLNPGM("(4) Move to position near new extruder"); + #endif + current_position[X_AXIS] += (active_extruder == 0 ? 10 : -10); // move 10mm away from parked extruder + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("Moving away from parked extruder", current_position); + #endif + planner.buffer_line_kinematic(current_position, planner.max_feedrate_mm_s[X_AXIS], active_extruder); + stepper.synchronize(); + + // STEP 5 + #if ENABLED(DEBUG_LEVELING_FEATURE) + SERIAL_ECHOLNPGM("(5) Engage magnetic field"); + #endif + + #if ENABLED(PARKING_EXTRUDER_SOLENOIDS_INVERT) + pe_activate_magnet(active_extruder); //just save power for inverted magnets + #endif + pe_activate_magnet(tmp_extruder); + + // STEP 6 + current_position[X_AXIS] = grabpos + (tmp_extruder == 0 ? (+10) : (-10)); + planner.buffer_line_kinematic(current_position, planner.max_feedrate_mm_s[X_AXIS], active_extruder); + current_position[X_AXIS] = grabpos; + #if ENABLED(DEBUG_LEVELING_FEATURE) + SERIAL_ECHOLNPAIR("(6) Unpark extruder ", tmp_extruder); + if (DEBUGGING(LEVELING)) DEBUG_POS("Move UnparkPos", current_position); + #endif + planner.buffer_line_kinematic(current_position, planner.max_feedrate_mm_s[X_AXIS]/2, active_extruder); + stepper.synchronize(); + + // Step 7 + current_position[X_AXIS] = midpos - hotend_offset[X_AXIS][tmp_extruder]; + #if ENABLED(DEBUG_LEVELING_FEATURE) + SERIAL_ECHOLNPGM("(7) Move midway between hotends"); + if (DEBUGGING(LEVELING)) DEBUG_POS("Move midway to new extruder", current_position); + #endif + planner.buffer_line_kinematic(current_position, planner.max_feedrate_mm_s[X_AXIS], active_extruder); + stepper.synchronize(); + #if ENABLED(DEBUG_LEVELING_FEATURE) + SERIAL_ECHOLNPGM("Autopark done."); + #endif + } + else { // nomove == true + // Only engage magnetic field for new extruder + pe_activate_magnet(tmp_extruder); + #if ENABLED(PARKING_EXTRUDER_SOLENOIDS_INVERT) + pe_activate_magnet(active_extruder); // Just save power for inverted magnets + #endif + } + current_position[Z_AXIS] -= hotend_offset[Z_AXIS][tmp_extruder] - hotend_offset[Z_AXIS][active_extruder]; // Apply Zoffset + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("Applying Z-offset", current_position); + #endif + + #endif // dualParking extruder + + #if ENABLED(SWITCHING_NOZZLE) + #define DONT_SWITCH (SWITCHING_EXTRUDER_SERVO_NR == SWITCHING_NOZZLE_SERVO_NR) + // <0 if the new nozzle is higher, >0 if lower. A bigger raise when lower. + const float z_diff = hotend_offset[Z_AXIS][active_extruder] - hotend_offset[Z_AXIS][tmp_extruder], + z_raise = 0.3 + (z_diff > 0.0 ? z_diff : 0.0); + + // Always raise by some amount (destination copied from current_position earlier) + current_position[Z_AXIS] += z_raise; + planner.buffer_line_kinematic(current_position, planner.max_feedrate_mm_s[Z_AXIS], active_extruder); + move_nozzle_servo(tmp_extruder); + #endif + + /** + * Set current_position to the position of the new nozzle. + * Offsets are based on linear distance, so we need to get + * the resulting position in coordinate space. + * + * - With grid or 3-point leveling, offset XYZ by a tilted vector + * - With mesh leveling, update Z for the new position + * - Otherwise, just use the raw linear distance + * + * Software endstops are altered here too. Consider a case where: + * E0 at X=0 ... E1 at X=10 + * When we switch to E1 now X=10, but E1 can't move left. + * To express this we apply the change in XY to the software endstops. + * E1 can move farther right than E0, so the right limit is extended. + * + * Note that we don't adjust the Z software endstops. Why not? + * Consider a case where Z=0 (here) and switching to E1 makes Z=1 + * because the bed is 1mm lower at the new position. As long as + * the first nozzle is out of the way, the carriage should be + * allowed to move 1mm lower. This technically "breaks" the + * Z software endstop. But this is technically correct (and + * there is no viable alternative). + */ + #if ABL_PLANAR + // Offset extruder, make sure to apply the bed level rotation matrix + vector_3 tmp_offset_vec = vector_3(hotend_offset[X_AXIS][tmp_extruder], + hotend_offset[Y_AXIS][tmp_extruder], + 0), + act_offset_vec = vector_3(hotend_offset[X_AXIS][active_extruder], + hotend_offset[Y_AXIS][active_extruder], + 0), + offset_vec = tmp_offset_vec - act_offset_vec; + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + tmp_offset_vec.debug(PSTR("tmp_offset_vec")); + act_offset_vec.debug(PSTR("act_offset_vec")); + offset_vec.debug(PSTR("offset_vec (BEFORE)")); + } + #endif + + offset_vec.apply_rotation(planner.bed_level_matrix.transpose(planner.bed_level_matrix)); + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) offset_vec.debug(PSTR("offset_vec (AFTER)")); + #endif + + // Adjustments to the current position + const float xydiff[2] = { offset_vec.x, offset_vec.y }; + current_position[Z_AXIS] += offset_vec.z; + + #else // !ABL_PLANAR + + const float xydiff[2] = { + hotend_offset[X_AXIS][tmp_extruder] - hotend_offset[X_AXIS][active_extruder], + hotend_offset[Y_AXIS][tmp_extruder] - hotend_offset[Y_AXIS][active_extruder] + }; + + #if ENABLED(MESH_BED_LEVELING) + + if (leveling_is_active()) { + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) SERIAL_ECHOPAIR("Z before MBL: ", current_position[Z_AXIS]); + #endif + float x2 = current_position[X_AXIS] + xydiff[X_AXIS], + y2 = current_position[Y_AXIS] + xydiff[Y_AXIS], + z1 = current_position[Z_AXIS], z2 = z1; + planner.apply_leveling(current_position[X_AXIS], current_position[Y_AXIS], z1); + planner.apply_leveling(x2, y2, z2); + current_position[Z_AXIS] += z2 - z1; + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) + SERIAL_ECHOLNPAIR(" after: ", current_position[Z_AXIS]); + #endif + } + + #endif // MESH_BED_LEVELING + + #endif // !HAS_ABL + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOPAIR("Offset Tool XY by { ", xydiff[X_AXIS]); + SERIAL_ECHOPAIR(", ", xydiff[Y_AXIS]); + SERIAL_ECHOLNPGM(" }"); + } + #endif + + // The newly-selected extruder XY is actually at... + current_position[X_AXIS] += xydiff[X_AXIS]; + current_position[Y_AXIS] += xydiff[Y_AXIS]; + #if HAS_WORKSPACE_OFFSET || ENABLED(DUAL_X_CARRIAGE) || ENABLED(PARKING_EXTRUDER) + for (uint8_t i = X_AXIS; i <= Y_AXIS; i++) { + #if HAS_POSITION_SHIFT + position_shift[i] += xydiff[i]; + #endif + update_software_endstops((AxisEnum)i); + } + #endif + + // Set the new active extruder + active_extruder = tmp_extruder; + + #endif // !DUAL_X_CARRIAGE + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("Sync After Toolchange", current_position); + #endif + + // Tell the planner the new "current position" + SYNC_PLAN_POSITION_KINEMATIC(); + + // Move to the "old position" (move the extruder into place) + if (!no_move && IsRunning()) { + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("Move back", destination); + #endif + prepare_move_to_destination(); + } + + #if ENABLED(SWITCHING_NOZZLE) + // Move back down, if needed. (Including when the new tool is higher.) + if (z_raise != z_diff) { + destination[Z_AXIS] += z_diff; + feedrate_mm_s = planner.max_feedrate_mm_s[Z_AXIS]; + prepare_move_to_destination(); + } + #endif + + } // (tmp_extruder != active_extruder) + + stepper.synchronize(); + + #if ENABLED(EXT_SOLENOID) && !ENABLED(PARKING_EXTRUDER) + disable_all_solenoids(); + enable_solenoid_on_active_extruder(); + #endif // EXT_SOLENOID + + feedrate_mm_s = old_feedrate_mm_s; + + #else // HOTENDS <= 1 + + UNUSED(fr_mm_s); + UNUSED(no_move); + + #if ENABLED(MK2_MULTIPLEXER) + if (tmp_extruder >= E_STEPPERS) + return invalid_extruder_error(tmp_extruder); + + select_multiplexed_stepper(tmp_extruder); + #endif + + // Set the new active extruder + active_extruder = tmp_extruder; + + #endif // HOTENDS <= 1 + + #if ENABLED(SWITCHING_EXTRUDER) && !DONT_SWITCH + stepper.synchronize(); + move_extruder_servo(active_extruder); + #endif + + #if HAS_FANMUX + fanmux_switch(active_extruder); + #endif + + SERIAL_ECHO_START(); + SERIAL_ECHOLNPAIR(MSG_ACTIVE_EXTRUDER, (int)active_extruder); + + #endif // !MIXING_EXTRUDER || MIXING_VIRTUAL_TOOLS <= 1 +} + +/** + * T0-T3: Switch tool, usually switching extruders + * + * F[units/min] Set the movement feedrate + * S1 Don't move the tool in XY after change + */ +inline void gcode_T(uint8_t tmp_extruder) { + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOPAIR(">>> gcode_T(", tmp_extruder); + SERIAL_CHAR(')'); + SERIAL_EOL(); + DEBUG_POS("BEFORE", current_position); + } + #endif + + #if HOTENDS == 1 || (ENABLED(MIXING_EXTRUDER) && MIXING_VIRTUAL_TOOLS > 1) + + tool_change(tmp_extruder); + + #elif HOTENDS > 1 + + tool_change( + tmp_extruder, + MMM_TO_MMS(parser.linearval('F')), + (tmp_extruder == active_extruder) || parser.boolval('S') + ); + + #endif + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + DEBUG_POS("AFTER", current_position); + SERIAL_ECHOLNPGM("<<< gcode_T"); + } + #endif +} + +/** + * Process a single command and dispatch it to its handler + * This is called from the main loop() + */ +void process_next_command() { + char * const current_command = command_queue[cmd_queue_index_r]; + + if (DEBUGGING(ECHO)) { + SERIAL_ECHO_START(); + SERIAL_ECHOLN(current_command); + #if ENABLED(M100_FREE_MEMORY_WATCHER) + SERIAL_ECHOPAIR("slot:", cmd_queue_index_r); + M100_dump_routine(" Command Queue:", (const char*)command_queue, (const char*)(command_queue + sizeof(command_queue))); + #endif + } + + KEEPALIVE_STATE(IN_HANDLER); + + // Parse the next command in the queue + parser.parse(current_command); + + // Handle a known G, M, or T + switch (parser.command_letter) { + case 'G': switch (parser.codenum) { + + // G0, G1 + case 0: + case 1: + #if IS_SCARA + gcode_G0_G1(parser.codenum == 0); + #else + gcode_G0_G1(); + #endif + break; + + // G2, G3 + #if ENABLED(ARC_SUPPORT) && DISABLED(SCARA) + case 2: // G2: CW ARC + case 3: // G3: CCW ARC + gcode_G2_G3(parser.codenum == 2); + break; + #endif + + // G4 Dwell + case 4: + gcode_G4(); + break; + + #if ENABLED(BEZIER_CURVE_SUPPORT) + case 5: // G5: Cubic B_spline + gcode_G5(); + break; + #endif // BEZIER_CURVE_SUPPORT + + #if ENABLED(FWRETRACT) + case 10: // G10: retract + gcode_G10(); + break; + case 11: // G11: retract_recover + gcode_G11(); + break; + #endif // FWRETRACT + + #if ENABLED(NOZZLE_CLEAN_FEATURE) + case 12: + gcode_G12(); // G12: Nozzle Clean + break; + #endif // NOZZLE_CLEAN_FEATURE + + #if ENABLED(CNC_WORKSPACE_PLANES) + case 17: // G17: Select Plane XY + gcode_G17(); + break; + case 18: // G18: Select Plane ZX + gcode_G18(); + break; + case 19: // G19: Select Plane YZ + gcode_G19(); + break; + #endif // CNC_WORKSPACE_PLANES + + #if ENABLED(INCH_MODE_SUPPORT) + case 20: // G20: Inch Mode + gcode_G20(); + break; + + case 21: // G21: MM Mode + gcode_G21(); + break; + #endif // INCH_MODE_SUPPORT + + #if ENABLED(AUTO_BED_LEVELING_UBL) && ENABLED(UBL_G26_MESH_VALIDATION) + case 26: // G26: Mesh Validation Pattern generation + gcode_G26(); + break; + #endif // AUTO_BED_LEVELING_UBL + + #if ENABLED(NOZZLE_PARK_FEATURE) + case 27: // G27: Nozzle Park + gcode_G27(); + break; + #endif // NOZZLE_PARK_FEATURE + + case 28: // G28: Home all axes, one at a time + gcode_G28(false); + break; + + #if HAS_LEVELING + case 29: // G29 Detailed Z probe, probes the bed at 3 or more points, + // or provides access to the UBL System if enabled. + gcode_G29(); + break; + #endif // HAS_LEVELING + + #if HAS_BED_PROBE + + case 30: // G30 Single Z probe + gcode_G30(); + break; + + #if ENABLED(Z_PROBE_SLED) + + case 31: // G31: dock the sled + gcode_G31(); + break; + + case 32: // G32: undock the sled + gcode_G32(); + break; + + #endif // Z_PROBE_SLED + + #endif // HAS_BED_PROBE + + #if PROBE_SELECTED + + #if ENABLED(DELTA_AUTO_CALIBRATION) + + case 33: // G33: Delta Auto-Calibration + gcode_G33(); + break; + + #endif // DELTA_AUTO_CALIBRATION + + #endif // PROBE_SELECTED + + #if ENABLED(G38_PROBE_TARGET) + case 38: // G38.2 & G38.3 + if (parser.subcode == 2 || parser.subcode == 3) + gcode_G38(parser.subcode == 2); + break; + #endif + + case 90: // G90 + relative_mode = false; + break; + case 91: // G91 + relative_mode = true; + break; + + case 92: // G92 + gcode_G92(); + break; + + #if ENABLED(AUTO_BED_LEVELING_BILINEAR) || ENABLED(AUTO_BED_LEVELING_UBL) || ENABLED(MESH_BED_LEVELING) + case 42: + gcode_G42(); + break; + #endif + + #if ENABLED(DEBUG_GCODE_PARSER) + case 800: + parser.debug(); // GCode Parser Test for G + break; + #endif + } + break; + + case 'M': switch (parser.codenum) { + #if HAS_RESUME_CONTINUE + case 0: // M0: Unconditional stop - Wait for user button press on LCD + case 1: // M1: Conditional stop - Wait for user button press on LCD + gcode_M0_M1(); + break; + #endif // ULTIPANEL + + #if ENABLED(SPINDLE_LASER_ENABLE) + case 3: + gcode_M3_M4(true); // M3: turn spindle/laser on, set laser/spindle power/speed, set rotation direction CW + break; // synchronizes with movement commands + case 4: + gcode_M3_M4(false); // M4: turn spindle/laser on, set laser/spindle power/speed, set rotation direction CCW + break; // synchronizes with movement commands + case 5: + gcode_M5(); // M5 - turn spindle/laser off + break; // synchronizes with movement commands + #endif + case 17: // M17: Enable all stepper motors + gcode_M17(); + break; + + #if ENABLED(SDSUPPORT) + case 20: // M20: list SD card + gcode_M20(); break; + case 21: // M21: init SD card + gcode_M21(); break; + case 22: // M22: release SD card + gcode_M22(); break; + case 23: // M23: Select file + gcode_M23(); break; + case 24: // M24: Start SD print + gcode_M24(); break; + case 25: // M25: Pause SD print + gcode_M25(); break; + case 26: // M26: Set SD index + gcode_M26(); break; + case 27: // M27: Get SD status + gcode_M27(); break; + case 28: // M28: Start SD write + gcode_M28(); break; + case 29: // M29: Stop SD write + gcode_M29(); break; + case 30: // M30 Delete File + gcode_M30(); break; + case 32: // M32: Select file and start SD print + gcode_M32(); break; + + #if ENABLED(LONG_FILENAME_HOST_SUPPORT) + case 33: // M33: Get the long full path to a file or folder + gcode_M33(); break; + #endif + + #if ENABLED(SDCARD_SORT_ALPHA) && ENABLED(SDSORT_GCODE) + case 34: // M34: Set SD card sorting options + gcode_M34(); break; + #endif // SDCARD_SORT_ALPHA && SDSORT_GCODE + + case 928: // M928: Start SD write + gcode_M928(); break; + #endif // SDSUPPORT + + case 31: // M31: Report time since the start of SD print or last M109 + gcode_M31(); break; + + case 42: // M42: Change pin state + gcode_M42(); break; + + #if ENABLED(PINS_DEBUGGING) + case 43: // M43: Read pin state + gcode_M43(); break; + #endif + + + #if ENABLED(Z_MIN_PROBE_REPEATABILITY_TEST) + case 48: // M48: Z probe repeatability test + gcode_M48(); + break; + #endif // Z_MIN_PROBE_REPEATABILITY_TEST + + #if ENABLED(AUTO_BED_LEVELING_UBL) && ENABLED(UBL_G26_MESH_VALIDATION) + case 49: // M49: Turn on or off G26 debug flag for verbose output + gcode_M49(); + break; + #endif // AUTO_BED_LEVELING_UBL && UBL_G26_MESH_VALIDATION + + case 75: // M75: Start print timer + gcode_M75(); break; + case 76: // M76: Pause print timer + gcode_M76(); break; + case 77: // M77: Stop print timer + gcode_M77(); break; + + #if ENABLED(PRINTCOUNTER) + case 78: // M78: Show print statistics + gcode_M78(); break; + #endif + + #if ENABLED(M100_FREE_MEMORY_WATCHER) + case 100: // M100: Free Memory Report + gcode_M100(); + break; + #endif + + case 104: // M104: Set hot end temperature + gcode_M104(); + break; + + case 110: // M110: Set Current Line Number + gcode_M110(); + break; + + case 111: // M111: Set debug level + gcode_M111(); + break; + + #if DISABLED(EMERGENCY_PARSER) + + case 108: // M108: Cancel Waiting + gcode_M108(); + break; + + case 112: // M112: Emergency Stop + gcode_M112(); + break; + + case 410: // M410 quickstop - Abort all the planned moves. + gcode_M410(); + break; + + #endif + + #if ENABLED(HOST_KEEPALIVE_FEATURE) + case 113: // M113: Set Host Keepalive interval + gcode_M113(); + break; + #endif + + case 140: // M140: Set bed temperature + gcode_M140(); + break; + + case 105: // M105: Report current temperature + gcode_M105(); + KEEPALIVE_STATE(NOT_BUSY); + return; // "ok" already printed + + #if ENABLED(AUTO_REPORT_TEMPERATURES) && (HAS_TEMP_HOTEND || HAS_TEMP_BED) + case 155: // M155: Set temperature auto-report interval + gcode_M155(); + break; + #endif + + case 109: // M109: Wait for hotend temperature to reach target + gcode_M109(); + break; + + #if HAS_TEMP_BED + case 190: // M190: Wait for bed temperature to reach target + gcode_M190(); + break; + #endif // HAS_TEMP_BED + + #if FAN_COUNT > 0 + case 106: // M106: Fan On + gcode_M106(); + break; + case 107: // M107: Fan Off + gcode_M107(); + break; + #endif // FAN_COUNT > 0 + + #if ENABLED(PARK_HEAD_ON_PAUSE) + case 125: // M125: Store current position and move to filament change position + gcode_M125(); break; + #endif + + #if ENABLED(BARICUDA) + // PWM for HEATER_1_PIN + #if HAS_HEATER_1 + case 126: // M126: valve open + gcode_M126(); + break; + case 127: // M127: valve closed + gcode_M127(); + break; + #endif // HAS_HEATER_1 + + // PWM for HEATER_2_PIN + #if HAS_HEATER_2 + case 128: // M128: valve open + gcode_M128(); + break; + case 129: // M129: valve closed + gcode_M129(); + break; + #endif // HAS_HEATER_2 + #endif // BARICUDA + + #if HAS_POWER_SWITCH + + case 80: // M80: Turn on Power Supply + gcode_M80(); + break; + + #endif // HAS_POWER_SWITCH + + case 81: // M81: Turn off Power, including Power Supply, if possible + gcode_M81(); + break; + + case 82: // M82: Set E axis normal mode (same as other axes) + gcode_M82(); + break; + case 83: // M83: Set E axis relative mode + gcode_M83(); + break; + case 18: // M18 => M84 + case 84: // M84: Disable all steppers or set timeout + gcode_M18_M84(); + break; + case 85: // M85: Set inactivity stepper shutdown timeout + gcode_M85(); + break; + case 92: // M92: Set the steps-per-unit for one or more axes + gcode_M92(); + break; + case 114: // M114: Report current position + gcode_M114(); + break; + case 115: // M115: Report capabilities + gcode_M115(); + break; + case 117: // M117: Set LCD message text, if possible + gcode_M117(); + break; + case 118: // M118: Display a message in the host console + gcode_M118(); + break; + case 119: // M119: Report endstop states + gcode_M119(); + break; + case 120: // M120: Enable endstops + gcode_M120(); + break; + case 121: // M121: Disable endstops + gcode_M121(); + break; + + #if ENABLED(ULTIPANEL) + + case 145: // M145: Set material heatup parameters + gcode_M145(); + break; + + #endif + + #if ENABLED(TEMPERATURE_UNITS_SUPPORT) + case 149: // M149: Set temperature units + gcode_M149(); + break; + #endif + + #if HAS_COLOR_LEDS + + case 150: // M150: Set Status LED Color + gcode_M150(); + break; + + #endif // HAS_COLOR_LEDS + + #if ENABLED(MIXING_EXTRUDER) + case 163: // M163: Set a component weight for mixing extruder + gcode_M163(); + break; + #if MIXING_VIRTUAL_TOOLS > 1 + case 164: // M164: Save current mix as a virtual extruder + gcode_M164(); + break; + #endif + #if ENABLED(DIRECT_MIXING_IN_G1) + case 165: // M165: Set multiple mix weights + gcode_M165(); + break; + #endif + #endif + + case 200: // M200: Set filament diameter, E to cubic units + gcode_M200(); + break; + case 201: // M201: Set max acceleration for print moves (units/s^2) + gcode_M201(); + break; + #if 0 // Not used for Sprinter/grbl gen6 + case 202: // M202 + gcode_M202(); + break; + #endif + case 203: // M203: Set max feedrate (units/sec) + gcode_M203(); + break; + case 204: // M204: Set acceleration + gcode_M204(); + break; + case 205: // M205: Set advanced settings + gcode_M205(); + break; + + #if HAS_M206_COMMAND + case 206: // M206: Set home offsets + gcode_M206(); + break; + #endif + + #if ENABLED(DELTA) + case 665: // M665: Set delta configurations + gcode_M665(); + break; + #endif + + #if ENABLED(DELTA) || ENABLED(Z_DUAL_ENDSTOPS) + case 666: // M666: Set delta or dual endstop adjustment + gcode_M666(); + break; + #endif + + #if ENABLED(FWRETRACT) + case 207: // M207: Set Retract Length, Feedrate, and Z lift + gcode_M207(); + break; + case 208: // M208: Set Recover (unretract) Additional Length and Feedrate + gcode_M208(); + break; + case 209: // M209: Turn Automatic Retract Detection on/off + if (MIN_AUTORETRACT <= MAX_AUTORETRACT) gcode_M209(); + break; + #endif // FWRETRACT + + case 211: // M211: Enable, Disable, and/or Report software endstops + gcode_M211(); + break; + + #if HOTENDS > 1 + case 218: // M218: Set a tool offset + gcode_M218(); + break; + #endif + + case 220: // M220: Set Feedrate Percentage: S ("FR" on your LCD) + gcode_M220(); + break; + + case 221: // M221: Set Flow Percentage + gcode_M221(); + break; + + case 226: // M226: Wait until a pin reaches a state + gcode_M226(); + break; + + #if HAS_SERVOS + case 280: // M280: Set servo position absolute + gcode_M280(); + break; + #endif // HAS_SERVOS + + #if HAS_BUZZER + case 300: // M300: Play beep tone + gcode_M300(); + break; + #endif // HAS_BUZZER + + #if ENABLED(PIDTEMP) + case 301: // M301: Set hotend PID parameters + gcode_M301(); + break; + #endif // PIDTEMP + + #if ENABLED(PIDTEMPBED) + case 304: // M304: Set bed PID parameters + gcode_M304(); + break; + #endif // PIDTEMPBED + + #if defined(CHDK) || HAS_PHOTOGRAPH + case 240: // M240: Trigger a camera by emulating a Canon RC-1 : http://www.doc-diy.net/photo/rc-1_hacked/ + gcode_M240(); + break; + #endif // CHDK || PHOTOGRAPH_PIN + + #if HAS_LCD_CONTRAST + case 250: // M250: Set LCD contrast + gcode_M250(); + break; + #endif // HAS_LCD_CONTRAST + + #if ENABLED(EXPERIMENTAL_I2CBUS) + + case 260: // M260: Send data to an i2c slave + gcode_M260(); + break; + + case 261: // M261: Request data from an i2c slave + gcode_M261(); + break; + + #endif // EXPERIMENTAL_I2CBUS + + #if ENABLED(PREVENT_COLD_EXTRUSION) + case 302: // M302: Allow cold extrudes (set the minimum extrude temperature) + gcode_M302(); + break; + #endif // PREVENT_COLD_EXTRUSION + + case 303: // M303: PID autotune + gcode_M303(); + break; + + #if ENABLED(MORGAN_SCARA) + case 360: // M360: SCARA Theta pos1 + if (gcode_M360()) return; + break; + case 361: // M361: SCARA Theta pos2 + if (gcode_M361()) return; + break; + case 362: // M362: SCARA Psi pos1 + if (gcode_M362()) return; + break; + case 363: // M363: SCARA Psi pos2 + if (gcode_M363()) return; + break; + case 364: // M364: SCARA Psi pos3 (90 deg to Theta) + if (gcode_M364()) return; + break; + #endif // SCARA + + case 400: // M400: Finish all moves + gcode_M400(); + break; + + #if HAS_BED_PROBE + case 401: // M401: Deploy probe + gcode_M401(); + break; + case 402: // M402: Stow probe + gcode_M402(); + break; + #endif // HAS_BED_PROBE + + #if ENABLED(FILAMENT_WIDTH_SENSOR) + case 404: // M404: Enter the nominal filament width (3mm, 1.75mm ) N<3.0> or display nominal filament width + gcode_M404(); + break; + case 405: // M405: Turn on filament sensor for control + gcode_M405(); + break; + case 406: // M406: Turn off filament sensor for control + gcode_M406(); + break; + case 407: // M407: Display measured filament diameter + gcode_M407(); + break; + #endif // FILAMENT_WIDTH_SENSOR + + #if HAS_LEVELING + case 420: // M420: Enable/Disable Bed Leveling + gcode_M420(); + break; + #endif + + #if ENABLED(MESH_BED_LEVELING) || ENABLED(AUTO_BED_LEVELING_UBL) || ENABLED(AUTO_BED_LEVELING_BILINEAR) + case 421: // M421: Set a Mesh Bed Leveling Z coordinate + gcode_M421(); + break; + #endif + + #if HAS_M206_COMMAND + case 428: // M428: Apply current_position to home_offset + gcode_M428(); + break; + #endif + + case 500: // M500: Store settings in EEPROM + gcode_M500(); + break; + case 501: // M501: Read settings from EEPROM + gcode_M501(); + break; + case 502: // M502: Revert to default settings + gcode_M502(); + break; + + #if DISABLED(DISABLE_M503) + case 503: // M503: print settings currently in memory + gcode_M503(); + break; + #endif + + #if ENABLED(ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED) + case 540: // M540: Set abort on endstop hit for SD printing + gcode_M540(); + break; + #endif + + #if HAS_BED_PROBE + case 851: // M851: Set Z Probe Z Offset + gcode_M851(); + break; + #endif // HAS_BED_PROBE + + #if ENABLED(ADVANCED_PAUSE_FEATURE) + case 600: // M600: Pause for filament change + gcode_M600(); + break; + #endif // ADVANCED_PAUSE_FEATURE + + #if ENABLED(DUAL_X_CARRIAGE) || ENABLED(DUAL_NOZZLE_DUPLICATION_MODE) + case 605: // M605: Set Dual X Carriage movement mode + gcode_M605(); + break; + #endif // DUAL_X_CARRIAGE + + #if ENABLED(MK2_MULTIPLEXER) + case 702: // M702: Unload all extruders + gcode_M702(); + break; + #endif + + #if ENABLED(LIN_ADVANCE) + case 900: // M900: Set advance K factor. + gcode_M900(); + break; + #endif + + #if ENABLED(HAVE_TMC2130) + case 906: // M906: Set motor current in milliamps using axis codes X, Y, Z, E + gcode_M906(); + break; + #endif + + case 907: // M907: Set digital trimpot motor current using axis codes. + gcode_M907(); + break; + + #if HAS_DIGIPOTSS || ENABLED(DAC_STEPPER_CURRENT) + + case 908: // M908: Control digital trimpot directly. + gcode_M908(); + break; + + #if ENABLED(DAC_STEPPER_CURRENT) // As with Printrbot RevF + + case 909: // M909: Print digipot/DAC current value + gcode_M909(); + break; + + case 910: // M910: Commit digipot/DAC value to external EEPROM + gcode_M910(); + break; + + #endif + + #endif // HAS_DIGIPOTSS || DAC_STEPPER_CURRENT + + #if ENABLED(HAVE_TMC2130) + case 911: // M911: Report TMC2130 prewarn triggered flags + gcode_M911(); + break; + + case 912: // M911: Clear TMC2130 prewarn triggered flags + gcode_M912(); + break; + + #if ENABLED(HYBRID_THRESHOLD) + case 913: // M913: Set HYBRID_THRESHOLD speed. + gcode_M913(); + break; + #endif + + #if ENABLED(SENSORLESS_HOMING) + case 914: // M914: Set SENSORLESS_HOMING sensitivity. + gcode_M914(); + break; + #endif + #endif + + #if HAS_MICROSTEPS + + case 350: // M350: Set microstepping mode. Warning: Steps per unit remains unchanged. S code sets stepping mode for all drivers. + gcode_M350(); + break; + + case 351: // M351: Toggle MS1 MS2 pins directly, S# determines MS1 or MS2, X# sets the pin high/low. + gcode_M351(); + break; + + #endif // HAS_MICROSTEPS + + case 355: // M355 set case light brightness + gcode_M355(); + break; + + #if ENABLED(DEBUG_GCODE_PARSER) + case 800: + parser.debug(); // GCode Parser Test for M + break; + #endif + + #if ENABLED(I2C_POSITION_ENCODERS) + + case 860: // M860 Report encoder module position + gcode_M860(); + break; + + case 861: // M861 Report encoder module status + gcode_M861(); + break; + + case 862: // M862 Perform axis test + gcode_M862(); + break; + + case 863: // M863 Calibrate steps/mm + gcode_M863(); + break; + + case 864: // M864 Change module address + gcode_M864(); + break; + + case 865: // M865 Check module firmware version + gcode_M865(); + break; + + case 866: // M866 Report axis error count + gcode_M866(); + break; + + case 867: // M867 Toggle error correction + gcode_M867(); + break; + + case 868: // M868 Set error correction threshold + gcode_M868(); + break; + + case 869: // M869 Report axis error + gcode_M869(); + break; + + #endif // I2C_POSITION_ENCODERS + + case 999: // M999: Restart after being Stopped + gcode_M999(); + break; + } + break; + + case 'T': + gcode_T(parser.codenum); + break; + + default: parser.unknown_command_error(); + } + + KEEPALIVE_STATE(NOT_BUSY); + + ok_to_send(); +} + +/** + * Send a "Resend: nnn" message to the host to + * indicate that a command needs to be re-sent. + */ +void FlushSerialRequestResend() { + //char command_queue[cmd_queue_index_r][100]="Resend:"; + MYSERIAL.flush(); + SERIAL_PROTOCOLPGM(MSG_RESEND); + SERIAL_PROTOCOLLN(gcode_LastN + 1); + ok_to_send(); +} + +/** + * Send an "ok" message to the host, indicating + * that a command was successfully processed. + * + * If ADVANCED_OK is enabled also include: + * N Line number of the command, if any + * P Planner space remaining + * B Block queue space remaining + */ +void ok_to_send() { + refresh_cmd_timeout(); + if (!send_ok[cmd_queue_index_r]) return; + SERIAL_PROTOCOLPGM(MSG_OK); + #if ENABLED(ADVANCED_OK) + char* p = command_queue[cmd_queue_index_r]; + if (*p == 'N') { + SERIAL_PROTOCOL(' '); + SERIAL_ECHO(*p++); + while (NUMERIC_SIGNED(*p)) + SERIAL_ECHO(*p++); + } + SERIAL_PROTOCOLPGM(" P"); SERIAL_PROTOCOL(int(BLOCK_BUFFER_SIZE - planner.movesplanned() - 1)); + SERIAL_PROTOCOLPGM(" B"); SERIAL_PROTOCOL(BUFSIZE - commands_in_queue); + #endif + SERIAL_EOL(); +} + +#if HAS_SOFTWARE_ENDSTOPS + + /** + * Constrain the given coordinates to the software endstops. + */ + + // NOTE: This makes no sense for delta beds other than Z-axis. + // For delta the X/Y would need to be clamped at + // DELTA_PRINTABLE_RADIUS from center of bed, but delta + // now enforces is_position_reachable for X/Y regardless + // of HAS_SOFTWARE_ENDSTOPS, so that enforcement would be + // redundant here. + + void clamp_to_software_endstops(float target[XYZ]) { + if (!soft_endstops_enabled) return; + #if ENABLED(MIN_SOFTWARE_ENDSTOPS) + #if DISABLED(DELTA) + NOLESS(target[X_AXIS], soft_endstop_min[X_AXIS]); + NOLESS(target[Y_AXIS], soft_endstop_min[Y_AXIS]); + #endif + NOLESS(target[Z_AXIS], soft_endstop_min[Z_AXIS]); + #endif + #if ENABLED(MAX_SOFTWARE_ENDSTOPS) + #if DISABLED(DELTA) + NOMORE(target[X_AXIS], soft_endstop_max[X_AXIS]); + NOMORE(target[Y_AXIS], soft_endstop_max[Y_AXIS]); + #endif + NOMORE(target[Z_AXIS], soft_endstop_max[Z_AXIS]); + #endif + } + +#endif + +#if ENABLED(AUTO_BED_LEVELING_BILINEAR) + + #if ENABLED(ABL_BILINEAR_SUBDIVISION) + #define ABL_BG_SPACING(A) bilinear_grid_spacing_virt[A] + #define ABL_BG_FACTOR(A) bilinear_grid_factor_virt[A] + #define ABL_BG_POINTS_X ABL_GRID_POINTS_VIRT_X + #define ABL_BG_POINTS_Y ABL_GRID_POINTS_VIRT_Y + #define ABL_BG_GRID(X,Y) z_values_virt[X][Y] + #else + #define ABL_BG_SPACING(A) bilinear_grid_spacing[A] + #define ABL_BG_FACTOR(A) bilinear_grid_factor[A] + #define ABL_BG_POINTS_X GRID_MAX_POINTS_X + #define ABL_BG_POINTS_Y GRID_MAX_POINTS_Y + #define ABL_BG_GRID(X,Y) z_values[X][Y] + #endif + + // Get the Z adjustment for non-linear bed leveling + float bilinear_z_offset(const float logical[XYZ]) { + + static float z1, d2, z3, d4, L, D, ratio_x, ratio_y, + last_x = -999.999, last_y = -999.999; + + // Whole units for the grid line indices. Constrained within bounds. + static int8_t gridx, gridy, nextx, nexty, + last_gridx = -99, last_gridy = -99; + + // XY relative to the probed area + const float x = RAW_X_POSITION(logical[X_AXIS]) - bilinear_start[X_AXIS], + y = RAW_Y_POSITION(logical[Y_AXIS]) - bilinear_start[Y_AXIS]; + + #if ENABLED(EXTRAPOLATE_BEYOND_GRID) + // Keep using the last grid box + #define FAR_EDGE_OR_BOX 2 + #else + // Just use the grid far edge + #define FAR_EDGE_OR_BOX 1 + #endif + + if (last_x != x) { + last_x = x; + ratio_x = x * ABL_BG_FACTOR(X_AXIS); + const float gx = constrain(FLOOR(ratio_x), 0, ABL_BG_POINTS_X - FAR_EDGE_OR_BOX); + ratio_x -= gx; // Subtract whole to get the ratio within the grid box + + #if DISABLED(EXTRAPOLATE_BEYOND_GRID) + // Beyond the grid maintain height at grid edges + NOLESS(ratio_x, 0); // Never < 0.0. (> 1.0 is ok when nextx==gridx.) + #endif + + gridx = gx; + nextx = min(gridx + 1, ABL_BG_POINTS_X - 1); + } + + if (last_y != y || last_gridx != gridx) { + + if (last_y != y) { + last_y = y; + ratio_y = y * ABL_BG_FACTOR(Y_AXIS); + const float gy = constrain(FLOOR(ratio_y), 0, ABL_BG_POINTS_Y - FAR_EDGE_OR_BOX); + ratio_y -= gy; + + #if DISABLED(EXTRAPOLATE_BEYOND_GRID) + // Beyond the grid maintain height at grid edges + NOLESS(ratio_y, 0); // Never < 0.0. (> 1.0 is ok when nexty==gridy.) + #endif + + gridy = gy; + nexty = min(gridy + 1, ABL_BG_POINTS_Y - 1); + } + + if (last_gridx != gridx || last_gridy != gridy) { + last_gridx = gridx; + last_gridy = gridy; + // Z at the box corners + z1 = ABL_BG_GRID(gridx, gridy); // left-front + d2 = ABL_BG_GRID(gridx, nexty) - z1; // left-back (delta) + z3 = ABL_BG_GRID(nextx, gridy); // right-front + d4 = ABL_BG_GRID(nextx, nexty) - z3; // right-back (delta) + } + + // Bilinear interpolate. Needed since y or gridx has changed. + L = z1 + d2 * ratio_y; // Linear interp. LF -> LB + const float R = z3 + d4 * ratio_y; // Linear interp. RF -> RB + + D = R - L; + } + + const float offset = L + ratio_x * D; // the offset almost always changes + + /* + static float last_offset = 0; + if (FABS(last_offset - offset) > 0.2) { + SERIAL_ECHOPGM("Sudden Shift at "); + SERIAL_ECHOPAIR("x=", x); + SERIAL_ECHOPAIR(" / ", bilinear_grid_spacing[X_AXIS]); + SERIAL_ECHOLNPAIR(" -> gridx=", gridx); + SERIAL_ECHOPAIR(" y=", y); + SERIAL_ECHOPAIR(" / ", bilinear_grid_spacing[Y_AXIS]); + SERIAL_ECHOLNPAIR(" -> gridy=", gridy); + SERIAL_ECHOPAIR(" ratio_x=", ratio_x); + SERIAL_ECHOLNPAIR(" ratio_y=", ratio_y); + SERIAL_ECHOPAIR(" z1=", z1); + SERIAL_ECHOPAIR(" z2=", z2); + SERIAL_ECHOPAIR(" z3=", z3); + SERIAL_ECHOLNPAIR(" z4=", z4); + SERIAL_ECHOPAIR(" L=", L); + SERIAL_ECHOPAIR(" R=", R); + SERIAL_ECHOLNPAIR(" offset=", offset); + } + last_offset = offset; + //*/ + + return offset; + } + +#endif // AUTO_BED_LEVELING_BILINEAR + +#if ENABLED(DELTA) + + /** + * Recalculate factors used for delta kinematics whenever + * settings have been changed (e.g., by M665). + */ + void recalc_delta_settings(float radius, float diagonal_rod, float tower_angle_trim[ABC]) { + const float trt[ABC] = DELTA_RADIUS_TRIM_TOWER, + drt[ABC] = DELTA_DIAGONAL_ROD_TRIM_TOWER; + delta_tower[A_AXIS][X_AXIS] = cos(RADIANS(210 + tower_angle_trim[A_AXIS])) * (radius + trt[A_AXIS]); // front left tower + delta_tower[A_AXIS][Y_AXIS] = sin(RADIANS(210 + tower_angle_trim[A_AXIS])) * (radius + trt[A_AXIS]); + delta_tower[B_AXIS][X_AXIS] = cos(RADIANS(330 + tower_angle_trim[B_AXIS])) * (radius + trt[B_AXIS]); // front right tower + delta_tower[B_AXIS][Y_AXIS] = sin(RADIANS(330 + tower_angle_trim[B_AXIS])) * (radius + trt[B_AXIS]); + delta_tower[C_AXIS][X_AXIS] = cos(RADIANS( 90 + tower_angle_trim[C_AXIS])) * (radius + trt[C_AXIS]); // back middle tower + delta_tower[C_AXIS][Y_AXIS] = sin(RADIANS( 90 + tower_angle_trim[C_AXIS])) * (radius + trt[C_AXIS]); + delta_diagonal_rod_2_tower[A_AXIS] = sq(diagonal_rod + drt[A_AXIS]); + delta_diagonal_rod_2_tower[B_AXIS] = sq(diagonal_rod + drt[B_AXIS]); + delta_diagonal_rod_2_tower[C_AXIS] = sq(diagonal_rod + drt[C_AXIS]); + } + + #if ENABLED(DELTA_FAST_SQRT) + /** + * Fast inverse sqrt from Quake III Arena + * See: https://en.wikipedia.org/wiki/Fast_inverse_square_root + */ + float Q_rsqrt(float number) { + long i; + float x2, y; + const float threehalfs = 1.5f; + x2 = number * 0.5f; + y = number; + i = * ( long * ) &y; // evil floating point bit level hacking + i = 0x5F3759DF - ( i >> 1 ); // what the f***? + y = * ( float * ) &i; + y = y * ( threehalfs - ( x2 * y * y ) ); // 1st iteration + // y = y * ( threehalfs - ( x2 * y * y ) ); // 2nd iteration, this can be removed + return y; + } + + #define _SQRT(n) (1.0f / Q_rsqrt(n)) + + #else + + #define _SQRT(n) SQRT(n) + + #endif + + /** + * Delta Inverse Kinematics + * + * Calculate the tower positions for a given logical + * position, storing the result in the delta[] array. + * + * This is an expensive calculation, requiring 3 square + * roots per segmented linear move, and strains the limits + * of a Mega2560 with a Graphical Display. + * + * Suggested optimizations include: + * + * - Disable the home_offset (M206) and/or position_shift (G92) + * features to remove up to 12 float additions. + * + * - Use a fast-inverse-sqrt function and add the reciprocal. + * (see above) + */ + + // Macro to obtain the Z position of an individual tower + #define DELTA_Z(T) raw[Z_AXIS] + _SQRT( \ + delta_diagonal_rod_2_tower[T] - HYPOT2( \ + delta_tower[T][X_AXIS] - raw[X_AXIS], \ + delta_tower[T][Y_AXIS] - raw[Y_AXIS] \ + ) \ + ) + + #define DELTA_RAW_IK() do { \ + delta[A_AXIS] = DELTA_Z(A_AXIS); \ + delta[B_AXIS] = DELTA_Z(B_AXIS); \ + delta[C_AXIS] = DELTA_Z(C_AXIS); \ + }while(0) + + #define DELTA_LOGICAL_IK() do { \ + const float raw[XYZ] = { \ + RAW_X_POSITION(logical[X_AXIS]), \ + RAW_Y_POSITION(logical[Y_AXIS]), \ + RAW_Z_POSITION(logical[Z_AXIS]) \ + }; \ + DELTA_RAW_IK(); \ + }while(0) + + #define DELTA_DEBUG() do { \ + SERIAL_ECHOPAIR("cartesian X:", raw[X_AXIS]); \ + SERIAL_ECHOPAIR(" Y:", raw[Y_AXIS]); \ + SERIAL_ECHOLNPAIR(" Z:", raw[Z_AXIS]); \ + SERIAL_ECHOPAIR("delta A:", delta[A_AXIS]); \ + SERIAL_ECHOPAIR(" B:", delta[B_AXIS]); \ + SERIAL_ECHOLNPAIR(" C:", delta[C_AXIS]); \ + }while(0) + + void inverse_kinematics(const float logical[XYZ]) { + DELTA_LOGICAL_IK(); + // DELTA_DEBUG(); + } + + /** + * Calculate the highest Z position where the + * effector has the full range of XY motion. + */ + float delta_safe_distance_from_top() { + float cartesian[XYZ] = { + LOGICAL_X_POSITION(0), + LOGICAL_Y_POSITION(0), + LOGICAL_Z_POSITION(0) + }; + inverse_kinematics(cartesian); + float distance = delta[A_AXIS]; + cartesian[Y_AXIS] = LOGICAL_Y_POSITION(DELTA_PRINTABLE_RADIUS); + inverse_kinematics(cartesian); + return FABS(distance - delta[A_AXIS]); + } + + /** + * Delta Forward Kinematics + * + * See the Wikipedia article "Trilateration" + * https://en.wikipedia.org/wiki/Trilateration + * + * Establish a new coordinate system in the plane of the + * three carriage points. This system has its origin at + * tower1, with tower2 on the X axis. Tower3 is in the X-Y + * plane with a Z component of zero. + * We will define unit vectors in this coordinate system + * in our original coordinate system. Then when we calculate + * the Xnew, Ynew and Znew values, we can translate back into + * the original system by moving along those unit vectors + * by the corresponding values. + * + * Variable names matched to Marlin, c-version, and avoid the + * use of any vector library. + * + * by Andreas Hardtung 2016-06-07 + * based on a Java function from "Delta Robot Kinematics V3" + * by Steve Graves + * + * The result is stored in the cartes[] array. + */ + void forward_kinematics_DELTA(float z1, float z2, float z3) { + // Create a vector in old coordinates along x axis of new coordinate + float p12[3] = { delta_tower[B_AXIS][X_AXIS] - delta_tower[A_AXIS][X_AXIS], delta_tower[B_AXIS][Y_AXIS] - delta_tower[A_AXIS][Y_AXIS], z2 - z1 }; + + // Get the Magnitude of vector. + float d = SQRT( sq(p12[0]) + sq(p12[1]) + sq(p12[2]) ); + + // Create unit vector by dividing by magnitude. + float ex[3] = { p12[0] / d, p12[1] / d, p12[2] / d }; + + // Get the vector from the origin of the new system to the third point. + float p13[3] = { delta_tower[C_AXIS][X_AXIS] - delta_tower[A_AXIS][X_AXIS], delta_tower[C_AXIS][Y_AXIS] - delta_tower[A_AXIS][Y_AXIS], z3 - z1 }; + + // Use the dot product to find the component of this vector on the X axis. + float i = ex[0] * p13[0] + ex[1] * p13[1] + ex[2] * p13[2]; + + // Create a vector along the x axis that represents the x component of p13. + float iex[3] = { ex[0] * i, ex[1] * i, ex[2] * i }; + + // Subtract the X component from the original vector leaving only Y. We use the + // variable that will be the unit vector after we scale it. + float ey[3] = { p13[0] - iex[0], p13[1] - iex[1], p13[2] - iex[2] }; + + // The magnitude of Y component + float j = SQRT( sq(ey[0]) + sq(ey[1]) + sq(ey[2]) ); + + // Convert to a unit vector + ey[0] /= j; ey[1] /= j; ey[2] /= j; + + // The cross product of the unit x and y is the unit z + // float[] ez = vectorCrossProd(ex, ey); + float ez[3] = { + ex[1] * ey[2] - ex[2] * ey[1], + ex[2] * ey[0] - ex[0] * ey[2], + ex[0] * ey[1] - ex[1] * ey[0] + }; + + // We now have the d, i and j values defined in Wikipedia. + // Plug them into the equations defined in Wikipedia for Xnew, Ynew and Znew + float Xnew = (delta_diagonal_rod_2_tower[A_AXIS] - delta_diagonal_rod_2_tower[B_AXIS] + sq(d)) / (d * 2), + Ynew = ((delta_diagonal_rod_2_tower[A_AXIS] - delta_diagonal_rod_2_tower[C_AXIS] + HYPOT2(i, j)) / 2 - i * Xnew) / j, + Znew = SQRT(delta_diagonal_rod_2_tower[A_AXIS] - HYPOT2(Xnew, Ynew)); + + // Start from the origin of the old coordinates and add vectors in the + // old coords that represent the Xnew, Ynew and Znew to find the point + // in the old system. + cartes[X_AXIS] = delta_tower[A_AXIS][X_AXIS] + ex[0] * Xnew + ey[0] * Ynew - ez[0] * Znew; + cartes[Y_AXIS] = delta_tower[A_AXIS][Y_AXIS] + ex[1] * Xnew + ey[1] * Ynew - ez[1] * Znew; + cartes[Z_AXIS] = z1 + ex[2] * Xnew + ey[2] * Ynew - ez[2] * Znew; + } + + void forward_kinematics_DELTA(float point[ABC]) { + forward_kinematics_DELTA(point[A_AXIS], point[B_AXIS], point[C_AXIS]); + } + +#endif // DELTA + +/** + * Get the stepper positions in the cartes[] array. + * Forward kinematics are applied for DELTA and SCARA. + * + * The result is in the current coordinate space with + * leveling applied. The coordinates need to be run through + * unapply_leveling to obtain the "ideal" coordinates + * suitable for current_position, etc. + */ +void get_cartesian_from_steppers() { + #if ENABLED(DELTA) + forward_kinematics_DELTA( + stepper.get_axis_position_mm(A_AXIS), + stepper.get_axis_position_mm(B_AXIS), + stepper.get_axis_position_mm(C_AXIS) + ); + cartes[X_AXIS] += LOGICAL_X_POSITION(0); + cartes[Y_AXIS] += LOGICAL_Y_POSITION(0); + cartes[Z_AXIS] += LOGICAL_Z_POSITION(0); + #elif IS_SCARA + forward_kinematics_SCARA( + stepper.get_axis_position_degrees(A_AXIS), + stepper.get_axis_position_degrees(B_AXIS) + ); + cartes[X_AXIS] += LOGICAL_X_POSITION(0); + cartes[Y_AXIS] += LOGICAL_Y_POSITION(0); + cartes[Z_AXIS] = stepper.get_axis_position_mm(Z_AXIS); + #else + cartes[X_AXIS] = stepper.get_axis_position_mm(X_AXIS); + cartes[Y_AXIS] = stepper.get_axis_position_mm(Y_AXIS); + cartes[Z_AXIS] = stepper.get_axis_position_mm(Z_AXIS); + #endif +} + +/** + * Set the current_position for an axis based on + * the stepper positions, removing any leveling that + * may have been applied. + */ +void set_current_from_steppers_for_axis(const AxisEnum axis) { + get_cartesian_from_steppers(); + #if PLANNER_LEVELING + planner.unapply_leveling(cartes); + #endif + if (axis == ALL_AXES) + COPY(current_position, cartes); + else + current_position[axis] = cartes[axis]; +} + +#if ENABLED(MESH_BED_LEVELING) + + /** + * Prepare a mesh-leveled linear move in a Cartesian setup, + * splitting the move where it crosses mesh borders. + */ + void mesh_line_to_destination(float fr_mm_s, uint8_t x_splits = 0xFF, uint8_t y_splits = 0xFF) { + int cx1 = mbl.cell_index_x(RAW_CURRENT_POSITION(X)), + cy1 = mbl.cell_index_y(RAW_CURRENT_POSITION(Y)), + cx2 = mbl.cell_index_x(RAW_X_POSITION(destination[X_AXIS])), + cy2 = mbl.cell_index_y(RAW_Y_POSITION(destination[Y_AXIS])); + NOMORE(cx1, GRID_MAX_POINTS_X - 2); + NOMORE(cy1, GRID_MAX_POINTS_Y - 2); + NOMORE(cx2, GRID_MAX_POINTS_X - 2); + NOMORE(cy2, GRID_MAX_POINTS_Y - 2); + + if (cx1 == cx2 && cy1 == cy2) { + // Start and end on same mesh square + line_to_destination(fr_mm_s); + set_current_to_destination(); + return; + } + + #define MBL_SEGMENT_END(A) (current_position[A ##_AXIS] + (destination[A ##_AXIS] - current_position[A ##_AXIS]) * normalized_dist) + + float normalized_dist, end[XYZE]; + + // Split at the left/front border of the right/top square + const int8_t gcx = max(cx1, cx2), gcy = max(cy1, cy2); + if (cx2 != cx1 && TEST(x_splits, gcx)) { + COPY(end, destination); + destination[X_AXIS] = LOGICAL_X_POSITION(mbl.index_to_xpos[gcx]); + normalized_dist = (destination[X_AXIS] - current_position[X_AXIS]) / (end[X_AXIS] - current_position[X_AXIS]); + destination[Y_AXIS] = MBL_SEGMENT_END(Y); + CBI(x_splits, gcx); + } + else if (cy2 != cy1 && TEST(y_splits, gcy)) { + COPY(end, destination); + destination[Y_AXIS] = LOGICAL_Y_POSITION(mbl.index_to_ypos[gcy]); + normalized_dist = (destination[Y_AXIS] - current_position[Y_AXIS]) / (end[Y_AXIS] - current_position[Y_AXIS]); + destination[X_AXIS] = MBL_SEGMENT_END(X); + CBI(y_splits, gcy); + } + else { + // Already split on a border + line_to_destination(fr_mm_s); + set_current_to_destination(); + return; + } + + destination[Z_AXIS] = MBL_SEGMENT_END(Z); + destination[E_AXIS] = MBL_SEGMENT_END(E); + + // Do the split and look for more borders + mesh_line_to_destination(fr_mm_s, x_splits, y_splits); + + // Restore destination from stack + COPY(destination, end); + mesh_line_to_destination(fr_mm_s, x_splits, y_splits); + } + +#elif ENABLED(AUTO_BED_LEVELING_BILINEAR) && !IS_KINEMATIC + + #define CELL_INDEX(A,V) ((RAW_##A##_POSITION(V) - bilinear_start[A##_AXIS]) * ABL_BG_FACTOR(A##_AXIS)) + + /** + * Prepare a bilinear-leveled linear move on Cartesian, + * splitting the move where it crosses grid borders. + */ + void bilinear_line_to_destination(float fr_mm_s, uint16_t x_splits = 0xFFFF, uint16_t y_splits = 0xFFFF) { + int cx1 = CELL_INDEX(X, current_position[X_AXIS]), + cy1 = CELL_INDEX(Y, current_position[Y_AXIS]), + cx2 = CELL_INDEX(X, destination[X_AXIS]), + cy2 = CELL_INDEX(Y, destination[Y_AXIS]); + cx1 = constrain(cx1, 0, ABL_BG_POINTS_X - 2); + cy1 = constrain(cy1, 0, ABL_BG_POINTS_Y - 2); + cx2 = constrain(cx2, 0, ABL_BG_POINTS_X - 2); + cy2 = constrain(cy2, 0, ABL_BG_POINTS_Y - 2); + + if (cx1 == cx2 && cy1 == cy2) { + // Start and end on same mesh square + line_to_destination(fr_mm_s); + set_current_to_destination(); + return; + } + + #define LINE_SEGMENT_END(A) (current_position[A ##_AXIS] + (destination[A ##_AXIS] - current_position[A ##_AXIS]) * normalized_dist) + + float normalized_dist, end[XYZE]; + + // Split at the left/front border of the right/top square + const int8_t gcx = max(cx1, cx2), gcy = max(cy1, cy2); + if (cx2 != cx1 && TEST(x_splits, gcx)) { + COPY(end, destination); + destination[X_AXIS] = LOGICAL_X_POSITION(bilinear_start[X_AXIS] + ABL_BG_SPACING(X_AXIS) * gcx); + normalized_dist = (destination[X_AXIS] - current_position[X_AXIS]) / (end[X_AXIS] - current_position[X_AXIS]); + destination[Y_AXIS] = LINE_SEGMENT_END(Y); + CBI(x_splits, gcx); + } + else if (cy2 != cy1 && TEST(y_splits, gcy)) { + COPY(end, destination); + destination[Y_AXIS] = LOGICAL_Y_POSITION(bilinear_start[Y_AXIS] + ABL_BG_SPACING(Y_AXIS) * gcy); + normalized_dist = (destination[Y_AXIS] - current_position[Y_AXIS]) / (end[Y_AXIS] - current_position[Y_AXIS]); + destination[X_AXIS] = LINE_SEGMENT_END(X); + CBI(y_splits, gcy); + } + else { + // Already split on a border + line_to_destination(fr_mm_s); + set_current_to_destination(); + return; + } + + destination[Z_AXIS] = LINE_SEGMENT_END(Z); + destination[E_AXIS] = LINE_SEGMENT_END(E); + + // Do the split and look for more borders + bilinear_line_to_destination(fr_mm_s, x_splits, y_splits); + + // Restore destination from stack + COPY(destination, end); + bilinear_line_to_destination(fr_mm_s, x_splits, y_splits); + } + +#endif // AUTO_BED_LEVELING_BILINEAR + +#if IS_KINEMATIC && !UBL_DELTA + + /** + * Prepare a linear move in a DELTA or SCARA setup. + * + * This calls planner.buffer_line several times, adding + * small incremental moves for DELTA or SCARA. + */ + inline bool prepare_kinematic_move_to(float ltarget[XYZE]) { + + // Get the top feedrate of the move in the XY plane + const float _feedrate_mm_s = MMS_SCALED(feedrate_mm_s); + + // If the move is only in Z/E don't split up the move + if (ltarget[X_AXIS] == current_position[X_AXIS] && ltarget[Y_AXIS] == current_position[Y_AXIS]) { + planner.buffer_line_kinematic(ltarget, _feedrate_mm_s, active_extruder); + return false; + } + + // Fail if attempting move outside printable radius + if (!position_is_reachable_xy(ltarget[X_AXIS], ltarget[Y_AXIS])) return true; + + // Get the cartesian distances moved in XYZE + const float difference[XYZE] = { + ltarget[X_AXIS] - current_position[X_AXIS], + ltarget[Y_AXIS] - current_position[Y_AXIS], + ltarget[Z_AXIS] - current_position[Z_AXIS], + ltarget[E_AXIS] - current_position[E_AXIS] + }; + + // Get the linear distance in XYZ + float cartesian_mm = SQRT(sq(difference[X_AXIS]) + sq(difference[Y_AXIS]) + sq(difference[Z_AXIS])); + + // If the move is very short, check the E move distance + if (UNEAR_ZERO(cartesian_mm)) cartesian_mm = FABS(difference[E_AXIS]); + + // No E move either? Game over. + if (UNEAR_ZERO(cartesian_mm)) return true; + + // Minimum number of seconds to move the given distance + const float seconds = cartesian_mm / _feedrate_mm_s; + + // The number of segments-per-second times the duration + // gives the number of segments + uint16_t segments = delta_segments_per_second * seconds; + + // For SCARA minimum segment size is 0.25mm + #if IS_SCARA + NOMORE(segments, cartesian_mm * 4); + #endif + + // At least one segment is required + NOLESS(segments, 1); + + // The approximate length of each segment + const float inv_segments = 1.0 / float(segments), + segment_distance[XYZE] = { + difference[X_AXIS] * inv_segments, + difference[Y_AXIS] * inv_segments, + difference[Z_AXIS] * inv_segments, + difference[E_AXIS] * inv_segments + }; + + // SERIAL_ECHOPAIR("mm=", cartesian_mm); + // SERIAL_ECHOPAIR(" seconds=", seconds); + // SERIAL_ECHOLNPAIR(" segments=", segments); + + #if IS_SCARA && ENABLED(SCARA_FEEDRATE_SCALING) + // SCARA needs to scale the feed rate from mm/s to degrees/s + const float inv_segment_length = min(10.0, float(segments) / cartesian_mm), // 1/mm/segs + feed_factor = inv_segment_length * _feedrate_mm_s; + float oldA = stepper.get_axis_position_degrees(A_AXIS), + oldB = stepper.get_axis_position_degrees(B_AXIS); + #endif + + // Get the logical current position as starting point + float logical[XYZE]; + COPY(logical, current_position); + + // Drop one segment so the last move is to the exact target. + // If there's only 1 segment, loops will be skipped entirely. + --segments; + + // Calculate and execute the segments + for (uint16_t s = segments + 1; --s;) { + LOOP_XYZE(i) logical[i] += segment_distance[i]; + #if ENABLED(DELTA) + DELTA_LOGICAL_IK(); // Delta can inline its kinematics + #else + inverse_kinematics(logical); + #endif + + ADJUST_DELTA(logical); // Adjust Z if bed leveling is enabled + + #if IS_SCARA && ENABLED(SCARA_FEEDRATE_SCALING) + // For SCARA scale the feed rate from mm/s to degrees/s + // Use ratio between the length of the move and the larger angle change + const float adiff = abs(delta[A_AXIS] - oldA), + bdiff = abs(delta[B_AXIS] - oldB); + planner.buffer_line(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], logical[E_AXIS], max(adiff, bdiff) * feed_factor, active_extruder); + oldA = delta[A_AXIS]; + oldB = delta[B_AXIS]; + #else + planner.buffer_line(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], logical[E_AXIS], _feedrate_mm_s, active_extruder); + #endif + } + + // Since segment_distance is only approximate, + // the final move must be to the exact destination. + + #if IS_SCARA && ENABLED(SCARA_FEEDRATE_SCALING) + // For SCARA scale the feed rate from mm/s to degrees/s + // With segments > 1 length is 1 segment, otherwise total length + inverse_kinematics(ltarget); + ADJUST_DELTA(ltarget); + const float adiff = abs(delta[A_AXIS] - oldA), + bdiff = abs(delta[B_AXIS] - oldB); + planner.buffer_line(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], logical[E_AXIS], max(adiff, bdiff) * feed_factor, active_extruder); + #else + planner.buffer_line_kinematic(ltarget, _feedrate_mm_s, active_extruder); + #endif + + return false; + } + +#else // !IS_KINEMATIC || UBL_DELTA + + /** + * Prepare a linear move in a Cartesian setup. + * If Mesh Bed Leveling is enabled, perform a mesh move. + * + * Returns true if the caller didn't update current_position. + */ + inline bool prepare_move_to_destination_cartesian() { + #if ENABLED(AUTO_BED_LEVELING_UBL) + const float fr_scaled = MMS_SCALED(feedrate_mm_s); + if (ubl.state.active) { // direct use of ubl.state.active for speed + ubl.line_to_destination_cartesian(fr_scaled, active_extruder); + return true; + } + else + line_to_destination(fr_scaled); + #else + // Do not use feedrate_percentage for E or Z only moves + if (current_position[X_AXIS] == destination[X_AXIS] && current_position[Y_AXIS] == destination[Y_AXIS]) + line_to_destination(); + else { + const float fr_scaled = MMS_SCALED(feedrate_mm_s); + #if ENABLED(MESH_BED_LEVELING) + if (mbl.active()) { // direct used of mbl.active() for speed + mesh_line_to_destination(fr_scaled); + return true; + } + else + #elif ENABLED(AUTO_BED_LEVELING_BILINEAR) + if (planner.abl_enabled) { // direct use of abl_enabled for speed + bilinear_line_to_destination(fr_scaled); + return true; + } + else + #endif + line_to_destination(fr_scaled); + } + #endif + return false; + } + +#endif // !IS_KINEMATIC || UBL_DELTA + +#if ENABLED(DUAL_X_CARRIAGE) + + /** + * Prepare a linear move in a dual X axis setup + */ + inline bool prepare_move_to_destination_dualx() { + if (active_extruder_parked) { + switch (dual_x_carriage_mode) { + case DXC_FULL_CONTROL_MODE: + break; + case DXC_AUTO_PARK_MODE: + if (current_position[E_AXIS] == destination[E_AXIS]) { + // This is a travel move (with no extrusion) + // Skip it, but keep track of the current position + // (so it can be used as the start of the next non-travel move) + if (delayed_move_time != 0xFFFFFFFFUL) { + set_current_to_destination(); + NOLESS(raised_parked_position[Z_AXIS], destination[Z_AXIS]); + delayed_move_time = millis(); + return true; + } + } + // unpark extruder: 1) raise, 2) move into starting XY position, 3) lower + for (uint8_t i = 0; i < 3; i++) + planner.buffer_line( + i == 0 ? raised_parked_position[X_AXIS] : current_position[X_AXIS], + i == 0 ? raised_parked_position[Y_AXIS] : current_position[Y_AXIS], + i == 2 ? current_position[Z_AXIS] : raised_parked_position[Z_AXIS], + current_position[E_AXIS], + i == 1 ? PLANNER_XY_FEEDRATE() : planner.max_feedrate_mm_s[Z_AXIS], + active_extruder + ); + delayed_move_time = 0; + active_extruder_parked = false; + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("Clear active_extruder_parked"); + #endif + break; + case DXC_DUPLICATION_MODE: + if (active_extruder == 0) { + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOPAIR("Set planner X", LOGICAL_X_POSITION(inactive_extruder_x_pos)); + SERIAL_ECHOLNPAIR(" ... Line to X", current_position[X_AXIS] + duplicate_extruder_x_offset); + } + #endif + // move duplicate extruder into correct duplication position. + planner.set_position_mm( + LOGICAL_X_POSITION(inactive_extruder_x_pos), + current_position[Y_AXIS], + current_position[Z_AXIS], + current_position[E_AXIS] + ); + planner.buffer_line( + current_position[X_AXIS] + duplicate_extruder_x_offset, + current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], + planner.max_feedrate_mm_s[X_AXIS], 1 + ); + SYNC_PLAN_POSITION_KINEMATIC(); + stepper.synchronize(); + extruder_duplication_enabled = true; + active_extruder_parked = false; + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("Set extruder_duplication_enabled\nClear active_extruder_parked"); + #endif + } + else { + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("Active extruder not 0"); + #endif + } + break; + } + } + return prepare_move_to_destination_cartesian(); + } + +#endif // DUAL_X_CARRIAGE + +/** + * Prepare a single move and get ready for the next one + * + * This may result in several calls to planner.buffer_line to + * do smaller moves for DELTA, SCARA, mesh moves, etc. + */ +void prepare_move_to_destination() { + clamp_to_software_endstops(destination); + refresh_cmd_timeout(); + + #if ENABLED(PREVENT_COLD_EXTRUSION) + + if (!DEBUGGING(DRYRUN)) { + if (destination[E_AXIS] != current_position[E_AXIS]) { + if (thermalManager.tooColdToExtrude(active_extruder)) { + current_position[E_AXIS] = destination[E_AXIS]; // Behave as if the move really took place, but ignore E part + SERIAL_ECHO_START(); + SERIAL_ECHOLNPGM(MSG_ERR_COLD_EXTRUDE_STOP); + } + #if ENABLED(PREVENT_LENGTHY_EXTRUDE) + if (destination[E_AXIS] - current_position[E_AXIS] > EXTRUDE_MAXLENGTH) { + current_position[E_AXIS] = destination[E_AXIS]; // Behave as if the move really took place, but ignore E part + SERIAL_ECHO_START(); + SERIAL_ECHOLNPGM(MSG_ERR_LONG_EXTRUDE_STOP); + } + #endif + } + } + + #endif + + if ( + #if UBL_DELTA // Also works for CARTESIAN (smaller segments follow mesh more closely) + ubl.prepare_segmented_line_to(destination, feedrate_mm_s) + #elif IS_KINEMATIC + prepare_kinematic_move_to(destination) + #elif ENABLED(DUAL_X_CARRIAGE) + prepare_move_to_destination_dualx() + #else + prepare_move_to_destination_cartesian() + #endif + ) return; + + set_current_to_destination(); +} + +#if ENABLED(ARC_SUPPORT) + + #if N_ARC_CORRECTION < 1 + #undef N_ARC_CORRECTION + #define N_ARC_CORRECTION 1 + #endif + + /** + * Plan an arc in 2 dimensions + * + * The arc is approximated by generating many small linear segments. + * The length of each segment is configured in MM_PER_ARC_SEGMENT (Default 1mm) + * Arcs should only be made relatively large (over 5mm), as larger arcs with + * larger segments will tend to be more efficient. Your slicer should have + * options for G2/G3 arc generation. In future these options may be GCode tunable. + */ + void plan_arc( + float logical[XYZE], // Destination position + float *offset, // Center of rotation relative to current_position + uint8_t clockwise // Clockwise? + ) { + #if ENABLED(CNC_WORKSPACE_PLANES) + AxisEnum p_axis, q_axis, l_axis; + switch (workspace_plane) { + case PLANE_XY: p_axis = X_AXIS; q_axis = Y_AXIS; l_axis = Z_AXIS; break; + case PLANE_ZX: p_axis = Z_AXIS; q_axis = X_AXIS; l_axis = Y_AXIS; break; + case PLANE_YZ: p_axis = Y_AXIS; q_axis = Z_AXIS; l_axis = X_AXIS; break; + } + #else + constexpr AxisEnum p_axis = X_AXIS, q_axis = Y_AXIS, l_axis = Z_AXIS; + #endif + + // Radius vector from center to current location + float r_P = -offset[0], r_Q = -offset[1]; + + const float radius = HYPOT(r_P, r_Q), + center_P = current_position[p_axis] - r_P, + center_Q = current_position[q_axis] - r_Q, + rt_X = logical[p_axis] - center_P, + rt_Y = logical[q_axis] - center_Q, + linear_travel = logical[l_axis] - current_position[l_axis], + extruder_travel = logical[E_AXIS] - current_position[E_AXIS]; + + // CCW angle of rotation between position and target from the circle center. Only one atan2() trig computation required. + float angular_travel = ATAN2(r_P * rt_Y - r_Q * rt_X, r_P * rt_X + r_Q * rt_Y); + if (angular_travel < 0) angular_travel += RADIANS(360); + if (clockwise) angular_travel -= RADIANS(360); + + // Make a circle if the angular rotation is 0 and the target is current position + if (angular_travel == 0 && current_position[p_axis] == logical[p_axis] && current_position[q_axis] == logical[q_axis]) + angular_travel = RADIANS(360); + + const float mm_of_travel = HYPOT(angular_travel * radius, FABS(linear_travel)); + if (mm_of_travel < 0.001) return; + + uint16_t segments = FLOOR(mm_of_travel / (MM_PER_ARC_SEGMENT)); + if (segments == 0) segments = 1; + + /** + * Vector rotation by transformation matrix: r is the original vector, r_T is the rotated vector, + * and phi is the angle of rotation. Based on the solution approach by Jens Geisler. + * r_T = [cos(phi) -sin(phi); + * sin(phi) cos(phi)] * r ; + * + * For arc generation, the center of the circle is the axis of rotation and the radius vector is + * defined from the circle center to the initial position. Each line segment is formed by successive + * vector rotations. This requires only two cos() and sin() computations to form the rotation + * matrix for the duration of the entire arc. Error may accumulate from numerical round-off, since + * all double numbers are single precision on the Arduino. (True double precision will not have + * round off issues for CNC applications.) Single precision error can accumulate to be greater than + * tool precision in some cases. Therefore, arc path correction is implemented. + * + * Small angle approximation may be used to reduce computation overhead further. This approximation + * holds for everything, but very small circles and large MM_PER_ARC_SEGMENT values. In other words, + * theta_per_segment would need to be greater than 0.1 rad and N_ARC_CORRECTION would need to be large + * to cause an appreciable drift error. N_ARC_CORRECTION~=25 is more than small enough to correct for + * numerical drift error. N_ARC_CORRECTION may be on the order a hundred(s) before error becomes an + * issue for CNC machines with the single precision Arduino calculations. + * + * This approximation also allows plan_arc to immediately insert a line segment into the planner + * without the initial overhead of computing cos() or sin(). By the time the arc needs to be applied + * a correction, the planner should have caught up to the lag caused by the initial plan_arc overhead. + * This is important when there are successive arc motions. + */ + // Vector rotation matrix values + float arc_target[XYZE]; + 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.5 * sq(theta_per_segment); // Small angle approximation + + // Initialize the linear axis + arc_target[l_axis] = current_position[l_axis]; + + // Initialize the extruder axis + arc_target[E_AXIS] = current_position[E_AXIS]; + + const float fr_mm_s = MMS_SCALED(feedrate_mm_s); + + millis_t next_idle_ms = millis() + 200UL; + + #if N_ARC_CORRECTION > 1 + int8_t arc_recalc_count = N_ARC_CORRECTION; + #endif + + for (uint16_t i = 1; i < segments; i++) { // Iterate (segments-1) times + + thermalManager.manage_heater(); + if (ELAPSED(millis(), next_idle_ms)) { + next_idle_ms = millis() + 200UL; + idle(); + } + + #if N_ARC_CORRECTION > 1 + if (--arc_recalc_count) { + // Apply vector rotation matrix to previous r_P / 1 + const float r_new_Y = r_P * sin_T + r_Q * cos_T; + r_P = r_P * cos_T - r_Q * sin_T; + r_Q = r_new_Y; + } + else + #endif + { + #if N_ARC_CORRECTION > 1 + arc_recalc_count = N_ARC_CORRECTION; + #endif + + // Arc correction to radius vector. Computed only every N_ARC_CORRECTION increments. + // Compute exact location by applying transformation matrix from initial radius vector(=-offset). + // To reduce stuttering, the sin and cos could be computed at different times. + // For now, compute both at the same time. + const float cos_Ti = cos(i * theta_per_segment), sin_Ti = sin(i * theta_per_segment); + r_P = -offset[0] * cos_Ti + offset[1] * sin_Ti; + r_Q = -offset[0] * sin_Ti - offset[1] * cos_Ti; + } + + // Update arc_target location + arc_target[p_axis] = center_P + r_P; + arc_target[q_axis] = center_Q + r_Q; + arc_target[l_axis] += linear_per_segment; + arc_target[E_AXIS] += extruder_per_segment; + + clamp_to_software_endstops(arc_target); + + planner.buffer_line_kinematic(arc_target, fr_mm_s, active_extruder); + } + + // Ensure last segment arrives at target location. + planner.buffer_line_kinematic(logical, fr_mm_s, active_extruder); + + // As far as the parser is concerned, the position is now == target. In reality the + // motion control system might still be processing the action and the real tool position + // in any intermediate location. + set_current_to_destination(); + } // plan_arc + +#endif // ARC_SUPPORT + +#if ENABLED(BEZIER_CURVE_SUPPORT) + + void plan_cubic_move(const float offset[4]) { + cubic_b_spline(current_position, destination, offset, MMS_SCALED(feedrate_mm_s), active_extruder); + + // As far as the parser is concerned, the position is now == destination. In reality the + // motion control system might still be processing the action and the real tool position + // in any intermediate location. + set_current_to_destination(); + } + +#endif // BEZIER_CURVE_SUPPORT + +#if ENABLED(USE_CONTROLLER_FAN) + + void controllerFan() { + 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 + if (X_ENABLE_READ == X_ENABLE_ON || Y_ENABLE_READ == Y_ENABLE_ON || Z_ENABLE_READ == Z_ENABLE_ON || thermalManager.soft_pwm_amount_bed > 0 + || E0_ENABLE_READ == E_ENABLE_ON // If any of the drivers are enabled... + #if E_STEPPERS > 1 + || E1_ENABLE_READ == E_ENABLE_ON + #if HAS_X2_ENABLE + || X2_ENABLE_READ == X_ENABLE_ON + #endif + #if E_STEPPERS > 2 + || E2_ENABLE_READ == E_ENABLE_ON + #if E_STEPPERS > 3 + || E3_ENABLE_READ == E_ENABLE_ON + #if E_STEPPERS > 4 + || E4_ENABLE_READ == E_ENABLE_ON + #endif // E_STEPPERS > 4 + #endif // E_STEPPERS > 3 + #endif // E_STEPPERS > 2 + #endif // E_STEPPERS > 1 + ) { + lastMotorOn = ms; //... set time to NOW so the fan will turn on + } + + // Fan off if no steppers have been enabled for CONTROLLERFAN_SECS seconds + uint8_t speed = (!lastMotorOn || ELAPSED(ms, lastMotorOn + (CONTROLLERFAN_SECS) * 1000UL)) ? 0 : CONTROLLERFAN_SPEED; + + // allows digital or PWM fan output to be used (see M42 handling) + WRITE(CONTROLLER_FAN_PIN, speed); + analogWrite(CONTROLLER_FAN_PIN, speed); + } + } + +#endif // USE_CONTROLLER_FAN + +#if ENABLED(MORGAN_SCARA) + + /** + * Morgan SCARA Forward Kinematics. Results in cartes[]. + * Maths and first version by QHARLEY. + * Integrated into Marlin and slightly restructured by Joachim Cerny. + */ + void forward_kinematics_SCARA(const float &a, const float &b) { + + float a_sin = sin(RADIANS(a)) * L1, + a_cos = cos(RADIANS(a)) * L1, + b_sin = sin(RADIANS(b)) * L2, + b_cos = cos(RADIANS(b)) * L2; + + cartes[X_AXIS] = a_cos + b_cos + SCARA_OFFSET_X; //theta + cartes[Y_AXIS] = a_sin + b_sin + SCARA_OFFSET_Y; //theta+phi + + /* + SERIAL_ECHOPAIR("SCARA FK Angle a=", a); + SERIAL_ECHOPAIR(" b=", b); + SERIAL_ECHOPAIR(" a_sin=", a_sin); + SERIAL_ECHOPAIR(" a_cos=", a_cos); + SERIAL_ECHOPAIR(" b_sin=", b_sin); + SERIAL_ECHOLNPAIR(" b_cos=", b_cos); + SERIAL_ECHOPAIR(" cartes[X_AXIS]=", cartes[X_AXIS]); + SERIAL_ECHOLNPAIR(" cartes[Y_AXIS]=", cartes[Y_AXIS]); + //*/ + } + + /** + * Morgan SCARA Inverse Kinematics. Results in delta[]. + * + * See http://forums.reprap.org/read.php?185,283327 + * + * Maths and first version by QHARLEY. + * Integrated into Marlin and slightly restructured by Joachim Cerny. + */ + void inverse_kinematics(const float logical[XYZ]) { + + static float C2, S2, SK1, SK2, THETA, PSI; + + float sx = RAW_X_POSITION(logical[X_AXIS]) - SCARA_OFFSET_X, // Translate SCARA to standard X Y + sy = RAW_Y_POSITION(logical[Y_AXIS]) - SCARA_OFFSET_Y; // With scaling factor. + + if (L1 == L2) + C2 = HYPOT2(sx, sy) / L1_2_2 - 1; + else + C2 = (HYPOT2(sx, sy) - (L1_2 + L2_2)) / (2.0 * L1 * L2); + + S2 = SQRT(1 - sq(C2)); + + // Unrotated Arm1 plus rotated Arm2 gives the distance from Center to End + SK1 = L1 + L2 * C2; + + // Rotated Arm2 gives the distance from Arm1 to Arm2 + SK2 = L2 * S2; + + // Angle of Arm1 is the difference between Center-to-End angle and the Center-to-Elbow + THETA = ATAN2(SK1, SK2) - ATAN2(sx, sy); + + // Angle of Arm2 + PSI = ATAN2(S2, C2); + + delta[A_AXIS] = DEGREES(THETA); // theta is support arm angle + delta[B_AXIS] = DEGREES(THETA + PSI); // equal to sub arm angle (inverted motor) + delta[C_AXIS] = logical[Z_AXIS]; + + /* + DEBUG_POS("SCARA IK", logical); + DEBUG_POS("SCARA IK", delta); + SERIAL_ECHOPAIR(" SCARA (x,y) ", sx); + SERIAL_ECHOPAIR(",", sy); + SERIAL_ECHOPAIR(" C2=", C2); + SERIAL_ECHOPAIR(" S2=", S2); + SERIAL_ECHOPAIR(" Theta=", THETA); + SERIAL_ECHOLNPAIR(" Phi=", PHI); + //*/ + } + +#endif // MORGAN_SCARA + +#if ENABLED(TEMP_STAT_LEDS) + + static bool red_led = false; + static millis_t next_status_led_update_ms = 0; + + void handle_status_leds(void) { + 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_TEMP_BED + max_temp = MAX3(max_temp, thermalManager.degTargetBed(), thermalManager.degBed()); + #endif + HOTEND_LOOP() + max_temp = MAX3(max_temp, thermalManager.degHotend(e), thermalManager.degTargetHotend(e)); + const bool new_led = (max_temp > 55.0) ? true : (max_temp < 54.0) ? false : red_led; + if (new_led != red_led) { + red_led = new_led; + #if PIN_EXISTS(STAT_LED_RED) + WRITE(STAT_LED_RED_PIN, new_led ? HIGH : LOW); + #if PIN_EXISTS(STAT_LED_BLUE) + WRITE(STAT_LED_BLUE_PIN, new_led ? LOW : HIGH); + #endif + #else + WRITE(STAT_LED_BLUE_PIN, new_led ? HIGH : LOW); + #endif + } + } + } + +#endif + +#if ENABLED(FILAMENT_RUNOUT_SENSOR) + + void handle_filament_runout() { + if (!filament_ran_out) { + filament_ran_out = true; + enqueue_and_echo_commands_P(PSTR(FILAMENT_RUNOUT_SCRIPT)); + stepper.synchronize(); + } + } + +#endif // FILAMENT_RUNOUT_SENSOR + +#if ENABLED(FAST_PWM_FAN) + + void setPwmFrequency(uint8_t pin, int val) { + val &= 0x07; + switch (digitalPinToTimer(pin)) { + #ifdef TCCR0A + #if !AVR_AT90USB1286_FAMILY + case TIMER0A: + #endif + case TIMER0B: + //_SET_CS(0, val); + break; + #endif + #ifdef TCCR1A + case TIMER1A: + case TIMER1B: + //_SET_CS(1, val); + break; + #endif + #ifdef TCCR2 + case TIMER2: + case TIMER2: + _SET_CS(2, val); + break; + #endif + #ifdef TCCR2A + case TIMER2A: + case TIMER2B: + _SET_CS(2, val); + break; + #endif + #ifdef TCCR3A + case TIMER3A: + case TIMER3B: + case TIMER3C: + _SET_CS(3, val); + break; + #endif + #ifdef TCCR4A + case TIMER4A: + case TIMER4B: + case TIMER4C: + _SET_CS(4, val); + break; + #endif + #ifdef TCCR5A + case TIMER5A: + case TIMER5B: + case TIMER5C: + _SET_CS(5, val); + break; + #endif + } + } + +#endif // FAST_PWM_FAN + +float calculate_volumetric_multiplier(const float diameter) { + if (!volumetric_enabled || diameter == 0) return 1.0; + return 1.0 / (M_PI * sq(diameter * 0.5)); +} + +void calculate_volumetric_multipliers() { + for (uint8_t i = 0; i < COUNT(filament_size); i++) + volumetric_multiplier[i] = calculate_volumetric_multiplier(filament_size[i]); +} + +void enable_all_steppers() { + enable_X(); + enable_Y(); + enable_Z(); + enable_E0(); + enable_E1(); + enable_E2(); + enable_E3(); + enable_E4(); +} + +void disable_e_steppers() { + disable_E0(); + disable_E1(); + disable_E2(); + disable_E3(); + disable_E4(); +} + +void disable_all_steppers() { + disable_X(); + disable_Y(); + disable_Z(); + disable_e_steppers(); +} + +#if ENABLED(HAVE_TMC2130) + + void automatic_current_control(TMC2130Stepper &st, String axisID) { + // Check otpw even if we don't use automatic control. Allows for flag inspection. + const bool is_otpw = st.checkOT(); + + // Report if a warning was triggered + static bool previous_otpw = false; + if (is_otpw && !previous_otpw) { + char timestamp[10]; + duration_t elapsed = print_job_timer.duration(); + const bool has_days = (elapsed.value > 60*60*24L); + (void)elapsed.toDigital(timestamp, has_days); + SERIAL_ECHO(timestamp); + SERIAL_ECHOPGM(": "); + SERIAL_ECHO(axisID); + SERIAL_ECHOLNPGM(" driver overtemperature warning!"); + } + previous_otpw = is_otpw; + + #if CURRENT_STEP > 0 && ENABLED(AUTOMATIC_CURRENT_CONTROL) + // Return if user has not enabled current control start with M906 S1. + if (!auto_current_control) return; + + /** + * Decrease current if is_otpw is true. + * Bail out if driver is disabled. + * Increase current if OTPW has not been triggered yet. + */ + uint16_t current = st.getCurrent(); + if (is_otpw) { + st.setCurrent(current - CURRENT_STEP, R_SENSE, HOLD_MULTIPLIER); + #if ENABLED(REPORT_CURRENT_CHANGE) + SERIAL_ECHO(axisID); + SERIAL_ECHOPAIR(" current decreased to ", st.getCurrent()); + #endif + } + + else if (!st.isEnabled()) + return; + + else if (!is_otpw && !st.getOTPW()) { + current += CURRENT_STEP; + if (current <= AUTO_ADJUST_MAX) { + st.setCurrent(current, R_SENSE, HOLD_MULTIPLIER); + #if ENABLED(REPORT_CURRENT_CHANGE) + SERIAL_ECHO(axisID); + SERIAL_ECHOPAIR(" current increased to ", st.getCurrent()); + #endif + } + } + SERIAL_EOL(); + #endif + } + + void checkOverTemp() { + static millis_t next_cOT = 0; + if (ELAPSED(millis(), next_cOT)) { + next_cOT = millis() + 5000; + #if ENABLED(X_IS_TMC2130) + automatic_current_control(stepperX, "X"); + #endif + #if ENABLED(Y_IS_TMC2130) + automatic_current_control(stepperY, "Y"); + #endif + #if ENABLED(Z_IS_TMC2130) + automatic_current_control(stepperZ, "Z"); + #endif + #if ENABLED(X2_IS_TMC2130) + automatic_current_control(stepperX2, "X2"); + #endif + #if ENABLED(Y2_IS_TMC2130) + automatic_current_control(stepperY2, "Y2"); + #endif + #if ENABLED(Z2_IS_TMC2130) + automatic_current_control(stepperZ2, "Z2"); + #endif + #if ENABLED(E0_IS_TMC2130) + automatic_current_control(stepperE0, "E0"); + #endif + #if ENABLED(E1_IS_TMC2130) + automatic_current_control(stepperE1, "E1"); + #endif + #if ENABLED(E2_IS_TMC2130) + automatic_current_control(stepperE2, "E2"); + #endif + #if ENABLED(E3_IS_TMC2130) + automatic_current_control(stepperE3, "E3"); + #endif + #if ENABLED(E4_IS_TMC2130) + automatic_current_control(stepperE4, "E4"); + #endif + } + } + +#endif // HAVE_TMC2130 + +/** + * Manage several 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 + * - Check if pin CHDK needs to go LOW + * - Check for KILL button held down + * - Check for HOME button held down + * - Check if cooling fan needs to be switched on + * - Check if an idle but hot extruder needs filament extruded (EXTRUDER_RUNOUT_PREVENT) + */ +void manage_inactivity(bool ignore_stepper_queue/*=false*/) { + + #if ENABLED(FILAMENT_RUNOUT_SENSOR) + if ((IS_SD_PRINTING || print_job_timer.isRunning()) && (READ(FIL_RUNOUT_PIN) == FIL_RUNOUT_INVERTING)) + handle_filament_runout(); + #endif + + if (commands_in_queue < BUFSIZE) get_available_commands(); + + const millis_t ms = millis(); + + if (max_inactive_time && ELAPSED(ms, previous_cmd_ms + max_inactive_time)) { + SERIAL_ERROR_START(); + SERIAL_ECHOLNPAIR(MSG_KILL_INACTIVE_TIME, parser.command_ptr); + kill(PSTR(MSG_KILLED)); + } + + // Prevent steppers timing-out in the middle of M600 + #if ENABLED(ADVANCED_PAUSE_FEATURE) && ENABLED(PAUSE_PARK_NO_STEPPER_TIMEOUT) + #define MOVE_AWAY_TEST !move_away_flag + #else + #define MOVE_AWAY_TEST true + #endif + + if (MOVE_AWAY_TEST && stepper_inactive_time && ELAPSED(ms, previous_cmd_ms + stepper_inactive_time) + && !ignore_stepper_queue && !planner.blocks_queued()) { + #if ENABLED(DISABLE_INACTIVE_X) + disable_X(); + #endif + #if ENABLED(DISABLE_INACTIVE_Y) + disable_Y(); + #endif + #if ENABLED(DISABLE_INACTIVE_Z) + disable_Z(); + #endif + #if ENABLED(DISABLE_INACTIVE_E) + disable_e_steppers(); + #endif + #if ENABLED(AUTO_BED_LEVELING_UBL) && ENABLED(ULTRA_LCD) // Only needed with an LCD + ubl_lcd_map_control = defer_return_to_status = false; + #endif + } + + #ifdef CHDK // Check if pin should be set to LOW after M240 set it to HIGH + if (chdkActive && ELAPSED(ms, chdkHigh + CHDK_DELAY)) { + chdkActive = false; + WRITE(CHDK, LOW); + } + #endif + + #if HAS_KILL + + // Check if the kill button was pressed and wait just in case it was an accidental + // key kill key press + // ------------------------------------------------------------------------------- + static int killCount = 0; // make the inactivity button a bit less responsive + const int KILL_DELAY = 750; + if (!READ(KILL_PIN)) + killCount++; + else if (killCount > 0) + killCount--; + + // Exceeded threshold and we can confirm that it was not accidental + // KILL the machine + // ---------------------------------------------------------------- + if (killCount >= KILL_DELAY) { + SERIAL_ERROR_START(); + SERIAL_ERRORLNPGM(MSG_KILL_BUTTON); + kill(PSTR(MSG_KILLED)); + } + #endif + + #if HAS_HOME + // Check to see if we have to home, use poor man's debouncer + // --------------------------------------------------------- + static int homeDebounceCount = 0; // poor man's debouncing count + const int HOME_DEBOUNCE_DELAY = 2500; + if (!IS_SD_PRINTING && !READ(HOME_PIN)) { + if (!homeDebounceCount) { + enqueue_and_echo_commands_P(PSTR("G28")); + LCD_MESSAGEPGM(MSG_AUTO_HOME); + } + if (homeDebounceCount < HOME_DEBOUNCE_DELAY) + homeDebounceCount++; + else + homeDebounceCount = 0; + } + #endif + + #if ENABLED(USE_CONTROLLER_FAN) + controllerFan(); // Check if fan should be turned on to cool stepper drivers down + #endif + + #if ENABLED(EXTRUDER_RUNOUT_PREVENT) + if (ELAPSED(ms, previous_cmd_ms + (EXTRUDER_RUNOUT_SECONDS) * 1000UL) + && thermalManager.degHotend(active_extruder) > EXTRUDER_RUNOUT_MINTEMP) { + #if ENABLED(SWITCHING_EXTRUDER) + const bool oldstatus = E0_ENABLE_READ; + enable_E0(); + #else // !SWITCHING_EXTRUDER + bool oldstatus; + switch (active_extruder) { + default: oldstatus = E0_ENABLE_READ; enable_E0(); break; + #if E_STEPPERS > 1 + case 1: oldstatus = E1_ENABLE_READ; enable_E1(); break; + #if E_STEPPERS > 2 + case 2: oldstatus = E2_ENABLE_READ; enable_E2(); break; + #if E_STEPPERS > 3 + case 3: oldstatus = E3_ENABLE_READ; enable_E3(); break; + #if E_STEPPERS > 4 + case 4: oldstatus = E4_ENABLE_READ; enable_E4(); break; + #endif // E_STEPPERS > 4 + #endif // E_STEPPERS > 3 + #endif // E_STEPPERS > 2 + #endif // E_STEPPERS > 1 + } + #endif // !SWITCHING_EXTRUDER + + previous_cmd_ms = ms; // refresh_cmd_timeout() + + const float olde = current_position[E_AXIS]; + current_position[E_AXIS] += EXTRUDER_RUNOUT_EXTRUDE; + planner.buffer_line_kinematic(current_position, MMM_TO_MMS(EXTRUDER_RUNOUT_SPEED), active_extruder); + current_position[E_AXIS] = olde; + planner.set_e_position_mm(olde); + stepper.synchronize(); + #if ENABLED(SWITCHING_EXTRUDER) + E0_ENABLE_WRITE(oldstatus); + #else + switch (active_extruder) { + case 0: E0_ENABLE_WRITE(oldstatus); break; + #if E_STEPPERS > 1 + case 1: E1_ENABLE_WRITE(oldstatus); break; + #if E_STEPPERS > 2 + case 2: E2_ENABLE_WRITE(oldstatus); break; + #if E_STEPPERS > 3 + case 3: E3_ENABLE_WRITE(oldstatus); break; + #if E_STEPPERS > 4 + case 4: E4_ENABLE_WRITE(oldstatus); break; + #endif // E_STEPPERS > 4 + #endif // E_STEPPERS > 3 + #endif // E_STEPPERS > 2 + #endif // E_STEPPERS > 1 + } + #endif // !SWITCHING_EXTRUDER + } + #endif // EXTRUDER_RUNOUT_PREVENT + + #if ENABLED(DUAL_X_CARRIAGE) + // handle delayed move timeout + if (delayed_move_time && ELAPSED(ms, delayed_move_time + 1000UL) && IsRunning()) { + // travel moves have been received so enact them + delayed_move_time = 0xFFFFFFFFUL; // force moves to be done + set_destination_to_current(); + prepare_move_to_destination(); + } + #endif + + #if ENABLED(TEMP_STAT_LEDS) + handle_status_leds(); + #endif + + #if ENABLED(HAVE_TMC2130) + checkOverTemp(); + #endif + + planner.check_axes_activity(); +} + +/** + * Standard idle routine keeps the machine alive + */ +void idle( + #if ENABLED(ADVANCED_PAUSE_FEATURE) + bool no_stepper_sleep/*=false*/ + #endif +) { + #if ENABLED(MAX7219_DEBUG) + Max7219_idle_tasks(); + #endif // MAX7219_DEBUG + + lcd_update(); + + host_keepalive(); + + #if ENABLED(AUTO_REPORT_TEMPERATURES) && (HAS_TEMP_HOTEND || HAS_TEMP_BED) + auto_report_temperatures(); + #endif + + manage_inactivity( + #if ENABLED(ADVANCED_PAUSE_FEATURE) + no_stepper_sleep + #endif + ); + + thermalManager.manage_heater(); + + #if ENABLED(PRINTCOUNTER) + print_job_timer.tick(); + #endif + + #if HAS_BUZZER && DISABLED(LCD_USE_I2C_BUZZER) + buzzer.tick(); + #endif + + #if ENABLED(I2C_POSITION_ENCODERS) + if (planner.blocks_queued() && + ( (blockBufferIndexRef != planner.block_buffer_head) || + ((lastUpdateMillis + I2CPE_MIN_UPD_TIME_MS) < millis())) ) { + blockBufferIndexRef = planner.block_buffer_head; + I2CPEM.update(); + lastUpdateMillis = millis(); + } + #endif +} + +/** + * Kill all activity and lock the machine. + * After this the machine will need to be reset. + */ +void kill(const char* lcd_msg) { + SERIAL_ERROR_START(); + SERIAL_ERRORLNPGM(MSG_ERR_KILLED); + + thermalManager.disable_all_heaters(); + disable_all_steppers(); + + #if ENABLED(ULTRA_LCD) + kill_screen(lcd_msg); + #else + UNUSED(lcd_msg); + #endif + + _delay_ms(600); // Wait a short time (allows messages to get out before shutting down. + cli(); // Stop interrupts + + _delay_ms(250); //Wait to ensure all interrupts routines stopped + thermalManager.disable_all_heaters(); //turn off heaters again + + #ifdef ACTION_ON_KILL + SERIAL_ECHOLNPGM("//action:" ACTION_ON_KILL); + #endif + + #if HAS_POWER_SWITCH + SET_INPUT(PS_ON_PIN); + #endif + + suicide(); + while (1) { + #if ENABLED(USE_WATCHDOG) + watchdog_reset(); + #endif + } // Wait for reset +} + +/** + * Turn off heaters and stop the print in progress + * After a stop the machine may be resumed with M999 + */ +void stop() { + thermalManager.disable_all_heaters(); // 'unpause' taken care of in here + + #if ENABLED(PROBING_FANS_OFF) + if (fans_paused) fans_pause(false); // put things back the way they were + #endif + + if (IsRunning()) { + Stopped_gcode_LastN = gcode_LastN; // Save last g_code for restart + SERIAL_ERROR_START(); + SERIAL_ERRORLNPGM(MSG_ERR_STOPPED); + LCD_MESSAGEPGM(MSG_STOPPED); + safe_delay(350); // allow enough time for messages to get out before stopping + Running = false; + } +} + +/** + * Marlin entry-point: Set up before the program loop + * - Set up the kill pin, filament runout, power hold + * - Start the serial port + * - Print startup messages and diagnostics + * - Get EEPROM or default settings + * - Initialize managers for: + * • temperature + * • planner + * • watchdog + * • stepper + * • photo pin + * • servos + * • LCD controller + * • Digipot I2C + * • Z probe sled + * • status LEDs + */ +void setup() { + + #if ENABLED(MAX7219_DEBUG) + Max7219_init(); + #endif + + #ifdef DISABLE_JTAG + // Disable JTAG on AT90USB chips to free up pins for IO + MCUCR = 0x80; + MCUCR = 0x80; + #endif + + #if ENABLED(FILAMENT_RUNOUT_SENSOR) + setup_filrunoutpin(); + #endif + + setup_killpin(); + + setup_powerhold(); + + #if HAS_STEPPER_RESET + disableStepperDrivers(); + #endif + + MYSERIAL.begin(BAUDRATE); + SERIAL_PROTOCOLLNPGM("start"); + SERIAL_ECHO_START(); + + // Check startup - does nothing if bootloader sets MCUSR to 0 + byte mcu = MCUSR; + if (mcu & 1) SERIAL_ECHOLNPGM(MSG_POWERUP); + if (mcu & 2) SERIAL_ECHOLNPGM(MSG_EXTERNAL_RESET); + if (mcu & 4) SERIAL_ECHOLNPGM(MSG_BROWNOUT_RESET); + if (mcu & 8) SERIAL_ECHOLNPGM(MSG_WATCHDOG_RESET); + if (mcu & 32) SERIAL_ECHOLNPGM(MSG_SOFTWARE_RESET); + MCUSR = 0; + + SERIAL_ECHOPGM(MSG_MARLIN); + SERIAL_CHAR(' '); + SERIAL_ECHOLNPGM(SHORT_BUILD_VERSION); + SERIAL_EOL(); + + #if defined(STRING_DISTRIBUTION_DATE) && defined(STRING_CONFIG_H_AUTHOR) + SERIAL_ECHO_START(); + SERIAL_ECHOPGM(MSG_CONFIGURATION_VER); + SERIAL_ECHOPGM(STRING_DISTRIBUTION_DATE); + SERIAL_ECHOLNPGM(MSG_AUTHOR STRING_CONFIG_H_AUTHOR); + SERIAL_ECHO_START(); + SERIAL_ECHOLNPGM("Compiled: " __DATE__); + #endif + + SERIAL_ECHO_START(); + SERIAL_ECHOPAIR(MSG_FREE_MEMORY, freeMemory()); + SERIAL_ECHOLNPAIR(MSG_PLANNER_BUFFER_BYTES, (int)sizeof(block_t)*BLOCK_BUFFER_SIZE); + + // Send "ok" after commands by default + for (int8_t i = 0; i < BUFSIZE; i++) send_ok[i] = true; + + // Load data from EEPROM if available (or use defaults) + // This also updates variables in the planner, elsewhere + (void)settings.load(); + + #if HAS_M206_COMMAND + // Initialize current position based on home_offset + COPY(current_position, home_offset); + #else + ZERO(current_position); + #endif + + // Vital to init stepper/planner equivalent for current_position + SYNC_PLAN_POSITION_KINEMATIC(); + + thermalManager.init(); // Initialize temperature loop + + #if ENABLED(USE_WATCHDOG) + watchdog_init(); + #endif + + stepper.init(); // Initialize stepper, this enables interrupts! + servo_init(); + + #if HAS_PHOTOGRAPH + OUT_WRITE(PHOTOGRAPH_PIN, LOW); + #endif + + #if HAS_CASE_LIGHT + case_light_on = CASE_LIGHT_DEFAULT_ON; + case_light_brightness = CASE_LIGHT_DEFAULT_BRIGHTNESS; + update_case_light(); + #endif + + #if ENABLED(SPINDLE_LASER_ENABLE) + OUT_WRITE(SPINDLE_LASER_ENABLE_PIN, !SPINDLE_LASER_ENABLE_INVERT); // init spindle to off + #if SPINDLE_DIR_CHANGE + OUT_WRITE(SPINDLE_DIR_PIN, SPINDLE_INVERT_DIR ? 255 : 0); // init rotation to clockwise (M3) + #endif + #if ENABLED(SPINDLE_LASER_PWM) + SET_OUTPUT(SPINDLE_LASER_PWM_PIN); + analogWrite(SPINDLE_LASER_PWM_PIN, SPINDLE_LASER_PWM_INVERT ? 255 : 0); // set to lowest speed + #endif + #endif + + #if HAS_BED_PROBE + endstops.enable_z_probe(false); + #endif + + #if ENABLED(USE_CONTROLLER_FAN) + SET_OUTPUT(CONTROLLER_FAN_PIN); //Set pin used for driver cooling fan + #endif + + #if HAS_STEPPER_RESET + enableStepperDrivers(); + #endif + + #if ENABLED(DIGIPOT_I2C) + digipot_i2c_init(); + #endif + + #if ENABLED(DAC_STEPPER_CURRENT) + dac_init(); + #endif + + #if (ENABLED(Z_PROBE_SLED) || ENABLED(SOLENOID_PROBE)) && HAS_SOLENOID_1 + OUT_WRITE(SOL1_PIN, LOW); // turn it off + #endif + + #if HAS_HOME + SET_INPUT_PULLUP(HOME_PIN); + #endif + + #if PIN_EXISTS(STAT_LED_RED) + OUT_WRITE(STAT_LED_RED_PIN, LOW); // turn it off + #endif + + #if PIN_EXISTS(STAT_LED_BLUE) + OUT_WRITE(STAT_LED_BLUE_PIN, LOW); // turn it off + #endif + + #if ENABLED(NEOPIXEL_LED) + SET_OUTPUT(NEOPIXEL_PIN); + setup_neopixel(); + #endif + + #if ENABLED(RGB_LED) || ENABLED(RGBW_LED) + SET_OUTPUT(RGB_LED_R_PIN); + SET_OUTPUT(RGB_LED_G_PIN); + SET_OUTPUT(RGB_LED_B_PIN); + #if ENABLED(RGBW_LED) + SET_OUTPUT(RGB_LED_W_PIN); + #endif + #endif + + #if ENABLED(MK2_MULTIPLEXER) + SET_OUTPUT(E_MUX0_PIN); + SET_OUTPUT(E_MUX1_PIN); + SET_OUTPUT(E_MUX2_PIN); + #endif + + #if HAS_FANMUX + fanmux_init(); + #endif + + lcd_init(); + + #ifndef CUSTOM_BOOTSCREEN_TIMEOUT + #define CUSTOM_BOOTSCREEN_TIMEOUT 2500 + #endif + + #if ENABLED(SHOW_BOOTSCREEN) + #if ENABLED(DOGLCD) // On DOGM the first bootscreen is already drawn + #if ENABLED(SHOW_CUSTOM_BOOTSCREEN) + safe_delay(CUSTOM_BOOTSCREEN_TIMEOUT); // Custom boot screen pause + lcd_bootscreen(); // Show Marlin boot screen + #endif + safe_delay(BOOTSCREEN_TIMEOUT); // Pause + #elif ENABLED(ULTRA_LCD) + lcd_bootscreen(); + #if DISABLED(SDSUPPORT) + lcd_init(); + #endif + #endif + #endif + + #if ENABLED(MIXING_EXTRUDER) && MIXING_VIRTUAL_TOOLS > 1 + // Initialize mixing to 100% color 1 + for (uint8_t i = 0; i < MIXING_STEPPERS; i++) + mixing_factor[i] = (i == 0) ? 1.0 : 0.0; + for (uint8_t t = 0; t < MIXING_VIRTUAL_TOOLS; t++) + for (uint8_t i = 0; i < MIXING_STEPPERS; i++) + mixing_virtual_tool_mix[t][i] = mixing_factor[i]; + #endif + + #if ENABLED(BLTOUCH) + // Make sure any BLTouch error condition is cleared + bltouch_command(BLTOUCH_RESET); + set_bltouch_deployed(true); + set_bltouch_deployed(false); + #endif + + #if ENABLED(I2C_POSITION_ENCODERS) + I2CPEM.init(); + #endif + + #if ENABLED(EXPERIMENTAL_I2CBUS) && I2C_SLAVE_ADDRESS > 0 + i2c.onReceive(i2c_on_receive); + i2c.onRequest(i2c_on_request); + #endif + + #if ENABLED(ENDSTOP_INTERRUPTS_FEATURE) + setup_endstop_interrupts(); + #endif + + #if ENABLED(SWITCHING_EXTRUDER) && !DONT_SWITCH + move_extruder_servo(0); // Initialize extruder servo + #endif + + #if ENABLED(SWITCHING_NOZZLE) + move_nozzle_servo(0); // Initialize nozzle servo + #endif + + #if ENABLED(PARKING_EXTRUDER) + #if ENABLED(PARKING_EXTRUDER_SOLENOIDS_INVERT) + pe_activate_magnet(0); + pe_activate_magnet(1); + #else + pe_deactivate_magnet(0); + pe_deactivate_magnet(1); + #endif + #endif + #if ENABLED(MKS_12864OLED) + SET_OUTPUT(LCD_PINS_DC); + OUT_WRITE(LCD_PINS_RS, LOW); + delay(1000); + WRITE(LCD_PINS_RS, HIGH); + #endif +} + +/** + * The main Marlin program loop + * + * - Save or log commands to SD + * - Process available commands (if not saving) + * - Call heater manager + * - Call inactivity manager + * - Call endstop manager + * - Call LCD update + */ +void loop() { + if (commands_in_queue < BUFSIZE) get_available_commands(); + + #if ENABLED(SDSUPPORT) + card.checkautostart(false); + #endif + + if (commands_in_queue) { + + #if ENABLED(SDSUPPORT) + + if (card.saving) { + char* command = command_queue[cmd_queue_index_r]; + if (strstr_P(command, PSTR("M29"))) { + // M29 closes the file + card.closefile(); + SERIAL_PROTOCOLLNPGM(MSG_FILE_SAVED); + + #if ENABLED(SERIAL_STATS_DROPPED_RX) + SERIAL_ECHOLNPAIR("Dropped bytes: ", customizedSerial.dropped()); + #endif + + #if ENABLED(SERIAL_STATS_MAX_RX_QUEUED) + SERIAL_ECHOLNPAIR("Max RX Queue Size: ", customizedSerial.rxMaxEnqueued()); + #endif + + ok_to_send(); + } + else { + // Write the string from the read buffer to SD + card.write_command(command); + if (card.logging) + process_next_command(); // The card is saving because it's logging + else + ok_to_send(); + } + } + else + process_next_command(); + + #else + + process_next_command(); + + #endif // SDSUPPORT + + // The queue may be reset by a command handler or by code invoked by idle() within a handler + if (commands_in_queue) { + --commands_in_queue; + if (++cmd_queue_index_r >= BUFSIZE) cmd_queue_index_r = 0; + } + } + endstops.report_state(); + idle(); +} + diff --git a/trunk/Arduino/Marlin_1.1.6/Max7219_Debug_LEDs.cpp b/trunk/Arduino/Marlin_1.1.6/Max7219_Debug_LEDs.cpp new file mode 100644 index 00000000..d6110053 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/Max7219_Debug_LEDs.cpp @@ -0,0 +1,236 @@ +/** + * 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 . + * + */ + +/** + * This module is off by default, but can be enabled to facilitate the display of + * extra debug information during code development. It assumes the existence of a + * Max7219 LED Matrix. A suitable device can be obtained on eBay similar to this: + * http://www.ebay.com/itm/191781645249 for under $2.00 including shipping. + * + * Just connect up +5v and GND to give it power, then connect up the pins assigned + * in Configuration_adv.h. For example, on the Re-ARM you could use: + * + * #define MAX7219_CLK_PIN 77 + * #define MAX7219_DIN_PIN 78 + * #define MAX7219_LOAD_PIN 79 + * + * Max7219_init() is called automatically at startup, and then there are a number of + * support functions available to control the LEDs in the 8x8 grid. + * + * void Max7219_init(); + * void Max7219_PutByte(uint8_t data); + * void Max7219(uint8_t reg, uint8_t data); + * void Max7219_LED_On(uint8_t row, uint8_t col); + * void Max7219_LED_Off(uint8_t row, uint8_t col); + * void Max7219_LED_Toggle(uint8_t row, uint8_t col); + * void Max7219_Clear_Row(uint8_t row); + * void Max7219_Clear_Column(uint8_t col); + * void Max7219_Set_Row(uint8_t row, uint8_t val); + * void Max7219_Set_Column(uint8_t col, uint8_t val); + * void Max7219_idle_tasks(); + */ + +#include "MarlinConfig.h" + +#if ENABLED(MAX7219_DEBUG) + + #include "Marlin.h" + #include "planner.h" + #include "stepper.h" + #include "Max7219_Debug_LEDs.h" + + static uint8_t LEDs[8] = { 0 }; + + void Max7219_PutByte(uint8_t data) { + for (uint8_t i = 8; i--;) { + WRITE(MAX7219_CLK_PIN, LOW); // tick + WRITE(MAX7219_DIN_PIN, (data & 0x80) ? HIGH : LOW); // send 1 or 0 based on data bit + WRITE(MAX7219_CLK_PIN, HIGH); // tock + data <<= 1; + } + } + + void Max7219(const uint8_t reg, const uint8_t data) { + WRITE(MAX7219_LOAD_PIN, LOW); // begin + Max7219_PutByte(reg); // specify register + Max7219_PutByte(data); // put data + WRITE(MAX7219_LOAD_PIN, LOW); // and tell the chip to load the data + WRITE(MAX7219_LOAD_PIN, HIGH); + } + + void Max7219_LED_Set(const uint8_t row, const uint8_t col, const bool on) { + if (row > 7 || col > 7) return; + if (TEST(LEDs[row], col) == on) return; // if LED is already on/off, leave alone + if (on) SBI(LEDs[row], col); else CBI(LEDs[row], col); + Max7219(8 - row, LEDs[row]); + } + + void Max7219_LED_On(const uint8_t row, const uint8_t col) { + Max7219_LED_Set(row, col, true); + } + + void Max7219_LED_Off(const uint8_t row, const uint8_t col) { + Max7219_LED_Set(row, col, false); + } + + void Max7219_LED_Toggle(const uint8_t row, const uint8_t col) { + if (row > 7 || col > 7) return; + if (TEST(LEDs[row], col)) + Max7219_LED_Off(row, col); + else + Max7219_LED_On(row, col); + } + + void Max7219_Clear_Column(const uint8_t col) { + if (col > 7) return; + LEDs[col] = 0; + Max7219(8 - col, LEDs[col]); + } + + void Max7219_Clear_Row(const uint8_t row) { + if (row > 7) return; + for (uint8_t c = 0; c <= 7; c++) + Max7219_LED_Off(c, row); + } + + void Max7219_Set_Row(const uint8_t row, const uint8_t val) { + if (row > 7) return; + for (uint8_t b = 0; b <= 7; b++) + if (TEST(val, b)) + Max7219_LED_On(7 - b, row); + else + Max7219_LED_Off(7 - b, row); + } + + void Max7219_Set_Column(const uint8_t col, const uint8_t val) { + if (col > 7) return; + LEDs[col] = val; + Max7219(8 - col, LEDs[col]); + } + + void Max7219_init() { + uint8_t i, x, y; + + SET_OUTPUT(MAX7219_DIN_PIN); + SET_OUTPUT(MAX7219_CLK_PIN); + + OUT_WRITE(MAX7219_LOAD_PIN, HIGH); + + //initiation of the max 7219 + Max7219(max7219_reg_scanLimit, 0x07); + Max7219(max7219_reg_decodeMode, 0x00); // using an led matrix (not digits) + Max7219(max7219_reg_shutdown, 0x01); // not in shutdown mode + Max7219(max7219_reg_displayTest, 0x00); // no display test + Max7219(max7219_reg_intensity, 0x01 & 0x0F); // the first 0x0F is the value you can set + // range: 0x00 to 0x0F + for (i = 0; i <= 7; i++) { // empty registers, turn all LEDs off + LEDs[i] = 0x00; + Max7219(i + 1, 0); + } + + for (x = 0; x <= 7; x++) // Do an aesthetically pleasing pattern to fully test + for (y = 0; y <= 7; y++) { // the Max7219 module and LEDs. First, turn them + Max7219_LED_On(x, y); // all on. + delay(3); + } + + for (x = 0; x <= 7; x++) // Now, turn them all off. + for (y = 0; y <= 7; y++) { + Max7219_LED_Off(x, y); + delay(3); // delay() is OK here. Max7219_init() is only called from + } // setup() and nothing is running yet. + + delay(150); + + for (x = 8; x--;) // Now, do the same thing from the opposite direction + for (y = 0; y <= 7; y++) { + Max7219_LED_On(x, y); + delay(2); + } + + for (x = 8; x--;) + for (y = 0; y <= 7; y++) { + Max7219_LED_Off(x, y); + delay(2); + } + } + +/** + * These are sample debug features to demonstrate the usage of the 8x8 LED Matrix for debug purposes. + * There is very little CPU burden added to the system by displaying information within the idle() + * task. + * + * But with that said, if your debugging can be facilitated by making calls into the library from + * other places in the code, feel free to do it. The CPU burden for a few calls to toggle an LED + * or clear a row is not very significant. + */ + void Max7219_idle_tasks() { + #if ENABLED(MAX7219_DEBUG_PRINTER_ALIVE) + static int debug_cnt = 0; + if (debug_cnt++ > 100) { + Max7219_LED_Toggle(7, 7); + debug_cnt = 0; + } + #endif + + #ifdef MAX7219_DEBUG_STEPPER_HEAD + Max7219_Clear_Row(MAX7219_DEBUG_STEPPER_HEAD); + Max7219_Clear_Row(MAX7219_DEBUG_STEPPER_HEAD + 1); + if ( planner.block_buffer_head < 8) + Max7219_LED_On( planner.block_buffer_head, MAX7219_DEBUG_STEPPER_HEAD); + else + Max7219_LED_On( planner.block_buffer_head-8, MAX7219_DEBUG_STEPPER_HEAD+1); + #endif + + #ifdef MAX7219_DEBUG_STEPPER_TAIL + Max7219_Clear_Row(MAX7219_DEBUG_STEPPER_TAIL); + Max7219_Clear_Row(MAX7219_DEBUG_STEPPER_TAIL + 1); + if ( planner.block_buffer_tail < 8) + Max7219_LED_On( planner.block_buffer_tail, MAX7219_DEBUG_STEPPER_TAIL ); + else + Max7219_LED_On( planner.block_buffer_tail-8, MAX7219_DEBUG_STEPPER_TAIL+1 ); + #endif + + #ifdef MAX7219_DEBUG_STEPPER_QUEUE + static int16_t last_depth = 0; + int16_t current_depth = planner.block_buffer_head - planner.block_buffer_tail; + if (current_depth != last_depth) { // usually, no update will be needed. + if (current_depth < 0) current_depth += BLOCK_BUFFER_SIZE; + NOMORE(current_depth, BLOCK_BUFFER_SIZE); + NOMORE(current_depth, 16); // if the BLOCK_BUFFER_SIZE is greater than 16, two lines + // of LEDs is enough to see if the buffer is draining + + const uint8_t st = min(current_depth, last_depth), + en = max(current_depth, last_depth); + if (current_depth < last_depth) + for (uint8_t i = st; i <= en; i++) // clear the highest order LEDs + Max7219_LED_Off(i >> 1, MAX7219_DEBUG_STEPPER_QUEUE + (i & 1)); + else + for (uint8_t i = st; i <= en; i++) // set the highest order LEDs + Max7219_LED_On(i >> 1, MAX7219_DEBUG_STEPPER_QUEUE + (i & 1)); + + last_depth = current_depth; + } + #endif + } + +#endif // MAX7219_DEBUG diff --git a/trunk/Arduino/Marlin_1.1.6/Max7219_Debug_LEDs.h b/trunk/Arduino/Marlin_1.1.6/Max7219_Debug_LEDs.h new file mode 100644 index 00000000..71a5124e --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/Max7219_Debug_LEDs.h @@ -0,0 +1,88 @@ +/** + * 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 . + * + */ + +/** + * This module is off by default, but can be enabled to facilitate the display of + * extra debug information during code development. It assumes the existence of a + * Max7219 LED Matrix. A suitable device can be obtained on eBay similar to this: + * http://www.ebay.com/itm/191781645249 for under $2.00 including shipping. + * + * Just connect up +5v and GND to give it power, then connect up the pins assigned + * in Configuration_adv.h. For example, on the Re-ARM you could use: + * + * #define MAX7219_CLK_PIN 77 + * #define MAX7219_DIN_PIN 78 + * #define MAX7219_LOAD_PIN 79 + * + * Max7219_init() is called automatically at startup, and then there are a number of + * support functions available to control the LEDs in the 8x8 grid. + * + * void Max7219_init(); + * void Max7219_PutByte(uint8_t data); + * void Max7219(uint8_t reg, uint8_t data); + * void Max7219_LED_Set(uint8_t row, uint8_t col, bool on); + * void Max7219_LED_On(uint8_t row, uint8_t col); + * void Max7219_LED_Off(uint8_t row, uint8_t col); + * void Max7219_LED_Toggle(uint8_t row, uint8_t col); + * void Max7219_Clear_Row(uint8_t row); + * void Max7219_Clear_Column(uint8_t col); + * void Max7219_Set_Row(uint8_t row, uint8_t val); + * void Max7219_Set_Column(uint8_t col, uint8_t val); + * void Max7219_idle_tasks(); + */ + +#ifndef __MAX7219_DEBUG_LEDS_H__ +#define __MAX7219_DEBUG_LEDS_H__ + + // + // define max7219 registers + // + #define max7219_reg_noop 0x00 + #define max7219_reg_digit0 0x01 + #define max7219_reg_digit1 0x02 + #define max7219_reg_digit2 0x03 + #define max7219_reg_digit3 0x04 + #define max7219_reg_digit4 0x05 + #define max7219_reg_digit5 0x06 + #define max7219_reg_digit6 0x07 + #define max7219_reg_digit7 0x08 + + #define max7219_reg_intensity 0x0A + #define max7219_reg_displayTest 0x0F + #define max7219_reg_decodeMode 0x09 + #define max7219_reg_scanLimit 0x0B + #define max7219_reg_shutdown 0x0C + + void Max7219_init(); + void Max7219_PutByte(uint8_t data); + void Max7219(const uint8_t reg, const uint8_t data); + void Max7219_LED_Set(const uint8_t row, const uint8_t col, const bool on); + void Max7219_LED_On(const uint8_t row, const uint8_t col); + void Max7219_LED_Off(const uint8_t row, const uint8_t col); + void Max7219_LED_Toggle(const uint8_t row, const uint8_t col); + void Max7219_Clear_Row(const uint8_t row); + void Max7219_Clear_Column(const uint8_t col); + void Max7219_Set_Row(const uint8_t row, const uint8_t val); + void Max7219_Set_Column(const uint8_t col, const uint8_t val); + void Max7219_idle_tasks(); + +#endif // __MAX7219_DEBUG_LEDS_H__ diff --git a/trunk/Arduino/Marlin_1.1.6/SanityCheck.h b/trunk/Arduino/Marlin_1.1.6/SanityCheck.h new file mode 100644 index 00000000..7d960f86 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/SanityCheck.h @@ -0,0 +1,1386 @@ +/** + * 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 . + * + */ + +/** + * SanityCheck.h + * + * Test configuration values for errors at compile-time. + */ + +/** + * Require gcc 4.7 or newer (first included with Arduino 1.6.8) for C++11 features. + */ +#if __cplusplus < 201103L + #error "Marlin requires C++11 support (gcc >= 4.7, Arduino IDE >= 1.6.8). Please upgrade your toolchain." +#endif + +/** + * 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. + */ +#if ! defined(CONFIGURATION_H_VERSION) || CONFIGURATION_H_VERSION < REQUIRED_CONFIGURATION_H_VERSION + #error "You are using an old Configuration.h file, update it before building Marlin." +#endif + +#if ! defined(CONFIGURATION_ADV_H_VERSION) || CONFIGURATION_ADV_H_VERSION < REQUIRED_CONFIGURATION_ADV_H_VERSION + #error "You are using an old Configuration_adv.h file, update it before building Marlin." +#endif + +/** + * Warnings for old configurations + */ +#if !defined(X_BED_SIZE) || !defined(Y_BED_SIZE) + #error "X_BED_SIZE and Y_BED_SIZE are now required! Please update your configuration." +#elif WATCH_TEMP_PERIOD > 500 + #error "WATCH_TEMP_PERIOD now uses seconds instead of milliseconds." +#elif DISABLED(THERMAL_PROTECTION_HOTENDS) && (defined(WATCH_TEMP_PERIOD) || defined(THERMAL_PROTECTION_PERIOD)) + #error "Thermal Runaway Protection for hotends is now enabled with THERMAL_PROTECTION_HOTENDS." +#elif DISABLED(THERMAL_PROTECTION_BED) && defined(THERMAL_PROTECTION_BED_PERIOD) + #error "Thermal Runaway Protection for the bed is now enabled with THERMAL_PROTECTION_BED." +#elif (CORE_IS_XZ || CORE_IS_YZ) && ENABLED(Z_LATE_ENABLE) + #error "Z_LATE_ENABLE can't be used with COREXZ, COREZX, COREYZ, or COREZY." +#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." +#elif defined(BTENABLED) + #error "BTENABLED is now BLUETOOTH. Please update your configuration." +#elif defined(CUSTOM_MENDEL_NAME) + #error "CUSTOM_MENDEL_NAME is now CUSTOM_MACHINE_NAME. Please update your configuration." +#elif defined(HAS_AUTOMATIC_VERSIONING) + #error "HAS_AUTOMATIC_VERSIONING is now USE_AUTOMATIC_VERSIONING. Please update your configuration." +#elif defined(SDSLOW) + #error "SDSLOW deprecated. Set SPI_SPEED to SPI_HALF_SPEED instead." +#elif defined(SDEXTRASLOW) + #error "SDEXTRASLOW deprecated. Set SPI_SPEED to SPI_QUARTER_SPEED instead." +#elif defined(FILAMENT_SENSOR) + #error "FILAMENT_SENSOR is deprecated. Use FILAMENT_WIDTH_SENSOR instead." +#elif defined(DISABLE_MAX_ENDSTOPS) || defined(DISABLE_MIN_ENDSTOPS) + #error "DISABLE_MAX_ENDSTOPS and DISABLE_MIN_ENDSTOPS deprecated. Use individual USE_*_PLUG options instead." +#elif ENABLED(Z_DUAL_ENDSTOPS) && !defined(Z2_USE_ENDSTOP) + #error "Z_DUAL_ENDSTOPS settings are simplified. Just set Z2_USE_ENDSTOP to the endstop you want to repurpose for Z2." +#elif defined(LANGUAGE_INCLUDE) + #error "LANGUAGE_INCLUDE has been replaced by LCD_LANGUAGE. Please update your configuration." +#elif defined(EXTRUDER_OFFSET_X) || defined(EXTRUDER_OFFSET_Y) + #error "EXTRUDER_OFFSET_[XY] is deprecated. Use HOTEND_OFFSET_[XY] instead." +#elif defined(PID_PARAMS_PER_EXTRUDER) + #error "PID_PARAMS_PER_EXTRUDER is deprecated. Use PID_PARAMS_PER_HOTEND instead." +#elif defined(EXTRUDER_WATTS) || defined(BED_WATTS) + #error "EXTRUDER_WATTS and BED_WATTS are deprecated. Remove them from your configuration." +#elif defined(SERVO_ENDSTOP_ANGLES) + #error "SERVO_ENDSTOP_ANGLES is deprecated. Use Z_SERVO_ANGLES instead." +#elif defined(X_ENDSTOP_SERVO_NR) || defined(Y_ENDSTOP_SERVO_NR) + #error "X_ENDSTOP_SERVO_NR and Y_ENDSTOP_SERVO_NR are deprecated and should be removed." +#elif defined(DEFAULT_XYJERK) + #error "DEFAULT_XYJERK is deprecated. Use DEFAULT_XJERK and DEFAULT_YJERK instead." +#elif defined(XY_TRAVEL_SPEED) + #error "XY_TRAVEL_SPEED is deprecated. Use XY_PROBE_SPEED instead." +#elif defined(PROBE_SERVO_DEACTIVATION_DELAY) + #error "PROBE_SERVO_DEACTIVATION_DELAY is deprecated. Use DEACTIVATE_SERVOS_AFTER_MOVE instead." +#elif defined(SERVO_DEACTIVATION_DELAY) + #error "SERVO_DEACTIVATION_DELAY is deprecated. Use SERVO_DELAY instead." +#elif ENABLED(FILAMENTCHANGEENABLE) + #error "FILAMENTCHANGEENABLE is now ADVANCED_PAUSE_FEATURE. Please update your configuration." +#elif ENABLED(FILAMENT_CHANGE_FEATURE) + #error "FILAMENT_CHANGE_FEATURE is now ADVANCED_PAUSE_FEATURE. Please update your configuration." +#elif ENABLED(FILAMENT_CHANGE_X_POS) + #error "FILAMENT_CHANGE_X_POS is now PAUSE_PARK_X_POS. Please update your configuration." +#elif ENABLED(FILAMENT_CHANGE_Y_POS) + #error "FILAMENT_CHANGE_Y_POS is now PAUSE_PARK_Y_POS. Please update your configuration." +#elif ENABLED(FILAMENT_CHANGE_Z_ADD) + #error "FILAMENT_CHANGE_Z_ADD is now PAUSE_PARK_Z_ADD. Please update your configuration." +#elif ENABLED(FILAMENT_CHANGE_XY_FEEDRATE) + #error "FILAMENT_CHANGE_XY_FEEDRATE is now PAUSE_PARK_XY_FEEDRATE. Please update your configuration." +#elif ENABLED(FILAMENT_CHANGE_Z_FEEDRATE) + #error "FILAMENT_CHANGE_Z_FEEDRATE is now PAUSE_PARK_Z_FEEDRATE. Please update your configuration." +#elif ENABLED(FILAMENT_CHANGE_RETRACT_FEEDRATE) + #error "FILAMENT_CHANGE_RETRACT_FEEDRATE is now PAUSE_PARK_RETRACT_FEEDRATE. Please update your configuration." +#elif ENABLED(FILAMENT_CHANGE_RETRACT_LENGTH) + #error "FILAMENT_CHANGE_RETRACT_LENGTH is now PAUSE_PARK_RETRACT_LENGTH. Please update your configuration." +#elif ENABLED(FILAMENT_CHANGE_EXTRUDE_FEEDRATE) + #error "FILAMENT_CHANGE_EXTRUDE_FEEDRATE is now ADVANCED_PAUSE_EXTRUDE_FEEDRATE. Please update your configuration." +#elif ENABLED(FILAMENT_CHANGE_EXTRUDE_LENGTH) + #error "FILAMENT_CHANGE_EXTRUDE_LENGTH is now ADVANCED_PAUSE_EXTRUDE_LENGTH. Please update your configuration." +#elif ENABLED(FILAMENT_CHANGE_NOZZLE_TIMEOUT) + #error "FILAMENT_CHANGE_NOZZLE_TIMEOUT is now PAUSE_PARK_NOZZLE_TIMEOUT. Please update your configuration." +#elif ENABLED(FILAMENT_CHANGE_NO_STEPPER_TIMEOUT) + #error "FILAMENT_CHANGE_NO_STEPPER_TIMEOUT is now PAUSE_PARK_NO_STEPPER_TIMEOUT. Please update your configuration." +#elif defined(PLA_PREHEAT_HOTEND_TEMP) + #error "PLA_PREHEAT_HOTEND_TEMP is now PREHEAT_1_TEMP_HOTEND. Please update your configuration." +#elif defined(PLA_PREHEAT_HPB_TEMP) + #error "PLA_PREHEAT_HPB_TEMP is now PREHEAT_1_TEMP_BED. Please update your configuration." +#elif defined(PLA_PREHEAT_FAN_SPEED) + #error "PLA_PREHEAT_FAN_SPEED is now PREHEAT_1_FAN_SPEED. Please update your configuration." +#elif defined(ABS_PREHEAT_HOTEND_TEMP) + #error "ABS_PREHEAT_HOTEND_TEMP is now PREHEAT_2_TEMP_HOTEND. Please update your configuration." +#elif defined(ABS_PREHEAT_HPB_TEMP) + #error "ABS_PREHEAT_HPB_TEMP is now PREHEAT_2_TEMP_BED. Please update your configuration." +#elif defined(ABS_PREHEAT_FAN_SPEED) + #error "ABS_PREHEAT_FAN_SPEED is now PREHEAT_2_FAN_SPEED. Please update your configuration." +#elif defined(ENDSTOPS_ONLY_FOR_HOMING) + #error "ENDSTOPS_ONLY_FOR_HOMING is deprecated. Use (disable) ENDSTOPS_ALWAYS_ON_DEFAULT instead." +#elif defined(HOMING_FEEDRATE) + #error "HOMING_FEEDRATE is deprecated. Set individual rates with HOMING_FEEDRATE_(XY|Z|E) instead." +#elif defined(MANUAL_HOME_POSITIONS) + #error "MANUAL_HOME_POSITIONS is deprecated. Set MANUAL_[XYZ]_HOME_POS as-needed instead." +#elif defined(PID_ADD_EXTRUSION_RATE) + #error "PID_ADD_EXTRUSION_RATE is now PID_EXTRUSION_SCALING and is DISABLED by default. Are you sure you want to use this option? Please update your configuration." +#elif defined(Z_RAISE_BEFORE_HOMING) + #error "Z_RAISE_BEFORE_HOMING is now Z_HOMING_HEIGHT. Please update your configuration." +#elif defined(MIN_Z_HEIGHT_FOR_HOMING) + #error "MIN_Z_HEIGHT_FOR_HOMING is now Z_HOMING_HEIGHT. Please update your configuration." +#elif defined(Z_RAISE_BEFORE_PROBING) || defined(Z_RAISE_AFTER_PROBING) + #error "Z_RAISE_(BEFORE|AFTER)_PROBING are deprecated. Use Z_CLEARANCE_DEPLOY_PROBE instead." +#elif defined(Z_RAISE_PROBE_DEPLOY_STOW) || defined(Z_RAISE_BETWEEN_PROBINGS) + #error "Z_RAISE_PROBE_DEPLOY_STOW and Z_RAISE_BETWEEN_PROBINGS are now Z_CLEARANCE_DEPLOY_PROBE and Z_CLEARANCE_BETWEEN_PROBES. Please update your configuration." +#elif defined(Z_PROBE_DEPLOY_HEIGHT) || defined(Z_PROBE_TRAVEL_HEIGHT) + #error "Z_PROBE_DEPLOY_HEIGHT and Z_PROBE_TRAVEL_HEIGHT are now Z_CLEARANCE_DEPLOY_PROBE and Z_CLEARANCE_BETWEEN_PROBES. Please update your configuration." +#elif defined(MANUAL_BED_LEVELING) + #error "MANUAL_BED_LEVELING is now LCD_BED_LEVELING. Please update your configuration." +#elif defined(MESH_HOME_SEARCH_Z) + #error "MESH_HOME_SEARCH_Z is now LCD_PROBE_Z_RANGE. Please update your configuration." +#elif defined(MANUAL_PROBE_Z_RANGE) + #error "MANUAL_PROBE_Z_RANGE is now LCD_PROBE_Z_RANGE. Please update your configuration." +#elif !defined(MIN_STEPS_PER_SEGMENT) + #error Please replace "const int dropsegments" with "#define MIN_STEPS_PER_SEGMENT" (and increase by 1) in Configuration_adv.h. +#elif defined(PREVENT_DANGEROUS_EXTRUDE) + #error "PREVENT_DANGEROUS_EXTRUDE is now PREVENT_COLD_EXTRUSION. Please update your configuration." +#elif defined(SCARA) + #error "SCARA is now MORGAN_SCARA. Please update your configuration." +#elif defined(ENABLE_AUTO_BED_LEVELING) + #error "ENABLE_AUTO_BED_LEVELING is deprecated. Specify AUTO_BED_LEVELING_LINEAR, AUTO_BED_LEVELING_BILINEAR, or AUTO_BED_LEVELING_3POINT." +#elif defined(AUTO_BED_LEVELING_FEATURE) + #error "AUTO_BED_LEVELING_FEATURE is deprecated. Specify AUTO_BED_LEVELING_LINEAR, AUTO_BED_LEVELING_BILINEAR, or AUTO_BED_LEVELING_3POINT." +#elif defined(ABL_GRID_POINTS) + #error "ABL_GRID_POINTS is now GRID_MAX_POINTS_X and GRID_MAX_POINTS_Y. Please update your configuration." +#elif defined(ABL_GRID_POINTS_X) || defined(ABL_GRID_POINTS_Y) + #error "ABL_GRID_POINTS_[XY] is now GRID_MAX_POINTS_[XY]. Please update your configuration." +#elif defined(ABL_GRID_MAX_POINTS_X) || defined(ABL_GRID_MAX_POINTS_Y) + #error "ABL_GRID_MAX_POINTS_[XY] is now GRID_MAX_POINTS_[XY]. Please update your configuration." +#elif defined(MESH_NUM_X_POINTS) || defined(MESH_NUM_Y_POINTS) + #error "MESH_NUM_[XY]_POINTS is now GRID_MAX_POINTS_[XY]. Please update your configuration." +#elif defined(UBL_MESH_NUM_X_POINTS) || defined(UBL_MESH_NUM_Y_POINTS) + #error "UBL_MESH_NUM_[XY]_POINTS is now GRID_MAX_POINTS_[XY]. Please update your configuration." +#elif defined(UBL_MESH_EDIT_ENABLED) + #error "UBL_MESH_EDIT_ENABLED is now UBL_G26_MESH_VALIDATION. Please update your configuration." +#elif defined(UBL_MESH_EDITING) + #error "UBL_MESH_EDITING is now UBL_G26_MESH_VALIDATION. Please update your configuration." +#elif defined(BLTOUCH_HEATERS_OFF) + #error "BLTOUCH_HEATERS_OFF is now PROBING_HEATERS_OFF. Please update your configuration." +#elif defined(BEEPER) + #error "BEEPER is now BEEPER_PIN. Please update your pins definitions." +#elif defined(SDCARDDETECT) + #error "SDCARDDETECT is now SD_DETECT_PIN. Please update your pins definitions." +#elif defined(STAT_LED_RED) || defined(STAT_LED_BLUE) + #error "STAT_LED_RED/STAT_LED_BLUE are now STAT_LED_RED_PIN/STAT_LED_BLUE_PIN. Please update your pins definitions." +#elif defined(LCD_PIN_BL) + #error "LCD_PIN_BL is now LCD_BACKLIGHT_PIN. Please update your pins definitions." +#elif defined(LCD_PIN_RESET) + #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(min_software_endstops) || defined(max_software_endstops) + #error "(min|max)_software_endstops are now (MIN|MAX)_SOFTWARE_ENDSTOPS. Please update your configuration." +#elif ENABLED(Z_PROBE_SLED) && defined(SLED_PIN) + #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(MIN_RETRACT) + #error "MIN_RETRACT is now MIN_AUTORETRACT and MAX_AUTORETRACT. Please update your Configuration_adv.h." +#elif defined(ADVANCE) + #error "ADVANCE was removed in Marlin 1.1.6. Please use LIN_ADVANCE." +#elif defined(NEOPIXEL_RGBW_LED) + #error "NEOPIXEL_RGBW_LED is now NEOPIXEL_LED. Please update your configuration." +#endif + +/** + * Marlin release, version and default string + */ +#ifndef SHORT_BUILD_VERSION + #error "SHORT_BUILD_VERSION must be specified." +#elif !defined(DETAILED_BUILD_VERSION) + #error "BUILD_VERSION must be specified." +#elif !defined(STRING_DISTRIBUTION_DATE) + #error "STRING_DISTRIBUTION_DATE must be specified." +#elif !defined(PROTOCOL_VERSION) + #error "PROTOCOL_VERSION must be specified." +#elif !defined(MACHINE_NAME) + #error "MACHINE_NAME must be specified." +#elif !defined(SOURCE_CODE_URL) + #error "SOURCE_CODE_URL must be specified." +#elif !defined(DEFAULT_MACHINE_UUID) + #error "DEFAULT_MACHINE_UUID must be specified." +#elif !defined(WEBSITE_URL) + #error "WEBSITE_URL must be specified." +#endif + +/** + * Dual Stepper Drivers + */ +#if ENABLED(X_DUAL_STEPPER_DRIVERS) && ENABLED(DUAL_X_CARRIAGE) + #error "DUAL_X_CARRIAGE is not compatible with X_DUAL_STEPPER_DRIVERS." +#elif ENABLED(X_DUAL_STEPPER_DRIVERS) && (!HAS_X2_ENABLE || !HAS_X2_STEP || !HAS_X2_DIR) + #error "X_DUAL_STEPPER_DRIVERS requires X2 pins (and an extra E plug)." +#elif ENABLED(Y_DUAL_STEPPER_DRIVERS) && (!HAS_Y2_ENABLE || !HAS_Y2_STEP || !HAS_Y2_DIR) + #error "Y_DUAL_STEPPER_DRIVERS requires Y2 pins (and an extra E plug)." +#elif ENABLED(Z_DUAL_STEPPER_DRIVERS) && (!HAS_Z2_ENABLE || !HAS_Z2_STEP || !HAS_Z2_DIR) + #error "Z_DUAL_STEPPER_DRIVERS requires Z2 pins (and an extra E plug)." +#endif + +/** + * Validate that the bed size fits + */ +static_assert(X_MAX_LENGTH >= X_BED_SIZE && Y_MAX_LENGTH >= Y_BED_SIZE, + "Movement bounds ([XY]_MIN_POS, [XY]_MAX_POS) are too narrow to contain [XY]_BED_SIZE."); + +/** + * Progress Bar + */ +#if ENABLED(LCD_PROGRESS_BAR) + #if DISABLED(SDSUPPORT) + #error "LCD_PROGRESS_BAR requires SDSUPPORT." + #elif ENABLED(DOGLCD) + #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." + #endif +#endif + +/** + * SD File Sorting + */ +#if ENABLED(SDCARD_SORT_ALPHA) + #if SDSORT_LIMIT > 256 + #error "SDSORT_LIMIT must be 256 or smaller." + #elif SDSORT_LIMIT < 10 + #error "SDSORT_LIMIT should be greater than 9 to be useful." + #elif DISABLED(SDSORT_USES_RAM) + #if ENABLED(SDSORT_DYNAMIC_RAM) + #error "SDSORT_DYNAMIC_RAM requires SDSORT_USES_RAM (which reads the directory into RAM)." + #elif ENABLED(SDSORT_CACHE_NAMES) + #error "SDSORT_CACHE_NAMES requires SDSORT_USES_RAM (which reads the directory into RAM)." + #endif + #endif +#endif + +/** + * I2C Position Encoders + */ +#if ENABLED(I2C_POSITION_ENCODERS) + #if DISABLED(BABYSTEPPING) + #error "I2C_POSITION_ENCODERS requires BABYSTEPPING." + #elif !WITHIN(I2CPE_ENCODER_CNT, 1, 5) + #error "I2CPE_ENCODER_CNT must be between 1 and 5." + #endif +#endif + +/** + * Babystepping + */ +#if ENABLED(BABYSTEPPING) + #if DISABLED(ULTRA_LCD) && DISABLED(I2C_POSITION_ENCODERS) + #error "BABYSTEPPING requires an LCD controller." + #elif ENABLED(SCARA) + #error "BABYSTEPPING is not implemented for SCARA yet." + #elif ENABLED(DELTA) && ENABLED(BABYSTEP_XY) + #error "BABYSTEPPING only implemented for Z axis on deltabots." + #elif ENABLED(BABYSTEP_ZPROBE_OFFSET) && ENABLED(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) && !ENABLED(DOGLCD) + #error "BABYSTEP_ZPROBE_GFX_OVERLAY requires a DOGLCD." + #elif ENABLED(BABYSTEP_ZPROBE_GFX_OVERLAY) && !ENABLED(BABYSTEP_ZPROBE_OFFSET) + #error "BABYSTEP_ZPROBE_GFX_OVERLAY requires a BABYSTEP_ZPROBE_OFFSET." + #endif +#endif + +/** + * Filament Runout needs a pin and either SD Support or Auto print start detection + */ +#if ENABLED(FILAMENT_RUNOUT_SENSOR) + #if !HAS_FIL_RUNOUT + #error "FILAMENT_RUNOUT_SENSOR requires FIL_RUNOUT_PIN." + #elif DISABLED(SDSUPPORT) && DISABLED(PRINTJOB_TIMER_AUTOSTART) + #error "FILAMENT_RUNOUT_SENSOR requires SDSUPPORT or PRINTJOB_TIMER_AUTOSTART." + #elif DISABLED(ADVANCED_PAUSE_FEATURE) + static_assert(NULL == strstr(FILAMENT_RUNOUT_SCRIPT, "M600"), "ADVANCED_PAUSE_FEATURE is required to use M600 with FILAMENT_RUNOUT_SENSOR."); + #endif +#endif + +/** + * Advanced Pause + */ +#if ENABLED(ADVANCED_PAUSE_FEATURE) + #if DISABLED(NEWPANEL) + #error "ADVANCED_PAUSE_FEATURE currently requires an LCD controller." + #elif ENABLED(EXTRUDER_RUNOUT_PREVENT) + #error "EXTRUDER_RUNOUT_PREVENT is incompatible with ADVANCED_PAUSE_FEATURE." + #elif ENABLED(PARK_HEAD_ON_PAUSE) && DISABLED(SDSUPPORT) && DISABLED(NEWPANEL) && DISABLED(EMERGENCY_PARSER) + #error "PARK_HEAD_ON_PAUSE requires SDSUPPORT, EMERGENCY_PARSER, or an LCD controller." + #elif ENABLED(HOME_BEFORE_FILAMENT_CHANGE) && DISABLED(PAUSE_PARK_NO_STEPPER_TIMEOUT) + #error "HOME_BEFORE_FILAMENT_CHANGE requires PAUSE_PARK_NO_STEPPER_TIMEOUT" + #endif +#endif + +/** + * Individual axis homing is useless for DELTAS + */ +#if ENABLED(INDIVIDUAL_AXIS_HOMING_MENU) && ENABLED(DELTA) + #error "INDIVIDUAL_AXIS_HOMING_MENU is incompatible with DELTA kinematics." +#endif + +/** + * Options only for EXTRUDERS > 1 + */ +#if EXTRUDERS > 1 + + #if EXTRUDERS > 5 + #error "Marlin supports a maximum of 5 EXTRUDERS." + #endif + + #if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT) + #error "EXTRUDERS must be 1 with TEMP_SENSOR_1_AS_REDUNDANT." + #endif + + #if ENABLED(HEATERS_PARALLEL) + #error "EXTRUDERS must be 1 with HEATERS_PARALLEL." + #endif + +#elif ENABLED(MK2_MULTIPLEXER) + #error "MK2_MULTIPLEXER requires 2 or more EXTRUDERS." +#elif ENABLED(SINGLENOZZLE) + #error "SINGLENOZZLE requires 2 or more EXTRUDERS." +#endif + +/** + * Sanity checking for the Průša MK2 Multiplexer + */ +#ifdef SNMM + #error "SNMM is now MK2_MULTIPLEXER. Please update your configuration." +#elif ENABLED(MK2_MULTIPLEXER) && DISABLED(ADVANCED_PAUSE_FEATURE) + #error "ADVANCED_PAUSE_FEATURE is required with MK2_MULTIPLEXER." +#endif + +/** + * A Dual Nozzle carriage with switching servo + */ +#if ENABLED(SWITCHING_NOZZLE) + #if ENABLED(DUAL_X_CARRIAGE) + #error "SWITCHING_NOZZLE and DUAL_X_CARRIAGE are incompatible." + #elif ENABLED(SINGLENOZZLE) + #error "SWITCHING_NOZZLE and SINGLENOZZLE are incompatible." + #elif EXTRUDERS != 2 + #error "SWITCHING_NOZZLE requires exactly 2 EXTRUDERS." + #elif NUM_SERVOS < 1 + #error "SWITCHING_NOZZLE requires NUM_SERVOS >= 1." + #endif +#endif + +/** + * Single Stepper Dual Extruder with switching servo + */ +#if ENABLED(SWITCHING_EXTRUDER) && NUM_SERVOS < 1 + #error "SWITCHING_EXTRUDER requires NUM_SERVOS >= 1." +#endif + +/** + * Mixing Extruder requirements + */ +#if ENABLED(MIXING_EXTRUDER) + #if EXTRUDERS > 1 + #error "MIXING_EXTRUDER currently only supports one extruder." + #elif MIXING_STEPPERS < 2 + #error "You must set MIXING_STEPPERS >= 2 for a mixing extruder." + #elif ENABLED(FILAMENT_SENSOR) + #error "MIXING_EXTRUDER is incompatible with FILAMENT_SENSOR. Comment out this line to use it anyway." + #elif ENABLED(SWITCHING_EXTRUDER) + #error "Please select either MIXING_EXTRUDER or SWITCHING_EXTRUDER, not both." + #elif ENABLED(SINGLENOZZLE) + #error "MIXING_EXTRUDER is incompatible with SINGLENOZZLE." + #elif ENABLED(LIN_ADVANCE) + #error "MIXING_EXTRUDER is incompatible with LIN_ADVANCE." + #endif +#endif + +/** + * Parking Extruder requirements + */ +#if ENABLED(PARKING_EXTRUDER) + #if ENABLED(DUAL_X_CARRIAGE) + #error "PARKING_EXTRUDER and DUAL_X_CARRIAGE are incompatible." + #elif ENABLED(SINGLENOZZLE) + #error "PARKING_EXTRUDER and SINGLENOZZLE are incompatible." + #elif ENABLED(EXT_SOLENOID) + #error "PARKING_EXTRUDER and EXT_SOLENOID are incompatible. (Pins are used twice.)" + #elif EXTRUDERS != 2 + #error "PARKING_EXTRUDER requires exactly 2 EXTRUDERS." + #elif !PIN_EXISTS(SOL0) || !PIN_EXISTS(SOL1) + #error "PARKING_EXTRUDER requires SOL0_PIN and SOL1_PIN." + #elif !defined(PARKING_EXTRUDER_PARKING_X) + #error "PARKING_EXTRUDER requires PARKING_EXTRUDER_PARKING_X." + #elif !defined(PARKING_EXTRUDER_SECURITY_RAISE) + #error "PARKING_EXTRUDER requires PARKING_EXTRUDER_SECURITY_RAISE." + #elif PARKING_EXTRUDER_SECURITY_RAISE < 0 + #error "PARKING_EXTRUDER_SECURITY_RAISE must be 0 or higher." + #elif !defined(PARKING_EXTRUDER_SOLENOIDS_PINS_ACTIVE) || !WITHIN(PARKING_EXTRUDER_SOLENOIDS_PINS_ACTIVE, LOW, HIGH) + #error "PARKING_EXTRUDER_SOLENOIDS_PINS_ACTIVE must be defined as HIGH or LOW." + #elif !defined(PARKING_EXTRUDER_SOLENOIDS_DELAY) || !WITHIN(PARKING_EXTRUDER_SOLENOIDS_DELAY, 0, 2000) + #error "PARKING_EXTRUDER_SOLENOIDS_DELAY must be between 0 and 2000 (ms)." + #endif +#endif + +/** + * Part-Cooling Fan Multiplexer requirements + */ +#if PIN_EXISTS(FANMUX1) + #if !HAS_FANMUX + #error "FANMUX0_PIN must be set before FANMUX1_PIN can be set." + #endif +#elif PIN_EXISTS(FANMUX2) + #error "FANMUX0_PIN and FANMUX1_PIN must be set before FANMUX2_PIN can be set." +#endif + +/** + * Limited number of servos + */ +#if NUM_SERVOS > 4 + #error "The maximum number of SERVOS in Marlin is 4." +#endif + +/** + * Servo deactivation depends on servo endstops, switching nozzle, or switching extruder + */ +#if ENABLED(DEACTIVATE_SERVOS_AFTER_MOVE) && !HAS_Z_SERVO_ENDSTOP && !defined(SWITCHING_NOZZLE_SERVO_NR) && !defined(SWITCHING_EXTRUDER_SERVO_NR) + #error "Z_ENDSTOP_SERVO_NR, switching nozzle, or switching extruder is required for DEACTIVATE_SERVOS_AFTER_MOVE." +#endif + +/** + * Required LCD language + */ +#if DISABLED(DOGLCD) && ENABLED(ULTRA_LCD) && !defined(DISPLAY_CHARSET_HD44780) + #error "You must set DISPLAY_CHARSET_HD44780 to JAPANESE, WESTERN or CYRILLIC for your LCD controller." +#endif + +/** + * Bed Heating Options - PID vs Limit Switching + */ +#if ENABLED(PIDTEMPBED) && ENABLED(BED_LIMIT_SWITCHING) + #error "To use BED_LIMIT_SWITCHING you must disable PIDTEMPBED." +#endif + +/** + * Kinematics + */ + +/** + * Allow only one kinematic type to be defined + */ +static_assert(1 >= 0 + #if ENABLED(DELTA) + + 1 + #endif + #if ENABLED(MORGAN_SCARA) + + 1 + #endif + #if ENABLED(MAKERARM_SCARA) + + 1 + #endif + #if ENABLED(COREXY) + + 1 + #endif + #if ENABLED(COREXZ) + + 1 + #endif + #if ENABLED(COREYZ) + + 1 + #endif + #if ENABLED(COREYX) + + 1 + #endif + #if ENABLED(COREZX) + + 1 + #endif + #if ENABLED(COREZY) + + 1 + #endif + , "Please enable only one of DELTA, MORGAN_SCARA, MAKERARM_SCARA, COREXY, COREYX, COREXZ, COREZX, COREYZ, or COREZY." +); + +/** + * Delta requirements + */ +#if ENABLED(DELTA) + #if DISABLED(USE_XMAX_PLUG) && DISABLED(USE_YMAX_PLUG) && DISABLED(USE_ZMAX_PLUG) + #error "You probably want to use Max Endstops for DELTA!" + #elif ENABLED(ENABLE_LEVELING_FADE_HEIGHT) && DISABLED(AUTO_BED_LEVELING_BILINEAR) && !UBL_DELTA + #error "ENABLE_LEVELING_FADE_HEIGHT on DELTA requires AUTO_BED_LEVELING_BILINEAR or AUTO_BED_LEVELING_UBL." + #elif ENABLED(DELTA_AUTO_CALIBRATION) && !PROBE_SELECTED + #error "DELTA_AUTO_CALIBRATION requires a probe: PROBE_MANUALLY, FIX_MOUNTED_PROBE, BLTOUCH, SOLENOID_PROBE, Z_PROBE_ALLEN_KEY, Z_PROBE_SLED, Z Servo." + #elif ENABLED(DELTA_AUTO_CALIBRATION) && ENABLED(PROBE_MANUALLY) && DISABLED(ULTIPANEL) + #error "DELTA_AUTO_CALIBRATION requires an LCD controller with PROBE_MANUALLY." + #elif ABL_GRID + #if (GRID_MAX_POINTS_X & 1) == 0 || (GRID_MAX_POINTS_Y & 1) == 0 + #error "DELTA requires GRID_MAX_POINTS_X and GRID_MAX_POINTS_Y to be odd numbers." + #elif GRID_MAX_POINTS_X < 3 + #error "DELTA requires GRID_MAX_POINTS_X and GRID_MAX_POINTS_Y to be 3 or higher." + #endif + #endif +#endif + +/** + * Probes + */ + +/** + * Allow only one probe option to be defined + */ +static_assert(1 >= 0 + #if ENABLED(PROBE_MANUALLY) + + 1 + #endif + #if ENABLED(FIX_MOUNTED_PROBE) + + 1 + #endif + #if HAS_Z_SERVO_ENDSTOP && DISABLED(BLTOUCH) + + 1 + #endif + #if ENABLED(BLTOUCH) + + 1 + #endif + #if ENABLED(SOLENOID_PROBE) + + 1 + #endif + #if ENABLED(Z_PROBE_ALLEN_KEY) + + 1 + #endif + #if ENABLED(Z_PROBE_SLED) + + 1 + #endif + , "Please enable only one probe option: PROBE_MANUALLY, FIX_MOUNTED_PROBE, BLTOUCH, SOLENOID_PROBE, Z_PROBE_ALLEN_KEY, Z_PROBE_SLED, or Z Servo." +); + +#if PROBE_SELECTED + + /** + * Z_PROBE_SLED is incompatible with DELTA + */ + #if ENABLED(Z_PROBE_SLED) && ENABLED(DELTA) + #error "You cannot use Z_PROBE_SLED with DELTA." + #endif + + /** + * SOLENOID_PROBE requirements + */ + #if ENABLED(SOLENOID_PROBE) + #if ENABLED(EXT_SOLENOID) + #error "SOLENOID_PROBE is incompatible with EXT_SOLENOID." + #elif !HAS_SOLENOID_1 + #error "SOLENOID_PROBE requires SOL1_PIN. It can be added to your Configuration.h." + #endif + #endif + + /** + * NUM_SERVOS is required for a Z servo probe + */ + #if HAS_Z_SERVO_ENDSTOP + #ifndef NUM_SERVOS + #error "You must set NUM_SERVOS for a Z servo probe (Z_ENDSTOP_SERVO_NR)." + #elif Z_ENDSTOP_SERVO_NR >= NUM_SERVOS + #error "Z_ENDSTOP_SERVO_NR must be smaller than NUM_SERVOS." + #endif + #endif + + /** + * Require pin options and pins to be defined + */ + #if ENABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN) + #if ENABLED(Z_MIN_PROBE_ENDSTOP) + #error "Enable only one option: Z_MIN_PROBE_ENDSTOP or Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN." + #elif DISABLED(USE_ZMIN_PLUG) + #error "Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN requires USE_ZMIN_PLUG to be enabled." + #elif !HAS_Z_MIN + #error "Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN requires the Z_MIN_PIN to be defined." + #elif ENABLED(Z_MIN_PROBE_ENDSTOP_INVERTING) != ENABLED(Z_MIN_ENDSTOP_INVERTING) + #error "Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN requires Z_MIN_ENDSTOP_INVERTING to match Z_MIN_PROBE_ENDSTOP_INVERTING." + #endif + #elif ENABLED(Z_MIN_PROBE_ENDSTOP) + #if !HAS_Z_MIN_PROBE_PIN + #error "Z_MIN_PROBE_ENDSTOP requires the Z_MIN_PROBE_PIN to be defined." + #endif + #elif DISABLED(PROBE_MANUALLY) + #error "You must enable either Z_MIN_PROBE_ENDSTOP or Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN to use a probe." + #endif + + /** + * Make sure Z raise values are set + */ + #if !defined(Z_CLEARANCE_DEPLOY_PROBE) + #error "You must define Z_CLEARANCE_DEPLOY_PROBE in your configuration." + #elif !defined(Z_CLEARANCE_BETWEEN_PROBES) + #error "You must define Z_CLEARANCE_BETWEEN_PROBES in your configuration." + #elif Z_CLEARANCE_DEPLOY_PROBE < 0 + #error "Probes need Z_CLEARANCE_DEPLOY_PROBE >= 0." + #elif Z_CLEARANCE_BETWEEN_PROBES < 0 + #error "Probes need Z_CLEARANCE_BETWEEN_PROBES >= 0." + #endif + +#else + + /** + * Require some kind of probe for bed leveling and probe testing + */ + #if HAS_ABL && DISABLED(AUTO_BED_LEVELING_UBL) + #error "Auto Bed Leveling requires one of these: PROBE_MANUALLY, FIX_MOUNTED_PROBE, BLTOUCH, SOLENOID_PROBE, Z_PROBE_ALLEN_KEY, Z_PROBE_SLED, or a Z Servo." + #endif + +#endif + +#if ENABLED(Z_MIN_PROBE_REPEATABILITY_TEST) && !HAS_BED_PROBE + #error "Z_MIN_PROBE_REPEATABILITY_TEST requires a probe: FIX_MOUNTED_PROBE, BLTOUCH, SOLENOID_PROBE, Z_PROBE_ALLEN_KEY, Z_PROBE_SLED, or Z Servo." +#endif + +/** + * Allow only one bed leveling option to be defined + */ +static_assert(1 >= 0 + #if ENABLED(AUTO_BED_LEVELING_LINEAR) + + 1 + #endif + #if ENABLED(AUTO_BED_LEVELING_3POINT) + + 1 + #endif + #if ENABLED(AUTO_BED_LEVELING_BILINEAR) + + 1 + #endif + #if ENABLED(AUTO_BED_LEVELING_UBL) + + 1 + #endif + #if ENABLED(MESH_BED_LEVELING) + + 1 + #endif + , "Select only one of: MESH_BED_LEVELING, AUTO_BED_LEVELING_LINEAR, AUTO_BED_LEVELING_3POINT, AUTO_BED_LEVELING_BILINEAR or AUTO_BED_LEVELING_UBL." +); + +/** + * Bed Leveling Requirements + */ + +#if ENABLED(AUTO_BED_LEVELING_UBL) + + /** + * Unified Bed Leveling + */ + + #if IS_SCARA + #error "AUTO_BED_LEVELING_UBL does not yet support SCARA printers." + #elif DISABLED(EEPROM_SETTINGS) + #error "AUTO_BED_LEVELING_UBL requires EEPROM_SETTINGS. Please update your configuration." + #elif !WITHIN(GRID_MAX_POINTS_X, 3, 15) || !WITHIN(GRID_MAX_POINTS_Y, 3, 15) + #error "GRID_MAX_POINTS_[XY] must be a whole number between 3 and 15." + #else + static_assert(WITHIN(UBL_PROBE_PT_1_X, MIN_PROBE_X, MAX_PROBE_X), "UBL_PROBE_PT_1_X can't be reached by the Z probe."); + static_assert(WITHIN(UBL_PROBE_PT_2_X, MIN_PROBE_X, MAX_PROBE_X), "UBL_PROBE_PT_2_X can't be reached by the Z probe."); + static_assert(WITHIN(UBL_PROBE_PT_3_X, MIN_PROBE_X, MAX_PROBE_X), "UBL_PROBE_PT_3_X can't be reached by the Z probe."); + static_assert(WITHIN(UBL_PROBE_PT_1_Y, MIN_PROBE_Y, MAX_PROBE_Y), "UBL_PROBE_PT_1_Y can't be reached by the Z probe."); + static_assert(WITHIN(UBL_PROBE_PT_2_Y, MIN_PROBE_Y, MAX_PROBE_Y), "UBL_PROBE_PT_2_Y can't be reached by the Z probe."); + static_assert(WITHIN(UBL_PROBE_PT_3_Y, MIN_PROBE_Y, MAX_PROBE_Y), "UBL_PROBE_PT_3_Y can't be reached by the Z probe."); + #endif + +#elif HAS_ABL + + /** + * Auto Bed Leveling + */ + + #if ENABLED(USE_RAW_KINEMATICS) + #error "USE_RAW_KINEMATICS is not compatible with AUTO_BED_LEVELING" + #endif + + /** + * Delta and SCARA have limited bed leveling options + */ + #if IS_SCARA && DISABLED(AUTO_BED_LEVELING_BILINEAR) + #error "Only AUTO_BED_LEVELING_BILINEAR currently supports SCARA bed leveling." + #endif + + /** + * Check auto bed leveling probe points + */ + #if ABL_GRID + + #ifdef DELTA_PROBEABLE_RADIUS + static_assert(LEFT_PROBE_BED_POSITION >= -DELTA_PROBEABLE_RADIUS, "LEFT_PROBE_BED_POSITION must be within DELTA_PROBEABLE_RADIUS."); + static_assert(RIGHT_PROBE_BED_POSITION <= DELTA_PROBEABLE_RADIUS, "RIGHT_PROBE_BED_POSITION must be within DELTA_PROBEABLE_RADIUS."); + static_assert(FRONT_PROBE_BED_POSITION >= -DELTA_PROBEABLE_RADIUS, "FRONT_PROBE_BED_POSITION must be within DELTA_PROBEABLE_RADIUS."); + static_assert(BACK_PROBE_BED_POSITION <= DELTA_PROBEABLE_RADIUS, "BACK_PROBE_BED_POSITION must be within DELTA_PROBEABLE_RADIUS."); + #else + static_assert(LEFT_PROBE_BED_POSITION < RIGHT_PROBE_BED_POSITION, "LEFT_PROBE_BED_POSITION must be less than RIGHT_PROBE_BED_POSITION."); + static_assert(FRONT_PROBE_BED_POSITION < BACK_PROBE_BED_POSITION, "FRONT_PROBE_BED_POSITION must be less than BACK_PROBE_BED_POSITION."); + static_assert(LEFT_PROBE_BED_POSITION >= MIN_PROBE_X, "LEFT_PROBE_BED_POSITION can't be reached by the Z probe."); + static_assert(RIGHT_PROBE_BED_POSITION <= MAX_PROBE_X, "RIGHT_PROBE_BED_POSITION can't be reached by the Z probe."); + static_assert(FRONT_PROBE_BED_POSITION >= MIN_PROBE_Y, "FRONT_PROBE_BED_POSITION can't be reached by the Z probe."); + static_assert(BACK_PROBE_BED_POSITION <= MAX_PROBE_Y, "BACK_PROBE_BED_POSITION can't be reached by the Z probe."); + #endif + + #else // AUTO_BED_LEVELING_3POINT + + static_assert(WITHIN(ABL_PROBE_PT_1_X, MIN_PROBE_X, MAX_PROBE_X), "ABL_PROBE_PT_1_X can't be reached by the Z probe."); + static_assert(WITHIN(ABL_PROBE_PT_2_X, MIN_PROBE_X, MAX_PROBE_X), "ABL_PROBE_PT_2_X can't be reached by the Z probe."); + static_assert(WITHIN(ABL_PROBE_PT_3_X, MIN_PROBE_X, MAX_PROBE_X), "ABL_PROBE_PT_3_X can't be reached by the Z probe."); + static_assert(WITHIN(ABL_PROBE_PT_1_Y, MIN_PROBE_Y, MAX_PROBE_Y), "ABL_PROBE_PT_1_Y can't be reached by the Z probe."); + static_assert(WITHIN(ABL_PROBE_PT_2_Y, MIN_PROBE_Y, MAX_PROBE_Y), "ABL_PROBE_PT_2_Y can't be reached by the Z probe."); + static_assert(WITHIN(ABL_PROBE_PT_3_Y, MIN_PROBE_Y, MAX_PROBE_Y), "ABL_PROBE_PT_3_Y can't be reached by the Z probe."); + + #endif // AUTO_BED_LEVELING_3POINT + +#elif ENABLED(MESH_BED_LEVELING) + + /** + * Mesh Bed Leveling + */ + + #if ENABLED(DELTA) + #error "MESH_BED_LEVELING does not yet support DELTA printers." + #elif GRID_MAX_POINTS_X > 9 || GRID_MAX_POINTS_Y > 9 + #error "GRID_MAX_POINTS_X and GRID_MAX_POINTS_Y must be less than 10 for MBL." + #endif + +#endif + +/** + * LCD_BED_LEVELING requirements + */ +#if ENABLED(LCD_BED_LEVELING) + #if DISABLED(ULTIPANEL) + #error "LCD_BED_LEVELING requires an LCD controller." + #elif DISABLED(MESH_BED_LEVELING) && !(HAS_ABL && ENABLED(PROBE_MANUALLY)) + #error "LCD_BED_LEVELING requires MESH_BED_LEVELING or PROBE_MANUALLY with auto bed leveling enabled." + #endif +#endif + +/** + * Homing Bump + */ +#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 + +/** + * Make sure Z_SAFE_HOMING point is reachable + */ +#if ENABLED(Z_SAFE_HOMING) + #if !WITHIN(Z_SAFE_HOMING_X_POINT, MIN_PROBE_X, MAX_PROBE_X) + #if HAS_BED_PROBE + #error "Z_SAFE_HOMING_X_POINT can't be reached by the Z probe." + #else + #error "Z_SAFE_HOMING_X_POINT can't be reached by the nozzle." + #endif + #elif !WITHIN(Z_SAFE_HOMING_Y_POINT, MIN_PROBE_Y, MAX_PROBE_Y) + #if HAS_BED_PROBE + #error "Z_SAFE_HOMING_Y_POINT can't be reached by the Z probe." + #else + #error "Z_SAFE_HOMING_Y_POINT can't be reached by the nozzle." + #endif + #endif +#endif // Z_SAFE_HOMING + +/** + * Make sure DISABLE_[XYZ] compatible with selected homing options + */ +#if ENABLED(DISABLE_X) || ENABLED(DISABLE_Y) || ENABLED(DISABLE_Z) + #if ENABLED(HOME_AFTER_DEACTIVATE) || ENABLED(Z_SAFE_HOMING) + #error "DISABLE_[XYZ] not compatible with HOME_AFTER_DEACTIVATE or Z_SAFE_HOMING." + #endif +#endif // DISABLE_[XYZ] + +/** + * Filament Width Sensor + */ +#if ENABLED(FILAMENT_WIDTH_SENSOR) && !HAS_FILAMENT_WIDTH_SENSOR + #error "FILAMENT_WIDTH_SENSOR requires a FILWIDTH_PIN to be defined." +#endif + +/** + * ULTIPANEL encoder + */ +#if ENABLED(ULTIPANEL) && DISABLED(NEWPANEL) && DISABLED(SR_LCD_2W_NL) && !defined(SHIFT_CLK) + #error "ULTIPANEL requires some kind of encoder." +#endif + +#if ENCODER_PULSES_PER_STEP < 0 + #error "ENCODER_PULSES_PER_STEP should not be negative, use REVERSE_MENU_DIRECTION instead." +#endif + +/** + * SAV_3DGLCD display options + */ +#if ENABLED(U8GLIB_SSD1306) && ENABLED(U8GLIB_SH1106) + #error "Only enable one SAV_3DGLCD display type: U8GLIB_SSD1306 or U8GLIB_SH1106." +#endif + +/** + * Allen Key + * 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" +#endif + +/** + * Dual X Carriage requirements + */ +#if ENABLED(DUAL_X_CARRIAGE) + #if EXTRUDERS == 1 + #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 !HAS_X2_ENABLE || !HAS_X2_STEP || !HAS_X2_DIR + #error "DUAL_X_CARRIAGE requires X2 stepper pins to be defined." + #elif !HAS_X_MAX + #error "DUAL_X_CARRIAGE requires USE_XMAX_PLUG and an X Max Endstop." + #elif !defined(X2_HOME_POS) || !defined(X2_MIN_POS) || !defined(X2_MAX_POS) + #error "DUAL_X_CARRIAGE requires X2_HOME_POS, X2_MIN_POS, and X2_MAX_POS." + #elif X_HOME_DIR != -1 || X2_HOME_DIR != 1 + #error "DUAL_X_CARRIAGE requires X_HOME_DIR -1 and X2_HOME_DIR 1." + #endif +#endif // DUAL_X_CARRIAGE + +/** + * Make sure auto fan pins don't conflict with the fan pin + */ +#if HAS_AUTO_FAN + #if HAS_FAN0 + #if E0_AUTO_FAN_PIN == FAN_PIN + #error "You cannot set E0_AUTO_FAN_PIN equal to FAN_PIN." + #elif E1_AUTO_FAN_PIN == FAN_PIN + #error "You cannot set E1_AUTO_FAN_PIN equal to FAN_PIN." + #elif E2_AUTO_FAN_PIN == FAN_PIN + #error "You cannot set E2_AUTO_FAN_PIN equal to FAN_PIN." + #elif E3_AUTO_FAN_PIN == FAN_PIN + #error "You cannot set E3_AUTO_FAN_PIN equal to FAN_PIN." + #endif + #endif +#endif + +#if HAS_FAN0 && CONTROLLER_FAN_PIN == FAN_PIN + #error "You cannot set CONTROLLER_FAN_PIN equal to FAN_PIN." +#endif + +#if ENABLED(USE_CONTROLLER_FAN) + #if !HAS_CONTROLLER_FAN + #error "USE_CONTROLLER_FAN requires a CONTROLLER_FAN_PIN. Define in Configuration_adv.h." + #elif E0_AUTO_FAN_PIN == CONTROLLER_FAN_PIN + #error "You cannot set E0_AUTO_FAN_PIN equal to CONTROLLER_FAN_PIN." + #elif E1_AUTO_FAN_PIN == CONTROLLER_FAN_PIN + #error "You cannot set E1_AUTO_FAN_PIN equal to CONTROLLER_FAN_PIN." + #elif E2_AUTO_FAN_PIN == CONTROLLER_FAN_PIN + #error "You cannot set E2_AUTO_FAN_PIN equal to CONTROLLER_FAN_PIN." + #elif E3_AUTO_FAN_PIN == CONTROLLER_FAN_PIN + #error "You cannot set E3_AUTO_FAN_PIN equal to CONTROLLER_FAN_PIN." + #endif +#endif + +/** + * Test Heater, Temp Sensor, and Extruder Pins; Sensor Type must also be set. + */ +#if !HAS_HEATER_0 + #error "HEATER_0_PIN not defined for this board." +#elif !PIN_EXISTS(TEMP_0) && !(defined(MAX6675_SS) && MAX6675_SS >= 0) + #error "TEMP_0_PIN not defined for this board." +#elif !PIN_EXISTS(E0_STEP) || !PIN_EXISTS(E0_DIR) || !PIN_EXISTS(E0_ENABLE) + #error "E0_STEP_PIN, E0_DIR_PIN, or E0_ENABLE_PIN not defined for this board." +#elif TEMP_SENSOR_0 == 0 + #error "TEMP_SENSOR_0 is required." +#endif + +#if HOTENDS > 1 || ENABLED(HEATERS_PARALLEL) + #if !HAS_HEATER_1 + #error "HEATER_1_PIN not defined for this board." + #endif +#endif + +#if HOTENDS > 1 + #if TEMP_SENSOR_1 == 0 + #error "TEMP_SENSOR_1 is required with 2 or more HOTENDS." + #elif !PIN_EXISTS(TEMP_1) + #error "TEMP_1_PIN not defined for this board." + #endif + #if HOTENDS > 2 + #if TEMP_SENSOR_2 == 0 + #error "TEMP_SENSOR_2 is required with 3 or more HOTENDS." + #elif !HAS_HEATER_2 + #error "HEATER_2_PIN not defined for this board." + #elif !PIN_EXISTS(TEMP_2) + #error "TEMP_2_PIN not defined for this board." + #endif + #if HOTENDS > 3 + #if TEMP_SENSOR_3 == 0 + #error "TEMP_SENSOR_3 is required with 4 or more HOTENDS." + #elif !HAS_HEATER_3 + #error "HEATER_3_PIN not defined for this board." + #elif !PIN_EXISTS(TEMP_3) + #error "TEMP_3_PIN not defined for this board." + #endif + #if HOTENDS > 4 + #if TEMP_SENSOR_4 == 0 + #error "TEMP_SENSOR_4 is required with 5 HOTENDS." + #elif !HAS_HEATER_4 + #error "HEATER_4_PIN not defined for this board." + #elif !PIN_EXISTS(TEMP_4) + #error "TEMP_4_PIN not defined for this board." + #endif + #elif TEMP_SENSOR_4 != 0 + #error "TEMP_SENSOR_4 shouldn't be set with only 4 HOTENDS." + #endif + #elif TEMP_SENSOR_3 != 0 + #error "TEMP_SENSOR_3 shouldn't be set with only 3 HOTENDS." + #elif TEMP_SENSOR_4 != 0 + #error "TEMP_SENSOR_4 shouldn't be set with only 3 HOTENDS." + #endif + #elif TEMP_SENSOR_2 != 0 + #error "TEMP_SENSOR_2 shouldn't be set with only 2 HOTENDS." + #elif TEMP_SENSOR_3 != 0 + #error "TEMP_SENSOR_3 shouldn't be set with only 2 HOTENDS." + #elif TEMP_SENSOR_4 != 0 + #error "TEMP_SENSOR_4 shouldn't be set with only 2 HOTENDS." + #endif +#elif TEMP_SENSOR_1 != 0 && DISABLED(TEMP_SENSOR_1_AS_REDUNDANT) + #error "TEMP_SENSOR_1 shouldn't be set with only 1 HOTEND." +#elif TEMP_SENSOR_2 != 0 + #error "TEMP_SENSOR_2 shouldn't be set with only 1 HOTEND." +#elif TEMP_SENSOR_3 != 0 + #error "TEMP_SENSOR_3 shouldn't be set with only 1 HOTEND." +#elif TEMP_SENSOR_4 != 0 + #error "TEMP_SENSOR_4 shouldn't be set with only 1 HOTEND." +#endif + +#if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT) && TEMP_SENSOR_1 == 0 + #error "TEMP_SENSOR_1 is required with TEMP_SENSOR_1_AS_REDUNDANT." +#endif + +/** + * Temperature status LEDs + */ +#if ENABLED(TEMP_STAT_LEDS) && !PIN_EXISTS(STAT_LED_RED) && !PIN_EXISTS(STAT_LED_BLUE) + #error "TEMP_STAT_LEDS requires STAT_LED_RED_PIN or STAT_LED_BLUE_PIN, preferably both." +#endif + +/** + * Basic 2-nozzle duplication mode + */ +#if ENABLED(DUAL_NOZZLE_DUPLICATION_MODE) + #if HOTENDS != 2 + #error "DUAL_NOZZLE_DUPLICATION_MODE requires exactly 2 hotends." + #elif ENABLED(DUAL_X_CARRIAGE) + #error "DUAL_NOZZLE_DUPLICATION_MODE is incompatible with DUAL_X_CARRIAGE." + #elif ENABLED(SINGLENOZZLE) + #error "DUAL_NOZZLE_DUPLICATION_MODE is incompatible with SINGLENOZZLE." + #elif ENABLED(MIXING_EXTRUDER) + #error "DUAL_NOZZLE_DUPLICATION_MODE is incompatible with MIXING_EXTRUDER." + #elif ENABLED(SWITCHING_EXTRUDER) + #error "DUAL_NOZZLE_DUPLICATION_MODE is incompatible with SWITCHING_EXTRUDER." + #endif +#endif + +/** + * Test Extruder Stepper Pins + */ +#if E_STEPPERS > 4 + #if !PIN_EXISTS(E4_STEP) || !PIN_EXISTS(E4_DIR) || !PIN_EXISTS(E4_ENABLE) + #error "E4_STEP_PIN, E4_DIR_PIN, or E4_ENABLE_PIN not defined for this board." + #endif +#elif E_STEPPERS > 3 + #if !PIN_EXISTS(E3_STEP) || !PIN_EXISTS(E3_DIR) || !PIN_EXISTS(E3_ENABLE) + #error "E3_STEP_PIN, E3_DIR_PIN, or E3_ENABLE_PIN not defined for this board." + #endif +#elif E_STEPPERS > 2 + #if !PIN_EXISTS(E2_STEP) || !PIN_EXISTS(E2_DIR) || !PIN_EXISTS(E2_ENABLE) + #error "E2_STEP_PIN, E2_DIR_PIN, or E2_ENABLE_PIN not defined for this board." + #endif +#elif E_STEPPERS > 1 + #if !PIN_EXISTS(E1_STEP) || !PIN_EXISTS(E1_DIR) || !PIN_EXISTS(E1_ENABLE) + #error "E1_STEP_PIN, E1_DIR_PIN, or E1_ENABLE_PIN not defined for this board." + #endif +#endif + +/** + * Endstops + */ +#if DISABLED(USE_XMIN_PLUG) && DISABLED(USE_XMAX_PLUG) && !(ENABLED(Z_DUAL_ENDSTOPS) && WITHIN(Z2_USE_ENDSTOP, _XMAX_, _XMIN_)) + #error "You must enable USE_XMIN_PLUG or USE_XMAX_PLUG." +#elif DISABLED(USE_YMIN_PLUG) && DISABLED(USE_YMAX_PLUG) && !(ENABLED(Z_DUAL_ENDSTOPS) && WITHIN(Z2_USE_ENDSTOP, _YMAX_, _YMIN_)) + #error "You must enable USE_YMIN_PLUG or USE_YMAX_PLUG." +#elif DISABLED(USE_ZMIN_PLUG) && DISABLED(USE_ZMAX_PLUG) && !(ENABLED(Z_DUAL_ENDSTOPS) && WITHIN(Z2_USE_ENDSTOP, _ZMAX_, _ZMIN_)) + #error "You must enable USE_ZMIN_PLUG or USE_ZMAX_PLUG." +#elif ENABLED(Z_DUAL_ENDSTOPS) + #if !Z2_USE_ENDSTOP + #error "You must set Z2_USE_ENDSTOP with Z_DUAL_ENDSTOPS." + #elif Z2_MAX_PIN == 0 && Z2_MIN_PIN == 0 + #error "Z2_USE_ENDSTOP has been assigned to a nonexistent endstop!" + #elif ENABLED(DELTA) + #error "Z_DUAL_ENDSTOPS is not compatible with DELTA." + #endif +#elif !IS_SCARA + #if X_HOME_DIR < 0 && DISABLED(USE_XMIN_PLUG) + #error "Enable USE_XMIN_PLUG when homing X to MIN." + #elif X_HOME_DIR > 0 && DISABLED(USE_XMAX_PLUG) + #error "Enable USE_XMAX_PLUG when homing X to MAX." + #elif Y_HOME_DIR < 0 && DISABLED(USE_YMIN_PLUG) + #error "Enable USE_YMIN_PLUG when homing Y to MIN." + #elif Y_HOME_DIR > 0 && DISABLED(USE_YMAX_PLUG) + #error "Enable USE_YMAX_PLUG when homing Y to MAX." + #elif Z_HOME_DIR < 0 && DISABLED(USE_ZMIN_PLUG) + #error "Enable USE_ZMIN_PLUG when homing Z to MIN." + #elif Z_HOME_DIR > 0 && DISABLED(USE_ZMAX_PLUG) + #error "Enable USE_ZMAX_PLUG when homing Z to MAX." + #endif +#endif + +/** + * emergency-command parser + */ +#if ENABLED(EMERGENCY_PARSER) && defined(USBCON) + #error "EMERGENCY_PARSER does not work on boards with AT90USB processors (USBCON)." +#endif + +/** + * I2C bus + */ +#if ENABLED(EXPERIMENTAL_I2CBUS) && I2C_SLAVE_ADDRESS > 0 + #if I2C_SLAVE_ADDRESS < 8 + #error "I2C_SLAVE_ADDRESS can't be less than 8. (Addresses 0 - 7 are reserved.)" + #elif I2C_SLAVE_ADDRESS > 127 + #error "I2C_SLAVE_ADDRESS can't be over 127. (Only 7 bits allowed.)" + #endif +#endif + +/** + * G38 Probe Target + */ +#if ENABLED(G38_PROBE_TARGET) + #if !HAS_BED_PROBE + #error "G38_PROBE_TARGET requires a bed probe." + #elif !IS_CARTESIAN + #error "G38_PROBE_TARGET requires a Cartesian machine." + #endif +#endif + +/** + * RGB_LED Requirements + */ +#define _RGB_TEST (PIN_EXISTS(RGB_LED_R) && PIN_EXISTS(RGB_LED_G) && PIN_EXISTS(RGB_LED_B)) +#if ENABLED(RGB_LED) + #if !_RGB_TEST + #error "RGB_LED requires RGB_LED_R_PIN, RGB_LED_G_PIN, and RGB_LED_B_PIN." + #elif ENABLED(RGBW_LED) + #error "Please enable only one of RGB_LED and RGBW_LED." + #endif +#elif ENABLED(RGBW_LED) + #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) + #error "NEOPIXEL_LED requires NEOPIXEL_PIN and NEOPIXEL_PIXELS." + #endif +#elif ENABLED(PRINTER_EVENT_LEDS) && DISABLED(BLINKM) && DISABLED(PCA9632) && DISABLED(NEOPIXEL_LED) + #error "PRINTER_EVENT_LEDS requires BLINKM, PCA9632, RGB_LED, RGBW_LED or NEOPIXEL_LED." +#endif + +/** + * Auto Fan check for PWM pins + */ +#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(GET_TIMER(E0_AUTO_FAN_PIN), "E0" AF_ERR_SUFF); + #elif HAS_AUTO_FAN_1 + static_assert(GET_TIMER(E1_AUTO_FAN_PIN), "E1" AF_ERR_SUFF); + #elif HAS_AUTO_FAN_2 + static_assert(GET_TIMER(E2_AUTO_FAN_PIN), "E2" AF_ERR_SUFF); + #elif HAS_AUTO_FAN_3 + static_assert(GET_TIMER(E3_AUTO_FAN_PIN), "E3" AF_ERR_SUFF); + #endif +#endif + +/** + * Make sure only one display is enabled + * + * Note: BQ_LCD_SMART_CONTROLLER => REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER + * REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER => REPRAP_DISCOUNT_SMART_CONTROLLER + * SAV_3DGLCD => U8GLIB_SH1106 => ULTIMAKERCONTROLLER + * MKS_12864OLED => U8GLIB_SH1106 => ULTIMAKERCONTROLLER + * miniVIKI => ULTIMAKERCONTROLLER + * VIKI2 => ULTIMAKERCONTROLLER + * ELB_FULL_GRAPHIC_CONTROLLER => ULTIMAKERCONTROLLER + * PANEL_ONE => ULTIMAKERCONTROLLER + */ +static_assert(1 >= 0 + #if ENABLED(ULTIMAKERCONTROLLER) \ + && DISABLED(SAV_3DGLCD) \ + && DISABLED(miniVIKI) \ + && DISABLED(VIKI2) \ + && DISABLED(ELB_FULL_GRAPHIC_CONTROLLER) \ + && DISABLED(PANEL_ONE) \ + && DISABLED(MKS_12864OLED) + + 1 + #endif + #if ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER) \ + && DISABLED(REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER) \ + && DISABLED(LCD_FOR_MELZI) \ + && DISABLED(MAKEBOARD_MINI_2_LINE_DISPLAY_1602) \ + && DISABLED(MKS_12864OLED) + + 1 + #endif + #if ENABLED(REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER) \ + && DISABLED(BQ_LCD_SMART_CONTROLLER) + + 1 + #endif + #if ENABLED(LCD_FOR_MELZI) + + 1 + #endif + #if ENABLED(MKS_12864OLED) + + 1 + #endif + #if ENABLED(MAKEBOARD_MINI_2_LINE_DISPLAY_1602) + + 1 + #endif + #if ENABLED(CARTESIO_UI) + + 1 + #endif + #if ENABLED(PANEL_ONE) + + 1 + #endif + #if ENABLED(MAKRPANEL) + + 1 + #endif + #if ENABLED(REPRAPWORLD_GRAPHICAL_LCD) + + 1 + #endif + #if ENABLED(VIKI2) + + 1 + #endif + #if ENABLED(miniVIKI) + + 1 + #endif + #if ENABLED(ELB_FULL_GRAPHIC_CONTROLLER) + + 1 + #endif + #if ENABLED(G3D_PANEL) + + 1 + #endif + #if ENABLED(MINIPANEL) && DISABLED(MKS_MINI_12864) + + 1 + #endif + #if ENABLED(MKS_MINI_12864) + + 1 + #endif + #if ENABLED(REPRAPWORLD_KEYPAD) \ + && DISABLED(CARTESIO_UI) \ + && DISABLED(ANET_KEYPAD_LCD) + + 1 + #endif + #if ENABLED(RIGIDBOT_PANEL) + + 1 + #endif + #if ENABLED(RA_CONTROL_PANEL) + + 1 + #endif + #if ENABLED(LCD_I2C_SAINSMART_YWROBOT) + + 1 + #endif + #if ENABLED(LCM1602) + + 1 + #endif + #if ENABLED(LCD_I2C_PANELOLU2) + + 1 + #endif + #if ENABLED(LCD_I2C_VIKI) + + 1 + #endif + #if ENABLED(U8GLIB_SSD1306) && DISABLED(OLED_PANEL_TINYBOY2) + + 1 + #endif + #if ENABLED(SAV_3DLCD) + + 1 + #endif + #if ENABLED(BQ_LCD_SMART_CONTROLLER) + + 1 + #endif + #if ENABLED(SAV_3DGLCD) + + 1 + #endif + #if ENABLED(OLED_PANEL_TINYBOY2) + + 1 + #endif + #if ENABLED(ANET_KEYPAD_LCD) + + 1 + #endif + , "Please select no more than one LCD controller option." +); + +/** + * Make sure HAVE_TMCDRIVER is warranted + */ +#if ENABLED(HAVE_TMCDRIVER) && !( \ + ENABLED( X_IS_TMC ) \ + || ENABLED( X2_IS_TMC ) \ + || ENABLED( Y_IS_TMC ) \ + || ENABLED( Y2_IS_TMC ) \ + || ENABLED( Z_IS_TMC ) \ + || ENABLED( Z2_IS_TMC ) \ + || ENABLED( E0_IS_TMC ) \ + || ENABLED( E1_IS_TMC ) \ + || ENABLED( E2_IS_TMC ) \ + || ENABLED( E3_IS_TMC ) \ + || ENABLED( E4_IS_TMC ) \ + ) + #error "HAVE_TMCDRIVER requires at least one TMC stepper to be set." +#endif + +/** + * Make sure HAVE_TMC2130 is warranted + */ +#if ENABLED(HAVE_TMC2130) + #if !( ENABLED( X_IS_TMC2130 ) \ + || ENABLED( X2_IS_TMC2130 ) \ + || ENABLED( Y_IS_TMC2130 ) \ + || ENABLED( Y2_IS_TMC2130 ) \ + || ENABLED( Z_IS_TMC2130 ) \ + || ENABLED( Z2_IS_TMC2130 ) \ + || ENABLED( E0_IS_TMC2130 ) \ + || ENABLED( E1_IS_TMC2130 ) \ + || ENABLED( E2_IS_TMC2130 ) \ + || ENABLED( E3_IS_TMC2130 ) \ + || ENABLED( E4_IS_TMC2130 ) \ + ) + #error "HAVE_TMC2130 requires at least one TMC2130 stepper to be set." + #elif ENABLED(HYBRID_THRESHOLD) && DISABLED(STEALTHCHOP) + #error "Enable STEALTHCHOP to use HYBRID_THRESHOLD." + #endif +#endif + +/** + * Make sure HAVE_L6470DRIVER is warranted + */ +#if ENABLED(HAVE_L6470DRIVER) && !( \ + ENABLED( X_IS_L6470 ) \ + || ENABLED( X2_IS_L6470 ) \ + || ENABLED( Y_IS_L6470 ) \ + || ENABLED( Y2_IS_L6470 ) \ + || ENABLED( Z_IS_L6470 ) \ + || ENABLED( Z2_IS_L6470 ) \ + || ENABLED( E0_IS_L6470 ) \ + || ENABLED( E1_IS_L6470 ) \ + || ENABLED( E2_IS_L6470 ) \ + || ENABLED( E3_IS_L6470 ) \ + || ENABLED( E4_IS_L6470 ) \ + ) + #error "HAVE_L6470DRIVER requires at least one L6470 stepper to be set." +#endif + +/** + * 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 + +/** + * Require 4 or more elements in per-axis initializers + */ +constexpr float sanity_arr_1[] = DEFAULT_AXIS_STEPS_PER_UNIT, + sanity_arr_2[] = DEFAULT_MAX_FEEDRATE, + sanity_arr_3[] = DEFAULT_MAX_ACCELERATION; +static_assert(COUNT(sanity_arr_1) >= XYZE, "DEFAULT_AXIS_STEPS_PER_UNIT requires 4 (or more) elements."); +static_assert(COUNT(sanity_arr_2) >= XYZE, "DEFAULT_MAX_FEEDRATE requires 4 (or more) elements."); +static_assert(COUNT(sanity_arr_3) >= XYZE, "DEFAULT_MAX_ACCELERATION requires 4 (or more) elements."); +static_assert(COUNT(sanity_arr_1) <= XYZE_N, "DEFAULT_AXIS_STEPS_PER_UNIT has too many elements."); +static_assert(COUNT(sanity_arr_2) <= XYZE_N, "DEFAULT_MAX_FEEDRATE has too many elements."); +static_assert(COUNT(sanity_arr_3) <= XYZE_N, "DEFAULT_MAX_ACCELERATION has too many elements."); + +/** + * Sanity checks for Spindle / Laser + */ +#if ENABLED(SPINDLE_LASER_ENABLE) + #if !PIN_EXISTS(SPINDLE_LASER_ENABLE) + #error "SPINDLE_LASER_ENABLE requires SPINDLE_LASER_ENABLE_PIN." + #elif SPINDLE_DIR_CHANGE && !PIN_EXISTS(SPINDLE_DIR) + #error "SPINDLE_DIR_PIN not defined." + #elif ENABLED(SPINDLE_LASER_PWM) && PIN_EXISTS(SPINDLE_LASER_PWM) + #if !(WITHIN(SPINDLE_LASER_PWM_PIN, 2, 13) || WITHIN(SPINDLE_LASER_PWM_PIN, 44, 46)) + #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 missing." + #elif !defined(SPEED_POWER_SLOPE) || !defined(SPEED_POWER_INTERCEPT) || !defined(SPEED_POWER_MIN) || !defined(SPEED_POWER_MAX) + #error "SPINDLE_LASER_PWM equation constant(s) missing." + #elif 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 PIN_EXISTS(X_MAX) && X_MAX_PIN == SPINDLE_LASER_PWM_PIN + #error "SPINDLE_LASER_PWM pin is in use by X_MAX endstop." + #elif PIN_EXISTS(X_MIN) && X_MIN_PIN == SPINDLE_LASER_PWM_PIN + #error "SPINDLE_LASER_PWM pin is in use by X_MIN endstop." + #elif PIN_EXISTS(Z_STEP) && Z_STEP_PIN == SPINDLE_LASER_PWM_PIN + #error "SPINDLE_LASER_PWM pin in use by Z_STEP." + #elif NUM_SERVOS > 0 && (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." + #elif PIN_EXISTS(CASE_LIGHT) && SPINDLE_LASER_PWM_PIN == CASE_LIGHT_PIN + #error "SPINDLE_LASER_PWM_PIN is used by CASE_LIGHT_PIN." + #elif PIN_EXISTS(E0_AUTO_FAN) && SPINDLE_LASER_PWM_PIN == E0_AUTO_FAN_PIN + #error "SPINDLE_LASER_PWM_PIN is used by E0_AUTO_FAN_PIN." + #elif PIN_EXISTS(E1_AUTO_FAN) && SPINDLE_LASER_PWM_PIN == E1_AUTO_FAN_PIN + #error "SPINDLE_LASER_PWM_PIN is used by E1_AUTO_FAN_PIN." + #elif PIN_EXISTS(E2_AUTO_FAN) && SPINDLE_LASER_PWM_PIN == E2_AUTO_FAN_PIN + #error "SPINDLE_LASER_PWM_PIN is used by E2_AUTO_FAN_PIN." + #elif PIN_EXISTS(E3_AUTO_FAN) && SPINDLE_LASER_PWM_PIN == E3_AUTO_FAN_PIN + #error "SPINDLE_LASER_PWM_PIN is used by E3_AUTO_FAN_PIN." + #elif PIN_EXISTS(E4_AUTO_FAN) && SPINDLE_LASER_PWM_PIN == E4_AUTO_FAN_PIN + #error "SPINDLE_LASER_PWM_PIN is used by E4_AUTO_FAN_PIN." + #elif PIN_EXISTS(FAN) && SPINDLE_LASER_PWM_PIN == FAN_PIN + #error "SPINDLE_LASER_PWM_PIN is used FAN_PIN." + #elif PIN_EXISTS(FAN1) && SPINDLE_LASER_PWM_PIN == FAN1_PIN + #error "SPINDLE_LASER_PWM_PIN is used FAN1_PIN." + #elif PIN_EXISTS(FAN2) && SPINDLE_LASER_PWM_PIN == FAN2_PIN + #error "SPINDLE_LASER_PWM_PIN is used FAN2_PIN." + #elif PIN_EXISTS(CONTROLLERFAN) && SPINDLE_LASER_PWM_PIN == CONTROLLERFAN_PIN + #error "SPINDLE_LASER_PWM_PIN is used by CONTROLLERFAN_PIN." + #elif PIN_EXISTS(MOTOR_CURRENT_PWM_XY) && SPINDLE_LASER_PWM_PIN == MOTOR_CURRENT_PWM_XY_PIN + #error "SPINDLE_LASER_PWM_PIN is used by MOTOR_CURRENT_PWM_XY." + #elif PIN_EXISTS(MOTOR_CURRENT_PWM_Z) && SPINDLE_LASER_PWM_PIN == MOTOR_CURRENT_PWM_Z_PIN + #error "SPINDLE_LASER_PWM_PIN is used by MOTOR_CURRENT_PWM_Z." + #elif PIN_EXISTS(MOTOR_CURRENT_PWM_E) && SPINDLE_LASER_PWM_PIN == MOTOR_CURRENT_PWM_E_PIN + #error "SPINDLE_LASER_PWM_PIN is used by MOTOR_CURRENT_PWM_E." + #elif PIN_EXISTS(CASE_LIGHT) && SPINDLE_LASER_PWM_PIN == CASE_LIGHT_PIN + #error "SPINDLE_LASER_PWM_PIN is used by CASE_LIGHT." + #endif + #endif +#endif // SPINDLE_LASER_ENABLE diff --git a/trunk/Arduino/Marlin_1.1.6/Sd2Card.cpp b/trunk/Arduino/Marlin_1.1.6/Sd2Card.cpp new file mode 100644 index 00000000..2afe9a8b --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/Sd2Card.cpp @@ -0,0 +1,729 @@ +/** + * 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 . + * + */ + +/** + * Arduino Sd2Card Library + * Copyright (C) 2009 by William Greiman + * + * This file is part of the Arduino Sd2Card Library + */ +#include "Marlin.h" + +#if ENABLED(SDSUPPORT) +#include "Sd2Card.h" + +#if ENABLED(USE_WATCHDOG) + #include "watchdog.h" +#endif + +//------------------------------------------------------------------------------ +#if DISABLED(SOFTWARE_SPI) + // functions for hardware SPI + //------------------------------------------------------------------------------ + // make sure SPCR rate is in expected bits + #if (SPR0 != 0 || SPR1 != 1) + #error "unexpected SPCR bits" + #endif + /** + * Initialize hardware SPI + * Set SCK rate to F_CPU/pow(2, 1 + spiRate) for spiRate [0,6] + */ + static void spiInit(uint8_t spiRate) { + // See avr processor documentation + SPCR = _BV(SPE) | _BV(MSTR) | (spiRate >> 1); + SPSR = spiRate & 1 || spiRate == 6 ? 0 : _BV(SPI2X); + } + //------------------------------------------------------------------------------ + /** SPI receive a byte */ + static uint8_t spiRec() { + SPDR = 0xFF; + while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ } + return SPDR; + } + //------------------------------------------------------------------------------ + /** SPI read data - only one call so force inline */ + static inline __attribute__((always_inline)) + void spiRead(uint8_t* buf, uint16_t nbyte) { + 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; + } + //------------------------------------------------------------------------------ + /** SPI send a byte */ + static void spiSend(uint8_t b) { + SPDR = b; + while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ } + } + //------------------------------------------------------------------------------ + /** SPI send block - only one call so force inline */ + static inline __attribute__((always_inline)) + void spiSendBlock(uint8_t token, const uint8_t* buf) { + SPDR = token; + for (uint16_t i = 0; i < 512; i += 2) { + while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ } + SPDR = buf[i]; + while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ } + SPDR = buf[i + 1]; + } + while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ } + } + //------------------------------------------------------------------------------ +#else // SOFTWARE_SPI + //------------------------------------------------------------------------------ + /** nop to tune soft SPI timing */ + #define nop asm volatile ("nop\n\t") + //------------------------------------------------------------------------------ + /** Soft SPI receive byte */ + static uint8_t spiRec() { + uint8_t data = 0; + // no interrupts during byte receive - about 8 us + cli(); + // output pin high - like sending 0xFF + WRITE(SPI_MOSI_PIN, HIGH); + + for (uint8_t i = 0; i < 8; i++) { + WRITE(SPI_SCK_PIN, HIGH); + + // adjust so SCK is nice + nop; + nop; + + data <<= 1; + + if (READ(SPI_MISO_PIN)) data |= 1; + + WRITE(SPI_SCK_PIN, LOW); + } + // enable interrupts + sei(); + return data; + } + //------------------------------------------------------------------------------ + /** Soft SPI read data */ + static void spiRead(uint8_t* buf, uint16_t nbyte) { + for (uint16_t i = 0; i < nbyte; i++) + buf[i] = spiRec(); + } + //------------------------------------------------------------------------------ + /** Soft SPI send byte */ + static void spiSend(uint8_t data) { + // no interrupts during byte send - about 8 us + cli(); + for (uint8_t i = 0; i < 8; i++) { + WRITE(SPI_SCK_PIN, LOW); + + WRITE(SPI_MOSI_PIN, data & 0x80); + + data <<= 1; + + WRITE(SPI_SCK_PIN, HIGH); + } + // hold SCK high for a few ns + nop; + nop; + nop; + nop; + + WRITE(SPI_SCK_PIN, LOW); + // enable interrupts + sei(); + } + //------------------------------------------------------------------------------ + /** Soft SPI send block */ + void spiSendBlock(uint8_t token, const uint8_t* buf) { + spiSend(token); + for (uint16_t i = 0; i < 512; i++) + spiSend(buf[i]); + } +#endif // SOFTWARE_SPI +//------------------------------------------------------------------------------ +// send command and return error code. Return zero for OK +uint8_t Sd2Card::cardCommand(uint8_t cmd, uint32_t arg) { + // select card + chipSelectLow(); + + // wait up to 300 ms if busy + waitNotBusy(300); + + // send command + spiSend(cmd | 0x40); + + // send argument + for (int8_t s = 24; s >= 0; s -= 8) spiSend(arg >> s); + + // send CRC + uint8_t crc = 0xFF; + if (cmd == CMD0) crc = 0x95; // correct crc for CMD0 with arg 0 + if (cmd == CMD8) crc = 0x87; // correct crc for CMD8 with arg 0x1AA + spiSend(crc); + + // skip stuff byte for stop read + if (cmd == CMD12) spiRec(); + + // wait for response + for (uint8_t i = 0; ((status_ = spiRec()) & 0x80) && i != 0xFF; i++) { /* Intentionally left empty */ } + return status_; +} +//------------------------------------------------------------------------------ +/** + * Determine the size of an SD flash memory card. + * + * \return The number of 512 byte data blocks in the card + * or zero if an error occurs. + */ +uint32_t Sd2Card::cardSize() { + csd_t csd; + if (!readCSD(&csd)) return 0; + if (csd.v1.csd_ver == 0) { + uint8_t read_bl_len = csd.v1.read_bl_len; + uint16_t c_size = (csd.v1.c_size_high << 10) + | (csd.v1.c_size_mid << 2) | csd.v1.c_size_low; + uint8_t c_size_mult = (csd.v1.c_size_mult_high << 1) + | csd.v1.c_size_mult_low; + return (uint32_t)(c_size + 1) << (c_size_mult + read_bl_len - 7); + } + else if (csd.v2.csd_ver == 1) { + uint32_t c_size = ((uint32_t)csd.v2.c_size_high << 16) + | (csd.v2.c_size_mid << 8) | csd.v2.c_size_low; + return (c_size + 1) << 10; + } + else { + error(SD_CARD_ERROR_BAD_CSD); + return 0; + } +} +//------------------------------------------------------------------------------ +void Sd2Card::chipSelectHigh() { + digitalWrite(chipSelectPin_, HIGH); +} +//------------------------------------------------------------------------------ +void Sd2Card::chipSelectLow() { + #if DISABLED(SOFTWARE_SPI) + spiInit(spiRate_); + #endif // SOFTWARE_SPI + digitalWrite(chipSelectPin_, LOW); +} +//------------------------------------------------------------------------------ +/** Erase a range of blocks. + * + * \param[in] firstBlock The address of the first block in the range. + * \param[in] lastBlock The address of the last block in the range. + * + * \note This function requests the SD card to do a flash erase for a + * range of blocks. The data on the card after an erase operation is + * either 0 or 1, depends on the card vendor. The card must support + * single block erase. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool Sd2Card::erase(uint32_t firstBlock, uint32_t lastBlock) { + csd_t csd; + if (!readCSD(&csd)) goto FAIL; + // check for single block erase + if (!csd.v1.erase_blk_en) { + // erase size mask + uint8_t m = (csd.v1.sector_size_high << 1) | csd.v1.sector_size_low; + if ((firstBlock & m) != 0 || ((lastBlock + 1) & m) != 0) { + // error card can't erase specified area + error(SD_CARD_ERROR_ERASE_SINGLE_BLOCK); + goto FAIL; + } + } + if (type_ != SD_CARD_TYPE_SDHC) { + firstBlock <<= 9; + lastBlock <<= 9; + } + if (cardCommand(CMD32, firstBlock) + || cardCommand(CMD33, lastBlock) + || cardCommand(CMD38, 0)) { + error(SD_CARD_ERROR_ERASE); + goto FAIL; + } + if (!waitNotBusy(SD_ERASE_TIMEOUT)) { + error(SD_CARD_ERROR_ERASE_TIMEOUT); + goto FAIL; + } + chipSelectHigh(); + return true; + FAIL: + chipSelectHigh(); + return false; +} +//------------------------------------------------------------------------------ +/** Determine if card supports single block erase. + * + * \return The value one, true, is returned if single block erase is supported. + * The value zero, false, is returned if single block erase is not supported. + */ +bool Sd2Card::eraseSingleBlockEnable() { + csd_t csd; + return readCSD(&csd) ? csd.v1.erase_blk_en : false; +} +//------------------------------------------------------------------------------ +/** + * Initialize an SD flash memory card. + * + * \param[in] sckRateID SPI clock rate selector. See setSckRate(). + * \param[in] chipSelectPin SD chip select pin number. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. The reason for failure + * can be determined by calling errorCode() and errorData(). + */ +bool Sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin) { + errorCode_ = type_ = 0; + chipSelectPin_ = chipSelectPin; + // 16-bit init start time allows over a minute + uint16_t t0 = (uint16_t)millis(); + uint32_t arg; + + // If init takes more than 4s it could trigger + // watchdog leading to a reboot loop. + #if ENABLED(USE_WATCHDOG) + watchdog_reset(); + #endif + + // set pin modes + pinMode(chipSelectPin_, OUTPUT); + chipSelectHigh(); + SET_INPUT(SPI_MISO_PIN); + SET_OUTPUT(SPI_MOSI_PIN); + SET_OUTPUT(SPI_SCK_PIN); + + #if DISABLED(SOFTWARE_SPI) + // SS must be in output mode even it is not chip select + SET_OUTPUT(SS_PIN); + // set SS high - may be chip select for another SPI device + #if SET_SPI_SS_HIGH + WRITE(SS_PIN, HIGH); + #endif // SET_SPI_SS_HIGH + // set SCK rate for initialization commands + spiRate_ = SPI_SD_INIT_RATE; + spiInit(spiRate_); + #endif // SOFTWARE_SPI + + // must supply min of 74 clock cycles with CS high. + for (uint8_t i = 0; i < 10; i++) spiSend(0xFF); + + // command to go idle in SPI mode + while ((status_ = cardCommand(CMD0, 0)) != R1_IDLE_STATE) { + if (((uint16_t)millis() - t0) > SD_INIT_TIMEOUT) { + error(SD_CARD_ERROR_CMD0); + goto FAIL; + } + } + // check SD version + if ((cardCommand(CMD8, 0x1AA) & R1_ILLEGAL_COMMAND)) { + type(SD_CARD_TYPE_SD1); + } + else { + // only need last byte of r7 response + for (uint8_t i = 0; i < 4; i++) status_ = spiRec(); + if (status_ != 0xAA) { + error(SD_CARD_ERROR_CMD8); + goto FAIL; + } + type(SD_CARD_TYPE_SD2); + } + // initialize card and send host supports SDHC if SD2 + arg = type() == SD_CARD_TYPE_SD2 ? 0x40000000 : 0; + + while ((status_ = cardAcmd(ACMD41, arg)) != R1_READY_STATE) { + // check for timeout + if (((uint16_t)millis() - t0) > SD_INIT_TIMEOUT) { + error(SD_CARD_ERROR_ACMD41); + goto FAIL; + } + } + // if SD2 read OCR register to check for SDHC card + if (type() == SD_CARD_TYPE_SD2) { + if (cardCommand(CMD58, 0)) { + error(SD_CARD_ERROR_CMD58); + goto FAIL; + } + 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(); + } + chipSelectHigh(); + + #if DISABLED(SOFTWARE_SPI) + return setSckRate(sckRateID); + #else // SOFTWARE_SPI + UNUSED(sckRateID); + return true; + #endif // SOFTWARE_SPI + + FAIL: + chipSelectHigh(); + return false; +} +//------------------------------------------------------------------------------ +/** + * Read a 512 byte block from an SD card. + * + * \param[in] blockNumber Logical block to be read. + * \param[out] dst Pointer to the location that will receive the data. + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool Sd2Card::readBlock(uint32_t blockNumber, uint8_t* dst) { + // use address if not SDHC card + if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9; + + #if ENABLED(SD_CHECK_AND_RETRY) + uint8_t retryCnt = 3; + do { + if (!cardCommand(CMD17, blockNumber)) { + if (readData(dst, 512)) return true; + } + else + error(SD_CARD_ERROR_CMD17); + + if (!--retryCnt) break; + + chipSelectHigh(); + cardCommand(CMD12, 0); // Try sending a stop command, ignore the result. + errorCode_ = 0; + } while (true); + #else + if (cardCommand(CMD17, blockNumber)) + error(SD_CARD_ERROR_CMD17); + else + return readData(dst, 512); + #endif + + chipSelectHigh(); + return false; +} +//------------------------------------------------------------------------------ +/** Read one data block in a multiple block read sequence + * + * \param[in] dst Pointer to the location for the data to be read. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool Sd2Card::readData(uint8_t* dst) { + chipSelectLow(); + return readData(dst, 512); +} + +#if ENABLED(SD_CHECK_AND_RETRY) +static const uint16_t crctab[] PROGMEM = { + 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, + 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF, + 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6, + 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE, + 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485, + 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D, + 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4, + 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC, + 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823, + 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B, + 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12, + 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A, + 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41, + 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49, + 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70, + 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78, + 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F, + 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067, + 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E, + 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256, + 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D, + 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, + 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C, + 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634, + 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB, + 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3, + 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A, + 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92, + 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9, + 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1, + 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8, + 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0 +}; +static uint16_t CRC_CCITT(const uint8_t* data, size_t n) { + uint16_t crc = 0; + for (size_t i = 0; i < n; i++) { + crc = pgm_read_word(&crctab[(crc >> 8 ^ data[i]) & 0xFF]) ^ (crc << 8); + } + return crc; +} +#endif + +//------------------------------------------------------------------------------ +bool Sd2Card::readData(uint8_t* dst, uint16_t count) { + // wait for start block token + uint16_t t0 = millis(); + while ((status_ = spiRec()) == 0XFF) { + if (((uint16_t)millis() - t0) > SD_READ_TIMEOUT) { + error(SD_CARD_ERROR_READ_TIMEOUT); + goto FAIL; + } + } + if (status_ != DATA_START_BLOCK) { + error(SD_CARD_ERROR_READ); + goto FAIL; + } + // transfer data + spiRead(dst, count); + +#if ENABLED(SD_CHECK_AND_RETRY) + { + uint16_t calcCrc = CRC_CCITT(dst, count); + uint16_t recvCrc = spiRec() << 8; + recvCrc |= spiRec(); + if (calcCrc != recvCrc) { + error(SD_CARD_ERROR_CRC); + goto FAIL; + } + } +#else + // discard CRC + spiRec(); + spiRec(); +#endif + chipSelectHigh(); + // Send an additional dummy byte, required by Toshiba Flash Air SD Card + spiSend(0XFF); + return true; + FAIL: + chipSelectHigh(); + // Send an additional dummy byte, required by Toshiba Flash Air SD Card + spiSend(0XFF); + return false; +} +//------------------------------------------------------------------------------ +/** read CID or CSR register */ +bool Sd2Card::readRegister(uint8_t cmd, void* buf) { + uint8_t* dst = reinterpret_cast(buf); + if (cardCommand(cmd, 0)) { + error(SD_CARD_ERROR_READ_REG); + goto FAIL; + } + return readData(dst, 16); + FAIL: + chipSelectHigh(); + return false; +} +//------------------------------------------------------------------------------ +/** Start a read multiple blocks sequence. + * + * \param[in] blockNumber Address of first block in sequence. + * + * \note This function is used with readData() and readStop() for optimized + * multiple block reads. SPI chipSelect must be low for the entire sequence. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool Sd2Card::readStart(uint32_t blockNumber) { + if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9; + if (cardCommand(CMD18, blockNumber)) { + error(SD_CARD_ERROR_CMD18); + goto FAIL; + } + chipSelectHigh(); + return true; + FAIL: + chipSelectHigh(); + return false; +} +//------------------------------------------------------------------------------ +/** End a read multiple blocks sequence. + * +* \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool Sd2Card::readStop() { + chipSelectLow(); + if (cardCommand(CMD12, 0)) { + error(SD_CARD_ERROR_CMD12); + goto FAIL; + } + chipSelectHigh(); + return true; + FAIL: + chipSelectHigh(); + return false; +} +//------------------------------------------------------------------------------ +/** + * Set the SPI clock rate. + * + * \param[in] sckRateID A value in the range [0, 6]. + * + * The SPI clock will be set to F_CPU/pow(2, 1 + sckRateID). The maximum + * SPI rate is F_CPU/2 for \a sckRateID = 0 and the minimum rate is F_CPU/128 + * for \a scsRateID = 6. + * + * \return The value one, true, is returned for success and the value zero, + * false, is returned for an invalid value of \a sckRateID. + */ +bool Sd2Card::setSckRate(uint8_t sckRateID) { + if (sckRateID > 6) { + error(SD_CARD_ERROR_SCK_RATE); + return false; + } + spiRate_ = sckRateID; + return true; +} +//------------------------------------------------------------------------------ +// wait for card to go not busy +bool Sd2Card::waitNotBusy(uint16_t timeoutMillis) { + uint16_t t0 = millis(); + while (spiRec() != 0XFF) { + if (((uint16_t)millis() - t0) >= timeoutMillis) goto FAIL; + } + return true; + FAIL: + return false; +} +//------------------------------------------------------------------------------ +/** + * Writes a 512 byte block to an SD card. + * + * \param[in] blockNumber Logical block to be written. + * \param[in] src Pointer to the location of the data to be written. + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool Sd2Card::writeBlock(uint32_t blockNumber, const uint8_t* src) { + // use address if not SDHC card + if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9; + if (cardCommand(CMD24, blockNumber)) { + error(SD_CARD_ERROR_CMD24); + goto FAIL; + } + if (!writeData(DATA_START_BLOCK, src)) goto FAIL; + + // wait for flash programming to complete + if (!waitNotBusy(SD_WRITE_TIMEOUT)) { + error(SD_CARD_ERROR_WRITE_TIMEOUT); + goto FAIL; + } + // response is r2 so get and check two bytes for nonzero + if (cardCommand(CMD13, 0) || spiRec()) { + error(SD_CARD_ERROR_WRITE_PROGRAMMING); + goto FAIL; + } + chipSelectHigh(); + return true; + FAIL: + chipSelectHigh(); + return false; +} +//------------------------------------------------------------------------------ +/** Write one data block in a multiple block write sequence + * \param[in] src Pointer to the location of the data to be written. + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool Sd2Card::writeData(const uint8_t* src) { + chipSelectLow(); + // wait for previous write to finish + if (!waitNotBusy(SD_WRITE_TIMEOUT)) goto FAIL; + if (!writeData(WRITE_MULTIPLE_TOKEN, src)) goto FAIL; + chipSelectHigh(); + return true; + FAIL: + error(SD_CARD_ERROR_WRITE_MULTIPLE); + chipSelectHigh(); + return false; +} +//------------------------------------------------------------------------------ +// send one block of data for write block or write multiple blocks +bool Sd2Card::writeData(uint8_t token, const uint8_t* src) { + spiSendBlock(token, src); + + spiSend(0xFF); // dummy crc + spiSend(0xFF); // dummy crc + + status_ = spiRec(); + if ((status_ & DATA_RES_MASK) != DATA_RES_ACCEPTED) { + error(SD_CARD_ERROR_WRITE); + goto FAIL; + } + return true; + FAIL: + chipSelectHigh(); + return false; +} +//------------------------------------------------------------------------------ +/** Start a write multiple blocks sequence. + * + * \param[in] blockNumber Address of first block in sequence. + * \param[in] eraseCount The number of blocks to be pre-erased. + * + * \note This function is used with writeData() and writeStop() + * for optimized multiple block writes. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool Sd2Card::writeStart(uint32_t blockNumber, uint32_t eraseCount) { + // send pre-erase count + if (cardAcmd(ACMD23, eraseCount)) { + error(SD_CARD_ERROR_ACMD23); + goto FAIL; + } + // use address if not SDHC card + if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9; + if (cardCommand(CMD25, blockNumber)) { + error(SD_CARD_ERROR_CMD25); + goto FAIL; + } + chipSelectHigh(); + return true; + FAIL: + chipSelectHigh(); + return false; +} +//------------------------------------------------------------------------------ +/** End a write multiple blocks sequence. + * +* \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool Sd2Card::writeStop() { + chipSelectLow(); + if (!waitNotBusy(SD_WRITE_TIMEOUT)) goto FAIL; + spiSend(STOP_TRAN_TOKEN); + if (!waitNotBusy(SD_WRITE_TIMEOUT)) goto FAIL; + chipSelectHigh(); + return true; + FAIL: + error(SD_CARD_ERROR_STOP_TRAN); + chipSelectHigh(); + return false; +} + +#endif diff --git a/trunk/Arduino/Marlin_1.1.6/Sd2Card.h b/trunk/Arduino/Marlin_1.1.6/Sd2Card.h new file mode 100644 index 00000000..1fbd5274 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/Sd2Card.h @@ -0,0 +1,251 @@ +/** + * 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 . + * + */ + +/** + * Arduino Sd2Card Library + * Copyright (C) 2009 by William Greiman + * + * This file is part of the Arduino Sd2Card Library + */ + +#include "Marlin.h" +#if ENABLED(SDSUPPORT) + +#ifndef Sd2Card_h +#define Sd2Card_h +/** + * \file + * \brief Sd2Card class for V2 SD/SDHC cards + */ +#include "SdFatConfig.h" +#include "SdInfo.h" +//------------------------------------------------------------------------------ +// SPI speed is F_CPU/2^(1 + index), 0 <= index <= 6 +/** Set SCK to max rate of F_CPU/2. See Sd2Card::setSckRate(). */ +uint8_t const SPI_FULL_SPEED = 0; +/** Set SCK rate to F_CPU/4. See Sd2Card::setSckRate(). */ +uint8_t const SPI_HALF_SPEED = 1; +/** Set SCK rate to F_CPU/8. See Sd2Card::setSckRate(). */ +uint8_t const SPI_QUARTER_SPEED = 2; +/** Set SCK rate to F_CPU/16. See Sd2Card::setSckRate(). */ +uint8_t const SPI_EIGHTH_SPEED = 3; +/** Set SCK rate to F_CPU/32. See Sd2Card::setSckRate(). */ +uint8_t const SPI_SIXTEENTH_SPEED = 4; +//------------------------------------------------------------------------------ +/** init timeout ms */ +uint16_t const SD_INIT_TIMEOUT = 2000; +/** erase timeout ms */ +uint16_t const SD_ERASE_TIMEOUT = 10000; +/** read timeout ms */ +uint16_t const SD_READ_TIMEOUT = 300; +/** write time out ms */ +uint16_t const SD_WRITE_TIMEOUT = 600; +//------------------------------------------------------------------------------ +// SD card errors +/** timeout error for command CMD0 (initialize card in SPI mode) */ +uint8_t const SD_CARD_ERROR_CMD0 = 0X1; +/** CMD8 was not accepted - not a valid SD card*/ +uint8_t const SD_CARD_ERROR_CMD8 = 0X2; +/** card returned an error response for CMD12 (write stop) */ +uint8_t const SD_CARD_ERROR_CMD12 = 0X3; +/** card returned an error response for CMD17 (read block) */ +uint8_t const SD_CARD_ERROR_CMD17 = 0X4; +/** card returned an error response for CMD18 (read multiple block) */ +uint8_t const SD_CARD_ERROR_CMD18 = 0X5; +/** card returned an error response for CMD24 (write block) */ +uint8_t const SD_CARD_ERROR_CMD24 = 0X6; +/** WRITE_MULTIPLE_BLOCKS command failed */ +uint8_t const SD_CARD_ERROR_CMD25 = 0X7; +/** card returned an error response for CMD58 (read OCR) */ +uint8_t const SD_CARD_ERROR_CMD58 = 0X8; +/** SET_WR_BLK_ERASE_COUNT failed */ +uint8_t const SD_CARD_ERROR_ACMD23 = 0X9; +/** ACMD41 initialization process timeout */ +uint8_t const SD_CARD_ERROR_ACMD41 = 0XA; +/** card returned a bad CSR version field */ +uint8_t const SD_CARD_ERROR_BAD_CSD = 0XB; +/** erase block group command failed */ +uint8_t const SD_CARD_ERROR_ERASE = 0XC; +/** card not capable of single block erase */ +uint8_t const SD_CARD_ERROR_ERASE_SINGLE_BLOCK = 0XD; +/** Erase sequence timed out */ +uint8_t const SD_CARD_ERROR_ERASE_TIMEOUT = 0XE; +/** card returned an error token instead of read data */ +uint8_t const SD_CARD_ERROR_READ = 0XF; +/** read CID or CSD failed */ +uint8_t const SD_CARD_ERROR_READ_REG = 0x10; +/** timeout while waiting for start of read data */ +uint8_t const SD_CARD_ERROR_READ_TIMEOUT = 0x11; +/** card did not accept STOP_TRAN_TOKEN */ +uint8_t const SD_CARD_ERROR_STOP_TRAN = 0x12; +/** card returned an error token as a response to a write operation */ +uint8_t const SD_CARD_ERROR_WRITE = 0x13; +/** attempt to write protected block zero */ +uint8_t const SD_CARD_ERROR_WRITE_BLOCK_ZERO = 0x14; // REMOVE - not used +/** card did not go ready for a multiple block write */ +uint8_t const SD_CARD_ERROR_WRITE_MULTIPLE = 0x15; +/** card returned an error to a CMD13 status check after a write */ +uint8_t const SD_CARD_ERROR_WRITE_PROGRAMMING = 0x16; +/** timeout occurred during write programming */ +uint8_t const SD_CARD_ERROR_WRITE_TIMEOUT = 0x17; +/** incorrect rate selected */ +uint8_t const SD_CARD_ERROR_SCK_RATE = 0x18; +/** init() not called */ +uint8_t const SD_CARD_ERROR_INIT_NOT_CALLED = 0x19; +/** crc check error */ +uint8_t const SD_CARD_ERROR_CRC = 0x20; +//------------------------------------------------------------------------------ +// card types +/** Standard capacity V1 SD card */ +uint8_t const SD_CARD_TYPE_SD1 = 1; +/** Standard capacity V2 SD card */ +uint8_t const SD_CARD_TYPE_SD2 = 2; +/** High Capacity SD card */ +uint8_t const SD_CARD_TYPE_SDHC = 3; +/** + * define SOFTWARE_SPI to use bit-bang SPI + */ +//------------------------------------------------------------------------------ +#if MEGA_SOFT_SPI + #define SOFTWARE_SPI +#elif USE_SOFTWARE_SPI + #define SOFTWARE_SPI +#endif // MEGA_SOFT_SPI +//------------------------------------------------------------------------------ +// SPI pin definitions - do not edit here - change in SdFatConfig.h +// +#if DISABLED(SOFTWARE_SPI) + // hardware pin defs + /** The default chip select pin for the SD card is SS. */ + #define SD_CHIP_SELECT_PIN SS_PIN + // The following three pins must not be redefined for hardware SPI. + /** SPI Master Out Slave In pin */ + #define SPI_MOSI_PIN MOSI_PIN + /** SPI Master In Slave Out pin */ + #define SPI_MISO_PIN MISO_PIN + /** SPI Clock pin */ + #define SPI_SCK_PIN SCK_PIN + +#else // SOFTWARE_SPI + + /** SPI chip select pin */ + #define SD_CHIP_SELECT_PIN SOFT_SPI_CS_PIN + /** SPI Master Out Slave In pin */ + #define SPI_MOSI_PIN SOFT_SPI_MOSI_PIN + /** SPI Master In Slave Out pin */ + #define SPI_MISO_PIN SOFT_SPI_MISO_PIN + /** SPI Clock pin */ + #define SPI_SCK_PIN SOFT_SPI_SCK_PIN +#endif // SOFTWARE_SPI +//------------------------------------------------------------------------------ +/** + * \class Sd2Card + * \brief Raw access to SD and SDHC flash memory cards. + */ +class Sd2Card { + public: + /** Construct an instance of Sd2Card. */ + Sd2Card() : errorCode_(SD_CARD_ERROR_INIT_NOT_CALLED), type_(0) {} + uint32_t cardSize(); + bool erase(uint32_t firstBlock, uint32_t lastBlock); + bool eraseSingleBlockEnable(); + /** + * Set SD error code. + * \param[in] code value for error code. + */ + void error(uint8_t code) {errorCode_ = code;} + /** + * \return error code for last error. See Sd2Card.h for a list of error codes. + */ + int errorCode() const {return errorCode_;} + /** \return error data for last error. */ + int errorData() const {return status_;} + /** + * Initialize an SD flash memory card with default clock rate and chip + * select pin. See sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin). + * + * \return true for success or false for failure. + */ + bool init(uint8_t sckRateID = SPI_FULL_SPEED, + uint8_t chipSelectPin = SD_CHIP_SELECT_PIN); + bool readBlock(uint32_t block, uint8_t* dst); + /** + * Read a card's CID register. The CID contains card identification + * information such as Manufacturer ID, Product name, Product serial + * number and Manufacturing date. + * + * \param[out] cid pointer to area for returned data. + * + * \return true for success or false for failure. + */ + bool readCID(cid_t* cid) { + return readRegister(CMD10, cid); + } + /** + * Read a card's CSD register. The CSD contains Card-Specific Data that + * provides information regarding access to the card's contents. + * + * \param[out] csd pointer to area for returned data. + * + * \return true for success or false for failure. + */ + bool readCSD(csd_t* csd) { + return readRegister(CMD9, csd); + } + bool readData(uint8_t* dst); + bool readStart(uint32_t blockNumber); + bool readStop(); + bool setSckRate(uint8_t sckRateID); + /** Return the card type: SD V1, SD V2 or SDHC + * \return 0 - SD V1, 1 - SD V2, or 3 - SDHC. + */ + int type() const {return type_;} + bool writeBlock(uint32_t blockNumber, const uint8_t* src); + bool writeData(const uint8_t* src); + bool writeStart(uint32_t blockNumber, uint32_t eraseCount); + bool writeStop(); + private: + //---------------------------------------------------------------------------- + uint8_t chipSelectPin_; + uint8_t errorCode_; + uint8_t spiRate_; + uint8_t status_; + uint8_t type_; + // private functions + uint8_t cardAcmd(uint8_t cmd, uint32_t arg) { + cardCommand(CMD55, 0); + return cardCommand(cmd, arg); + } + uint8_t cardCommand(uint8_t cmd, uint32_t arg); + + bool readData(uint8_t* dst, uint16_t count); + bool readRegister(uint8_t cmd, void* buf); + void chipSelectHigh(); + void chipSelectLow(); + void type(uint8_t value) {type_ = value;} + bool waitNotBusy(uint16_t timeoutMillis); + bool writeData(uint8_t token, const uint8_t* src); +}; +#endif // Sd2Card_h + + +#endif diff --git a/trunk/Arduino/Marlin_1.1.6/SdBaseFile.cpp b/trunk/Arduino/Marlin_1.1.6/SdBaseFile.cpp new file mode 100644 index 00000000..95fc2b62 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/SdBaseFile.cpp @@ -0,0 +1,1826 @@ +/** + * 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 . + * + */ + +/** + * Arduino SdFat Library + * Copyright (C) 2009 by William Greiman + * + * This file is part of the Arduino Sd2Card Library + */ + +#include "Marlin.h" +#if ENABLED(SDSUPPORT) + +#include "SdBaseFile.h" +//------------------------------------------------------------------------------ +// pointer to cwd directory +SdBaseFile* SdBaseFile::cwd_ = 0; +// callback function for date/time +void (*SdBaseFile::dateTime_)(uint16_t* date, uint16_t* time) = 0; +//------------------------------------------------------------------------------ +// add a cluster to a file +bool SdBaseFile::addCluster() { + if (!vol_->allocContiguous(1, &curCluster_)) goto FAIL; + + // if first cluster of file link to directory entry + if (firstCluster_ == 0) { + firstCluster_ = curCluster_; + flags_ |= F_FILE_DIR_DIRTY; + } + return true; + + FAIL: + return false; +} +//------------------------------------------------------------------------------ +// Add a cluster to a directory file and zero the cluster. +// return with first block of cluster in the cache +bool SdBaseFile::addDirCluster() { + uint32_t block; + // max folder size + if (fileSize_ / sizeof(dir_t) >= 0xFFFF) goto FAIL; + + if (!addCluster()) goto FAIL; + if (!vol_->cacheFlush()) goto FAIL; + + block = vol_->clusterStartBlock(curCluster_); + + // set cache to first block of cluster + vol_->cacheSetBlockNumber(block, true); + + // zero first block of cluster + memset(vol_->cacheBuffer_.data, 0, 512); + + // zero rest of cluster + for (uint8_t i = 1; i < vol_->blocksPerCluster_; i++) { + if (!vol_->writeBlock(block + i, vol_->cacheBuffer_.data)) goto FAIL; + } + // Increase directory file size by cluster size + fileSize_ += 512UL << vol_->clusterSizeShift_; + return true; + FAIL: + return false; +} +//------------------------------------------------------------------------------ +// cache a file's directory entry +// return pointer to cached entry or null for failure +dir_t* SdBaseFile::cacheDirEntry(uint8_t action) { + if (!vol_->cacheRawBlock(dirBlock_, action)) goto FAIL; + return vol_->cache()->dir + dirIndex_; + FAIL: + return 0; +} +//------------------------------------------------------------------------------ +/** Close a file and force cached data and directory information + * to be written to the storage device. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include no file is open or an I/O error. + */ +bool SdBaseFile::close() { + bool rtn = sync(); + type_ = FAT_FILE_TYPE_CLOSED; + return rtn; +} +//------------------------------------------------------------------------------ +/** Check for contiguous file and return its raw block range. + * + * \param[out] bgnBlock the first block address for the file. + * \param[out] endBlock the last block address for the file. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include file is not contiguous, file has zero length + * or an I/O error occurred. + */ +bool SdBaseFile::contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock) { + // error if no blocks + if (firstCluster_ == 0) goto FAIL; + + for (uint32_t c = firstCluster_; ; c++) { + uint32_t next; + if (!vol_->fatGet(c, &next)) goto FAIL; + + // check for contiguous + if (next != (c + 1)) { + // error if not end of chain + if (!vol_->isEOC(next)) goto FAIL; + *bgnBlock = vol_->clusterStartBlock(firstCluster_); + *endBlock = vol_->clusterStartBlock(c) + + vol_->blocksPerCluster_ - 1; + return true; + } + } + + FAIL: + return false; +} +//------------------------------------------------------------------------------ +/** Create and open a new contiguous file of a specified size. + * + * \note This function only supports short DOS 8.3 names. + * See open() for more information. + * + * \param[in] dirFile The directory where the file will be created. + * \param[in] path A path with a valid DOS 8.3 file name. + * \param[in] size The desired file size. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include \a path contains + * 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) { + uint32_t count; + // don't allow zero length file + if (size == 0) goto FAIL; + if (!open(dirFile, path, O_CREAT | O_EXCL | O_RDWR)) goto FAIL; + + // calculate number of clusters needed + count = ((size - 1) >> (vol_->clusterSizeShift_ + 9)) + 1; + + // allocate clusters + if (!vol_->allocContiguous(count, &firstCluster_)) { + remove(); + goto FAIL; + } + fileSize_ = size; + + // insure sync() will update dir entry + flags_ |= F_FILE_DIR_DIRTY; + + return sync(); + FAIL: + return false; +} +//------------------------------------------------------------------------------ +/** Return a file's directory entry. + * + * \param[out] dir Location for return of the file's directory entry. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool SdBaseFile::dirEntry(dir_t* dir) { + dir_t* p; + // make sure fields on SD are correct + if (!sync()) goto FAIL; + + // read entry + p = cacheDirEntry(SdVolume::CACHE_FOR_READ); + if (!p) goto FAIL; + + // copy to caller's struct + memcpy(dir, p, sizeof(dir_t)); + return true; + FAIL: + return false; +} +//------------------------------------------------------------------------------ +/** Format the name field of \a dir into the 13 byte array + * \a name in standard 8.3 short name format. + * + * \param[in] dir The directory structure containing the name. + * \param[out] name A 13 byte char array for the formatted name. + */ +void SdBaseFile::dirName(const dir_t& dir, char* name) { + uint8_t j = 0; + for (uint8_t i = 0; i < 11; i++) { + if (dir.name[i] == ' ')continue; + if (i == 8) name[j++] = '.'; + name[j++] = dir.name[i]; + } + name[j] = 0; +} +//------------------------------------------------------------------------------ +/** Test for the existence of a file in a directory + * + * \param[in] name Name of the file to be tested for. + * + * The calling instance must be an open directory file. + * + * dirFile.exists("TOFIND.TXT") searches for "TOFIND.TXT" in the directory + * dirFile. + * + * \return true if the file exists else false. + */ +bool SdBaseFile::exists(const char* name) { + SdBaseFile file; + return file.open(this, name, O_READ); +} +//------------------------------------------------------------------------------ +/** + * Get a string from a file. + * + * fgets() reads bytes from a file into the array pointed to by \a str, until + * \a num - 1 bytes are read, or a delimiter is read and transferred to \a str, + * or end-of-file is encountered. The string is then terminated + * with a null byte. + * + * fgets() deletes CR, '\\r', from the string. This insures only a '\\n' + * terminates the string for Windows text files which use CRLF for newline. + * + * \param[out] str Pointer to the array where the string is stored. + * \param[in] num Maximum number of characters to be read + * (including the final null byte). Usually the length + * of the array \a str is used. + * \param[in] delim Optional set of delimiters. The default is "\n". + * + * \return For success fgets() returns the length of the string in \a str. + * If no data is read, fgets() returns zero for EOF or -1 if an error occurred. + **/ +int16_t SdBaseFile::fgets(char* str, int16_t num, char* delim) { + char ch; + int16_t n = 0; + int16_t r = -1; + while ((n + 1) < num && (r = read(&ch, 1)) == 1) { + // delete CR + if (ch == '\r') continue; + str[n++] = ch; + if (!delim) { + if (ch == '\n') break; + } + else { + if (strchr(delim, ch)) break; + } + } + if (r < 0) { + // read error + return -1; + } + str[n] = '\0'; + return n; +} +//------------------------------------------------------------------------------ +/** Get a file's name + * + * \param[out] name An array of 13 characters for the file's name. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool SdBaseFile::getFilename(char* name) { + if (!isOpen()) return false; + + if (isRoot()) { + name[0] = '/'; + name[1] = '\0'; + return true; + } + // cache entry + dir_t* p = cacheDirEntry(SdVolume::CACHE_FOR_READ); + if (!p) return false; + + // format name + dirName(*p, name); + return true; +} +//------------------------------------------------------------------------------ +void SdBaseFile::getpos(filepos_t* pos) { + pos->position = curPosition_; + pos->cluster = curCluster_; +} + +//------------------------------------------------------------------------------ +/** List directory contents. + * + * \param[in] pr Print stream for list. + * + * \param[in] flags The inclusive OR of + * + * LS_DATE - %Print file modification date + * + * LS_SIZE - %Print file size. + * + * LS_R - Recursive list of subdirectories. + * + * \param[in] indent Amount of space before file name. Used for recursive + * list to indicate subdirectory level. + */ +void SdBaseFile::ls(uint8_t flags, uint8_t indent) { + rewind(); + int8_t status; + while ((status = lsPrintNext(flags, indent))) { + if (status > 1 && (flags & LS_R)) { + uint16_t index = curPosition() / 32 - 1; + SdBaseFile s; + if (s.open(this, index, O_READ)) s.ls(flags, indent + 2); + seekSet(32 * (index + 1)); + } + } +} +//------------------------------------------------------------------------------ +// saves 32 bytes on stack for ls recursion +// return 0 - EOF, 1 - normal file, or 2 - directory +int8_t SdBaseFile::lsPrintNext(uint8_t flags, uint8_t indent) { + dir_t dir; + uint8_t w = 0; + + while (1) { + if (read(&dir, sizeof(dir)) != sizeof(dir)) return 0; + if (dir.name[0] == DIR_NAME_FREE) return 0; + + // skip deleted entry and entries for . and .. + if (dir.name[0] != DIR_NAME_DELETED && dir.name[0] != '.' + && DIR_IS_FILE_OR_SUBDIR(&dir)) break; + } + // indent for dir level + for (uint8_t i = 0; i < indent; i++) MYSERIAL.write(' '); + + // print name + for (uint8_t i = 0; i < 11; i++) { + if (dir.name[i] == ' ')continue; + if (i == 8) { + MYSERIAL.write('.'); + w++; + } + MYSERIAL.write(dir.name[i]); + w++; + } + if (DIR_IS_SUBDIR(&dir)) { + MYSERIAL.write('/'); + w++; + } + if (flags & (LS_DATE | LS_SIZE)) { + while (w++ < 14) MYSERIAL.write(' '); + } + // print modify date/time if requested + if (flags & LS_DATE) { + MYSERIAL.write(' '); + printFatDate(dir.lastWriteDate); + MYSERIAL.write(' '); + printFatTime(dir.lastWriteTime); + } + // print size if requested + if (!DIR_IS_SUBDIR(&dir) && (flags & LS_SIZE)) { + MYSERIAL.write(' '); + MYSERIAL.print(dir.fileSize); + } + MYSERIAL.println(); + return DIR_IS_FILE(&dir) ? 1 : 2; +} +//------------------------------------------------------------------------------ +// format directory name field from a 8.3 name string +bool SdBaseFile::make83Name(const char* str, uint8_t* name, const char** ptr) { + uint8_t c; + uint8_t n = 7; // max index for part before dot + uint8_t i = 0; + // blank fill name and extension + while (i < 11) name[i++] = ' '; + i = 0; + while (*str != '\0' && *str != '/') { + c = *str++; + if (c == '.') { + if (n == 10) goto FAIL; // only one dot allowed + n = 10; // max index for full 8.3 name + i = 8; // place for extension + } + else { + // illegal FAT characters + PGM_P p = PSTR("|<>^+=?/[];,*\"\\"); + uint8_t b; + while ((b = pgm_read_byte(p++))) if (b == c) goto FAIL; + // check size and only allow ASCII printable characters + if (i > n || c < 0x21 || c == 0x7F) goto FAIL; + // only upper case allowed in 8.3 names - convert lower to upper + name[i++] = (c < 'a' || c > 'z') ? (c) : (c + ('A' - 'a')); + } + } + *ptr = str; + // must have a file name, extension is optional + return name[0] != ' '; + FAIL: + return false; +} +//------------------------------------------------------------------------------ +/** Make a new directory. + * + * \param[in] parent An open SdFat instance for the directory that will contain + * the new directory. + * + * \param[in] path A path with a valid 8.3 DOS name for the new directory. + * + * \param[in] pFlag Create missing parent directories if true. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include this file is already open, \a parent is not a + * directory, \a path is invalid or already exists in \a parent. + */ +bool SdBaseFile::mkdir(SdBaseFile* parent, const char* path, bool pFlag) { + uint8_t dname[11]; + SdBaseFile dir1, dir2; + SdBaseFile* sub = &dir1; + SdBaseFile* start = parent; + + if (!parent || isOpen()) goto FAIL; + + if (*path == '/') { + while (*path == '/') path++; + if (!parent->isRoot()) { + if (!dir2.openRoot(parent->vol_)) goto FAIL; + parent = &dir2; + } + } + while (1) { + if (!make83Name(path, dname, &path)) goto FAIL; + while (*path == '/') path++; + if (!*path) break; + if (!sub->open(parent, dname, O_READ)) { + if (!pFlag || !sub->mkdir(parent, dname)) { + goto FAIL; + } + } + if (parent != start) parent->close(); + parent = sub; + sub = parent != &dir1 ? &dir1 : &dir2; + } + return mkdir(parent, dname); + FAIL: + return false; +} +//------------------------------------------------------------------------------ +bool SdBaseFile::mkdir(SdBaseFile* parent, const uint8_t dname[11]) { + uint32_t block; + dir_t d; + dir_t* p; + + if (!parent->isDir()) goto FAIL; + + // create a normal file + if (!open(parent, dname, O_CREAT | O_EXCL | O_RDWR)) goto FAIL; + + // convert file to directory + flags_ = O_READ; + type_ = FAT_FILE_TYPE_SUBDIR; + + // allocate and zero first cluster + if (!addDirCluster())goto FAIL; + + // force entry to SD + if (!sync()) goto FAIL; + + // cache entry - should already be in cache due to sync() call + p = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); + if (!p) goto FAIL; + + // change directory entry attribute + p->attributes = DIR_ATT_DIRECTORY; + + // make entry for '.' + memcpy(&d, p, sizeof(d)); + d.name[0] = '.'; + for (uint8_t i = 1; i < 11; i++) d.name[i] = ' '; + + // cache block for '.' and '..' + block = vol_->clusterStartBlock(firstCluster_); + if (!vol_->cacheRawBlock(block, SdVolume::CACHE_FOR_WRITE)) goto FAIL; + + // copy '.' to block + memcpy(&vol_->cache()->dir[0], &d, sizeof(d)); + + // make entry for '..' + d.name[1] = '.'; + if (parent->isRoot()) { + d.firstClusterLow = 0; + d.firstClusterHigh = 0; + } + else { + d.firstClusterLow = parent->firstCluster_ & 0xFFFF; + d.firstClusterHigh = parent->firstCluster_ >> 16; + } + // copy '..' to block + memcpy(&vol_->cache()->dir[1], &d, sizeof(d)); + + // write first block + return vol_->cacheFlush(); + FAIL: + return false; +} +//------------------------------------------------------------------------------ +/** Open a file in the current working directory. + * + * \param[in] path A path with a valid 8.3 DOS name for a file to be opened. + * + * \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive + * OR of open flags. see SdBaseFile::open(SdBaseFile*, const char*, uint8_t). + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool SdBaseFile::open(const char* path, uint8_t oflag) { + return open(cwd_, path, oflag); +} +//------------------------------------------------------------------------------ +/** Open a file or directory by name. + * + * \param[in] dirFile An open SdFat instance for the directory containing the + * file to be opened. + * + * \param[in] path A path with a valid 8.3 DOS name for a file to be opened. + * + * \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive + * OR of flags from the following list + * + * O_READ - Open for reading. + * + * O_RDONLY - Same as O_READ. + * + * O_WRITE - Open for writing. + * + * O_WRONLY - Same as O_WRITE. + * + * O_RDWR - Open for reading and writing. + * + * O_APPEND - If set, the file offset shall be set to the end of the + * file prior to each write. + * + * O_AT_END - Set the initial position at the end of the file. + * + * O_CREAT - If the file exists, this flag has no effect except as noted + * under O_EXCL below. Otherwise, the file shall be created + * + * O_EXCL - If O_CREAT and O_EXCL are set, open() shall fail if the file exists. + * + * O_SYNC - Call sync() after each write. This flag should not be used with + * write(uint8_t), write_P(PGM_P), writeln_P(PGM_P), or the Arduino Print class. + * These functions do character at a time writes so sync() will be called + * after each byte. + * + * O_TRUNC - If the file exists and is a regular file, and the file is + * successfully opened and is not read only, its length shall be truncated to 0. + * + * WARNING: A given file must not be opened by more than one SdBaseFile object + * of file corruption may occur. + * + * \note Directory files must be opened read only. Write and truncation is + * not allowed for directory files. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include this file is already open, \a dirFile is not + * a directory, \a path is invalid, the file does not exist + * or can't be opened in the access mode specified by oflag. + */ +bool SdBaseFile::open(SdBaseFile* dirFile, const char* path, uint8_t oflag) { + uint8_t dname[11]; + SdBaseFile dir1, dir2; + SdBaseFile* parent = dirFile; + SdBaseFile* sub = &dir1; + + if (!dirFile) goto FAIL; + + // error if already open + if (isOpen()) goto FAIL; + + if (*path == '/') { + while (*path == '/') path++; + if (!dirFile->isRoot()) { + if (!dir2.openRoot(dirFile->vol_)) goto FAIL; + parent = &dir2; + } + } + while (1) { + if (!make83Name(path, dname, &path)) goto FAIL; + while (*path == '/') path++; + if (!*path) break; + if (!sub->open(parent, dname, O_READ)) goto FAIL; + if (parent != dirFile) parent->close(); + parent = sub; + sub = parent != &dir1 ? &dir1 : &dir2; + } + return open(parent, dname, oflag); + FAIL: + return false; +} +//------------------------------------------------------------------------------ +// open with filename in dname +bool SdBaseFile::open(SdBaseFile* dirFile, + const uint8_t dname[11], uint8_t oflag) { + bool emptyFound = false; + bool fileFound = false; + uint8_t index; + dir_t* p; + + vol_ = dirFile->vol_; + + dirFile->rewind(); + // search for file + + while (dirFile->curPosition_ < dirFile->fileSize_) { + index = 0XF & (dirFile->curPosition_ >> 5); + p = dirFile->readDirCache(); + if (!p) goto FAIL; + + if (p->name[0] == DIR_NAME_FREE || p->name[0] == DIR_NAME_DELETED) { + // remember first empty slot + if (!emptyFound) { + dirBlock_ = dirFile->vol_->cacheBlockNumber(); + dirIndex_ = index; + emptyFound = true; + } + // done if no entries follow + if (p->name[0] == DIR_NAME_FREE) break; + } + else if (!memcmp(dname, p->name, 11)) { + fileFound = true; + break; + } + } + if (fileFound) { + // don't open existing file if O_EXCL + if (oflag & O_EXCL) goto FAIL; + } + else { + // don't create unless O_CREAT and O_WRITE + if (!(oflag & O_CREAT) || !(oflag & O_WRITE)) goto FAIL; + if (emptyFound) { + index = dirIndex_; + p = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); + if (!p) goto FAIL; + } + else { + if (dirFile->type_ == FAT_FILE_TYPE_ROOT_FIXED) goto FAIL; + + // add and zero cluster for dirFile - first cluster is in cache for write + if (!dirFile->addDirCluster()) goto FAIL; + + // use first entry in cluster + p = dirFile->vol_->cache()->dir; + index = 0; + } + // initialize as empty file + memset(p, 0, sizeof(*p)); + memcpy(p->name, dname, 11); + + // set timestamps + if (dateTime_) { + // call user date/time function + dateTime_(&p->creationDate, &p->creationTime); + } + else { + // use default date/time + p->creationDate = FAT_DEFAULT_DATE; + p->creationTime = FAT_DEFAULT_TIME; + } + p->lastAccessDate = p->creationDate; + p->lastWriteDate = p->creationDate; + p->lastWriteTime = p->creationTime; + + // write entry to SD + if (!dirFile->vol_->cacheFlush()) goto FAIL; + } + // open entry in cache + return openCachedEntry(index, oflag); + FAIL: + return false; +} +//------------------------------------------------------------------------------ +/** Open a file by index. + * + * \param[in] dirFile An open SdFat instance for the directory. + * + * \param[in] index The \a index of the directory entry for the file to be + * opened. The value for \a index is (directory file position)/32. + * + * \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive + * OR of flags O_READ, O_WRITE, O_TRUNC, and O_SYNC. + * + * See open() by path for definition of flags. + * \return true for success or false for failure. + */ +bool SdBaseFile::open(SdBaseFile* dirFile, uint16_t index, uint8_t oflag) { + dir_t* p; + + vol_ = dirFile->vol_; + + // error if already open + if (isOpen() || !dirFile) goto FAIL; + + // don't open existing file if O_EXCL - user call error + if (oflag & O_EXCL) goto FAIL; + + // seek to location of entry + if (!dirFile->seekSet(32 * index)) goto FAIL; + + // read entry into cache + p = dirFile->readDirCache(); + if (!p) goto FAIL; + + // error if empty slot or '.' or '..' + if (p->name[0] == DIR_NAME_FREE || + p->name[0] == DIR_NAME_DELETED || p->name[0] == '.') { + goto FAIL; + } + // open cached entry + return openCachedEntry(index & 0XF, oflag); + FAIL: + return false; +} +//------------------------------------------------------------------------------ +// open a cached directory entry. Assumes vol_ is initialized +bool SdBaseFile::openCachedEntry(uint8_t dirIndex, uint8_t oflag) { + // location of entry in cache + dir_t* 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)) { + if (oflag & (O_WRITE | O_TRUNC)) goto FAIL; + } + // remember location of directory entry on SD + dirBlock_ = vol_->cacheBlockNumber(); + dirIndex_ = dirIndex; + + // copy first cluster number for directory fields + firstCluster_ = (uint32_t)p->firstClusterHigh << 16; + firstCluster_ |= p->firstClusterLow; + + // make sure it is a normal file or subdirectory + if (DIR_IS_FILE(p)) { + fileSize_ = p->fileSize; + type_ = FAT_FILE_TYPE_NORMAL; + } + else if (DIR_IS_SUBDIR(p)) { + if (!vol_->chainSize(firstCluster_, &fileSize_)) goto FAIL; + type_ = FAT_FILE_TYPE_SUBDIR; + } + else { + goto FAIL; + } + // save open flags for read/write + flags_ = oflag & F_OFLAG; + + // set to start of file + curCluster_ = 0; + curPosition_ = 0; + if ((oflag & O_TRUNC) && !truncate(0)) return false; + return oflag & O_AT_END ? seekEnd(0) : true; + FAIL: + type_ = FAT_FILE_TYPE_CLOSED; + return false; +} +//------------------------------------------------------------------------------ +/** Open the next file or subdirectory in a directory. + * + * \param[in] dirFile An open SdFat instance for the directory containing the + * file to be opened. + * + * \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive + * OR of flags O_READ, O_WRITE, O_TRUNC, and O_SYNC. + * + * See open() by path for definition of flags. + * \return true for success or false for failure. + */ +bool SdBaseFile::openNext(SdBaseFile* dirFile, uint8_t oflag) { + dir_t* p; + uint8_t index; + + if (!dirFile) goto FAIL; + + // error if already open + if (isOpen()) goto FAIL; + + vol_ = dirFile->vol_; + + while (1) { + index = 0XF & (dirFile->curPosition_ >> 5); + + // read entry into cache + p = dirFile->readDirCache(); + if (!p) goto FAIL; + + // done if last entry + if (p->name[0] == DIR_NAME_FREE) goto FAIL; + + // skip empty slot or '.' or '..' + if (p->name[0] == DIR_NAME_DELETED || p->name[0] == '.') { + continue; + } + // must be file or dir + if (DIR_IS_FILE_OR_SUBDIR(p)) { + return openCachedEntry(index, oflag); + } + } + FAIL: + return false; +} +//------------------------------------------------------------------------------ +/** Open a directory's parent directory. + * + * \param[in] dir Parent of this directory will be opened. Must not be root. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool SdBaseFile::openParent(SdBaseFile* dir) { + dir_t entry; + dir_t* p; + SdBaseFile file; + uint32_t c; + uint32_t cluster; + uint32_t lbn; + // error if already open or dir is root or dir is not a directory + if (isOpen() || !dir || dir->isRoot() || !dir->isDir()) goto FAIL; + vol_ = dir->vol_; + // position to '..' + if (!dir->seekSet(32)) goto FAIL; + // read '..' entry + if (dir->read(&entry, sizeof(entry)) != 32) goto FAIL; + // verify it is '..' + if (entry.name[0] != '.' || entry.name[1] != '.') goto FAIL; + // start cluster for '..' + cluster = entry.firstClusterLow; + cluster |= (uint32_t)entry.firstClusterHigh << 16; + if (cluster == 0) return openRoot(vol_); + // start block for '..' + lbn = vol_->clusterStartBlock(cluster); + // first block of parent dir + if (!vol_->cacheRawBlock(lbn, SdVolume::CACHE_FOR_READ)) { + goto FAIL; + } + p = &vol_->cacheBuffer_.dir[1]; + // verify name for '../..' + if (p->name[0] != '.' || p->name[1] != '.') goto FAIL; + // '..' is pointer to first cluster of parent. open '../..' to find parent + if (p->firstClusterHigh == 0 && p->firstClusterLow == 0) { + if (!file.openRoot(dir->volume())) goto FAIL; + } + else if (!file.openCachedEntry(1, O_READ)) { + goto FAIL; + } + // search for parent in '../..' + do { + if (file.readDir(&entry, NULL) != 32) goto FAIL; + c = entry.firstClusterLow; + c |= (uint32_t)entry.firstClusterHigh << 16; + } while (c != cluster); + // open parent + return open(&file, file.curPosition() / 32 - 1, O_READ); + FAIL: + return false; +} +//------------------------------------------------------------------------------ +/** Open a volume's root directory. + * + * \param[in] vol The FAT volume containing the root directory to be opened. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include the file is already open, the FAT volume has + * not been initialized or it a FAT12 volume. + */ +bool SdBaseFile::openRoot(SdVolume* vol) { + // error if file is already open + if (isOpen()) goto FAIL; + + if (vol->fatType() == 16 || (FAT12_SUPPORT && vol->fatType() == 12)) { + type_ = FAT_FILE_TYPE_ROOT_FIXED; + firstCluster_ = 0; + fileSize_ = 32 * vol->rootDirEntryCount(); + } + else if (vol->fatType() == 32) { + type_ = FAT_FILE_TYPE_ROOT32; + firstCluster_ = vol->rootDirStart(); + if (!vol->chainSize(firstCluster_, &fileSize_)) goto FAIL; + } + else { + // volume is not initialized, invalid, or FAT12 without support + return false; + } + vol_ = vol; + // read only + flags_ = O_READ; + + // set to start of file + curCluster_ = 0; + curPosition_ = 0; + + // root has no directory entry + dirBlock_ = 0; + dirIndex_ = 0; + return true; + FAIL: + return false; +} +//------------------------------------------------------------------------------ +/** Return the next available byte without consuming it. + * + * \return The byte if no error and not at eof else -1; + */ +int SdBaseFile::peek() { + filepos_t pos; + getpos(&pos); + int c = read(); + if (c >= 0) setpos(&pos); + return c; +} + +//------------------------------------------------------------------------------ +/** %Print the name field of a directory entry in 8.3 format. + * \param[in] pr Print stream for output. + * \param[in] dir The directory structure containing the name. + * \param[in] width Blank fill name if length is less than \a width. + * \param[in] printSlash Print '/' after directory names if true. + */ +void SdBaseFile::printDirName(const dir_t& dir, + uint8_t width, bool printSlash) { + uint8_t w = 0; + for (uint8_t i = 0; i < 11; i++) { + if (dir.name[i] == ' ')continue; + if (i == 8) { + MYSERIAL.write('.'); + w++; + } + MYSERIAL.write(dir.name[i]); + w++; + } + if (DIR_IS_SUBDIR(&dir) && printSlash) { + MYSERIAL.write('/'); + w++; + } + while (w < width) { + MYSERIAL.write(' '); + w++; + } +} +//------------------------------------------------------------------------------ +// print uint8_t with width 2 +static void print2u(uint8_t v) { + if (v < 10) MYSERIAL.write('0'); + MYSERIAL.print(v, DEC); +} +//------------------------------------------------------------------------------ +/** %Print a directory date field to Serial. + * + * Format is yyyy-mm-dd. + * + * \param[in] fatDate The date field from a directory entry. + */ + +//------------------------------------------------------------------------------ +/** %Print a directory date field. + * + * Format is yyyy-mm-dd. + * + * \param[in] pr Print stream for output. + * \param[in] fatDate The date field from a directory entry. + */ +void SdBaseFile::printFatDate(uint16_t fatDate) { + MYSERIAL.print(FAT_YEAR(fatDate)); + MYSERIAL.write('-'); + print2u(FAT_MONTH(fatDate)); + MYSERIAL.write('-'); + print2u(FAT_DAY(fatDate)); +} + +//------------------------------------------------------------------------------ +/** %Print a directory time field. + * + * Format is hh:mm:ss. + * + * \param[in] pr Print stream for output. + * \param[in] fatTime The time field from a directory entry. + */ +void SdBaseFile::printFatTime(uint16_t fatTime) { + print2u(FAT_HOUR(fatTime)); + MYSERIAL.write(':'); + print2u(FAT_MINUTE(fatTime)); + MYSERIAL.write(':'); + print2u(FAT_SECOND(fatTime)); +} +//------------------------------------------------------------------------------ +/** Print a file's name to Serial + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool SdBaseFile::printName() { + char name[FILENAME_LENGTH]; + if (!getFilename(name)) return false; + MYSERIAL.print(name); + return true; +} +//------------------------------------------------------------------------------ +/** Read the next byte from a file. + * + * \return For success read returns the next byte in the file as an int. + * If an error occurs or end of file is reached -1 is returned. + */ +int16_t SdBaseFile::read() { + uint8_t b; + return read(&b, 1) == 1 ? b : -1; +} +//------------------------------------------------------------------------------ +/** Read data from a file starting at the current position. + * + * \param[out] buf Pointer to the location that will receive the data. + * + * \param[in] nbyte Maximum number of bytes to read. + * + * \return For success read() returns the number of bytes read. + * A value less than \a nbyte, including zero, will be returned + * if end of file is reached. + * If an error occurs, read() returns -1. Possible errors include + * read() called before a file has been opened, corrupt file system + * or an I/O error occurred. + */ +int16_t SdBaseFile::read(void* buf, uint16_t nbyte) { + uint8_t* dst = reinterpret_cast(buf); + uint16_t offset; + uint16_t toRead; + uint32_t block; // raw device block number + + // error if not open or write only + if (!isOpen() || !(flags_ & O_READ)) goto FAIL; + + // max bytes left in file + NOMORE(nbyte, fileSize_ - curPosition_); + + // amount left to read + toRead = nbyte; + while (toRead > 0) { + offset = curPosition_ & 0x1FF; // offset in block + if (type_ == FAT_FILE_TYPE_ROOT_FIXED) { + block = vol_->rootDirStart() + (curPosition_ >> 9); + } + else { + uint8_t blockOfCluster = vol_->blockOfCluster(curPosition_); + if (offset == 0 && blockOfCluster == 0) { + // start of new cluster + if (curPosition_ == 0) { + // use first cluster in file + curCluster_ = firstCluster_; + } + else { + // get next cluster from FAT + if (!vol_->fatGet(curCluster_, &curCluster_)) goto FAIL; + } + } + block = vol_->clusterStartBlock(curCluster_) + blockOfCluster; + } + uint16_t n = toRead; + + // amount to be read from current block + NOMORE(n, 512 - offset); + + // no buffering needed if n == 512 + if (n == 512 && block != vol_->cacheBlockNumber()) { + if (!vol_->readBlock(block, dst)) goto FAIL; + } + else { + // read block to cache and copy data to caller + if (!vol_->cacheRawBlock(block, SdVolume::CACHE_FOR_READ)) goto FAIL; + uint8_t* src = vol_->cache()->data + offset; + memcpy(dst, src, n); + } + dst += n; + curPosition_ += n; + toRead -= n; + } + return nbyte; + FAIL: + return -1; +} + +/** + * Read the next entry in a directory. + * + * \param[out] dir The dir_t struct that will receive the data. + * + * \return For success readDir() returns the number of bytes read. + * A value of zero will be returned if end of file is reached. + * If an error occurs, readDir() returns -1. Possible errors include + * readDir() called before a directory has been opened, this is not + * a directory file or an I/O error occurred. + */ +int8_t SdBaseFile::readDir(dir_t* dir, char* longFilename) { + int16_t n; + // if not a directory file or miss-positioned return an error + if (!isDir() || (0x1F & curPosition_)) return -1; + + //If we have a longFilename buffer, mark it as invalid. If we find a long filename it will be filled automaticly. + if (longFilename != NULL) longFilename[0] = '\0'; + + while (1) { + + n = read(dir, sizeof(dir_t)); + if (n != sizeof(dir_t)) return n == 0 ? 0 : -1; + + // last entry if DIR_NAME_FREE + if (dir->name[0] == DIR_NAME_FREE) return 0; + + // skip empty entries and entry for . and .. + if (dir->name[0] == DIR_NAME_DELETED || dir->name[0] == '.') continue; + + // Fill the long filename if we have a long filename entry. + // Long filename entries are stored before the short filename. + if (longFilename != NULL && DIR_IS_LONG_NAME(dir)) { + vfat_t* VFAT = (vfat_t*)dir; + // Sanity-check the VFAT entry. The first cluster is always set to zero. And the sequence number should be higher than 0 + if (VFAT->firstClusterLow == 0 && (VFAT->sequenceNumber & 0x1F) > 0 && (VFAT->sequenceNumber & 0x1F) <= MAX_VFAT_ENTRIES) { + // TODO: Store the filename checksum to verify if a none-long filename aware system modified the file table. + n = ((VFAT->sequenceNumber & 0x1F) - 1) * (FILENAME_LENGTH); + for (uint8_t i = 0; i < FILENAME_LENGTH; i++) + 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'; + } + } + // Return if normal file or subdirectory + if (DIR_IS_FILE_OR_SUBDIR(dir)) return n; + } +} + +//------------------------------------------------------------------------------ +// Read next directory entry into the cache +// Assumes file is correctly positioned +dir_t* SdBaseFile::readDirCache() { + uint8_t i; + // error if not directory + if (!isDir()) goto FAIL; + + // index of entry in cache + i = (curPosition_ >> 5) & 0XF; + + // use read to locate and cache block + if (read() < 0) goto FAIL; + + // advance to next entry + curPosition_ += 31; + + // return pointer to entry + return vol_->cache()->dir + i; + FAIL: + return 0; +} +//------------------------------------------------------------------------------ +/** Remove a file. + * + * The directory entry and all data for the file are deleted. + * + * \note This function should not be used to delete the 8.3 version of a + * file that has a long name. For example if a file has the long name + * "New Text Document.txt" you should not delete the 8.3 name "NEWTEX~1.TXT". + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include the file read-only, is a directory, + * or an I/O error occurred. + */ +bool SdBaseFile::remove() { + dir_t* d; + // free any clusters - will fail if read-only or directory + if (!truncate(0)) goto FAIL; + + // cache directory entry + d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); + if (!d) goto FAIL; + + // mark entry deleted + d->name[0] = DIR_NAME_DELETED; + + // set this file closed + type_ = FAT_FILE_TYPE_CLOSED; + + // write entry to SD + return vol_->cacheFlush(); + return true; + FAIL: + return false; +} +//------------------------------------------------------------------------------ +/** Remove a file. + * + * The directory entry and all data for the file are deleted. + * + * \param[in] dirFile The directory that contains the file. + * \param[in] path Path for the file to be removed. + * + * \note This function should not be used to delete the 8.3 version of a + * file that has a long name. For example if a file has the long name + * "New Text Document.txt" you should not delete the 8.3 name "NEWTEX~1.TXT". + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include the file is a directory, is read only, + * \a dirFile is not a directory, \a path is not found + * or an I/O error occurred. + */ +bool SdBaseFile::remove(SdBaseFile* dirFile, const char* path) { + SdBaseFile file; + if (!file.open(dirFile, path, O_WRITE)) goto FAIL; + return file.remove(); + FAIL: + // can't set iostate - static function + return false; +} +//------------------------------------------------------------------------------ +/** Rename a file or subdirectory. + * + * \param[in] dirFile Directory for the new path. + * \param[in] newPath New path name for the file/directory. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include \a dirFile is not open or is not a directory + * file, newPath is invalid or already exists, or an I/O error occurs. + */ +bool SdBaseFile::rename(SdBaseFile* dirFile, const char* newPath) { + dir_t entry; + uint32_t dirCluster = 0; + SdBaseFile file; + dir_t* d; + + // must be an open file or subdirectory + if (!(isFile() || isSubDir())) goto FAIL; + + // can't move file + if (vol_ != dirFile->vol_) goto FAIL; + + // sync() and cache directory entry + sync(); + d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); + if (!d) goto FAIL; + + // save directory entry + memcpy(&entry, d, sizeof(entry)); + + // mark entry deleted + d->name[0] = DIR_NAME_DELETED; + + // make directory entry for new path + if (isFile()) { + if (!file.open(dirFile, newPath, O_CREAT | O_EXCL | O_WRITE)) { + goto restore; + } + } + else { + // don't create missing path prefix components + if (!file.mkdir(dirFile, newPath, false)) { + goto restore; + } + // save cluster containing new dot dot + dirCluster = file.firstCluster_; + } + // change to new directory entry + dirBlock_ = file.dirBlock_; + dirIndex_ = file.dirIndex_; + + // mark closed to avoid possible destructor close call + file.type_ = FAT_FILE_TYPE_CLOSED; + + // cache new directory entry + d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); + if (!d) goto FAIL; + + // copy all but name field to new directory entry + memcpy(&d->attributes, &entry.attributes, sizeof(entry) - sizeof(d->name)); + + // update dot dot if directory + if (dirCluster) { + // get new dot dot + uint32_t block = vol_->clusterStartBlock(dirCluster); + if (!vol_->cacheRawBlock(block, SdVolume::CACHE_FOR_READ)) goto FAIL; + memcpy(&entry, &vol_->cache()->dir[1], sizeof(entry)); + + // free unused cluster + if (!vol_->freeChain(dirCluster)) goto FAIL; + + // store new dot dot + block = vol_->clusterStartBlock(firstCluster_); + if (!vol_->cacheRawBlock(block, SdVolume::CACHE_FOR_WRITE)) goto FAIL; + memcpy(&vol_->cache()->dir[1], &entry, sizeof(entry)); + } + return vol_->cacheFlush(); + +restore: + d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); + if (!d) goto FAIL; + // restore entry + d->name[0] = entry.name[0]; + vol_->cacheFlush(); + + FAIL: + return false; +} +//------------------------------------------------------------------------------ +/** Remove a directory file. + * + * The directory file will be removed only if it is empty and is not the + * root directory. rmdir() follows DOS and Windows and ignores the + * read-only attribute for the directory. + * + * \note This function should not be used to delete the 8.3 version of a + * directory that has a long name. For example if a directory has the + * long name "New folder" you should not delete the 8.3 name "NEWFOL~1". + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include the file is not a directory, is the root + * directory, is not empty, or an I/O error occurred. + */ +bool SdBaseFile::rmdir() { + // must be open subdirectory + if (!isSubDir()) goto FAIL; + + rewind(); + + // make sure directory is empty + while (curPosition_ < fileSize_) { + dir_t* p = readDirCache(); + if (!p) goto FAIL; + // done if past last used entry + if (p->name[0] == DIR_NAME_FREE) break; + // skip empty slot, '.' or '..' + if (p->name[0] == DIR_NAME_DELETED || p->name[0] == '.') continue; + // error not empty + if (DIR_IS_FILE_OR_SUBDIR(p)) goto FAIL; + } + // convert empty directory to normal file for remove + type_ = FAT_FILE_TYPE_NORMAL; + flags_ |= O_WRITE; + return remove(); + FAIL: + return false; +} +//------------------------------------------------------------------------------ +/** Recursively delete a directory and all contained files. + * + * This is like the Unix/Linux 'rm -rf *' if called with the root directory + * hence the name. + * + * Warning - This will remove all contents of the directory including + * subdirectories. The directory will then be removed if it is not root. + * The read-only attribute for files will be ignored. + * + * \note This function should not be used to delete the 8.3 version of + * a directory that has a long name. See remove() and rmdir(). + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool SdBaseFile::rmRfStar() { + uint16_t index; + SdBaseFile f; + rewind(); + while (curPosition_ < fileSize_) { + // remember position + index = curPosition_ / 32; + + dir_t* p = readDirCache(); + if (!p) goto FAIL; + + // done if past last entry + if (p->name[0] == DIR_NAME_FREE) break; + + // skip empty slot or '.' or '..' + if (p->name[0] == DIR_NAME_DELETED || p->name[0] == '.') continue; + + // skip if part of long file name or volume label in root + if (!DIR_IS_FILE_OR_SUBDIR(p)) continue; + + if (!f.open(this, index, O_READ)) goto FAIL; + if (f.isSubDir()) { + // recursively delete + if (!f.rmRfStar()) goto FAIL; + } + else { + // ignore read-only + f.flags_ |= O_WRITE; + if (!f.remove()) goto FAIL; + } + // position to next entry if required + if (curPosition_ != (32 * (index + 1))) { + if (!seekSet(32 * (index + 1))) goto FAIL; + } + } + // don't try to delete root + if (!isRoot()) { + if (!rmdir()) goto FAIL; + } + return true; + FAIL: + return false; +} +//------------------------------------------------------------------------------ +/** Create a file object and open it in the current working directory. + * + * \param[in] path A path with a valid 8.3 DOS name for a file to be opened. + * + * \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive + * OR of open flags. see SdBaseFile::open(SdBaseFile*, const char*, uint8_t). + */ +SdBaseFile::SdBaseFile(const char* path, uint8_t oflag) { + type_ = FAT_FILE_TYPE_CLOSED; + writeError = false; + open(path, oflag); +} +//------------------------------------------------------------------------------ +/** Sets a file's position. + * + * \param[in] pos The new position in bytes from the beginning of the file. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool SdBaseFile::seekSet(uint32_t pos) { + uint32_t nCur; + uint32_t nNew; + // error if file not open or seek past end of file + if (!isOpen() || pos > fileSize_) goto FAIL; + + if (type_ == FAT_FILE_TYPE_ROOT_FIXED) { + curPosition_ = pos; + goto done; + } + if (pos == 0) { + // set position to start of file + curCluster_ = 0; + curPosition_ = 0; + goto done; + } + // calculate cluster index for cur and new position + nCur = (curPosition_ - 1) >> (vol_->clusterSizeShift_ + 9); + nNew = (pos - 1) >> (vol_->clusterSizeShift_ + 9); + + if (nNew < nCur || curPosition_ == 0) { + // must follow chain from first cluster + curCluster_ = firstCluster_; + } + else { + // advance from curPosition + nNew -= nCur; + } + while (nNew--) { + if (!vol_->fatGet(curCluster_, &curCluster_)) goto FAIL; + } + curPosition_ = pos; + +done: + return true; + + FAIL: + return false; +} +//------------------------------------------------------------------------------ +void SdBaseFile::setpos(filepos_t* pos) { + curPosition_ = pos->position; + curCluster_ = pos->cluster; +} +//------------------------------------------------------------------------------ +/** The sync() call causes all modified data and directory fields + * to be written to the storage device. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include a call to sync() before a file has been + * opened or an I/O error. + */ +bool SdBaseFile::sync() { + // only allow open files and directories + if (!isOpen()) goto FAIL; + + if (flags_ & F_FILE_DIR_DIRTY) { + dir_t* d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); + // check for deleted by another open file object + if (!d || d->name[0] == DIR_NAME_DELETED) goto FAIL; + + // do not set filesize for dir files + if (!isDir()) d->fileSize = fileSize_; + + // update first cluster fields + d->firstClusterLow = firstCluster_ & 0xFFFF; + d->firstClusterHigh = firstCluster_ >> 16; + + // set modify time if user supplied a callback date/time function + if (dateTime_) { + dateTime_(&d->lastWriteDate, &d->lastWriteTime); + d->lastAccessDate = d->lastWriteDate; + } + // clear directory dirty + flags_ &= ~F_FILE_DIR_DIRTY; + } + return vol_->cacheFlush(); + + FAIL: + writeError = true; + return false; +} +//------------------------------------------------------------------------------ +/** Copy a file's timestamps + * + * \param[in] file File to copy timestamps from. + * + * \note + * Modify and access timestamps may be overwritten if a date time callback + * function has been set by dateTimeCallback(). + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool SdBaseFile::timestamp(SdBaseFile* file) { + dir_t* d; + dir_t dir; + + // get timestamps + if (!file->dirEntry(&dir)) goto FAIL; + + // update directory fields + if (!sync()) goto FAIL; + + d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); + if (!d) goto FAIL; + + // copy timestamps + d->lastAccessDate = dir.lastAccessDate; + d->creationDate = dir.creationDate; + d->creationTime = dir.creationTime; + d->creationTimeTenths = dir.creationTimeTenths; + d->lastWriteDate = dir.lastWriteDate; + d->lastWriteTime = dir.lastWriteTime; + + // write back entry + return vol_->cacheFlush(); + + FAIL: + return false; +} +//------------------------------------------------------------------------------ +/** Set a file's timestamps in its directory entry. + * + * \param[in] flags Values for \a flags are constructed by a bitwise-inclusive + * OR of flags from the following list + * + * T_ACCESS - Set the file's last access date. + * + * T_CREATE - Set the file's creation date and time. + * + * T_WRITE - Set the file's last write/modification date and time. + * + * \param[in] year Valid range 1980 - 2107 inclusive. + * + * \param[in] month Valid range 1 - 12 inclusive. + * + * \param[in] day Valid range 1 - 31 inclusive. + * + * \param[in] hour Valid range 0 - 23 inclusive. + * + * \param[in] minute Valid range 0 - 59 inclusive. + * + * \param[in] second Valid range 0 - 59 inclusive + * + * \note It is possible to set an invalid date since there is no check for + * the number of days in a month. + * + * \note + * Modify and access timestamps may be overwritten if a date time callback + * function has been set by dateTimeCallback(). + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool SdBaseFile::timestamp(uint8_t flags, uint16_t year, uint8_t month, + uint8_t day, uint8_t hour, uint8_t minute, uint8_t second) { + uint16_t dirDate; + uint16_t dirTime; + dir_t* d; + + if (!isOpen() + || year < 1980 + || year > 2107 + || month < 1 + || month > 12 + || day < 1 + || day > 31 + || hour > 23 + || minute > 59 + || second > 59) { + goto FAIL; + } + // update directory entry + if (!sync()) goto FAIL; + + d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); + if (!d) goto FAIL; + + dirDate = FAT_DATE(year, month, day); + dirTime = FAT_TIME(hour, minute, second); + if (flags & T_ACCESS) { + d->lastAccessDate = dirDate; + } + if (flags & T_CREATE) { + d->creationDate = dirDate; + d->creationTime = dirTime; + // seems to be units of 1/100 second not 1/10 as Microsoft states + d->creationTimeTenths = second & 1 ? 100 : 0; + } + if (flags & T_WRITE) { + d->lastWriteDate = dirDate; + d->lastWriteTime = dirTime; + } + return vol_->cacheFlush(); + FAIL: + return false; +} +//------------------------------------------------------------------------------ +/** Truncate a file to a specified length. The current file position + * will be maintained if it is less than or equal to \a length otherwise + * it will be set to end of file. + * + * \param[in] length The desired length for the file. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include file is read only, file is a directory, + * \a length is greater than the current file size or an I/O error occurs. + */ +bool SdBaseFile::truncate(uint32_t length) { + uint32_t newPos; + // error if not a normal file or read-only + if (!isFile() || !(flags_ & O_WRITE)) goto FAIL; + + // error if length is greater than current size + if (length > fileSize_) goto FAIL; + + // fileSize and length are zero - nothing to do + if (fileSize_ == 0) return true; + + // remember position for seek after truncation + newPos = curPosition_ > length ? length : curPosition_; + + // position to last cluster in truncated file + if (!seekSet(length)) goto FAIL; + + if (length == 0) { + // free all clusters + if (!vol_->freeChain(firstCluster_)) goto FAIL; + firstCluster_ = 0; + } + else { + uint32_t toFree; + if (!vol_->fatGet(curCluster_, &toFree)) goto FAIL; + + if (!vol_->isEOC(toFree)) { + // free extra clusters + if (!vol_->freeChain(toFree)) goto FAIL; + + // current cluster is end of chain + if (!vol_->fatPutEOC(curCluster_)) goto FAIL; + } + } + fileSize_ = length; + + // need to update directory entry + flags_ |= F_FILE_DIR_DIRTY; + + if (!sync()) goto FAIL; + + // set file to correct position + return seekSet(newPos); + + FAIL: + return false; +} +//------------------------------------------------------------------------------ +/** Write data to an open file. + * + * \note Data is moved to the cache but may not be written to the + * storage device until sync() is called. + * + * \param[in] buf Pointer to the location of the data to be written. + * + * \param[in] nbyte Number of bytes to write. + * + * \return For success write() returns the number of bytes written, always + * \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) { + // convert void* to uint8_t* - must be before goto statements + const uint8_t* src = reinterpret_cast(buf); + + // number of bytes left to write - must be before goto statements + uint16_t nToWrite = nbyte; + + // error if not a normal file or is read-only + if (!isFile() || !(flags_ & O_WRITE)) goto FAIL; + + // seek to end of file if append flag + if ((flags_ & O_APPEND) && curPosition_ != fileSize_) { + if (!seekEnd()) goto FAIL; + } + + while (nToWrite > 0) { + uint8_t blockOfCluster = vol_->blockOfCluster(curPosition_); + uint16_t blockOffset = curPosition_ & 0x1FF; + if (blockOfCluster == 0 && blockOffset == 0) { + // start of new cluster + if (curCluster_ == 0) { + if (firstCluster_ == 0) { + // allocate first cluster of file + if (!addCluster()) goto FAIL; + } + else { + curCluster_ = firstCluster_; + } + } + else { + uint32_t next; + if (!vol_->fatGet(curCluster_, &next)) goto FAIL; + if (vol_->isEOC(next)) { + // add cluster if at end of chain + if (!addCluster()) goto FAIL; + } + else { + curCluster_ = next; + } + } + } + // max space in block + uint16_t n = 512 - blockOffset; + + // lesser of space and amount to write + NOMORE(n, nToWrite); + + // block for data write + uint32_t block = vol_->clusterStartBlock(curCluster_) + blockOfCluster; + if (n == 512) { + // full block - don't need to use cache + if (vol_->cacheBlockNumber() == block) { + // invalidate cache if block is in cache + vol_->cacheSetBlockNumber(0xFFFFFFFF, false); + } + if (!vol_->writeBlock(block, src)) goto FAIL; + } + else { + if (blockOffset == 0 && curPosition_ >= fileSize_) { + // start of new block don't need to read into cache + if (!vol_->cacheFlush()) goto FAIL; + // set cache dirty and SD address of block + vol_->cacheSetBlockNumber(block, true); + } + else { + // rewrite part of block + if (!vol_->cacheRawBlock(block, SdVolume::CACHE_FOR_WRITE)) goto FAIL; + } + uint8_t* dst = vol_->cache()->data + blockOffset; + memcpy(dst, src, n); + } + curPosition_ += n; + src += n; + nToWrite -= n; + } + if (curPosition_ > fileSize_) { + // update fileSize and insure sync will update dir entry + fileSize_ = curPosition_; + flags_ |= F_FILE_DIR_DIRTY; + } + else if (dateTime_ && nbyte) { + // insure sync will update modified date and time + flags_ |= F_FILE_DIR_DIRTY; + } + + if (flags_ & O_SYNC) { + if (!sync()) goto FAIL; + } + return nbyte; + + FAIL: + // return for write error + writeError = true; + return -1; +} +//------------------------------------------------------------------------------ +// suppress cpplint warnings with NOLINT comment +#if ALLOW_DEPRECATED_FUNCTIONS && !defined(DOXYGEN) + void (*SdBaseFile::oldDateTime_)(uint16_t &date, uint16_t &time) = 0; // NOLINT +#endif // ALLOW_DEPRECATED_FUNCTIONS + + +#endif diff --git a/trunk/Arduino/Marlin_1.1.6/SdBaseFile.h b/trunk/Arduino/Marlin_1.1.6/SdBaseFile.h new file mode 100644 index 00000000..02daa7b7 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/SdBaseFile.h @@ -0,0 +1,492 @@ +/** + * 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 . + * + */ + +/** + * Arduino SdFat Library + * Copyright (C) 2009 by William Greiman + * + * This file is part of the Arduino Sd2Card Library + */ +#include "Marlin.h" +#if ENABLED(SDSUPPORT) + +#ifndef SdBaseFile_h +#define SdBaseFile_h +/** + * \file + * \brief SdBaseFile class + */ +#include "Marlin.h" +#include "SdFatConfig.h" +#include "SdVolume.h" +//------------------------------------------------------------------------------ +/** + * \struct filepos_t + * \brief internal type for istream + * do not use in user apps + */ +struct filepos_t { + /** stream position */ + uint32_t position; + /** cluster for position */ + uint32_t cluster; + filepos_t() : position(0), cluster(0) {} +}; + +// use the gnu style oflag in open() +/** open() oflag for reading */ +uint8_t const O_READ = 0x01; +/** open() oflag - same as O_IN */ +uint8_t const O_RDONLY = O_READ; +/** open() oflag for write */ +uint8_t const O_WRITE = 0x02; +/** open() oflag - same as O_WRITE */ +uint8_t const O_WRONLY = O_WRITE; +/** open() oflag for reading and writing */ +uint8_t const O_RDWR = (O_READ | O_WRITE); +/** open() oflag mask for access modes */ +uint8_t const O_ACCMODE = (O_READ | O_WRITE); +/** The file offset shall be set to the end of the file prior to each write. */ +uint8_t const O_APPEND = 0x04; +/** synchronous writes - call sync() after each write */ +uint8_t const O_SYNC = 0x08; +/** truncate the file to zero length */ +uint8_t const O_TRUNC = 0x10; +/** set the initial position at the end of the file */ +uint8_t const O_AT_END = 0x20; +/** create the file if nonexistent */ +uint8_t const O_CREAT = 0x40; +/** If O_CREAT and O_EXCL are set, open() shall fail if the file exists */ +uint8_t const O_EXCL = 0x80; + +// SdBaseFile class static and const definitions +// flags for ls() +/** ls() flag to print modify date */ +uint8_t const LS_DATE = 1; +/** ls() flag to print file size */ +uint8_t const LS_SIZE = 2; +/** ls() flag for recursive list of subdirectories */ +uint8_t const LS_R = 4; + + +// flags for timestamp +/** set the file's last access date */ +uint8_t const T_ACCESS = 1; +/** set the file's creation date and time */ +uint8_t const T_CREATE = 2; +/** Set the file's write date and time */ +uint8_t const T_WRITE = 4; +// values for type_ +/** This file has not been opened. */ +uint8_t const FAT_FILE_TYPE_CLOSED = 0; +/** A normal file */ +uint8_t const FAT_FILE_TYPE_NORMAL = 1; +/** A FAT12 or FAT16 root directory */ +uint8_t const FAT_FILE_TYPE_ROOT_FIXED = 2; +/** A FAT32 root directory */ +uint8_t const FAT_FILE_TYPE_ROOT32 = 3; +/** A subdirectory file*/ +uint8_t const FAT_FILE_TYPE_SUBDIR = 4; +/** Test value for directory type */ +uint8_t const FAT_FILE_TYPE_MIN_DIR = FAT_FILE_TYPE_ROOT_FIXED; + +/** date field for FAT directory entry + * \param[in] year [1980,2107] + * \param[in] month [1,12] + * \param[in] day [1,31] + * + * \return Packed date for dir_t entry. + */ +static inline uint16_t FAT_DATE(uint16_t year, uint8_t month, uint8_t day) { + return (year - 1980) << 9 | month << 5 | day; +} +/** year part of FAT directory date field + * \param[in] fatDate Date in packed dir format. + * + * \return Extracted year [1980,2107] + */ +static inline uint16_t FAT_YEAR(uint16_t fatDate) { + return 1980 + (fatDate >> 9); +} +/** month part of FAT directory date field + * \param[in] fatDate Date in packed dir format. + * + * \return Extracted month [1,12] + */ +static inline uint8_t FAT_MONTH(uint16_t fatDate) { + return (fatDate >> 5) & 0XF; +} +/** day part of FAT directory date field + * \param[in] fatDate Date in packed dir format. + * + * \return Extracted day [1,31] + */ +static inline uint8_t FAT_DAY(uint16_t fatDate) { + return fatDate & 0x1F; +} +/** time field for FAT directory entry + * \param[in] hour [0,23] + * \param[in] minute [0,59] + * \param[in] second [0,59] + * + * \return Packed time for dir_t entry. + */ +static inline uint16_t FAT_TIME(uint8_t hour, uint8_t minute, uint8_t second) { + return hour << 11 | minute << 5 | second >> 1; +} +/** hour part of FAT directory time field + * \param[in] fatTime Time in packed dir format. + * + * \return Extracted hour [0,23] + */ +static inline uint8_t FAT_HOUR(uint16_t fatTime) { + return fatTime >> 11; +} +/** minute part of FAT directory time field + * \param[in] fatTime Time in packed dir format. + * + * \return Extracted minute [0,59] + */ +static inline uint8_t FAT_MINUTE(uint16_t fatTime) { + return (fatTime >> 5) & 0x3F; +} +/** second part of FAT directory time field + * Note second/2 is stored in packed time. + * + * \param[in] fatTime Time in packed dir format. + * + * \return Extracted second [0,58] + */ +static inline uint8_t FAT_SECOND(uint16_t fatTime) { + return 2 * (fatTime & 0x1F); +} +/** Default date for file timestamps is 1 Jan 2000 */ +uint16_t const FAT_DEFAULT_DATE = ((2000 - 1980) << 9) | (1 << 5) | 1; +/** Default time for file timestamp is 1 am */ +uint16_t const FAT_DEFAULT_TIME = (1 << 11); +//------------------------------------------------------------------------------ +/** + * \class SdBaseFile + * \brief Base class for SdFile with Print and C++ streams. + */ +class SdBaseFile { + public: + /** Create an instance. */ + SdBaseFile() : writeError(false), type_(FAT_FILE_TYPE_CLOSED) {} + SdBaseFile(const char* path, uint8_t oflag); + ~SdBaseFile() {if (isOpen()) close();} + /** + * writeError is set to true if an error occurs during a write(). + * Set writeError to false before calling print() and/or write() and check + * for true after calls to print() and/or write(). + */ + bool writeError; + //---------------------------------------------------------------------------- + // helpers for stream classes + /** get position for streams + * \param[out] pos struct to receive position + */ + void getpos(filepos_t* pos); + /** set position for streams + * \param[out] pos struct with value for new position + */ + void setpos(filepos_t* pos); + //---------------------------------------------------------------------------- + bool close(); + bool contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock); + bool createContiguous(SdBaseFile* dirFile, + const char* path, uint32_t size); + /** \return The current cluster number for a file or directory. */ + uint32_t curCluster() const {return curCluster_;} + /** \return The current position for a file or directory. */ + uint32_t curPosition() const {return curPosition_;} + /** \return Current working directory */ + static SdBaseFile* cwd() {return cwd_;} + /** Set the date/time callback function + * + * \param[in] dateTime The user's call back function. The callback + * function is of the form: + * + * \code + * void dateTime(uint16_t* date, uint16_t* time) { + * uint16_t year; + * uint8_t month, day, hour, minute, second; + * + * // User gets date and time from GPS or real-time clock here + * + * // return date using FAT_DATE macro to format fields + * *date = FAT_DATE(year, month, day); + * + * // return time using FAT_TIME macro to format fields + * *time = FAT_TIME(hour, minute, second); + * } + * \endcode + * + * Sets the function that is called when a file is created or when + * a file's directory entry is modified by sync(). All timestamps, + * access, creation, and modify, are set when a file is created. + * sync() maintains the last access date and last modify date/time. + * + * See the timestamp() function. + */ + static void dateTimeCallback( + void (*dateTime)(uint16_t* date, uint16_t* time)) { + dateTime_ = dateTime; + } + /** Cancel the date/time callback function. */ + static void dateTimeCallbackCancel() {dateTime_ = 0;} + bool dirEntry(dir_t* dir); + static void dirName(const dir_t& dir, char* name); + bool exists(const char* name); + int16_t fgets(char* str, int16_t num, char* delim = 0); + /** \return The total number of bytes in a file or directory. */ + uint32_t fileSize() const {return fileSize_;} + /** \return The first cluster number for a file or directory. */ + uint32_t firstCluster() const {return firstCluster_;} + bool getFilename(char* name); + /** \return True if this is a directory else false. */ + bool isDir() const {return type_ >= FAT_FILE_TYPE_MIN_DIR;} + /** \return True if this is a normal file else false. */ + bool isFile() const {return type_ == FAT_FILE_TYPE_NORMAL;} + /** \return True if this is an open file/directory else false. */ + bool isOpen() const {return type_ != FAT_FILE_TYPE_CLOSED;} + /** \return True if this is a subdirectory else false. */ + bool isSubDir() const {return type_ == FAT_FILE_TYPE_SUBDIR;} + /** \return True if this is the root directory. */ + bool isRoot() const { + return type_ == FAT_FILE_TYPE_ROOT_FIXED || type_ == FAT_FILE_TYPE_ROOT32; + } + void ls(uint8_t flags = 0, uint8_t indent = 0); + bool mkdir(SdBaseFile* dir, const char* path, bool pFlag = true); + // alias for backward compactability + bool makeDir(SdBaseFile* dir, const char* path) { + return mkdir(dir, path, false); + } + bool open(SdBaseFile* dirFile, uint16_t index, uint8_t oflag); + bool open(SdBaseFile* dirFile, const char* path, uint8_t oflag); + bool open(const char* path, uint8_t oflag = O_READ); + bool openNext(SdBaseFile* dirFile, uint8_t oflag); + bool openRoot(SdVolume* vol); + int peek(); + static void printFatDate(uint16_t fatDate); + static void printFatTime(uint16_t fatTime); + bool printName(); + int16_t read(); + int16_t read(void* buf, uint16_t nbyte); + int8_t readDir(dir_t* dir, char* longFilename); + static bool remove(SdBaseFile* dirFile, const char* path); + bool remove(); + /** Set the file's current position to zero. */ + void rewind() {seekSet(0);} + bool rename(SdBaseFile* dirFile, const char* newPath); + bool rmdir(); + // for backward compatibility + bool rmDir() {return rmdir();} + bool rmRfStar(); + /** Set the files position to current position + \a pos. See seekSet(). + * \param[in] offset The new position in bytes from the current position. + * \return true for success or false for failure. + */ + bool seekCur(int32_t offset) { + return seekSet(curPosition_ + offset); + } + /** Set the files position to end-of-file + \a offset. See seekSet(). + * \param[in] offset The new position in bytes from end-of-file. + * \return true for success or false for failure. + */ + bool seekEnd(int32_t offset = 0) {return seekSet(fileSize_ + offset);} + bool seekSet(uint32_t pos); + bool sync(); + bool timestamp(SdBaseFile* file); + bool timestamp(uint8_t flag, uint16_t year, uint8_t month, uint8_t day, + uint8_t hour, uint8_t minute, uint8_t second); + /** Type of file. You should use isFile() or isDir() instead of type() + * if possible. + * + * \return The file or directory type. + */ + uint8_t type() const {return type_;} + bool truncate(uint32_t size); + /** \return SdVolume that contains this file. */ + SdVolume* volume() const {return vol_;} + int16_t write(const void* buf, uint16_t nbyte); + //------------------------------------------------------------------------------ + private: + // allow SdFat to set cwd_ + friend class SdFat; + // global pointer to cwd dir + static SdBaseFile* cwd_; + // data time callback function + static void (*dateTime_)(uint16_t* date, uint16_t* time); + // bits defined in flags_ + // should be 0x0F + static uint8_t const F_OFLAG = (O_ACCMODE | O_APPEND | O_SYNC); + // sync of directory entry required + static uint8_t const F_FILE_DIR_DIRTY = 0x80; + + // private data + uint8_t flags_; // See above for definition of flags_ bits + uint8_t fstate_; // error and eof indicator + uint8_t type_; // type of file see above for values + uint32_t curCluster_; // cluster for current file position + uint32_t curPosition_; // current file position in bytes from beginning + uint32_t dirBlock_; // block for this files directory entry + uint8_t dirIndex_; // index of directory entry in dirBlock + uint32_t fileSize_; // file size in bytes + uint32_t firstCluster_; // first cluster of file + SdVolume* vol_; // volume where file is located + + /** experimental don't use */ + bool openParent(SdBaseFile* dir); + // private functions + bool addCluster(); + bool addDirCluster(); + dir_t* cacheDirEntry(uint8_t action); + int8_t lsPrintNext(uint8_t flags, uint8_t indent); + static bool make83Name(const char* str, uint8_t* name, const char** ptr); + bool mkdir(SdBaseFile* parent, const uint8_t dname[11]); + bool open(SdBaseFile* dirFile, const uint8_t dname[11], uint8_t oflag); + bool openCachedEntry(uint8_t cacheIndex, uint8_t oflags); + dir_t* readDirCache(); + //------------------------------------------------------------------------------ + // to be deleted + static void printDirName(const dir_t& dir, + uint8_t width, bool printSlash); + //------------------------------------------------------------------------------ + // Deprecated functions - suppress cpplint warnings with NOLINT comment +#if ALLOW_DEPRECATED_FUNCTIONS && !defined(DOXYGEN) + public: + /** \deprecated Use: + * bool contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock); + * \param[out] bgnBlock the first block address for the file. + * \param[out] endBlock the last block address for the file. + * \return true for success or false for failure. + */ + bool contiguousRange(uint32_t& bgnBlock, uint32_t& endBlock) { // NOLINT + return contiguousRange(&bgnBlock, &endBlock); + } + /** \deprecated Use: + * bool createContiguous(SdBaseFile* dirFile, + * const char* path, uint32_t size) + * \param[in] dirFile The directory where the file will be created. + * \param[in] path A path with a valid DOS 8.3 file name. + * \param[in] size The desired file size. + * \return true for success or false for failure. + */ + bool createContiguous(SdBaseFile& dirFile, // NOLINT + const char* path, uint32_t size) { + return createContiguous(&dirFile, path, size); + } + /** \deprecated Use: + * static void dateTimeCallback( + * void (*dateTime)(uint16_t* date, uint16_t* time)); + * \param[in] dateTime The user's call back function. + */ + static void dateTimeCallback( + void (*dateTime)(uint16_t &date, uint16_t &time)) { // NOLINT + oldDateTime_ = dateTime; + dateTime_ = dateTime ? oldToNew : 0; + } + /** \deprecated Use: bool dirEntry(dir_t* dir); + * \param[out] dir Location for return of the file's directory entry. + * \return true for success or false for failure. + */ + bool dirEntry(dir_t& dir) {return dirEntry(&dir);} // NOLINT + /** \deprecated Use: + * bool mkdir(SdBaseFile* dir, const char* path); + * \param[in] dir An open SdFat instance for the directory that will contain + * the new directory. + * \param[in] path A path with a valid 8.3 DOS name for the new directory. + * \return true for success or false for failure. + */ + bool mkdir(SdBaseFile& dir, const char* path) { // NOLINT + return mkdir(&dir, path); + } + /** \deprecated Use: + * bool open(SdBaseFile* dirFile, const char* path, uint8_t oflag); + * \param[in] dirFile An open SdFat instance for the directory containing the + * file to be opened. + * \param[in] path A path with a valid 8.3 DOS name for the file. + * \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive + * OR of flags O_READ, O_WRITE, O_TRUNC, and O_SYNC. + * \return true for success or false for failure. + */ + bool open(SdBaseFile& dirFile, // NOLINT + const char* path, uint8_t oflag) { + return open(&dirFile, path, oflag); + } + /** \deprecated Do not use in new apps + * \param[in] dirFile An open SdFat instance for the directory containing the + * file to be opened. + * \param[in] path A path with a valid 8.3 DOS name for a file to be opened. + * \return true for success or false for failure. + */ + bool open(SdBaseFile& dirFile, const char* path) { // NOLINT + return open(dirFile, path, O_RDWR); + } + /** \deprecated Use: + * bool open(SdBaseFile* dirFile, uint16_t index, uint8_t oflag); + * \param[in] dirFile An open SdFat instance for the directory. + * \param[in] index The \a index of the directory entry for the file to be + * opened. The value for \a index is (directory file position)/32. + * \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive + * OR of flags O_READ, O_WRITE, O_TRUNC, and O_SYNC. + * \return true for success or false for failure. + */ + bool open(SdBaseFile& dirFile, uint16_t index, uint8_t oflag) { // NOLINT + return open(&dirFile, index, oflag); + } + /** \deprecated Use: bool openRoot(SdVolume* vol); + * \param[in] vol The FAT volume containing the root directory to be opened. + * \return true for success or false for failure. + */ + bool openRoot(SdVolume& vol) {return openRoot(&vol);} // NOLINT + /** \deprecated Use: int8_t readDir(dir_t* dir); + * \param[out] dir The dir_t struct that will receive the data. + * \return bytes read for success zero for eof or -1 for failure. + */ + int8_t readDir(dir_t& dir, char* longFilename) {return readDir(&dir, longFilename);} // NOLINT + /** \deprecated Use: + * static uint8_t remove(SdBaseFile* dirFile, const char* path); + * \param[in] dirFile The directory that contains the file. + * \param[in] path The name of the file to be removed. + * \return true for success or false for failure. + */ + static bool remove(SdBaseFile& dirFile, const char* path) { // NOLINT + return remove(&dirFile, path); + } + //------------------------------------------------------------------------------ + // rest are private + private: + static void (*oldDateTime_)(uint16_t &date, uint16_t &time); // NOLINT + static void oldToNew(uint16_t* date, uint16_t* time) { + uint16_t d; + uint16_t t; + oldDateTime_(d, t); + *date = d; + *time = t; + } +#endif // ALLOW_DEPRECATED_FUNCTIONS +}; + +#endif // SdBaseFile_h +#endif diff --git a/trunk/Arduino/Marlin_1.1.6/SdFatConfig.h b/trunk/Arduino/Marlin_1.1.6/SdFatConfig.h new file mode 100644 index 00000000..d3406a02 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/SdFatConfig.h @@ -0,0 +1,134 @@ +/** + * 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 . + * + */ + +/** + * Arduino SdFat Library + * Copyright (C) 2009 by William Greiman + * + * This file is part of the Arduino Sd2Card Library + */ +/** + * \file + * \brief configuration definitions + */ +#include "Marlin.h" +#if ENABLED(SDSUPPORT) + +#ifndef SdFatConfig_h + #define SdFatConfig_h + #include + //------------------------------------------------------------------------------ + /** + * To use multiple SD cards set USE_MULTIPLE_CARDS nonzero. + * + * Using multiple cards costs 400 - 500 bytes of flash. + * + * Each card requires about 550 bytes of SRAM so use of a Mega is recommended. + */ + #define USE_MULTIPLE_CARDS 0 + //------------------------------------------------------------------------------ + /** + * Call flush for endl if ENDL_CALLS_FLUSH is nonzero + * + * The standard for iostreams is to call flush. This is very costly for + * SdFat. Each call to flush causes 2048 bytes of I/O to the SD. + * + * SdFat has a single 512 byte buffer for SD I/O so it must write the current + * data block to the SD, read the directory block from the SD, update the + * directory entry, write the directory block to the SD and read the data + * block back into the buffer. + * + * The SD flash memory controller is not designed for this many rewrites + * so performance may be reduced by more than a factor of 100. + * + * If ENDL_CALLS_FLUSH is zero, you must call flush and/or close to force + * all data to be written to the SD. + */ + #define ENDL_CALLS_FLUSH 0 + //------------------------------------------------------------------------------ + /** + * Allow use of deprecated functions if ALLOW_DEPRECATED_FUNCTIONS is nonzero + */ + #define ALLOW_DEPRECATED_FUNCTIONS 1 + //------------------------------------------------------------------------------ + /** + * Allow FAT12 volumes if FAT12_SUPPORT is nonzero. + * FAT12 has not been well tested. + */ + #define FAT12_SUPPORT 0 + //------------------------------------------------------------------------------ + /** + * SPI init rate for SD initialization commands. Must be 5 (F_CPU/64) + * or 6 (F_CPU/128). + */ + #define SPI_SD_INIT_RATE 5 + //------------------------------------------------------------------------------ + /** + * Set the SS pin high for hardware SPI. If SS is chip select for another SPI + * device this will disable that device during the SD init phase. + */ + #define SET_SPI_SS_HIGH 1 + //------------------------------------------------------------------------------ + /** + * Define MEGA_SOFT_SPI nonzero to use software SPI on Mega Arduinos. + * Pins used are SS 10, MOSI 11, MISO 12, and SCK 13. + * + * MEGA_SOFT_SPI allows an unmodified Adafruit GPS Shield to be used + * on Mega Arduinos. Software SPI works well with GPS Shield V1.1 + * but many SD cards will fail with GPS Shield V1.0. + */ + #define MEGA_SOFT_SPI 0 + //------------------------------------------------------------------------------ + /** + * Set USE_SOFTWARE_SPI nonzero to always use software SPI. + */ + #define USE_SOFTWARE_SPI 0 + // define software SPI pins so Mega can use unmodified 168/328 shields + /** Software SPI chip select pin for the SD */ + #define SOFT_SPI_CS_PIN 10 + /** Software SPI Master Out Slave In pin */ + #define SOFT_SPI_MOSI_PIN 11 + /** Software SPI Master In Slave Out pin */ + #define SOFT_SPI_MISO_PIN 12 + /** Software SPI Clock pin */ + #define SOFT_SPI_SCK_PIN 13 + //------------------------------------------------------------------------------ + /** + * The __cxa_pure_virtual function is an error handler that is invoked when + * a pure virtual function is called. + */ + #define USE_CXA_PURE_VIRTUAL 1 + + /** Number of UTF-16 characters per entry */ + #define FILENAME_LENGTH 13 + + /** + * Defines for long (vfat) filenames + */ + /** Number of VFAT entries used. Every entry has 13 UTF-16 characters */ + #define MAX_VFAT_ENTRIES (2) + /** Total size of the buffer used to store the long filenames */ + #define LONG_FILENAME_LENGTH (FILENAME_LENGTH*MAX_VFAT_ENTRIES+1) +#endif // SdFatConfig_h + + +#endif diff --git a/trunk/Arduino/Marlin_1.1.6/SdFatStructs.h b/trunk/Arduino/Marlin_1.1.6/SdFatStructs.h new file mode 100644 index 00000000..52c815d7 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/SdFatStructs.h @@ -0,0 +1,655 @@ +/** + * 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 . + * + */ + +/** + * Arduino SdFat Library + * Copyright (C) 2009 by William Greiman + * + * This file is part of the Arduino Sd2Card Library + */ +#include "Marlin.h" +#if ENABLED(SDSUPPORT) + +#ifndef SdFatStructs_h +#define SdFatStructs_h + +#define PACKED __attribute__((__packed__)) +/** + * \file + * \brief FAT file structures + */ +/** + * mostly from Microsoft document fatgen103.doc + * http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx + */ +//------------------------------------------------------------------------------ +/** Value for byte 510 of boot block or MBR */ +uint8_t const BOOTSIG0 = 0x55; +/** Value for byte 511 of boot block or MBR */ +uint8_t const BOOTSIG1 = 0xAA; +/** Value for bootSignature field int FAT/FAT32 boot sector */ +uint8_t const EXTENDED_BOOT_SIG = 0x29; +//------------------------------------------------------------------------------ +/** + * \struct partitionTable + * \brief MBR partition table entry + * + * A partition table entry for a MBR formatted storage device. + * The MBR partition table has four entries. + */ +struct partitionTable { + /** + * Boot Indicator . Indicates whether the volume is the active + * partition. Legal values include: 0x00. Do not use for booting. + * 0x80 Active partition. + */ + uint8_t boot; + /** + * Head part of Cylinder-head-sector address of the first block in + * the partition. Legal values are 0-255. Only used in old PC BIOS. + */ + uint8_t beginHead; + /** + * Sector part of Cylinder-head-sector address of the first block in + * the partition. Legal values are 1-63. Only used in old PC BIOS. + */ + unsigned beginSector : 6; + /** High bits cylinder for first block in partition. */ + unsigned beginCylinderHigh : 2; + /** + * Combine beginCylinderLow with beginCylinderHigh. Legal values + * are 0-1023. Only used in old PC BIOS. + */ + uint8_t beginCylinderLow; + /** + * Partition type. See defines that begin with PART_TYPE_ for + * some Microsoft partition types. + */ + uint8_t type; + /** + * head part of cylinder-head-sector address of the last sector in the + * partition. Legal values are 0-255. Only used in old PC BIOS. + */ + uint8_t endHead; + /** + * Sector part of cylinder-head-sector address of the last sector in + * the partition. Legal values are 1-63. Only used in old PC BIOS. + */ + unsigned endSector : 6; + /** High bits of end cylinder */ + unsigned endCylinderHigh : 2; + /** + * Combine endCylinderLow with endCylinderHigh. Legal values + * are 0-1023. Only used in old PC BIOS. + */ + uint8_t endCylinderLow; + /** Logical block address of the first block in the partition. */ + uint32_t firstSector; + /** Length of the partition, in blocks. */ + uint32_t totalSectors; +} PACKED; +/** Type name for partitionTable */ +typedef struct partitionTable part_t; +//------------------------------------------------------------------------------ +/** + * \struct masterBootRecord + * + * \brief Master Boot Record + * + * The first block of a storage device that is formatted with a MBR. + */ +struct masterBootRecord { + /** Code Area for master boot program. */ + uint8_t codeArea[440]; + /** Optional Windows NT disk signature. May contain boot code. */ + uint32_t diskSignature; + /** Usually zero but may be more boot code. */ + uint16_t usuallyZero; + /** Partition tables. */ + part_t part[4]; + /** First MBR signature byte. Must be 0x55 */ + uint8_t mbrSig0; + /** Second MBR signature byte. Must be 0xAA */ + uint8_t mbrSig1; +} PACKED; +/** Type name for masterBootRecord */ +typedef struct masterBootRecord mbr_t; +//------------------------------------------------------------------------------ +/** + * \struct fat_boot + * + * \brief Boot sector for a FAT12/FAT16 volume. + * + */ +struct fat_boot { + /** + * The first three bytes of the boot sector must be valid, + * executable x 86-based CPU instructions. This includes a + * jump instruction that skips the next nonexecutable bytes. + */ + uint8_t jump[3]; + /** + * This is typically a string of characters that identifies + * the operating system that formatted the volume. + */ + char oemId[8]; + /** + * The size of a hardware sector. Valid decimal values for this + * field are 512, 1024, 2048, and 4096. For most disks used in + * the United States, the value of this field is 512. + */ + uint16_t bytesPerSector; + /** + * Number of sectors per allocation unit. This value must be a + * power of 2 that is greater than 0. The legal values are + * 1, 2, 4, 8, 16, 32, 64, and 128. 128 should be avoided. + */ + uint8_t sectorsPerCluster; + /** + * The number of sectors preceding the start of the first FAT, + * including the boot sector. The value of this field is always 1. + */ + uint16_t reservedSectorCount; + /** + * The number of copies of the FAT on the volume. + * The value of this field is always 2. + */ + uint8_t fatCount; + /** + * For FAT12 and FAT16 volumes, this field contains the count of + * 32-byte directory entries in the root directory. For FAT32 volumes, + * this field must be set to 0. For FAT12 and FAT16 volumes, this + * value should always specify a count that when multiplied by 32 + * results in a multiple of bytesPerSector. FAT16 volumes should + * use the value 512. + */ + uint16_t rootDirEntryCount; + /** + * This field is the old 16-bit total count of sectors on the volume. + * This count includes the count of all sectors in all four regions + * of the volume. This field can be 0; if it is 0, then totalSectors32 + * must be nonzero. For FAT32 volumes, this field must be 0. For + * FAT12 and FAT16 volumes, this field contains the sector count, and + * totalSectors32 is 0 if the total sector count fits + * (is less than 0x10000). + */ + uint16_t totalSectors16; + /** + * This dates back to the old MS-DOS 1.x media determination and is + * no longer usually used for anything. 0xF8 is the standard value + * for fixed (nonremovable) media. For removable media, 0xF0 is + * frequently used. Legal values are 0xF0 or 0xF8-0xFF. + */ + uint8_t mediaType; + /** + * Count of sectors occupied by one FAT on FAT12/FAT16 volumes. + * On FAT32 volumes this field must be 0, and sectorsPerFat32 + * contains the FAT size count. + */ + uint16_t sectorsPerFat16; + /** Sectors per track for interrupt 0x13. Not used otherwise. */ + uint16_t sectorsPerTrack; + /** Number of heads for interrupt 0x13. Not used otherwise. */ + uint16_t headCount; + /** + * Count of hidden sectors preceding the partition that contains this + * FAT volume. This field is generally only relevant for media + * visible on interrupt 0x13. + */ + uint32_t hidddenSectors; + /** + * This field is the new 32-bit total count of sectors on the volume. + * This count includes the count of all sectors in all four regions + * of the volume. This field can be 0; if it is 0, then + * totalSectors16 must be nonzero. + */ + uint32_t totalSectors32; + /** + * Related to the BIOS physical drive number. Floppy drives are + * identified as 0x00 and physical hard disks are identified as + * 0x80, regardless of the number of physical disk drives. + * Typically, this value is set prior to issuing an INT 13h BIOS + * call to specify the device to access. The value is only + * relevant if the device is a boot device. + */ + uint8_t driveNumber; + /** used by Windows NT - should be zero for FAT */ + uint8_t reserved1; + /** 0x29 if next three fields are valid */ + uint8_t bootSignature; + /** + * A random serial number created when formatting a disk, + * which helps to distinguish between disks. + * Usually generated by combining date and time. + */ + uint32_t volumeSerialNumber; + /** + * A field once used to store the volume label. The volume label + * is now stored as a special file in the root directory. + */ + char volumeLabel[11]; + /** + * A field with a value of either FAT, FAT12 or FAT16, + * depending on the disk format. + */ + char fileSystemType[8]; + /** X86 boot code */ + uint8_t bootCode[448]; + /** must be 0x55 */ + uint8_t bootSectorSig0; + /** must be 0xAA */ + uint8_t bootSectorSig1; +} PACKED; +/** Type name for FAT Boot Sector */ +typedef struct fat_boot fat_boot_t; +//------------------------------------------------------------------------------ +/** + * \struct fat32_boot + * + * \brief Boot sector for a FAT32 volume. + * + */ +struct fat32_boot { + /** + * The first three bytes of the boot sector must be valid, + * executable x 86-based CPU instructions. This includes a + * jump instruction that skips the next nonexecutable bytes. + */ + uint8_t jump[3]; + /** + * This is typically a string of characters that identifies + * the operating system that formatted the volume. + */ + char oemId[8]; + /** + * The size of a hardware sector. Valid decimal values for this + * field are 512, 1024, 2048, and 4096. For most disks used in + * the United States, the value of this field is 512. + */ + uint16_t bytesPerSector; + /** + * Number of sectors per allocation unit. This value must be a + * power of 2 that is greater than 0. The legal values are + * 1, 2, 4, 8, 16, 32, 64, and 128. 128 should be avoided. + */ + uint8_t sectorsPerCluster; + /** + * The number of sectors preceding the start of the first FAT, + * including the boot sector. Must not be zero + */ + uint16_t reservedSectorCount; + /** + * The number of copies of the FAT on the volume. + * The value of this field is always 2. + */ + uint8_t fatCount; + /** + * FAT12/FAT16 only. For FAT32 volumes, this field must be set to 0. + */ + uint16_t rootDirEntryCount; + /** + * For FAT32 volumes, this field must be 0. + */ + uint16_t totalSectors16; + /** + * This dates back to the old MS-DOS 1.x media determination and is + * no longer usually used for anything. 0xF8 is the standard value + * for fixed (nonremovable) media. For removable media, 0xF0 is + * frequently used. Legal values are 0xF0 or 0xF8-0xFF. + */ + uint8_t mediaType; + /** + * On FAT32 volumes this field must be 0, and sectorsPerFat32 + * contains the FAT size count. + */ + uint16_t sectorsPerFat16; + /** Sectors per track for interrupt 0x13. Not used otherwise. */ + uint16_t sectorsPerTrack; + /** Number of heads for interrupt 0x13. Not used otherwise. */ + uint16_t headCount; + /** + * Count of hidden sectors preceding the partition that contains this + * FAT volume. This field is generally only relevant for media + * visible on interrupt 0x13. + */ + uint32_t hidddenSectors; + /** + * Contains the total number of sectors in the FAT32 volume. + */ + uint32_t totalSectors32; + /** + * Count of sectors occupied by one FAT on FAT32 volumes. + */ + uint32_t sectorsPerFat32; + /** + * This field is only defined for FAT32 media and does not exist on + * FAT12 and FAT16 media. + * Bits 0-3 -- Zero-based number of active FAT. + * Only valid if mirroring is disabled. + * Bits 4-6 -- Reserved. + * Bit 7 -- 0 means the FAT is mirrored at runtime into all FATs. + * -- 1 means only one FAT is active; it is the one referenced + * in bits 0-3. + * Bits 8-15 -- Reserved. + */ + uint16_t fat32Flags; + /** + * FAT32 version. High byte is major revision number. + * Low byte is minor revision number. Only 0.0 define. + */ + uint16_t fat32Version; + /** + * Cluster number of the first cluster of the root directory for FAT32. + * This usually 2 but not required to be 2. + */ + uint32_t fat32RootCluster; + /** + * Sector number of FSINFO structure in the reserved area of the + * FAT32 volume. Usually 1. + */ + uint16_t fat32FSInfo; + /** + * If nonzero, indicates the sector number in the reserved area + * of the volume of a copy of the boot record. Usually 6. + * No value other than 6 is recommended. + */ + uint16_t fat32BackBootBlock; + /** + * Reserved for future expansion. Code that formats FAT32 volumes + * should always set all of the bytes of this field to 0. + */ + uint8_t fat32Reserved[12]; + /** + * Related to the BIOS physical drive number. Floppy drives are + * identified as 0x00 and physical hard disks are identified as + * 0x80, regardless of the number of physical disk drives. + * Typically, this value is set prior to issuing an INT 13h BIOS + * call to specify the device to access. The value is only + * relevant if the device is a boot device. + */ + uint8_t driveNumber; + /** used by Windows NT - should be zero for FAT */ + uint8_t reserved1; + /** 0x29 if next three fields are valid */ + uint8_t bootSignature; + /** + * A random serial number created when formatting a disk, + * which helps to distinguish between disks. + * Usually generated by combining date and time. + */ + uint32_t volumeSerialNumber; + /** + * A field once used to store the volume label. The volume label + * is now stored as a special file in the root directory. + */ + char volumeLabel[11]; + /** + * A text field with a value of FAT32. + */ + char fileSystemType[8]; + /** X86 boot code */ + uint8_t bootCode[420]; + /** must be 0x55 */ + uint8_t bootSectorSig0; + /** must be 0xAA */ + uint8_t bootSectorSig1; +} PACKED; +/** Type name for FAT32 Boot Sector */ +typedef struct fat32_boot fat32_boot_t; +//------------------------------------------------------------------------------ +/** Lead signature for a FSINFO sector */ +uint32_t const FSINFO_LEAD_SIG = 0x41615252; +/** Struct signature for a FSINFO sector */ +uint32_t const FSINFO_STRUCT_SIG = 0x61417272; +/** + * \struct fat32_fsinfo + * + * \brief FSINFO sector for a FAT32 volume. + * + */ +struct fat32_fsinfo { + /** must be 0x52, 0x52, 0x61, 0x41 */ + uint32_t leadSignature; + /** must be zero */ + uint8_t reserved1[480]; + /** must be 0x72, 0x72, 0x41, 0x61 */ + uint32_t structSignature; + /** + * Contains the last known free cluster count on the volume. + * If the value is 0xFFFFFFFF, then the free count is unknown + * and must be computed. Any other value can be used, but is + * not necessarily correct. It should be range checked at least + * to make sure it is <= volume cluster count. + */ + uint32_t freeCount; + /** + * This is a hint for the FAT driver. It indicates the cluster + * number at which the driver should start looking for free clusters. + * If the value is 0xFFFFFFFF, then there is no hint and the driver + * should start looking at cluster 2. + */ + uint32_t nextFree; + /** must be zero */ + uint8_t reserved2[12]; + /** must be 0x00, 0x00, 0x55, 0xAA */ + uint8_t tailSignature[4]; +} PACKED; +/** Type name for FAT32 FSINFO Sector */ +typedef struct fat32_fsinfo fat32_fsinfo_t; +//------------------------------------------------------------------------------ +// End Of Chain values for FAT entries +/** FAT12 end of chain value used by Microsoft. */ +uint16_t const FAT12EOC = 0xFFF; +/** Minimum value for FAT12 EOC. Use to test for EOC. */ +uint16_t const FAT12EOC_MIN = 0xFF8; +/** FAT16 end of chain value used by Microsoft. */ +uint16_t const FAT16EOC = 0xFFFF; +/** Minimum value for FAT16 EOC. Use to test for EOC. */ +uint16_t const FAT16EOC_MIN = 0xFFF8; +/** FAT32 end of chain value used by Microsoft. */ +uint32_t const FAT32EOC = 0x0FFFFFFF; +/** Minimum value for FAT32 EOC. Use to test for EOC. */ +uint32_t const FAT32EOC_MIN = 0x0FFFFFF8; +/** Mask a for FAT32 entry. Entries are 28 bits. */ +uint32_t const FAT32MASK = 0x0FFFFFFF; +//------------------------------------------------------------------------------ +/** + * \struct directoryEntry + * \brief FAT short directory entry + * + * Short means short 8.3 name, not the entry size. + * + * Date Format. A FAT directory entry date stamp is a 16-bit field that is + * basically a date relative to the MS-DOS epoch of 01/01/1980. Here is the + * format (bit 0 is the LSB of the 16-bit word, bit 15 is the MSB of the + * 16-bit word): + * + * Bits 9-15: Count of years from 1980, valid value range 0-127 + * inclusive (1980-2107). + * + * Bits 5-8: Month of year, 1 = January, valid value range 1-12 inclusive. + * + * Bits 0-4: Day of month, valid value range 1-31 inclusive. + * + * Time Format. A FAT directory entry time stamp is a 16-bit field that has + * a granularity of 2 seconds. Here is the format (bit 0 is the LSB of the + * 16-bit word, bit 15 is the MSB of the 16-bit word). + * + * Bits 11-15: Hours, valid value range 0-23 inclusive. + * + * Bits 5-10: Minutes, valid value range 0-59 inclusive. + * + * Bits 0-4: 2-second count, valid value range 0-29 inclusive (0 - 58 seconds). + * + * The valid time range is from Midnight 00:00:00 to 23:59:58. + */ +struct directoryEntry { + /** Short 8.3 name. + * + * The first eight bytes contain the file name with blank fill. + * The last three bytes contain the file extension with blank fill. + */ + uint8_t name[11]; + /** Entry attributes. + * + * The upper two bits of the attribute byte are reserved and should + * always be set to 0 when a file is created and never modified or + * looked at after that. See defines that begin with DIR_ATT_. + */ + uint8_t attributes; + /** + * Reserved for use by Windows NT. Set value to 0 when a file is + * created and never modify or look at it after that. + */ + uint8_t reservedNT; + /** + * The granularity of the seconds part of creationTime is 2 seconds + * so this field is a count of tenths of a second and it's valid + * value range is 0-199 inclusive. (WHG note - seems to be hundredths) + */ + uint8_t creationTimeTenths; + /** Time file was created. */ + uint16_t creationTime; + /** Date file was created. */ + uint16_t creationDate; + /** + * Last access date. Note that there is no last access time, only + * a date. This is the date of last read or write. In the case of + * a write, this should be set to the same date as lastWriteDate. + */ + uint16_t lastAccessDate; + /** + * High word of this entry's first cluster number (always 0 for a + * FAT12 or FAT16 volume). + */ + uint16_t firstClusterHigh; + /** Time of last write. File creation is considered a write. */ + uint16_t lastWriteTime; + /** Date of last write. File creation is considered a write. */ + uint16_t lastWriteDate; + /** Low word of this entry's first cluster number. */ + uint16_t firstClusterLow; + /** 32-bit unsigned holding this file's size in bytes. */ + uint32_t fileSize; +} PACKED; +/** + * \struct directoryVFATEntry + * \brief VFAT long filename directory entry + * + * directoryVFATEntries are found in the same list as normal directoryEntry. + * But have the attribute field set to DIR_ATT_LONG_NAME. + * + * Long filenames are saved in multiple directoryVFATEntries. + * Each entry containing 13 UTF-16 characters. + */ +struct directoryVFATEntry { + /** + * Sequence number. Consists of 2 parts: + * bit 6: indicates first long filename block for the next file + * bit 0-4: the position of this long filename block (first block is 1) + */ + uint8_t sequenceNumber; + /** First set of UTF-16 characters */ + uint16_t name1[5];//UTF-16 + /** attributes (at the same location as in directoryEntry), always 0x0F */ + uint8_t attributes; + /** Reserved for use by Windows NT. Always 0. */ + uint8_t reservedNT; + /** Checksum of the short 8.3 filename, can be used to checked if the file system as modified by a not-long-filename aware implementation. */ + uint8_t checksum; + /** Second set of UTF-16 characters */ + uint16_t name2[6];//UTF-16 + /** firstClusterLow is always zero for longFilenames */ + uint16_t firstClusterLow; + /** Third set of UTF-16 characters */ + uint16_t name3[2];//UTF-16 +} PACKED; +//------------------------------------------------------------------------------ +// Definitions for directory entries +// +/** Type name for directoryEntry */ +typedef struct directoryEntry dir_t; +/** Type name for directoryVFATEntry */ +typedef struct directoryVFATEntry vfat_t; +/** escape for name[0] = 0xE5 */ +uint8_t const DIR_NAME_0xE5 = 0x05; +/** name[0] value for entry that is free after being "deleted" */ +uint8_t const DIR_NAME_DELETED = 0xE5; +/** name[0] value for entry that is free and no allocated entries follow */ +uint8_t const DIR_NAME_FREE = 0x00; +/** file is read-only */ +uint8_t const DIR_ATT_READ_ONLY = 0x01; +/** File should hidden in directory listings */ +uint8_t const DIR_ATT_HIDDEN = 0x02; +/** Entry is for a system file */ +uint8_t const DIR_ATT_SYSTEM = 0x04; +/** Directory entry contains the volume label */ +uint8_t const DIR_ATT_VOLUME_ID = 0x08; +/** Entry is for a directory */ +uint8_t const DIR_ATT_DIRECTORY = 0x10; +/** Old DOS archive bit for backup support */ +uint8_t const DIR_ATT_ARCHIVE = 0x20; +/** Test value for long name entry. Test is + (d->attributes & DIR_ATT_LONG_NAME_MASK) == DIR_ATT_LONG_NAME. */ +uint8_t const DIR_ATT_LONG_NAME = 0x0F; +/** Test mask for long name entry */ +uint8_t const DIR_ATT_LONG_NAME_MASK = 0x3F; +/** defined attribute bits */ +uint8_t const DIR_ATT_DEFINED_BITS = 0x3F; +/** Directory entry is part of a long name + * \param[in] dir Pointer to a directory entry. + * + * \return true if the entry is for part of a long name else false. + */ +static inline uint8_t DIR_IS_LONG_NAME(const dir_t* dir) { + return (dir->attributes & DIR_ATT_LONG_NAME_MASK) == DIR_ATT_LONG_NAME; +} +/** Mask for file/subdirectory tests */ +uint8_t const DIR_ATT_FILE_TYPE_MASK = (DIR_ATT_VOLUME_ID | DIR_ATT_DIRECTORY); +/** Directory entry is for a file + * \param[in] dir Pointer to a directory entry. + * + * \return true if the entry is for a normal file else false. + */ +static inline uint8_t DIR_IS_FILE(const dir_t* dir) { + return (dir->attributes & DIR_ATT_FILE_TYPE_MASK) == 0; +} +/** Directory entry is for a subdirectory + * \param[in] dir Pointer to a directory entry. + * + * \return true if the entry is for a subdirectory else false. + */ +static inline uint8_t DIR_IS_SUBDIR(const dir_t* dir) { + return (dir->attributes & DIR_ATT_FILE_TYPE_MASK) == DIR_ATT_DIRECTORY; +} +/** Directory entry is for a file or subdirectory + * \param[in] dir Pointer to a directory entry. + * + * \return true if the entry is for a normal file or subdirectory else false. + */ +static inline uint8_t DIR_IS_FILE_OR_SUBDIR(const dir_t* dir) { + return (dir->attributes & DIR_ATT_VOLUME_ID) == 0; +} +#endif // SdFatStructs_h + + +#endif diff --git a/trunk/Arduino/Marlin_1.1.6/SdFatUtil.cpp b/trunk/Arduino/Marlin_1.1.6/SdFatUtil.cpp new file mode 100644 index 00000000..48d91df6 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/SdFatUtil.cpp @@ -0,0 +1,91 @@ +/** + * 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 . + * + */ + +/** + * Arduino SdFat Library + * Copyright (C) 2008 by William Greiman + * + * This file is part of the Arduino Sd2Card Library + */ +#include "Marlin.h" + +#if ENABLED(SDSUPPORT) +#include "SdFatUtil.h" + +//------------------------------------------------------------------------------ +/** Amount of free RAM + * \return The number of free bytes. + */ +#ifdef __arm__ +extern "C" char* sbrk(int incr); +int SdFatUtil::FreeRam() { + char top; + return &top - reinterpret_cast(sbrk(0)); +} +#else // __arm__ +extern char* __brkval; +extern char __bss_end; +/** Amount of free RAM + * \return The number of free bytes. + */ +int SdFatUtil::FreeRam() { + char top; + return __brkval ? &top - __brkval : &top - &__bss_end; +} +#endif // __arm + +//------------------------------------------------------------------------------ +/** %Print a string in flash memory. + * + * \param[in] pr Print object for output. + * \param[in] str Pointer to string stored in flash memory. + */ +void SdFatUtil::print_P(PGM_P str) { + for (uint8_t c; (c = pgm_read_byte(str)); str++) MYSERIAL.write(c); +} +//------------------------------------------------------------------------------ +/** %Print a string in flash memory followed by a CR/LF. + * + * \param[in] pr Print object for output. + * \param[in] str Pointer to string stored in flash memory. + */ +void SdFatUtil::println_P(PGM_P str) { + print_P(str); + MYSERIAL.println(); +} +//------------------------------------------------------------------------------ +/** %Print a string in flash memory to Serial. + * + * \param[in] str Pointer to string stored in flash memory. + */ +void SdFatUtil::SerialPrint_P(PGM_P str) { + print_P(str); +} +//------------------------------------------------------------------------------ +/** %Print a string in flash memory to Serial followed by a CR/LF. + * + * \param[in] str Pointer to string stored in flash memory. + */ +void SdFatUtil::SerialPrintln_P(PGM_P str) { + println_P(str); +} +#endif diff --git a/trunk/Arduino/Marlin_1.1.6/SdFatUtil.h b/trunk/Arduino/Marlin_1.1.6/SdFatUtil.h new file mode 100644 index 00000000..2e6435bb --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/SdFatUtil.h @@ -0,0 +1,56 @@ +/** + * 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 . + * + */ + +/** + * Arduino SdFat Library + * Copyright (C) 2008 by William Greiman + * + * This file is part of the Arduino Sd2Card Library + */ +#ifndef SdFatUtil_h +#define SdFatUtil_h + +#include "Marlin.h" +#if ENABLED(SDSUPPORT) + +/** + * \file + * \brief Useful utility functions. + */ +/** Store and print a string in flash memory.*/ +#define PgmPrint(x) SerialPrint_P(PSTR(x)) +/** Store and print a string in flash memory followed by a CR/LF.*/ +#define PgmPrintln(x) SerialPrintln_P(PSTR(x)) + +namespace SdFatUtil { + int FreeRam(); + void print_P(PGM_P str); + void println_P(PGM_P str); + void SerialPrint_P(PGM_P str); + void SerialPrintln_P(PGM_P str); +} + +using namespace SdFatUtil; // NOLINT + +#endif // SDSUPPORT + +#endif // SdFatUtil_h diff --git a/trunk/Arduino/Marlin_1.1.6/SdFile.cpp b/trunk/Arduino/Marlin_1.1.6/SdFile.cpp new file mode 100644 index 00000000..fc66f417 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/SdFile.cpp @@ -0,0 +1,102 @@ +/** + * 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 . + * + */ + +/** + * Arduino SdFat Library + * Copyright (C) 2009 by William Greiman + * + * This file is part of the Arduino Sd2Card Library + */ +#include "Marlin.h" + +#if ENABLED(SDSUPPORT) +#include "SdFile.h" +/** Create a file object and open it in the current working directory. + * + * \param[in] path A path with a valid 8.3 DOS name for a file to be opened. + * + * \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive + * OR of open flags. see SdBaseFile::open(SdBaseFile*, const char*, uint8_t). + */ +SdFile::SdFile(const char* path, uint8_t oflag) : SdBaseFile(path, oflag) { +} +//------------------------------------------------------------------------------ +/** Write data to an open file. + * + * \note Data is moved to the cache but may not be written to the + * storage device until sync() is called. + * + * \param[in] buf Pointer to the location of the data to be written. + * + * \param[in] nbyte Number of bytes to write. + * + * \return For success write() returns the number of bytes written, always + * \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); +} +//------------------------------------------------------------------------------ +/** Write a byte to a file. Required by the Arduino Print class. + * \param[in] b the byte to be written. + * Use writeError to check for errors. + */ +#if ARDUINO >= 100 + size_t SdFile::write(uint8_t b) { + return SdBaseFile::write(&b, 1); + } +#else + void SdFile::write(uint8_t b) { + SdBaseFile::write(&b, 1); + } +#endif +//------------------------------------------------------------------------------ +/** Write a string to a file. Used by the Arduino Print class. + * \param[in] str Pointer to the string. + * Use writeError to check for errors. + */ +void SdFile::write(const char* str) { + SdBaseFile::write(str, strlen(str)); +} +//------------------------------------------------------------------------------ +/** Write a PROGMEM string to a file. + * \param[in] str Pointer to the PROGMEM string. + * Use writeError to check for errors. + */ +void SdFile::write_P(PGM_P str) { + for (uint8_t c; (c = pgm_read_byte(str)); str++) write(c); +} +//------------------------------------------------------------------------------ +/** Write a PROGMEM string followed by CR/LF to a file. + * \param[in] str Pointer to the PROGMEM string. + * Use writeError to check for errors. + */ +void SdFile::writeln_P(PGM_P str) { + write_P(str); + write_P(PSTR("\r\n")); +} + + +#endif diff --git a/trunk/Arduino/Marlin_1.1.6/SdFile.h b/trunk/Arduino/Marlin_1.1.6/SdFile.h new file mode 100644 index 00000000..53f38255 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/SdFile.h @@ -0,0 +1,63 @@ +/** + * 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 . + * + */ + +/** + * Arduino SdFat Library + * Copyright (C) 2009 by William Greiman + * + * This file is part of the Arduino Sd2Card Library + */ +/** + * \file + * \brief SdFile class + */ +#include "Marlin.h" + +#if ENABLED(SDSUPPORT) +#include "SdBaseFile.h" +#include +#ifndef SdFile_h +#define SdFile_h +//------------------------------------------------------------------------------ +/** + * \class SdFile + * \brief SdBaseFile with Print. + */ +class SdFile : public SdBaseFile, public Print { + public: + SdFile() {} + SdFile(const char* name, uint8_t oflag); + #if ARDUINO >= 100 + size_t write(uint8_t b); + #else + void write(uint8_t b); + #endif + + int16_t write(const void* buf, uint16_t nbyte); + void write(const char* str); + void write_P(PGM_P str); + void writeln_P(PGM_P str); +}; +#endif // SdFile_h + + +#endif diff --git a/trunk/Arduino/Marlin_1.1.6/SdInfo.h b/trunk/Arduino/Marlin_1.1.6/SdInfo.h new file mode 100644 index 00000000..88b46569 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/SdInfo.h @@ -0,0 +1,289 @@ +/** + * 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 . + * + */ + +/** + * Arduino Sd2Card Library + * Copyright (C) 2009 by William Greiman + * + * This file is part of the Arduino Sd2Card Library + */ +#include "Marlin.h" +#if ENABLED(SDSUPPORT) + +#ifndef SdInfo_h +#define SdInfo_h +#include +// Based on the document: +// +// SD Specifications +// Part 1 +// Physical Layer +// Simplified Specification +// Version 3.01 +// May 18, 2010 +// +// http://www.sdcard.org/developers/tech/sdcard/pls/simplified_specs +//------------------------------------------------------------------------------ +// SD card commands +/** GO_IDLE_STATE - init card in spi mode if CS low */ +uint8_t const CMD0 = 0x00; +/** SEND_IF_COND - verify SD Memory Card interface operating condition.*/ +uint8_t const CMD8 = 0x08; +/** SEND_CSD - read the Card Specific Data (CSD register) */ +uint8_t const CMD9 = 0x09; +/** SEND_CID - read the card identification information (CID register) */ +uint8_t const CMD10 = 0x0A; +/** STOP_TRANSMISSION - end multiple block read sequence */ +uint8_t const CMD12 = 0x0C; +/** SEND_STATUS - read the card status register */ +uint8_t const CMD13 = 0x0D; +/** READ_SINGLE_BLOCK - read a single data block from the card */ +uint8_t const CMD17 = 0x11; +/** READ_MULTIPLE_BLOCK - read a multiple data blocks from the card */ +uint8_t const CMD18 = 0x12; +/** WRITE_BLOCK - write a single data block to the card */ +uint8_t const CMD24 = 0x18; +/** WRITE_MULTIPLE_BLOCK - write blocks of data until a STOP_TRANSMISSION */ +uint8_t const CMD25 = 0x19; +/** ERASE_WR_BLK_START - sets the address of the first block to be erased */ +uint8_t const CMD32 = 0x20; +/** ERASE_WR_BLK_END - sets the address of the last block of the continuous + range to be erased*/ +uint8_t const CMD33 = 0x21; +/** ERASE - erase all previously selected blocks */ +uint8_t const CMD38 = 0x26; +/** APP_CMD - escape for application specific command */ +uint8_t const CMD55 = 0x37; +/** READ_OCR - read the OCR register of a card */ +uint8_t const CMD58 = 0x3A; +/** SET_WR_BLK_ERASE_COUNT - Set the number of write blocks to be + pre-erased before writing */ +uint8_t const ACMD23 = 0x17; +/** SD_SEND_OP_COMD - Sends host capacity support information and + activates the card's initialization process */ +uint8_t const ACMD41 = 0x29; +//------------------------------------------------------------------------------ +/** status for card in the ready state */ +uint8_t const R1_READY_STATE = 0x00; +/** status for card in the idle state */ +uint8_t const R1_IDLE_STATE = 0x01; +/** status bit for illegal command */ +uint8_t const R1_ILLEGAL_COMMAND = 0x04; +/** start data token for read or write single block*/ +uint8_t const DATA_START_BLOCK = 0xFE; +/** stop token for write multiple blocks*/ +uint8_t const STOP_TRAN_TOKEN = 0xFD; +/** start data token for write multiple blocks*/ +uint8_t const WRITE_MULTIPLE_TOKEN = 0xFC; +/** mask for data response tokens after a write block operation */ +uint8_t const DATA_RES_MASK = 0x1F; +/** write data accepted token */ +uint8_t const DATA_RES_ACCEPTED = 0x05; +//------------------------------------------------------------------------------ +/** Card IDentification (CID) register */ +typedef struct CID { + // byte 0 + /** Manufacturer ID */ + unsigned char mid; + // byte 1-2 + /** OEM/Application ID */ + char oid[2]; + // byte 3-7 + /** Product name */ + char pnm[5]; + // byte 8 + /** Product revision least significant digit */ + unsigned char prv_m : 4; + /** Product revision most significant digit */ + unsigned char prv_n : 4; + // byte 9-12 + /** Product serial number */ + uint32_t psn; + // byte 13 + /** Manufacturing date year low digit */ + unsigned char mdt_year_high : 4; + /** not used */ + unsigned char reserved : 4; + // byte 14 + /** Manufacturing date month */ + unsigned char mdt_month : 4; + /** Manufacturing date year low digit */ + unsigned char mdt_year_low : 4; + // byte 15 + /** not used always 1 */ + unsigned char always1 : 1; + /** CRC7 checksum */ + unsigned char crc : 7; +} cid_t; +//------------------------------------------------------------------------------ +/** CSD for version 1.00 cards */ +typedef struct CSDV1 { + // byte 0 + unsigned char reserved1 : 6; + unsigned char csd_ver : 2; + // byte 1 + unsigned char taac; + // byte 2 + unsigned char nsac; + // byte 3 + unsigned char tran_speed; + // byte 4 + unsigned char ccc_high; + // byte 5 + unsigned char read_bl_len : 4; + unsigned char ccc_low : 4; + // byte 6 + unsigned char c_size_high : 2; + unsigned char reserved2 : 2; + unsigned char dsr_imp : 1; + unsigned char read_blk_misalign : 1; + unsigned char write_blk_misalign : 1; + unsigned char read_bl_partial : 1; + // byte 7 + unsigned char c_size_mid; + // byte 8 + unsigned char vdd_r_curr_max : 3; + unsigned char vdd_r_curr_min : 3; + unsigned char c_size_low : 2; + // byte 9 + unsigned char c_size_mult_high : 2; + unsigned char vdd_w_cur_max : 3; + unsigned char vdd_w_curr_min : 3; + // byte 10 + unsigned char sector_size_high : 6; + unsigned char erase_blk_en : 1; + unsigned char c_size_mult_low : 1; + // byte 11 + unsigned char wp_grp_size : 7; + unsigned char sector_size_low : 1; + // byte 12 + unsigned char write_bl_len_high : 2; + unsigned char r2w_factor : 3; + unsigned char reserved3 : 2; + unsigned char wp_grp_enable : 1; + // byte 13 + unsigned char reserved4 : 5; + unsigned char write_partial : 1; + unsigned char write_bl_len_low : 2; + // byte 14 + unsigned char reserved5: 2; + unsigned char file_format : 2; + unsigned char tmp_write_protect : 1; + unsigned char perm_write_protect : 1; + unsigned char copy : 1; + /** Indicates the file format on the card */ + unsigned char file_format_grp : 1; + // byte 15 + unsigned char always1 : 1; + unsigned char crc : 7; +} csd1_t; +//------------------------------------------------------------------------------ +/** CSD for version 2.00 cards */ +typedef struct CSDV2 { + // byte 0 + unsigned char reserved1 : 6; + unsigned char csd_ver : 2; + // byte 1 + /** fixed to 0x0E */ + unsigned char taac; + // byte 2 + /** fixed to 0 */ + unsigned char nsac; + // byte 3 + unsigned char tran_speed; + // byte 4 + unsigned char ccc_high; + // byte 5 + /** This field is fixed to 9h, which indicates READ_BL_LEN=512 Byte */ + unsigned char read_bl_len : 4; + unsigned char ccc_low : 4; + // byte 6 + /** not used */ + unsigned char reserved2 : 4; + unsigned char dsr_imp : 1; + /** fixed to 0 */ + unsigned char read_blk_misalign : 1; + /** fixed to 0 */ + unsigned char write_blk_misalign : 1; + /** fixed to 0 - no partial read */ + unsigned char read_bl_partial : 1; + // byte 7 + /** not used */ + unsigned char reserved3 : 2; + /** high part of card size */ + unsigned char c_size_high : 6; + // byte 8 + /** middle part of card size */ + unsigned char c_size_mid; + // byte 9 + /** low part of card size */ + unsigned char c_size_low; + // byte 10 + /** sector size is fixed at 64 KB */ + unsigned char sector_size_high : 6; + /** fixed to 1 - erase single is supported */ + unsigned char erase_blk_en : 1; + /** not used */ + unsigned char reserved4 : 1; + // byte 11 + unsigned char wp_grp_size : 7; + /** sector size is fixed at 64 KB */ + unsigned char sector_size_low : 1; + // byte 12 + /** write_bl_len fixed for 512 byte blocks */ + unsigned char write_bl_len_high : 2; + /** fixed value of 2 */ + unsigned char r2w_factor : 3; + /** not used */ + unsigned char reserved5 : 2; + /** fixed value of 0 - no write protect groups */ + unsigned char wp_grp_enable : 1; + // byte 13 + unsigned char reserved6 : 5; + /** always zero - no partial block read*/ + unsigned char write_partial : 1; + /** write_bl_len fixed for 512 byte blocks */ + unsigned char write_bl_len_low : 2; + // byte 14 + unsigned char reserved7: 2; + /** Do not use always 0 */ + unsigned char file_format : 2; + unsigned char tmp_write_protect : 1; + unsigned char perm_write_protect : 1; + unsigned char copy : 1; + /** Do not use always 0 */ + unsigned char file_format_grp : 1; + // byte 15 + /** not used always 1 */ + unsigned char always1 : 1; + /** checksum */ + unsigned char crc : 7; +} csd2_t; +//------------------------------------------------------------------------------ +/** union of old and new style CSD register */ +union csd_t { + csd1_t v1; + csd2_t v2; +}; +#endif // SdInfo_h + +#endif diff --git a/trunk/Arduino/Marlin_1.1.6/SdVolume.cpp b/trunk/Arduino/Marlin_1.1.6/SdVolume.cpp new file mode 100644 index 00000000..4093cb5e --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/SdVolume.cpp @@ -0,0 +1,420 @@ +/** + * 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 . + * + */ + +/** + * Arduino SdFat Library + * Copyright (C) 2009 by William Greiman + * + * This file is part of the Arduino Sd2Card Library + */ +#include "Marlin.h" +#if ENABLED(SDSUPPORT) + +#include "SdVolume.h" +//------------------------------------------------------------------------------ +#if !USE_MULTIPLE_CARDS + // raw block cache + uint32_t SdVolume::cacheBlockNumber_; // current block number + cache_t SdVolume::cacheBuffer_; // 512 byte cache for Sd2Card + Sd2Card* SdVolume::sdCard_; // pointer to SD card object + bool SdVolume::cacheDirty_; // cacheFlush() will write block if true + uint32_t SdVolume::cacheMirrorBlock_; // mirror block for second FAT +#endif // USE_MULTIPLE_CARDS +//------------------------------------------------------------------------------ +// find a contiguous group of clusters +bool SdVolume::allocContiguous(uint32_t count, uint32_t* curCluster) { + // start of group + uint32_t bgnCluster; + // end of group + uint32_t endCluster; + // last cluster of FAT + uint32_t fatEnd = clusterCount_ + 1; + + // flag to save place to start next search + bool setStart; + + // set search start cluster + if (*curCluster) { + // try to make file contiguous + bgnCluster = *curCluster + 1; + + // don't save new start location + setStart = false; + } + else { + // start at likely place for free cluster + bgnCluster = allocSearchStart_; + + // save next search start if one cluster + setStart = count == 1; + } + // end of group + endCluster = bgnCluster; + + // search the FAT for free clusters + for (uint32_t n = 0;; n++, endCluster++) { + // can't find space checked all clusters + if (n >= clusterCount_) goto FAIL; + + // past end - start from beginning of FAT + if (endCluster > fatEnd) { + bgnCluster = endCluster = 2; + } + uint32_t f; + if (!fatGet(endCluster, &f)) goto FAIL; + + if (f != 0) { + // cluster in use try next cluster as bgnCluster + bgnCluster = endCluster + 1; + } + else if ((endCluster - bgnCluster + 1) == count) { + // done - found space + break; + } + } + // mark end of chain + if (!fatPutEOC(endCluster)) goto FAIL; + + // link clusters + while (endCluster > bgnCluster) { + if (!fatPut(endCluster - 1, endCluster)) goto FAIL; + endCluster--; + } + if (*curCluster != 0) { + // connect chains + if (!fatPut(*curCluster, bgnCluster)) goto FAIL; + } + // return first cluster number to caller + *curCluster = bgnCluster; + + // remember possible next free cluster + if (setStart) allocSearchStart_ = bgnCluster + 1; + + return true; + FAIL: + return false; +} +//------------------------------------------------------------------------------ +bool SdVolume::cacheFlush() { + if (cacheDirty_) { + if (!sdCard_->writeBlock(cacheBlockNumber_, cacheBuffer_.data)) { + goto FAIL; + } + // mirror FAT tables + if (cacheMirrorBlock_) { + if (!sdCard_->writeBlock(cacheMirrorBlock_, cacheBuffer_.data)) { + goto FAIL; + } + cacheMirrorBlock_ = 0; + } + cacheDirty_ = 0; + } + return true; + FAIL: + return false; +} +//------------------------------------------------------------------------------ +bool SdVolume::cacheRawBlock(uint32_t blockNumber, bool dirty) { + if (cacheBlockNumber_ != blockNumber) { + if (!cacheFlush()) goto FAIL; + if (!sdCard_->readBlock(blockNumber, cacheBuffer_.data)) goto FAIL; + cacheBlockNumber_ = blockNumber; + } + if (dirty) cacheDirty_ = true; + return true; + FAIL: + return false; +} +//------------------------------------------------------------------------------ +// return the size in bytes of a cluster chain +bool SdVolume::chainSize(uint32_t cluster, uint32_t* size) { + uint32_t s = 0; + do { + if (!fatGet(cluster, &cluster)) goto FAIL; + s += 512UL << clusterSizeShift_; + } while (!isEOC(cluster)); + *size = s; + return true; + FAIL: + return false; +} +//------------------------------------------------------------------------------ +// Fetch a FAT entry +bool SdVolume::fatGet(uint32_t cluster, uint32_t* value) { + uint32_t lba; + if (cluster > (clusterCount_ + 1)) goto FAIL; + if (FAT12_SUPPORT && fatType_ == 12) { + uint16_t index = cluster; + index += index >> 1; + lba = fatStartBlock_ + (index >> 9); + if (!cacheRawBlock(lba, CACHE_FOR_READ)) goto FAIL; + index &= 0x1FF; + uint16_t tmp = cacheBuffer_.data[index]; + index++; + if (index == 512) { + if (!cacheRawBlock(lba + 1, CACHE_FOR_READ)) goto FAIL; + index = 0; + } + tmp |= cacheBuffer_.data[index] << 8; + *value = cluster & 1 ? tmp >> 4 : tmp & 0xFFF; + return true; + } + if (fatType_ == 16) { + lba = fatStartBlock_ + (cluster >> 8); + } + else if (fatType_ == 32) { + lba = fatStartBlock_ + (cluster >> 7); + } + else { + goto FAIL; + } + if (lba != cacheBlockNumber_) { + if (!cacheRawBlock(lba, CACHE_FOR_READ)) goto FAIL; + } + if (fatType_ == 16) { + *value = cacheBuffer_.fat16[cluster & 0xFF]; + } + else { + *value = cacheBuffer_.fat32[cluster & 0x7F] & FAT32MASK; + } + return true; + FAIL: + return false; +} +//------------------------------------------------------------------------------ +// Store a FAT entry +bool SdVolume::fatPut(uint32_t cluster, uint32_t value) { + uint32_t lba; + // error if reserved cluster + if (cluster < 2) goto FAIL; + + // error if not in FAT + if (cluster > (clusterCount_ + 1)) goto FAIL; + + if (FAT12_SUPPORT && fatType_ == 12) { + uint16_t index = cluster; + index += index >> 1; + lba = fatStartBlock_ + (index >> 9); + if (!cacheRawBlock(lba, CACHE_FOR_WRITE)) goto FAIL; + // mirror second FAT + if (fatCount_ > 1) cacheMirrorBlock_ = lba + blocksPerFat_; + index &= 0x1FF; + uint8_t tmp = value; + if (cluster & 1) { + tmp = (cacheBuffer_.data[index] & 0XF) | tmp << 4; + } + cacheBuffer_.data[index] = tmp; + index++; + if (index == 512) { + lba++; + index = 0; + if (!cacheRawBlock(lba, CACHE_FOR_WRITE)) goto FAIL; + // mirror second FAT + if (fatCount_ > 1) cacheMirrorBlock_ = lba + blocksPerFat_; + } + tmp = value >> 4; + if (!(cluster & 1)) { + tmp = ((cacheBuffer_.data[index] & 0xF0)) | tmp >> 4; + } + cacheBuffer_.data[index] = tmp; + return true; + } + if (fatType_ == 16) { + lba = fatStartBlock_ + (cluster >> 8); + } + else if (fatType_ == 32) { + lba = fatStartBlock_ + (cluster >> 7); + } + else { + goto FAIL; + } + if (!cacheRawBlock(lba, CACHE_FOR_WRITE)) goto FAIL; + // store entry + if (fatType_ == 16) { + cacheBuffer_.fat16[cluster & 0xFF] = value; + } + else { + cacheBuffer_.fat32[cluster & 0x7F] = value; + } + // mirror second FAT + if (fatCount_ > 1) cacheMirrorBlock_ = lba + blocksPerFat_; + return true; + FAIL: + return false; +} +//------------------------------------------------------------------------------ +// free a cluster chain +bool SdVolume::freeChain(uint32_t cluster) { + uint32_t next; + + // clear free cluster location + allocSearchStart_ = 2; + + do { + if (!fatGet(cluster, &next)) goto FAIL; + + // free cluster + if (!fatPut(cluster, 0)) goto FAIL; + + cluster = next; + } while (!isEOC(cluster)); + + return true; + FAIL: + return false; +} +//------------------------------------------------------------------------------ +/** Volume free space in clusters. + * + * \return Count of free clusters for success or -1 if an error occurs. + */ +int32_t SdVolume::freeClusterCount() { + uint32_t free = 0; + uint16_t n; + uint32_t todo = clusterCount_ + 2; + + if (fatType_ == 16) { + n = 256; + } + else if (fatType_ == 32) { + n = 128; + } + else { + // put FAT12 here + return -1; + } + + for (uint32_t lba = fatStartBlock_; todo; todo -= n, lba++) { + if (!cacheRawBlock(lba, CACHE_FOR_READ)) return -1; + NOMORE(n, todo); + if (fatType_ == 16) { + for (uint16_t i = 0; i < n; i++) { + if (cacheBuffer_.fat16[i] == 0) free++; + } + } + else { + for (uint16_t i = 0; i < n; i++) { + if (cacheBuffer_.fat32[i] == 0) free++; + } + } + } + return free; +} +//------------------------------------------------------------------------------ +/** Initialize a FAT volume. + * + * \param[in] dev The SD card where the volume is located. + * + * \param[in] part The partition to be used. Legal values for \a part are + * 1-4 to use the corresponding partition on a device formatted with + * a MBR, Master Boot Record, or zero if the device is formatted as + * a super floppy with the FAT boot sector in block zero. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. Reasons for + * failure include not finding a valid partition, not finding a valid + * FAT file system in the specified partition or an I/O error. + */ +bool SdVolume::init(Sd2Card* dev, uint8_t part) { + uint32_t totalBlocks; + uint32_t volumeStartBlock = 0; + fat32_boot_t* fbs; + + sdCard_ = dev; + fatType_ = 0; + allocSearchStart_ = 2; + cacheDirty_ = 0; // cacheFlush() will write block if true + cacheMirrorBlock_ = 0; + cacheBlockNumber_ = 0xFFFFFFFF; + + // if part == 0 assume super floppy with FAT boot sector in block zero + // if part > 0 assume mbr volume with partition table + if (part) { + if (part > 4)goto FAIL; + if (!cacheRawBlock(volumeStartBlock, CACHE_FOR_READ)) goto FAIL; + part_t* p = &cacheBuffer_.mbr.part[part - 1]; + if ((p->boot & 0x7F) != 0 || + p->totalSectors < 100 || + p->firstSector == 0) { + // not a valid partition + goto FAIL; + } + volumeStartBlock = p->firstSector; + } + if (!cacheRawBlock(volumeStartBlock, CACHE_FOR_READ)) goto FAIL; + fbs = &cacheBuffer_.fbs32; + if (fbs->bytesPerSector != 512 || + fbs->fatCount == 0 || + fbs->reservedSectorCount == 0 || + fbs->sectorsPerCluster == 0) { + // not valid FAT volume + goto FAIL; + } + fatCount_ = fbs->fatCount; + blocksPerCluster_ = fbs->sectorsPerCluster; + // determine shift that is same as multiply by blocksPerCluster_ + clusterSizeShift_ = 0; + while (blocksPerCluster_ != _BV(clusterSizeShift_)) { + // error if not power of 2 + if (clusterSizeShift_++ > 7) goto FAIL; + } + blocksPerFat_ = fbs->sectorsPerFat16 ? + fbs->sectorsPerFat16 : fbs->sectorsPerFat32; + + fatStartBlock_ = volumeStartBlock + fbs->reservedSectorCount; + + // count for FAT16 zero for FAT32 + rootDirEntryCount_ = fbs->rootDirEntryCount; + + // directory start for FAT16 dataStart for FAT32 + rootDirStart_ = fatStartBlock_ + fbs->fatCount * blocksPerFat_; + + // data start for FAT16 and FAT32 + dataStartBlock_ = rootDirStart_ + ((32 * fbs->rootDirEntryCount + 511) / 512); + + // total blocks for FAT16 or FAT32 + totalBlocks = fbs->totalSectors16 ? + fbs->totalSectors16 : fbs->totalSectors32; + + // total data blocks + clusterCount_ = totalBlocks - (dataStartBlock_ - volumeStartBlock); + + // divide by cluster size to get cluster count + clusterCount_ >>= clusterSizeShift_; + + // FAT type is determined by cluster count + if (clusterCount_ < 4085) { + fatType_ = 12; + if (!FAT12_SUPPORT) goto FAIL; + } + else if (clusterCount_ < 65525) { + fatType_ = 16; + } + else { + rootDirStart_ = fbs->fat32RootCluster; + fatType_ = 32; + } + return true; + FAIL: + return false; +} +#endif diff --git a/trunk/Arduino/Marlin_1.1.6/SdVolume.h b/trunk/Arduino/Marlin_1.1.6/SdVolume.h new file mode 100644 index 00000000..3041a6df --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/SdVolume.h @@ -0,0 +1,227 @@ +/** + * 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 . + * + */ + +/** + * Arduino SdFat Library + * Copyright (C) 2009 by William Greiman + * + * This file is part of the Arduino Sd2Card Library + */ +#include "Marlin.h" +#if ENABLED(SDSUPPORT) +#ifndef SdVolume_h +#define SdVolume_h +/** + * \file + * \brief SdVolume class + */ +#include "SdFatConfig.h" +#include "Sd2Card.h" +#include "SdFatStructs.h" + +//============================================================================== +// SdVolume class +/** + * \brief Cache for an SD data block + */ +union cache_t { + /** Used to access cached file data blocks. */ + uint8_t data[512]; + /** Used to access cached FAT16 entries. */ + uint16_t fat16[256]; + /** Used to access cached FAT32 entries. */ + uint32_t fat32[128]; + /** Used to access cached directory entries. */ + dir_t dir[16]; + /** Used to access a cached Master Boot Record. */ + mbr_t mbr; + /** Used to access to a cached FAT boot sector. */ + fat_boot_t fbs; + /** Used to access to a cached FAT32 boot sector. */ + fat32_boot_t fbs32; + /** Used to access to a cached FAT32 FSINFO sector. */ + fat32_fsinfo_t fsinfo; +}; +//------------------------------------------------------------------------------ +/** + * \class SdVolume + * \brief Access FAT16 and FAT32 volumes on SD and SDHC cards. + */ +class SdVolume { + public: + /** Create an instance of SdVolume */ + SdVolume() : fatType_(0) {} + /** Clear the cache and returns a pointer to the cache. Used by the WaveRP + * recorder to do raw write to the SD card. Not for normal apps. + * \return A pointer to the cache buffer or zero if an error occurs. + */ + cache_t* cacheClear() { + if (!cacheFlush()) return 0; + cacheBlockNumber_ = 0xFFFFFFFF; + return &cacheBuffer_; + } + /** Initialize a FAT volume. Try partition one first then try super + * floppy format. + * + * \param[in] dev The Sd2Card where the volume is located. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. Reasons for + * failure include not finding a valid partition, not finding a valid + * FAT file system or an I/O error. + */ + bool init(Sd2Card* dev) { return init(dev, 1) ? true : init(dev, 0);} + bool init(Sd2Card* dev, uint8_t part); + + // inline functions that return volume info + /** \return The volume's cluster size in blocks. */ + uint8_t blocksPerCluster() const {return blocksPerCluster_;} + /** \return The number of blocks in one FAT. */ + uint32_t blocksPerFat() const {return blocksPerFat_;} + /** \return The total number of clusters in the volume. */ + uint32_t clusterCount() const {return clusterCount_;} + /** \return The shift count required to multiply by blocksPerCluster. */ + uint8_t clusterSizeShift() const {return clusterSizeShift_;} + /** \return The logical block number for the start of file data. */ + uint32_t dataStartBlock() const {return dataStartBlock_;} + /** \return The number of FAT structures on the volume. */ + uint8_t fatCount() const {return fatCount_;} + /** \return The logical block number for the start of the first FAT. */ + uint32_t fatStartBlock() const {return fatStartBlock_;} + /** \return The FAT type of the volume. Values are 12, 16 or 32. */ + uint8_t fatType() const {return fatType_;} + int32_t freeClusterCount(); + /** \return The number of entries in the root directory for FAT16 volumes. */ + uint32_t rootDirEntryCount() const {return rootDirEntryCount_;} + /** \return The logical block number for the start of the root directory + on FAT16 volumes or the first cluster number on FAT32 volumes. */ + uint32_t rootDirStart() const {return rootDirStart_;} + /** Sd2Card object for this volume + * \return pointer to Sd2Card object. + */ + Sd2Card* sdCard() {return sdCard_;} + /** Debug access to FAT table + * + * \param[in] n cluster number. + * \param[out] v value of entry + * \return true for success or false for failure + */ + bool dbgFat(uint32_t n, uint32_t* v) {return fatGet(n, v);} + //------------------------------------------------------------------------------ + private: + // Allow SdBaseFile access to SdVolume private data. + friend class SdBaseFile; + + // value for dirty argument in cacheRawBlock to indicate read from cache + static bool const CACHE_FOR_READ = false; + // value for dirty argument in cacheRawBlock to indicate write to cache + static bool const CACHE_FOR_WRITE = true; + +#if USE_MULTIPLE_CARDS + cache_t cacheBuffer_; // 512 byte cache for device blocks + uint32_t cacheBlockNumber_; // Logical number of block in the cache + Sd2Card* sdCard_; // Sd2Card object for cache + bool cacheDirty_; // cacheFlush() will write block if true + uint32_t cacheMirrorBlock_; // block number for mirror FAT +#else // USE_MULTIPLE_CARDS + static cache_t cacheBuffer_; // 512 byte cache for device blocks + static uint32_t cacheBlockNumber_; // Logical number of block in the cache + static Sd2Card* sdCard_; // Sd2Card object for cache + static bool cacheDirty_; // cacheFlush() will write block if true + static uint32_t cacheMirrorBlock_; // block number for mirror FAT +#endif // USE_MULTIPLE_CARDS + uint32_t allocSearchStart_; // start cluster for alloc search + uint8_t blocksPerCluster_; // cluster size in blocks + uint32_t blocksPerFat_; // FAT size in blocks + uint32_t clusterCount_; // clusters in one FAT + uint8_t clusterSizeShift_; // shift to convert cluster count to block count + uint32_t dataStartBlock_; // first data block number + uint8_t fatCount_; // number of FATs on volume + uint32_t fatStartBlock_; // start block for first FAT + uint8_t fatType_; // volume type (12, 16, OR 32) + uint16_t rootDirEntryCount_; // number of entries in FAT16 root dir + uint32_t rootDirStart_; // root start block for FAT16, cluster for FAT32 + //---------------------------------------------------------------------------- + bool allocContiguous(uint32_t count, uint32_t* curCluster); + uint8_t blockOfCluster(uint32_t position) const { + return (position >> 9) & (blocksPerCluster_ - 1); + } + uint32_t clusterStartBlock(uint32_t cluster) const { + return dataStartBlock_ + ((cluster - 2) << clusterSizeShift_); + } + uint32_t blockNumber(uint32_t cluster, uint32_t position) const { + return clusterStartBlock(cluster) + blockOfCluster(position); + } + cache_t* cache() {return &cacheBuffer_;} + uint32_t cacheBlockNumber() {return cacheBlockNumber_;} +#if USE_MULTIPLE_CARDS + bool cacheFlush(); + bool cacheRawBlock(uint32_t blockNumber, bool dirty); +#else // USE_MULTIPLE_CARDS + static bool cacheFlush(); + static bool cacheRawBlock(uint32_t blockNumber, bool dirty); +#endif // USE_MULTIPLE_CARDS + // used by SdBaseFile write to assign cache to SD location + void cacheSetBlockNumber(uint32_t blockNumber, bool dirty) { + cacheDirty_ = dirty; + cacheBlockNumber_ = blockNumber; + } + void cacheSetDirty() {cacheDirty_ |= CACHE_FOR_WRITE;} + bool chainSize(uint32_t beginCluster, uint32_t* size); + bool fatGet(uint32_t cluster, uint32_t* value); + bool fatPut(uint32_t cluster, uint32_t value); + bool fatPutEOC(uint32_t cluster) { + return fatPut(cluster, 0x0FFFFFFF); + } + bool freeChain(uint32_t cluster); + bool isEOC(uint32_t cluster) const { + if (FAT12_SUPPORT && fatType_ == 12) return cluster >= FAT12EOC_MIN; + if (fatType_ == 16) return cluster >= FAT16EOC_MIN; + return cluster >= FAT32EOC_MIN; + } + bool readBlock(uint32_t block, uint8_t* dst) { + return sdCard_->readBlock(block, dst); + } + bool writeBlock(uint32_t block, const uint8_t* dst) { + return sdCard_->writeBlock(block, dst); + } + //------------------------------------------------------------------------------ + // Deprecated functions - suppress cpplint warnings with NOLINT comment +#if ALLOW_DEPRECATED_FUNCTIONS && !defined(DOXYGEN) + public: + /** \deprecated Use: bool SdVolume::init(Sd2Card* dev); + * \param[in] dev The SD card where the volume is located. + * \return true for success or false for failure. + */ + bool init(Sd2Card& dev) {return init(&dev);} // NOLINT + /** \deprecated Use: bool SdVolume::init(Sd2Card* dev, uint8_t vol); + * \param[in] dev The SD card where the volume is located. + * \param[in] part The partition to be used. + * \return true for success or false for failure. + */ + bool init(Sd2Card& dev, uint8_t part) { // NOLINT + return init(&dev, part); + } +#endif // ALLOW_DEPRECATED_FUNCTIONS +}; +#endif // SdVolume +#endif diff --git a/trunk/Arduino/Marlin_1.1.6/Version.h b/trunk/Arduino/Marlin_1.1.6/Version.h new file mode 100644 index 00000000..3039da59 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/Version.h @@ -0,0 +1,94 @@ +/** + * 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 . + * + */ + +/** + * This file is the standard Marlin version identifier file, all fields can be + * overriden by the ones defined on _Version.h by using the Configuration.h + * directive USE_AUTOMATIC_VERSIONING. + */ + +#if ENABLED(USE_AUTOMATIC_VERSIONING) + + #include "_Version.h" + +#else + + /** + * Marlin release version identifier + */ + #define SHORT_BUILD_VERSION "1.1.6" + + /** + * 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)" + + /** + * 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 "2017-10-10 12:00" + + /** + * Required minimum Configuration.h and Configuration_adv.h file versions. + * + * You must increment this version number for every significant change such as, + * but not limited to: ADD, DELETE RENAME OR REPURPOSE any directive/option on + * the configuration files. + */ + #define REQUIRED_CONFIGURATION_H_VERSION 010100 + #define REQUIRED_CONFIGURATION_ADV_H_VERSION 010100 + + /** + * The protocol for communication to the host. Protocol indicates communication + * standards such as the use of ASCII, "echo:" and "error:" line prefixes, etc. + * (Other behaviors are given by the firmware version and capabilities report.) + */ + #define PROTOCOL_VERSION "1.0" + + /** + * Defines a generic printer name to be output to the LCD after booting Marlin. + */ + #define MACHINE_NAME "3D Printer" + + /** + * The SOURCE_CODE_URL is the location where users will find the Marlin Source + * Code which is installed on the device. In most cases —unless the manufacturer + * has a distinct Github fork— the Source Code URL should just be the main + * Marlin repository. + */ + #define SOURCE_CODE_URL "https://github.com/MarlinFirmware/Marlin" + + /** + * Default generic printer UUID. + */ + #define DEFAULT_MACHINE_UUID "cede2a2f-41a2-4748-9b12-c55c62f367ff" + + /** + * 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" + +#endif // USE_AUTOMATIC_VERSIONING diff --git a/trunk/Arduino/Marlin_1.1.6/blinkm.cpp b/trunk/Arduino/Marlin_1.1.6/blinkm.cpp new file mode 100644 index 00000000..1caf0a07 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/blinkm.cpp @@ -0,0 +1,46 @@ +/** + * 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 . + * + */ + +/** + * blinkm.cpp - Library for controlling a BlinkM over i2c + * Created by Tim Koster, August 21 2013. + */ + +#include "Marlin.h" + +#if ENABLED(BLINKM) + +#include "blinkm.h" + +void SendColors(byte red, byte grn, byte blu) { + Wire.begin(); + Wire.beginTransmission(0x09); + Wire.write('o'); //to disable ongoing script, only needs to be used once + Wire.write('n'); + Wire.write(red); + Wire.write(grn); + Wire.write(blu); + Wire.endTransmission(); +} + +#endif // BLINKM + diff --git a/trunk/Arduino/Marlin_1.1.6/blinkm.h b/trunk/Arduino/Marlin_1.1.6/blinkm.h new file mode 100644 index 00000000..ed2ad79b --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/blinkm.h @@ -0,0 +1,31 @@ +/** + * 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 . + * + */ + +/** + * blinkm.h - Library for controlling a BlinkM over i2c + * Created by Tim Koster, August 21 2013. + */ + +#include "Arduino.h" +#include "Wire.h" + +void SendColors(byte red, byte grn, byte blu); diff --git a/trunk/Arduino/Marlin_1.1.6/boards.h b/trunk/Arduino/Marlin_1.1.6/boards.h new file mode 100644 index 00000000..398165e4 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/boards.h @@ -0,0 +1,106 @@ +/** + * 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 . + * + */ + +#ifndef BOARDS_H +#define BOARDS_H + +#define BOARD_UNKNOWN -1 + +#define BOARD_GEN7_CUSTOM 10 // Gen7 custom (Alfons3 Version) "https://github.com/Alfons3/Generation_7_Electronics" +#define BOARD_GEN7_12 11 // Gen7 v1.1, v1.2 +#define BOARD_GEN7_13 12 // Gen7 v1.3 +#define BOARD_GEN7_14 13 // Gen7 v1.4 +#define BOARD_CNCONTROLS_11 111 // Cartesio CN Controls V11 +#define BOARD_CNCONTROLS_12 112 // Cartesio CN Controls V12 +#define BOARD_CHEAPTRONIC 2 // Cheaptronic v1.0 +#define BOARD_CHEAPTRONIC_V2 21 // Cheaptronic v2.0 +#define BOARD_SETHI 20 // Sethi 3D_1 +#define BOARD_MIGHTYBOARD_REVE 200 // Makerbot Mightyboard Revision E +#define BOARD_RAMPS_OLD 3 // MEGA/RAMPS up to 1.2 +#define BOARD_RAMPS_13_EFB 33 // RAMPS 1.3 (Power outputs: Hotend, Fan, Bed) +#define BOARD_RAMPS_13_EEB 34 // RAMPS 1.3 (Power outputs: Hotend0, Hotend1, Bed) +#define BOARD_RAMPS_13_EFF 35 // RAMPS 1.3 (Power outputs: Hotend, Fan0, Fan1) +#define BOARD_RAMPS_13_EEF 36 // RAMPS 1.3 (Power outputs: Hotend0, Hotend1, Fan) +#define BOARD_RAMPS_13_SF 38 // RAMPS 1.3 (Power outputs: Spindle, Controller Fan) +#define BOARD_FELIX2 37 // Felix 2.0+ Electronics Board (RAMPS like) +#define BOARD_RIGIDBOARD 42 // Invent-A-Part RigidBoard +#define BOARD_RIGIDBOARD_V2 52 // Invent-A-Part RigidBoard V2 +#define BOARD_RAMPS_14_EFB 43 // RAMPS 1.4 (Power outputs: Hotend, Fan, Bed) +#define BOARD_RAMPS_14_EEB 44 // RAMPS 1.4 (Power outputs: Hotend0, Hotend1, Bed) +#define BOARD_RAMPS_14_EFF 45 // RAMPS 1.4 (Power outputs: Hotend, Fan0, Fan1) +#define BOARD_RAMPS_14_EEF 46 // RAMPS 1.4 (Power outputs: Hotend0, Hotend1, Fan) +#define BOARD_RAMPS_14_SF 48 // RAMPS 1.4 (Power outputs: Spindle, Controller Fan) +#define BOARD_GEN6 5 // Gen6 +#define BOARD_GEN6_DELUXE 51 // Gen6 deluxe +#define BOARD_SANGUINOLOLU_11 6 // Sanguinololu < 1.2 +#define BOARD_SANGUINOLOLU_12 62 // Sanguinololu 1.2 and above +#define BOARD_MELZI 63 // Melzi +#define BOARD_MELZI_MAKR3D 66 // Melzi with ATmega1284 (MaKr3d version) +#define BOARD_MELZI_CREALITY 89 // Melzi Creality3D board (for CR-10 etc) +#define BOARD_STB_11 64 // STB V1.1 +#define BOARD_AZTEEG_X1 65 // Azteeg X1 +#define BOARD_AZTEEG_X3 67 // Azteeg X3 +#define BOARD_AZTEEG_X3_PRO 68 // Azteeg X3 Pro +#define BOARD_ANET_10 69 // Anet 1.0 (Melzi clone) +#define BOARD_ULTIMAKER 7 // Ultimaker +#define BOARD_ULTIMAKER_OLD 71 // Ultimaker (Older electronics. Pre 1.5.4. This is rare) +#define BOARD_ULTIMAIN_2 72 // Ultimainboard 2.x (Uses TEMP_SENSOR 20) +#define BOARD_GT2560_REV_A 74 // Geeetech GT2560 Rev. A +#define BOARD_GT2560_REV_A_PLUS 75 // Geeetech GT2560 Rev. A+ (with auto level probe) +#define BOARD_3DRAG 77 // 3Drag Controller +#define BOARD_K8200 78 // Velleman K8200 Controller (derived from 3Drag Controller) +#define BOARD_K8400 79 // Velleman K8400 Controller (derived from 3Drag Controller) +#define BOARD_TEENSYLU 8 // Teensylu +#define BOARD_RUMBA 80 // Rumba +#define BOARD_PRINTRBOARD 81 // Printrboard (AT90USB1286) +#define BOARD_PRINTRBOARD_REVF 811 // Printrboard Revision F (AT90USB1286) +#define BOARD_BRAINWAVE 82 // Brainwave (AT90USB646) +#define BOARD_SAV_MKI 83 // SAV Mk-I (AT90USB1286) +#define BOARD_TEENSY2 84 // Teensy++2.0 (AT90USB1286) - CLI compile: HARDWARE_MOTHERBOARD=84 make +#define BOARD_BRAINWAVE_PRO 85 // Brainwave Pro (AT90USB1286) +#define BOARD_GEN3_PLUS 9 // Gen3+ +#define BOARD_GEN3_MONOLITHIC 22 // Gen3 Monolithic Electronics +#define BOARD_MEGATRONICS 70 // Megatronics +#define BOARD_MEGATRONICS_2 701 // Megatronics v2.0 +#define BOARD_MINITRONICS 702 // Minitronics v1.0/1.1 +#define BOARD_MEGATRONICS_3 703 // Megatronics v3.0 +#define BOARD_MEGATRONICS_31 704 // Megatronics v3.1 +#define BOARD_OMCA_A 90 // Alpha OMCA board +#define BOARD_OMCA 91 // Final OMCA board +#define BOARD_RAMBO 301 // Rambo +#define BOARD_MINIRAMBO 302 // Mini-Rambo +#define BOARD_SCOOVO_X9H 303 // abee Scoovo X9H +#define BOARD_MEGACONTROLLER 310 // Mega controller +#define BOARD_ELEFU_3 21 // Elefu Ra Board (v3) +#define BOARD_5DPRINT 88 // 5DPrint D8 Driver Board +#define BOARD_LEAPFROG 999 // Leapfrog +#define BOARD_MKS_BASE 40 // MKS BASE 1.0 +#define BOARD_MKS_13 47 // MKS v1.3 or 1.4 (maybe higher) +#define BOARD_SAINSMART_2IN1 49 // Sainsmart 2-in-1 board +#define BOARD_BAM_DICE 401 // 2PrintBeta BAM&DICE with STK drivers +#define BOARD_BAM_DICE_DUE 402 // 2PrintBeta BAM&DICE Due with STK drivers +#define BOARD_BQ_ZUM_MEGA_3D 503 // bq ZUM Mega 3D +#define BOARD_ZRIB_V20 504 // zrib V2.0 control board (Chinese knock off RAMPS replica) + +#define MB(board) (MOTHERBOARD==BOARD_##board) + +#endif // __BOARDS_H diff --git a/trunk/Arduino/Marlin_1.1.6/buzzer.h b/trunk/Arduino/Marlin_1.1.6/buzzer.h new file mode 100644 index 00000000..530b7296 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/buzzer.h @@ -0,0 +1,146 @@ +/** + * 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 . + * + */ + +#ifndef __BUZZER_H__ +#define __BUZZER_H__ + +#include "types.h" +#include "fastio.h" +#include "circularqueue.h" +#include "temperature.h" + +#include "MarlinConfig.h" + +#define TONE_QUEUE_LENGTH 4 + +/** + * @brief Tone structure + * @details Simple abstraction of a tone based on a duration and a frequency. + */ +struct tone_t { + uint16_t duration; + uint16_t frequency; +}; + +/** + * @brief Buzzer class + */ +class Buzzer { + private: + struct state_t { + tone_t tone; + uint32_t endtime; + } state; + + protected: + CircularQueue buffer; + + /** + * @brief Inverts the sate of a digital PIN + * @details This will invert the current state of an digital IO pin. + */ + void invert() { + TOGGLE(BEEPER_PIN); + } + + /** + * @brief Turn off a digital PIN + * @details Alias of digitalWrite(PIN, LOW) using FastIO + */ + void off() { + WRITE(BEEPER_PIN, LOW); + } + + /** + * @brief Turn on a digital PIN + * @details Alias of digitalWrite(PIN, HIGH) using FastIO + */ + void on() { + WRITE(BEEPER_PIN, HIGH); + } + + /** + * @brief Resets the state of the class + * @details Brings the class state to a known one. + */ + void reset() { + this->off(); + this->state.endtime = 0; + } + + public: + /** + * @brief Class constructor + */ + Buzzer() { + SET_OUTPUT(BEEPER_PIN); + this->reset(); + } + + /** + * @brief Add a tone to the queue + * @details Adds a tone_t structure to the ring buffer, will block IO if the + * queue is full waiting for one slot to get available. + * + * @param duration Duration of the tone in milliseconds + * @param frequency Frequency of the tone in hertz + */ + void tone(const uint16_t &duration, const uint16_t &frequency = 0) { + while (buffer.isFull()) { + this->tick(); + thermalManager.manage_heater(); + } + tone_t tone = { duration, frequency }; + this->buffer.enqueue(tone); + } + + /** + * @brief Loop function + * @details This function should be called at loop, it will take care of + * playing the tones in the queue. + */ + virtual void tick() { + const millis_t now = millis(); + + if (!this->state.endtime) { + if (this->buffer.isEmpty()) return; + + this->state.tone = this->buffer.dequeue(); + this->state.endtime = now + this->state.tone.duration; + + if (this->state.tone.frequency > 0) { + #if ENABLED(SPEAKER) + CRITICAL_SECTION_START; + ::tone(BEEPER_PIN, this->state.tone.frequency, this->state.tone.duration); + CRITICAL_SECTION_END; + #else + this->on(); + #endif + } + } + else if (ELAPSED(now, this->state.endtime)) this->reset(); + } +}; + +extern Buzzer buzzer; + +#endif diff --git a/trunk/Arduino/Marlin_1.1.6/cardreader.cpp b/trunk/Arduino/Marlin_1.1.6/cardreader.cpp new file mode 100644 index 00000000..89147d97 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/cardreader.cpp @@ -0,0 +1,885 @@ +/** + * 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 . + * + */ + +#include "cardreader.h" + +#include "ultralcd.h" +#include "stepper.h" +#include "language.h" + +#include "Marlin.h" + +#if ENABLED(SDSUPPORT) + +#define LONGEST_FILENAME (longFilename[0] ? longFilename : filename) + +CardReader::CardReader() { + #if ENABLED(SDCARD_SORT_ALPHA) + sort_count = 0; + #if ENABLED(SDSORT_GCODE) + sort_alpha = true; + sort_folders = FOLDER_SORTING; + //sort_reverse = false; + #endif + #endif + sdprinting = cardOK = saving = logging = false; + filesize = 0; + sdpos = 0; + workDirDepth = 0; + file_subcall_ctr = 0; + ZERO(workDirParents); + + autostart_stilltocheck = true; //the SD start is delayed, because otherwise the serial cannot answer fast enough to make contact with the host software. + autostart_index = 0; + + //power to SD reader + #if SDPOWER > -1 + OUT_WRITE(SDPOWER, HIGH); + #endif // SDPOWER + + next_autostart_ms = millis() + 5000; +} + +char *createFilename(char *buffer, const dir_t &p) { //buffer > 12characters + char *pos = buffer; + for (uint8_t i = 0; i < 11; i++) { + if (p.name[i] == ' ') continue; + if (i == 8) *pos++ = '.'; + *pos++ = p.name[i]; + } + *pos++ = 0; + return buffer; +} + +/** + * Dive into a folder and recurse depth-first to perform a pre-set operation lsAction: + * LS_Count - Add +1 to nrFiles for every file within the parent + * LS_GetFilename - Get the filename of the file indexed by nrFiles + * LS_SerialPrint - Print the full path and size of each file to serial output + */ +void CardReader::lsDive(const char *prepend, SdFile parent, const char * const match/*=NULL*/) { + dir_t p; + uint8_t cnt = 0; + + // Read the next entry from a directory + while (parent.readDir(p, longFilename) > 0) { + + // If the entry is a directory and the action is LS_SerialPrint + if (DIR_IS_SUBDIR(&p) && lsAction != LS_Count && lsAction != LS_GetFilename) { + + // Get the short name for the item, which we know is a folder + char lfilename[FILENAME_LENGTH]; + createFilename(lfilename, p); + + // Allocate enough stack space for the full path to a folder, trailing slash, and nul + bool prepend_is_empty = (prepend[0] == '\0'); + int len = (prepend_is_empty ? 1 : strlen(prepend)) + strlen(lfilename) + 1 + 1; + char path[len]; + + // Append the FOLDERNAME12/ to the passed string. + // It contains the full path to the "parent" argument. + // We now have the full path to the item in this folder. + strcpy(path, prepend_is_empty ? "/" : prepend); // root slash if prepend is empty + strcat(path, lfilename); // FILENAME_LENGTH-1 characters maximum + strcat(path, "/"); // 1 character + + // Serial.print(path); + + // Get a new directory object using the full path + // and dive recursively into it. + SdFile dir; + if (!dir.open(parent, lfilename, O_READ)) { + if (lsAction == LS_SerialPrint) { + SERIAL_ECHO_START(); + SERIAL_ECHOPGM(MSG_SD_CANT_OPEN_SUBDIR); + SERIAL_ECHOLN(lfilename); + } + } + lsDive(path, dir); + // close() is done automatically by destructor of SdFile + } + else { + uint8_t pn0 = p.name[0]; + if (pn0 == DIR_NAME_FREE) break; + if (pn0 == DIR_NAME_DELETED || pn0 == '.') continue; + if (longFilename[0] == '.') continue; + + if (!DIR_IS_FILE_OR_SUBDIR(&p) || (p.attributes & DIR_ATT_HIDDEN)) continue; + + filenameIsDir = DIR_IS_SUBDIR(&p); + + if (!filenameIsDir && (p.name[8] != 'G' || p.name[9] == '~')) continue; + + switch (lsAction) { + case LS_Count: + nrFiles++; + break; + + case LS_SerialPrint: + createFilename(filename, p); + SERIAL_PROTOCOL(prepend); + SERIAL_PROTOCOL(filename); + SERIAL_PROTOCOLCHAR(' '); + SERIAL_PROTOCOLLN(p.fileSize); + break; + + case LS_GetFilename: + createFilename(filename, p); + if (match != NULL) { + if (strcasecmp(match, filename) == 0) return; + } + else if (cnt == nrFiles) return; + cnt++; + break; + } + + } + } // while readDir +} + +void CardReader::ls() { + lsAction = LS_SerialPrint; + root.rewind(); + lsDive("", root); +} + +#if ENABLED(LONG_FILENAME_HOST_SUPPORT) + + /** + * Get a long pretty path based on a DOS 8.3 path + */ + void CardReader::printLongPath(char *path) { + lsAction = LS_GetFilename; + + int i, pathLen = strlen(path); + + // SERIAL_ECHOPGM("Full Path: "); SERIAL_ECHOLN(path); + + // Zero out slashes to make segments + for (i = 0; i < pathLen; i++) if (path[i] == '/') path[i] = '\0'; + + SdFile diveDir = root; // start from the root for segment 1 + for (i = 0; i < pathLen;) { + + if (path[i] == '\0') i++; // move past a single nul + + char *segment = &path[i]; // The segment after most slashes + + // If a segment is empty (extra-slash) then exit + if (!*segment) break; + + // Go to the next segment + while (path[++i]) { } + + // SERIAL_ECHOPGM("Looking for segment: "); SERIAL_ECHOLN(segment); + + // Find the item, setting the long filename + diveDir.rewind(); + lsDive("", diveDir, segment); + + // Print /LongNamePart to serial output + SERIAL_PROTOCOLCHAR('/'); + SERIAL_PROTOCOL(longFilename[0] ? longFilename : "???"); + + // If the filename was printed then that's it + if (!filenameIsDir) break; + + // SERIAL_ECHOPGM("Opening dir: "); SERIAL_ECHOLN(segment); + + // Open the sub-item as the new dive parent + SdFile dir; + if (!dir.open(diveDir, segment, O_READ)) { + SERIAL_EOL(); + SERIAL_ECHO_START(); + SERIAL_ECHOPGM(MSG_SD_CANT_OPEN_SUBDIR); + SERIAL_ECHO(segment); + break; + } + + diveDir.close(); + diveDir = dir; + + } // while i SD_PROCEDURE_DEPTH - 1) { + SERIAL_ERROR_START(); + SERIAL_ERRORPGM("trying to call sub-gcode files with too many levels. MAX level is:"); + SERIAL_ERRORLN(SD_PROCEDURE_DEPTH); + kill(PSTR(MSG_KILLED)); + return; + } + + // Store current filename and position + getAbsFilename(proc_filenames[file_subcall_ctr]); + + SERIAL_ECHO_START(); + SERIAL_ECHOPAIR("SUBROUTINE CALL target:\"", name); + SERIAL_ECHOPAIR("\" parent:\"", proc_filenames[file_subcall_ctr]); + SERIAL_ECHOLNPAIR("\" pos", sdpos); + filespos[file_subcall_ctr] = sdpos; + file_subcall_ctr++; + } + else { + doing = 1; + } + } + else { // Opening fresh file + doing = 2; + file_subcall_ctr = 0; // Reset procedure depth in case user cancels print while in procedure + } + + if (doing) { + SERIAL_ECHO_START(); + SERIAL_ECHOPGM("Now "); + SERIAL_ECHO(doing == 1 ? "doing" : "fresh"); + SERIAL_ECHOLNPAIR(" file: ", name); + } + + stopSDPrint(); + + SdFile myDir; + curDir = &root; + char *fname = name; + char *dirname_start, *dirname_end; + + if (name[0] == '/') { + dirname_start = &name[1]; + while (dirname_start != NULL) { + dirname_end = strchr(dirname_start, '/'); + //SERIAL_ECHOPGM("start:");SERIAL_ECHOLN((int)(dirname_start - name)); + //SERIAL_ECHOPGM("end :");SERIAL_ECHOLN((int)(dirname_end - name)); + if (dirname_end != NULL && dirname_end > dirname_start) { + char subdirname[FILENAME_LENGTH]; + strncpy(subdirname, dirname_start, dirname_end - dirname_start); + subdirname[dirname_end - dirname_start] = 0; + SERIAL_ECHOLN(subdirname); + if (!myDir.open(curDir, subdirname, O_READ)) { + SERIAL_PROTOCOLPGM(MSG_SD_OPEN_FILE_FAIL); + SERIAL_PROTOCOL(subdirname); + SERIAL_PROTOCOLCHAR('.'); + return; + } + else { + //SERIAL_ECHOLNPGM("dive ok"); + } + + curDir = &myDir; + dirname_start = dirname_end + 1; + } + else { // the remainder after all /fsa/fdsa/ is the filename + fname = dirname_start; + //SERIAL_ECHOLNPGM("remainder"); + //SERIAL_ECHOLN(fname); + break; + } + } + } + else { //relative path + curDir = &workDir; + } + + if (read) { + if (file.open(curDir, fname, O_READ)) { + filesize = file.fileSize(); + SERIAL_PROTOCOLPAIR(MSG_SD_FILE_OPENED, fname); + SERIAL_PROTOCOLLNPAIR(MSG_SD_SIZE, filesize); + sdpos = 0; + + SERIAL_PROTOCOLLNPGM(MSG_SD_FILE_SELECTED); + getfilename(0, fname); + lcd_setstatus(longFilename[0] ? longFilename : fname); + } + else { + SERIAL_PROTOCOLPAIR(MSG_SD_OPEN_FILE_FAIL, fname); + SERIAL_PROTOCOLCHAR('.'); + SERIAL_EOL(); + } + } + else { //write + if (!file.open(curDir, fname, O_CREAT | O_APPEND | O_WRITE | O_TRUNC)) { + SERIAL_PROTOCOLPAIR(MSG_SD_OPEN_FILE_FAIL, fname); + SERIAL_PROTOCOLCHAR('.'); + SERIAL_EOL(); + } + else { + saving = true; + SERIAL_PROTOCOLLNPAIR(MSG_SD_WRITE_TO_FILE, name); + lcd_setstatus(fname); + } + } +} + +void CardReader::removeFile(char* name) { + if (!cardOK) return; + + stopSDPrint(); + + SdFile myDir; + curDir = &root; + char *fname = name; + + char *dirname_start, *dirname_end; + if (name[0] == '/') { + dirname_start = strchr(name, '/') + 1; + while (dirname_start != NULL) { + dirname_end = strchr(dirname_start, '/'); + //SERIAL_ECHOPGM("start:");SERIAL_ECHOLN((int)(dirname_start - name)); + //SERIAL_ECHOPGM("end :");SERIAL_ECHOLN((int)(dirname_end - name)); + if (dirname_end != NULL && dirname_end > dirname_start) { + char subdirname[FILENAME_LENGTH]; + strncpy(subdirname, dirname_start, dirname_end - dirname_start); + subdirname[dirname_end - dirname_start] = 0; + SERIAL_ECHOLN(subdirname); + if (!myDir.open(curDir, subdirname, O_READ)) { + SERIAL_PROTOCOLPAIR("open failed, File: ", subdirname); + SERIAL_PROTOCOLCHAR('.'); + SERIAL_EOL(); + return; + } + else { + //SERIAL_ECHOLNPGM("dive ok"); + } + + curDir = &myDir; + dirname_start = dirname_end + 1; + } + else { // the remainder after all /fsa/fdsa/ is the filename + fname = dirname_start; + //SERIAL_ECHOLNPGM("remainder"); + //SERIAL_ECHOLN(fname); + break; + } + } + } + else { // relative path + curDir = &workDir; + } + + if (file.remove(curDir, fname)) { + SERIAL_PROTOCOLPGM("File deleted:"); + SERIAL_PROTOCOLLN(fname); + sdpos = 0; + #if ENABLED(SDCARD_SORT_ALPHA) + presort(); + #endif + } + else { + SERIAL_PROTOCOLPGM("Deletion failed, File: "); + SERIAL_PROTOCOL(fname); + SERIAL_PROTOCOLCHAR('.'); + } +} + +void CardReader::getStatus() { + if (cardOK) { + SERIAL_PROTOCOLPGM(MSG_SD_PRINTING_BYTE); + SERIAL_PROTOCOL(sdpos); + SERIAL_PROTOCOLCHAR('/'); + SERIAL_PROTOCOLLN(filesize); + } + else { + SERIAL_PROTOCOLLNPGM(MSG_SD_NOT_PRINTING); + } +} + +void CardReader::write_command(char *buf) { + char* begin = buf; + char* npos = 0; + char* end = buf + strlen(buf) - 1; + + file.writeError = false; + if ((npos = strchr(buf, 'N')) != NULL) { + begin = strchr(npos, ' ') + 1; + end = strchr(npos, '*') - 1; + } + end[1] = '\r'; + end[2] = '\n'; + end[3] = '\0'; + file.write(begin); + if (file.writeError) { + SERIAL_ERROR_START(); + SERIAL_ERRORLNPGM(MSG_SD_ERR_WRITE_TO_FILE); + } +} + +void CardReader::checkautostart(bool force) { + if (!force && (!autostart_stilltocheck || PENDING(millis(), next_autostart_ms))) + return; + + autostart_stilltocheck = false; + + if (!cardOK) { + initsd(); + if (!cardOK) return; // fail + } + + char autoname[10]; + sprintf_P(autoname, PSTR("auto%i.g"), autostart_index); + for (int8_t i = 0; i < (int8_t)strlen(autoname); i++) autoname[i] = tolower(autoname[i]); + + dir_t p; + + root.rewind(); + + bool found = false; + while (root.readDir(p, NULL) > 0) { + for (int8_t i = (int8_t)strlen((char*)p.name); i--;) p.name[i] = tolower(p.name[i]); + if (p.name[9] != '~' && strncmp((char*)p.name, autoname, 5) == 0) { + openAndPrintFile(autoname); + found = true; + } + } + if (!found) + autostart_index = -1; + else + autostart_index++; +} + +void CardReader::closefile(bool store_location) { + file.sync(); + file.close(); + saving = logging = false; + + if (store_location) { + //future: store printer state, filename and position for continuing a stopped print + // so one can unplug the printer and continue printing the next day. + } +} + +/** + * Get the name of a file in the current directory by index + */ +void CardReader::getfilename(uint16_t nr, const char * const match/*=NULL*/) { + #if ENABLED(SDSORT_CACHE_NAMES) + if (match != NULL) { + while (nr < sort_count) { + if (strcasecmp(match, sortshort[nr]) == 0) break; + nr++; + } + } + if (nr < sort_count) { + strcpy(filename, sortshort[nr]); + strcpy(longFilename, sortnames[nr]); + filenameIsDir = TEST(isDir[nr>>3], nr & 0x07); + return; + } + #endif // SDSORT_CACHE_NAMES + curDir = &workDir; + lsAction = LS_GetFilename; + nrFiles = nr; + curDir->rewind(); + lsDive("", *curDir, match); +} + +uint16_t CardReader::getnrfilenames() { + curDir = &workDir; + lsAction = LS_Count; + nrFiles = 0; + curDir->rewind(); + lsDive("", *curDir); + //SERIAL_ECHOLN(nrFiles); + return nrFiles; +} + +void CardReader::chdir(const char * relpath) { + SdFile newfile; + SdFile *parent = &root; + + if (workDir.isOpen()) parent = &workDir; + + if (!newfile.open(*parent, relpath, O_READ)) { + SERIAL_ECHO_START(); + SERIAL_ECHOPGM(MSG_SD_CANT_ENTER_SUBDIR); + SERIAL_ECHOLN(relpath); + } + else { + if (workDirDepth < MAX_DIR_DEPTH) + workDirParents[workDirDepth++] = *parent; + workDir = newfile; + #if ENABLED(SDCARD_SORT_ALPHA) + presort(); + #endif + } +} + +void CardReader::updir() { + if (workDirDepth > 0) { + workDir = workDirParents[--workDirDepth]; + #if ENABLED(SDCARD_SORT_ALPHA) + presort(); + #endif + } +} + +#if ENABLED(SDCARD_SORT_ALPHA) + + /** + * Get the name of a file in the current directory by sort-index + */ + void CardReader::getfilename_sorted(const uint16_t nr) { + getfilename( + #if ENABLED(SDSORT_GCODE) + sort_alpha && + #endif + (nr < sort_count) ? sort_order[nr] : nr + ); + } + + /** + * Read all the files and produce a sort key + * + * We can do this in 3 ways... + * - Minimal RAM: Read two filenames at a time sorting along... + * - Some RAM: Buffer the directory just for this sort + * - Most RAM: Buffer the directory and return filenames from RAM + */ + void CardReader::presort() { + + // Sorting may be turned off + #if ENABLED(SDSORT_GCODE) + if (!sort_alpha) return; + #endif + + // Throw away old sort index + flush_presort(); + + // If there are files, sort up to the limit + uint16_t fileCnt = getnrfilenames(); + if (fileCnt > 0) { + + // Never sort more than the max allowed + // If you use folders to organize, 20 may be enough + if (fileCnt > SDSORT_LIMIT) fileCnt = SDSORT_LIMIT; + + // Sort order is always needed. May be static or dynamic. + #if ENABLED(SDSORT_DYNAMIC_RAM) + sort_order = new uint8_t[fileCnt]; + #endif + + // Use RAM to store the entire directory during pre-sort. + // SDSORT_LIMIT should be set to prevent over-allocation. + #if ENABLED(SDSORT_USES_RAM) + + // If using dynamic ram for names, allocate on the heap. + #if ENABLED(SDSORT_CACHE_NAMES) + #if ENABLED(SDSORT_DYNAMIC_RAM) + sortshort = new char*[fileCnt]; + sortnames = new char*[fileCnt]; + #endif + #elif ENABLED(SDSORT_USES_STACK) + char sortnames[fileCnt][LONG_FILENAME_LENGTH]; + #endif + + // Folder sorting needs 1 bit per entry for flags. + #if HAS_FOLDER_SORTING + #if ENABLED(SDSORT_DYNAMIC_RAM) + isDir = new uint8_t[(fileCnt + 7) >> 3]; + #elif ENABLED(SDSORT_USES_STACK) + uint8_t isDir[(fileCnt + 7) >> 3]; + #endif + #endif + + #else // !SDSORT_USES_RAM + + // By default re-read the names from SD for every compare + // retaining only two filenames at a time. This is very + // slow but is safest and uses minimal RAM. + char name1[LONG_FILENAME_LENGTH + 1]; + + #endif + + if (fileCnt > 1) { + + // Init sort order. + for (uint16_t i = 0; i < fileCnt; i++) { + sort_order[i] = i; + // If using RAM then read all filenames now. + #if ENABLED(SDSORT_USES_RAM) + getfilename(i); + #if ENABLED(SDSORT_DYNAMIC_RAM) + // Use dynamic method to copy long filename + sortnames[i] = strdup(LONGEST_FILENAME); + #if ENABLED(SDSORT_CACHE_NAMES) + // When caching also store the short name, since + // we're replacing the getfilename() behavior. + sortshort[i] = strdup(filename); + #endif + #else + // Copy filenames into the static array + strcpy(sortnames[i], LONGEST_FILENAME); + #if ENABLED(SDSORT_CACHE_NAMES) + strcpy(sortshort[i], filename); + #endif + #endif + // char out[30]; + // sprintf_P(out, PSTR("---- %i %s %s"), i, filenameIsDir ? "D" : " ", sortnames[i]); + // SERIAL_ECHOLN(out); + #if HAS_FOLDER_SORTING + const uint16_t bit = i & 0x07, ind = i >> 3; + if (bit == 0) isDir[ind] = 0x00; + if (filenameIsDir) isDir[ind] |= _BV(bit); + #endif + #endif + } + + // Bubble Sort + for (uint16_t i = fileCnt; --i;) { + bool didSwap = false; + for (uint16_t j = 0; j < i; ++j) { + const uint16_t o1 = sort_order[j], o2 = sort_order[j + 1]; + + // Compare names from the array or just the two buffered names + #if ENABLED(SDSORT_USES_RAM) + #define _SORT_CMP_NODIR() (strcasecmp(sortnames[o1], sortnames[o2]) > 0) + #else + #define _SORT_CMP_NODIR() (strcasecmp(name1, name2) > 0) + #endif + + #if HAS_FOLDER_SORTING + #if ENABLED(SDSORT_USES_RAM) + // Folder sorting needs an index and bit to test for folder-ness. + const uint8_t ind1 = o1 >> 3, bit1 = o1 & 0x07, + ind2 = o2 >> 3, bit2 = o2 & 0x07; + #define _SORT_CMP_DIR(fs) \ + (((isDir[ind1] & _BV(bit1)) != 0) == ((isDir[ind2] & _BV(bit2)) != 0) \ + ? _SORT_CMP_NODIR() \ + : (isDir[fs > 0 ? ind1 : ind2] & (fs > 0 ? _BV(bit1) : _BV(bit2))) != 0) + #else + #define _SORT_CMP_DIR(fs) ((dir1 == filenameIsDir) ? _SORT_CMP_NODIR() : (fs > 0 ? dir1 : !dir1)) + #endif + #endif + + // The most economical method reads names as-needed + // throughout the loop. Slow if there are many. + #if DISABLED(SDSORT_USES_RAM) + getfilename(o1); + strcpy(name1, LONGEST_FILENAME); // save (or getfilename below will trounce it) + #if HAS_FOLDER_SORTING + bool dir1 = filenameIsDir; + #endif + getfilename(o2); + char *name2 = LONGEST_FILENAME; // use the string in-place + #endif // !SDSORT_USES_RAM + + // Sort the current pair according to settings. + if ( + #if HAS_FOLDER_SORTING + #if ENABLED(SDSORT_GCODE) + sort_folders ? _SORT_CMP_DIR(sort_folders) : _SORT_CMP_NODIR() + #else + _SORT_CMP_DIR(FOLDER_SORTING) + #endif + #else + _SORT_CMP_NODIR() + #endif + ) { + sort_order[j] = o2; + sort_order[j + 1] = o1; + didSwap = true; + } + } + if (!didSwap) break; + } + // Using RAM but not keeping names around + #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 + #endif + #endif + } + else { + sort_order[0] = 0; + #if ENABLED(SDSORT_USES_RAM) && ENABLED(SDSORT_CACHE_NAMES) + getfilename(0); + #if ENABLED(SDSORT_DYNAMIC_RAM) + sortnames = new char*[1]; + sortnames[0] = strdup(LONGEST_FILENAME); // malloc + sortshort = new char*[1]; + sortshort[0] = strdup(filename); // malloc + isDir = new uint8_t[1]; + #else + strcpy(sortnames[0], LONGEST_FILENAME); + strcpy(sortshort[0], filename); + #endif + isDir[0] = filenameIsDir ? 0x01 : 0x00; + #endif + } + + sort_count = fileCnt; + } + } + + void CardReader::flush_presort() { + if (sort_count > 0) { + #if ENABLED(SDSORT_DYNAMIC_RAM) + delete sort_order; + #if ENABLED(SDSORT_CACHE_NAMES) + for (uint8_t i = 0; i < sort_count; ++i) { + free(sortshort[i]); // strdup + free(sortnames[i]); // strdup + } + delete sortshort; + delete sortnames; + #endif + #endif + sort_count = 0; + } + } + +#endif // SDCARD_SORT_ALPHA + +void CardReader::printingHasFinished() { + stepper.synchronize(); + file.close(); + if (file_subcall_ctr > 0) { // Heading up to a parent file that called current as a procedure. + file_subcall_ctr--; + openFile(proc_filenames[file_subcall_ctr], true, true); + setIndex(filespos[file_subcall_ctr]); + startFileprint(); + } + else { + sdprinting = false; + if (SD_FINISHED_STEPPERRELEASE) + enqueue_and_echo_commands_P(PSTR(SD_FINISHED_RELEASECOMMAND)); + print_job_timer.stop(); + if (print_job_timer.duration() > 60) + enqueue_and_echo_commands_P(PSTR("M31")); + #if ENABLED(SDCARD_SORT_ALPHA) + presort(); + #endif + } +} + +#endif // SDSUPPORT diff --git a/trunk/Arduino/Marlin_1.1.6/cardreader.h b/trunk/Arduino/Marlin_1.1.6/cardreader.h new file mode 100644 index 00000000..75674a8e --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/cardreader.h @@ -0,0 +1,190 @@ +/** + * 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 . + * + */ + +#ifndef CARDREADER_H +#define CARDREADER_H + +#include "MarlinConfig.h" + +#if ENABLED(SDSUPPORT) + +#define MAX_DIR_DEPTH 10 // Maximum folder depth + +#include "SdFile.h" + +#include "types.h" +#include "enum.h" + +class CardReader { +public: + CardReader(); + + void initsd(); + void write_command(char *buf); + //files auto[0-9].g on the sd card are performed in a row + //this is to delay autostart and hence the initialisaiton of the sd card to some seconds after the normal init, so the device is available quick after a reset + + void checkautostart(bool x); + void openFile(char* name, bool read, bool push_current=false); + void openLogFile(char* name); + void removeFile(char* name); + void closefile(bool store_location=false); + void release(); + void openAndPrintFile(const char *name); + void startFileprint(); + void stopSDPrint(); + void getStatus(); + void printingHasFinished(); + + #if ENABLED(LONG_FILENAME_HOST_SUPPORT) + void printLongPath(char *path); + #endif + + void getfilename(uint16_t nr, const char* const match=NULL); + uint16_t getnrfilenames(); + + void getAbsFilename(char *t); + + void ls(); + void chdir(const char *relpath); + void updir(); + void setroot(); + + #if ENABLED(SDCARD_SORT_ALPHA) + void presort(); + void getfilename_sorted(const uint16_t nr); + #if ENABLED(SDSORT_GCODE) + FORCE_INLINE void setSortOn(bool b) { sort_alpha = b; presort(); } + FORCE_INLINE void setSortFolders(int i) { sort_folders = i; presort(); } + //FORCE_INLINE void setSortReverse(bool b) { sort_reverse = b; } + #endif + #endif + + FORCE_INLINE void pauseSDPrint() { sdprinting = false; } + FORCE_INLINE bool isFileOpen() { return file.isOpen(); } + FORCE_INLINE bool eof() { return sdpos >= filesize; } + FORCE_INLINE int16_t get() { sdpos = file.curPosition(); return (int16_t)file.read(); } + FORCE_INLINE void setIndex(long index) { sdpos = index; file.seekSet(index); } + FORCE_INLINE uint8_t percentDone() { return (isFileOpen() && filesize) ? sdpos / ((filesize + 99) / 100) : 0; } + FORCE_INLINE char* getWorkDirName() { workDir.getFilename(filename); return filename; } + +public: + bool saving, logging, sdprinting, cardOK, filenameIsDir; + char filename[FILENAME_LENGTH], longFilename[LONG_FILENAME_LENGTH]; + int autostart_index; +private: + SdFile root, *curDir, workDir, workDirParents[MAX_DIR_DEPTH]; + uint8_t workDirDepth; + + // Sort files and folders alphabetically. + #if ENABLED(SDCARD_SORT_ALPHA) + uint16_t sort_count; // Count of sorted items in the current directory + #if ENABLED(SDSORT_GCODE) + bool sort_alpha; // Flag to enable / disable the feature + int sort_folders; // Flag to enable / disable folder sorting + //bool sort_reverse; // Flag to enable / disable reverse sorting + #endif + + // By default the sort index is static + #if ENABLED(SDSORT_DYNAMIC_RAM) + uint8_t *sort_order; + #else + uint8_t sort_order[SDSORT_LIMIT]; + #endif + + // Cache filenames to speed up SD menus. + #if ENABLED(SDSORT_USES_RAM) + + // If using dynamic ram for names, allocate on the heap. + #if ENABLED(SDSORT_CACHE_NAMES) + #if ENABLED(SDSORT_DYNAMIC_RAM) + char **sortshort, **sortnames; + #else + char sortshort[SDSORT_LIMIT][FILENAME_LENGTH]; + char sortnames[SDSORT_LIMIT][LONG_FILENAME_LENGTH]; + #endif + #elif DISABLED(SDSORT_USES_STACK) + char sortnames[SDSORT_LIMIT][LONG_FILENAME_LENGTH]; + #endif + + // Folder sorting uses an isDir array when caching items. + #if HAS_FOLDER_SORTING + #if ENABLED(SDSORT_DYNAMIC_RAM) + uint8_t *isDir; + #elif ENABLED(SDSORT_CACHE_NAMES) || DISABLED(SDSORT_USES_STACK) + uint8_t isDir[(SDSORT_LIMIT+7)>>3]; + #endif + #endif + + #endif // SDSORT_USES_RAM + + #endif // SDCARD_SORT_ALPHA + + Sd2Card card; + SdVolume volume; + SdFile file; + + #define SD_PROCEDURE_DEPTH 1 + #define MAXPATHNAMELENGTH (FILENAME_LENGTH*MAX_DIR_DEPTH + MAX_DIR_DEPTH + 1) + uint8_t file_subcall_ctr; + uint32_t filespos[SD_PROCEDURE_DEPTH]; + char proc_filenames[SD_PROCEDURE_DEPTH][MAXPATHNAMELENGTH]; + uint32_t filesize; + uint32_t sdpos; + + millis_t next_autostart_ms; + bool autostart_stilltocheck; //the sd start is delayed, because otherwise the serial cannot answer fast enought to make contact with the hostsoftware. + + LsAction lsAction; //stored for recursion. + uint16_t nrFiles; //counter for the files in the current directory and recycled as position counter for getting the nrFiles'th name in the directory. + char* diveDirName; + void lsDive(const char *prepend, SdFile parent, const char * const match=NULL); + + #if ENABLED(SDCARD_SORT_ALPHA) + void flush_presort(); + #endif +}; + +extern CardReader card; + +#define IS_SD_PRINTING (card.sdprinting) +#define IS_SD_FILE_OPEN (card.isFileOpen()) + +#if PIN_EXISTS(SD_DETECT) + #if ENABLED(SD_DETECT_INVERTED) + #define IS_SD_INSERTED (READ(SD_DETECT_PIN) != 0) + #else + #define IS_SD_INSERTED (READ(SD_DETECT_PIN) == 0) + #endif +#else + //No card detect line? Assume the card is inserted. + #define IS_SD_INSERTED true +#endif + +#else + +#define IS_SD_PRINTING (false) +#define IS_SD_FILE_OPEN (false) + +#endif // SDSUPPORT + +#endif // __CARDREADER_H diff --git a/trunk/Arduino/Marlin_1.1.6/circularqueue.h b/trunk/Arduino/Marlin_1.1.6/circularqueue.h new file mode 100644 index 00000000..9aafb99a --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/circularqueue.h @@ -0,0 +1,145 @@ +/** + * 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 . + * + */ + +#ifndef __CIRCULARQUEUE_H__ +#define __CIRCULARQUEUE_H__ + +#include + +/** + * @brief Circular Queue class + * @details Implementation of the classic ring buffer data structure + */ +template +class CircularQueue { + private: + + /** + * @brief Buffer structure + * @details This structure consolidates all the overhead required to handle + * a circular queue such as the pointers and the buffer vector. + */ + struct buffer_t { + uint8_t head; + uint8_t tail; + uint8_t count; + uint8_t size; + T queue[N]; + } buffer; + + public: + /** + * @brief Class constructor + * @details This class requires two template parameters, T defines the type + * of item this queue will handle and N defines the maximum number of + * items that can be stored on the queue. + */ + CircularQueue() { + this->buffer.size = N; + this->buffer.count = this->buffer.head = this->buffer.tail = 0; + } + + /** + * @brief Removes and returns a item from the queue + * @details Removes the oldest item on the queue, pointed to by the + * buffer_t head field. The item is returned to the caller. + * @return type T item + */ + T dequeue() { + if (this->isEmpty()) return T(); + + uint8_t index = this->buffer.head; + + --this->buffer.count; + if (++this->buffer.head == this->buffer.size) + this->buffer.head = 0; + + return this->buffer.queue[index]; + } + + /** + * @brief Adds an item to the queue + * @details Adds an item to the queue on the location pointed by the buffer_t + * tail variable. Returns false if no queue space is available. + * @param item Item to be added to the queue + * @return true if the operation was successful + */ + bool enqueue(T const &item) { + if (this->isFull()) return false; + + this->buffer.queue[this->buffer.tail] = item; + + ++this->buffer.count; + if (++this->buffer.tail == this->buffer.size) + this->buffer.tail = 0; + + return true; + } + + /** + * @brief Checks if the queue has no items + * @details Returns true if there are no items on the queue, false otherwise. + * @return true if queue is empty + */ + bool isEmpty() { + return this->buffer.count == 0; + } + + /** + * @brief Checks if the queue is full + * @details Returns true if the queue is full, false otherwise. + * @return true if queue is full + */ + bool isFull() { + return this->buffer.count == this->buffer.size; + } + + /** + * @brief Gets the queue size + * @details Returns the maximum number of items a queue can have. + * @return the queue size + */ + uint8_t size() { + return this->buffer.size; + } + + /** + * @brief Gets the next item from the queue without removing it + * @details Returns the next item in the queue without removing it + * or updating the pointers. + * @return first item in the queue + */ + T peek() { + return this->buffer.queue[this->buffer.head]; + } + + /** + * @brief Gets the number of items on the queue + * @details Returns the current number of items stored on the queue. + * @return number of items in the queue + */ + uint8_t count() { + return this->buffer.count; + } +}; + +#endif diff --git a/trunk/Arduino/Marlin_1.1.6/configuration_store.cpp b/trunk/Arduino/Marlin_1.1.6/configuration_store.cpp new file mode 100644 index 00000000..4fa9db91 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/configuration_store.cpp @@ -0,0 +1,1852 @@ +/** + * 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 . + * + */ + +/** + * configuration_store.cpp + * + * Settings and EEPROM storage + * + * IMPORTANT: Whenever there are changes made to the variables stored in EEPROM + * in the functions below, also increment the version number. This makes sure that + * the default values are used whenever there is a change to the data, to prevent + * wrong data being written to the variables. + * + * 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. + * + */ + +#define EEPROM_VERSION "V41" + +// Change EEPROM version if these are changed: +#define EEPROM_OFFSET 100 + +/** + * V41 EEPROM Layout: + * + * 100 Version (char x4) + * 104 EEPROM CRC16 (uint16_t) + * + * 106 E_STEPPERS (uint8_t) + * 107 M92 XYZE planner.axis_steps_per_mm (float x4 ... x8) + * 123 M203 XYZE planner.max_feedrate_mm_s (float x4 ... x8) + * 139 M201 XYZE planner.max_acceleration_mm_per_s2 (uint32_t x4 ... x8) + * 155 M204 P planner.acceleration (float) + * 159 M204 R planner.retract_acceleration (float) + * 163 M204 T planner.travel_acceleration (float) + * 167 M205 S planner.min_feedrate_mm_s (float) + * 171 M205 T planner.min_travel_feedrate_mm_s (float) + * 175 M205 B planner.min_segment_time (ulong) + * 179 M205 X planner.max_jerk[X_AXIS] (float) + * 183 M205 Y planner.max_jerk[Y_AXIS] (float) + * 187 M205 Z planner.max_jerk[Z_AXIS] (float) + * 191 M205 E planner.max_jerk[E_AXIS] (float) + * 195 M206 XYZ home_offset (float x3) + * 207 M218 XYZ hotend_offset (float x3 per additional hotend) + * + * Global Leveling: + * 219 z_fade_height (float) + * + * MESH_BED_LEVELING: 43 bytes + * 223 M420 S from mbl.status (bool) + * 224 mbl.z_offset (float) + * 228 GRID_MAX_POINTS_X (uint8_t) + * 229 GRID_MAX_POINTS_Y (uint8_t) + * 230 G29 S3 XYZ z_values[][] (float x9, up to float x81) +288 + * + * HAS_BED_PROBE: 4 bytes + * 266 M851 zprobe_zoffset (float) + * + * ABL_PLANAR: 36 bytes + * 270 planner.bed_level_matrix (matrix_3x3 = float x9) + * + * AUTO_BED_LEVELING_BILINEAR: 47 bytes + * 306 GRID_MAX_POINTS_X (uint8_t) + * 307 GRID_MAX_POINTS_Y (uint8_t) + * 308 bilinear_grid_spacing (int x2) + * 312 G29 L F bilinear_start (int x2) + * 316 z_values[][] (float x9, up to float x256) +988 + * + * AUTO_BED_LEVELING_UBL: 6 bytes + * 324 G29 A ubl.state.active (bool) + * 325 G29 Z ubl.state.z_offset (float) + * 329 G29 S ubl.state.storage_slot (int8_t) + * + * DELTA: 48 bytes + * 348 M666 XYZ endstop_adj (float x3) + * 360 M665 R delta_radius (float) + * 364 M665 L delta_diagonal_rod (float) + * 368 M665 S delta_segments_per_second (float) + * 372 M665 B delta_calibration_radius (float) + * 376 M665 X delta_tower_angle_trim[A] (float) + * 380 M665 Y delta_tower_angle_trim[B] (float) + * 384 M665 Z delta_tower_angle_trim[C] (float) + * + * Z_DUAL_ENDSTOPS: 48 bytes + * 348 M666 Z z_endstop_adj (float) + * --- dummy data (float x11) + * + * ULTIPANEL: 6 bytes + * 396 M145 S0 H lcd_preheat_hotend_temp (int x2) + * 400 M145 S0 B lcd_preheat_bed_temp (int x2) + * 404 M145 S0 F lcd_preheat_fan_speed (int x2) + * + * PIDTEMP: 66 bytes + * 408 M301 E0 PIDC Kp[0], Ki[0], Kd[0], Kc[0] (float x4) + * 424 M301 E1 PIDC Kp[1], Ki[1], Kd[1], Kc[1] (float x4) + * 440 M301 E2 PIDC Kp[2], Ki[2], Kd[2], Kc[2] (float x4) + * 456 M301 E3 PIDC Kp[3], Ki[3], Kd[3], Kc[3] (float x4) + * 472 M301 E4 PIDC Kp[3], Ki[3], Kd[3], Kc[3] (float x4) + * 488 M301 L lpq_len (int) + * + * PIDTEMPBED: 12 bytes + * 490 M304 PID thermalManager.bedKp, .bedKi, .bedKd (float x3) + * + * DOGLCD: 2 bytes + * 502 M250 C lcd_contrast (uint16_t) + * + * FWRETRACT: 33 bytes + * 504 M209 S autoretract_enabled (bool) + * 505 M207 S retract_length (float) + * 509 M207 F retract_feedrate_mm_s (float) + * 513 M207 Z retract_zlift (float) + * 517 M208 S retract_recover_length (float) + * 521 M208 F retract_recover_feedrate_mm_s (float) + * 525 M207 W swap_retract_length (float) + * 529 M208 W swap_retract_recover_length (float) + * 533 M208 R swap_retract_recover_feedrate_mm_s (float) + * + * Volumetric Extrusion: 21 bytes + * 537 M200 D volumetric_enabled (bool) + * 538 M200 T D filament_size (float x5) (T0..3) + * + * HAVE_TMC2130: 20 bytes + * 558 M906 X Stepper X current (uint16_t) + * 560 M906 Y Stepper Y current (uint16_t) + * 562 M906 Z Stepper Z current (uint16_t) + * 564 M906 X2 Stepper X2 current (uint16_t) + * 566 M906 Y2 Stepper Y2 current (uint16_t) + * 568 M906 Z2 Stepper Z2 current (uint16_t) + * 570 M906 E0 Stepper E0 current (uint16_t) + * 572 M906 E1 Stepper E1 current (uint16_t) + * 574 M906 E2 Stepper E2 current (uint16_t) + * 576 M906 E3 Stepper E3 current (uint16_t) + * 580 M906 E4 Stepper E4 current (uint16_t) + * + * LIN_ADVANCE: 8 bytes + * 584 M900 K extruder_advance_k (float) + * 588 M900 WHD advance_ed_ratio (float) + * + * HAS_MOTOR_CURRENT_PWM: + * 592 M907 X Stepper XY current (uint32_t) + * 596 M907 Z Stepper Z current (uint32_t) + * 600 M907 E Stepper E current (uint32_t) + * + * 604 Minimum end-point + * 1925 (604 + 36 + 9 + 288 + 988) Maximum end-point + * + * ======================================================================== + * meshes_begin (between max and min end-point, directly above) + * -- MESHES -- + * meshes_end + * -- MAT (Mesh Allocation Table) -- 128 bytes (placeholder size) + * mat_end = E2END (0xFFF) + * + */ +#include "configuration_store.h" + +MarlinSettings settings; + +#include "Marlin.h" +#include "language.h" +#include "endstops.h" +#include "planner.h" +#include "temperature.h" +#include "ultralcd.h" +#include "stepper.h" + +#if ENABLED(INCH_MODE_SUPPORT) || (ENABLED(ULTIPANEL) && ENABLED(TEMPERATURE_UNITS_SUPPORT)) + #include "gcode.h" +#endif + +#if ENABLED(MESH_BED_LEVELING) + #include "mesh_bed_leveling.h" +#endif + +#if ENABLED(HAVE_TMC2130) + #include "stepper_indirection.h" +#endif + +#if ENABLED(AUTO_BED_LEVELING_UBL) + #include "ubl.h" +#endif + +#if ENABLED(AUTO_BED_LEVELING_BILINEAR) + extern void refresh_bed_level(); +#endif + +/** + * Post-process after Retrieve or Reset + */ +void MarlinSettings::postprocess() { + // steps per s2 needs to be updated to agree with units per s2 + planner.reset_acceleration_rates(); + + // 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(delta_radius, delta_diagonal_rod, delta_tower_angle_trim); + #endif + + // Refresh steps_to_mm with the reciprocal of axis_steps_per_mm + // and init stepper.count[], planner.position[] with current_position + planner.refresh_positioning(); + + #if ENABLED(PIDTEMP) + thermalManager.updatePID(); + #endif + + calculate_volumetric_multipliers(); + + #if HAS_HOME_OFFSET || ENABLED(DUAL_X_CARRIAGE) + // Software endstops depend on home_offset + LOOP_XYZ(i) update_software_endstops((AxisEnum)i); + #endif + + #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) + set_z_fade_height(planner.z_fade_height); + #endif + + #if HAS_BED_PROBE + refresh_zprobe_zoffset(); + #endif + + #if ENABLED(AUTO_BED_LEVELING_BILINEAR) + refresh_bed_level(); + //set_bed_leveling_enabled(leveling_is_on); + #endif + + #if HAS_MOTOR_CURRENT_PWM + stepper.refresh_motor_power(); + #endif +} + +#if ENABLED(EEPROM_SETTINGS) + + #define DUMMY_PID_VALUE 3000.0f + #define EEPROM_START() int eeprom_index = EEPROM_OFFSET + #define EEPROM_SKIP(VAR) eeprom_index += sizeof(VAR) + #define EEPROM_WRITE(VAR) write_data(eeprom_index, (uint8_t*)&VAR, sizeof(VAR), &working_crc) + #define EEPROM_READ(VAR) read_data(eeprom_index, (uint8_t*)&VAR, sizeof(VAR), &working_crc) + #define EEPROM_ASSERT(TST,ERR) if (!(TST)) do{ SERIAL_ERROR_START(); SERIAL_ERRORLNPGM(ERR); eeprom_read_error = true; }while(0) + + const char version[4] = EEPROM_VERSION; + + bool MarlinSettings::eeprom_error; + + #if ENABLED(AUTO_BED_LEVELING_UBL) + int MarlinSettings::meshes_begin; + #endif + + void MarlinSettings::write_data(int &pos, const uint8_t *value, uint16_t size, uint16_t *crc) { + if (eeprom_error) return; + 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_START(); + SERIAL_ECHOLNPGM(MSG_ERR_EEPROM_WRITE); + eeprom_error = true; + return; + } + } + crc16(crc, &v, 1); + pos++; + value++; + }; + } + + void MarlinSettings::read_data(int &pos, uint8_t* value, uint16_t size, uint16_t *crc) { + if (eeprom_error) return; + do { + uint8_t c = eeprom_read_byte((unsigned char*)pos); + *value = c; + crc16(crc, &c, 1); + pos++; + value++; + } while (--size); + } + + /** + * M500 - Store Configuration + */ + bool MarlinSettings::save() { + float dummy = 0.0f; + char ver[4] = "000"; + + uint16_t working_crc = 0; + + EEPROM_START(); + + eeprom_error = false; + + EEPROM_WRITE(ver); // invalidate data first + EEPROM_SKIP(working_crc); // Skip the checksum slot + + working_crc = 0; // clear before first "real data" + + const uint8_t esteppers = COUNT(planner.axis_steps_per_mm) - XYZ; + EEPROM_WRITE(esteppers); + + EEPROM_WRITE(planner.axis_steps_per_mm); + EEPROM_WRITE(planner.max_feedrate_mm_s); + EEPROM_WRITE(planner.max_acceleration_mm_per_s2); + + EEPROM_WRITE(planner.acceleration); + EEPROM_WRITE(planner.retract_acceleration); + EEPROM_WRITE(planner.travel_acceleration); + EEPROM_WRITE(planner.min_feedrate_mm_s); + EEPROM_WRITE(planner.min_travel_feedrate_mm_s); + EEPROM_WRITE(planner.min_segment_time); + EEPROM_WRITE(planner.max_jerk); + #if !HAS_HOME_OFFSET + const float home_offset[XYZ] = { 0 }; + #endif + #if ENABLED(DELTA) + dummy = 0.0; + EEPROM_WRITE(dummy); + EEPROM_WRITE(dummy); + dummy = DELTA_HEIGHT + home_offset[Z_AXIS]; + EEPROM_WRITE(dummy); + #else + EEPROM_WRITE(home_offset); + #endif + + #if HOTENDS > 1 + // Skip hotend 0 which must be 0 + for (uint8_t e = 1; e < HOTENDS; e++) + LOOP_XYZ(i) EEPROM_WRITE(hotend_offset[i][e]); + #endif + + // + // Global Leveling + // + + #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) + const float zfh = planner.z_fade_height; + #else + const float zfh = 10.0; + #endif + EEPROM_WRITE(zfh); + + // + // Mesh Bed Leveling + // + + #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 bool leveling_is_on = TEST(mbl.status, MBL_STATUS_HAS_MESH_BIT); + const uint8_t mesh_num_x = GRID_MAX_POINTS_X, mesh_num_y = GRID_MAX_POINTS_Y; + EEPROM_WRITE(leveling_is_on); + EEPROM_WRITE(mbl.z_offset); + EEPROM_WRITE(mesh_num_x); + EEPROM_WRITE(mesh_num_y); + EEPROM_WRITE(mbl.z_values); + #else // For disabled MBL write a default mesh + const bool leveling_is_on = false; + dummy = 0.0f; + const uint8_t mesh_num_x = 3, mesh_num_y = 3; + EEPROM_WRITE(leveling_is_on); + 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); + #endif // MESH_BED_LEVELING + + #if !HAS_BED_PROBE + const float zprobe_zoffset = 0; + #endif + EEPROM_WRITE(zprobe_zoffset); + + // + // Planar Bed Leveling matrix + // + + #if ABL_PLANAR + EEPROM_WRITE(planner.bed_level_matrix); + #else + dummy = 0.0; + for (uint8_t q = 9; q--;) EEPROM_WRITE(dummy); + #endif + + // + // Bilinear Auto Bed Leveling + // + + #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 int bilinear_start[2] = { 0 }, bilinear_grid_spacing[2] = { 0 }; + dummy = 0.0f; + 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 // AUTO_BED_LEVELING_BILINEAR + + #if ENABLED(AUTO_BED_LEVELING_UBL) + EEPROM_WRITE(ubl.state.active); + EEPROM_WRITE(ubl.state.z_offset); + EEPROM_WRITE(ubl.state.storage_slot); + #else + const bool ubl_active = false; + dummy = 0.0f; + const int8_t storage_slot = -1; + EEPROM_WRITE(ubl_active); + EEPROM_WRITE(dummy); + EEPROM_WRITE(storage_slot); + #endif // AUTO_BED_LEVELING_UBL + + // 10 floats for DELTA / Z_DUAL_ENDSTOPS + #if ENABLED(DELTA) + EEPROM_WRITE(endstop_adj); // 3 floats + EEPROM_WRITE(delta_radius); // 1 float + EEPROM_WRITE(delta_diagonal_rod); // 1 float + EEPROM_WRITE(delta_segments_per_second); // 1 float + EEPROM_WRITE(delta_calibration_radius); // 1 float + EEPROM_WRITE(delta_tower_angle_trim); // 3 floats + dummy = 0.0f; + for (uint8_t q = 2; q--;) EEPROM_WRITE(dummy); + #elif ENABLED(Z_DUAL_ENDSTOPS) + EEPROM_WRITE(z_endstop_adj); // 1 float + dummy = 0.0f; + for (uint8_t q = 11; q--;) EEPROM_WRITE(dummy); + #else + dummy = 0.0f; + for (uint8_t q = 12; q--;) EEPROM_WRITE(dummy); + #endif + + #if DISABLED(ULTIPANEL) + constexpr int lcd_preheat_hotend_temp[2] = { PREHEAT_1_TEMP_HOTEND, PREHEAT_2_TEMP_HOTEND }, + lcd_preheat_bed_temp[2] = { PREHEAT_1_TEMP_BED, PREHEAT_2_TEMP_BED }, + lcd_preheat_fan_speed[2] = { PREHEAT_1_FAN_SPEED, PREHEAT_2_FAN_SPEED }; + #endif + + EEPROM_WRITE(lcd_preheat_hotend_temp); + EEPROM_WRITE(lcd_preheat_bed_temp); + EEPROM_WRITE(lcd_preheat_fan_speed); + + for (uint8_t e = 0; e < MAX_EXTRUDERS; e++) { + + #if ENABLED(PIDTEMP) + if (e < HOTENDS) { + EEPROM_WRITE(PID_PARAM(Kp, e)); + EEPROM_WRITE(PID_PARAM(Ki, e)); + EEPROM_WRITE(PID_PARAM(Kd, e)); + #if ENABLED(PID_EXTRUSION_SCALING) + EEPROM_WRITE(PID_PARAM(Kc, e)); + #else + dummy = 1.0f; // 1.0 = default kc + EEPROM_WRITE(dummy); + #endif + } + else + #endif // !PIDTEMP + { + dummy = DUMMY_PID_VALUE; // When read, will not change the existing value + EEPROM_WRITE(dummy); // Kp + dummy = 0.0f; + for (uint8_t q = 3; q--;) EEPROM_WRITE(dummy); // Ki, Kd, Kc + } + + } // Hotends Loop + + #if DISABLED(PID_EXTRUSION_SCALING) + int lpq_len = 20; + #endif + EEPROM_WRITE(lpq_len); + + #if DISABLED(PIDTEMPBED) + dummy = DUMMY_PID_VALUE; + for (uint8_t q = 3; q--;) EEPROM_WRITE(dummy); + #else + EEPROM_WRITE(thermalManager.bedKp); + EEPROM_WRITE(thermalManager.bedKi); + EEPROM_WRITE(thermalManager.bedKd); + #endif + + #if !HAS_LCD_CONTRAST + const uint16_t lcd_contrast = 32; + #endif + EEPROM_WRITE(lcd_contrast); + + #if DISABLED(FWRETRACT) + const bool autoretract_enabled = false; + const float retract_length = 3, + retract_feedrate_mm_s = 45, + retract_zlift = 0, + retract_recover_length = 0, + retract_recover_feedrate_mm_s = 0, + swap_retract_length = 13, + swap_retract_recover_length = 0, + swap_retract_recover_feedrate_mm_s = 8; + #endif + EEPROM_WRITE(autoretract_enabled); + EEPROM_WRITE(retract_length); + EEPROM_WRITE(retract_feedrate_mm_s); + EEPROM_WRITE(retract_zlift); + EEPROM_WRITE(retract_recover_length); + EEPROM_WRITE(retract_recover_feedrate_mm_s); + EEPROM_WRITE(swap_retract_length); + EEPROM_WRITE(swap_retract_recover_length); + EEPROM_WRITE(swap_retract_recover_feedrate_mm_s); + + EEPROM_WRITE(volumetric_enabled); + + // Save filament sizes + for (uint8_t q = 0; q < MAX_EXTRUDERS; q++) { + if (q < COUNT(filament_size)) dummy = filament_size[q]; + EEPROM_WRITE(dummy); + } + + // Save TMC2130 Configuration, and placeholder values + uint16_t val; + #if ENABLED(HAVE_TMC2130) + #if ENABLED(X_IS_TMC2130) + val = stepperX.getCurrent(); + #else + val = 0; + #endif + EEPROM_WRITE(val); + #if ENABLED(Y_IS_TMC2130) + val = stepperY.getCurrent(); + #else + val = 0; + #endif + EEPROM_WRITE(val); + #if ENABLED(Z_IS_TMC2130) + val = stepperZ.getCurrent(); + #else + val = 0; + #endif + EEPROM_WRITE(val); + #if ENABLED(X2_IS_TMC2130) + val = stepperX2.getCurrent(); + #else + val = 0; + #endif + EEPROM_WRITE(val); + #if ENABLED(Y2_IS_TMC2130) + val = stepperY2.getCurrent(); + #else + val = 0; + #endif + EEPROM_WRITE(val); + #if ENABLED(Z2_IS_TMC2130) + val = stepperZ2.getCurrent(); + #else + val = 0; + #endif + EEPROM_WRITE(val); + #if ENABLED(E0_IS_TMC2130) + val = stepperE0.getCurrent(); + #else + val = 0; + #endif + EEPROM_WRITE(val); + #if ENABLED(E1_IS_TMC2130) + val = stepperE1.getCurrent(); + #else + val = 0; + #endif + EEPROM_WRITE(val); + #if ENABLED(E2_IS_TMC2130) + val = stepperE2.getCurrent(); + #else + val = 0; + #endif + EEPROM_WRITE(val); + #if ENABLED(E3_IS_TMC2130) + val = stepperE3.getCurrent(); + #else + val = 0; + #endif + EEPROM_WRITE(val); + #if ENABLED(E4_IS_TMC2130) + val = stepperE4.getCurrent(); + #else + val = 0; + #endif + EEPROM_WRITE(val); + #else + val = 0; + for (uint8_t q = 11; q--;) EEPROM_WRITE(val); + #endif + + // + // Linear Advance + // + + #if ENABLED(LIN_ADVANCE) + EEPROM_WRITE(planner.extruder_advance_k); + EEPROM_WRITE(planner.advance_ed_ratio); + #else + dummy = 0.0f; + EEPROM_WRITE(dummy); + EEPROM_WRITE(dummy); + #endif + + #if HAS_MOTOR_CURRENT_PWM + for (uint8_t q = 3; q--;) EEPROM_WRITE(stepper.motor_current_setting[q]); + #else + const uint32_t dummyui32 = 0; + for (uint8_t q = 3; q--;) EEPROM_WRITE(dummyui32); + #endif + + if (!eeprom_error) { + const int eeprom_size = eeprom_index; + + const uint16_t final_crc = working_crc; + + // Write the EEPROM header + eeprom_index = EEPROM_OFFSET; + + EEPROM_WRITE(version); + EEPROM_WRITE(final_crc); + + // Report storage size + #if ENABLED(EEPROM_CHITCHAT) + SERIAL_ECHO_START(); + SERIAL_ECHOPAIR("Settings Stored (", eeprom_size - (EEPROM_OFFSET)); + SERIAL_ECHOPAIR(" bytes; crc ", (uint32_t)final_crc); + SERIAL_ECHOLNPGM(")"); + #endif + } + + #if ENABLED(UBL_SAVE_ACTIVE_ON_M500) + if (ubl.state.storage_slot >= 0) + store_mesh(ubl.state.storage_slot); + #endif + + return !eeprom_error; + } + + /** + * M501 - Retrieve Configuration + */ + bool MarlinSettings::load() { + uint16_t working_crc = 0; + + EEPROM_START(); + + char stored_ver[4]; + EEPROM_READ(stored_ver); + + uint16_t stored_crc; + EEPROM_READ(stored_crc); + + // Version has to match or defaults are used + if (strncmp(version, stored_ver, 3) != 0) { + if (stored_ver[0] != 'V') { + stored_ver[0] = '?'; + stored_ver[1] = '\0'; + } + #if ENABLED(EEPROM_CHITCHAT) + SERIAL_ECHO_START(); + SERIAL_ECHOPGM("EEPROM version mismatch "); + SERIAL_ECHOPAIR("(EEPROM=", stored_ver); + SERIAL_ECHOLNPGM(" Marlin=" EEPROM_VERSION ")"); + #endif + reset(); + } + else { + float dummy = 0; + bool dummyb; + + working_crc = 0; //clear before reading first "real data" + + // Number of esteppers may change + uint8_t esteppers; + EEPROM_READ(esteppers); + + // Get only the number of E stepper parameters previously stored + // Any steppers added later are set to their defaults + const float def1[] = DEFAULT_AXIS_STEPS_PER_UNIT, def2[] = DEFAULT_MAX_FEEDRATE; + const uint32_t def3[] = DEFAULT_MAX_ACCELERATION; + float tmp1[XYZ + esteppers], tmp2[XYZ + esteppers]; + uint32_t tmp3[XYZ + esteppers]; + EEPROM_READ(tmp1); + EEPROM_READ(tmp2); + EEPROM_READ(tmp3); + LOOP_XYZE_N(i) { + planner.axis_steps_per_mm[i] = i < XYZ + esteppers ? tmp1[i] : def1[i < COUNT(def1) ? i : COUNT(def1) - 1]; + planner.max_feedrate_mm_s[i] = i < XYZ + esteppers ? tmp2[i] : def2[i < COUNT(def2) ? i : COUNT(def2) - 1]; + planner.max_acceleration_mm_per_s2[i] = i < XYZ + esteppers ? tmp3[i] : def3[i < COUNT(def3) ? i : COUNT(def3) - 1]; + } + + EEPROM_READ(planner.acceleration); + EEPROM_READ(planner.retract_acceleration); + EEPROM_READ(planner.travel_acceleration); + EEPROM_READ(planner.min_feedrate_mm_s); + EEPROM_READ(planner.min_travel_feedrate_mm_s); + EEPROM_READ(planner.min_segment_time); + EEPROM_READ(planner.max_jerk); + + #if !HAS_HOME_OFFSET + float home_offset[XYZ]; + #endif + EEPROM_READ(home_offset); + + #if ENABLED(DELTA) + home_offset[X_AXIS] = 0.0; + home_offset[Y_AXIS] = 0.0; + home_offset[Z_AXIS] -= DELTA_HEIGHT; + #endif + + #if HOTENDS > 1 + // Skip hotend 0 which must be 0 + for (uint8_t e = 1; e < HOTENDS; e++) + LOOP_XYZ(i) EEPROM_READ(hotend_offset[i][e]); + #endif + + // + // Global Leveling + // + + #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) + EEPROM_READ(planner.z_fade_height); + #else + EEPROM_READ(dummy); + #endif + + // + // Mesh (Manual) Bed Leveling + // + + bool leveling_is_on; + uint8_t mesh_num_x, mesh_num_y; + EEPROM_READ(leveling_is_on); + EEPROM_READ(dummy); + EEPROM_READ(mesh_num_x); + EEPROM_READ(mesh_num_y); + + #if ENABLED(MESH_BED_LEVELING) + mbl.status = leveling_is_on ? _BV(MBL_STATUS_HAS_MESH_BIT) : 0; + mbl.z_offset = dummy; + 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); + } + else { + // EEPROM data is stale + mbl.reset(); + for (uint16_t q = mesh_num_x * mesh_num_y; q--;) EEPROM_READ(dummy); + } + #else + // MBL is disabled - skip the stored data + for (uint16_t q = mesh_num_x * mesh_num_y; q--;) EEPROM_READ(dummy); + #endif // MESH_BED_LEVELING + + #if !HAS_BED_PROBE + float zprobe_zoffset; + #endif + EEPROM_READ(zprobe_zoffset); + + // + // Planar Bed Leveling matrix + // + + #if ABL_PLANAR + EEPROM_READ(planner.bed_level_matrix); + #else + for (uint8_t q = 9; q--;) EEPROM_READ(dummy); + #endif + + // + // Bilinear Auto Bed Leveling + // + + uint8_t grid_max_x, grid_max_y; + EEPROM_READ(grid_max_x); // 1 byte + EEPROM_READ(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) { + set_bed_leveling_enabled(false); + EEPROM_READ(bilinear_grid_spacing); // 2 ints + EEPROM_READ(bilinear_start); // 2 ints + EEPROM_READ(z_values); // 9 to 256 floats + } + else // EEPROM data is stale + #endif // AUTO_BED_LEVELING_BILINEAR + { + // Skip past disabled (or stale) Bilinear Grid data + int bgs[2], bs[2]; + EEPROM_READ(bgs); + EEPROM_READ(bs); + for (uint16_t q = grid_max_x * grid_max_y; q--;) EEPROM_READ(dummy); + } + + #if ENABLED(AUTO_BED_LEVELING_UBL) + EEPROM_READ(ubl.state.active); + EEPROM_READ(ubl.state.z_offset); + EEPROM_READ(ubl.state.storage_slot); + #else + uint8_t dummyui8; + EEPROM_READ(dummyb); + EEPROM_READ(dummy); + EEPROM_READ(dummyui8); + #endif // AUTO_BED_LEVELING_UBL + + #if ENABLED(DELTA) + EEPROM_READ(endstop_adj); // 3 floats + EEPROM_READ(delta_radius); // 1 float + EEPROM_READ(delta_diagonal_rod); // 1 float + EEPROM_READ(delta_segments_per_second); // 1 float + EEPROM_READ(delta_calibration_radius); // 1 float + EEPROM_READ(delta_tower_angle_trim); // 3 floats + dummy = 0.0f; + for (uint8_t q=2; q--;) EEPROM_READ(dummy); + #elif ENABLED(Z_DUAL_ENDSTOPS) + EEPROM_READ(z_endstop_adj); + dummy = 0.0f; + for (uint8_t q=11; q--;) EEPROM_READ(dummy); + #else + dummy = 0.0f; + for (uint8_t q=12; q--;) EEPROM_READ(dummy); + #endif + + #if DISABLED(ULTIPANEL) + int lcd_preheat_hotend_temp[2], lcd_preheat_bed_temp[2], lcd_preheat_fan_speed[2]; + #endif + + EEPROM_READ(lcd_preheat_hotend_temp); + EEPROM_READ(lcd_preheat_bed_temp); + EEPROM_READ(lcd_preheat_fan_speed); + + //EEPROM_ASSERT( + // WITHIN(lcd_preheat_fan_speed, 0, 255), + // "lcd_preheat_fan_speed out of range" + //); + + #if ENABLED(PIDTEMP) + for (uint8_t e = 0; e < MAX_EXTRUDERS; e++) { + EEPROM_READ(dummy); // Kp + if (e < HOTENDS && dummy != DUMMY_PID_VALUE) { + // do not need to scale PID values as the values in EEPROM are already scaled + PID_PARAM(Kp, e) = dummy; + EEPROM_READ(PID_PARAM(Ki, e)); + EEPROM_READ(PID_PARAM(Kd, e)); + #if ENABLED(PID_EXTRUSION_SCALING) + EEPROM_READ(PID_PARAM(Kc, e)); + #else + EEPROM_READ(dummy); + #endif + } + else { + for (uint8_t q=3; q--;) EEPROM_READ(dummy); // Ki, Kd, Kc + } + } + #else // !PIDTEMP + // 4 x 4 = 16 slots for PID parameters + for (uint8_t q = MAX_EXTRUDERS * 4; q--;) EEPROM_READ(dummy); // Kp, Ki, Kd, Kc + #endif // !PIDTEMP + + #if DISABLED(PID_EXTRUSION_SCALING) + int lpq_len; + #endif + EEPROM_READ(lpq_len); + + #if ENABLED(PIDTEMPBED) + EEPROM_READ(dummy); // bedKp + if (dummy != DUMMY_PID_VALUE) { + thermalManager.bedKp = dummy; + EEPROM_READ(thermalManager.bedKi); + EEPROM_READ(thermalManager.bedKd); + } + #else + for (uint8_t q=3; q--;) EEPROM_READ(dummy); // bedKp, bedKi, bedKd + #endif + + #if !HAS_LCD_CONTRAST + uint16_t lcd_contrast; + #endif + EEPROM_READ(lcd_contrast); + + #if ENABLED(FWRETRACT) + EEPROM_READ(autoretract_enabled); + EEPROM_READ(retract_length); + EEPROM_READ(retract_feedrate_mm_s); + EEPROM_READ(retract_zlift); + EEPROM_READ(retract_recover_length); + EEPROM_READ(retract_recover_feedrate_mm_s); + EEPROM_READ(swap_retract_length); + EEPROM_READ(swap_retract_recover_length); + EEPROM_READ(swap_retract_recover_feedrate_mm_s); + #else + EEPROM_READ(dummyb); + for (uint8_t q=8; q--;) EEPROM_READ(dummy); + #endif + + EEPROM_READ(volumetric_enabled); + + for (uint8_t q = 0; q < MAX_EXTRUDERS; q++) { + EEPROM_READ(dummy); + if (q < COUNT(filament_size)) filament_size[q] = dummy; + } + + uint16_t val; + #if ENABLED(HAVE_TMC2130) + EEPROM_READ(val); + #if ENABLED(X_IS_TMC2130) + stepperX.setCurrent(val, R_SENSE, HOLD_MULTIPLIER); + #endif + EEPROM_READ(val); + #if ENABLED(Y_IS_TMC2130) + stepperY.setCurrent(val, R_SENSE, HOLD_MULTIPLIER); + #endif + EEPROM_READ(val); + #if ENABLED(Z_IS_TMC2130) + stepperZ.setCurrent(val, R_SENSE, HOLD_MULTIPLIER); + #endif + EEPROM_READ(val); + #if ENABLED(X2_IS_TMC2130) + stepperX2.setCurrent(val, R_SENSE, HOLD_MULTIPLIER); + #endif + EEPROM_READ(val); + #if ENABLED(Y2_IS_TMC2130) + stepperY2.setCurrent(val, R_SENSE, HOLD_MULTIPLIER); + #endif + EEPROM_READ(val); + #if ENABLED(Z2_IS_TMC2130) + stepperZ2.setCurrent(val, R_SENSE, HOLD_MULTIPLIER); + #endif + EEPROM_READ(val); + #if ENABLED(E0_IS_TMC2130) + stepperE0.setCurrent(val, R_SENSE, HOLD_MULTIPLIER); + #endif + EEPROM_READ(val); + #if ENABLED(E1_IS_TMC2130) + stepperE1.setCurrent(val, R_SENSE, HOLD_MULTIPLIER); + #endif + EEPROM_READ(val); + #if ENABLED(E2_IS_TMC2130) + stepperE2.setCurrent(val, R_SENSE, HOLD_MULTIPLIER); + #endif + EEPROM_READ(val); + #if ENABLED(E3_IS_TMC2130) + stepperE3.setCurrent(val, R_SENSE, HOLD_MULTIPLIER); + #endif + EEPROM_READ(val); + #if ENABLED(E4_IS_TMC2130) + stepperE4.setCurrent(val, R_SENSE, HOLD_MULTIPLIER); + #endif + #else + for (uint8_t q = 0; q < 11; q++) EEPROM_READ(val); + #endif + + // + // Linear Advance + // + + #if ENABLED(LIN_ADVANCE) + EEPROM_READ(planner.extruder_advance_k); + EEPROM_READ(planner.advance_ed_ratio); + #else + EEPROM_READ(dummy); + EEPROM_READ(dummy); + #endif + + #if HAS_MOTOR_CURRENT_PWM + for (uint8_t q = 3; q--;) EEPROM_READ(stepper.motor_current_setting[q]); + #else + uint32_t dummyui32; + for (uint8_t q = 3; q--;) EEPROM_READ(dummyui32); + #endif + + if (working_crc == stored_crc) { + postprocess(); + #if ENABLED(EEPROM_CHITCHAT) + SERIAL_ECHO_START(); + SERIAL_ECHO(version); + SERIAL_ECHOPAIR(" stored settings retrieved (", eeprom_index - (EEPROM_OFFSET)); + SERIAL_ECHOPAIR(" bytes; crc ", (uint32_t)working_crc); + SERIAL_ECHOLNPGM(")"); + #endif + } + else { + #if ENABLED(EEPROM_CHITCHAT) + SERIAL_ERROR_START(); + SERIAL_ERRORPGM("EEPROM CRC mismatch - (stored) "); + SERIAL_ERROR(stored_crc); + SERIAL_ERRORPGM(" != "); + SERIAL_ERROR(working_crc); + SERIAL_ERRORLNPGM(" (calculated)!"); + #endif + reset(); + } + + #if ENABLED(AUTO_BED_LEVELING_UBL) + meshes_begin = (eeprom_index + 32) & 0xFFF8; // Pad the end of configuration data so it + // can float up or down a little bit without + // disrupting the mesh data + ubl.report_state(); + + if (!ubl.sanity_check()) { + SERIAL_EOL(); + #if ENABLED(EEPROM_CHITCHAT) + ubl.echo_name(); + SERIAL_ECHOLNPGM(" initialized.\n"); + #endif + } + else { + #if ENABLED(EEPROM_CHITCHAT) + SERIAL_PROTOCOLPGM("?Can't enable "); + ubl.echo_name(); + SERIAL_PROTOCOLLNPGM("."); + #endif + ubl.reset(); + } + + if (ubl.state.storage_slot >= 0) { + load_mesh(ubl.state.storage_slot); + #if ENABLED(EEPROM_CHITCHAT) + SERIAL_ECHOPAIR("Mesh ", ubl.state.storage_slot); + SERIAL_ECHOLNPGM(" loaded from storage."); + #endif + } + else { + ubl.reset(); + #if ENABLED(EEPROM_CHITCHAT) + SERIAL_ECHOLNPGM("UBL System reset()"); + #endif + } + #endif + } + + #if ENABLED(EEPROM_CHITCHAT) && DISABLED(DISABLE_M503) + report(); + #endif + + return !eeprom_error; + } + + #if ENABLED(AUTO_BED_LEVELING_UBL) + + #if ENABLED(EEPROM_CHITCHAT) + void ubl_invalid_slot(const int s) { + SERIAL_PROTOCOLLNPGM("?Invalid slot."); + SERIAL_PROTOCOL(s); + SERIAL_PROTOCOLLNPGM(" mesh slots available."); + } + #endif + + int MarlinSettings::calc_num_meshes() { + //obviously this will get more sophisticated once we've added an actual MAT + + if (meshes_begin <= 0) return 0; + + return (meshes_end - meshes_begin) / sizeof(ubl.z_values); + } + + void MarlinSettings::store_mesh(int8_t slot) { + + #if ENABLED(AUTO_BED_LEVELING_UBL) + const int a = calc_num_meshes(); + if (!WITHIN(slot, 0, a - 1)) { + #if ENABLED(EEPROM_CHITCHAT) + ubl_invalid_slot(a); + SERIAL_PROTOCOLPAIR("E2END=", E2END); + SERIAL_PROTOCOLPAIR(" meshes_end=", meshes_end); + SERIAL_PROTOCOLLNPAIR(" slot=", slot); + SERIAL_EOL(); + #endif + return; + } + + uint16_t crc = 0; + int pos = meshes_end - (slot + 1) * sizeof(ubl.z_values); + + write_data(pos, (uint8_t *)&ubl.z_values, sizeof(ubl.z_values), &crc); + + // Write crc to MAT along with other data, or just tack on to the beginning or end + + #if ENABLED(EEPROM_CHITCHAT) + SERIAL_PROTOCOLLNPAIR("Mesh saved in slot ", slot); + #endif + + #else + + // Other mesh types + + #endif + } + + void MarlinSettings::load_mesh(int8_t slot, void *into /* = 0 */) { + + #if ENABLED(AUTO_BED_LEVELING_UBL) + + const int16_t a = settings.calc_num_meshes(); + + if (!WITHIN(slot, 0, a - 1)) { + #if ENABLED(EEPROM_CHITCHAT) + ubl_invalid_slot(a); + #endif + return; + } + + uint16_t crc = 0; + int pos = meshes_end - (slot + 1) * sizeof(ubl.z_values); + uint8_t * const dest = into ? (uint8_t*)into : (uint8_t*)&ubl.z_values; + read_data(pos, dest, sizeof(ubl.z_values), &crc); + + // Compare crc with crc from MAT, or read from end + + #if ENABLED(EEPROM_CHITCHAT) + SERIAL_PROTOCOLLNPAIR("Mesh loaded from slot ", slot); + #endif + + #else + + // Other mesh types + + #endif + } + + //void MarlinSettings::delete_mesh() { return; } + //void MarlinSettings::defrag_meshes() { return; } + + #endif // AUTO_BED_LEVELING_UBL + +#else // !EEPROM_SETTINGS + + bool MarlinSettings::save() { + SERIAL_ERROR_START(); + SERIAL_ERRORLNPGM("EEPROM disabled"); + return false; + } + +#endif // !EEPROM_SETTINGS + +/** + * M502 - Reset Configuration + */ +void MarlinSettings::reset() { + static const float tmp1[] PROGMEM = DEFAULT_AXIS_STEPS_PER_UNIT, tmp2[] PROGMEM = DEFAULT_MAX_FEEDRATE; + static const uint32_t tmp3[] PROGMEM = DEFAULT_MAX_ACCELERATION; + LOOP_XYZE_N(i) { + planner.axis_steps_per_mm[i] = pgm_read_float(&tmp1[i < COUNT(tmp1) ? i : COUNT(tmp1) - 1]); + planner.max_feedrate_mm_s[i] = pgm_read_float(&tmp2[i < COUNT(tmp2) ? i : COUNT(tmp2) - 1]); + planner.max_acceleration_mm_per_s2[i] = pgm_read_dword_near(&tmp3[i < COUNT(tmp3) ? i : COUNT(tmp3) - 1]); + } + + planner.acceleration = DEFAULT_ACCELERATION; + planner.retract_acceleration = DEFAULT_RETRACT_ACCELERATION; + planner.travel_acceleration = DEFAULT_TRAVEL_ACCELERATION; + planner.min_feedrate_mm_s = DEFAULT_MINIMUMFEEDRATE; + planner.min_segment_time = DEFAULT_MINSEGMENTTIME; + planner.min_travel_feedrate_mm_s = DEFAULT_MINTRAVELFEEDRATE; + planner.max_jerk[X_AXIS] = DEFAULT_XJERK; + planner.max_jerk[Y_AXIS] = DEFAULT_YJERK; + planner.max_jerk[Z_AXIS] = DEFAULT_ZJERK; + planner.max_jerk[E_AXIS] = DEFAULT_EJERK; + + #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) + planner.z_fade_height = 0.0; + #endif + + #if HAS_HOME_OFFSET + ZERO(home_offset); + #endif + + #if HOTENDS > 1 + constexpr float tmp4[XYZ][HOTENDS] = { + HOTEND_OFFSET_X, + HOTEND_OFFSET_Y + #ifdef HOTEND_OFFSET_Z + , HOTEND_OFFSET_Z + #else + , { 0 } + #endif + }; + static_assert( + tmp4[X_AXIS][0] == 0 && tmp4[Y_AXIS][0] == 0 && tmp4[Z_AXIS][0] == 0, + "Offsets for the first hotend must be 0.0." + ); + LOOP_XYZ(i) HOTEND_LOOP() hotend_offset[i][e] = tmp4[i][e]; + #endif + + // Applies to all MBL and ABL + #if HAS_LEVELING + reset_bed_level(); + #endif + + #if HAS_BED_PROBE + zprobe_zoffset = Z_PROBE_OFFSET_FROM_EXTRUDER; + #endif + + #if ENABLED(DELTA) + const float adj[ABC] = DELTA_ENDSTOP_ADJ, + dta[ABC] = DELTA_TOWER_ANGLE_TRIM; + COPY(endstop_adj, adj); + delta_radius = DELTA_RADIUS; + delta_diagonal_rod = DELTA_DIAGONAL_ROD; + delta_segments_per_second = DELTA_SEGMENTS_PER_SECOND; + delta_calibration_radius = DELTA_CALIBRATION_RADIUS; + COPY(delta_tower_angle_trim, dta); + home_offset[Z_AXIS] = 0; + + #elif ENABLED(Z_DUAL_ENDSTOPS) + + z_endstop_adj = + #ifdef Z_DUAL_ENDSTOPS_ADJUSTMENT + Z_DUAL_ENDSTOPS_ADJUSTMENT + #else + 0 + #endif + ; + + #endif + + #if ENABLED(ULTIPANEL) + lcd_preheat_hotend_temp[0] = PREHEAT_1_TEMP_HOTEND; + lcd_preheat_hotend_temp[1] = PREHEAT_2_TEMP_HOTEND; + lcd_preheat_bed_temp[0] = PREHEAT_1_TEMP_BED; + lcd_preheat_bed_temp[1] = PREHEAT_2_TEMP_BED; + lcd_preheat_fan_speed[0] = PREHEAT_1_FAN_SPEED; + lcd_preheat_fan_speed[1] = PREHEAT_2_FAN_SPEED; + #endif + + #if HAS_LCD_CONTRAST + lcd_contrast = DEFAULT_LCD_CONTRAST; + #endif + + #if ENABLED(PIDTEMP) + #if ENABLED(PID_PARAMS_PER_HOTEND) && HOTENDS > 1 + HOTEND_LOOP() + #endif + { + PID_PARAM(Kp, e) = DEFAULT_Kp; + PID_PARAM(Ki, e) = scalePID_i(DEFAULT_Ki); + PID_PARAM(Kd, e) = scalePID_d(DEFAULT_Kd); + #if ENABLED(PID_EXTRUSION_SCALING) + PID_PARAM(Kc, e) = DEFAULT_Kc; + #endif + } + #if ENABLED(PID_EXTRUSION_SCALING) + lpq_len = 20; // default last-position-queue size + #endif + #endif // PIDTEMP + + #if ENABLED(PIDTEMPBED) + thermalManager.bedKp = DEFAULT_bedKp; + thermalManager.bedKi = scalePID_i(DEFAULT_bedKi); + thermalManager.bedKd = scalePID_d(DEFAULT_bedKd); + #endif + + #if ENABLED(FWRETRACT) + autoretract_enabled = false; + retract_length = RETRACT_LENGTH; + retract_feedrate_mm_s = RETRACT_FEEDRATE; + retract_zlift = RETRACT_ZLIFT; + retract_recover_length = RETRACT_RECOVER_LENGTH; + retract_recover_feedrate_mm_s = RETRACT_RECOVER_FEEDRATE; + swap_retract_length = RETRACT_LENGTH_SWAP; + swap_retract_recover_length = RETRACT_RECOVER_LENGTH_SWAP; + swap_retract_recover_feedrate_mm_s = RETRACT_RECOVER_FEEDRATE_SWAP; + #endif // FWRETRACT + + volumetric_enabled = + #if ENABLED(VOLUMETRIC_DEFAULT_ON) + true + #else + false + #endif + ; + for (uint8_t q = 0; q < COUNT(filament_size); q++) + filament_size[q] = DEFAULT_NOMINAL_FILAMENT_DIA; + + endstops.enable_globally( + #if ENABLED(ENDSTOPS_ALWAYS_ON_DEFAULT) + true + #else + false + #endif + ); + + #if ENABLED(HAVE_TMC2130) + #if ENABLED(X_IS_TMC2130) + stepperX.setCurrent(X_CURRENT, R_SENSE, HOLD_MULTIPLIER); + #endif + #if ENABLED(Y_IS_TMC2130) + stepperY.setCurrent(Y_CURRENT, R_SENSE, HOLD_MULTIPLIER); + #endif + #if ENABLED(Z_IS_TMC2130) + stepperZ.setCurrent(Z_CURRENT, R_SENSE, HOLD_MULTIPLIER); + #endif + #if ENABLED(X2_IS_TMC2130) + stepperX2.setCurrent(X2_CURRENT, R_SENSE, HOLD_MULTIPLIER); + #endif + #if ENABLED(Y2_IS_TMC2130) + stepperY2.setCurrent(Y2_CURRENT, R_SENSE, HOLD_MULTIPLIER); + #endif + #if ENABLED(Z2_IS_TMC2130) + stepperZ2.setCurrent(Z2_CURRENT, R_SENSE, HOLD_MULTIPLIER); + #endif + #if ENABLED(E0_IS_TMC2130) + stepperE0.setCurrent(E0_CURRENT, R_SENSE, HOLD_MULTIPLIER); + #endif + #if ENABLED(E1_IS_TMC2130) + stepperE1.setCurrent(E1_CURRENT, R_SENSE, HOLD_MULTIPLIER); + #endif + #if ENABLED(E2_IS_TMC2130) + stepperE2.setCurrent(E2_CURRENT, R_SENSE, HOLD_MULTIPLIER); + #endif + #if ENABLED(E3_IS_TMC2130) + stepperE3.setCurrent(E3_CURRENT, R_SENSE, HOLD_MULTIPLIER); + #endif + #endif + + #if ENABLED(LIN_ADVANCE) + planner.extruder_advance_k = LIN_ADVANCE_K; + planner.advance_ed_ratio = LIN_ADVANCE_E_D_RATIO; + #endif + + #if HAS_MOTOR_CURRENT_PWM + 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])); + #endif + + #if ENABLED(AUTO_BED_LEVELING_UBL) + ubl.reset(); + #endif + + postprocess(); + + #if ENABLED(EEPROM_CHITCHAT) + SERIAL_ECHO_START(); + SERIAL_ECHOLNPGM("Hardcoded Default Settings Loaded"); + #endif +} + +#if DISABLED(DISABLE_M503) + + #define CONFIG_ECHO_START do{ if (!forReplay) SERIAL_ECHO_START(); }while(0) + + /** + * M503 - Report current settings in RAM + * + * Unless specifically disabled, M503 is available even without EEPROM + */ + void MarlinSettings::report(bool forReplay) { + + /** + * Announce current units, in case inches are being displayed + */ + CONFIG_ECHO_START; + #if ENABLED(INCH_MODE_SUPPORT) + #define LINEAR_UNIT(N) ((N) / parser.linear_unit_factor) + #define VOLUMETRIC_UNIT(N) ((N) / (volumetric_enabled ? parser.volumetric_unit_factor : parser.linear_unit_factor)) + SERIAL_ECHOPGM(" G2"); + SERIAL_CHAR(parser.linear_unit_factor == 1.0 ? '1' : '0'); + SERIAL_ECHOPGM(" ; Units in "); + serialprintPGM(parser.linear_unit_factor == 1.0 ? PSTR("mm\n") : PSTR("inches\n")); + #else + #define LINEAR_UNIT(N) N + #define VOLUMETRIC_UNIT(N) N + SERIAL_ECHOLNPGM(" G21 ; Units in mm"); + #endif + + #if ENABLED(ULTIPANEL) + + // Temperature units - for Ultipanel temperature options + + CONFIG_ECHO_START; + #if ENABLED(TEMPERATURE_UNITS_SUPPORT) + #define TEMP_UNIT(N) parser.to_temp_units(N) + SERIAL_ECHOPGM(" M149 "); + SERIAL_CHAR(parser.temp_units_code()); + SERIAL_ECHOPGM(" ; Units in "); + serialprintPGM(parser.temp_units_name()); + #else + #define TEMP_UNIT(N) N + SERIAL_ECHOLNPGM(" M149 C ; Units in Celsius"); + #endif + + #endif + + SERIAL_EOL(); + + /** + * Volumetric extrusion M200 + */ + if (!forReplay) { + CONFIG_ECHO_START; + SERIAL_ECHOPGM("Filament settings:"); + if (volumetric_enabled) + SERIAL_EOL(); + else + SERIAL_ECHOLNPGM(" Disabled"); + } + + CONFIG_ECHO_START; + SERIAL_ECHOPAIR(" M200 D", filament_size[0]); + SERIAL_EOL(); + #if EXTRUDERS > 1 + CONFIG_ECHO_START; + SERIAL_ECHOPAIR(" M200 T1 D", filament_size[1]); + SERIAL_EOL(); + #if EXTRUDERS > 2 + CONFIG_ECHO_START; + SERIAL_ECHOPAIR(" M200 T2 D", filament_size[2]); + SERIAL_EOL(); + #if EXTRUDERS > 3 + CONFIG_ECHO_START; + SERIAL_ECHOPAIR(" M200 T3 D", filament_size[3]); + SERIAL_EOL(); + #if EXTRUDERS > 4 + CONFIG_ECHO_START; + SERIAL_ECHOPAIR(" M200 T4 D", filament_size[4]); + SERIAL_EOL(); + #endif // EXTRUDERS > 4 + #endif // EXTRUDERS > 3 + #endif // EXTRUDERS > 2 + #endif // EXTRUDERS > 1 + + if (!volumetric_enabled) { + CONFIG_ECHO_START; + SERIAL_ECHOLNPGM(" M200 D0"); + } + + if (!forReplay) { + CONFIG_ECHO_START; + SERIAL_ECHOLNPGM("Steps per unit:"); + } + CONFIG_ECHO_START; + SERIAL_ECHOPAIR(" M92 X", LINEAR_UNIT(planner.axis_steps_per_mm[X_AXIS])); + SERIAL_ECHOPAIR(" Y", LINEAR_UNIT(planner.axis_steps_per_mm[Y_AXIS])); + SERIAL_ECHOPAIR(" Z", LINEAR_UNIT(planner.axis_steps_per_mm[Z_AXIS])); + #if DISABLED(DISTINCT_E_FACTORS) + SERIAL_ECHOPAIR(" E", VOLUMETRIC_UNIT(planner.axis_steps_per_mm[E_AXIS])); + #endif + SERIAL_EOL(); + #if ENABLED(DISTINCT_E_FACTORS) + CONFIG_ECHO_START; + for (uint8_t i = 0; i < E_STEPPERS; i++) { + SERIAL_ECHOPAIR(" M92 T", (int)i); + SERIAL_ECHOLNPAIR(" E", VOLUMETRIC_UNIT(planner.axis_steps_per_mm[E_AXIS + i])); + } + #endif + + if (!forReplay) { + CONFIG_ECHO_START; + SERIAL_ECHOLNPGM("Maximum feedrates (units/s):"); + } + CONFIG_ECHO_START; + SERIAL_ECHOPAIR(" M203 X", LINEAR_UNIT(planner.max_feedrate_mm_s[X_AXIS])); + SERIAL_ECHOPAIR(" Y", LINEAR_UNIT(planner.max_feedrate_mm_s[Y_AXIS])); + SERIAL_ECHOPAIR(" Z", LINEAR_UNIT(planner.max_feedrate_mm_s[Z_AXIS])); + #if DISABLED(DISTINCT_E_FACTORS) + SERIAL_ECHOPAIR(" E", VOLUMETRIC_UNIT(planner.max_feedrate_mm_s[E_AXIS])); + #endif + SERIAL_EOL(); + #if ENABLED(DISTINCT_E_FACTORS) + CONFIG_ECHO_START; + for (uint8_t i = 0; i < E_STEPPERS; i++) { + SERIAL_ECHOPAIR(" M203 T", (int)i); + SERIAL_ECHOLNPAIR(" E", VOLUMETRIC_UNIT(planner.max_feedrate_mm_s[E_AXIS + i])); + } + #endif + + if (!forReplay) { + CONFIG_ECHO_START; + SERIAL_ECHOLNPGM("Maximum Acceleration (units/s2):"); + } + CONFIG_ECHO_START; + SERIAL_ECHOPAIR(" M201 X", LINEAR_UNIT(planner.max_acceleration_mm_per_s2[X_AXIS])); + SERIAL_ECHOPAIR(" Y", LINEAR_UNIT(planner.max_acceleration_mm_per_s2[Y_AXIS])); + SERIAL_ECHOPAIR(" Z", LINEAR_UNIT(planner.max_acceleration_mm_per_s2[Z_AXIS])); + #if DISABLED(DISTINCT_E_FACTORS) + SERIAL_ECHOPAIR(" E", VOLUMETRIC_UNIT(planner.max_acceleration_mm_per_s2[E_AXIS])); + #endif + SERIAL_EOL(); + #if ENABLED(DISTINCT_E_FACTORS) + CONFIG_ECHO_START; + for (uint8_t i = 0; i < E_STEPPERS; i++) { + SERIAL_ECHOPAIR(" M201 T", (int)i); + SERIAL_ECHOLNPAIR(" E", VOLUMETRIC_UNIT(planner.max_acceleration_mm_per_s2[E_AXIS + i])); + } + #endif + + if (!forReplay) { + CONFIG_ECHO_START; + SERIAL_ECHOLNPGM("Acceleration (units/s2): P R T"); + } + CONFIG_ECHO_START; + SERIAL_ECHOPAIR(" M204 P", LINEAR_UNIT(planner.acceleration)); + SERIAL_ECHOPAIR(" R", LINEAR_UNIT(planner.retract_acceleration)); + SERIAL_ECHOLNPAIR(" T", LINEAR_UNIT(planner.travel_acceleration)); + + if (!forReplay) { + CONFIG_ECHO_START; + SERIAL_ECHOLNPGM("Advanced: S T B X Z E"); + } + CONFIG_ECHO_START; + SERIAL_ECHOPAIR(" M205 S", LINEAR_UNIT(planner.min_feedrate_mm_s)); + SERIAL_ECHOPAIR(" T", LINEAR_UNIT(planner.min_travel_feedrate_mm_s)); + SERIAL_ECHOPAIR(" B", planner.min_segment_time); + SERIAL_ECHOPAIR(" X", LINEAR_UNIT(planner.max_jerk[X_AXIS])); + SERIAL_ECHOPAIR(" Y", LINEAR_UNIT(planner.max_jerk[Y_AXIS])); + SERIAL_ECHOPAIR(" Z", LINEAR_UNIT(planner.max_jerk[Z_AXIS])); + SERIAL_ECHOLNPAIR(" E", LINEAR_UNIT(planner.max_jerk[E_AXIS])); + + #if HAS_M206_COMMAND + if (!forReplay) { + CONFIG_ECHO_START; + SERIAL_ECHOLNPGM("Home offset:"); + } + CONFIG_ECHO_START; + SERIAL_ECHOPAIR(" M206 X", LINEAR_UNIT(home_offset[X_AXIS])); + SERIAL_ECHOPAIR(" Y", LINEAR_UNIT(home_offset[Y_AXIS])); + SERIAL_ECHOLNPAIR(" Z", LINEAR_UNIT(home_offset[Z_AXIS])); + #endif + + #if HOTENDS > 1 + if (!forReplay) { + CONFIG_ECHO_START; + SERIAL_ECHOLNPGM("Hotend offsets:"); + } + CONFIG_ECHO_START; + for (uint8_t e = 1; e < HOTENDS; e++) { + SERIAL_ECHOPAIR(" M218 T", (int)e); + SERIAL_ECHOPAIR(" X", LINEAR_UNIT(hotend_offset[X_AXIS][e])); + SERIAL_ECHOPAIR(" Y", LINEAR_UNIT(hotend_offset[Y_AXIS][e])); + #if ENABLED(DUAL_X_CARRIAGE) || ENABLED(SWITCHING_NOZZLE) ||ENABLED(PARKING_EXTRUDER) + SERIAL_ECHOPAIR(" Z", LINEAR_UNIT(hotend_offset[Z_AXIS][e])); + #endif + SERIAL_EOL(); + } + #endif + + #if ENABLED(MESH_BED_LEVELING) + + if (!forReplay) { + CONFIG_ECHO_START; + SERIAL_ECHOLNPGM("Mesh Bed Leveling:"); + } + CONFIG_ECHO_START; + SERIAL_ECHOPAIR(" M420 S", leveling_is_valid() ? 1 : 0); + #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) + SERIAL_ECHOPAIR(" Z", LINEAR_UNIT(planner.z_fade_height)); + #endif + SERIAL_EOL(); + for (uint8_t py = 0; py < GRID_MAX_POINTS_Y; py++) { + for (uint8_t px = 0; px < GRID_MAX_POINTS_X; px++) { + CONFIG_ECHO_START; + SERIAL_ECHOPAIR(" G29 S3 X", (int)px + 1); + SERIAL_ECHOPAIR(" Y", (int)py + 1); + SERIAL_ECHOPGM(" Z"); + SERIAL_PROTOCOL_F(LINEAR_UNIT(mbl.z_values[px][py]), 5); + SERIAL_EOL(); + } + } + + #elif ENABLED(AUTO_BED_LEVELING_UBL) + + if (!forReplay) { + CONFIG_ECHO_START; + ubl.echo_name(); + SERIAL_ECHOLNPGM(":"); + } + CONFIG_ECHO_START; + SERIAL_ECHOPAIR(" M420 S", leveling_is_active() ? 1 : 0); + #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) + SERIAL_ECHOPAIR(" Z", planner.z_fade_height); + #endif + SERIAL_EOL(); + + if (!forReplay) { + SERIAL_EOL(); + ubl.report_state(); + + SERIAL_ECHOLNPAIR("\nActive Mesh Slot: ", ubl.state.storage_slot); + + SERIAL_ECHOPGM("z_offset: "); + SERIAL_ECHO_F(ubl.state.z_offset, 6); + SERIAL_EOL(); + + SERIAL_ECHOPAIR("EEPROM can hold ", calc_num_meshes()); + SERIAL_ECHOLNPGM(" meshes.\n"); + } + + #elif HAS_ABL + + if (!forReplay) { + CONFIG_ECHO_START; + SERIAL_ECHOLNPGM("Auto Bed Leveling:"); + } + CONFIG_ECHO_START; + SERIAL_ECHOPAIR(" M420 S", leveling_is_active() ? 1 : 0); + #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) + SERIAL_ECHOPAIR(" Z", LINEAR_UNIT(planner.z_fade_height)); + #endif + SERIAL_EOL(); + + #endif + + #if ENABLED(DELTA) + if (!forReplay) { + CONFIG_ECHO_START; + SERIAL_ECHOLNPGM("Endstop adjustment:"); + } + CONFIG_ECHO_START; + SERIAL_ECHOPAIR(" M666 X", LINEAR_UNIT(endstop_adj[X_AXIS])); + SERIAL_ECHOPAIR(" Y", LINEAR_UNIT(endstop_adj[Y_AXIS])); + SERIAL_ECHOLNPAIR(" Z", LINEAR_UNIT(endstop_adj[Z_AXIS])); + if (!forReplay) { + CONFIG_ECHO_START; + SERIAL_ECHOLNPGM("Delta settings: L R H S B XYZ"); + } + CONFIG_ECHO_START; + SERIAL_ECHOPAIR(" M665 L", LINEAR_UNIT(delta_diagonal_rod)); + SERIAL_ECHOPAIR(" R", LINEAR_UNIT(delta_radius)); + SERIAL_ECHOPAIR(" H", LINEAR_UNIT(DELTA_HEIGHT + home_offset[Z_AXIS])); + SERIAL_ECHOPAIR(" S", delta_segments_per_second); + SERIAL_ECHOPAIR(" B", LINEAR_UNIT(delta_calibration_radius)); + SERIAL_ECHOPAIR(" X", LINEAR_UNIT(delta_tower_angle_trim[A_AXIS])); + SERIAL_ECHOPAIR(" Y", LINEAR_UNIT(delta_tower_angle_trim[B_AXIS])); + SERIAL_ECHOPAIR(" Z", LINEAR_UNIT(delta_tower_angle_trim[C_AXIS])); + SERIAL_EOL(); + #elif ENABLED(Z_DUAL_ENDSTOPS) + if (!forReplay) { + CONFIG_ECHO_START; + SERIAL_ECHOLNPGM("Z2 Endstop adjustment:"); + } + CONFIG_ECHO_START; + SERIAL_ECHOLNPAIR(" M666 Z", LINEAR_UNIT(z_endstop_adj)); + #endif // DELTA + + #if ENABLED(ULTIPANEL) + if (!forReplay) { + CONFIG_ECHO_START; + SERIAL_ECHOLNPGM("Material heatup parameters:"); + } + CONFIG_ECHO_START; + for (uint8_t i = 0; i < COUNT(lcd_preheat_hotend_temp); i++) { + SERIAL_ECHOPAIR(" M145 S", (int)i); + SERIAL_ECHOPAIR(" H", TEMP_UNIT(lcd_preheat_hotend_temp[i])); + SERIAL_ECHOPAIR(" B", TEMP_UNIT(lcd_preheat_bed_temp[i])); + SERIAL_ECHOLNPAIR(" F", lcd_preheat_fan_speed[i]); + } + #endif // ULTIPANEL + + #if HAS_PID_HEATING + + if (!forReplay) { + CONFIG_ECHO_START; + SERIAL_ECHOLNPGM("PID settings:"); + } + #if ENABLED(PIDTEMP) + #if HOTENDS > 1 + if (forReplay) { + HOTEND_LOOP() { + CONFIG_ECHO_START; + SERIAL_ECHOPAIR(" M301 E", e); + SERIAL_ECHOPAIR(" P", PID_PARAM(Kp, e)); + SERIAL_ECHOPAIR(" I", unscalePID_i(PID_PARAM(Ki, e))); + SERIAL_ECHOPAIR(" D", unscalePID_d(PID_PARAM(Kd, e))); + #if ENABLED(PID_EXTRUSION_SCALING) + SERIAL_ECHOPAIR(" C", PID_PARAM(Kc, e)); + if (e == 0) SERIAL_ECHOPAIR(" L", lpq_len); + #endif + SERIAL_EOL(); + } + } + else + #endif // HOTENDS > 1 + // !forReplay || HOTENDS == 1 + { + CONFIG_ECHO_START; + SERIAL_ECHOPAIR(" M301 P", PID_PARAM(Kp, 0)); // for compatibility with hosts, only echo values for E0 + SERIAL_ECHOPAIR(" I", unscalePID_i(PID_PARAM(Ki, 0))); + SERIAL_ECHOPAIR(" D", unscalePID_d(PID_PARAM(Kd, 0))); + #if ENABLED(PID_EXTRUSION_SCALING) + SERIAL_ECHOPAIR(" C", PID_PARAM(Kc, 0)); + SERIAL_ECHOPAIR(" L", lpq_len); + #endif + SERIAL_EOL(); + } + #endif // PIDTEMP + + #if ENABLED(PIDTEMPBED) + CONFIG_ECHO_START; + SERIAL_ECHOPAIR(" M304 P", thermalManager.bedKp); + SERIAL_ECHOPAIR(" I", unscalePID_i(thermalManager.bedKi)); + SERIAL_ECHOPAIR(" D", unscalePID_d(thermalManager.bedKd)); + SERIAL_EOL(); + #endif + + #endif // PIDTEMP || PIDTEMPBED + + #if HAS_LCD_CONTRAST + if (!forReplay) { + CONFIG_ECHO_START; + SERIAL_ECHOLNPGM("LCD Contrast:"); + } + CONFIG_ECHO_START; + SERIAL_ECHOLNPAIR(" M250 C", lcd_contrast); + #endif + + #if ENABLED(FWRETRACT) + + if (!forReplay) { + CONFIG_ECHO_START; + SERIAL_ECHOLNPGM("Retract: S F Z"); + } + CONFIG_ECHO_START; + SERIAL_ECHOPAIR(" M207 S", LINEAR_UNIT(retract_length)); + SERIAL_ECHOPAIR(" W", LINEAR_UNIT(swap_retract_length)); + SERIAL_ECHOPAIR(" F", MMS_TO_MMM(LINEAR_UNIT(retract_feedrate_mm_s))); + SERIAL_ECHOLNPAIR(" Z", LINEAR_UNIT(retract_zlift)); + + if (!forReplay) { + CONFIG_ECHO_START; + SERIAL_ECHOLNPGM("Recover: S F"); + } + CONFIG_ECHO_START; + SERIAL_ECHOPAIR(" M208 S", LINEAR_UNIT(retract_recover_length)); + SERIAL_ECHOPAIR(" W", LINEAR_UNIT(swap_retract_recover_length)); + SERIAL_ECHOLNPAIR(" F", MMS_TO_MMM(LINEAR_UNIT(retract_recover_feedrate_mm_s))); + + if (!forReplay) { + CONFIG_ECHO_START; + SERIAL_ECHOLNPGM("Auto-Retract: S=0 to disable, 1 to interpret E-only moves as retract/recover"); + } + CONFIG_ECHO_START; + SERIAL_ECHOLNPAIR(" M209 S", autoretract_enabled ? 1 : 0); + + #endif // FWRETRACT + + /** + * Auto Bed Leveling + */ + #if HAS_BED_PROBE + if (!forReplay) { + CONFIG_ECHO_START; + SERIAL_ECHOLNPGM("Z-Probe Offset (mm):"); + } + CONFIG_ECHO_START; + SERIAL_ECHOLNPAIR(" M851 Z", LINEAR_UNIT(zprobe_zoffset)); + #endif + + /** + * TMC2130 stepper driver current + */ + #if ENABLED(HAVE_TMC2130) + if (!forReplay) { + CONFIG_ECHO_START; + SERIAL_ECHOLNPGM("Stepper driver current:"); + } + CONFIG_ECHO_START; + SERIAL_ECHO(" M906"); + #if ENABLED(X_IS_TMC2130) + SERIAL_ECHOPAIR(" X", stepperX.getCurrent()); + #endif + #if ENABLED(Y_IS_TMC2130) + SERIAL_ECHOPAIR(" Y", stepperY.getCurrent()); + #endif + #if ENABLED(Z_IS_TMC2130) + SERIAL_ECHOPAIR(" Z", stepperZ.getCurrent()); + #endif + #if ENABLED(X2_IS_TMC2130) + SERIAL_ECHOPAIR(" X2", stepperX2.getCurrent()); + #endif + #if ENABLED(Y2_IS_TMC2130) + SERIAL_ECHOPAIR(" Y2", stepperY2.getCurrent()); + #endif + #if ENABLED(Z2_IS_TMC2130) + SERIAL_ECHOPAIR(" Z2", stepperZ2.getCurrent()); + #endif + #if ENABLED(E0_IS_TMC2130) + SERIAL_ECHOPAIR(" E0", stepperE0.getCurrent()); + #endif + #if ENABLED(E1_IS_TMC2130) + SERIAL_ECHOPAIR(" E1", stepperE1.getCurrent()); + #endif + #if ENABLED(E2_IS_TMC2130) + SERIAL_ECHOPAIR(" E2", stepperE2.getCurrent()); + #endif + #if ENABLED(E3_IS_TMC2130) + SERIAL_ECHOPAIR(" E3", stepperE3.getCurrent()); + #endif + SERIAL_EOL(); + #endif + + /** + * Linear Advance + */ + #if ENABLED(LIN_ADVANCE) + if (!forReplay) { + CONFIG_ECHO_START; + SERIAL_ECHOLNPGM("Linear Advance:"); + } + CONFIG_ECHO_START; + SERIAL_ECHOPAIR(" M900 K", planner.extruder_advance_k); + SERIAL_ECHOLNPAIR(" R", planner.advance_ed_ratio); + #endif + + #if HAS_MOTOR_CURRENT_PWM + CONFIG_ECHO_START; + if (!forReplay) { + SERIAL_ECHOLNPGM("Stepper motor currents:"); + CONFIG_ECHO_START; + } + SERIAL_ECHOPAIR(" M907 X", stepper.motor_current_setting[0]); + SERIAL_ECHOPAIR(" Z", stepper.motor_current_setting[1]); + SERIAL_ECHOPAIR(" E", stepper.motor_current_setting[2]); + SERIAL_EOL(); + #endif + } + +#endif // !DISABLE_M503 diff --git a/trunk/Arduino/Marlin_1.1.6/configuration_store.h b/trunk/Arduino/Marlin_1.1.6/configuration_store.h new file mode 100644 index 00000000..99e95112 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/configuration_store.h @@ -0,0 +1,82 @@ +/** + * 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 . + * + */ + +#ifndef CONFIGURATION_STORE_H +#define CONFIGURATION_STORE_H + +#include "MarlinConfig.h" + +class MarlinSettings { + public: + MarlinSettings() { } + + static void reset(); + static bool save(); + + #if ENABLED(EEPROM_SETTINGS) + static bool load(); + + #if ENABLED(AUTO_BED_LEVELING_UBL) // Eventually make these available if any leveling system + // That can store is enabled + FORCE_INLINE static int get_start_of_meshes() { return meshes_begin; } + FORCE_INLINE static int get_end_of_meshes() { return meshes_end; } + static int calc_num_meshes(); + static void store_mesh(int8_t slot); + static void load_mesh(int8_t slot, void *into = 0); + + //static void delete_mesh(); // necessary if we have a MAT + //static void defrag_meshes(); // " + #endif + #else + FORCE_INLINE + static bool load() { reset(); report(); return true; } + #endif + + #if DISABLED(DISABLE_M503) + static void report(bool forReplay=false); + #else + FORCE_INLINE + static void report(bool forReplay=false) { UNUSED(forReplay); } + #endif + + private: + static void postprocess(); + + #if ENABLED(EEPROM_SETTINGS) + static bool eeprom_error; + + #if ENABLED(AUTO_BED_LEVELING_UBL) // Eventually make these available if any leveling system + // That can store is enabled + static int meshes_begin; + const static int meshes_end = E2END - 128; // 128 is a placeholder for the size of the MAT; the MAT will always + // live at the very end of the eeprom + + #endif + + static void write_data(int &pos, const uint8_t *value, uint16_t size, uint16_t *crc); + static void read_data(int &pos, uint8_t *value, uint16_t size, uint16_t *crc); + #endif +}; + +extern MarlinSettings settings; + +#endif // CONFIGURATION_STORE_H diff --git a/trunk/Arduino/Marlin_1.1.6/dac_mcp4728.cpp b/trunk/Arduino/Marlin_1.1.6/dac_mcp4728.cpp new file mode 100644 index 00000000..a06346c6 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/dac_mcp4728.cpp @@ -0,0 +1,151 @@ +/** + * 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 . + * + */ + +/** + * 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 + * + * For discussion and feedback, please go to: + * http://arduino.cc/forum/index.php/topic,51842.0.html + */ + +#include "dac_mcp4728.h" +#include "enum.h" + +#if ENABLED(DAC_STEPPER_CURRENT) + +uint16_t mcp4728_values[XYZE]; + +/** + * Begin I2C, get current values (input register and eeprom) of mcp4728 + */ +void mcp4728_init() { + Wire.begin(); + Wire.requestFrom(int(DAC_DEV_ADDRESS), 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); + } +} + +/** + * Write input resister value to specified channel using fastwrite method. + * Channel : 0-3, Values : 0-4095 + */ +uint8_t mcp4728_analogWrite(uint8_t channel, uint16_t value) { + mcp4728_values[channel] = value; + return mcp4728_fastWrite(); +} + +/** + * Write all input resistor values to EEPROM using SequencialWrite method. + * This will update both input register and EEPROM value + * This will also write current Vref, PowerDown, Gain settings to EEPROM + */ +uint8_t mcp4728_eepromWrite() { + Wire.beginTransmission(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])); + } + return Wire.endTransmission(); +} + +/** + * Write Voltage reference setting to all input regiters + */ +uint8_t mcp4728_setVref_all(uint8_t value) { + Wire.beginTransmission(DAC_DEV_ADDRESS); + Wire.write(VREFWRITE | (value ? 0x0F : 0x00)); + return Wire.endTransmission(); +} +/** + * Write Gain setting to all input regiters + */ +uint8_t mcp4728_setGain_all(uint8_t value) { + Wire.beginTransmission(DAC_DEV_ADDRESS); + Wire.write(GAINWRITE | (value ? 0x0F : 0x00)); + return Wire.endTransmission(); +} + +/** + * Return Input Register value + */ +uint16_t mcp4728_getValue(uint8_t channel) { return mcp4728_values[channel]; } + +/** + * Steph: Might be useful in the future + * Return Vout + * +uint16_t mcp4728_getVout(uint8_t channel) { + uint32_t vref = 2048, + vOut = (vref * mcp4728_values[channel] * (_DAC_STEPPER_GAIN + 1)) / 4096; + if (vOut > defaultVDD) vOut = defaultVDD; + return vOut; +} +*/ + +/** + * Returns DAC values as a 0-100 percentage of drive strength + */ +uint8_t mcp4728_getDrvPct(uint8_t channel) { return uint8_t(100.0 * mcp4728_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(uint8_t pct[XYZE]) { + LOOP_XYZE(i) mcp4728_values[i] = 0.01 * pct[i] * (DAC_STEPPER_MAX); + mcp4728_fastWrite(); +} + +/** + * FastWrite input register values - All DAC ouput update. refer to DATASHEET 5.6.1 + * DAC Input and PowerDown bits update. + * No EEPROM update + */ +uint8_t mcp4728_fastWrite() { + Wire.beginTransmission(DAC_DEV_ADDRESS); + LOOP_XYZE(i) { + Wire.write(highByte(mcp4728_values[i])); + Wire.write(lowByte(mcp4728_values[i])); + } + return Wire.endTransmission(); +} + +/** + * Common function for simple general commands + */ +uint8_t mcp4728_simpleCommand(byte simpleCommand) { + Wire.beginTransmission(GENERALCALL); + Wire.write(simpleCommand); + return Wire.endTransmission(); +} + +#endif // DAC_STEPPER_CURRENT diff --git a/trunk/Arduino/Marlin_1.1.6/dac_mcp4728.h b/trunk/Arduino/Marlin_1.1.6/dac_mcp4728.h new file mode 100644 index 00000000..f8337316 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/dac_mcp4728.h @@ -0,0 +1,66 @@ +/** + * 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 . + * + */ + +/** + * Arduino library for MicroChip MCP4728 I2C D/A converter. + */ + +#ifndef DAC_MCP4728_H +#define DAC_MCP4728_H + +#include "MarlinConfig.h" + +#if ENABLED(DAC_STEPPER_CURRENT) +#include "Wire.h" + +#define defaultVDD DAC_STEPPER_MAX //was 5000 but differs with internal Vref +#define BASE_ADDR 0x60 +#define RESET 0B00000110 +#define WAKE 0B00001001 +#define UPDATE 0B00001000 +#define MULTIWRITE 0B01000000 +#define SINGLEWRITE 0B01011000 +#define SEQWRITE 0B01010000 +#define VREFWRITE 0B10000000 +#define GAINWRITE 0B11000000 +#define POWERDOWNWRITE 0B10100000 +#define GENERALCALL 0B00000000 +#define GAINWRITE 0B11000000 + +// This is taken from the original lib, makes it easy to edit if needed +// 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(uint8_t channel, uint16_t value); +uint8_t mcp4728_eepromWrite(); +uint8_t mcp4728_setVref_all(uint8_t value); +uint8_t mcp4728_setGain_all(uint8_t value); +uint16_t mcp4728_getValue(uint8_t channel); +uint8_t mcp4728_fastWrite(); +uint8_t mcp4728_simpleCommand(byte simpleCommand); +uint8_t mcp4728_getDrvPct(uint8_t channel); +void mcp4728_setDrvPct(uint8_t pct[XYZE]); + +#endif +#endif // DAC_MCP4728_H diff --git a/trunk/Arduino/Marlin_1.1.6/digipot_mcp4018.cpp b/trunk/Arduino/Marlin_1.1.6/digipot_mcp4018.cpp new file mode 100644 index 00000000..06622d05 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/digipot_mcp4018.cpp @@ -0,0 +1,106 @@ +/** + * 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 . + * + */ + +#include "MarlinConfig.h" + +#if ENABLED(DIGIPOT_I2C) && ENABLED(DIGIPOT_MCP4018) + +#include "enum.h" +#include "Stream.h" +#include "utility/twi.h" +#include //https://github.com/stawel/SlowSoftI2CMaster + +// Settings for the I2C based DIGIPOT (MCP4018) based on WT150 + +#define DIGIPOT_I2C_ADDRESS 0x2F + +#define DIGIPOT_A4988_Rsx 0.250 +#define DIGIPOT_A4988_Vrefmax 1.666 +#define DIGIPOT_A4988_MAX_VALUE 127 + +#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_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 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 } + #if DIGIPOT_I2C_NUM_CHANNELS > 1 + , SlowSoftI2CMaster { sda_pins[Y_AXIS], DIGIPOTS_I2C_SCL } + #if DIGIPOT_I2C_NUM_CHANNELS > 2 + , SlowSoftI2CMaster { sda_pins[Z_AXIS], DIGIPOTS_I2C_SCL } + #if DIGIPOT_I2C_NUM_CHANNELS > 3 + , SlowSoftI2CMaster { sda_pins[E_AXIS], DIGIPOTS_I2C_SCL } + #if DIGIPOT_I2C_NUM_CHANNELS > 4 + , SlowSoftI2CMaster { sda_pins[E_AXIS + 1], DIGIPOTS_I2C_SCL } + #endif + #endif + #endif + #endif +}; + +static void 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) << 1) | I2C_WRITE); + pots[channel].i2c_write(v); + pots[channel].i2c_stop(); + } +} + +// This is for the MCP4018 I2C based digipot +void digipot_i2c_set_current(uint8_t channel, float current) { + i2c_send(channel, current_to_wiper(min(max(current, 0.0f), float(DIGIPOT_A4988_MAX_CURRENT)))); +} + +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(); + + // 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])); +} + +#endif // DIGIPOT_I2C && DIGIPOT_MCP4018 diff --git a/trunk/Arduino/Marlin_1.1.6/digipot_mcp4451.cpp b/trunk/Arduino/Marlin_1.1.6/digipot_mcp4451.cpp new file mode 100644 index 00000000..d79915cc --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/digipot_mcp4451.cpp @@ -0,0 +1,79 @@ +/** + * 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 . + * + */ + +#include "MarlinConfig.h" + +#if ENABLED(DIGIPOT_I2C) && DISABLED(DIGIPOT_MCP4018) + +#include "Stream.h" +#include "utility/twi.h" +#include "Wire.h" + +// 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 +#else + #define DIGIPOT_I2C_FACTOR 106.7 + #define DIGIPOT_I2C_MAX_CURRENT 2.5 +#endif + +static byte current_to_wiper(const float current) { + return byte(CEIL(float((DIGIPOT_I2C_FACTOR * current)))); +} + +static void i2c_send(const byte addr, const byte a, const byte b) { + Wire.beginTransmission(addr); + Wire.write(a); + Wire.write(b); + Wire.endTransmission(); +} + +// This is for the MCP4451 I2C based digipot +void digipot_i2c_set_current(uint8_t channel, float current) { + current = min((float) max(current, 0.0f), DIGIPOT_I2C_MAX_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 + byte addr = 0x2C; // channel 0-3 + if (channel >= 4) { + addr = 0x2E; // channel 4-7 + channel -= 4; + } + + // Initial setup + i2c_send(addr, 0x40, 0xFF); + i2c_send(addr, 0xA0, 0xFF); + + // Set actual wiper value + byte addresses[4] = { 0x00, 0x10, 0x60, 0x70 }; + i2c_send(addr, addresses[channel], current_to_wiper(current)); +} + +void digipot_i2c_init() { + static const float digipot_motor_current[] PROGMEM = DIGIPOT_I2C_MOTOR_CURRENTS; + Wire.begin(); + // 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])); +} + +#endif // DIGIPOT_I2C diff --git a/trunk/Arduino/Marlin_1.1.6/dogm_bitmaps.h b/trunk/Arduino/Marlin_1.1.6/dogm_bitmaps.h new file mode 100644 index 00000000..9a77ff78 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/dogm_bitmaps.h @@ -0,0 +1,514 @@ +/** + * 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 . + * + */ + +/** + * Standard Marlin Bitmap for splashscreen + * + * You may use one of the following tools to generate the C++ bitmap array from + * a black and white image: + * + * - http://www.marlinfw.org/tools/u8glib/converter.html + * - http://www.digole.com/tools/PicturetoC_Hex_converter.php + * + * Please note that using the high-res version takes 402Bytes of PROGMEM. + */ + +//#define START_BMPHIGH + +#if ENABLED(SHOW_BOOTSCREEN) + #if ENABLED(START_BMPHIGH) + #define START_BMPWIDTH 112 + #define START_BMPHEIGHT 38 + #define START_BMPBYTEWIDTH 14 + #define START_BMPBYTES 532 // START_BMPWIDTH * START_BMPHEIGHT / 8 + + const unsigned char start_bmp[START_BMPBYTES] PROGMEM = { + 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, + 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, + 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, + 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x3F, 0xFF, + 0xC0, 0x0F, 0xC0, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x18, 0x00, 0x1F, 0xFF, + 0xC0, 0x3F, 0xE1, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x3C, 0x00, 0x0F, 0xFF, + 0xC0, 0x7F, 0xF3, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x78, 0x3C, 0x00, 0x07, 0xFF, + 0xC0, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x78, 0x3C, 0x00, 0x03, 0xFF, + 0xC1, 0xF8, 0x7F, 0x87, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x01, 0xFF, + 0xC1, 0xF0, 0x3F, 0x03, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0xFF, + 0xC1, 0xE0, 0x1E, 0x01, 0xE0, 0x1F, 0x00, 0x03, 0xE0, 0x78, 0x3C, 0x03, 0xF0, 0x7F, + 0xC1, 0xE0, 0x1E, 0x01, 0xE0, 0x7F, 0xC0, 0x0F, 0xF8, 0x78, 0x3C, 0x07, 0xFC, 0x3F, + 0xC1, 0xE0, 0x1E, 0x01, 0xE1, 0xFF, 0xE0, 0x1F, 0xFC, 0x78, 0x3C, 0x0F, 0xFE, 0x1F, + 0xC1, 0xE0, 0x1E, 0x01, 0xE3, 0xFF, 0xF0, 0x3F, 0xFE, 0x78, 0x3C, 0x1F, 0xFE, 0x0F, + 0xC1, 0xE0, 0x1E, 0x01, 0xE3, 0xF3, 0xF8, 0x3F, 0x3E, 0x78, 0x3C, 0x3F, 0x3F, 0x07, + 0xC1, 0xE0, 0x1E, 0x01, 0xE7, 0xE0, 0xFC, 0x7C, 0x1F, 0x78, 0x3C, 0x3E, 0x1F, 0x07, + 0xC1, 0xE0, 0x1E, 0x01, 0xE7, 0xC0, 0x7C, 0x7C, 0x0F, 0x78, 0x3C, 0x3C, 0x0F, 0x03, + 0xC1, 0xE0, 0x1E, 0x01, 0xE7, 0x80, 0x7C, 0x78, 0x0F, 0x78, 0x3C, 0x3C, 0x0F, 0x03, + 0xC1, 0xE0, 0x1E, 0x01, 0xE7, 0x80, 0x3C, 0x78, 0x00, 0x78, 0x3C, 0x3C, 0x0F, 0x03, + 0xC1, 0xE0, 0x1E, 0x01, 0xE7, 0x80, 0x3C, 0x78, 0x00, 0x78, 0x3C, 0x3C, 0x0F, 0x03, + 0xC1, 0xE0, 0x1E, 0x01, 0xE7, 0x80, 0x3C, 0x78, 0x00, 0x78, 0x3C, 0x3C, 0x0F, 0x03, + 0xC1, 0xE0, 0x1E, 0x01, 0xE7, 0xC0, 0x3C, 0x78, 0x00, 0x78, 0x3C, 0x3C, 0x0F, 0x03, + 0xC1, 0xE0, 0x1E, 0x01, 0xE3, 0xE0, 0x3C, 0x78, 0x00, 0x7C, 0x3C, 0x3C, 0x0F, 0x03, + 0xC1, 0xE0, 0x1E, 0x01, 0xE3, 0xFF, 0x3F, 0xF8, 0x00, 0x7F, 0xBC, 0x3C, 0x0F, 0x03, + 0xC1, 0xE0, 0x1E, 0x01, 0xE1, 0xFF, 0x3F, 0xF8, 0x00, 0x3F, 0xBF, 0xFC, 0x0F, 0x03, + 0xC1, 0xE0, 0x1E, 0x01, 0xE0, 0xFF, 0x3F, 0xF8, 0x00, 0x1F, 0xBF, 0xFC, 0x0F, 0x03, + 0xC1, 0xE0, 0x1E, 0x01, 0xE0, 0x7F, 0x3F, 0xF8, 0x00, 0x0F, 0xBF, 0xFC, 0x0F, 0x03, + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, + 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, + 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, + 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, + 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, + 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80 }; + #else + #define START_BMPWIDTH 56 + #define START_BMPHEIGHT 19 + #define START_BMPBYTEWIDTH 7 + #define START_BMPBYTES 133 // START_BMPWIDTH * START_BMPHEIGHT / 8 + + const unsigned char start_bmp[START_BMPBYTES] PROGMEM = { + 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x60, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, + 0x83, 0xCF, 0x00, 0x00, 0x0C, 0x30, 0x3F, + 0x87, 0xFF, 0x80, 0x00, 0x0C, 0x30, 0x1F, + 0x86, 0x79, 0x80, 0x00, 0x0C, 0x00, 0x0F, + 0x8C, 0x30, 0xC7, 0x83, 0x8C, 0x30, 0xE7, + 0x8C, 0x30, 0xCF, 0xC7, 0xCC, 0x31, 0xF3, + 0x8C, 0x30, 0xDC, 0xEC, 0xEC, 0x33, 0xB9, + 0x8C, 0x30, 0xD8, 0x6C, 0x6C, 0x33, 0x19, + 0x8C, 0x30, 0xD0, 0x6C, 0x0C, 0x33, 0x19, + 0x8C, 0x30, 0xD8, 0x6C, 0x0C, 0x33, 0x19, + 0x8C, 0x30, 0xDC, 0x6C, 0x0E, 0x3B, 0x19, + 0x8C, 0x30, 0xCF, 0x7C, 0x07, 0x9F, 0x19, + 0x8C, 0x30, 0xC7, 0x7C, 0x03, 0x8F, 0x19, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, + 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8 }; + #endif +#endif + +// Here comes a compile-time operation to match the extruder symbols +// on the info screen to the set number of extruders in configuration.h +// +// When only one extruder is selected, the "1" on the symbol will not +// be displayed. + +#if HAS_TEMP_BED + #if HOTENDS == 1 + #define STATUS_SCREENWIDTH 115 //Width in pixels + #define STATUS_SCREENHEIGHT 19 //Height in pixels + #define STATUS_SCREENBYTEWIDTH 15 //Width in bytes + const unsigned char status_screen0_bmp[] PROGMEM = { //AVR-GCC, WinAVR + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x0C, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x0E, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4F, 0x0F, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x0F, 0xA0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5E, 0x07, 0xA0, + 0x7F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x04, 0x00, 0x40, 0x60, 0x20, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x82, 0x00, 0x40, 0xF0, 0x20, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x82, 0x00, 0x40, 0xF0, 0x20, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x04, 0x00, 0x40, 0x60, 0x20, + 0x7F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x08, 0x00, 0x5E, 0x07, 0xA0, + 0x7F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x10, 0x00, 0x5F, 0x0F, 0xA0, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x10, 0x00, 0x4F, 0x0F, 0x20, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x08, 0x00, 0x47, 0x0E, 0x20, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x04, 0x00, 0x63, 0x0C, 0x60, + 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, + 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x7F, 0xFF, 0xE0, + 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00 + }; + + #define STATUS_SCREENWIDTH 115 //Width in pixels + #define STATUS_SCREENHEIGHT 19 //Height in pixels + #define STATUS_SCREENBYTEWIDTH 15 //Width in bytes + const unsigned char status_screen1_bmp[] PROGMEM = { //AVR-GCC, WinAVR + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0xF8, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xF8, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xF0, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x60, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x01, 0xA0, + 0x7F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x04, 0x00, 0x5C, 0x63, 0xA0, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x82, 0x00, 0x5E, 0xF7, 0xA0, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x82, 0x00, 0x5E, 0xF7, 0xA0, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x04, 0x00, 0x5C, 0x63, 0xA0, + 0x7F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x08, 0x00, 0x58, 0x01, 0xA0, + 0x7F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x10, 0x00, 0x40, 0x60, 0x20, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x10, 0x00, 0x40, 0xF0, 0x20, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x08, 0x00, 0x41, 0xF8, 0x20, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x04, 0x00, 0x61, 0xF8, 0x60, + 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, + 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x7F, 0xFF, 0xE0, + 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00 + }; + #elif HOTENDS == 2 + #define STATUS_SCREENWIDTH 115 //Width in pixels + #define STATUS_SCREENHEIGHT 19 //Height in pixels + #define STATUS_SCREENBYTEWIDTH 15 //Width in bytes + const unsigned char status_screen0_bmp[] PROGMEM = { //AVR-GCC, WinAVR + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x0C, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x0E, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4F, 0x0F, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x0F, 0xA0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5E, 0x07, 0xA0, + 0x7F, 0x80, 0x00, 0x3F, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x41, 0x04, 0x00, 0x40, 0x60, 0x20, + 0xFB, 0xC0, 0x00, 0x79, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x20, 0x82, 0x00, 0x40, 0xF0, 0x20, + 0xF3, 0xC0, 0x00, 0x76, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x20, 0x82, 0x00, 0x40, 0xF0, 0x20, + 0xEB, 0xC0, 0x00, 0x7E, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x41, 0x04, 0x00, 0x40, 0x60, 0x20, + 0x7B, 0x80, 0x00, 0x3D, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x82, 0x08, 0x00, 0x5E, 0x07, 0xA0, + 0x7B, 0x80, 0x00, 0x3B, 0xC0, 0x00, 0x00, 0x00, 0x01, 0x04, 0x10, 0x00, 0x5F, 0x0F, 0xA0, + 0xFB, 0xC0, 0x00, 0x77, 0xE0, 0x00, 0x00, 0x00, 0x01, 0x04, 0x10, 0x00, 0x4F, 0x0F, 0x20, + 0xFB, 0xC0, 0x00, 0x70, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x82, 0x08, 0x00, 0x47, 0x0E, 0x20, + 0xFF, 0xC0, 0x00, 0x7F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x41, 0x04, 0x00, 0x63, 0x0C, 0x60, + 0x3F, 0x00, 0x00, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, + 0x1E, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x7F, 0xFF, 0xE0, + 0x0C, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00 + }; + + #define STATUS_SCREENWIDTH 115 //Width in pixels + #define STATUS_SCREENHEIGHT 19 //Height in pixels + #define STATUS_SCREENBYTEWIDTH 15 //Width in bytes + const unsigned char status_screen1_bmp[] PROGMEM = { //AVR-GCC, WinAVR + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0xF8, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xF8, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xF0, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x60, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x01, 0xA0, + 0x7F, 0x80, 0x00, 0x3F, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x41, 0x04, 0x00, 0x5C, 0x63, 0xA0, + 0xFB, 0xC0, 0x00, 0x79, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x20, 0x82, 0x00, 0x5E, 0xF7, 0xA0, + 0xF3, 0xC0, 0x00, 0x76, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x20, 0x82, 0x00, 0x5E, 0xF7, 0xA0, + 0xEB, 0xC0, 0x00, 0x7E, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x41, 0x04, 0x00, 0x5C, 0x63, 0xA0, + 0x7B, 0x80, 0x00, 0x3D, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x82, 0x08, 0x00, 0x58, 0x01, 0xA0, + 0x7B, 0x80, 0x00, 0x3B, 0xC0, 0x00, 0x00, 0x00, 0x01, 0x04, 0x10, 0x00, 0x40, 0x60, 0x20, + 0xFB, 0xC0, 0x00, 0x77, 0xE0, 0x00, 0x00, 0x00, 0x01, 0x04, 0x10, 0x00, 0x40, 0xF0, 0x20, + 0xFB, 0xC0, 0x00, 0x70, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x82, 0x08, 0x00, 0x41, 0xF8, 0x20, + 0xFF, 0xC0, 0x00, 0x7F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x41, 0x04, 0x00, 0x61, 0xF8, 0x60, + 0x3F, 0x00, 0x00, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, + 0x1E, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x7F, 0xFF, 0xE0, + 0x0C, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00 + }; + #else + #define STATUS_SCREENWIDTH 115 //Width in pixels + #define STATUS_SCREENHEIGHT 19 //Height in pixels + #define STATUS_SCREENBYTEWIDTH 15 //Width in bytes + const unsigned char status_screen0_bmp[] PROGMEM = { //AVR-GCC, WinAVR + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x0C, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x0E, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4F, 0x0F, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x0F, 0xA0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5E, 0x07, 0xA0, + 0x7F, 0x80, 0x00, 0x3F, 0xC0, 0x00, 0x3F, 0xC0, 0x00, 0x41, 0x04, 0x00, 0x40, 0x60, 0x20, + 0xFB, 0xC0, 0x00, 0x79, 0xE0, 0x00, 0x79, 0xE0, 0x00, 0x20, 0x82, 0x00, 0x40, 0xF0, 0x20, + 0xF3, 0xC0, 0x00, 0x76, 0xE0, 0x00, 0x76, 0xE0, 0x00, 0x20, 0x82, 0x00, 0x40, 0xF0, 0x20, + 0xEB, 0xC0, 0x00, 0x7E, 0xE0, 0x00, 0x7E, 0xE0, 0x00, 0x41, 0x04, 0x00, 0x40, 0x60, 0x20, + 0x7B, 0x80, 0x00, 0x3D, 0xC0, 0x00, 0x39, 0xC0, 0x00, 0x82, 0x08, 0x00, 0x5E, 0x07, 0xA0, + 0x7B, 0x80, 0x00, 0x3B, 0xC0, 0x00, 0x3E, 0xC0, 0x01, 0x04, 0x10, 0x00, 0x5F, 0x0F, 0xA0, + 0xFB, 0xC0, 0x00, 0x77, 0xE0, 0x00, 0x76, 0xE0, 0x01, 0x04, 0x10, 0x00, 0x4F, 0x0F, 0x20, + 0xFB, 0xC0, 0x00, 0x70, 0xE0, 0x00, 0x79, 0xE0, 0x00, 0x82, 0x08, 0x00, 0x47, 0x0E, 0x20, + 0xFF, 0xC0, 0x00, 0x7F, 0xE0, 0x00, 0x7F, 0xE0, 0x00, 0x41, 0x04, 0x00, 0x63, 0x0C, 0x60, + 0x3F, 0x00, 0x00, 0x1F, 0x80, 0x00, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, + 0x1E, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x0F, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x7F, 0xFF, 0xE0, + 0x0C, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00 + }; + + #define STATUS_SCREENWIDTH 115 //Width in pixels + #define STATUS_SCREENHEIGHT 19 //Height in pixels + #define STATUS_SCREENBYTEWIDTH 15 //Width in bytes + const unsigned char status_screen1_bmp[] PROGMEM = { //AVR-GCC, WinAVR + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0xF8, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xF8, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xF0, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x60, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x01, 0xA0, + 0x7F, 0x80, 0x00, 0x3F, 0xC0, 0x00, 0x3F, 0xC0, 0x00, 0x41, 0x04, 0x00, 0x5C, 0x63, 0xA0, + 0xFB, 0xC0, 0x00, 0x79, 0xE0, 0x00, 0x79, 0xE0, 0x00, 0x20, 0x82, 0x00, 0x5E, 0xF7, 0xA0, + 0xF3, 0xC0, 0x00, 0x76, 0xE0, 0x00, 0x76, 0xE0, 0x00, 0x20, 0x82, 0x00, 0x5E, 0xF7, 0xA0, + 0xEB, 0xC0, 0x00, 0x7E, 0xE0, 0x00, 0x7E, 0xE0, 0x00, 0x41, 0x04, 0x00, 0x5C, 0x63, 0xA0, + 0x7B, 0x80, 0x00, 0x3D, 0xC0, 0x00, 0x39, 0xC0, 0x00, 0x82, 0x08, 0x00, 0x58, 0x01, 0xA0, + 0x7B, 0x80, 0x00, 0x3B, 0xC0, 0x00, 0x3E, 0xC0, 0x01, 0x04, 0x10, 0x00, 0x40, 0x60, 0x20, + 0xFB, 0xC0, 0x00, 0x77, 0xE0, 0x00, 0x76, 0xE0, 0x01, 0x04, 0x10, 0x00, 0x40, 0xF0, 0x20, + 0xFB, 0xC0, 0x00, 0x70, 0xE0, 0x00, 0x79, 0xE0, 0x00, 0x82, 0x08, 0x00, 0x41, 0xF8, 0x20, + 0xFF, 0xC0, 0x00, 0x7F, 0xE0, 0x00, 0x7F, 0xE0, 0x00, 0x41, 0x04, 0x00, 0x61, 0xF8, 0x60, + 0x3F, 0x00, 0x00, 0x1F, 0x80, 0x00, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, + 0x1E, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x0F, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x7F, 0xFF, 0xE0, + 0x0C, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00 + }; + #endif // Extruders +#else + #if HOTENDS == 1 + #define STATUS_SCREENWIDTH 115 //Width in pixels + #define STATUS_SCREENHEIGHT 19 //Height in pixels + #define STATUS_SCREENBYTEWIDTH 15 //Width in bytes + const unsigned char status_screen0_bmp[] PROGMEM = { //AVR-GCC, WinAVR + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x0C, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x0E, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4F, 0x0F, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x0F, 0xA0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5E, 0x07, 0xA0, + 0x7F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x60, 0x20, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xF0, 0x20, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xF0, 0x20, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x60, 0x20, + 0x7F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5E, 0x07, 0xA0, + 0x7F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x0F, 0xA0, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4F, 0x0F, 0x20, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x0E, 0x20, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x0C, 0x60, + 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, + 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, + 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + #define STATUS_SCREENWIDTH 115 //Width in pixels + #define STATUS_SCREENHEIGHT 19 //Height in pixels + #define STATUS_SCREENBYTEWIDTH 15 //Width in bytes + const unsigned char status_screen1_bmp[] PROGMEM = { //AVR-GCC, WinAVR + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0xF8, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xF8, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xF0, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x60, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x01, 0xA0, + 0x7F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5C, 0x63, 0xA0, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5E, 0xF7, 0xA0, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5E, 0xF7, 0xA0, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5C, 0x63, 0xA0, + 0x7F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x01, 0xA0, + 0x7F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x60, 0x20, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xF0, 0x20, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xF8, 0x20, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0xF8, 0x60, + 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, + 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, + 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + #elif HOTENDS == 2 + #define STATUS_SCREENWIDTH 115 //Width in pixels + #define STATUS_SCREENHEIGHT 19 //Height in pixels + #define STATUS_SCREENBYTEWIDTH 15 //Width in bytes + const unsigned char status_screen0_bmp[] PROGMEM = { //AVR-GCC, WinAVR + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x0C, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x0E, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4F, 0x0F, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x0F, 0xA0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5E, 0x07, 0xA0, + 0x7F, 0x80, 0x00, 0x3F, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x60, 0x20, + 0xFB, 0xC0, 0x00, 0x79, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xF0, 0x20, + 0xF3, 0xC0, 0x00, 0x76, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xF0, 0x20, + 0xEB, 0xC0, 0x00, 0x7E, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x60, 0x20, + 0x7B, 0x80, 0x00, 0x3D, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5E, 0x07, 0xA0, + 0x7B, 0x80, 0x00, 0x3B, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x0F, 0xA0, + 0xFB, 0xC0, 0x00, 0x77, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4F, 0x0F, 0x20, + 0xFB, 0xC0, 0x00, 0x70, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x0E, 0x20, + 0xFF, 0xC0, 0x00, 0x7F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x0C, 0x60, + 0x3F, 0x00, 0x00, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, + 0x1E, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, + 0x0C, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + #define STATUS_SCREENWIDTH 115 //Width in pixels + #define STATUS_SCREENHEIGHT 19 //Height in pixels + #define STATUS_SCREENBYTEWIDTH 15 //Width in bytes + const unsigned char status_screen1_bmp[] PROGMEM = { //AVR-GCC, WinAVR + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0xF8, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xF8, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xF0, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x60, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x01, 0xA0, + 0x7F, 0x80, 0x00, 0x3F, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5C, 0x63, 0xA0, + 0xFB, 0xC0, 0x00, 0x79, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5E, 0xF7, 0xA0, + 0xF3, 0xC0, 0x00, 0x76, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5E, 0xF7, 0xA0, + 0xEB, 0xC0, 0x00, 0x7E, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5C, 0x63, 0xA0, + 0x7B, 0x80, 0x00, 0x3D, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x01, 0xA0, + 0x7B, 0x80, 0x00, 0x3B, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x60, 0x20, + 0xFB, 0xC0, 0x00, 0x77, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xF0, 0x20, + 0xFB, 0xC0, 0x00, 0x70, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xF8, 0x20, + 0xFF, 0xC0, 0x00, 0x7F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0xF8, 0x60, + 0x3F, 0x00, 0x00, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, + 0x1E, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, + 0x0C, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + #else + #define STATUS_SCREENWIDTH 115 //Width in pixels + #define STATUS_SCREENHEIGHT 19 //Height in pixels + #define STATUS_SCREENBYTEWIDTH 15 //Width in bytes + const unsigned char status_screen0_bmp[] PROGMEM = { //AVR-GCC, WinAVR + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x0C, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x0E, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4F, 0x0F, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x0F, 0xA0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5E, 0x07, 0xA0, + 0x7F, 0x80, 0x00, 0x3F, 0xC0, 0x00, 0x3F, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x40, 0x60, 0x20, + 0xFB, 0xC0, 0x00, 0x79, 0xE0, 0x00, 0x79, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x40, 0xF0, 0x20, + 0xF3, 0xC0, 0x00, 0x76, 0xE0, 0x00, 0x76, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x40, 0xF0, 0x20, + 0xEB, 0xC0, 0x00, 0x7E, 0xE0, 0x00, 0x7E, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x40, 0x60, 0x20, + 0x7B, 0x80, 0x00, 0x3D, 0xC0, 0x00, 0x39, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x5E, 0x07, 0xA0, + 0x7B, 0x80, 0x00, 0x3B, 0xC0, 0x00, 0x3E, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x0F, 0xA0, + 0xFB, 0xC0, 0x00, 0x77, 0xE0, 0x00, 0x76, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x4F, 0x0F, 0x20, + 0xFB, 0xC0, 0x00, 0x70, 0xE0, 0x00, 0x79, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x47, 0x0E, 0x20, + 0xFF, 0xC0, 0x00, 0x7F, 0xE0, 0x00, 0x7F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x63, 0x0C, 0x60, + 0x3F, 0x00, 0x00, 0x1F, 0x80, 0x00, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, + 0x1E, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, + 0x0C, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + #define STATUS_SCREENWIDTH 115 //Width in pixels + #define STATUS_SCREENHEIGHT 19 //Height in pixels + #define STATUS_SCREENBYTEWIDTH 15 //Width in bytes + const unsigned char status_screen1_bmp[] PROGMEM = { //AVR-GCC, WinAVR + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0xF8, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xF8, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xF0, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x60, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x01, 0xA0, + 0x7F, 0x80, 0x00, 0x3F, 0xC0, 0x00, 0x3F, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x5C, 0x63, 0xA0, + 0xFB, 0xC0, 0x00, 0x79, 0xE0, 0x00, 0x79, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x5E, 0xF7, 0xA0, + 0xF3, 0xC0, 0x00, 0x76, 0xE0, 0x00, 0x76, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x5E, 0xF7, 0xA0, + 0xEB, 0xC0, 0x00, 0x7E, 0xE0, 0x00, 0x7E, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x5C, 0x63, 0xA0, + 0x7B, 0x80, 0x00, 0x3D, 0xC0, 0x00, 0x39, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x58, 0x01, 0xA0, + 0x7B, 0x80, 0x00, 0x3B, 0xC0, 0x00, 0x3E, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x40, 0x60, 0x20, + 0xFB, 0xC0, 0x00, 0x77, 0xE0, 0x00, 0x76, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x40, 0xF0, 0x20, + 0xFB, 0xC0, 0x00, 0x70, 0xE0, 0x00, 0x79, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x41, 0xF8, 0x20, + 0xFF, 0xC0, 0x00, 0x7F, 0xE0, 0x00, 0x7F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x61, 0xF8, 0x60, + 0x3F, 0x00, 0x00, 0x1F, 0x80, 0x00, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, + 0x1E, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, + 0x0C, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + #endif // Extruders + + #if ENABLED(BABYSTEP_ZPROBE_GFX_OVERLAY) + const unsigned char cw_bmp[] PROGMEM = { //AVR-GCC, WinAVR + 0x07,0xf8,0x00, // 000001111111100000000000 + 0x0c,0x0c,0x00, // 000011000000110000000000 + 0x10,0x02,0x00, // 000100000000001000000000 + 0x20,0x01,0x00, // 001000000000000100000000 + 0x60,0x01,0x80, // 011000000000000100000000 + 0x40,0x00,0x80, // 010000000000000010000000 + 0x40,0x03,0xe0, // 010000000000000011100000 + 0x40,0x01,0xc0, // 010000000000000011000000 + 0x40,0x00,0x80, // 010000000000000010000000 + 0x40,0x00,0x00, // 010000000000000000000000 + 0x40,0x00,0x00, // 010000000000000000000000 + 0x60,0x00,0x00, // 011000000000000000000000 + 0x20,0x00,0x00, // 001000000000000000000000 + 0x10,0x00,0x00, // 000100000000000000000000 + 0x0c,0x0c,0x00, // 000011000000110000000000 + 0x07,0xf8,0x00 // 000001111111100000000000 + }; + + const unsigned char ccw_bmp[] PROGMEM = { //AVR-GCC, WinAVR + 0x01,0xfe,0x00, // 000000011111111000000000 + 0x03,0x03,0x00, // 000000110000001100000000 + 0x04,0x00,0x80, // 000001000000000010000000 + 0x08,0x00,0x40, // 000010000000000001000000 + 0x18,0x00,0x60, // 000110000000000001100000 + 0x10,0x00,0x20, // 000100000000000000100000 + 0x7c,0x00,0x20, // 011111000000000000100000 + 0x38,0x00,0x20, // 001110000000000000100000 + 0x10,0x00,0x20, // 000100000000000000100000 + 0x00,0x00,0x20, // 000000000000000000100000 + 0x00,0x00,0x20, // 000000000000000000100000 + 0x00,0x00,0x60, // 000000000000000001100000 + 0x00,0x00,0x40, // 000000000000000001000000 + 0x00,0x00,0x80, // 000000000000000010000000 + 0x03,0x03,0x00, // 000000110000001100000000 + 0x01,0xfe,0x00 // 000000011111111000000000 + }; + + + const unsigned char up_arrow_bmp[] PROGMEM = { //AVR-GCC, WinAVR + 0x06,0x00, // 000001100000 + 0x0F,0x00, // 000011110000 + 0x1F,0x80, // 000111111000 + 0x3F,0xC0, // 001111111100 + 0x06,0x00, // 000001100000 + 0x06,0x00, // 000001100000 + 0x06,0x00, // 000001100000 + 0x06,0x00, // 000001100000 + 0x06,0x00, // 000001100000 + 0x06,0x00, // 000001100000 + 0x06,0x00, // 000001100000 + 0x06,0x00, // 000001100000 + 0x06,0x00 // 000001100000 + }; + + const unsigned char down_arrow_bmp[] PROGMEM = { //AVR-GCC, WinAVR + 0x06,0x00, // 000001100000 + 0x06,0x00, // 000001100000 + 0x06,0x00, // 000001100000 + 0x06,0x00, // 000001100000 + 0x06,0x00, // 000001100000 + 0x06,0x00, // 000001100000 + 0x06,0x00, // 000001100000 + 0x06,0x00, // 000001100000 + 0x06,0x00, // 000001100000 + 0x3F,0xC0, // 001111111100 + 0x1F,0x80, // 000111111000 + 0x0F,0x00, // 000011110000 + 0x06,0x00 // 000001100000 + }; + + const unsigned char offset_bedline_bmp[] PROGMEM = { //AVR-GCC, WinAVR + 0xFF,0xFF,0xFF // 111111111111111111111111 + }; + + const unsigned char nozzle_bmp[] PROGMEM = { //AVR-GCC, WinAVR + 0x7F,0x80, // 0111111110000000 + 0xFF,0xC0, // 1111111111000000 + 0xFF,0xC0, // 1111111111000000 + 0xFF,0xC0, // 1111111111000000 + 0x7F,0x80, // 0111111110000000 + 0x7F,0x80, // 0111111110000000 + 0xFF,0xC0, // 1111111111000000 + 0xFF,0xC0, // 1111111111000000 + 0xFF,0xC0, // 1111111111000000 + 0x3F,0x00, // 0011111100000000 + 0x1E,0x00, // 0001111000000000 + 0x0C,0x00 // 0000110000000000 + }; + #endif // BABYSTEP_ZPROBE_GFX_OVERLAY +#endif // HAS_TEMP_BED diff --git a/trunk/Arduino/Marlin_1.1.6/dogm_font_data_6x9_marlin.h b/trunk/Arduino/Marlin_1.1.6/dogm_font_data_6x9_marlin.h new file mode 100644 index 00000000..f298a6ac --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/dogm_font_data_6x9_marlin.h @@ -0,0 +1,180 @@ +/** + * 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 . + * + */ + +/** + 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 + 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 + X Font ascent = 6 descent=-2 + 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 +}; diff --git a/trunk/Arduino/Marlin_1.1.6/dogm_font_data_HD44780_C.h b/trunk/Arduino/Marlin_1.1.6/dogm_font_data_HD44780_C.h new file mode 100644 index 00000000..21d4aaab --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/dogm_font_data_HD44780_C.h @@ -0,0 +1,194 @@ +/** + * 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 . + * + */ + +/** + Fontname: HD44780_C v1.2 + Copyright: A. Hardtung, public domain + Capital A Height: 7, '1' Height: 7 + Calculated Max Values w= 5 h= 8 x= 2 y= 7 dx= 6 dy= 0 ascent= 8 len= 8 + Font Bounding box w= 6 h= 9 x= 0 y=-2 + Calculated Min Values x= 0 y=-1 dx= 0 dy= 0 + Pure Font ascent = 7 descent=-1 + X Font ascent = 7 descent=-1 + Max Font ascent = 8 descent=-1 +*/ +#include +const u8g_fntpgm_uint8_t HD44780_C_5x7[2522] U8G_SECTION(".progmem.HD44780_C_5x7") = { + 0, 6, 9, 0, 254, 7, 1, 145, 3, 34, 32, 255, 255, 8, 255, 7, + 255, 0, 0, 0, 6, 0, 0, 1, 7, 7, 6, 2, 0, 128, 128, 128, + 128, 128, 0, 128, 3, 2, 2, 6, 1, 5, 160, 160, 5, 7, 7, 6, + 0, 0, 80, 80, 248, 80, 248, 80, 80, 5, 7, 7, 6, 0, 0, 32, + 120, 160, 112, 40, 240, 32, 5, 7, 7, 6, 0, 0, 192, 200, 16, 32, + 64, 152, 24, 5, 7, 7, 6, 0, 0, 96, 144, 160, 64, 168, 144, 104, + 2, 3, 3, 6, 1, 4, 192, 64, 128, 3, 7, 7, 6, 1, 0, 32, + 64, 128, 128, 128, 64, 32, 3, 7, 7, 6, 1, 0, 128, 64, 32, 32, + 32, 64, 128, 5, 5, 5, 6, 0, 1, 32, 168, 112, 168, 32, 5, 5, + 5, 6, 0, 1, 32, 32, 248, 32, 32, 2, 3, 3, 6, 2, 255, 192, + 64, 128, 5, 1, 1, 6, 0, 3, 248, 2, 2, 2, 6, 2, 0, 192, + 192, 5, 5, 5, 6, 0, 1, 8, 16, 32, 64, 128, 5, 7, 7, 6, + 0, 0, 112, 136, 152, 168, 200, 136, 112, 3, 7, 7, 6, 1, 0, 64, + 192, 64, 64, 64, 64, 224, 5, 7, 7, 6, 0, 0, 112, 136, 8, 112, + 128, 128, 248, 5, 7, 7, 6, 0, 0, 248, 16, 32, 16, 8, 8, 240, + 5, 7, 7, 6, 0, 0, 16, 48, 80, 144, 248, 16, 16, 5, 7, 7, + 6, 0, 0, 248, 128, 240, 8, 8, 136, 112, 5, 7, 7, 6, 0, 0, + 48, 64, 128, 240, 136, 136, 112, 5, 7, 7, 6, 0, 0, 248, 8, 16, + 32, 32, 32, 32, 5, 7, 7, 6, 0, 0, 112, 136, 136, 112, 136, 136, + 112, 5, 7, 7, 6, 0, 0, 112, 136, 136, 120, 8, 16, 96, 2, 5, + 5, 6, 2, 0, 192, 192, 0, 192, 192, 2, 6, 6, 6, 2, 255, 192, + 192, 0, 192, 64, 128, 4, 7, 7, 6, 0, 0, 16, 32, 64, 128, 64, + 32, 16, 5, 3, 3, 6, 0, 2, 248, 0, 248, 4, 7, 7, 6, 1, + 0, 128, 64, 32, 16, 32, 64, 128, 5, 7, 7, 6, 0, 0, 112, 136, + 8, 16, 32, 0, 32, 5, 6, 6, 6, 0, 0, 112, 136, 8, 104, 168, + 112, 5, 7, 7, 6, 0, 0, 112, 136, 136, 248, 136, 136, 136, 5, 7, + 7, 6, 0, 0, 240, 136, 136, 240, 136, 136, 240, 5, 7, 7, 6, 0, + 0, 112, 136, 128, 128, 128, 136, 112, 5, 7, 7, 6, 0, 0, 224, 144, + 136, 136, 136, 144, 224, 5, 7, 7, 6, 0, 0, 248, 128, 128, 240, 128, + 128, 248, 5, 7, 7, 6, 0, 0, 248, 128, 128, 240, 128, 128, 128, 5, + 7, 7, 6, 0, 0, 112, 136, 128, 184, 136, 136, 112, 5, 7, 7, 6, + 0, 0, 136, 136, 136, 248, 136, 136, 136, 1, 7, 7, 6, 2, 0, 128, + 128, 128, 128, 128, 128, 128, 5, 7, 7, 6, 0, 0, 56, 16, 16, 16, + 16, 144, 96, 5, 7, 7, 6, 0, 0, 136, 144, 160, 192, 160, 144, 136, + 5, 7, 7, 6, 0, 0, 128, 128, 128, 128, 128, 128, 248, 5, 7, 7, + 6, 0, 0, 136, 216, 168, 136, 136, 136, 136, 5, 7, 7, 6, 0, 0, + 136, 136, 200, 168, 152, 136, 136, 5, 7, 7, 6, 0, 0, 112, 136, 136, + 136, 136, 136, 112, 5, 7, 7, 6, 0, 0, 240, 136, 136, 240, 128, 128, + 128, 5, 7, 7, 6, 0, 0, 112, 136, 136, 136, 168, 144, 104, 5, 7, + 7, 6, 0, 0, 240, 136, 136, 240, 160, 144, 136, 5, 7, 7, 6, 0, + 0, 120, 128, 128, 112, 8, 8, 240, 5, 7, 7, 6, 0, 0, 248, 32, + 32, 32, 32, 32, 32, 5, 7, 7, 6, 0, 0, 136, 136, 136, 136, 136, + 136, 112, 5, 7, 7, 6, 0, 0, 136, 136, 136, 136, 136, 80, 32, 5, + 7, 7, 6, 0, 0, 136, 136, 136, 136, 136, 168, 80, 5, 7, 7, 6, + 0, 0, 136, 136, 80, 32, 80, 136, 136, 5, 7, 7, 6, 0, 0, 136, + 136, 136, 80, 32, 32, 32, 5, 7, 7, 6, 0, 0, 248, 8, 16, 32, + 64, 128, 248, 3, 7, 7, 6, 1, 0, 224, 128, 128, 128, 128, 128, 224, + 5, 7, 7, 6, 0, 0, 32, 112, 160, 160, 168, 112, 32, 3, 7, 7, + 6, 1, 0, 224, 32, 32, 32, 32, 32, 224, 5, 3, 3, 6, 0, 4, + 32, 80, 136, 5, 1, 1, 6, 0, 0, 248, 2, 2, 2, 6, 2, 5, + 128, 64, 5, 5, 5, 6, 0, 0, 112, 8, 120, 136, 120, 5, 7, 7, + 6, 0, 0, 128, 128, 176, 200, 136, 136, 240, 5, 5, 5, 6, 0, 0, + 112, 128, 128, 136, 112, 5, 7, 7, 6, 0, 0, 8, 8, 104, 152, 136, + 136, 120, 5, 5, 5, 6, 0, 0, 112, 136, 248, 128, 112, 5, 7, 7, + 6, 0, 0, 48, 72, 224, 64, 64, 64, 64, 5, 6, 6, 6, 0, 255, + 112, 136, 136, 120, 8, 112, 5, 7, 7, 6, 0, 0, 128, 128, 176, 200, + 136, 136, 136, 1, 7, 7, 6, 2, 0, 128, 0, 128, 128, 128, 128, 128, + 3, 8, 8, 6, 1, 255, 32, 0, 32, 32, 32, 32, 160, 64, 4, 7, + 7, 6, 0, 0, 128, 128, 144, 160, 192, 160, 144, 3, 7, 7, 6, 1, + 0, 192, 64, 64, 64, 64, 64, 224, 5, 5, 5, 6, 0, 0, 208, 168, + 168, 168, 168, 5, 5, 5, 6, 0, 0, 176, 200, 136, 136, 136, 5, 5, + 5, 6, 0, 0, 112, 136, 136, 136, 112, 5, 6, 6, 6, 0, 255, 240, + 136, 136, 240, 128, 128, 5, 6, 6, 6, 0, 255, 120, 136, 136, 120, 8, + 8, 5, 5, 5, 6, 0, 0, 176, 200, 128, 128, 128, 5, 5, 5, 6, + 0, 0, 112, 128, 112, 8, 240, 5, 7, 7, 6, 0, 0, 64, 64, 224, + 64, 64, 72, 48, 5, 5, 5, 6, 0, 0, 136, 136, 136, 152, 104, 5, + 5, 5, 6, 0, 0, 136, 136, 136, 80, 32, 5, 5, 5, 6, 0, 0, + 136, 136, 168, 168, 80, 5, 5, 5, 6, 0, 0, 136, 80, 32, 80, 136, + 5, 6, 6, 6, 0, 255, 136, 136, 136, 120, 8, 112, 5, 5, 5, 6, + 0, 0, 248, 16, 32, 64, 248, 5, 5, 5, 6, 0, 2, 184, 168, 168, + 168, 184, 5, 5, 5, 6, 0, 2, 184, 136, 184, 160, 184, 5, 5, 5, + 6, 0, 2, 184, 160, 184, 136, 184, 5, 6, 6, 6, 0, 1, 8, 40, + 72, 248, 64, 32, 5, 5, 5, 6, 0, 0, 56, 112, 224, 136, 240, 0, + 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, + 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, + 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, + 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, + 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, + 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, + 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, + 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 5, + 7, 7, 6, 0, 0, 248, 136, 128, 240, 136, 136, 240, 5, 7, 7, 6, + 0, 0, 248, 136, 128, 128, 128, 128, 128, 5, 7, 7, 6, 0, 0, 80, + 0, 248, 128, 240, 128, 248, 5, 7, 7, 6, 0, 0, 168, 168, 168, 112, + 168, 168, 168, 5, 7, 7, 6, 0, 0, 240, 8, 8, 112, 8, 8, 240, + 5, 7, 7, 6, 0, 0, 136, 136, 152, 168, 200, 136, 136, 5, 8, 8, + 6, 0, 0, 80, 32, 136, 152, 168, 168, 200, 136, 5, 7, 7, 6, 0, + 0, 120, 40, 40, 40, 40, 168, 72, 5, 7, 7, 6, 0, 0, 248, 136, + 136, 136, 136, 136, 136, 5, 7, 7, 6, 0, 0, 136, 136, 136, 80, 32, + 64, 128, 5, 7, 7, 6, 0, 0, 32, 112, 168, 168, 168, 112, 32, 5, + 7, 7, 6, 0, 0, 136, 136, 136, 120, 8, 8, 8, 5, 7, 7, 6, + 0, 0, 168, 168, 168, 168, 168, 168, 248, 5, 7, 7, 6, 0, 0, 192, + 64, 64, 112, 72, 72, 112, 5, 7, 7, 6, 0, 0, 136, 136, 136, 200, + 168, 168, 200, 5, 7, 7, 6, 0, 0, 112, 136, 8, 56, 8, 136, 112, + 5, 7, 7, 6, 0, 0, 144, 168, 168, 232, 168, 168, 144, 5, 7, 7, + 6, 0, 0, 120, 136, 136, 120, 40, 72, 136, 5, 7, 7, 6, 0, 0, + 24, 96, 128, 240, 136, 136, 112, 4, 5, 5, 6, 0, 0, 224, 144, 224, + 144, 224, 5, 5, 5, 6, 0, 0, 248, 136, 128, 128, 128, 5, 7, 7, + 6, 0, 0, 80, 0, 112, 136, 248, 128, 112, 5, 5, 5, 6, 0, 0, + 168, 168, 112, 168, 168, 5, 5, 5, 6, 0, 0, 240, 8, 48, 8, 240, + 5, 5, 5, 6, 0, 0, 136, 152, 168, 200, 136, 5, 7, 7, 6, 0, + 0, 80, 32, 136, 152, 168, 200, 136, 4, 5, 5, 6, 0, 0, 144, 160, + 192, 160, 144, 5, 5, 5, 6, 0, 0, 248, 40, 40, 168, 72, 5, 5, + 5, 6, 0, 0, 136, 216, 168, 136, 136, 5, 5, 5, 6, 0, 0, 136, + 136, 248, 136, 136, 5, 5, 5, 6, 0, 0, 248, 136, 136, 136, 136, 5, + 5, 5, 6, 0, 0, 248, 32, 32, 32, 32, 5, 5, 5, 6, 0, 0, + 136, 136, 120, 8, 8, 5, 5, 5, 6, 0, 0, 168, 168, 168, 168, 248, + 5, 5, 5, 6, 0, 0, 192, 64, 112, 72, 112, 5, 5, 5, 6, 0, + 0, 136, 136, 200, 168, 200, 4, 5, 5, 6, 0, 0, 128, 128, 224, 144, + 224, 5, 5, 5, 6, 0, 0, 112, 136, 56, 136, 112, 5, 5, 5, 6, + 0, 0, 144, 168, 232, 168, 144, 5, 5, 5, 6, 0, 0, 120, 136, 120, + 40, 72, 5, 5, 5, 6, 0, 1, 32, 72, 144, 72, 32, 5, 5, 5, + 6, 0, 1, 32, 144, 72, 144, 32, 5, 3, 3, 6, 0, 0, 72, 144, + 216, 5, 3, 3, 6, 0, 4, 216, 72, 144, 5, 7, 7, 6, 0, 0, + 144, 208, 176, 144, 56, 40, 56, 5, 7, 7, 6, 0, 0, 32, 0, 32, + 64, 128, 136, 112, 5, 7, 7, 6, 0, 0, 24, 32, 32, 112, 32, 32, + 192, 5, 7, 7, 6, 0, 0, 32, 80, 64, 240, 64, 64, 120, 1, 2, + 2, 6, 2, 0, 128, 128, 1, 4, 4, 6, 2, 0, 128, 128, 128, 128, + 3, 5, 5, 6, 1, 0, 160, 160, 160, 0, 224, 3, 5, 5, 6, 1, + 0, 160, 160, 160, 0, 160, 5, 7, 7, 6, 0, 0, 160, 0, 232, 16, + 32, 64, 128, 5, 5, 5, 6, 0, 1, 216, 112, 32, 112, 216, 5, 7, + 7, 6, 0, 0, 160, 64, 168, 16, 32, 64, 128, 3, 6, 6, 6, 1, + 1, 224, 64, 64, 64, 64, 224, 5, 6, 6, 6, 0, 1, 248, 80, 80, + 80, 80, 248, 5, 7, 7, 6, 0, 0, 32, 112, 168, 32, 32, 32, 32, + 5, 7, 7, 6, 0, 0, 32, 32, 32, 32, 168, 112, 32, 5, 7, 7, + 6, 0, 0, 128, 144, 176, 248, 176, 144, 128, 5, 7, 7, 6, 0, 0, + 8, 72, 104, 248, 104, 72, 8, 5, 7, 7, 6, 0, 0, 128, 136, 168, + 248, 168, 136, 128, 5, 7, 7, 6, 0, 0, 128, 224, 136, 16, 32, 64, + 128, 2, 2, 2, 6, 2, 2, 192, 192, 5, 8, 8, 6, 0, 255, 120, + 40, 40, 40, 72, 136, 248, 136, 5, 8, 8, 6, 0, 255, 136, 136, 136, + 136, 136, 136, 248, 8, 5, 8, 8, 6, 0, 255, 168, 168, 168, 168, 168, + 168, 248, 8, 5, 6, 6, 6, 0, 255, 120, 40, 72, 136, 248, 136, 5, + 7, 7, 6, 0, 255, 32, 32, 112, 168, 168, 112, 32, 5, 6, 6, 6, + 0, 255, 136, 136, 136, 136, 248, 8, 5, 6, 6, 6, 0, 255, 168, 168, + 168, 168, 248, 8, 2, 2, 2, 6, 2, 6, 64, 128, 3, 1, 1, 6, + 1, 7, 160, 5, 2, 2, 6, 0, 6, 72, 176, 5, 8, 8, 6, 0, + 0, 16, 32, 0, 112, 136, 248, 128, 112, 5, 6, 6, 6, 0, 255, 112, + 128, 136, 112, 32, 96, 3, 7, 7, 6, 1, 0, 160, 0, 160, 160, 160, + 32, 192, 5, 6, 6, 6, 0, 1, 32, 112, 112, 112, 248, 32, 5, 5, + 5, 6, 0, 1, 80, 0, 136, 0, 80, 5, 5, 5, 6, 0, 1, 112, + 136, 136, 136, 112, 5, 7, 7, 6, 0, 0, 136, 144, 168, 88, 184, 8, + 8, 5, 7, 7, 6, 0, 0, 136, 144, 184, 72, 184, 8, 56, 5, 7, + 7, 6, 0, 0, 136, 144, 184, 72, 152, 32, 56, 5, 8, 8, 6, 0, + 0, 192, 64, 192, 72, 216, 56, 8, 8, 5, 7, 7, 6, 0, 0, 136, + 248, 136, 248, 136, 248, 136, 4, 5, 5, 6, 0, 2, 192, 0, 48, 0, + 96, 5, 8, 8, 6, 0, 0, 64, 160, 224, 168, 8, 40, 120, 32, 5, + 8, 8, 6, 0, 0, 64, 112, 64, 120, 64, 112, 64, 224, 5, 8, 8, + 6, 0, 0, 32, 112, 32, 248, 32, 112, 32, 112, 5, 7, 7, 6, 0, + 0, 104, 0, 232, 0, 104, 16, 56, 5, 8, 8, 6, 0, 0, 16, 112, + 16, 240, 16, 112, 16, 56, 5, 7, 7, 6, 0, 1, 32, 112, 32, 248, + 32, 112, 32, 5, 8, 8, 6, 0, 0, 16, 144, 80, 48, 80, 144, 16, + 56, 5, 8, 8, 6, 0, 0, 48, 72, 32, 80, 80, 32, 144, 96, 5, + 7, 7, 6, 0, 0, 120, 168, 168, 120, 40, 40, 40, 5, 8, 8, 6, + 0, 0, 248, 248, 248, 248, 248, 248, 248, 248 +}; diff --git a/trunk/Arduino/Marlin_1.1.6/dogm_font_data_HD44780_J.h b/trunk/Arduino/Marlin_1.1.6/dogm_font_data_HD44780_J.h new file mode 100644 index 00000000..e4884c7c --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/dogm_font_data_HD44780_J.h @@ -0,0 +1,192 @@ +/** + * 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 . + * + */ + +/** + Fontname: HD44780_J + Copyright: A. Hardtung, public domain + Capital A Height: 7, '1' Height: 7 + Calculated Max Values w= 6 h=10 x= 2 y= 5 dx= 6 dy= 0 ascent= 8 len= 8 + 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 = 7 descent=-1 + X Font ascent = 7 descent=-1 + Max Font ascent = 8 descent=-2 +*/ +#include +const u8g_fntpgm_uint8_t HD44780_J_5x7[2492] U8G_SECTION(".progmem.HD44780_J_5x7") = { + 0, 6, 9, 0, 254, 7, 1, 145, 3, 34, 32, 255, 255, 8, 254, 7, + 255, 0, 0, 0, 6, 0, 0, 1, 7, 7, 6, 2, 0, 128, 128, 128, + 128, 128, 0, 128, 3, 2, 2, 6, 1, 5, 160, 160, 5, 7, 7, 6, + 0, 0, 80, 80, 248, 80, 248, 80, 80, 5, 7, 7, 6, 0, 0, 32, + 120, 160, 112, 40, 240, 32, 5, 7, 7, 6, 0, 0, 192, 200, 16, 32, + 64, 152, 24, 5, 7, 7, 6, 0, 0, 96, 144, 160, 64, 168, 144, 104, + 2, 3, 3, 6, 1, 4, 192, 64, 128, 3, 7, 7, 6, 1, 0, 32, + 64, 128, 128, 128, 64, 32, 3, 7, 7, 6, 1, 0, 128, 64, 32, 32, + 32, 64, 128, 5, 5, 5, 6, 0, 1, 32, 168, 112, 168, 32, 5, 5, + 5, 6, 0, 1, 32, 32, 248, 32, 32, 2, 3, 3, 6, 2, 255, 192, + 64, 128, 5, 1, 1, 6, 0, 3, 248, 2, 2, 2, 6, 2, 0, 192, + 192, 5, 5, 5, 6, 0, 1, 8, 16, 32, 64, 128, 5, 7, 7, 6, + 0, 0, 112, 136, 152, 168, 200, 136, 112, 3, 7, 7, 6, 1, 0, 64, + 192, 64, 64, 64, 64, 224, 5, 7, 7, 6, 0, 0, 112, 136, 8, 112, + 128, 128, 248, 5, 7, 7, 6, 0, 0, 248, 16, 32, 16, 8, 8, 240, + 5, 7, 7, 6, 0, 0, 16, 48, 80, 144, 248, 16, 16, 5, 7, 7, + 6, 0, 0, 248, 128, 240, 8, 8, 136, 112, 5, 7, 7, 6, 0, 0, + 48, 64, 128, 240, 136, 136, 112, 5, 7, 7, 6, 0, 0, 248, 8, 16, + 32, 32, 32, 32, 5, 7, 7, 6, 0, 0, 112, 136, 136, 112, 136, 136, + 112, 5, 7, 7, 6, 0, 0, 112, 136, 136, 120, 8, 16, 96, 2, 5, + 5, 6, 2, 0, 192, 192, 0, 192, 192, 2, 6, 6, 6, 2, 255, 192, + 192, 0, 192, 64, 128, 4, 7, 7, 6, 0, 0, 16, 32, 64, 128, 64, + 32, 16, 5, 3, 3, 6, 0, 2, 248, 0, 248, 4, 7, 7, 6, 1, + 0, 128, 64, 32, 16, 32, 64, 128, 5, 7, 7, 6, 0, 0, 112, 136, + 8, 16, 32, 0, 32, 5, 6, 6, 6, 0, 0, 112, 136, 8, 104, 168, + 112, 5, 7, 7, 6, 0, 0, 112, 136, 136, 248, 136, 136, 136, 5, 7, + 7, 6, 0, 0, 240, 136, 136, 240, 136, 136, 240, 5, 7, 7, 6, 0, + 0, 112, 136, 128, 128, 128, 136, 112, 5, 7, 7, 6, 0, 0, 224, 144, + 136, 136, 136, 144, 224, 5, 7, 7, 6, 0, 0, 248, 128, 128, 240, 128, + 128, 248, 5, 7, 7, 6, 0, 0, 248, 128, 128, 240, 128, 128, 128, 5, + 7, 7, 6, 0, 0, 112, 136, 128, 184, 136, 136, 112, 5, 7, 7, 6, + 0, 0, 136, 136, 136, 248, 136, 136, 136, 1, 7, 7, 6, 2, 0, 128, + 128, 128, 128, 128, 128, 128, 5, 7, 7, 6, 0, 0, 56, 16, 16, 16, + 16, 144, 96, 5, 7, 7, 6, 0, 0, 136, 144, 160, 192, 160, 144, 136, + 5, 7, 7, 6, 0, 0, 128, 128, 128, 128, 128, 128, 248, 5, 7, 7, + 6, 0, 0, 136, 216, 168, 136, 136, 136, 136, 5, 7, 7, 6, 0, 0, + 136, 136, 200, 168, 152, 136, 136, 5, 7, 7, 6, 0, 0, 112, 136, 136, + 136, 136, 136, 112, 5, 7, 7, 6, 0, 0, 240, 136, 136, 240, 128, 128, + 128, 5, 7, 7, 6, 0, 0, 112, 136, 136, 136, 168, 144, 104, 5, 7, + 7, 6, 0, 0, 240, 136, 136, 240, 160, 144, 136, 5, 7, 7, 6, 0, + 0, 120, 128, 128, 112, 8, 8, 240, 5, 7, 7, 6, 0, 0, 248, 32, + 32, 32, 32, 32, 32, 5, 7, 7, 6, 0, 0, 136, 136, 136, 136, 136, + 136, 112, 5, 7, 7, 6, 0, 0, 136, 136, 136, 136, 136, 80, 32, 5, + 7, 7, 6, 0, 0, 136, 136, 136, 136, 136, 168, 80, 5, 7, 7, 6, + 0, 0, 136, 136, 80, 32, 80, 136, 136, 5, 7, 7, 6, 0, 0, 136, + 136, 136, 80, 32, 32, 32, 5, 7, 7, 6, 0, 0, 248, 8, 16, 32, + 64, 128, 248, 3, 7, 7, 6, 1, 0, 224, 128, 128, 128, 128, 128, 224, + 5, 7, 7, 6, 0, 0, 136, 80, 248, 32, 248, 32, 32, 3, 7, 7, + 6, 1, 0, 224, 32, 32, 32, 32, 32, 224, 5, 3, 3, 6, 0, 4, + 32, 80, 136, 5, 1, 1, 6, 0, 0, 248, 2, 2, 2, 6, 2, 5, + 128, 64, 5, 5, 5, 6, 0, 0, 112, 8, 120, 136, 120, 5, 7, 7, + 6, 0, 0, 128, 128, 176, 200, 136, 136, 240, 5, 5, 5, 6, 0, 0, + 112, 128, 128, 136, 112, 5, 7, 7, 6, 0, 0, 8, 8, 104, 152, 136, + 136, 120, 5, 5, 5, 6, 0, 0, 112, 136, 248, 128, 112, 5, 7, 7, + 6, 0, 0, 48, 72, 224, 64, 64, 64, 64, 5, 6, 6, 6, 0, 255, + 112, 136, 136, 120, 8, 112, 5, 7, 7, 6, 0, 0, 128, 128, 176, 200, + 136, 136, 136, 1, 7, 7, 6, 2, 0, 128, 0, 128, 128, 128, 128, 128, + 3, 8, 8, 6, 1, 255, 32, 0, 32, 32, 32, 32, 160, 64, 4, 7, + 7, 6, 0, 0, 128, 128, 144, 160, 192, 160, 144, 3, 7, 7, 6, 1, + 0, 192, 64, 64, 64, 64, 64, 224, 5, 5, 5, 6, 0, 0, 208, 168, + 168, 168, 168, 5, 5, 5, 6, 0, 0, 176, 200, 136, 136, 136, 5, 5, + 5, 6, 0, 0, 112, 136, 136, 136, 112, 5, 6, 6, 6, 0, 255, 240, + 136, 136, 240, 128, 128, 5, 6, 6, 6, 0, 255, 120, 136, 136, 120, 8, + 8, 5, 5, 5, 6, 0, 0, 176, 200, 128, 128, 128, 5, 5, 5, 6, + 0, 0, 112, 128, 112, 8, 240, 5, 7, 7, 6, 0, 0, 64, 64, 224, + 64, 64, 72, 48, 5, 5, 5, 6, 0, 0, 136, 136, 136, 152, 104, 5, + 5, 5, 6, 0, 0, 136, 136, 136, 80, 32, 5, 5, 5, 6, 0, 0, + 136, 136, 168, 168, 80, 5, 5, 5, 6, 0, 0, 136, 80, 32, 80, 136, + 5, 6, 6, 6, 0, 255, 136, 136, 136, 120, 8, 112, 5, 5, 5, 6, + 0, 0, 248, 16, 32, 64, 248, 3, 7, 7, 6, 1, 0, 32, 64, 64, + 128, 64, 64, 32, 1, 7, 7, 6, 2, 0, 128, 128, 128, 128, 128, 128, + 128, 3, 7, 7, 6, 1, 0, 128, 64, 64, 32, 64, 64, 128, 5, 5, + 5, 6, 0, 1, 32, 16, 248, 16, 32, 5, 5, 5, 6, 0, 1, 32, + 64, 248, 64, 32, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, + 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, + 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, + 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, + 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, + 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, + 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, + 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, + 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, + 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, + 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, + 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, + 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 3, 3, 3, 6, 0, 0, + 224, 160, 224, 3, 4, 4, 6, 2, 3, 224, 128, 128, 128, 3, 4, 4, + 6, 0, 0, 32, 32, 32, 224, 3, 3, 3, 6, 0, 0, 128, 64, 32, + 2, 2, 2, 6, 1, 2, 192, 192, 5, 6, 6, 6, 0, 0, 248, 8, + 248, 8, 16, 32, 5, 5, 5, 6, 0, 0, 248, 8, 48, 32, 64, 4, + 5, 5, 6, 0, 0, 16, 32, 96, 160, 32, 5, 5, 5, 6, 0, 0, + 32, 248, 136, 8, 48, 5, 4, 4, 6, 0, 0, 248, 32, 32, 248, 5, + 5, 5, 6, 0, 0, 16, 248, 48, 80, 144, 5, 5, 5, 6, 0, 0, + 64, 248, 72, 80, 64, 5, 4, 4, 6, 0, 0, 112, 16, 16, 248, 4, + 5, 5, 6, 0, 0, 240, 16, 240, 16, 240, 5, 4, 4, 6, 0, 0, + 168, 168, 8, 48, 5, 1, 1, 6, 0, 3, 248, 5, 7, 7, 6, 0, + 0, 248, 8, 40, 48, 32, 32, 64, 5, 7, 7, 6, 0, 0, 8, 16, + 32, 96, 160, 32, 32, 5, 7, 7, 6, 0, 0, 32, 248, 136, 136, 8, + 16, 32, 5, 6, 6, 6, 0, 0, 248, 32, 32, 32, 32, 248, 5, 7, + 7, 6, 0, 0, 16, 248, 16, 48, 80, 144, 16, 5, 7, 7, 6, 0, + 0, 64, 248, 72, 72, 72, 72, 144, 5, 7, 7, 6, 0, 0, 32, 248, + 32, 248, 32, 32, 32, 5, 6, 6, 6, 0, 0, 120, 72, 136, 8, 16, + 96, 5, 7, 7, 6, 0, 0, 64, 120, 144, 16, 16, 16, 32, 5, 6, + 6, 6, 0, 0, 248, 8, 8, 8, 8, 248, 5, 7, 7, 6, 0, 0, + 80, 248, 80, 80, 16, 32, 64, 5, 6, 6, 6, 0, 0, 192, 8, 200, + 8, 16, 224, 5, 6, 6, 6, 0, 0, 248, 8, 16, 32, 80, 136, 5, + 7, 7, 6, 0, 0, 64, 248, 72, 80, 64, 64, 56, 5, 6, 6, 6, + 0, 0, 136, 136, 72, 8, 16, 96, 5, 6, 6, 6, 0, 0, 120, 72, + 168, 24, 16, 96, 5, 7, 7, 6, 0, 0, 16, 224, 32, 248, 32, 32, + 64, 5, 6, 6, 6, 0, 0, 168, 168, 168, 8, 16, 32, 5, 7, 7, + 6, 0, 0, 112, 0, 248, 32, 32, 32, 64, 3, 7, 7, 6, 1, 0, + 128, 128, 128, 192, 160, 128, 128, 5, 7, 7, 6, 0, 0, 32, 32, 248, + 32, 32, 64, 128, 5, 6, 6, 6, 0, 0, 112, 0, 0, 0, 0, 248, + 5, 6, 6, 6, 0, 0, 248, 8, 80, 32, 80, 128, 5, 7, 7, 6, + 0, 0, 32, 248, 16, 32, 112, 168, 32, 3, 7, 7, 6, 1, 0, 32, + 32, 32, 32, 32, 64, 128, 5, 6, 6, 6, 0, 0, 32, 16, 136, 136, + 136, 136, 5, 7, 7, 6, 0, 0, 128, 128, 248, 128, 128, 128, 120, 5, + 6, 6, 6, 0, 0, 248, 8, 8, 8, 16, 96, 5, 5, 5, 6, 0, + 1, 64, 160, 16, 8, 8, 5, 7, 7, 6, 0, 0, 32, 248, 32, 32, + 168, 168, 32, 5, 6, 6, 6, 0, 0, 248, 8, 8, 80, 32, 16, 4, + 6, 6, 6, 1, 0, 224, 0, 224, 0, 224, 16, 5, 6, 6, 6, 0, + 0, 32, 64, 128, 136, 248, 8, 5, 6, 6, 6, 0, 0, 8, 8, 80, + 32, 80, 128, 5, 6, 6, 6, 0, 0, 248, 64, 248, 64, 64, 56, 5, + 7, 7, 6, 0, 0, 64, 64, 248, 72, 80, 64, 64, 5, 7, 7, 6, + 0, 0, 112, 16, 16, 16, 16, 16, 248, 5, 6, 6, 6, 0, 0, 248, + 8, 248, 8, 8, 248, 5, 7, 7, 6, 0, 0, 112, 0, 248, 8, 8, + 16, 32, 4, 7, 7, 6, 0, 0, 144, 144, 144, 144, 16, 32, 64, 5, + 6, 6, 6, 0, 0, 32, 160, 160, 168, 168, 176, 5, 7, 7, 6, 0, + 0, 128, 128, 128, 136, 144, 160, 192, 5, 6, 6, 6, 0, 0, 248, 136, + 136, 136, 136, 248, 5, 6, 6, 6, 0, 0, 248, 136, 136, 8, 16, 32, + 5, 6, 6, 6, 0, 0, 192, 0, 8, 8, 16, 224, 4, 3, 3, 6, + 0, 4, 32, 144, 64, 3, 3, 3, 6, 0, 4, 224, 160, 224, 5, 5, + 5, 6, 0, 1, 72, 168, 144, 144, 104, 5, 7, 7, 6, 0, 0, 80, + 0, 112, 8, 120, 136, 120, 4, 8, 8, 6, 1, 255, 96, 144, 144, 224, + 144, 144, 224, 128, 5, 5, 5, 6, 0, 0, 112, 128, 96, 136, 112, 5, + 6, 6, 6, 0, 255, 136, 136, 152, 232, 136, 128, 5, 5, 5, 6, 0, + 0, 120, 160, 144, 136, 112, 5, 7, 7, 6, 0, 254, 48, 72, 136, 136, + 240, 128, 128, 5, 8, 8, 6, 0, 254, 120, 136, 136, 136, 120, 8, 8, + 112, 5, 5, 5, 6, 0, 1, 56, 32, 32, 160, 64, 4, 3, 3, 6, + 0, 3, 16, 208, 16, 4, 8, 8, 6, 0, 255, 16, 0, 48, 16, 16, + 16, 144, 96, 3, 3, 3, 6, 0, 4, 160, 64, 160, 5, 7, 7, 6, + 0, 0, 32, 112, 160, 160, 168, 112, 32, 5, 7, 7, 6, 0, 0, 64, + 64, 224, 64, 224, 64, 120, 5, 7, 7, 6, 0, 0, 112, 0, 176, 200, + 136, 136, 136, 5, 7, 7, 6, 0, 0, 80, 0, 112, 136, 136, 136, 112, + 5, 7, 7, 6, 0, 255, 176, 200, 136, 136, 240, 128, 128, 5, 7, 7, + 6, 0, 255, 104, 152, 136, 136, 120, 8, 8, 5, 6, 6, 6, 0, 0, + 112, 136, 248, 136, 136, 112, 5, 3, 3, 6, 0, 2, 88, 168, 208, 5, + 5, 5, 6, 0, 0, 112, 136, 136, 80, 216, 5, 7, 7, 6, 0, 0, + 80, 0, 136, 136, 136, 152, 104, 5, 7, 7, 6, 0, 0, 248, 128, 64, + 32, 64, 128, 248, 5, 5, 5, 6, 0, 0, 248, 80, 80, 80, 152, 5, + 7, 7, 6, 0, 0, 248, 0, 136, 80, 32, 80, 136, 5, 7, 7, 6, + 0, 255, 136, 136, 136, 136, 120, 8, 112, 5, 6, 6, 6, 0, 0, 8, + 240, 32, 248, 32, 32, 5, 5, 5, 6, 0, 0, 248, 64, 120, 72, 136, + 5, 5, 5, 6, 0, 0, 248, 168, 248, 136, 136, 5, 5, 5, 6, 0, + 1, 32, 0, 248, 0, 32, 0, 0, 0, 6, 0, 0, 6, 10, 10, 6, + 0, 254, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252 +}; diff --git a/trunk/Arduino/Marlin_1.1.6/dogm_font_data_HD44780_W.h b/trunk/Arduino/Marlin_1.1.6/dogm_font_data_HD44780_W.h new file mode 100644 index 00000000..86b4bf4b --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/dogm_font_data_HD44780_W.h @@ -0,0 +1,226 @@ +/** + * 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 . + * + */ + +/** + Fontname: HD44780_W + Copyright: A.Hardtung, public domain + Capital A Height: 7, '1' Height: 7 + Calculated Max Values w= 5 h= 9 x= 2 y= 5 dx= 6 dy= 0 ascent= 8 len= 9 + Font Bounding box w= 6 h= 9 x= 0 y=-2 + Calculated Min Values x= 0 y=-1 dx= 0 dy= 0 + Pure Font ascent = 7 descent=-1 + X Font ascent = 7 descent=-1 + Max Font ascent = 8 descent=-1 +*/ +#include +const u8g_fntpgm_uint8_t HD44780_W_5x7[3034] U8G_SECTION(".progmem.HD44780_W_5x7") = { + 0, 6, 9, 0, 254, 7, 2, 79, 3, 222, 16, 255, 255, 8, 255, 7, + 255, 4, 7, 7, 6, 0, 0, 16, 48, 112, 240, 112, 48, 16, 4, 7, + 7, 6, 1, 0, 128, 192, 224, 240, 224, 192, 128, 5, 3, 3, 6, 0, + 4, 216, 72, 144, 5, 3, 3, 6, 0, 4, 216, 144, 72, 5, 7, 7, + 6, 0, 0, 32, 112, 248, 0, 32, 112, 248, 5, 7, 7, 6, 0, 0, + 248, 112, 32, 0, 248, 112, 32, 5, 5, 5, 6, 0, 1, 112, 248, 248, + 248, 112, 5, 7, 7, 6, 0, 0, 8, 8, 40, 72, 248, 64, 32, 5, + 7, 7, 6, 0, 0, 32, 112, 168, 32, 32, 32, 32, 5, 7, 7, 6, + 0, 0, 32, 32, 32, 32, 168, 112, 32, 5, 5, 5, 6, 0, 1, 32, + 64, 248, 64, 32, 5, 5, 5, 6, 0, 1, 32, 16, 248, 16, 32, 5, + 7, 7, 6, 0, 0, 16, 32, 64, 32, 16, 0, 248, 5, 7, 7, 6, + 0, 0, 64, 32, 16, 32, 64, 0, 248, 5, 5, 5, 6, 0, 1, 32, + 32, 112, 112, 248, 5, 5, 5, 6, 0, 0, 248, 112, 112, 32, 32, 0, + 0, 0, 6, 0, 0, 1, 7, 7, 6, 2, 0, 128, 128, 128, 128, 128, + 0, 128, 3, 2, 2, 6, 1, 5, 160, 160, 5, 7, 7, 6, 0, 0, + 80, 80, 248, 80, 248, 80, 80, 5, 7, 7, 6, 0, 0, 32, 120, 160, + 112, 40, 240, 32, 5, 7, 7, 6, 0, 0, 192, 200, 16, 32, 64, 152, + 24, 5, 7, 7, 6, 0, 0, 96, 144, 160, 64, 168, 144, 104, 2, 3, + 3, 6, 1, 4, 192, 64, 128, 3, 7, 7, 6, 1, 0, 32, 64, 128, + 128, 128, 64, 32, 3, 7, 7, 6, 1, 0, 128, 64, 32, 32, 32, 64, + 128, 5, 5, 5, 6, 0, 1, 32, 168, 112, 168, 32, 5, 5, 5, 6, + 0, 1, 32, 32, 248, 32, 32, 2, 3, 3, 6, 2, 255, 192, 64, 128, + 5, 1, 1, 6, 0, 3, 248, 2, 2, 2, 6, 2, 0, 192, 192, 5, + 5, 5, 6, 0, 1, 8, 16, 32, 64, 128, 5, 7, 7, 6, 0, 0, + 112, 136, 152, 168, 200, 136, 112, 3, 7, 7, 6, 1, 0, 64, 192, 64, + 64, 64, 64, 224, 5, 7, 7, 6, 0, 0, 112, 136, 8, 112, 128, 128, + 248, 5, 7, 7, 6, 0, 0, 248, 16, 32, 16, 8, 8, 240, 5, 7, + 7, 6, 0, 0, 16, 48, 80, 144, 248, 16, 16, 5, 7, 7, 6, 0, + 0, 248, 128, 240, 8, 8, 136, 112, 5, 7, 7, 6, 0, 0, 48, 64, + 128, 240, 136, 136, 112, 5, 7, 7, 6, 0, 0, 248, 8, 16, 32, 32, + 32, 32, 5, 7, 7, 6, 0, 0, 112, 136, 136, 112, 136, 136, 112, 5, + 7, 7, 6, 0, 0, 112, 136, 136, 120, 8, 16, 96, 2, 5, 5, 6, + 2, 0, 192, 192, 0, 192, 192, 2, 6, 6, 6, 2, 255, 192, 192, 0, + 192, 64, 128, 4, 7, 7, 6, 0, 0, 16, 32, 64, 128, 64, 32, 16, + 5, 3, 3, 6, 0, 2, 248, 0, 248, 4, 7, 7, 6, 1, 0, 128, + 64, 32, 16, 32, 64, 128, 5, 7, 7, 6, 0, 0, 112, 136, 8, 16, + 32, 0, 32, 5, 6, 6, 6, 0, 0, 112, 136, 8, 104, 168, 112, 5, + 7, 7, 6, 0, 0, 112, 136, 136, 248, 136, 136, 136, 5, 7, 7, 6, + 0, 0, 240, 136, 136, 240, 136, 136, 240, 5, 7, 7, 6, 0, 0, 112, + 136, 128, 128, 128, 136, 112, 5, 7, 7, 6, 0, 0, 224, 144, 136, 136, + 136, 144, 224, 5, 7, 7, 6, 0, 0, 248, 128, 128, 240, 128, 128, 248, + 5, 7, 7, 6, 0, 0, 248, 128, 128, 240, 128, 128, 128, 5, 7, 7, + 6, 0, 0, 112, 136, 128, 184, 136, 136, 112, 5, 7, 7, 6, 0, 0, + 136, 136, 136, 248, 136, 136, 136, 1, 7, 7, 6, 2, 0, 128, 128, 128, + 128, 128, 128, 128, 5, 7, 7, 6, 0, 0, 56, 16, 16, 16, 16, 144, + 96, 5, 7, 7, 6, 0, 0, 136, 144, 160, 192, 160, 144, 136, 5, 7, + 7, 6, 0, 0, 128, 128, 128, 128, 128, 128, 248, 5, 7, 7, 6, 0, + 0, 136, 216, 168, 136, 136, 136, 136, 5, 7, 7, 6, 0, 0, 136, 136, + 200, 168, 152, 136, 136, 5, 7, 7, 6, 0, 0, 112, 136, 136, 136, 136, + 136, 112, 5, 7, 7, 6, 0, 0, 240, 136, 136, 240, 128, 128, 128, 5, + 7, 7, 6, 0, 0, 112, 136, 136, 136, 168, 144, 104, 5, 7, 7, 6, + 0, 0, 240, 136, 136, 240, 160, 144, 136, 5, 7, 7, 6, 0, 0, 120, + 128, 128, 112, 8, 8, 240, 5, 7, 7, 6, 0, 0, 248, 32, 32, 32, + 32, 32, 32, 5, 7, 7, 6, 0, 0, 136, 136, 136, 136, 136, 136, 112, + 5, 7, 7, 6, 0, 0, 136, 136, 136, 136, 136, 80, 32, 5, 7, 7, + 6, 0, 0, 136, 136, 136, 136, 136, 168, 80, 5, 7, 7, 6, 0, 0, + 136, 136, 80, 32, 80, 136, 136, 5, 7, 7, 6, 0, 0, 136, 136, 136, + 80, 32, 32, 32, 5, 7, 7, 6, 0, 0, 248, 8, 16, 32, 64, 128, + 248, 3, 7, 7, 6, 1, 0, 224, 128, 128, 128, 128, 128, 224, 5, 5, + 5, 6, 0, 1, 128, 64, 32, 16, 8, 3, 7, 7, 6, 1, 0, 224, + 32, 32, 32, 32, 32, 224, 5, 3, 3, 6, 0, 4, 32, 80, 136, 5, + 1, 1, 6, 0, 0, 248, 2, 2, 2, 6, 2, 5, 128, 64, 5, 5, + 5, 6, 0, 0, 112, 8, 120, 136, 120, 5, 7, 7, 6, 0, 0, 128, + 128, 176, 200, 136, 136, 240, 5, 5, 5, 6, 0, 0, 112, 128, 128, 136, + 112, 5, 7, 7, 6, 0, 0, 8, 8, 104, 152, 136, 136, 120, 5, 5, + 5, 6, 0, 0, 112, 136, 248, 128, 112, 5, 7, 7, 6, 0, 0, 48, + 72, 224, 64, 64, 64, 64, 5, 6, 6, 6, 0, 255, 112, 136, 136, 120, + 8, 112, 5, 7, 7, 6, 0, 0, 128, 128, 176, 200, 136, 136, 136, 1, + 7, 7, 6, 2, 0, 128, 0, 128, 128, 128, 128, 128, 3, 8, 8, 6, + 1, 255, 32, 0, 32, 32, 32, 32, 160, 64, 4, 7, 7, 6, 0, 0, + 128, 128, 144, 160, 192, 160, 144, 3, 7, 7, 6, 1, 0, 192, 64, 64, + 64, 64, 64, 224, 5, 5, 5, 6, 0, 0, 208, 168, 168, 168, 168, 5, + 5, 5, 6, 0, 0, 176, 200, 136, 136, 136, 5, 5, 5, 6, 0, 0, + 112, 136, 136, 136, 112, 5, 6, 6, 6, 0, 255, 240, 136, 136, 240, 128, + 128, 5, 6, 6, 6, 0, 255, 120, 136, 136, 120, 8, 8, 5, 5, 5, + 6, 0, 0, 176, 200, 128, 128, 128, 5, 5, 5, 6, 0, 0, 112, 128, + 112, 8, 240, 5, 7, 7, 6, 0, 0, 64, 64, 224, 64, 64, 72, 48, + 5, 5, 5, 6, 0, 0, 136, 136, 136, 152, 104, 5, 5, 5, 6, 0, + 0, 136, 136, 136, 80, 32, 5, 5, 5, 6, 0, 0, 136, 136, 168, 168, + 80, 5, 5, 5, 6, 0, 0, 136, 80, 32, 80, 136, 5, 6, 6, 6, + 0, 255, 136, 136, 136, 120, 8, 112, 5, 5, 5, 6, 0, 0, 248, 16, + 32, 64, 248, 3, 7, 7, 6, 1, 0, 32, 64, 64, 128, 64, 64, 32, + 1, 7, 7, 6, 2, 0, 128, 128, 128, 128, 128, 128, 128, 3, 7, 7, + 6, 1, 0, 128, 64, 64, 32, 64, 64, 128, 5, 6, 6, 6, 0, 1, + 8, 40, 72, 248, 64, 32, 5, 7, 7, 6, 0, 0, 32, 80, 136, 136, + 136, 136, 248, 5, 7, 7, 6, 0, 0, 248, 136, 128, 240, 136, 136, 240, + 5, 8, 8, 6, 0, 255, 120, 40, 40, 40, 72, 136, 248, 136, 5, 7, + 7, 6, 0, 0, 168, 168, 168, 112, 168, 168, 168, 5, 7, 7, 6, 0, + 0, 240, 8, 8, 112, 8, 8, 240, 5, 7, 7, 6, 0, 0, 136, 136, + 152, 168, 200, 136, 136, 5, 8, 8, 6, 0, 0, 80, 32, 136, 152, 168, + 168, 200, 136, 5, 7, 7, 6, 0, 0, 120, 40, 40, 40, 40, 168, 72, + 5, 7, 7, 6, 0, 0, 248, 136, 136, 136, 136, 136, 136, 5, 7, 7, + 6, 0, 0, 136, 136, 136, 80, 32, 64, 128, 5, 8, 8, 6, 0, 255, + 136, 136, 136, 136, 136, 136, 248, 8, 5, 7, 7, 6, 0, 0, 136, 136, + 136, 120, 8, 8, 8, 5, 7, 7, 6, 0, 0, 168, 168, 168, 168, 168, + 168, 248, 5, 8, 8, 6, 0, 255, 168, 168, 168, 168, 168, 168, 248, 8, + 5, 7, 7, 6, 0, 0, 192, 64, 64, 112, 72, 72, 112, 5, 7, 7, + 6, 0, 0, 136, 136, 136, 200, 168, 168, 200, 5, 7, 7, 6, 0, 0, + 112, 136, 40, 80, 8, 136, 112, 5, 5, 5, 6, 0, 0, 64, 160, 144, + 144, 104, 5, 7, 7, 6, 0, 0, 32, 48, 40, 40, 32, 224, 224, 5, + 7, 7, 6, 0, 0, 248, 136, 128, 128, 128, 128, 128, 5, 5, 5, 6, + 0, 0, 248, 80, 80, 80, 152, 5, 7, 7, 6, 0, 0, 248, 128, 64, + 32, 64, 128, 248, 5, 5, 5, 6, 0, 0, 120, 144, 144, 144, 96, 5, + 7, 7, 6, 0, 0, 48, 40, 56, 40, 200, 216, 24, 5, 6, 6, 6, + 0, 0, 8, 112, 160, 32, 32, 16, 5, 6, 6, 6, 0, 1, 32, 112, + 112, 112, 248, 32, 5, 7, 7, 6, 0, 0, 112, 136, 136, 248, 136, 136, + 112, 5, 5, 5, 6, 0, 0, 112, 136, 136, 80, 216, 5, 7, 7, 6, + 0, 0, 48, 72, 32, 80, 136, 136, 112, 5, 3, 3, 6, 0, 2, 88, + 168, 208, 5, 6, 6, 6, 0, 0, 80, 248, 248, 248, 112, 32, 5, 5, + 5, 6, 0, 0, 112, 128, 96, 136, 112, 5, 7, 7, 6, 0, 0, 112, + 136, 136, 136, 136, 136, 136, 5, 7, 7, 6, 0, 0, 216, 216, 216, 216, + 216, 216, 216, 1, 7, 7, 6, 2, 0, 128, 0, 128, 128, 128, 128, 128, + 5, 7, 7, 6, 0, 0, 32, 112, 160, 160, 168, 112, 32, 5, 7, 7, + 6, 0, 0, 48, 64, 64, 224, 64, 80, 168, 5, 5, 5, 6, 0, 0, + 136, 112, 80, 112, 136, 5, 7, 7, 6, 0, 0, 136, 80, 248, 32, 248, + 32, 32, 1, 7, 7, 6, 2, 0, 128, 128, 128, 0, 128, 128, 128, 5, + 8, 8, 6, 0, 0, 48, 72, 32, 80, 80, 32, 144, 96, 5, 7, 7, + 6, 0, 0, 24, 32, 32, 112, 32, 32, 192, 5, 7, 7, 6, 0, 0, + 248, 136, 184, 184, 184, 136, 248, 5, 7, 7, 6, 0, 0, 112, 8, 120, + 136, 120, 0, 248, 5, 5, 5, 6, 0, 1, 40, 80, 160, 80, 40, 5, + 7, 7, 6, 0, 0, 144, 168, 168, 232, 168, 168, 144, 5, 7, 7, 6, + 0, 0, 120, 136, 136, 120, 40, 72, 136, 5, 7, 7, 6, 0, 0, 248, + 136, 168, 136, 152, 168, 248, 2, 3, 3, 6, 2, 4, 64, 128, 192, 4, + 5, 5, 6, 0, 3, 96, 144, 144, 144, 96, 5, 7, 7, 6, 0, 0, + 32, 32, 248, 32, 32, 0, 248, 4, 5, 5, 6, 0, 3, 96, 144, 32, + 64, 240, 3, 5, 5, 6, 0, 3, 224, 32, 224, 32, 224, 5, 8, 8, + 6, 0, 0, 224, 144, 224, 128, 144, 184, 144, 24, 5, 8, 8, 6, 0, + 255, 136, 136, 136, 136, 152, 232, 128, 128, 5, 7, 7, 6, 0, 0, 120, + 152, 152, 120, 24, 24, 24, 2, 2, 2, 6, 2, 2, 192, 192, 5, 5, + 5, 6, 0, 0, 80, 136, 168, 168, 80, 3, 5, 5, 6, 0, 3, 64, + 192, 64, 64, 224, 5, 7, 7, 6, 0, 0, 112, 136, 136, 136, 112, 0, + 248, 5, 5, 5, 6, 0, 1, 160, 80, 40, 80, 160, 5, 7, 7, 6, + 0, 0, 136, 144, 168, 88, 184, 8, 8, 5, 7, 7, 6, 0, 0, 136, + 144, 184, 72, 152, 32, 56, 5, 8, 8, 6, 0, 0, 192, 64, 192, 72, + 216, 56, 8, 8, 5, 7, 7, 6, 0, 0, 32, 0, 32, 64, 128, 136, + 112, 5, 8, 8, 6, 0, 0, 64, 32, 32, 80, 136, 248, 136, 136, 5, + 8, 8, 6, 0, 0, 16, 32, 32, 80, 136, 248, 136, 136, 5, 8, 8, + 6, 0, 0, 32, 80, 0, 112, 136, 248, 136, 136, 5, 8, 8, 6, 0, + 0, 104, 144, 0, 112, 136, 248, 136, 136, 5, 8, 8, 6, 0, 0, 80, + 0, 32, 80, 136, 248, 136, 136, 5, 8, 8, 6, 0, 0, 32, 80, 32, + 112, 136, 248, 136, 136, 5, 7, 7, 6, 0, 0, 56, 96, 160, 184, 224, + 160, 184, 5, 8, 8, 6, 0, 255, 112, 136, 128, 128, 136, 112, 32, 96, + 5, 8, 8, 6, 0, 0, 64, 32, 0, 248, 128, 240, 128, 248, 5, 8, + 8, 6, 0, 0, 8, 16, 0, 248, 128, 240, 128, 248, 5, 8, 8, 6, + 0, 0, 32, 80, 0, 248, 128, 240, 128, 248, 5, 7, 7, 6, 0, 0, + 80, 0, 248, 128, 240, 128, 248, 3, 8, 8, 6, 1, 0, 128, 64, 0, + 224, 64, 64, 64, 224, 3, 8, 8, 6, 1, 0, 32, 64, 0, 224, 64, + 64, 64, 224, 3, 8, 8, 6, 1, 0, 64, 160, 0, 224, 64, 64, 64, + 224, 3, 7, 7, 6, 1, 0, 160, 0, 224, 64, 64, 64, 224, 5, 7, + 7, 6, 0, 0, 112, 72, 72, 232, 72, 72, 112, 5, 8, 8, 6, 0, + 0, 104, 144, 0, 136, 200, 168, 152, 136, 5, 8, 8, 6, 0, 0, 64, + 32, 112, 136, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, 16, 32, 112, + 136, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, 32, 80, 0, 112, 136, + 136, 136, 112, 5, 8, 8, 6, 0, 0, 104, 144, 0, 112, 136, 136, 136, + 112, 5, 8, 8, 6, 0, 0, 80, 0, 112, 136, 136, 136, 136, 112, 5, + 5, 5, 6, 0, 1, 136, 80, 32, 80, 136, 5, 7, 7, 6, 0, 0, + 112, 32, 112, 168, 112, 32, 112, 5, 8, 8, 6, 0, 0, 64, 32, 136, + 136, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, 16, 32, 136, 136, 136, + 136, 136, 112, 5, 8, 8, 6, 0, 0, 32, 80, 0, 136, 136, 136, 136, + 112, 5, 8, 8, 6, 0, 0, 80, 0, 136, 136, 136, 136, 136, 112, 5, + 8, 8, 6, 0, 0, 16, 32, 136, 80, 32, 32, 32, 32, 5, 8, 8, + 6, 0, 0, 192, 64, 112, 72, 72, 112, 64, 224, 5, 7, 7, 6, 0, + 0, 48, 72, 72, 112, 72, 72, 176, 5, 8, 8, 6, 0, 0, 64, 32, + 0, 112, 8, 120, 136, 120, 5, 8, 8, 6, 0, 0, 16, 32, 0, 112, + 8, 120, 136, 120, 5, 8, 8, 6, 0, 0, 32, 80, 0, 112, 8, 120, + 136, 120, 5, 8, 8, 6, 0, 0, 104, 144, 0, 112, 8, 120, 136, 120, + 5, 7, 7, 6, 0, 0, 80, 0, 112, 8, 120, 136, 120, 5, 8, 8, + 6, 0, 0, 32, 80, 32, 112, 8, 120, 136, 120, 5, 6, 6, 6, 0, + 0, 208, 40, 120, 160, 168, 80, 5, 6, 6, 6, 0, 255, 112, 128, 136, + 112, 32, 96, 5, 8, 8, 6, 0, 0, 64, 32, 0, 112, 136, 248, 128, + 112, 5, 8, 8, 6, 0, 0, 16, 32, 0, 112, 136, 248, 128, 112, 5, + 8, 8, 6, 0, 0, 32, 80, 0, 112, 136, 248, 128, 112, 5, 7, 7, + 6, 0, 0, 80, 0, 112, 136, 248, 128, 112, 3, 8, 8, 6, 1, 0, + 128, 64, 0, 64, 192, 64, 64, 224, 3, 8, 8, 6, 1, 0, 32, 64, + 0, 64, 192, 64, 64, 224, 3, 8, 8, 6, 1, 0, 64, 160, 0, 64, + 192, 64, 64, 224, 3, 7, 7, 6, 1, 0, 160, 0, 64, 192, 64, 64, + 224, 5, 7, 7, 6, 0, 0, 160, 64, 160, 16, 120, 136, 112, 5, 8, + 8, 6, 0, 0, 104, 144, 0, 176, 200, 136, 136, 136, 5, 8, 8, 6, + 0, 0, 64, 32, 0, 112, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, + 16, 32, 0, 112, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, 32, 80, + 0, 112, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, 104, 144, 0, 112, + 136, 136, 136, 112, 5, 7, 7, 6, 0, 0, 80, 0, 112, 136, 136, 136, + 112, 5, 5, 5, 6, 0, 1, 32, 0, 248, 0, 32, 5, 7, 7, 6, + 0, 0, 16, 32, 112, 168, 112, 32, 64, 5, 8, 8, 6, 0, 0, 64, + 32, 0, 136, 136, 136, 152, 104, 5, 8, 8, 6, 0, 0, 16, 32, 0, + 136, 136, 136, 152, 104, 5, 8, 8, 6, 0, 0, 32, 80, 0, 136, 136, + 136, 152, 104, 5, 7, 7, 6, 0, 0, 80, 0, 136, 136, 136, 152, 104, + 5, 9, 9, 6, 0, 255, 16, 32, 0, 136, 136, 136, 248, 8, 112, 4, + 7, 7, 6, 1, 0, 192, 64, 96, 80, 96, 64, 224, 5, 8, 8, 6, + 0, 255, 80, 0, 136, 136, 136, 248, 8, 112 +}; diff --git a/trunk/Arduino/Marlin_1.1.6/dogm_font_data_ISO10646_1.h b/trunk/Arduino/Marlin_1.1.6/dogm_font_data_ISO10646_1.h new file mode 100644 index 00000000..8ff40d05 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/dogm_font_data_ISO10646_1.h @@ -0,0 +1,198 @@ +/** + * 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 . + * + */ + +/** + Fontname: ISO10646-1 + Copyright: A.Hardtung, public domain + Capital A Height: 7, '1' Height: 7 + Calculated Max Values w= 5 h= 9 x= 2 y= 7 dx= 6 dy= 0 ascent= 8 len= 9 + Font Bounding box w= 6 h= 9 x= 0 y=-2 + Calculated Min Values x= 0 y=-1 dx= 0 dy= 0 + Pure Font ascent = 7 descent=-1 + X Font ascent = 7 descent=-1 + Max Font ascent = 8 descent=-1 +*/ +#include +const u8g_fntpgm_uint8_t ISO10646_1_5x7[2592] U8G_SECTION(".progmem.ISO10646_1_5x7") = { + 0, 6, 9, 0, 254, 7, 1, 146, 3, 33, 32, 255, 255, 8, 255, 7, + 255, 0, 0, 0, 6, 0, 0, 1, 7, 7, 6, 2, 0, 128, 128, 128, + 128, 128, 0, 128, 3, 2, 2, 6, 1, 5, 160, 160, 5, 7, 7, 6, + 0, 0, 80, 80, 248, 80, 248, 80, 80, 5, 7, 7, 6, 0, 0, 32, + 120, 160, 112, 40, 240, 32, 5, 7, 7, 6, 0, 0, 192, 200, 16, 32, + 64, 152, 24, 5, 7, 7, 6, 0, 0, 96, 144, 160, 64, 168, 144, 104, + 2, 3, 3, 6, 1, 4, 192, 64, 128, 3, 7, 7, 6, 1, 0, 32, + 64, 128, 128, 128, 64, 32, 3, 7, 7, 6, 1, 0, 128, 64, 32, 32, + 32, 64, 128, 5, 5, 5, 6, 0, 1, 32, 168, 112, 168, 32, 5, 5, + 5, 6, 0, 1, 32, 32, 248, 32, 32, 2, 3, 3, 6, 2, 255, 192, + 64, 128, 5, 1, 1, 6, 0, 3, 248, 2, 2, 2, 6, 2, 0, 192, + 192, 5, 5, 5, 6, 0, 1, 8, 16, 32, 64, 128, 5, 7, 7, 6, + 0, 0, 112, 136, 136, 136, 136, 136, 112, 3, 7, 7, 6, 1, 0, 64, + 192, 64, 64, 64, 64, 224, 5, 7, 7, 6, 0, 0, 112, 136, 8, 112, + 128, 128, 248, 5, 7, 7, 6, 0, 0, 248, 16, 32, 16, 8, 8, 240, + 5, 7, 7, 6, 0, 0, 16, 48, 80, 144, 248, 16, 16, 5, 7, 7, + 6, 0, 0, 248, 128, 240, 8, 8, 136, 112, 5, 7, 7, 6, 0, 0, + 112, 128, 128, 240, 136, 136, 112, 5, 7, 7, 6, 0, 0, 248, 8, 16, + 32, 32, 32, 32, 5, 7, 7, 6, 0, 0, 112, 136, 136, 112, 136, 136, + 112, 5, 7, 7, 6, 0, 0, 112, 136, 136, 120, 8, 8, 112, 2, 5, + 5, 6, 2, 0, 192, 192, 0, 192, 192, 2, 6, 6, 6, 2, 255, 192, + 192, 0, 192, 64, 128, 4, 7, 7, 6, 0, 0, 16, 32, 64, 128, 64, + 32, 16, 5, 3, 3, 6, 0, 2, 248, 0, 248, 4, 7, 7, 6, 1, + 0, 128, 64, 32, 16, 32, 64, 128, 5, 7, 7, 6, 0, 0, 112, 136, + 8, 16, 32, 0, 32, 5, 7, 7, 6, 0, 0, 112, 136, 8, 104, 168, + 168, 112, 5, 7, 7, 6, 0, 0, 112, 136, 136, 248, 136, 136, 136, 5, + 7, 7, 6, 0, 0, 240, 136, 136, 240, 136, 136, 240, 5, 7, 7, 6, + 0, 0, 112, 136, 128, 128, 128, 136, 112, 5, 7, 7, 6, 0, 0, 240, + 136, 136, 136, 136, 136, 240, 5, 7, 7, 6, 0, 0, 248, 128, 128, 240, + 128, 128, 248, 5, 7, 7, 6, 0, 0, 248, 128, 128, 240, 128, 128, 128, + 5, 7, 7, 6, 0, 0, 112, 136, 128, 184, 136, 136, 112, 5, 7, 7, + 6, 0, 0, 136, 136, 136, 248, 136, 136, 136, 1, 7, 7, 6, 2, 0, + 128, 128, 128, 128, 128, 128, 128, 5, 7, 7, 6, 0, 0, 56, 16, 16, + 16, 16, 144, 96, 5, 7, 7, 6, 0, 0, 136, 144, 160, 192, 160, 144, + 136, 5, 7, 7, 6, 0, 0, 128, 128, 128, 128, 128, 128, 248, 5, 7, + 7, 6, 0, 0, 136, 216, 168, 136, 136, 136, 136, 5, 7, 7, 6, 0, + 0, 136, 136, 200, 168, 152, 136, 136, 5, 7, 7, 6, 0, 0, 112, 136, + 136, 136, 136, 136, 112, 5, 7, 7, 6, 0, 0, 240, 136, 136, 240, 128, + 128, 128, 5, 7, 7, 6, 0, 0, 112, 136, 136, 136, 168, 144, 104, 5, + 7, 7, 6, 0, 0, 240, 136, 136, 240, 160, 144, 136, 5, 7, 7, 6, + 0, 0, 120, 128, 128, 112, 8, 8, 240, 5, 7, 7, 6, 0, 0, 248, + 32, 32, 32, 32, 32, 32, 5, 7, 7, 6, 0, 0, 136, 136, 136, 136, + 136, 136, 112, 5, 7, 7, 6, 0, 0, 136, 136, 136, 136, 136, 80, 32, + 5, 7, 7, 6, 0, 0, 136, 136, 136, 136, 136, 168, 80, 5, 7, 7, + 6, 0, 0, 136, 136, 80, 32, 80, 136, 136, 5, 7, 7, 6, 0, 0, + 136, 136, 136, 80, 32, 32, 32, 5, 7, 7, 6, 0, 0, 248, 8, 16, + 32, 64, 128, 248, 3, 7, 7, 6, 1, 0, 224, 128, 128, 128, 128, 128, + 224, 5, 5, 5, 6, 0, 1, 128, 64, 32, 16, 8, 3, 7, 7, 6, + 1, 0, 224, 32, 32, 32, 32, 32, 224, 5, 3, 3, 6, 0, 4, 32, + 80, 136, 5, 1, 1, 6, 0, 0, 248, 2, 2, 2, 6, 2, 5, 128, + 64, 5, 5, 5, 6, 0, 0, 112, 8, 120, 136, 120, 5, 7, 7, 6, + 0, 0, 128, 128, 176, 200, 136, 136, 240, 5, 5, 5, 6, 0, 0, 112, + 128, 128, 136, 112, 5, 7, 7, 6, 0, 0, 8, 8, 104, 152, 136, 136, + 120, 5, 5, 5, 6, 0, 0, 112, 136, 248, 128, 112, 5, 7, 7, 6, + 0, 0, 48, 72, 224, 64, 64, 64, 64, 5, 6, 6, 6, 0, 255, 112, + 136, 136, 120, 8, 112, 5, 7, 7, 6, 0, 0, 128, 128, 176, 200, 136, + 136, 136, 1, 7, 7, 6, 2, 0, 128, 0, 128, 128, 128, 128, 128, 3, + 8, 8, 6, 1, 255, 32, 0, 32, 32, 32, 32, 160, 64, 4, 7, 7, + 6, 0, 0, 128, 128, 144, 160, 192, 160, 144, 3, 7, 7, 6, 1, 0, + 192, 64, 64, 64, 64, 64, 224, 5, 5, 5, 6, 0, 0, 208, 168, 168, + 168, 168, 5, 5, 5, 6, 0, 0, 176, 200, 136, 136, 136, 5, 5, 5, + 6, 0, 0, 112, 136, 136, 136, 112, 5, 6, 6, 6, 0, 255, 240, 136, + 136, 240, 128, 128, 5, 6, 6, 6, 0, 255, 120, 136, 136, 120, 8, 8, + 5, 5, 5, 6, 0, 0, 176, 200, 128, 128, 128, 5, 5, 5, 6, 0, + 0, 112, 128, 112, 8, 240, 4, 7, 7, 6, 0, 0, 64, 64, 224, 64, + 64, 64, 48, 5, 5, 5, 6, 0, 0, 136, 136, 136, 152, 104, 5, 5, + 5, 6, 0, 0, 136, 136, 136, 80, 32, 5, 5, 5, 6, 0, 0, 136, + 136, 168, 168, 80, 5, 5, 5, 6, 0, 0, 136, 80, 32, 80, 136, 5, + 6, 6, 6, 0, 255, 136, 136, 136, 120, 8, 112, 5, 5, 5, 6, 0, + 0, 248, 16, 32, 64, 248, 3, 7, 7, 6, 1, 0, 32, 64, 64, 128, + 64, 64, 32, 1, 7, 7, 6, 2, 0, 128, 128, 128, 128, 128, 128, 128, + 3, 7, 7, 6, 1, 0, 128, 64, 64, 32, 64, 64, 128, 5, 2, 2, + 6, 0, 2, 104, 144, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, + 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, + 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, + 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, + 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, + 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, + 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, + 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, + 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, + 0, 1, 7, 7, 6, 2, 0, 128, 0, 128, 128, 128, 128, 128, 5, 7, + 7, 6, 0, 0, 32, 112, 168, 160, 168, 112, 32, 5, 7, 7, 6, 0, + 0, 48, 64, 64, 224, 64, 80, 168, 5, 5, 5, 6, 0, 0, 136, 112, + 80, 112, 136, 5, 7, 7, 6, 0, 0, 136, 80, 32, 248, 32, 248, 32, + 1, 7, 7, 6, 2, 0, 128, 128, 128, 0, 128, 128, 128, 5, 8, 8, + 6, 0, 0, 48, 72, 32, 80, 80, 32, 144, 96, 3, 1, 1, 6, 1, + 7, 160, 5, 7, 7, 6, 0, 0, 248, 136, 184, 184, 184, 136, 248, 5, + 7, 7, 6, 0, 1, 112, 8, 120, 136, 120, 0, 248, 5, 5, 5, 6, + 0, 1, 40, 80, 160, 80, 40, 5, 3, 3, 6, 0, 1, 248, 8, 8, + 2, 2, 2, 6, 2, 6, 64, 128, 5, 7, 7, 6, 0, 0, 248, 136, + 168, 136, 152, 168, 248, 5, 1, 1, 6, 0, 6, 248, 4, 4, 4, 6, + 0, 3, 96, 144, 144, 96, 5, 7, 7, 6, 0, 0, 32, 32, 248, 32, + 32, 0, 248, 4, 5, 5, 6, 0, 3, 96, 144, 32, 64, 240, 3, 5, + 5, 6, 0, 3, 224, 32, 224, 32, 224, 2, 2, 2, 6, 2, 6, 64, + 128, 5, 8, 8, 6, 0, 255, 136, 136, 136, 136, 152, 232, 128, 128, 5, + 7, 7, 6, 0, 0, 120, 152, 152, 120, 24, 24, 24, 2, 2, 2, 6, + 2, 2, 192, 192, 2, 2, 2, 6, 2, 255, 64, 128, 3, 5, 5, 6, + 0, 3, 64, 192, 64, 64, 224, 5, 7, 7, 6, 0, 1, 112, 136, 136, + 136, 112, 0, 248, 5, 5, 5, 6, 0, 1, 160, 80, 40, 80, 160, 5, + 7, 7, 6, 0, 0, 136, 144, 168, 88, 184, 8, 8, 5, 7, 7, 6, + 0, 0, 136, 144, 184, 72, 152, 32, 56, 5, 8, 8, 6, 0, 0, 192, + 64, 192, 72, 216, 56, 8, 8, 5, 7, 7, 6, 0, 0, 32, 0, 32, + 64, 128, 136, 112, 5, 8, 8, 6, 0, 0, 64, 32, 0, 112, 136, 248, + 136, 136, 5, 8, 8, 6, 0, 0, 16, 32, 0, 112, 136, 248, 136, 136, + 5, 8, 8, 6, 0, 0, 32, 80, 0, 112, 136, 248, 136, 136, 5, 8, + 8, 6, 0, 0, 104, 144, 0, 112, 136, 248, 136, 136, 5, 8, 8, 6, + 0, 0, 80, 0, 112, 136, 136, 248, 136, 136, 5, 8, 8, 6, 0, 0, + 32, 80, 32, 112, 136, 248, 136, 136, 5, 7, 7, 6, 0, 0, 56, 96, + 160, 184, 224, 160, 184, 5, 8, 8, 6, 0, 255, 112, 136, 128, 128, 136, + 112, 32, 96, 5, 8, 8, 6, 0, 0, 64, 32, 0, 248, 128, 240, 128, + 248, 5, 8, 8, 6, 0, 0, 8, 16, 0, 248, 128, 240, 128, 248, 5, + 8, 8, 6, 0, 0, 32, 80, 0, 248, 128, 240, 128, 248, 5, 7, 7, + 6, 0, 0, 80, 0, 248, 128, 240, 128, 248, 3, 8, 8, 6, 1, 0, + 128, 64, 0, 224, 64, 64, 64, 224, 3, 8, 8, 6, 1, 0, 32, 64, + 0, 224, 64, 64, 64, 224, 3, 8, 8, 6, 1, 0, 64, 160, 0, 224, + 64, 64, 64, 224, 3, 7, 7, 6, 1, 0, 160, 0, 224, 64, 64, 64, + 224, 5, 7, 7, 6, 0, 0, 112, 72, 72, 232, 72, 72, 112, 5, 8, + 8, 6, 0, 0, 104, 144, 0, 136, 200, 168, 152, 136, 5, 8, 8, 6, + 0, 0, 64, 32, 112, 136, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, + 16, 32, 112, 136, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, 32, 80, + 0, 112, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, 104, 144, 0, 112, + 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, 80, 0, 112, 136, 136, 136, + 136, 112, 5, 5, 5, 6, 0, 1, 136, 80, 32, 80, 136, 5, 8, 8, + 6, 0, 255, 16, 112, 168, 168, 168, 168, 112, 64, 5, 8, 8, 6, 0, + 0, 64, 32, 136, 136, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, 16, + 32, 136, 136, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, 32, 80, 0, + 136, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, 80, 0, 136, 136, 136, + 136, 136, 112, 5, 8, 8, 6, 0, 0, 16, 32, 136, 80, 32, 32, 32, + 32, 5, 9, 9, 6, 0, 255, 192, 64, 112, 72, 72, 112, 64, 64, 224, + 4, 8, 8, 6, 1, 255, 96, 144, 144, 160, 144, 144, 224, 128, 5, 8, + 8, 6, 0, 0, 64, 32, 0, 112, 8, 120, 136, 120, 5, 8, 8, 6, + 0, 0, 16, 32, 0, 112, 8, 120, 136, 120, 5, 8, 8, 6, 0, 0, + 32, 80, 0, 112, 8, 120, 136, 120, 5, 8, 8, 6, 0, 0, 104, 144, + 0, 112, 8, 120, 136, 120, 5, 7, 7, 6, 0, 0, 80, 0, 112, 8, + 120, 136, 120, 5, 8, 8, 6, 0, 0, 32, 80, 32, 112, 8, 120, 136, + 120, 5, 6, 6, 6, 0, 0, 208, 40, 120, 160, 168, 80, 5, 6, 6, + 6, 0, 255, 112, 128, 136, 112, 32, 96, 5, 8, 8, 6, 0, 0, 64, + 32, 0, 112, 136, 248, 128, 112, 5, 8, 8, 6, 0, 0, 16, 32, 0, + 112, 136, 248, 128, 112, 5, 8, 8, 6, 0, 0, 32, 80, 0, 112, 136, + 248, 128, 112, 5, 7, 7, 6, 0, 0, 80, 0, 112, 136, 248, 128, 112, + 3, 8, 8, 6, 1, 0, 128, 64, 0, 64, 192, 64, 64, 224, 3, 8, + 8, 6, 1, 0, 32, 64, 0, 64, 192, 64, 64, 224, 3, 8, 8, 6, + 1, 0, 64, 160, 0, 64, 192, 64, 64, 224, 3, 7, 7, 6, 1, 0, + 160, 0, 64, 192, 64, 64, 224, 5, 7, 7, 6, 0, 0, 160, 64, 160, + 16, 120, 136, 112, 5, 8, 8, 6, 0, 0, 104, 144, 0, 176, 200, 136, + 136, 136, 5, 8, 8, 6, 0, 0, 64, 32, 0, 112, 136, 136, 136, 112, + 5, 8, 8, 6, 0, 0, 16, 32, 0, 112, 136, 136, 136, 112, 5, 8, + 8, 6, 0, 0, 32, 80, 0, 112, 136, 136, 136, 112, 5, 8, 8, 6, + 0, 0, 104, 144, 0, 112, 136, 136, 136, 112, 5, 7, 7, 6, 0, 0, + 80, 0, 112, 136, 136, 136, 112, 5, 5, 5, 6, 0, 1, 32, 0, 248, + 0, 32, 5, 7, 7, 6, 0, 255, 16, 112, 168, 168, 168, 112, 64, 5, + 8, 8, 6, 0, 0, 64, 32, 0, 136, 136, 136, 152, 104, 5, 8, 8, + 6, 0, 0, 16, 32, 0, 136, 136, 136, 152, 104, 5, 8, 8, 6, 0, + 0, 32, 80, 0, 136, 136, 136, 152, 104, 5, 7, 7, 6, 0, 0, 80, + 0, 136, 136, 136, 152, 104, 5, 9, 9, 6, 0, 255, 16, 32, 0, 136, + 136, 136, 248, 8, 112, 4, 7, 7, 6, 1, 255, 192, 64, 96, 80, 96, + 64, 224, 5, 8, 8, 6, 0, 255, 80, 0, 136, 136, 136, 120, 8, 112 +}; diff --git a/trunk/Arduino/Marlin_1.1.6/dogm_font_data_ISO10646_1_PL.h b/trunk/Arduino/Marlin_1.1.6/dogm_font_data_ISO10646_1_PL.h new file mode 100644 index 00000000..47b0bbb0 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/dogm_font_data_ISO10646_1_PL.h @@ -0,0 +1,184 @@ +/* + Fontname: ISO10646-1-PL + Copyright: A.Hardtung, public domain + Capital A Height: 7, '1' Height: 7 + Calculated Max Values w= 5 h= 9 x= 2 y= 7 dx= 6 dy= 0 ascent= 8 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 = 7 descent=-1 + X Font ascent = 7 descent=-1 + Max Font ascent = 8 descent=-2 +*/ +#include +const u8g_fntpgm_uint8_t ISO10646_1_PL_5x7[2732] U8G_FONT_SECTION(".progmem.ISO10646_1_PL_5x7") = { + 0,6,9,0,254,7,1,146,3,33,32,255,255,8,254,7, + 255,0,0,0,6,0,0,1,7,7,6,2,0,128,128,128, + 128,128,0,128,3,2,2,6,1,5,160,160,5,7,7,6, + 0,0,80,80,248,80,248,80,80,5,7,7,6,0,0,32, + 120,160,112,40,240,32,5,7,7,6,0,0,192,200,16,32, + 64,152,24,5,7,7,6,0,0,96,144,160,64,168,144,104, + 2,3,3,6,1,4,192,64,128,3,7,7,6,1,0,32, + 64,128,128,128,64,32,3,7,7,6,1,0,128,64,32,32, + 32,64,128,5,5,5,6,0,1,32,168,112,168,32,5,5, + 5,6,0,1,32,32,248,32,32,2,3,3,6,2,255,192, + 64,128,5,1,1,6,0,3,248,2,2,2,6,2,0,192, + 192,5,5,5,6,0,1,8,16,32,64,128,5,7,7,6, + 0,0,112,136,136,136,136,136,112,3,7,7,6,1,0,64, + 192,64,64,64,64,224,5,7,7,6,0,0,112,136,8,112, + 128,128,248,5,7,7,6,0,0,248,16,32,16,8,8,240, + 5,7,7,6,0,0,16,48,80,144,248,16,16,5,7,7, + 6,0,0,248,128,240,8,8,136,112,5,7,7,6,0,0, + 112,128,128,240,136,136,112,5,7,7,6,0,0,248,8,16, + 32,32,32,32,5,7,7,6,0,0,112,136,136,112,136,136, + 112,5,7,7,6,0,0,112,136,136,120,8,8,112,2,5, + 5,6,2,0,192,192,0,192,192,2,6,6,6,2,255,192, + 192,0,192,64,128,4,7,7,6,0,0,16,32,64,128,64, + 32,16,5,3,3,6,0,2,248,0,248,4,7,7,6,1, + 0,128,64,32,16,32,64,128,5,7,7,6,0,0,112,136, + 8,16,32,0,32,5,7,7,6,0,0,112,136,8,104,168, + 168,112,5,7,7,6,0,0,112,136,136,248,136,136,136,5, + 7,7,6,0,0,240,136,136,240,136,136,240,5,7,7,6, + 0,0,112,136,128,128,128,136,112,5,7,7,6,0,0,240, + 136,136,136,136,136,240,5,7,7,6,0,0,248,128,128,240, + 128,128,248,5,7,7,6,0,0,248,128,128,240,128,128,128, + 5,7,7,6,0,0,112,136,128,184,136,136,112,5,7,7, + 6,0,0,136,136,136,248,136,136,136,1,7,7,6,2,0, + 128,128,128,128,128,128,128,5,7,7,6,0,0,56,16,16, + 16,16,144,96,5,7,7,6,0,0,136,144,160,192,160,144, + 136,5,7,7,6,0,0,128,128,128,128,128,128,248,5,7, + 7,6,0,0,136,216,168,136,136,136,136,5,7,7,6,0, + 0,136,136,200,168,152,136,136,5,7,7,6,0,0,112,136, + 136,136,136,136,112,5,7,7,6,0,0,240,136,136,240,128, + 128,128,5,7,7,6,0,0,112,136,136,136,168,144,104,5, + 7,7,6,0,0,240,136,136,240,160,144,136,5,7,7,6, + 0,0,120,128,128,112,8,8,240,5,7,7,6,0,0,248, + 32,32,32,32,32,32,5,7,7,6,0,0,136,136,136,136, + 136,136,112,5,7,7,6,0,0,136,136,136,136,136,80,32, + 5,7,7,6,0,0,136,136,136,136,136,168,80,5,7,7, + 6,0,0,136,136,80,32,80,136,136,5,7,7,6,0,0, + 136,136,136,80,32,32,32,5,7,7,6,0,0,248,8,16, + 32,64,128,248,3,7,7,6,1,0,224,128,128,128,128,128, + 224,5,5,5,6,0,1,128,64,32,16,8,3,7,7,6, + 1,0,224,32,32,32,32,32,224,5,3,3,6,0,4,32, + 80,136,5,1,1,6,0,0,248,2,2,2,6,2,5,128, + 64,5,5,5,6,0,0,112,8,120,136,120,5,7,7,6, + 0,0,128,128,176,200,136,136,240,5,5,5,6,0,0,112, + 128,128,136,112,5,7,7,6,0,0,8,8,104,152,136,136, + 120,5,5,5,6,0,0,112,136,248,128,112,5,7,7,6, + 0,0,48,72,224,64,64,64,64,5,6,6,6,0,255,112, + 136,136,120,8,112,5,7,7,6,0,0,128,128,176,200,136, + 136,136,1,7,7,6,2,0,128,0,128,128,128,128,128,3, + 8,8,6,1,255,32,0,32,32,32,32,160,64,4,7,7, + 6,0,0,128,128,144,160,192,160,144,3,7,7,6,1,0, + 192,64,64,64,64,64,224,5,5,5,6,0,0,208,168,168, + 168,168,5,5,5,6,0,0,176,200,136,136,136,5,5,5, + 6,0,0,112,136,136,136,112,5,6,6,6,0,255,240,136, + 136,240,128,128,5,6,6,6,0,255,120,136,136,120,8,8, + 5,5,5,6,0,0,176,200,128,128,128,5,5,5,6,0, + 0,112,128,112,8,240,4,7,7,6,0,0,64,64,224,64, + 64,64,48,5,5,5,6,0,0,136,136,136,152,104,5,5, + 5,6,0,0,136,136,136,80,32,5,5,5,6,0,0,136, + 136,168,168,80,5,5,5,6,0,0,136,80,32,80,136,5, + 6,6,6,0,255,136,136,136,120,8,112,5,5,5,6,0, + 0,248,16,32,64,248,3,7,7,6,1,0,32,64,64,128, + 64,64,32,1,7,7,6,2,0,128,128,128,128,128,128,128, + 3,7,7,6,1,0,128,64,64,32,64,64,128,5,2,2, + 6,0,2,104,144,0,0,0,6,0,0,5,9,9,6,0, + 254,112,136,136,248,136,136,136,16,32,5,7,7,6,0,254, + 112,8,120,136,120,16,32,5,8,8,6,0,0,16,32,112, + 136,128,128,136,112,5,7,7,6,0,0,16,32,112,128,128, + 136,112,5,9,9,6,0,254,248,128,128,240,128,128,248,8, + 16,5,7,7,6,0,254,112,136,248,128,112,16,32,5,7, + 7,6,0,0,128,144,160,192,128,128,248,5,7,7,6,0, + 0,96,40,48,96,160,32,112,5,8,8,6,0,0,16,168, + 136,200,168,152,136,136,5,8,8,6,0,0,8,16,0,176, + 200,136,136,136,5,8,8,6,0,0,16,32,112,136,136,136, + 136,112,5,8,8,6,0,0,16,32,0,112,136,136,136,112, + 5,8,8,6,0,0,16,120,128,128,112,8,8,240,5,8, + 8,6,0,0,16,32,0,112,128,112,8,240,5,8,8,6, + 0,0,32,248,8,16,32,64,128,248,5,8,8,6,0,0, + 16,32,0,248,16,32,64,248,5,7,7,6,0,0,248,8, + 16,248,64,128,248,5,8,8,6,0,0,48,48,0,248,16, + 32,64,248,0,0,0,6,0,0,0,0,0,6,0,0,0, + 0,0,6,0,0,0,0,0,6,0,0,0,0,0,6,0, + 0,0,0,0,6,0,0,0,0,0,6,0,0,0,0,0, + 6,0,0,0,0,0,6,0,0,0,0,0,6,0,0,0, + 0,0,6,0,0,0,0,0,6,0,0,0,0,0,6,0, + 0,0,0,0,6,0,0,0,0,0,6,0,0,1,7,7, + 6,2,0,128,0,128,128,128,128,128,5,7,7,6,0,0, + 32,112,168,160,168,112,32,5,7,7,6,0,0,48,64,64, + 224,64,80,168,5,5,5,6,0,0,136,112,80,112,136,5, + 7,7,6,0,0,136,80,32,248,32,248,32,1,7,7,6, + 2,0,128,128,128,0,128,128,128,5,8,8,6,0,0,48, + 72,32,80,80,32,144,96,3,1,1,6,1,7,160,5,7, + 7,6,0,0,248,136,184,184,184,136,248,5,7,7,6,0, + 1,112,8,120,136,120,0,248,5,5,5,6,0,1,40,80, + 160,80,40,5,3,3,6,0,1,248,8,8,2,2,2,6, + 2,6,64,128,5,7,7,6,0,0,248,136,168,136,152,168, + 248,5,1,1,6,0,6,248,4,4,4,6,0,3,96,144, + 144,96,5,7,7,6,0,0,32,32,248,32,32,0,248,4, + 5,5,6,0,3,96,144,32,64,240,3,5,5,6,0,3, + 224,32,224,32,224,2,2,2,6,2,6,64,128,5,8,8, + 6,0,255,136,136,136,136,152,232,128,128,5,7,7,6,0, + 0,120,152,152,120,24,24,24,2,2,2,6,2,2,192,192, + 2,2,2,6,2,255,64,128,3,5,5,6,0,3,64,192, + 64,64,224,5,7,7,6,0,1,112,136,136,136,112,0,248, + 5,5,5,6,0,1,160,80,40,80,160,5,7,7,6,0, + 0,136,144,168,88,184,8,8,5,7,7,6,0,0,136,144, + 184,72,152,32,56,5,8,8,6,0,0,192,64,192,72,216, + 56,8,8,5,7,7,6,0,0,32,0,32,64,128,136,112, + 5,8,8,6,0,0,64,32,0,112,136,248,136,136,5,8, + 8,6,0,0,16,32,0,112,136,248,136,136,5,8,8,6, + 0,0,32,80,0,112,136,248,136,136,5,8,8,6,0,0, + 104,144,0,112,136,248,136,136,5,8,8,6,0,0,80,0, + 112,136,136,248,136,136,5,8,8,6,0,0,32,80,32,112, + 136,248,136,136,5,7,7,6,0,0,56,96,160,184,224,160, + 184,5,8,8,6,0,255,112,136,128,128,136,112,32,96,5, + 8,8,6,0,0,64,32,0,248,128,240,128,248,5,8,8, + 6,0,0,8,16,0,248,128,240,128,248,5,8,8,6,0, + 0,32,80,0,248,128,240,128,248,5,7,7,6,0,0,80, + 0,248,128,240,128,248,3,8,8,6,1,0,128,64,0,224, + 64,64,64,224,3,8,8,6,1,0,32,64,0,224,64,64, + 64,224,3,8,8,6,1,0,64,160,0,224,64,64,64,224, + 3,7,7,6,1,0,160,0,224,64,64,64,224,5,7,7, + 6,0,0,112,72,72,232,72,72,112,5,8,8,6,0,0, + 104,144,0,136,200,168,152,136,5,8,8,6,0,0,64,32, + 112,136,136,136,136,112,5,8,8,6,0,0,16,32,112,136, + 136,136,136,112,5,8,8,6,0,0,32,80,0,112,136,136, + 136,112,5,8,8,6,0,0,104,144,0,112,136,136,136,112, + 5,8,8,6,0,0,80,0,112,136,136,136,136,112,5,5, + 5,6,0,1,136,80,32,80,136,5,8,8,6,0,255,16, + 112,168,168,168,168,112,64,5,8,8,6,0,0,64,32,136, + 136,136,136,136,112,5,8,8,6,0,0,16,32,136,136,136, + 136,136,112,5,8,8,6,0,0,32,80,0,136,136,136,136, + 112,5,8,8,6,0,0,80,0,136,136,136,136,136,112,5, + 8,8,6,0,0,16,32,136,80,32,32,32,32,5,9,9, + 6,0,255,192,64,112,72,72,112,64,64,224,4,8,8,6, + 1,255,96,144,144,160,144,144,224,128,5,8,8,6,0,0, + 64,32,0,112,8,120,136,120,5,8,8,6,0,0,16,32, + 0,112,8,120,136,120,5,8,8,6,0,0,32,80,0,112, + 8,120,136,120,5,8,8,6,0,0,104,144,0,112,8,120, + 136,120,5,7,7,6,0,0,80,0,112,8,120,136,120,5, + 8,8,6,0,0,32,80,32,112,8,120,136,120,5,6,6, + 6,0,0,208,40,120,160,168,80,5,6,6,6,0,255,112, + 128,136,112,32,96,5,8,8,6,0,0,64,32,0,112,136, + 248,128,112,5,8,8,6,0,0,16,32,0,112,136,248,128, + 112,5,8,8,6,0,0,32,80,0,112,136,248,128,112,5, + 7,7,6,0,0,80,0,112,136,248,128,112,3,8,8,6, + 1,0,128,64,0,64,192,64,64,224,3,8,8,6,1,0, + 32,64,0,64,192,64,64,224,3,8,8,6,1,0,64,160, + 0,64,192,64,64,224,3,7,7,6,1,0,160,0,64,192, + 64,64,224,5,7,7,6,0,0,160,64,160,16,120,136,112, + 5,8,8,6,0,0,104,144,0,176,200,136,136,136,5,8, + 8,6,0,0,64,32,0,112,136,136,136,112,5,8,8,6, + 0,0,16,32,0,112,136,136,136,112,5,8,8,6,0,0, + 32,80,0,112,136,136,136,112,5,8,8,6,0,0,104,144, + 0,112,136,136,136,112,5,7,7,6,0,0,80,0,112,136, + 136,136,112,5,5,5,6,0,1,32,0,248,0,32,5,7, + 7,6,0,255,16,112,168,168,168,112,64,5,8,8,6,0, + 0,64,32,0,136,136,136,152,104,5,8,8,6,0,0,16, + 32,0,136,136,136,152,104,5,8,8,6,0,0,32,80,0, + 136,136,136,152,104,5,7,7,6,0,0,80,0,136,136,136, + 152,104,5,9,9,6,0,255,16,32,0,136,136,136,248,8, + 112,4,7,7,6,1,255,192,64,96,80,96,64,224,5,8, + 8,6,0,255,80,0,136,136,136,120,8,112}; diff --git a/trunk/Arduino/Marlin_1.1.6/dogm_font_data_ISO10646_1_tr.h b/trunk/Arduino/Marlin_1.1.6/dogm_font_data_ISO10646_1_tr.h new file mode 100644 index 00000000..e32f59f9 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/dogm_font_data_ISO10646_1_tr.h @@ -0,0 +1,197 @@ +/** + * 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 . + * + */ + +/* + Fontname: ISO10646-1-tr + Copyright: public domain + Capital A Height: 7, '1' Height: 7 + Calculated Max Values w= 5 h= 9 x= 2 y= 7 dx= 6 dy= 0 ascent= 8 len= 9 + Font Bounding box w= 6 h= 9 x= 0 y=-2 + Calculated Min Values x= 0 y=-1 dx= 0 dy= 0 + Pure Font ascent = 7 descent=-1 + X Font ascent = 7 descent=-1 + Max Font ascent = 8 descent=-1 +*/ +#include +const u8g_fntpgm_uint8_t ISO10646_TR[2591] U8G_SECTION(".progmem.ISO10646_TR") = { + 0,6,9,0,254,7,1,146,3,33,32,255,255,8,255,7, + 255,0,0,0,6,0,0,1,7,7,6,2,0,128,128,128, + 128,128,0,128,3,2,2,6,1,5,160,160,5,7,7,6, + 0,0,80,80,248,80,248,80,80,5,7,7,6,0,0,32, + 120,160,112,40,240,32,5,7,7,6,0,0,192,200,16,32, + 64,152,24,5,7,7,6,0,0,96,144,160,64,168,144,104, + 2,3,3,6,1,4,192,64,128,3,7,7,6,1,0,32, + 64,128,128,128,64,32,3,7,7,6,1,0,128,64,32,32, + 32,64,128,5,5,5,6,0,1,32,168,112,168,32,5,5, + 5,6,0,1,32,32,248,32,32,2,3,3,6,2,255,192, + 64,128,5,1,1,6,0,3,248,2,2,2,6,2,0,192, + 192,5,5,5,6,0,1,8,16,32,64,128,5,7,7,6, + 0,0,112,136,136,136,136,136,112,3,7,7,6,1,0,64, + 192,64,64,64,64,224,5,7,7,6,0,0,112,136,8,112, + 128,128,248,5,7,7,6,0,0,248,16,32,16,8,8,240, + 5,7,7,6,0,0,16,48,80,144,248,16,16,5,7,7, + 6,0,0,248,128,240,8,8,136,112,5,7,7,6,0,0, + 112,128,128,240,136,136,112,5,7,7,6,0,0,248,8,16, + 32,32,32,32,5,7,7,6,0,0,112,136,136,112,136,136, + 112,5,7,7,6,0,0,112,136,136,120,8,8,112,2,5, + 5,6,2,0,192,192,0,192,192,2,6,6,6,2,255,192, + 192,0,192,64,128,4,7,7,6,0,0,16,32,64,128,64, + 32,16,5,3,3,6,0,2,248,0,248,4,7,7,6,1, + 0,128,64,32,16,32,64,128,5,7,7,6,0,0,112,136, + 8,16,32,0,32,5,7,7,6,0,0,112,136,8,104,168, + 168,112,5,7,7,6,0,0,112,136,136,248,136,136,136,5, + 7,7,6,0,0,240,136,136,240,136,136,240,5,7,7,6, + 0,0,112,136,128,128,128,136,112,5,7,7,6,0,0,240, + 136,136,136,136,136,240,5,7,7,6,0,0,248,128,128,240, + 128,128,248,5,7,7,6,0,0,248,128,128,240,128,128,128, + 5,7,7,6,0,0,112,136,128,184,136,136,112,5,7,7, + 6,0,0,136,136,136,248,136,136,136,1,7,7,6,2,0, + 128,128,128,128,128,128,128,5,7,7,6,0,0,56,16,16, + 16,16,144,96,5,7,7,6,0,0,136,144,160,192,160,144, + 136,5,7,7,6,0,0,128,128,128,128,128,128,248,5,7, + 7,6,0,0,136,216,168,136,136,136,136,5,7,7,6,0, + 0,136,136,200,168,152,136,136,5,7,7,6,0,0,112,136, + 136,136,136,136,112,5,7,7,6,0,0,240,136,136,240,128, + 128,128,5,7,7,6,0,0,112,136,136,136,168,144,104,5, + 7,7,6,0,0,240,136,136,240,160,144,136,5,7,7,6, + 0,0,120,128,128,112,8,8,240,5,7,7,6,0,0,248, + 32,32,32,32,32,32,5,7,7,6,0,0,136,136,136,136, + 136,136,112,5,7,7,6,0,0,136,136,136,136,136,80,32, + 5,7,7,6,0,0,136,136,136,136,136,168,80,5,7,7, + 6,0,0,136,136,80,32,80,136,136,5,7,7,6,0,0, + 136,136,136,80,32,32,32,5,7,7,6,0,0,248,8,16, + 32,64,128,248,3,7,7,6,1,0,224,128,128,128,128,128, + 224,5,5,5,6,0,1,128,64,32,16,8,3,7,7,6, + 1,0,224,32,32,32,32,32,224,5,3,3,6,0,4,32, + 80,136,5,1,1,6,0,0,248,2,2,2,6,2,5,128, + 64,5,5,5,6,0,0,112,8,120,136,120,5,7,7,6, + 0,0,128,128,176,200,136,136,240,5,5,5,6,0,0,112, + 128,128,136,112,5,7,7,6,0,0,8,8,104,152,136,136, + 120,5,5,5,6,0,0,112,136,248,128,112,5,7,7,6, + 0,0,48,72,224,64,64,64,64,5,6,6,6,0,255,112, + 136,136,120,8,112,5,7,7,6,0,0,128,128,176,200,136, + 136,136,1,7,7,6,2,0,128,0,128,128,128,128,128,3, + 8,8,6,1,255,32,0,32,32,32,32,160,64,4,7,7, + 6,0,0,128,128,144,160,192,160,144,3,7,7,6,1,0, + 192,64,64,64,64,64,224,5,5,5,6,0,0,208,168,168, + 168,168,5,5,5,6,0,0,176,200,136,136,136,5,5,5, + 6,0,0,112,136,136,136,112,5,6,6,6,0,255,240,136, + 136,240,128,128,5,6,6,6,0,255,120,136,136,120,8,8, + 5,5,5,6,0,0,176,200,128,128,128,5,5,5,6,0, + 0,112,128,112,8,240,4,7,7,6,0,0,64,64,224,64, + 64,64,48,5,5,5,6,0,0,136,136,136,152,104,5,5, + 5,6,0,0,136,136,136,80,32,5,5,5,6,0,0,136, + 136,168,168,80,5,5,5,6,0,0,136,80,32,80,136,5, + 6,6,6,0,255,136,136,136,120,8,112,5,5,5,6,0, + 0,248,16,32,64,248,3,7,7,6,1,0,32,64,64,128, + 64,64,32,1,7,7,6,2,0,128,128,128,128,128,128,128, + 3,7,7,6,1,0,128,64,64,32,64,64,128,5,2,2, + 6,0,2,104,144,0,0,0,6,0,0,0,0,0,6,0, + 0,0,0,0,6,0,0,0,0,0,6,0,0,0,0,0, + 6,0,0,0,0,0,6,0,0,0,0,0,6,0,0,0, + 0,0,6,0,0,0,0,0,6,0,0,0,0,0,6,0, + 0,0,0,0,6,0,0,0,0,0,6,0,0,0,0,0, + 6,0,0,0,0,0,6,0,0,0,0,0,6,0,0,0, + 0,0,6,0,0,0,0,0,6,0,0,0,0,0,6,0, + 0,0,0,0,6,0,0,0,0,0,6,0,0,0,0,0, + 6,0,0,0,0,0,6,0,0,0,0,0,6,0,0,0, + 0,0,6,0,0,0,0,0,6,0,0,0,0,0,6,0, + 0,0,0,0,6,0,0,0,0,0,6,0,0,0,0,0, + 6,0,0,0,0,0,6,0,0,0,0,0,6,0,0,0, + 0,0,6,0,0,0,0,0,6,0,0,0,0,0,6,0, + 0,1,7,7,6,2,0,128,0,128,128,128,128,128,5,7, + 7,6,0,0,32,112,168,160,168,112,32,5,7,7,6,0, + 0,48,64,64,224,64,80,168,5,5,5,6,0,0,136,112, + 80,112,136,5,7,7,6,0,0,136,80,32,248,32,248,32, + 1,7,7,6,2,0,128,128,128,0,128,128,128,5,8,8, + 6,0,0,48,72,32,80,80,32,144,96,3,1,1,6,1, + 7,160,5,7,7,6,0,0,248,136,184,184,184,136,248,5, + 7,7,6,0,1,112,8,120,136,120,0,248,5,5,5,6, + 0,1,40,80,160,80,40,5,3,3,6,0,1,248,8,8, + 2,2,2,6,2,6,64,128,5,7,7,6,0,0,248,136, + 168,136,152,168,248,5,1,1,6,0,6,248,4,4,4,6, + 0,3,96,144,144,96,5,7,7,6,0,0,32,32,248,32, + 32,0,248,4,5,5,6,0,3,96,144,32,64,240,3,5, + 5,6,0,3,224,32,224,32,224,2,2,2,6,2,6,64, + 128,5,8,8,6,0,255,136,136,136,136,152,232,128,128,5, + 7,7,6,0,0,120,152,152,120,24,24,24,2,2,2,6, + 2,2,192,192,2,2,2,6,2,255,64,128,3,5,5,6, + 0,3,64,192,64,64,224,5,7,7,6,0,1,112,136,136, + 136,112,0,248,5,5,5,6,0,1,160,80,40,80,160,5, + 7,7,6,0,0,136,144,168,88,184,8,8,5,7,7,6, + 0,0,136,144,184,72,152,32,56,5,8,8,6,0,0,192, + 64,192,72,216,56,8,8,5,7,7,6,0,0,32,0,32, + 64,128,136,112,5,8,8,6,0,0,64,32,0,112,136,248, + 136,136,5,8,8,6,0,0,16,32,0,112,136,248,136,136, + 5,8,8,6,0,0,32,80,0,112,136,248,136,136,5,8, + 8,6,0,0,104,144,0,112,136,248,136,136,5,8,8,6, + 0,0,80,0,112,136,136,248,136,136,5,8,8,6,0,0, + 32,80,32,112,136,248,136,136,5,7,7,6,0,0,56,96, + 160,184,224,160,184,5,8,8,6,0,255,112,136,128,128,136, + 112,32,96,5,8,8,6,0,0,64,32,0,248,128,240,128, + 248,5,8,8,6,0,0,8,16,0,248,128,240,128,248,5, + 8,8,6,0,0,32,80,0,248,128,240,128,248,5,7,7, + 6,0,0,80,0,248,128,240,128,248,3,8,8,6,1,0, + 128,64,0,224,64,64,64,224,3,8,8,6,1,0,32,64, + 0,224,64,64,64,224,3,8,8,6,1,0,64,160,0,224, + 64,64,64,224,3,7,7,6,1,0,160,0,224,64,64,64, + 224,5,9,9,6,0,255,80,32,112,136,128,184,136,136,112, + 5,8,8,6,0,0,104,144,0,136,200,168,152,136,5,8, + 8,6,0,0,64,32,112,136,136,136,136,112,5,8,8,6, + 0,0,16,32,112,136,136,136,136,112,5,8,8,6,0,0, + 32,80,0,112,136,136,136,112,5,8,8,6,0,0,104,144, + 0,112,136,136,136,112,5,8,8,6,0,0,80,0,112,136, + 136,136,136,112,5,5,5,6,0,1,136,80,32,80,136,5, + 8,8,6,0,255,16,112,168,168,168,168,112,64,5,8,8, + 6,0,0,64,32,136,136,136,136,136,112,5,8,8,6,0, + 0,16,32,136,136,136,136,136,112,5,8,8,6,0,0,32, + 80,0,136,136,136,136,112,5,8,8,6,0,0,80,0,136, + 136,136,136,136,112,1,7,7,6,2,0,128,0,128,128,128, + 128,128,5,9,9,6,0,255,120,128,128,112,8,8,240,32, + 96,4,8,8,6,1,255,96,144,144,160,144,144,224,128,5, + 8,8,6,0,0,64,32,0,112,8,120,136,120,5,8,8, + 6,0,0,16,32,0,112,8,120,136,120,5,8,8,6,0, + 0,32,80,0,112,8,120,136,120,5,8,8,6,0,0,104, + 144,0,112,8,120,136,120,5,7,7,6,0,0,80,0,112, + 8,120,136,120,5,8,8,6,0,0,32,80,32,112,8,120, + 136,120,5,6,6,6,0,0,208,40,120,160,168,80,5,7, + 7,6,0,255,112,128,128,136,112,32,96,5,8,8,6,0, + 0,64,32,0,112,136,248,128,112,5,8,8,6,0,0,16, + 32,0,112,136,248,128,112,5,8,8,6,0,0,32,80,0, + 112,136,248,128,112,5,7,7,6,0,0,80,0,112,136,248, + 128,112,3,8,8,6,1,0,128,64,0,64,192,64,64,224, + 3,8,8,6,1,0,32,64,0,64,192,64,64,224,3,8, + 8,6,1,0,64,160,0,64,192,64,64,224,3,7,7,6, + 1,0,160,0,64,192,64,64,224,5,8,8,6,0,255,80, + 32,112,136,136,120,8,112,5,8,8,6,0,0,104,144,0, + 176,200,136,136,136,5,8,8,6,0,0,64,32,0,112,136, + 136,136,112,5,8,8,6,0,0,16,32,0,112,136,136,136, + 112,5,8,8,6,0,0,32,80,0,112,136,136,136,112,5, + 8,8,6,0,0,104,144,0,112,136,136,136,112,5,7,7, + 6,0,0,80,0,112,136,136,136,112,5,5,5,6,0,1, + 32,0,248,0,32,5,7,7,6,0,255,16,112,168,168,168, + 112,64,5,8,8,6,0,0,64,32,0,136,136,136,152,104, + 5,8,8,6,0,0,16,32,0,136,136,136,152,104,5,8, + 8,6,0,0,32,80,0,136,136,136,152,104,5,7,7,6, + 0,0,80,0,136,136,136,152,104,1,5,5,6,2,0,128, + 128,128,128,128,5,7,7,6,0,255,112,128,112,8,240,32, + 96,5,8,8,6,0,255,80,0,136,136,136,120,8,112}; diff --git a/trunk/Arduino/Marlin_1.1.6/dogm_font_data_ISO10646_5_Cyrillic.h b/trunk/Arduino/Marlin_1.1.6/dogm_font_data_ISO10646_5_Cyrillic.h new file mode 100644 index 00000000..75e779fd --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/dogm_font_data_ISO10646_5_Cyrillic.h @@ -0,0 +1,196 @@ +/** + * 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 . + * + */ + +/** + Fontname: ISO10646_5_Cyrillic + Copyright: A. Hardtung, public domain + Capital A Height: 7, '1' Height: 7 + Calculated Max Values w= 5 h= 9 x= 2 y= 5 dx= 6 dy= 0 ascent= 8 len= 9 + Font Bounding box w= 6 h= 9 x= 0 y=-2 + Calculated Min Values x= 0 y=-1 dx= 0 dy= 0 + Pure Font ascent = 7 descent=-1 + X Font ascent = 7 descent=-1 + Max Font ascent = 8 descent=-1 +*/ +#include +const u8g_fntpgm_uint8_t ISO10646_5_Cyrillic_5x7[2560] U8G_SECTION(".progmem.ISO10646_5_Cyrillic_5x7") = { + 0, 6, 9, 0, 254, 7, 1, 145, 3, 32, 32, 255, 255, 8, 255, 7, + 255, 0, 0, 0, 6, 0, 0, 1, 7, 7, 6, 2, 0, 128, 128, 128, + 128, 128, 0, 128, 3, 2, 2, 6, 1, 5, 160, 160, 5, 7, 7, 6, + 0, 0, 80, 80, 248, 80, 248, 80, 80, 5, 7, 7, 6, 0, 0, 32, + 120, 160, 112, 40, 240, 32, 5, 7, 7, 6, 0, 0, 192, 200, 16, 32, + 64, 152, 24, 5, 7, 7, 6, 0, 0, 96, 144, 160, 64, 168, 144, 104, + 2, 3, 3, 6, 1, 4, 192, 64, 128, 3, 7, 7, 6, 1, 0, 32, + 64, 128, 128, 128, 64, 32, 3, 7, 7, 6, 1, 0, 128, 64, 32, 32, + 32, 64, 128, 5, 5, 5, 6, 0, 1, 32, 168, 112, 168, 32, 5, 5, + 5, 6, 0, 1, 32, 32, 248, 32, 32, 2, 3, 3, 6, 2, 255, 192, + 64, 128, 5, 1, 1, 6, 0, 3, 248, 2, 2, 2, 6, 2, 0, 192, + 192, 5, 5, 5, 6, 0, 1, 8, 16, 32, 64, 128, 5, 7, 7, 6, + 0, 0, 112, 136, 152, 168, 200, 136, 112, 3, 7, 7, 6, 1, 0, 64, + 192, 64, 64, 64, 64, 224, 5, 7, 7, 6, 0, 0, 112, 136, 8, 112, + 128, 128, 248, 5, 7, 7, 6, 0, 0, 248, 16, 32, 16, 8, 8, 240, + 5, 7, 7, 6, 0, 0, 16, 48, 80, 144, 248, 16, 16, 5, 7, 7, + 6, 0, 0, 248, 128, 240, 8, 8, 136, 112, 5, 7, 7, 6, 0, 0, + 48, 64, 128, 240, 136, 136, 112, 5, 7, 7, 6, 0, 0, 248, 8, 16, + 32, 32, 32, 32, 5, 7, 7, 6, 0, 0, 112, 136, 136, 112, 136, 136, + 112, 5, 7, 7, 6, 0, 0, 112, 136, 136, 120, 8, 16, 96, 2, 5, + 5, 6, 2, 0, 192, 192, 0, 192, 192, 2, 6, 6, 6, 2, 255, 192, + 192, 0, 192, 64, 128, 4, 7, 7, 6, 0, 0, 16, 32, 64, 128, 64, + 32, 16, 5, 3, 3, 6, 0, 2, 248, 0, 248, 4, 7, 7, 6, 1, + 0, 128, 64, 32, 16, 32, 64, 128, 5, 7, 7, 6, 0, 0, 112, 136, + 8, 16, 32, 0, 32, 5, 6, 6, 6, 0, 0, 112, 136, 8, 104, 168, + 112, 5, 7, 7, 6, 0, 0, 112, 136, 136, 248, 136, 136, 136, 5, 7, + 7, 6, 0, 0, 240, 136, 136, 240, 136, 136, 240, 5, 7, 7, 6, 0, + 0, 112, 136, 128, 128, 128, 136, 112, 5, 7, 7, 6, 0, 0, 224, 144, + 136, 136, 136, 144, 224, 5, 7, 7, 6, 0, 0, 248, 128, 128, 240, 128, + 128, 248, 5, 7, 7, 6, 0, 0, 248, 128, 128, 240, 128, 128, 128, 5, + 7, 7, 6, 0, 0, 112, 136, 128, 184, 136, 136, 112, 5, 7, 7, 6, + 0, 0, 136, 136, 136, 248, 136, 136, 136, 1, 7, 7, 6, 2, 0, 128, + 128, 128, 128, 128, 128, 128, 5, 7, 7, 6, 0, 0, 56, 16, 16, 16, + 16, 144, 96, 5, 7, 7, 6, 0, 0, 136, 144, 160, 192, 160, 144, 136, + 5, 7, 7, 6, 0, 0, 128, 128, 128, 128, 128, 128, 248, 5, 7, 7, + 6, 0, 0, 136, 216, 168, 136, 136, 136, 136, 5, 7, 7, 6, 0, 0, + 136, 136, 200, 168, 152, 136, 136, 5, 7, 7, 6, 0, 0, 112, 136, 136, + 136, 136, 136, 112, 5, 7, 7, 6, 0, 0, 240, 136, 136, 240, 128, 128, + 128, 5, 7, 7, 6, 0, 0, 112, 136, 136, 136, 168, 144, 104, 5, 7, + 7, 6, 0, 0, 240, 136, 136, 240, 160, 144, 136, 5, 7, 7, 6, 0, + 0, 120, 128, 128, 112, 8, 8, 240, 5, 7, 7, 6, 0, 0, 248, 32, + 32, 32, 32, 32, 32, 5, 7, 7, 6, 0, 0, 136, 136, 136, 136, 136, + 136, 112, 5, 7, 7, 6, 0, 0, 136, 136, 136, 136, 136, 80, 32, 5, + 7, 7, 6, 0, 0, 136, 136, 136, 136, 136, 168, 80, 5, 7, 7, 6, + 0, 0, 136, 136, 80, 32, 80, 136, 136, 5, 7, 7, 6, 0, 0, 136, + 136, 136, 80, 32, 32, 32, 5, 7, 7, 6, 0, 0, 248, 8, 16, 32, + 64, 128, 248, 3, 7, 7, 6, 1, 0, 224, 128, 128, 128, 128, 128, 224, + 5, 5, 5, 6, 0, 1, 128, 64, 32, 16, 8, 3, 7, 7, 6, 1, + 0, 224, 32, 32, 32, 32, 32, 224, 5, 3, 3, 6, 0, 4, 32, 80, + 136, 5, 1, 1, 6, 0, 0, 248, 2, 2, 2, 6, 2, 5, 128, 64, + 5, 5, 5, 6, 0, 0, 112, 8, 120, 136, 120, 5, 7, 7, 6, 0, + 0, 128, 128, 176, 200, 136, 136, 240, 5, 5, 5, 6, 0, 0, 112, 128, + 128, 136, 112, 5, 7, 7, 6, 0, 0, 8, 8, 104, 152, 136, 136, 120, + 5, 5, 5, 6, 0, 0, 112, 136, 248, 128, 112, 5, 7, 7, 6, 0, + 0, 48, 72, 224, 64, 64, 64, 64, 5, 6, 6, 6, 0, 255, 112, 136, + 136, 120, 8, 112, 5, 7, 7, 6, 0, 0, 128, 128, 176, 200, 136, 136, + 136, 1, 7, 7, 6, 2, 0, 128, 0, 128, 128, 128, 128, 128, 3, 8, + 8, 6, 1, 255, 32, 0, 32, 32, 32, 32, 160, 64, 4, 7, 7, 6, + 0, 0, 128, 128, 144, 160, 192, 160, 144, 3, 7, 7, 6, 1, 0, 192, + 64, 64, 64, 64, 64, 224, 5, 5, 5, 6, 0, 0, 208, 168, 168, 168, + 168, 5, 5, 5, 6, 0, 0, 176, 200, 136, 136, 136, 5, 5, 5, 6, + 0, 0, 112, 136, 136, 136, 112, 5, 6, 6, 6, 0, 255, 240, 136, 136, + 240, 128, 128, 5, 6, 6, 6, 0, 255, 120, 136, 136, 120, 8, 8, 5, + 5, 5, 6, 0, 0, 176, 200, 128, 128, 128, 5, 5, 5, 6, 0, 0, + 112, 128, 112, 8, 240, 5, 7, 7, 6, 0, 0, 64, 64, 224, 64, 64, + 72, 48, 5, 5, 5, 6, 0, 0, 136, 136, 136, 152, 104, 5, 5, 5, + 6, 0, 0, 136, 136, 136, 80, 32, 5, 5, 5, 6, 0, 0, 136, 136, + 168, 168, 80, 5, 5, 5, 6, 0, 0, 136, 80, 32, 80, 136, 5, 6, + 6, 6, 0, 255, 136, 136, 136, 120, 8, 112, 5, 5, 5, 6, 0, 0, + 248, 16, 32, 64, 248, 3, 7, 7, 6, 1, 0, 32, 64, 64, 128, 64, + 64, 32, 1, 7, 7, 6, 2, 0, 128, 128, 128, 128, 128, 128, 128, 3, + 7, 7, 6, 1, 0, 128, 64, 64, 32, 64, 64, 128, 5, 2, 2, 6, + 0, 3, 104, 144, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, + 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, + 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, + 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, + 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, + 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, + 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, + 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, + 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, + 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, + 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, + 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, + 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 5, 8, 8, 6, 0, 0, + 64, 248, 128, 128, 240, 128, 128, 248, 5, 8, 8, 6, 0, 0, 80, 248, + 128, 128, 240, 128, 128, 248, 5, 7, 7, 6, 0, 0, 224, 64, 64, 112, + 72, 72, 112, 5, 8, 8, 6, 0, 0, 16, 32, 248, 136, 128, 128, 128, + 128, 5, 7, 7, 6, 0, 0, 48, 72, 128, 224, 128, 72, 48, 5, 7, + 7, 6, 0, 0, 112, 136, 128, 112, 8, 136, 112, 3, 7, 7, 6, 1, + 0, 224, 64, 64, 64, 64, 64, 224, 3, 8, 8, 6, 1, 0, 160, 0, + 224, 64, 64, 64, 64, 224, 5, 7, 7, 6, 0, 0, 56, 16, 16, 16, + 16, 144, 96, 5, 7, 7, 6, 0, 0, 160, 160, 160, 184, 168, 168, 184, + 5, 7, 7, 6, 0, 0, 160, 160, 160, 248, 168, 168, 184, 4, 7, 7, + 6, 0, 0, 224, 64, 112, 80, 80, 80, 80, 5, 8, 8, 6, 0, 0, + 16, 32, 136, 144, 160, 224, 144, 136, 5, 8, 8, 6, 0, 0, 64, 32, + 136, 152, 168, 200, 136, 136, 5, 9, 9, 6, 0, 255, 80, 32, 136, 136, + 136, 80, 32, 32, 32, 5, 8, 8, 6, 0, 255, 136, 136, 136, 136, 136, + 136, 248, 32, 5, 7, 7, 6, 0, 0, 112, 136, 136, 248, 136, 136, 136, + 5, 7, 7, 6, 0, 0, 248, 128, 128, 240, 136, 136, 240, 5, 7, 7, + 6, 0, 0, 240, 136, 136, 240, 136, 136, 240, 5, 7, 7, 6, 0, 0, + 248, 136, 128, 128, 128, 128, 128, 5, 8, 8, 6, 0, 255, 120, 40, 40, + 40, 72, 136, 248, 136, 5, 7, 7, 6, 0, 0, 248, 128, 128, 240, 128, + 128, 248, 5, 7, 7, 6, 0, 0, 168, 168, 168, 112, 168, 168, 168, 5, + 7, 7, 6, 0, 0, 240, 8, 8, 112, 8, 8, 240, 5, 7, 7, 6, + 0, 0, 136, 136, 152, 168, 200, 136, 136, 5, 8, 8, 6, 0, 0, 80, + 32, 136, 152, 168, 168, 200, 136, 5, 7, 7, 6, 0, 0, 136, 144, 160, + 192, 160, 144, 136, 5, 7, 7, 6, 0, 0, 120, 40, 40, 40, 40, 168, + 72, 5, 7, 7, 6, 0, 0, 136, 216, 168, 136, 136, 136, 136, 5, 7, + 7, 6, 0, 0, 136, 136, 136, 248, 136, 136, 136, 5, 7, 7, 6, 0, + 0, 112, 136, 136, 136, 136, 136, 112, 5, 7, 7, 6, 0, 0, 248, 136, + 136, 136, 136, 136, 136, 5, 7, 7, 6, 0, 0, 240, 136, 136, 240, 128, + 128, 128, 5, 7, 7, 6, 0, 0, 112, 136, 128, 128, 128, 136, 112, 5, + 7, 7, 6, 0, 0, 248, 32, 32, 32, 32, 32, 32, 5, 7, 7, 6, + 0, 0, 136, 136, 136, 80, 32, 64, 128, 5, 7, 7, 6, 0, 0, 32, + 112, 168, 168, 168, 112, 32, 5, 7, 7, 6, 0, 0, 136, 136, 80, 32, + 80, 136, 136, 5, 8, 8, 6, 0, 255, 136, 136, 136, 136, 136, 136, 248, + 8, 5, 7, 7, 6, 0, 0, 136, 136, 136, 152, 104, 8, 8, 5, 7, + 7, 6, 0, 0, 168, 168, 168, 168, 168, 168, 248, 5, 8, 8, 6, 0, + 255, 168, 168, 168, 168, 168, 168, 248, 8, 5, 7, 7, 6, 0, 0, 192, + 64, 64, 112, 72, 72, 112, 5, 7, 7, 6, 0, 0, 136, 136, 136, 200, + 168, 168, 200, 5, 7, 7, 6, 0, 0, 128, 128, 128, 240, 136, 136, 240, + 5, 7, 7, 6, 0, 0, 112, 136, 8, 56, 8, 136, 112, 5, 7, 7, + 6, 0, 0, 144, 168, 168, 232, 168, 168, 144, 5, 7, 7, 6, 0, 0, + 120, 136, 136, 120, 40, 72, 136, 5, 5, 5, 6, 0, 0, 112, 8, 120, + 136, 120, 5, 7, 7, 6, 0, 0, 24, 96, 128, 240, 136, 136, 112, 4, + 5, 5, 6, 0, 0, 224, 144, 224, 144, 224, 5, 5, 5, 6, 0, 0, + 248, 136, 128, 128, 128, 5, 6, 6, 6, 0, 255, 120, 40, 72, 136, 248, + 136, 5, 5, 5, 6, 0, 0, 112, 136, 248, 128, 112, 5, 5, 5, 6, + 0, 0, 168, 168, 112, 168, 168, 5, 5, 5, 6, 0, 0, 240, 8, 48, + 8, 240, 5, 5, 5, 6, 0, 0, 136, 152, 168, 200, 136, 5, 7, 7, + 6, 0, 0, 80, 32, 136, 152, 168, 200, 136, 4, 5, 5, 6, 0, 0, + 144, 160, 192, 160, 144, 5, 5, 5, 6, 0, 0, 248, 40, 40, 168, 72, + 5, 5, 5, 6, 0, 0, 136, 216, 168, 136, 136, 5, 5, 5, 6, 0, + 0, 136, 136, 248, 136, 136, 5, 5, 5, 6, 0, 0, 112, 136, 136, 136, + 112, 5, 5, 5, 6, 0, 0, 248, 136, 136, 136, 136, 5, 6, 6, 6, + 0, 255, 240, 136, 136, 240, 128, 128, 5, 5, 5, 6, 0, 0, 112, 128, + 128, 136, 112, 5, 5, 5, 6, 0, 0, 248, 32, 32, 32, 32, 5, 6, + 6, 6, 0, 255, 136, 136, 136, 120, 8, 112, 5, 6, 6, 6, 0, 0, + 32, 112, 168, 168, 112, 32, 5, 5, 5, 6, 0, 0, 136, 80, 32, 80, + 136, 5, 6, 6, 6, 0, 255, 136, 136, 136, 136, 248, 8, 5, 5, 5, + 6, 0, 0, 136, 136, 248, 8, 8, 5, 5, 5, 6, 0, 0, 168, 168, + 168, 168, 248, 5, 6, 6, 6, 0, 255, 168, 168, 168, 168, 248, 8, 5, + 5, 5, 6, 0, 0, 192, 64, 112, 72, 112, 5, 5, 5, 6, 0, 0, + 136, 136, 200, 168, 200, 3, 5, 5, 6, 1, 0, 128, 128, 192, 160, 192, + 5, 5, 5, 6, 0, 0, 112, 136, 56, 136, 112, 5, 5, 5, 6, 0, + 0, 144, 168, 232, 168, 144, 5, 5, 5, 6, 0, 0, 120, 136, 120, 40, + 72, 5, 8, 8, 6, 0, 0, 64, 32, 0, 112, 136, 248, 128, 112, 5, + 7, 7, 6, 0, 0, 80, 0, 112, 136, 248, 128, 112, 5, 9, 9, 6, + 0, 255, 64, 224, 64, 64, 120, 72, 72, 72, 16, 5, 8, 8, 6, 0, + 0, 16, 32, 0, 248, 136, 128, 128, 128, 5, 5, 5, 6, 0, 0, 112, + 136, 96, 136, 112, 5, 5, 5, 6, 0, 0, 112, 128, 112, 8, 240, 1, + 7, 7, 6, 2, 0, 128, 0, 128, 128, 128, 128, 128, 3, 7, 7, 6, + 1, 0, 160, 0, 64, 64, 64, 64, 64, 3, 8, 8, 6, 1, 255, 32, + 0, 32, 32, 32, 32, 160, 64, 5, 5, 5, 6, 0, 0, 160, 160, 184, + 168, 184, 5, 5, 5, 6, 0, 0, 160, 160, 248, 168, 184, 5, 6, 6, + 6, 0, 0, 64, 224, 64, 120, 72, 72, 4, 8, 8, 6, 0, 0, 16, + 32, 0, 144, 160, 192, 160, 144, 5, 8, 8, 6, 0, 0, 64, 32, 0, + 136, 152, 168, 200, 136, 5, 9, 9, 6, 0, 255, 80, 32, 0, 136, 136, + 136, 120, 8, 112, 5, 6, 6, 6, 0, 255, 136, 136, 136, 136, 248, 32 +}; diff --git a/trunk/Arduino/Marlin_1.1.6/dogm_font_data_ISO10646_CN.h b/trunk/Arduino/Marlin_1.1.6/dogm_font_data_ISO10646_CN.h new file mode 100644 index 00000000..11fdb224 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/dogm_font_data_ISO10646_CN.h @@ -0,0 +1,293 @@ +/** + * 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 . + * + */ + +/** + Fontname: ISO10646_CN + Copyright: A. Hardtung, public domain + Capital A Height: 7, '1' Height: 7 + Calculated Max Values w=11 h=11 x= 2 y=10 dx=12 dy= 0 ascent=10 len=22 + Font Bounding box w=12 h=11 x= 0 y=-2 + Calculated Min Values x= 0 y=-1 dx= 0 dy= 0 + Pure Font ascent = 7 descent=-1 + X Font ascent = 7 descent=-1 + Max Font ascent =10 descent=-1 +*/ +#include +const u8g_fntpgm_uint8_t ISO10646_CN[4105] U8G_SECTION(".progmem.ISO10646_CN") = { + 0, 12, 11, 0, 254, 7, 1, 146, 3, 33, 32, 255, 255, 10, 255, 7, + 255, 0, 0, 0, 6, 0, 10, 1, 7, 7, 6, 2, 0, 128, 128, 128, + 128, 128, 0, 128, 3, 2, 2, 6, 1, 5, 160, 160, 5, 7, 7, 6, + 0, 0, 80, 80, 248, 80, 248, 80, 80, 5, 7, 7, 6, 0, 0, 32, + 120, 160, 112, 40, 240, 32, 5, 7, 7, 6, 0, 0, 192, 200, 16, 32, + 64, 152, 24, 5, 7, 7, 6, 0, 0, 96, 144, 160, 64, 168, 144, 104, + 2, 3, 3, 6, 1, 4, 192, 64, 128, 3, 7, 7, 6, 1, 0, 32, + 64, 128, 128, 128, 64, 32, 3, 7, 7, 6, 1, 0, 128, 64, 32, 32, + 32, 64, 128, 5, 5, 5, 6, 0, 1, 32, 168, 112, 168, 32, 5, 5, + 5, 6, 0, 1, 32, 32, 248, 32, 32, 2, 3, 3, 6, 2, 255, 192, + 64, 128, 5, 1, 1, 6, 0, 3, 248, 2, 2, 2, 6, 2, 0, 192, + 192, 5, 5, 5, 6, 0, 1, 8, 16, 32, 64, 128, 5, 7, 7, 6, + 0, 0, 112, 136, 152, 168, 200, 136, 112, 3, 7, 7, 6, 1, 0, 64, + 192, 64, 64, 64, 64, 224, 5, 7, 7, 6, 0, 0, 112, 136, 8, 112, + 128, 128, 248, 5, 7, 7, 6, 0, 0, 248, 16, 32, 16, 8, 8, 240, + 5, 7, 7, 6, 0, 0, 16, 48, 80, 144, 248, 16, 16, 5, 7, 7, + 6, 0, 0, 248, 128, 240, 8, 8, 136, 112, 5, 7, 7, 6, 0, 0, + 112, 128, 128, 240, 136, 136, 112, 5, 7, 7, 6, 0, 0, 248, 8, 16, + 32, 32, 32, 32, 5, 7, 7, 6, 0, 0, 112, 136, 136, 112, 136, 136, + 112, 5, 7, 7, 6, 0, 0, 112, 136, 136, 120, 8, 8, 112, 2, 5, + 5, 6, 2, 0, 192, 192, 0, 192, 192, 2, 6, 6, 6, 2, 255, 192, + 192, 0, 192, 64, 128, 4, 7, 7, 6, 0, 0, 16, 32, 64, 128, 64, + 32, 16, 5, 3, 3, 6, 0, 2, 248, 0, 248, 4, 7, 7, 6, 0, + 0, 128, 64, 32, 16, 32, 64, 128, 5, 7, 7, 6, 0, 0, 112, 136, + 8, 16, 32, 0, 32, 5, 7, 7, 6, 0, 0, 112, 136, 8, 104, 168, + 168, 112, 5, 7, 7, 6, 0, 0, 112, 136, 136, 248, 136, 136, 136, 5, + 7, 7, 6, 0, 0, 240, 136, 136, 240, 136, 136, 240, 5, 7, 7, 6, + 0, 0, 112, 136, 128, 128, 128, 136, 112, 5, 7, 7, 6, 0, 0, 240, + 136, 136, 136, 136, 136, 240, 5, 7, 7, 6, 0, 0, 248, 128, 128, 240, + 128, 128, 248, 5, 7, 7, 6, 0, 0, 248, 128, 128, 240, 128, 128, 128, + 5, 7, 7, 6, 0, 0, 112, 136, 128, 184, 136, 136, 112, 5, 7, 7, + 6, 0, 0, 136, 136, 136, 248, 136, 136, 136, 1, 7, 7, 6, 2, 0, + 128, 128, 128, 128, 128, 128, 128, 5, 7, 7, 6, 0, 0, 56, 16, 16, + 16, 16, 144, 96, 5, 7, 7, 6, 0, 0, 136, 144, 160, 192, 160, 144, + 136, 5, 7, 7, 6, 0, 0, 128, 128, 128, 128, 128, 128, 248, 5, 7, + 7, 6, 0, 0, 136, 216, 168, 136, 136, 136, 136, 5, 7, 7, 6, 0, + 0, 136, 136, 200, 168, 152, 136, 136, 5, 7, 7, 6, 0, 0, 112, 136, + 136, 136, 136, 136, 112, 5, 7, 7, 6, 0, 0, 240, 136, 136, 240, 128, + 128, 128, 5, 7, 7, 6, 0, 0, 112, 136, 136, 136, 168, 144, 104, 5, + 7, 7, 6, 0, 0, 240, 136, 136, 240, 160, 144, 136, 5, 7, 7, 6, + 0, 0, 120, 128, 128, 112, 8, 8, 240, 5, 7, 7, 6, 0, 0, 248, + 32, 32, 32, 32, 32, 32, 5, 7, 7, 6, 0, 0, 136, 136, 136, 136, + 136, 136, 112, 5, 7, 7, 6, 0, 0, 136, 136, 136, 136, 136, 80, 32, + 5, 7, 7, 6, 0, 0, 136, 136, 136, 136, 136, 168, 80, 5, 7, 7, + 6, 0, 0, 136, 136, 80, 32, 80, 136, 136, 5, 7, 7, 6, 0, 0, + 136, 136, 136, 80, 32, 32, 32, 5, 7, 7, 6, 0, 0, 248, 8, 16, + 32, 64, 128, 248, 3, 7, 7, 6, 0, 0, 224, 128, 128, 128, 128, 128, + 224, 5, 5, 5, 6, 0, 1, 128, 64, 32, 16, 8, 3, 7, 7, 6, + 0, 0, 224, 32, 32, 32, 32, 32, 224, 5, 3, 3, 6, 0, 4, 32, + 80, 136, 5, 1, 1, 6, 0, 0, 248, 2, 2, 2, 6, 2, 5, 128, + 64, 5, 5, 5, 6, 0, 0, 112, 8, 120, 136, 120, 5, 7, 7, 6, + 0, 0, 128, 128, 176, 200, 136, 136, 240, 5, 5, 5, 6, 0, 0, 112, + 128, 128, 136, 112, 5, 7, 7, 6, 0, 0, 8, 8, 104, 152, 136, 136, + 120, 5, 5, 5, 6, 0, 0, 112, 136, 248, 128, 112, 5, 7, 7, 6, + 0, 0, 48, 72, 224, 64, 64, 64, 64, 5, 6, 6, 6, 0, 255, 112, + 136, 136, 120, 8, 112, 5, 7, 7, 6, 0, 0, 128, 128, 176, 200, 136, + 136, 136, 1, 7, 7, 6, 2, 0, 128, 0, 128, 128, 128, 128, 128, 3, + 8, 8, 6, 1, 255, 32, 0, 32, 32, 32, 32, 160, 64, 4, 7, 7, + 6, 1, 0, 128, 128, 144, 160, 192, 160, 144, 3, 7, 7, 6, 1, 0, + 192, 64, 64, 64, 64, 64, 224, 5, 5, 5, 6, 0, 0, 208, 168, 168, + 168, 168, 5, 5, 5, 6, 0, 0, 176, 200, 136, 136, 136, 5, 5, 5, + 6, 0, 0, 112, 136, 136, 136, 112, 5, 6, 6, 6, 0, 255, 240, 136, + 136, 240, 128, 128, 5, 6, 6, 6, 0, 255, 120, 136, 136, 120, 8, 8, + 5, 5, 5, 6, 0, 0, 176, 200, 128, 128, 128, 5, 5, 5, 6, 0, + 0, 112, 128, 112, 8, 240, 4, 7, 7, 6, 0, 0, 64, 64, 224, 64, + 64, 64, 48, 5, 5, 5, 6, 0, 0, 136, 136, 136, 152, 104, 5, 5, + 5, 6, 0, 0, 136, 136, 136, 80, 32, 5, 5, 5, 6, 0, 0, 136, + 136, 168, 168, 80, 5, 5, 5, 6, 0, 0, 136, 80, 32, 80, 136, 5, + 6, 6, 6, 0, 255, 136, 136, 136, 120, 8, 112, 5, 5, 5, 6, 0, + 0, 248, 16, 32, 64, 248, 3, 7, 7, 6, 1, 0, 32, 64, 64, 128, + 64, 64, 32, 1, 7, 7, 6, 2, 0, 128, 128, 128, 128, 128, 128, 128, + 3, 7, 7, 6, 1, 0, 128, 64, 64, 32, 64, 64, 128, 5, 2, 2, + 6, 0, 3, 104, 144, 0, 0, 0, 6, 0, 10, 0, 0, 0, 12, 0, + 10, 0, 0, 0, 12, 0, 10, 0, 0, 0, 12, 0, 10, 0, 0, 0, + 12, 0, 10, 0, 0, 0, 12, 0, 10, 0, 0, 0, 12, 0, 10, 0, + 0, 0, 12, 0, 10, 0, 0, 0, 12, 0, 10, 0, 0, 0, 12, 0, + 10, 0, 0, 0, 12, 0, 10, 0, 0, 0, 12, 0, 10, 0, 0, 0, + 12, 0, 10, 0, 0, 0, 12, 0, 10, 0, 0, 0, 12, 0, 10, 0, + 0, 0, 12, 0, 10, 0, 0, 0, 12, 0, 10, 0, 0, 0, 12, 0, + 10, 0, 0, 0, 12, 0, 10, 0, 0, 0, 12, 0, 10, 0, 0, 0, + 12, 0, 10, 0, 0, 0, 12, 0, 10, 0, 0, 0, 12, 0, 10, 0, + 0, 0, 12, 0, 10, 0, 0, 0, 12, 0, 10, 0, 0, 0, 12, 0, + 10, 0, 0, 0, 12, 0, 10, 0, 0, 0, 12, 0, 10, 0, 0, 0, + 12, 0, 10, 0, 0, 0, 12, 0, 10, 11, 11, 22, 12, 0, 255, 255, + 224, 2, 0, 2, 0, 4, 0, 13, 0, 20, 128, 36, 64, 196, 32, 4, + 0, 4, 0, 4, 0, 11, 11, 22, 12, 0, 255, 249, 0, 138, 0, 171, + 224, 172, 64, 170, 64, 170, 64, 170, 64, 170, 128, 33, 0, 82, 128, 140, + 96, 11, 11, 22, 12, 0, 255, 36, 0, 36, 0, 63, 128, 68, 0, 132, + 0, 4, 0, 255, 224, 10, 0, 17, 0, 32, 128, 192, 96, 11, 11, 22, + 12, 0, 255, 36, 0, 36, 0, 63, 192, 68, 0, 4, 0, 255, 224, 9, + 0, 9, 0, 17, 32, 33, 32, 64, 224, 11, 11, 22, 12, 0, 255, 32, + 0, 61, 224, 81, 32, 145, 32, 17, 32, 255, 32, 17, 32, 41, 32, 37, + 224, 69, 32, 128, 0, 11, 11, 22, 12, 0, 255, 32, 128, 127, 192, 8, + 64, 255, 224, 17, 0, 32, 128, 95, 64, 128, 32, 63, 128, 0, 0, 127, + 192, 11, 11, 22, 12, 0, 255, 34, 64, 71, 224, 148, 128, 228, 128, 47, + 224, 68, 128, 244, 128, 7, 224, 52, 128, 196, 128, 7, 224, 11, 11, 22, + 12, 0, 255, 4, 128, 143, 224, 73, 0, 25, 0, 47, 192, 9, 0, 9, + 0, 47, 192, 73, 0, 137, 0, 15, 224, 11, 11, 22, 12, 0, 255, 16, + 0, 63, 128, 81, 0, 14, 0, 49, 128, 192, 96, 63, 128, 36, 128, 63, + 128, 36, 128, 63, 128, 11, 11, 22, 12, 0, 255, 34, 128, 250, 64, 7, + 224, 250, 128, 138, 128, 138, 128, 250, 128, 34, 128, 178, 128, 170, 160, 100, + 224, 11, 11, 22, 12, 0, 255, 34, 32, 71, 64, 146, 128, 239, 224, 34, + 0, 71, 192, 236, 64, 7, 192, 52, 64, 199, 192, 4, 64, 11, 11, 22, + 12, 0, 255, 8, 0, 15, 192, 8, 0, 8, 0, 255, 224, 8, 0, 14, + 0, 9, 128, 8, 64, 8, 0, 8, 0, 10, 11, 22, 12, 0, 255, 255, + 128, 0, 128, 0, 128, 128, 128, 128, 128, 255, 128, 128, 0, 128, 0, 128, + 64, 128, 64, 127, 192, 11, 11, 22, 12, 0, 255, 71, 192, 65, 0, 239, + 224, 65, 0, 69, 0, 105, 96, 201, 32, 77, 96, 73, 32, 79, 224, 200, + 32, 11, 11, 22, 12, 0, 255, 8, 0, 4, 0, 4, 0, 10, 0, 10, + 0, 10, 0, 17, 0, 17, 0, 32, 128, 64, 64, 128, 32, 11, 11, 22, + 12, 0, 255, 34, 64, 34, 0, 247, 224, 34, 0, 35, 224, 53, 32, 229, + 32, 37, 64, 40, 128, 41, 64, 114, 32, 11, 10, 20, 12, 0, 0, 68, + 64, 68, 64, 68, 64, 127, 192, 4, 0, 4, 0, 132, 32, 132, 32, 132, + 32, 255, 224, 11, 11, 22, 12, 0, 255, 4, 0, 0, 0, 127, 192, 4, + 0, 4, 0, 4, 0, 127, 192, 4, 0, 4, 0, 4, 0, 255, 224, 11, + 11, 22, 12, 0, 255, 255, 224, 17, 0, 1, 192, 254, 0, 72, 128, 37, + 0, 4, 0, 255, 224, 21, 0, 36, 128, 196, 96, 11, 11, 22, 12, 0, + 255, 17, 0, 127, 192, 68, 64, 127, 192, 68, 64, 127, 192, 4, 0, 255, + 224, 4, 0, 4, 0, 4, 0, 9, 11, 22, 12, 0, 255, 16, 0, 255, + 128, 128, 128, 128, 128, 255, 128, 128, 128, 128, 128, 255, 128, 128, 128, 128, + 128, 255, 128, 11, 11, 22, 12, 0, 255, 113, 0, 1, 0, 3, 224, 249, + 32, 33, 32, 65, 32, 81, 32, 137, 32, 250, 32, 2, 32, 4, 192, 11, + 11, 22, 12, 0, 255, 127, 192, 17, 0, 17, 0, 17, 0, 17, 0, 255, + 224, 17, 0, 17, 0, 33, 0, 33, 0, 65, 0, 11, 11, 22, 12, 0, + 255, 33, 0, 34, 0, 244, 64, 87, 224, 80, 32, 87, 192, 148, 64, 84, + 64, 36, 64, 87, 192, 148, 64, 11, 11, 22, 12, 0, 255, 17, 0, 10, + 0, 127, 192, 4, 0, 4, 0, 255, 224, 4, 0, 10, 0, 17, 0, 32, + 128, 192, 96, 10, 11, 22, 12, 0, 255, 95, 192, 0, 64, 132, 64, 132, + 64, 191, 64, 132, 64, 140, 64, 148, 64, 164, 64, 140, 64, 129, 192, 11, + 11, 22, 12, 0, 255, 36, 0, 39, 192, 36, 0, 36, 0, 255, 224, 0, + 0, 20, 64, 36, 128, 71, 0, 12, 0, 112, 0, 11, 11, 22, 12, 0, + 255, 36, 128, 4, 128, 15, 192, 228, 128, 36, 128, 63, 224, 36, 128, 36, + 128, 40, 128, 80, 0, 143, 224, 11, 11, 22, 12, 0, 255, 8, 0, 8, + 0, 255, 128, 136, 128, 136, 128, 255, 128, 136, 128, 136, 128, 255, 160, 136, + 32, 7, 224, 11, 11, 22, 12, 0, 255, 39, 128, 36, 128, 244, 128, 36, + 128, 116, 128, 108, 128, 164, 128, 36, 128, 36, 160, 40, 160, 48, 96, 10, + 11, 22, 12, 0, 255, 255, 192, 128, 64, 128, 64, 158, 64, 146, 64, 146, + 64, 158, 64, 128, 64, 128, 64, 255, 192, 128, 64, 11, 11, 22, 12, 0, + 255, 127, 192, 68, 0, 95, 192, 80, 64, 95, 192, 80, 64, 95, 192, 66, + 0, 74, 128, 82, 64, 166, 32, 11, 11, 22, 12, 0, 255, 4, 0, 7, + 224, 4, 0, 127, 192, 64, 64, 64, 64, 64, 64, 127, 192, 0, 0, 82, + 64, 137, 32, 11, 11, 22, 12, 0, 255, 71, 128, 36, 128, 4, 128, 4, + 128, 232, 96, 32, 0, 47, 192, 36, 64, 34, 128, 49, 0, 38, 192, 11, + 11, 22, 12, 0, 255, 127, 192, 74, 64, 127, 192, 4, 0, 255, 224, 4, + 0, 63, 128, 32, 128, 36, 128, 36, 128, 255, 224, 11, 11, 22, 12, 0, + 255, 34, 0, 79, 224, 72, 32, 79, 224, 200, 0, 79, 224, 74, 160, 90, + 160, 111, 224, 74, 160, 72, 96, 11, 11, 22, 12, 0, 255, 243, 192, 36, + 64, 42, 128, 241, 0, 34, 128, 101, 224, 114, 32, 165, 64, 32, 128, 35, + 0, 44, 0, 11, 11, 22, 12, 0, 255, 4, 0, 255, 224, 128, 32, 0, + 0, 255, 224, 4, 0, 36, 0, 39, 192, 36, 0, 84, 0, 143, 224, 11, + 11, 22, 12, 0, 255, 115, 224, 16, 128, 81, 0, 35, 224, 250, 32, 42, + 160, 34, 160, 34, 160, 32, 128, 33, 64, 98, 32, 11, 11, 22, 12, 0, + 255, 34, 0, 247, 128, 34, 128, 54, 128, 226, 160, 37, 160, 36, 96, 104, + 32, 0, 0, 82, 64, 137, 32, 11, 11, 22, 12, 0, 255, 115, 192, 66, + 0, 66, 0, 123, 224, 74, 64, 74, 64, 122, 64, 74, 64, 66, 64, 68, + 64, 136, 64, 11, 11, 22, 12, 0, 255, 8, 0, 255, 224, 8, 0, 31, + 192, 48, 64, 95, 192, 144, 64, 31, 192, 16, 64, 16, 64, 16, 192, 11, + 11, 22, 12, 0, 255, 2, 0, 127, 224, 66, 0, 66, 0, 95, 192, 66, + 0, 71, 0, 74, 128, 82, 64, 98, 32, 130, 0, 11, 11, 22, 12, 0, + 255, 243, 192, 150, 64, 145, 128, 166, 96, 161, 0, 151, 192, 145, 0, 149, + 0, 231, 224, 129, 0, 129, 0, 11, 11, 22, 12, 0, 255, 15, 128, 136, + 128, 79, 128, 8, 128, 143, 128, 64, 0, 31, 192, 53, 64, 85, 64, 149, + 64, 63, 224, 11, 11, 22, 12, 0, 255, 39, 224, 32, 128, 248, 128, 32, + 128, 32, 128, 56, 128, 224, 128, 32, 128, 32, 128, 32, 128, 97, 128, 11, + 11, 22, 12, 0, 255, 31, 224, 145, 0, 87, 192, 20, 64, 23, 192, 148, + 64, 87, 192, 17, 0, 85, 64, 153, 32, 35, 0, 11, 11, 22, 12, 0, + 255, 32, 128, 39, 224, 242, 64, 33, 128, 34, 64, 52, 32, 226, 64, 34, + 64, 34, 64, 34, 64, 100, 64, 11, 11, 22, 12, 0, 255, 65, 0, 65, + 0, 79, 224, 233, 32, 73, 32, 73, 32, 111, 224, 201, 32, 73, 32, 73, + 32, 207, 224, 11, 11, 22, 12, 0, 255, 33, 0, 241, 0, 79, 224, 169, + 32, 249, 32, 47, 224, 57, 32, 233, 32, 41, 32, 47, 224, 40, 32, 11, + 11, 22, 12, 0, 255, 143, 224, 73, 32, 9, 32, 203, 160, 73, 32, 79, + 224, 72, 32, 75, 160, 74, 160, 107, 160, 80, 224, 11, 11, 22, 12, 0, + 255, 127, 192, 4, 0, 68, 64, 36, 64, 36, 128, 4, 0, 255, 224, 4, + 0, 4, 0, 4, 0, 4, 0, 11, 11, 22, 12, 0, 255, 130, 0, 66, + 0, 31, 224, 194, 0, 95, 192, 82, 64, 95, 192, 71, 0, 74, 128, 82, + 64, 191, 224, 11, 11, 22, 12, 0, 255, 4, 0, 127, 224, 72, 128, 127, + 224, 72, 128, 79, 128, 64, 0, 95, 192, 72, 64, 71, 128, 152, 96, 11, + 11, 22, 12, 0, 255, 1, 0, 239, 224, 161, 0, 164, 64, 175, 224, 164, + 64, 175, 224, 169, 32, 233, 32, 2, 128, 12, 96, 11, 11, 22, 12, 0, + 255, 20, 192, 246, 160, 188, 96, 167, 128, 168, 128, 191, 224, 169, 32, 239, + 224, 9, 32, 15, 224, 9, 32, 11, 11, 22, 12, 0, 255, 127, 128, 64, + 128, 66, 128, 98, 128, 84, 128, 72, 128, 72, 128, 84, 160, 98, 160, 64, + 96, 128, 32, 11, 11, 22, 12, 0, 255, 4, 0, 127, 224, 64, 32, 127, + 224, 64, 0, 125, 224, 84, 32, 76, 160, 84, 96, 100, 160, 141, 96, 11, + 11, 22, 12, 0, 255, 130, 0, 95, 224, 4, 0, 8, 64, 159, 224, 64, + 32, 10, 128, 10, 128, 74, 160, 146, 160, 34, 96, 11, 11, 22, 12, 0, + 255, 65, 0, 79, 224, 232, 32, 66, 128, 68, 64, 104, 32, 199, 192, 65, + 0, 65, 0, 65, 0, 207, 224, 11, 11, 22, 12, 0, 255, 80, 32, 125, + 32, 145, 32, 255, 32, 17, 32, 125, 32, 85, 32, 85, 32, 84, 32, 92, + 32, 16, 224, 11, 11, 22, 12, 0, 255, 63, 128, 32, 128, 63, 128, 32, + 128, 255, 224, 72, 0, 123, 192, 73, 64, 121, 64, 72, 128, 251, 96, 11, + 11, 22, 12, 0, 255, 4, 0, 4, 0, 4, 0, 36, 128, 36, 64, 68, + 64, 68, 32, 132, 32, 4, 0, 4, 0, 28, 0, 11, 11, 22, 12, 0, + 255, 4, 0, 4, 0, 4, 0, 255, 224, 4, 0, 10, 0, 10, 0, 17, + 0, 17, 0, 32, 128, 192, 96, 9, 10, 20, 10, 0, 0, 136, 128, 73, + 0, 8, 0, 255, 128, 0, 128, 0, 128, 127, 128, 0, 128, 0, 128, 255, + 128, 11, 11, 22, 12, 0, 255, 33, 0, 18, 0, 255, 224, 0, 0, 120, + 128, 74, 128, 122, 128, 74, 128, 122, 128, 72, 128, 89, 128, 11, 11, 22, + 12, 0, 255, 39, 192, 0, 0, 0, 0, 239, 224, 33, 0, 34, 0, 36, + 64, 47, 224, 32, 32, 80, 0, 143, 224, 11, 11, 22, 12, 0, 255, 32, + 128, 39, 0, 249, 0, 33, 192, 119, 0, 33, 0, 249, 224, 39, 0, 113, + 32, 169, 32, 32, 224, 11, 11, 22, 12, 0, 255, 16, 64, 16, 64, 253, + 224, 16, 64, 56, 192, 53, 64, 82, 64, 148, 64, 16, 64, 16, 64, 16, + 192, 11, 11, 22, 12, 0, 255, 0, 64, 248, 64, 11, 224, 8, 64, 136, + 64, 82, 64, 81, 64, 33, 64, 80, 64, 72, 64, 137, 192, 10, 11, 22, + 12, 0, 255, 132, 0, 132, 64, 132, 128, 245, 0, 134, 0, 132, 0, 132, + 0, 148, 0, 164, 64, 196, 64, 131, 192, 11, 11, 22, 12, 0, 255, 17, + 32, 125, 0, 17, 0, 255, 224, 41, 0, 253, 64, 73, 64, 124, 128, 8, + 160, 253, 96, 10, 32, 11, 11, 22, 12, 0, 255, 23, 192, 36, 64, 36, + 64, 103, 192, 161, 0, 47, 224, 33, 0, 35, 128, 37, 64, 41, 32, 33, + 0, 11, 11, 22, 12, 0, 255, 8, 0, 255, 224, 16, 0, 39, 192, 32, + 128, 97, 0, 175, 224, 33, 0, 33, 0, 33, 0, 35, 0, 11, 11, 22, + 12, 0, 255, 36, 0, 47, 224, 180, 0, 164, 128, 164, 160, 170, 192, 42, + 128, 40, 128, 41, 64, 50, 64, 36, 32, 11, 11, 22, 12, 0, 255, 127, + 224, 128, 0, 63, 192, 32, 64, 63, 192, 16, 0, 31, 192, 16, 64, 40, + 128, 71, 0, 56, 224, 11, 11, 22, 12, 0, 255, 127, 224, 64, 0, 64, + 0, 64, 0, 64, 0, 64, 0, 64, 0, 64, 0, 64, 0, 64, 0, 128, + 0, 11, 11, 22, 12, 0, 255, 255, 224, 4, 0, 127, 192, 68, 64, 127, + 192, 68, 64, 127, 192, 68, 0, 36, 0, 24, 0, 231, 224, 11, 11, 22, + 12, 0, 255, 17, 224, 253, 0, 69, 0, 41, 224, 253, 64, 17, 64, 125, + 64, 17, 64, 85, 64, 146, 64, 52, 64, 11, 11, 22, 12, 0, 255, 33, + 0, 95, 224, 64, 0, 207, 192, 64, 0, 79, 192, 64, 0, 79, 192, 72, + 64, 79, 192, 72, 64, 11, 11, 22, 12, 0, 255, 4, 0, 127, 192, 64, + 64, 127, 192, 64, 64, 127, 192, 64, 64, 127, 192, 4, 64, 82, 32, 191, + 160, 11, 11, 22, 12, 0, 255, 127, 192, 68, 64, 127, 192, 68, 64, 127, + 192, 4, 0, 27, 0, 224, 224, 17, 0, 17, 0, 97, 0, 11, 11, 22, + 12, 0, 255, 255, 224, 4, 0, 8, 0, 127, 224, 73, 32, 79, 32, 73, + 32, 79, 32, 73, 32, 73, 32, 127, 224, 11, 11, 22, 12, 0, 255, 253, + 224, 86, 64, 121, 64, 56, 128, 85, 64, 146, 32, 255, 224, 4, 0, 39, + 192, 36, 0, 255, 224, 11, 11, 22, 12, 0, 255, 251, 128, 82, 0, 123, + 224, 18, 64, 250, 64, 20, 64, 63, 128, 32, 128, 63, 128, 32, 128, 63, + 128, 11, 11, 22, 12, 0, 255, 31, 224, 32, 0, 39, 192, 100, 64, 167, + 192, 32, 0, 47, 224, 40, 32, 39, 192, 33, 0, 35, 0, 11, 11, 22, + 12, 0, 255, 243, 224, 130, 32, 130, 32, 250, 32, 130, 32, 130, 32, 138, + 32, 178, 32, 194, 224, 2, 0, 2, 0, 11, 11, 22, 12, 0, 255, 36, + 128, 70, 160, 149, 192, 228, 128, 39, 224, 68, 128, 245, 192, 6, 160, 52, + 128, 196, 128, 7, 224, 11, 11, 22, 12, 0, 255, 39, 192, 65, 0, 135, + 224, 224, 32, 34, 128, 69, 128, 242, 128, 15, 224, 48, 128, 193, 64, 2, + 32, 11, 11, 22, 12, 0, 255, 2, 0, 2, 0, 34, 0, 35, 192, 34, + 0, 34, 0, 34, 0, 34, 0, 34, 0, 34, 0, 255, 224, 9, 11, 22, + 12, 0, 255, 8, 0, 8, 0, 255, 128, 136, 128, 136, 128, 136, 128, 255, + 128, 136, 128, 136, 128, 136, 128, 255, 128, 11, 11, 22, 12, 0, 255, 33, + 0, 83, 160, 65, 0, 247, 224, 81, 0, 83, 192, 86, 64, 83, 192, 90, + 64, 83, 192, 66, 64, 11, 11, 22, 12, 0, 255, 127, 192, 4, 0, 4, + 0, 4, 0, 255, 224, 10, 0, 10, 0, 18, 0, 34, 32, 66, 32, 129, + 224, 11, 11, 22, 12, 0, 255, 17, 0, 33, 0, 47, 224, 97, 0, 163, + 128, 35, 128, 37, 64, 37, 64, 41, 32, 33, 0, 33, 0, 11, 11, 22, + 12, 0, 255, 247, 224, 148, 32, 244, 32, 151, 224, 148, 128, 244, 128, 151, + 224, 148, 128, 244, 160, 150, 96, 4, 32, 11, 11, 22, 12, 0, 255, 123, + 224, 148, 128, 4, 0, 127, 192, 4, 0, 255, 224, 1, 0, 255, 224, 33, + 0, 17, 0, 7, 0, 11, 11, 22, 12, 0, 255, 33, 0, 71, 192, 145, + 0, 47, 224, 96, 128, 175, 224, 32, 128, 36, 128, 34, 128, 32, 128, 35, + 128, 11, 11, 22, 12, 0, 255, 39, 192, 36, 64, 247, 192, 46, 224, 42, + 160, 62, 224, 225, 0, 47, 224, 35, 128, 37, 64, 105, 32, 11, 11, 22, + 12, 0, 255, 20, 0, 39, 224, 42, 0, 98, 0, 163, 192, 34, 0, 34, + 0, 35, 224, 34, 0, 34, 0, 34, 0 +}; diff --git a/trunk/Arduino/Marlin_1.1.6/dogm_font_data_ISO10646_CZ.h b/trunk/Arduino/Marlin_1.1.6/dogm_font_data_ISO10646_CZ.h new file mode 100644 index 00000000..671ad8ea --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/dogm_font_data_ISO10646_CZ.h @@ -0,0 +1,192 @@ +/* + Fontname: ISO10646_CZ + Copyright: A. Hardtung, public domain + Modified for Czech accents by Petr Zahradnik, http://www.zahradniksebavi.cz + Capital A Height: 7, '1' Height: 7 + Calculated Max Values w= 6 h= 9 x= 2 y= 7 dx= 6 dy= 0 ascent= 8 len= 9 + Font Bounding box w= 6 h= 9 x= 0 y=-2 + Calculated Min Values x= 0 y=-1 dx= 0 dy= 0 + Pure Font ascent = 7 descent=-1 + X Font ascent = 7 descent=-1 + Max Font ascent = 8 descent=-1 +*/ +#include +const u8g_fntpgm_uint8_t ISO10646_CZ[2832] U8G_SECTION(".progmem.ISO10646_CZ") = { + 0,6,9,0,254,7,1,146,3,33,32,255,255,8,255,7, + 255,0,0,0,6,0,0,1,7,7,6,2,0,128,128,128, + 128,128,0,128,3,2,2,6,1,5,160,160,5,7,7,6, + 0,0,80,80,248,80,248,80,80,5,7,7,6,0,0,32, + 120,160,112,40,240,32,5,7,7,6,0,0,192,200,16,32, + 64,152,24,5,7,7,6,0,0,96,144,160,64,168,144,104, + 2,3,3,6,1,4,192,64,128,3,7,7,6,1,0,32, + 64,128,128,128,64,32,3,7,7,6,1,0,128,64,32,32, + 32,64,128,5,5,5,6,0,1,32,168,112,168,32,5,5, + 5,6,0,1,32,32,248,32,32,2,3,3,6,2,255,192, + 64,128,5,1,1,6,0,3,248,2,2,2,6,2,0,192, + 192,5,5,5,6,0,1,8,16,32,64,128,5,7,7,6, + 0,0,112,136,136,136,136,136,112,3,7,7,6,1,0,64, + 192,64,64,64,64,224,5,7,7,6,0,0,112,136,8,112, + 128,128,248,5,7,7,6,0,0,248,16,32,16,8,8,240, + 5,7,7,6,0,0,16,48,80,144,248,16,16,5,7,7, + 6,0,0,248,128,240,8,8,136,112,5,7,7,6,0,0, + 112,128,128,240,136,136,112,5,7,7,6,0,0,248,8,16, + 32,32,32,32,5,7,7,6,0,0,112,136,136,112,136,136, + 112,5,7,7,6,0,0,112,136,136,120,8,8,112,2,5, + 5,6,2,0,192,192,0,192,192,2,6,6,6,2,255,192, + 192,0,192,64,128,4,7,7,6,0,0,16,32,64,128,64, + 32,16,5,3,3,6,0,2,248,0,248,4,7,7,6,1, + 0,128,64,32,16,32,64,128,5,7,7,6,0,0,112,136, + 8,16,32,0,32,5,7,7,6,0,0,112,136,8,104,168, + 168,112,5,7,7,6,0,0,112,136,136,248,136,136,136,5, + 7,7,6,0,0,240,136,136,240,136,136,240,5,7,7,6, + 0,0,112,136,128,128,128,136,112,5,7,7,6,0,0,240, + 136,136,136,136,136,240,5,7,7,6,0,0,248,128,128,240, + 128,128,248,5,7,7,6,0,0,248,128,128,240,128,128,128, + 5,7,7,6,0,0,112,136,128,184,136,136,112,5,7,7, + 6,0,0,136,136,136,248,136,136,136,1,7,7,6,2,0, + 128,128,128,128,128,128,128,5,7,7,6,0,0,56,16,16, + 16,16,144,96,5,7,7,6,0,0,136,144,160,192,160,144, + 136,5,7,7,6,0,0,128,128,128,128,128,128,248,5,7, + 7,6,0,0,136,216,168,136,136,136,136,5,7,7,6,0, + 0,136,136,200,168,152,136,136,5,7,7,6,0,0,112,136, + 136,136,136,136,112,5,7,7,6,0,0,240,136,136,240,128, + 128,128,5,7,7,6,0,0,112,136,136,136,168,144,104,5, + 7,7,6,0,0,240,136,136,240,160,144,136,5,7,7,6, + 0,0,120,128,128,112,8,8,240,5,7,7,6,0,0,248, + 32,32,32,32,32,32,5,7,7,6,0,0,136,136,136,136, + 136,136,112,5,7,7,6,0,0,136,136,136,136,136,80,32, + 5,7,7,6,0,0,136,136,136,136,136,168,80,5,7,7, + 6,0,0,136,136,80,32,80,136,136,5,7,7,6,0,0, + 136,136,136,80,32,32,32,5,7,7,6,0,0,248,8,16, + 32,64,128,248,3,7,7,6,1,0,224,128,128,128,128,128, + 224,5,5,5,6,0,1,128,64,32,16,8,3,7,7,6, + 1,0,224,32,32,32,32,32,224,5,3,3,6,0,4,32, + 80,136,5,1,1,6,0,0,248,2,2,2,6,2,5,128, + 64,5,5,5,6,0,0,112,8,120,136,120,5,7,7,6, + 0,0,128,128,176,200,136,136,240,5,5,5,6,0,0,112, + 128,128,136,112,5,7,7,6,0,0,8,8,104,152,136,136, + 120,5,5,5,6,0,0,112,136,248,128,112,5,7,7,6, + 0,0,48,72,224,64,64,64,64,5,6,6,6,0,255,112, + 136,136,120,8,112,5,7,7,6,0,0,128,128,176,200,136, + 136,136,1,7,7,6,2,0,128,0,128,128,128,128,128,3, + 8,8,6,1,255,32,0,32,32,32,32,160,64,4,7,7, + 6,0,0,128,128,144,160,192,160,144,3,7,7,6,1,0, + 192,64,64,64,64,64,224,5,5,5,6,0,0,208,168,168, + 168,168,5,5,5,6,0,0,176,200,136,136,136,5,5,5, + 6,0,0,112,136,136,136,112,5,6,6,6,0,255,240,136, + 136,240,128,128,5,6,6,6,0,255,120,136,136,120,8,8, + 5,5,5,6,0,0,176,200,128,128,128,5,5,5,6,0, + 0,112,128,112,8,240,4,7,7,6,0,0,64,64,224,64, + 64,64,48,5,5,5,6,0,0,136,136,136,152,104,5,5, + 5,6,0,0,136,136,136,80,32,5,5,5,6,0,0,136, + 136,168,168,80,5,5,5,6,0,0,136,80,32,80,136,5, + 6,6,6,0,255,136,136,136,120,8,112,5,5,5,6,0, + 0,248,16,32,64,248,3,7,7,6,1,0,32,64,64,128, + 64,64,32,1,7,7,6,2,0,128,128,128,128,128,128,128, + 3,7,7,6,1,0,128,64,64,32,64,64,128,5,2,2, + 6,0,2,104,144,0,0,0,6,0,0,5,8,8,6,0, + 0,16,32,112,136,136,248,136,136,5,8,8,6,0,0,8, + 16,248,128,128,240,128,248,3,8,8,6,1,0,32,64,224, + 64,64,64,64,224,5,8,8,6,0,0,16,32,112,136,136, + 136,136,112,5,8,8,6,0,0,16,32,136,136,136,136,136, + 112,5,8,8,6,0,0,16,32,136,136,80,32,32,32,5, + 8,8,6,0,0,16,32,0,112,8,120,136,120,5,8,8, + 6,0,0,16,32,0,112,136,248,128,112,2,8,8,6,2, + 0,64,128,0,128,128,128,128,128,5,8,8,6,0,0,16, + 32,0,112,136,136,136,112,5,8,8,6,0,0,16,32,0, + 136,136,136,152,104,5,9,9,6,0,255,16,32,0,136,136, + 136,120,8,112,5,8,8,6,0,0,80,32,112,136,128,128, + 136,112,5,8,8,6,0,0,80,32,0,112,128,128,136,112, + 5,8,8,6,0,0,80,32,240,136,136,136,136,240,6,8, + 8,6,0,0,4,20,24,112,144,144,144,112,5,8,8,6, + 0,0,80,32,248,128,128,240,128,248,5,8,8,6,0,0, + 80,32,0,112,136,248,128,112,5,8,8,6,0,0,80,32, + 136,200,168,152,136,136,5,8,8,6,0,0,80,32,0,176, + 200,136,136,136,5,8,8,6,0,0,80,32,240,136,240,160, + 144,136,5,8,8,6,0,0,80,32,0,176,200,128,128,128, + 5,8,8,6,0,0,80,32,120,128,128,112,8,240,5,8, + 8,6,0,0,80,32,0,112,128,112,8,240,5,8,8,6, + 0,0,80,32,248,32,32,32,32,32,6,8,8,6,0,0, + 4,68,72,224,64,64,64,48,5,8,8,6,0,0,32,80, + 168,136,136,136,136,112,5,8,8,6,0,0,32,80,32,136, + 136,136,152,104,5,8,8,6,0,0,80,32,248,8,48,64, + 128,248,5,8,8,6,0,0,80,32,0,248,16,32,64,248, + 0,0,0,6,0,0,0,0,0,6,0,0,0,0,0,6, + 0,0,1,7,7,6,2,0,128,0,128,128,128,128,128,5, + 7,7,6,0,0,32,112,168,160,168,112,32,5,7,7,6, + 0,0,48,64,64,224,64,80,168,5,5,5,6,0,0,136, + 112,80,112,136,5,7,7,6,0,0,136,80,32,248,32,248, + 32,1,7,7,6,2,0,128,128,128,0,128,128,128,5,8, + 8,6,0,0,48,72,32,80,80,32,144,96,3,1,1,6, + 1,7,160,5,7,7,6,0,0,248,136,184,184,184,136,248, + 5,7,7,6,0,1,112,8,120,136,120,0,248,5,5,5, + 6,0,1,40,80,160,80,40,5,3,3,6,0,1,248,8, + 8,2,2,2,6,2,6,64,128,5,7,7,6,0,0,248, + 136,168,136,152,168,248,5,1,1,6,0,6,248,4,4,4, + 6,0,3,96,144,144,96,5,7,7,6,0,0,32,32,248, + 32,32,0,248,4,5,5,6,0,3,96,144,32,64,240,3, + 5,5,6,0,3,224,32,224,32,224,2,2,2,6,2,6, + 64,128,5,8,8,6,0,255,136,136,136,136,152,232,128,128, + 5,7,7,6,0,0,120,152,152,120,24,24,24,2,2,2, + 6,2,2,192,192,2,2,2,6,2,255,64,128,3,5,5, + 6,0,3,64,192,64,64,224,5,7,7,6,0,1,112,136, + 136,136,112,0,248,5,5,5,6,0,1,160,80,40,80,160, + 5,7,7,6,0,0,136,144,168,88,184,8,8,5,7,7, + 6,0,0,136,144,184,72,152,32,56,5,8,8,6,0,0, + 192,64,192,72,216,56,8,8,5,7,7,6,0,0,32,0, + 32,64,128,136,112,5,8,8,6,0,0,64,32,0,112,136, + 248,136,136,5,8,8,6,0,0,16,32,0,112,136,248,136, + 136,5,8,8,6,0,0,32,80,0,112,136,248,136,136,5, + 8,8,6,0,0,104,144,0,112,136,248,136,136,5,8,8, + 6,0,0,80,0,112,136,136,248,136,136,5,8,8,6,0, + 0,32,80,32,112,136,248,136,136,5,7,7,6,0,0,56, + 96,160,184,224,160,184,5,8,8,6,0,255,112,136,128,128, + 136,112,32,96,5,8,8,6,0,0,64,32,0,248,128,240, + 128,248,5,8,8,6,0,0,8,16,0,248,128,240,128,248, + 5,8,8,6,0,0,32,80,0,248,128,240,128,248,5,7, + 7,6,0,0,80,0,248,128,240,128,248,3,8,8,6,1, + 0,128,64,0,224,64,64,64,224,3,8,8,6,1,0,32, + 64,0,224,64,64,64,224,3,8,8,6,1,0,64,160,0, + 224,64,64,64,224,3,7,7,6,1,0,160,0,224,64,64, + 64,224,5,9,9,6,0,255,80,32,112,136,128,184,136,136, + 112,5,8,8,6,0,0,104,144,0,136,200,168,152,136,5, + 8,8,6,0,0,64,32,112,136,136,136,136,112,5,8,8, + 6,0,0,16,32,112,136,136,136,136,112,5,8,8,6,0, + 0,32,80,0,112,136,136,136,112,5,8,8,6,0,0,104, + 144,0,112,136,136,136,112,5,8,8,6,0,0,80,0,112, + 136,136,136,136,112,5,5,5,6,0,1,136,80,32,80,136, + 5,8,8,6,0,255,16,112,168,168,168,168,112,64,5,8, + 8,6,0,0,64,32,136,136,136,136,136,112,5,8,8,6, + 0,0,16,32,136,136,136,136,136,112,5,8,8,6,0,0, + 32,80,0,136,136,136,136,112,5,8,8,6,0,0,80,0, + 136,136,136,136,136,112,1,7,7,6,2,0,128,0,128,128, + 128,128,128,5,9,9,6,0,255,120,128,128,112,8,8,240, + 32,96,4,8,8,6,1,255,96,144,144,160,144,144,224,128, + 5,8,8,6,0,0,64,32,0,112,8,120,136,120,5,8, + 8,6,0,0,16,32,0,112,8,120,136,120,5,8,8,6, + 0,0,32,80,0,112,8,120,136,120,5,8,8,6,0,0, + 104,144,0,112,8,120,136,120,5,7,7,6,0,0,80,0, + 112,8,120,136,120,5,8,8,6,0,0,32,80,32,112,8, + 120,136,120,5,6,6,6,0,0,208,40,120,160,168,80,5, + 7,7,6,0,255,112,128,128,136,112,32,96,5,8,8,6, + 0,0,64,32,0,112,136,248,128,112,5,8,8,6,0,0, + 16,32,0,112,136,248,128,112,5,8,8,6,0,0,32,80, + 0,112,136,248,128,112,5,7,7,6,0,0,80,0,112,136, + 248,128,112,3,8,8,6,1,0,128,64,0,64,192,64,64, + 224,3,8,8,6,1,0,32,64,0,64,192,64,64,224,3, + 8,8,6,1,0,64,160,0,64,192,64,64,224,3,7,7, + 6,1,0,160,0,64,192,64,64,224,5,8,8,6,0,255, + 80,32,112,136,136,120,8,112,5,8,8,6,0,0,104,144, + 0,176,200,136,136,136,5,8,8,6,0,0,64,32,0,112, + 136,136,136,112,5,8,8,6,0,0,16,32,0,112,136,136, + 136,112,5,8,8,6,0,0,32,80,0,112,136,136,136,112, + 5,8,8,6,0,0,104,144,0,112,136,136,136,112,5,7, + 7,6,0,0,80,0,112,136,136,136,112,5,5,5,6,0, + 1,32,0,248,0,32,5,7,7,6,0,255,16,112,168,168, + 168,112,64,5,8,8,6,0,0,64,32,0,136,136,136,152, + 104,5,8,8,6,0,0,16,32,0,136,136,136,152,104,5, + 8,8,6,0,0,32,80,0,136,136,136,152,104,5,7,7, + 6,0,0,80,0,136,136,136,152,104,1,5,5,6,2,0, + 128,128,128,128,128,5,7,7,6,0,255,112,128,112,8,240, + 32,96,5,8,8,6,0,255,80,0,136,136,136,120,8,112 + }; diff --git a/trunk/Arduino/Marlin_1.1.6/dogm_font_data_ISO10646_Greek.h b/trunk/Arduino/Marlin_1.1.6/dogm_font_data_ISO10646_Greek.h new file mode 100644 index 00000000..efe44f3c --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/dogm_font_data_ISO10646_Greek.h @@ -0,0 +1,205 @@ +/** + * 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 . + * + */ + +/* + Fontname: ISO10646_4_Greek + Copyright: A. Hardtung, public domain + Capital A Height: 7, '1' Height: 7 + Calculated Max Values w= 5 h= 9 x= 2 y= 6 dx= 6 dy= 0 ascent= 8 len= 9 + Font Bounding box w= 6 h= 9 x= 0 y=-2 + Calculated Min Values x= 0 y=-1 dx= 0 dy= 0 + Pure Font ascent = 7 descent=-1 + X Font ascent = 7 descent=-1 + Max Font ascent = 8 descent=-1 +*/ +#include +const u8g_fntpgm_uint8_t ISO10646_Greek_5x7[2715] U8G_SECTION(".progmem.ISO10646_Greek_5x7") = { + 0,6,9,0,254,7,1,145,3,32,32,255,255,8,255,7, + 255,0,0,0,6,0,0,1,7,7,6,2,0,128,128,128, + 128,128,0,128,3,2,2,6,1,5,160,160,5,7,7,6, + 0,0,80,80,248,80,248,80,80,5,7,7,6,0,0,32, + 120,160,112,40,240,32,5,7,7,6,0,0,192,200,16,32, + 64,152,24,5,7,7,6,0,0,96,144,160,64,168,144,104, + 2,3,3,6,1,4,192,64,128,3,7,7,6,1,0,32, + 64,128,128,128,64,32,3,7,7,6,1,0,128,64,32,32, + 32,64,128,5,5,5,6,0,1,32,168,112,168,32,5,5, + 5,6,0,1,32,32,248,32,32,2,3,3,6,2,255,192, + 64,128,5,1,1,6,0,3,248,2,2,2,6,2,0,192, + 192,5,5,5,6,0,1,8,16,32,64,128,5,7,7,6, + 0,0,112,136,152,168,200,136,112,3,7,7,6,1,0,64, + 192,64,64,64,64,224,5,7,7,6,0,0,112,136,8,112, + 128,128,248,5,7,7,6,0,0,248,16,32,16,8,8,240, + 5,7,7,6,0,0,16,48,80,144,248,16,16,5,7,7, + 6,0,0,248,128,240,8,8,136,112,5,7,7,6,0,0, + 48,64,128,240,136,136,112,5,7,7,6,0,0,248,8,16, + 32,32,32,32,5,7,7,6,0,0,112,136,136,112,136,136, + 112,5,7,7,6,0,0,112,136,136,120,8,16,96,2,5, + 5,6,2,0,192,192,0,192,192,2,6,6,6,2,255,192, + 192,0,192,64,128,4,7,7,6,0,0,16,32,64,128,64, + 32,16,5,3,3,6,0,2,248,0,248,4,7,7,6,1, + 0,128,64,32,16,32,64,128,5,7,7,6,0,0,112,136, + 8,16,32,0,32,5,6,6,6,0,0,112,136,8,104,168, + 112,5,7,7,6,0,0,112,136,136,248,136,136,136,5,7, + 7,6,0,0,240,136,136,240,136,136,240,5,7,7,6,0, + 0,112,136,128,128,128,136,112,5,7,7,6,0,0,224,144, + 136,136,136,144,224,5,7,7,6,0,0,248,128,128,240,128, + 128,248,5,7,7,6,0,0,248,128,128,240,128,128,128,5, + 7,7,6,0,0,112,136,128,184,136,136,112,5,7,7,6, + 0,0,136,136,136,248,136,136,136,1,7,7,6,2,0,128, + 128,128,128,128,128,128,5,7,7,6,0,0,56,16,16,16, + 16,144,96,5,7,7,6,0,0,136,144,160,192,160,144,136, + 5,7,7,6,0,0,128,128,128,128,128,128,248,5,7,7, + 6,0,0,136,216,168,136,136,136,136,5,7,7,6,0,0, + 136,136,200,168,152,136,136,5,7,7,6,0,0,112,136,136, + 136,136,136,112,5,7,7,6,0,0,240,136,136,240,128,128, + 128,5,7,7,6,0,0,112,136,136,136,168,144,104,5,7, + 7,6,0,0,240,136,136,240,160,144,136,5,7,7,6,0, + 0,120,128,128,112,8,8,240,5,7,7,6,0,0,248,32, + 32,32,32,32,32,5,7,7,6,0,0,136,136,136,136,136, + 136,112,5,7,7,6,0,0,136,136,136,136,136,80,32,5, + 7,7,6,0,0,136,136,136,136,136,168,80,5,7,7,6, + 0,0,136,136,80,32,80,136,136,5,7,7,6,0,0,136, + 136,136,80,32,32,32,5,7,7,6,0,0,248,8,16,32, + 64,128,248,3,7,7,6,1,0,224,128,128,128,128,128,224, + 5,5,5,6,0,1,128,64,32,16,8,3,7,7,6,1, + 0,224,32,32,32,32,32,224,5,3,3,6,0,4,32,80, + 136,5,1,1,6,0,0,248,2,2,2,6,2,5,128,64, + 5,5,5,6,0,0,112,8,120,136,120,5,7,7,6,0, + 0,128,128,176,200,136,136,240,5,5,5,6,0,0,112,128, + 128,136,112,5,7,7,6,0,0,8,8,104,152,136,136,120, + 5,5,5,6,0,0,112,136,248,128,112,5,7,7,6,0, + 0,48,72,224,64,64,64,64,5,6,6,6,0,255,112,136, + 136,120,8,112,5,7,7,6,0,0,128,128,176,200,136,136, + 136,1,7,7,6,2,0,128,0,128,128,128,128,128,3,8, + 8,6,1,255,32,0,32,32,32,32,160,64,4,7,7,6, + 0,0,128,128,144,160,192,160,144,3,7,7,6,1,0,192, + 64,64,64,64,64,224,5,5,5,6,0,0,208,168,168,168, + 168,5,5,5,6,0,0,176,200,136,136,136,5,5,5,6, + 0,0,112,136,136,136,112,5,6,6,6,0,255,240,136,136, + 240,128,128,5,6,6,6,0,255,120,136,136,120,8,8,5, + 5,5,6,0,0,176,200,128,128,128,5,5,5,6,0,0, + 112,128,112,8,240,5,7,7,6,0,0,64,64,224,64,64, + 72,48,5,5,5,6,0,0,136,136,136,152,104,5,5,5, + 6,0,0,136,136,136,80,32,5,5,5,6,0,0,136,136, + 168,168,80,5,5,5,6,0,0,136,80,32,80,136,5,6, + 6,6,0,255,136,136,136,120,8,112,5,5,5,6,0,0, + 248,16,32,64,248,3,7,7,6,1,0,32,64,64,128,64, + 64,32,1,7,7,6,2,0,128,128,128,128,128,128,128,3, + 7,7,6,1,0,128,64,64,32,64,64,128,5,2,2,6, + 0,3,104,144,0,0,0,6,0,0,0,0,0,6,0,0, + 0,0,0,6,0,0,0,0,0,6,0,0,0,0,0,6, + 0,0,2,2,2,6,1,6,64,128,3,3,3,6,1,5, + 32,64,160,5,8,8,6,0,0,64,160,80,80,136,248,136, + 136,2,2,2,6,1,2,192,192,5,8,8,6,0,0,64, + 128,248,128,240,128,128,248,5,8,8,6,0,0,64,128,136, + 136,248,136,136,136,4,8,8,6,0,0,64,128,112,32,32, + 32,32,112,0,0,0,6,0,0,5,8,8,6,0,0,64, + 128,112,136,136,136,136,112,0,0,0,6,0,0,5,8,8, + 6,0,0,64,128,8,136,112,32,32,32,5,8,8,6,0, + 0,64,128,112,136,136,136,80,216,3,8,8,6,1,0,32, + 64,160,0,64,64,64,32,5,7,7,6,0,0,32,80,136, + 136,248,136,136,5,7,7,6,0,0,240,72,72,112,72,72, + 240,5,7,7,6,0,0,248,128,128,128,128,128,128,5,6, + 6,6,0,0,32,80,80,136,136,248,5,7,7,6,0,0, + 248,128,128,240,128,128,248,5,7,7,6,0,0,248,8,16, + 32,64,128,248,5,7,7,6,0,0,136,136,136,248,136,136, + 136,5,7,7,6,0,0,112,136,136,168,136,136,112,3,7, + 7,6,1,0,224,64,64,64,64,64,224,5,7,7,6,0, + 0,136,144,160,192,160,144,136,5,7,7,6,0,0,32,80, + 136,136,136,136,136,5,7,7,6,0,0,136,216,168,168,136, + 136,136,5,7,7,6,0,0,136,200,200,168,152,152,136,5, + 7,7,6,0,0,248,0,0,112,0,0,248,5,7,7,6, + 0,0,112,136,136,136,136,136,112,5,7,7,6,0,0,248, + 80,80,80,80,80,80,5,7,7,6,0,0,240,136,136,240, + 128,128,128,0,0,0,6,0,0,5,7,7,6,0,0,248, + 128,64,32,64,128,248,5,7,7,6,0,0,248,32,32,32, + 32,32,32,5,7,7,6,0,0,136,136,80,32,32,32,32, + 5,7,7,6,0,0,112,32,112,168,112,32,112,5,7,7, + 6,0,0,136,136,80,32,80,136,136,5,7,7,6,0,0, + 168,168,168,168,112,32,32,5,6,6,6,0,0,112,136,136, + 80,80,216,3,8,8,6,1,0,160,0,224,64,64,64,64, + 224,5,8,8,6,0,0,80,0,136,136,136,80,32,32,5, + 8,8,6,0,0,32,64,8,104,152,144,144,104,5,8,8, + 6,0,0,32,64,0,112,136,224,136,112,5,9,9,6,0, + 255,32,64,0,112,136,136,136,136,8,2,8,8,6,1,0, + 64,128,0,128,128,128,128,64,5,8,8,6,0,0,16,32, + 80,0,136,136,136,112,5,6,6,6,0,0,8,104,152,144, + 144,104,4,6,6,6,0,255,96,144,240,144,224,128,5,6, + 6,6,0,255,136,72,80,32,32,64,5,6,6,6,0,0, + 48,64,112,136,136,112,5,5,5,6,0,0,112,136,224,136, + 112,5,8,8,6,0,255,128,112,64,128,128,112,8,112,5, + 6,6,6,0,255,184,200,136,136,136,8,5,5,5,6,0, + 0,112,136,248,136,112,3,5,5,6,1,0,128,128,128,128, + 96,4,5,5,6,0,0,144,160,192,160,144,5,6,6,6, + 0,0,64,32,32,80,80,136,5,6,6,6,0,255,136,136, + 136,216,168,128,5,5,5,6,0,0,136,136,80,96,32,5, + 9,9,6,0,255,128,224,128,112,32,64,240,8,112,5,5, + 5,6,0,0,112,136,136,136,112,5,5,5,6,0,0,248, + 80,80,80,80,5,6,6,6,0,255,112,136,136,200,176,128, + 5,7,7,6,0,255,48,64,128,64,48,8,112,5,5,5, + 6,0,0,104,144,144,144,96,4,5,5,6,0,0,240,64, + 64,64,48,5,5,5,6,0,0,136,136,144,144,224,5,7, + 7,6,0,255,32,168,168,168,112,32,32,5,6,6,6,0, + 255,136,80,32,32,80,136,5,6,6,6,0,255,168,168,168, + 168,112,32,5,5,5,6,0,0,80,136,136,168,112,4,7, + 7,6,0,0,160,0,64,64,64,64,48,5,7,7,6,0, + 0,80,0,136,136,144,144,224,4,8,8,6,0,0,32,64, + 0,96,144,144,144,96,5,8,8,6,0,0,32,64,0,136, + 136,144,144,96,5,8,8,6,0,0,32,64,0,80,136,136, + 168,112,5,7,7,6,0,255,144,160,192,160,144,136,16,5, + 8,8,6,0,0,96,144,160,128,240,136,136,112,5,7,7, + 6,0,0,112,80,56,144,144,144,96,5,6,6,6,0,0, + 152,80,32,32,32,32,5,8,8,6,0,0,64,128,152,80, + 32,32,32,32,5,8,8,6,0,0,80,0,152,80,32,32, + 32,32,5,7,7,6,0,255,48,168,168,168,168,112,32,5, + 5,5,6,0,0,248,80,80,80,88,5,6,6,6,0,255, + 136,80,112,80,136,16,5,7,7,6,0,255,112,136,136,136, + 112,32,112,5,6,6,6,0,255,112,136,136,112,32,112,5, + 6,6,6,0,0,112,136,128,112,32,112,5,7,7,6,0, + 255,8,8,112,128,112,16,96,5,6,6,6,0,0,248,128, + 128,240,128,128,4,5,5,6,0,0,240,128,224,128,128,5, + 6,6,6,0,0,248,0,0,112,0,248,4,5,5,6,0, + 0,64,128,240,16,32,5,7,7,6,0,0,224,80,40,40, + 8,8,16,5,7,7,6,0,0,192,32,80,40,8,8,8, + 5,7,7,6,0,255,168,168,168,168,88,8,112,5,6,6, + 6,0,255,168,168,168,88,8,112,5,6,6,6,0,0,104, + 136,136,120,8,8,5,6,6,6,0,255,104,136,136,120,8, + 8,4,8,8,6,0,255,128,224,144,144,144,144,32,192,5, + 5,5,6,0,0,104,144,112,16,224,5,6,6,6,0,0, + 96,144,16,96,136,112,4,6,6,6,0,0,96,144,16,96, + 128,112,5,6,6,6,0,0,136,80,32,80,136,248,5,5, + 5,6,0,0,136,80,32,80,112,5,6,6,6,0,0,120, + 128,240,136,136,112,4,5,5,6,0,0,240,128,224,144,96, + 3,6,6,6,1,0,64,224,64,64,64,64,3,6,6,6, + 1,255,64,224,64,64,64,128,5,5,5,6,0,0,136,80, + 112,80,136,5,6,6,6,0,255,112,136,136,240,128,112,4, + 5,5,6,0,0,112,128,128,128,112,2,8,8,6,1,255, + 64,0,192,64,64,64,64,128,5,7,7,6,0,0,112,136, + 136,248,136,136,112,4,5,5,6,0,0,112,128,224,128,112, + 4,5,5,6,0,0,224,16,112,16,224,5,7,7,6,0, + 0,128,240,136,136,136,240,128,4,7,7,6,0,255,128,224, + 144,144,144,224,128,5,6,6,6,0,0,112,136,128,128,136, + 112,5,6,6,6,0,0,136,216,168,136,136,136,5,6,6, + 6,0,255,136,216,168,136,136,128,5,8,8,6,0,255,112, + 136,136,136,112,64,224,64,5,6,6,6,0,0,112,136,8, + 8,136,112,5,6,6,6,0,0,112,136,160,128,136,112,5, + 6,6,6,0,0,112,136,40,8,136,112}; diff --git a/trunk/Arduino/Marlin_1.1.6/dogm_font_data_ISO10646_Kana.h b/trunk/Arduino/Marlin_1.1.6/dogm_font_data_ISO10646_Kana.h new file mode 100644 index 00000000..69683740 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/dogm_font_data_ISO10646_Kana.h @@ -0,0 +1,192 @@ +/** + * 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 . + * + */ + +/** + Fontname: ISO10646_Kana + Copyright: A. Hardtung, public domain + Capital A Height: 7, '1' Height: 7 + Calculated Max Values w= 5 h= 8 x= 2 y= 5 dx= 6 dy= 0 ascent= 8 len= 8 + Font Bounding box w= 6 h= 9 x= 0 y=-2 + Calculated Min Values x= 0 y=-1 dx= 0 dy= 0 + Pure Font ascent = 7 descent=-1 + X Font ascent = 7 descent=-1 + Max Font ascent = 8 descent=-1 +*/ +#include +const u8g_fntpgm_uint8_t ISO10646_Kana_5x7[2482] U8G_SECTION(".progmem.ISO10646_Kana_5x7") = { + 0, 6, 9, 0, 254, 7, 1, 145, 3, 32, 32, 255, 255, 8, 255, 7, + 255, 0, 0, 0, 6, 0, 0, 1, 7, 7, 6, 2, 0, 128, 128, 128, + 128, 128, 0, 128, 3, 2, 2, 6, 1, 5, 160, 160, 5, 7, 7, 6, + 0, 0, 80, 80, 248, 80, 248, 80, 80, 5, 7, 7, 6, 0, 0, 32, + 120, 160, 112, 40, 240, 32, 5, 7, 7, 6, 0, 0, 192, 200, 16, 32, + 64, 152, 24, 5, 7, 7, 6, 0, 0, 96, 144, 160, 64, 168, 144, 104, + 2, 3, 3, 6, 1, 4, 192, 64, 128, 3, 7, 7, 6, 1, 0, 32, + 64, 128, 128, 128, 64, 32, 3, 7, 7, 6, 1, 0, 128, 64, 32, 32, + 32, 64, 128, 5, 5, 5, 6, 0, 1, 32, 168, 112, 168, 32, 5, 5, + 5, 6, 0, 1, 32, 32, 248, 32, 32, 2, 3, 3, 6, 2, 255, 192, + 64, 128, 5, 1, 1, 6, 0, 3, 248, 2, 2, 2, 6, 2, 0, 192, + 192, 5, 5, 5, 6, 0, 1, 8, 16, 32, 64, 128, 5, 7, 7, 6, + 0, 0, 112, 136, 152, 168, 200, 136, 112, 3, 7, 7, 6, 1, 0, 64, + 192, 64, 64, 64, 64, 224, 5, 7, 7, 6, 0, 0, 112, 136, 8, 112, + 128, 128, 248, 5, 7, 7, 6, 0, 0, 248, 16, 32, 16, 8, 8, 240, + 5, 7, 7, 6, 0, 0, 16, 48, 80, 144, 248, 16, 16, 5, 7, 7, + 6, 0, 0, 248, 128, 240, 8, 8, 136, 112, 5, 7, 7, 6, 0, 0, + 48, 64, 128, 240, 136, 136, 112, 5, 7, 7, 6, 0, 0, 248, 8, 16, + 32, 32, 32, 32, 5, 7, 7, 6, 0, 0, 112, 136, 136, 112, 136, 136, + 112, 5, 7, 7, 6, 0, 0, 112, 136, 136, 120, 8, 16, 96, 2, 5, + 5, 6, 2, 0, 192, 192, 0, 192, 192, 2, 6, 6, 6, 2, 255, 192, + 192, 0, 192, 64, 128, 4, 7, 7, 6, 0, 0, 16, 32, 64, 128, 64, + 32, 16, 5, 3, 3, 6, 0, 2, 248, 0, 248, 4, 7, 7, 6, 1, + 0, 128, 64, 32, 16, 32, 64, 128, 5, 7, 7, 6, 0, 0, 112, 136, + 8, 16, 32, 0, 32, 5, 6, 6, 6, 0, 0, 112, 136, 8, 104, 168, + 112, 5, 7, 7, 6, 0, 0, 112, 136, 136, 248, 136, 136, 136, 5, 7, + 7, 6, 0, 0, 240, 136, 136, 240, 136, 136, 240, 5, 7, 7, 6, 0, + 0, 112, 136, 128, 128, 128, 136, 112, 5, 7, 7, 6, 0, 0, 224, 144, + 136, 136, 136, 144, 224, 5, 7, 7, 6, 0, 0, 248, 128, 128, 240, 128, + 128, 248, 5, 7, 7, 6, 0, 0, 248, 128, 128, 240, 128, 128, 128, 5, + 7, 7, 6, 0, 0, 112, 136, 128, 184, 136, 136, 112, 5, 7, 7, 6, + 0, 0, 136, 136, 136, 248, 136, 136, 136, 1, 7, 7, 6, 2, 0, 128, + 128, 128, 128, 128, 128, 128, 5, 7, 7, 6, 0, 0, 56, 16, 16, 16, + 16, 144, 96, 5, 7, 7, 6, 0, 0, 136, 144, 160, 192, 160, 144, 136, + 5, 7, 7, 6, 0, 0, 128, 128, 128, 128, 128, 128, 248, 5, 7, 7, + 6, 0, 0, 136, 216, 168, 136, 136, 136, 136, 5, 7, 7, 6, 0, 0, + 136, 136, 200, 168, 152, 136, 136, 5, 7, 7, 6, 0, 0, 112, 136, 136, + 136, 136, 136, 112, 5, 7, 7, 6, 0, 0, 240, 136, 136, 240, 128, 128, + 128, 5, 7, 7, 6, 0, 0, 112, 136, 136, 136, 168, 144, 104, 5, 7, + 7, 6, 0, 0, 240, 136, 136, 240, 160, 144, 136, 5, 7, 7, 6, 0, + 0, 120, 128, 128, 112, 8, 8, 240, 5, 7, 7, 6, 0, 0, 248, 32, + 32, 32, 32, 32, 32, 5, 7, 7, 6, 0, 0, 136, 136, 136, 136, 136, + 136, 112, 5, 7, 7, 6, 0, 0, 136, 136, 136, 136, 136, 80, 32, 5, + 7, 7, 6, 0, 0, 136, 136, 136, 136, 136, 168, 80, 5, 7, 7, 6, + 0, 0, 136, 136, 80, 32, 80, 136, 136, 5, 7, 7, 6, 0, 0, 136, + 136, 136, 80, 32, 32, 32, 5, 7, 7, 6, 0, 0, 248, 8, 16, 32, + 64, 128, 248, 3, 7, 7, 6, 1, 0, 224, 128, 128, 128, 128, 128, 224, + 5, 5, 5, 6, 0, 1, 128, 64, 32, 16, 8, 3, 7, 7, 6, 1, + 0, 224, 32, 32, 32, 32, 32, 224, 5, 3, 3, 6, 0, 4, 32, 80, + 136, 5, 1, 1, 6, 0, 0, 248, 2, 2, 2, 6, 2, 5, 128, 64, + 5, 5, 5, 6, 0, 0, 112, 8, 120, 136, 120, 5, 7, 7, 6, 0, + 0, 128, 128, 176, 200, 136, 136, 240, 5, 5, 5, 6, 0, 0, 112, 128, + 128, 136, 112, 5, 7, 7, 6, 0, 0, 8, 8, 104, 152, 136, 136, 120, + 5, 5, 5, 6, 0, 0, 112, 136, 248, 128, 112, 5, 7, 7, 6, 0, + 0, 48, 72, 224, 64, 64, 64, 64, 5, 6, 6, 6, 0, 255, 112, 136, + 136, 120, 8, 112, 5, 7, 7, 6, 0, 0, 128, 128, 176, 200, 136, 136, + 136, 1, 7, 7, 6, 2, 0, 128, 0, 128, 128, 128, 128, 128, 3, 8, + 8, 6, 1, 255, 32, 0, 32, 32, 32, 32, 160, 64, 4, 7, 7, 6, + 0, 0, 128, 128, 144, 160, 192, 160, 144, 3, 7, 7, 6, 1, 0, 192, + 64, 64, 64, 64, 64, 224, 5, 5, 5, 6, 0, 0, 208, 168, 168, 168, + 168, 5, 5, 5, 6, 0, 0, 176, 200, 136, 136, 136, 5, 5, 5, 6, + 0, 0, 112, 136, 136, 136, 112, 5, 6, 6, 6, 0, 255, 240, 136, 136, + 240, 128, 128, 5, 6, 6, 6, 0, 255, 120, 136, 136, 120, 8, 8, 5, + 5, 5, 6, 0, 0, 176, 200, 128, 128, 128, 5, 5, 5, 6, 0, 0, + 112, 128, 112, 8, 240, 5, 7, 7, 6, 0, 0, 64, 64, 224, 64, 64, + 72, 48, 5, 5, 5, 6, 0, 0, 136, 136, 136, 152, 104, 5, 5, 5, + 6, 0, 0, 136, 136, 136, 80, 32, 5, 5, 5, 6, 0, 0, 136, 136, + 168, 168, 80, 5, 5, 5, 6, 0, 0, 136, 80, 32, 80, 136, 5, 6, + 6, 6, 0, 255, 136, 136, 136, 120, 8, 112, 5, 5, 5, 6, 0, 0, + 248, 16, 32, 64, 248, 3, 7, 7, 6, 1, 0, 32, 64, 64, 128, 64, + 64, 32, 1, 7, 7, 6, 2, 0, 128, 128, 128, 128, 128, 128, 128, 3, + 7, 7, 6, 1, 0, 128, 64, 64, 32, 64, 64, 128, 5, 2, 2, 6, + 0, 3, 104, 144, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, + 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, + 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, + 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, + 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, + 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, + 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, + 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, + 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, + 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, + 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, + 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, + 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 5, 3, 3, 6, 0, 1, + 248, 0, 248, 4, 4, 4, 6, 0, 0, 240, 16, 96, 64, 5, 6, 6, + 6, 0, 0, 248, 8, 40, 48, 32, 64, 3, 4, 4, 6, 1, 0, 32, + 64, 192, 64, 4, 6, 6, 6, 0, 0, 16, 32, 96, 160, 32, 32, 4, + 4, 4, 6, 0, 0, 32, 240, 144, 32, 5, 6, 6, 6, 0, 0, 32, + 248, 136, 8, 16, 32, 3, 4, 4, 6, 1, 0, 224, 64, 64, 224, 5, + 5, 5, 6, 0, 0, 248, 32, 32, 32, 248, 4, 4, 4, 6, 0, 0, + 32, 240, 96, 160, 5, 6, 6, 6, 0, 0, 16, 248, 48, 80, 144, 16, + 5, 6, 6, 6, 0, 0, 64, 248, 72, 72, 72, 144, 5, 8, 8, 6, + 0, 0, 40, 0, 64, 248, 72, 72, 72, 144, 5, 6, 6, 6, 0, 0, + 32, 248, 32, 248, 32, 32, 5, 8, 8, 6, 0, 0, 40, 0, 32, 248, + 32, 248, 32, 32, 4, 5, 5, 6, 0, 0, 112, 144, 16, 32, 192, 5, + 7, 7, 6, 0, 0, 40, 0, 112, 144, 16, 32, 192, 5, 6, 6, 6, + 0, 0, 64, 120, 144, 16, 16, 32, 5, 8, 8, 6, 0, 0, 40, 0, + 64, 120, 144, 16, 16, 32, 5, 5, 5, 6, 0, 0, 248, 8, 8, 8, + 248, 5, 7, 7, 6, 0, 0, 40, 0, 248, 8, 8, 8, 248, 5, 6, + 6, 6, 0, 0, 80, 248, 80, 16, 32, 64, 5, 8, 8, 6, 0, 0, + 40, 0, 80, 248, 80, 16, 32, 64, 5, 5, 5, 6, 0, 0, 192, 8, + 200, 16, 224, 5, 7, 7, 6, 0, 0, 40, 0, 192, 8, 200, 16, 224, + 5, 5, 5, 6, 0, 0, 248, 16, 32, 80, 136, 5, 7, 7, 6, 0, + 0, 40, 0, 248, 16, 32, 80, 136, 5, 6, 6, 6, 0, 0, 64, 248, + 72, 80, 64, 56, 5, 8, 8, 6, 0, 0, 40, 0, 64, 248, 72, 80, + 64, 56, 5, 5, 5, 6, 0, 0, 136, 136, 72, 16, 96, 5, 7, 7, + 6, 0, 0, 40, 0, 136, 136, 72, 16, 96, 5, 5, 5, 6, 0, 0, + 120, 72, 168, 16, 96, 5, 7, 7, 6, 0, 0, 40, 0, 120, 72, 168, + 16, 96, 5, 6, 6, 6, 0, 0, 16, 224, 32, 248, 32, 64, 5, 8, + 8, 6, 0, 0, 40, 0, 16, 224, 32, 248, 32, 64, 5, 4, 4, 6, + 0, 0, 168, 168, 8, 48, 5, 5, 5, 6, 0, 0, 168, 168, 8, 16, + 32, 5, 7, 7, 6, 0, 0, 40, 0, 168, 168, 8, 16, 32, 5, 6, + 6, 6, 0, 0, 112, 0, 248, 32, 32, 64, 5, 8, 8, 6, 0, 0, + 40, 0, 112, 0, 248, 32, 32, 64, 3, 6, 6, 6, 1, 0, 128, 128, + 192, 160, 128, 128, 4, 8, 8, 6, 1, 0, 80, 0, 128, 128, 192, 160, + 128, 128, 5, 6, 6, 6, 0, 0, 32, 248, 32, 32, 64, 128, 5, 5, + 5, 6, 0, 0, 112, 0, 0, 0, 248, 5, 5, 5, 6, 0, 0, 248, + 8, 80, 32, 208, 5, 6, 6, 6, 0, 0, 32, 248, 16, 32, 112, 168, + 3, 6, 6, 6, 1, 0, 32, 32, 32, 32, 64, 128, 5, 5, 5, 6, + 0, 0, 16, 136, 136, 136, 136, 5, 7, 7, 6, 0, 0, 40, 0, 16, + 136, 136, 136, 136, 5, 8, 8, 6, 0, 0, 24, 24, 0, 16, 136, 136, + 136, 136, 5, 6, 6, 6, 0, 0, 128, 128, 248, 128, 128, 120, 5, 7, + 7, 6, 0, 0, 40, 128, 128, 248, 128, 128, 120, 5, 7, 7, 6, 0, + 0, 24, 152, 128, 248, 128, 128, 120, 5, 5, 5, 6, 0, 0, 248, 8, + 8, 16, 96, 5, 7, 7, 6, 0, 0, 40, 0, 248, 8, 8, 16, 96, + 5, 8, 8, 6, 0, 0, 24, 24, 0, 248, 8, 8, 16, 96, 5, 4, + 4, 6, 0, 1, 64, 160, 16, 8, 5, 6, 6, 6, 0, 1, 40, 0, + 64, 160, 16, 8, 5, 6, 6, 6, 0, 1, 24, 24, 64, 160, 16, 8, + 5, 6, 6, 6, 0, 0, 32, 248, 32, 168, 168, 32, 5, 8, 8, 6, + 0, 0, 40, 0, 32, 248, 32, 168, 168, 32, 5, 8, 8, 6, 0, 0, + 24, 24, 32, 248, 32, 168, 168, 32, 5, 5, 5, 6, 0, 0, 248, 8, + 80, 32, 16, 4, 5, 5, 6, 1, 0, 224, 0, 224, 0, 240, 5, 5, + 5, 6, 0, 0, 32, 64, 136, 248, 8, 5, 5, 5, 6, 0, 0, 8, + 40, 16, 40, 192, 5, 5, 5, 6, 0, 0, 248, 64, 248, 64, 56, 5, + 4, 4, 6, 0, 0, 64, 248, 80, 64, 5, 6, 6, 6, 0, 0, 64, + 248, 72, 80, 64, 64, 4, 4, 4, 6, 0, 0, 96, 32, 32, 240, 5, + 5, 5, 6, 0, 0, 112, 16, 16, 16, 248, 4, 5, 5, 6, 0, 0, + 240, 16, 240, 16, 240, 5, 5, 5, 6, 0, 0, 248, 8, 248, 8, 248, + 5, 6, 6, 6, 0, 0, 112, 0, 248, 8, 16, 32, 4, 6, 6, 6, + 0, 0, 144, 144, 144, 144, 16, 32, 5, 5, 5, 6, 0, 0, 32, 160, + 168, 168, 176, 4, 5, 5, 6, 0, 0, 128, 128, 144, 160, 192, 5, 5, + 5, 6, 0, 0, 248, 136, 136, 136, 248, 4, 4, 4, 6, 0, 0, 240, + 144, 16, 32, 5, 5, 5, 6, 0, 0, 248, 136, 8, 16, 32, 5, 6, + 6, 6, 0, 0, 16, 248, 80, 80, 248, 16, 5, 5, 5, 6, 0, 0, + 248, 8, 48, 32, 248, 5, 5, 5, 6, 0, 0, 248, 8, 248, 8, 48, + 5, 5, 5, 6, 0, 0, 192, 8, 8, 16, 224, 5, 8, 8, 6, 0, + 0, 40, 0, 32, 248, 136, 8, 16, 32, 4, 4, 4, 6, 0, 0, 64, + 240, 80, 160, 4, 4, 4, 6, 0, 0, 64, 240, 32, 64, 5, 7, 7, + 6, 0, 0, 40, 0, 248, 136, 8, 16, 96, 5, 8, 8, 6, 0, 0, + 40, 0, 16, 248, 80, 80, 248, 16, 5, 7, 7, 6, 0, 0, 40, 0, + 248, 8, 48, 32, 248, 5, 7, 7, 6, 0, 0, 40, 0, 248, 8, 248, + 8, 48, 2, 2, 2, 6, 2, 2, 192, 192, 5, 1, 1, 6, 0, 2, + 248, 5, 4, 4, 6, 0, 1, 128, 96, 16, 8, 5, 5, 5, 6, 0, + 1, 40, 128, 96, 16, 8, 5, 6, 6, 6, 0, 0, 248, 8, 8, 8, + 8, 8 +}; diff --git a/trunk/Arduino/Marlin_1.1.6/dogm_font_data_ISO10646_SK.h b/trunk/Arduino/Marlin_1.1.6/dogm_font_data_ISO10646_SK.h new file mode 100644 index 00000000..7a460858 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/dogm_font_data_ISO10646_SK.h @@ -0,0 +1,151 @@ +/* + Fontname: ISO10646_SK + Copyright: A. Hardtung, modified by Roman Moravcik + Capital A Height: 7, '1' Height: 7 + Calculated Max Values w= 6 h= 9 x= 2 y= 7 dx= 6 dy= 0 ascent= 8 len= 9 + Font Bounding box w= 6 h= 9 x= 0 y=-2 + Calculated Min Values x= 0 y=-1 dx= 0 dy= 0 + Pure Font ascent = 7 descent=-1 + X Font ascent = 7 descent=-1 + Max Font ascent = 8 descent=-1 +*/ +#include +const u8g_fntpgm_uint8_t ISO10646_SK[2203] U8G_SECTION(".progmem.ISO10646_SK") = { + 0,6,9,0,254,7,1,146,3,33,32,255,255,8,255,7, + 255,0,0,0,6,0,0,1,7,7,6,2,0,128,128,128, + 128,128,0,128,3,2,2,6,1,5,160,160,5,7,7,6, + 0,0,80,80,248,80,248,80,80,5,7,7,6,0,0,32, + 120,160,112,40,240,32,5,7,7,6,0,0,192,200,16,32, + 64,152,24,5,7,7,6,0,0,96,144,160,64,168,144,104, + 2,3,3,6,1,4,192,64,128,3,7,7,6,1,0,32, + 64,128,128,128,64,32,3,7,7,6,1,0,128,64,32,32, + 32,64,128,5,5,5,6,0,1,32,168,112,168,32,5,5, + 5,6,0,1,32,32,248,32,32,2,3,3,6,2,255,192, + 64,128,5,1,1,6,0,3,248,2,2,2,6,2,0,192, + 192,5,5,5,6,0,1,8,16,32,64,128,5,7,7,6, + 0,0,112,136,136,136,136,136,112,3,7,7,6,1,0,64, + 192,64,64,64,64,224,5,7,7,6,0,0,112,136,8,112, + 128,128,248,5,7,7,6,0,0,248,16,32,16,8,8,240, + 5,7,7,6,0,0,16,48,80,144,248,16,16,5,7,7, + 6,0,0,248,128,240,8,8,136,112,5,7,7,6,0,0, + 112,128,128,240,136,136,112,5,7,7,6,0,0,248,8,16, + 32,32,32,32,5,7,7,6,0,0,112,136,136,112,136,136, + 112,5,7,7,6,0,0,112,136,136,120,8,8,112,2,5, + 5,6,2,0,192,192,0,192,192,2,6,6,6,2,255,192, + 192,0,192,64,128,4,7,7,6,0,0,16,32,64,128,64, + 32,16,5,3,3,6,0,2,248,0,248,4,7,7,6,1, + 0,128,64,32,16,32,64,128,5,7,7,6,0,0,112,136, + 8,16,32,0,32,5,7,7,6,0,0,112,136,8,104,168, + 168,112,5,7,7,6,0,0,112,136,136,248,136,136,136,5, + 7,7,6,0,0,240,136,136,240,136,136,240,5,7,7,6, + 0,0,112,136,128,128,128,136,112,5,7,7,6,0,0,240, + 136,136,136,136,136,240,5,7,7,6,0,0,248,128,128,240, + 128,128,248,5,7,7,6,0,0,248,128,128,240,128,128,128, + 5,7,7,6,0,0,112,136,128,184,136,136,112,5,7,7, + 6,0,0,136,136,136,248,136,136,136,1,7,7,6,2,0, + 128,128,128,128,128,128,128,5,7,7,6,0,0,56,16,16, + 16,16,144,96,5,7,7,6,0,0,136,144,160,192,160,144, + 136,5,7,7,6,0,0,128,128,128,128,128,128,248,5,7, + 7,6,0,0,136,216,168,136,136,136,136,5,7,7,6,0, + 0,136,136,200,168,152,136,136,5,7,7,6,0,0,112,136, + 136,136,136,136,112,5,7,7,6,0,0,240,136,136,240,128, + 128,128,5,7,7,6,0,0,112,136,136,136,168,144,104,5, + 7,7,6,0,0,240,136,136,240,160,144,136,5,7,7,6, + 0,0,120,128,128,112,8,8,240,5,7,7,6,0,0,248, + 32,32,32,32,32,32,5,7,7,6,0,0,136,136,136,136, + 136,136,112,5,7,7,6,0,0,136,136,136,136,136,80,32, + 5,7,7,6,0,0,136,136,136,136,136,168,80,5,7,7, + 6,0,0,136,136,80,32,80,136,136,5,7,7,6,0,0, + 136,136,136,80,32,32,32,5,7,7,6,0,0,248,8,16, + 32,64,128,248,3,7,7,6,1,0,224,128,128,128,128,128, + 224,5,5,5,6,0,1,128,64,32,16,8,3,7,7,6, + 1,0,224,32,32,32,32,32,224,5,3,3,6,0,4,32, + 80,136,5,1,1,6,0,0,248,2,2,2,6,2,5,128, + 64,5,5,5,6,0,0,112,8,120,136,120,5,7,7,6, + 0,0,128,128,176,200,136,136,240,5,5,5,6,0,0,112, + 128,128,136,112,5,7,7,6,0,0,8,8,104,152,136,136, + 120,5,5,5,6,0,0,112,136,248,128,112,5,7,7,6, + 0,0,48,72,224,64,64,64,64,5,6,6,6,0,255,112, + 136,136,120,8,112,5,7,7,6,0,0,128,128,176,200,136, + 136,136,1,7,7,6,2,0,128,0,128,128,128,128,128,3, + 8,8,6,1,255,32,0,32,32,32,32,160,64,4,7,7, + 6,0,0,128,128,144,160,192,160,144,3,7,7,6,1,0, + 192,64,64,64,64,64,224,5,5,5,6,0,0,208,168,168, + 168,168,5,5,5,6,0,0,176,200,136,136,136,5,5,5, + 6,0,0,112,136,136,136,112,5,6,6,6,0,255,240,136, + 136,240,128,128,5,6,6,6,0,255,120,136,136,120,8,8, + 5,5,5,6,0,0,176,200,128,128,128,5,5,5,6,0, + 0,112,128,112,8,240,4,7,7,6,0,0,64,64,224,64, + 64,64,48,5,5,5,6,0,0,136,136,136,152,104,5,5, + 5,6,0,0,136,136,136,80,32,5,5,5,6,0,0,136, + 136,168,168,80,5,5,5,6,0,0,136,80,32,80,136,5, + 6,6,6,0,255,136,136,136,120,8,112,5,5,5,6,0, + 0,248,16,32,64,248,3,7,7,6,1,0,32,64,64,128, + 64,64,32,1,7,7,6,2,0,128,128,128,128,128,128,128, + 3,7,7,6,1,0,128,64,64,32,64,64,128,5,2,2, + 6,0,2,104,144,0,0,0,6,0,0,5,8,8,6,0, + 0,16,32,112,136,136,248,136,136,5,8,8,6,0,0,80, + 0,112,136,136,248,136,136,5,8,8,6,0,0,8,16,248, + 128,128,240,128,248,3,8,8,6,1,0,32,64,224,64,64, + 64,64,224,5,8,8,6,0,0,16,32,112,136,136,136,136, + 112,5,8,8,6,0,0,32,80,112,136,136,136,136,112,5, + 8,8,6,0,0,16,32,136,136,136,136,136,112,5,8,8, + 6,0,0,16,32,136,136,80,32,32,32,5,8,8,6,0, + 0,16,32,0,112,8,120,136,120,5,7,7,6,0,0,80, + 0,112,8,120,136,120,5,8,8,6,0,0,16,32,0,112, + 136,248,128,112,2,8,8,6,2,0,64,128,0,128,128,128, + 128,128,5,8,8,6,0,0,16,32,0,112,136,136,136,112, + 5,8,8,6,0,0,32,80,0,112,136,136,136,112,5,8, + 8,6,0,0,16,32,0,136,136,136,152,104,5,9,9,6, + 0,255,16,32,0,136,136,136,120,8,112,5,8,8,6,0, + 0,80,32,112,136,128,128,136,112,5,8,8,6,0,0,80, + 32,0,112,128,128,136,112,5,8,8,6,0,0,80,32,240, + 136,136,136,136,240,6,8,8,6,0,0,4,20,24,112,144, + 144,144,112,5,8,8,6,0,0,16,32,128,128,128,128,128, + 248,3,8,8,6,1,0,32,64,0,192,64,64,64,224,5, + 8,8,6,0,0,16,144,160,128,128,128,128,248,5,8,8, + 6,1,0,8,200,80,64,64,64,64,224,5,8,8,6,0, + 0,80,32,136,200,168,152,136,136,5,8,8,6,0,0,80, + 32,0,176,200,136,136,136,5,8,8,6,0,0,16,32,240, + 136,240,160,144,136,5,8,8,6,0,0,16,32,0,176,200, + 128,128,128,5,8,8,6,0,0,80,32,120,128,128,112,8, + 240,5,8,8,6,0,0,80,32,0,112,128,112,8,240,5, + 8,8,6,0,0,80,32,248,32,32,32,32,32,6,8,8, + 6,0,0,4,68,72,224,64,64,64,48,5,8,8,6,0, + 0,80,32,248,8,48,64,128,248,5,8,8,6,0,0,80, + 32,0,248,16,32,64,248,0,0,0,6,0,0,0,0,0, + 6,0,0,0,0,0,6,0,0,0,0,0,6,0,0,0, + 0,0,6,0,0,0,0,0,6,0,0,0,0,0,6,0, + 0,0,0,0,6,0,0,0,0,0,6,0,0,0,0,0, + 6,0,0,0,0,0,6,0,0,0,0,0,6,0,0,0, + 0,0,6,0,0,0,0,0,6,0,0,0,0,0,6,0, + 0,0,0,0,6,0,0,0,0,0,6,0,0,0,0,0, + 6,0,0,0,0,0,6,0,0,0,0,0,6,0,0,0, + 0,0,6,0,0,0,0,0,6,0,0,0,0,0,6,0, + 0,0,0,0,6,0,0,0,0,0,6,0,0,0,0,0, + 6,0,0,0,0,0,6,0,0,0,0,0,6,0,0,0, + 0,0,6,0,0,0,0,0,6,0,0,0,0,0,6,0, + 0,0,0,0,6,0,0,0,0,0,6,0,0,0,0,0, + 6,0,0,0,0,0,6,0,0,0,0,0,6,0,0,0, + 0,0,6,0,0,0,0,0,6,0,0,0,0,0,6,0, + 0,0,0,0,6,0,0,0,0,0,6,0,0,0,0,0, + 6,0,0,0,0,0,6,0,0,0,0,0,6,0,0,0, + 0,0,6,0,0,0,0,0,6,0,0,0,0,0,6,0, + 0,0,0,0,6,0,0,0,0,0,6,0,0,0,0,0, + 6,0,0,0,0,0,6,0,0,0,0,0,6,0,0,0, + 0,0,6,0,0,0,0,0,6,0,0,0,0,0,6,0, + 0,0,0,0,6,0,0,0,0,0,6,0,0,0,0,0, + 6,0,0,0,0,0,6,0,0,0,0,0,6,0,0,0, + 0,0,6,0,0,0,0,0,6,0,0,0,0,0,6,0, + 0,0,0,0,6,0,0,0,0,0,6,0,0,0,0,0, + 6,0,0,0,0,0,6,0,0,0,0,0,6,0,0,0, + 0,0,6,0,0,0,0,0,6,0,0,0,0,0,6,0, + 0,0,0,0,6,0,0,0,0,0,6,0,0,0,0,0, + 6,0,0,0,0,0,6,0,0,0,0,0,6,0,0,0, + 0,0,6,0,0,0,0,0,6,0,0,0,0,0,6,0, + 0,0,0,0,6,0,0,0,0,0,6,0,0,0,0,0, + 6,0,0,0,0,0,6,0,0,0,0,0,6,0,0,0, + 0,0,6,0,0,0,0,0,6,0,0,0,0,0,6,0, + 0,0,0,0,6,0,0,0,0,0,6,0,0,0,0,0, + 6,0,0,0,0,0,6,0,0,0,0,0,6,0,0,0, + 0,0,6,0,0,0,0,0,6,0,0}; diff --git a/trunk/Arduino/Marlin_1.1.6/dogm_font_data_Marlin_symbols.h b/trunk/Arduino/Marlin_1.1.6/dogm_font_data_Marlin_symbols.h new file mode 100644 index 00000000..ad9b983b --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/dogm_font_data_Marlin_symbols.h @@ -0,0 +1,45 @@ +/** + * 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 . + * + */ + +/** + Fontname: Marlin_symbols + Copyright: Created with Fony 1.4.7 + Capital A Height: 0, '1' Height: 0 + Calculated Max Values w= 5 h=10 x= 0 y= 3 dx= 6 dy= 0 ascent= 8 len=10 + 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 = 0 descent= 0 + X Font ascent = 0 descent= 0 + Max Font ascent = 8 descent=-2 +*/ +#include +const u8g_fntpgm_uint8_t Marlin_symbols[140] U8G_SECTION(".progmem.Marlin_symbols") = { + 0, 6, 9, 0, 254, 0, 0, 0, 0, 0, 1, 9, 0, 8, 254, 0, + 0, 5, 8, 8, 6, 0, 0, 64, 240, 200, 136, 136, 152, 120, 16, 5, + 8, 8, 6, 0, 0, 192, 248, 136, 136, 136, 136, 136, 248, 5, 5, 5, + 6, 0, 1, 32, 48, 248, 48, 32, 5, 8, 8, 6, 0, 0, 32, 112, + 248, 32, 32, 32, 32, 224, 5, 9, 9, 6, 0, 255, 32, 112, 168, 168, + 184, 136, 136, 112, 32, 5, 9, 9, 6, 0, 255, 224, 128, 192, 176, 168, + 40, 48, 40, 40, 5, 9, 9, 6, 0, 255, 248, 168, 136, 136, 136, 136, + 136, 168, 248, 5, 10, 10, 6, 0, 254, 32, 80, 80, 80, 80, 136, 168, + 168, 136, 112, 3, 3, 3, 6, 0, 3, 64, 160, 64 +}; diff --git a/trunk/Arduino/Marlin_1.1.6/duration_t.h b/trunk/Arduino/Marlin_1.1.6/duration_t.h new file mode 100644 index 00000000..5e9dd1c0 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/duration_t.h @@ -0,0 +1,167 @@ +/** + * 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 . + * + */ + +#ifndef __DURATION_T__ +#define __DURATION_T__ + +struct duration_t { + /** + * @brief Duration is stored in seconds + */ + uint32_t value; + + /** + * @brief Constructor + */ + duration_t() + : duration_t(0) {}; + + /** + * @brief Constructor + * + * @param seconds The number of seconds + */ + duration_t(uint32_t const &seconds) { + this->value = seconds; + } + + /** + * @brief Equality comparison + * @details Overloads the equality comparison operator + * + * @param value The number of seconds to compare to + * @return True if both durations are equal + */ + bool operator==(const uint32_t &value) const { + return (this->value == value); + } + + /** + * @brief Inequality comparison + * @details Overloads the inequality comparison operator + * + * @param value The number of seconds to compare to + * @return False if both durations are equal + */ + bool operator!=(const uint32_t &value) const { + return ! this->operator==(value); + } + + /** + * @brief Formats the duration as years + * @return The number of years + */ + inline uint8_t year() const { + return this->day() / 365; + } + + /** + * @brief Formats the duration as days + * @return The number of days + */ + inline uint16_t day() const { + return this->hour() / 24; + } + + /** + * @brief Formats the duration as hours + * @return The number of hours + */ + inline uint32_t hour() const { + return this->minute() / 60; + } + + /** + * @brief Formats the duration as minutes + * @return The number of minutes + */ + inline uint32_t minute() const { + return this->second() / 60; + } + + /** + * @brief Formats the duration as seconds + * @return The number of seconds + */ + inline uint32_t second() const { + return this->value; + } + + /** + * @brief Formats the duration as a string + * @details String will be formated using a "full" representation of duration + * + * @param buffer The array pointed to must be able to accommodate 21 bytes + * + * Output examples: + * 123456789012345678901 (strlen) + * 135y 364d 23h 59m 59s + * 364d 23h 59m 59s + * 23h 59m 59s + * 59m 59s + * 59s + */ + void toString(char *buffer) const { + int y = this->year(), + d = this->day() % 365, + h = this->hour() % 24, + m = this->minute() % 60, + s = this->second() % 60; + + if (y) sprintf_P(buffer, PSTR("%iy %id %ih %im %is"), y, d, h, m, s); + else if (d) sprintf_P(buffer, PSTR("%id %ih %im %is"), d, h, m, s); + else if (h) sprintf_P(buffer, PSTR("%ih %im %is"), h, m, s); + else if (m) sprintf_P(buffer, PSTR("%im %is"), m, s); + else sprintf_P(buffer, PSTR("%is"), s); + } + + /** + * @brief Formats the duration as a string + * @details String will be formated using a "digital" representation of duration + * + * @param buffer The array pointed to must be able to accommodate 10 bytes + * + * Output examples: + * 123456789 (strlen) + * 99:59 + * 11d 12:33 + */ + uint8_t toDigital(char *buffer, bool with_days=false) const { + uint16_t h = uint16_t(this->hour()), + m = uint16_t(this->minute() % 60UL); + if (with_days) { + uint16_t d = this->day(); + sprintf_P(buffer, PSTR("%ud %02u:%02u"), d, h % 24, m); + return d >= 10 ? 8 : 7; + } + else if (h < 100) { + sprintf_P(buffer, PSTR("%02u:%02u"), h % 24, m); + return 5; + } + else { + sprintf_P(buffer, PSTR("%u:%02u"), h, m); + return 6; + } + } +}; + +#endif // __DURATION_T__ diff --git a/trunk/Arduino/Marlin_1.1.6/endstop_interrupts.h b/trunk/Arduino/Marlin_1.1.6/endstop_interrupts.h new file mode 100644 index 00000000..7d37c77c --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/endstop_interrupts.h @@ -0,0 +1,206 @@ +/** + * 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 . + * + */ + +/** + * Endstop Interrupts + * + * Without endstop interrupts the endstop pins must be polled continually in + * the stepper-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 either an + * 'external interrupt' or a 'pin change 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) + */ + +#ifndef _ENDSTOP_INTERRUPTS_H_ +#define _ENDSTOP_INTERRUPTS_H_ + +#include "macros.h" + +/** + * Patch for pins_arduino.h (...\Arduino\hardware\arduino\avr\variants\mega\pins_arduino.h) + * + * These macros for the Arduino MEGA do not include the two connected pins on Port J (D13, D14). + * So we extend them here because these are the normal pins for Y_MIN and Y_MAX on RAMPS. + * There are more PCI-enabled processor pins on Port J, but they are not connected to Arduino MEGA. + */ +#if defined(ARDUINO_AVR_MEGA2560) || defined(ARDUINO_AVR_MEGA) + #undef digitalPinToPCICR + #define digitalPinToPCICR(p) ( WITHIN(p, 10, 15) || \ + WITHIN(p, 50, 53) || \ + WITHIN(p, 62, 69) ? &PCICR : (uint8_t*)0 ) + #undef digitalPinToPCICRbit + #define digitalPinToPCICRbit(p) ( WITHIN(p, 10, 13) || WITHIN(p, 50, 53) ? 0 : \ + WITHIN(p, 14, 15) ? 1 : \ + WITHIN(p, 62, 69) ? 2 : \ + 0 ) + #undef digitalPinToPCMSK + #define digitalPinToPCMSK(p) ( WITHIN(p, 10, 13) || WITHIN(p, 50, 53) ? &PCMSK0 : \ + WITHIN(p, 14, 15) ? &PCMSK1 : \ + WITHIN(p, 62, 69) ? &PCMSK2 : \ + (uint8_t *)0 ) + #undef digitalPinToPCMSKbit + #define digitalPinToPCMSKbit(p) ( WITHIN(p, 10, 13) ? ((p) - 6) : \ + (p) == 14 || (p) == 51 ? 2 : \ + (p) == 15 || (p) == 52 ? 1 : \ + (p) == 50 ? 3 : \ + (p) == 53 ? 0 : \ + WITHIN(p, 62, 69) ? ((p) - 62) : \ + 0 ) +#endif + +volatile uint8_t e_hit = 0; // Different from 0 when the endstops should be tested in detail. + // Must be reset to 0 by the test function when finished. + +// Install Pin change interrupt for a pin. Can be called multiple times. +void pciSetup(byte pin) { + SBI(*digitalPinToPCMSK(pin), digitalPinToPCMSKbit(pin)); // enable pin + SBI(PCIFR, digitalPinToPCICRbit(pin)); // clear any outstanding interrupt + SBI(PCICR, digitalPinToPCICRbit(pin)); // enable interrupt for the group +} + +// This is what is really done inside the interrupts. +FORCE_INLINE void endstop_ISR_worker( void ) { + e_hit = 2; // Because the detection of a e-stop hit has a 1 step debouncer it has to be called at least twice. +} + +// Use one Routine to handle each group +// One ISR for all EXT-Interrupts +void endstop_ISR(void) { endstop_ISR_worker(); } + +// Handlers for pin change interrupts +#ifdef PCINT0_vect + ISR(PCINT0_vect) { endstop_ISR_worker(); } +#endif + +#ifdef PCINT1_vect + ISR(PCINT1_vect) { endstop_ISR_worker(); } +#endif + +#ifdef PCINT2_vect + ISR(PCINT2_vect) { endstop_ISR_worker(); } +#endif + +#ifdef PCINT3_vect + ISR(PCINT3_vect) { endstop_ISR_worker(); } +#endif + +void setup_endstop_interrupts( void ) { + + #if HAS_X_MAX + #if (digitalPinToInterrupt(X_MAX_PIN) != NOT_AN_INTERRUPT) // if pin has an external interrupt + attachInterrupt(digitalPinToInterrupt(X_MAX_PIN), endstop_ISR, CHANGE); // assign it + #else + // Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration! + static_assert(digitalPinToPCICR(X_MAX_PIN) != NULL, "X_MAX_PIN is not interrupt-capable"); // if pin has no pin change interrupt - error + pciSetup(X_MAX_PIN); // assign it + #endif + #endif + + #if HAS_X_MIN + #if (digitalPinToInterrupt(X_MIN_PIN) != NOT_AN_INTERRUPT) + attachInterrupt(digitalPinToInterrupt(X_MIN_PIN), endstop_ISR, CHANGE); + #else + // Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration! + static_assert(digitalPinToPCICR(X_MIN_PIN) != NULL, "X_MIN_PIN is not interrupt-capable"); + pciSetup(X_MIN_PIN); + #endif + #endif + + #if HAS_Y_MAX + #if (digitalPinToInterrupt(Y_MAX_PIN) != NOT_AN_INTERRUPT) + attachInterrupt(digitalPinToInterrupt(Y_MAX_PIN), endstop_ISR, CHANGE); + #else + // Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration! + static_assert(digitalPinToPCICR(Y_MAX_PIN) != NULL, "Y_MAX_PIN is not interrupt-capable"); + pciSetup(Y_MAX_PIN); + #endif + #endif + + #if HAS_Y_MIN + #if (digitalPinToInterrupt(Y_MIN_PIN) != NOT_AN_INTERRUPT) + attachInterrupt(digitalPinToInterrupt(Y_MIN_PIN), endstop_ISR, CHANGE); + #else + // Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration! + static_assert(digitalPinToPCICR(Y_MIN_PIN) != NULL, "Y_MIN_PIN is not interrupt-capable"); + pciSetup(Y_MIN_PIN); + #endif + #endif + + #if HAS_Z_MAX + #if (digitalPinToInterrupt(Z_MAX_PIN) != NOT_AN_INTERRUPT) + attachInterrupt(digitalPinToInterrupt(Z_MAX_PIN), endstop_ISR, CHANGE); + #else + // Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration! + static_assert(digitalPinToPCICR(Z_MAX_PIN) != NULL, "Z_MAX_PIN is not interrupt-capable"); + pciSetup(Z_MAX_PIN); + #endif + #endif + + #if HAS_Z_MIN + #if (digitalPinToInterrupt(Z_MIN_PIN) != NOT_AN_INTERRUPT) + attachInterrupt(digitalPinToInterrupt(Z_MIN_PIN), endstop_ISR, CHANGE); + #else + // Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration! + static_assert(digitalPinToPCICR(Z_MIN_PIN) != NULL, "Z_MIN_PIN is not interrupt-capable"); + pciSetup(Z_MIN_PIN); + #endif + #endif + + #if HAS_Z2_MAX + #if (digitalPinToInterrupt(Z2_MAX_PIN) != NOT_AN_INTERRUPT) + attachInterrupt(digitalPinToInterrupt(Z2_MAX_PIN), endstop_ISR, CHANGE); + #else + // Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration! + static_assert(digitalPinToPCICR(Z2_MAX_PIN) != NULL, "Z2_MAX_PIN is not interrupt-capable"); + pciSetup(Z2_MAX_PIN); + #endif + #endif + + #if HAS_Z2_MIN + #if (digitalPinToInterrupt(Z2_MIN_PIN) != NOT_AN_INTERRUPT) + attachInterrupt(digitalPinToInterrupt(Z2_MIN_PIN), endstop_ISR, CHANGE); + #else + // Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration! + static_assert(digitalPinToPCICR(Z2_MIN_PIN) != NULL, "Z2_MIN_PIN is not interrupt-capable"); + pciSetup(Z2_MIN_PIN); + #endif + #endif + + #if HAS_Z_MIN_PROBE_PIN + #if (digitalPinToInterrupt(Z_MIN_PROBE_PIN) != NOT_AN_INTERRUPT) + attachInterrupt(digitalPinToInterrupt(Z_MIN_PROBE_PIN), endstop_ISR, CHANGE); + #else + // Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration! + static_assert(digitalPinToPCICR(Z_MIN_PROBE_PIN) != NULL, "Z_MIN_PROBE_PIN is not interrupt-capable"); + pciSetup(Z_MIN_PROBE_PIN); + #endif + #endif + + // If we arrive here without raising an assertion, each pin has either an EXT-interrupt or a PCI. +} + +#endif // _ENDSTOP_INTERRUPTS_H_ diff --git a/trunk/Arduino/Marlin_1.1.6/endstops.cpp b/trunk/Arduino/Marlin_1.1.6/endstops.cpp new file mode 100644 index 00000000..8ff6c766 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/endstops.cpp @@ -0,0 +1,451 @@ +/** + * 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 . + * + */ + +/** + * endstops.cpp - A singleton object to manage endstops + */ + +#include "Marlin.h" +#include "cardreader.h" +#include "endstops.h" +#include "temperature.h" +#include "stepper.h" +#include "ultralcd.h" + +// TEST_ENDSTOP: test the old and the current status of an endstop +#define TEST_ENDSTOP(ENDSTOP) (TEST(current_endstop_bits & old_endstop_bits, ENDSTOP)) + +Endstops endstops; + +// public: + +bool Endstops::enabled, Endstops::enabled_globally; // Initialized by settings.load() +volatile char Endstops::endstop_hit_bits; // use X_MIN, Y_MIN, Z_MIN and Z_MIN_PROBE as BIT value + +#if ENABLED(Z_DUAL_ENDSTOPS) + uint16_t +#else + byte +#endif + Endstops::current_endstop_bits = 0, + Endstops::old_endstop_bits = 0; + +#if HAS_BED_PROBE + volatile bool Endstops::z_probe_enabled = false; +#endif + +/** + * Class and Instance Methods + */ + +void Endstops::init() { + + #if HAS_X_MIN + #if ENABLED(ENDSTOPPULLUP_XMIN) + SET_INPUT_PULLUP(X_MIN_PIN); + #else + SET_INPUT(X_MIN_PIN); + #endif + #endif + + #if HAS_Y_MIN + #if ENABLED(ENDSTOPPULLUP_YMIN) + SET_INPUT_PULLUP(Y_MIN_PIN); + #else + SET_INPUT(Y_MIN_PIN); + #endif + #endif + + #if HAS_Z_MIN + #if ENABLED(ENDSTOPPULLUP_ZMIN) + SET_INPUT_PULLUP(Z_MIN_PIN); + #else + SET_INPUT(Z_MIN_PIN); + #endif + #endif + + #if HAS_Z2_MIN + #if ENABLED(ENDSTOPPULLUP_ZMIN) + SET_INPUT_PULLUP(Z2_MIN_PIN); + #else + SET_INPUT(Z2_MIN_PIN); + #endif + #endif + + #if HAS_X_MAX + #if ENABLED(ENDSTOPPULLUP_XMAX) + SET_INPUT_PULLUP(X_MAX_PIN); + #else + SET_INPUT(X_MAX_PIN); + #endif + #endif + + #if HAS_Y_MAX + #if ENABLED(ENDSTOPPULLUP_YMAX) + SET_INPUT_PULLUP(Y_MAX_PIN); + #else + SET_INPUT(Y_MAX_PIN); + #endif + #endif + + #if HAS_Z_MAX + #if ENABLED(ENDSTOPPULLUP_ZMAX) + SET_INPUT_PULLUP(Z_MAX_PIN); + #else + SET_INPUT(Z_MAX_PIN); + #endif + #endif + + #if HAS_Z2_MAX + #if ENABLED(ENDSTOPPULLUP_ZMAX) + SET_INPUT_PULLUP(Z2_MAX_PIN); + #else + SET_INPUT(Z2_MAX_PIN); + #endif + #endif + + #if ENABLED(Z_MIN_PROBE_ENDSTOP) + #if ENABLED(ENDSTOPPULLUP_ZMIN_PROBE) + SET_INPUT_PULLUP(Z_MIN_PROBE_PIN); + #else + SET_INPUT(Z_MIN_PROBE_PIN); + #endif + #endif + +} // Endstops::init + +void Endstops::report_state() { + if (endstop_hit_bits) { + #if ENABLED(ULTRA_LCD) + char chrX = ' ', chrY = ' ', chrZ = ' ', chrP = ' '; + #define _SET_STOP_CHAR(A,C) (chr## A = C) + #else + #define _SET_STOP_CHAR(A,C) ; + #endif + + #define _ENDSTOP_HIT_ECHO(A,C) do{ \ + SERIAL_ECHOPAIR(" " STRINGIFY(A) ":", stepper.triggered_position_mm(A ##_AXIS)); \ + _SET_STOP_CHAR(A,C); }while(0) + + #define _ENDSTOP_HIT_TEST(A,C) \ + if (TEST(endstop_hit_bits, A ##_MIN) || TEST(endstop_hit_bits, A ##_MAX)) \ + _ENDSTOP_HIT_ECHO(A,C) + + #define ENDSTOP_HIT_TEST_X() _ENDSTOP_HIT_TEST(X,'X') + #define ENDSTOP_HIT_TEST_Y() _ENDSTOP_HIT_TEST(Y,'Y') + #define ENDSTOP_HIT_TEST_Z() _ENDSTOP_HIT_TEST(Z,'Z') + + SERIAL_ECHO_START(); + SERIAL_ECHOPGM(MSG_ENDSTOPS_HIT); + ENDSTOP_HIT_TEST_X(); + ENDSTOP_HIT_TEST_Y(); + ENDSTOP_HIT_TEST_Z(); + + #if ENABLED(Z_MIN_PROBE_ENDSTOP) + #define P_AXIS Z_AXIS + if (TEST(endstop_hit_bits, Z_MIN_PROBE)) _ENDSTOP_HIT_ECHO(P, 'P'); + #endif + SERIAL_EOL(); + + #if ENABLED(ULTRA_LCD) + lcd_status_printf_P(0, PSTR(MSG_LCD_ENDSTOPS " %c %c %c %c"), chrX, chrY, chrZ, chrP); + #endif + + hit_on_purpose(); + + #if ENABLED(ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED) && ENABLED(SDSUPPORT) + if (stepper.abort_on_endstop_hit) { + card.sdprinting = false; + card.closefile(); + quickstop_stepper(); + thermalManager.disable_all_heaters(); // switch off all heaters. + } + #endif + } +} // Endstops::report_state + +void Endstops::M119() { + SERIAL_PROTOCOLLNPGM(MSG_M119_REPORT); + #if HAS_X_MIN + SERIAL_PROTOCOLPGM(MSG_X_MIN); + SERIAL_PROTOCOLLN(((READ(X_MIN_PIN)^X_MIN_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN)); + #endif + #if HAS_X_MAX + SERIAL_PROTOCOLPGM(MSG_X_MAX); + SERIAL_PROTOCOLLN(((READ(X_MAX_PIN)^X_MAX_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN)); + #endif + #if HAS_Y_MIN + SERIAL_PROTOCOLPGM(MSG_Y_MIN); + SERIAL_PROTOCOLLN(((READ(Y_MIN_PIN)^Y_MIN_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN)); + #endif + #if HAS_Y_MAX + SERIAL_PROTOCOLPGM(MSG_Y_MAX); + SERIAL_PROTOCOLLN(((READ(Y_MAX_PIN)^Y_MAX_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN)); + #endif + #if HAS_Z_MIN + SERIAL_PROTOCOLPGM(MSG_Z_MIN); + SERIAL_PROTOCOLLN(((READ(Z_MIN_PIN)^Z_MIN_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN)); + #endif + #if HAS_Z2_MIN + SERIAL_PROTOCOLPGM(MSG_Z2_MIN); + SERIAL_PROTOCOLLN(((READ(Z2_MIN_PIN)^Z2_MIN_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN)); + #endif + #if HAS_Z_MAX + SERIAL_PROTOCOLPGM(MSG_Z_MAX); + SERIAL_PROTOCOLLN(((READ(Z_MAX_PIN)^Z_MAX_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN)); + #endif + #if HAS_Z2_MAX + SERIAL_PROTOCOLPGM(MSG_Z2_MAX); + SERIAL_PROTOCOLLN(((READ(Z2_MAX_PIN)^Z2_MAX_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN)); + #endif + #if ENABLED(Z_MIN_PROBE_ENDSTOP) + SERIAL_PROTOCOLPGM(MSG_Z_PROBE); + SERIAL_PROTOCOLLN(((READ(Z_MIN_PROBE_PIN)^Z_MIN_PROBE_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN)); + #endif + #if ENABLED(FILAMENT_RUNOUT_SENSOR) + SERIAL_PROTOCOLPGM(MSG_FILAMENT_RUNOUT_SENSOR); + SERIAL_PROTOCOLLN(((READ(FIL_RUNOUT_PIN)^FIL_RUNOUT_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN)); + #endif +} // Endstops::M119 + +#if ENABLED(Z_DUAL_ENDSTOPS) + + // Pass the result of the endstop test + void Endstops::test_dual_z_endstops(const EndstopEnum es1, const EndstopEnum es2) { + byte z_test = TEST_ENDSTOP(es1) | (TEST_ENDSTOP(es2) << 1); // bit 0 for Z, bit 1 for Z2 + if (z_test && stepper.current_block->steps[Z_AXIS] > 0) { + SBI(endstop_hit_bits, Z_MIN); + if (!stepper.performing_homing || (z_test == 0x3)) //if not performing home or if both endstops were trigged during homing... + stepper.kill_current_block(); + } + } + +#endif + +// Check endstops - Called from ISR! +void Endstops::update() { + + #define _ENDSTOP(AXIS, MINMAX) AXIS ##_## MINMAX + #define _ENDSTOP_PIN(AXIS, MINMAX) AXIS ##_## MINMAX ##_PIN + #define _ENDSTOP_INVERTING(AXIS, MINMAX) AXIS ##_## MINMAX ##_ENDSTOP_INVERTING + #define _ENDSTOP_HIT(AXIS, MINMAX) SBI(endstop_hit_bits, _ENDSTOP(AXIS, MINMAX)) + + // UPDATE_ENDSTOP_BIT: set the current endstop bits for an endstop to its status + #define UPDATE_ENDSTOP_BIT(AXIS, MINMAX) SET_BIT(current_endstop_bits, _ENDSTOP(AXIS, MINMAX), (READ(_ENDSTOP_PIN(AXIS, MINMAX)) != _ENDSTOP_INVERTING(AXIS, MINMAX))) + // COPY_BIT: copy the value of SRC_BIT to DST_BIT in DST + #define COPY_BIT(DST, SRC_BIT, DST_BIT) SET_BIT(DST, DST_BIT, TEST(DST, SRC_BIT)) + + #define UPDATE_ENDSTOP(AXIS,MINMAX) do { \ + UPDATE_ENDSTOP_BIT(AXIS, MINMAX); \ + if (TEST_ENDSTOP(_ENDSTOP(AXIS, MINMAX)) && stepper.current_block->steps[_AXIS(AXIS)] > 0) { \ + _ENDSTOP_HIT(AXIS, MINMAX); \ + stepper.endstop_triggered(_AXIS(AXIS)); \ + } \ + } while(0) + + #if ENABLED(G38_PROBE_TARGET) && PIN_EXISTS(Z_MIN_PROBE) && !(CORE_IS_XY || CORE_IS_XZ) + // If G38 command is active check Z_MIN_PROBE for ALL movement + if (G38_move) { + UPDATE_ENDSTOP_BIT(Z, MIN_PROBE); + if (TEST_ENDSTOP(_ENDSTOP(Z, MIN_PROBE))) { + if (stepper.current_block->steps[_AXIS(X)] > 0) { _ENDSTOP_HIT(X, MIN); stepper.endstop_triggered(_AXIS(X)); } + else if (stepper.current_block->steps[_AXIS(Y)] > 0) { _ENDSTOP_HIT(Y, MIN); stepper.endstop_triggered(_AXIS(Y)); } + else if (stepper.current_block->steps[_AXIS(Z)] > 0) { _ENDSTOP_HIT(Z, MIN); stepper.endstop_triggered(_AXIS(Z)); } + G38_endstop_hit = true; + } + } + #endif + + /** + * Define conditions for checking endstops + */ + + #if IS_CORE + #define S_(N) stepper.current_block->steps[CORE_AXIS_##N] + #define D_(N) stepper.motor_direction(CORE_AXIS_##N) + #endif + + #if CORE_IS_XY || CORE_IS_XZ + /** + * Head direction in -X axis for CoreXY and CoreXZ bots. + * + * If steps differ, both axes are moving. + * If DeltaA == -DeltaB, the movement is only in the 2nd axis (Y or Z, handled below) + * If DeltaA == DeltaB, the movement is only in the 1st axis (X) + */ + #if ENABLED(COREXY) || ENABLED(COREXZ) + #define X_CMP == + #else + #define X_CMP != + #endif + #define X_MOVE_TEST ( S_(1) != S_(2) || (S_(1) > 0 && D_(1) X_CMP D_(2)) ) + #define X_AXIS_HEAD X_HEAD + #else + #define X_MOVE_TEST stepper.current_block->steps[X_AXIS] > 0 + #define X_AXIS_HEAD X_AXIS + #endif + + #if CORE_IS_XY || CORE_IS_YZ + /** + * Head direction in -Y axis for CoreXY / CoreYZ bots. + * + * If steps differ, both axes are moving + * If DeltaA == DeltaB, the movement is only in the 1st axis (X or Y) + * If DeltaA == -DeltaB, the movement is only in the 2nd axis (Y or Z) + */ + #if ENABLED(COREYX) || ENABLED(COREYZ) + #define Y_CMP == + #else + #define Y_CMP != + #endif + #define Y_MOVE_TEST ( S_(1) != S_(2) || (S_(1) > 0 && D_(1) Y_CMP D_(2)) ) + #define Y_AXIS_HEAD Y_HEAD + #else + #define Y_MOVE_TEST stepper.current_block->steps[Y_AXIS] > 0 + #define Y_AXIS_HEAD Y_AXIS + #endif + + #if CORE_IS_XZ || CORE_IS_YZ + /** + * Head direction in -Z axis for CoreXZ or CoreYZ bots. + * + * If steps differ, both axes are moving + * If DeltaA == DeltaB, the movement is only in the 1st axis (X or Y, already handled above) + * If DeltaA == -DeltaB, the movement is only in the 2nd axis (Z) + */ + #if ENABLED(COREZX) || ENABLED(COREZY) + #define Z_CMP == + #else + #define Z_CMP != + #endif + #define Z_MOVE_TEST ( S_(1) != S_(2) || (S_(1) > 0 && D_(1) Z_CMP D_(2)) ) + #define Z_AXIS_HEAD Z_HEAD + #else + #define Z_MOVE_TEST stepper.current_block->steps[Z_AXIS] > 0 + #define Z_AXIS_HEAD Z_AXIS + #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.current_block->active_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 + #define X_MIN_TEST true + #define X_MAX_TEST true + #endif + + /** + * Check and update endstops according to conditions + */ + + if (X_MOVE_TEST) { + if (stepper.motor_direction(X_AXIS_HEAD)) { + if (X_MIN_TEST) { // -direction + #if HAS_X_MIN + UPDATE_ENDSTOP(X, MIN); + #endif + } + } + else if (X_MAX_TEST) { // +direction + #if HAS_X_MAX + UPDATE_ENDSTOP(X, MAX); + #endif + } + } + + if (Y_MOVE_TEST) { + if (stepper.motor_direction(Y_AXIS_HEAD)) { // -direction + #if HAS_Y_MIN + UPDATE_ENDSTOP(Y, MIN); + #endif + } + else { // +direction + #if HAS_Y_MAX + UPDATE_ENDSTOP(Y, MAX); + #endif + } + } + + if (Z_MOVE_TEST) { + if (stepper.motor_direction(Z_AXIS_HEAD)) { // Z -direction. Gantry down, bed up. + #if HAS_Z_MIN + #if ENABLED(Z_DUAL_ENDSTOPS) + + UPDATE_ENDSTOP_BIT(Z, MIN); + #if HAS_Z2_MIN + UPDATE_ENDSTOP_BIT(Z2, MIN); + #else + COPY_BIT(current_endstop_bits, Z_MIN, Z2_MIN); + #endif + + test_dual_z_endstops(Z_MIN, Z2_MIN); + + #else // !Z_DUAL_ENDSTOPS + + #if ENABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN) + if (z_probe_enabled) UPDATE_ENDSTOP(Z, MIN); + #else + UPDATE_ENDSTOP(Z, MIN); + #endif + + #endif // !Z_DUAL_ENDSTOPS + + #endif // HAS_Z_MIN + + // When closing the gap check the enabled probe + #if ENABLED(Z_MIN_PROBE_ENDSTOP) + if (z_probe_enabled) { + UPDATE_ENDSTOP(Z, MIN_PROBE); + if (TEST_ENDSTOP(Z_MIN_PROBE)) SBI(endstop_hit_bits, Z_MIN_PROBE); + } + #endif + } + else { // Z +direction. Gantry up, bed down. + #if HAS_Z_MAX + + // Check both Z dual endstops + #if ENABLED(Z_DUAL_ENDSTOPS) + + UPDATE_ENDSTOP_BIT(Z, MAX); + #if HAS_Z2_MAX + UPDATE_ENDSTOP_BIT(Z2, MAX); + #else + COPY_BIT(current_endstop_bits, Z_MAX, Z2_MAX); + #endif + + test_dual_z_endstops(Z_MAX, Z2_MAX); + + // If this pin is not hijacked for the bed probe + // then it belongs to the Z endstop + #elif DISABLED(Z_MIN_PROBE_ENDSTOP) || Z_MAX_PIN != Z_MIN_PROBE_PIN + + UPDATE_ENDSTOP(Z, MAX); + + #endif // !Z_MIN_PROBE_PIN... + #endif // Z_MAX_PIN + } + } + + old_endstop_bits = current_endstop_bits; + +} // Endstops::update() diff --git a/trunk/Arduino/Marlin_1.1.6/endstops.h b/trunk/Arduino/Marlin_1.1.6/endstops.h new file mode 100644 index 00000000..2788fb64 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/endstops.h @@ -0,0 +1,102 @@ +/** + * 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 . + * + */ + +/** + * endstops.h - manages endstops + */ + +#ifndef ENDSTOPS_H +#define ENDSTOPS_H + +#include "enum.h" + +class Endstops { + + public: + + static bool enabled, enabled_globally; + static volatile char endstop_hit_bits; // use X_MIN, Y_MIN, Z_MIN and Z_MIN_PROBE as BIT value + + #if ENABLED(Z_DUAL_ENDSTOPS) + static uint16_t + #else + static byte + #endif + current_endstop_bits, old_endstop_bits; + + Endstops() {}; + + /** + * Initialize the endstop pins + */ + void init(); + + /** + * Update the endstops bits from the pins + */ + static void update(); + + /** + * Print an error message reporting the position when the endstops were last hit. + */ + static void report_state(); //call from somewhere to create an serial error message with the locations the endstops where hit, in case they were triggered + + /** + * Report endstop positions in response to M119 + */ + static void M119(); + + // Enable / disable endstop checking globally + static void enable_globally(bool onoff=true) { enabled_globally = enabled = onoff; } + + // Enable / disable endstop checking + static void enable(bool onoff=true) { enabled = onoff; } + + // Disable / Enable endstops based on ENSTOPS_ONLY_FOR_HOMING and global enable + static void not_homing() { enabled = enabled_globally; } + + // Clear endstops (i.e., they were hit intentionally) to suppress the report + static void hit_on_purpose() { endstop_hit_bits = 0; } + + // Enable / disable endstop z-probe checking + #if HAS_BED_PROBE + static volatile bool z_probe_enabled; + static void enable_z_probe(bool onoff=true) { z_probe_enabled = onoff; } + #endif + + private: + + #if ENABLED(Z_DUAL_ENDSTOPS) + static void test_dual_z_endstops(const EndstopEnum es1, const EndstopEnum es2); + #endif +}; + +extern Endstops endstops; + +#if HAS_BED_PROBE + #define ENDSTOPS_ENABLED (endstops.enabled || endstops.z_probe_enabled) +#else + #define ENDSTOPS_ENABLED endstops.enabled +#endif + + +#endif // ENDSTOPS_H diff --git a/trunk/Arduino/Marlin_1.1.6/enum.h b/trunk/Arduino/Marlin_1.1.6/enum.h new file mode 100644 index 00000000..c3e9ad01 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/enum.h @@ -0,0 +1,189 @@ +/** + * 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 . + * + */ + +#ifndef __ENUM_H__ +#define __ENUM_H__ + +#include "MarlinConfig.h" + +/** + * Axis indices as enumerated constants + * + * Special axis: + * - A_AXIS and B_AXIS are used by COREXY printers + * - X_HEAD and Y_HEAD is used for systems that don't have a 1:1 relationship + * between X_AXIS and X Head movement, like CoreXY bots + */ +enum AxisEnum { + NO_AXIS = -1, + X_AXIS = 0, + A_AXIS = 0, + Y_AXIS = 1, + B_AXIS = 1, + Z_AXIS = 2, + C_AXIS = 2, + E_AXIS = 3, + X_HEAD = 4, + Y_HEAD = 5, + Z_HEAD = 6, + ALL_AXES = 100 +}; + +#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. + * + */ + +/** + * Configuration.h + * + * Basic settings such as: + * + * - Type of electronics + * - Type of temperature sensor + * - Printer geometry + * - Endstop configuration + * - LCD controller + * - Extra features + * + * Advanced settings can be found in Configuration_adv.h + * + */ +#ifndef CONFIGURATION_H +#define CONFIGURATION_H +#define CONFIGURATION_H_VERSION 010100 + +//=========================================================================== +//============================= Getting Started ============================= +//=========================================================================== + +/** + * Here are some standard links for getting your machine calibrated: + * + * http://reprap.org/wiki/Calibration + * http://youtu.be/wAL9d7FgInk + * http://calculator.josefprusa.cz + * http://reprap.org/wiki/Triffid_Hunter%27s_Calibration_Guide + * http://www.thingiverse.com/thing:5573 + * https://sites.google.com/site/repraplogphase/calibration-of-your-reprap + * http://www.thingiverse.com/thing:298812 + */ + +//=========================================================================== +//============================= DELTA Printer =============================== +//=========================================================================== +// For a Delta printer start with one of the configuration files in the +// example_configurations/delta directory and customize for your machine. +// + +//=========================================================================== +//============================= SCARA Printer =============================== +//=========================================================================== +// For a SCARA printer start with the configuration files in +// example_configurations/SCARA and customize for your machine. +// + +// @section info + +// User-specified version info of this build to display in [Pronterface, etc] terminal window during +// startup. Implementation of an idea by Prof Braino to inform user that any changes made to this +// build by the user have been successfully uploaded into firmware. +#define STRING_CONFIG_H_AUTHOR "(Aleph Objects Inc, TAZ)" // Who made the changes. +#define SHOW_BOOTSCREEN +#define STRING_SPLASH_LINE1 SHORT_BUILD_VERSION // will be shown during bootup in line 1 +#define STRING_SPLASH_LINE2 WEBSITE_URL // will be shown during bootup in line 2 + +// +// *** VENDORS PLEASE READ ***************************************************** +// +// Marlin now allow you to have a vendor boot image to be displayed on machine +// start. When SHOW_CUSTOM_BOOTSCREEN is defined Marlin will first show your +// custom boot image and then the default Marlin boot image is shown. +// +// We suggest for you to take advantage of this new feature and keep the Marlin +// boot image unmodified. For an example have a look at the bq Hephestos 2 +// example configuration folder. +// +//#define SHOW_CUSTOM_BOOTSCREEN +// @section machine + +/** + * Select which serial port on the board will be used for communication with the host. + * This allows the connection of wireless adapters (for instance) to non-default port pins. + * Serial port 0 is always used by the Arduino bootloader regardless of this setting. + * + * :[0, 1, 2, 3, 4, 5, 6, 7] + */ +#define SERIAL_PORT 0 + +/** + * This setting determines the communication speed of the printer. + * + * 250000 works in most cases, but you might try a lower speed if + * you commonly experience drop-outs during host printing. + * You may try up to 1000000 to speed up SD file transfer. + * + * :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000] + */ +#define BAUDRATE 250000 + +// Enable the Bluetooth serial interface on AT90USB devices +//#define BLUETOOTH + +// The following define selects which electronics board you have. +// Please choose the name from boards.h that matches your setup +#ifndef MOTHERBOARD + #define MOTHERBOARD BOARD_RAMBO +#endif + +// Optional custom name for your RepStrap or other custom machine +// Displayed in the LCD "Ready" message +#define CUSTOM_MACHINE_NAME "TAZ" + +// Define this to set a unique identifier for this printer, (Used by some programs to differentiate between machines) +// You can use an online service to generate a random UUID. (eg http://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] +#define EXTRUDERS 1 + +// For Cyclops or any "multi-extruder" that shares a single nozzle. +//#define SINGLENOZZLE + +/** + * Průša MK2 Single Nozzle Multi-Material Multiplexer, and variants. + * + * This device allows one stepper driver on a control board to drive + * two to eight stepper motors, one at a time, in a manner suitable + * for extruders. + * + * This option only allows the multiplexer to switch on tool-change. + * Additional options to configure custom E moves are pending. + */ +//#define MK2_MULTIPLEXER +#if ENABLED(MK2_MULTIPLEXER) + // Override the default DIO selector pins here, if needed. + // Some pins files may provide defaults for these pins. + //#define E_MUX0_PIN 40 // Always Required + //#define E_MUX1_PIN 42 // Needed for 3 to 8 steppers + //#define E_MUX2_PIN 44 // Needed for 5 to 8 steppers +#endif + +// A dual extruder that uses a single stepper motor +//#define SWITCHING_EXTRUDER +#if ENABLED(SWITCHING_EXTRUDER) + #define SWITCHING_EXTRUDER_SERVO_NR 0 + #define SWITCHING_EXTRUDER_SERVO_ANGLES { 0, 90 } // Angles for E0, E1[, E2, E3] + #if EXTRUDERS > 3 + #define SWITCHING_EXTRUDER_E23_SERVO_NR 1 + #endif +#endif + +// A dual-nozzle that uses a servomotor to raise/lower one of the nozzles +//#define SWITCHING_NOZZLE +#if ENABLED(SWITCHING_NOZZLE) + #define SWITCHING_NOZZLE_SERVO_NR 0 + #define SWITCHING_NOZZLE_SERVO_ANGLES { 0, 90 } // Angles for E0, E1 + //#define HOTEND_OFFSET_Z { 0.0, 0.0 } +#endif + +/** + * Two separate X-carriages with extruders that connect to a moving part + * via a magnetic docking mechanism. Requires SOL1_PIN and SOL2_PIN. + */ +//#define PARKING_EXTRUDER +#if ENABLED(PARKING_EXTRUDER) + #define PARKING_EXTRUDER_SOLENOIDS_INVERT // If enabled, the solenoid is NOT magnetized with applied voltage + #define PARKING_EXTRUDER_SOLENOIDS_PINS_ACTIVE LOW // LOW or HIGH pin signal energizes the coil + #define PARKING_EXTRUDER_SOLENOIDS_DELAY 250 // Delay (ms) for magnetic field. No delay if 0 or not defined. + #define PARKING_EXTRUDER_PARKING_X { -78, 184 } // X positions for parking the extruders + #define PARKING_EXTRUDER_GRAB_DISTANCE 1 // mm to move beyond the parking point to grab the extruder + #define PARKING_EXTRUDER_SECURITY_RAISE 5 // Z-raise before parking + #define HOTEND_OFFSET_Z { 0.0, 1.3 } // Z-offsets of the two hotends. The first must be 0. +#endif + +/** + * "Mixing Extruder" + * - Adds a new code, M165, to set the current mix factors. + * - Extends the stepping routines to move multiple steppers in proportion to the mix. + * - Optional support for Repetier Firmware M163, M164, and virtual extruder. + * - This implementation supports only a single extruder. + * - Enable DIRECT_MIXING_IN_G1 for Pia Taubert's reference implementation + */ +//#define MIXING_EXTRUDER +#if ENABLED(MIXING_EXTRUDER) + #define MIXING_STEPPERS 2 // Number of steppers in your mixing extruder + #define MIXING_VIRTUAL_TOOLS 16 // Use the Virtual Tool method with M163 and M164 + //#define DIRECT_MIXING_IN_G1 // Allow ABCDHI mix factors in G1 movement commands +#endif + +// Offset of the extruders (uncomment if using more than one and relying on firmware to position when changing). +// The offset has to be X=0, Y=0 for the extruder 0 hotend (default extruder). +// For the other hotends it is their distance from the extruder 0 hotend. +//#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis +//#define HOTEND_OFFSET_Y {0.0, 5.00} // (in mm) for each extruder, offset of the hotend on the Y axis + +// @section machine + +/** + * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN + * + * 0 = No Power Switch + * 1 = ATX + * 2 = X-Box 360 203Watts (the blue wire connected to PS_ON and the red wire to VCC) + * + * :{ 0:'No power switch', 1:'ATX', 2:'X-Box 360' } + */ +#define POWER_SUPPLY 1 + +#if POWER_SUPPLY > 0 + // Enable this option to leave the PSU off at startup. + // Power to steppers and heaters will need to be turned on with M80. + //#define PS_DEFAULT_OFF +#endif + +// @section temperature + +//=========================================================================== +//============================= Thermal Settings ============================ +//=========================================================================== + +/** + * --NORMAL IS 4.7kohm PULLUP!-- 1kohm pullup can be used on hotend sensor, using correct resistor and table + * + * Temperature sensors available: + * + * -3 : thermocouple with MAX31855 (only for sensor 0) + * -2 : thermocouple with MAX6675 (only for sensor 0) + * -1 : thermocouple with AD595 + * 0 : not used + * 1 : 100k thermistor - best choice for EPCOS 100k (4.7k pullup) + * 2 : 200k thermistor - ATC Semitec 204GT-2 (4.7k pullup) + * 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 (Used in ParCan & J-Head) (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) + * 71 : 100k Honeywell thermistor 135-104LAF-J01 (4.7k pullup) + * 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) + * 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" + * 20 : the PT100 circuit found in the Ultimainboard V2.x + * 60 : 100k Maker's Tool Works Kapton Bed Thermistor beta=3950 + * 66 : 4.7M High Temperature thermistor from Dyze Design + * 70 : the 100K thermistor found in the bq Hephestos 2 + * 75 : 100k Generic Silicon Heat Pad with NTC 100K MGB18-104F39050L32 thermistor + * + * 1k ohm pullup tables - This is atypical, and requires changing out the 4.7k pullup for 1k. + * (but gives greater accuracy and more stable PID) + * 51 : 100k thermistor - EPCOS (1k pullup) + * 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 + * 1010 : Pt1000 with 1k pullup (non standard) + * 147 : Pt100 with 4k7 pullup + * 110 : Pt100 with 1k pullup (non standard) + * + * Use these for Testing or Development purposes. NEVER for production machine. + * 998 : Dummy Table that ALWAYS reads 25°C or the temperature defined below. + * 999 : Dummy Table that ALWAYS reads 100°C or the temperature defined below. + * + * :{ '0': "Not used", '1':"100k / 4.7k - EPCOS", '2':"200k / 4.7k - ATC Semitec 204GT-2", '3':"Mendel-parts / 4.7k", '4':"10k !! do not use for a hotend. Bad resolution at high temp. !!", '5':"100K / 4.7k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '6':"100k / 4.7k EPCOS - Not as accurate as Table 1", '7':"100k / 4.7k Honeywell 135-104LAG-J01", '8':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT", '9':"100k / 4.7k GE Sensing AL03006-58.2K-97-G1", '10':"100k / 4.7k RS 198-961", '11':"100k / 4.7k beta 3950 1%", '12':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT (calibrated for Makibox hot bed)", '13':"100k Hisens 3950 1% up to 300°C for hotend 'Simple ONE ' & hotend 'All In ONE'", '20':"PT100 (Ultimainboard V2.x)", '51':"100k / 1k - EPCOS", '52':"200k / 1k - ATC Semitec 204GT-2", '55':"100k / 1k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '60':"100k Maker's Tool Works Kapton Bed Thermistor beta=3950", '66':"Dyze Design 4.7M High Temperature thermistor", '70':"the 100K thermistor found in the bq Hephestos 2", '71':"100k / 4.7k Honeywell 135-104LAF-J01", '147':"Pt100 / 4.7k", '1047':"Pt1000 / 4.7k", '110':"Pt100 / 1k (non-standard)", '1010':"Pt1000 / 1k (non standard)", '-3':"Thermocouple + MAX31855 (only for sensor 0)", '-2':"Thermocouple + MAX6675 (only for sensor 0)", '-1':"Thermocouple + AD595",'998':"Dummy 1", '999':"Dummy 2" } + */ +#define TEMP_SENSOR_0 7 +#define TEMP_SENSOR_1 7 +#define TEMP_SENSOR_2 0 +#define TEMP_SENSOR_3 0 +#define TEMP_SENSOR_4 0 +#define TEMP_SENSOR_BED 7 + +// Dummy thermistor constant temperature readings, for use with 998 and 999 +#define DUMMY_THERMISTOR_998_VALUE 25 +#define DUMMY_THERMISTOR_999_VALUE 100 + +// 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 +#define MAX_REDUNDANT_TEMP_SENSOR_DIFF 10 + +// Extruder temperature must be close to target for this long before M109 returns success +#define TEMP_RESIDENCY_TIME 10 // (seconds) +#define TEMP_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// Bed temperature must be close to target for this long before M190 returns success +#define TEMP_BED_RESIDENCY_TIME 0 // (seconds) +#define TEMP_BED_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_BED_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// The minimal temperature defines the temperature below which the heater will not be enabled It is used +// to check that the wiring to the thermistor is not broken. +// Otherwise this would lead to the heater being powered on all the time. +#define HEATER_0_MINTEMP 5 +#define HEATER_1_MINTEMP 5 +#define HEATER_2_MINTEMP 5 +#define HEATER_3_MINTEMP 5 +#define HEATER_4_MINTEMP 5 +#define BED_MINTEMP 5 + +// When temperature exceeds max temp, your heater will be switched off. +// This feature exists to protect your hotend from overheating accidentally, but *NOT* from thermistor short/failure! +// You should use MINTEMP for thermistor short/failure protection. +#define HEATER_0_MAXTEMP 250 +#define HEATER_1_MAXTEMP 250 +#define HEATER_2_MAXTEMP 250 +#define HEATER_3_MAXTEMP 250 +#define HEATER_4_MAXTEMP 250 +#define BED_MAXTEMP 150 + +//=========================================================================== +//============================= PID Settings ================================ +//=========================================================================== +// PID Tuning Guide here: http://reprap.org/wiki/PID_Tuning + +// Comment the following line to disable PID and enable bang-bang. +#define PIDTEMP +#define BANG_MAX 70 // limits current to nozzle while in bang-bang mode; 255=full current +#define PID_MAX 74 // limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#if ENABLED(PIDTEMP) + //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. + //#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 16 // 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. + #define K1 0.95 //smoothing factor within the PID + + // If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it + // Buda 2.0 on 24V + #define DEFAULT_Kp 6 + #define DEFAULT_Ki .3 + #define DEFAULT_Kd 125 + + // Buda 2.0 on 12V + //#define DEFAULT_Kp 22.2 + //#define DEFAULT_Ki 1.01 + //#define DEFAULT_Kd 114 + + // 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 + +#endif // PIDTEMP + +//=========================================================================== +//============================= PID > Bed Temperature Control =============== +//=========================================================================== +// Select PID or bang-bang with PIDTEMPBED. If bang-bang, BED_LIMIT_SWITCHING will enable hysteresis +// +// Uncomment this to enable PID on the bed. It uses the same frequency PWM as the extruder. +// If your PID_dT is the default, and correct for your hardware/configuration, that means 7.689Hz, +// which is fine for driving a square wave into a resistive load and does not significantly impact you FET heating. +// This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W heater. +// If your configuration is significantly different than this and you don't understand the issues involved, you probably +// shouldn't use bed PID until someone else verifies your hardware works. +// If this is enabled, find your own PID constants below. +#define PIDTEMPBED + +//#define BED_LIMIT_SWITCHING + +// This sets the max power delivered to the bed, and replaces the HEATER_BED_DUTY_CYCLE_DIVIDER option. +// all forms of bed control obey this (PID, bang-bang, bang-bang with hysteresis) +// setting this to anything other than 255 enables a form of PWM to the bed just like HEATER_BED_DUTY_CYCLE_DIVIDER did, +// so you shouldn't use it unless you are OK with PWM on your bed. (see the comment on enabling PIDTEMPBED) +#define MAX_BED_POWER 206 // limits duty cycle to bed; 255=full current + +#if ENABLED(PIDTEMPBED) + + //#define PID_BED_DEBUG // Sends debug data to the serial port. + + //24V 360W silicone heater from NPH on 3mm borosilicate (TAZ 2.2+) + #define DEFAULT_bedKp 20 + #define DEFAULT_bedKi 5 + #define DEFAULT_bedKd 275 + + //12v 400W silicone heater from QUDB into 3mm borosilicate (TAZ 1.0+) + //from pidautotune + //#define DEFAULT_bedKp 650 + //#define DEFAULT_bedKi 60 + //#define DEFAULT_bedKd 1800 + + //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 + +// @section extruder + +// This option prevents extrusion if the temperature is below EXTRUDE_MINTEMP. +// It also enables the M302 command to set the minimum extrusion temperature +// or to allow moving the extruder regardless of the hotend temperature. +// *** IT IS HIGHLY RECOMMENDED TO LEAVE THIS OPTION ENABLED! *** +#define PREVENT_COLD_EXTRUSION +#define EXTRUDE_MINTEMP 170 + +// This option prevents a single extrusion longer than EXTRUDE_MAXLENGTH. +// Note that for Bowden Extruders a too-small value here may prevent loading. +#define PREVENT_LENGTHY_EXTRUDE +#define EXTRUDE_MAXLENGTH 200 + +//=========================================================================== +//======================== Thermal Runaway Protection ======================= +//=========================================================================== + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * If you get "Thermal Runaway" or "Heating failed" errors the + * details can be tuned in Configuration_adv.h + */ + +#define THERMAL_PROTECTION_HOTENDS // Enable thermal protection for all extruders +#define THERMAL_PROTECTION_BED // Enable thermal protection for the heated bed + +//=========================================================================== +//============================= Mechanical Settings ========================= +//=========================================================================== + +// @section machine + +// Uncomment one of these options to enable CoreXY, CoreXZ, or CoreYZ kinematics +// either in the usual order or reversed +//#define COREXY +//#define COREXZ +//#define COREYZ +//#define COREYX +//#define COREZX +//#define COREZY + +//=========================================================================== +//============================== Endstop Settings =========================== +//=========================================================================== + +// @section homing + +// Specify here all the endstop connectors that are connected to any endstop or probe. +// Almost all printers will be using one per axis. Probes will use one or more of the +// extra connectors. Leave undefined any used for non-endstop and non-probe purposes. +#define USE_XMIN_PLUG +#define USE_YMIN_PLUG +#define USE_ZMIN_PLUG +//#define USE_XMAX_PLUG +//#define USE_YMAX_PLUG +//#define USE_ZMAX_PLUG + +// coarse Endstop Settings +#define ENDSTOPPULLUPS // Comment this out (using // at the start of the line) to disable the endstop pullup resistors + +#if DISABLED(ENDSTOPPULLUPS) + // fine endstop settings: Individual pullups. will be ignored if ENDSTOPPULLUPS is defined + //#define ENDSTOPPULLUP_XMAX + //#define ENDSTOPPULLUP_YMAX + //#define ENDSTOPPULLUP_ZMAX + //#define ENDSTOPPULLUP_XMIN + //#define ENDSTOPPULLUP_YMIN + //#define ENDSTOPPULLUP_ZMIN + //#define ENDSTOPPULLUP_ZMIN_PROBE +#endif + +// Mechanical endstop with COM to ground and NC to Signal uses "false" here (most common setup). +#define X_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Y_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define X_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Y_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MIN_PROBE_ENDSTOP_INVERTING true // set to true to invert the logic of the probe. + +// Enable this feature if all enabled endstop pins are interrupt-capable. +// This will remove the need to poll the interrupt pins, saving many CPU cycles. +//#define ENDSTOP_INTERRUPTS_FEATURE + +//============================================================================= +//============================== Movement Settings ============================ +//============================================================================= +// @section motion + +/** + * Default Settings + * + * These settings can be reset by M502 + * + * Note that if EEPROM is enabled, saved values will override these. + */ + +/** + * With this option each E stepper can have its own factors for the + * following movement settings. If fewer factors are given than the + * total number of extruders, the last value applies to the rest. + */ +//#define DISTINCT_E_FACTORS + +/** + * Default Axis Steps Per Unit (steps/mm) + * Override with M92 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_AXIS_STEPS_PER_UNIT { 100.5, 100.5, 400, 850 } + +/** + * Default Max Feed Rate (mm/s) + * Override with M203 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_FEEDRATE { 800, 800, 8, 50 } + +/** + * Default Max Acceleration (change/s) change = mm/s + * (Maximum start speed for accelerated moves) + * Override with M201 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_ACCELERATION { 9000, 9000, 100, 10000 } + +/** + * Default Acceleration (change/s) change = mm/s + * Override with M204 + * + * M204 P Acceleration + * M204 R Retract Acceleration + * M204 T Travel Acceleration + */ +#define DEFAULT_ACCELERATION 500 // X, Y, Z and E acceleration for printing moves +#define DEFAULT_RETRACT_ACCELERATION 3000 // E acceleration for retracts +#define DEFAULT_TRAVEL_ACCELERATION 3000 // X, Y, Z acceleration for travel (non printing) moves + +/** + * Default Jerk (mm/s) + * Override with M205 X Y Z E + * + * "Jerk" specifies the minimum speed change that requires acceleration. + * When changing speed and direction, if the difference is less than the + * value set here, it may happen instantaneously. + */ +#define DEFAULT_XJERK 8.0 +#define DEFAULT_YJERK 8.0 +#define DEFAULT_ZJERK 0.4 +#define DEFAULT_EJERK 10.0 + +//=========================================================================== +//============================= Z Probe Options ============================= +//=========================================================================== +// @section probes + +// +// See http://marlinfw.org/configuration/probes.html +// + +/** + * Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + * + * Enable this option for a probe connected to the Z Min endstop pin. + */ +#define Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + +/** + * Z_MIN_PROBE_ENDSTOP + * + * Enable this option for a probe connected to any pin except Z-Min. + * (By default Marlin assumes the Z-Max endstop pin.) + * To use a custom Z Probe pin, set Z_MIN_PROBE_PIN below. + * + * - The simplest option is to use a free endstop connector. + * - Use 5V for powered (usually inductive) sensors. + * + * - RAMPS 1.3/1.4 boards may use the 5V, GND, and Aux4->D32 pin: + * - For simple switches connect... + * - normally-closed switches to GND and D32. + * - normally-open switches to 5V and D32. + * + * WARNING: Setting the wrong pin may have unexpected and potentially + * disastrous consequences. Use with caution and do your homework. + * + */ +//#define Z_MIN_PROBE_ENDSTOP + +/** + * Probe Type + * + * Allen Key Probes, Servo Probes, Z-Sled Probes, FIX_MOUNTED_PROBE, etc. + * Activate one of these to use Auto Bed Leveling below. + */ + +/** + * The "Manual Probe" provides a means to do "Auto" Bed Leveling without a probe. + * Use G29 repeatedly, adjusting the Z height at each point with movement commands + * or (with LCD_BED_LEVELING) the LCD controller. + */ +//#define PROBE_MANUALLY + +/** + * A Fix-Mounted Probe either doesn't deploy or needs manual deployment. + * (e.g., an inductive probe or a nozzle-based probe-switch.) + */ +#define FIX_MOUNTED_PROBE + +/** + * Z Servo Probe, such as an endstop switch on a rotating arm. + */ +//#define Z_ENDSTOP_SERVO_NR 0 // Defaults to SERVO 0 connector. +//#define Z_SERVO_ANGLES {70,0} // Z Servo Deploy and Stow angles + +/** + * The BLTouch probe uses a Hall effect sensor and emulates a servo. + */ +//#define BLTOUCH +#if ENABLED(BLTOUCH) + //#define BLTOUCH_DELAY 375 // (ms) Enable and increase if needed +#endif + +/** + * Enable one or more of the following if probing seems unreliable. + * Heaters and/or fans can be disabled during probing to minimize electrical + * noise. A delay can also be added to allow noise and vibration to settle. + * These options are most useful for the BLTouch probe, but may also improve + * readings with inductive probes and piezo sensors. + */ +//#define PROBING_HEATERS_OFF // Turn heaters off when probing +//#define PROBING_FANS_OFF // Turn fans off when probing +//#define DELAY_BEFORE_PROBING 200 // (ms) To prevent vibrations from triggering piezo sensors + +// A probe that is deployed and stowed with a solenoid pin (SOL1_PIN) +//#define SOLENOID_PROBE + +// A sled-mounted probe like those designed by Charles Bell. +//#define Z_PROBE_SLED +//#define SLED_DOCKING_OFFSET 5 // The extra distance the X axis must travel to pickup the sled. 0 should be fine but you can push it further if you'd like. + +// +// For Z_PROBE_ALLEN_KEY see the Delta example configurations. +// + +/** + * Z Probe to nozzle (X,Y) offset, relative to (0, 0). + * X and Y offsets must be integers. + * + * In the following example the X and Y offsets are both positive: + * #define X_PROBE_OFFSET_FROM_EXTRUDER 10 + * #define Y_PROBE_OFFSET_FROM_EXTRUDER 10 + * + * +-- BACK ---+ + * | | + * L | (+) P | R <-- probe (20,20) + * E | | I + * F | (-) N (+) | G <-- nozzle (10,10) + * T | | H + * | (-) | T + * | | + * O-- FRONT --+ + * (0,0) + */ +#define X_PROBE_OFFSET_FROM_EXTRUDER -25 // X offset: -left +right [of the nozzle] +#define Y_PROBE_OFFSET_FROM_EXTRUDER -29 // Y offset: -front +behind [the nozzle] +#define Z_PROBE_OFFSET_FROM_EXTRUDER -12.35 // Z offset: -below +above [the nozzle] + +// X and Y axis travel speed (mm/m) between probes +#define XY_PROBE_SPEED 8000 + +// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +#define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z + +// Speed for the "accurate" probe of each point +#define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) + +// Use double touch for probing +//#define PROBE_DOUBLE_TOUCH + +/** + * Z probes require clearance when deploying, stowing, and moving between + * probe points to avoid hitting the bed and other hardware. + * Servo-mounted probes require extra space for the arm to rotate. + * Inductive probes need space to keep from triggering early. + * + * Use these settings to specify the distance (mm) to raise the probe (or + * lower the bed). The values set here apply over and above any (negative) + * probe Z Offset set with Z_PROBE_OFFSET_FROM_EXTRUDER, M851, or the LCD. + * Only integer values >= 1 are valid here. + * + * Example: `M851 Z-5` with a CLEARANCE of 4 => 9mm from bed to nozzle. + * But: `M851 Z+1` with a CLEARANCE of 2 => 2mm from bed to nozzle. + */ +#define Z_CLEARANCE_DEPLOY_PROBE 15 // Z Clearance for Deploy/Stow +#define Z_CLEARANCE_BETWEEN_PROBES 5 // Z Clearance between probe points + +// For M851 give a range for adjusting the Z probe offset +#define Z_PROBE_OFFSET_RANGE_MIN -20 +#define Z_PROBE_OFFSET_RANGE_MAX 20 + +// Enable the M48 repeatability test to test probe accuracy +//#define Z_MIN_PROBE_REPEATABILITY_TEST + +// For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1 +// :{ 0:'Low', 1:'High' } +#define X_ENABLE_ON 0 +#define Y_ENABLE_ON 0 +#define Z_ENABLE_ON 0 +#define E_ENABLE_ON 0 // For all extruders + +// Disables axis stepper immediately when it's not being used. +// 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 +//#define DISABLE_REDUCED_ACCURACY_WARNING + +// @section extruder + +#define DISABLE_E false // For all extruders +#define DISABLE_INACTIVE_EXTRUDER true // Keep only the active extruder enabled. + +// @section machine + +// Invert the stepper direction. Change (or reverse the motor connector) if an axis goes the wrong way. +#define INVERT_X_DIR false +#define INVERT_Y_DIR true +#define INVERT_Z_DIR false + +// Enable this option for Toshiba stepper drivers +//#define CONFIG_STEPPERS_TOSHIBA + +// @section extruder + +// For direct drive extruder v9 set to true, for geared extruder set to false. +#define INVERT_E0_DIR true +#define INVERT_E1_DIR true +#define INVERT_E2_DIR true +#define INVERT_E3_DIR true +#define INVERT_E4_DIR true + +// @section homing + +//#define NO_MOTION_BEFORE_HOMING // Inhibit movement until all axes have been homed + +//#define Z_HOMING_HEIGHT 4 // (in mm) Minimal z height before homing (G28) for Z clearance above the bed, clamps, ... + // Be sure you have this distance over your Z_MAX_POS in case. + +// Direction of endstops when homing; 1=MAX, -1=MIN +// :[-1,1] +#define X_HOME_DIR -1 +#define Y_HOME_DIR -1 +#define Z_HOME_DIR -1 + +// @section machine + +// The size of the print bed +#define X_BED_SIZE 298 +#define Y_BED_SIZE 275 + +// Travel limits (mm) after homing, corresponding to endstop positions. +#define X_MIN_POS 0 +#define Y_MIN_POS 0 +#define Z_MIN_POS 0 +#define X_MAX_POS X_BED_SIZE +#define Y_MAX_POS Y_BED_SIZE +#define Z_MAX_POS 250 + +// If enabled, axes won't move below MIN_POS in response to movement commands. +#define MIN_SOFTWARE_ENDSTOPS +// If enabled, axes won't move above MAX_POS in response to movement commands. +#define MAX_SOFTWARE_ENDSTOPS + +/** + * Filament Runout Sensor + * A mechanical or opto endstop is used to check for the presence of filament. + * + * RAMPS-based boards use SERVO3_PIN. + * For other boards you may need to define FIL_RUNOUT_PIN. + * By default the firmware assumes HIGH = has filament, LOW = ran out + */ +//#define FILAMENT_RUNOUT_SENSOR +#if ENABLED(FILAMENT_RUNOUT_SENSOR) + #define FIL_RUNOUT_INVERTING false // set to true to invert the logic of the sensor. + #define ENDSTOPPULLUP_FIL_RUNOUT // Uncomment to use internal pullup for filament runout pins if the sensor is defined. + #define FILAMENT_RUNOUT_SCRIPT "M600" +#endif + +//=========================================================================== +//=============================== Bed Leveling ============================== +//=========================================================================== +// @section bedlevel + +/** + * Choose one of the options below to enable G29 Bed Leveling. The parameters + * and behavior of G29 will change depending on your selection. + * + * If using a Probe for Z Homing, enable Z_SAFE_HOMING also! + * + * - AUTO_BED_LEVELING_3POINT + * Probe 3 arbitrary points on the bed (that aren't collinear) + * You specify the XY coordinates of all 3 points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_LINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_BILINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a mesh, best for large or uneven beds. + * + * - AUTO_BED_LEVELING_UBL (Unified Bed Leveling) + * A comprehensive bed leveling system combining the features and benefits + * of other systems. UBL also includes integrated Mesh Generation, Mesh + * Validation and Mesh Editing systems. Currently, UBL is only checked out + * for Cartesian Printers. That said, it was primarily designed to correct + * poor quality Delta Printers. If you feel adventurous and have a Delta, + * please post an issue if something doesn't work correctly. Initially, + * you will need to set a reduced bed size so you have a rectangular area + * to test on. + * + * - MESH_BED_LEVELING + * Probe a grid manually + * The result is a mesh, suitable for large or uneven beds. (See BILINEAR.) + * For machines without a probe, Mesh Bed Leveling provides a method to perform + * leveling in steps so you can manually adjust the Z height at each grid-point. + * With an LCD controller the process is guided step-by-step. + */ +//#define AUTO_BED_LEVELING_3POINT +//#define AUTO_BED_LEVELING_LINEAR +//#define AUTO_BED_LEVELING_BILINEAR +//#define AUTO_BED_LEVELING_UBL +//#define MESH_BED_LEVELING + +/** + * Enable detailed logging of G28, G29, M48, etc. + * Turn on with the command 'M111 S32'. + * NOTE: Requires a lot of PROGMEM! + */ +//#define DEBUG_LEVELING_FEATURE + +#if ENABLED(MESH_BED_LEVELING) || ENABLED(AUTO_BED_LEVELING_BILINEAR) || ENABLED(AUTO_BED_LEVELING_UBL) + // Gradually reduce leveling correction until a set height is reached, + // at which point movement will be level to the machine's XY plane. + // The height can be set with M420 Z + #define ENABLE_LEVELING_FADE_HEIGHT +#endif + +#if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Set the number of grid points per dimension. + #define GRID_MAX_POINTS_X 3 + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + // Set the boundaries for probing (where the probe can reach). + #define LEFT_PROBE_BED_POSITION 15 + #define RIGHT_PROBE_BED_POSITION 170 + #define FRONT_PROBE_BED_POSITION 20 + #define BACK_PROBE_BED_POSITION 170 + + // The Z probe minimum outer margin (to validate G29 parameters). + #define MIN_PROBE_EDGE 10 + + // Probe along the Y axis, advancing X after each column + //#define PROBE_Y_FIRST + + #if ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Beyond the probed grid, continue the implied tilt? + // Default is to maintain the height of the nearest edge. + //#define EXTRAPOLATE_BEYOND_GRID + + // + // Experimental Subdivision of the grid by Catmull-Rom method. + // Synthesizes intermediate points to produce a more detailed mesh. + // + //#define ABL_BILINEAR_SUBDIVISION + #if ENABLED(ABL_BILINEAR_SUBDIVISION) + // Number of subdivisions between probe points + #define BILINEAR_SUBDIVISIONS 3 + #endif + + #endif + +#elif ENABLED(AUTO_BED_LEVELING_3POINT) + + // 3 arbitrary points to probe. + // A simple cross-product is used to estimate the plane of the bed. + #define ABL_PROBE_PT_1_X 15 + #define ABL_PROBE_PT_1_Y 180 + #define ABL_PROBE_PT_2_X 15 + #define ABL_PROBE_PT_2_Y 20 + #define ABL_PROBE_PT_3_X 170 + #define ABL_PROBE_PT_3_Y 20 + +#elif ENABLED(AUTO_BED_LEVELING_UBL) + + //=========================================================================== + //========================= Unified Bed Leveling ============================ + //=========================================================================== + + #define UBL_MESH_INSET 1 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 10 // Don't use more than 15 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + #define UBL_PROBE_PT_1_X 39 // Probing points for 3-Point leveling of the mesh + #define UBL_PROBE_PT_1_Y 180 + #define UBL_PROBE_PT_2_X 39 + #define UBL_PROBE_PT_2_Y 20 + #define UBL_PROBE_PT_3_X 180 + #define UBL_PROBE_PT_3_Y 20 + + #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation + #define UBL_MESH_EDIT_MOVES_Z // Sophisticated users prefer no movement of nozzle + +#elif ENABLED(MESH_BED_LEVELING) + + //=========================================================================== + //=================================== Mesh ================================== + //=========================================================================== + + #define MESH_INSET 10 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 3 // Don't use more than 7 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + //#define MESH_G28_REST_ORIGIN // After homing all axes ('G28' or 'G28 XYZ') rest Z at Z_MIN_POS + +#endif // BED_LEVELING + +/** + * Use the LCD controller for bed leveling + * Requires MESH_BED_LEVELING or PROBE_MANUALLY + */ +//#define LCD_BED_LEVELING + +#if ENABLED(LCD_BED_LEVELING) + #define MBL_Z_STEP 0.025 // Step size while manually probing Z axis. + #define LCD_PROBE_Z_RANGE 4 // Z Range centered on Z_MIN_POS for LCD Z adjustment +#endif + +// Add a menu item to move between bed corners for manual bed adjustment +//#define LEVEL_BED_CORNERS + +/** + * Commands to execute at the end of G29 probing. + * Useful to retract or move the Z probe out of the way. + */ +//#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) +//#define BED_CENTER_AT_0_0 + +// Manually set the home position. Leave these undefined for automatic settings. +// For DELTA this is the top-center of the Cartesian print volume. +//#define MANUAL_X_HOME_POS 0 +//#define MANUAL_Y_HOME_POS 0 +//#define MANUAL_Z_HOME_POS 0 + +// Use "Z Safe Homing" to avoid homing with a Z probe outside the bed area. +// +// With this feature enabled: +// +// - 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). +// - 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 axis (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). +#endif + +// Homing speeds (mm/m) +#define HOMING_FEEDRATE_XY (50*60) +#define HOMING_FEEDRATE_Z (8*60) + +//============================================================================= +//============================= Additional Features =========================== +//============================================================================= + +// @section extras + +// +// EEPROM +// +// The microcontroller can store settings in the EEPROM, e.g. max velocity... +// M500 - stores parameters in EEPROM +// M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily). +// M502 - reverts to the default "factory settings". You still need to store them in EEPROM afterwards if you want to. +// +#define EEPROM_SETTINGS // Enable for M500 and M501 commands +//#define DISABLE_M503 // Saves ~2700 bytes of PROGMEM. Disable for release! +#define EEPROM_CHITCHAT // Give feedback on EEPROM commands. Disable to save PROGMEM. + +// +// Host Keepalive +// +// When enabled Marlin will send a busy status message to the host +// every couple of seconds when it can't accept commands. +// +#define HOST_KEEPALIVE_FEATURE // Disable this if your host doesn't like keepalive messages +#define DEFAULT_KEEPALIVE_INTERVAL 2 // Number of seconds between "busy" messages. Set with M113. +#define BUSY_WHILE_HEATING // Some hosts require "busy" messages even during heating + +// +// M100 Free Memory Watcher +// +//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose + +// +// G20/G21 Inch mode support +// +//#define INCH_MODE_SUPPORT + +// +// M149 Set temperature units support +// +//#define TEMPERATURE_UNITS_SUPPORT + +// @section temperature + +// Preheat Constants +#define PREHEAT_1_TEMP_HOTEND 180 +#define PREHEAT_1_TEMP_BED 70 +#define PREHEAT_1_FAN_SPEED 0 // Value from 0 to 255 + +#define PREHEAT_2_TEMP_HOTEND 230 +#define PREHEAT_2_TEMP_BED 110 +#define PREHEAT_2_FAN_SPEED 0 // Value from 0 to 255 + +/** + * Nozzle Park -- EXPERIMENTAL + * + * Park the nozzle at the given XYZ position on idle or G27. + * + * The "P" parameter controls the action applied to the Z axis: + * + * P0 (Default) If Z is below park Z raise the nozzle. + * P1 Raise the nozzle always to Z-park height. + * P2 Raise the nozzle by Z-park amount, limited to Z_MAX_POS. + */ +//#define NOZZLE_PARK_FEATURE + +#if ENABLED(NOZZLE_PARK_FEATURE) + // Specify a park position as { X, Y, Z } + #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 } +#endif + +/** + * Clean Nozzle Feature -- EXPERIMENTAL + * + * Adds the G12 command to perform a nozzle cleaning process. + * + * Parameters: + * P Pattern + * S Strokes / Repetitions + * T Triangles (P1 only) + * + * Patterns: + * P0 Straight line (default). This process requires a sponge type material + * at a fixed bed location. "S" specifies strokes (i.e. back-forth motions) + * between the start / end points. + * + * P1 Zig-zag pattern between (X0, Y0) and (X1, Y1), "T" specifies the + * number of zig-zag triangles to do. "S" defines the number of strokes. + * Zig-zags are done in whichever is the narrower dimension. + * For example, "G12 P1 S1 T3" will execute: + * + * -- + * | (X0, Y1) | /\ /\ /\ | (X1, Y1) + * | | / \ / \ / \ | + * A | | / \ / \ / \ | + * | | / \ / \ / \ | + * | (X0, Y0) | / \/ \/ \ | (X1, Y0) + * -- +--------------------------------+ + * |________|_________|_________| + * T1 T2 T3 + * + * P2 Circular pattern with middle at NOZZLE_CLEAN_CIRCLE_MIDDLE. + * "R" specifies the radius. "S" specifies the stroke count. + * Before starting, the nozzle moves to NOZZLE_CLEAN_START_POINT. + * + * Caveats: The ending Z should be the same as starting Z. + * Attention: EXPERIMENTAL. G-code arguments may change. + * + */ +//#define NOZZLE_CLEAN_FEATURE + +#if ENABLED(NOZZLE_CLEAN_FEATURE) + // Default number of pattern repetitions + #define NOZZLE_CLEAN_STROKES 12 + + // Default number of triangles + #define NOZZLE_CLEAN_TRIANGLES 3 + + // Specify positions as { X, Y, Z } + #define NOZZLE_CLEAN_START_POINT { 30, 30, (Z_MIN_POS + 1)} + #define NOZZLE_CLEAN_END_POINT {100, 60, (Z_MIN_POS + 1)} + + // Circular pattern radius + #define NOZZLE_CLEAN_CIRCLE_RADIUS 6.5 + // Circular pattern circle fragments number + #define NOZZLE_CLEAN_CIRCLE_FN 10 + // Middle point of circle + #define NOZZLE_CLEAN_CIRCLE_MIDDLE NOZZLE_CLEAN_START_POINT + + // Moves the nozzle to the initial position + #define NOZZLE_CLEAN_GOBACK +#endif + +/** + * Print Job Timer + * + * Automatically start and stop the print job timer on M104/M109/M190. + * + * M104 (hotend, no wait) - high temp = none, low temp = stop timer + * M109 (hotend, wait) - high temp = start timer, low temp = stop timer + * M190 (bed, wait) - high temp = start timer, low temp = none + * + * The timer can also be controlled with the following commands: + * + * M75 - Start the print job timer + * M76 - Pause the print job timer + * M77 - Stop the print job timer + */ +#define PRINTJOB_TIMER_AUTOSTART + +/** + * Print Counter + * + * Track statistical data such as: + * + * - Total print jobs + * - Total successful print jobs + * - Total failed print jobs + * - Total time printing + * + * View the current statistics with M78. + */ +//#define PRINTCOUNTER + +//============================================================================= +//============================= LCD and SD support ============================ +//============================================================================= + +// @section lcd + +/** + * LCD LANGUAGE + * + * Select the language to display on the LCD. These languages are available: + * + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, + * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * tr, uk, zh_CN, zh_TW, test + * + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + */ +#define LCD_LANGUAGE en + +/** + * LCD Character Set + * + * Note: This option is NOT applicable to Graphical Displays. + * + * All character-based LCDs provide ASCII plus one of these + * language extensions: + * + * - JAPANESE ... the most common + * - WESTERN ... with more accented characters + * - CYRILLIC ... for the Russian language + * + * To determine the language extension installed on your controller: + * + * - Compile and upload with LCD_LANGUAGE set to 'test' + * - 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 + * + * :['JAPANESE', 'WESTERN', 'CYRILLIC'] + */ +#define DISPLAY_CHARSET_HD44780 JAPANESE + +/** + * LCD TYPE + * + * Enable ULTRA_LCD for a 16x2, 16x4, 20x2, or 20x4 character-based LCD. + * Enable DOGLCD for a 128x64 (ST7565R) Full Graphical Display. + * (These options will be enabled automatically for most displays.) + * + * IMPORTANT: The U8glib library is required for Full Graphic Display! + * https://github.com/olikraus/U8glib_Arduino + */ +//#define ULTRA_LCD // Character based +//#define DOGLCD // Full graphics display + +/** + * SD CARD + * + * 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 + +/** + * SD CARD: SPI SPEED + * + * Enable one of the following items for a slower SPI transfer speed. + * This may be required to resolve "volume init" errors. + */ +//#define SPI_SPEED SPI_HALF_SPEED +//#define SPI_SPEED SPI_QUARTER_SPEED +//#define SPI_SPEED SPI_EIGHTH_SPEED + +/** + * SD CARD: ENABLE CRC + * + * Use CRC checks and retries on the SD communication. + */ +//#define SD_CHECK_AND_RETRY + +// +// ENCODER SETTINGS +// +// This option overrides the default number of encoder pulses needed to +// produce one step. Should be increased for high-resolution encoders. +// +#define ENCODER_PULSES_PER_STEP 2 + +// +// Use this option to override the number of step signals required to +// move between next/prev menu items. +// +#define ENCODER_STEPS_PER_MENU_ITEM 1 + +/** + * Encoder Direction Options + * + * Test your encoder's behavior first with both options disabled. + * + * Reversed Value Edit and Menu Nav? Enable REVERSE_ENCODER_DIRECTION. + * Reversed Menu Navigation only? Enable REVERSE_MENU_DIRECTION. + * Reversed Value Editing only? Enable BOTH options. + */ + +// +// This option reverses the encoder direction everywhere. +// +// Set this option if CLOCKWISE causes values to DECREASE +// +//#define REVERSE_ENCODER_DIRECTION + +// +// This option reverses the encoder direction for navigating LCD menus. +// +// If CLOCKWISE normally moves DOWN this makes it go UP. +// If CLOCKWISE normally moves UP this makes it go DOWN. +// +//#define REVERSE_MENU_DIRECTION + +// +// Individual Axis Homing +// +// Add individual axis homing items (Home X, Home Y, and Home Z) to the LCD menu. +// +//#define INDIVIDUAL_AXIS_HOMING_MENU + +// +// SPEAKER/BUZZER +// +// If you have a speaker that can produce tones, enable it here. +// By default Marlin assumes you have a buzzer with a fixed frequency. +// +//#define SPEAKER + +// +// The duration and frequency for the UI feedback sound. +// Set these to 0 to disable audio feedback in the LCD menus. +// +// Note: Test audio output with the G-Code: +// M300 S P +// +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 +//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 + +// +// CONTROLLER TYPE: Standard +// +// Marlin supports a wide variety of controllers. +// Enable one of the following options to specify your controller. +// + +// +// ULTIMAKER Controller. +// +//#define ULTIMAKERCONTROLLER + +// +// ULTIPANEL as seen on Thingiverse. +// +//#define ULTIPANEL + +// +// PanelOne from T3P3 (via RAMPS 1.4 AUX2/AUX3) +// http://reprap.org/wiki/PanelOne +// +//#define PANEL_ONE + +// +// MaKr3d Makr-Panel with graphic controller and SD support. +// http://reprap.org/wiki/MaKr3d_MaKrPanel +// +//#define MAKRPANEL + +// +// ReprapWorld Graphical LCD +// https://reprapworld.com/?products_details&products_id/1218 +// +//#define REPRAPWORLD_GRAPHICAL_LCD + +// +// Activate one of these if you have a Panucatt Devices +// Viki 2.0 or mini Viki with Graphic LCD +// http://panucatt.com +// +//#define VIKI2 +//#define miniVIKI + +// +// Adafruit ST7565 Full Graphic Controller. +// https://github.com/eboston/Adafruit-ST7565-Full-Graphic-Controller/ +// +//#define ELB_FULL_GRAPHIC_CONTROLLER + +// +// RepRapDiscount Smart Controller. +// http://reprap.org/wiki/RepRapDiscount_Smart_Controller +// +// Note: Usually sold with a white PCB. +// +//#define REPRAP_DISCOUNT_SMART_CONTROLLER + +// +// GADGETS3D G3D LCD/SD Controller +// http://reprap.org/wiki/RAMPS_1.3/1.4_GADGETS3D_Shield_with_Panel +// +// Note: Usually sold with a blue PCB. +// +//#define G3D_PANEL + +// +// RepRapDiscount FULL GRAPHIC Smart Controller +// http://reprap.org/wiki/RepRapDiscount_Full_Graphic_Smart_Controller +// +#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER + +// +// MakerLab Mini Panel with graphic +// controller and SD support - http://reprap.org/wiki/Mini_panel +// +//#define MINIPANEL + +// +// RepRapWorld REPRAPWORLD_KEYPAD v1.1 +// http://reprapworld.com/?products_details&products_id=202&cPath=1591_1626 +// +// REPRAPWORLD_KEYPAD_MOVE_STEP sets how much should the robot move when a key +// is pressed, a value of 10.0 means 10mm per click. +// +//#define REPRAPWORLD_KEYPAD +//#define REPRAPWORLD_KEYPAD_MOVE_STEP 1.0 + +// +// RigidBot Panel V1.0 +// http://www.inventapart.com/ +// +//#define RIGIDBOT_PANEL + +// +// BQ LCD Smart Controller shipped by +// default with the BQ Hephestos 2 and Witbox 2. +// +//#define BQ_LCD_SMART_CONTROLLER + +// +// Cartesio UI +// http://mauk.cc/webshop/cartesio-shop/electronics/user-interface +// +//#define CARTESIO_UI + +// +// ANET_10 Controller supported displays. +// +//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. + // This LCD is known to be susceptible to electrical interference + // which scrambles the display. Pressing any button clears it up. +//#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 + // A clone of the RepRapDiscount full graphics display but with + // different pins/wiring (see pins_ANET_10.h). + +// +// LCD for Melzi Card with Graphical LCD +// +//#define LCD_FOR_MELZI + +// +// CONTROLLER TYPE: I2C +// +// Note: These controllers require the installation of Arduino's LiquidCrystal_I2C +// library. For more info: https://github.com/kiyoshigawa/LiquidCrystal_I2C +// + +// +// Elefu RA Board Control Panel +// http://www.elefu.com/index.php?route=product/product&product_id=53 +// +//#define RA_CONTROL_PANEL + +// +// Sainsmart YW Robot (LCM1602) LCD Display +// +// Note: This controller requires F.Malpartida's LiquidCrystal_I2C library +// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home +// +//#define LCD_I2C_SAINSMART_YWROBOT + +// +// Generic LCM1602 LCD adapter +// +//#define LCM1602 + +// +// PANELOLU2 LCD with status LEDs, +// separate encoder and click inputs. +// +// Note: This controller requires Arduino's LiquidTWI2 library v1.2.3 or later. +// For more info: https://github.com/lincomatic/LiquidTWI2 +// +// Note: The PANELOLU2 encoder click input can either be directly connected to +// a pin (if BTN_ENC defined to != -1) or read through I2C (when BTN_ENC == -1). +// +//#define LCD_I2C_PANELOLU2 + +// +// Panucatt VIKI LCD with status LEDs, +// integrated click & L/R/U/D buttons, separate encoder inputs. +// +//#define LCD_I2C_VIKI + +// +// SSD1306 OLED full graphics generic display +// +//#define U8GLIB_SSD1306 + +// +// SAV OLEd LCD module support using either SSD1306 or SH1106 based LCD modules +// +//#define SAV_3DGLCD +#if ENABLED(SAV_3DGLCD) + //#define U8GLIB_SSD1306 + #define U8GLIB_SH1106 +#endif + +// +// CONTROLLER TYPE: Shift register panels +// +// 2 wire Non-latching LCD SR from https://goo.gl/aJJ4sH +// LCD configuration: http://reprap.org/wiki/SAV_3D_LCD +// +//#define SAV_3DLCD + +// +// TinyBoy2 128x64 OLED / Encoder Panel +// +//#define OLED_PANEL_TINYBOY2 + +// +// Makeboard 3D Printer Parts 3D Printer Mini Display 1602 Mini Controller +// https://www.aliexpress.com/item/Micromake-Makeboard-3D-Printer-Parts-3D-Printer-Mini-Display-1602-Mini-Controller-Compatible-with-Ramps-1/32765887917.html +// +//#define MAKEBOARD_MINI_2_LINE_DISPLAY_1602 + +// +// MKS MINI12864 with graphic controller and SD support +// http://reprap.org/wiki/MKS_MINI_12864 +// +//#define MKS_MINI_12864 + +// +// Factory display for Creality CR-10 +// https://www.aliexpress.com/item/Universal-LCD-12864-3D-Printer-Display-Screen-With-Encoder-For-CR-10-CR-7-Model/32833148327.html +// +// This is RAMPS-compatible using a single 10-pin connector. +// (For CR-10 owners who want to replace the Melzi Creality board but retain the display) +// +//#define CR10_STOCKDISPLAY + +// +// MKS OLED 1.3" 128 × 64 FULL GRAPHICS CONTROLLER +// http://reprap.org/wiki/MKS_12864OLED +// +// Tiny, but very sharp OLED display +// +//#define MKS_12864OLED + +//============================================================================= +//=============================== Extra Features ============================== +//============================================================================= + +// @section extras + +// Increase the FAN PWM frequency. Removes the PWM noise but increases heating in the FET/Arduino +#define FAST_PWM_FAN + +// Use software PWM to drive the fan, as for the heaters. This uses a very low frequency +// which is not as annoying as with the hardware PWM. On the other hand, if this frequency +// is too low, you should also increment SOFT_PWM_SCALE. +//#define FAN_SOFT_PWM + +// Incrementing this by 1 will double the software PWM frequency, +// affecting heaters, and the fan if FAN_SOFT_PWM is enabled. +// However, control resolution will be halved for each increment; +// at zero value, there are 128 effective control positions. +#define SOFT_PWM_SCALE 0 + +// If SOFT_PWM_SCALE is set to a value higher than 0, dithering can +// be used to mitigate the associated resolution loss. If enabled, +// some of the PWM cycles are stretched so on average the desired +// duty cycle is attained. +//#define SOFT_PWM_DITHER + +// Temperature status LEDs that display the hotend and bed temperature. +// If all hotends, bed temperature, and target temperature are under 54C +// then the BLUE led is on. Otherwise the RED led is on. (1C hysteresis) +//#define TEMP_STAT_LEDS + +// M240 Triggers a camera by emulating a Canon RC-1 Remote +// Data from: http://www.doc-diy.net/photo/rc-1_hacked/ +//#define PHOTOGRAPH_PIN 23 + +// 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 + +// Support for BlinkM/CyzRgb +//#define BLINKM + +// Support for PCA9632 PWM LED driver +//#define PCA9632 + +/** + * RGB LED / LED Strip Control + * + * Enable support for an RGB LED connected to 5V digital pins, or + * an RGB Strip connected to MOSFETs controlled by digital pins. + * + * 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 overall brightness parameters is also available + * + * *** CAUTION *** + * LED Strips require a MOFSET 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! + * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino + * cannot handle such current, separate 5V power supply must be used + * *** CAUTION *** + * + * LED type. This options are mutualy exclusive. Uncomment only one. + * + */ +//#define RGB_LED +//#define RGBW_LED + +#if ENABLED(RGB_LED) || ENABLED(RGBW_LED) + #define RGB_LED_R_PIN 34 + #define RGB_LED_G_PIN 43 + #define RGB_LED_B_PIN 35 + #define RGB_LED_W_PIN -1 +#endif + +// 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 (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) + #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip + #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time + #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + //#define NEOPIXEL_STARTUP_TEST // Cycle through colors at startup +#endif + +/** + * Printer Event LEDs + * + * During printing, the LEDs will reflect the printer status: + * + * - Gradually change from blue to violet as the heated bed gets to target temp + * - Gradually change from violet to red as the hotend gets to temperature + * - Change to white to illuminate work surface + * - Change to green once print has finished + * - Turn off after the print has finished and the user has pushed a button + */ +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) + #define PRINTER_EVENT_LEDS +#endif + +/*********************************************************************\ +* R/C SERVO support +* Sponsored by TrinityLabs, Reworked by codexmas +**********************************************************************/ + +// Number of servos +// +// If you select a configuration below, this will receive a default value and does not need to be set manually +// set it manually if you have more servos than extruders and wish to manually control some +// leaving it undefined or defining as 0 will disable the servo subsystem +// If unsure, leave commented / disabled +// +//#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command + +// Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. +// 300ms is a good value but you can try less delay. +// If the servo can't reach the requested position, increase it. +#define SERVO_DELAY { 300 } + +// Servo deactivation +// +// With this option servos are powered only during movement, then turned off to prevent jitter. +//#define DEACTIVATE_SERVOS_AFTER_MOVE + +/** + * Filament Width Sensor + * + * Measures the filament width in real-time and adjusts + * flow rate to compensate for any irregularities. + * + * Also allows the measured filament diameter to set the + * extrusion rate, so the slicer only has to specify the + * volume. + * + * Only a single extruder is supported at this time. + * + * 34 RAMPS_14 : Analog input 5 on the AUX2 connector + * 81 PRINTRBOARD : Analog input 2 on the Exp1 connector (version B,C,D,E) + * 301 RAMBO : Analog input 3 + * + * Note: May require analog pins to be defined for other boards. + */ +//#define FILAMENT_WIDTH_SENSOR + +#define DEFAULT_NOMINAL_FILAMENT_DIA 3.00 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. + +#if ENABLED(FILAMENT_WIDTH_SENSOR) + #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) + #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber + + #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading + #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading + #define MAX_MEASUREMENT_DELAY 20 // (bytes) Buffer size for stored measurements (1 byte per cm). Must be larger than MEASUREMENT_DELAY_CM. + + #define DEFAULT_MEASURED_FILAMENT_DIA DEFAULT_NOMINAL_FILAMENT_DIA // Set measured to nominal initially + + // Display filament width on the LCD status line. Status messages will expire after 5 seconds. + //#define FILAMENT_LCD_DISPLAY +#endif + +#endif // CONFIGURATION_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/AlephObjects/TAZ4/Configuration_adv.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/AlephObjects/TAZ4/Configuration_adv.h new file mode 100644 index 00000000..eec1b6c1 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/AlephObjects/TAZ4/Configuration_adv.h @@ -0,0 +1,1424 @@ +/** + * 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 . + * + */ + +/** + * Configuration_adv.h + * + * Advanced settings. + * Only change these if you know exactly what you're doing. + * Some of these settings can damage your printer if improperly set! + * + * Basic settings can be found in Configuration.h + * + */ +#ifndef CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H_VERSION 010100 + +// @section temperature + +//=========================================================================== +//=============================Thermal Settings ============================ +//=========================================================================== + +#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 + #endif +#endif + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * The solution: Once the temperature reaches the target, start observing. + * If the temperature stays too far below the target (hysteresis) for too long (period), + * the firmware will halt the machine as a safety precaution. + * + * If you get false positives for "Thermal Runaway" increase THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD + */ +#if ENABLED(THERMAL_PROTECTION_HOTENDS) + #define THERMAL_PROTECTION_PERIOD 40 // Seconds + #define THERMAL_PROTECTION_HYSTERESIS 4 // Degrees Celsius + + /** + * Whenever an M104 or M109 increases the target temperature the firmware will wait for the + * WATCH_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get false positives for "Heating failed" increase WATCH_TEMP_PERIOD and/or decrease WATCH_TEMP_INCREASE + * WATCH_TEMP_INCREASE should not be below 2. + */ + #define WATCH_TEMP_PERIOD 20 // Seconds + #define WATCH_TEMP_INCREASE 2 // Degrees Celsius +#endif + +/** + * Thermal Protection parameters for the bed are just as above for hotends. + */ +#if ENABLED(THERMAL_PROTECTION_BED) + #define THERMAL_PROTECTION_BED_PERIOD 20 // Seconds + #define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius + + /** + * Whenever an M140 or M190 increases the target temperature the firmware will wait for the + * WATCH_BED_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_BED_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get too many "Heating failed" errors, increase WATCH_BED_TEMP_PERIOD and/or decrease + * WATCH_BED_TEMP_INCREASE. (WATCH_BED_TEMP_INCREASE should not be below 2.) + */ + #define WATCH_BED_TEMP_PERIOD 60 // Seconds + #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius +#endif + +#if ENABLED(PIDTEMP) + // this adds an experimental additional term to the heating power, proportional to the extrusion speed. + // if Kc is chosen well, the additional required power due to increased melting should be compensated. + //#define PID_EXTRUSION_SCALING + #if ENABLED(PID_EXTRUSION_SCALING) + #define DEFAULT_Kc (100) //heating power=Kc*(e_speed) + #define LPQ_MAX_LEN 50 + #endif +#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 + */ +#define AUTOTEMP +#if ENABLED(AUTOTEMP) + #define AUTOTEMP_OLDWEIGHT 0.98 +#endif + +// Show Temperature ADC value +// Enable for M105 to include ADC values read from temperature sensors. +//#define SHOW_TEMP_ADC_VALUES + +/** + * High Temperature Thermistor Support + * + * Thermistors able to support high temperature tend to have a hard time getting + * good readings at room and lower temperatures. This means HEATER_X_RAW_LO_TEMP + * will probably be caught when the heating element first turns on during the + * preheating process, which will trigger a min_temp_error as a safety measure + * and force stop everything. + * To circumvent this limitation, we allow for a preheat time (during which, + * min_temp_error won't be triggered) and add a min_temp buffer to handle + * aberrant readings. + * + * If you want to enable this feature for your hotend thermistor(s) + * uncomment and set values > 0 in the constants below + */ + +// The number of consecutive low temperature errors that can occur +// before a min_temp_error is triggered. (Shouldn't be more than 10.) +//#define MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED 0 + +// The number of milliseconds a hotend will preheat before starting to check +// the temperature. This value should NOT be set to the time it takes the +// hot end to reach the target temperature, but the time it takes to reach +// the minimum temperature your thermistor can read. The lower the better/safer. +// This shouldn't need to be more than 30 seconds (30000) +//#define MILLISECONDS_PREHEAT_TIME 0 + +// @section extruder + +// Extruder runout prevention. +// If the machine is idle and the temperature over MINTEMP +// then extrude some filament every couple of SECONDS. +//#define EXTRUDER_RUNOUT_PREVENT +#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_EXTRUDE 5 // mm +#endif + +// @section temperature + +//These defines help to calibrate the AD595 sensor in case you get wrong temperature measurements. +//The measured temperature is defined as "actualTemp = (measuredTemp * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET" +#define TEMP_SENSOR_AD595_OFFSET 0.0 +#define TEMP_SENSOR_AD595_GAIN 1.0 + +/** + * 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. + */ +#define USE_CONTROLLER_FAN +#if ENABLED(USE_CONTROLLER_FAN) + #define CONTROLLER_FAN_PIN 2 // 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 130 // 255 == full speed +#endif + +// When first starting the main fan, run it at full speed for the +// given number of milliseconds. This gets the fan spinning reliably +// before setting a PWM value. (Does not work with software PWM for fan on Sanguinololu) +//#define FAN_KICKSTART_TIME 100 + +// This defines the minimal speed for the main fan, run in PWM mode +// to enable uncomment and set minimal PWM speed for reliable running (1-255) +// if fan speed is [1 - (FAN_MIN_PWM-1)] it is set to FAN_MIN_PWM +//#define FAN_MIN_PWM 50 + +// @section extruder + +/** + * Extruder cooling fans + * + * Extruder auto fans automatically turn on when their extruders' + * temperatures go above EXTRUDER_AUTO_FAN_TEMPERATURE. + * + * Your board's pins file specifies the recommended pins. Override those here + * or set to -1 to disable completely. + * + * Multiple extruders can be assigned to the same pin in which case + * the fan will turn on when any selected extruder is above the threshold. + */ +#define E0_AUTO_FAN_PIN -1 +#define E1_AUTO_FAN_PIN -1 +#define E2_AUTO_FAN_PIN -1 +#define E3_AUTO_FAN_PIN -1 +#define E4_AUTO_FAN_PIN -1 +#define EXTRUDER_AUTO_FAN_TEMPERATURE 50 +#define EXTRUDER_AUTO_FAN_SPEED 255 // == full speed + +/** + * Part-Cooling Fan Multiplexer + * + * This feature allows you to digitally multiplex the fan output. + * The multiplexer is automatically switched at tool-change. + * Set FANMUX[012]_PINs below for up to 2, 4, or 8 multiplexed fans. + */ +#define FANMUX0_PIN -1 +#define FANMUX1_PIN -1 +#define FANMUX2_PIN -1 + +/** + * M355 Case Light on-off / brightness + */ +//#define CASE_LIGHT_ENABLE +#if ENABLED(CASE_LIGHT_ENABLE) + //#define CASE_LIGHT_PIN 4 // Override the default pin if needed + #define INVERT_CASE_LIGHT false // Set true if Case Light is ON when pin is LOW + #define CASE_LIGHT_DEFAULT_ON true // Set default power-up state on + #define CASE_LIGHT_DEFAULT_BRIGHTNESS 105 // Set default power-up brightness (0-255, requires PWM pin) + //#define MENU_ITEM_CASE_LIGHT // Add a Case Light option to the LCD main menu +#endif + +//=========================================================================== +//============================ Mechanical Settings ========================== +//=========================================================================== + +// @section homing + +// If you want endstops to stay on (by default) even when not homing +// enable this option. Override at any time with M120, M121. +//#define ENDSTOPS_ALWAYS_ON_DEFAULT + +// @section extras + +//#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. + +// Dual X Steppers +// Uncomment this option to drive two X axis motors. +// The next unused E driver will be assigned to the second X stepper. +//#define X_DUAL_STEPPER_DRIVERS +#if ENABLED(X_DUAL_STEPPER_DRIVERS) + // Set true if the two X motors need to rotate in opposite directions + #define INVERT_X2_VS_X_DIR true +#endif + +// Dual Y Steppers +// Uncomment this option to drive two Y axis motors. +// The next unused E driver will be assigned to the second Y stepper. +//#define Y_DUAL_STEPPER_DRIVERS +#if ENABLED(Y_DUAL_STEPPER_DRIVERS) + // Set true if the two Y motors need to rotate in opposite directions + #define INVERT_Y2_VS_Y_DIR true +#endif + +// A single Z stepper driver is usually used to drive 2 stepper motors. +// Uncomment this option to use a separate stepper driver for each Z axis motor. +// The next unused E driver will be assigned to the second Z stepper. +//#define Z_DUAL_STEPPER_DRIVERS + +#if ENABLED(Z_DUAL_STEPPER_DRIVERS) + + // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper. + // That way the machine is capable to align the bed during home, since both Z steppers are homed. + // There is also an implementation of M666 (software endstops adjustment) to this feature. + // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed. + // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2. + // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive. + // Play a little bit with small adjustments (0.5mm) and check the behaviour. + // The M119 (endstops report) will start reporting the Z2 Endstop as well. + + //#define Z_DUAL_ENDSTOPS + + #if ENABLED(Z_DUAL_ENDSTOPS) + #define Z2_USE_ENDSTOP _XMAX_ + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 // Use M666 to determine/test this value + #endif + +#endif // Z_DUAL_STEPPER_DRIVERS + +// Enable this for dual x-carriage printers. +// A dual x-carriage design has the advantage that the inactive extruder can be parked which +// prevents hot-end ooze contaminating the print. It also reduces the weight of each x-carriage +// allowing faster printing speeds. Connect your X2 stepper to the first unused E plug. +//#define DUAL_X_CARRIAGE +#if ENABLED(DUAL_X_CARRIAGE) + // Configuration for second X-carriage + // Note: the first x-carriage is defined as the x-carriage which homes to the minimum endstop; + // the second x-carriage always homes to the maximum endstop. + #define X2_MIN_POS 80 // set minimum to ensure second x-carriage doesn't hit the parked first X-carriage + #define X2_MAX_POS 353 // set maximum to the distance between toolheads when both heads are homed + #define X2_HOME_DIR 1 // the second X-carriage always homes to the maximum endstop position + #define X2_HOME_POS X2_MAX_POS // default home position is the maximum carriage position + // However: In this mode the HOTEND_OFFSET_X value for the second extruder provides a software + // override for X2_HOME_POS. This also allow recalibration of the distance between the two endstops + // without modifying the firmware (through the "M218 T1 X???" command). + // Remember: you should set the second extruder x-offset to 0 in your slicer. + + // There are a few selectable movement modes for dual x-carriages using M605 S + // Mode 0 (DXC_FULL_CONTROL_MODE): Full control. The slicer has full control over both x-carriages and can achieve optimal travel results + // as long as it supports dual x-carriages. (M605 S0) + // Mode 1 (DXC_AUTO_PARK_MODE) : Auto-park mode. The firmware will automatically park and unpark the x-carriages on tool changes so + // that additional slicer support is not required. (M605 S1) + // Mode 2 (DXC_DUPLICATION_MODE) : Duplication mode. The firmware will transparently make the second x-carriage and extruder copy all + // actions of the first x-carriage. This allows the printer to print 2 arbitrary items at + // once. (2nd extruder x offset and temp offset are set using: M605 S2 [Xnnn] [Rmmm]) + + // This is the default power-up mode which can be later using M605. + #define DEFAULT_DUAL_X_CARRIAGE_MODE DXC_FULL_CONTROL_MODE + + // Default settings in "Auto-park Mode" + #define TOOLCHANGE_PARK_ZLIFT 0.2 // the distance to raise Z axis when parking an extruder + #define TOOLCHANGE_UNPARK_ZLIFT 1 // the distance to raise Z axis when unparking an extruder + + // Default x offset in duplication mode (typically set to half print bed width) + #define DEFAULT_DUPLICATION_X_OFFSET 100 + +#endif // DUAL_X_CARRIAGE + +// 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. +//#define EXT_SOLENOID + +// @section homing + +//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +#define X_HOME_BUMP_MM 5 +#define Y_HOME_BUMP_MM 5 +#define Z_HOME_BUMP_MM 4 +#define HOMING_BUMP_DIVISOR {2, 2, 4} // Re-Bump Speed Divisor (Divides the Homing Feedrate) +#define QUICK_HOME //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially. + +// When G28 is called, this option will make Y home before X +//#define HOME_Y_BEFORE_X + +// @section machine + +#define AXIS_RELATIVE_MODES {false, false, false, false} + +// Allow duplication mode with a basic dual-nozzle extruder +//#define DUAL_NOZZLE_DUPLICATION_MODE + +// By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step. +#define INVERT_X_STEP_PIN false +#define INVERT_Y_STEP_PIN false +#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. +#define DEFAULT_STEPPER_DEACTIVE_TIME 60 +#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_E true + +#define DEFAULT_MINIMUMFEEDRATE 0.0 // minimum feedrate +#define DEFAULT_MINTRAVELFEEDRATE 0.0 + +//#define HOME_AFTER_DEACTIVATE // Require rehoming after steppers are deactivated + +// @section lcd + +#if ENABLED(ULTIPANEL) + #define MANUAL_FEEDRATE {50*60, 50*60, 4*60, 60} // Feedrates for manual moves along X, Y, Z, E from panel + #define ULTIPANEL_FEEDMULTIPLY // Comment to disable setting feedrate multiplier via encoder +#endif + +// @section extras + +// minimum time in microseconds that a movement needs to take if the buffer is emptied. +#define DEFAULT_MINSEGMENTTIME 20000 + +// If defined the movements slow down when the look ahead buffer is only half full +#define SLOWDOWN + +// Frequency limit +// See nophead's blog for more info +// Not working O +//#define XY_FREQUENCY_LIMIT 15 + +// 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 +// if unwanted behavior is observed on a user's machine when running at very slow speeds. +#define MINIMUM_PLANNER_SPEED 0.05 // (mm/sec) + +// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU. +#define MICROSTEP_MODES {16,16,4,16,16} // [1,2,4,8,16] + +/** + * @section stepper motor current + * + * Some boards have a means of setting the stepper motor current via firmware. + * + * The power on motor currents are set by: + * PWM_MOTOR_CURRENT - used by MINIRAMBO & ULTIMAIN_2 + * known compatible chips: A4982 + * DIGIPOT_MOTOR_CURRENT - used by BQ_ZUM_MEGA_3D, RAMBO & SCOOVO_X9H + * known compatible chips: AD5206 + * DAC_MOTOR_CURRENT_DEFAULT - used by PRINTRBOARD_REVF & RIGIDBOARD_V2 + * known compatible chips: MCP4728 + * DIGIPOT_I2C_MOTOR_CURRENTS - used by 5DPRINT, AZTEEG_X3_PRO, MIGHTYBOARD_REVE + * known compatible chips: MCP4451, MCP4018 + * + * Motor currents can also be set by M907 - M910 and by the LCD. + * M907 - applies to all. + * M908 - BQ_ZUM_MEGA_3D, RAMBO, PRINTRBOARD_REVF, RIGIDBOARD_V2 & SCOOVO_X9H + * M909, M910 & LCD - only PRINTRBOARD_REVF & RIGIDBOARD_V2 + */ +//#define PWM_MOTOR_CURRENT { 1300, 1300, 1250 } // Values in milliamps +//#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 + +// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +//#define DIGIPOT_I2C +//#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster +#define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 +// Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS +#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=========================== +//=========================================================================== + +#define ENCODER_RATE_MULTIPLIER // If defined, certain menu edit operations automatically multiply the steps when the encoder is moved quickly +#define ENCODER_10X_STEPS_PER_SEC 75 // If the encoder steps per sec exceeds this value, multiply steps moved x10 to quickly advance the value +#define ENCODER_100X_STEPS_PER_SEC 160 // If the encoder steps per sec exceeds this value, multiply steps moved x100 to really quickly advance the value + +//#define CHDK 4 //Pin for triggering CHDK to take a picture see how to use it here http://captain-slow.dk/2014/03/09/3d-printing-timelapses/ +#define CHDK_DELAY 50 //How long in ms the pin should stay HIGH before going LOW again + +// @section lcd + +// Include a page of printer information in the LCD Main Menu +//#define LCD_INFO_MENU + +// Scroll a longer status message into view +//#define STATUS_MESSAGE_SCROLLING + +// On the Info Screen, display XY with one decimal place when possible +//#define LCD_DECIMAL_SMALL_XY + +// The timeout (in ms) to return to the status screen from sub-menus +//#define LCD_TIMEOUT_TO_STATUS 15000 + +#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 + + #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? + #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. + + #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. + // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. + // using: + //#define MENU_ADDAUTOSTART + + /** + * Sort SD file listings in alphabetical order. + * + * With this option enabled, items on SD cards will be sorted + * by name for easier navigation. + * + * By default... + * + * - Use the slowest -but safest- method for sorting. + * - Folders are sorted to the top. + * - The sort key is statically allocated. + * - No added G-code (M34) support. + * - 40 item sorting limit. (Items after the first 40 are unsorted.) + * + * SD sorting uses static allocation (as set by SDSORT_LIMIT), allowing the + * compiler to calculate the worst-case usage and throw an error if the SRAM + * limit is exceeded. + * + * - SDSORT_USES_RAM provides faster sorting via a static directory buffer. + * - SDSORT_USES_STACK does the same, but uses a local stack-based buffer. + * - SDSORT_CACHE_NAMES will retain the sorted file listing in RAM. (Expensive!) + * - SDSORT_DYNAMIC_RAM only uses RAM when the SD menu is visible. (Use with caution!) + */ + //#define SDCARD_SORT_ALPHA + + // SD Card Sorting options + #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_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. + #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #endif + + // Show a progress bar on HD44780 LCDs for SD printing + //#define LCD_PROGRESS_BAR + + #if ENABLED(LCD_PROGRESS_BAR) + // Amount of time (ms) to show the bar + #define PROGRESS_BAR_BAR_TIME 2000 + // Amount of time (ms) to show the status message + #define PROGRESS_BAR_MSG_TIME 3000 + // Amount of time (ms) to retain the status message (0=forever) + #define PROGRESS_MSG_EXPIRE 0 + // Enable this to show messages for MSG_TIME then hide them + //#define PROGRESS_MSG_ONCE + // Add a menu item to test the progress bar: + //#define LCD_PROGRESS_BAR_TEST + #endif + + // This allows hosts to request long names for files and folders with M33 + //#define LONG_FILENAME_HOST_SUPPORT + + // This option allows you to abort SD printing when any endstop is triggered. + // This feature must be enabled with "M540 S1" or from the LCD menu. + // To have any effect, endstops must be enabled during SD printing. + //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + +#endif // SDSUPPORT + +/** + * Additional options for Graphical Displays + * + * Use the optimizations here to improve printing performance, + * which can be adversely affected by graphical display drawing, + * especially when doing several short moves, and when printing + * on DELTA and SCARA machines. + * + * Some of these options may result in the display lagging behind + * controller events, as there is a trade-off between reliable + * printing performance versus fast display updates. + */ +#if ENABLED(DOGLCD) + // Enable to save many cycles by drawing a hollow frame on the Info Screen + #define XYZ_HOLLOW_FRAME + + // Enable to save many cycles by drawing a hollow frame on Menu Screens + #define MENU_HOLLOW_FRAME + + // A bigger font is available for edit items. Costs 3120 bytes of PROGMEM. + // 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. + // 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 +#endif // DOGLCD + +// @section safety + +// The hardware watchdog should reset the microcontroller disabling all outputs, +// in case the firmware gets stuck and doesn't do temperature regulation. +#define USE_WATCHDOG + +#if ENABLED(USE_WATCHDOG) + // If you have a watchdog reboot in an ArduinoMega2560 then the device will hang forever, as a watchdog reset will leave the watchdog on. + // The "WATCHDOG_RESET_MANUAL" goes around this by not using the hardware reset. + // However, THIS FEATURE IS UNSAFE!, as it will only work if interrupts are disabled. And the code could hang in an interrupt routine with interrupts disabled. + //#define WATCHDOG_RESET_MANUAL +#endif + +// @section lcd + +/** + * Babystepping enables movement of the axes by tiny increments without changing + * the current position values. This feature is used primarily to adjust the Z + * axis in the first layer of a print in real-time. + * + * Warning: Does not respect endstops! + */ +//#define BABYSTEPPING +#if ENABLED(BABYSTEPPING) + //#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 100 // Babysteps are very small. Increase for faster motion. + //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping + //#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen 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_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor + //#define BABYSTEP_ZPROBE_GFX_REVERSE // Reverses the direction of the CW/CCW indicators +#endif + +// @section extruder + +/** + * Implementation of linear pressure control + * + * Assumption: advance = k * (delta velocity) + * K=0 means advance disabled. + * See Marlin documentation for calibration instructions. + */ +//#define LIN_ADVANCE + +#if ENABLED(LIN_ADVANCE) + #define LIN_ADVANCE_K 75 + + /** + * Some Slicers produce Gcode with randomly jumping extrusion widths occasionally. + * For example within a 0.4mm perimeter it may produce a single segment of 0.05mm width. + * While this is harmless for normal printing (the fluid nature of the filament will + * close this very, very tiny gap), it throws off the LIN_ADVANCE pressure adaption. + * + * For this case LIN_ADVANCE_E_D_RATIO can be used to set the extrusion:distance ratio + * to a fixed value. Note that using a fixed ratio will lead to wrong nozzle pressures + * if the slicer is using variable widths or layer heights within one print! + * + * This option sets the default E:D ratio at startup. Use `M900` to override this value. + * + * Example: `M900 W0.4 H0.2 D1.75`, where: + * - W is the extrusion width in mm + * - H is the layer height in mm + * - D is the filament diameter in mm + * + * Example: `M900 R0.0458` to set the ratio directly. + * + * Set to 0 to auto-detect the ratio based on given Gcode G1 print moves. + * + * Slic3r (including Průša Control) produces Gcode compatible with the automatic mode. + * Cura (as of this writing) may produce Gcode incompatible with the automatic mode. + */ + #define LIN_ADVANCE_E_D_RATIO 0 // The calculated ratio (or 0) according to the formula W * H / ((D / 2) ^ 2 * PI) + // Example: 0.4 * 0.2 / ((1.75 / 2) ^ 2 * PI) = 0.033260135 +#endif + +// @section leveling + +// Default mesh area is an area with an inset margin on the print area. +// Below are the macros that are used to define the borders for the mesh area, +// made available here for specialized needs, ie dual extruder setup. +#if ENABLED(MESH_BED_LEVELING) + #define MESH_MIN_X MESH_INSET + #define MESH_MAX_X (X_BED_SIZE - (MESH_INSET)) + #define MESH_MIN_Y MESH_INSET + #define MESH_MAX_Y (Y_BED_SIZE - (MESH_INSET)) +#elif ENABLED(AUTO_BED_LEVELING_UBL) + #define UBL_MESH_MIN_X UBL_MESH_INSET + #define UBL_MESH_MAX_X (X_BED_SIZE - (UBL_MESH_INSET)) + #define UBL_MESH_MIN_Y UBL_MESH_INSET + #define UBL_MESH_MAX_Y (Y_BED_SIZE - (UBL_MESH_INSET)) + + // If this is defined, the currently active mesh will be saved in the + // current slot on M500. + #define UBL_SAVE_ACTIVE_ON_M500 +#endif + +// @section extras + +// +// G2/G3 Arc Support +// +#define ARC_SUPPORT // Disable this feature to save ~3226 bytes +#if ENABLED(ARC_SUPPORT) + #define MM_PER_ARC_SEGMENT 1 // Length of each arc segment + #define N_ARC_CORRECTION 25 // Number of intertpolated 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 +#endif + +// Support for G5 with XYZE destination and IJPQ offsets. Requires ~2666 bytes. +//#define BEZIER_CURVE_SUPPORT + +// G38.2 and G38.3 Probe Target +// Enable PROBE_DOUBLE_TOUCH if you want G38 to double touch +//#define G38_PROBE_TARGET +#if ENABLED(G38_PROBE_TARGET) + #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) +#endif + +// Moves (or segments) with fewer steps than this will be joined with the next move +#define MIN_STEPS_PER_SEGMENT 6 + +// The minimum pulse width (in µs) for stepping a stepper. +// Set this if you find stepping unreliable, or if using a very fast CPU. +#define MINIMUM_STEPPER_PULSE 0 // (µs) The smallest stepper pulse allowed + +// @section temperature + +// Control heater 0 and heater 1 in parallel. +//#define HEATERS_PARALLEL + +//=========================================================================== +//================================= Buffers ================================= +//=========================================================================== + +// @section hidden + +// 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, i.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 +#else + #define BLOCK_BUFFER_SIZE 16 // maximize block buffer +#endif + +// @section serial + +// The ASCII buffer for serial input +#define MAX_CMD_SIZE 96 +#define BUFSIZE 4 + +// Transmission to Host Buffer Size +// To save 386 bytes of PROGMEM (and TX_BUFFER_SIZE+3 bytes of RAM) set to 0. +// To buffer a simple "ok" you need 4 bytes. +// For ADVANCED_OK (M105) you need 32 bytes. +// For debug-echo: 128 bytes for the optimal speed. +// Other output doesn't need to be that speedy. +// :[0, 2, 4, 8, 16, 32, 64, 128, 256] +#define TX_BUFFER_SIZE 0 + +// Host Receive Buffer Size +// Without XON/XOFF flow control (see SERIAL_XON_XOFF below) 32 bytes should be enough. +// To use flow control, set this buffer size to at least 1024 bytes. +// :[0, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048] +//#define RX_BUFFER_SIZE 1024 + +#if RX_BUFFER_SIZE >= 1024 + // Enable to have the controller send XON/XOFF control characters to + // the host to signal the RX buffer is becoming full. + //#define SERIAL_XON_XOFF +#endif + +#if ENABLED(SDSUPPORT) + // Enable this option to collect and display the maximum + // RX queue usage after transferring a file to SD. + //#define SERIAL_STATS_MAX_RX_QUEUED + + // Enable this option to collect and display the number + // of dropped bytes after a file transfer to SD. + //#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! +//#define EMERGENCY_PARSER + +// Bad Serial-connections can miss a received command by sending an 'ok' +// Therefore some clients abort after 30 seconds in a timeout. +// Some other clients start sending commands while receiving a 'wait'. +// This "wait" is only sent when the buffer is empty. 1 second is a good value here. +//#define NO_TIMEOUTS 1000 // Milliseconds + +// Some clients will have this feature soon. This could make the NO_TIMEOUTS unnecessary. +//#define ADVANCED_OK + +// @section extras + +/** + * Firmware-based and LCD-controlled retract + * + * Add G10 / G11 commands for automatic firmware-based retract / recover. + * Use M207 and M208 to define parameters for retract / recover. + * + * Use M209 to enable or disable auto-retract. + * With auto-retract enabled, all G1 E moves within the set range + * will be converted to firmware-based retract/recover moves. + * + * Be sure to turn off auto-retract during filament change. + * + * Note that M207 / M208 / M209 settings are saved to EEPROM. + * + */ +//#define FWRETRACT // ONLY PARTIALLY TESTED +#if ENABLED(FWRETRACT) + #define MIN_AUTORETRACT 0.1 // When auto-retract is on, convert E moves of this length and over + #define MAX_AUTORETRACT 10.0 // Upper limit for auto-retract conversion + #define RETRACT_LENGTH 3 // Default retract length (positive mm) + #define RETRACT_LENGTH_SWAP 13 // Default swap retract length (positive mm), for extruder change + #define RETRACT_FEEDRATE 45 // Default feedrate for retracting (mm/s) + #define RETRACT_ZLIFT 0 // Default retract Z-lift + #define RETRACT_RECOVER_LENGTH 0 // Default additional recover length (mm, added to retract length when recovering) + #define RETRACT_RECOVER_LENGTH_SWAP 0 // Default additional swap recover length (mm, added to retract length when recovering from extruder change) + #define RETRACT_RECOVER_FEEDRATE 8 // Default feedrate for recovering from retraction (mm/s) + #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) +#endif + +/** + * Advanced Pause + * Experimental feature for filament change support and for parking the nozzle when paused. + * Adds the GCode M600 for initiating filament change. + * If PARK_HEAD_ON_PAUSE enabled, adds the GCode M125 to pause printing and park the nozzle. + * + * Requires an LCD display. + * This feature is required for the default FILAMENT_RUNOUT_SCRIPT. + */ +//#define ADVANCED_PAUSE_FEATURE +#if ENABLED(ADVANCED_PAUSE_FEATURE) + #define PAUSE_PARK_X_POS 3 // X position of hotend + #define PAUSE_PARK_Y_POS 3 // Y position of hotend + #define PAUSE_PARK_Z_ADD 10 // Z addition of hotend (lift) + #define PAUSE_PARK_XY_FEEDRATE 100 // X and Y axes feedrate in mm/s (also used for delta printers Z axis) + #define PAUSE_PARK_Z_FEEDRATE 5 // Z axis feedrate in mm/s (not used for delta printers) + #define PAUSE_PARK_RETRACT_FEEDRATE 60 // Initial retract feedrate in mm/s + #define PAUSE_PARK_RETRACT_LENGTH 2 // Initial retract in mm + // It is a short retract used immediately after print interrupt before move to filament exchange position + #define FILAMENT_CHANGE_UNLOAD_FEEDRATE 10 // Unload filament feedrate in mm/s - filament unloading can be fast + #define FILAMENT_CHANGE_UNLOAD_LENGTH 100 // Unload filament length from hotend in mm + // Longer length for bowden printers to unload filament from whole bowden tube, + // shorter length for printers without bowden to unload filament from extruder only, + // 0 to disable unloading for manual unloading + #define FILAMENT_CHANGE_LOAD_FEEDRATE 6 // Load filament feedrate in mm/s - filament loading into the bowden tube can be fast + #define FILAMENT_CHANGE_LOAD_LENGTH 0 // Load filament length over hotend in mm + // Longer length for bowden printers to fast load filament into whole bowden tube over the hotend, + // Short or zero length for printers without bowden where loading is not used + #define ADVANCED_PAUSE_EXTRUDE_FEEDRATE 3 // Extrude filament feedrate in mm/s - must be slower than load feedrate + #define ADVANCED_PAUSE_EXTRUDE_LENGTH 50 // Extrude filament length in mm after filament is loaded over the hotend, + // 0 to disable for manual extrusion + // Filament can be extruded repeatedly from the filament exchange menu to fill the hotend, + // or until outcoming filament color is not clear for filament color change + #define PAUSE_PARK_NOZZLE_TIMEOUT 45 // Turn off nozzle if user doesn't change filament within this time limit in seconds + #define FILAMENT_CHANGE_NUMBER_OF_ALERT_BEEPS 5 // Number of alert beeps before printer goes quiet + #define PAUSE_PARK_NO_STEPPER_TIMEOUT // Enable to have stepper motors hold position during filament change + // even if it takes longer than DEFAULT_STEPPER_DEACTIVE_TIME. + //#define PARK_HEAD_ON_PAUSE // Go to filament change position on pause, return to print position on resume + //#define HOME_BEFORE_FILAMENT_CHANGE // Ensure homing has been completed prior to parking for filament change +#endif + +// @section tmc + +/** + * Enable this section if you have TMC26X motor drivers. + * You will need to import the TMC26XStepper library into the Arduino IDE for this + * (https://github.com/trinamic/TMC26XStepper.git) + */ +//#define HAVE_TMCDRIVER + +#if ENABLED(HAVE_TMCDRIVER) + + //#define X_IS_TMC + //#define X2_IS_TMC + //#define Y_IS_TMC + //#define Y2_IS_TMC + //#define Z_IS_TMC + //#define Z2_IS_TMC + //#define E0_IS_TMC + //#define E1_IS_TMC + //#define E2_IS_TMC + //#define E3_IS_TMC + //#define E4_IS_TMC + + #define X_MAX_CURRENT 1000 // in mA + #define X_SENSE_RESISTOR 91 // in mOhms + #define X_MICROSTEPS 16 // number of microsteps + + #define X2_MAX_CURRENT 1000 + #define X2_SENSE_RESISTOR 91 + #define X2_MICROSTEPS 16 + + #define Y_MAX_CURRENT 1000 + #define Y_SENSE_RESISTOR 91 + #define Y_MICROSTEPS 16 + + #define Y2_MAX_CURRENT 1000 + #define Y2_SENSE_RESISTOR 91 + #define Y2_MICROSTEPS 16 + + #define Z_MAX_CURRENT 1000 + #define Z_SENSE_RESISTOR 91 + #define Z_MICROSTEPS 16 + + #define Z2_MAX_CURRENT 1000 + #define Z2_SENSE_RESISTOR 91 + #define Z2_MICROSTEPS 16 + + #define E0_MAX_CURRENT 1000 + #define E0_SENSE_RESISTOR 91 + #define E0_MICROSTEPS 16 + + #define E1_MAX_CURRENT 1000 + #define E1_SENSE_RESISTOR 91 + #define E1_MICROSTEPS 16 + + #define E2_MAX_CURRENT 1000 + #define E2_SENSE_RESISTOR 91 + #define E2_MICROSTEPS 16 + + #define E3_MAX_CURRENT 1000 + #define E3_SENSE_RESISTOR 91 + #define E3_MICROSTEPS 16 + + #define E4_MAX_CURRENT 1000 + #define E4_SENSE_RESISTOR 91 + #define E4_MICROSTEPS 16 + +#endif + +// @section TMC2130 + +/** + * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. + * + * You'll also need the TMC2130Stepper Arduino library + * (https://github.com/teemuatlut/TMC2130Stepper). + * + * To use TMC2130 stepper drivers in SPI mode connect your SPI2130 pins to + * the hardware SPI interface on your board and define the required CS pins + * in your `pins_MYBOARD.h` file. (e.g., RAMPS 1.4 uses AUX3 pins `X_CS_PIN 53`, `Y_CS_PIN 49`, etc.). + */ +//#define HAVE_TMC2130 + +#if ENABLED(HAVE_TMC2130) + + // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY + //#define X_IS_TMC2130 + //#define X2_IS_TMC2130 + //#define Y_IS_TMC2130 + //#define Y2_IS_TMC2130 + //#define Z_IS_TMC2130 + //#define Z2_IS_TMC2130 + //#define E0_IS_TMC2130 + //#define E1_IS_TMC2130 + //#define E2_IS_TMC2130 + //#define E3_IS_TMC2130 + //#define E4_IS_TMC2130 + + /** + * Stepper driver settings + */ + + #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 + #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current + #define INTERPOLATE 1 // Interpolate X/Y/Z_MICROSTEPS to 256 + + #define X_CURRENT 1000 // rms current in mA. Multiply by 1.41 for peak current. + #define X_MICROSTEPS 16 // 0..256 + + #define Y_CURRENT 1000 + #define Y_MICROSTEPS 16 + + #define Z_CURRENT 1000 + #define Z_MICROSTEPS 16 + + //#define X2_CURRENT 1000 + //#define X2_MICROSTEPS 16 + + //#define Y2_CURRENT 1000 + //#define Y2_MICROSTEPS 16 + + //#define Z2_CURRENT 1000 + //#define Z2_MICROSTEPS 16 + + //#define E0_CURRENT 1000 + //#define E0_MICROSTEPS 16 + + //#define E1_CURRENT 1000 + //#define E1_MICROSTEPS 16 + + //#define E2_CURRENT 1000 + //#define E2_MICROSTEPS 16 + + //#define E3_CURRENT 1000 + //#define E3_MICROSTEPS 16 + + //#define E4_CURRENT 1000 + //#define E4_MICROSTEPS 16 + + /** + * Use Trinamic's ultra quiet stepping mode. + * When disabled, Marlin will use spreadCycle stepping mode. + */ + #define STEALTHCHOP + + /** + * Let Marlin automatically control stepper current. + * This is still an experimental feature. + * Increase current every 5s by CURRENT_STEP until stepper temperature prewarn gets triggered, + * then decrease current by CURRENT_STEP until temperature prewarn is cleared. + * Adjusting starts from X/Y/Z/E_CURRENT but will not increase over AUTO_ADJUST_MAX + * 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. + * M906 S1 - Start adjusting current + * M906 S0 - Stop adjusting current + * M911 - Report stepper driver overtemperature pre-warn condition. + * M912 - Clear stepper driver overtemperature pre-warn condition flag. + */ + //#define AUTOMATIC_CURRENT_CONTROL + + #if ENABLED(AUTOMATIC_CURRENT_CONTROL) + #define CURRENT_STEP 50 // [mA] + #define AUTO_ADJUST_MAX 1300 // [mA], 1300mA_rms = 1840mA_peak + #define REPORT_CURRENT_CHANGE + #endif + + /** + * The driver will switch to spreadCycle when stepper speed is over HYBRID_THRESHOLD. + * This mode allows for faster movements at the expense of higher noise levels. + * STEALTHCHOP needs to be enabled. + * M913 X/Y/Z/E to live tune the setting + */ + //#define HYBRID_THRESHOLD + + #define X_HYBRID_THRESHOLD 100 // [mm/s] + #define X2_HYBRID_THRESHOLD 100 + #define Y_HYBRID_THRESHOLD 100 + #define Y2_HYBRID_THRESHOLD 100 + #define Z_HYBRID_THRESHOLD 4 + #define Z2_HYBRID_THRESHOLD 4 + #define E0_HYBRID_THRESHOLD 30 + #define E1_HYBRID_THRESHOLD 30 + #define E2_HYBRID_THRESHOLD 30 + #define E3_HYBRID_THRESHOLD 30 + #define E4_HYBRID_THRESHOLD 30 + + /** + * Use stallGuard2 to sense an obstacle and trigger an endstop. + * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. + * If used along with STEALTHCHOP, the movement will be louder when homing. This is normal. + * + * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. + * Higher values make the system LESS sensitive. + * Lower value make the system MORE sensitive. + * Too low values can lead to false positives, while too high values will collide the axis without triggering. + * It is advised to set X/Y_HOME_BUMP_MM to 0. + * M914 X/Y to live tune the setting + */ + //#define SENSORLESS_HOMING + + #if ENABLED(SENSORLESS_HOMING) + #define X_HOMING_SENSITIVITY 19 + #define Y_HOMING_SENSITIVITY 19 + #endif + + /** + * You can set your own advanced settings by filling in predefined functions. + * A list of available functions can be found on the library github page + * https://github.com/teemuatlut/TMC2130Stepper + * + * Example: + * #define TMC2130_ADV() { \ + * stepperX.diag0_temp_prewarn(1); \ + * stepperX.interpolate(0); \ + * } + */ + #define TMC2130_ADV() { } + +#endif // HAVE_TMC2130 + +// @section L6470 + +/** + * Enable this section if you have L6470 motor drivers. + * You need to import the L6470 library into the Arduino IDE for this. + * (https://github.com/ameyer/Arduino-L6470) + */ + +//#define HAVE_L6470DRIVER +#if ENABLED(HAVE_L6470DRIVER) + + //#define X_IS_L6470 + //#define X2_IS_L6470 + //#define Y_IS_L6470 + //#define Y2_IS_L6470 + //#define Z_IS_L6470 + //#define Z2_IS_L6470 + //#define E0_IS_L6470 + //#define E1_IS_L6470 + //#define E2_IS_L6470 + //#define E3_IS_L6470 + //#define E4_IS_L6470 + + #define X_MICROSTEPS 16 // number of microsteps + #define X_K_VAL 50 // 0 - 255, Higher values, are higher power. Be careful not to go too high + #define X_OVERCURRENT 2000 // maxc current in mA. If the current goes over this value, the driver will switch off + #define X_STALLCURRENT 1500 // current in mA where the driver will detect a stall + + #define X2_MICROSTEPS 16 + #define X2_K_VAL 50 + #define X2_OVERCURRENT 2000 + #define X2_STALLCURRENT 1500 + + #define Y_MICROSTEPS 16 + #define Y_K_VAL 50 + #define Y_OVERCURRENT 2000 + #define Y_STALLCURRENT 1500 + + #define Y2_MICROSTEPS 16 + #define Y2_K_VAL 50 + #define Y2_OVERCURRENT 2000 + #define Y2_STALLCURRENT 1500 + + #define Z_MICROSTEPS 16 + #define Z_K_VAL 50 + #define Z_OVERCURRENT 2000 + #define Z_STALLCURRENT 1500 + + #define Z2_MICROSTEPS 16 + #define Z2_K_VAL 50 + #define Z2_OVERCURRENT 2000 + #define Z2_STALLCURRENT 1500 + + #define E0_MICROSTEPS 16 + #define E0_K_VAL 50 + #define E0_OVERCURRENT 2000 + #define E0_STALLCURRENT 1500 + + #define E1_MICROSTEPS 16 + #define E1_K_VAL 50 + #define E1_OVERCURRENT 2000 + #define E1_STALLCURRENT 1500 + + #define E2_MICROSTEPS 16 + #define E2_K_VAL 50 + #define E2_OVERCURRENT 2000 + #define E2_STALLCURRENT 1500 + + #define E3_MICROSTEPS 16 + #define E3_K_VAL 50 + #define E3_OVERCURRENT 2000 + #define E3_STALLCURRENT 1500 + + #define E4_MICROSTEPS 16 + #define E4_K_VAL 50 + #define E4_OVERCURRENT 2000 + #define E4_STALLCURRENT 1500 + +#endif + +/** + * TWI/I2C BUS + * + * This feature is an EXPERIMENTAL feature so it shall not be used on production + * machines. Enabling this will allow you to send and receive I2C data from slave + * devices on the bus. + * + * ; Example #1 + * ; This macro send the string "Marlin" to the slave device with address 0x63 (99) + * ; It uses multiple M260 commands with one B arg + * M260 A99 ; Target slave address + * M260 B77 ; M + * M260 B97 ; a + * M260 B114 ; r + * M260 B108 ; l + * M260 B105 ; i + * M260 B110 ; n + * M260 S1 ; Send the current buffer + * + * ; Example #2 + * ; Request 6 bytes from slave device with address 0x63 (99) + * M261 A99 B5 + * + * ; Example #3 + * ; Example serial output of a M261 request + * echo:i2c-reply: from:99 bytes:5 data:hello + */ + +// @section i2cbus + +//#define EXPERIMENTAL_I2CBUS +#define I2C_SLAVE_ADDRESS 0 // Set a value from 8 to 127 to act as a slave + +// @section extras + +/** + * Spindle & Laser control + * + * Add the M3, M4, and M5 commands to turn the spindle/laser on and off, and + * to set spindle speed, spindle direction, and laser power. + * + * SuperPid is a router/spindle speed controller used in the CNC milling community. + * Marlin can be used to turn the spindle on and off. It can also be used to set + * the spindle speed from 5,000 to 30,000 RPM. + * + * 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. + */ +//#define SPINDLE_LASER_ENABLE +#if ENABLED(SPINDLE_LASER_ENABLE) + + #define SPINDLE_LASER_ENABLE_INVERT false // set to "true" if the on/off function is reversed + #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 // delay in milliseconds to allow the spindle/laser to come up to speed/power + #define SPINDLE_LASER_POWERDOWN_DELAY 5000 // delay in milliseconds to allow the spindle to stop + #define SPINDLE_DIR_CHANGE true // set to true if your spindle controller supports changing spindle direction + #define SPINDLE_INVERT_DIR false + #define SPINDLE_STOP_ON_DIR_CHANGE true // set to true if Marlin should stop the spindle before changing rotation direction + + /** + * The M3 & M4 commands use the following equation to convert PWM duty cycle to speed/power + * + * SPEED/POWER = PWM duty cycle * SPEED_POWER_SLOPE + SPEED_POWER_INTERCEPT + * where PWM duty cycle varies from 0 to 255 + * + * set the following for your controller (ALL MUST BE SET) + */ + + #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_SLOPE 0.3922 + //#define SPEED_POWER_INTERCEPT 0 + //#define SPEED_POWER_MIN 10 + //#define SPEED_POWER_MAX 100 // 0-100% +#endif + +/** + * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins + */ +//#define PINS_DEBUGGING + +/** + * Auto-report temperatures with M155 S + */ +#define AUTO_REPORT_TEMPERATURES + +/** + * Include capabilities in M115 output + */ +#define EXTENDED_CAPABILITIES_REPORT + +/** + * Volumetric extrusion default state + * 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. + */ +//#define VOLUMETRIC_DEFAULT_ON + +/** + * Enable this option for a leaner build of Marlin that removes all + * workspace offsets, simplifying coordinate transformations, leveling, etc. + * + * - M206 and M428 are disabled. + * - G92 will revert to its behavior from Marlin 1.0. + */ +//#define NO_WORKSPACE_OFFSETS + +/** + * 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. + * + * For clients that use a fixed-width font (like OctoPrint), leave this set to 1.0. + * Otherwise, adjust according to your client and font. + */ +#define PROPORTIONAL_FONT_RATIO 1.0 + +/** + * Spend 28 bytes of SRAM to optimize the GCode parser + */ +#define FASTER_GCODE_PARSER + +/** + * User-defined menu items that execute custom GCode + */ +//#define CUSTOM_USER_MENUS +#if ENABLED(CUSTOM_USER_MENUS) + #define USER_SCRIPT_DONE "M117 User Script Done" + #define USER_SCRIPT_AUDIBLE_FEEDBACK + //#define USER_SCRIPT_RETURN // Return to status screen after a script + + #define USER_DESC_1 "Home & UBL Info" + #define USER_GCODE_1 "G28\nG29 W" + + #define USER_DESC_2 "Preheat for PLA" + #define USER_GCODE_2 "M140 S" STRINGIFY(PREHEAT_1_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND) + + #define USER_DESC_3 "Preheat for ABS" + #define USER_GCODE_3 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND) + + #define USER_DESC_4 "Heat Bed/Home/Level" + #define USER_GCODE_4 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nG28\nG29" + + //#define USER_DESC_5 "Home & Info" + //#define USER_GCODE_5 "G28\nM503" +#endif + +/** + * Specify an action command to send to the host when the printer is killed. + * Will be sent in the form '//action:ACTION_ON_KILL', e.g. '//action:poweroff'. + * The host must be configured to handle the action command. + */ +//#define ACTION_ON_KILL "poweroff" + +//=========================================================================== +//====================== I2C Position Encoder Settings ====================== +//=========================================================================== + +/** + * I2C position encoders for closed loop control. + * Developed by Chris Barr at Aus3D. + * + * Wiki: http://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/ + * + * Reilabuild encoders have been modified to improve reliability. + */ + +//#define I2C_POSITION_ENCODERS +#if ENABLED(I2C_POSITION_ENCODERS) + + #define I2CPE_ENCODER_CNT 1 // The number of encoders installed; max of 5 + // encoders supported currently. + + #define I2CPE_ENC_1_ADDR I2CPE_PRESET_ADDR_X // I2C address of the encoder. 30-200. + #define I2CPE_ENC_1_AXIS X_AXIS // Axis the encoder module is installed on. _AXIS. + #define I2CPE_ENC_1_TYPE I2CPE_ENC_TYPE_LINEAR // Type of encoder: I2CPE_ENC_TYPE_LINEAR -or- + // I2CPE_ENC_TYPE_ROTARY. + #define I2CPE_ENC_1_TICKS_UNIT 2048 // 1024 for magnetic strips with 2mm poles; 2048 for + // 1mm poles. For linear encoders this is ticks / mm, + // for rotary encoders this is ticks / revolution. + //#define I2CPE_ENC_1_TICKS_REV (16 * 200) // Only needed for rotary encoders; number of stepper + // steps per full revolution (motor steps/rev * microstepping) + //#define I2CPE_ENC_1_INVERT // Invert the direction of axis travel. + #define I2CPE_ENC_1_EC_METHOD I2CPE_ECM_NONE // Type of error error correction. + #define I2CPE_ENC_1_EC_THRESH 0.10 // Threshold size for error (in mm) above which the + // printer will attempt to correct the error; errors + // smaller than this are ignored to minimize effects of + // measurement noise / latency (filter). + + #define I2CPE_ENC_2_ADDR I2CPE_PRESET_ADDR_Y // Same as above, but for encoder 2. + #define I2CPE_ENC_2_AXIS Y_AXIS + #define I2CPE_ENC_2_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_ENC_2_TICKS_UNIT 2048 + //#define I2CPE_ENC_2_TICKS_REV (16 * 200) + //#define I2CPE_ENC_2_INVERT + #define I2CPE_ENC_2_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_ENC_2_EC_THRESH 0.10 + + #define I2CPE_ENC_3_ADDR I2CPE_PRESET_ADDR_Z // Encoder 3. Add additional configuration options + #define I2CPE_ENC_3_AXIS Z_AXIS // as above, or use defaults below. + + #define I2CPE_ENC_4_ADDR I2CPE_PRESET_ADDR_E // Encoder 4. + #define I2CPE_ENC_4_AXIS E_AXIS + + #define I2CPE_ENC_5_ADDR 34 // Encoder 5. + #define I2CPE_ENC_5_AXIS E_AXIS + + // Default settings for encoders which are enabled, but without settings configured above. + #define I2CPE_DEF_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_DEF_ENC_TICKS_UNIT 2048 + #define I2CPE_DEF_TICKS_REV (16 * 200) + #define I2CPE_DEF_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_DEF_EC_THRESH 0.1 + + //#define I2CPE_ERR_THRESH_ABORT 100.0 // Threshold size for error (in mm) error on any given + // axis after which the printer will abort. Comment out to + // disable abort behaviour. + + #define I2CPE_TIME_TRUSTED 10000 // After an encoder fault, there must be no further fault + // for this amount of time (in ms) before the encoder + // is trusted again. + + /** + * Position is checked every time a new command is executed from the buffer but during long moves, + * this setting determines the minimum update time between checks. A value of 100 works well with + * error rolling average when attempting to correct only for skips and not for vibration. + */ + #define I2CPE_MIN_UPD_TIME_MS 100 // Minimum time in miliseconds between encoder checks. + + // Use a rolling average to identify persistant errors that indicate skips, as opposed to vibration and noise. + #define I2CPE_ERR_ROLLING_AVERAGE + +#endif // I2C_POSITION_ENCODERS + +/** + * MAX7219 Debug Matrix + * + * Add support for a low-cost 8x8 LED Matrix based on the Max7219 chip, which can be used as a status + * display. Requires 3 signal wires. Some useful debug options are included to demonstrate its usage. + * + * Fully assembled MAX7219 boards can be found on the internet for under $2(US). + * For example, see https://www.ebay.com/sch/i.html?_nkw=332349290049 + */ +//#define MAX7219_DEBUG +#if ENABLED(MAX7219_DEBUG) + #define MAX7219_CLK_PIN 64 // 77 on Re-ARM // Configuration of the 3 pins to control the display + #define MAX7219_DIN_PIN 57 // 78 on Re-ARM + #define MAX7219_LOAD_PIN 44 // 79 on Re-ARM + + /** + * Sample debug features + * If you add more debug displays, be careful to avoid conflicts! + */ + #define MAX7219_DEBUG_PRINTER_ALIVE // Blink corner LED of 8x8 matrix to show that the firmware is functioning + #define MAX7219_DEBUG_STEPPER_HEAD 3 // Show the stepper queue head position on this and the next LED matrix row + #define MAX7219_DEBUG_STEPPER_TAIL 5 // Show the stepper queue tail position on this and the next LED matrix row + + #define MAX7219_DEBUG_STEPPER_QUEUE 0 // Show the current stepper queue depth on this and the next LED matrix row + // If you experience stuttering, reboots, etc. this option can reveal how + // tweaks made to the configuration are affecting the printer in real-time. +#endif + +#endif // CONFIGURATION_ADV_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/AliExpress/CL-260/Configuration.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/AliExpress/CL-260/Configuration.h new file mode 100644 index 00000000..f3bd3290 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/AliExpress/CL-260/Configuration.h @@ -0,0 +1,1700 @@ +/** + * 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 . + * + */ + +/** + * Configuration.h + * + * Basic settings such as: + * + * - Type of electronics + * - Type of temperature sensor + * - Printer geometry + * - Endstop configuration + * - LCD controller + * - Extra features + * + * Advanced settings can be found in Configuration_adv.h + * + */ +#ifndef CONFIGURATION_H +#define CONFIGURATION_H +#define CONFIGURATION_H_VERSION 010100 + +//=========================================================================== +//============================= Getting Started ============================= +//=========================================================================== + +/** + * Here are some standard links for getting your machine calibrated: + * + * http://reprap.org/wiki/Calibration + * http://youtu.be/wAL9d7FgInk + * http://calculator.josefprusa.cz + * http://reprap.org/wiki/Triffid_Hunter%27s_Calibration_Guide + * http://www.thingiverse.com/thing:5573 + * https://sites.google.com/site/repraplogphase/calibration-of-your-reprap + * http://www.thingiverse.com/thing:298812 + */ + +//=========================================================================== +//============================= DELTA Printer =============================== +//=========================================================================== +// For a Delta printer start with one of the configuration files in the +// example_configurations/delta directory and customize for your machine. +// + +//=========================================================================== +//============================= SCARA Printer =============================== +//=========================================================================== +// For a SCARA printer start with the configuration files in +// example_configurations/SCARA and customize for your machine. +// + +// @section info + +// User-specified version info of this build to display in [Pronterface, etc] terminal window during +// startup. Implementation of an idea by Prof Braino to inform user that any changes made to this +// build by the user have been successfully uploaded into firmware. +#define STRING_CONFIG_H_AUTHOR "(none, CL-260)" // Who made the changes. +#define SHOW_BOOTSCREEN +#define STRING_SPLASH_LINE1 SHORT_BUILD_VERSION // will be shown during bootup in line 1 +#define STRING_SPLASH_LINE2 WEBSITE_URL // will be shown during bootup in line 2 + +// +// *** VENDORS PLEASE READ ***************************************************** +// +// Marlin now allow you to have a vendor boot image to be displayed on machine +// start. When SHOW_CUSTOM_BOOTSCREEN is defined Marlin will first show your +// custom boot image and then the default Marlin boot image is shown. +// +// We suggest for you to take advantage of this new feature and keep the Marlin +// boot image unmodified. For an example have a look at the bq Hephestos 2 +// example configuration folder. +// +//#define SHOW_CUSTOM_BOOTSCREEN +// @section machine + +/** + * Select which serial port on the board will be used for communication with the host. + * This allows the connection of wireless adapters (for instance) to non-default port pins. + * Serial port 0 is always used by the Arduino bootloader regardless of this setting. + * + * :[0, 1, 2, 3, 4, 5, 6, 7] + */ +#define SERIAL_PORT 0 + +/** + * This setting determines the communication speed of the printer. + * + * 250000 works in most cases, but you might try a lower speed if + * you commonly experience drop-outs during host printing. + * You may try up to 1000000 to speed up SD file transfer. + * + * :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000] + */ +#define BAUDRATE 250000 + +// Enable the Bluetooth serial interface on AT90USB devices +//#define BLUETOOTH + +// The following define selects which electronics board you have. +// Please choose the name from boards.h that matches your setup +#ifndef MOTHERBOARD + #define MOTHERBOARD BOARD_RAMPS_14_EFB +#endif + +// Optional custom name for your RepStrap or other custom machine +// Displayed in the LCD "Ready" message +#define CUSTOM_MACHINE_NAME "CL-260" + +// Define this to set a unique identifier for this printer, (Used by some programs to differentiate between machines) +// You can use an online service to generate a random UUID. (eg http://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] +#define EXTRUDERS 1 + +// For Cyclops or any "multi-extruder" that shares a single nozzle. +//#define SINGLENOZZLE + +/** + * Průša MK2 Single Nozzle Multi-Material Multiplexer, and variants. + * + * This device allows one stepper driver on a control board to drive + * two to eight stepper motors, one at a time, in a manner suitable + * for extruders. + * + * This option only allows the multiplexer to switch on tool-change. + * Additional options to configure custom E moves are pending. + */ +//#define MK2_MULTIPLEXER +#if ENABLED(MK2_MULTIPLEXER) + // Override the default DIO selector pins here, if needed. + // Some pins files may provide defaults for these pins. + //#define E_MUX0_PIN 40 // Always Required + //#define E_MUX1_PIN 42 // Needed for 3 to 8 steppers + //#define E_MUX2_PIN 44 // Needed for 5 to 8 steppers +#endif + +// A dual extruder that uses a single stepper motor +//#define SWITCHING_EXTRUDER +#if ENABLED(SWITCHING_EXTRUDER) + #define SWITCHING_EXTRUDER_SERVO_NR 0 + #define SWITCHING_EXTRUDER_SERVO_ANGLES { 0, 90 } // Angles for E0, E1[, E2, E3] + #if EXTRUDERS > 3 + #define SWITCHING_EXTRUDER_E23_SERVO_NR 1 + #endif +#endif + +// A dual-nozzle that uses a servomotor to raise/lower one of the nozzles +//#define SWITCHING_NOZZLE +#if ENABLED(SWITCHING_NOZZLE) + #define SWITCHING_NOZZLE_SERVO_NR 0 + #define SWITCHING_NOZZLE_SERVO_ANGLES { 0, 90 } // Angles for E0, E1 + //#define HOTEND_OFFSET_Z { 0.0, 0.0 } +#endif + +/** + * Two separate X-carriages with extruders that connect to a moving part + * via a magnetic docking mechanism. Requires SOL1_PIN and SOL2_PIN. + */ +//#define PARKING_EXTRUDER +#if ENABLED(PARKING_EXTRUDER) + #define PARKING_EXTRUDER_SOLENOIDS_INVERT // If enabled, the solenoid is NOT magnetized with applied voltage + #define PARKING_EXTRUDER_SOLENOIDS_PINS_ACTIVE LOW // LOW or HIGH pin signal energizes the coil + #define PARKING_EXTRUDER_SOLENOIDS_DELAY 250 // Delay (ms) for magnetic field. No delay if 0 or not defined. + #define PARKING_EXTRUDER_PARKING_X { -78, 184 } // X positions for parking the extruders + #define PARKING_EXTRUDER_GRAB_DISTANCE 1 // mm to move beyond the parking point to grab the extruder + #define PARKING_EXTRUDER_SECURITY_RAISE 5 // Z-raise before parking + #define HOTEND_OFFSET_Z { 0.0, 1.3 } // Z-offsets of the two hotends. The first must be 0. +#endif + +/** + * "Mixing Extruder" + * - Adds a new code, M165, to set the current mix factors. + * - Extends the stepping routines to move multiple steppers in proportion to the mix. + * - Optional support for Repetier Firmware M163, M164, and virtual extruder. + * - This implementation supports only a single extruder. + * - Enable DIRECT_MIXING_IN_G1 for Pia Taubert's reference implementation + */ +//#define MIXING_EXTRUDER +#if ENABLED(MIXING_EXTRUDER) + #define MIXING_STEPPERS 2 // Number of steppers in your mixing extruder + #define MIXING_VIRTUAL_TOOLS 16 // Use the Virtual Tool method with M163 and M164 + //#define DIRECT_MIXING_IN_G1 // Allow ABCDHI mix factors in G1 movement commands +#endif + +// Offset of the extruders (uncomment if using more than one and relying on firmware to position when changing). +// The offset has to be X=0, Y=0 for the extruder 0 hotend (default extruder). +// For the other hotends it is their distance from the extruder 0 hotend. +//#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis +//#define HOTEND_OFFSET_Y {0.0, 5.00} // (in mm) for each extruder, offset of the hotend on the Y axis + +// @section machine + +/** + * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN + * + * 0 = No Power Switch + * 1 = ATX + * 2 = X-Box 360 203Watts (the blue wire connected to PS_ON and the red wire to VCC) + * + * :{ 0:'No power switch', 1:'ATX', 2:'X-Box 360' } + */ +#define POWER_SUPPLY 0 + +#if POWER_SUPPLY > 0 + // Enable this option to leave the PSU off at startup. + // Power to steppers and heaters will need to be turned on with M80. + //#define PS_DEFAULT_OFF +#endif + +// @section temperature + +//=========================================================================== +//============================= Thermal Settings ============================ +//=========================================================================== + +/** + * --NORMAL IS 4.7kohm PULLUP!-- 1kohm pullup can be used on hotend sensor, using correct resistor and table + * + * Temperature sensors available: + * + * -3 : thermocouple with MAX31855 (only for sensor 0) + * -2 : thermocouple with MAX6675 (only for sensor 0) + * -1 : thermocouple with AD595 + * 0 : not used + * 1 : 100k thermistor - best choice for EPCOS 100k (4.7k pullup) + * 2 : 200k thermistor - ATC Semitec 204GT-2 (4.7k pullup) + * 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 (Used in ParCan & J-Head) (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) + * 71 : 100k Honeywell thermistor 135-104LAF-J01 (4.7k pullup) + * 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) + * 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" + * 20 : the PT100 circuit found in the Ultimainboard V2.x + * 60 : 100k Maker's Tool Works Kapton Bed Thermistor beta=3950 + * 66 : 4.7M High Temperature thermistor from Dyze Design + * 70 : the 100K thermistor found in the bq Hephestos 2 + * 75 : 100k Generic Silicon Heat Pad with NTC 100K MGB18-104F39050L32 thermistor + * + * 1k ohm pullup tables - This is atypical, and requires changing out the 4.7k pullup for 1k. + * (but gives greater accuracy and more stable PID) + * 51 : 100k thermistor - EPCOS (1k pullup) + * 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 + * 1010 : Pt1000 with 1k pullup (non standard) + * 147 : Pt100 with 4k7 pullup + * 110 : Pt100 with 1k pullup (non standard) + * + * Use these for Testing or Development purposes. NEVER for production machine. + * 998 : Dummy Table that ALWAYS reads 25°C or the temperature defined below. + * 999 : Dummy Table that ALWAYS reads 100°C or the temperature defined below. + * + * :{ '0': "Not used", '1':"100k / 4.7k - EPCOS", '2':"200k / 4.7k - ATC Semitec 204GT-2", '3':"Mendel-parts / 4.7k", '4':"10k !! do not use for a hotend. Bad resolution at high temp. !!", '5':"100K / 4.7k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '6':"100k / 4.7k EPCOS - Not as accurate as Table 1", '7':"100k / 4.7k Honeywell 135-104LAG-J01", '8':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT", '9':"100k / 4.7k GE Sensing AL03006-58.2K-97-G1", '10':"100k / 4.7k RS 198-961", '11':"100k / 4.7k beta 3950 1%", '12':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT (calibrated for Makibox hot bed)", '13':"100k Hisens 3950 1% up to 300°C for hotend 'Simple ONE ' & hotend 'All In ONE'", '20':"PT100 (Ultimainboard V2.x)", '51':"100k / 1k - EPCOS", '52':"200k / 1k - ATC Semitec 204GT-2", '55':"100k / 1k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '60':"100k Maker's Tool Works Kapton Bed Thermistor beta=3950", '66':"Dyze Design 4.7M High Temperature thermistor", '70':"the 100K thermistor found in the bq Hephestos 2", '71':"100k / 4.7k Honeywell 135-104LAF-J01", '147':"Pt100 / 4.7k", '1047':"Pt1000 / 4.7k", '110':"Pt100 / 1k (non-standard)", '1010':"Pt1000 / 1k (non standard)", '-3':"Thermocouple + MAX31855 (only for sensor 0)", '-2':"Thermocouple + MAX6675 (only for sensor 0)", '-1':"Thermocouple + AD595",'998':"Dummy 1", '999':"Dummy 2" } + */ +#define TEMP_SENSOR_0 1 +#define TEMP_SENSOR_1 0 +#define TEMP_SENSOR_2 0 +#define TEMP_SENSOR_3 0 +#define TEMP_SENSOR_4 0 +#define TEMP_SENSOR_BED 1 + +// Dummy thermistor constant temperature readings, for use with 998 and 999 +#define DUMMY_THERMISTOR_998_VALUE 25 +#define DUMMY_THERMISTOR_999_VALUE 100 + +// 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 +#define MAX_REDUNDANT_TEMP_SENSOR_DIFF 10 + +// Extruder temperature must be close to target for this long before M109 returns success +#define TEMP_RESIDENCY_TIME 10 // (seconds) +#define TEMP_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// Bed temperature must be close to target for this long before M190 returns success +#define TEMP_BED_RESIDENCY_TIME 10 // (seconds) +#define TEMP_BED_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_BED_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// The minimal temperature defines the temperature below which the heater will not be enabled It is used +// to check that the wiring to the thermistor is not broken. +// Otherwise this would lead to the heater being powered on all the time. +#define HEATER_0_MINTEMP 5 +#define HEATER_1_MINTEMP 5 +#define HEATER_2_MINTEMP 5 +#define HEATER_3_MINTEMP 5 +#define HEATER_4_MINTEMP 5 +#define BED_MINTEMP 5 + +// When temperature exceeds max temp, your heater will be switched off. +// This feature exists to protect your hotend from overheating accidentally, but *NOT* from thermistor short/failure! +// You should use MINTEMP for thermistor short/failure protection. +#define HEATER_0_MAXTEMP 275 +#define HEATER_1_MAXTEMP 275 +#define HEATER_2_MAXTEMP 275 +#define HEATER_3_MAXTEMP 275 +#define HEATER_4_MAXTEMP 275 +#define BED_MAXTEMP 150 + +//=========================================================================== +//============================= PID Settings ================================ +//=========================================================================== +// PID Tuning Guide here: http://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 +#if ENABLED(PIDTEMP) + //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. + //#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. + #define K1 0.95 //smoothing factor within the PID + + // 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 + +#endif // PIDTEMP + +//=========================================================================== +//============================= PID > Bed Temperature Control =============== +//=========================================================================== +// Select PID or bang-bang with PIDTEMPBED. If bang-bang, BED_LIMIT_SWITCHING will enable hysteresis +// +// Uncomment this to enable PID on the bed. It uses the same frequency PWM as the extruder. +// If your PID_dT is the default, and correct for your hardware/configuration, that means 7.689Hz, +// which is fine for driving a square wave into a resistive load and does not significantly impact you FET heating. +// This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W heater. +// If your configuration is significantly different than this and you don't understand the issues involved, you probably +// shouldn't use bed PID until someone else verifies your hardware works. +// If this is enabled, find your own PID constants below. +//#define PIDTEMPBED + +//#define BED_LIMIT_SWITCHING + +// This sets the max power delivered to the bed, and replaces the HEATER_BED_DUTY_CYCLE_DIVIDER option. +// all forms of bed control obey this (PID, bang-bang, bang-bang with hysteresis) +// setting this to anything other than 255 enables a form of PWM to the bed just like HEATER_BED_DUTY_CYCLE_DIVIDER did, +// so you shouldn't use it unless you are OK with PWM on your bed. (see the comment on enabling PIDTEMPBED) +#define MAX_BED_POWER 255 // limits duty cycle to bed; 255=full current + +#if ENABLED(PIDTEMPBED) + + //#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) + #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 + +// @section extruder + +// This option prevents extrusion if the temperature is below EXTRUDE_MINTEMP. +// It also enables the M302 command to set the minimum extrusion temperature +// or to allow moving the extruder regardless of the hotend temperature. +// *** IT IS HIGHLY RECOMMENDED TO LEAVE THIS OPTION ENABLED! *** +#define PREVENT_COLD_EXTRUSION +#define EXTRUDE_MINTEMP 170 + +// This option prevents a single extrusion longer than EXTRUDE_MAXLENGTH. +// Note that for Bowden Extruders a too-small value here may prevent loading. +#define PREVENT_LENGTHY_EXTRUDE +#define EXTRUDE_MAXLENGTH 800 + +//=========================================================================== +//======================== Thermal Runaway Protection ======================= +//=========================================================================== + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * If you get "Thermal Runaway" or "Heating failed" errors the + * details can be tuned in Configuration_adv.h + */ + +#define THERMAL_PROTECTION_HOTENDS // Enable thermal protection for all extruders +#define THERMAL_PROTECTION_BED // Enable thermal protection for the heated bed + +//=========================================================================== +//============================= Mechanical Settings ========================= +//=========================================================================== + +// @section machine + +// Uncomment one of these options to enable CoreXY, CoreXZ, or CoreYZ kinematics +// either in the usual order or reversed +//#define COREXY +//#define COREXZ +//#define COREYZ +//#define COREYX +//#define COREZX +//#define COREZY + +//=========================================================================== +//============================== Endstop Settings =========================== +//=========================================================================== + +// @section homing + +// Specify here all the endstop connectors that are connected to any endstop or probe. +// Almost all printers will be using one per axis. Probes will use one or more of the +// extra connectors. Leave undefined any used for non-endstop and non-probe purposes. +#define USE_XMIN_PLUG +//#define USE_YMIN_PLUG +#define USE_ZMIN_PLUG +//#define USE_XMAX_PLUG +#define USE_YMAX_PLUG +//#define USE_ZMAX_PLUG + +// coarse Endstop Settings +#define ENDSTOPPULLUPS // Comment this out (using // at the start of the line) to disable the endstop pullup resistors + +#if DISABLED(ENDSTOPPULLUPS) + // fine endstop settings: Individual pullups. will be ignored if ENDSTOPPULLUPS is defined + //#define ENDSTOPPULLUP_XMAX + //#define ENDSTOPPULLUP_YMAX + //#define ENDSTOPPULLUP_ZMAX + //#define ENDSTOPPULLUP_XMIN + //#define ENDSTOPPULLUP_YMIN + //#define ENDSTOPPULLUP_ZMIN + //#define ENDSTOPPULLUP_ZMIN_PROBE +#endif + +// Mechanical endstop with COM to ground and NC to Signal uses "false" here (most common setup). +#define X_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Y_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define X_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Y_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MIN_PROBE_ENDSTOP_INVERTING false // set to true to invert the logic of the probe. + +// Enable this feature if all enabled endstop pins are interrupt-capable. +// This will remove the need to poll the interrupt pins, saving many CPU cycles. +//#define ENDSTOP_INTERRUPTS_FEATURE + +//============================================================================= +//============================== Movement Settings ============================ +//============================================================================= +// @section motion + +/** + * Default Settings + * + * These settings can be reset by M502 + * + * Note that if EEPROM is enabled, saved values will override these. + */ + +/** + * With this option each E stepper can have its own factors for the + * following movement settings. If fewer factors are given than the + * total number of extruders, the last value applies to the rest. + */ +//#define DISTINCT_E_FACTORS + +/** + * Default Axis Steps Per Unit (steps/mm) + * Override with M92 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_AXIS_STEPS_PER_UNIT { 80, 80, 400, 160.6 } + +/** + * Default Max Feed Rate (mm/s) + * Override with M203 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_FEEDRATE { 300, 300, 5, 25 } + +/** + * Default Max Acceleration (change/s) change = mm/s + * (Maximum start speed for accelerated moves) + * Override with M201 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_ACCELERATION { 3000, 3000, 100, 10000 } + +/** + * Default Acceleration (change/s) change = mm/s + * Override with M204 + * + * M204 P Acceleration + * M204 R Retract Acceleration + * M204 T Travel Acceleration + */ +#define DEFAULT_ACCELERATION 3000 // X, Y, Z and E acceleration for printing moves +#define DEFAULT_RETRACT_ACCELERATION 3000 // E acceleration for retracts +#define DEFAULT_TRAVEL_ACCELERATION 3000 // X, Y, Z acceleration for travel (non printing) moves + +/** + * Default Jerk (mm/s) + * Override with M205 X Y Z E + * + * "Jerk" specifies the minimum speed change that requires acceleration. + * When changing speed and direction, if the difference is less than the + * value set here, it may happen instantaneously. + */ +#define DEFAULT_XJERK 20.0 +#define DEFAULT_YJERK 20.0 +#define DEFAULT_ZJERK 0.4 +#define DEFAULT_EJERK 5.0 + +//=========================================================================== +//============================= Z Probe Options ============================= +//=========================================================================== +// @section probes + +// +// See http://marlinfw.org/configuration/probes.html +// + +/** + * Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + * + * Enable this option for a probe connected to the Z Min endstop pin. + */ +#define Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + +/** + * Z_MIN_PROBE_ENDSTOP + * + * Enable this option for a probe connected to any pin except Z-Min. + * (By default Marlin assumes the Z-Max endstop pin.) + * To use a custom Z Probe pin, set Z_MIN_PROBE_PIN below. + * + * - The simplest option is to use a free endstop connector. + * - Use 5V for powered (usually inductive) sensors. + * + * - RAMPS 1.3/1.4 boards may use the 5V, GND, and Aux4->D32 pin: + * - For simple switches connect... + * - normally-closed switches to GND and D32. + * - normally-open switches to 5V and D32. + * + * WARNING: Setting the wrong pin may have unexpected and potentially + * disastrous consequences. Use with caution and do your homework. + * + */ +//#define Z_MIN_PROBE_ENDSTOP + +/** + * Probe Type + * + * Allen Key Probes, Servo Probes, Z-Sled Probes, FIX_MOUNTED_PROBE, etc. + * Activate one of these to use Auto Bed Leveling below. + */ + +/** + * The "Manual Probe" provides a means to do "Auto" Bed Leveling without a probe. + * Use G29 repeatedly, adjusting the Z height at each point with movement commands + * or (with LCD_BED_LEVELING) the LCD controller. + */ +//#define PROBE_MANUALLY + +/** + * A Fix-Mounted Probe either doesn't deploy or needs manual deployment. + * (e.g., an inductive probe or a nozzle-based probe-switch.) + */ +//#define FIX_MOUNTED_PROBE + +/** + * Z Servo Probe, such as an endstop switch on a rotating arm. + */ +//#define Z_ENDSTOP_SERVO_NR 0 // Defaults to SERVO 0 connector. +//#define Z_SERVO_ANGLES {70,0} // Z Servo Deploy and Stow angles + +/** + * The BLTouch probe uses a Hall effect sensor and emulates a servo. + */ +//#define BLTOUCH +#if ENABLED(BLTOUCH) + //#define BLTOUCH_DELAY 375 // (ms) Enable and increase if needed +#endif + +/** + * Enable one or more of the following if probing seems unreliable. + * Heaters and/or fans can be disabled during probing to minimize electrical + * noise. A delay can also be added to allow noise and vibration to settle. + * These options are most useful for the BLTouch probe, but may also improve + * readings with inductive probes and piezo sensors. + */ +//#define PROBING_HEATERS_OFF // Turn heaters off when probing +//#define PROBING_FANS_OFF // Turn fans off when probing +//#define DELAY_BEFORE_PROBING 200 // (ms) To prevent vibrations from triggering piezo sensors + +// A probe that is deployed and stowed with a solenoid pin (SOL1_PIN) +//#define SOLENOID_PROBE + +// A sled-mounted probe like those designed by Charles Bell. +//#define Z_PROBE_SLED +//#define SLED_DOCKING_OFFSET 5 // The extra distance the X axis must travel to pickup the sled. 0 should be fine but you can push it further if you'd like. + +// +// For Z_PROBE_ALLEN_KEY see the Delta example configurations. +// + +/** + * Z Probe to nozzle (X,Y) offset, relative to (0, 0). + * X and Y offsets must be integers. + * + * In the following example the X and Y offsets are both positive: + * #define X_PROBE_OFFSET_FROM_EXTRUDER 10 + * #define Y_PROBE_OFFSET_FROM_EXTRUDER 10 + * + * +-- BACK ---+ + * | | + * L | (+) P | R <-- probe (20,20) + * E | | I + * F | (-) N (+) | G <-- nozzle (10,10) + * T | | H + * | (-) | T + * | | + * O-- FRONT --+ + * (0,0) + */ +#define X_PROBE_OFFSET_FROM_EXTRUDER 10 // X offset: -left +right [of the nozzle] +#define Y_PROBE_OFFSET_FROM_EXTRUDER 10 // Y offset: -front +behind [the nozzle] +#define Z_PROBE_OFFSET_FROM_EXTRUDER 0 // Z offset: -below +above [the nozzle] + +// X and Y axis travel speed (mm/m) between probes +#define XY_PROBE_SPEED 8000 + +// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +#define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z + +// Speed for the "accurate" probe of each point +#define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) + +// Use double touch for probing +//#define PROBE_DOUBLE_TOUCH + +/** + * Z probes require clearance when deploying, stowing, and moving between + * probe points to avoid hitting the bed and other hardware. + * Servo-mounted probes require extra space for the arm to rotate. + * Inductive probes need space to keep from triggering early. + * + * Use these settings to specify the distance (mm) to raise the probe (or + * lower the bed). The values set here apply over and above any (negative) + * probe Z Offset set with Z_PROBE_OFFSET_FROM_EXTRUDER, M851, or the LCD. + * Only integer values >= 1 are valid here. + * + * Example: `M851 Z-5` with a CLEARANCE of 4 => 9mm from bed to nozzle. + * But: `M851 Z+1` with a CLEARANCE of 2 => 2mm from bed to nozzle. + */ +#define Z_CLEARANCE_DEPLOY_PROBE 10 // Z Clearance for Deploy/Stow +#define Z_CLEARANCE_BETWEEN_PROBES 5 // Z Clearance between probe points + +// For M851 give a range for adjusting the Z probe offset +#define Z_PROBE_OFFSET_RANGE_MIN -20 +#define Z_PROBE_OFFSET_RANGE_MAX 20 + +// Enable the M48 repeatability test to test probe accuracy +//#define Z_MIN_PROBE_REPEATABILITY_TEST + +// For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1 +// :{ 0:'Low', 1:'High' } +#define X_ENABLE_ON 0 +#define Y_ENABLE_ON 0 +#define Z_ENABLE_ON 0 +#define E_ENABLE_ON 0 // For all extruders + +// Disables axis stepper immediately when it's not being used. +// 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 +//#define DISABLE_REDUCED_ACCURACY_WARNING + +// @section extruder + +#define DISABLE_E false // For all extruders +#define DISABLE_INACTIVE_EXTRUDER true // Keep only the active extruder enabled. + +// @section machine + +// Invert the stepper direction. Change (or reverse the motor connector) if an axis goes the wrong way. +#define INVERT_X_DIR false +#define INVERT_Y_DIR true +#define INVERT_Z_DIR false + +// Enable this option for Toshiba stepper drivers +//#define CONFIG_STEPPERS_TOSHIBA + +// @section extruder + +// For direct drive extruder v9 set to true, for geared extruder set to false. +#define INVERT_E0_DIR true +#define INVERT_E1_DIR false +#define INVERT_E2_DIR false +#define INVERT_E3_DIR false +#define INVERT_E4_DIR false + +// @section homing + +//#define NO_MOTION_BEFORE_HOMING // Inhibit movement until all axes have been homed + +//#define Z_HOMING_HEIGHT 4 // (in mm) Minimal z height before homing (G28) for Z clearance above the bed, clamps, ... + // Be sure you have this distance over your Z_MAX_POS in case. + +// Direction of endstops when homing; 1=MAX, -1=MIN +// :[-1,1] +#define X_HOME_DIR -1 +#define Y_HOME_DIR 1 +#define Z_HOME_DIR -1 + +// @section machine + +// The size of the print bed +#define X_BED_SIZE 220 +#define Y_BED_SIZE 220 + +// Travel limits (mm) after homing, corresponding to endstop positions. +#define X_MIN_POS 0 +#define Y_MIN_POS 0 +#define Z_MIN_POS 0 +#define X_MAX_POS X_BED_SIZE +#define Y_MAX_POS Y_BED_SIZE +#define Z_MAX_POS 260 + +// If enabled, axes won't move below MIN_POS in response to movement commands. +#define MIN_SOFTWARE_ENDSTOPS +// If enabled, axes won't move above MAX_POS in response to movement commands. +#define MAX_SOFTWARE_ENDSTOPS + +/** + * Filament Runout Sensor + * A mechanical or opto endstop is used to check for the presence of filament. + * + * RAMPS-based boards use SERVO3_PIN. + * For other boards you may need to define FIL_RUNOUT_PIN. + * By default the firmware assumes HIGH = has filament, LOW = ran out + */ +//#define FILAMENT_RUNOUT_SENSOR +#if ENABLED(FILAMENT_RUNOUT_SENSOR) + #define FIL_RUNOUT_INVERTING false // set to true to invert the logic of the sensor. + #define ENDSTOPPULLUP_FIL_RUNOUT // Uncomment to use internal pullup for filament runout pins if the sensor is defined. + #define FILAMENT_RUNOUT_SCRIPT "M600" +#endif + +//=========================================================================== +//=============================== Bed Leveling ============================== +//=========================================================================== +// @section bedlevel + +/** + * Choose one of the options below to enable G29 Bed Leveling. The parameters + * and behavior of G29 will change depending on your selection. + * + * If using a Probe for Z Homing, enable Z_SAFE_HOMING also! + * + * - AUTO_BED_LEVELING_3POINT + * Probe 3 arbitrary points on the bed (that aren't collinear) + * You specify the XY coordinates of all 3 points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_LINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_BILINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a mesh, best for large or uneven beds. + * + * - AUTO_BED_LEVELING_UBL (Unified Bed Leveling) + * A comprehensive bed leveling system combining the features and benefits + * of other systems. UBL also includes integrated Mesh Generation, Mesh + * Validation and Mesh Editing systems. Currently, UBL is only checked out + * for Cartesian Printers. That said, it was primarily designed to correct + * poor quality Delta Printers. If you feel adventurous and have a Delta, + * please post an issue if something doesn't work correctly. Initially, + * you will need to set a reduced bed size so you have a rectangular area + * to test on. + * + * - MESH_BED_LEVELING + * Probe a grid manually + * The result is a mesh, suitable for large or uneven beds. (See BILINEAR.) + * For machines without a probe, Mesh Bed Leveling provides a method to perform + * leveling in steps so you can manually adjust the Z height at each grid-point. + * With an LCD controller the process is guided step-by-step. + */ +//#define AUTO_BED_LEVELING_3POINT +//#define AUTO_BED_LEVELING_LINEAR +//#define AUTO_BED_LEVELING_BILINEAR +//#define AUTO_BED_LEVELING_UBL +//#define MESH_BED_LEVELING + +/** + * Enable detailed logging of G28, G29, M48, etc. + * Turn on with the command 'M111 S32'. + * NOTE: Requires a lot of PROGMEM! + */ +//#define DEBUG_LEVELING_FEATURE + +#if ENABLED(MESH_BED_LEVELING) || ENABLED(AUTO_BED_LEVELING_BILINEAR) || ENABLED(AUTO_BED_LEVELING_UBL) + // Gradually reduce leveling correction until a set height is reached, + // at which point movement will be level to the machine's XY plane. + // The height can be set with M420 Z + #define ENABLE_LEVELING_FADE_HEIGHT +#endif + +#if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Set the number of grid points per dimension. + #define GRID_MAX_POINTS_X 3 + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + // Set the boundaries for probing (where the probe can reach). + #define LEFT_PROBE_BED_POSITION 15 + #define RIGHT_PROBE_BED_POSITION 170 + #define FRONT_PROBE_BED_POSITION 20 + #define BACK_PROBE_BED_POSITION 170 + + // The Z probe minimum outer margin (to validate G29 parameters). + #define MIN_PROBE_EDGE 10 + + // Probe along the Y axis, advancing X after each column + //#define PROBE_Y_FIRST + + #if ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Beyond the probed grid, continue the implied tilt? + // Default is to maintain the height of the nearest edge. + //#define EXTRAPOLATE_BEYOND_GRID + + // + // Experimental Subdivision of the grid by Catmull-Rom method. + // Synthesizes intermediate points to produce a more detailed mesh. + // + //#define ABL_BILINEAR_SUBDIVISION + #if ENABLED(ABL_BILINEAR_SUBDIVISION) + // Number of subdivisions between probe points + #define BILINEAR_SUBDIVISIONS 3 + #endif + + #endif + +#elif ENABLED(AUTO_BED_LEVELING_3POINT) + + // 3 arbitrary points to probe. + // A simple cross-product is used to estimate the plane of the bed. + #define ABL_PROBE_PT_1_X 15 + #define ABL_PROBE_PT_1_Y 180 + #define ABL_PROBE_PT_2_X 15 + #define ABL_PROBE_PT_2_Y 20 + #define ABL_PROBE_PT_3_X 170 + #define ABL_PROBE_PT_3_Y 20 + +#elif ENABLED(AUTO_BED_LEVELING_UBL) + + //=========================================================================== + //========================= Unified Bed Leveling ============================ + //=========================================================================== + + #define UBL_MESH_INSET 1 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 10 // Don't use more than 15 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + #define UBL_PROBE_PT_1_X 39 // Probing points for 3-Point leveling of the mesh + #define UBL_PROBE_PT_1_Y 180 + #define UBL_PROBE_PT_2_X 39 + #define UBL_PROBE_PT_2_Y 20 + #define UBL_PROBE_PT_3_X 180 + #define UBL_PROBE_PT_3_Y 20 + + #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation + #define UBL_MESH_EDIT_MOVES_Z // Sophisticated users prefer no movement of nozzle + +#elif ENABLED(MESH_BED_LEVELING) + + //=========================================================================== + //=================================== Mesh ================================== + //=========================================================================== + + #define MESH_INSET 10 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 3 // Don't use more than 7 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + //#define MESH_G28_REST_ORIGIN // After homing all axes ('G28' or 'G28 XYZ') rest Z at Z_MIN_POS + +#endif // BED_LEVELING + +/** + * Use the LCD controller for bed leveling + * Requires MESH_BED_LEVELING or PROBE_MANUALLY + */ +//#define LCD_BED_LEVELING + +#if ENABLED(LCD_BED_LEVELING) + #define MBL_Z_STEP 0.025 // Step size while manually probing Z axis. + #define LCD_PROBE_Z_RANGE 4 // Z Range centered on Z_MIN_POS for LCD Z adjustment +#endif + +// Add a menu item to move between bed corners for manual bed adjustment +//#define LEVEL_BED_CORNERS + +/** + * Commands to execute at the end of G29 probing. + * Useful to retract or move the Z probe out of the way. + */ +//#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) +//#define BED_CENTER_AT_0_0 + +// Manually set the home position. Leave these undefined for automatic settings. +// For DELTA this is the top-center of the Cartesian print volume. +//#define MANUAL_X_HOME_POS 0 +//#define MANUAL_Y_HOME_POS 0 +//#define MANUAL_Z_HOME_POS 0 + +// Use "Z Safe Homing" to avoid homing with a Z probe outside the bed area. +// +// With this feature enabled: +// +// - 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). +// - 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 axis (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). +#endif + +// Homing speeds (mm/m) +#define HOMING_FEEDRATE_XY (50*60) +#define HOMING_FEEDRATE_Z (4*60) + +//============================================================================= +//============================= Additional Features =========================== +//============================================================================= + +// @section extras + +// +// EEPROM +// +// The microcontroller can store settings in the EEPROM, e.g. max velocity... +// M500 - stores parameters in EEPROM +// M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily). +// M502 - reverts to the default "factory settings". You still need to store them in EEPROM afterwards if you want to. +// +//#define EEPROM_SETTINGS // Enable for M500 and M501 commands +//#define DISABLE_M503 // Saves ~2700 bytes of PROGMEM. Disable for release! +#define EEPROM_CHITCHAT // Give feedback on EEPROM commands. Disable to save PROGMEM. + +// +// Host Keepalive +// +// When enabled Marlin will send a busy status message to the host +// every couple of seconds when it can't accept commands. +// +#define HOST_KEEPALIVE_FEATURE // Disable this if your host doesn't like keepalive messages +#define DEFAULT_KEEPALIVE_INTERVAL 2 // Number of seconds between "busy" messages. Set with M113. +#define BUSY_WHILE_HEATING // Some hosts require "busy" messages even during heating + +// +// M100 Free Memory Watcher +// +//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose + +// +// G20/G21 Inch mode support +// +//#define INCH_MODE_SUPPORT + +// +// M149 Set temperature units support +// +//#define TEMPERATURE_UNITS_SUPPORT + +// @section temperature + +// Preheat Constants +#define PREHEAT_1_TEMP_HOTEND 180 +#define PREHEAT_1_TEMP_BED 70 +#define PREHEAT_1_FAN_SPEED 0 // Value from 0 to 255 + +#define PREHEAT_2_TEMP_HOTEND 240 +#define PREHEAT_2_TEMP_BED 110 +#define PREHEAT_2_FAN_SPEED 0 // Value from 0 to 255 + +/** + * Nozzle Park -- EXPERIMENTAL + * + * Park the nozzle at the given XYZ position on idle or G27. + * + * The "P" parameter controls the action applied to the Z axis: + * + * P0 (Default) If Z is below park Z raise the nozzle. + * P1 Raise the nozzle always to Z-park height. + * P2 Raise the nozzle by Z-park amount, limited to Z_MAX_POS. + */ +//#define NOZZLE_PARK_FEATURE + +#if ENABLED(NOZZLE_PARK_FEATURE) + // Specify a park position as { X, Y, Z } + #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 } +#endif + +/** + * Clean Nozzle Feature -- EXPERIMENTAL + * + * Adds the G12 command to perform a nozzle cleaning process. + * + * Parameters: + * P Pattern + * S Strokes / Repetitions + * T Triangles (P1 only) + * + * Patterns: + * P0 Straight line (default). This process requires a sponge type material + * at a fixed bed location. "S" specifies strokes (i.e. back-forth motions) + * between the start / end points. + * + * P1 Zig-zag pattern between (X0, Y0) and (X1, Y1), "T" specifies the + * number of zig-zag triangles to do. "S" defines the number of strokes. + * Zig-zags are done in whichever is the narrower dimension. + * For example, "G12 P1 S1 T3" will execute: + * + * -- + * | (X0, Y1) | /\ /\ /\ | (X1, Y1) + * | | / \ / \ / \ | + * A | | / \ / \ / \ | + * | | / \ / \ / \ | + * | (X0, Y0) | / \/ \/ \ | (X1, Y0) + * -- +--------------------------------+ + * |________|_________|_________| + * T1 T2 T3 + * + * P2 Circular pattern with middle at NOZZLE_CLEAN_CIRCLE_MIDDLE. + * "R" specifies the radius. "S" specifies the stroke count. + * Before starting, the nozzle moves to NOZZLE_CLEAN_START_POINT. + * + * Caveats: The ending Z should be the same as starting Z. + * Attention: EXPERIMENTAL. G-code arguments may change. + * + */ +//#define NOZZLE_CLEAN_FEATURE + +#if ENABLED(NOZZLE_CLEAN_FEATURE) + // Default number of pattern repetitions + #define NOZZLE_CLEAN_STROKES 12 + + // Default number of triangles + #define NOZZLE_CLEAN_TRIANGLES 3 + + // Specify positions as { X, Y, Z } + #define NOZZLE_CLEAN_START_POINT { 30, 30, (Z_MIN_POS + 1)} + #define NOZZLE_CLEAN_END_POINT {100, 60, (Z_MIN_POS + 1)} + + // Circular pattern radius + #define NOZZLE_CLEAN_CIRCLE_RADIUS 6.5 + // Circular pattern circle fragments number + #define NOZZLE_CLEAN_CIRCLE_FN 10 + // Middle point of circle + #define NOZZLE_CLEAN_CIRCLE_MIDDLE NOZZLE_CLEAN_START_POINT + + // Moves the nozzle to the initial position + #define NOZZLE_CLEAN_GOBACK +#endif + +/** + * Print Job Timer + * + * Automatically start and stop the print job timer on M104/M109/M190. + * + * M104 (hotend, no wait) - high temp = none, low temp = stop timer + * M109 (hotend, wait) - high temp = start timer, low temp = stop timer + * M190 (bed, wait) - high temp = start timer, low temp = none + * + * The timer can also be controlled with the following commands: + * + * M75 - Start the print job timer + * M76 - Pause the print job timer + * M77 - Stop the print job timer + */ +#define PRINTJOB_TIMER_AUTOSTART + +/** + * Print Counter + * + * Track statistical data such as: + * + * - Total print jobs + * - Total successful print jobs + * - Total failed print jobs + * - Total time printing + * + * View the current statistics with M78. + */ +//#define PRINTCOUNTER + +//============================================================================= +//============================= LCD and SD support ============================ +//============================================================================= + +// @section lcd + +/** + * LCD LANGUAGE + * + * Select the language to display on the LCD. These languages are available: + * + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, + * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * tr, uk, zh_CN, zh_TW, test + * + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + */ +#define LCD_LANGUAGE en + +/** + * LCD Character Set + * + * Note: This option is NOT applicable to Graphical Displays. + * + * All character-based LCDs provide ASCII plus one of these + * language extensions: + * + * - JAPANESE ... the most common + * - WESTERN ... with more accented characters + * - CYRILLIC ... for the Russian language + * + * To determine the language extension installed on your controller: + * + * - Compile and upload with LCD_LANGUAGE set to 'test' + * - 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 + * + * :['JAPANESE', 'WESTERN', 'CYRILLIC'] + */ +#define DISPLAY_CHARSET_HD44780 JAPANESE + +/** + * LCD TYPE + * + * Enable ULTRA_LCD for a 16x2, 16x4, 20x2, or 20x4 character-based LCD. + * Enable DOGLCD for a 128x64 (ST7565R) Full Graphical Display. + * (These options will be enabled automatically for most displays.) + * + * IMPORTANT: The U8glib library is required for Full Graphic Display! + * https://github.com/olikraus/U8glib_Arduino + */ +//#define ULTRA_LCD // Character based +//#define DOGLCD // Full graphics display + +/** + * SD CARD + * + * 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 + +/** + * SD CARD: SPI SPEED + * + * Enable one of the following items for a slower SPI transfer speed. + * This may be required to resolve "volume init" errors. + */ +//#define SPI_SPEED SPI_HALF_SPEED +//#define SPI_SPEED SPI_QUARTER_SPEED +//#define SPI_SPEED SPI_EIGHTH_SPEED + +/** + * SD CARD: ENABLE CRC + * + * Use CRC checks and retries on the SD communication. + */ +//#define SD_CHECK_AND_RETRY + +// +// ENCODER SETTINGS +// +// This option overrides the default number of encoder pulses needed to +// produce one step. Should be increased for high-resolution encoders. +// +//#define ENCODER_PULSES_PER_STEP 1 + +// +// Use this option to override the number of step signals required to +// move between next/prev menu items. +// +//#define ENCODER_STEPS_PER_MENU_ITEM 5 + +/** + * Encoder Direction Options + * + * Test your encoder's behavior first with both options disabled. + * + * Reversed Value Edit and Menu Nav? Enable REVERSE_ENCODER_DIRECTION. + * Reversed Menu Navigation only? Enable REVERSE_MENU_DIRECTION. + * Reversed Value Editing only? Enable BOTH options. + */ + +// +// This option reverses the encoder direction everywhere. +// +// Set this option if CLOCKWISE causes values to DECREASE +// +//#define REVERSE_ENCODER_DIRECTION + +// +// This option reverses the encoder direction for navigating LCD menus. +// +// If CLOCKWISE normally moves DOWN this makes it go UP. +// If CLOCKWISE normally moves UP this makes it go DOWN. +// +//#define REVERSE_MENU_DIRECTION + +// +// Individual Axis Homing +// +// Add individual axis homing items (Home X, Home Y, and Home Z) to the LCD menu. +// +//#define INDIVIDUAL_AXIS_HOMING_MENU + +// +// SPEAKER/BUZZER +// +// If you have a speaker that can produce tones, enable it here. +// By default Marlin assumes you have a buzzer with a fixed frequency. +// +//#define SPEAKER + +// +// The duration and frequency for the UI feedback sound. +// Set these to 0 to disable audio feedback in the LCD menus. +// +// Note: Test audio output with the G-Code: +// M300 S P +// +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 +//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 + +// +// CONTROLLER TYPE: Standard +// +// Marlin supports a wide variety of controllers. +// Enable one of the following options to specify your controller. +// + +// +// ULTIMAKER Controller. +// +//#define ULTIMAKERCONTROLLER + +// +// ULTIPANEL as seen on Thingiverse. +// +//#define ULTIPANEL + +// +// PanelOne from T3P3 (via RAMPS 1.4 AUX2/AUX3) +// http://reprap.org/wiki/PanelOne +// +//#define PANEL_ONE + +// +// MaKr3d Makr-Panel with graphic controller and SD support. +// http://reprap.org/wiki/MaKr3d_MaKrPanel +// +//#define MAKRPANEL + +// +// ReprapWorld Graphical LCD +// https://reprapworld.com/?products_details&products_id/1218 +// +//#define REPRAPWORLD_GRAPHICAL_LCD + +// +// Activate one of these if you have a Panucatt Devices +// Viki 2.0 or mini Viki with Graphic LCD +// http://panucatt.com +// +//#define VIKI2 +//#define miniVIKI + +// +// Adafruit ST7565 Full Graphic Controller. +// https://github.com/eboston/Adafruit-ST7565-Full-Graphic-Controller/ +// +//#define ELB_FULL_GRAPHIC_CONTROLLER + +// +// RepRapDiscount Smart Controller. +// http://reprap.org/wiki/RepRapDiscount_Smart_Controller +// +// Note: Usually sold with a white PCB. +// +#define REPRAP_DISCOUNT_SMART_CONTROLLER + +// +// GADGETS3D G3D LCD/SD Controller +// http://reprap.org/wiki/RAMPS_1.3/1.4_GADGETS3D_Shield_with_Panel +// +// Note: Usually sold with a blue PCB. +// +//#define G3D_PANEL + +// +// RepRapDiscount FULL GRAPHIC Smart Controller +// http://reprap.org/wiki/RepRapDiscount_Full_Graphic_Smart_Controller +// +//#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER + +// +// MakerLab Mini Panel with graphic +// controller and SD support - http://reprap.org/wiki/Mini_panel +// +//#define MINIPANEL + +// +// RepRapWorld REPRAPWORLD_KEYPAD v1.1 +// http://reprapworld.com/?products_details&products_id=202&cPath=1591_1626 +// +// REPRAPWORLD_KEYPAD_MOVE_STEP sets how much should the robot move when a key +// is pressed, a value of 10.0 means 10mm per click. +// +//#define REPRAPWORLD_KEYPAD +//#define REPRAPWORLD_KEYPAD_MOVE_STEP 1.0 + +// +// RigidBot Panel V1.0 +// http://www.inventapart.com/ +// +//#define RIGIDBOT_PANEL + +// +// BQ LCD Smart Controller shipped by +// default with the BQ Hephestos 2 and Witbox 2. +// +//#define BQ_LCD_SMART_CONTROLLER + +// +// Cartesio UI +// http://mauk.cc/webshop/cartesio-shop/electronics/user-interface +// +//#define CARTESIO_UI + +// +// ANET_10 Controller supported displays. +// +//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. + // This LCD is known to be susceptible to electrical interference + // which scrambles the display. Pressing any button clears it up. +//#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 + // A clone of the RepRapDiscount full graphics display but with + // different pins/wiring (see pins_ANET_10.h). + +// +// LCD for Melzi Card with Graphical LCD +// +//#define LCD_FOR_MELZI + +// +// CONTROLLER TYPE: I2C +// +// Note: These controllers require the installation of Arduino's LiquidCrystal_I2C +// library. For more info: https://github.com/kiyoshigawa/LiquidCrystal_I2C +// + +// +// Elefu RA Board Control Panel +// http://www.elefu.com/index.php?route=product/product&product_id=53 +// +//#define RA_CONTROL_PANEL + +// +// Sainsmart YW Robot (LCM1602) LCD Display +// +// Note: This controller requires F.Malpartida's LiquidCrystal_I2C library +// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home +// +//#define LCD_I2C_SAINSMART_YWROBOT + +// +// Generic LCM1602 LCD adapter +// +//#define LCM1602 + +// +// PANELOLU2 LCD with status LEDs, +// separate encoder and click inputs. +// +// Note: This controller requires Arduino's LiquidTWI2 library v1.2.3 or later. +// For more info: https://github.com/lincomatic/LiquidTWI2 +// +// Note: The PANELOLU2 encoder click input can either be directly connected to +// a pin (if BTN_ENC defined to != -1) or read through I2C (when BTN_ENC == -1). +// +//#define LCD_I2C_PANELOLU2 + +// +// Panucatt VIKI LCD with status LEDs, +// integrated click & L/R/U/D buttons, separate encoder inputs. +// +//#define LCD_I2C_VIKI + +// +// SSD1306 OLED full graphics generic display +// +//#define U8GLIB_SSD1306 + +// +// SAV OLEd LCD module support using either SSD1306 or SH1106 based LCD modules +// +//#define SAV_3DGLCD +#if ENABLED(SAV_3DGLCD) + //#define U8GLIB_SSD1306 + #define U8GLIB_SH1106 +#endif + +// +// CONTROLLER TYPE: Shift register panels +// +// 2 wire Non-latching LCD SR from https://goo.gl/aJJ4sH +// LCD configuration: http://reprap.org/wiki/SAV_3D_LCD +// +//#define SAV_3DLCD + +// +// TinyBoy2 128x64 OLED / Encoder Panel +// +//#define OLED_PANEL_TINYBOY2 + +// +// Makeboard 3D Printer Parts 3D Printer Mini Display 1602 Mini Controller +// https://www.aliexpress.com/item/Micromake-Makeboard-3D-Printer-Parts-3D-Printer-Mini-Display-1602-Mini-Controller-Compatible-with-Ramps-1/32765887917.html +// +//#define MAKEBOARD_MINI_2_LINE_DISPLAY_1602 + +// +// MKS MINI12864 with graphic controller and SD support +// http://reprap.org/wiki/MKS_MINI_12864 +// +//#define MKS_MINI_12864 + +// +// Factory display for Creality CR-10 +// https://www.aliexpress.com/item/Universal-LCD-12864-3D-Printer-Display-Screen-With-Encoder-For-CR-10-CR-7-Model/32833148327.html +// +// This is RAMPS-compatible using a single 10-pin connector. +// (For CR-10 owners who want to replace the Melzi Creality board but retain the display) +// +//#define CR10_STOCKDISPLAY + +// +// MKS OLED 1.3" 128 × 64 FULL GRAPHICS CONTROLLER +// http://reprap.org/wiki/MKS_12864OLED +// +// Tiny, but very sharp OLED display +// +//#define MKS_12864OLED + +//============================================================================= +//=============================== Extra Features ============================== +//============================================================================= + +// @section extras + +// Increase the FAN PWM frequency. Removes the PWM noise but increases heating in the FET/Arduino +//#define FAST_PWM_FAN + +// Use software PWM to drive the fan, as for the heaters. This uses a very low frequency +// which is not as annoying as with the hardware PWM. On the other hand, if this frequency +// is too low, you should also increment SOFT_PWM_SCALE. +//#define FAN_SOFT_PWM + +// Incrementing this by 1 will double the software PWM frequency, +// affecting heaters, and the fan if FAN_SOFT_PWM is enabled. +// However, control resolution will be halved for each increment; +// at zero value, there are 128 effective control positions. +#define SOFT_PWM_SCALE 0 + +// If SOFT_PWM_SCALE is set to a value higher than 0, dithering can +// be used to mitigate the associated resolution loss. If enabled, +// some of the PWM cycles are stretched so on average the desired +// duty cycle is attained. +//#define SOFT_PWM_DITHER + +// Temperature status LEDs that display the hotend and bed temperature. +// If all hotends, bed temperature, and target temperature are under 54C +// then the BLUE led is on. Otherwise the RED led is on. (1C hysteresis) +//#define TEMP_STAT_LEDS + +// M240 Triggers a camera by emulating a Canon RC-1 Remote +// Data from: http://www.doc-diy.net/photo/rc-1_hacked/ +//#define PHOTOGRAPH_PIN 23 + +// 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 + +// Support for BlinkM/CyzRgb +//#define BLINKM + +// Support for PCA9632 PWM LED driver +//#define PCA9632 + +/** + * RGB LED / LED Strip Control + * + * Enable support for an RGB LED connected to 5V digital pins, or + * an RGB Strip connected to MOSFETs controlled by digital pins. + * + * 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 overall brightness parameters is also available + * + * *** CAUTION *** + * LED Strips require a MOFSET 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! + * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino + * cannot handle such current, separate 5V power supply must be used + * *** CAUTION *** + * + * LED type. This options are mutualy exclusive. Uncomment only one. + * + */ +//#define RGB_LED +//#define RGBW_LED + +#if ENABLED(RGB_LED) || ENABLED(RGBW_LED) + #define RGB_LED_R_PIN 34 + #define RGB_LED_G_PIN 43 + #define RGB_LED_B_PIN 35 + #define RGB_LED_W_PIN -1 +#endif + +// 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 (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) + #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip + #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time + #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + //#define NEOPIXEL_STARTUP_TEST // Cycle through colors at startup +#endif + +/** + * Printer Event LEDs + * + * During printing, the LEDs will reflect the printer status: + * + * - Gradually change from blue to violet as the heated bed gets to target temp + * - Gradually change from violet to red as the hotend gets to temperature + * - Change to white to illuminate work surface + * - Change to green once print has finished + * - Turn off after the print has finished and the user has pushed a button + */ +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) + #define PRINTER_EVENT_LEDS +#endif + +/*********************************************************************\ +* R/C SERVO support +* Sponsored by TrinityLabs, Reworked by codexmas +**********************************************************************/ + +// Number of servos +// +// If you select a configuration below, this will receive a default value and does not need to be set manually +// set it manually if you have more servos than extruders and wish to manually control some +// leaving it undefined or defining as 0 will disable the servo subsystem +// If unsure, leave commented / disabled +// +//#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command + +// Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. +// 300ms is a good value but you can try less delay. +// If the servo can't reach the requested position, increase it. +#define SERVO_DELAY { 300 } + +// Servo deactivation +// +// With this option servos are powered only during movement, then turned off to prevent jitter. +//#define DEACTIVATE_SERVOS_AFTER_MOVE + +/** + * Filament Width Sensor + * + * Measures the filament width in real-time and adjusts + * flow rate to compensate for any irregularities. + * + * Also allows the measured filament diameter to set the + * extrusion rate, so the slicer only has to specify the + * volume. + * + * Only a single extruder is supported at this time. + * + * 34 RAMPS_14 : Analog input 5 on the AUX2 connector + * 81 PRINTRBOARD : Analog input 2 on the Exp1 connector (version B,C,D,E) + * 301 RAMBO : Analog input 3 + * + * Note: May require analog pins to be defined for other boards. + */ +//#define FILAMENT_WIDTH_SENSOR + +#define DEFAULT_NOMINAL_FILAMENT_DIA 3.00 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. + +#if ENABLED(FILAMENT_WIDTH_SENSOR) + #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) + #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber + + #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading + #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading + #define MAX_MEASUREMENT_DELAY 20 // (bytes) Buffer size for stored measurements (1 byte per cm). Must be larger than MEASUREMENT_DELAY_CM. + + #define DEFAULT_MEASURED_FILAMENT_DIA DEFAULT_NOMINAL_FILAMENT_DIA // Set measured to nominal initially + + // Display filament width on the LCD status line. Status messages will expire after 5 seconds. + //#define FILAMENT_LCD_DISPLAY +#endif + +#endif // CONFIGURATION_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/AliExpress/CL-260/README.txt b/trunk/Arduino/Marlin_1.1.6/example_configurations/AliExpress/CL-260/README.txt new file mode 100644 index 00000000..b8d6856a --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/AliExpress/CL-260/README.txt @@ -0,0 +1,15 @@ +This is an example configuration for the CL-260 Ultimaker 2 clone. +Change Z_MAX_POS to 300 for the CL-260MAX. + +(The printer is available on AliExpress; be aware that this is not a beginner's +printer -- it needs tweaking and some parts replaced before being decent.) + +The printer comes with a quite old Marlin, the sources are available here: +http://www.thingiverse.com/thing:1635830/ and I recommend replacing them. + +The setting "works" for my printer and the extruder using my calibration value. +You might want to tweak some settings, e.g enable EEPROM, increase default Z speed, adjust homing speeds,... + +Have fun! +-- +tobi diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/Anet/A6/Configuration.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/Anet/A6/Configuration.h new file mode 100644 index 00000000..a371f3e8 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/Anet/A6/Configuration.h @@ -0,0 +1,1859 @@ +/** + * 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 . + * + */ + +/** + * Configuration.h + * + * Basic settings such as: + * + * - Type of electronics + * - Type of temperature sensor + * - Printer geometry + * - Endstop configuration + * - LCD controller + * - Extra features + * + * Advanced settings can be found in Configuration_adv.h + * + */ +#ifndef CONFIGURATION_H +#define CONFIGURATION_H +#define CONFIGURATION_H_VERSION 010100 + +//=========================================================================== +//============================= Getting Started ============================= +//=========================================================================== + +/** + * Here are some standard links for getting your machine calibrated: + * + * http://reprap.org/wiki/Calibration + * http://youtu.be/wAL9d7FgInk + * http://calculator.josefprusa.cz + * http://reprap.org/wiki/Triffid_Hunter%27s_Calibration_Guide + * http://www.thingiverse.com/thing:5573 + * https://sites.google.com/site/repraplogphase/calibration-of-your-reprap + * http://www.thingiverse.com/thing:298812 + */ + +//=========================================================================== +//============================= DELTA Printer =============================== +//=========================================================================== +// For a Delta printer start with one of the configuration files in the +// example_configurations/delta directory and customize for your machine. +// + +//=========================================================================== +//============================= SCARA Printer =============================== +//=========================================================================== +// For a SCARA printer start with the configuration files in +// example_configurations/SCARA and customize for your machine. +// + +// @section info + +// User-specified version info of this build to display in [Pronterface, etc] terminal window during +// startup. Implementation of an idea by Prof Braino to inform user that any changes made to this +// build by the user have been successfully uploaded into firmware. +#define STRING_CONFIG_H_AUTHOR "(Ralf_E, ANET A6 config)" // Who made the changes. +#define SHOW_BOOTSCREEN +#define STRING_SPLASH_LINE1 SHORT_BUILD_VERSION // will be shown during bootup in line 1 +#define STRING_SPLASH_LINE2 WEBSITE_URL // will be shown during bootup in line 2 + +// +// *** VENDORS PLEASE READ ***************************************************** +// +// Marlin now allow you to have a vendor boot image to be displayed on machine +// start. When SHOW_CUSTOM_BOOTSCREEN is defined Marlin will first show your +// custom boot image and then the default Marlin boot image is shown. +// +// We suggest for you to take advantage of this new feature and keep the Marlin +// boot image unmodified. For an example have a look at the bq Hephestos 2 +// example configuration folder. +// +//#define SHOW_CUSTOM_BOOTSCREEN +// @section machine + +/** + * Select which serial port on the board will be used for communication with the host. + * This allows the connection of wireless adapters (for instance) to non-default port pins. + * Serial port 0 is always used by the Arduino bootloader regardless of this setting. + * + * :[0, 1, 2, 3, 4, 5, 6, 7] + */ +#define SERIAL_PORT 0 + +/** + * This setting determines the communication speed of the printer. + * + * 250000 works in most cases, but you might try a lower speed if + * you commonly experience drop-outs during host printing. + * You may try up to 1000000 to speed up SD file transfer. + * + * :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000] + */ +#define BAUDRATE 115200 + +// Enable the Bluetooth serial interface on AT90USB devices +//#define BLUETOOTH + +// The following define selects which electronics board you have. +// Please choose the name from boards.h that matches your setup +#ifndef MOTHERBOARD + #define MOTHERBOARD BOARD_ANET_10 +#endif + +// Optional custom name for your RepStrap or other custom machine +// Displayed in the LCD "Ready" message +//#define CUSTOM_MACHINE_NAME "3D Printer" + +// Define this to set a unique identifier for this printer, (Used by some programs to differentiate between machines) +// You can use an online service to generate a random UUID. (eg http://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] +#define EXTRUDERS 1 + +// For Cyclops or any "multi-extruder" that shares a single nozzle. +//#define SINGLENOZZLE + +/** + * Průša MK2 Single Nozzle Multi-Material Multiplexer, and variants. + * + * This device allows one stepper driver on a control board to drive + * two to eight stepper motors, one at a time, in a manner suitable + * for extruders. + * + * This option only allows the multiplexer to switch on tool-change. + * Additional options to configure custom E moves are pending. + */ +//#define MK2_MULTIPLEXER +#if ENABLED(MK2_MULTIPLEXER) + // Override the default DIO selector pins here, if needed. + // Some pins files may provide defaults for these pins. + //#define E_MUX0_PIN 40 // Always Required + //#define E_MUX1_PIN 42 // Needed for 3 to 8 steppers + //#define E_MUX2_PIN 44 // Needed for 5 to 8 steppers +#endif + +// A dual extruder that uses a single stepper motor +//#define SWITCHING_EXTRUDER +#if ENABLED(SWITCHING_EXTRUDER) + #define SWITCHING_EXTRUDER_SERVO_NR 0 + #define SWITCHING_EXTRUDER_SERVO_ANGLES { 0, 90 } // Angles for E0, E1[, E2, E3] + #if EXTRUDERS > 3 + #define SWITCHING_EXTRUDER_E23_SERVO_NR 1 + #endif +#endif + +// A dual-nozzle that uses a servomotor to raise/lower one of the nozzles +//#define SWITCHING_NOZZLE +#if ENABLED(SWITCHING_NOZZLE) + #define SWITCHING_NOZZLE_SERVO_NR 0 + #define SWITCHING_NOZZLE_SERVO_ANGLES { 0, 90 } // Angles for E0, E1 + //#define HOTEND_OFFSET_Z { 0.0, 0.0 } +#endif + +/** + * Two separate X-carriages with extruders that connect to a moving part + * via a magnetic docking mechanism. Requires SOL1_PIN and SOL2_PIN. + */ +//#define PARKING_EXTRUDER +#if ENABLED(PARKING_EXTRUDER) + #define PARKING_EXTRUDER_SOLENOIDS_INVERT // If enabled, the solenoid is NOT magnetized with applied voltage + #define PARKING_EXTRUDER_SOLENOIDS_PINS_ACTIVE LOW // LOW or HIGH pin signal energizes the coil + #define PARKING_EXTRUDER_SOLENOIDS_DELAY 250 // Delay (ms) for magnetic field. No delay if 0 or not defined. + #define PARKING_EXTRUDER_PARKING_X { -78, 184 } // X positions for parking the extruders + #define PARKING_EXTRUDER_GRAB_DISTANCE 1 // mm to move beyond the parking point to grab the extruder + #define PARKING_EXTRUDER_SECURITY_RAISE 5 // Z-raise before parking + #define HOTEND_OFFSET_Z { 0.0, 1.3 } // Z-offsets of the two hotends. The first must be 0. +#endif + +/** + * "Mixing Extruder" + * - Adds a new code, M165, to set the current mix factors. + * - Extends the stepping routines to move multiple steppers in proportion to the mix. + * - Optional support for Repetier Firmware M163, M164, and virtual extruder. + * - This implementation supports only a single extruder. + * - Enable DIRECT_MIXING_IN_G1 for Pia Taubert's reference implementation + */ +//#define MIXING_EXTRUDER +#if ENABLED(MIXING_EXTRUDER) + #define MIXING_STEPPERS 2 // Number of steppers in your mixing extruder + #define MIXING_VIRTUAL_TOOLS 16 // Use the Virtual Tool method with M163 and M164 + //#define DIRECT_MIXING_IN_G1 // Allow ABCDHI mix factors in G1 movement commands +#endif + +// Offset of the extruders (uncomment if using more than one and relying on firmware to position when changing). +// The offset has to be X=0, Y=0 for the extruder 0 hotend (default extruder). +// For the other hotends it is their distance from the extruder 0 hotend. +//#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis +//#define HOTEND_OFFSET_Y {0.0, 5.00} // (in mm) for each extruder, offset of the hotend on the Y axis + +// @section machine + +/** + * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN + * + * 0 = No Power Switch + * 1 = ATX + * 2 = X-Box 360 203Watts (the blue wire connected to PS_ON and the red wire to VCC) + * + * :{ 0:'No power switch', 1:'ATX', 2:'X-Box 360' } + */ +#define POWER_SUPPLY 0 + +#if POWER_SUPPLY > 0 + // Enable this option to leave the PSU off at startup. + // Power to steppers and heaters will need to be turned on with M80. + //#define PS_DEFAULT_OFF +#endif + +// @section temperature + +//=========================================================================== +//============================= Thermal Settings ============================ +//=========================================================================== + +/** + * --NORMAL IS 4.7kohm PULLUP!-- 1kohm pullup can be used on hotend sensor, using correct resistor and table + * + * Temperature sensors available: + * + * -3 : thermocouple with MAX31855 (only for sensor 0) + * -2 : thermocouple with MAX6675 (only for sensor 0) + * -1 : thermocouple with AD595 + * 0 : not used + * 1 : 100k thermistor - best choice for EPCOS 100k (4.7k pullup) + * 2 : 200k thermistor - ATC Semitec 204GT-2 (4.7k pullup) + * 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 (Used in ParCan & J-Head) (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) + * 71 : 100k Honeywell thermistor 135-104LAF-J01 (4.7k pullup) + * 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) + * 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" + * 20 : the PT100 circuit found in the Ultimainboard V2.x + * 60 : 100k Maker's Tool Works Kapton Bed Thermistor beta=3950 + * 66 : 4.7M High Temperature thermistor from Dyze Design + * 70 : the 100K thermistor found in the bq Hephestos 2 + * 75 : 100k Generic Silicon Heat Pad with NTC 100K MGB18-104F39050L32 thermistor + * + * 1k ohm pullup tables - This is atypical, and requires changing out the 4.7k pullup for 1k. + * (but gives greater accuracy and more stable PID) + * 51 : 100k thermistor - EPCOS (1k pullup) + * 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 + * 1010 : Pt1000 with 1k pullup (non standard) + * 147 : Pt100 with 4k7 pullup + * 110 : Pt100 with 1k pullup (non standard) + * + * Use these for Testing or Development purposes. NEVER for production machine. + * 998 : Dummy Table that ALWAYS reads 25°C or the temperature defined below. + * 999 : Dummy Table that ALWAYS reads 100°C or the temperature defined below. + * + * :{ '0': "Not used", '1':"100k / 4.7k - EPCOS", '2':"200k / 4.7k - ATC Semitec 204GT-2", '3':"Mendel-parts / 4.7k", '4':"10k !! do not use for a hotend. Bad resolution at high temp. !!", '5':"100K / 4.7k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '6':"100k / 4.7k EPCOS - Not as accurate as Table 1", '7':"100k / 4.7k Honeywell 135-104LAG-J01", '8':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT", '9':"100k / 4.7k GE Sensing AL03006-58.2K-97-G1", '10':"100k / 4.7k RS 198-961", '11':"100k / 4.7k beta 3950 1%", '12':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT (calibrated for Makibox hot bed)", '13':"100k Hisens 3950 1% up to 300°C for hotend 'Simple ONE ' & hotend 'All In ONE'", '20':"PT100 (Ultimainboard V2.x)", '51':"100k / 1k - EPCOS", '52':"200k / 1k - ATC Semitec 204GT-2", '55':"100k / 1k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '60':"100k Maker's Tool Works Kapton Bed Thermistor beta=3950", '66':"Dyze Design 4.7M High Temperature thermistor", '70':"the 100K thermistor found in the bq Hephestos 2", '71':"100k / 4.7k Honeywell 135-104LAF-J01", '147':"Pt100 / 4.7k", '1047':"Pt1000 / 4.7k", '110':"Pt100 / 1k (non-standard)", '1010':"Pt1000 / 1k (non standard)", '-3':"Thermocouple + MAX31855 (only for sensor 0)", '-2':"Thermocouple + MAX6675 (only for sensor 0)", '-1':"Thermocouple + AD595",'998':"Dummy 1", '999':"Dummy 2" } + */ +#define TEMP_SENSOR_0 5 +#define TEMP_SENSOR_1 0 +#define TEMP_SENSOR_2 0 +#define TEMP_SENSOR_3 0 +#define TEMP_SENSOR_4 0 +#define TEMP_SENSOR_BED 5 + +// Dummy thermistor constant temperature readings, for use with 998 and 999 +#define DUMMY_THERMISTOR_998_VALUE 25 +#define DUMMY_THERMISTOR_999_VALUE 100 + +// 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 +#define MAX_REDUNDANT_TEMP_SENSOR_DIFF 10 + +// Extruder temperature must be close to target for this long before M109 returns success +#define TEMP_RESIDENCY_TIME 10 // (seconds) +#define TEMP_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// Bed temperature must be close to target for this long before M190 returns success +#define TEMP_BED_RESIDENCY_TIME 10 // (seconds) +#define TEMP_BED_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_BED_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// The minimal temperature defines the temperature below which the heater will not be enabled It is used +// to check that the wiring to the thermistor is not broken. +// Otherwise this would lead to the heater being powered on all the time. +#define HEATER_0_MINTEMP 5 +#define HEATER_1_MINTEMP 5 +#define HEATER_2_MINTEMP 5 +#define HEATER_3_MINTEMP 5 +#define HEATER_4_MINTEMP 5 +#define BED_MINTEMP 5 + +// When temperature exceeds max temp, your heater will be switched off. +// This feature exists to protect your hotend from overheating accidentally, but *NOT* from thermistor short/failure! +// You should use MINTEMP for thermistor short/failure protection. +#define HEATER_0_MAXTEMP 275 +#define HEATER_1_MAXTEMP 275 +#define HEATER_2_MAXTEMP 275 +#define HEATER_3_MAXTEMP 275 +#define HEATER_4_MAXTEMP 275 +#define BED_MAXTEMP 130 + +//=========================================================================== +//============================= PID Settings ================================ +//=========================================================================== +// PID Tuning Guide here: http://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 +#if ENABLED(PIDTEMP) + //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. + //#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. + #define K1 0.95 //smoothing factor within the PID + + // 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 + + // ANET A6 Firmware V2.0 Standard Extruder defaults: + // PID-P: +022.20, PID-I: +001.08, PID-D: +114.00, PID-C: 1 + //#define DEFAULT_Kp 22.2 + //#define DEFAULT_Ki 1.08 + //#define DEFAULT_Kd 114.0 + + // Tuned by ralf-e. Always re-tune for your machine! + #define DEFAULT_Kp 16.83 + #define DEFAULT_Ki 1.02 + #define DEFAULT_Kd 69.29 + +#endif // PIDTEMP + +//=========================================================================== +//============================= PID > Bed Temperature Control =============== +//=========================================================================== +// Select PID or bang-bang with PIDTEMPBED. If bang-bang, BED_LIMIT_SWITCHING will enable hysteresis +// +// Uncomment this to enable PID on the bed. It uses the same frequency PWM as the extruder. +// If your PID_dT is the default, and correct for your hardware/configuration, that means 7.689Hz, +// which is fine for driving a square wave into a resistive load and does not significantly impact you FET heating. +// This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W heater. +// If your configuration is significantly different than this and you don't understand the issues involved, you probably +// shouldn't use bed PID until someone else verifies your hardware works. +// If this is enabled, find your own PID constants below. +#define PIDTEMPBED + +//#define BED_LIMIT_SWITCHING + +// This sets the max power delivered to the bed, and replaces the HEATER_BED_DUTY_CYCLE_DIVIDER option. +// all forms of bed control obey this (PID, bang-bang, bang-bang with hysteresis) +// setting this to anything other than 255 enables a form of PWM to the bed just like HEATER_BED_DUTY_CYCLE_DIVIDER did, +// so you shouldn't use it unless you are OK with PWM on your bed. (see the comment on enabling PIDTEMPBED) +#define MAX_BED_POWER 255 // limits duty cycle to bed; 255=full current + +#if ENABLED(PIDTEMPBED) + + //#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) + //#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 + + // ANET A6 + // original Bed + 0.3mm Heat conducting into 4mm borosilicate (PID-Autotune: M303 E-1 S60 C5): + //#define DEFAULT_bedKp 295.00 + //#define DEFAULT_bedKi 35.65 + //#define DEFAULT_bedKd 610.21 + #define DEFAULT_bedKp 295.00 + #define DEFAULT_bedKi 35.65 + #define DEFAULT_bedKd 610.21 + + // FIND YOUR OWN: "M303 E-1 C8 S90" to run autotune on the bed at 90 degreesC for 8 cycles. +#endif // PIDTEMPBED + +// @section extruder + +// This option prevents extrusion if the temperature is below EXTRUDE_MINTEMP. +// It also enables the M302 command to set the minimum extrusion temperature +// or to allow moving the extruder regardless of the hotend temperature. +// *** IT IS HIGHLY RECOMMENDED TO LEAVE THIS OPTION ENABLED! *** +#define PREVENT_COLD_EXTRUSION +#define EXTRUDE_MINTEMP 170 + +// This option prevents a single extrusion longer than EXTRUDE_MAXLENGTH. +// Note that for Bowden Extruders a too-small value here may prevent loading. +#define PREVENT_LENGTHY_EXTRUDE +#define EXTRUDE_MAXLENGTH 200 + +//=========================================================================== +//======================== Thermal Runaway Protection ======================= +//=========================================================================== + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * If you get "Thermal Runaway" or "Heating failed" errors the + * details can be tuned in Configuration_adv.h + */ + +#define THERMAL_PROTECTION_HOTENDS // Enable thermal protection for all extruders +#define THERMAL_PROTECTION_BED // Enable thermal protection for the heated bed + +//=========================================================================== +//============================= Mechanical Settings ========================= +//=========================================================================== + +// @section machine + +// Uncomment one of these options to enable CoreXY, CoreXZ, or CoreYZ kinematics +// either in the usual order or reversed +//#define COREXY +//#define COREXZ +//#define COREYZ +//#define COREYX +//#define COREZX +//#define COREZY + +//=========================================================================== +//============================== Endstop Settings =========================== +//=========================================================================== + +// @section homing + +// Specify here all the endstop connectors that are connected to any endstop or probe. +// Almost all printers will be using one per axis. Probes will use one or more of the +// extra connectors. Leave undefined any used for non-endstop and non-probe purposes. +#define USE_XMIN_PLUG +#define USE_YMIN_PLUG +#define USE_ZMIN_PLUG +//#define USE_XMAX_PLUG +//#define USE_YMAX_PLUG +//#define USE_ZMAX_PLUG + +// coarse Endstop Settings +#define ENDSTOPPULLUPS // Comment this out (using // at the start of the line) to disable the endstop pullup resistors + +#if DISABLED(ENDSTOPPULLUPS) + // fine endstop settings: Individual pullups. will be ignored if ENDSTOPPULLUPS is defined + //#define ENDSTOPPULLUP_XMAX + //#define ENDSTOPPULLUP_YMAX + //#define ENDSTOPPULLUP_ZMAX + //#define ENDSTOPPULLUP_XMIN + //#define ENDSTOPPULLUP_YMIN + //#define ENDSTOPPULLUP_ZMIN + //#define ENDSTOPPULLUP_ZMIN_PROBE +#endif + +// Mechanical endstop with COM to ground and NC to Signal uses "false" here (most common setup). +#define X_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Y_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define X_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Y_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MIN_PROBE_ENDSTOP_INVERTING false // set to true to invert the logic of the probe. + +// Enable this feature if all enabled endstop pins are interrupt-capable. +// This will remove the need to poll the interrupt pins, saving many CPU cycles. +#define ENDSTOP_INTERRUPTS_FEATURE + +//============================================================================= +//============================== Movement Settings ============================ +//============================================================================= +// @section motion + +/** + * Default Settings + * + * These settings can be reset by M502 + * + * Note that if EEPROM is enabled, saved values will override these. + */ + +/** + * With this option each E stepper can have its own factors for the + * following movement settings. If fewer factors are given than the + * total number of extruders, the last value applies to the rest. + */ +//#define DISTINCT_E_FACTORS + +/** + * Default Axis Steps Per Unit (steps/mm) + * Override with M92 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +//#define DEFAULT_AXIS_STEPS_PER_UNIT { 80, 80, 4000, 500 } + +// ANET A6 Firmwae V2.0 defaults: (steps/mm) +// Xsteps/mm: +100.0, Ysteps/mm: +100.0, Zsteps/mm: +0400.0, eSteps/mm: +0095.0 +#define DEFAULT_AXIS_STEPS_PER_UNIT {100, 100, 400, 95} +//#define DEFAULT_AXIS_STEPS_PER_UNIT {80, 80, 400, 95} + +/** + * Default Max Feed Rate (mm/s) + * Override with M203 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +//#define DEFAULT_MAX_FEEDRATE { 300, 300, 5, 25 } + +// ANET A6 Firmware V2.0 defaults (Vmax): +// Vmax x: 400, Vmax y: 400, Vmax z: 4, Vmax e: 25 +#define DEFAULT_MAX_FEEDRATE {400, 400, 4, 25} +//#define DEFAULT_MAX_FEEDRATE {400, 400, 20, 50} + + +/** + * Default Max Acceleration (change/s) change = mm/s + * (Maximum start speed for accelerated moves) + * Override with M201 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +//#define DEFAULT_MAX_ACCELERATION { 3000, 3000, 100, 10000 } + +// ANET A6 Firmware V2.0 defaults (Amax): +// Amx x: 9000, Amax Y: 5000, Amax z: 50, Amax e: 10000 +#define DEFAULT_MAX_ACCELERATION { 9000, 5000, 50, 10000 } +//#define DEFAULT_MAX_ACCELERATION { 10000, 10000, 200, 10000 } + +/** + * Default Acceleration (change/s) change = mm/s + * Override with M204 + * + * M204 P Acceleration + * M204 R Retract Acceleration + * M204 T Travel Acceleration + */ +//#define DEFAULT_ACCELERATION 3000 // X, Y, Z and E acceleration for printing moves +//#define DEFAULT_RETRACT_ACCELERATION 3000 // E acceleration for retracts +//#define DEFAULT_TRAVEL_ACCELERATION 3000 // X, Y, Z acceleration for travel (non printing) moves + +// ANET A6 Firmware V2.0 defaults: +// Accel: 1000 A-retract: 1000 +#define DEFAULT_ACCELERATION 1000 // X, Y, Z and E acceleration for printing moves +#define DEFAULT_RETRACT_ACCELERATION 1000 // E acceleration for retracts +#define DEFAULT_TRAVEL_ACCELERATION 1000 // X, Y, Z acceleration for travel (non printing) moves +//#define DEFAULT_ACCELERATION 2000 // X, Y, Z and E acceleration for printing moves +//#define DEFAULT_RETRACT_ACCELERATION 2000 // E acceleration for retracts +//#define DEFAULT_TRAVEL_ACCELERATION 4000 // X, Y, Z acceleration for travel (non printing) moves + + +/** + * Default Jerk (mm/s) + * Override with M205 X Y Z E + * + * "Jerk" specifies the minimum speed change that requires acceleration. + * When changing speed and direction, if the difference is less than the + * value set here, it may happen instantaneously. + */ +//#define DEFAULT_XJERK 20.0 +//#define DEFAULT_YJERK 20.0 +//#define DEFAULT_ZJERK 0.4 +//#define DEFAULT_EJERK 5.0 + +// ANET A6 Firmware V2.0 defaults (jerk): +// Vxy-jerk: 20, Vz-jerk: +000.30, Ve-jerk: 10 +#define DEFAULT_XJERK 20.0 +#define DEFAULT_YJERK 20.0 +#define DEFAULT_ZJERK 0.3 +#define DEFAULT_EJERK 10.0 +//#define DEFAULT_XJERK 20.0 +//#define DEFAULT_YJERK 20.0 +//#define DEFAULT_ZJERK 0.3 +//#define DEFAULT_EJERK 5.0 + +//=========================================================================== +//============================= Z Probe Options ============================= +//=========================================================================== +// @section probes + +// +// See http://marlinfw.org/configuration/probes.html +// + +/** + * Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + * + * Enable this option for a probe connected to the Z Min endstop pin. + */ +#define Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + +/** + * Z_MIN_PROBE_ENDSTOP + * + * Enable this option for a probe connected to any pin except Z-Min. + * (By default Marlin assumes the Z-Max endstop pin.) + * To use a custom Z Probe pin, set Z_MIN_PROBE_PIN below. + * + * - The simplest option is to use a free endstop connector. + * - Use 5V for powered (usually inductive) sensors. + * + * - RAMPS 1.3/1.4 boards may use the 5V, GND, and Aux4->D32 pin: + * - For simple switches connect... + * - normally-closed switches to GND and D32. + * - normally-open switches to 5V and D32. + * + * WARNING: Setting the wrong pin may have unexpected and potentially + * disastrous consequences. Use with caution and do your homework. + * + */ +//#define Z_MIN_PROBE_ENDSTOP + +/** + * Probe Type + * + * Allen Key Probes, Servo Probes, Z-Sled Probes, FIX_MOUNTED_PROBE, etc. + * Activate one of these to use Auto Bed Leveling below. + */ + +/** + * The "Manual Probe" provides a means to do "Auto" Bed Leveling without a probe. + * Use G29 repeatedly, adjusting the Z height at each point with movement commands + * or (with LCD_BED_LEVELING) the LCD controller. + */ +//#define PROBE_MANUALLY + +/** + * A Fix-Mounted Probe either doesn't deploy or needs manual deployment. + * (e.g., an inductive probe or a nozzle-based probe-switch.) + */ +//#define FIX_MOUNTED_PROBE + +/** + * Z Servo Probe, such as an endstop switch on a rotating arm. + */ +//#define Z_ENDSTOP_SERVO_NR 0 // Defaults to SERVO 0 connector. +//#define Z_SERVO_ANGLES {70,0} // Z Servo Deploy and Stow angles + +/** + * The BLTouch probe uses a Hall effect sensor and emulates a servo. + */ +//#define BLTOUCH +#if ENABLED(BLTOUCH) + //#define BLTOUCH_DELAY 375 // (ms) Enable and increase if needed +#endif + +/** + * Enable one or more of the following if probing seems unreliable. + * Heaters and/or fans can be disabled during probing to minimize electrical + * noise. A delay can also be added to allow noise and vibration to settle. + * These options are most useful for the BLTouch probe, but may also improve + * readings with inductive probes and piezo sensors. + */ +#define PROBING_HEATERS_OFF // Turn heaters off when probing +#define PROBING_FANS_OFF // Turn fans off when probing +//#define DELAY_BEFORE_PROBING 200 // (ms) To prevent vibrations from triggering piezo sensors + +// A probe that is deployed and stowed with a solenoid pin (SOL1_PIN) +//#define SOLENOID_PROBE + +// A sled-mounted probe like those designed by Charles Bell. +//#define Z_PROBE_SLED +//#define SLED_DOCKING_OFFSET 5 // The extra distance the X axis must travel to pickup the sled. 0 should be fine but you can push it further if you'd like. + +// +// For Z_PROBE_ALLEN_KEY see the Delta example configurations. +// + +/** + * Z Probe to nozzle (X,Y) offset, relative to (0, 0). + * X and Y offsets must be integers. + * + * In the following example the X and Y offsets are both positive: + * #define X_PROBE_OFFSET_FROM_EXTRUDER 10 + * #define Y_PROBE_OFFSET_FROM_EXTRUDER 10 + * + * +-- BACK ---+ + * | | + * L | (+) P | R <-- probe (20,20) + * E | | I + * F | (-) N (+) | G <-- nozzle (10,10) + * T | | H + * | (-) | T + * | | + * O-- FRONT --+ + * (0,0) + */ +//#define X_PROBE_OFFSET_FROM_EXTRUDER 10 // X offset: -left +right [of the nozzle] +//#define Y_PROBE_OFFSET_FROM_EXTRUDER 10 // Y offset: -front +behind [the nozzle] +//#define Z_PROBE_OFFSET_FROM_EXTRUDER 0 // Z offset: -below +above [the nozzle] + +// ANET A8: BELOW IS FOR THE FRONT MOUNTED SENSOR WITH 3D PRINTED MOUNT +//#define X_PROBE_OFFSET_FROM_EXTRUDER -28 // X offset: -left +right [of the nozzle] +//#define Y_PROBE_OFFSET_FROM_EXTRUDER -45 // Y offset: -front +behind [the nozzle] +//#define Z_PROBE_OFFSET_FROM_EXTRUDER 0 // Z offset: -below +above [the nozzle] + +//AND THE LINES BELOW HERE ARE FOR THE OFFICIAL ANET REAR MOUNTED SENSOR +//#define X_PROBE_OFFSET_FROM_EXTRUDER -1 // X offset: -left +right [of the nozzle] +//#define Y_PROBE_OFFSET_FROM_EXTRUDER 3 // Y offset: -front +behind [the nozzle] +//#define Z_PROBE_OFFSET_FROM_EXTRUDER 0 // Z offset: -below +above [the nozzle] + +//ANET A6 with BLTouch/3D-Touch mounted right to the nozzel +#define X_PROBE_OFFSET_FROM_EXTRUDER 39 // X offset: -left +right [of the nozzle] +#define Y_PROBE_OFFSET_FROM_EXTRUDER 0 // Y offset: -front +behind [the nozzle] +#define Z_PROBE_OFFSET_FROM_EXTRUDER 0 // Z offset: -below +above [the nozzle] + +//ANET A6 with BLTouch/3D-Touch betwen Fan and Belt +// (mount: https://github.com/ralf-e/ANET_A6_modifications/tree/master/A6_X-Axis) +//#define X_PROBE_OFFSET_FROM_EXTRUDER -30 // X offset: -left +right [of the nozzle] +//#define Y_PROBE_OFFSET_FROM_EXTRUDER 15 // Y offset: -front +behind [the nozzle] +//#define Z_PROBE_OFFSET_FROM_EXTRUDER 0.75 // Z offset: -below +above [the nozzle] + +// X and Y axis travel speed (mm/m) between probes +#define XY_PROBE_SPEED 8000 +//#define XY_PROBE_SPEED 6000 + +// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +#define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z + +// Speed for the "accurate" probe of each point +#define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 3) + +// Use double touch for probing +#define PROBE_DOUBLE_TOUCH + +/** + * Z probes require clearance when deploying, stowing, and moving between + * probe points to avoid hitting the bed and other hardware. + * Servo-mounted probes require extra space for the arm to rotate. + * Inductive probes need space to keep from triggering early. + * + * Use these settings to specify the distance (mm) to raise the probe (or + * lower the bed). The values set here apply over and above any (negative) + * probe Z Offset set with Z_PROBE_OFFSET_FROM_EXTRUDER, M851, or the LCD. + * Only integer values >= 1 are valid here. + * + * Example: `M851 Z-5` with a CLEARANCE of 4 => 9mm from bed to nozzle. + * But: `M851 Z+1` with a CLEARANCE of 2 => 2mm from bed to nozzle. + */ +#define Z_CLEARANCE_DEPLOY_PROBE 10 // Z Clearance for Deploy/Stow +#define Z_CLEARANCE_BETWEEN_PROBES 5 // Z Clearance between probe points +//#define Z_CLEARANCE_DEPLOY_PROBE 5 // Z Clearance for Deploy/Stow +//#define Z_CLEARANCE_BETWEEN_PROBES 3 // Z Clearance between probe points + +// For M851 give a range for adjusting the Z probe offset +#define Z_PROBE_OFFSET_RANGE_MIN -20 +#define Z_PROBE_OFFSET_RANGE_MAX 20 + +// Enable the M48 repeatability test to test probe accuracy +//#define Z_MIN_PROBE_REPEATABILITY_TEST + +// For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1 +// :{ 0:'Low', 1:'High' } +#define X_ENABLE_ON 0 +#define Y_ENABLE_ON 0 +#define Z_ENABLE_ON 0 +#define E_ENABLE_ON 0 // For all extruders + +// Disables axis stepper immediately when it's not being used. +// 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 +//#define DISABLE_REDUCED_ACCURACY_WARNING + +// @section extruder + +#define DISABLE_E false // For all extruders +#define DISABLE_INACTIVE_EXTRUDER true // Keep only the active extruder enabled. + +// @section machine + +// Invert the stepper direction. Change (or reverse the motor connector) if an axis goes the wrong way. +#define INVERT_X_DIR false +//#define INVERT_Y_DIR true +//#define INVERT_Z_DIR false +//ANET A6: +#define INVERT_Y_DIR false +#define INVERT_Z_DIR true + +// Enable this option for Toshiba stepper drivers +//#define CONFIG_STEPPERS_TOSHIBA + +// @section extruder + +// For direct drive extruder v9 set to true, for geared extruder set to false. +#define INVERT_E0_DIR false +#define INVERT_E1_DIR false +#define INVERT_E2_DIR false +#define INVERT_E3_DIR false +#define INVERT_E4_DIR false + +// @section homing + +//#define NO_MOTION_BEFORE_HOMING // Inhibit movement until all axes have been homed + +//#define Z_HOMING_HEIGHT 4 // (in mm) Minimal z height before homing (G28) for Z clearance above the bed, clamps, ... + // Be sure you have this distance over your Z_MAX_POS in case. + +// Direction of endstops when homing; 1=MAX, -1=MIN +// :[-1,1] +#define X_HOME_DIR -1 +#define Y_HOME_DIR -1 +#define Z_HOME_DIR -1 + +// @section machine + +// The size of the print bed +//#define X_BED_SIZE 200 +//#define Y_BED_SIZE 200 + +// Travel limits (mm) after homing, corresponding to endstop positions. +//#define X_MIN_POS 0 +//#define Y_MIN_POS 0 +//#define X_MAX_POS X_BED_SIZE +//#define Y_MAX_POS Y_BED_SIZE +//#define Z_MIN_POS 0 +//#define Z_MAX_POS 200 + +// ANET A6 Firmware V2.0 defaults: +//#define X_BED_SIZE 220 +//#define Y_BED_SIZE 220 +//#define X_MIN_POS 0 +//#define Y_MIN_POS 0 +//#define Z_MIN_POS 0 +//#define Z_MAX_POS 250 + +// ANET A6, X0/Y0 0 front left bed edge : +#define X_BED_SIZE 222 +#define Y_BED_SIZE 222 +#define X_MIN_POS -3 +#define Y_MIN_POS -5 +#define Z_MIN_POS 0 +#define Z_MAX_POS 230 + +// ANET A6 with new X-Axis / modded Y-Axis: +//#define X_BED_SIZE 235 +//#define Y_BED_SIZE 230 +//#define X_MIN_POS 0 +//#define Y_MIN_POS 0 +//#define Z_MIN_POS 0 +//#define Z_MAX_POS 230 + +// ANET A6 with new X-Axis / modded Y-Axis, X0/Y0 0 front left bed edge : +//#define X_BED_SIZE 227 +//#define Y_BED_SIZE 224 +//#define X_MIN_POS -8 +//#define Y_MIN_POS -6 +//#define Z_MIN_POS 0 +//#define Z_MAX_POS 230 + +#define X_MAX_POS X_BED_SIZE +#define Y_MAX_POS Y_BED_SIZE + +// If enabled, axes won't move below MIN_POS in response to movement commands. +#define MIN_SOFTWARE_ENDSTOPS +// If enabled, axes won't move above MAX_POS in response to movement commands. +#define MAX_SOFTWARE_ENDSTOPS + +/** + * Filament Runout Sensor + * A mechanical or opto endstop is used to check for the presence of filament. + * + * RAMPS-based boards use SERVO3_PIN. + * For other boards you may need to define FIL_RUNOUT_PIN. + * By default the firmware assumes HIGH = has filament, LOW = ran out + */ +//#define FILAMENT_RUNOUT_SENSOR +#if ENABLED(FILAMENT_RUNOUT_SENSOR) + #define FIL_RUNOUT_INVERTING false // set to true to invert the logic of the sensor. + #define ENDSTOPPULLUP_FIL_RUNOUT // Uncomment to use internal pullup for filament runout pins if the sensor is defined. + #define FILAMENT_RUNOUT_SCRIPT "M600" +#endif + +//=========================================================================== +//=============================== Bed Leveling ============================== +//=========================================================================== +// @section bedlevel + +/** + * Choose one of the options below to enable G29 Bed Leveling. The parameters + * and behavior of G29 will change depending on your selection. + * + * If using a Probe for Z Homing, enable Z_SAFE_HOMING also! + * + * - AUTO_BED_LEVELING_3POINT + * Probe 3 arbitrary points on the bed (that aren't collinear) + * You specify the XY coordinates of all 3 points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_LINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_BILINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a mesh, best for large or uneven beds. + * + * - AUTO_BED_LEVELING_UBL (Unified Bed Leveling) + * A comprehensive bed leveling system combining the features and benefits + * of other systems. UBL also includes integrated Mesh Generation, Mesh + * Validation and Mesh Editing systems. Currently, UBL is only checked out + * for Cartesian Printers. That said, it was primarily designed to correct + * poor quality Delta Printers. If you feel adventurous and have a Delta, + * please post an issue if something doesn't work correctly. Initially, + * you will need to set a reduced bed size so you have a rectangular area + * to test on. + * + * - MESH_BED_LEVELING + * Probe a grid manually + * The result is a mesh, suitable for large or uneven beds. (See BILINEAR.) + * For machines without a probe, Mesh Bed Leveling provides a method to perform + * leveling in steps so you can manually adjust the Z height at each grid-point. + * With an LCD controller the process is guided step-by-step. + */ +//#define AUTO_BED_LEVELING_3POINT +//#define AUTO_BED_LEVELING_LINEAR +//#define AUTO_BED_LEVELING_BILINEAR +//#define AUTO_BED_LEVELING_UBL +//#define MESH_BED_LEVELING + +/** + * Enable detailed logging of G28, G29, M48, etc. + * Turn on with the command 'M111 S32'. + * NOTE: Requires a lot of PROGMEM! + */ +//#define DEBUG_LEVELING_FEATURE + +#if ENABLED(MESH_BED_LEVELING) || ENABLED(AUTO_BED_LEVELING_BILINEAR) || ENABLED(AUTO_BED_LEVELING_UBL) + // Gradually reduce leveling correction until a set height is reached, + // at which point movement will be level to the machine's XY plane. + // The height can be set with M420 Z + #define ENABLE_LEVELING_FADE_HEIGHT +#endif + +#if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Set the number of grid points per dimension. + #define GRID_MAX_POINTS_X 4 + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + // Set the boundaries for probing (where the probe can reach). + //#define LEFT_PROBE_BED_POSITION 15 + //#define RIGHT_PROBE_BED_POSITION 170 + //#define FRONT_PROBE_BED_POSITION 20 + //#define BACK_PROBE_BED_POSITION 170 + + // ANET A6 + //#define LEFT_PROBE_BED_POSITION 20 + //#define RIGHT_PROBE_BED_POSITION 190 + //#define FRONT_PROBE_BED_POSITION 20 + //#define BACK_PROBE_BED_POSITION 190 + + // ANET A6 BLTOUCH right (39mm) to the nozzle + #define LEFT_PROBE_BED_POSITION 36 + #define RIGHT_PROBE_BED_POSITION 190 + #define FRONT_PROBE_BED_POSITION 20 + #define BACK_PROBE_BED_POSITION 190 + + // ANET A6 with new X-Axis and modded Y-Axis + //#define LEFT_PROBE_BED_POSITION 20 + //#define RIGHT_PROBE_BED_POSITION 205 + //#define FRONT_PROBE_BED_POSITION 20 + //#define BACK_PROBE_BED_POSITION 205 + + // ANET A6 with new X-Axis and modded Y-Axis, X0/Y0 front left bed edge + //#define LEFT_PROBE_BED_POSITION 20 + //#define RIGHT_PROBE_BED_POSITION 194 + //#define FRONT_PROBE_BED_POSITION 20 + //#define BACK_PROBE_BED_POSITION 194 + + // The Z probe minimum outer margin (to validate G29 parameters). + #define MIN_PROBE_EDGE 10 + + // Probe along the Y axis, advancing X after each column + //#define PROBE_Y_FIRST + + #if ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Beyond the probed grid, continue the implied tilt? + // Default is to maintain the height of the nearest edge. + //#define EXTRAPOLATE_BEYOND_GRID + + // + // Experimental Subdivision of the grid by Catmull-Rom method. + // Synthesizes intermediate points to produce a more detailed mesh. + // + //#define ABL_BILINEAR_SUBDIVISION + #if ENABLED(ABL_BILINEAR_SUBDIVISION) + // Number of subdivisions between probe points + #define BILINEAR_SUBDIVISIONS 3 + #endif + + #endif + +#elif ENABLED(AUTO_BED_LEVELING_3POINT) + + // 3 arbitrary points to probe. + // A simple cross-product is used to estimate the plane of the bed. + #define ABL_PROBE_PT_1_X 15 + #define ABL_PROBE_PT_1_Y 180 + #define ABL_PROBE_PT_2_X 15 + #define ABL_PROBE_PT_2_Y 20 + #define ABL_PROBE_PT_3_X 170 + #define ABL_PROBE_PT_3_Y 20 + +#elif ENABLED(AUTO_BED_LEVELING_UBL) + + //=========================================================================== + //========================= Unified Bed Leveling ============================ + //=========================================================================== + + #define UBL_MESH_INSET 1 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 10 // Don't use more than 15 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + #define UBL_PROBE_PT_1_X 39 // Probing points for 3-Point leveling of the mesh + #define UBL_PROBE_PT_1_Y 180 + #define UBL_PROBE_PT_2_X 39 + #define UBL_PROBE_PT_2_Y 20 + #define UBL_PROBE_PT_3_X 180 + #define UBL_PROBE_PT_3_Y 20 + + #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation + #define UBL_MESH_EDIT_MOVES_Z // Sophisticated users prefer no movement of nozzle + +#elif ENABLED(MESH_BED_LEVELING) + + //=========================================================================== + //=================================== Mesh ================================== + //=========================================================================== + + #define MESH_INSET 10 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 5 // Don't use more than 7 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + //#define MESH_G28_REST_ORIGIN // After homing all axes ('G28' or 'G28 XYZ') rest Z at Z_MIN_POS + +#endif // BED_LEVELING + +/** + * Use the LCD controller for bed leveling + * Requires MESH_BED_LEVELING or PROBE_MANUALLY + */ +//#define LCD_BED_LEVELING + +#if ENABLED(LCD_BED_LEVELING) + #define MBL_Z_STEP 0.025 // Step size while manually probing Z axis. + #define LCD_PROBE_Z_RANGE 4 // Z Range centered on Z_MIN_POS for LCD Z adjustment +#endif + +// Add a menu item to move between bed corners for manual bed adjustment +//#define LEVEL_BED_CORNERS + +/** + * Commands to execute at the end of G29 probing. + * Useful to retract or move the Z probe out of the way. + */ +//#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) +//#define BED_CENTER_AT_0_0 + +// Manually set the home position. Leave these undefined for automatic settings. +// For DELTA this is the top-center of the Cartesian print volume. +//#define MANUAL_X_HOME_POS 0 +//#define MANUAL_Y_HOME_POS 0 +//#define MANUAL_Z_HOME_POS 0 + +// ANET A6 with new X-Axis / modded Y-Axis: +//#define MANUAL_X_HOME_POS X_MIN_POS - 8 +//#define MANUAL_Y_HOME_POS Y_MIN_POS - 6 +//#define MANUAL_Z_HOME_POS Z_MIN_POS + +// Use "Z Safe Homing" to avoid homing with a Z probe outside the bed area. +// +// With this feature enabled: +// +// - 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). +// - 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 axis (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). + + //Anet A6 with new X-Axis + //#define Z_SAFE_HOMING_X_POINT 113 // X point for Z homing when homing all axis (G28). + //#define Z_SAFE_HOMING_Y_POINT 112 // Y point for Z homing when homing all axis (G28). + + //Anet A6 with new X-Axis and defined X_HOME_POS -7, Y_HOME_POS -6 + //#define Z_SAFE_HOMING_X_POINT 107 // X point for Z homing when homing all axis (G28). + //#define Z_SAFE_HOMING_Y_POINT 107 // Y point for Z homing when homing all axis (G28). + +#endif + +// Homing speeds (mm/m) +#define HOMING_FEEDRATE_XY (50*60) +#define HOMING_FEEDRATE_Z (4*60) + +//============================================================================= +//============================= Additional Features =========================== +//============================================================================= + +// @section extras + +// +// EEPROM +// +// The microcontroller can store settings in the EEPROM, e.g. max velocity... +// M500 - stores parameters in EEPROM +// M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily). +// M502 - reverts to the default "factory settings". You still need to store them in EEPROM afterwards if you want to. +// +#define EEPROM_SETTINGS // Enable for M500 and M501 commands +//#define DISABLE_M503 // Saves ~2700 bytes of PROGMEM. Disable for release! +#define EEPROM_CHITCHAT // Give feedback on EEPROM commands. Disable to save PROGMEM. + +// +// Host Keepalive +// +// When enabled Marlin will send a busy status message to the host +// every couple of seconds when it can't accept commands. +// +#define HOST_KEEPALIVE_FEATURE // Disable this if your host doesn't like keepalive messages +#define DEFAULT_KEEPALIVE_INTERVAL 2 // Number of seconds between "busy" messages. Set with M113. +#define BUSY_WHILE_HEATING // Some hosts require "busy" messages even during heating + +// +// M100 Free Memory Watcher +// +//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose + +// +// G20/G21 Inch mode support +// +//#define INCH_MODE_SUPPORT + +// +// M149 Set temperature units support +// +//#define TEMPERATURE_UNITS_SUPPORT + +// @section temperature + +// Preheat Constants +#define PREHEAT_1_TEMP_HOTEND 200 +#define PREHEAT_1_TEMP_BED 50 +#define PREHEAT_1_FAN_SPEED 0 // ANET A6 Default is 255 + +#define PREHEAT_2_TEMP_HOTEND 230 +#define PREHEAT_2_TEMP_BED 70 +#define PREHEAT_2_FAN_SPEED 0 // ANET A6 Default is 255 + +/** + * Nozzle Park -- EXPERIMENTAL + * + * Park the nozzle at the given XYZ position on idle or G27. + * + * The "P" parameter controls the action applied to the Z axis: + * + * P0 (Default) If Z is below park Z raise the nozzle. + * P1 Raise the nozzle always to Z-park height. + * P2 Raise the nozzle by Z-park amount, limited to Z_MAX_POS. + */ +//#define NOZZLE_PARK_FEATURE + +#if ENABLED(NOZZLE_PARK_FEATURE) + // Specify a park position as { X, Y, Z } + #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 } +#endif + +/** + * Clean Nozzle Feature -- EXPERIMENTAL + * + * Adds the G12 command to perform a nozzle cleaning process. + * + * Parameters: + * P Pattern + * S Strokes / Repetitions + * T Triangles (P1 only) + * + * Patterns: + * P0 Straight line (default). This process requires a sponge type material + * at a fixed bed location. "S" specifies strokes (i.e. back-forth motions) + * between the start / end points. + * + * P1 Zig-zag pattern between (X0, Y0) and (X1, Y1), "T" specifies the + * number of zig-zag triangles to do. "S" defines the number of strokes. + * Zig-zags are done in whichever is the narrower dimension. + * For example, "G12 P1 S1 T3" will execute: + * + * -- + * | (X0, Y1) | /\ /\ /\ | (X1, Y1) + * | | / \ / \ / \ | + * A | | / \ / \ / \ | + * | | / \ / \ / \ | + * | (X0, Y0) | / \/ \/ \ | (X1, Y0) + * -- +--------------------------------+ + * |________|_________|_________| + * T1 T2 T3 + * + * P2 Circular pattern with middle at NOZZLE_CLEAN_CIRCLE_MIDDLE. + * "R" specifies the radius. "S" specifies the stroke count. + * Before starting, the nozzle moves to NOZZLE_CLEAN_START_POINT. + * + * Caveats: The ending Z should be the same as starting Z. + * Attention: EXPERIMENTAL. G-code arguments may change. + * + */ +//#define NOZZLE_CLEAN_FEATURE + +#if ENABLED(NOZZLE_CLEAN_FEATURE) + // Default number of pattern repetitions + #define NOZZLE_CLEAN_STROKES 12 + + // Default number of triangles + #define NOZZLE_CLEAN_TRIANGLES 3 + + // Specify positions as { X, Y, Z } + #define NOZZLE_CLEAN_START_POINT { 30, 30, (Z_MIN_POS + 1)} + #define NOZZLE_CLEAN_END_POINT {100, 60, (Z_MIN_POS + 1)} + + // Circular pattern radius + #define NOZZLE_CLEAN_CIRCLE_RADIUS 6.5 + // Circular pattern circle fragments number + #define NOZZLE_CLEAN_CIRCLE_FN 10 + // Middle point of circle + #define NOZZLE_CLEAN_CIRCLE_MIDDLE NOZZLE_CLEAN_START_POINT + + // Moves the nozzle to the initial position + #define NOZZLE_CLEAN_GOBACK +#endif + +/** + * Print Job Timer + * + * Automatically start and stop the print job timer on M104/M109/M190. + * + * M104 (hotend, no wait) - high temp = none, low temp = stop timer + * M109 (hotend, wait) - high temp = start timer, low temp = stop timer + * M190 (bed, wait) - high temp = start timer, low temp = none + * + * The timer can also be controlled with the following commands: + * + * M75 - Start the print job timer + * M76 - Pause the print job timer + * M77 - Stop the print job timer + */ +#define PRINTJOB_TIMER_AUTOSTART + +/** + * Print Counter + * + * Track statistical data such as: + * + * - Total print jobs + * - Total successful print jobs + * - Total failed print jobs + * - Total time printing + * + * View the current statistics with M78. + */ +//#define PRINTCOUNTER + +//============================================================================= +//============================= LCD and SD support ============================ +//============================================================================= + +// @section lcd + +/** + * LCD LANGUAGE + * + * Select the language to display on the LCD. These languages are available: + * + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, + * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * tr, uk, zh_CN, zh_TW, test + * + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + */ +#define LCD_LANGUAGE en + +/** + * LCD Character Set + * + * Note: This option is NOT applicable to Graphical Displays. + * + * All character-based LCDs provide ASCII plus one of these + * language extensions: + * + * - JAPANESE ... the most common + * - WESTERN ... with more accented characters + * - CYRILLIC ... for the Russian language + * + * To determine the language extension installed on your controller: + * + * - Compile and upload with LCD_LANGUAGE set to 'test' + * - 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 + * + * :['JAPANESE', 'WESTERN', 'CYRILLIC'] + */ +#define DISPLAY_CHARSET_HD44780 JAPANESE + +/** + * LCD TYPE + * + * Enable ULTRA_LCD for a 16x2, 16x4, 20x2, or 20x4 character-based LCD. + * Enable DOGLCD for a 128x64 (ST7565R) Full Graphical Display. + * (These options will be enabled automatically for most displays.) + * + * IMPORTANT: The U8glib library is required for Full Graphic Display! + * https://github.com/olikraus/U8glib_Arduino + */ +//#define ULTRA_LCD // Character based +//#define DOGLCD // Full graphics display + +/** + * SD CARD + * + * 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 + +/** + * SD CARD: SPI SPEED + * + * Enable one of the following items for a slower SPI transfer speed. + * This may be required to resolve "volume init" errors. + */ +//#define SPI_SPEED SPI_HALF_SPEED +//#define SPI_SPEED SPI_QUARTER_SPEED +//#define SPI_SPEED SPI_EIGHTH_SPEED + +/** + * SD CARD: ENABLE CRC + * + * Use CRC checks and retries on the SD communication. + */ +//#define SD_CHECK_AND_RETRY + +// +// ENCODER SETTINGS +// +// This option overrides the default number of encoder pulses needed to +// produce one step. Should be increased for high-resolution encoders. +// +//#define ENCODER_PULSES_PER_STEP 1 + +// +// Use this option to override the number of step signals required to +// move between next/prev menu items. +// +//#define ENCODER_STEPS_PER_MENU_ITEM 5 + +/** + * Encoder Direction Options + * + * Test your encoder's behavior first with both options disabled. + * + * Reversed Value Edit and Menu Nav? Enable REVERSE_ENCODER_DIRECTION. + * Reversed Menu Navigation only? Enable REVERSE_MENU_DIRECTION. + * Reversed Value Editing only? Enable BOTH options. + */ + +// +// This option reverses the encoder direction everywhere. +// +// Set this option if CLOCKWISE causes values to DECREASE +// +//#define REVERSE_ENCODER_DIRECTION + +// +// This option reverses the encoder direction for navigating LCD menus. +// +// If CLOCKWISE normally moves DOWN this makes it go UP. +// If CLOCKWISE normally moves UP this makes it go DOWN. +// +//#define REVERSE_MENU_DIRECTION + +// +// Individual Axis Homing +// +// Add individual axis homing items (Home X, Home Y, and Home Z) to the LCD menu. +// +//#define INDIVIDUAL_AXIS_HOMING_MENU + +// +// SPEAKER/BUZZER +// +// If you have a speaker that can produce tones, enable it here. +// By default Marlin assumes you have a buzzer with a fixed frequency. +// +//#define SPEAKER + +// +// The duration and frequency for the UI feedback sound. +// Set these to 0 to disable audio feedback in the LCD menus. +// +// Note: Test audio output with the G-Code: +// M300 S P +// +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 +//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 + +// +// CONTROLLER TYPE: Standard +// +// Marlin supports a wide variety of controllers. +// Enable one of the following options to specify your controller. +// + +// +// ULTIMAKER Controller. +// +//#define ULTIMAKERCONTROLLER + +// +// ULTIPANEL as seen on Thingiverse. +// +//#define ULTIPANEL + +// +// PanelOne from T3P3 (via RAMPS 1.4 AUX2/AUX3) +// http://reprap.org/wiki/PanelOne +// +//#define PANEL_ONE + +// +// MaKr3d Makr-Panel with graphic controller and SD support. +// http://reprap.org/wiki/MaKr3d_MaKrPanel +// +//#define MAKRPANEL + +// +// ReprapWorld Graphical LCD +// https://reprapworld.com/?products_details&products_id/1218 +// +//#define REPRAPWORLD_GRAPHICAL_LCD + +// +// Activate one of these if you have a Panucatt Devices +// Viki 2.0 or mini Viki with Graphic LCD +// http://panucatt.com +// +//#define VIKI2 +//#define miniVIKI + +// +// Adafruit ST7565 Full Graphic Controller. +// https://github.com/eboston/Adafruit-ST7565-Full-Graphic-Controller/ +// +//#define ELB_FULL_GRAPHIC_CONTROLLER + +// +// RepRapDiscount Smart Controller. +// http://reprap.org/wiki/RepRapDiscount_Smart_Controller +// +// Note: Usually sold with a white PCB. +// +//#define REPRAP_DISCOUNT_SMART_CONTROLLER + +// +// GADGETS3D G3D LCD/SD Controller +// http://reprap.org/wiki/RAMPS_1.3/1.4_GADGETS3D_Shield_with_Panel +// +// Note: Usually sold with a blue PCB. +// +//#define G3D_PANEL + +// +// RepRapDiscount FULL GRAPHIC Smart Controller +// http://reprap.org/wiki/RepRapDiscount_Full_Graphic_Smart_Controller +// +// Note: Details on connecting to the Anet V1.0 controller are in the file pins_ANET_10.h +// +//#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER + +// +// MakerLab Mini Panel with graphic +// controller and SD support - http://reprap.org/wiki/Mini_panel +// +//#define MINIPANEL + +// +// RepRapWorld REPRAPWORLD_KEYPAD v1.1 +// http://reprapworld.com/?products_details&products_id=202&cPath=1591_1626 +// +// REPRAPWORLD_KEYPAD_MOVE_STEP sets how much should the robot move when a key +// is pressed, a value of 10.0 means 10mm per click. +// +//#define REPRAPWORLD_KEYPAD +//#define REPRAPWORLD_KEYPAD_MOVE_STEP 1.0 + +// +// RigidBot Panel V1.0 +// http://www.inventapart.com/ +// +//#define RIGIDBOT_PANEL + +// +// BQ LCD Smart Controller shipped by +// default with the BQ Hephestos 2 and Witbox 2. +// +//#define BQ_LCD_SMART_CONTROLLER + +// +// Cartesio UI +// http://mauk.cc/webshop/cartesio-shop/electronics/user-interface +// +//#define CARTESIO_UI + +// +// ANET_10 Controller supported displays. +// +//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. + // This LCD is known to be susceptible to electrical interference + // which scrambles the display. Pressing any button clears it up. +#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 + // A clone of the RepRapDiscount full graphics display but with + // different pins/wiring (see pins_ANET_10.h). + +// +// LCD for Melzi Card with Graphical LCD +// +//#define LCD_FOR_MELZI + +// +// CONTROLLER TYPE: I2C +// +// Note: These controllers require the installation of Arduino's LiquidCrystal_I2C +// library. For more info: https://github.com/kiyoshigawa/LiquidCrystal_I2C +// + +// +// Elefu RA Board Control Panel +// http://www.elefu.com/index.php?route=product/product&product_id=53 +// +//#define RA_CONTROL_PANEL + +// +// Sainsmart YW Robot (LCM1602) LCD Display +// +// Note: This controller requires F.Malpartida's LiquidCrystal_I2C library +// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home +// +//#define LCD_I2C_SAINSMART_YWROBOT + +// +// Generic LCM1602 LCD adapter +// +//#define LCM1602 + +// +// PANELOLU2 LCD with status LEDs, +// separate encoder and click inputs. +// +// Note: This controller requires Arduino's LiquidTWI2 library v1.2.3 or later. +// For more info: https://github.com/lincomatic/LiquidTWI2 +// +// Note: The PANELOLU2 encoder click input can either be directly connected to +// a pin (if BTN_ENC defined to != -1) or read through I2C (when BTN_ENC == -1). +// +//#define LCD_I2C_PANELOLU2 + +// +// Panucatt VIKI LCD with status LEDs, +// integrated click & L/R/U/D buttons, separate encoder inputs. +// +//#define LCD_I2C_VIKI + +// +// SSD1306 OLED full graphics generic display +// +//#define U8GLIB_SSD1306 + +// +// SAV OLEd LCD module support using either SSD1306 or SH1106 based LCD modules +// +//#define SAV_3DGLCD +#if ENABLED(SAV_3DGLCD) + //#define U8GLIB_SSD1306 + #define U8GLIB_SH1106 +#endif + +// +// CONTROLLER TYPE: Shift register panels +// +// 2 wire Non-latching LCD SR from https://goo.gl/aJJ4sH +// LCD configuration: http://reprap.org/wiki/SAV_3D_LCD +// +//#define SAV_3DLCD + +// +// TinyBoy2 128x64 OLED / Encoder Panel +// +//#define OLED_PANEL_TINYBOY2 + +// +// Makeboard 3D Printer Parts 3D Printer Mini Display 1602 Mini Controller +// https://www.aliexpress.com/item/Micromake-Makeboard-3D-Printer-Parts-3D-Printer-Mini-Display-1602-Mini-Controller-Compatible-with-Ramps-1/32765887917.html +// +//#define MAKEBOARD_MINI_2_LINE_DISPLAY_1602 + +// +// MKS MINI12864 with graphic controller and SD support +// http://reprap.org/wiki/MKS_MINI_12864 +// +//#define MKS_MINI_12864 + +// +// Factory display for Creality CR-10 +// https://www.aliexpress.com/item/Universal-LCD-12864-3D-Printer-Display-Screen-With-Encoder-For-CR-10-CR-7-Model/32833148327.html +// +// This is RAMPS-compatible using a single 10-pin connector. +// (For CR-10 owners who want to replace the Melzi Creality board but retain the display) +// +//#define CR10_STOCKDISPLAY + +// +// MKS OLED 1.3" 128 × 64 FULL GRAPHICS CONTROLLER +// http://reprap.org/wiki/MKS_12864OLED +// +// Tiny, but very sharp OLED display +// +//#define MKS_12864OLED + +//============================================================================= +//=============================== Extra Features ============================== +//============================================================================= + +// @section extras + +// Increase the FAN PWM frequency. Removes the PWM noise but increases heating in the FET/Arduino +//#define FAST_PWM_FAN + +// Use software PWM to drive the fan, as for the heaters. This uses a very low frequency +// which is not as annoying as with the hardware PWM. On the other hand, if this frequency +// is too low, you should also increment SOFT_PWM_SCALE. +//#define FAN_SOFT_PWM + +// Incrementing this by 1 will double the software PWM frequency, +// affecting heaters, and the fan if FAN_SOFT_PWM is enabled. +// However, control resolution will be halved for each increment; +// at zero value, there are 128 effective control positions. +#define SOFT_PWM_SCALE 0 + +// If SOFT_PWM_SCALE is set to a value higher than 0, dithering can +// be used to mitigate the associated resolution loss. If enabled, +// some of the PWM cycles are stretched so on average the desired +// duty cycle is attained. +//#define SOFT_PWM_DITHER + +// Temperature status LEDs that display the hotend and bed temperature. +// If all hotends, bed temperature, and target temperature are under 54C +// then the BLUE led is on. Otherwise the RED led is on. (1C hysteresis) +//#define TEMP_STAT_LEDS + +// M240 Triggers a camera by emulating a Canon RC-1 Remote +// Data from: http://www.doc-diy.net/photo/rc-1_hacked/ +//#define PHOTOGRAPH_PIN 23 + +// 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 + +// Support for BlinkM/CyzRgb +//#define BLINKM + +// Support for PCA9632 PWM LED driver +//#define PCA9632 + +/** + * RGB LED / LED Strip Control + * + * Enable support for an RGB LED connected to 5V digital pins, or + * an RGB Strip connected to MOSFETs controlled by digital pins. + * + * 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 overall brightness parameters is also available + * + * *** CAUTION *** + * LED Strips require a MOFSET 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! + * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino + * cannot handle such current, separate 5V power supply must be used + * *** CAUTION *** + * + * LED type. This options are mutualy exclusive. Uncomment only one. + * + */ +//#define RGB_LED +//#define RGBW_LED + +#if ENABLED(RGB_LED) || ENABLED(RGBW_LED) + #define RGB_LED_R_PIN 34 + #define RGB_LED_G_PIN 43 + #define RGB_LED_B_PIN 35 + #define RGB_LED_W_PIN -1 +#endif + +// 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 (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) + #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip + #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time + #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + //#define NEOPIXEL_STARTUP_TEST // Cycle through colors at startup +#endif + +/** + * Printer Event LEDs + * + * During printing, the LEDs will reflect the printer status: + * + * - Gradually change from blue to violet as the heated bed gets to target temp + * - Gradually change from violet to red as the hotend gets to temperature + * - Change to white to illuminate work surface + * - Change to green once print has finished + * - Turn off after the print has finished and the user has pushed a button + */ +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) + #define PRINTER_EVENT_LEDS +#endif + +/*********************************************************************\ +* R/C SERVO support +* Sponsored by TrinityLabs, Reworked by codexmas +**********************************************************************/ + +// Number of servos +// +// If you select a configuration below, this will receive a default value and does not need to be set manually +// set it manually if you have more servos than extruders and wish to manually control some +// leaving it undefined or defining as 0 will disable the servo subsystem +// If unsure, leave commented / disabled +// +//#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command + +// Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. +// 300ms is a good value but you can try less delay. +// If the servo can't reach the requested position, increase it. +#define SERVO_DELAY { 300 } + +// Servo deactivation +// +// With this option servos are powered only during movement, then turned off to prevent jitter. +//#define DEACTIVATE_SERVOS_AFTER_MOVE + +/** + * Filament Width Sensor + * + * Measures the filament width in real-time and adjusts + * flow rate to compensate for any irregularities. + * + * Also allows the measured filament diameter to set the + * extrusion rate, so the slicer only has to specify the + * volume. + * + * Only a single extruder is supported at this time. + * + * 34 RAMPS_14 : Analog input 5 on the AUX2 connector + * 81 PRINTRBOARD : Analog input 2 on the Exp1 connector (version B,C,D,E) + * 301 RAMBO : Analog input 3 + * + * Note: May require analog pins to be defined for other boards. + */ +//#define FILAMENT_WIDTH_SENSOR + +#define DEFAULT_NOMINAL_FILAMENT_DIA 3.00 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. + +#if ENABLED(FILAMENT_WIDTH_SENSOR) + #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) + #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber + + #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading + #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading + #define MAX_MEASUREMENT_DELAY 20 // (bytes) Buffer size for stored measurements (1 byte per cm). Must be larger than MEASUREMENT_DELAY_CM. + + #define DEFAULT_MEASURED_FILAMENT_DIA DEFAULT_NOMINAL_FILAMENT_DIA // Set measured to nominal initially + + // Display filament width on the LCD status line. Status messages will expire after 5 seconds. + //#define FILAMENT_LCD_DISPLAY +#endif + +#endif // CONFIGURATION_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/Anet/A6/Configuration_adv.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/Anet/A6/Configuration_adv.h new file mode 100644 index 00000000..b4e0f6a7 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/Anet/A6/Configuration_adv.h @@ -0,0 +1,1424 @@ +/** + * 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 . + * + */ + +/** + * Configuration_adv.h + * + * Advanced settings. + * Only change these if you know exactly what you're doing. + * Some of these settings can damage your printer if improperly set! + * + * Basic settings can be found in Configuration.h + * + */ +#ifndef CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H_VERSION 010100 + +// @section temperature + +//=========================================================================== +//=============================Thermal Settings ============================ +//=========================================================================== + +#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 + #endif +#endif + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * The solution: Once the temperature reaches the target, start observing. + * If the temperature stays too far below the target (hysteresis) for too long (period), + * the firmware will halt the machine as a safety precaution. + * + * If you get false positives for "Thermal Runaway" increase THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD + */ +#if ENABLED(THERMAL_PROTECTION_HOTENDS) + #define THERMAL_PROTECTION_PERIOD 60 // Seconds + #define THERMAL_PROTECTION_HYSTERESIS 10 // Degrees Celsius + + /** + * Whenever an M104 or M109 increases the target temperature the firmware will wait for the + * WATCH_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get false positives for "Heating failed" increase WATCH_TEMP_PERIOD and/or decrease WATCH_TEMP_INCREASE + * WATCH_TEMP_INCREASE should not be below 2. + */ + #define WATCH_TEMP_PERIOD 60 // Seconds + #define WATCH_TEMP_INCREASE 5 // Degrees Celsius +#endif + +/** + * Thermal Protection parameters for the bed are just as above for hotends. + */ +#if ENABLED(THERMAL_PROTECTION_BED) + #define THERMAL_PROTECTION_BED_PERIOD 60 // Seconds + #define THERMAL_PROTECTION_BED_HYSTERESIS 5 // Degrees Celsius + + /** + * Whenever an M140 or M190 increases the target temperature the firmware will wait for the + * WATCH_BED_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_BED_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get too many "Heating failed" errors, increase WATCH_BED_TEMP_PERIOD and/or decrease + * WATCH_BED_TEMP_INCREASE. (WATCH_BED_TEMP_INCREASE should not be below 2.) + */ + #define WATCH_BED_TEMP_PERIOD 180 // Seconds + #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius +#endif + +#if ENABLED(PIDTEMP) + // this adds an experimental additional term to the heating power, proportional to the extrusion speed. + // if Kc is chosen well, the additional required power due to increased melting should be compensated. + //#define PID_EXTRUSION_SCALING + #if ENABLED(PID_EXTRUSION_SCALING) + #define DEFAULT_Kc (100) //heating power=Kc*(e_speed) + #define LPQ_MAX_LEN 50 + #endif +#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 + */ +//#define AUTOTEMP +#if ENABLED(AUTOTEMP) + #define AUTOTEMP_OLDWEIGHT 0.98 +#endif + +// Show Temperature ADC value +// Enable for M105 to include ADC values read from temperature sensors. +//#define SHOW_TEMP_ADC_VALUES + +/** + * High Temperature Thermistor Support + * + * Thermistors able to support high temperature tend to have a hard time getting + * good readings at room and lower temperatures. This means HEATER_X_RAW_LO_TEMP + * will probably be caught when the heating element first turns on during the + * preheating process, which will trigger a min_temp_error as a safety measure + * and force stop everything. + * To circumvent this limitation, we allow for a preheat time (during which, + * min_temp_error won't be triggered) and add a min_temp buffer to handle + * aberrant readings. + * + * If you want to enable this feature for your hotend thermistor(s) + * uncomment and set values > 0 in the constants below + */ + +// The number of consecutive low temperature errors that can occur +// before a min_temp_error is triggered. (Shouldn't be more than 10.) +//#define MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED 0 + +// The number of milliseconds a hotend will preheat before starting to check +// the temperature. This value should NOT be set to the time it takes the +// hot end to reach the target temperature, but the time it takes to reach +// the minimum temperature your thermistor can read. The lower the better/safer. +// This shouldn't need to be more than 30 seconds (30000) +//#define MILLISECONDS_PREHEAT_TIME 0 + +// @section extruder + +// Extruder runout prevention. +// If the machine is idle and the temperature over MINTEMP +// then extrude some filament every couple of SECONDS. +//#define EXTRUDER_RUNOUT_PREVENT +#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_EXTRUDE 5 // mm +#endif + +// @section temperature + +//These defines help to calibrate the AD595 sensor in case you get wrong temperature measurements. +//The measured temperature is defined as "actualTemp = (measuredTemp * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET" +#define TEMP_SENSOR_AD595_OFFSET 0.0 +#define TEMP_SENSOR_AD595_GAIN 1.0 + +/** + * 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. + */ +//#define USE_CONTROLLER_FAN +#if ENABLED(USE_CONTROLLER_FAN) + //#define CONTROLLER_FAN_PIN FAN1_PIN // 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 +#endif + +// When first starting the main fan, run it at full speed for the +// given number of milliseconds. This gets the fan spinning reliably +// before setting a PWM value. (Does not work with software PWM for fan on Sanguinololu) +//#define FAN_KICKSTART_TIME 100 + +// This defines the minimal speed for the main fan, run in PWM mode +// to enable uncomment and set minimal PWM speed for reliable running (1-255) +// if fan speed is [1 - (FAN_MIN_PWM-1)] it is set to FAN_MIN_PWM +//#define FAN_MIN_PWM 50 + +// @section extruder + +/** + * Extruder cooling fans + * + * Extruder auto fans automatically turn on when their extruders' + * temperatures go above EXTRUDER_AUTO_FAN_TEMPERATURE. + * + * Your board's pins file specifies the recommended pins. Override those here + * or set to -1 to disable completely. + * + * Multiple extruders can be assigned to the same pin in which case + * the fan will turn on when any selected extruder is above the threshold. + */ +#define E0_AUTO_FAN_PIN -1 +#define E1_AUTO_FAN_PIN -1 +#define E2_AUTO_FAN_PIN -1 +#define E3_AUTO_FAN_PIN -1 +#define E4_AUTO_FAN_PIN -1 +#define EXTRUDER_AUTO_FAN_TEMPERATURE 50 +#define EXTRUDER_AUTO_FAN_SPEED 255 // == full speed + +/** + * Part-Cooling Fan Multiplexer + * + * This feature allows you to digitally multiplex the fan output. + * The multiplexer is automatically switched at tool-change. + * Set FANMUX[012]_PINs below for up to 2, 4, or 8 multiplexed fans. + */ +#define FANMUX0_PIN -1 +#define FANMUX1_PIN -1 +#define FANMUX2_PIN -1 + +/** + * M355 Case Light on-off / brightness + */ +//#define CASE_LIGHT_ENABLE +#if ENABLED(CASE_LIGHT_ENABLE) + //#define CASE_LIGHT_PIN 4 // Override the default pin if needed + #define INVERT_CASE_LIGHT false // Set true if Case Light is ON when pin is LOW + #define CASE_LIGHT_DEFAULT_ON true // Set default power-up state on + #define CASE_LIGHT_DEFAULT_BRIGHTNESS 105 // Set default power-up brightness (0-255, requires PWM pin) + //#define MENU_ITEM_CASE_LIGHT // Add a Case Light option to the LCD main menu +#endif + +//=========================================================================== +//============================ Mechanical Settings ========================== +//=========================================================================== + +// @section homing + +// If you want endstops to stay on (by default) even when not homing +// enable this option. Override at any time with M120, M121. +//#define ENDSTOPS_ALWAYS_ON_DEFAULT + +// @section extras + +//#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. + +// Dual X Steppers +// Uncomment this option to drive two X axis motors. +// The next unused E driver will be assigned to the second X stepper. +//#define X_DUAL_STEPPER_DRIVERS +#if ENABLED(X_DUAL_STEPPER_DRIVERS) + // Set true if the two X motors need to rotate in opposite directions + #define INVERT_X2_VS_X_DIR true +#endif + +// Dual Y Steppers +// Uncomment this option to drive two Y axis motors. +// The next unused E driver will be assigned to the second Y stepper. +//#define Y_DUAL_STEPPER_DRIVERS +#if ENABLED(Y_DUAL_STEPPER_DRIVERS) + // Set true if the two Y motors need to rotate in opposite directions + #define INVERT_Y2_VS_Y_DIR true +#endif + +// A single Z stepper driver is usually used to drive 2 stepper motors. +// Uncomment this option to use a separate stepper driver for each Z axis motor. +// The next unused E driver will be assigned to the second Z stepper. +//#define Z_DUAL_STEPPER_DRIVERS + +#if ENABLED(Z_DUAL_STEPPER_DRIVERS) + + // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper. + // That way the machine is capable to align the bed during home, since both Z steppers are homed. + // There is also an implementation of M666 (software endstops adjustment) to this feature. + // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed. + // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2. + // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive. + // Play a little bit with small adjustments (0.5mm) and check the behaviour. + // The M119 (endstops report) will start reporting the Z2 Endstop as well. + + //#define Z_DUAL_ENDSTOPS + + #if ENABLED(Z_DUAL_ENDSTOPS) + #define Z2_USE_ENDSTOP _XMAX_ + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 // Use M666 to determine/test this value + #endif + +#endif // Z_DUAL_STEPPER_DRIVERS + +// Enable this for dual x-carriage printers. +// A dual x-carriage design has the advantage that the inactive extruder can be parked which +// prevents hot-end ooze contaminating the print. It also reduces the weight of each x-carriage +// allowing faster printing speeds. Connect your X2 stepper to the first unused E plug. +//#define DUAL_X_CARRIAGE +#if ENABLED(DUAL_X_CARRIAGE) + // Configuration for second X-carriage + // Note: the first x-carriage is defined as the x-carriage which homes to the minimum endstop; + // the second x-carriage always homes to the maximum endstop. + #define X2_MIN_POS 80 // set minimum to ensure second x-carriage doesn't hit the parked first X-carriage + #define X2_MAX_POS 353 // set maximum to the distance between toolheads when both heads are homed + #define X2_HOME_DIR 1 // the second X-carriage always homes to the maximum endstop position + #define X2_HOME_POS X2_MAX_POS // default home position is the maximum carriage position + // However: In this mode the HOTEND_OFFSET_X value for the second extruder provides a software + // override for X2_HOME_POS. This also allow recalibration of the distance between the two endstops + // without modifying the firmware (through the "M218 T1 X???" command). + // Remember: you should set the second extruder x-offset to 0 in your slicer. + + // There are a few selectable movement modes for dual x-carriages using M605 S + // Mode 0 (DXC_FULL_CONTROL_MODE): Full control. The slicer has full control over both x-carriages and can achieve optimal travel results + // as long as it supports dual x-carriages. (M605 S0) + // Mode 1 (DXC_AUTO_PARK_MODE) : Auto-park mode. The firmware will automatically park and unpark the x-carriages on tool changes so + // that additional slicer support is not required. (M605 S1) + // Mode 2 (DXC_DUPLICATION_MODE) : Duplication mode. The firmware will transparently make the second x-carriage and extruder copy all + // actions of the first x-carriage. This allows the printer to print 2 arbitrary items at + // once. (2nd extruder x offset and temp offset are set using: M605 S2 [Xnnn] [Rmmm]) + + // This is the default power-up mode which can be later using M605. + #define DEFAULT_DUAL_X_CARRIAGE_MODE DXC_FULL_CONTROL_MODE + + // Default settings in "Auto-park Mode" + #define TOOLCHANGE_PARK_ZLIFT 0.2 // the distance to raise Z axis when parking an extruder + #define TOOLCHANGE_UNPARK_ZLIFT 1 // the distance to raise Z axis when unparking an extruder + + // Default x offset in duplication mode (typically set to half print bed width) + #define DEFAULT_DUPLICATION_X_OFFSET 100 + +#endif // DUAL_X_CARRIAGE + +// 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. +//#define EXT_SOLENOID + +// @section homing + +//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +#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 this is defined, if both x and y are to be homed, a diagonal move will be performed initially. + +// When G28 is called, this option will make Y home before X +//#define HOME_Y_BEFORE_X + +// @section machine + +#define AXIS_RELATIVE_MODES {false, false, false, false} + +// Allow duplication mode with a basic dual-nozzle extruder +//#define DUAL_NOZZLE_DUPLICATION_MODE + +// By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step. +#define INVERT_X_STEP_PIN false +#define INVERT_Y_STEP_PIN false +#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. +#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_E true + +#define DEFAULT_MINIMUMFEEDRATE 0.0 // minimum feedrate +#define DEFAULT_MINTRAVELFEEDRATE 0.0 + +//#define HOME_AFTER_DEACTIVATE // Require rehoming after steppers are deactivated + +// @section lcd + +#if ENABLED(ULTIPANEL) + #define MANUAL_FEEDRATE {50*60, 50*60, 4*60, 60} // Feedrates for manual moves along X, Y, Z, E from panel + #define ULTIPANEL_FEEDMULTIPLY // Comment to disable setting feedrate multiplier via encoder +#endif + +// @section extras + +// minimum time in microseconds that a movement needs to take if the buffer is emptied. +#define DEFAULT_MINSEGMENTTIME 20000 + +// If defined the movements slow down when the look ahead buffer is only half full +#define SLOWDOWN + +// Frequency limit +// See nophead's blog for more info +// Not working O +//#define XY_FREQUENCY_LIMIT 15 + +// 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 +// if unwanted behavior is observed on a user's machine when running at very slow speeds. +#define MINIMUM_PLANNER_SPEED 0.05 // (mm/sec) + +// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU. +#define MICROSTEP_MODES {16,16,16,16,16} // [1,2,4,8,16] + +/** + * @section stepper motor current + * + * Some boards have a means of setting the stepper motor current via firmware. + * + * The power on motor currents are set by: + * PWM_MOTOR_CURRENT - used by MINIRAMBO & ULTIMAIN_2 + * known compatible chips: A4982 + * DIGIPOT_MOTOR_CURRENT - used by BQ_ZUM_MEGA_3D, RAMBO & SCOOVO_X9H + * known compatible chips: AD5206 + * DAC_MOTOR_CURRENT_DEFAULT - used by PRINTRBOARD_REVF & RIGIDBOARD_V2 + * known compatible chips: MCP4728 + * DIGIPOT_I2C_MOTOR_CURRENTS - used by 5DPRINT, AZTEEG_X3_PRO, MIGHTYBOARD_REVE + * known compatible chips: MCP4451, MCP4018 + * + * Motor currents can also be set by M907 - M910 and by the LCD. + * M907 - applies to all. + * M908 - BQ_ZUM_MEGA_3D, RAMBO, PRINTRBOARD_REVF, RIGIDBOARD_V2 & SCOOVO_X9H + * M909, M910 & LCD - only PRINTRBOARD_REVF & RIGIDBOARD_V2 + */ +//#define PWM_MOTOR_CURRENT { 1300, 1300, 1250 } // Values in milliamps +//#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 + +// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +//#define DIGIPOT_I2C +//#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster +#define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 +// Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS +#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=========================== +//=========================================================================== + +#define ENCODER_RATE_MULTIPLIER // If defined, certain menu edit operations automatically multiply the steps when the encoder is moved quickly +#define ENCODER_10X_STEPS_PER_SEC 75 // If the encoder steps per sec exceeds this value, multiply steps moved x10 to quickly advance the value +#define ENCODER_100X_STEPS_PER_SEC 160 // If the encoder steps per sec exceeds this value, multiply steps moved x100 to really quickly advance the value + +//#define CHDK 4 //Pin for triggering CHDK to take a picture see how to use it here http://captain-slow.dk/2014/03/09/3d-printing-timelapses/ +#define CHDK_DELAY 50 //How long in ms the pin should stay HIGH before going LOW again + +// @section lcd + +// Include a page of printer information in the LCD Main Menu +//#define LCD_INFO_MENU + +// Scroll a longer status message into view +//#define STATUS_MESSAGE_SCROLLING + +// On the Info Screen, display XY with one decimal place when possible +//#define LCD_DECIMAL_SMALL_XY + +// The timeout (in ms) to return to the status screen from sub-menus +//#define LCD_TIMEOUT_TO_STATUS 15000 + +#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 + + #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? + #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. + + #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. + // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. + // using: + //#define MENU_ADDAUTOSTART + + /** + * Sort SD file listings in alphabetical order. + * + * With this option enabled, items on SD cards will be sorted + * by name for easier navigation. + * + * By default... + * + * - Use the slowest -but safest- method for sorting. + * - Folders are sorted to the top. + * - The sort key is statically allocated. + * - No added G-code (M34) support. + * - 40 item sorting limit. (Items after the first 40 are unsorted.) + * + * SD sorting uses static allocation (as set by SDSORT_LIMIT), allowing the + * compiler to calculate the worst-case usage and throw an error if the SRAM + * limit is exceeded. + * + * - SDSORT_USES_RAM provides faster sorting via a static directory buffer. + * - SDSORT_USES_STACK does the same, but uses a local stack-based buffer. + * - SDSORT_CACHE_NAMES will retain the sorted file listing in RAM. (Expensive!) + * - SDSORT_DYNAMIC_RAM only uses RAM when the SD menu is visible. (Use with caution!) + */ + //#define SDCARD_SORT_ALPHA + + // SD Card Sorting options + #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_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. + #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #endif + + // Show a progress bar on HD44780 LCDs for SD printing + //#define LCD_PROGRESS_BAR + + #if ENABLED(LCD_PROGRESS_BAR) + // Amount of time (ms) to show the bar + #define PROGRESS_BAR_BAR_TIME 2000 + // Amount of time (ms) to show the status message + #define PROGRESS_BAR_MSG_TIME 3000 + // Amount of time (ms) to retain the status message (0=forever) + #define PROGRESS_MSG_EXPIRE 0 + // Enable this to show messages for MSG_TIME then hide them + //#define PROGRESS_MSG_ONCE + // Add a menu item to test the progress bar: + //#define LCD_PROGRESS_BAR_TEST + #endif + + // This allows hosts to request long names for files and folders with M33 + //#define LONG_FILENAME_HOST_SUPPORT + + // This option allows you to abort SD printing when any endstop is triggered. + // This feature must be enabled with "M540 S1" or from the LCD menu. + // To have any effect, endstops must be enabled during SD printing. + //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + +#endif // SDSUPPORT + +/** + * Additional options for Graphical Displays + * + * Use the optimizations here to improve printing performance, + * which can be adversely affected by graphical display drawing, + * especially when doing several short moves, and when printing + * on DELTA and SCARA machines. + * + * Some of these options may result in the display lagging behind + * controller events, as there is a trade-off between reliable + * printing performance versus fast display updates. + */ +#if ENABLED(DOGLCD) + // Enable to save many cycles by drawing a hollow frame on the Info Screen + #define XYZ_HOLLOW_FRAME + + // Enable to save many cycles by drawing a hollow frame on Menu Screens + #define MENU_HOLLOW_FRAME + + // A bigger font is available for edit items. Costs 3120 bytes of PROGMEM. + // 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. + // 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 +#endif // DOGLCD + +// @section safety + +// The hardware watchdog should reset the microcontroller disabling all outputs, +// in case the firmware gets stuck and doesn't do temperature regulation. +#define USE_WATCHDOG + +#if ENABLED(USE_WATCHDOG) + // If you have a watchdog reboot in an ArduinoMega2560 then the device will hang forever, as a watchdog reset will leave the watchdog on. + // The "WATCHDOG_RESET_MANUAL" goes around this by not using the hardware reset. + // However, THIS FEATURE IS UNSAFE!, as it will only work if interrupts are disabled. And the code could hang in an interrupt routine with interrupts disabled. + //#define WATCHDOG_RESET_MANUAL +#endif + +// @section lcd + +/** + * Babystepping enables movement of the axes by tiny increments without changing + * the current position values. This feature is used primarily to adjust the Z + * axis in the first layer of a print in real-time. + * + * Warning: Does not respect endstops! + */ +//#define BABYSTEPPING +#if ENABLED(BABYSTEPPING) + //#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 100 // Babysteps are very small. Increase for faster motion. + //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping + //#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen 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_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor + //#define BABYSTEP_ZPROBE_GFX_REVERSE // Reverses the direction of the CW/CCW indicators +#endif + +// @section extruder + +/** + * Implementation of linear pressure control + * + * Assumption: advance = k * (delta velocity) + * K=0 means advance disabled. + * See Marlin documentation for calibration instructions. + */ +//#define LIN_ADVANCE + +#if ENABLED(LIN_ADVANCE) + #define LIN_ADVANCE_K 75 + + /** + * Some Slicers produce Gcode with randomly jumping extrusion widths occasionally. + * For example within a 0.4mm perimeter it may produce a single segment of 0.05mm width. + * While this is harmless for normal printing (the fluid nature of the filament will + * close this very, very tiny gap), it throws off the LIN_ADVANCE pressure adaption. + * + * For this case LIN_ADVANCE_E_D_RATIO can be used to set the extrusion:distance ratio + * to a fixed value. Note that using a fixed ratio will lead to wrong nozzle pressures + * if the slicer is using variable widths or layer heights within one print! + * + * This option sets the default E:D ratio at startup. Use `M900` to override this value. + * + * Example: `M900 W0.4 H0.2 D1.75`, where: + * - W is the extrusion width in mm + * - H is the layer height in mm + * - D is the filament diameter in mm + * + * Example: `M900 R0.0458` to set the ratio directly. + * + * Set to 0 to auto-detect the ratio based on given Gcode G1 print moves. + * + * Slic3r (including Průša Control) produces Gcode compatible with the automatic mode. + * Cura (as of this writing) may produce Gcode incompatible with the automatic mode. + */ + #define LIN_ADVANCE_E_D_RATIO 0 // The calculated ratio (or 0) according to the formula W * H / ((D / 2) ^ 2 * PI) + // Example: 0.4 * 0.2 / ((1.75 / 2) ^ 2 * PI) = 0.033260135 +#endif + +// @section leveling + +// Default mesh area is an area with an inset margin on the print area. +// Below are the macros that are used to define the borders for the mesh area, +// made available here for specialized needs, ie dual extruder setup. +#if ENABLED(MESH_BED_LEVELING) + #define MESH_MIN_X MESH_INSET + #define MESH_MAX_X (X_BED_SIZE - (MESH_INSET)) + #define MESH_MIN_Y MESH_INSET + #define MESH_MAX_Y (Y_BED_SIZE - (MESH_INSET)) +#elif ENABLED(AUTO_BED_LEVELING_UBL) + #define UBL_MESH_MIN_X UBL_MESH_INSET + #define UBL_MESH_MAX_X (X_BED_SIZE - (UBL_MESH_INSET)) + #define UBL_MESH_MIN_Y UBL_MESH_INSET + #define UBL_MESH_MAX_Y (Y_BED_SIZE - (UBL_MESH_INSET)) + + // If this is defined, the currently active mesh will be saved in the + // current slot on M500. + #define UBL_SAVE_ACTIVE_ON_M500 +#endif + +// @section extras + +// +// G2/G3 Arc Support +// +//#define ARC_SUPPORT // Disable this feature to save ~3226 bytes +#if ENABLED(ARC_SUPPORT) + #define MM_PER_ARC_SEGMENT 1 // Length of each arc segment + #define N_ARC_CORRECTION 25 // Number of intertpolated 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 +#endif + +// Support for G5 with XYZE destination and IJPQ offsets. Requires ~2666 bytes. +//#define BEZIER_CURVE_SUPPORT + +// G38.2 and G38.3 Probe Target +// Enable PROBE_DOUBLE_TOUCH if you want G38 to double touch +//#define G38_PROBE_TARGET +#if ENABLED(G38_PROBE_TARGET) + #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) +#endif + +// Moves (or segments) with fewer steps than this will be joined with the next move +#define MIN_STEPS_PER_SEGMENT 6 + +// The minimum pulse width (in µs) for stepping a stepper. +// Set this if you find stepping unreliable, or if using a very fast CPU. +#define MINIMUM_STEPPER_PULSE 0 // (µs) The smallest stepper pulse allowed + +// @section temperature + +// Control heater 0 and heater 1 in parallel. +//#define HEATERS_PARALLEL + +//=========================================================================== +//================================= Buffers ================================= +//=========================================================================== + +// @section hidden + +// 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, i.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 +#else + #define BLOCK_BUFFER_SIZE 16 // maximize block buffer +#endif + +// @section serial + +// The ASCII buffer for serial input +#define MAX_CMD_SIZE 96 +#define BUFSIZE 4 + +// Transmission to Host Buffer Size +// To save 386 bytes of PROGMEM (and TX_BUFFER_SIZE+3 bytes of RAM) set to 0. +// To buffer a simple "ok" you need 4 bytes. +// For ADVANCED_OK (M105) you need 32 bytes. +// For debug-echo: 128 bytes for the optimal speed. +// Other output doesn't need to be that speedy. +// :[0, 2, 4, 8, 16, 32, 64, 128, 256] +#define TX_BUFFER_SIZE 0 + +// Host Receive Buffer Size +// Without XON/XOFF flow control (see SERIAL_XON_XOFF below) 32 bytes should be enough. +// To use flow control, set this buffer size to at least 1024 bytes. +// :[0, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048] +//#define RX_BUFFER_SIZE 1024 + +#if RX_BUFFER_SIZE >= 1024 + // Enable to have the controller send XON/XOFF control characters to + // the host to signal the RX buffer is becoming full. + //#define SERIAL_XON_XOFF +#endif + +#if ENABLED(SDSUPPORT) + // Enable this option to collect and display the maximum + // RX queue usage after transferring a file to SD. + //#define SERIAL_STATS_MAX_RX_QUEUED + + // Enable this option to collect and display the number + // of dropped bytes after a file transfer to SD. + //#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! +//#define EMERGENCY_PARSER + +// Bad Serial-connections can miss a received command by sending an 'ok' +// Therefore some clients abort after 30 seconds in a timeout. +// Some other clients start sending commands while receiving a 'wait'. +// This "wait" is only sent when the buffer is empty. 1 second is a good value here. +//#define NO_TIMEOUTS 1000 // Milliseconds + +// Some clients will have this feature soon. This could make the NO_TIMEOUTS unnecessary. +//#define ADVANCED_OK + +// @section extras + +/** + * Firmware-based and LCD-controlled retract + * + * Add G10 / G11 commands for automatic firmware-based retract / recover. + * Use M207 and M208 to define parameters for retract / recover. + * + * Use M209 to enable or disable auto-retract. + * With auto-retract enabled, all G1 E moves within the set range + * will be converted to firmware-based retract/recover moves. + * + * Be sure to turn off auto-retract during filament change. + * + * Note that M207 / M208 / M209 settings are saved to EEPROM. + * + */ +//#define FWRETRACT // ONLY PARTIALLY TESTED +#if ENABLED(FWRETRACT) + #define MIN_AUTORETRACT 0.1 // When auto-retract is on, convert E moves of this length and over + #define MAX_AUTORETRACT 10.0 // Upper limit for auto-retract conversion + #define RETRACT_LENGTH 3 // Default retract length (positive mm) + #define RETRACT_LENGTH_SWAP 13 // Default swap retract length (positive mm), for extruder change + #define RETRACT_FEEDRATE 45 // Default feedrate for retracting (mm/s) + #define RETRACT_ZLIFT 0 // Default retract Z-lift + #define RETRACT_RECOVER_LENGTH 0 // Default additional recover length (mm, added to retract length when recovering) + #define RETRACT_RECOVER_LENGTH_SWAP 0 // Default additional swap recover length (mm, added to retract length when recovering from extruder change) + #define RETRACT_RECOVER_FEEDRATE 8 // Default feedrate for recovering from retraction (mm/s) + #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) +#endif + +/** + * Advanced Pause + * Experimental feature for filament change support and for parking the nozzle when paused. + * Adds the GCode M600 for initiating filament change. + * If PARK_HEAD_ON_PAUSE enabled, adds the GCode M125 to pause printing and park the nozzle. + * + * Requires an LCD display. + * This feature is required for the default FILAMENT_RUNOUT_SCRIPT. + */ +//#define ADVANCED_PAUSE_FEATURE +#if ENABLED(ADVANCED_PAUSE_FEATURE) + #define PAUSE_PARK_X_POS 3 // X position of hotend + #define PAUSE_PARK_Y_POS 3 // Y position of hotend + #define PAUSE_PARK_Z_ADD 10 // Z addition of hotend (lift) + #define PAUSE_PARK_XY_FEEDRATE 100 // X and Y axes feedrate in mm/s (also used for delta printers Z axis) + #define PAUSE_PARK_Z_FEEDRATE 5 // Z axis feedrate in mm/s (not used for delta printers) + #define PAUSE_PARK_RETRACT_FEEDRATE 60 // Initial retract feedrate in mm/s + #define PAUSE_PARK_RETRACT_LENGTH 2 // Initial retract in mm + // It is a short retract used immediately after print interrupt before move to filament exchange position + #define FILAMENT_CHANGE_UNLOAD_FEEDRATE 10 // Unload filament feedrate in mm/s - filament unloading can be fast + #define FILAMENT_CHANGE_UNLOAD_LENGTH 100 // Unload filament length from hotend in mm + // Longer length for bowden printers to unload filament from whole bowden tube, + // shorter length for printers without bowden to unload filament from extruder only, + // 0 to disable unloading for manual unloading + #define FILAMENT_CHANGE_LOAD_FEEDRATE 6 // Load filament feedrate in mm/s - filament loading into the bowden tube can be fast + #define FILAMENT_CHANGE_LOAD_LENGTH 0 // Load filament length over hotend in mm + // Longer length for bowden printers to fast load filament into whole bowden tube over the hotend, + // Short or zero length for printers without bowden where loading is not used + #define ADVANCED_PAUSE_EXTRUDE_FEEDRATE 3 // Extrude filament feedrate in mm/s - must be slower than load feedrate + #define ADVANCED_PAUSE_EXTRUDE_LENGTH 50 // Extrude filament length in mm after filament is loaded over the hotend, + // 0 to disable for manual extrusion + // Filament can be extruded repeatedly from the filament exchange menu to fill the hotend, + // or until outcoming filament color is not clear for filament color change + #define PAUSE_PARK_NOZZLE_TIMEOUT 45 // Turn off nozzle if user doesn't change filament within this time limit in seconds + #define FILAMENT_CHANGE_NUMBER_OF_ALERT_BEEPS 5 // Number of alert beeps before printer goes quiet + #define PAUSE_PARK_NO_STEPPER_TIMEOUT // Enable to have stepper motors hold position during filament change + // even if it takes longer than DEFAULT_STEPPER_DEACTIVE_TIME. + //#define PARK_HEAD_ON_PAUSE // Go to filament change position on pause, return to print position on resume + //#define HOME_BEFORE_FILAMENT_CHANGE // Ensure homing has been completed prior to parking for filament change +#endif + +// @section tmc + +/** + * Enable this section if you have TMC26X motor drivers. + * You will need to import the TMC26XStepper library into the Arduino IDE for this + * (https://github.com/trinamic/TMC26XStepper.git) + */ +//#define HAVE_TMCDRIVER + +#if ENABLED(HAVE_TMCDRIVER) + + //#define X_IS_TMC + //#define X2_IS_TMC + //#define Y_IS_TMC + //#define Y2_IS_TMC + //#define Z_IS_TMC + //#define Z2_IS_TMC + //#define E0_IS_TMC + //#define E1_IS_TMC + //#define E2_IS_TMC + //#define E3_IS_TMC + //#define E4_IS_TMC + + #define X_MAX_CURRENT 1000 // in mA + #define X_SENSE_RESISTOR 91 // in mOhms + #define X_MICROSTEPS 16 // number of microsteps + + #define X2_MAX_CURRENT 1000 + #define X2_SENSE_RESISTOR 91 + #define X2_MICROSTEPS 16 + + #define Y_MAX_CURRENT 1000 + #define Y_SENSE_RESISTOR 91 + #define Y_MICROSTEPS 16 + + #define Y2_MAX_CURRENT 1000 + #define Y2_SENSE_RESISTOR 91 + #define Y2_MICROSTEPS 16 + + #define Z_MAX_CURRENT 1000 + #define Z_SENSE_RESISTOR 91 + #define Z_MICROSTEPS 16 + + #define Z2_MAX_CURRENT 1000 + #define Z2_SENSE_RESISTOR 91 + #define Z2_MICROSTEPS 16 + + #define E0_MAX_CURRENT 1000 + #define E0_SENSE_RESISTOR 91 + #define E0_MICROSTEPS 16 + + #define E1_MAX_CURRENT 1000 + #define E1_SENSE_RESISTOR 91 + #define E1_MICROSTEPS 16 + + #define E2_MAX_CURRENT 1000 + #define E2_SENSE_RESISTOR 91 + #define E2_MICROSTEPS 16 + + #define E3_MAX_CURRENT 1000 + #define E3_SENSE_RESISTOR 91 + #define E3_MICROSTEPS 16 + + #define E4_MAX_CURRENT 1000 + #define E4_SENSE_RESISTOR 91 + #define E4_MICROSTEPS 16 + +#endif + +// @section TMC2130 + +/** + * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. + * + * You'll also need the TMC2130Stepper Arduino library + * (https://github.com/teemuatlut/TMC2130Stepper). + * + * To use TMC2130 stepper drivers in SPI mode connect your SPI2130 pins to + * the hardware SPI interface on your board and define the required CS pins + * in your `pins_MYBOARD.h` file. (e.g., RAMPS 1.4 uses AUX3 pins `X_CS_PIN 53`, `Y_CS_PIN 49`, etc.). + */ +//#define HAVE_TMC2130 + +#if ENABLED(HAVE_TMC2130) + + // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY + //#define X_IS_TMC2130 + //#define X2_IS_TMC2130 + //#define Y_IS_TMC2130 + //#define Y2_IS_TMC2130 + //#define Z_IS_TMC2130 + //#define Z2_IS_TMC2130 + //#define E0_IS_TMC2130 + //#define E1_IS_TMC2130 + //#define E2_IS_TMC2130 + //#define E3_IS_TMC2130 + //#define E4_IS_TMC2130 + + /** + * Stepper driver settings + */ + + #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 + #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current + #define INTERPOLATE 1 // Interpolate X/Y/Z_MICROSTEPS to 256 + + #define X_CURRENT 1000 // rms current in mA. Multiply by 1.41 for peak current. + #define X_MICROSTEPS 16 // 0..256 + + #define Y_CURRENT 1000 + #define Y_MICROSTEPS 16 + + #define Z_CURRENT 1000 + #define Z_MICROSTEPS 16 + + //#define X2_CURRENT 1000 + //#define X2_MICROSTEPS 16 + + //#define Y2_CURRENT 1000 + //#define Y2_MICROSTEPS 16 + + //#define Z2_CURRENT 1000 + //#define Z2_MICROSTEPS 16 + + //#define E0_CURRENT 1000 + //#define E0_MICROSTEPS 16 + + //#define E1_CURRENT 1000 + //#define E1_MICROSTEPS 16 + + //#define E2_CURRENT 1000 + //#define E2_MICROSTEPS 16 + + //#define E3_CURRENT 1000 + //#define E3_MICROSTEPS 16 + + //#define E4_CURRENT 1000 + //#define E4_MICROSTEPS 16 + + /** + * Use Trinamic's ultra quiet stepping mode. + * When disabled, Marlin will use spreadCycle stepping mode. + */ + #define STEALTHCHOP + + /** + * Let Marlin automatically control stepper current. + * This is still an experimental feature. + * Increase current every 5s by CURRENT_STEP until stepper temperature prewarn gets triggered, + * then decrease current by CURRENT_STEP until temperature prewarn is cleared. + * Adjusting starts from X/Y/Z/E_CURRENT but will not increase over AUTO_ADJUST_MAX + * 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. + * M906 S1 - Start adjusting current + * M906 S0 - Stop adjusting current + * M911 - Report stepper driver overtemperature pre-warn condition. + * M912 - Clear stepper driver overtemperature pre-warn condition flag. + */ + //#define AUTOMATIC_CURRENT_CONTROL + + #if ENABLED(AUTOMATIC_CURRENT_CONTROL) + #define CURRENT_STEP 50 // [mA] + #define AUTO_ADJUST_MAX 1300 // [mA], 1300mA_rms = 1840mA_peak + #define REPORT_CURRENT_CHANGE + #endif + + /** + * The driver will switch to spreadCycle when stepper speed is over HYBRID_THRESHOLD. + * This mode allows for faster movements at the expense of higher noise levels. + * STEALTHCHOP needs to be enabled. + * M913 X/Y/Z/E to live tune the setting + */ + //#define HYBRID_THRESHOLD + + #define X_HYBRID_THRESHOLD 100 // [mm/s] + #define X2_HYBRID_THRESHOLD 100 + #define Y_HYBRID_THRESHOLD 100 + #define Y2_HYBRID_THRESHOLD 100 + #define Z_HYBRID_THRESHOLD 4 + #define Z2_HYBRID_THRESHOLD 4 + #define E0_HYBRID_THRESHOLD 30 + #define E1_HYBRID_THRESHOLD 30 + #define E2_HYBRID_THRESHOLD 30 + #define E3_HYBRID_THRESHOLD 30 + #define E4_HYBRID_THRESHOLD 30 + + /** + * Use stallGuard2 to sense an obstacle and trigger an endstop. + * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. + * If used along with STEALTHCHOP, the movement will be louder when homing. This is normal. + * + * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. + * Higher values make the system LESS sensitive. + * Lower value make the system MORE sensitive. + * Too low values can lead to false positives, while too high values will collide the axis without triggering. + * It is advised to set X/Y_HOME_BUMP_MM to 0. + * M914 X/Y to live tune the setting + */ + //#define SENSORLESS_HOMING + + #if ENABLED(SENSORLESS_HOMING) + #define X_HOMING_SENSITIVITY 19 + #define Y_HOMING_SENSITIVITY 19 + #endif + + /** + * You can set your own advanced settings by filling in predefined functions. + * A list of available functions can be found on the library github page + * https://github.com/teemuatlut/TMC2130Stepper + * + * Example: + * #define TMC2130_ADV() { \ + * stepperX.diag0_temp_prewarn(1); \ + * stepperX.interpolate(0); \ + * } + */ + #define TMC2130_ADV() { } + +#endif // HAVE_TMC2130 + +// @section L6470 + +/** + * Enable this section if you have L6470 motor drivers. + * You need to import the L6470 library into the Arduino IDE for this. + * (https://github.com/ameyer/Arduino-L6470) + */ + +//#define HAVE_L6470DRIVER +#if ENABLED(HAVE_L6470DRIVER) + + //#define X_IS_L6470 + //#define X2_IS_L6470 + //#define Y_IS_L6470 + //#define Y2_IS_L6470 + //#define Z_IS_L6470 + //#define Z2_IS_L6470 + //#define E0_IS_L6470 + //#define E1_IS_L6470 + //#define E2_IS_L6470 + //#define E3_IS_L6470 + //#define E4_IS_L6470 + + #define X_MICROSTEPS 16 // number of microsteps + #define X_K_VAL 50 // 0 - 255, Higher values, are higher power. Be careful not to go too high + #define X_OVERCURRENT 2000 // maxc current in mA. If the current goes over this value, the driver will switch off + #define X_STALLCURRENT 1500 // current in mA where the driver will detect a stall + + #define X2_MICROSTEPS 16 + #define X2_K_VAL 50 + #define X2_OVERCURRENT 2000 + #define X2_STALLCURRENT 1500 + + #define Y_MICROSTEPS 16 + #define Y_K_VAL 50 + #define Y_OVERCURRENT 2000 + #define Y_STALLCURRENT 1500 + + #define Y2_MICROSTEPS 16 + #define Y2_K_VAL 50 + #define Y2_OVERCURRENT 2000 + #define Y2_STALLCURRENT 1500 + + #define Z_MICROSTEPS 16 + #define Z_K_VAL 50 + #define Z_OVERCURRENT 2000 + #define Z_STALLCURRENT 1500 + + #define Z2_MICROSTEPS 16 + #define Z2_K_VAL 50 + #define Z2_OVERCURRENT 2000 + #define Z2_STALLCURRENT 1500 + + #define E0_MICROSTEPS 16 + #define E0_K_VAL 50 + #define E0_OVERCURRENT 2000 + #define E0_STALLCURRENT 1500 + + #define E1_MICROSTEPS 16 + #define E1_K_VAL 50 + #define E1_OVERCURRENT 2000 + #define E1_STALLCURRENT 1500 + + #define E2_MICROSTEPS 16 + #define E2_K_VAL 50 + #define E2_OVERCURRENT 2000 + #define E2_STALLCURRENT 1500 + + #define E3_MICROSTEPS 16 + #define E3_K_VAL 50 + #define E3_OVERCURRENT 2000 + #define E3_STALLCURRENT 1500 + + #define E4_MICROSTEPS 16 + #define E4_K_VAL 50 + #define E4_OVERCURRENT 2000 + #define E4_STALLCURRENT 1500 + +#endif + +/** + * TWI/I2C BUS + * + * This feature is an EXPERIMENTAL feature so it shall not be used on production + * machines. Enabling this will allow you to send and receive I2C data from slave + * devices on the bus. + * + * ; Example #1 + * ; This macro send the string "Marlin" to the slave device with address 0x63 (99) + * ; It uses multiple M260 commands with one B arg + * M260 A99 ; Target slave address + * M260 B77 ; M + * M260 B97 ; a + * M260 B114 ; r + * M260 B108 ; l + * M260 B105 ; i + * M260 B110 ; n + * M260 S1 ; Send the current buffer + * + * ; Example #2 + * ; Request 6 bytes from slave device with address 0x63 (99) + * M261 A99 B5 + * + * ; Example #3 + * ; Example serial output of a M261 request + * echo:i2c-reply: from:99 bytes:5 data:hello + */ + +// @section i2cbus + +//#define EXPERIMENTAL_I2CBUS +#define I2C_SLAVE_ADDRESS 0 // Set a value from 8 to 127 to act as a slave + +// @section extras + +/** + * Spindle & Laser control + * + * Add the M3, M4, and M5 commands to turn the spindle/laser on and off, and + * to set spindle speed, spindle direction, and laser power. + * + * SuperPid is a router/spindle speed controller used in the CNC milling community. + * Marlin can be used to turn the spindle on and off. It can also be used to set + * the spindle speed from 5,000 to 30,000 RPM. + * + * 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. + */ +//#define SPINDLE_LASER_ENABLE +#if ENABLED(SPINDLE_LASER_ENABLE) + + #define SPINDLE_LASER_ENABLE_INVERT false // set to "true" if the on/off function is reversed + #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 // delay in milliseconds to allow the spindle/laser to come up to speed/power + #define SPINDLE_LASER_POWERDOWN_DELAY 5000 // delay in milliseconds to allow the spindle to stop + #define SPINDLE_DIR_CHANGE true // set to true if your spindle controller supports changing spindle direction + #define SPINDLE_INVERT_DIR false + #define SPINDLE_STOP_ON_DIR_CHANGE true // set to true if Marlin should stop the spindle before changing rotation direction + + /** + * The M3 & M4 commands use the following equation to convert PWM duty cycle to speed/power + * + * SPEED/POWER = PWM duty cycle * SPEED_POWER_SLOPE + SPEED_POWER_INTERCEPT + * where PWM duty cycle varies from 0 to 255 + * + * set the following for your controller (ALL MUST BE SET) + */ + + #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_SLOPE 0.3922 + //#define SPEED_POWER_INTERCEPT 0 + //#define SPEED_POWER_MIN 10 + //#define SPEED_POWER_MAX 100 // 0-100% +#endif + +/** + * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins + */ +//#define PINS_DEBUGGING + +/** + * Auto-report temperatures with M155 S + */ +#define AUTO_REPORT_TEMPERATURES + +/** + * Include capabilities in M115 output + */ +#define EXTENDED_CAPABILITIES_REPORT + +/** + * Volumetric extrusion default state + * 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. + */ +//#define VOLUMETRIC_DEFAULT_ON + +/** + * Enable this option for a leaner build of Marlin that removes all + * workspace offsets, simplifying coordinate transformations, leveling, etc. + * + * - M206 and M428 are disabled. + * - G92 will revert to its behavior from Marlin 1.0. + */ +//#define NO_WORKSPACE_OFFSETS + +/** + * 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. + * + * For clients that use a fixed-width font (like OctoPrint), leave this set to 1.0. + * Otherwise, adjust according to your client and font. + */ +#define PROPORTIONAL_FONT_RATIO 1.0 + +/** + * Spend 28 bytes of SRAM to optimize the GCode parser + */ +#define FASTER_GCODE_PARSER + +/** + * User-defined menu items that execute custom GCode + */ +//#define CUSTOM_USER_MENUS +#if ENABLED(CUSTOM_USER_MENUS) + #define USER_SCRIPT_DONE "M117 User Script Done" + #define USER_SCRIPT_AUDIBLE_FEEDBACK + //#define USER_SCRIPT_RETURN // Return to status screen after a script + + #define USER_DESC_1 "Home & UBL Info" + #define USER_GCODE_1 "G28\nG29 W" + + #define USER_DESC_2 "Preheat for PLA" + #define USER_GCODE_2 "M140 S" STRINGIFY(PREHEAT_1_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND) + + #define USER_DESC_3 "Preheat for ABS" + #define USER_GCODE_3 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND) + + #define USER_DESC_4 "Heat Bed/Home/Level" + #define USER_GCODE_4 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nG28\nG29" + + #define USER_DESC_5 "Home & Info" + #define USER_GCODE_5 "G28\nM503" +#endif + +/** + * Specify an action command to send to the host when the printer is killed. + * Will be sent in the form '//action:ACTION_ON_KILL', e.g. '//action:poweroff'. + * The host must be configured to handle the action command. + */ +//#define ACTION_ON_KILL "poweroff" + +//=========================================================================== +//====================== I2C Position Encoder Settings ====================== +//=========================================================================== + +/** + * I2C position encoders for closed loop control. + * Developed by Chris Barr at Aus3D. + * + * Wiki: http://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/ + * + * Reilabuild encoders have been modified to improve reliability. + */ + +//#define I2C_POSITION_ENCODERS +#if ENABLED(I2C_POSITION_ENCODERS) + + #define I2CPE_ENCODER_CNT 1 // The number of encoders installed; max of 5 + // encoders supported currently. + + #define I2CPE_ENC_1_ADDR I2CPE_PRESET_ADDR_X // I2C address of the encoder. 30-200. + #define I2CPE_ENC_1_AXIS X_AXIS // Axis the encoder module is installed on. _AXIS. + #define I2CPE_ENC_1_TYPE I2CPE_ENC_TYPE_LINEAR // Type of encoder: I2CPE_ENC_TYPE_LINEAR -or- + // I2CPE_ENC_TYPE_ROTARY. + #define I2CPE_ENC_1_TICKS_UNIT 2048 // 1024 for magnetic strips with 2mm poles; 2048 for + // 1mm poles. For linear encoders this is ticks / mm, + // for rotary encoders this is ticks / revolution. + //#define I2CPE_ENC_1_TICKS_REV (16 * 200) // Only needed for rotary encoders; number of stepper + // steps per full revolution (motor steps/rev * microstepping) + //#define I2CPE_ENC_1_INVERT // Invert the direction of axis travel. + #define I2CPE_ENC_1_EC_METHOD I2CPE_ECM_NONE // Type of error error correction. + #define I2CPE_ENC_1_EC_THRESH 0.10 // Threshold size for error (in mm) above which the + // printer will attempt to correct the error; errors + // smaller than this are ignored to minimize effects of + // measurement noise / latency (filter). + + #define I2CPE_ENC_2_ADDR I2CPE_PRESET_ADDR_Y // Same as above, but for encoder 2. + #define I2CPE_ENC_2_AXIS Y_AXIS + #define I2CPE_ENC_2_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_ENC_2_TICKS_UNIT 2048 + //#define I2CPE_ENC_2_TICKS_REV (16 * 200) + //#define I2CPE_ENC_2_INVERT + #define I2CPE_ENC_2_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_ENC_2_EC_THRESH 0.10 + + #define I2CPE_ENC_3_ADDR I2CPE_PRESET_ADDR_Z // Encoder 3. Add additional configuration options + #define I2CPE_ENC_3_AXIS Z_AXIS // as above, or use defaults below. + + #define I2CPE_ENC_4_ADDR I2CPE_PRESET_ADDR_E // Encoder 4. + #define I2CPE_ENC_4_AXIS E_AXIS + + #define I2CPE_ENC_5_ADDR 34 // Encoder 5. + #define I2CPE_ENC_5_AXIS E_AXIS + + // Default settings for encoders which are enabled, but without settings configured above. + #define I2CPE_DEF_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_DEF_ENC_TICKS_UNIT 2048 + #define I2CPE_DEF_TICKS_REV (16 * 200) + #define I2CPE_DEF_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_DEF_EC_THRESH 0.1 + + //#define I2CPE_ERR_THRESH_ABORT 100.0 // Threshold size for error (in mm) error on any given + // axis after which the printer will abort. Comment out to + // disable abort behaviour. + + #define I2CPE_TIME_TRUSTED 10000 // After an encoder fault, there must be no further fault + // for this amount of time (in ms) before the encoder + // is trusted again. + + /** + * Position is checked every time a new command is executed from the buffer but during long moves, + * this setting determines the minimum update time between checks. A value of 100 works well with + * error rolling average when attempting to correct only for skips and not for vibration. + */ + #define I2CPE_MIN_UPD_TIME_MS 100 // Minimum time in miliseconds between encoder checks. + + // Use a rolling average to identify persistant errors that indicate skips, as opposed to vibration and noise. + #define I2CPE_ERR_ROLLING_AVERAGE + +#endif // I2C_POSITION_ENCODERS + +/** + * MAX7219 Debug Matrix + * + * Add support for a low-cost 8x8 LED Matrix based on the Max7219 chip, which can be used as a status + * display. Requires 3 signal wires. Some useful debug options are included to demonstrate its usage. + * + * Fully assembled MAX7219 boards can be found on the internet for under $2(US). + * For example, see https://www.ebay.com/sch/i.html?_nkw=332349290049 + */ +//#define MAX7219_DEBUG +#if ENABLED(MAX7219_DEBUG) + #define MAX7219_CLK_PIN 64 // 77 on Re-ARM // Configuration of the 3 pins to control the display + #define MAX7219_DIN_PIN 57 // 78 on Re-ARM + #define MAX7219_LOAD_PIN 44 // 79 on Re-ARM + + /** + * Sample debug features + * If you add more debug displays, be careful to avoid conflicts! + */ + #define MAX7219_DEBUG_PRINTER_ALIVE // Blink corner LED of 8x8 matrix to show that the firmware is functioning + #define MAX7219_DEBUG_STEPPER_HEAD 3 // Show the stepper queue head position on this and the next LED matrix row + #define MAX7219_DEBUG_STEPPER_TAIL 5 // Show the stepper queue tail position on this and the next LED matrix row + + #define MAX7219_DEBUG_STEPPER_QUEUE 0 // Show the current stepper queue depth on this and the next LED matrix row + // If you experience stuttering, reboots, etc. this option can reveal how + // tweaks made to the configuration are affecting the printer in real-time. +#endif + +#endif // CONFIGURATION_ADV_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/Anet/A8/Configuration.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/Anet/A8/Configuration.h new file mode 100644 index 00000000..11ed3dfe --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/Anet/A8/Configuration.h @@ -0,0 +1,1708 @@ +/** + * 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 . + * + */ + +/** + * Configuration.h + * + * Basic settings such as: + * + * - Type of electronics + * - Type of temperature sensor + * - Printer geometry + * - Endstop configuration + * - LCD controller + * - Extra features + * + * Advanced settings can be found in Configuration_adv.h + * + */ +#ifndef CONFIGURATION_H +#define CONFIGURATION_H +#define CONFIGURATION_H_VERSION 010100 + +//=========================================================================== +//============================= Getting Started ============================= +//=========================================================================== + +/** + * Here are some standard links for getting your machine calibrated: + * + * http://reprap.org/wiki/Calibration + * http://youtu.be/wAL9d7FgInk + * http://calculator.josefprusa.cz + * http://reprap.org/wiki/Triffid_Hunter%27s_Calibration_Guide + * http://www.thingiverse.com/thing:5573 + * https://sites.google.com/site/repraplogphase/calibration-of-your-reprap + * http://www.thingiverse.com/thing:298812 + */ + +//=========================================================================== +//============================= DELTA Printer =============================== +//=========================================================================== +// For a Delta printer start with one of the configuration files in the +// example_configurations/delta directory and customize for your machine. +// + +//=========================================================================== +//============================= SCARA Printer =============================== +//=========================================================================== +// For a SCARA printer start with the configuration files in +// example_configurations/SCARA and customize for your machine. +// + +// @section info + +// User-specified version info of this build to display in [Pronterface, etc] terminal window during +// startup. Implementation of an idea by Prof Braino to inform user that any changes made to this +// build by the user have been successfully uploaded into firmware. +#define STRING_CONFIG_H_AUTHOR "(Bob Kuhn, Anet config)" // Who made the changes. +#define SHOW_BOOTSCREEN +#define STRING_SPLASH_LINE1 SHORT_BUILD_VERSION // will be shown during bootup in line 1 +#define STRING_SPLASH_LINE2 WEBSITE_URL // will be shown during bootup in line 2 + +// +// *** VENDORS PLEASE READ ***************************************************** +// +// Marlin now allow you to have a vendor boot image to be displayed on machine +// start. When SHOW_CUSTOM_BOOTSCREEN is defined Marlin will first show your +// custom boot image and then the default Marlin boot image is shown. +// +// We suggest for you to take advantage of this new feature and keep the Marlin +// boot image unmodified. For an example have a look at the bq Hephestos 2 +// example configuration folder. +// +//#define SHOW_CUSTOM_BOOTSCREEN +// @section machine + +/** + * Select which serial port on the board will be used for communication with the host. + * This allows the connection of wireless adapters (for instance) to non-default port pins. + * Serial port 0 is always used by the Arduino bootloader regardless of this setting. + * + * :[0, 1, 2, 3, 4, 5, 6, 7] + */ +#define SERIAL_PORT 0 + +/** + * This setting determines the communication speed of the printer. + * + * 250000 works in most cases, but you might try a lower speed if + * you commonly experience drop-outs during host printing. + * You may try up to 1000000 to speed up SD file transfer. + * + * :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000] + */ +#define BAUDRATE 115200 + +// Enable the Bluetooth serial interface on AT90USB devices +//#define BLUETOOTH + +// The following define selects which electronics board you have. +// Please choose the name from boards.h that matches your setup +#ifndef MOTHERBOARD + #define MOTHERBOARD BOARD_ANET_10 +#endif + +// Optional custom name for your RepStrap or other custom machine +// Displayed in the LCD "Ready" message +//#define CUSTOM_MACHINE_NAME "3D Printer" + +// Define this to set a unique identifier for this printer, (Used by some programs to differentiate between machines) +// You can use an online service to generate a random UUID. (eg http://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] +#define EXTRUDERS 1 + +// For Cyclops or any "multi-extruder" that shares a single nozzle. +//#define SINGLENOZZLE + +/** + * Průša MK2 Single Nozzle Multi-Material Multiplexer, and variants. + * + * This device allows one stepper driver on a control board to drive + * two to eight stepper motors, one at a time, in a manner suitable + * for extruders. + * + * This option only allows the multiplexer to switch on tool-change. + * Additional options to configure custom E moves are pending. + */ +//#define MK2_MULTIPLEXER +#if ENABLED(MK2_MULTIPLEXER) + // Override the default DIO selector pins here, if needed. + // Some pins files may provide defaults for these pins. + //#define E_MUX0_PIN 40 // Always Required + //#define E_MUX1_PIN 42 // Needed for 3 to 8 steppers + //#define E_MUX2_PIN 44 // Needed for 5 to 8 steppers +#endif + +// A dual extruder that uses a single stepper motor +//#define SWITCHING_EXTRUDER +#if ENABLED(SWITCHING_EXTRUDER) + #define SWITCHING_EXTRUDER_SERVO_NR 0 + #define SWITCHING_EXTRUDER_SERVO_ANGLES { 0, 90 } // Angles for E0, E1[, E2, E3] + #if EXTRUDERS > 3 + #define SWITCHING_EXTRUDER_E23_SERVO_NR 1 + #endif +#endif + +// A dual-nozzle that uses a servomotor to raise/lower one of the nozzles +//#define SWITCHING_NOZZLE +#if ENABLED(SWITCHING_NOZZLE) + #define SWITCHING_NOZZLE_SERVO_NR 0 + #define SWITCHING_NOZZLE_SERVO_ANGLES { 0, 90 } // Angles for E0, E1 + //#define HOTEND_OFFSET_Z { 0.0, 0.0 } +#endif + +/** + * Two separate X-carriages with extruders that connect to a moving part + * via a magnetic docking mechanism. Requires SOL1_PIN and SOL2_PIN. + */ +//#define PARKING_EXTRUDER +#if ENABLED(PARKING_EXTRUDER) + #define PARKING_EXTRUDER_SOLENOIDS_INVERT // If enabled, the solenoid is NOT magnetized with applied voltage + #define PARKING_EXTRUDER_SOLENOIDS_PINS_ACTIVE LOW // LOW or HIGH pin signal energizes the coil + #define PARKING_EXTRUDER_SOLENOIDS_DELAY 250 // Delay (ms) for magnetic field. No delay if 0 or not defined. + #define PARKING_EXTRUDER_PARKING_X { -78, 184 } // X positions for parking the extruders + #define PARKING_EXTRUDER_GRAB_DISTANCE 1 // mm to move beyond the parking point to grab the extruder + #define PARKING_EXTRUDER_SECURITY_RAISE 5 // Z-raise before parking + #define HOTEND_OFFSET_Z { 0.0, 1.3 } // Z-offsets of the two hotends. The first must be 0. +#endif + +/** + * "Mixing Extruder" + * - Adds a new code, M165, to set the current mix factors. + * - Extends the stepping routines to move multiple steppers in proportion to the mix. + * - Optional support for Repetier Firmware M163, M164, and virtual extruder. + * - This implementation supports only a single extruder. + * - Enable DIRECT_MIXING_IN_G1 for Pia Taubert's reference implementation + */ +//#define MIXING_EXTRUDER +#if ENABLED(MIXING_EXTRUDER) + #define MIXING_STEPPERS 2 // Number of steppers in your mixing extruder + #define MIXING_VIRTUAL_TOOLS 16 // Use the Virtual Tool method with M163 and M164 + //#define DIRECT_MIXING_IN_G1 // Allow ABCDHI mix factors in G1 movement commands +#endif + +// Offset of the extruders (uncomment if using more than one and relying on firmware to position when changing). +// The offset has to be X=0, Y=0 for the extruder 0 hotend (default extruder). +// For the other hotends it is their distance from the extruder 0 hotend. +//#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis +//#define HOTEND_OFFSET_Y {0.0, 5.00} // (in mm) for each extruder, offset of the hotend on the Y axis + +// @section machine + +/** + * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN + * + * 0 = No Power Switch + * 1 = ATX + * 2 = X-Box 360 203Watts (the blue wire connected to PS_ON and the red wire to VCC) + * + * :{ 0:'No power switch', 1:'ATX', 2:'X-Box 360' } + */ +#define POWER_SUPPLY 0 + +#if POWER_SUPPLY > 0 + // Enable this option to leave the PSU off at startup. + // Power to steppers and heaters will need to be turned on with M80. + //#define PS_DEFAULT_OFF +#endif + +// @section temperature + +//=========================================================================== +//============================= Thermal Settings ============================ +//=========================================================================== + +/** + * --NORMAL IS 4.7kohm PULLUP!-- 1kohm pullup can be used on hotend sensor, using correct resistor and table + * + * Temperature sensors available: + * + * -3 : thermocouple with MAX31855 (only for sensor 0) + * -2 : thermocouple with MAX6675 (only for sensor 0) + * -1 : thermocouple with AD595 + * 0 : not used + * 1 : 100k thermistor - best choice for EPCOS 100k (4.7k pullup) + * 2 : 200k thermistor - ATC Semitec 204GT-2 (4.7k pullup) + * 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 (Used in ParCan & J-Head) (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) + * 71 : 100k Honeywell thermistor 135-104LAF-J01 (4.7k pullup) + * 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) + * 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" + * 20 : the PT100 circuit found in the Ultimainboard V2.x + * 60 : 100k Maker's Tool Works Kapton Bed Thermistor beta=3950 + * 66 : 4.7M High Temperature thermistor from Dyze Design + * 70 : the 100K thermistor found in the bq Hephestos 2 + * 75 : 100k Generic Silicon Heat Pad with NTC 100K MGB18-104F39050L32 thermistor + * + * 1k ohm pullup tables - This is atypical, and requires changing out the 4.7k pullup for 1k. + * (but gives greater accuracy and more stable PID) + * 51 : 100k thermistor - EPCOS (1k pullup) + * 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 + * 1010 : Pt1000 with 1k pullup (non standard) + * 147 : Pt100 with 4k7 pullup + * 110 : Pt100 with 1k pullup (non standard) + * + * Use these for Testing or Development purposes. NEVER for production machine. + * 998 : Dummy Table that ALWAYS reads 25°C or the temperature defined below. + * 999 : Dummy Table that ALWAYS reads 100°C or the temperature defined below. + * + * :{ '0': "Not used", '1':"100k / 4.7k - EPCOS", '2':"200k / 4.7k - ATC Semitec 204GT-2", '3':"Mendel-parts / 4.7k", '4':"10k !! do not use for a hotend. Bad resolution at high temp. !!", '5':"100K / 4.7k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '6':"100k / 4.7k EPCOS - Not as accurate as Table 1", '7':"100k / 4.7k Honeywell 135-104LAG-J01", '8':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT", '9':"100k / 4.7k GE Sensing AL03006-58.2K-97-G1", '10':"100k / 4.7k RS 198-961", '11':"100k / 4.7k beta 3950 1%", '12':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT (calibrated for Makibox hot bed)", '13':"100k Hisens 3950 1% up to 300°C for hotend 'Simple ONE ' & hotend 'All In ONE'", '20':"PT100 (Ultimainboard V2.x)", '51':"100k / 1k - EPCOS", '52':"200k / 1k - ATC Semitec 204GT-2", '55':"100k / 1k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '60':"100k Maker's Tool Works Kapton Bed Thermistor beta=3950", '66':"Dyze Design 4.7M High Temperature thermistor", '70':"the 100K thermistor found in the bq Hephestos 2", '71':"100k / 4.7k Honeywell 135-104LAF-J01", '147':"Pt100 / 4.7k", '1047':"Pt1000 / 4.7k", '110':"Pt100 / 1k (non-standard)", '1010':"Pt1000 / 1k (non standard)", '-3':"Thermocouple + MAX31855 (only for sensor 0)", '-2':"Thermocouple + MAX6675 (only for sensor 0)", '-1':"Thermocouple + AD595",'998':"Dummy 1", '999':"Dummy 2" } + */ +#define TEMP_SENSOR_0 5 +#define TEMP_SENSOR_1 0 +#define TEMP_SENSOR_2 0 +#define TEMP_SENSOR_3 0 +#define TEMP_SENSOR_4 0 +#define TEMP_SENSOR_BED 5 + +// Dummy thermistor constant temperature readings, for use with 998 and 999 +#define DUMMY_THERMISTOR_998_VALUE 25 +#define DUMMY_THERMISTOR_999_VALUE 100 + +// 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 +#define MAX_REDUNDANT_TEMP_SENSOR_DIFF 10 + +// Extruder temperature must be close to target for this long before M109 returns success +#define TEMP_RESIDENCY_TIME 6 // (seconds) +#define TEMP_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// Bed temperature must be close to target for this long before M190 returns success +#define TEMP_BED_RESIDENCY_TIME 6 // (seconds) +#define TEMP_BED_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_BED_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// The minimal temperature defines the temperature below which the heater will not be enabled It is used +// to check that the wiring to the thermistor is not broken. +// Otherwise this would lead to the heater being powered on all the time. +#define HEATER_0_MINTEMP 5 +#define HEATER_1_MINTEMP 5 +#define HEATER_2_MINTEMP 5 +#define HEATER_3_MINTEMP 5 +#define HEATER_4_MINTEMP 5 +#define BED_MINTEMP 5 + +// When temperature exceeds max temp, your heater will be switched off. +// This feature exists to protect your hotend from overheating accidentally, but *NOT* from thermistor short/failure! +// You should use MINTEMP for thermistor short/failure protection. +#define HEATER_0_MAXTEMP 275 +#define HEATER_1_MAXTEMP 275 +#define HEATER_2_MAXTEMP 275 +#define HEATER_3_MAXTEMP 275 +#define HEATER_4_MAXTEMP 275 +#define BED_MAXTEMP 130 + +//=========================================================================== +//============================= PID Settings ================================ +//=========================================================================== +// PID Tuning Guide here: http://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 +#if ENABLED(PIDTEMP) + //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. + //#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 15 // 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. + #define K1 0.95 //smoothing factor within the PID + + // If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it + + // Ultimaker + //#define DEFAULT_Kp 21.0 + //#define DEFAULT_Ki 1.25 + //#define DEFAULT_Kd 86.0 + + // 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 + + // ANET A8 Standard Extruder at 210 Degree Celsius and 100% Fan + //(measured after M106 S255 with M303 E0 S210 C8) + #define DEFAULT_Kp 21.0 + #define DEFAULT_Ki 1.25 + #define DEFAULT_Kd 86.0 + +#endif // PIDTEMP + +//=========================================================================== +//============================= PID > Bed Temperature Control =============== +//=========================================================================== +// Select PID or bang-bang with PIDTEMPBED. If bang-bang, BED_LIMIT_SWITCHING will enable hysteresis +// +// Uncomment this to enable PID on the bed. It uses the same frequency PWM as the extruder. +// If your PID_dT is the default, and correct for your hardware/configuration, that means 7.689Hz, +// which is fine for driving a square wave into a resistive load and does not significantly impact you FET heating. +// This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W heater. +// If your configuration is significantly different than this and you don't understand the issues involved, you probably +// shouldn't use bed PID until someone else verifies your hardware works. +// If this is enabled, find your own PID constants below. +//#define PIDTEMPBED + +#define BED_LIMIT_SWITCHING + +// This sets the max power delivered to the bed, and replaces the HEATER_BED_DUTY_CYCLE_DIVIDER option. +// all forms of bed control obey this (PID, bang-bang, bang-bang with hysteresis) +// setting this to anything other than 255 enables a form of PWM to the bed just like HEATER_BED_DUTY_CYCLE_DIVIDER did, +// so you shouldn't use it unless you are OK with PWM on your bed. (see the comment on enabling PIDTEMPBED) +#define MAX_BED_POWER 255 // limits duty cycle to bed; 255=full current + +#if ENABLED(PIDTEMPBED) + + //#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) + #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 + +// @section extruder + +// This option prevents extrusion if the temperature is below EXTRUDE_MINTEMP. +// It also enables the M302 command to set the minimum extrusion temperature +// or to allow moving the extruder regardless of the hotend temperature. +// *** IT IS HIGHLY RECOMMENDED TO LEAVE THIS OPTION ENABLED! *** +#define PREVENT_COLD_EXTRUSION +#define EXTRUDE_MINTEMP 170 + +// This option prevents a single extrusion longer than EXTRUDE_MAXLENGTH. +// Note that for Bowden Extruders a too-small value here may prevent loading. +#define PREVENT_LENGTHY_EXTRUDE +#define EXTRUDE_MAXLENGTH 200 + +//=========================================================================== +//======================== Thermal Runaway Protection ======================= +//=========================================================================== + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * If you get "Thermal Runaway" or "Heating failed" errors the + * details can be tuned in Configuration_adv.h + */ + +#define THERMAL_PROTECTION_HOTENDS // Enable thermal protection for all extruders +#define THERMAL_PROTECTION_BED // Enable thermal protection for the heated bed + +//=========================================================================== +//============================= Mechanical Settings ========================= +//=========================================================================== + +// @section machine + +// Uncomment one of these options to enable CoreXY, CoreXZ, or CoreYZ kinematics +// either in the usual order or reversed +//#define COREXY +//#define COREXZ +//#define COREYZ +//#define COREYX +//#define COREZX +//#define COREZY + +//=========================================================================== +//============================== Endstop Settings =========================== +//=========================================================================== + +// @section homing + +// Specify here all the endstop connectors that are connected to any endstop or probe. +// Almost all printers will be using one per axis. Probes will use one or more of the +// extra connectors. Leave undefined any used for non-endstop and non-probe purposes. +#define USE_XMIN_PLUG +#define USE_YMIN_PLUG +#define USE_ZMIN_PLUG +//#define USE_XMAX_PLUG +//#define USE_YMAX_PLUG +//#define USE_ZMAX_PLUG + +// coarse Endstop Settings +#define ENDSTOPPULLUPS // Comment this out (using // at the start of the line) to disable the endstop pullup resistors + +#if DISABLED(ENDSTOPPULLUPS) + // fine endstop settings: Individual pullups. will be ignored if ENDSTOPPULLUPS is defined + //#define ENDSTOPPULLUP_XMAX + //#define ENDSTOPPULLUP_YMAX + //#define ENDSTOPPULLUP_ZMAX + //#define ENDSTOPPULLUP_XMIN + //#define ENDSTOPPULLUP_YMIN + //#define ENDSTOPPULLUP_ZMIN + //#define ENDSTOPPULLUP_ZMIN_PROBE +#endif + +// Mechanical endstop with COM to ground and NC to Signal uses "false" here (most common setup). +#define X_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Y_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define X_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Y_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MIN_PROBE_ENDSTOP_INVERTING true // set to true to invert the logic of the probe. + +// Enable this feature if all enabled endstop pins are interrupt-capable. +// This will remove the need to poll the interrupt pins, saving many CPU cycles. +#define ENDSTOP_INTERRUPTS_FEATURE + +//============================================================================= +//============================== Movement Settings ============================ +//============================================================================= +// @section motion + +/** + * Default Settings + * + * These settings can be reset by M502 + * + * Note that if EEPROM is enabled, saved values will override these. + */ + +/** + * With this option each E stepper can have its own factors for the + * following movement settings. If fewer factors are given than the + * total number of extruders, the last value applies to the rest. + */ +//#define DISTINCT_E_FACTORS + +/** + * Default Axis Steps Per Unit (steps/mm) + * Override with M92 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_AXIS_STEPS_PER_UNIT { 100, 100, 400, 95 } + +/** + * Default Max Feed Rate (mm/s) + * Override with M203 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_FEEDRATE { 400, 400, 8, 50 } + +/** + * Default Max Acceleration (change/s) change = mm/s + * (Maximum start speed for accelerated moves) + * Override with M201 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_ACCELERATION { 2000, 2000, 100, 10000 } + +/** + * Default Acceleration (change/s) change = mm/s + * Override with M204 + * + * M204 P Acceleration + * M204 R Retract Acceleration + * M204 T Travel Acceleration + */ +#define DEFAULT_ACCELERATION 400 // X, Y, Z and E acceleration for printing moves +#define DEFAULT_RETRACT_ACCELERATION 1000 // E acceleration for retracts +#define DEFAULT_TRAVEL_ACCELERATION 1000 // X, Y, Z acceleration for travel (non printing) moves + +/** + * Default Jerk (mm/s) + * Override with M205 X Y Z E + * + * "Jerk" specifies the minimum speed change that requires acceleration. + * When changing speed and direction, if the difference is less than the + * value set here, it may happen instantaneously. + */ +#define DEFAULT_XJERK 20.0 +#define DEFAULT_YJERK 20.0 +#define DEFAULT_ZJERK 0.3 +#define DEFAULT_EJERK 5.0 + +//=========================================================================== +//============================= Z Probe Options ============================= +//=========================================================================== +// @section probes + +// +// See http://marlinfw.org/configuration/probes.html +// + +/** + * Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + * + * Enable this option for a probe connected to the Z Min endstop pin. + */ +#define Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + +/** + * Z_MIN_PROBE_ENDSTOP + * + * Enable this option for a probe connected to any pin except Z-Min. + * (By default Marlin assumes the Z-Max endstop pin.) + * To use a custom Z Probe pin, set Z_MIN_PROBE_PIN below. + * + * - The simplest option is to use a free endstop connector. + * - Use 5V for powered (usually inductive) sensors. + * + * - RAMPS 1.3/1.4 boards may use the 5V, GND, and Aux4->D32 pin: + * - For simple switches connect... + * - normally-closed switches to GND and D32. + * - normally-open switches to 5V and D32. + * + * WARNING: Setting the wrong pin may have unexpected and potentially + * disastrous consequences. Use with caution and do your homework. + * + */ +//#define Z_MIN_PROBE_ENDSTOP + +/** + * Probe Type + * + * Allen Key Probes, Servo Probes, Z-Sled Probes, FIX_MOUNTED_PROBE, etc. + * Activate one of these to use Auto Bed Leveling below. + */ + +/** + * The "Manual Probe" provides a means to do "Auto" Bed Leveling without a probe. + * Use G29 repeatedly, adjusting the Z height at each point with movement commands + * or (with LCD_BED_LEVELING) the LCD controller. + */ +//#define PROBE_MANUALLY + +/** + * A Fix-Mounted Probe either doesn't deploy or needs manual deployment. + * (e.g., an inductive probe or a nozzle-based probe-switch.) + */ +//#define FIX_MOUNTED_PROBE + +/** + * Z Servo Probe, such as an endstop switch on a rotating arm. + */ +//#define Z_ENDSTOP_SERVO_NR 0 // Defaults to SERVO 0 connector. +//#define Z_SERVO_ANGLES {70,0} // Z Servo Deploy and Stow angles + +/** + * The BLTouch probe uses a Hall effect sensor and emulates a servo. + */ +//#define BLTOUCH +#if ENABLED(BLTOUCH) + //#define BLTOUCH_DELAY 375 // (ms) Enable and increase if needed +#endif + +/** + * Enable one or more of the following if probing seems unreliable. + * Heaters and/or fans can be disabled during probing to minimize electrical + * noise. A delay can also be added to allow noise and vibration to settle. + * These options are most useful for the BLTouch probe, but may also improve + * readings with inductive probes and piezo sensors. + */ +//#define PROBING_HEATERS_OFF // Turn heaters off when probing +//#define PROBING_FANS_OFF // Turn fans off when probing +//#define DELAY_BEFORE_PROBING 200 // (ms) To prevent vibrations from triggering piezo sensors + +// A probe that is deployed and stowed with a solenoid pin (SOL1_PIN) +//#define SOLENOID_PROBE + +// A sled-mounted probe like those designed by Charles Bell. +//#define Z_PROBE_SLED +//#define SLED_DOCKING_OFFSET 5 // The extra distance the X axis must travel to pickup the sled. 0 should be fine but you can push it further if you'd like. + +// +// For Z_PROBE_ALLEN_KEY see the Delta example configurations. +// + +/** + * Z Probe to nozzle (X,Y) offset, relative to (0, 0). + * X and Y offsets must be integers. + * + * In the following example the X and Y offsets are both positive: + * #define X_PROBE_OFFSET_FROM_EXTRUDER 10 + * #define Y_PROBE_OFFSET_FROM_EXTRUDER 10 + * + * +-- BACK ---+ + * | | + * L | (+) P | R <-- probe (20,20) + * E | | I + * F | (-) N (+) | G <-- nozzle (10,10) + * T | | H + * | (-) | T + * | | + * O-- FRONT --+ + * (0,0) + */ +#define X_PROBE_OFFSET_FROM_EXTRUDER 0 // X offset: -left +right [of the nozzle] +#define Y_PROBE_OFFSET_FROM_EXTRUDER 0 // Y offset: -front +behind [the nozzle] +#define Z_PROBE_OFFSET_FROM_EXTRUDER 0 // Z offset: -below +above [the nozzle] + +// X and Y axis travel speed (mm/m) between probes +#define XY_PROBE_SPEED 6000 + +// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +#define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z + +// Speed for the "accurate" probe of each point +#define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) + +// Use double touch for probing +//#define PROBE_DOUBLE_TOUCH + +/** + * Z probes require clearance when deploying, stowing, and moving between + * probe points to avoid hitting the bed and other hardware. + * Servo-mounted probes require extra space for the arm to rotate. + * Inductive probes need space to keep from triggering early. + * + * Use these settings to specify the distance (mm) to raise the probe (or + * lower the bed). The values set here apply over and above any (negative) + * probe Z Offset set with Z_PROBE_OFFSET_FROM_EXTRUDER, M851, or the LCD. + * Only integer values >= 1 are valid here. + * + * Example: `M851 Z-5` with a CLEARANCE of 4 => 9mm from bed to nozzle. + * But: `M851 Z+1` with a CLEARANCE of 2 => 2mm from bed to nozzle. + */ +#define Z_CLEARANCE_DEPLOY_PROBE 10 // Z Clearance for Deploy/Stow +#define Z_CLEARANCE_BETWEEN_PROBES 5 // Z Clearance between probe points + +// For M851 give a range for adjusting the Z probe offset +#define Z_PROBE_OFFSET_RANGE_MIN -20 +#define Z_PROBE_OFFSET_RANGE_MAX 20 + +// Enable the M48 repeatability test to test probe accuracy +//#define Z_MIN_PROBE_REPEATABILITY_TEST + +// For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1 +// :{ 0:'Low', 1:'High' } +#define X_ENABLE_ON 0 +#define Y_ENABLE_ON 0 +#define Z_ENABLE_ON 0 +#define E_ENABLE_ON 0 // For all extruders + +// Disables axis stepper immediately when it's not being used. +// 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 +//#define DISABLE_REDUCED_ACCURACY_WARNING + +// @section extruder + +#define DISABLE_E false // For all extruders +#define DISABLE_INACTIVE_EXTRUDER true // Keep only the active extruder enabled. + +// @section machine + +// Invert the stepper direction. Change (or reverse the motor connector) if an axis goes the wrong way. +#define INVERT_X_DIR false +#define INVERT_Y_DIR false +#define INVERT_Z_DIR true + +// Enable this option for Toshiba stepper drivers +//#define CONFIG_STEPPERS_TOSHIBA + +// @section extruder + +// For direct drive extruder v9 set to true, for geared extruder set to false. +#define INVERT_E0_DIR false +#define INVERT_E1_DIR false +#define INVERT_E2_DIR false +#define INVERT_E3_DIR false +#define INVERT_E4_DIR false + +// @section homing + +//#define NO_MOTION_BEFORE_HOMING // Inhibit movement until all axes have been homed + +//#define Z_HOMING_HEIGHT 4 // (in mm) Minimal z height before homing (G28) for Z clearance above the bed, clamps, ... + // Be sure you have this distance over your Z_MAX_POS in case. + +// Direction of endstops when homing; 1=MAX, -1=MIN +// :[-1,1] +#define X_HOME_DIR -1 +#define Y_HOME_DIR -1 +#define Z_HOME_DIR -1 + +// @section machine + +// The size of the print bed +#define X_BED_SIZE 220 +#define Y_BED_SIZE 220 + +// Travel limits (mm) after homing, corresponding to endstop positions. +#define X_MIN_POS -33 +#define Y_MIN_POS -10 +#define Z_MIN_POS 0 +#define X_MAX_POS X_BED_SIZE +#define Y_MAX_POS Y_BED_SIZE +#define Z_MAX_POS 240 + +// If enabled, axes won't move below MIN_POS in response to movement commands. +#define MIN_SOFTWARE_ENDSTOPS +// If enabled, axes won't move above MAX_POS in response to movement commands. +#define MAX_SOFTWARE_ENDSTOPS + +/** + * Filament Runout Sensor + * A mechanical or opto endstop is used to check for the presence of filament. + * + * RAMPS-based boards use SERVO3_PIN. + * For other boards you may need to define FIL_RUNOUT_PIN. + * By default the firmware assumes HIGH = has filament, LOW = ran out + */ +//#define FILAMENT_RUNOUT_SENSOR +#if ENABLED(FILAMENT_RUNOUT_SENSOR) + #define FIL_RUNOUT_INVERTING false // set to true to invert the logic of the sensor. + #define ENDSTOPPULLUP_FIL_RUNOUT // Uncomment to use internal pullup for filament runout pins if the sensor is defined. + #define FILAMENT_RUNOUT_SCRIPT "M600" +#endif + +//=========================================================================== +//=============================== Bed Leveling ============================== +//=========================================================================== +// @section bedlevel + +/** + * Choose one of the options below to enable G29 Bed Leveling. The parameters + * and behavior of G29 will change depending on your selection. + * + * If using a Probe for Z Homing, enable Z_SAFE_HOMING also! + * + * - AUTO_BED_LEVELING_3POINT + * Probe 3 arbitrary points on the bed (that aren't collinear) + * You specify the XY coordinates of all 3 points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_LINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_BILINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a mesh, best for large or uneven beds. + * + * - AUTO_BED_LEVELING_UBL (Unified Bed Leveling) + * A comprehensive bed leveling system combining the features and benefits + * of other systems. UBL also includes integrated Mesh Generation, Mesh + * Validation and Mesh Editing systems. Currently, UBL is only checked out + * for Cartesian Printers. That said, it was primarily designed to correct + * poor quality Delta Printers. If you feel adventurous and have a Delta, + * please post an issue if something doesn't work correctly. Initially, + * you will need to set a reduced bed size so you have a rectangular area + * to test on. + * + * - MESH_BED_LEVELING + * Probe a grid manually + * The result is a mesh, suitable for large or uneven beds. (See BILINEAR.) + * For machines without a probe, Mesh Bed Leveling provides a method to perform + * leveling in steps so you can manually adjust the Z height at each grid-point. + * With an LCD controller the process is guided step-by-step. + */ +//#define AUTO_BED_LEVELING_3POINT +//#define AUTO_BED_LEVELING_LINEAR +//#define AUTO_BED_LEVELING_BILINEAR +//#define AUTO_BED_LEVELING_UBL +//#define MESH_BED_LEVELING + +/** + * Enable detailed logging of G28, G29, M48, etc. + * Turn on with the command 'M111 S32'. + * NOTE: Requires a lot of PROGMEM! + */ +//#define DEBUG_LEVELING_FEATURE + +#if ENABLED(MESH_BED_LEVELING) || ENABLED(AUTO_BED_LEVELING_BILINEAR) || ENABLED(AUTO_BED_LEVELING_UBL) + // Gradually reduce leveling correction until a set height is reached, + // at which point movement will be level to the machine's XY plane. + // The height can be set with M420 Z + #define ENABLE_LEVELING_FADE_HEIGHT +#endif + +#if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Set the number of grid points per dimension. + #define GRID_MAX_POINTS_X 3 + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + // Set the boundaries for probing (where the probe can reach). + #define LEFT_PROBE_BED_POSITION 15 + #define RIGHT_PROBE_BED_POSITION 190 + #define FRONT_PROBE_BED_POSITION 15 + #define BACK_PROBE_BED_POSITION 170 + + // The Z probe minimum outer margin (to validate G29 parameters). + #define MIN_PROBE_EDGE 10 + + // Probe along the Y axis, advancing X after each column + //#define PROBE_Y_FIRST + + #if ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Beyond the probed grid, continue the implied tilt? + // Default is to maintain the height of the nearest edge. + //#define EXTRAPOLATE_BEYOND_GRID + + // + // Experimental Subdivision of the grid by Catmull-Rom method. + // Synthesizes intermediate points to produce a more detailed mesh. + // + //#define ABL_BILINEAR_SUBDIVISION + #if ENABLED(ABL_BILINEAR_SUBDIVISION) + // Number of subdivisions between probe points + #define BILINEAR_SUBDIVISIONS 3 + #endif + + #endif + +#elif ENABLED(AUTO_BED_LEVELING_3POINT) + + // 3 arbitrary points to probe. + // A simple cross-product is used to estimate the plane of the bed. + #define ABL_PROBE_PT_1_X 20 + #define ABL_PROBE_PT_1_Y 160 + #define ABL_PROBE_PT_2_X 20 + #define ABL_PROBE_PT_2_Y 10 + #define ABL_PROBE_PT_3_X 180 + #define ABL_PROBE_PT_3_Y 10 + +#elif ENABLED(AUTO_BED_LEVELING_UBL) + + //=========================================================================== + //========================= Unified Bed Leveling ============================ + //=========================================================================== + + #define UBL_MESH_INSET 1 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 10 // Don't use more than 15 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + #define UBL_PROBE_PT_1_X 39 // Probing points for 3-Point leveling of the mesh + #define UBL_PROBE_PT_1_Y 180 + #define UBL_PROBE_PT_2_X 39 + #define UBL_PROBE_PT_2_Y 20 + #define UBL_PROBE_PT_3_X 180 + #define UBL_PROBE_PT_3_Y 20 + + #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation + #define UBL_MESH_EDIT_MOVES_Z // Sophisticated users prefer no movement of nozzle + +#elif ENABLED(MESH_BED_LEVELING) + + //=========================================================================== + //=================================== Mesh ================================== + //=========================================================================== + + #define MESH_INSET 10 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 3 // Don't use more than 7 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + //#define MESH_G28_REST_ORIGIN // After homing all axes ('G28' or 'G28 XYZ') rest Z at Z_MIN_POS + +#endif // BED_LEVELING + +/** + * Use the LCD controller for bed leveling + * Requires MESH_BED_LEVELING or PROBE_MANUALLY + */ +//#define LCD_BED_LEVELING + +#if ENABLED(LCD_BED_LEVELING) + #define MBL_Z_STEP 0.025 // Step size while manually probing Z axis. + #define LCD_PROBE_Z_RANGE 4 // Z Range centered on Z_MIN_POS for LCD Z adjustment +#endif + +// Add a menu item to move between bed corners for manual bed adjustment +//#define LEVEL_BED_CORNERS + +/** + * Commands to execute at the end of G29 probing. + * Useful to retract or move the Z probe out of the way. + */ +//#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) +//#define BED_CENTER_AT_0_0 + +// Manually set the home position. Leave these undefined for automatic settings. +// For DELTA this is the top-center of the Cartesian print volume. +//#define MANUAL_X_HOME_POS 0 +//#define MANUAL_Y_HOME_POS 0 +//#define MANUAL_Z_HOME_POS 0 + +// Use "Z Safe Homing" to avoid homing with a Z probe outside the bed area. +// +// With this feature enabled: +// +// - 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). +// - 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 axis (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). +#endif + +// Homing speeds (mm/m) +#define HOMING_FEEDRATE_XY (100*60) +#define HOMING_FEEDRATE_Z (4*60) + +//============================================================================= +//============================= Additional Features =========================== +//============================================================================= + +// @section extras + +// +// EEPROM +// +// The microcontroller can store settings in the EEPROM, e.g. max velocity... +// M500 - stores parameters in EEPROM +// M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily). +// M502 - reverts to the default "factory settings". You still need to store them in EEPROM afterwards if you want to. +// +#define EEPROM_SETTINGS // Enable for M500 and M501 commands +//#define DISABLE_M503 // Saves ~2700 bytes of PROGMEM. Disable for release! +#define EEPROM_CHITCHAT // Give feedback on EEPROM commands. Disable to save PROGMEM. + +// +// Host Keepalive +// +// When enabled Marlin will send a busy status message to the host +// every couple of seconds when it can't accept commands. +// +//#define HOST_KEEPALIVE_FEATURE // Disable this if your host doesn't like keepalive messages +//#define DEFAULT_KEEPALIVE_INTERVAL 2 // Number of seconds between "busy" messages. Set with M113. +#define BUSY_WHILE_HEATING // Some hosts require "busy" messages even during heating + +// +// M100 Free Memory Watcher +// +//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose + +// +// G20/G21 Inch mode support +// +//#define INCH_MODE_SUPPORT + +// +// M149 Set temperature units support +// +//#define TEMPERATURE_UNITS_SUPPORT + +// @section temperature + +// Preheat Constants +#define PREHEAT_1_TEMP_HOTEND 190 +#define PREHEAT_1_TEMP_BED 60 +#define PREHEAT_1_FAN_SPEED 0 // Value from 0 to 255 + +#define PREHEAT_2_TEMP_HOTEND 240 +#define PREHEAT_2_TEMP_BED 90 +#define PREHEAT_2_FAN_SPEED 0 // Value from 0 to 255 + +/** + * Nozzle Park -- EXPERIMENTAL + * + * Park the nozzle at the given XYZ position on idle or G27. + * + * The "P" parameter controls the action applied to the Z axis: + * + * P0 (Default) If Z is below park Z raise the nozzle. + * P1 Raise the nozzle always to Z-park height. + * P2 Raise the nozzle by Z-park amount, limited to Z_MAX_POS. + */ +//#define NOZZLE_PARK_FEATURE + +#if ENABLED(NOZZLE_PARK_FEATURE) + // Specify a park position as { X, Y, Z } + #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 } +#endif + +/** + * Clean Nozzle Feature -- EXPERIMENTAL + * + * Adds the G12 command to perform a nozzle cleaning process. + * + * Parameters: + * P Pattern + * S Strokes / Repetitions + * T Triangles (P1 only) + * + * Patterns: + * P0 Straight line (default). This process requires a sponge type material + * at a fixed bed location. "S" specifies strokes (i.e. back-forth motions) + * between the start / end points. + * + * P1 Zig-zag pattern between (X0, Y0) and (X1, Y1), "T" specifies the + * number of zig-zag triangles to do. "S" defines the number of strokes. + * Zig-zags are done in whichever is the narrower dimension. + * For example, "G12 P1 S1 T3" will execute: + * + * -- + * | (X0, Y1) | /\ /\ /\ | (X1, Y1) + * | | / \ / \ / \ | + * A | | / \ / \ / \ | + * | | / \ / \ / \ | + * | (X0, Y0) | / \/ \/ \ | (X1, Y0) + * -- +--------------------------------+ + * |________|_________|_________| + * T1 T2 T3 + * + * P2 Circular pattern with middle at NOZZLE_CLEAN_CIRCLE_MIDDLE. + * "R" specifies the radius. "S" specifies the stroke count. + * Before starting, the nozzle moves to NOZZLE_CLEAN_START_POINT. + * + * Caveats: The ending Z should be the same as starting Z. + * Attention: EXPERIMENTAL. G-code arguments may change. + * + */ +//#define NOZZLE_CLEAN_FEATURE + +#if ENABLED(NOZZLE_CLEAN_FEATURE) + // Default number of pattern repetitions + #define NOZZLE_CLEAN_STROKES 12 + + // Default number of triangles + #define NOZZLE_CLEAN_TRIANGLES 3 + + // Specify positions as { X, Y, Z } + #define NOZZLE_CLEAN_START_POINT { 30, 30, (Z_MIN_POS + 1)} + #define NOZZLE_CLEAN_END_POINT {100, 60, (Z_MIN_POS + 1)} + + // Circular pattern radius + #define NOZZLE_CLEAN_CIRCLE_RADIUS 6.5 + // Circular pattern circle fragments number + #define NOZZLE_CLEAN_CIRCLE_FN 10 + // Middle point of circle + #define NOZZLE_CLEAN_CIRCLE_MIDDLE NOZZLE_CLEAN_START_POINT + + // Moves the nozzle to the initial position + #define NOZZLE_CLEAN_GOBACK +#endif + +/** + * Print Job Timer + * + * Automatically start and stop the print job timer on M104/M109/M190. + * + * M104 (hotend, no wait) - high temp = none, low temp = stop timer + * M109 (hotend, wait) - high temp = start timer, low temp = stop timer + * M190 (bed, wait) - high temp = start timer, low temp = none + * + * The timer can also be controlled with the following commands: + * + * M75 - Start the print job timer + * M76 - Pause the print job timer + * M77 - Stop the print job timer + */ +#define PRINTJOB_TIMER_AUTOSTART + +/** + * Print Counter + * + * Track statistical data such as: + * + * - Total print jobs + * - Total successful print jobs + * - Total failed print jobs + * - Total time printing + * + * View the current statistics with M78. + */ +//#define PRINTCOUNTER + +//============================================================================= +//============================= LCD and SD support ============================ +//============================================================================= + +// @section lcd + +/** + * LCD LANGUAGE + * + * Select the language to display on the LCD. These languages are available: + * + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, + * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * tr, uk, zh_CN, zh_TW, test + * + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + */ +#define LCD_LANGUAGE en + +/** + * LCD Character Set + * + * Note: This option is NOT applicable to Graphical Displays. + * + * All character-based LCDs provide ASCII plus one of these + * language extensions: + * + * - JAPANESE ... the most common + * - WESTERN ... with more accented characters + * - CYRILLIC ... for the Russian language + * + * To determine the language extension installed on your controller: + * + * - Compile and upload with LCD_LANGUAGE set to 'test' + * - 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 + * + * :['JAPANESE', 'WESTERN', 'CYRILLIC'] + */ +#define DISPLAY_CHARSET_HD44780 JAPANESE + +/** + * LCD TYPE + * + * Enable ULTRA_LCD for a 16x2, 16x4, 20x2, or 20x4 character-based LCD. + * Enable DOGLCD for a 128x64 (ST7565R) Full Graphical Display. + * (These options will be enabled automatically for most displays.) + * + * IMPORTANT: The U8glib library is required for Full Graphic Display! + * https://github.com/olikraus/U8glib_Arduino + */ +//#define ULTRA_LCD // Character based +//#define DOGLCD // Full graphics display + +/** + * SD CARD + * + * 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 + +/** + * SD CARD: SPI SPEED + * + * Enable one of the following items for a slower SPI transfer speed. + * This may be required to resolve "volume init" errors. + */ +//#define SPI_SPEED SPI_HALF_SPEED +//#define SPI_SPEED SPI_QUARTER_SPEED +//#define SPI_SPEED SPI_EIGHTH_SPEED + +/** + * SD CARD: ENABLE CRC + * + * Use CRC checks and retries on the SD communication. + */ +//#define SD_CHECK_AND_RETRY + +// +// ENCODER SETTINGS +// +// This option overrides the default number of encoder pulses needed to +// produce one step. Should be increased for high-resolution encoders. +// +//#define ENCODER_PULSES_PER_STEP 1 + +// +// Use this option to override the number of step signals required to +// move between next/prev menu items. +// +//#define ENCODER_STEPS_PER_MENU_ITEM 5 + +/** + * Encoder Direction Options + * + * Test your encoder's behavior first with both options disabled. + * + * Reversed Value Edit and Menu Nav? Enable REVERSE_ENCODER_DIRECTION. + * Reversed Menu Navigation only? Enable REVERSE_MENU_DIRECTION. + * Reversed Value Editing only? Enable BOTH options. + */ + +// +// This option reverses the encoder direction everywhere. +// +// Set this option if CLOCKWISE causes values to DECREASE +// +//#define REVERSE_ENCODER_DIRECTION + +// +// This option reverses the encoder direction for navigating LCD menus. +// +// If CLOCKWISE normally moves DOWN this makes it go UP. +// If CLOCKWISE normally moves UP this makes it go DOWN. +// +//#define REVERSE_MENU_DIRECTION + +// +// Individual Axis Homing +// +// Add individual axis homing items (Home X, Home Y, and Home Z) to the LCD menu. +// +//#define INDIVIDUAL_AXIS_HOMING_MENU + +// +// SPEAKER/BUZZER +// +// If you have a speaker that can produce tones, enable it here. +// By default Marlin assumes you have a buzzer with a fixed frequency. +// +//#define SPEAKER + +// +// The duration and frequency for the UI feedback sound. +// Set these to 0 to disable audio feedback in the LCD menus. +// +// Note: Test audio output with the G-Code: +// M300 S P +// +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 +//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 + +// +// CONTROLLER TYPE: Standard +// +// Marlin supports a wide variety of controllers. +// Enable one of the following options to specify your controller. +// + +// +// ULTIMAKER Controller. +// +//#define ULTIMAKERCONTROLLER + +// +// ULTIPANEL as seen on Thingiverse. +// +//#define ULTIPANEL + +// +// PanelOne from T3P3 (via RAMPS 1.4 AUX2/AUX3) +// http://reprap.org/wiki/PanelOne +// +//#define PANEL_ONE + +// +// MaKr3d Makr-Panel with graphic controller and SD support. +// http://reprap.org/wiki/MaKr3d_MaKrPanel +// +//#define MAKRPANEL + +// +// ReprapWorld Graphical LCD +// https://reprapworld.com/?products_details&products_id/1218 +// +//#define REPRAPWORLD_GRAPHICAL_LCD + +// +// Activate one of these if you have a Panucatt Devices +// Viki 2.0 or mini Viki with Graphic LCD +// http://panucatt.com +// +//#define VIKI2 +//#define miniVIKI + +// +// Adafruit ST7565 Full Graphic Controller. +// https://github.com/eboston/Adafruit-ST7565-Full-Graphic-Controller/ +// +//#define ELB_FULL_GRAPHIC_CONTROLLER + +// +// RepRapDiscount Smart Controller. +// http://reprap.org/wiki/RepRapDiscount_Smart_Controller +// +// Note: Usually sold with a white PCB. +// +//#define REPRAP_DISCOUNT_SMART_CONTROLLER + +// +// GADGETS3D G3D LCD/SD Controller +// http://reprap.org/wiki/RAMPS_1.3/1.4_GADGETS3D_Shield_with_Panel +// +// Note: Usually sold with a blue PCB. +// +//#define G3D_PANEL + +// +// RepRapDiscount FULL GRAPHIC Smart Controller +// http://reprap.org/wiki/RepRapDiscount_Full_Graphic_Smart_Controller +// +// Note: Details on connecting to the Anet V1.0 controller are in the file pins_ANET_10.h +// +//#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER + +// +// MakerLab Mini Panel with graphic +// controller and SD support - http://reprap.org/wiki/Mini_panel +// +//#define MINIPANEL + +// +// RepRapWorld REPRAPWORLD_KEYPAD v1.1 +// http://reprapworld.com/?products_details&products_id=202&cPath=1591_1626 +// +// REPRAPWORLD_KEYPAD_MOVE_STEP sets how much should the robot move when a key +// is pressed, a value of 10.0 means 10mm per click. +// +//#define REPRAPWORLD_KEYPAD +//#define REPRAPWORLD_KEYPAD_MOVE_STEP 1.0 + +// +// RigidBot Panel V1.0 +// http://www.inventapart.com/ +// +//#define RIGIDBOT_PANEL + +// +// BQ LCD Smart Controller shipped by +// default with the BQ Hephestos 2 and Witbox 2. +// +//#define BQ_LCD_SMART_CONTROLLER + +// +// Cartesio UI +// http://mauk.cc/webshop/cartesio-shop/electronics/user-interface +// +//#define CARTESIO_UI + +// +// ANET_10 Controller supported displays. +// +#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. + // This LCD is known to be susceptible to electrical interference + // which scrambles the display. Pressing any button clears it up. +//#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 + // A clone of the RepRapDiscount full graphics display but with + // different pins/wiring (see pins_ANET_10.h). + +// +// LCD for Melzi Card with Graphical LCD +// +//#define LCD_FOR_MELZI + +// +// CONTROLLER TYPE: I2C +// +// Note: These controllers require the installation of Arduino's LiquidCrystal_I2C +// library. For more info: https://github.com/kiyoshigawa/LiquidCrystal_I2C +// + +// +// Elefu RA Board Control Panel +// http://www.elefu.com/index.php?route=product/product&product_id=53 +// +//#define RA_CONTROL_PANEL + +// +// Sainsmart YW Robot (LCM1602) LCD Display +// +// Note: This controller requires F.Malpartida's LiquidCrystal_I2C library +// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home +// +//#define LCD_I2C_SAINSMART_YWROBOT + +// +// Generic LCM1602 LCD adapter +// +//#define LCM1602 + +// +// PANELOLU2 LCD with status LEDs, +// separate encoder and click inputs. +// +// Note: This controller requires Arduino's LiquidTWI2 library v1.2.3 or later. +// For more info: https://github.com/lincomatic/LiquidTWI2 +// +// Note: The PANELOLU2 encoder click input can either be directly connected to +// a pin (if BTN_ENC defined to != -1) or read through I2C (when BTN_ENC == -1). +// +//#define LCD_I2C_PANELOLU2 + +// +// Panucatt VIKI LCD with status LEDs, +// integrated click & L/R/U/D buttons, separate encoder inputs. +// +//#define LCD_I2C_VIKI + +// +// SSD1306 OLED full graphics generic display +// +//#define U8GLIB_SSD1306 + +// +// SAV OLEd LCD module support using either SSD1306 or SH1106 based LCD modules +// +//#define SAV_3DGLCD +#if ENABLED(SAV_3DGLCD) + //#define U8GLIB_SSD1306 + #define U8GLIB_SH1106 +#endif + +// +// CONTROLLER TYPE: Shift register panels +// +// 2 wire Non-latching LCD SR from https://goo.gl/aJJ4sH +// LCD configuration: http://reprap.org/wiki/SAV_3D_LCD +// +//#define SAV_3DLCD + +// +// TinyBoy2 128x64 OLED / Encoder Panel +// +//#define OLED_PANEL_TINYBOY2 + +// +// Makeboard 3D Printer Parts 3D Printer Mini Display 1602 Mini Controller +// https://www.aliexpress.com/item/Micromake-Makeboard-3D-Printer-Parts-3D-Printer-Mini-Display-1602-Mini-Controller-Compatible-with-Ramps-1/32765887917.html +// +//#define MAKEBOARD_MINI_2_LINE_DISPLAY_1602 + +// +// MKS MINI12864 with graphic controller and SD support +// http://reprap.org/wiki/MKS_MINI_12864 +// +//#define MKS_MINI_12864 + +// +// Factory display for Creality CR-10 +// https://www.aliexpress.com/item/Universal-LCD-12864-3D-Printer-Display-Screen-With-Encoder-For-CR-10-CR-7-Model/32833148327.html +// +// This is RAMPS-compatible using a single 10-pin connector. +// (For CR-10 owners who want to replace the Melzi Creality board but retain the display) +// +//#define CR10_STOCKDISPLAY + +// +// MKS OLED 1.3" 128 × 64 FULL GRAPHICS CONTROLLER +// http://reprap.org/wiki/MKS_12864OLED +// +// Tiny, but very sharp OLED display +// +//#define MKS_12864OLED + +//============================================================================= +//=============================== Extra Features ============================== +//============================================================================= + +// @section extras + +// Increase the FAN PWM frequency. Removes the PWM noise but increases heating in the FET/Arduino +//#define FAST_PWM_FAN + +// Use software PWM to drive the fan, as for the heaters. This uses a very low frequency +// which is not as annoying as with the hardware PWM. On the other hand, if this frequency +// is too low, you should also increment SOFT_PWM_SCALE. +//#define FAN_SOFT_PWM + +// Incrementing this by 1 will double the software PWM frequency, +// affecting heaters, and the fan if FAN_SOFT_PWM is enabled. +// However, control resolution will be halved for each increment; +// at zero value, there are 128 effective control positions. +#define SOFT_PWM_SCALE 0 + +// If SOFT_PWM_SCALE is set to a value higher than 0, dithering can +// be used to mitigate the associated resolution loss. If enabled, +// some of the PWM cycles are stretched so on average the desired +// duty cycle is attained. +//#define SOFT_PWM_DITHER + +// Temperature status LEDs that display the hotend and bed temperature. +// If all hotends, bed temperature, and target temperature are under 54C +// then the BLUE led is on. Otherwise the RED led is on. (1C hysteresis) +//#define TEMP_STAT_LEDS + +// M240 Triggers a camera by emulating a Canon RC-1 Remote +// Data from: http://www.doc-diy.net/photo/rc-1_hacked/ +//#define PHOTOGRAPH_PIN 23 + +// 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 + +// Support for BlinkM/CyzRgb +//#define BLINKM + +// Support for PCA9632 PWM LED driver +//#define PCA9632 + +/** + * RGB LED / LED Strip Control + * + * Enable support for an RGB LED connected to 5V digital pins, or + * an RGB Strip connected to MOSFETs controlled by digital pins. + * + * 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 overall brightness parameters is also available + * + * *** CAUTION *** + * LED Strips require a MOFSET 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! + * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino + * cannot handle such current, separate 5V power supply must be used + * *** CAUTION *** + * + * LED type. This options are mutualy exclusive. Uncomment only one. + * + */ +//#define RGB_LED +//#define RGBW_LED + +#if ENABLED(RGB_LED) || ENABLED(RGBW_LED) + #define RGB_LED_R_PIN 34 + #define RGB_LED_G_PIN 43 + #define RGB_LED_B_PIN 35 + #define RGB_LED_W_PIN -1 +#endif + +// 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 (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) + #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip + #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time + #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + //#define NEOPIXEL_STARTUP_TEST // Cycle through colors at startup +#endif + +/** + * Printer Event LEDs + * + * During printing, the LEDs will reflect the printer status: + * + * - Gradually change from blue to violet as the heated bed gets to target temp + * - Gradually change from violet to red as the hotend gets to temperature + * - Change to white to illuminate work surface + * - Change to green once print has finished + * - Turn off after the print has finished and the user has pushed a button + */ +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) + #define PRINTER_EVENT_LEDS +#endif + +/*********************************************************************\ +* R/C SERVO support +* Sponsored by TrinityLabs, Reworked by codexmas +**********************************************************************/ + +// Number of servos +// +// If you select a configuration below, this will receive a default value and does not need to be set manually +// set it manually if you have more servos than extruders and wish to manually control some +// leaving it undefined or defining as 0 will disable the servo subsystem +// If unsure, leave commented / disabled +// +//#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command + +// Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. +// 300ms is a good value but you can try less delay. +// If the servo can't reach the requested position, increase it. +#define SERVO_DELAY { 300 } + +// Servo deactivation +// +// With this option servos are powered only during movement, then turned off to prevent jitter. +//#define DEACTIVATE_SERVOS_AFTER_MOVE + +/** + * Filament Width Sensor + * + * Measures the filament width in real-time and adjusts + * flow rate to compensate for any irregularities. + * + * Also allows the measured filament diameter to set the + * extrusion rate, so the slicer only has to specify the + * volume. + * + * Only a single extruder is supported at this time. + * + * 34 RAMPS_14 : Analog input 5 on the AUX2 connector + * 81 PRINTRBOARD : Analog input 2 on the Exp1 connector (version B,C,D,E) + * 301 RAMBO : Analog input 3 + * + * Note: May require analog pins to be defined for other boards. + */ +//#define FILAMENT_WIDTH_SENSOR + +#define DEFAULT_NOMINAL_FILAMENT_DIA 3.00 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. + +#if ENABLED(FILAMENT_WIDTH_SENSOR) + #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) + #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber + + #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading + #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading + #define MAX_MEASUREMENT_DELAY 20 // (bytes) Buffer size for stored measurements (1 byte per cm). Must be larger than MEASUREMENT_DELAY_CM. + + #define DEFAULT_MEASURED_FILAMENT_DIA DEFAULT_NOMINAL_FILAMENT_DIA // Set measured to nominal initially + + // Display filament width on the LCD status line. Status messages will expire after 5 seconds. + //#define FILAMENT_LCD_DISPLAY +#endif + +#endif // CONFIGURATION_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/Anet/A8/Configuration_adv.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/Anet/A8/Configuration_adv.h new file mode 100644 index 00000000..039e0b59 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/Anet/A8/Configuration_adv.h @@ -0,0 +1,1424 @@ +/** + * 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 . + * + */ + +/** + * Configuration_adv.h + * + * Advanced settings. + * Only change these if you know exactly what you're doing. + * Some of these settings can damage your printer if improperly set! + * + * Basic settings can be found in Configuration.h + * + */ +#ifndef CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H_VERSION 010100 + +// @section temperature + +//=========================================================================== +//=============================Thermal Settings ============================ +//=========================================================================== + +#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 + #endif +#endif + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * The solution: Once the temperature reaches the target, start observing. + * If the temperature stays too far below the target (hysteresis) for too long (period), + * the firmware will halt the machine as a safety precaution. + * + * If you get false positives for "Thermal Runaway" increase THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD + */ +#if ENABLED(THERMAL_PROTECTION_HOTENDS) + #define THERMAL_PROTECTION_PERIOD 60 // Seconds + #define THERMAL_PROTECTION_HYSTERESIS 10 // Degrees Celsius + + /** + * Whenever an M104 or M109 increases the target temperature the firmware will wait for the + * WATCH_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get false positives for "Heating failed" increase WATCH_TEMP_PERIOD and/or decrease WATCH_TEMP_INCREASE + * WATCH_TEMP_INCREASE should not be below 2. + */ + #define WATCH_TEMP_PERIOD 20 // Seconds + #define WATCH_TEMP_INCREASE 2 // Degrees Celsius +#endif + +/** + * Thermal Protection parameters for the bed are just as above for hotends. + */ +#if ENABLED(THERMAL_PROTECTION_BED) + #define THERMAL_PROTECTION_BED_PERIOD 60 // Seconds + #define THERMAL_PROTECTION_BED_HYSTERESIS 5 // Degrees Celsius + + /** + * Whenever an M140 or M190 increases the target temperature the firmware will wait for the + * WATCH_BED_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_BED_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get too many "Heating failed" errors, increase WATCH_BED_TEMP_PERIOD and/or decrease + * WATCH_BED_TEMP_INCREASE. (WATCH_BED_TEMP_INCREASE should not be below 2.) + */ + #define WATCH_BED_TEMP_PERIOD 180 // Seconds + #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius +#endif + +#if ENABLED(PIDTEMP) + // this adds an experimental additional term to the heating power, proportional to the extrusion speed. + // if Kc is chosen well, the additional required power due to increased melting should be compensated. + //#define PID_EXTRUSION_SCALING + #if ENABLED(PID_EXTRUSION_SCALING) + #define DEFAULT_Kc (100) //heating power=Kc*(e_speed) + #define LPQ_MAX_LEN 50 + #endif +#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 + */ +//#define AUTOTEMP +#if ENABLED(AUTOTEMP) + #define AUTOTEMP_OLDWEIGHT 0.98 +#endif + +// Show Temperature ADC value +// Enable for M105 to include ADC values read from temperature sensors. +//#define SHOW_TEMP_ADC_VALUES + +/** + * High Temperature Thermistor Support + * + * Thermistors able to support high temperature tend to have a hard time getting + * good readings at room and lower temperatures. This means HEATER_X_RAW_LO_TEMP + * will probably be caught when the heating element first turns on during the + * preheating process, which will trigger a min_temp_error as a safety measure + * and force stop everything. + * To circumvent this limitation, we allow for a preheat time (during which, + * min_temp_error won't be triggered) and add a min_temp buffer to handle + * aberrant readings. + * + * If you want to enable this feature for your hotend thermistor(s) + * uncomment and set values > 0 in the constants below + */ + +// The number of consecutive low temperature errors that can occur +// before a min_temp_error is triggered. (Shouldn't be more than 10.) +//#define MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED 0 + +// The number of milliseconds a hotend will preheat before starting to check +// the temperature. This value should NOT be set to the time it takes the +// hot end to reach the target temperature, but the time it takes to reach +// the minimum temperature your thermistor can read. The lower the better/safer. +// This shouldn't need to be more than 30 seconds (30000) +//#define MILLISECONDS_PREHEAT_TIME 0 + +// @section extruder + +// Extruder runout prevention. +// If the machine is idle and the temperature over MINTEMP +// then extrude some filament every couple of SECONDS. +//#define EXTRUDER_RUNOUT_PREVENT +#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_EXTRUDE 5 // mm +#endif + +// @section temperature + +//These defines help to calibrate the AD595 sensor in case you get wrong temperature measurements. +//The measured temperature is defined as "actualTemp = (measuredTemp * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET" +#define TEMP_SENSOR_AD595_OFFSET 0.0 +#define TEMP_SENSOR_AD595_GAIN 1.0 + +/** + * 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. + */ +//#define USE_CONTROLLER_FAN +#if ENABLED(USE_CONTROLLER_FAN) + //#define CONTROLLER_FAN_PIN FAN1_PIN // 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 +#endif + +// When first starting the main fan, run it at full speed for the +// given number of milliseconds. This gets the fan spinning reliably +// before setting a PWM value. (Does not work with software PWM for fan on Sanguinololu) +//#define FAN_KICKSTART_TIME 100 + +// This defines the minimal speed for the main fan, run in PWM mode +// to enable uncomment and set minimal PWM speed for reliable running (1-255) +// if fan speed is [1 - (FAN_MIN_PWM-1)] it is set to FAN_MIN_PWM +//#define FAN_MIN_PWM 50 + +// @section extruder + +/** + * Extruder cooling fans + * + * Extruder auto fans automatically turn on when their extruders' + * temperatures go above EXTRUDER_AUTO_FAN_TEMPERATURE. + * + * Your board's pins file specifies the recommended pins. Override those here + * or set to -1 to disable completely. + * + * Multiple extruders can be assigned to the same pin in which case + * the fan will turn on when any selected extruder is above the threshold. + */ +#define E0_AUTO_FAN_PIN -1 +#define E1_AUTO_FAN_PIN -1 +#define E2_AUTO_FAN_PIN -1 +#define E3_AUTO_FAN_PIN -1 +#define E4_AUTO_FAN_PIN -1 +#define EXTRUDER_AUTO_FAN_TEMPERATURE 50 +#define EXTRUDER_AUTO_FAN_SPEED 255 // == full speed + +/** + * Part-Cooling Fan Multiplexer + * + * This feature allows you to digitally multiplex the fan output. + * The multiplexer is automatically switched at tool-change. + * Set FANMUX[012]_PINs below for up to 2, 4, or 8 multiplexed fans. + */ +#define FANMUX0_PIN -1 +#define FANMUX1_PIN -1 +#define FANMUX2_PIN -1 + +/** + * M355 Case Light on-off / brightness + */ +//#define CASE_LIGHT_ENABLE +#if ENABLED(CASE_LIGHT_ENABLE) + //#define CASE_LIGHT_PIN 4 // Override the default pin if needed + #define INVERT_CASE_LIGHT false // Set true if Case Light is ON when pin is LOW + #define CASE_LIGHT_DEFAULT_ON true // Set default power-up state on + #define CASE_LIGHT_DEFAULT_BRIGHTNESS 105 // Set default power-up brightness (0-255, requires PWM pin) + //#define MENU_ITEM_CASE_LIGHT // Add a Case Light option to the LCD main menu +#endif + +//=========================================================================== +//============================ Mechanical Settings ========================== +//=========================================================================== + +// @section homing + +// If you want endstops to stay on (by default) even when not homing +// enable this option. Override at any time with M120, M121. +#define ENDSTOPS_ALWAYS_ON_DEFAULT + +// @section extras + +//#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. + +// Dual X Steppers +// Uncomment this option to drive two X axis motors. +// The next unused E driver will be assigned to the second X stepper. +//#define X_DUAL_STEPPER_DRIVERS +#if ENABLED(X_DUAL_STEPPER_DRIVERS) + // Set true if the two X motors need to rotate in opposite directions + #define INVERT_X2_VS_X_DIR true +#endif + +// Dual Y Steppers +// Uncomment this option to drive two Y axis motors. +// The next unused E driver will be assigned to the second Y stepper. +//#define Y_DUAL_STEPPER_DRIVERS +#if ENABLED(Y_DUAL_STEPPER_DRIVERS) + // Set true if the two Y motors need to rotate in opposite directions + #define INVERT_Y2_VS_Y_DIR true +#endif + +// A single Z stepper driver is usually used to drive 2 stepper motors. +// Uncomment this option to use a separate stepper driver for each Z axis motor. +// The next unused E driver will be assigned to the second Z stepper. +//#define Z_DUAL_STEPPER_DRIVERS + +#if ENABLED(Z_DUAL_STEPPER_DRIVERS) + + // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper. + // That way the machine is capable to align the bed during home, since both Z steppers are homed. + // There is also an implementation of M666 (software endstops adjustment) to this feature. + // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed. + // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2. + // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive. + // Play a little bit with small adjustments (0.5mm) and check the behaviour. + // The M119 (endstops report) will start reporting the Z2 Endstop as well. + + //#define Z_DUAL_ENDSTOPS + + #if ENABLED(Z_DUAL_ENDSTOPS) + #define Z2_USE_ENDSTOP _XMAX_ + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 // Use M666 to determine/test this value + #endif + +#endif // Z_DUAL_STEPPER_DRIVERS + +// Enable this for dual x-carriage printers. +// A dual x-carriage design has the advantage that the inactive extruder can be parked which +// prevents hot-end ooze contaminating the print. It also reduces the weight of each x-carriage +// allowing faster printing speeds. Connect your X2 stepper to the first unused E plug. +//#define DUAL_X_CARRIAGE +#if ENABLED(DUAL_X_CARRIAGE) + // Configuration for second X-carriage + // Note: the first x-carriage is defined as the x-carriage which homes to the minimum endstop; + // the second x-carriage always homes to the maximum endstop. + #define X2_MIN_POS 80 // set minimum to ensure second x-carriage doesn't hit the parked first X-carriage + #define X2_MAX_POS 353 // set maximum to the distance between toolheads when both heads are homed + #define X2_HOME_DIR 1 // the second X-carriage always homes to the maximum endstop position + #define X2_HOME_POS X2_MAX_POS // default home position is the maximum carriage position + // However: In this mode the HOTEND_OFFSET_X value for the second extruder provides a software + // override for X2_HOME_POS. This also allow recalibration of the distance between the two endstops + // without modifying the firmware (through the "M218 T1 X???" command). + // Remember: you should set the second extruder x-offset to 0 in your slicer. + + // There are a few selectable movement modes for dual x-carriages using M605 S + // Mode 0 (DXC_FULL_CONTROL_MODE): Full control. The slicer has full control over both x-carriages and can achieve optimal travel results + // as long as it supports dual x-carriages. (M605 S0) + // Mode 1 (DXC_AUTO_PARK_MODE) : Auto-park mode. The firmware will automatically park and unpark the x-carriages on tool changes so + // that additional slicer support is not required. (M605 S1) + // Mode 2 (DXC_DUPLICATION_MODE) : Duplication mode. The firmware will transparently make the second x-carriage and extruder copy all + // actions of the first x-carriage. This allows the printer to print 2 arbitrary items at + // once. (2nd extruder x offset and temp offset are set using: M605 S2 [Xnnn] [Rmmm]) + + // This is the default power-up mode which can be later using M605. + #define DEFAULT_DUAL_X_CARRIAGE_MODE DXC_FULL_CONTROL_MODE + + // Default settings in "Auto-park Mode" + #define TOOLCHANGE_PARK_ZLIFT 0.2 // the distance to raise Z axis when parking an extruder + #define TOOLCHANGE_UNPARK_ZLIFT 1 // the distance to raise Z axis when unparking an extruder + + // Default x offset in duplication mode (typically set to half print bed width) + #define DEFAULT_DUPLICATION_X_OFFSET 100 + +#endif // DUAL_X_CARRIAGE + +// 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. +//#define EXT_SOLENOID + +// @section homing + +//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +#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 this is defined, if both x and y are to be homed, a diagonal move will be performed initially. + +// When G28 is called, this option will make Y home before X +//#define HOME_Y_BEFORE_X + +// @section machine + +#define AXIS_RELATIVE_MODES {false, false, false, false} + +// Allow duplication mode with a basic dual-nozzle extruder +//#define DUAL_NOZZLE_DUPLICATION_MODE + +// By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step. +#define INVERT_X_STEP_PIN false +#define INVERT_Y_STEP_PIN false +#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. +#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_E true + +#define DEFAULT_MINIMUMFEEDRATE 0.0 // minimum feedrate +#define DEFAULT_MINTRAVELFEEDRATE 0.0 + +//#define HOME_AFTER_DEACTIVATE // Require rehoming after steppers are deactivated + +// @section lcd + +#if ENABLED(ULTIPANEL) + #define MANUAL_FEEDRATE {50*60, 50*60, 4*60, 60} // Feedrates for manual moves along X, Y, Z, E from panel + #define ULTIPANEL_FEEDMULTIPLY // Comment to disable setting feedrate multiplier via encoder +#endif + +// @section extras + +// minimum time in microseconds that a movement needs to take if the buffer is emptied. +#define DEFAULT_MINSEGMENTTIME 20000 + +// If defined the movements slow down when the look ahead buffer is only half full +#define SLOWDOWN + +// Frequency limit +// See nophead's blog for more info +// Not working O +//#define XY_FREQUENCY_LIMIT 15 + +// 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 +// if unwanted behavior is observed on a user's machine when running at very slow speeds. +#define MINIMUM_PLANNER_SPEED 0.05 // (mm/sec) + +// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU. +#define MICROSTEP_MODES {16,16,16,16,16} // [1,2,4,8,16] + +/** + * @section stepper motor current + * + * Some boards have a means of setting the stepper motor current via firmware. + * + * The power on motor currents are set by: + * PWM_MOTOR_CURRENT - used by MINIRAMBO & ULTIMAIN_2 + * known compatible chips: A4982 + * DIGIPOT_MOTOR_CURRENT - used by BQ_ZUM_MEGA_3D, RAMBO & SCOOVO_X9H + * known compatible chips: AD5206 + * DAC_MOTOR_CURRENT_DEFAULT - used by PRINTRBOARD_REVF & RIGIDBOARD_V2 + * known compatible chips: MCP4728 + * DIGIPOT_I2C_MOTOR_CURRENTS - used by 5DPRINT, AZTEEG_X3_PRO, MIGHTYBOARD_REVE + * known compatible chips: MCP4451, MCP4018 + * + * Motor currents can also be set by M907 - M910 and by the LCD. + * M907 - applies to all. + * M908 - BQ_ZUM_MEGA_3D, RAMBO, PRINTRBOARD_REVF, RIGIDBOARD_V2 & SCOOVO_X9H + * M909, M910 & LCD - only PRINTRBOARD_REVF & RIGIDBOARD_V2 + */ +//#define PWM_MOTOR_CURRENT { 1300, 1300, 1250 } // Values in milliamps +//#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 + +// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +//#define DIGIPOT_I2C +//#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster +#define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 +// Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS +#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=========================== +//=========================================================================== + +#define ENCODER_RATE_MULTIPLIER // If defined, certain menu edit operations automatically multiply the steps when the encoder is moved quickly +#define ENCODER_10X_STEPS_PER_SEC 75 // If the encoder steps per sec exceeds this value, multiply steps moved x10 to quickly advance the value +#define ENCODER_100X_STEPS_PER_SEC 160 // If the encoder steps per sec exceeds this value, multiply steps moved x100 to really quickly advance the value + +//#define CHDK 4 //Pin for triggering CHDK to take a picture see how to use it here http://captain-slow.dk/2014/03/09/3d-printing-timelapses/ +#define CHDK_DELAY 50 //How long in ms the pin should stay HIGH before going LOW again + +// @section lcd + +// Include a page of printer information in the LCD Main Menu +//#define LCD_INFO_MENU + +// Scroll a longer status message into view +//#define STATUS_MESSAGE_SCROLLING + +// On the Info Screen, display XY with one decimal place when possible +//#define LCD_DECIMAL_SMALL_XY + +// The timeout (in ms) to return to the status screen from sub-menus +//#define LCD_TIMEOUT_TO_STATUS 15000 + +#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 + + #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? + #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. + + #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. + // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. + // using: + //#define MENU_ADDAUTOSTART + + /** + * Sort SD file listings in alphabetical order. + * + * With this option enabled, items on SD cards will be sorted + * by name for easier navigation. + * + * By default... + * + * - Use the slowest -but safest- method for sorting. + * - Folders are sorted to the top. + * - The sort key is statically allocated. + * - No added G-code (M34) support. + * - 40 item sorting limit. (Items after the first 40 are unsorted.) + * + * SD sorting uses static allocation (as set by SDSORT_LIMIT), allowing the + * compiler to calculate the worst-case usage and throw an error if the SRAM + * limit is exceeded. + * + * - SDSORT_USES_RAM provides faster sorting via a static directory buffer. + * - SDSORT_USES_STACK does the same, but uses a local stack-based buffer. + * - SDSORT_CACHE_NAMES will retain the sorted file listing in RAM. (Expensive!) + * - SDSORT_DYNAMIC_RAM only uses RAM when the SD menu is visible. (Use with caution!) + */ + //#define SDCARD_SORT_ALPHA + + // SD Card Sorting options + #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_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. + #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #endif + + // Show a progress bar on HD44780 LCDs for SD printing + //#define LCD_PROGRESS_BAR + + #if ENABLED(LCD_PROGRESS_BAR) + // Amount of time (ms) to show the bar + #define PROGRESS_BAR_BAR_TIME 2000 + // Amount of time (ms) to show the status message + #define PROGRESS_BAR_MSG_TIME 3000 + // Amount of time (ms) to retain the status message (0=forever) + #define PROGRESS_MSG_EXPIRE 0 + // Enable this to show messages for MSG_TIME then hide them + //#define PROGRESS_MSG_ONCE + // Add a menu item to test the progress bar: + //#define LCD_PROGRESS_BAR_TEST + #endif + + // This allows hosts to request long names for files and folders with M33 + //#define LONG_FILENAME_HOST_SUPPORT + + // This option allows you to abort SD printing when any endstop is triggered. + // This feature must be enabled with "M540 S1" or from the LCD menu. + // To have any effect, endstops must be enabled during SD printing. + //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + +#endif // SDSUPPORT + +/** + * Additional options for Graphical Displays + * + * Use the optimizations here to improve printing performance, + * which can be adversely affected by graphical display drawing, + * especially when doing several short moves, and when printing + * on DELTA and SCARA machines. + * + * Some of these options may result in the display lagging behind + * controller events, as there is a trade-off between reliable + * printing performance versus fast display updates. + */ +#if ENABLED(DOGLCD) + // Enable to save many cycles by drawing a hollow frame on the Info Screen + #define XYZ_HOLLOW_FRAME + + // Enable to save many cycles by drawing a hollow frame on Menu Screens + #define MENU_HOLLOW_FRAME + + // A bigger font is available for edit items. Costs 3120 bytes of PROGMEM. + // 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. + // 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 +#endif // DOGLCD + +// @section safety + +// The hardware watchdog should reset the microcontroller disabling all outputs, +// in case the firmware gets stuck and doesn't do temperature regulation. +#define USE_WATCHDOG + +#if ENABLED(USE_WATCHDOG) + // If you have a watchdog reboot in an ArduinoMega2560 then the device will hang forever, as a watchdog reset will leave the watchdog on. + // The "WATCHDOG_RESET_MANUAL" goes around this by not using the hardware reset. + // However, THIS FEATURE IS UNSAFE!, as it will only work if interrupts are disabled. And the code could hang in an interrupt routine with interrupts disabled. + //#define WATCHDOG_RESET_MANUAL +#endif + +// @section lcd + +/** + * Babystepping enables movement of the axes by tiny increments without changing + * the current position values. This feature is used primarily to adjust the Z + * axis in the first layer of a print in real-time. + * + * Warning: Does not respect endstops! + */ +//#define BABYSTEPPING +#if ENABLED(BABYSTEPPING) + //#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 100 // Babysteps are very small. Increase for faster motion. + //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping + //#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen 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_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor + //#define BABYSTEP_ZPROBE_GFX_REVERSE // Reverses the direction of the CW/CCW indicators +#endif + +// @section extruder + +/** + * Implementation of linear pressure control + * + * Assumption: advance = k * (delta velocity) + * K=0 means advance disabled. + * See Marlin documentation for calibration instructions. + */ +//#define LIN_ADVANCE + +#if ENABLED(LIN_ADVANCE) + #define LIN_ADVANCE_K 75 + + /** + * Some Slicers produce Gcode with randomly jumping extrusion widths occasionally. + * For example within a 0.4mm perimeter it may produce a single segment of 0.05mm width. + * While this is harmless for normal printing (the fluid nature of the filament will + * close this very, very tiny gap), it throws off the LIN_ADVANCE pressure adaption. + * + * For this case LIN_ADVANCE_E_D_RATIO can be used to set the extrusion:distance ratio + * to a fixed value. Note that using a fixed ratio will lead to wrong nozzle pressures + * if the slicer is using variable widths or layer heights within one print! + * + * This option sets the default E:D ratio at startup. Use `M900` to override this value. + * + * Example: `M900 W0.4 H0.2 D1.75`, where: + * - W is the extrusion width in mm + * - H is the layer height in mm + * - D is the filament diameter in mm + * + * Example: `M900 R0.0458` to set the ratio directly. + * + * Set to 0 to auto-detect the ratio based on given Gcode G1 print moves. + * + * Slic3r (including Průša Control) produces Gcode compatible with the automatic mode. + * Cura (as of this writing) may produce Gcode incompatible with the automatic mode. + */ + #define LIN_ADVANCE_E_D_RATIO 0 // The calculated ratio (or 0) according to the formula W * H / ((D / 2) ^ 2 * PI) + // Example: 0.4 * 0.2 / ((1.75 / 2) ^ 2 * PI) = 0.033260135 +#endif + +// @section leveling + +// Default mesh area is an area with an inset margin on the print area. +// Below are the macros that are used to define the borders for the mesh area, +// made available here for specialized needs, ie dual extruder setup. +#if ENABLED(MESH_BED_LEVELING) + #define MESH_MIN_X MESH_INSET + #define MESH_MAX_X (X_BED_SIZE - (MESH_INSET)) + #define MESH_MIN_Y MESH_INSET + #define MESH_MAX_Y (Y_BED_SIZE - (MESH_INSET)) +#elif ENABLED(AUTO_BED_LEVELING_UBL) + #define UBL_MESH_MIN_X UBL_MESH_INSET + #define UBL_MESH_MAX_X (X_BED_SIZE - (UBL_MESH_INSET)) + #define UBL_MESH_MIN_Y UBL_MESH_INSET + #define UBL_MESH_MAX_Y (Y_BED_SIZE - (UBL_MESH_INSET)) + + // If this is defined, the currently active mesh will be saved in the + // current slot on M500. + #define UBL_SAVE_ACTIVE_ON_M500 +#endif + +// @section extras + +// +// G2/G3 Arc Support +// +//#define ARC_SUPPORT // Disable this feature to save ~3226 bytes +#if ENABLED(ARC_SUPPORT) + #define MM_PER_ARC_SEGMENT 1 // Length of each arc segment + #define N_ARC_CORRECTION 25 // Number of intertpolated 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 +#endif + +// Support for G5 with XYZE destination and IJPQ offsets. Requires ~2666 bytes. +//#define BEZIER_CURVE_SUPPORT + +// G38.2 and G38.3 Probe Target +// Enable PROBE_DOUBLE_TOUCH if you want G38 to double touch +//#define G38_PROBE_TARGET +#if ENABLED(G38_PROBE_TARGET) + #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) +#endif + +// Moves (or segments) with fewer steps than this will be joined with the next move +#define MIN_STEPS_PER_SEGMENT 6 + +// The minimum pulse width (in µs) for stepping a stepper. +// Set this if you find stepping unreliable, or if using a very fast CPU. +#define MINIMUM_STEPPER_PULSE 0 // (µs) The smallest stepper pulse allowed + +// @section temperature + +// Control heater 0 and heater 1 in parallel. +//#define HEATERS_PARALLEL + +//=========================================================================== +//================================= Buffers ================================= +//=========================================================================== + +// @section hidden + +// 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, i.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 +#else + #define BLOCK_BUFFER_SIZE 16 // maximize block buffer +#endif + +// @section serial + +// The ASCII buffer for serial input +#define MAX_CMD_SIZE 96 +#define BUFSIZE 4 + +// Transmission to Host Buffer Size +// To save 386 bytes of PROGMEM (and TX_BUFFER_SIZE+3 bytes of RAM) set to 0. +// To buffer a simple "ok" you need 4 bytes. +// For ADVANCED_OK (M105) you need 32 bytes. +// For debug-echo: 128 bytes for the optimal speed. +// Other output doesn't need to be that speedy. +// :[0, 2, 4, 8, 16, 32, 64, 128, 256] +#define TX_BUFFER_SIZE 0 + +// Host Receive Buffer Size +// Without XON/XOFF flow control (see SERIAL_XON_XOFF below) 32 bytes should be enough. +// To use flow control, set this buffer size to at least 1024 bytes. +// :[0, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048] +//#define RX_BUFFER_SIZE 1024 + +#if RX_BUFFER_SIZE >= 1024 + // Enable to have the controller send XON/XOFF control characters to + // the host to signal the RX buffer is becoming full. + //#define SERIAL_XON_XOFF +#endif + +#if ENABLED(SDSUPPORT) + // Enable this option to collect and display the maximum + // RX queue usage after transferring a file to SD. + //#define SERIAL_STATS_MAX_RX_QUEUED + + // Enable this option to collect and display the number + // of dropped bytes after a file transfer to SD. + //#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! +//#define EMERGENCY_PARSER + +// Bad Serial-connections can miss a received command by sending an 'ok' +// Therefore some clients abort after 30 seconds in a timeout. +// Some other clients start sending commands while receiving a 'wait'. +// This "wait" is only sent when the buffer is empty. 1 second is a good value here. +//#define NO_TIMEOUTS 1000 // Milliseconds + +// Some clients will have this feature soon. This could make the NO_TIMEOUTS unnecessary. +//#define ADVANCED_OK + +// @section extras + +/** + * Firmware-based and LCD-controlled retract + * + * Add G10 / G11 commands for automatic firmware-based retract / recover. + * Use M207 and M208 to define parameters for retract / recover. + * + * Use M209 to enable or disable auto-retract. + * With auto-retract enabled, all G1 E moves within the set range + * will be converted to firmware-based retract/recover moves. + * + * Be sure to turn off auto-retract during filament change. + * + * Note that M207 / M208 / M209 settings are saved to EEPROM. + * + */ +//#define FWRETRACT // ONLY PARTIALLY TESTED +#if ENABLED(FWRETRACT) + #define MIN_AUTORETRACT 0.1 // When auto-retract is on, convert E moves of this length and over + #define MAX_AUTORETRACT 10.0 // Upper limit for auto-retract conversion + #define RETRACT_LENGTH 3 // Default retract length (positive mm) + #define RETRACT_LENGTH_SWAP 13 // Default swap retract length (positive mm), for extruder change + #define RETRACT_FEEDRATE 45 // Default feedrate for retracting (mm/s) + #define RETRACT_ZLIFT 0 // Default retract Z-lift + #define RETRACT_RECOVER_LENGTH 0 // Default additional recover length (mm, added to retract length when recovering) + #define RETRACT_RECOVER_LENGTH_SWAP 0 // Default additional swap recover length (mm, added to retract length when recovering from extruder change) + #define RETRACT_RECOVER_FEEDRATE 8 // Default feedrate for recovering from retraction (mm/s) + #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) +#endif + +/** + * Advanced Pause + * Experimental feature for filament change support and for parking the nozzle when paused. + * Adds the GCode M600 for initiating filament change. + * If PARK_HEAD_ON_PAUSE enabled, adds the GCode M125 to pause printing and park the nozzle. + * + * Requires an LCD display. + * This feature is required for the default FILAMENT_RUNOUT_SCRIPT. + */ +//#define ADVANCED_PAUSE_FEATURE +#if ENABLED(ADVANCED_PAUSE_FEATURE) + #define PAUSE_PARK_X_POS 3 // X position of hotend + #define PAUSE_PARK_Y_POS 3 // Y position of hotend + #define PAUSE_PARK_Z_ADD 10 // Z addition of hotend (lift) + #define PAUSE_PARK_XY_FEEDRATE 100 // X and Y axes feedrate in mm/s (also used for delta printers Z axis) + #define PAUSE_PARK_Z_FEEDRATE 5 // Z axis feedrate in mm/s (not used for delta printers) + #define PAUSE_PARK_RETRACT_FEEDRATE 60 // Initial retract feedrate in mm/s + #define PAUSE_PARK_RETRACT_LENGTH 2 // Initial retract in mm + // It is a short retract used immediately after print interrupt before move to filament exchange position + #define FILAMENT_CHANGE_UNLOAD_FEEDRATE 10 // Unload filament feedrate in mm/s - filament unloading can be fast + #define FILAMENT_CHANGE_UNLOAD_LENGTH 100 // Unload filament length from hotend in mm + // Longer length for bowden printers to unload filament from whole bowden tube, + // shorter length for printers without bowden to unload filament from extruder only, + // 0 to disable unloading for manual unloading + #define FILAMENT_CHANGE_LOAD_FEEDRATE 6 // Load filament feedrate in mm/s - filament loading into the bowden tube can be fast + #define FILAMENT_CHANGE_LOAD_LENGTH 0 // Load filament length over hotend in mm + // Longer length for bowden printers to fast load filament into whole bowden tube over the hotend, + // Short or zero length for printers without bowden where loading is not used + #define ADVANCED_PAUSE_EXTRUDE_FEEDRATE 3 // Extrude filament feedrate in mm/s - must be slower than load feedrate + #define ADVANCED_PAUSE_EXTRUDE_LENGTH 50 // Extrude filament length in mm after filament is loaded over the hotend, + // 0 to disable for manual extrusion + // Filament can be extruded repeatedly from the filament exchange menu to fill the hotend, + // or until outcoming filament color is not clear for filament color change + #define PAUSE_PARK_NOZZLE_TIMEOUT 45 // Turn off nozzle if user doesn't change filament within this time limit in seconds + #define FILAMENT_CHANGE_NUMBER_OF_ALERT_BEEPS 5 // Number of alert beeps before printer goes quiet + #define PAUSE_PARK_NO_STEPPER_TIMEOUT // Enable to have stepper motors hold position during filament change + // even if it takes longer than DEFAULT_STEPPER_DEACTIVE_TIME. + //#define PARK_HEAD_ON_PAUSE // Go to filament change position on pause, return to print position on resume + //#define HOME_BEFORE_FILAMENT_CHANGE // Ensure homing has been completed prior to parking for filament change +#endif + +// @section tmc + +/** + * Enable this section if you have TMC26X motor drivers. + * You will need to import the TMC26XStepper library into the Arduino IDE for this + * (https://github.com/trinamic/TMC26XStepper.git) + */ +//#define HAVE_TMCDRIVER + +#if ENABLED(HAVE_TMCDRIVER) + + //#define X_IS_TMC + //#define X2_IS_TMC + //#define Y_IS_TMC + //#define Y2_IS_TMC + //#define Z_IS_TMC + //#define Z2_IS_TMC + //#define E0_IS_TMC + //#define E1_IS_TMC + //#define E2_IS_TMC + //#define E3_IS_TMC + //#define E4_IS_TMC + + #define X_MAX_CURRENT 1000 // in mA + #define X_SENSE_RESISTOR 91 // in mOhms + #define X_MICROSTEPS 16 // number of microsteps + + #define X2_MAX_CURRENT 1000 + #define X2_SENSE_RESISTOR 91 + #define X2_MICROSTEPS 16 + + #define Y_MAX_CURRENT 1000 + #define Y_SENSE_RESISTOR 91 + #define Y_MICROSTEPS 16 + + #define Y2_MAX_CURRENT 1000 + #define Y2_SENSE_RESISTOR 91 + #define Y2_MICROSTEPS 16 + + #define Z_MAX_CURRENT 1000 + #define Z_SENSE_RESISTOR 91 + #define Z_MICROSTEPS 16 + + #define Z2_MAX_CURRENT 1000 + #define Z2_SENSE_RESISTOR 91 + #define Z2_MICROSTEPS 16 + + #define E0_MAX_CURRENT 1000 + #define E0_SENSE_RESISTOR 91 + #define E0_MICROSTEPS 16 + + #define E1_MAX_CURRENT 1000 + #define E1_SENSE_RESISTOR 91 + #define E1_MICROSTEPS 16 + + #define E2_MAX_CURRENT 1000 + #define E2_SENSE_RESISTOR 91 + #define E2_MICROSTEPS 16 + + #define E3_MAX_CURRENT 1000 + #define E3_SENSE_RESISTOR 91 + #define E3_MICROSTEPS 16 + + #define E4_MAX_CURRENT 1000 + #define E4_SENSE_RESISTOR 91 + #define E4_MICROSTEPS 16 + +#endif + +// @section TMC2130 + +/** + * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. + * + * You'll also need the TMC2130Stepper Arduino library + * (https://github.com/teemuatlut/TMC2130Stepper). + * + * To use TMC2130 stepper drivers in SPI mode connect your SPI2130 pins to + * the hardware SPI interface on your board and define the required CS pins + * in your `pins_MYBOARD.h` file. (e.g., RAMPS 1.4 uses AUX3 pins `X_CS_PIN 53`, `Y_CS_PIN 49`, etc.). + */ +//#define HAVE_TMC2130 + +#if ENABLED(HAVE_TMC2130) + + // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY + //#define X_IS_TMC2130 + //#define X2_IS_TMC2130 + //#define Y_IS_TMC2130 + //#define Y2_IS_TMC2130 + //#define Z_IS_TMC2130 + //#define Z2_IS_TMC2130 + //#define E0_IS_TMC2130 + //#define E1_IS_TMC2130 + //#define E2_IS_TMC2130 + //#define E3_IS_TMC2130 + //#define E4_IS_TMC2130 + + /** + * Stepper driver settings + */ + + #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 + #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current + #define INTERPOLATE 1 // Interpolate X/Y/Z_MICROSTEPS to 256 + + #define X_CURRENT 1000 // rms current in mA. Multiply by 1.41 for peak current. + #define X_MICROSTEPS 16 // 0..256 + + #define Y_CURRENT 1000 + #define Y_MICROSTEPS 16 + + #define Z_CURRENT 1000 + #define Z_MICROSTEPS 16 + + //#define X2_CURRENT 1000 + //#define X2_MICROSTEPS 16 + + //#define Y2_CURRENT 1000 + //#define Y2_MICROSTEPS 16 + + //#define Z2_CURRENT 1000 + //#define Z2_MICROSTEPS 16 + + //#define E0_CURRENT 1000 + //#define E0_MICROSTEPS 16 + + //#define E1_CURRENT 1000 + //#define E1_MICROSTEPS 16 + + //#define E2_CURRENT 1000 + //#define E2_MICROSTEPS 16 + + //#define E3_CURRENT 1000 + //#define E3_MICROSTEPS 16 + + //#define E4_CURRENT 1000 + //#define E4_MICROSTEPS 16 + + /** + * Use Trinamic's ultra quiet stepping mode. + * When disabled, Marlin will use spreadCycle stepping mode. + */ + #define STEALTHCHOP + + /** + * Let Marlin automatically control stepper current. + * This is still an experimental feature. + * Increase current every 5s by CURRENT_STEP until stepper temperature prewarn gets triggered, + * then decrease current by CURRENT_STEP until temperature prewarn is cleared. + * Adjusting starts from X/Y/Z/E_CURRENT but will not increase over AUTO_ADJUST_MAX + * 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. + * M906 S1 - Start adjusting current + * M906 S0 - Stop adjusting current + * M911 - Report stepper driver overtemperature pre-warn condition. + * M912 - Clear stepper driver overtemperature pre-warn condition flag. + */ + //#define AUTOMATIC_CURRENT_CONTROL + + #if ENABLED(AUTOMATIC_CURRENT_CONTROL) + #define CURRENT_STEP 50 // [mA] + #define AUTO_ADJUST_MAX 1300 // [mA], 1300mA_rms = 1840mA_peak + #define REPORT_CURRENT_CHANGE + #endif + + /** + * The driver will switch to spreadCycle when stepper speed is over HYBRID_THRESHOLD. + * This mode allows for faster movements at the expense of higher noise levels. + * STEALTHCHOP needs to be enabled. + * M913 X/Y/Z/E to live tune the setting + */ + //#define HYBRID_THRESHOLD + + #define X_HYBRID_THRESHOLD 100 // [mm/s] + #define X2_HYBRID_THRESHOLD 100 + #define Y_HYBRID_THRESHOLD 100 + #define Y2_HYBRID_THRESHOLD 100 + #define Z_HYBRID_THRESHOLD 4 + #define Z2_HYBRID_THRESHOLD 4 + #define E0_HYBRID_THRESHOLD 30 + #define E1_HYBRID_THRESHOLD 30 + #define E2_HYBRID_THRESHOLD 30 + #define E3_HYBRID_THRESHOLD 30 + #define E4_HYBRID_THRESHOLD 30 + + /** + * Use stallGuard2 to sense an obstacle and trigger an endstop. + * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. + * If used along with STEALTHCHOP, the movement will be louder when homing. This is normal. + * + * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. + * Higher values make the system LESS sensitive. + * Lower value make the system MORE sensitive. + * Too low values can lead to false positives, while too high values will collide the axis without triggering. + * It is advised to set X/Y_HOME_BUMP_MM to 0. + * M914 X/Y to live tune the setting + */ + //#define SENSORLESS_HOMING + + #if ENABLED(SENSORLESS_HOMING) + #define X_HOMING_SENSITIVITY 19 + #define Y_HOMING_SENSITIVITY 19 + #endif + + /** + * You can set your own advanced settings by filling in predefined functions. + * A list of available functions can be found on the library github page + * https://github.com/teemuatlut/TMC2130Stepper + * + * Example: + * #define TMC2130_ADV() { \ + * stepperX.diag0_temp_prewarn(1); \ + * stepperX.interpolate(0); \ + * } + */ + #define TMC2130_ADV() { } + +#endif // HAVE_TMC2130 + +// @section L6470 + +/** + * Enable this section if you have L6470 motor drivers. + * You need to import the L6470 library into the Arduino IDE for this. + * (https://github.com/ameyer/Arduino-L6470) + */ + +//#define HAVE_L6470DRIVER +#if ENABLED(HAVE_L6470DRIVER) + + //#define X_IS_L6470 + //#define X2_IS_L6470 + //#define Y_IS_L6470 + //#define Y2_IS_L6470 + //#define Z_IS_L6470 + //#define Z2_IS_L6470 + //#define E0_IS_L6470 + //#define E1_IS_L6470 + //#define E2_IS_L6470 + //#define E3_IS_L6470 + //#define E4_IS_L6470 + + #define X_MICROSTEPS 16 // number of microsteps + #define X_K_VAL 50 // 0 - 255, Higher values, are higher power. Be careful not to go too high + #define X_OVERCURRENT 2000 // maxc current in mA. If the current goes over this value, the driver will switch off + #define X_STALLCURRENT 1500 // current in mA where the driver will detect a stall + + #define X2_MICROSTEPS 16 + #define X2_K_VAL 50 + #define X2_OVERCURRENT 2000 + #define X2_STALLCURRENT 1500 + + #define Y_MICROSTEPS 16 + #define Y_K_VAL 50 + #define Y_OVERCURRENT 2000 + #define Y_STALLCURRENT 1500 + + #define Y2_MICROSTEPS 16 + #define Y2_K_VAL 50 + #define Y2_OVERCURRENT 2000 + #define Y2_STALLCURRENT 1500 + + #define Z_MICROSTEPS 16 + #define Z_K_VAL 50 + #define Z_OVERCURRENT 2000 + #define Z_STALLCURRENT 1500 + + #define Z2_MICROSTEPS 16 + #define Z2_K_VAL 50 + #define Z2_OVERCURRENT 2000 + #define Z2_STALLCURRENT 1500 + + #define E0_MICROSTEPS 16 + #define E0_K_VAL 50 + #define E0_OVERCURRENT 2000 + #define E0_STALLCURRENT 1500 + + #define E1_MICROSTEPS 16 + #define E1_K_VAL 50 + #define E1_OVERCURRENT 2000 + #define E1_STALLCURRENT 1500 + + #define E2_MICROSTEPS 16 + #define E2_K_VAL 50 + #define E2_OVERCURRENT 2000 + #define E2_STALLCURRENT 1500 + + #define E3_MICROSTEPS 16 + #define E3_K_VAL 50 + #define E3_OVERCURRENT 2000 + #define E3_STALLCURRENT 1500 + + #define E4_MICROSTEPS 16 + #define E4_K_VAL 50 + #define E4_OVERCURRENT 2000 + #define E4_STALLCURRENT 1500 + +#endif + +/** + * TWI/I2C BUS + * + * This feature is an EXPERIMENTAL feature so it shall not be used on production + * machines. Enabling this will allow you to send and receive I2C data from slave + * devices on the bus. + * + * ; Example #1 + * ; This macro send the string "Marlin" to the slave device with address 0x63 (99) + * ; It uses multiple M260 commands with one B arg + * M260 A99 ; Target slave address + * M260 B77 ; M + * M260 B97 ; a + * M260 B114 ; r + * M260 B108 ; l + * M260 B105 ; i + * M260 B110 ; n + * M260 S1 ; Send the current buffer + * + * ; Example #2 + * ; Request 6 bytes from slave device with address 0x63 (99) + * M261 A99 B5 + * + * ; Example #3 + * ; Example serial output of a M261 request + * echo:i2c-reply: from:99 bytes:5 data:hello + */ + +// @section i2cbus + +//#define EXPERIMENTAL_I2CBUS +#define I2C_SLAVE_ADDRESS 0 // Set a value from 8 to 127 to act as a slave + +// @section extras + +/** + * Spindle & Laser control + * + * Add the M3, M4, and M5 commands to turn the spindle/laser on and off, and + * to set spindle speed, spindle direction, and laser power. + * + * SuperPid is a router/spindle speed controller used in the CNC milling community. + * Marlin can be used to turn the spindle on and off. It can also be used to set + * the spindle speed from 5,000 to 30,000 RPM. + * + * 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. + */ +//#define SPINDLE_LASER_ENABLE +#if ENABLED(SPINDLE_LASER_ENABLE) + + #define SPINDLE_LASER_ENABLE_INVERT false // set to "true" if the on/off function is reversed + #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 // delay in milliseconds to allow the spindle/laser to come up to speed/power + #define SPINDLE_LASER_POWERDOWN_DELAY 5000 // delay in milliseconds to allow the spindle to stop + #define SPINDLE_DIR_CHANGE true // set to true if your spindle controller supports changing spindle direction + #define SPINDLE_INVERT_DIR false + #define SPINDLE_STOP_ON_DIR_CHANGE true // set to true if Marlin should stop the spindle before changing rotation direction + + /** + * The M3 & M4 commands use the following equation to convert PWM duty cycle to speed/power + * + * SPEED/POWER = PWM duty cycle * SPEED_POWER_SLOPE + SPEED_POWER_INTERCEPT + * where PWM duty cycle varies from 0 to 255 + * + * set the following for your controller (ALL MUST BE SET) + */ + + #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_SLOPE 0.3922 + //#define SPEED_POWER_INTERCEPT 0 + //#define SPEED_POWER_MIN 10 + //#define SPEED_POWER_MAX 100 // 0-100% +#endif + +/** + * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins + */ +//#define PINS_DEBUGGING + +/** + * Auto-report temperatures with M155 S + */ +#define AUTO_REPORT_TEMPERATURES + +/** + * Include capabilities in M115 output + */ +#define EXTENDED_CAPABILITIES_REPORT + +/** + * Volumetric extrusion default state + * 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. + */ +//#define VOLUMETRIC_DEFAULT_ON + +/** + * Enable this option for a leaner build of Marlin that removes all + * workspace offsets, simplifying coordinate transformations, leveling, etc. + * + * - M206 and M428 are disabled. + * - G92 will revert to its behavior from Marlin 1.0. + */ +//#define NO_WORKSPACE_OFFSETS + +/** + * 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. + * + * For clients that use a fixed-width font (like OctoPrint), leave this set to 1.0. + * Otherwise, adjust according to your client and font. + */ +#define PROPORTIONAL_FONT_RATIO 1.0 + +/** + * Spend 28 bytes of SRAM to optimize the GCode parser + */ +#define FASTER_GCODE_PARSER + +/** + * User-defined menu items that execute custom GCode + */ +//#define CUSTOM_USER_MENUS +#if ENABLED(CUSTOM_USER_MENUS) + #define USER_SCRIPT_DONE "M117 User Script Done" + #define USER_SCRIPT_AUDIBLE_FEEDBACK + //#define USER_SCRIPT_RETURN // Return to status screen after a script + + #define USER_DESC_1 "Home & UBL Info" + #define USER_GCODE_1 "G28\nG29 W" + + #define USER_DESC_2 "Preheat for PLA" + #define USER_GCODE_2 "M140 S" STRINGIFY(PREHEAT_1_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND) + + #define USER_DESC_3 "Preheat for ABS" + #define USER_GCODE_3 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND) + + #define USER_DESC_4 "Heat Bed/Home/Level" + #define USER_GCODE_4 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nG28\nG29" + + #define USER_DESC_5 "Home & Info" + #define USER_GCODE_5 "G28\nM503" +#endif + +/** + * Specify an action command to send to the host when the printer is killed. + * Will be sent in the form '//action:ACTION_ON_KILL', e.g. '//action:poweroff'. + * The host must be configured to handle the action command. + */ +//#define ACTION_ON_KILL "poweroff" + +//=========================================================================== +//====================== I2C Position Encoder Settings ====================== +//=========================================================================== + +/** + * I2C position encoders for closed loop control. + * Developed by Chris Barr at Aus3D. + * + * Wiki: http://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/ + * + * Reilabuild encoders have been modified to improve reliability. + */ + +//#define I2C_POSITION_ENCODERS +#if ENABLED(I2C_POSITION_ENCODERS) + + #define I2CPE_ENCODER_CNT 1 // The number of encoders installed; max of 5 + // encoders supported currently. + + #define I2CPE_ENC_1_ADDR I2CPE_PRESET_ADDR_X // I2C address of the encoder. 30-200. + #define I2CPE_ENC_1_AXIS X_AXIS // Axis the encoder module is installed on. _AXIS. + #define I2CPE_ENC_1_TYPE I2CPE_ENC_TYPE_LINEAR // Type of encoder: I2CPE_ENC_TYPE_LINEAR -or- + // I2CPE_ENC_TYPE_ROTARY. + #define I2CPE_ENC_1_TICKS_UNIT 2048 // 1024 for magnetic strips with 2mm poles; 2048 for + // 1mm poles. For linear encoders this is ticks / mm, + // for rotary encoders this is ticks / revolution. + //#define I2CPE_ENC_1_TICKS_REV (16 * 200) // Only needed for rotary encoders; number of stepper + // steps per full revolution (motor steps/rev * microstepping) + //#define I2CPE_ENC_1_INVERT // Invert the direction of axis travel. + #define I2CPE_ENC_1_EC_METHOD I2CPE_ECM_NONE // Type of error error correction. + #define I2CPE_ENC_1_EC_THRESH 0.10 // Threshold size for error (in mm) above which the + // printer will attempt to correct the error; errors + // smaller than this are ignored to minimize effects of + // measurement noise / latency (filter). + + #define I2CPE_ENC_2_ADDR I2CPE_PRESET_ADDR_Y // Same as above, but for encoder 2. + #define I2CPE_ENC_2_AXIS Y_AXIS + #define I2CPE_ENC_2_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_ENC_2_TICKS_UNIT 2048 + //#define I2CPE_ENC_2_TICKS_REV (16 * 200) + //#define I2CPE_ENC_2_INVERT + #define I2CPE_ENC_2_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_ENC_2_EC_THRESH 0.10 + + #define I2CPE_ENC_3_ADDR I2CPE_PRESET_ADDR_Z // Encoder 3. Add additional configuration options + #define I2CPE_ENC_3_AXIS Z_AXIS // as above, or use defaults below. + + #define I2CPE_ENC_4_ADDR I2CPE_PRESET_ADDR_E // Encoder 4. + #define I2CPE_ENC_4_AXIS E_AXIS + + #define I2CPE_ENC_5_ADDR 34 // Encoder 5. + #define I2CPE_ENC_5_AXIS E_AXIS + + // Default settings for encoders which are enabled, but without settings configured above. + #define I2CPE_DEF_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_DEF_ENC_TICKS_UNIT 2048 + #define I2CPE_DEF_TICKS_REV (16 * 200) + #define I2CPE_DEF_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_DEF_EC_THRESH 0.1 + + //#define I2CPE_ERR_THRESH_ABORT 100.0 // Threshold size for error (in mm) error on any given + // axis after which the printer will abort. Comment out to + // disable abort behaviour. + + #define I2CPE_TIME_TRUSTED 10000 // After an encoder fault, there must be no further fault + // for this amount of time (in ms) before the encoder + // is trusted again. + + /** + * Position is checked every time a new command is executed from the buffer but during long moves, + * this setting determines the minimum update time between checks. A value of 100 works well with + * error rolling average when attempting to correct only for skips and not for vibration. + */ + #define I2CPE_MIN_UPD_TIME_MS 100 // Minimum time in miliseconds between encoder checks. + + // Use a rolling average to identify persistant errors that indicate skips, as opposed to vibration and noise. + #define I2CPE_ERR_ROLLING_AVERAGE + +#endif // I2C_POSITION_ENCODERS + +/** + * MAX7219 Debug Matrix + * + * Add support for a low-cost 8x8 LED Matrix based on the Max7219 chip, which can be used as a status + * display. Requires 3 signal wires. Some useful debug options are included to demonstrate its usage. + * + * Fully assembled MAX7219 boards can be found on the internet for under $2(US). + * For example, see https://www.ebay.com/sch/i.html?_nkw=332349290049 + */ +//#define MAX7219_DEBUG +#if ENABLED(MAX7219_DEBUG) + #define MAX7219_CLK_PIN 64 // 77 on Re-ARM // Configuration of the 3 pins to control the display + #define MAX7219_DIN_PIN 57 // 78 on Re-ARM + #define MAX7219_LOAD_PIN 44 // 79 on Re-ARM + + /** + * Sample debug features + * If you add more debug displays, be careful to avoid conflicts! + */ + #define MAX7219_DEBUG_PRINTER_ALIVE // Blink corner LED of 8x8 matrix to show that the firmware is functioning + #define MAX7219_DEBUG_STEPPER_HEAD 3 // Show the stepper queue head position on this and the next LED matrix row + #define MAX7219_DEBUG_STEPPER_TAIL 5 // Show the stepper queue tail position on this and the next LED matrix row + + #define MAX7219_DEBUG_STEPPER_QUEUE 0 // Show the current stepper queue depth on this and the next LED matrix row + // If you experience stuttering, reboots, etc. this option can reveal how + // tweaks made to the configuration are affecting the printer in real-time. +#endif + +#endif // CONFIGURATION_ADV_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/BQ/Hephestos/Configuration.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/BQ/Hephestos/Configuration.h new file mode 100644 index 00000000..592cfe15 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/BQ/Hephestos/Configuration.h @@ -0,0 +1,1691 @@ +/** + * 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 . + * + */ + +/** + * Configuration.h + * + * Basic settings such as: + * + * - Type of electronics + * - Type of temperature sensor + * - Printer geometry + * - Endstop configuration + * - LCD controller + * - Extra features + * + * Advanced settings can be found in Configuration_adv.h + * + */ +#ifndef CONFIGURATION_H +#define CONFIGURATION_H +#define CONFIGURATION_H_VERSION 010100 + +//=========================================================================== +//============================= Getting Started ============================= +//=========================================================================== + +/** + * Here are some standard links for getting your machine calibrated: + * + * http://reprap.org/wiki/Calibration + * http://youtu.be/wAL9d7FgInk + * http://calculator.josefprusa.cz + * http://reprap.org/wiki/Triffid_Hunter%27s_Calibration_Guide + * http://www.thingiverse.com/thing:5573 + * https://sites.google.com/site/repraplogphase/calibration-of-your-reprap + * http://www.thingiverse.com/thing:298812 + */ + +//=========================================================================== +//============================= DELTA Printer =============================== +//=========================================================================== +// For a Delta printer start with one of the configuration files in the +// example_configurations/delta directory and customize for your machine. +// + +//=========================================================================== +//============================= SCARA Printer =============================== +//=========================================================================== +// For a SCARA printer start with the configuration files in +// example_configurations/SCARA and customize for your machine. +// + +// @section info + +// User-specified version info of this build to display in [Pronterface, etc] terminal window during +// startup. Implementation of an idea by Prof Braino to inform user that any changes made to this +// build by the user have been successfully uploaded into firmware. +#define STRING_CONFIG_H_AUTHOR "(none, default config)" // Who made the changes. +#define SHOW_BOOTSCREEN +#define STRING_SPLASH_LINE1 SHORT_BUILD_VERSION // will be shown during bootup in line 1 +#define STRING_SPLASH_LINE2 WEBSITE_URL // will be shown during bootup in line 2 + +// +// *** VENDORS PLEASE READ ***************************************************** +// +// Marlin now allow you to have a vendor boot image to be displayed on machine +// start. When SHOW_CUSTOM_BOOTSCREEN is defined Marlin will first show your +// custom boot image and then the default Marlin boot image is shown. +// +// We suggest for you to take advantage of this new feature and keep the Marlin +// boot image unmodified. For an example have a look at the bq Hephestos 2 +// example configuration folder. +// +//#define SHOW_CUSTOM_BOOTSCREEN +// @section machine + +/** + * Select which serial port on the board will be used for communication with the host. + * This allows the connection of wireless adapters (for instance) to non-default port pins. + * Serial port 0 is always used by the Arduino bootloader regardless of this setting. + * + * :[0, 1, 2, 3, 4, 5, 6, 7] + */ +#define SERIAL_PORT 0 + +/** + * This setting determines the communication speed of the printer. + * + * 250000 works in most cases, but you might try a lower speed if + * you commonly experience drop-outs during host printing. + * You may try up to 1000000 to speed up SD file transfer. + * + * :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000] + */ +#define BAUDRATE 115200 + +// Enable the Bluetooth serial interface on AT90USB devices +//#define BLUETOOTH + +// The following define selects which electronics board you have. +// Please choose the name from boards.h that matches your setup +#ifndef MOTHERBOARD + #define MOTHERBOARD BOARD_RAMPS_14_EFB +#endif + +// Optional custom name for your RepStrap or other custom machine +// Displayed in the LCD "Ready" message +#define CUSTOM_MACHINE_NAME "HEPHESTOS" + +// Added for BQ +#define SOURCE_CODE_URL "http://www.bq.com/gb/downloads-prusa-i3-hephestos.html" + +// Define this to set a unique identifier for this printer, (Used by some programs to differentiate between machines) +// You can use an online service to generate a random UUID. (eg http://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] +#define EXTRUDERS 1 + +// For Cyclops or any "multi-extruder" that shares a single nozzle. +//#define SINGLENOZZLE + +/** + * Průša MK2 Single Nozzle Multi-Material Multiplexer, and variants. + * + * This device allows one stepper driver on a control board to drive + * two to eight stepper motors, one at a time, in a manner suitable + * for extruders. + * + * This option only allows the multiplexer to switch on tool-change. + * Additional options to configure custom E moves are pending. + */ +//#define MK2_MULTIPLEXER +#if ENABLED(MK2_MULTIPLEXER) + // Override the default DIO selector pins here, if needed. + // Some pins files may provide defaults for these pins. + //#define E_MUX0_PIN 40 // Always Required + //#define E_MUX1_PIN 42 // Needed for 3 to 8 steppers + //#define E_MUX2_PIN 44 // Needed for 5 to 8 steppers +#endif + +// A dual extruder that uses a single stepper motor +//#define SWITCHING_EXTRUDER +#if ENABLED(SWITCHING_EXTRUDER) + #define SWITCHING_EXTRUDER_SERVO_NR 0 + #define SWITCHING_EXTRUDER_SERVO_ANGLES { 0, 90 } // Angles for E0, E1[, E2, E3] + #if EXTRUDERS > 3 + #define SWITCHING_EXTRUDER_E23_SERVO_NR 1 + #endif +#endif + +// A dual-nozzle that uses a servomotor to raise/lower one of the nozzles +//#define SWITCHING_NOZZLE +#if ENABLED(SWITCHING_NOZZLE) + #define SWITCHING_NOZZLE_SERVO_NR 0 + #define SWITCHING_NOZZLE_SERVO_ANGLES { 0, 90 } // Angles for E0, E1 + //#define HOTEND_OFFSET_Z { 0.0, 0.0 } +#endif + +/** + * Two separate X-carriages with extruders that connect to a moving part + * via a magnetic docking mechanism. Requires SOL1_PIN and SOL2_PIN. + */ +//#define PARKING_EXTRUDER +#if ENABLED(PARKING_EXTRUDER) + #define PARKING_EXTRUDER_SOLENOIDS_INVERT // If enabled, the solenoid is NOT magnetized with applied voltage + #define PARKING_EXTRUDER_SOLENOIDS_PINS_ACTIVE LOW // LOW or HIGH pin signal energizes the coil + #define PARKING_EXTRUDER_SOLENOIDS_DELAY 250 // Delay (ms) for magnetic field. No delay if 0 or not defined. + #define PARKING_EXTRUDER_PARKING_X { -78, 184 } // X positions for parking the extruders + #define PARKING_EXTRUDER_GRAB_DISTANCE 1 // mm to move beyond the parking point to grab the extruder + #define PARKING_EXTRUDER_SECURITY_RAISE 5 // Z-raise before parking + #define HOTEND_OFFSET_Z { 0.0, 1.3 } // Z-offsets of the two hotends. The first must be 0. +#endif + +/** + * "Mixing Extruder" + * - Adds a new code, M165, to set the current mix factors. + * - Extends the stepping routines to move multiple steppers in proportion to the mix. + * - Optional support for Repetier Firmware M163, M164, and virtual extruder. + * - This implementation supports only a single extruder. + * - Enable DIRECT_MIXING_IN_G1 for Pia Taubert's reference implementation + */ +//#define MIXING_EXTRUDER +#if ENABLED(MIXING_EXTRUDER) + #define MIXING_STEPPERS 2 // Number of steppers in your mixing extruder + #define MIXING_VIRTUAL_TOOLS 16 // Use the Virtual Tool method with M163 and M164 + //#define DIRECT_MIXING_IN_G1 // Allow ABCDHI mix factors in G1 movement commands +#endif + +// Offset of the extruders (uncomment if using more than one and relying on firmware to position when changing). +// The offset has to be X=0, Y=0 for the extruder 0 hotend (default extruder). +// For the other hotends it is their distance from the extruder 0 hotend. +//#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis +//#define HOTEND_OFFSET_Y {0.0, 5.00} // (in mm) for each extruder, offset of the hotend on the Y axis + +// @section machine + +/** + * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN + * + * 0 = No Power Switch + * 1 = ATX + * 2 = X-Box 360 203Watts (the blue wire connected to PS_ON and the red wire to VCC) + * + * :{ 0:'No power switch', 1:'ATX', 2:'X-Box 360' } + */ +#define POWER_SUPPLY 1 + +#if POWER_SUPPLY > 0 + // Enable this option to leave the PSU off at startup. + // Power to steppers and heaters will need to be turned on with M80. + //#define PS_DEFAULT_OFF +#endif + +// @section temperature + +//=========================================================================== +//============================= Thermal Settings ============================ +//=========================================================================== + +/** + * --NORMAL IS 4.7kohm PULLUP!-- 1kohm pullup can be used on hotend sensor, using correct resistor and table + * + * Temperature sensors available: + * + * -3 : thermocouple with MAX31855 (only for sensor 0) + * -2 : thermocouple with MAX6675 (only for sensor 0) + * -1 : thermocouple with AD595 + * 0 : not used + * 1 : 100k thermistor - best choice for EPCOS 100k (4.7k pullup) + * 2 : 200k thermistor - ATC Semitec 204GT-2 (4.7k pullup) + * 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 (Used in ParCan & J-Head) (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) + * 71 : 100k Honeywell thermistor 135-104LAF-J01 (4.7k pullup) + * 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) + * 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" + * 20 : the PT100 circuit found in the Ultimainboard V2.x + * 60 : 100k Maker's Tool Works Kapton Bed Thermistor beta=3950 + * 66 : 4.7M High Temperature thermistor from Dyze Design + * 70 : the 100K thermistor found in the bq Hephestos 2 + * 75 : 100k Generic Silicon Heat Pad with NTC 100K MGB18-104F39050L32 thermistor + * + * 1k ohm pullup tables - This is atypical, and requires changing out the 4.7k pullup for 1k. + * (but gives greater accuracy and more stable PID) + * 51 : 100k thermistor - EPCOS (1k pullup) + * 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 + * 1010 : Pt1000 with 1k pullup (non standard) + * 147 : Pt100 with 4k7 pullup + * 110 : Pt100 with 1k pullup (non standard) + * + * Use these for Testing or Development purposes. NEVER for production machine. + * 998 : Dummy Table that ALWAYS reads 25°C or the temperature defined below. + * 999 : Dummy Table that ALWAYS reads 100°C or the temperature defined below. + * + * :{ '0': "Not used", '1':"100k / 4.7k - EPCOS", '2':"200k / 4.7k - ATC Semitec 204GT-2", '3':"Mendel-parts / 4.7k", '4':"10k !! do not use for a hotend. Bad resolution at high temp. !!", '5':"100K / 4.7k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '6':"100k / 4.7k EPCOS - Not as accurate as Table 1", '7':"100k / 4.7k Honeywell 135-104LAG-J01", '8':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT", '9':"100k / 4.7k GE Sensing AL03006-58.2K-97-G1", '10':"100k / 4.7k RS 198-961", '11':"100k / 4.7k beta 3950 1%", '12':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT (calibrated for Makibox hot bed)", '13':"100k Hisens 3950 1% up to 300°C for hotend 'Simple ONE ' & hotend 'All In ONE'", '20':"PT100 (Ultimainboard V2.x)", '51':"100k / 1k - EPCOS", '52':"200k / 1k - ATC Semitec 204GT-2", '55':"100k / 1k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '60':"100k Maker's Tool Works Kapton Bed Thermistor beta=3950", '66':"Dyze Design 4.7M High Temperature thermistor", '70':"the 100K thermistor found in the bq Hephestos 2", '71':"100k / 4.7k Honeywell 135-104LAF-J01", '147':"Pt100 / 4.7k", '1047':"Pt1000 / 4.7k", '110':"Pt100 / 1k (non-standard)", '1010':"Pt1000 / 1k (non standard)", '-3':"Thermocouple + MAX31855 (only for sensor 0)", '-2':"Thermocouple + MAX6675 (only for sensor 0)", '-1':"Thermocouple + AD595",'998':"Dummy 1", '999':"Dummy 2" } + */ +#define TEMP_SENSOR_0 1 +#define TEMP_SENSOR_1 0 +#define TEMP_SENSOR_2 0 +#define TEMP_SENSOR_3 0 +#define TEMP_SENSOR_4 0 +#define TEMP_SENSOR_BED 0 + +// Dummy thermistor constant temperature readings, for use with 998 and 999 +#define DUMMY_THERMISTOR_998_VALUE 25 +#define DUMMY_THERMISTOR_999_VALUE 100 + +// 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 +#define MAX_REDUNDANT_TEMP_SENSOR_DIFF 10 + +// Extruder temperature must be close to target for this long before M109 returns success +#define TEMP_RESIDENCY_TIME 10 // (seconds) +#define TEMP_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// Bed temperature must be close to target for this long before M190 returns success +#define TEMP_BED_RESIDENCY_TIME 0 // (seconds) +#define TEMP_BED_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_BED_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// The minimal temperature defines the temperature below which the heater will not be enabled It is used +// to check that the wiring to the thermistor is not broken. +// Otherwise this would lead to the heater being powered on all the time. +#define HEATER_0_MINTEMP 5 +#define HEATER_1_MINTEMP 5 +#define HEATER_2_MINTEMP 5 +#define HEATER_3_MINTEMP 5 +#define HEATER_4_MINTEMP 5 +#define BED_MINTEMP 5 + +// When temperature exceeds max temp, your heater will be switched off. +// This feature exists to protect your hotend from overheating accidentally, but *NOT* from thermistor short/failure! +// You should use MINTEMP for thermistor short/failure protection. +#define HEATER_0_MAXTEMP 260 +#define HEATER_1_MAXTEMP 260 +#define HEATER_2_MAXTEMP 260 +#define HEATER_3_MAXTEMP 260 +#define HEATER_4_MAXTEMP 260 +#define BED_MAXTEMP 150 + +//=========================================================================== +//============================= PID Settings ================================ +//=========================================================================== +// PID Tuning Guide here: http://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 +#if ENABLED(PIDTEMP) + //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. + //#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. + #define K1 0.95 //smoothing factor within the PID + + // Hephestos i3 + #define DEFAULT_Kp 23.05 + #define DEFAULT_Ki 2.00 + #define DEFAULT_Kd 66.47 + +#endif // PIDTEMP + +//=========================================================================== +//============================= PID > Bed Temperature Control =============== +//=========================================================================== +// Select PID or bang-bang with PIDTEMPBED. If bang-bang, BED_LIMIT_SWITCHING will enable hysteresis +// +// Uncomment this to enable PID on the bed. It uses the same frequency PWM as the extruder. +// If your PID_dT is the default, and correct for your hardware/configuration, that means 7.689Hz, +// which is fine for driving a square wave into a resistive load and does not significantly impact you FET heating. +// This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W heater. +// If your configuration is significantly different than this and you don't understand the issues involved, you probably +// shouldn't use bed PID until someone else verifies your hardware works. +// If this is enabled, find your own PID constants below. +//#define PIDTEMPBED + +//#define BED_LIMIT_SWITCHING + +// This sets the max power delivered to the bed, and replaces the HEATER_BED_DUTY_CYCLE_DIVIDER option. +// all forms of bed control obey this (PID, bang-bang, bang-bang with hysteresis) +// setting this to anything other than 255 enables a form of PWM to the bed just like HEATER_BED_DUTY_CYCLE_DIVIDER did, +// so you shouldn't use it unless you are OK with PWM on your bed. (see the comment on enabling PIDTEMPBED) +#define MAX_BED_POWER 255 // limits duty cycle to bed; 255=full current + +#if ENABLED(PIDTEMPBED) + + //#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) + #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 + +// @section extruder + +// This option prevents extrusion if the temperature is below EXTRUDE_MINTEMP. +// It also enables the M302 command to set the minimum extrusion temperature +// or to allow moving the extruder regardless of the hotend temperature. +// *** IT IS HIGHLY RECOMMENDED TO LEAVE THIS OPTION ENABLED! *** +#define PREVENT_COLD_EXTRUSION +#define EXTRUDE_MINTEMP 170 + +// This option prevents a single extrusion longer than EXTRUDE_MAXLENGTH. +// Note that for Bowden Extruders a too-small value here may prevent loading. +#define PREVENT_LENGTHY_EXTRUDE +#define EXTRUDE_MAXLENGTH 200 + +//=========================================================================== +//======================== Thermal Runaway Protection ======================= +//=========================================================================== + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * If you get "Thermal Runaway" or "Heating failed" errors the + * details can be tuned in Configuration_adv.h + */ + +#define THERMAL_PROTECTION_HOTENDS // Enable thermal protection for all extruders +#define THERMAL_PROTECTION_BED // Enable thermal protection for the heated bed + +//=========================================================================== +//============================= Mechanical Settings ========================= +//=========================================================================== + +// @section machine + +// Uncomment one of these options to enable CoreXY, CoreXZ, or CoreYZ kinematics +// either in the usual order or reversed +//#define COREXY +//#define COREXZ +//#define COREYZ +//#define COREYX +//#define COREZX +//#define COREZY + +//=========================================================================== +//============================== Endstop Settings =========================== +//=========================================================================== + +// @section homing + +// Specify here all the endstop connectors that are connected to any endstop or probe. +// Almost all printers will be using one per axis. Probes will use one or more of the +// extra connectors. Leave undefined any used for non-endstop and non-probe purposes. +#define USE_XMIN_PLUG +#define USE_YMIN_PLUG +#define USE_ZMIN_PLUG +//#define USE_XMAX_PLUG +//#define USE_YMAX_PLUG +//#define USE_ZMAX_PLUG + +// coarse Endstop Settings +#define ENDSTOPPULLUPS // Comment this out (using // at the start of the line) to disable the endstop pullup resistors + +#if DISABLED(ENDSTOPPULLUPS) + // fine endstop settings: Individual pullups. will be ignored if ENDSTOPPULLUPS is defined + //#define ENDSTOPPULLUP_XMAX + //#define ENDSTOPPULLUP_YMAX + //#define ENDSTOPPULLUP_ZMAX + //#define ENDSTOPPULLUP_XMIN + //#define ENDSTOPPULLUP_YMIN + //#define ENDSTOPPULLUP_ZMIN + //#define ENDSTOPPULLUP_ZMIN_PROBE +#endif + +// Mechanical endstop with COM to ground and NC to Signal uses "false" here (most common setup). +#define X_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Y_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define X_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Y_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MIN_PROBE_ENDSTOP_INVERTING true // set to true to invert the logic of the probe. + +// Enable this feature if all enabled endstop pins are interrupt-capable. +// This will remove the need to poll the interrupt pins, saving many CPU cycles. +//#define ENDSTOP_INTERRUPTS_FEATURE + +//============================================================================= +//============================== Movement Settings ============================ +//============================================================================= +// @section motion + +/** + * Default Settings + * + * These settings can be reset by M502 + * + * Note that if EEPROM is enabled, saved values will override these. + */ + +/** + * With this option each E stepper can have its own factors for the + * following movement settings. If fewer factors are given than the + * total number of extruders, the last value applies to the rest. + */ +//#define DISTINCT_E_FACTORS + +/** + * Default Axis Steps Per Unit (steps/mm) + * Override with M92 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_AXIS_STEPS_PER_UNIT { 80, 80, 4000, 100.47095761381482 } + +/** + * Default Max Feed Rate (mm/s) + * Override with M203 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_FEEDRATE { 200, 200, 3.3, 25 } + +/** + * Default Max Acceleration (change/s) change = mm/s + * (Maximum start speed for accelerated moves) + * Override with M201 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_ACCELERATION { 1100, 1100, 100, 10000 } + +/** + * Default Acceleration (change/s) change = mm/s + * Override with M204 + * + * M204 P Acceleration + * M204 R Retract Acceleration + * M204 T Travel Acceleration + */ +#define DEFAULT_ACCELERATION 650 // X, Y, Z and E acceleration for printing moves +#define DEFAULT_RETRACT_ACCELERATION 1000 // E acceleration for retracts +#define DEFAULT_TRAVEL_ACCELERATION 1000 // X, Y, Z acceleration for travel (non printing) moves + +/** + * Default Jerk (mm/s) + * Override with M205 X Y Z E + * + * "Jerk" specifies the minimum speed change that requires acceleration. + * When changing speed and direction, if the difference is less than the + * value set here, it may happen instantaneously. + */ +#define DEFAULT_XJERK 10.0 +#define DEFAULT_YJERK 10.0 +#define DEFAULT_ZJERK 0.4 +#define DEFAULT_EJERK 5.0 + +//=========================================================================== +//============================= Z Probe Options ============================= +//=========================================================================== +// @section probes + +// +// See http://marlinfw.org/configuration/probes.html +// + +/** + * Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + * + * Enable this option for a probe connected to the Z Min endstop pin. + */ +//#define Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + +/** + * Z_MIN_PROBE_ENDSTOP + * + * Enable this option for a probe connected to any pin except Z-Min. + * (By default Marlin assumes the Z-Max endstop pin.) + * To use a custom Z Probe pin, set Z_MIN_PROBE_PIN below. + * + * - The simplest option is to use a free endstop connector. + * - Use 5V for powered (usually inductive) sensors. + * + * - RAMPS 1.3/1.4 boards may use the 5V, GND, and Aux4->D32 pin: + * - For simple switches connect... + * - normally-closed switches to GND and D32. + * - normally-open switches to 5V and D32. + * + * WARNING: Setting the wrong pin may have unexpected and potentially + * disastrous consequences. Use with caution and do your homework. + * + */ +#define Z_MIN_PROBE_ENDSTOP + +/** + * Probe Type + * + * Allen Key Probes, Servo Probes, Z-Sled Probes, FIX_MOUNTED_PROBE, etc. + * Activate one of these to use Auto Bed Leveling below. + */ + +/** + * The "Manual Probe" provides a means to do "Auto" Bed Leveling without a probe. + * Use G29 repeatedly, adjusting the Z height at each point with movement commands + * or (with LCD_BED_LEVELING) the LCD controller. + */ +//#define PROBE_MANUALLY + +/** + * A Fix-Mounted Probe either doesn't deploy or needs manual deployment. + * (e.g., an inductive probe or a nozzle-based probe-switch.) + */ +//#define FIX_MOUNTED_PROBE + +/** + * Z Servo Probe, such as an endstop switch on a rotating arm. + */ +//#define Z_ENDSTOP_SERVO_NR 0 // Defaults to SERVO 0 connector. +//#define Z_SERVO_ANGLES {70,0} // Z Servo Deploy and Stow angles + +/** + * The BLTouch probe uses a Hall effect sensor and emulates a servo. + */ +//#define BLTOUCH +#if ENABLED(BLTOUCH) + //#define BLTOUCH_DELAY 375 // (ms) Enable and increase if needed +#endif + +/** + * Enable one or more of the following if probing seems unreliable. + * Heaters and/or fans can be disabled during probing to minimize electrical + * noise. A delay can also be added to allow noise and vibration to settle. + * These options are most useful for the BLTouch probe, but may also improve + * readings with inductive probes and piezo sensors. + */ +//#define PROBING_HEATERS_OFF // Turn heaters off when probing +//#define PROBING_FANS_OFF // Turn fans off when probing +//#define DELAY_BEFORE_PROBING 200 // (ms) To prevent vibrations from triggering piezo sensors + +// A probe that is deployed and stowed with a solenoid pin (SOL1_PIN) +//#define SOLENOID_PROBE + +// A sled-mounted probe like those designed by Charles Bell. +//#define Z_PROBE_SLED +//#define SLED_DOCKING_OFFSET 5 // The extra distance the X axis must travel to pickup the sled. 0 should be fine but you can push it further if you'd like. + +// +// For Z_PROBE_ALLEN_KEY see the Delta example configurations. +// + +/** + * Z Probe to nozzle (X,Y) offset, relative to (0, 0). + * X and Y offsets must be integers. + * + * In the following example the X and Y offsets are both positive: + * #define X_PROBE_OFFSET_FROM_EXTRUDER 10 + * #define Y_PROBE_OFFSET_FROM_EXTRUDER 10 + * + * +-- BACK ---+ + * | | + * L | (+) P | R <-- probe (20,20) + * E | | I + * F | (-) N (+) | G <-- nozzle (10,10) + * T | | H + * | (-) | T + * | | + * O-- FRONT --+ + * (0,0) + */ +#define X_PROBE_OFFSET_FROM_EXTRUDER -25 // X offset: -left +right [of the nozzle] +#define Y_PROBE_OFFSET_FROM_EXTRUDER -29 // Y offset: -front +behind [the nozzle] +#define Z_PROBE_OFFSET_FROM_EXTRUDER -12.35 // Z offset: -below +above [the nozzle] + +// X and Y axis travel speed (mm/m) between probes +#define XY_PROBE_SPEED 8000 + +// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +#define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z + +// Speed for the "accurate" probe of each point +#define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) + +// Use double touch for probing +//#define PROBE_DOUBLE_TOUCH + +/** + * Z probes require clearance when deploying, stowing, and moving between + * probe points to avoid hitting the bed and other hardware. + * Servo-mounted probes require extra space for the arm to rotate. + * Inductive probes need space to keep from triggering early. + * + * Use these settings to specify the distance (mm) to raise the probe (or + * lower the bed). The values set here apply over and above any (negative) + * probe Z Offset set with Z_PROBE_OFFSET_FROM_EXTRUDER, M851, or the LCD. + * Only integer values >= 1 are valid here. + * + * Example: `M851 Z-5` with a CLEARANCE of 4 => 9mm from bed to nozzle. + * But: `M851 Z+1` with a CLEARANCE of 2 => 2mm from bed to nozzle. + */ +#define Z_CLEARANCE_DEPLOY_PROBE 15 // Z Clearance for Deploy/Stow +#define Z_CLEARANCE_BETWEEN_PROBES 5 // Z Clearance between probe points + +// For M851 give a range for adjusting the Z probe offset +#define Z_PROBE_OFFSET_RANGE_MIN -20 +#define Z_PROBE_OFFSET_RANGE_MAX 20 + +// Enable the M48 repeatability test to test probe accuracy +//#define Z_MIN_PROBE_REPEATABILITY_TEST + +// For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1 +// :{ 0:'Low', 1:'High' } +#define X_ENABLE_ON 0 +#define Y_ENABLE_ON 0 +#define Z_ENABLE_ON 0 +#define E_ENABLE_ON 0 // For all extruders + +// Disables axis stepper immediately when it's not being used. +// 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 +//#define DISABLE_REDUCED_ACCURACY_WARNING + +// @section extruder + +#define DISABLE_E false // For all extruders +#define DISABLE_INACTIVE_EXTRUDER true // Keep only the active extruder enabled. + +// @section machine + +// Invert the stepper direction. Change (or reverse the motor connector) if an axis goes the wrong way. +#define INVERT_X_DIR true +#define INVERT_Y_DIR false +#define INVERT_Z_DIR true + +// Enable this option for Toshiba stepper drivers +//#define CONFIG_STEPPERS_TOSHIBA + +// @section extruder + +// For direct drive extruder v9 set to true, for geared extruder set to false. +#define INVERT_E0_DIR false +#define INVERT_E1_DIR false +#define INVERT_E2_DIR false +#define INVERT_E3_DIR false +#define INVERT_E4_DIR false + +// @section homing + +//#define NO_MOTION_BEFORE_HOMING // Inhibit movement until all axes have been homed + +//#define Z_HOMING_HEIGHT 4 // (in mm) Minimal z height before homing (G28) for Z clearance above the bed, clamps, ... + // Be sure you have this distance over your Z_MAX_POS in case. + +// Direction of endstops when homing; 1=MAX, -1=MIN +// :[-1,1] +#define X_HOME_DIR -1 +#define Y_HOME_DIR -1 +#define Z_HOME_DIR -1 + +// @section machine + +// The size of the print bed +#define X_BED_SIZE 215 +#define Y_BED_SIZE 210 + +// Travel limits (mm) after homing, corresponding to endstop positions. +#define X_MIN_POS 0 +#define Y_MIN_POS 0 +#define Z_MIN_POS 0 +#define X_MAX_POS X_BED_SIZE +#define Y_MAX_POS Y_BED_SIZE +#define Z_MAX_POS 180 + +// If enabled, axes won't move below MIN_POS in response to movement commands. +#define MIN_SOFTWARE_ENDSTOPS +// If enabled, axes won't move above MAX_POS in response to movement commands. +#define MAX_SOFTWARE_ENDSTOPS + +/** + * Filament Runout Sensor + * A mechanical or opto endstop is used to check for the presence of filament. + * + * RAMPS-based boards use SERVO3_PIN. + * For other boards you may need to define FIL_RUNOUT_PIN. + * By default the firmware assumes HIGH = has filament, LOW = ran out + */ +//#define FILAMENT_RUNOUT_SENSOR +#if ENABLED(FILAMENT_RUNOUT_SENSOR) + #define FIL_RUNOUT_INVERTING false // set to true to invert the logic of the sensor. + #define ENDSTOPPULLUP_FIL_RUNOUT // Uncomment to use internal pullup for filament runout pins if the sensor is defined. + #define FILAMENT_RUNOUT_SCRIPT "M600" +#endif + +//=========================================================================== +//=============================== Bed Leveling ============================== +//=========================================================================== +// @section bedlevel + +/** + * Choose one of the options below to enable G29 Bed Leveling. The parameters + * and behavior of G29 will change depending on your selection. + * + * If using a Probe for Z Homing, enable Z_SAFE_HOMING also! + * + * - AUTO_BED_LEVELING_3POINT + * Probe 3 arbitrary points on the bed (that aren't collinear) + * You specify the XY coordinates of all 3 points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_LINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_BILINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a mesh, best for large or uneven beds. + * + * - AUTO_BED_LEVELING_UBL (Unified Bed Leveling) + * A comprehensive bed leveling system combining the features and benefits + * of other systems. UBL also includes integrated Mesh Generation, Mesh + * Validation and Mesh Editing systems. Currently, UBL is only checked out + * for Cartesian Printers. That said, it was primarily designed to correct + * poor quality Delta Printers. If you feel adventurous and have a Delta, + * please post an issue if something doesn't work correctly. Initially, + * you will need to set a reduced bed size so you have a rectangular area + * to test on. + * + * - MESH_BED_LEVELING + * Probe a grid manually + * The result is a mesh, suitable for large or uneven beds. (See BILINEAR.) + * For machines without a probe, Mesh Bed Leveling provides a method to perform + * leveling in steps so you can manually adjust the Z height at each grid-point. + * With an LCD controller the process is guided step-by-step. + */ +//#define AUTO_BED_LEVELING_3POINT +//#define AUTO_BED_LEVELING_LINEAR +//#define AUTO_BED_LEVELING_BILINEAR +//#define AUTO_BED_LEVELING_UBL +//#define MESH_BED_LEVELING + +/** + * Enable detailed logging of G28, G29, M48, etc. + * Turn on with the command 'M111 S32'. + * NOTE: Requires a lot of PROGMEM! + */ +//#define DEBUG_LEVELING_FEATURE + +#if ENABLED(MESH_BED_LEVELING) || ENABLED(AUTO_BED_LEVELING_BILINEAR) || ENABLED(AUTO_BED_LEVELING_UBL) + // Gradually reduce leveling correction until a set height is reached, + // at which point movement will be level to the machine's XY plane. + // The height can be set with M420 Z + #define ENABLE_LEVELING_FADE_HEIGHT +#endif + +#if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Set the number of grid points per dimension. + #define GRID_MAX_POINTS_X 3 + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + // Set the boundaries for probing (where the probe can reach). + #define LEFT_PROBE_BED_POSITION 15 + #define RIGHT_PROBE_BED_POSITION 170 + #define FRONT_PROBE_BED_POSITION 20 + #define BACK_PROBE_BED_POSITION 170 + + // The Z probe minimum outer margin (to validate G29 parameters). + #define MIN_PROBE_EDGE 10 + + // Probe along the Y axis, advancing X after each column + //#define PROBE_Y_FIRST + + #if ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Beyond the probed grid, continue the implied tilt? + // Default is to maintain the height of the nearest edge. + //#define EXTRAPOLATE_BEYOND_GRID + + // + // Experimental Subdivision of the grid by Catmull-Rom method. + // Synthesizes intermediate points to produce a more detailed mesh. + // + //#define ABL_BILINEAR_SUBDIVISION + #if ENABLED(ABL_BILINEAR_SUBDIVISION) + // Number of subdivisions between probe points + #define BILINEAR_SUBDIVISIONS 3 + #endif + + #endif + +#elif ENABLED(AUTO_BED_LEVELING_3POINT) + + // 3 arbitrary points to probe. + // A simple cross-product is used to estimate the plane of the bed. + #define ABL_PROBE_PT_1_X 15 + #define ABL_PROBE_PT_1_Y 180 + #define ABL_PROBE_PT_2_X 15 + #define ABL_PROBE_PT_2_Y 20 + #define ABL_PROBE_PT_3_X 170 + #define ABL_PROBE_PT_3_Y 20 + +#elif ENABLED(AUTO_BED_LEVELING_UBL) + + //=========================================================================== + //========================= Unified Bed Leveling ============================ + //=========================================================================== + + #define UBL_MESH_INSET 1 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 10 // Don't use more than 15 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + #define UBL_PROBE_PT_1_X 39 // Probing points for 3-Point leveling of the mesh + #define UBL_PROBE_PT_1_Y 180 + #define UBL_PROBE_PT_2_X 39 + #define UBL_PROBE_PT_2_Y 20 + #define UBL_PROBE_PT_3_X 180 + #define UBL_PROBE_PT_3_Y 20 + + #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation + #define UBL_MESH_EDIT_MOVES_Z // Sophisticated users prefer no movement of nozzle + +#elif ENABLED(MESH_BED_LEVELING) + + //=========================================================================== + //=================================== Mesh ================================== + //=========================================================================== + + #define MESH_INSET 10 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 3 // Don't use more than 7 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + //#define MESH_G28_REST_ORIGIN // After homing all axes ('G28' or 'G28 XYZ') rest Z at Z_MIN_POS + +#endif // BED_LEVELING + +/** + * Use the LCD controller for bed leveling + * Requires MESH_BED_LEVELING or PROBE_MANUALLY + */ +//#define LCD_BED_LEVELING + +#if ENABLED(LCD_BED_LEVELING) + #define MBL_Z_STEP 0.025 // Step size while manually probing Z axis. + #define LCD_PROBE_Z_RANGE 4 // Z Range centered on Z_MIN_POS for LCD Z adjustment +#endif + +// Add a menu item to move between bed corners for manual bed adjustment +//#define LEVEL_BED_CORNERS + +/** + * Commands to execute at the end of G29 probing. + * Useful to retract or move the Z probe out of the way. + */ +//#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) +//#define BED_CENTER_AT_0_0 + +// Manually set the home position. Leave these undefined for automatic settings. +// For DELTA this is the top-center of the Cartesian print volume. +//#define MANUAL_X_HOME_POS 0 +//#define MANUAL_Y_HOME_POS 0 +//#define MANUAL_Z_HOME_POS 0 + +// Use "Z Safe Homing" to avoid homing with a Z probe outside the bed area. +// +// With this feature enabled: +// +// - 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). +// - 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 axis (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). +#endif + +// Homing speeds (mm/m) +#define HOMING_FEEDRATE_XY 2000 +#define HOMING_FEEDRATE_Z 150 + +//============================================================================= +//============================= Additional Features =========================== +//============================================================================= + +// @section extras + +// +// EEPROM +// +// The microcontroller can store settings in the EEPROM, e.g. max velocity... +// M500 - stores parameters in EEPROM +// M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily). +// M502 - reverts to the default "factory settings". You still need to store them in EEPROM afterwards if you want to. +// +//#define EEPROM_SETTINGS // Enable for M500 and M501 commands +//#define DISABLE_M503 // Saves ~2700 bytes of PROGMEM. Disable for release! +#define EEPROM_CHITCHAT // Give feedback on EEPROM commands. Disable to save PROGMEM. + +// +// Host Keepalive +// +// When enabled Marlin will send a busy status message to the host +// every couple of seconds when it can't accept commands. +// +#define HOST_KEEPALIVE_FEATURE // Disable this if your host doesn't like keepalive messages +#define DEFAULT_KEEPALIVE_INTERVAL 2 // Number of seconds between "busy" messages. Set with M113. +#define BUSY_WHILE_HEATING // Some hosts require "busy" messages even during heating + +// +// M100 Free Memory Watcher +// +//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose + +// +// G20/G21 Inch mode support +// +//#define INCH_MODE_SUPPORT + +// +// M149 Set temperature units support +// +//#define TEMPERATURE_UNITS_SUPPORT + +// @section temperature + +// Preheat Constants +#define PREHEAT_1_TEMP_HOTEND 200 +#define PREHEAT_1_TEMP_BED 0 +#define PREHEAT_1_FAN_SPEED 255 // Value from 0 to 255 + +#define PREHEAT_2_TEMP_HOTEND 220 +#define PREHEAT_2_TEMP_BED 100 +#define PREHEAT_2_FAN_SPEED 255 // Value from 0 to 255 + +/** + * Nozzle Park -- EXPERIMENTAL + * + * Park the nozzle at the given XYZ position on idle or G27. + * + * The "P" parameter controls the action applied to the Z axis: + * + * P0 (Default) If Z is below park Z raise the nozzle. + * P1 Raise the nozzle always to Z-park height. + * P2 Raise the nozzle by Z-park amount, limited to Z_MAX_POS. + */ +//#define NOZZLE_PARK_FEATURE + +#if ENABLED(NOZZLE_PARK_FEATURE) + // Specify a park position as { X, Y, Z } + #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 } +#endif + +/** + * Clean Nozzle Feature -- EXPERIMENTAL + * + * Adds the G12 command to perform a nozzle cleaning process. + * + * Parameters: + * P Pattern + * S Strokes / Repetitions + * T Triangles (P1 only) + * + * Patterns: + * P0 Straight line (default). This process requires a sponge type material + * at a fixed bed location. "S" specifies strokes (i.e. back-forth motions) + * between the start / end points. + * + * P1 Zig-zag pattern between (X0, Y0) and (X1, Y1), "T" specifies the + * number of zig-zag triangles to do. "S" defines the number of strokes. + * Zig-zags are done in whichever is the narrower dimension. + * For example, "G12 P1 S1 T3" will execute: + * + * -- + * | (X0, Y1) | /\ /\ /\ | (X1, Y1) + * | | / \ / \ / \ | + * A | | / \ / \ / \ | + * | | / \ / \ / \ | + * | (X0, Y0) | / \/ \/ \ | (X1, Y0) + * -- +--------------------------------+ + * |________|_________|_________| + * T1 T2 T3 + * + * P2 Circular pattern with middle at NOZZLE_CLEAN_CIRCLE_MIDDLE. + * "R" specifies the radius. "S" specifies the stroke count. + * Before starting, the nozzle moves to NOZZLE_CLEAN_START_POINT. + * + * Caveats: The ending Z should be the same as starting Z. + * Attention: EXPERIMENTAL. G-code arguments may change. + * + */ +//#define NOZZLE_CLEAN_FEATURE + +#if ENABLED(NOZZLE_CLEAN_FEATURE) + // Default number of pattern repetitions + #define NOZZLE_CLEAN_STROKES 12 + + // Default number of triangles + #define NOZZLE_CLEAN_TRIANGLES 3 + + // Specify positions as { X, Y, Z } + #define NOZZLE_CLEAN_START_POINT { 30, 30, (Z_MIN_POS + 1)} + #define NOZZLE_CLEAN_END_POINT {100, 60, (Z_MIN_POS + 1)} + + // Circular pattern radius + #define NOZZLE_CLEAN_CIRCLE_RADIUS 6.5 + // Circular pattern circle fragments number + #define NOZZLE_CLEAN_CIRCLE_FN 10 + // Middle point of circle + #define NOZZLE_CLEAN_CIRCLE_MIDDLE NOZZLE_CLEAN_START_POINT + + // Moves the nozzle to the initial position + #define NOZZLE_CLEAN_GOBACK +#endif + +/** + * Print Job Timer + * + * Automatically start and stop the print job timer on M104/M109/M190. + * + * M104 (hotend, no wait) - high temp = none, low temp = stop timer + * M109 (hotend, wait) - high temp = start timer, low temp = stop timer + * M190 (bed, wait) - high temp = start timer, low temp = none + * + * The timer can also be controlled with the following commands: + * + * M75 - Start the print job timer + * M76 - Pause the print job timer + * M77 - Stop the print job timer + */ +#define PRINTJOB_TIMER_AUTOSTART + +/** + * Print Counter + * + * Track statistical data such as: + * + * - Total print jobs + * - Total successful print jobs + * - Total failed print jobs + * - Total time printing + * + * View the current statistics with M78. + */ +//#define PRINTCOUNTER + +//============================================================================= +//============================= LCD and SD support ============================ +//============================================================================= + +// @section lcd + +/** + * LCD LANGUAGE + * + * Select the language to display on the LCD. These languages are available: + * + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, + * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * tr, uk, zh_CN, zh_TW, test + * + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + */ +//#define LCD_LANGUAGE en + +/** + * LCD Character Set + * + * Note: This option is NOT applicable to Graphical Displays. + * + * All character-based LCDs provide ASCII plus one of these + * language extensions: + * + * - JAPANESE ... the most common + * - WESTERN ... with more accented characters + * - CYRILLIC ... for the Russian language + * + * To determine the language extension installed on your controller: + * + * - Compile and upload with LCD_LANGUAGE set to 'test' + * - 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 + * + * :['JAPANESE', 'WESTERN', 'CYRILLIC'] + */ +#define DISPLAY_CHARSET_HD44780 JAPANESE + +/** + * LCD TYPE + * + * Enable ULTRA_LCD for a 16x2, 16x4, 20x2, or 20x4 character-based LCD. + * Enable DOGLCD for a 128x64 (ST7565R) Full Graphical Display. + * (These options will be enabled automatically for most displays.) + * + * IMPORTANT: The U8glib library is required for Full Graphic Display! + * https://github.com/olikraus/U8glib_Arduino + */ +//#define ULTRA_LCD // Character based +//#define DOGLCD // Full graphics display + +/** + * SD CARD + * + * 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 + +/** + * SD CARD: SPI SPEED + * + * Enable one of the following items for a slower SPI transfer speed. + * This may be required to resolve "volume init" errors. + */ +//#define SPI_SPEED SPI_HALF_SPEED +//#define SPI_SPEED SPI_QUARTER_SPEED +//#define SPI_SPEED SPI_EIGHTH_SPEED + +/** + * SD CARD: ENABLE CRC + * + * Use CRC checks and retries on the SD communication. + */ +//#define SD_CHECK_AND_RETRY + +// +// ENCODER SETTINGS +// +// This option overrides the default number of encoder pulses needed to +// produce one step. Should be increased for high-resolution encoders. +// +//#define ENCODER_PULSES_PER_STEP 1 + +// +// Use this option to override the number of step signals required to +// move between next/prev menu items. +// +//#define ENCODER_STEPS_PER_MENU_ITEM 5 + +/** + * Encoder Direction Options + * + * Test your encoder's behavior first with both options disabled. + * + * Reversed Value Edit and Menu Nav? Enable REVERSE_ENCODER_DIRECTION. + * Reversed Menu Navigation only? Enable REVERSE_MENU_DIRECTION. + * Reversed Value Editing only? Enable BOTH options. + */ + +// +// This option reverses the encoder direction everywhere. +// +// Set this option if CLOCKWISE causes values to DECREASE +// +//#define REVERSE_ENCODER_DIRECTION + +// +// This option reverses the encoder direction for navigating LCD menus. +// +// If CLOCKWISE normally moves DOWN this makes it go UP. +// If CLOCKWISE normally moves UP this makes it go DOWN. +// +//#define REVERSE_MENU_DIRECTION + +// +// Individual Axis Homing +// +// Add individual axis homing items (Home X, Home Y, and Home Z) to the LCD menu. +// +//#define INDIVIDUAL_AXIS_HOMING_MENU + +// +// SPEAKER/BUZZER +// +// If you have a speaker that can produce tones, enable it here. +// By default Marlin assumes you have a buzzer with a fixed frequency. +// +//#define SPEAKER + +// +// The duration and frequency for the UI feedback sound. +// Set these to 0 to disable audio feedback in the LCD menus. +// +// Note: Test audio output with the G-Code: +// M300 S P +// +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 +//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 + +// +// CONTROLLER TYPE: Standard +// +// Marlin supports a wide variety of controllers. +// Enable one of the following options to specify your controller. +// + +// +// ULTIMAKER Controller. +// +//#define ULTIMAKERCONTROLLER + +// +// ULTIPANEL as seen on Thingiverse. +// +//#define ULTIPANEL + +// +// PanelOne from T3P3 (via RAMPS 1.4 AUX2/AUX3) +// http://reprap.org/wiki/PanelOne +// +//#define PANEL_ONE + +// +// MaKr3d Makr-Panel with graphic controller and SD support. +// http://reprap.org/wiki/MaKr3d_MaKrPanel +// +//#define MAKRPANEL + +// +// ReprapWorld Graphical LCD +// https://reprapworld.com/?products_details&products_id/1218 +// +//#define REPRAPWORLD_GRAPHICAL_LCD + +// +// Activate one of these if you have a Panucatt Devices +// Viki 2.0 or mini Viki with Graphic LCD +// http://panucatt.com +// +//#define VIKI2 +//#define miniVIKI + +// +// Adafruit ST7565 Full Graphic Controller. +// https://github.com/eboston/Adafruit-ST7565-Full-Graphic-Controller/ +// +//#define ELB_FULL_GRAPHIC_CONTROLLER + +// +// RepRapDiscount Smart Controller. +// http://reprap.org/wiki/RepRapDiscount_Smart_Controller +// +// Note: Usually sold with a white PCB. +// +#define REPRAP_DISCOUNT_SMART_CONTROLLER + +// +// GADGETS3D G3D LCD/SD Controller +// http://reprap.org/wiki/RAMPS_1.3/1.4_GADGETS3D_Shield_with_Panel +// +// Note: Usually sold with a blue PCB. +// +//#define G3D_PANEL + +// +// RepRapDiscount FULL GRAPHIC Smart Controller +// http://reprap.org/wiki/RepRapDiscount_Full_Graphic_Smart_Controller +// +//#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER + +// +// MakerLab Mini Panel with graphic +// controller and SD support - http://reprap.org/wiki/Mini_panel +// +//#define MINIPANEL + +// +// RepRapWorld REPRAPWORLD_KEYPAD v1.1 +// http://reprapworld.com/?products_details&products_id=202&cPath=1591_1626 +// +// REPRAPWORLD_KEYPAD_MOVE_STEP sets how much should the robot move when a key +// is pressed, a value of 10.0 means 10mm per click. +// +//#define REPRAPWORLD_KEYPAD +//#define REPRAPWORLD_KEYPAD_MOVE_STEP 1.0 + +// +// RigidBot Panel V1.0 +// http://www.inventapart.com/ +// +//#define RIGIDBOT_PANEL + +// +// BQ LCD Smart Controller shipped by +// default with the BQ Hephestos 2 and Witbox 2. +// +//#define BQ_LCD_SMART_CONTROLLER + +// +// Cartesio UI +// http://mauk.cc/webshop/cartesio-shop/electronics/user-interface +// +//#define CARTESIO_UI + +// +// ANET_10 Controller supported displays. +// +//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. + // This LCD is known to be susceptible to electrical interference + // which scrambles the display. Pressing any button clears it up. +//#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 + // A clone of the RepRapDiscount full graphics display but with + // different pins/wiring (see pins_ANET_10.h). + +// +// LCD for Melzi Card with Graphical LCD +// +//#define LCD_FOR_MELZI + +// +// CONTROLLER TYPE: I2C +// +// Note: These controllers require the installation of Arduino's LiquidCrystal_I2C +// library. For more info: https://github.com/kiyoshigawa/LiquidCrystal_I2C +// + +// +// Elefu RA Board Control Panel +// http://www.elefu.com/index.php?route=product/product&product_id=53 +// +//#define RA_CONTROL_PANEL + +// +// Sainsmart YW Robot (LCM1602) LCD Display +// +// Note: This controller requires F.Malpartida's LiquidCrystal_I2C library +// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home +// +//#define LCD_I2C_SAINSMART_YWROBOT + +// +// Generic LCM1602 LCD adapter +// +//#define LCM1602 + +// +// PANELOLU2 LCD with status LEDs, +// separate encoder and click inputs. +// +// Note: This controller requires Arduino's LiquidTWI2 library v1.2.3 or later. +// For more info: https://github.com/lincomatic/LiquidTWI2 +// +// Note: The PANELOLU2 encoder click input can either be directly connected to +// a pin (if BTN_ENC defined to != -1) or read through I2C (when BTN_ENC == -1). +// +//#define LCD_I2C_PANELOLU2 + +// +// Panucatt VIKI LCD with status LEDs, +// integrated click & L/R/U/D buttons, separate encoder inputs. +// +//#define LCD_I2C_VIKI + +// +// SSD1306 OLED full graphics generic display +// +//#define U8GLIB_SSD1306 + +// +// SAV OLEd LCD module support using either SSD1306 or SH1106 based LCD modules +// +//#define SAV_3DGLCD +#if ENABLED(SAV_3DGLCD) + //#define U8GLIB_SSD1306 + #define U8GLIB_SH1106 +#endif + +// +// CONTROLLER TYPE: Shift register panels +// +// 2 wire Non-latching LCD SR from https://goo.gl/aJJ4sH +// LCD configuration: http://reprap.org/wiki/SAV_3D_LCD +// +//#define SAV_3DLCD + +// +// TinyBoy2 128x64 OLED / Encoder Panel +// +//#define OLED_PANEL_TINYBOY2 + +// +// Makeboard 3D Printer Parts 3D Printer Mini Display 1602 Mini Controller +// https://www.aliexpress.com/item/Micromake-Makeboard-3D-Printer-Parts-3D-Printer-Mini-Display-1602-Mini-Controller-Compatible-with-Ramps-1/32765887917.html +// +//#define MAKEBOARD_MINI_2_LINE_DISPLAY_1602 + +// +// MKS MINI12864 with graphic controller and SD support +// http://reprap.org/wiki/MKS_MINI_12864 +// +//#define MKS_MINI_12864 + +// +// Factory display for Creality CR-10 +// https://www.aliexpress.com/item/Universal-LCD-12864-3D-Printer-Display-Screen-With-Encoder-For-CR-10-CR-7-Model/32833148327.html +// +// This is RAMPS-compatible using a single 10-pin connector. +// (For CR-10 owners who want to replace the Melzi Creality board but retain the display) +// +//#define CR10_STOCKDISPLAY + +// +// MKS OLED 1.3" 128 × 64 FULL GRAPHICS CONTROLLER +// http://reprap.org/wiki/MKS_12864OLED +// +// Tiny, but very sharp OLED display +// +//#define MKS_12864OLED + +//============================================================================= +//=============================== Extra Features ============================== +//============================================================================= + +// @section extras + +// Increase the FAN PWM frequency. Removes the PWM noise but increases heating in the FET/Arduino +//#define FAST_PWM_FAN + +// Use software PWM to drive the fan, as for the heaters. This uses a very low frequency +// which is not as annoying as with the hardware PWM. On the other hand, if this frequency +// is too low, you should also increment SOFT_PWM_SCALE. +//#define FAN_SOFT_PWM + +// Incrementing this by 1 will double the software PWM frequency, +// affecting heaters, and the fan if FAN_SOFT_PWM is enabled. +// However, control resolution will be halved for each increment; +// at zero value, there are 128 effective control positions. +#define SOFT_PWM_SCALE 0 + +// If SOFT_PWM_SCALE is set to a value higher than 0, dithering can +// be used to mitigate the associated resolution loss. If enabled, +// some of the PWM cycles are stretched so on average the desired +// duty cycle is attained. +//#define SOFT_PWM_DITHER + +// Temperature status LEDs that display the hotend and bed temperature. +// If all hotends, bed temperature, and target temperature are under 54C +// then the BLUE led is on. Otherwise the RED led is on. (1C hysteresis) +//#define TEMP_STAT_LEDS + +// M240 Triggers a camera by emulating a Canon RC-1 Remote +// Data from: http://www.doc-diy.net/photo/rc-1_hacked/ +//#define PHOTOGRAPH_PIN 23 + +// 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 + +// Support for BlinkM/CyzRgb +//#define BLINKM + +// Support for PCA9632 PWM LED driver +//#define PCA9632 + +/** + * RGB LED / LED Strip Control + * + * Enable support for an RGB LED connected to 5V digital pins, or + * an RGB Strip connected to MOSFETs controlled by digital pins. + * + * 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 overall brightness parameters is also available + * + * *** CAUTION *** + * LED Strips require a MOFSET 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! + * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino + * cannot handle such current, separate 5V power supply must be used + * *** CAUTION *** + * + * LED type. This options are mutualy exclusive. Uncomment only one. + * + */ +//#define RGB_LED +//#define RGBW_LED + +#if ENABLED(RGB_LED) || ENABLED(RGBW_LED) + #define RGB_LED_R_PIN 34 + #define RGB_LED_G_PIN 43 + #define RGB_LED_B_PIN 35 + #define RGB_LED_W_PIN -1 +#endif + +// 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 (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) + #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip + #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time + #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + //#define NEOPIXEL_STARTUP_TEST // Cycle through colors at startup +#endif + +/** + * Printer Event LEDs + * + * During printing, the LEDs will reflect the printer status: + * + * - Gradually change from blue to violet as the heated bed gets to target temp + * - Gradually change from violet to red as the hotend gets to temperature + * - Change to white to illuminate work surface + * - Change to green once print has finished + * - Turn off after the print has finished and the user has pushed a button + */ +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) + #define PRINTER_EVENT_LEDS +#endif + +/*********************************************************************\ +* R/C SERVO support +* Sponsored by TrinityLabs, Reworked by codexmas +**********************************************************************/ + +// Number of servos +// +// If you select a configuration below, this will receive a default value and does not need to be set manually +// set it manually if you have more servos than extruders and wish to manually control some +// leaving it undefined or defining as 0 will disable the servo subsystem +// If unsure, leave commented / disabled +// +//#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command + +// Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. +// 300ms is a good value but you can try less delay. +// If the servo can't reach the requested position, increase it. +#define SERVO_DELAY { 300 } + +// Servo deactivation +// +// With this option servos are powered only during movement, then turned off to prevent jitter. +//#define DEACTIVATE_SERVOS_AFTER_MOVE + +/** + * Filament Width Sensor + * + * Measures the filament width in real-time and adjusts + * flow rate to compensate for any irregularities. + * + * Also allows the measured filament diameter to set the + * extrusion rate, so the slicer only has to specify the + * volume. + * + * Only a single extruder is supported at this time. + * + * 34 RAMPS_14 : Analog input 5 on the AUX2 connector + * 81 PRINTRBOARD : Analog input 2 on the Exp1 connector (version B,C,D,E) + * 301 RAMBO : Analog input 3 + * + * Note: May require analog pins to be defined for other boards. + */ +//#define FILAMENT_WIDTH_SENSOR + +#define DEFAULT_NOMINAL_FILAMENT_DIA 3.00 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. + +#if ENABLED(FILAMENT_WIDTH_SENSOR) + #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) + #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber + + #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading + #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading + #define MAX_MEASUREMENT_DELAY 20 // (bytes) Buffer size for stored measurements (1 byte per cm). Must be larger than MEASUREMENT_DELAY_CM. + + #define DEFAULT_MEASURED_FILAMENT_DIA DEFAULT_NOMINAL_FILAMENT_DIA // Set measured to nominal initially + + // Display filament width on the LCD status line. Status messages will expire after 5 seconds. + //#define FILAMENT_LCD_DISPLAY +#endif + +#endif // CONFIGURATION_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/BQ/Hephestos/Configuration_adv.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/BQ/Hephestos/Configuration_adv.h new file mode 100644 index 00000000..af68c570 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/BQ/Hephestos/Configuration_adv.h @@ -0,0 +1,1424 @@ +/** + * 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 . + * + */ + +/** + * Configuration_adv.h + * + * Advanced settings. + * Only change these if you know exactly what you're doing. + * Some of these settings can damage your printer if improperly set! + * + * Basic settings can be found in Configuration.h + * + */ +#ifndef CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H_VERSION 010100 + +// @section temperature + +//=========================================================================== +//=============================Thermal Settings ============================ +//=========================================================================== + +#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 + #endif +#endif + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * The solution: Once the temperature reaches the target, start observing. + * If the temperature stays too far below the target (hysteresis) for too long (period), + * the firmware will halt the machine as a safety precaution. + * + * If you get false positives for "Thermal Runaway" increase THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD + */ +#if ENABLED(THERMAL_PROTECTION_HOTENDS) + #define THERMAL_PROTECTION_PERIOD 40 // Seconds + #define THERMAL_PROTECTION_HYSTERESIS 4 // Degrees Celsius + + /** + * Whenever an M104 or M109 increases the target temperature the firmware will wait for the + * WATCH_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get false positives for "Heating failed" increase WATCH_TEMP_PERIOD and/or decrease WATCH_TEMP_INCREASE + * WATCH_TEMP_INCREASE should not be below 2. + */ + #define WATCH_TEMP_PERIOD 20 // Seconds + #define WATCH_TEMP_INCREASE 2 // Degrees Celsius +#endif + +/** + * Thermal Protection parameters for the bed are just as above for hotends. + */ +#if ENABLED(THERMAL_PROTECTION_BED) + #define THERMAL_PROTECTION_BED_PERIOD 20 // Seconds + #define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius + + /** + * Whenever an M140 or M190 increases the target temperature the firmware will wait for the + * WATCH_BED_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_BED_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get too many "Heating failed" errors, increase WATCH_BED_TEMP_PERIOD and/or decrease + * WATCH_BED_TEMP_INCREASE. (WATCH_BED_TEMP_INCREASE should not be below 2.) + */ + #define WATCH_BED_TEMP_PERIOD 60 // Seconds + #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius +#endif + +#if ENABLED(PIDTEMP) + // this adds an experimental additional term to the heating power, proportional to the extrusion speed. + // if Kc is chosen well, the additional required power due to increased melting should be compensated. + //#define PID_EXTRUSION_SCALING + #if ENABLED(PID_EXTRUSION_SCALING) + #define DEFAULT_Kc (100) //heating power=Kc*(e_speed) + #define LPQ_MAX_LEN 50 + #endif +#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 + */ +#define AUTOTEMP +#if ENABLED(AUTOTEMP) + #define AUTOTEMP_OLDWEIGHT 0.98 +#endif + +// Show Temperature ADC value +// Enable for M105 to include ADC values read from temperature sensors. +//#define SHOW_TEMP_ADC_VALUES + +/** + * High Temperature Thermistor Support + * + * Thermistors able to support high temperature tend to have a hard time getting + * good readings at room and lower temperatures. This means HEATER_X_RAW_LO_TEMP + * will probably be caught when the heating element first turns on during the + * preheating process, which will trigger a min_temp_error as a safety measure + * and force stop everything. + * To circumvent this limitation, we allow for a preheat time (during which, + * min_temp_error won't be triggered) and add a min_temp buffer to handle + * aberrant readings. + * + * If you want to enable this feature for your hotend thermistor(s) + * uncomment and set values > 0 in the constants below + */ + +// The number of consecutive low temperature errors that can occur +// before a min_temp_error is triggered. (Shouldn't be more than 10.) +//#define MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED 0 + +// The number of milliseconds a hotend will preheat before starting to check +// the temperature. This value should NOT be set to the time it takes the +// hot end to reach the target temperature, but the time it takes to reach +// the minimum temperature your thermistor can read. The lower the better/safer. +// This shouldn't need to be more than 30 seconds (30000) +//#define MILLISECONDS_PREHEAT_TIME 0 + +// @section extruder + +// Extruder runout prevention. +// If the machine is idle and the temperature over MINTEMP +// then extrude some filament every couple of SECONDS. +//#define EXTRUDER_RUNOUT_PREVENT +#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_EXTRUDE 5 // mm +#endif + +// @section temperature + +//These defines help to calibrate the AD595 sensor in case you get wrong temperature measurements. +//The measured temperature is defined as "actualTemp = (measuredTemp * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET" +#define TEMP_SENSOR_AD595_OFFSET 0.0 +#define TEMP_SENSOR_AD595_GAIN 1.0 + +/** + * 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. + */ +//#define USE_CONTROLLER_FAN +#if ENABLED(USE_CONTROLLER_FAN) + //#define CONTROLLER_FAN_PIN FAN1_PIN // 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 +#endif + +// When first starting the main fan, run it at full speed for the +// given number of milliseconds. This gets the fan spinning reliably +// before setting a PWM value. (Does not work with software PWM for fan on Sanguinololu) +//#define FAN_KICKSTART_TIME 100 + +// This defines the minimal speed for the main fan, run in PWM mode +// to enable uncomment and set minimal PWM speed for reliable running (1-255) +// if fan speed is [1 - (FAN_MIN_PWM-1)] it is set to FAN_MIN_PWM +//#define FAN_MIN_PWM 50 + +// @section extruder + +/** + * Extruder cooling fans + * + * Extruder auto fans automatically turn on when their extruders' + * temperatures go above EXTRUDER_AUTO_FAN_TEMPERATURE. + * + * Your board's pins file specifies the recommended pins. Override those here + * or set to -1 to disable completely. + * + * Multiple extruders can be assigned to the same pin in which case + * the fan will turn on when any selected extruder is above the threshold. + */ +#define E0_AUTO_FAN_PIN -1 +#define E1_AUTO_FAN_PIN -1 +#define E2_AUTO_FAN_PIN -1 +#define E3_AUTO_FAN_PIN -1 +#define E4_AUTO_FAN_PIN -1 +#define EXTRUDER_AUTO_FAN_TEMPERATURE 50 +#define EXTRUDER_AUTO_FAN_SPEED 255 // == full speed + +/** + * Part-Cooling Fan Multiplexer + * + * This feature allows you to digitally multiplex the fan output. + * The multiplexer is automatically switched at tool-change. + * Set FANMUX[012]_PINs below for up to 2, 4, or 8 multiplexed fans. + */ +#define FANMUX0_PIN -1 +#define FANMUX1_PIN -1 +#define FANMUX2_PIN -1 + +/** + * M355 Case Light on-off / brightness + */ +//#define CASE_LIGHT_ENABLE +#if ENABLED(CASE_LIGHT_ENABLE) + //#define CASE_LIGHT_PIN 4 // Override the default pin if needed + #define INVERT_CASE_LIGHT false // Set true if Case Light is ON when pin is LOW + #define CASE_LIGHT_DEFAULT_ON true // Set default power-up state on + #define CASE_LIGHT_DEFAULT_BRIGHTNESS 105 // Set default power-up brightness (0-255, requires PWM pin) + //#define MENU_ITEM_CASE_LIGHT // Add a Case Light option to the LCD main menu +#endif + +//=========================================================================== +//============================ Mechanical Settings ========================== +//=========================================================================== + +// @section homing + +// If you want endstops to stay on (by default) even when not homing +// enable this option. Override at any time with M120, M121. +#define ENDSTOPS_ALWAYS_ON_DEFAULT + +// @section extras + +//#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. + +// Dual X Steppers +// Uncomment this option to drive two X axis motors. +// The next unused E driver will be assigned to the second X stepper. +//#define X_DUAL_STEPPER_DRIVERS +#if ENABLED(X_DUAL_STEPPER_DRIVERS) + // Set true if the two X motors need to rotate in opposite directions + #define INVERT_X2_VS_X_DIR true +#endif + +// Dual Y Steppers +// Uncomment this option to drive two Y axis motors. +// The next unused E driver will be assigned to the second Y stepper. +//#define Y_DUAL_STEPPER_DRIVERS +#if ENABLED(Y_DUAL_STEPPER_DRIVERS) + // Set true if the two Y motors need to rotate in opposite directions + #define INVERT_Y2_VS_Y_DIR true +#endif + +// A single Z stepper driver is usually used to drive 2 stepper motors. +// Uncomment this option to use a separate stepper driver for each Z axis motor. +// The next unused E driver will be assigned to the second Z stepper. +//#define Z_DUAL_STEPPER_DRIVERS + +#if ENABLED(Z_DUAL_STEPPER_DRIVERS) + + // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper. + // That way the machine is capable to align the bed during home, since both Z steppers are homed. + // There is also an implementation of M666 (software endstops adjustment) to this feature. + // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed. + // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2. + // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive. + // Play a little bit with small adjustments (0.5mm) and check the behaviour. + // The M119 (endstops report) will start reporting the Z2 Endstop as well. + + //#define Z_DUAL_ENDSTOPS + + #if ENABLED(Z_DUAL_ENDSTOPS) + #define Z2_USE_ENDSTOP _XMAX_ + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 // Use M666 to determine/test this value + #endif + +#endif // Z_DUAL_STEPPER_DRIVERS + +// Enable this for dual x-carriage printers. +// A dual x-carriage design has the advantage that the inactive extruder can be parked which +// prevents hot-end ooze contaminating the print. It also reduces the weight of each x-carriage +// allowing faster printing speeds. Connect your X2 stepper to the first unused E plug. +//#define DUAL_X_CARRIAGE +#if ENABLED(DUAL_X_CARRIAGE) + // Configuration for second X-carriage + // Note: the first x-carriage is defined as the x-carriage which homes to the minimum endstop; + // the second x-carriage always homes to the maximum endstop. + #define X2_MIN_POS 80 // set minimum to ensure second x-carriage doesn't hit the parked first X-carriage + #define X2_MAX_POS 353 // set maximum to the distance between toolheads when both heads are homed + #define X2_HOME_DIR 1 // the second X-carriage always homes to the maximum endstop position + #define X2_HOME_POS X2_MAX_POS // default home position is the maximum carriage position + // However: In this mode the HOTEND_OFFSET_X value for the second extruder provides a software + // override for X2_HOME_POS. This also allow recalibration of the distance between the two endstops + // without modifying the firmware (through the "M218 T1 X???" command). + // Remember: you should set the second extruder x-offset to 0 in your slicer. + + // There are a few selectable movement modes for dual x-carriages using M605 S + // Mode 0 (DXC_FULL_CONTROL_MODE): Full control. The slicer has full control over both x-carriages and can achieve optimal travel results + // as long as it supports dual x-carriages. (M605 S0) + // Mode 1 (DXC_AUTO_PARK_MODE) : Auto-park mode. The firmware will automatically park and unpark the x-carriages on tool changes so + // that additional slicer support is not required. (M605 S1) + // Mode 2 (DXC_DUPLICATION_MODE) : Duplication mode. The firmware will transparently make the second x-carriage and extruder copy all + // actions of the first x-carriage. This allows the printer to print 2 arbitrary items at + // once. (2nd extruder x offset and temp offset are set using: M605 S2 [Xnnn] [Rmmm]) + + // This is the default power-up mode which can be later using M605. + #define DEFAULT_DUAL_X_CARRIAGE_MODE DXC_FULL_CONTROL_MODE + + // Default settings in "Auto-park Mode" + #define TOOLCHANGE_PARK_ZLIFT 0.2 // the distance to raise Z axis when parking an extruder + #define TOOLCHANGE_UNPARK_ZLIFT 1 // the distance to raise Z axis when unparking an extruder + + // Default x offset in duplication mode (typically set to half print bed width) + #define DEFAULT_DUPLICATION_X_OFFSET 100 + +#endif // DUAL_X_CARRIAGE + +// 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. +//#define EXT_SOLENOID + +// @section homing + +//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +#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 this is defined, if both x and y are to be homed, a diagonal move will be performed initially. + +// When G28 is called, this option will make Y home before X +//#define HOME_Y_BEFORE_X + +// @section machine + +#define AXIS_RELATIVE_MODES {false, false, false, false} + +// Allow duplication mode with a basic dual-nozzle extruder +//#define DUAL_NOZZLE_DUPLICATION_MODE + +// By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step. +#define INVERT_X_STEP_PIN false +#define INVERT_Y_STEP_PIN false +#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. +#define DEFAULT_STEPPER_DEACTIVE_TIME 60 +#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_E true + +#define DEFAULT_MINIMUMFEEDRATE 0.0 // minimum feedrate +#define DEFAULT_MINTRAVELFEEDRATE 0.0 + +//#define HOME_AFTER_DEACTIVATE // Require rehoming after steppers are deactivated + +// @section lcd + +#if ENABLED(ULTIPANEL) + #define MANUAL_FEEDRATE {120*60, 120*60, 18*60, 60} // Feedrates for manual moves along X, Y, Z, E from panel + #define ULTIPANEL_FEEDMULTIPLY // Comment to disable setting feedrate multiplier via encoder +#endif + +// @section extras + +// minimum time in microseconds that a movement needs to take if the buffer is emptied. +#define DEFAULT_MINSEGMENTTIME 20000 + +// If defined the movements slow down when the look ahead buffer is only half full +#define SLOWDOWN + +// Frequency limit +// See nophead's blog for more info +// Not working O +//#define XY_FREQUENCY_LIMIT 15 + +// 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 +// if unwanted behavior is observed on a user's machine when running at very slow speeds. +#define MINIMUM_PLANNER_SPEED 0.05 // (mm/sec) + +// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU. +#define MICROSTEP_MODES {16,16,16,16,16} // [1,2,4,8,16] + +/** + * @section stepper motor current + * + * Some boards have a means of setting the stepper motor current via firmware. + * + * The power on motor currents are set by: + * PWM_MOTOR_CURRENT - used by MINIRAMBO & ULTIMAIN_2 + * known compatible chips: A4982 + * DIGIPOT_MOTOR_CURRENT - used by BQ_ZUM_MEGA_3D, RAMBO & SCOOVO_X9H + * known compatible chips: AD5206 + * DAC_MOTOR_CURRENT_DEFAULT - used by PRINTRBOARD_REVF & RIGIDBOARD_V2 + * known compatible chips: MCP4728 + * DIGIPOT_I2C_MOTOR_CURRENTS - used by 5DPRINT, AZTEEG_X3_PRO, MIGHTYBOARD_REVE + * known compatible chips: MCP4451, MCP4018 + * + * Motor currents can also be set by M907 - M910 and by the LCD. + * M907 - applies to all. + * M908 - BQ_ZUM_MEGA_3D, RAMBO, PRINTRBOARD_REVF, RIGIDBOARD_V2 & SCOOVO_X9H + * M909, M910 & LCD - only PRINTRBOARD_REVF & RIGIDBOARD_V2 + */ +//#define PWM_MOTOR_CURRENT { 1300, 1300, 1250 } // Values in milliamps +//#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 + +// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +//#define DIGIPOT_I2C +//#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster +#define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 +// Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS +#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=========================== +//=========================================================================== + +#define ENCODER_RATE_MULTIPLIER // If defined, certain menu edit operations automatically multiply the steps when the encoder is moved quickly +#define ENCODER_10X_STEPS_PER_SEC 75 // If the encoder steps per sec exceeds this value, multiply steps moved x10 to quickly advance the value +#define ENCODER_100X_STEPS_PER_SEC 160 // If the encoder steps per sec exceeds this value, multiply steps moved x100 to really quickly advance the value + +//#define CHDK 4 //Pin for triggering CHDK to take a picture see how to use it here http://captain-slow.dk/2014/03/09/3d-printing-timelapses/ +#define CHDK_DELAY 50 //How long in ms the pin should stay HIGH before going LOW again + +// @section lcd + +// Include a page of printer information in the LCD Main Menu +//#define LCD_INFO_MENU + +// Scroll a longer status message into view +//#define STATUS_MESSAGE_SCROLLING + +// On the Info Screen, display XY with one decimal place when possible +//#define LCD_DECIMAL_SMALL_XY + +// The timeout (in ms) to return to the status screen from sub-menus +//#define LCD_TIMEOUT_TO_STATUS 15000 + +#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 + + #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? + #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. + + #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. + // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. + // using: + //#define MENU_ADDAUTOSTART + + /** + * Sort SD file listings in alphabetical order. + * + * With this option enabled, items on SD cards will be sorted + * by name for easier navigation. + * + * By default... + * + * - Use the slowest -but safest- method for sorting. + * - Folders are sorted to the top. + * - The sort key is statically allocated. + * - No added G-code (M34) support. + * - 40 item sorting limit. (Items after the first 40 are unsorted.) + * + * SD sorting uses static allocation (as set by SDSORT_LIMIT), allowing the + * compiler to calculate the worst-case usage and throw an error if the SRAM + * limit is exceeded. + * + * - SDSORT_USES_RAM provides faster sorting via a static directory buffer. + * - SDSORT_USES_STACK does the same, but uses a local stack-based buffer. + * - SDSORT_CACHE_NAMES will retain the sorted file listing in RAM. (Expensive!) + * - SDSORT_DYNAMIC_RAM only uses RAM when the SD menu is visible. (Use with caution!) + */ + //#define SDCARD_SORT_ALPHA + + // SD Card Sorting options + #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_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. + #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #endif + + // Show a progress bar on HD44780 LCDs for SD printing + //#define LCD_PROGRESS_BAR + + #if ENABLED(LCD_PROGRESS_BAR) + // Amount of time (ms) to show the bar + #define PROGRESS_BAR_BAR_TIME 2000 + // Amount of time (ms) to show the status message + #define PROGRESS_BAR_MSG_TIME 3000 + // Amount of time (ms) to retain the status message (0=forever) + #define PROGRESS_MSG_EXPIRE 0 + // Enable this to show messages for MSG_TIME then hide them + //#define PROGRESS_MSG_ONCE + // Add a menu item to test the progress bar: + //#define LCD_PROGRESS_BAR_TEST + #endif + + // This allows hosts to request long names for files and folders with M33 + //#define LONG_FILENAME_HOST_SUPPORT + + // This option allows you to abort SD printing when any endstop is triggered. + // This feature must be enabled with "M540 S1" or from the LCD menu. + // To have any effect, endstops must be enabled during SD printing. + //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + +#endif // SDSUPPORT + +/** + * Additional options for Graphical Displays + * + * Use the optimizations here to improve printing performance, + * which can be adversely affected by graphical display drawing, + * especially when doing several short moves, and when printing + * on DELTA and SCARA machines. + * + * Some of these options may result in the display lagging behind + * controller events, as there is a trade-off between reliable + * printing performance versus fast display updates. + */ +#if ENABLED(DOGLCD) + // Enable to save many cycles by drawing a hollow frame on the Info Screen + #define XYZ_HOLLOW_FRAME + + // Enable to save many cycles by drawing a hollow frame on Menu Screens + #define MENU_HOLLOW_FRAME + + // A bigger font is available for edit items. Costs 3120 bytes of PROGMEM. + // 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. + // 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 +#endif // DOGLCD + +// @section safety + +// The hardware watchdog should reset the microcontroller disabling all outputs, +// in case the firmware gets stuck and doesn't do temperature regulation. +#define USE_WATCHDOG + +#if ENABLED(USE_WATCHDOG) + // If you have a watchdog reboot in an ArduinoMega2560 then the device will hang forever, as a watchdog reset will leave the watchdog on. + // The "WATCHDOG_RESET_MANUAL" goes around this by not using the hardware reset. + // However, THIS FEATURE IS UNSAFE!, as it will only work if interrupts are disabled. And the code could hang in an interrupt routine with interrupts disabled. + //#define WATCHDOG_RESET_MANUAL +#endif + +// @section lcd + +/** + * Babystepping enables movement of the axes by tiny increments without changing + * the current position values. This feature is used primarily to adjust the Z + * axis in the first layer of a print in real-time. + * + * Warning: Does not respect endstops! + */ +//#define BABYSTEPPING +#if ENABLED(BABYSTEPPING) + //#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 100 // Babysteps are very small. Increase for faster motion. + //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping + //#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen 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_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor + //#define BABYSTEP_ZPROBE_GFX_REVERSE // Reverses the direction of the CW/CCW indicators +#endif + +// @section extruder + +/** + * Implementation of linear pressure control + * + * Assumption: advance = k * (delta velocity) + * K=0 means advance disabled. + * See Marlin documentation for calibration instructions. + */ +//#define LIN_ADVANCE + +#if ENABLED(LIN_ADVANCE) + #define LIN_ADVANCE_K 75 + + /** + * Some Slicers produce Gcode with randomly jumping extrusion widths occasionally. + * For example within a 0.4mm perimeter it may produce a single segment of 0.05mm width. + * While this is harmless for normal printing (the fluid nature of the filament will + * close this very, very tiny gap), it throws off the LIN_ADVANCE pressure adaption. + * + * For this case LIN_ADVANCE_E_D_RATIO can be used to set the extrusion:distance ratio + * to a fixed value. Note that using a fixed ratio will lead to wrong nozzle pressures + * if the slicer is using variable widths or layer heights within one print! + * + * This option sets the default E:D ratio at startup. Use `M900` to override this value. + * + * Example: `M900 W0.4 H0.2 D1.75`, where: + * - W is the extrusion width in mm + * - H is the layer height in mm + * - D is the filament diameter in mm + * + * Example: `M900 R0.0458` to set the ratio directly. + * + * Set to 0 to auto-detect the ratio based on given Gcode G1 print moves. + * + * Slic3r (including Průša Control) produces Gcode compatible with the automatic mode. + * Cura (as of this writing) may produce Gcode incompatible with the automatic mode. + */ + #define LIN_ADVANCE_E_D_RATIO 0 // The calculated ratio (or 0) according to the formula W * H / ((D / 2) ^ 2 * PI) + // Example: 0.4 * 0.2 / ((1.75 / 2) ^ 2 * PI) = 0.033260135 +#endif + +// @section leveling + +// Default mesh area is an area with an inset margin on the print area. +// Below are the macros that are used to define the borders for the mesh area, +// made available here for specialized needs, ie dual extruder setup. +#if ENABLED(MESH_BED_LEVELING) + #define MESH_MIN_X MESH_INSET + #define MESH_MAX_X (X_BED_SIZE - (MESH_INSET)) + #define MESH_MIN_Y MESH_INSET + #define MESH_MAX_Y (Y_BED_SIZE - (MESH_INSET)) +#elif ENABLED(AUTO_BED_LEVELING_UBL) + #define UBL_MESH_MIN_X UBL_MESH_INSET + #define UBL_MESH_MAX_X (X_BED_SIZE - (UBL_MESH_INSET)) + #define UBL_MESH_MIN_Y UBL_MESH_INSET + #define UBL_MESH_MAX_Y (Y_BED_SIZE - (UBL_MESH_INSET)) + + // If this is defined, the currently active mesh will be saved in the + // current slot on M500. + #define UBL_SAVE_ACTIVE_ON_M500 +#endif + +// @section extras + +// +// G2/G3 Arc Support +// +#define ARC_SUPPORT // Disable this feature to save ~3226 bytes +#if ENABLED(ARC_SUPPORT) + #define MM_PER_ARC_SEGMENT 1 // Length of each arc segment + #define N_ARC_CORRECTION 25 // Number of intertpolated 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 +#endif + +// Support for G5 with XYZE destination and IJPQ offsets. Requires ~2666 bytes. +//#define BEZIER_CURVE_SUPPORT + +// G38.2 and G38.3 Probe Target +// Enable PROBE_DOUBLE_TOUCH if you want G38 to double touch +//#define G38_PROBE_TARGET +#if ENABLED(G38_PROBE_TARGET) + #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) +#endif + +// Moves (or segments) with fewer steps than this will be joined with the next move +#define MIN_STEPS_PER_SEGMENT 6 + +// The minimum pulse width (in µs) for stepping a stepper. +// Set this if you find stepping unreliable, or if using a very fast CPU. +#define MINIMUM_STEPPER_PULSE 0 // (µs) The smallest stepper pulse allowed + +// @section temperature + +// Control heater 0 and heater 1 in parallel. +//#define HEATERS_PARALLEL + +//=========================================================================== +//================================= Buffers ================================= +//=========================================================================== + +// @section hidden + +// 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, i.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 +#else + #define BLOCK_BUFFER_SIZE 16 // maximize block buffer +#endif + +// @section serial + +// The ASCII buffer for serial input +#define MAX_CMD_SIZE 96 +#define BUFSIZE 4 + +// Transmission to Host Buffer Size +// To save 386 bytes of PROGMEM (and TX_BUFFER_SIZE+3 bytes of RAM) set to 0. +// To buffer a simple "ok" you need 4 bytes. +// For ADVANCED_OK (M105) you need 32 bytes. +// For debug-echo: 128 bytes for the optimal speed. +// Other output doesn't need to be that speedy. +// :[0, 2, 4, 8, 16, 32, 64, 128, 256] +#define TX_BUFFER_SIZE 0 + +// Host Receive Buffer Size +// Without XON/XOFF flow control (see SERIAL_XON_XOFF below) 32 bytes should be enough. +// To use flow control, set this buffer size to at least 1024 bytes. +// :[0, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048] +//#define RX_BUFFER_SIZE 1024 + +#if RX_BUFFER_SIZE >= 1024 + // Enable to have the controller send XON/XOFF control characters to + // the host to signal the RX buffer is becoming full. + //#define SERIAL_XON_XOFF +#endif + +#if ENABLED(SDSUPPORT) + // Enable this option to collect and display the maximum + // RX queue usage after transferring a file to SD. + //#define SERIAL_STATS_MAX_RX_QUEUED + + // Enable this option to collect and display the number + // of dropped bytes after a file transfer to SD. + //#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! +//#define EMERGENCY_PARSER + +// Bad Serial-connections can miss a received command by sending an 'ok' +// Therefore some clients abort after 30 seconds in a timeout. +// Some other clients start sending commands while receiving a 'wait'. +// This "wait" is only sent when the buffer is empty. 1 second is a good value here. +//#define NO_TIMEOUTS 1000 // Milliseconds + +// Some clients will have this feature soon. This could make the NO_TIMEOUTS unnecessary. +//#define ADVANCED_OK + +// @section extras + +/** + * Firmware-based and LCD-controlled retract + * + * Add G10 / G11 commands for automatic firmware-based retract / recover. + * Use M207 and M208 to define parameters for retract / recover. + * + * Use M209 to enable or disable auto-retract. + * With auto-retract enabled, all G1 E moves within the set range + * will be converted to firmware-based retract/recover moves. + * + * Be sure to turn off auto-retract during filament change. + * + * Note that M207 / M208 / M209 settings are saved to EEPROM. + * + */ +//#define FWRETRACT // ONLY PARTIALLY TESTED +#if ENABLED(FWRETRACT) + #define MIN_AUTORETRACT 0.1 // When auto-retract is on, convert E moves of this length and over + #define MAX_AUTORETRACT 10.0 // Upper limit for auto-retract conversion + #define RETRACT_LENGTH 3 // Default retract length (positive mm) + #define RETRACT_LENGTH_SWAP 13 // Default swap retract length (positive mm), for extruder change + #define RETRACT_FEEDRATE 45 // Default feedrate for retracting (mm/s) + #define RETRACT_ZLIFT 0 // Default retract Z-lift + #define RETRACT_RECOVER_LENGTH 0 // Default additional recover length (mm, added to retract length when recovering) + #define RETRACT_RECOVER_LENGTH_SWAP 0 // Default additional swap recover length (mm, added to retract length when recovering from extruder change) + #define RETRACT_RECOVER_FEEDRATE 8 // Default feedrate for recovering from retraction (mm/s) + #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) +#endif + +/** + * Advanced Pause + * Experimental feature for filament change support and for parking the nozzle when paused. + * Adds the GCode M600 for initiating filament change. + * If PARK_HEAD_ON_PAUSE enabled, adds the GCode M125 to pause printing and park the nozzle. + * + * Requires an LCD display. + * This feature is required for the default FILAMENT_RUNOUT_SCRIPT. + */ +//#define ADVANCED_PAUSE_FEATURE +#if ENABLED(ADVANCED_PAUSE_FEATURE) + #define PAUSE_PARK_X_POS 3 // X position of hotend + #define PAUSE_PARK_Y_POS 3 // Y position of hotend + #define PAUSE_PARK_Z_ADD 10 // Z addition of hotend (lift) + #define PAUSE_PARK_XY_FEEDRATE 100 // X and Y axes feedrate in mm/s (also used for delta printers Z axis) + #define PAUSE_PARK_Z_FEEDRATE 5 // Z axis feedrate in mm/s (not used for delta printers) + #define PAUSE_PARK_RETRACT_FEEDRATE 60 // Initial retract feedrate in mm/s + #define PAUSE_PARK_RETRACT_LENGTH 2 // Initial retract in mm + // It is a short retract used immediately after print interrupt before move to filament exchange position + #define FILAMENT_CHANGE_UNLOAD_FEEDRATE 10 // Unload filament feedrate in mm/s - filament unloading can be fast + #define FILAMENT_CHANGE_UNLOAD_LENGTH 100 // Unload filament length from hotend in mm + // Longer length for bowden printers to unload filament from whole bowden tube, + // shorter length for printers without bowden to unload filament from extruder only, + // 0 to disable unloading for manual unloading + #define FILAMENT_CHANGE_LOAD_FEEDRATE 6 // Load filament feedrate in mm/s - filament loading into the bowden tube can be fast + #define FILAMENT_CHANGE_LOAD_LENGTH 0 // Load filament length over hotend in mm + // Longer length for bowden printers to fast load filament into whole bowden tube over the hotend, + // Short or zero length for printers without bowden where loading is not used + #define ADVANCED_PAUSE_EXTRUDE_FEEDRATE 3 // Extrude filament feedrate in mm/s - must be slower than load feedrate + #define ADVANCED_PAUSE_EXTRUDE_LENGTH 50 // Extrude filament length in mm after filament is loaded over the hotend, + // 0 to disable for manual extrusion + // Filament can be extruded repeatedly from the filament exchange menu to fill the hotend, + // or until outcoming filament color is not clear for filament color change + #define PAUSE_PARK_NOZZLE_TIMEOUT 45 // Turn off nozzle if user doesn't change filament within this time limit in seconds + #define FILAMENT_CHANGE_NUMBER_OF_ALERT_BEEPS 5 // Number of alert beeps before printer goes quiet + #define PAUSE_PARK_NO_STEPPER_TIMEOUT // Enable to have stepper motors hold position during filament change + // even if it takes longer than DEFAULT_STEPPER_DEACTIVE_TIME. + //#define PARK_HEAD_ON_PAUSE // Go to filament change position on pause, return to print position on resume + //#define HOME_BEFORE_FILAMENT_CHANGE // Ensure homing has been completed prior to parking for filament change +#endif + +// @section tmc + +/** + * Enable this section if you have TMC26X motor drivers. + * You will need to import the TMC26XStepper library into the Arduino IDE for this + * (https://github.com/trinamic/TMC26XStepper.git) + */ +//#define HAVE_TMCDRIVER + +#if ENABLED(HAVE_TMCDRIVER) + + //#define X_IS_TMC + //#define X2_IS_TMC + //#define Y_IS_TMC + //#define Y2_IS_TMC + //#define Z_IS_TMC + //#define Z2_IS_TMC + //#define E0_IS_TMC + //#define E1_IS_TMC + //#define E2_IS_TMC + //#define E3_IS_TMC + //#define E4_IS_TMC + + #define X_MAX_CURRENT 1000 // in mA + #define X_SENSE_RESISTOR 91 // in mOhms + #define X_MICROSTEPS 16 // number of microsteps + + #define X2_MAX_CURRENT 1000 + #define X2_SENSE_RESISTOR 91 + #define X2_MICROSTEPS 16 + + #define Y_MAX_CURRENT 1000 + #define Y_SENSE_RESISTOR 91 + #define Y_MICROSTEPS 16 + + #define Y2_MAX_CURRENT 1000 + #define Y2_SENSE_RESISTOR 91 + #define Y2_MICROSTEPS 16 + + #define Z_MAX_CURRENT 1000 + #define Z_SENSE_RESISTOR 91 + #define Z_MICROSTEPS 16 + + #define Z2_MAX_CURRENT 1000 + #define Z2_SENSE_RESISTOR 91 + #define Z2_MICROSTEPS 16 + + #define E0_MAX_CURRENT 1000 + #define E0_SENSE_RESISTOR 91 + #define E0_MICROSTEPS 16 + + #define E1_MAX_CURRENT 1000 + #define E1_SENSE_RESISTOR 91 + #define E1_MICROSTEPS 16 + + #define E2_MAX_CURRENT 1000 + #define E2_SENSE_RESISTOR 91 + #define E2_MICROSTEPS 16 + + #define E3_MAX_CURRENT 1000 + #define E3_SENSE_RESISTOR 91 + #define E3_MICROSTEPS 16 + + #define E4_MAX_CURRENT 1000 + #define E4_SENSE_RESISTOR 91 + #define E4_MICROSTEPS 16 + +#endif + +// @section TMC2130 + +/** + * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. + * + * You'll also need the TMC2130Stepper Arduino library + * (https://github.com/teemuatlut/TMC2130Stepper). + * + * To use TMC2130 stepper drivers in SPI mode connect your SPI2130 pins to + * the hardware SPI interface on your board and define the required CS pins + * in your `pins_MYBOARD.h` file. (e.g., RAMPS 1.4 uses AUX3 pins `X_CS_PIN 53`, `Y_CS_PIN 49`, etc.). + */ +//#define HAVE_TMC2130 + +#if ENABLED(HAVE_TMC2130) + + // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY + //#define X_IS_TMC2130 + //#define X2_IS_TMC2130 + //#define Y_IS_TMC2130 + //#define Y2_IS_TMC2130 + //#define Z_IS_TMC2130 + //#define Z2_IS_TMC2130 + //#define E0_IS_TMC2130 + //#define E1_IS_TMC2130 + //#define E2_IS_TMC2130 + //#define E3_IS_TMC2130 + //#define E4_IS_TMC2130 + + /** + * Stepper driver settings + */ + + #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 + #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current + #define INTERPOLATE 1 // Interpolate X/Y/Z_MICROSTEPS to 256 + + #define X_CURRENT 1000 // rms current in mA. Multiply by 1.41 for peak current. + #define X_MICROSTEPS 16 // 0..256 + + #define Y_CURRENT 1000 + #define Y_MICROSTEPS 16 + + #define Z_CURRENT 1000 + #define Z_MICROSTEPS 16 + + //#define X2_CURRENT 1000 + //#define X2_MICROSTEPS 16 + + //#define Y2_CURRENT 1000 + //#define Y2_MICROSTEPS 16 + + //#define Z2_CURRENT 1000 + //#define Z2_MICROSTEPS 16 + + //#define E0_CURRENT 1000 + //#define E0_MICROSTEPS 16 + + //#define E1_CURRENT 1000 + //#define E1_MICROSTEPS 16 + + //#define E2_CURRENT 1000 + //#define E2_MICROSTEPS 16 + + //#define E3_CURRENT 1000 + //#define E3_MICROSTEPS 16 + + //#define E4_CURRENT 1000 + //#define E4_MICROSTEPS 16 + + /** + * Use Trinamic's ultra quiet stepping mode. + * When disabled, Marlin will use spreadCycle stepping mode. + */ + #define STEALTHCHOP + + /** + * Let Marlin automatically control stepper current. + * This is still an experimental feature. + * Increase current every 5s by CURRENT_STEP until stepper temperature prewarn gets triggered, + * then decrease current by CURRENT_STEP until temperature prewarn is cleared. + * Adjusting starts from X/Y/Z/E_CURRENT but will not increase over AUTO_ADJUST_MAX + * 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. + * M906 S1 - Start adjusting current + * M906 S0 - Stop adjusting current + * M911 - Report stepper driver overtemperature pre-warn condition. + * M912 - Clear stepper driver overtemperature pre-warn condition flag. + */ + //#define AUTOMATIC_CURRENT_CONTROL + + #if ENABLED(AUTOMATIC_CURRENT_CONTROL) + #define CURRENT_STEP 50 // [mA] + #define AUTO_ADJUST_MAX 1300 // [mA], 1300mA_rms = 1840mA_peak + #define REPORT_CURRENT_CHANGE + #endif + + /** + * The driver will switch to spreadCycle when stepper speed is over HYBRID_THRESHOLD. + * This mode allows for faster movements at the expense of higher noise levels. + * STEALTHCHOP needs to be enabled. + * M913 X/Y/Z/E to live tune the setting + */ + //#define HYBRID_THRESHOLD + + #define X_HYBRID_THRESHOLD 100 // [mm/s] + #define X2_HYBRID_THRESHOLD 100 + #define Y_HYBRID_THRESHOLD 100 + #define Y2_HYBRID_THRESHOLD 100 + #define Z_HYBRID_THRESHOLD 4 + #define Z2_HYBRID_THRESHOLD 4 + #define E0_HYBRID_THRESHOLD 30 + #define E1_HYBRID_THRESHOLD 30 + #define E2_HYBRID_THRESHOLD 30 + #define E3_HYBRID_THRESHOLD 30 + #define E4_HYBRID_THRESHOLD 30 + + /** + * Use stallGuard2 to sense an obstacle and trigger an endstop. + * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. + * If used along with STEALTHCHOP, the movement will be louder when homing. This is normal. + * + * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. + * Higher values make the system LESS sensitive. + * Lower value make the system MORE sensitive. + * Too low values can lead to false positives, while too high values will collide the axis without triggering. + * It is advised to set X/Y_HOME_BUMP_MM to 0. + * M914 X/Y to live tune the setting + */ + //#define SENSORLESS_HOMING + + #if ENABLED(SENSORLESS_HOMING) + #define X_HOMING_SENSITIVITY 19 + #define Y_HOMING_SENSITIVITY 19 + #endif + + /** + * You can set your own advanced settings by filling in predefined functions. + * A list of available functions can be found on the library github page + * https://github.com/teemuatlut/TMC2130Stepper + * + * Example: + * #define TMC2130_ADV() { \ + * stepperX.diag0_temp_prewarn(1); \ + * stepperX.interpolate(0); \ + * } + */ + #define TMC2130_ADV() { } + +#endif // HAVE_TMC2130 + +// @section L6470 + +/** + * Enable this section if you have L6470 motor drivers. + * You need to import the L6470 library into the Arduino IDE for this. + * (https://github.com/ameyer/Arduino-L6470) + */ + +//#define HAVE_L6470DRIVER +#if ENABLED(HAVE_L6470DRIVER) + + //#define X_IS_L6470 + //#define X2_IS_L6470 + //#define Y_IS_L6470 + //#define Y2_IS_L6470 + //#define Z_IS_L6470 + //#define Z2_IS_L6470 + //#define E0_IS_L6470 + //#define E1_IS_L6470 + //#define E2_IS_L6470 + //#define E3_IS_L6470 + //#define E4_IS_L6470 + + #define X_MICROSTEPS 16 // number of microsteps + #define X_K_VAL 50 // 0 - 255, Higher values, are higher power. Be careful not to go too high + #define X_OVERCURRENT 2000 // maxc current in mA. If the current goes over this value, the driver will switch off + #define X_STALLCURRENT 1500 // current in mA where the driver will detect a stall + + #define X2_MICROSTEPS 16 + #define X2_K_VAL 50 + #define X2_OVERCURRENT 2000 + #define X2_STALLCURRENT 1500 + + #define Y_MICROSTEPS 16 + #define Y_K_VAL 50 + #define Y_OVERCURRENT 2000 + #define Y_STALLCURRENT 1500 + + #define Y2_MICROSTEPS 16 + #define Y2_K_VAL 50 + #define Y2_OVERCURRENT 2000 + #define Y2_STALLCURRENT 1500 + + #define Z_MICROSTEPS 16 + #define Z_K_VAL 50 + #define Z_OVERCURRENT 2000 + #define Z_STALLCURRENT 1500 + + #define Z2_MICROSTEPS 16 + #define Z2_K_VAL 50 + #define Z2_OVERCURRENT 2000 + #define Z2_STALLCURRENT 1500 + + #define E0_MICROSTEPS 16 + #define E0_K_VAL 50 + #define E0_OVERCURRENT 2000 + #define E0_STALLCURRENT 1500 + + #define E1_MICROSTEPS 16 + #define E1_K_VAL 50 + #define E1_OVERCURRENT 2000 + #define E1_STALLCURRENT 1500 + + #define E2_MICROSTEPS 16 + #define E2_K_VAL 50 + #define E2_OVERCURRENT 2000 + #define E2_STALLCURRENT 1500 + + #define E3_MICROSTEPS 16 + #define E3_K_VAL 50 + #define E3_OVERCURRENT 2000 + #define E3_STALLCURRENT 1500 + + #define E4_MICROSTEPS 16 + #define E4_K_VAL 50 + #define E4_OVERCURRENT 2000 + #define E4_STALLCURRENT 1500 + +#endif + +/** + * TWI/I2C BUS + * + * This feature is an EXPERIMENTAL feature so it shall not be used on production + * machines. Enabling this will allow you to send and receive I2C data from slave + * devices on the bus. + * + * ; Example #1 + * ; This macro send the string "Marlin" to the slave device with address 0x63 (99) + * ; It uses multiple M260 commands with one B arg + * M260 A99 ; Target slave address + * M260 B77 ; M + * M260 B97 ; a + * M260 B114 ; r + * M260 B108 ; l + * M260 B105 ; i + * M260 B110 ; n + * M260 S1 ; Send the current buffer + * + * ; Example #2 + * ; Request 6 bytes from slave device with address 0x63 (99) + * M261 A99 B5 + * + * ; Example #3 + * ; Example serial output of a M261 request + * echo:i2c-reply: from:99 bytes:5 data:hello + */ + +// @section i2cbus + +//#define EXPERIMENTAL_I2CBUS +#define I2C_SLAVE_ADDRESS 0 // Set a value from 8 to 127 to act as a slave + +// @section extras + +/** + * Spindle & Laser control + * + * Add the M3, M4, and M5 commands to turn the spindle/laser on and off, and + * to set spindle speed, spindle direction, and laser power. + * + * SuperPid is a router/spindle speed controller used in the CNC milling community. + * Marlin can be used to turn the spindle on and off. It can also be used to set + * the spindle speed from 5,000 to 30,000 RPM. + * + * 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. + */ +//#define SPINDLE_LASER_ENABLE +#if ENABLED(SPINDLE_LASER_ENABLE) + + #define SPINDLE_LASER_ENABLE_INVERT false // set to "true" if the on/off function is reversed + #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 // delay in milliseconds to allow the spindle/laser to come up to speed/power + #define SPINDLE_LASER_POWERDOWN_DELAY 5000 // delay in milliseconds to allow the spindle to stop + #define SPINDLE_DIR_CHANGE true // set to true if your spindle controller supports changing spindle direction + #define SPINDLE_INVERT_DIR false + #define SPINDLE_STOP_ON_DIR_CHANGE true // set to true if Marlin should stop the spindle before changing rotation direction + + /** + * The M3 & M4 commands use the following equation to convert PWM duty cycle to speed/power + * + * SPEED/POWER = PWM duty cycle * SPEED_POWER_SLOPE + SPEED_POWER_INTERCEPT + * where PWM duty cycle varies from 0 to 255 + * + * set the following for your controller (ALL MUST BE SET) + */ + + #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_SLOPE 0.3922 + //#define SPEED_POWER_INTERCEPT 0 + //#define SPEED_POWER_MIN 10 + //#define SPEED_POWER_MAX 100 // 0-100% +#endif + +/** + * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins + */ +//#define PINS_DEBUGGING + +/** + * Auto-report temperatures with M155 S + */ +#define AUTO_REPORT_TEMPERATURES + +/** + * Include capabilities in M115 output + */ +#define EXTENDED_CAPABILITIES_REPORT + +/** + * Volumetric extrusion default state + * 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. + */ +//#define VOLUMETRIC_DEFAULT_ON + +/** + * Enable this option for a leaner build of Marlin that removes all + * workspace offsets, simplifying coordinate transformations, leveling, etc. + * + * - M206 and M428 are disabled. + * - G92 will revert to its behavior from Marlin 1.0. + */ +//#define NO_WORKSPACE_OFFSETS + +/** + * 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. + * + * For clients that use a fixed-width font (like OctoPrint), leave this set to 1.0. + * Otherwise, adjust according to your client and font. + */ +#define PROPORTIONAL_FONT_RATIO 1.0 + +/** + * Spend 28 bytes of SRAM to optimize the GCode parser + */ +#define FASTER_GCODE_PARSER + +/** + * User-defined menu items that execute custom GCode + */ +//#define CUSTOM_USER_MENUS +#if ENABLED(CUSTOM_USER_MENUS) + #define USER_SCRIPT_DONE "M117 User Script Done" + #define USER_SCRIPT_AUDIBLE_FEEDBACK + //#define USER_SCRIPT_RETURN // Return to status screen after a script + + #define USER_DESC_1 "Home & UBL Info" + #define USER_GCODE_1 "G28\nG29 W" + + #define USER_DESC_2 "Preheat for PLA" + #define USER_GCODE_2 "M140 S" STRINGIFY(PREHEAT_1_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND) + + #define USER_DESC_3 "Preheat for ABS" + #define USER_GCODE_3 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND) + + #define USER_DESC_4 "Heat Bed/Home/Level" + #define USER_GCODE_4 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nG28\nG29" + + //#define USER_DESC_5 "Home & Info" + //#define USER_GCODE_5 "G28\nM503" +#endif + +/** + * Specify an action command to send to the host when the printer is killed. + * Will be sent in the form '//action:ACTION_ON_KILL', e.g. '//action:poweroff'. + * The host must be configured to handle the action command. + */ +//#define ACTION_ON_KILL "poweroff" + +//=========================================================================== +//====================== I2C Position Encoder Settings ====================== +//=========================================================================== + +/** + * I2C position encoders for closed loop control. + * Developed by Chris Barr at Aus3D. + * + * Wiki: http://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/ + * + * Reilabuild encoders have been modified to improve reliability. + */ + +//#define I2C_POSITION_ENCODERS +#if ENABLED(I2C_POSITION_ENCODERS) + + #define I2CPE_ENCODER_CNT 1 // The number of encoders installed; max of 5 + // encoders supported currently. + + #define I2CPE_ENC_1_ADDR I2CPE_PRESET_ADDR_X // I2C address of the encoder. 30-200. + #define I2CPE_ENC_1_AXIS X_AXIS // Axis the encoder module is installed on. _AXIS. + #define I2CPE_ENC_1_TYPE I2CPE_ENC_TYPE_LINEAR // Type of encoder: I2CPE_ENC_TYPE_LINEAR -or- + // I2CPE_ENC_TYPE_ROTARY. + #define I2CPE_ENC_1_TICKS_UNIT 2048 // 1024 for magnetic strips with 2mm poles; 2048 for + // 1mm poles. For linear encoders this is ticks / mm, + // for rotary encoders this is ticks / revolution. + //#define I2CPE_ENC_1_TICKS_REV (16 * 200) // Only needed for rotary encoders; number of stepper + // steps per full revolution (motor steps/rev * microstepping) + //#define I2CPE_ENC_1_INVERT // Invert the direction of axis travel. + #define I2CPE_ENC_1_EC_METHOD I2CPE_ECM_NONE // Type of error error correction. + #define I2CPE_ENC_1_EC_THRESH 0.10 // Threshold size for error (in mm) above which the + // printer will attempt to correct the error; errors + // smaller than this are ignored to minimize effects of + // measurement noise / latency (filter). + + #define I2CPE_ENC_2_ADDR I2CPE_PRESET_ADDR_Y // Same as above, but for encoder 2. + #define I2CPE_ENC_2_AXIS Y_AXIS + #define I2CPE_ENC_2_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_ENC_2_TICKS_UNIT 2048 + //#define I2CPE_ENC_2_TICKS_REV (16 * 200) + //#define I2CPE_ENC_2_INVERT + #define I2CPE_ENC_2_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_ENC_2_EC_THRESH 0.10 + + #define I2CPE_ENC_3_ADDR I2CPE_PRESET_ADDR_Z // Encoder 3. Add additional configuration options + #define I2CPE_ENC_3_AXIS Z_AXIS // as above, or use defaults below. + + #define I2CPE_ENC_4_ADDR I2CPE_PRESET_ADDR_E // Encoder 4. + #define I2CPE_ENC_4_AXIS E_AXIS + + #define I2CPE_ENC_5_ADDR 34 // Encoder 5. + #define I2CPE_ENC_5_AXIS E_AXIS + + // Default settings for encoders which are enabled, but without settings configured above. + #define I2CPE_DEF_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_DEF_ENC_TICKS_UNIT 2048 + #define I2CPE_DEF_TICKS_REV (16 * 200) + #define I2CPE_DEF_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_DEF_EC_THRESH 0.1 + + //#define I2CPE_ERR_THRESH_ABORT 100.0 // Threshold size for error (in mm) error on any given + // axis after which the printer will abort. Comment out to + // disable abort behaviour. + + #define I2CPE_TIME_TRUSTED 10000 // After an encoder fault, there must be no further fault + // for this amount of time (in ms) before the encoder + // is trusted again. + + /** + * Position is checked every time a new command is executed from the buffer but during long moves, + * this setting determines the minimum update time between checks. A value of 100 works well with + * error rolling average when attempting to correct only for skips and not for vibration. + */ + #define I2CPE_MIN_UPD_TIME_MS 100 // Minimum time in miliseconds between encoder checks. + + // Use a rolling average to identify persistant errors that indicate skips, as opposed to vibration and noise. + #define I2CPE_ERR_ROLLING_AVERAGE + +#endif // I2C_POSITION_ENCODERS + +/** + * MAX7219 Debug Matrix + * + * Add support for a low-cost 8x8 LED Matrix based on the Max7219 chip, which can be used as a status + * display. Requires 3 signal wires. Some useful debug options are included to demonstrate its usage. + * + * Fully assembled MAX7219 boards can be found on the internet for under $2(US). + * For example, see https://www.ebay.com/sch/i.html?_nkw=332349290049 + */ +//#define MAX7219_DEBUG +#if ENABLED(MAX7219_DEBUG) + #define MAX7219_CLK_PIN 64 // 77 on Re-ARM // Configuration of the 3 pins to control the display + #define MAX7219_DIN_PIN 57 // 78 on Re-ARM + #define MAX7219_LOAD_PIN 44 // 79 on Re-ARM + + /** + * Sample debug features + * If you add more debug displays, be careful to avoid conflicts! + */ + #define MAX7219_DEBUG_PRINTER_ALIVE // Blink corner LED of 8x8 matrix to show that the firmware is functioning + #define MAX7219_DEBUG_STEPPER_HEAD 3 // Show the stepper queue head position on this and the next LED matrix row + #define MAX7219_DEBUG_STEPPER_TAIL 5 // Show the stepper queue tail position on this and the next LED matrix row + + #define MAX7219_DEBUG_STEPPER_QUEUE 0 // Show the current stepper queue depth on this and the next LED matrix row + // If you experience stuttering, reboots, etc. this option can reveal how + // tweaks made to the configuration are affecting the printer in real-time. +#endif + +#endif // CONFIGURATION_ADV_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/BQ/Hephestos_2/Configuration.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/BQ/Hephestos_2/Configuration.h new file mode 100644 index 00000000..f7fdd8e3 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/BQ/Hephestos_2/Configuration.h @@ -0,0 +1,1701 @@ +/** + * 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 . + * + */ + +#ifndef CONFIGURATION_H +#define CONFIGURATION_H +#define CONFIGURATION_H_VERSION 010100 + +//=========================================================================== +//================================= README ================================== +//=========================================================================== + +/** + * BQ Hephestos 2 Configuration + * + * This configuration supports the standard Hephestos 2 with or without the + * heated bed kit featured at https://store.bq.com/en/heated-bed-kit-hephestos2 + * + * Enable the following option to activate all functionality related to the heated bed. + */ +//#define HEPHESTOS2_HEATED_BED_KIT + +//=========================================================================== +//============================= Getting Started ============================= +//=========================================================================== + +/** + * Here are some standard links for getting your machine calibrated: + * + * http://reprap.org/wiki/Calibration + * http://youtu.be/wAL9d7FgInk + * http://calculator.josefprusa.cz + * http://reprap.org/wiki/Triffid_Hunter%27s_Calibration_Guide + * http://www.thingiverse.com/thing:5573 + * https://sites.google.com/site/repraplogphase/calibration-of-your-reprap + * http://www.thingiverse.com/thing:298812 + */ + +//=========================================================================== +//============================= DELTA Printer =============================== +//=========================================================================== +// For a Delta printer start with one of the configuration files in the +// example_configurations/delta directory and customize for your machine. +// + +//=========================================================================== +//============================= SCARA Printer =============================== +//=========================================================================== +// For a SCARA printer start with the configuration files in +// example_configurations/SCARA and customize for your machine. +// + +// @section info + +// User-specified version info of this build to display in [Pronterface, etc] terminal window during +// startup. Implementation of an idea by Prof Braino to inform user that any changes made to this +// build by the user have been successfully uploaded into firmware. +#define STRING_CONFIG_H_AUTHOR "@jbrazio" // Who made the changes. +#define SHOW_BOOTSCREEN +#define STRING_SPLASH_LINE1 SHORT_BUILD_VERSION // will be shown during bootup in line 1 +#define STRING_SPLASH_LINE2 WEBSITE_URL // will be shown during bootup in line 2 + +// +// *** VENDORS PLEASE READ ***************************************************** +// +// Marlin now allow you to have a vendor boot image to be displayed on machine +// start. When SHOW_CUSTOM_BOOTSCREEN is defined Marlin will first show your +// custom boot image and then the default Marlin boot image is shown. +// +// We suggest for you to take advantage of this new feature and keep the Marlin +// boot image unmodified. For an example have a look at the bq Hephestos 2 +// example configuration folder. +// +#define SHOW_CUSTOM_BOOTSCREEN +// @section machine + +/** + * Select which serial port on the board will be used for communication with the host. + * This allows the connection of wireless adapters (for instance) to non-default port pins. + * Serial port 0 is always used by the Arduino bootloader regardless of this setting. + * + * :[0, 1, 2, 3, 4, 5, 6, 7] + */ +#define SERIAL_PORT 0 + +/** + * This setting determines the communication speed of the printer. + * + * 250000 works in most cases, but you might try a lower speed if + * you commonly experience drop-outs during host printing. + * You may try up to 1000000 to speed up SD file transfer. + * + * :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000] + */ +#define BAUDRATE 115200 + +// Enable the Bluetooth serial interface on AT90USB devices +//#define BLUETOOTH + +// The following define selects which electronics board you have. +// Please choose the name from boards.h that matches your setup +#ifndef MOTHERBOARD + #define MOTHERBOARD BOARD_BQ_ZUM_MEGA_3D +#endif + +// Optional custom name for your RepStrap or other custom machine +// Displayed in the LCD "Ready" message +#define CUSTOM_MACHINE_NAME "BQ Hephestos 2" + +// Define this to set a unique identifier for this printer, (Used by some programs to differentiate between machines) +// You can use an online service to generate a random UUID. (eg http://www.uuidgenerator.net/version4) +#define MACHINE_UUID "8d083632-40c5-4649-85b8-43d9ae6c5d55" // BQ Hephestos 2 standard config + +// @section extruder + +// This defines the number of extruders +// :[1, 2, 3, 4, 5] +#define EXTRUDERS 1 + +// For Cyclops or any "multi-extruder" that shares a single nozzle. +//#define SINGLENOZZLE + +/** + * Průša MK2 Single Nozzle Multi-Material Multiplexer, and variants. + * + * This device allows one stepper driver on a control board to drive + * two to eight stepper motors, one at a time, in a manner suitable + * for extruders. + * + * This option only allows the multiplexer to switch on tool-change. + * Additional options to configure custom E moves are pending. + */ +//#define MK2_MULTIPLEXER +#if ENABLED(MK2_MULTIPLEXER) + // Override the default DIO selector pins here, if needed. + // Some pins files may provide defaults for these pins. + //#define E_MUX0_PIN 40 // Always Required + //#define E_MUX1_PIN 42 // Needed for 3 to 8 steppers + //#define E_MUX2_PIN 44 // Needed for 5 to 8 steppers +#endif + +// A dual extruder that uses a single stepper motor +//#define SWITCHING_EXTRUDER +#if ENABLED(SWITCHING_EXTRUDER) + #define SWITCHING_EXTRUDER_SERVO_NR 0 + #define SWITCHING_EXTRUDER_SERVO_ANGLES { 0, 90 } // Angles for E0, E1[, E2, E3] + #if EXTRUDERS > 3 + #define SWITCHING_EXTRUDER_E23_SERVO_NR 1 + #endif +#endif + +// A dual-nozzle that uses a servomotor to raise/lower one of the nozzles +//#define SWITCHING_NOZZLE +#if ENABLED(SWITCHING_NOZZLE) + #define SWITCHING_NOZZLE_SERVO_NR 0 + #define SWITCHING_NOZZLE_SERVO_ANGLES { 0, 90 } // Angles for E0, E1 + //#define HOTEND_OFFSET_Z { 0.0, 0.0 } +#endif + +/** + * Two separate X-carriages with extruders that connect to a moving part + * via a magnetic docking mechanism. Requires SOL1_PIN and SOL2_PIN. + */ +//#define PARKING_EXTRUDER +#if ENABLED(PARKING_EXTRUDER) + #define PARKING_EXTRUDER_SOLENOIDS_INVERT // If enabled, the solenoid is NOT magnetized with applied voltage + #define PARKING_EXTRUDER_SOLENOIDS_PINS_ACTIVE LOW // LOW or HIGH pin signal energizes the coil + #define PARKING_EXTRUDER_SOLENOIDS_DELAY 250 // Delay (ms) for magnetic field. No delay if 0 or not defined. + #define PARKING_EXTRUDER_PARKING_X { -78, 184 } // X positions for parking the extruders + #define PARKING_EXTRUDER_GRAB_DISTANCE 1 // mm to move beyond the parking point to grab the extruder + #define PARKING_EXTRUDER_SECURITY_RAISE 5 // Z-raise before parking + #define HOTEND_OFFSET_Z { 0.0, 1.3 } // Z-offsets of the two hotends. The first must be 0. +#endif + +/** + * "Mixing Extruder" + * - Adds a new code, M165, to set the current mix factors. + * - Extends the stepping routines to move multiple steppers in proportion to the mix. + * - Optional support for Repetier Firmware M163, M164, and virtual extruder. + * - This implementation supports only a single extruder. + * - Enable DIRECT_MIXING_IN_G1 for Pia Taubert's reference implementation + */ +//#define MIXING_EXTRUDER +#if ENABLED(MIXING_EXTRUDER) + #define MIXING_STEPPERS 2 // Number of steppers in your mixing extruder + #define MIXING_VIRTUAL_TOOLS 16 // Use the Virtual Tool method with M163 and M164 + //#define DIRECT_MIXING_IN_G1 // Allow ABCDHI mix factors in G1 movement commands +#endif + +// Offset of the extruders (uncomment if using more than one and relying on firmware to position when changing). +// The offset has to be X=0, Y=0 for the extruder 0 hotend (default extruder). +// For the other hotends it is their distance from the extruder 0 hotend. +//#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis +//#define HOTEND_OFFSET_Y {0.0, 5.00} // (in mm) for each extruder, offset of the hotend on the Y axis + +// @section machine + +/** + * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN + * + * 0 = No Power Switch + * 1 = ATX + * 2 = X-Box 360 203Watts (the blue wire connected to PS_ON and the red wire to VCC) + * + * :{ 0:'No power switch', 1:'ATX', 2:'X-Box 360' } + */ +#define POWER_SUPPLY 0 + +#if POWER_SUPPLY > 0 + // Enable this option to leave the PSU off at startup. + // Power to steppers and heaters will need to be turned on with M80. + //#define PS_DEFAULT_OFF +#endif + +// @section temperature + +//=========================================================================== +//============================= Thermal Settings ============================ +//=========================================================================== + +/** + * --NORMAL IS 4.7kohm PULLUP!-- 1kohm pullup can be used on hotend sensor, using correct resistor and table + * + * Temperature sensors available: + * + * -3 : thermocouple with MAX31855 (only for sensor 0) + * -2 : thermocouple with MAX6675 (only for sensor 0) + * -1 : thermocouple with AD595 + * 0 : not used + * 1 : 100k thermistor - best choice for EPCOS 100k (4.7k pullup) + * 2 : 200k thermistor - ATC Semitec 204GT-2 (4.7k pullup) + * 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 (Used in ParCan & J-Head) (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) + * 71 : 100k Honeywell thermistor 135-104LAF-J01 (4.7k pullup) + * 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) + * 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" + * 20 : the PT100 circuit found in the Ultimainboard V2.x + * 60 : 100k Maker's Tool Works Kapton Bed Thermistor beta=3950 + * 66 : 4.7M High Temperature thermistor from Dyze Design + * 70 : the 100K thermistor found in the bq Hephestos 2 + * 75 : 100k Generic Silicon Heat Pad with NTC 100K MGB18-104F39050L32 thermistor + * + * 1k ohm pullup tables - This is atypical, and requires changing out the 4.7k pullup for 1k. + * (but gives greater accuracy and more stable PID) + * 51 : 100k thermistor - EPCOS (1k pullup) + * 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 + * 1010 : Pt1000 with 1k pullup (non standard) + * 147 : Pt100 with 4k7 pullup + * 110 : Pt100 with 1k pullup (non standard) + * + * Use these for Testing or Development purposes. NEVER for production machine. + * 998 : Dummy Table that ALWAYS reads 25°C or the temperature defined below. + * 999 : Dummy Table that ALWAYS reads 100°C or the temperature defined below. + * + * :{ '0': "Not used", '1':"100k / 4.7k - EPCOS", '2':"200k / 4.7k - ATC Semitec 204GT-2", '3':"Mendel-parts / 4.7k", '4':"10k !! do not use for a hotend. Bad resolution at high temp. !!", '5':"100K / 4.7k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '6':"100k / 4.7k EPCOS - Not as accurate as Table 1", '7':"100k / 4.7k Honeywell 135-104LAG-J01", '8':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT", '9':"100k / 4.7k GE Sensing AL03006-58.2K-97-G1", '10':"100k / 4.7k RS 198-961", '11':"100k / 4.7k beta 3950 1%", '12':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT (calibrated for Makibox hot bed)", '13':"100k Hisens 3950 1% up to 300°C for hotend 'Simple ONE ' & hotend 'All In ONE'", '20':"PT100 (Ultimainboard V2.x)", '51':"100k / 1k - EPCOS", '52':"200k / 1k - ATC Semitec 204GT-2", '55':"100k / 1k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '60':"100k Maker's Tool Works Kapton Bed Thermistor beta=3950", '66':"Dyze Design 4.7M High Temperature thermistor", '70':"the 100K thermistor found in the bq Hephestos 2", '71':"100k / 4.7k Honeywell 135-104LAF-J01", '147':"Pt100 / 4.7k", '1047':"Pt1000 / 4.7k", '110':"Pt100 / 1k (non-standard)", '1010':"Pt1000 / 1k (non standard)", '-3':"Thermocouple + MAX31855 (only for sensor 0)", '-2':"Thermocouple + MAX6675 (only for sensor 0)", '-1':"Thermocouple + AD595",'998':"Dummy 1", '999':"Dummy 2" } + */ +#define TEMP_SENSOR_0 70 +#define TEMP_SENSOR_1 0 +#define TEMP_SENSOR_2 0 +#define TEMP_SENSOR_3 0 +#define TEMP_SENSOR_4 0 + +#if ENABLED(HEPHESTOS2_HEATED_BED_KIT) + #define TEMP_SENSOR_BED 70 + #define HEATER_BED_INVERTING true +#else + #define TEMP_SENSOR_BED 0 +#endif + +// Dummy thermistor constant temperature readings, for use with 998 and 999 +#define DUMMY_THERMISTOR_998_VALUE 25 +#define DUMMY_THERMISTOR_999_VALUE 100 + +// 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 +#define MAX_REDUNDANT_TEMP_SENSOR_DIFF 10 + +// Extruder temperature must be close to target for this long before M109 returns success +#define TEMP_RESIDENCY_TIME 10 // (seconds) +#define TEMP_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// Bed temperature must be close to target for this long before M190 returns success +#define TEMP_BED_RESIDENCY_TIME 0 // (seconds) +#define TEMP_BED_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_BED_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// The minimal temperature defines the temperature below which the heater will not be enabled It is used +// to check that the wiring to the thermistor is not broken. +// Otherwise this would lead to the heater being powered on all the time. +#define HEATER_0_MINTEMP 5 +#define HEATER_1_MINTEMP 5 +#define HEATER_2_MINTEMP 5 +#define HEATER_3_MINTEMP 5 +#define HEATER_4_MINTEMP 5 +#define BED_MINTEMP 5 + +// When temperature exceeds max temp, your heater will be switched off. +// This feature exists to protect your hotend from overheating accidentally, but *NOT* from thermistor short/failure! +// You should use MINTEMP for thermistor short/failure protection. +#define HEATER_0_MAXTEMP 275 +#define HEATER_1_MAXTEMP 275 +#define HEATER_2_MAXTEMP 275 +#define HEATER_3_MAXTEMP 275 +#define HEATER_4_MAXTEMP 275 +#define BED_MAXTEMP 110 + +//=========================================================================== +//============================= PID Settings ================================ +//=========================================================================== +// PID Tuning Guide here: http://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 +#if ENABLED(PIDTEMP) + //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. + //#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 50 // 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. + #define K1 0.95 //smoothing factor within the PID + + // Tuned PID values using M303 + #define DEFAULT_Kp 19.18 + #define DEFAULT_Ki 1.36 + #define DEFAULT_Kd 67.42 + + // BQ firmware stock PID values + //#define DEFAULT_Kp 10.7 + //#define DEFAULT_Ki 0.45 + //#define DEFAULT_Kd 3 + +#endif // PIDTEMP + +//=========================================================================== +//============================= PID > Bed Temperature Control =============== +//=========================================================================== +// Select PID or bang-bang with PIDTEMPBED. If bang-bang, BED_LIMIT_SWITCHING will enable hysteresis +// +// Uncomment this to enable PID on the bed. It uses the same frequency PWM as the extruder. +// If your PID_dT is the default, and correct for your hardware/configuration, that means 7.689Hz, +// which is fine for driving a square wave into a resistive load and does not significantly impact you FET heating. +// This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W heater. +// If your configuration is significantly different than this and you don't understand the issues involved, you probably +// shouldn't use bed PID until someone else verifies your hardware works. +// If this is enabled, find your own PID constants below. +//#define PIDTEMPBED + +//#define BED_LIMIT_SWITCHING + +// This sets the max power delivered to the bed, and replaces the HEATER_BED_DUTY_CYCLE_DIVIDER option. +// all forms of bed control obey this (PID, bang-bang, bang-bang with hysteresis) +// setting this to anything other than 255 enables a form of PWM to the bed just like HEATER_BED_DUTY_CYCLE_DIVIDER did, +// so you shouldn't use it unless you are OK with PWM on your bed. (see the comment on enabling PIDTEMPBED) + +#if ENABLED(HEPHESTOS2_HEATED_BED_KIT) + #define MAX_BED_POWER 255 // limits duty cycle to bed; 255=full current +#endif + +#if ENABLED(PIDTEMPBED) + + //#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) + #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 + +// @section extruder + +// This option prevents extrusion if the temperature is below EXTRUDE_MINTEMP. +// It also enables the M302 command to set the minimum extrusion temperature +// or to allow moving the extruder regardless of the hotend temperature. +// *** IT IS HIGHLY RECOMMENDED TO LEAVE THIS OPTION ENABLED! *** +#define PREVENT_COLD_EXTRUSION +#define EXTRUDE_MINTEMP 170 + +// This option prevents a single extrusion longer than EXTRUDE_MAXLENGTH. +// Note that for Bowden Extruders a too-small value here may prevent loading. +#define PREVENT_LENGTHY_EXTRUDE +#define EXTRUDE_MAXLENGTH 200 + +//=========================================================================== +//======================== Thermal Runaway Protection ======================= +//=========================================================================== + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * If you get "Thermal Runaway" or "Heating failed" errors the + * details can be tuned in Configuration_adv.h + */ + +#define THERMAL_PROTECTION_HOTENDS // Enable thermal protection for all extruders +#define THERMAL_PROTECTION_BED // Enable thermal protection for the heated bed + +//=========================================================================== +//============================= Mechanical Settings ========================= +//=========================================================================== + +// @section machine + +// Uncomment one of these options to enable CoreXY, CoreXZ, or CoreYZ kinematics +// either in the usual order or reversed +//#define COREXY +//#define COREXZ +//#define COREYZ +//#define COREYX +//#define COREZX +//#define COREZY + +//=========================================================================== +//============================== Endstop Settings =========================== +//=========================================================================== + +// @section homing + +// Specify here all the endstop connectors that are connected to any endstop or probe. +// Almost all printers will be using one per axis. Probes will use one or more of the +// extra connectors. Leave undefined any used for non-endstop and non-probe purposes. +#define USE_XMIN_PLUG +#define USE_YMIN_PLUG +#define USE_ZMIN_PLUG +//#define USE_XMAX_PLUG +//#define USE_YMAX_PLUG +//#define USE_ZMAX_PLUG + +// coarse Endstop Settings +#define ENDSTOPPULLUPS // Comment this out (using // at the start of the line) to disable the endstop pullup resistors + +#if DISABLED(ENDSTOPPULLUPS) + // fine endstop settings: Individual pullups. will be ignored if ENDSTOPPULLUPS is defined + //#define ENDSTOPPULLUP_XMAX + //#define ENDSTOPPULLUP_YMAX + //#define ENDSTOPPULLUP_ZMAX + //#define ENDSTOPPULLUP_XMIN + //#define ENDSTOPPULLUP_YMIN + //#define ENDSTOPPULLUP_ZMIN + //#define ENDSTOPPULLUP_ZMIN_PROBE +#endif + +// Mechanical endstop with COM to ground and NC to Signal uses "false" here (most common setup). +#define X_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Y_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MIN_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define X_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Y_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MIN_PROBE_ENDSTOP_INVERTING false // set to true to invert the logic of the probe. + +// Enable this feature if all enabled endstop pins are interrupt-capable. +// This will remove the need to poll the interrupt pins, saving many CPU cycles. +#define ENDSTOP_INTERRUPTS_FEATURE + +//============================================================================= +//============================== Movement Settings ============================ +//============================================================================= +// @section motion + +/** + * Default Settings + * + * These settings can be reset by M502 + * + * Note that if EEPROM is enabled, saved values will override these. + */ + +/** + * With this option each E stepper can have its own factors for the + * following movement settings. If fewer factors are given than the + * total number of extruders, the last value applies to the rest. + */ +//#define DISTINCT_E_FACTORS + +/** + * Default Axis Steps Per Unit (steps/mm) + * Override with M92 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_AXIS_STEPS_PER_UNIT { 160, 160, 8000, 210.02 } + +/** + * Default Max Feed Rate (mm/s) + * Override with M203 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_FEEDRATE { 167, 167, 3.3, 167 } + +/** + * Default Max Acceleration (change/s) change = mm/s + * (Maximum start speed for accelerated moves) + * Override with M201 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_ACCELERATION { 1000, 1000, 100, 3000 } + +/** + * Default Acceleration (change/s) change = mm/s + * Override with M204 + * + * M204 P Acceleration + * M204 R Retract Acceleration + * M204 T Travel Acceleration + */ +#define DEFAULT_ACCELERATION 1000 // X, Y, Z and E acceleration for printing moves +#define DEFAULT_RETRACT_ACCELERATION 3000 // E acceleration for retracts +#define DEFAULT_TRAVEL_ACCELERATION 1000 // X, Y, Z acceleration for travel (non printing) moves + +/** + * Default Jerk (mm/s) + * Override with M205 X Y Z E + * + * "Jerk" specifies the minimum speed change that requires acceleration. + * When changing speed and direction, if the difference is less than the + * value set here, it may happen instantaneously. + */ +#define DEFAULT_XJERK 20.0 +#define DEFAULT_YJERK 20.0 +#define DEFAULT_ZJERK 0.4 +#define DEFAULT_EJERK 1.0 + +//=========================================================================== +//============================= Z Probe Options ============================= +//=========================================================================== +// @section probes + +// +// See http://marlinfw.org/configuration/probes.html +// + +/** + * Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + * + * Enable this option for a probe connected to the Z Min endstop pin. + */ +#define Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + +/** + * Z_MIN_PROBE_ENDSTOP + * + * Enable this option for a probe connected to any pin except Z-Min. + * (By default Marlin assumes the Z-Max endstop pin.) + * To use a custom Z Probe pin, set Z_MIN_PROBE_PIN below. + * + * - The simplest option is to use a free endstop connector. + * - Use 5V for powered (usually inductive) sensors. + * + * - RAMPS 1.3/1.4 boards may use the 5V, GND, and Aux4->D32 pin: + * - For simple switches connect... + * - normally-closed switches to GND and D32. + * - normally-open switches to 5V and D32. + * + * WARNING: Setting the wrong pin may have unexpected and potentially + * disastrous consequences. Use with caution and do your homework. + * + */ +//#define Z_MIN_PROBE_ENDSTOP + +/** + * Probe Type + * + * Allen Key Probes, Servo Probes, Z-Sled Probes, FIX_MOUNTED_PROBE, etc. + * Activate one of these to use Auto Bed Leveling below. + */ + +/** + * The "Manual Probe" provides a means to do "Auto" Bed Leveling without a probe. + * Use G29 repeatedly, adjusting the Z height at each point with movement commands + * or (with LCD_BED_LEVELING) the LCD controller. + */ +//#define PROBE_MANUALLY + +/** + * A Fix-Mounted Probe either doesn't deploy or needs manual deployment. + * (e.g., an inductive probe or a nozzle-based probe-switch.) + */ +#define FIX_MOUNTED_PROBE + +/** + * Z Servo Probe, such as an endstop switch on a rotating arm. + */ +//#define Z_ENDSTOP_SERVO_NR 0 // Defaults to SERVO 0 connector. +//#define Z_SERVO_ANGLES {70,0} // Z Servo Deploy and Stow angles + +/** + * The BLTouch probe uses a Hall effect sensor and emulates a servo. + */ +//#define BLTOUCH +#if ENABLED(BLTOUCH) + //#define BLTOUCH_DELAY 375 // (ms) Enable and increase if needed +#endif + +/** + * Enable one or more of the following if probing seems unreliable. + * Heaters and/or fans can be disabled during probing to minimize electrical + * noise. A delay can also be added to allow noise and vibration to settle. + * These options are most useful for the BLTouch probe, but may also improve + * readings with inductive probes and piezo sensors. + */ +//#define PROBING_HEATERS_OFF // Turn heaters off when probing +//#define PROBING_FANS_OFF // Turn fans off when probing +//#define DELAY_BEFORE_PROBING 200 // (ms) To prevent vibrations from triggering piezo sensors + +// A probe that is deployed and stowed with a solenoid pin (SOL1_PIN) +//#define SOLENOID_PROBE + +// A sled-mounted probe like those designed by Charles Bell. +//#define Z_PROBE_SLED +//#define SLED_DOCKING_OFFSET 5 // The extra distance the X axis must travel to pickup the sled. 0 should be fine but you can push it further if you'd like. + +// +// For Z_PROBE_ALLEN_KEY see the Delta example configurations. +// + +/** + * Z Probe to nozzle (X,Y) offset, relative to (0, 0). + * X and Y offsets must be integers. + * + * In the following example the X and Y offsets are both positive: + * #define X_PROBE_OFFSET_FROM_EXTRUDER 10 + * #define Y_PROBE_OFFSET_FROM_EXTRUDER 10 + * + * +-- BACK ---+ + * | | + * L | (+) P | R <-- probe (20,20) + * E | | I + * F | (-) N (+) | G <-- nozzle (10,10) + * T | | H + * | (-) | T + * | | + * O-- FRONT --+ + * (0,0) + */ +#define X_PROBE_OFFSET_FROM_EXTRUDER 34 // X offset: -left +right [of the nozzle] +#define Y_PROBE_OFFSET_FROM_EXTRUDER 15 // Y offset: -front +behind [the nozzle] +#define Z_PROBE_OFFSET_FROM_EXTRUDER 0 // Z offset: -below +above [the nozzle] + +// X and Y axis travel speed (mm/m) between probes +#define XY_PROBE_SPEED 8000 + +// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +#define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z + +// Speed for the "accurate" probe of each point +#define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) + +// Use double touch for probing +//#define PROBE_DOUBLE_TOUCH + +/** + * Z probes require clearance when deploying, stowing, and moving between + * probe points to avoid hitting the bed and other hardware. + * Servo-mounted probes require extra space for the arm to rotate. + * Inductive probes need space to keep from triggering early. + * + * Use these settings to specify the distance (mm) to raise the probe (or + * lower the bed). The values set here apply over and above any (negative) + * probe Z Offset set with Z_PROBE_OFFSET_FROM_EXTRUDER, M851, or the LCD. + * Only integer values >= 1 are valid here. + * + * Example: `M851 Z-5` with a CLEARANCE of 4 => 9mm from bed to nozzle. + * But: `M851 Z+1` with a CLEARANCE of 2 => 2mm from bed to nozzle. + */ +#define Z_CLEARANCE_DEPLOY_PROBE 0 // Z Clearance for Deploy/Stow +#define Z_CLEARANCE_BETWEEN_PROBES 2 // Z Clearance between probe points + +// For M851 give a range for adjusting the Z probe offset +#define Z_PROBE_OFFSET_RANGE_MIN -2 +#define Z_PROBE_OFFSET_RANGE_MAX 0 + +// Enable the M48 repeatability test to test probe accuracy +#define Z_MIN_PROBE_REPEATABILITY_TEST + +// For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1 +// :{ 0:'Low', 1:'High' } +#define X_ENABLE_ON 0 +#define Y_ENABLE_ON 0 +#define Z_ENABLE_ON 0 +#define E_ENABLE_ON 0 // For all extruders + +// Disables axis stepper immediately when it's not being used. +// 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 +//#define DISABLE_REDUCED_ACCURACY_WARNING + +// @section extruder + +#define DISABLE_E false // For all extruders +#define DISABLE_INACTIVE_EXTRUDER true // Keep only the active extruder enabled. + +// @section machine + +// Invert the stepper direction. Change (or reverse the motor connector) if an axis goes the wrong way. +#define INVERT_X_DIR true +#define INVERT_Y_DIR true +#define INVERT_Z_DIR true + +// Enable this option for Toshiba stepper drivers +//#define CONFIG_STEPPERS_TOSHIBA + +// @section extruder + +// For direct drive extruder v9 set to true, for geared extruder set to false. +#define INVERT_E0_DIR true +#define INVERT_E1_DIR false +#define INVERT_E2_DIR false +#define INVERT_E3_DIR false +#define INVERT_E4_DIR false + +// @section homing + +//#define NO_MOTION_BEFORE_HOMING // Inhibit movement until all axes have been homed + +#define Z_HOMING_HEIGHT 5 // (in mm) Minimal z height before homing (G28) for Z clearance above the bed, clamps, ... + // Be sure you have this distance over your Z_MAX_POS in case. + +// Direction of endstops when homing; 1=MAX, -1=MIN +// :[-1,1] +#define X_HOME_DIR -1 +#define Y_HOME_DIR -1 +#define Z_HOME_DIR -1 + +// @section machine + +// The size of the print bed +#define X_BED_SIZE 210 +#define Y_BED_SIZE 297 + +// Travel limits (mm) after homing, corresponding to endstop positions. +#define X_MIN_POS 0 +#define Y_MIN_POS 0 +#define Z_MIN_POS 0 +#define X_MAX_POS X_BED_SIZE +#define Y_MAX_POS Y_BED_SIZE +#define Z_MAX_POS 210 + +// If enabled, axes won't move below MIN_POS in response to movement commands. +#define MIN_SOFTWARE_ENDSTOPS +// If enabled, axes won't move above MAX_POS in response to movement commands. +#define MAX_SOFTWARE_ENDSTOPS + +/** + * Filament Runout Sensor + * A mechanical or opto endstop is used to check for the presence of filament. + * + * RAMPS-based boards use SERVO3_PIN. + * For other boards you may need to define FIL_RUNOUT_PIN. + * By default the firmware assumes HIGH = has filament, LOW = ran out + */ +//#define FILAMENT_RUNOUT_SENSOR +#if ENABLED(FILAMENT_RUNOUT_SENSOR) + #define FIL_RUNOUT_INVERTING false // set to true to invert the logic of the sensor. + #define ENDSTOPPULLUP_FIL_RUNOUT // Uncomment to use internal pullup for filament runout pins if the sensor is defined. + #define FILAMENT_RUNOUT_SCRIPT "M600" +#endif + +//=========================================================================== +//=============================== Bed Leveling ============================== +//=========================================================================== +// @section bedlevel + +/** + * Choose one of the options below to enable G29 Bed Leveling. The parameters + * and behavior of G29 will change depending on your selection. + * + * If using a Probe for Z Homing, enable Z_SAFE_HOMING also! + * + * - AUTO_BED_LEVELING_3POINT + * Probe 3 arbitrary points on the bed (that aren't collinear) + * You specify the XY coordinates of all 3 points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_LINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_BILINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a mesh, best for large or uneven beds. + * + * - AUTO_BED_LEVELING_UBL (Unified Bed Leveling) + * A comprehensive bed leveling system combining the features and benefits + * of other systems. UBL also includes integrated Mesh Generation, Mesh + * Validation and Mesh Editing systems. Currently, UBL is only checked out + * for Cartesian Printers. That said, it was primarily designed to correct + * poor quality Delta Printers. If you feel adventurous and have a Delta, + * please post an issue if something doesn't work correctly. Initially, + * you will need to set a reduced bed size so you have a rectangular area + * to test on. + * + * - MESH_BED_LEVELING + * Probe a grid manually + * The result is a mesh, suitable for large or uneven beds. (See BILINEAR.) + * For machines without a probe, Mesh Bed Leveling provides a method to perform + * leveling in steps so you can manually adjust the Z height at each grid-point. + * With an LCD controller the process is guided step-by-step. + */ +//#define AUTO_BED_LEVELING_3POINT +//#define AUTO_BED_LEVELING_LINEAR +#define AUTO_BED_LEVELING_BILINEAR +//#define AUTO_BED_LEVELING_UBL +//#define MESH_BED_LEVELING + +/** + * Enable detailed logging of G28, G29, M48, etc. + * Turn on with the command 'M111 S32'. + * NOTE: Requires a lot of PROGMEM! + */ +//#define DEBUG_LEVELING_FEATURE + +#if ENABLED(MESH_BED_LEVELING) || ENABLED(AUTO_BED_LEVELING_BILINEAR) || ENABLED(AUTO_BED_LEVELING_UBL) + // Gradually reduce leveling correction until a set height is reached, + // at which point movement will be level to the machine's XY plane. + // The height can be set with M420 Z + #define ENABLE_LEVELING_FADE_HEIGHT +#endif + +#if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Set the number of grid points per dimension. + #define GRID_MAX_POINTS_X 3 + #define GRID_MAX_POINTS_Y 4 + + // Set the boundaries for probing (where the probe can reach). + #define LEFT_PROBE_BED_POSITION X_MIN_POS + (X_PROBE_OFFSET_FROM_EXTRUDER) + #define RIGHT_PROBE_BED_POSITION X_MAX_POS - (X_PROBE_OFFSET_FROM_EXTRUDER) + #define FRONT_PROBE_BED_POSITION Y_MIN_POS + (Y_PROBE_OFFSET_FROM_EXTRUDER) + #define BACK_PROBE_BED_POSITION Y_MAX_POS - (Y_PROBE_OFFSET_FROM_EXTRUDER) + + // The Z probe minimum outer margin (to validate G29 parameters). + #define MIN_PROBE_EDGE 10 + + // Probe along the Y axis, advancing X after each column + //#define PROBE_Y_FIRST + + #if ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Beyond the probed grid, continue the implied tilt? + // Default is to maintain the height of the nearest edge. + //#define EXTRAPOLATE_BEYOND_GRID + + // + // Experimental Subdivision of the grid by Catmull-Rom method. + // Synthesizes intermediate points to produce a more detailed mesh. + // + //#define ABL_BILINEAR_SUBDIVISION + #if ENABLED(ABL_BILINEAR_SUBDIVISION) + // Number of subdivisions between probe points + #define BILINEAR_SUBDIVISIONS 3 + #endif + + #endif + +#elif ENABLED(AUTO_BED_LEVELING_3POINT) + + // 3 arbitrary points to probe. + // A simple cross-product is used to estimate the plane of the bed. + #define ABL_PROBE_PT_1_X X_MIN_POS + X_PROBE_OFFSET_FROM_EXTRUDER + #define ABL_PROBE_PT_1_Y Y_MIN_POS + Y_PROBE_OFFSET_FROM_EXTRUDER + #define ABL_PROBE_PT_2_X X_MAX_POS - (X_PROBE_OFFSET_FROM_EXTRUDER) + #define ABL_PROBE_PT_2_Y Y_MIN_POS + Y_PROBE_OFFSET_FROM_EXTRUDER + #define ABL_PROBE_PT_3_X ((X_MIN_POS + X_MAX_POS) / 2) + #define ABL_PROBE_PT_3_Y Y_MAX_POS - (Y_PROBE_OFFSET_FROM_EXTRUDER) + +#elif ENABLED(AUTO_BED_LEVELING_UBL) + + //=========================================================================== + //========================= Unified Bed Leveling ============================ + //=========================================================================== + + #define UBL_MESH_INSET 1 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 10 // Don't use more than 15 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + #define UBL_PROBE_PT_1_X 39 // Probing points for 3-Point leveling of the mesh + #define UBL_PROBE_PT_1_Y 180 + #define UBL_PROBE_PT_2_X 39 + #define UBL_PROBE_PT_2_Y 20 + #define UBL_PROBE_PT_3_X 180 + #define UBL_PROBE_PT_3_Y 20 + + #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation + #define UBL_MESH_EDIT_MOVES_Z // Sophisticated users prefer no movement of nozzle + +#elif ENABLED(MESH_BED_LEVELING) + + //=========================================================================== + //=================================== Mesh ================================== + //=========================================================================== + + #define MESH_INSET 10 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 3 // Don't use more than 7 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + //#define MESH_G28_REST_ORIGIN // After homing all axes ('G28' or 'G28 XYZ') rest Z at Z_MIN_POS + +#endif // BED_LEVELING + +/** + * Use the LCD controller for bed leveling + * Requires MESH_BED_LEVELING or PROBE_MANUALLY + */ +//#define LCD_BED_LEVELING + +#if ENABLED(LCD_BED_LEVELING) + #define MBL_Z_STEP 0.025 // Step size while manually probing Z axis. + #define LCD_PROBE_Z_RANGE 4 // Z Range centered on Z_MIN_POS for LCD Z adjustment +#endif + +// Add a menu item to move between bed corners for manual bed adjustment +//#define LEVEL_BED_CORNERS + +/** + * Commands to execute at the end of G29 probing. + * Useful to retract or move the Z probe out of the way. + */ +//#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) +//#define BED_CENTER_AT_0_0 + +// Manually set the home position. Leave these undefined for automatic settings. +// For DELTA this is the top-center of the Cartesian print volume. +//#define MANUAL_X_HOME_POS 0 +//#define MANUAL_Y_HOME_POS 0 +//#define MANUAL_Z_HOME_POS 0 + +// Use "Z Safe Homing" to avoid homing with a Z probe outside the bed area. +// +// With this feature enabled: +// +// - 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). +// - 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 axis (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). +#endif + +// Homing speeds (mm/m) +#define HOMING_FEEDRATE_XY (60*60) +#define HOMING_FEEDRATE_Z 120 + +//============================================================================= +//============================= Additional Features =========================== +//============================================================================= + +// @section extras + +// +// EEPROM +// +// The microcontroller can store settings in the EEPROM, e.g. max velocity... +// M500 - stores parameters in EEPROM +// M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily). +// M502 - reverts to the default "factory settings". You still need to store them in EEPROM afterwards if you want to. +// +#define EEPROM_SETTINGS // Enable for M500 and M501 commands +//#define DISABLE_M503 // Saves ~2700 bytes of PROGMEM. Disable for release! +#define EEPROM_CHITCHAT // Give feedback on EEPROM commands. Disable to save PROGMEM. + +// +// Host Keepalive +// +// When enabled Marlin will send a busy status message to the host +// every couple of seconds when it can't accept commands. +// +#define HOST_KEEPALIVE_FEATURE // Disable this if your host doesn't like keepalive messages +#define DEFAULT_KEEPALIVE_INTERVAL 10 // Number of seconds between "busy" messages. Set with M113. +#define BUSY_WHILE_HEATING // Some hosts require "busy" messages even during heating + +// +// M100 Free Memory Watcher +// +//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose + +// +// G20/G21 Inch mode support +// +//#define INCH_MODE_SUPPORT + +// +// M149 Set temperature units support +// +//#define TEMPERATURE_UNITS_SUPPORT + +// @section temperature + +// Preheat Constants +#define PREHEAT_1_TEMP_HOTEND 205 +#define PREHEAT_1_TEMP_BED 50 +#define PREHEAT_1_FAN_SPEED 0 // Value from 0 to 255 + +#define PREHEAT_2_TEMP_HOTEND 245 +#define PREHEAT_2_TEMP_BED 50 +#define PREHEAT_2_FAN_SPEED 0 // Value from 0 to 255 + +/** + * Nozzle Park -- EXPERIMENTAL + * + * Park the nozzle at the given XYZ position on idle or G27. + * + * The "P" parameter controls the action applied to the Z axis: + * + * P0 (Default) If Z is below park Z raise the nozzle. + * P1 Raise the nozzle always to Z-park height. + * P2 Raise the nozzle by Z-park amount, limited to Z_MAX_POS. + */ +#define NOZZLE_PARK_FEATURE + +#if ENABLED(NOZZLE_PARK_FEATURE) + // Specify a park position as { X, Y, Z } + #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 10 } +#endif + +/** + * Clean Nozzle Feature -- EXPERIMENTAL + * + * Adds the G12 command to perform a nozzle cleaning process. + * + * Parameters: + * P Pattern + * S Strokes / Repetitions + * T Triangles (P1 only) + * + * Patterns: + * P0 Straight line (default). This process requires a sponge type material + * at a fixed bed location. "S" specifies strokes (i.e. back-forth motions) + * between the start / end points. + * + * P1 Zig-zag pattern between (X0, Y0) and (X1, Y1), "T" specifies the + * number of zig-zag triangles to do. "S" defines the number of strokes. + * Zig-zags are done in whichever is the narrower dimension. + * For example, "G12 P1 S1 T3" will execute: + * + * -- + * | (X0, Y1) | /\ /\ /\ | (X1, Y1) + * | | / \ / \ / \ | + * A | | / \ / \ / \ | + * | | / \ / \ / \ | + * | (X0, Y0) | / \/ \/ \ | (X1, Y0) + * -- +--------------------------------+ + * |________|_________|_________| + * T1 T2 T3 + * + * P2 Circular pattern with middle at NOZZLE_CLEAN_CIRCLE_MIDDLE. + * "R" specifies the radius. "S" specifies the stroke count. + * Before starting, the nozzle moves to NOZZLE_CLEAN_START_POINT. + * + * Caveats: The ending Z should be the same as starting Z. + * Attention: EXPERIMENTAL. G-code arguments may change. + * + */ +#define NOZZLE_CLEAN_FEATURE + +#if ENABLED(NOZZLE_CLEAN_FEATURE) + // Default number of pattern repetitions + #define NOZZLE_CLEAN_STROKES 12 + + // Default number of triangles + #define NOZZLE_CLEAN_TRIANGLES 3 + + // Specify positions as { X, Y, Z } + #define NOZZLE_CLEAN_START_POINT { X_MIN_POS + 10, Y_MAX_POS - 9, (Z_MIN_POS + 0.5)} + #define NOZZLE_CLEAN_END_POINT { X_MIN_POS + 90, Y_MAX_POS - 0, (Z_MIN_POS + 0.5)} + + // Circular pattern radius + #define NOZZLE_CLEAN_CIRCLE_RADIUS 6.5 + // Circular pattern circle fragments number + #define NOZZLE_CLEAN_CIRCLE_FN 10 + // Middle point of circle + #define NOZZLE_CLEAN_CIRCLE_MIDDLE NOZZLE_CLEAN_START_POINT + + // Moves the nozzle to the initial position + //#define NOZZLE_CLEAN_GOBACK +#endif + +/** + * Print Job Timer + * + * Automatically start and stop the print job timer on M104/M109/M190. + * + * M104 (hotend, no wait) - high temp = none, low temp = stop timer + * M109 (hotend, wait) - high temp = start timer, low temp = stop timer + * M190 (bed, wait) - high temp = start timer, low temp = none + * + * The timer can also be controlled with the following commands: + * + * M75 - Start the print job timer + * M76 - Pause the print job timer + * M77 - Stop the print job timer + */ +#define PRINTJOB_TIMER_AUTOSTART + +/** + * Print Counter + * + * Track statistical data such as: + * + * - Total print jobs + * - Total successful print jobs + * - Total failed print jobs + * - Total time printing + * + * View the current statistics with M78. + */ +#define PRINTCOUNTER + +//============================================================================= +//============================= LCD and SD support ============================ +//============================================================================= + +// @section lcd + +/** + * LCD LANGUAGE + * + * Select the language to display on the LCD. These languages are available: + * + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, + * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * tr, uk, zh_CN, zh_TW, test + * + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + */ +#define LCD_LANGUAGE en + +/** + * LCD Character Set + * + * Note: This option is NOT applicable to Graphical Displays. + * + * All character-based LCDs provide ASCII plus one of these + * language extensions: + * + * - JAPANESE ... the most common + * - WESTERN ... with more accented characters + * - CYRILLIC ... for the Russian language + * + * To determine the language extension installed on your controller: + * + * - Compile and upload with LCD_LANGUAGE set to 'test' + * - 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 + * + * :['JAPANESE', 'WESTERN', 'CYRILLIC'] + */ +#define DISPLAY_CHARSET_HD44780 JAPANESE + +/** + * LCD TYPE + * + * Enable ULTRA_LCD for a 16x2, 16x4, 20x2, or 20x4 character-based LCD. + * Enable DOGLCD for a 128x64 (ST7565R) Full Graphical Display. + * (These options will be enabled automatically for most displays.) + * + * IMPORTANT: The U8glib library is required for Full Graphic Display! + * https://github.com/olikraus/U8glib_Arduino + */ +//#define ULTRA_LCD // Character based +//#define DOGLCD // Full graphics display + +/** + * SD CARD + * + * 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 + +/** + * SD CARD: SPI SPEED + * + * Enable one of the following items for a slower SPI transfer speed. + * This may be required to resolve "volume init" errors. + */ +//#define SPI_SPEED SPI_HALF_SPEED +//#define SPI_SPEED SPI_QUARTER_SPEED +//#define SPI_SPEED SPI_EIGHTH_SPEED + +/** + * SD CARD: ENABLE CRC + * + * Use CRC checks and retries on the SD communication. + */ +#define SD_CHECK_AND_RETRY + +// +// ENCODER SETTINGS +// +// This option overrides the default number of encoder pulses needed to +// produce one step. Should be increased for high-resolution encoders. +// +//#define ENCODER_PULSES_PER_STEP 1 + +// +// Use this option to override the number of step signals required to +// move between next/prev menu items. +// +//#define ENCODER_STEPS_PER_MENU_ITEM 5 + +/** + * Encoder Direction Options + * + * Test your encoder's behavior first with both options disabled. + * + * Reversed Value Edit and Menu Nav? Enable REVERSE_ENCODER_DIRECTION. + * Reversed Menu Navigation only? Enable REVERSE_MENU_DIRECTION. + * Reversed Value Editing only? Enable BOTH options. + */ + +// +// This option reverses the encoder direction everywhere. +// +// Set this option if CLOCKWISE causes values to DECREASE +// +//#define REVERSE_ENCODER_DIRECTION + +// +// This option reverses the encoder direction for navigating LCD menus. +// +// If CLOCKWISE normally moves DOWN this makes it go UP. +// If CLOCKWISE normally moves UP this makes it go DOWN. +// +//#define REVERSE_MENU_DIRECTION + +// +// Individual Axis Homing +// +// Add individual axis homing items (Home X, Home Y, and Home Z) to the LCD menu. +// +//#define INDIVIDUAL_AXIS_HOMING_MENU + +// +// SPEAKER/BUZZER +// +// If you have a speaker that can produce tones, enable it here. +// By default Marlin assumes you have a buzzer with a fixed frequency. +// +//#define SPEAKER + +// +// The duration and frequency for the UI feedback sound. +// Set these to 0 to disable audio feedback in the LCD menus. +// +// Note: Test audio output with the G-Code: +// M300 S P +// +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 +//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 + +// +// CONTROLLER TYPE: Standard +// +// Marlin supports a wide variety of controllers. +// Enable one of the following options to specify your controller. +// + +// +// ULTIMAKER Controller. +// +//#define ULTIMAKERCONTROLLER + +// +// ULTIPANEL as seen on Thingiverse. +// +//#define ULTIPANEL + +// +// PanelOne from T3P3 (via RAMPS 1.4 AUX2/AUX3) +// http://reprap.org/wiki/PanelOne +// +//#define PANEL_ONE + +// +// MaKr3d Makr-Panel with graphic controller and SD support. +// http://reprap.org/wiki/MaKr3d_MaKrPanel +// +//#define MAKRPANEL + +// +// ReprapWorld Graphical LCD +// https://reprapworld.com/?products_details&products_id/1218 +// +//#define REPRAPWORLD_GRAPHICAL_LCD + +// +// Activate one of these if you have a Panucatt Devices +// Viki 2.0 or mini Viki with Graphic LCD +// http://panucatt.com +// +//#define VIKI2 +//#define miniVIKI + +// +// Adafruit ST7565 Full Graphic Controller. +// https://github.com/eboston/Adafruit-ST7565-Full-Graphic-Controller/ +// +//#define ELB_FULL_GRAPHIC_CONTROLLER + +// +// RepRapDiscount Smart Controller. +// http://reprap.org/wiki/RepRapDiscount_Smart_Controller +// +// Note: Usually sold with a white PCB. +// +//#define REPRAP_DISCOUNT_SMART_CONTROLLER + +// +// GADGETS3D G3D LCD/SD Controller +// http://reprap.org/wiki/RAMPS_1.3/1.4_GADGETS3D_Shield_with_Panel +// +// Note: Usually sold with a blue PCB. +// +//#define G3D_PANEL + +// +// RepRapDiscount FULL GRAPHIC Smart Controller +// http://reprap.org/wiki/RepRapDiscount_Full_Graphic_Smart_Controller +// +//#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER + +// +// MakerLab Mini Panel with graphic +// controller and SD support - http://reprap.org/wiki/Mini_panel +// +//#define MINIPANEL + +// +// RepRapWorld REPRAPWORLD_KEYPAD v1.1 +// http://reprapworld.com/?products_details&products_id=202&cPath=1591_1626 +// +// REPRAPWORLD_KEYPAD_MOVE_STEP sets how much should the robot move when a key +// is pressed, a value of 10.0 means 10mm per click. +// +//#define REPRAPWORLD_KEYPAD +//#define REPRAPWORLD_KEYPAD_MOVE_STEP 1.0 + +// +// RigidBot Panel V1.0 +// http://www.inventapart.com/ +// +//#define RIGIDBOT_PANEL + +// +// BQ LCD Smart Controller shipped by +// default with the BQ Hephestos 2 and Witbox 2. +// +#define BQ_LCD_SMART_CONTROLLER + +// +// Cartesio UI +// http://mauk.cc/webshop/cartesio-shop/electronics/user-interface +// +//#define CARTESIO_UI + +// +// ANET_10 Controller supported displays. +// +//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. + // This LCD is known to be susceptible to electrical interference + // which scrambles the display. Pressing any button clears it up. +//#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 + // A clone of the RepRapDiscount full graphics display but with + // different pins/wiring (see pins_ANET_10.h). + +// +// LCD for Melzi Card with Graphical LCD +// +//#define LCD_FOR_MELZI + +// +// CONTROLLER TYPE: I2C +// +// Note: These controllers require the installation of Arduino's LiquidCrystal_I2C +// library. For more info: https://github.com/kiyoshigawa/LiquidCrystal_I2C +// + +// +// Elefu RA Board Control Panel +// http://www.elefu.com/index.php?route=product/product&product_id=53 +// +//#define RA_CONTROL_PANEL + +// +// Sainsmart YW Robot (LCM1602) LCD Display +// +// Note: This controller requires F.Malpartida's LiquidCrystal_I2C library +// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home +// +//#define LCD_I2C_SAINSMART_YWROBOT + +// +// Generic LCM1602 LCD adapter +// +//#define LCM1602 + +// +// PANELOLU2 LCD with status LEDs, +// separate encoder and click inputs. +// +// Note: This controller requires Arduino's LiquidTWI2 library v1.2.3 or later. +// For more info: https://github.com/lincomatic/LiquidTWI2 +// +// Note: The PANELOLU2 encoder click input can either be directly connected to +// a pin (if BTN_ENC defined to != -1) or read through I2C (when BTN_ENC == -1). +// +//#define LCD_I2C_PANELOLU2 + +// +// Panucatt VIKI LCD with status LEDs, +// integrated click & L/R/U/D buttons, separate encoder inputs. +// +//#define LCD_I2C_VIKI + +// +// SSD1306 OLED full graphics generic display +// +//#define U8GLIB_SSD1306 + +// +// SAV OLEd LCD module support using either SSD1306 or SH1106 based LCD modules +// +//#define SAV_3DGLCD +#if ENABLED(SAV_3DGLCD) + //#define U8GLIB_SSD1306 + #define U8GLIB_SH1106 +#endif + +// +// CONTROLLER TYPE: Shift register panels +// +// 2 wire Non-latching LCD SR from https://goo.gl/aJJ4sH +// LCD configuration: http://reprap.org/wiki/SAV_3D_LCD +// +//#define SAV_3DLCD + +// +// TinyBoy2 128x64 OLED / Encoder Panel +// +//#define OLED_PANEL_TINYBOY2 + +// +// Makeboard 3D Printer Parts 3D Printer Mini Display 1602 Mini Controller +// https://www.aliexpress.com/item/Micromake-Makeboard-3D-Printer-Parts-3D-Printer-Mini-Display-1602-Mini-Controller-Compatible-with-Ramps-1/32765887917.html +// +//#define MAKEBOARD_MINI_2_LINE_DISPLAY_1602 + +// +// MKS MINI12864 with graphic controller and SD support +// http://reprap.org/wiki/MKS_MINI_12864 +// +//#define MKS_MINI_12864 + +// +// Factory display for Creality CR-10 +// https://www.aliexpress.com/item/Universal-LCD-12864-3D-Printer-Display-Screen-With-Encoder-For-CR-10-CR-7-Model/32833148327.html +// +// This is RAMPS-compatible using a single 10-pin connector. +// (For CR-10 owners who want to replace the Melzi Creality board but retain the display) +// +//#define CR10_STOCKDISPLAY + +// +// MKS OLED 1.3" 128 × 64 FULL GRAPHICS CONTROLLER +// http://reprap.org/wiki/MKS_12864OLED +// +// Tiny, but very sharp OLED display +// +//#define MKS_12864OLED + +//============================================================================= +//=============================== Extra Features ============================== +//============================================================================= + +// @section extras + +// Increase the FAN PWM frequency. Removes the PWM noise but increases heating in the FET/Arduino +//#define FAST_PWM_FAN + +// Use software PWM to drive the fan, as for the heaters. This uses a very low frequency +// which is not as annoying as with the hardware PWM. On the other hand, if this frequency +// is too low, you should also increment SOFT_PWM_SCALE. +#define FAN_SOFT_PWM + +// Incrementing this by 1 will double the software PWM frequency, +// affecting heaters, and the fan if FAN_SOFT_PWM is enabled. +// However, control resolution will be halved for each increment; +// at zero value, there are 128 effective control positions. +#define SOFT_PWM_SCALE 0 + +// If SOFT_PWM_SCALE is set to a value higher than 0, dithering can +// be used to mitigate the associated resolution loss. If enabled, +// some of the PWM cycles are stretched so on average the desired +// duty cycle is attained. +//#define SOFT_PWM_DITHER + +// Temperature status LEDs that display the hotend and bed temperature. +// If all hotends, bed temperature, and target temperature are under 54C +// then the BLUE led is on. Otherwise the RED led is on. (1C hysteresis) +//#define TEMP_STAT_LEDS + +// M240 Triggers a camera by emulating a Canon RC-1 Remote +// Data from: http://www.doc-diy.net/photo/rc-1_hacked/ +//#define PHOTOGRAPH_PIN 23 + +// 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 + +// Support for BlinkM/CyzRgb +//#define BLINKM + +// Support for PCA9632 PWM LED driver +//#define PCA9632 + +/** + * RGB LED / LED Strip Control + * + * Enable support for an RGB LED connected to 5V digital pins, or + * an RGB Strip connected to MOSFETs controlled by digital pins. + * + * 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 overall brightness parameters is also available + * + * *** CAUTION *** + * LED Strips require a MOFSET 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! + * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino + * cannot handle such current, separate 5V power supply must be used + * *** CAUTION *** + * + * LED type. This options are mutualy exclusive. Uncomment only one. + * + */ +//#define RGB_LED +//#define RGBW_LED + +#if ENABLED(RGB_LED) || ENABLED(RGBW_LED) + #define RGB_LED_R_PIN 34 + #define RGB_LED_G_PIN 43 + #define RGB_LED_B_PIN 35 + #define RGB_LED_W_PIN -1 +#endif + +// 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 (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) + #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip + #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time + #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + //#define NEOPIXEL_STARTUP_TEST // Cycle through colors at startup +#endif + +/** + * Printer Event LEDs + * + * During printing, the LEDs will reflect the printer status: + * + * - Gradually change from blue to violet as the heated bed gets to target temp + * - Gradually change from violet to red as the hotend gets to temperature + * - Change to white to illuminate work surface + * - Change to green once print has finished + * - Turn off after the print has finished and the user has pushed a button + */ +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) + #define PRINTER_EVENT_LEDS +#endif + +/*********************************************************************\ +* R/C SERVO support +* Sponsored by TrinityLabs, Reworked by codexmas +**********************************************************************/ + +// Number of servos +// +// If you select a configuration below, this will receive a default value and does not need to be set manually +// set it manually if you have more servos than extruders and wish to manually control some +// leaving it undefined or defining as 0 will disable the servo subsystem +// If unsure, leave commented / disabled +// +//#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command + +// Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. +// 300ms is a good value but you can try less delay. +// If the servo can't reach the requested position, increase it. +#define SERVO_DELAY { 300 } + +// Servo deactivation +// +// With this option servos are powered only during movement, then turned off to prevent jitter. +//#define DEACTIVATE_SERVOS_AFTER_MOVE + +/** + * Filament Width Sensor + * + * Measures the filament width in real-time and adjusts + * flow rate to compensate for any irregularities. + * + * Also allows the measured filament diameter to set the + * extrusion rate, so the slicer only has to specify the + * volume. + * + * Only a single extruder is supported at this time. + * + * 34 RAMPS_14 : Analog input 5 on the AUX2 connector + * 81 PRINTRBOARD : Analog input 2 on the Exp1 connector (version B,C,D,E) + * 301 RAMBO : Analog input 3 + * + * Note: May require analog pins to be defined for other boards. + */ +//#define FILAMENT_WIDTH_SENSOR + +#define DEFAULT_NOMINAL_FILAMENT_DIA 3.00 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. + +#if ENABLED(FILAMENT_WIDTH_SENSOR) + #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) + #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber + + #define MEASURED_UPPER_LIMIT 2.00 // (mm) Upper limit used to validate sensor reading + #define MEASURED_LOWER_LIMIT 1.60 // (mm) Lower limit used to validate sensor reading + #define MAX_MEASUREMENT_DELAY 20 // (bytes) Buffer size for stored measurements (1 byte per cm). Must be larger than MEASUREMENT_DELAY_CM. + + #define DEFAULT_MEASURED_FILAMENT_DIA DEFAULT_NOMINAL_FILAMENT_DIA // Set measured to nominal initially + + // Display filament width on the LCD status line. Status messages will expire after 5 seconds. + //#define FILAMENT_LCD_DISPLAY +#endif + +#endif // CONFIGURATION_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/BQ/Hephestos_2/Configuration_adv.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/BQ/Hephestos_2/Configuration_adv.h new file mode 100644 index 00000000..a89e6978 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/BQ/Hephestos_2/Configuration_adv.h @@ -0,0 +1,1424 @@ +/** + * 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 . + * + */ + +/** + * Configuration_adv.h + * + * Advanced settings. + * Only change these if you know exactly what you're doing. + * Some of these settings can damage your printer if improperly set! + * + * Basic settings can be found in Configuration.h + * + */ +#ifndef CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H_VERSION 010100 + +// @section temperature + +//=========================================================================== +//=============================Thermal Settings ============================ +//=========================================================================== + +#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 + #endif +#endif + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * The solution: Once the temperature reaches the target, start observing. + * If the temperature stays too far below the target (hysteresis) for too long (period), + * the firmware will halt the machine as a safety precaution. + * + * If you get false positives for "Thermal Runaway" increase THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD + */ +#if ENABLED(THERMAL_PROTECTION_HOTENDS) + #define THERMAL_PROTECTION_PERIOD 40 // Seconds + #define THERMAL_PROTECTION_HYSTERESIS 4 // Degrees Celsius + + /** + * Whenever an M104 or M109 increases the target temperature the firmware will wait for the + * WATCH_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get false positives for "Heating failed" increase WATCH_TEMP_PERIOD and/or decrease WATCH_TEMP_INCREASE + * WATCH_TEMP_INCREASE should not be below 2. + */ + #define WATCH_TEMP_PERIOD 20 // Seconds + #define WATCH_TEMP_INCREASE 2 // Degrees Celsius +#endif + +/** + * Thermal Protection parameters for the bed are just as above for hotends. + */ +#if ENABLED(THERMAL_PROTECTION_BED) + #define THERMAL_PROTECTION_BED_PERIOD 20 // Seconds + #define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius + + /** + * Whenever an M140 or M190 increases the target temperature the firmware will wait for the + * WATCH_BED_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_BED_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get too many "Heating failed" errors, increase WATCH_BED_TEMP_PERIOD and/or decrease + * WATCH_BED_TEMP_INCREASE. (WATCH_BED_TEMP_INCREASE should not be below 2.) + */ + #define WATCH_BED_TEMP_PERIOD 60 // Seconds + #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius +#endif + +#if ENABLED(PIDTEMP) + // this adds an experimental additional term to the heating power, proportional to the extrusion speed. + // if Kc is chosen well, the additional required power due to increased melting should be compensated. + //#define PID_EXTRUSION_SCALING + #if ENABLED(PID_EXTRUSION_SCALING) + #define DEFAULT_Kc (100) //heating power=Kc*(e_speed) + #define LPQ_MAX_LEN 50 + #endif +#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 + */ +#define AUTOTEMP +#if ENABLED(AUTOTEMP) + #define AUTOTEMP_OLDWEIGHT 0.98 +#endif + +// Show Temperature ADC value +// Enable for M105 to include ADC values read from temperature sensors. +//#define SHOW_TEMP_ADC_VALUES + +/** + * High Temperature Thermistor Support + * + * Thermistors able to support high temperature tend to have a hard time getting + * good readings at room and lower temperatures. This means HEATER_X_RAW_LO_TEMP + * will probably be caught when the heating element first turns on during the + * preheating process, which will trigger a min_temp_error as a safety measure + * and force stop everything. + * To circumvent this limitation, we allow for a preheat time (during which, + * min_temp_error won't be triggered) and add a min_temp buffer to handle + * aberrant readings. + * + * If you want to enable this feature for your hotend thermistor(s) + * uncomment and set values > 0 in the constants below + */ + +// The number of consecutive low temperature errors that can occur +// before a min_temp_error is triggered. (Shouldn't be more than 10.) +//#define MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED 0 + +// The number of milliseconds a hotend will preheat before starting to check +// the temperature. This value should NOT be set to the time it takes the +// hot end to reach the target temperature, but the time it takes to reach +// the minimum temperature your thermistor can read. The lower the better/safer. +// This shouldn't need to be more than 30 seconds (30000) +//#define MILLISECONDS_PREHEAT_TIME 0 + +// @section extruder + +// Extruder runout prevention. +// If the machine is idle and the temperature over MINTEMP +// then extrude some filament every couple of SECONDS. +#define EXTRUDER_RUNOUT_PREVENT +#if ENABLED(EXTRUDER_RUNOUT_PREVENT) + #define EXTRUDER_RUNOUT_MINTEMP 170 + #define EXTRUDER_RUNOUT_SECONDS 60 + #define EXTRUDER_RUNOUT_SPEED 1500 // mm/m + #define EXTRUDER_RUNOUT_EXTRUDE 5 // mm +#endif + +// @section temperature + +//These defines help to calibrate the AD595 sensor in case you get wrong temperature measurements. +//The measured temperature is defined as "actualTemp = (measuredTemp * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET" +#define TEMP_SENSOR_AD595_OFFSET 0.0 +#define TEMP_SENSOR_AD595_GAIN 1.0 + +/** + * 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. + */ +//#define USE_CONTROLLER_FAN +#if ENABLED(USE_CONTROLLER_FAN) + //#define CONTROLLER_FAN_PIN FAN1_PIN // 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 +#endif + +// When first starting the main fan, run it at full speed for the +// given number of milliseconds. This gets the fan spinning reliably +// before setting a PWM value. (Does not work with software PWM for fan on Sanguinololu) +//#define FAN_KICKSTART_TIME 100 + +// This defines the minimal speed for the main fan, run in PWM mode +// to enable uncomment and set minimal PWM speed for reliable running (1-255) +// if fan speed is [1 - (FAN_MIN_PWM-1)] it is set to FAN_MIN_PWM +//#define FAN_MIN_PWM 50 + +// @section extruder + +/** + * Extruder cooling fans + * + * Extruder auto fans automatically turn on when their extruders' + * temperatures go above EXTRUDER_AUTO_FAN_TEMPERATURE. + * + * Your board's pins file specifies the recommended pins. Override those here + * or set to -1 to disable completely. + * + * Multiple extruders can be assigned to the same pin in which case + * the fan will turn on when any selected extruder is above the threshold. + */ +//#define E0_AUTO_FAN_PIN -1 +//#define E1_AUTO_FAN_PIN -1 +#define E2_AUTO_FAN_PIN -1 +#define E3_AUTO_FAN_PIN -1 +#define E4_AUTO_FAN_PIN -1 +#define EXTRUDER_AUTO_FAN_TEMPERATURE 50 +#define EXTRUDER_AUTO_FAN_SPEED 255 // == full speed + +/** + * Part-Cooling Fan Multiplexer + * + * This feature allows you to digitally multiplex the fan output. + * The multiplexer is automatically switched at tool-change. + * Set FANMUX[012]_PINs below for up to 2, 4, or 8 multiplexed fans. + */ +#define FANMUX0_PIN -1 +#define FANMUX1_PIN -1 +#define FANMUX2_PIN -1 + +/** + * M355 Case Light on-off / brightness + */ +//#define CASE_LIGHT_ENABLE +#if ENABLED(CASE_LIGHT_ENABLE) + //#define CASE_LIGHT_PIN 4 // Override the default pin if needed + #define INVERT_CASE_LIGHT false // Set true if Case Light is ON when pin is LOW + #define CASE_LIGHT_DEFAULT_ON true // Set default power-up state on + #define CASE_LIGHT_DEFAULT_BRIGHTNESS 105 // Set default power-up brightness (0-255, requires PWM pin) + //#define MENU_ITEM_CASE_LIGHT // Add a Case Light option to the LCD main menu +#endif + +//=========================================================================== +//============================ Mechanical Settings ========================== +//=========================================================================== + +// @section homing + +// If you want endstops to stay on (by default) even when not homing +// enable this option. Override at any time with M120, M121. +//#define ENDSTOPS_ALWAYS_ON_DEFAULT + +// @section extras + +//#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. + +// Dual X Steppers +// Uncomment this option to drive two X axis motors. +// The next unused E driver will be assigned to the second X stepper. +//#define X_DUAL_STEPPER_DRIVERS +#if ENABLED(X_DUAL_STEPPER_DRIVERS) + // Set true if the two X motors need to rotate in opposite directions + #define INVERT_X2_VS_X_DIR true +#endif + +// Dual Y Steppers +// Uncomment this option to drive two Y axis motors. +// The next unused E driver will be assigned to the second Y stepper. +//#define Y_DUAL_STEPPER_DRIVERS +#if ENABLED(Y_DUAL_STEPPER_DRIVERS) + // Set true if the two Y motors need to rotate in opposite directions + #define INVERT_Y2_VS_Y_DIR true +#endif + +// A single Z stepper driver is usually used to drive 2 stepper motors. +// Uncomment this option to use a separate stepper driver for each Z axis motor. +// The next unused E driver will be assigned to the second Z stepper. +//#define Z_DUAL_STEPPER_DRIVERS + +#if ENABLED(Z_DUAL_STEPPER_DRIVERS) + + // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper. + // That way the machine is capable to align the bed during home, since both Z steppers are homed. + // There is also an implementation of M666 (software endstops adjustment) to this feature. + // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed. + // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2. + // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive. + // Play a little bit with small adjustments (0.5mm) and check the behaviour. + // The M119 (endstops report) will start reporting the Z2 Endstop as well. + + //#define Z_DUAL_ENDSTOPS + + #if ENABLED(Z_DUAL_ENDSTOPS) + #define Z2_USE_ENDSTOP _XMAX_ + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 // Use M666 to determine/test this value + #endif + +#endif // Z_DUAL_STEPPER_DRIVERS + +// Enable this for dual x-carriage printers. +// A dual x-carriage design has the advantage that the inactive extruder can be parked which +// prevents hot-end ooze contaminating the print. It also reduces the weight of each x-carriage +// allowing faster printing speeds. Connect your X2 stepper to the first unused E plug. +//#define DUAL_X_CARRIAGE +#if ENABLED(DUAL_X_CARRIAGE) + // Configuration for second X-carriage + // Note: the first x-carriage is defined as the x-carriage which homes to the minimum endstop; + // the second x-carriage always homes to the maximum endstop. + #define X2_MIN_POS 80 // set minimum to ensure second x-carriage doesn't hit the parked first X-carriage + #define X2_MAX_POS 353 // set maximum to the distance between toolheads when both heads are homed + #define X2_HOME_DIR 1 // the second X-carriage always homes to the maximum endstop position + #define X2_HOME_POS X2_MAX_POS // default home position is the maximum carriage position + // However: In this mode the HOTEND_OFFSET_X value for the second extruder provides a software + // override for X2_HOME_POS. This also allow recalibration of the distance between the two endstops + // without modifying the firmware (through the "M218 T1 X???" command). + // Remember: you should set the second extruder x-offset to 0 in your slicer. + + // There are a few selectable movement modes for dual x-carriages using M605 S + // Mode 0 (DXC_FULL_CONTROL_MODE): Full control. The slicer has full control over both x-carriages and can achieve optimal travel results + // as long as it supports dual x-carriages. (M605 S0) + // Mode 1 (DXC_AUTO_PARK_MODE) : Auto-park mode. The firmware will automatically park and unpark the x-carriages on tool changes so + // that additional slicer support is not required. (M605 S1) + // Mode 2 (DXC_DUPLICATION_MODE) : Duplication mode. The firmware will transparently make the second x-carriage and extruder copy all + // actions of the first x-carriage. This allows the printer to print 2 arbitrary items at + // once. (2nd extruder x offset and temp offset are set using: M605 S2 [Xnnn] [Rmmm]) + + // This is the default power-up mode which can be later using M605. + #define DEFAULT_DUAL_X_CARRIAGE_MODE DXC_FULL_CONTROL_MODE + + // Default settings in "Auto-park Mode" + #define TOOLCHANGE_PARK_ZLIFT 0.2 // the distance to raise Z axis when parking an extruder + #define TOOLCHANGE_UNPARK_ZLIFT 1 // the distance to raise Z axis when unparking an extruder + + // Default x offset in duplication mode (typically set to half print bed width) + #define DEFAULT_DUPLICATION_X_OFFSET 100 + +#endif // DUAL_X_CARRIAGE + +// 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. +//#define EXT_SOLENOID + +// @section homing + +//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +#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 this is defined, if both x and y are to be homed, a diagonal move will be performed initially. + +// When G28 is called, this option will make Y home before X +#define HOME_Y_BEFORE_X + +// @section machine + +#define AXIS_RELATIVE_MODES {false, false, false, false} + +// Allow duplication mode with a basic dual-nozzle extruder +//#define DUAL_NOZZLE_DUPLICATION_MODE + +// By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step. +#define INVERT_X_STEP_PIN false +#define INVERT_Y_STEP_PIN false +#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. +#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_E true + +#define DEFAULT_MINIMUMFEEDRATE 0.0 // minimum feedrate +#define DEFAULT_MINTRAVELFEEDRATE 0.0 + +#define HOME_AFTER_DEACTIVATE // Require rehoming after steppers are deactivated + +// @section lcd + +#if ENABLED(ULTIPANEL) + #define MANUAL_FEEDRATE {50*60, 50*60, 4*60, 60} // Feedrates for manual moves along X, Y, Z, E from panel + //#define ULTIPANEL_FEEDMULTIPLY // Comment to disable setting feedrate multiplier via encoder +#endif + +// @section extras + +// minimum time in microseconds that a movement needs to take if the buffer is emptied. +#define DEFAULT_MINSEGMENTTIME 20000 + +// If defined the movements slow down when the look ahead buffer is only half full +#define SLOWDOWN + +// Frequency limit +// See nophead's blog for more info +// Not working O +//#define XY_FREQUENCY_LIMIT 15 + +// 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 +// if unwanted behavior is observed on a user's machine when running at very slow speeds. +#define MINIMUM_PLANNER_SPEED 0.05 // (mm/sec) + +// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU. +#define MICROSTEP_MODES {16,16,16,16,16} // [1,2,4,8,16] + +/** + * @section stepper motor current + * + * Some boards have a means of setting the stepper motor current via firmware. + * + * The power on motor currents are set by: + * PWM_MOTOR_CURRENT - used by MINIRAMBO & ULTIMAIN_2 + * known compatible chips: A4982 + * DIGIPOT_MOTOR_CURRENT - used by BQ_ZUM_MEGA_3D, RAMBO & SCOOVO_X9H + * known compatible chips: AD5206 + * DAC_MOTOR_CURRENT_DEFAULT - used by PRINTRBOARD_REVF & RIGIDBOARD_V2 + * known compatible chips: MCP4728 + * DIGIPOT_I2C_MOTOR_CURRENTS - used by 5DPRINT, AZTEEG_X3_PRO, MIGHTYBOARD_REVE + * known compatible chips: MCP4451, MCP4018 + * + * Motor currents can also be set by M907 - M910 and by the LCD. + * M907 - applies to all. + * M908 - BQ_ZUM_MEGA_3D, RAMBO, PRINTRBOARD_REVF, RIGIDBOARD_V2 & SCOOVO_X9H + * M909, M910 & LCD - only PRINTRBOARD_REVF & RIGIDBOARD_V2 + */ +//#define PWM_MOTOR_CURRENT { 1300, 1300, 1250 } // Values in milliamps +#define DIGIPOT_MOTOR_CURRENT { 150, 170, 180, 190, 180 } // Values 0-255 (bq ZUM Mega 3D (default): X = 150 [~1.17A]; Y = 170 [~1.33A]; Z = 180 [~1.41A]; E0 = 190 [~1.49A]) +//#define DAC_MOTOR_CURRENT_DEFAULT { 70, 80, 90, 80 } // Default drive percent - X, Y, Z, E axis + +// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +//#define DIGIPOT_I2C +//#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster +#define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 +// Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS +#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=========================== +//=========================================================================== + +//#define ENCODER_RATE_MULTIPLIER // If defined, certain menu edit operations automatically multiply the steps when the encoder is moved quickly +//#define ENCODER_10X_STEPS_PER_SEC 75 // If the encoder steps per sec exceeds this value, multiply steps moved x10 to quickly advance the value +//#define ENCODER_100X_STEPS_PER_SEC 160 // If the encoder steps per sec exceeds this value, multiply steps moved x100 to really quickly advance the value + +//#define CHDK 4 //Pin for triggering CHDK to take a picture see how to use it here http://captain-slow.dk/2014/03/09/3d-printing-timelapses/ +//#define CHDK_DELAY 50 //How long in ms the pin should stay HIGH before going LOW again + +// @section lcd + +// Include a page of printer information in the LCD Main Menu +#define LCD_INFO_MENU + +// Scroll a longer status message into view +#define STATUS_MESSAGE_SCROLLING + +// On the Info Screen, display XY with one decimal place when possible +#define LCD_DECIMAL_SMALL_XY + +// The timeout (in ms) to return to the status screen from sub-menus +//#define LCD_TIMEOUT_TO_STATUS 15000 + +#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 + + #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? + #define SD_FINISHED_RELEASECOMMAND "M104 S0\nM84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. + + #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. + // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. + // using: + //#define MENU_ADDAUTOSTART + + /** + * Sort SD file listings in alphabetical order. + * + * With this option enabled, items on SD cards will be sorted + * by name for easier navigation. + * + * By default... + * + * - Use the slowest -but safest- method for sorting. + * - Folders are sorted to the top. + * - The sort key is statically allocated. + * - No added G-code (M34) support. + * - 40 item sorting limit. (Items after the first 40 are unsorted.) + * + * SD sorting uses static allocation (as set by SDSORT_LIMIT), allowing the + * compiler to calculate the worst-case usage and throw an error if the SRAM + * limit is exceeded. + * + * - SDSORT_USES_RAM provides faster sorting via a static directory buffer. + * - SDSORT_USES_STACK does the same, but uses a local stack-based buffer. + * - SDSORT_CACHE_NAMES will retain the sorted file listing in RAM. (Expensive!) + * - SDSORT_DYNAMIC_RAM only uses RAM when the SD menu is visible. (Use with caution!) + */ + //#define SDCARD_SORT_ALPHA + + // SD Card Sorting options + #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_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. + #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #endif + + // Show a progress bar on HD44780 LCDs for SD printing + //#define LCD_PROGRESS_BAR + + #if ENABLED(LCD_PROGRESS_BAR) + // Amount of time (ms) to show the bar + #define PROGRESS_BAR_BAR_TIME 2000 + // Amount of time (ms) to show the status message + #define PROGRESS_BAR_MSG_TIME 3000 + // Amount of time (ms) to retain the status message (0=forever) + #define PROGRESS_MSG_EXPIRE 0 + // Enable this to show messages for MSG_TIME then hide them + //#define PROGRESS_MSG_ONCE + // Add a menu item to test the progress bar: + //#define LCD_PROGRESS_BAR_TEST + #endif + + // This allows hosts to request long names for files and folders with M33 + #define LONG_FILENAME_HOST_SUPPORT + + // This option allows you to abort SD printing when any endstop is triggered. + // This feature must be enabled with "M540 S1" or from the LCD menu. + // To have any effect, endstops must be enabled during SD printing. + //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + +#endif // SDSUPPORT + +/** + * Additional options for Graphical Displays + * + * Use the optimizations here to improve printing performance, + * which can be adversely affected by graphical display drawing, + * especially when doing several short moves, and when printing + * on DELTA and SCARA machines. + * + * Some of these options may result in the display lagging behind + * controller events, as there is a trade-off between reliable + * printing performance versus fast display updates. + */ +#if ENABLED(DOGLCD) + // Enable to save many cycles by drawing a hollow frame on the Info Screen + #define XYZ_HOLLOW_FRAME + + // Enable to save many cycles by drawing a hollow frame on Menu Screens + #define MENU_HOLLOW_FRAME + + // A bigger font is available for edit items. Costs 3120 bytes of PROGMEM. + // 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. + // 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 +#endif // DOGLCD + +// @section safety + +// The hardware watchdog should reset the microcontroller disabling all outputs, +// in case the firmware gets stuck and doesn't do temperature regulation. +#define USE_WATCHDOG + +#if ENABLED(USE_WATCHDOG) + // If you have a watchdog reboot in an ArduinoMega2560 then the device will hang forever, as a watchdog reset will leave the watchdog on. + // The "WATCHDOG_RESET_MANUAL" goes around this by not using the hardware reset. + // However, THIS FEATURE IS UNSAFE!, as it will only work if interrupts are disabled. And the code could hang in an interrupt routine with interrupts disabled. + //#define WATCHDOG_RESET_MANUAL +#endif + +// @section lcd + +/** + * Babystepping enables movement of the axes by tiny increments without changing + * the current position values. This feature is used primarily to adjust the Z + * axis in the first layer of a print in real-time. + * + * Warning: Does not respect endstops! + */ +//#define BABYSTEPPING +#if ENABLED(BABYSTEPPING) + //#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 100 // Babysteps are very small. Increase for faster motion. + //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping + //#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen 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_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor + //#define BABYSTEP_ZPROBE_GFX_REVERSE // Reverses the direction of the CW/CCW indicators +#endif + +// @section extruder + +/** + * Implementation of linear pressure control + * + * Assumption: advance = k * (delta velocity) + * K=0 means advance disabled. + * See Marlin documentation for calibration instructions. + */ +//#define LIN_ADVANCE + +#if ENABLED(LIN_ADVANCE) + #define LIN_ADVANCE_K 75 + + /** + * Some Slicers produce Gcode with randomly jumping extrusion widths occasionally. + * For example within a 0.4mm perimeter it may produce a single segment of 0.05mm width. + * While this is harmless for normal printing (the fluid nature of the filament will + * close this very, very tiny gap), it throws off the LIN_ADVANCE pressure adaption. + * + * For this case LIN_ADVANCE_E_D_RATIO can be used to set the extrusion:distance ratio + * to a fixed value. Note that using a fixed ratio will lead to wrong nozzle pressures + * if the slicer is using variable widths or layer heights within one print! + * + * This option sets the default E:D ratio at startup. Use `M900` to override this value. + * + * Example: `M900 W0.4 H0.2 D1.75`, where: + * - W is the extrusion width in mm + * - H is the layer height in mm + * - D is the filament diameter in mm + * + * Example: `M900 R0.0458` to set the ratio directly. + * + * Set to 0 to auto-detect the ratio based on given Gcode G1 print moves. + * + * Slic3r (including Průša Control) produces Gcode compatible with the automatic mode. + * Cura (as of this writing) may produce Gcode incompatible with the automatic mode. + */ + #define LIN_ADVANCE_E_D_RATIO 0 // The calculated ratio (or 0) according to the formula W * H / ((D / 2) ^ 2 * PI) + // Example: 0.4 * 0.2 / ((1.75 / 2) ^ 2 * PI) = 0.033260135 +#endif + +// @section leveling + +// Default mesh area is an area with an inset margin on the print area. +// Below are the macros that are used to define the borders for the mesh area, +// made available here for specialized needs, ie dual extruder setup. +#if ENABLED(MESH_BED_LEVELING) + #define MESH_MIN_X MESH_INSET + #define MESH_MAX_X (X_BED_SIZE - (MESH_INSET)) + #define MESH_MIN_Y MESH_INSET + #define MESH_MAX_Y (Y_BED_SIZE - (MESH_INSET)) +#elif ENABLED(AUTO_BED_LEVELING_UBL) + #define UBL_MESH_MIN_X UBL_MESH_INSET + #define UBL_MESH_MAX_X (X_BED_SIZE - (UBL_MESH_INSET)) + #define UBL_MESH_MIN_Y UBL_MESH_INSET + #define UBL_MESH_MAX_Y (Y_BED_SIZE - (UBL_MESH_INSET)) + + // If this is defined, the currently active mesh will be saved in the + // current slot on M500. + #define UBL_SAVE_ACTIVE_ON_M500 +#endif + +// @section extras + +// +// G2/G3 Arc Support +// +#define ARC_SUPPORT // Disable this feature to save ~3226 bytes +#if ENABLED(ARC_SUPPORT) + #define MM_PER_ARC_SEGMENT 1 // Length of each arc segment + #define N_ARC_CORRECTION 25 // Number of intertpolated 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 +#endif + +// Support for G5 with XYZE destination and IJPQ offsets. Requires ~2666 bytes. +//#define BEZIER_CURVE_SUPPORT + +// G38.2 and G38.3 Probe Target +// Enable PROBE_DOUBLE_TOUCH if you want G38 to double touch +//#define G38_PROBE_TARGET +#if ENABLED(G38_PROBE_TARGET) + #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) +#endif + +// Moves (or segments) with fewer steps than this will be joined with the next move +#define MIN_STEPS_PER_SEGMENT 6 + +// The minimum pulse width (in µs) for stepping a stepper. +// Set this if you find stepping unreliable, or if using a very fast CPU. +#define MINIMUM_STEPPER_PULSE 0 // (µs) The smallest stepper pulse allowed + +// @section temperature + +// Control heater 0 and heater 1 in parallel. +//#define HEATERS_PARALLEL + +//=========================================================================== +//================================= Buffers ================================= +//=========================================================================== + +// @section hidden + +// 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, i.g. 8,16,32 because shifts and ors are used to do the ring-buffering. +#if ENABLED(SDSUPPORT) + #define BLOCK_BUFFER_SIZE 32 // SD,LCD,Buttons take more memory, block buffer needs to be smaller +#else + #define BLOCK_BUFFER_SIZE 64 // maximize block buffer +#endif + +// @section serial + +// The ASCII buffer for serial input +#define MAX_CMD_SIZE 96 +#define BUFSIZE 4 + +// Transmission to Host Buffer Size +// To save 386 bytes of PROGMEM (and TX_BUFFER_SIZE+3 bytes of RAM) set to 0. +// To buffer a simple "ok" you need 4 bytes. +// For ADVANCED_OK (M105) you need 32 bytes. +// For debug-echo: 128 bytes for the optimal speed. +// Other output doesn't need to be that speedy. +// :[0, 2, 4, 8, 16, 32, 64, 128, 256] +#define TX_BUFFER_SIZE 32 + +// Host Receive Buffer Size +// Without XON/XOFF flow control (see SERIAL_XON_XOFF below) 32 bytes should be enough. +// To use flow control, set this buffer size to at least 1024 bytes. +// :[0, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048] +//#define RX_BUFFER_SIZE 1024 + +#if RX_BUFFER_SIZE >= 1024 + // Enable to have the controller send XON/XOFF control characters to + // the host to signal the RX buffer is becoming full. + //#define SERIAL_XON_XOFF +#endif + +#if ENABLED(SDSUPPORT) + // Enable this option to collect and display the maximum + // RX queue usage after transferring a file to SD. + //#define SERIAL_STATS_MAX_RX_QUEUED + + // Enable this option to collect and display the number + // of dropped bytes after a file transfer to SD. + //#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! +#define EMERGENCY_PARSER + +// Bad Serial-connections can miss a received command by sending an 'ok' +// Therefore some clients abort after 30 seconds in a timeout. +// Some other clients start sending commands while receiving a 'wait'. +// This "wait" is only sent when the buffer is empty. 1 second is a good value here. +//#define NO_TIMEOUTS 1000 // Milliseconds + +// Some clients will have this feature soon. This could make the NO_TIMEOUTS unnecessary. +#define ADVANCED_OK + +// @section extras + +/** + * Firmware-based and LCD-controlled retract + * + * Add G10 / G11 commands for automatic firmware-based retract / recover. + * Use M207 and M208 to define parameters for retract / recover. + * + * Use M209 to enable or disable auto-retract. + * With auto-retract enabled, all G1 E moves within the set range + * will be converted to firmware-based retract/recover moves. + * + * Be sure to turn off auto-retract during filament change. + * + * Note that M207 / M208 / M209 settings are saved to EEPROM. + * + */ +//#define FWRETRACT // ONLY PARTIALLY TESTED +#if ENABLED(FWRETRACT) + #define MIN_AUTORETRACT 0.1 // When auto-retract is on, convert E moves of this length and over + #define MAX_AUTORETRACT 10.0 // Upper limit for auto-retract conversion + #define RETRACT_LENGTH 3 // Default retract length (positive mm) + #define RETRACT_LENGTH_SWAP 13 // Default swap retract length (positive mm), for extruder change + #define RETRACT_FEEDRATE 45 // Default feedrate for retracting (mm/s) + #define RETRACT_ZLIFT 0 // Default retract Z-lift + #define RETRACT_RECOVER_LENGTH 0 // Default additional recover length (mm, added to retract length when recovering) + #define RETRACT_RECOVER_LENGTH_SWAP 0 // Default additional swap recover length (mm, added to retract length when recovering from extruder change) + #define RETRACT_RECOVER_FEEDRATE 8 // Default feedrate for recovering from retraction (mm/s) + #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) +#endif + +/** + * Advanced Pause + * Experimental feature for filament change support and for parking the nozzle when paused. + * Adds the GCode M600 for initiating filament change. + * If PARK_HEAD_ON_PAUSE enabled, adds the GCode M125 to pause printing and park the nozzle. + * + * Requires an LCD display. + * This feature is required for the default FILAMENT_RUNOUT_SCRIPT. + */ +//#define ADVANCED_PAUSE_FEATURE +#if ENABLED(ADVANCED_PAUSE_FEATURE) + #define PAUSE_PARK_X_POS 3 // X position of hotend + #define PAUSE_PARK_Y_POS 3 // Y position of hotend + #define PAUSE_PARK_Z_ADD 10 // Z addition of hotend (lift) + #define PAUSE_PARK_XY_FEEDRATE 100 // X and Y axes feedrate in mm/s (also used for delta printers Z axis) + #define PAUSE_PARK_Z_FEEDRATE 5 // Z axis feedrate in mm/s (not used for delta printers) + #define PAUSE_PARK_RETRACT_FEEDRATE 60 // Initial retract feedrate in mm/s + #define PAUSE_PARK_RETRACT_LENGTH 2 // Initial retract in mm + // It is a short retract used immediately after print interrupt before move to filament exchange position + #define FILAMENT_CHANGE_UNLOAD_FEEDRATE 10 // Unload filament feedrate in mm/s - filament unloading can be fast + #define FILAMENT_CHANGE_UNLOAD_LENGTH 100 // Unload filament length from hotend in mm + // Longer length for bowden printers to unload filament from whole bowden tube, + // shorter length for printers without bowden to unload filament from extruder only, + // 0 to disable unloading for manual unloading + #define FILAMENT_CHANGE_LOAD_FEEDRATE 6 // Load filament feedrate in mm/s - filament loading into the bowden tube can be fast + #define FILAMENT_CHANGE_LOAD_LENGTH 0 // Load filament length over hotend in mm + // Longer length for bowden printers to fast load filament into whole bowden tube over the hotend, + // Short or zero length for printers without bowden where loading is not used + #define ADVANCED_PAUSE_EXTRUDE_FEEDRATE 3 // Extrude filament feedrate in mm/s - must be slower than load feedrate + #define ADVANCED_PAUSE_EXTRUDE_LENGTH 50 // Extrude filament length in mm after filament is loaded over the hotend, + // 0 to disable for manual extrusion + // Filament can be extruded repeatedly from the filament exchange menu to fill the hotend, + // or until outcoming filament color is not clear for filament color change + #define PAUSE_PARK_NOZZLE_TIMEOUT 45 // Turn off nozzle if user doesn't change filament within this time limit in seconds + #define FILAMENT_CHANGE_NUMBER_OF_ALERT_BEEPS 5 // Number of alert beeps before printer goes quiet + #define PAUSE_PARK_NO_STEPPER_TIMEOUT // Enable to have stepper motors hold position during filament change + // even if it takes longer than DEFAULT_STEPPER_DEACTIVE_TIME. + //#define PARK_HEAD_ON_PAUSE // Go to filament change position on pause, return to print position on resume + //#define HOME_BEFORE_FILAMENT_CHANGE // Ensure homing has been completed prior to parking for filament change +#endif + +// @section tmc + +/** + * Enable this section if you have TMC26X motor drivers. + * You will need to import the TMC26XStepper library into the Arduino IDE for this + * (https://github.com/trinamic/TMC26XStepper.git) + */ +//#define HAVE_TMCDRIVER + +#if ENABLED(HAVE_TMCDRIVER) + + //#define X_IS_TMC + //#define X2_IS_TMC + //#define Y_IS_TMC + //#define Y2_IS_TMC + //#define Z_IS_TMC + //#define Z2_IS_TMC + //#define E0_IS_TMC + //#define E1_IS_TMC + //#define E2_IS_TMC + //#define E3_IS_TMC + //#define E4_IS_TMC + + #define X_MAX_CURRENT 1000 // in mA + #define X_SENSE_RESISTOR 91 // in mOhms + #define X_MICROSTEPS 16 // number of microsteps + + #define X2_MAX_CURRENT 1000 + #define X2_SENSE_RESISTOR 91 + #define X2_MICROSTEPS 16 + + #define Y_MAX_CURRENT 1000 + #define Y_SENSE_RESISTOR 91 + #define Y_MICROSTEPS 16 + + #define Y2_MAX_CURRENT 1000 + #define Y2_SENSE_RESISTOR 91 + #define Y2_MICROSTEPS 16 + + #define Z_MAX_CURRENT 1000 + #define Z_SENSE_RESISTOR 91 + #define Z_MICROSTEPS 16 + + #define Z2_MAX_CURRENT 1000 + #define Z2_SENSE_RESISTOR 91 + #define Z2_MICROSTEPS 16 + + #define E0_MAX_CURRENT 1000 + #define E0_SENSE_RESISTOR 91 + #define E0_MICROSTEPS 16 + + #define E1_MAX_CURRENT 1000 + #define E1_SENSE_RESISTOR 91 + #define E1_MICROSTEPS 16 + + #define E2_MAX_CURRENT 1000 + #define E2_SENSE_RESISTOR 91 + #define E2_MICROSTEPS 16 + + #define E3_MAX_CURRENT 1000 + #define E3_SENSE_RESISTOR 91 + #define E3_MICROSTEPS 16 + + #define E4_MAX_CURRENT 1000 + #define E4_SENSE_RESISTOR 91 + #define E4_MICROSTEPS 16 + +#endif + +// @section TMC2130 + +/** + * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. + * + * You'll also need the TMC2130Stepper Arduino library + * (https://github.com/teemuatlut/TMC2130Stepper). + * + * To use TMC2130 stepper drivers in SPI mode connect your SPI2130 pins to + * the hardware SPI interface on your board and define the required CS pins + * in your `pins_MYBOARD.h` file. (e.g., RAMPS 1.4 uses AUX3 pins `X_CS_PIN 53`, `Y_CS_PIN 49`, etc.). + */ +//#define HAVE_TMC2130 + +#if ENABLED(HAVE_TMC2130) + + // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY + //#define X_IS_TMC2130 + //#define X2_IS_TMC2130 + //#define Y_IS_TMC2130 + //#define Y2_IS_TMC2130 + //#define Z_IS_TMC2130 + //#define Z2_IS_TMC2130 + //#define E0_IS_TMC2130 + //#define E1_IS_TMC2130 + //#define E2_IS_TMC2130 + //#define E3_IS_TMC2130 + //#define E4_IS_TMC2130 + + /** + * Stepper driver settings + */ + + #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 + #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current + #define INTERPOLATE 1 // Interpolate X/Y/Z_MICROSTEPS to 256 + + #define X_CURRENT 1000 // rms current in mA. Multiply by 1.41 for peak current. + #define X_MICROSTEPS 16 // 0..256 + + #define Y_CURRENT 1000 + #define Y_MICROSTEPS 16 + + #define Z_CURRENT 1000 + #define Z_MICROSTEPS 16 + + //#define X2_CURRENT 1000 + //#define X2_MICROSTEPS 16 + + //#define Y2_CURRENT 1000 + //#define Y2_MICROSTEPS 16 + + //#define Z2_CURRENT 1000 + //#define Z2_MICROSTEPS 16 + + //#define E0_CURRENT 1000 + //#define E0_MICROSTEPS 16 + + //#define E1_CURRENT 1000 + //#define E1_MICROSTEPS 16 + + //#define E2_CURRENT 1000 + //#define E2_MICROSTEPS 16 + + //#define E3_CURRENT 1000 + //#define E3_MICROSTEPS 16 + + //#define E3_CURRENT 1000 + //#define E3_MICROSTEPS 16 + + /** + * Use Trinamic's ultra quiet stepping mode. + * When disabled, Marlin will use spreadCycle stepping mode. + */ + #define STEALTHCHOP + + /** + * Let Marlin automatically control stepper current. + * This is still an experimental feature. + * Increase current every 5s by CURRENT_STEP until stepper temperature prewarn gets triggered, + * then decrease current by CURRENT_STEP until temperature prewarn is cleared. + * Adjusting starts from X/Y/Z/E_CURRENT but will not increase over AUTO_ADJUST_MAX + * 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. + * M906 S1 - Start adjusting current + * M906 S0 - Stop adjusting current + * M911 - Report stepper driver overtemperature pre-warn condition. + * M912 - Clear stepper driver overtemperature pre-warn condition flag. + */ + //#define AUTOMATIC_CURRENT_CONTROL + + #if ENABLED(AUTOMATIC_CURRENT_CONTROL) + #define CURRENT_STEP 50 // [mA] + #define AUTO_ADJUST_MAX 1300 // [mA], 1300mA_rms = 1840mA_peak + #define REPORT_CURRENT_CHANGE + #endif + + /** + * The driver will switch to spreadCycle when stepper speed is over HYBRID_THRESHOLD. + * This mode allows for faster movements at the expense of higher noise levels. + * STEALTHCHOP needs to be enabled. + * M913 X/Y/Z/E to live tune the setting + */ + //#define HYBRID_THRESHOLD + + #define X_HYBRID_THRESHOLD 100 // [mm/s] + #define X2_HYBRID_THRESHOLD 100 + #define Y_HYBRID_THRESHOLD 100 + #define Y2_HYBRID_THRESHOLD 100 + #define Z_HYBRID_THRESHOLD 4 + #define Z2_HYBRID_THRESHOLD 4 + #define E0_HYBRID_THRESHOLD 30 + #define E1_HYBRID_THRESHOLD 30 + #define E2_HYBRID_THRESHOLD 30 + #define E3_HYBRID_THRESHOLD 30 + #define E4_HYBRID_THRESHOLD 30 + + /** + * Use stallGuard2 to sense an obstacle and trigger an endstop. + * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. + * If used along with STEALTHCHOP, the movement will be louder when homing. This is normal. + * + * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. + * Higher values make the system LESS sensitive. + * Lower value make the system MORE sensitive. + * Too low values can lead to false positives, while too high values will collide the axis without triggering. + * It is advised to set X/Y_HOME_BUMP_MM to 0. + * M914 X/Y to live tune the setting + */ + //#define SENSORLESS_HOMING + + #if ENABLED(SENSORLESS_HOMING) + #define X_HOMING_SENSITIVITY 19 + #define Y_HOMING_SENSITIVITY 19 + #endif + + /** + * You can set your own advanced settings by filling in predefined functions. + * A list of available functions can be found on the library github page + * https://github.com/teemuatlut/TMC2130Stepper + * + * Example: + * #define TMC2130_ADV() { \ + * stepperX.diag0_temp_prewarn(1); \ + * stepperX.interpolate(0); \ + * } + */ + #define TMC2130_ADV() { } + +#endif // HAVE_TMC2130 + +// @section L6470 + +/** + * Enable this section if you have L6470 motor drivers. + * You need to import the L6470 library into the Arduino IDE for this. + * (https://github.com/ameyer/Arduino-L6470) + */ + +//#define HAVE_L6470DRIVER +#if ENABLED(HAVE_L6470DRIVER) + + //#define X_IS_L6470 + //#define X2_IS_L6470 + //#define Y_IS_L6470 + //#define Y2_IS_L6470 + //#define Z_IS_L6470 + //#define Z2_IS_L6470 + //#define E0_IS_L6470 + //#define E1_IS_L6470 + //#define E2_IS_L6470 + //#define E3_IS_L6470 + //#define E4_IS_L6470 + + #define X_MICROSTEPS 16 // number of microsteps + #define X_K_VAL 50 // 0 - 255, Higher values, are higher power. Be careful not to go too high + #define X_OVERCURRENT 2000 // maxc current in mA. If the current goes over this value, the driver will switch off + #define X_STALLCURRENT 1500 // current in mA where the driver will detect a stall + + #define X2_MICROSTEPS 16 + #define X2_K_VAL 50 + #define X2_OVERCURRENT 2000 + #define X2_STALLCURRENT 1500 + + #define Y_MICROSTEPS 16 + #define Y_K_VAL 50 + #define Y_OVERCURRENT 2000 + #define Y_STALLCURRENT 1500 + + #define Y2_MICROSTEPS 16 + #define Y2_K_VAL 50 + #define Y2_OVERCURRENT 2000 + #define Y2_STALLCURRENT 1500 + + #define Z_MICROSTEPS 16 + #define Z_K_VAL 50 + #define Z_OVERCURRENT 2000 + #define Z_STALLCURRENT 1500 + + #define Z2_MICROSTEPS 16 + #define Z2_K_VAL 50 + #define Z2_OVERCURRENT 2000 + #define Z2_STALLCURRENT 1500 + + #define E0_MICROSTEPS 16 + #define E0_K_VAL 50 + #define E0_OVERCURRENT 2000 + #define E0_STALLCURRENT 1500 + + #define E1_MICROSTEPS 16 + #define E1_K_VAL 50 + #define E1_OVERCURRENT 2000 + #define E1_STALLCURRENT 1500 + + #define E2_MICROSTEPS 16 + #define E2_K_VAL 50 + #define E2_OVERCURRENT 2000 + #define E2_STALLCURRENT 1500 + + #define E3_MICROSTEPS 16 + #define E3_K_VAL 50 + #define E3_OVERCURRENT 2000 + #define E3_STALLCURRENT 1500 + + #define E4_MICROSTEPS 16 + #define E4_K_VAL 50 + #define E4_OVERCURRENT 2000 + #define E4_STALLCURRENT 1500 + +#endif + +/** + * TWI/I2C BUS + * + * This feature is an EXPERIMENTAL feature so it shall not be used on production + * machines. Enabling this will allow you to send and receive I2C data from slave + * devices on the bus. + * + * ; Example #1 + * ; This macro send the string "Marlin" to the slave device with address 0x63 (99) + * ; It uses multiple M260 commands with one B arg + * M260 A99 ; Target slave address + * M260 B77 ; M + * M260 B97 ; a + * M260 B114 ; r + * M260 B108 ; l + * M260 B105 ; i + * M260 B110 ; n + * M260 S1 ; Send the current buffer + * + * ; Example #2 + * ; Request 6 bytes from slave device with address 0x63 (99) + * M261 A99 B5 + * + * ; Example #3 + * ; Example serial output of a M261 request + * echo:i2c-reply: from:99 bytes:5 data:hello + */ + +// @section i2cbus + +//#define EXPERIMENTAL_I2CBUS +#define I2C_SLAVE_ADDRESS 0 // Set a value from 8 to 127 to act as a slave + +// @section extras + +/** + * Spindle & Laser control + * + * Add the M3, M4, and M5 commands to turn the spindle/laser on and off, and + * to set spindle speed, spindle direction, and laser power. + * + * SuperPid is a router/spindle speed controller used in the CNC milling community. + * Marlin can be used to turn the spindle on and off. It can also be used to set + * the spindle speed from 5,000 to 30,000 RPM. + * + * 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. + */ +//#define SPINDLE_LASER_ENABLE +#if ENABLED(SPINDLE_LASER_ENABLE) + + #define SPINDLE_LASER_ENABLE_INVERT false // set to "true" if the on/off function is reversed + #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 // delay in milliseconds to allow the spindle/laser to come up to speed/power + #define SPINDLE_LASER_POWERDOWN_DELAY 5000 // delay in milliseconds to allow the spindle to stop + #define SPINDLE_DIR_CHANGE true // set to true if your spindle controller supports changing spindle direction + #define SPINDLE_INVERT_DIR false + #define SPINDLE_STOP_ON_DIR_CHANGE true // set to true if Marlin should stop the spindle before changing rotation direction + + /** + * The M3 & M4 commands use the following equation to convert PWM duty cycle to speed/power + * + * SPEED/POWER = PWM duty cycle * SPEED_POWER_SLOPE + SPEED_POWER_INTERCEPT + * where PWM duty cycle varies from 0 to 255 + * + * set the following for your controller (ALL MUST BE SET) + */ + + #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_SLOPE 0.3922 + //#define SPEED_POWER_INTERCEPT 0 + //#define SPEED_POWER_MIN 10 + //#define SPEED_POWER_MAX 100 // 0-100% +#endif + +/** + * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins + */ +//#define PINS_DEBUGGING + +/** + * Auto-report temperatures with M155 S + */ +#define AUTO_REPORT_TEMPERATURES + +/** + * Include capabilities in M115 output + */ +#define EXTENDED_CAPABILITIES_REPORT + +/** + * Volumetric extrusion default state + * 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. + */ +//#define VOLUMETRIC_DEFAULT_ON + +/** + * Enable this option for a leaner build of Marlin that removes all + * workspace offsets, simplifying coordinate transformations, leveling, etc. + * + * - M206 and M428 are disabled. + * - G92 will revert to its behavior from Marlin 1.0. + */ +//#define NO_WORKSPACE_OFFSETS + +/** + * 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. + * + * For clients that use a fixed-width font (like OctoPrint), leave this set to 1.0. + * Otherwise, adjust according to your client and font. + */ +#define PROPORTIONAL_FONT_RATIO 1.0 + +/** + * Spend 28 bytes of SRAM to optimize the GCode parser + */ +#define FASTER_GCODE_PARSER + +/** + * User-defined menu items that execute custom GCode + */ +//#define CUSTOM_USER_MENUS +#if ENABLED(CUSTOM_USER_MENUS) + #define USER_SCRIPT_DONE "M117 User Script Done" + #define USER_SCRIPT_AUDIBLE_FEEDBACK + //#define USER_SCRIPT_RETURN // Return to status screen after a script + + #define USER_DESC_1 "Home & UBL Info" + #define USER_GCODE_1 "G28\nG29 W" + + #define USER_DESC_2 "Preheat for PLA" + #define USER_GCODE_2 "M140 S" STRINGIFY(PREHEAT_1_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND) + + #define USER_DESC_3 "Preheat for ABS" + #define USER_GCODE_3 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND) + + #define USER_DESC_4 "Heat Bed/Home/Level" + #define USER_GCODE_4 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nG28\nG29" + + //#define USER_DESC_5 "Home & Info" + //#define USER_GCODE_5 "G28\nM503" +#endif + +/** + * Specify an action command to send to the host when the printer is killed. + * Will be sent in the form '//action:ACTION_ON_KILL', e.g. '//action:poweroff'. + * The host must be configured to handle the action command. + */ +//#define ACTION_ON_KILL "poweroff" + +//=========================================================================== +//====================== I2C Position Encoder Settings ====================== +//=========================================================================== + +/** + * I2C position encoders for closed loop control. + * Developed by Chris Barr at Aus3D. + * + * Wiki: http://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/ + * + * Reilabuild encoders have been modified to improve reliability. + */ + +//#define I2C_POSITION_ENCODERS +#if ENABLED(I2C_POSITION_ENCODERS) + + #define I2CPE_ENCODER_CNT 1 // The number of encoders installed; max of 5 + // encoders supported currently. + + #define I2CPE_ENC_1_ADDR I2CPE_PRESET_ADDR_X // I2C address of the encoder. 30-200. + #define I2CPE_ENC_1_AXIS X_AXIS // Axis the encoder module is installed on. _AXIS. + #define I2CPE_ENC_1_TYPE I2CPE_ENC_TYPE_LINEAR // Type of encoder: I2CPE_ENC_TYPE_LINEAR -or- + // I2CPE_ENC_TYPE_ROTARY. + #define I2CPE_ENC_1_TICKS_UNIT 2048 // 1024 for magnetic strips with 2mm poles; 2048 for + // 1mm poles. For linear encoders this is ticks / mm, + // for rotary encoders this is ticks / revolution. + //#define I2CPE_ENC_1_TICKS_REV (16 * 200) // Only needed for rotary encoders; number of stepper + // steps per full revolution (motor steps/rev * microstepping) + //#define I2CPE_ENC_1_INVERT // Invert the direction of axis travel. + #define I2CPE_ENC_1_EC_METHOD I2CPE_ECM_NONE // Type of error error correction. + #define I2CPE_ENC_1_EC_THRESH 0.10 // Threshold size for error (in mm) above which the + // printer will attempt to correct the error; errors + // smaller than this are ignored to minimize effects of + // measurement noise / latency (filter). + + #define I2CPE_ENC_2_ADDR I2CPE_PRESET_ADDR_Y // Same as above, but for encoder 2. + #define I2CPE_ENC_2_AXIS Y_AXIS + #define I2CPE_ENC_2_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_ENC_2_TICKS_UNIT 2048 + //#define I2CPE_ENC_2_TICKS_REV (16 * 200) + //#define I2CPE_ENC_2_INVERT + #define I2CPE_ENC_2_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_ENC_2_EC_THRESH 0.10 + + #define I2CPE_ENC_3_ADDR I2CPE_PRESET_ADDR_Z // Encoder 3. Add additional configuration options + #define I2CPE_ENC_3_AXIS Z_AXIS // as above, or use defaults below. + + #define I2CPE_ENC_4_ADDR I2CPE_PRESET_ADDR_E // Encoder 4. + #define I2CPE_ENC_4_AXIS E_AXIS + + #define I2CPE_ENC_5_ADDR 34 // Encoder 5. + #define I2CPE_ENC_5_AXIS E_AXIS + + // Default settings for encoders which are enabled, but without settings configured above. + #define I2CPE_DEF_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_DEF_ENC_TICKS_UNIT 2048 + #define I2CPE_DEF_TICKS_REV (16 * 200) + #define I2CPE_DEF_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_DEF_EC_THRESH 0.1 + + //#define I2CPE_ERR_THRESH_ABORT 100.0 // Threshold size for error (in mm) error on any given + // axis after which the printer will abort. Comment out to + // disable abort behaviour. + + #define I2CPE_TIME_TRUSTED 10000 // After an encoder fault, there must be no further fault + // for this amount of time (in ms) before the encoder + // is trusted again. + + /** + * Position is checked every time a new command is executed from the buffer but during long moves, + * this setting determines the minimum update time between checks. A value of 100 works well with + * error rolling average when attempting to correct only for skips and not for vibration. + */ + #define I2CPE_MIN_UPD_TIME_MS 100 // Minimum time in miliseconds between encoder checks. + + // Use a rolling average to identify persistant errors that indicate skips, as opposed to vibration and noise. + #define I2CPE_ERR_ROLLING_AVERAGE + +#endif // I2C_POSITION_ENCODERS + +/** + * MAX7219 Debug Matrix + * + * Add support for a low-cost 8x8 LED Matrix based on the Max7219 chip, which can be used as a status + * display. Requires 3 signal wires. Some useful debug options are included to demonstrate its usage. + * + * Fully assembled MAX7219 boards can be found on the internet for under $2(US). + * For example, see https://www.ebay.com/sch/i.html?_nkw=332349290049 + */ +//#define MAX7219_DEBUG +#if ENABLED(MAX7219_DEBUG) + #define MAX7219_CLK_PIN 64 // 77 on Re-ARM // Configuration of the 3 pins to control the display + #define MAX7219_DIN_PIN 57 // 78 on Re-ARM + #define MAX7219_LOAD_PIN 44 // 79 on Re-ARM + + /** + * Sample debug features + * If you add more debug displays, be careful to avoid conflicts! + */ + #define MAX7219_DEBUG_PRINTER_ALIVE // Blink corner LED of 8x8 matrix to show that the firmware is functioning + #define MAX7219_DEBUG_STEPPER_HEAD 3 // Show the stepper queue head position on this and the next LED matrix row + #define MAX7219_DEBUG_STEPPER_TAIL 5 // Show the stepper queue tail position on this and the next LED matrix row + + #define MAX7219_DEBUG_STEPPER_QUEUE 0 // Show the current stepper queue depth on this and the next LED matrix row + // If you experience stuttering, reboots, etc. this option can reveal how + // tweaks made to the configuration are affecting the printer in real-time. +#endif + +#endif // CONFIGURATION_ADV_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/BQ/Hephestos_2/README.md b/trunk/Arduino/Marlin_1.1.6/example_configurations/BQ/Hephestos_2/README.md new file mode 100644 index 00000000..cbe9965e --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/BQ/Hephestos_2/README.md @@ -0,0 +1,22 @@ +# Example Configuration for BQ [Hephestos 2](http://www.bq.com/uk/hephestos-2) +This configuration file is based on the original configuration file shipped with the heavily modified Marlin fork by BQ. The original firmware and configuration file can be found at [BQ Github repository](https://github.com/bq/Marlin). + +NOTE: The look and feel of the Hephestos 2 while navigating the LCD menu will change by using the original Marlin firmware. + +## Changelog + * 2016/03/01 - Initial release + + * 2016/03/21 - Activated 4-point auto leveling by default + Updated miscellaneous z-probe values + + * 2016/06/21 - Disabled hot bed related options + Activated software endstops + SD printing now disables the heater when finished + + * 2016/07/13 - Update the `DEFAULT_AXIS_STEPS_PER_UNIT` for the Z axis + Increased the `DEFAULT_XYJERK` + + * 2016/12/13 - Configuration updated. + + * 2017/07/06 - Configuration updated to the latest Marlin version. + Added support for the official BQ heated bed kit. diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/BQ/Hephestos_2/_Bootscreen.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/BQ/Hephestos_2/_Bootscreen.h new file mode 100644 index 00000000..786d37b4 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/BQ/Hephestos_2/_Bootscreen.h @@ -0,0 +1,103 @@ +/** + * 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 . + * + */ + +/** + * Custom Bitmap for splashscreen + * + * You may use one of the following tools to generate the C++ bitmap array from + * a black and white image: + * + * - http://www.marlinfw.org/tools/u8glib/converter.html + * - http://www.digole.com/tools/PicturetoC_Hex_converter.php + */ +#include + +#define CUSTOM_BOOTSCREEN_TIMEOUT 2500 +#define CUSTOM_BOOTSCREEN_BMPWIDTH 62 +#define CUSTOM_BOOTSCREEN_BMPHEIGHT 64 + +const unsigned char custom_start_bmp[512] PROGMEM = { + 0x00, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x1F, 0xF8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x1F, 0xF8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x1F, 0xF8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x1F, 0xF8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x1F, 0xF8, 0x00, 0x00, 0x00, + 0x00, 0x03, 0xC0, 0x0F, 0xF0, 0x07, 0x80, 0x00, + 0x00, 0x07, 0xE0, 0x07, 0xE0, 0x0F, 0xC0, 0x00, + 0x00, 0x0F, 0xF0, 0x03, 0xC0, 0x1F, 0xE0, 0x00, + 0x00, 0x1F, 0xF8, 0x00, 0x00, 0x3F, 0xF0, 0x00, + 0x00, 0x1F, 0xF8, 0x00, 0x00, 0x3F, 0xF0, 0x00, + 0x00, 0x1F, 0xF8, 0x00, 0x00, 0x3F, 0xF0, 0x00, + 0x00, 0x1F, 0xF8, 0x00, 0x00, 0x3F, 0xF0, 0x00, + 0x00, 0x1F, 0xF8, 0x00, 0x00, 0x3F, 0xF0, 0x00, + 0x00, 0x0F, 0xF0, 0x00, 0x00, 0x1F, 0xE0, 0x00, + 0x00, 0x07, 0xE0, 0x00, 0x00, 0x0F, 0xC0, 0x00, + 0x00, 0x03, 0xC0, 0x00, 0x00, 0x07, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xF8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFC, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFC, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFC, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFC, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFC, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFC, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFC, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xF8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1E, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, + 0x3F, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, + 0x7F, 0x80, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, + 0xFF, 0xC0, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, + 0xFF, 0xC0, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, + 0xFF, 0xC0, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, + 0xFF, 0xC0, 0x00, 0x00, 0xF7, 0xC0, 0x1F, 0x80, + 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xF0, 0x7F, 0xC0, + 0x7F, 0x80, 0x00, 0x00, 0xFF, 0xF8, 0xFF, 0xE0, + 0x3F, 0x00, 0x00, 0x00, 0xFC, 0xF8, 0xF0, 0xF8, + 0x1E, 0x00, 0x00, 0x00, 0xF8, 0x7D, 0xE0, 0x78, + 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3D, 0xE0, 0x78, + 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3D, 0xE0, 0x78, + 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3D, 0xE0, 0x78, + 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3D, 0xE0, 0x78, + 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3D, 0xE0, 0x78, + 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3D, 0xE0, 0x78, + 0x00, 0x00, 0x00, 0x00, 0xF8, 0x79, 0xF0, 0xF8, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xF8, 0xFF, 0xF8, + 0x00, 0x00, 0x00, 0x00, 0x3F, 0xF0, 0x7F, 0xF8, + 0x00, 0x00, 0x00, 0x00, 0x0F, 0xE0, 0x3F, 0xF8, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x0E, 0x78, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, +}; diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/BQ/WITBOX/Configuration.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/BQ/WITBOX/Configuration.h new file mode 100644 index 00000000..27853e04 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/BQ/WITBOX/Configuration.h @@ -0,0 +1,1691 @@ +/** + * 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 . + * + */ + +/** + * Configuration.h + * + * Basic settings such as: + * + * - Type of electronics + * - Type of temperature sensor + * - Printer geometry + * - Endstop configuration + * - LCD controller + * - Extra features + * + * Advanced settings can be found in Configuration_adv.h + * + */ +#ifndef CONFIGURATION_H +#define CONFIGURATION_H +#define CONFIGURATION_H_VERSION 010100 + +//=========================================================================== +//============================= Getting Started ============================= +//=========================================================================== + +/** + * Here are some standard links for getting your machine calibrated: + * + * http://reprap.org/wiki/Calibration + * http://youtu.be/wAL9d7FgInk + * http://calculator.josefprusa.cz + * http://reprap.org/wiki/Triffid_Hunter%27s_Calibration_Guide + * http://www.thingiverse.com/thing:5573 + * https://sites.google.com/site/repraplogphase/calibration-of-your-reprap + * http://www.thingiverse.com/thing:298812 + */ + +//=========================================================================== +//============================= DELTA Printer =============================== +//=========================================================================== +// For a Delta printer start with one of the configuration files in the +// example_configurations/delta directory and customize for your machine. +// + +//=========================================================================== +//============================= SCARA Printer =============================== +//=========================================================================== +// For a SCARA printer start with the configuration files in +// example_configurations/SCARA and customize for your machine. +// + +// @section info + +// User-specified version info of this build to display in [Pronterface, etc] terminal window during +// startup. Implementation of an idea by Prof Braino to inform user that any changes made to this +// build by the user have been successfully uploaded into firmware. +#define STRING_CONFIG_H_AUTHOR "(bq Witbox)" // Who made the changes. +#define SHOW_BOOTSCREEN +#define STRING_SPLASH_LINE1 SHORT_BUILD_VERSION // will be shown during bootup in line 1 +#define STRING_SPLASH_LINE2 WEBSITE_URL // will be shown during bootup in line 2 + +// +// *** VENDORS PLEASE READ ***************************************************** +// +// Marlin now allow you to have a vendor boot image to be displayed on machine +// start. When SHOW_CUSTOM_BOOTSCREEN is defined Marlin will first show your +// custom boot image and then the default Marlin boot image is shown. +// +// We suggest for you to take advantage of this new feature and keep the Marlin +// boot image unmodified. For an example have a look at the bq Hephestos 2 +// example configuration folder. +// +//#define SHOW_CUSTOM_BOOTSCREEN +// @section machine + +/** + * Select which serial port on the board will be used for communication with the host. + * This allows the connection of wireless adapters (for instance) to non-default port pins. + * Serial port 0 is always used by the Arduino bootloader regardless of this setting. + * + * :[0, 1, 2, 3, 4, 5, 6, 7] + */ +#define SERIAL_PORT 0 + +/** + * This setting determines the communication speed of the printer. + * + * 250000 works in most cases, but you might try a lower speed if + * you commonly experience drop-outs during host printing. + * You may try up to 1000000 to speed up SD file transfer. + * + * :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000] + */ +#define BAUDRATE 115200 + +// Enable the Bluetooth serial interface on AT90USB devices +//#define BLUETOOTH + +// The following define selects which electronics board you have. +// Please choose the name from boards.h that matches your setup +#ifndef MOTHERBOARD + #define MOTHERBOARD BOARD_RAMPS_14_EFB +#endif + +// Optional custom name for your RepStrap or other custom machine +// Displayed in the LCD "Ready" message +#define CUSTOM_MACHINE_NAME "WITBOX" + +// Added for BQ +#define SOURCE_CODE_URL "http://www.bq.com/gb/downloads-witbox.html" + +// Define this to set a unique identifier for this printer, (Used by some programs to differentiate between machines) +// You can use an online service to generate a random UUID. (eg http://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] +#define EXTRUDERS 1 + +// For Cyclops or any "multi-extruder" that shares a single nozzle. +//#define SINGLENOZZLE + +/** + * Průša MK2 Single Nozzle Multi-Material Multiplexer, and variants. + * + * This device allows one stepper driver on a control board to drive + * two to eight stepper motors, one at a time, in a manner suitable + * for extruders. + * + * This option only allows the multiplexer to switch on tool-change. + * Additional options to configure custom E moves are pending. + */ +//#define MK2_MULTIPLEXER +#if ENABLED(MK2_MULTIPLEXER) + // Override the default DIO selector pins here, if needed. + // Some pins files may provide defaults for these pins. + //#define E_MUX0_PIN 40 // Always Required + //#define E_MUX1_PIN 42 // Needed for 3 to 8 steppers + //#define E_MUX2_PIN 44 // Needed for 5 to 8 steppers +#endif + +// A dual extruder that uses a single stepper motor +//#define SWITCHING_EXTRUDER +#if ENABLED(SWITCHING_EXTRUDER) + #define SWITCHING_EXTRUDER_SERVO_NR 0 + #define SWITCHING_EXTRUDER_SERVO_ANGLES { 0, 90 } // Angles for E0, E1[, E2, E3] + #if EXTRUDERS > 3 + #define SWITCHING_EXTRUDER_E23_SERVO_NR 1 + #endif +#endif + +// A dual-nozzle that uses a servomotor to raise/lower one of the nozzles +//#define SWITCHING_NOZZLE +#if ENABLED(SWITCHING_NOZZLE) + #define SWITCHING_NOZZLE_SERVO_NR 0 + #define SWITCHING_NOZZLE_SERVO_ANGLES { 0, 90 } // Angles for E0, E1 + //#define HOTEND_OFFSET_Z { 0.0, 0.0 } +#endif + +/** + * Two separate X-carriages with extruders that connect to a moving part + * via a magnetic docking mechanism. Requires SOL1_PIN and SOL2_PIN. + */ +//#define PARKING_EXTRUDER +#if ENABLED(PARKING_EXTRUDER) + #define PARKING_EXTRUDER_SOLENOIDS_INVERT // If enabled, the solenoid is NOT magnetized with applied voltage + #define PARKING_EXTRUDER_SOLENOIDS_PINS_ACTIVE LOW // LOW or HIGH pin signal energizes the coil + #define PARKING_EXTRUDER_SOLENOIDS_DELAY 250 // Delay (ms) for magnetic field. No delay if 0 or not defined. + #define PARKING_EXTRUDER_PARKING_X { -78, 184 } // X positions for parking the extruders + #define PARKING_EXTRUDER_GRAB_DISTANCE 1 // mm to move beyond the parking point to grab the extruder + #define PARKING_EXTRUDER_SECURITY_RAISE 5 // Z-raise before parking + #define HOTEND_OFFSET_Z { 0.0, 1.3 } // Z-offsets of the two hotends. The first must be 0. +#endif + +/** + * "Mixing Extruder" + * - Adds a new code, M165, to set the current mix factors. + * - Extends the stepping routines to move multiple steppers in proportion to the mix. + * - Optional support for Repetier Firmware M163, M164, and virtual extruder. + * - This implementation supports only a single extruder. + * - Enable DIRECT_MIXING_IN_G1 for Pia Taubert's reference implementation + */ +//#define MIXING_EXTRUDER +#if ENABLED(MIXING_EXTRUDER) + #define MIXING_STEPPERS 2 // Number of steppers in your mixing extruder + #define MIXING_VIRTUAL_TOOLS 16 // Use the Virtual Tool method with M163 and M164 + //#define DIRECT_MIXING_IN_G1 // Allow ABCDHI mix factors in G1 movement commands +#endif + +// Offset of the extruders (uncomment if using more than one and relying on firmware to position when changing). +// The offset has to be X=0, Y=0 for the extruder 0 hotend (default extruder). +// For the other hotends it is their distance from the extruder 0 hotend. +//#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis +//#define HOTEND_OFFSET_Y {0.0, 5.00} // (in mm) for each extruder, offset of the hotend on the Y axis + +// @section machine + +/** + * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN + * + * 0 = No Power Switch + * 1 = ATX + * 2 = X-Box 360 203Watts (the blue wire connected to PS_ON and the red wire to VCC) + * + * :{ 0:'No power switch', 1:'ATX', 2:'X-Box 360' } + */ +#define POWER_SUPPLY 1 + +#if POWER_SUPPLY > 0 + // Enable this option to leave the PSU off at startup. + // Power to steppers and heaters will need to be turned on with M80. + //#define PS_DEFAULT_OFF +#endif + +// @section temperature + +//=========================================================================== +//============================= Thermal Settings ============================ +//=========================================================================== + +/** + * --NORMAL IS 4.7kohm PULLUP!-- 1kohm pullup can be used on hotend sensor, using correct resistor and table + * + * Temperature sensors available: + * + * -3 : thermocouple with MAX31855 (only for sensor 0) + * -2 : thermocouple with MAX6675 (only for sensor 0) + * -1 : thermocouple with AD595 + * 0 : not used + * 1 : 100k thermistor - best choice for EPCOS 100k (4.7k pullup) + * 2 : 200k thermistor - ATC Semitec 204GT-2 (4.7k pullup) + * 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 (Used in ParCan & J-Head) (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) + * 71 : 100k Honeywell thermistor 135-104LAF-J01 (4.7k pullup) + * 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) + * 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" + * 20 : the PT100 circuit found in the Ultimainboard V2.x + * 60 : 100k Maker's Tool Works Kapton Bed Thermistor beta=3950 + * 66 : 4.7M High Temperature thermistor from Dyze Design + * 70 : the 100K thermistor found in the bq Hephestos 2 + * 75 : 100k Generic Silicon Heat Pad with NTC 100K MGB18-104F39050L32 thermistor + * + * 1k ohm pullup tables - This is atypical, and requires changing out the 4.7k pullup for 1k. + * (but gives greater accuracy and more stable PID) + * 51 : 100k thermistor - EPCOS (1k pullup) + * 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 + * 1010 : Pt1000 with 1k pullup (non standard) + * 147 : Pt100 with 4k7 pullup + * 110 : Pt100 with 1k pullup (non standard) + * + * Use these for Testing or Development purposes. NEVER for production machine. + * 998 : Dummy Table that ALWAYS reads 25°C or the temperature defined below. + * 999 : Dummy Table that ALWAYS reads 100°C or the temperature defined below. + * + * :{ '0': "Not used", '1':"100k / 4.7k - EPCOS", '2':"200k / 4.7k - ATC Semitec 204GT-2", '3':"Mendel-parts / 4.7k", '4':"10k !! do not use for a hotend. Bad resolution at high temp. !!", '5':"100K / 4.7k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '6':"100k / 4.7k EPCOS - Not as accurate as Table 1", '7':"100k / 4.7k Honeywell 135-104LAG-J01", '8':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT", '9':"100k / 4.7k GE Sensing AL03006-58.2K-97-G1", '10':"100k / 4.7k RS 198-961", '11':"100k / 4.7k beta 3950 1%", '12':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT (calibrated for Makibox hot bed)", '13':"100k Hisens 3950 1% up to 300°C for hotend 'Simple ONE ' & hotend 'All In ONE'", '20':"PT100 (Ultimainboard V2.x)", '51':"100k / 1k - EPCOS", '52':"200k / 1k - ATC Semitec 204GT-2", '55':"100k / 1k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '60':"100k Maker's Tool Works Kapton Bed Thermistor beta=3950", '66':"Dyze Design 4.7M High Temperature thermistor", '70':"the 100K thermistor found in the bq Hephestos 2", '71':"100k / 4.7k Honeywell 135-104LAF-J01", '147':"Pt100 / 4.7k", '1047':"Pt1000 / 4.7k", '110':"Pt100 / 1k (non-standard)", '1010':"Pt1000 / 1k (non standard)", '-3':"Thermocouple + MAX31855 (only for sensor 0)", '-2':"Thermocouple + MAX6675 (only for sensor 0)", '-1':"Thermocouple + AD595",'998':"Dummy 1", '999':"Dummy 2" } + */ +#define TEMP_SENSOR_0 1 +#define TEMP_SENSOR_1 0 +#define TEMP_SENSOR_2 0 +#define TEMP_SENSOR_3 0 +#define TEMP_SENSOR_4 0 +#define TEMP_SENSOR_BED 0 + +// Dummy thermistor constant temperature readings, for use with 998 and 999 +#define DUMMY_THERMISTOR_998_VALUE 25 +#define DUMMY_THERMISTOR_999_VALUE 100 + +// 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 +#define MAX_REDUNDANT_TEMP_SENSOR_DIFF 10 + +// Extruder temperature must be close to target for this long before M109 returns success +#define TEMP_RESIDENCY_TIME 10 // (seconds) +#define TEMP_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// Bed temperature must be close to target for this long before M190 returns success +#define TEMP_BED_RESIDENCY_TIME 0 // (seconds) +#define TEMP_BED_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_BED_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// The minimal temperature defines the temperature below which the heater will not be enabled It is used +// to check that the wiring to the thermistor is not broken. +// Otherwise this would lead to the heater being powered on all the time. +#define HEATER_0_MINTEMP 5 +#define HEATER_1_MINTEMP 5 +#define HEATER_2_MINTEMP 5 +#define HEATER_3_MINTEMP 5 +#define HEATER_4_MINTEMP 5 +#define BED_MINTEMP 5 + +// When temperature exceeds max temp, your heater will be switched off. +// This feature exists to protect your hotend from overheating accidentally, but *NOT* from thermistor short/failure! +// You should use MINTEMP for thermistor short/failure protection. +#define HEATER_0_MAXTEMP 260 +#define HEATER_1_MAXTEMP 260 +#define HEATER_2_MAXTEMP 260 +#define HEATER_3_MAXTEMP 260 +#define HEATER_4_MAXTEMP 260 +#define BED_MAXTEMP 150 + +//=========================================================================== +//============================= PID Settings ================================ +//=========================================================================== +// PID Tuning Guide here: http://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 +#if ENABLED(PIDTEMP) + //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. + //#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. + #define K1 0.95 //smoothing factor within the PID + + // Witbox + #define DEFAULT_Kp 22.2 + #define DEFAULT_Ki 1.08 + #define DEFAULT_Kd 114 + +#endif // PIDTEMP + +//=========================================================================== +//============================= PID > Bed Temperature Control =============== +//=========================================================================== +// Select PID or bang-bang with PIDTEMPBED. If bang-bang, BED_LIMIT_SWITCHING will enable hysteresis +// +// Uncomment this to enable PID on the bed. It uses the same frequency PWM as the extruder. +// If your PID_dT is the default, and correct for your hardware/configuration, that means 7.689Hz, +// which is fine for driving a square wave into a resistive load and does not significantly impact you FET heating. +// This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W heater. +// If your configuration is significantly different than this and you don't understand the issues involved, you probably +// shouldn't use bed PID until someone else verifies your hardware works. +// If this is enabled, find your own PID constants below. +//#define PIDTEMPBED + +//#define BED_LIMIT_SWITCHING + +// This sets the max power delivered to the bed, and replaces the HEATER_BED_DUTY_CYCLE_DIVIDER option. +// all forms of bed control obey this (PID, bang-bang, bang-bang with hysteresis) +// setting this to anything other than 255 enables a form of PWM to the bed just like HEATER_BED_DUTY_CYCLE_DIVIDER did, +// so you shouldn't use it unless you are OK with PWM on your bed. (see the comment on enabling PIDTEMPBED) +#define MAX_BED_POWER 255 // limits duty cycle to bed; 255=full current + +#if ENABLED(PIDTEMPBED) + + //#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) + #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 + +// @section extruder + +// This option prevents extrusion if the temperature is below EXTRUDE_MINTEMP. +// It also enables the M302 command to set the minimum extrusion temperature +// or to allow moving the extruder regardless of the hotend temperature. +// *** IT IS HIGHLY RECOMMENDED TO LEAVE THIS OPTION ENABLED! *** +#define PREVENT_COLD_EXTRUSION +#define EXTRUDE_MINTEMP 170 + +// This option prevents a single extrusion longer than EXTRUDE_MAXLENGTH. +// Note that for Bowden Extruders a too-small value here may prevent loading. +#define PREVENT_LENGTHY_EXTRUDE +#define EXTRUDE_MAXLENGTH 200 + +//=========================================================================== +//======================== Thermal Runaway Protection ======================= +//=========================================================================== + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * If you get "Thermal Runaway" or "Heating failed" errors the + * details can be tuned in Configuration_adv.h + */ + +#define THERMAL_PROTECTION_HOTENDS // Enable thermal protection for all extruders +#define THERMAL_PROTECTION_BED // Enable thermal protection for the heated bed + +//=========================================================================== +//============================= Mechanical Settings ========================= +//=========================================================================== + +// @section machine + +// Uncomment one of these options to enable CoreXY, CoreXZ, or CoreYZ kinematics +// either in the usual order or reversed +//#define COREXY +//#define COREXZ +//#define COREYZ +//#define COREYX +//#define COREZX +//#define COREZY + +//=========================================================================== +//============================== Endstop Settings =========================== +//=========================================================================== + +// @section homing + +// Specify here all the endstop connectors that are connected to any endstop or probe. +// Almost all printers will be using one per axis. Probes will use one or more of the +// extra connectors. Leave undefined any used for non-endstop and non-probe purposes. +//#define USE_XMIN_PLUG +//#define USE_YMIN_PLUG +#define USE_ZMIN_PLUG +#define USE_XMAX_PLUG +#define USE_YMAX_PLUG +//#define USE_ZMAX_PLUG + +// coarse Endstop Settings +#define ENDSTOPPULLUPS // Comment this out (using // at the start of the line) to disable the endstop pullup resistors + +#if DISABLED(ENDSTOPPULLUPS) + // fine endstop settings: Individual pullups. will be ignored if ENDSTOPPULLUPS is defined + //#define ENDSTOPPULLUP_XMAX + //#define ENDSTOPPULLUP_YMAX + //#define ENDSTOPPULLUP_ZMAX + //#define ENDSTOPPULLUP_XMIN + //#define ENDSTOPPULLUP_YMIN + //#define ENDSTOPPULLUP_ZMIN + //#define ENDSTOPPULLUP_ZMIN_PROBE +#endif + +// Mechanical endstop with COM to ground and NC to Signal uses "false" here (most common setup). +#define X_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Y_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define X_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Y_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MIN_PROBE_ENDSTOP_INVERTING true // set to true to invert the logic of the probe. + +// Enable this feature if all enabled endstop pins are interrupt-capable. +// This will remove the need to poll the interrupt pins, saving many CPU cycles. +//#define ENDSTOP_INTERRUPTS_FEATURE + +//============================================================================= +//============================== Movement Settings ============================ +//============================================================================= +// @section motion + +/** + * Default Settings + * + * These settings can be reset by M502 + * + * Note that if EEPROM is enabled, saved values will override these. + */ + +/** + * With this option each E stepper can have its own factors for the + * following movement settings. If fewer factors are given than the + * total number of extruders, the last value applies to the rest. + */ +//#define DISTINCT_E_FACTORS + +/** + * Default Axis Steps Per Unit (steps/mm) + * Override with M92 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_AXIS_STEPS_PER_UNIT { 80, 80, 600.0*8/3, 102.073 } + +/** + * Default Max Feed Rate (mm/s) + * Override with M203 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_FEEDRATE { 350, 350, 7.2, 80 } + +/** + * Default Max Acceleration (change/s) change = mm/s + * (Maximum start speed for accelerated moves) + * Override with M201 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_ACCELERATION { 1000, 1000, 10, 1000 } + +/** + * Default Acceleration (change/s) change = mm/s + * Override with M204 + * + * M204 P Acceleration + * M204 R Retract Acceleration + * M204 T Travel Acceleration + */ +#define DEFAULT_ACCELERATION 3000 // X, Y, Z and E acceleration for printing moves +#define DEFAULT_RETRACT_ACCELERATION 3000 // E acceleration for retracts +#define DEFAULT_TRAVEL_ACCELERATION 3000 // X, Y, Z acceleration for travel (non printing) moves + +/** + * Default Jerk (mm/s) + * Override with M205 X Y Z E + * + * "Jerk" specifies the minimum speed change that requires acceleration. + * When changing speed and direction, if the difference is less than the + * value set here, it may happen instantaneously. + */ +#define DEFAULT_XJERK 10.0 +#define DEFAULT_YJERK 10.0 +#define DEFAULT_ZJERK 0.4 +#define DEFAULT_EJERK 5.0 + +//=========================================================================== +//============================= Z Probe Options ============================= +//=========================================================================== +// @section probes + +// +// See http://marlinfw.org/configuration/probes.html +// + +/** + * Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + * + * Enable this option for a probe connected to the Z Min endstop pin. + */ +#define Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + +/** + * Z_MIN_PROBE_ENDSTOP + * + * Enable this option for a probe connected to any pin except Z-Min. + * (By default Marlin assumes the Z-Max endstop pin.) + * To use a custom Z Probe pin, set Z_MIN_PROBE_PIN below. + * + * - The simplest option is to use a free endstop connector. + * - Use 5V for powered (usually inductive) sensors. + * + * - RAMPS 1.3/1.4 boards may use the 5V, GND, and Aux4->D32 pin: + * - For simple switches connect... + * - normally-closed switches to GND and D32. + * - normally-open switches to 5V and D32. + * + * WARNING: Setting the wrong pin may have unexpected and potentially + * disastrous consequences. Use with caution and do your homework. + * + */ +//#define Z_MIN_PROBE_ENDSTOP + +/** + * Probe Type + * + * Allen Key Probes, Servo Probes, Z-Sled Probes, FIX_MOUNTED_PROBE, etc. + * Activate one of these to use Auto Bed Leveling below. + */ + +/** + * The "Manual Probe" provides a means to do "Auto" Bed Leveling without a probe. + * Use G29 repeatedly, adjusting the Z height at each point with movement commands + * or (with LCD_BED_LEVELING) the LCD controller. + */ +//#define PROBE_MANUALLY + +/** + * A Fix-Mounted Probe either doesn't deploy or needs manual deployment. + * (e.g., an inductive probe or a nozzle-based probe-switch.) + */ +//#define FIX_MOUNTED_PROBE + +/** + * Z Servo Probe, such as an endstop switch on a rotating arm. + */ +//#define Z_ENDSTOP_SERVO_NR 0 // Defaults to SERVO 0 connector. +//#define Z_SERVO_ANGLES {70,0} // Z Servo Deploy and Stow angles + +/** + * The BLTouch probe uses a Hall effect sensor and emulates a servo. + */ +//#define BLTOUCH +#if ENABLED(BLTOUCH) + //#define BLTOUCH_DELAY 375 // (ms) Enable and increase if needed +#endif + +/** + * Enable one or more of the following if probing seems unreliable. + * Heaters and/or fans can be disabled during probing to minimize electrical + * noise. A delay can also be added to allow noise and vibration to settle. + * These options are most useful for the BLTouch probe, but may also improve + * readings with inductive probes and piezo sensors. + */ +//#define PROBING_HEATERS_OFF // Turn heaters off when probing +//#define PROBING_FANS_OFF // Turn fans off when probing +//#define DELAY_BEFORE_PROBING 200 // (ms) To prevent vibrations from triggering piezo sensors + +// A probe that is deployed and stowed with a solenoid pin (SOL1_PIN) +//#define SOLENOID_PROBE + +// A sled-mounted probe like those designed by Charles Bell. +//#define Z_PROBE_SLED +//#define SLED_DOCKING_OFFSET 5 // The extra distance the X axis must travel to pickup the sled. 0 should be fine but you can push it further if you'd like. + +// +// For Z_PROBE_ALLEN_KEY see the Delta example configurations. +// + +/** + * Z Probe to nozzle (X,Y) offset, relative to (0, 0). + * X and Y offsets must be integers. + * + * In the following example the X and Y offsets are both positive: + * #define X_PROBE_OFFSET_FROM_EXTRUDER 10 + * #define Y_PROBE_OFFSET_FROM_EXTRUDER 10 + * + * +-- BACK ---+ + * | | + * L | (+) P | R <-- probe (20,20) + * E | | I + * F | (-) N (+) | G <-- nozzle (10,10) + * T | | H + * | (-) | T + * | | + * O-- FRONT --+ + * (0,0) + */ +#define X_PROBE_OFFSET_FROM_EXTRUDER -25 // X offset: -left +right [of the nozzle] +#define Y_PROBE_OFFSET_FROM_EXTRUDER -29 // Y offset: -front +behind [the nozzle] +#define Z_PROBE_OFFSET_FROM_EXTRUDER -12.35 // Z offset: -below +above [the nozzle] + +// X and Y axis travel speed (mm/m) between probes +#define XY_PROBE_SPEED 8000 + +// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +#define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z + +// Speed for the "accurate" probe of each point +#define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) + +// Use double touch for probing +//#define PROBE_DOUBLE_TOUCH + +/** + * Z probes require clearance when deploying, stowing, and moving between + * probe points to avoid hitting the bed and other hardware. + * Servo-mounted probes require extra space for the arm to rotate. + * Inductive probes need space to keep from triggering early. + * + * Use these settings to specify the distance (mm) to raise the probe (or + * lower the bed). The values set here apply over and above any (negative) + * probe Z Offset set with Z_PROBE_OFFSET_FROM_EXTRUDER, M851, or the LCD. + * Only integer values >= 1 are valid here. + * + * Example: `M851 Z-5` with a CLEARANCE of 4 => 9mm from bed to nozzle. + * But: `M851 Z+1` with a CLEARANCE of 2 => 2mm from bed to nozzle. + */ +#define Z_CLEARANCE_DEPLOY_PROBE 15 // Z Clearance for Deploy/Stow +#define Z_CLEARANCE_BETWEEN_PROBES 5 // Z Clearance between probe points + +// For M851 give a range for adjusting the Z probe offset +#define Z_PROBE_OFFSET_RANGE_MIN -20 +#define Z_PROBE_OFFSET_RANGE_MAX 20 + +// Enable the M48 repeatability test to test probe accuracy +//#define Z_MIN_PROBE_REPEATABILITY_TEST + +// For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1 +// :{ 0:'Low', 1:'High' } +#define X_ENABLE_ON 0 +#define Y_ENABLE_ON 0 +#define Z_ENABLE_ON 0 +#define E_ENABLE_ON 0 // For all extruders + +// Disables axis stepper immediately when it's not being used. +// WARNING: When motors turn off there is a chance of losing position accuracy! +#define DISABLE_X false +#define DISABLE_Y false +#define DISABLE_Z true +// Warn on display about possibly reduced accuracy +//#define DISABLE_REDUCED_ACCURACY_WARNING + +// @section extruder + +#define DISABLE_E false // For all extruders +#define DISABLE_INACTIVE_EXTRUDER true // Keep only the active extruder enabled. + +// @section machine + +// Invert the stepper direction. Change (or reverse the motor connector) if an axis goes the wrong way. +#define INVERT_X_DIR true +#define INVERT_Y_DIR false +#define INVERT_Z_DIR true + +// Enable this option for Toshiba stepper drivers +//#define CONFIG_STEPPERS_TOSHIBA + +// @section extruder + +// For direct drive extruder v9 set to true, for geared extruder set to false. +#define INVERT_E0_DIR false +#define INVERT_E1_DIR false +#define INVERT_E2_DIR false +#define INVERT_E3_DIR false +#define INVERT_E4_DIR false + +// @section homing + +//#define NO_MOTION_BEFORE_HOMING // Inhibit movement until all axes have been homed + +//#define Z_HOMING_HEIGHT 4 // (in mm) Minimal z height before homing (G28) for Z clearance above the bed, clamps, ... + // Be sure you have this distance over your Z_MAX_POS in case. + +// Direction of endstops when homing; 1=MAX, -1=MIN +// :[-1,1] +#define X_HOME_DIR 1 +#define Y_HOME_DIR 1 +#define Z_HOME_DIR -1 + +// @section machine + +// The size of the print bed +#define X_BED_SIZE 297 +#define Y_BED_SIZE 210 + +// Travel limits (mm) after homing, corresponding to endstop positions. +#define X_MIN_POS 0 +#define Y_MIN_POS 0 +#define Z_MIN_POS 0 +#define X_MAX_POS X_BED_SIZE +#define Y_MAX_POS Y_BED_SIZE +#define Z_MAX_POS 200 + +// If enabled, axes won't move below MIN_POS in response to movement commands. +#define MIN_SOFTWARE_ENDSTOPS +// If enabled, axes won't move above MAX_POS in response to movement commands. +#define MAX_SOFTWARE_ENDSTOPS + +/** + * Filament Runout Sensor + * A mechanical or opto endstop is used to check for the presence of filament. + * + * RAMPS-based boards use SERVO3_PIN. + * For other boards you may need to define FIL_RUNOUT_PIN. + * By default the firmware assumes HIGH = has filament, LOW = ran out + */ +//#define FILAMENT_RUNOUT_SENSOR +#if ENABLED(FILAMENT_RUNOUT_SENSOR) + #define FIL_RUNOUT_INVERTING false // set to true to invert the logic of the sensor. + #define ENDSTOPPULLUP_FIL_RUNOUT // Uncomment to use internal pullup for filament runout pins if the sensor is defined. + #define FILAMENT_RUNOUT_SCRIPT "M600" +#endif + +//=========================================================================== +//=============================== Bed Leveling ============================== +//=========================================================================== +// @section bedlevel + +/** + * Choose one of the options below to enable G29 Bed Leveling. The parameters + * and behavior of G29 will change depending on your selection. + * + * If using a Probe for Z Homing, enable Z_SAFE_HOMING also! + * + * - AUTO_BED_LEVELING_3POINT + * Probe 3 arbitrary points on the bed (that aren't collinear) + * You specify the XY coordinates of all 3 points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_LINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_BILINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a mesh, best for large or uneven beds. + * + * - AUTO_BED_LEVELING_UBL (Unified Bed Leveling) + * A comprehensive bed leveling system combining the features and benefits + * of other systems. UBL also includes integrated Mesh Generation, Mesh + * Validation and Mesh Editing systems. Currently, UBL is only checked out + * for Cartesian Printers. That said, it was primarily designed to correct + * poor quality Delta Printers. If you feel adventurous and have a Delta, + * please post an issue if something doesn't work correctly. Initially, + * you will need to set a reduced bed size so you have a rectangular area + * to test on. + * + * - MESH_BED_LEVELING + * Probe a grid manually + * The result is a mesh, suitable for large or uneven beds. (See BILINEAR.) + * For machines without a probe, Mesh Bed Leveling provides a method to perform + * leveling in steps so you can manually adjust the Z height at each grid-point. + * With an LCD controller the process is guided step-by-step. + */ +//#define AUTO_BED_LEVELING_3POINT +//#define AUTO_BED_LEVELING_LINEAR +//#define AUTO_BED_LEVELING_BILINEAR +//#define AUTO_BED_LEVELING_UBL +//#define MESH_BED_LEVELING + +/** + * Enable detailed logging of G28, G29, M48, etc. + * Turn on with the command 'M111 S32'. + * NOTE: Requires a lot of PROGMEM! + */ +//#define DEBUG_LEVELING_FEATURE + +#if ENABLED(MESH_BED_LEVELING) || ENABLED(AUTO_BED_LEVELING_BILINEAR) || ENABLED(AUTO_BED_LEVELING_UBL) + // Gradually reduce leveling correction until a set height is reached, + // at which point movement will be level to the machine's XY plane. + // The height can be set with M420 Z + #define ENABLE_LEVELING_FADE_HEIGHT +#endif + +#if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Set the number of grid points per dimension. + #define GRID_MAX_POINTS_X 3 + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + // Set the boundaries for probing (where the probe can reach). + #define LEFT_PROBE_BED_POSITION 15 + #define RIGHT_PROBE_BED_POSITION 170 + #define FRONT_PROBE_BED_POSITION 20 + #define BACK_PROBE_BED_POSITION 170 + + // The Z probe minimum outer margin (to validate G29 parameters). + #define MIN_PROBE_EDGE 10 + + // Probe along the Y axis, advancing X after each column + //#define PROBE_Y_FIRST + + #if ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Beyond the probed grid, continue the implied tilt? + // Default is to maintain the height of the nearest edge. + //#define EXTRAPOLATE_BEYOND_GRID + + // + // Experimental Subdivision of the grid by Catmull-Rom method. + // Synthesizes intermediate points to produce a more detailed mesh. + // + //#define ABL_BILINEAR_SUBDIVISION + #if ENABLED(ABL_BILINEAR_SUBDIVISION) + // Number of subdivisions between probe points + #define BILINEAR_SUBDIVISIONS 3 + #endif + + #endif + +#elif ENABLED(AUTO_BED_LEVELING_3POINT) + + // 3 arbitrary points to probe. + // A simple cross-product is used to estimate the plane of the bed. + #define ABL_PROBE_PT_1_X 15 + #define ABL_PROBE_PT_1_Y 180 + #define ABL_PROBE_PT_2_X 15 + #define ABL_PROBE_PT_2_Y 20 + #define ABL_PROBE_PT_3_X 170 + #define ABL_PROBE_PT_3_Y 20 + +#elif ENABLED(AUTO_BED_LEVELING_UBL) + + //=========================================================================== + //========================= Unified Bed Leveling ============================ + //=========================================================================== + + #define UBL_MESH_INSET 1 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 10 // Don't use more than 15 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + #define UBL_PROBE_PT_1_X 39 // Probing points for 3-Point leveling of the mesh + #define UBL_PROBE_PT_1_Y 180 + #define UBL_PROBE_PT_2_X 39 + #define UBL_PROBE_PT_2_Y 20 + #define UBL_PROBE_PT_3_X 180 + #define UBL_PROBE_PT_3_Y 20 + + #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation + #define UBL_MESH_EDIT_MOVES_Z // Sophisticated users prefer no movement of nozzle + +#elif ENABLED(MESH_BED_LEVELING) + + //=========================================================================== + //=================================== Mesh ================================== + //=========================================================================== + + #define MESH_INSET 10 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 3 // Don't use more than 7 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + //#define MESH_G28_REST_ORIGIN // After homing all axes ('G28' or 'G28 XYZ') rest Z at Z_MIN_POS + +#endif // BED_LEVELING + +/** + * Use the LCD controller for bed leveling + * Requires MESH_BED_LEVELING or PROBE_MANUALLY + */ +//#define LCD_BED_LEVELING + +#if ENABLED(LCD_BED_LEVELING) + #define MBL_Z_STEP 0.025 // Step size while manually probing Z axis. + #define LCD_PROBE_Z_RANGE 4 // Z Range centered on Z_MIN_POS for LCD Z adjustment +#endif + +// Add a menu item to move between bed corners for manual bed adjustment +//#define LEVEL_BED_CORNERS + +/** + * Commands to execute at the end of G29 probing. + * Useful to retract or move the Z probe out of the way. + */ +//#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) +//#define BED_CENTER_AT_0_0 + +// Manually set the home position. Leave these undefined for automatic settings. +// For DELTA this is the top-center of the Cartesian print volume. +//#define MANUAL_X_HOME_POS 0 +//#define MANUAL_Y_HOME_POS 0 +//#define MANUAL_Z_HOME_POS 0 + +// Use "Z Safe Homing" to avoid homing with a Z probe outside the bed area. +// +// With this feature enabled: +// +// - 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). +// - 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 axis (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). +#endif + +// Homing speeds (mm/m) +#define HOMING_FEEDRATE_XY (120*60) +#define HOMING_FEEDRATE_Z 432 + +//============================================================================= +//============================= Additional Features =========================== +//============================================================================= + +// @section extras + +// +// EEPROM +// +// The microcontroller can store settings in the EEPROM, e.g. max velocity... +// M500 - stores parameters in EEPROM +// M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily). +// M502 - reverts to the default "factory settings". You still need to store them in EEPROM afterwards if you want to. +// +//#define EEPROM_SETTINGS // Enable for M500 and M501 commands +//#define DISABLE_M503 // Saves ~2700 bytes of PROGMEM. Disable for release! +#define EEPROM_CHITCHAT // Give feedback on EEPROM commands. Disable to save PROGMEM. + +// +// Host Keepalive +// +// When enabled Marlin will send a busy status message to the host +// every couple of seconds when it can't accept commands. +// +#define HOST_KEEPALIVE_FEATURE // Disable this if your host doesn't like keepalive messages +#define DEFAULT_KEEPALIVE_INTERVAL 2 // Number of seconds between "busy" messages. Set with M113. +#define BUSY_WHILE_HEATING // Some hosts require "busy" messages even during heating + +// +// M100 Free Memory Watcher +// +//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose + +// +// G20/G21 Inch mode support +// +//#define INCH_MODE_SUPPORT + +// +// M149 Set temperature units support +// +//#define TEMPERATURE_UNITS_SUPPORT + +// @section temperature + +// Preheat Constants +#define PREHEAT_1_TEMP_HOTEND 200 +#define PREHEAT_1_TEMP_BED 0 +#define PREHEAT_1_FAN_SPEED 255 // Value from 0 to 255 + +#define PREHEAT_2_TEMP_HOTEND 220 +#define PREHEAT_2_TEMP_BED 100 +#define PREHEAT_2_FAN_SPEED 255 // Value from 0 to 255 + +/** + * Nozzle Park -- EXPERIMENTAL + * + * Park the nozzle at the given XYZ position on idle or G27. + * + * The "P" parameter controls the action applied to the Z axis: + * + * P0 (Default) If Z is below park Z raise the nozzle. + * P1 Raise the nozzle always to Z-park height. + * P2 Raise the nozzle by Z-park amount, limited to Z_MAX_POS. + */ +//#define NOZZLE_PARK_FEATURE + +#if ENABLED(NOZZLE_PARK_FEATURE) + // Specify a park position as { X, Y, Z } + #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 } +#endif + +/** + * Clean Nozzle Feature -- EXPERIMENTAL + * + * Adds the G12 command to perform a nozzle cleaning process. + * + * Parameters: + * P Pattern + * S Strokes / Repetitions + * T Triangles (P1 only) + * + * Patterns: + * P0 Straight line (default). This process requires a sponge type material + * at a fixed bed location. "S" specifies strokes (i.e. back-forth motions) + * between the start / end points. + * + * P1 Zig-zag pattern between (X0, Y0) and (X1, Y1), "T" specifies the + * number of zig-zag triangles to do. "S" defines the number of strokes. + * Zig-zags are done in whichever is the narrower dimension. + * For example, "G12 P1 S1 T3" will execute: + * + * -- + * | (X0, Y1) | /\ /\ /\ | (X1, Y1) + * | | / \ / \ / \ | + * A | | / \ / \ / \ | + * | | / \ / \ / \ | + * | (X0, Y0) | / \/ \/ \ | (X1, Y0) + * -- +--------------------------------+ + * |________|_________|_________| + * T1 T2 T3 + * + * P2 Circular pattern with middle at NOZZLE_CLEAN_CIRCLE_MIDDLE. + * "R" specifies the radius. "S" specifies the stroke count. + * Before starting, the nozzle moves to NOZZLE_CLEAN_START_POINT. + * + * Caveats: The ending Z should be the same as starting Z. + * Attention: EXPERIMENTAL. G-code arguments may change. + * + */ +//#define NOZZLE_CLEAN_FEATURE + +#if ENABLED(NOZZLE_CLEAN_FEATURE) + // Default number of pattern repetitions + #define NOZZLE_CLEAN_STROKES 12 + + // Default number of triangles + #define NOZZLE_CLEAN_TRIANGLES 3 + + // Specify positions as { X, Y, Z } + #define NOZZLE_CLEAN_START_POINT { 30, 30, (Z_MIN_POS + 1)} + #define NOZZLE_CLEAN_END_POINT {100, 60, (Z_MIN_POS + 1)} + + // Circular pattern radius + #define NOZZLE_CLEAN_CIRCLE_RADIUS 6.5 + // Circular pattern circle fragments number + #define NOZZLE_CLEAN_CIRCLE_FN 10 + // Middle point of circle + #define NOZZLE_CLEAN_CIRCLE_MIDDLE NOZZLE_CLEAN_START_POINT + + // Moves the nozzle to the initial position + #define NOZZLE_CLEAN_GOBACK +#endif + +/** + * Print Job Timer + * + * Automatically start and stop the print job timer on M104/M109/M190. + * + * M104 (hotend, no wait) - high temp = none, low temp = stop timer + * M109 (hotend, wait) - high temp = start timer, low temp = stop timer + * M190 (bed, wait) - high temp = start timer, low temp = none + * + * The timer can also be controlled with the following commands: + * + * M75 - Start the print job timer + * M76 - Pause the print job timer + * M77 - Stop the print job timer + */ +#define PRINTJOB_TIMER_AUTOSTART + +/** + * Print Counter + * + * Track statistical data such as: + * + * - Total print jobs + * - Total successful print jobs + * - Total failed print jobs + * - Total time printing + * + * View the current statistics with M78. + */ +//#define PRINTCOUNTER + +//============================================================================= +//============================= LCD and SD support ============================ +//============================================================================= + +// @section lcd + +/** + * LCD LANGUAGE + * + * Select the language to display on the LCD. These languages are available: + * + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, + * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * tr, uk, zh_CN, zh_TW, test + * + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + */ +//#define LCD_LANGUAGE en + +/** + * LCD Character Set + * + * Note: This option is NOT applicable to Graphical Displays. + * + * All character-based LCDs provide ASCII plus one of these + * language extensions: + * + * - JAPANESE ... the most common + * - WESTERN ... with more accented characters + * - CYRILLIC ... for the Russian language + * + * To determine the language extension installed on your controller: + * + * - Compile and upload with LCD_LANGUAGE set to 'test' + * - 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 + * + * :['JAPANESE', 'WESTERN', 'CYRILLIC'] + */ +#define DISPLAY_CHARSET_HD44780 JAPANESE + +/** + * LCD TYPE + * + * Enable ULTRA_LCD for a 16x2, 16x4, 20x2, or 20x4 character-based LCD. + * Enable DOGLCD for a 128x64 (ST7565R) Full Graphical Display. + * (These options will be enabled automatically for most displays.) + * + * IMPORTANT: The U8glib library is required for Full Graphic Display! + * https://github.com/olikraus/U8glib_Arduino + */ +#define ULTRA_LCD // Character based +//#define DOGLCD // Full graphics display + +/** + * SD CARD + * + * 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 + +/** + * SD CARD: SPI SPEED + * + * Enable one of the following items for a slower SPI transfer speed. + * This may be required to resolve "volume init" errors. + */ +//#define SPI_SPEED SPI_HALF_SPEED +//#define SPI_SPEED SPI_QUARTER_SPEED +//#define SPI_SPEED SPI_EIGHTH_SPEED + +/** + * SD CARD: ENABLE CRC + * + * Use CRC checks and retries on the SD communication. + */ +//#define SD_CHECK_AND_RETRY + +// +// ENCODER SETTINGS +// +// This option overrides the default number of encoder pulses needed to +// produce one step. Should be increased for high-resolution encoders. +// +//#define ENCODER_PULSES_PER_STEP 1 + +// +// Use this option to override the number of step signals required to +// move between next/prev menu items. +// +//#define ENCODER_STEPS_PER_MENU_ITEM 5 + +/** + * Encoder Direction Options + * + * Test your encoder's behavior first with both options disabled. + * + * Reversed Value Edit and Menu Nav? Enable REVERSE_ENCODER_DIRECTION. + * Reversed Menu Navigation only? Enable REVERSE_MENU_DIRECTION. + * Reversed Value Editing only? Enable BOTH options. + */ + +// +// This option reverses the encoder direction everywhere. +// +// Set this option if CLOCKWISE causes values to DECREASE +// +//#define REVERSE_ENCODER_DIRECTION + +// +// This option reverses the encoder direction for navigating LCD menus. +// +// If CLOCKWISE normally moves DOWN this makes it go UP. +// If CLOCKWISE normally moves UP this makes it go DOWN. +// +//#define REVERSE_MENU_DIRECTION + +// +// Individual Axis Homing +// +// Add individual axis homing items (Home X, Home Y, and Home Z) to the LCD menu. +// +//#define INDIVIDUAL_AXIS_HOMING_MENU + +// +// SPEAKER/BUZZER +// +// If you have a speaker that can produce tones, enable it here. +// By default Marlin assumes you have a buzzer with a fixed frequency. +// +//#define SPEAKER + +// +// The duration and frequency for the UI feedback sound. +// Set these to 0 to disable audio feedback in the LCD menus. +// +// Note: Test audio output with the G-Code: +// M300 S P +// +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 +//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 + +// +// CONTROLLER TYPE: Standard +// +// Marlin supports a wide variety of controllers. +// Enable one of the following options to specify your controller. +// + +// +// ULTIMAKER Controller. +// +//#define ULTIMAKERCONTROLLER + +// +// ULTIPANEL as seen on Thingiverse. +// +//#define ULTIPANEL + +// +// PanelOne from T3P3 (via RAMPS 1.4 AUX2/AUX3) +// http://reprap.org/wiki/PanelOne +// +//#define PANEL_ONE + +// +// MaKr3d Makr-Panel with graphic controller and SD support. +// http://reprap.org/wiki/MaKr3d_MaKrPanel +// +//#define MAKRPANEL + +// +// ReprapWorld Graphical LCD +// https://reprapworld.com/?products_details&products_id/1218 +// +//#define REPRAPWORLD_GRAPHICAL_LCD + +// +// Activate one of these if you have a Panucatt Devices +// Viki 2.0 or mini Viki with Graphic LCD +// http://panucatt.com +// +//#define VIKI2 +//#define miniVIKI + +// +// Adafruit ST7565 Full Graphic Controller. +// https://github.com/eboston/Adafruit-ST7565-Full-Graphic-Controller/ +// +//#define ELB_FULL_GRAPHIC_CONTROLLER + +// +// RepRapDiscount Smart Controller. +// http://reprap.org/wiki/RepRapDiscount_Smart_Controller +// +// Note: Usually sold with a white PCB. +// +#define REPRAP_DISCOUNT_SMART_CONTROLLER + +// +// GADGETS3D G3D LCD/SD Controller +// http://reprap.org/wiki/RAMPS_1.3/1.4_GADGETS3D_Shield_with_Panel +// +// Note: Usually sold with a blue PCB. +// +//#define G3D_PANEL + +// +// RepRapDiscount FULL GRAPHIC Smart Controller +// http://reprap.org/wiki/RepRapDiscount_Full_Graphic_Smart_Controller +// +//#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER + +// +// MakerLab Mini Panel with graphic +// controller and SD support - http://reprap.org/wiki/Mini_panel +// +//#define MINIPANEL + +// +// RepRapWorld REPRAPWORLD_KEYPAD v1.1 +// http://reprapworld.com/?products_details&products_id=202&cPath=1591_1626 +// +// REPRAPWORLD_KEYPAD_MOVE_STEP sets how much should the robot move when a key +// is pressed, a value of 10.0 means 10mm per click. +// +//#define REPRAPWORLD_KEYPAD +//#define REPRAPWORLD_KEYPAD_MOVE_STEP 1.0 + +// +// RigidBot Panel V1.0 +// http://www.inventapart.com/ +// +//#define RIGIDBOT_PANEL + +// +// BQ LCD Smart Controller shipped by +// default with the BQ Hephestos 2 and Witbox 2. +// +//#define BQ_LCD_SMART_CONTROLLER + +// +// Cartesio UI +// http://mauk.cc/webshop/cartesio-shop/electronics/user-interface +// +//#define CARTESIO_UI + +// +// ANET_10 Controller supported displays. +// +//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. + // This LCD is known to be susceptible to electrical interference + // which scrambles the display. Pressing any button clears it up. +//#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 + // A clone of the RepRapDiscount full graphics display but with + // different pins/wiring (see pins_ANET_10.h). + +// +// LCD for Melzi Card with Graphical LCD +// +//#define LCD_FOR_MELZI + +// +// CONTROLLER TYPE: I2C +// +// Note: These controllers require the installation of Arduino's LiquidCrystal_I2C +// library. For more info: https://github.com/kiyoshigawa/LiquidCrystal_I2C +// + +// +// Elefu RA Board Control Panel +// http://www.elefu.com/index.php?route=product/product&product_id=53 +// +//#define RA_CONTROL_PANEL + +// +// Sainsmart YW Robot (LCM1602) LCD Display +// +// Note: This controller requires F.Malpartida's LiquidCrystal_I2C library +// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home +// +//#define LCD_I2C_SAINSMART_YWROBOT + +// +// Generic LCM1602 LCD adapter +// +//#define LCM1602 + +// +// PANELOLU2 LCD with status LEDs, +// separate encoder and click inputs. +// +// Note: This controller requires Arduino's LiquidTWI2 library v1.2.3 or later. +// For more info: https://github.com/lincomatic/LiquidTWI2 +// +// Note: The PANELOLU2 encoder click input can either be directly connected to +// a pin (if BTN_ENC defined to != -1) or read through I2C (when BTN_ENC == -1). +// +//#define LCD_I2C_PANELOLU2 + +// +// Panucatt VIKI LCD with status LEDs, +// integrated click & L/R/U/D buttons, separate encoder inputs. +// +//#define LCD_I2C_VIKI + +// +// SSD1306 OLED full graphics generic display +// +//#define U8GLIB_SSD1306 + +// +// SAV OLEd LCD module support using either SSD1306 or SH1106 based LCD modules +// +//#define SAV_3DGLCD +#if ENABLED(SAV_3DGLCD) + //#define U8GLIB_SSD1306 + #define U8GLIB_SH1106 +#endif + +// +// CONTROLLER TYPE: Shift register panels +// +// 2 wire Non-latching LCD SR from https://goo.gl/aJJ4sH +// LCD configuration: http://reprap.org/wiki/SAV_3D_LCD +// +//#define SAV_3DLCD + +// +// TinyBoy2 128x64 OLED / Encoder Panel +// +//#define OLED_PANEL_TINYBOY2 + +// +// Makeboard 3D Printer Parts 3D Printer Mini Display 1602 Mini Controller +// https://www.aliexpress.com/item/Micromake-Makeboard-3D-Printer-Parts-3D-Printer-Mini-Display-1602-Mini-Controller-Compatible-with-Ramps-1/32765887917.html +// +//#define MAKEBOARD_MINI_2_LINE_DISPLAY_1602 + +// +// MKS MINI12864 with graphic controller and SD support +// http://reprap.org/wiki/MKS_MINI_12864 +// +//#define MKS_MINI_12864 + +// +// Factory display for Creality CR-10 +// https://www.aliexpress.com/item/Universal-LCD-12864-3D-Printer-Display-Screen-With-Encoder-For-CR-10-CR-7-Model/32833148327.html +// +// This is RAMPS-compatible using a single 10-pin connector. +// (For CR-10 owners who want to replace the Melzi Creality board but retain the display) +// +//#define CR10_STOCKDISPLAY + +// +// MKS OLED 1.3" 128 × 64 FULL GRAPHICS CONTROLLER +// http://reprap.org/wiki/MKS_12864OLED +// +// Tiny, but very sharp OLED display +// +//#define MKS_12864OLED + +//============================================================================= +//=============================== Extra Features ============================== +//============================================================================= + +// @section extras + +// Increase the FAN PWM frequency. Removes the PWM noise but increases heating in the FET/Arduino +//#define FAST_PWM_FAN + +// Use software PWM to drive the fan, as for the heaters. This uses a very low frequency +// which is not as annoying as with the hardware PWM. On the other hand, if this frequency +// is too low, you should also increment SOFT_PWM_SCALE. +//#define FAN_SOFT_PWM + +// Incrementing this by 1 will double the software PWM frequency, +// affecting heaters, and the fan if FAN_SOFT_PWM is enabled. +// However, control resolution will be halved for each increment; +// at zero value, there are 128 effective control positions. +#define SOFT_PWM_SCALE 0 + +// If SOFT_PWM_SCALE is set to a value higher than 0, dithering can +// be used to mitigate the associated resolution loss. If enabled, +// some of the PWM cycles are stretched so on average the desired +// duty cycle is attained. +//#define SOFT_PWM_DITHER + +// Temperature status LEDs that display the hotend and bed temperature. +// If all hotends, bed temperature, and target temperature are under 54C +// then the BLUE led is on. Otherwise the RED led is on. (1C hysteresis) +//#define TEMP_STAT_LEDS + +// M240 Triggers a camera by emulating a Canon RC-1 Remote +// Data from: http://www.doc-diy.net/photo/rc-1_hacked/ +//#define PHOTOGRAPH_PIN 23 + +// 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 + +// Support for BlinkM/CyzRgb +//#define BLINKM + +// Support for PCA9632 PWM LED driver +//#define PCA9632 + +/** + * RGB LED / LED Strip Control + * + * Enable support for an RGB LED connected to 5V digital pins, or + * an RGB Strip connected to MOSFETs controlled by digital pins. + * + * 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 overall brightness parameters is also available + * + * *** CAUTION *** + * LED Strips require a MOFSET 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! + * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino + * cannot handle such current, separate 5V power supply must be used + * *** CAUTION *** + * + * LED type. This options are mutualy exclusive. Uncomment only one. + * + */ +//#define RGB_LED +//#define RGBW_LED + +#if ENABLED(RGB_LED) || ENABLED(RGBW_LED) + #define RGB_LED_R_PIN 34 + #define RGB_LED_G_PIN 43 + #define RGB_LED_B_PIN 35 + #define RGB_LED_W_PIN -1 +#endif + +// 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 (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) + #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip + #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time + #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + //#define NEOPIXEL_STARTUP_TEST // Cycle through colors at startup +#endif + +/** + * Printer Event LEDs + * + * During printing, the LEDs will reflect the printer status: + * + * - Gradually change from blue to violet as the heated bed gets to target temp + * - Gradually change from violet to red as the hotend gets to temperature + * - Change to white to illuminate work surface + * - Change to green once print has finished + * - Turn off after the print has finished and the user has pushed a button + */ +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) + #define PRINTER_EVENT_LEDS +#endif + +/*********************************************************************\ +* R/C SERVO support +* Sponsored by TrinityLabs, Reworked by codexmas +**********************************************************************/ + +// Number of servos +// +// If you select a configuration below, this will receive a default value and does not need to be set manually +// set it manually if you have more servos than extruders and wish to manually control some +// leaving it undefined or defining as 0 will disable the servo subsystem +// If unsure, leave commented / disabled +// +//#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command + +// Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. +// 300ms is a good value but you can try less delay. +// If the servo can't reach the requested position, increase it. +#define SERVO_DELAY { 300 } + +// Servo deactivation +// +// With this option servos are powered only during movement, then turned off to prevent jitter. +//#define DEACTIVATE_SERVOS_AFTER_MOVE + +/** + * Filament Width Sensor + * + * Measures the filament width in real-time and adjusts + * flow rate to compensate for any irregularities. + * + * Also allows the measured filament diameter to set the + * extrusion rate, so the slicer only has to specify the + * volume. + * + * Only a single extruder is supported at this time. + * + * 34 RAMPS_14 : Analog input 5 on the AUX2 connector + * 81 PRINTRBOARD : Analog input 2 on the Exp1 connector (version B,C,D,E) + * 301 RAMBO : Analog input 3 + * + * Note: May require analog pins to be defined for other boards. + */ +//#define FILAMENT_WIDTH_SENSOR + +#define DEFAULT_NOMINAL_FILAMENT_DIA 3.00 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. + +#if ENABLED(FILAMENT_WIDTH_SENSOR) + #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) + #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber + + #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading + #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading + #define MAX_MEASUREMENT_DELAY 20 // (bytes) Buffer size for stored measurements (1 byte per cm). Must be larger than MEASUREMENT_DELAY_CM. + + #define DEFAULT_MEASURED_FILAMENT_DIA DEFAULT_NOMINAL_FILAMENT_DIA // Set measured to nominal initially + + // Display filament width on the LCD status line. Status messages will expire after 5 seconds. + //#define FILAMENT_LCD_DISPLAY +#endif + +#endif // CONFIGURATION_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/BQ/WITBOX/Configuration_adv.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/BQ/WITBOX/Configuration_adv.h new file mode 100644 index 00000000..af68c570 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/BQ/WITBOX/Configuration_adv.h @@ -0,0 +1,1424 @@ +/** + * 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 . + * + */ + +/** + * Configuration_adv.h + * + * Advanced settings. + * Only change these if you know exactly what you're doing. + * Some of these settings can damage your printer if improperly set! + * + * Basic settings can be found in Configuration.h + * + */ +#ifndef CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H_VERSION 010100 + +// @section temperature + +//=========================================================================== +//=============================Thermal Settings ============================ +//=========================================================================== + +#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 + #endif +#endif + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * The solution: Once the temperature reaches the target, start observing. + * If the temperature stays too far below the target (hysteresis) for too long (period), + * the firmware will halt the machine as a safety precaution. + * + * If you get false positives for "Thermal Runaway" increase THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD + */ +#if ENABLED(THERMAL_PROTECTION_HOTENDS) + #define THERMAL_PROTECTION_PERIOD 40 // Seconds + #define THERMAL_PROTECTION_HYSTERESIS 4 // Degrees Celsius + + /** + * Whenever an M104 or M109 increases the target temperature the firmware will wait for the + * WATCH_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get false positives for "Heating failed" increase WATCH_TEMP_PERIOD and/or decrease WATCH_TEMP_INCREASE + * WATCH_TEMP_INCREASE should not be below 2. + */ + #define WATCH_TEMP_PERIOD 20 // Seconds + #define WATCH_TEMP_INCREASE 2 // Degrees Celsius +#endif + +/** + * Thermal Protection parameters for the bed are just as above for hotends. + */ +#if ENABLED(THERMAL_PROTECTION_BED) + #define THERMAL_PROTECTION_BED_PERIOD 20 // Seconds + #define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius + + /** + * Whenever an M140 or M190 increases the target temperature the firmware will wait for the + * WATCH_BED_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_BED_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get too many "Heating failed" errors, increase WATCH_BED_TEMP_PERIOD and/or decrease + * WATCH_BED_TEMP_INCREASE. (WATCH_BED_TEMP_INCREASE should not be below 2.) + */ + #define WATCH_BED_TEMP_PERIOD 60 // Seconds + #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius +#endif + +#if ENABLED(PIDTEMP) + // this adds an experimental additional term to the heating power, proportional to the extrusion speed. + // if Kc is chosen well, the additional required power due to increased melting should be compensated. + //#define PID_EXTRUSION_SCALING + #if ENABLED(PID_EXTRUSION_SCALING) + #define DEFAULT_Kc (100) //heating power=Kc*(e_speed) + #define LPQ_MAX_LEN 50 + #endif +#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 + */ +#define AUTOTEMP +#if ENABLED(AUTOTEMP) + #define AUTOTEMP_OLDWEIGHT 0.98 +#endif + +// Show Temperature ADC value +// Enable for M105 to include ADC values read from temperature sensors. +//#define SHOW_TEMP_ADC_VALUES + +/** + * High Temperature Thermistor Support + * + * Thermistors able to support high temperature tend to have a hard time getting + * good readings at room and lower temperatures. This means HEATER_X_RAW_LO_TEMP + * will probably be caught when the heating element first turns on during the + * preheating process, which will trigger a min_temp_error as a safety measure + * and force stop everything. + * To circumvent this limitation, we allow for a preheat time (during which, + * min_temp_error won't be triggered) and add a min_temp buffer to handle + * aberrant readings. + * + * If you want to enable this feature for your hotend thermistor(s) + * uncomment and set values > 0 in the constants below + */ + +// The number of consecutive low temperature errors that can occur +// before a min_temp_error is triggered. (Shouldn't be more than 10.) +//#define MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED 0 + +// The number of milliseconds a hotend will preheat before starting to check +// the temperature. This value should NOT be set to the time it takes the +// hot end to reach the target temperature, but the time it takes to reach +// the minimum temperature your thermistor can read. The lower the better/safer. +// This shouldn't need to be more than 30 seconds (30000) +//#define MILLISECONDS_PREHEAT_TIME 0 + +// @section extruder + +// Extruder runout prevention. +// If the machine is idle and the temperature over MINTEMP +// then extrude some filament every couple of SECONDS. +//#define EXTRUDER_RUNOUT_PREVENT +#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_EXTRUDE 5 // mm +#endif + +// @section temperature + +//These defines help to calibrate the AD595 sensor in case you get wrong temperature measurements. +//The measured temperature is defined as "actualTemp = (measuredTemp * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET" +#define TEMP_SENSOR_AD595_OFFSET 0.0 +#define TEMP_SENSOR_AD595_GAIN 1.0 + +/** + * 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. + */ +//#define USE_CONTROLLER_FAN +#if ENABLED(USE_CONTROLLER_FAN) + //#define CONTROLLER_FAN_PIN FAN1_PIN // 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 +#endif + +// When first starting the main fan, run it at full speed for the +// given number of milliseconds. This gets the fan spinning reliably +// before setting a PWM value. (Does not work with software PWM for fan on Sanguinololu) +//#define FAN_KICKSTART_TIME 100 + +// This defines the minimal speed for the main fan, run in PWM mode +// to enable uncomment and set minimal PWM speed for reliable running (1-255) +// if fan speed is [1 - (FAN_MIN_PWM-1)] it is set to FAN_MIN_PWM +//#define FAN_MIN_PWM 50 + +// @section extruder + +/** + * Extruder cooling fans + * + * Extruder auto fans automatically turn on when their extruders' + * temperatures go above EXTRUDER_AUTO_FAN_TEMPERATURE. + * + * Your board's pins file specifies the recommended pins. Override those here + * or set to -1 to disable completely. + * + * Multiple extruders can be assigned to the same pin in which case + * the fan will turn on when any selected extruder is above the threshold. + */ +#define E0_AUTO_FAN_PIN -1 +#define E1_AUTO_FAN_PIN -1 +#define E2_AUTO_FAN_PIN -1 +#define E3_AUTO_FAN_PIN -1 +#define E4_AUTO_FAN_PIN -1 +#define EXTRUDER_AUTO_FAN_TEMPERATURE 50 +#define EXTRUDER_AUTO_FAN_SPEED 255 // == full speed + +/** + * Part-Cooling Fan Multiplexer + * + * This feature allows you to digitally multiplex the fan output. + * The multiplexer is automatically switched at tool-change. + * Set FANMUX[012]_PINs below for up to 2, 4, or 8 multiplexed fans. + */ +#define FANMUX0_PIN -1 +#define FANMUX1_PIN -1 +#define FANMUX2_PIN -1 + +/** + * M355 Case Light on-off / brightness + */ +//#define CASE_LIGHT_ENABLE +#if ENABLED(CASE_LIGHT_ENABLE) + //#define CASE_LIGHT_PIN 4 // Override the default pin if needed + #define INVERT_CASE_LIGHT false // Set true if Case Light is ON when pin is LOW + #define CASE_LIGHT_DEFAULT_ON true // Set default power-up state on + #define CASE_LIGHT_DEFAULT_BRIGHTNESS 105 // Set default power-up brightness (0-255, requires PWM pin) + //#define MENU_ITEM_CASE_LIGHT // Add a Case Light option to the LCD main menu +#endif + +//=========================================================================== +//============================ Mechanical Settings ========================== +//=========================================================================== + +// @section homing + +// If you want endstops to stay on (by default) even when not homing +// enable this option. Override at any time with M120, M121. +#define ENDSTOPS_ALWAYS_ON_DEFAULT + +// @section extras + +//#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. + +// Dual X Steppers +// Uncomment this option to drive two X axis motors. +// The next unused E driver will be assigned to the second X stepper. +//#define X_DUAL_STEPPER_DRIVERS +#if ENABLED(X_DUAL_STEPPER_DRIVERS) + // Set true if the two X motors need to rotate in opposite directions + #define INVERT_X2_VS_X_DIR true +#endif + +// Dual Y Steppers +// Uncomment this option to drive two Y axis motors. +// The next unused E driver will be assigned to the second Y stepper. +//#define Y_DUAL_STEPPER_DRIVERS +#if ENABLED(Y_DUAL_STEPPER_DRIVERS) + // Set true if the two Y motors need to rotate in opposite directions + #define INVERT_Y2_VS_Y_DIR true +#endif + +// A single Z stepper driver is usually used to drive 2 stepper motors. +// Uncomment this option to use a separate stepper driver for each Z axis motor. +// The next unused E driver will be assigned to the second Z stepper. +//#define Z_DUAL_STEPPER_DRIVERS + +#if ENABLED(Z_DUAL_STEPPER_DRIVERS) + + // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper. + // That way the machine is capable to align the bed during home, since both Z steppers are homed. + // There is also an implementation of M666 (software endstops adjustment) to this feature. + // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed. + // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2. + // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive. + // Play a little bit with small adjustments (0.5mm) and check the behaviour. + // The M119 (endstops report) will start reporting the Z2 Endstop as well. + + //#define Z_DUAL_ENDSTOPS + + #if ENABLED(Z_DUAL_ENDSTOPS) + #define Z2_USE_ENDSTOP _XMAX_ + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 // Use M666 to determine/test this value + #endif + +#endif // Z_DUAL_STEPPER_DRIVERS + +// Enable this for dual x-carriage printers. +// A dual x-carriage design has the advantage that the inactive extruder can be parked which +// prevents hot-end ooze contaminating the print. It also reduces the weight of each x-carriage +// allowing faster printing speeds. Connect your X2 stepper to the first unused E plug. +//#define DUAL_X_CARRIAGE +#if ENABLED(DUAL_X_CARRIAGE) + // Configuration for second X-carriage + // Note: the first x-carriage is defined as the x-carriage which homes to the minimum endstop; + // the second x-carriage always homes to the maximum endstop. + #define X2_MIN_POS 80 // set minimum to ensure second x-carriage doesn't hit the parked first X-carriage + #define X2_MAX_POS 353 // set maximum to the distance between toolheads when both heads are homed + #define X2_HOME_DIR 1 // the second X-carriage always homes to the maximum endstop position + #define X2_HOME_POS X2_MAX_POS // default home position is the maximum carriage position + // However: In this mode the HOTEND_OFFSET_X value for the second extruder provides a software + // override for X2_HOME_POS. This also allow recalibration of the distance between the two endstops + // without modifying the firmware (through the "M218 T1 X???" command). + // Remember: you should set the second extruder x-offset to 0 in your slicer. + + // There are a few selectable movement modes for dual x-carriages using M605 S + // Mode 0 (DXC_FULL_CONTROL_MODE): Full control. The slicer has full control over both x-carriages and can achieve optimal travel results + // as long as it supports dual x-carriages. (M605 S0) + // Mode 1 (DXC_AUTO_PARK_MODE) : Auto-park mode. The firmware will automatically park and unpark the x-carriages on tool changes so + // that additional slicer support is not required. (M605 S1) + // Mode 2 (DXC_DUPLICATION_MODE) : Duplication mode. The firmware will transparently make the second x-carriage and extruder copy all + // actions of the first x-carriage. This allows the printer to print 2 arbitrary items at + // once. (2nd extruder x offset and temp offset are set using: M605 S2 [Xnnn] [Rmmm]) + + // This is the default power-up mode which can be later using M605. + #define DEFAULT_DUAL_X_CARRIAGE_MODE DXC_FULL_CONTROL_MODE + + // Default settings in "Auto-park Mode" + #define TOOLCHANGE_PARK_ZLIFT 0.2 // the distance to raise Z axis when parking an extruder + #define TOOLCHANGE_UNPARK_ZLIFT 1 // the distance to raise Z axis when unparking an extruder + + // Default x offset in duplication mode (typically set to half print bed width) + #define DEFAULT_DUPLICATION_X_OFFSET 100 + +#endif // DUAL_X_CARRIAGE + +// 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. +//#define EXT_SOLENOID + +// @section homing + +//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +#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 this is defined, if both x and y are to be homed, a diagonal move will be performed initially. + +// When G28 is called, this option will make Y home before X +//#define HOME_Y_BEFORE_X + +// @section machine + +#define AXIS_RELATIVE_MODES {false, false, false, false} + +// Allow duplication mode with a basic dual-nozzle extruder +//#define DUAL_NOZZLE_DUPLICATION_MODE + +// By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step. +#define INVERT_X_STEP_PIN false +#define INVERT_Y_STEP_PIN false +#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. +#define DEFAULT_STEPPER_DEACTIVE_TIME 60 +#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_E true + +#define DEFAULT_MINIMUMFEEDRATE 0.0 // minimum feedrate +#define DEFAULT_MINTRAVELFEEDRATE 0.0 + +//#define HOME_AFTER_DEACTIVATE // Require rehoming after steppers are deactivated + +// @section lcd + +#if ENABLED(ULTIPANEL) + #define MANUAL_FEEDRATE {120*60, 120*60, 18*60, 60} // Feedrates for manual moves along X, Y, Z, E from panel + #define ULTIPANEL_FEEDMULTIPLY // Comment to disable setting feedrate multiplier via encoder +#endif + +// @section extras + +// minimum time in microseconds that a movement needs to take if the buffer is emptied. +#define DEFAULT_MINSEGMENTTIME 20000 + +// If defined the movements slow down when the look ahead buffer is only half full +#define SLOWDOWN + +// Frequency limit +// See nophead's blog for more info +// Not working O +//#define XY_FREQUENCY_LIMIT 15 + +// 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 +// if unwanted behavior is observed on a user's machine when running at very slow speeds. +#define MINIMUM_PLANNER_SPEED 0.05 // (mm/sec) + +// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU. +#define MICROSTEP_MODES {16,16,16,16,16} // [1,2,4,8,16] + +/** + * @section stepper motor current + * + * Some boards have a means of setting the stepper motor current via firmware. + * + * The power on motor currents are set by: + * PWM_MOTOR_CURRENT - used by MINIRAMBO & ULTIMAIN_2 + * known compatible chips: A4982 + * DIGIPOT_MOTOR_CURRENT - used by BQ_ZUM_MEGA_3D, RAMBO & SCOOVO_X9H + * known compatible chips: AD5206 + * DAC_MOTOR_CURRENT_DEFAULT - used by PRINTRBOARD_REVF & RIGIDBOARD_V2 + * known compatible chips: MCP4728 + * DIGIPOT_I2C_MOTOR_CURRENTS - used by 5DPRINT, AZTEEG_X3_PRO, MIGHTYBOARD_REVE + * known compatible chips: MCP4451, MCP4018 + * + * Motor currents can also be set by M907 - M910 and by the LCD. + * M907 - applies to all. + * M908 - BQ_ZUM_MEGA_3D, RAMBO, PRINTRBOARD_REVF, RIGIDBOARD_V2 & SCOOVO_X9H + * M909, M910 & LCD - only PRINTRBOARD_REVF & RIGIDBOARD_V2 + */ +//#define PWM_MOTOR_CURRENT { 1300, 1300, 1250 } // Values in milliamps +//#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 + +// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +//#define DIGIPOT_I2C +//#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster +#define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 +// Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS +#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=========================== +//=========================================================================== + +#define ENCODER_RATE_MULTIPLIER // If defined, certain menu edit operations automatically multiply the steps when the encoder is moved quickly +#define ENCODER_10X_STEPS_PER_SEC 75 // If the encoder steps per sec exceeds this value, multiply steps moved x10 to quickly advance the value +#define ENCODER_100X_STEPS_PER_SEC 160 // If the encoder steps per sec exceeds this value, multiply steps moved x100 to really quickly advance the value + +//#define CHDK 4 //Pin for triggering CHDK to take a picture see how to use it here http://captain-slow.dk/2014/03/09/3d-printing-timelapses/ +#define CHDK_DELAY 50 //How long in ms the pin should stay HIGH before going LOW again + +// @section lcd + +// Include a page of printer information in the LCD Main Menu +//#define LCD_INFO_MENU + +// Scroll a longer status message into view +//#define STATUS_MESSAGE_SCROLLING + +// On the Info Screen, display XY with one decimal place when possible +//#define LCD_DECIMAL_SMALL_XY + +// The timeout (in ms) to return to the status screen from sub-menus +//#define LCD_TIMEOUT_TO_STATUS 15000 + +#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 + + #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? + #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. + + #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. + // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. + // using: + //#define MENU_ADDAUTOSTART + + /** + * Sort SD file listings in alphabetical order. + * + * With this option enabled, items on SD cards will be sorted + * by name for easier navigation. + * + * By default... + * + * - Use the slowest -but safest- method for sorting. + * - Folders are sorted to the top. + * - The sort key is statically allocated. + * - No added G-code (M34) support. + * - 40 item sorting limit. (Items after the first 40 are unsorted.) + * + * SD sorting uses static allocation (as set by SDSORT_LIMIT), allowing the + * compiler to calculate the worst-case usage and throw an error if the SRAM + * limit is exceeded. + * + * - SDSORT_USES_RAM provides faster sorting via a static directory buffer. + * - SDSORT_USES_STACK does the same, but uses a local stack-based buffer. + * - SDSORT_CACHE_NAMES will retain the sorted file listing in RAM. (Expensive!) + * - SDSORT_DYNAMIC_RAM only uses RAM when the SD menu is visible. (Use with caution!) + */ + //#define SDCARD_SORT_ALPHA + + // SD Card Sorting options + #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_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. + #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #endif + + // Show a progress bar on HD44780 LCDs for SD printing + //#define LCD_PROGRESS_BAR + + #if ENABLED(LCD_PROGRESS_BAR) + // Amount of time (ms) to show the bar + #define PROGRESS_BAR_BAR_TIME 2000 + // Amount of time (ms) to show the status message + #define PROGRESS_BAR_MSG_TIME 3000 + // Amount of time (ms) to retain the status message (0=forever) + #define PROGRESS_MSG_EXPIRE 0 + // Enable this to show messages for MSG_TIME then hide them + //#define PROGRESS_MSG_ONCE + // Add a menu item to test the progress bar: + //#define LCD_PROGRESS_BAR_TEST + #endif + + // This allows hosts to request long names for files and folders with M33 + //#define LONG_FILENAME_HOST_SUPPORT + + // This option allows you to abort SD printing when any endstop is triggered. + // This feature must be enabled with "M540 S1" or from the LCD menu. + // To have any effect, endstops must be enabled during SD printing. + //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + +#endif // SDSUPPORT + +/** + * Additional options for Graphical Displays + * + * Use the optimizations here to improve printing performance, + * which can be adversely affected by graphical display drawing, + * especially when doing several short moves, and when printing + * on DELTA and SCARA machines. + * + * Some of these options may result in the display lagging behind + * controller events, as there is a trade-off between reliable + * printing performance versus fast display updates. + */ +#if ENABLED(DOGLCD) + // Enable to save many cycles by drawing a hollow frame on the Info Screen + #define XYZ_HOLLOW_FRAME + + // Enable to save many cycles by drawing a hollow frame on Menu Screens + #define MENU_HOLLOW_FRAME + + // A bigger font is available for edit items. Costs 3120 bytes of PROGMEM. + // 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. + // 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 +#endif // DOGLCD + +// @section safety + +// The hardware watchdog should reset the microcontroller disabling all outputs, +// in case the firmware gets stuck and doesn't do temperature regulation. +#define USE_WATCHDOG + +#if ENABLED(USE_WATCHDOG) + // If you have a watchdog reboot in an ArduinoMega2560 then the device will hang forever, as a watchdog reset will leave the watchdog on. + // The "WATCHDOG_RESET_MANUAL" goes around this by not using the hardware reset. + // However, THIS FEATURE IS UNSAFE!, as it will only work if interrupts are disabled. And the code could hang in an interrupt routine with interrupts disabled. + //#define WATCHDOG_RESET_MANUAL +#endif + +// @section lcd + +/** + * Babystepping enables movement of the axes by tiny increments without changing + * the current position values. This feature is used primarily to adjust the Z + * axis in the first layer of a print in real-time. + * + * Warning: Does not respect endstops! + */ +//#define BABYSTEPPING +#if ENABLED(BABYSTEPPING) + //#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 100 // Babysteps are very small. Increase for faster motion. + //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping + //#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen 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_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor + //#define BABYSTEP_ZPROBE_GFX_REVERSE // Reverses the direction of the CW/CCW indicators +#endif + +// @section extruder + +/** + * Implementation of linear pressure control + * + * Assumption: advance = k * (delta velocity) + * K=0 means advance disabled. + * See Marlin documentation for calibration instructions. + */ +//#define LIN_ADVANCE + +#if ENABLED(LIN_ADVANCE) + #define LIN_ADVANCE_K 75 + + /** + * Some Slicers produce Gcode with randomly jumping extrusion widths occasionally. + * For example within a 0.4mm perimeter it may produce a single segment of 0.05mm width. + * While this is harmless for normal printing (the fluid nature of the filament will + * close this very, very tiny gap), it throws off the LIN_ADVANCE pressure adaption. + * + * For this case LIN_ADVANCE_E_D_RATIO can be used to set the extrusion:distance ratio + * to a fixed value. Note that using a fixed ratio will lead to wrong nozzle pressures + * if the slicer is using variable widths or layer heights within one print! + * + * This option sets the default E:D ratio at startup. Use `M900` to override this value. + * + * Example: `M900 W0.4 H0.2 D1.75`, where: + * - W is the extrusion width in mm + * - H is the layer height in mm + * - D is the filament diameter in mm + * + * Example: `M900 R0.0458` to set the ratio directly. + * + * Set to 0 to auto-detect the ratio based on given Gcode G1 print moves. + * + * Slic3r (including Průša Control) produces Gcode compatible with the automatic mode. + * Cura (as of this writing) may produce Gcode incompatible with the automatic mode. + */ + #define LIN_ADVANCE_E_D_RATIO 0 // The calculated ratio (or 0) according to the formula W * H / ((D / 2) ^ 2 * PI) + // Example: 0.4 * 0.2 / ((1.75 / 2) ^ 2 * PI) = 0.033260135 +#endif + +// @section leveling + +// Default mesh area is an area with an inset margin on the print area. +// Below are the macros that are used to define the borders for the mesh area, +// made available here for specialized needs, ie dual extruder setup. +#if ENABLED(MESH_BED_LEVELING) + #define MESH_MIN_X MESH_INSET + #define MESH_MAX_X (X_BED_SIZE - (MESH_INSET)) + #define MESH_MIN_Y MESH_INSET + #define MESH_MAX_Y (Y_BED_SIZE - (MESH_INSET)) +#elif ENABLED(AUTO_BED_LEVELING_UBL) + #define UBL_MESH_MIN_X UBL_MESH_INSET + #define UBL_MESH_MAX_X (X_BED_SIZE - (UBL_MESH_INSET)) + #define UBL_MESH_MIN_Y UBL_MESH_INSET + #define UBL_MESH_MAX_Y (Y_BED_SIZE - (UBL_MESH_INSET)) + + // If this is defined, the currently active mesh will be saved in the + // current slot on M500. + #define UBL_SAVE_ACTIVE_ON_M500 +#endif + +// @section extras + +// +// G2/G3 Arc Support +// +#define ARC_SUPPORT // Disable this feature to save ~3226 bytes +#if ENABLED(ARC_SUPPORT) + #define MM_PER_ARC_SEGMENT 1 // Length of each arc segment + #define N_ARC_CORRECTION 25 // Number of intertpolated 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 +#endif + +// Support for G5 with XYZE destination and IJPQ offsets. Requires ~2666 bytes. +//#define BEZIER_CURVE_SUPPORT + +// G38.2 and G38.3 Probe Target +// Enable PROBE_DOUBLE_TOUCH if you want G38 to double touch +//#define G38_PROBE_TARGET +#if ENABLED(G38_PROBE_TARGET) + #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) +#endif + +// Moves (or segments) with fewer steps than this will be joined with the next move +#define MIN_STEPS_PER_SEGMENT 6 + +// The minimum pulse width (in µs) for stepping a stepper. +// Set this if you find stepping unreliable, or if using a very fast CPU. +#define MINIMUM_STEPPER_PULSE 0 // (µs) The smallest stepper pulse allowed + +// @section temperature + +// Control heater 0 and heater 1 in parallel. +//#define HEATERS_PARALLEL + +//=========================================================================== +//================================= Buffers ================================= +//=========================================================================== + +// @section hidden + +// 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, i.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 +#else + #define BLOCK_BUFFER_SIZE 16 // maximize block buffer +#endif + +// @section serial + +// The ASCII buffer for serial input +#define MAX_CMD_SIZE 96 +#define BUFSIZE 4 + +// Transmission to Host Buffer Size +// To save 386 bytes of PROGMEM (and TX_BUFFER_SIZE+3 bytes of RAM) set to 0. +// To buffer a simple "ok" you need 4 bytes. +// For ADVANCED_OK (M105) you need 32 bytes. +// For debug-echo: 128 bytes for the optimal speed. +// Other output doesn't need to be that speedy. +// :[0, 2, 4, 8, 16, 32, 64, 128, 256] +#define TX_BUFFER_SIZE 0 + +// Host Receive Buffer Size +// Without XON/XOFF flow control (see SERIAL_XON_XOFF below) 32 bytes should be enough. +// To use flow control, set this buffer size to at least 1024 bytes. +// :[0, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048] +//#define RX_BUFFER_SIZE 1024 + +#if RX_BUFFER_SIZE >= 1024 + // Enable to have the controller send XON/XOFF control characters to + // the host to signal the RX buffer is becoming full. + //#define SERIAL_XON_XOFF +#endif + +#if ENABLED(SDSUPPORT) + // Enable this option to collect and display the maximum + // RX queue usage after transferring a file to SD. + //#define SERIAL_STATS_MAX_RX_QUEUED + + // Enable this option to collect and display the number + // of dropped bytes after a file transfer to SD. + //#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! +//#define EMERGENCY_PARSER + +// Bad Serial-connections can miss a received command by sending an 'ok' +// Therefore some clients abort after 30 seconds in a timeout. +// Some other clients start sending commands while receiving a 'wait'. +// This "wait" is only sent when the buffer is empty. 1 second is a good value here. +//#define NO_TIMEOUTS 1000 // Milliseconds + +// Some clients will have this feature soon. This could make the NO_TIMEOUTS unnecessary. +//#define ADVANCED_OK + +// @section extras + +/** + * Firmware-based and LCD-controlled retract + * + * Add G10 / G11 commands for automatic firmware-based retract / recover. + * Use M207 and M208 to define parameters for retract / recover. + * + * Use M209 to enable or disable auto-retract. + * With auto-retract enabled, all G1 E moves within the set range + * will be converted to firmware-based retract/recover moves. + * + * Be sure to turn off auto-retract during filament change. + * + * Note that M207 / M208 / M209 settings are saved to EEPROM. + * + */ +//#define FWRETRACT // ONLY PARTIALLY TESTED +#if ENABLED(FWRETRACT) + #define MIN_AUTORETRACT 0.1 // When auto-retract is on, convert E moves of this length and over + #define MAX_AUTORETRACT 10.0 // Upper limit for auto-retract conversion + #define RETRACT_LENGTH 3 // Default retract length (positive mm) + #define RETRACT_LENGTH_SWAP 13 // Default swap retract length (positive mm), for extruder change + #define RETRACT_FEEDRATE 45 // Default feedrate for retracting (mm/s) + #define RETRACT_ZLIFT 0 // Default retract Z-lift + #define RETRACT_RECOVER_LENGTH 0 // Default additional recover length (mm, added to retract length when recovering) + #define RETRACT_RECOVER_LENGTH_SWAP 0 // Default additional swap recover length (mm, added to retract length when recovering from extruder change) + #define RETRACT_RECOVER_FEEDRATE 8 // Default feedrate for recovering from retraction (mm/s) + #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) +#endif + +/** + * Advanced Pause + * Experimental feature for filament change support and for parking the nozzle when paused. + * Adds the GCode M600 for initiating filament change. + * If PARK_HEAD_ON_PAUSE enabled, adds the GCode M125 to pause printing and park the nozzle. + * + * Requires an LCD display. + * This feature is required for the default FILAMENT_RUNOUT_SCRIPT. + */ +//#define ADVANCED_PAUSE_FEATURE +#if ENABLED(ADVANCED_PAUSE_FEATURE) + #define PAUSE_PARK_X_POS 3 // X position of hotend + #define PAUSE_PARK_Y_POS 3 // Y position of hotend + #define PAUSE_PARK_Z_ADD 10 // Z addition of hotend (lift) + #define PAUSE_PARK_XY_FEEDRATE 100 // X and Y axes feedrate in mm/s (also used for delta printers Z axis) + #define PAUSE_PARK_Z_FEEDRATE 5 // Z axis feedrate in mm/s (not used for delta printers) + #define PAUSE_PARK_RETRACT_FEEDRATE 60 // Initial retract feedrate in mm/s + #define PAUSE_PARK_RETRACT_LENGTH 2 // Initial retract in mm + // It is a short retract used immediately after print interrupt before move to filament exchange position + #define FILAMENT_CHANGE_UNLOAD_FEEDRATE 10 // Unload filament feedrate in mm/s - filament unloading can be fast + #define FILAMENT_CHANGE_UNLOAD_LENGTH 100 // Unload filament length from hotend in mm + // Longer length for bowden printers to unload filament from whole bowden tube, + // shorter length for printers without bowden to unload filament from extruder only, + // 0 to disable unloading for manual unloading + #define FILAMENT_CHANGE_LOAD_FEEDRATE 6 // Load filament feedrate in mm/s - filament loading into the bowden tube can be fast + #define FILAMENT_CHANGE_LOAD_LENGTH 0 // Load filament length over hotend in mm + // Longer length for bowden printers to fast load filament into whole bowden tube over the hotend, + // Short or zero length for printers without bowden where loading is not used + #define ADVANCED_PAUSE_EXTRUDE_FEEDRATE 3 // Extrude filament feedrate in mm/s - must be slower than load feedrate + #define ADVANCED_PAUSE_EXTRUDE_LENGTH 50 // Extrude filament length in mm after filament is loaded over the hotend, + // 0 to disable for manual extrusion + // Filament can be extruded repeatedly from the filament exchange menu to fill the hotend, + // or until outcoming filament color is not clear for filament color change + #define PAUSE_PARK_NOZZLE_TIMEOUT 45 // Turn off nozzle if user doesn't change filament within this time limit in seconds + #define FILAMENT_CHANGE_NUMBER_OF_ALERT_BEEPS 5 // Number of alert beeps before printer goes quiet + #define PAUSE_PARK_NO_STEPPER_TIMEOUT // Enable to have stepper motors hold position during filament change + // even if it takes longer than DEFAULT_STEPPER_DEACTIVE_TIME. + //#define PARK_HEAD_ON_PAUSE // Go to filament change position on pause, return to print position on resume + //#define HOME_BEFORE_FILAMENT_CHANGE // Ensure homing has been completed prior to parking for filament change +#endif + +// @section tmc + +/** + * Enable this section if you have TMC26X motor drivers. + * You will need to import the TMC26XStepper library into the Arduino IDE for this + * (https://github.com/trinamic/TMC26XStepper.git) + */ +//#define HAVE_TMCDRIVER + +#if ENABLED(HAVE_TMCDRIVER) + + //#define X_IS_TMC + //#define X2_IS_TMC + //#define Y_IS_TMC + //#define Y2_IS_TMC + //#define Z_IS_TMC + //#define Z2_IS_TMC + //#define E0_IS_TMC + //#define E1_IS_TMC + //#define E2_IS_TMC + //#define E3_IS_TMC + //#define E4_IS_TMC + + #define X_MAX_CURRENT 1000 // in mA + #define X_SENSE_RESISTOR 91 // in mOhms + #define X_MICROSTEPS 16 // number of microsteps + + #define X2_MAX_CURRENT 1000 + #define X2_SENSE_RESISTOR 91 + #define X2_MICROSTEPS 16 + + #define Y_MAX_CURRENT 1000 + #define Y_SENSE_RESISTOR 91 + #define Y_MICROSTEPS 16 + + #define Y2_MAX_CURRENT 1000 + #define Y2_SENSE_RESISTOR 91 + #define Y2_MICROSTEPS 16 + + #define Z_MAX_CURRENT 1000 + #define Z_SENSE_RESISTOR 91 + #define Z_MICROSTEPS 16 + + #define Z2_MAX_CURRENT 1000 + #define Z2_SENSE_RESISTOR 91 + #define Z2_MICROSTEPS 16 + + #define E0_MAX_CURRENT 1000 + #define E0_SENSE_RESISTOR 91 + #define E0_MICROSTEPS 16 + + #define E1_MAX_CURRENT 1000 + #define E1_SENSE_RESISTOR 91 + #define E1_MICROSTEPS 16 + + #define E2_MAX_CURRENT 1000 + #define E2_SENSE_RESISTOR 91 + #define E2_MICROSTEPS 16 + + #define E3_MAX_CURRENT 1000 + #define E3_SENSE_RESISTOR 91 + #define E3_MICROSTEPS 16 + + #define E4_MAX_CURRENT 1000 + #define E4_SENSE_RESISTOR 91 + #define E4_MICROSTEPS 16 + +#endif + +// @section TMC2130 + +/** + * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. + * + * You'll also need the TMC2130Stepper Arduino library + * (https://github.com/teemuatlut/TMC2130Stepper). + * + * To use TMC2130 stepper drivers in SPI mode connect your SPI2130 pins to + * the hardware SPI interface on your board and define the required CS pins + * in your `pins_MYBOARD.h` file. (e.g., RAMPS 1.4 uses AUX3 pins `X_CS_PIN 53`, `Y_CS_PIN 49`, etc.). + */ +//#define HAVE_TMC2130 + +#if ENABLED(HAVE_TMC2130) + + // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY + //#define X_IS_TMC2130 + //#define X2_IS_TMC2130 + //#define Y_IS_TMC2130 + //#define Y2_IS_TMC2130 + //#define Z_IS_TMC2130 + //#define Z2_IS_TMC2130 + //#define E0_IS_TMC2130 + //#define E1_IS_TMC2130 + //#define E2_IS_TMC2130 + //#define E3_IS_TMC2130 + //#define E4_IS_TMC2130 + + /** + * Stepper driver settings + */ + + #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 + #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current + #define INTERPOLATE 1 // Interpolate X/Y/Z_MICROSTEPS to 256 + + #define X_CURRENT 1000 // rms current in mA. Multiply by 1.41 for peak current. + #define X_MICROSTEPS 16 // 0..256 + + #define Y_CURRENT 1000 + #define Y_MICROSTEPS 16 + + #define Z_CURRENT 1000 + #define Z_MICROSTEPS 16 + + //#define X2_CURRENT 1000 + //#define X2_MICROSTEPS 16 + + //#define Y2_CURRENT 1000 + //#define Y2_MICROSTEPS 16 + + //#define Z2_CURRENT 1000 + //#define Z2_MICROSTEPS 16 + + //#define E0_CURRENT 1000 + //#define E0_MICROSTEPS 16 + + //#define E1_CURRENT 1000 + //#define E1_MICROSTEPS 16 + + //#define E2_CURRENT 1000 + //#define E2_MICROSTEPS 16 + + //#define E3_CURRENT 1000 + //#define E3_MICROSTEPS 16 + + //#define E4_CURRENT 1000 + //#define E4_MICROSTEPS 16 + + /** + * Use Trinamic's ultra quiet stepping mode. + * When disabled, Marlin will use spreadCycle stepping mode. + */ + #define STEALTHCHOP + + /** + * Let Marlin automatically control stepper current. + * This is still an experimental feature. + * Increase current every 5s by CURRENT_STEP until stepper temperature prewarn gets triggered, + * then decrease current by CURRENT_STEP until temperature prewarn is cleared. + * Adjusting starts from X/Y/Z/E_CURRENT but will not increase over AUTO_ADJUST_MAX + * 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. + * M906 S1 - Start adjusting current + * M906 S0 - Stop adjusting current + * M911 - Report stepper driver overtemperature pre-warn condition. + * M912 - Clear stepper driver overtemperature pre-warn condition flag. + */ + //#define AUTOMATIC_CURRENT_CONTROL + + #if ENABLED(AUTOMATIC_CURRENT_CONTROL) + #define CURRENT_STEP 50 // [mA] + #define AUTO_ADJUST_MAX 1300 // [mA], 1300mA_rms = 1840mA_peak + #define REPORT_CURRENT_CHANGE + #endif + + /** + * The driver will switch to spreadCycle when stepper speed is over HYBRID_THRESHOLD. + * This mode allows for faster movements at the expense of higher noise levels. + * STEALTHCHOP needs to be enabled. + * M913 X/Y/Z/E to live tune the setting + */ + //#define HYBRID_THRESHOLD + + #define X_HYBRID_THRESHOLD 100 // [mm/s] + #define X2_HYBRID_THRESHOLD 100 + #define Y_HYBRID_THRESHOLD 100 + #define Y2_HYBRID_THRESHOLD 100 + #define Z_HYBRID_THRESHOLD 4 + #define Z2_HYBRID_THRESHOLD 4 + #define E0_HYBRID_THRESHOLD 30 + #define E1_HYBRID_THRESHOLD 30 + #define E2_HYBRID_THRESHOLD 30 + #define E3_HYBRID_THRESHOLD 30 + #define E4_HYBRID_THRESHOLD 30 + + /** + * Use stallGuard2 to sense an obstacle and trigger an endstop. + * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. + * If used along with STEALTHCHOP, the movement will be louder when homing. This is normal. + * + * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. + * Higher values make the system LESS sensitive. + * Lower value make the system MORE sensitive. + * Too low values can lead to false positives, while too high values will collide the axis without triggering. + * It is advised to set X/Y_HOME_BUMP_MM to 0. + * M914 X/Y to live tune the setting + */ + //#define SENSORLESS_HOMING + + #if ENABLED(SENSORLESS_HOMING) + #define X_HOMING_SENSITIVITY 19 + #define Y_HOMING_SENSITIVITY 19 + #endif + + /** + * You can set your own advanced settings by filling in predefined functions. + * A list of available functions can be found on the library github page + * https://github.com/teemuatlut/TMC2130Stepper + * + * Example: + * #define TMC2130_ADV() { \ + * stepperX.diag0_temp_prewarn(1); \ + * stepperX.interpolate(0); \ + * } + */ + #define TMC2130_ADV() { } + +#endif // HAVE_TMC2130 + +// @section L6470 + +/** + * Enable this section if you have L6470 motor drivers. + * You need to import the L6470 library into the Arduino IDE for this. + * (https://github.com/ameyer/Arduino-L6470) + */ + +//#define HAVE_L6470DRIVER +#if ENABLED(HAVE_L6470DRIVER) + + //#define X_IS_L6470 + //#define X2_IS_L6470 + //#define Y_IS_L6470 + //#define Y2_IS_L6470 + //#define Z_IS_L6470 + //#define Z2_IS_L6470 + //#define E0_IS_L6470 + //#define E1_IS_L6470 + //#define E2_IS_L6470 + //#define E3_IS_L6470 + //#define E4_IS_L6470 + + #define X_MICROSTEPS 16 // number of microsteps + #define X_K_VAL 50 // 0 - 255, Higher values, are higher power. Be careful not to go too high + #define X_OVERCURRENT 2000 // maxc current in mA. If the current goes over this value, the driver will switch off + #define X_STALLCURRENT 1500 // current in mA where the driver will detect a stall + + #define X2_MICROSTEPS 16 + #define X2_K_VAL 50 + #define X2_OVERCURRENT 2000 + #define X2_STALLCURRENT 1500 + + #define Y_MICROSTEPS 16 + #define Y_K_VAL 50 + #define Y_OVERCURRENT 2000 + #define Y_STALLCURRENT 1500 + + #define Y2_MICROSTEPS 16 + #define Y2_K_VAL 50 + #define Y2_OVERCURRENT 2000 + #define Y2_STALLCURRENT 1500 + + #define Z_MICROSTEPS 16 + #define Z_K_VAL 50 + #define Z_OVERCURRENT 2000 + #define Z_STALLCURRENT 1500 + + #define Z2_MICROSTEPS 16 + #define Z2_K_VAL 50 + #define Z2_OVERCURRENT 2000 + #define Z2_STALLCURRENT 1500 + + #define E0_MICROSTEPS 16 + #define E0_K_VAL 50 + #define E0_OVERCURRENT 2000 + #define E0_STALLCURRENT 1500 + + #define E1_MICROSTEPS 16 + #define E1_K_VAL 50 + #define E1_OVERCURRENT 2000 + #define E1_STALLCURRENT 1500 + + #define E2_MICROSTEPS 16 + #define E2_K_VAL 50 + #define E2_OVERCURRENT 2000 + #define E2_STALLCURRENT 1500 + + #define E3_MICROSTEPS 16 + #define E3_K_VAL 50 + #define E3_OVERCURRENT 2000 + #define E3_STALLCURRENT 1500 + + #define E4_MICROSTEPS 16 + #define E4_K_VAL 50 + #define E4_OVERCURRENT 2000 + #define E4_STALLCURRENT 1500 + +#endif + +/** + * TWI/I2C BUS + * + * This feature is an EXPERIMENTAL feature so it shall not be used on production + * machines. Enabling this will allow you to send and receive I2C data from slave + * devices on the bus. + * + * ; Example #1 + * ; This macro send the string "Marlin" to the slave device with address 0x63 (99) + * ; It uses multiple M260 commands with one B arg + * M260 A99 ; Target slave address + * M260 B77 ; M + * M260 B97 ; a + * M260 B114 ; r + * M260 B108 ; l + * M260 B105 ; i + * M260 B110 ; n + * M260 S1 ; Send the current buffer + * + * ; Example #2 + * ; Request 6 bytes from slave device with address 0x63 (99) + * M261 A99 B5 + * + * ; Example #3 + * ; Example serial output of a M261 request + * echo:i2c-reply: from:99 bytes:5 data:hello + */ + +// @section i2cbus + +//#define EXPERIMENTAL_I2CBUS +#define I2C_SLAVE_ADDRESS 0 // Set a value from 8 to 127 to act as a slave + +// @section extras + +/** + * Spindle & Laser control + * + * Add the M3, M4, and M5 commands to turn the spindle/laser on and off, and + * to set spindle speed, spindle direction, and laser power. + * + * SuperPid is a router/spindle speed controller used in the CNC milling community. + * Marlin can be used to turn the spindle on and off. It can also be used to set + * the spindle speed from 5,000 to 30,000 RPM. + * + * 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. + */ +//#define SPINDLE_LASER_ENABLE +#if ENABLED(SPINDLE_LASER_ENABLE) + + #define SPINDLE_LASER_ENABLE_INVERT false // set to "true" if the on/off function is reversed + #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 // delay in milliseconds to allow the spindle/laser to come up to speed/power + #define SPINDLE_LASER_POWERDOWN_DELAY 5000 // delay in milliseconds to allow the spindle to stop + #define SPINDLE_DIR_CHANGE true // set to true if your spindle controller supports changing spindle direction + #define SPINDLE_INVERT_DIR false + #define SPINDLE_STOP_ON_DIR_CHANGE true // set to true if Marlin should stop the spindle before changing rotation direction + + /** + * The M3 & M4 commands use the following equation to convert PWM duty cycle to speed/power + * + * SPEED/POWER = PWM duty cycle * SPEED_POWER_SLOPE + SPEED_POWER_INTERCEPT + * where PWM duty cycle varies from 0 to 255 + * + * set the following for your controller (ALL MUST BE SET) + */ + + #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_SLOPE 0.3922 + //#define SPEED_POWER_INTERCEPT 0 + //#define SPEED_POWER_MIN 10 + //#define SPEED_POWER_MAX 100 // 0-100% +#endif + +/** + * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins + */ +//#define PINS_DEBUGGING + +/** + * Auto-report temperatures with M155 S + */ +#define AUTO_REPORT_TEMPERATURES + +/** + * Include capabilities in M115 output + */ +#define EXTENDED_CAPABILITIES_REPORT + +/** + * Volumetric extrusion default state + * 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. + */ +//#define VOLUMETRIC_DEFAULT_ON + +/** + * Enable this option for a leaner build of Marlin that removes all + * workspace offsets, simplifying coordinate transformations, leveling, etc. + * + * - M206 and M428 are disabled. + * - G92 will revert to its behavior from Marlin 1.0. + */ +//#define NO_WORKSPACE_OFFSETS + +/** + * 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. + * + * For clients that use a fixed-width font (like OctoPrint), leave this set to 1.0. + * Otherwise, adjust according to your client and font. + */ +#define PROPORTIONAL_FONT_RATIO 1.0 + +/** + * Spend 28 bytes of SRAM to optimize the GCode parser + */ +#define FASTER_GCODE_PARSER + +/** + * User-defined menu items that execute custom GCode + */ +//#define CUSTOM_USER_MENUS +#if ENABLED(CUSTOM_USER_MENUS) + #define USER_SCRIPT_DONE "M117 User Script Done" + #define USER_SCRIPT_AUDIBLE_FEEDBACK + //#define USER_SCRIPT_RETURN // Return to status screen after a script + + #define USER_DESC_1 "Home & UBL Info" + #define USER_GCODE_1 "G28\nG29 W" + + #define USER_DESC_2 "Preheat for PLA" + #define USER_GCODE_2 "M140 S" STRINGIFY(PREHEAT_1_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND) + + #define USER_DESC_3 "Preheat for ABS" + #define USER_GCODE_3 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND) + + #define USER_DESC_4 "Heat Bed/Home/Level" + #define USER_GCODE_4 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nG28\nG29" + + //#define USER_DESC_5 "Home & Info" + //#define USER_GCODE_5 "G28\nM503" +#endif + +/** + * Specify an action command to send to the host when the printer is killed. + * Will be sent in the form '//action:ACTION_ON_KILL', e.g. '//action:poweroff'. + * The host must be configured to handle the action command. + */ +//#define ACTION_ON_KILL "poweroff" + +//=========================================================================== +//====================== I2C Position Encoder Settings ====================== +//=========================================================================== + +/** + * I2C position encoders for closed loop control. + * Developed by Chris Barr at Aus3D. + * + * Wiki: http://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/ + * + * Reilabuild encoders have been modified to improve reliability. + */ + +//#define I2C_POSITION_ENCODERS +#if ENABLED(I2C_POSITION_ENCODERS) + + #define I2CPE_ENCODER_CNT 1 // The number of encoders installed; max of 5 + // encoders supported currently. + + #define I2CPE_ENC_1_ADDR I2CPE_PRESET_ADDR_X // I2C address of the encoder. 30-200. + #define I2CPE_ENC_1_AXIS X_AXIS // Axis the encoder module is installed on. _AXIS. + #define I2CPE_ENC_1_TYPE I2CPE_ENC_TYPE_LINEAR // Type of encoder: I2CPE_ENC_TYPE_LINEAR -or- + // I2CPE_ENC_TYPE_ROTARY. + #define I2CPE_ENC_1_TICKS_UNIT 2048 // 1024 for magnetic strips with 2mm poles; 2048 for + // 1mm poles. For linear encoders this is ticks / mm, + // for rotary encoders this is ticks / revolution. + //#define I2CPE_ENC_1_TICKS_REV (16 * 200) // Only needed for rotary encoders; number of stepper + // steps per full revolution (motor steps/rev * microstepping) + //#define I2CPE_ENC_1_INVERT // Invert the direction of axis travel. + #define I2CPE_ENC_1_EC_METHOD I2CPE_ECM_NONE // Type of error error correction. + #define I2CPE_ENC_1_EC_THRESH 0.10 // Threshold size for error (in mm) above which the + // printer will attempt to correct the error; errors + // smaller than this are ignored to minimize effects of + // measurement noise / latency (filter). + + #define I2CPE_ENC_2_ADDR I2CPE_PRESET_ADDR_Y // Same as above, but for encoder 2. + #define I2CPE_ENC_2_AXIS Y_AXIS + #define I2CPE_ENC_2_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_ENC_2_TICKS_UNIT 2048 + //#define I2CPE_ENC_2_TICKS_REV (16 * 200) + //#define I2CPE_ENC_2_INVERT + #define I2CPE_ENC_2_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_ENC_2_EC_THRESH 0.10 + + #define I2CPE_ENC_3_ADDR I2CPE_PRESET_ADDR_Z // Encoder 3. Add additional configuration options + #define I2CPE_ENC_3_AXIS Z_AXIS // as above, or use defaults below. + + #define I2CPE_ENC_4_ADDR I2CPE_PRESET_ADDR_E // Encoder 4. + #define I2CPE_ENC_4_AXIS E_AXIS + + #define I2CPE_ENC_5_ADDR 34 // Encoder 5. + #define I2CPE_ENC_5_AXIS E_AXIS + + // Default settings for encoders which are enabled, but without settings configured above. + #define I2CPE_DEF_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_DEF_ENC_TICKS_UNIT 2048 + #define I2CPE_DEF_TICKS_REV (16 * 200) + #define I2CPE_DEF_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_DEF_EC_THRESH 0.1 + + //#define I2CPE_ERR_THRESH_ABORT 100.0 // Threshold size for error (in mm) error on any given + // axis after which the printer will abort. Comment out to + // disable abort behaviour. + + #define I2CPE_TIME_TRUSTED 10000 // After an encoder fault, there must be no further fault + // for this amount of time (in ms) before the encoder + // is trusted again. + + /** + * Position is checked every time a new command is executed from the buffer but during long moves, + * this setting determines the minimum update time between checks. A value of 100 works well with + * error rolling average when attempting to correct only for skips and not for vibration. + */ + #define I2CPE_MIN_UPD_TIME_MS 100 // Minimum time in miliseconds between encoder checks. + + // Use a rolling average to identify persistant errors that indicate skips, as opposed to vibration and noise. + #define I2CPE_ERR_ROLLING_AVERAGE + +#endif // I2C_POSITION_ENCODERS + +/** + * MAX7219 Debug Matrix + * + * Add support for a low-cost 8x8 LED Matrix based on the Max7219 chip, which can be used as a status + * display. Requires 3 signal wires. Some useful debug options are included to demonstrate its usage. + * + * Fully assembled MAX7219 boards can be found on the internet for under $2(US). + * For example, see https://www.ebay.com/sch/i.html?_nkw=332349290049 + */ +//#define MAX7219_DEBUG +#if ENABLED(MAX7219_DEBUG) + #define MAX7219_CLK_PIN 64 // 77 on Re-ARM // Configuration of the 3 pins to control the display + #define MAX7219_DIN_PIN 57 // 78 on Re-ARM + #define MAX7219_LOAD_PIN 44 // 79 on Re-ARM + + /** + * Sample debug features + * If you add more debug displays, be careful to avoid conflicts! + */ + #define MAX7219_DEBUG_PRINTER_ALIVE // Blink corner LED of 8x8 matrix to show that the firmware is functioning + #define MAX7219_DEBUG_STEPPER_HEAD 3 // Show the stepper queue head position on this and the next LED matrix row + #define MAX7219_DEBUG_STEPPER_TAIL 5 // Show the stepper queue tail position on this and the next LED matrix row + + #define MAX7219_DEBUG_STEPPER_QUEUE 0 // Show the current stepper queue depth on this and the next LED matrix row + // If you experience stuttering, reboots, etc. this option can reveal how + // tweaks made to the configuration are affecting the printer in real-time. +#endif + +#endif // CONFIGURATION_ADV_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/Cartesio/Configuration.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/Cartesio/Configuration.h new file mode 100644 index 00000000..306e8a3d --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/Cartesio/Configuration.h @@ -0,0 +1,1699 @@ +/** + * 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 . + * + */ + +/** + * Configuration.h + * + * Basic settings such as: + * + * - Type of electronics + * - Type of temperature sensor + * - Printer geometry + * - Endstop configuration + * - LCD controller + * - Extra features + * + * Advanced settings can be found in Configuration_adv.h + * + */ +#ifndef CONFIGURATION_H +#define CONFIGURATION_H +#define CONFIGURATION_H_VERSION 010100 + +//=========================================================================== +//============================= Getting Started ============================= +//=========================================================================== + +/** + * Here are some standard links for getting your machine calibrated: + * + * http://reprap.org/wiki/Calibration + * http://youtu.be/wAL9d7FgInk + * http://calculator.josefprusa.cz + * http://reprap.org/wiki/Triffid_Hunter%27s_Calibration_Guide + * http://www.thingiverse.com/thing:5573 + * https://sites.google.com/site/repraplogphase/calibration-of-your-reprap + * http://www.thingiverse.com/thing:298812 + */ + +//=========================================================================== +//============================= DELTA Printer =============================== +//=========================================================================== +// For a Delta printer start with one of the configuration files in the +// example_configurations/delta directory and customize for your machine. +// + +//=========================================================================== +//============================= SCARA Printer =============================== +//=========================================================================== +// For a SCARA printer start with the configuration files in +// example_configurations/SCARA and customize for your machine. +// + +// @section info + +// User-specified version info of this build to display in [Pronterface, etc] terminal window during +// startup. Implementation of an idea by Prof Braino to inform user that any changes made to this +// build by the user have been successfully uploaded into firmware. +#define STRING_CONFIG_H_AUTHOR "(MaukCC, CartesioE)" // Who made the changes. +#define SHOW_BOOTSCREEN +#define STRING_SPLASH_LINE1 SHORT_BUILD_VERSION // will be shown during bootup in line 1 +#define STRING_SPLASH_LINE2 WEBSITE_URL // will be shown during bootup in line 2 + +// +// *** VENDORS PLEASE READ ***************************************************** +// +// Marlin now allow you to have a vendor boot image to be displayed on machine +// start. When SHOW_CUSTOM_BOOTSCREEN is defined Marlin will first show your +// custom boot image and then the default Marlin boot image is shown. +// +// We suggest for you to take advantage of this new feature and keep the Marlin +// boot image unmodified. For an example have a look at the bq Hephestos 2 +// example configuration folder. +// +#define SHOW_CUSTOM_BOOTSCREEN +// @section machine + +/** + * Select which serial port on the board will be used for communication with the host. + * This allows the connection of wireless adapters (for instance) to non-default port pins. + * Serial port 0 is always used by the Arduino bootloader regardless of this setting. + * + * :[0, 1, 2, 3, 4, 5, 6, 7] + */ +#define SERIAL_PORT 0 + +/** + * This setting determines the communication speed of the printer. + * + * 250000 works in most cases, but you might try a lower speed if + * you commonly experience drop-outs during host printing. + * You may try up to 1000000 to speed up SD file transfer. + * + * :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000] + */ +#define BAUDRATE 115200 + +// Enable the Bluetooth serial interface on AT90USB devices +//#define BLUETOOTH + +// The following define selects which electronics board you have. +// Please choose the name from boards.h that matches your setup +#ifndef MOTHERBOARD + //#define MOTHERBOARD BOARD_CNCONTROLS_11 + #define MOTHERBOARD BOARD_CNCONTROLS_12 +#endif + +// Optional custom name for your RepStrap or other custom machine +// Displayed in the LCD "Ready" message +#define CUSTOM_MACHINE_NAME "CartesioE" + +// Define this to set a unique identifier for this printer, (Used by some programs to differentiate between machines) +// You can use an online service to generate a random UUID. (eg http://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] +#define EXTRUDERS 3 + +// For Cyclops or any "multi-extruder" that shares a single nozzle. +//#define SINGLENOZZLE + +/** + * Průša MK2 Single Nozzle Multi-Material Multiplexer, and variants. + * + * This device allows one stepper driver on a control board to drive + * two to eight stepper motors, one at a time, in a manner suitable + * for extruders. + * + * This option only allows the multiplexer to switch on tool-change. + * Additional options to configure custom E moves are pending. + */ +//#define MK2_MULTIPLEXER +#if ENABLED(MK2_MULTIPLEXER) + // Override the default DIO selector pins here, if needed. + // Some pins files may provide defaults for these pins. + //#define E_MUX0_PIN 40 // Always Required + //#define E_MUX1_PIN 42 // Needed for 3 to 8 steppers + //#define E_MUX2_PIN 44 // Needed for 5 to 8 steppers +#endif + +// A dual extruder that uses a single stepper motor +//#define SWITCHING_EXTRUDER +#if ENABLED(SWITCHING_EXTRUDER) + #define SWITCHING_EXTRUDER_SERVO_NR 0 + #define SWITCHING_EXTRUDER_SERVO_ANGLES { 0, 90 } // Angles for E0, E1[, E2, E3] + #if EXTRUDERS > 3 + #define SWITCHING_EXTRUDER_E23_SERVO_NR 1 + #endif +#endif + +// A dual-nozzle that uses a servomotor to raise/lower one of the nozzles +//#define SWITCHING_NOZZLE +#if ENABLED(SWITCHING_NOZZLE) + #define SWITCHING_NOZZLE_SERVO_NR 0 + #define SWITCHING_NOZZLE_SERVO_ANGLES { 0, 90 } // Angles for E0, E1 + //#define HOTEND_OFFSET_Z { 0.0, 0.0 } +#endif + +/** + * Two separate X-carriages with extruders that connect to a moving part + * via a magnetic docking mechanism. Requires SOL1_PIN and SOL2_PIN. + */ +//#define PARKING_EXTRUDER +#if ENABLED(PARKING_EXTRUDER) + #define PARKING_EXTRUDER_SOLENOIDS_INVERT // If enabled, the solenoid is NOT magnetized with applied voltage + #define PARKING_EXTRUDER_SOLENOIDS_PINS_ACTIVE LOW // LOW or HIGH pin signal energizes the coil + #define PARKING_EXTRUDER_SOLENOIDS_DELAY 250 // Delay (ms) for magnetic field. No delay if 0 or not defined. + #define PARKING_EXTRUDER_PARKING_X { -78, 184 } // X positions for parking the extruders + #define PARKING_EXTRUDER_GRAB_DISTANCE 1 // mm to move beyond the parking point to grab the extruder + #define PARKING_EXTRUDER_SECURITY_RAISE 5 // Z-raise before parking + #define HOTEND_OFFSET_Z { 0.0, 1.3 } // Z-offsets of the two hotends. The first must be 0. +#endif + +/** + * "Mixing Extruder" + * - Adds a new code, M165, to set the current mix factors. + * - Extends the stepping routines to move multiple steppers in proportion to the mix. + * - Optional support for Repetier Firmware M163, M164, and virtual extruder. + * - This implementation supports only a single extruder. + * - Enable DIRECT_MIXING_IN_G1 for Pia Taubert's reference implementation + */ +//#define MIXING_EXTRUDER +#if ENABLED(MIXING_EXTRUDER) + #define MIXING_STEPPERS 2 // Number of steppers in your mixing extruder + #define MIXING_VIRTUAL_TOOLS 16 // Use the Virtual Tool method with M163 and M164 + //#define DIRECT_MIXING_IN_G1 // Allow ABCDHI mix factors in G1 movement commands +#endif + +// Offset of the extruders (uncomment if using more than one and relying on firmware to position when changing). +// The offset has to be X=0, Y=0 for the extruder 0 hotend (default extruder). +// For the other hotends it is their distance from the extruder 0 hotend. +//#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis +//#define HOTEND_OFFSET_Y {0.0, 5.00} // (in mm) for each extruder, offset of the hotend on the Y axis + +// @section machine + +/** + * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN + * + * 0 = No Power Switch + * 1 = ATX + * 2 = X-Box 360 203Watts (the blue wire connected to PS_ON and the red wire to VCC) + * + * :{ 0:'No power switch', 1:'ATX', 2:'X-Box 360' } + */ +#define POWER_SUPPLY 1 + +#if POWER_SUPPLY > 0 + // Enable this option to leave the PSU off at startup. + // Power to steppers and heaters will need to be turned on with M80. + //#define PS_DEFAULT_OFF +#endif + +// @section temperature + +//=========================================================================== +//============================= Thermal Settings ============================ +//=========================================================================== + +/** + * --NORMAL IS 4.7kohm PULLUP!-- 1kohm pullup can be used on hotend sensor, using correct resistor and table + * + * Temperature sensors available: + * + * -3 : thermocouple with MAX31855 (only for sensor 0) + * -2 : thermocouple with MAX6675 (only for sensor 0) + * -1 : thermocouple with AD595 + * 0 : not used + * 1 : 100k thermistor - best choice for EPCOS 100k (4.7k pullup) + * 2 : 200k thermistor - ATC Semitec 204GT-2 (4.7k pullup) + * 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 (Used in ParCan & J-Head) (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) + * 71 : 100k Honeywell thermistor 135-104LAF-J01 (4.7k pullup) + * 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) + * 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" + * 20 : the PT100 circuit found in the Ultimainboard V2.x + * 60 : 100k Maker's Tool Works Kapton Bed Thermistor beta=3950 + * 66 : 4.7M High Temperature thermistor from Dyze Design + * 70 : the 100K thermistor found in the bq Hephestos 2 + * 75 : 100k Generic Silicon Heat Pad with NTC 100K MGB18-104F39050L32 thermistor + * + * 1k ohm pullup tables - This is atypical, and requires changing out the 4.7k pullup for 1k. + * (but gives greater accuracy and more stable PID) + * 51 : 100k thermistor - EPCOS (1k pullup) + * 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 + * 1010 : Pt1000 with 1k pullup (non standard) + * 147 : Pt100 with 4k7 pullup + * 110 : Pt100 with 1k pullup (non standard) + * + * Use these for Testing or Development purposes. NEVER for production machine. + * 998 : Dummy Table that ALWAYS reads 25°C or the temperature defined below. + * 999 : Dummy Table that ALWAYS reads 100°C or the temperature defined below. + * + * :{ '0': "Not used", '1':"100k / 4.7k - EPCOS", '2':"200k / 4.7k - ATC Semitec 204GT-2", '3':"Mendel-parts / 4.7k", '4':"10k !! do not use for a hotend. Bad resolution at high temp. !!", '5':"100K / 4.7k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '6':"100k / 4.7k EPCOS - Not as accurate as Table 1", '7':"100k / 4.7k Honeywell 135-104LAG-J01", '8':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT", '9':"100k / 4.7k GE Sensing AL03006-58.2K-97-G1", '10':"100k / 4.7k RS 198-961", '11':"100k / 4.7k beta 3950 1%", '12':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT (calibrated for Makibox hot bed)", '13':"100k Hisens 3950 1% up to 300°C for hotend 'Simple ONE ' & hotend 'All In ONE'", '20':"PT100 (Ultimainboard V2.x)", '51':"100k / 1k - EPCOS", '52':"200k / 1k - ATC Semitec 204GT-2", '55':"100k / 1k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '60':"100k Maker's Tool Works Kapton Bed Thermistor beta=3950", '66':"Dyze Design 4.7M High Temperature thermistor", '70':"the 100K thermistor found in the bq Hephestos 2", '71':"100k / 4.7k Honeywell 135-104LAF-J01", '147':"Pt100 / 4.7k", '1047':"Pt1000 / 4.7k", '110':"Pt100 / 1k (non-standard)", '1010':"Pt1000 / 1k (non standard)", '-3':"Thermocouple + MAX31855 (only for sensor 0)", '-2':"Thermocouple + MAX6675 (only for sensor 0)", '-1':"Thermocouple + AD595",'998':"Dummy 1", '999':"Dummy 2" } + */ +#define TEMP_SENSOR_0 -1 +#define TEMP_SENSOR_1 -1 +#define TEMP_SENSOR_2 1 +#define TEMP_SENSOR_3 0 +#define TEMP_SENSOR_4 0 +#define TEMP_SENSOR_BED 1 + +// Dummy thermistor constant temperature readings, for use with 998 and 999 +#define DUMMY_THERMISTOR_998_VALUE 25 +#define DUMMY_THERMISTOR_999_VALUE 100 + +// 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 +#define MAX_REDUNDANT_TEMP_SENSOR_DIFF 10 + +// Extruder temperature must be close to target for this long before M109 returns success +#define TEMP_RESIDENCY_TIME 4 // (seconds) +#define TEMP_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// Bed temperature must be close to target for this long before M190 returns success +#define TEMP_BED_RESIDENCY_TIME 1 // (seconds) +#define TEMP_BED_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_BED_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// The minimal temperature defines the temperature below which the heater will not be enabled It is used +// to check that the wiring to the thermistor is not broken. +// Otherwise this would lead to the heater being powered on all the time. +#define HEATER_0_MINTEMP 5 +#define HEATER_1_MINTEMP 5 +#define HEATER_2_MINTEMP 5 +#define HEATER_3_MINTEMP 5 +#define HEATER_4_MINTEMP 5 +#define BED_MINTEMP 5 + +// When temperature exceeds max temp, your heater will be switched off. +// This feature exists to protect your hotend from overheating accidentally, but *NOT* from thermistor short/failure! +// You should use MINTEMP for thermistor short/failure protection. +#define HEATER_0_MAXTEMP 415 +#define HEATER_1_MAXTEMP 415 +#define HEATER_2_MAXTEMP 415 +#define HEATER_3_MAXTEMP 415 +#define HEATER_4_MAXTEMP 415 +#define BED_MAXTEMP 165 + +//=========================================================================== +//============================= PID Settings ================================ +//=========================================================================== +// PID Tuning Guide here: http://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 +#if ENABLED(PIDTEMP) + //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. + //#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. + #define K1 0.95 //smoothing factor within the PID + + // If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it + + // Cartesio extruderV6 40W Normal + #define DEFAULT_Kp 18 + #define DEFAULT_Ki 1 + #define DEFAULT_Kd 100 + + // Cartesio extruderV6 40W Volcano + //#define DEFAULT_Kp 50 + //#define DEFAULT_Ki 9 + //#define DEFAULT_Kd 70 + + // Cartesio extruderV6 40W Cyclops + //#define DEFAULT_Kp 18 + //#define DEFAULT_Ki 1 + //#define DEFAULT_Kd 100 + +#endif // PIDTEMP + +//=========================================================================== +//============================= PID > Bed Temperature Control =============== +//=========================================================================== +// Select PID or bang-bang with PIDTEMPBED. If bang-bang, BED_LIMIT_SWITCHING will enable hysteresis +// +// Uncomment this to enable PID on the bed. It uses the same frequency PWM as the extruder. +// If your PID_dT is the default, and correct for your hardware/configuration, that means 7.689Hz, +// which is fine for driving a square wave into a resistive load and does not significantly impact you FET heating. +// This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W heater. +// If your configuration is significantly different than this and you don't understand the issues involved, you probably +// shouldn't use bed PID until someone else verifies your hardware works. +// If this is enabled, find your own PID constants below. +#define PIDTEMPBED + +//#define BED_LIMIT_SWITCHING + +// This sets the max power delivered to the bed, and replaces the HEATER_BED_DUTY_CYCLE_DIVIDER option. +// all forms of bed control obey this (PID, bang-bang, bang-bang with hysteresis) +// setting this to anything other than 255 enables a form of PWM to the bed just like HEATER_BED_DUTY_CYCLE_DIVIDER did, +// so you shouldn't use it unless you are OK with PWM on your bed. (see the comment on enabling PIDTEMPBED) +#define MAX_BED_POWER 255 // limits duty cycle to bed; 255=full current + +#if ENABLED(PIDTEMPBED) + + //#define PID_BED_DEBUG // Sends debug data to the serial port. + + //24V 500W silicone heater on to 4mm glass CartesioW + #define DEFAULT_bedKp 390 + #define DEFAULT_bedKi 70 + #define DEFAULT_bedKd 546 + + //24V 250W silicone heater on to 4mm glass CartesioM + //#define DEFAULT_bedKp 303 + //#define DEFAULT_bedKi 42 + //#define DEFAULT_bedKd 539 + + // FIND YOUR OWN: "M303 E-1 C8 S90" to run autotune on the bed at 90 degreesC for 8 cycles. +#endif // PIDTEMPBED + +// @section extruder + +// This option prevents extrusion if the temperature is below EXTRUDE_MINTEMP. +// It also enables the M302 command to set the minimum extrusion temperature +// or to allow moving the extruder regardless of the hotend temperature. +// *** IT IS HIGHLY RECOMMENDED TO LEAVE THIS OPTION ENABLED! *** +#define PREVENT_COLD_EXTRUSION +#define EXTRUDE_MINTEMP 170 + +// This option prevents a single extrusion longer than EXTRUDE_MAXLENGTH. +// Note that for Bowden Extruders a too-small value here may prevent loading. +#define PREVENT_LENGTHY_EXTRUDE +#define EXTRUDE_MAXLENGTH 200 + +//=========================================================================== +//======================== Thermal Runaway Protection ======================= +//=========================================================================== + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * If you get "Thermal Runaway" or "Heating failed" errors the + * details can be tuned in Configuration_adv.h + */ + +#define THERMAL_PROTECTION_HOTENDS // Enable thermal protection for all extruders +#define THERMAL_PROTECTION_BED // Enable thermal protection for the heated bed + +//=========================================================================== +//============================= Mechanical Settings ========================= +//=========================================================================== + +// @section machine + +// Uncomment one of these options to enable CoreXY, CoreXZ, or CoreYZ kinematics +// either in the usual order or reversed +//#define COREXY +//#define COREXZ +//#define COREYZ +//#define COREYX +//#define COREZX +//#define COREZY + +//=========================================================================== +//============================== Endstop Settings =========================== +//=========================================================================== + +// @section homing + +// Specify here all the endstop connectors that are connected to any endstop or probe. +// Almost all printers will be using one per axis. Probes will use one or more of the +// extra connectors. Leave undefined any used for non-endstop and non-probe purposes. +#define USE_XMIN_PLUG +#define USE_YMIN_PLUG +#define USE_ZMIN_PLUG +//#define USE_XMAX_PLUG +//#define USE_YMAX_PLUG +//#define USE_ZMAX_PLUG + +// coarse Endstop Settings +#define ENDSTOPPULLUPS // Comment this out (using // at the start of the line) to disable the endstop pullup resistors + +#if DISABLED(ENDSTOPPULLUPS) + // fine endstop settings: Individual pullups. will be ignored if ENDSTOPPULLUPS is defined + //#define ENDSTOPPULLUP_XMAX + //#define ENDSTOPPULLUP_YMAX + //#define ENDSTOPPULLUP_ZMAX + //#define ENDSTOPPULLUP_XMIN + //#define ENDSTOPPULLUP_YMIN + //#define ENDSTOPPULLUP_ZMIN + //#define ENDSTOPPULLUP_ZMIN_PROBE +#endif + +// Mechanical endstop with COM to ground and NC to Signal uses "false" here (most common setup). +#define X_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Y_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define X_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Y_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MIN_PROBE_ENDSTOP_INVERTING true // set to true to invert the logic of the probe. + +// Enable this feature if all enabled endstop pins are interrupt-capable. +// This will remove the need to poll the interrupt pins, saving many CPU cycles. +//#define ENDSTOP_INTERRUPTS_FEATURE + +//============================================================================= +//============================== Movement Settings ============================ +//============================================================================= +// @section motion + +/** + * Default Settings + * + * These settings can be reset by M502 + * + * Note that if EEPROM is enabled, saved values will override these. + */ + +/** + * With this option each E stepper can have its own factors for the + * following movement settings. If fewer factors are given than the + * total number of extruders, the last value applies to the rest. + */ +//#define DISTINCT_E_FACTORS + +/** + * Default Axis Steps Per Unit (steps/mm) + * Override with M92 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_AXIS_STEPS_PER_UNIT { 71.128, 71.128, 640, 152 } + +/** + * Default Max Feed Rate (mm/s) + * Override with M203 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_FEEDRATE { 200, 200, 20, 20 } + +/** + * Default Max Acceleration (change/s) change = mm/s + * (Maximum start speed for accelerated moves) + * Override with M201 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_ACCELERATION { 1000, 1000, 100, 10000 } + +/** + * Default Acceleration (change/s) change = mm/s + * Override with M204 + * + * M204 P Acceleration + * M204 R Retract Acceleration + * M204 T Travel Acceleration + */ +#define DEFAULT_ACCELERATION 500 // X, Y, Z and E acceleration for printing moves +#define DEFAULT_RETRACT_ACCELERATION 10000 // E acceleration for retracts +#define DEFAULT_TRAVEL_ACCELERATION 1000 // X, Y, Z acceleration for travel (non printing) moves + +/** + * Default Jerk (mm/s) + * Override with M205 X Y Z E + * + * "Jerk" specifies the minimum speed change that requires acceleration. + * When changing speed and direction, if the difference is less than the + * value set here, it may happen instantaneously. + */ +#define DEFAULT_XJERK 10.0 +#define DEFAULT_YJERK 10.0 +#define DEFAULT_ZJERK 0.4 +#define DEFAULT_EJERK 5.0 + +//=========================================================================== +//============================= Z Probe Options ============================= +//=========================================================================== +// @section probes + +// +// See http://marlinfw.org/configuration/probes.html +// + +/** + * Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + * + * Enable this option for a probe connected to the Z Min endstop pin. + */ +#define Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + +/** + * Z_MIN_PROBE_ENDSTOP + * + * Enable this option for a probe connected to any pin except Z-Min. + * (By default Marlin assumes the Z-Max endstop pin.) + * To use a custom Z Probe pin, set Z_MIN_PROBE_PIN below. + * + * - The simplest option is to use a free endstop connector. + * - Use 5V for powered (usually inductive) sensors. + * + * - RAMPS 1.3/1.4 boards may use the 5V, GND, and Aux4->D32 pin: + * - For simple switches connect... + * - normally-closed switches to GND and D32. + * - normally-open switches to 5V and D32. + * + * WARNING: Setting the wrong pin may have unexpected and potentially + * disastrous consequences. Use with caution and do your homework. + * + */ +//#define Z_MIN_PROBE_ENDSTOP + +/** + * Probe Type + * + * Allen Key Probes, Servo Probes, Z-Sled Probes, FIX_MOUNTED_PROBE, etc. + * Activate one of these to use Auto Bed Leveling below. + */ + +/** + * The "Manual Probe" provides a means to do "Auto" Bed Leveling without a probe. + * Use G29 repeatedly, adjusting the Z height at each point with movement commands + * or (with LCD_BED_LEVELING) the LCD controller. + */ +//#define PROBE_MANUALLY + +/** + * A Fix-Mounted Probe either doesn't deploy or needs manual deployment. + * (e.g., an inductive probe or a nozzle-based probe-switch.) + */ +//#define FIX_MOUNTED_PROBE + +/** + * Z Servo Probe, such as an endstop switch on a rotating arm. + */ +//#define Z_ENDSTOP_SERVO_NR 0 // Defaults to SERVO 0 connector. +//#define Z_SERVO_ANGLES {70,0} // Z Servo Deploy and Stow angles + +/** + * The BLTouch probe uses a Hall effect sensor and emulates a servo. + */ +//#define BLTOUCH +#if ENABLED(BLTOUCH) + //#define BLTOUCH_DELAY 375 // (ms) Enable and increase if needed +#endif + +/** + * Enable one or more of the following if probing seems unreliable. + * Heaters and/or fans can be disabled during probing to minimize electrical + * noise. A delay can also be added to allow noise and vibration to settle. + * These options are most useful for the BLTouch probe, but may also improve + * readings with inductive probes and piezo sensors. + */ +//#define PROBING_HEATERS_OFF // Turn heaters off when probing +//#define PROBING_FANS_OFF // Turn fans off when probing +//#define DELAY_BEFORE_PROBING 200 // (ms) To prevent vibrations from triggering piezo sensors + +// A probe that is deployed and stowed with a solenoid pin (SOL1_PIN) +//#define SOLENOID_PROBE + +// A sled-mounted probe like those designed by Charles Bell. +//#define Z_PROBE_SLED +//#define SLED_DOCKING_OFFSET 5 // The extra distance the X axis must travel to pickup the sled. 0 should be fine but you can push it further if you'd like. + +// +// For Z_PROBE_ALLEN_KEY see the Delta example configurations. +// + +/** + * Z Probe to nozzle (X,Y) offset, relative to (0, 0). + * X and Y offsets must be integers. + * + * In the following example the X and Y offsets are both positive: + * #define X_PROBE_OFFSET_FROM_EXTRUDER 10 + * #define Y_PROBE_OFFSET_FROM_EXTRUDER 10 + * + * +-- BACK ---+ + * | | + * L | (+) P | R <-- probe (20,20) + * E | | I + * F | (-) N (+) | G <-- nozzle (10,10) + * T | | H + * | (-) | T + * | | + * O-- FRONT --+ + * (0,0) + */ +#define X_PROBE_OFFSET_FROM_EXTRUDER 10 // X offset: -left +right [of the nozzle] +#define Y_PROBE_OFFSET_FROM_EXTRUDER 10 // Y offset: -front +behind [the nozzle] +#define Z_PROBE_OFFSET_FROM_EXTRUDER 0 // Z offset: -below +above [the nozzle] + +// X and Y axis travel speed (mm/m) between probes +#define XY_PROBE_SPEED 8000 + +// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +#define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z + +// Speed for the "accurate" probe of each point +#define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) + +// Use double touch for probing +//#define PROBE_DOUBLE_TOUCH + +/** + * Z probes require clearance when deploying, stowing, and moving between + * probe points to avoid hitting the bed and other hardware. + * Servo-mounted probes require extra space for the arm to rotate. + * Inductive probes need space to keep from triggering early. + * + * Use these settings to specify the distance (mm) to raise the probe (or + * lower the bed). The values set here apply over and above any (negative) + * probe Z Offset set with Z_PROBE_OFFSET_FROM_EXTRUDER, M851, or the LCD. + * Only integer values >= 1 are valid here. + * + * Example: `M851 Z-5` with a CLEARANCE of 4 => 9mm from bed to nozzle. + * But: `M851 Z+1` with a CLEARANCE of 2 => 2mm from bed to nozzle. + */ +#define Z_CLEARANCE_DEPLOY_PROBE 15 // Z Clearance for Deploy/Stow +#define Z_CLEARANCE_BETWEEN_PROBES 5 // Z Clearance between probe points + +// For M851 give a range for adjusting the Z probe offset +#define Z_PROBE_OFFSET_RANGE_MIN -20 +#define Z_PROBE_OFFSET_RANGE_MAX 20 + +// Enable the M48 repeatability test to test probe accuracy +//#define Z_MIN_PROBE_REPEATABILITY_TEST + +// For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1 +// :{ 0:'Low', 1:'High' } +#define X_ENABLE_ON 1 +#define Y_ENABLE_ON 1 +#define Z_ENABLE_ON 1 +#define E_ENABLE_ON 0 // For all extruders + +// Disables axis stepper immediately when it's not being used. +// 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 +//#define DISABLE_REDUCED_ACCURACY_WARNING + +// @section extruder + +#define DISABLE_E false // For all extruders +#define DISABLE_INACTIVE_EXTRUDER true // Keep only the active extruder enabled. + +// @section machine + +// Invert the stepper direction. Change (or reverse the motor connector) if an axis goes the wrong way. +#define INVERT_X_DIR false +#define INVERT_Y_DIR true +#define INVERT_Z_DIR false + +// Enable this option for Toshiba stepper drivers +//#define CONFIG_STEPPERS_TOSHIBA + +// @section extruder + +// For direct drive extruder v9 set to true, for geared extruder set to false. +#define INVERT_E0_DIR false +#define INVERT_E1_DIR false +#define INVERT_E2_DIR false +#define INVERT_E3_DIR false +#define INVERT_E4_DIR false + +// @section homing + +//#define NO_MOTION_BEFORE_HOMING // Inhibit movement until all axes have been homed + +//#define Z_HOMING_HEIGHT 4 // (in mm) Minimal z height before homing (G28) for Z clearance above the bed, clamps, ... + // Be sure you have this distance over your Z_MAX_POS in case. + +// Direction of endstops when homing; 1=MAX, -1=MIN +// :[-1,1] +#define X_HOME_DIR -1 +#define Y_HOME_DIR -1 +#define Z_HOME_DIR -1 + +// @section machine + +// The size of the print bed +#define X_BED_SIZE 435 +#define Y_BED_SIZE 270 + +// Travel limits (mm) after homing, corresponding to endstop positions. +#define X_MIN_POS 0 +#define Y_MIN_POS 0 +#define Z_MIN_POS 0 +#define X_MAX_POS X_BED_SIZE +#define Y_MAX_POS Y_BED_SIZE +#define Z_MAX_POS 400 + +// If enabled, axes won't move below MIN_POS in response to movement commands. +#define MIN_SOFTWARE_ENDSTOPS +// If enabled, axes won't move above MAX_POS in response to movement commands. +#define MAX_SOFTWARE_ENDSTOPS + +/** + * Filament Runout Sensor + * A mechanical or opto endstop is used to check for the presence of filament. + * + * RAMPS-based boards use SERVO3_PIN. + * For other boards you may need to define FIL_RUNOUT_PIN. + * By default the firmware assumes HIGH = has filament, LOW = ran out + */ +//#define FILAMENT_RUNOUT_SENSOR +#if ENABLED(FILAMENT_RUNOUT_SENSOR) + #define FIL_RUNOUT_INVERTING false // set to true to invert the logic of the sensor. + #define ENDSTOPPULLUP_FIL_RUNOUT // Uncomment to use internal pullup for filament runout pins if the sensor is defined. + #define FILAMENT_RUNOUT_SCRIPT "M600" +#endif + +//=========================================================================== +//=============================== Bed Leveling ============================== +//=========================================================================== +// @section bedlevel + +/** + * Choose one of the options below to enable G29 Bed Leveling. The parameters + * and behavior of G29 will change depending on your selection. + * + * If using a Probe for Z Homing, enable Z_SAFE_HOMING also! + * + * - AUTO_BED_LEVELING_3POINT + * Probe 3 arbitrary points on the bed (that aren't collinear) + * You specify the XY coordinates of all 3 points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_LINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_BILINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a mesh, best for large or uneven beds. + * + * - AUTO_BED_LEVELING_UBL (Unified Bed Leveling) + * A comprehensive bed leveling system combining the features and benefits + * of other systems. UBL also includes integrated Mesh Generation, Mesh + * Validation and Mesh Editing systems. Currently, UBL is only checked out + * for Cartesian Printers. That said, it was primarily designed to correct + * poor quality Delta Printers. If you feel adventurous and have a Delta, + * please post an issue if something doesn't work correctly. Initially, + * you will need to set a reduced bed size so you have a rectangular area + * to test on. + * + * - MESH_BED_LEVELING + * Probe a grid manually + * The result is a mesh, suitable for large or uneven beds. (See BILINEAR.) + * For machines without a probe, Mesh Bed Leveling provides a method to perform + * leveling in steps so you can manually adjust the Z height at each grid-point. + * With an LCD controller the process is guided step-by-step. + */ +//#define AUTO_BED_LEVELING_3POINT +//#define AUTO_BED_LEVELING_LINEAR +//#define AUTO_BED_LEVELING_BILINEAR +//#define AUTO_BED_LEVELING_UBL +//#define MESH_BED_LEVELING + +/** + * Enable detailed logging of G28, G29, M48, etc. + * Turn on with the command 'M111 S32'. + * NOTE: Requires a lot of PROGMEM! + */ +//#define DEBUG_LEVELING_FEATURE + +#if ENABLED(MESH_BED_LEVELING) || ENABLED(AUTO_BED_LEVELING_BILINEAR) || ENABLED(AUTO_BED_LEVELING_UBL) + // Gradually reduce leveling correction until a set height is reached, + // at which point movement will be level to the machine's XY plane. + // The height can be set with M420 Z + #define ENABLE_LEVELING_FADE_HEIGHT +#endif + +#if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Set the number of grid points per dimension. + #define GRID_MAX_POINTS_X 3 + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + // Set the boundaries for probing (where the probe can reach). + #define LEFT_PROBE_BED_POSITION 15 + #define RIGHT_PROBE_BED_POSITION 170 + #define FRONT_PROBE_BED_POSITION 20 + #define BACK_PROBE_BED_POSITION 170 + + // The Z probe minimum outer margin (to validate G29 parameters). + #define MIN_PROBE_EDGE 10 + + // Probe along the Y axis, advancing X after each column + //#define PROBE_Y_FIRST + + #if ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Beyond the probed grid, continue the implied tilt? + // Default is to maintain the height of the nearest edge. + //#define EXTRAPOLATE_BEYOND_GRID + + // + // Experimental Subdivision of the grid by Catmull-Rom method. + // Synthesizes intermediate points to produce a more detailed mesh. + // + //#define ABL_BILINEAR_SUBDIVISION + #if ENABLED(ABL_BILINEAR_SUBDIVISION) + // Number of subdivisions between probe points + #define BILINEAR_SUBDIVISIONS 3 + #endif + + #endif + +#elif ENABLED(AUTO_BED_LEVELING_3POINT) + + // 3 arbitrary points to probe. + // A simple cross-product is used to estimate the plane of the bed. + #define ABL_PROBE_PT_1_X 15 + #define ABL_PROBE_PT_1_Y 180 + #define ABL_PROBE_PT_2_X 15 + #define ABL_PROBE_PT_2_Y 20 + #define ABL_PROBE_PT_3_X 170 + #define ABL_PROBE_PT_3_Y 20 + +#elif ENABLED(AUTO_BED_LEVELING_UBL) + + //=========================================================================== + //========================= Unified Bed Leveling ============================ + //=========================================================================== + + #define UBL_MESH_INSET 1 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 10 // Don't use more than 15 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + #define UBL_PROBE_PT_1_X 39 // Probing points for 3-Point leveling of the mesh + #define UBL_PROBE_PT_1_Y 180 + #define UBL_PROBE_PT_2_X 39 + #define UBL_PROBE_PT_2_Y 20 + #define UBL_PROBE_PT_3_X 180 + #define UBL_PROBE_PT_3_Y 20 + + #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation + #define UBL_MESH_EDIT_MOVES_Z // Sophisticated users prefer no movement of nozzle + +#elif ENABLED(MESH_BED_LEVELING) + + //=========================================================================== + //=================================== Mesh ================================== + //=========================================================================== + + #define MESH_INSET 10 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 3 // Don't use more than 7 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + //#define MESH_G28_REST_ORIGIN // After homing all axes ('G28' or 'G28 XYZ') rest Z at Z_MIN_POS + +#endif // BED_LEVELING + +/** + * Use the LCD controller for bed leveling + * Requires MESH_BED_LEVELING or PROBE_MANUALLY + */ +//#define LCD_BED_LEVELING + +#if ENABLED(LCD_BED_LEVELING) + #define MBL_Z_STEP 0.025 // Step size while manually probing Z axis. + #define LCD_PROBE_Z_RANGE 4 // Z Range centered on Z_MIN_POS for LCD Z adjustment +#endif + +// Add a menu item to move between bed corners for manual bed adjustment +//#define LEVEL_BED_CORNERS + +/** + * Commands to execute at the end of G29 probing. + * Useful to retract or move the Z probe out of the way. + */ +//#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) +//#define BED_CENTER_AT_0_0 + +// Manually set the home position. Leave these undefined for automatic settings. +// For DELTA this is the top-center of the Cartesian print volume. +//#define MANUAL_X_HOME_POS 0 +//#define MANUAL_Y_HOME_POS 0 +//#define MANUAL_Z_HOME_POS 0 + +// Use "Z Safe Homing" to avoid homing with a Z probe outside the bed area. +// +// With this feature enabled: +// +// - 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). +// - 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 axis (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). +#endif + +// Homing speeds (mm/m) +#define HOMING_FEEDRATE_XY (50*60) +#define HOMING_FEEDRATE_Z (10*60) + +//============================================================================= +//============================= Additional Features =========================== +//============================================================================= + +// @section extras + +// +// EEPROM +// +// The microcontroller can store settings in the EEPROM, e.g. max velocity... +// M500 - stores parameters in EEPROM +// M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily). +// M502 - reverts to the default "factory settings". You still need to store them in EEPROM afterwards if you want to. +// +//#define EEPROM_SETTINGS // Enable for M500 and M501 commands +//#define DISABLE_M503 // Saves ~2700 bytes of PROGMEM. Disable for release! +#define EEPROM_CHITCHAT // Give feedback on EEPROM commands. Disable to save PROGMEM. + +// +// Host Keepalive +// +// When enabled Marlin will send a busy status message to the host +// every couple of seconds when it can't accept commands. +// +#define HOST_KEEPALIVE_FEATURE // Disable this if your host doesn't like keepalive messages +#define DEFAULT_KEEPALIVE_INTERVAL 2 // Number of seconds between "busy" messages. Set with M113. +#define BUSY_WHILE_HEATING // Some hosts require "busy" messages even during heating + +// +// M100 Free Memory Watcher +// +//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose + +// +// G20/G21 Inch mode support +// +//#define INCH_MODE_SUPPORT + +// +// M149 Set temperature units support +// +//#define TEMPERATURE_UNITS_SUPPORT + +// @section temperature + +// Preheat Constants +#define PREHEAT_1_TEMP_HOTEND 190 +#define PREHEAT_1_TEMP_BED 50 +#define PREHEAT_1_FAN_SPEED 0 // Value from 0 to 255 + +#define PREHEAT_2_TEMP_HOTEND 240 +#define PREHEAT_2_TEMP_BED 110 +#define PREHEAT_2_FAN_SPEED 0 // Value from 0 to 255 + +/** + * Nozzle Park -- EXPERIMENTAL + * + * Park the nozzle at the given XYZ position on idle or G27. + * + * The "P" parameter controls the action applied to the Z axis: + * + * P0 (Default) If Z is below park Z raise the nozzle. + * P1 Raise the nozzle always to Z-park height. + * P2 Raise the nozzle by Z-park amount, limited to Z_MAX_POS. + */ +//#define NOZZLE_PARK_FEATURE + +#if ENABLED(NOZZLE_PARK_FEATURE) + // Specify a park position as { X, Y, Z } + #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 } +#endif + +/** + * Clean Nozzle Feature -- EXPERIMENTAL + * + * Adds the G12 command to perform a nozzle cleaning process. + * + * Parameters: + * P Pattern + * S Strokes / Repetitions + * T Triangles (P1 only) + * + * Patterns: + * P0 Straight line (default). This process requires a sponge type material + * at a fixed bed location. "S" specifies strokes (i.e. back-forth motions) + * between the start / end points. + * + * P1 Zig-zag pattern between (X0, Y0) and (X1, Y1), "T" specifies the + * number of zig-zag triangles to do. "S" defines the number of strokes. + * Zig-zags are done in whichever is the narrower dimension. + * For example, "G12 P1 S1 T3" will execute: + * + * -- + * | (X0, Y1) | /\ /\ /\ | (X1, Y1) + * | | / \ / \ / \ | + * A | | / \ / \ / \ | + * | | / \ / \ / \ | + * | (X0, Y0) | / \/ \/ \ | (X1, Y0) + * -- +--------------------------------+ + * |________|_________|_________| + * T1 T2 T3 + * + * P2 Circular pattern with middle at NOZZLE_CLEAN_CIRCLE_MIDDLE. + * "R" specifies the radius. "S" specifies the stroke count. + * Before starting, the nozzle moves to NOZZLE_CLEAN_START_POINT. + * + * Caveats: The ending Z should be the same as starting Z. + * Attention: EXPERIMENTAL. G-code arguments may change. + * + */ +//#define NOZZLE_CLEAN_FEATURE + +#if ENABLED(NOZZLE_CLEAN_FEATURE) + // Default number of pattern repetitions + #define NOZZLE_CLEAN_STROKES 12 + + // Default number of triangles + #define NOZZLE_CLEAN_TRIANGLES 3 + + // Specify positions as { X, Y, Z } + #define NOZZLE_CLEAN_START_POINT { 30, 30, (Z_MIN_POS + 1)} + #define NOZZLE_CLEAN_END_POINT {100, 60, (Z_MIN_POS + 1)} + + // Circular pattern radius + #define NOZZLE_CLEAN_CIRCLE_RADIUS 6.5 + // Circular pattern circle fragments number + #define NOZZLE_CLEAN_CIRCLE_FN 10 + // Middle point of circle + #define NOZZLE_CLEAN_CIRCLE_MIDDLE NOZZLE_CLEAN_START_POINT + + // Moves the nozzle to the initial position + #define NOZZLE_CLEAN_GOBACK +#endif + +/** + * Print Job Timer + * + * Automatically start and stop the print job timer on M104/M109/M190. + * + * M104 (hotend, no wait) - high temp = none, low temp = stop timer + * M109 (hotend, wait) - high temp = start timer, low temp = stop timer + * M190 (bed, wait) - high temp = start timer, low temp = none + * + * The timer can also be controlled with the following commands: + * + * M75 - Start the print job timer + * M76 - Pause the print job timer + * M77 - Stop the print job timer + */ +#define PRINTJOB_TIMER_AUTOSTART + +/** + * Print Counter + * + * Track statistical data such as: + * + * - Total print jobs + * - Total successful print jobs + * - Total failed print jobs + * - Total time printing + * + * View the current statistics with M78. + */ +//#define PRINTCOUNTER + +//============================================================================= +//============================= LCD and SD support ============================ +//============================================================================= + +// @section lcd + +/** + * LCD LANGUAGE + * + * Select the language to display on the LCD. These languages are available: + * + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, + * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * tr, uk, zh_CN, zh_TW, test + * + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + */ +#define LCD_LANGUAGE en + +/** + * LCD Character Set + * + * Note: This option is NOT applicable to Graphical Displays. + * + * All character-based LCDs provide ASCII plus one of these + * language extensions: + * + * - JAPANESE ... the most common + * - WESTERN ... with more accented characters + * - CYRILLIC ... for the Russian language + * + * To determine the language extension installed on your controller: + * + * - Compile and upload with LCD_LANGUAGE set to 'test' + * - 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 + * + * :['JAPANESE', 'WESTERN', 'CYRILLIC'] + */ +#define DISPLAY_CHARSET_HD44780 JAPANESE + +/** + * LCD TYPE + * + * Enable ULTRA_LCD for a 16x2, 16x4, 20x2, or 20x4 character-based LCD. + * Enable DOGLCD for a 128x64 (ST7565R) Full Graphical Display. + * (These options will be enabled automatically for most displays.) + * + * IMPORTANT: The U8glib library is required for Full Graphic Display! + * https://github.com/olikraus/U8glib_Arduino + */ +//#define ULTRA_LCD // Character based +//#define DOGLCD // Full graphics display + +/** + * SD CARD + * + * 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 + +/** + * SD CARD: SPI SPEED + * + * Enable one of the following items for a slower SPI transfer speed. + * This may be required to resolve "volume init" errors. + */ +//#define SPI_SPEED SPI_HALF_SPEED +//#define SPI_SPEED SPI_QUARTER_SPEED +//#define SPI_SPEED SPI_EIGHTH_SPEED + +/** + * SD CARD: ENABLE CRC + * + * Use CRC checks and retries on the SD communication. + */ +//#define SD_CHECK_AND_RETRY + +// +// ENCODER SETTINGS +// +// This option overrides the default number of encoder pulses needed to +// produce one step. Should be increased for high-resolution encoders. +// +#define ENCODER_PULSES_PER_STEP 2 + +// +// Use this option to override the number of step signals required to +// move between next/prev menu items. +// +#define ENCODER_STEPS_PER_MENU_ITEM 1 + +/** + * Encoder Direction Options + * + * Test your encoder's behavior first with both options disabled. + * + * Reversed Value Edit and Menu Nav? Enable REVERSE_ENCODER_DIRECTION. + * Reversed Menu Navigation only? Enable REVERSE_MENU_DIRECTION. + * Reversed Value Editing only? Enable BOTH options. + */ + +// +// This option reverses the encoder direction everywhere. +// +// Set this option if CLOCKWISE causes values to DECREASE +// +//#define REVERSE_ENCODER_DIRECTION + +// +// This option reverses the encoder direction for navigating LCD menus. +// +// If CLOCKWISE normally moves DOWN this makes it go UP. +// If CLOCKWISE normally moves UP this makes it go DOWN. +// +//#define REVERSE_MENU_DIRECTION + +// +// Individual Axis Homing +// +// Add individual axis homing items (Home X, Home Y, and Home Z) to the LCD menu. +// +//#define INDIVIDUAL_AXIS_HOMING_MENU + +// +// SPEAKER/BUZZER +// +// If you have a speaker that can produce tones, enable it here. +// By default Marlin assumes you have a buzzer with a fixed frequency. +// +#define SPEAKER + +// +// The duration and frequency for the UI feedback sound. +// Set these to 0 to disable audio feedback in the LCD menus. +// +// Note: Test audio output with the G-Code: +// M300 S P +// +#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 +#define LCD_FEEDBACK_FREQUENCY_HZ 1000 + +// +// CONTROLLER TYPE: Standard +// +// Marlin supports a wide variety of controllers. +// Enable one of the following options to specify your controller. +// + +// +// ULTIMAKER Controller. +// +//#define ULTIMAKERCONTROLLER + +// +// ULTIPANEL as seen on Thingiverse. +// +//#define ULTIPANEL + +// +// PanelOne from T3P3 (via RAMPS 1.4 AUX2/AUX3) +// http://reprap.org/wiki/PanelOne +// +//#define PANEL_ONE + +// +// MaKr3d Makr-Panel with graphic controller and SD support. +// http://reprap.org/wiki/MaKr3d_MaKrPanel +// +//#define MAKRPANEL + +// +// ReprapWorld Graphical LCD +// https://reprapworld.com/?products_details&products_id/1218 +// +//#define REPRAPWORLD_GRAPHICAL_LCD + +// +// Activate one of these if you have a Panucatt Devices +// Viki 2.0 or mini Viki with Graphic LCD +// http://panucatt.com +// +//#define VIKI2 +//#define miniVIKI + +// +// Adafruit ST7565 Full Graphic Controller. +// https://github.com/eboston/Adafruit-ST7565-Full-Graphic-Controller/ +// +//#define ELB_FULL_GRAPHIC_CONTROLLER + +// +// RepRapDiscount Smart Controller. +// http://reprap.org/wiki/RepRapDiscount_Smart_Controller +// +// Note: Usually sold with a white PCB. +// +//#define REPRAP_DISCOUNT_SMART_CONTROLLER + +// +// GADGETS3D G3D LCD/SD Controller +// http://reprap.org/wiki/RAMPS_1.3/1.4_GADGETS3D_Shield_with_Panel +// +// Note: Usually sold with a blue PCB. +// +//#define G3D_PANEL + +// +// RepRapDiscount FULL GRAPHIC Smart Controller +// http://reprap.org/wiki/RepRapDiscount_Full_Graphic_Smart_Controller +// +//#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER + +// +// MakerLab Mini Panel with graphic +// controller and SD support - http://reprap.org/wiki/Mini_panel +// +//#define MINIPANEL + +// +// RepRapWorld REPRAPWORLD_KEYPAD v1.1 +// http://reprapworld.com/?products_details&products_id=202&cPath=1591_1626 +// +// REPRAPWORLD_KEYPAD_MOVE_STEP sets how much should the robot move when a key +// is pressed, a value of 10.0 means 10mm per click. +// +#define REPRAPWORLD_KEYPAD +#define REPRAPWORLD_KEYPAD_MOVE_STEP 10.0 + +// +// RigidBot Panel V1.0 +// http://www.inventapart.com/ +// +//#define RIGIDBOT_PANEL + +// +// BQ LCD Smart Controller shipped by +// default with the BQ Hephestos 2 and Witbox 2. +// +//#define BQ_LCD_SMART_CONTROLLER + +// +// Cartesio UI +// http://mauk.cc/webshop/cartesio-shop/electronics/user-interface +// +#define CARTESIO_UI + +// +// ANET_10 Controller supported displays. +// +//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. + // This LCD is known to be susceptible to electrical interference + // which scrambles the display. Pressing any button clears it up. +//#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 + // A clone of the RepRapDiscount full graphics display but with + // different pins/wiring (see pins_ANET_10.h). + +// +// LCD for Melzi Card with Graphical LCD +// +//#define LCD_FOR_MELZI + +// +// CONTROLLER TYPE: I2C +// +// Note: These controllers require the installation of Arduino's LiquidCrystal_I2C +// library. For more info: https://github.com/kiyoshigawa/LiquidCrystal_I2C +// + +// +// Elefu RA Board Control Panel +// http://www.elefu.com/index.php?route=product/product&product_id=53 +// +//#define RA_CONTROL_PANEL + +// +// Sainsmart YW Robot (LCM1602) LCD Display +// +// Note: This controller requires F.Malpartida's LiquidCrystal_I2C library +// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home +// +//#define LCD_I2C_SAINSMART_YWROBOT + +// +// Generic LCM1602 LCD adapter +// +//#define LCM1602 + +// +// PANELOLU2 LCD with status LEDs, +// separate encoder and click inputs. +// +// Note: This controller requires Arduino's LiquidTWI2 library v1.2.3 or later. +// For more info: https://github.com/lincomatic/LiquidTWI2 +// +// Note: The PANELOLU2 encoder click input can either be directly connected to +// a pin (if BTN_ENC defined to != -1) or read through I2C (when BTN_ENC == -1). +// +//#define LCD_I2C_PANELOLU2 + +// +// Panucatt VIKI LCD with status LEDs, +// integrated click & L/R/U/D buttons, separate encoder inputs. +// +//#define LCD_I2C_VIKI + +// +// SSD1306 OLED full graphics generic display +// +//#define U8GLIB_SSD1306 + +// +// SAV OLEd LCD module support using either SSD1306 or SH1106 based LCD modules +// +//#define SAV_3DGLCD +#if ENABLED(SAV_3DGLCD) + //#define U8GLIB_SSD1306 + #define U8GLIB_SH1106 +#endif + +// +// CONTROLLER TYPE: Shift register panels +// +// 2 wire Non-latching LCD SR from https://goo.gl/aJJ4sH +// LCD configuration: http://reprap.org/wiki/SAV_3D_LCD +// +//#define SAV_3DLCD + +// +// TinyBoy2 128x64 OLED / Encoder Panel +// +//#define OLED_PANEL_TINYBOY2 + +// +// Makeboard 3D Printer Parts 3D Printer Mini Display 1602 Mini Controller +// https://www.aliexpress.com/item/Micromake-Makeboard-3D-Printer-Parts-3D-Printer-Mini-Display-1602-Mini-Controller-Compatible-with-Ramps-1/32765887917.html +// +//#define MAKEBOARD_MINI_2_LINE_DISPLAY_1602 + +// +// MKS MINI12864 with graphic controller and SD support +// http://reprap.org/wiki/MKS_MINI_12864 +// +//#define MKS_MINI_12864 + +// +// Factory display for Creality CR-10 +// https://www.aliexpress.com/item/Universal-LCD-12864-3D-Printer-Display-Screen-With-Encoder-For-CR-10-CR-7-Model/32833148327.html +// +// This is RAMPS-compatible using a single 10-pin connector. +// (For CR-10 owners who want to replace the Melzi Creality board but retain the display) +// +//#define CR10_STOCKDISPLAY + +// +// MKS OLED 1.3" 128 × 64 FULL GRAPHICS CONTROLLER +// http://reprap.org/wiki/MKS_12864OLED +// +// Tiny, but very sharp OLED display +// +//#define MKS_12864OLED + +//============================================================================= +//=============================== Extra Features ============================== +//============================================================================= + +// @section extras + +// Increase the FAN PWM frequency. Removes the PWM noise but increases heating in the FET/Arduino +//#define FAST_PWM_FAN + +// Use software PWM to drive the fan, as for the heaters. This uses a very low frequency +// which is not as annoying as with the hardware PWM. On the other hand, if this frequency +// is too low, you should also increment SOFT_PWM_SCALE. +//#define FAN_SOFT_PWM + +// Incrementing this by 1 will double the software PWM frequency, +// affecting heaters, and the fan if FAN_SOFT_PWM is enabled. +// However, control resolution will be halved for each increment; +// at zero value, there are 128 effective control positions. +#define SOFT_PWM_SCALE 0 + +// If SOFT_PWM_SCALE is set to a value higher than 0, dithering can +// be used to mitigate the associated resolution loss. If enabled, +// some of the PWM cycles are stretched so on average the desired +// duty cycle is attained. +//#define SOFT_PWM_DITHER + +// Temperature status LEDs that display the hotend and bed temperature. +// If all hotends, bed temperature, and target temperature are under 54C +// then the BLUE led is on. Otherwise the RED led is on. (1C hysteresis) +#define TEMP_STAT_LEDS + +// M240 Triggers a camera by emulating a Canon RC-1 Remote +// Data from: http://www.doc-diy.net/photo/rc-1_hacked/ +//#define PHOTOGRAPH_PIN 23 + +// 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 + +// Support for BlinkM/CyzRgb +//#define BLINKM + +// Support for PCA9632 PWM LED driver +//#define PCA9632 + +/** + * RGB LED / LED Strip Control + * + * Enable support for an RGB LED connected to 5V digital pins, or + * an RGB Strip connected to MOSFETs controlled by digital pins. + * + * 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 overall brightness parameters is also available + * + * *** CAUTION *** + * LED Strips require a MOFSET 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! + * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino + * cannot handle such current, separate 5V power supply must be used + * *** CAUTION *** + * + * LED type. This options are mutualy exclusive. Uncomment only one. + * + */ +//#define RGB_LED +//#define RGBW_LED + +#if ENABLED(RGB_LED) || ENABLED(RGBW_LED) + #define RGB_LED_R_PIN 34 + #define RGB_LED_G_PIN 43 + #define RGB_LED_B_PIN 35 + #define RGB_LED_W_PIN -1 +#endif + +// 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 (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) + #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip + #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time + #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + //#define NEOPIXEL_STARTUP_TEST // Cycle through colors at startup +#endif + +/** + * Printer Event LEDs + * + * During printing, the LEDs will reflect the printer status: + * + * - Gradually change from blue to violet as the heated bed gets to target temp + * - Gradually change from violet to red as the hotend gets to temperature + * - Change to white to illuminate work surface + * - Change to green once print has finished + * - Turn off after the print has finished and the user has pushed a button + */ +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) + #define PRINTER_EVENT_LEDS +#endif + +/*********************************************************************\ +* R/C SERVO support +* Sponsored by TrinityLabs, Reworked by codexmas +**********************************************************************/ + +// Number of servos +// +// If you select a configuration below, this will receive a default value and does not need to be set manually +// set it manually if you have more servos than extruders and wish to manually control some +// leaving it undefined or defining as 0 will disable the servo subsystem +// If unsure, leave commented / disabled +// +//#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command + +// Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. +// 300ms is a good value but you can try less delay. +// If the servo can't reach the requested position, increase it. +#define SERVO_DELAY { 300 } + +// Servo deactivation +// +// With this option servos are powered only during movement, then turned off to prevent jitter. +//#define DEACTIVATE_SERVOS_AFTER_MOVE + +/** + * Filament Width Sensor + * + * Measures the filament width in real-time and adjusts + * flow rate to compensate for any irregularities. + * + * Also allows the measured filament diameter to set the + * extrusion rate, so the slicer only has to specify the + * volume. + * + * Only a single extruder is supported at this time. + * + * 34 RAMPS_14 : Analog input 5 on the AUX2 connector + * 81 PRINTRBOARD : Analog input 2 on the Exp1 connector (version B,C,D,E) + * 301 RAMBO : Analog input 3 + * + * Note: May require analog pins to be defined for other boards. + */ +//#define FILAMENT_WIDTH_SENSOR + +#define DEFAULT_NOMINAL_FILAMENT_DIA 3.00 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. + +#if ENABLED(FILAMENT_WIDTH_SENSOR) + #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) + #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber + + #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading + #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading + #define MAX_MEASUREMENT_DELAY 20 // (bytes) Buffer size for stored measurements (1 byte per cm). Must be larger than MEASUREMENT_DELAY_CM. + + #define DEFAULT_MEASURED_FILAMENT_DIA DEFAULT_NOMINAL_FILAMENT_DIA // Set measured to nominal initially + + // Display filament width on the LCD status line. Status messages will expire after 5 seconds. + //#define FILAMENT_LCD_DISPLAY +#endif + +#endif // CONFIGURATION_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/Cartesio/Configuration_adv.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/Cartesio/Configuration_adv.h new file mode 100644 index 00000000..61aa19e1 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/Cartesio/Configuration_adv.h @@ -0,0 +1,1424 @@ +/** + * 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 . + * + */ + +/** + * Configuration_adv.h + * + * Advanced settings. + * Only change these if you know exactly what you're doing. + * Some of these settings can damage your printer if improperly set! + * + * Basic settings can be found in Configuration.h + * + */ +#ifndef CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H_VERSION 010100 + +// @section temperature + +//=========================================================================== +//=============================Thermal Settings ============================ +//=========================================================================== + +#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 + #endif +#endif + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * The solution: Once the temperature reaches the target, start observing. + * If the temperature stays too far below the target (hysteresis) for too long (period), + * the firmware will halt the machine as a safety precaution. + * + * If you get false positives for "Thermal Runaway" increase THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD + */ +#if ENABLED(THERMAL_PROTECTION_HOTENDS) + #define THERMAL_PROTECTION_PERIOD 40 // Seconds + #define THERMAL_PROTECTION_HYSTERESIS 4 // Degrees Celsius + + /** + * Whenever an M104 or M109 increases the target temperature the firmware will wait for the + * WATCH_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get false positives for "Heating failed" increase WATCH_TEMP_PERIOD and/or decrease WATCH_TEMP_INCREASE + * WATCH_TEMP_INCREASE should not be below 2. + */ + #define WATCH_TEMP_PERIOD 20 // Seconds + #define WATCH_TEMP_INCREASE 2 // Degrees Celsius +#endif + +/** + * Thermal Protection parameters for the bed are just as above for hotends. + */ +#if ENABLED(THERMAL_PROTECTION_BED) + #define THERMAL_PROTECTION_BED_PERIOD 20 // Seconds + #define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius + + /** + * Whenever an M140 or M190 increases the target temperature the firmware will wait for the + * WATCH_BED_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_BED_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get too many "Heating failed" errors, increase WATCH_BED_TEMP_PERIOD and/or decrease + * WATCH_BED_TEMP_INCREASE. (WATCH_BED_TEMP_INCREASE should not be below 2.) + */ + #define WATCH_BED_TEMP_PERIOD 60 // Seconds + #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius +#endif + +#if ENABLED(PIDTEMP) + // this adds an experimental additional term to the heating power, proportional to the extrusion speed. + // if Kc is chosen well, the additional required power due to increased melting should be compensated. + //#define PID_EXTRUSION_SCALING + #if ENABLED(PID_EXTRUSION_SCALING) + #define DEFAULT_Kc (100) //heating power=Kc*(e_speed) + #define LPQ_MAX_LEN 50 + #endif +#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 + */ +#define AUTOTEMP +#if ENABLED(AUTOTEMP) + #define AUTOTEMP_OLDWEIGHT 0.98 +#endif + +// Show Temperature ADC value +// Enable for M105 to include ADC values read from temperature sensors. +//#define SHOW_TEMP_ADC_VALUES + +/** + * High Temperature Thermistor Support + * + * Thermistors able to support high temperature tend to have a hard time getting + * good readings at room and lower temperatures. This means HEATER_X_RAW_LO_TEMP + * will probably be caught when the heating element first turns on during the + * preheating process, which will trigger a min_temp_error as a safety measure + * and force stop everything. + * To circumvent this limitation, we allow for a preheat time (during which, + * min_temp_error won't be triggered) and add a min_temp buffer to handle + * aberrant readings. + * + * If you want to enable this feature for your hotend thermistor(s) + * uncomment and set values > 0 in the constants below + */ + +// The number of consecutive low temperature errors that can occur +// before a min_temp_error is triggered. (Shouldn't be more than 10.) +//#define MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED 0 + +// The number of milliseconds a hotend will preheat before starting to check +// the temperature. This value should NOT be set to the time it takes the +// hot end to reach the target temperature, but the time it takes to reach +// the minimum temperature your thermistor can read. The lower the better/safer. +// This shouldn't need to be more than 30 seconds (30000) +//#define MILLISECONDS_PREHEAT_TIME 0 + +// @section extruder + +// Extruder runout prevention. +// If the machine is idle and the temperature over MINTEMP +// then extrude some filament every couple of SECONDS. +//#define EXTRUDER_RUNOUT_PREVENT +#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_EXTRUDE 5 // mm +#endif + +// @section temperature + +//These defines help to calibrate the AD595 sensor in case you get wrong temperature measurements. +//The measured temperature is defined as "actualTemp = (measuredTemp * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET" +#define TEMP_SENSOR_AD595_OFFSET 3.0 +#define TEMP_SENSOR_AD595_GAIN 2.0 + +/** + * 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. + */ +//#define USE_CONTROLLER_FAN +#if ENABLED(USE_CONTROLLER_FAN) + //#define CONTROLLER_FAN_PIN FAN1_PIN // 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 +#endif + +// When first starting the main fan, run it at full speed for the +// given number of milliseconds. This gets the fan spinning reliably +// before setting a PWM value. (Does not work with software PWM for fan on Sanguinololu) +//#define FAN_KICKSTART_TIME 100 + +// This defines the minimal speed for the main fan, run in PWM mode +// to enable uncomment and set minimal PWM speed for reliable running (1-255) +// if fan speed is [1 - (FAN_MIN_PWM-1)] it is set to FAN_MIN_PWM +//#define FAN_MIN_PWM 50 + +// @section extruder + +/** + * Extruder cooling fans + * + * Extruder auto fans automatically turn on when their extruders' + * temperatures go above EXTRUDER_AUTO_FAN_TEMPERATURE. + * + * Your board's pins file specifies the recommended pins. Override those here + * or set to -1 to disable completely. + * + * Multiple extruders can be assigned to the same pin in which case + * the fan will turn on when any selected extruder is above the threshold. + */ +//#define E0_AUTO_FAN_PIN -1 +//#define E1_AUTO_FAN_PIN -1 +#define E2_AUTO_FAN_PIN -1 +#define E3_AUTO_FAN_PIN -1 +#define E4_AUTO_FAN_PIN -1 +#define EXTRUDER_AUTO_FAN_TEMPERATURE 35 +#define EXTRUDER_AUTO_FAN_SPEED 255 // == full speed + +/** + * Part-Cooling Fan Multiplexer + * + * This feature allows you to digitally multiplex the fan output. + * The multiplexer is automatically switched at tool-change. + * Set FANMUX[012]_PINs below for up to 2, 4, or 8 multiplexed fans. + */ +#define FANMUX0_PIN -1 +#define FANMUX1_PIN -1 +#define FANMUX2_PIN -1 + +/** + * M355 Case Light on-off / brightness + */ +//#define CASE_LIGHT_ENABLE +#if ENABLED(CASE_LIGHT_ENABLE) + //#define CASE_LIGHT_PIN 4 // Override the default pin if needed + #define INVERT_CASE_LIGHT false // Set true if Case Light is ON when pin is LOW + #define CASE_LIGHT_DEFAULT_ON true // Set default power-up state on + #define CASE_LIGHT_DEFAULT_BRIGHTNESS 105 // Set default power-up brightness (0-255, requires PWM pin) + //#define MENU_ITEM_CASE_LIGHT // Add a Case Light option to the LCD main menu +#endif + +//=========================================================================== +//============================ Mechanical Settings ========================== +//=========================================================================== + +// @section homing + +// If you want endstops to stay on (by default) even when not homing +// enable this option. Override at any time with M120, M121. +//#define ENDSTOPS_ALWAYS_ON_DEFAULT + +// @section extras + +//#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. + +// Dual X Steppers +// Uncomment this option to drive two X axis motors. +// The next unused E driver will be assigned to the second X stepper. +//#define X_DUAL_STEPPER_DRIVERS +#if ENABLED(X_DUAL_STEPPER_DRIVERS) + // Set true if the two X motors need to rotate in opposite directions + #define INVERT_X2_VS_X_DIR true +#endif + +// Dual Y Steppers +// Uncomment this option to drive two Y axis motors. +// The next unused E driver will be assigned to the second Y stepper. +//#define Y_DUAL_STEPPER_DRIVERS +#if ENABLED(Y_DUAL_STEPPER_DRIVERS) + // Set true if the two Y motors need to rotate in opposite directions + #define INVERT_Y2_VS_Y_DIR true +#endif + +// A single Z stepper driver is usually used to drive 2 stepper motors. +// Uncomment this option to use a separate stepper driver for each Z axis motor. +// The next unused E driver will be assigned to the second Z stepper. +//#define Z_DUAL_STEPPER_DRIVERS + +#if ENABLED(Z_DUAL_STEPPER_DRIVERS) + + // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper. + // That way the machine is capable to align the bed during home, since both Z steppers are homed. + // There is also an implementation of M666 (software endstops adjustment) to this feature. + // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed. + // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2. + // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive. + // Play a little bit with small adjustments (0.5mm) and check the behaviour. + // The M119 (endstops report) will start reporting the Z2 Endstop as well. + + //#define Z_DUAL_ENDSTOPS + + #if ENABLED(Z_DUAL_ENDSTOPS) + #define Z2_USE_ENDSTOP _XMAX_ + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 // Use M666 to determine/test this value + #endif + +#endif // Z_DUAL_STEPPER_DRIVERS + +// Enable this for dual x-carriage printers. +// A dual x-carriage design has the advantage that the inactive extruder can be parked which +// prevents hot-end ooze contaminating the print. It also reduces the weight of each x-carriage +// allowing faster printing speeds. Connect your X2 stepper to the first unused E plug. +//#define DUAL_X_CARRIAGE +#if ENABLED(DUAL_X_CARRIAGE) + // Configuration for second X-carriage + // Note: the first x-carriage is defined as the x-carriage which homes to the minimum endstop; + // the second x-carriage always homes to the maximum endstop. + #define X2_MIN_POS 80 // set minimum to ensure second x-carriage doesn't hit the parked first X-carriage + #define X2_MAX_POS 353 // set maximum to the distance between toolheads when both heads are homed + #define X2_HOME_DIR 1 // the second X-carriage always homes to the maximum endstop position + #define X2_HOME_POS X2_MAX_POS // default home position is the maximum carriage position + // However: In this mode the HOTEND_OFFSET_X value for the second extruder provides a software + // override for X2_HOME_POS. This also allow recalibration of the distance between the two endstops + // without modifying the firmware (through the "M218 T1 X???" command). + // Remember: you should set the second extruder x-offset to 0 in your slicer. + + // There are a few selectable movement modes for dual x-carriages using M605 S + // Mode 0 (DXC_FULL_CONTROL_MODE): Full control. The slicer has full control over both x-carriages and can achieve optimal travel results + // as long as it supports dual x-carriages. (M605 S0) + // Mode 1 (DXC_AUTO_PARK_MODE) : Auto-park mode. The firmware will automatically park and unpark the x-carriages on tool changes so + // that additional slicer support is not required. (M605 S1) + // Mode 2 (DXC_DUPLICATION_MODE) : Duplication mode. The firmware will transparently make the second x-carriage and extruder copy all + // actions of the first x-carriage. This allows the printer to print 2 arbitrary items at + // once. (2nd extruder x offset and temp offset are set using: M605 S2 [Xnnn] [Rmmm]) + + // This is the default power-up mode which can be later using M605. + #define DEFAULT_DUAL_X_CARRIAGE_MODE DXC_FULL_CONTROL_MODE + + // Default settings in "Auto-park Mode" + #define TOOLCHANGE_PARK_ZLIFT 0.2 // the distance to raise Z axis when parking an extruder + #define TOOLCHANGE_UNPARK_ZLIFT 1 // the distance to raise Z axis when unparking an extruder + + // Default x offset in duplication mode (typically set to half print bed width) + #define DEFAULT_DUPLICATION_X_OFFSET 100 + +#endif // DUAL_X_CARRIAGE + +// 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. +//#define EXT_SOLENOID + +// @section homing + +//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +#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 this is defined, if both x and y are to be homed, a diagonal move will be performed initially. + +// When G28 is called, this option will make Y home before X +#define HOME_Y_BEFORE_X + +// @section machine + +#define AXIS_RELATIVE_MODES {false, false, false, false} + +// Allow duplication mode with a basic dual-nozzle extruder +//#define DUAL_NOZZLE_DUPLICATION_MODE + +// By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step. +#define INVERT_X_STEP_PIN false +#define INVERT_Y_STEP_PIN false +#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. +#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_E true + +#define DEFAULT_MINIMUMFEEDRATE 0.0 // minimum feedrate +#define DEFAULT_MINTRAVELFEEDRATE 0.0 + +//#define HOME_AFTER_DEACTIVATE // Require rehoming after steppers are deactivated + +// @section lcd + +#if ENABLED(ULTIPANEL) + #define MANUAL_FEEDRATE {50*60, 50*60, 4*60, 60} // Feedrates for manual moves along X, Y, Z, E from panel + #define ULTIPANEL_FEEDMULTIPLY // Comment to disable setting feedrate multiplier via encoder +#endif + +// @section extras + +// minimum time in microseconds that a movement needs to take if the buffer is emptied. +#define DEFAULT_MINSEGMENTTIME 20000 + +// If defined the movements slow down when the look ahead buffer is only half full +#define SLOWDOWN + +// Frequency limit +// See nophead's blog for more info +// Not working O +//#define XY_FREQUENCY_LIMIT 15 + +// 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 +// if unwanted behavior is observed on a user's machine when running at very slow speeds. +#define MINIMUM_PLANNER_SPEED 0.05 // (mm/sec) + +// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU. +#define MICROSTEP_MODES {16,16,16,16,16} // [1,2,4,8,16] + +/** + * @section stepper motor current + * + * Some boards have a means of setting the stepper motor current via firmware. + * + * The power on motor currents are set by: + * PWM_MOTOR_CURRENT - used by MINIRAMBO & ULTIMAIN_2 + * known compatible chips: A4982 + * DIGIPOT_MOTOR_CURRENT - used by BQ_ZUM_MEGA_3D, RAMBO & SCOOVO_X9H + * known compatible chips: AD5206 + * DAC_MOTOR_CURRENT_DEFAULT - used by PRINTRBOARD_REVF & RIGIDBOARD_V2 + * known compatible chips: MCP4728 + * DIGIPOT_I2C_MOTOR_CURRENTS - used by 5DPRINT, AZTEEG_X3_PRO, MIGHTYBOARD_REVE + * known compatible chips: MCP4451, MCP4018 + * + * Motor currents can also be set by M907 - M910 and by the LCD. + * M907 - applies to all. + * M908 - BQ_ZUM_MEGA_3D, RAMBO, PRINTRBOARD_REVF, RIGIDBOARD_V2 & SCOOVO_X9H + * M909, M910 & LCD - only PRINTRBOARD_REVF & RIGIDBOARD_V2 + */ +//#define PWM_MOTOR_CURRENT { 1300, 1300, 1250 } // Values in milliamps +//#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 + +// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +//#define DIGIPOT_I2C +//#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster +#define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 +// Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS +#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=========================== +//=========================================================================== + +#define ENCODER_RATE_MULTIPLIER // If defined, certain menu edit operations automatically multiply the steps when the encoder is moved quickly +#define ENCODER_10X_STEPS_PER_SEC 75 // If the encoder steps per sec exceeds this value, multiply steps moved x10 to quickly advance the value +#define ENCODER_100X_STEPS_PER_SEC 160 // If the encoder steps per sec exceeds this value, multiply steps moved x100 to really quickly advance the value + +//#define CHDK 4 //Pin for triggering CHDK to take a picture see how to use it here http://captain-slow.dk/2014/03/09/3d-printing-timelapses/ +#define CHDK_DELAY 50 //How long in ms the pin should stay HIGH before going LOW again + +// @section lcd + +// Include a page of printer information in the LCD Main Menu +//#define LCD_INFO_MENU + +// Scroll a longer status message into view +//#define STATUS_MESSAGE_SCROLLING + +// On the Info Screen, display XY with one decimal place when possible +//#define LCD_DECIMAL_SMALL_XY + +// The timeout (in ms) to return to the status screen from sub-menus +//#define LCD_TIMEOUT_TO_STATUS 15000 + +#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 + + #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? + #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. + + #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. + // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. + // using: + //#define MENU_ADDAUTOSTART + + /** + * Sort SD file listings in alphabetical order. + * + * With this option enabled, items on SD cards will be sorted + * by name for easier navigation. + * + * By default... + * + * - Use the slowest -but safest- method for sorting. + * - Folders are sorted to the top. + * - The sort key is statically allocated. + * - No added G-code (M34) support. + * - 40 item sorting limit. (Items after the first 40 are unsorted.) + * + * SD sorting uses static allocation (as set by SDSORT_LIMIT), allowing the + * compiler to calculate the worst-case usage and throw an error if the SRAM + * limit is exceeded. + * + * - SDSORT_USES_RAM provides faster sorting via a static directory buffer. + * - SDSORT_USES_STACK does the same, but uses a local stack-based buffer. + * - SDSORT_CACHE_NAMES will retain the sorted file listing in RAM. (Expensive!) + * - SDSORT_DYNAMIC_RAM only uses RAM when the SD menu is visible. (Use with caution!) + */ + //#define SDCARD_SORT_ALPHA + + // SD Card Sorting options + #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_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. + #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #endif + + // Show a progress bar on HD44780 LCDs for SD printing + //#define LCD_PROGRESS_BAR + + #if ENABLED(LCD_PROGRESS_BAR) + // Amount of time (ms) to show the bar + #define PROGRESS_BAR_BAR_TIME 2000 + // Amount of time (ms) to show the status message + #define PROGRESS_BAR_MSG_TIME 3000 + // Amount of time (ms) to retain the status message (0=forever) + #define PROGRESS_MSG_EXPIRE 0 + // Enable this to show messages for MSG_TIME then hide them + //#define PROGRESS_MSG_ONCE + // Add a menu item to test the progress bar: + //#define LCD_PROGRESS_BAR_TEST + #endif + + // This allows hosts to request long names for files and folders with M33 + //#define LONG_FILENAME_HOST_SUPPORT + + // This option allows you to abort SD printing when any endstop is triggered. + // This feature must be enabled with "M540 S1" or from the LCD menu. + // To have any effect, endstops must be enabled during SD printing. + //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + +#endif // SDSUPPORT + +/** + * Additional options for Graphical Displays + * + * Use the optimizations here to improve printing performance, + * which can be adversely affected by graphical display drawing, + * especially when doing several short moves, and when printing + * on DELTA and SCARA machines. + * + * Some of these options may result in the display lagging behind + * controller events, as there is a trade-off between reliable + * printing performance versus fast display updates. + */ +#if ENABLED(DOGLCD) + // Enable to save many cycles by drawing a hollow frame on the Info Screen + #define XYZ_HOLLOW_FRAME + + // Enable to save many cycles by drawing a hollow frame on Menu Screens + #define MENU_HOLLOW_FRAME + + // A bigger font is available for edit items. Costs 3120 bytes of PROGMEM. + // 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. + // 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 +#endif // DOGLCD + +// @section safety + +// The hardware watchdog should reset the microcontroller disabling all outputs, +// in case the firmware gets stuck and doesn't do temperature regulation. +#define USE_WATCHDOG + +#if ENABLED(USE_WATCHDOG) + // If you have a watchdog reboot in an ArduinoMega2560 then the device will hang forever, as a watchdog reset will leave the watchdog on. + // The "WATCHDOG_RESET_MANUAL" goes around this by not using the hardware reset. + // However, THIS FEATURE IS UNSAFE!, as it will only work if interrupts are disabled. And the code could hang in an interrupt routine with interrupts disabled. + //#define WATCHDOG_RESET_MANUAL +#endif + +// @section lcd + +/** + * Babystepping enables movement of the axes by tiny increments without changing + * the current position values. This feature is used primarily to adjust the Z + * axis in the first layer of a print in real-time. + * + * Warning: Does not respect endstops! + */ +//#define BABYSTEPPING +#if ENABLED(BABYSTEPPING) + //#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 100 // Babysteps are very small. Increase for faster motion. + //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping + //#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen 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_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor + //#define BABYSTEP_ZPROBE_GFX_REVERSE // Reverses the direction of the CW/CCW indicators +#endif + +// @section extruder + +/** + * Implementation of linear pressure control + * + * Assumption: advance = k * (delta velocity) + * K=0 means advance disabled. + * See Marlin documentation for calibration instructions. + */ +//#define LIN_ADVANCE + +#if ENABLED(LIN_ADVANCE) + #define LIN_ADVANCE_K 75 + + /** + * Some Slicers produce Gcode with randomly jumping extrusion widths occasionally. + * For example within a 0.4mm perimeter it may produce a single segment of 0.05mm width. + * While this is harmless for normal printing (the fluid nature of the filament will + * close this very, very tiny gap), it throws off the LIN_ADVANCE pressure adaption. + * + * For this case LIN_ADVANCE_E_D_RATIO can be used to set the extrusion:distance ratio + * to a fixed value. Note that using a fixed ratio will lead to wrong nozzle pressures + * if the slicer is using variable widths or layer heights within one print! + * + * This option sets the default E:D ratio at startup. Use `M900` to override this value. + * + * Example: `M900 W0.4 H0.2 D1.75`, where: + * - W is the extrusion width in mm + * - H is the layer height in mm + * - D is the filament diameter in mm + * + * Example: `M900 R0.0458` to set the ratio directly. + * + * Set to 0 to auto-detect the ratio based on given Gcode G1 print moves. + * + * Slic3r (including Průša Control) produces Gcode compatible with the automatic mode. + * Cura (as of this writing) may produce Gcode incompatible with the automatic mode. + */ + #define LIN_ADVANCE_E_D_RATIO 0 // The calculated ratio (or 0) according to the formula W * H / ((D / 2) ^ 2 * PI) + // Example: 0.4 * 0.2 / ((1.75 / 2) ^ 2 * PI) = 0.033260135 +#endif + +// @section leveling + +// Default mesh area is an area with an inset margin on the print area. +// Below are the macros that are used to define the borders for the mesh area, +// made available here for specialized needs, ie dual extruder setup. +#if ENABLED(MESH_BED_LEVELING) + #define MESH_MIN_X MESH_INSET + #define MESH_MAX_X (X_BED_SIZE - (MESH_INSET)) + #define MESH_MIN_Y MESH_INSET + #define MESH_MAX_Y (Y_BED_SIZE - (MESH_INSET)) +#elif ENABLED(AUTO_BED_LEVELING_UBL) + #define UBL_MESH_MIN_X UBL_MESH_INSET + #define UBL_MESH_MAX_X (X_BED_SIZE - (UBL_MESH_INSET)) + #define UBL_MESH_MIN_Y UBL_MESH_INSET + #define UBL_MESH_MAX_Y (Y_BED_SIZE - (UBL_MESH_INSET)) + + // If this is defined, the currently active mesh will be saved in the + // current slot on M500. + #define UBL_SAVE_ACTIVE_ON_M500 +#endif + +// @section extras + +// +// G2/G3 Arc Support +// +#define ARC_SUPPORT // Disable this feature to save ~3226 bytes +#if ENABLED(ARC_SUPPORT) + #define MM_PER_ARC_SEGMENT 1 // Length of each arc segment + #define N_ARC_CORRECTION 25 // Number of intertpolated 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 +#endif + +// Support for G5 with XYZE destination and IJPQ offsets. Requires ~2666 bytes. +//#define BEZIER_CURVE_SUPPORT + +// G38.2 and G38.3 Probe Target +// Enable PROBE_DOUBLE_TOUCH if you want G38 to double touch +//#define G38_PROBE_TARGET +#if ENABLED(G38_PROBE_TARGET) + #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) +#endif + +// Moves (or segments) with fewer steps than this will be joined with the next move +#define MIN_STEPS_PER_SEGMENT 6 + +// The minimum pulse width (in µs) for stepping a stepper. +// Set this if you find stepping unreliable, or if using a very fast CPU. +#define MINIMUM_STEPPER_PULSE 0 // (µs) The smallest stepper pulse allowed + +// @section temperature + +// Control heater 0 and heater 1 in parallel. +//#define HEATERS_PARALLEL + +//=========================================================================== +//================================= Buffers ================================= +//=========================================================================== + +// @section hidden + +// 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, i.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 +#else + #define BLOCK_BUFFER_SIZE 16 // maximize block buffer +#endif + +// @section serial + +// The ASCII buffer for serial input +#define MAX_CMD_SIZE 96 +#define BUFSIZE 4 + +// Transmission to Host Buffer Size +// To save 386 bytes of PROGMEM (and TX_BUFFER_SIZE+3 bytes of RAM) set to 0. +// To buffer a simple "ok" you need 4 bytes. +// For ADVANCED_OK (M105) you need 32 bytes. +// For debug-echo: 128 bytes for the optimal speed. +// Other output doesn't need to be that speedy. +// :[0, 2, 4, 8, 16, 32, 64, 128, 256] +#define TX_BUFFER_SIZE 0 + +// Host Receive Buffer Size +// Without XON/XOFF flow control (see SERIAL_XON_XOFF below) 32 bytes should be enough. +// To use flow control, set this buffer size to at least 1024 bytes. +// :[0, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048] +//#define RX_BUFFER_SIZE 1024 + +#if RX_BUFFER_SIZE >= 1024 + // Enable to have the controller send XON/XOFF control characters to + // the host to signal the RX buffer is becoming full. + //#define SERIAL_XON_XOFF +#endif + +#if ENABLED(SDSUPPORT) + // Enable this option to collect and display the maximum + // RX queue usage after transferring a file to SD. + //#define SERIAL_STATS_MAX_RX_QUEUED + + // Enable this option to collect and display the number + // of dropped bytes after a file transfer to SD. + //#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! +//#define EMERGENCY_PARSER + +// Bad Serial-connections can miss a received command by sending an 'ok' +// Therefore some clients abort after 30 seconds in a timeout. +// Some other clients start sending commands while receiving a 'wait'. +// This "wait" is only sent when the buffer is empty. 1 second is a good value here. +//#define NO_TIMEOUTS 1000 // Milliseconds + +// Some clients will have this feature soon. This could make the NO_TIMEOUTS unnecessary. +//#define ADVANCED_OK + +// @section extras + +/** + * Firmware-based and LCD-controlled retract + * + * Add G10 / G11 commands for automatic firmware-based retract / recover. + * Use M207 and M208 to define parameters for retract / recover. + * + * Use M209 to enable or disable auto-retract. + * With auto-retract enabled, all G1 E moves within the set range + * will be converted to firmware-based retract/recover moves. + * + * Be sure to turn off auto-retract during filament change. + * + * Note that M207 / M208 / M209 settings are saved to EEPROM. + * + */ +//#define FWRETRACT // ONLY PARTIALLY TESTED +#if ENABLED(FWRETRACT) + #define MIN_AUTORETRACT 0.1 // When auto-retract is on, convert E moves of this length and over + #define MAX_AUTORETRACT 10.0 // Upper limit for auto-retract conversion + #define RETRACT_LENGTH 3 // Default retract length (positive mm) + #define RETRACT_LENGTH_SWAP 13 // Default swap retract length (positive mm), for extruder change + #define RETRACT_FEEDRATE 45 // Default feedrate for retracting (mm/s) + #define RETRACT_ZLIFT 0 // Default retract Z-lift + #define RETRACT_RECOVER_LENGTH 0 // Default additional recover length (mm, added to retract length when recovering) + #define RETRACT_RECOVER_LENGTH_SWAP 0 // Default additional swap recover length (mm, added to retract length when recovering from extruder change) + #define RETRACT_RECOVER_FEEDRATE 8 // Default feedrate for recovering from retraction (mm/s) + #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) +#endif + +/** + * Advanced Pause + * Experimental feature for filament change support and for parking the nozzle when paused. + * Adds the GCode M600 for initiating filament change. + * If PARK_HEAD_ON_PAUSE enabled, adds the GCode M125 to pause printing and park the nozzle. + * + * Requires an LCD display. + * This feature is required for the default FILAMENT_RUNOUT_SCRIPT. + */ +//#define ADVANCED_PAUSE_FEATURE +#if ENABLED(ADVANCED_PAUSE_FEATURE) + #define PAUSE_PARK_X_POS 30 // X position of hotend + #define PAUSE_PARK_Y_POS 10 // Y position of hotend + #define PAUSE_PARK_Z_ADD 10 // Z addition of hotend (lift) + #define PAUSE_PARK_XY_FEEDRATE 100 // X and Y axes feedrate in mm/s (also used for delta printers Z axis) + #define PAUSE_PARK_Z_FEEDRATE 5 // Z axis feedrate in mm/s (not used for delta printers) + #define PAUSE_PARK_RETRACT_FEEDRATE 60 // Initial retract feedrate in mm/s + #define PAUSE_PARK_RETRACT_LENGTH 1 // Initial retract in mm + // It is a short retract used immediately after print interrupt before move to filament exchange position + #define FILAMENT_CHANGE_UNLOAD_FEEDRATE 10 // Unload filament feedrate in mm/s - filament unloading can be fast + //#define FILAMENT_CHANGE_UNLOAD_LENGTH 100 // Unload filament length from hotend in mm + // Longer length for bowden printers to unload filament from whole bowden tube, + // shorter length for printers without bowden to unload filament from extruder only, + // 0 to disable unloading for manual unloading + #define FILAMENT_CHANGE_LOAD_FEEDRATE 6 // Load filament feedrate in mm/s - filament loading into the bowden tube can be fast + #define FILAMENT_CHANGE_LOAD_LENGTH 0 // Load filament length over hotend in mm + // Longer length for bowden printers to fast load filament into whole bowden tube over the hotend, + // Short or zero length for printers without bowden where loading is not used + #define ADVANCED_PAUSE_EXTRUDE_FEEDRATE 3 // Extrude filament feedrate in mm/s - must be slower than load feedrate + #define ADVANCED_PAUSE_EXTRUDE_LENGTH 50 // Extrude filament length in mm after filament is loaded over the hotend, + // 0 to disable for manual extrusion + // Filament can be extruded repeatedly from the filament exchange menu to fill the hotend, + // or until outcoming filament color is not clear for filament color change + #define PAUSE_PARK_NOZZLE_TIMEOUT 45 // Turn off nozzle if user doesn't change filament within this time limit in seconds + #define FILAMENT_CHANGE_NUMBER_OF_ALERT_BEEPS 5 // Number of alert beeps before printer goes quiet + #define PAUSE_PARK_NO_STEPPER_TIMEOUT // Enable to have stepper motors hold position during filament change + // even if it takes longer than DEFAULT_STEPPER_DEACTIVE_TIME. + //#define PARK_HEAD_ON_PAUSE // Go to filament change position on pause, return to print position on resume + //#define HOME_BEFORE_FILAMENT_CHANGE // Ensure homing has been completed prior to parking for filament change +#endif + +// @section tmc + +/** + * Enable this section if you have TMC26X motor drivers. + * You will need to import the TMC26XStepper library into the Arduino IDE for this + * (https://github.com/trinamic/TMC26XStepper.git) + */ +//#define HAVE_TMCDRIVER + +#if ENABLED(HAVE_TMCDRIVER) + + //#define X_IS_TMC + //#define X2_IS_TMC + //#define Y_IS_TMC + //#define Y2_IS_TMC + //#define Z_IS_TMC + //#define Z2_IS_TMC + //#define E0_IS_TMC + //#define E1_IS_TMC + //#define E2_IS_TMC + //#define E3_IS_TMC + //#define E4_IS_TMC + + #define X_MAX_CURRENT 1000 // in mA + #define X_SENSE_RESISTOR 91 // in mOhms + #define X_MICROSTEPS 16 // number of microsteps + + #define X2_MAX_CURRENT 1000 + #define X2_SENSE_RESISTOR 91 + #define X2_MICROSTEPS 16 + + #define Y_MAX_CURRENT 1000 + #define Y_SENSE_RESISTOR 91 + #define Y_MICROSTEPS 16 + + #define Y2_MAX_CURRENT 1000 + #define Y2_SENSE_RESISTOR 91 + #define Y2_MICROSTEPS 16 + + #define Z_MAX_CURRENT 1000 + #define Z_SENSE_RESISTOR 91 + #define Z_MICROSTEPS 16 + + #define Z2_MAX_CURRENT 1000 + #define Z2_SENSE_RESISTOR 91 + #define Z2_MICROSTEPS 16 + + #define E0_MAX_CURRENT 1000 + #define E0_SENSE_RESISTOR 91 + #define E0_MICROSTEPS 16 + + #define E1_MAX_CURRENT 1000 + #define E1_SENSE_RESISTOR 91 + #define E1_MICROSTEPS 16 + + #define E2_MAX_CURRENT 1000 + #define E2_SENSE_RESISTOR 91 + #define E2_MICROSTEPS 16 + + #define E3_MAX_CURRENT 1000 + #define E3_SENSE_RESISTOR 91 + #define E3_MICROSTEPS 16 + + #define E4_MAX_CURRENT 1000 + #define E4_SENSE_RESISTOR 91 + #define E4_MICROSTEPS 16 + +#endif + +// @section TMC2130 + +/** + * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. + * + * You'll also need the TMC2130Stepper Arduino library + * (https://github.com/teemuatlut/TMC2130Stepper). + * + * To use TMC2130 stepper drivers in SPI mode connect your SPI2130 pins to + * the hardware SPI interface on your board and define the required CS pins + * in your `pins_MYBOARD.h` file. (e.g., RAMPS 1.4 uses AUX3 pins `X_CS_PIN 53`, `Y_CS_PIN 49`, etc.). + */ +//#define HAVE_TMC2130 + +#if ENABLED(HAVE_TMC2130) + + // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY + //#define X_IS_TMC2130 + //#define X2_IS_TMC2130 + //#define Y_IS_TMC2130 + //#define Y2_IS_TMC2130 + //#define Z_IS_TMC2130 + //#define Z2_IS_TMC2130 + //#define E0_IS_TMC2130 + //#define E1_IS_TMC2130 + //#define E2_IS_TMC2130 + //#define E3_IS_TMC2130 + //#define E4_IS_TMC2130 + + /** + * Stepper driver settings + */ + + #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 + #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current + #define INTERPOLATE 1 // Interpolate X/Y/Z_MICROSTEPS to 256 + + #define X_CURRENT 1000 // rms current in mA. Multiply by 1.41 for peak current. + #define X_MICROSTEPS 16 // 0..256 + + #define Y_CURRENT 1000 + #define Y_MICROSTEPS 16 + + #define Z_CURRENT 1000 + #define Z_MICROSTEPS 16 + + //#define X2_CURRENT 1000 + //#define X2_MICROSTEPS 16 + + //#define Y2_CURRENT 1000 + //#define Y2_MICROSTEPS 16 + + //#define Z2_CURRENT 1000 + //#define Z2_MICROSTEPS 16 + + //#define E0_CURRENT 1000 + //#define E0_MICROSTEPS 16 + + //#define E1_CURRENT 1000 + //#define E1_MICROSTEPS 16 + + //#define E2_CURRENT 1000 + //#define E2_MICROSTEPS 16 + + //#define E3_CURRENT 1000 + //#define E3_MICROSTEPS 16 + + //#define E4_CURRENT 1000 + //#define E4_MICROSTEPS 16 + + /** + * Use Trinamic's ultra quiet stepping mode. + * When disabled, Marlin will use spreadCycle stepping mode. + */ + #define STEALTHCHOP + + /** + * Let Marlin automatically control stepper current. + * This is still an experimental feature. + * Increase current every 5s by CURRENT_STEP until stepper temperature prewarn gets triggered, + * then decrease current by CURRENT_STEP until temperature prewarn is cleared. + * Adjusting starts from X/Y/Z/E_CURRENT but will not increase over AUTO_ADJUST_MAX + * 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. + * M906 S1 - Start adjusting current + * M906 S0 - Stop adjusting current + * M911 - Report stepper driver overtemperature pre-warn condition. + * M912 - Clear stepper driver overtemperature pre-warn condition flag. + */ + //#define AUTOMATIC_CURRENT_CONTROL + + #if ENABLED(AUTOMATIC_CURRENT_CONTROL) + #define CURRENT_STEP 50 // [mA] + #define AUTO_ADJUST_MAX 1300 // [mA], 1300mA_rms = 1840mA_peak + #define REPORT_CURRENT_CHANGE + #endif + + /** + * The driver will switch to spreadCycle when stepper speed is over HYBRID_THRESHOLD. + * This mode allows for faster movements at the expense of higher noise levels. + * STEALTHCHOP needs to be enabled. + * M913 X/Y/Z/E to live tune the setting + */ + //#define HYBRID_THRESHOLD + + #define X_HYBRID_THRESHOLD 100 // [mm/s] + #define X2_HYBRID_THRESHOLD 100 + #define Y_HYBRID_THRESHOLD 100 + #define Y2_HYBRID_THRESHOLD 100 + #define Z_HYBRID_THRESHOLD 4 + #define Z2_HYBRID_THRESHOLD 4 + #define E0_HYBRID_THRESHOLD 30 + #define E1_HYBRID_THRESHOLD 30 + #define E2_HYBRID_THRESHOLD 30 + #define E3_HYBRID_THRESHOLD 30 + #define E4_HYBRID_THRESHOLD 30 + + /** + * Use stallGuard2 to sense an obstacle and trigger an endstop. + * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. + * If used along with STEALTHCHOP, the movement will be louder when homing. This is normal. + * + * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. + * Higher values make the system LESS sensitive. + * Lower value make the system MORE sensitive. + * Too low values can lead to false positives, while too high values will collide the axis without triggering. + * It is advised to set X/Y_HOME_BUMP_MM to 0. + * M914 X/Y to live tune the setting + */ + //#define SENSORLESS_HOMING + + #if ENABLED(SENSORLESS_HOMING) + #define X_HOMING_SENSITIVITY 19 + #define Y_HOMING_SENSITIVITY 19 + #endif + + /** + * You can set your own advanced settings by filling in predefined functions. + * A list of available functions can be found on the library github page + * https://github.com/teemuatlut/TMC2130Stepper + * + * Example: + * #define TMC2130_ADV() { \ + * stepperX.diag0_temp_prewarn(1); \ + * stepperX.interpolate(0); \ + * } + */ + #define TMC2130_ADV() { } + +#endif // HAVE_TMC2130 + +// @section L6470 + +/** + * Enable this section if you have L6470 motor drivers. + * You need to import the L6470 library into the Arduino IDE for this. + * (https://github.com/ameyer/Arduino-L6470) + */ + +//#define HAVE_L6470DRIVER +#if ENABLED(HAVE_L6470DRIVER) + + //#define X_IS_L6470 + //#define X2_IS_L6470 + //#define Y_IS_L6470 + //#define Y2_IS_L6470 + //#define Z_IS_L6470 + //#define Z2_IS_L6470 + //#define E0_IS_L6470 + //#define E1_IS_L6470 + //#define E2_IS_L6470 + //#define E3_IS_L6470 + //#define E4_IS_L6470 + + #define X_MICROSTEPS 16 // number of microsteps + #define X_K_VAL 50 // 0 - 255, Higher values, are higher power. Be careful not to go too high + #define X_OVERCURRENT 2000 // maxc current in mA. If the current goes over this value, the driver will switch off + #define X_STALLCURRENT 1500 // current in mA where the driver will detect a stall + + #define X2_MICROSTEPS 16 + #define X2_K_VAL 50 + #define X2_OVERCURRENT 2000 + #define X2_STALLCURRENT 1500 + + #define Y_MICROSTEPS 16 + #define Y_K_VAL 50 + #define Y_OVERCURRENT 2000 + #define Y_STALLCURRENT 1500 + + #define Y2_MICROSTEPS 16 + #define Y2_K_VAL 50 + #define Y2_OVERCURRENT 2000 + #define Y2_STALLCURRENT 1500 + + #define Z_MICROSTEPS 16 + #define Z_K_VAL 50 + #define Z_OVERCURRENT 2000 + #define Z_STALLCURRENT 1500 + + #define Z2_MICROSTEPS 16 + #define Z2_K_VAL 50 + #define Z2_OVERCURRENT 2000 + #define Z2_STALLCURRENT 1500 + + #define E0_MICROSTEPS 16 + #define E0_K_VAL 50 + #define E0_OVERCURRENT 2000 + #define E0_STALLCURRENT 1500 + + #define E1_MICROSTEPS 16 + #define E1_K_VAL 50 + #define E1_OVERCURRENT 2000 + #define E1_STALLCURRENT 1500 + + #define E2_MICROSTEPS 16 + #define E2_K_VAL 50 + #define E2_OVERCURRENT 2000 + #define E2_STALLCURRENT 1500 + + #define E3_MICROSTEPS 16 + #define E3_K_VAL 50 + #define E3_OVERCURRENT 2000 + #define E3_STALLCURRENT 1500 + + #define E4_MICROSTEPS 16 + #define E4_K_VAL 50 + #define E4_OVERCURRENT 2000 + #define E4_STALLCURRENT 1500 + +#endif + +/** + * TWI/I2C BUS + * + * This feature is an EXPERIMENTAL feature so it shall not be used on production + * machines. Enabling this will allow you to send and receive I2C data from slave + * devices on the bus. + * + * ; Example #1 + * ; This macro send the string "Marlin" to the slave device with address 0x63 (99) + * ; It uses multiple M260 commands with one B arg + * M260 A99 ; Target slave address + * M260 B77 ; M + * M260 B97 ; a + * M260 B114 ; r + * M260 B108 ; l + * M260 B105 ; i + * M260 B110 ; n + * M260 S1 ; Send the current buffer + * + * ; Example #2 + * ; Request 6 bytes from slave device with address 0x63 (99) + * M261 A99 B5 + * + * ; Example #3 + * ; Example serial output of a M261 request + * echo:i2c-reply: from:99 bytes:5 data:hello + */ + +// @section i2cbus + +//#define EXPERIMENTAL_I2CBUS +#define I2C_SLAVE_ADDRESS 0 // Set a value from 8 to 127 to act as a slave + +// @section extras + +/** + * Spindle & Laser control + * + * Add the M3, M4, and M5 commands to turn the spindle/laser on and off, and + * to set spindle speed, spindle direction, and laser power. + * + * SuperPid is a router/spindle speed controller used in the CNC milling community. + * Marlin can be used to turn the spindle on and off. It can also be used to set + * the spindle speed from 5,000 to 30,000 RPM. + * + * 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. + */ +//#define SPINDLE_LASER_ENABLE +#if ENABLED(SPINDLE_LASER_ENABLE) + + #define SPINDLE_LASER_ENABLE_INVERT false // set to "true" if the on/off function is reversed + #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 // delay in milliseconds to allow the spindle/laser to come up to speed/power + #define SPINDLE_LASER_POWERDOWN_DELAY 5000 // delay in milliseconds to allow the spindle to stop + #define SPINDLE_DIR_CHANGE true // set to true if your spindle controller supports changing spindle direction + #define SPINDLE_INVERT_DIR false + #define SPINDLE_STOP_ON_DIR_CHANGE true // set to true if Marlin should stop the spindle before changing rotation direction + + /** + * The M3 & M4 commands use the following equation to convert PWM duty cycle to speed/power + * + * SPEED/POWER = PWM duty cycle * SPEED_POWER_SLOPE + SPEED_POWER_INTERCEPT + * where PWM duty cycle varies from 0 to 255 + * + * set the following for your controller (ALL MUST BE SET) + */ + + #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_SLOPE 0.3922 + //#define SPEED_POWER_INTERCEPT 0 + //#define SPEED_POWER_MIN 10 + //#define SPEED_POWER_MAX 100 // 0-100% +#endif + +/** + * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins + */ +//#define PINS_DEBUGGING + +/** + * Auto-report temperatures with M155 S + */ +#define AUTO_REPORT_TEMPERATURES + +/** + * Include capabilities in M115 output + */ +#define EXTENDED_CAPABILITIES_REPORT + +/** + * Volumetric extrusion default state + * 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. + */ +//#define VOLUMETRIC_DEFAULT_ON + +/** + * Enable this option for a leaner build of Marlin that removes all + * workspace offsets, simplifying coordinate transformations, leveling, etc. + * + * - M206 and M428 are disabled. + * - G92 will revert to its behavior from Marlin 1.0. + */ +//#define NO_WORKSPACE_OFFSETS + +/** + * 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. + * + * For clients that use a fixed-width font (like OctoPrint), leave this set to 1.0. + * Otherwise, adjust according to your client and font. + */ +#define PROPORTIONAL_FONT_RATIO 1.0 + +/** + * Spend 28 bytes of SRAM to optimize the GCode parser + */ +#define FASTER_GCODE_PARSER + +/** + * User-defined menu items that execute custom GCode + */ +//#define CUSTOM_USER_MENUS +#if ENABLED(CUSTOM_USER_MENUS) + #define USER_SCRIPT_DONE "M117 User Script Done" + #define USER_SCRIPT_AUDIBLE_FEEDBACK + //#define USER_SCRIPT_RETURN // Return to status screen after a script + + #define USER_DESC_1 "Home & UBL Info" + #define USER_GCODE_1 "G28\nG29 W" + + #define USER_DESC_2 "Preheat for PLA" + #define USER_GCODE_2 "M140 S" STRINGIFY(PREHEAT_1_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND) + + #define USER_DESC_3 "Preheat for ABS" + #define USER_GCODE_3 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND) + + #define USER_DESC_4 "Heat Bed/Home/Level" + #define USER_GCODE_4 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nG28\nG29" + + #define USER_DESC_5 "Home & Info" + #define USER_GCODE_5 "G28\nM503" +#endif + +/** + * Specify an action command to send to the host when the printer is killed. + * Will be sent in the form '//action:ACTION_ON_KILL', e.g. '//action:poweroff'. + * The host must be configured to handle the action command. + */ +//#define ACTION_ON_KILL "poweroff" + +//=========================================================================== +//====================== I2C Position Encoder Settings ====================== +//=========================================================================== + +/** + * I2C position encoders for closed loop control. + * Developed by Chris Barr at Aus3D. + * + * Wiki: http://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/ + * + * Reilabuild encoders have been modified to improve reliability. + */ + +//#define I2C_POSITION_ENCODERS +#if ENABLED(I2C_POSITION_ENCODERS) + + #define I2CPE_ENCODER_CNT 1 // The number of encoders installed; max of 5 + // encoders supported currently. + + #define I2CPE_ENC_1_ADDR I2CPE_PRESET_ADDR_X // I2C address of the encoder. 30-200. + #define I2CPE_ENC_1_AXIS X_AXIS // Axis the encoder module is installed on. _AXIS. + #define I2CPE_ENC_1_TYPE I2CPE_ENC_TYPE_LINEAR // Type of encoder: I2CPE_ENC_TYPE_LINEAR -or- + // I2CPE_ENC_TYPE_ROTARY. + #define I2CPE_ENC_1_TICKS_UNIT 2048 // 1024 for magnetic strips with 2mm poles; 2048 for + // 1mm poles. For linear encoders this is ticks / mm, + // for rotary encoders this is ticks / revolution. + //#define I2CPE_ENC_1_TICKS_REV (16 * 200) // Only needed for rotary encoders; number of stepper + // steps per full revolution (motor steps/rev * microstepping) + //#define I2CPE_ENC_1_INVERT // Invert the direction of axis travel. + #define I2CPE_ENC_1_EC_METHOD I2CPE_ECM_NONE // Type of error error correction. + #define I2CPE_ENC_1_EC_THRESH 0.10 // Threshold size for error (in mm) above which the + // printer will attempt to correct the error; errors + // smaller than this are ignored to minimize effects of + // measurement noise / latency (filter). + + #define I2CPE_ENC_2_ADDR I2CPE_PRESET_ADDR_Y // Same as above, but for encoder 2. + #define I2CPE_ENC_2_AXIS Y_AXIS + #define I2CPE_ENC_2_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_ENC_2_TICKS_UNIT 2048 + //#define I2CPE_ENC_2_TICKS_REV (16 * 200) + //#define I2CPE_ENC_2_INVERT + #define I2CPE_ENC_2_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_ENC_2_EC_THRESH 0.10 + + #define I2CPE_ENC_3_ADDR I2CPE_PRESET_ADDR_Z // Encoder 3. Add additional configuration options + #define I2CPE_ENC_3_AXIS Z_AXIS // as above, or use defaults below. + + #define I2CPE_ENC_4_ADDR I2CPE_PRESET_ADDR_E // Encoder 4. + #define I2CPE_ENC_4_AXIS E_AXIS + + #define I2CPE_ENC_5_ADDR 34 // Encoder 5. + #define I2CPE_ENC_5_AXIS E_AXIS + + // Default settings for encoders which are enabled, but without settings configured above. + #define I2CPE_DEF_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_DEF_ENC_TICKS_UNIT 2048 + #define I2CPE_DEF_TICKS_REV (16 * 200) + #define I2CPE_DEF_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_DEF_EC_THRESH 0.1 + + //#define I2CPE_ERR_THRESH_ABORT 100.0 // Threshold size for error (in mm) error on any given + // axis after which the printer will abort. Comment out to + // disable abort behaviour. + + #define I2CPE_TIME_TRUSTED 10000 // After an encoder fault, there must be no further fault + // for this amount of time (in ms) before the encoder + // is trusted again. + + /** + * Position is checked every time a new command is executed from the buffer but during long moves, + * this setting determines the minimum update time between checks. A value of 100 works well with + * error rolling average when attempting to correct only for skips and not for vibration. + */ + #define I2CPE_MIN_UPD_TIME_MS 100 // Minimum time in miliseconds between encoder checks. + + // Use a rolling average to identify persistant errors that indicate skips, as opposed to vibration and noise. + #define I2CPE_ERR_ROLLING_AVERAGE + +#endif // I2C_POSITION_ENCODERS + +/** + * MAX7219 Debug Matrix + * + * Add support for a low-cost 8x8 LED Matrix based on the Max7219 chip, which can be used as a status + * display. Requires 3 signal wires. Some useful debug options are included to demonstrate its usage. + * + * Fully assembled MAX7219 boards can be found on the internet for under $2(US). + * For example, see https://www.ebay.com/sch/i.html?_nkw=332349290049 + */ +//#define MAX7219_DEBUG +#if ENABLED(MAX7219_DEBUG) + #define MAX7219_CLK_PIN 64 // 77 on Re-ARM // Configuration of the 3 pins to control the display + #define MAX7219_DIN_PIN 57 // 78 on Re-ARM + #define MAX7219_LOAD_PIN 44 // 79 on Re-ARM + + /** + * Sample debug features + * If you add more debug displays, be careful to avoid conflicts! + */ + #define MAX7219_DEBUG_PRINTER_ALIVE // Blink corner LED of 8x8 matrix to show that the firmware is functioning + #define MAX7219_DEBUG_STEPPER_HEAD 3 // Show the stepper queue head position on this and the next LED matrix row + #define MAX7219_DEBUG_STEPPER_TAIL 5 // Show the stepper queue tail position on this and the next LED matrix row + + #define MAX7219_DEBUG_STEPPER_QUEUE 0 // Show the current stepper queue depth on this and the next LED matrix row + // If you experience stuttering, reboots, etc. this option can reveal how + // tweaks made to the configuration are affecting the printer in real-time. +#endif + +#endif // CONFIGURATION_ADV_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/Cartesio/_Bootscreen.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/Cartesio/_Bootscreen.h new file mode 100644 index 00000000..b78b6e1c --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/Cartesio/_Bootscreen.h @@ -0,0 +1,103 @@ +/** + * 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 . + * + */ + +/** + * Custom Bitmap for splashscreen + * + * You may use one of the following tools to generate the C++ bitmap array from + * a black and white image: + * + * - http://www.marlinfw.org/tools/u8glib/converter.html + * - http://www.digole.com/tools/PicturetoC_Hex_converter.php + */ +#include + +#define CUSTOM_BOOTSCREEN_TIMEOUT 2500 +#define CUSTOM_BOOTSCREEN_BMPWIDTH 63 +#define CUSTOM_BOOTSCREEN_BMPHEIGHT 64 + +const unsigned char custom_start_bmp[512] PROGMEM = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0xC0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x3F, 0xFC, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, + 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, + 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, + 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, + 0x00, 0x00, 0x00, 0x07, 0xC0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0xC0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0xC0, 0x00, 0x00, 0x00, + 0x00, 0x0F, 0x07, 0x87, 0xFF, 0xFF, 0xE0, 0x00, + 0x00, 0x1F, 0x8F, 0xC7, 0xFF, 0xFF, 0xF1, 0x00, + 0x01, 0x1F, 0x8F, 0xC7, 0xFF, 0xFF, 0xF1, 0x80, + 0x03, 0x1F, 0x8F, 0xC7, 0xFF, 0xFF, 0xF1, 0x80, + 0x07, 0x1F, 0x8F, 0xC7, 0xFF, 0xFF, 0xE1, 0xC0, + 0x07, 0x1F, 0x8F, 0xC7, 0xC0, 0x00, 0x01, 0xE0, + 0x0F, 0x1F, 0x8F, 0xC7, 0xC0, 0x00, 0x01, 0xE0, + 0x0F, 0x1F, 0x8F, 0xC7, 0xC0, 0x00, 0x01, 0xF0, + 0x1F, 0x1F, 0x8F, 0xC7, 0xC0, 0x00, 0x01, 0xF0, + 0x1F, 0x1F, 0x8F, 0xC7, 0xFF, 0xFF, 0xE1, 0xF0, + 0x3F, 0x1F, 0x8F, 0xC7, 0xFF, 0xFF, 0xF1, 0xF8, + 0x3F, 0x1F, 0x8F, 0xC7, 0xFF, 0xFF, 0xF1, 0xF8, + 0x3F, 0x1F, 0x8F, 0xC7, 0xFF, 0xFF, 0xF1, 0xF8, + 0x3F, 0x1F, 0x8F, 0xC7, 0xFF, 0xFF, 0xE1, 0xF8, + 0x7F, 0x1F, 0x8F, 0xC7, 0xC0, 0x00, 0x01, 0xFC, + 0x7F, 0x1F, 0x8F, 0xC7, 0xC0, 0x00, 0x01, 0xFC, + 0x7F, 0x1F, 0x8F, 0xC7, 0xC0, 0x00, 0x01, 0xFC, + 0x7F, 0x1F, 0x8F, 0xC7, 0xC0, 0x00, 0x01, 0xFC, + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, + 0x7F, 0x00, 0x00, 0x07, 0xC7, 0xE3, 0xF1, 0xFC, + 0x7F, 0x00, 0x00, 0x07, 0xC7, 0xE3, 0xF1, 0xFC, + 0x7F, 0x00, 0x00, 0x07, 0xC7, 0xE3, 0xF1, 0xFC, + 0x3F, 0x0F, 0xFF, 0xFF, 0xC7, 0xE3, 0xF1, 0xF8, + 0x3F, 0x1F, 0xFF, 0xFF, 0xC7, 0xE3, 0xF1, 0xF8, + 0x3F, 0x1F, 0xFF, 0xFF, 0xC7, 0xE3, 0xF1, 0xF8, + 0x3F, 0x1F, 0xFF, 0xFF, 0xC7, 0xE3, 0xF1, 0xF8, + 0x1F, 0x1F, 0xFF, 0xFF, 0xC7, 0xE3, 0xF1, 0xF0, + 0x1F, 0x0F, 0xFF, 0xFF, 0xC7, 0xE3, 0xF1, 0xF0, + 0x1F, 0x00, 0x00, 0x07, 0xC7, 0xE3, 0xF1, 0xE0, + 0x0F, 0x00, 0x00, 0x07, 0xC7, 0xE3, 0xF1, 0xE0, + 0x0F, 0x00, 0x00, 0x07, 0xC7, 0xE3, 0xF1, 0xC0, + 0x07, 0x0F, 0xFF, 0xFF, 0xC7, 0xE3, 0xF1, 0xC0, + 0x03, 0x1F, 0xFF, 0xFF, 0xC7, 0xE3, 0xF1, 0x80, + 0x03, 0x1F, 0xFF, 0xFF, 0xC7, 0xE3, 0xF1, 0x00, + 0x01, 0x1F, 0xFF, 0xFF, 0xC7, 0xE3, 0xF0, 0x00, + 0x00, 0x1F, 0xFF, 0xFF, 0xC7, 0xE3, 0xF0, 0x00, + 0x00, 0x0F, 0xFF, 0xFF, 0xC3, 0xC1, 0xE0, 0x00, + 0x00, 0x00, 0x00, 0x07, 0xC0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0xC0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0xC0, 0x00, 0x00, 0x00, + 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, + 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, + 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, + 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7F, 0xF8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/Creality/CR-10/Configuration.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/Creality/CR-10/Configuration.h new file mode 100644 index 00000000..fbab8cf8 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/Creality/CR-10/Configuration.h @@ -0,0 +1,1712 @@ +/** + * 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 . + * + */ + +/** + * Configuration.h + * + * Basic settings such as: + * + * - Type of electronics + * - Type of temperature sensor + * - Printer geometry + * - Endstop configuration + * - LCD controller + * - Extra features + * + * Advanced settings can be found in Configuration_adv.h + * + */ +#ifndef CONFIGURATION_H +#define CONFIGURATION_H +#define CONFIGURATION_H_VERSION 010100 + +//=========================================================================== +//============================= Getting Started ============================= +//=========================================================================== + +/** + * Here are some standard links for getting your machine calibrated: + * + * http://reprap.org/wiki/Calibration + * http://youtu.be/wAL9d7FgInk + * http://calculator.josefprusa.cz + * http://reprap.org/wiki/Triffid_Hunter%27s_Calibration_Guide + * http://www.thingiverse.com/thing:5573 + * https://sites.google.com/site/repraplogphase/calibration-of-your-reprap + * http://www.thingiverse.com/thing:298812 + */ + +//=========================================================================== +//============================= DELTA Printer =============================== +//=========================================================================== +// For a Delta printer start with one of the configuration files in the +// example_configurations/delta directory and customize for your machine. +// + +//=========================================================================== +//============================= SCARA Printer =============================== +//=========================================================================== +// For a SCARA printer start with the configuration files in +// example_configurations/SCARA and customize for your machine. +// + +// @section info + +// User-specified version info of this build to display in [Pronterface, etc] terminal window during +// startup. Implementation of an idea by Prof Braino to inform user that any changes made to this +// build by the user have been successfully uploaded into firmware. +#define STRING_CONFIG_H_AUTHOR "(Creality CR-10)" // Who made the changes. +#define SHOW_BOOTSCREEN +#define STRING_SPLASH_LINE1 SHORT_BUILD_VERSION // will be shown during bootup in line 1 +#define STRING_SPLASH_LINE2 WEBSITE_URL // will be shown during bootup in line 2 + +// +// *** VENDORS PLEASE READ ***************************************************** +// +// Marlin now allow you to have a vendor boot image to be displayed on machine +// start. When SHOW_CUSTOM_BOOTSCREEN is defined Marlin will first show your +// custom boot image and then the default Marlin boot image is shown. +// +// We suggest for you to take advantage of this new feature and keep the Marlin +// boot image unmodified. For an example have a look at the bq Hephestos 2 +// example configuration folder. +// +#define SHOW_CUSTOM_BOOTSCREEN +// @section machine + +/** + * Select which serial port on the board will be used for communication with the host. + * This allows the connection of wireless adapters (for instance) to non-default port pins. + * Serial port 0 is always used by the Arduino bootloader regardless of this setting. + * + * :[0, 1, 2, 3, 4, 5, 6, 7] + */ +#define SERIAL_PORT 0 + +/** + * This setting determines the communication speed of the printer. + * + * 250000 works in most cases, but you might try a lower speed if + * you commonly experience drop-outs during host printing. + * You may try up to 1000000 to speed up SD file transfer. + * + * :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000] + */ +#define BAUDRATE 115200 + +// Enable the Bluetooth serial interface on AT90USB devices +//#define BLUETOOTH + +// The following define selects which electronics board you have. +// Please choose the name from boards.h that matches your setup +#ifndef MOTHERBOARD + #define MOTHERBOARD BOARD_MELZI_CREALITY +#endif + +// Optional custom name for your RepStrap or other custom machine +// Displayed in the LCD "Ready" message +#define CUSTOM_MACHINE_NAME "CR-10" + +// Define this to set a unique identifier for this printer, (Used by some programs to differentiate between machines) +// You can use an online service to generate a random UUID. (eg http://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] +#define EXTRUDERS 1 + +// For Cyclops or any "multi-extruder" that shares a single nozzle. +//#define SINGLENOZZLE + +/** + * Průša MK2 Single Nozzle Multi-Material Multiplexer, and variants. + * + * This device allows one stepper driver on a control board to drive + * two to eight stepper motors, one at a time, in a manner suitable + * for extruders. + * + * This option only allows the multiplexer to switch on tool-change. + * Additional options to configure custom E moves are pending. + */ +//#define MK2_MULTIPLEXER +#if ENABLED(MK2_MULTIPLEXER) + // Override the default DIO selector pins here, if needed. + // Some pins files may provide defaults for these pins. + //#define E_MUX0_PIN 40 // Always Required + //#define E_MUX1_PIN 42 // Needed for 3 to 8 steppers + //#define E_MUX2_PIN 44 // Needed for 5 to 8 steppers +#endif + +// A dual extruder that uses a single stepper motor +//#define SWITCHING_EXTRUDER +#if ENABLED(SWITCHING_EXTRUDER) + #define SWITCHING_EXTRUDER_SERVO_NR 0 + #define SWITCHING_EXTRUDER_SERVO_ANGLES { 0, 90 } // Angles for E0, E1[, E2, E3] + #if EXTRUDERS > 3 + #define SWITCHING_EXTRUDER_E23_SERVO_NR 1 + #endif +#endif + +// A dual-nozzle that uses a servomotor to raise/lower one of the nozzles +//#define SWITCHING_NOZZLE +#if ENABLED(SWITCHING_NOZZLE) + #define SWITCHING_NOZZLE_SERVO_NR 0 + #define SWITCHING_NOZZLE_SERVO_ANGLES { 0, 90 } // Angles for E0, E1 + //#define HOTEND_OFFSET_Z { 0.0, 0.0 } +#endif + +/** + * Two separate X-carriages with extruders that connect to a moving part + * via a magnetic docking mechanism. Requires SOL1_PIN and SOL2_PIN. + */ +//#define PARKING_EXTRUDER +#if ENABLED(PARKING_EXTRUDER) + #define PARKING_EXTRUDER_SOLENOIDS_INVERT // If enabled, the solenoid is NOT magnetized with applied voltage + #define PARKING_EXTRUDER_SOLENOIDS_PINS_ACTIVE LOW // LOW or HIGH pin signal energizes the coil + #define PARKING_EXTRUDER_SOLENOIDS_DELAY 250 // Delay (ms) for magnetic field. No delay if 0 or not defined. + #define PARKING_EXTRUDER_PARKING_X { -78, 184 } // X positions for parking the extruders + #define PARKING_EXTRUDER_GRAB_DISTANCE 1 // mm to move beyond the parking point to grab the extruder + #define PARKING_EXTRUDER_SECURITY_RAISE 5 // Z-raise before parking + #define HOTEND_OFFSET_Z { 0.0, 1.3 } // Z-offsets of the two hotends. The first must be 0. +#endif + +/** + * "Mixing Extruder" + * - Adds a new code, M165, to set the current mix factors. + * - Extends the stepping routines to move multiple steppers in proportion to the mix. + * - Optional support for Repetier Firmware M163, M164, and virtual extruder. + * - This implementation supports only a single extruder. + * - Enable DIRECT_MIXING_IN_G1 for Pia Taubert's reference implementation + */ +//#define MIXING_EXTRUDER +#if ENABLED(MIXING_EXTRUDER) + #define MIXING_STEPPERS 2 // Number of steppers in your mixing extruder + #define MIXING_VIRTUAL_TOOLS 16 // Use the Virtual Tool method with M163 and M164 + //#define DIRECT_MIXING_IN_G1 // Allow ABCDHI mix factors in G1 movement commands +#endif + +// Offset of the extruders (uncomment if using more than one and relying on firmware to position when changing). +// The offset has to be X=0, Y=0 for the extruder 0 hotend (default extruder). +// For the other hotends it is their distance from the extruder 0 hotend. +//#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis +//#define HOTEND_OFFSET_Y {0.0, 5.00} // (in mm) for each extruder, offset of the hotend on the Y axis + +// @section machine + +/** + * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN + * + * 0 = No Power Switch + * 1 = ATX + * 2 = X-Box 360 203Watts (the blue wire connected to PS_ON and the red wire to VCC) + * + * :{ 0:'No power switch', 1:'ATX', 2:'X-Box 360' } + */ +#define POWER_SUPPLY 0 + +#if POWER_SUPPLY > 0 + // Enable this option to leave the PSU off at startup. + // Power to steppers and heaters will need to be turned on with M80. + //#define PS_DEFAULT_OFF +#endif + +// @section temperature + +//=========================================================================== +//============================= Thermal Settings ============================ +//=========================================================================== + +/** + * --NORMAL IS 4.7kohm PULLUP!-- 1kohm pullup can be used on hotend sensor, using correct resistor and table + * + * Temperature sensors available: + * + * -3 : thermocouple with MAX31855 (only for sensor 0) + * -2 : thermocouple with MAX6675 (only for sensor 0) + * -1 : thermocouple with AD595 + * 0 : not used + * 1 : 100k thermistor - best choice for EPCOS 100k (4.7k pullup) + * 2 : 200k thermistor - ATC Semitec 204GT-2 (4.7k pullup) + * 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 (Used in ParCan & J-Head) (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) + * 71 : 100k Honeywell thermistor 135-104LAF-J01 (4.7k pullup) + * 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) + * 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" + * 20 : the PT100 circuit found in the Ultimainboard V2.x + * 60 : 100k Maker's Tool Works Kapton Bed Thermistor beta=3950 + * 66 : 4.7M High Temperature thermistor from Dyze Design + * 70 : the 100K thermistor found in the bq Hephestos 2 + * 75 : 100k Generic Silicon Heat Pad with NTC 100K MGB18-104F39050L32 thermistor + * + * 1k ohm pullup tables - This is atypical, and requires changing out the 4.7k pullup for 1k. + * (but gives greater accuracy and more stable PID) + * 51 : 100k thermistor - EPCOS (1k pullup) + * 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 + * 1010 : Pt1000 with 1k pullup (non standard) + * 147 : Pt100 with 4k7 pullup + * 110 : Pt100 with 1k pullup (non standard) + * + * Use these for Testing or Development purposes. NEVER for production machine. + * 998 : Dummy Table that ALWAYS reads 25°C or the temperature defined below. + * 999 : Dummy Table that ALWAYS reads 100°C or the temperature defined below. + * + * :{ '0': "Not used", '1':"100k / 4.7k - EPCOS", '2':"200k / 4.7k - ATC Semitec 204GT-2", '3':"Mendel-parts / 4.7k", '4':"10k !! do not use for a hotend. Bad resolution at high temp. !!", '5':"100K / 4.7k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '6':"100k / 4.7k EPCOS - Not as accurate as Table 1", '7':"100k / 4.7k Honeywell 135-104LAG-J01", '8':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT", '9':"100k / 4.7k GE Sensing AL03006-58.2K-97-G1", '10':"100k / 4.7k RS 198-961", '11':"100k / 4.7k beta 3950 1%", '12':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT (calibrated for Makibox hot bed)", '13':"100k Hisens 3950 1% up to 300°C for hotend 'Simple ONE ' & hotend 'All In ONE'", '20':"PT100 (Ultimainboard V2.x)", '51':"100k / 1k - EPCOS", '52':"200k / 1k - ATC Semitec 204GT-2", '55':"100k / 1k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '60':"100k Maker's Tool Works Kapton Bed Thermistor beta=3950", '66':"Dyze Design 4.7M High Temperature thermistor", '70':"the 100K thermistor found in the bq Hephestos 2", '71':"100k / 4.7k Honeywell 135-104LAF-J01", '147':"Pt100 / 4.7k", '1047':"Pt1000 / 4.7k", '110':"Pt100 / 1k (non-standard)", '1010':"Pt1000 / 1k (non standard)", '-3':"Thermocouple + MAX31855 (only for sensor 0)", '-2':"Thermocouple + MAX6675 (only for sensor 0)", '-1':"Thermocouple + AD595",'998':"Dummy 1", '999':"Dummy 2" } + */ +#define TEMP_SENSOR_0 1 +#define TEMP_SENSOR_1 0 +#define TEMP_SENSOR_2 0 +#define TEMP_SENSOR_3 0 +#define TEMP_SENSOR_4 0 +#define TEMP_SENSOR_BED 5 + +// Dummy thermistor constant temperature readings, for use with 998 and 999 +#define DUMMY_THERMISTOR_998_VALUE 25 +#define DUMMY_THERMISTOR_999_VALUE 100 + +// 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 +#define MAX_REDUNDANT_TEMP_SENSOR_DIFF 10 + +// Extruder temperature must be close to target for this long before M109 returns success +#define TEMP_RESIDENCY_TIME 10 // (seconds) +#define TEMP_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// Bed temperature must be close to target for this long before M190 returns success +#define TEMP_BED_RESIDENCY_TIME 10 // (seconds) +#define TEMP_BED_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_BED_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// The minimal temperature defines the temperature below which the heater will not be enabled It is used +// to check that the wiring to the thermistor is not broken. +// Otherwise this would lead to the heater being powered on all the time. +#define HEATER_0_MINTEMP 5 +#define HEATER_1_MINTEMP 5 +#define HEATER_2_MINTEMP 5 +#define HEATER_3_MINTEMP 5 +#define HEATER_4_MINTEMP 5 +#define BED_MINTEMP 5 + +// When temperature exceeds max temp, your heater will be switched off. +// This feature exists to protect your hotend from overheating accidentally, but *NOT* from thermistor short/failure! +// You should use MINTEMP for thermistor short/failure protection. +#define HEATER_0_MAXTEMP 275 +#define HEATER_1_MAXTEMP 275 +#define HEATER_2_MAXTEMP 275 +#define HEATER_3_MAXTEMP 275 +#define HEATER_4_MAXTEMP 275 +#define BED_MAXTEMP 120 + +//=========================================================================== +//============================= PID Settings ================================ +//=========================================================================== +// PID Tuning Guide here: http://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 +#if ENABLED(PIDTEMP) + //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. + //#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. + #define K1 0.95 //smoothing factor within the PID + + // If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it + + // Stock CR-10 tuned for 70C + #define DEFAULT_Kp 22.57 + #define DEFAULT_Ki 1.72 + #define DEFAULT_Kd 73.96 + + // 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 + +#endif // PIDTEMP + +//=========================================================================== +//============================= PID > Bed Temperature Control =============== +//=========================================================================== +// Select PID or bang-bang with PIDTEMPBED. If bang-bang, BED_LIMIT_SWITCHING will enable hysteresis +// +// Uncomment this to enable PID on the bed. It uses the same frequency PWM as the extruder. +// If your PID_dT is the default, and correct for your hardware/configuration, that means 7.689Hz, +// which is fine for driving a square wave into a resistive load and does not significantly impact you FET heating. +// This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W heater. +// If your configuration is significantly different than this and you don't understand the issues involved, you probably +// shouldn't use bed PID until someone else verifies your hardware works. +// If this is enabled, find your own PID constants below. +#define PIDTEMPBED + +//#define BED_LIMIT_SWITCHING + +// This sets the max power delivered to the bed, and replaces the HEATER_BED_DUTY_CYCLE_DIVIDER option. +// all forms of bed control obey this (PID, bang-bang, bang-bang with hysteresis) +// setting this to anything other than 255 enables a form of PWM to the bed just like HEATER_BED_DUTY_CYCLE_DIVIDER did, +// so you shouldn't use it unless you are OK with PWM on your bed. (see the comment on enabling PIDTEMPBED) +#define MAX_BED_POWER 255 // limits duty cycle to bed; 255=full current + +#if ENABLED(PIDTEMPBED) + + //#define PID_BED_DEBUG // Sends debug data to the serial port. + + //Stock CR-10 Bed Tuned for 70C + #define DEFAULT_bedKp 426.68 + #define DEFAULT_bedKi 78.92 + #define DEFAULT_bedKd 576.71 + + //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 + +// @section extruder + +// This option prevents extrusion if the temperature is below EXTRUDE_MINTEMP. +// It also enables the M302 command to set the minimum extrusion temperature +// or to allow moving the extruder regardless of the hotend temperature. +// *** IT IS HIGHLY RECOMMENDED TO LEAVE THIS OPTION ENABLED! *** +#define PREVENT_COLD_EXTRUSION +#define EXTRUDE_MINTEMP 170 + +// This option prevents a single extrusion longer than EXTRUDE_MAXLENGTH. +// Note that for Bowden Extruders a too-small value here may prevent loading. +#define PREVENT_LENGTHY_EXTRUDE +#define EXTRUDE_MAXLENGTH 1000 + +//=========================================================================== +//======================== Thermal Runaway Protection ======================= +//=========================================================================== + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * If you get "Thermal Runaway" or "Heating failed" errors the + * details can be tuned in Configuration_adv.h + */ + +#define THERMAL_PROTECTION_HOTENDS // Enable thermal protection for all extruders +#define THERMAL_PROTECTION_BED // Enable thermal protection for the heated bed + +//=========================================================================== +//============================= Mechanical Settings ========================= +//=========================================================================== + +// @section machine + +// Uncomment one of these options to enable CoreXY, CoreXZ, or CoreYZ kinematics +// either in the usual order or reversed +//#define COREXY +//#define COREXZ +//#define COREYZ +//#define COREYX +//#define COREZX +//#define COREZY + +//=========================================================================== +//============================== Endstop Settings =========================== +//=========================================================================== + +// @section homing + +// Specify here all the endstop connectors that are connected to any endstop or probe. +// Almost all printers will be using one per axis. Probes will use one or more of the +// extra connectors. Leave undefined any used for non-endstop and non-probe purposes. +#define USE_XMIN_PLUG +#define USE_YMIN_PLUG +#define USE_ZMIN_PLUG +//#define USE_XMAX_PLUG +//#define USE_YMAX_PLUG +//#define USE_ZMAX_PLUG + +// coarse Endstop Settings +//#define ENDSTOPPULLUPS // Comment this out (using // at the start of the line) to disable the endstop pullup resistors + +#if DISABLED(ENDSTOPPULLUPS) + // fine endstop settings: Individual pullups. will be ignored if ENDSTOPPULLUPS is defined + //#define ENDSTOPPULLUP_XMAX + //#define ENDSTOPPULLUP_YMAX + //#define ENDSTOPPULLUP_ZMAX + //#define ENDSTOPPULLUP_XMIN + //#define ENDSTOPPULLUP_YMIN + //#define ENDSTOPPULLUP_ZMIN + //#define ENDSTOPPULLUP_ZMIN_PROBE +#endif + +// Mechanical endstop with COM to ground and NC to Signal uses "false" here (most common setup). +#define X_MIN_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Y_MIN_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MIN_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define X_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Y_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MIN_PROBE_ENDSTOP_INVERTING false // set to true to invert the logic of the probe. + +// Enable this feature if all enabled endstop pins are interrupt-capable. +// This will remove the need to poll the interrupt pins, saving many CPU cycles. +//#define ENDSTOP_INTERRUPTS_FEATURE + +//============================================================================= +//============================== Movement Settings ============================ +//============================================================================= +// @section motion + +/** + * Default Settings + * + * These settings can be reset by M502 + * + * Note that if EEPROM is enabled, saved values will override these. + */ + +/** + * With this option each E stepper can have its own factors for the + * following movement settings. If fewer factors are given than the + * total number of extruders, the last value applies to the rest. + */ +//#define DISTINCT_E_FACTORS + +/** + * Default Axis Steps Per Unit (steps/mm) + * Override with M92 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_AXIS_STEPS_PER_UNIT { 80, 80, 400, 95 } + +/** + * Default Max Feed Rate (mm/s) + * Override with M203 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_FEEDRATE { 500, 500, 15, 25 } + +/** + * Default Max Acceleration (change/s) change = mm/s + * (Maximum start speed for accelerated moves) + * Override with M201 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_ACCELERATION { 3000, 3000, 100, 5000 } + +/** + * Default Acceleration (change/s) change = mm/s + * Override with M204 + * + * M204 P Acceleration + * M204 R Retract Acceleration + * M204 T Travel Acceleration + */ +#define DEFAULT_ACCELERATION 500 // X, Y, Z and E acceleration for printing moves +#define DEFAULT_RETRACT_ACCELERATION 500 // E acceleration for retracts +#define DEFAULT_TRAVEL_ACCELERATION 1000 // X, Y, Z acceleration for travel (non printing) moves + +/** + * Default Jerk (mm/s) + * Override with M205 X Y Z E + * + * "Jerk" specifies the minimum speed change that requires acceleration. + * When changing speed and direction, if the difference is less than the + * value set here, it may happen instantaneously. + */ +#define DEFAULT_XJERK 20.0 +#define DEFAULT_YJERK 20.0 +#define DEFAULT_ZJERK 2.7 +#define DEFAULT_EJERK 5.0 + +//=========================================================================== +//============================= Z Probe Options ============================= +//=========================================================================== +// @section probes + +// +// See http://marlinfw.org/configuration/probes.html +// + +/** + * Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + * + * Enable this option for a probe connected to the Z Min endstop pin. + */ +#define Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + +/** + * Z_MIN_PROBE_ENDSTOP + * + * Enable this option for a probe connected to any pin except Z-Min. + * (By default Marlin assumes the Z-Max endstop pin.) + * To use a custom Z Probe pin, set Z_MIN_PROBE_PIN below. + * + * - The simplest option is to use a free endstop connector. + * - Use 5V for powered (usually inductive) sensors. + * + * - RAMPS 1.3/1.4 boards may use the 5V, GND, and Aux4->D32 pin: + * - For simple switches connect... + * - normally-closed switches to GND and D32. + * - normally-open switches to 5V and D32. + * + * WARNING: Setting the wrong pin may have unexpected and potentially + * disastrous consequences. Use with caution and do your homework. + * + */ +//#define Z_MIN_PROBE_ENDSTOP + +/** + * Probe Type + * + * Allen Key Probes, Servo Probes, Z-Sled Probes, FIX_MOUNTED_PROBE, etc. + * Activate one of these to use Auto Bed Leveling below. + */ + +/** + * The "Manual Probe" provides a means to do "Auto" Bed Leveling without a probe. + * Use G29 repeatedly, adjusting the Z height at each point with movement commands + * or (with LCD_BED_LEVELING) the LCD controller. + */ +//#define PROBE_MANUALLY + +/** + * A Fix-Mounted Probe either doesn't deploy or needs manual deployment. + * (e.g., an inductive probe or a nozzle-based probe-switch.) + */ +//#define FIX_MOUNTED_PROBE + +/** + * Z Servo Probe, such as an endstop switch on a rotating arm. + */ +//#define Z_ENDSTOP_SERVO_NR 0 // Defaults to SERVO 0 connector. +//#define Z_SERVO_ANGLES {70,0} // Z Servo Deploy and Stow angles + +/** + * The BLTouch probe uses a Hall effect sensor and emulates a servo. + */ +//#define BLTOUCH +#if ENABLED(BLTOUCH) + //#define BLTOUCH_DELAY 375 // (ms) Enable and increase if needed +#endif + +/** + * Enable one or more of the following if probing seems unreliable. + * Heaters and/or fans can be disabled during probing to minimize electrical + * noise. A delay can also be added to allow noise and vibration to settle. + * These options are most useful for the BLTouch probe, but may also improve + * readings with inductive probes and piezo sensors. + */ +//#define PROBING_HEATERS_OFF // Turn heaters off when probing +//#define PROBING_FANS_OFF // Turn fans off when probing +//#define DELAY_BEFORE_PROBING 200 // (ms) To prevent vibrations from triggering piezo sensors + +// A probe that is deployed and stowed with a solenoid pin (SOL1_PIN) +//#define SOLENOID_PROBE + +// A sled-mounted probe like those designed by Charles Bell. +//#define Z_PROBE_SLED +//#define SLED_DOCKING_OFFSET 5 // The extra distance the X axis must travel to pickup the sled. 0 should be fine but you can push it further if you'd like. + +// +// For Z_PROBE_ALLEN_KEY see the Delta example configurations. +// + +/** + * Z Probe to nozzle (X,Y) offset, relative to (0, 0). + * X and Y offsets must be integers. + * + * In the following example the X and Y offsets are both positive: + * #define X_PROBE_OFFSET_FROM_EXTRUDER 10 + * #define Y_PROBE_OFFSET_FROM_EXTRUDER 10 + * + * +-- BACK ---+ + * | | + * L | (+) P | R <-- probe (20,20) + * E | | I + * F | (-) N (+) | G <-- nozzle (10,10) + * T | | H + * | (-) | T + * | | + * O-- FRONT --+ + * (0,0) + */ +#define X_PROBE_OFFSET_FROM_EXTRUDER 10 // X offset: -left +right [of the nozzle] +#define Y_PROBE_OFFSET_FROM_EXTRUDER 10 // Y offset: -front +behind [the nozzle] +#define Z_PROBE_OFFSET_FROM_EXTRUDER 0 // Z offset: -below +above [the nozzle] + +// X and Y axis travel speed (mm/m) between probes +#define XY_PROBE_SPEED 8000 + +// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +#define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z + +// Speed for the "accurate" probe of each point +#define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) + +// Use double touch for probing +//#define PROBE_DOUBLE_TOUCH + +/** + * Z probes require clearance when deploying, stowing, and moving between + * probe points to avoid hitting the bed and other hardware. + * Servo-mounted probes require extra space for the arm to rotate. + * Inductive probes need space to keep from triggering early. + * + * Use these settings to specify the distance (mm) to raise the probe (or + * lower the bed). The values set here apply over and above any (negative) + * probe Z Offset set with Z_PROBE_OFFSET_FROM_EXTRUDER, M851, or the LCD. + * Only integer values >= 1 are valid here. + * + * Example: `M851 Z-5` with a CLEARANCE of 4 => 9mm from bed to nozzle. + * But: `M851 Z+1` with a CLEARANCE of 2 => 2mm from bed to nozzle. + */ +#define Z_CLEARANCE_DEPLOY_PROBE 10 // Z Clearance for Deploy/Stow +#define Z_CLEARANCE_BETWEEN_PROBES 10 // Z Clearance between probe points + +// For M851 give a range for adjusting the Z probe offset +#define Z_PROBE_OFFSET_RANGE_MIN -20 +#define Z_PROBE_OFFSET_RANGE_MAX 20 + +// Enable the M48 repeatability test to test probe accuracy +//#define Z_MIN_PROBE_REPEATABILITY_TEST + +// For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1 +// :{ 0:'Low', 1:'High' } +#define X_ENABLE_ON 0 +#define Y_ENABLE_ON 0 +#define Z_ENABLE_ON 0 +#define E_ENABLE_ON 0 // For all extruders + +// Disables axis stepper immediately when it's not being used. +// 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 +//#define DISABLE_REDUCED_ACCURACY_WARNING + +// @section extruder + +#define DISABLE_E false // For all extruders +#define DISABLE_INACTIVE_EXTRUDER true // Keep only the active extruder enabled. + +// @section machine + +// Invert the stepper direction. Change (or reverse the motor connector) if an axis goes the wrong way. +#define INVERT_X_DIR true +#define INVERT_Y_DIR true +#define INVERT_Z_DIR false + +// Enable this option for Toshiba stepper drivers +//#define CONFIG_STEPPERS_TOSHIBA + +// @section extruder + +// For direct drive extruder v9 set to true, for geared extruder set to false. +#define INVERT_E0_DIR true +#define INVERT_E1_DIR false +#define INVERT_E2_DIR false +#define INVERT_E3_DIR false +#define INVERT_E4_DIR false + +// @section homing + +//#define NO_MOTION_BEFORE_HOMING // Inhibit movement until all axes have been homed + +//#define Z_HOMING_HEIGHT 5 // (in mm) Minimal z height before homing (G28) for Z clearance above the bed, clamps, ... + // Be sure you have this distance over your Z_MAX_POS in case. + +// Direction of endstops when homing; 1=MAX, -1=MIN +// :[-1,1] +#define X_HOME_DIR -1 +#define Y_HOME_DIR -1 +#define Z_HOME_DIR -1 + +// @section machine + +// The size of the print bed +#define X_BED_SIZE 300 +#define Y_BED_SIZE 300 + +// Travel limits (mm) after homing, corresponding to endstop positions. +#define X_MIN_POS 0 +#define Y_MIN_POS 0 +#define Z_MIN_POS 0 +#define X_MAX_POS X_BED_SIZE + 20 +#define Y_MAX_POS Y_BED_SIZE +#define Z_MAX_POS 400 + +// If enabled, axes won't move below MIN_POS in response to movement commands. +#define MIN_SOFTWARE_ENDSTOPS +// If enabled, axes won't move above MAX_POS in response to movement commands. +#define MAX_SOFTWARE_ENDSTOPS + +/** + * Filament Runout Sensor + * A mechanical or opto endstop is used to check for the presence of filament. + * + * RAMPS-based boards use SERVO3_PIN. + * For other boards you may need to define FIL_RUNOUT_PIN. + * By default the firmware assumes HIGH = has filament, LOW = ran out + */ +//#define FILAMENT_RUNOUT_SENSOR +#if ENABLED(FILAMENT_RUNOUT_SENSOR) + #define FIL_RUNOUT_INVERTING false // set to true to invert the logic of the sensor. + #define ENDSTOPPULLUP_FIL_RUNOUT // Uncomment to use internal pullup for filament runout pins if the sensor is defined. + #define FILAMENT_RUNOUT_SCRIPT "M600" +#endif + +//=========================================================================== +//=============================== Bed Leveling ============================== +//=========================================================================== +// @section bedlevel + +/** + * Choose one of the options below to enable G29 Bed Leveling. The parameters + * and behavior of G29 will change depending on your selection. + * + * If using a Probe for Z Homing, enable Z_SAFE_HOMING also! + * + * - AUTO_BED_LEVELING_3POINT + * Probe 3 arbitrary points on the bed (that aren't collinear) + * You specify the XY coordinates of all 3 points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_LINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_BILINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a mesh, best for large or uneven beds. + * + * - AUTO_BED_LEVELING_UBL (Unified Bed Leveling) + * A comprehensive bed leveling system combining the features and benefits + * of other systems. UBL also includes integrated Mesh Generation, Mesh + * Validation and Mesh Editing systems. Currently, UBL is only checked out + * for Cartesian Printers. That said, it was primarily designed to correct + * poor quality Delta Printers. If you feel adventurous and have a Delta, + * please post an issue if something doesn't work correctly. Initially, + * you will need to set a reduced bed size so you have a rectangular area + * to test on. + * + * - MESH_BED_LEVELING + * Probe a grid manually + * The result is a mesh, suitable for large or uneven beds. (See BILINEAR.) + * For machines without a probe, Mesh Bed Leveling provides a method to perform + * leveling in steps so you can manually adjust the Z height at each grid-point. + * With an LCD controller the process is guided step-by-step. + */ +//#define AUTO_BED_LEVELING_3POINT +//#define AUTO_BED_LEVELING_LINEAR +//#define AUTO_BED_LEVELING_BILINEAR +//#define AUTO_BED_LEVELING_UBL +//#define MESH_BED_LEVELING + +/** + * Enable detailed logging of G28, G29, M48, etc. + * Turn on with the command 'M111 S32'. + * NOTE: Requires a lot of PROGMEM! + */ +//#define DEBUG_LEVELING_FEATURE + +#if ENABLED(MESH_BED_LEVELING) || ENABLED(AUTO_BED_LEVELING_BILINEAR) || ENABLED(AUTO_BED_LEVELING_UBL) + // Gradually reduce leveling correction until a set height is reached, + // at which point movement will be level to the machine's XY plane. + // The height can be set with M420 Z + #define ENABLE_LEVELING_FADE_HEIGHT +#endif + +#if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Set the number of grid points per dimension. + #define GRID_MAX_POINTS_X 3 + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + // Set the boundaries for probing (where the probe can reach). + #define LEFT_PROBE_BED_POSITION 15 + #define RIGHT_PROBE_BED_POSITION 170 + #define FRONT_PROBE_BED_POSITION 20 + #define BACK_PROBE_BED_POSITION 170 + + // The Z probe minimum outer margin (to validate G29 parameters). + #define MIN_PROBE_EDGE 10 + + // Probe along the Y axis, advancing X after each column + //#define PROBE_Y_FIRST + + #if ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Beyond the probed grid, continue the implied tilt? + // Default is to maintain the height of the nearest edge. + //#define EXTRAPOLATE_BEYOND_GRID + + // + // Experimental Subdivision of the grid by Catmull-Rom method. + // Synthesizes intermediate points to produce a more detailed mesh. + // + //#define ABL_BILINEAR_SUBDIVISION + #if ENABLED(ABL_BILINEAR_SUBDIVISION) + // Number of subdivisions between probe points + #define BILINEAR_SUBDIVISIONS 3 + #endif + + #endif + +#elif ENABLED(AUTO_BED_LEVELING_3POINT) + + // 3 arbitrary points to probe. + // A simple cross-product is used to estimate the plane of the bed. + #define ABL_PROBE_PT_1_X 15 + #define ABL_PROBE_PT_1_Y 180 + #define ABL_PROBE_PT_2_X 15 + #define ABL_PROBE_PT_2_Y 20 + #define ABL_PROBE_PT_3_X 170 + #define ABL_PROBE_PT_3_Y 20 + +#elif ENABLED(AUTO_BED_LEVELING_UBL) + + //=========================================================================== + //========================= Unified Bed Leveling ============================ + //=========================================================================== + + #define UBL_MESH_INSET 1 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 10 // Don't use more than 15 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + #define UBL_PROBE_PT_1_X 39 // Probing points for 3-Point leveling of the mesh + #define UBL_PROBE_PT_1_Y 180 + #define UBL_PROBE_PT_2_X 39 + #define UBL_PROBE_PT_2_Y 20 + #define UBL_PROBE_PT_3_X 180 + #define UBL_PROBE_PT_3_Y 20 + + //#define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation + #define UBL_MESH_EDIT_MOVES_Z // Sophisticated users prefer no movement of nozzle + +#elif ENABLED(MESH_BED_LEVELING) + + //=========================================================================== + //=================================== Mesh ================================== + //=========================================================================== + + #define MESH_INSET 10 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 3 // Don't use more than 7 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + //#define MESH_G28_REST_ORIGIN // After homing all axes ('G28' or 'G28 XYZ') rest Z at Z_MIN_POS + +#endif // BED_LEVELING + +/** + * Use the LCD controller for bed leveling + * Requires MESH_BED_LEVELING or PROBE_MANUALLY + */ +//#define LCD_BED_LEVELING + +#if ENABLED(LCD_BED_LEVELING) + #define MBL_Z_STEP 0.025 // Step size while manually probing Z axis. + #define LCD_PROBE_Z_RANGE 4 // Z Range centered on Z_MIN_POS for LCD Z adjustment +#endif + +// Add a menu item to move between bed corners for manual bed adjustment +#define LEVEL_BED_CORNERS + +/** + * Commands to execute at the end of G29 probing. + * Useful to retract or move the Z probe out of the way. + */ +//#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) +//#define BED_CENTER_AT_0_0 + +// Manually set the home position. Leave these undefined for automatic settings. +// For DELTA this is the top-center of the Cartesian print volume. +//#define MANUAL_X_HOME_POS 0 +//#define MANUAL_Y_HOME_POS 0 +//#define MANUAL_Z_HOME_POS 0 + +// Use "Z Safe Homing" to avoid homing with a Z probe outside the bed area. +// +// With this feature enabled: +// +// - 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). +// - 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 axis (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). +#endif + +// Homing speeds (mm/m) +#define HOMING_FEEDRATE_XY (50*60) +#define HOMING_FEEDRATE_Z (4*60) + +//============================================================================= +//============================= Additional Features =========================== +//============================================================================= + +// @section extras + +// +// EEPROM +// +// The microcontroller can store settings in the EEPROM, e.g. max velocity... +// M500 - stores parameters in EEPROM +// M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily). +// M502 - reverts to the default "factory settings". You still need to store them in EEPROM afterwards if you want to. +// +#define EEPROM_SETTINGS // Enable for M500 and M501 commands +//#define DISABLE_M503 // Saves ~2700 bytes of PROGMEM. Disable for release! +#define EEPROM_CHITCHAT // Give feedback on EEPROM commands. Disable to save PROGMEM. + +// +// Host Keepalive +// +// When enabled Marlin will send a busy status message to the host +// every couple of seconds when it can't accept commands. +// +#define HOST_KEEPALIVE_FEATURE // Disable this if your host doesn't like keepalive messages +#define DEFAULT_KEEPALIVE_INTERVAL 2 // Number of seconds between "busy" messages. Set with M113. +#define BUSY_WHILE_HEATING // Some hosts require "busy" messages even during heating + +// +// M100 Free Memory Watcher +// +//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose + +// +// G20/G21 Inch mode support +// +//#define INCH_MODE_SUPPORT + +// +// M149 Set temperature units support +// +//#define TEMPERATURE_UNITS_SUPPORT + +// @section temperature + +// Preheat Constants +#define PREHEAT_1_TEMP_HOTEND 190 +#define PREHEAT_1_TEMP_BED 70 +#define PREHEAT_1_FAN_SPEED 0 // Value from 0 to 255 + +#define PREHEAT_2_TEMP_HOTEND 240 +#define PREHEAT_2_TEMP_BED 110 +#define PREHEAT_2_FAN_SPEED 0 // Value from 0 to 255 + +/** + * Nozzle Park -- EXPERIMENTAL + * + * Park the nozzle at the given XYZ position on idle or G27. + * + * The "P" parameter controls the action applied to the Z axis: + * + * P0 (Default) If Z is below park Z raise the nozzle. + * P1 Raise the nozzle always to Z-park height. + * P2 Raise the nozzle by Z-park amount, limited to Z_MAX_POS. + */ +//#define NOZZLE_PARK_FEATURE + +#if ENABLED(NOZZLE_PARK_FEATURE) + // Specify a park position as { X, Y, Z } + #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 } +#endif + +/** + * Clean Nozzle Feature -- EXPERIMENTAL + * + * Adds the G12 command to perform a nozzle cleaning process. + * + * Parameters: + * P Pattern + * S Strokes / Repetitions + * T Triangles (P1 only) + * + * Patterns: + * P0 Straight line (default). This process requires a sponge type material + * at a fixed bed location. "S" specifies strokes (i.e. back-forth motions) + * between the start / end points. + * + * P1 Zig-zag pattern between (X0, Y0) and (X1, Y1), "T" specifies the + * number of zig-zag triangles to do. "S" defines the number of strokes. + * Zig-zags are done in whichever is the narrower dimension. + * For example, "G12 P1 S1 T3" will execute: + * + * -- + * | (X0, Y1) | /\ /\ /\ | (X1, Y1) + * | | / \ / \ / \ | + * A | | / \ / \ / \ | + * | | / \ / \ / \ | + * | (X0, Y0) | / \/ \/ \ | (X1, Y0) + * -- +--------------------------------+ + * |________|_________|_________| + * T1 T2 T3 + * + * P2 Circular pattern with middle at NOZZLE_CLEAN_CIRCLE_MIDDLE. + * "R" specifies the radius. "S" specifies the stroke count. + * Before starting, the nozzle moves to NOZZLE_CLEAN_START_POINT. + * + * Caveats: The ending Z should be the same as starting Z. + * Attention: EXPERIMENTAL. G-code arguments may change. + * + */ +//#define NOZZLE_CLEAN_FEATURE + +#if ENABLED(NOZZLE_CLEAN_FEATURE) + // Default number of pattern repetitions + #define NOZZLE_CLEAN_STROKES 12 + + // Default number of triangles + #define NOZZLE_CLEAN_TRIANGLES 3 + + // Specify positions as { X, Y, Z } + #define NOZZLE_CLEAN_START_POINT { 30, 30, (Z_MIN_POS + 1)} + #define NOZZLE_CLEAN_END_POINT {100, 60, (Z_MIN_POS + 1)} + + // Circular pattern radius + #define NOZZLE_CLEAN_CIRCLE_RADIUS 6.5 + // Circular pattern circle fragments number + #define NOZZLE_CLEAN_CIRCLE_FN 10 + // Middle point of circle + #define NOZZLE_CLEAN_CIRCLE_MIDDLE NOZZLE_CLEAN_START_POINT + + // Moves the nozzle to the initial position + #define NOZZLE_CLEAN_GOBACK +#endif + +/** + * Print Job Timer + * + * Automatically start and stop the print job timer on M104/M109/M190. + * + * M104 (hotend, no wait) - high temp = none, low temp = stop timer + * M109 (hotend, wait) - high temp = start timer, low temp = stop timer + * M190 (bed, wait) - high temp = start timer, low temp = none + * + * The timer can also be controlled with the following commands: + * + * M75 - Start the print job timer + * M76 - Pause the print job timer + * M77 - Stop the print job timer + */ +#define PRINTJOB_TIMER_AUTOSTART + +/** + * Print Counter + * + * Track statistical data such as: + * + * - Total print jobs + * - Total successful print jobs + * - Total failed print jobs + * - Total time printing + * + * View the current statistics with M78. + */ +//#define PRINTCOUNTER + +//============================================================================= +//============================= LCD and SD support ============================ +//============================================================================= + +// @section lcd + +/** + * LCD LANGUAGE + * + * Select the language to display on the LCD. These languages are available: + * + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, + * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * tr, uk, zh_CN, zh_TW, test + * + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + */ +#define LCD_LANGUAGE en + +/** + * LCD Character Set + * + * Note: This option is NOT applicable to Graphical Displays. + * + * All character-based LCDs provide ASCII plus one of these + * language extensions: + * + * - JAPANESE ... the most common + * - WESTERN ... with more accented characters + * - CYRILLIC ... for the Russian language + * + * To determine the language extension installed on your controller: + * + * - Compile and upload with LCD_LANGUAGE set to 'test' + * - 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 + * + * :['JAPANESE', 'WESTERN', 'CYRILLIC'] + */ +#define DISPLAY_CHARSET_HD44780 JAPANESE + +/** + * LCD TYPE + * + * Enable ULTRA_LCD for a 16x2, 16x4, 20x2, or 20x4 character-based LCD. + * Enable DOGLCD for a 128x64 (ST7565R) Full Graphical Display. + * (These options will be enabled automatically for most displays.) + * + * IMPORTANT: The U8glib library is required for Full Graphic Display! + * https://github.com/olikraus/U8glib_Arduino + */ +//#define ULTRA_LCD // Character based +//#define DOGLCD // Full graphics display + +/** + * SD CARD + * + * 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 + +/** + * SD CARD: SPI SPEED + * + * Enable one of the following items for a slower SPI transfer speed. + * This may be required to resolve "volume init" errors. + */ +//#define SPI_SPEED SPI_HALF_SPEED +//#define SPI_SPEED SPI_QUARTER_SPEED +//#define SPI_SPEED SPI_EIGHTH_SPEED + +/** + * SD CARD: ENABLE CRC + * + * Use CRC checks and retries on the SD communication. + */ +//#define SD_CHECK_AND_RETRY + +// +// ENCODER SETTINGS +// +// This option overrides the default number of encoder pulses needed to +// produce one step. Should be increased for high-resolution encoders. +// +#define ENCODER_PULSES_PER_STEP 4 + +// +// Use this option to override the number of step signals required to +// move between next/prev menu items. +// +#define ENCODER_STEPS_PER_MENU_ITEM 1 + +/** + * Encoder Direction Options + * + * Test your encoder's behavior first with both options disabled. + * + * Reversed Value Edit and Menu Nav? Enable REVERSE_ENCODER_DIRECTION. + * Reversed Menu Navigation only? Enable REVERSE_MENU_DIRECTION. + * Reversed Value Editing only? Enable BOTH options. + */ + +// +// This option reverses the encoder direction everywhere. +// +// Set this option if CLOCKWISE causes values to DECREASE +// +//#define REVERSE_ENCODER_DIRECTION + +// +// This option reverses the encoder direction for navigating LCD menus. +// +// If CLOCKWISE normally moves DOWN this makes it go UP. +// If CLOCKWISE normally moves UP this makes it go DOWN. +// +//#define REVERSE_MENU_DIRECTION + +// +// Individual Axis Homing +// +// Add individual axis homing items (Home X, Home Y, and Home Z) to the LCD menu. +// +//#define INDIVIDUAL_AXIS_HOMING_MENU + +// +// SPEAKER/BUZZER +// +// If you have a speaker that can produce tones, enable it here. +// By default Marlin assumes you have a buzzer with a fixed frequency. +// +#define SPEAKER + +// +// The duration and frequency for the UI feedback sound. +// Set these to 0 to disable audio feedback in the LCD menus. +// +// Note: Test audio output with the G-Code: +// M300 S P +// +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 +//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 + +// +// CONTROLLER TYPE: Standard +// +// Marlin supports a wide variety of controllers. +// Enable one of the following options to specify your controller. +// + +// +// ULTIMAKER Controller. +// +//#define ULTIMAKERCONTROLLER + +// +// ULTIPANEL as seen on Thingiverse. +// +//#define ULTIPANEL + +// +// PanelOne from T3P3 (via RAMPS 1.4 AUX2/AUX3) +// http://reprap.org/wiki/PanelOne +// +//#define PANEL_ONE + +// +// MaKr3d Makr-Panel with graphic controller and SD support. +// http://reprap.org/wiki/MaKr3d_MaKrPanel +// +//#define MAKRPANEL + +// +// ReprapWorld Graphical LCD +// https://reprapworld.com/?products_details&products_id/1218 +// +//#define REPRAPWORLD_GRAPHICAL_LCD + +// +// Activate one of these if you have a Panucatt Devices +// Viki 2.0 or mini Viki with Graphic LCD +// http://panucatt.com +// +//#define VIKI2 +//#define miniVIKI + +// +// Adafruit ST7565 Full Graphic Controller. +// https://github.com/eboston/Adafruit-ST7565-Full-Graphic-Controller/ +// +//#define ELB_FULL_GRAPHIC_CONTROLLER + +// +// RepRapDiscount Smart Controller. +// http://reprap.org/wiki/RepRapDiscount_Smart_Controller +// +// Note: Usually sold with a white PCB. +// +//#define REPRAP_DISCOUNT_SMART_CONTROLLER + +// +// GADGETS3D G3D LCD/SD Controller +// http://reprap.org/wiki/RAMPS_1.3/1.4_GADGETS3D_Shield_with_Panel +// +// Note: Usually sold with a blue PCB. +// +//#define G3D_PANEL + +// +// RepRapDiscount FULL GRAPHIC Smart Controller +// http://reprap.org/wiki/RepRapDiscount_Full_Graphic_Smart_Controller +// +//#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER + +// +// MakerLab Mini Panel with graphic +// controller and SD support - http://reprap.org/wiki/Mini_panel +// +//#define MINIPANEL + +// +// RepRapWorld REPRAPWORLD_KEYPAD v1.1 +// http://reprapworld.com/?products_details&products_id=202&cPath=1591_1626 +// +// REPRAPWORLD_KEYPAD_MOVE_STEP sets how much should the robot move when a key +// is pressed, a value of 10.0 means 10mm per click. +// +//#define REPRAPWORLD_KEYPAD +//#define REPRAPWORLD_KEYPAD_MOVE_STEP 1.0 + +// +// RigidBot Panel V1.0 +// http://www.inventapart.com/ +// +//#define RIGIDBOT_PANEL + +// +// BQ LCD Smart Controller shipped by +// default with the BQ Hephestos 2 and Witbox 2. +// +//#define BQ_LCD_SMART_CONTROLLER + +// +// Cartesio UI +// http://mauk.cc/webshop/cartesio-shop/electronics/user-interface +// +//#define CARTESIO_UI + +// +// ANET_10 Controller supported displays. +// +//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. + // This LCD is known to be susceptible to electrical interference + // which scrambles the display. Pressing any button clears it up. +//#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 + // A clone of the RepRapDiscount full graphics display but with + // different pins/wiring (see pins_ANET_10.h). + +// +// LCD for Melzi Card with Graphical LCD +// +//#define LCD_FOR_MELZI + +// +// CONTROLLER TYPE: I2C +// +// Note: These controllers require the installation of Arduino's LiquidCrystal_I2C +// library. For more info: https://github.com/kiyoshigawa/LiquidCrystal_I2C +// + +// +// Elefu RA Board Control Panel +// http://www.elefu.com/index.php?route=product/product&product_id=53 +// +//#define RA_CONTROL_PANEL + +// +// Sainsmart YW Robot (LCM1602) LCD Display +// +// Note: This controller requires F.Malpartida's LiquidCrystal_I2C library +// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home +// +//#define LCD_I2C_SAINSMART_YWROBOT + +// +// Generic LCM1602 LCD adapter +// +//#define LCM1602 + +// +// PANELOLU2 LCD with status LEDs, +// separate encoder and click inputs. +// +// Note: This controller requires Arduino's LiquidTWI2 library v1.2.3 or later. +// For more info: https://github.com/lincomatic/LiquidTWI2 +// +// Note: The PANELOLU2 encoder click input can either be directly connected to +// a pin (if BTN_ENC defined to != -1) or read through I2C (when BTN_ENC == -1). +// +//#define LCD_I2C_PANELOLU2 + +// +// Panucatt VIKI LCD with status LEDs, +// integrated click & L/R/U/D buttons, separate encoder inputs. +// +//#define LCD_I2C_VIKI + +// +// SSD1306 OLED full graphics generic display +// +//#define U8GLIB_SSD1306 + +// +// SAV OLEd LCD module support using either SSD1306 or SH1106 based LCD modules +// +//#define SAV_3DGLCD +#if ENABLED(SAV_3DGLCD) + //#define U8GLIB_SSD1306 + #define U8GLIB_SH1106 +#endif + +// +// CONTROLLER TYPE: Shift register panels +// +// 2 wire Non-latching LCD SR from https://goo.gl/aJJ4sH +// LCD configuration: http://reprap.org/wiki/SAV_3D_LCD +// +//#define SAV_3DLCD + +// +// TinyBoy2 128x64 OLED / Encoder Panel +// +//#define OLED_PANEL_TINYBOY2 + +// +// Makeboard 3D Printer Parts 3D Printer Mini Display 1602 Mini Controller +// https://www.aliexpress.com/item/Micromake-Makeboard-3D-Printer-Parts-3D-Printer-Mini-Display-1602-Mini-Controller-Compatible-with-Ramps-1/32765887917.html +// +//#define MAKEBOARD_MINI_2_LINE_DISPLAY_1602 + +// +// MKS MINI12864 with graphic controller and SD support +// http://reprap.org/wiki/MKS_MINI_12864 +// +//#define MKS_MINI_12864 + +// +// Factory display for Creality CR-10 +// https://www.aliexpress.com/item/Universal-LCD-12864-3D-Printer-Display-Screen-With-Encoder-For-CR-10-CR-7-Model/32833148327.html +// +// This is RAMPS-compatible using a single 10-pin connector. +// (For CR-10 owners who want to replace the Melzi Creality board but retain the display) +// +#define CR10_STOCKDISPLAY + +// +// MKS OLED 1.3" 128 × 64 FULL GRAPHICS CONTROLLER +// http://reprap.org/wiki/MKS_12864OLED +// +// Tiny, but very sharp OLED display +// +//#define MKS_12864OLED + +//============================================================================= +//=============================== Extra Features ============================== +//============================================================================= + +// @section extras + +// Increase the FAN PWM frequency. Removes the PWM noise but increases heating in the FET/Arduino +//#define FAST_PWM_FAN + +// Use software PWM to drive the fan, as for the heaters. This uses a very low frequency +// which is not as annoying as with the hardware PWM. On the other hand, if this frequency +// is too low, you should also increment SOFT_PWM_SCALE. +//#define FAN_SOFT_PWM + +// Incrementing this by 1 will double the software PWM frequency, +// affecting heaters, and the fan if FAN_SOFT_PWM is enabled. +// However, control resolution will be halved for each increment; +// at zero value, there are 128 effective control positions. +#define SOFT_PWM_SCALE 0 + +// If SOFT_PWM_SCALE is set to a value higher than 0, dithering can +// be used to mitigate the associated resolution loss. If enabled, +// some of the PWM cycles are stretched so on average the desired +// duty cycle is attained. +//#define SOFT_PWM_DITHER + +// Temperature status LEDs that display the hotend and bed temperature. +// If all hotends, bed temperature, and target temperature are under 54C +// then the BLUE led is on. Otherwise the RED led is on. (1C hysteresis) +//#define TEMP_STAT_LEDS + +// M240 Triggers a camera by emulating a Canon RC-1 Remote +// Data from: http://www.doc-diy.net/photo/rc-1_hacked/ +//#define PHOTOGRAPH_PIN 23 + +// 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 + +// Support for BlinkM/CyzRgb +//#define BLINKM + +// Support for PCA9632 PWM LED driver +//#define PCA9632 + +/** + * RGB LED / LED Strip Control + * + * Enable support for an RGB LED connected to 5V digital pins, or + * an RGB Strip connected to MOSFETs controlled by digital pins. + * + * 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 overall brightness parameters is also available + * + * *** CAUTION *** + * LED Strips require a MOFSET 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! + * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino + * cannot handle such current, separate 5V power supply must be used + * *** CAUTION *** + * + * LED type. This options are mutualy exclusive. Uncomment only one. + * + */ +//#define RGB_LED +//#define RGBW_LED + +#if ENABLED(RGB_LED) || ENABLED(RGBW_LED) + #define RGB_LED_R_PIN 34 + #define RGB_LED_G_PIN 43 + #define RGB_LED_B_PIN 35 + #define RGB_LED_W_PIN -1 +#endif + +// 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 (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) + #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip + #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time + #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + //#define NEOPIXEL_STARTUP_TEST // Cycle through colors at startup +#endif + +/** + * Printer Event LEDs + * + * During printing, the LEDs will reflect the printer status: + * + * - Gradually change from blue to violet as the heated bed gets to target temp + * - Gradually change from violet to red as the hotend gets to temperature + * - Change to white to illuminate work surface + * - Change to green once print has finished + * - Turn off after the print has finished and the user has pushed a button + */ +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) + #define PRINTER_EVENT_LEDS +#endif + +/*********************************************************************\ +* R/C SERVO support +* Sponsored by TrinityLabs, Reworked by codexmas +**********************************************************************/ + +// Number of servos +// +// If you select a configuration below, this will receive a default value and does not need to be set manually +// set it manually if you have more servos than extruders and wish to manually control some +// leaving it undefined or defining as 0 will disable the servo subsystem +// If unsure, leave commented / disabled +// +//#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command + +// Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. +// 300ms is a good value but you can try less delay. +// If the servo can't reach the requested position, increase it. +#define SERVO_DELAY { 300 } + +// Servo deactivation +// +// With this option servos are powered only during movement, then turned off to prevent jitter. +//#define DEACTIVATE_SERVOS_AFTER_MOVE + +/** + * Filament Width Sensor + * + * Measures the filament width in real-time and adjusts + * flow rate to compensate for any irregularities. + * + * Also allows the measured filament diameter to set the + * extrusion rate, so the slicer only has to specify the + * volume. + * + * Only a single extruder is supported at this time. + * + * 34 RAMPS_14 : Analog input 5 on the AUX2 connector + * 81 PRINTRBOARD : Analog input 2 on the Exp1 connector (version B,C,D,E) + * 301 RAMBO : Analog input 3 + * + * Note: May require analog pins to be defined for other boards. + */ +//#define FILAMENT_WIDTH_SENSOR + +#define DEFAULT_NOMINAL_FILAMENT_DIA 1.75 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. +#define DEFAULT_STDDEV_FILAMENT_DIA 0.05 // Typical estimate for cheap filament +//#define DEFAULT_STDDEV_FILAMENT_DIA 0.02 // Typical advertised for higher quality filament + +#if ENABLED(FILAMENT_WIDTH_SENSOR) + #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) + #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber + + #define MEASURED_UPPER_LIMIT (DEFAULT_NOMINAL_FILAMENT_DIA+4*DEFAULT_STDDEV_FILAMENT_DIA) // (mm) Upper limit used to validate sensor reading + #define MEASURED_LOWER_LIMIT (DEFAULT_NOMINAL_FILAMENT_DIA-4*DEFAULT_STDDEV_FILAMENT_DIA) // (mm) Lower limit used to validate sensor reading + #define MAX_MEASUREMENT_DELAY 20 // (bytes) Buffer size for stored measurements (1 byte per cm). Must be larger than MEASUREMENT_DELAY_CM. + + #define DEFAULT_MEASURED_FILAMENT_DIA DEFAULT_NOMINAL_FILAMENT_DIA // Set measured to nominal initially + + // Display filament width on the LCD status line. Status messages will expire after 5 seconds. + //#define FILAMENT_LCD_DISPLAY +#endif + +#endif // CONFIGURATION_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/Creality/CR-10/Configuration_adv.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/Creality/CR-10/Configuration_adv.h new file mode 100644 index 00000000..adfd6aa5 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/Creality/CR-10/Configuration_adv.h @@ -0,0 +1,1424 @@ +/** + * 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 . + * + */ + +/** + * Configuration_adv.h + * + * Advanced settings. + * Only change these if you know exactly what you're doing. + * Some of these settings can damage your printer if improperly set! + * + * Basic settings can be found in Configuration.h + * + */ +#ifndef CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H_VERSION 010100 + +// @section temperature + +//=========================================================================== +//=============================Thermal Settings ============================ +//=========================================================================== + +#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 + #endif +#endif + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * The solution: Once the temperature reaches the target, start observing. + * If the temperature stays too far below the target (hysteresis) for too long (period), + * the firmware will halt the machine as a safety precaution. + * + * If you get false positives for "Thermal Runaway" increase THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD + */ +#if ENABLED(THERMAL_PROTECTION_HOTENDS) + #define THERMAL_PROTECTION_PERIOD 40 // Seconds + #define THERMAL_PROTECTION_HYSTERESIS 4 // Degrees Celsius + + /** + * Whenever an M104 or M109 increases the target temperature the firmware will wait for the + * WATCH_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get false positives for "Heating failed" increase WATCH_TEMP_PERIOD and/or decrease WATCH_TEMP_INCREASE + * WATCH_TEMP_INCREASE should not be below 2. + */ + #define WATCH_TEMP_PERIOD 20 // Seconds + #define WATCH_TEMP_INCREASE 2 // Degrees Celsius +#endif + +/** + * Thermal Protection parameters for the bed are just as above for hotends. + */ +#if ENABLED(THERMAL_PROTECTION_BED) + #define THERMAL_PROTECTION_BED_PERIOD 20 // Seconds + #define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius + + /** + * Whenever an M140 or M190 increases the target temperature the firmware will wait for the + * WATCH_BED_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_BED_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get too many "Heating failed" errors, increase WATCH_BED_TEMP_PERIOD and/or decrease + * WATCH_BED_TEMP_INCREASE. (WATCH_BED_TEMP_INCREASE should not be below 2.) + */ + #define WATCH_BED_TEMP_PERIOD 60 // Seconds + #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius +#endif + +#if ENABLED(PIDTEMP) + // this adds an experimental additional term to the heating power, proportional to the extrusion speed. + // if Kc is chosen well, the additional required power due to increased melting should be compensated. + //#define PID_EXTRUSION_SCALING + #if ENABLED(PID_EXTRUSION_SCALING) + #define DEFAULT_Kc (100) //heating power=Kc*(e_speed) + #define LPQ_MAX_LEN 50 + #endif +#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 + */ +#define AUTOTEMP +#if ENABLED(AUTOTEMP) + #define AUTOTEMP_OLDWEIGHT 0.98 +#endif + +// Show Temperature ADC value +// Enable for M105 to include ADC values read from temperature sensors. +//#define SHOW_TEMP_ADC_VALUES + +/** + * High Temperature Thermistor Support + * + * Thermistors able to support high temperature tend to have a hard time getting + * good readings at room and lower temperatures. This means HEATER_X_RAW_LO_TEMP + * will probably be caught when the heating element first turns on during the + * preheating process, which will trigger a min_temp_error as a safety measure + * and force stop everything. + * To circumvent this limitation, we allow for a preheat time (during which, + * min_temp_error won't be triggered) and add a min_temp buffer to handle + * aberrant readings. + * + * If you want to enable this feature for your hotend thermistor(s) + * uncomment and set values > 0 in the constants below + */ + +// The number of consecutive low temperature errors that can occur +// before a min_temp_error is triggered. (Shouldn't be more than 10.) +//#define MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED 0 + +// The number of milliseconds a hotend will preheat before starting to check +// the temperature. This value should NOT be set to the time it takes the +// hot end to reach the target temperature, but the time it takes to reach +// the minimum temperature your thermistor can read. The lower the better/safer. +// This shouldn't need to be more than 30 seconds (30000) +//#define MILLISECONDS_PREHEAT_TIME 0 + +// @section extruder + +// Extruder runout prevention. +// If the machine is idle and the temperature over MINTEMP +// then extrude some filament every couple of SECONDS. +//#define EXTRUDER_RUNOUT_PREVENT +#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_EXTRUDE 5 // mm +#endif + +// @section temperature + +//These defines help to calibrate the AD595 sensor in case you get wrong temperature measurements. +//The measured temperature is defined as "actualTemp = (measuredTemp * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET" +#define TEMP_SENSOR_AD595_OFFSET 0.0 +#define TEMP_SENSOR_AD595_GAIN 1.0 + +/** + * 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. + */ +//#define USE_CONTROLLER_FAN +#if ENABLED(USE_CONTROLLER_FAN) + //#define CONTROLLER_FAN_PIN FAN1_PIN // 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 +#endif + +// When first starting the main fan, run it at full speed for the +// given number of milliseconds. This gets the fan spinning reliably +// before setting a PWM value. (Does not work with software PWM for fan on Sanguinololu) +//#define FAN_KICKSTART_TIME 100 + +// This defines the minimal speed for the main fan, run in PWM mode +// to enable uncomment and set minimal PWM speed for reliable running (1-255) +// if fan speed is [1 - (FAN_MIN_PWM-1)] it is set to FAN_MIN_PWM +//#define FAN_MIN_PWM 50 + +// @section extruder + +/** + * Extruder cooling fans + * + * Extruder auto fans automatically turn on when their extruders' + * temperatures go above EXTRUDER_AUTO_FAN_TEMPERATURE. + * + * Your board's pins file specifies the recommended pins. Override those here + * or set to -1 to disable completely. + * + * Multiple extruders can be assigned to the same pin in which case + * the fan will turn on when any selected extruder is above the threshold. + */ +#define E0_AUTO_FAN_PIN -1 +#define E1_AUTO_FAN_PIN -1 +#define E2_AUTO_FAN_PIN -1 +#define E3_AUTO_FAN_PIN -1 +#define E4_AUTO_FAN_PIN -1 +#define EXTRUDER_AUTO_FAN_TEMPERATURE 50 +#define EXTRUDER_AUTO_FAN_SPEED 255 // == full speed + +/** + * Part-Cooling Fan Multiplexer + * + * This feature allows you to digitally multiplex the fan output. + * The multiplexer is automatically switched at tool-change. + * Set FANMUX[012]_PINs below for up to 2, 4, or 8 multiplexed fans. + */ +#define FANMUX0_PIN -1 +#define FANMUX1_PIN -1 +#define FANMUX2_PIN -1 + +/** + * M355 Case Light on-off / brightness + */ +//#define CASE_LIGHT_ENABLE +#if ENABLED(CASE_LIGHT_ENABLE) + //#define CASE_LIGHT_PIN 4 // Override the default pin if needed + #define INVERT_CASE_LIGHT false // Set true if Case Light is ON when pin is LOW + #define CASE_LIGHT_DEFAULT_ON true // Set default power-up state on + #define CASE_LIGHT_DEFAULT_BRIGHTNESS 105 // Set default power-up brightness (0-255, requires PWM pin) + //#define MENU_ITEM_CASE_LIGHT // Add a Case Light option to the LCD main menu +#endif + +//=========================================================================== +//============================ Mechanical Settings ========================== +//=========================================================================== + +// @section homing + +// If you want endstops to stay on (by default) even when not homing +// enable this option. Override at any time with M120, M121. +//#define ENDSTOPS_ALWAYS_ON_DEFAULT + +// @section extras + +//#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. + +// Dual X Steppers +// Uncomment this option to drive two X axis motors. +// The next unused E driver will be assigned to the second X stepper. +//#define X_DUAL_STEPPER_DRIVERS +#if ENABLED(X_DUAL_STEPPER_DRIVERS) + // Set true if the two X motors need to rotate in opposite directions + #define INVERT_X2_VS_X_DIR true +#endif + +// Dual Y Steppers +// Uncomment this option to drive two Y axis motors. +// The next unused E driver will be assigned to the second Y stepper. +//#define Y_DUAL_STEPPER_DRIVERS +#if ENABLED(Y_DUAL_STEPPER_DRIVERS) + // Set true if the two Y motors need to rotate in opposite directions + #define INVERT_Y2_VS_Y_DIR true +#endif + +// A single Z stepper driver is usually used to drive 2 stepper motors. +// Uncomment this option to use a separate stepper driver for each Z axis motor. +// The next unused E driver will be assigned to the second Z stepper. +//#define Z_DUAL_STEPPER_DRIVERS + +#if ENABLED(Z_DUAL_STEPPER_DRIVERS) + + // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper. + // That way the machine is capable to align the bed during home, since both Z steppers are homed. + // There is also an implementation of M666 (software endstops adjustment) to this feature. + // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed. + // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2. + // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive. + // Play a little bit with small adjustments (0.5mm) and check the behaviour. + // The M119 (endstops report) will start reporting the Z2 Endstop as well. + + //#define Z_DUAL_ENDSTOPS + + #if ENABLED(Z_DUAL_ENDSTOPS) + #define Z2_USE_ENDSTOP _XMAX_ + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 // Use M666 to determine/test this value + #endif + +#endif // Z_DUAL_STEPPER_DRIVERS + +// Enable this for dual x-carriage printers. +// A dual x-carriage design has the advantage that the inactive extruder can be parked which +// prevents hot-end ooze contaminating the print. It also reduces the weight of each x-carriage +// allowing faster printing speeds. Connect your X2 stepper to the first unused E plug. +//#define DUAL_X_CARRIAGE +#if ENABLED(DUAL_X_CARRIAGE) + // Configuration for second X-carriage + // Note: the first x-carriage is defined as the x-carriage which homes to the minimum endstop; + // the second x-carriage always homes to the maximum endstop. + #define X2_MIN_POS 80 // set minimum to ensure second x-carriage doesn't hit the parked first X-carriage + #define X2_MAX_POS 353 // set maximum to the distance between toolheads when both heads are homed + #define X2_HOME_DIR 1 // the second X-carriage always homes to the maximum endstop position + #define X2_HOME_POS X2_MAX_POS // default home position is the maximum carriage position + // However: In this mode the HOTEND_OFFSET_X value for the second extruder provides a software + // override for X2_HOME_POS. This also allow recalibration of the distance between the two endstops + // without modifying the firmware (through the "M218 T1 X???" command). + // Remember: you should set the second extruder x-offset to 0 in your slicer. + + // There are a few selectable movement modes for dual x-carriages using M605 S + // Mode 0 (DXC_FULL_CONTROL_MODE): Full control. The slicer has full control over both x-carriages and can achieve optimal travel results + // as long as it supports dual x-carriages. (M605 S0) + // Mode 1 (DXC_AUTO_PARK_MODE) : Auto-park mode. The firmware will automatically park and unpark the x-carriages on tool changes so + // that additional slicer support is not required. (M605 S1) + // Mode 2 (DXC_DUPLICATION_MODE) : Duplication mode. The firmware will transparently make the second x-carriage and extruder copy all + // actions of the first x-carriage. This allows the printer to print 2 arbitrary items at + // once. (2nd extruder x offset and temp offset are set using: M605 S2 [Xnnn] [Rmmm]) + + // This is the default power-up mode which can be later using M605. + #define DEFAULT_DUAL_X_CARRIAGE_MODE DXC_FULL_CONTROL_MODE + + // Default settings in "Auto-park Mode" + #define TOOLCHANGE_PARK_ZLIFT 0.2 // the distance to raise Z axis when parking an extruder + #define TOOLCHANGE_UNPARK_ZLIFT 1 // the distance to raise Z axis when unparking an extruder + + // Default x offset in duplication mode (typically set to half print bed width) + #define DEFAULT_DUPLICATION_X_OFFSET 100 + +#endif // DUAL_X_CARRIAGE + +// 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. +//#define EXT_SOLENOID + +// @section homing + +//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +#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 this is defined, if both x and y are to be homed, a diagonal move will be performed initially. + +// When G28 is called, this option will make Y home before X +//#define HOME_Y_BEFORE_X + +// @section machine + +#define AXIS_RELATIVE_MODES {false, false, false, false} + +// Allow duplication mode with a basic dual-nozzle extruder +//#define DUAL_NOZZLE_DUPLICATION_MODE + +// By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step. +#define INVERT_X_STEP_PIN false +#define INVERT_Y_STEP_PIN false +#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. +#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_E true + +#define DEFAULT_MINIMUMFEEDRATE 0.0 // minimum feedrate +#define DEFAULT_MINTRAVELFEEDRATE 0.0 + +//#define HOME_AFTER_DEACTIVATE // Require rehoming after steppers are deactivated + +// @section lcd + +#if ENABLED(ULTIPANEL) + #define MANUAL_FEEDRATE {50*60, 50*60, 4*60, 60} // Feedrates for manual moves along X, Y, Z, E from panel + #define ULTIPANEL_FEEDMULTIPLY // Comment to disable setting feedrate multiplier via encoder +#endif + +// @section extras + +// minimum time in microseconds that a movement needs to take if the buffer is emptied. +#define DEFAULT_MINSEGMENTTIME 20000 + +// If defined the movements slow down when the look ahead buffer is only half full +#define SLOWDOWN + +// Frequency limit +// See nophead's blog for more info +// Not working O +//#define XY_FREQUENCY_LIMIT 15 + +// 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 +// if unwanted behavior is observed on a user's machine when running at very slow speeds. +#define MINIMUM_PLANNER_SPEED 0.05 // (mm/sec) + +// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU. +#define MICROSTEP_MODES {16,16,16,16,16} // [1,2,4,8,16] + +/** + * @section stepper motor current + * + * Some boards have a means of setting the stepper motor current via firmware. + * + * The power on motor currents are set by: + * PWM_MOTOR_CURRENT - used by MINIRAMBO & ULTIMAIN_2 + * known compatible chips: A4982 + * DIGIPOT_MOTOR_CURRENT - used by BQ_ZUM_MEGA_3D, RAMBO & SCOOVO_X9H + * known compatible chips: AD5206 + * DAC_MOTOR_CURRENT_DEFAULT - used by PRINTRBOARD_REVF & RIGIDBOARD_V2 + * known compatible chips: MCP4728 + * DIGIPOT_I2C_MOTOR_CURRENTS - used by 5DPRINT, AZTEEG_X3_PRO, MIGHTYBOARD_REVE + * known compatible chips: MCP4451, MCP4018 + * + * Motor currents can also be set by M907 - M910 and by the LCD. + * M907 - applies to all. + * M908 - BQ_ZUM_MEGA_3D, RAMBO, PRINTRBOARD_REVF, RIGIDBOARD_V2 & SCOOVO_X9H + * M909, M910 & LCD - only PRINTRBOARD_REVF & RIGIDBOARD_V2 + */ +//#define PWM_MOTOR_CURRENT { 1300, 1300, 1250 } // Values in milliamps +//#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 + +// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +//#define DIGIPOT_I2C +//#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster +#define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 +// Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS +#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=========================== +//=========================================================================== + +#define ENCODER_RATE_MULTIPLIER // If defined, certain menu edit operations automatically multiply the steps when the encoder is moved quickly +#define ENCODER_10X_STEPS_PER_SEC 75 // If the encoder steps per sec exceeds this value, multiply steps moved x10 to quickly advance the value +#define ENCODER_100X_STEPS_PER_SEC 160 // If the encoder steps per sec exceeds this value, multiply steps moved x100 to really quickly advance the value + +//#define CHDK 4 //Pin for triggering CHDK to take a picture see how to use it here http://captain-slow.dk/2014/03/09/3d-printing-timelapses/ +#define CHDK_DELAY 50 //How long in ms the pin should stay HIGH before going LOW again + +// @section lcd + +// Include a page of printer information in the LCD Main Menu +//#define LCD_INFO_MENU + +// Scroll a longer status message into view +#define STATUS_MESSAGE_SCROLLING + +// On the Info Screen, display XY with one decimal place when possible +//#define LCD_DECIMAL_SMALL_XY + +// The timeout (in ms) to return to the status screen from sub-menus +//#define LCD_TIMEOUT_TO_STATUS 15000 + +#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 + + #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? + #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. + + #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. + // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. + // using: + //#define MENU_ADDAUTOSTART + + /** + * Sort SD file listings in alphabetical order. + * + * With this option enabled, items on SD cards will be sorted + * by name for easier navigation. + * + * By default... + * + * - Use the slowest -but safest- method for sorting. + * - Folders are sorted to the top. + * - The sort key is statically allocated. + * - No added G-code (M34) support. + * - 40 item sorting limit. (Items after the first 40 are unsorted.) + * + * SD sorting uses static allocation (as set by SDSORT_LIMIT), allowing the + * compiler to calculate the worst-case usage and throw an error if the SRAM + * limit is exceeded. + * + * - SDSORT_USES_RAM provides faster sorting via a static directory buffer. + * - SDSORT_USES_STACK does the same, but uses a local stack-based buffer. + * - SDSORT_CACHE_NAMES will retain the sorted file listing in RAM. (Expensive!) + * - SDSORT_DYNAMIC_RAM only uses RAM when the SD menu is visible. (Use with caution!) + */ + #define SDCARD_SORT_ALPHA + + // SD Card Sorting options + #if ENABLED(SDCARD_SORT_ALPHA) + #define SDSORT_LIMIT 256 // 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_USES_RAM true // 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 true // Keep sorted items in RAM longer for speedy performance. Most expensive option. + #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #endif + + // Show a progress bar on HD44780 LCDs for SD printing + //#define LCD_PROGRESS_BAR + + #if ENABLED(LCD_PROGRESS_BAR) + // Amount of time (ms) to show the bar + #define PROGRESS_BAR_BAR_TIME 2000 + // Amount of time (ms) to show the status message + #define PROGRESS_BAR_MSG_TIME 3000 + // Amount of time (ms) to retain the status message (0=forever) + #define PROGRESS_MSG_EXPIRE 0 + // Enable this to show messages for MSG_TIME then hide them + //#define PROGRESS_MSG_ONCE + // Add a menu item to test the progress bar: + //#define LCD_PROGRESS_BAR_TEST + #endif + + // This allows hosts to request long names for files and folders with M33 + //#define LONG_FILENAME_HOST_SUPPORT + + // This option allows you to abort SD printing when any endstop is triggered. + // This feature must be enabled with "M540 S1" or from the LCD menu. + // To have any effect, endstops must be enabled during SD printing. + //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + +#endif // SDSUPPORT + +/** + * Additional options for Graphical Displays + * + * Use the optimizations here to improve printing performance, + * which can be adversely affected by graphical display drawing, + * especially when doing several short moves, and when printing + * on DELTA and SCARA machines. + * + * Some of these options may result in the display lagging behind + * controller events, as there is a trade-off between reliable + * printing performance versus fast display updates. + */ +#if ENABLED(DOGLCD) + // Enable to save many cycles by drawing a hollow frame on the Info Screen + #define XYZ_HOLLOW_FRAME + + // Enable to save many cycles by drawing a hollow frame on Menu Screens + #define MENU_HOLLOW_FRAME + + // A bigger font is available for edit items. Costs 3120 bytes of PROGMEM. + // 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. + // 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 +#endif // DOGLCD + +// @section safety + +// The hardware watchdog should reset the microcontroller disabling all outputs, +// in case the firmware gets stuck and doesn't do temperature regulation. +#define USE_WATCHDOG + +#if ENABLED(USE_WATCHDOG) + // If you have a watchdog reboot in an ArduinoMega2560 then the device will hang forever, as a watchdog reset will leave the watchdog on. + // The "WATCHDOG_RESET_MANUAL" goes around this by not using the hardware reset. + // However, THIS FEATURE IS UNSAFE!, as it will only work if interrupts are disabled. And the code could hang in an interrupt routine with interrupts disabled. + //#define WATCHDOG_RESET_MANUAL +#endif + +// @section lcd + +/** + * Babystepping enables movement of the axes by tiny increments without changing + * the current position values. This feature is used primarily to adjust the Z + * axis in the first layer of a print in real-time. + * + * Warning: Does not respect endstops! + */ +#define BABYSTEPPING +#if ENABLED(BABYSTEPPING) + //#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 10 // Babysteps are very small. Increase for faster motion. + //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping + #define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen 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_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor + //#define BABYSTEP_ZPROBE_GFX_REVERSE // Reverses the direction of the CW/CCW indicators +#endif + +// @section extruder + +/** + * Implementation of linear pressure control + * + * Assumption: advance = k * (delta velocity) + * K=0 means advance disabled. + * See Marlin documentation for calibration instructions. + */ +//#define LIN_ADVANCE + +#if ENABLED(LIN_ADVANCE) + #define LIN_ADVANCE_K 75 + + /** + * Some Slicers produce Gcode with randomly jumping extrusion widths occasionally. + * For example within a 0.4mm perimeter it may produce a single segment of 0.05mm width. + * While this is harmless for normal printing (the fluid nature of the filament will + * close this very, very tiny gap), it throws off the LIN_ADVANCE pressure adaption. + * + * For this case LIN_ADVANCE_E_D_RATIO can be used to set the extrusion:distance ratio + * to a fixed value. Note that using a fixed ratio will lead to wrong nozzle pressures + * if the slicer is using variable widths or layer heights within one print! + * + * This option sets the default E:D ratio at startup. Use `M900` to override this value. + * + * Example: `M900 W0.4 H0.2 D1.75`, where: + * - W is the extrusion width in mm + * - H is the layer height in mm + * - D is the filament diameter in mm + * + * Example: `M900 R0.0458` to set the ratio directly. + * + * Set to 0 to auto-detect the ratio based on given Gcode G1 print moves. + * + * Slic3r (including Průša Control) produces Gcode compatible with the automatic mode. + * Cura (as of this writing) may produce Gcode incompatible with the automatic mode. + */ + #define LIN_ADVANCE_E_D_RATIO 0 // The calculated ratio (or 0) according to the formula W * H / ((D / 2) ^ 2 * PI) + // Example: 0.4 * 0.2 / ((1.75 / 2) ^ 2 * PI) = 0.033260135 +#endif + +// @section leveling + +// Default mesh area is an area with an inset margin on the print area. +// Below are the macros that are used to define the borders for the mesh area, +// made available here for specialized needs, ie dual extruder setup. +#if ENABLED(MESH_BED_LEVELING) + #define MESH_MIN_X MESH_INSET + #define MESH_MAX_X (X_BED_SIZE - (MESH_INSET)) + #define MESH_MIN_Y MESH_INSET + #define MESH_MAX_Y (Y_BED_SIZE - (MESH_INSET)) +#elif ENABLED(AUTO_BED_LEVELING_UBL) + #define UBL_MESH_MIN_X UBL_MESH_INSET + #define UBL_MESH_MAX_X (X_BED_SIZE - (UBL_MESH_INSET)) + #define UBL_MESH_MIN_Y UBL_MESH_INSET + #define UBL_MESH_MAX_Y (Y_BED_SIZE - (UBL_MESH_INSET)) + + // If this is defined, the currently active mesh will be saved in the + // current slot on M500. + #define UBL_SAVE_ACTIVE_ON_M500 +#endif + +// @section extras + +// +// G2/G3 Arc Support +// +//#define ARC_SUPPORT // Disable this feature to save ~3226 bytes +#if ENABLED(ARC_SUPPORT) + #define MM_PER_ARC_SEGMENT 1 // Length of each arc segment + #define N_ARC_CORRECTION 25 // Number of intertpolated 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 +#endif + +// Support for G5 with XYZE destination and IJPQ offsets. Requires ~2666 bytes. +//#define BEZIER_CURVE_SUPPORT + +// G38.2 and G38.3 Probe Target +// Enable PROBE_DOUBLE_TOUCH if you want G38 to double touch +//#define G38_PROBE_TARGET +#if ENABLED(G38_PROBE_TARGET) + #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) +#endif + +// Moves (or segments) with fewer steps than this will be joined with the next move +#define MIN_STEPS_PER_SEGMENT 6 + +// The minimum pulse width (in µs) for stepping a stepper. +// Set this if you find stepping unreliable, or if using a very fast CPU. +#define MINIMUM_STEPPER_PULSE 0 // (µs) The smallest stepper pulse allowed + +// @section temperature + +// Control heater 0 and heater 1 in parallel. +//#define HEATERS_PARALLEL + +//=========================================================================== +//================================= Buffers ================================= +//=========================================================================== + +// @section hidden + +// 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, i.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 +#else + #define BLOCK_BUFFER_SIZE 16 // maximize block buffer +#endif + +// @section serial + +// The ASCII buffer for serial input +#define MAX_CMD_SIZE 96 +#define BUFSIZE 4 + +// Transmission to Host Buffer Size +// To save 386 bytes of PROGMEM (and TX_BUFFER_SIZE+3 bytes of RAM) set to 0. +// To buffer a simple "ok" you need 4 bytes. +// For ADVANCED_OK (M105) you need 32 bytes. +// For debug-echo: 128 bytes for the optimal speed. +// Other output doesn't need to be that speedy. +// :[0, 2, 4, 8, 16, 32, 64, 128, 256] +#define TX_BUFFER_SIZE 0 + +// Host Receive Buffer Size +// Without XON/XOFF flow control (see SERIAL_XON_XOFF below) 32 bytes should be enough. +// To use flow control, set this buffer size to at least 1024 bytes. +// :[0, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048] +//#define RX_BUFFER_SIZE 1024 + +#if RX_BUFFER_SIZE >= 1024 + // Enable to have the controller send XON/XOFF control characters to + // the host to signal the RX buffer is becoming full. + //#define SERIAL_XON_XOFF +#endif + +#if ENABLED(SDSUPPORT) + // Enable this option to collect and display the maximum + // RX queue usage after transferring a file to SD. + //#define SERIAL_STATS_MAX_RX_QUEUED + + // Enable this option to collect and display the number + // of dropped bytes after a file transfer to SD. + //#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! +//#define EMERGENCY_PARSER + +// Bad Serial-connections can miss a received command by sending an 'ok' +// Therefore some clients abort after 30 seconds in a timeout. +// Some other clients start sending commands while receiving a 'wait'. +// This "wait" is only sent when the buffer is empty. 1 second is a good value here. +//#define NO_TIMEOUTS 1000 // Milliseconds + +// Some clients will have this feature soon. This could make the NO_TIMEOUTS unnecessary. +//#define ADVANCED_OK + +// @section extras + +/** + * Firmware-based and LCD-controlled retract + * + * Add G10 / G11 commands for automatic firmware-based retract / recover. + * Use M207 and M208 to define parameters for retract / recover. + * + * Use M209 to enable or disable auto-retract. + * With auto-retract enabled, all G1 E moves within the set range + * will be converted to firmware-based retract/recover moves. + * + * Be sure to turn off auto-retract during filament change. + * + * Note that M207 / M208 / M209 settings are saved to EEPROM. + * + */ +//#define FWRETRACT // ONLY PARTIALLY TESTED +#if ENABLED(FWRETRACT) + #define MIN_AUTORETRACT 0.1 // When auto-retract is on, convert E moves of this length and over + #define MAX_AUTORETRACT 10.0 // Upper limit for auto-retract conversion + #define RETRACT_LENGTH 3 // Default retract length (positive mm) + #define RETRACT_LENGTH_SWAP 13 // Default swap retract length (positive mm), for extruder change + #define RETRACT_FEEDRATE 45 // Default feedrate for retracting (mm/s) + #define RETRACT_ZLIFT 0 // Default retract Z-lift + #define RETRACT_RECOVER_LENGTH 0 // Default additional recover length (mm, added to retract length when recovering) + #define RETRACT_RECOVER_LENGTH_SWAP 0 // Default additional swap recover length (mm, added to retract length when recovering from extruder change) + #define RETRACT_RECOVER_FEEDRATE 8 // Default feedrate for recovering from retraction (mm/s) + #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) +#endif + +/** + * Advanced Pause + * Experimental feature for filament change support and for parking the nozzle when paused. + * Adds the GCode M600 for initiating filament change. + * If PARK_HEAD_ON_PAUSE enabled, adds the GCode M125 to pause printing and park the nozzle. + * + * Requires an LCD display. + * This feature is required for the default FILAMENT_RUNOUT_SCRIPT. + */ +#define ADVANCED_PAUSE_FEATURE +#if ENABLED(ADVANCED_PAUSE_FEATURE) + #define PAUSE_PARK_X_POS 3 // X position of hotend + #define PAUSE_PARK_Y_POS 297 // Y position of hotend + #define PAUSE_PARK_Z_ADD 5 // Z addition of hotend (lift) + #define PAUSE_PARK_XY_FEEDRATE 100 // X and Y axes feedrate in mm/s (also used for delta printers Z axis) + #define PAUSE_PARK_Z_FEEDRATE 5 // Z axis feedrate in mm/s (not used for delta printers) + #define PAUSE_PARK_RETRACT_FEEDRATE 60 // Initial retract feedrate in mm/s + #define PAUSE_PARK_RETRACT_LENGTH 4 // Initial retract in mm + // It is a short retract used immediately after print interrupt before move to filament exchange position + #define FILAMENT_CHANGE_UNLOAD_FEEDRATE 10 // Unload filament feedrate in mm/s - filament unloading can be fast + #define FILAMENT_CHANGE_UNLOAD_LENGTH 420 // Unload filament length from hotend in mm + // Longer length for bowden printers to unload filament from whole bowden tube, + // shorter length for printers without bowden to unload filament from extruder only, + // 0 to disable unloading for manual unloading + #define FILAMENT_CHANGE_LOAD_FEEDRATE 8 // Load filament feedrate in mm/s - filament loading into the bowden tube can be fast + #define FILAMENT_CHANGE_LOAD_LENGTH 0 // Load filament length over hotend in mm + // Longer length for bowden printers to fast load filament into whole bowden tube over the hotend, + // Short or zero length for printers without bowden where loading is not used + #define ADVANCED_PAUSE_EXTRUDE_FEEDRATE 3 // Extrude filament feedrate in mm/s - must be slower than load feedrate + #define ADVANCED_PAUSE_EXTRUDE_LENGTH 50 // Extrude filament length in mm after filament is loaded over the hotend, + // 0 to disable for manual extrusion + // Filament can be extruded repeatedly from the filament exchange menu to fill the hotend, + // or until outcoming filament color is not clear for filament color change + #define PAUSE_PARK_NOZZLE_TIMEOUT 120 // Turn off nozzle if user doesn't change filament within this time limit in seconds + #define FILAMENT_CHANGE_NUMBER_OF_ALERT_BEEPS 3 // Number of alert beeps before printer goes quiet + #define PAUSE_PARK_NO_STEPPER_TIMEOUT // Enable to have stepper motors hold position during filament change + // even if it takes longer than DEFAULT_STEPPER_DEACTIVE_TIME. + #define PARK_HEAD_ON_PAUSE // Go to filament change position on pause, return to print position on resume + #define HOME_BEFORE_FILAMENT_CHANGE // Ensure homing has been completed prior to parking for filament change +#endif + +// @section tmc + +/** + * Enable this section if you have TMC26X motor drivers. + * You will need to import the TMC26XStepper library into the Arduino IDE for this + * (https://github.com/trinamic/TMC26XStepper.git) + */ +//#define HAVE_TMCDRIVER + +#if ENABLED(HAVE_TMCDRIVER) + + //#define X_IS_TMC + //#define X2_IS_TMC + //#define Y_IS_TMC + //#define Y2_IS_TMC + //#define Z_IS_TMC + //#define Z2_IS_TMC + //#define E0_IS_TMC + //#define E1_IS_TMC + //#define E2_IS_TMC + //#define E3_IS_TMC + //#define E4_IS_TMC + + #define X_MAX_CURRENT 1000 // in mA + #define X_SENSE_RESISTOR 91 // in mOhms + #define X_MICROSTEPS 16 // number of microsteps + + #define X2_MAX_CURRENT 1000 + #define X2_SENSE_RESISTOR 91 + #define X2_MICROSTEPS 16 + + #define Y_MAX_CURRENT 1000 + #define Y_SENSE_RESISTOR 91 + #define Y_MICROSTEPS 16 + + #define Y2_MAX_CURRENT 1000 + #define Y2_SENSE_RESISTOR 91 + #define Y2_MICROSTEPS 16 + + #define Z_MAX_CURRENT 1000 + #define Z_SENSE_RESISTOR 91 + #define Z_MICROSTEPS 16 + + #define Z2_MAX_CURRENT 1000 + #define Z2_SENSE_RESISTOR 91 + #define Z2_MICROSTEPS 16 + + #define E0_MAX_CURRENT 1000 + #define E0_SENSE_RESISTOR 91 + #define E0_MICROSTEPS 16 + + #define E1_MAX_CURRENT 1000 + #define E1_SENSE_RESISTOR 91 + #define E1_MICROSTEPS 16 + + #define E2_MAX_CURRENT 1000 + #define E2_SENSE_RESISTOR 91 + #define E2_MICROSTEPS 16 + + #define E3_MAX_CURRENT 1000 + #define E3_SENSE_RESISTOR 91 + #define E3_MICROSTEPS 16 + + #define E4_MAX_CURRENT 1000 + #define E4_SENSE_RESISTOR 91 + #define E4_MICROSTEPS 16 + +#endif + +// @section TMC2130 + +/** + * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. + * + * You'll also need the TMC2130Stepper Arduino library + * (https://github.com/teemuatlut/TMC2130Stepper). + * + * To use TMC2130 stepper drivers in SPI mode connect your SPI2130 pins to + * the hardware SPI interface on your board and define the required CS pins + * in your `pins_MYBOARD.h` file. (e.g., RAMPS 1.4 uses AUX3 pins `X_CS_PIN 53`, `Y_CS_PIN 49`, etc.). + */ +//#define HAVE_TMC2130 + +#if ENABLED(HAVE_TMC2130) + + // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY + //#define X_IS_TMC2130 + //#define X2_IS_TMC2130 + //#define Y_IS_TMC2130 + //#define Y2_IS_TMC2130 + //#define Z_IS_TMC2130 + //#define Z2_IS_TMC2130 + //#define E0_IS_TMC2130 + //#define E1_IS_TMC2130 + //#define E2_IS_TMC2130 + //#define E3_IS_TMC2130 + //#define E4_IS_TMC2130 + + /** + * Stepper driver settings + */ + + #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 + #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current + #define INTERPOLATE 1 // Interpolate X/Y/Z_MICROSTEPS to 256 + + #define X_CURRENT 1000 // rms current in mA. Multiply by 1.41 for peak current. + #define X_MICROSTEPS 16 // 0..256 + + #define Y_CURRENT 1000 + #define Y_MICROSTEPS 16 + + #define Z_CURRENT 1000 + #define Z_MICROSTEPS 16 + + //#define X2_CURRENT 1000 + //#define X2_MICROSTEPS 16 + + //#define Y2_CURRENT 1000 + //#define Y2_MICROSTEPS 16 + + //#define Z2_CURRENT 1000 + //#define Z2_MICROSTEPS 16 + + //#define E0_CURRENT 1000 + //#define E0_MICROSTEPS 16 + + //#define E1_CURRENT 1000 + //#define E1_MICROSTEPS 16 + + //#define E2_CURRENT 1000 + //#define E2_MICROSTEPS 16 + + //#define E3_CURRENT 1000 + //#define E3_MICROSTEPS 16 + + //#define E4_CURRENT 1000 + //#define E4_MICROSTEPS 16 + + /** + * Use Trinamic's ultra quiet stepping mode. + * When disabled, Marlin will use spreadCycle stepping mode. + */ + #define STEALTHCHOP + + /** + * Let Marlin automatically control stepper current. + * This is still an experimental feature. + * Increase current every 5s by CURRENT_STEP until stepper temperature prewarn gets triggered, + * then decrease current by CURRENT_STEP until temperature prewarn is cleared. + * Adjusting starts from X/Y/Z/E_CURRENT but will not increase over AUTO_ADJUST_MAX + * 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. + * M906 S1 - Start adjusting current + * M906 S0 - Stop adjusting current + * M911 - Report stepper driver overtemperature pre-warn condition. + * M912 - Clear stepper driver overtemperature pre-warn condition flag. + */ + //#define AUTOMATIC_CURRENT_CONTROL + + #if ENABLED(AUTOMATIC_CURRENT_CONTROL) + #define CURRENT_STEP 50 // [mA] + #define AUTO_ADJUST_MAX 1300 // [mA], 1300mA_rms = 1840mA_peak + #define REPORT_CURRENT_CHANGE + #endif + + /** + * The driver will switch to spreadCycle when stepper speed is over HYBRID_THRESHOLD. + * This mode allows for faster movements at the expense of higher noise levels. + * STEALTHCHOP needs to be enabled. + * M913 X/Y/Z/E to live tune the setting + */ + //#define HYBRID_THRESHOLD + + #define X_HYBRID_THRESHOLD 100 // [mm/s] + #define X2_HYBRID_THRESHOLD 100 + #define Y_HYBRID_THRESHOLD 100 + #define Y2_HYBRID_THRESHOLD 100 + #define Z_HYBRID_THRESHOLD 4 + #define Z2_HYBRID_THRESHOLD 4 + #define E0_HYBRID_THRESHOLD 30 + #define E1_HYBRID_THRESHOLD 30 + #define E2_HYBRID_THRESHOLD 30 + #define E3_HYBRID_THRESHOLD 30 + #define E4_HYBRID_THRESHOLD 30 + + /** + * Use stallGuard2 to sense an obstacle and trigger an endstop. + * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. + * If used along with STEALTHCHOP, the movement will be louder when homing. This is normal. + * + * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. + * Higher values make the system LESS sensitive. + * Lower value make the system MORE sensitive. + * Too low values can lead to false positives, while too high values will collide the axis without triggering. + * It is advised to set X/Y_HOME_BUMP_MM to 0. + * M914 X/Y to live tune the setting + */ + //#define SENSORLESS_HOMING + + #if ENABLED(SENSORLESS_HOMING) + #define X_HOMING_SENSITIVITY 19 + #define Y_HOMING_SENSITIVITY 19 + #endif + + /** + * You can set your own advanced settings by filling in predefined functions. + * A list of available functions can be found on the library github page + * https://github.com/teemuatlut/TMC2130Stepper + * + * Example: + * #define TMC2130_ADV() { \ + * stepperX.diag0_temp_prewarn(1); \ + * stepperX.interpolate(0); \ + * } + */ + #define TMC2130_ADV() { } + +#endif // HAVE_TMC2130 + +// @section L6470 + +/** + * Enable this section if you have L6470 motor drivers. + * You need to import the L6470 library into the Arduino IDE for this. + * (https://github.com/ameyer/Arduino-L6470) + */ + +//#define HAVE_L6470DRIVER +#if ENABLED(HAVE_L6470DRIVER) + + //#define X_IS_L6470 + //#define X2_IS_L6470 + //#define Y_IS_L6470 + //#define Y2_IS_L6470 + //#define Z_IS_L6470 + //#define Z2_IS_L6470 + //#define E0_IS_L6470 + //#define E1_IS_L6470 + //#define E2_IS_L6470 + //#define E3_IS_L6470 + //#define E4_IS_L6470 + + #define X_MICROSTEPS 16 // number of microsteps + #define X_K_VAL 50 // 0 - 255, Higher values, are higher power. Be careful not to go too high + #define X_OVERCURRENT 2000 // maxc current in mA. If the current goes over this value, the driver will switch off + #define X_STALLCURRENT 1500 // current in mA where the driver will detect a stall + + #define X2_MICROSTEPS 16 + #define X2_K_VAL 50 + #define X2_OVERCURRENT 2000 + #define X2_STALLCURRENT 1500 + + #define Y_MICROSTEPS 16 + #define Y_K_VAL 50 + #define Y_OVERCURRENT 2000 + #define Y_STALLCURRENT 1500 + + #define Y2_MICROSTEPS 16 + #define Y2_K_VAL 50 + #define Y2_OVERCURRENT 2000 + #define Y2_STALLCURRENT 1500 + + #define Z_MICROSTEPS 16 + #define Z_K_VAL 50 + #define Z_OVERCURRENT 2000 + #define Z_STALLCURRENT 1500 + + #define Z2_MICROSTEPS 16 + #define Z2_K_VAL 50 + #define Z2_OVERCURRENT 2000 + #define Z2_STALLCURRENT 1500 + + #define E0_MICROSTEPS 16 + #define E0_K_VAL 50 + #define E0_OVERCURRENT 2000 + #define E0_STALLCURRENT 1500 + + #define E1_MICROSTEPS 16 + #define E1_K_VAL 50 + #define E1_OVERCURRENT 2000 + #define E1_STALLCURRENT 1500 + + #define E2_MICROSTEPS 16 + #define E2_K_VAL 50 + #define E2_OVERCURRENT 2000 + #define E2_STALLCURRENT 1500 + + #define E3_MICROSTEPS 16 + #define E3_K_VAL 50 + #define E3_OVERCURRENT 2000 + #define E3_STALLCURRENT 1500 + + #define E4_MICROSTEPS 16 + #define E4_K_VAL 50 + #define E4_OVERCURRENT 2000 + #define E4_STALLCURRENT 1500 + +#endif + +/** + * TWI/I2C BUS + * + * This feature is an EXPERIMENTAL feature so it shall not be used on production + * machines. Enabling this will allow you to send and receive I2C data from slave + * devices on the bus. + * + * ; Example #1 + * ; This macro send the string "Marlin" to the slave device with address 0x63 (99) + * ; It uses multiple M260 commands with one B arg + * M260 A99 ; Target slave address + * M260 B77 ; M + * M260 B97 ; a + * M260 B114 ; r + * M260 B108 ; l + * M260 B105 ; i + * M260 B110 ; n + * M260 S1 ; Send the current buffer + * + * ; Example #2 + * ; Request 6 bytes from slave device with address 0x63 (99) + * M261 A99 B5 + * + * ; Example #3 + * ; Example serial output of a M261 request + * echo:i2c-reply: from:99 bytes:5 data:hello + */ + +// @section i2cbus + +//#define EXPERIMENTAL_I2CBUS +#define I2C_SLAVE_ADDRESS 0 // Set a value from 8 to 127 to act as a slave + +// @section extras + +/** + * Spindle & Laser control + * + * Add the M3, M4, and M5 commands to turn the spindle/laser on and off, and + * to set spindle speed, spindle direction, and laser power. + * + * SuperPid is a router/spindle speed controller used in the CNC milling community. + * Marlin can be used to turn the spindle on and off. It can also be used to set + * the spindle speed from 5,000 to 30,000 RPM. + * + * 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. + */ +//#define SPINDLE_LASER_ENABLE +#if ENABLED(SPINDLE_LASER_ENABLE) + + #define SPINDLE_LASER_ENABLE_INVERT false // set to "true" if the on/off function is reversed + #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 // delay in milliseconds to allow the spindle/laser to come up to speed/power + #define SPINDLE_LASER_POWERDOWN_DELAY 5000 // delay in milliseconds to allow the spindle to stop + #define SPINDLE_DIR_CHANGE true // set to true if your spindle controller supports changing spindle direction + #define SPINDLE_INVERT_DIR false + #define SPINDLE_STOP_ON_DIR_CHANGE true // set to true if Marlin should stop the spindle before changing rotation direction + + /** + * The M3 & M4 commands use the following equation to convert PWM duty cycle to speed/power + * + * SPEED/POWER = PWM duty cycle * SPEED_POWER_SLOPE + SPEED_POWER_INTERCEPT + * where PWM duty cycle varies from 0 to 255 + * + * set the following for your controller (ALL MUST BE SET) + */ + + #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_SLOPE 0.3922 + //#define SPEED_POWER_INTERCEPT 0 + //#define SPEED_POWER_MIN 10 + //#define SPEED_POWER_MAX 100 // 0-100% +#endif + +/** + * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins + */ +//#define PINS_DEBUGGING + +/** + * Auto-report temperatures with M155 S + */ +#define AUTO_REPORT_TEMPERATURES + +/** + * Include capabilities in M115 output + */ +#define EXTENDED_CAPABILITIES_REPORT + +/** + * Volumetric extrusion default state + * 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. + */ +//#define VOLUMETRIC_DEFAULT_ON + +/** + * Enable this option for a leaner build of Marlin that removes all + * workspace offsets, simplifying coordinate transformations, leveling, etc. + * + * - M206 and M428 are disabled. + * - G92 will revert to its behavior from Marlin 1.0. + */ +#define NO_WORKSPACE_OFFSETS + +/** + * 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. + * + * For clients that use a fixed-width font (like OctoPrint), leave this set to 1.0. + * Otherwise, adjust according to your client and font. + */ +#define PROPORTIONAL_FONT_RATIO 1.0 + +/** + * Spend 28 bytes of SRAM to optimize the GCode parser + */ +#define FASTER_GCODE_PARSER + +/** + * User-defined menu items that execute custom GCode + */ +//#define CUSTOM_USER_MENUS +#if ENABLED(CUSTOM_USER_MENUS) + #define USER_SCRIPT_DONE "M117 User Script Done" + #define USER_SCRIPT_AUDIBLE_FEEDBACK + //#define USER_SCRIPT_RETURN // Return to status screen after a script + + #define USER_DESC_1 "Home & UBL Info" + #define USER_GCODE_1 "G28\nG29 W" + + #define USER_DESC_2 "Preheat for PLA" + #define USER_GCODE_2 "M140 S" STRINGIFY(PREHEAT_1_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND) + + #define USER_DESC_3 "Preheat for ABS" + #define USER_GCODE_3 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND) + + #define USER_DESC_4 "Heat Bed/Home/Level" + #define USER_GCODE_4 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nG28\nG29" + + #define USER_DESC_5 "Home & Info" + #define USER_GCODE_5 "G28\nM503" +#endif + +/** + * Specify an action command to send to the host when the printer is killed. + * Will be sent in the form '//action:ACTION_ON_KILL', e.g. '//action:poweroff'. + * The host must be configured to handle the action command. + */ +//#define ACTION_ON_KILL "poweroff" + +//=========================================================================== +//====================== I2C Position Encoder Settings ====================== +//=========================================================================== + +/** + * I2C position encoders for closed loop control. + * Developed by Chris Barr at Aus3D. + * + * Wiki: http://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/ + * + * Reilabuild encoders have been modified to improve reliability. + */ + +//#define I2C_POSITION_ENCODERS +#if ENABLED(I2C_POSITION_ENCODERS) + + #define I2CPE_ENCODER_CNT 1 // The number of encoders installed; max of 5 + // encoders supported currently. + + #define I2CPE_ENC_1_ADDR I2CPE_PRESET_ADDR_X // I2C address of the encoder. 30-200. + #define I2CPE_ENC_1_AXIS X_AXIS // Axis the encoder module is installed on. _AXIS. + #define I2CPE_ENC_1_TYPE I2CPE_ENC_TYPE_LINEAR // Type of encoder: I2CPE_ENC_TYPE_LINEAR -or- + // I2CPE_ENC_TYPE_ROTARY. + #define I2CPE_ENC_1_TICKS_UNIT 2048 // 1024 for magnetic strips with 2mm poles; 2048 for + // 1mm poles. For linear encoders this is ticks / mm, + // for rotary encoders this is ticks / revolution. + //#define I2CPE_ENC_1_TICKS_REV (16 * 200) // Only needed for rotary encoders; number of stepper + // steps per full revolution (motor steps/rev * microstepping) + //#define I2CPE_ENC_1_INVERT // Invert the direction of axis travel. + #define I2CPE_ENC_1_EC_METHOD I2CPE_ECM_NONE // Type of error error correction. + #define I2CPE_ENC_1_EC_THRESH 0.10 // Threshold size for error (in mm) above which the + // printer will attempt to correct the error; errors + // smaller than this are ignored to minimize effects of + // measurement noise / latency (filter). + + #define I2CPE_ENC_2_ADDR I2CPE_PRESET_ADDR_Y // Same as above, but for encoder 2. + #define I2CPE_ENC_2_AXIS Y_AXIS + #define I2CPE_ENC_2_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_ENC_2_TICKS_UNIT 2048 + //#define I2CPE_ENC_2_TICKS_REV (16 * 200) + //#define I2CPE_ENC_2_INVERT + #define I2CPE_ENC_2_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_ENC_2_EC_THRESH 0.10 + + #define I2CPE_ENC_3_ADDR I2CPE_PRESET_ADDR_Z // Encoder 3. Add additional configuration options + #define I2CPE_ENC_3_AXIS Z_AXIS // as above, or use defaults below. + + #define I2CPE_ENC_4_ADDR I2CPE_PRESET_ADDR_E // Encoder 4. + #define I2CPE_ENC_4_AXIS E_AXIS + + #define I2CPE_ENC_5_ADDR 34 // Encoder 5. + #define I2CPE_ENC_5_AXIS E_AXIS + + // Default settings for encoders which are enabled, but without settings configured above. + #define I2CPE_DEF_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_DEF_ENC_TICKS_UNIT 2048 + #define I2CPE_DEF_TICKS_REV (16 * 200) + #define I2CPE_DEF_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_DEF_EC_THRESH 0.1 + + //#define I2CPE_ERR_THRESH_ABORT 100.0 // Threshold size for error (in mm) error on any given + // axis after which the printer will abort. Comment out to + // disable abort behaviour. + + #define I2CPE_TIME_TRUSTED 10000 // After an encoder fault, there must be no further fault + // for this amount of time (in ms) before the encoder + // is trusted again. + + /** + * Position is checked every time a new command is executed from the buffer but during long moves, + * this setting determines the minimum update time between checks. A value of 100 works well with + * error rolling average when attempting to correct only for skips and not for vibration. + */ + #define I2CPE_MIN_UPD_TIME_MS 100 // Minimum time in miliseconds between encoder checks. + + // Use a rolling average to identify persistant errors that indicate skips, as opposed to vibration and noise. + #define I2CPE_ERR_ROLLING_AVERAGE + +#endif // I2C_POSITION_ENCODERS + +/** + * MAX7219 Debug Matrix + * + * Add support for a low-cost 8x8 LED Matrix based on the Max7219 chip, which can be used as a status + * display. Requires 3 signal wires. Some useful debug options are included to demonstrate its usage. + * + * Fully assembled MAX7219 boards can be found on the internet for under $2(US). + * For example, see https://www.ebay.com/sch/i.html?_nkw=332349290049 + */ +//#define MAX7219_DEBUG +#if ENABLED(MAX7219_DEBUG) + #define MAX7219_CLK_PIN 64 // 77 on Re-ARM // Configuration of the 3 pins to control the display + #define MAX7219_DIN_PIN 57 // 78 on Re-ARM + #define MAX7219_LOAD_PIN 44 // 79 on Re-ARM + + /** + * Sample debug features + * If you add more debug displays, be careful to avoid conflicts! + */ + #define MAX7219_DEBUG_PRINTER_ALIVE // Blink corner LED of 8x8 matrix to show that the firmware is functioning + #define MAX7219_DEBUG_STEPPER_HEAD 3 // Show the stepper queue head position on this and the next LED matrix row + #define MAX7219_DEBUG_STEPPER_TAIL 5 // Show the stepper queue tail position on this and the next LED matrix row + + #define MAX7219_DEBUG_STEPPER_QUEUE 0 // Show the current stepper queue depth on this and the next LED matrix row + // If you experience stuttering, reboots, etc. this option can reveal how + // tweaks made to the configuration are affecting the printer in real-time. +#endif + +#endif // CONFIGURATION_ADV_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/Creality/CR-10/_Bootscreen.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/Creality/CR-10/_Bootscreen.h new file mode 100644 index 00000000..fdf09dec --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/Creality/CR-10/_Bootscreen.h @@ -0,0 +1,100 @@ +/** + * 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 . + * + */ + +/** + * Tongue-in-cheek placeholder for a more Marlin-specific bitmap + * The joke is that every "CR-10" has different branding! + * Made using The Gimp and... + * - http://www.digole.com/tools/PicturetoC_Hex_converter.php + */ +#include + +#define CUSTOM_BOOTSCREEN_TIMEOUT 2500 +#define CUSTOM_BOOTSCREEN_BMPWIDTH 54 +#define CUSTOM_BOOTSCREEN_BMPHEIGHT 64 + +const unsigned char custom_start_bmp[] PROGMEM = { + 0x00, 0x00, 0x00, 0x01, 0xE0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x3F, 0xF8, 0x00, 0x00, + 0x00, 0x00, 0x03, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x00, 0x0F, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x00, 0x7F, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x00, 0x7F, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xFC, 0x0F, 0xF0, + 0x00, 0x00, 0xFF, 0xFF, 0xFD, 0xFF, 0xF8, + 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, + 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, + 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, + 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, + 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, + 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, + 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, + 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, + 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, + 0x7F, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, + 0x7F, 0xFC, 0xFF, 0xFF, 0xFC, 0x00, 0x00, + 0x1F, 0x80, 0xFF, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xFE, 0x3F, 0xF8, + 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, + 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, + 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, + 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, + 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, + 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, + 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, + 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, + 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xC0, + 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFE, 0x00, + 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xE0, 0x00, + 0x00, 0x00, 0x07, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00 +}; diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/Felix/Configuration.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/Felix/Configuration.h new file mode 100644 index 00000000..e919e5d8 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/Felix/Configuration.h @@ -0,0 +1,1682 @@ +/** + * 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 . + * + */ + +/** + * Configuration.h + * + * Basic settings such as: + * + * - Type of electronics + * - Type of temperature sensor + * - Printer geometry + * - Endstop configuration + * - LCD controller + * - Extra features + * + * Advanced settings can be found in Configuration_adv.h + * + */ +#ifndef CONFIGURATION_H +#define CONFIGURATION_H +#define CONFIGURATION_H_VERSION 010100 + +//=========================================================================== +//============================= Getting Started ============================= +//=========================================================================== + +/** + * Here are some standard links for getting your machine calibrated: + * + * http://reprap.org/wiki/Calibration + * http://youtu.be/wAL9d7FgInk + * http://calculator.josefprusa.cz + * http://reprap.org/wiki/Triffid_Hunter%27s_Calibration_Guide + * http://www.thingiverse.com/thing:5573 + * https://sites.google.com/site/repraplogphase/calibration-of-your-reprap + * http://www.thingiverse.com/thing:298812 + */ + +//=========================================================================== +//============================= DELTA Printer =============================== +//=========================================================================== +// For a Delta printer start with one of the configuration files in the +// example_configurations/delta directory and customize for your machine. +// + +//=========================================================================== +//============================= SCARA Printer =============================== +//=========================================================================== +// For a SCARA printer start with the configuration files in +// example_configurations/SCARA and customize for your machine. +// + +// @section info + +// User-specified version info of this build to display in [Pronterface, etc] terminal window during +// startup. Implementation of an idea by Prof Braino to inform user that any changes made to this +// build by the user have been successfully uploaded into firmware. +#define STRING_CONFIG_H_AUTHOR "(none, Felix)" // Who made the changes. +#define SHOW_BOOTSCREEN +#define STRING_SPLASH_LINE1 SHORT_BUILD_VERSION // will be shown during bootup in line 1 +#define STRING_SPLASH_LINE2 WEBSITE_URL // will be shown during bootup in line 2 + +// +// *** VENDORS PLEASE READ ***************************************************** +// +// Marlin now allow you to have a vendor boot image to be displayed on machine +// start. When SHOW_CUSTOM_BOOTSCREEN is defined Marlin will first show your +// custom boot image and then the default Marlin boot image is shown. +// +// We suggest for you to take advantage of this new feature and keep the Marlin +// boot image unmodified. For an example have a look at the bq Hephestos 2 +// example configuration folder. +// +//#define SHOW_CUSTOM_BOOTSCREEN +// @section machine + +/** + * Select which serial port on the board will be used for communication with the host. + * This allows the connection of wireless adapters (for instance) to non-default port pins. + * Serial port 0 is always used by the Arduino bootloader regardless of this setting. + * + * :[0, 1, 2, 3, 4, 5, 6, 7] + */ +#define SERIAL_PORT 0 + +/** + * This setting determines the communication speed of the printer. + * + * 250000 works in most cases, but you might try a lower speed if + * you commonly experience drop-outs during host printing. + * You may try up to 1000000 to speed up SD file transfer. + * + * :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000] + */ +#define BAUDRATE 250000 + +// Enable the Bluetooth serial interface on AT90USB devices +//#define BLUETOOTH + +// The following define selects which electronics board you have. +// Please choose the name from boards.h that matches your setup +#ifndef MOTHERBOARD + #define MOTHERBOARD BOARD_FELIX2 +#endif + +// Optional custom name for your RepStrap or other custom machine +// Displayed in the LCD "Ready" message +#define CUSTOM_MACHINE_NAME "Felix" + +// Define this to set a unique identifier for this printer, (Used by some programs to differentiate between machines) +// You can use an online service to generate a random UUID. (eg http://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] +#define EXTRUDERS 1 + +// For Cyclops or any "multi-extruder" that shares a single nozzle. +//#define SINGLENOZZLE + +/** + * Průša MK2 Single Nozzle Multi-Material Multiplexer, and variants. + * + * This device allows one stepper driver on a control board to drive + * two to eight stepper motors, one at a time, in a manner suitable + * for extruders. + * + * This option only allows the multiplexer to switch on tool-change. + * Additional options to configure custom E moves are pending. + */ +//#define MK2_MULTIPLEXER +#if ENABLED(MK2_MULTIPLEXER) + // Override the default DIO selector pins here, if needed. + // Some pins files may provide defaults for these pins. + //#define E_MUX0_PIN 40 // Always Required + //#define E_MUX1_PIN 42 // Needed for 3 to 8 steppers + //#define E_MUX2_PIN 44 // Needed for 5 to 8 steppers +#endif + +// A dual extruder that uses a single stepper motor +//#define SWITCHING_EXTRUDER +#if ENABLED(SWITCHING_EXTRUDER) + #define SWITCHING_EXTRUDER_SERVO_NR 0 + #define SWITCHING_EXTRUDER_SERVO_ANGLES { 0, 90 } // Angles for E0, E1[, E2, E3] + #if EXTRUDERS > 3 + #define SWITCHING_EXTRUDER_E23_SERVO_NR 1 + #endif +#endif + +// A dual-nozzle that uses a servomotor to raise/lower one of the nozzles +//#define SWITCHING_NOZZLE +#if ENABLED(SWITCHING_NOZZLE) + #define SWITCHING_NOZZLE_SERVO_NR 0 + #define SWITCHING_NOZZLE_SERVO_ANGLES { 0, 90 } // Angles for E0, E1 + //#define HOTEND_OFFSET_Z { 0.0, 0.0 } +#endif + +/** + * Two separate X-carriages with extruders that connect to a moving part + * via a magnetic docking mechanism. Requires SOL1_PIN and SOL2_PIN. + */ +//#define PARKING_EXTRUDER +#if ENABLED(PARKING_EXTRUDER) + #define PARKING_EXTRUDER_SOLENOIDS_INVERT // If enabled, the solenoid is NOT magnetized with applied voltage + #define PARKING_EXTRUDER_SOLENOIDS_PINS_ACTIVE LOW // LOW or HIGH pin signal energizes the coil + #define PARKING_EXTRUDER_SOLENOIDS_DELAY 250 // Delay (ms) for magnetic field. No delay if 0 or not defined. + #define PARKING_EXTRUDER_PARKING_X { -78, 184 } // X positions for parking the extruders + #define PARKING_EXTRUDER_GRAB_DISTANCE 1 // mm to move beyond the parking point to grab the extruder + #define PARKING_EXTRUDER_SECURITY_RAISE 5 // Z-raise before parking + #define HOTEND_OFFSET_Z { 0.0, 1.3 } // Z-offsets of the two hotends. The first must be 0. +#endif + +/** + * "Mixing Extruder" + * - Adds a new code, M165, to set the current mix factors. + * - Extends the stepping routines to move multiple steppers in proportion to the mix. + * - Optional support for Repetier Firmware M163, M164, and virtual extruder. + * - This implementation supports only a single extruder. + * - Enable DIRECT_MIXING_IN_G1 for Pia Taubert's reference implementation + */ +//#define MIXING_EXTRUDER +#if ENABLED(MIXING_EXTRUDER) + #define MIXING_STEPPERS 2 // Number of steppers in your mixing extruder + #define MIXING_VIRTUAL_TOOLS 16 // Use the Virtual Tool method with M163 and M164 + //#define DIRECT_MIXING_IN_G1 // Allow ABCDHI mix factors in G1 movement commands +#endif + +// Offset of the extruders (uncomment if using more than one and relying on firmware to position when changing). +// The offset has to be X=0, Y=0 for the extruder 0 hotend (default extruder). +// For the other hotends it is their distance from the extruder 0 hotend. +//#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis +//#define HOTEND_OFFSET_Y {0.0, 5.00} // (in mm) for each extruder, offset of the hotend on the Y axis + +// @section machine + +/** + * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN + * + * 0 = No Power Switch + * 1 = ATX + * 2 = X-Box 360 203Watts (the blue wire connected to PS_ON and the red wire to VCC) + * + * :{ 0:'No power switch', 1:'ATX', 2:'X-Box 360' } + */ +#define POWER_SUPPLY 1 + +#if POWER_SUPPLY > 0 + // Enable this option to leave the PSU off at startup. + // Power to steppers and heaters will need to be turned on with M80. + #define PS_DEFAULT_OFF +#endif + +// @section temperature + +//=========================================================================== +//============================= Thermal Settings ============================ +//=========================================================================== + +/** + * --NORMAL IS 4.7kohm PULLUP!-- 1kohm pullup can be used on hotend sensor, using correct resistor and table + * + * Temperature sensors available: + * + * -3 : thermocouple with MAX31855 (only for sensor 0) + * -2 : thermocouple with MAX6675 (only for sensor 0) + * -1 : thermocouple with AD595 + * 0 : not used + * 1 : 100k thermistor - best choice for EPCOS 100k (4.7k pullup) + * 2 : 200k thermistor - ATC Semitec 204GT-2 (4.7k pullup) + * 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 (Used in ParCan & J-Head) (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) + * 71 : 100k Honeywell thermistor 135-104LAF-J01 (4.7k pullup) + * 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) + * 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" + * 20 : the PT100 circuit found in the Ultimainboard V2.x + * 60 : 100k Maker's Tool Works Kapton Bed Thermistor beta=3950 + * 66 : 4.7M High Temperature thermistor from Dyze Design + * 70 : the 100K thermistor found in the bq Hephestos 2 + * 75 : 100k Generic Silicon Heat Pad with NTC 100K MGB18-104F39050L32 thermistor + * + * 1k ohm pullup tables - This is atypical, and requires changing out the 4.7k pullup for 1k. + * (but gives greater accuracy and more stable PID) + * 51 : 100k thermistor - EPCOS (1k pullup) + * 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 + * 1010 : Pt1000 with 1k pullup (non standard) + * 147 : Pt100 with 4k7 pullup + * 110 : Pt100 with 1k pullup (non standard) + * + * Use these for Testing or Development purposes. NEVER for production machine. + * 998 : Dummy Table that ALWAYS reads 25°C or the temperature defined below. + * 999 : Dummy Table that ALWAYS reads 100°C or the temperature defined below. + * + * :{ '0': "Not used", '1':"100k / 4.7k - EPCOS", '2':"200k / 4.7k - ATC Semitec 204GT-2", '3':"Mendel-parts / 4.7k", '4':"10k !! do not use for a hotend. Bad resolution at high temp. !!", '5':"100K / 4.7k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '6':"100k / 4.7k EPCOS - Not as accurate as Table 1", '7':"100k / 4.7k Honeywell 135-104LAG-J01", '8':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT", '9':"100k / 4.7k GE Sensing AL03006-58.2K-97-G1", '10':"100k / 4.7k RS 198-961", '11':"100k / 4.7k beta 3950 1%", '12':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT (calibrated for Makibox hot bed)", '13':"100k Hisens 3950 1% up to 300°C for hotend 'Simple ONE ' & hotend 'All In ONE'", '20':"PT100 (Ultimainboard V2.x)", '51':"100k / 1k - EPCOS", '52':"200k / 1k - ATC Semitec 204GT-2", '55':"100k / 1k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '60':"100k Maker's Tool Works Kapton Bed Thermistor beta=3950", '66':"Dyze Design 4.7M High Temperature thermistor", '70':"the 100K thermistor found in the bq Hephestos 2", '71':"100k / 4.7k Honeywell 135-104LAF-J01", '147':"Pt100 / 4.7k", '1047':"Pt1000 / 4.7k", '110':"Pt100 / 1k (non-standard)", '1010':"Pt1000 / 1k (non standard)", '-3':"Thermocouple + MAX31855 (only for sensor 0)", '-2':"Thermocouple + MAX6675 (only for sensor 0)", '-1':"Thermocouple + AD595",'998':"Dummy 1", '999':"Dummy 2" } + */ +#define TEMP_SENSOR_0 1 +#define TEMP_SENSOR_1 0 +#define TEMP_SENSOR_2 0 +#define TEMP_SENSOR_3 0 +#define TEMP_SENSOR_4 0 +#define TEMP_SENSOR_BED 1 + +// Dummy thermistor constant temperature readings, for use with 998 and 999 +#define DUMMY_THERMISTOR_998_VALUE 25 +#define DUMMY_THERMISTOR_999_VALUE 100 + +// 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 +#define MAX_REDUNDANT_TEMP_SENSOR_DIFF 10 + +// Extruder temperature must be close to target for this long before M109 returns success +#define TEMP_RESIDENCY_TIME 15 // (seconds) +#define TEMP_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// Bed temperature must be close to target for this long before M190 returns success +#define TEMP_BED_RESIDENCY_TIME 0 // (seconds) +#define TEMP_BED_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_BED_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// The minimal temperature defines the temperature below which the heater will not be enabled It is used +// to check that the wiring to the thermistor is not broken. +// Otherwise this would lead to the heater being powered on all the time. +#define HEATER_0_MINTEMP 5 +#define HEATER_1_MINTEMP 5 +#define HEATER_2_MINTEMP 5 +#define HEATER_3_MINTEMP 5 +#define HEATER_4_MINTEMP 5 +#define BED_MINTEMP 5 + +// When temperature exceeds max temp, your heater will be switched off. +// This feature exists to protect your hotend from overheating accidentally, but *NOT* from thermistor short/failure! +// You should use MINTEMP for thermistor short/failure protection. +#define HEATER_0_MAXTEMP 275 +#define HEATER_1_MAXTEMP 275 +#define HEATER_2_MAXTEMP 275 +#define HEATER_3_MAXTEMP 275 +#define HEATER_4_MAXTEMP 275 +#define BED_MAXTEMP 150 + +//=========================================================================== +//============================= PID Settings ================================ +//=========================================================================== +// PID Tuning Guide here: http://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 +#if ENABLED(PIDTEMP) + //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. + //#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. + #define K1 0.95 //smoothing factor within the PID + + // Felix 2.0+ electronics with v4 Hotend + #define DEFAULT_Kp 12 + #define DEFAULT_Ki 0.84 + #define DEFAULT_Kd 85 + +#endif // PIDTEMP + +//=========================================================================== +//============================= PID > Bed Temperature Control =============== +//=========================================================================== +// Select PID or bang-bang with PIDTEMPBED. If bang-bang, BED_LIMIT_SWITCHING will enable hysteresis +// +// Uncomment this to enable PID on the bed. It uses the same frequency PWM as the extruder. +// If your PID_dT is the default, and correct for your hardware/configuration, that means 7.689Hz, +// which is fine for driving a square wave into a resistive load and does not significantly impact you FET heating. +// This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W heater. +// If your configuration is significantly different than this and you don't understand the issues involved, you probably +// shouldn't use bed PID until someone else verifies your hardware works. +// If this is enabled, find your own PID constants below. +#define PIDTEMPBED + +//#define BED_LIMIT_SWITCHING + +// This sets the max power delivered to the bed, and replaces the HEATER_BED_DUTY_CYCLE_DIVIDER option. +// all forms of bed control obey this (PID, bang-bang, bang-bang with hysteresis) +// setting this to anything other than 255 enables a form of PWM to the bed just like HEATER_BED_DUTY_CYCLE_DIVIDER did, +// so you shouldn't use it unless you are OK with PWM on your bed. (see the comment on enabling PIDTEMPBED) +#define MAX_BED_POWER 255 // limits duty cycle to bed; 255=full current + +#if ENABLED(PIDTEMPBED) + + //#define PID_BED_DEBUG // Sends debug data to the serial port. + + // Felix Foil Heater + #define DEFAULT_bedKp 103.37 + #define DEFAULT_bedKi 2.79 + #define DEFAULT_bedKd 956.94 + + // FIND YOUR OWN: "M303 E-1 C8 S90" to run autotune on the bed at 90 degreesC for 8 cycles. +#endif // PIDTEMPBED + +// @section extruder + +// This option prevents extrusion if the temperature is below EXTRUDE_MINTEMP. +// It also enables the M302 command to set the minimum extrusion temperature +// or to allow moving the extruder regardless of the hotend temperature. +// *** IT IS HIGHLY RECOMMENDED TO LEAVE THIS OPTION ENABLED! *** +#define PREVENT_COLD_EXTRUSION +#define EXTRUDE_MINTEMP 170 + +// This option prevents a single extrusion longer than EXTRUDE_MAXLENGTH. +// Note that for Bowden Extruders a too-small value here may prevent loading. +#define PREVENT_LENGTHY_EXTRUDE +#define EXTRUDE_MAXLENGTH 200 + +//=========================================================================== +//======================== Thermal Runaway Protection ======================= +//=========================================================================== + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * If you get "Thermal Runaway" or "Heating failed" errors the + * details can be tuned in Configuration_adv.h + */ + +#define THERMAL_PROTECTION_HOTENDS // Enable thermal protection for all extruders +#define THERMAL_PROTECTION_BED // Enable thermal protection for the heated bed + +//=========================================================================== +//============================= Mechanical Settings ========================= +//=========================================================================== + +// @section machine + +// Uncomment one of these options to enable CoreXY, CoreXZ, or CoreYZ kinematics +// either in the usual order or reversed +//#define COREXY +//#define COREXZ +//#define COREYZ +//#define COREYX +//#define COREZX +//#define COREZY + +//=========================================================================== +//============================== Endstop Settings =========================== +//=========================================================================== + +// @section homing + +// Specify here all the endstop connectors that are connected to any endstop or probe. +// Almost all printers will be using one per axis. Probes will use one or more of the +// extra connectors. Leave undefined any used for non-endstop and non-probe purposes. +#define USE_XMIN_PLUG +#define USE_YMIN_PLUG +#define USE_ZMIN_PLUG +//#define USE_XMAX_PLUG +//#define USE_YMAX_PLUG +//#define USE_ZMAX_PLUG + +// coarse Endstop Settings +#define ENDSTOPPULLUPS // Comment this out (using // at the start of the line) to disable the endstop pullup resistors + +#if DISABLED(ENDSTOPPULLUPS) + // fine endstop settings: Individual pullups. will be ignored if ENDSTOPPULLUPS is defined + //#define ENDSTOPPULLUP_XMAX + //#define ENDSTOPPULLUP_YMAX + //#define ENDSTOPPULLUP_ZMAX + //#define ENDSTOPPULLUP_XMIN + //#define ENDSTOPPULLUP_YMIN + //#define ENDSTOPPULLUP_ZMIN + //#define ENDSTOPPULLUP_ZMIN_PROBE +#endif + +// Mechanical endstop with COM to ground and NC to Signal uses "false" here (most common setup). +#define X_MIN_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Y_MIN_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MIN_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define X_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Y_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MIN_PROBE_ENDSTOP_INVERTING false // set to true to invert the logic of the probe. + +// Enable this feature if all enabled endstop pins are interrupt-capable. +// This will remove the need to poll the interrupt pins, saving many CPU cycles. +//#define ENDSTOP_INTERRUPTS_FEATURE + +//============================================================================= +//============================== Movement Settings ============================ +//============================================================================= +// @section motion + +// default steps per unit for Felix 2.0/3.0: 0.00249mm x/y rounding error with 3mm pitch HTD belt and 14 tooth pulleys. 0 z error. +/** + * Default Settings + * + * These settings can be reset by M502 + * + * Note that if EEPROM is enabled, saved values will override these. + */ + +/** + * With this option each E stepper can have its own factors for the + * following movement settings. If fewer factors are given than the + * total number of extruders, the last value applies to the rest. + */ +//#define DISTINCT_E_FACTORS + +/** + * Default Axis Steps Per Unit (steps/mm) + * Override with M92 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_AXIS_STEPS_PER_UNIT { 76.190476, 76.190476, 1600, 164 } + +/** + * Default Max Feed Rate (mm/s) + * Override with M203 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_FEEDRATE { 500, 500, 5, 25 } + +/** + * Default Max Acceleration (change/s) change = mm/s + * (Maximum start speed for accelerated moves) + * Override with M201 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_ACCELERATION { 5000, 5000, 100, 80000 } + +/** + * Default Acceleration (change/s) change = mm/s + * Override with M204 + * + * M204 P Acceleration + * M204 R Retract Acceleration + * M204 T Travel Acceleration + */ +#define DEFAULT_ACCELERATION 1750 // X, Y, Z and E max acceleration for printing moves +#define DEFAULT_RETRACT_ACCELERATION 5000 // E acceleration for retracts +#define DEFAULT_TRAVEL_ACCELERATION 3000 // X, Y, Z acceleration for travel (non printing) moves + +/** + * Default Jerk (mm/s) + * Override with M205 X Y Z E + * + * "Jerk" specifies the minimum speed change that requires acceleration. + * When changing speed and direction, if the difference is less than the + * value set here, it may happen instantaneously. + */ +#define DEFAULT_XJERK 10.0 +#define DEFAULT_YJERK 10.0 +#define DEFAULT_ZJERK 0.3 +#define DEFAULT_EJERK 5.0 + +//=========================================================================== +//============================= Z Probe Options ============================= +//=========================================================================== +// @section probes + +// +// See http://marlinfw.org/configuration/probes.html +// + +/** + * Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + * + * Enable this option for a probe connected to the Z Min endstop pin. + */ +#define Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + +/** + * Z_MIN_PROBE_ENDSTOP + * + * Enable this option for a probe connected to any pin except Z-Min. + * (By default Marlin assumes the Z-Max endstop pin.) + * To use a custom Z Probe pin, set Z_MIN_PROBE_PIN below. + * + * - The simplest option is to use a free endstop connector. + * - Use 5V for powered (usually inductive) sensors. + * + * - RAMPS 1.3/1.4 boards may use the 5V, GND, and Aux4->D32 pin: + * - For simple switches connect... + * - normally-closed switches to GND and D32. + * - normally-open switches to 5V and D32. + * + * WARNING: Setting the wrong pin may have unexpected and potentially + * disastrous consequences. Use with caution and do your homework. + * + */ +//#define Z_MIN_PROBE_ENDSTOP + +/** + * Probe Type + * + * Allen Key Probes, Servo Probes, Z-Sled Probes, FIX_MOUNTED_PROBE, etc. + * Activate one of these to use Auto Bed Leveling below. + */ + +/** + * The "Manual Probe" provides a means to do "Auto" Bed Leveling without a probe. + * Use G29 repeatedly, adjusting the Z height at each point with movement commands + * or (with LCD_BED_LEVELING) the LCD controller. + */ +//#define PROBE_MANUALLY + +/** + * A Fix-Mounted Probe either doesn't deploy or needs manual deployment. + * (e.g., an inductive probe or a nozzle-based probe-switch.) + */ +//#define FIX_MOUNTED_PROBE + +/** + * Z Servo Probe, such as an endstop switch on a rotating arm. + */ +//#define Z_ENDSTOP_SERVO_NR 0 // Defaults to SERVO 0 connector. +//#define Z_SERVO_ANGLES {70,0} // Z Servo Deploy and Stow angles + +/** + * The BLTouch probe uses a Hall effect sensor and emulates a servo. + */ +//#define BLTOUCH +#if ENABLED(BLTOUCH) + //#define BLTOUCH_DELAY 375 // (ms) Enable and increase if needed +#endif + +/** + * Enable one or more of the following if probing seems unreliable. + * Heaters and/or fans can be disabled during probing to minimize electrical + * noise. A delay can also be added to allow noise and vibration to settle. + * These options are most useful for the BLTouch probe, but may also improve + * readings with inductive probes and piezo sensors. + */ +//#define PROBING_HEATERS_OFF // Turn heaters off when probing +//#define PROBING_FANS_OFF // Turn fans off when probing +//#define DELAY_BEFORE_PROBING 200 // (ms) To prevent vibrations from triggering piezo sensors + +// A probe that is deployed and stowed with a solenoid pin (SOL1_PIN) +//#define SOLENOID_PROBE + +// A sled-mounted probe like those designed by Charles Bell. +//#define Z_PROBE_SLED +//#define SLED_DOCKING_OFFSET 5 // The extra distance the X axis must travel to pickup the sled. 0 should be fine but you can push it further if you'd like. + +// +// For Z_PROBE_ALLEN_KEY see the Delta example configurations. +// + +/** + * Z Probe to nozzle (X,Y) offset, relative to (0, 0). + * X and Y offsets must be integers. + * + * In the following example the X and Y offsets are both positive: + * #define X_PROBE_OFFSET_FROM_EXTRUDER 10 + * #define Y_PROBE_OFFSET_FROM_EXTRUDER 10 + * + * +-- BACK ---+ + * | | + * L | (+) P | R <-- probe (20,20) + * E | | I + * F | (-) N (+) | G <-- nozzle (10,10) + * T | | H + * | (-) | T + * | | + * O-- FRONT --+ + * (0,0) + */ +#define X_PROBE_OFFSET_FROM_EXTRUDER -25 // X offset: -left +right [of the nozzle] +#define Y_PROBE_OFFSET_FROM_EXTRUDER -29 // Y offset: -front +behind [the nozzle] +#define Z_PROBE_OFFSET_FROM_EXTRUDER -12.35 // Z offset: -below +above [the nozzle] + +// X and Y axis travel speed (mm/m) between probes +#define XY_PROBE_SPEED 8000 + +// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +#define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z + +// Speed for the "accurate" probe of each point +#define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) + +// Use double touch for probing +//#define PROBE_DOUBLE_TOUCH + +/** + * Z probes require clearance when deploying, stowing, and moving between + * probe points to avoid hitting the bed and other hardware. + * Servo-mounted probes require extra space for the arm to rotate. + * Inductive probes need space to keep from triggering early. + * + * Use these settings to specify the distance (mm) to raise the probe (or + * lower the bed). The values set here apply over and above any (negative) + * probe Z Offset set with Z_PROBE_OFFSET_FROM_EXTRUDER, M851, or the LCD. + * Only integer values >= 1 are valid here. + * + * Example: `M851 Z-5` with a CLEARANCE of 4 => 9mm from bed to nozzle. + * But: `M851 Z+1` with a CLEARANCE of 2 => 2mm from bed to nozzle. + */ +#define Z_CLEARANCE_DEPLOY_PROBE 15 // Z Clearance for Deploy/Stow +#define Z_CLEARANCE_BETWEEN_PROBES 5 // Z Clearance between probe points + +// For M851 give a range for adjusting the Z probe offset +#define Z_PROBE_OFFSET_RANGE_MIN -20 +#define Z_PROBE_OFFSET_RANGE_MAX 20 + +// Enable the M48 repeatability test to test probe accuracy +//#define Z_MIN_PROBE_REPEATABILITY_TEST + +// For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1 +// :{ 0:'Low', 1:'High' } +#define X_ENABLE_ON 0 +#define Y_ENABLE_ON 0 +#define Z_ENABLE_ON 0 +#define E_ENABLE_ON 0 // For all extruders + +// Disables axis stepper immediately when it's not being used. +// 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 +//#define DISABLE_REDUCED_ACCURACY_WARNING + +// @section extruder + +#define DISABLE_E false // For all extruders +#define DISABLE_INACTIVE_EXTRUDER true // Keep only the active extruder enabled. + +// @section machine + +// Invert the stepper direction. Change (or reverse the motor connector) if an axis goes the wrong way. +#define INVERT_X_DIR true +#define INVERT_Y_DIR true +#define INVERT_Z_DIR true + +// Enable this option for Toshiba stepper drivers +//#define CONFIG_STEPPERS_TOSHIBA + +// @section extruder + +// For direct drive extruder v9 set to true, for geared extruder set to false. +#define INVERT_E0_DIR false +#define INVERT_E1_DIR false +#define INVERT_E2_DIR false +#define INVERT_E3_DIR false +#define INVERT_E4_DIR false + +// @section homing + +//#define NO_MOTION_BEFORE_HOMING // Inhibit movement until all axes have been homed + +//#define Z_HOMING_HEIGHT 4 // (in mm) Minimal z height before homing (G28) for Z clearance above the bed, clamps, ... + // Be sure you have this distance over your Z_MAX_POS in case. + +// Direction of endstops when homing; 1=MAX, -1=MIN +// :[-1,1] +#define X_HOME_DIR -1 +#define Y_HOME_DIR -1 +#define Z_HOME_DIR -1 + +// @section machine + +// The size of the print bed +#define X_BED_SIZE 255 +#define Y_BED_SIZE 205 + +// Travel limits (mm) after homing, corresponding to endstop positions. +#define X_MIN_POS 0 +#define Y_MIN_POS 0 +#define Z_MIN_POS 0 +#define X_MAX_POS X_BED_SIZE +#define Y_MAX_POS Y_BED_SIZE +#define Z_MAX_POS 235 + +// If enabled, axes won't move below MIN_POS in response to movement commands. +#define MIN_SOFTWARE_ENDSTOPS +// If enabled, axes won't move above MAX_POS in response to movement commands. +#define MAX_SOFTWARE_ENDSTOPS + +/** + * Filament Runout Sensor + * A mechanical or opto endstop is used to check for the presence of filament. + * + * RAMPS-based boards use SERVO3_PIN. + * For other boards you may need to define FIL_RUNOUT_PIN. + * By default the firmware assumes HIGH = has filament, LOW = ran out + */ +//#define FILAMENT_RUNOUT_SENSOR +#if ENABLED(FILAMENT_RUNOUT_SENSOR) + #define FIL_RUNOUT_INVERTING false // set to true to invert the logic of the sensor. + #define ENDSTOPPULLUP_FIL_RUNOUT // Uncomment to use internal pullup for filament runout pins if the sensor is defined. + #define FILAMENT_RUNOUT_SCRIPT "M600" +#endif + +//=========================================================================== +//=============================== Bed Leveling ============================== +//=========================================================================== +// @section bedlevel + +/** + * Choose one of the options below to enable G29 Bed Leveling. The parameters + * and behavior of G29 will change depending on your selection. + * + * If using a Probe for Z Homing, enable Z_SAFE_HOMING also! + * + * - AUTO_BED_LEVELING_3POINT + * Probe 3 arbitrary points on the bed (that aren't collinear) + * You specify the XY coordinates of all 3 points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_LINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_BILINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a mesh, best for large or uneven beds. + * + * - AUTO_BED_LEVELING_UBL (Unified Bed Leveling) + * A comprehensive bed leveling system combining the features and benefits + * of other systems. UBL also includes integrated Mesh Generation, Mesh + * Validation and Mesh Editing systems. Currently, UBL is only checked out + * for Cartesian Printers. That said, it was primarily designed to correct + * poor quality Delta Printers. If you feel adventurous and have a Delta, + * please post an issue if something doesn't work correctly. Initially, + * you will need to set a reduced bed size so you have a rectangular area + * to test on. + * + * - MESH_BED_LEVELING + * Probe a grid manually + * The result is a mesh, suitable for large or uneven beds. (See BILINEAR.) + * For machines without a probe, Mesh Bed Leveling provides a method to perform + * leveling in steps so you can manually adjust the Z height at each grid-point. + * With an LCD controller the process is guided step-by-step. + */ +//#define AUTO_BED_LEVELING_3POINT +//#define AUTO_BED_LEVELING_LINEAR +//#define AUTO_BED_LEVELING_BILINEAR +//#define AUTO_BED_LEVELING_UBL +//#define MESH_BED_LEVELING + +/** + * Enable detailed logging of G28, G29, M48, etc. + * Turn on with the command 'M111 S32'. + * NOTE: Requires a lot of PROGMEM! + */ +//#define DEBUG_LEVELING_FEATURE + +#if ENABLED(MESH_BED_LEVELING) || ENABLED(AUTO_BED_LEVELING_BILINEAR) || ENABLED(AUTO_BED_LEVELING_UBL) + // Gradually reduce leveling correction until a set height is reached, + // at which point movement will be level to the machine's XY plane. + // The height can be set with M420 Z + #define ENABLE_LEVELING_FADE_HEIGHT +#endif + +#if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Set the number of grid points per dimension. + #define GRID_MAX_POINTS_X 3 + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + // Set the boundaries for probing (where the probe can reach). + #define LEFT_PROBE_BED_POSITION 15 + #define RIGHT_PROBE_BED_POSITION 170 + #define FRONT_PROBE_BED_POSITION 20 + #define BACK_PROBE_BED_POSITION 180 + + // The Z probe minimum outer margin (to validate G29 parameters). + #define MIN_PROBE_EDGE 10 + + // Probe along the Y axis, advancing X after each column + //#define PROBE_Y_FIRST + + #if ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Beyond the probed grid, continue the implied tilt? + // Default is to maintain the height of the nearest edge. + //#define EXTRAPOLATE_BEYOND_GRID + + // + // Experimental Subdivision of the grid by Catmull-Rom method. + // Synthesizes intermediate points to produce a more detailed mesh. + // + //#define ABL_BILINEAR_SUBDIVISION + #if ENABLED(ABL_BILINEAR_SUBDIVISION) + // Number of subdivisions between probe points + #define BILINEAR_SUBDIVISIONS 3 + #endif + + #endif + +#elif ENABLED(AUTO_BED_LEVELING_3POINT) + + // 3 arbitrary points to probe. + // A simple cross-product is used to estimate the plane of the bed. + #define ABL_PROBE_PT_1_X 15 + #define ABL_PROBE_PT_1_Y 180 + #define ABL_PROBE_PT_2_X 15 + #define ABL_PROBE_PT_2_Y 20 + #define ABL_PROBE_PT_3_X 170 + #define ABL_PROBE_PT_3_Y 20 + +#elif ENABLED(AUTO_BED_LEVELING_UBL) + + //=========================================================================== + //========================= Unified Bed Leveling ============================ + //=========================================================================== + + #define UBL_MESH_INSET 1 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 10 // Don't use more than 15 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + #define UBL_PROBE_PT_1_X 39 // Probing points for 3-Point leveling of the mesh + #define UBL_PROBE_PT_1_Y 180 + #define UBL_PROBE_PT_2_X 39 + #define UBL_PROBE_PT_2_Y 20 + #define UBL_PROBE_PT_3_X 180 + #define UBL_PROBE_PT_3_Y 20 + + #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation + #define UBL_MESH_EDIT_MOVES_Z // Sophisticated users prefer no movement of nozzle + +#elif ENABLED(MESH_BED_LEVELING) + + //=========================================================================== + //=================================== Mesh ================================== + //=========================================================================== + + #define MESH_INSET 10 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 3 // Don't use more than 7 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + //#define MESH_G28_REST_ORIGIN // After homing all axes ('G28' or 'G28 XYZ') rest Z at Z_MIN_POS + +#endif // BED_LEVELING + +/** + * Use the LCD controller for bed leveling + * Requires MESH_BED_LEVELING or PROBE_MANUALLY + */ +//#define LCD_BED_LEVELING + +#if ENABLED(LCD_BED_LEVELING) + #define MBL_Z_STEP 0.025 // Step size while manually probing Z axis. + #define LCD_PROBE_Z_RANGE 4 // Z Range centered on Z_MIN_POS for LCD Z adjustment +#endif + +// Add a menu item to move between bed corners for manual bed adjustment +//#define LEVEL_BED_CORNERS + +/** + * Commands to execute at the end of G29 probing. + * Useful to retract or move the Z probe out of the way. + */ +//#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) +//#define BED_CENTER_AT_0_0 + +// Manually set the home position. Leave these undefined for automatic settings. +// For DELTA this is the top-center of the Cartesian print volume. +//#define MANUAL_X_HOME_POS 0 +//#define MANUAL_Y_HOME_POS 0 +//#define MANUAL_Z_HOME_POS 0 + +// Use "Z Safe Homing" to avoid homing with a Z probe outside the bed area. +// +// With this feature enabled: +// +// - 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). +// - 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 axis (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). +#endif + +// Homing speeds (mm/m) +#define HOMING_FEEDRATE_XY (50*60) +#define HOMING_FEEDRATE_Z (4*60) + +//============================================================================= +//============================= Additional Features =========================== +//============================================================================= + +// @section extras + +// +// EEPROM +// +// The microcontroller can store settings in the EEPROM, e.g. max velocity... +// M500 - stores parameters in EEPROM +// M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily). +// M502 - reverts to the default "factory settings". You still need to store them in EEPROM afterwards if you want to. +// +//#define EEPROM_SETTINGS // Enable for M500 and M501 commands +//#define DISABLE_M503 // Saves ~2700 bytes of PROGMEM. Disable for release! +#define EEPROM_CHITCHAT // Give feedback on EEPROM commands. Disable to save PROGMEM. + +// +// Host Keepalive +// +// When enabled Marlin will send a busy status message to the host +// every couple of seconds when it can't accept commands. +// +#define HOST_KEEPALIVE_FEATURE // Disable this if your host doesn't like keepalive messages +#define DEFAULT_KEEPALIVE_INTERVAL 2 // Number of seconds between "busy" messages. Set with M113. +#define BUSY_WHILE_HEATING // Some hosts require "busy" messages even during heating + +// +// M100 Free Memory Watcher +// +//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose + +// +// G20/G21 Inch mode support +// +//#define INCH_MODE_SUPPORT + +// +// M149 Set temperature units support +// +//#define TEMPERATURE_UNITS_SUPPORT + +// @section temperature + +// Preheat Constants +#define PREHEAT_1_TEMP_HOTEND 180 +#define PREHEAT_1_TEMP_BED 70 +#define PREHEAT_1_FAN_SPEED 255 // Value from 0 to 255 + +#define PREHEAT_2_TEMP_HOTEND 240 +#define PREHEAT_2_TEMP_BED 100 +#define PREHEAT_2_FAN_SPEED 255 // Value from 0 to 255 + +/** + * Nozzle Park -- EXPERIMENTAL + * + * Park the nozzle at the given XYZ position on idle or G27. + * + * The "P" parameter controls the action applied to the Z axis: + * + * P0 (Default) If Z is below park Z raise the nozzle. + * P1 Raise the nozzle always to Z-park height. + * P2 Raise the nozzle by Z-park amount, limited to Z_MAX_POS. + */ +//#define NOZZLE_PARK_FEATURE + +#if ENABLED(NOZZLE_PARK_FEATURE) + // Specify a park position as { X, Y, Z } + #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 } +#endif + +/** + * Clean Nozzle Feature -- EXPERIMENTAL + * + * Adds the G12 command to perform a nozzle cleaning process. + * + * Parameters: + * P Pattern + * S Strokes / Repetitions + * T Triangles (P1 only) + * + * Patterns: + * P0 Straight line (default). This process requires a sponge type material + * at a fixed bed location. "S" specifies strokes (i.e. back-forth motions) + * between the start / end points. + * + * P1 Zig-zag pattern between (X0, Y0) and (X1, Y1), "T" specifies the + * number of zig-zag triangles to do. "S" defines the number of strokes. + * Zig-zags are done in whichever is the narrower dimension. + * For example, "G12 P1 S1 T3" will execute: + * + * -- + * | (X0, Y1) | /\ /\ /\ | (X1, Y1) + * | | / \ / \ / \ | + * A | | / \ / \ / \ | + * | | / \ / \ / \ | + * | (X0, Y0) | / \/ \/ \ | (X1, Y0) + * -- +--------------------------------+ + * |________|_________|_________| + * T1 T2 T3 + * + * P2 Circular pattern with middle at NOZZLE_CLEAN_CIRCLE_MIDDLE. + * "R" specifies the radius. "S" specifies the stroke count. + * Before starting, the nozzle moves to NOZZLE_CLEAN_START_POINT. + * + * Caveats: The ending Z should be the same as starting Z. + * Attention: EXPERIMENTAL. G-code arguments may change. + * + */ +//#define NOZZLE_CLEAN_FEATURE + +#if ENABLED(NOZZLE_CLEAN_FEATURE) + // Default number of pattern repetitions + #define NOZZLE_CLEAN_STROKES 12 + + // Default number of triangles + #define NOZZLE_CLEAN_TRIANGLES 3 + + // Specify positions as { X, Y, Z } + #define NOZZLE_CLEAN_START_POINT { 30, 30, (Z_MIN_POS + 1)} + #define NOZZLE_CLEAN_END_POINT {100, 60, (Z_MIN_POS + 1)} + + // Circular pattern radius + #define NOZZLE_CLEAN_CIRCLE_RADIUS 6.5 + // Circular pattern circle fragments number + #define NOZZLE_CLEAN_CIRCLE_FN 10 + // Middle point of circle + #define NOZZLE_CLEAN_CIRCLE_MIDDLE NOZZLE_CLEAN_START_POINT + + // Moves the nozzle to the initial position + #define NOZZLE_CLEAN_GOBACK +#endif + +/** + * Print Job Timer + * + * Automatically start and stop the print job timer on M104/M109/M190. + * + * M104 (hotend, no wait) - high temp = none, low temp = stop timer + * M109 (hotend, wait) - high temp = start timer, low temp = stop timer + * M190 (bed, wait) - high temp = start timer, low temp = none + * + * The timer can also be controlled with the following commands: + * + * M75 - Start the print job timer + * M76 - Pause the print job timer + * M77 - Stop the print job timer + */ +#define PRINTJOB_TIMER_AUTOSTART + +/** + * Print Counter + * + * Track statistical data such as: + * + * - Total print jobs + * - Total successful print jobs + * - Total failed print jobs + * - Total time printing + * + * View the current statistics with M78. + */ +//#define PRINTCOUNTER + +//============================================================================= +//============================= LCD and SD support ============================ +//============================================================================= + +// @section lcd + +/** + * LCD LANGUAGE + * + * Select the language to display on the LCD. These languages are available: + * + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, + * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * tr, uk, zh_CN, zh_TW, test + * + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + */ +//#define LCD_LANGUAGE en + +/** + * LCD Character Set + * + * Note: This option is NOT applicable to Graphical Displays. + * + * All character-based LCDs provide ASCII plus one of these + * language extensions: + * + * - JAPANESE ... the most common + * - WESTERN ... with more accented characters + * - CYRILLIC ... for the Russian language + * + * To determine the language extension installed on your controller: + * + * - Compile and upload with LCD_LANGUAGE set to 'test' + * - 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 + * + * :['JAPANESE', 'WESTERN', 'CYRILLIC'] + */ +#define DISPLAY_CHARSET_HD44780 JAPANESE + +/** + * LCD TYPE + * + * Enable ULTRA_LCD for a 16x2, 16x4, 20x2, or 20x4 character-based LCD. + * Enable DOGLCD for a 128x64 (ST7565R) Full Graphical Display. + * (These options will be enabled automatically for most displays.) + * + * IMPORTANT: The U8glib library is required for Full Graphic Display! + * https://github.com/olikraus/U8glib_Arduino + */ +//#define ULTRA_LCD // Character based +//#define DOGLCD // Full graphics display + +/** + * SD CARD + * + * 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 + +/** + * SD CARD: SPI SPEED + * + * Enable one of the following items for a slower SPI transfer speed. + * This may be required to resolve "volume init" errors. + */ +//#define SPI_SPEED SPI_HALF_SPEED +//#define SPI_SPEED SPI_QUARTER_SPEED +//#define SPI_SPEED SPI_EIGHTH_SPEED + +/** + * SD CARD: ENABLE CRC + * + * Use CRC checks and retries on the SD communication. + */ +//#define SD_CHECK_AND_RETRY + +// +// ENCODER SETTINGS +// +// This option overrides the default number of encoder pulses needed to +// produce one step. Should be increased for high-resolution encoders. +// +//#define ENCODER_PULSES_PER_STEP 1 + +// +// Use this option to override the number of step signals required to +// move between next/prev menu items. +// +//#define ENCODER_STEPS_PER_MENU_ITEM 5 + +/** + * Encoder Direction Options + * + * Test your encoder's behavior first with both options disabled. + * + * Reversed Value Edit and Menu Nav? Enable REVERSE_ENCODER_DIRECTION. + * Reversed Menu Navigation only? Enable REVERSE_MENU_DIRECTION. + * Reversed Value Editing only? Enable BOTH options. + */ + +// +// This option reverses the encoder direction everywhere. +// +// Set this option if CLOCKWISE causes values to DECREASE +// +//#define REVERSE_ENCODER_DIRECTION + +// +// This option reverses the encoder direction for navigating LCD menus. +// +// If CLOCKWISE normally moves DOWN this makes it go UP. +// If CLOCKWISE normally moves UP this makes it go DOWN. +// +//#define REVERSE_MENU_DIRECTION + +// +// Individual Axis Homing +// +// Add individual axis homing items (Home X, Home Y, and Home Z) to the LCD menu. +// +//#define INDIVIDUAL_AXIS_HOMING_MENU + +// +// SPEAKER/BUZZER +// +// If you have a speaker that can produce tones, enable it here. +// By default Marlin assumes you have a buzzer with a fixed frequency. +// +//#define SPEAKER + +// +// The duration and frequency for the UI feedback sound. +// Set these to 0 to disable audio feedback in the LCD menus. +// +// Note: Test audio output with the G-Code: +// M300 S P +// +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 +//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 + +// +// CONTROLLER TYPE: Standard +// +// Marlin supports a wide variety of controllers. +// Enable one of the following options to specify your controller. +// + +// +// ULTIMAKER Controller. +// +//#define ULTIMAKERCONTROLLER + +// +// ULTIPANEL as seen on Thingiverse. +// +//#define ULTIPANEL + +// +// PanelOne from T3P3 (via RAMPS 1.4 AUX2/AUX3) +// http://reprap.org/wiki/PanelOne +// +//#define PANEL_ONE + +// +// MaKr3d Makr-Panel with graphic controller and SD support. +// http://reprap.org/wiki/MaKr3d_MaKrPanel +// +//#define MAKRPANEL + +// +// ReprapWorld Graphical LCD +// https://reprapworld.com/?products_details&products_id/1218 +// +//#define REPRAPWORLD_GRAPHICAL_LCD + +// +// Activate one of these if you have a Panucatt Devices +// Viki 2.0 or mini Viki with Graphic LCD +// http://panucatt.com +// +//#define VIKI2 +//#define miniVIKI + +// +// Adafruit ST7565 Full Graphic Controller. +// https://github.com/eboston/Adafruit-ST7565-Full-Graphic-Controller/ +// +//#define ELB_FULL_GRAPHIC_CONTROLLER + +// +// RepRapDiscount Smart Controller. +// http://reprap.org/wiki/RepRapDiscount_Smart_Controller +// +// Note: Usually sold with a white PCB. +// +//#define REPRAP_DISCOUNT_SMART_CONTROLLER + +// +// GADGETS3D G3D LCD/SD Controller +// http://reprap.org/wiki/RAMPS_1.3/1.4_GADGETS3D_Shield_with_Panel +// +// Note: Usually sold with a blue PCB. +// +//#define G3D_PANEL + +// +// RepRapDiscount FULL GRAPHIC Smart Controller +// http://reprap.org/wiki/RepRapDiscount_Full_Graphic_Smart_Controller +// +//#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER + +// +// MakerLab Mini Panel with graphic +// controller and SD support - http://reprap.org/wiki/Mini_panel +// +//#define MINIPANEL + +// +// RepRapWorld REPRAPWORLD_KEYPAD v1.1 +// http://reprapworld.com/?products_details&products_id=202&cPath=1591_1626 +// +// REPRAPWORLD_KEYPAD_MOVE_STEP sets how much should the robot move when a key +// is pressed, a value of 10.0 means 10mm per click. +// +//#define REPRAPWORLD_KEYPAD +//#define REPRAPWORLD_KEYPAD_MOVE_STEP 1.0 + +// +// RigidBot Panel V1.0 +// http://www.inventapart.com/ +// +//#define RIGIDBOT_PANEL + +// +// BQ LCD Smart Controller shipped by +// default with the BQ Hephestos 2 and Witbox 2. +// +//#define BQ_LCD_SMART_CONTROLLER + +// +// Cartesio UI +// http://mauk.cc/webshop/cartesio-shop/electronics/user-interface +// +//#define CARTESIO_UI + +// +// ANET_10 Controller supported displays. +// +//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. + // This LCD is known to be susceptible to electrical interference + // which scrambles the display. Pressing any button clears it up. +//#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 + // A clone of the RepRapDiscount full graphics display but with + // different pins/wiring (see pins_ANET_10.h). + +// +// LCD for Melzi Card with Graphical LCD +// +//#define LCD_FOR_MELZI + +// +// CONTROLLER TYPE: I2C +// +// Note: These controllers require the installation of Arduino's LiquidCrystal_I2C +// library. For more info: https://github.com/kiyoshigawa/LiquidCrystal_I2C +// + +// +// Elefu RA Board Control Panel +// http://www.elefu.com/index.php?route=product/product&product_id=53 +// +//#define RA_CONTROL_PANEL + +// +// Sainsmart YW Robot (LCM1602) LCD Display +// +// Note: This controller requires F.Malpartida's LiquidCrystal_I2C library +// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home +// +//#define LCD_I2C_SAINSMART_YWROBOT + +// +// Generic LCM1602 LCD adapter +// +//#define LCM1602 + +// +// PANELOLU2 LCD with status LEDs, +// separate encoder and click inputs. +// +// Note: This controller requires Arduino's LiquidTWI2 library v1.2.3 or later. +// For more info: https://github.com/lincomatic/LiquidTWI2 +// +// Note: The PANELOLU2 encoder click input can either be directly connected to +// a pin (if BTN_ENC defined to != -1) or read through I2C (when BTN_ENC == -1). +// +//#define LCD_I2C_PANELOLU2 + +// +// Panucatt VIKI LCD with status LEDs, +// integrated click & L/R/U/D buttons, separate encoder inputs. +// +//#define LCD_I2C_VIKI + +// +// SSD1306 OLED full graphics generic display +// +//#define U8GLIB_SSD1306 + +// +// SAV OLEd LCD module support using either SSD1306 or SH1106 based LCD modules +// +//#define SAV_3DGLCD +#if ENABLED(SAV_3DGLCD) + //#define U8GLIB_SSD1306 + #define U8GLIB_SH1106 +#endif + +// +// CONTROLLER TYPE: Shift register panels +// +// 2 wire Non-latching LCD SR from https://goo.gl/aJJ4sH +// LCD configuration: http://reprap.org/wiki/SAV_3D_LCD +// +//#define SAV_3DLCD + +// +// TinyBoy2 128x64 OLED / Encoder Panel +// +//#define OLED_PANEL_TINYBOY2 + +// +// Makeboard 3D Printer Parts 3D Printer Mini Display 1602 Mini Controller +// https://www.aliexpress.com/item/Micromake-Makeboard-3D-Printer-Parts-3D-Printer-Mini-Display-1602-Mini-Controller-Compatible-with-Ramps-1/32765887917.html +// +//#define MAKEBOARD_MINI_2_LINE_DISPLAY_1602 + +// +// MKS MINI12864 with graphic controller and SD support +// http://reprap.org/wiki/MKS_MINI_12864 +// +//#define MKS_MINI_12864 + +// +// Factory display for Creality CR-10 +// https://www.aliexpress.com/item/Universal-LCD-12864-3D-Printer-Display-Screen-With-Encoder-For-CR-10-CR-7-Model/32833148327.html +// +// This is RAMPS-compatible using a single 10-pin connector. +// (For CR-10 owners who want to replace the Melzi Creality board but retain the display) +// +//#define CR10_STOCKDISPLAY + +// +// MKS OLED 1.3" 128 × 64 FULL GRAPHICS CONTROLLER +// http://reprap.org/wiki/MKS_12864OLED +// +// Tiny, but very sharp OLED display +// +//#define MKS_12864OLED + +//============================================================================= +//=============================== Extra Features ============================== +//============================================================================= + +// @section extras + +// Increase the FAN PWM frequency. Removes the PWM noise but increases heating in the FET/Arduino +#define FAST_PWM_FAN + +// Use software PWM to drive the fan, as for the heaters. This uses a very low frequency +// which is not as annoying as with the hardware PWM. On the other hand, if this frequency +// is too low, you should also increment SOFT_PWM_SCALE. +//#define FAN_SOFT_PWM + +// Incrementing this by 1 will double the software PWM frequency, +// affecting heaters, and the fan if FAN_SOFT_PWM is enabled. +// However, control resolution will be halved for each increment; +// at zero value, there are 128 effective control positions. +#define SOFT_PWM_SCALE 0 + +// If SOFT_PWM_SCALE is set to a value higher than 0, dithering can +// be used to mitigate the associated resolution loss. If enabled, +// some of the PWM cycles are stretched so on average the desired +// duty cycle is attained. +//#define SOFT_PWM_DITHER + +// Temperature status LEDs that display the hotend and bed temperature. +// If all hotends, bed temperature, and target temperature are under 54C +// then the BLUE led is on. Otherwise the RED led is on. (1C hysteresis) +//#define TEMP_STAT_LEDS + +// M240 Triggers a camera by emulating a Canon RC-1 Remote +// Data from: http://www.doc-diy.net/photo/rc-1_hacked/ +//#define PHOTOGRAPH_PIN 23 + +// 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 + +// Support for BlinkM/CyzRgb +//#define BLINKM + +// Support for PCA9632 PWM LED driver +//#define PCA9632 + +/** + * RGB LED / LED Strip Control + * + * Enable support for an RGB LED connected to 5V digital pins, or + * an RGB Strip connected to MOSFETs controlled by digital pins. + * + * 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 overall brightness parameters is also available + * + * *** CAUTION *** + * LED Strips require a MOFSET 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! + * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino + * cannot handle such current, separate 5V power supply must be used + * *** CAUTION *** + * + * LED type. This options are mutualy exclusive. Uncomment only one. + * + */ +//#define RGB_LED +//#define RGBW_LED + +#if ENABLED(RGB_LED) || ENABLED(RGBW_LED) + #define RGB_LED_R_PIN 34 + #define RGB_LED_G_PIN 43 + #define RGB_LED_B_PIN 35 + #define RGB_LED_W_PIN -1 +#endif + +// 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 (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) + #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip + #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time + #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + //#define NEOPIXEL_STARTUP_TEST // Cycle through colors at startup +#endif + +/** + * Printer Event LEDs + * + * During printing, the LEDs will reflect the printer status: + * + * - Gradually change from blue to violet as the heated bed gets to target temp + * - Gradually change from violet to red as the hotend gets to temperature + * - Change to white to illuminate work surface + * - Change to green once print has finished + * - Turn off after the print has finished and the user has pushed a button + */ +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) + #define PRINTER_EVENT_LEDS +#endif + +/*********************************************************************\ +* R/C SERVO support +* Sponsored by TrinityLabs, Reworked by codexmas +**********************************************************************/ + +// Number of servos +// +// If you select a configuration below, this will receive a default value and does not need to be set manually +// set it manually if you have more servos than extruders and wish to manually control some +// leaving it undefined or defining as 0 will disable the servo subsystem +// If unsure, leave commented / disabled +// +//#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command + +// Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. +// 300ms is a good value but you can try less delay. +// If the servo can't reach the requested position, increase it. +#define SERVO_DELAY { 300 } + +// Servo deactivation +// +// With this option servos are powered only during movement, then turned off to prevent jitter. +//#define DEACTIVATE_SERVOS_AFTER_MOVE + +/** + * Filament Width Sensor + * + * Measures the filament width in real-time and adjusts + * flow rate to compensate for any irregularities. + * + * Also allows the measured filament diameter to set the + * extrusion rate, so the slicer only has to specify the + * volume. + * + * Only a single extruder is supported at this time. + * + * 34 RAMPS_14 : Analog input 5 on the AUX2 connector + * 81 PRINTRBOARD : Analog input 2 on the Exp1 connector (version B,C,D,E) + * 301 RAMBO : Analog input 3 + * + * Note: May require analog pins to be defined for other boards. + */ +//#define FILAMENT_WIDTH_SENSOR + +#define DEFAULT_NOMINAL_FILAMENT_DIA 3.00 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. + +#if ENABLED(FILAMENT_WIDTH_SENSOR) + #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) + #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber + + #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading + #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading + #define MAX_MEASUREMENT_DELAY 20 // (bytes) Buffer size for stored measurements (1 byte per cm). Must be larger than MEASUREMENT_DELAY_CM. + + #define DEFAULT_MEASURED_FILAMENT_DIA DEFAULT_NOMINAL_FILAMENT_DIA // Set measured to nominal initially + + // Display filament width on the LCD status line. Status messages will expire after 5 seconds. + //#define FILAMENT_LCD_DISPLAY +#endif + +#endif // CONFIGURATION_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/Felix/Configuration_adv.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/Felix/Configuration_adv.h new file mode 100644 index 00000000..03ae2b21 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/Felix/Configuration_adv.h @@ -0,0 +1,1424 @@ +/** + * 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 . + * + */ + +/** + * Configuration_adv.h + * + * Advanced settings. + * Only change these if you know exactly what you're doing. + * Some of these settings can damage your printer if improperly set! + * + * Basic settings can be found in Configuration.h + * + */ +#ifndef CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H_VERSION 010100 + +// @section temperature + +//=========================================================================== +//=============================Thermal Settings ============================ +//=========================================================================== + +#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 + #endif +#endif + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * The solution: Once the temperature reaches the target, start observing. + * If the temperature stays too far below the target (hysteresis) for too long (period), + * the firmware will halt the machine as a safety precaution. + * + * If you get false positives for "Thermal Runaway" increase THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD + */ +#if ENABLED(THERMAL_PROTECTION_HOTENDS) + #define THERMAL_PROTECTION_PERIOD 40 // Seconds + #define THERMAL_PROTECTION_HYSTERESIS 4 // Degrees Celsius + + /** + * Whenever an M104 or M109 increases the target temperature the firmware will wait for the + * WATCH_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get false positives for "Heating failed" increase WATCH_TEMP_PERIOD and/or decrease WATCH_TEMP_INCREASE + * WATCH_TEMP_INCREASE should not be below 2. + */ + #define WATCH_TEMP_PERIOD 20 // Seconds + #define WATCH_TEMP_INCREASE 2 // Degrees Celsius +#endif + +/** + * Thermal Protection parameters for the bed are just as above for hotends. + */ +#if ENABLED(THERMAL_PROTECTION_BED) + #define THERMAL_PROTECTION_BED_PERIOD 20 // Seconds + #define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius + + /** + * Whenever an M140 or M190 increases the target temperature the firmware will wait for the + * WATCH_BED_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_BED_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get too many "Heating failed" errors, increase WATCH_BED_TEMP_PERIOD and/or decrease + * WATCH_BED_TEMP_INCREASE. (WATCH_BED_TEMP_INCREASE should not be below 2.) + */ + #define WATCH_BED_TEMP_PERIOD 60 // Seconds + #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius +#endif + +#if ENABLED(PIDTEMP) + // this adds an experimental additional term to the heating power, proportional to the extrusion speed. + // if Kc is chosen well, the additional required power due to increased melting should be compensated. + //#define PID_EXTRUSION_SCALING + #if ENABLED(PID_EXTRUSION_SCALING) + #define DEFAULT_Kc (100) //heating power=Kc*(e_speed) + #define LPQ_MAX_LEN 50 + #endif +#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 + */ +#define AUTOTEMP +#if ENABLED(AUTOTEMP) + #define AUTOTEMP_OLDWEIGHT 0.98 +#endif + +// Show Temperature ADC value +// Enable for M105 to include ADC values read from temperature sensors. +//#define SHOW_TEMP_ADC_VALUES + +/** + * High Temperature Thermistor Support + * + * Thermistors able to support high temperature tend to have a hard time getting + * good readings at room and lower temperatures. This means HEATER_X_RAW_LO_TEMP + * will probably be caught when the heating element first turns on during the + * preheating process, which will trigger a min_temp_error as a safety measure + * and force stop everything. + * To circumvent this limitation, we allow for a preheat time (during which, + * min_temp_error won't be triggered) and add a min_temp buffer to handle + * aberrant readings. + * + * If you want to enable this feature for your hotend thermistor(s) + * uncomment and set values > 0 in the constants below + */ + +// The number of consecutive low temperature errors that can occur +// before a min_temp_error is triggered. (Shouldn't be more than 10.) +//#define MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED 0 + +// The number of milliseconds a hotend will preheat before starting to check +// the temperature. This value should NOT be set to the time it takes the +// hot end to reach the target temperature, but the time it takes to reach +// the minimum temperature your thermistor can read. The lower the better/safer. +// This shouldn't need to be more than 30 seconds (30000) +//#define MILLISECONDS_PREHEAT_TIME 0 + +// @section extruder + +// Extruder runout prevention. +// If the machine is idle and the temperature over MINTEMP +// then extrude some filament every couple of SECONDS. +//#define EXTRUDER_RUNOUT_PREVENT +#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_EXTRUDE 5 // mm +#endif + +// @section temperature + +//These defines help to calibrate the AD595 sensor in case you get wrong temperature measurements. +//The measured temperature is defined as "actualTemp = (measuredTemp * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET" +#define TEMP_SENSOR_AD595_OFFSET 0.0 +#define TEMP_SENSOR_AD595_GAIN 1.0 + +/** + * 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. + */ +//#define USE_CONTROLLER_FAN +#if ENABLED(USE_CONTROLLER_FAN) + //#define CONTROLLER_FAN_PIN FAN1_PIN // 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 +#endif + +// When first starting the main fan, run it at full speed for the +// given number of milliseconds. This gets the fan spinning reliably +// before setting a PWM value. (Does not work with software PWM for fan on Sanguinololu) +//#define FAN_KICKSTART_TIME 100 + +// This defines the minimal speed for the main fan, run in PWM mode +// to enable uncomment and set minimal PWM speed for reliable running (1-255) +// if fan speed is [1 - (FAN_MIN_PWM-1)] it is set to FAN_MIN_PWM +//#define FAN_MIN_PWM 50 + +// @section extruder + +/** + * Extruder cooling fans + * + * Extruder auto fans automatically turn on when their extruders' + * temperatures go above EXTRUDER_AUTO_FAN_TEMPERATURE. + * + * Your board's pins file specifies the recommended pins. Override those here + * or set to -1 to disable completely. + * + * Multiple extruders can be assigned to the same pin in which case + * the fan will turn on when any selected extruder is above the threshold. + */ +#define E0_AUTO_FAN_PIN -1 +#define E1_AUTO_FAN_PIN -1 +#define E2_AUTO_FAN_PIN -1 +#define E3_AUTO_FAN_PIN -1 +#define E4_AUTO_FAN_PIN -1 +#define EXTRUDER_AUTO_FAN_TEMPERATURE 50 +#define EXTRUDER_AUTO_FAN_SPEED 255 // == full speed + +/** + * Part-Cooling Fan Multiplexer + * + * This feature allows you to digitally multiplex the fan output. + * The multiplexer is automatically switched at tool-change. + * Set FANMUX[012]_PINs below for up to 2, 4, or 8 multiplexed fans. + */ +#define FANMUX0_PIN -1 +#define FANMUX1_PIN -1 +#define FANMUX2_PIN -1 + +/** + * M355 Case Light on-off / brightness + */ +//#define CASE_LIGHT_ENABLE +#if ENABLED(CASE_LIGHT_ENABLE) + //#define CASE_LIGHT_PIN 4 // Override the default pin if needed + #define INVERT_CASE_LIGHT false // Set true if Case Light is ON when pin is LOW + #define CASE_LIGHT_DEFAULT_ON true // Set default power-up state on + #define CASE_LIGHT_DEFAULT_BRIGHTNESS 105 // Set default power-up brightness (0-255, requires PWM pin) + //#define MENU_ITEM_CASE_LIGHT // Add a Case Light option to the LCD main menu +#endif + +//=========================================================================== +//============================ Mechanical Settings ========================== +//=========================================================================== + +// @section homing + +// If you want endstops to stay on (by default) even when not homing +// enable this option. Override at any time with M120, M121. +//#define ENDSTOPS_ALWAYS_ON_DEFAULT + +// @section extras + +//#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. + +// Dual X Steppers +// Uncomment this option to drive two X axis motors. +// The next unused E driver will be assigned to the second X stepper. +//#define X_DUAL_STEPPER_DRIVERS +#if ENABLED(X_DUAL_STEPPER_DRIVERS) + // Set true if the two X motors need to rotate in opposite directions + #define INVERT_X2_VS_X_DIR true +#endif + +// Dual Y Steppers +// Uncomment this option to drive two Y axis motors. +// The next unused E driver will be assigned to the second Y stepper. +//#define Y_DUAL_STEPPER_DRIVERS +#if ENABLED(Y_DUAL_STEPPER_DRIVERS) + // Set true if the two Y motors need to rotate in opposite directions + #define INVERT_Y2_VS_Y_DIR true +#endif + +// A single Z stepper driver is usually used to drive 2 stepper motors. +// Uncomment this option to use a separate stepper driver for each Z axis motor. +// The next unused E driver will be assigned to the second Z stepper. +//#define Z_DUAL_STEPPER_DRIVERS + +#if ENABLED(Z_DUAL_STEPPER_DRIVERS) + + // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper. + // That way the machine is capable to align the bed during home, since both Z steppers are homed. + // There is also an implementation of M666 (software endstops adjustment) to this feature. + // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed. + // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2. + // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive. + // Play a little bit with small adjustments (0.5mm) and check the behaviour. + // The M119 (endstops report) will start reporting the Z2 Endstop as well. + + //#define Z_DUAL_ENDSTOPS + + #if ENABLED(Z_DUAL_ENDSTOPS) + #define Z2_USE_ENDSTOP _XMAX_ + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 // Use M666 to determine/test this value + #endif + +#endif // Z_DUAL_STEPPER_DRIVERS + +// Enable this for dual x-carriage printers. +// A dual x-carriage design has the advantage that the inactive extruder can be parked which +// prevents hot-end ooze contaminating the print. It also reduces the weight of each x-carriage +// allowing faster printing speeds. Connect your X2 stepper to the first unused E plug. +//#define DUAL_X_CARRIAGE +#if ENABLED(DUAL_X_CARRIAGE) + // Configuration for second X-carriage + // Note: the first x-carriage is defined as the x-carriage which homes to the minimum endstop; + // the second x-carriage always homes to the maximum endstop. + #define X2_MIN_POS 80 // set minimum to ensure second x-carriage doesn't hit the parked first X-carriage + #define X2_MAX_POS 353 // set maximum to the distance between toolheads when both heads are homed + #define X2_HOME_DIR 1 // the second X-carriage always homes to the maximum endstop position + #define X2_HOME_POS X2_MAX_POS // default home position is the maximum carriage position + // However: In this mode the HOTEND_OFFSET_X value for the second extruder provides a software + // override for X2_HOME_POS. This also allow recalibration of the distance between the two endstops + // without modifying the firmware (through the "M218 T1 X???" command). + // Remember: you should set the second extruder x-offset to 0 in your slicer. + + // There are a few selectable movement modes for dual x-carriages using M605 S + // Mode 0 (DXC_FULL_CONTROL_MODE): Full control. The slicer has full control over both x-carriages and can achieve optimal travel results + // as long as it supports dual x-carriages. (M605 S0) + // Mode 1 (DXC_AUTO_PARK_MODE) : Auto-park mode. The firmware will automatically park and unpark the x-carriages on tool changes so + // that additional slicer support is not required. (M605 S1) + // Mode 2 (DXC_DUPLICATION_MODE) : Duplication mode. The firmware will transparently make the second x-carriage and extruder copy all + // actions of the first x-carriage. This allows the printer to print 2 arbitrary items at + // once. (2nd extruder x offset and temp offset are set using: M605 S2 [Xnnn] [Rmmm]) + + // This is the default power-up mode which can be later using M605. + #define DEFAULT_DUAL_X_CARRIAGE_MODE DXC_FULL_CONTROL_MODE + + // Default settings in "Auto-park Mode" + #define TOOLCHANGE_PARK_ZLIFT 0.2 // the distance to raise Z axis when parking an extruder + #define TOOLCHANGE_UNPARK_ZLIFT 1 // the distance to raise Z axis when unparking an extruder + + // Default x offset in duplication mode (typically set to half print bed width) + #define DEFAULT_DUPLICATION_X_OFFSET 100 + +#endif // DUAL_X_CARRIAGE + +// 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. +//#define EXT_SOLENOID + +// @section homing + +//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +#define X_HOME_BUMP_MM 5 +#define Y_HOME_BUMP_MM 5 +#define Z_HOME_BUMP_MM 3 +#define HOMING_BUMP_DIVISOR {2, 2, 4} // Re-Bump Speed Divisor (Divides the Homing Feedrate) +//#define QUICK_HOME //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially. + +// When G28 is called, this option will make Y home before X +//#define HOME_Y_BEFORE_X + +// @section machine + +#define AXIS_RELATIVE_MODES {false, false, false, false} + +// Allow duplication mode with a basic dual-nozzle extruder +//#define DUAL_NOZZLE_DUPLICATION_MODE + +// By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step. +#define INVERT_X_STEP_PIN false +#define INVERT_Y_STEP_PIN false +#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. +#define DEFAULT_STEPPER_DEACTIVE_TIME 60 +#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_E true + +#define DEFAULT_MINIMUMFEEDRATE 0.0 // minimum feedrate +#define DEFAULT_MINTRAVELFEEDRATE 0.0 + +//#define HOME_AFTER_DEACTIVATE // Require rehoming after steppers are deactivated + +// @section lcd + +#if ENABLED(ULTIPANEL) + #define MANUAL_FEEDRATE {50*60, 50*60, 4*60, 60} // Feedrates for manual moves along X, Y, Z, E from panel + #define ULTIPANEL_FEEDMULTIPLY // Comment to disable setting feedrate multiplier via encoder +#endif + +// @section extras + +// minimum time in microseconds that a movement needs to take if the buffer is emptied. +#define DEFAULT_MINSEGMENTTIME 20000 + +// If defined the movements slow down when the look ahead buffer is only half full +#define SLOWDOWN + +// Frequency limit +// See nophead's blog for more info +// Not working O +//#define XY_FREQUENCY_LIMIT 15 + +// 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 +// if unwanted behavior is observed on a user's machine when running at very slow speeds. +#define MINIMUM_PLANNER_SPEED 0.05 // (mm/sec) + +// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU. +#define MICROSTEP_MODES {16,16,16,16,16} // [1,2,4,8,16] + +/** + * @section stepper motor current + * + * Some boards have a means of setting the stepper motor current via firmware. + * + * The power on motor currents are set by: + * PWM_MOTOR_CURRENT - used by MINIRAMBO & ULTIMAIN_2 + * known compatible chips: A4982 + * DIGIPOT_MOTOR_CURRENT - used by BQ_ZUM_MEGA_3D, RAMBO & SCOOVO_X9H + * known compatible chips: AD5206 + * DAC_MOTOR_CURRENT_DEFAULT - used by PRINTRBOARD_REVF & RIGIDBOARD_V2 + * known compatible chips: MCP4728 + * DIGIPOT_I2C_MOTOR_CURRENTS - used by 5DPRINT, AZTEEG_X3_PRO, MIGHTYBOARD_REVE + * known compatible chips: MCP4451, MCP4018 + * + * Motor currents can also be set by M907 - M910 and by the LCD. + * M907 - applies to all. + * M908 - BQ_ZUM_MEGA_3D, RAMBO, PRINTRBOARD_REVF, RIGIDBOARD_V2 & SCOOVO_X9H + * M909, M910 & LCD - only PRINTRBOARD_REVF & RIGIDBOARD_V2 + */ +//#define PWM_MOTOR_CURRENT { 1300, 1300, 1250 } // Values in milliamps +//#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 + +// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +//#define DIGIPOT_I2C +//#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster +#define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 +// Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS +#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=========================== +//=========================================================================== + +#define ENCODER_RATE_MULTIPLIER // If defined, certain menu edit operations automatically multiply the steps when the encoder is moved quickly +#define ENCODER_10X_STEPS_PER_SEC 75 // If the encoder steps per sec exceeds this value, multiply steps moved x10 to quickly advance the value +#define ENCODER_100X_STEPS_PER_SEC 160 // If the encoder steps per sec exceeds this value, multiply steps moved x100 to really quickly advance the value + +//#define CHDK 4 //Pin for triggering CHDK to take a picture see how to use it here http://captain-slow.dk/2014/03/09/3d-printing-timelapses/ +#define CHDK_DELAY 50 //How long in ms the pin should stay HIGH before going LOW again + +// @section lcd + +// Include a page of printer information in the LCD Main Menu +//#define LCD_INFO_MENU + +// Scroll a longer status message into view +//#define STATUS_MESSAGE_SCROLLING + +// On the Info Screen, display XY with one decimal place when possible +//#define LCD_DECIMAL_SMALL_XY + +// The timeout (in ms) to return to the status screen from sub-menus +//#define LCD_TIMEOUT_TO_STATUS 15000 + +#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 + + #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? + #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. + + #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. + // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. + // using: + //#define MENU_ADDAUTOSTART + + /** + * Sort SD file listings in alphabetical order. + * + * With this option enabled, items on SD cards will be sorted + * by name for easier navigation. + * + * By default... + * + * - Use the slowest -but safest- method for sorting. + * - Folders are sorted to the top. + * - The sort key is statically allocated. + * - No added G-code (M34) support. + * - 40 item sorting limit. (Items after the first 40 are unsorted.) + * + * SD sorting uses static allocation (as set by SDSORT_LIMIT), allowing the + * compiler to calculate the worst-case usage and throw an error if the SRAM + * limit is exceeded. + * + * - SDSORT_USES_RAM provides faster sorting via a static directory buffer. + * - SDSORT_USES_STACK does the same, but uses a local stack-based buffer. + * - SDSORT_CACHE_NAMES will retain the sorted file listing in RAM. (Expensive!) + * - SDSORT_DYNAMIC_RAM only uses RAM when the SD menu is visible. (Use with caution!) + */ + //#define SDCARD_SORT_ALPHA + + // SD Card Sorting options + #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_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. + #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #endif + + // Show a progress bar on HD44780 LCDs for SD printing + //#define LCD_PROGRESS_BAR + + #if ENABLED(LCD_PROGRESS_BAR) + // Amount of time (ms) to show the bar + #define PROGRESS_BAR_BAR_TIME 2000 + // Amount of time (ms) to show the status message + #define PROGRESS_BAR_MSG_TIME 3000 + // Amount of time (ms) to retain the status message (0=forever) + #define PROGRESS_MSG_EXPIRE 0 + // Enable this to show messages for MSG_TIME then hide them + //#define PROGRESS_MSG_ONCE + // Add a menu item to test the progress bar: + //#define LCD_PROGRESS_BAR_TEST + #endif + + // This allows hosts to request long names for files and folders with M33 + //#define LONG_FILENAME_HOST_SUPPORT + + // This option allows you to abort SD printing when any endstop is triggered. + // This feature must be enabled with "M540 S1" or from the LCD menu. + // To have any effect, endstops must be enabled during SD printing. + //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + +#endif // SDSUPPORT + +/** + * Additional options for Graphical Displays + * + * Use the optimizations here to improve printing performance, + * which can be adversely affected by graphical display drawing, + * especially when doing several short moves, and when printing + * on DELTA and SCARA machines. + * + * Some of these options may result in the display lagging behind + * controller events, as there is a trade-off between reliable + * printing performance versus fast display updates. + */ +#if ENABLED(DOGLCD) + // Enable to save many cycles by drawing a hollow frame on the Info Screen + #define XYZ_HOLLOW_FRAME + + // Enable to save many cycles by drawing a hollow frame on Menu Screens + #define MENU_HOLLOW_FRAME + + // A bigger font is available for edit items. Costs 3120 bytes of PROGMEM. + // 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. + // 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 +#endif // DOGLCD + +// @section safety + +// The hardware watchdog should reset the microcontroller disabling all outputs, +// in case the firmware gets stuck and doesn't do temperature regulation. +#define USE_WATCHDOG + +#if ENABLED(USE_WATCHDOG) + // If you have a watchdog reboot in an ArduinoMega2560 then the device will hang forever, as a watchdog reset will leave the watchdog on. + // The "WATCHDOG_RESET_MANUAL" goes around this by not using the hardware reset. + // However, THIS FEATURE IS UNSAFE!, as it will only work if interrupts are disabled. And the code could hang in an interrupt routine with interrupts disabled. + //#define WATCHDOG_RESET_MANUAL +#endif + +// @section lcd + +/** + * Babystepping enables movement of the axes by tiny increments without changing + * the current position values. This feature is used primarily to adjust the Z + * axis in the first layer of a print in real-time. + * + * Warning: Does not respect endstops! + */ +//#define BABYSTEPPING +#if ENABLED(BABYSTEPPING) + //#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 100 // Babysteps are very small. Increase for faster motion. + //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping + //#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen 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_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor + //#define BABYSTEP_ZPROBE_GFX_REVERSE // Reverses the direction of the CW/CCW indicators +#endif + +// @section extruder + +/** + * Implementation of linear pressure control + * + * Assumption: advance = k * (delta velocity) + * K=0 means advance disabled. + * See Marlin documentation for calibration instructions. + */ +//#define LIN_ADVANCE + +#if ENABLED(LIN_ADVANCE) + #define LIN_ADVANCE_K 75 + + /** + * Some Slicers produce Gcode with randomly jumping extrusion widths occasionally. + * For example within a 0.4mm perimeter it may produce a single segment of 0.05mm width. + * While this is harmless for normal printing (the fluid nature of the filament will + * close this very, very tiny gap), it throws off the LIN_ADVANCE pressure adaption. + * + * For this case LIN_ADVANCE_E_D_RATIO can be used to set the extrusion:distance ratio + * to a fixed value. Note that using a fixed ratio will lead to wrong nozzle pressures + * if the slicer is using variable widths or layer heights within one print! + * + * This option sets the default E:D ratio at startup. Use `M900` to override this value. + * + * Example: `M900 W0.4 H0.2 D1.75`, where: + * - W is the extrusion width in mm + * - H is the layer height in mm + * - D is the filament diameter in mm + * + * Example: `M900 R0.0458` to set the ratio directly. + * + * Set to 0 to auto-detect the ratio based on given Gcode G1 print moves. + * + * Slic3r (including Průša Control) produces Gcode compatible with the automatic mode. + * Cura (as of this writing) may produce Gcode incompatible with the automatic mode. + */ + #define LIN_ADVANCE_E_D_RATIO 0 // The calculated ratio (or 0) according to the formula W * H / ((D / 2) ^ 2 * PI) + // Example: 0.4 * 0.2 / ((1.75 / 2) ^ 2 * PI) = 0.033260135 +#endif + +// @section leveling + +// Default mesh area is an area with an inset margin on the print area. +// Below are the macros that are used to define the borders for the mesh area, +// made available here for specialized needs, ie dual extruder setup. +#if ENABLED(MESH_BED_LEVELING) + #define MESH_MIN_X MESH_INSET + #define MESH_MAX_X (X_BED_SIZE - (MESH_INSET)) + #define MESH_MIN_Y MESH_INSET + #define MESH_MAX_Y (Y_BED_SIZE - (MESH_INSET)) +#elif ENABLED(AUTO_BED_LEVELING_UBL) + #define UBL_MESH_MIN_X UBL_MESH_INSET + #define UBL_MESH_MAX_X (X_BED_SIZE - (UBL_MESH_INSET)) + #define UBL_MESH_MIN_Y UBL_MESH_INSET + #define UBL_MESH_MAX_Y (Y_BED_SIZE - (UBL_MESH_INSET)) + + // If this is defined, the currently active mesh will be saved in the + // current slot on M500. + #define UBL_SAVE_ACTIVE_ON_M500 +#endif + +// @section extras + +// +// G2/G3 Arc Support +// +#define ARC_SUPPORT // Disable this feature to save ~3226 bytes +#if ENABLED(ARC_SUPPORT) + #define MM_PER_ARC_SEGMENT 1 // Length of each arc segment + #define N_ARC_CORRECTION 25 // Number of intertpolated 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 +#endif + +// Support for G5 with XYZE destination and IJPQ offsets. Requires ~2666 bytes. +//#define BEZIER_CURVE_SUPPORT + +// G38.2 and G38.3 Probe Target +// Enable PROBE_DOUBLE_TOUCH if you want G38 to double touch +//#define G38_PROBE_TARGET +#if ENABLED(G38_PROBE_TARGET) + #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) +#endif + +// Moves (or segments) with fewer steps than this will be joined with the next move +#define MIN_STEPS_PER_SEGMENT 6 + +// The minimum pulse width (in µs) for stepping a stepper. +// Set this if you find stepping unreliable, or if using a very fast CPU. +#define MINIMUM_STEPPER_PULSE 0 // (µs) The smallest stepper pulse allowed + +// @section temperature + +// Control heater 0 and heater 1 in parallel. +//#define HEATERS_PARALLEL + +//=========================================================================== +//================================= Buffers ================================= +//=========================================================================== + +// @section hidden + +// 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, i.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 +#else + #define BLOCK_BUFFER_SIZE 16 // maximize block buffer +#endif + +// @section serial + +// The ASCII buffer for serial input +#define MAX_CMD_SIZE 96 +#define BUFSIZE 4 + +// Transmission to Host Buffer Size +// To save 386 bytes of PROGMEM (and TX_BUFFER_SIZE+3 bytes of RAM) set to 0. +// To buffer a simple "ok" you need 4 bytes. +// For ADVANCED_OK (M105) you need 32 bytes. +// For debug-echo: 128 bytes for the optimal speed. +// Other output doesn't need to be that speedy. +// :[0, 2, 4, 8, 16, 32, 64, 128, 256] +#define TX_BUFFER_SIZE 0 + +// Host Receive Buffer Size +// Without XON/XOFF flow control (see SERIAL_XON_XOFF below) 32 bytes should be enough. +// To use flow control, set this buffer size to at least 1024 bytes. +// :[0, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048] +//#define RX_BUFFER_SIZE 1024 + +#if RX_BUFFER_SIZE >= 1024 + // Enable to have the controller send XON/XOFF control characters to + // the host to signal the RX buffer is becoming full. + //#define SERIAL_XON_XOFF +#endif + +#if ENABLED(SDSUPPORT) + // Enable this option to collect and display the maximum + // RX queue usage after transferring a file to SD. + //#define SERIAL_STATS_MAX_RX_QUEUED + + // Enable this option to collect and display the number + // of dropped bytes after a file transfer to SD. + //#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! +//#define EMERGENCY_PARSER + +// Bad Serial-connections can miss a received command by sending an 'ok' +// Therefore some clients abort after 30 seconds in a timeout. +// Some other clients start sending commands while receiving a 'wait'. +// This "wait" is only sent when the buffer is empty. 1 second is a good value here. +//#define NO_TIMEOUTS 1000 // Milliseconds + +// Some clients will have this feature soon. This could make the NO_TIMEOUTS unnecessary. +//#define ADVANCED_OK + +// @section extras + +/** + * Firmware-based and LCD-controlled retract + * + * Add G10 / G11 commands for automatic firmware-based retract / recover. + * Use M207 and M208 to define parameters for retract / recover. + * + * Use M209 to enable or disable auto-retract. + * With auto-retract enabled, all G1 E moves within the set range + * will be converted to firmware-based retract/recover moves. + * + * Be sure to turn off auto-retract during filament change. + * + * Note that M207 / M208 / M209 settings are saved to EEPROM. + * + */ +//#define FWRETRACT // ONLY PARTIALLY TESTED +#if ENABLED(FWRETRACT) + #define MIN_AUTORETRACT 0.1 // When auto-retract is on, convert E moves of this length and over + #define MAX_AUTORETRACT 10.0 // Upper limit for auto-retract conversion + #define RETRACT_LENGTH 3 // Default retract length (positive mm) + #define RETRACT_LENGTH_SWAP 13 // Default swap retract length (positive mm), for extruder change + #define RETRACT_FEEDRATE 45 // Default feedrate for retracting (mm/s) + #define RETRACT_ZLIFT 0 // Default retract Z-lift + #define RETRACT_RECOVER_LENGTH 0 // Default additional recover length (mm, added to retract length when recovering) + #define RETRACT_RECOVER_LENGTH_SWAP 0 // Default additional swap recover length (mm, added to retract length when recovering from extruder change) + #define RETRACT_RECOVER_FEEDRATE 8 // Default feedrate for recovering from retraction (mm/s) + #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) +#endif + +/** + * Advanced Pause + * Experimental feature for filament change support and for parking the nozzle when paused. + * Adds the GCode M600 for initiating filament change. + * If PARK_HEAD_ON_PAUSE enabled, adds the GCode M125 to pause printing and park the nozzle. + * + * Requires an LCD display. + * This feature is required for the default FILAMENT_RUNOUT_SCRIPT. + */ +//#define ADVANCED_PAUSE_FEATURE +#if ENABLED(ADVANCED_PAUSE_FEATURE) + #define PAUSE_PARK_X_POS 3 // X position of hotend + #define PAUSE_PARK_Y_POS 3 // Y position of hotend + #define PAUSE_PARK_Z_ADD 10 // Z addition of hotend (lift) + #define PAUSE_PARK_XY_FEEDRATE 100 // X and Y axes feedrate in mm/s (also used for delta printers Z axis) + #define PAUSE_PARK_Z_FEEDRATE 5 // Z axis feedrate in mm/s (not used for delta printers) + #define PAUSE_PARK_RETRACT_FEEDRATE 60 // Initial retract feedrate in mm/s + #define PAUSE_PARK_RETRACT_LENGTH 2 // Initial retract in mm + // It is a short retract used immediately after print interrupt before move to filament exchange position + #define FILAMENT_CHANGE_UNLOAD_FEEDRATE 10 // Unload filament feedrate in mm/s - filament unloading can be fast + #define FILAMENT_CHANGE_UNLOAD_LENGTH 100 // Unload filament length from hotend in mm + // Longer length for bowden printers to unload filament from whole bowden tube, + // shorter length for printers without bowden to unload filament from extruder only, + // 0 to disable unloading for manual unloading + #define FILAMENT_CHANGE_LOAD_FEEDRATE 6 // Load filament feedrate in mm/s - filament loading into the bowden tube can be fast + #define FILAMENT_CHANGE_LOAD_LENGTH 0 // Load filament length over hotend in mm + // Longer length for bowden printers to fast load filament into whole bowden tube over the hotend, + // Short or zero length for printers without bowden where loading is not used + #define ADVANCED_PAUSE_EXTRUDE_FEEDRATE 3 // Extrude filament feedrate in mm/s - must be slower than load feedrate + #define ADVANCED_PAUSE_EXTRUDE_LENGTH 50 // Extrude filament length in mm after filament is loaded over the hotend, + // 0 to disable for manual extrusion + // Filament can be extruded repeatedly from the filament exchange menu to fill the hotend, + // or until outcoming filament color is not clear for filament color change + #define PAUSE_PARK_NOZZLE_TIMEOUT 45 // Turn off nozzle if user doesn't change filament within this time limit in seconds + #define FILAMENT_CHANGE_NUMBER_OF_ALERT_BEEPS 5 // Number of alert beeps before printer goes quiet + #define PAUSE_PARK_NO_STEPPER_TIMEOUT // Enable to have stepper motors hold position during filament change + // even if it takes longer than DEFAULT_STEPPER_DEACTIVE_TIME. + //#define PARK_HEAD_ON_PAUSE // Go to filament change position on pause, return to print position on resume + //#define HOME_BEFORE_FILAMENT_CHANGE // Ensure homing has been completed prior to parking for filament change +#endif + +// @section tmc + +/** + * Enable this section if you have TMC26X motor drivers. + * You will need to import the TMC26XStepper library into the Arduino IDE for this + * (https://github.com/trinamic/TMC26XStepper.git) + */ +//#define HAVE_TMCDRIVER + +#if ENABLED(HAVE_TMCDRIVER) + + //#define X_IS_TMC + //#define X2_IS_TMC + //#define Y_IS_TMC + //#define Y2_IS_TMC + //#define Z_IS_TMC + //#define Z2_IS_TMC + //#define E0_IS_TMC + //#define E1_IS_TMC + //#define E2_IS_TMC + //#define E3_IS_TMC + //#define E4_IS_TMC + + #define X_MAX_CURRENT 1000 // in mA + #define X_SENSE_RESISTOR 91 // in mOhms + #define X_MICROSTEPS 16 // number of microsteps + + #define X2_MAX_CURRENT 1000 + #define X2_SENSE_RESISTOR 91 + #define X2_MICROSTEPS 16 + + #define Y_MAX_CURRENT 1000 + #define Y_SENSE_RESISTOR 91 + #define Y_MICROSTEPS 16 + + #define Y2_MAX_CURRENT 1000 + #define Y2_SENSE_RESISTOR 91 + #define Y2_MICROSTEPS 16 + + #define Z_MAX_CURRENT 1000 + #define Z_SENSE_RESISTOR 91 + #define Z_MICROSTEPS 16 + + #define Z2_MAX_CURRENT 1000 + #define Z2_SENSE_RESISTOR 91 + #define Z2_MICROSTEPS 16 + + #define E0_MAX_CURRENT 1000 + #define E0_SENSE_RESISTOR 91 + #define E0_MICROSTEPS 16 + + #define E1_MAX_CURRENT 1000 + #define E1_SENSE_RESISTOR 91 + #define E1_MICROSTEPS 16 + + #define E2_MAX_CURRENT 1000 + #define E2_SENSE_RESISTOR 91 + #define E2_MICROSTEPS 16 + + #define E3_MAX_CURRENT 1000 + #define E3_SENSE_RESISTOR 91 + #define E3_MICROSTEPS 16 + + #define E4_MAX_CURRENT 1000 + #define E4_SENSE_RESISTOR 91 + #define E4_MICROSTEPS 16 + +#endif + +// @section TMC2130 + +/** + * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. + * + * You'll also need the TMC2130Stepper Arduino library + * (https://github.com/teemuatlut/TMC2130Stepper). + * + * To use TMC2130 stepper drivers in SPI mode connect your SPI2130 pins to + * the hardware SPI interface on your board and define the required CS pins + * in your `pins_MYBOARD.h` file. (e.g., RAMPS 1.4 uses AUX3 pins `X_CS_PIN 53`, `Y_CS_PIN 49`, etc.). + */ +//#define HAVE_TMC2130 + +#if ENABLED(HAVE_TMC2130) + + // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY + //#define X_IS_TMC2130 + //#define X2_IS_TMC2130 + //#define Y_IS_TMC2130 + //#define Y2_IS_TMC2130 + //#define Z_IS_TMC2130 + //#define Z2_IS_TMC2130 + //#define E0_IS_TMC2130 + //#define E1_IS_TMC2130 + //#define E2_IS_TMC2130 + //#define E3_IS_TMC2130 + //#define E4_IS_TMC2130 + + /** + * Stepper driver settings + */ + + #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 + #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current + #define INTERPOLATE 1 // Interpolate X/Y/Z_MICROSTEPS to 256 + + #define X_CURRENT 1000 // rms current in mA. Multiply by 1.41 for peak current. + #define X_MICROSTEPS 16 // 0..256 + + #define Y_CURRENT 1000 + #define Y_MICROSTEPS 16 + + #define Z_CURRENT 1000 + #define Z_MICROSTEPS 16 + + //#define X2_CURRENT 1000 + //#define X2_MICROSTEPS 16 + + //#define Y2_CURRENT 1000 + //#define Y2_MICROSTEPS 16 + + //#define Z2_CURRENT 1000 + //#define Z2_MICROSTEPS 16 + + //#define E0_CURRENT 1000 + //#define E0_MICROSTEPS 16 + + //#define E1_CURRENT 1000 + //#define E1_MICROSTEPS 16 + + //#define E2_CURRENT 1000 + //#define E2_MICROSTEPS 16 + + //#define E3_CURRENT 1000 + //#define E3_MICROSTEPS 16 + + //#define E4_CURRENT 1000 + //#define E4_MICROSTEPS 16 + + /** + * Use Trinamic's ultra quiet stepping mode. + * When disabled, Marlin will use spreadCycle stepping mode. + */ + #define STEALTHCHOP + + /** + * Let Marlin automatically control stepper current. + * This is still an experimental feature. + * Increase current every 5s by CURRENT_STEP until stepper temperature prewarn gets triggered, + * then decrease current by CURRENT_STEP until temperature prewarn is cleared. + * Adjusting starts from X/Y/Z/E_CURRENT but will not increase over AUTO_ADJUST_MAX + * 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. + * M906 S1 - Start adjusting current + * M906 S0 - Stop adjusting current + * M911 - Report stepper driver overtemperature pre-warn condition. + * M912 - Clear stepper driver overtemperature pre-warn condition flag. + */ + //#define AUTOMATIC_CURRENT_CONTROL + + #if ENABLED(AUTOMATIC_CURRENT_CONTROL) + #define CURRENT_STEP 50 // [mA] + #define AUTO_ADJUST_MAX 1300 // [mA], 1300mA_rms = 1840mA_peak + #define REPORT_CURRENT_CHANGE + #endif + + /** + * The driver will switch to spreadCycle when stepper speed is over HYBRID_THRESHOLD. + * This mode allows for faster movements at the expense of higher noise levels. + * STEALTHCHOP needs to be enabled. + * M913 X/Y/Z/E to live tune the setting + */ + //#define HYBRID_THRESHOLD + + #define X_HYBRID_THRESHOLD 100 // [mm/s] + #define X2_HYBRID_THRESHOLD 100 + #define Y_HYBRID_THRESHOLD 100 + #define Y2_HYBRID_THRESHOLD 100 + #define Z_HYBRID_THRESHOLD 4 + #define Z2_HYBRID_THRESHOLD 4 + #define E0_HYBRID_THRESHOLD 30 + #define E1_HYBRID_THRESHOLD 30 + #define E2_HYBRID_THRESHOLD 30 + #define E3_HYBRID_THRESHOLD 30 + #define E4_HYBRID_THRESHOLD 30 + + /** + * Use stallGuard2 to sense an obstacle and trigger an endstop. + * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. + * If used along with STEALTHCHOP, the movement will be louder when homing. This is normal. + * + * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. + * Higher values make the system LESS sensitive. + * Lower value make the system MORE sensitive. + * Too low values can lead to false positives, while too high values will collide the axis without triggering. + * It is advised to set X/Y_HOME_BUMP_MM to 0. + * M914 X/Y to live tune the setting + */ + //#define SENSORLESS_HOMING + + #if ENABLED(SENSORLESS_HOMING) + #define X_HOMING_SENSITIVITY 19 + #define Y_HOMING_SENSITIVITY 19 + #endif + + /** + * You can set your own advanced settings by filling in predefined functions. + * A list of available functions can be found on the library github page + * https://github.com/teemuatlut/TMC2130Stepper + * + * Example: + * #define TMC2130_ADV() { \ + * stepperX.diag0_temp_prewarn(1); \ + * stepperX.interpolate(0); \ + * } + */ + #define TMC2130_ADV() { } + +#endif // HAVE_TMC2130 + +// @section L6470 + +/** + * Enable this section if you have L6470 motor drivers. + * You need to import the L6470 library into the Arduino IDE for this. + * (https://github.com/ameyer/Arduino-L6470) + */ + +//#define HAVE_L6470DRIVER +#if ENABLED(HAVE_L6470DRIVER) + + //#define X_IS_L6470 + //#define X2_IS_L6470 + //#define Y_IS_L6470 + //#define Y2_IS_L6470 + //#define Z_IS_L6470 + //#define Z2_IS_L6470 + //#define E0_IS_L6470 + //#define E1_IS_L6470 + //#define E2_IS_L6470 + //#define E3_IS_L6470 + //#define E4_IS_L6470 + + #define X_MICROSTEPS 16 // number of microsteps + #define X_K_VAL 50 // 0 - 255, Higher values, are higher power. Be careful not to go too high + #define X_OVERCURRENT 2000 // maxc current in mA. If the current goes over this value, the driver will switch off + #define X_STALLCURRENT 1500 // current in mA where the driver will detect a stall + + #define X2_MICROSTEPS 16 + #define X2_K_VAL 50 + #define X2_OVERCURRENT 2000 + #define X2_STALLCURRENT 1500 + + #define Y_MICROSTEPS 16 + #define Y_K_VAL 50 + #define Y_OVERCURRENT 2000 + #define Y_STALLCURRENT 1500 + + #define Y2_MICROSTEPS 16 + #define Y2_K_VAL 50 + #define Y2_OVERCURRENT 2000 + #define Y2_STALLCURRENT 1500 + + #define Z_MICROSTEPS 16 + #define Z_K_VAL 50 + #define Z_OVERCURRENT 2000 + #define Z_STALLCURRENT 1500 + + #define Z2_MICROSTEPS 16 + #define Z2_K_VAL 50 + #define Z2_OVERCURRENT 2000 + #define Z2_STALLCURRENT 1500 + + #define E0_MICROSTEPS 16 + #define E0_K_VAL 50 + #define E0_OVERCURRENT 2000 + #define E0_STALLCURRENT 1500 + + #define E1_MICROSTEPS 16 + #define E1_K_VAL 50 + #define E1_OVERCURRENT 2000 + #define E1_STALLCURRENT 1500 + + #define E2_MICROSTEPS 16 + #define E2_K_VAL 50 + #define E2_OVERCURRENT 2000 + #define E2_STALLCURRENT 1500 + + #define E3_MICROSTEPS 16 + #define E3_K_VAL 50 + #define E3_OVERCURRENT 2000 + #define E3_STALLCURRENT 1500 + + #define E4_MICROSTEPS 16 + #define E4_K_VAL 50 + #define E4_OVERCURRENT 2000 + #define E4_STALLCURRENT 1500 + +#endif + +/** + * TWI/I2C BUS + * + * This feature is an EXPERIMENTAL feature so it shall not be used on production + * machines. Enabling this will allow you to send and receive I2C data from slave + * devices on the bus. + * + * ; Example #1 + * ; This macro send the string "Marlin" to the slave device with address 0x63 (99) + * ; It uses multiple M260 commands with one B arg + * M260 A99 ; Target slave address + * M260 B77 ; M + * M260 B97 ; a + * M260 B114 ; r + * M260 B108 ; l + * M260 B105 ; i + * M260 B110 ; n + * M260 S1 ; Send the current buffer + * + * ; Example #2 + * ; Request 6 bytes from slave device with address 0x63 (99) + * M261 A99 B5 + * + * ; Example #3 + * ; Example serial output of a M261 request + * echo:i2c-reply: from:99 bytes:5 data:hello + */ + +// @section i2cbus + +//#define EXPERIMENTAL_I2CBUS +#define I2C_SLAVE_ADDRESS 0 // Set a value from 8 to 127 to act as a slave + +// @section extras + +/** + * Spindle & Laser control + * + * Add the M3, M4, and M5 commands to turn the spindle/laser on and off, and + * to set spindle speed, spindle direction, and laser power. + * + * SuperPid is a router/spindle speed controller used in the CNC milling community. + * Marlin can be used to turn the spindle on and off. It can also be used to set + * the spindle speed from 5,000 to 30,000 RPM. + * + * 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. + */ +//#define SPINDLE_LASER_ENABLE +#if ENABLED(SPINDLE_LASER_ENABLE) + + #define SPINDLE_LASER_ENABLE_INVERT false // set to "true" if the on/off function is reversed + #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 // delay in milliseconds to allow the spindle/laser to come up to speed/power + #define SPINDLE_LASER_POWERDOWN_DELAY 5000 // delay in milliseconds to allow the spindle to stop + #define SPINDLE_DIR_CHANGE true // set to true if your spindle controller supports changing spindle direction + #define SPINDLE_INVERT_DIR false + #define SPINDLE_STOP_ON_DIR_CHANGE true // set to true if Marlin should stop the spindle before changing rotation direction + + /** + * The M3 & M4 commands use the following equation to convert PWM duty cycle to speed/power + * + * SPEED/POWER = PWM duty cycle * SPEED_POWER_SLOPE + SPEED_POWER_INTERCEPT + * where PWM duty cycle varies from 0 to 255 + * + * set the following for your controller (ALL MUST BE SET) + */ + + #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_SLOPE 0.3922 + //#define SPEED_POWER_INTERCEPT 0 + //#define SPEED_POWER_MIN 10 + //#define SPEED_POWER_MAX 100 // 0-100% +#endif + +/** + * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins + */ +//#define PINS_DEBUGGING + +/** + * Auto-report temperatures with M155 S + */ +#define AUTO_REPORT_TEMPERATURES + +/** + * Include capabilities in M115 output + */ +#define EXTENDED_CAPABILITIES_REPORT + +/** + * Volumetric extrusion default state + * 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. + */ +//#define VOLUMETRIC_DEFAULT_ON + +/** + * Enable this option for a leaner build of Marlin that removes all + * workspace offsets, simplifying coordinate transformations, leveling, etc. + * + * - M206 and M428 are disabled. + * - G92 will revert to its behavior from Marlin 1.0. + */ +//#define NO_WORKSPACE_OFFSETS + +/** + * 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. + * + * For clients that use a fixed-width font (like OctoPrint), leave this set to 1.0. + * Otherwise, adjust according to your client and font. + */ +#define PROPORTIONAL_FONT_RATIO 1.0 + +/** + * Spend 28 bytes of SRAM to optimize the GCode parser + */ +#define FASTER_GCODE_PARSER + +/** + * User-defined menu items that execute custom GCode + */ +//#define CUSTOM_USER_MENUS +#if ENABLED(CUSTOM_USER_MENUS) + #define USER_SCRIPT_DONE "M117 User Script Done" + #define USER_SCRIPT_AUDIBLE_FEEDBACK + //#define USER_SCRIPT_RETURN // Return to status screen after a script + + #define USER_DESC_1 "Home & UBL Info" + #define USER_GCODE_1 "G28\nG29 W" + + #define USER_DESC_2 "Preheat for PLA" + #define USER_GCODE_2 "M140 S" STRINGIFY(PREHEAT_1_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND) + + #define USER_DESC_3 "Preheat for ABS" + #define USER_GCODE_3 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND) + + #define USER_DESC_4 "Heat Bed/Home/Level" + #define USER_GCODE_4 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nG28\nG29" + + //#define USER_DESC_5 "Home & Info" + //#define USER_GCODE_5 "G28\nM503" +#endif + +/** + * Specify an action command to send to the host when the printer is killed. + * Will be sent in the form '//action:ACTION_ON_KILL', e.g. '//action:poweroff'. + * The host must be configured to handle the action command. + */ +//#define ACTION_ON_KILL "poweroff" + +//=========================================================================== +//====================== I2C Position Encoder Settings ====================== +//=========================================================================== + +/** + * I2C position encoders for closed loop control. + * Developed by Chris Barr at Aus3D. + * + * Wiki: http://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/ + * + * Reilabuild encoders have been modified to improve reliability. + */ + +//#define I2C_POSITION_ENCODERS +#if ENABLED(I2C_POSITION_ENCODERS) + + #define I2CPE_ENCODER_CNT 1 // The number of encoders installed; max of 5 + // encoders supported currently. + + #define I2CPE_ENC_1_ADDR I2CPE_PRESET_ADDR_X // I2C address of the encoder. 30-200. + #define I2CPE_ENC_1_AXIS X_AXIS // Axis the encoder module is installed on. _AXIS. + #define I2CPE_ENC_1_TYPE I2CPE_ENC_TYPE_LINEAR // Type of encoder: I2CPE_ENC_TYPE_LINEAR -or- + // I2CPE_ENC_TYPE_ROTARY. + #define I2CPE_ENC_1_TICKS_UNIT 2048 // 1024 for magnetic strips with 2mm poles; 2048 for + // 1mm poles. For linear encoders this is ticks / mm, + // for rotary encoders this is ticks / revolution. + //#define I2CPE_ENC_1_TICKS_REV (16 * 200) // Only needed for rotary encoders; number of stepper + // steps per full revolution (motor steps/rev * microstepping) + //#define I2CPE_ENC_1_INVERT // Invert the direction of axis travel. + #define I2CPE_ENC_1_EC_METHOD I2CPE_ECM_NONE // Type of error error correction. + #define I2CPE_ENC_1_EC_THRESH 0.10 // Threshold size for error (in mm) above which the + // printer will attempt to correct the error; errors + // smaller than this are ignored to minimize effects of + // measurement noise / latency (filter). + + #define I2CPE_ENC_2_ADDR I2CPE_PRESET_ADDR_Y // Same as above, but for encoder 2. + #define I2CPE_ENC_2_AXIS Y_AXIS + #define I2CPE_ENC_2_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_ENC_2_TICKS_UNIT 2048 + //#define I2CPE_ENC_2_TICKS_REV (16 * 200) + //#define I2CPE_ENC_2_INVERT + #define I2CPE_ENC_2_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_ENC_2_EC_THRESH 0.10 + + #define I2CPE_ENC_3_ADDR I2CPE_PRESET_ADDR_Z // Encoder 3. Add additional configuration options + #define I2CPE_ENC_3_AXIS Z_AXIS // as above, or use defaults below. + + #define I2CPE_ENC_4_ADDR I2CPE_PRESET_ADDR_E // Encoder 4. + #define I2CPE_ENC_4_AXIS E_AXIS + + #define I2CPE_ENC_5_ADDR 34 // Encoder 5. + #define I2CPE_ENC_5_AXIS E_AXIS + + // Default settings for encoders which are enabled, but without settings configured above. + #define I2CPE_DEF_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_DEF_ENC_TICKS_UNIT 2048 + #define I2CPE_DEF_TICKS_REV (16 * 200) + #define I2CPE_DEF_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_DEF_EC_THRESH 0.1 + + //#define I2CPE_ERR_THRESH_ABORT 100.0 // Threshold size for error (in mm) error on any given + // axis after which the printer will abort. Comment out to + // disable abort behaviour. + + #define I2CPE_TIME_TRUSTED 10000 // After an encoder fault, there must be no further fault + // for this amount of time (in ms) before the encoder + // is trusted again. + + /** + * Position is checked every time a new command is executed from the buffer but during long moves, + * this setting determines the minimum update time between checks. A value of 100 works well with + * error rolling average when attempting to correct only for skips and not for vibration. + */ + #define I2CPE_MIN_UPD_TIME_MS 100 // Minimum time in miliseconds between encoder checks. + + // Use a rolling average to identify persistant errors that indicate skips, as opposed to vibration and noise. + #define I2CPE_ERR_ROLLING_AVERAGE + +#endif // I2C_POSITION_ENCODERS + +/** + * MAX7219 Debug Matrix + * + * Add support for a low-cost 8x8 LED Matrix based on the Max7219 chip, which can be used as a status + * display. Requires 3 signal wires. Some useful debug options are included to demonstrate its usage. + * + * Fully assembled MAX7219 boards can be found on the internet for under $2(US). + * For example, see https://www.ebay.com/sch/i.html?_nkw=332349290049 + */ +//#define MAX7219_DEBUG +#if ENABLED(MAX7219_DEBUG) + #define MAX7219_CLK_PIN 64 // 77 on Re-ARM // Configuration of the 3 pins to control the display + #define MAX7219_DIN_PIN 57 // 78 on Re-ARM + #define MAX7219_LOAD_PIN 44 // 79 on Re-ARM + + /** + * Sample debug features + * If you add more debug displays, be careful to avoid conflicts! + */ + #define MAX7219_DEBUG_PRINTER_ALIVE // Blink corner LED of 8x8 matrix to show that the firmware is functioning + #define MAX7219_DEBUG_STEPPER_HEAD 3 // Show the stepper queue head position on this and the next LED matrix row + #define MAX7219_DEBUG_STEPPER_TAIL 5 // Show the stepper queue tail position on this and the next LED matrix row + + #define MAX7219_DEBUG_STEPPER_QUEUE 0 // Show the current stepper queue depth on this and the next LED matrix row + // If you experience stuttering, reboots, etc. this option can reveal how + // tweaks made to the configuration are affecting the printer in real-time. +#endif + +#endif // CONFIGURATION_ADV_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/Felix/DUAL/Configuration.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/Felix/DUAL/Configuration.h new file mode 100644 index 00000000..ae090bda --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/Felix/DUAL/Configuration.h @@ -0,0 +1,1682 @@ +/** + * 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 . + * + */ + +/** + * Configuration.h + * + * Basic settings such as: + * + * - Type of electronics + * - Type of temperature sensor + * - Printer geometry + * - Endstop configuration + * - LCD controller + * - Extra features + * + * Advanced settings can be found in Configuration_adv.h + * + */ +#ifndef CONFIGURATION_H +#define CONFIGURATION_H +#define CONFIGURATION_H_VERSION 010100 + +//=========================================================================== +//============================= Getting Started ============================= +//=========================================================================== + +/** + * Here are some standard links for getting your machine calibrated: + * + * http://reprap.org/wiki/Calibration + * http://youtu.be/wAL9d7FgInk + * http://calculator.josefprusa.cz + * http://reprap.org/wiki/Triffid_Hunter%27s_Calibration_Guide + * http://www.thingiverse.com/thing:5573 + * https://sites.google.com/site/repraplogphase/calibration-of-your-reprap + * http://www.thingiverse.com/thing:298812 + */ + +//=========================================================================== +//============================= DELTA Printer =============================== +//=========================================================================== +// For a Delta printer start with one of the configuration files in the +// example_configurations/delta directory and customize for your machine. +// + +//=========================================================================== +//============================= SCARA Printer =============================== +//=========================================================================== +// For a SCARA printer start with the configuration files in +// example_configurations/SCARA and customize for your machine. +// + +// @section info + +// User-specified version info of this build to display in [Pronterface, etc] terminal window during +// startup. Implementation of an idea by Prof Braino to inform user that any changes made to this +// build by the user have been successfully uploaded into firmware. +#define STRING_CONFIG_H_AUTHOR "(none, Felix/DUAL)" // Who made the changes. +#define SHOW_BOOTSCREEN +#define STRING_SPLASH_LINE1 SHORT_BUILD_VERSION // will be shown during bootup in line 1 +#define STRING_SPLASH_LINE2 WEBSITE_URL // will be shown during bootup in line 2 + +// +// *** VENDORS PLEASE READ ***************************************************** +// +// Marlin now allow you to have a vendor boot image to be displayed on machine +// start. When SHOW_CUSTOM_BOOTSCREEN is defined Marlin will first show your +// custom boot image and then the default Marlin boot image is shown. +// +// We suggest for you to take advantage of this new feature and keep the Marlin +// boot image unmodified. For an example have a look at the bq Hephestos 2 +// example configuration folder. +// +//#define SHOW_CUSTOM_BOOTSCREEN +// @section machine + +/** + * Select which serial port on the board will be used for communication with the host. + * This allows the connection of wireless adapters (for instance) to non-default port pins. + * Serial port 0 is always used by the Arduino bootloader regardless of this setting. + * + * :[0, 1, 2, 3, 4, 5, 6, 7] + */ +#define SERIAL_PORT 0 + +/** + * This setting determines the communication speed of the printer. + * + * 250000 works in most cases, but you might try a lower speed if + * you commonly experience drop-outs during host printing. + * You may try up to 1000000 to speed up SD file transfer. + * + * :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000] + */ +#define BAUDRATE 250000 + +// Enable the Bluetooth serial interface on AT90USB devices +//#define BLUETOOTH + +// The following define selects which electronics board you have. +// Please choose the name from boards.h that matches your setup +#ifndef MOTHERBOARD + #define MOTHERBOARD BOARD_FELIX2 +#endif + +// Optional custom name for your RepStrap or other custom machine +// Displayed in the LCD "Ready" message +#define CUSTOM_MACHINE_NAME "Felix Dual" + +// Define this to set a unique identifier for this printer, (Used by some programs to differentiate between machines) +// You can use an online service to generate a random UUID. (eg http://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] +#define EXTRUDERS 2 + +// For Cyclops or any "multi-extruder" that shares a single nozzle. +//#define SINGLENOZZLE + +/** + * Průša MK2 Single Nozzle Multi-Material Multiplexer, and variants. + * + * This device allows one stepper driver on a control board to drive + * two to eight stepper motors, one at a time, in a manner suitable + * for extruders. + * + * This option only allows the multiplexer to switch on tool-change. + * Additional options to configure custom E moves are pending. + */ +//#define MK2_MULTIPLEXER +#if ENABLED(MK2_MULTIPLEXER) + // Override the default DIO selector pins here, if needed. + // Some pins files may provide defaults for these pins. + //#define E_MUX0_PIN 40 // Always Required + //#define E_MUX1_PIN 42 // Needed for 3 to 8 steppers + //#define E_MUX2_PIN 44 // Needed for 5 to 8 steppers +#endif + +// A dual extruder that uses a single stepper motor +//#define SWITCHING_EXTRUDER +#if ENABLED(SWITCHING_EXTRUDER) + #define SWITCHING_EXTRUDER_SERVO_NR 0 + #define SWITCHING_EXTRUDER_SERVO_ANGLES { 0, 90 } // Angles for E0, E1[, E2, E3] + #if EXTRUDERS > 3 + #define SWITCHING_EXTRUDER_E23_SERVO_NR 1 + #endif +#endif + +// A dual-nozzle that uses a servomotor to raise/lower one of the nozzles +//#define SWITCHING_NOZZLE +#if ENABLED(SWITCHING_NOZZLE) + #define SWITCHING_NOZZLE_SERVO_NR 0 + #define SWITCHING_NOZZLE_SERVO_ANGLES { 0, 90 } // Angles for E0, E1 + //#define HOTEND_OFFSET_Z { 0.0, 0.0 } +#endif + +/** + * Two separate X-carriages with extruders that connect to a moving part + * via a magnetic docking mechanism. Requires SOL1_PIN and SOL2_PIN. + */ +//#define PARKING_EXTRUDER +#if ENABLED(PARKING_EXTRUDER) + #define PARKING_EXTRUDER_SOLENOIDS_INVERT // If enabled, the solenoid is NOT magnetized with applied voltage + #define PARKING_EXTRUDER_SOLENOIDS_PINS_ACTIVE LOW // LOW or HIGH pin signal energizes the coil + #define PARKING_EXTRUDER_SOLENOIDS_DELAY 250 // Delay (ms) for magnetic field. No delay if 0 or not defined. + #define PARKING_EXTRUDER_PARKING_X { -78, 184 } // X positions for parking the extruders + #define PARKING_EXTRUDER_GRAB_DISTANCE 1 // mm to move beyond the parking point to grab the extruder + #define PARKING_EXTRUDER_SECURITY_RAISE 5 // Z-raise before parking + #define HOTEND_OFFSET_Z { 0.0, 1.3 } // Z-offsets of the two hotends. The first must be 0. +#endif + +/** + * "Mixing Extruder" + * - Adds a new code, M165, to set the current mix factors. + * - Extends the stepping routines to move multiple steppers in proportion to the mix. + * - Optional support for Repetier Firmware M163, M164, and virtual extruder. + * - This implementation supports only a single extruder. + * - Enable DIRECT_MIXING_IN_G1 for Pia Taubert's reference implementation + */ +//#define MIXING_EXTRUDER +#if ENABLED(MIXING_EXTRUDER) + #define MIXING_STEPPERS 2 // Number of steppers in your mixing extruder + #define MIXING_VIRTUAL_TOOLS 16 // Use the Virtual Tool method with M163 and M164 + //#define DIRECT_MIXING_IN_G1 // Allow ABCDHI mix factors in G1 movement commands +#endif + +// Offset of the extruders (uncomment if using more than one and relying on firmware to position when changing). +// The offset has to be X=0, Y=0 for the extruder 0 hotend (default extruder). +// For the other hotends it is their distance from the extruder 0 hotend. +//#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis +//#define HOTEND_OFFSET_Y {0.0, 5.00} // (in mm) for each extruder, offset of the hotend on the Y axis + +// @section machine + +/** + * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN + * + * 0 = No Power Switch + * 1 = ATX + * 2 = X-Box 360 203Watts (the blue wire connected to PS_ON and the red wire to VCC) + * + * :{ 0:'No power switch', 1:'ATX', 2:'X-Box 360' } + */ +#define POWER_SUPPLY 1 + +#if POWER_SUPPLY > 0 + // Enable this option to leave the PSU off at startup. + // Power to steppers and heaters will need to be turned on with M80. + #define PS_DEFAULT_OFF +#endif + +// @section temperature + +//=========================================================================== +//============================= Thermal Settings ============================ +//=========================================================================== + +/** + * --NORMAL IS 4.7kohm PULLUP!-- 1kohm pullup can be used on hotend sensor, using correct resistor and table + * + * Temperature sensors available: + * + * -3 : thermocouple with MAX31855 (only for sensor 0) + * -2 : thermocouple with MAX6675 (only for sensor 0) + * -1 : thermocouple with AD595 + * 0 : not used + * 1 : 100k thermistor - best choice for EPCOS 100k (4.7k pullup) + * 2 : 200k thermistor - ATC Semitec 204GT-2 (4.7k pullup) + * 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 (Used in ParCan & J-Head) (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) + * 71 : 100k Honeywell thermistor 135-104LAF-J01 (4.7k pullup) + * 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) + * 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" + * 20 : the PT100 circuit found in the Ultimainboard V2.x + * 60 : 100k Maker's Tool Works Kapton Bed Thermistor beta=3950 + * 66 : 4.7M High Temperature thermistor from Dyze Design + * 70 : the 100K thermistor found in the bq Hephestos 2 + * 75 : 100k Generic Silicon Heat Pad with NTC 100K MGB18-104F39050L32 thermistor + * + * 1k ohm pullup tables - This is atypical, and requires changing out the 4.7k pullup for 1k. + * (but gives greater accuracy and more stable PID) + * 51 : 100k thermistor - EPCOS (1k pullup) + * 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 + * 1010 : Pt1000 with 1k pullup (non standard) + * 147 : Pt100 with 4k7 pullup + * 110 : Pt100 with 1k pullup (non standard) + * + * Use these for Testing or Development purposes. NEVER for production machine. + * 998 : Dummy Table that ALWAYS reads 25°C or the temperature defined below. + * 999 : Dummy Table that ALWAYS reads 100°C or the temperature defined below. + * + * :{ '0': "Not used", '1':"100k / 4.7k - EPCOS", '2':"200k / 4.7k - ATC Semitec 204GT-2", '3':"Mendel-parts / 4.7k", '4':"10k !! do not use for a hotend. Bad resolution at high temp. !!", '5':"100K / 4.7k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '6':"100k / 4.7k EPCOS - Not as accurate as Table 1", '7':"100k / 4.7k Honeywell 135-104LAG-J01", '8':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT", '9':"100k / 4.7k GE Sensing AL03006-58.2K-97-G1", '10':"100k / 4.7k RS 198-961", '11':"100k / 4.7k beta 3950 1%", '12':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT (calibrated for Makibox hot bed)", '13':"100k Hisens 3950 1% up to 300°C for hotend 'Simple ONE ' & hotend 'All In ONE'", '20':"PT100 (Ultimainboard V2.x)", '51':"100k / 1k - EPCOS", '52':"200k / 1k - ATC Semitec 204GT-2", '55':"100k / 1k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '60':"100k Maker's Tool Works Kapton Bed Thermistor beta=3950", '66':"Dyze Design 4.7M High Temperature thermistor", '70':"the 100K thermistor found in the bq Hephestos 2", '71':"100k / 4.7k Honeywell 135-104LAF-J01", '147':"Pt100 / 4.7k", '1047':"Pt1000 / 4.7k", '110':"Pt100 / 1k (non-standard)", '1010':"Pt1000 / 1k (non standard)", '-3':"Thermocouple + MAX31855 (only for sensor 0)", '-2':"Thermocouple + MAX6675 (only for sensor 0)", '-1':"Thermocouple + AD595",'998':"Dummy 1", '999':"Dummy 2" } + */ +#define TEMP_SENSOR_0 1 +#define TEMP_SENSOR_1 1 +#define TEMP_SENSOR_2 0 +#define TEMP_SENSOR_3 0 +#define TEMP_SENSOR_4 0 +#define TEMP_SENSOR_BED 1 + +// Dummy thermistor constant temperature readings, for use with 998 and 999 +#define DUMMY_THERMISTOR_998_VALUE 25 +#define DUMMY_THERMISTOR_999_VALUE 100 + +// 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 +#define MAX_REDUNDANT_TEMP_SENSOR_DIFF 10 + +// Extruder temperature must be close to target for this long before M109 returns success +#define TEMP_RESIDENCY_TIME 15 // (seconds) +#define TEMP_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// Bed temperature must be close to target for this long before M190 returns success +#define TEMP_BED_RESIDENCY_TIME 0 // (seconds) +#define TEMP_BED_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_BED_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// The minimal temperature defines the temperature below which the heater will not be enabled It is used +// to check that the wiring to the thermistor is not broken. +// Otherwise this would lead to the heater being powered on all the time. +#define HEATER_0_MINTEMP 5 +#define HEATER_1_MINTEMP 5 +#define HEATER_2_MINTEMP 5 +#define HEATER_3_MINTEMP 5 +#define HEATER_4_MINTEMP 5 +#define BED_MINTEMP 5 + +// When temperature exceeds max temp, your heater will be switched off. +// This feature exists to protect your hotend from overheating accidentally, but *NOT* from thermistor short/failure! +// You should use MINTEMP for thermistor short/failure protection. +#define HEATER_0_MAXTEMP 275 +#define HEATER_1_MAXTEMP 275 +#define HEATER_2_MAXTEMP 275 +#define HEATER_3_MAXTEMP 275 +#define HEATER_4_MAXTEMP 275 +#define BED_MAXTEMP 150 + +//=========================================================================== +//============================= PID Settings ================================ +//=========================================================================== +// PID Tuning Guide here: http://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 +#if ENABLED(PIDTEMP) + //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. + //#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. + #define K1 0.95 //smoothing factor within the PID + + // Felix 2.0+ electronics with v4 Hotend + #define DEFAULT_Kp 12 + #define DEFAULT_Ki 0.84 + #define DEFAULT_Kd 85 + +#endif // PIDTEMP + +//=========================================================================== +//============================= PID > Bed Temperature Control =============== +//=========================================================================== +// Select PID or bang-bang with PIDTEMPBED. If bang-bang, BED_LIMIT_SWITCHING will enable hysteresis +// +// Uncomment this to enable PID on the bed. It uses the same frequency PWM as the extruder. +// If your PID_dT is the default, and correct for your hardware/configuration, that means 7.689Hz, +// which is fine for driving a square wave into a resistive load and does not significantly impact you FET heating. +// This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W heater. +// If your configuration is significantly different than this and you don't understand the issues involved, you probably +// shouldn't use bed PID until someone else verifies your hardware works. +// If this is enabled, find your own PID constants below. +#define PIDTEMPBED + +//#define BED_LIMIT_SWITCHING + +// This sets the max power delivered to the bed, and replaces the HEATER_BED_DUTY_CYCLE_DIVIDER option. +// all forms of bed control obey this (PID, bang-bang, bang-bang with hysteresis) +// setting this to anything other than 255 enables a form of PWM to the bed just like HEATER_BED_DUTY_CYCLE_DIVIDER did, +// so you shouldn't use it unless you are OK with PWM on your bed. (see the comment on enabling PIDTEMPBED) +#define MAX_BED_POWER 255 // limits duty cycle to bed; 255=full current + +#if ENABLED(PIDTEMPBED) + + //#define PID_BED_DEBUG // Sends debug data to the serial port. + + // Felix Foil Heater + #define DEFAULT_bedKp 103.37 + #define DEFAULT_bedKi 2.79 + #define DEFAULT_bedKd 956.94 + + // FIND YOUR OWN: "M303 E-1 C8 S90" to run autotune on the bed at 90 degreesC for 8 cycles. +#endif // PIDTEMPBED + +// @section extruder + +// This option prevents extrusion if the temperature is below EXTRUDE_MINTEMP. +// It also enables the M302 command to set the minimum extrusion temperature +// or to allow moving the extruder regardless of the hotend temperature. +// *** IT IS HIGHLY RECOMMENDED TO LEAVE THIS OPTION ENABLED! *** +#define PREVENT_COLD_EXTRUSION +#define EXTRUDE_MINTEMP 170 + +// This option prevents a single extrusion longer than EXTRUDE_MAXLENGTH. +// Note that for Bowden Extruders a too-small value here may prevent loading. +#define PREVENT_LENGTHY_EXTRUDE +#define EXTRUDE_MAXLENGTH 200 + +//=========================================================================== +//======================== Thermal Runaway Protection ======================= +//=========================================================================== + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * If you get "Thermal Runaway" or "Heating failed" errors the + * details can be tuned in Configuration_adv.h + */ + +#define THERMAL_PROTECTION_HOTENDS // Enable thermal protection for all extruders +#define THERMAL_PROTECTION_BED // Enable thermal protection for the heated bed + +//=========================================================================== +//============================= Mechanical Settings ========================= +//=========================================================================== + +// @section machine + +// Uncomment one of these options to enable CoreXY, CoreXZ, or CoreYZ kinematics +// either in the usual order or reversed +//#define COREXY +//#define COREXZ +//#define COREYZ +//#define COREYX +//#define COREZX +//#define COREZY + +//=========================================================================== +//============================== Endstop Settings =========================== +//=========================================================================== + +// @section homing + +// Specify here all the endstop connectors that are connected to any endstop or probe. +// Almost all printers will be using one per axis. Probes will use one or more of the +// extra connectors. Leave undefined any used for non-endstop and non-probe purposes. +#define USE_XMIN_PLUG +#define USE_YMIN_PLUG +#define USE_ZMIN_PLUG +//#define USE_XMAX_PLUG +//#define USE_YMAX_PLUG +//#define USE_ZMAX_PLUG + +// coarse Endstop Settings +#define ENDSTOPPULLUPS // Comment this out (using // at the start of the line) to disable the endstop pullup resistors + +#if DISABLED(ENDSTOPPULLUPS) + // fine endstop settings: Individual pullups. will be ignored if ENDSTOPPULLUPS is defined + //#define ENDSTOPPULLUP_XMAX + //#define ENDSTOPPULLUP_YMAX + //#define ENDSTOPPULLUP_ZMAX + //#define ENDSTOPPULLUP_XMIN + //#define ENDSTOPPULLUP_YMIN + //#define ENDSTOPPULLUP_ZMIN + //#define ENDSTOPPULLUP_ZMIN_PROBE +#endif + +// Mechanical endstop with COM to ground and NC to Signal uses "false" here (most common setup). +#define X_MIN_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Y_MIN_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MIN_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define X_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Y_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MIN_PROBE_ENDSTOP_INVERTING false // set to true to invert the logic of the probe. + +// Enable this feature if all enabled endstop pins are interrupt-capable. +// This will remove the need to poll the interrupt pins, saving many CPU cycles. +//#define ENDSTOP_INTERRUPTS_FEATURE + +//============================================================================= +//============================== Movement Settings ============================ +//============================================================================= +// @section motion + +// default steps per unit for Felix 2.0/3.0: 0.00249mm x/y rounding error with 3mm pitch HTD belt and 14 tooth pulleys. 0 z error. +/** + * Default Settings + * + * These settings can be reset by M502 + * + * Note that if EEPROM is enabled, saved values will override these. + */ + +/** + * With this option each E stepper can have its own factors for the + * following movement settings. If fewer factors are given than the + * total number of extruders, the last value applies to the rest. + */ +//#define DISTINCT_E_FACTORS + +/** + * Default Axis Steps Per Unit (steps/mm) + * Override with M92 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_AXIS_STEPS_PER_UNIT { 76.190476, 76.190476, 1600, 164 } + +/** + * Default Max Feed Rate (mm/s) + * Override with M203 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_FEEDRATE { 500, 500, 5, 25 } + +/** + * Default Max Acceleration (change/s) change = mm/s + * (Maximum start speed for accelerated moves) + * Override with M201 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_ACCELERATION { 5000, 5000, 100, 80000 } + +/** + * Default Acceleration (change/s) change = mm/s + * Override with M204 + * + * M204 P Acceleration + * M204 R Retract Acceleration + * M204 T Travel Acceleration + */ +#define DEFAULT_ACCELERATION 1750 // X, Y, Z and E max acceleration for printing moves +#define DEFAULT_RETRACT_ACCELERATION 5000 // E acceleration for retracts +#define DEFAULT_TRAVEL_ACCELERATION 3000 // X, Y, Z acceleration for travel (non printing) moves + +/** + * Default Jerk (mm/s) + * Override with M205 X Y Z E + * + * "Jerk" specifies the minimum speed change that requires acceleration. + * When changing speed and direction, if the difference is less than the + * value set here, it may happen instantaneously. + */ +#define DEFAULT_XJERK 10.0 +#define DEFAULT_YJERK 10.0 +#define DEFAULT_ZJERK 0.3 +#define DEFAULT_EJERK 5.0 + +//=========================================================================== +//============================= Z Probe Options ============================= +//=========================================================================== +// @section probes + +// +// See http://marlinfw.org/configuration/probes.html +// + +/** + * Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + * + * Enable this option for a probe connected to the Z Min endstop pin. + */ +#define Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + +/** + * Z_MIN_PROBE_ENDSTOP + * + * Enable this option for a probe connected to any pin except Z-Min. + * (By default Marlin assumes the Z-Max endstop pin.) + * To use a custom Z Probe pin, set Z_MIN_PROBE_PIN below. + * + * - The simplest option is to use a free endstop connector. + * - Use 5V for powered (usually inductive) sensors. + * + * - RAMPS 1.3/1.4 boards may use the 5V, GND, and Aux4->D32 pin: + * - For simple switches connect... + * - normally-closed switches to GND and D32. + * - normally-open switches to 5V and D32. + * + * WARNING: Setting the wrong pin may have unexpected and potentially + * disastrous consequences. Use with caution and do your homework. + * + */ +//#define Z_MIN_PROBE_ENDSTOP + +/** + * Probe Type + * + * Allen Key Probes, Servo Probes, Z-Sled Probes, FIX_MOUNTED_PROBE, etc. + * Activate one of these to use Auto Bed Leveling below. + */ + +/** + * The "Manual Probe" provides a means to do "Auto" Bed Leveling without a probe. + * Use G29 repeatedly, adjusting the Z height at each point with movement commands + * or (with LCD_BED_LEVELING) the LCD controller. + */ +//#define PROBE_MANUALLY + +/** + * A Fix-Mounted Probe either doesn't deploy or needs manual deployment. + * (e.g., an inductive probe or a nozzle-based probe-switch.) + */ +//#define FIX_MOUNTED_PROBE + +/** + * Z Servo Probe, such as an endstop switch on a rotating arm. + */ +//#define Z_ENDSTOP_SERVO_NR 0 // Defaults to SERVO 0 connector. +//#define Z_SERVO_ANGLES {70,0} // Z Servo Deploy and Stow angles + +/** + * The BLTouch probe uses a Hall effect sensor and emulates a servo. + */ +//#define BLTOUCH +#if ENABLED(BLTOUCH) + //#define BLTOUCH_DELAY 375 // (ms) Enable and increase if needed +#endif + +/** + * Enable one or more of the following if probing seems unreliable. + * Heaters and/or fans can be disabled during probing to minimize electrical + * noise. A delay can also be added to allow noise and vibration to settle. + * These options are most useful for the BLTouch probe, but may also improve + * readings with inductive probes and piezo sensors. + */ +//#define PROBING_HEATERS_OFF // Turn heaters off when probing +//#define PROBING_FANS_OFF // Turn fans off when probing +//#define DELAY_BEFORE_PROBING 200 // (ms) To prevent vibrations from triggering piezo sensors + +// A probe that is deployed and stowed with a solenoid pin (SOL1_PIN) +//#define SOLENOID_PROBE + +// A sled-mounted probe like those designed by Charles Bell. +//#define Z_PROBE_SLED +//#define SLED_DOCKING_OFFSET 5 // The extra distance the X axis must travel to pickup the sled. 0 should be fine but you can push it further if you'd like. + +// +// For Z_PROBE_ALLEN_KEY see the Delta example configurations. +// + +/** + * Z Probe to nozzle (X,Y) offset, relative to (0, 0). + * X and Y offsets must be integers. + * + * In the following example the X and Y offsets are both positive: + * #define X_PROBE_OFFSET_FROM_EXTRUDER 10 + * #define Y_PROBE_OFFSET_FROM_EXTRUDER 10 + * + * +-- BACK ---+ + * | | + * L | (+) P | R <-- probe (20,20) + * E | | I + * F | (-) N (+) | G <-- nozzle (10,10) + * T | | H + * | (-) | T + * | | + * O-- FRONT --+ + * (0,0) + */ +#define X_PROBE_OFFSET_FROM_EXTRUDER -25 // X offset: -left +right [of the nozzle] +#define Y_PROBE_OFFSET_FROM_EXTRUDER -29 // Y offset: -front +behind [the nozzle] +#define Z_PROBE_OFFSET_FROM_EXTRUDER -12.35 // Z offset: -below +above [the nozzle] + +// X and Y axis travel speed (mm/m) between probes +#define XY_PROBE_SPEED 8000 + +// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +#define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z + +// Speed for the "accurate" probe of each point +#define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) + +// Use double touch for probing +//#define PROBE_DOUBLE_TOUCH + +/** + * Z probes require clearance when deploying, stowing, and moving between + * probe points to avoid hitting the bed and other hardware. + * Servo-mounted probes require extra space for the arm to rotate. + * Inductive probes need space to keep from triggering early. + * + * Use these settings to specify the distance (mm) to raise the probe (or + * lower the bed). The values set here apply over and above any (negative) + * probe Z Offset set with Z_PROBE_OFFSET_FROM_EXTRUDER, M851, or the LCD. + * Only integer values >= 1 are valid here. + * + * Example: `M851 Z-5` with a CLEARANCE of 4 => 9mm from bed to nozzle. + * But: `M851 Z+1` with a CLEARANCE of 2 => 2mm from bed to nozzle. + */ +#define Z_CLEARANCE_DEPLOY_PROBE 15 // Z Clearance for Deploy/Stow +#define Z_CLEARANCE_BETWEEN_PROBES 5 // Z Clearance between probe points + +// For M851 give a range for adjusting the Z probe offset +#define Z_PROBE_OFFSET_RANGE_MIN -20 +#define Z_PROBE_OFFSET_RANGE_MAX 20 + +// Enable the M48 repeatability test to test probe accuracy +//#define Z_MIN_PROBE_REPEATABILITY_TEST + +// For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1 +// :{ 0:'Low', 1:'High' } +#define X_ENABLE_ON 0 +#define Y_ENABLE_ON 0 +#define Z_ENABLE_ON 0 +#define E_ENABLE_ON 0 // For all extruders + +// Disables axis stepper immediately when it's not being used. +// 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 +//#define DISABLE_REDUCED_ACCURACY_WARNING + +// @section extruder + +#define DISABLE_E false // For all extruders +#define DISABLE_INACTIVE_EXTRUDER true // Keep only the active extruder enabled. + +// @section machine + +// Invert the stepper direction. Change (or reverse the motor connector) if an axis goes the wrong way. +#define INVERT_X_DIR true +#define INVERT_Y_DIR true +#define INVERT_Z_DIR true + +// Enable this option for Toshiba stepper drivers +//#define CONFIG_STEPPERS_TOSHIBA + +// @section extruder + +// For direct drive extruder v9 set to true, for geared extruder set to false. +#define INVERT_E0_DIR false +#define INVERT_E1_DIR true +#define INVERT_E2_DIR false +#define INVERT_E3_DIR false +#define INVERT_E4_DIR false + +// @section homing + +//#define NO_MOTION_BEFORE_HOMING // Inhibit movement until all axes have been homed + +//#define Z_HOMING_HEIGHT 4 // (in mm) Minimal z height before homing (G28) for Z clearance above the bed, clamps, ... + // Be sure you have this distance over your Z_MAX_POS in case. + +// Direction of endstops when homing; 1=MAX, -1=MIN +// :[-1,1] +#define X_HOME_DIR -1 +#define Y_HOME_DIR -1 +#define Z_HOME_DIR -1 + +// @section machine + +// The size of the print bed +#define X_BED_SIZE 255 +#define Y_BED_SIZE 205 + +// Travel limits (mm) after homing, corresponding to endstop positions. +#define X_MIN_POS 0 +#define Y_MIN_POS 0 +#define Z_MIN_POS 0 +#define X_MAX_POS X_BED_SIZE +#define Y_MAX_POS Y_BED_SIZE +#define Z_MAX_POS 235 + +// If enabled, axes won't move below MIN_POS in response to movement commands. +#define MIN_SOFTWARE_ENDSTOPS +// If enabled, axes won't move above MAX_POS in response to movement commands. +#define MAX_SOFTWARE_ENDSTOPS + +/** + * Filament Runout Sensor + * A mechanical or opto endstop is used to check for the presence of filament. + * + * RAMPS-based boards use SERVO3_PIN. + * For other boards you may need to define FIL_RUNOUT_PIN. + * By default the firmware assumes HIGH = has filament, LOW = ran out + */ +//#define FILAMENT_RUNOUT_SENSOR +#if ENABLED(FILAMENT_RUNOUT_SENSOR) + #define FIL_RUNOUT_INVERTING false // set to true to invert the logic of the sensor. + #define ENDSTOPPULLUP_FIL_RUNOUT // Uncomment to use internal pullup for filament runout pins if the sensor is defined. + #define FILAMENT_RUNOUT_SCRIPT "M600" +#endif + +//=========================================================================== +//=============================== Bed Leveling ============================== +//=========================================================================== +// @section bedlevel + +/** + * Choose one of the options below to enable G29 Bed Leveling. The parameters + * and behavior of G29 will change depending on your selection. + * + * If using a Probe for Z Homing, enable Z_SAFE_HOMING also! + * + * - AUTO_BED_LEVELING_3POINT + * Probe 3 arbitrary points on the bed (that aren't collinear) + * You specify the XY coordinates of all 3 points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_LINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_BILINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a mesh, best for large or uneven beds. + * + * - AUTO_BED_LEVELING_UBL (Unified Bed Leveling) + * A comprehensive bed leveling system combining the features and benefits + * of other systems. UBL also includes integrated Mesh Generation, Mesh + * Validation and Mesh Editing systems. Currently, UBL is only checked out + * for Cartesian Printers. That said, it was primarily designed to correct + * poor quality Delta Printers. If you feel adventurous and have a Delta, + * please post an issue if something doesn't work correctly. Initially, + * you will need to set a reduced bed size so you have a rectangular area + * to test on. + * + * - MESH_BED_LEVELING + * Probe a grid manually + * The result is a mesh, suitable for large or uneven beds. (See BILINEAR.) + * For machines without a probe, Mesh Bed Leveling provides a method to perform + * leveling in steps so you can manually adjust the Z height at each grid-point. + * With an LCD controller the process is guided step-by-step. + */ +//#define AUTO_BED_LEVELING_3POINT +//#define AUTO_BED_LEVELING_LINEAR +//#define AUTO_BED_LEVELING_BILINEAR +//#define AUTO_BED_LEVELING_UBL +//#define MESH_BED_LEVELING + +/** + * Enable detailed logging of G28, G29, M48, etc. + * Turn on with the command 'M111 S32'. + * NOTE: Requires a lot of PROGMEM! + */ +//#define DEBUG_LEVELING_FEATURE + +#if ENABLED(MESH_BED_LEVELING) || ENABLED(AUTO_BED_LEVELING_BILINEAR) || ENABLED(AUTO_BED_LEVELING_UBL) + // Gradually reduce leveling correction until a set height is reached, + // at which point movement will be level to the machine's XY plane. + // The height can be set with M420 Z + #define ENABLE_LEVELING_FADE_HEIGHT +#endif + +#if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Set the number of grid points per dimension. + #define GRID_MAX_POINTS_X 3 + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + // Set the boundaries for probing (where the probe can reach). + #define LEFT_PROBE_BED_POSITION 15 + #define RIGHT_PROBE_BED_POSITION 170 + #define FRONT_PROBE_BED_POSITION 20 + #define BACK_PROBE_BED_POSITION 180 + + // The Z probe minimum outer margin (to validate G29 parameters). + #define MIN_PROBE_EDGE 10 + + // Probe along the Y axis, advancing X after each column + //#define PROBE_Y_FIRST + + #if ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Beyond the probed grid, continue the implied tilt? + // Default is to maintain the height of the nearest edge. + //#define EXTRAPOLATE_BEYOND_GRID + + // + // Experimental Subdivision of the grid by Catmull-Rom method. + // Synthesizes intermediate points to produce a more detailed mesh. + // + //#define ABL_BILINEAR_SUBDIVISION + #if ENABLED(ABL_BILINEAR_SUBDIVISION) + // Number of subdivisions between probe points + #define BILINEAR_SUBDIVISIONS 3 + #endif + + #endif + +#elif ENABLED(AUTO_BED_LEVELING_3POINT) + + // 3 arbitrary points to probe. + // A simple cross-product is used to estimate the plane of the bed. + #define ABL_PROBE_PT_1_X 15 + #define ABL_PROBE_PT_1_Y 180 + #define ABL_PROBE_PT_2_X 15 + #define ABL_PROBE_PT_2_Y 20 + #define ABL_PROBE_PT_3_X 170 + #define ABL_PROBE_PT_3_Y 20 + +#elif ENABLED(AUTO_BED_LEVELING_UBL) + + //=========================================================================== + //========================= Unified Bed Leveling ============================ + //=========================================================================== + + #define UBL_MESH_INSET 1 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 10 // Don't use more than 15 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + #define UBL_PROBE_PT_1_X 39 // Probing points for 3-Point leveling of the mesh + #define UBL_PROBE_PT_1_Y 180 + #define UBL_PROBE_PT_2_X 39 + #define UBL_PROBE_PT_2_Y 20 + #define UBL_PROBE_PT_3_X 180 + #define UBL_PROBE_PT_3_Y 20 + + #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation + #define UBL_MESH_EDIT_MOVES_Z // Sophisticated users prefer no movement of nozzle + +#elif ENABLED(MESH_BED_LEVELING) + + //=========================================================================== + //=================================== Mesh ================================== + //=========================================================================== + + #define MESH_INSET 10 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 3 // Don't use more than 7 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + //#define MESH_G28_REST_ORIGIN // After homing all axes ('G28' or 'G28 XYZ') rest Z at Z_MIN_POS + +#endif // BED_LEVELING + +/** + * Use the LCD controller for bed leveling + * Requires MESH_BED_LEVELING or PROBE_MANUALLY + */ +//#define LCD_BED_LEVELING + +#if ENABLED(LCD_BED_LEVELING) + #define MBL_Z_STEP 0.025 // Step size while manually probing Z axis. + #define LCD_PROBE_Z_RANGE 4 // Z Range centered on Z_MIN_POS for LCD Z adjustment +#endif + +// Add a menu item to move between bed corners for manual bed adjustment +//#define LEVEL_BED_CORNERS + +/** + * Commands to execute at the end of G29 probing. + * Useful to retract or move the Z probe out of the way. + */ +//#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) +//#define BED_CENTER_AT_0_0 + +// Manually set the home position. Leave these undefined for automatic settings. +// For DELTA this is the top-center of the Cartesian print volume. +//#define MANUAL_X_HOME_POS 0 +//#define MANUAL_Y_HOME_POS 0 +//#define MANUAL_Z_HOME_POS 0 + +// Use "Z Safe Homing" to avoid homing with a Z probe outside the bed area. +// +// With this feature enabled: +// +// - 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). +// - 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 axis (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). +#endif + +// Homing speeds (mm/m) +#define HOMING_FEEDRATE_XY (50*60) +#define HOMING_FEEDRATE_Z (4*60) + +//============================================================================= +//============================= Additional Features =========================== +//============================================================================= + +// @section extras + +// +// EEPROM +// +// The microcontroller can store settings in the EEPROM, e.g. max velocity... +// M500 - stores parameters in EEPROM +// M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily). +// M502 - reverts to the default "factory settings". You still need to store them in EEPROM afterwards if you want to. +// +//#define EEPROM_SETTINGS // Enable for M500 and M501 commands +//#define DISABLE_M503 // Saves ~2700 bytes of PROGMEM. Disable for release! +#define EEPROM_CHITCHAT // Give feedback on EEPROM commands. Disable to save PROGMEM. + +// +// Host Keepalive +// +// When enabled Marlin will send a busy status message to the host +// every couple of seconds when it can't accept commands. +// +#define HOST_KEEPALIVE_FEATURE // Disable this if your host doesn't like keepalive messages +#define DEFAULT_KEEPALIVE_INTERVAL 2 // Number of seconds between "busy" messages. Set with M113. +#define BUSY_WHILE_HEATING // Some hosts require "busy" messages even during heating + +// +// M100 Free Memory Watcher +// +//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose + +// +// G20/G21 Inch mode support +// +//#define INCH_MODE_SUPPORT + +// +// M149 Set temperature units support +// +//#define TEMPERATURE_UNITS_SUPPORT + +// @section temperature + +// Preheat Constants +#define PREHEAT_1_TEMP_HOTEND 180 +#define PREHEAT_1_TEMP_BED 70 +#define PREHEAT_1_FAN_SPEED 255 // Value from 0 to 255 + +#define PREHEAT_2_TEMP_HOTEND 240 +#define PREHEAT_2_TEMP_BED 100 +#define PREHEAT_2_FAN_SPEED 255 // Value from 0 to 255 + +/** + * Nozzle Park -- EXPERIMENTAL + * + * Park the nozzle at the given XYZ position on idle or G27. + * + * The "P" parameter controls the action applied to the Z axis: + * + * P0 (Default) If Z is below park Z raise the nozzle. + * P1 Raise the nozzle always to Z-park height. + * P2 Raise the nozzle by Z-park amount, limited to Z_MAX_POS. + */ +//#define NOZZLE_PARK_FEATURE + +#if ENABLED(NOZZLE_PARK_FEATURE) + // Specify a park position as { X, Y, Z } + #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 } +#endif + +/** + * Clean Nozzle Feature -- EXPERIMENTAL + * + * Adds the G12 command to perform a nozzle cleaning process. + * + * Parameters: + * P Pattern + * S Strokes / Repetitions + * T Triangles (P1 only) + * + * Patterns: + * P0 Straight line (default). This process requires a sponge type material + * at a fixed bed location. "S" specifies strokes (i.e. back-forth motions) + * between the start / end points. + * + * P1 Zig-zag pattern between (X0, Y0) and (X1, Y1), "T" specifies the + * number of zig-zag triangles to do. "S" defines the number of strokes. + * Zig-zags are done in whichever is the narrower dimension. + * For example, "G12 P1 S1 T3" will execute: + * + * -- + * | (X0, Y1) | /\ /\ /\ | (X1, Y1) + * | | / \ / \ / \ | + * A | | / \ / \ / \ | + * | | / \ / \ / \ | + * | (X0, Y0) | / \/ \/ \ | (X1, Y0) + * -- +--------------------------------+ + * |________|_________|_________| + * T1 T2 T3 + * + * P2 Circular pattern with middle at NOZZLE_CLEAN_CIRCLE_MIDDLE. + * "R" specifies the radius. "S" specifies the stroke count. + * Before starting, the nozzle moves to NOZZLE_CLEAN_START_POINT. + * + * Caveats: The ending Z should be the same as starting Z. + * Attention: EXPERIMENTAL. G-code arguments may change. + * + */ +//#define NOZZLE_CLEAN_FEATURE + +#if ENABLED(NOZZLE_CLEAN_FEATURE) + // Default number of pattern repetitions + #define NOZZLE_CLEAN_STROKES 12 + + // Default number of triangles + #define NOZZLE_CLEAN_TRIANGLES 3 + + // Specify positions as { X, Y, Z } + #define NOZZLE_CLEAN_START_POINT { 30, 30, (Z_MIN_POS + 1)} + #define NOZZLE_CLEAN_END_POINT {100, 60, (Z_MIN_POS + 1)} + + // Circular pattern radius + #define NOZZLE_CLEAN_CIRCLE_RADIUS 6.5 + // Circular pattern circle fragments number + #define NOZZLE_CLEAN_CIRCLE_FN 10 + // Middle point of circle + #define NOZZLE_CLEAN_CIRCLE_MIDDLE NOZZLE_CLEAN_START_POINT + + // Moves the nozzle to the initial position + #define NOZZLE_CLEAN_GOBACK +#endif + +/** + * Print Job Timer + * + * Automatically start and stop the print job timer on M104/M109/M190. + * + * M104 (hotend, no wait) - high temp = none, low temp = stop timer + * M109 (hotend, wait) - high temp = start timer, low temp = stop timer + * M190 (bed, wait) - high temp = start timer, low temp = none + * + * The timer can also be controlled with the following commands: + * + * M75 - Start the print job timer + * M76 - Pause the print job timer + * M77 - Stop the print job timer + */ +#define PRINTJOB_TIMER_AUTOSTART + +/** + * Print Counter + * + * Track statistical data such as: + * + * - Total print jobs + * - Total successful print jobs + * - Total failed print jobs + * - Total time printing + * + * View the current statistics with M78. + */ +//#define PRINTCOUNTER + +//============================================================================= +//============================= LCD and SD support ============================ +//============================================================================= + +// @section lcd + +/** + * LCD LANGUAGE + * + * Select the language to display on the LCD. These languages are available: + * + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, + * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * tr, uk, zh_CN, zh_TW, test + * + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + */ +//#define LCD_LANGUAGE en + +/** + * LCD Character Set + * + * Note: This option is NOT applicable to Graphical Displays. + * + * All character-based LCDs provide ASCII plus one of these + * language extensions: + * + * - JAPANESE ... the most common + * - WESTERN ... with more accented characters + * - CYRILLIC ... for the Russian language + * + * To determine the language extension installed on your controller: + * + * - Compile and upload with LCD_LANGUAGE set to 'test' + * - 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 + * + * :['JAPANESE', 'WESTERN', 'CYRILLIC'] + */ +#define DISPLAY_CHARSET_HD44780 JAPANESE + +/** + * LCD TYPE + * + * Enable ULTRA_LCD for a 16x2, 16x4, 20x2, or 20x4 character-based LCD. + * Enable DOGLCD for a 128x64 (ST7565R) Full Graphical Display. + * (These options will be enabled automatically for most displays.) + * + * IMPORTANT: The U8glib library is required for Full Graphic Display! + * https://github.com/olikraus/U8glib_Arduino + */ +//#define ULTRA_LCD // Character based +//#define DOGLCD // Full graphics display + +/** + * SD CARD + * + * 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 + +/** + * SD CARD: SPI SPEED + * + * Enable one of the following items for a slower SPI transfer speed. + * This may be required to resolve "volume init" errors. + */ +//#define SPI_SPEED SPI_HALF_SPEED +//#define SPI_SPEED SPI_QUARTER_SPEED +//#define SPI_SPEED SPI_EIGHTH_SPEED + +/** + * SD CARD: ENABLE CRC + * + * Use CRC checks and retries on the SD communication. + */ +//#define SD_CHECK_AND_RETRY + +// +// ENCODER SETTINGS +// +// This option overrides the default number of encoder pulses needed to +// produce one step. Should be increased for high-resolution encoders. +// +//#define ENCODER_PULSES_PER_STEP 1 + +// +// Use this option to override the number of step signals required to +// move between next/prev menu items. +// +//#define ENCODER_STEPS_PER_MENU_ITEM 5 + +/** + * Encoder Direction Options + * + * Test your encoder's behavior first with both options disabled. + * + * Reversed Value Edit and Menu Nav? Enable REVERSE_ENCODER_DIRECTION. + * Reversed Menu Navigation only? Enable REVERSE_MENU_DIRECTION. + * Reversed Value Editing only? Enable BOTH options. + */ + +// +// This option reverses the encoder direction everywhere. +// +// Set this option if CLOCKWISE causes values to DECREASE +// +//#define REVERSE_ENCODER_DIRECTION + +// +// This option reverses the encoder direction for navigating LCD menus. +// +// If CLOCKWISE normally moves DOWN this makes it go UP. +// If CLOCKWISE normally moves UP this makes it go DOWN. +// +//#define REVERSE_MENU_DIRECTION + +// +// Individual Axis Homing +// +// Add individual axis homing items (Home X, Home Y, and Home Z) to the LCD menu. +// +//#define INDIVIDUAL_AXIS_HOMING_MENU + +// +// SPEAKER/BUZZER +// +// If you have a speaker that can produce tones, enable it here. +// By default Marlin assumes you have a buzzer with a fixed frequency. +// +//#define SPEAKER + +// +// The duration and frequency for the UI feedback sound. +// Set these to 0 to disable audio feedback in the LCD menus. +// +// Note: Test audio output with the G-Code: +// M300 S P +// +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 +//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 + +// +// CONTROLLER TYPE: Standard +// +// Marlin supports a wide variety of controllers. +// Enable one of the following options to specify your controller. +// + +// +// ULTIMAKER Controller. +// +//#define ULTIMAKERCONTROLLER + +// +// ULTIPANEL as seen on Thingiverse. +// +//#define ULTIPANEL + +// +// PanelOne from T3P3 (via RAMPS 1.4 AUX2/AUX3) +// http://reprap.org/wiki/PanelOne +// +//#define PANEL_ONE + +// +// MaKr3d Makr-Panel with graphic controller and SD support. +// http://reprap.org/wiki/MaKr3d_MaKrPanel +// +//#define MAKRPANEL + +// +// ReprapWorld Graphical LCD +// https://reprapworld.com/?products_details&products_id/1218 +// +//#define REPRAPWORLD_GRAPHICAL_LCD + +// +// Activate one of these if you have a Panucatt Devices +// Viki 2.0 or mini Viki with Graphic LCD +// http://panucatt.com +// +//#define VIKI2 +//#define miniVIKI + +// +// Adafruit ST7565 Full Graphic Controller. +// https://github.com/eboston/Adafruit-ST7565-Full-Graphic-Controller/ +// +//#define ELB_FULL_GRAPHIC_CONTROLLER + +// +// RepRapDiscount Smart Controller. +// http://reprap.org/wiki/RepRapDiscount_Smart_Controller +// +// Note: Usually sold with a white PCB. +// +//#define REPRAP_DISCOUNT_SMART_CONTROLLER + +// +// GADGETS3D G3D LCD/SD Controller +// http://reprap.org/wiki/RAMPS_1.3/1.4_GADGETS3D_Shield_with_Panel +// +// Note: Usually sold with a blue PCB. +// +//#define G3D_PANEL + +// +// RepRapDiscount FULL GRAPHIC Smart Controller +// http://reprap.org/wiki/RepRapDiscount_Full_Graphic_Smart_Controller +// +//#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER + +// +// MakerLab Mini Panel with graphic +// controller and SD support - http://reprap.org/wiki/Mini_panel +// +//#define MINIPANEL + +// +// RepRapWorld REPRAPWORLD_KEYPAD v1.1 +// http://reprapworld.com/?products_details&products_id=202&cPath=1591_1626 +// +// REPRAPWORLD_KEYPAD_MOVE_STEP sets how much should the robot move when a key +// is pressed, a value of 10.0 means 10mm per click. +// +//#define REPRAPWORLD_KEYPAD +//#define REPRAPWORLD_KEYPAD_MOVE_STEP 1.0 + +// +// RigidBot Panel V1.0 +// http://www.inventapart.com/ +// +//#define RIGIDBOT_PANEL + +// +// BQ LCD Smart Controller shipped by +// default with the BQ Hephestos 2 and Witbox 2. +// +//#define BQ_LCD_SMART_CONTROLLER + +// +// Cartesio UI +// http://mauk.cc/webshop/cartesio-shop/electronics/user-interface +// +//#define CARTESIO_UI + +// +// ANET_10 Controller supported displays. +// +//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. + // This LCD is known to be susceptible to electrical interference + // which scrambles the display. Pressing any button clears it up. +//#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 + // A clone of the RepRapDiscount full graphics display but with + // different pins/wiring (see pins_ANET_10.h). + +// +// LCD for Melzi Card with Graphical LCD +// +//#define LCD_FOR_MELZI + +// +// CONTROLLER TYPE: I2C +// +// Note: These controllers require the installation of Arduino's LiquidCrystal_I2C +// library. For more info: https://github.com/kiyoshigawa/LiquidCrystal_I2C +// + +// +// Elefu RA Board Control Panel +// http://www.elefu.com/index.php?route=product/product&product_id=53 +// +//#define RA_CONTROL_PANEL + +// +// Sainsmart YW Robot (LCM1602) LCD Display +// +// Note: This controller requires F.Malpartida's LiquidCrystal_I2C library +// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home +// +//#define LCD_I2C_SAINSMART_YWROBOT + +// +// Generic LCM1602 LCD adapter +// +//#define LCM1602 + +// +// PANELOLU2 LCD with status LEDs, +// separate encoder and click inputs. +// +// Note: This controller requires Arduino's LiquidTWI2 library v1.2.3 or later. +// For more info: https://github.com/lincomatic/LiquidTWI2 +// +// Note: The PANELOLU2 encoder click input can either be directly connected to +// a pin (if BTN_ENC defined to != -1) or read through I2C (when BTN_ENC == -1). +// +//#define LCD_I2C_PANELOLU2 + +// +// Panucatt VIKI LCD with status LEDs, +// integrated click & L/R/U/D buttons, separate encoder inputs. +// +//#define LCD_I2C_VIKI + +// +// SSD1306 OLED full graphics generic display +// +//#define U8GLIB_SSD1306 + +// +// SAV OLEd LCD module support using either SSD1306 or SH1106 based LCD modules +// +//#define SAV_3DGLCD +#if ENABLED(SAV_3DGLCD) + //#define U8GLIB_SSD1306 + #define U8GLIB_SH1106 +#endif + +// +// CONTROLLER TYPE: Shift register panels +// +// 2 wire Non-latching LCD SR from https://goo.gl/aJJ4sH +// LCD configuration: http://reprap.org/wiki/SAV_3D_LCD +// +//#define SAV_3DLCD + +// +// TinyBoy2 128x64 OLED / Encoder Panel +// +//#define OLED_PANEL_TINYBOY2 + +// +// Makeboard 3D Printer Parts 3D Printer Mini Display 1602 Mini Controller +// https://www.aliexpress.com/item/Micromake-Makeboard-3D-Printer-Parts-3D-Printer-Mini-Display-1602-Mini-Controller-Compatible-with-Ramps-1/32765887917.html +// +//#define MAKEBOARD_MINI_2_LINE_DISPLAY_1602 + +// +// MKS MINI12864 with graphic controller and SD support +// http://reprap.org/wiki/MKS_MINI_12864 +// +//#define MKS_MINI_12864 + +// +// Factory display for Creality CR-10 +// https://www.aliexpress.com/item/Universal-LCD-12864-3D-Printer-Display-Screen-With-Encoder-For-CR-10-CR-7-Model/32833148327.html +// +// This is RAMPS-compatible using a single 10-pin connector. +// (For CR-10 owners who want to replace the Melzi Creality board but retain the display) +// +//#define CR10_STOCKDISPLAY + +// +// MKS OLED 1.3" 128 × 64 FULL GRAPHICS CONTROLLER +// http://reprap.org/wiki/MKS_12864OLED +// +// Tiny, but very sharp OLED display +// +//#define MKS_12864OLED + +//============================================================================= +//=============================== Extra Features ============================== +//============================================================================= + +// @section extras + +// Increase the FAN PWM frequency. Removes the PWM noise but increases heating in the FET/Arduino +#define FAST_PWM_FAN + +// Use software PWM to drive the fan, as for the heaters. This uses a very low frequency +// which is not as annoying as with the hardware PWM. On the other hand, if this frequency +// is too low, you should also increment SOFT_PWM_SCALE. +//#define FAN_SOFT_PWM + +// Incrementing this by 1 will double the software PWM frequency, +// affecting heaters, and the fan if FAN_SOFT_PWM is enabled. +// However, control resolution will be halved for each increment; +// at zero value, there are 128 effective control positions. +#define SOFT_PWM_SCALE 0 + +// If SOFT_PWM_SCALE is set to a value higher than 0, dithering can +// be used to mitigate the associated resolution loss. If enabled, +// some of the PWM cycles are stretched so on average the desired +// duty cycle is attained. +//#define SOFT_PWM_DITHER + +// Temperature status LEDs that display the hotend and bed temperature. +// If all hotends, bed temperature, and target temperature are under 54C +// then the BLUE led is on. Otherwise the RED led is on. (1C hysteresis) +//#define TEMP_STAT_LEDS + +// M240 Triggers a camera by emulating a Canon RC-1 Remote +// Data from: http://www.doc-diy.net/photo/rc-1_hacked/ +//#define PHOTOGRAPH_PIN 23 + +// 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 + +// Support for BlinkM/CyzRgb +//#define BLINKM + +// Support for PCA9632 PWM LED driver +//#define PCA9632 + +/** + * RGB LED / LED Strip Control + * + * Enable support for an RGB LED connected to 5V digital pins, or + * an RGB Strip connected to MOSFETs controlled by digital pins. + * + * 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 overall brightness parameters is also available + * + * *** CAUTION *** + * LED Strips require a MOFSET 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! + * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino + * cannot handle such current, separate 5V power supply must be used + * *** CAUTION *** + * + * LED type. This options are mutualy exclusive. Uncomment only one. + * + */ +//#define RGB_LED +//#define RGBW_LED + +#if ENABLED(RGB_LED) || ENABLED(RGBW_LED) + #define RGB_LED_R_PIN 34 + #define RGB_LED_G_PIN 43 + #define RGB_LED_B_PIN 35 + #define RGB_LED_W_PIN -1 +#endif + +// 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 (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) + #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip + #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time + #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + //#define NEOPIXEL_STARTUP_TEST // Cycle through colors at startup +#endif + +/** + * Printer Event LEDs + * + * During printing, the LEDs will reflect the printer status: + * + * - Gradually change from blue to violet as the heated bed gets to target temp + * - Gradually change from violet to red as the hotend gets to temperature + * - Change to white to illuminate work surface + * - Change to green once print has finished + * - Turn off after the print has finished and the user has pushed a button + */ +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) + #define PRINTER_EVENT_LEDS +#endif + +/*********************************************************************\ +* R/C SERVO support +* Sponsored by TrinityLabs, Reworked by codexmas +**********************************************************************/ + +// Number of servos +// +// If you select a configuration below, this will receive a default value and does not need to be set manually +// set it manually if you have more servos than extruders and wish to manually control some +// leaving it undefined or defining as 0 will disable the servo subsystem +// If unsure, leave commented / disabled +// +//#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command + +// Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. +// 300ms is a good value but you can try less delay. +// If the servo can't reach the requested position, increase it. +#define SERVO_DELAY { 300 } + +// Servo deactivation +// +// With this option servos are powered only during movement, then turned off to prevent jitter. +//#define DEACTIVATE_SERVOS_AFTER_MOVE + +/** + * Filament Width Sensor + * + * Measures the filament width in real-time and adjusts + * flow rate to compensate for any irregularities. + * + * Also allows the measured filament diameter to set the + * extrusion rate, so the slicer only has to specify the + * volume. + * + * Only a single extruder is supported at this time. + * + * 34 RAMPS_14 : Analog input 5 on the AUX2 connector + * 81 PRINTRBOARD : Analog input 2 on the Exp1 connector (version B,C,D,E) + * 301 RAMBO : Analog input 3 + * + * Note: May require analog pins to be defined for other boards. + */ +//#define FILAMENT_WIDTH_SENSOR + +#define DEFAULT_NOMINAL_FILAMENT_DIA 3.00 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. + +#if ENABLED(FILAMENT_WIDTH_SENSOR) + #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) + #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber + + #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading + #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading + #define MAX_MEASUREMENT_DELAY 20 // (bytes) Buffer size for stored measurements (1 byte per cm). Must be larger than MEASUREMENT_DELAY_CM. + + #define DEFAULT_MEASURED_FILAMENT_DIA DEFAULT_NOMINAL_FILAMENT_DIA // Set measured to nominal initially + + // Display filament width on the LCD status line. Status messages will expire after 5 seconds. + //#define FILAMENT_LCD_DISPLAY +#endif + +#endif // CONFIGURATION_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/Felix/README.md b/trunk/Arduino/Marlin_1.1.6/example_configurations/Felix/README.md new file mode 100644 index 00000000..b1b8f367 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/Felix/README.md @@ -0,0 +1,60 @@ +# Felix 2.0/3.0 Configuration for Marlin Firmware + +Bringing silky smooth prints to Felix. + +## Build HOWTO + + - Install the latest non-beta Arduino software IDE/toolset: http://www.arduino.cc/en/Main/Software + - Download the Marlin firmware + - [Latest developement version](https://github.com/MarlinFirmware/Marlin/tree/Development) + - [Stable version](https://github.com/MarlinFirmware/Marlin/tree/Development) + - In both cases use the "Download Zip" button on the right. + +``` +cd Marlin/Marlin +cp example_configurations/Felix/Configuration_adv.h . +``` + +The next step depends on your setup: + +### Single Extruder Configuration + + cp example_configurations/Felix/Configuration.h . + +### Dual Extruder Configuration + + cp example_configurations/Felix/DUAL/Configuration.h Configuration.h + +### Compile Firmware + + - Start the Arduino IDE. + - Select Tools -> Board -> Arduino Mega 2560 + - Select the correct serial port in Tools -> Serial Port (usually /dev/ttyUSB0) + - Open Marlin.pde or .ino + - Click the Verify/Compile button + +### Flash Firmware + +#### Connected directly via USB + + - Click the Upload button. If all goes well the firmware is uploading + +#### Remote update + +Find the latest Arduino build: + + ls -altr /tmp/ + drwxr-xr-x 5 chrono users 12288 Mar 3 21:41 build6072035599686630843.tmp + +Copy the firmware to your printer host: + + scp /tmp/build6072035599686630843.tmp/Marlin.cpp.hex a.b.c.d:/tmp/ + +Connect to your printer host via ssh, stop Octoprint or any other service that may block your USB device and make sure you have avrdude installed, then run: + + avrdude -C/etc/avrdude.conf -v -v -v -patmega2560 -cwiring -P/dev/ttyUSB0 \ + -b115200 -D -Uflash:w:/tmp/Marlin.cpp.hex:i + +## Acknowledgements + +Mashed together and tested on https://apollo.open-resource.org/mission:resources:picoprint based on collaborative teamwork of @andrewsil1 and @thinkyhead. diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/Folger Tech/i3-2020/Configuration.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/Folger Tech/i3-2020/Configuration.h new file mode 100644 index 00000000..fea2f2eb --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/Folger Tech/i3-2020/Configuration.h @@ -0,0 +1,1705 @@ +/** + * 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 . + * + */ + +/** + * Configuration.h + * + * Basic settings such as: + * + * - Type of electronics + * - Type of temperature sensor + * - Printer geometry + * - Endstop configuration + * - LCD controller + * - Extra features + * + * Advanced settings can be found in Configuration_adv.h + * + */ +#ifndef CONFIGURATION_H +#define CONFIGURATION_H +#define CONFIGURATION_H_VERSION 010100 + +//=========================================================================== +//============================= Getting Started ============================= +//=========================================================================== + +/** + * Here are some standard links for getting your machine calibrated: + * + * http://reprap.org/wiki/Calibration + * http://youtu.be/wAL9d7FgInk + * http://calculator.josefprusa.cz + * http://reprap.org/wiki/Triffid_Hunter%27s_Calibration_Guide + * http://www.thingiverse.com/thing:5573 + * https://sites.google.com/site/repraplogphase/calibration-of-your-reprap + * http://www.thingiverse.com/thing:298812 + */ + +//=========================================================================== +//============================= DELTA Printer =============================== +//=========================================================================== +// For a Delta printer start with one of the configuration files in the +// example_configurations/delta directory and customize for your machine. +// + +//=========================================================================== +//============================= SCARA Printer =============================== +//=========================================================================== +// For a SCARA printer start with the configuration files in +// example_configurations/SCARA and customize for your machine. +// + +// @section info + +// User-specified version info of this build to display in [Pronterface, etc] terminal window during +// startup. Implementation of an idea by Prof Braino to inform user that any changes made to this +// build by the user have been successfully uploaded into firmware. +#define STRING_CONFIG_H_AUTHOR "(none, default config)" // Who made the changes. +#define SHOW_BOOTSCREEN +#define STRING_SPLASH_LINE1 SHORT_BUILD_VERSION // will be shown during bootup in line 1 +#define STRING_SPLASH_LINE2 WEBSITE_URL // will be shown during bootup in line 2 + +// +// *** VENDORS PLEASE READ ***************************************************** +// +// Marlin now allow you to have a vendor boot image to be displayed on machine +// start. When SHOW_CUSTOM_BOOTSCREEN is defined Marlin will first show your +// custom boot image and then the default Marlin boot image is shown. +// +// We suggest for you to take advantage of this new feature and keep the Marlin +// boot image unmodified. For an example have a look at the bq Hephestos 2 +// example configuration folder. +// +//#define SHOW_CUSTOM_BOOTSCREEN +// @section machine + +/** + * Select which serial port on the board will be used for communication with the host. + * This allows the connection of wireless adapters (for instance) to non-default port pins. + * Serial port 0 is always used by the Arduino bootloader regardless of this setting. + * + * :[0, 1, 2, 3, 4, 5, 6, 7] + */ +#define SERIAL_PORT 0 + +/** + * This setting determines the communication speed of the printer. + * + * 250000 works in most cases, but you might try a lower speed if + * you commonly experience drop-outs during host printing. + * You may try up to 1000000 to speed up SD file transfer. + * + * :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000] + */ +#define BAUDRATE 250000 + +// Enable the Bluetooth serial interface on AT90USB devices +//#define BLUETOOTH + +// The following define selects which electronics board you have. +// Please choose the name from boards.h that matches your setup +#ifndef MOTHERBOARD + #define MOTHERBOARD BOARD_RAMPS_14_EFB +#endif + +// Optional custom name for your RepStrap or other custom machine +// Displayed in the LCD "Ready" message +#define CUSTOM_MACHINE_NAME "FT-2020" + +// Define this to set a unique identifier for this printer, (Used by some programs to differentiate between machines) +// You can use an online service to generate a random UUID. (eg http://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] +#define EXTRUDERS 1 + +// For Cyclops or any "multi-extruder" that shares a single nozzle. +//#define SINGLENOZZLE + +/** + * Průša MK2 Single Nozzle Multi-Material Multiplexer, and variants. + * + * This device allows one stepper driver on a control board to drive + * two to eight stepper motors, one at a time, in a manner suitable + * for extruders. + * + * This option only allows the multiplexer to switch on tool-change. + * Additional options to configure custom E moves are pending. + */ +//#define MK2_MULTIPLEXER +#if ENABLED(MK2_MULTIPLEXER) + // Override the default DIO selector pins here, if needed. + // Some pins files may provide defaults for these pins. + //#define E_MUX0_PIN 40 // Always Required + //#define E_MUX1_PIN 42 // Needed for 3 to 8 steppers + //#define E_MUX2_PIN 44 // Needed for 5 to 8 steppers +#endif + +// A dual extruder that uses a single stepper motor +//#define SWITCHING_EXTRUDER +#if ENABLED(SWITCHING_EXTRUDER) + #define SWITCHING_EXTRUDER_SERVO_NR 0 + #define SWITCHING_EXTRUDER_SERVO_ANGLES { 0, 90 } // Angles for E0, E1[, E2, E3] + #if EXTRUDERS > 3 + #define SWITCHING_EXTRUDER_E23_SERVO_NR 1 + #endif +#endif + +// A dual-nozzle that uses a servomotor to raise/lower one of the nozzles +//#define SWITCHING_NOZZLE +#if ENABLED(SWITCHING_NOZZLE) + #define SWITCHING_NOZZLE_SERVO_NR 0 + #define SWITCHING_NOZZLE_SERVO_ANGLES { 0, 90 } // Angles for E0, E1 + //#define HOTEND_OFFSET_Z { 0.0, 0.0 } +#endif + +/** + * Two separate X-carriages with extruders that connect to a moving part + * via a magnetic docking mechanism. Requires SOL1_PIN and SOL2_PIN. + */ +//#define PARKING_EXTRUDER +#if ENABLED(PARKING_EXTRUDER) + #define PARKING_EXTRUDER_SOLENOIDS_INVERT // If enabled, the solenoid is NOT magnetized with applied voltage + #define PARKING_EXTRUDER_SOLENOIDS_PINS_ACTIVE LOW // LOW or HIGH pin signal energizes the coil + #define PARKING_EXTRUDER_SOLENOIDS_DELAY 250 // Delay (ms) for magnetic field. No delay if 0 or not defined. + #define PARKING_EXTRUDER_PARKING_X { -78, 184 } // X positions for parking the extruders + #define PARKING_EXTRUDER_GRAB_DISTANCE 1 // mm to move beyond the parking point to grab the extruder + #define PARKING_EXTRUDER_SECURITY_RAISE 5 // Z-raise before parking + #define HOTEND_OFFSET_Z { 0.0, 1.3 } // Z-offsets of the two hotends. The first must be 0. +#endif + +/** + * "Mixing Extruder" + * - Adds a new code, M165, to set the current mix factors. + * - Extends the stepping routines to move multiple steppers in proportion to the mix. + * - Optional support for Repetier Firmware M163, M164, and virtual extruder. + * - This implementation supports only a single extruder. + * - Enable DIRECT_MIXING_IN_G1 for Pia Taubert's reference implementation + */ +//#define MIXING_EXTRUDER +#if ENABLED(MIXING_EXTRUDER) + #define MIXING_STEPPERS 2 // Number of steppers in your mixing extruder + #define MIXING_VIRTUAL_TOOLS 16 // Use the Virtual Tool method with M163 and M164 + //#define DIRECT_MIXING_IN_G1 // Allow ABCDHI mix factors in G1 movement commands +#endif + +// Offset of the extruders (uncomment if using more than one and relying on firmware to position when changing). +// The offset has to be X=0, Y=0 for the extruder 0 hotend (default extruder). +// For the other hotends it is their distance from the extruder 0 hotend. +//#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis +//#define HOTEND_OFFSET_Y {0.0, 5.00} // (in mm) for each extruder, offset of the hotend on the Y axis + +// @section machine + +/** + * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN + * + * 0 = No Power Switch + * 1 = ATX + * 2 = X-Box 360 203Watts (the blue wire connected to PS_ON and the red wire to VCC) + * + * :{ 0:'No power switch', 1:'ATX', 2:'X-Box 360' } + */ +#define POWER_SUPPLY 0 + +#if POWER_SUPPLY > 0 + // Enable this option to leave the PSU off at startup. + // Power to steppers and heaters will need to be turned on with M80. + //#define PS_DEFAULT_OFF +#endif + +// @section temperature + +//=========================================================================== +//============================= Thermal Settings ============================ +//=========================================================================== + +/** + * --NORMAL IS 4.7kohm PULLUP!-- 1kohm pullup can be used on hotend sensor, using correct resistor and table + * + * Temperature sensors available: + * + * -3 : thermocouple with MAX31855 (only for sensor 0) + * -2 : thermocouple with MAX6675 (only for sensor 0) + * -1 : thermocouple with AD595 + * 0 : not used + * 1 : 100k thermistor - best choice for EPCOS 100k (4.7k pullup) + * 2 : 200k thermistor - ATC Semitec 204GT-2 (4.7k pullup) + * 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 (Used in ParCan & J-Head) (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) + * 71 : 100k Honeywell thermistor 135-104LAF-J01 (4.7k pullup) + * 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) + * 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" + * 20 : the PT100 circuit found in the Ultimainboard V2.x + * 60 : 100k Maker's Tool Works Kapton Bed Thermistor beta=3950 + * 66 : 4.7M High Temperature thermistor from Dyze Design + * 70 : the 100K thermistor found in the bq Hephestos 2 + * 75 : 100k Generic Silicon Heat Pad with NTC 100K MGB18-104F39050L32 thermistor + * + * 1k ohm pullup tables - This is atypical, and requires changing out the 4.7k pullup for 1k. + * (but gives greater accuracy and more stable PID) + * 51 : 100k thermistor - EPCOS (1k pullup) + * 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 + * 1010 : Pt1000 with 1k pullup (non standard) + * 147 : Pt100 with 4k7 pullup + * 110 : Pt100 with 1k pullup (non standard) + * + * Use these for Testing or Development purposes. NEVER for production machine. + * 998 : Dummy Table that ALWAYS reads 25°C or the temperature defined below. + * 999 : Dummy Table that ALWAYS reads 100°C or the temperature defined below. + * + * :{ '0': "Not used", '1':"100k / 4.7k - EPCOS", '2':"200k / 4.7k - ATC Semitec 204GT-2", '3':"Mendel-parts / 4.7k", '4':"10k !! do not use for a hotend. Bad resolution at high temp. !!", '5':"100K / 4.7k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '6':"100k / 4.7k EPCOS - Not as accurate as Table 1", '7':"100k / 4.7k Honeywell 135-104LAG-J01", '8':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT", '9':"100k / 4.7k GE Sensing AL03006-58.2K-97-G1", '10':"100k / 4.7k RS 198-961", '11':"100k / 4.7k beta 3950 1%", '12':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT (calibrated for Makibox hot bed)", '13':"100k Hisens 3950 1% up to 300°C for hotend 'Simple ONE ' & hotend 'All In ONE'", '20':"PT100 (Ultimainboard V2.x)", '51':"100k / 1k - EPCOS", '52':"200k / 1k - ATC Semitec 204GT-2", '55':"100k / 1k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '60':"100k Maker's Tool Works Kapton Bed Thermistor beta=3950", '66':"Dyze Design 4.7M High Temperature thermistor", '70':"the 100K thermistor found in the bq Hephestos 2", '71':"100k / 4.7k Honeywell 135-104LAF-J01", '147':"Pt100 / 4.7k", '1047':"Pt1000 / 4.7k", '110':"Pt100 / 1k (non-standard)", '1010':"Pt1000 / 1k (non standard)", '-3':"Thermocouple + MAX31855 (only for sensor 0)", '-2':"Thermocouple + MAX6675 (only for sensor 0)", '-1':"Thermocouple + AD595",'998':"Dummy 1", '999':"Dummy 2" } + */ +#define TEMP_SENSOR_0 5 +#define TEMP_SENSOR_1 0 +#define TEMP_SENSOR_2 0 +#define TEMP_SENSOR_3 0 +#define TEMP_SENSOR_4 0 +#define TEMP_SENSOR_BED 1 + +// Dummy thermistor constant temperature readings, for use with 998 and 999 +#define DUMMY_THERMISTOR_998_VALUE 25 +#define DUMMY_THERMISTOR_999_VALUE 100 + +// 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 +#define MAX_REDUNDANT_TEMP_SENSOR_DIFF 10 + +// Extruder temperature must be close to target for this long before M109 returns success +#define TEMP_RESIDENCY_TIME 10 // (seconds) +#define TEMP_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// Bed temperature must be close to target for this long before M190 returns success +#define TEMP_BED_RESIDENCY_TIME 10 // (seconds) +#define TEMP_BED_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_BED_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// The minimal temperature defines the temperature below which the heater will not be enabled It is used +// to check that the wiring to the thermistor is not broken. +// Otherwise this would lead to the heater being powered on all the time. +#define HEATER_0_MINTEMP 5 +#define HEATER_1_MINTEMP 5 +#define HEATER_2_MINTEMP 5 +#define HEATER_3_MINTEMP 5 +#define HEATER_4_MINTEMP 5 +#define BED_MINTEMP 5 + +// When temperature exceeds max temp, your heater will be switched off. +// This feature exists to protect your hotend from overheating accidentally, but *NOT* from thermistor short/failure! +// You should use MINTEMP for thermistor short/failure protection. +#define HEATER_0_MAXTEMP 245 +#define HEATER_1_MAXTEMP 245 +#define HEATER_2_MAXTEMP 245 +#define HEATER_3_MAXTEMP 245 +#define HEATER_4_MAXTEMP 245 +#define BED_MAXTEMP 115 + +//=========================================================================== +//============================= PID Settings ================================ +//=========================================================================== +// PID Tuning Guide here: http://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 +#if ENABLED(PIDTEMP) + //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. + //#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. + #define K1 0.95 //smoothing factor within the PID + + // If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it + + // FolgerTech i3-2020 + #define DEFAULT_Kp 11.50 + #define DEFAULT_Ki 0.50 + #define DEFAULT_Kd 60.00 + + // 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 + +#endif // PIDTEMP + +//=========================================================================== +//============================= PID > Bed Temperature Control =============== +//=========================================================================== +// Select PID or bang-bang with PIDTEMPBED. If bang-bang, BED_LIMIT_SWITCHING will enable hysteresis +// +// Uncomment this to enable PID on the bed. It uses the same frequency PWM as the extruder. +// If your PID_dT is the default, and correct for your hardware/configuration, that means 7.689Hz, +// which is fine for driving a square wave into a resistive load and does not significantly impact you FET heating. +// This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W heater. +// If your configuration is significantly different than this and you don't understand the issues involved, you probably +// shouldn't use bed PID until someone else verifies your hardware works. +// If this is enabled, find your own PID constants below. +#define PIDTEMPBED + +//#define BED_LIMIT_SWITCHING + +// This sets the max power delivered to the bed, and replaces the HEATER_BED_DUTY_CYCLE_DIVIDER option. +// all forms of bed control obey this (PID, bang-bang, bang-bang with hysteresis) +// setting this to anything other than 255 enables a form of PWM to the bed just like HEATER_BED_DUTY_CYCLE_DIVIDER did, +// so you shouldn't use it unless you are OK with PWM on your bed. (see the comment on enabling PIDTEMPBED) +#define MAX_BED_POWER 255 // limits duty cycle to bed; 255=full current + +#if ENABLED(PIDTEMPBED) + + //#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) + #define DEFAULT_bedKp 250.0 + #define DEFAULT_bedKi 18.0 + #define DEFAULT_bedKd 950.0 + + //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 + +// @section extruder + +// This option prevents extrusion if the temperature is below EXTRUDE_MINTEMP. +// It also enables the M302 command to set the minimum extrusion temperature +// or to allow moving the extruder regardless of the hotend temperature. +// *** IT IS HIGHLY RECOMMENDED TO LEAVE THIS OPTION ENABLED! *** +#define PREVENT_COLD_EXTRUSION +#define EXTRUDE_MINTEMP 170 + +// This option prevents a single extrusion longer than EXTRUDE_MAXLENGTH. +// Note that for Bowden Extruders a too-small value here may prevent loading. +#define PREVENT_LENGTHY_EXTRUDE +#define EXTRUDE_MAXLENGTH 200 + +//=========================================================================== +//======================== Thermal Runaway Protection ======================= +//=========================================================================== + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * If you get "Thermal Runaway" or "Heating failed" errors the + * details can be tuned in Configuration_adv.h + */ + +#define THERMAL_PROTECTION_HOTENDS // Enable thermal protection for all extruders +#define THERMAL_PROTECTION_BED // Enable thermal protection for the heated bed + +//=========================================================================== +//============================= Mechanical Settings ========================= +//=========================================================================== + +// @section machine + +// Uncomment one of these options to enable CoreXY, CoreXZ, or CoreYZ kinematics +// either in the usual order or reversed +//#define COREXY +//#define COREXZ +//#define COREYZ +//#define COREYX +//#define COREZX +//#define COREZY + +//=========================================================================== +//============================== Endstop Settings =========================== +//=========================================================================== + +// @section homing + +// Specify here all the endstop connectors that are connected to any endstop or probe. +// Almost all printers will be using one per axis. Probes will use one or more of the +// extra connectors. Leave undefined any used for non-endstop and non-probe purposes. +#define USE_XMIN_PLUG +#define USE_YMIN_PLUG +#define USE_ZMIN_PLUG +//#define USE_XMAX_PLUG +//#define USE_YMAX_PLUG +//#define USE_ZMAX_PLUG + +// coarse Endstop Settings +#define ENDSTOPPULLUPS // Comment this out (using // at the start of the line) to disable the endstop pullup resistors + +#if DISABLED(ENDSTOPPULLUPS) + // fine endstop settings: Individual pullups. will be ignored if ENDSTOPPULLUPS is defined + //#define ENDSTOPPULLUP_XMAX + //#define ENDSTOPPULLUP_YMAX + //#define ENDSTOPPULLUP_ZMAX + //#define ENDSTOPPULLUP_XMIN + //#define ENDSTOPPULLUP_YMIN + //#define ENDSTOPPULLUP_ZMIN + //#define ENDSTOPPULLUP_ZMIN_PROBE +#endif + +// Mechanical endstop with COM to ground and NC to Signal uses "false" here (most common setup). +#define X_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Y_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define X_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Y_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MIN_PROBE_ENDSTOP_INVERTING true // set to true to invert the logic of the probe. + +// Enable this feature if all enabled endstop pins are interrupt-capable. +// This will remove the need to poll the interrupt pins, saving many CPU cycles. +//#define ENDSTOP_INTERRUPTS_FEATURE + +//============================================================================= +//============================== Movement Settings ============================ +//============================================================================= +// @section motion + +/** + * Default Settings + * + * These settings can be reset by M502 + * + * Note that if EEPROM is enabled, saved values will override these. + */ + +/** + * With this option each E stepper can have its own factors for the + * following movement settings. If fewer factors are given than the + * total number of extruders, the last value applies to the rest. + */ +//#define DISTINCT_E_FACTORS + +/** + * Default Axis Steps Per Unit (steps/mm) + * Override with M92 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_AXIS_STEPS_PER_UNIT { 80, 80, 4000, 52.2 } + +/** + * Default Max Feed Rate (mm/s) + * Override with M203 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_FEEDRATE { 250, 250, 2, 17 } + +/** + * Default Max Acceleration (change/s) change = mm/s + * (Maximum start speed for accelerated moves) + * Override with M201 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_ACCELERATION { 1000, 1000, 4, 750 } + +/** + * Default Acceleration (change/s) change = mm/s + * Override with M204 + * + * M204 P Acceleration + * M204 R Retract Acceleration + * M204 T Travel Acceleration + */ +#define DEFAULT_ACCELERATION 500 // X, Y, Z and E acceleration for printing moves +#define DEFAULT_RETRACT_ACCELERATION 400 // E acceleration for retracts +#define DEFAULT_TRAVEL_ACCELERATION 400 // X, Y, Z acceleration for travel (non printing) moves + +/** + * Default Jerk (mm/s) + * Override with M205 X Y Z E + * + * "Jerk" specifies the minimum speed change that requires acceleration. + * When changing speed and direction, if the difference is less than the + * value set here, it may happen instantaneously. + */ +#define DEFAULT_XJERK 17.0 +#define DEFAULT_YJERK 17.0 +#define DEFAULT_ZJERK 0.4 +#define DEFAULT_EJERK 4.0 + +//=========================================================================== +//============================= Z Probe Options ============================= +//=========================================================================== +// @section probes + +// +// See http://marlinfw.org/configuration/probes.html +// + +/** + * Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + * + * Enable this option for a probe connected to the Z Min endstop pin. + */ +#define Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + +/** + * Z_MIN_PROBE_ENDSTOP + * + * Enable this option for a probe connected to any pin except Z-Min. + * (By default Marlin assumes the Z-Max endstop pin.) + * To use a custom Z Probe pin, set Z_MIN_PROBE_PIN below. + * + * - The simplest option is to use a free endstop connector. + * - Use 5V for powered (usually inductive) sensors. + * + * - RAMPS 1.3/1.4 boards may use the 5V, GND, and Aux4->D32 pin: + * - For simple switches connect... + * - normally-closed switches to GND and D32. + * - normally-open switches to 5V and D32. + * + * WARNING: Setting the wrong pin may have unexpected and potentially + * disastrous consequences. Use with caution and do your homework. + * + */ +//#define Z_MIN_PROBE_ENDSTOP + +/** + * Probe Type + * + * Allen Key Probes, Servo Probes, Z-Sled Probes, FIX_MOUNTED_PROBE, etc. + * Activate one of these to use Auto Bed Leveling below. + */ + +/** + * The "Manual Probe" provides a means to do "Auto" Bed Leveling without a probe. + * Use G29 repeatedly, adjusting the Z height at each point with movement commands + * or (with LCD_BED_LEVELING) the LCD controller. + */ +//#define PROBE_MANUALLY + +/** + * A Fix-Mounted Probe either doesn't deploy or needs manual deployment. + * (e.g., an inductive probe or a nozzle-based probe-switch.) + */ +//#define FIX_MOUNTED_PROBE + +/** + * Z Servo Probe, such as an endstop switch on a rotating arm. + */ +#define Z_ENDSTOP_SERVO_NR 0 // Defaults to SERVO 0 connector. +#define Z_SERVO_ANGLES {40,85} // Z Servo Deploy and Stow angles + +/** + * The BLTouch probe uses a Hall effect sensor and emulates a servo. + */ +//#define BLTOUCH +#if ENABLED(BLTOUCH) + //#define BLTOUCH_DELAY 375 // (ms) Enable and increase if needed +#endif + +/** + * Enable one or more of the following if probing seems unreliable. + * Heaters and/or fans can be disabled during probing to minimize electrical + * noise. A delay can also be added to allow noise and vibration to settle. + * These options are most useful for the BLTouch probe, but may also improve + * readings with inductive probes and piezo sensors. + */ +//#define PROBING_HEATERS_OFF // Turn heaters off when probing +//#define PROBING_FANS_OFF // Turn fans off when probing +//#define DELAY_BEFORE_PROBING 200 // (ms) To prevent vibrations from triggering piezo sensors + +// A probe that is deployed and stowed with a solenoid pin (SOL1_PIN) +//#define SOLENOID_PROBE + +// A sled-mounted probe like those designed by Charles Bell. +//#define Z_PROBE_SLED +//#define SLED_DOCKING_OFFSET 5 // The extra distance the X axis must travel to pickup the sled. 0 should be fine but you can push it further if you'd like. + +// +// For Z_PROBE_ALLEN_KEY see the Delta example configurations. +// + +/** + * Z Probe to nozzle (X,Y) offset, relative to (0, 0). + * X and Y offsets must be integers. + * + * In the following example the X and Y offsets are both positive: + * #define X_PROBE_OFFSET_FROM_EXTRUDER 10 + * #define Y_PROBE_OFFSET_FROM_EXTRUDER 10 + * + * +-- BACK ---+ + * | | + * L | (+) P | R <-- probe (20,20) + * E | | I + * F | (-) N (+) | G <-- nozzle (10,10) + * T | | H + * | (-) | T + * | | + * O-- FRONT --+ + * (0,0) + */ +#define X_PROBE_OFFSET_FROM_EXTRUDER 38 // X offset: -left +right [of the nozzle] +#define Y_PROBE_OFFSET_FROM_EXTRUDER -7 // Y offset: -front +behind [the nozzle] +#define Z_PROBE_OFFSET_FROM_EXTRUDER -10.4 // Z offset: -below +above [the nozzle] + +// X and Y axis travel speed (mm/m) between probes +#define XY_PROBE_SPEED 7500 +// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +#define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z + +// Speed for the "accurate" probe of each point +#define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) + +// Use double touch for probing +//#define PROBE_DOUBLE_TOUCH + +/** + * Z probes require clearance when deploying, stowing, and moving between + * probe points to avoid hitting the bed and other hardware. + * Servo-mounted probes require extra space for the arm to rotate. + * Inductive probes need space to keep from triggering early. + * + * Use these settings to specify the distance (mm) to raise the probe (or + * lower the bed). The values set here apply over and above any (negative) + * probe Z Offset set with Z_PROBE_OFFSET_FROM_EXTRUDER, M851, or the LCD. + * Only integer values >= 1 are valid here. + * + * Example: `M851 Z-5` with a CLEARANCE of 4 => 9mm from bed to nozzle. + * But: `M851 Z+1` with a CLEARANCE of 2 => 2mm from bed to nozzle. + */ +#define Z_CLEARANCE_DEPLOY_PROBE 3 // Z Clearance for Deploy/Stow +#define Z_CLEARANCE_BETWEEN_PROBES 3 // Z Clearance between probe points + +// For M851 give a range for adjusting the Z probe offset +#define Z_PROBE_OFFSET_RANGE_MIN -20 +#define Z_PROBE_OFFSET_RANGE_MAX 20 + +// Enable the M48 repeatability test to test probe accuracy +#define Z_MIN_PROBE_REPEATABILITY_TEST + +// For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1 +// :{ 0:'Low', 1:'High' } +#define X_ENABLE_ON 0 +#define Y_ENABLE_ON 0 +#define Z_ENABLE_ON 0 +#define E_ENABLE_ON 0 // For all extruders + +// Disables axis stepper immediately when it's not being used. +// 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 +//#define DISABLE_REDUCED_ACCURACY_WARNING + +// @section extruder + +#define DISABLE_E false // For all extruders +#define DISABLE_INACTIVE_EXTRUDER true // Keep only the active extruder enabled. + +// @section machine + +// Invert the stepper direction. Change (or reverse the motor connector) if an axis goes the wrong way. +#define INVERT_X_DIR false +#define INVERT_Y_DIR true +#define INVERT_Z_DIR true +// Enable this option for Toshiba stepper drivers +//#define CONFIG_STEPPERS_TOSHIBA + +// @section extruder + +// For direct drive extruder v9 set to true, for geared extruder set to false. +#define INVERT_E0_DIR true +#define INVERT_E1_DIR false +#define INVERT_E2_DIR false +#define INVERT_E3_DIR false +#define INVERT_E4_DIR false + +// @section homing + +//#define NO_MOTION_BEFORE_HOMING // Inhibit movement until all axes have been homed + +#define Z_HOMING_HEIGHT 2 // (in mm) Minimal z height before homing (G28) for Z clearance above the bed, clamps, ... + // Be sure you have this distance over your Z_MAX_POS in case. + +// Direction of endstops when homing; 1=MAX, -1=MIN +// :[-1,1] +#define X_HOME_DIR -1 +#define Y_HOME_DIR -1 +#define Z_HOME_DIR -1 + +// @section machine + +// The size of the print bed +#define X_BED_SIZE 207 +#define Y_BED_SIZE 182 + +// Travel limits (mm) after homing, corresponding to endstop positions. +#define X_MIN_POS 6 +#define Y_MIN_POS 3 +#define Z_MIN_POS 0 +#define X_MAX_POS X_BED_SIZE +#define Y_MAX_POS Y_BED_SIZE +#define Z_MAX_POS 175 + +// If enabled, axes won't move below MIN_POS in response to movement commands. +//#define MIN_SOFTWARE_ENDSTOPS +// If enabled, axes won't move above MAX_POS in response to movement commands. +#define MAX_SOFTWARE_ENDSTOPS + +/** + * Filament Runout Sensor + * A mechanical or opto endstop is used to check for the presence of filament. + * + * RAMPS-based boards use SERVO3_PIN. + * For other boards you may need to define FIL_RUNOUT_PIN. + * By default the firmware assumes HIGH = has filament, LOW = ran out + */ +//#define FILAMENT_RUNOUT_SENSOR +#if ENABLED(FILAMENT_RUNOUT_SENSOR) + #define FIL_RUNOUT_INVERTING false // set to true to invert the logic of the sensor. + #define ENDSTOPPULLUP_FIL_RUNOUT // Uncomment to use internal pullup for filament runout pins if the sensor is defined. + #define FILAMENT_RUNOUT_SCRIPT "M600" +#endif + +//=========================================================================== +//=============================== Bed Leveling ============================== +//=========================================================================== +// @section bedlevel + +/** + * Choose one of the options below to enable G29 Bed Leveling. The parameters + * and behavior of G29 will change depending on your selection. + * + * If using a Probe for Z Homing, enable Z_SAFE_HOMING also! + * + * - AUTO_BED_LEVELING_3POINT + * Probe 3 arbitrary points on the bed (that aren't collinear) + * You specify the XY coordinates of all 3 points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_LINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_BILINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a mesh, best for large or uneven beds. + * + * - AUTO_BED_LEVELING_UBL (Unified Bed Leveling) + * A comprehensive bed leveling system combining the features and benefits + * of other systems. UBL also includes integrated Mesh Generation, Mesh + * Validation and Mesh Editing systems. Currently, UBL is only checked out + * for Cartesian Printers. That said, it was primarily designed to correct + * poor quality Delta Printers. If you feel adventurous and have a Delta, + * please post an issue if something doesn't work correctly. Initially, + * you will need to set a reduced bed size so you have a rectangular area + * to test on. + * + * - MESH_BED_LEVELING + * Probe a grid manually + * The result is a mesh, suitable for large or uneven beds. (See BILINEAR.) + * For machines without a probe, Mesh Bed Leveling provides a method to perform + * leveling in steps so you can manually adjust the Z height at each grid-point. + * With an LCD controller the process is guided step-by-step. + */ +//#define AUTO_BED_LEVELING_3POINT +//#define AUTO_BED_LEVELING_LINEAR +//#define AUTO_BED_LEVELING_BILINEAR +#define AUTO_BED_LEVELING_UBL +//#define MESH_BED_LEVELING + +/** + * Enable detailed logging of G28, G29, M48, etc. + * Turn on with the command 'M111 S32'. + * NOTE: Requires a lot of PROGMEM! + */ +//#define DEBUG_LEVELING_FEATURE + +#if ENABLED(MESH_BED_LEVELING) || ENABLED(AUTO_BED_LEVELING_BILINEAR) || ENABLED(AUTO_BED_LEVELING_UBL) + // Gradually reduce leveling correction until a set height is reached, + // at which point movement will be level to the machine's XY plane. + // The height can be set with M420 Z + #define ENABLE_LEVELING_FADE_HEIGHT +#endif + +#if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Set the number of grid points per dimension. + #define GRID_MAX_POINTS_X 3 + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + // Set the boundaries for probing (where the probe can reach). + #define LEFT_PROBE_BED_POSITION 39 + #define RIGHT_PROBE_BED_POSITION 170 + #define FRONT_PROBE_BED_POSITION 10 + #define BACK_PROBE_BED_POSITION 170 + + // The Z probe minimum outer margin (to validate G29 parameters). + #define MIN_PROBE_EDGE 10 + + // Probe along the Y axis, advancing X after each column + //#define PROBE_Y_FIRST + + #if ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Beyond the probed grid, continue the implied tilt? + // Default is to maintain the height of the nearest edge. + //#define EXTRAPOLATE_BEYOND_GRID + + // + // Experimental Subdivision of the grid by Catmull-Rom method. + // Synthesizes intermediate points to produce a more detailed mesh. + // + //#define ABL_BILINEAR_SUBDIVISION + #if ENABLED(ABL_BILINEAR_SUBDIVISION) + // Number of subdivisions between probe points + #define BILINEAR_SUBDIVISIONS 3 + #endif + + #endif + +#elif ENABLED(AUTO_BED_LEVELING_3POINT) + + // 3 arbitrary points to probe. + // A simple cross-product is used to estimate the plane of the bed. + #define ABL_PROBE_PT_1_X 39 + #define ABL_PROBE_PT_1_Y 170 + #define ABL_PROBE_PT_2_X 39 + #define ABL_PROBE_PT_2_Y 10 + #define ABL_PROBE_PT_3_X 170 + #define ABL_PROBE_PT_3_Y 10 + + + +#elif ENABLED(AUTO_BED_LEVELING_UBL) + + //=========================================================================== + //========================= Unified Bed Leveling ============================ + //=========================================================================== + + #define UBL_MESH_INSET 1 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 10 // Don't use more than 15 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y 10 + + #define UBL_PROBE_PT_1_X 45 // Probing points for 3-Point leveling of the mesh + #define UBL_PROBE_PT_1_Y 170 + #define UBL_PROBE_PT_2_X 45 + #define UBL_PROBE_PT_2_Y 25 + #define UBL_PROBE_PT_3_X 180 + #define UBL_PROBE_PT_3_Y 25 + + #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation + #define UBL_MESH_EDIT_MOVES_Z // Sophisticated users prefer no movement of nozzle + +#elif ENABLED(MESH_BED_LEVELING) + + //=========================================================================== + //=================================== Mesh ================================== + //=========================================================================== + + #define MESH_INSET 10 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 3 // Don't use more than 7 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + //#define MESH_G28_REST_ORIGIN // After homing all axes ('G28' or 'G28 XYZ') rest Z at Z_MIN_POS + +#endif // BED_LEVELING + +/** + * Use the LCD controller for bed leveling + * Requires MESH_BED_LEVELING or PROBE_MANUALLY + */ +//#define LCD_BED_LEVELING + +#if ENABLED(LCD_BED_LEVELING) + #define MBL_Z_STEP 0.025 // Step size while manually probing Z axis. + #define LCD_PROBE_Z_RANGE 4 // Z Range centered on Z_MIN_POS for LCD Z adjustment +#endif + +// Add a menu item to move between bed corners for manual bed adjustment +//#define LEVEL_BED_CORNERS + +/** + * Commands to execute at the end of G29 probing. + * Useful to retract or move the Z probe out of the way. + */ +//#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) +//#define BED_CENTER_AT_0_0 + +// Manually set the home position. Leave these undefined for automatic settings. +// For DELTA this is the top-center of the Cartesian print volume. +//#define MANUAL_X_HOME_POS 0 +//#define MANUAL_Y_HOME_POS 0 +//#define MANUAL_Z_HOME_POS 0 + +// Use "Z Safe Homing" to avoid homing with a Z probe outside the bed area. +// +// With this feature enabled: +// +// - 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). +// - 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 axis (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). +#endif + +// Homing speeds (mm/m) +#define HOMING_FEEDRATE_XY (40*60) +#define HOMING_FEEDRATE_Z (55) + +//============================================================================= +//============================= Additional Features =========================== +//============================================================================= + +// @section extras + +// +// EEPROM +// +// The microcontroller can store settings in the EEPROM, e.g. max velocity... +// M500 - stores parameters in EEPROM +// M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily). +// M502 - reverts to the default "factory settings". You still need to store them in EEPROM afterwards if you want to. +// +#define EEPROM_SETTINGS // Enable for M500 and M501 commands +//#define DISABLE_M503 // Saves ~2700 bytes of PROGMEM. Disable for release! +#define EEPROM_CHITCHAT // Give feedback on EEPROM commands. Disable to save PROGMEM. + +// +// Host Keepalive +// +// When enabled Marlin will send a busy status message to the host +// every couple of seconds when it can't accept commands. +// +//#define HOST_KEEPALIVE_FEATURE // Disable this if your host doesn't like keepalive messages +#define DEFAULT_KEEPALIVE_INTERVAL 2 // Number of seconds between "busy" messages. Set with M113. +#define BUSY_WHILE_HEATING // Some hosts require "busy" messages even during heating + +// +// M100 Free Memory Watcher +// +#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose + +// +// G20/G21 Inch mode support +// +//#define INCH_MODE_SUPPORT + +// +// M149 Set temperature units support +// +//#define TEMPERATURE_UNITS_SUPPORT + +// @section temperature + +// Preheat Constants +#define PREHEAT_1_TEMP_HOTEND 180 +#define PREHEAT_1_TEMP_BED 70 +#define PREHEAT_1_FAN_SPEED 0 // Value from 0 to 255 + +#define PREHEAT_2_TEMP_HOTEND 240 +#define PREHEAT_2_TEMP_BED 110 +#define PREHEAT_2_FAN_SPEED 0 // Value from 0 to 255 + +/** + * Nozzle Park -- EXPERIMENTAL + * + * Park the nozzle at the given XYZ position on idle or G27. + * + * The "P" parameter controls the action applied to the Z axis: + * + * P0 (Default) If Z is below park Z raise the nozzle. + * P1 Raise the nozzle always to Z-park height. + * P2 Raise the nozzle by Z-park amount, limited to Z_MAX_POS. + */ +//#define NOZZLE_PARK_FEATURE + +#if ENABLED(NOZZLE_PARK_FEATURE) + // Specify a park position as { X, Y, Z } + #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 } +#endif + +/** + * Clean Nozzle Feature -- EXPERIMENTAL + * + * Adds the G12 command to perform a nozzle cleaning process. + * + * Parameters: + * P Pattern + * S Strokes / Repetitions + * T Triangles (P1 only) + * + * Patterns: + * P0 Straight line (default). This process requires a sponge type material + * at a fixed bed location. "S" specifies strokes (i.e. back-forth motions) + * between the start / end points. + * + * P1 Zig-zag pattern between (X0, Y0) and (X1, Y1), "T" specifies the + * number of zig-zag triangles to do. "S" defines the number of strokes. + * Zig-zags are done in whichever is the narrower dimension. + * For example, "G12 P1 S1 T3" will execute: + * + * -- + * | (X0, Y1) | /\ /\ /\ | (X1, Y1) + * | | / \ / \ / \ | + * A | | / \ / \ / \ | + * | | / \ / \ / \ | + * | (X0, Y0) | / \/ \/ \ | (X1, Y0) + * -- +--------------------------------+ + * |________|_________|_________| + * T1 T2 T3 + * + * P2 Circular pattern with middle at NOZZLE_CLEAN_CIRCLE_MIDDLE. + * "R" specifies the radius. "S" specifies the stroke count. + * Before starting, the nozzle moves to NOZZLE_CLEAN_START_POINT. + * + * Caveats: The ending Z should be the same as starting Z. + * Attention: EXPERIMENTAL. G-code arguments may change. + * + */ +//#define NOZZLE_CLEAN_FEATURE + +#if ENABLED(NOZZLE_CLEAN_FEATURE) + // Default number of pattern repetitions + #define NOZZLE_CLEAN_STROKES 12 + + // Default number of triangles + #define NOZZLE_CLEAN_TRIANGLES 3 + + // Specify positions as { X, Y, Z } + #define NOZZLE_CLEAN_START_POINT { 30, 30, (Z_MIN_POS + 1)} + #define NOZZLE_CLEAN_END_POINT {100, 60, (Z_MIN_POS + 1)} + + // Circular pattern radius + #define NOZZLE_CLEAN_CIRCLE_RADIUS 6.5 + // Circular pattern circle fragments number + #define NOZZLE_CLEAN_CIRCLE_FN 10 + // Middle point of circle + #define NOZZLE_CLEAN_CIRCLE_MIDDLE NOZZLE_CLEAN_START_POINT + + // Moves the nozzle to the initial position + #define NOZZLE_CLEAN_GOBACK +#endif + +/** + * Print Job Timer + * + * Automatically start and stop the print job timer on M104/M109/M190. + * + * M104 (hotend, no wait) - high temp = none, low temp = stop timer + * M109 (hotend, wait) - high temp = start timer, low temp = stop timer + * M190 (bed, wait) - high temp = start timer, low temp = none + * + * The timer can also be controlled with the following commands: + * + * M75 - Start the print job timer + * M76 - Pause the print job timer + * M77 - Stop the print job timer + */ +#define PRINTJOB_TIMER_AUTOSTART + +/** + * Print Counter + * + * Track statistical data such as: + * + * - Total print jobs + * - Total successful print jobs + * - Total failed print jobs + * - Total time printing + * + * View the current statistics with M78. + */ +//#define PRINTCOUNTER + +//============================================================================= +//============================= LCD and SD support ============================ +//============================================================================= + +// @section lcd + +/** + * LCD LANGUAGE + * + * Select the language to display on the LCD. These languages are available: + * + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, + * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * tr, uk, zh_CN, zh_TW, test + * + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + */ +#define LCD_LANGUAGE en + +/** + * LCD Character Set + * + * Note: This option is NOT applicable to Graphical Displays. + * + * All character-based LCDs provide ASCII plus one of these + * language extensions: + * + * - JAPANESE ... the most common + * - WESTERN ... with more accented characters + * - CYRILLIC ... for the Russian language + * + * To determine the language extension installed on your controller: + * + * - Compile and upload with LCD_LANGUAGE set to 'test' + * - 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 + * + * :['JAPANESE', 'WESTERN', 'CYRILLIC'] + */ +#define DISPLAY_CHARSET_HD44780 JAPANESE + +/** + * LCD TYPE + * + * Enable ULTRA_LCD for a 16x2, 16x4, 20x2, or 20x4 character-based LCD. + * Enable DOGLCD for a 128x64 (ST7565R) Full Graphical Display. + * (These options will be enabled automatically for most displays.) + * + * IMPORTANT: The U8glib library is required for Full Graphic Display! + * https://github.com/olikraus/U8glib_Arduino + */ +//#define ULTRA_LCD // Character based +//#define DOGLCD // Full graphics display + +/** + * SD CARD + * + * 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 + +/** + * SD CARD: SPI SPEED + * + * Enable one of the following items for a slower SPI transfer speed. + * This may be required to resolve "volume init" errors. + */ +//#define SPI_SPEED SPI_HALF_SPEED +//#define SPI_SPEED SPI_QUARTER_SPEED +//#define SPI_SPEED SPI_EIGHTH_SPEED + +/** + * SD CARD: ENABLE CRC + * + * Use CRC checks and retries on the SD communication. + */ +#define SD_CHECK_AND_RETRY + +// +// ENCODER SETTINGS +// +// This option overrides the default number of encoder pulses needed to +// produce one step. Should be increased for high-resolution encoders. +// +//#define ENCODER_PULSES_PER_STEP 1 + +// +// Use this option to override the number of step signals required to +// move between next/prev menu items. +// +//#define ENCODER_STEPS_PER_MENU_ITEM 5 + +/** + * Encoder Direction Options + * + * Test your encoder's behavior first with both options disabled. + * + * Reversed Value Edit and Menu Nav? Enable REVERSE_ENCODER_DIRECTION. + * Reversed Menu Navigation only? Enable REVERSE_MENU_DIRECTION. + * Reversed Value Editing only? Enable BOTH options. + */ + +// +// This option reverses the encoder direction everywhere. +// +// Set this option if CLOCKWISE causes values to DECREASE +// +//#define REVERSE_ENCODER_DIRECTION + +// +// This option reverses the encoder direction for navigating LCD menus. +// +// If CLOCKWISE normally moves DOWN this makes it go UP. +// If CLOCKWISE normally moves UP this makes it go DOWN. +// +#define REVERSE_MENU_DIRECTION + +// +// Individual Axis Homing +// +// Add individual axis homing items (Home X, Home Y, and Home Z) to the LCD menu. +// +//#define INDIVIDUAL_AXIS_HOMING_MENU + +// +// SPEAKER/BUZZER +// +// If you have a speaker that can produce tones, enable it here. +// By default Marlin assumes you have a buzzer with a fixed frequency. +// +//#define SPEAKER + +// +// The duration and frequency for the UI feedback sound. +// Set these to 0 to disable audio feedback in the LCD menus. +// +// Note: Test audio output with the G-Code: +// M300 S P +// +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 +//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 + +// +// CONTROLLER TYPE: Standard +// +// Marlin supports a wide variety of controllers. +// Enable one of the following options to specify your controller. +// + +// +// ULTIMAKER Controller. +// +//#define ULTIMAKERCONTROLLER + +// +// ULTIPANEL as seen on Thingiverse. +// +//#define ULTIPANEL + +// +// PanelOne from T3P3 (via RAMPS 1.4 AUX2/AUX3) +// http://reprap.org/wiki/PanelOne +// +//#define PANEL_ONE + +// +// MaKr3d Makr-Panel with graphic controller and SD support. +// http://reprap.org/wiki/MaKr3d_MaKrPanel +// +//#define MAKRPANEL + +// +// ReprapWorld Graphical LCD +// https://reprapworld.com/?products_details&products_id/1218 +// +//#define REPRAPWORLD_GRAPHICAL_LCD + +// +// Activate one of these if you have a Panucatt Devices +// Viki 2.0 or mini Viki with Graphic LCD +// http://panucatt.com +// +//#define VIKI2 +//#define miniVIKI + +// +// Adafruit ST7565 Full Graphic Controller. +// https://github.com/eboston/Adafruit-ST7565-Full-Graphic-Controller/ +// +//#define ELB_FULL_GRAPHIC_CONTROLLER + +// +// RepRapDiscount Smart Controller. +// http://reprap.org/wiki/RepRapDiscount_Smart_Controller +// +// Note: Usually sold with a white PCB. +// +#define REPRAP_DISCOUNT_SMART_CONTROLLER + +// +// GADGETS3D G3D LCD/SD Controller +// http://reprap.org/wiki/RAMPS_1.3/1.4_GADGETS3D_Shield_with_Panel +// +// Note: Usually sold with a blue PCB. +// +//#define G3D_PANEL + +// +// RepRapDiscount FULL GRAPHIC Smart Controller +// http://reprap.org/wiki/RepRapDiscount_Full_Graphic_Smart_Controller +// +//#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER + +// +// MakerLab Mini Panel with graphic +// controller and SD support - http://reprap.org/wiki/Mini_panel +// +//#define MINIPANEL + +// +// RepRapWorld REPRAPWORLD_KEYPAD v1.1 +// http://reprapworld.com/?products_details&products_id=202&cPath=1591_1626 +// +// REPRAPWORLD_KEYPAD_MOVE_STEP sets how much should the robot move when a key +// is pressed, a value of 10.0 means 10mm per click. +// +//#define REPRAPWORLD_KEYPAD +//#define REPRAPWORLD_KEYPAD_MOVE_STEP 1.0 + +// +// RigidBot Panel V1.0 +// http://www.inventapart.com/ +// +//#define RIGIDBOT_PANEL + +// +// BQ LCD Smart Controller shipped by +// default with the BQ Hephestos 2 and Witbox 2. +// +//#define BQ_LCD_SMART_CONTROLLER + +// +// Cartesio UI +// http://mauk.cc/webshop/cartesio-shop/electronics/user-interface +// +//#define CARTESIO_UI + +// +// ANET_10 Controller supported displays. +// +//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. + // This LCD is known to be susceptible to electrical interference + // which scrambles the display. Pressing any button clears it up. +//#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 + // A clone of the RepRapDiscount full graphics display but with + // different pins/wiring (see pins_ANET_10.h). + +// +// LCD for Melzi Card with Graphical LCD +// +//#define LCD_FOR_MELZI + +// +// CONTROLLER TYPE: I2C +// +// Note: These controllers require the installation of Arduino's LiquidCrystal_I2C +// library. For more info: https://github.com/kiyoshigawa/LiquidCrystal_I2C +// + +// +// Elefu RA Board Control Panel +// http://www.elefu.com/index.php?route=product/product&product_id=53 +// +//#define RA_CONTROL_PANEL + +// +// Sainsmart YW Robot (LCM1602) LCD Display +// +// Note: This controller requires F.Malpartida's LiquidCrystal_I2C library +// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home +// +//#define LCD_I2C_SAINSMART_YWROBOT + +// +// Generic LCM1602 LCD adapter +// +//#define LCM1602 + +// +// PANELOLU2 LCD with status LEDs, +// separate encoder and click inputs. +// +// Note: This controller requires Arduino's LiquidTWI2 library v1.2.3 or later. +// For more info: https://github.com/lincomatic/LiquidTWI2 +// +// Note: The PANELOLU2 encoder click input can either be directly connected to +// a pin (if BTN_ENC defined to != -1) or read through I2C (when BTN_ENC == -1). +// +//#define LCD_I2C_PANELOLU2 + +// +// Panucatt VIKI LCD with status LEDs, +// integrated click & L/R/U/D buttons, separate encoder inputs. +// +//#define LCD_I2C_VIKI + +// +// SSD1306 OLED full graphics generic display +// +//#define U8GLIB_SSD1306 + +// +// SAV OLEd LCD module support using either SSD1306 or SH1106 based LCD modules +// +//#define SAV_3DGLCD +#if ENABLED(SAV_3DGLCD) + //#define U8GLIB_SSD1306 + #define U8GLIB_SH1106 +#endif + +// +// CONTROLLER TYPE: Shift register panels +// +// 2 wire Non-latching LCD SR from https://goo.gl/aJJ4sH +// LCD configuration: http://reprap.org/wiki/SAV_3D_LCD +// +//#define SAV_3DLCD + +// +// TinyBoy2 128x64 OLED / Encoder Panel +// +//#define OLED_PANEL_TINYBOY2 + +// +// Makeboard 3D Printer Parts 3D Printer Mini Display 1602 Mini Controller +// https://www.aliexpress.com/item/Micromake-Makeboard-3D-Printer-Parts-3D-Printer-Mini-Display-1602-Mini-Controller-Compatible-with-Ramps-1/32765887917.html +// +//#define MAKEBOARD_MINI_2_LINE_DISPLAY_1602 + +// +// MKS MINI12864 with graphic controller and SD support +// http://reprap.org/wiki/MKS_MINI_12864 +// +//#define MKS_MINI_12864 + +// +// Factory display for Creality CR-10 +// https://www.aliexpress.com/item/Universal-LCD-12864-3D-Printer-Display-Screen-With-Encoder-For-CR-10-CR-7-Model/32833148327.html +// +// This is RAMPS-compatible using a single 10-pin connector. +// (For CR-10 owners who want to replace the Melzi Creality board but retain the display) +// +//#define CR10_STOCKDISPLAY + +// +// MKS OLED 1.3" 128 × 64 FULL GRAPHICS CONTROLLER +// http://reprap.org/wiki/MKS_12864OLED +// +// Tiny, but very sharp OLED display +// +//#define MKS_12864OLED + +//============================================================================= +//=============================== Extra Features ============================== +//============================================================================= + +// @section extras + +// Increase the FAN PWM frequency. Removes the PWM noise but increases heating in the FET/Arduino +//#define FAST_PWM_FAN + +// Use software PWM to drive the fan, as for the heaters. This uses a very low frequency +// which is not as annoying as with the hardware PWM. On the other hand, if this frequency +// is too low, you should also increment SOFT_PWM_SCALE. +//#define FAN_SOFT_PWM + +// Incrementing this by 1 will double the software PWM frequency, +// affecting heaters, and the fan if FAN_SOFT_PWM is enabled. +// However, control resolution will be halved for each increment; +// at zero value, there are 128 effective control positions. +#define SOFT_PWM_SCALE 0 + +// If SOFT_PWM_SCALE is set to a value higher than 0, dithering can +// be used to mitigate the associated resolution loss. If enabled, +// some of the PWM cycles are stretched so on average the desired +// duty cycle is attained. +//#define SOFT_PWM_DITHER + +// Temperature status LEDs that display the hotend and bed temperature. +// If all hotends, bed temperature, and target temperature are under 54C +// then the BLUE led is on. Otherwise the RED led is on. (1C hysteresis) +//#define TEMP_STAT_LEDS + +// M240 Triggers a camera by emulating a Canon RC-1 Remote +// Data from: http://www.doc-diy.net/photo/rc-1_hacked/ +//#define PHOTOGRAPH_PIN 23 + +// 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 + +// Support for BlinkM/CyzRgb +//#define BLINKM + +// Support for PCA9632 PWM LED driver +//#define PCA9632 + +/** + * RGB LED / LED Strip Control + * + * Enable support for an RGB LED connected to 5V digital pins, or + * an RGB Strip connected to MOSFETs controlled by digital pins. + * + * 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 overall brightness parameters is also available + * + * *** CAUTION *** + * LED Strips require a MOFSET 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! + * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino + * cannot handle such current, separate 5V power supply must be used + * *** CAUTION *** + * + * LED type. This options are mutualy exclusive. Uncomment only one. + * + */ +//#define RGB_LED +//#define RGBW_LED + +#if ENABLED(RGB_LED) || ENABLED(RGBW_LED) + #define RGB_LED_R_PIN 34 + #define RGB_LED_G_PIN 43 + #define RGB_LED_B_PIN 35 + #define RGB_LED_W_PIN -1 +#endif + +// 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 (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) + #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip + #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time + #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + //#define NEOPIXEL_STARTUP_TEST // Cycle through colors at startup +#endif + +/** + * Printer Event LEDs + * + * During printing, the LEDs will reflect the printer status: + * + * - Gradually change from blue to violet as the heated bed gets to target temp + * - Gradually change from violet to red as the hotend gets to temperature + * - Change to white to illuminate work surface + * - Change to green once print has finished + * - Turn off after the print has finished and the user has pushed a button + */ +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) + #define PRINTER_EVENT_LEDS +#endif + +/*********************************************************************\ +* R/C SERVO support +* Sponsored by TrinityLabs, Reworked by codexmas +**********************************************************************/ + +// Number of servos +// +// If you select a configuration below, this will receive a default value and does not need to be set manually +// set it manually if you have more servos than extruders and wish to manually control some +// leaving it undefined or defining as 0 will disable the servo subsystem +// If unsure, leave commented / disabled +// +#define NUM_SERVOS 2 // Servo index starts with 0 for M280 command + +// Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. +// 300ms is a good value but you can try less delay. +// If the servo can't reach the requested position, increase it. +#define SERVO_DELAY { 500, 500 } + +// Servo deactivation +// +// With this option servos are powered only during movement, then turned off to prevent jitter. +#define DEACTIVATE_SERVOS_AFTER_MOVE + +/** + * Filament Width Sensor + * + * Measures the filament width in real-time and adjusts + * flow rate to compensate for any irregularities. + * + * Also allows the measured filament diameter to set the + * extrusion rate, so the slicer only has to specify the + * volume. + * + * Only a single extruder is supported at this time. + * + * 34 RAMPS_14 : Analog input 5 on the AUX2 connector + * 81 PRINTRBOARD : Analog input 2 on the Exp1 connector (version B,C,D,E) + * 301 RAMBO : Analog input 3 + * + * Note: May require analog pins to be defined for other boards. + */ +//#define FILAMENT_WIDTH_SENSOR + +#define DEFAULT_NOMINAL_FILAMENT_DIA 1.75 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. + +#if ENABLED(FILAMENT_WIDTH_SENSOR) + #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) + #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber + + #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading + #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading + #define MAX_MEASUREMENT_DELAY 20 // (bytes) Buffer size for stored measurements (1 byte per cm). Must be larger than MEASUREMENT_DELAY_CM. + + #define DEFAULT_MEASURED_FILAMENT_DIA DEFAULT_NOMINAL_FILAMENT_DIA // Set measured to nominal initially + + // Display filament width on the LCD status line. Status messages will expire after 5 seconds. + //#define FILAMENT_LCD_DISPLAY +#endif + +#endif // CONFIGURATION_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/Folger Tech/i3-2020/Configuration_adv.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/Folger Tech/i3-2020/Configuration_adv.h new file mode 100644 index 00000000..ae7d5708 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/Folger Tech/i3-2020/Configuration_adv.h @@ -0,0 +1,1424 @@ +/** + * 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 . + * + */ + +/** + * Configuration_adv.h + * + * Advanced settings. + * Only change these if you know exactly what you're doing. + * Some of these settings can damage your printer if improperly set! + * + * Basic settings can be found in Configuration.h + * + */ +#ifndef CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H_VERSION 010100 + +// @section temperature + +//=========================================================================== +//=============================Thermal Settings ============================ +//=========================================================================== + +#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 + #endif +#endif + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * The solution: Once the temperature reaches the target, start observing. + * If the temperature stays too far below the target (hysteresis) for too long (period), + * the firmware will halt the machine as a safety precaution. + * + * If you get false positives for "Thermal Runaway" increase THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD + */ +#if ENABLED(THERMAL_PROTECTION_HOTENDS) + #define THERMAL_PROTECTION_PERIOD 40 // Seconds + #define THERMAL_PROTECTION_HYSTERESIS 2 // Degrees Celsius + + /** + * Whenever an M104 or M109 increases the target temperature the firmware will wait for the + * WATCH_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get false positives for "Heating failed" increase WATCH_TEMP_PERIOD and/or decrease WATCH_TEMP_INCREASE + * WATCH_TEMP_INCREASE should not be below 2. + */ + #define WATCH_TEMP_PERIOD 40 // Seconds + #define WATCH_TEMP_INCREASE 2 // Degrees Celsius +#endif + +/** + * Thermal Protection parameters for the bed are just as above for hotends. + */ +#if ENABLED(THERMAL_PROTECTION_BED) + #define THERMAL_PROTECTION_BED_PERIOD 40 // Seconds + #define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius + + /** + * Whenever an M140 or M190 increases the target temperature the firmware will wait for the + * WATCH_BED_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_BED_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get too many "Heating failed" errors, increase WATCH_BED_TEMP_PERIOD and/or decrease + * WATCH_BED_TEMP_INCREASE. (WATCH_BED_TEMP_INCREASE should not be below 2.) + */ + #define WATCH_BED_TEMP_PERIOD 60 // Seconds + #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius +#endif + +#if ENABLED(PIDTEMP) + // this adds an experimental additional term to the heating power, proportional to the extrusion speed. + // if Kc is chosen well, the additional required power due to increased melting should be compensated. + //#define PID_EXTRUSION_SCALING + #if ENABLED(PID_EXTRUSION_SCALING) + #define DEFAULT_Kc (100) //heating power=Kc*(e_speed) + #define LPQ_MAX_LEN 50 + #endif +#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 + */ +#define AUTOTEMP +#if ENABLED(AUTOTEMP) + #define AUTOTEMP_OLDWEIGHT 0.98 +#endif + +// Show Temperature ADC value +// Enable for M105 to include ADC values read from temperature sensors. +//#define SHOW_TEMP_ADC_VALUES + +/** + * High Temperature Thermistor Support + * + * Thermistors able to support high temperature tend to have a hard time getting + * good readings at room and lower temperatures. This means HEATER_X_RAW_LO_TEMP + * will probably be caught when the heating element first turns on during the + * preheating process, which will trigger a min_temp_error as a safety measure + * and force stop everything. + * To circumvent this limitation, we allow for a preheat time (during which, + * min_temp_error won't be triggered) and add a min_temp buffer to handle + * aberrant readings. + * + * If you want to enable this feature for your hotend thermistor(s) + * uncomment and set values > 0 in the constants below + */ + +// The number of consecutive low temperature errors that can occur +// before a min_temp_error is triggered. (Shouldn't be more than 10.) +//#define MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED 0 + +// The number of milliseconds a hotend will preheat before starting to check +// the temperature. This value should NOT be set to the time it takes the +// hot end to reach the target temperature, but the time it takes to reach +// the minimum temperature your thermistor can read. The lower the better/safer. +// This shouldn't need to be more than 30 seconds (30000) +//#define MILLISECONDS_PREHEAT_TIME 0 + +// @section extruder + +// Extruder runout prevention. +// If the machine is idle and the temperature over MINTEMP +// then extrude some filament every couple of SECONDS. +//#define EXTRUDER_RUNOUT_PREVENT +#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_EXTRUDE 5 // mm +#endif + +// @section temperature + +//These defines help to calibrate the AD595 sensor in case you get wrong temperature measurements. +//The measured temperature is defined as "actualTemp = (measuredTemp * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET" +#define TEMP_SENSOR_AD595_OFFSET 0.0 +#define TEMP_SENSOR_AD595_GAIN 1.0 + +/** + * 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. + */ +//#define USE_CONTROLLER_FAN +#if ENABLED(USE_CONTROLLER_FAN) + //#define CONTROLLER_FAN_PIN FAN1_PIN // 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 +#endif + +// When first starting the main fan, run it at full speed for the +// given number of milliseconds. This gets the fan spinning reliably +// before setting a PWM value. (Does not work with software PWM for fan on Sanguinololu) +//#define FAN_KICKSTART_TIME 100 + +// This defines the minimal speed for the main fan, run in PWM mode +// to enable uncomment and set minimal PWM speed for reliable running (1-255) +// if fan speed is [1 - (FAN_MIN_PWM-1)] it is set to FAN_MIN_PWM +//#define FAN_MIN_PWM 50 + +// @section extruder + +/** + * Extruder cooling fans + * + * Extruder auto fans automatically turn on when their extruders' + * temperatures go above EXTRUDER_AUTO_FAN_TEMPERATURE. + * + * Your board's pins file specifies the recommended pins. Override those here + * or set to -1 to disable completely. + * + * Multiple extruders can be assigned to the same pin in which case + * the fan will turn on when any selected extruder is above the threshold. + */ +#define E0_AUTO_FAN_PIN -1 +#define E1_AUTO_FAN_PIN -1 +#define E2_AUTO_FAN_PIN -1 +#define E3_AUTO_FAN_PIN -1 +#define E4_AUTO_FAN_PIN -1 +#define EXTRUDER_AUTO_FAN_TEMPERATURE 50 +#define EXTRUDER_AUTO_FAN_SPEED 255 // == full speed + +/** + * Part-Cooling Fan Multiplexer + * + * This feature allows you to digitally multiplex the fan output. + * The multiplexer is automatically switched at tool-change. + * Set FANMUX[012]_PINs below for up to 2, 4, or 8 multiplexed fans. + */ +#define FANMUX0_PIN -1 +#define FANMUX1_PIN -1 +#define FANMUX2_PIN -1 + +/** + * M355 Case Light on-off / brightness + */ +//#define CASE_LIGHT_ENABLE +#if ENABLED(CASE_LIGHT_ENABLE) + //#define CASE_LIGHT_PIN 4 // Override the default pin if needed + #define INVERT_CASE_LIGHT false // Set true if Case Light is ON when pin is LOW + #define CASE_LIGHT_DEFAULT_ON true // Set default power-up state on + #define CASE_LIGHT_DEFAULT_BRIGHTNESS 105 // Set default power-up brightness (0-255, requires PWM pin) + //#define MENU_ITEM_CASE_LIGHT // Add a Case Light option to the LCD main menu +#endif + +//=========================================================================== +//============================ Mechanical Settings ========================== +//=========================================================================== + +// @section homing + +// If you want endstops to stay on (by default) even when not homing +// enable this option. Override at any time with M120, M121. +//#define ENDSTOPS_ALWAYS_ON_DEFAULT + +// @section extras + +//#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. + +// Dual X Steppers +// Uncomment this option to drive two X axis motors. +// The next unused E driver will be assigned to the second X stepper. +//#define X_DUAL_STEPPER_DRIVERS +#if ENABLED(X_DUAL_STEPPER_DRIVERS) + // Set true if the two X motors need to rotate in opposite directions + #define INVERT_X2_VS_X_DIR true +#endif + +// Dual Y Steppers +// Uncomment this option to drive two Y axis motors. +// The next unused E driver will be assigned to the second Y stepper. +//#define Y_DUAL_STEPPER_DRIVERS +#if ENABLED(Y_DUAL_STEPPER_DRIVERS) + // Set true if the two Y motors need to rotate in opposite directions + #define INVERT_Y2_VS_Y_DIR true +#endif + +// A single Z stepper driver is usually used to drive 2 stepper motors. +// Uncomment this option to use a separate stepper driver for each Z axis motor. +// The next unused E driver will be assigned to the second Z stepper. +//#define Z_DUAL_STEPPER_DRIVERS + +#if ENABLED(Z_DUAL_STEPPER_DRIVERS) + + // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper. + // That way the machine is capable to align the bed during home, since both Z steppers are homed. + // There is also an implementation of M666 (software endstops adjustment) to this feature. + // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed. + // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2. + // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive. + // Play a little bit with small adjustments (0.5mm) and check the behaviour. + // The M119 (endstops report) will start reporting the Z2 Endstop as well. + + //#define Z_DUAL_ENDSTOPS + + #if ENABLED(Z_DUAL_ENDSTOPS) + #define Z2_USE_ENDSTOP _XMAX_ + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 // Use M666 to determine/test this value + #endif + +#endif // Z_DUAL_STEPPER_DRIVERS + +// Enable this for dual x-carriage printers. +// A dual x-carriage design has the advantage that the inactive extruder can be parked which +// prevents hot-end ooze contaminating the print. It also reduces the weight of each x-carriage +// allowing faster printing speeds. Connect your X2 stepper to the first unused E plug. +//#define DUAL_X_CARRIAGE +#if ENABLED(DUAL_X_CARRIAGE) + // Configuration for second X-carriage + // Note: the first x-carriage is defined as the x-carriage which homes to the minimum endstop; + // the second x-carriage always homes to the maximum endstop. + #define X2_MIN_POS 80 // set minimum to ensure second x-carriage doesn't hit the parked first X-carriage + #define X2_MAX_POS 353 // set maximum to the distance between toolheads when both heads are homed + #define X2_HOME_DIR 1 // the second X-carriage always homes to the maximum endstop position + #define X2_HOME_POS X2_MAX_POS // default home position is the maximum carriage position + // However: In this mode the HOTEND_OFFSET_X value for the second extruder provides a software + // override for X2_HOME_POS. This also allow recalibration of the distance between the two endstops + // without modifying the firmware (through the "M218 T1 X???" command). + // Remember: you should set the second extruder x-offset to 0 in your slicer. + + // There are a few selectable movement modes for dual x-carriages using M605 S + // Mode 0 (DXC_FULL_CONTROL_MODE): Full control. The slicer has full control over both x-carriages and can achieve optimal travel results + // as long as it supports dual x-carriages. (M605 S0) + // Mode 1 (DXC_AUTO_PARK_MODE) : Auto-park mode. The firmware will automatically park and unpark the x-carriages on tool changes so + // that additional slicer support is not required. (M605 S1) + // Mode 2 (DXC_DUPLICATION_MODE) : Duplication mode. The firmware will transparently make the second x-carriage and extruder copy all + // actions of the first x-carriage. This allows the printer to print 2 arbitrary items at + // once. (2nd extruder x offset and temp offset are set using: M605 S2 [Xnnn] [Rmmm]) + + // This is the default power-up mode which can be later using M605. + #define DEFAULT_DUAL_X_CARRIAGE_MODE DXC_FULL_CONTROL_MODE + + // Default settings in "Auto-park Mode" + #define TOOLCHANGE_PARK_ZLIFT 0.2 // the distance to raise Z axis when parking an extruder + #define TOOLCHANGE_UNPARK_ZLIFT 1 // the distance to raise Z axis when unparking an extruder + + // Default x offset in duplication mode (typically set to half print bed width) + #define DEFAULT_DUPLICATION_X_OFFSET 100 + +#endif // DUAL_X_CARRIAGE + +// 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. +//#define EXT_SOLENOID + +// @section homing + +//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +#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 this is defined, if both x and y are to be homed, a diagonal move will be performed initially. + +// When G28 is called, this option will make Y home before X +//#define HOME_Y_BEFORE_X + +// @section machine + +#define AXIS_RELATIVE_MODES {false, false, false, false} + +// Allow duplication mode with a basic dual-nozzle extruder +//#define DUAL_NOZZLE_DUPLICATION_MODE + +// By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step. +#define INVERT_X_STEP_PIN false +#define INVERT_Y_STEP_PIN false +#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. +#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_E true + +#define DEFAULT_MINIMUMFEEDRATE 0.0 // minimum feedrate +#define DEFAULT_MINTRAVELFEEDRATE 0.0 + +//#define HOME_AFTER_DEACTIVATE // Require rehoming after steppers are deactivated + +// @section lcd + +#if ENABLED(ULTIPANEL) + #define MANUAL_FEEDRATE {50*60, 50*60, 4*60, 60} // Feedrates for manual moves along X, Y, Z, E from panel + #define ULTIPANEL_FEEDMULTIPLY // Comment to disable setting feedrate multiplier via encoder +#endif + +// @section extras + +// minimum time in microseconds that a movement needs to take if the buffer is emptied. +#define DEFAULT_MINSEGMENTTIME 20000 + +// If defined the movements slow down when the look ahead buffer is only half full +#define SLOWDOWN + +// Frequency limit +// See nophead's blog for more info +// Not working O +//#define XY_FREQUENCY_LIMIT 15 + +// 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 +// if unwanted behavior is observed on a user's machine when running at very slow speeds. +#define MINIMUM_PLANNER_SPEED 0.05 // (mm/sec) + +// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU. +#define MICROSTEP_MODES {16,16,16,16,16} // [1,2,4,8,16] + +/** + * @section stepper motor current + * + * Some boards have a means of setting the stepper motor current via firmware. + * + * The power on motor currents are set by: + * PWM_MOTOR_CURRENT - used by MINIRAMBO & ULTIMAIN_2 + * known compatible chips: A4982 + * DIGIPOT_MOTOR_CURRENT - used by BQ_ZUM_MEGA_3D, RAMBO & SCOOVO_X9H + * known compatible chips: AD5206 + * DAC_MOTOR_CURRENT_DEFAULT - used by PRINTRBOARD_REVF & RIGIDBOARD_V2 + * known compatible chips: MCP4728 + * DIGIPOT_I2C_MOTOR_CURRENTS - used by 5DPRINT, AZTEEG_X3_PRO, MIGHTYBOARD_REVE + * known compatible chips: MCP4451, MCP4018 + * + * Motor currents can also be set by M907 - M910 and by the LCD. + * M907 - applies to all. + * M908 - BQ_ZUM_MEGA_3D, RAMBO, PRINTRBOARD_REVF, RIGIDBOARD_V2 & SCOOVO_X9H + * M909, M910 & LCD - only PRINTRBOARD_REVF & RIGIDBOARD_V2 + */ +//#define PWM_MOTOR_CURRENT { 1300, 1300, 1250 } // Values in milliamps +//#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 + +// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +//#define DIGIPOT_I2C +//#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster +#define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 +// Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS +#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=========================== +//=========================================================================== + +#define ENCODER_RATE_MULTIPLIER // If defined, certain menu edit operations automatically multiply the steps when the encoder is moved quickly +#define ENCODER_10X_STEPS_PER_SEC 75 // If the encoder steps per sec exceeds this value, multiply steps moved x10 to quickly advance the value +#define ENCODER_100X_STEPS_PER_SEC 160 // If the encoder steps per sec exceeds this value, multiply steps moved x100 to really quickly advance the value + +//#define CHDK 4 //Pin for triggering CHDK to take a picture see how to use it here http://captain-slow.dk/2014/03/09/3d-printing-timelapses/ +#define CHDK_DELAY 50 //How long in ms the pin should stay HIGH before going LOW again + +// @section lcd + +// Include a page of printer information in the LCD Main Menu +//#define LCD_INFO_MENU + +// Scroll a longer status message into view +//#define STATUS_MESSAGE_SCROLLING + +// On the Info Screen, display XY with one decimal place when possible +//#define LCD_DECIMAL_SMALL_XY + +// The timeout (in ms) to return to the status screen from sub-menus +//#define LCD_TIMEOUT_TO_STATUS 15000 + +#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 + + #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? + #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. + + #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. + // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. + // using: + //#define MENU_ADDAUTOSTART + + /** + * Sort SD file listings in alphabetical order. + * + * With this option enabled, items on SD cards will be sorted + * by name for easier navigation. + * + * By default... + * + * - Use the slowest -but safest- method for sorting. + * - Folders are sorted to the top. + * - The sort key is statically allocated. + * - No added G-code (M34) support. + * - 40 item sorting limit. (Items after the first 40 are unsorted.) + * + * SD sorting uses static allocation (as set by SDSORT_LIMIT), allowing the + * compiler to calculate the worst-case usage and throw an error if the SRAM + * limit is exceeded. + * + * - SDSORT_USES_RAM provides faster sorting via a static directory buffer. + * - SDSORT_USES_STACK does the same, but uses a local stack-based buffer. + * - SDSORT_CACHE_NAMES will retain the sorted file listing in RAM. (Expensive!) + * - SDSORT_DYNAMIC_RAM only uses RAM when the SD menu is visible. (Use with caution!) + */ + //#define SDCARD_SORT_ALPHA + + // SD Card Sorting options + #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_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. + #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #endif + + // Show a progress bar on HD44780 LCDs for SD printing + #define LCD_PROGRESS_BAR + + #if ENABLED(LCD_PROGRESS_BAR) + // Amount of time (ms) to show the bar + #define PROGRESS_BAR_BAR_TIME 2000 + // Amount of time (ms) to show the status message + #define PROGRESS_BAR_MSG_TIME 3000 + // Amount of time (ms) to retain the status message (0=forever) + #define PROGRESS_MSG_EXPIRE 0 + // Enable this to show messages for MSG_TIME then hide them + //#define PROGRESS_MSG_ONCE + // Add a menu item to test the progress bar: + //#define LCD_PROGRESS_BAR_TEST + #endif + + // This allows hosts to request long names for files and folders with M33 + //#define LONG_FILENAME_HOST_SUPPORT + + // This option allows you to abort SD printing when any endstop is triggered. + // This feature must be enabled with "M540 S1" or from the LCD menu. + // To have any effect, endstops must be enabled during SD printing. + //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + +#endif // SDSUPPORT + +/** + * Additional options for Graphical Displays + * + * Use the optimizations here to improve printing performance, + * which can be adversely affected by graphical display drawing, + * especially when doing several short moves, and when printing + * on DELTA and SCARA machines. + * + * Some of these options may result in the display lagging behind + * controller events, as there is a trade-off between reliable + * printing performance versus fast display updates. + */ +#if ENABLED(DOGLCD) + // Enable to save many cycles by drawing a hollow frame on the Info Screen + #define XYZ_HOLLOW_FRAME + + // Enable to save many cycles by drawing a hollow frame on Menu Screens + #define MENU_HOLLOW_FRAME + + // A bigger font is available for edit items. Costs 3120 bytes of PROGMEM. + // 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. + // 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 +#endif // DOGLCD + +// @section safety + +// The hardware watchdog should reset the microcontroller disabling all outputs, +// in case the firmware gets stuck and doesn't do temperature regulation. +#define USE_WATCHDOG + +#if ENABLED(USE_WATCHDOG) + // If you have a watchdog reboot in an ArduinoMega2560 then the device will hang forever, as a watchdog reset will leave the watchdog on. + // The "WATCHDOG_RESET_MANUAL" goes around this by not using the hardware reset. + // However, THIS FEATURE IS UNSAFE!, as it will only work if interrupts are disabled. And the code could hang in an interrupt routine with interrupts disabled. + //#define WATCHDOG_RESET_MANUAL +#endif + +// @section lcd + +/** + * Babystepping enables movement of the axes by tiny increments without changing + * the current position values. This feature is used primarily to adjust the Z + * axis in the first layer of a print in real-time. + * + * Warning: Does not respect endstops! + */ +#define BABYSTEPPING +#if ENABLED(BABYSTEPPING) + //#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 2 // Babysteps are very small. Increase for faster motion. + //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping + #define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen 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_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor + //#define BABYSTEP_ZPROBE_GFX_REVERSE // Reverses the direction of the CW/CCW indicators +#endif + +// @section extruder + +/** + * Implementation of linear pressure control + * + * Assumption: advance = k * (delta velocity) + * K=0 means advance disabled. + * See Marlin documentation for calibration instructions. + */ +//#define LIN_ADVANCE + +#if ENABLED(LIN_ADVANCE) + #define LIN_ADVANCE_K 75 + + /** + * Some Slicers produce Gcode with randomly jumping extrusion widths occasionally. + * For example within a 0.4mm perimeter it may produce a single segment of 0.05mm width. + * While this is harmless for normal printing (the fluid nature of the filament will + * close this very, very tiny gap), it throws off the LIN_ADVANCE pressure adaption. + * + * For this case LIN_ADVANCE_E_D_RATIO can be used to set the extrusion:distance ratio + * to a fixed value. Note that using a fixed ratio will lead to wrong nozzle pressures + * if the slicer is using variable widths or layer heights within one print! + * + * This option sets the default E:D ratio at startup. Use `M900` to override this value. + * + * Example: `M900 W0.4 H0.2 D1.75`, where: + * - W is the extrusion width in mm + * - H is the layer height in mm + * - D is the filament diameter in mm + * + * Example: `M900 R0.0458` to set the ratio directly. + * + * Set to 0 to auto-detect the ratio based on given Gcode G1 print moves. + * + * Slic3r (including Průša Control) produces Gcode compatible with the automatic mode. + * Cura (as of this writing) may produce Gcode incompatible with the automatic mode. + */ + #define LIN_ADVANCE_E_D_RATIO 0 // The calculated ratio (or 0) according to the formula W * H / ((D / 2) ^ 2 * PI) + // Example: 0.4 * 0.2 / ((1.75 / 2) ^ 2 * PI) = 0.033260135 +#endif + +// @section leveling + +// Default mesh area is an area with an inset margin on the print area. +// Below are the macros that are used to define the borders for the mesh area, +// made available here for specialized needs, ie dual extruder setup. +#if ENABLED(MESH_BED_LEVELING) + #define MESH_MIN_X MESH_INSET + #define MESH_MAX_X (X_BED_SIZE - (MESH_INSET)) + #define MESH_MIN_Y MESH_INSET + #define MESH_MAX_Y (Y_BED_SIZE - (MESH_INSET)) +#elif ENABLED(AUTO_BED_LEVELING_UBL) + #define UBL_MESH_MIN_X UBL_MESH_INSET + #define UBL_MESH_MAX_X (X_BED_SIZE - (UBL_MESH_INSET)) + #define UBL_MESH_MIN_Y UBL_MESH_INSET + #define UBL_MESH_MAX_Y (Y_BED_SIZE - (UBL_MESH_INSET)) + + // If this is defined, the currently active mesh will be saved in the + // current slot on M500. + #define UBL_SAVE_ACTIVE_ON_M500 +#endif + +// @section extras + +// +// G2/G3 Arc Support +// +#define ARC_SUPPORT // Disable this feature to save ~3226 bytes +#if ENABLED(ARC_SUPPORT) + #define MM_PER_ARC_SEGMENT 1 // Length of each arc segment + #define N_ARC_CORRECTION 25 // Number of intertpolated 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 +#endif + +// Support for G5 with XYZE destination and IJPQ offsets. Requires ~2666 bytes. +//#define BEZIER_CURVE_SUPPORT + +// G38.2 and G38.3 Probe Target +// Enable PROBE_DOUBLE_TOUCH if you want G38 to double touch +//#define G38_PROBE_TARGET +#if ENABLED(G38_PROBE_TARGET) + #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) +#endif + +// Moves (or segments) with fewer steps than this will be joined with the next move +#define MIN_STEPS_PER_SEGMENT 6 + +// The minimum pulse width (in µs) for stepping a stepper. +// Set this if you find stepping unreliable, or if using a very fast CPU. +#define MINIMUM_STEPPER_PULSE 0 // (µs) The smallest stepper pulse allowed + +// @section temperature + +// Control heater 0 and heater 1 in parallel. +//#define HEATERS_PARALLEL + +//=========================================================================== +//================================= Buffers ================================= +//=========================================================================== + +// @section hidden + +// 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, i.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 +#else + #define BLOCK_BUFFER_SIZE 16 // maximize block buffer +#endif + +// @section serial + +// The ASCII buffer for serial input +#define MAX_CMD_SIZE 96 +#define BUFSIZE 4 + +// Transmission to Host Buffer Size +// To save 386 bytes of PROGMEM (and TX_BUFFER_SIZE+3 bytes of RAM) set to 0. +// To buffer a simple "ok" you need 4 bytes. +// For ADVANCED_OK (M105) you need 32 bytes. +// For debug-echo: 128 bytes for the optimal speed. +// Other output doesn't need to be that speedy. +// :[0, 2, 4, 8, 16, 32, 64, 128, 256] +#define TX_BUFFER_SIZE 0 + +// Host Receive Buffer Size +// Without XON/XOFF flow control (see SERIAL_XON_XOFF below) 32 bytes should be enough. +// To use flow control, set this buffer size to at least 1024 bytes. +// :[0, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048] +//#define RX_BUFFER_SIZE 1024 + +#if RX_BUFFER_SIZE >= 1024 + // Enable to have the controller send XON/XOFF control characters to + // the host to signal the RX buffer is becoming full. + //#define SERIAL_XON_XOFF +#endif + +#if ENABLED(SDSUPPORT) + // Enable this option to collect and display the maximum + // RX queue usage after transferring a file to SD. + //#define SERIAL_STATS_MAX_RX_QUEUED + + // Enable this option to collect and display the number + // of dropped bytes after a file transfer to SD. + //#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! +//#define EMERGENCY_PARSER + +// Bad Serial-connections can miss a received command by sending an 'ok' +// Therefore some clients abort after 30 seconds in a timeout. +// Some other clients start sending commands while receiving a 'wait'. +// This "wait" is only sent when the buffer is empty. 1 second is a good value here. +//#define NO_TIMEOUTS 1000 // Milliseconds + +// Some clients will have this feature soon. This could make the NO_TIMEOUTS unnecessary. +//#define ADVANCED_OK + +// @section extras + +/** + * Firmware-based and LCD-controlled retract + * + * Add G10 / G11 commands for automatic firmware-based retract / recover. + * Use M207 and M208 to define parameters for retract / recover. + * + * Use M209 to enable or disable auto-retract. + * With auto-retract enabled, all G1 E moves within the set range + * will be converted to firmware-based retract/recover moves. + * + * Be sure to turn off auto-retract during filament change. + * + * Note that M207 / M208 / M209 settings are saved to EEPROM. + * + */ +//#define FWRETRACT // ONLY PARTIALLY TESTED +#if ENABLED(FWRETRACT) + #define MIN_AUTORETRACT 0.1 // When auto-retract is on, convert E moves of this length and over + #define MAX_AUTORETRACT 10.0 // Upper limit for auto-retract conversion + #define RETRACT_LENGTH 3 // Default retract length (positive mm) + #define RETRACT_LENGTH_SWAP 13 // Default swap retract length (positive mm), for extruder change + #define RETRACT_FEEDRATE 45 // Default feedrate for retracting (mm/s) + #define RETRACT_ZLIFT 0 // Default retract Z-lift + #define RETRACT_RECOVER_LENGTH 0 // Default additional recover length (mm, added to retract length when recovering) + #define RETRACT_RECOVER_LENGTH_SWAP 0 // Default additional swap recover length (mm, added to retract length when recovering from extruder change) + #define RETRACT_RECOVER_FEEDRATE 8 // Default feedrate for recovering from retraction (mm/s) + #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) +#endif + +/** + * Advanced Pause + * Experimental feature for filament change support and for parking the nozzle when paused. + * Adds the GCode M600 for initiating filament change. + * If PARK_HEAD_ON_PAUSE enabled, adds the GCode M125 to pause printing and park the nozzle. + * + * Requires an LCD display. + * This feature is required for the default FILAMENT_RUNOUT_SCRIPT. + */ +#define ADVANCED_PAUSE_FEATURE +#if ENABLED(ADVANCED_PAUSE_FEATURE) + #define PAUSE_PARK_X_POS 10 // X position of hotend + #define PAUSE_PARK_Y_POS 10 // Y position of hotend + #define PAUSE_PARK_Z_ADD 10 // Z addition of hotend (lift) + #define PAUSE_PARK_XY_FEEDRATE 100 // X and Y axes feedrate in mm/s (also used for delta printers Z axis) + #define PAUSE_PARK_Z_FEEDRATE 5 // Z axis feedrate in mm/s (not used for delta printers) + #define PAUSE_PARK_RETRACT_FEEDRATE 60 // Initial retract feedrate in mm/s + #define PAUSE_PARK_RETRACT_LENGTH 2 // Initial retract in mm + // It is a short retract used immediately after print interrupt before move to filament exchange position + #define FILAMENT_CHANGE_UNLOAD_FEEDRATE 10 // Unload filament feedrate in mm/s - filament unloading can be fast + #define FILAMENT_CHANGE_UNLOAD_LENGTH 100 // Unload filament length from hotend in mm + // Longer length for bowden printers to unload filament from whole bowden tube, + // shorter length for printers without bowden to unload filament from extruder only, + // 0 to disable unloading for manual unloading + #define FILAMENT_CHANGE_LOAD_FEEDRATE 6 // Load filament feedrate in mm/s - filament loading into the bowden tube can be fast + #define FILAMENT_CHANGE_LOAD_LENGTH 0 // Load filament length over hotend in mm + // Longer length for bowden printers to fast load filament into whole bowden tube over the hotend, + // Short or zero length for printers without bowden where loading is not used + #define ADVANCED_PAUSE_EXTRUDE_FEEDRATE 3 // Extrude filament feedrate in mm/s - must be slower than load feedrate + #define ADVANCED_PAUSE_EXTRUDE_LENGTH 50 // Extrude filament length in mm after filament is loaded over the hotend, + // 0 to disable for manual extrusion + // Filament can be extruded repeatedly from the filament exchange menu to fill the hotend, + // or until outcoming filament color is not clear for filament color change + #define PAUSE_PARK_NOZZLE_TIMEOUT 45 // Turn off nozzle if user doesn't change filament within this time limit in seconds + #define FILAMENT_CHANGE_NUMBER_OF_ALERT_BEEPS 5 // Number of alert beeps before printer goes quiet + #define PAUSE_PARK_NO_STEPPER_TIMEOUT // Enable to have stepper motors hold position during filament change + // even if it takes longer than DEFAULT_STEPPER_DEACTIVE_TIME. + #define PARK_HEAD_ON_PAUSE // Go to filament change position on pause, return to print position on resume + //#define HOME_BEFORE_FILAMENT_CHANGE // Ensure homing has been completed prior to parking for filament change +#endif + +// @section tmc + +/** + * Enable this section if you have TMC26X motor drivers. + * You will need to import the TMC26XStepper library into the Arduino IDE for this + * (https://github.com/trinamic/TMC26XStepper.git) + */ +//#define HAVE_TMCDRIVER + +#if ENABLED(HAVE_TMCDRIVER) + + //#define X_IS_TMC + //#define X2_IS_TMC + //#define Y_IS_TMC + //#define Y2_IS_TMC + //#define Z_IS_TMC + //#define Z2_IS_TMC + //#define E0_IS_TMC + //#define E1_IS_TMC + //#define E2_IS_TMC + //#define E3_IS_TMC + //#define E4_IS_TMC + + #define X_MAX_CURRENT 1000 // in mA + #define X_SENSE_RESISTOR 91 // in mOhms + #define X_MICROSTEPS 16 // number of microsteps + + #define X2_MAX_CURRENT 1000 + #define X2_SENSE_RESISTOR 91 + #define X2_MICROSTEPS 16 + + #define Y_MAX_CURRENT 1000 + #define Y_SENSE_RESISTOR 91 + #define Y_MICROSTEPS 16 + + #define Y2_MAX_CURRENT 1000 + #define Y2_SENSE_RESISTOR 91 + #define Y2_MICROSTEPS 16 + + #define Z_MAX_CURRENT 1000 + #define Z_SENSE_RESISTOR 91 + #define Z_MICROSTEPS 16 + + #define Z2_MAX_CURRENT 1000 + #define Z2_SENSE_RESISTOR 91 + #define Z2_MICROSTEPS 16 + + #define E0_MAX_CURRENT 1000 + #define E0_SENSE_RESISTOR 91 + #define E0_MICROSTEPS 16 + + #define E1_MAX_CURRENT 1000 + #define E1_SENSE_RESISTOR 91 + #define E1_MICROSTEPS 16 + + #define E2_MAX_CURRENT 1000 + #define E2_SENSE_RESISTOR 91 + #define E2_MICROSTEPS 16 + + #define E3_MAX_CURRENT 1000 + #define E3_SENSE_RESISTOR 91 + #define E3_MICROSTEPS 16 + + #define E4_MAX_CURRENT 1000 + #define E4_SENSE_RESISTOR 91 + #define E4_MICROSTEPS 16 + +#endif + +// @section TMC2130 + +/** + * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. + * + * You'll also need the TMC2130Stepper Arduino library + * (https://github.com/teemuatlut/TMC2130Stepper). + * + * To use TMC2130 stepper drivers in SPI mode connect your SPI2130 pins to + * the hardware SPI interface on your board and define the required CS pins + * in your `pins_MYBOARD.h` file. (e.g., RAMPS 1.4 uses AUX3 pins `X_CS_PIN 53`, `Y_CS_PIN 49`, etc.). + */ +//#define HAVE_TMC2130 + +#if ENABLED(HAVE_TMC2130) + + // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY + //#define X_IS_TMC2130 + //#define X2_IS_TMC2130 + //#define Y_IS_TMC2130 + //#define Y2_IS_TMC2130 + //#define Z_IS_TMC2130 + //#define Z2_IS_TMC2130 + //#define E0_IS_TMC2130 + //#define E1_IS_TMC2130 + //#define E2_IS_TMC2130 + //#define E3_IS_TMC2130 + //#define E4_IS_TMC2130 + + /** + * Stepper driver settings + */ + + #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 + #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current + #define INTERPOLATE 1 // Interpolate X/Y/Z_MICROSTEPS to 256 + + #define X_CURRENT 1000 // rms current in mA. Multiply by 1.41 for peak current. + #define X_MICROSTEPS 16 // 0..256 + + #define Y_CURRENT 1000 + #define Y_MICROSTEPS 16 + + #define Z_CURRENT 1000 + #define Z_MICROSTEPS 16 + + //#define X2_CURRENT 1000 + //#define X2_MICROSTEPS 16 + + //#define Y2_CURRENT 1000 + //#define Y2_MICROSTEPS 16 + + //#define Z2_CURRENT 1000 + //#define Z2_MICROSTEPS 16 + + //#define E0_CURRENT 1000 + //#define E0_MICROSTEPS 16 + + //#define E1_CURRENT 1000 + //#define E1_MICROSTEPS 16 + + //#define E2_CURRENT 1000 + //#define E2_MICROSTEPS 16 + + //#define E3_CURRENT 1000 + //#define E3_MICROSTEPS 16 + + //#define E4_CURRENT 1000 + //#define E4_MICROSTEPS 16 + + /** + * Use Trinamic's ultra quiet stepping mode. + * When disabled, Marlin will use spreadCycle stepping mode. + */ + #define STEALTHCHOP + + /** + * Let Marlin automatically control stepper current. + * This is still an experimental feature. + * Increase current every 5s by CURRENT_STEP until stepper temperature prewarn gets triggered, + * then decrease current by CURRENT_STEP until temperature prewarn is cleared. + * Adjusting starts from X/Y/Z/E_CURRENT but will not increase over AUTO_ADJUST_MAX + * 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. + * M906 S1 - Start adjusting current + * M906 S0 - Stop adjusting current + * M911 - Report stepper driver overtemperature pre-warn condition. + * M912 - Clear stepper driver overtemperature pre-warn condition flag. + */ + //#define AUTOMATIC_CURRENT_CONTROL + + #if ENABLED(AUTOMATIC_CURRENT_CONTROL) + #define CURRENT_STEP 50 // [mA] + #define AUTO_ADJUST_MAX 1300 // [mA], 1300mA_rms = 1840mA_peak + #define REPORT_CURRENT_CHANGE + #endif + + /** + * The driver will switch to spreadCycle when stepper speed is over HYBRID_THRESHOLD. + * This mode allows for faster movements at the expense of higher noise levels. + * STEALTHCHOP needs to be enabled. + * M913 X/Y/Z/E to live tune the setting + */ + //#define HYBRID_THRESHOLD + + #define X_HYBRID_THRESHOLD 100 // [mm/s] + #define X2_HYBRID_THRESHOLD 100 + #define Y_HYBRID_THRESHOLD 100 + #define Y2_HYBRID_THRESHOLD 100 + #define Z_HYBRID_THRESHOLD 4 + #define Z2_HYBRID_THRESHOLD 4 + #define E0_HYBRID_THRESHOLD 30 + #define E1_HYBRID_THRESHOLD 30 + #define E2_HYBRID_THRESHOLD 30 + #define E3_HYBRID_THRESHOLD 30 + #define E4_HYBRID_THRESHOLD 30 + + /** + * Use stallGuard2 to sense an obstacle and trigger an endstop. + * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. + * If used along with STEALTHCHOP, the movement will be louder when homing. This is normal. + * + * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. + * Higher values make the system LESS sensitive. + * Lower value make the system MORE sensitive. + * Too low values can lead to false positives, while too high values will collide the axis without triggering. + * It is advised to set X/Y_HOME_BUMP_MM to 0. + * M914 X/Y to live tune the setting + */ + //#define SENSORLESS_HOMING + + #if ENABLED(SENSORLESS_HOMING) + #define X_HOMING_SENSITIVITY 19 + #define Y_HOMING_SENSITIVITY 19 + #endif + + /** + * You can set your own advanced settings by filling in predefined functions. + * A list of available functions can be found on the library github page + * https://github.com/teemuatlut/TMC2130Stepper + * + * Example: + * #define TMC2130_ADV() { \ + * stepperX.diag0_temp_prewarn(1); \ + * stepperX.interpolate(0); \ + * } + */ + #define TMC2130_ADV() { } + +#endif // HAVE_TMC2130 + +// @section L6470 + +/** + * Enable this section if you have L6470 motor drivers. + * You need to import the L6470 library into the Arduino IDE for this. + * (https://github.com/ameyer/Arduino-L6470) + */ + +//#define HAVE_L6470DRIVER +#if ENABLED(HAVE_L6470DRIVER) + + //#define X_IS_L6470 + //#define X2_IS_L6470 + //#define Y_IS_L6470 + //#define Y2_IS_L6470 + //#define Z_IS_L6470 + //#define Z2_IS_L6470 + //#define E0_IS_L6470 + //#define E1_IS_L6470 + //#define E2_IS_L6470 + //#define E3_IS_L6470 + //#define E4_IS_L6470 + + #define X_MICROSTEPS 16 // number of microsteps + #define X_K_VAL 50 // 0 - 255, Higher values, are higher power. Be careful not to go too high + #define X_OVERCURRENT 2000 // maxc current in mA. If the current goes over this value, the driver will switch off + #define X_STALLCURRENT 1500 // current in mA where the driver will detect a stall + + #define X2_MICROSTEPS 16 + #define X2_K_VAL 50 + #define X2_OVERCURRENT 2000 + #define X2_STALLCURRENT 1500 + + #define Y_MICROSTEPS 16 + #define Y_K_VAL 50 + #define Y_OVERCURRENT 2000 + #define Y_STALLCURRENT 1500 + + #define Y2_MICROSTEPS 16 + #define Y2_K_VAL 50 + #define Y2_OVERCURRENT 2000 + #define Y2_STALLCURRENT 1500 + + #define Z_MICROSTEPS 16 + #define Z_K_VAL 50 + #define Z_OVERCURRENT 2000 + #define Z_STALLCURRENT 1500 + + #define Z2_MICROSTEPS 16 + #define Z2_K_VAL 50 + #define Z2_OVERCURRENT 2000 + #define Z2_STALLCURRENT 1500 + + #define E0_MICROSTEPS 16 + #define E0_K_VAL 50 + #define E0_OVERCURRENT 2000 + #define E0_STALLCURRENT 1500 + + #define E1_MICROSTEPS 16 + #define E1_K_VAL 50 + #define E1_OVERCURRENT 2000 + #define E1_STALLCURRENT 1500 + + #define E2_MICROSTEPS 16 + #define E2_K_VAL 50 + #define E2_OVERCURRENT 2000 + #define E2_STALLCURRENT 1500 + + #define E3_MICROSTEPS 16 + #define E3_K_VAL 50 + #define E3_OVERCURRENT 2000 + #define E3_STALLCURRENT 1500 + + #define E4_MICROSTEPS 16 + #define E4_K_VAL 50 + #define E4_OVERCURRENT 2000 + #define E4_STALLCURRENT 1500 + +#endif + +/** + * TWI/I2C BUS + * + * This feature is an EXPERIMENTAL feature so it shall not be used on production + * machines. Enabling this will allow you to send and receive I2C data from slave + * devices on the bus. + * + * ; Example #1 + * ; This macro send the string "Marlin" to the slave device with address 0x63 (99) + * ; It uses multiple M260 commands with one B arg + * M260 A99 ; Target slave address + * M260 B77 ; M + * M260 B97 ; a + * M260 B114 ; r + * M260 B108 ; l + * M260 B105 ; i + * M260 B110 ; n + * M260 S1 ; Send the current buffer + * + * ; Example #2 + * ; Request 6 bytes from slave device with address 0x63 (99) + * M261 A99 B5 + * + * ; Example #3 + * ; Example serial output of a M261 request + * echo:i2c-reply: from:99 bytes:5 data:hello + */ + +// @section i2cbus + +//#define EXPERIMENTAL_I2CBUS +#define I2C_SLAVE_ADDRESS 0 // Set a value from 8 to 127 to act as a slave + +// @section extras + +/** + * Spindle & Laser control + * + * Add the M3, M4, and M5 commands to turn the spindle/laser on and off, and + * to set spindle speed, spindle direction, and laser power. + * + * SuperPid is a router/spindle speed controller used in the CNC milling community. + * Marlin can be used to turn the spindle on and off. It can also be used to set + * the spindle speed from 5,000 to 30,000 RPM. + * + * 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. + */ +//#define SPINDLE_LASER_ENABLE +#if ENABLED(SPINDLE_LASER_ENABLE) + + #define SPINDLE_LASER_ENABLE_INVERT false // set to "true" if the on/off function is reversed + #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 // delay in milliseconds to allow the spindle/laser to come up to speed/power + #define SPINDLE_LASER_POWERDOWN_DELAY 5000 // delay in milliseconds to allow the spindle to stop + #define SPINDLE_DIR_CHANGE true // set to true if your spindle controller supports changing spindle direction + #define SPINDLE_INVERT_DIR false + #define SPINDLE_STOP_ON_DIR_CHANGE true // set to true if Marlin should stop the spindle before changing rotation direction + + /** + * The M3 & M4 commands use the following equation to convert PWM duty cycle to speed/power + * + * SPEED/POWER = PWM duty cycle * SPEED_POWER_SLOPE + SPEED_POWER_INTERCEPT + * where PWM duty cycle varies from 0 to 255 + * + * set the following for your controller (ALL MUST BE SET) + */ + + #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_SLOPE 0.3922 + //#define SPEED_POWER_INTERCEPT 0 + //#define SPEED_POWER_MIN 10 + //#define SPEED_POWER_MAX 100 // 0-100% +#endif + +/** + * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins + */ +#define PINS_DEBUGGING + +/** + * Auto-report temperatures with M155 S + */ +#define AUTO_REPORT_TEMPERATURES + +/** + * Include capabilities in M115 output + */ +#define EXTENDED_CAPABILITIES_REPORT + +/** + * Volumetric extrusion default state + * 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. + */ +//#define VOLUMETRIC_DEFAULT_ON + +/** + * Enable this option for a leaner build of Marlin that removes all + * workspace offsets, simplifying coordinate transformations, leveling, etc. + * + * - M206 and M428 are disabled. + * - G92 will revert to its behavior from Marlin 1.0. + */ +#define NO_WORKSPACE_OFFSETS + +/** + * 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. + * + * For clients that use a fixed-width font (like OctoPrint), leave this set to 1.0. + * Otherwise, adjust according to your client and font. + */ +#define PROPORTIONAL_FONT_RATIO 1.5 + +/** + * Spend 28 bytes of SRAM to optimize the GCode parser + */ +#define FASTER_GCODE_PARSER + +/** + * User-defined menu items that execute custom GCode + */ +//#define CUSTOM_USER_MENUS +#if ENABLED(CUSTOM_USER_MENUS) + #define USER_SCRIPT_DONE "M117 User Script Done" + #define USER_SCRIPT_AUDIBLE_FEEDBACK + //#define USER_SCRIPT_RETURN // Return to status screen after a script + + #define USER_DESC_1 "Home & UBL Info" + #define USER_GCODE_1 "G28\nG29 W" + + #define USER_DESC_2 "Preheat for PLA" + #define USER_GCODE_2 "M140 S" STRINGIFY(PREHEAT_1_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND) + + #define USER_DESC_3 "Preheat for ABS" + #define USER_GCODE_3 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND) + + #define USER_DESC_4 "Heat Bed/Home/Level" + #define USER_GCODE_4 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nG28\nG29" + + //#define USER_DESC_5 "Home & Info" + //#define USER_GCODE_5 "G28\nM503" +#endif + +/** + * Specify an action command to send to the host when the printer is killed. + * Will be sent in the form '//action:ACTION_ON_KILL', e.g. '//action:poweroff'. + * The host must be configured to handle the action command. + */ +//#define ACTION_ON_KILL "poweroff" + +//=========================================================================== +//====================== I2C Position Encoder Settings ====================== +//=========================================================================== + +/** + * I2C position encoders for closed loop control. + * Developed by Chris Barr at Aus3D. + * + * Wiki: http://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/ + * + * Reilabuild encoders have been modified to improve reliability. + */ + +//#define I2C_POSITION_ENCODERS +#if ENABLED(I2C_POSITION_ENCODERS) + + #define I2CPE_ENCODER_CNT 1 // The number of encoders installed; max of 5 + // encoders supported currently. + + #define I2CPE_ENC_1_ADDR I2CPE_PRESET_ADDR_X // I2C address of the encoder. 30-200. + #define I2CPE_ENC_1_AXIS X_AXIS // Axis the encoder module is installed on. _AXIS. + #define I2CPE_ENC_1_TYPE I2CPE_ENC_TYPE_LINEAR // Type of encoder: I2CPE_ENC_TYPE_LINEAR -or- + // I2CPE_ENC_TYPE_ROTARY. + #define I2CPE_ENC_1_TICKS_UNIT 2048 // 1024 for magnetic strips with 2mm poles; 2048 for + // 1mm poles. For linear encoders this is ticks / mm, + // for rotary encoders this is ticks / revolution. + //#define I2CPE_ENC_1_TICKS_REV (16 * 200) // Only needed for rotary encoders; number of stepper + // steps per full revolution (motor steps/rev * microstepping) + //#define I2CPE_ENC_1_INVERT // Invert the direction of axis travel. + #define I2CPE_ENC_1_EC_METHOD I2CPE_ECM_NONE // Type of error error correction. + #define I2CPE_ENC_1_EC_THRESH 0.10 // Threshold size for error (in mm) above which the + // printer will attempt to correct the error; errors + // smaller than this are ignored to minimize effects of + // measurement noise / latency (filter). + + #define I2CPE_ENC_2_ADDR I2CPE_PRESET_ADDR_Y // Same as above, but for encoder 2. + #define I2CPE_ENC_2_AXIS Y_AXIS + #define I2CPE_ENC_2_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_ENC_2_TICKS_UNIT 2048 + //#define I2CPE_ENC_2_TICKS_REV (16 * 200) + //#define I2CPE_ENC_2_INVERT + #define I2CPE_ENC_2_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_ENC_2_EC_THRESH 0.10 + + #define I2CPE_ENC_3_ADDR I2CPE_PRESET_ADDR_Z // Encoder 3. Add additional configuration options + #define I2CPE_ENC_3_AXIS Z_AXIS // as above, or use defaults below. + + #define I2CPE_ENC_4_ADDR I2CPE_PRESET_ADDR_E // Encoder 4. + #define I2CPE_ENC_4_AXIS E_AXIS + + #define I2CPE_ENC_5_ADDR 34 // Encoder 5. + #define I2CPE_ENC_5_AXIS E_AXIS + + // Default settings for encoders which are enabled, but without settings configured above. + #define I2CPE_DEF_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_DEF_ENC_TICKS_UNIT 2048 + #define I2CPE_DEF_TICKS_REV (16 * 200) + #define I2CPE_DEF_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_DEF_EC_THRESH 0.1 + + //#define I2CPE_ERR_THRESH_ABORT 100.0 // Threshold size for error (in mm) error on any given + // axis after which the printer will abort. Comment out to + // disable abort behaviour. + + #define I2CPE_TIME_TRUSTED 10000 // After an encoder fault, there must be no further fault + // for this amount of time (in ms) before the encoder + // is trusted again. + + /** + * Position is checked every time a new command is executed from the buffer but during long moves, + * this setting determines the minimum update time between checks. A value of 100 works well with + * error rolling average when attempting to correct only for skips and not for vibration. + */ + #define I2CPE_MIN_UPD_TIME_MS 100 // Minimum time in miliseconds between encoder checks. + + // Use a rolling average to identify persistant errors that indicate skips, as opposed to vibration and noise. + #define I2CPE_ERR_ROLLING_AVERAGE + +#endif // I2C_POSITION_ENCODERS + +/** + * MAX7219 Debug Matrix + * + * Add support for a low-cost 8x8 LED Matrix based on the Max7219 chip, which can be used as a status + * display. Requires 3 signal wires. Some useful debug options are included to demonstrate its usage. + * + * Fully assembled MAX7219 boards can be found on the internet for under $2(US). + * For example, see https://www.ebay.com/sch/i.html?_nkw=332349290049 + */ +//#define MAX7219_DEBUG +#if ENABLED(MAX7219_DEBUG) + #define MAX7219_CLK_PIN 64 // 77 on Re-ARM // Configuration of the 3 pins to control the display + #define MAX7219_DIN_PIN 57 // 78 on Re-ARM + #define MAX7219_LOAD_PIN 44 // 79 on Re-ARM + + /** + * Sample debug features + * If you add more debug displays, be careful to avoid conflicts! + */ + #define MAX7219_DEBUG_PRINTER_ALIVE // Blink corner LED of 8x8 matrix to show that the firmware is functioning + #define MAX7219_DEBUG_STEPPER_HEAD 3 // Show the stepper queue head position on this and the next LED matrix row + #define MAX7219_DEBUG_STEPPER_TAIL 5 // Show the stepper queue tail position on this and the next LED matrix row + + #define MAX7219_DEBUG_STEPPER_QUEUE 0 // Show the current stepper queue depth on this and the next LED matrix row + // If you experience stuttering, reboots, etc. this option can reveal how + // tweaks made to the configuration are affecting the printer in real-time. +#endif + +#endif // CONFIGURATION_ADV_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/Geeetech/GT2560/Configuration.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/Geeetech/GT2560/Configuration.h new file mode 100644 index 00000000..da9cf690 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/Geeetech/GT2560/Configuration.h @@ -0,0 +1,1724 @@ +/** + * 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 . + * + */ + +/** + * Configuration.h + * + * Basic settings such as: + * + * - Type of electronics + * - Type of temperature sensor + * - Printer geometry + * - Endstop configuration + * - LCD controller + * - Extra features + * + * Advanced settings can be found in Configuration_adv.h + * + */ +#ifndef CONFIGURATION_H +#define CONFIGURATION_H +#define CONFIGURATION_H_VERSION 010100 + +//=========================================================================== +//============================= Getting Started ============================= +//=========================================================================== + +/** + * Here are some standard links for getting your machine calibrated: + * + * http://reprap.org/wiki/Calibration + * http://youtu.be/wAL9d7FgInk + * http://calculator.josefprusa.cz + * http://reprap.org/wiki/Triffid_Hunter%27s_Calibration_Guide + * http://www.thingiverse.com/thing:5573 + * https://sites.google.com/site/repraplogphase/calibration-of-your-reprap + * http://www.thingiverse.com/thing:298812 + */ + +//=========================================================================== +//============================= DELTA Printer =============================== +//=========================================================================== +// For a Delta printer start with one of the configuration files in the +// example_configurations/delta directory and customize for your machine. +// + +//=========================================================================== +//============================= SCARA Printer =============================== +//=========================================================================== +// For a SCARA printer start with the configuration files in +// example_configurations/SCARA and customize for your machine. +// + +// @section info + +// User-specified version info of this build to display in [Pronterface, etc] terminal window during +// startup. Implementation of an idea by Prof Braino to inform user that any changes made to this +// build by the user have been successfully uploaded into firmware. +#define STRING_CONFIG_H_AUTHOR "(none, default config)" // Who made the changes. +#define SHOW_BOOTSCREEN +#define STRING_SPLASH_LINE1 SHORT_BUILD_VERSION // will be shown during bootup in line 1 +#define STRING_SPLASH_LINE2 WEBSITE_URL // will be shown during bootup in line 2 + +// +// *** VENDORS PLEASE READ ***************************************************** +// +// Marlin now allow you to have a vendor boot image to be displayed on machine +// start. When SHOW_CUSTOM_BOOTSCREEN is defined Marlin will first show your +// custom boot image and then the default Marlin boot image is shown. +// +// We suggest for you to take advantage of this new feature and keep the Marlin +// boot image unmodified. For an example have a look at the bq Hephestos 2 +// example configuration folder. +// +//#define SHOW_CUSTOM_BOOTSCREEN +// @section machine + +/** + * Select which serial port on the board will be used for communication with the host. + * This allows the connection of wireless adapters (for instance) to non-default port pins. + * Serial port 0 is always used by the Arduino bootloader regardless of this setting. + * + * :[0, 1, 2, 3, 4, 5, 6, 7] + */ +#define SERIAL_PORT 0 + +/** + * This setting determines the communication speed of the printer. + * + * 250000 works in most cases, but you might try a lower speed if + * you commonly experience drop-outs during host printing. + * You may try up to 1000000 to speed up SD file transfer. + * + * :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000] + */ +#define BAUDRATE 250000 + +// Enable the Bluetooth serial interface on AT90USB devices +//#define BLUETOOTH + +// The following define selects which electronics board you have. +// Please choose the name from boards.h that matches your setup +#ifndef MOTHERBOARD + #define MOTHERBOARD BOARD_GT2560_REV_A +#endif + +// Optional custom name for your RepStrap or other custom machine +// Displayed in the LCD "Ready" message +//#define CUSTOM_MACHINE_NAME "3D Printer" + +// Define this to set a unique identifier for this printer, (Used by some programs to differentiate between machines) +// You can use an online service to generate a random UUID. (eg http://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] +#define EXTRUDERS 1 + +// For Cyclops or any "multi-extruder" that shares a single nozzle. +//#define SINGLENOZZLE + +/** + * Průša MK2 Single Nozzle Multi-Material Multiplexer, and variants. + * + * This device allows one stepper driver on a control board to drive + * two to eight stepper motors, one at a time, in a manner suitable + * for extruders. + * + * This option only allows the multiplexer to switch on tool-change. + * Additional options to configure custom E moves are pending. + */ +//#define MK2_MULTIPLEXER +#if ENABLED(MK2_MULTIPLEXER) + // Override the default DIO selector pins here, if needed. + // Some pins files may provide defaults for these pins. + //#define E_MUX0_PIN 40 // Always Required + //#define E_MUX1_PIN 42 // Needed for 3 to 8 steppers + //#define E_MUX2_PIN 44 // Needed for 5 to 8 steppers +#endif + +// A dual extruder that uses a single stepper motor +//#define SWITCHING_EXTRUDER +#if ENABLED(SWITCHING_EXTRUDER) + #define SWITCHING_EXTRUDER_SERVO_NR 0 + #define SWITCHING_EXTRUDER_SERVO_ANGLES { 0, 90 } // Angles for E0, E1[, E2, E3] + #if EXTRUDERS > 3 + #define SWITCHING_EXTRUDER_E23_SERVO_NR 1 + #endif +#endif + +// A dual-nozzle that uses a servomotor to raise/lower one of the nozzles +//#define SWITCHING_NOZZLE +#if ENABLED(SWITCHING_NOZZLE) + #define SWITCHING_NOZZLE_SERVO_NR 0 + #define SWITCHING_NOZZLE_SERVO_ANGLES { 0, 90 } // Angles for E0, E1 + //#define HOTEND_OFFSET_Z { 0.0, 0.0 } +#endif + +/** + * Two separate X-carriages with extruders that connect to a moving part + * via a magnetic docking mechanism. Requires SOL1_PIN and SOL2_PIN. + */ +//#define PARKING_EXTRUDER +#if ENABLED(PARKING_EXTRUDER) + #define PARKING_EXTRUDER_SOLENOIDS_INVERT // If enabled, the solenoid is NOT magnetized with applied voltage + #define PARKING_EXTRUDER_SOLENOIDS_PINS_ACTIVE LOW // LOW or HIGH pin signal energizes the coil + #define PARKING_EXTRUDER_SOLENOIDS_DELAY 250 // Delay (ms) for magnetic field. No delay if 0 or not defined. + #define PARKING_EXTRUDER_PARKING_X { -78, 184 } // X positions for parking the extruders + #define PARKING_EXTRUDER_GRAB_DISTANCE 1 // mm to move beyond the parking point to grab the extruder + #define PARKING_EXTRUDER_SECURITY_RAISE 5 // Z-raise before parking + #define HOTEND_OFFSET_Z { 0.0, 1.3 } // Z-offsets of the two hotends. The first must be 0. +#endif + +/** + * "Mixing Extruder" + * - Adds a new code, M165, to set the current mix factors. + * - Extends the stepping routines to move multiple steppers in proportion to the mix. + * - Optional support for Repetier Firmware M163, M164, and virtual extruder. + * - This implementation supports only a single extruder. + * - Enable DIRECT_MIXING_IN_G1 for Pia Taubert's reference implementation + */ +//#define MIXING_EXTRUDER +#if ENABLED(MIXING_EXTRUDER) + #define MIXING_STEPPERS 2 // Number of steppers in your mixing extruder + #define MIXING_VIRTUAL_TOOLS 16 // Use the Virtual Tool method with M163 and M164 + //#define DIRECT_MIXING_IN_G1 // Allow ABCDHI mix factors in G1 movement commands +#endif + +// Offset of the extruders (uncomment if using more than one and relying on firmware to position when changing). +// The offset has to be X=0, Y=0 for the extruder 0 hotend (default extruder). +// For the other hotends it is their distance from the extruder 0 hotend. +//#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis +//#define HOTEND_OFFSET_Y {0.0, 5.00} // (in mm) for each extruder, offset of the hotend on the Y axis + +// @section machine + +/** + * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN + * + * 0 = No Power Switch + * 1 = ATX + * 2 = X-Box 360 203Watts (the blue wire connected to PS_ON and the red wire to VCC) + * + * :{ 0:'No power switch', 1:'ATX', 2:'X-Box 360' } + */ +#define POWER_SUPPLY 0 + +#if POWER_SUPPLY > 0 + // Enable this option to leave the PSU off at startup. + // Power to steppers and heaters will need to be turned on with M80. + //#define PS_DEFAULT_OFF +#endif + +// @section temperature + +//=========================================================================== +//============================= Thermal Settings ============================ +//=========================================================================== + +/** + * --NORMAL IS 4.7kohm PULLUP!-- 1kohm pullup can be used on hotend sensor, using correct resistor and table + * + * Temperature sensors available: + * + * -3 : thermocouple with MAX31855 (only for sensor 0) + * -2 : thermocouple with MAX6675 (only for sensor 0) + * -1 : thermocouple with AD595 + * 0 : not used + * 1 : 100k thermistor - best choice for EPCOS 100k (4.7k pullup) + * 2 : 200k thermistor - ATC Semitec 204GT-2 (4.7k pullup) + * 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 (Used in ParCan & J-Head) (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) + * 71 : 100k Honeywell thermistor 135-104LAF-J01 (4.7k pullup) + * 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) + * 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" + * 20 : the PT100 circuit found in the Ultimainboard V2.x + * 60 : 100k Maker's Tool Works Kapton Bed Thermistor beta=3950 + * 66 : 4.7M High Temperature thermistor from Dyze Design + * 70 : the 100K thermistor found in the bq Hephestos 2 + * 75 : 100k Generic Silicon Heat Pad with NTC 100K MGB18-104F39050L32 thermistor + * + * 1k ohm pullup tables - This is atypical, and requires changing out the 4.7k pullup for 1k. + * (but gives greater accuracy and more stable PID) + * 51 : 100k thermistor - EPCOS (1k pullup) + * 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 + * 1010 : Pt1000 with 1k pullup (non standard) + * 147 : Pt100 with 4k7 pullup + * 110 : Pt100 with 1k pullup (non standard) + * + * Use these for Testing or Development purposes. NEVER for production machine. + * 998 : Dummy Table that ALWAYS reads 25°C or the temperature defined below. + * 999 : Dummy Table that ALWAYS reads 100°C or the temperature defined below. + * + * :{ '0': "Not used", '1':"100k / 4.7k - EPCOS", '2':"200k / 4.7k - ATC Semitec 204GT-2", '3':"Mendel-parts / 4.7k", '4':"10k !! do not use for a hotend. Bad resolution at high temp. !!", '5':"100K / 4.7k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '6':"100k / 4.7k EPCOS - Not as accurate as Table 1", '7':"100k / 4.7k Honeywell 135-104LAG-J01", '8':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT", '9':"100k / 4.7k GE Sensing AL03006-58.2K-97-G1", '10':"100k / 4.7k RS 198-961", '11':"100k / 4.7k beta 3950 1%", '12':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT (calibrated for Makibox hot bed)", '13':"100k Hisens 3950 1% up to 300°C for hotend 'Simple ONE ' & hotend 'All In ONE'", '20':"PT100 (Ultimainboard V2.x)", '51':"100k / 1k - EPCOS", '52':"200k / 1k - ATC Semitec 204GT-2", '55':"100k / 1k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '60':"100k Maker's Tool Works Kapton Bed Thermistor beta=3950", '66':"Dyze Design 4.7M High Temperature thermistor", '70':"the 100K thermistor found in the bq Hephestos 2", '71':"100k / 4.7k Honeywell 135-104LAF-J01", '147':"Pt100 / 4.7k", '1047':"Pt1000 / 4.7k", '110':"Pt100 / 1k (non-standard)", '1010':"Pt1000 / 1k (non standard)", '-3':"Thermocouple + MAX31855 (only for sensor 0)", '-2':"Thermocouple + MAX6675 (only for sensor 0)", '-1':"Thermocouple + AD595",'998':"Dummy 1", '999':"Dummy 2" } + */ +#define TEMP_SENSOR_0 1 +#define TEMP_SENSOR_1 0 +#define TEMP_SENSOR_2 0 +#define TEMP_SENSOR_3 0 +#define TEMP_SENSOR_4 0 +#define TEMP_SENSOR_BED 1 + +// Dummy thermistor constant temperature readings, for use with 998 and 999 +#define DUMMY_THERMISTOR_998_VALUE 25 +#define DUMMY_THERMISTOR_999_VALUE 100 + +// 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 +#define MAX_REDUNDANT_TEMP_SENSOR_DIFF 10 + +// Extruder temperature must be close to target for this long before M109 returns success +#define TEMP_RESIDENCY_TIME 10 // (seconds) +#define TEMP_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// Bed temperature must be close to target for this long before M190 returns success +#define TEMP_BED_RESIDENCY_TIME 10 // (seconds) +#define TEMP_BED_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_BED_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// The minimal temperature defines the temperature below which the heater will not be enabled It is used +// to check that the wiring to the thermistor is not broken. +// Otherwise this would lead to the heater being powered on all the time. +#define HEATER_0_MINTEMP 5 +#define HEATER_1_MINTEMP 5 +#define HEATER_2_MINTEMP 5 +#define HEATER_3_MINTEMP 5 +#define HEATER_4_MINTEMP 5 +#define BED_MINTEMP 5 + +// When temperature exceeds max temp, your heater will be switched off. +// This feature exists to protect your hotend from overheating accidentally, but *NOT* from thermistor short/failure! +// You should use MINTEMP for thermistor short/failure protection. +#define HEATER_0_MAXTEMP 275 +#define HEATER_1_MAXTEMP 275 +#define HEATER_2_MAXTEMP 275 +#define HEATER_3_MAXTEMP 275 +#define HEATER_4_MAXTEMP 275 +#define BED_MAXTEMP 150 + +//=========================================================================== +//============================= PID Settings ================================ +//=========================================================================== +// PID Tuning Guide here: http://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 +#if ENABLED(PIDTEMP) + //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. + //#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. + #define K1 0.95 //smoothing factor within the PID + + // Geeetech MK8 Extruder + #define DEFAULT_Kp 12.33 + #define DEFAULT_Ki 0.51 + #define DEFAULT_Kd 74.50 + + // CTC MK8 Extruder + //#define DEFAULT_Kp 19.86 + //#define DEFAULT_Ki 1.0 + //#define DEFAULT_Kd 98.83 + + // 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 + +#endif // PIDTEMP + +//=========================================================================== +//============================= PID > Bed Temperature Control =============== +//=========================================================================== +// Select PID or bang-bang with PIDTEMPBED. If bang-bang, BED_LIMIT_SWITCHING will enable hysteresis +// +// Uncomment this to enable PID on the bed. It uses the same frequency PWM as the extruder. +// If your PID_dT is the default, and correct for your hardware/configuration, that means 7.689Hz, +// which is fine for driving a square wave into a resistive load and does not significantly impact you FET heating. +// This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W heater. +// If your configuration is significantly different than this and you don't understand the issues involved, you probably +// shouldn't use bed PID until someone else verifies your hardware works. +// If this is enabled, find your own PID constants below. +//#define PIDTEMPBED + +//#define BED_LIMIT_SWITCHING + +// This sets the max power delivered to the bed, and replaces the HEATER_BED_DUTY_CYCLE_DIVIDER option. +// all forms of bed control obey this (PID, bang-bang, bang-bang with hysteresis) +// setting this to anything other than 255 enables a form of PWM to the bed just like HEATER_BED_DUTY_CYCLE_DIVIDER did, +// so you shouldn't use it unless you are OK with PWM on your bed. (see the comment on enabling PIDTEMPBED) +#define MAX_BED_POWER 255 // limits duty cycle to bed; 255=full current + +#if ENABLED(PIDTEMPBED) + + //#define PID_BED_DEBUG // Sends debug data to the serial port. + + //12v (120 watt?) MK2a PCB Heatbed into 4mm borosilicate (Geeetech Prusa i3 Pro, Pro/B/C/X) + #define DEFAULT_bedKp 234.88 + #define DEFAULT_bedKi 42.79 + #define DEFAULT_bedKd 322.28 + + //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 + +// @section extruder + +// This option prevents extrusion if the temperature is below EXTRUDE_MINTEMP. +// It also enables the M302 command to set the minimum extrusion temperature +// or to allow moving the extruder regardless of the hotend temperature. +// *** IT IS HIGHLY RECOMMENDED TO LEAVE THIS OPTION ENABLED! *** +#define PREVENT_COLD_EXTRUSION +#define EXTRUDE_MINTEMP 170 + +// This option prevents a single extrusion longer than EXTRUDE_MAXLENGTH. +// Note that for Bowden Extruders a too-small value here may prevent loading. +#define PREVENT_LENGTHY_EXTRUDE +#define EXTRUDE_MAXLENGTH 200 + +//=========================================================================== +//======================== Thermal Runaway Protection ======================= +//=========================================================================== + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * If you get "Thermal Runaway" or "Heating failed" errors the + * details can be tuned in Configuration_adv.h + */ + +#define THERMAL_PROTECTION_HOTENDS // Enable thermal protection for all extruders +#define THERMAL_PROTECTION_BED // Enable thermal protection for the heated bed + +//=========================================================================== +//============================= Mechanical Settings ========================= +//=========================================================================== + +// @section machine + +// Uncomment one of these options to enable CoreXY, CoreXZ, or CoreYZ kinematics +// either in the usual order or reversed +//#define COREXY +//#define COREXZ +//#define COREYZ +//#define COREYX +//#define COREZX +//#define COREZY + +//=========================================================================== +//============================== Endstop Settings =========================== +//=========================================================================== + +// @section homing + +// Specify here all the endstop connectors that are connected to any endstop or probe. +// Almost all printers will be using one per axis. Probes will use one or more of the +// extra connectors. Leave undefined any used for non-endstop and non-probe purposes. +#define USE_XMIN_PLUG +#define USE_YMIN_PLUG +#define USE_ZMIN_PLUG +//#define USE_XMAX_PLUG +//#define USE_YMAX_PLUG +//#define USE_ZMAX_PLUG + +// coarse Endstop Settings +#define ENDSTOPPULLUPS // Comment this out (using // at the start of the line) to disable the endstop pullup resistors + +#if DISABLED(ENDSTOPPULLUPS) + // fine endstop settings: Individual pullups. will be ignored if ENDSTOPPULLUPS is defined + //#define ENDSTOPPULLUP_XMAX + //#define ENDSTOPPULLUP_YMAX + //#define ENDSTOPPULLUP_ZMAX + //#define ENDSTOPPULLUP_XMIN + //#define ENDSTOPPULLUP_YMIN + //#define ENDSTOPPULLUP_ZMIN + //#define ENDSTOPPULLUP_ZMIN_PROBE +#endif + +// Mechanical endstop with COM to ground and NC to Signal uses "false" here (most common setup). +#define X_MIN_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Y_MIN_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MIN_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define X_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Y_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MIN_PROBE_ENDSTOP_INVERTING false // set to true to invert the logic of the probe. + +// Enable this feature if all enabled endstop pins are interrupt-capable. +// This will remove the need to poll the interrupt pins, saving many CPU cycles. +//#define ENDSTOP_INTERRUPTS_FEATURE + +//============================================================================= +//============================== Movement Settings ============================ +//============================================================================= +// @section motion + +/** + * Default Settings + * + * These settings can be reset by M502 + * + * Note that if EEPROM is enabled, saved values will override these. + */ + +/** + * With this option each E stepper can have its own factors for the + * following movement settings. If fewer factors are given than the + * total number of extruders, the last value applies to the rest. + */ +//#define DISTINCT_E_FACTORS + +/** + * Default Axis Steps Per Unit (steps/mm) + * Override with M92 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_AXIS_STEPS_PER_UNIT { 78.74, 78.74, 2560, 105 } + +/** + * Default Max Feed Rate (mm/s) + * Override with M203 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_FEEDRATE { 400, 400, 2, 45 } + +/** + * Default Max Acceleration (change/s) change = mm/s + * (Maximum start speed for accelerated moves) + * Override with M201 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_ACCELERATION { 5000, 5000, 50, 5000 } + +/** + * Default Acceleration (change/s) change = mm/s + * Override with M204 + * + * M204 P Acceleration + * M204 R Retract Acceleration + * M204 T Travel Acceleration + */ +#define DEFAULT_ACCELERATION 1000 // X, Y, Z and E acceleration for printing moves +#define DEFAULT_RETRACT_ACCELERATION 2000 // E acceleration for retracts +#define DEFAULT_TRAVEL_ACCELERATION 3000 // X, Y, Z acceleration for travel (non printing) moves + +/** + * Default Jerk (mm/s) + * Override with M205 X Y Z E + * + * "Jerk" specifies the minimum speed change that requires acceleration. + * When changing speed and direction, if the difference is less than the + * value set here, it may happen instantaneously. + */ +#define DEFAULT_XJERK 20.0 +#define DEFAULT_YJERK 20.0 +#define DEFAULT_ZJERK 0.4 +#define DEFAULT_EJERK 5.0 + +//=========================================================================== +//============================= Z Probe Options ============================= +//=========================================================================== +// @section probes + +// +// See http://marlinfw.org/configuration/probes.html +// + +/** + * Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + * + * Enable this option for a probe connected to the Z Min endstop pin. + */ +//#define Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + +/** + * Z_MIN_PROBE_ENDSTOP + * + * Enable this option for a probe connected to any pin except Z-Min. + * (By default Marlin assumes the Z-Max endstop pin.) + * To use a custom Z Probe pin, set Z_MIN_PROBE_PIN below. + * + * - The simplest option is to use a free endstop connector. + * - Use 5V for powered (usually inductive) sensors. + * + * - RAMPS 1.3/1.4 boards may use the 5V, GND, and Aux4->D32 pin: + * - For simple switches connect... + * - normally-closed switches to GND and D32. + * - normally-open switches to 5V and D32. + * + * WARNING: Setting the wrong pin may have unexpected and potentially + * disastrous consequences. Use with caution and do your homework. + * + */ +//#define Z_MIN_PROBE_ENDSTOP + +/** + * Probe Type + * + * Allen Key Probes, Servo Probes, Z-Sled Probes, FIX_MOUNTED_PROBE, etc. + * Activate one of these to use Auto Bed Leveling below. + */ + +/** + * The "Manual Probe" provides a means to do "Auto" Bed Leveling without a probe. + * Use G29 repeatedly, adjusting the Z height at each point with movement commands + * or (with LCD_BED_LEVELING) the LCD controller. + */ +//#define PROBE_MANUALLY + +/** + * A Fix-Mounted Probe either doesn't deploy or needs manual deployment. + * (e.g., an inductive probe or a nozzle-based probe-switch.) + */ +//#define FIX_MOUNTED_PROBE + +/** + * Z Servo Probe, such as an endstop switch on a rotating arm. + */ +//#define Z_ENDSTOP_SERVO_NR 0 // Defaults to SERVO 0 connector. +//#define Z_SERVO_ANGLES {70,0} // Z Servo Deploy and Stow angles + +/** + * The BLTouch probe uses a Hall effect sensor and emulates a servo. + */ +//#define BLTOUCH +#if ENABLED(BLTOUCH) + //#define BLTOUCH_DELAY 375 // (ms) Enable and increase if needed +#endif + +/** + * Enable one or more of the following if probing seems unreliable. + * Heaters and/or fans can be disabled during probing to minimize electrical + * noise. A delay can also be added to allow noise and vibration to settle. + * These options are most useful for the BLTouch probe, but may also improve + * readings with inductive probes and piezo sensors. + */ +//#define PROBING_HEATERS_OFF // Turn heaters off when probing +//#define PROBING_FANS_OFF // Turn fans off when probing +//#define DELAY_BEFORE_PROBING 200 // (ms) To prevent vibrations from triggering piezo sensors + +// A probe that is deployed and stowed with a solenoid pin (SOL1_PIN) +//#define SOLENOID_PROBE + +// A sled-mounted probe like those designed by Charles Bell. +//#define Z_PROBE_SLED +//#define SLED_DOCKING_OFFSET 5 // The extra distance the X axis must travel to pickup the sled. 0 should be fine but you can push it further if you'd like. + +// +// For Z_PROBE_ALLEN_KEY see the Delta example configurations. +// + +/** + * Z Probe to nozzle (X,Y) offset, relative to (0, 0). + * X and Y offsets must be integers. + * + * In the following example the X and Y offsets are both positive: + * #define X_PROBE_OFFSET_FROM_EXTRUDER 10 + * #define Y_PROBE_OFFSET_FROM_EXTRUDER 10 + * + * +-- BACK ---+ + * | | + * L | (+) P | R <-- probe (20,20) + * E | | I + * F | (-) N (+) | G <-- nozzle (10,10) + * T | | H + * | (-) | T + * | | + * O-- FRONT --+ + * (0,0) + */ +#define X_PROBE_OFFSET_FROM_EXTRUDER 10 // X offset: -left +right [of the nozzle] +#define Y_PROBE_OFFSET_FROM_EXTRUDER 10 // Y offset: -front +behind [the nozzle] +#define Z_PROBE_OFFSET_FROM_EXTRUDER 0 // Z offset: -below +above [the nozzle] + +// X and Y axis travel speed (mm/m) between probes +#define XY_PROBE_SPEED 8000 + +// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +#define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z + +// Speed for the "accurate" probe of each point +#define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) + +// Use double touch for probing +//#define PROBE_DOUBLE_TOUCH + +/** + * Z probes require clearance when deploying, stowing, and moving between + * probe points to avoid hitting the bed and other hardware. + * Servo-mounted probes require extra space for the arm to rotate. + * Inductive probes need space to keep from triggering early. + * + * Use these settings to specify the distance (mm) to raise the probe (or + * lower the bed). The values set here apply over and above any (negative) + * probe Z Offset set with Z_PROBE_OFFSET_FROM_EXTRUDER, M851, or the LCD. + * Only integer values >= 1 are valid here. + * + * Example: `M851 Z-5` with a CLEARANCE of 4 => 9mm from bed to nozzle. + * But: `M851 Z+1` with a CLEARANCE of 2 => 2mm from bed to nozzle. + */ +#define Z_CLEARANCE_DEPLOY_PROBE 10 // Z Clearance for Deploy/Stow +#define Z_CLEARANCE_BETWEEN_PROBES 5 // Z Clearance between probe points + +// For M851 give a range for adjusting the Z probe offset +#define Z_PROBE_OFFSET_RANGE_MIN -20 +#define Z_PROBE_OFFSET_RANGE_MAX 20 + +// Enable the M48 repeatability test to test probe accuracy +//#define Z_MIN_PROBE_REPEATABILITY_TEST + +// For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1 +// :{ 0:'Low', 1:'High' } +#define X_ENABLE_ON 0 +#define Y_ENABLE_ON 0 +#define Z_ENABLE_ON 0 +#define E_ENABLE_ON 0 // For all extruders + +// Disables axis stepper immediately when it's not being used. +// 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 +//#define DISABLE_REDUCED_ACCURACY_WARNING + +// @section extruder + +#define DISABLE_E false // For all extruders +#define DISABLE_INACTIVE_EXTRUDER true // Keep only the active extruder enabled. + +// @section machine + +// Invert the stepper direction. Change (or reverse the motor connector) if an axis goes the wrong way. +#define INVERT_X_DIR true +#define INVERT_Y_DIR true +#define INVERT_Z_DIR false + +// Enable this option for Toshiba stepper drivers +//#define CONFIG_STEPPERS_TOSHIBA + +// @section extruder + +// For direct drive extruder v9 set to true, for geared extruder set to false. +#define INVERT_E0_DIR true +#define INVERT_E1_DIR true +#define INVERT_E2_DIR true +#define INVERT_E3_DIR true +#define INVERT_E4_DIR true + +// @section homing + +//#define NO_MOTION_BEFORE_HOMING // Inhibit movement until all axes have been homed + +//#define Z_HOMING_HEIGHT 4 // (in mm) Minimal z height before homing (G28) for Z clearance above the bed, clamps, ... + // Be sure you have this distance over your Z_MAX_POS in case. + +// Direction of endstops when homing; 1=MAX, -1=MIN +// :[-1,1] +#define X_HOME_DIR -1 +#define Y_HOME_DIR -1 +#define Z_HOME_DIR -1 + +// @section machine + +// The size of the print bed +#define X_BED_SIZE 200 +#define Y_BED_SIZE 200 + +// Travel limits (mm) after homing, corresponding to endstop positions. +#define X_MIN_POS 0 +#define Y_MIN_POS 0 +#define Z_MIN_POS 0 +#define X_MAX_POS X_BED_SIZE +#define Y_MAX_POS Y_BED_SIZE +#define Z_MAX_POS 200 + +// If enabled, axes won't move below MIN_POS in response to movement commands. +#define MIN_SOFTWARE_ENDSTOPS +// If enabled, axes won't move above MAX_POS in response to movement commands. +#define MAX_SOFTWARE_ENDSTOPS + +/** + * Filament Runout Sensor + * A mechanical or opto endstop is used to check for the presence of filament. + * + * RAMPS-based boards use SERVO3_PIN. + * For other boards you may need to define FIL_RUNOUT_PIN. + * By default the firmware assumes HIGH = has filament, LOW = ran out + */ +//#define FILAMENT_RUNOUT_SENSOR +#if ENABLED(FILAMENT_RUNOUT_SENSOR) + #define FIL_RUNOUT_INVERTING false // set to true to invert the logic of the sensor. + #define ENDSTOPPULLUP_FIL_RUNOUT // Uncomment to use internal pullup for filament runout pins if the sensor is defined. + #define FILAMENT_RUNOUT_SCRIPT "M600" +#endif + +//=========================================================================== +//=============================== Bed Leveling ============================== +//=========================================================================== +// @section bedlevel + +/** + * Choose one of the options below to enable G29 Bed Leveling. The parameters + * and behavior of G29 will change depending on your selection. + * + * If using a Probe for Z Homing, enable Z_SAFE_HOMING also! + * + * - AUTO_BED_LEVELING_3POINT + * Probe 3 arbitrary points on the bed (that aren't collinear) + * You specify the XY coordinates of all 3 points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_LINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_BILINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a mesh, best for large or uneven beds. + * + * - AUTO_BED_LEVELING_UBL (Unified Bed Leveling) + * A comprehensive bed leveling system combining the features and benefits + * of other systems. UBL also includes integrated Mesh Generation, Mesh + * Validation and Mesh Editing systems. Currently, UBL is only checked out + * for Cartesian Printers. That said, it was primarily designed to correct + * poor quality Delta Printers. If you feel adventurous and have a Delta, + * please post an issue if something doesn't work correctly. Initially, + * you will need to set a reduced bed size so you have a rectangular area + * to test on. + * + * - MESH_BED_LEVELING + * Probe a grid manually + * The result is a mesh, suitable for large or uneven beds. (See BILINEAR.) + * For machines without a probe, Mesh Bed Leveling provides a method to perform + * leveling in steps so you can manually adjust the Z height at each grid-point. + * With an LCD controller the process is guided step-by-step. + */ +//#define AUTO_BED_LEVELING_3POINT +//#define AUTO_BED_LEVELING_LINEAR +//#define AUTO_BED_LEVELING_BILINEAR +//#define AUTO_BED_LEVELING_UBL +//#define MESH_BED_LEVELING + +/** + * Enable detailed logging of G28, G29, M48, etc. + * Turn on with the command 'M111 S32'. + * NOTE: Requires a lot of PROGMEM! + */ +//#define DEBUG_LEVELING_FEATURE + +#if ENABLED(MESH_BED_LEVELING) || ENABLED(AUTO_BED_LEVELING_BILINEAR) || ENABLED(AUTO_BED_LEVELING_UBL) + // Gradually reduce leveling correction until a set height is reached, + // at which point movement will be level to the machine's XY plane. + // The height can be set with M420 Z + #define ENABLE_LEVELING_FADE_HEIGHT +#endif + +#if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Set the number of grid points per dimension. + #define GRID_MAX_POINTS_X 3 + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + // Set the boundaries for probing (where the probe can reach). + #define LEFT_PROBE_BED_POSITION 15 + #define RIGHT_PROBE_BED_POSITION 170 + #define FRONT_PROBE_BED_POSITION 20 + #define BACK_PROBE_BED_POSITION 170 + + // The Z probe minimum outer margin (to validate G29 parameters). + #define MIN_PROBE_EDGE 10 + + // Probe along the Y axis, advancing X after each column + //#define PROBE_Y_FIRST + + #if ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Beyond the probed grid, continue the implied tilt? + // Default is to maintain the height of the nearest edge. + //#define EXTRAPOLATE_BEYOND_GRID + + // + // Experimental Subdivision of the grid by Catmull-Rom method. + // Synthesizes intermediate points to produce a more detailed mesh. + // + //#define ABL_BILINEAR_SUBDIVISION + #if ENABLED(ABL_BILINEAR_SUBDIVISION) + // Number of subdivisions between probe points + #define BILINEAR_SUBDIVISIONS 3 + #endif + + #endif + +#elif ENABLED(AUTO_BED_LEVELING_3POINT) + + // 3 arbitrary points to probe. + // A simple cross-product is used to estimate the plane of the bed. + #define ABL_PROBE_PT_1_X 15 + #define ABL_PROBE_PT_1_Y 180 + #define ABL_PROBE_PT_2_X 15 + #define ABL_PROBE_PT_2_Y 20 + #define ABL_PROBE_PT_3_X 170 + #define ABL_PROBE_PT_3_Y 20 + +#elif ENABLED(AUTO_BED_LEVELING_UBL) + + //=========================================================================== + //========================= Unified Bed Leveling ============================ + //=========================================================================== + + #define UBL_MESH_INSET 1 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 10 // Don't use more than 15 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + #define UBL_PROBE_PT_1_X 39 // Probing points for 3-Point leveling of the mesh + #define UBL_PROBE_PT_1_Y 180 + #define UBL_PROBE_PT_2_X 39 + #define UBL_PROBE_PT_2_Y 20 + #define UBL_PROBE_PT_3_X 180 + #define UBL_PROBE_PT_3_Y 20 + + #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation + #define UBL_MESH_EDIT_MOVES_Z // Sophisticated users prefer no movement of nozzle + +#elif ENABLED(MESH_BED_LEVELING) + + //=========================================================================== + //=================================== Mesh ================================== + //=========================================================================== + + #define MESH_INSET 10 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 3 // Don't use more than 7 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + //#define MESH_G28_REST_ORIGIN // After homing all axes ('G28' or 'G28 XYZ') rest Z at Z_MIN_POS + +#endif // BED_LEVELING + +/** + * Use the LCD controller for bed leveling + * Requires MESH_BED_LEVELING or PROBE_MANUALLY + */ +//#define LCD_BED_LEVELING + +#if ENABLED(LCD_BED_LEVELING) + #define MBL_Z_STEP 0.025 // Step size while manually probing Z axis. + #define LCD_PROBE_Z_RANGE 4 // Z Range centered on Z_MIN_POS for LCD Z adjustment +#endif + +// Add a menu item to move between bed corners for manual bed adjustment +//#define LEVEL_BED_CORNERS + +/** + * Commands to execute at the end of G29 probing. + * Useful to retract or move the Z probe out of the way. + */ +//#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) +//#define BED_CENTER_AT_0_0 + +// Manually set the home position. Leave these undefined for automatic settings. +// For DELTA this is the top-center of the Cartesian print volume. +//#define MANUAL_X_HOME_POS 0 +//#define MANUAL_Y_HOME_POS 0 +//#define MANUAL_Z_HOME_POS 0 + +// Use "Z Safe Homing" to avoid homing with a Z probe outside the bed area. +// +// With this feature enabled: +// +// - 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). +// - 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 axis (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). +#endif + +// Homing speeds (mm/m) +#define HOMING_FEEDRATE_XY (50*60) +#define HOMING_FEEDRATE_Z (4*60) + +//============================================================================= +//============================= Additional Features =========================== +//============================================================================= + +// @section extras + +// +// EEPROM +// +// The microcontroller can store settings in the EEPROM, e.g. max velocity... +// M500 - stores parameters in EEPROM +// M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily). +// M502 - reverts to the default "factory settings". You still need to store them in EEPROM afterwards if you want to. +// +#define EEPROM_SETTINGS // Enable for M500 and M501 commands +//#define DISABLE_M503 // Saves ~2700 bytes of PROGMEM. Disable for release! +#define EEPROM_CHITCHAT // Give feedback on EEPROM commands. Disable to save PROGMEM. + +// +// Host Keepalive +// +// When enabled Marlin will send a busy status message to the host +// every couple of seconds when it can't accept commands. +// +#define HOST_KEEPALIVE_FEATURE // Disable this if your host doesn't like keepalive messages +#define DEFAULT_KEEPALIVE_INTERVAL 2 // Number of seconds between "busy" messages. Set with M113. +#define BUSY_WHILE_HEATING // Some hosts require "busy" messages even during heating + +// +// M100 Free Memory Watcher +// +//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose + +// +// G20/G21 Inch mode support +// +//#define INCH_MODE_SUPPORT + +// +// M149 Set temperature units support +// +//#define TEMPERATURE_UNITS_SUPPORT + +// @section temperature + +// Preheat Constants +#define PREHEAT_1_TEMP_HOTEND 180 +#define PREHEAT_1_TEMP_BED 70 +#define PREHEAT_1_FAN_SPEED 0 // Value from 0 to 255 + +#define PREHEAT_2_TEMP_HOTEND 240 +#define PREHEAT_2_TEMP_BED 110 +#define PREHEAT_2_FAN_SPEED 0 // Value from 0 to 255 + +/** + * Nozzle Park -- EXPERIMENTAL + * + * Park the nozzle at the given XYZ position on idle or G27. + * + * The "P" parameter controls the action applied to the Z axis: + * + * P0 (Default) If Z is below park Z raise the nozzle. + * P1 Raise the nozzle always to Z-park height. + * P2 Raise the nozzle by Z-park amount, limited to Z_MAX_POS. + */ +//#define NOZZLE_PARK_FEATURE + +#if ENABLED(NOZZLE_PARK_FEATURE) + // Specify a park position as { X, Y, Z } + #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 } +#endif + +/** + * Clean Nozzle Feature -- EXPERIMENTAL + * + * Adds the G12 command to perform a nozzle cleaning process. + * + * Parameters: + * P Pattern + * S Strokes / Repetitions + * T Triangles (P1 only) + * + * Patterns: + * P0 Straight line (default). This process requires a sponge type material + * at a fixed bed location. "S" specifies strokes (i.e. back-forth motions) + * between the start / end points. + * + * P1 Zig-zag pattern between (X0, Y0) and (X1, Y1), "T" specifies the + * number of zig-zag triangles to do. "S" defines the number of strokes. + * Zig-zags are done in whichever is the narrower dimension. + * For example, "G12 P1 S1 T3" will execute: + * + * -- + * | (X0, Y1) | /\ /\ /\ | (X1, Y1) + * | | / \ / \ / \ | + * A | | / \ / \ / \ | + * | | / \ / \ / \ | + * | (X0, Y0) | / \/ \/ \ | (X1, Y0) + * -- +--------------------------------+ + * |________|_________|_________| + * T1 T2 T3 + * + * P2 Circular pattern with middle at NOZZLE_CLEAN_CIRCLE_MIDDLE. + * "R" specifies the radius. "S" specifies the stroke count. + * Before starting, the nozzle moves to NOZZLE_CLEAN_START_POINT. + * + * Caveats: The ending Z should be the same as starting Z. + * Attention: EXPERIMENTAL. G-code arguments may change. + * + */ +//#define NOZZLE_CLEAN_FEATURE + +#if ENABLED(NOZZLE_CLEAN_FEATURE) + // Default number of pattern repetitions + #define NOZZLE_CLEAN_STROKES 12 + + // Default number of triangles + #define NOZZLE_CLEAN_TRIANGLES 3 + + // Specify positions as { X, Y, Z } + #define NOZZLE_CLEAN_START_POINT { 30, 30, (Z_MIN_POS + 1)} + #define NOZZLE_CLEAN_END_POINT {100, 60, (Z_MIN_POS + 1)} + + // Circular pattern radius + #define NOZZLE_CLEAN_CIRCLE_RADIUS 6.5 + // Circular pattern circle fragments number + #define NOZZLE_CLEAN_CIRCLE_FN 10 + // Middle point of circle + #define NOZZLE_CLEAN_CIRCLE_MIDDLE NOZZLE_CLEAN_START_POINT + + // Moves the nozzle to the initial position + #define NOZZLE_CLEAN_GOBACK +#endif + +/** + * Print Job Timer + * + * Automatically start and stop the print job timer on M104/M109/M190. + * + * M104 (hotend, no wait) - high temp = none, low temp = stop timer + * M109 (hotend, wait) - high temp = start timer, low temp = stop timer + * M190 (bed, wait) - high temp = start timer, low temp = none + * + * The timer can also be controlled with the following commands: + * + * M75 - Start the print job timer + * M76 - Pause the print job timer + * M77 - Stop the print job timer + */ +#define PRINTJOB_TIMER_AUTOSTART + +/** + * Print Counter + * + * Track statistical data such as: + * + * - Total print jobs + * - Total successful print jobs + * - Total failed print jobs + * - Total time printing + * + * View the current statistics with M78. + */ +//#define PRINTCOUNTER + +//============================================================================= +//============================= LCD and SD support ============================ +//============================================================================= + +// @section lcd + +/** + * LCD LANGUAGE + * + * Select the language to display on the LCD. These languages are available: + * + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, + * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * tr, uk, zh_CN, zh_TW, test + * + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + */ +#define LCD_LANGUAGE en + +/** + * LCD Character Set + * + * Note: This option is NOT applicable to Graphical Displays. + * + * All character-based LCDs provide ASCII plus one of these + * language extensions: + * + * - JAPANESE ... the most common + * - WESTERN ... with more accented characters + * - CYRILLIC ... for the Russian language + * + * To determine the language extension installed on your controller: + * + * - Compile and upload with LCD_LANGUAGE set to 'test' + * - 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 + * + * :['JAPANESE', 'WESTERN', 'CYRILLIC'] + */ +#define DISPLAY_CHARSET_HD44780 JAPANESE + +/** + * LCD TYPE + * + * Enable ULTRA_LCD for a 16x2, 16x4, 20x2, or 20x4 character-based LCD. + * Enable DOGLCD for a 128x64 (ST7565R) Full Graphical Display. + * (These options will be enabled automatically for most displays.) + * + * IMPORTANT: The U8glib library is required for Full Graphic Display! + * https://github.com/olikraus/U8glib_Arduino + */ +//#define ULTRA_LCD // Character based +//#define DOGLCD // Full graphics display + +/** + * SD CARD + * + * 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 + +/** + * SD CARD: SPI SPEED + * + * Enable one of the following items for a slower SPI transfer speed. + * This may be required to resolve "volume init" errors. + */ +//#define SPI_SPEED SPI_HALF_SPEED +//#define SPI_SPEED SPI_QUARTER_SPEED +//#define SPI_SPEED SPI_EIGHTH_SPEED + +/** + * SD CARD: ENABLE CRC + * + * Use CRC checks and retries on the SD communication. + */ +//#define SD_CHECK_AND_RETRY + +// +// ENCODER SETTINGS +// +// This option overrides the default number of encoder pulses needed to +// produce one step. Should be increased for high-resolution encoders. +// +//#define ENCODER_PULSES_PER_STEP 1 + +// +// Use this option to override the number of step signals required to +// move between next/prev menu items. +// +//#define ENCODER_STEPS_PER_MENU_ITEM 5 + +/** + * Encoder Direction Options + * + * Test your encoder's behavior first with both options disabled. + * + * Reversed Value Edit and Menu Nav? Enable REVERSE_ENCODER_DIRECTION. + * Reversed Menu Navigation only? Enable REVERSE_MENU_DIRECTION. + * Reversed Value Editing only? Enable BOTH options. + */ + +// +// This option reverses the encoder direction everywhere. +// +// Set this option if CLOCKWISE causes values to DECREASE +// +//#define REVERSE_ENCODER_DIRECTION + +// +// This option reverses the encoder direction for navigating LCD menus. +// +// If CLOCKWISE normally moves DOWN this makes it go UP. +// If CLOCKWISE normally moves UP this makes it go DOWN. +// +//#define REVERSE_MENU_DIRECTION + +// +// Individual Axis Homing +// +// Add individual axis homing items (Home X, Home Y, and Home Z) to the LCD menu. +// +//#define INDIVIDUAL_AXIS_HOMING_MENU + +// +// SPEAKER/BUZZER +// +// If you have a speaker that can produce tones, enable it here. +// By default Marlin assumes you have a buzzer with a fixed frequency. +// +//#define SPEAKER + +// +// The duration and frequency for the UI feedback sound. +// Set these to 0 to disable audio feedback in the LCD menus. +// +// Note: Test audio output with the G-Code: +// M300 S P +// +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 +//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 + +// +// CONTROLLER TYPE: Standard +// +// Marlin supports a wide variety of controllers. +// Enable one of the following options to specify your controller. +// + +// +// ULTIMAKER Controller. +// +//#define ULTIMAKERCONTROLLER + +// +// ULTIPANEL as seen on Thingiverse. +// +//#define ULTIPANEL + +// +// PanelOne from T3P3 (via RAMPS 1.4 AUX2/AUX3) +// http://reprap.org/wiki/PanelOne +// +//#define PANEL_ONE + +// +// MaKr3d Makr-Panel with graphic controller and SD support. +// http://reprap.org/wiki/MaKr3d_MaKrPanel +// +//#define MAKRPANEL + +// +// ReprapWorld Graphical LCD +// https://reprapworld.com/?products_details&products_id/1218 +// +//#define REPRAPWORLD_GRAPHICAL_LCD + +// +// Activate one of these if you have a Panucatt Devices +// Viki 2.0 or mini Viki with Graphic LCD +// http://panucatt.com +// +//#define VIKI2 +//#define miniVIKI + +// +// Adafruit ST7565 Full Graphic Controller. +// https://github.com/eboston/Adafruit-ST7565-Full-Graphic-Controller/ +// +//#define ELB_FULL_GRAPHIC_CONTROLLER + +// +// RepRapDiscount Smart Controller. +// http://reprap.org/wiki/RepRapDiscount_Smart_Controller +// +// Note: Usually sold with a white PCB. +// +#define REPRAP_DISCOUNT_SMART_CONTROLLER + +// +// GADGETS3D G3D LCD/SD Controller +// http://reprap.org/wiki/RAMPS_1.3/1.4_GADGETS3D_Shield_with_Panel +// +// Note: Usually sold with a blue PCB. +// +//#define G3D_PANEL + +// +// RepRapDiscount FULL GRAPHIC Smart Controller +// http://reprap.org/wiki/RepRapDiscount_Full_Graphic_Smart_Controller +// +//#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER + +// +// MakerLab Mini Panel with graphic +// controller and SD support - http://reprap.org/wiki/Mini_panel +// +//#define MINIPANEL + +// +// RepRapWorld REPRAPWORLD_KEYPAD v1.1 +// http://reprapworld.com/?products_details&products_id=202&cPath=1591_1626 +// +// REPRAPWORLD_KEYPAD_MOVE_STEP sets how much should the robot move when a key +// is pressed, a value of 10.0 means 10mm per click. +// +//#define REPRAPWORLD_KEYPAD +//#define REPRAPWORLD_KEYPAD_MOVE_STEP 1.0 + +// +// RigidBot Panel V1.0 +// http://www.inventapart.com/ +// +//#define RIGIDBOT_PANEL + +// +// BQ LCD Smart Controller shipped by +// default with the BQ Hephestos 2 and Witbox 2. +// +//#define BQ_LCD_SMART_CONTROLLER + +// +// Cartesio UI +// http://mauk.cc/webshop/cartesio-shop/electronics/user-interface +// +//#define CARTESIO_UI + +// +// ANET_10 Controller supported displays. +// +//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. + // This LCD is known to be susceptible to electrical interference + // which scrambles the display. Pressing any button clears it up. +//#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 + // A clone of the RepRapDiscount full graphics display but with + // different pins/wiring (see pins_ANET_10.h). + +// +// LCD for Melzi Card with Graphical LCD +// +//#define LCD_FOR_MELZI + +// +// CONTROLLER TYPE: I2C +// +// Note: These controllers require the installation of Arduino's LiquidCrystal_I2C +// library. For more info: https://github.com/kiyoshigawa/LiquidCrystal_I2C +// + +// +// Elefu RA Board Control Panel +// http://www.elefu.com/index.php?route=product/product&product_id=53 +// +//#define RA_CONTROL_PANEL + +// +// Sainsmart YW Robot (LCM1602) LCD Display +// +// Note: This controller requires F.Malpartida's LiquidCrystal_I2C library +// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home +// +//#define LCD_I2C_SAINSMART_YWROBOT + +// +// Generic LCM1602 LCD adapter +// +//#define LCM1602 + +// +// PANELOLU2 LCD with status LEDs, +// separate encoder and click inputs. +// +// Note: This controller requires Arduino's LiquidTWI2 library v1.2.3 or later. +// For more info: https://github.com/lincomatic/LiquidTWI2 +// +// Note: The PANELOLU2 encoder click input can either be directly connected to +// a pin (if BTN_ENC defined to != -1) or read through I2C (when BTN_ENC == -1). +// +//#define LCD_I2C_PANELOLU2 + +// +// Panucatt VIKI LCD with status LEDs, +// integrated click & L/R/U/D buttons, separate encoder inputs. +// +//#define LCD_I2C_VIKI + +// +// SSD1306 OLED full graphics generic display +// +//#define U8GLIB_SSD1306 + +// +// SAV OLEd LCD module support using either SSD1306 or SH1106 based LCD modules +// +//#define SAV_3DGLCD +#if ENABLED(SAV_3DGLCD) + //#define U8GLIB_SSD1306 + #define U8GLIB_SH1106 +#endif + +// +// CONTROLLER TYPE: Shift register panels +// +// 2 wire Non-latching LCD SR from https://goo.gl/aJJ4sH +// LCD configuration: http://reprap.org/wiki/SAV_3D_LCD +// +//#define SAV_3DLCD + +// +// TinyBoy2 128x64 OLED / Encoder Panel +// +//#define OLED_PANEL_TINYBOY2 + +// +// Makeboard 3D Printer Parts 3D Printer Mini Display 1602 Mini Controller +// https://www.aliexpress.com/item/Micromake-Makeboard-3D-Printer-Parts-3D-Printer-Mini-Display-1602-Mini-Controller-Compatible-with-Ramps-1/32765887917.html +// +//#define MAKEBOARD_MINI_2_LINE_DISPLAY_1602 + +// +// MKS MINI12864 with graphic controller and SD support +// http://reprap.org/wiki/MKS_MINI_12864 +// +//#define MKS_MINI_12864 + +// +// Factory display for Creality CR-10 +// https://www.aliexpress.com/item/Universal-LCD-12864-3D-Printer-Display-Screen-With-Encoder-For-CR-10-CR-7-Model/32833148327.html +// +// This is RAMPS-compatible using a single 10-pin connector. +// (For CR-10 owners who want to replace the Melzi Creality board but retain the display) +// +//#define CR10_STOCKDISPLAY + +// +// MKS OLED 1.3" 128 × 64 FULL GRAPHICS CONTROLLER +// http://reprap.org/wiki/MKS_12864OLED +// +// Tiny, but very sharp OLED display +// +//#define MKS_12864OLED + +//============================================================================= +//=============================== Extra Features ============================== +//============================================================================= + +// @section extras + +// Increase the FAN PWM frequency. Removes the PWM noise but increases heating in the FET/Arduino +//#define FAST_PWM_FAN + +// Use software PWM to drive the fan, as for the heaters. This uses a very low frequency +// which is not as annoying as with the hardware PWM. On the other hand, if this frequency +// is too low, you should also increment SOFT_PWM_SCALE. +//#define FAN_SOFT_PWM + +// Incrementing this by 1 will double the software PWM frequency, +// affecting heaters, and the fan if FAN_SOFT_PWM is enabled. +// However, control resolution will be halved for each increment; +// at zero value, there are 128 effective control positions. +#define SOFT_PWM_SCALE 0 + +// If SOFT_PWM_SCALE is set to a value higher than 0, dithering can +// be used to mitigate the associated resolution loss. If enabled, +// some of the PWM cycles are stretched so on average the desired +// duty cycle is attained. +//#define SOFT_PWM_DITHER + +// Temperature status LEDs that display the hotend and bed temperature. +// If all hotends, bed temperature, and target temperature are under 54C +// then the BLUE led is on. Otherwise the RED led is on. (1C hysteresis) +//#define TEMP_STAT_LEDS + +// M240 Triggers a camera by emulating a Canon RC-1 Remote +// Data from: http://www.doc-diy.net/photo/rc-1_hacked/ +//#define PHOTOGRAPH_PIN 23 + +// 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 + +// Support for BlinkM/CyzRgb +//#define BLINKM + +// Support for PCA9632 PWM LED driver +//#define PCA9632 + +/** + * RGB LED / LED Strip Control + * + * Enable support for an RGB LED connected to 5V digital pins, or + * an RGB Strip connected to MOSFETs controlled by digital pins. + * + * 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 overall brightness parameters is also available + * + * *** CAUTION *** + * LED Strips require a MOFSET 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! + * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino + * cannot handle such current, separate 5V power supply must be used + * *** CAUTION *** + * + * LED type. This options are mutualy exclusive. Uncomment only one. + * + */ +//#define RGB_LED +//#define RGBW_LED + +#if ENABLED(RGB_LED) || ENABLED(RGBW_LED) + #define RGB_LED_R_PIN 34 + #define RGB_LED_G_PIN 43 + #define RGB_LED_B_PIN 35 + #define RGB_LED_W_PIN -1 +#endif + +// 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 (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) + #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip + #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time + #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + //#define NEOPIXEL_STARTUP_TEST // Cycle through colors at startup +#endif + +/** + * Printer Event LEDs + * + * During printing, the LEDs will reflect the printer status: + * + * - Gradually change from blue to violet as the heated bed gets to target temp + * - Gradually change from violet to red as the hotend gets to temperature + * - Change to white to illuminate work surface + * - Change to green once print has finished + * - Turn off after the print has finished and the user has pushed a button + */ +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) + #define PRINTER_EVENT_LEDS +#endif + +/*********************************************************************\ +* R/C SERVO support +* Sponsored by TrinityLabs, Reworked by codexmas +**********************************************************************/ + +// Number of servos +// +// If you select a configuration below, this will receive a default value and does not need to be set manually +// set it manually if you have more servos than extruders and wish to manually control some +// leaving it undefined or defining as 0 will disable the servo subsystem +// If unsure, leave commented / disabled +// +//#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command + +// Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. +// 300ms is a good value but you can try less delay. +// If the servo can't reach the requested position, increase it. +#define SERVO_DELAY { 300 } + +// Servo deactivation +// +// With this option servos are powered only during movement, then turned off to prevent jitter. +//#define DEACTIVATE_SERVOS_AFTER_MOVE + +/** + * Filament Width Sensor + * + * Measures the filament width in real-time and adjusts + * flow rate to compensate for any irregularities. + * + * Also allows the measured filament diameter to set the + * extrusion rate, so the slicer only has to specify the + * volume. + * + * Only a single extruder is supported at this time. + * + * 34 RAMPS_14 : Analog input 5 on the AUX2 connector + * 81 PRINTRBOARD : Analog input 2 on the Exp1 connector (version B,C,D,E) + * 301 RAMBO : Analog input 3 + * + * Note: May require analog pins to be defined for other boards. + */ +//#define FILAMENT_WIDTH_SENSOR + +#define DEFAULT_NOMINAL_FILAMENT_DIA 1.75 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. + +#if ENABLED(FILAMENT_WIDTH_SENSOR) + #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) + #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber + + #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading + #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading + #define MAX_MEASUREMENT_DELAY 20 // (bytes) Buffer size for stored measurements (1 byte per cm). Must be larger than MEASUREMENT_DELAY_CM. + + #define DEFAULT_MEASURED_FILAMENT_DIA DEFAULT_NOMINAL_FILAMENT_DIA // Set measured to nominal initially + + // Display filament width on the LCD status line. Status messages will expire after 5 seconds. + //#define FILAMENT_LCD_DISPLAY +#endif + +/** + * Customize common displays for GT2560 + */ +#if ENABLED(ULTIMAKERCONTROLLER) || ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER) || ENABLED(G3D_PANEL) + #define SDSUPPORT // Force SD Card support on for these displays +#elif ENABLED(ULTRA_LCD) && ENABLED(DOGLCD) // No panel, just graphical LCD? + #define LCD_WIDTH 20 // Default is 22. For this Geeetech use 20 +#endif + +#endif // CONFIGURATION_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/Geeetech/I3_Pro_X-GT2560/Configuration.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/Geeetech/I3_Pro_X-GT2560/Configuration.h new file mode 100644 index 00000000..00bf9dc7 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/Geeetech/I3_Pro_X-GT2560/Configuration.h @@ -0,0 +1,1700 @@ +/** + * 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 . + * + */ + +/** + * Configuration.h + * + * Basic settings such as: + * + * - Type of electronics + * - Type of temperature sensor + * - Printer geometry + * - Endstop configuration + * - LCD controller + * - Extra features + * + * Advanced settings can be found in Configuration_adv.h + * + */ +#ifndef CONFIGURATION_H +#define CONFIGURATION_H +#define CONFIGURATION_H_VERSION 010100 + +//=========================================================================== +//============================= Getting Started ============================= +//=========================================================================== + +/** + * Here are some standard links for getting your machine calibrated: + * + * http://reprap.org/wiki/Calibration + * http://youtu.be/wAL9d7FgInk + * http://calculator.josefprusa.cz + * http://reprap.org/wiki/Triffid_Hunter%27s_Calibration_Guide + * http://www.thingiverse.com/thing:5573 + * https://sites.google.com/site/repraplogphase/calibration-of-your-reprap + * http://www.thingiverse.com/thing:298812 + */ + +//=========================================================================== +//============================= DELTA Printer =============================== +//=========================================================================== +// For a Delta printer start with one of the configuration files in the +// example_configurations/delta directory and customize for your machine. +// + +//=========================================================================== +//============================= SCARA Printer =============================== +//=========================================================================== +// For a SCARA printer start with the configuration files in +// example_configurations/SCARA and customize for your machine. +// + +// @section info + +// User-specified version info of this build to display in [Pronterface, etc] terminal window during +// startup. Implementation of an idea by Prof Braino to inform user that any changes made to this +// build by the user have been successfully uploaded into firmware. +#define STRING_CONFIG_H_AUTHOR "(R. de Weerd, I3 Pro X)" // Who made the changes. +#define SHOW_BOOTSCREEN +#define STRING_SPLASH_LINE1 SHORT_BUILD_VERSION // will be shown during bootup in line 1 +#define STRING_SPLASH_LINE2 WEBSITE_URL // will be shown during bootup in line 2 + +// +// *** VENDORS PLEASE READ ***************************************************** +// +// Marlin now allow you to have a vendor boot image to be displayed on machine +// start. When SHOW_CUSTOM_BOOTSCREEN is defined Marlin will first show your +// custom boot image and then the default Marlin boot image is shown. +// +// We suggest for you to take advantage of this new feature and keep the Marlin +// boot image unmodified. For an example have a look at the bq Hephestos 2 +// example configuration folder. +// +//#define SHOW_CUSTOM_BOOTSCREEN +// @section machine + +/** + * Select which serial port on the board will be used for communication with the host. + * This allows the connection of wireless adapters (for instance) to non-default port pins. + * Serial port 0 is always used by the Arduino bootloader regardless of this setting. + * + * :[0, 1, 2, 3, 4, 5, 6, 7] + */ +#define SERIAL_PORT 0 + +/** + * This setting determines the communication speed of the printer. + * + * 250000 works in most cases, but you might try a lower speed if + * you commonly experience drop-outs during host printing. + * You may try up to 1000000 to speed up SD file transfer. + * + * :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000] + */ +#define BAUDRATE 250000 + +// Enable the Bluetooth serial interface on AT90USB devices +//#define BLUETOOTH + +// The following define selects which electronics board you have. +// Please choose the name from boards.h that matches your setup +#ifndef MOTHERBOARD + #define MOTHERBOARD BOARD_ULTIMAKER +#endif + +// Optional custom name for your RepStrap or other custom machine +// Displayed in the LCD "Ready" message +#define CUSTOM_MACHINE_NAME "RdW i3 Pro X" + +// Define this to set a unique identifier for this printer, (Used by some programs to differentiate between machines) +// You can use an online service to generate a random UUID. (eg http://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] +#define EXTRUDERS 1 + +// For Cyclops or any "multi-extruder" that shares a single nozzle. +//#define SINGLENOZZLE + +/** + * Průša MK2 Single Nozzle Multi-Material Multiplexer, and variants. + * + * This device allows one stepper driver on a control board to drive + * two to eight stepper motors, one at a time, in a manner suitable + * for extruders. + * + * This option only allows the multiplexer to switch on tool-change. + * Additional options to configure custom E moves are pending. + */ +//#define MK2_MULTIPLEXER +#if ENABLED(MK2_MULTIPLEXER) + // Override the default DIO selector pins here, if needed. + // Some pins files may provide defaults for these pins. + //#define E_MUX0_PIN 40 // Always Required + //#define E_MUX1_PIN 42 // Needed for 3 to 8 steppers + //#define E_MUX2_PIN 44 // Needed for 5 to 8 steppers +#endif + +// A dual extruder that uses a single stepper motor +//#define SWITCHING_EXTRUDER +#if ENABLED(SWITCHING_EXTRUDER) + #define SWITCHING_EXTRUDER_SERVO_NR 0 + #define SWITCHING_EXTRUDER_SERVO_ANGLES { 0, 90 } // Angles for E0, E1[, E2, E3] + #if EXTRUDERS > 3 + #define SWITCHING_EXTRUDER_E23_SERVO_NR 1 + #endif +#endif + +// A dual-nozzle that uses a servomotor to raise/lower one of the nozzles +//#define SWITCHING_NOZZLE +#if ENABLED(SWITCHING_NOZZLE) + #define SWITCHING_NOZZLE_SERVO_NR 0 + #define SWITCHING_NOZZLE_SERVO_ANGLES { 0, 90 } // Angles for E0, E1 + //#define HOTEND_OFFSET_Z { 0.0, 0.0 } +#endif + +/** + * Two separate X-carriages with extruders that connect to a moving part + * via a magnetic docking mechanism. Requires SOL1_PIN and SOL2_PIN. + */ +//#define PARKING_EXTRUDER +#if ENABLED(PARKING_EXTRUDER) + #define PARKING_EXTRUDER_SOLENOIDS_INVERT // If enabled, the solenoid is NOT magnetized with applied voltage + #define PARKING_EXTRUDER_SOLENOIDS_PINS_ACTIVE LOW // LOW or HIGH pin signal energizes the coil + #define PARKING_EXTRUDER_SOLENOIDS_DELAY 250 // Delay (ms) for magnetic field. No delay if 0 or not defined. + #define PARKING_EXTRUDER_PARKING_X { -78, 184 } // X positions for parking the extruders + #define PARKING_EXTRUDER_GRAB_DISTANCE 1 // mm to move beyond the parking point to grab the extruder + #define PARKING_EXTRUDER_SECURITY_RAISE 5 // Z-raise before parking + #define HOTEND_OFFSET_Z { 0.0, 1.3 } // Z-offsets of the two hotends. The first must be 0. +#endif + +/** + * "Mixing Extruder" + * - Adds a new code, M165, to set the current mix factors. + * - Extends the stepping routines to move multiple steppers in proportion to the mix. + * - Optional support for Repetier Firmware M163, M164, and virtual extruder. + * - This implementation supports only a single extruder. + * - Enable DIRECT_MIXING_IN_G1 for Pia Taubert's reference implementation + */ +//#define MIXING_EXTRUDER +#if ENABLED(MIXING_EXTRUDER) + #define MIXING_STEPPERS 2 // Number of steppers in your mixing extruder + #define MIXING_VIRTUAL_TOOLS 16 // Use the Virtual Tool method with M163 and M164 + //#define DIRECT_MIXING_IN_G1 // Allow ABCDHI mix factors in G1 movement commands +#endif + +// Offset of the extruders (uncomment if using more than one and relying on firmware to position when changing). +// The offset has to be X=0, Y=0 for the extruder 0 hotend (default extruder). +// For the other hotends it is their distance from the extruder 0 hotend. +//#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis +//#define HOTEND_OFFSET_Y {0.0, 5.00} // (in mm) for each extruder, offset of the hotend on the Y axis + +// @section machine + +/** + * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN + * + * 0 = No Power Switch + * 1 = ATX + * 2 = X-Box 360 203Watts (the blue wire connected to PS_ON and the red wire to VCC) + * + * :{ 0:'No power switch', 1:'ATX', 2:'X-Box 360' } + */ +#define POWER_SUPPLY 0 + +#if POWER_SUPPLY > 0 + // Enable this option to leave the PSU off at startup. + // Power to steppers and heaters will need to be turned on with M80. + //#define PS_DEFAULT_OFF +#endif + +// @section temperature + +//=========================================================================== +//============================= Thermal Settings ============================ +//=========================================================================== + +/** + * --NORMAL IS 4.7kohm PULLUP!-- 1kohm pullup can be used on hotend sensor, using correct resistor and table + * + * Temperature sensors available: + * + * -3 : thermocouple with MAX31855 (only for sensor 0) + * -2 : thermocouple with MAX6675 (only for sensor 0) + * -1 : thermocouple with AD595 + * 0 : not used + * 1 : 100k thermistor - best choice for EPCOS 100k (4.7k pullup) + * 2 : 200k thermistor - ATC Semitec 204GT-2 (4.7k pullup) + * 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 (Used in ParCan & J-Head) (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) + * 71 : 100k Honeywell thermistor 135-104LAF-J01 (4.7k pullup) + * 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) + * 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" + * 20 : the PT100 circuit found in the Ultimainboard V2.x + * 60 : 100k Maker's Tool Works Kapton Bed Thermistor beta=3950 + * 66 : 4.7M High Temperature thermistor from Dyze Design + * 70 : the 100K thermistor found in the bq Hephestos 2 + * 75 : 100k Generic Silicon Heat Pad with NTC 100K MGB18-104F39050L32 thermistor + * + * 1k ohm pullup tables - This is atypical, and requires changing out the 4.7k pullup for 1k. + * (but gives greater accuracy and more stable PID) + * 51 : 100k thermistor - EPCOS (1k pullup) + * 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 + * 1010 : Pt1000 with 1k pullup (non standard) + * 147 : Pt100 with 4k7 pullup + * 110 : Pt100 with 1k pullup (non standard) + * + * Use these for Testing or Development purposes. NEVER for production machine. + * 998 : Dummy Table that ALWAYS reads 25°C or the temperature defined below. + * 999 : Dummy Table that ALWAYS reads 100°C or the temperature defined below. + * + * :{ '0': "Not used", '1':"100k / 4.7k - EPCOS", '2':"200k / 4.7k - ATC Semitec 204GT-2", '3':"Mendel-parts / 4.7k", '4':"10k !! do not use for a hotend. Bad resolution at high temp. !!", '5':"100K / 4.7k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '6':"100k / 4.7k EPCOS - Not as accurate as Table 1", '7':"100k / 4.7k Honeywell 135-104LAG-J01", '8':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT", '9':"100k / 4.7k GE Sensing AL03006-58.2K-97-G1", '10':"100k / 4.7k RS 198-961", '11':"100k / 4.7k beta 3950 1%", '12':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT (calibrated for Makibox hot bed)", '13':"100k Hisens 3950 1% up to 300°C for hotend 'Simple ONE ' & hotend 'All In ONE'", '20':"PT100 (Ultimainboard V2.x)", '51':"100k / 1k - EPCOS", '52':"200k / 1k - ATC Semitec 204GT-2", '55':"100k / 1k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '60':"100k Maker's Tool Works Kapton Bed Thermistor beta=3950", '66':"Dyze Design 4.7M High Temperature thermistor", '70':"the 100K thermistor found in the bq Hephestos 2", '71':"100k / 4.7k Honeywell 135-104LAF-J01", '147':"Pt100 / 4.7k", '1047':"Pt1000 / 4.7k", '110':"Pt100 / 1k (non-standard)", '1010':"Pt1000 / 1k (non standard)", '-3':"Thermocouple + MAX31855 (only for sensor 0)", '-2':"Thermocouple + MAX6675 (only for sensor 0)", '-1':"Thermocouple + AD595",'998':"Dummy 1", '999':"Dummy 2" } + */ +#define TEMP_SENSOR_0 1 +#define TEMP_SENSOR_1 0 +#define TEMP_SENSOR_2 0 +#define TEMP_SENSOR_3 0 +#define TEMP_SENSOR_4 0 +#define TEMP_SENSOR_BED 1 + +// Dummy thermistor constant temperature readings, for use with 998 and 999 +#define DUMMY_THERMISTOR_998_VALUE 25 +#define DUMMY_THERMISTOR_999_VALUE 100 + +// 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 +#define MAX_REDUNDANT_TEMP_SENSOR_DIFF 10 + +// Extruder temperature must be close to target for this long before M109 returns success +#define TEMP_RESIDENCY_TIME 10 // (seconds) +#define TEMP_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// Bed temperature must be close to target for this long before M190 returns success +#define TEMP_BED_RESIDENCY_TIME 10 // (seconds) +#define TEMP_BED_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_BED_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// The minimal temperature defines the temperature below which the heater will not be enabled It is used +// to check that the wiring to the thermistor is not broken. +// Otherwise this would lead to the heater being powered on all the time. +#define HEATER_0_MINTEMP 5 +#define HEATER_1_MINTEMP 5 +#define HEATER_2_MINTEMP 5 +#define HEATER_3_MINTEMP 5 +#define HEATER_4_MINTEMP 5 +#define BED_MINTEMP 5 + +// When temperature exceeds max temp, your heater will be switched off. +// This feature exists to protect your hotend from overheating accidentally, but *NOT* from thermistor short/failure! +// You should use MINTEMP for thermistor short/failure protection. +#define HEATER_0_MAXTEMP 275 +#define HEATER_1_MAXTEMP 275 +#define HEATER_2_MAXTEMP 275 +#define HEATER_3_MAXTEMP 275 +#define HEATER_4_MAXTEMP 275 +#define BED_MAXTEMP 150 + +//=========================================================================== +//============================= PID Settings ================================ +//=========================================================================== +// PID Tuning Guide here: http://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 +#if ENABLED(PIDTEMP) + //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. + //#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. + #define K1 0.95 //smoothing factor within the PID + + // 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 + +#endif // PIDTEMP + +//=========================================================================== +//============================= PID > Bed Temperature Control =============== +//=========================================================================== +// Select PID or bang-bang with PIDTEMPBED. If bang-bang, BED_LIMIT_SWITCHING will enable hysteresis +// +// Uncomment this to enable PID on the bed. It uses the same frequency PWM as the extruder. +// If your PID_dT is the default, and correct for your hardware/configuration, that means 7.689Hz, +// which is fine for driving a square wave into a resistive load and does not significantly impact you FET heating. +// This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W heater. +// If your configuration is significantly different than this and you don't understand the issues involved, you probably +// shouldn't use bed PID until someone else verifies your hardware works. +// If this is enabled, find your own PID constants below. +//#define PIDTEMPBED + +//#define BED_LIMIT_SWITCHING + +// This sets the max power delivered to the bed, and replaces the HEATER_BED_DUTY_CYCLE_DIVIDER option. +// all forms of bed control obey this (PID, bang-bang, bang-bang with hysteresis) +// setting this to anything other than 255 enables a form of PWM to the bed just like HEATER_BED_DUTY_CYCLE_DIVIDER did, +// so you shouldn't use it unless you are OK with PWM on your bed. (see the comment on enabling PIDTEMPBED) +#define MAX_BED_POWER 255 // limits duty cycle to bed; 255=full current + +#if ENABLED(PIDTEMPBED) + + //#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) + #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 + +// @section extruder + +// This option prevents extrusion if the temperature is below EXTRUDE_MINTEMP. +// It also enables the M302 command to set the minimum extrusion temperature +// or to allow moving the extruder regardless of the hotend temperature. +// *** IT IS HIGHLY RECOMMENDED TO LEAVE THIS OPTION ENABLED! *** +#define PREVENT_COLD_EXTRUSION +#define EXTRUDE_MINTEMP 170 + +// This option prevents a single extrusion longer than EXTRUDE_MAXLENGTH. +// Note that for Bowden Extruders a too-small value here may prevent loading. +#define PREVENT_LENGTHY_EXTRUDE +#define EXTRUDE_MAXLENGTH 300 + +//=========================================================================== +//======================== Thermal Runaway Protection ======================= +//=========================================================================== + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * If you get "Thermal Runaway" or "Heating failed" errors the + * details can be tuned in Configuration_adv.h + */ + +#define THERMAL_PROTECTION_HOTENDS // Enable thermal protection for all extruders +#define THERMAL_PROTECTION_BED // Enable thermal protection for the heated bed + +//=========================================================================== +//============================= Mechanical Settings ========================= +//=========================================================================== + +// @section machine + +// Uncomment one of these options to enable CoreXY, CoreXZ, or CoreYZ kinematics +// either in the usual order or reversed +//#define COREXY +//#define COREXZ +//#define COREYZ +//#define COREYX +//#define COREZX +//#define COREZY + +//=========================================================================== +//============================== Endstop Settings =========================== +//=========================================================================== + +// @section homing + +// Specify here all the endstop connectors that are connected to any endstop or probe. +// Almost all printers will be using one per axis. Probes will use one or more of the +// extra connectors. Leave undefined any used for non-endstop and non-probe purposes. +#define USE_XMIN_PLUG +#define USE_YMIN_PLUG +#define USE_ZMIN_PLUG +//#define USE_XMAX_PLUG +//#define USE_YMAX_PLUG +//#define USE_ZMAX_PLUG + +// coarse Endstop Settings +#define ENDSTOPPULLUPS // Comment this out (using // at the start of the line) to disable the endstop pullup resistors + +#if DISABLED(ENDSTOPPULLUPS) + // fine endstop settings: Individual pullups. will be ignored if ENDSTOPPULLUPS is defined + //#define ENDSTOPPULLUP_XMAX + //#define ENDSTOPPULLUP_YMAX + //#define ENDSTOPPULLUP_ZMAX + //#define ENDSTOPPULLUP_XMIN + //#define ENDSTOPPULLUP_YMIN + //#define ENDSTOPPULLUP_ZMIN + //#define ENDSTOPPULLUP_ZMIN_PROBE +#endif + +// Mechanical endstop with COM to ground and NC to Signal uses "false" here (most common setup). +#define X_MIN_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Y_MIN_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MIN_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define X_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Y_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MIN_PROBE_ENDSTOP_INVERTING false // set to true to invert the logic of the probe. + +// Enable this feature if all enabled endstop pins are interrupt-capable. +// This will remove the need to poll the interrupt pins, saving many CPU cycles. +//#define ENDSTOP_INTERRUPTS_FEATURE + +//============================================================================= +//============================== Movement Settings ============================ +//============================================================================= +// @section motion + +/** + * Default Settings + * + * These settings can be reset by M502 + * + * Note that if EEPROM is enabled, saved values will override these. + */ + +/** + * With this option each E stepper can have its own factors for the + * following movement settings. If fewer factors are given than the + * total number of extruders, the last value applies to the rest. + */ +//#define DISTINCT_E_FACTORS + +/** + * Default Axis Steps Per Unit (steps/mm) + * Override with M92 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_AXIS_STEPS_PER_UNIT { 80, 80, 2560, 93 } // MXL, Z M8=1.25, MK8 + +/** + * Default Max Feed Rate (mm/s) + * Override with M203 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_FEEDRATE { 400, 400, 2, 45 } + +/** + * Default Max Acceleration (change/s) change = mm/s + * (Maximum start speed for accelerated moves) + * Override with M201 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_ACCELERATION { 4000, 4000, 40, 4000 } + +/** + * Default Acceleration (change/s) change = mm/s + * Override with M204 + * + * M204 P Acceleration + * M204 R Retract Acceleration + * M204 T Travel Acceleration + */ +#define DEFAULT_ACCELERATION 1000 // X, Y, Z and E acceleration for printing moves +#define DEFAULT_RETRACT_ACCELERATION 2000 // E acceleration for retracts +#define DEFAULT_TRAVEL_ACCELERATION 3000 // X, Y, Z acceleration for travel (non printing) moves + +/** + * Default Jerk (mm/s) + * Override with M205 X Y Z E + * + * "Jerk" specifies the minimum speed change that requires acceleration. + * When changing speed and direction, if the difference is less than the + * value set here, it may happen instantaneously. + */ +#define DEFAULT_XJERK 5.0 +#define DEFAULT_YJERK 5.0 +#define DEFAULT_ZJERK 0.3 +#define DEFAULT_EJERK 4.0 + +//=========================================================================== +//============================= Z Probe Options ============================= +//=========================================================================== +// @section probes + +// +// See http://marlinfw.org/configuration/probes.html +// + +/** + * Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + * + * Enable this option for a probe connected to the Z Min endstop pin. + */ +#define Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + +/** + * Z_MIN_PROBE_ENDSTOP + * + * Enable this option for a probe connected to any pin except Z-Min. + * (By default Marlin assumes the Z-Max endstop pin.) + * To use a custom Z Probe pin, set Z_MIN_PROBE_PIN below. + * + * - The simplest option is to use a free endstop connector. + * - Use 5V for powered (usually inductive) sensors. + * + * - RAMPS 1.3/1.4 boards may use the 5V, GND, and Aux4->D32 pin: + * - For simple switches connect... + * - normally-closed switches to GND and D32. + * - normally-open switches to 5V and D32. + * + * WARNING: Setting the wrong pin may have unexpected and potentially + * disastrous consequences. Use with caution and do your homework. + * + */ +//#define Z_MIN_PROBE_ENDSTOP + +/** + * Probe Type + * + * Allen Key Probes, Servo Probes, Z-Sled Probes, FIX_MOUNTED_PROBE, etc. + * Activate one of these to use Auto Bed Leveling below. + */ + +/** + * The "Manual Probe" provides a means to do "Auto" Bed Leveling without a probe. + * Use G29 repeatedly, adjusting the Z height at each point with movement commands + * or (with LCD_BED_LEVELING) the LCD controller. + */ +//#define PROBE_MANUALLY + +/** + * A Fix-Mounted Probe either doesn't deploy or needs manual deployment. + * (e.g., an inductive probe or a nozzle-based probe-switch.) + */ +//#define FIX_MOUNTED_PROBE + +/** + * Z Servo Probe, such as an endstop switch on a rotating arm. + */ +//#define Z_ENDSTOP_SERVO_NR 1 // Defaults to SERVO 0 connector. +//#define Z_SERVO_ANGLES {10,90} // Z Servo Deploy and Stow angles + +/** + * The BLTouch probe uses a Hall effect sensor and emulates a servo. + */ +//#define BLTOUCH +#if ENABLED(BLTOUCH) + #define BLTOUCH_DELAY 375 // (ms) Enable and increase if needed +#endif + +/** + * Enable one or more of the following if probing seems unreliable. + * Heaters and/or fans can be disabled during probing to minimize electrical + * noise. A delay can also be added to allow noise and vibration to settle. + * These options are most useful for the BLTouch probe, but may also improve + * readings with inductive probes and piezo sensors. + */ +//#define PROBING_HEATERS_OFF // Turn heaters off when probing +//#define PROBING_FANS_OFF // Turn fans off when probing +//#define DELAY_BEFORE_PROBING 200 // (ms) To prevent vibrations from triggering piezo sensors + +// A probe that is deployed and stowed with a solenoid pin (SOL1_PIN) +//#define SOLENOID_PROBE + +// A sled-mounted probe like those designed by Charles Bell. +//#define Z_PROBE_SLED +//#define SLED_DOCKING_OFFSET 5 // The extra distance the X axis must travel to pickup the sled. 0 should be fine but you can push it further if you'd like. + +// +// For Z_PROBE_ALLEN_KEY see the Delta example configurations. +// + +/** + * Z Probe to nozzle (X,Y) offset, relative to (0, 0). + * X and Y offsets must be integers. + * + * In the following example the X and Y offsets are both positive: + * #define X_PROBE_OFFSET_FROM_EXTRUDER 10 + * #define Y_PROBE_OFFSET_FROM_EXTRUDER 10 + * + * +-- BACK ---+ + * | | + * L | (+) P | R <-- probe (20,20) + * E | | I + * F | (-) N (+) | G <-- nozzle (10,10) + * T | | H + * | (-) | T + * | | + * O-- FRONT --+ + * (0,0) + */ +#define X_PROBE_OFFSET_FROM_EXTRUDER 10 // X offset: -left +right [of the nozzle] +#define Y_PROBE_OFFSET_FROM_EXTRUDER 10 // Y offset: -front +behind [the nozzle] +#define Z_PROBE_OFFSET_FROM_EXTRUDER 0 // Z offset: -below +above [the nozzle] + +// X and Y axis travel speed (mm/m) between probes +#define XY_PROBE_SPEED 8000 + +// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +#define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z + +// Speed for the "accurate" probe of each point +#define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) + +// Use double touch for probing +//#define PROBE_DOUBLE_TOUCH + +/** + * Z probes require clearance when deploying, stowing, and moving between + * probe points to avoid hitting the bed and other hardware. + * Servo-mounted probes require extra space for the arm to rotate. + * Inductive probes need space to keep from triggering early. + * + * Use these settings to specify the distance (mm) to raise the probe (or + * lower the bed). The values set here apply over and above any (negative) + * probe Z Offset set with Z_PROBE_OFFSET_FROM_EXTRUDER, M851, or the LCD. + * Only integer values >= 1 are valid here. + * + * Example: `M851 Z-5` with a CLEARANCE of 4 => 9mm from bed to nozzle. + * But: `M851 Z+1` with a CLEARANCE of 2 => 2mm from bed to nozzle. + */ +#define Z_CLEARANCE_DEPLOY_PROBE 10 // Z Clearance for Deploy/Stow +#define Z_CLEARANCE_BETWEEN_PROBES 6 // Z Clearance between probe points + +// For M851 give a range for adjusting the Z probe offset +#define Z_PROBE_OFFSET_RANGE_MIN -20 +#define Z_PROBE_OFFSET_RANGE_MAX 20 + +// Enable the M48 repeatability test to test probe accuracy +//#define Z_MIN_PROBE_REPEATABILITY_TEST + +// For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1 +// :{ 0:'Low', 1:'High' } +#define X_ENABLE_ON 0 +#define Y_ENABLE_ON 0 +#define Z_ENABLE_ON 0 +#define E_ENABLE_ON 0 // For all extruders + +// Disables axis stepper immediately when it's not being used. +// 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 +//#define DISABLE_REDUCED_ACCURACY_WARNING + +// @section extruder + +#define DISABLE_E false // For all extruders +#define DISABLE_INACTIVE_EXTRUDER true // Keep only the active extruder enabled. + +// @section machine + +// Invert the stepper direction. Change (or reverse the motor connector) if an axis goes the wrong way. +#define INVERT_X_DIR true +#define INVERT_Y_DIR true +#define INVERT_Z_DIR false + +// Enable this option for Toshiba stepper drivers +//#define CONFIG_STEPPERS_TOSHIBA + +// @section extruder + +// For direct drive extruder v9 set to true, for geared extruder set to false. +#define INVERT_E0_DIR true +#define INVERT_E1_DIR false +#define INVERT_E2_DIR false +#define INVERT_E3_DIR false +#define INVERT_E4_DIR false + +// @section homing + +//#define NO_MOTION_BEFORE_HOMING // Inhibit movement until all axes have been homed + +#define Z_HOMING_HEIGHT 8 // (in mm) Minimal z height before homing (G28) for Z clearance above the bed, clamps, ... + // Be sure you have this distance over your Z_MAX_POS in case. + +// Direction of endstops when homing; 1=MAX, -1=MIN +// :[-1,1] +#define X_HOME_DIR -1 +#define Y_HOME_DIR -1 +#define Z_HOME_DIR -1 + +// @section machine + +// The size of the print bed +#define X_BED_SIZE 205 +#define Y_BED_SIZE 230 + +// Travel limits (mm) after homing, corresponding to endstop positions. +#define X_MIN_POS 0 +#define Y_MIN_POS 0 +#define Z_MIN_POS 0 +#define X_MAX_POS X_BED_SIZE +#define Y_MAX_POS Y_BED_SIZE +#define Z_MAX_POS 170 + +// If enabled, axes won't move below MIN_POS in response to movement commands. +#define MIN_SOFTWARE_ENDSTOPS +// If enabled, axes won't move above MAX_POS in response to movement commands. +#define MAX_SOFTWARE_ENDSTOPS + +/** + * Filament Runout Sensor + * A mechanical or opto endstop is used to check for the presence of filament. + * + * RAMPS-based boards use SERVO3_PIN. + * For other boards you may need to define FIL_RUNOUT_PIN. + * By default the firmware assumes HIGH = has filament, LOW = ran out + */ +//#define FILAMENT_RUNOUT_SENSOR +#if ENABLED(FILAMENT_RUNOUT_SENSOR) + #define FIL_RUNOUT_INVERTING false // set to true to invert the logic of the sensor. + #define ENDSTOPPULLUP_FIL_RUNOUT // Uncomment to use internal pullup for filament runout pins if the sensor is defined. + #define FILAMENT_RUNOUT_SCRIPT "M600" +#endif + +//=========================================================================== +//=============================== Bed Leveling ============================== +//=========================================================================== +// @section bedlevel + +/** + * Choose one of the options below to enable G29 Bed Leveling. The parameters + * and behavior of G29 will change depending on your selection. + * + * If using a Probe for Z Homing, enable Z_SAFE_HOMING also! + * + * - AUTO_BED_LEVELING_3POINT + * Probe 3 arbitrary points on the bed (that aren't collinear) + * You specify the XY coordinates of all 3 points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_LINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_BILINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a mesh, best for large or uneven beds. + * + * - AUTO_BED_LEVELING_UBL (Unified Bed Leveling) + * A comprehensive bed leveling system combining the features and benefits + * of other systems. UBL also includes integrated Mesh Generation, Mesh + * Validation and Mesh Editing systems. Currently, UBL is only checked out + * for Cartesian Printers. That said, it was primarily designed to correct + * poor quality Delta Printers. If you feel adventurous and have a Delta, + * please post an issue if something doesn't work correctly. Initially, + * you will need to set a reduced bed size so you have a rectangular area + * to test on. + * + * - MESH_BED_LEVELING + * Probe a grid manually + * The result is a mesh, suitable for large or uneven beds. (See BILINEAR.) + * For machines without a probe, Mesh Bed Leveling provides a method to perform + * leveling in steps so you can manually adjust the Z height at each grid-point. + * With an LCD controller the process is guided step-by-step. + */ +//#define AUTO_BED_LEVELING_3POINT +//#define AUTO_BED_LEVELING_LINEAR +//#define AUTO_BED_LEVELING_BILINEAR +//#define AUTO_BED_LEVELING_UBL +//#define MESH_BED_LEVELING + +/** + * Enable detailed logging of G28, G29, M48, etc. + * Turn on with the command 'M111 S32'. + * NOTE: Requires a lot of PROGMEM! + */ +//#define DEBUG_LEVELING_FEATURE + +#if ENABLED(MESH_BED_LEVELING) || ENABLED(AUTO_BED_LEVELING_BILINEAR) || ENABLED(AUTO_BED_LEVELING_UBL) + // Gradually reduce leveling correction until a set height is reached, + // at which point movement will be level to the machine's XY plane. + // The height can be set with M420 Z + #define ENABLE_LEVELING_FADE_HEIGHT +#endif + +#if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Set the number of grid points per dimension. + #define GRID_MAX_POINTS_X 3 + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + // Set the boundaries for probing (where the probe can reach). + #define LEFT_PROBE_BED_POSITION 15 + #define RIGHT_PROBE_BED_POSITION 170 + #define FRONT_PROBE_BED_POSITION 20 + #define BACK_PROBE_BED_POSITION 170 + + // The Z probe minimum outer margin (to validate G29 parameters). + #define MIN_PROBE_EDGE 8 + + // Probe along the Y axis, advancing X after each column + //#define PROBE_Y_FIRST + + #if ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Beyond the probed grid, continue the implied tilt? + // Default is to maintain the height of the nearest edge. + //#define EXTRAPOLATE_BEYOND_GRID + + // + // Experimental Subdivision of the grid by Catmull-Rom method. + // Synthesizes intermediate points to produce a more detailed mesh. + // + //#define ABL_BILINEAR_SUBDIVISION + #if ENABLED(ABL_BILINEAR_SUBDIVISION) + // Number of subdivisions between probe points + #define BILINEAR_SUBDIVISIONS 3 + #endif + + #endif + +#elif ENABLED(AUTO_BED_LEVELING_3POINT) + + // 3 arbitrary points to probe. + // A simple cross-product is used to estimate the plane of the bed. + #define ABL_PROBE_PT_1_X 15 + #define ABL_PROBE_PT_1_Y 180 + #define ABL_PROBE_PT_2_X 15 + #define ABL_PROBE_PT_2_Y 20 + #define ABL_PROBE_PT_3_X 170 + #define ABL_PROBE_PT_3_Y 20 + +#elif ENABLED(AUTO_BED_LEVELING_UBL) + + //=========================================================================== + //========================= Unified Bed Leveling ============================ + //=========================================================================== + + #define UBL_MESH_INSET 1 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 10 // Don't use more than 15 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + #define UBL_PROBE_PT_1_X 39 // Probing points for 3-Point leveling of the mesh + #define UBL_PROBE_PT_1_Y 180 + #define UBL_PROBE_PT_2_X 39 + #define UBL_PROBE_PT_2_Y 20 + #define UBL_PROBE_PT_3_X 180 + #define UBL_PROBE_PT_3_Y 20 + + #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation + #define UBL_MESH_EDIT_MOVES_Z // Sophisticated users prefer no movement of nozzle + +#elif ENABLED(MESH_BED_LEVELING) + + //=========================================================================== + //=================================== Mesh ================================== + //=========================================================================== + + #define MESH_INSET 10 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 3 // Don't use more than 7 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + //#define MESH_G28_REST_ORIGIN // After homing all axes ('G28' or 'G28 XYZ') rest Z at Z_MIN_POS + +#endif // BED_LEVELING + +/** + * Use the LCD controller for bed leveling + * Requires MESH_BED_LEVELING or PROBE_MANUALLY + */ +//#define LCD_BED_LEVELING + +#if ENABLED(LCD_BED_LEVELING) + #define MBL_Z_STEP 0.025 // Step size while manually probing Z axis. + #define LCD_PROBE_Z_RANGE 4 // Z Range centered on Z_MIN_POS for LCD Z adjustment +#endif + +// Add a menu item to move between bed corners for manual bed adjustment +//#define LEVEL_BED_CORNERS + +/** + * Commands to execute at the end of G29 probing. + * Useful to retract or move the Z probe out of the way. + */ +//#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) +//#define BED_CENTER_AT_0_0 + +// Manually set the home position. Leave these undefined for automatic settings. +// For DELTA this is the top-center of the Cartesian print volume. +//#define MANUAL_X_HOME_POS 0 +//#define MANUAL_Y_HOME_POS 0 +//#define MANUAL_Z_HOME_POS 0 + +// Use "Z Safe Homing" to avoid homing with a Z probe outside the bed area. +// +// With this feature enabled: +// +// - 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). +// - 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 axis (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). +#endif + +// Homing speeds (mm/m) +#define HOMING_FEEDRATE_XY (50*60) +#define HOMING_FEEDRATE_Z (4*60) + +//============================================================================= +//============================= Additional Features =========================== +//============================================================================= + +// @section extras + +// +// EEPROM +// +// The microcontroller can store settings in the EEPROM, e.g. max velocity... +// M500 - stores parameters in EEPROM +// M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily). +// M502 - reverts to the default "factory settings". You still need to store them in EEPROM afterwards if you want to. +// +#define EEPROM_SETTINGS // Enable for M500 and M501 commands +//#define DISABLE_M503 // Saves ~2700 bytes of PROGMEM. Disable for release! +#define EEPROM_CHITCHAT // Give feedback on EEPROM commands. Disable to save PROGMEM. + +// +// Host Keepalive +// +// When enabled Marlin will send a busy status message to the host +// every couple of seconds when it can't accept commands. +// +#define HOST_KEEPALIVE_FEATURE // Disable this if your host doesn't like keepalive messages +#define DEFAULT_KEEPALIVE_INTERVAL 4 // Number of seconds between "busy" messages. Set with M113. +#define BUSY_WHILE_HEATING // Some hosts require "busy" messages even during heating + +// +// M100 Free Memory Watcher +// +//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose + +// +// G20/G21 Inch mode support +// +//#define INCH_MODE_SUPPORT + +// +// M149 Set temperature units support +// +//#define TEMPERATURE_UNITS_SUPPORT + +// @section temperature + +// Preheat Constants +#define PREHEAT_1_TEMP_HOTEND 180 +#define PREHEAT_1_TEMP_BED 70 +#define PREHEAT_1_FAN_SPEED 0 // Value from 0 to 255 + +#define PREHEAT_2_TEMP_HOTEND 215 +#define PREHEAT_2_TEMP_BED 105 +#define PREHEAT_2_FAN_SPEED 0 // Value from 0 to 255 + +/** + * Nozzle Park -- EXPERIMENTAL + * + * Park the nozzle at the given XYZ position on idle or G27. + * + * The "P" parameter controls the action applied to the Z axis: + * + * P0 (Default) If Z is below park Z raise the nozzle. + * P1 Raise the nozzle always to Z-park height. + * P2 Raise the nozzle by Z-park amount, limited to Z_MAX_POS. + */ +//#define NOZZLE_PARK_FEATURE + +#if ENABLED(NOZZLE_PARK_FEATURE) + // Specify a park position as { X, Y, Z } + #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 } +#endif + +/** + * Clean Nozzle Feature -- EXPERIMENTAL + * + * Adds the G12 command to perform a nozzle cleaning process. + * + * Parameters: + * P Pattern + * S Strokes / Repetitions + * T Triangles (P1 only) + * + * Patterns: + * P0 Straight line (default). This process requires a sponge type material + * at a fixed bed location. "S" specifies strokes (i.e. back-forth motions) + * between the start / end points. + * + * P1 Zig-zag pattern between (X0, Y0) and (X1, Y1), "T" specifies the + * number of zig-zag triangles to do. "S" defines the number of strokes. + * Zig-zags are done in whichever is the narrower dimension. + * For example, "G12 P1 S1 T3" will execute: + * + * -- + * | (X0, Y1) | /\ /\ /\ | (X1, Y1) + * | | / \ / \ / \ | + * A | | / \ / \ / \ | + * | | / \ / \ / \ | + * | (X0, Y0) | / \/ \/ \ | (X1, Y0) + * -- +--------------------------------+ + * |________|_________|_________| + * T1 T2 T3 + * + * P2 Circular pattern with middle at NOZZLE_CLEAN_CIRCLE_MIDDLE. + * "R" specifies the radius. "S" specifies the stroke count. + * Before starting, the nozzle moves to NOZZLE_CLEAN_START_POINT. + * + * Caveats: The ending Z should be the same as starting Z. + * Attention: EXPERIMENTAL. G-code arguments may change. + * + */ +//#define NOZZLE_CLEAN_FEATURE + +#if ENABLED(NOZZLE_CLEAN_FEATURE) + // Default number of pattern repetitions + #define NOZZLE_CLEAN_STROKES 12 + + // Default number of triangles + #define NOZZLE_CLEAN_TRIANGLES 3 + + // Specify positions as { X, Y, Z } + #define NOZZLE_CLEAN_START_POINT { 30, 30, (Z_MIN_POS + 1)} + #define NOZZLE_CLEAN_END_POINT {100, 60, (Z_MIN_POS + 1)} + + // Circular pattern radius + #define NOZZLE_CLEAN_CIRCLE_RADIUS 6.5 + // Circular pattern circle fragments number + #define NOZZLE_CLEAN_CIRCLE_FN 10 + // Middle point of circle + #define NOZZLE_CLEAN_CIRCLE_MIDDLE NOZZLE_CLEAN_START_POINT + + // Moves the nozzle to the initial position + #define NOZZLE_CLEAN_GOBACK +#endif + +/** + * Print Job Timer + * + * Automatically start and stop the print job timer on M104/M109/M190. + * + * M104 (hotend, no wait) - high temp = none, low temp = stop timer + * M109 (hotend, wait) - high temp = start timer, low temp = stop timer + * M190 (bed, wait) - high temp = start timer, low temp = none + * + * The timer can also be controlled with the following commands: + * + * M75 - Start the print job timer + * M76 - Pause the print job timer + * M77 - Stop the print job timer + */ +#define PRINTJOB_TIMER_AUTOSTART + +/** + * Print Counter + * + * Track statistical data such as: + * + * - Total print jobs + * - Total successful print jobs + * - Total failed print jobs + * - Total time printing + * + * View the current statistics with M78. + */ +//#define PRINTCOUNTER + +//============================================================================= +//============================= LCD and SD support ============================ +//============================================================================= + +// @section lcd + +/** + * LCD LANGUAGE + * + * Select the language to display on the LCD. These languages are available: + * + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, + * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * tr, uk, zh_CN, zh_TW, test + * + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + */ +#define LCD_LANGUAGE en + +/** + * LCD Character Set + * + * Note: This option is NOT applicable to Graphical Displays. + * + * All character-based LCDs provide ASCII plus one of these + * language extensions: + * + * - JAPANESE ... the most common + * - WESTERN ... with more accented characters + * - CYRILLIC ... for the Russian language + * + * To determine the language extension installed on your controller: + * + * - Compile and upload with LCD_LANGUAGE set to 'test' + * - 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 + * + * :['JAPANESE', 'WESTERN', 'CYRILLIC'] + */ +#define DISPLAY_CHARSET_HD44780 JAPANESE + +/** + * LCD TYPE + * + * Enable ULTRA_LCD for a 16x2, 16x4, 20x2, or 20x4 character-based LCD. + * Enable DOGLCD for a 128x64 (ST7565R) Full Graphical Display. + * (These options will be enabled automatically for most displays.) + * + * IMPORTANT: The U8glib library is required for Full Graphic Display! + * https://github.com/olikraus/U8glib_Arduino + */ +//#define ULTRA_LCD // Character based +//#define DOGLCD // Full graphics display + +/** + * SD CARD + * + * 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 + +/** + * SD CARD: SPI SPEED + * + * Enable one of the following items for a slower SPI transfer speed. + * This may be required to resolve "volume init" errors. + */ +//#define SPI_SPEED SPI_HALF_SPEED +//#define SPI_SPEED SPI_QUARTER_SPEED +//#define SPI_SPEED SPI_EIGHTH_SPEED + +/** + * SD CARD: ENABLE CRC + * + * Use CRC checks and retries on the SD communication. + */ +//#define SD_CHECK_AND_RETRY + +// +// ENCODER SETTINGS +// +// This option overrides the default number of encoder pulses needed to +// produce one step. Should be increased for high-resolution encoders. +// +//#define ENCODER_PULSES_PER_STEP 1 + +// +// Use this option to override the number of step signals required to +// move between next/prev menu items. +// +//#define ENCODER_STEPS_PER_MENU_ITEM 5 + +/** + * Encoder Direction Options + * + * Test your encoder's behavior first with both options disabled. + * + * Reversed Value Edit and Menu Nav? Enable REVERSE_ENCODER_DIRECTION. + * Reversed Menu Navigation only? Enable REVERSE_MENU_DIRECTION. + * Reversed Value Editing only? Enable BOTH options. + */ + +// +// This option reverses the encoder direction everywhere. +// +// Set this option if CLOCKWISE causes values to DECREASE +// +//#define REVERSE_ENCODER_DIRECTION + +// +// This option reverses the encoder direction for navigating LCD menus. +// +// If CLOCKWISE normally moves DOWN this makes it go UP. +// If CLOCKWISE normally moves UP this makes it go DOWN. +// +//#define REVERSE_MENU_DIRECTION + +// +// Individual Axis Homing +// +// Add individual axis homing items (Home X, Home Y, and Home Z) to the LCD menu. +// +//#define INDIVIDUAL_AXIS_HOMING_MENU + +// +// SPEAKER/BUZZER +// +// If you have a speaker that can produce tones, enable it here. +// By default Marlin assumes you have a buzzer with a fixed frequency. +// +//#define SPEAKER + +// +// The duration and frequency for the UI feedback sound. +// Set these to 0 to disable audio feedback in the LCD menus. +// +// Note: Test audio output with the G-Code: +// M300 S P +// +#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 +#define LCD_FEEDBACK_FREQUENCY_HZ 1000 + +// +// CONTROLLER TYPE: Standard +// +// Marlin supports a wide variety of controllers. +// Enable one of the following options to specify your controller. +// + +// +// ULTIMAKER Controller. +// +//#define ULTIMAKERCONTROLLER + +// +// ULTIPANEL as seen on Thingiverse. +// +//#define ULTIPANEL + +// +// PanelOne from T3P3 (via RAMPS 1.4 AUX2/AUX3) +// http://reprap.org/wiki/PanelOne +// +//#define PANEL_ONE + +// +// MaKr3d Makr-Panel with graphic controller and SD support. +// http://reprap.org/wiki/MaKr3d_MaKrPanel +// +//#define MAKRPANEL + +// +// ReprapWorld Graphical LCD +// https://reprapworld.com/?products_details&products_id/1218 +// +//#define REPRAPWORLD_GRAPHICAL_LCD + +// +// Activate one of these if you have a Panucatt Devices +// Viki 2.0 or mini Viki with Graphic LCD +// http://panucatt.com +// +//#define VIKI2 +//#define miniVIKI + +// +// Adafruit ST7565 Full Graphic Controller. +// https://github.com/eboston/Adafruit-ST7565-Full-Graphic-Controller/ +// +//#define ELB_FULL_GRAPHIC_CONTROLLER + +// +// RepRapDiscount Smart Controller. +// http://reprap.org/wiki/RepRapDiscount_Smart_Controller +// +// Note: Usually sold with a white PCB. +// +#define REPRAP_DISCOUNT_SMART_CONTROLLER + +// +// GADGETS3D G3D LCD/SD Controller +// http://reprap.org/wiki/RAMPS_1.3/1.4_GADGETS3D_Shield_with_Panel +// +// Note: Usually sold with a blue PCB. +// +//#define G3D_PANEL + +// +// RepRapDiscount FULL GRAPHIC Smart Controller +// http://reprap.org/wiki/RepRapDiscount_Full_Graphic_Smart_Controller +// +//#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER + +// +// MakerLab Mini Panel with graphic +// controller and SD support - http://reprap.org/wiki/Mini_panel +// +//#define MINIPANEL + +// +// RepRapWorld REPRAPWORLD_KEYPAD v1.1 +// http://reprapworld.com/?products_details&products_id=202&cPath=1591_1626 +// +// REPRAPWORLD_KEYPAD_MOVE_STEP sets how much should the robot move when a key +// is pressed, a value of 10.0 means 10mm per click. +// +//#define REPRAPWORLD_KEYPAD +//#define REPRAPWORLD_KEYPAD_MOVE_STEP 1.0 + +// +// RigidBot Panel V1.0 +// http://www.inventapart.com/ +// +//#define RIGIDBOT_PANEL + +// +// BQ LCD Smart Controller shipped by +// default with the BQ Hephestos 2 and Witbox 2. +// +//#define BQ_LCD_SMART_CONTROLLER + +// +// Cartesio UI +// http://mauk.cc/webshop/cartesio-shop/electronics/user-interface +// +//#define CARTESIO_UI + +// +// ANET_10 Controller supported displays. +// +//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. + // This LCD is known to be susceptible to electrical interference + // which scrambles the display. Pressing any button clears it up. +//#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 + // A clone of the RepRapDiscount full graphics display but with + // different pins/wiring (see pins_ANET_10.h). + +// +// LCD for Melzi Card with Graphical LCD +// +//#define LCD_FOR_MELZI + +// +// CONTROLLER TYPE: I2C +// +// Note: These controllers require the installation of Arduino's LiquidCrystal_I2C +// library. For more info: https://github.com/kiyoshigawa/LiquidCrystal_I2C +// + +// +// Elefu RA Board Control Panel +// http://www.elefu.com/index.php?route=product/product&product_id=53 +// +//#define RA_CONTROL_PANEL + +// +// Sainsmart YW Robot (LCM1602) LCD Display +// +// Note: This controller requires F.Malpartida's LiquidCrystal_I2C library +// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home +// +//#define LCD_I2C_SAINSMART_YWROBOT + +// +// Generic LCM1602 LCD adapter +// +//#define LCM1602 + +// +// PANELOLU2 LCD with status LEDs, +// separate encoder and click inputs. +// +// Note: This controller requires Arduino's LiquidTWI2 library v1.2.3 or later. +// For more info: https://github.com/lincomatic/LiquidTWI2 +// +// Note: The PANELOLU2 encoder click input can either be directly connected to +// a pin (if BTN_ENC defined to != -1) or read through I2C (when BTN_ENC == -1). +// +//#define LCD_I2C_PANELOLU2 + +// +// Panucatt VIKI LCD with status LEDs, +// integrated click & L/R/U/D buttons, separate encoder inputs. +// +//#define LCD_I2C_VIKI + +// +// SSD1306 OLED full graphics generic display +// +//#define U8GLIB_SSD1306 + +// +// SAV OLEd LCD module support using either SSD1306 or SH1106 based LCD modules +// +//#define SAV_3DGLCD +#if ENABLED(SAV_3DGLCD) + //#define U8GLIB_SSD1306 + #define U8GLIB_SH1106 +#endif + +// +// CONTROLLER TYPE: Shift register panels +// +// 2 wire Non-latching LCD SR from https://goo.gl/aJJ4sH +// LCD configuration: http://reprap.org/wiki/SAV_3D_LCD +// +//#define SAV_3DLCD + +// +// TinyBoy2 128x64 OLED / Encoder Panel +// +//#define OLED_PANEL_TINYBOY2 + +// +// Makeboard 3D Printer Parts 3D Printer Mini Display 1602 Mini Controller +// https://www.aliexpress.com/item/Micromake-Makeboard-3D-Printer-Parts-3D-Printer-Mini-Display-1602-Mini-Controller-Compatible-with-Ramps-1/32765887917.html +// +//#define MAKEBOARD_MINI_2_LINE_DISPLAY_1602 + +// +// MKS MINI12864 with graphic controller and SD support +// http://reprap.org/wiki/MKS_MINI_12864 +// +//#define MKS_MINI_12864 + +// +// Factory display for Creality CR-10 +// https://www.aliexpress.com/item/Universal-LCD-12864-3D-Printer-Display-Screen-With-Encoder-For-CR-10-CR-7-Model/32833148327.html +// +// This is RAMPS-compatible using a single 10-pin connector. +// (For CR-10 owners who want to replace the Melzi Creality board but retain the display) +// +//#define CR10_STOCKDISPLAY + +// +// MKS OLED 1.3" 128 × 64 FULL GRAPHICS CONTROLLER +// http://reprap.org/wiki/MKS_12864OLED +// +// Tiny, but very sharp OLED display +// +//#define MKS_12864OLED + +//============================================================================= +//=============================== Extra Features ============================== +//============================================================================= + +// @section extras + +// Increase the FAN PWM frequency. Removes the PWM noise but increases heating in the FET/Arduino +//#define FAST_PWM_FAN + +// Use software PWM to drive the fan, as for the heaters. This uses a very low frequency +// which is not as annoying as with the hardware PWM. On the other hand, if this frequency +// is too low, you should also increment SOFT_PWM_SCALE. +//#define FAN_SOFT_PWM + +// Incrementing this by 1 will double the software PWM frequency, +// affecting heaters, and the fan if FAN_SOFT_PWM is enabled. +// However, control resolution will be halved for each increment; +// at zero value, there are 128 effective control positions. +#define SOFT_PWM_SCALE 0 + +// If SOFT_PWM_SCALE is set to a value higher than 0, dithering can +// be used to mitigate the associated resolution loss. If enabled, +// some of the PWM cycles are stretched so on average the desired +// duty cycle is attained. +//#define SOFT_PWM_DITHER + +// Temperature status LEDs that display the hotend and bed temperature. +// If all hotends, bed temperature, and target temperature are under 54C +// then the BLUE led is on. Otherwise the RED led is on. (1C hysteresis) +//#define TEMP_STAT_LEDS + +// M240 Triggers a camera by emulating a Canon RC-1 Remote +// Data from: http://www.doc-diy.net/photo/rc-1_hacked/ +//#define PHOTOGRAPH_PIN 23 + +// 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 + +// Support for BlinkM/CyzRgb +//#define BLINKM + +// Support for PCA9632 PWM LED driver +//#define PCA9632 + +/** + * RGB LED / LED Strip Control + * + * Enable support for an RGB LED connected to 5V digital pins, or + * an RGB Strip connected to MOSFETs controlled by digital pins. + * + * 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 overall brightness parameters is also available + * + * *** CAUTION *** + * LED Strips require a MOFSET 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! + * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino + * cannot handle such current, separate 5V power supply must be used + * *** CAUTION *** + * + * LED type. This options are mutualy exclusive. Uncomment only one. + * + */ +//#define RGB_LED +//#define RGBW_LED + +#if ENABLED(RGB_LED) || ENABLED(RGBW_LED) + #define RGB_LED_R_PIN 34 + #define RGB_LED_G_PIN 43 + #define RGB_LED_B_PIN 35 + #define RGB_LED_W_PIN -1 +#endif + +// 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 (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) + #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip + #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time + #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + //#define NEOPIXEL_STARTUP_TEST // Cycle through colors at startup +#endif + +/** + * Printer Event LEDs + * + * During printing, the LEDs will reflect the printer status: + * + * - Gradually change from blue to violet as the heated bed gets to target temp + * - Gradually change from violet to red as the hotend gets to temperature + * - Change to white to illuminate work surface + * - Change to green once print has finished + * - Turn off after the print has finished and the user has pushed a button + */ +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) + #define PRINTER_EVENT_LEDS +#endif + +/*********************************************************************\ +* R/C SERVO support +* Sponsored by TrinityLabs, Reworked by codexmas +**********************************************************************/ + +// Number of servos +// +// If you select a configuration below, this will receive a default value and does not need to be set manually +// set it manually if you have more servos than extruders and wish to manually control some +// leaving it undefined or defining as 0 will disable the servo subsystem +// If unsure, leave commented / disabled +// +#define NUM_SERVOS 1 // Servo index starts with 0 for M280 command + +// Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. +// 300ms is a good value but you can try less delay. +// If the servo can't reach the requested position, increase it. +#define SERVO_DELAY { 300 } + +// Servo deactivation +// +// With this option servos are powered only during movement, then turned off to prevent jitter. +//#define DEACTIVATE_SERVOS_AFTER_MOVE + +/** + * Filament Width Sensor + * + * Measures the filament width in real-time and adjusts + * flow rate to compensate for any irregularities. + * + * Also allows the measured filament diameter to set the + * extrusion rate, so the slicer only has to specify the + * volume. + * + * Only a single extruder is supported at this time. + * + * 34 RAMPS_14 : Analog input 5 on the AUX2 connector + * 81 PRINTRBOARD : Analog input 2 on the Exp1 connector (version B,C,D,E) + * 301 RAMBO : Analog input 3 + * + * Note: May require analog pins to be defined for other boards. + */ +//#define FILAMENT_WIDTH_SENSOR + +#define DEFAULT_NOMINAL_FILAMENT_DIA 1.75 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. + +#if ENABLED(FILAMENT_WIDTH_SENSOR) + #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) + #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber + + #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading + #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading + #define MAX_MEASUREMENT_DELAY 20 // (bytes) Buffer size for stored measurements (1 byte per cm). Must be larger than MEASUREMENT_DELAY_CM. + + #define DEFAULT_MEASURED_FILAMENT_DIA DEFAULT_NOMINAL_FILAMENT_DIA // Set measured to nominal initially + + // Display filament width on the LCD status line. Status messages will expire after 5 seconds. + //#define FILAMENT_LCD_DISPLAY +#endif + +#endif // CONFIGURATION_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/Infitary/i3-M508/Configuration.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/Infitary/i3-M508/Configuration.h new file mode 100644 index 00000000..284b875d --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/Infitary/i3-M508/Configuration.h @@ -0,0 +1,1704 @@ +/** + * 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 . + * + */ + +/** + * Configuration.h + * + * Basic settings such as: + * + * - Type of electronics + * - Type of temperature sensor + * - Printer geometry + * - Endstop configuration + * - LCD controller + * - Extra features + * + * Advanced settings can be found in Configuration_adv.h + * + */ +#ifndef CONFIGURATION_H +#define CONFIGURATION_H +#define CONFIGURATION_H_VERSION 010100 + +//=========================================================================== +//============================= Getting Started ============================= +//=========================================================================== + +/** + * Here are some standard links for getting your machine calibrated: + * + * http://reprap.org/wiki/Calibration + * http://youtu.be/wAL9d7FgInk + * http://calculator.josefprusa.cz + * http://reprap.org/wiki/Triffid_Hunter%27s_Calibration_Guide + * http://www.thingiverse.com/thing:5573 + * https://sites.google.com/site/repraplogphase/calibration-of-your-reprap + * http://www.thingiverse.com/thing:298812 + */ + +//=========================================================================== +//============================= DELTA Printer =============================== +//=========================================================================== +// For a Delta printer start with one of the configuration files in the +// example_configurations/delta directory and customize for your machine. +// + +//=========================================================================== +//============================= SCARA Printer =============================== +//=========================================================================== +// For a SCARA printer start with the configuration files in +// example_configurations/SCARA and customize for your machine. +// + +// @section info + +// User-specified version info of this build to display in [Pronterface, etc] terminal window during +// startup. Implementation of an idea by Prof Braino to inform user that any changes made to this +// build by the user have been successfully uploaded into firmware. +#define STRING_CONFIG_H_AUTHOR "(tjclement, Infitary M508)" // Who made the changes. +#define SHOW_BOOTSCREEN +#define STRING_SPLASH_LINE1 SHORT_BUILD_VERSION // will be shown during bootup in line 1 +#define STRING_SPLASH_LINE2 WEBSITE_URL // will be shown during bootup in line 2 + +// +// *** VENDORS PLEASE READ ***************************************************** +// +// Marlin now allow you to have a vendor boot image to be displayed on machine +// start. When SHOW_CUSTOM_BOOTSCREEN is defined Marlin will first show your +// custom boot image and then the default Marlin boot image is shown. +// +// We suggest for you to take advantage of this new feature and keep the Marlin +// boot image unmodified. For an example have a look at the bq Hephestos 2 +// example configuration folder. +// +//#define SHOW_CUSTOM_BOOTSCREEN +// @section machine + +/** + * Select which serial port on the board will be used for communication with the host. + * This allows the connection of wireless adapters (for instance) to non-default port pins. + * Serial port 0 is always used by the Arduino bootloader regardless of this setting. + * + * :[0, 1, 2, 3, 4, 5, 6, 7] + */ +#define SERIAL_PORT 0 + +/** + * This setting determines the communication speed of the printer. + * + * 250000 works in most cases, but you might try a lower speed if + * you commonly experience drop-outs during host printing. + * You may try up to 1000000 to speed up SD file transfer. + * + * :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000] + */ +#define BAUDRATE 250000 + +// Enable the Bluetooth serial interface on AT90USB devices +//#define BLUETOOTH + +// The following define selects which electronics board you have. +// Please choose the name from boards.h that matches your setup +#ifndef MOTHERBOARD + #define MOTHERBOARD BOARD_RAMPS_13_EFB +#endif + +// Optional custom name for your RepStrap or other custom machine +// Displayed in the LCD "Ready" message +#define CUSTOM_MACHINE_NAME "Infitary M508" + +// Define this to set a unique identifier for this printer, (Used by some programs to differentiate between machines) +// You can use an online service to generate a random UUID. (eg http://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] +#define EXTRUDERS 1 + +// For Cyclops or any "multi-extruder" that shares a single nozzle. +//#define SINGLENOZZLE + +/** + * Průša MK2 Single Nozzle Multi-Material Multiplexer, and variants. + * + * This device allows one stepper driver on a control board to drive + * two to eight stepper motors, one at a time, in a manner suitable + * for extruders. + * + * This option only allows the multiplexer to switch on tool-change. + * Additional options to configure custom E moves are pending. + */ +//#define MK2_MULTIPLEXER +#if ENABLED(MK2_MULTIPLEXER) + // Override the default DIO selector pins here, if needed. + // Some pins files may provide defaults for these pins. + //#define E_MUX0_PIN 40 // Always Required + //#define E_MUX1_PIN 42 // Needed for 3 to 8 steppers + //#define E_MUX2_PIN 44 // Needed for 5 to 8 steppers +#endif + +// A dual extruder that uses a single stepper motor +//#define SWITCHING_EXTRUDER +#if ENABLED(SWITCHING_EXTRUDER) + #define SWITCHING_EXTRUDER_SERVO_NR 0 + #define SWITCHING_EXTRUDER_SERVO_ANGLES { 0, 90 } // Angles for E0, E1[, E2, E3] + #if EXTRUDERS > 3 + #define SWITCHING_EXTRUDER_E23_SERVO_NR 1 + #endif +#endif + +// A dual-nozzle that uses a servomotor to raise/lower one of the nozzles +//#define SWITCHING_NOZZLE +#if ENABLED(SWITCHING_NOZZLE) + #define SWITCHING_NOZZLE_SERVO_NR 0 + #define SWITCHING_NOZZLE_SERVO_ANGLES { 0, 90 } // Angles for E0, E1 + //#define HOTEND_OFFSET_Z { 0.0, 0.0 } +#endif + +/** + * Two separate X-carriages with extruders that connect to a moving part + * via a magnetic docking mechanism. Requires SOL1_PIN and SOL2_PIN. + */ +//#define PARKING_EXTRUDER +#if ENABLED(PARKING_EXTRUDER) + #define PARKING_EXTRUDER_SOLENOIDS_INVERT // If enabled, the solenoid is NOT magnetized with applied voltage + #define PARKING_EXTRUDER_SOLENOIDS_PINS_ACTIVE LOW // LOW or HIGH pin signal energizes the coil + #define PARKING_EXTRUDER_SOLENOIDS_DELAY 250 // Delay (ms) for magnetic field. No delay if 0 or not defined. + #define PARKING_EXTRUDER_PARKING_X { -78, 184 } // X positions for parking the extruders + #define PARKING_EXTRUDER_GRAB_DISTANCE 1 // mm to move beyond the parking point to grab the extruder + #define PARKING_EXTRUDER_SECURITY_RAISE 5 // Z-raise before parking + #define HOTEND_OFFSET_Z { 0.0, 1.3 } // Z-offsets of the two hotends. The first must be 0. +#endif + +/** + * "Mixing Extruder" + * - Adds a new code, M165, to set the current mix factors. + * - Extends the stepping routines to move multiple steppers in proportion to the mix. + * - Optional support for Repetier Firmware M163, M164, and virtual extruder. + * - This implementation supports only a single extruder. + * - Enable DIRECT_MIXING_IN_G1 for Pia Taubert's reference implementation + */ +//#define MIXING_EXTRUDER +#if ENABLED(MIXING_EXTRUDER) + #define MIXING_STEPPERS 2 // Number of steppers in your mixing extruder + #define MIXING_VIRTUAL_TOOLS 16 // Use the Virtual Tool method with M163 and M164 + //#define DIRECT_MIXING_IN_G1 // Allow ABCDHI mix factors in G1 movement commands +#endif + +// Offset of the extruders (uncomment if using more than one and relying on firmware to position when changing). +// The offset has to be X=0, Y=0 for the extruder 0 hotend (default extruder). +// For the other hotends it is their distance from the extruder 0 hotend. +//#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis +//#define HOTEND_OFFSET_Y {0.0, 5.00} // (in mm) for each extruder, offset of the hotend on the Y axis + +// @section machine + +/** + * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN + * + * 0 = No Power Switch + * 1 = ATX + * 2 = X-Box 360 203Watts (the blue wire connected to PS_ON and the red wire to VCC) + * + * :{ 0:'No power switch', 1:'ATX', 2:'X-Box 360' } + */ +#define POWER_SUPPLY 0 + +#if POWER_SUPPLY > 0 + // Enable this option to leave the PSU off at startup. + // Power to steppers and heaters will need to be turned on with M80. + //#define PS_DEFAULT_OFF +#endif + +// @section temperature + +//=========================================================================== +//============================= Thermal Settings ============================ +//=========================================================================== + +/** + * --NORMAL IS 4.7kohm PULLUP!-- 1kohm pullup can be used on hotend sensor, using correct resistor and table + * + * Temperature sensors available: + * + * -3 : thermocouple with MAX31855 (only for sensor 0) + * -2 : thermocouple with MAX6675 (only for sensor 0) + * -1 : thermocouple with AD595 + * 0 : not used + * 1 : 100k thermistor - best choice for EPCOS 100k (4.7k pullup) + * 2 : 200k thermistor - ATC Semitec 204GT-2 (4.7k pullup) + * 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 (Used in ParCan & J-Head) (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) + * 71 : 100k Honeywell thermistor 135-104LAF-J01 (4.7k pullup) + * 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) + * 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" + * 20 : the PT100 circuit found in the Ultimainboard V2.x + * 60 : 100k Maker's Tool Works Kapton Bed Thermistor beta=3950 + * 66 : 4.7M High Temperature thermistor from Dyze Design + * 70 : the 100K thermistor found in the bq Hephestos 2 + * 75 : 100k Generic Silicon Heat Pad with NTC 100K MGB18-104F39050L32 thermistor + * + * 1k ohm pullup tables - This is atypical, and requires changing out the 4.7k pullup for 1k. + * (but gives greater accuracy and more stable PID) + * 51 : 100k thermistor - EPCOS (1k pullup) + * 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 + * 1010 : Pt1000 with 1k pullup (non standard) + * 147 : Pt100 with 4k7 pullup + * 110 : Pt100 with 1k pullup (non standard) + * + * Use these for Testing or Development purposes. NEVER for production machine. + * 998 : Dummy Table that ALWAYS reads 25°C or the temperature defined below. + * 999 : Dummy Table that ALWAYS reads 100°C or the temperature defined below. + * + * :{ '0': "Not used", '1':"100k / 4.7k - EPCOS", '2':"200k / 4.7k - ATC Semitec 204GT-2", '3':"Mendel-parts / 4.7k", '4':"10k !! do not use for a hotend. Bad resolution at high temp. !!", '5':"100K / 4.7k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '6':"100k / 4.7k EPCOS - Not as accurate as Table 1", '7':"100k / 4.7k Honeywell 135-104LAG-J01", '8':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT", '9':"100k / 4.7k GE Sensing AL03006-58.2K-97-G1", '10':"100k / 4.7k RS 198-961", '11':"100k / 4.7k beta 3950 1%", '12':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT (calibrated for Makibox hot bed)", '13':"100k Hisens 3950 1% up to 300°C for hotend 'Simple ONE ' & hotend 'All In ONE'", '20':"PT100 (Ultimainboard V2.x)", '51':"100k / 1k - EPCOS", '52':"200k / 1k - ATC Semitec 204GT-2", '55':"100k / 1k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '60':"100k Maker's Tool Works Kapton Bed Thermistor beta=3950", '66':"Dyze Design 4.7M High Temperature thermistor", '70':"the 100K thermistor found in the bq Hephestos 2", '71':"100k / 4.7k Honeywell 135-104LAF-J01", '147':"Pt100 / 4.7k", '1047':"Pt1000 / 4.7k", '110':"Pt100 / 1k (non-standard)", '1010':"Pt1000 / 1k (non standard)", '-3':"Thermocouple + MAX31855 (only for sensor 0)", '-2':"Thermocouple + MAX6675 (only for sensor 0)", '-1':"Thermocouple + AD595",'998':"Dummy 1", '999':"Dummy 2" } + */ +#define TEMP_SENSOR_0 1 +#define TEMP_SENSOR_1 0 +#define TEMP_SENSOR_2 0 +#define TEMP_SENSOR_3 0 +#define TEMP_SENSOR_4 0 +#define TEMP_SENSOR_BED 1 + +// Dummy thermistor constant temperature readings, for use with 998 and 999 +#define DUMMY_THERMISTOR_998_VALUE 25 +#define DUMMY_THERMISTOR_999_VALUE 100 + +// 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 +#define MAX_REDUNDANT_TEMP_SENSOR_DIFF 10 + +// Extruder temperature must be close to target for this long before M109 returns success +#define TEMP_RESIDENCY_TIME 10 // (seconds) +#define TEMP_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// Bed temperature must be close to target for this long before M190 returns success +#define TEMP_BED_RESIDENCY_TIME 10 // (seconds) +#define TEMP_BED_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_BED_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// The minimal temperature defines the temperature below which the heater will not be enabled It is used +// to check that the wiring to the thermistor is not broken. +// Otherwise this would lead to the heater being powered on all the time. +#define HEATER_0_MINTEMP 5 +#define HEATER_1_MINTEMP 5 +#define HEATER_2_MINTEMP 5 +#define HEATER_3_MINTEMP 5 +#define HEATER_4_MINTEMP 5 +#define BED_MINTEMP 5 + +// When temperature exceeds max temp, your heater will be switched off. +// This feature exists to protect your hotend from overheating accidentally, but *NOT* from thermistor short/failure! +// You should use MINTEMP for thermistor short/failure protection. +#define HEATER_0_MAXTEMP 275 +#define HEATER_1_MAXTEMP 275 +#define HEATER_2_MAXTEMP 275 +#define HEATER_3_MAXTEMP 275 +#define HEATER_4_MAXTEMP 275 +#define BED_MAXTEMP 125 + +//=========================================================================== +//============================= PID Settings ================================ +//=========================================================================== +// PID Tuning Guide here: http://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 +#if ENABLED(PIDTEMP) + //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. + //#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. + #define K1 0.95 //smoothing factor within the PID + + // 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 + + #define DEFAULT_Kp 213.2 + #define DEFAULT_Ki 1.54 + #define DEFAULT_Kd 765 + +#endif // PIDTEMP + +//=========================================================================== +//============================= PID > Bed Temperature Control =============== +//=========================================================================== +// Select PID or bang-bang with PIDTEMPBED. If bang-bang, BED_LIMIT_SWITCHING will enable hysteresis +// +// Uncomment this to enable PID on the bed. It uses the same frequency PWM as the extruder. +// If your PID_dT is the default, and correct for your hardware/configuration, that means 7.689Hz, +// which is fine for driving a square wave into a resistive load and does not significantly impact you FET heating. +// This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W heater. +// If your configuration is significantly different than this and you don't understand the issues involved, you probably +// shouldn't use bed PID until someone else verifies your hardware works. +// If this is enabled, find your own PID constants below. +//#define PIDTEMPBED + +//#define BED_LIMIT_SWITCHING + +// This sets the max power delivered to the bed, and replaces the HEATER_BED_DUTY_CYCLE_DIVIDER option. +// all forms of bed control obey this (PID, bang-bang, bang-bang with hysteresis) +// setting this to anything other than 255 enables a form of PWM to the bed just like HEATER_BED_DUTY_CYCLE_DIVIDER did, +// so you shouldn't use it unless you are OK with PWM on your bed. (see the comment on enabling PIDTEMPBED) +#define MAX_BED_POWER 255 // limits duty cycle to bed; 255=full current + +#if ENABLED(PIDTEMPBED) + + //#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) + #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 + +// @section extruder + +// This option prevents extrusion if the temperature is below EXTRUDE_MINTEMP. +// It also enables the M302 command to set the minimum extrusion temperature +// or to allow moving the extruder regardless of the hotend temperature. +// *** IT IS HIGHLY RECOMMENDED TO LEAVE THIS OPTION ENABLED! *** +#define PREVENT_COLD_EXTRUSION +#define EXTRUDE_MINTEMP 170 + +// This option prevents a single extrusion longer than EXTRUDE_MAXLENGTH. +// Note that for Bowden Extruders a too-small value here may prevent loading. +#define PREVENT_LENGTHY_EXTRUDE +#define EXTRUDE_MAXLENGTH 200 + +//=========================================================================== +//======================== Thermal Runaway Protection ======================= +//=========================================================================== + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * If you get "Thermal Runaway" or "Heating failed" errors the + * details can be tuned in Configuration_adv.h + */ + +#define THERMAL_PROTECTION_HOTENDS // Enable thermal protection for all extruders +#define THERMAL_PROTECTION_BED // Enable thermal protection for the heated bed + +//=========================================================================== +//============================= Mechanical Settings ========================= +//=========================================================================== + +// @section machine + +// Uncomment one of these options to enable CoreXY, CoreXZ, or CoreYZ kinematics +// either in the usual order or reversed +//#define COREXY +//#define COREXZ +//#define COREYZ +//#define COREYX +//#define COREZX +//#define COREZY + +//=========================================================================== +//============================== Endstop Settings =========================== +//=========================================================================== + +// @section homing + +// Specify here all the endstop connectors that are connected to any endstop or probe. +// Almost all printers will be using one per axis. Probes will use one or more of the +// extra connectors. Leave undefined any used for non-endstop and non-probe purposes. +#define USE_XMIN_PLUG +#define USE_YMIN_PLUG +#define USE_ZMIN_PLUG +//#define USE_XMAX_PLUG +//#define USE_YMAX_PLUG +//#define USE_ZMAX_PLUG + +// coarse Endstop Settings +#define ENDSTOPPULLUPS // Comment this out (using // at the start of the line) to disable the endstop pullup resistors + +#if DISABLED(ENDSTOPPULLUPS) + // fine endstop settings: Individual pullups. will be ignored if ENDSTOPPULLUPS is defined + //#define ENDSTOPPULLUP_XMAX + //#define ENDSTOPPULLUP_YMAX + //#define ENDSTOPPULLUP_ZMAX + //#define ENDSTOPPULLUP_XMIN + //#define ENDSTOPPULLUP_YMIN + //#define ENDSTOPPULLUP_ZMIN + //#define ENDSTOPPULLUP_ZMIN_PROBE +#endif + +// Mechanical endstop with COM to ground and NC to Signal uses "false" here (most common setup). +#define X_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Y_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define X_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Y_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MIN_PROBE_ENDSTOP_INVERTING true // set to true to invert the logic of the probe. + +// Enable this feature if all enabled endstop pins are interrupt-capable. +// This will remove the need to poll the interrupt pins, saving many CPU cycles. +//#define ENDSTOP_INTERRUPTS_FEATURE + +//============================================================================= +//============================== Movement Settings ============================ +//============================================================================= +// @section motion + +/** + * Default Settings + * + * These settings can be reset by M502 + * + * Note that if EEPROM is enabled, saved values will override these. + */ + +/** + * With this option each E stepper can have its own factors for the + * following movement settings. If fewer factors are given than the + * total number of extruders, the last value applies to the rest. + */ +//#define DISTINCT_E_FACTORS + +/** + * Default Axis Steps Per Unit (steps/mm) + * Override with M92 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_AXIS_STEPS_PER_UNIT { 100, 100, 400, 92.6 } + +/** + * Default Max Feed Rate (mm/s) + * Override with M203 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_FEEDRATE { 400, 400, 5, 25 } + +/** + * Default Max Acceleration (change/s) change = mm/s + * (Maximum start speed for accelerated moves) + * Override with M201 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_ACCELERATION { 9000, 9000, 100, 10000 } + +/** + * Default Acceleration (change/s) change = mm/s + * Override with M204 + * + * M204 P Acceleration + * M204 R Retract Acceleration + * M204 T Travel Acceleration + */ +#define DEFAULT_ACCELERATION 3000 // X, Y, Z and E acceleration for printing moves +#define DEFAULT_RETRACT_ACCELERATION 3000 // E acceleration for retracts +#define DEFAULT_TRAVEL_ACCELERATION 3000 // X, Y, Z acceleration for travel (non printing) moves + +/** + * Default Jerk (mm/s) + * Override with M205 X Y Z E + * + * "Jerk" specifies the minimum speed change that requires acceleration. + * When changing speed and direction, if the difference is less than the + * value set here, it may happen instantaneously. + */ +#define DEFAULT_XJERK 20.0 +#define DEFAULT_YJERK 20.0 +#define DEFAULT_ZJERK 0.4 +#define DEFAULT_EJERK 5.0 + +//=========================================================================== +//============================= Z Probe Options ============================= +//=========================================================================== +// @section probes + +// +// See http://marlinfw.org/configuration/probes.html +// + +/** + * Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + * + * Enable this option for a probe connected to the Z Min endstop pin. + */ +#define Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + +/** + * Z_MIN_PROBE_ENDSTOP + * + * Enable this option for a probe connected to any pin except Z-Min. + * (By default Marlin assumes the Z-Max endstop pin.) + * To use a custom Z Probe pin, set Z_MIN_PROBE_PIN below. + * + * - The simplest option is to use a free endstop connector. + * - Use 5V for powered (usually inductive) sensors. + * + * - RAMPS 1.3/1.4 boards may use the 5V, GND, and Aux4->D32 pin: + * - For simple switches connect... + * - normally-closed switches to GND and D32. + * - normally-open switches to 5V and D32. + * + * WARNING: Setting the wrong pin may have unexpected and potentially + * disastrous consequences. Use with caution and do your homework. + * + */ +//#define Z_MIN_PROBE_ENDSTOP + +/** + * Probe Type + * + * Allen Key Probes, Servo Probes, Z-Sled Probes, FIX_MOUNTED_PROBE, etc. + * Activate one of these to use Auto Bed Leveling below. + */ + +/** + * The "Manual Probe" provides a means to do "Auto" Bed Leveling without a probe. + * Use G29 repeatedly, adjusting the Z height at each point with movement commands + * or (with LCD_BED_LEVELING) the LCD controller. + */ +//#define PROBE_MANUALLY + +/** + * A Fix-Mounted Probe either doesn't deploy or needs manual deployment. + * (e.g., an inductive probe or a nozzle-based probe-switch.) + */ +//#define FIX_MOUNTED_PROBE + +/** + * Z Servo Probe, such as an endstop switch on a rotating arm. + */ +//#define Z_ENDSTOP_SERVO_NR 0 // Defaults to SERVO 0 connector. +//#define Z_SERVO_ANGLES {70,0} // Z Servo Deploy and Stow angles + +/** + * The BLTouch probe uses a Hall effect sensor and emulates a servo. + */ +//#define BLTOUCH +#if ENABLED(BLTOUCH) + //#define BLTOUCH_DELAY 375 // (ms) Enable and increase if needed +#endif + +/** + * Enable one or more of the following if probing seems unreliable. + * Heaters and/or fans can be disabled during probing to minimize electrical + * noise. A delay can also be added to allow noise and vibration to settle. + * These options are most useful for the BLTouch probe, but may also improve + * readings with inductive probes and piezo sensors. + */ +//#define PROBING_HEATERS_OFF // Turn heaters off when probing +//#define PROBING_FANS_OFF // Turn fans off when probing +//#define DELAY_BEFORE_PROBING 200 // (ms) To prevent vibrations from triggering piezo sensors + +// A probe that is deployed and stowed with a solenoid pin (SOL1_PIN) +//#define SOLENOID_PROBE + +// A sled-mounted probe like those designed by Charles Bell. +//#define Z_PROBE_SLED +//#define SLED_DOCKING_OFFSET 5 // The extra distance the X axis must travel to pickup the sled. 0 should be fine but you can push it further if you'd like. + +// +// For Z_PROBE_ALLEN_KEY see the Delta example configurations. +// + +/** + * Z Probe to nozzle (X,Y) offset, relative to (0, 0). + * X and Y offsets must be integers. + * + * In the following example the X and Y offsets are both positive: + * #define X_PROBE_OFFSET_FROM_EXTRUDER 10 + * #define Y_PROBE_OFFSET_FROM_EXTRUDER 10 + * + * +-- BACK ---+ + * | | + * L | (+) P | R <-- probe (20,20) + * E | | I + * F | (-) N (+) | G <-- nozzle (10,10) + * T | | H + * | (-) | T + * | | + * O-- FRONT --+ + * (0,0) + */ +#define X_PROBE_OFFSET_FROM_EXTRUDER 10 // X offset: -left +right [of the nozzle] +#define Y_PROBE_OFFSET_FROM_EXTRUDER 10 // Y offset: -front +behind [the nozzle] +#define Z_PROBE_OFFSET_FROM_EXTRUDER 0 // Z offset: -below +above [the nozzle] + +// X and Y axis travel speed (mm/m) between probes +#define XY_PROBE_SPEED 8000 + +// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +#define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z + +// Speed for the "accurate" probe of each point +#define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) + +// Use double touch for probing +//#define PROBE_DOUBLE_TOUCH + +/** + * Z probes require clearance when deploying, stowing, and moving between + * probe points to avoid hitting the bed and other hardware. + * Servo-mounted probes require extra space for the arm to rotate. + * Inductive probes need space to keep from triggering early. + * + * Use these settings to specify the distance (mm) to raise the probe (or + * lower the bed). The values set here apply over and above any (negative) + * probe Z Offset set with Z_PROBE_OFFSET_FROM_EXTRUDER, M851, or the LCD. + * Only integer values >= 1 are valid here. + * + * Example: `M851 Z-5` with a CLEARANCE of 4 => 9mm from bed to nozzle. + * But: `M851 Z+1` with a CLEARANCE of 2 => 2mm from bed to nozzle. + */ +#define Z_CLEARANCE_DEPLOY_PROBE 10 // Z Clearance for Deploy/Stow +#define Z_CLEARANCE_BETWEEN_PROBES 5 // Z Clearance between probe points + +// For M851 give a range for adjusting the Z probe offset +#define Z_PROBE_OFFSET_RANGE_MIN -20 +#define Z_PROBE_OFFSET_RANGE_MAX 20 + +// Enable the M48 repeatability test to test probe accuracy +//#define Z_MIN_PROBE_REPEATABILITY_TEST + +// For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1 +// :{ 0:'Low', 1:'High' } +#define X_ENABLE_ON 0 +#define Y_ENABLE_ON 0 +#define Z_ENABLE_ON 0 +#define E_ENABLE_ON 0 // For all extruders + +// Disables axis stepper immediately when it's not being used. +// 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 +//#define DISABLE_REDUCED_ACCURACY_WARNING + +// @section extruder + +#define DISABLE_E false // For all extruders +#define DISABLE_INACTIVE_EXTRUDER true // Keep only the active extruder enabled. + +// @section machine + +// Invert the stepper direction. Change (or reverse the motor connector) if an axis goes the wrong way. +#define INVERT_X_DIR true +#define INVERT_Y_DIR true +#define INVERT_Z_DIR false + +// Enable this option for Toshiba stepper drivers +//#define CONFIG_STEPPERS_TOSHIBA + +// @section extruder + +// For direct drive extruder v9 set to true, for geared extruder set to false. +#define INVERT_E0_DIR true +#define INVERT_E1_DIR false +#define INVERT_E2_DIR false +#define INVERT_E3_DIR false +#define INVERT_E4_DIR false + +// @section homing + +//#define NO_MOTION_BEFORE_HOMING // Inhibit movement until all axes have been homed + +//#define Z_HOMING_HEIGHT 4 // (in mm) Minimal z height before homing (G28) for Z clearance above the bed, clamps, ... + // Be sure you have this distance over your Z_MAX_POS in case. + +// Direction of endstops when homing; 1=MAX, -1=MIN +// :[-1,1] +#define X_HOME_DIR -1 +#define Y_HOME_DIR -1 +#define Z_HOME_DIR -1 + +// @section machine + +// The size of the print bed +#define X_BED_SIZE 205 +#define Y_BED_SIZE 205 + +// Travel limits (mm) after homing, corresponding to endstop positions. +#define X_MIN_POS 0 +#define Y_MIN_POS 0 +#define Z_MIN_POS 0 +#define X_MAX_POS X_BED_SIZE +#define Y_MAX_POS Y_BED_SIZE +#define Z_MAX_POS 185 + +// If enabled, axes won't move below MIN_POS in response to movement commands. +#define MIN_SOFTWARE_ENDSTOPS +// If enabled, axes won't move above MAX_POS in response to movement commands. +#define MAX_SOFTWARE_ENDSTOPS + +/** + * Filament Runout Sensor + * A mechanical or opto endstop is used to check for the presence of filament. + * + * RAMPS-based boards use SERVO3_PIN. + * For other boards you may need to define FIL_RUNOUT_PIN. + * By default the firmware assumes HIGH = has filament, LOW = ran out + */ +//#define FILAMENT_RUNOUT_SENSOR +#if ENABLED(FILAMENT_RUNOUT_SENSOR) + #define FIL_RUNOUT_INVERTING false // set to true to invert the logic of the sensor. + #define ENDSTOPPULLUP_FIL_RUNOUT // Uncomment to use internal pullup for filament runout pins if the sensor is defined. + #define FILAMENT_RUNOUT_SCRIPT "M600" +#endif + +//=========================================================================== +//=============================== Bed Leveling ============================== +//=========================================================================== +// @section bedlevel + +/** + * Choose one of the options below to enable G29 Bed Leveling. The parameters + * and behavior of G29 will change depending on your selection. + * + * If using a Probe for Z Homing, enable Z_SAFE_HOMING also! + * + * - AUTO_BED_LEVELING_3POINT + * Probe 3 arbitrary points on the bed (that aren't collinear) + * You specify the XY coordinates of all 3 points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_LINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_BILINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a mesh, best for large or uneven beds. + * + * - AUTO_BED_LEVELING_UBL (Unified Bed Leveling) + * A comprehensive bed leveling system combining the features and benefits + * of other systems. UBL also includes integrated Mesh Generation, Mesh + * Validation and Mesh Editing systems. Currently, UBL is only checked out + * for Cartesian Printers. That said, it was primarily designed to correct + * poor quality Delta Printers. If you feel adventurous and have a Delta, + * please post an issue if something doesn't work correctly. Initially, + * you will need to set a reduced bed size so you have a rectangular area + * to test on. + * + * - MESH_BED_LEVELING + * Probe a grid manually + * The result is a mesh, suitable for large or uneven beds. (See BILINEAR.) + * For machines without a probe, Mesh Bed Leveling provides a method to perform + * leveling in steps so you can manually adjust the Z height at each grid-point. + * With an LCD controller the process is guided step-by-step. + */ +//#define AUTO_BED_LEVELING_3POINT +//#define AUTO_BED_LEVELING_LINEAR +//#define AUTO_BED_LEVELING_BILINEAR +//#define AUTO_BED_LEVELING_UBL +//#define MESH_BED_LEVELING + +/** + * Enable detailed logging of G28, G29, M48, etc. + * Turn on with the command 'M111 S32'. + * NOTE: Requires a lot of PROGMEM! + */ +//#define DEBUG_LEVELING_FEATURE + +#if ENABLED(MESH_BED_LEVELING) || ENABLED(AUTO_BED_LEVELING_BILINEAR) || ENABLED(AUTO_BED_LEVELING_UBL) + // Gradually reduce leveling correction until a set height is reached, + // at which point movement will be level to the machine's XY plane. + // The height can be set with M420 Z + #define ENABLE_LEVELING_FADE_HEIGHT +#endif + +#if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Set the number of grid points per dimension. + #define GRID_MAX_POINTS_X 3 + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + // Set the boundaries for probing (where the probe can reach). + #define LEFT_PROBE_BED_POSITION 15 + #define RIGHT_PROBE_BED_POSITION 170 + #define FRONT_PROBE_BED_POSITION 20 + #define BACK_PROBE_BED_POSITION 170 + + // The Z probe minimum outer margin (to validate G29 parameters). + #define MIN_PROBE_EDGE 10 + + // Probe along the Y axis, advancing X after each column + //#define PROBE_Y_FIRST + + #if ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Beyond the probed grid, continue the implied tilt? + // Default is to maintain the height of the nearest edge. + //#define EXTRAPOLATE_BEYOND_GRID + + // + // Experimental Subdivision of the grid by Catmull-Rom method. + // Synthesizes intermediate points to produce a more detailed mesh. + // + //#define ABL_BILINEAR_SUBDIVISION + #if ENABLED(ABL_BILINEAR_SUBDIVISION) + // Number of subdivisions between probe points + #define BILINEAR_SUBDIVISIONS 3 + #endif + + #endif + +#elif ENABLED(AUTO_BED_LEVELING_3POINT) + + // 3 arbitrary points to probe. + // A simple cross-product is used to estimate the plane of the bed. + #define ABL_PROBE_PT_1_X 15 + #define ABL_PROBE_PT_1_Y 180 + #define ABL_PROBE_PT_2_X 15 + #define ABL_PROBE_PT_2_Y 20 + #define ABL_PROBE_PT_3_X 170 + #define ABL_PROBE_PT_3_Y 20 + +#elif ENABLED(AUTO_BED_LEVELING_UBL) + + //=========================================================================== + //========================= Unified Bed Leveling ============================ + //=========================================================================== + + #define UBL_MESH_INSET 1 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 10 // Don't use more than 15 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + #define UBL_PROBE_PT_1_X 39 // Probing points for 3-Point leveling of the mesh + #define UBL_PROBE_PT_1_Y 180 + #define UBL_PROBE_PT_2_X 39 + #define UBL_PROBE_PT_2_Y 20 + #define UBL_PROBE_PT_3_X 180 + #define UBL_PROBE_PT_3_Y 20 + + #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation + #define UBL_MESH_EDIT_MOVES_Z // Sophisticated users prefer no movement of nozzle + +#elif ENABLED(MESH_BED_LEVELING) + + //=========================================================================== + //=================================== Mesh ================================== + //=========================================================================== + + #define MESH_INSET 10 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 3 // Don't use more than 7 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + //#define MESH_G28_REST_ORIGIN // After homing all axes ('G28' or 'G28 XYZ') rest Z at Z_MIN_POS + +#endif // BED_LEVELING + +/** + * Use the LCD controller for bed leveling + * Requires MESH_BED_LEVELING or PROBE_MANUALLY + */ +//#define LCD_BED_LEVELING + +#if ENABLED(LCD_BED_LEVELING) + #define MBL_Z_STEP 0.025 // Step size while manually probing Z axis. + #define LCD_PROBE_Z_RANGE 4 // Z Range centered on Z_MIN_POS for LCD Z adjustment +#endif + +// Add a menu item to move between bed corners for manual bed adjustment +//#define LEVEL_BED_CORNERS + +/** + * Commands to execute at the end of G29 probing. + * Useful to retract or move the Z probe out of the way. + */ +//#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) +//#define BED_CENTER_AT_0_0 + +// Manually set the home position. Leave these undefined for automatic settings. +// For DELTA this is the top-center of the Cartesian print volume. +//#define MANUAL_X_HOME_POS 0 +//#define MANUAL_Y_HOME_POS 0 +//#define MANUAL_Z_HOME_POS 0 + +// Use "Z Safe Homing" to avoid homing with a Z probe outside the bed area. +// +// With this feature enabled: +// +// - 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). +// - 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 axis (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). +#endif + +// Homing speeds (mm/m) +#define HOMING_FEEDRATE_XY (50*60) +#define HOMING_FEEDRATE_Z (4*60) + +//============================================================================= +//============================= Additional Features =========================== +//============================================================================= + +// @section extras + +// +// EEPROM +// +// The microcontroller can store settings in the EEPROM, e.g. max velocity... +// M500 - stores parameters in EEPROM +// M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily). +// M502 - reverts to the default "factory settings". You still need to store them in EEPROM afterwards if you want to. +// +//#define EEPROM_SETTINGS // Enable for M500 and M501 commands +//#define DISABLE_M503 // Saves ~2700 bytes of PROGMEM. Disable for release! +#define EEPROM_CHITCHAT // Give feedback on EEPROM commands. Disable to save PROGMEM. + +// +// Host Keepalive +// +// When enabled Marlin will send a busy status message to the host +// every couple of seconds when it can't accept commands. +// +#define HOST_KEEPALIVE_FEATURE // Disable this if your host doesn't like keepalive messages +#define DEFAULT_KEEPALIVE_INTERVAL 2 // Number of seconds between "busy" messages. Set with M113. +#define BUSY_WHILE_HEATING // Some hosts require "busy" messages even during heating + +// +// M100 Free Memory Watcher +// +//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose + +// +// G20/G21 Inch mode support +// +//#define INCH_MODE_SUPPORT + +// +// M149 Set temperature units support +// +//#define TEMPERATURE_UNITS_SUPPORT + +// @section temperature + +// Preheat Constants +#define PREHEAT_1_TEMP_HOTEND 200 +#define PREHEAT_1_TEMP_BED 50 +#define PREHEAT_1_FAN_SPEED 0 // Value from 0 to 255 + +#define PREHEAT_2_TEMP_HOTEND 245 +#define PREHEAT_2_TEMP_BED 100 +#define PREHEAT_2_FAN_SPEED 0 // Value from 0 to 255 + +/** + * Nozzle Park -- EXPERIMENTAL + * + * Park the nozzle at the given XYZ position on idle or G27. + * + * The "P" parameter controls the action applied to the Z axis: + * + * P0 (Default) If Z is below park Z raise the nozzle. + * P1 Raise the nozzle always to Z-park height. + * P2 Raise the nozzle by Z-park amount, limited to Z_MAX_POS. + */ +//#define NOZZLE_PARK_FEATURE + +#if ENABLED(NOZZLE_PARK_FEATURE) + // Specify a park position as { X, Y, Z } + #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 } +#endif + +/** + * Clean Nozzle Feature -- EXPERIMENTAL + * + * Adds the G12 command to perform a nozzle cleaning process. + * + * Parameters: + * P Pattern + * S Strokes / Repetitions + * T Triangles (P1 only) + * + * Patterns: + * P0 Straight line (default). This process requires a sponge type material + * at a fixed bed location. "S" specifies strokes (i.e. back-forth motions) + * between the start / end points. + * + * P1 Zig-zag pattern between (X0, Y0) and (X1, Y1), "T" specifies the + * number of zig-zag triangles to do. "S" defines the number of strokes. + * Zig-zags are done in whichever is the narrower dimension. + * For example, "G12 P1 S1 T3" will execute: + * + * -- + * | (X0, Y1) | /\ /\ /\ | (X1, Y1) + * | | / \ / \ / \ | + * A | | / \ / \ / \ | + * | | / \ / \ / \ | + * | (X0, Y0) | / \/ \/ \ | (X1, Y0) + * -- +--------------------------------+ + * |________|_________|_________| + * T1 T2 T3 + * + * P2 Circular pattern with middle at NOZZLE_CLEAN_CIRCLE_MIDDLE. + * "R" specifies the radius. "S" specifies the stroke count. + * Before starting, the nozzle moves to NOZZLE_CLEAN_START_POINT. + * + * Caveats: The ending Z should be the same as starting Z. + * Attention: EXPERIMENTAL. G-code arguments may change. + * + */ +//#define NOZZLE_CLEAN_FEATURE + +#if ENABLED(NOZZLE_CLEAN_FEATURE) + // Default number of pattern repetitions + #define NOZZLE_CLEAN_STROKES 12 + + // Default number of triangles + #define NOZZLE_CLEAN_TRIANGLES 3 + + // Specify positions as { X, Y, Z } + #define NOZZLE_CLEAN_START_POINT { 30, 30, (Z_MIN_POS + 1)} + #define NOZZLE_CLEAN_END_POINT {100, 60, (Z_MIN_POS + 1)} + + // Circular pattern radius + #define NOZZLE_CLEAN_CIRCLE_RADIUS 6.5 + // Circular pattern circle fragments number + #define NOZZLE_CLEAN_CIRCLE_FN 10 + // Middle point of circle + #define NOZZLE_CLEAN_CIRCLE_MIDDLE NOZZLE_CLEAN_START_POINT + + // Moves the nozzle to the initial position + #define NOZZLE_CLEAN_GOBACK +#endif + +/** + * Print Job Timer + * + * Automatically start and stop the print job timer on M104/M109/M190. + * + * M104 (hotend, no wait) - high temp = none, low temp = stop timer + * M109 (hotend, wait) - high temp = start timer, low temp = stop timer + * M190 (bed, wait) - high temp = start timer, low temp = none + * + * The timer can also be controlled with the following commands: + * + * M75 - Start the print job timer + * M76 - Pause the print job timer + * M77 - Stop the print job timer + */ +#define PRINTJOB_TIMER_AUTOSTART + +/** + * Print Counter + * + * Track statistical data such as: + * + * - Total print jobs + * - Total successful print jobs + * - Total failed print jobs + * - Total time printing + * + * View the current statistics with M78. + */ +//#define PRINTCOUNTER + +//============================================================================= +//============================= LCD and SD support ============================ +//============================================================================= + +// @section lcd + +/** + * LCD LANGUAGE + * + * Select the language to display on the LCD. These languages are available: + * + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, + * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * tr, uk, zh_CN, zh_TW, test + * + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + */ +#define LCD_LANGUAGE en + +/** + * LCD Character Set + * + * Note: This option is NOT applicable to Graphical Displays. + * + * All character-based LCDs provide ASCII plus one of these + * language extensions: + * + * - JAPANESE ... the most common + * - WESTERN ... with more accented characters + * - CYRILLIC ... for the Russian language + * + * To determine the language extension installed on your controller: + * + * - Compile and upload with LCD_LANGUAGE set to 'test' + * - 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 + * + * :['JAPANESE', 'WESTERN', 'CYRILLIC'] + */ +#define DISPLAY_CHARSET_HD44780 JAPANESE + +/** + * LCD TYPE + * + * Enable ULTRA_LCD for a 16x2, 16x4, 20x2, or 20x4 character-based LCD. + * Enable DOGLCD for a 128x64 (ST7565R) Full Graphical Display. + * (These options will be enabled automatically for most displays.) + * + * IMPORTANT: The U8glib library is required for Full Graphic Display! + * https://github.com/olikraus/U8glib_Arduino + */ +//#define ULTRA_LCD // Character based +//#define DOGLCD // Full graphics display + +/** + * SD CARD + * + * 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 + +/** + * SD CARD: SPI SPEED + * + * Enable one of the following items for a slower SPI transfer speed. + * This may be required to resolve "volume init" errors. + */ +//#define SPI_SPEED SPI_HALF_SPEED +//#define SPI_SPEED SPI_QUARTER_SPEED +//#define SPI_SPEED SPI_EIGHTH_SPEED + +/** + * SD CARD: ENABLE CRC + * + * Use CRC checks and retries on the SD communication. + */ +#define SD_CHECK_AND_RETRY + +// +// ENCODER SETTINGS +// +// This option overrides the default number of encoder pulses needed to +// produce one step. Should be increased for high-resolution encoders. +// +//#define ENCODER_PULSES_PER_STEP 1 + +// +// Use this option to override the number of step signals required to +// move between next/prev menu items. +// +//#define ENCODER_STEPS_PER_MENU_ITEM 5 + +/** + * Encoder Direction Options + * + * Test your encoder's behavior first with both options disabled. + * + * Reversed Value Edit and Menu Nav? Enable REVERSE_ENCODER_DIRECTION. + * Reversed Menu Navigation only? Enable REVERSE_MENU_DIRECTION. + * Reversed Value Editing only? Enable BOTH options. + */ + +// +// This option reverses the encoder direction everywhere. +// +// Set this option if CLOCKWISE causes values to DECREASE +// +//#define REVERSE_ENCODER_DIRECTION + +// +// This option reverses the encoder direction for navigating LCD menus. +// +// If CLOCKWISE normally moves DOWN this makes it go UP. +// If CLOCKWISE normally moves UP this makes it go DOWN. +// +//#define REVERSE_MENU_DIRECTION + +// +// Individual Axis Homing +// +// Add individual axis homing items (Home X, Home Y, and Home Z) to the LCD menu. +// +//#define INDIVIDUAL_AXIS_HOMING_MENU + +// +// SPEAKER/BUZZER +// +// If you have a speaker that can produce tones, enable it here. +// By default Marlin assumes you have a buzzer with a fixed frequency. +// +//#define SPEAKER + +// +// The duration and frequency for the UI feedback sound. +// Set these to 0 to disable audio feedback in the LCD menus. +// +// Note: Test audio output with the G-Code: +// M300 S P +// +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 +//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 + +// +// CONTROLLER TYPE: Standard +// +// Marlin supports a wide variety of controllers. +// Enable one of the following options to specify your controller. +// + +// +// ULTIMAKER Controller. +// +//#define ULTIMAKERCONTROLLER + +// +// ULTIPANEL as seen on Thingiverse. +// +//#define ULTIPANEL + +// +// PanelOne from T3P3 (via RAMPS 1.4 AUX2/AUX3) +// http://reprap.org/wiki/PanelOne +// +//#define PANEL_ONE + +// +// MaKr3d Makr-Panel with graphic controller and SD support. +// http://reprap.org/wiki/MaKr3d_MaKrPanel +// +//#define MAKRPANEL + +// +// ReprapWorld Graphical LCD +// https://reprapworld.com/?products_details&products_id/1218 +// +//#define REPRAPWORLD_GRAPHICAL_LCD + +// +// Activate one of these if you have a Panucatt Devices +// Viki 2.0 or mini Viki with Graphic LCD +// http://panucatt.com +// +//#define VIKI2 +//#define miniVIKI + +// +// Adafruit ST7565 Full Graphic Controller. +// https://github.com/eboston/Adafruit-ST7565-Full-Graphic-Controller/ +// +//#define ELB_FULL_GRAPHIC_CONTROLLER + +// +// RepRapDiscount Smart Controller. +// http://reprap.org/wiki/RepRapDiscount_Smart_Controller +// +// Note: Usually sold with a white PCB. +// +#define REPRAP_DISCOUNT_SMART_CONTROLLER + +// +// GADGETS3D G3D LCD/SD Controller +// http://reprap.org/wiki/RAMPS_1.3/1.4_GADGETS3D_Shield_with_Panel +// +// Note: Usually sold with a blue PCB. +// +//#define G3D_PANEL + +// +// RepRapDiscount FULL GRAPHIC Smart Controller +// http://reprap.org/wiki/RepRapDiscount_Full_Graphic_Smart_Controller +// +//#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER + +// +// MakerLab Mini Panel with graphic +// controller and SD support - http://reprap.org/wiki/Mini_panel +// +//#define MINIPANEL + +// +// RepRapWorld REPRAPWORLD_KEYPAD v1.1 +// http://reprapworld.com/?products_details&products_id=202&cPath=1591_1626 +// +// REPRAPWORLD_KEYPAD_MOVE_STEP sets how much should the robot move when a key +// is pressed, a value of 10.0 means 10mm per click. +// +//#define REPRAPWORLD_KEYPAD +//#define REPRAPWORLD_KEYPAD_MOVE_STEP 1.0 + +// +// RigidBot Panel V1.0 +// http://www.inventapart.com/ +// +//#define RIGIDBOT_PANEL + +// +// BQ LCD Smart Controller shipped by +// default with the BQ Hephestos 2 and Witbox 2. +// +//#define BQ_LCD_SMART_CONTROLLER + +// +// Cartesio UI +// http://mauk.cc/webshop/cartesio-shop/electronics/user-interface +// +//#define CARTESIO_UI + +// +// ANET_10 Controller supported displays. +// +//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. + // This LCD is known to be susceptible to electrical interference + // which scrambles the display. Pressing any button clears it up. +//#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 + // A clone of the RepRapDiscount full graphics display but with + // different pins/wiring (see pins_ANET_10.h). + +// +// LCD for Melzi Card with Graphical LCD +// +//#define LCD_FOR_MELZI + +// +// CONTROLLER TYPE: I2C +// +// Note: These controllers require the installation of Arduino's LiquidCrystal_I2C +// library. For more info: https://github.com/kiyoshigawa/LiquidCrystal_I2C +// + +// +// Elefu RA Board Control Panel +// http://www.elefu.com/index.php?route=product/product&product_id=53 +// +//#define RA_CONTROL_PANEL + +// +// Sainsmart YW Robot (LCM1602) LCD Display +// +// Note: This controller requires F.Malpartida's LiquidCrystal_I2C library +// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home +// +//#define LCD_I2C_SAINSMART_YWROBOT + +// +// Generic LCM1602 LCD adapter +// +//#define LCM1602 + +// +// PANELOLU2 LCD with status LEDs, +// separate encoder and click inputs. +// +// Note: This controller requires Arduino's LiquidTWI2 library v1.2.3 or later. +// For more info: https://github.com/lincomatic/LiquidTWI2 +// +// Note: The PANELOLU2 encoder click input can either be directly connected to +// a pin (if BTN_ENC defined to != -1) or read through I2C (when BTN_ENC == -1). +// +//#define LCD_I2C_PANELOLU2 + +// +// Panucatt VIKI LCD with status LEDs, +// integrated click & L/R/U/D buttons, separate encoder inputs. +// +//#define LCD_I2C_VIKI + +// +// SSD1306 OLED full graphics generic display +// +//#define U8GLIB_SSD1306 + +// +// SAV OLEd LCD module support using either SSD1306 or SH1106 based LCD modules +// +//#define SAV_3DGLCD +#if ENABLED(SAV_3DGLCD) + //#define U8GLIB_SSD1306 + #define U8GLIB_SH1106 +#endif + +// +// CONTROLLER TYPE: Shift register panels +// +// 2 wire Non-latching LCD SR from https://goo.gl/aJJ4sH +// LCD configuration: http://reprap.org/wiki/SAV_3D_LCD +// +//#define SAV_3DLCD + +// +// TinyBoy2 128x64 OLED / Encoder Panel +// +//#define OLED_PANEL_TINYBOY2 + +// +// Makeboard 3D Printer Parts 3D Printer Mini Display 1602 Mini Controller +// https://www.aliexpress.com/item/Micromake-Makeboard-3D-Printer-Parts-3D-Printer-Mini-Display-1602-Mini-Controller-Compatible-with-Ramps-1/32765887917.html +// +//#define MAKEBOARD_MINI_2_LINE_DISPLAY_1602 + +// +// MKS MINI12864 with graphic controller and SD support +// http://reprap.org/wiki/MKS_MINI_12864 +// +//#define MKS_MINI_12864 + +// +// Factory display for Creality CR-10 +// https://www.aliexpress.com/item/Universal-LCD-12864-3D-Printer-Display-Screen-With-Encoder-For-CR-10-CR-7-Model/32833148327.html +// +// This is RAMPS-compatible using a single 10-pin connector. +// (For CR-10 owners who want to replace the Melzi Creality board but retain the display) +// +//#define CR10_STOCKDISPLAY + +// +// MKS OLED 1.3" 128 × 64 FULL GRAPHICS CONTROLLER +// http://reprap.org/wiki/MKS_12864OLED +// +// Tiny, but very sharp OLED display +// +//#define MKS_12864OLED + +//============================================================================= +//=============================== Extra Features ============================== +//============================================================================= + +// @section extras + +// Increase the FAN PWM frequency. Removes the PWM noise but increases heating in the FET/Arduino +//#define FAST_PWM_FAN + +// Use software PWM to drive the fan, as for the heaters. This uses a very low frequency +// which is not as annoying as with the hardware PWM. On the other hand, if this frequency +// is too low, you should also increment SOFT_PWM_SCALE. +//#define FAN_SOFT_PWM + +// Incrementing this by 1 will double the software PWM frequency, +// affecting heaters, and the fan if FAN_SOFT_PWM is enabled. +// However, control resolution will be halved for each increment; +// at zero value, there are 128 effective control positions. +#define SOFT_PWM_SCALE 0 + +// If SOFT_PWM_SCALE is set to a value higher than 0, dithering can +// be used to mitigate the associated resolution loss. If enabled, +// some of the PWM cycles are stretched so on average the desired +// duty cycle is attained. +//#define SOFT_PWM_DITHER + +// Temperature status LEDs that display the hotend and bed temperature. +// If all hotends, bed temperature, and target temperature are under 54C +// then the BLUE led is on. Otherwise the RED led is on. (1C hysteresis) +//#define TEMP_STAT_LEDS + +// M240 Triggers a camera by emulating a Canon RC-1 Remote +// Data from: http://www.doc-diy.net/photo/rc-1_hacked/ +//#define PHOTOGRAPH_PIN 23 + +// 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 + +// Support for BlinkM/CyzRgb +//#define BLINKM + +// Support for PCA9632 PWM LED driver +//#define PCA9632 + +/** + * RGB LED / LED Strip Control + * + * Enable support for an RGB LED connected to 5V digital pins, or + * an RGB Strip connected to MOSFETs controlled by digital pins. + * + * 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 overall brightness parameters is also available + * + * *** CAUTION *** + * LED Strips require a MOFSET 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! + * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino + * cannot handle such current, separate 5V power supply must be used + * *** CAUTION *** + * + * LED type. This options are mutualy exclusive. Uncomment only one. + * + */ +//#define RGB_LED +//#define RGBW_LED + +#if ENABLED(RGB_LED) || ENABLED(RGBW_LED) + #define RGB_LED_R_PIN 34 + #define RGB_LED_G_PIN 43 + #define RGB_LED_B_PIN 35 + #define RGB_LED_W_PIN -1 +#endif + +// 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 (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) + #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip + #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time + #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + //#define NEOPIXEL_STARTUP_TEST // Cycle through colors at startup +#endif + +/** + * Printer Event LEDs + * + * During printing, the LEDs will reflect the printer status: + * + * - Gradually change from blue to violet as the heated bed gets to target temp + * - Gradually change from violet to red as the hotend gets to temperature + * - Change to white to illuminate work surface + * - Change to green once print has finished + * - Turn off after the print has finished and the user has pushed a button + */ +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) + #define PRINTER_EVENT_LEDS +#endif + +/*********************************************************************\ +* R/C SERVO support +* Sponsored by TrinityLabs, Reworked by codexmas +**********************************************************************/ + +// Number of servos +// +// If you select a configuration below, this will receive a default value and does not need to be set manually +// set it manually if you have more servos than extruders and wish to manually control some +// leaving it undefined or defining as 0 will disable the servo subsystem +// If unsure, leave commented / disabled +// +//#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command + +// Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. +// 300ms is a good value but you can try less delay. +// If the servo can't reach the requested position, increase it. +#define SERVO_DELAY { 300 } + +// Servo deactivation +// +// With this option servos are powered only during movement, then turned off to prevent jitter. +//#define DEACTIVATE_SERVOS_AFTER_MOVE + +/** + * Filament Width Sensor + * + * Measures the filament width in real-time and adjusts + * flow rate to compensate for any irregularities. + * + * Also allows the measured filament diameter to set the + * extrusion rate, so the slicer only has to specify the + * volume. + * + * Only a single extruder is supported at this time. + * + * 34 RAMPS_14 : Analog input 5 on the AUX2 connector + * 81 PRINTRBOARD : Analog input 2 on the Exp1 connector (version B,C,D,E) + * 301 RAMBO : Analog input 3 + * + * Note: May require analog pins to be defined for other boards. + */ +//#define FILAMENT_WIDTH_SENSOR + +#define DEFAULT_NOMINAL_FILAMENT_DIA 3.00 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. + +#if ENABLED(FILAMENT_WIDTH_SENSOR) + #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) + #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber + + #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading + #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading + #define MAX_MEASUREMENT_DELAY 20 // (bytes) Buffer size for stored measurements (1 byte per cm). Must be larger than MEASUREMENT_DELAY_CM. + + #define DEFAULT_MEASURED_FILAMENT_DIA DEFAULT_NOMINAL_FILAMENT_DIA // Set measured to nominal initially + + // Display filament width on the LCD status line. Status messages will expire after 5 seconds. + //#define FILAMENT_LCD_DISPLAY +#endif + +#endif // CONFIGURATION_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/Infitary/i3-M508/Configuration_adv.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/Infitary/i3-M508/Configuration_adv.h new file mode 100644 index 00000000..811e6d62 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/Infitary/i3-M508/Configuration_adv.h @@ -0,0 +1,1424 @@ +/** + * 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 . + * + */ + +/** + * Configuration_adv.h + * + * Advanced settings. + * Only change these if you know exactly what you're doing. + * Some of these settings can damage your printer if improperly set! + * + * Basic settings can be found in Configuration.h + * + */ +#ifndef CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H_VERSION 010100 + +// @section temperature + +//=========================================================================== +//=============================Thermal Settings ============================ +//=========================================================================== + +#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 + #endif +#endif + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * The solution: Once the temperature reaches the target, start observing. + * If the temperature stays too far below the target (hysteresis) for too long (period), + * the firmware will halt the machine as a safety precaution. + * + * If you get false positives for "Thermal Runaway" increase THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD + */ +#if ENABLED(THERMAL_PROTECTION_HOTENDS) + #define THERMAL_PROTECTION_PERIOD 40 // Seconds + #define THERMAL_PROTECTION_HYSTERESIS 4 // Degrees Celsius + + /** + * Whenever an M104 or M109 increases the target temperature the firmware will wait for the + * WATCH_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get false positives for "Heating failed" increase WATCH_TEMP_PERIOD and/or decrease WATCH_TEMP_INCREASE + * WATCH_TEMP_INCREASE should not be below 2. + */ + #define WATCH_TEMP_PERIOD 20 // Seconds + #define WATCH_TEMP_INCREASE 2 // Degrees Celsius +#endif + +/** + * Thermal Protection parameters for the bed are just as above for hotends. + */ +#if ENABLED(THERMAL_PROTECTION_BED) + #define THERMAL_PROTECTION_BED_PERIOD 20 // Seconds + #define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius + + /** + * Whenever an M140 or M190 increases the target temperature the firmware will wait for the + * WATCH_BED_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_BED_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get too many "Heating failed" errors, increase WATCH_BED_TEMP_PERIOD and/or decrease + * WATCH_BED_TEMP_INCREASE. (WATCH_BED_TEMP_INCREASE should not be below 2.) + */ + #define WATCH_BED_TEMP_PERIOD 60 // Seconds + #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius +#endif + +#if ENABLED(PIDTEMP) + // this adds an experimental additional term to the heating power, proportional to the extrusion speed. + // if Kc is chosen well, the additional required power due to increased melting should be compensated. + //#define PID_EXTRUSION_SCALING + #if ENABLED(PID_EXTRUSION_SCALING) + #define DEFAULT_Kc (100) //heating power=Kc*(e_speed) + #define LPQ_MAX_LEN 50 + #endif +#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 + */ +#define AUTOTEMP +#if ENABLED(AUTOTEMP) + #define AUTOTEMP_OLDWEIGHT 0.98 +#endif + +// Show Temperature ADC value +// Enable for M105 to include ADC values read from temperature sensors. +//#define SHOW_TEMP_ADC_VALUES + +/** + * High Temperature Thermistor Support + * + * Thermistors able to support high temperature tend to have a hard time getting + * good readings at room and lower temperatures. This means HEATER_X_RAW_LO_TEMP + * will probably be caught when the heating element first turns on during the + * preheating process, which will trigger a min_temp_error as a safety measure + * and force stop everything. + * To circumvent this limitation, we allow for a preheat time (during which, + * min_temp_error won't be triggered) and add a min_temp buffer to handle + * aberrant readings. + * + * If you want to enable this feature for your hotend thermistor(s) + * uncomment and set values > 0 in the constants below + */ + +// The number of consecutive low temperature errors that can occur +// before a min_temp_error is triggered. (Shouldn't be more than 10.) +//#define MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED 0 + +// The number of milliseconds a hotend will preheat before starting to check +// the temperature. This value should NOT be set to the time it takes the +// hot end to reach the target temperature, but the time it takes to reach +// the minimum temperature your thermistor can read. The lower the better/safer. +// This shouldn't need to be more than 30 seconds (30000) +//#define MILLISECONDS_PREHEAT_TIME 0 + +// @section extruder + +// Extruder runout prevention. +// If the machine is idle and the temperature over MINTEMP +// then extrude some filament every couple of SECONDS. +//#define EXTRUDER_RUNOUT_PREVENT +#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_EXTRUDE 5 // mm +#endif + +// @section temperature + +//These defines help to calibrate the AD595 sensor in case you get wrong temperature measurements. +//The measured temperature is defined as "actualTemp = (measuredTemp * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET" +#define TEMP_SENSOR_AD595_OFFSET 0.0 +#define TEMP_SENSOR_AD595_GAIN 1.0 + +/** + * 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. + */ +//#define USE_CONTROLLER_FAN +#if ENABLED(USE_CONTROLLER_FAN) + //#define CONTROLLER_FAN_PIN FAN1_PIN // 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 +#endif + +// When first starting the main fan, run it at full speed for the +// given number of milliseconds. This gets the fan spinning reliably +// before setting a PWM value. (Does not work with software PWM for fan on Sanguinololu) +//#define FAN_KICKSTART_TIME 100 + +// This defines the minimal speed for the main fan, run in PWM mode +// to enable uncomment and set minimal PWM speed for reliable running (1-255) +// if fan speed is [1 - (FAN_MIN_PWM-1)] it is set to FAN_MIN_PWM +//#define FAN_MIN_PWM 50 + +// @section extruder + +/** + * Extruder cooling fans + * + * Extruder auto fans automatically turn on when their extruders' + * temperatures go above EXTRUDER_AUTO_FAN_TEMPERATURE. + * + * Your board's pins file specifies the recommended pins. Override those here + * or set to -1 to disable completely. + * + * Multiple extruders can be assigned to the same pin in which case + * the fan will turn on when any selected extruder is above the threshold. + */ +#define E0_AUTO_FAN_PIN -1 +#define E1_AUTO_FAN_PIN -1 +#define E2_AUTO_FAN_PIN -1 +#define E3_AUTO_FAN_PIN -1 +#define E4_AUTO_FAN_PIN -1 +#define EXTRUDER_AUTO_FAN_TEMPERATURE 50 +#define EXTRUDER_AUTO_FAN_SPEED 255 // == full speed + +/** + * Part-Cooling Fan Multiplexer + * + * This feature allows you to digitally multiplex the fan output. + * The multiplexer is automatically switched at tool-change. + * Set FANMUX[012]_PINs below for up to 2, 4, or 8 multiplexed fans. + */ +#define FANMUX0_PIN -1 +#define FANMUX1_PIN -1 +#define FANMUX2_PIN -1 + +/** + * M355 Case Light on-off / brightness + */ +//#define CASE_LIGHT_ENABLE +#if ENABLED(CASE_LIGHT_ENABLE) + //#define CASE_LIGHT_PIN 4 // Override the default pin if needed + #define INVERT_CASE_LIGHT false // Set true if Case Light is ON when pin is LOW + #define CASE_LIGHT_DEFAULT_ON true // Set default power-up state on + #define CASE_LIGHT_DEFAULT_BRIGHTNESS 105 // Set default power-up brightness (0-255, requires PWM pin) + //#define MENU_ITEM_CASE_LIGHT // Add a Case Light option to the LCD main menu +#endif + +//=========================================================================== +//============================ Mechanical Settings ========================== +//=========================================================================== + +// @section homing + +// If you want endstops to stay on (by default) even when not homing +// enable this option. Override at any time with M120, M121. +//#define ENDSTOPS_ALWAYS_ON_DEFAULT + +// @section extras + +//#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. + +// Dual X Steppers +// Uncomment this option to drive two X axis motors. +// The next unused E driver will be assigned to the second X stepper. +//#define X_DUAL_STEPPER_DRIVERS +#if ENABLED(X_DUAL_STEPPER_DRIVERS) + // Set true if the two X motors need to rotate in opposite directions + #define INVERT_X2_VS_X_DIR true +#endif + +// Dual Y Steppers +// Uncomment this option to drive two Y axis motors. +// The next unused E driver will be assigned to the second Y stepper. +//#define Y_DUAL_STEPPER_DRIVERS +#if ENABLED(Y_DUAL_STEPPER_DRIVERS) + // Set true if the two Y motors need to rotate in opposite directions + #define INVERT_Y2_VS_Y_DIR true +#endif + +// A single Z stepper driver is usually used to drive 2 stepper motors. +// Uncomment this option to use a separate stepper driver for each Z axis motor. +// The next unused E driver will be assigned to the second Z stepper. +//#define Z_DUAL_STEPPER_DRIVERS + +#if ENABLED(Z_DUAL_STEPPER_DRIVERS) + + // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper. + // That way the machine is capable to align the bed during home, since both Z steppers are homed. + // There is also an implementation of M666 (software endstops adjustment) to this feature. + // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed. + // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2. + // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive. + // Play a little bit with small adjustments (0.5mm) and check the behaviour. + // The M119 (endstops report) will start reporting the Z2 Endstop as well. + + //#define Z_DUAL_ENDSTOPS + + #if ENABLED(Z_DUAL_ENDSTOPS) + #define Z2_USE_ENDSTOP _XMAX_ + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 // Use M666 to determine/test this value + #endif + +#endif // Z_DUAL_STEPPER_DRIVERS + +// Enable this for dual x-carriage printers. +// A dual x-carriage design has the advantage that the inactive extruder can be parked which +// prevents hot-end ooze contaminating the print. It also reduces the weight of each x-carriage +// allowing faster printing speeds. Connect your X2 stepper to the first unused E plug. +//#define DUAL_X_CARRIAGE +#if ENABLED(DUAL_X_CARRIAGE) + // Configuration for second X-carriage + // Note: the first x-carriage is defined as the x-carriage which homes to the minimum endstop; + // the second x-carriage always homes to the maximum endstop. + #define X2_MIN_POS 80 // set minimum to ensure second x-carriage doesn't hit the parked first X-carriage + #define X2_MAX_POS 353 // set maximum to the distance between toolheads when both heads are homed + #define X2_HOME_DIR 1 // the second X-carriage always homes to the maximum endstop position + #define X2_HOME_POS X2_MAX_POS // default home position is the maximum carriage position + // However: In this mode the HOTEND_OFFSET_X value for the second extruder provides a software + // override for X2_HOME_POS. This also allow recalibration of the distance between the two endstops + // without modifying the firmware (through the "M218 T1 X???" command). + // Remember: you should set the second extruder x-offset to 0 in your slicer. + + // There are a few selectable movement modes for dual x-carriages using M605 S + // Mode 0 (DXC_FULL_CONTROL_MODE): Full control. The slicer has full control over both x-carriages and can achieve optimal travel results + // as long as it supports dual x-carriages. (M605 S0) + // Mode 1 (DXC_AUTO_PARK_MODE) : Auto-park mode. The firmware will automatically park and unpark the x-carriages on tool changes so + // that additional slicer support is not required. (M605 S1) + // Mode 2 (DXC_DUPLICATION_MODE) : Duplication mode. The firmware will transparently make the second x-carriage and extruder copy all + // actions of the first x-carriage. This allows the printer to print 2 arbitrary items at + // once. (2nd extruder x offset and temp offset are set using: M605 S2 [Xnnn] [Rmmm]) + + // This is the default power-up mode which can be later using M605. + #define DEFAULT_DUAL_X_CARRIAGE_MODE DXC_FULL_CONTROL_MODE + + // Default settings in "Auto-park Mode" + #define TOOLCHANGE_PARK_ZLIFT 0.2 // the distance to raise Z axis when parking an extruder + #define TOOLCHANGE_UNPARK_ZLIFT 1 // the distance to raise Z axis when unparking an extruder + + // Default x offset in duplication mode (typically set to half print bed width) + #define DEFAULT_DUPLICATION_X_OFFSET 100 + +#endif // DUAL_X_CARRIAGE + +// 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. +//#define EXT_SOLENOID + +// @section homing + +//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +#define X_HOME_BUMP_MM 5 +#define Y_HOME_BUMP_MM 5 +#define Z_HOME_BUMP_MM 1 +#define HOMING_BUMP_DIVISOR {2, 2, 4} // Re-Bump Speed Divisor (Divides the Homing Feedrate) +#define QUICK_HOME //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially. + +// When G28 is called, this option will make Y home before X +//#define HOME_Y_BEFORE_X + +// @section machine + +#define AXIS_RELATIVE_MODES {false, false, false, false} + +// Allow duplication mode with a basic dual-nozzle extruder +//#define DUAL_NOZZLE_DUPLICATION_MODE + +// By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step. +#define INVERT_X_STEP_PIN false +#define INVERT_Y_STEP_PIN false +#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. +#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_E true + +#define DEFAULT_MINIMUMFEEDRATE 0.0 // minimum feedrate +#define DEFAULT_MINTRAVELFEEDRATE 0.0 + +//#define HOME_AFTER_DEACTIVATE // Require rehoming after steppers are deactivated + +// @section lcd + +#if ENABLED(ULTIPANEL) + #define MANUAL_FEEDRATE {50*60, 50*60, 4*60, 60} // Feedrates for manual moves along X, Y, Z, E from panel + #define ULTIPANEL_FEEDMULTIPLY // Comment to disable setting feedrate multiplier via encoder +#endif + +// @section extras + +// minimum time in microseconds that a movement needs to take if the buffer is emptied. +#define DEFAULT_MINSEGMENTTIME 20000 + +// If defined the movements slow down when the look ahead buffer is only half full +#define SLOWDOWN + +// Frequency limit +// See nophead's blog for more info +// Not working O +//#define XY_FREQUENCY_LIMIT 15 + +// 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 +// if unwanted behavior is observed on a user's machine when running at very slow speeds. +#define MINIMUM_PLANNER_SPEED 0.05 // (mm/sec) + +// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU. +#define MICROSTEP_MODES {16,16,16,16,16} // [1,2,4,8,16] + +/** + * @section stepper motor current + * + * Some boards have a means of setting the stepper motor current via firmware. + * + * The power on motor currents are set by: + * PWM_MOTOR_CURRENT - used by MINIRAMBO & ULTIMAIN_2 + * known compatible chips: A4982 + * DIGIPOT_MOTOR_CURRENT - used by BQ_ZUM_MEGA_3D, RAMBO & SCOOVO_X9H + * known compatible chips: AD5206 + * DAC_MOTOR_CURRENT_DEFAULT - used by PRINTRBOARD_REVF & RIGIDBOARD_V2 + * known compatible chips: MCP4728 + * DIGIPOT_I2C_MOTOR_CURRENTS - used by 5DPRINT, AZTEEG_X3_PRO, MIGHTYBOARD_REVE + * known compatible chips: MCP4451, MCP4018 + * + * Motor currents can also be set by M907 - M910 and by the LCD. + * M907 - applies to all. + * M908 - BQ_ZUM_MEGA_3D, RAMBO, PRINTRBOARD_REVF, RIGIDBOARD_V2 & SCOOVO_X9H + * M909, M910 & LCD - only PRINTRBOARD_REVF & RIGIDBOARD_V2 + */ +//#define PWM_MOTOR_CURRENT { 1300, 1300, 1250 } // Values in milliamps +#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 + +// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +//#define DIGIPOT_I2C +//#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster +#define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 +// Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS +#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=========================== +//=========================================================================== + +#define ENCODER_RATE_MULTIPLIER // If defined, certain menu edit operations automatically multiply the steps when the encoder is moved quickly +#define ENCODER_10X_STEPS_PER_SEC 75 // If the encoder steps per sec exceeds this value, multiply steps moved x10 to quickly advance the value +#define ENCODER_100X_STEPS_PER_SEC 160 // If the encoder steps per sec exceeds this value, multiply steps moved x100 to really quickly advance the value + +//#define CHDK 4 //Pin for triggering CHDK to take a picture see how to use it here http://captain-slow.dk/2014/03/09/3d-printing-timelapses/ +#define CHDK_DELAY 50 //How long in ms the pin should stay HIGH before going LOW again + +// @section lcd + +// Include a page of printer information in the LCD Main Menu +//#define LCD_INFO_MENU + +// Scroll a longer status message into view +//#define STATUS_MESSAGE_SCROLLING + +// On the Info Screen, display XY with one decimal place when possible +//#define LCD_DECIMAL_SMALL_XY + +// The timeout (in ms) to return to the status screen from sub-menus +//#define LCD_TIMEOUT_TO_STATUS 15000 + +#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 + + #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? + #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. + + #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. + // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. + // using: + //#define MENU_ADDAUTOSTART + + /** + * Sort SD file listings in alphabetical order. + * + * With this option enabled, items on SD cards will be sorted + * by name for easier navigation. + * + * By default... + * + * - Use the slowest -but safest- method for sorting. + * - Folders are sorted to the top. + * - The sort key is statically allocated. + * - No added G-code (M34) support. + * - 40 item sorting limit. (Items after the first 40 are unsorted.) + * + * SD sorting uses static allocation (as set by SDSORT_LIMIT), allowing the + * compiler to calculate the worst-case usage and throw an error if the SRAM + * limit is exceeded. + * + * - SDSORT_USES_RAM provides faster sorting via a static directory buffer. + * - SDSORT_USES_STACK does the same, but uses a local stack-based buffer. + * - SDSORT_CACHE_NAMES will retain the sorted file listing in RAM. (Expensive!) + * - SDSORT_DYNAMIC_RAM only uses RAM when the SD menu is visible. (Use with caution!) + */ + //#define SDCARD_SORT_ALPHA + + // SD Card Sorting options + #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_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. + #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #endif + + // Show a progress bar on HD44780 LCDs for SD printing + //#define LCD_PROGRESS_BAR + + #if ENABLED(LCD_PROGRESS_BAR) + // Amount of time (ms) to show the bar + #define PROGRESS_BAR_BAR_TIME 2000 + // Amount of time (ms) to show the status message + #define PROGRESS_BAR_MSG_TIME 3000 + // Amount of time (ms) to retain the status message (0=forever) + #define PROGRESS_MSG_EXPIRE 0 + // Enable this to show messages for MSG_TIME then hide them + //#define PROGRESS_MSG_ONCE + // Add a menu item to test the progress bar: + //#define LCD_PROGRESS_BAR_TEST + #endif + + // This allows hosts to request long names for files and folders with M33 + //#define LONG_FILENAME_HOST_SUPPORT + + // This option allows you to abort SD printing when any endstop is triggered. + // This feature must be enabled with "M540 S1" or from the LCD menu. + // To have any effect, endstops must be enabled during SD printing. + //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + +#endif // SDSUPPORT + +/** + * Additional options for Graphical Displays + * + * Use the optimizations here to improve printing performance, + * which can be adversely affected by graphical display drawing, + * especially when doing several short moves, and when printing + * on DELTA and SCARA machines. + * + * Some of these options may result in the display lagging behind + * controller events, as there is a trade-off between reliable + * printing performance versus fast display updates. + */ +#if ENABLED(DOGLCD) + // Enable to save many cycles by drawing a hollow frame on the Info Screen + #define XYZ_HOLLOW_FRAME + + // Enable to save many cycles by drawing a hollow frame on Menu Screens + #define MENU_HOLLOW_FRAME + + // A bigger font is available for edit items. Costs 3120 bytes of PROGMEM. + // 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. + // 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 +#endif // DOGLCD + +// @section safety + +// The hardware watchdog should reset the microcontroller disabling all outputs, +// in case the firmware gets stuck and doesn't do temperature regulation. +#define USE_WATCHDOG + +#if ENABLED(USE_WATCHDOG) + // If you have a watchdog reboot in an ArduinoMega2560 then the device will hang forever, as a watchdog reset will leave the watchdog on. + // The "WATCHDOG_RESET_MANUAL" goes around this by not using the hardware reset. + // However, THIS FEATURE IS UNSAFE!, as it will only work if interrupts are disabled. And the code could hang in an interrupt routine with interrupts disabled. + //#define WATCHDOG_RESET_MANUAL +#endif + +// @section lcd + +/** + * Babystepping enables movement of the axes by tiny increments without changing + * the current position values. This feature is used primarily to adjust the Z + * axis in the first layer of a print in real-time. + * + * Warning: Does not respect endstops! + */ +//#define BABYSTEPPING +#if ENABLED(BABYSTEPPING) + //#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 100 // Babysteps are very small. Increase for faster motion. + //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping + //#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen 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_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor + //#define BABYSTEP_ZPROBE_GFX_REVERSE // Reverses the direction of the CW/CCW indicators +#endif + +// @section extruder + +/** + * Implementation of linear pressure control + * + * Assumption: advance = k * (delta velocity) + * K=0 means advance disabled. + * See Marlin documentation for calibration instructions. + */ +//#define LIN_ADVANCE + +#if ENABLED(LIN_ADVANCE) + #define LIN_ADVANCE_K 75 + + /** + * Some Slicers produce Gcode with randomly jumping extrusion widths occasionally. + * For example within a 0.4mm perimeter it may produce a single segment of 0.05mm width. + * While this is harmless for normal printing (the fluid nature of the filament will + * close this very, very tiny gap), it throws off the LIN_ADVANCE pressure adaption. + * + * For this case LIN_ADVANCE_E_D_RATIO can be used to set the extrusion:distance ratio + * to a fixed value. Note that using a fixed ratio will lead to wrong nozzle pressures + * if the slicer is using variable widths or layer heights within one print! + * + * This option sets the default E:D ratio at startup. Use `M900` to override this value. + * + * Example: `M900 W0.4 H0.2 D1.75`, where: + * - W is the extrusion width in mm + * - H is the layer height in mm + * - D is the filament diameter in mm + * + * Example: `M900 R0.0458` to set the ratio directly. + * + * Set to 0 to auto-detect the ratio based on given Gcode G1 print moves. + * + * Slic3r (including Průša Control) produces Gcode compatible with the automatic mode. + * Cura (as of this writing) may produce Gcode incompatible with the automatic mode. + */ + #define LIN_ADVANCE_E_D_RATIO 0 // The calculated ratio (or 0) according to the formula W * H / ((D / 2) ^ 2 * PI) + // Example: 0.4 * 0.2 / ((1.75 / 2) ^ 2 * PI) = 0.033260135 +#endif + +// @section leveling + +// Default mesh area is an area with an inset margin on the print area. +// Below are the macros that are used to define the borders for the mesh area, +// made available here for specialized needs, ie dual extruder setup. +#if ENABLED(MESH_BED_LEVELING) + #define MESH_MIN_X MESH_INSET + #define MESH_MAX_X (X_BED_SIZE - (MESH_INSET)) + #define MESH_MIN_Y MESH_INSET + #define MESH_MAX_Y (Y_BED_SIZE - (MESH_INSET)) +#elif ENABLED(AUTO_BED_LEVELING_UBL) + #define UBL_MESH_MIN_X UBL_MESH_INSET + #define UBL_MESH_MAX_X (X_BED_SIZE - (UBL_MESH_INSET)) + #define UBL_MESH_MIN_Y UBL_MESH_INSET + #define UBL_MESH_MAX_Y (Y_BED_SIZE - (UBL_MESH_INSET)) + + // If this is defined, the currently active mesh will be saved in the + // current slot on M500. + #define UBL_SAVE_ACTIVE_ON_M500 +#endif + +// @section extras + +// +// G2/G3 Arc Support +// +#define ARC_SUPPORT // Disable this feature to save ~3226 bytes +#if ENABLED(ARC_SUPPORT) + #define MM_PER_ARC_SEGMENT 1 // Length of each arc segment + #define N_ARC_CORRECTION 25 // Number of intertpolated 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 +#endif + +// Support for G5 with XYZE destination and IJPQ offsets. Requires ~2666 bytes. +//#define BEZIER_CURVE_SUPPORT + +// G38.2 and G38.3 Probe Target +// Enable PROBE_DOUBLE_TOUCH if you want G38 to double touch +//#define G38_PROBE_TARGET +#if ENABLED(G38_PROBE_TARGET) + #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) +#endif + +// Moves (or segments) with fewer steps than this will be joined with the next move +#define MIN_STEPS_PER_SEGMENT 6 + +// The minimum pulse width (in µs) for stepping a stepper. +// Set this if you find stepping unreliable, or if using a very fast CPU. +#define MINIMUM_STEPPER_PULSE 0 // (µs) The smallest stepper pulse allowed + +// @section temperature + +// Control heater 0 and heater 1 in parallel. +//#define HEATERS_PARALLEL + +//=========================================================================== +//================================= Buffers ================================= +//=========================================================================== + +// @section hidden + +// 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, i.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 +#else + #define BLOCK_BUFFER_SIZE 16 // maximize block buffer +#endif + +// @section serial + +// The ASCII buffer for serial input +#define MAX_CMD_SIZE 96 +#define BUFSIZE 4 + +// Transmission to Host Buffer Size +// To save 386 bytes of PROGMEM (and TX_BUFFER_SIZE+3 bytes of RAM) set to 0. +// To buffer a simple "ok" you need 4 bytes. +// For ADVANCED_OK (M105) you need 32 bytes. +// For debug-echo: 128 bytes for the optimal speed. +// Other output doesn't need to be that speedy. +// :[0, 2, 4, 8, 16, 32, 64, 128, 256] +#define TX_BUFFER_SIZE 0 + +// Host Receive Buffer Size +// Without XON/XOFF flow control (see SERIAL_XON_XOFF below) 32 bytes should be enough. +// To use flow control, set this buffer size to at least 1024 bytes. +// :[0, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048] +//#define RX_BUFFER_SIZE 1024 + +#if RX_BUFFER_SIZE >= 1024 + // Enable to have the controller send XON/XOFF control characters to + // the host to signal the RX buffer is becoming full. + //#define SERIAL_XON_XOFF +#endif + +#if ENABLED(SDSUPPORT) + // Enable this option to collect and display the maximum + // RX queue usage after transferring a file to SD. + //#define SERIAL_STATS_MAX_RX_QUEUED + + // Enable this option to collect and display the number + // of dropped bytes after a file transfer to SD. + //#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! +//#define EMERGENCY_PARSER + +// Bad Serial-connections can miss a received command by sending an 'ok' +// Therefore some clients abort after 30 seconds in a timeout. +// Some other clients start sending commands while receiving a 'wait'. +// This "wait" is only sent when the buffer is empty. 1 second is a good value here. +//#define NO_TIMEOUTS 1000 // Milliseconds + +// Some clients will have this feature soon. This could make the NO_TIMEOUTS unnecessary. +//#define ADVANCED_OK + +// @section extras + +/** + * Firmware-based and LCD-controlled retract + * + * Add G10 / G11 commands for automatic firmware-based retract / recover. + * Use M207 and M208 to define parameters for retract / recover. + * + * Use M209 to enable or disable auto-retract. + * With auto-retract enabled, all G1 E moves within the set range + * will be converted to firmware-based retract/recover moves. + * + * Be sure to turn off auto-retract during filament change. + * + * Note that M207 / M208 / M209 settings are saved to EEPROM. + * + */ +//#define FWRETRACT // ONLY PARTIALLY TESTED +#if ENABLED(FWRETRACT) + #define MIN_AUTORETRACT 0.1 // When auto-retract is on, convert E moves of this length and over + #define MAX_AUTORETRACT 10.0 // Upper limit for auto-retract conversion + #define RETRACT_LENGTH 3 // Default retract length (positive mm) + #define RETRACT_LENGTH_SWAP 13 // Default swap retract length (positive mm), for extruder change + #define RETRACT_FEEDRATE 45 // Default feedrate for retracting (mm/s) + #define RETRACT_ZLIFT 0 // Default retract Z-lift + #define RETRACT_RECOVER_LENGTH 0 // Default additional recover length (mm, added to retract length when recovering) + #define RETRACT_RECOVER_LENGTH_SWAP 0 // Default additional swap recover length (mm, added to retract length when recovering from extruder change) + #define RETRACT_RECOVER_FEEDRATE 8 // Default feedrate for recovering from retraction (mm/s) + #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) +#endif + +/** + * Advanced Pause + * Experimental feature for filament change support and for parking the nozzle when paused. + * Adds the GCode M600 for initiating filament change. + * If PARK_HEAD_ON_PAUSE enabled, adds the GCode M125 to pause printing and park the nozzle. + * + * Requires an LCD display. + * This feature is required for the default FILAMENT_RUNOUT_SCRIPT. + */ +//#define ADVANCED_PAUSE_FEATURE +#if ENABLED(ADVANCED_PAUSE_FEATURE) + #define PAUSE_PARK_X_POS 3 // X position of hotend + #define PAUSE_PARK_Y_POS 3 // Y position of hotend + #define PAUSE_PARK_Z_ADD 10 // Z addition of hotend (lift) + #define PAUSE_PARK_XY_FEEDRATE 100 // X and Y axes feedrate in mm/s (also used for delta printers Z axis) + #define PAUSE_PARK_Z_FEEDRATE 5 // Z axis feedrate in mm/s (not used for delta printers) + #define PAUSE_PARK_RETRACT_FEEDRATE 60 // Initial retract feedrate in mm/s + #define PAUSE_PARK_RETRACT_LENGTH 2 // Initial retract in mm + // It is a short retract used immediately after print interrupt before move to filament exchange position + #define FILAMENT_CHANGE_UNLOAD_FEEDRATE 10 // Unload filament feedrate in mm/s - filament unloading can be fast + #define FILAMENT_CHANGE_UNLOAD_LENGTH 100 // Unload filament length from hotend in mm + // Longer length for bowden printers to unload filament from whole bowden tube, + // shorter length for printers without bowden to unload filament from extruder only, + // 0 to disable unloading for manual unloading + #define FILAMENT_CHANGE_LOAD_FEEDRATE 6 // Load filament feedrate in mm/s - filament loading into the bowden tube can be fast + #define FILAMENT_CHANGE_LOAD_LENGTH 0 // Load filament length over hotend in mm + // Longer length for bowden printers to fast load filament into whole bowden tube over the hotend, + // Short or zero length for printers without bowden where loading is not used + #define ADVANCED_PAUSE_EXTRUDE_FEEDRATE 3 // Extrude filament feedrate in mm/s - must be slower than load feedrate + #define ADVANCED_PAUSE_EXTRUDE_LENGTH 50 // Extrude filament length in mm after filament is loaded over the hotend, + // 0 to disable for manual extrusion + // Filament can be extruded repeatedly from the filament exchange menu to fill the hotend, + // or until outcoming filament color is not clear for filament color change + #define PAUSE_PARK_NOZZLE_TIMEOUT 45 // Turn off nozzle if user doesn't change filament within this time limit in seconds + #define FILAMENT_CHANGE_NUMBER_OF_ALERT_BEEPS 5 // Number of alert beeps before printer goes quiet + #define PAUSE_PARK_NO_STEPPER_TIMEOUT // Enable to have stepper motors hold position during filament change + // even if it takes longer than DEFAULT_STEPPER_DEACTIVE_TIME. + //#define PARK_HEAD_ON_PAUSE // Go to filament change position on pause, return to print position on resume + //#define HOME_BEFORE_FILAMENT_CHANGE // Ensure homing has been completed prior to parking for filament change +#endif + +// @section tmc + +/** + * Enable this section if you have TMC26X motor drivers. + * You will need to import the TMC26XStepper library into the Arduino IDE for this + * (https://github.com/trinamic/TMC26XStepper.git) + */ +//#define HAVE_TMCDRIVER + +#if ENABLED(HAVE_TMCDRIVER) + + //#define X_IS_TMC + //#define X2_IS_TMC + //#define Y_IS_TMC + //#define Y2_IS_TMC + //#define Z_IS_TMC + //#define Z2_IS_TMC + //#define E0_IS_TMC + //#define E1_IS_TMC + //#define E2_IS_TMC + //#define E3_IS_TMC + //#define E4_IS_TMC + + #define X_MAX_CURRENT 1000 // in mA + #define X_SENSE_RESISTOR 91 // in mOhms + #define X_MICROSTEPS 16 // number of microsteps + + #define X2_MAX_CURRENT 1000 + #define X2_SENSE_RESISTOR 91 + #define X2_MICROSTEPS 16 + + #define Y_MAX_CURRENT 1000 + #define Y_SENSE_RESISTOR 91 + #define Y_MICROSTEPS 16 + + #define Y2_MAX_CURRENT 1000 + #define Y2_SENSE_RESISTOR 91 + #define Y2_MICROSTEPS 16 + + #define Z_MAX_CURRENT 1000 + #define Z_SENSE_RESISTOR 91 + #define Z_MICROSTEPS 16 + + #define Z2_MAX_CURRENT 1000 + #define Z2_SENSE_RESISTOR 91 + #define Z2_MICROSTEPS 16 + + #define E0_MAX_CURRENT 1000 + #define E0_SENSE_RESISTOR 91 + #define E0_MICROSTEPS 16 + + #define E1_MAX_CURRENT 1000 + #define E1_SENSE_RESISTOR 91 + #define E1_MICROSTEPS 16 + + #define E2_MAX_CURRENT 1000 + #define E2_SENSE_RESISTOR 91 + #define E2_MICROSTEPS 16 + + #define E3_MAX_CURRENT 1000 + #define E3_SENSE_RESISTOR 91 + #define E3_MICROSTEPS 16 + + #define E4_MAX_CURRENT 1000 + #define E4_SENSE_RESISTOR 91 + #define E4_MICROSTEPS 16 + +#endif + +// @section TMC2130 + +/** + * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. + * + * You'll also need the TMC2130Stepper Arduino library + * (https://github.com/teemuatlut/TMC2130Stepper). + * + * To use TMC2130 stepper drivers in SPI mode connect your SPI2130 pins to + * the hardware SPI interface on your board and define the required CS pins + * in your `pins_MYBOARD.h` file. (e.g., RAMPS 1.4 uses AUX3 pins `X_CS_PIN 53`, `Y_CS_PIN 49`, etc.). + */ +//#define HAVE_TMC2130 + +#if ENABLED(HAVE_TMC2130) + + // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY + //#define X_IS_TMC2130 + //#define X2_IS_TMC2130 + //#define Y_IS_TMC2130 + //#define Y2_IS_TMC2130 + //#define Z_IS_TMC2130 + //#define Z2_IS_TMC2130 + //#define E0_IS_TMC2130 + //#define E1_IS_TMC2130 + //#define E2_IS_TMC2130 + //#define E3_IS_TMC2130 + //#define E4_IS_TMC2130 + + /** + * Stepper driver settings + */ + + #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 + #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current + #define INTERPOLATE 1 // Interpolate X/Y/Z_MICROSTEPS to 256 + + #define X_CURRENT 1000 // rms current in mA. Multiply by 1.41 for peak current. + #define X_MICROSTEPS 16 // 0..256 + + #define Y_CURRENT 1000 + #define Y_MICROSTEPS 16 + + #define Z_CURRENT 1000 + #define Z_MICROSTEPS 16 + + //#define X2_CURRENT 1000 + //#define X2_MICROSTEPS 16 + + //#define Y2_CURRENT 1000 + //#define Y2_MICROSTEPS 16 + + //#define Z2_CURRENT 1000 + //#define Z2_MICROSTEPS 16 + + //#define E0_CURRENT 1000 + //#define E0_MICROSTEPS 16 + + //#define E1_CURRENT 1000 + //#define E1_MICROSTEPS 16 + + //#define E2_CURRENT 1000 + //#define E2_MICROSTEPS 16 + + //#define E3_CURRENT 1000 + //#define E3_MICROSTEPS 16 + + //#define E4_CURRENT 1000 + //#define E4_MICROSTEPS 16 + + /** + * Use Trinamic's ultra quiet stepping mode. + * When disabled, Marlin will use spreadCycle stepping mode. + */ + #define STEALTHCHOP + + /** + * Let Marlin automatically control stepper current. + * This is still an experimental feature. + * Increase current every 5s by CURRENT_STEP until stepper temperature prewarn gets triggered, + * then decrease current by CURRENT_STEP until temperature prewarn is cleared. + * Adjusting starts from X/Y/Z/E_CURRENT but will not increase over AUTO_ADJUST_MAX + * 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. + * M906 S1 - Start adjusting current + * M906 S0 - Stop adjusting current + * M911 - Report stepper driver overtemperature pre-warn condition. + * M912 - Clear stepper driver overtemperature pre-warn condition flag. + */ + //#define AUTOMATIC_CURRENT_CONTROL + + #if ENABLED(AUTOMATIC_CURRENT_CONTROL) + #define CURRENT_STEP 50 // [mA] + #define AUTO_ADJUST_MAX 1300 // [mA], 1300mA_rms = 1840mA_peak + #define REPORT_CURRENT_CHANGE + #endif + + /** + * The driver will switch to spreadCycle when stepper speed is over HYBRID_THRESHOLD. + * This mode allows for faster movements at the expense of higher noise levels. + * STEALTHCHOP needs to be enabled. + * M913 X/Y/Z/E to live tune the setting + */ + //#define HYBRID_THRESHOLD + + #define X_HYBRID_THRESHOLD 100 // [mm/s] + #define X2_HYBRID_THRESHOLD 100 + #define Y_HYBRID_THRESHOLD 100 + #define Y2_HYBRID_THRESHOLD 100 + #define Z_HYBRID_THRESHOLD 4 + #define Z2_HYBRID_THRESHOLD 4 + #define E0_HYBRID_THRESHOLD 30 + #define E1_HYBRID_THRESHOLD 30 + #define E2_HYBRID_THRESHOLD 30 + #define E3_HYBRID_THRESHOLD 30 + #define E4_HYBRID_THRESHOLD 30 + + /** + * Use stallGuard2 to sense an obstacle and trigger an endstop. + * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. + * If used along with STEALTHCHOP, the movement will be louder when homing. This is normal. + * + * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. + * Higher values make the system LESS sensitive. + * Lower value make the system MORE sensitive. + * Too low values can lead to false positives, while too high values will collide the axis without triggering. + * It is advised to set X/Y_HOME_BUMP_MM to 0. + * M914 X/Y to live tune the setting + */ + //#define SENSORLESS_HOMING + + #if ENABLED(SENSORLESS_HOMING) + #define X_HOMING_SENSITIVITY 19 + #define Y_HOMING_SENSITIVITY 19 + #endif + + /** + * You can set your own advanced settings by filling in predefined functions. + * A list of available functions can be found on the library github page + * https://github.com/teemuatlut/TMC2130Stepper + * + * Example: + * #define TMC2130_ADV() { \ + * stepperX.diag0_temp_prewarn(1); \ + * stepperX.interpolate(0); \ + * } + */ + #define TMC2130_ADV() { } + +#endif // HAVE_TMC2130 + +// @section L6470 + +/** + * Enable this section if you have L6470 motor drivers. + * You need to import the L6470 library into the Arduino IDE for this. + * (https://github.com/ameyer/Arduino-L6470) + */ + +//#define HAVE_L6470DRIVER +#if ENABLED(HAVE_L6470DRIVER) + + //#define X_IS_L6470 + //#define X2_IS_L6470 + //#define Y_IS_L6470 + //#define Y2_IS_L6470 + //#define Z_IS_L6470 + //#define Z2_IS_L6470 + //#define E0_IS_L6470 + //#define E1_IS_L6470 + //#define E2_IS_L6470 + //#define E3_IS_L6470 + //#define E4_IS_L6470 + + #define X_MICROSTEPS 16 // number of microsteps + #define X_K_VAL 50 // 0 - 255, Higher values, are higher power. Be careful not to go too high + #define X_OVERCURRENT 2000 // maxc current in mA. If the current goes over this value, the driver will switch off + #define X_STALLCURRENT 1500 // current in mA where the driver will detect a stall + + #define X2_MICROSTEPS 16 + #define X2_K_VAL 50 + #define X2_OVERCURRENT 2000 + #define X2_STALLCURRENT 1500 + + #define Y_MICROSTEPS 16 + #define Y_K_VAL 50 + #define Y_OVERCURRENT 2000 + #define Y_STALLCURRENT 1500 + + #define Y2_MICROSTEPS 16 + #define Y2_K_VAL 50 + #define Y2_OVERCURRENT 2000 + #define Y2_STALLCURRENT 1500 + + #define Z_MICROSTEPS 16 + #define Z_K_VAL 50 + #define Z_OVERCURRENT 2000 + #define Z_STALLCURRENT 1500 + + #define Z2_MICROSTEPS 16 + #define Z2_K_VAL 50 + #define Z2_OVERCURRENT 2000 + #define Z2_STALLCURRENT 1500 + + #define E0_MICROSTEPS 16 + #define E0_K_VAL 50 + #define E0_OVERCURRENT 2000 + #define E0_STALLCURRENT 1500 + + #define E1_MICROSTEPS 16 + #define E1_K_VAL 50 + #define E1_OVERCURRENT 2000 + #define E1_STALLCURRENT 1500 + + #define E2_MICROSTEPS 16 + #define E2_K_VAL 50 + #define E2_OVERCURRENT 2000 + #define E2_STALLCURRENT 1500 + + #define E3_MICROSTEPS 16 + #define E3_K_VAL 50 + #define E3_OVERCURRENT 2000 + #define E3_STALLCURRENT 1500 + + #define E4_MICROSTEPS 16 + #define E4_K_VAL 50 + #define E4_OVERCURRENT 2000 + #define E4_STALLCURRENT 1500 + +#endif + +/** + * TWI/I2C BUS + * + * This feature is an EXPERIMENTAL feature so it shall not be used on production + * machines. Enabling this will allow you to send and receive I2C data from slave + * devices on the bus. + * + * ; Example #1 + * ; This macro send the string "Marlin" to the slave device with address 0x63 (99) + * ; It uses multiple M260 commands with one B arg + * M260 A99 ; Target slave address + * M260 B77 ; M + * M260 B97 ; a + * M260 B114 ; r + * M260 B108 ; l + * M260 B105 ; i + * M260 B110 ; n + * M260 S1 ; Send the current buffer + * + * ; Example #2 + * ; Request 6 bytes from slave device with address 0x63 (99) + * M261 A99 B5 + * + * ; Example #3 + * ; Example serial output of a M261 request + * echo:i2c-reply: from:99 bytes:5 data:hello + */ + +// @section i2cbus + +//#define EXPERIMENTAL_I2CBUS +#define I2C_SLAVE_ADDRESS 0 // Set a value from 8 to 127 to act as a slave + +// @section extras + +/** + * Spindle & Laser control + * + * Add the M3, M4, and M5 commands to turn the spindle/laser on and off, and + * to set spindle speed, spindle direction, and laser power. + * + * SuperPid is a router/spindle speed controller used in the CNC milling community. + * Marlin can be used to turn the spindle on and off. It can also be used to set + * the spindle speed from 5,000 to 30,000 RPM. + * + * 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. + */ +//#define SPINDLE_LASER_ENABLE +#if ENABLED(SPINDLE_LASER_ENABLE) + + #define SPINDLE_LASER_ENABLE_INVERT false // set to "true" if the on/off function is reversed + #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 // delay in milliseconds to allow the spindle/laser to come up to speed/power + #define SPINDLE_LASER_POWERDOWN_DELAY 5000 // delay in milliseconds to allow the spindle to stop + #define SPINDLE_DIR_CHANGE true // set to true if your spindle controller supports changing spindle direction + #define SPINDLE_INVERT_DIR false + #define SPINDLE_STOP_ON_DIR_CHANGE true // set to true if Marlin should stop the spindle before changing rotation direction + + /** + * The M3 & M4 commands use the following equation to convert PWM duty cycle to speed/power + * + * SPEED/POWER = PWM duty cycle * SPEED_POWER_SLOPE + SPEED_POWER_INTERCEPT + * where PWM duty cycle varies from 0 to 255 + * + * set the following for your controller (ALL MUST BE SET) + */ + + #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_SLOPE 0.3922 + //#define SPEED_POWER_INTERCEPT 0 + //#define SPEED_POWER_MIN 10 + //#define SPEED_POWER_MAX 100 // 0-100% +#endif + +/** + * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins + */ +//#define PINS_DEBUGGING + +/** + * Auto-report temperatures with M155 S + */ +//#define AUTO_REPORT_TEMPERATURES + +/** + * Include capabilities in M115 output + */ +//#define EXTENDED_CAPABILITIES_REPORT + +/** + * Volumetric extrusion default state + * 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. + */ +//#define VOLUMETRIC_DEFAULT_ON + +/** + * Enable this option for a leaner build of Marlin that removes all + * workspace offsets, simplifying coordinate transformations, leveling, etc. + * + * - M206 and M428 are disabled. + * - G92 will revert to its behavior from Marlin 1.0. + */ +//#define NO_WORKSPACE_OFFSETS + +/** + * 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. + * + * For clients that use a fixed-width font (like OctoPrint), leave this set to 1.0. + * Otherwise, adjust according to your client and font. + */ +#define PROPORTIONAL_FONT_RATIO 1.0 + +/** + * Spend 28 bytes of SRAM to optimize the GCode parser + */ +#define FASTER_GCODE_PARSER + +/** + * User-defined menu items that execute custom GCode + */ +//#define CUSTOM_USER_MENUS +#if ENABLED(CUSTOM_USER_MENUS) + #define USER_SCRIPT_DONE "M117 User Script Done" + #define USER_SCRIPT_AUDIBLE_FEEDBACK + //#define USER_SCRIPT_RETURN // Return to status screen after a script + + #define USER_DESC_1 "Home & UBL Info" + #define USER_GCODE_1 "G28\nG29 W" + + #define USER_DESC_2 "Preheat for PLA" + #define USER_GCODE_2 "M140 S" STRINGIFY(PREHEAT_1_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND) + + #define USER_DESC_3 "Preheat for ABS" + #define USER_GCODE_3 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND) + + #define USER_DESC_4 "Heat Bed/Home/Level" + #define USER_GCODE_4 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nG28\nG29" + + #define USER_DESC_5 "Home & Info" + #define USER_GCODE_5 "G28\nM503" +#endif + +/** + * Specify an action command to send to the host when the printer is killed. + * Will be sent in the form '//action:ACTION_ON_KILL', e.g. '//action:poweroff'. + * The host must be configured to handle the action command. + */ +//#define ACTION_ON_KILL "poweroff" + +//=========================================================================== +//====================== I2C Position Encoder Settings ====================== +//=========================================================================== + +/** + * I2C position encoders for closed loop control. + * Developed by Chris Barr at Aus3D. + * + * Wiki: http://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/ + * + * Reilabuild encoders have been modified to improve reliability. + */ + +//#define I2C_POSITION_ENCODERS +#if ENABLED(I2C_POSITION_ENCODERS) + + #define I2CPE_ENCODER_CNT 1 // The number of encoders installed; max of 5 + // encoders supported currently. + + #define I2CPE_ENC_1_ADDR I2CPE_PRESET_ADDR_X // I2C address of the encoder. 30-200. + #define I2CPE_ENC_1_AXIS X_AXIS // Axis the encoder module is installed on. _AXIS. + #define I2CPE_ENC_1_TYPE I2CPE_ENC_TYPE_LINEAR // Type of encoder: I2CPE_ENC_TYPE_LINEAR -or- + // I2CPE_ENC_TYPE_ROTARY. + #define I2CPE_ENC_1_TICKS_UNIT 2048 // 1024 for magnetic strips with 2mm poles; 2048 for + // 1mm poles. For linear encoders this is ticks / mm, + // for rotary encoders this is ticks / revolution. + //#define I2CPE_ENC_1_TICKS_REV (16 * 200) // Only needed for rotary encoders; number of stepper + // steps per full revolution (motor steps/rev * microstepping) + //#define I2CPE_ENC_1_INVERT // Invert the direction of axis travel. + #define I2CPE_ENC_1_EC_METHOD I2CPE_ECM_NONE // Type of error error correction. + #define I2CPE_ENC_1_EC_THRESH 0.10 // Threshold size for error (in mm) above which the + // printer will attempt to correct the error; errors + // smaller than this are ignored to minimize effects of + // measurement noise / latency (filter). + + #define I2CPE_ENC_2_ADDR I2CPE_PRESET_ADDR_Y // Same as above, but for encoder 2. + #define I2CPE_ENC_2_AXIS Y_AXIS + #define I2CPE_ENC_2_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_ENC_2_TICKS_UNIT 2048 + //#define I2CPE_ENC_2_TICKS_REV (16 * 200) + //#define I2CPE_ENC_2_INVERT + #define I2CPE_ENC_2_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_ENC_2_EC_THRESH 0.10 + + #define I2CPE_ENC_3_ADDR I2CPE_PRESET_ADDR_Z // Encoder 3. Add additional configuration options + #define I2CPE_ENC_3_AXIS Z_AXIS // as above, or use defaults below. + + #define I2CPE_ENC_4_ADDR I2CPE_PRESET_ADDR_E // Encoder 4. + #define I2CPE_ENC_4_AXIS E_AXIS + + #define I2CPE_ENC_5_ADDR 34 // Encoder 5. + #define I2CPE_ENC_5_AXIS E_AXIS + + // Default settings for encoders which are enabled, but without settings configured above. + #define I2CPE_DEF_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_DEF_ENC_TICKS_UNIT 2048 + #define I2CPE_DEF_TICKS_REV (16 * 200) + #define I2CPE_DEF_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_DEF_EC_THRESH 0.1 + + //#define I2CPE_ERR_THRESH_ABORT 100.0 // Threshold size for error (in mm) error on any given + // axis after which the printer will abort. Comment out to + // disable abort behaviour. + + #define I2CPE_TIME_TRUSTED 10000 // After an encoder fault, there must be no further fault + // for this amount of time (in ms) before the encoder + // is trusted again. + + /** + * Position is checked every time a new command is executed from the buffer but during long moves, + * this setting determines the minimum update time between checks. A value of 100 works well with + * error rolling average when attempting to correct only for skips and not for vibration. + */ + #define I2CPE_MIN_UPD_TIME_MS 100 // Minimum time in miliseconds between encoder checks. + + // Use a rolling average to identify persistant errors that indicate skips, as opposed to vibration and noise. + #define I2CPE_ERR_ROLLING_AVERAGE + +#endif // I2C_POSITION_ENCODERS + +/** + * MAX7219 Debug Matrix + * + * Add support for a low-cost 8x8 LED Matrix based on the Max7219 chip, which can be used as a status + * display. Requires 3 signal wires. Some useful debug options are included to demonstrate its usage. + * + * Fully assembled MAX7219 boards can be found on the internet for under $2(US). + * For example, see https://www.ebay.com/sch/i.html?_nkw=332349290049 + */ +//#define MAX7219_DEBUG +#if ENABLED(MAX7219_DEBUG) + #define MAX7219_CLK_PIN 64 // 77 on Re-ARM // Configuration of the 3 pins to control the display + #define MAX7219_DIN_PIN 57 // 78 on Re-ARM + #define MAX7219_LOAD_PIN 44 // 79 on Re-ARM + + /** + * Sample debug features + * If you add more debug displays, be careful to avoid conflicts! + */ + #define MAX7219_DEBUG_PRINTER_ALIVE // Blink corner LED of 8x8 matrix to show that the firmware is functioning + #define MAX7219_DEBUG_STEPPER_HEAD 3 // Show the stepper queue head position on this and the next LED matrix row + #define MAX7219_DEBUG_STEPPER_TAIL 5 // Show the stepper queue tail position on this and the next LED matrix row + + #define MAX7219_DEBUG_STEPPER_QUEUE 0 // Show the current stepper queue depth on this and the next LED matrix row + // If you experience stuttering, reboots, etc. this option can reveal how + // tweaks made to the configuration are affecting the printer in real-time. +#endif + +#endif // CONFIGURATION_ADV_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/Malyan/M150/Configuration.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/Malyan/M150/Configuration.h new file mode 100644 index 00000000..f9a5bb8b --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/Malyan/M150/Configuration.h @@ -0,0 +1,1728 @@ +/** + * 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 . + * + */ + +/** + * Maylan M150 Configuration + * Non-Automatic Bed Level config by default + */ + +/** + * Configuration.h + * + * Basic settings such as: + * + * - Type of electronics + * - Type of temperature sensor + * - Printer geometry + * - Endstop configuration + * - LCD controller + * - Extra features + * + * Advanced settings can be found in Configuration_adv.h + * + */ +#ifndef CONFIGURATION_H +#define CONFIGURATION_H +#define CONFIGURATION_H_VERSION 010100 + +//=========================================================================== +//============================= Getting Started ============================= +//=========================================================================== + +/** + * Here are some standard links for getting your machine calibrated: + * + * http://reprap.org/wiki/Calibration + * http://youtu.be/wAL9d7FgInk + * http://calculator.josefprusa.cz + * http://reprap.org/wiki/Triffid_Hunter%27s_Calibration_Guide + * http://www.thingiverse.com/thing:5573 + * https://sites.google.com/site/repraplogphase/calibration-of-your-reprap + * http://www.thingiverse.com/thing:298812 + */ + +//=========================================================================== +//============================= DELTA Printer =============================== +//=========================================================================== +// For a Delta printer start with one of the configuration files in the +// example_configurations/delta directory and customize for your machine. +// + +//=========================================================================== +//============================= SCARA Printer =============================== +//=========================================================================== +// For a SCARA printer start with the configuration files in +// example_configurations/SCARA and customize for your machine. +// + +// @section info + +// User-specified version info of this build to display in [Pronterface, etc] terminal window during +// startup. Implementation of an idea by Prof Braino to inform user that any changes made to this +// build by the user have been successfully uploaded into firmware. +#define STRING_CONFIG_H_AUTHOR "(Gunther)" // Who made the changes. +#define SHOW_BOOTSCREEN +//#define STRING_SPLASH_LINE1 SHORT_BUILD_VERSION // will be shown during bootup in line 1 +//#define STRING_SPLASH_LINE2 WEBSITE_URL // will be shown during bootup in line 2 + +// +// *** VENDORS PLEASE READ ***************************************************** +// +// Marlin now allow you to have a vendor boot image to be displayed on machine +// start. When SHOW_CUSTOM_BOOTSCREEN is defined Marlin will first show your +// custom boot image and then the default Marlin boot image is shown. +// +// We suggest for you to take advantage of this new feature and keep the Marlin +// boot image unmodified. For an example have a look at the bq Hephestos 2 +// example configuration folder. +// +#define SHOW_CUSTOM_BOOTSCREEN +// @section machine + +/** + * Select which serial port on the board will be used for communication with the host. + * This allows the connection of wireless adapters (for instance) to non-default port pins. + * Serial port 0 is always used by the Arduino bootloader regardless of this setting. + * + * :[0, 1, 2, 3, 4, 5, 6, 7] + */ +#define SERIAL_PORT 0 + +/** + * This setting determines the communication speed of the printer. + * + * 250000 works in most cases, but you might try a lower speed if + * you commonly experience drop-outs during host printing. + * You may try up to 1000000 to speed up SD file transfer. + * + * :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000] + */ +#define BAUDRATE 115200 + +// Enable the Bluetooth serial interface on AT90USB devices +//#define BLUETOOTH + +// The following define selects which electronics board you have. +// Please choose the name from boards.h that matches your setup +#ifndef MOTHERBOARD + #define MOTHERBOARD BOARD_MELZI +#endif + +// Optional custom name for your RepStrap or other custom machine +// Displayed in the LCD "Ready" message +#define CUSTOM_MACHINE_NAME "Malyan M150" + +// Define this to set a unique identifier for this printer, (Used by some programs to differentiate between machines) +// You can use an online service to generate a random UUID. (eg http://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] +#define EXTRUDERS 1 + +// For Cyclops or any "multi-extruder" that shares a single nozzle. +//#define SINGLENOZZLE + +/** + * Průša MK2 Single Nozzle Multi-Material Multiplexer, and variants. + * + * This device allows one stepper driver on a control board to drive + * two to eight stepper motors, one at a time, in a manner suitable + * for extruders. + * + * This option only allows the multiplexer to switch on tool-change. + * Additional options to configure custom E moves are pending. + */ +//#define MK2_MULTIPLEXER +#if ENABLED(MK2_MULTIPLEXER) + // Override the default DIO selector pins here, if needed. + // Some pins files may provide defaults for these pins. + //#define E_MUX0_PIN 40 // Always Required + //#define E_MUX1_PIN 42 // Needed for 3 to 8 steppers + //#define E_MUX2_PIN 44 // Needed for 5 to 8 steppers +#endif + +// A dual extruder that uses a single stepper motor +//#define SWITCHING_EXTRUDER +#if ENABLED(SWITCHING_EXTRUDER) + #define SWITCHING_EXTRUDER_SERVO_NR 0 + #define SWITCHING_EXTRUDER_SERVO_ANGLES { 0, 90 } // Angles for E0, E1[, E2, E3] + #if EXTRUDERS > 3 + #define SWITCHING_EXTRUDER_E23_SERVO_NR 1 + #endif +#endif + +// A dual-nozzle that uses a servomotor to raise/lower one of the nozzles +//#define SWITCHING_NOZZLE +#if ENABLED(SWITCHING_NOZZLE) + #define SWITCHING_NOZZLE_SERVO_NR 0 + #define SWITCHING_NOZZLE_SERVO_ANGLES { 0, 90 } // Angles for E0, E1 + //#define HOTEND_OFFSET_Z { 0.0, 0.0 } +#endif + +/** + * Two separate X-carriages with extruders that connect to a moving part + * via a magnetic docking mechanism. Requires SOL1_PIN and SOL2_PIN. + */ +//#define PARKING_EXTRUDER +#if ENABLED(PARKING_EXTRUDER) + #define PARKING_EXTRUDER_SOLENOIDS_INVERT // If enabled, the solenoid is NOT magnetized with applied voltage + #define PARKING_EXTRUDER_SOLENOIDS_PINS_ACTIVE LOW // LOW or HIGH pin signal energizes the coil + #define PARKING_EXTRUDER_SOLENOIDS_DELAY 250 // Delay (ms) for magnetic field. No delay if 0 or not defined. + #define PARKING_EXTRUDER_PARKING_X { -78, 184 } // X positions for parking the extruders + #define PARKING_EXTRUDER_GRAB_DISTANCE 1 // mm to move beyond the parking point to grab the extruder + #define PARKING_EXTRUDER_SECURITY_RAISE 5 // Z-raise before parking + #define HOTEND_OFFSET_Z { 0.0, 1.3 } // Z-offsets of the two hotends. The first must be 0. +#endif + +/** + * "Mixing Extruder" + * - Adds a new code, M165, to set the current mix factors. + * - Extends the stepping routines to move multiple steppers in proportion to the mix. + * - Optional support for Repetier Firmware M163, M164, and virtual extruder. + * - This implementation supports only a single extruder. + * - Enable DIRECT_MIXING_IN_G1 for Pia Taubert's reference implementation + */ +//#define MIXING_EXTRUDER +#if ENABLED(MIXING_EXTRUDER) + #define MIXING_STEPPERS 2 // Number of steppers in your mixing extruder + #define MIXING_VIRTUAL_TOOLS 16 // Use the Virtual Tool method with M163 and M164 + //#define DIRECT_MIXING_IN_G1 // Allow ABCDHI mix factors in G1 movement commands +#endif + +// Offset of the extruders (uncomment if using more than one and relying on firmware to position when changing). +// The offset has to be X=0, Y=0 for the extruder 0 hotend (default extruder). +// For the other hotends it is their distance from the extruder 0 hotend. +//#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis +//#define HOTEND_OFFSET_Y {0.0, 5.00} // (in mm) for each extruder, offset of the hotend on the Y axis + +// @section machine + +/** + * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN + * + * 0 = No Power Switch + * 1 = ATX + * 2 = X-Box 360 203Watts (the blue wire connected to PS_ON and the red wire to VCC) + * + * :{ 0:'No power switch', 1:'ATX', 2:'X-Box 360' } + */ +#define POWER_SUPPLY 0 + +#if POWER_SUPPLY > 0 + // Enable this option to leave the PSU off at startup. + // Power to steppers and heaters will need to be turned on with M80. + //#define PS_DEFAULT_OFF +#endif + +// @section temperature + +//=========================================================================== +//============================= Thermal Settings ============================ +//=========================================================================== + +/** + * --NORMAL IS 4.7kohm PULLUP!-- 1kohm pullup can be used on hotend sensor, using correct resistor and table + * + * Temperature sensors available: + * + * -3 : thermocouple with MAX31855 (only for sensor 0) + * -2 : thermocouple with MAX6675 (only for sensor 0) + * -1 : thermocouple with AD595 + * 0 : not used + * 1 : 100k thermistor - best choice for EPCOS 100k (4.7k pullup) + * 2 : 200k thermistor - ATC Semitec 204GT-2 (4.7k pullup) + * 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 (Used in ParCan & J-Head) (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) + * 71 : 100k Honeywell thermistor 135-104LAF-J01 (4.7k pullup) + * 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) + * 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" + * 20 : the PT100 circuit found in the Ultimainboard V2.x + * 60 : 100k Maker's Tool Works Kapton Bed Thermistor beta=3950 + * 66 : 4.7M High Temperature thermistor from Dyze Design + * 70 : the 100K thermistor found in the bq Hephestos 2 + * 75 : 100k Generic Silicon Heat Pad with NTC 100K MGB18-104F39050L32 thermistor + * + * 1k ohm pullup tables - This is atypical, and requires changing out the 4.7k pullup for 1k. + * (but gives greater accuracy and more stable PID) + * 51 : 100k thermistor - EPCOS (1k pullup) + * 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 + * 1010 : Pt1000 with 1k pullup (non standard) + * 147 : Pt100 with 4k7 pullup + * 110 : Pt100 with 1k pullup (non standard) + * + * Use these for Testing or Development purposes. NEVER for production machine. + * 998 : Dummy Table that ALWAYS reads 25°C or the temperature defined below. + * 999 : Dummy Table that ALWAYS reads 100°C or the temperature defined below. + * + * :{ '0': "Not used", '1':"100k / 4.7k - EPCOS", '2':"200k / 4.7k - ATC Semitec 204GT-2", '3':"Mendel-parts / 4.7k", '4':"10k !! do not use for a hotend. Bad resolution at high temp. !!", '5':"100K / 4.7k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '6':"100k / 4.7k EPCOS - Not as accurate as Table 1", '7':"100k / 4.7k Honeywell 135-104LAG-J01", '8':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT", '9':"100k / 4.7k GE Sensing AL03006-58.2K-97-G1", '10':"100k / 4.7k RS 198-961", '11':"100k / 4.7k beta 3950 1%", '12':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT (calibrated for Makibox hot bed)", '13':"100k Hisens 3950 1% up to 300°C for hotend 'Simple ONE ' & hotend 'All In ONE'", '20':"PT100 (Ultimainboard V2.x)", '51':"100k / 1k - EPCOS", '52':"200k / 1k - ATC Semitec 204GT-2", '55':"100k / 1k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '60':"100k Maker's Tool Works Kapton Bed Thermistor beta=3950", '66':"Dyze Design 4.7M High Temperature thermistor", '70':"the 100K thermistor found in the bq Hephestos 2", '71':"100k / 4.7k Honeywell 135-104LAF-J01", '147':"Pt100 / 4.7k", '1047':"Pt1000 / 4.7k", '110':"Pt100 / 1k (non-standard)", '1010':"Pt1000 / 1k (non standard)", '-3':"Thermocouple + MAX31855 (only for sensor 0)", '-2':"Thermocouple + MAX6675 (only for sensor 0)", '-1':"Thermocouple + AD595",'998':"Dummy 1", '999':"Dummy 2" } + */ +#define TEMP_SENSOR_0 1 +#define TEMP_SENSOR_1 0 +#define TEMP_SENSOR_2 0 +#define TEMP_SENSOR_3 0 +#define TEMP_SENSOR_4 0 + +// For Malyan M150, some discussions around changing the TEMP_SENSOR_BED from 1 to 3 on a french discussion board. +// The reasons are inconclusive so I leave at 1 +#define TEMP_SENSOR_BED 1 + +// Dummy thermistor constant temperature readings, for use with 998 and 999 +#define DUMMY_THERMISTOR_998_VALUE 25 +#define DUMMY_THERMISTOR_999_VALUE 100 + +// 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 +#define MAX_REDUNDANT_TEMP_SENSOR_DIFF 10 + +// Extruder temperature must be close to target for this long before M109 returns success +#define TEMP_RESIDENCY_TIME 10 // (seconds) +#define TEMP_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// Bed temperature must be close to target for this long before M190 returns success +#define TEMP_BED_RESIDENCY_TIME 10 // (seconds) +#define TEMP_BED_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_BED_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// The minimal temperature defines the temperature below which the heater will not be enabled It is used +// to check that the wiring to the thermistor is not broken. +// Otherwise this would lead to the heater being powered on all the time. +#define HEATER_0_MINTEMP 5 +#define HEATER_1_MINTEMP 5 +#define HEATER_2_MINTEMP 5 +#define HEATER_3_MINTEMP 5 +#define HEATER_4_MINTEMP 5 +#define BED_MINTEMP 5 + +// When temperature exceeds max temp, your heater will be switched off. +// This feature exists to protect your hotend from overheating accidentally, but *NOT* from thermistor short/failure! +// You should use MINTEMP for thermistor short/failure protection. +#define HEATER_0_MAXTEMP 275 +#define HEATER_1_MAXTEMP 275 +#define HEATER_2_MAXTEMP 275 +#define HEATER_3_MAXTEMP 275 +#define HEATER_4_MAXTEMP 275 +#define BED_MAXTEMP 150 + +//=========================================================================== +//============================= PID Settings ================================ +//=========================================================================== +// PID Tuning Guide here: http://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 +#if ENABLED(PIDTEMP) + //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. + //#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. + #define K1 0.95 //smoothing factor within the PID + + // If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it + + // Malyan M150 example + #define DEFAULT_Kp 29 + #define DEFAULT_Ki 2 + #define DEFAULT_Kd 97 + + // 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 + +#endif // PIDTEMP + +//=========================================================================== +//============================= PID > Bed Temperature Control =============== +//=========================================================================== +// Select PID or bang-bang with PIDTEMPBED. If bang-bang, BED_LIMIT_SWITCHING will enable hysteresis +// +// Uncomment this to enable PID on the bed. It uses the same frequency PWM as the extruder. +// If your PID_dT is the default, and correct for your hardware/configuration, that means 7.689Hz, +// which is fine for driving a square wave into a resistive load and does not significantly impact you FET heating. +// This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W heater. +// If your configuration is significantly different than this and you don't understand the issues involved, you probably +// shouldn't use bed PID until someone else verifies your hardware works. +// If this is enabled, find your own PID constants below. +//#define PIDTEMPBED + +//#define BED_LIMIT_SWITCHING + +// This sets the max power delivered to the bed, and replaces the HEATER_BED_DUTY_CYCLE_DIVIDER option. +// all forms of bed control obey this (PID, bang-bang, bang-bang with hysteresis) +// setting this to anything other than 255 enables a form of PWM to the bed just like HEATER_BED_DUTY_CYCLE_DIVIDER did, +// so you shouldn't use it unless you are OK with PWM on your bed. (see the comment on enabling PIDTEMPBED) +#define MAX_BED_POWER 255 // limits duty cycle to bed; 255=full current + +#if ENABLED(PIDTEMPBED) + + //#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) + #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 + +// @section extruder + +// This option prevents extrusion if the temperature is below EXTRUDE_MINTEMP. +// It also enables the M302 command to set the minimum extrusion temperature +// or to allow moving the extruder regardless of the hotend temperature. +// *** IT IS HIGHLY RECOMMENDED TO LEAVE THIS OPTION ENABLED! *** +#define PREVENT_COLD_EXTRUSION +#define EXTRUDE_MINTEMP 170 + +// This option prevents a single extrusion longer than EXTRUDE_MAXLENGTH. +// Note that for Bowden Extruders a too-small value here may prevent loading. +#define PREVENT_LENGTHY_EXTRUDE +#define EXTRUDE_MAXLENGTH 200 + +//=========================================================================== +//======================== Thermal Runaway Protection ======================= +//=========================================================================== + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * If you get "Thermal Runaway" or "Heating failed" errors the + * details can be tuned in Configuration_adv.h + */ + +#define THERMAL_PROTECTION_HOTENDS // Enable thermal protection for all extruders +#define THERMAL_PROTECTION_BED // Enable thermal protection for the heated bed + +//=========================================================================== +//============================= Mechanical Settings ========================= +//=========================================================================== + +// @section machine + +// Uncomment one of these options to enable CoreXY, CoreXZ, or CoreYZ kinematics +// either in the usual order or reversed +//#define COREXY +//#define COREXZ +//#define COREYZ +//#define COREYX +//#define COREZX +//#define COREZY + +//=========================================================================== +//============================== Endstop Settings =========================== +//=========================================================================== + +// @section homing + +// Specify here all the endstop connectors that are connected to any endstop or probe. +// Almost all printers will be using one per axis. Probes will use one or more of the +// extra connectors. Leave undefined any used for non-endstop and non-probe purposes. +#define USE_XMIN_PLUG +#define USE_YMIN_PLUG +#define USE_ZMIN_PLUG +//#define USE_XMAX_PLUG +//#define USE_YMAX_PLUG +//#define USE_ZMAX_PLUG + +// coarse Endstop Settings +#define ENDSTOPPULLUPS // Comment this out (using // at the start of the line) to disable the endstop pullup resistors + +#if DISABLED(ENDSTOPPULLUPS) + // fine endstop settings: Individual pullups. will be ignored if ENDSTOPPULLUPS is defined + //#define ENDSTOPPULLUP_XMAX + //#define ENDSTOPPULLUP_YMAX + //#define ENDSTOPPULLUP_ZMAX + //#define ENDSTOPPULLUP_XMIN + //#define ENDSTOPPULLUP_YMIN + //#define ENDSTOPPULLUP_ZMIN + //#define ENDSTOPPULLUP_ZMIN_PROBE +#endif + +// Mechanical endstop with COM to ground and NC to Signal uses "false" here (most common setup). + +#define X_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Y_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define X_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Y_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MIN_PROBE_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. + +// Enable this feature if all enabled endstop pins are interrupt-capable. +// This will remove the need to poll the interrupt pins, saving many CPU cycles. +//#define ENDSTOP_INTERRUPTS_FEATURE + +//============================================================================= +//============================== Movement Settings ============================ +//============================================================================= +// @section motion + +/** + * Default Settings + * + * These settings can be reset by M502 + * + * Note that if EEPROM is enabled, saved values will override these. + * + * These defaults for the Malyan M150 are low values intended to + * give a baseline. With mods it is possible to raise jerk, etc. + * + */ + +/** + * With this option each E stepper can have its own factors for the + * following movement settings. If fewer factors are given than the + * total number of extruders, the last value applies to the rest. + */ +//#define DISTINCT_E_FACTORS + +/** + * Default Axis Steps Per Unit (steps/mm) + * Override with M92 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ + // Standard M150 17T MXL on X and Y +#define DEFAULT_AXIS_STEPS_PER_UNIT { 3200/34.544, 3200/34.544, 1600, 103.00 } + +// Other common M150 values: +// 16T MXL on X and Y +// #define DEFAULT_AXIS_STEPS_PER_UNIT {3200/32.512, 3200/32.512, 1600, 103.00} +// 16T GT2 on X and Y +// #define DEFAULT_AXIS_STEPS_PER_UNIT {100, 100, 1600, 103.00} + +/** + * Default Max Feed Rate (mm/s) + * Override with M203 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_FEEDRATE { 300, 300, 5, 25 } + +/** + * Default Max Acceleration (change/s) change = mm/s + * (Maximum start speed for accelerated moves) + * Override with M201 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_ACCELERATION { 700, 700, 100, 10000 } + +/** + * Default Acceleration (change/s) change = mm/s + * Override with M204 + * + * M204 P Acceleration + * M204 R Retract Acceleration + * M204 T Travel Acceleration + */ +#define DEFAULT_ACCELERATION 700 // X, Y, Z and E acceleration for printing moves +#define DEFAULT_RETRACT_ACCELERATION 3000 // E acceleration for retracts +#define DEFAULT_TRAVEL_ACCELERATION 700 // X, Y, Z acceleration for travel (non printing) moves + +/** + * Default Jerk (mm/s) + * Override with M205 X Y Z E + * + * "Jerk" specifies the minimum speed change that requires acceleration. + * When changing speed and direction, if the difference is less than the + * value set here, it may happen instantaneously. + */ +#define DEFAULT_XJERK 8.0 +#define DEFAULT_YJERK 8.0 +#define DEFAULT_ZJERK 0.40 +#define DEFAULT_EJERK 5.0 + +//=========================================================================== +//============================= Z Probe Options ============================= +//=========================================================================== +// @section probes + +// +// See http://marlinfw.org/configuration/probes.html +// + +/** + * Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + * + * Enable this option for a probe connected to the Z Min endstop pin. + */ +#define Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + +/** + * Z_MIN_PROBE_ENDSTOP + * + * Enable this option for a probe connected to any pin except Z-Min. + * (By default Marlin assumes the Z-Max endstop pin.) + * To use a custom Z Probe pin, set Z_MIN_PROBE_PIN below. + * + * - The simplest option is to use a free endstop connector. + * - Use 5V for powered (usually inductive) sensors. + * + * - RAMPS 1.3/1.4 boards may use the 5V, GND, and Aux4->D32 pin: + * - For simple switches connect... + * - normally-closed switches to GND and D32. + * - normally-open switches to 5V and D32. + * + * WARNING: Setting the wrong pin may have unexpected and potentially + * disastrous consequences. Use with caution and do your homework. + * + */ +//#define Z_MIN_PROBE_ENDSTOP + +/** + * Probe Type + * + * Allen Key Probes, Servo Probes, Z-Sled Probes, FIX_MOUNTED_PROBE, etc. + * Activate one of these to use Auto Bed Leveling below. + */ + +/** + * The "Manual Probe" provides a means to do "Auto" Bed Leveling without a probe. + * Use G29 repeatedly, adjusting the Z height at each point with movement commands + * or (with LCD_BED_LEVELING) the LCD controller. + */ +//#define PROBE_MANUALLY + +/** + * A Fix-Mounted Probe either doesn't deploy or needs manual deployment. + * (e.g., an inductive probe or a nozzle-based probe-switch.) + */ +//#define FIX_MOUNTED_PROBE + +/** + * Z Servo Probe, such as an endstop switch on a rotating arm. + */ +//#define Z_ENDSTOP_SERVO_NR 0 // Defaults to SERVO 0 connector. +//#define Z_SERVO_ANGLES {70,0} // Z Servo Deploy and Stow angles + +/** + * The BLTouch probe uses a Hall effect sensor and emulates a servo. + */ +//#define BLTOUCH +#if ENABLED(BLTOUCH) + //#define BLTOUCH_DELAY 375 // (ms) Enable and increase if needed +#endif + +/** + * Enable one or more of the following if probing seems unreliable. + * Heaters and/or fans can be disabled during probing to minimize electrical + * noise. A delay can also be added to allow noise and vibration to settle. + * These options are most useful for the BLTouch probe, but may also improve + * readings with inductive probes and piezo sensors. + */ +//#define PROBING_HEATERS_OFF // Turn heaters off when probing +//#define PROBING_FANS_OFF // Turn fans off when probing +//#define DELAY_BEFORE_PROBING 200 // (ms) To prevent vibrations from triggering piezo sensors + +// A probe that is deployed and stowed with a solenoid pin (SOL1_PIN) +//#define SOLENOID_PROBE + +// A sled-mounted probe like those designed by Charles Bell. +//#define Z_PROBE_SLED +//#define SLED_DOCKING_OFFSET 5 // The extra distance the X axis must travel to pickup the sled. 0 should be fine but you can push it further if you'd like. + +// +// For Z_PROBE_ALLEN_KEY see the Delta example configurations. +// + +/** + * Z Probe to nozzle (X,Y) offset, relative to (0, 0). + * X and Y offsets must be integers. + * + * In the following example the X and Y offsets are both positive: + * #define X_PROBE_OFFSET_FROM_EXTRUDER 10 + * #define Y_PROBE_OFFSET_FROM_EXTRUDER 10 + * + * +-- BACK ---+ + * | | + * L | (+) P | R <-- probe (20,20) + * E | | I + * F | (-) N (+) | G <-- nozzle (10,10) + * T | | H + * | (-) | T + * | | + * O-- FRONT --+ + * (0,0) + */ + +// Set for HoolyHoo's probe mount +// http://www.thingiverse.com/thing:1960419 +// Note: HoolyHoo mount is X=35, Y=-50. +//#define X_PROBE_OFFSET_FROM_EXTRUDER 35 // X offset: -left +right [of the nozzle] +//#define Y_PROBE_OFFSET_FROM_EXTRUDER -50 // Y offset: -front +behind [the nozzle] +//#define Z_PROBE_OFFSET_FROM_EXTRUDER 0 // Z offset: -below +above [the nozzle] + +// X and Y axis travel speed (mm/m) between probes +//#define XY_PROBE_SPEED 8000 + +// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +//#define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z + +// Speed for the "accurate" probe of each point +//#define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) + +// Use double touch for probing +//#define PROBE_DOUBLE_TOUCH + +/** + * Z probes require clearance when deploying, stowing, and moving between + * probe points to avoid hitting the bed and other hardware. + * Servo-mounted probes require extra space for the arm to rotate. + * Inductive probes need space to keep from triggering early. + * + * Use these settings to specify the distance (mm) to raise the probe (or + * lower the bed). The values set here apply over and above any (negative) + * probe Z Offset set with Z_PROBE_OFFSET_FROM_EXTRUDER, M851, or the LCD. + * Only integer values >= 1 are valid here. + * + * Example: `M851 Z-5` with a CLEARANCE of 4 => 9mm from bed to nozzle. + * But: `M851 Z+1` with a CLEARANCE of 2 => 2mm from bed to nozzle. + */ +//#define Z_CLEARANCE_DEPLOY_PROBE 10 // Z Clearance for Deploy/Stow +//#define Z_CLEARANCE_BETWEEN_PROBES 5 // Z Clearance between probe points + +// For M851 give a range for adjusting the Z probe offset +//#define Z_PROBE_OFFSET_RANGE_MIN -20 +//#define Z_PROBE_OFFSET_RANGE_MAX 20 + +// Enable the M48 repeatability test to test probe accuracy +//#define Z_MIN_PROBE_REPEATABILITY_TEST + +// For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1 +// :{ 0:'Low', 1:'High' } +#define X_ENABLE_ON 0 +#define Y_ENABLE_ON 0 +#define Z_ENABLE_ON 0 +#define E_ENABLE_ON 0 // For all extruders + +// Disables axis stepper immediately when it's not being used. +// 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 +//#define DISABLE_REDUCED_ACCURACY_WARNING + +// @section extruder + +#define DISABLE_E false // For all extruders +#define DISABLE_INACTIVE_EXTRUDER true // Keep only the active extruder enabled. + +// @section machine + +// Invert the stepper direction. Change (or reverse the motor connector) if an axis goes the wrong way. +#define INVERT_X_DIR false +#define INVERT_Y_DIR false +#define INVERT_Z_DIR false + +// Enable this option for Toshiba stepper drivers +//#define CONFIG_STEPPERS_TOSHIBA + +// @section extruder + +// For direct drive extruder v9 set to true, for geared extruder set to false. +#define INVERT_E0_DIR true +#define INVERT_E1_DIR false +#define INVERT_E2_DIR false +#define INVERT_E3_DIR false +#define INVERT_E4_DIR false + +// @section homing + +//#define NO_MOTION_BEFORE_HOMING // Inhibit movement until all axes have been homed + +//#define Z_HOMING_HEIGHT 4 // (in mm) Minimal z height before homing (G28) for Z clearance above the bed, clamps, ... + // Be sure you have this distance over your Z_MAX_POS in case. + +// Direction of endstops when homing; 1=MAX, -1=MIN +// :[-1,1] +#define X_HOME_DIR -1 +#define Y_HOME_DIR -1 +#define Z_HOME_DIR -1 + +// @section machine + +// The size of the print bed +#define X_BED_SIZE 200 +#define Y_BED_SIZE 200 + +// Travel limits (mm) after homing, corresponding to endstop positions. +#define X_MIN_POS 0 +#define Y_MIN_POS 0 +#define Z_MIN_POS 0 +#define X_MAX_POS X_BED_SIZE +#define Y_MAX_POS Y_BED_SIZE +#define Z_MAX_POS 180 + +// If enabled, axes won't move below MIN_POS in response to movement commands. +#define MIN_SOFTWARE_ENDSTOPS +// If enabled, axes won't move above MAX_POS in response to movement commands. +#define MAX_SOFTWARE_ENDSTOPS + +/** + * Filament Runout Sensor + * A mechanical or opto endstop is used to check for the presence of filament. + * + * RAMPS-based boards use SERVO3_PIN. + * For other boards you may need to define FIL_RUNOUT_PIN. + * By default the firmware assumes HIGH = has filament, LOW = ran out + */ +//#define FILAMENT_RUNOUT_SENSOR +#if ENABLED(FILAMENT_RUNOUT_SENSOR) + #define FIL_RUNOUT_INVERTING false // set to true to invert the logic of the sensor. + #define ENDSTOPPULLUP_FIL_RUNOUT // Uncomment to use internal pullup for filament runout pins if the sensor is defined. + #define FILAMENT_RUNOUT_SCRIPT "M600" +#endif + +//=========================================================================== +//=============================== Bed Leveling ============================== +//=========================================================================== +// @section bedlevel + +/** + * Choose one of the options below to enable G29 Bed Leveling. The parameters + * and behavior of G29 will change depending on your selection. + * + * If using a Probe for Z Homing, enable Z_SAFE_HOMING also! + * + * - AUTO_BED_LEVELING_3POINT + * Probe 3 arbitrary points on the bed (that aren't collinear) + * You specify the XY coordinates of all 3 points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_LINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_BILINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a mesh, best for large or uneven beds. + * + * - AUTO_BED_LEVELING_UBL (Unified Bed Leveling) + * A comprehensive bed leveling system combining the features and benefits + * of other systems. UBL also includes integrated Mesh Generation, Mesh + * Validation and Mesh Editing systems. Currently, UBL is only checked out + * for Cartesian Printers. That said, it was primarily designed to correct + * poor quality Delta Printers. If you feel adventurous and have a Delta, + * please post an issue if something doesn't work correctly. Initially, + * you will need to set a reduced bed size so you have a rectangular area + * to test on. + * + * - MESH_BED_LEVELING + * Probe a grid manually + * The result is a mesh, suitable for large or uneven beds. (See BILINEAR.) + * For machines without a probe, Mesh Bed Leveling provides a method to perform + * leveling in steps so you can manually adjust the Z height at each grid-point. + * With an LCD controller the process is guided step-by-step. + */ + +// - LINEAR - Not Available on Malyan M150 due to compile memory issues +// - Use MESH_BED_LEVELING, AUTO_BED_LEVELING_3POINT or AUTO_BED_LEVELING_BILINEAR + +//#define AUTO_BED_LEVELING_3POINT +//#define AUTO_BED_LEVELING_LINEAR +//#define AUTO_BED_LEVELING_BILINEAR +//#define AUTO_BED_LEVELING_UBL +//#define MESH_BED_LEVELING + +/** + * Enable detailed logging of G28, G29, M48, etc. + * Turn on with the command 'M111 S32'. + * NOTE: Requires a lot of PROGMEM! + */ +//#define DEBUG_LEVELING_FEATURE + +#if ENABLED(MESH_BED_LEVELING) || ENABLED(AUTO_BED_LEVELING_BILINEAR) || ENABLED(AUTO_BED_LEVELING_UBL) + // Gradually reduce leveling correction until a set height is reached, + // at which point movement will be level to the machine's XY plane. + // The height can be set with M420 Z + #define ENABLE_LEVELING_FADE_HEIGHT +#endif + +#if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Set the number of grid points per dimension. + #define GRID_MAX_POINTS_X 3 + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + // Set the boundaries for probing (where the probe can reach). + #define LEFT_PROBE_BED_POSITION 50 + #define RIGHT_PROBE_BED_POSITION 150 + #define FRONT_PROBE_BED_POSITION 50 + #define BACK_PROBE_BED_POSITION 150 + + // The Z probe minimum outer margin (to validate G29 parameters). + #define MIN_PROBE_EDGE 10 + + // Probe along the Y axis, advancing X after each column + //#define PROBE_Y_FIRST + + #if ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Beyond the probed grid, continue the implied tilt? + // Default is to maintain the height of the nearest edge. + //#define EXTRAPOLATE_BEYOND_GRID + + // + // Experimental Subdivision of the grid by Catmull-Rom method. + // Synthesizes intermediate points to produce a more detailed mesh. + // + //#define ABL_BILINEAR_SUBDIVISION + #if ENABLED(ABL_BILINEAR_SUBDIVISION) + // Number of subdivisions between probe points + #define BILINEAR_SUBDIVISIONS 3 + #endif + + #endif + +#elif ENABLED(AUTO_BED_LEVELING_3POINT) + + // 3 arbitrary points to probe. + // A simple cross-product is used to estimate the plane of the bed. + #define ABL_PROBE_PT_1_X 50 + #define ABL_PROBE_PT_1_Y 150 + #define ABL_PROBE_PT_2_X 50 + #define ABL_PROBE_PT_2_Y 50 + #define ABL_PROBE_PT_3_X 150 + #define ABL_PROBE_PT_3_Y 50 + +#elif ENABLED(AUTO_BED_LEVELING_UBL) + + //=========================================================================== + //========================= Unified Bed Leveling ============================ + //=========================================================================== + + #define UBL_MESH_INSET 1 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 10 // Don't use more than 15 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + #define UBL_PROBE_PT_1_X 39 // Probing points for 3-Point leveling of the mesh + #define UBL_PROBE_PT_1_Y 180 + #define UBL_PROBE_PT_2_X 39 + #define UBL_PROBE_PT_2_Y 20 + #define UBL_PROBE_PT_3_X 180 + #define UBL_PROBE_PT_3_Y 20 + + #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation + #define UBL_MESH_EDIT_MOVES_Z // Sophisticated users prefer no movement of nozzle + +#elif ENABLED(MESH_BED_LEVELING) + + //=========================================================================== + //=================================== Mesh ================================== + //=========================================================================== + + #define MESH_INSET 10 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 3 // Don't use more than 7 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + //#define MESH_G28_REST_ORIGIN // After homing all axes ('G28' or 'G28 XYZ') rest Z at Z_MIN_POS + +#endif // BED_LEVELING + +/** + * Use the LCD controller for bed leveling + * Requires MESH_BED_LEVELING or PROBE_MANUALLY + */ +//#define LCD_BED_LEVELING + +#if ENABLED(LCD_BED_LEVELING) + #define MBL_Z_STEP 0.025 // Step size while manually probing Z axis. + #define LCD_PROBE_Z_RANGE 4 // Z Range centered on Z_MIN_POS for LCD Z adjustment +#endif + +// Add a menu item to move between bed corners for manual bed adjustment +//#define LEVEL_BED_CORNERS + +/** + * Commands to execute at the end of G29 probing. + * Useful to retract or move the Z probe out of the way. + */ +//#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) +//#define BED_CENTER_AT_0_0 + +// Manually set the home position. Leave these undefined for automatic settings. +// For DELTA this is the top-center of the Cartesian print volume. +//#define MANUAL_X_HOME_POS 0 +//#define MANUAL_Y_HOME_POS 0 +//#define MANUAL_Z_HOME_POS 0 + +// Use "Z Safe Homing" to avoid homing with a Z probe outside the bed area. +// +// With this feature enabled: +// +// - 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). +// - 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 axis (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). +#endif + +// Homing speeds (mm/m) +#define HOMING_FEEDRATE_XY (50*60) +#define HOMING_FEEDRATE_Z (4*60) + +//============================================================================= +//============================= Additional Features =========================== +//============================================================================= + +// @section extras + +// +// EEPROM +// +// The microcontroller can store settings in the EEPROM, e.g. max velocity... +// M500 - stores parameters in EEPROM +// M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily). +// M502 - reverts to the default "factory settings". You still need to store them in EEPROM afterwards if you want to. +// +#define EEPROM_SETTINGS // Enable for M500 and M501 commands +//#define DISABLE_M503 // Saves ~2700 bytes of PROGMEM. Disable for release! +#define EEPROM_CHITCHAT // Give feedback on EEPROM commands. Disable to save PROGMEM. + +// +// Host Keepalive +// +// When enabled Marlin will send a busy status message to the host +// every couple of seconds when it can't accept commands. +// +#define HOST_KEEPALIVE_FEATURE // Disable this if your host doesn't like keepalive messages +#define DEFAULT_KEEPALIVE_INTERVAL 2 // Number of seconds between "busy" messages. Set with M113. +#define BUSY_WHILE_HEATING // Some hosts require "busy" messages even during heating + +// +// M100 Free Memory Watcher +// +//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose + +// +// G20/G21 Inch mode support +// +//#define INCH_MODE_SUPPORT + +// +// M149 Set temperature units support +// +//#define TEMPERATURE_UNITS_SUPPORT + +// @section temperature + +// Preheat Constants +#define PREHEAT_1_TEMP_HOTEND 205 +#define PREHEAT_1_TEMP_BED 60 +#define PREHEAT_1_FAN_SPEED 128 // Value from 0 to 255 + +#define PREHEAT_2_TEMP_HOTEND 230 +#define PREHEAT_2_TEMP_BED 100 +#define PREHEAT_2_FAN_SPEED 0 // Value from 0 to 255 + +/** + * Nozzle Park -- EXPERIMENTAL + * + * Park the nozzle at the given XYZ position on idle or G27. + * + * The "P" parameter controls the action applied to the Z axis: + * + * P0 (Default) If Z is below park Z raise the nozzle. + * P1 Raise the nozzle always to Z-park height. + * P2 Raise the nozzle by Z-park amount, limited to Z_MAX_POS. + */ +//#define NOZZLE_PARK_FEATURE + +#if ENABLED(NOZZLE_PARK_FEATURE) + // Specify a park position as { X, Y, Z } + #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 } +#endif + +/** + * Clean Nozzle Feature -- EXPERIMENTAL + * + * Adds the G12 command to perform a nozzle cleaning process. + * + * Parameters: + * P Pattern + * S Strokes / Repetitions + * T Triangles (P1 only) + * + * Patterns: + * P0 Straight line (default). This process requires a sponge type material + * at a fixed bed location. "S" specifies strokes (i.e. back-forth motions) + * between the start / end points. + * + * P1 Zig-zag pattern between (X0, Y0) and (X1, Y1), "T" specifies the + * number of zig-zag triangles to do. "S" defines the number of strokes. + * Zig-zags are done in whichever is the narrower dimension. + * For example, "G12 P1 S1 T3" will execute: + * + * -- + * | (X0, Y1) | /\ /\ /\ | (X1, Y1) + * | | / \ / \ / \ | + * A | | / \ / \ / \ | + * | | / \ / \ / \ | + * | (X0, Y0) | / \/ \/ \ | (X1, Y0) + * -- +--------------------------------+ + * |________|_________|_________| + * T1 T2 T3 + * + * P2 Circular pattern with middle at NOZZLE_CLEAN_CIRCLE_MIDDLE. + * "R" specifies the radius. "S" specifies the stroke count. + * Before starting, the nozzle moves to NOZZLE_CLEAN_START_POINT. + * + * Caveats: The ending Z should be the same as starting Z. + * Attention: EXPERIMENTAL. G-code arguments may change. + * + */ +//#define NOZZLE_CLEAN_FEATURE + +#if ENABLED(NOZZLE_CLEAN_FEATURE) + // Default number of pattern repetitions + #define NOZZLE_CLEAN_STROKES 12 + + // Default number of triangles + #define NOZZLE_CLEAN_TRIANGLES 3 + + // Specify positions as { X, Y, Z } + #define NOZZLE_CLEAN_START_POINT { 30, 30, (Z_MIN_POS + 1)} + #define NOZZLE_CLEAN_END_POINT {100, 60, (Z_MIN_POS + 1)} + + // Circular pattern radius + #define NOZZLE_CLEAN_CIRCLE_RADIUS 6.5 + // Circular pattern circle fragments number + #define NOZZLE_CLEAN_CIRCLE_FN 10 + // Middle point of circle + #define NOZZLE_CLEAN_CIRCLE_MIDDLE NOZZLE_CLEAN_START_POINT + + // Moves the nozzle to the initial position + #define NOZZLE_CLEAN_GOBACK +#endif + +/** + * Print Job Timer + * + * Automatically start and stop the print job timer on M104/M109/M190. + * + * M104 (hotend, no wait) - high temp = none, low temp = stop timer + * M109 (hotend, wait) - high temp = start timer, low temp = stop timer + * M190 (bed, wait) - high temp = start timer, low temp = none + * + * The timer can also be controlled with the following commands: + * + * M75 - Start the print job timer + * M76 - Pause the print job timer + * M77 - Stop the print job timer + */ +#define PRINTJOB_TIMER_AUTOSTART + +/** + * Print Counter + * + * Track statistical data such as: + * + * - Total print jobs + * - Total successful print jobs + * - Total failed print jobs + * - Total time printing + * + * View the current statistics with M78. + */ +//#define PRINTCOUNTER + +//============================================================================= +//============================= LCD and SD support ============================ +//============================================================================= + +// @section lcd + +/** + * LCD LANGUAGE + * + * Select the language to display on the LCD. These languages are available: + * + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, + * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * tr, uk, zh_CN, zh_TW, test + * + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + */ +#define LCD_LANGUAGE en + +/** + * LCD Character Set + * + * Note: This option is NOT applicable to Graphical Displays. + * + * All character-based LCDs provide ASCII plus one of these + * language extensions: + * + * - JAPANESE ... the most common + * - WESTERN ... with more accented characters + * - CYRILLIC ... for the Russian language + * + * To determine the language extension installed on your controller: + * + * - Compile and upload with LCD_LANGUAGE set to 'test' + * - 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 + * + * :['JAPANESE', 'WESTERN', 'CYRILLIC'] + */ +#define DISPLAY_CHARSET_HD44780 JAPANESE + +/** + * LCD TYPE + * + * Enable ULTRA_LCD for a 16x2, 16x4, 20x2, or 20x4 character-based LCD. + * Enable DOGLCD for a 128x64 (ST7565R) Full Graphical Display. + * (These options will be enabled automatically for most displays.) + * + * IMPORTANT: The U8glib library is required for Full Graphic Display! + * https://github.com/olikraus/U8glib_Arduino + */ +//#define ULTRA_LCD // Character based +//#define DOGLCD // Full graphics display + +/** + * SD CARD + * + * 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 + +/** + * SD CARD: SPI SPEED + * + * Enable one of the following items for a slower SPI transfer speed. + * This may be required to resolve "volume init" errors. + */ +//#define SPI_SPEED SPI_HALF_SPEED +//#define SPI_SPEED SPI_QUARTER_SPEED +//#define SPI_SPEED SPI_EIGHTH_SPEED + +/** + * SD CARD: ENABLE CRC + * + * Use CRC checks and retries on the SD communication. + */ +//#define SD_CHECK_AND_RETRY + +// +// ENCODER SETTINGS +// +// This option overrides the default number of encoder pulses needed to +// produce one step. Should be increased for high-resolution encoders. +// +//#define ENCODER_PULSES_PER_STEP 1 + +// +// Use this option to override the number of step signals required to +// move between next/prev menu items. +// +//#define ENCODER_STEPS_PER_MENU_ITEM 5 + +/** + * Encoder Direction Options + * + * Test your encoder's behavior first with both options disabled. + * + * Reversed Value Edit and Menu Nav? Enable REVERSE_ENCODER_DIRECTION. + * Reversed Menu Navigation only? Enable REVERSE_MENU_DIRECTION. + * Reversed Value Editing only? Enable BOTH options. + */ + +// +// This option reverses the encoder direction everywhere. +// +// Set this option if CLOCKWISE causes values to DECREASE +// +//#define REVERSE_ENCODER_DIRECTION + +// +// This option reverses the encoder direction for navigating LCD menus. +// +// If CLOCKWISE normally moves DOWN this makes it go UP. +// If CLOCKWISE normally moves UP this makes it go DOWN. +// +//#define REVERSE_MENU_DIRECTION + +// +// Individual Axis Homing +// +// Add individual axis homing items (Home X, Home Y, and Home Z) to the LCD menu. +// +//#define INDIVIDUAL_AXIS_HOMING_MENU + +// +// SPEAKER/BUZZER +// +// If you have a speaker that can produce tones, enable it here. +// By default Marlin assumes you have a buzzer with a fixed frequency. +// +//#define SPEAKER + +// +// The duration and frequency for the UI feedback sound. +// Set these to 0 to disable audio feedback in the LCD menus. +// +// Note: Test audio output with the G-Code: +// M300 S P +// +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 +//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 + +// +// CONTROLLER TYPE: Standard +// +// Marlin supports a wide variety of controllers. +// Enable one of the following options to specify your controller. +// + +// +// ULTIMAKER Controller. +// +//#define ULTIMAKERCONTROLLER + +// +// ULTIPANEL as seen on Thingiverse. +// +//#define ULTIPANEL + +// +// PanelOne from T3P3 (via RAMPS 1.4 AUX2/AUX3) +// http://reprap.org/wiki/PanelOne +// +//#define PANEL_ONE + +// +// MaKr3d Makr-Panel with graphic controller and SD support. +// http://reprap.org/wiki/MaKr3d_MaKrPanel +// +//#define MAKRPANEL + +// +// ReprapWorld Graphical LCD +// https://reprapworld.com/?products_details&products_id/1218 +// +//#define REPRAPWORLD_GRAPHICAL_LCD + +// +// Activate one of these if you have a Panucatt Devices +// Viki 2.0 or mini Viki with Graphic LCD +// http://panucatt.com +// +//#define VIKI2 +//#define miniVIKI + +// +// Adafruit ST7565 Full Graphic Controller. +// https://github.com/eboston/Adafruit-ST7565-Full-Graphic-Controller/ +// +//#define ELB_FULL_GRAPHIC_CONTROLLER + +// +// RepRapDiscount Smart Controller. +// http://reprap.org/wiki/RepRapDiscount_Smart_Controller +// +// Note: Usually sold with a white PCB. +// +//#define REPRAP_DISCOUNT_SMART_CONTROLLER + +// +// GADGETS3D G3D LCD/SD Controller +// http://reprap.org/wiki/RAMPS_1.3/1.4_GADGETS3D_Shield_with_Panel +// +// Note: Usually sold with a blue PCB. +// +//#define G3D_PANEL + +// +// RepRapDiscount FULL GRAPHIC Smart Controller +// http://reprap.org/wiki/RepRapDiscount_Full_Graphic_Smart_Controller +// +#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER + +// +// MakerLab Mini Panel with graphic +// controller and SD support - http://reprap.org/wiki/Mini_panel +// +//#define MINIPANEL + +// +// RepRapWorld REPRAPWORLD_KEYPAD v1.1 +// http://reprapworld.com/?products_details&products_id=202&cPath=1591_1626 +// +// REPRAPWORLD_KEYPAD_MOVE_STEP sets how much should the robot move when a key +// is pressed, a value of 10.0 means 10mm per click. +// +//#define REPRAPWORLD_KEYPAD +//#define REPRAPWORLD_KEYPAD_MOVE_STEP 1.0 + +// +// RigidBot Panel V1.0 +// http://www.inventapart.com/ +// +//#define RIGIDBOT_PANEL + +// +// BQ LCD Smart Controller shipped by +// default with the BQ Hephestos 2 and Witbox 2. +// +//#define BQ_LCD_SMART_CONTROLLER + +// +// Cartesio UI +// http://mauk.cc/webshop/cartesio-shop/electronics/user-interface +// +//#define CARTESIO_UI + +// +// ANET_10 Controller supported displays. +// +//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. + // This LCD is known to be susceptible to electrical interference + // which scrambles the display. Pressing any button clears it up. +//#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 + // A clone of the RepRapDiscount full graphics display but with + // different pins/wiring (see pins_ANET_10.h). + +// +// LCD for Melzi Card with Graphical LCD +// +//#define LCD_FOR_MELZI + +// +// CONTROLLER TYPE: I2C +// +// Note: These controllers require the installation of Arduino's LiquidCrystal_I2C +// library. For more info: https://github.com/kiyoshigawa/LiquidCrystal_I2C +// + +// +// Elefu RA Board Control Panel +// http://www.elefu.com/index.php?route=product/product&product_id=53 +// +//#define RA_CONTROL_PANEL + +// +// Sainsmart YW Robot (LCM1602) LCD Display +// +// Note: This controller requires F.Malpartida's LiquidCrystal_I2C library +// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home +// +//#define LCD_I2C_SAINSMART_YWROBOT + +// +// Generic LCM1602 LCD adapter +// +//#define LCM1602 + +// +// PANELOLU2 LCD with status LEDs, +// separate encoder and click inputs. +// +// Note: This controller requires Arduino's LiquidTWI2 library v1.2.3 or later. +// For more info: https://github.com/lincomatic/LiquidTWI2 +// +// Note: The PANELOLU2 encoder click input can either be directly connected to +// a pin (if BTN_ENC defined to != -1) or read through I2C (when BTN_ENC == -1). +// +//#define LCD_I2C_PANELOLU2 + +// +// Panucatt VIKI LCD with status LEDs, +// integrated click & L/R/U/D buttons, separate encoder inputs. +// +//#define LCD_I2C_VIKI + +// +// SSD1306 OLED full graphics generic display +// +//#define U8GLIB_SSD1306 + +// +// SAV OLEd LCD module support using either SSD1306 or SH1106 based LCD modules +// +//#define SAV_3DGLCD +#if ENABLED(SAV_3DGLCD) + //#define U8GLIB_SSD1306 + #define U8GLIB_SH1106 +#endif + +// +// CONTROLLER TYPE: Shift register panels +// +// 2 wire Non-latching LCD SR from https://goo.gl/aJJ4sH +// LCD configuration: http://reprap.org/wiki/SAV_3D_LCD +// +//#define SAV_3DLCD + +// +// TinyBoy2 128x64 OLED / Encoder Panel +// +//#define OLED_PANEL_TINYBOY2 + +// +// Makeboard 3D Printer Parts 3D Printer Mini Display 1602 Mini Controller +// https://www.aliexpress.com/item/Micromake-Makeboard-3D-Printer-Parts-3D-Printer-Mini-Display-1602-Mini-Controller-Compatible-with-Ramps-1/32765887917.html +// +//#define MAKEBOARD_MINI_2_LINE_DISPLAY_1602 + +// +// MKS MINI12864 with graphic controller and SD support +// http://reprap.org/wiki/MKS_MINI_12864 +// +//#define MKS_MINI_12864 + +// +// Factory display for Creality CR-10 +// https://www.aliexpress.com/item/Universal-LCD-12864-3D-Printer-Display-Screen-With-Encoder-For-CR-10-CR-7-Model/32833148327.html +// +// This is RAMPS-compatible using a single 10-pin connector. +// (For CR-10 owners who want to replace the Melzi Creality board but retain the display) +// +//#define CR10_STOCKDISPLAY + +// +// MKS OLED 1.3" 128 × 64 FULL GRAPHICS CONTROLLER +// http://reprap.org/wiki/MKS_12864OLED +// +// Tiny, but very sharp OLED display +// +//#define MKS_12864OLED + +//============================================================================= +//=============================== Extra Features ============================== +//============================================================================= + +// @section extras + +// Increase the FAN PWM frequency. Removes the PWM noise but increases heating in the FET/Arduino +//#define FAST_PWM_FAN + +// Use software PWM to drive the fan, as for the heaters. This uses a very low frequency +// which is not as annoying as with the hardware PWM. On the other hand, if this frequency +// is too low, you should also increment SOFT_PWM_SCALE. +//#define FAN_SOFT_PWM + +// Incrementing this by 1 will double the software PWM frequency, +// affecting heaters, and the fan if FAN_SOFT_PWM is enabled. +// However, control resolution will be halved for each increment; +// at zero value, there are 128 effective control positions. +#define SOFT_PWM_SCALE 0 + +// If SOFT_PWM_SCALE is set to a value higher than 0, dithering can +// be used to mitigate the associated resolution loss. If enabled, +// some of the PWM cycles are stretched so on average the desired +// duty cycle is attained. +//#define SOFT_PWM_DITHER + +// Temperature status LEDs that display the hotend and bed temperature. +// If all hotends, bed temperature, and target temperature are under 54C +// then the BLUE led is on. Otherwise the RED led is on. (1C hysteresis) +//#define TEMP_STAT_LEDS + +// M240 Triggers a camera by emulating a Canon RC-1 Remote +// Data from: http://www.doc-diy.net/photo/rc-1_hacked/ +//#define PHOTOGRAPH_PIN 23 + +// 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 + +// Support for BlinkM/CyzRgb +//#define BLINKM + +// Support for PCA9632 PWM LED driver +//#define PCA9632 + +/** + * RGB LED / LED Strip Control + * + * Enable support for an RGB LED connected to 5V digital pins, or + * an RGB Strip connected to MOSFETs controlled by digital pins. + * + * 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 overall brightness parameters is also available + * + * *** CAUTION *** + * LED Strips require a MOFSET 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! + * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino + * cannot handle such current, separate 5V power supply must be used + * *** CAUTION *** + * + * LED type. This options are mutualy exclusive. Uncomment only one. + * + */ +//#define RGB_LED +//#define RGBW_LED + +#if ENABLED(RGB_LED) || ENABLED(RGBW_LED) + #define RGB_LED_R_PIN 34 + #define RGB_LED_G_PIN 43 + #define RGB_LED_B_PIN 35 + #define RGB_LED_W_PIN -1 +#endif + +// 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 (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) + #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip + #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time + #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + //#define NEOPIXEL_STARTUP_TEST // Cycle through colors at startup +#endif + +/** + * Printer Event LEDs + * + * During printing, the LEDs will reflect the printer status: + * + * - Gradually change from blue to violet as the heated bed gets to target temp + * - Gradually change from violet to red as the hotend gets to temperature + * - Change to white to illuminate work surface + * - Change to green once print has finished + * - Turn off after the print has finished and the user has pushed a button + */ +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) + #define PRINTER_EVENT_LEDS +#endif + +/*********************************************************************\ +* R/C SERVO support +* Sponsored by TrinityLabs, Reworked by codexmas +**********************************************************************/ + +// Number of servos +// +// If you select a configuration below, this will receive a default value and does not need to be set manually +// set it manually if you have more servos than extruders and wish to manually control some +// leaving it undefined or defining as 0 will disable the servo subsystem +// If unsure, leave commented / disabled +// +//#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command + +// Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. +// 300ms is a good value but you can try less delay. +// If the servo can't reach the requested position, increase it. +#define SERVO_DELAY { 300 } + +// Servo deactivation +// +// With this option servos are powered only during movement, then turned off to prevent jitter. +//#define DEACTIVATE_SERVOS_AFTER_MOVE + +/** + * Filament Width Sensor + * + * Measures the filament width in real-time and adjusts + * flow rate to compensate for any irregularities. + * + * Also allows the measured filament diameter to set the + * extrusion rate, so the slicer only has to specify the + * volume. + * + * Only a single extruder is supported at this time. + * + * 34 RAMPS_14 : Analog input 5 on the AUX2 connector + * 81 PRINTRBOARD : Analog input 2 on the Exp1 connector (version B,C,D,E) + * 301 RAMBO : Analog input 3 + * + * Note: May require analog pins to be defined for other boards. + */ +//#define FILAMENT_WIDTH_SENSOR + +#define DEFAULT_NOMINAL_FILAMENT_DIA 3.00 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. + +#if ENABLED(FILAMENT_WIDTH_SENSOR) + #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) + #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber + + #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading + #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading + #define MAX_MEASUREMENT_DELAY 20 // (bytes) Buffer size for stored measurements (1 byte per cm). Must be larger than MEASUREMENT_DELAY_CM. + + #define DEFAULT_MEASURED_FILAMENT_DIA DEFAULT_NOMINAL_FILAMENT_DIA // Set measured to nominal initially + + // Display filament width on the LCD status line. Status messages will expire after 5 seconds. + //#define FILAMENT_LCD_DISPLAY +#endif + +#endif // CONFIGURATION_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/Malyan/M150/Configuration_adv.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/Malyan/M150/Configuration_adv.h new file mode 100644 index 00000000..f16d9c2c --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/Malyan/M150/Configuration_adv.h @@ -0,0 +1,1424 @@ +/** + * 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 . + * + */ + +/** + * Configuration_adv.h + * + * Advanced settings. + * Only change these if you know exactly what you're doing. + * Some of these settings can damage your printer if improperly set! + * + * Basic settings can be found in Configuration.h + * + */ +#ifndef CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H_VERSION 010100 + +// @section temperature + +//=========================================================================== +//=============================Thermal Settings ============================ +//=========================================================================== + +#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 + #endif +#endif + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * The solution: Once the temperature reaches the target, start observing. + * If the temperature stays too far below the target (hysteresis) for too long (period), + * the firmware will halt the machine as a safety precaution. + * + * If you get false positives for "Thermal Runaway" increase THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD + */ +#if ENABLED(THERMAL_PROTECTION_HOTENDS) + #define THERMAL_PROTECTION_PERIOD 40 // Seconds + #define THERMAL_PROTECTION_HYSTERESIS 4 // Degrees Celsius + + /** + * Whenever an M104 or M109 increases the target temperature the firmware will wait for the + * WATCH_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get false positives for "Heating failed" increase WATCH_TEMP_PERIOD and/or decrease WATCH_TEMP_INCREASE + * WATCH_TEMP_INCREASE should not be below 2. + */ + #define WATCH_TEMP_PERIOD 20 // Seconds + #define WATCH_TEMP_INCREASE 2 // Degrees Celsius +#endif + +/** + * Thermal Protection parameters for the bed are just as above for hotends. + */ +#if ENABLED(THERMAL_PROTECTION_BED) + #define THERMAL_PROTECTION_BED_PERIOD 120 // Seconds + #define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius + + /** + * Whenever an M140 or M190 increases the target temperature the firmware will wait for the + * WATCH_BED_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_BED_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get too many "Heating failed" errors, increase WATCH_BED_TEMP_PERIOD and/or decrease + * WATCH_BED_TEMP_INCREASE. (WATCH_BED_TEMP_INCREASE should not be below 2.) + */ + #define WATCH_BED_TEMP_PERIOD 60 // Seconds + #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius +#endif + +#if ENABLED(PIDTEMP) + // this adds an experimental additional term to the heating power, proportional to the extrusion speed. + // if Kc is chosen well, the additional required power due to increased melting should be compensated. + //#define PID_EXTRUSION_SCALING + #if ENABLED(PID_EXTRUSION_SCALING) + #define DEFAULT_Kc (100) //heating power=Kc*(e_speed) + #define LPQ_MAX_LEN 50 + #endif +#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 + */ +//#define AUTOTEMP +#if ENABLED(AUTOTEMP) + #define AUTOTEMP_OLDWEIGHT 0.98 +#endif + +// Show Temperature ADC value +// Enable for M105 to include ADC values read from temperature sensors. +//#define SHOW_TEMP_ADC_VALUES + +/** + * High Temperature Thermistor Support + * + * Thermistors able to support high temperature tend to have a hard time getting + * good readings at room and lower temperatures. This means HEATER_X_RAW_LO_TEMP + * will probably be caught when the heating element first turns on during the + * preheating process, which will trigger a min_temp_error as a safety measure + * and force stop everything. + * To circumvent this limitation, we allow for a preheat time (during which, + * min_temp_error won't be triggered) and add a min_temp buffer to handle + * aberrant readings. + * + * If you want to enable this feature for your hotend thermistor(s) + * uncomment and set values > 0 in the constants below + */ + +// The number of consecutive low temperature errors that can occur +// before a min_temp_error is triggered. (Shouldn't be more than 10.) +//#define MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED 0 + +// The number of milliseconds a hotend will preheat before starting to check +// the temperature. This value should NOT be set to the time it takes the +// hot end to reach the target temperature, but the time it takes to reach +// the minimum temperature your thermistor can read. The lower the better/safer. +// This shouldn't need to be more than 30 seconds (30000) +//#define MILLISECONDS_PREHEAT_TIME 0 + +// @section extruder + +// Extruder runout prevention. +// If the machine is idle and the temperature over MINTEMP +// then extrude some filament every couple of SECONDS. +//#define EXTRUDER_RUNOUT_PREVENT +#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_EXTRUDE 5 // mm +#endif + +// @section temperature + +//These defines help to calibrate the AD595 sensor in case you get wrong temperature measurements. +//The measured temperature is defined as "actualTemp = (measuredTemp * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET" +#define TEMP_SENSOR_AD595_OFFSET 0.0 +#define TEMP_SENSOR_AD595_GAIN 1.0 + +/** + * 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. + */ +//#define USE_CONTROLLER_FAN +#if ENABLED(USE_CONTROLLER_FAN) + //#define CONTROLLER_FAN_PIN FAN1_PIN // 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 +#endif + +// When first starting the main fan, run it at full speed for the +// given number of milliseconds. This gets the fan spinning reliably +// before setting a PWM value. (Does not work with software PWM for fan on Sanguinololu) +//#define FAN_KICKSTART_TIME 100 + +// This defines the minimal speed for the main fan, run in PWM mode +// to enable uncomment and set minimal PWM speed for reliable running (1-255) +// if fan speed is [1 - (FAN_MIN_PWM-1)] it is set to FAN_MIN_PWM +//#define FAN_MIN_PWM 50 + +// @section extruder + +/** + * Extruder cooling fans + * + * Extruder auto fans automatically turn on when their extruders' + * temperatures go above EXTRUDER_AUTO_FAN_TEMPERATURE. + * + * Your board's pins file specifies the recommended pins. Override those here + * or set to -1 to disable completely. + * + * Multiple extruders can be assigned to the same pin in which case + * the fan will turn on when any selected extruder is above the threshold. + */ +#define E0_AUTO_FAN_PIN -1 +#define E1_AUTO_FAN_PIN -1 +#define E2_AUTO_FAN_PIN -1 +#define E3_AUTO_FAN_PIN -1 +#define E4_AUTO_FAN_PIN -1 +#define EXTRUDER_AUTO_FAN_TEMPERATURE 50 +#define EXTRUDER_AUTO_FAN_SPEED 255 // == full speed + +/** + * Part-Cooling Fan Multiplexer + * + * This feature allows you to digitally multiplex the fan output. + * The multiplexer is automatically switched at tool-change. + * Set FANMUX[012]_PINs below for up to 2, 4, or 8 multiplexed fans. + */ +#define FANMUX0_PIN -1 +#define FANMUX1_PIN -1 +#define FANMUX2_PIN -1 + +/** + * M355 Case Light on-off / brightness + */ +//#define CASE_LIGHT_ENABLE +#if ENABLED(CASE_LIGHT_ENABLE) + //#define CASE_LIGHT_PIN 4 // Override the default pin if needed + #define INVERT_CASE_LIGHT false // Set true if Case Light is ON when pin is LOW + #define CASE_LIGHT_DEFAULT_ON true // Set default power-up state on + #define CASE_LIGHT_DEFAULT_BRIGHTNESS 105 // Set default power-up brightness (0-255, requires PWM pin) + //#define MENU_ITEM_CASE_LIGHT // Add a Case Light option to the LCD main menu +#endif + +//=========================================================================== +//============================ Mechanical Settings ========================== +//=========================================================================== + +// @section homing + +// If you want endstops to stay on (by default) even when not homing +// enable this option. Override at any time with M120, M121. +//#define ENDSTOPS_ALWAYS_ON_DEFAULT + +// @section extras + +//#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. + +// Dual X Steppers +// Uncomment this option to drive two X axis motors. +// The next unused E driver will be assigned to the second X stepper. +//#define X_DUAL_STEPPER_DRIVERS +#if ENABLED(X_DUAL_STEPPER_DRIVERS) + // Set true if the two X motors need to rotate in opposite directions + #define INVERT_X2_VS_X_DIR true +#endif + +// Dual Y Steppers +// Uncomment this option to drive two Y axis motors. +// The next unused E driver will be assigned to the second Y stepper. +//#define Y_DUAL_STEPPER_DRIVERS +#if ENABLED(Y_DUAL_STEPPER_DRIVERS) + // Set true if the two Y motors need to rotate in opposite directions + #define INVERT_Y2_VS_Y_DIR true +#endif + +// A single Z stepper driver is usually used to drive 2 stepper motors. +// Uncomment this option to use a separate stepper driver for each Z axis motor. +// The next unused E driver will be assigned to the second Z stepper. +//#define Z_DUAL_STEPPER_DRIVERS + +#if ENABLED(Z_DUAL_STEPPER_DRIVERS) + + // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper. + // That way the machine is capable to align the bed during home, since both Z steppers are homed. + // There is also an implementation of M666 (software endstops adjustment) to this feature. + // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed. + // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2. + // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive. + // Play a little bit with small adjustments (0.5mm) and check the behaviour. + // The M119 (endstops report) will start reporting the Z2 Endstop as well. + + //#define Z_DUAL_ENDSTOPS + + #if ENABLED(Z_DUAL_ENDSTOPS) + #define Z2_USE_ENDSTOP _XMAX_ + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 // Use M666 to determine/test this value + #endif + +#endif // Z_DUAL_STEPPER_DRIVERS + +// Enable this for dual x-carriage printers. +// A dual x-carriage design has the advantage that the inactive extruder can be parked which +// prevents hot-end ooze contaminating the print. It also reduces the weight of each x-carriage +// allowing faster printing speeds. Connect your X2 stepper to the first unused E plug. +//#define DUAL_X_CARRIAGE +#if ENABLED(DUAL_X_CARRIAGE) + // Configuration for second X-carriage + // Note: the first x-carriage is defined as the x-carriage which homes to the minimum endstop; + // the second x-carriage always homes to the maximum endstop. + #define X2_MIN_POS 80 // set minimum to ensure second x-carriage doesn't hit the parked first X-carriage + #define X2_MAX_POS 353 // set maximum to the distance between toolheads when both heads are homed + #define X2_HOME_DIR 1 // the second X-carriage always homes to the maximum endstop position + #define X2_HOME_POS X2_MAX_POS // default home position is the maximum carriage position + // However: In this mode the HOTEND_OFFSET_X value for the second extruder provides a software + // override for X2_HOME_POS. This also allow recalibration of the distance between the two endstops + // without modifying the firmware (through the "M218 T1 X???" command). + // Remember: you should set the second extruder x-offset to 0 in your slicer. + + // There are a few selectable movement modes for dual x-carriages using M605 S + // Mode 0 (DXC_FULL_CONTROL_MODE): Full control. The slicer has full control over both x-carriages and can achieve optimal travel results + // as long as it supports dual x-carriages. (M605 S0) + // Mode 1 (DXC_AUTO_PARK_MODE) : Auto-park mode. The firmware will automatically park and unpark the x-carriages on tool changes so + // that additional slicer support is not required. (M605 S1) + // Mode 2 (DXC_DUPLICATION_MODE) : Duplication mode. The firmware will transparently make the second x-carriage and extruder copy all + // actions of the first x-carriage. This allows the printer to print 2 arbitrary items at + // once. (2nd extruder x offset and temp offset are set using: M605 S2 [Xnnn] [Rmmm]) + + // This is the default power-up mode which can be later using M605. + #define DEFAULT_DUAL_X_CARRIAGE_MODE DXC_FULL_CONTROL_MODE + + // Default settings in "Auto-park Mode" + #define TOOLCHANGE_PARK_ZLIFT 0.2 // the distance to raise Z axis when parking an extruder + #define TOOLCHANGE_UNPARK_ZLIFT 1 // the distance to raise Z axis when unparking an extruder + + // Default x offset in duplication mode (typically set to half print bed width) + #define DEFAULT_DUPLICATION_X_OFFSET 100 + +#endif // DUAL_X_CARRIAGE + +// 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. +//#define EXT_SOLENOID + +// @section homing + +//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +#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 this is defined, if both x and y are to be homed, a diagonal move will be performed initially. + +// When G28 is called, this option will make Y home before X +//#define HOME_Y_BEFORE_X + +// @section machine + +#define AXIS_RELATIVE_MODES {false, false, false, false} + +// Allow duplication mode with a basic dual-nozzle extruder +//#define DUAL_NOZZLE_DUPLICATION_MODE + +// By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step. +#define INVERT_X_STEP_PIN false +#define INVERT_Y_STEP_PIN false +#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. +#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_E true + +#define DEFAULT_MINIMUMFEEDRATE 0.0 // minimum feedrate +#define DEFAULT_MINTRAVELFEEDRATE 0.0 + +//#define HOME_AFTER_DEACTIVATE // Require rehoming after steppers are deactivated + +// @section lcd + +#if ENABLED(ULTIPANEL) + #define MANUAL_FEEDRATE {50*60, 50*60, 4*60, 60} // Feedrates for manual moves along X, Y, Z, E from panel + #define ULTIPANEL_FEEDMULTIPLY // Comment to disable setting feedrate multiplier via encoder +#endif + +// @section extras + +// minimum time in microseconds that a movement needs to take if the buffer is emptied. +#define DEFAULT_MINSEGMENTTIME 20000 + +// If defined the movements slow down when the look ahead buffer is only half full +#define SLOWDOWN + +// Frequency limit +// See nophead's blog for more info +// Not working O +//#define XY_FREQUENCY_LIMIT 15 + +// 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 +// if unwanted behavior is observed on a user's machine when running at very slow speeds. +#define MINIMUM_PLANNER_SPEED 0.05 // (mm/sec) + +// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU. +#define MICROSTEP_MODES {16,16,16,16,16} // [1,2,4,8,16] + +/** + * @section stepper motor current + * + * Some boards have a means of setting the stepper motor current via firmware. + * + * The power on motor currents are set by: + * PWM_MOTOR_CURRENT - used by MINIRAMBO & ULTIMAIN_2 + * known compatible chips: A4982 + * DIGIPOT_MOTOR_CURRENT - used by BQ_ZUM_MEGA_3D, RAMBO & SCOOVO_X9H + * known compatible chips: AD5206 + * DAC_MOTOR_CURRENT_DEFAULT - used by PRINTRBOARD_REVF & RIGIDBOARD_V2 + * known compatible chips: MCP4728 + * DIGIPOT_I2C_MOTOR_CURRENTS - used by 5DPRINT, AZTEEG_X3_PRO, MIGHTYBOARD_REVE + * known compatible chips: MCP4451, MCP4018 + * + * Motor currents can also be set by M907 - M910 and by the LCD. + * M907 - applies to all. + * M908 - BQ_ZUM_MEGA_3D, RAMBO, PRINTRBOARD_REVF, RIGIDBOARD_V2 & SCOOVO_X9H + * M909, M910 & LCD - only PRINTRBOARD_REVF & RIGIDBOARD_V2 + */ +//#define PWM_MOTOR_CURRENT { 1300, 1300, 1250 } // Values in milliamps +//#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 + +// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +//#define DIGIPOT_I2C +//#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster +#define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 +// Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS +#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=========================== +//=========================================================================== + +#define ENCODER_RATE_MULTIPLIER // If defined, certain menu edit operations automatically multiply the steps when the encoder is moved quickly +#define ENCODER_10X_STEPS_PER_SEC 75 // If the encoder steps per sec exceeds this value, multiply steps moved x10 to quickly advance the value +#define ENCODER_100X_STEPS_PER_SEC 300 // If the encoder steps per sec exceeds this value, multiply steps moved x100 to really quickly advance the value + +//#define CHDK 4 //Pin for triggering CHDK to take a picture see how to use it here http://captain-slow.dk/2014/03/09/3d-printing-timelapses/ +#define CHDK_DELAY 50 //How long in ms the pin should stay HIGH before going LOW again + +// @section lcd + +// Include a page of printer information in the LCD Main Menu +//#define LCD_INFO_MENU + +// Scroll a longer status message into view +//#define STATUS_MESSAGE_SCROLLING + +// On the Info Screen, display XY with one decimal place when possible +//#define LCD_DECIMAL_SMALL_XY + +// The timeout (in ms) to return to the status screen from sub-menus +//#define LCD_TIMEOUT_TO_STATUS 15000 + +#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 + + #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? + #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. + + #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. + // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. + // using: + //#define MENU_ADDAUTOSTART + + /** + * Sort SD file listings in alphabetical order. + * + * With this option enabled, items on SD cards will be sorted + * by name for easier navigation. + * + * By default... + * + * - Use the slowest -but safest- method for sorting. + * - Folders are sorted to the top. + * - The sort key is statically allocated. + * - No added G-code (M34) support. + * - 40 item sorting limit. (Items after the first 40 are unsorted.) + * + * SD sorting uses static allocation (as set by SDSORT_LIMIT), allowing the + * compiler to calculate the worst-case usage and throw an error if the SRAM + * limit is exceeded. + * + * - SDSORT_USES_RAM provides faster sorting via a static directory buffer. + * - SDSORT_USES_STACK does the same, but uses a local stack-based buffer. + * - SDSORT_CACHE_NAMES will retain the sorted file listing in RAM. (Expensive!) + * - SDSORT_DYNAMIC_RAM only uses RAM when the SD menu is visible. (Use with caution!) + */ + //#define SDCARD_SORT_ALPHA + + // SD Card Sorting options + #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_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. + #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #endif + + // Show a progress bar on HD44780 LCDs for SD printing + //#define LCD_PROGRESS_BAR + + #if ENABLED(LCD_PROGRESS_BAR) + // Amount of time (ms) to show the bar + #define PROGRESS_BAR_BAR_TIME 2000 + // Amount of time (ms) to show the status message + #define PROGRESS_BAR_MSG_TIME 3000 + // Amount of time (ms) to retain the status message (0=forever) + #define PROGRESS_MSG_EXPIRE 0 + // Enable this to show messages for MSG_TIME then hide them + //#define PROGRESS_MSG_ONCE + // Add a menu item to test the progress bar: + //#define LCD_PROGRESS_BAR_TEST + #endif + + // This allows hosts to request long names for files and folders with M33 + #define LONG_FILENAME_HOST_SUPPORT + + // This option allows you to abort SD printing when any endstop is triggered. + // This feature must be enabled with "M540 S1" or from the LCD menu. + // To have any effect, endstops must be enabled during SD printing. + //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + +#endif // SDSUPPORT + +/** + * Additional options for Graphical Displays + * + * Use the optimizations here to improve printing performance, + * which can be adversely affected by graphical display drawing, + * especially when doing several short moves, and when printing + * on DELTA and SCARA machines. + * + * Some of these options may result in the display lagging behind + * controller events, as there is a trade-off between reliable + * printing performance versus fast display updates. + */ +#if ENABLED(DOGLCD) + // Enable to save many cycles by drawing a hollow frame on the Info Screen + #define XYZ_HOLLOW_FRAME + + // Enable to save many cycles by drawing a hollow frame on Menu Screens + #define MENU_HOLLOW_FRAME + + // A bigger font is available for edit items. Costs 3120 bytes of PROGMEM. + // 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. + // 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 +#endif // DOGLCD + +// @section safety + +// The hardware watchdog should reset the microcontroller disabling all outputs, +// in case the firmware gets stuck and doesn't do temperature regulation. +#define USE_WATCHDOG + +#if ENABLED(USE_WATCHDOG) + // If you have a watchdog reboot in an ArduinoMega2560 then the device will hang forever, as a watchdog reset will leave the watchdog on. + // The "WATCHDOG_RESET_MANUAL" goes around this by not using the hardware reset. + // However, THIS FEATURE IS UNSAFE!, as it will only work if interrupts are disabled. And the code could hang in an interrupt routine with interrupts disabled. + //#define WATCHDOG_RESET_MANUAL +#endif + +// @section lcd + +/** + * Babystepping enables movement of the axes by tiny increments without changing + * the current position values. This feature is used primarily to adjust the Z + * axis in the first layer of a print in real-time. + * + * Warning: Does not respect endstops! + */ +//#define BABYSTEPPING +#if ENABLED(BABYSTEPPING) + //#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 100 // Babysteps are very small. Increase for faster motion. + //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping + //#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen 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_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor + //#define BABYSTEP_ZPROBE_GFX_REVERSE // Reverses the direction of the CW/CCW indicators +#endif + +// @section extruder + +/** + * Implementation of linear pressure control + * + * Assumption: advance = k * (delta velocity) + * K=0 means advance disabled. + * See Marlin documentation for calibration instructions. + */ +//#define LIN_ADVANCE + +#if ENABLED(LIN_ADVANCE) + #define LIN_ADVANCE_K 75 + + /** + * Some Slicers produce Gcode with randomly jumping extrusion widths occasionally. + * For example within a 0.4mm perimeter it may produce a single segment of 0.05mm width. + * While this is harmless for normal printing (the fluid nature of the filament will + * close this very, very tiny gap), it throws off the LIN_ADVANCE pressure adaption. + * + * For this case LIN_ADVANCE_E_D_RATIO can be used to set the extrusion:distance ratio + * to a fixed value. Note that using a fixed ratio will lead to wrong nozzle pressures + * if the slicer is using variable widths or layer heights within one print! + * + * This option sets the default E:D ratio at startup. Use `M900` to override this value. + * + * Example: `M900 W0.4 H0.2 D1.75`, where: + * - W is the extrusion width in mm + * - H is the layer height in mm + * - D is the filament diameter in mm + * + * Example: `M900 R0.0458` to set the ratio directly. + * + * Set to 0 to auto-detect the ratio based on given Gcode G1 print moves. + * + * Slic3r (including Průša Control) produces Gcode compatible with the automatic mode. + * Cura (as of this writing) may produce Gcode incompatible with the automatic mode. + */ + #define LIN_ADVANCE_E_D_RATIO 0 // The calculated ratio (or 0) according to the formula W * H / ((D / 2) ^ 2 * PI) + // Example: 0.4 * 0.2 / ((1.75 / 2) ^ 2 * PI) = 0.033260135 +#endif + +// @section leveling + +// Default mesh area is an area with an inset margin on the print area. +// Below are the macros that are used to define the borders for the mesh area, +// made available here for specialized needs, ie dual extruder setup. +#if ENABLED(MESH_BED_LEVELING) + #define MESH_MIN_X MESH_INSET + #define MESH_MAX_X (X_BED_SIZE - (MESH_INSET)) + #define MESH_MIN_Y MESH_INSET + #define MESH_MAX_Y (Y_BED_SIZE - (MESH_INSET)) +#elif ENABLED(AUTO_BED_LEVELING_UBL) + #define UBL_MESH_MIN_X UBL_MESH_INSET + #define UBL_MESH_MAX_X (X_BED_SIZE - (UBL_MESH_INSET)) + #define UBL_MESH_MIN_Y UBL_MESH_INSET + #define UBL_MESH_MAX_Y (Y_BED_SIZE - (UBL_MESH_INSET)) + + // If this is defined, the currently active mesh will be saved in the + // current slot on M500. + #define UBL_SAVE_ACTIVE_ON_M500 +#endif + +// @section extras + +// +// G2/G3 Arc Support +// +#define ARC_SUPPORT // Disable this feature to save ~3226 bytes +#if ENABLED(ARC_SUPPORT) + #define MM_PER_ARC_SEGMENT 1 // Length of each arc segment + #define N_ARC_CORRECTION 25 // Number of intertpolated 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 +#endif + +// Support for G5 with XYZE destination and IJPQ offsets. Requires ~2666 bytes. +//#define BEZIER_CURVE_SUPPORT + +// G38.2 and G38.3 Probe Target +// Enable PROBE_DOUBLE_TOUCH if you want G38 to double touch +//#define G38_PROBE_TARGET +#if ENABLED(G38_PROBE_TARGET) + #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) +#endif + +// Moves (or segments) with fewer steps than this will be joined with the next move +#define MIN_STEPS_PER_SEGMENT 6 + +// The minimum pulse width (in µs) for stepping a stepper. +// Set this if you find stepping unreliable, or if using a very fast CPU. +#define MINIMUM_STEPPER_PULSE 0 // (µs) The smallest stepper pulse allowed + +// @section temperature + +// Control heater 0 and heater 1 in parallel. +//#define HEATERS_PARALLEL + +//=========================================================================== +//================================= Buffers ================================= +//=========================================================================== + +// @section hidden + +// 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, i.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 +#else + #define BLOCK_BUFFER_SIZE 16 // maximize block buffer +#endif + +// @section serial + +// The ASCII buffer for serial input +#define MAX_CMD_SIZE 96 +#define BUFSIZE 4 + +// Transmission to Host Buffer Size +// To save 386 bytes of PROGMEM (and TX_BUFFER_SIZE+3 bytes of RAM) set to 0. +// To buffer a simple "ok" you need 4 bytes. +// For ADVANCED_OK (M105) you need 32 bytes. +// For debug-echo: 128 bytes for the optimal speed. +// Other output doesn't need to be that speedy. +// :[0, 2, 4, 8, 16, 32, 64, 128, 256] +#define TX_BUFFER_SIZE 0 + +// Host Receive Buffer Size +// Without XON/XOFF flow control (see SERIAL_XON_XOFF below) 32 bytes should be enough. +// To use flow control, set this buffer size to at least 1024 bytes. +// :[0, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048] +//#define RX_BUFFER_SIZE 1024 + +#if RX_BUFFER_SIZE >= 1024 + // Enable to have the controller send XON/XOFF control characters to + // the host to signal the RX buffer is becoming full. + //#define SERIAL_XON_XOFF +#endif + +#if ENABLED(SDSUPPORT) + // Enable this option to collect and display the maximum + // RX queue usage after transferring a file to SD. + //#define SERIAL_STATS_MAX_RX_QUEUED + + // Enable this option to collect and display the number + // of dropped bytes after a file transfer to SD. + //#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! +//#define EMERGENCY_PARSER + +// Bad Serial-connections can miss a received command by sending an 'ok' +// Therefore some clients abort after 30 seconds in a timeout. +// Some other clients start sending commands while receiving a 'wait'. +// This "wait" is only sent when the buffer is empty. 1 second is a good value here. +//#define NO_TIMEOUTS 1000 // Milliseconds + +// Some clients will have this feature soon. This could make the NO_TIMEOUTS unnecessary. +//#define ADVANCED_OK + +// @section extras + +/** + * Firmware-based and LCD-controlled retract + * + * Add G10 / G11 commands for automatic firmware-based retract / recover. + * Use M207 and M208 to define parameters for retract / recover. + * + * Use M209 to enable or disable auto-retract. + * With auto-retract enabled, all G1 E moves within the set range + * will be converted to firmware-based retract/recover moves. + * + * Be sure to turn off auto-retract during filament change. + * + * Note that M207 / M208 / M209 settings are saved to EEPROM. + * + */ +//#define FWRETRACT // ONLY PARTIALLY TESTED +#if ENABLED(FWRETRACT) + #define MIN_AUTORETRACT 0.1 // When auto-retract is on, convert E moves of this length and over + #define MAX_AUTORETRACT 10.0 // Upper limit for auto-retract conversion + #define RETRACT_LENGTH 3 // Default retract length (positive mm) + #define RETRACT_LENGTH_SWAP 13 // Default swap retract length (positive mm), for extruder change + #define RETRACT_FEEDRATE 45 // Default feedrate for retracting (mm/s) + #define RETRACT_ZLIFT 0 // Default retract Z-lift + #define RETRACT_RECOVER_LENGTH 0 // Default additional recover length (mm, added to retract length when recovering) + #define RETRACT_RECOVER_LENGTH_SWAP 0 // Default additional swap recover length (mm, added to retract length when recovering from extruder change) + #define RETRACT_RECOVER_FEEDRATE 8 // Default feedrate for recovering from retraction (mm/s) + #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) +#endif + +/** + * Advanced Pause + * Experimental feature for filament change support and for parking the nozzle when paused. + * Adds the GCode M600 for initiating filament change. + * If PARK_HEAD_ON_PAUSE enabled, adds the GCode M125 to pause printing and park the nozzle. + * + * Requires an LCD display. + * This feature is required for the default FILAMENT_RUNOUT_SCRIPT. + */ +//#define ADVANCED_PAUSE_FEATURE +#if ENABLED(ADVANCED_PAUSE_FEATURE) + #define PAUSE_PARK_X_POS 3 // X position of hotend + #define PAUSE_PARK_Y_POS 3 // Y position of hotend + #define PAUSE_PARK_Z_ADD 10 // Z addition of hotend (lift) + #define PAUSE_PARK_XY_FEEDRATE 100 // X and Y axes feedrate in mm/s (also used for delta printers Z axis) + #define PAUSE_PARK_Z_FEEDRATE 5 // Z axis feedrate in mm/s (not used for delta printers) + #define PAUSE_PARK_RETRACT_FEEDRATE 60 // Initial retract feedrate in mm/s + #define PAUSE_PARK_RETRACT_LENGTH 2 // Initial retract in mm + // It is a short retract used immediately after print interrupt before move to filament exchange position + #define FILAMENT_CHANGE_UNLOAD_FEEDRATE 10 // Unload filament feedrate in mm/s - filament unloading can be fast + #define FILAMENT_CHANGE_UNLOAD_LENGTH 100 // Unload filament length from hotend in mm + // Longer length for bowden printers to unload filament from whole bowden tube, + // shorter length for printers without bowden to unload filament from extruder only, + // 0 to disable unloading for manual unloading + #define FILAMENT_CHANGE_LOAD_FEEDRATE 6 // Load filament feedrate in mm/s - filament loading into the bowden tube can be fast + #define FILAMENT_CHANGE_LOAD_LENGTH 0 // Load filament length over hotend in mm + // Longer length for bowden printers to fast load filament into whole bowden tube over the hotend, + // Short or zero length for printers without bowden where loading is not used + #define ADVANCED_PAUSE_EXTRUDE_FEEDRATE 3 // Extrude filament feedrate in mm/s - must be slower than load feedrate + #define ADVANCED_PAUSE_EXTRUDE_LENGTH 50 // Extrude filament length in mm after filament is loaded over the hotend, + // 0 to disable for manual extrusion + // Filament can be extruded repeatedly from the filament exchange menu to fill the hotend, + // or until outcoming filament color is not clear for filament color change + #define PAUSE_PARK_NOZZLE_TIMEOUT 45 // Turn off nozzle if user doesn't change filament within this time limit in seconds + #define FILAMENT_CHANGE_NUMBER_OF_ALERT_BEEPS 5 // Number of alert beeps before printer goes quiet + #define PAUSE_PARK_NO_STEPPER_TIMEOUT // Enable to have stepper motors hold position during filament change + // even if it takes longer than DEFAULT_STEPPER_DEACTIVE_TIME. + //#define PARK_HEAD_ON_PAUSE // Go to filament change position on pause, return to print position on resume + //#define HOME_BEFORE_FILAMENT_CHANGE // Ensure homing has been completed prior to parking for filament change +#endif + +// @section tmc + +/** + * Enable this section if you have TMC26X motor drivers. + * You will need to import the TMC26XStepper library into the Arduino IDE for this + * (https://github.com/trinamic/TMC26XStepper.git) + */ +//#define HAVE_TMCDRIVER + +#if ENABLED(HAVE_TMCDRIVER) + + //#define X_IS_TMC + //#define X2_IS_TMC + //#define Y_IS_TMC + //#define Y2_IS_TMC + //#define Z_IS_TMC + //#define Z2_IS_TMC + //#define E0_IS_TMC + //#define E1_IS_TMC + //#define E2_IS_TMC + //#define E3_IS_TMC + //#define E4_IS_TMC + + #define X_MAX_CURRENT 1000 // in mA + #define X_SENSE_RESISTOR 91 // in mOhms + #define X_MICROSTEPS 16 // number of microsteps + + #define X2_MAX_CURRENT 1000 + #define X2_SENSE_RESISTOR 91 + #define X2_MICROSTEPS 16 + + #define Y_MAX_CURRENT 1000 + #define Y_SENSE_RESISTOR 91 + #define Y_MICROSTEPS 16 + + #define Y2_MAX_CURRENT 1000 + #define Y2_SENSE_RESISTOR 91 + #define Y2_MICROSTEPS 16 + + #define Z_MAX_CURRENT 1000 + #define Z_SENSE_RESISTOR 91 + #define Z_MICROSTEPS 16 + + #define Z2_MAX_CURRENT 1000 + #define Z2_SENSE_RESISTOR 91 + #define Z2_MICROSTEPS 16 + + #define E0_MAX_CURRENT 1000 + #define E0_SENSE_RESISTOR 91 + #define E0_MICROSTEPS 16 + + #define E1_MAX_CURRENT 1000 + #define E1_SENSE_RESISTOR 91 + #define E1_MICROSTEPS 16 + + #define E2_MAX_CURRENT 1000 + #define E2_SENSE_RESISTOR 91 + #define E2_MICROSTEPS 16 + + #define E3_MAX_CURRENT 1000 + #define E3_SENSE_RESISTOR 91 + #define E3_MICROSTEPS 16 + + #define E4_MAX_CURRENT 1000 + #define E4_SENSE_RESISTOR 91 + #define E4_MICROSTEPS 16 + +#endif + +// @section TMC2130 + +/** + * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. + * + * You'll also need the TMC2130Stepper Arduino library + * (https://github.com/teemuatlut/TMC2130Stepper). + * + * To use TMC2130 stepper drivers in SPI mode connect your SPI2130 pins to + * the hardware SPI interface on your board and define the required CS pins + * in your `pins_MYBOARD.h` file. (e.g., RAMPS 1.4 uses AUX3 pins `X_CS_PIN 53`, `Y_CS_PIN 49`, etc.). + */ +//#define HAVE_TMC2130 + +#if ENABLED(HAVE_TMC2130) + + // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY + //#define X_IS_TMC2130 + //#define X2_IS_TMC2130 + //#define Y_IS_TMC2130 + //#define Y2_IS_TMC2130 + //#define Z_IS_TMC2130 + //#define Z2_IS_TMC2130 + //#define E0_IS_TMC2130 + //#define E1_IS_TMC2130 + //#define E2_IS_TMC2130 + //#define E3_IS_TMC2130 + //#define E4_IS_TMC2130 + + /** + * Stepper driver settings + */ + + #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 + #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current + #define INTERPOLATE 1 // Interpolate X/Y/Z_MICROSTEPS to 256 + + #define X_CURRENT 1000 // rms current in mA. Multiply by 1.41 for peak current. + #define X_MICROSTEPS 16 // 0..256 + + #define Y_CURRENT 1000 + #define Y_MICROSTEPS 16 + + #define Z_CURRENT 1000 + #define Z_MICROSTEPS 16 + + //#define X2_CURRENT 1000 + //#define X2_MICROSTEPS 16 + + //#define Y2_CURRENT 1000 + //#define Y2_MICROSTEPS 16 + + //#define Z2_CURRENT 1000 + //#define Z2_MICROSTEPS 16 + + //#define E0_CURRENT 1000 + //#define E0_MICROSTEPS 16 + + //#define E1_CURRENT 1000 + //#define E1_MICROSTEPS 16 + + //#define E2_CURRENT 1000 + //#define E2_MICROSTEPS 16 + + //#define E3_CURRENT 1000 + //#define E3_MICROSTEPS 16 + + //#define E4_CURRENT 1000 + //#define E4_MICROSTEPS 16 + + /** + * Use Trinamic's ultra quiet stepping mode. + * When disabled, Marlin will use spreadCycle stepping mode. + */ + #define STEALTHCHOP + + /** + * Let Marlin automatically control stepper current. + * This is still an experimental feature. + * Increase current every 5s by CURRENT_STEP until stepper temperature prewarn gets triggered, + * then decrease current by CURRENT_STEP until temperature prewarn is cleared. + * Adjusting starts from X/Y/Z/E_CURRENT but will not increase over AUTO_ADJUST_MAX + * 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. + * M906 S1 - Start adjusting current + * M906 S0 - Stop adjusting current + * M911 - Report stepper driver overtemperature pre-warn condition. + * M912 - Clear stepper driver overtemperature pre-warn condition flag. + */ + //#define AUTOMATIC_CURRENT_CONTROL + + #if ENABLED(AUTOMATIC_CURRENT_CONTROL) + #define CURRENT_STEP 50 // [mA] + #define AUTO_ADJUST_MAX 1300 // [mA], 1300mA_rms = 1840mA_peak + #define REPORT_CURRENT_CHANGE + #endif + + /** + * The driver will switch to spreadCycle when stepper speed is over HYBRID_THRESHOLD. + * This mode allows for faster movements at the expense of higher noise levels. + * STEALTHCHOP needs to be enabled. + * M913 X/Y/Z/E to live tune the setting + */ + //#define HYBRID_THRESHOLD + + #define X_HYBRID_THRESHOLD 100 // [mm/s] + #define X2_HYBRID_THRESHOLD 100 + #define Y_HYBRID_THRESHOLD 100 + #define Y2_HYBRID_THRESHOLD 100 + #define Z_HYBRID_THRESHOLD 4 + #define Z2_HYBRID_THRESHOLD 4 + #define E0_HYBRID_THRESHOLD 30 + #define E1_HYBRID_THRESHOLD 30 + #define E2_HYBRID_THRESHOLD 30 + #define E3_HYBRID_THRESHOLD 30 + #define E4_HYBRID_THRESHOLD 30 + + /** + * Use stallGuard2 to sense an obstacle and trigger an endstop. + * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. + * If used along with STEALTHCHOP, the movement will be louder when homing. This is normal. + * + * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. + * Higher values make the system LESS sensitive. + * Lower value make the system MORE sensitive. + * Too low values can lead to false positives, while too high values will collide the axis without triggering. + * It is advised to set X/Y_HOME_BUMP_MM to 0. + * M914 X/Y to live tune the setting + */ + //#define SENSORLESS_HOMING + + #if ENABLED(SENSORLESS_HOMING) + #define X_HOMING_SENSITIVITY 19 + #define Y_HOMING_SENSITIVITY 19 + #endif + + /** + * You can set your own advanced settings by filling in predefined functions. + * A list of available functions can be found on the library github page + * https://github.com/teemuatlut/TMC2130Stepper + * + * Example: + * #define TMC2130_ADV() { \ + * stepperX.diag0_temp_prewarn(1); \ + * stepperX.interpolate(0); \ + * } + */ + #define TMC2130_ADV() { } + +#endif // HAVE_TMC2130 + +// @section L6470 + +/** + * Enable this section if you have L6470 motor drivers. + * You need to import the L6470 library into the Arduino IDE for this. + * (https://github.com/ameyer/Arduino-L6470) + */ + +//#define HAVE_L6470DRIVER +#if ENABLED(HAVE_L6470DRIVER) + + //#define X_IS_L6470 + //#define X2_IS_L6470 + //#define Y_IS_L6470 + //#define Y2_IS_L6470 + //#define Z_IS_L6470 + //#define Z2_IS_L6470 + //#define E0_IS_L6470 + //#define E1_IS_L6470 + //#define E2_IS_L6470 + //#define E3_IS_L6470 + //#define E4_IS_L6470 + + #define X_MICROSTEPS 16 // number of microsteps + #define X_K_VAL 50 // 0 - 255, Higher values, are higher power. Be careful not to go too high + #define X_OVERCURRENT 2000 // maxc current in mA. If the current goes over this value, the driver will switch off + #define X_STALLCURRENT 1500 // current in mA where the driver will detect a stall + + #define X2_MICROSTEPS 16 + #define X2_K_VAL 50 + #define X2_OVERCURRENT 2000 + #define X2_STALLCURRENT 1500 + + #define Y_MICROSTEPS 16 + #define Y_K_VAL 50 + #define Y_OVERCURRENT 2000 + #define Y_STALLCURRENT 1500 + + #define Y2_MICROSTEPS 16 + #define Y2_K_VAL 50 + #define Y2_OVERCURRENT 2000 + #define Y2_STALLCURRENT 1500 + + #define Z_MICROSTEPS 16 + #define Z_K_VAL 50 + #define Z_OVERCURRENT 2000 + #define Z_STALLCURRENT 1500 + + #define Z2_MICROSTEPS 16 + #define Z2_K_VAL 50 + #define Z2_OVERCURRENT 2000 + #define Z2_STALLCURRENT 1500 + + #define E0_MICROSTEPS 16 + #define E0_K_VAL 50 + #define E0_OVERCURRENT 2000 + #define E0_STALLCURRENT 1500 + + #define E1_MICROSTEPS 16 + #define E1_K_VAL 50 + #define E1_OVERCURRENT 2000 + #define E1_STALLCURRENT 1500 + + #define E2_MICROSTEPS 16 + #define E2_K_VAL 50 + #define E2_OVERCURRENT 2000 + #define E2_STALLCURRENT 1500 + + #define E3_MICROSTEPS 16 + #define E3_K_VAL 50 + #define E3_OVERCURRENT 2000 + #define E3_STALLCURRENT 1500 + + #define E4_MICROSTEPS 16 + #define E4_K_VAL 50 + #define E4_OVERCURRENT 2000 + #define E4_STALLCURRENT 1500 + +#endif + +/** + * TWI/I2C BUS + * + * This feature is an EXPERIMENTAL feature so it shall not be used on production + * machines. Enabling this will allow you to send and receive I2C data from slave + * devices on the bus. + * + * ; Example #1 + * ; This macro send the string "Marlin" to the slave device with address 0x63 (99) + * ; It uses multiple M260 commands with one B arg + * M260 A99 ; Target slave address + * M260 B77 ; M + * M260 B97 ; a + * M260 B114 ; r + * M260 B108 ; l + * M260 B105 ; i + * M260 B110 ; n + * M260 S1 ; Send the current buffer + * + * ; Example #2 + * ; Request 6 bytes from slave device with address 0x63 (99) + * M261 A99 B5 + * + * ; Example #3 + * ; Example serial output of a M261 request + * echo:i2c-reply: from:99 bytes:5 data:hello + */ + +// @section i2cbus + +//#define EXPERIMENTAL_I2CBUS +#define I2C_SLAVE_ADDRESS 0 // Set a value from 8 to 127 to act as a slave + +// @section extras + +/** + * Spindle & Laser control + * + * Add the M3, M4, and M5 commands to turn the spindle/laser on and off, and + * to set spindle speed, spindle direction, and laser power. + * + * SuperPid is a router/spindle speed controller used in the CNC milling community. + * Marlin can be used to turn the spindle on and off. It can also be used to set + * the spindle speed from 5,000 to 30,000 RPM. + * + * 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. + */ +//#define SPINDLE_LASER_ENABLE +#if ENABLED(SPINDLE_LASER_ENABLE) + + #define SPINDLE_LASER_ENABLE_INVERT false // set to "true" if the on/off function is reversed + #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 // delay in milliseconds to allow the spindle/laser to come up to speed/power + #define SPINDLE_LASER_POWERDOWN_DELAY 5000 // delay in milliseconds to allow the spindle to stop + #define SPINDLE_DIR_CHANGE true // set to true if your spindle controller supports changing spindle direction + #define SPINDLE_INVERT_DIR false + #define SPINDLE_STOP_ON_DIR_CHANGE true // set to true if Marlin should stop the spindle before changing rotation direction + + /** + * The M3 & M4 commands use the following equation to convert PWM duty cycle to speed/power + * + * SPEED/POWER = PWM duty cycle * SPEED_POWER_SLOPE + SPEED_POWER_INTERCEPT + * where PWM duty cycle varies from 0 to 255 + * + * set the following for your controller (ALL MUST BE SET) + */ + + #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_SLOPE 0.3922 + //#define SPEED_POWER_INTERCEPT 0 + //#define SPEED_POWER_MIN 10 + //#define SPEED_POWER_MAX 100 // 0-100% +#endif + +/** + * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins + */ +//#define PINS_DEBUGGING + +/** + * Auto-report temperatures with M155 S + */ +#define AUTO_REPORT_TEMPERATURES + +/** + * Include capabilities in M115 output + */ +#define EXTENDED_CAPABILITIES_REPORT + +/** + * Volumetric extrusion default state + * 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. + */ +//#define VOLUMETRIC_DEFAULT_ON + +/** + * Enable this option for a leaner build of Marlin that removes all + * workspace offsets, simplifying coordinate transformations, leveling, etc. + * + * - M206 and M428 are disabled. + * - G92 will revert to its behavior from Marlin 1.0. + */ +//#define NO_WORKSPACE_OFFSETS + +/** + * 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. + * + * For clients that use a fixed-width font (like OctoPrint), leave this set to 1.0. + * Otherwise, adjust according to your client and font. + */ +#define PROPORTIONAL_FONT_RATIO 1.0 + +/** + * Spend 28 bytes of SRAM to optimize the GCode parser + */ +#define FASTER_GCODE_PARSER + +/** + * User-defined menu items that execute custom GCode + */ +//#define CUSTOM_USER_MENUS +#if ENABLED(CUSTOM_USER_MENUS) + #define USER_SCRIPT_DONE "M117 User Script Done" + #define USER_SCRIPT_AUDIBLE_FEEDBACK + //#define USER_SCRIPT_RETURN // Return to status screen after a script + + #define USER_DESC_1 "Home & UBL Info" + #define USER_GCODE_1 "G28\nG29 W" + + #define USER_DESC_2 "Preheat for PLA" + #define USER_GCODE_2 "M140 S" STRINGIFY(PREHEAT_1_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND) + + #define USER_DESC_3 "Preheat for ABS" + #define USER_GCODE_3 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND) + + #define USER_DESC_4 "Heat Bed/Home/Level" + #define USER_GCODE_4 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nG28\nG29" + + #define USER_DESC_5 "Home & Info" + #define USER_GCODE_5 "G28\nM503" +#endif + +/** + * Specify an action command to send to the host when the printer is killed. + * Will be sent in the form '//action:ACTION_ON_KILL', e.g. '//action:poweroff'. + * The host must be configured to handle the action command. + */ +//#define ACTION_ON_KILL "poweroff" + +//=========================================================================== +//====================== I2C Position Encoder Settings ====================== +//=========================================================================== + +/** + * I2C position encoders for closed loop control. + * Developed by Chris Barr at Aus3D. + * + * Wiki: http://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/ + * + * Reilabuild encoders have been modified to improve reliability. + */ + +//#define I2C_POSITION_ENCODERS +#if ENABLED(I2C_POSITION_ENCODERS) + + #define I2CPE_ENCODER_CNT 1 // The number of encoders installed; max of 5 + // encoders supported currently. + + #define I2CPE_ENC_1_ADDR I2CPE_PRESET_ADDR_X // I2C address of the encoder. 30-200. + #define I2CPE_ENC_1_AXIS X_AXIS // Axis the encoder module is installed on. _AXIS. + #define I2CPE_ENC_1_TYPE I2CPE_ENC_TYPE_LINEAR // Type of encoder: I2CPE_ENC_TYPE_LINEAR -or- + // I2CPE_ENC_TYPE_ROTARY. + #define I2CPE_ENC_1_TICKS_UNIT 2048 // 1024 for magnetic strips with 2mm poles; 2048 for + // 1mm poles. For linear encoders this is ticks / mm, + // for rotary encoders this is ticks / revolution. + //#define I2CPE_ENC_1_TICKS_REV (16 * 200) // Only needed for rotary encoders; number of stepper + // steps per full revolution (motor steps/rev * microstepping) + //#define I2CPE_ENC_1_INVERT // Invert the direction of axis travel. + #define I2CPE_ENC_1_EC_METHOD I2CPE_ECM_NONE // Type of error error correction. + #define I2CPE_ENC_1_EC_THRESH 0.10 // Threshold size for error (in mm) above which the + // printer will attempt to correct the error; errors + // smaller than this are ignored to minimize effects of + // measurement noise / latency (filter). + + #define I2CPE_ENC_2_ADDR I2CPE_PRESET_ADDR_Y // Same as above, but for encoder 2. + #define I2CPE_ENC_2_AXIS Y_AXIS + #define I2CPE_ENC_2_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_ENC_2_TICKS_UNIT 2048 + //#define I2CPE_ENC_2_TICKS_REV (16 * 200) + //#define I2CPE_ENC_2_INVERT + #define I2CPE_ENC_2_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_ENC_2_EC_THRESH 0.10 + + #define I2CPE_ENC_3_ADDR I2CPE_PRESET_ADDR_Z // Encoder 3. Add additional configuration options + #define I2CPE_ENC_3_AXIS Z_AXIS // as above, or use defaults below. + + #define I2CPE_ENC_4_ADDR I2CPE_PRESET_ADDR_E // Encoder 4. + #define I2CPE_ENC_4_AXIS E_AXIS + + #define I2CPE_ENC_5_ADDR 34 // Encoder 5. + #define I2CPE_ENC_5_AXIS E_AXIS + + // Default settings for encoders which are enabled, but without settings configured above. + #define I2CPE_DEF_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_DEF_ENC_TICKS_UNIT 2048 + #define I2CPE_DEF_TICKS_REV (16 * 200) + #define I2CPE_DEF_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_DEF_EC_THRESH 0.1 + + //#define I2CPE_ERR_THRESH_ABORT 100.0 // Threshold size for error (in mm) error on any given + // axis after which the printer will abort. Comment out to + // disable abort behaviour. + + #define I2CPE_TIME_TRUSTED 10000 // After an encoder fault, there must be no further fault + // for this amount of time (in ms) before the encoder + // is trusted again. + + /** + * Position is checked every time a new command is executed from the buffer but during long moves, + * this setting determines the minimum update time between checks. A value of 100 works well with + * error rolling average when attempting to correct only for skips and not for vibration. + */ + #define I2CPE_MIN_UPD_TIME_MS 100 // Minimum time in miliseconds between encoder checks. + + // Use a rolling average to identify persistant errors that indicate skips, as opposed to vibration and noise. + #define I2CPE_ERR_ROLLING_AVERAGE + +#endif // I2C_POSITION_ENCODERS + +/** + * MAX7219 Debug Matrix + * + * Add support for a low-cost 8x8 LED Matrix based on the Max7219 chip, which can be used as a status + * display. Requires 3 signal wires. Some useful debug options are included to demonstrate its usage. + * + * Fully assembled MAX7219 boards can be found on the internet for under $2(US). + * For example, see https://www.ebay.com/sch/i.html?_nkw=332349290049 + */ +//#define MAX7219_DEBUG +#if ENABLED(MAX7219_DEBUG) + #define MAX7219_CLK_PIN 64 // 77 on Re-ARM // Configuration of the 3 pins to control the display + #define MAX7219_DIN_PIN 57 // 78 on Re-ARM + #define MAX7219_LOAD_PIN 44 // 79 on Re-ARM + + /** + * Sample debug features + * If you add more debug displays, be careful to avoid conflicts! + */ + #define MAX7219_DEBUG_PRINTER_ALIVE // Blink corner LED of 8x8 matrix to show that the firmware is functioning + #define MAX7219_DEBUG_STEPPER_HEAD 3 // Show the stepper queue head position on this and the next LED matrix row + #define MAX7219_DEBUG_STEPPER_TAIL 5 // Show the stepper queue tail position on this and the next LED matrix row + + #define MAX7219_DEBUG_STEPPER_QUEUE 0 // Show the current stepper queue depth on this and the next LED matrix row + // If you experience stuttering, reboots, etc. this option can reveal how + // tweaks made to the configuration are affecting the printer in real-time. +#endif + +#endif // CONFIGURATION_ADV_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/Malyan/M150/README.md b/trunk/Arduino/Marlin_1.1.6/example_configurations/Malyan/M150/README.md new file mode 100644 index 00000000..1d311776 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/Malyan/M150/README.md @@ -0,0 +1,3 @@ +# Configuration for Malyan M150 hobbyking printer +# config without automatic bed level sensor +# or in other words, "as stock" diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/Malyan/M150/_Bootscreen.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/Malyan/M150/_Bootscreen.h new file mode 100644 index 00000000..25570b10 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/Malyan/M150/_Bootscreen.h @@ -0,0 +1,104 @@ +/** + * 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 . + * + */ + +/** + * Custom Bitmap for splashscreen + * + * You may use one of the following tools to generate the C++ bitmap array from + * a black and white image: + * + * - http://www.marlinfw.org/tools/u8glib/converter.html + * - http://www.digole.com/tools/PicturetoC_Hex_converter.php + */ +#include + +#define CUSTOM_BOOTSCREEN_TIMEOUT 1000 +#define CUSTOM_BOOTSCREEN_BMPWIDTH 128 +#define CUSTOM_BOOTSCREEN_BMPHEIGHT 64 + +const unsigned char custom_start_bmp[1024] PROGMEM = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,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,0x03,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +,0x1f,0xc0,0x00,0x0f,0xe0,0x7c,0x03,0xe0,0x78,0x1c,0x07,0x81,0xe0,0xf0,0x3e,0x0e +,0x7f,0xe0,0x00,0x3f,0xf0,0x7e,0x07,0xe0,0xfc,0x1c,0x03,0x81,0xc1,0xf8,0x3f,0x0e +,0x7f,0xf8,0x00,0x7f,0xf0,0x7e,0x07,0xe0,0xfc,0x1c,0x03,0xc3,0xc1,0xf8,0x3f,0x0e +,0x7b,0xfe,0x01,0xfe,0xf0,0x7f,0x0f,0xe1,0xfe,0x1c,0x01,0xc3,0x83,0xfc,0x3f,0x8e +,0x7c,0xff,0x87,0xf9,0xf0,0x77,0x0e,0xe1,0xfe,0x1c,0x01,0xe7,0x83,0xfc,0x3b,0x8e +,0x7f,0x7f,0xcf,0xf7,0xf0,0x77,0x9e,0xe1,0xce,0x1c,0x00,0xe7,0x03,0x9c,0x3b,0xce +,0x7f,0x9f,0xff,0xcf,0xf0,0x73,0x9c,0xe3,0xcf,0x1c,0x00,0xff,0x07,0x9e,0x39,0xce +,0x7f,0xe7,0xff,0x3f,0xf0,0x73,0xfc,0xe3,0x87,0x1c,0x00,0x7e,0x07,0x0e,0x39,0xee +,0x7f,0xfb,0xfe,0xff,0xf0,0x71,0xf8,0xe3,0x87,0x1c,0x00,0x7e,0x0f,0x0f,0x38,0xee +,0x7f,0xfc,0xf9,0xff,0xf0,0x71,0xf8,0xe7,0xff,0x9c,0x00,0x3c,0x0f,0xff,0x38,0xfe +,0x7f,0xff,0x27,0xff,0xf0,0x70,0xf0,0xe7,0xff,0x9c,0x00,0x3c,0x0f,0xff,0x38,0x7e +,0x7f,0xff,0xdf,0xff,0xf0,0x70,0xf0,0xef,0xff,0xdc,0x00,0x3c,0x1f,0xff,0xb8,0x7e +,0x7f,0xdf,0xff,0xdf,0xf0,0x70,0x60,0xef,0x03,0xdf,0xf8,0x3c,0x1e,0x07,0xb8,0x3e +,0x7f,0xc7,0xff,0x1f,0xf0,0x70,0x60,0xee,0x01,0xdf,0xf8,0x3c,0x1c,0x03,0xb8,0x3e +,0x7f,0xc3,0xfe,0x1f,0xf0,0x70,0x00,0xee,0x01,0xdf,0xf8,0x3c,0x1c,0x03,0xb8,0x1e +,0x7f,0xc3,0xfe,0x1f,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +,0x7f,0xc3,0xde,0x1f,0xf0,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe +,0x7f,0xc3,0xde,0x1f,0xf0,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe +,0x7f,0xc3,0xde,0x1f,0xf0,0x7c,0x3f,0xfa,0xfb,0xff,0xff,0xff,0xfd,0x7a,0xbf,0xfe +,0x7f,0xc3,0xde,0x1f,0xf0,0x7d,0x9f,0xfb,0xff,0xff,0xff,0xff,0xff,0x7e,0xf7,0xfe +,0x7f,0xc3,0xde,0x1f,0xf0,0x7d,0x93,0x1a,0x8a,0x18,0xe3,0x8c,0x45,0x1a,0xa2,0xde +,0x3f,0xc3,0xde,0x0f,0xf0,0x7c,0x2d,0xca,0xca,0xd6,0xe9,0x24,0xcd,0x6a,0xb6,0xbe +,0x1f,0x83,0xde,0x07,0xe0,0x7d,0xa3,0x6a,0x9a,0xd6,0xe9,0x26,0x65,0x6a,0xb6,0x3e +,0x06,0x03,0xde,0x01,0x80,0x7d,0x91,0x0a,0x8a,0xd8,0xe3,0x8c,0x45,0x1a,0xb3,0x7e +,0x00,0x03,0xde,0x00,0x00,0x7f,0xff,0xff,0xff,0xfe,0xef,0xff,0xff,0xff,0xff,0x7e +,0x00,0x03,0xde,0x00,0x00,0x7f,0xff,0xff,0xff,0xf1,0xef,0xff,0xff,0xff,0xfe,0xfe +,0x00,0x03,0xde,0x00,0x00,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe +,0x00,0x03,0xde,0x00,0x00,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe +,0x00,0x03,0xde,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +,0x00,0x01,0xdc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +,0x00,0x00,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,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + +}; diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/RepRapWorld/Megatronics/Configuration.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/RepRapWorld/Megatronics/Configuration.h new file mode 100644 index 00000000..6b385741 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/RepRapWorld/Megatronics/Configuration.h @@ -0,0 +1,1700 @@ +/** + * 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 . + * + */ + +/** + * Configuration.h + * + * Basic settings such as: + * + * - Type of electronics + * - Type of temperature sensor + * - Printer geometry + * - Endstop configuration + * - LCD controller + * - Extra features + * + * Advanced settings can be found in Configuration_adv.h + * + */ +#ifndef CONFIGURATION_H +#define CONFIGURATION_H +#define CONFIGURATION_H_VERSION 010100 + +//=========================================================================== +//============================= Getting Started ============================= +//=========================================================================== + +/** + * Here are some standard links for getting your machine calibrated: + * + * http://reprap.org/wiki/Calibration + * http://youtu.be/wAL9d7FgInk + * http://calculator.josefprusa.cz + * http://reprap.org/wiki/Triffid_Hunter%27s_Calibration_Guide + * http://www.thingiverse.com/thing:5573 + * https://sites.google.com/site/repraplogphase/calibration-of-your-reprap + * http://www.thingiverse.com/thing:298812 + */ + +//=========================================================================== +//============================= DELTA Printer =============================== +//=========================================================================== +// For a Delta printer start with one of the configuration files in the +// example_configurations/delta directory and customize for your machine. +// + +//=========================================================================== +//============================= SCARA Printer =============================== +//=========================================================================== +// For a SCARA printer start with the configuration files in +// example_configurations/SCARA and customize for your machine. +// + +// @section info + +// User-specified version info of this build to display in [Pronterface, etc] terminal window during +// startup. Implementation of an idea by Prof Braino to inform user that any changes made to this +// build by the user have been successfully uploaded into firmware. +#define STRING_CONFIG_H_AUTHOR "RepRapWorld.com" // Who made the changes. +#define SHOW_BOOTSCREEN +#define STRING_SPLASH_LINE1 SHORT_BUILD_VERSION // will be shown during bootup in line 1 +#define STRING_SPLASH_LINE2 WEBSITE_URL // will be shown during bootup in line 2 + +// +// *** VENDORS PLEASE READ ***************************************************** +// +// Marlin now allow you to have a vendor boot image to be displayed on machine +// start. When SHOW_CUSTOM_BOOTSCREEN is defined Marlin will first show your +// custom boot image and then the default Marlin boot image is shown. +// +// We suggest for you to take advantage of this new feature and keep the Marlin +// boot image unmodified. For an example have a look at the bq Hephestos 2 +// example configuration folder. +// +//#define SHOW_CUSTOM_BOOTSCREEN +// @section machine + +/** + * Select which serial port on the board will be used for communication with the host. + * This allows the connection of wireless adapters (for instance) to non-default port pins. + * Serial port 0 is always used by the Arduino bootloader regardless of this setting. + * + * :[0, 1, 2, 3, 4, 5, 6, 7] + */ +#define SERIAL_PORT 0 + +/** + * This setting determines the communication speed of the printer. + * + * 250000 works in most cases, but you might try a lower speed if + * you commonly experience drop-outs during host printing. + * You may try up to 1000000 to speed up SD file transfer. + * + * :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000] + */ +#define BAUDRATE 250000 + +// Enable the Bluetooth serial interface on AT90USB devices +//#define BLUETOOTH + +// The following define selects which electronics board you have. +// Please choose the name from boards.h that matches your setup +#ifndef MOTHERBOARD + #define MOTHERBOARD BOARD_MEGATRONICS_3 +#endif + +// Optional custom name for your RepStrap or other custom machine +// Displayed in the LCD "Ready" message +//#define CUSTOM_MACHINE_NAME "3D Printer" + +// Define this to set a unique identifier for this printer, (Used by some programs to differentiate between machines) +// You can use an online service to generate a random UUID. (eg http://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] +#define EXTRUDERS 1 + +// For Cyclops or any "multi-extruder" that shares a single nozzle. +//#define SINGLENOZZLE + +/** + * Průša MK2 Single Nozzle Multi-Material Multiplexer, and variants. + * + * This device allows one stepper driver on a control board to drive + * two to eight stepper motors, one at a time, in a manner suitable + * for extruders. + * + * This option only allows the multiplexer to switch on tool-change. + * Additional options to configure custom E moves are pending. + */ +//#define MK2_MULTIPLEXER +#if ENABLED(MK2_MULTIPLEXER) + // Override the default DIO selector pins here, if needed. + // Some pins files may provide defaults for these pins. + //#define E_MUX0_PIN 40 // Always Required + //#define E_MUX1_PIN 42 // Needed for 3 to 8 steppers + //#define E_MUX2_PIN 44 // Needed for 5 to 8 steppers +#endif + +// A dual extruder that uses a single stepper motor +//#define SWITCHING_EXTRUDER +#if ENABLED(SWITCHING_EXTRUDER) + #define SWITCHING_EXTRUDER_SERVO_NR 0 + #define SWITCHING_EXTRUDER_SERVO_ANGLES { 0, 90 } // Angles for E0, E1[, E2, E3] + #if EXTRUDERS > 3 + #define SWITCHING_EXTRUDER_E23_SERVO_NR 1 + #endif +#endif + +// A dual-nozzle that uses a servomotor to raise/lower one of the nozzles +//#define SWITCHING_NOZZLE +#if ENABLED(SWITCHING_NOZZLE) + #define SWITCHING_NOZZLE_SERVO_NR 0 + #define SWITCHING_NOZZLE_SERVO_ANGLES { 0, 90 } // Angles for E0, E1 + //#define HOTEND_OFFSET_Z { 0.0, 0.0 } +#endif + +/** + * Two separate X-carriages with extruders that connect to a moving part + * via a magnetic docking mechanism. Requires SOL1_PIN and SOL2_PIN. + */ +//#define PARKING_EXTRUDER +#if ENABLED(PARKING_EXTRUDER) + #define PARKING_EXTRUDER_SOLENOIDS_INVERT // If enabled, the solenoid is NOT magnetized with applied voltage + #define PARKING_EXTRUDER_SOLENOIDS_PINS_ACTIVE LOW // LOW or HIGH pin signal energizes the coil + #define PARKING_EXTRUDER_SOLENOIDS_DELAY 250 // Delay (ms) for magnetic field. No delay if 0 or not defined. + #define PARKING_EXTRUDER_PARKING_X { -78, 184 } // X positions for parking the extruders + #define PARKING_EXTRUDER_GRAB_DISTANCE 1 // mm to move beyond the parking point to grab the extruder + #define PARKING_EXTRUDER_SECURITY_RAISE 5 // Z-raise before parking + #define HOTEND_OFFSET_Z { 0.0, 1.3 } // Z-offsets of the two hotends. The first must be 0. +#endif + +/** + * "Mixing Extruder" + * - Adds a new code, M165, to set the current mix factors. + * - Extends the stepping routines to move multiple steppers in proportion to the mix. + * - Optional support for Repetier Firmware M163, M164, and virtual extruder. + * - This implementation supports only a single extruder. + * - Enable DIRECT_MIXING_IN_G1 for Pia Taubert's reference implementation + */ +//#define MIXING_EXTRUDER +#if ENABLED(MIXING_EXTRUDER) + #define MIXING_STEPPERS 2 // Number of steppers in your mixing extruder + #define MIXING_VIRTUAL_TOOLS 16 // Use the Virtual Tool method with M163 and M164 + //#define DIRECT_MIXING_IN_G1 // Allow ABCDHI mix factors in G1 movement commands +#endif + +// Offset of the extruders (uncomment if using more than one and relying on firmware to position when changing). +// The offset has to be X=0, Y=0 for the extruder 0 hotend (default extruder). +// For the other hotends it is their distance from the extruder 0 hotend. +//#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis +//#define HOTEND_OFFSET_Y {0.0, 5.00} // (in mm) for each extruder, offset of the hotend on the Y axis + +// @section machine + +/** + * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN + * + * 0 = No Power Switch + * 1 = ATX + * 2 = X-Box 360 203Watts (the blue wire connected to PS_ON and the red wire to VCC) + * + * :{ 0:'No power switch', 1:'ATX', 2:'X-Box 360' } + */ +#define POWER_SUPPLY 1 + +#if POWER_SUPPLY > 0 + // Enable this option to leave the PSU off at startup. + // Power to steppers and heaters will need to be turned on with M80. + //#define PS_DEFAULT_OFF +#endif + +// @section temperature + +//=========================================================================== +//============================= Thermal Settings ============================ +//=========================================================================== + +/** + * --NORMAL IS 4.7kohm PULLUP!-- 1kohm pullup can be used on hotend sensor, using correct resistor and table + * + * Temperature sensors available: + * + * -3 : thermocouple with MAX31855 (only for sensor 0) + * -2 : thermocouple with MAX6675 (only for sensor 0) + * -1 : thermocouple with AD595 + * 0 : not used + * 1 : 100k thermistor - best choice for EPCOS 100k (4.7k pullup) + * 2 : 200k thermistor - ATC Semitec 204GT-2 (4.7k pullup) + * 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 (Used in ParCan & J-Head) (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) + * 71 : 100k Honeywell thermistor 135-104LAF-J01 (4.7k pullup) + * 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) + * 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" + * 20 : the PT100 circuit found in the Ultimainboard V2.x + * 60 : 100k Maker's Tool Works Kapton Bed Thermistor beta=3950 + * 66 : 4.7M High Temperature thermistor from Dyze Design + * 70 : the 100K thermistor found in the bq Hephestos 2 + * 75 : 100k Generic Silicon Heat Pad with NTC 100K MGB18-104F39050L32 thermistor + * + * 1k ohm pullup tables - This is atypical, and requires changing out the 4.7k pullup for 1k. + * (but gives greater accuracy and more stable PID) + * 51 : 100k thermistor - EPCOS (1k pullup) + * 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 + * 1010 : Pt1000 with 1k pullup (non standard) + * 147 : Pt100 with 4k7 pullup + * 110 : Pt100 with 1k pullup (non standard) + * + * Use these for Testing or Development purposes. NEVER for production machine. + * 998 : Dummy Table that ALWAYS reads 25°C or the temperature defined below. + * 999 : Dummy Table that ALWAYS reads 100°C or the temperature defined below. + * + * :{ '0': "Not used", '1':"100k / 4.7k - EPCOS", '2':"200k / 4.7k - ATC Semitec 204GT-2", '3':"Mendel-parts / 4.7k", '4':"10k !! do not use for a hotend. Bad resolution at high temp. !!", '5':"100K / 4.7k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '6':"100k / 4.7k EPCOS - Not as accurate as Table 1", '7':"100k / 4.7k Honeywell 135-104LAG-J01", '8':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT", '9':"100k / 4.7k GE Sensing AL03006-58.2K-97-G1", '10':"100k / 4.7k RS 198-961", '11':"100k / 4.7k beta 3950 1%", '12':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT (calibrated for Makibox hot bed)", '13':"100k Hisens 3950 1% up to 300°C for hotend 'Simple ONE ' & hotend 'All In ONE'", '20':"PT100 (Ultimainboard V2.x)", '51':"100k / 1k - EPCOS", '52':"200k / 1k - ATC Semitec 204GT-2", '55':"100k / 1k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '60':"100k Maker's Tool Works Kapton Bed Thermistor beta=3950", '66':"Dyze Design 4.7M High Temperature thermistor", '70':"the 100K thermistor found in the bq Hephestos 2", '71':"100k / 4.7k Honeywell 135-104LAF-J01", '147':"Pt100 / 4.7k", '1047':"Pt1000 / 4.7k", '110':"Pt100 / 1k (non-standard)", '1010':"Pt1000 / 1k (non standard)", '-3':"Thermocouple + MAX31855 (only for sensor 0)", '-2':"Thermocouple + MAX6675 (only for sensor 0)", '-1':"Thermocouple + AD595",'998':"Dummy 1", '999':"Dummy 2" } + */ +#define TEMP_SENSOR_0 1 +#define TEMP_SENSOR_1 0 +#define TEMP_SENSOR_2 0 +#define TEMP_SENSOR_3 0 +#define TEMP_SENSOR_4 0 +#define TEMP_SENSOR_BED 1 + +// Dummy thermistor constant temperature readings, for use with 998 and 999 +#define DUMMY_THERMISTOR_998_VALUE 25 +#define DUMMY_THERMISTOR_999_VALUE 100 + +// 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 +#define MAX_REDUNDANT_TEMP_SENSOR_DIFF 10 + +// Extruder temperature must be close to target for this long before M109 returns success +#define TEMP_RESIDENCY_TIME 10 // (seconds) +#define TEMP_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// Bed temperature must be close to target for this long before M190 returns success +#define TEMP_BED_RESIDENCY_TIME 0 // (seconds) +#define TEMP_BED_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_BED_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// The minimal temperature defines the temperature below which the heater will not be enabled It is used +// to check that the wiring to the thermistor is not broken. +// Otherwise this would lead to the heater being powered on all the time. +#define HEATER_0_MINTEMP 5 +#define HEATER_1_MINTEMP 5 +#define HEATER_2_MINTEMP 5 +#define HEATER_3_MINTEMP 5 +#define HEATER_4_MINTEMP 5 +#define BED_MINTEMP 5 + +// When temperature exceeds max temp, your heater will be switched off. +// This feature exists to protect your hotend from overheating accidentally, but *NOT* from thermistor short/failure! +// You should use MINTEMP for thermistor short/failure protection. +#define HEATER_0_MAXTEMP 275 +#define HEATER_1_MAXTEMP 275 +#define HEATER_2_MAXTEMP 275 +#define HEATER_3_MAXTEMP 275 +#define HEATER_4_MAXTEMP 275 +#define BED_MAXTEMP 150 + +//=========================================================================== +//============================= PID Settings ================================ +//=========================================================================== +// PID Tuning Guide here: http://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 +#if ENABLED(PIDTEMP) + //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. + //#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. + #define K1 0.95 //smoothing factor within the PID + + // 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 + +#endif // PIDTEMP + +//=========================================================================== +//============================= PID > Bed Temperature Control =============== +//=========================================================================== +// Select PID or bang-bang with PIDTEMPBED. If bang-bang, BED_LIMIT_SWITCHING will enable hysteresis +// +// Uncomment this to enable PID on the bed. It uses the same frequency PWM as the extruder. +// If your PID_dT is the default, and correct for your hardware/configuration, that means 7.689Hz, +// which is fine for driving a square wave into a resistive load and does not significantly impact you FET heating. +// This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W heater. +// If your configuration is significantly different than this and you don't understand the issues involved, you probably +// shouldn't use bed PID until someone else verifies your hardware works. +// If this is enabled, find your own PID constants below. +//#define PIDTEMPBED + +//#define BED_LIMIT_SWITCHING + +// This sets the max power delivered to the bed, and replaces the HEATER_BED_DUTY_CYCLE_DIVIDER option. +// all forms of bed control obey this (PID, bang-bang, bang-bang with hysteresis) +// setting this to anything other than 255 enables a form of PWM to the bed just like HEATER_BED_DUTY_CYCLE_DIVIDER did, +// so you shouldn't use it unless you are OK with PWM on your bed. (see the comment on enabling PIDTEMPBED) +#define MAX_BED_POWER 255 // limits duty cycle to bed; 255=full current + +#if ENABLED(PIDTEMPBED) + + //#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) + #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 + +// @section extruder + +// This option prevents extrusion if the temperature is below EXTRUDE_MINTEMP. +// It also enables the M302 command to set the minimum extrusion temperature +// or to allow moving the extruder regardless of the hotend temperature. +// *** IT IS HIGHLY RECOMMENDED TO LEAVE THIS OPTION ENABLED! *** +#define PREVENT_COLD_EXTRUSION +#define EXTRUDE_MINTEMP 170 + +// This option prevents a single extrusion longer than EXTRUDE_MAXLENGTH. +// Note that for Bowden Extruders a too-small value here may prevent loading. +#define PREVENT_LENGTHY_EXTRUDE +#define EXTRUDE_MAXLENGTH 200 + +//=========================================================================== +//======================== Thermal Runaway Protection ======================= +//=========================================================================== + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * If you get "Thermal Runaway" or "Heating failed" errors the + * details can be tuned in Configuration_adv.h + */ + +#define THERMAL_PROTECTION_HOTENDS // Enable thermal protection for all extruders +#define THERMAL_PROTECTION_BED // Enable thermal protection for the heated bed + +//=========================================================================== +//============================= Mechanical Settings ========================= +//=========================================================================== + +// @section machine + +// Uncomment one of these options to enable CoreXY, CoreXZ, or CoreYZ kinematics +// either in the usual order or reversed +//#define COREXY +//#define COREXZ +//#define COREYZ +//#define COREYX +//#define COREZX +//#define COREZY + +//=========================================================================== +//============================== Endstop Settings =========================== +//=========================================================================== + +// @section homing + +// Specify here all the endstop connectors that are connected to any endstop or probe. +// Almost all printers will be using one per axis. Probes will use one or more of the +// extra connectors. Leave undefined any used for non-endstop and non-probe purposes. +#define USE_XMIN_PLUG +#define USE_YMIN_PLUG +#define USE_ZMIN_PLUG +//#define USE_XMAX_PLUG +//#define USE_YMAX_PLUG +//#define USE_ZMAX_PLUG + +// coarse Endstop Settings +#define ENDSTOPPULLUPS // Comment this out (using // at the start of the line) to disable the endstop pullup resistors + +#if DISABLED(ENDSTOPPULLUPS) + // fine endstop settings: Individual pullups. will be ignored if ENDSTOPPULLUPS is defined + //#define ENDSTOPPULLUP_XMAX + //#define ENDSTOPPULLUP_YMAX + //#define ENDSTOPPULLUP_ZMAX + //#define ENDSTOPPULLUP_XMIN + //#define ENDSTOPPULLUP_YMIN + //#define ENDSTOPPULLUP_ZMIN + //#define ENDSTOPPULLUP_ZMIN_PROBE +#endif + +// Mechanical endstop with COM to ground and NC to Signal uses "false" here (most common setup). +#define X_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Y_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define X_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Y_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MIN_PROBE_ENDSTOP_INVERTING true // set to true to invert the logic of the probe. + +// Enable this feature if all enabled endstop pins are interrupt-capable. +// This will remove the need to poll the interrupt pins, saving many CPU cycles. +//#define ENDSTOP_INTERRUPTS_FEATURE + +//============================================================================= +//============================== Movement Settings ============================ +//============================================================================= +// @section motion + +/** + * Default Settings + * + * These settings can be reset by M502 + * + * Note that if EEPROM is enabled, saved values will override these. + */ + +/** + * With this option each E stepper can have its own factors for the + * following movement settings. If fewer factors are given than the + * total number of extruders, the last value applies to the rest. + */ +//#define DISTINCT_E_FACTORS + +/** + * Default Axis Steps Per Unit (steps/mm) + * Override with M92 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_AXIS_STEPS_PER_UNIT { 78.7402*2, 78.7402*2, 5120.00, 760*1*1.5 } + +/** + * Default Max Feed Rate (mm/s) + * Override with M203 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_FEEDRATE { 300, 300, 5, 25 } + +/** + * Default Max Acceleration (change/s) change = mm/s + * (Maximum start speed for accelerated moves) + * Override with M201 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_ACCELERATION { 3000, 3000, 100, 10000 } + +/** + * Default Acceleration (change/s) change = mm/s + * Override with M204 + * + * M204 P Acceleration + * M204 R Retract Acceleration + * M204 T Travel Acceleration + */ +#define DEFAULT_ACCELERATION 3000 // X, Y, Z and E acceleration for printing moves +#define DEFAULT_RETRACT_ACCELERATION 3000 // E acceleration for retracts +#define DEFAULT_TRAVEL_ACCELERATION 3000 // X, Y, Z acceleration for travel (non printing) moves + +/** + * Default Jerk (mm/s) + * Override with M205 X Y Z E + * + * "Jerk" specifies the minimum speed change that requires acceleration. + * When changing speed and direction, if the difference is less than the + * value set here, it may happen instantaneously. + */ +#define DEFAULT_XJERK 20.0 +#define DEFAULT_YJERK 20.0 +#define DEFAULT_ZJERK 0.4 +#define DEFAULT_EJERK 5.0 + +//=========================================================================== +//============================= Z Probe Options ============================= +//=========================================================================== +// @section probes + +// +// See http://marlinfw.org/configuration/probes.html +// + +/** + * Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + * + * Enable this option for a probe connected to the Z Min endstop pin. + */ +#define Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + +/** + * Z_MIN_PROBE_ENDSTOP + * + * Enable this option for a probe connected to any pin except Z-Min. + * (By default Marlin assumes the Z-Max endstop pin.) + * To use a custom Z Probe pin, set Z_MIN_PROBE_PIN below. + * + * - The simplest option is to use a free endstop connector. + * - Use 5V for powered (usually inductive) sensors. + * + * - RAMPS 1.3/1.4 boards may use the 5V, GND, and Aux4->D32 pin: + * - For simple switches connect... + * - normally-closed switches to GND and D32. + * - normally-open switches to 5V and D32. + * + * WARNING: Setting the wrong pin may have unexpected and potentially + * disastrous consequences. Use with caution and do your homework. + * + */ +//#define Z_MIN_PROBE_ENDSTOP + +/** + * Probe Type + * + * Allen Key Probes, Servo Probes, Z-Sled Probes, FIX_MOUNTED_PROBE, etc. + * Activate one of these to use Auto Bed Leveling below. + */ + +/** + * The "Manual Probe" provides a means to do "Auto" Bed Leveling without a probe. + * Use G29 repeatedly, adjusting the Z height at each point with movement commands + * or (with LCD_BED_LEVELING) the LCD controller. + */ +//#define PROBE_MANUALLY + +/** + * A Fix-Mounted Probe either doesn't deploy or needs manual deployment. + * (e.g., an inductive probe or a nozzle-based probe-switch.) + */ +//#define FIX_MOUNTED_PROBE + +/** + * Z Servo Probe, such as an endstop switch on a rotating arm. + */ +//#define Z_ENDSTOP_SERVO_NR 0 // Defaults to SERVO 0 connector. +//#define Z_SERVO_ANGLES {70,0} // Z Servo Deploy and Stow angles + +/** + * The BLTouch probe uses a Hall effect sensor and emulates a servo. + */ +//#define BLTOUCH +#if ENABLED(BLTOUCH) + //#define BLTOUCH_DELAY 375 // (ms) Enable and increase if needed +#endif + +/** + * Enable one or more of the following if probing seems unreliable. + * Heaters and/or fans can be disabled during probing to minimize electrical + * noise. A delay can also be added to allow noise and vibration to settle. + * These options are most useful for the BLTouch probe, but may also improve + * readings with inductive probes and piezo sensors. + */ +//#define PROBING_HEATERS_OFF // Turn heaters off when probing +//#define PROBING_FANS_OFF // Turn fans off when probing +//#define DELAY_BEFORE_PROBING 200 // (ms) To prevent vibrations from triggering piezo sensors + +// A probe that is deployed and stowed with a solenoid pin (SOL1_PIN) +//#define SOLENOID_PROBE + +// A sled-mounted probe like those designed by Charles Bell. +//#define Z_PROBE_SLED +//#define SLED_DOCKING_OFFSET 5 // The extra distance the X axis must travel to pickup the sled. 0 should be fine but you can push it further if you'd like. + +// +// For Z_PROBE_ALLEN_KEY see the Delta example configurations. +// + +/** + * Z Probe to nozzle (X,Y) offset, relative to (0, 0). + * X and Y offsets must be integers. + * + * In the following example the X and Y offsets are both positive: + * #define X_PROBE_OFFSET_FROM_EXTRUDER 10 + * #define Y_PROBE_OFFSET_FROM_EXTRUDER 10 + * + * +-- BACK ---+ + * | | + * L | (+) P | R <-- probe (20,20) + * E | | I + * F | (-) N (+) | G <-- nozzle (10,10) + * T | | H + * | (-) | T + * | | + * O-- FRONT --+ + * (0,0) + */ +#define X_PROBE_OFFSET_FROM_EXTRUDER -25 // X offset: -left +right [of the nozzle] +#define Y_PROBE_OFFSET_FROM_EXTRUDER -29 // Y offset: -front +behind [the nozzle] +#define Z_PROBE_OFFSET_FROM_EXTRUDER -12.35 // Z offset: -below +above [the nozzle] + +// X and Y axis travel speed (mm/m) between probes +#define XY_PROBE_SPEED 8000 + +// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +#define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z + +// Speed for the "accurate" probe of each point +#define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) + +// Use double touch for probing +//#define PROBE_DOUBLE_TOUCH + +/** + * Z probes require clearance when deploying, stowing, and moving between + * probe points to avoid hitting the bed and other hardware. + * Servo-mounted probes require extra space for the arm to rotate. + * Inductive probes need space to keep from triggering early. + * + * Use these settings to specify the distance (mm) to raise the probe (or + * lower the bed). The values set here apply over and above any (negative) + * probe Z Offset set with Z_PROBE_OFFSET_FROM_EXTRUDER, M851, or the LCD. + * Only integer values >= 1 are valid here. + * + * Example: `M851 Z-5` with a CLEARANCE of 4 => 9mm from bed to nozzle. + * But: `M851 Z+1` with a CLEARANCE of 2 => 2mm from bed to nozzle. + */ +#define Z_CLEARANCE_DEPLOY_PROBE 15 // Z Clearance for Deploy/Stow +#define Z_CLEARANCE_BETWEEN_PROBES 5 // Z Clearance between probe points + +// For M851 give a range for adjusting the Z probe offset +#define Z_PROBE_OFFSET_RANGE_MIN -20 +#define Z_PROBE_OFFSET_RANGE_MAX 20 + +// Enable the M48 repeatability test to test probe accuracy +//#define Z_MIN_PROBE_REPEATABILITY_TEST + +// For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1 +// :{ 0:'Low', 1:'High' } +#define X_ENABLE_ON 0 +#define Y_ENABLE_ON 0 +#define Z_ENABLE_ON 0 +#define E_ENABLE_ON 0 // For all extruders + +// Disables axis stepper immediately when it's not being used. +// 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 +//#define DISABLE_REDUCED_ACCURACY_WARNING + +// @section extruder + +#define DISABLE_E false // For all extruders +#define DISABLE_INACTIVE_EXTRUDER true // Keep only the active extruder enabled. + +// @section machine + +// Invert the stepper direction. Change (or reverse the motor connector) if an axis goes the wrong way. +#define INVERT_X_DIR false +#define INVERT_Y_DIR true +#define INVERT_Z_DIR false + +// Enable this option for Toshiba stepper drivers +//#define CONFIG_STEPPERS_TOSHIBA + +// @section extruder + +// For direct drive extruder v9 set to true, for geared extruder set to false. +#define INVERT_E0_DIR false +#define INVERT_E1_DIR false +#define INVERT_E2_DIR false +#define INVERT_E3_DIR false +#define INVERT_E4_DIR false + +// @section homing + +//#define NO_MOTION_BEFORE_HOMING // Inhibit movement until all axes have been homed + +//#define Z_HOMING_HEIGHT 4 // (in mm) Minimal z height before homing (G28) for Z clearance above the bed, clamps, ... + // Be sure you have this distance over your Z_MAX_POS in case. + +// Direction of endstops when homing; 1=MAX, -1=MIN +// :[-1,1] +#define X_HOME_DIR -1 +#define Y_HOME_DIR -1 +#define Z_HOME_DIR -1 + +// @section machine + +// The size of the print bed +#define X_BED_SIZE 200 +#define Y_BED_SIZE 200 + +// Travel limits (mm) after homing, corresponding to endstop positions. +#define X_MIN_POS 0 +#define Y_MIN_POS 0 +#define Z_MIN_POS 0 +#define X_MAX_POS X_BED_SIZE +#define Y_MAX_POS Y_BED_SIZE +#define Z_MAX_POS 200 + +// If enabled, axes won't move below MIN_POS in response to movement commands. +#define MIN_SOFTWARE_ENDSTOPS +// If enabled, axes won't move above MAX_POS in response to movement commands. +#define MAX_SOFTWARE_ENDSTOPS + +/** + * Filament Runout Sensor + * A mechanical or opto endstop is used to check for the presence of filament. + * + * RAMPS-based boards use SERVO3_PIN. + * For other boards you may need to define FIL_RUNOUT_PIN. + * By default the firmware assumes HIGH = has filament, LOW = ran out + */ +//#define FILAMENT_RUNOUT_SENSOR +#if ENABLED(FILAMENT_RUNOUT_SENSOR) + #define FIL_RUNOUT_INVERTING false // set to true to invert the logic of the sensor. + #define ENDSTOPPULLUP_FIL_RUNOUT // Uncomment to use internal pullup for filament runout pins if the sensor is defined. + #define FILAMENT_RUNOUT_SCRIPT "M600" +#endif + +//=========================================================================== +//=============================== Bed Leveling ============================== +//=========================================================================== +// @section bedlevel + +/** + * Choose one of the options below to enable G29 Bed Leveling. The parameters + * and behavior of G29 will change depending on your selection. + * + * If using a Probe for Z Homing, enable Z_SAFE_HOMING also! + * + * - AUTO_BED_LEVELING_3POINT + * Probe 3 arbitrary points on the bed (that aren't collinear) + * You specify the XY coordinates of all 3 points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_LINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_BILINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a mesh, best for large or uneven beds. + * + * - AUTO_BED_LEVELING_UBL (Unified Bed Leveling) + * A comprehensive bed leveling system combining the features and benefits + * of other systems. UBL also includes integrated Mesh Generation, Mesh + * Validation and Mesh Editing systems. Currently, UBL is only checked out + * for Cartesian Printers. That said, it was primarily designed to correct + * poor quality Delta Printers. If you feel adventurous and have a Delta, + * please post an issue if something doesn't work correctly. Initially, + * you will need to set a reduced bed size so you have a rectangular area + * to test on. + * + * - MESH_BED_LEVELING + * Probe a grid manually + * The result is a mesh, suitable for large or uneven beds. (See BILINEAR.) + * For machines without a probe, Mesh Bed Leveling provides a method to perform + * leveling in steps so you can manually adjust the Z height at each grid-point. + * With an LCD controller the process is guided step-by-step. + */ +//#define AUTO_BED_LEVELING_3POINT +//#define AUTO_BED_LEVELING_LINEAR +//#define AUTO_BED_LEVELING_BILINEAR +//#define AUTO_BED_LEVELING_UBL +//#define MESH_BED_LEVELING + +/** + * Enable detailed logging of G28, G29, M48, etc. + * Turn on with the command 'M111 S32'. + * NOTE: Requires a lot of PROGMEM! + */ +//#define DEBUG_LEVELING_FEATURE + +#if ENABLED(MESH_BED_LEVELING) || ENABLED(AUTO_BED_LEVELING_BILINEAR) || ENABLED(AUTO_BED_LEVELING_UBL) + // Gradually reduce leveling correction until a set height is reached, + // at which point movement will be level to the machine's XY plane. + // The height can be set with M420 Z + #define ENABLE_LEVELING_FADE_HEIGHT +#endif + +#if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Set the number of grid points per dimension. + #define GRID_MAX_POINTS_X 3 + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + // Set the boundaries for probing (where the probe can reach). + #define LEFT_PROBE_BED_POSITION 15 + #define RIGHT_PROBE_BED_POSITION 170 + #define FRONT_PROBE_BED_POSITION 20 + #define BACK_PROBE_BED_POSITION 170 + + // The Z probe minimum outer margin (to validate G29 parameters). + #define MIN_PROBE_EDGE 10 + + // Probe along the Y axis, advancing X after each column + //#define PROBE_Y_FIRST + + #if ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Beyond the probed grid, continue the implied tilt? + // Default is to maintain the height of the nearest edge. + //#define EXTRAPOLATE_BEYOND_GRID + + // + // Experimental Subdivision of the grid by Catmull-Rom method. + // Synthesizes intermediate points to produce a more detailed mesh. + // + //#define ABL_BILINEAR_SUBDIVISION + #if ENABLED(ABL_BILINEAR_SUBDIVISION) + // Number of subdivisions between probe points + #define BILINEAR_SUBDIVISIONS 3 + #endif + + #endif + +#elif ENABLED(AUTO_BED_LEVELING_3POINT) + + // 3 arbitrary points to probe. + // A simple cross-product is used to estimate the plane of the bed. + #define ABL_PROBE_PT_1_X 15 + #define ABL_PROBE_PT_1_Y 180 + #define ABL_PROBE_PT_2_X 15 + #define ABL_PROBE_PT_2_Y 20 + #define ABL_PROBE_PT_3_X 170 + #define ABL_PROBE_PT_3_Y 20 + +#elif ENABLED(AUTO_BED_LEVELING_UBL) + + //=========================================================================== + //========================= Unified Bed Leveling ============================ + //=========================================================================== + + #define UBL_MESH_INSET 1 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 10 // Don't use more than 15 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + #define UBL_PROBE_PT_1_X 39 // Probing points for 3-Point leveling of the mesh + #define UBL_PROBE_PT_1_Y 180 + #define UBL_PROBE_PT_2_X 39 + #define UBL_PROBE_PT_2_Y 20 + #define UBL_PROBE_PT_3_X 180 + #define UBL_PROBE_PT_3_Y 20 + + #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation + #define UBL_MESH_EDIT_MOVES_Z // Sophisticated users prefer no movement of nozzle + +#elif ENABLED(MESH_BED_LEVELING) + + //=========================================================================== + //=================================== Mesh ================================== + //=========================================================================== + + #define MESH_INSET 10 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 3 // Don't use more than 7 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + //#define MESH_G28_REST_ORIGIN // After homing all axes ('G28' or 'G28 XYZ') rest Z at Z_MIN_POS + +#endif // BED_LEVELING + +/** + * Use the LCD controller for bed leveling + * Requires MESH_BED_LEVELING or PROBE_MANUALLY + */ +//#define LCD_BED_LEVELING + +#if ENABLED(LCD_BED_LEVELING) + #define MBL_Z_STEP 0.025 // Step size while manually probing Z axis. + #define LCD_PROBE_Z_RANGE 4 // Z Range centered on Z_MIN_POS for LCD Z adjustment +#endif + +// Add a menu item to move between bed corners for manual bed adjustment +//#define LEVEL_BED_CORNERS + +/** + * Commands to execute at the end of G29 probing. + * Useful to retract or move the Z probe out of the way. + */ +//#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) +//#define BED_CENTER_AT_0_0 + +// Manually set the home position. Leave these undefined for automatic settings. +// For DELTA this is the top-center of the Cartesian print volume. +//#define MANUAL_X_HOME_POS 0 +//#define MANUAL_Y_HOME_POS 0 +//#define MANUAL_Z_HOME_POS 0 + +// Use "Z Safe Homing" to avoid homing with a Z probe outside the bed area. +// +// With this feature enabled: +// +// - 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). +// - 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 axis (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). +#endif + +// Homing speeds (mm/m) +#define HOMING_FEEDRATE_XY (50*60) +#define HOMING_FEEDRATE_Z (4*60) + +//============================================================================= +//============================= Additional Features =========================== +//============================================================================= + +// @section extras + +// +// EEPROM +// +// The microcontroller can store settings in the EEPROM, e.g. max velocity... +// M500 - stores parameters in EEPROM +// M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily). +// M502 - reverts to the default "factory settings". You still need to store them in EEPROM afterwards if you want to. +// +//#define EEPROM_SETTINGS // Enable for M500 and M501 commands +//#define DISABLE_M503 // Saves ~2700 bytes of PROGMEM. Disable for release! +#define EEPROM_CHITCHAT // Give feedback on EEPROM commands. Disable to save PROGMEM. + +// +// Host Keepalive +// +// When enabled Marlin will send a busy status message to the host +// every couple of seconds when it can't accept commands. +// +#define HOST_KEEPALIVE_FEATURE // Disable this if your host doesn't like keepalive messages +#define DEFAULT_KEEPALIVE_INTERVAL 2 // Number of seconds between "busy" messages. Set with M113. +#define BUSY_WHILE_HEATING // Some hosts require "busy" messages even during heating + +// +// M100 Free Memory Watcher +// +//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose + +// +// G20/G21 Inch mode support +// +//#define INCH_MODE_SUPPORT + +// +// M149 Set temperature units support +// +//#define TEMPERATURE_UNITS_SUPPORT + +// @section temperature + +// Preheat Constants +#define PREHEAT_1_TEMP_HOTEND 180 +#define PREHEAT_1_TEMP_BED 70 +#define PREHEAT_1_FAN_SPEED 0 // Value from 0 to 255 + +#define PREHEAT_2_TEMP_HOTEND 240 +#define PREHEAT_2_TEMP_BED 110 +#define PREHEAT_2_FAN_SPEED 0 // Value from 0 to 255 + +/** + * Nozzle Park -- EXPERIMENTAL + * + * Park the nozzle at the given XYZ position on idle or G27. + * + * The "P" parameter controls the action applied to the Z axis: + * + * P0 (Default) If Z is below park Z raise the nozzle. + * P1 Raise the nozzle always to Z-park height. + * P2 Raise the nozzle by Z-park amount, limited to Z_MAX_POS. + */ +//#define NOZZLE_PARK_FEATURE + +#if ENABLED(NOZZLE_PARK_FEATURE) + // Specify a park position as { X, Y, Z } + #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 } +#endif + +/** + * Clean Nozzle Feature -- EXPERIMENTAL + * + * Adds the G12 command to perform a nozzle cleaning process. + * + * Parameters: + * P Pattern + * S Strokes / Repetitions + * T Triangles (P1 only) + * + * Patterns: + * P0 Straight line (default). This process requires a sponge type material + * at a fixed bed location. "S" specifies strokes (i.e. back-forth motions) + * between the start / end points. + * + * P1 Zig-zag pattern between (X0, Y0) and (X1, Y1), "T" specifies the + * number of zig-zag triangles to do. "S" defines the number of strokes. + * Zig-zags are done in whichever is the narrower dimension. + * For example, "G12 P1 S1 T3" will execute: + * + * -- + * | (X0, Y1) | /\ /\ /\ | (X1, Y1) + * | | / \ / \ / \ | + * A | | / \ / \ / \ | + * | | / \ / \ / \ | + * | (X0, Y0) | / \/ \/ \ | (X1, Y0) + * -- +--------------------------------+ + * |________|_________|_________| + * T1 T2 T3 + * + * P2 Circular pattern with middle at NOZZLE_CLEAN_CIRCLE_MIDDLE. + * "R" specifies the radius. "S" specifies the stroke count. + * Before starting, the nozzle moves to NOZZLE_CLEAN_START_POINT. + * + * Caveats: The ending Z should be the same as starting Z. + * Attention: EXPERIMENTAL. G-code arguments may change. + * + */ +//#define NOZZLE_CLEAN_FEATURE + +#if ENABLED(NOZZLE_CLEAN_FEATURE) + // Default number of pattern repetitions + #define NOZZLE_CLEAN_STROKES 12 + + // Default number of triangles + #define NOZZLE_CLEAN_TRIANGLES 3 + + // Specify positions as { X, Y, Z } + #define NOZZLE_CLEAN_START_POINT { 30, 30, (Z_MIN_POS + 1)} + #define NOZZLE_CLEAN_END_POINT {100, 60, (Z_MIN_POS + 1)} + + // Circular pattern radius + #define NOZZLE_CLEAN_CIRCLE_RADIUS 6.5 + // Circular pattern circle fragments number + #define NOZZLE_CLEAN_CIRCLE_FN 10 + // Middle point of circle + #define NOZZLE_CLEAN_CIRCLE_MIDDLE NOZZLE_CLEAN_START_POINT + + // Moves the nozzle to the initial position + #define NOZZLE_CLEAN_GOBACK +#endif + +/** + * Print Job Timer + * + * Automatically start and stop the print job timer on M104/M109/M190. + * + * M104 (hotend, no wait) - high temp = none, low temp = stop timer + * M109 (hotend, wait) - high temp = start timer, low temp = stop timer + * M190 (bed, wait) - high temp = start timer, low temp = none + * + * The timer can also be controlled with the following commands: + * + * M75 - Start the print job timer + * M76 - Pause the print job timer + * M77 - Stop the print job timer + */ +#define PRINTJOB_TIMER_AUTOSTART + +/** + * Print Counter + * + * Track statistical data such as: + * + * - Total print jobs + * - Total successful print jobs + * - Total failed print jobs + * - Total time printing + * + * View the current statistics with M78. + */ +//#define PRINTCOUNTER + +//============================================================================= +//============================= LCD and SD support ============================ +//============================================================================= + +// @section lcd + +/** + * LCD LANGUAGE + * + * Select the language to display on the LCD. These languages are available: + * + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, + * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * tr, uk, zh_CN, zh_TW, test + * + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + */ +#define LCD_LANGUAGE en + +/** + * LCD Character Set + * + * Note: This option is NOT applicable to Graphical Displays. + * + * All character-based LCDs provide ASCII plus one of these + * language extensions: + * + * - JAPANESE ... the most common + * - WESTERN ... with more accented characters + * - CYRILLIC ... for the Russian language + * + * To determine the language extension installed on your controller: + * + * - Compile and upload with LCD_LANGUAGE set to 'test' + * - 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 + * + * :['JAPANESE', 'WESTERN', 'CYRILLIC'] + */ +#define DISPLAY_CHARSET_HD44780 JAPANESE + +/** + * LCD TYPE + * + * Enable ULTRA_LCD for a 16x2, 16x4, 20x2, or 20x4 character-based LCD. + * Enable DOGLCD for a 128x64 (ST7565R) Full Graphical Display. + * (These options will be enabled automatically for most displays.) + * + * IMPORTANT: The U8glib library is required for Full Graphic Display! + * https://github.com/olikraus/U8glib_Arduino + */ +#define ULTRA_LCD // Character based +//#define DOGLCD // Full graphics display + +/** + * SD CARD + * + * 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 + +/** + * SD CARD: SPI SPEED + * + * Enable one of the following items for a slower SPI transfer speed. + * This may be required to resolve "volume init" errors. + */ +//#define SPI_SPEED SPI_HALF_SPEED +//#define SPI_SPEED SPI_QUARTER_SPEED +//#define SPI_SPEED SPI_EIGHTH_SPEED + +/** + * SD CARD: ENABLE CRC + * + * Use CRC checks and retries on the SD communication. + */ +#define SD_CHECK_AND_RETRY + +// +// ENCODER SETTINGS +// +// This option overrides the default number of encoder pulses needed to +// produce one step. Should be increased for high-resolution encoders. +// +//#define ENCODER_PULSES_PER_STEP 1 + +// +// Use this option to override the number of step signals required to +// move between next/prev menu items. +// +//#define ENCODER_STEPS_PER_MENU_ITEM 5 + +/** + * Encoder Direction Options + * + * Test your encoder's behavior first with both options disabled. + * + * Reversed Value Edit and Menu Nav? Enable REVERSE_ENCODER_DIRECTION. + * Reversed Menu Navigation only? Enable REVERSE_MENU_DIRECTION. + * Reversed Value Editing only? Enable BOTH options. + */ + +// +// This option reverses the encoder direction everywhere. +// +// Set this option if CLOCKWISE causes values to DECREASE +// +//#define REVERSE_ENCODER_DIRECTION + +// +// This option reverses the encoder direction for navigating LCD menus. +// +// If CLOCKWISE normally moves DOWN this makes it go UP. +// If CLOCKWISE normally moves UP this makes it go DOWN. +// +//#define REVERSE_MENU_DIRECTION + +// +// Individual Axis Homing +// +// Add individual axis homing items (Home X, Home Y, and Home Z) to the LCD menu. +// +//#define INDIVIDUAL_AXIS_HOMING_MENU + +// +// SPEAKER/BUZZER +// +// If you have a speaker that can produce tones, enable it here. +// By default Marlin assumes you have a buzzer with a fixed frequency. +// +//#define SPEAKER + +// +// The duration and frequency for the UI feedback sound. +// Set these to 0 to disable audio feedback in the LCD menus. +// +// Note: Test audio output with the G-Code: +// M300 S P +// +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 +//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 + +// +// CONTROLLER TYPE: Standard +// +// Marlin supports a wide variety of controllers. +// Enable one of the following options to specify your controller. +// + +// +// ULTIMAKER Controller. +// +//#define ULTIMAKERCONTROLLER + +// +// ULTIPANEL as seen on Thingiverse. +// +//#define ULTIPANEL + +// +// PanelOne from T3P3 (via RAMPS 1.4 AUX2/AUX3) +// http://reprap.org/wiki/PanelOne +// +//#define PANEL_ONE + +// +// MaKr3d Makr-Panel with graphic controller and SD support. +// http://reprap.org/wiki/MaKr3d_MaKrPanel +// +//#define MAKRPANEL + +// +// ReprapWorld Graphical LCD +// https://reprapworld.com/?products_details&products_id/1218 +// +//#define REPRAPWORLD_GRAPHICAL_LCD + +// +// Activate one of these if you have a Panucatt Devices +// Viki 2.0 or mini Viki with Graphic LCD +// http://panucatt.com +// +//#define VIKI2 +//#define miniVIKI + +// +// Adafruit ST7565 Full Graphic Controller. +// https://github.com/eboston/Adafruit-ST7565-Full-Graphic-Controller/ +// +//#define ELB_FULL_GRAPHIC_CONTROLLER + +// +// RepRapDiscount Smart Controller. +// http://reprap.org/wiki/RepRapDiscount_Smart_Controller +// +// Note: Usually sold with a white PCB. +// +//#define REPRAP_DISCOUNT_SMART_CONTROLLER + +// +// GADGETS3D G3D LCD/SD Controller +// http://reprap.org/wiki/RAMPS_1.3/1.4_GADGETS3D_Shield_with_Panel +// +// Note: Usually sold with a blue PCB. +// +//#define G3D_PANEL + +// +// RepRapDiscount FULL GRAPHIC Smart Controller +// http://reprap.org/wiki/RepRapDiscount_Full_Graphic_Smart_Controller +// +//#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER + +// +// MakerLab Mini Panel with graphic +// controller and SD support - http://reprap.org/wiki/Mini_panel +// +//#define MINIPANEL + +// +// RepRapWorld REPRAPWORLD_KEYPAD v1.1 +// http://reprapworld.com/?products_details&products_id=202&cPath=1591_1626 +// +// REPRAPWORLD_KEYPAD_MOVE_STEP sets how much should the robot move when a key +// is pressed, a value of 10.0 means 10mm per click. +// +#define REPRAPWORLD_KEYPAD +#define REPRAPWORLD_KEYPAD_MOVE_STEP 1.0 + +// +// RigidBot Panel V1.0 +// http://www.inventapart.com/ +// +//#define RIGIDBOT_PANEL + +// +// BQ LCD Smart Controller shipped by +// default with the BQ Hephestos 2 and Witbox 2. +// +//#define BQ_LCD_SMART_CONTROLLER + +// +// Cartesio UI +// http://mauk.cc/webshop/cartesio-shop/electronics/user-interface +// +//#define CARTESIO_UI + +// +// ANET_10 Controller supported displays. +// +//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. + // This LCD is known to be susceptible to electrical interference + // which scrambles the display. Pressing any button clears it up. +//#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 + // A clone of the RepRapDiscount full graphics display but with + // different pins/wiring (see pins_ANET_10.h). + +// +// LCD for Melzi Card with Graphical LCD +// +//#define LCD_FOR_MELZI + +// +// CONTROLLER TYPE: I2C +// +// Note: These controllers require the installation of Arduino's LiquidCrystal_I2C +// library. For more info: https://github.com/kiyoshigawa/LiquidCrystal_I2C +// + +// +// Elefu RA Board Control Panel +// http://www.elefu.com/index.php?route=product/product&product_id=53 +// +//#define RA_CONTROL_PANEL + +// +// Sainsmart YW Robot (LCM1602) LCD Display +// +// Note: This controller requires F.Malpartida's LiquidCrystal_I2C library +// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home +// +//#define LCD_I2C_SAINSMART_YWROBOT + +// +// Generic LCM1602 LCD adapter +// +//#define LCM1602 + +// +// PANELOLU2 LCD with status LEDs, +// separate encoder and click inputs. +// +// Note: This controller requires Arduino's LiquidTWI2 library v1.2.3 or later. +// For more info: https://github.com/lincomatic/LiquidTWI2 +// +// Note: The PANELOLU2 encoder click input can either be directly connected to +// a pin (if BTN_ENC defined to != -1) or read through I2C (when BTN_ENC == -1). +// +//#define LCD_I2C_PANELOLU2 + +// +// Panucatt VIKI LCD with status LEDs, +// integrated click & L/R/U/D buttons, separate encoder inputs. +// +//#define LCD_I2C_VIKI + +// +// SSD1306 OLED full graphics generic display +// +//#define U8GLIB_SSD1306 + +// +// SAV OLEd LCD module support using either SSD1306 or SH1106 based LCD modules +// +//#define SAV_3DGLCD +#if ENABLED(SAV_3DGLCD) + //#define U8GLIB_SSD1306 + #define U8GLIB_SH1106 +#endif + +// +// CONTROLLER TYPE: Shift register panels +// +// 2 wire Non-latching LCD SR from https://goo.gl/aJJ4sH +// LCD configuration: http://reprap.org/wiki/SAV_3D_LCD +// +//#define SAV_3DLCD + +// +// TinyBoy2 128x64 OLED / Encoder Panel +// +//#define OLED_PANEL_TINYBOY2 + +// +// Makeboard 3D Printer Parts 3D Printer Mini Display 1602 Mini Controller +// https://www.aliexpress.com/item/Micromake-Makeboard-3D-Printer-Parts-3D-Printer-Mini-Display-1602-Mini-Controller-Compatible-with-Ramps-1/32765887917.html +// +//#define MAKEBOARD_MINI_2_LINE_DISPLAY_1602 + +// +// MKS MINI12864 with graphic controller and SD support +// http://reprap.org/wiki/MKS_MINI_12864 +// +//#define MKS_MINI_12864 + +// +// Factory display for Creality CR-10 +// https://www.aliexpress.com/item/Universal-LCD-12864-3D-Printer-Display-Screen-With-Encoder-For-CR-10-CR-7-Model/32833148327.html +// +// This is RAMPS-compatible using a single 10-pin connector. +// (For CR-10 owners who want to replace the Melzi Creality board but retain the display) +// +//#define CR10_STOCKDISPLAY + +// +// MKS OLED 1.3" 128 × 64 FULL GRAPHICS CONTROLLER +// http://reprap.org/wiki/MKS_12864OLED +// +// Tiny, but very sharp OLED display +// +//#define MKS_12864OLED + +//============================================================================= +//=============================== Extra Features ============================== +//============================================================================= + +// @section extras + +// Increase the FAN PWM frequency. Removes the PWM noise but increases heating in the FET/Arduino +//#define FAST_PWM_FAN + +// Use software PWM to drive the fan, as for the heaters. This uses a very low frequency +// which is not as annoying as with the hardware PWM. On the other hand, if this frequency +// is too low, you should also increment SOFT_PWM_SCALE. +//#define FAN_SOFT_PWM + +// Incrementing this by 1 will double the software PWM frequency, +// affecting heaters, and the fan if FAN_SOFT_PWM is enabled. +// However, control resolution will be halved for each increment; +// at zero value, there are 128 effective control positions. +#define SOFT_PWM_SCALE 0 + +// If SOFT_PWM_SCALE is set to a value higher than 0, dithering can +// be used to mitigate the associated resolution loss. If enabled, +// some of the PWM cycles are stretched so on average the desired +// duty cycle is attained. +//#define SOFT_PWM_DITHER + +// Temperature status LEDs that display the hotend and bed temperature. +// If all hotends, bed temperature, and target temperature are under 54C +// then the BLUE led is on. Otherwise the RED led is on. (1C hysteresis) +//#define TEMP_STAT_LEDS + +// M240 Triggers a camera by emulating a Canon RC-1 Remote +// Data from: http://www.doc-diy.net/photo/rc-1_hacked/ +//#define PHOTOGRAPH_PIN 23 + +// 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 + +// Support for BlinkM/CyzRgb +//#define BLINKM + +// Support for PCA9632 PWM LED driver +//#define PCA9632 + +/** + * RGB LED / LED Strip Control + * + * Enable support for an RGB LED connected to 5V digital pins, or + * an RGB Strip connected to MOSFETs controlled by digital pins. + * + * 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 overall brightness parameters is also available + * + * *** CAUTION *** + * LED Strips require a MOFSET 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! + * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino + * cannot handle such current, separate 5V power supply must be used + * *** CAUTION *** + * + * LED type. This options are mutualy exclusive. Uncomment only one. + * + */ +//#define RGB_LED +//#define RGBW_LED + +#if ENABLED(RGB_LED) || ENABLED(RGBW_LED) + #define RGB_LED_R_PIN 34 + #define RGB_LED_G_PIN 43 + #define RGB_LED_B_PIN 35 + #define RGB_LED_W_PIN -1 +#endif + +// 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 (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) + #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip + #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time + #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + //#define NEOPIXEL_STARTUP_TEST // Cycle through colors at startup +#endif + +/** + * Printer Event LEDs + * + * During printing, the LEDs will reflect the printer status: + * + * - Gradually change from blue to violet as the heated bed gets to target temp + * - Gradually change from violet to red as the hotend gets to temperature + * - Change to white to illuminate work surface + * - Change to green once print has finished + * - Turn off after the print has finished and the user has pushed a button + */ +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) + #define PRINTER_EVENT_LEDS +#endif + +/*********************************************************************\ +* R/C SERVO support +* Sponsored by TrinityLabs, Reworked by codexmas +**********************************************************************/ + +// Number of servos +// +// If you select a configuration below, this will receive a default value and does not need to be set manually +// set it manually if you have more servos than extruders and wish to manually control some +// leaving it undefined or defining as 0 will disable the servo subsystem +// If unsure, leave commented / disabled +// +//#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command + +// Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. +// 300ms is a good value but you can try less delay. +// If the servo can't reach the requested position, increase it. +#define SERVO_DELAY { 300 } + +// Servo deactivation +// +// With this option servos are powered only during movement, then turned off to prevent jitter. +//#define DEACTIVATE_SERVOS_AFTER_MOVE + +/** + * Filament Width Sensor + * + * Measures the filament width in real-time and adjusts + * flow rate to compensate for any irregularities. + * + * Also allows the measured filament diameter to set the + * extrusion rate, so the slicer only has to specify the + * volume. + * + * Only a single extruder is supported at this time. + * + * 34 RAMPS_14 : Analog input 5 on the AUX2 connector + * 81 PRINTRBOARD : Analog input 2 on the Exp1 connector (version B,C,D,E) + * 301 RAMBO : Analog input 3 + * + * Note: May require analog pins to be defined for other boards. + */ +//#define FILAMENT_WIDTH_SENSOR + +#define DEFAULT_NOMINAL_FILAMENT_DIA 3.00 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. + +#if ENABLED(FILAMENT_WIDTH_SENSOR) + #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) + #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber + + #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading + #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading + #define MAX_MEASUREMENT_DELAY 20 // (bytes) Buffer size for stored measurements (1 byte per cm). Must be larger than MEASUREMENT_DELAY_CM. + + #define DEFAULT_MEASURED_FILAMENT_DIA DEFAULT_NOMINAL_FILAMENT_DIA // Set measured to nominal initially + + // Display filament width on the LCD status line. Status messages will expire after 5 seconds. + //#define FILAMENT_LCD_DISPLAY +#endif + +#endif // CONFIGURATION_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/RigidBot/Configuration.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/RigidBot/Configuration.h new file mode 100644 index 00000000..705b6679 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/RigidBot/Configuration.h @@ -0,0 +1,1700 @@ +/** + * 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 . + * + */ + +/** + * Configuration.h + * + * Basic settings such as: + * + * - Type of electronics + * - Type of temperature sensor + * - Printer geometry + * - Endstop configuration + * - LCD controller + * - Extra features + * + * Advanced settings can be found in Configuration_adv.h + * + */ +#ifndef CONFIGURATION_H +#define CONFIGURATION_H +#define CONFIGURATION_H_VERSION 010100 + +//=========================================================================== +//============================= Getting Started ============================= +//=========================================================================== + +/** + * Here are some standard links for getting your machine calibrated: + * + * http://reprap.org/wiki/Calibration + * http://youtu.be/wAL9d7FgInk + * http://calculator.josefprusa.cz + * http://reprap.org/wiki/Triffid_Hunter%27s_Calibration_Guide + * http://www.thingiverse.com/thing:5573 + * https://sites.google.com/site/repraplogphase/calibration-of-your-reprap + * http://www.thingiverse.com/thing:298812 + */ + +//=========================================================================== +//============================= DELTA Printer =============================== +//=========================================================================== +// For a Delta printer start with one of the configuration files in the +// example_configurations/delta directory and customize for your machine. +// + +//=========================================================================== +//============================= SCARA Printer =============================== +//=========================================================================== +// For a SCARA printer start with the configuration files in +// example_configurations/SCARA and customize for your machine. +// + +// @section info + +// User-specified version info of this build to display in [Pronterface, etc] terminal window during +// startup. Implementation of an idea by Prof Braino to inform user that any changes made to this +// build by the user have been successfully uploaded into firmware. +#define STRING_CONFIG_H_AUTHOR "(none, RigidBot)" // Who made the changes. +#define SHOW_BOOTSCREEN +#define STRING_SPLASH_LINE1 SHORT_BUILD_VERSION // will be shown during bootup in line 1 +#define STRING_SPLASH_LINE2 WEBSITE_URL // will be shown during bootup in line 2 + +// +// *** VENDORS PLEASE READ ***************************************************** +// +// Marlin now allow you to have a vendor boot image to be displayed on machine +// start. When SHOW_CUSTOM_BOOTSCREEN is defined Marlin will first show your +// custom boot image and then the default Marlin boot image is shown. +// +// We suggest for you to take advantage of this new feature and keep the Marlin +// boot image unmodified. For an example have a look at the bq Hephestos 2 +// example configuration folder. +// +//#define SHOW_CUSTOM_BOOTSCREEN +// @section machine + +/** + * Select which serial port on the board will be used for communication with the host. + * This allows the connection of wireless adapters (for instance) to non-default port pins. + * Serial port 0 is always used by the Arduino bootloader regardless of this setting. + * + * :[0, 1, 2, 3, 4, 5, 6, 7] + */ +#define SERIAL_PORT 0 + +/** + * This setting determines the communication speed of the printer. + * + * 250000 works in most cases, but you might try a lower speed if + * you commonly experience drop-outs during host printing. + * You may try up to 1000000 to speed up SD file transfer. + * + * :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000] + */ +#define BAUDRATE 115200 + +// Enable the Bluetooth serial interface on AT90USB devices +//#define BLUETOOTH + +// The following define selects which electronics board you have. +// Please choose the name from boards.h that matches your setup +// for Rigidbot version 1 : #define MOTHERBOARD BOARD_RIGIDBOARD +// for Rigidbot Version 2 : #define MOTHERBOARD BOARD_RIGIDBOARD_V2 + +#ifndef MOTHERBOARD + #define MOTHERBOARD BOARD_RIGIDBOARD_V2 +#endif + +// Optional custom name for your RepStrap or other custom machine +// Displayed in the LCD "Ready" message +//#define CUSTOM_MACHINE_NAME "3D Printer" + +// Define this to set a unique identifier for this printer, (Used by some programs to differentiate between machines) +// You can use an online service to generate a random UUID. (eg http://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] +#define EXTRUDERS 1 // Single extruder. Set to 2 for dual extruders + +// For Cyclops or any "multi-extruder" that shares a single nozzle. +//#define SINGLENOZZLE + +/** + * Průša MK2 Single Nozzle Multi-Material Multiplexer, and variants. + * + * This device allows one stepper driver on a control board to drive + * two to eight stepper motors, one at a time, in a manner suitable + * for extruders. + * + * This option only allows the multiplexer to switch on tool-change. + * Additional options to configure custom E moves are pending. + */ +//#define MK2_MULTIPLEXER +#if ENABLED(MK2_MULTIPLEXER) + // Override the default DIO selector pins here, if needed. + // Some pins files may provide defaults for these pins. + //#define E_MUX0_PIN 40 // Always Required + //#define E_MUX1_PIN 42 // Needed for 3 to 8 steppers + //#define E_MUX2_PIN 44 // Needed for 5 to 8 steppers +#endif + +// A dual extruder that uses a single stepper motor +//#define SWITCHING_EXTRUDER +#if ENABLED(SWITCHING_EXTRUDER) + #define SWITCHING_EXTRUDER_SERVO_NR 0 + #define SWITCHING_EXTRUDER_SERVO_ANGLES { 0, 90 } // Angles for E0, E1[, E2, E3] + #if EXTRUDERS > 3 + #define SWITCHING_EXTRUDER_E23_SERVO_NR 1 + #endif +#endif + +// A dual-nozzle that uses a servomotor to raise/lower one of the nozzles +//#define SWITCHING_NOZZLE +#if ENABLED(SWITCHING_NOZZLE) + #define SWITCHING_NOZZLE_SERVO_NR 0 + #define SWITCHING_NOZZLE_SERVO_ANGLES { 0, 90 } // Angles for E0, E1 + //#define HOTEND_OFFSET_Z { 0.0, 0.0 } +#endif + +/** + * Two separate X-carriages with extruders that connect to a moving part + * via a magnetic docking mechanism. Requires SOL1_PIN and SOL2_PIN. + */ +//#define PARKING_EXTRUDER +#if ENABLED(PARKING_EXTRUDER) + #define PARKING_EXTRUDER_SOLENOIDS_INVERT // If enabled, the solenoid is NOT magnetized with applied voltage + #define PARKING_EXTRUDER_SOLENOIDS_PINS_ACTIVE LOW // LOW or HIGH pin signal energizes the coil + #define PARKING_EXTRUDER_SOLENOIDS_DELAY 250 // Delay (ms) for magnetic field. No delay if 0 or not defined. + #define PARKING_EXTRUDER_PARKING_X { -78, 184 } // X positions for parking the extruders + #define PARKING_EXTRUDER_GRAB_DISTANCE 1 // mm to move beyond the parking point to grab the extruder + #define PARKING_EXTRUDER_SECURITY_RAISE 5 // Z-raise before parking + #define HOTEND_OFFSET_Z { 0.0, 1.3 } // Z-offsets of the two hotends. The first must be 0. +#endif + +/** + * "Mixing Extruder" + * - Adds a new code, M165, to set the current mix factors. + * - Extends the stepping routines to move multiple steppers in proportion to the mix. + * - Optional support for Repetier Firmware M163, M164, and virtual extruder. + * - This implementation supports only a single extruder. + * - Enable DIRECT_MIXING_IN_G1 for Pia Taubert's reference implementation + */ +//#define MIXING_EXTRUDER +#if ENABLED(MIXING_EXTRUDER) + #define MIXING_STEPPERS 2 // Number of steppers in your mixing extruder + #define MIXING_VIRTUAL_TOOLS 16 // Use the Virtual Tool method with M163 and M164 + //#define DIRECT_MIXING_IN_G1 // Allow ABCDHI mix factors in G1 movement commands +#endif + +// Offset of the extruders (uncomment if using more than one and relying on firmware to position when changing). +// The offset has to be X=0, Y=0 for the extruder 0 hotend (default extruder). +// For the other hotends it is their distance from the extruder 0 hotend. +#define HOTEND_OFFSET_X {0.0, 36.00} // (in mm) for each extruder, offset of the hotend on the X axis +#define HOTEND_OFFSET_Y {0.0, 0.00} // (in mm) for each extruder, offset of the hotend on the Y axis + +// @section machine + +/** + * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN + * + * 0 = No Power Switch + * 1 = ATX + * 2 = X-Box 360 203Watts (the blue wire connected to PS_ON and the red wire to VCC) + * + * :{ 0:'No power switch', 1:'ATX', 2:'X-Box 360' } + */ +#define POWER_SUPPLY 1 + +#if POWER_SUPPLY > 0 + // Enable this option to leave the PSU off at startup. + // Power to steppers and heaters will need to be turned on with M80. + //#define PS_DEFAULT_OFF +#endif + +// @section temperature + +//=========================================================================== +//============================= Thermal Settings ============================ +//=========================================================================== + +/** + * --NORMAL IS 4.7kohm PULLUP!-- 1kohm pullup can be used on hotend sensor, using correct resistor and table + * + * Temperature sensors available: + * + * -3 : thermocouple with MAX31855 (only for sensor 0) + * -2 : thermocouple with MAX6675 (only for sensor 0) + * -1 : thermocouple with AD595 + * 0 : not used + * 1 : 100k thermistor - best choice for EPCOS 100k (4.7k pullup) + * 2 : 200k thermistor - ATC Semitec 204GT-2 (4.7k pullup) + * 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 (Used in ParCan & J-Head) (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) + * 71 : 100k Honeywell thermistor 135-104LAF-J01 (4.7k pullup) + * 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) + * 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" + * 20 : the PT100 circuit found in the Ultimainboard V2.x + * 60 : 100k Maker's Tool Works Kapton Bed Thermistor beta=3950 + * 66 : 4.7M High Temperature thermistor from Dyze Design + * 70 : the 100K thermistor found in the bq Hephestos 2 + * 75 : 100k Generic Silicon Heat Pad with NTC 100K MGB18-104F39050L32 thermistor + * + * 1k ohm pullup tables - This is atypical, and requires changing out the 4.7k pullup for 1k. + * (but gives greater accuracy and more stable PID) + * 51 : 100k thermistor - EPCOS (1k pullup) + * 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 + * 1010 : Pt1000 with 1k pullup (non standard) + * 147 : Pt100 with 4k7 pullup + * 110 : Pt100 with 1k pullup (non standard) + * + * Use these for Testing or Development purposes. NEVER for production machine. + * 998 : Dummy Table that ALWAYS reads 25°C or the temperature defined below. + * 999 : Dummy Table that ALWAYS reads 100°C or the temperature defined below. + * + * :{ '0': "Not used", '1':"100k / 4.7k - EPCOS", '2':"200k / 4.7k - ATC Semitec 204GT-2", '3':"Mendel-parts / 4.7k", '4':"10k !! do not use for a hotend. Bad resolution at high temp. !!", '5':"100K / 4.7k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '6':"100k / 4.7k EPCOS - Not as accurate as Table 1", '7':"100k / 4.7k Honeywell 135-104LAG-J01", '8':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT", '9':"100k / 4.7k GE Sensing AL03006-58.2K-97-G1", '10':"100k / 4.7k RS 198-961", '11':"100k / 4.7k beta 3950 1%", '12':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT (calibrated for Makibox hot bed)", '13':"100k Hisens 3950 1% up to 300°C for hotend 'Simple ONE ' & hotend 'All In ONE'", '20':"PT100 (Ultimainboard V2.x)", '51':"100k / 1k - EPCOS", '52':"200k / 1k - ATC Semitec 204GT-2", '55':"100k / 1k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '60':"100k Maker's Tool Works Kapton Bed Thermistor beta=3950", '66':"Dyze Design 4.7M High Temperature thermistor", '70':"the 100K thermistor found in the bq Hephestos 2", '71':"100k / 4.7k Honeywell 135-104LAF-J01", '147':"Pt100 / 4.7k", '1047':"Pt1000 / 4.7k", '110':"Pt100 / 1k (non-standard)", '1010':"Pt1000 / 1k (non standard)", '-3':"Thermocouple + MAX31855 (only for sensor 0)", '-2':"Thermocouple + MAX6675 (only for sensor 0)", '-1':"Thermocouple + AD595",'998':"Dummy 1", '999':"Dummy 2" } + */ +#define TEMP_SENSOR_0 1 // DGlass3D = 5; RigidBot = 1; 3DSv6 = 5 +#define TEMP_SENSOR_1 0 +#define TEMP_SENSOR_2 0 +#define TEMP_SENSOR_3 0 +#define TEMP_SENSOR_4 0 +#define TEMP_SENSOR_BED 1 + +// Dummy thermistor constant temperature readings, for use with 998 and 999 +#define DUMMY_THERMISTOR_998_VALUE 25 +#define DUMMY_THERMISTOR_999_VALUE 100 + +// 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 +//#define MAX_REDUNDANT_TEMP_SENSOR_DIFF 10 + +// Extruder temperature must be close to target for this long before M109 returns success +#define TEMP_RESIDENCY_TIME 10 // (seconds) +#define TEMP_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// Bed temperature must be close to target for this long before M190 returns success +#define TEMP_BED_RESIDENCY_TIME 0 // (seconds) +#define TEMP_BED_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_BED_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// The minimal temperature defines the temperature below which the heater will not be enabled It is used +// to check that the wiring to the thermistor is not broken. +// Otherwise this would lead to the heater being powered on all the time. +#define HEATER_0_MINTEMP 5 +#define HEATER_1_MINTEMP 5 +#define HEATER_2_MINTEMP 5 +#define HEATER_3_MINTEMP 5 +#define HEATER_4_MINTEMP 5 +#define BED_MINTEMP 5 + +// When temperature exceeds max temp, your heater will be switched off. +// This feature exists to protect your hotend from overheating accidentally, but *NOT* from thermistor short/failure! +// You should use MINTEMP for thermistor short/failure protection. +#define HEATER_0_MAXTEMP 275 +#define HEATER_1_MAXTEMP 275 +#define HEATER_2_MAXTEMP 275 +#define HEATER_3_MAXTEMP 275 +#define HEATER_4_MAXTEMP 275 +#define BED_MAXTEMP 150 + +//=========================================================================== +//============================= PID Settings ================================ +//=========================================================================== +// PID Tuning Guide here: http://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 +#if ENABLED(PIDTEMP) + //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. + //#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. + #define K1 0.95 //smoothing factor within the PID + + // If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it + + // Rigidbot hotend + #define DEFAULT_Kp 16.17 + #define DEFAULT_Ki 0.85 + #define DEFAULT_Kd 76.55 + + // Base DGlass3D/E3Dv6 hotend + //#define DEFAULT_Kp 10 + //#define DEFAULT_Ki 0.85 + //#define DEFAULT_Kd 245 + + // E3D w/ rigidbot cartridge + //#define DEFAULT_Kp 16.30 + //#define DEFAULT_Ki 0.95 + //#define DEFAULT_Kd 69.69 + +#endif // PIDTEMP + +//=========================================================================== +//============================= PID > Bed Temperature Control =============== +//=========================================================================== +// Select PID or bang-bang with PIDTEMPBED. If bang-bang, BED_LIMIT_SWITCHING will enable hysteresis +// +// Uncomment this to enable PID on the bed. It uses the same frequency PWM as the extruder. +// If your PID_dT is the default, and correct for your hardware/configuration, that means 7.689Hz, +// which is fine for driving a square wave into a resistive load and does not significantly impact you FET heating. +// This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W heater. +// If your configuration is significantly different than this and you don't understand the issues involved, you probably +// shouldn't use bed PID until someone else verifies your hardware works. +// If this is enabled, find your own PID constants below. +//#define PIDTEMPBED + +//#define BED_LIMIT_SWITCHING + +// This sets the max power delivered to the bed, and replaces the HEATER_BED_DUTY_CYCLE_DIVIDER option. +// all forms of bed control obey this (PID, bang-bang, bang-bang with hysteresis) +// setting this to anything other than 255 enables a form of PWM to the bed just like HEATER_BED_DUTY_CYCLE_DIVIDER did, +// so you shouldn't use it unless you are OK with PWM on your bed. (see the comment on enabling PIDTEMPBED) +#define MAX_BED_POWER 255 // limits duty cycle to bed; 255=full current + +#if ENABLED(PIDTEMPBED) + + //#define PID_BED_DEBUG // Sends debug data to the serial port. + + //RigidBot, from pid autotune + #define DEFAULT_bedKp 355 + #define DEFAULT_bedKi 66.5 + #define DEFAULT_bedKd 480 + + // FIND YOUR OWN: "M303 E-1 C8 S90" to run autotune on the bed at 90 degreesC for 8 cycles. +#endif // PIDTEMPBED + +// @section extruder + +// This option prevents extrusion if the temperature is below EXTRUDE_MINTEMP. +// It also enables the M302 command to set the minimum extrusion temperature +// or to allow moving the extruder regardless of the hotend temperature. +// *** IT IS HIGHLY RECOMMENDED TO LEAVE THIS OPTION ENABLED! *** +#define PREVENT_COLD_EXTRUSION +#define EXTRUDE_MINTEMP 170 + +// This option prevents a single extrusion longer than EXTRUDE_MAXLENGTH. +// Note that for Bowden Extruders a too-small value here may prevent loading. +#define PREVENT_LENGTHY_EXTRUDE +#define EXTRUDE_MAXLENGTH 200 + +//=========================================================================== +//======================== Thermal Runaway Protection ======================= +//=========================================================================== + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * If you get "Thermal Runaway" or "Heating failed" errors the + * details can be tuned in Configuration_adv.h + */ + +#define THERMAL_PROTECTION_HOTENDS // Enable thermal protection for all extruders +#define THERMAL_PROTECTION_BED // Enable thermal protection for the heated bed + +//=========================================================================== +//============================= Mechanical Settings ========================= +//=========================================================================== + +// @section machine + +// Uncomment one of these options to enable CoreXY, CoreXZ, or CoreYZ kinematics +// either in the usual order or reversed +//#define COREXY +//#define COREXZ +//#define COREYZ +//#define COREYX +//#define COREZX +//#define COREZY + +//=========================================================================== +//============================== Endstop Settings =========================== +//=========================================================================== + +// @section homing + +// Specify here all the endstop connectors that are connected to any endstop or probe. +// Almost all printers will be using one per axis. Probes will use one or more of the +// extra connectors. Leave undefined any used for non-endstop and non-probe purposes. +#define USE_XMIN_PLUG +#define USE_YMIN_PLUG +#define USE_ZMIN_PLUG +//#define USE_XMAX_PLUG +//#define USE_YMAX_PLUG +//#define USE_ZMAX_PLUG + +// coarse Endstop Settings +#define ENDSTOPPULLUPS // Comment this out (using // at the start of the line) to disable the endstop pullup resistors + +#if DISABLED(ENDSTOPPULLUPS) + // fine endstop settings: Individual pullups. will be ignored if ENDSTOPPULLUPS is defined + //#define ENDSTOPPULLUP_XMAX + //#define ENDSTOPPULLUP_YMAX + //#define ENDSTOPPULLUP_ZMAX + //#define ENDSTOPPULLUP_XMIN + //#define ENDSTOPPULLUP_YMIN + //#define ENDSTOPPULLUP_ZMIN + //#define ENDSTOPPULLUP_ZMIN_PROBE +#endif + +// Mechanical endstop with COM to ground and NC to Signal uses "false" here (most common setup). +#define X_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Y_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define X_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Y_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MIN_PROBE_ENDSTOP_INVERTING true // set to true to invert the logic of the probe. + +// Enable this feature if all enabled endstop pins are interrupt-capable. +// This will remove the need to poll the interrupt pins, saving many CPU cycles. +//#define ENDSTOP_INTERRUPTS_FEATURE + +//============================================================================= +//============================== Movement Settings ============================ +//============================================================================= +// @section motion + +/** + * Default Settings + * + * These settings can be reset by M502 + * + * Note that if EEPROM is enabled, saved values will override these. + */ + +/** + * With this option each E stepper can have its own factors for the + * following movement settings. If fewer factors are given than the + * total number of extruders, the last value applies to the rest. + */ +//#define DISTINCT_E_FACTORS + +/** + * Default Axis Steps Per Unit (steps/mm) + * Override with M92 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ + // default steps per unit for RigidBot with standard hardware +#define DEFAULT_AXIS_STEPS_PER_UNIT { 44.3090, 22.1545, 1600, 53.5 } +// default steps for 16-tooth pulleys { 100.06, 50.06, 1600, 76 } // HPX2-MAX E=504, RigidBot E=53.5, Peter Stoneham's=76 + +/** + * Default Max Feed Rate (mm/s) + * Override with M203 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_FEEDRATE { 500, 500, 5, 25 } + +/** + * Default Max Acceleration (change/s) change = mm/s + * (Maximum start speed for accelerated moves) + * Override with M201 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_ACCELERATION { 800, 800, 100, 10000 } + +/** + * Default Acceleration (change/s) change = mm/s + * Override with M204 + * + * M204 P Acceleration + * M204 R Retract Acceleration + * M204 T Travel Acceleration + */ +#define DEFAULT_ACCELERATION 600 // X, Y, Z and E acceleration for printing moves +#define DEFAULT_RETRACT_ACCELERATION 1000 // E acceleration for retracts +#define DEFAULT_TRAVEL_ACCELERATION 3000 // X, Y, Z acceleration for travel (non printing) moves + +/** + * Default Jerk (mm/s) + * Override with M205 X Y Z E + * + * "Jerk" specifies the minimum speed change that requires acceleration. + * When changing speed and direction, if the difference is less than the + * value set here, it may happen instantaneously. + */ +#define DEFAULT_XJERK 8.0 +#define DEFAULT_YJERK 8.0 +#define DEFAULT_ZJERK 0.4 +#define DEFAULT_EJERK 5.0 + +//=========================================================================== +//============================= Z Probe Options ============================= +//=========================================================================== +// @section probes + +// +// See http://marlinfw.org/configuration/probes.html +// + +/** + * Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + * + * Enable this option for a probe connected to the Z Min endstop pin. + */ +#define Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + +/** + * Z_MIN_PROBE_ENDSTOP + * + * Enable this option for a probe connected to any pin except Z-Min. + * (By default Marlin assumes the Z-Max endstop pin.) + * To use a custom Z Probe pin, set Z_MIN_PROBE_PIN below. + * + * - The simplest option is to use a free endstop connector. + * - Use 5V for powered (usually inductive) sensors. + * + * - RAMPS 1.3/1.4 boards may use the 5V, GND, and Aux4->D32 pin: + * - For simple switches connect... + * - normally-closed switches to GND and D32. + * - normally-open switches to 5V and D32. + * + * WARNING: Setting the wrong pin may have unexpected and potentially + * disastrous consequences. Use with caution and do your homework. + * + */ +//#define Z_MIN_PROBE_ENDSTOP + +/** + * Probe Type + * + * Allen Key Probes, Servo Probes, Z-Sled Probes, FIX_MOUNTED_PROBE, etc. + * Activate one of these to use Auto Bed Leveling below. + */ + +/** + * The "Manual Probe" provides a means to do "Auto" Bed Leveling without a probe. + * Use G29 repeatedly, adjusting the Z height at each point with movement commands + * or (with LCD_BED_LEVELING) the LCD controller. + */ +//#define PROBE_MANUALLY + +/** + * A Fix-Mounted Probe either doesn't deploy or needs manual deployment. + * (e.g., an inductive probe or a nozzle-based probe-switch.) + */ +//#define FIX_MOUNTED_PROBE + +/** + * Z Servo Probe, such as an endstop switch on a rotating arm. + */ +//#define Z_ENDSTOP_SERVO_NR 0 // Defaults to SERVO 0 connector. +//#define Z_SERVO_ANGLES {70,0} // Z Servo Deploy and Stow angles + +/** + * The BLTouch probe uses a Hall effect sensor and emulates a servo. + */ +//#define BLTOUCH +#if ENABLED(BLTOUCH) + //#define BLTOUCH_DELAY 375 // (ms) Enable and increase if needed +#endif + +/** + * Enable one or more of the following if probing seems unreliable. + * Heaters and/or fans can be disabled during probing to minimize electrical + * noise. A delay can also be added to allow noise and vibration to settle. + * These options are most useful for the BLTouch probe, but may also improve + * readings with inductive probes and piezo sensors. + */ +//#define PROBING_HEATERS_OFF // Turn heaters off when probing +//#define PROBING_FANS_OFF // Turn fans off when probing +//#define DELAY_BEFORE_PROBING 200 // (ms) To prevent vibrations from triggering piezo sensors + +// A probe that is deployed and stowed with a solenoid pin (SOL1_PIN) +//#define SOLENOID_PROBE + +// A sled-mounted probe like those designed by Charles Bell. +//#define Z_PROBE_SLED +//#define SLED_DOCKING_OFFSET 5 // The extra distance the X axis must travel to pickup the sled. 0 should be fine but you can push it further if you'd like. + +// +// For Z_PROBE_ALLEN_KEY see the Delta example configurations. +// + +/** + * Z Probe to nozzle (X,Y) offset, relative to (0, 0). + * X and Y offsets must be integers. + * + * In the following example the X and Y offsets are both positive: + * #define X_PROBE_OFFSET_FROM_EXTRUDER 10 + * #define Y_PROBE_OFFSET_FROM_EXTRUDER 10 + * + * +-- BACK ---+ + * | | + * L | (+) P | R <-- probe (20,20) + * E | | I + * F | (-) N (+) | G <-- nozzle (10,10) + * T | | H + * | (-) | T + * | | + * O-- FRONT --+ + * (0,0) + */ +#define X_PROBE_OFFSET_FROM_EXTRUDER -25 // X offset: -left +right [of the nozzle] +#define Y_PROBE_OFFSET_FROM_EXTRUDER -29 // Y offset: -front +behind [the nozzle] +#define Z_PROBE_OFFSET_FROM_EXTRUDER -12.35 // Z offset: -below +above [the nozzle] + +// X and Y axis travel speed (mm/m) between probes +#define XY_PROBE_SPEED 8000 + +// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +#define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z + +// Speed for the "accurate" probe of each point +#define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) + +// Use double touch for probing +//#define PROBE_DOUBLE_TOUCH + +/** + * Z probes require clearance when deploying, stowing, and moving between + * probe points to avoid hitting the bed and other hardware. + * Servo-mounted probes require extra space for the arm to rotate. + * Inductive probes need space to keep from triggering early. + * + * Use these settings to specify the distance (mm) to raise the probe (or + * lower the bed). The values set here apply over and above any (negative) + * probe Z Offset set with Z_PROBE_OFFSET_FROM_EXTRUDER, M851, or the LCD. + * Only integer values >= 1 are valid here. + * + * Example: `M851 Z-5` with a CLEARANCE of 4 => 9mm from bed to nozzle. + * But: `M851 Z+1` with a CLEARANCE of 2 => 2mm from bed to nozzle. + */ +#define Z_CLEARANCE_DEPLOY_PROBE 15 // Z Clearance for Deploy/Stow +#define Z_CLEARANCE_BETWEEN_PROBES 5 // Z Clearance between probe points + +// For M851 give a range for adjusting the Z probe offset +#define Z_PROBE_OFFSET_RANGE_MIN -20 +#define Z_PROBE_OFFSET_RANGE_MAX 20 + +// Enable the M48 repeatability test to test probe accuracy +//#define Z_MIN_PROBE_REPEATABILITY_TEST + +// For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1 +// :{ 0:'Low', 1:'High' } +#define X_ENABLE_ON 0 +#define Y_ENABLE_ON 0 +#define Z_ENABLE_ON 0 +#define E_ENABLE_ON 0 // For all extruders + +// Disables axis stepper immediately when it's not being used. +// 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 +//#define DISABLE_REDUCED_ACCURACY_WARNING + +// @section extruder + +#define DISABLE_E false // For all extruders +#define DISABLE_INACTIVE_EXTRUDER true // Keep only the active extruder enabled. + +// @section machine + +// Invert the stepper direction. Change (or reverse the motor connector) if an axis goes the wrong way. +#define INVERT_X_DIR true +#define INVERT_Y_DIR false +#define INVERT_Z_DIR false + +// Enable this option for Toshiba stepper drivers +//#define CONFIG_STEPPERS_TOSHIBA + +// @section extruder + +// For direct drive extruder v9 set to true, for geared extruder set to false. +#define INVERT_E0_DIR true +#define INVERT_E1_DIR true +#define INVERT_E2_DIR false +#define INVERT_E3_DIR false +#define INVERT_E4_DIR false + +// @section homing + +//#define NO_MOTION_BEFORE_HOMING // Inhibit movement until all axes have been homed + +//#define Z_HOMING_HEIGHT 4 // (in mm) Minimal z height before homing (G28) for Z clearance above the bed, clamps, ... + // Be sure you have this distance over your Z_MAX_POS in case. + +// Direction of endstops when homing; 1=MAX, -1=MIN +// :[-1,1] +#define X_HOME_DIR -1 +#define Y_HOME_DIR -1 +#define Z_HOME_DIR -1 + +// @section machine + +// The size of the print bed +#define X_BED_SIZE 254 // RigidBot regular is 254mm, RigitBot Big is 406mm +#define Y_BED_SIZE 248 // RigidBot regular is 248mm, RigitBot Big is 304mm + +// Travel limits (mm) after homing, corresponding to endstop positions. +#define X_MIN_POS 0 +#define Y_MIN_POS 0 +#define Z_MIN_POS 0 +#define X_MAX_POS X_BED_SIZE +#define Y_MAX_POS Y_BED_SIZE +#define Z_MAX_POS 254 // RigidBot regular and Big are 254mm + +// If enabled, axes won't move below MIN_POS in response to movement commands. +#define MIN_SOFTWARE_ENDSTOPS +// If enabled, axes won't move above MAX_POS in response to movement commands. +#define MAX_SOFTWARE_ENDSTOPS + +/** + * Filament Runout Sensor + * A mechanical or opto endstop is used to check for the presence of filament. + * + * RAMPS-based boards use SERVO3_PIN. + * For other boards you may need to define FIL_RUNOUT_PIN. + * By default the firmware assumes HIGH = has filament, LOW = ran out + */ +//#define FILAMENT_RUNOUT_SENSOR +#if ENABLED(FILAMENT_RUNOUT_SENSOR) + #define FIL_RUNOUT_INVERTING false // set to true to invert the logic of the sensor. + #define ENDSTOPPULLUP_FIL_RUNOUT // Uncomment to use internal pullup for filament runout pins if the sensor is defined. + #define FILAMENT_RUNOUT_SCRIPT "M600" +#endif + +//=========================================================================== +//=============================== Bed Leveling ============================== +//=========================================================================== +// @section bedlevel + +/** + * Choose one of the options below to enable G29 Bed Leveling. The parameters + * and behavior of G29 will change depending on your selection. + * + * If using a Probe for Z Homing, enable Z_SAFE_HOMING also! + * + * - AUTO_BED_LEVELING_3POINT + * Probe 3 arbitrary points on the bed (that aren't collinear) + * You specify the XY coordinates of all 3 points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_LINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_BILINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a mesh, best for large or uneven beds. + * + * - AUTO_BED_LEVELING_UBL (Unified Bed Leveling) + * A comprehensive bed leveling system combining the features and benefits + * of other systems. UBL also includes integrated Mesh Generation, Mesh + * Validation and Mesh Editing systems. Currently, UBL is only checked out + * for Cartesian Printers. That said, it was primarily designed to correct + * poor quality Delta Printers. If you feel adventurous and have a Delta, + * please post an issue if something doesn't work correctly. Initially, + * you will need to set a reduced bed size so you have a rectangular area + * to test on. + * + * - MESH_BED_LEVELING + * Probe a grid manually + * The result is a mesh, suitable for large or uneven beds. (See BILINEAR.) + * For machines without a probe, Mesh Bed Leveling provides a method to perform + * leveling in steps so you can manually adjust the Z height at each grid-point. + * With an LCD controller the process is guided step-by-step. + */ +//#define AUTO_BED_LEVELING_3POINT +//#define AUTO_BED_LEVELING_LINEAR +//#define AUTO_BED_LEVELING_BILINEAR +//#define AUTO_BED_LEVELING_UBL +//#define MESH_BED_LEVELING + +/** + * Enable detailed logging of G28, G29, M48, etc. + * Turn on with the command 'M111 S32'. + * NOTE: Requires a lot of PROGMEM! + */ +//#define DEBUG_LEVELING_FEATURE + +#if ENABLED(MESH_BED_LEVELING) || ENABLED(AUTO_BED_LEVELING_BILINEAR) || ENABLED(AUTO_BED_LEVELING_UBL) + // Gradually reduce leveling correction until a set height is reached, + // at which point movement will be level to the machine's XY plane. + // The height can be set with M420 Z + #define ENABLE_LEVELING_FADE_HEIGHT +#endif + +#if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Set the number of grid points per dimension. + #define GRID_MAX_POINTS_X 3 + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + // Set the boundaries for probing (where the probe can reach). + #define LEFT_PROBE_BED_POSITION 15 + #define RIGHT_PROBE_BED_POSITION 170 + #define FRONT_PROBE_BED_POSITION 20 + #define BACK_PROBE_BED_POSITION 170 + + // The Z probe minimum outer margin (to validate G29 parameters). + #define MIN_PROBE_EDGE 10 + + // Probe along the Y axis, advancing X after each column + //#define PROBE_Y_FIRST + + #if ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Beyond the probed grid, continue the implied tilt? + // Default is to maintain the height of the nearest edge. + //#define EXTRAPOLATE_BEYOND_GRID + + // + // Experimental Subdivision of the grid by Catmull-Rom method. + // Synthesizes intermediate points to produce a more detailed mesh. + // + //#define ABL_BILINEAR_SUBDIVISION + #if ENABLED(ABL_BILINEAR_SUBDIVISION) + // Number of subdivisions between probe points + #define BILINEAR_SUBDIVISIONS 3 + #endif + + #endif + +#elif ENABLED(AUTO_BED_LEVELING_3POINT) + + // 3 arbitrary points to probe. + // A simple cross-product is used to estimate the plane of the bed. + #define ABL_PROBE_PT_1_X 15 + #define ABL_PROBE_PT_1_Y 180 + #define ABL_PROBE_PT_2_X 15 + #define ABL_PROBE_PT_2_Y 20 + #define ABL_PROBE_PT_3_X 170 + #define ABL_PROBE_PT_3_Y 20 + +#elif ENABLED(AUTO_BED_LEVELING_UBL) + + //=========================================================================== + //========================= Unified Bed Leveling ============================ + //=========================================================================== + + #define UBL_MESH_INSET 1 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 10 // Don't use more than 15 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + #define UBL_PROBE_PT_1_X 39 // Probing points for 3-Point leveling of the mesh + #define UBL_PROBE_PT_1_Y 180 + #define UBL_PROBE_PT_2_X 39 + #define UBL_PROBE_PT_2_Y 20 + #define UBL_PROBE_PT_3_X 180 + #define UBL_PROBE_PT_3_Y 20 + + #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation + #define UBL_MESH_EDIT_MOVES_Z // Sophisticated users prefer no movement of nozzle + +#elif ENABLED(MESH_BED_LEVELING) + + //=========================================================================== + //=================================== Mesh ================================== + //=========================================================================== + + #define MESH_INSET 10 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 3 // Don't use more than 7 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + //#define MESH_G28_REST_ORIGIN // After homing all axes ('G28' or 'G28 XYZ') rest Z at Z_MIN_POS + +#endif // BED_LEVELING + +/** + * Use the LCD controller for bed leveling + * Requires MESH_BED_LEVELING or PROBE_MANUALLY + */ +//#define LCD_BED_LEVELING + +#if ENABLED(LCD_BED_LEVELING) + #define MBL_Z_STEP 0.025 // Step size while manually probing Z axis. + #define LCD_PROBE_Z_RANGE 4 // Z Range centered on Z_MIN_POS for LCD Z adjustment +#endif + +// Add a menu item to move between bed corners for manual bed adjustment +//#define LEVEL_BED_CORNERS + +/** + * Commands to execute at the end of G29 probing. + * Useful to retract or move the Z probe out of the way. + */ +//#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) +//#define BED_CENTER_AT_0_0 + +// Manually set the home position. Leave these undefined for automatic settings. +// For DELTA this is the top-center of the Cartesian print volume. +//#define MANUAL_X_HOME_POS 0 +//#define MANUAL_Y_HOME_POS 0 +//#define MANUAL_Z_HOME_POS 0 + +// Use "Z Safe Homing" to avoid homing with a Z probe outside the bed area. +// +// With this feature enabled: +// +// - 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). +// - 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 axis (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). +#endif + +// Homing speeds (mm/m) +#define HOMING_FEEDRATE_XY (50*60) +#define HOMING_FEEDRATE_Z (15*60) + +//============================================================================= +//============================= Additional Features =========================== +//============================================================================= + +// @section extras + +// +// EEPROM +// +// The microcontroller can store settings in the EEPROM, e.g. max velocity... +// M500 - stores parameters in EEPROM +// M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily). +// M502 - reverts to the default "factory settings". You still need to store them in EEPROM afterwards if you want to. +// +#define EEPROM_SETTINGS // Enable for M500 and M501 commands +//#define DISABLE_M503 // Saves ~2700 bytes of PROGMEM. Disable for release! +#define EEPROM_CHITCHAT // Give feedback on EEPROM commands. Disable to save PROGMEM. + +// +// Host Keepalive +// +// When enabled Marlin will send a busy status message to the host +// every couple of seconds when it can't accept commands. +// +#define HOST_KEEPALIVE_FEATURE // Disable this if your host doesn't like keepalive messages +#define DEFAULT_KEEPALIVE_INTERVAL 2 // Number of seconds between "busy" messages. Set with M113. +#define BUSY_WHILE_HEATING // Some hosts require "busy" messages even during heating + +// +// M100 Free Memory Watcher +// +//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose + +// +// G20/G21 Inch mode support +// +//#define INCH_MODE_SUPPORT + +// +// M149 Set temperature units support +// +//#define TEMPERATURE_UNITS_SUPPORT + +// @section temperature + +// Preheat Constants +#define PREHEAT_1_TEMP_HOTEND 180 +#define PREHEAT_1_TEMP_BED 70 +#define PREHEAT_1_FAN_SPEED 255 // Value from 0 to 255 + +#define PREHEAT_2_TEMP_HOTEND 240 +#define PREHEAT_2_TEMP_BED 110 +#define PREHEAT_2_FAN_SPEED 255 // Value from 0 to 255 + +/** + * Nozzle Park -- EXPERIMENTAL + * + * Park the nozzle at the given XYZ position on idle or G27. + * + * The "P" parameter controls the action applied to the Z axis: + * + * P0 (Default) If Z is below park Z raise the nozzle. + * P1 Raise the nozzle always to Z-park height. + * P2 Raise the nozzle by Z-park amount, limited to Z_MAX_POS. + */ +//#define NOZZLE_PARK_FEATURE + +#if ENABLED(NOZZLE_PARK_FEATURE) + // Specify a park position as { X, Y, Z } + #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 } +#endif + +/** + * Clean Nozzle Feature -- EXPERIMENTAL + * + * Adds the G12 command to perform a nozzle cleaning process. + * + * Parameters: + * P Pattern + * S Strokes / Repetitions + * T Triangles (P1 only) + * + * Patterns: + * P0 Straight line (default). This process requires a sponge type material + * at a fixed bed location. "S" specifies strokes (i.e. back-forth motions) + * between the start / end points. + * + * P1 Zig-zag pattern between (X0, Y0) and (X1, Y1), "T" specifies the + * number of zig-zag triangles to do. "S" defines the number of strokes. + * Zig-zags are done in whichever is the narrower dimension. + * For example, "G12 P1 S1 T3" will execute: + * + * -- + * | (X0, Y1) | /\ /\ /\ | (X1, Y1) + * | | / \ / \ / \ | + * A | | / \ / \ / \ | + * | | / \ / \ / \ | + * | (X0, Y0) | / \/ \/ \ | (X1, Y0) + * -- +--------------------------------+ + * |________|_________|_________| + * T1 T2 T3 + * + * P2 Circular pattern with middle at NOZZLE_CLEAN_CIRCLE_MIDDLE. + * "R" specifies the radius. "S" specifies the stroke count. + * Before starting, the nozzle moves to NOZZLE_CLEAN_START_POINT. + * + * Caveats: The ending Z should be the same as starting Z. + * Attention: EXPERIMENTAL. G-code arguments may change. + * + */ +//#define NOZZLE_CLEAN_FEATURE + +#if ENABLED(NOZZLE_CLEAN_FEATURE) + // Default number of pattern repetitions + #define NOZZLE_CLEAN_STROKES 12 + + // Default number of triangles + #define NOZZLE_CLEAN_TRIANGLES 3 + + // Specify positions as { X, Y, Z } + #define NOZZLE_CLEAN_START_POINT { 30, 30, (Z_MIN_POS + 1)} + #define NOZZLE_CLEAN_END_POINT {100, 60, (Z_MIN_POS + 1)} + + // Circular pattern radius + #define NOZZLE_CLEAN_CIRCLE_RADIUS 6.5 + // Circular pattern circle fragments number + #define NOZZLE_CLEAN_CIRCLE_FN 10 + // Middle point of circle + #define NOZZLE_CLEAN_CIRCLE_MIDDLE NOZZLE_CLEAN_START_POINT + + // Moves the nozzle to the initial position + #define NOZZLE_CLEAN_GOBACK +#endif + +/** + * Print Job Timer + * + * Automatically start and stop the print job timer on M104/M109/M190. + * + * M104 (hotend, no wait) - high temp = none, low temp = stop timer + * M109 (hotend, wait) - high temp = start timer, low temp = stop timer + * M190 (bed, wait) - high temp = start timer, low temp = none + * + * The timer can also be controlled with the following commands: + * + * M75 - Start the print job timer + * M76 - Pause the print job timer + * M77 - Stop the print job timer + */ +#define PRINTJOB_TIMER_AUTOSTART + +/** + * Print Counter + * + * Track statistical data such as: + * + * - Total print jobs + * - Total successful print jobs + * - Total failed print jobs + * - Total time printing + * + * View the current statistics with M78. + */ +//#define PRINTCOUNTER + +//============================================================================= +//============================= LCD and SD support ============================ +//============================================================================= + +// @section lcd + +/** + * LCD LANGUAGE + * + * Select the language to display on the LCD. These languages are available: + * + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, + * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * tr, uk, zh_CN, zh_TW, test + * + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + */ +#define LCD_LANGUAGE en + +/** + * LCD Character Set + * + * Note: This option is NOT applicable to Graphical Displays. + * + * All character-based LCDs provide ASCII plus one of these + * language extensions: + * + * - JAPANESE ... the most common + * - WESTERN ... with more accented characters + * - CYRILLIC ... for the Russian language + * + * To determine the language extension installed on your controller: + * + * - Compile and upload with LCD_LANGUAGE set to 'test' + * - 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 + * + * :['JAPANESE', 'WESTERN', 'CYRILLIC'] + */ +#define DISPLAY_CHARSET_HD44780 JAPANESE + +/** + * LCD TYPE + * + * Enable ULTRA_LCD for a 16x2, 16x4, 20x2, or 20x4 character-based LCD. + * Enable DOGLCD for a 128x64 (ST7565R) Full Graphical Display. + * (These options will be enabled automatically for most displays.) + * + * IMPORTANT: The U8glib library is required for Full Graphic Display! + * https://github.com/olikraus/U8glib_Arduino + */ +//#define ULTRA_LCD // Character based +//#define DOGLCD // Full graphics display + +/** + * SD CARD + * + * 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 + +/** + * SD CARD: SPI SPEED + * + * Enable one of the following items for a slower SPI transfer speed. + * This may be required to resolve "volume init" errors. + */ +//#define SPI_SPEED SPI_HALF_SPEED +//#define SPI_SPEED SPI_QUARTER_SPEED +#define SPI_SPEED SPI_EIGHTH_SPEED + +/** + * SD CARD: ENABLE CRC + * + * Use CRC checks and retries on the SD communication. + */ +//#define SD_CHECK_AND_RETRY + +// +// ENCODER SETTINGS +// +// This option overrides the default number of encoder pulses needed to +// produce one step. Should be increased for high-resolution encoders. +// +//#define ENCODER_PULSES_PER_STEP 1 + +// +// Use this option to override the number of step signals required to +// move between next/prev menu items. +// +//#define ENCODER_STEPS_PER_MENU_ITEM 5 + +/** + * Encoder Direction Options + * + * Test your encoder's behavior first with both options disabled. + * + * Reversed Value Edit and Menu Nav? Enable REVERSE_ENCODER_DIRECTION. + * Reversed Menu Navigation only? Enable REVERSE_MENU_DIRECTION. + * Reversed Value Editing only? Enable BOTH options. + */ + +// +// This option reverses the encoder direction everywhere. +// +// Set this option if CLOCKWISE causes values to DECREASE +// +//#define REVERSE_ENCODER_DIRECTION + +// +// This option reverses the encoder direction for navigating LCD menus. +// +// If CLOCKWISE normally moves DOWN this makes it go UP. +// If CLOCKWISE normally moves UP this makes it go DOWN. +// +//#define REVERSE_MENU_DIRECTION + +// +// Individual Axis Homing +// +// Add individual axis homing items (Home X, Home Y, and Home Z) to the LCD menu. +// +//#define INDIVIDUAL_AXIS_HOMING_MENU + +// +// SPEAKER/BUZZER +// +// If you have a speaker that can produce tones, enable it here. +// By default Marlin assumes you have a buzzer with a fixed frequency. +// +//#define SPEAKER + +// +// The duration and frequency for the UI feedback sound. +// Set these to 0 to disable audio feedback in the LCD menus. +// +// Note: Test audio output with the G-Code: +// M300 S P +// +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 +//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 + +// +// CONTROLLER TYPE: Standard +// +// Marlin supports a wide variety of controllers. +// Enable one of the following options to specify your controller. +// + +// +// ULTIMAKER Controller. +// +//#define ULTIMAKERCONTROLLER + +// +// ULTIPANEL as seen on Thingiverse. +// +//#define ULTIPANEL + +// +// PanelOne from T3P3 (via RAMPS 1.4 AUX2/AUX3) +// http://reprap.org/wiki/PanelOne +// +//#define PANEL_ONE + +// +// MaKr3d Makr-Panel with graphic controller and SD support. +// http://reprap.org/wiki/MaKr3d_MaKrPanel +// +//#define MAKRPANEL + +// +// ReprapWorld Graphical LCD +// https://reprapworld.com/?products_details&products_id/1218 +// +//#define REPRAPWORLD_GRAPHICAL_LCD + +// +// Activate one of these if you have a Panucatt Devices +// Viki 2.0 or mini Viki with Graphic LCD +// http://panucatt.com +// +//#define VIKI2 +//#define miniVIKI + +// +// Adafruit ST7565 Full Graphic Controller. +// https://github.com/eboston/Adafruit-ST7565-Full-Graphic-Controller/ +// +//#define ELB_FULL_GRAPHIC_CONTROLLER + +// +// RepRapDiscount Smart Controller. +// http://reprap.org/wiki/RepRapDiscount_Smart_Controller +// +// Note: Usually sold with a white PCB. +// +//#define REPRAP_DISCOUNT_SMART_CONTROLLER + +// +// GADGETS3D G3D LCD/SD Controller +// http://reprap.org/wiki/RAMPS_1.3/1.4_GADGETS3D_Shield_with_Panel +// +// Note: Usually sold with a blue PCB. +// +//#define G3D_PANEL + +// +// RepRapDiscount FULL GRAPHIC Smart Controller +// http://reprap.org/wiki/RepRapDiscount_Full_Graphic_Smart_Controller +// +// RigidBoard: To rewire this for a RigidBot see http://rigidtalk.com/wiki/index.php?title=LCD_Smart_Controller +// +//#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER + +// +// MakerLab Mini Panel with graphic +// controller and SD support - http://reprap.org/wiki/Mini_panel +// +//#define MINIPANEL + +// +// RepRapWorld REPRAPWORLD_KEYPAD v1.1 +// http://reprapworld.com/?products_details&products_id=202&cPath=1591_1626 +// +// REPRAPWORLD_KEYPAD_MOVE_STEP sets how much should the robot move when a key +// is pressed, a value of 10.0 means 10mm per click. +// +//#define REPRAPWORLD_KEYPAD +//#define REPRAPWORLD_KEYPAD_MOVE_STEP 1.0 + +// +// RigidBot Panel V1.0 +// http://www.inventapart.com/ +// +#define RIGIDBOT_PANEL + +// +// BQ LCD Smart Controller shipped by +// default with the BQ Hephestos 2 and Witbox 2. +// +//#define BQ_LCD_SMART_CONTROLLER + +// +// Cartesio UI +// http://mauk.cc/webshop/cartesio-shop/electronics/user-interface +// +//#define CARTESIO_UI + +// +// ANET_10 Controller supported displays. +// +//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. + // This LCD is known to be susceptible to electrical interference + // which scrambles the display. Pressing any button clears it up. +//#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 + // A clone of the RepRapDiscount full graphics display but with + // different pins/wiring (see pins_ANET_10.h). + +// +// LCD for Melzi Card with Graphical LCD +// +//#define LCD_FOR_MELZI + +// +// CONTROLLER TYPE: I2C +// +// Note: These controllers require the installation of Arduino's LiquidCrystal_I2C +// library. For more info: https://github.com/kiyoshigawa/LiquidCrystal_I2C +// + +// +// Elefu RA Board Control Panel +// http://www.elefu.com/index.php?route=product/product&product_id=53 +// +//#define RA_CONTROL_PANEL + +// +// Sainsmart YW Robot (LCM1602) LCD Display +// +// Note: This controller requires F.Malpartida's LiquidCrystal_I2C library +// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home +// +//#define LCD_I2C_SAINSMART_YWROBOT + +// +// Generic LCM1602 LCD adapter +// +//#define LCM1602 + +// +// PANELOLU2 LCD with status LEDs, +// separate encoder and click inputs. +// +// Note: This controller requires Arduino's LiquidTWI2 library v1.2.3 or later. +// For more info: https://github.com/lincomatic/LiquidTWI2 +// +// Note: The PANELOLU2 encoder click input can either be directly connected to +// a pin (if BTN_ENC defined to != -1) or read through I2C (when BTN_ENC == -1). +// +//#define LCD_I2C_PANELOLU2 + +// +// Panucatt VIKI LCD with status LEDs, +// integrated click & L/R/U/D buttons, separate encoder inputs. +// +//#define LCD_I2C_VIKI + +// +// SSD1306 OLED full graphics generic display +// +//#define U8GLIB_SSD1306 + +// +// SAV OLEd LCD module support using either SSD1306 or SH1106 based LCD modules +// +//#define SAV_3DGLCD +#if ENABLED(SAV_3DGLCD) + //#define U8GLIB_SSD1306 + #define U8GLIB_SH1106 +#endif + +// +// CONTROLLER TYPE: Shift register panels +// +// 2 wire Non-latching LCD SR from https://goo.gl/aJJ4sH +// LCD configuration: http://reprap.org/wiki/SAV_3D_LCD +// +//#define SAV_3DLCD + +// +// TinyBoy2 128x64 OLED / Encoder Panel +// +//#define OLED_PANEL_TINYBOY2 + +// +// Makeboard 3D Printer Parts 3D Printer Mini Display 1602 Mini Controller +// https://www.aliexpress.com/item/Micromake-Makeboard-3D-Printer-Parts-3D-Printer-Mini-Display-1602-Mini-Controller-Compatible-with-Ramps-1/32765887917.html +// +//#define MAKEBOARD_MINI_2_LINE_DISPLAY_1602 + +// +// MKS MINI12864 with graphic controller and SD support +// http://reprap.org/wiki/MKS_MINI_12864 +// +//#define MKS_MINI_12864 + +// +// Factory display for Creality CR-10 +// https://www.aliexpress.com/item/Universal-LCD-12864-3D-Printer-Display-Screen-With-Encoder-For-CR-10-CR-7-Model/32833148327.html +// +// This is RAMPS-compatible using a single 10-pin connector. +// (For CR-10 owners who want to replace the Melzi Creality board but retain the display) +// +//#define CR10_STOCKDISPLAY + +// +// MKS OLED 1.3" 128 × 64 FULL GRAPHICS CONTROLLER +// http://reprap.org/wiki/MKS_12864OLED +// +// Tiny, but very sharp OLED display +// +//#define MKS_12864OLED + +//============================================================================= +//=============================== Extra Features ============================== +//============================================================================= + +// @section extras + +// Increase the FAN PWM frequency. Removes the PWM noise but increases heating in the FET/Arduino +//#define FAST_PWM_FAN + +// Use software PWM to drive the fan, as for the heaters. This uses a very low frequency +// which is not as annoying as with the hardware PWM. On the other hand, if this frequency +// is too low, you should also increment SOFT_PWM_SCALE. +//#define FAN_SOFT_PWM + +// Incrementing this by 1 will double the software PWM frequency, +// affecting heaters, and the fan if FAN_SOFT_PWM is enabled. +// However, control resolution will be halved for each increment; +// at zero value, there are 128 effective control positions. +#define SOFT_PWM_SCALE 0 + +// If SOFT_PWM_SCALE is set to a value higher than 0, dithering can +// be used to mitigate the associated resolution loss. If enabled, +// some of the PWM cycles are stretched so on average the desired +// duty cycle is attained. +//#define SOFT_PWM_DITHER + +// Temperature status LEDs that display the hotend and bed temperature. +// If all hotends, bed temperature, and target temperature are under 54C +// then the BLUE led is on. Otherwise the RED led is on. (1C hysteresis) +//#define TEMP_STAT_LEDS + +// M240 Triggers a camera by emulating a Canon RC-1 Remote +// Data from: http://www.doc-diy.net/photo/rc-1_hacked/ +//#define PHOTOGRAPH_PIN 23 + +// 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 + +// Support for BlinkM/CyzRgb +//#define BLINKM + +// Support for PCA9632 PWM LED driver +//#define PCA9632 + +/** + * RGB LED / LED Strip Control + * + * Enable support for an RGB LED connected to 5V digital pins, or + * an RGB Strip connected to MOSFETs controlled by digital pins. + * + * 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 overall brightness parameters is also available + * + * *** CAUTION *** + * LED Strips require a MOFSET 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! + * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino + * cannot handle such current, separate 5V power supply must be used + * *** CAUTION *** + * + * LED type. This options are mutualy exclusive. Uncomment only one. + * + */ +//#define RGB_LED +//#define RGBW_LED + +#if ENABLED(RGB_LED) || ENABLED(RGBW_LED) + #define RGB_LED_R_PIN 34 + #define RGB_LED_G_PIN 43 + #define RGB_LED_B_PIN 35 + #define RGB_LED_W_PIN -1 +#endif + +// 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 (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) + #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip + #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time + #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + //#define NEOPIXEL_STARTUP_TEST // Cycle through colors at startup +#endif + +/** + * Printer Event LEDs + * + * During printing, the LEDs will reflect the printer status: + * + * - Gradually change from blue to violet as the heated bed gets to target temp + * - Gradually change from violet to red as the hotend gets to temperature + * - Change to white to illuminate work surface + * - Change to green once print has finished + * - Turn off after the print has finished and the user has pushed a button + */ +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) + #define PRINTER_EVENT_LEDS +#endif + +/*********************************************************************\ +* R/C SERVO support +* Sponsored by TrinityLabs, Reworked by codexmas +**********************************************************************/ + +// Number of servos +// +// If you select a configuration below, this will receive a default value and does not need to be set manually +// set it manually if you have more servos than extruders and wish to manually control some +// leaving it undefined or defining as 0 will disable the servo subsystem +// If unsure, leave commented / disabled +// +//#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command + +// Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. +// 300ms is a good value but you can try less delay. +// If the servo can't reach the requested position, increase it. +#define SERVO_DELAY { 300 } + +// Servo deactivation +// +// With this option servos are powered only during movement, then turned off to prevent jitter. +//#define DEACTIVATE_SERVOS_AFTER_MOVE + +/** + * Filament Width Sensor + * + * Measures the filament width in real-time and adjusts + * flow rate to compensate for any irregularities. + * + * Also allows the measured filament diameter to set the + * extrusion rate, so the slicer only has to specify the + * volume. + * + * Only a single extruder is supported at this time. + * + * 34 RAMPS_14 : Analog input 5 on the AUX2 connector + * 81 PRINTRBOARD : Analog input 2 on the Exp1 connector (version B,C,D,E) + * 301 RAMBO : Analog input 3 + * + * Note: May require analog pins to be defined for other boards. + */ +//#define FILAMENT_WIDTH_SENSOR + +#define DEFAULT_NOMINAL_FILAMENT_DIA 3.00 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. + +#if ENABLED(FILAMENT_WIDTH_SENSOR) + #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) + #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber + + #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading + #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading + #define MAX_MEASUREMENT_DELAY 20 // (bytes) Buffer size for stored measurements (1 byte per cm). Must be larger than MEASUREMENT_DELAY_CM. + + #define DEFAULT_MEASURED_FILAMENT_DIA DEFAULT_NOMINAL_FILAMENT_DIA // Set measured to nominal initially + + // Display filament width on the LCD status line. Status messages will expire after 5 seconds. + //#define FILAMENT_LCD_DISPLAY +#endif + +#endif // CONFIGURATION_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/RigidBot/Configuration_adv.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/RigidBot/Configuration_adv.h new file mode 100644 index 00000000..e488c514 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/RigidBot/Configuration_adv.h @@ -0,0 +1,1424 @@ +/** + * 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 . + * + */ + +/** + * Configuration_adv.h + * + * Advanced settings. + * Only change these if you know exactly what you're doing. + * Some of these settings can damage your printer if improperly set! + * + * Basic settings can be found in Configuration.h + * + */ +#ifndef CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H_VERSION 010100 + +// @section temperature + +//=========================================================================== +//=============================Thermal Settings ============================ +//=========================================================================== + +#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 + #endif +#endif + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * The solution: Once the temperature reaches the target, start observing. + * If the temperature stays too far below the target (hysteresis) for too long (period), + * the firmware will halt the machine as a safety precaution. + * + * If you get false positives for "Thermal Runaway" increase THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD + */ +#if ENABLED(THERMAL_PROTECTION_HOTENDS) + #define THERMAL_PROTECTION_PERIOD 40 // Seconds + #define THERMAL_PROTECTION_HYSTERESIS 4 // Degrees Celsius + + /** + * Whenever an M104 or M109 increases the target temperature the firmware will wait for the + * WATCH_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get false positives for "Heating failed" increase WATCH_TEMP_PERIOD and/or decrease WATCH_TEMP_INCREASE + * WATCH_TEMP_INCREASE should not be below 2. + */ + #define WATCH_TEMP_PERIOD 20 // Seconds + #define WATCH_TEMP_INCREASE 2 // Degrees Celsius +#endif + +/** + * Thermal Protection parameters for the bed are just as above for hotends. + */ +#if ENABLED(THERMAL_PROTECTION_BED) + #define THERMAL_PROTECTION_BED_PERIOD 20 // Seconds + #define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius + + /** + * Whenever an M140 or M190 increases the target temperature the firmware will wait for the + * WATCH_BED_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_BED_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get too many "Heating failed" errors, increase WATCH_BED_TEMP_PERIOD and/or decrease + * WATCH_BED_TEMP_INCREASE. (WATCH_BED_TEMP_INCREASE should not be below 2.) + */ + #define WATCH_BED_TEMP_PERIOD 60 // Seconds + #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius +#endif + +#if ENABLED(PIDTEMP) + // this adds an experimental additional term to the heating power, proportional to the extrusion speed. + // if Kc is chosen well, the additional required power due to increased melting should be compensated. + //#define PID_EXTRUSION_SCALING + #if ENABLED(PID_EXTRUSION_SCALING) + #define DEFAULT_Kc (100) //heating power=Kc*(e_speed) + #define LPQ_MAX_LEN 50 + #endif +#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 + */ +#define AUTOTEMP +#if ENABLED(AUTOTEMP) + #define AUTOTEMP_OLDWEIGHT 0.98 +#endif + +// Show Temperature ADC value +// Enable for M105 to include ADC values read from temperature sensors. +//#define SHOW_TEMP_ADC_VALUES + +/** + * High Temperature Thermistor Support + * + * Thermistors able to support high temperature tend to have a hard time getting + * good readings at room and lower temperatures. This means HEATER_X_RAW_LO_TEMP + * will probably be caught when the heating element first turns on during the + * preheating process, which will trigger a min_temp_error as a safety measure + * and force stop everything. + * To circumvent this limitation, we allow for a preheat time (during which, + * min_temp_error won't be triggered) and add a min_temp buffer to handle + * aberrant readings. + * + * If you want to enable this feature for your hotend thermistor(s) + * uncomment and set values > 0 in the constants below + */ + +// The number of consecutive low temperature errors that can occur +// before a min_temp_error is triggered. (Shouldn't be more than 10.) +//#define MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED 0 + +// The number of milliseconds a hotend will preheat before starting to check +// the temperature. This value should NOT be set to the time it takes the +// hot end to reach the target temperature, but the time it takes to reach +// the minimum temperature your thermistor can read. The lower the better/safer. +// This shouldn't need to be more than 30 seconds (30000) +//#define MILLISECONDS_PREHEAT_TIME 0 + +// @section extruder + +// Extruder runout prevention. +// If the machine is idle and the temperature over MINTEMP +// then extrude some filament every couple of SECONDS. +//#define EXTRUDER_RUNOUT_PREVENT +#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_EXTRUDE 5 // mm +#endif + +// @section temperature + +//These defines help to calibrate the AD595 sensor in case you get wrong temperature measurements. +//The measured temperature is defined as "actualTemp = (measuredTemp * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET" +#define TEMP_SENSOR_AD595_OFFSET 0.0 +#define TEMP_SENSOR_AD595_GAIN 1.0 + +/** + * 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. + */ +#define USE_CONTROLLER_FAN +#if ENABLED(USE_CONTROLLER_FAN) + #define CONTROLLER_FAN_PIN 4 // 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 +#endif + +// When first starting the main fan, run it at full speed for the +// given number of milliseconds. This gets the fan spinning reliably +// before setting a PWM value. (Does not work with software PWM for fan on Sanguinololu) +//#define FAN_KICKSTART_TIME 100 + +// This defines the minimal speed for the main fan, run in PWM mode +// to enable uncomment and set minimal PWM speed for reliable running (1-255) +// if fan speed is [1 - (FAN_MIN_PWM-1)] it is set to FAN_MIN_PWM +//#define FAN_MIN_PWM 50 + +// @section extruder + +/** + * Extruder cooling fans + * + * Extruder auto fans automatically turn on when their extruders' + * temperatures go above EXTRUDER_AUTO_FAN_TEMPERATURE. + * + * Your board's pins file specifies the recommended pins. Override those here + * or set to -1 to disable completely. + * + * Multiple extruders can be assigned to the same pin in which case + * the fan will turn on when any selected extruder is above the threshold. + */ +#define E0_AUTO_FAN_PIN -1 +#define E1_AUTO_FAN_PIN -1 +#define E2_AUTO_FAN_PIN -1 +#define E3_AUTO_FAN_PIN -1 +#define E4_AUTO_FAN_PIN -1 +#define EXTRUDER_AUTO_FAN_TEMPERATURE 50 +#define EXTRUDER_AUTO_FAN_SPEED 255 // == full speed + +/** + * Part-Cooling Fan Multiplexer + * + * This feature allows you to digitally multiplex the fan output. + * The multiplexer is automatically switched at tool-change. + * Set FANMUX[012]_PINs below for up to 2, 4, or 8 multiplexed fans. + */ +#define FANMUX0_PIN -1 +#define FANMUX1_PIN -1 +#define FANMUX2_PIN -1 + +/** + * M355 Case Light on-off / brightness + */ +//#define CASE_LIGHT_ENABLE +#if ENABLED(CASE_LIGHT_ENABLE) + //#define CASE_LIGHT_PIN 4 // Override the default pin if needed + #define INVERT_CASE_LIGHT false // Set true if Case Light is ON when pin is LOW + #define CASE_LIGHT_DEFAULT_ON true // Set default power-up state on + #define CASE_LIGHT_DEFAULT_BRIGHTNESS 105 // Set default power-up brightness (0-255, requires PWM pin) + //#define MENU_ITEM_CASE_LIGHT // Add a Case Light option to the LCD main menu +#endif + +//=========================================================================== +//============================ Mechanical Settings ========================== +//=========================================================================== + +// @section homing + +// If you want endstops to stay on (by default) even when not homing +// enable this option. Override at any time with M120, M121. +//#define ENDSTOPS_ALWAYS_ON_DEFAULT + +// @section extras + +//#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. + +// Dual X Steppers +// Uncomment this option to drive two X axis motors. +// The next unused E driver will be assigned to the second X stepper. +//#define X_DUAL_STEPPER_DRIVERS +#if ENABLED(X_DUAL_STEPPER_DRIVERS) + // Set true if the two X motors need to rotate in opposite directions + #define INVERT_X2_VS_X_DIR true +#endif + +// Dual Y Steppers +// Uncomment this option to drive two Y axis motors. +// The next unused E driver will be assigned to the second Y stepper. +//#define Y_DUAL_STEPPER_DRIVERS +#if ENABLED(Y_DUAL_STEPPER_DRIVERS) + // Set true if the two Y motors need to rotate in opposite directions + #define INVERT_Y2_VS_Y_DIR true +#endif + +// A single Z stepper driver is usually used to drive 2 stepper motors. +// Uncomment this option to use a separate stepper driver for each Z axis motor. +// The next unused E driver will be assigned to the second Z stepper. +//#define Z_DUAL_STEPPER_DRIVERS + +#if ENABLED(Z_DUAL_STEPPER_DRIVERS) + + // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper. + // That way the machine is capable to align the bed during home, since both Z steppers are homed. + // There is also an implementation of M666 (software endstops adjustment) to this feature. + // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed. + // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2. + // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive. + // Play a little bit with small adjustments (0.5mm) and check the behaviour. + // The M119 (endstops report) will start reporting the Z2 Endstop as well. + + //#define Z_DUAL_ENDSTOPS + + #if ENABLED(Z_DUAL_ENDSTOPS) + #define Z2_USE_ENDSTOP _XMAX_ + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 // Use M666 to determine/test this value + #endif + +#endif // Z_DUAL_STEPPER_DRIVERS + +// Enable this for dual x-carriage printers. +// A dual x-carriage design has the advantage that the inactive extruder can be parked which +// prevents hot-end ooze contaminating the print. It also reduces the weight of each x-carriage +// allowing faster printing speeds. Connect your X2 stepper to the first unused E plug. +//#define DUAL_X_CARRIAGE +#if ENABLED(DUAL_X_CARRIAGE) + // Configuration for second X-carriage + // Note: the first x-carriage is defined as the x-carriage which homes to the minimum endstop; + // the second x-carriage always homes to the maximum endstop. + #define X2_MIN_POS 80 // set minimum to ensure second x-carriage doesn't hit the parked first X-carriage + #define X2_MAX_POS 353 // set maximum to the distance between toolheads when both heads are homed + #define X2_HOME_DIR 1 // the second X-carriage always homes to the maximum endstop position + #define X2_HOME_POS X2_MAX_POS // default home position is the maximum carriage position + // However: In this mode the HOTEND_OFFSET_X value for the second extruder provides a software + // override for X2_HOME_POS. This also allow recalibration of the distance between the two endstops + // without modifying the firmware (through the "M218 T1 X???" command). + // Remember: you should set the second extruder x-offset to 0 in your slicer. + + // There are a few selectable movement modes for dual x-carriages using M605 S + // Mode 0 (DXC_FULL_CONTROL_MODE): Full control. The slicer has full control over both x-carriages and can achieve optimal travel results + // as long as it supports dual x-carriages. (M605 S0) + // Mode 1 (DXC_AUTO_PARK_MODE) : Auto-park mode. The firmware will automatically park and unpark the x-carriages on tool changes so + // that additional slicer support is not required. (M605 S1) + // Mode 2 (DXC_DUPLICATION_MODE) : Duplication mode. The firmware will transparently make the second x-carriage and extruder copy all + // actions of the first x-carriage. This allows the printer to print 2 arbitrary items at + // once. (2nd extruder x offset and temp offset are set using: M605 S2 [Xnnn] [Rmmm]) + + // This is the default power-up mode which can be later using M605. + #define DEFAULT_DUAL_X_CARRIAGE_MODE DXC_FULL_CONTROL_MODE + + // Default settings in "Auto-park Mode" + #define TOOLCHANGE_PARK_ZLIFT 0.2 // the distance to raise Z axis when parking an extruder + #define TOOLCHANGE_UNPARK_ZLIFT 1 // the distance to raise Z axis when unparking an extruder + + // Default x offset in duplication mode (typically set to half print bed width) + #define DEFAULT_DUPLICATION_X_OFFSET 100 + +#endif // DUAL_X_CARRIAGE + +// 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. +//#define EXT_SOLENOID + +// @section homing + +//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +#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 this is defined, if both x and y are to be homed, a diagonal move will be performed initially. + +// When G28 is called, this option will make Y home before X +//#define HOME_Y_BEFORE_X + +// @section machine + +#define AXIS_RELATIVE_MODES {false, false, false, false} + +// Allow duplication mode with a basic dual-nozzle extruder +//#define DUAL_NOZZLE_DUPLICATION_MODE + +// By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step. +#define INVERT_X_STEP_PIN false +#define INVERT_Y_STEP_PIN false +#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. +#define DEFAULT_STEPPER_DEACTIVE_TIME 60 +#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_E true + +#define DEFAULT_MINIMUMFEEDRATE 0.0 // minimum feedrate +#define DEFAULT_MINTRAVELFEEDRATE 0.0 + +//#define HOME_AFTER_DEACTIVATE // Require rehoming after steppers are deactivated + +// @section lcd + +#if ENABLED(ULTIPANEL) + #define MANUAL_FEEDRATE {50*60, 50*60, 4*60, 60} // Feedrates for manual moves along X, Y, Z, E from panel + #define ULTIPANEL_FEEDMULTIPLY // Comment to disable setting feedrate multiplier via encoder +#endif + +// @section extras + +// minimum time in microseconds that a movement needs to take if the buffer is emptied. +#define DEFAULT_MINSEGMENTTIME 20000 + +// If defined the movements slow down when the look ahead buffer is only half full +#define SLOWDOWN + +// Frequency limit +// See nophead's blog for more info +// Not working O +//#define XY_FREQUENCY_LIMIT 15 + +// 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 +// if unwanted behavior is observed on a user's machine when running at very slow speeds. +#define MINIMUM_PLANNER_SPEED 0.05 // (mm/sec) + +// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU. +#define MICROSTEP_MODES {16,16,16,16,16} // [1,2,4,8,16] + +/** + * @section stepper motor current + * + * Some boards have a means of setting the stepper motor current via firmware. + * + * The power on motor currents are set by: + * PWM_MOTOR_CURRENT - used by MINIRAMBO & ULTIMAIN_2 + * known compatible chips: A4982 + * DIGIPOT_MOTOR_CURRENT - used by BQ_ZUM_MEGA_3D, RAMBO & SCOOVO_X9H + * known compatible chips: AD5206 + * DAC_MOTOR_CURRENT_DEFAULT - used by PRINTRBOARD_REVF & RIGIDBOARD_V2 + * known compatible chips: MCP4728 + * DIGIPOT_I2C_MOTOR_CURRENTS - used by 5DPRINT, AZTEEG_X3_PRO, MIGHTYBOARD_REVE + * known compatible chips: MCP4451, MCP4018 + * + * Motor currents can also be set by M907 - M910 and by the LCD. + * M907 - applies to all. + * M908 - BQ_ZUM_MEGA_3D, RAMBO, PRINTRBOARD_REVF, RIGIDBOARD_V2 & SCOOVO_X9H + * M909, M910 & LCD - only PRINTRBOARD_REVF & RIGIDBOARD_V2 + */ +//#define PWM_MOTOR_CURRENT { 1300, 1300, 1250 } // Values in milliamps +//#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 + +// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +//#define DIGIPOT_I2C +//#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster +#define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 +// Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS +#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=========================== +//=========================================================================== + +//#define ENCODER_RATE_MULTIPLIER // If defined, certain menu edit operations automatically multiply the steps when the encoder is moved quickly +//#define ENCODER_10X_STEPS_PER_SEC 75 // If the encoder steps per sec exceeds this value, multiply steps moved x10 to quickly advance the value +//#define ENCODER_100X_STEPS_PER_SEC 160 // If the encoder steps per sec exceeds this value, multiply steps moved x100 to really quickly advance the value + +//#define CHDK 4 //Pin for triggering CHDK to take a picture see how to use it here http://captain-slow.dk/2014/03/09/3d-printing-timelapses/ +#define CHDK_DELAY 50 //How long in ms the pin should stay HIGH before going LOW again + +// @section lcd + +// Include a page of printer information in the LCD Main Menu +//#define LCD_INFO_MENU + +// Scroll a longer status message into view +//#define STATUS_MESSAGE_SCROLLING + +// On the Info Screen, display XY with one decimal place when possible +//#define LCD_DECIMAL_SMALL_XY + +// The timeout (in ms) to return to the status screen from sub-menus +//#define LCD_TIMEOUT_TO_STATUS 15000 + +#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 + + #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? + #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. + + #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. + // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. + // using: + //#define MENU_ADDAUTOSTART + + /** + * Sort SD file listings in alphabetical order. + * + * With this option enabled, items on SD cards will be sorted + * by name for easier navigation. + * + * By default... + * + * - Use the slowest -but safest- method for sorting. + * - Folders are sorted to the top. + * - The sort key is statically allocated. + * - No added G-code (M34) support. + * - 40 item sorting limit. (Items after the first 40 are unsorted.) + * + * SD sorting uses static allocation (as set by SDSORT_LIMIT), allowing the + * compiler to calculate the worst-case usage and throw an error if the SRAM + * limit is exceeded. + * + * - SDSORT_USES_RAM provides faster sorting via a static directory buffer. + * - SDSORT_USES_STACK does the same, but uses a local stack-based buffer. + * - SDSORT_CACHE_NAMES will retain the sorted file listing in RAM. (Expensive!) + * - SDSORT_DYNAMIC_RAM only uses RAM when the SD menu is visible. (Use with caution!) + */ + //#define SDCARD_SORT_ALPHA + + // SD Card Sorting options + #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_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. + #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #endif + + // Show a progress bar on HD44780 LCDs for SD printing + //#define LCD_PROGRESS_BAR + + #if ENABLED(LCD_PROGRESS_BAR) + // Amount of time (ms) to show the bar + #define PROGRESS_BAR_BAR_TIME 2000 + // Amount of time (ms) to show the status message + #define PROGRESS_BAR_MSG_TIME 3000 + // Amount of time (ms) to retain the status message (0=forever) + #define PROGRESS_MSG_EXPIRE 0 + // Enable this to show messages for MSG_TIME then hide them + //#define PROGRESS_MSG_ONCE + // Add a menu item to test the progress bar: + //#define LCD_PROGRESS_BAR_TEST + #endif + + // This allows hosts to request long names for files and folders with M33 + //#define LONG_FILENAME_HOST_SUPPORT + + // This option allows you to abort SD printing when any endstop is triggered. + // This feature must be enabled with "M540 S1" or from the LCD menu. + // To have any effect, endstops must be enabled during SD printing. + //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + +#endif // SDSUPPORT + +/** + * Additional options for Graphical Displays + * + * Use the optimizations here to improve printing performance, + * which can be adversely affected by graphical display drawing, + * especially when doing several short moves, and when printing + * on DELTA and SCARA machines. + * + * Some of these options may result in the display lagging behind + * controller events, as there is a trade-off between reliable + * printing performance versus fast display updates. + */ +#if ENABLED(DOGLCD) + // Enable to save many cycles by drawing a hollow frame on the Info Screen + #define XYZ_HOLLOW_FRAME + + // Enable to save many cycles by drawing a hollow frame on Menu Screens + #define MENU_HOLLOW_FRAME + + // A bigger font is available for edit items. Costs 3120 bytes of PROGMEM. + // 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. + // 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 +#endif // DOGLCD + +// @section safety + +// The hardware watchdog should reset the microcontroller disabling all outputs, +// in case the firmware gets stuck and doesn't do temperature regulation. +#define USE_WATCHDOG + +#if ENABLED(USE_WATCHDOG) + // If you have a watchdog reboot in an ArduinoMega2560 then the device will hang forever, as a watchdog reset will leave the watchdog on. + // The "WATCHDOG_RESET_MANUAL" goes around this by not using the hardware reset. + // However, THIS FEATURE IS UNSAFE!, as it will only work if interrupts are disabled. And the code could hang in an interrupt routine with interrupts disabled. + //#define WATCHDOG_RESET_MANUAL +#endif + +// @section lcd + +/** + * Babystepping enables movement of the axes by tiny increments without changing + * the current position values. This feature is used primarily to adjust the Z + * axis in the first layer of a print in real-time. + * + * Warning: Does not respect endstops! + */ +//#define BABYSTEPPING +#if ENABLED(BABYSTEPPING) + //#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 100 // Babysteps are very small. Increase for faster motion. + //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping + //#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen 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_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor + //#define BABYSTEP_ZPROBE_GFX_REVERSE // Reverses the direction of the CW/CCW indicators +#endif + +// @section extruder + +/** + * Implementation of linear pressure control + * + * Assumption: advance = k * (delta velocity) + * K=0 means advance disabled. + * See Marlin documentation for calibration instructions. + */ +//#define LIN_ADVANCE + +#if ENABLED(LIN_ADVANCE) + #define LIN_ADVANCE_K 75 + + /** + * Some Slicers produce Gcode with randomly jumping extrusion widths occasionally. + * For example within a 0.4mm perimeter it may produce a single segment of 0.05mm width. + * While this is harmless for normal printing (the fluid nature of the filament will + * close this very, very tiny gap), it throws off the LIN_ADVANCE pressure adaption. + * + * For this case LIN_ADVANCE_E_D_RATIO can be used to set the extrusion:distance ratio + * to a fixed value. Note that using a fixed ratio will lead to wrong nozzle pressures + * if the slicer is using variable widths or layer heights within one print! + * + * This option sets the default E:D ratio at startup. Use `M900` to override this value. + * + * Example: `M900 W0.4 H0.2 D1.75`, where: + * - W is the extrusion width in mm + * - H is the layer height in mm + * - D is the filament diameter in mm + * + * Example: `M900 R0.0458` to set the ratio directly. + * + * Set to 0 to auto-detect the ratio based on given Gcode G1 print moves. + * + * Slic3r (including Průša Control) produces Gcode compatible with the automatic mode. + * Cura (as of this writing) may produce Gcode incompatible with the automatic mode. + */ + #define LIN_ADVANCE_E_D_RATIO 0 // The calculated ratio (or 0) according to the formula W * H / ((D / 2) ^ 2 * PI) + // Example: 0.4 * 0.2 / ((1.75 / 2) ^ 2 * PI) = 0.033260135 +#endif + +// @section leveling + +// Default mesh area is an area with an inset margin on the print area. +// Below are the macros that are used to define the borders for the mesh area, +// made available here for specialized needs, ie dual extruder setup. +#if ENABLED(MESH_BED_LEVELING) + #define MESH_MIN_X MESH_INSET + #define MESH_MAX_X (X_BED_SIZE - (MESH_INSET)) + #define MESH_MIN_Y MESH_INSET + #define MESH_MAX_Y (Y_BED_SIZE - (MESH_INSET)) +#elif ENABLED(AUTO_BED_LEVELING_UBL) + #define UBL_MESH_MIN_X UBL_MESH_INSET + #define UBL_MESH_MAX_X (X_BED_SIZE - (UBL_MESH_INSET)) + #define UBL_MESH_MIN_Y UBL_MESH_INSET + #define UBL_MESH_MAX_Y (Y_BED_SIZE - (UBL_MESH_INSET)) + + // If this is defined, the currently active mesh will be saved in the + // current slot on M500. + #define UBL_SAVE_ACTIVE_ON_M500 +#endif + +// @section extras + +// +// G2/G3 Arc Support +// +#define ARC_SUPPORT // Disable this feature to save ~3226 bytes +#if ENABLED(ARC_SUPPORT) + #define MM_PER_ARC_SEGMENT 1 // Length of each arc segment + #define N_ARC_CORRECTION 25 // Number of intertpolated 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 +#endif + +// Support for G5 with XYZE destination and IJPQ offsets. Requires ~2666 bytes. +//#define BEZIER_CURVE_SUPPORT + +// G38.2 and G38.3 Probe Target +// Enable PROBE_DOUBLE_TOUCH if you want G38 to double touch +//#define G38_PROBE_TARGET +#if ENABLED(G38_PROBE_TARGET) + #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) +#endif + +// Moves (or segments) with fewer steps than this will be joined with the next move +#define MIN_STEPS_PER_SEGMENT 6 + +// The minimum pulse width (in µs) for stepping a stepper. +// Set this if you find stepping unreliable, or if using a very fast CPU. +#define MINIMUM_STEPPER_PULSE 0 // (µs) The smallest stepper pulse allowed + +// @section temperature + +// Control heater 0 and heater 1 in parallel. +//#define HEATERS_PARALLEL + +//=========================================================================== +//================================= Buffers ================================= +//=========================================================================== + +// @section hidden + +// 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, i.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 +#else + #define BLOCK_BUFFER_SIZE 16 // maximize block buffer +#endif + +// @section serial + +// The ASCII buffer for serial input +#define MAX_CMD_SIZE 96 +#define BUFSIZE 8 + +// Transmission to Host Buffer Size +// To save 386 bytes of PROGMEM (and TX_BUFFER_SIZE+3 bytes of RAM) set to 0. +// To buffer a simple "ok" you need 4 bytes. +// For ADVANCED_OK (M105) you need 32 bytes. +// For debug-echo: 128 bytes for the optimal speed. +// Other output doesn't need to be that speedy. +// :[0, 2, 4, 8, 16, 32, 64, 128, 256] +#define TX_BUFFER_SIZE 0 + +// Host Receive Buffer Size +// Without XON/XOFF flow control (see SERIAL_XON_XOFF below) 32 bytes should be enough. +// To use flow control, set this buffer size to at least 1024 bytes. +// :[0, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048] +//#define RX_BUFFER_SIZE 1024 + +#if RX_BUFFER_SIZE >= 1024 + // Enable to have the controller send XON/XOFF control characters to + // the host to signal the RX buffer is becoming full. + //#define SERIAL_XON_XOFF +#endif + +#if ENABLED(SDSUPPORT) + // Enable this option to collect and display the maximum + // RX queue usage after transferring a file to SD. + //#define SERIAL_STATS_MAX_RX_QUEUED + + // Enable this option to collect and display the number + // of dropped bytes after a file transfer to SD. + //#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! +//#define EMERGENCY_PARSER + +// Bad Serial-connections can miss a received command by sending an 'ok' +// Therefore some clients abort after 30 seconds in a timeout. +// Some other clients start sending commands while receiving a 'wait'. +// This "wait" is only sent when the buffer is empty. 1 second is a good value here. +//#define NO_TIMEOUTS 1000 // Milliseconds + +// Some clients will have this feature soon. This could make the NO_TIMEOUTS unnecessary. +//#define ADVANCED_OK + +// @section extras + +/** + * Firmware-based and LCD-controlled retract + * + * Add G10 / G11 commands for automatic firmware-based retract / recover. + * Use M207 and M208 to define parameters for retract / recover. + * + * Use M209 to enable or disable auto-retract. + * With auto-retract enabled, all G1 E moves within the set range + * will be converted to firmware-based retract/recover moves. + * + * Be sure to turn off auto-retract during filament change. + * + * Note that M207 / M208 / M209 settings are saved to EEPROM. + * + */ +//#define FWRETRACT // ONLY PARTIALLY TESTED +#if ENABLED(FWRETRACT) + #define MIN_AUTORETRACT 0.1 // When auto-retract is on, convert E moves of this length and over + #define MAX_AUTORETRACT 10.0 // Upper limit for auto-retract conversion + #define RETRACT_LENGTH 3 // Default retract length (positive mm) + #define RETRACT_LENGTH_SWAP 13 // Default swap retract length (positive mm), for extruder change + #define RETRACT_FEEDRATE 45 // Default feedrate for retracting (mm/s) + #define RETRACT_ZLIFT 0 // Default retract Z-lift + #define RETRACT_RECOVER_LENGTH 0 // Default additional recover length (mm, added to retract length when recovering) + #define RETRACT_RECOVER_LENGTH_SWAP 0 // Default additional swap recover length (mm, added to retract length when recovering from extruder change) + #define RETRACT_RECOVER_FEEDRATE 8 // Default feedrate for recovering from retraction (mm/s) + #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) +#endif + +/** + * Advanced Pause + * Experimental feature for filament change support and for parking the nozzle when paused. + * Adds the GCode M600 for initiating filament change. + * If PARK_HEAD_ON_PAUSE enabled, adds the GCode M125 to pause printing and park the nozzle. + * + * Requires an LCD display. + * This feature is required for the default FILAMENT_RUNOUT_SCRIPT. + */ +//#define ADVANCED_PAUSE_FEATURE +#if ENABLED(ADVANCED_PAUSE_FEATURE) + #define PAUSE_PARK_X_POS 3 // X position of hotend + #define PAUSE_PARK_Y_POS 3 // Y position of hotend + #define PAUSE_PARK_Z_ADD 10 // Z addition of hotend (lift) + #define PAUSE_PARK_XY_FEEDRATE 100 // X and Y axes feedrate in mm/s (also used for delta printers Z axis) + #define PAUSE_PARK_Z_FEEDRATE 5 // Z axis feedrate in mm/s (not used for delta printers) + #define PAUSE_PARK_RETRACT_FEEDRATE 60 // Initial retract feedrate in mm/s + #define PAUSE_PARK_RETRACT_LENGTH 2 // Initial retract in mm + // It is a short retract used immediately after print interrupt before move to filament exchange position + #define FILAMENT_CHANGE_UNLOAD_FEEDRATE 10 // Unload filament feedrate in mm/s - filament unloading can be fast + #define FILAMENT_CHANGE_UNLOAD_LENGTH 100 // Unload filament length from hotend in mm + // Longer length for bowden printers to unload filament from whole bowden tube, + // shorter length for printers without bowden to unload filament from extruder only, + // 0 to disable unloading for manual unloading + #define FILAMENT_CHANGE_LOAD_FEEDRATE 6 // Load filament feedrate in mm/s - filament loading into the bowden tube can be fast + #define FILAMENT_CHANGE_LOAD_LENGTH 0 // Load filament length over hotend in mm + // Longer length for bowden printers to fast load filament into whole bowden tube over the hotend, + // Short or zero length for printers without bowden where loading is not used + #define ADVANCED_PAUSE_EXTRUDE_FEEDRATE 3 // Extrude filament feedrate in mm/s - must be slower than load feedrate + #define ADVANCED_PAUSE_EXTRUDE_LENGTH 50 // Extrude filament length in mm after filament is loaded over the hotend, + // 0 to disable for manual extrusion + // Filament can be extruded repeatedly from the filament exchange menu to fill the hotend, + // or until outcoming filament color is not clear for filament color change + #define PAUSE_PARK_NOZZLE_TIMEOUT 45 // Turn off nozzle if user doesn't change filament within this time limit in seconds + #define FILAMENT_CHANGE_NUMBER_OF_ALERT_BEEPS 5 // Number of alert beeps before printer goes quiet + #define PAUSE_PARK_NO_STEPPER_TIMEOUT // Enable to have stepper motors hold position during filament change + // even if it takes longer than DEFAULT_STEPPER_DEACTIVE_TIME. + //#define PARK_HEAD_ON_PAUSE // Go to filament change position on pause, return to print position on resume + //#define HOME_BEFORE_FILAMENT_CHANGE // Ensure homing has been completed prior to parking for filament change +#endif + +// @section tmc + +/** + * Enable this section if you have TMC26X motor drivers. + * You will need to import the TMC26XStepper library into the Arduino IDE for this + * (https://github.com/trinamic/TMC26XStepper.git) + */ +//#define HAVE_TMCDRIVER + +#if ENABLED(HAVE_TMCDRIVER) + + //#define X_IS_TMC + //#define X2_IS_TMC + //#define Y_IS_TMC + //#define Y2_IS_TMC + //#define Z_IS_TMC + //#define Z2_IS_TMC + //#define E0_IS_TMC + //#define E1_IS_TMC + //#define E2_IS_TMC + //#define E3_IS_TMC + //#define E4_IS_TMC + + #define X_MAX_CURRENT 1000 // in mA + #define X_SENSE_RESISTOR 91 // in mOhms + #define X_MICROSTEPS 16 // number of microsteps + + #define X2_MAX_CURRENT 1000 + #define X2_SENSE_RESISTOR 91 + #define X2_MICROSTEPS 16 + + #define Y_MAX_CURRENT 1000 + #define Y_SENSE_RESISTOR 91 + #define Y_MICROSTEPS 16 + + #define Y2_MAX_CURRENT 1000 + #define Y2_SENSE_RESISTOR 91 + #define Y2_MICROSTEPS 16 + + #define Z_MAX_CURRENT 1000 + #define Z_SENSE_RESISTOR 91 + #define Z_MICROSTEPS 16 + + #define Z2_MAX_CURRENT 1000 + #define Z2_SENSE_RESISTOR 91 + #define Z2_MICROSTEPS 16 + + #define E0_MAX_CURRENT 1000 + #define E0_SENSE_RESISTOR 91 + #define E0_MICROSTEPS 16 + + #define E1_MAX_CURRENT 1000 + #define E1_SENSE_RESISTOR 91 + #define E1_MICROSTEPS 16 + + #define E2_MAX_CURRENT 1000 + #define E2_SENSE_RESISTOR 91 + #define E2_MICROSTEPS 16 + + #define E3_MAX_CURRENT 1000 + #define E3_SENSE_RESISTOR 91 + #define E3_MICROSTEPS 16 + + #define E4_MAX_CURRENT 1000 + #define E4_SENSE_RESISTOR 91 + #define E4_MICROSTEPS 16 + +#endif + +// @section TMC2130 + +/** + * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. + * + * You'll also need the TMC2130Stepper Arduino library + * (https://github.com/teemuatlut/TMC2130Stepper). + * + * To use TMC2130 stepper drivers in SPI mode connect your SPI2130 pins to + * the hardware SPI interface on your board and define the required CS pins + * in your `pins_MYBOARD.h` file. (e.g., RAMPS 1.4 uses AUX3 pins `X_CS_PIN 53`, `Y_CS_PIN 49`, etc.). + */ +//#define HAVE_TMC2130 + +#if ENABLED(HAVE_TMC2130) + + // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY + //#define X_IS_TMC2130 + //#define X2_IS_TMC2130 + //#define Y_IS_TMC2130 + //#define Y2_IS_TMC2130 + //#define Z_IS_TMC2130 + //#define Z2_IS_TMC2130 + //#define E0_IS_TMC2130 + //#define E1_IS_TMC2130 + //#define E2_IS_TMC2130 + //#define E3_IS_TMC2130 + //#define E4_IS_TMC2130 + + /** + * Stepper driver settings + */ + + #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 + #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current + #define INTERPOLATE 1 // Interpolate X/Y/Z_MICROSTEPS to 256 + + #define X_CURRENT 1000 // rms current in mA. Multiply by 1.41 for peak current. + #define X_MICROSTEPS 16 // 0..256 + + #define Y_CURRENT 1000 + #define Y_MICROSTEPS 16 + + #define Z_CURRENT 1000 + #define Z_MICROSTEPS 16 + + //#define X2_CURRENT 1000 + //#define X2_MICROSTEPS 16 + + //#define Y2_CURRENT 1000 + //#define Y2_MICROSTEPS 16 + + //#define Z2_CURRENT 1000 + //#define Z2_MICROSTEPS 16 + + //#define E0_CURRENT 1000 + //#define E0_MICROSTEPS 16 + + //#define E1_CURRENT 1000 + //#define E1_MICROSTEPS 16 + + //#define E2_CURRENT 1000 + //#define E2_MICROSTEPS 16 + + //#define E3_CURRENT 1000 + //#define E3_MICROSTEPS 16 + + //#define E4_CURRENT 1000 + //#define E4_MICROSTEPS 16 + + /** + * Use Trinamic's ultra quiet stepping mode. + * When disabled, Marlin will use spreadCycle stepping mode. + */ + #define STEALTHCHOP + + /** + * Let Marlin automatically control stepper current. + * This is still an experimental feature. + * Increase current every 5s by CURRENT_STEP until stepper temperature prewarn gets triggered, + * then decrease current by CURRENT_STEP until temperature prewarn is cleared. + * Adjusting starts from X/Y/Z/E_CURRENT but will not increase over AUTO_ADJUST_MAX + * 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. + * M906 S1 - Start adjusting current + * M906 S0 - Stop adjusting current + * M911 - Report stepper driver overtemperature pre-warn condition. + * M912 - Clear stepper driver overtemperature pre-warn condition flag. + */ + //#define AUTOMATIC_CURRENT_CONTROL + + #if ENABLED(AUTOMATIC_CURRENT_CONTROL) + #define CURRENT_STEP 50 // [mA] + #define AUTO_ADJUST_MAX 1300 // [mA], 1300mA_rms = 1840mA_peak + #define REPORT_CURRENT_CHANGE + #endif + + /** + * The driver will switch to spreadCycle when stepper speed is over HYBRID_THRESHOLD. + * This mode allows for faster movements at the expense of higher noise levels. + * STEALTHCHOP needs to be enabled. + * M913 X/Y/Z/E to live tune the setting + */ + //#define HYBRID_THRESHOLD + + #define X_HYBRID_THRESHOLD 100 // [mm/s] + #define X2_HYBRID_THRESHOLD 100 + #define Y_HYBRID_THRESHOLD 100 + #define Y2_HYBRID_THRESHOLD 100 + #define Z_HYBRID_THRESHOLD 4 + #define Z2_HYBRID_THRESHOLD 4 + #define E0_HYBRID_THRESHOLD 30 + #define E1_HYBRID_THRESHOLD 30 + #define E2_HYBRID_THRESHOLD 30 + #define E3_HYBRID_THRESHOLD 30 + #define E4_HYBRID_THRESHOLD 30 + + /** + * Use stallGuard2 to sense an obstacle and trigger an endstop. + * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. + * If used along with STEALTHCHOP, the movement will be louder when homing. This is normal. + * + * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. + * Higher values make the system LESS sensitive. + * Lower value make the system MORE sensitive. + * Too low values can lead to false positives, while too high values will collide the axis without triggering. + * It is advised to set X/Y_HOME_BUMP_MM to 0. + * M914 X/Y to live tune the setting + */ + //#define SENSORLESS_HOMING + + #if ENABLED(SENSORLESS_HOMING) + #define X_HOMING_SENSITIVITY 19 + #define Y_HOMING_SENSITIVITY 19 + #endif + + /** + * You can set your own advanced settings by filling in predefined functions. + * A list of available functions can be found on the library github page + * https://github.com/teemuatlut/TMC2130Stepper + * + * Example: + * #define TMC2130_ADV() { \ + * stepperX.diag0_temp_prewarn(1); \ + * stepperX.interpolate(0); \ + * } + */ + #define TMC2130_ADV() { } + +#endif // HAVE_TMC2130 + +// @section L6470 + +/** + * Enable this section if you have L6470 motor drivers. + * You need to import the L6470 library into the Arduino IDE for this. + * (https://github.com/ameyer/Arduino-L6470) + */ + +//#define HAVE_L6470DRIVER +#if ENABLED(HAVE_L6470DRIVER) + + //#define X_IS_L6470 + //#define X2_IS_L6470 + //#define Y_IS_L6470 + //#define Y2_IS_L6470 + //#define Z_IS_L6470 + //#define Z2_IS_L6470 + //#define E0_IS_L6470 + //#define E1_IS_L6470 + //#define E2_IS_L6470 + //#define E3_IS_L6470 + //#define E4_IS_L6470 + + #define X_MICROSTEPS 16 // number of microsteps + #define X_K_VAL 50 // 0 - 255, Higher values, are higher power. Be careful not to go too high + #define X_OVERCURRENT 2000 // maxc current in mA. If the current goes over this value, the driver will switch off + #define X_STALLCURRENT 1500 // current in mA where the driver will detect a stall + + #define X2_MICROSTEPS 16 + #define X2_K_VAL 50 + #define X2_OVERCURRENT 2000 + #define X2_STALLCURRENT 1500 + + #define Y_MICROSTEPS 16 + #define Y_K_VAL 50 + #define Y_OVERCURRENT 2000 + #define Y_STALLCURRENT 1500 + + #define Y2_MICROSTEPS 16 + #define Y2_K_VAL 50 + #define Y2_OVERCURRENT 2000 + #define Y2_STALLCURRENT 1500 + + #define Z_MICROSTEPS 16 + #define Z_K_VAL 50 + #define Z_OVERCURRENT 2000 + #define Z_STALLCURRENT 1500 + + #define Z2_MICROSTEPS 16 + #define Z2_K_VAL 50 + #define Z2_OVERCURRENT 2000 + #define Z2_STALLCURRENT 1500 + + #define E0_MICROSTEPS 16 + #define E0_K_VAL 50 + #define E0_OVERCURRENT 2000 + #define E0_STALLCURRENT 1500 + + #define E1_MICROSTEPS 16 + #define E1_K_VAL 50 + #define E1_OVERCURRENT 2000 + #define E1_STALLCURRENT 1500 + + #define E2_MICROSTEPS 16 + #define E2_K_VAL 50 + #define E2_OVERCURRENT 2000 + #define E2_STALLCURRENT 1500 + + #define E3_MICROSTEPS 16 + #define E3_K_VAL 50 + #define E3_OVERCURRENT 2000 + #define E3_STALLCURRENT 1500 + + #define E4_MICROSTEPS 16 + #define E4_K_VAL 50 + #define E4_OVERCURRENT 2000 + #define E4_STALLCURRENT 1500 + +#endif + +/** + * TWI/I2C BUS + * + * This feature is an EXPERIMENTAL feature so it shall not be used on production + * machines. Enabling this will allow you to send and receive I2C data from slave + * devices on the bus. + * + * ; Example #1 + * ; This macro send the string "Marlin" to the slave device with address 0x63 (99) + * ; It uses multiple M260 commands with one B arg + * M260 A99 ; Target slave address + * M260 B77 ; M + * M260 B97 ; a + * M260 B114 ; r + * M260 B108 ; l + * M260 B105 ; i + * M260 B110 ; n + * M260 S1 ; Send the current buffer + * + * ; Example #2 + * ; Request 6 bytes from slave device with address 0x63 (99) + * M261 A99 B5 + * + * ; Example #3 + * ; Example serial output of a M261 request + * echo:i2c-reply: from:99 bytes:5 data:hello + */ + +// @section i2cbus + +//#define EXPERIMENTAL_I2CBUS +#define I2C_SLAVE_ADDRESS 0 // Set a value from 8 to 127 to act as a slave + +// @section extras + +/** + * Spindle & Laser control + * + * Add the M3, M4, and M5 commands to turn the spindle/laser on and off, and + * to set spindle speed, spindle direction, and laser power. + * + * SuperPid is a router/spindle speed controller used in the CNC milling community. + * Marlin can be used to turn the spindle on and off. It can also be used to set + * the spindle speed from 5,000 to 30,000 RPM. + * + * 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. + */ +//#define SPINDLE_LASER_ENABLE +#if ENABLED(SPINDLE_LASER_ENABLE) + + #define SPINDLE_LASER_ENABLE_INVERT false // set to "true" if the on/off function is reversed + #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 // delay in milliseconds to allow the spindle/laser to come up to speed/power + #define SPINDLE_LASER_POWERDOWN_DELAY 5000 // delay in milliseconds to allow the spindle to stop + #define SPINDLE_DIR_CHANGE true // set to true if your spindle controller supports changing spindle direction + #define SPINDLE_INVERT_DIR false + #define SPINDLE_STOP_ON_DIR_CHANGE true // set to true if Marlin should stop the spindle before changing rotation direction + + /** + * The M3 & M4 commands use the following equation to convert PWM duty cycle to speed/power + * + * SPEED/POWER = PWM duty cycle * SPEED_POWER_SLOPE + SPEED_POWER_INTERCEPT + * where PWM duty cycle varies from 0 to 255 + * + * set the following for your controller (ALL MUST BE SET) + */ + + #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_SLOPE 0.3922 + //#define SPEED_POWER_INTERCEPT 0 + //#define SPEED_POWER_MIN 10 + //#define SPEED_POWER_MAX 100 // 0-100% +#endif + +/** + * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins + */ +//#define PINS_DEBUGGING + +/** + * Auto-report temperatures with M155 S + */ +#define AUTO_REPORT_TEMPERATURES + +/** + * Include capabilities in M115 output + */ +#define EXTENDED_CAPABILITIES_REPORT + +/** + * Volumetric extrusion default state + * 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. + */ +//#define VOLUMETRIC_DEFAULT_ON + +/** + * Enable this option for a leaner build of Marlin that removes all + * workspace offsets, simplifying coordinate transformations, leveling, etc. + * + * - M206 and M428 are disabled. + * - G92 will revert to its behavior from Marlin 1.0. + */ +//#define NO_WORKSPACE_OFFSETS + +/** + * 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. + * + * For clients that use a fixed-width font (like OctoPrint), leave this set to 1.0. + * Otherwise, adjust according to your client and font. + */ +#define PROPORTIONAL_FONT_RATIO 1.0 + +/** + * Spend 28 bytes of SRAM to optimize the GCode parser + */ +#define FASTER_GCODE_PARSER + +/** + * User-defined menu items that execute custom GCode + */ +//#define CUSTOM_USER_MENUS +#if ENABLED(CUSTOM_USER_MENUS) + #define USER_SCRIPT_DONE "M117 User Script Done" + #define USER_SCRIPT_AUDIBLE_FEEDBACK + //#define USER_SCRIPT_RETURN // Return to status screen after a script + + #define USER_DESC_1 "Home & UBL Info" + #define USER_GCODE_1 "G28\nG29 W" + + #define USER_DESC_2 "Preheat for PLA" + #define USER_GCODE_2 "M140 S" STRINGIFY(PREHEAT_1_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND) + + #define USER_DESC_3 "Preheat for ABS" + #define USER_GCODE_3 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND) + + #define USER_DESC_4 "Heat Bed/Home/Level" + #define USER_GCODE_4 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nG28\nG29" + + //#define USER_DESC_5 "Home & Info" + //#define USER_GCODE_5 "G28\nM503" +#endif + +/** + * Specify an action command to send to the host when the printer is killed. + * Will be sent in the form '//action:ACTION_ON_KILL', e.g. '//action:poweroff'. + * The host must be configured to handle the action command. + */ +//#define ACTION_ON_KILL "poweroff" + +//=========================================================================== +//====================== I2C Position Encoder Settings ====================== +//=========================================================================== + +/** + * I2C position encoders for closed loop control. + * Developed by Chris Barr at Aus3D. + * + * Wiki: http://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/ + * + * Reilabuild encoders have been modified to improve reliability. + */ + +//#define I2C_POSITION_ENCODERS +#if ENABLED(I2C_POSITION_ENCODERS) + + #define I2CPE_ENCODER_CNT 1 // The number of encoders installed; max of 5 + // encoders supported currently. + + #define I2CPE_ENC_1_ADDR I2CPE_PRESET_ADDR_X // I2C address of the encoder. 30-200. + #define I2CPE_ENC_1_AXIS X_AXIS // Axis the encoder module is installed on. _AXIS. + #define I2CPE_ENC_1_TYPE I2CPE_ENC_TYPE_LINEAR // Type of encoder: I2CPE_ENC_TYPE_LINEAR -or- + // I2CPE_ENC_TYPE_ROTARY. + #define I2CPE_ENC_1_TICKS_UNIT 2048 // 1024 for magnetic strips with 2mm poles; 2048 for + // 1mm poles. For linear encoders this is ticks / mm, + // for rotary encoders this is ticks / revolution. + //#define I2CPE_ENC_1_TICKS_REV (16 * 200) // Only needed for rotary encoders; number of stepper + // steps per full revolution (motor steps/rev * microstepping) + //#define I2CPE_ENC_1_INVERT // Invert the direction of axis travel. + #define I2CPE_ENC_1_EC_METHOD I2CPE_ECM_NONE // Type of error error correction. + #define I2CPE_ENC_1_EC_THRESH 0.10 // Threshold size for error (in mm) above which the + // printer will attempt to correct the error; errors + // smaller than this are ignored to minimize effects of + // measurement noise / latency (filter). + + #define I2CPE_ENC_2_ADDR I2CPE_PRESET_ADDR_Y // Same as above, but for encoder 2. + #define I2CPE_ENC_2_AXIS Y_AXIS + #define I2CPE_ENC_2_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_ENC_2_TICKS_UNIT 2048 + //#define I2CPE_ENC_2_TICKS_REV (16 * 200) + //#define I2CPE_ENC_2_INVERT + #define I2CPE_ENC_2_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_ENC_2_EC_THRESH 0.10 + + #define I2CPE_ENC_3_ADDR I2CPE_PRESET_ADDR_Z // Encoder 3. Add additional configuration options + #define I2CPE_ENC_3_AXIS Z_AXIS // as above, or use defaults below. + + #define I2CPE_ENC_4_ADDR I2CPE_PRESET_ADDR_E // Encoder 4. + #define I2CPE_ENC_4_AXIS E_AXIS + + #define I2CPE_ENC_5_ADDR 34 // Encoder 5. + #define I2CPE_ENC_5_AXIS E_AXIS + + // Default settings for encoders which are enabled, but without settings configured above. + #define I2CPE_DEF_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_DEF_ENC_TICKS_UNIT 2048 + #define I2CPE_DEF_TICKS_REV (16 * 200) + #define I2CPE_DEF_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_DEF_EC_THRESH 0.1 + + //#define I2CPE_ERR_THRESH_ABORT 100.0 // Threshold size for error (in mm) error on any given + // axis after which the printer will abort. Comment out to + // disable abort behaviour. + + #define I2CPE_TIME_TRUSTED 10000 // After an encoder fault, there must be no further fault + // for this amount of time (in ms) before the encoder + // is trusted again. + + /** + * Position is checked every time a new command is executed from the buffer but during long moves, + * this setting determines the minimum update time between checks. A value of 100 works well with + * error rolling average when attempting to correct only for skips and not for vibration. + */ + #define I2CPE_MIN_UPD_TIME_MS 100 // Minimum time in miliseconds between encoder checks. + + // Use a rolling average to identify persistant errors that indicate skips, as opposed to vibration and noise. + #define I2CPE_ERR_ROLLING_AVERAGE + +#endif // I2C_POSITION_ENCODERS + +/** + * MAX7219 Debug Matrix + * + * Add support for a low-cost 8x8 LED Matrix based on the Max7219 chip, which can be used as a status + * display. Requires 3 signal wires. Some useful debug options are included to demonstrate its usage. + * + * Fully assembled MAX7219 boards can be found on the internet for under $2(US). + * For example, see https://www.ebay.com/sch/i.html?_nkw=332349290049 + */ +//#define MAX7219_DEBUG +#if ENABLED(MAX7219_DEBUG) + #define MAX7219_CLK_PIN 64 // 77 on Re-ARM // Configuration of the 3 pins to control the display + #define MAX7219_DIN_PIN 57 // 78 on Re-ARM + #define MAX7219_LOAD_PIN 44 // 79 on Re-ARM + + /** + * Sample debug features + * If you add more debug displays, be careful to avoid conflicts! + */ + #define MAX7219_DEBUG_PRINTER_ALIVE // Blink corner LED of 8x8 matrix to show that the firmware is functioning + #define MAX7219_DEBUG_STEPPER_HEAD 3 // Show the stepper queue head position on this and the next LED matrix row + #define MAX7219_DEBUG_STEPPER_TAIL 5 // Show the stepper queue tail position on this and the next LED matrix row + + #define MAX7219_DEBUG_STEPPER_QUEUE 0 // Show the current stepper queue depth on this and the next LED matrix row + // If you experience stuttering, reboots, etc. this option can reveal how + // tweaks made to the configuration are affecting the printer in real-time. +#endif + +#endif // CONFIGURATION_ADV_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/SCARA/Configuration.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/SCARA/Configuration.h new file mode 100644 index 00000000..a927723d --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/SCARA/Configuration.h @@ -0,0 +1,1712 @@ +/** + * 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 . + * + */ + +/** + * Configuration.h + * + * Basic settings such as: + * + * - Type of electronics + * - Type of temperature sensor + * - Printer geometry + * - Endstop configuration + * - LCD controller + * - Extra features + * + * Advanced settings can be found in Configuration_adv.h + * + */ +#ifndef CONFIGURATION_H +#define CONFIGURATION_H +#define CONFIGURATION_H_VERSION 010100 + +//=========================================================================== +//============================= Getting Started ============================= +//=========================================================================== + +/** + * Here are some standard links for getting your machine calibrated: + * + * http://reprap.org/wiki/Calibration + * http://youtu.be/wAL9d7FgInk + * http://calculator.josefprusa.cz + * http://reprap.org/wiki/Triffid_Hunter%27s_Calibration_Guide + * http://www.thingiverse.com/thing:5573 + * https://sites.google.com/site/repraplogphase/calibration-of-your-reprap + * http://www.thingiverse.com/thing:298812 + */ + +//=========================================================================== +//============================= SCARA Printer =============================== +//=========================================================================== + +/** + * MORGAN_SCARA was developed by QHARLEY in South Africa in 2012-2013. + * Implemented and slightly reworked by JCERNY in June, 2014. + * + * MAKERARM_SCARA is in development, included as an alternate example. + * Other SCARA models may be added, or SCARA may be unified in the future. + */ + +// Specify the specific SCARA model +#define MORGAN_SCARA +//#define MAKERARM_SCARA + +#if ENABLED(MORGAN_SCARA) || ENABLED(MAKERARM_SCARA) + //#define DEBUG_SCARA_KINEMATICS + //#define SCARA_FEEDRATE_SCALING // Convert XY feedrate from mm/s to degrees/s on the fly + + // If movement is choppy try lowering this value + #define SCARA_SEGMENTS_PER_SECOND 200 + + // Length of inner and outer support arms. Measure arm lengths precisely. + #define SCARA_LINKAGE_1 150 //mm + #define SCARA_LINKAGE_2 150 //mm + + // SCARA tower offset (position of Tower relative to bed zero position) + // This needs to be reasonably accurate as it defines the printbed position in the SCARA space. + #define SCARA_OFFSET_X 100 //mm + #define SCARA_OFFSET_Y -56 //mm + + // Radius around the center where the arm cannot reach + #define MIDDLE_DEAD_ZONE_R 0 //mm + + #define THETA_HOMING_OFFSET 0 //calculatated from Calibration Guide and command M360 / M114 see picture in http://reprap.harleystudio.co.za/?page_id=1073 + #define PSI_HOMING_OFFSET 0 //calculatated from Calibration Guide and command M364 / M114 see picture in http://reprap.harleystudio.co.za/?page_id=1073 + +#endif + +//=========================================================================== +//==================== END ==== SCARA Printer ==== END ====================== +//=========================================================================== + +// @section info + +// User-specified version info of this build to display in [Pronterface, etc] terminal window during +// startup. Implementation of an idea by Prof Braino to inform user that any changes made to this +// build by the user have been successfully uploaded into firmware. +#define STRING_CONFIG_H_AUTHOR "(none, default config)" // Who made the changes. +#define SHOW_BOOTSCREEN +#define STRING_SPLASH_LINE1 SHORT_BUILD_VERSION // will be shown during bootup in line 1 +#define STRING_SPLASH_LINE2 WEBSITE_URL // will be shown during bootup in line 2 + +// +// *** VENDORS PLEASE READ ***************************************************** +// +// Marlin now allow you to have a vendor boot image to be displayed on machine +// start. When SHOW_CUSTOM_BOOTSCREEN is defined Marlin will first show your +// custom boot image and then the default Marlin boot image is shown. +// +// We suggest for you to take advantage of this new feature and keep the Marlin +// boot image unmodified. For an example have a look at the bq Hephestos 2 +// example configuration folder. +// +//#define SHOW_CUSTOM_BOOTSCREEN +// @section machine + +/** + * Select which serial port on the board will be used for communication with the host. + * This allows the connection of wireless adapters (for instance) to non-default port pins. + * Serial port 0 is always used by the Arduino bootloader regardless of this setting. + * + * :[0, 1, 2, 3, 4, 5, 6, 7] + */ +#define SERIAL_PORT 0 + +/** + * This setting determines the communication speed of the printer. + * + * 250000 works in most cases, but you might try a lower speed if + * you commonly experience drop-outs during host printing. + * You may try up to 1000000 to speed up SD file transfer. + * + * :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000] + */ +#define BAUDRATE 250000 + +// Enable the Bluetooth serial interface on AT90USB devices +//#define BLUETOOTH + +// The following define selects which electronics board you have. +// Please choose the name from boards.h that matches your setup +#ifndef MOTHERBOARD + #define MOTHERBOARD BOARD_RAMPS_14_EFB +#endif + +// Optional custom name for your RepStrap or other custom machine +// Displayed in the LCD "Ready" message +//#define CUSTOM_MACHINE_NAME "3D Printer" + +// Define this to set a unique identifier for this printer, (Used by some programs to differentiate between machines) +// You can use an online service to generate a random UUID. (eg http://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] +#define EXTRUDERS 1 + +// For Cyclops or any "multi-extruder" that shares a single nozzle. +//#define SINGLENOZZLE + +/** + * Průša MK2 Single Nozzle Multi-Material Multiplexer, and variants. + * + * This device allows one stepper driver on a control board to drive + * two to eight stepper motors, one at a time, in a manner suitable + * for extruders. + * + * This option only allows the multiplexer to switch on tool-change. + * Additional options to configure custom E moves are pending. + */ +//#define MK2_MULTIPLEXER +#if ENABLED(MK2_MULTIPLEXER) + // Override the default DIO selector pins here, if needed. + // Some pins files may provide defaults for these pins. + //#define E_MUX0_PIN 40 // Always Required + //#define E_MUX1_PIN 42 // Needed for 3 to 8 steppers + //#define E_MUX2_PIN 44 // Needed for 5 to 8 steppers +#endif + +// A dual extruder that uses a single stepper motor +//#define SWITCHING_EXTRUDER +#if ENABLED(SWITCHING_EXTRUDER) + #define SWITCHING_EXTRUDER_SERVO_NR 0 + #define SWITCHING_EXTRUDER_SERVO_ANGLES { 0, 90 } // Angles for E0, E1[, E2, E3] + #if EXTRUDERS > 3 + #define SWITCHING_EXTRUDER_E23_SERVO_NR 1 + #endif +#endif + +// A dual-nozzle that uses a servomotor to raise/lower one of the nozzles +//#define SWITCHING_NOZZLE +#if ENABLED(SWITCHING_NOZZLE) + #define SWITCHING_NOZZLE_SERVO_NR 0 + #define SWITCHING_NOZZLE_SERVO_ANGLES { 0, 90 } // Angles for E0, E1 + //#define HOTEND_OFFSET_Z { 0.0, 0.0 } +#endif + +/** + * Two separate X-carriages with extruders that connect to a moving part + * via a magnetic docking mechanism. Requires SOL1_PIN and SOL2_PIN. + */ +//#define PARKING_EXTRUDER +#if ENABLED(PARKING_EXTRUDER) + #define PARKING_EXTRUDER_SOLENOIDS_INVERT // If enabled, the solenoid is NOT magnetized with applied voltage + #define PARKING_EXTRUDER_SOLENOIDS_PINS_ACTIVE LOW // LOW or HIGH pin signal energizes the coil + #define PARKING_EXTRUDER_SOLENOIDS_DELAY 250 // Delay (ms) for magnetic field. No delay if 0 or not defined. + #define PARKING_EXTRUDER_PARKING_X { -78, 184 } // X positions for parking the extruders + #define PARKING_EXTRUDER_GRAB_DISTANCE 1 // mm to move beyond the parking point to grab the extruder + #define PARKING_EXTRUDER_SECURITY_RAISE 5 // Z-raise before parking + #define HOTEND_OFFSET_Z { 0.0, 1.3 } // Z-offsets of the two hotends. The first must be 0. +#endif + +/** + * "Mixing Extruder" + * - Adds a new code, M165, to set the current mix factors. + * - Extends the stepping routines to move multiple steppers in proportion to the mix. + * - Optional support for Repetier Firmware M163, M164, and virtual extruder. + * - This implementation supports only a single extruder. + * - Enable DIRECT_MIXING_IN_G1 for Pia Taubert's reference implementation + */ +//#define MIXING_EXTRUDER +#if ENABLED(MIXING_EXTRUDER) + #define MIXING_STEPPERS 2 // Number of steppers in your mixing extruder + #define MIXING_VIRTUAL_TOOLS 16 // Use the Virtual Tool method with M163 and M164 + //#define DIRECT_MIXING_IN_G1 // Allow ABCDHI mix factors in G1 movement commands +#endif + +// Offset of the extruders (uncomment if using more than one and relying on firmware to position when changing). +// The offset has to be X=0, Y=0 for the extruder 0 hotend (default extruder). +// For the other hotends it is their distance from the extruder 0 hotend. +//#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis +//#define HOTEND_OFFSET_Y {0.0, 5.00} // (in mm) for each extruder, offset of the hotend on the Y axis + +// @section machine + +/** + * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN + * + * 0 = No Power Switch + * 1 = ATX + * 2 = X-Box 360 203Watts (the blue wire connected to PS_ON and the red wire to VCC) + * + * :{ 0:'No power switch', 1:'ATX', 2:'X-Box 360' } + */ +#define POWER_SUPPLY 1 + +#if POWER_SUPPLY > 0 + // Enable this option to leave the PSU off at startup. + // Power to steppers and heaters will need to be turned on with M80. + //#define PS_DEFAULT_OFF +#endif + +// @section temperature + +//=========================================================================== +//============================= Thermal Settings ============================ +//=========================================================================== + +/** + * --NORMAL IS 4.7kohm PULLUP!-- 1kohm pullup can be used on hotend sensor, using correct resistor and table + * + * Temperature sensors available: + * + * -3 : thermocouple with MAX31855 (only for sensor 0) + * -2 : thermocouple with MAX6675 (only for sensor 0) + * -1 : thermocouple with AD595 + * 0 : not used + * 1 : 100k thermistor - best choice for EPCOS 100k (4.7k pullup) + * 2 : 200k thermistor - ATC Semitec 204GT-2 (4.7k pullup) + * 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 (Used in ParCan & J-Head) (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) + * 71 : 100k Honeywell thermistor 135-104LAF-J01 (4.7k pullup) + * 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) + * 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" + * 20 : the PT100 circuit found in the Ultimainboard V2.x + * 60 : 100k Maker's Tool Works Kapton Bed Thermistor beta=3950 + * 66 : 4.7M High Temperature thermistor from Dyze Design + * 70 : the 100K thermistor found in the bq Hephestos 2 + * 75 : 100k Generic Silicon Heat Pad with NTC 100K MGB18-104F39050L32 thermistor + * + * 1k ohm pullup tables - This is atypical, and requires changing out the 4.7k pullup for 1k. + * (but gives greater accuracy and more stable PID) + * 51 : 100k thermistor - EPCOS (1k pullup) + * 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 + * 1010 : Pt1000 with 1k pullup (non standard) + * 147 : Pt100 with 4k7 pullup + * 110 : Pt100 with 1k pullup (non standard) + * + * Use these for Testing or Development purposes. NEVER for production machine. + * 998 : Dummy Table that ALWAYS reads 25°C or the temperature defined below. + * 999 : Dummy Table that ALWAYS reads 100°C or the temperature defined below. + * + * :{ '0': "Not used", '1':"100k / 4.7k - EPCOS", '2':"200k / 4.7k - ATC Semitec 204GT-2", '3':"Mendel-parts / 4.7k", '4':"10k !! do not use for a hotend. Bad resolution at high temp. !!", '5':"100K / 4.7k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '6':"100k / 4.7k EPCOS - Not as accurate as Table 1", '7':"100k / 4.7k Honeywell 135-104LAG-J01", '8':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT", '9':"100k / 4.7k GE Sensing AL03006-58.2K-97-G1", '10':"100k / 4.7k RS 198-961", '11':"100k / 4.7k beta 3950 1%", '12':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT (calibrated for Makibox hot bed)", '13':"100k Hisens 3950 1% up to 300°C for hotend 'Simple ONE ' & hotend 'All In ONE'", '20':"PT100 (Ultimainboard V2.x)", '51':"100k / 1k - EPCOS", '52':"200k / 1k - ATC Semitec 204GT-2", '55':"100k / 1k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '60':"100k Maker's Tool Works Kapton Bed Thermistor beta=3950", '66':"Dyze Design 4.7M High Temperature thermistor", '70':"the 100K thermistor found in the bq Hephestos 2", '71':"100k / 4.7k Honeywell 135-104LAF-J01", '147':"Pt100 / 4.7k", '1047':"Pt1000 / 4.7k", '110':"Pt100 / 1k (non-standard)", '1010':"Pt1000 / 1k (non standard)", '-3':"Thermocouple + MAX31855 (only for sensor 0)", '-2':"Thermocouple + MAX6675 (only for sensor 0)", '-1':"Thermocouple + AD595",'998':"Dummy 1", '999':"Dummy 2" } + */ +#define TEMP_SENSOR_0 1 +#define TEMP_SENSOR_1 0 +#define TEMP_SENSOR_2 0 +#define TEMP_SENSOR_3 0 +#define TEMP_SENSOR_4 0 +#define TEMP_SENSOR_BED 1 + +// Dummy thermistor constant temperature readings, for use with 998 and 999 +#define DUMMY_THERMISTOR_998_VALUE 25 +#define DUMMY_THERMISTOR_999_VALUE 100 + +// 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 +#define MAX_REDUNDANT_TEMP_SENSOR_DIFF 10 + +// Extruder temperature must be close to target for this long before M109 returns success +#define TEMP_RESIDENCY_TIME 3 // (seconds) +#define TEMP_HYSTERESIS 2 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// Bed temperature must be close to target for this long before M190 returns success +#define TEMP_BED_RESIDENCY_TIME 0 // (seconds) +#define TEMP_BED_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_BED_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// The minimal temperature defines the temperature below which the heater will not be enabled It is used +// to check that the wiring to the thermistor is not broken. +// Otherwise this would lead to the heater being powered on all the time. +#define HEATER_0_MINTEMP 5 +#define HEATER_1_MINTEMP 5 +#define HEATER_2_MINTEMP 5 +#define HEATER_3_MINTEMP 5 +#define HEATER_4_MINTEMP 5 +#define BED_MINTEMP 5 + +// When temperature exceeds max temp, your heater will be switched off. +// This feature exists to protect your hotend from overheating accidentally, but *NOT* from thermistor short/failure! +// You should use MINTEMP for thermistor short/failure protection. +#define HEATER_0_MAXTEMP 275 +#define HEATER_1_MAXTEMP 275 +#define HEATER_2_MAXTEMP 275 +#define HEATER_3_MAXTEMP 275 +#define HEATER_4_MAXTEMP 275 +#define BED_MAXTEMP 150 + +//=========================================================================== +//============================= PID Settings ================================ +//=========================================================================== +// PID Tuning Guide here: http://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 +#if ENABLED(PIDTEMP) + //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. + //#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 20 // 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. + #define K1 0.95 //smoothing factor within the PID + + // Merlin Hotend: From Autotune + #define DEFAULT_Kp 24.5 + #define DEFAULT_Ki 1.72 + #define DEFAULT_Kd 87.73 + +#endif // PIDTEMP + +//=========================================================================== +//============================= PID > Bed Temperature Control =============== +//=========================================================================== +// Select PID or bang-bang with PIDTEMPBED. If bang-bang, BED_LIMIT_SWITCHING will enable hysteresis +// +// Uncomment this to enable PID on the bed. It uses the same frequency PWM as the extruder. +// If your PID_dT is the default, and correct for your hardware/configuration, that means 7.689Hz, +// which is fine for driving a square wave into a resistive load and does not significantly impact you FET heating. +// This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W heater. +// If your configuration is significantly different than this and you don't understand the issues involved, you probably +// shouldn't use bed PID until someone else verifies your hardware works. +// If this is enabled, find your own PID constants below. +#define PIDTEMPBED + +//#define BED_LIMIT_SWITCHING + +// This sets the max power delivered to the bed, and replaces the HEATER_BED_DUTY_CYCLE_DIVIDER option. +// all forms of bed control obey this (PID, bang-bang, bang-bang with hysteresis) +// setting this to anything other than 255 enables a form of PWM to the bed just like HEATER_BED_DUTY_CYCLE_DIVIDER did, +// so you shouldn't use it unless you are OK with PWM on your bed. (see the comment on enabling PIDTEMPBED) +#define MAX_BED_POWER 255 // limits duty cycle to bed; 255=full current + +#if ENABLED(PIDTEMPBED) + + //#define PID_BED_DEBUG // Sends debug data to the serial port. + + //12v Heatbed Mk3 12V in parallel + //from pidautotune + #define DEFAULT_bedKp 630.14 + #define DEFAULT_bedKi 121.71 + #define DEFAULT_bedKd 815.64 + + // FIND YOUR OWN: "M303 E-1 C8 S90" to run autotune on the bed at 90 degreesC for 8 cycles. +#endif // PIDTEMPBED + +// @section extruder + +// This option prevents extrusion if the temperature is below EXTRUDE_MINTEMP. +// It also enables the M302 command to set the minimum extrusion temperature +// or to allow moving the extruder regardless of the hotend temperature. +// *** IT IS HIGHLY RECOMMENDED TO LEAVE THIS OPTION ENABLED! *** +#define PREVENT_COLD_EXTRUSION +#define EXTRUDE_MINTEMP 170 + +// This option prevents a single extrusion longer than EXTRUDE_MAXLENGTH. +// Note that for Bowden Extruders a too-small value here may prevent loading. +#define PREVENT_LENGTHY_EXTRUDE +#define EXTRUDE_MAXLENGTH 200 + +//=========================================================================== +//======================== Thermal Runaway Protection ======================= +//=========================================================================== + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * If you get "Thermal Runaway" or "Heating failed" errors the + * details can be tuned in Configuration_adv.h + */ + +#define THERMAL_PROTECTION_HOTENDS // Enable thermal protection for all extruders +#define THERMAL_PROTECTION_BED // Enable thermal protection for the heated bed + +//=========================================================================== +//============================= Mechanical Settings ========================= +//=========================================================================== + +// @section machine + +// Uncomment one of these options to enable CoreXY, CoreXZ, or CoreYZ kinematics +// either in the usual order or reversed +//#define COREXY +//#define COREXZ +//#define COREYZ +//#define COREYX +//#define COREZX +//#define COREZY + +//=========================================================================== +//============================== Endstop Settings =========================== +//=========================================================================== + +// @section homing + +// Specify here all the endstop connectors that are connected to any endstop or probe. +// Almost all printers will be using one per axis. Probes will use one or more of the +// extra connectors. Leave undefined any used for non-endstop and non-probe purposes. +#define USE_XMIN_PLUG +#define USE_YMIN_PLUG +//#define USE_ZMIN_PLUG +//#define USE_XMAX_PLUG +//#define USE_YMAX_PLUG +#define USE_ZMAX_PLUG + +// coarse Endstop Settings +//#define ENDSTOPPULLUPS // Comment this out (using // at the start of the line) to disable the endstop pullup resistors + +#if DISABLED(ENDSTOPPULLUPS) + // fine endstop settings: Individual pullups. will be ignored if ENDSTOPPULLUPS is defined + //#define ENDSTOPPULLUP_XMAX + //#define ENDSTOPPULLUP_YMAX + #define ENDSTOPPULLUP_ZMAX // open pin, inverted + #define ENDSTOPPULLUP_XMIN // open pin, inverted + #define ENDSTOPPULLUP_YMIN // open pin, inverted + //#define ENDSTOPPULLUP_ZMIN + //#define ENDSTOPPULLUP_ZMIN_PROBE +#endif + +// Mechanical endstop with COM to ground and NC to Signal uses "false" here (most common setup). +#define X_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Y_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define X_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Y_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MIN_PROBE_ENDSTOP_INVERTING true // set to true to invert the logic of the probe. + +// Enable this feature if all enabled endstop pins are interrupt-capable. +// This will remove the need to poll the interrupt pins, saving many CPU cycles. +//#define ENDSTOP_INTERRUPTS_FEATURE + +//============================================================================= +//============================== Movement Settings ============================ +//============================================================================= +// @section motion + +/** + * Default Settings + * + * These settings can be reset by M502 + * + * Note that if EEPROM is enabled, saved values will override these. + */ + +/** + * With this option each E stepper can have its own factors for the + * following movement settings. If fewer factors are given than the + * total number of extruders, the last value applies to the rest. + */ +//#define DISTINCT_E_FACTORS + +/** + * Default Axis Steps Per Unit (steps/mm) + * Override with M92 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_AXIS_STEPS_PER_UNIT { 103.69, 106.65, 200/1.25, 1000 } // default steps per unit for SCARA + +/** + * Default Max Feed Rate (mm/s) + * Override with M203 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_FEEDRATE { 300, 300, 30, 25 } + +/** + * Default Max Acceleration (change/s) change = mm/s + * (Maximum start speed for accelerated moves) + * Override with M201 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_ACCELERATION { 300, 300, 20, 1000 } + +/** + * Default Acceleration (change/s) change = mm/s + * Override with M204 + * + * M204 P Acceleration + * M204 R Retract Acceleration + * M204 T Travel Acceleration + */ +#define DEFAULT_ACCELERATION 400 // X, Y, Z and E acceleration for printing moves +#define DEFAULT_RETRACT_ACCELERATION 2000 // E acceleration for retracts +#define DEFAULT_TRAVEL_ACCELERATION 400 // X, Y, Z acceleration for travel (non printing) moves + +/** + * Default Jerk (mm/s) + * Override with M205 X Y Z E + * + * "Jerk" specifies the minimum speed change that requires acceleration. + * When changing speed and direction, if the difference is less than the + * value set here, it may happen instantaneously. + */ +#define DEFAULT_XJERK 5.0 +#define DEFAULT_YJERK 5.0 +#define DEFAULT_ZJERK 0.4 +#define DEFAULT_EJERK 3.0 + +//=========================================================================== +//============================= Z Probe Options ============================= +//=========================================================================== +// @section probes + +// +// See http://marlinfw.org/configuration/probes.html +// + +/** + * Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + * + * Enable this option for a probe connected to the Z Min endstop pin. + */ +#define Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + +/** + * Z_MIN_PROBE_ENDSTOP + * + * Enable this option for a probe connected to any pin except Z-Min. + * (By default Marlin assumes the Z-Max endstop pin.) + * To use a custom Z Probe pin, set Z_MIN_PROBE_PIN below. + * + * - The simplest option is to use a free endstop connector. + * - Use 5V for powered (usually inductive) sensors. + * + * - RAMPS 1.3/1.4 boards may use the 5V, GND, and Aux4->D32 pin: + * - For simple switches connect... + * - normally-closed switches to GND and D32. + * - normally-open switches to 5V and D32. + * + * WARNING: Setting the wrong pin may have unexpected and potentially + * disastrous consequences. Use with caution and do your homework. + * + */ +//#define Z_MIN_PROBE_ENDSTOP + +/** + * Probe Type + * + * Allen Key Probes, Servo Probes, Z-Sled Probes, FIX_MOUNTED_PROBE, etc. + * Activate one of these to use Auto Bed Leveling below. + */ + +/** + * The "Manual Probe" provides a means to do "Auto" Bed Leveling without a probe. + * Use G29 repeatedly, adjusting the Z height at each point with movement commands + * or (with LCD_BED_LEVELING) the LCD controller. + */ +//#define PROBE_MANUALLY + +/** + * A Fix-Mounted Probe either doesn't deploy or needs manual deployment. + * (e.g., an inductive probe or a nozzle-based probe-switch.) + */ +//#define FIX_MOUNTED_PROBE + +/** + * Z Servo Probe, such as an endstop switch on a rotating arm. + */ +//#define Z_ENDSTOP_SERVO_NR 0 // Defaults to SERVO 0 connector. +//#define Z_SERVO_ANGLES {70,0} // Z Servo Deploy and Stow angles + +/** + * The BLTouch probe uses a Hall effect sensor and emulates a servo. + */ +//#define BLTOUCH +#if ENABLED(BLTOUCH) + //#define BLTOUCH_DELAY 375 // (ms) Enable and increase if needed +#endif + +/** + * Enable one or more of the following if probing seems unreliable. + * Heaters and/or fans can be disabled during probing to minimize electrical + * noise. A delay can also be added to allow noise and vibration to settle. + * These options are most useful for the BLTouch probe, but may also improve + * readings with inductive probes and piezo sensors. + */ +//#define PROBING_HEATERS_OFF // Turn heaters off when probing +//#define PROBING_FANS_OFF // Turn fans off when probing +//#define DELAY_BEFORE_PROBING 200 // (ms) To prevent vibrations from triggering piezo sensors + +// A probe that is deployed and stowed with a solenoid pin (SOL1_PIN) +//#define SOLENOID_PROBE + +// A sled-mounted probe like those designed by Charles Bell. +//#define Z_PROBE_SLED +//#define SLED_DOCKING_OFFSET 5 // The extra distance the X axis must travel to pickup the sled. 0 should be fine but you can push it further if you'd like. + +// +// For Z_PROBE_ALLEN_KEY see the Delta example configurations. +// + +/** + * Z Probe to nozzle (X,Y) offset, relative to (0, 0). + * X and Y offsets must be integers. + * + * In the following example the X and Y offsets are both positive: + * #define X_PROBE_OFFSET_FROM_EXTRUDER 10 + * #define Y_PROBE_OFFSET_FROM_EXTRUDER 10 + * + * +-- BACK ---+ + * | | + * L | (+) P | R <-- probe (20,20) + * E | | I + * F | (-) N (+) | G <-- nozzle (10,10) + * T | | H + * | (-) | T + * | | + * O-- FRONT --+ + * (0,0) + */ +#define X_PROBE_OFFSET_FROM_EXTRUDER -25 // X offset: -left +right [of the nozzle] +#define Y_PROBE_OFFSET_FROM_EXTRUDER -29 // Y offset: -front +behind [the nozzle] +#define Z_PROBE_OFFSET_FROM_EXTRUDER -12.35 // Z offset: -below +above [the nozzle] + +// X and Y axis travel speed (mm/m) between probes +#define XY_PROBE_SPEED 8000 + +// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +#define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z + +// Speed for the "accurate" probe of each point +#define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) + +// Use double touch for probing +//#define PROBE_DOUBLE_TOUCH + +/** + * Z probes require clearance when deploying, stowing, and moving between + * probe points to avoid hitting the bed and other hardware. + * Servo-mounted probes require extra space for the arm to rotate. + * Inductive probes need space to keep from triggering early. + * + * Use these settings to specify the distance (mm) to raise the probe (or + * lower the bed). The values set here apply over and above any (negative) + * probe Z Offset set with Z_PROBE_OFFSET_FROM_EXTRUDER, M851, or the LCD. + * Only integer values >= 1 are valid here. + * + * Example: `M851 Z-5` with a CLEARANCE of 4 => 9mm from bed to nozzle. + * But: `M851 Z+1` with a CLEARANCE of 2 => 2mm from bed to nozzle. + */ +#define Z_CLEARANCE_DEPLOY_PROBE 15 // Z Clearance for Deploy/Stow +#define Z_CLEARANCE_BETWEEN_PROBES 5 // Z Clearance between probe points + +// For M851 give a range for adjusting the Z probe offset +#define Z_PROBE_OFFSET_RANGE_MIN -20 +#define Z_PROBE_OFFSET_RANGE_MAX 20 + +// Enable the M48 repeatability test to test probe accuracy +//#define Z_MIN_PROBE_REPEATABILITY_TEST + +// For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1 +// :{ 0:'Low', 1:'High' } +#define X_ENABLE_ON 0 +#define Y_ENABLE_ON 0 +#define Z_ENABLE_ON 0 +#define E_ENABLE_ON 0 // For all extruders + +// Disables axis stepper immediately when it's not being used. +// 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 +//#define DISABLE_REDUCED_ACCURACY_WARNING + +// @section extruder + +#define DISABLE_E false // For all extruders +#define DISABLE_INACTIVE_EXTRUDER true // Keep only the active extruder enabled. + +// @section machine + +// Invert the stepper direction. Change (or reverse the motor connector) if an axis goes the wrong way. +#define INVERT_X_DIR false +#define INVERT_Y_DIR false +#define INVERT_Z_DIR true + +// Enable this option for Toshiba stepper drivers +//#define CONFIG_STEPPERS_TOSHIBA + +// @section extruder + +// For direct drive extruder v9 set to true, for geared extruder set to false. +#define INVERT_E0_DIR false +#define INVERT_E1_DIR false +#define INVERT_E2_DIR false +#define INVERT_E3_DIR false +#define INVERT_E4_DIR false + +// @section homing + +//#define NO_MOTION_BEFORE_HOMING // Inhibit movement until all axes have been homed + +//#define Z_HOMING_HEIGHT 4 // (in mm) Minimal z height before homing (G28) for Z clearance above the bed, clamps, ... + // Be sure you have this distance over your Z_MAX_POS in case. + +// Direction of endstops when homing; 1=MAX, -1=MIN +// :[-1,1] +#define X_HOME_DIR 1 +#define Y_HOME_DIR 1 +#define Z_HOME_DIR -1 + +// @section machine + +// The size of the print bed +#define X_BED_SIZE 200 +#define Y_BED_SIZE 200 + +// Travel limits (mm) after homing, corresponding to endstop positions. +#define X_MIN_POS 0 +#define Y_MIN_POS 0 +#define Z_MIN_POS MANUAL_Z_HOME_POS +#define X_MAX_POS X_BED_SIZE +#define Y_MAX_POS Y_BED_SIZE +#define Z_MAX_POS 225 + +// If enabled, axes won't move below MIN_POS in response to movement commands. +#define MIN_SOFTWARE_ENDSTOPS +// If enabled, axes won't move above MAX_POS in response to movement commands. +#define MAX_SOFTWARE_ENDSTOPS + +/** + * Filament Runout Sensor + * A mechanical or opto endstop is used to check for the presence of filament. + * + * RAMPS-based boards use SERVO3_PIN. + * For other boards you may need to define FIL_RUNOUT_PIN. + * By default the firmware assumes HIGH = has filament, LOW = ran out + */ +//#define FILAMENT_RUNOUT_SENSOR +#if ENABLED(FILAMENT_RUNOUT_SENSOR) + #define FIL_RUNOUT_INVERTING false // set to true to invert the logic of the sensor. + #define ENDSTOPPULLUP_FIL_RUNOUT // Uncomment to use internal pullup for filament runout pins if the sensor is defined. + #define FILAMENT_RUNOUT_SCRIPT "M600" +#endif + +//=========================================================================== +//=============================== Bed Leveling ============================== +//=========================================================================== +// @section bedlevel + +/** + * Choose one of the options below to enable G29 Bed Leveling. The parameters + * and behavior of G29 will change depending on your selection. + * + * If using a Probe for Z Homing, enable Z_SAFE_HOMING also! + * + * - AUTO_BED_LEVELING_3POINT + * Probe 3 arbitrary points on the bed (that aren't collinear) + * You specify the XY coordinates of all 3 points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_LINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_BILINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a mesh, best for large or uneven beds. + * + * - AUTO_BED_LEVELING_UBL (Unified Bed Leveling) + * A comprehensive bed leveling system combining the features and benefits + * of other systems. UBL also includes integrated Mesh Generation, Mesh + * Validation and Mesh Editing systems. Currently, UBL is only checked out + * for Cartesian Printers. That said, it was primarily designed to correct + * poor quality Delta Printers. If you feel adventurous and have a Delta, + * please post an issue if something doesn't work correctly. Initially, + * you will need to set a reduced bed size so you have a rectangular area + * to test on. + * + * - MESH_BED_LEVELING + * Probe a grid manually + * The result is a mesh, suitable for large or uneven beds. (See BILINEAR.) + * For machines without a probe, Mesh Bed Leveling provides a method to perform + * leveling in steps so you can manually adjust the Z height at each grid-point. + * With an LCD controller the process is guided step-by-step. + */ +//#define AUTO_BED_LEVELING_3POINT +//#define AUTO_BED_LEVELING_LINEAR +//#define AUTO_BED_LEVELING_BILINEAR +//#define AUTO_BED_LEVELING_UBL +//#define MESH_BED_LEVELING + +/** + * Enable detailed logging of G28, G29, M48, etc. + * Turn on with the command 'M111 S32'. + * NOTE: Requires a lot of PROGMEM! + */ +//#define DEBUG_LEVELING_FEATURE + +#if ENABLED(MESH_BED_LEVELING) || ENABLED(AUTO_BED_LEVELING_BILINEAR) || ENABLED(AUTO_BED_LEVELING_UBL) + // Gradually reduce leveling correction until a set height is reached, + // at which point movement will be level to the machine's XY plane. + // The height can be set with M420 Z + #define ENABLE_LEVELING_FADE_HEIGHT +#endif + +#if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Set the number of grid points per dimension. + #define GRID_MAX_POINTS_X 3 + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + // Set the boundaries for probing (where the probe can reach). + #define LEFT_PROBE_BED_POSITION 15 + #define RIGHT_PROBE_BED_POSITION 170 + #define FRONT_PROBE_BED_POSITION 20 + #define BACK_PROBE_BED_POSITION 170 + + // The Z probe minimum outer margin (to validate G29 parameters). + #define MIN_PROBE_EDGE 10 + + // Probe along the Y axis, advancing X after each column + //#define PROBE_Y_FIRST + + #if ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Beyond the probed grid, continue the implied tilt? + // Default is to maintain the height of the nearest edge. + //#define EXTRAPOLATE_BEYOND_GRID + + // + // Experimental Subdivision of the grid by Catmull-Rom method. + // Synthesizes intermediate points to produce a more detailed mesh. + // + //#define ABL_BILINEAR_SUBDIVISION + #if ENABLED(ABL_BILINEAR_SUBDIVISION) + // Number of subdivisions between probe points + #define BILINEAR_SUBDIVISIONS 3 + #endif + + #endif + +#elif ENABLED(AUTO_BED_LEVELING_3POINT) + + // 3 arbitrary points to probe. + // A simple cross-product is used to estimate the plane of the bed. + #define ABL_PROBE_PT_1_X 15 + #define ABL_PROBE_PT_1_Y 180 + #define ABL_PROBE_PT_2_X 15 + #define ABL_PROBE_PT_2_Y 20 + #define ABL_PROBE_PT_3_X 170 + #define ABL_PROBE_PT_3_Y 20 + +#elif ENABLED(AUTO_BED_LEVELING_UBL) + + //=========================================================================== + //========================= Unified Bed Leveling ============================ + //=========================================================================== + + #define UBL_MESH_INSET 1 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 10 // Don't use more than 15 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + #define UBL_PROBE_PT_1_X 39 // Probing points for 3-Point leveling of the mesh + #define UBL_PROBE_PT_1_Y 180 + #define UBL_PROBE_PT_2_X 39 + #define UBL_PROBE_PT_2_Y 20 + #define UBL_PROBE_PT_3_X 180 + #define UBL_PROBE_PT_3_Y 20 + + #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation + #define UBL_MESH_EDIT_MOVES_Z // Sophisticated users prefer no movement of nozzle + +#elif ENABLED(MESH_BED_LEVELING) + + //=========================================================================== + //=================================== Mesh ================================== + //=========================================================================== + + #define MESH_INSET 10 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 3 // Don't use more than 7 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + //#define MESH_G28_REST_ORIGIN // After homing all axes ('G28' or 'G28 XYZ') rest Z at Z_MIN_POS + +#endif // BED_LEVELING + +/** + * Use the LCD controller for bed leveling + * Requires MESH_BED_LEVELING or PROBE_MANUALLY + */ +//#define LCD_BED_LEVELING + +#if ENABLED(LCD_BED_LEVELING) + #define MBL_Z_STEP 0.025 // Step size while manually probing Z axis. + #define LCD_PROBE_Z_RANGE 4 // Z Range centered on Z_MIN_POS for LCD Z adjustment +#endif + +// Add a menu item to move between bed corners for manual bed adjustment +//#define LEVEL_BED_CORNERS + +/** + * Commands to execute at the end of G29 probing. + * Useful to retract or move the Z probe out of the way. + */ +//#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) +//#define BED_CENTER_AT_0_0 + +// Manually set the home position. Leave these undefined for automatic settings. +// For DELTA this is the top-center of the Cartesian print volume. +#define MANUAL_X_HOME_POS -22 +#define MANUAL_Y_HOME_POS -52 +#define MANUAL_Z_HOME_POS 0.1 + +// Use "Z Safe Homing" to avoid homing with a Z probe outside the bed area. +// +// With this feature enabled: +// +// - 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). +// - 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 axis (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). +#endif + +// Homing speeds (mm/m) +#define HOMING_FEEDRATE_XY (40*60) +#define HOMING_FEEDRATE_Z (10*60) + +//============================================================================= +//============================= Additional Features =========================== +//============================================================================= + +// @section extras + +// +// EEPROM +// +// The microcontroller can store settings in the EEPROM, e.g. max velocity... +// M500 - stores parameters in EEPROM +// M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily). +// M502 - reverts to the default "factory settings". You still need to store them in EEPROM afterwards if you want to. +// +//#define EEPROM_SETTINGS // Enable for M500 and M501 commands +//#define DISABLE_M503 // Saves ~2700 bytes of PROGMEM. Disable for release! +#define EEPROM_CHITCHAT // Give feedback on EEPROM commands. Disable to save PROGMEM. + +// +// Host Keepalive +// +// When enabled Marlin will send a busy status message to the host +// every couple of seconds when it can't accept commands. +// +#define HOST_KEEPALIVE_FEATURE // Disable this if your host doesn't like keepalive messages +#define DEFAULT_KEEPALIVE_INTERVAL 2 // Number of seconds between "busy" messages. Set with M113. +#define BUSY_WHILE_HEATING // Some hosts require "busy" messages even during heating + +// +// M100 Free Memory Watcher +// +//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose + +// +// G20/G21 Inch mode support +// +//#define INCH_MODE_SUPPORT + +// +// M149 Set temperature units support +// +//#define TEMPERATURE_UNITS_SUPPORT + +// @section temperature + +// Preheat Constants +#define PREHEAT_1_TEMP_HOTEND 180 +#define PREHEAT_1_TEMP_BED 70 +#define PREHEAT_1_FAN_SPEED 255 // Value from 0 to 255 + +#define PREHEAT_2_TEMP_HOTEND 240 +#define PREHEAT_2_TEMP_BED 100 +#define PREHEAT_2_FAN_SPEED 255 // Value from 0 to 255 + +/** + * Nozzle Park -- EXPERIMENTAL + * + * Park the nozzle at the given XYZ position on idle or G27. + * + * The "P" parameter controls the action applied to the Z axis: + * + * P0 (Default) If Z is below park Z raise the nozzle. + * P1 Raise the nozzle always to Z-park height. + * P2 Raise the nozzle by Z-park amount, limited to Z_MAX_POS. + */ +//#define NOZZLE_PARK_FEATURE + +#if ENABLED(NOZZLE_PARK_FEATURE) + // Specify a park position as { X, Y, Z } + #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 } +#endif + +/** + * Clean Nozzle Feature -- EXPERIMENTAL + * + * Adds the G12 command to perform a nozzle cleaning process. + * + * Parameters: + * P Pattern + * S Strokes / Repetitions + * T Triangles (P1 only) + * + * Patterns: + * P0 Straight line (default). This process requires a sponge type material + * at a fixed bed location. "S" specifies strokes (i.e. back-forth motions) + * between the start / end points. + * + * P1 Zig-zag pattern between (X0, Y0) and (X1, Y1), "T" specifies the + * number of zig-zag triangles to do. "S" defines the number of strokes. + * Zig-zags are done in whichever is the narrower dimension. + * For example, "G12 P1 S1 T3" will execute: + * + * -- + * | (X0, Y1) | /\ /\ /\ | (X1, Y1) + * | | / \ / \ / \ | + * A | | / \ / \ / \ | + * | | / \ / \ / \ | + * | (X0, Y0) | / \/ \/ \ | (X1, Y0) + * -- +--------------------------------+ + * |________|_________|_________| + * T1 T2 T3 + * + * P2 Circular pattern with middle at NOZZLE_CLEAN_CIRCLE_MIDDLE. + * "R" specifies the radius. "S" specifies the stroke count. + * Before starting, the nozzle moves to NOZZLE_CLEAN_START_POINT. + * + * Caveats: The ending Z should be the same as starting Z. + * Attention: EXPERIMENTAL. G-code arguments may change. + * + */ +//#define NOZZLE_CLEAN_FEATURE + +#if ENABLED(NOZZLE_CLEAN_FEATURE) + // Default number of pattern repetitions + #define NOZZLE_CLEAN_STROKES 12 + + // Default number of triangles + #define NOZZLE_CLEAN_TRIANGLES 3 + + // Specify positions as { X, Y, Z } + #define NOZZLE_CLEAN_START_POINT { 30, 30, (Z_MIN_POS + 1)} + #define NOZZLE_CLEAN_END_POINT {100, 60, (Z_MIN_POS + 1)} + + // Circular pattern radius + #define NOZZLE_CLEAN_CIRCLE_RADIUS 6.5 + // Circular pattern circle fragments number + #define NOZZLE_CLEAN_CIRCLE_FN 10 + // Middle point of circle + #define NOZZLE_CLEAN_CIRCLE_MIDDLE NOZZLE_CLEAN_START_POINT + + // Moves the nozzle to the initial position + #define NOZZLE_CLEAN_GOBACK +#endif + +/** + * Print Job Timer + * + * Automatically start and stop the print job timer on M104/M109/M190. + * + * M104 (hotend, no wait) - high temp = none, low temp = stop timer + * M109 (hotend, wait) - high temp = start timer, low temp = stop timer + * M190 (bed, wait) - high temp = start timer, low temp = none + * + * The timer can also be controlled with the following commands: + * + * M75 - Start the print job timer + * M76 - Pause the print job timer + * M77 - Stop the print job timer + */ +#define PRINTJOB_TIMER_AUTOSTART + +/** + * Print Counter + * + * Track statistical data such as: + * + * - Total print jobs + * - Total successful print jobs + * - Total failed print jobs + * - Total time printing + * + * View the current statistics with M78. + */ +//#define PRINTCOUNTER + +//============================================================================= +//============================= LCD and SD support ============================ +//============================================================================= + +// @section lcd + +/** + * LCD LANGUAGE + * + * Select the language to display on the LCD. These languages are available: + * + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, + * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * tr, uk, zh_CN, zh_TW, test + * + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + */ +//#define LCD_LANGUAGE en + +/** + * LCD Character Set + * + * Note: This option is NOT applicable to Graphical Displays. + * + * All character-based LCDs provide ASCII plus one of these + * language extensions: + * + * - JAPANESE ... the most common + * - WESTERN ... with more accented characters + * - CYRILLIC ... for the Russian language + * + * To determine the language extension installed on your controller: + * + * - Compile and upload with LCD_LANGUAGE set to 'test' + * - 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 + * + * :['JAPANESE', 'WESTERN', 'CYRILLIC'] + */ +#define DISPLAY_CHARSET_HD44780 JAPANESE + +/** + * LCD TYPE + * + * Enable ULTRA_LCD for a 16x2, 16x4, 20x2, or 20x4 character-based LCD. + * Enable DOGLCD for a 128x64 (ST7565R) Full Graphical Display. + * (These options will be enabled automatically for most displays.) + * + * IMPORTANT: The U8glib library is required for Full Graphic Display! + * https://github.com/olikraus/U8glib_Arduino + */ +//#define ULTRA_LCD // Character based +//#define DOGLCD // Full graphics display + +/** + * SD CARD + * + * 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 + +/** + * SD CARD: SPI SPEED + * + * Enable one of the following items for a slower SPI transfer speed. + * This may be required to resolve "volume init" errors. + */ +//#define SPI_SPEED SPI_HALF_SPEED +//#define SPI_SPEED SPI_QUARTER_SPEED +//#define SPI_SPEED SPI_EIGHTH_SPEED + +/** + * SD CARD: ENABLE CRC + * + * Use CRC checks and retries on the SD communication. + */ +//#define SD_CHECK_AND_RETRY + +// +// ENCODER SETTINGS +// +// This option overrides the default number of encoder pulses needed to +// produce one step. Should be increased for high-resolution encoders. +// +//#define ENCODER_PULSES_PER_STEP 1 + +// +// Use this option to override the number of step signals required to +// move between next/prev menu items. +// +//#define ENCODER_STEPS_PER_MENU_ITEM 5 + +/** + * Encoder Direction Options + * + * Test your encoder's behavior first with both options disabled. + * + * Reversed Value Edit and Menu Nav? Enable REVERSE_ENCODER_DIRECTION. + * Reversed Menu Navigation only? Enable REVERSE_MENU_DIRECTION. + * Reversed Value Editing only? Enable BOTH options. + */ + +// +// This option reverses the encoder direction everywhere. +// +// Set this option if CLOCKWISE causes values to DECREASE +// +//#define REVERSE_ENCODER_DIRECTION + +// +// This option reverses the encoder direction for navigating LCD menus. +// +// If CLOCKWISE normally moves DOWN this makes it go UP. +// If CLOCKWISE normally moves UP this makes it go DOWN. +// +//#define REVERSE_MENU_DIRECTION + +// +// Individual Axis Homing +// +// Add individual axis homing items (Home X, Home Y, and Home Z) to the LCD menu. +// +//#define INDIVIDUAL_AXIS_HOMING_MENU + +// +// SPEAKER/BUZZER +// +// If you have a speaker that can produce tones, enable it here. +// By default Marlin assumes you have a buzzer with a fixed frequency. +// +//#define SPEAKER + +// +// The duration and frequency for the UI feedback sound. +// Set these to 0 to disable audio feedback in the LCD menus. +// +// Note: Test audio output with the G-Code: +// M300 S P +// +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 +//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 + +// +// CONTROLLER TYPE: Standard +// +// Marlin supports a wide variety of controllers. +// Enable one of the following options to specify your controller. +// + +// +// ULTIMAKER Controller. +// +//#define ULTIMAKERCONTROLLER + +// +// ULTIPANEL as seen on Thingiverse. +// +//#define ULTIPANEL + +// +// PanelOne from T3P3 (via RAMPS 1.4 AUX2/AUX3) +// http://reprap.org/wiki/PanelOne +// +//#define PANEL_ONE + +// +// MaKr3d Makr-Panel with graphic controller and SD support. +// http://reprap.org/wiki/MaKr3d_MaKrPanel +// +//#define MAKRPANEL + +// +// ReprapWorld Graphical LCD +// https://reprapworld.com/?products_details&products_id/1218 +// +//#define REPRAPWORLD_GRAPHICAL_LCD + +// +// Activate one of these if you have a Panucatt Devices +// Viki 2.0 or mini Viki with Graphic LCD +// http://panucatt.com +// +//#define VIKI2 +//#define miniVIKI + +// +// Adafruit ST7565 Full Graphic Controller. +// https://github.com/eboston/Adafruit-ST7565-Full-Graphic-Controller/ +// +//#define ELB_FULL_GRAPHIC_CONTROLLER + +// +// RepRapDiscount Smart Controller. +// http://reprap.org/wiki/RepRapDiscount_Smart_Controller +// +// Note: Usually sold with a white PCB. +// +//#define REPRAP_DISCOUNT_SMART_CONTROLLER + +// +// GADGETS3D G3D LCD/SD Controller +// http://reprap.org/wiki/RAMPS_1.3/1.4_GADGETS3D_Shield_with_Panel +// +// Note: Usually sold with a blue PCB. +// +//#define G3D_PANEL + +// +// RepRapDiscount FULL GRAPHIC Smart Controller +// http://reprap.org/wiki/RepRapDiscount_Full_Graphic_Smart_Controller +// +//#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER + +// +// MakerLab Mini Panel with graphic +// controller and SD support - http://reprap.org/wiki/Mini_panel +// +//#define MINIPANEL + +// +// RepRapWorld REPRAPWORLD_KEYPAD v1.1 +// http://reprapworld.com/?products_details&products_id=202&cPath=1591_1626 +// +// REPRAPWORLD_KEYPAD_MOVE_STEP sets how much should the robot move when a key +// is pressed, a value of 10.0 means 10mm per click. +// +//#define REPRAPWORLD_KEYPAD +//#define REPRAPWORLD_KEYPAD_MOVE_STEP 1.0 + +// +// RigidBot Panel V1.0 +// http://www.inventapart.com/ +// +//#define RIGIDBOT_PANEL + +// +// BQ LCD Smart Controller shipped by +// default with the BQ Hephestos 2 and Witbox 2. +// +//#define BQ_LCD_SMART_CONTROLLER + +// +// Cartesio UI +// http://mauk.cc/webshop/cartesio-shop/electronics/user-interface +// +//#define CARTESIO_UI + +// +// ANET_10 Controller supported displays. +// +//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. + // This LCD is known to be susceptible to electrical interference + // which scrambles the display. Pressing any button clears it up. +//#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 + // A clone of the RepRapDiscount full graphics display but with + // different pins/wiring (see pins_ANET_10.h). + +// +// LCD for Melzi Card with Graphical LCD +// +//#define LCD_FOR_MELZI + +// +// CONTROLLER TYPE: I2C +// +// Note: These controllers require the installation of Arduino's LiquidCrystal_I2C +// library. For more info: https://github.com/kiyoshigawa/LiquidCrystal_I2C +// + +// +// Elefu RA Board Control Panel +// http://www.elefu.com/index.php?route=product/product&product_id=53 +// +//#define RA_CONTROL_PANEL + +// +// Sainsmart YW Robot (LCM1602) LCD Display +// +// Note: This controller requires F.Malpartida's LiquidCrystal_I2C library +// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home +// +//#define LCD_I2C_SAINSMART_YWROBOT + +// +// Generic LCM1602 LCD adapter +// +//#define LCM1602 + +// +// PANELOLU2 LCD with status LEDs, +// separate encoder and click inputs. +// +// Note: This controller requires Arduino's LiquidTWI2 library v1.2.3 or later. +// For more info: https://github.com/lincomatic/LiquidTWI2 +// +// Note: The PANELOLU2 encoder click input can either be directly connected to +// a pin (if BTN_ENC defined to != -1) or read through I2C (when BTN_ENC == -1). +// +//#define LCD_I2C_PANELOLU2 + +// +// Panucatt VIKI LCD with status LEDs, +// integrated click & L/R/U/D buttons, separate encoder inputs. +// +//#define LCD_I2C_VIKI + +// +// SSD1306 OLED full graphics generic display +// +//#define U8GLIB_SSD1306 + +// +// SAV OLEd LCD module support using either SSD1306 or SH1106 based LCD modules +// +//#define SAV_3DGLCD +#if ENABLED(SAV_3DGLCD) + //#define U8GLIB_SSD1306 + #define U8GLIB_SH1106 +#endif + +// +// CONTROLLER TYPE: Shift register panels +// +// 2 wire Non-latching LCD SR from https://goo.gl/aJJ4sH +// LCD configuration: http://reprap.org/wiki/SAV_3D_LCD +// +//#define SAV_3DLCD + +// +// TinyBoy2 128x64 OLED / Encoder Panel +// +//#define OLED_PANEL_TINYBOY2 + +// +// Makeboard 3D Printer Parts 3D Printer Mini Display 1602 Mini Controller +// https://www.aliexpress.com/item/Micromake-Makeboard-3D-Printer-Parts-3D-Printer-Mini-Display-1602-Mini-Controller-Compatible-with-Ramps-1/32765887917.html +// +//#define MAKEBOARD_MINI_2_LINE_DISPLAY_1602 + +// +// MKS MINI12864 with graphic controller and SD support +// http://reprap.org/wiki/MKS_MINI_12864 +// +//#define MKS_MINI_12864 + +// +// Factory display for Creality CR-10 +// https://www.aliexpress.com/item/Universal-LCD-12864-3D-Printer-Display-Screen-With-Encoder-For-CR-10-CR-7-Model/32833148327.html +// +// This is RAMPS-compatible using a single 10-pin connector. +// (For CR-10 owners who want to replace the Melzi Creality board but retain the display) +// +//#define CR10_STOCKDISPLAY + +// +// MKS OLED 1.3" 128 × 64 FULL GRAPHICS CONTROLLER +// http://reprap.org/wiki/MKS_12864OLED +// +// Tiny, but very sharp OLED display +// +//#define MKS_12864OLED + +//============================================================================= +//=============================== Extra Features ============================== +//============================================================================= + +// @section extras + +// Increase the FAN PWM frequency. Removes the PWM noise but increases heating in the FET/Arduino +//#define FAST_PWM_FAN + +// Use software PWM to drive the fan, as for the heaters. This uses a very low frequency +// which is not as annoying as with the hardware PWM. On the other hand, if this frequency +// is too low, you should also increment SOFT_PWM_SCALE. +//#define FAN_SOFT_PWM + +// Incrementing this by 1 will double the software PWM frequency, +// affecting heaters, and the fan if FAN_SOFT_PWM is enabled. +// However, control resolution will be halved for each increment; +// at zero value, there are 128 effective control positions. +#define SOFT_PWM_SCALE 0 + +// If SOFT_PWM_SCALE is set to a value higher than 0, dithering can +// be used to mitigate the associated resolution loss. If enabled, +// some of the PWM cycles are stretched so on average the desired +// duty cycle is attained. +//#define SOFT_PWM_DITHER + +// Temperature status LEDs that display the hotend and bed temperature. +// If all hotends, bed temperature, and target temperature are under 54C +// then the BLUE led is on. Otherwise the RED led is on. (1C hysteresis) +//#define TEMP_STAT_LEDS + +// M240 Triggers a camera by emulating a Canon RC-1 Remote +// Data from: http://www.doc-diy.net/photo/rc-1_hacked/ +//#define PHOTOGRAPH_PIN 23 + +// 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 + +// Support for BlinkM/CyzRgb +//#define BLINKM + +// Support for PCA9632 PWM LED driver +//#define PCA9632 + +/** + * RGB LED / LED Strip Control + * + * Enable support for an RGB LED connected to 5V digital pins, or + * an RGB Strip connected to MOSFETs controlled by digital pins. + * + * 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 overall brightness parameters is also available + * + * *** CAUTION *** + * LED Strips require a MOFSET 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! + * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino + * cannot handle such current, separate 5V power supply must be used + * *** CAUTION *** + * + * LED type. This options are mutualy exclusive. Uncomment only one. + * + */ +//#define RGB_LED +//#define RGBW_LED + +#if ENABLED(RGB_LED) || ENABLED(RGBW_LED) + #define RGB_LED_R_PIN 34 + #define RGB_LED_G_PIN 43 + #define RGB_LED_B_PIN 35 + #define RGB_LED_W_PIN -1 +#endif + +// 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 (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) + #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip + #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time + #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + //#define NEOPIXEL_STARTUP_TEST // Cycle through colors at startup +#endif + +/** + * Printer Event LEDs + * + * During printing, the LEDs will reflect the printer status: + * + * - Gradually change from blue to violet as the heated bed gets to target temp + * - Gradually change from violet to red as the hotend gets to temperature + * - Change to white to illuminate work surface + * - Change to green once print has finished + * - Turn off after the print has finished and the user has pushed a button + */ +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) + #define PRINTER_EVENT_LEDS +#endif + +/*********************************************************************\ +* R/C SERVO support +* Sponsored by TrinityLabs, Reworked by codexmas +**********************************************************************/ + +// Number of servos +// +// If you select a configuration below, this will receive a default value and does not need to be set manually +// set it manually if you have more servos than extruders and wish to manually control some +// leaving it undefined or defining as 0 will disable the servo subsystem +// If unsure, leave commented / disabled +// +//#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command + +// Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. +// 300ms is a good value but you can try less delay. +// If the servo can't reach the requested position, increase it. +#define SERVO_DELAY { 300 } + +// Servo deactivation +// +// With this option servos are powered only during movement, then turned off to prevent jitter. +//#define DEACTIVATE_SERVOS_AFTER_MOVE + +/** + * Filament Width Sensor + * + * Measures the filament width in real-time and adjusts + * flow rate to compensate for any irregularities. + * + * Also allows the measured filament diameter to set the + * extrusion rate, so the slicer only has to specify the + * volume. + * + * Only a single extruder is supported at this time. + * + * 34 RAMPS_14 : Analog input 5 on the AUX2 connector + * 81 PRINTRBOARD : Analog input 2 on the Exp1 connector (version B,C,D,E) + * 301 RAMBO : Analog input 3 + * + * Note: May require analog pins to be defined for other boards. + */ +//#define FILAMENT_WIDTH_SENSOR + +#define DEFAULT_NOMINAL_FILAMENT_DIA 3.00 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. + +#if ENABLED(FILAMENT_WIDTH_SENSOR) + #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) + #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber + + #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading + #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading + #define MAX_MEASUREMENT_DELAY 20 // (bytes) Buffer size for stored measurements (1 byte per cm). Must be larger than MEASUREMENT_DELAY_CM. + + #define DEFAULT_MEASURED_FILAMENT_DIA DEFAULT_NOMINAL_FILAMENT_DIA // Set measured to nominal initially + + // Display filament width on the LCD status line. Status messages will expire after 5 seconds. + //#define FILAMENT_LCD_DISPLAY +#endif + +#endif // CONFIGURATION_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/SCARA/Configuration_adv.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/SCARA/Configuration_adv.h new file mode 100644 index 00000000..0a92aeeb --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/SCARA/Configuration_adv.h @@ -0,0 +1,1424 @@ +/** + * 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 . + * + */ + +/** + * Configuration_adv.h + * + * Advanced settings. + * Only change these if you know exactly what you're doing. + * Some of these settings can damage your printer if improperly set! + * + * Basic settings can be found in Configuration.h + * + */ +#ifndef CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H_VERSION 010100 + +// @section temperature + +//=========================================================================== +//=============================Thermal Settings ============================ +//=========================================================================== + +#if DISABLED(PIDTEMPBED) + #define BED_CHECK_INTERVAL 3000 // 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 + #endif +#endif + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * The solution: Once the temperature reaches the target, start observing. + * If the temperature stays too far below the target (hysteresis) for too long (period), + * the firmware will halt the machine as a safety precaution. + * + * If you get false positives for "Thermal Runaway" increase THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD + */ +#if ENABLED(THERMAL_PROTECTION_HOTENDS) + #define THERMAL_PROTECTION_PERIOD 40 // Seconds + #define THERMAL_PROTECTION_HYSTERESIS 4 // Degrees Celsius + + /** + * Whenever an M104 or M109 increases the target temperature the firmware will wait for the + * WATCH_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get false positives for "Heating failed" increase WATCH_TEMP_PERIOD and/or decrease WATCH_TEMP_INCREASE + * WATCH_TEMP_INCREASE should not be below 2. + */ + #define WATCH_TEMP_PERIOD 20 // Seconds + #define WATCH_TEMP_INCREASE 2 // Degrees Celsius +#endif + +/** + * Thermal Protection parameters for the bed are just as above for hotends. + */ +#if ENABLED(THERMAL_PROTECTION_BED) + #define THERMAL_PROTECTION_BED_PERIOD 20 // Seconds + #define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius + + /** + * Whenever an M140 or M190 increases the target temperature the firmware will wait for the + * WATCH_BED_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_BED_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get too many "Heating failed" errors, increase WATCH_BED_TEMP_PERIOD and/or decrease + * WATCH_BED_TEMP_INCREASE. (WATCH_BED_TEMP_INCREASE should not be below 2.) + */ + #define WATCH_BED_TEMP_PERIOD 60 // Seconds + #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius +#endif + +#if ENABLED(PIDTEMP) + // this adds an experimental additional term to the heating power, proportional to the extrusion speed. + // if Kc is chosen well, the additional required power due to increased melting should be compensated. + //#define PID_EXTRUSION_SCALING + #if ENABLED(PID_EXTRUSION_SCALING) + #define DEFAULT_Kc (100) //heating power=Kc*(e_speed) + #define LPQ_MAX_LEN 50 + #endif +#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 + */ +#define AUTOTEMP +#if ENABLED(AUTOTEMP) + #define AUTOTEMP_OLDWEIGHT 0.98 +#endif + +// Show Temperature ADC value +// Enable for M105 to include ADC values read from temperature sensors. +//#define SHOW_TEMP_ADC_VALUES + +/** + * High Temperature Thermistor Support + * + * Thermistors able to support high temperature tend to have a hard time getting + * good readings at room and lower temperatures. This means HEATER_X_RAW_LO_TEMP + * will probably be caught when the heating element first turns on during the + * preheating process, which will trigger a min_temp_error as a safety measure + * and force stop everything. + * To circumvent this limitation, we allow for a preheat time (during which, + * min_temp_error won't be triggered) and add a min_temp buffer to handle + * aberrant readings. + * + * If you want to enable this feature for your hotend thermistor(s) + * uncomment and set values > 0 in the constants below + */ + +// The number of consecutive low temperature errors that can occur +// before a min_temp_error is triggered. (Shouldn't be more than 10.) +//#define MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED 0 + +// The number of milliseconds a hotend will preheat before starting to check +// the temperature. This value should NOT be set to the time it takes the +// hot end to reach the target temperature, but the time it takes to reach +// the minimum temperature your thermistor can read. The lower the better/safer. +// This shouldn't need to be more than 30 seconds (30000) +//#define MILLISECONDS_PREHEAT_TIME 0 + +// @section extruder + +// Extruder runout prevention. +// If the machine is idle and the temperature over MINTEMP +// then extrude some filament every couple of SECONDS. +//#define EXTRUDER_RUNOUT_PREVENT +#if ENABLED(EXTRUDER_RUNOUT_PREVENT) + #define EXTRUDER_RUNOUT_MINTEMP 190 + #define EXTRUDER_RUNOUT_SECONDS 30 + #define EXTRUDER_RUNOUT_SPEED 180 // mm/m + #define EXTRUDER_RUNOUT_EXTRUDE 5 // mm +#endif + +// @section temperature + +//These defines help to calibrate the AD595 sensor in case you get wrong temperature measurements. +//The measured temperature is defined as "actualTemp = (measuredTemp * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET" +#define TEMP_SENSOR_AD595_OFFSET 0.0 +#define TEMP_SENSOR_AD595_GAIN 1.0 + +/** + * 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. + */ +//#define USE_CONTROLLER_FAN +#if ENABLED(USE_CONTROLLER_FAN) + //#define CONTROLLER_FAN_PIN FAN1_PIN // 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 +#endif + +// When first starting the main fan, run it at full speed for the +// given number of milliseconds. This gets the fan spinning reliably +// before setting a PWM value. (Does not work with software PWM for fan on Sanguinololu) +//#define FAN_KICKSTART_TIME 100 + +// This defines the minimal speed for the main fan, run in PWM mode +// to enable uncomment and set minimal PWM speed for reliable running (1-255) +// if fan speed is [1 - (FAN_MIN_PWM-1)] it is set to FAN_MIN_PWM +//#define FAN_MIN_PWM 50 + +// @section extruder + +/** + * Extruder cooling fans + * + * Extruder auto fans automatically turn on when their extruders' + * temperatures go above EXTRUDER_AUTO_FAN_TEMPERATURE. + * + * Your board's pins file specifies the recommended pins. Override those here + * or set to -1 to disable completely. + * + * Multiple extruders can be assigned to the same pin in which case + * the fan will turn on when any selected extruder is above the threshold. + */ +#define E0_AUTO_FAN_PIN -1 +#define E1_AUTO_FAN_PIN -1 +#define E2_AUTO_FAN_PIN -1 +#define E3_AUTO_FAN_PIN -1 +#define E4_AUTO_FAN_PIN -1 +#define EXTRUDER_AUTO_FAN_TEMPERATURE 50 +#define EXTRUDER_AUTO_FAN_SPEED 255 // == full speed + +/** + * Part-Cooling Fan Multiplexer + * + * This feature allows you to digitally multiplex the fan output. + * The multiplexer is automatically switched at tool-change. + * Set FANMUX[012]_PINs below for up to 2, 4, or 8 multiplexed fans. + */ +#define FANMUX0_PIN -1 +#define FANMUX1_PIN -1 +#define FANMUX2_PIN -1 + +/** + * M355 Case Light on-off / brightness + */ +//#define CASE_LIGHT_ENABLE +#if ENABLED(CASE_LIGHT_ENABLE) + //#define CASE_LIGHT_PIN 4 // Override the default pin if needed + #define INVERT_CASE_LIGHT false // Set true if Case Light is ON when pin is LOW + #define CASE_LIGHT_DEFAULT_ON true // Set default power-up state on + #define CASE_LIGHT_DEFAULT_BRIGHTNESS 105 // Set default power-up brightness (0-255, requires PWM pin) + //#define MENU_ITEM_CASE_LIGHT // Add a Case Light option to the LCD main menu +#endif + +//=========================================================================== +//============================ Mechanical Settings ========================== +//=========================================================================== + +// @section homing + +// If you want endstops to stay on (by default) even when not homing +// enable this option. Override at any time with M120, M121. +//#define ENDSTOPS_ALWAYS_ON_DEFAULT + +// @section extras + +//#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. + +// Dual X Steppers +// Uncomment this option to drive two X axis motors. +// The next unused E driver will be assigned to the second X stepper. +//#define X_DUAL_STEPPER_DRIVERS +#if ENABLED(X_DUAL_STEPPER_DRIVERS) + // Set true if the two X motors need to rotate in opposite directions + #define INVERT_X2_VS_X_DIR true +#endif + +// Dual Y Steppers +// Uncomment this option to drive two Y axis motors. +// The next unused E driver will be assigned to the second Y stepper. +//#define Y_DUAL_STEPPER_DRIVERS +#if ENABLED(Y_DUAL_STEPPER_DRIVERS) + // Set true if the two Y motors need to rotate in opposite directions + #define INVERT_Y2_VS_Y_DIR true +#endif + +// A single Z stepper driver is usually used to drive 2 stepper motors. +// Uncomment this option to use a separate stepper driver for each Z axis motor. +// The next unused E driver will be assigned to the second Z stepper. +//#define Z_DUAL_STEPPER_DRIVERS + +#if ENABLED(Z_DUAL_STEPPER_DRIVERS) + + // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper. + // That way the machine is capable to align the bed during home, since both Z steppers are homed. + // There is also an implementation of M666 (software endstops adjustment) to this feature. + // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed. + // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2. + // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive. + // Play a little bit with small adjustments (0.5mm) and check the behaviour. + // The M119 (endstops report) will start reporting the Z2 Endstop as well. + + //#define Z_DUAL_ENDSTOPS + + #if ENABLED(Z_DUAL_ENDSTOPS) + #define Z2_USE_ENDSTOP _XMAX_ + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 // Use M666 to determine/test this value + #endif + +#endif // Z_DUAL_STEPPER_DRIVERS + +// Enable this for dual x-carriage printers. +// A dual x-carriage design has the advantage that the inactive extruder can be parked which +// prevents hot-end ooze contaminating the print. It also reduces the weight of each x-carriage +// allowing faster printing speeds. Connect your X2 stepper to the first unused E plug. +//#define DUAL_X_CARRIAGE +#if ENABLED(DUAL_X_CARRIAGE) + // Configuration for second X-carriage + // Note: the first x-carriage is defined as the x-carriage which homes to the minimum endstop; + // the second x-carriage always homes to the maximum endstop. + #define X2_MIN_POS 80 // set minimum to ensure second x-carriage doesn't hit the parked first X-carriage + #define X2_MAX_POS 353 // set maximum to the distance between toolheads when both heads are homed + #define X2_HOME_DIR 1 // the second X-carriage always homes to the maximum endstop position + #define X2_HOME_POS X2_MAX_POS // default home position is the maximum carriage position + // However: In this mode the HOTEND_OFFSET_X value for the second extruder provides a software + // override for X2_HOME_POS. This also allow recalibration of the distance between the two endstops + // without modifying the firmware (through the "M218 T1 X???" command). + // Remember: you should set the second extruder x-offset to 0 in your slicer. + + // There are a few selectable movement modes for dual x-carriages using M605 S + // Mode 0 (DXC_FULL_CONTROL_MODE): Full control. The slicer has full control over both x-carriages and can achieve optimal travel results + // as long as it supports dual x-carriages. (M605 S0) + // Mode 1 (DXC_AUTO_PARK_MODE) : Auto-park mode. The firmware will automatically park and unpark the x-carriages on tool changes so + // that additional slicer support is not required. (M605 S1) + // Mode 2 (DXC_DUPLICATION_MODE) : Duplication mode. The firmware will transparently make the second x-carriage and extruder copy all + // actions of the first x-carriage. This allows the printer to print 2 arbitrary items at + // once. (2nd extruder x offset and temp offset are set using: M605 S2 [Xnnn] [Rmmm]) + + // This is the default power-up mode which can be later using M605. + #define DEFAULT_DUAL_X_CARRIAGE_MODE DXC_FULL_CONTROL_MODE + + // Default settings in "Auto-park Mode" + #define TOOLCHANGE_PARK_ZLIFT 0.2 // the distance to raise Z axis when parking an extruder + #define TOOLCHANGE_UNPARK_ZLIFT 1 // the distance to raise Z axis when unparking an extruder + + // Default x offset in duplication mode (typically set to half print bed width) + #define DEFAULT_DUPLICATION_X_OFFSET 100 + +#endif // DUAL_X_CARRIAGE + +// 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. +//#define EXT_SOLENOID + +// @section homing + +//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +#define X_HOME_BUMP_MM 3 +#define Y_HOME_BUMP_MM 3 +#define Z_HOME_BUMP_MM 3 +#define HOMING_BUMP_DIVISOR {2, 2, 4} // Re-Bump Speed Divisor (Divides the Homing Feedrate) +//#define QUICK_HOME //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially. + +// When G28 is called, this option will make Y home before X +//#define HOME_Y_BEFORE_X + +// @section machine + +#define AXIS_RELATIVE_MODES {false, false, false, false} + +// Allow duplication mode with a basic dual-nozzle extruder +//#define DUAL_NOZZLE_DUPLICATION_MODE + +// By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step. +#define INVERT_X_STEP_PIN false +#define INVERT_Y_STEP_PIN false +#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. +#define DEFAULT_STEPPER_DEACTIVE_TIME 240 +#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_E true + +#define DEFAULT_MINIMUMFEEDRATE 0.0 // minimum feedrate +#define DEFAULT_MINTRAVELFEEDRATE 0.0 + +//#define HOME_AFTER_DEACTIVATE // Require rehoming after steppers are deactivated + +// @section lcd + +#if ENABLED(ULTIPANEL) + #define MANUAL_FEEDRATE {50*60, 50*60, 10*60, 60} // Feedrates for manual moves along X, Y, Z, E from panel + #define ULTIPANEL_FEEDMULTIPLY // Comment to disable setting feedrate multiplier via encoder +#endif + +// @section extras + +// minimum time in microseconds that a movement needs to take if the buffer is emptied. +#define DEFAULT_MINSEGMENTTIME 20000 + +// If defined the movements slow down when the look ahead buffer is only half full +//#define SLOWDOWN + +// Frequency limit +// See nophead's blog for more info +// Not working O +//#define XY_FREQUENCY_LIMIT 15 + +// 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 +// if unwanted behavior is observed on a user's machine when running at very slow speeds. +#define MINIMUM_PLANNER_SPEED 0.05 // (mm/sec) + +// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU. +#define MICROSTEP_MODES {16,16,16,16,16} // [1,2,4,8,16] + +/** + * @section stepper motor current + * + * Some boards have a means of setting the stepper motor current via firmware. + * + * The power on motor currents are set by: + * PWM_MOTOR_CURRENT - used by MINIRAMBO & ULTIMAIN_2 + * known compatible chips: A4982 + * DIGIPOT_MOTOR_CURRENT - used by BQ_ZUM_MEGA_3D, RAMBO & SCOOVO_X9H + * known compatible chips: AD5206 + * DAC_MOTOR_CURRENT_DEFAULT - used by PRINTRBOARD_REVF & RIGIDBOARD_V2 + * known compatible chips: MCP4728 + * DIGIPOT_I2C_MOTOR_CURRENTS - used by 5DPRINT, AZTEEG_X3_PRO, MIGHTYBOARD_REVE + * known compatible chips: MCP4451, MCP4018 + * + * Motor currents can also be set by M907 - M910 and by the LCD. + * M907 - applies to all. + * M908 - BQ_ZUM_MEGA_3D, RAMBO, PRINTRBOARD_REVF, RIGIDBOARD_V2 & SCOOVO_X9H + * M909, M910 & LCD - only PRINTRBOARD_REVF & RIGIDBOARD_V2 + */ +//#define PWM_MOTOR_CURRENT { 1300, 1300, 1250 } // Values in milliamps +//#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 + +// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +//#define DIGIPOT_I2C +//#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster +#define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 +// Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS +#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=========================== +//=========================================================================== + +#define ENCODER_RATE_MULTIPLIER // If defined, certain menu edit operations automatically multiply the steps when the encoder is moved quickly +#define ENCODER_10X_STEPS_PER_SEC 75 // If the encoder steps per sec exceeds this value, multiply steps moved x10 to quickly advance the value +#define ENCODER_100X_STEPS_PER_SEC 160 // If the encoder steps per sec exceeds this value, multiply steps moved x100 to really quickly advance the value + +//#define CHDK 4 //Pin for triggering CHDK to take a picture see how to use it here http://captain-slow.dk/2014/03/09/3d-printing-timelapses/ +#define CHDK_DELAY 50 //How long in ms the pin should stay HIGH before going LOW again + +// @section lcd + +// Include a page of printer information in the LCD Main Menu +//#define LCD_INFO_MENU + +// Scroll a longer status message into view +//#define STATUS_MESSAGE_SCROLLING + +// On the Info Screen, display XY with one decimal place when possible +//#define LCD_DECIMAL_SMALL_XY + +// The timeout (in ms) to return to the status screen from sub-menus +//#define LCD_TIMEOUT_TO_STATUS 15000 + +#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 + + #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? + #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. + + #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. + // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. + // using: + //#define MENU_ADDAUTOSTART + + /** + * Sort SD file listings in alphabetical order. + * + * With this option enabled, items on SD cards will be sorted + * by name for easier navigation. + * + * By default... + * + * - Use the slowest -but safest- method for sorting. + * - Folders are sorted to the top. + * - The sort key is statically allocated. + * - No added G-code (M34) support. + * - 40 item sorting limit. (Items after the first 40 are unsorted.) + * + * SD sorting uses static allocation (as set by SDSORT_LIMIT), allowing the + * compiler to calculate the worst-case usage and throw an error if the SRAM + * limit is exceeded. + * + * - SDSORT_USES_RAM provides faster sorting via a static directory buffer. + * - SDSORT_USES_STACK does the same, but uses a local stack-based buffer. + * - SDSORT_CACHE_NAMES will retain the sorted file listing in RAM. (Expensive!) + * - SDSORT_DYNAMIC_RAM only uses RAM when the SD menu is visible. (Use with caution!) + */ + //#define SDCARD_SORT_ALPHA + + // SD Card Sorting options + #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_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. + #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #endif + + // Show a progress bar on HD44780 LCDs for SD printing + //#define LCD_PROGRESS_BAR + + #if ENABLED(LCD_PROGRESS_BAR) + // Amount of time (ms) to show the bar + #define PROGRESS_BAR_BAR_TIME 2000 + // Amount of time (ms) to show the status message + #define PROGRESS_BAR_MSG_TIME 3000 + // Amount of time (ms) to retain the status message (0=forever) + #define PROGRESS_MSG_EXPIRE 0 + // Enable this to show messages for MSG_TIME then hide them + //#define PROGRESS_MSG_ONCE + // Add a menu item to test the progress bar: + //#define LCD_PROGRESS_BAR_TEST + #endif + + // This allows hosts to request long names for files and folders with M33 + //#define LONG_FILENAME_HOST_SUPPORT + + // This option allows you to abort SD printing when any endstop is triggered. + // This feature must be enabled with "M540 S1" or from the LCD menu. + // To have any effect, endstops must be enabled during SD printing. + //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + +#endif // SDSUPPORT + +/** + * Additional options for Graphical Displays + * + * Use the optimizations here to improve printing performance, + * which can be adversely affected by graphical display drawing, + * especially when doing several short moves, and when printing + * on DELTA and SCARA machines. + * + * Some of these options may result in the display lagging behind + * controller events, as there is a trade-off between reliable + * printing performance versus fast display updates. + */ +#if ENABLED(DOGLCD) + // Enable to save many cycles by drawing a hollow frame on the Info Screen + #define XYZ_HOLLOW_FRAME + + // Enable to save many cycles by drawing a hollow frame on Menu Screens + #define MENU_HOLLOW_FRAME + + // A bigger font is available for edit items. Costs 3120 bytes of PROGMEM. + // 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. + // 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 +#endif // DOGLCD + +// @section safety + +// The hardware watchdog should reset the microcontroller disabling all outputs, +// in case the firmware gets stuck and doesn't do temperature regulation. +#define USE_WATCHDOG + +#if ENABLED(USE_WATCHDOG) + // If you have a watchdog reboot in an ArduinoMega2560 then the device will hang forever, as a watchdog reset will leave the watchdog on. + // The "WATCHDOG_RESET_MANUAL" goes around this by not using the hardware reset. + // However, THIS FEATURE IS UNSAFE!, as it will only work if interrupts are disabled. And the code could hang in an interrupt routine with interrupts disabled. + //#define WATCHDOG_RESET_MANUAL +#endif + +// @section lcd + +/** + * Babystepping enables movement of the axes by tiny increments without changing + * the current position values. This feature is used primarily to adjust the Z + * axis in the first layer of a print in real-time. + * + * Warning: Does not respect endstops! + */ +//#define BABYSTEPPING +#if ENABLED(BABYSTEPPING) + //#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 100 // Babysteps are very small. Increase for faster motion. + //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping + //#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen 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_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor + //#define BABYSTEP_ZPROBE_GFX_REVERSE // Reverses the direction of the CW/CCW indicators +#endif + +// @section extruder + +/** + * Implementation of linear pressure control + * + * Assumption: advance = k * (delta velocity) + * K=0 means advance disabled. + * See Marlin documentation for calibration instructions. + */ +//#define LIN_ADVANCE + +#if ENABLED(LIN_ADVANCE) + #define LIN_ADVANCE_K 75 + + /** + * Some Slicers produce Gcode with randomly jumping extrusion widths occasionally. + * For example within a 0.4mm perimeter it may produce a single segment of 0.05mm width. + * While this is harmless for normal printing (the fluid nature of the filament will + * close this very, very tiny gap), it throws off the LIN_ADVANCE pressure adaption. + * + * For this case LIN_ADVANCE_E_D_RATIO can be used to set the extrusion:distance ratio + * to a fixed value. Note that using a fixed ratio will lead to wrong nozzle pressures + * if the slicer is using variable widths or layer heights within one print! + * + * This option sets the default E:D ratio at startup. Use `M900` to override this value. + * + * Example: `M900 W0.4 H0.2 D1.75`, where: + * - W is the extrusion width in mm + * - H is the layer height in mm + * - D is the filament diameter in mm + * + * Example: `M900 R0.0458` to set the ratio directly. + * + * Set to 0 to auto-detect the ratio based on given Gcode G1 print moves. + * + * Slic3r (including Průša Control) produces Gcode compatible with the automatic mode. + * Cura (as of this writing) may produce Gcode incompatible with the automatic mode. + */ + #define LIN_ADVANCE_E_D_RATIO 0 // The calculated ratio (or 0) according to the formula W * H / ((D / 2) ^ 2 * PI) + // Example: 0.4 * 0.2 / ((1.75 / 2) ^ 2 * PI) = 0.033260135 +#endif + +// @section leveling + +// Default mesh area is an area with an inset margin on the print area. +// Below are the macros that are used to define the borders for the mesh area, +// made available here for specialized needs, ie dual extruder setup. +#if ENABLED(MESH_BED_LEVELING) + #define MESH_MIN_X MESH_INSET + #define MESH_MAX_X (X_BED_SIZE - (MESH_INSET)) + #define MESH_MIN_Y MESH_INSET + #define MESH_MAX_Y (Y_BED_SIZE - (MESH_INSET)) +#elif ENABLED(AUTO_BED_LEVELING_UBL) + #define UBL_MESH_MIN_X UBL_MESH_INSET + #define UBL_MESH_MAX_X (X_BED_SIZE - (UBL_MESH_INSET)) + #define UBL_MESH_MIN_Y UBL_MESH_INSET + #define UBL_MESH_MAX_Y (Y_BED_SIZE - (UBL_MESH_INSET)) + + // If this is defined, the currently active mesh will be saved in the + // current slot on M500. + #define UBL_SAVE_ACTIVE_ON_M500 +#endif + +// @section extras + +// +// G2/G3 Arc Support +// +#define ARC_SUPPORT // Disable this feature to save ~3226 bytes +#if ENABLED(ARC_SUPPORT) + #define MM_PER_ARC_SEGMENT 1 // Length of each arc segment + #define N_ARC_CORRECTION 25 // Number of intertpolated 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 +#endif + +// Support for G5 with XYZE destination and IJPQ offsets. Requires ~2666 bytes. +//#define BEZIER_CURVE_SUPPORT + +// G38.2 and G38.3 Probe Target +// Enable PROBE_DOUBLE_TOUCH if you want G38 to double touch +//#define G38_PROBE_TARGET +#if ENABLED(G38_PROBE_TARGET) + #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) +#endif + +// Moves (or segments) with fewer steps than this will be joined with the next move +#define MIN_STEPS_PER_SEGMENT 6 + +// The minimum pulse width (in µs) for stepping a stepper. +// Set this if you find stepping unreliable, or if using a very fast CPU. +#define MINIMUM_STEPPER_PULSE 0 // (µs) The smallest stepper pulse allowed + +// @section temperature + +// Control heater 0 and heater 1 in parallel. +//#define HEATERS_PARALLEL + +//=========================================================================== +//================================= Buffers ================================= +//=========================================================================== + +// @section hidden + +// 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, i.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 +#else + #define BLOCK_BUFFER_SIZE 16 // maximize block buffer +#endif + +// @section serial + +// The ASCII buffer for serial input +#define MAX_CMD_SIZE 96 +#define BUFSIZE 4 + +// Transmission to Host Buffer Size +// To save 386 bytes of PROGMEM (and TX_BUFFER_SIZE+3 bytes of RAM) set to 0. +// To buffer a simple "ok" you need 4 bytes. +// For ADVANCED_OK (M105) you need 32 bytes. +// For debug-echo: 128 bytes for the optimal speed. +// Other output doesn't need to be that speedy. +// :[0, 2, 4, 8, 16, 32, 64, 128, 256] +#define TX_BUFFER_SIZE 0 + +// Host Receive Buffer Size +// Without XON/XOFF flow control (see SERIAL_XON_XOFF below) 32 bytes should be enough. +// To use flow control, set this buffer size to at least 1024 bytes. +// :[0, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048] +//#define RX_BUFFER_SIZE 1024 + +#if RX_BUFFER_SIZE >= 1024 + // Enable to have the controller send XON/XOFF control characters to + // the host to signal the RX buffer is becoming full. + //#define SERIAL_XON_XOFF +#endif + +#if ENABLED(SDSUPPORT) + // Enable this option to collect and display the maximum + // RX queue usage after transferring a file to SD. + //#define SERIAL_STATS_MAX_RX_QUEUED + + // Enable this option to collect and display the number + // of dropped bytes after a file transfer to SD. + //#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! +//#define EMERGENCY_PARSER + +// Bad Serial-connections can miss a received command by sending an 'ok' +// Therefore some clients abort after 30 seconds in a timeout. +// Some other clients start sending commands while receiving a 'wait'. +// This "wait" is only sent when the buffer is empty. 1 second is a good value here. +//#define NO_TIMEOUTS 1000 // Milliseconds + +// Some clients will have this feature soon. This could make the NO_TIMEOUTS unnecessary. +//#define ADVANCED_OK + +// @section extras + +/** + * Firmware-based and LCD-controlled retract + * + * Add G10 / G11 commands for automatic firmware-based retract / recover. + * Use M207 and M208 to define parameters for retract / recover. + * + * Use M209 to enable or disable auto-retract. + * With auto-retract enabled, all G1 E moves within the set range + * will be converted to firmware-based retract/recover moves. + * + * Be sure to turn off auto-retract during filament change. + * + * Note that M207 / M208 / M209 settings are saved to EEPROM. + * + */ +//#define FWRETRACT // ONLY PARTIALLY TESTED +#if ENABLED(FWRETRACT) + #define MIN_AUTORETRACT 0.1 // When auto-retract is on, convert E moves of this length and over + #define MAX_AUTORETRACT 10.0 // Upper limit for auto-retract conversion + #define RETRACT_LENGTH 3 // Default retract length (positive mm) + #define RETRACT_LENGTH_SWAP 13 // Default swap retract length (positive mm), for extruder change + #define RETRACT_FEEDRATE 35 // Default feedrate for retracting (mm/s) + #define RETRACT_ZLIFT 0 // Default retract Z-lift + #define RETRACT_RECOVER_LENGTH 0 // Default additional recover length (mm, added to retract length when recovering) + #define RETRACT_RECOVER_LENGTH_SWAP 0 // Default additional swap recover length (mm, added to retract length when recovering from extruder change) + #define RETRACT_RECOVER_FEEDRATE 8 // Default feedrate for recovering from retraction (mm/s) + #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) +#endif + +/** + * Advanced Pause + * Experimental feature for filament change support and for parking the nozzle when paused. + * Adds the GCode M600 for initiating filament change. + * If PARK_HEAD_ON_PAUSE enabled, adds the GCode M125 to pause printing and park the nozzle. + * + * Requires an LCD display. + * This feature is required for the default FILAMENT_RUNOUT_SCRIPT. + */ +//#define ADVANCED_PAUSE_FEATURE +#if ENABLED(ADVANCED_PAUSE_FEATURE) + #define PAUSE_PARK_X_POS 3 // X position of hotend + #define PAUSE_PARK_Y_POS 3 // Y position of hotend + #define PAUSE_PARK_Z_ADD 10 // Z addition of hotend (lift) + #define PAUSE_PARK_XY_FEEDRATE 100 // X and Y axes feedrate in mm/s (also used for delta printers Z axis) + #define PAUSE_PARK_Z_FEEDRATE 5 // Z axis feedrate in mm/s (not used for delta printers) + #define PAUSE_PARK_RETRACT_FEEDRATE 60 // Initial retract feedrate in mm/s + #define PAUSE_PARK_RETRACT_LENGTH 2 // Initial retract in mm + // It is a short retract used immediately after print interrupt before move to filament exchange position + #define FILAMENT_CHANGE_UNLOAD_FEEDRATE 10 // Unload filament feedrate in mm/s - filament unloading can be fast + #define FILAMENT_CHANGE_UNLOAD_LENGTH 100 // Unload filament length from hotend in mm + // Longer length for bowden printers to unload filament from whole bowden tube, + // shorter length for printers without bowden to unload filament from extruder only, + // 0 to disable unloading for manual unloading + #define FILAMENT_CHANGE_LOAD_FEEDRATE 6 // Load filament feedrate in mm/s - filament loading into the bowden tube can be fast + #define FILAMENT_CHANGE_LOAD_LENGTH 0 // Load filament length over hotend in mm + // Longer length for bowden printers to fast load filament into whole bowden tube over the hotend, + // Short or zero length for printers without bowden where loading is not used + #define ADVANCED_PAUSE_EXTRUDE_FEEDRATE 3 // Extrude filament feedrate in mm/s - must be slower than load feedrate + #define ADVANCED_PAUSE_EXTRUDE_LENGTH 50 // Extrude filament length in mm after filament is loaded over the hotend, + // 0 to disable for manual extrusion + // Filament can be extruded repeatedly from the filament exchange menu to fill the hotend, + // or until outcoming filament color is not clear for filament color change + #define PAUSE_PARK_NOZZLE_TIMEOUT 45 // Turn off nozzle if user doesn't change filament within this time limit in seconds + #define FILAMENT_CHANGE_NUMBER_OF_ALERT_BEEPS 5 // Number of alert beeps before printer goes quiet + #define PAUSE_PARK_NO_STEPPER_TIMEOUT // Enable to have stepper motors hold position during filament change + // even if it takes longer than DEFAULT_STEPPER_DEACTIVE_TIME. + //#define PARK_HEAD_ON_PAUSE // Go to filament change position on pause, return to print position on resume + //#define HOME_BEFORE_FILAMENT_CHANGE // Ensure homing has been completed prior to parking for filament change +#endif + +// @section tmc + +/** + * Enable this section if you have TMC26X motor drivers. + * You will need to import the TMC26XStepper library into the Arduino IDE for this + * (https://github.com/trinamic/TMC26XStepper.git) + */ +//#define HAVE_TMCDRIVER + +#if ENABLED(HAVE_TMCDRIVER) + + //#define X_IS_TMC + //#define X2_IS_TMC + //#define Y_IS_TMC + //#define Y2_IS_TMC + //#define Z_IS_TMC + //#define Z2_IS_TMC + //#define E0_IS_TMC + //#define E1_IS_TMC + //#define E2_IS_TMC + //#define E3_IS_TMC + //#define E4_IS_TMC + + #define X_MAX_CURRENT 1000 // in mA + #define X_SENSE_RESISTOR 91 // in mOhms + #define X_MICROSTEPS 16 // number of microsteps + + #define X2_MAX_CURRENT 1000 + #define X2_SENSE_RESISTOR 91 + #define X2_MICROSTEPS 16 + + #define Y_MAX_CURRENT 1000 + #define Y_SENSE_RESISTOR 91 + #define Y_MICROSTEPS 16 + + #define Y2_MAX_CURRENT 1000 + #define Y2_SENSE_RESISTOR 91 + #define Y2_MICROSTEPS 16 + + #define Z_MAX_CURRENT 1000 + #define Z_SENSE_RESISTOR 91 + #define Z_MICROSTEPS 16 + + #define Z2_MAX_CURRENT 1000 + #define Z2_SENSE_RESISTOR 91 + #define Z2_MICROSTEPS 16 + + #define E0_MAX_CURRENT 1000 + #define E0_SENSE_RESISTOR 91 + #define E0_MICROSTEPS 16 + + #define E1_MAX_CURRENT 1000 + #define E1_SENSE_RESISTOR 91 + #define E1_MICROSTEPS 16 + + #define E2_MAX_CURRENT 1000 + #define E2_SENSE_RESISTOR 91 + #define E2_MICROSTEPS 16 + + #define E3_MAX_CURRENT 1000 + #define E3_SENSE_RESISTOR 91 + #define E3_MICROSTEPS 16 + + #define E4_MAX_CURRENT 1000 + #define E4_SENSE_RESISTOR 91 + #define E4_MICROSTEPS 16 + +#endif + +// @section TMC2130 + +/** + * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. + * + * You'll also need the TMC2130Stepper Arduino library + * (https://github.com/teemuatlut/TMC2130Stepper). + * + * To use TMC2130 stepper drivers in SPI mode connect your SPI2130 pins to + * the hardware SPI interface on your board and define the required CS pins + * in your `pins_MYBOARD.h` file. (e.g., RAMPS 1.4 uses AUX3 pins `X_CS_PIN 53`, `Y_CS_PIN 49`, etc.). + */ +//#define HAVE_TMC2130 + +#if ENABLED(HAVE_TMC2130) + + // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY + //#define X_IS_TMC2130 + //#define X2_IS_TMC2130 + //#define Y_IS_TMC2130 + //#define Y2_IS_TMC2130 + //#define Z_IS_TMC2130 + //#define Z2_IS_TMC2130 + //#define E0_IS_TMC2130 + //#define E1_IS_TMC2130 + //#define E2_IS_TMC2130 + //#define E3_IS_TMC2130 + //#define E4_IS_TMC2130 + + /** + * Stepper driver settings + */ + + #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 + #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current + #define INTERPOLATE 1 // Interpolate X/Y/Z_MICROSTEPS to 256 + + #define X_CURRENT 1000 // rms current in mA. Multiply by 1.41 for peak current. + #define X_MICROSTEPS 16 // 0..256 + + #define Y_CURRENT 1000 + #define Y_MICROSTEPS 16 + + #define Z_CURRENT 1000 + #define Z_MICROSTEPS 16 + + //#define X2_CURRENT 1000 + //#define X2_MICROSTEPS 16 + + //#define Y2_CURRENT 1000 + //#define Y2_MICROSTEPS 16 + + //#define Z2_CURRENT 1000 + //#define Z2_MICROSTEPS 16 + + //#define E0_CURRENT 1000 + //#define E0_MICROSTEPS 16 + + //#define E1_CURRENT 1000 + //#define E1_MICROSTEPS 16 + + //#define E2_CURRENT 1000 + //#define E2_MICROSTEPS 16 + + //#define E3_CURRENT 1000 + //#define E3_MICROSTEPS 16 + + //#define E4_CURRENT 1000 + //#define E4_MICROSTEPS 16 + + /** + * Use Trinamic's ultra quiet stepping mode. + * When disabled, Marlin will use spreadCycle stepping mode. + */ + #define STEALTHCHOP + + /** + * Let Marlin automatically control stepper current. + * This is still an experimental feature. + * Increase current every 5s by CURRENT_STEP until stepper temperature prewarn gets triggered, + * then decrease current by CURRENT_STEP until temperature prewarn is cleared. + * Adjusting starts from X/Y/Z/E_CURRENT but will not increase over AUTO_ADJUST_MAX + * 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. + * M906 S1 - Start adjusting current + * M906 S0 - Stop adjusting current + * M911 - Report stepper driver overtemperature pre-warn condition. + * M912 - Clear stepper driver overtemperature pre-warn condition flag. + */ + //#define AUTOMATIC_CURRENT_CONTROL + + #if ENABLED(AUTOMATIC_CURRENT_CONTROL) + #define CURRENT_STEP 50 // [mA] + #define AUTO_ADJUST_MAX 1300 // [mA], 1300mA_rms = 1840mA_peak + #define REPORT_CURRENT_CHANGE + #endif + + /** + * The driver will switch to spreadCycle when stepper speed is over HYBRID_THRESHOLD. + * This mode allows for faster movements at the expense of higher noise levels. + * STEALTHCHOP needs to be enabled. + * M913 X/Y/Z/E to live tune the setting + */ + //#define HYBRID_THRESHOLD + + #define X_HYBRID_THRESHOLD 100 // [mm/s] + #define X2_HYBRID_THRESHOLD 100 + #define Y_HYBRID_THRESHOLD 100 + #define Y2_HYBRID_THRESHOLD 100 + #define Z_HYBRID_THRESHOLD 4 + #define Z2_HYBRID_THRESHOLD 4 + #define E0_HYBRID_THRESHOLD 30 + #define E1_HYBRID_THRESHOLD 30 + #define E2_HYBRID_THRESHOLD 30 + #define E3_HYBRID_THRESHOLD 30 + #define E4_HYBRID_THRESHOLD 30 + + /** + * Use stallGuard2 to sense an obstacle and trigger an endstop. + * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. + * If used along with STEALTHCHOP, the movement will be louder when homing. This is normal. + * + * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. + * Higher values make the system LESS sensitive. + * Lower value make the system MORE sensitive. + * Too low values can lead to false positives, while too high values will collide the axis without triggering. + * It is advised to set X/Y_HOME_BUMP_MM to 0. + * M914 X/Y to live tune the setting + */ + //#define SENSORLESS_HOMING + + #if ENABLED(SENSORLESS_HOMING) + #define X_HOMING_SENSITIVITY 19 + #define Y_HOMING_SENSITIVITY 19 + #endif + + /** + * You can set your own advanced settings by filling in predefined functions. + * A list of available functions can be found on the library github page + * https://github.com/teemuatlut/TMC2130Stepper + * + * Example: + * #define TMC2130_ADV() { \ + * stepperX.diag0_temp_prewarn(1); \ + * stepperX.interpolate(0); \ + * } + */ + #define TMC2130_ADV() { } + +#endif // HAVE_TMC2130 + +// @section L6470 + +/** + * Enable this section if you have L6470 motor drivers. + * You need to import the L6470 library into the Arduino IDE for this. + * (https://github.com/ameyer/Arduino-L6470) + */ + +//#define HAVE_L6470DRIVER +#if ENABLED(HAVE_L6470DRIVER) + + //#define X_IS_L6470 + //#define X2_IS_L6470 + //#define Y_IS_L6470 + //#define Y2_IS_L6470 + //#define Z_IS_L6470 + //#define Z2_IS_L6470 + //#define E0_IS_L6470 + //#define E1_IS_L6470 + //#define E2_IS_L6470 + //#define E3_IS_L6470 + //#define E4_IS_L6470 + + #define X_MICROSTEPS 16 // number of microsteps + #define X_K_VAL 50 // 0 - 255, Higher values, are higher power. Be careful not to go too high + #define X_OVERCURRENT 2000 // maxc current in mA. If the current goes over this value, the driver will switch off + #define X_STALLCURRENT 1500 // current in mA where the driver will detect a stall + + #define X2_MICROSTEPS 16 + #define X2_K_VAL 50 + #define X2_OVERCURRENT 2000 + #define X2_STALLCURRENT 1500 + + #define Y_MICROSTEPS 16 + #define Y_K_VAL 50 + #define Y_OVERCURRENT 2000 + #define Y_STALLCURRENT 1500 + + #define Y2_MICROSTEPS 16 + #define Y2_K_VAL 50 + #define Y2_OVERCURRENT 2000 + #define Y2_STALLCURRENT 1500 + + #define Z_MICROSTEPS 16 + #define Z_K_VAL 50 + #define Z_OVERCURRENT 2000 + #define Z_STALLCURRENT 1500 + + #define Z2_MICROSTEPS 16 + #define Z2_K_VAL 50 + #define Z2_OVERCURRENT 2000 + #define Z2_STALLCURRENT 1500 + + #define E0_MICROSTEPS 16 + #define E0_K_VAL 50 + #define E0_OVERCURRENT 2000 + #define E0_STALLCURRENT 1500 + + #define E1_MICROSTEPS 16 + #define E1_K_VAL 50 + #define E1_OVERCURRENT 2000 + #define E1_STALLCURRENT 1500 + + #define E2_MICROSTEPS 16 + #define E2_K_VAL 50 + #define E2_OVERCURRENT 2000 + #define E2_STALLCURRENT 1500 + + #define E3_MICROSTEPS 16 + #define E3_K_VAL 50 + #define E3_OVERCURRENT 2000 + #define E3_STALLCURRENT 1500 + + #define E4_MICROSTEPS 16 + #define E4_K_VAL 50 + #define E4_OVERCURRENT 2000 + #define E4_STALLCURRENT 1500 + +#endif + +/** + * TWI/I2C BUS + * + * This feature is an EXPERIMENTAL feature so it shall not be used on production + * machines. Enabling this will allow you to send and receive I2C data from slave + * devices on the bus. + * + * ; Example #1 + * ; This macro send the string "Marlin" to the slave device with address 0x63 (99) + * ; It uses multiple M260 commands with one B arg + * M260 A99 ; Target slave address + * M260 B77 ; M + * M260 B97 ; a + * M260 B114 ; r + * M260 B108 ; l + * M260 B105 ; i + * M260 B110 ; n + * M260 S1 ; Send the current buffer + * + * ; Example #2 + * ; Request 6 bytes from slave device with address 0x63 (99) + * M261 A99 B5 + * + * ; Example #3 + * ; Example serial output of a M261 request + * echo:i2c-reply: from:99 bytes:5 data:hello + */ + +// @section i2cbus + +//#define EXPERIMENTAL_I2CBUS +#define I2C_SLAVE_ADDRESS 0 // Set a value from 8 to 127 to act as a slave + +// @section extras + +/** + * Spindle & Laser control + * + * Add the M3, M4, and M5 commands to turn the spindle/laser on and off, and + * to set spindle speed, spindle direction, and laser power. + * + * SuperPid is a router/spindle speed controller used in the CNC milling community. + * Marlin can be used to turn the spindle on and off. It can also be used to set + * the spindle speed from 5,000 to 30,000 RPM. + * + * 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. + */ +//#define SPINDLE_LASER_ENABLE +#if ENABLED(SPINDLE_LASER_ENABLE) + + #define SPINDLE_LASER_ENABLE_INVERT false // set to "true" if the on/off function is reversed + #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 // delay in milliseconds to allow the spindle/laser to come up to speed/power + #define SPINDLE_LASER_POWERDOWN_DELAY 5000 // delay in milliseconds to allow the spindle to stop + #define SPINDLE_DIR_CHANGE true // set to true if your spindle controller supports changing spindle direction + #define SPINDLE_INVERT_DIR false + #define SPINDLE_STOP_ON_DIR_CHANGE true // set to true if Marlin should stop the spindle before changing rotation direction + + /** + * The M3 & M4 commands use the following equation to convert PWM duty cycle to speed/power + * + * SPEED/POWER = PWM duty cycle * SPEED_POWER_SLOPE + SPEED_POWER_INTERCEPT + * where PWM duty cycle varies from 0 to 255 + * + * set the following for your controller (ALL MUST BE SET) + */ + + #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_SLOPE 0.3922 + //#define SPEED_POWER_INTERCEPT 0 + //#define SPEED_POWER_MIN 10 + //#define SPEED_POWER_MAX 100 // 0-100% +#endif + +/** + * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins + */ +//#define PINS_DEBUGGING + +/** + * Auto-report temperatures with M155 S + */ +#define AUTO_REPORT_TEMPERATURES + +/** + * Include capabilities in M115 output + */ +#define EXTENDED_CAPABILITIES_REPORT + +/** + * Volumetric extrusion default state + * 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. + */ +//#define VOLUMETRIC_DEFAULT_ON + +/** + * Enable this option for a leaner build of Marlin that removes all + * workspace offsets, simplifying coordinate transformations, leveling, etc. + * + * - M206 and M428 are disabled. + * - G92 will revert to its behavior from Marlin 1.0. + */ +//#define NO_WORKSPACE_OFFSETS + +/** + * 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. + * + * For clients that use a fixed-width font (like OctoPrint), leave this set to 1.0. + * Otherwise, adjust according to your client and font. + */ +#define PROPORTIONAL_FONT_RATIO 1.0 + +/** + * Spend 28 bytes of SRAM to optimize the GCode parser + */ +#define FASTER_GCODE_PARSER + +/** + * User-defined menu items that execute custom GCode + */ +//#define CUSTOM_USER_MENUS +#if ENABLED(CUSTOM_USER_MENUS) + #define USER_SCRIPT_DONE "M117 User Script Done" + #define USER_SCRIPT_AUDIBLE_FEEDBACK + //#define USER_SCRIPT_RETURN // Return to status screen after a script + + #define USER_DESC_1 "Home & UBL Info" + #define USER_GCODE_1 "G28\nG29 W" + + #define USER_DESC_2 "Preheat for PLA" + #define USER_GCODE_2 "M140 S" STRINGIFY(PREHEAT_1_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND) + + #define USER_DESC_3 "Preheat for ABS" + #define USER_GCODE_3 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND) + + #define USER_DESC_4 "Heat Bed/Home/Level" + #define USER_GCODE_4 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nG28\nG29" + + //#define USER_DESC_5 "Home & Info" + //#define USER_GCODE_5 "G28\nM503" +#endif + +/** + * Specify an action command to send to the host when the printer is killed. + * Will be sent in the form '//action:ACTION_ON_KILL', e.g. '//action:poweroff'. + * The host must be configured to handle the action command. + */ +//#define ACTION_ON_KILL "poweroff" + +//=========================================================================== +//====================== I2C Position Encoder Settings ====================== +//=========================================================================== + +/** + * I2C position encoders for closed loop control. + * Developed by Chris Barr at Aus3D. + * + * Wiki: http://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/ + * + * Reilabuild encoders have been modified to improve reliability. + */ + +//#define I2C_POSITION_ENCODERS +#if ENABLED(I2C_POSITION_ENCODERS) + + #define I2CPE_ENCODER_CNT 1 // The number of encoders installed; max of 5 + // encoders supported currently. + + #define I2CPE_ENC_1_ADDR I2CPE_PRESET_ADDR_X // I2C address of the encoder. 30-200. + #define I2CPE_ENC_1_AXIS X_AXIS // Axis the encoder module is installed on. _AXIS. + #define I2CPE_ENC_1_TYPE I2CPE_ENC_TYPE_LINEAR // Type of encoder: I2CPE_ENC_TYPE_LINEAR -or- + // I2CPE_ENC_TYPE_ROTARY. + #define I2CPE_ENC_1_TICKS_UNIT 2048 // 1024 for magnetic strips with 2mm poles; 2048 for + // 1mm poles. For linear encoders this is ticks / mm, + // for rotary encoders this is ticks / revolution. + //#define I2CPE_ENC_1_TICKS_REV (16 * 200) // Only needed for rotary encoders; number of stepper + // steps per full revolution (motor steps/rev * microstepping) + //#define I2CPE_ENC_1_INVERT // Invert the direction of axis travel. + #define I2CPE_ENC_1_EC_METHOD I2CPE_ECM_NONE // Type of error error correction. + #define I2CPE_ENC_1_EC_THRESH 0.10 // Threshold size for error (in mm) above which the + // printer will attempt to correct the error; errors + // smaller than this are ignored to minimize effects of + // measurement noise / latency (filter). + + #define I2CPE_ENC_2_ADDR I2CPE_PRESET_ADDR_Y // Same as above, but for encoder 2. + #define I2CPE_ENC_2_AXIS Y_AXIS + #define I2CPE_ENC_2_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_ENC_2_TICKS_UNIT 2048 + //#define I2CPE_ENC_2_TICKS_REV (16 * 200) + //#define I2CPE_ENC_2_INVERT + #define I2CPE_ENC_2_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_ENC_2_EC_THRESH 0.10 + + #define I2CPE_ENC_3_ADDR I2CPE_PRESET_ADDR_Z // Encoder 3. Add additional configuration options + #define I2CPE_ENC_3_AXIS Z_AXIS // as above, or use defaults below. + + #define I2CPE_ENC_4_ADDR I2CPE_PRESET_ADDR_E // Encoder 4. + #define I2CPE_ENC_4_AXIS E_AXIS + + #define I2CPE_ENC_5_ADDR 34 // Encoder 5. + #define I2CPE_ENC_5_AXIS E_AXIS + + // Default settings for encoders which are enabled, but without settings configured above. + #define I2CPE_DEF_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_DEF_ENC_TICKS_UNIT 2048 + #define I2CPE_DEF_TICKS_REV (16 * 200) + #define I2CPE_DEF_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_DEF_EC_THRESH 0.1 + + //#define I2CPE_ERR_THRESH_ABORT 100.0 // Threshold size for error (in mm) error on any given + // axis after which the printer will abort. Comment out to + // disable abort behaviour. + + #define I2CPE_TIME_TRUSTED 10000 // After an encoder fault, there must be no further fault + // for this amount of time (in ms) before the encoder + // is trusted again. + + /** + * Position is checked every time a new command is executed from the buffer but during long moves, + * this setting determines the minimum update time between checks. A value of 100 works well with + * error rolling average when attempting to correct only for skips and not for vibration. + */ + #define I2CPE_MIN_UPD_TIME_MS 100 // Minimum time in miliseconds between encoder checks. + + // Use a rolling average to identify persistant errors that indicate skips, as opposed to vibration and noise. + #define I2CPE_ERR_ROLLING_AVERAGE + +#endif // I2C_POSITION_ENCODERS + +/** + * MAX7219 Debug Matrix + * + * Add support for a low-cost 8x8 LED Matrix based on the Max7219 chip, which can be used as a status + * display. Requires 3 signal wires. Some useful debug options are included to demonstrate its usage. + * + * Fully assembled MAX7219 boards can be found on the internet for under $2(US). + * For example, see https://www.ebay.com/sch/i.html?_nkw=332349290049 + */ +//#define MAX7219_DEBUG +#if ENABLED(MAX7219_DEBUG) + #define MAX7219_CLK_PIN 64 // 77 on Re-ARM // Configuration of the 3 pins to control the display + #define MAX7219_DIN_PIN 57 // 78 on Re-ARM + #define MAX7219_LOAD_PIN 44 // 79 on Re-ARM + + /** + * Sample debug features + * If you add more debug displays, be careful to avoid conflicts! + */ + #define MAX7219_DEBUG_PRINTER_ALIVE // Blink corner LED of 8x8 matrix to show that the firmware is functioning + #define MAX7219_DEBUG_STEPPER_HEAD 3 // Show the stepper queue head position on this and the next LED matrix row + #define MAX7219_DEBUG_STEPPER_TAIL 5 // Show the stepper queue tail position on this and the next LED matrix row + + #define MAX7219_DEBUG_STEPPER_QUEUE 0 // Show the current stepper queue depth on this and the next LED matrix row + // If you experience stuttering, reboots, etc. this option can reveal how + // tweaks made to the configuration are affecting the printer in real-time. +#endif + +#endif // CONFIGURATION_ADV_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/Sanguinololu/Configuration.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/Sanguinololu/Configuration.h new file mode 100644 index 00000000..c65c5c3f --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/Sanguinololu/Configuration.h @@ -0,0 +1,1731 @@ +/** + * 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 . + * + */ + +/** + * Configuration.h + * + * Basic settings such as: + * + * - Type of electronics + * - Type of temperature sensor + * - Printer geometry + * - Endstop configuration + * - LCD controller + * - Extra features + * + * Advanced settings can be found in Configuration_adv.h + * + */ +#ifndef CONFIGURATION_H +#define CONFIGURATION_H +#define CONFIGURATION_H_VERSION 010100 + +//=========================================================================== +//============================= Getting Started ============================= +//=========================================================================== + +/** + * Here are some standard links for getting your machine calibrated: + * + * http://reprap.org/wiki/Calibration + * http://youtu.be/wAL9d7FgInk + * http://calculator.josefprusa.cz + * http://reprap.org/wiki/Triffid_Hunter%27s_Calibration_Guide + * http://www.thingiverse.com/thing:5573 + * https://sites.google.com/site/repraplogphase/calibration-of-your-reprap + * http://www.thingiverse.com/thing:298812 + */ + +//=========================================================================== +//============================= DELTA Printer =============================== +//=========================================================================== +// For a Delta printer start with one of the configuration files in the +// example_configurations/delta directory and customize for your machine. +// + +//=========================================================================== +//============================= SCARA Printer =============================== +//=========================================================================== +// For a SCARA printer start with the configuration files in +// example_configurations/SCARA and customize for your machine. +// + +// @section info + +// User-specified version info of this build to display in [Pronterface, etc] terminal window during +// startup. Implementation of an idea by Prof Braino to inform user that any changes made to this +// build by the user have been successfully uploaded into firmware. +#define STRING_CONFIG_H_AUTHOR "(thinkyhead, Sanguinololu)" // Who made the changes. +#define SHOW_BOOTSCREEN +#define STRING_SPLASH_LINE1 SHORT_BUILD_VERSION // will be shown during bootup in line 1 +#define STRING_SPLASH_LINE2 WEBSITE_URL // will be shown during bootup in line 2 + +// +// *** VENDORS PLEASE READ ***************************************************** +// +// Marlin now allow you to have a vendor boot image to be displayed on machine +// start. When SHOW_CUSTOM_BOOTSCREEN is defined Marlin will first show your +// custom boot image and then the default Marlin boot image is shown. +// +// We suggest for you to take advantage of this new feature and keep the Marlin +// boot image unmodified. For an example have a look at the bq Hephestos 2 +// example configuration folder. +// +//#define SHOW_CUSTOM_BOOTSCREEN +// @section machine + +/** + * Select which serial port on the board will be used for communication with the host. + * This allows the connection of wireless adapters (for instance) to non-default port pins. + * Serial port 0 is always used by the Arduino bootloader regardless of this setting. + * + * :[0, 1, 2, 3, 4, 5, 6, 7] + */ +#define SERIAL_PORT 0 + +/** + * This setting determines the communication speed of the printer. + * + * 250000 works in most cases, but you might try a lower speed if + * you commonly experience drop-outs during host printing. + * You may try up to 1000000 to speed up SD file transfer. + * + * :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000] + */ +#define BAUDRATE 115200 + +// Enable the Bluetooth serial interface on AT90USB devices +//#define BLUETOOTH + +// The following define selects which electronics board you have. +// Please choose the name from boards.h that matches your setup +#ifndef MOTHERBOARD + #define MOTHERBOARD BOARD_SANGUINOLOLU_12 +#endif + +// Optional custom name for your RepStrap or other custom machine +// Displayed in the LCD "Ready" message +#define CUSTOM_MACHINE_NAME "Sanguinololu" + +// Define this to set a unique identifier for this printer, (Used by some programs to differentiate between machines) +// You can use an online service to generate a random UUID. (eg http://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] +#define EXTRUDERS 1 + +// For Cyclops or any "multi-extruder" that shares a single nozzle. +//#define SINGLENOZZLE + +/** + * Průša MK2 Single Nozzle Multi-Material Multiplexer, and variants. + * + * This device allows one stepper driver on a control board to drive + * two to eight stepper motors, one at a time, in a manner suitable + * for extruders. + * + * This option only allows the multiplexer to switch on tool-change. + * Additional options to configure custom E moves are pending. + */ +//#define MK2_MULTIPLEXER +#if ENABLED(MK2_MULTIPLEXER) + // Override the default DIO selector pins here, if needed. + // Some pins files may provide defaults for these pins. + //#define E_MUX0_PIN 40 // Always Required + //#define E_MUX1_PIN 42 // Needed for 3 to 8 steppers + //#define E_MUX2_PIN 44 // Needed for 5 to 8 steppers +#endif + +// A dual extruder that uses a single stepper motor +//#define SWITCHING_EXTRUDER +#if ENABLED(SWITCHING_EXTRUDER) + #define SWITCHING_EXTRUDER_SERVO_NR 0 + #define SWITCHING_EXTRUDER_SERVO_ANGLES { 0, 90 } // Angles for E0, E1[, E2, E3] + #if EXTRUDERS > 3 + #define SWITCHING_EXTRUDER_E23_SERVO_NR 1 + #endif +#endif + +// A dual-nozzle that uses a servomotor to raise/lower one of the nozzles +//#define SWITCHING_NOZZLE +#if ENABLED(SWITCHING_NOZZLE) + #define SWITCHING_NOZZLE_SERVO_NR 0 + #define SWITCHING_NOZZLE_SERVO_ANGLES { 0, 90 } // Angles for E0, E1 + //#define HOTEND_OFFSET_Z { 0.0, 0.0 } +#endif + +/** + * Two separate X-carriages with extruders that connect to a moving part + * via a magnetic docking mechanism. Requires SOL1_PIN and SOL2_PIN. + */ +//#define PARKING_EXTRUDER +#if ENABLED(PARKING_EXTRUDER) + #define PARKING_EXTRUDER_SOLENOIDS_INVERT // If enabled, the solenoid is NOT magnetized with applied voltage + #define PARKING_EXTRUDER_SOLENOIDS_PINS_ACTIVE LOW // LOW or HIGH pin signal energizes the coil + #define PARKING_EXTRUDER_SOLENOIDS_DELAY 250 // Delay (ms) for magnetic field. No delay if 0 or not defined. + #define PARKING_EXTRUDER_PARKING_X { -78, 184 } // X positions for parking the extruders + #define PARKING_EXTRUDER_GRAB_DISTANCE 1 // mm to move beyond the parking point to grab the extruder + #define PARKING_EXTRUDER_SECURITY_RAISE 5 // Z-raise before parking + #define HOTEND_OFFSET_Z { 0.0, 1.3 } // Z-offsets of the two hotends. The first must be 0. +#endif + +/** + * "Mixing Extruder" + * - Adds a new code, M165, to set the current mix factors. + * - Extends the stepping routines to move multiple steppers in proportion to the mix. + * - Optional support for Repetier Firmware M163, M164, and virtual extruder. + * - This implementation supports only a single extruder. + * - Enable DIRECT_MIXING_IN_G1 for Pia Taubert's reference implementation + */ +//#define MIXING_EXTRUDER +#if ENABLED(MIXING_EXTRUDER) + #define MIXING_STEPPERS 2 // Number of steppers in your mixing extruder + #define MIXING_VIRTUAL_TOOLS 16 // Use the Virtual Tool method with M163 and M164 + //#define DIRECT_MIXING_IN_G1 // Allow ABCDHI mix factors in G1 movement commands +#endif + +// Offset of the extruders (uncomment if using more than one and relying on firmware to position when changing). +// The offset has to be X=0, Y=0 for the extruder 0 hotend (default extruder). +// For the other hotends it is their distance from the extruder 0 hotend. +//#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis +//#define HOTEND_OFFSET_Y {0.0, 5.00} // (in mm) for each extruder, offset of the hotend on the Y axis + +// @section machine + +/** + * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN + * + * 0 = No Power Switch + * 1 = ATX + * 2 = X-Box 360 203Watts (the blue wire connected to PS_ON and the red wire to VCC) + * + * :{ 0:'No power switch', 1:'ATX', 2:'X-Box 360' } + */ +#define POWER_SUPPLY 0 + +#if POWER_SUPPLY > 0 + // Enable this option to leave the PSU off at startup. + // Power to steppers and heaters will need to be turned on with M80. + //#define PS_DEFAULT_OFF +#endif + +// @section temperature + +//=========================================================================== +//============================= Thermal Settings ============================ +//=========================================================================== + +/** + * --NORMAL IS 4.7kohm PULLUP!-- 1kohm pullup can be used on hotend sensor, using correct resistor and table + * + * Temperature sensors available: + * + * -3 : thermocouple with MAX31855 (only for sensor 0) + * -2 : thermocouple with MAX6675 (only for sensor 0) + * -1 : thermocouple with AD595 + * 0 : not used + * 1 : 100k thermistor - best choice for EPCOS 100k (4.7k pullup) + * 2 : 200k thermistor - ATC Semitec 204GT-2 (4.7k pullup) + * 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 (Used in ParCan & J-Head) (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) + * 71 : 100k Honeywell thermistor 135-104LAF-J01 (4.7k pullup) + * 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) + * 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" + * 20 : the PT100 circuit found in the Ultimainboard V2.x + * 60 : 100k Maker's Tool Works Kapton Bed Thermistor beta=3950 + * 66 : 4.7M High Temperature thermistor from Dyze Design + * 70 : the 100K thermistor found in the bq Hephestos 2 + * 75 : 100k Generic Silicon Heat Pad with NTC 100K MGB18-104F39050L32 thermistor + * + * 1k ohm pullup tables - This is atypical, and requires changing out the 4.7k pullup for 1k. + * (but gives greater accuracy and more stable PID) + * 51 : 100k thermistor - EPCOS (1k pullup) + * 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 + * 1010 : Pt1000 with 1k pullup (non standard) + * 147 : Pt100 with 4k7 pullup + * 110 : Pt100 with 1k pullup (non standard) + * + * Use these for Testing or Development purposes. NEVER for production machine. + * 998 : Dummy Table that ALWAYS reads 25°C or the temperature defined below. + * 999 : Dummy Table that ALWAYS reads 100°C or the temperature defined below. + * + * :{ '0': "Not used", '1':"100k / 4.7k - EPCOS", '2':"200k / 4.7k - ATC Semitec 204GT-2", '3':"Mendel-parts / 4.7k", '4':"10k !! do not use for a hotend. Bad resolution at high temp. !!", '5':"100K / 4.7k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '6':"100k / 4.7k EPCOS - Not as accurate as Table 1", '7':"100k / 4.7k Honeywell 135-104LAG-J01", '8':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT", '9':"100k / 4.7k GE Sensing AL03006-58.2K-97-G1", '10':"100k / 4.7k RS 198-961", '11':"100k / 4.7k beta 3950 1%", '12':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT (calibrated for Makibox hot bed)", '13':"100k Hisens 3950 1% up to 300°C for hotend 'Simple ONE ' & hotend 'All In ONE'", '20':"PT100 (Ultimainboard V2.x)", '51':"100k / 1k - EPCOS", '52':"200k / 1k - ATC Semitec 204GT-2", '55':"100k / 1k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '60':"100k Maker's Tool Works Kapton Bed Thermistor beta=3950", '66':"Dyze Design 4.7M High Temperature thermistor", '70':"the 100K thermistor found in the bq Hephestos 2", '71':"100k / 4.7k Honeywell 135-104LAF-J01", '147':"Pt100 / 4.7k", '1047':"Pt1000 / 4.7k", '110':"Pt100 / 1k (non-standard)", '1010':"Pt1000 / 1k (non standard)", '-3':"Thermocouple + MAX31855 (only for sensor 0)", '-2':"Thermocouple + MAX6675 (only for sensor 0)", '-1':"Thermocouple + AD595",'998':"Dummy 1", '999':"Dummy 2" } + */ +#define TEMP_SENSOR_0 1 +#define TEMP_SENSOR_1 0 +#define TEMP_SENSOR_2 0 +#define TEMP_SENSOR_3 0 +#define TEMP_SENSOR_4 0 +#define TEMP_SENSOR_BED 1 + +// Dummy thermistor constant temperature readings, for use with 998 and 999 +#define DUMMY_THERMISTOR_998_VALUE 25 +#define DUMMY_THERMISTOR_999_VALUE 100 + +// 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 +#define MAX_REDUNDANT_TEMP_SENSOR_DIFF 10 + +// Extruder temperature must be close to target for this long before M109 returns success +#define TEMP_RESIDENCY_TIME 10 // (seconds) +#define TEMP_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// Bed temperature must be close to target for this long before M190 returns success +#define TEMP_BED_RESIDENCY_TIME 10 // (seconds) +#define TEMP_BED_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_BED_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// The minimal temperature defines the temperature below which the heater will not be enabled It is used +// to check that the wiring to the thermistor is not broken. +// Otherwise this would lead to the heater being powered on all the time. +#define HEATER_0_MINTEMP 5 +#define HEATER_1_MINTEMP 5 +#define HEATER_2_MINTEMP 5 +#define HEATER_3_MINTEMP 5 +#define HEATER_4_MINTEMP 5 +#define BED_MINTEMP 5 + +// When temperature exceeds max temp, your heater will be switched off. +// This feature exists to protect your hotend from overheating accidentally, but *NOT* from thermistor short/failure! +// You should use MINTEMP for thermistor short/failure protection. +#define HEATER_0_MAXTEMP 275 +#define HEATER_1_MAXTEMP 275 +#define HEATER_2_MAXTEMP 275 +#define HEATER_3_MAXTEMP 275 +#define HEATER_4_MAXTEMP 275 +#define BED_MAXTEMP 150 + +//=========================================================================== +//============================= PID Settings ================================ +//=========================================================================== +// PID Tuning Guide here: http://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 +#if ENABLED(PIDTEMP) + //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. + //#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. + #define K1 0.95 //smoothing factor within the PID + + // 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 + +#endif // PIDTEMP + +//=========================================================================== +//============================= PID > Bed Temperature Control =============== +//=========================================================================== +// Select PID or bang-bang with PIDTEMPBED. If bang-bang, BED_LIMIT_SWITCHING will enable hysteresis +// +// Uncomment this to enable PID on the bed. It uses the same frequency PWM as the extruder. +// If your PID_dT is the default, and correct for your hardware/configuration, that means 7.689Hz, +// which is fine for driving a square wave into a resistive load and does not significantly impact you FET heating. +// This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W heater. +// If your configuration is significantly different than this and you don't understand the issues involved, you probably +// shouldn't use bed PID until someone else verifies your hardware works. +// If this is enabled, find your own PID constants below. +//#define PIDTEMPBED + +//#define BED_LIMIT_SWITCHING + +// This sets the max power delivered to the bed, and replaces the HEATER_BED_DUTY_CYCLE_DIVIDER option. +// all forms of bed control obey this (PID, bang-bang, bang-bang with hysteresis) +// setting this to anything other than 255 enables a form of PWM to the bed just like HEATER_BED_DUTY_CYCLE_DIVIDER did, +// so you shouldn't use it unless you are OK with PWM on your bed. (see the comment on enabling PIDTEMPBED) +#define MAX_BED_POWER 255 // limits duty cycle to bed; 255=full current + +#if ENABLED(PIDTEMPBED) + + //#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) + #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 + +// @section extruder + +// This option prevents extrusion if the temperature is below EXTRUDE_MINTEMP. +// It also enables the M302 command to set the minimum extrusion temperature +// or to allow moving the extruder regardless of the hotend temperature. +// *** IT IS HIGHLY RECOMMENDED TO LEAVE THIS OPTION ENABLED! *** +#define PREVENT_COLD_EXTRUSION +#define EXTRUDE_MINTEMP 170 + +// This option prevents a single extrusion longer than EXTRUDE_MAXLENGTH. +// Note that for Bowden Extruders a too-small value here may prevent loading. +#define PREVENT_LENGTHY_EXTRUDE +#define EXTRUDE_MAXLENGTH 200 + +//=========================================================================== +//======================== Thermal Runaway Protection ======================= +//=========================================================================== + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * If you get "Thermal Runaway" or "Heating failed" errors the + * details can be tuned in Configuration_adv.h + */ + +#define THERMAL_PROTECTION_HOTENDS // Enable thermal protection for all extruders +#define THERMAL_PROTECTION_BED // Enable thermal protection for the heated bed + +//=========================================================================== +//============================= Mechanical Settings ========================= +//=========================================================================== + +// @section machine + +// Uncomment one of these options to enable CoreXY, CoreXZ, or CoreYZ kinematics +// either in the usual order or reversed +//#define COREXY +//#define COREXZ +//#define COREYZ +//#define COREYX +//#define COREZX +//#define COREZY + +//=========================================================================== +//============================== Endstop Settings =========================== +//=========================================================================== + +// @section homing + +// Specify here all the endstop connectors that are connected to any endstop or probe. +// Almost all printers will be using one per axis. Probes will use one or more of the +// extra connectors. Leave undefined any used for non-endstop and non-probe purposes. +#define USE_XMIN_PLUG +#define USE_YMIN_PLUG +#define USE_ZMIN_PLUG +//#define USE_XMAX_PLUG +//#define USE_YMAX_PLUG +//#define USE_ZMAX_PLUG + +// coarse Endstop Settings +#define ENDSTOPPULLUPS // Comment this out (using // at the start of the line) to disable the endstop pullup resistors + +#if DISABLED(ENDSTOPPULLUPS) + // fine endstop settings: Individual pullups. will be ignored if ENDSTOPPULLUPS is defined + //#define ENDSTOPPULLUP_XMAX + //#define ENDSTOPPULLUP_YMAX + //#define ENDSTOPPULLUP_ZMAX + //#define ENDSTOPPULLUP_XMIN + //#define ENDSTOPPULLUP_YMIN + //#define ENDSTOPPULLUP_ZMIN + //#define ENDSTOPPULLUP_ZMIN_PROBE +#endif + +// Mechanical endstop with COM to ground and NC to Signal uses "false" here (most common setup). +#define X_MIN_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Y_MIN_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MIN_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define X_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Y_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MIN_PROBE_ENDSTOP_INVERTING false // set to true to invert the logic of the probe. + +// Enable this feature if all enabled endstop pins are interrupt-capable. +// This will remove the need to poll the interrupt pins, saving many CPU cycles. +//#define ENDSTOP_INTERRUPTS_FEATURE + +//============================================================================= +//============================== Movement Settings ============================ +//============================================================================= +// @section motion + +/** + * Default Settings + * + * These settings can be reset by M502 + * + * Note that if EEPROM is enabled, saved values will override these. + */ + +// +// Standard NEMA 17 with T2 belt and 20 tooth pulley +// +#define NEMA17_FULL_STEPS 200.0 +#define XY_MICROSTEPS 16.0 +#define E_MICROSTEPS 16.0 +#define Z_MICROSTEPS 16.0 + +#define XY_PULLEY_PITCH 2.0 +#define XY_PULLEY_TEETH 20.0 + +// +// Standard NEMA 17 with fancy 2mm lead screws +// +#define Z_RODS_PITCH 0.5 + +#define XY_MOTOR_STEPS (NEMA17_FULL_STEPS * XY_MICROSTEPS) +#define Z_MOTOR_STEPS (NEMA17_FULL_STEPS * Z_MICROSTEPS) +#define E_MOTOR_STEPS (NEMA17_FULL_STEPS * E_MICROSTEPS) + +// +// MK7 Direct Drive +// +#define MK7_GEAR_DIAM 10.56 +#define MK7_GEAR_CIRC (M_PI * MK7_GEAR_DIAM) +#define E_STEPS (E_MOTOR_STEPS / MK7_GEAR_CIRC) + +// Get steps/mm from selected results above +#define XY_STEPS (XY_MOTOR_STEPS / (XY_PULLEY_PITCH * XY_PULLEY_TEETH)) +#define Z_STEPS (Z_MOTOR_STEPS / Z_RODS_PITCH) + +/** + * With this option each E stepper can have its own factors for the + * following movement settings. If fewer factors are given than the + * total number of extruders, the last value applies to the rest. + */ +//#define DISTINCT_E_FACTORS + +/** + * Default Axis Steps Per Unit (steps/mm) + * Override with M92 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_AXIS_STEPS_PER_UNIT { XY_STEPS, XY_STEPS, Z_STEPS, E_STEPS } + +/** + * Default Max Feed Rate (mm/s) + * Override with M203 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_FEEDRATE { 500, 500, 8, 45 } + +/** + * Default Max Acceleration (change/s) change = mm/s + * (Maximum start speed for accelerated moves) + * Override with M201 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_ACCELERATION { 3000, 3000, 100, 10000 } + +/** + * Default Acceleration (change/s) change = mm/s + * Override with M204 + * + * M204 P Acceleration + * M204 R Retract Acceleration + * M204 T Travel Acceleration + */ +#define DEFAULT_ACCELERATION 3000 // X, Y, Z and E acceleration for printing moves +#define DEFAULT_RETRACT_ACCELERATION 3000 // E acceleration for retracts +#define DEFAULT_TRAVEL_ACCELERATION 3000 // X, Y, Z acceleration for travel (non printing) moves + +/** + * Default Jerk (mm/s) + * Override with M205 X Y Z E + * + * "Jerk" specifies the minimum speed change that requires acceleration. + * When changing speed and direction, if the difference is less than the + * value set here, it may happen instantaneously. + */ +#define DEFAULT_XJERK 10.0 +#define DEFAULT_YJERK 10.0 +#define DEFAULT_ZJERK 0.4 +#define DEFAULT_EJERK 5.0 + +//=========================================================================== +//============================= Z Probe Options ============================= +//=========================================================================== +// @section probes + +// +// See http://marlinfw.org/configuration/probes.html +// + +/** + * Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + * + * Enable this option for a probe connected to the Z Min endstop pin. + */ +#define Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + +/** + * Z_MIN_PROBE_ENDSTOP + * + * Enable this option for a probe connected to any pin except Z-Min. + * (By default Marlin assumes the Z-Max endstop pin.) + * To use a custom Z Probe pin, set Z_MIN_PROBE_PIN below. + * + * - The simplest option is to use a free endstop connector. + * - Use 5V for powered (usually inductive) sensors. + * + * - RAMPS 1.3/1.4 boards may use the 5V, GND, and Aux4->D32 pin: + * - For simple switches connect... + * - normally-closed switches to GND and D32. + * - normally-open switches to 5V and D32. + * + * WARNING: Setting the wrong pin may have unexpected and potentially + * disastrous consequences. Use with caution and do your homework. + * + */ +//#define Z_MIN_PROBE_ENDSTOP + +/** + * Probe Type + * + * Allen Key Probes, Servo Probes, Z-Sled Probes, FIX_MOUNTED_PROBE, etc. + * Activate one of these to use Auto Bed Leveling below. + */ + +/** + * The "Manual Probe" provides a means to do "Auto" Bed Leveling without a probe. + * Use G29 repeatedly, adjusting the Z height at each point with movement commands + * or (with LCD_BED_LEVELING) the LCD controller. + */ +//#define PROBE_MANUALLY + +/** + * A Fix-Mounted Probe either doesn't deploy or needs manual deployment. + * (e.g., an inductive probe or a nozzle-based probe-switch.) + */ +//#define FIX_MOUNTED_PROBE + +/** + * Z Servo Probe, such as an endstop switch on a rotating arm. + */ +//#define Z_ENDSTOP_SERVO_NR 0 // Defaults to SERVO 0 connector. +//#define Z_SERVO_ANGLES {70,0} // Z Servo Deploy and Stow angles + +/** + * The BLTouch probe uses a Hall effect sensor and emulates a servo. + */ +//#define BLTOUCH +#if ENABLED(BLTOUCH) + //#define BLTOUCH_DELAY 375 // (ms) Enable and increase if needed +#endif + +/** + * Enable one or more of the following if probing seems unreliable. + * Heaters and/or fans can be disabled during probing to minimize electrical + * noise. A delay can also be added to allow noise and vibration to settle. + * These options are most useful for the BLTouch probe, but may also improve + * readings with inductive probes and piezo sensors. + */ +//#define PROBING_HEATERS_OFF // Turn heaters off when probing +//#define PROBING_FANS_OFF // Turn fans off when probing +//#define DELAY_BEFORE_PROBING 200 // (ms) To prevent vibrations from triggering piezo sensors + +// A probe that is deployed and stowed with a solenoid pin (SOL1_PIN) +//#define SOLENOID_PROBE + +// A sled-mounted probe like those designed by Charles Bell. +//#define Z_PROBE_SLED +//#define SLED_DOCKING_OFFSET 5 // The extra distance the X axis must travel to pickup the sled. 0 should be fine but you can push it further if you'd like. + +// +// For Z_PROBE_ALLEN_KEY see the Delta example configurations. +// + +/** + * Z Probe to nozzle (X,Y) offset, relative to (0, 0). + * X and Y offsets must be integers. + * + * In the following example the X and Y offsets are both positive: + * #define X_PROBE_OFFSET_FROM_EXTRUDER 10 + * #define Y_PROBE_OFFSET_FROM_EXTRUDER 10 + * + * +-- BACK ---+ + * | | + * L | (+) P | R <-- probe (20,20) + * E | | I + * F | (-) N (+) | G <-- nozzle (10,10) + * T | | H + * | (-) | T + * | | + * O-- FRONT --+ + * (0,0) + */ +#define X_PROBE_OFFSET_FROM_EXTRUDER 10 // X offset: -left +right [of the nozzle] +#define Y_PROBE_OFFSET_FROM_EXTRUDER 10 // Y offset: -front +behind [the nozzle] +#define Z_PROBE_OFFSET_FROM_EXTRUDER 0 // Z offset: -below +above [the nozzle] + +// X and Y axis travel speed (mm/m) between probes +#define XY_PROBE_SPEED 8000 + +// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +#define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z + +// Speed for the "accurate" probe of each point +#define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) + +// Use double touch for probing +//#define PROBE_DOUBLE_TOUCH + +/** + * Z probes require clearance when deploying, stowing, and moving between + * probe points to avoid hitting the bed and other hardware. + * Servo-mounted probes require extra space for the arm to rotate. + * Inductive probes need space to keep from triggering early. + * + * Use these settings to specify the distance (mm) to raise the probe (or + * lower the bed). The values set here apply over and above any (negative) + * probe Z Offset set with Z_PROBE_OFFSET_FROM_EXTRUDER, M851, or the LCD. + * Only integer values >= 1 are valid here. + * + * Example: `M851 Z-5` with a CLEARANCE of 4 => 9mm from bed to nozzle. + * But: `M851 Z+1` with a CLEARANCE of 2 => 2mm from bed to nozzle. + */ +#define Z_CLEARANCE_DEPLOY_PROBE 10 // Z Clearance for Deploy/Stow +#define Z_CLEARANCE_BETWEEN_PROBES 5 // Z Clearance between probe points + +// For M851 give a range for adjusting the Z probe offset +#define Z_PROBE_OFFSET_RANGE_MIN -20 +#define Z_PROBE_OFFSET_RANGE_MAX 20 + +// Enable the M48 repeatability test to test probe accuracy +//#define Z_MIN_PROBE_REPEATABILITY_TEST + +// For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1 +// :{ 0:'Low', 1:'High' } +#define X_ENABLE_ON 0 +#define Y_ENABLE_ON 0 +#define Z_ENABLE_ON 0 +#define E_ENABLE_ON 0 // For all extruders + +// Disables axis stepper immediately when it's not being used. +// 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 +//#define DISABLE_REDUCED_ACCURACY_WARNING + +// @section extruder + +#define DISABLE_E false // For all extruders +#define DISABLE_INACTIVE_EXTRUDER true // Keep only the active extruder enabled. + +// @section machine + +// Invert the stepper direction. Change (or reverse the motor connector) if an axis goes the wrong way. +#define INVERT_X_DIR false +#define INVERT_Y_DIR false +#define INVERT_Z_DIR false + +// Enable this option for Toshiba stepper drivers +//#define CONFIG_STEPPERS_TOSHIBA + +// @section extruder + +// For direct drive extruder v9 set to true, for geared extruder set to false. +#define INVERT_E0_DIR false +#define INVERT_E1_DIR false +#define INVERT_E2_DIR false +#define INVERT_E3_DIR false +#define INVERT_E4_DIR false + +// @section homing + +//#define NO_MOTION_BEFORE_HOMING // Inhibit movement until all axes have been homed + +#define Z_HOMING_HEIGHT 4 // (in mm) Minimal z height before homing (G28) for Z clearance above the bed, clamps, ... + // Be sure you have this distance over your Z_MAX_POS in case. + +// Direction of endstops when homing; 1=MAX, -1=MIN +// :[-1,1] +#define X_HOME_DIR -1 +#define Y_HOME_DIR -1 +#define Z_HOME_DIR -1 + +// @section machine + +// The size of the print bed +#define X_BED_SIZE 200 +#define Y_BED_SIZE 200 + +// Travel limits (mm) after homing, corresponding to endstop positions. +#define X_MIN_POS 0 +#define Y_MIN_POS 0 +#define Z_MIN_POS 0 +#define X_MAX_POS X_BED_SIZE +#define Y_MAX_POS Y_BED_SIZE +#define Z_MAX_POS 170 + +// If enabled, axes won't move below MIN_POS in response to movement commands. +#define MIN_SOFTWARE_ENDSTOPS +// If enabled, axes won't move above MAX_POS in response to movement commands. +#define MAX_SOFTWARE_ENDSTOPS + +/** + * Filament Runout Sensor + * A mechanical or opto endstop is used to check for the presence of filament. + * + * RAMPS-based boards use SERVO3_PIN. + * For other boards you may need to define FIL_RUNOUT_PIN. + * By default the firmware assumes HIGH = has filament, LOW = ran out + */ +//#define FILAMENT_RUNOUT_SENSOR +#if ENABLED(FILAMENT_RUNOUT_SENSOR) + #define FIL_RUNOUT_INVERTING false // set to true to invert the logic of the sensor. + #define ENDSTOPPULLUP_FIL_RUNOUT // Uncomment to use internal pullup for filament runout pins if the sensor is defined. + #define FILAMENT_RUNOUT_SCRIPT "M600" +#endif + +//=========================================================================== +//=============================== Bed Leveling ============================== +//=========================================================================== +// @section bedlevel + +/** + * Choose one of the options below to enable G29 Bed Leveling. The parameters + * and behavior of G29 will change depending on your selection. + * + * If using a Probe for Z Homing, enable Z_SAFE_HOMING also! + * + * - AUTO_BED_LEVELING_3POINT + * Probe 3 arbitrary points on the bed (that aren't collinear) + * You specify the XY coordinates of all 3 points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_LINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_BILINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a mesh, best for large or uneven beds. + * + * - AUTO_BED_LEVELING_UBL (Unified Bed Leveling) + * A comprehensive bed leveling system combining the features and benefits + * of other systems. UBL also includes integrated Mesh Generation, Mesh + * Validation and Mesh Editing systems. Currently, UBL is only checked out + * for Cartesian Printers. That said, it was primarily designed to correct + * poor quality Delta Printers. If you feel adventurous and have a Delta, + * please post an issue if something doesn't work correctly. Initially, + * you will need to set a reduced bed size so you have a rectangular area + * to test on. + * + * - MESH_BED_LEVELING + * Probe a grid manually + * The result is a mesh, suitable for large or uneven beds. (See BILINEAR.) + * For machines without a probe, Mesh Bed Leveling provides a method to perform + * leveling in steps so you can manually adjust the Z height at each grid-point. + * With an LCD controller the process is guided step-by-step. + */ +//#define AUTO_BED_LEVELING_3POINT +//#define AUTO_BED_LEVELING_LINEAR +//#define AUTO_BED_LEVELING_BILINEAR +//#define AUTO_BED_LEVELING_UBL +//#define MESH_BED_LEVELING + +/** + * Enable detailed logging of G28, G29, M48, etc. + * Turn on with the command 'M111 S32'. + * NOTE: Requires a lot of PROGMEM! + */ +//#define DEBUG_LEVELING_FEATURE + +#if ENABLED(MESH_BED_LEVELING) || ENABLED(AUTO_BED_LEVELING_BILINEAR) || ENABLED(AUTO_BED_LEVELING_UBL) + // Gradually reduce leveling correction until a set height is reached, + // at which point movement will be level to the machine's XY plane. + // The height can be set with M420 Z + #define ENABLE_LEVELING_FADE_HEIGHT +#endif + +#if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Set the number of grid points per dimension. + #define GRID_MAX_POINTS_X 3 + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + // Set the boundaries for probing (where the probe can reach). + #define LEFT_PROBE_BED_POSITION 15 + #define RIGHT_PROBE_BED_POSITION 170 + #define FRONT_PROBE_BED_POSITION 20 + #define BACK_PROBE_BED_POSITION 170 + + // The Z probe minimum outer margin (to validate G29 parameters). + #define MIN_PROBE_EDGE 10 + + // Probe along the Y axis, advancing X after each column + //#define PROBE_Y_FIRST + + #if ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Beyond the probed grid, continue the implied tilt? + // Default is to maintain the height of the nearest edge. + //#define EXTRAPOLATE_BEYOND_GRID + + // + // Experimental Subdivision of the grid by Catmull-Rom method. + // Synthesizes intermediate points to produce a more detailed mesh. + // + //#define ABL_BILINEAR_SUBDIVISION + #if ENABLED(ABL_BILINEAR_SUBDIVISION) + // Number of subdivisions between probe points + #define BILINEAR_SUBDIVISIONS 3 + #endif + + #endif + +#elif ENABLED(AUTO_BED_LEVELING_3POINT) + + // 3 arbitrary points to probe. + // A simple cross-product is used to estimate the plane of the bed. + #define ABL_PROBE_PT_1_X 15 + #define ABL_PROBE_PT_1_Y 180 + #define ABL_PROBE_PT_2_X 15 + #define ABL_PROBE_PT_2_Y 20 + #define ABL_PROBE_PT_3_X 170 + #define ABL_PROBE_PT_3_Y 20 + +#elif ENABLED(AUTO_BED_LEVELING_UBL) + + //=========================================================================== + //========================= Unified Bed Leveling ============================ + //=========================================================================== + + #define UBL_MESH_INSET 1 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 10 // Don't use more than 15 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + #define UBL_PROBE_PT_1_X 39 // Probing points for 3-Point leveling of the mesh + #define UBL_PROBE_PT_1_Y 180 + #define UBL_PROBE_PT_2_X 39 + #define UBL_PROBE_PT_2_Y 20 + #define UBL_PROBE_PT_3_X 180 + #define UBL_PROBE_PT_3_Y 20 + + //#define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation + #define UBL_MESH_EDIT_MOVES_Z // Sophisticated users prefer no movement of nozzle + +#elif ENABLED(MESH_BED_LEVELING) + + //=========================================================================== + //=================================== Mesh ================================== + //=========================================================================== + + #define MESH_INSET 10 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 3 // Don't use more than 7 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + //#define MESH_G28_REST_ORIGIN // After homing all axes ('G28' or 'G28 XYZ') rest Z at Z_MIN_POS + +#endif // BED_LEVELING + +/** + * Use the LCD controller for bed leveling + * Requires MESH_BED_LEVELING or PROBE_MANUALLY + */ +//#define LCD_BED_LEVELING + +#if ENABLED(LCD_BED_LEVELING) + #define MBL_Z_STEP 0.025 // Step size while manually probing Z axis. + #define LCD_PROBE_Z_RANGE 4 // Z Range centered on Z_MIN_POS for LCD Z adjustment +#endif + +// Add a menu item to move between bed corners for manual bed adjustment +//#define LEVEL_BED_CORNERS + +/** + * Commands to execute at the end of G29 probing. + * Useful to retract or move the Z probe out of the way. + */ +//#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) +//#define BED_CENTER_AT_0_0 + +// Manually set the home position. Leave these undefined for automatic settings. +// For DELTA this is the top-center of the Cartesian print volume. +//#define MANUAL_X_HOME_POS 0 +//#define MANUAL_Y_HOME_POS 0 +//#define MANUAL_Z_HOME_POS 0 + +// Use "Z Safe Homing" to avoid homing with a Z probe outside the bed area. +// +// With this feature enabled: +// +// - 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). +// - 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 axis (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). +#endif + +// Homing speeds (mm/m) +#define HOMING_FEEDRATE_XY (50*60) +#define HOMING_FEEDRATE_Z (6*60) + +//============================================================================= +//============================= Additional Features =========================== +//============================================================================= + +// @section extras + +// +// EEPROM +// +// The microcontroller can store settings in the EEPROM, e.g. max velocity... +// M500 - stores parameters in EEPROM +// M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily). +// M502 - reverts to the default "factory settings". You still need to store them in EEPROM afterwards if you want to. +// +#define EEPROM_SETTINGS // Enable for M500 and M501 commands +//#define DISABLE_M503 // Saves ~2700 bytes of PROGMEM. Disable for release! +#define EEPROM_CHITCHAT // Give feedback on EEPROM commands. Disable to save PROGMEM. + +// +// Host Keepalive +// +// When enabled Marlin will send a busy status message to the host +// every couple of seconds when it can't accept commands. +// +#define HOST_KEEPALIVE_FEATURE // Disable this if your host doesn't like keepalive messages +#define DEFAULT_KEEPALIVE_INTERVAL 2 // Number of seconds between "busy" messages. Set with M113. +#define BUSY_WHILE_HEATING // Some hosts require "busy" messages even during heating + +// +// M100 Free Memory Watcher +// +//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose + +// +// G20/G21 Inch mode support +// +//#define INCH_MODE_SUPPORT + +// +// M149 Set temperature units support +// +//#define TEMPERATURE_UNITS_SUPPORT + +// @section temperature + +// Preheat Constants +#define PREHEAT_1_TEMP_HOTEND 180 +#define PREHEAT_1_TEMP_BED 70 +#define PREHEAT_1_FAN_SPEED 0 // Value from 0 to 255 + +#define PREHEAT_2_TEMP_HOTEND 240 +#define PREHEAT_2_TEMP_BED 110 +#define PREHEAT_2_FAN_SPEED 0 // Value from 0 to 255 + +/** + * Nozzle Park -- EXPERIMENTAL + * + * Park the nozzle at the given XYZ position on idle or G27. + * + * The "P" parameter controls the action applied to the Z axis: + * + * P0 (Default) If Z is below park Z raise the nozzle. + * P1 Raise the nozzle always to Z-park height. + * P2 Raise the nozzle by Z-park amount, limited to Z_MAX_POS. + */ +//#define NOZZLE_PARK_FEATURE + +#if ENABLED(NOZZLE_PARK_FEATURE) + // Specify a park position as { X, Y, Z } + #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 } +#endif + +/** + * Clean Nozzle Feature -- EXPERIMENTAL + * + * Adds the G12 command to perform a nozzle cleaning process. + * + * Parameters: + * P Pattern + * S Strokes / Repetitions + * T Triangles (P1 only) + * + * Patterns: + * P0 Straight line (default). This process requires a sponge type material + * at a fixed bed location. "S" specifies strokes (i.e. back-forth motions) + * between the start / end points. + * + * P1 Zig-zag pattern between (X0, Y0) and (X1, Y1), "T" specifies the + * number of zig-zag triangles to do. "S" defines the number of strokes. + * Zig-zags are done in whichever is the narrower dimension. + * For example, "G12 P1 S1 T3" will execute: + * + * -- + * | (X0, Y1) | /\ /\ /\ | (X1, Y1) + * | | / \ / \ / \ | + * A | | / \ / \ / \ | + * | | / \ / \ / \ | + * | (X0, Y0) | / \/ \/ \ | (X1, Y0) + * -- +--------------------------------+ + * |________|_________|_________| + * T1 T2 T3 + * + * P2 Circular pattern with middle at NOZZLE_CLEAN_CIRCLE_MIDDLE. + * "R" specifies the radius. "S" specifies the stroke count. + * Before starting, the nozzle moves to NOZZLE_CLEAN_START_POINT. + * + * Caveats: The ending Z should be the same as starting Z. + * Attention: EXPERIMENTAL. G-code arguments may change. + * + */ +//#define NOZZLE_CLEAN_FEATURE + +#if ENABLED(NOZZLE_CLEAN_FEATURE) + // Default number of pattern repetitions + #define NOZZLE_CLEAN_STROKES 12 + + // Default number of triangles + #define NOZZLE_CLEAN_TRIANGLES 3 + + // Specify positions as { X, Y, Z } + #define NOZZLE_CLEAN_START_POINT { 30, 30, (Z_MIN_POS + 1)} + #define NOZZLE_CLEAN_END_POINT {100, 60, (Z_MIN_POS + 1)} + + // Circular pattern radius + #define NOZZLE_CLEAN_CIRCLE_RADIUS 6.5 + // Circular pattern circle fragments number + #define NOZZLE_CLEAN_CIRCLE_FN 10 + // Middle point of circle + #define NOZZLE_CLEAN_CIRCLE_MIDDLE NOZZLE_CLEAN_START_POINT + + // Moves the nozzle to the initial position + #define NOZZLE_CLEAN_GOBACK +#endif + +/** + * Print Job Timer + * + * Automatically start and stop the print job timer on M104/M109/M190. + * + * M104 (hotend, no wait) - high temp = none, low temp = stop timer + * M109 (hotend, wait) - high temp = start timer, low temp = stop timer + * M190 (bed, wait) - high temp = start timer, low temp = none + * + * The timer can also be controlled with the following commands: + * + * M75 - Start the print job timer + * M76 - Pause the print job timer + * M77 - Stop the print job timer + */ +#define PRINTJOB_TIMER_AUTOSTART + +/** + * Print Counter + * + * Track statistical data such as: + * + * - Total print jobs + * - Total successful print jobs + * - Total failed print jobs + * - Total time printing + * + * View the current statistics with M78. + */ +//#define PRINTCOUNTER + +//============================================================================= +//============================= LCD and SD support ============================ +//============================================================================= + +// @section lcd + +/** + * LCD LANGUAGE + * + * Select the language to display on the LCD. These languages are available: + * + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, + * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, tr, uk, + * zh_CN, zh_TW, test + * + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + */ +#define LCD_LANGUAGE en + +/** + * LCD Character Set + * + * Note: This option is NOT applicable to Graphical Displays. + * + * All character-based LCDs provide ASCII plus one of these + * language extensions: + * + * - JAPANESE ... the most common + * - WESTERN ... with more accented characters + * - CYRILLIC ... for the Russian language + * + * To determine the language extension installed on your controller: + * + * - Compile and upload with LCD_LANGUAGE set to 'test' + * - 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 + * + * :['JAPANESE', 'WESTERN', 'CYRILLIC'] + */ +#define DISPLAY_CHARSET_HD44780 JAPANESE + +/** + * LCD TYPE + * + * Enable ULTRA_LCD for a 16x2, 16x4, 20x2, or 20x4 character-based LCD. + * Enable DOGLCD for a 128x64 (ST7565R) Full Graphical Display. + * (These options will be enabled automatically for most displays.) + * + * IMPORTANT: The U8glib library is required for Full Graphic Display! + * https://github.com/olikraus/U8glib_Arduino + */ +//#define ULTRA_LCD // Character based +//#define DOGLCD // Full graphics display + +/** + * SD CARD + * + * 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 + +/** + * SD CARD: SPI SPEED + * + * Enable one of the following items for a slower SPI transfer speed. + * This may be required to resolve "volume init" errors. + */ +//#define SPI_SPEED SPI_HALF_SPEED +//#define SPI_SPEED SPI_QUARTER_SPEED +//#define SPI_SPEED SPI_EIGHTH_SPEED + +/** + * SD CARD: ENABLE CRC + * + * Use CRC checks and retries on the SD communication. + */ +//#define SD_CHECK_AND_RETRY + +// +// ENCODER SETTINGS +// +// This option overrides the default number of encoder pulses needed to +// produce one step. Should be increased for high-resolution encoders. +// +//#define ENCODER_PULSES_PER_STEP 1 + +// +// Use this option to override the number of step signals required to +// move between next/prev menu items. +// +//#define ENCODER_STEPS_PER_MENU_ITEM 5 + +/** + * Encoder Direction Options + * + * Test your encoder's behavior first with both options disabled. + * + * Reversed Value Edit and Menu Nav? Enable REVERSE_ENCODER_DIRECTION. + * Reversed Menu Navigation only? Enable REVERSE_MENU_DIRECTION. + * Reversed Value Editing only? Enable BOTH options. + */ + +// +// This option reverses the encoder direction everywhere. +// +// Set this option if CLOCKWISE causes values to DECREASE +// +//#define REVERSE_ENCODER_DIRECTION + +// +// This option reverses the encoder direction for navigating LCD menus. +// +// If CLOCKWISE normally moves DOWN this makes it go UP. +// If CLOCKWISE normally moves UP this makes it go DOWN. +// +//#define REVERSE_MENU_DIRECTION + +// +// Individual Axis Homing +// +// Add individual axis homing items (Home X, Home Y, and Home Z) to the LCD menu. +// +//#define INDIVIDUAL_AXIS_HOMING_MENU + +// +// SPEAKER/BUZZER +// +// If you have a speaker that can produce tones, enable it here. +// By default Marlin assumes you have a buzzer with a fixed frequency. +// +//#define SPEAKER + +// +// The duration and frequency for the UI feedback sound. +// Set these to 0 to disable audio feedback in the LCD menus. +// +// Note: Test audio output with the G-Code: +// M300 S P +// +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 +//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 + +// +// CONTROLLER TYPE: Standard +// +// Marlin supports a wide variety of controllers. +// Enable one of the following options to specify your controller. +// + +// +// ULTIMAKER Controller. +// +//#define ULTIMAKERCONTROLLER + +// +// ULTIPANEL as seen on Thingiverse. +// +//#define ULTIPANEL + +// +// PanelOne from T3P3 (via RAMPS 1.4 AUX2/AUX3) +// http://reprap.org/wiki/PanelOne +// +//#define PANEL_ONE + +// +// MaKr3d Makr-Panel with graphic controller and SD support. +// http://reprap.org/wiki/MaKr3d_MaKrPanel +// +//#define MAKRPANEL + +// +// ReprapWorld Graphical LCD +// https://reprapworld.com/?products_details&products_id/1218 +// +//#define REPRAPWORLD_GRAPHICAL_LCD + +// +// Activate one of these if you have a Panucatt Devices +// Viki 2.0 or mini Viki with Graphic LCD +// http://panucatt.com +// +//#define VIKI2 +//#define miniVIKI + +// +// Adafruit ST7565 Full Graphic Controller. +// https://github.com/eboston/Adafruit-ST7565-Full-Graphic-Controller/ +// +//#define ELB_FULL_GRAPHIC_CONTROLLER + +// +// RepRapDiscount Smart Controller. +// http://reprap.org/wiki/RepRapDiscount_Smart_Controller +// +// Note: Usually sold with a white PCB. +// +//#define REPRAP_DISCOUNT_SMART_CONTROLLER + +// +// GADGETS3D G3D LCD/SD Controller +// http://reprap.org/wiki/RAMPS_1.3/1.4_GADGETS3D_Shield_with_Panel +// +// Note: Usually sold with a blue PCB. +// +//#define G3D_PANEL + +// +// RepRapDiscount FULL GRAPHIC Smart Controller +// http://reprap.org/wiki/RepRapDiscount_Full_Graphic_Smart_Controller +// +//#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER + +// +// MakerLab Mini Panel with graphic +// controller and SD support - http://reprap.org/wiki/Mini_panel +// +//#define MINIPANEL + +// +// RepRapWorld REPRAPWORLD_KEYPAD v1.1 +// http://reprapworld.com/?products_details&products_id=202&cPath=1591_1626 +// +// REPRAPWORLD_KEYPAD_MOVE_STEP sets how much should the robot move when a key +// is pressed, a value of 10.0 means 10mm per click. +// +//#define REPRAPWORLD_KEYPAD +//#define REPRAPWORLD_KEYPAD_MOVE_STEP 1.0 + +// +// RigidBot Panel V1.0 +// http://www.inventapart.com/ +// +//#define RIGIDBOT_PANEL + +// +// BQ LCD Smart Controller shipped by +// default with the BQ Hephestos 2 and Witbox 2. +// +//#define BQ_LCD_SMART_CONTROLLER + +// +// Cartesio UI +// http://mauk.cc/webshop/cartesio-shop/electronics/user-interface +// +//#define CARTESIO_UI + +// +// ANET_10 Controller supported displays. +// +//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. + // This LCD is known to be susceptible to electrical interference + // which scrambles the display. Pressing any button clears it up. +//#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 + // A clone of the RepRapDiscount full graphics display but with + // different pins/wiring (see pins_ANET_10.h). + +// +// LCD for Melzi Card with Graphical LCD +// +//#define LCD_FOR_MELZI + +// +// CONTROLLER TYPE: I2C +// +// Note: These controllers require the installation of Arduino's LiquidCrystal_I2C +// library. For more info: https://github.com/kiyoshigawa/LiquidCrystal_I2C +// + +// +// Elefu RA Board Control Panel +// http://www.elefu.com/index.php?route=product/product&product_id=53 +// +//#define RA_CONTROL_PANEL + +// +// Sainsmart YW Robot (LCM1602) LCD Display +// +// Note: This controller requires F.Malpartida's LiquidCrystal_I2C library +// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home +// +//#define LCD_I2C_SAINSMART_YWROBOT + +// +// Generic LCM1602 LCD adapter +// +//#define LCM1602 + +// +// PANELOLU2 LCD with status LEDs, +// separate encoder and click inputs. +// +// Note: This controller requires Arduino's LiquidTWI2 library v1.2.3 or later. +// For more info: https://github.com/lincomatic/LiquidTWI2 +// +// Note: The PANELOLU2 encoder click input can either be directly connected to +// a pin (if BTN_ENC defined to != -1) or read through I2C (when BTN_ENC == -1). +// +//#define LCD_I2C_PANELOLU2 + +// +// Panucatt VIKI LCD with status LEDs, +// integrated click & L/R/U/D buttons, separate encoder inputs. +// +//#define LCD_I2C_VIKI + +// +// SSD1306 OLED full graphics generic display +// +//#define U8GLIB_SSD1306 + +// +// SAV OLEd LCD module support using either SSD1306 or SH1106 based LCD modules +// +//#define SAV_3DGLCD +#if ENABLED(SAV_3DGLCD) + //#define U8GLIB_SSD1306 + #define U8GLIB_SH1106 +#endif + +// +// CONTROLLER TYPE: Shift register panels +// +// 2 wire Non-latching LCD SR from https://goo.gl/aJJ4sH +// LCD configuration: http://reprap.org/wiki/SAV_3D_LCD +// +//#define SAV_3DLCD + +// +// TinyBoy2 128x64 OLED / Encoder Panel +// +//#define OLED_PANEL_TINYBOY2 + +// +// Makeboard 3D Printer Parts 3D Printer Mini Display 1602 Mini Controller +// https://www.aliexpress.com/item/Micromake-Makeboard-3D-Printer-Parts-3D-Printer-Mini-Display-1602-Mini-Controller-Compatible-with-Ramps-1/32765887917.html +// +//#define MAKEBOARD_MINI_2_LINE_DISPLAY_1602 + +// +// MKS MINI12864 with graphic controller and SD support +// http://reprap.org/wiki/MKS_MINI_12864 +// +//#define MKS_MINI_12864 + +// +// Factory display for Creality CR-10 +// https://www.aliexpress.com/item/Universal-LCD-12864-3D-Printer-Display-Screen-With-Encoder-For-CR-10-CR-7-Model/32833148327.html +// +// This is RAMPS-compatible using a single 10-pin connector. +// (For CR-10 owners who want to replace the Melzi Creality board but retain the display) +// +//#define CR10_STOCKDISPLAY + +// +// MKS OLED 1.3" 128 × 64 FULL GRAPHICS CONTROLLER +// http://reprap.org/wiki/MKS_12864OLED +// +// Tiny, but very sharp OLED display +// +//#define MKS_12864OLED + +//============================================================================= +//=============================== Extra Features ============================== +//============================================================================= + +// @section extras + +// Increase the FAN PWM frequency. Removes the PWM noise but increases heating in the FET/Arduino +//#define FAST_PWM_FAN + +// Use software PWM to drive the fan, as for the heaters. This uses a very low frequency +// which is not as annoying as with the hardware PWM. On the other hand, if this frequency +// is too low, you should also increment SOFT_PWM_SCALE. +//#define FAN_SOFT_PWM + +// Incrementing this by 1 will double the software PWM frequency, +// affecting heaters, and the fan if FAN_SOFT_PWM is enabled. +// However, control resolution will be halved for each increment; +// at zero value, there are 128 effective control positions. +#define SOFT_PWM_SCALE 0 + +// If SOFT_PWM_SCALE is set to a value higher than 0, dithering can +// be used to mitigate the associated resolution loss. If enabled, +// some of the PWM cycles are stretched so on average the desired +// duty cycle is attained. +//#define SOFT_PWM_DITHER + +// Temperature status LEDs that display the hotend and bed temperature. +// If all hotends, bed temperature, and target temperature are under 54C +// then the BLUE led is on. Otherwise the RED led is on. (1C hysteresis) +//#define TEMP_STAT_LEDS + +// M240 Triggers a camera by emulating a Canon RC-1 Remote +// Data from: http://www.doc-diy.net/photo/rc-1_hacked/ +//#define PHOTOGRAPH_PIN 23 + +// 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 + +// Support for BlinkM/CyzRgb +//#define BLINKM + +// Support for PCA9632 PWM LED driver +//#define PCA9632 + +/** + * RGB LED / LED Strip Control + * + * Enable support for an RGB LED connected to 5V digital pins, or + * an RGB Strip connected to MOSFETs controlled by digital pins. + * + * 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 overall brightness parameters is also available + * + * *** CAUTION *** + * LED Strips require a MOFSET 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! + * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino + * cannot handle such current, separate 5V power supply must be used + * *** CAUTION *** + * + * LED type. This options are mutualy exclusive. Uncomment only one. + * + */ +#define RGB_LED +//#define RGBW_LED + +#if ENABLED(RGB_LED) || ENABLED(RGBW_LED) + #define RGB_LED_R_PIN 11 + #define RGB_LED_G_PIN 10 + #define RGB_LED_B_PIN 17 + #define RGB_LED_W_PIN -1 +#endif + +// 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 (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) + #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip + #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time + #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + //#define NEOPIXEL_STARTUP_TEST // Cycle through colors at startup +#endif + +/** + * Printer Event LEDs + * + * During printing, the LEDs will reflect the printer status: + * + * - Gradually change from blue to violet as the heated bed gets to target temp + * - Gradually change from violet to red as the hotend gets to temperature + * - Change to white to illuminate work surface + * - Change to green once print has finished + * - Turn off after the print has finished and the user has pushed a button + */ +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) + #define PRINTER_EVENT_LEDS +#endif + +/*********************************************************************\ +* R/C SERVO support +* Sponsored by TrinityLabs, Reworked by codexmas +**********************************************************************/ + +// Number of servos +// +// If you select a configuration below, this will receive a default value and does not need to be set manually +// set it manually if you have more servos than extruders and wish to manually control some +// leaving it undefined or defining as 0 will disable the servo subsystem +// If unsure, leave commented / disabled +// +//#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command + +// Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. +// 300ms is a good value but you can try less delay. +// If the servo can't reach the requested position, increase it. +#define SERVO_DELAY { 300 } + +// Servo deactivation +// +// With this option servos are powered only during movement, then turned off to prevent jitter. +//#define DEACTIVATE_SERVOS_AFTER_MOVE + +/** + * Filament Width Sensor + * + * Measures the filament width in real-time and adjusts + * flow rate to compensate for any irregularities. + * + * Also allows the measured filament diameter to set the + * extrusion rate, so the slicer only has to specify the + * volume. + * + * Only a single extruder is supported at this time. + * + * 34 RAMPS_14 : Analog input 5 on the AUX2 connector + * 81 PRINTRBOARD : Analog input 2 on the Exp1 connector (version B,C,D,E) + * 301 RAMBO : Analog input 3 + * + * Note: May require analog pins to be defined for other boards. + */ +//#define FILAMENT_WIDTH_SENSOR + +#define DEFAULT_NOMINAL_FILAMENT_DIA 1.75 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. + +#if ENABLED(FILAMENT_WIDTH_SENSOR) + #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) + #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber + + #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading + #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading + #define MAX_MEASUREMENT_DELAY 20 // (bytes) Buffer size for stored measurements (1 byte per cm). Must be larger than MEASUREMENT_DELAY_CM. + + #define DEFAULT_MEASURED_FILAMENT_DIA DEFAULT_NOMINAL_FILAMENT_DIA // Set measured to nominal initially + + // Display filament width on the LCD status line. Status messages will expire after 5 seconds. + //#define FILAMENT_LCD_DISPLAY +#endif + +#endif // CONFIGURATION_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/Sanguinololu/Configuration_adv.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/Sanguinololu/Configuration_adv.h new file mode 100644 index 00000000..00401a88 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/Sanguinololu/Configuration_adv.h @@ -0,0 +1,1391 @@ +/** + * 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 . + * + */ + +/** + * Configuration_adv.h + * + * Advanced settings. + * Only change these if you know exactly what you're doing. + * Some of these settings can damage your printer if improperly set! + * + * Basic settings can be found in Configuration.h + * + */ +#ifndef CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H_VERSION 010100 + +// @section temperature + +//=========================================================================== +//=============================Thermal Settings ============================ +//=========================================================================== + +#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 + #endif +#endif + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * The solution: Once the temperature reaches the target, start observing. + * If the temperature stays too far below the target (hysteresis) for too long (period), + * the firmware will halt the machine as a safety precaution. + * + * If you get false positives for "Thermal Runaway" increase THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD + */ +#if ENABLED(THERMAL_PROTECTION_HOTENDS) + #define THERMAL_PROTECTION_PERIOD 40 // Seconds + #define THERMAL_PROTECTION_HYSTERESIS 4 // Degrees Celsius + + /** + * Whenever an M104 or M109 increases the target temperature the firmware will wait for the + * WATCH_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get false positives for "Heating failed" increase WATCH_TEMP_PERIOD and/or decrease WATCH_TEMP_INCREASE + * WATCH_TEMP_INCREASE should not be below 2. + */ + #define WATCH_TEMP_PERIOD 20 // Seconds + #define WATCH_TEMP_INCREASE 2 // Degrees Celsius +#endif + +/** + * Thermal Protection parameters for the bed are just as above for hotends. + */ +#if ENABLED(THERMAL_PROTECTION_BED) + #define THERMAL_PROTECTION_BED_PERIOD 20 // Seconds + #define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius + + /** + * Whenever an M140 or M190 increases the target temperature the firmware will wait for the + * WATCH_BED_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_BED_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get too many "Heating failed" errors, increase WATCH_BED_TEMP_PERIOD and/or decrease + * WATCH_BED_TEMP_INCREASE. (WATCH_BED_TEMP_INCREASE should not be below 2.) + */ + #define WATCH_BED_TEMP_PERIOD 60 // Seconds + #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius +#endif + +#if ENABLED(PIDTEMP) + // this adds an experimental additional term to the heating power, proportional to the extrusion speed. + // if Kc is chosen well, the additional required power due to increased melting should be compensated. + //#define PID_EXTRUSION_SCALING + #if ENABLED(PID_EXTRUSION_SCALING) + #define DEFAULT_Kc (100) //heating power=Kc*(e_speed) + #define LPQ_MAX_LEN 50 + #endif +#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 + */ +#define AUTOTEMP +#if ENABLED(AUTOTEMP) + #define AUTOTEMP_OLDWEIGHT 0.98 +#endif + +// Show Temperature ADC value +// Enable for M105 to include ADC values read from temperature sensors. +//#define SHOW_TEMP_ADC_VALUES + +/** + * High Temperature Thermistor Support + * + * Thermistors able to support high temperature tend to have a hard time getting + * good readings at room and lower temperatures. This means HEATER_X_RAW_LO_TEMP + * will probably be caught when the heating element first turns on during the + * preheating process, which will trigger a min_temp_error as a safety measure + * and force stop everything. + * To circumvent this limitation, we allow for a preheat time (during which, + * min_temp_error won't be triggered) and add a min_temp buffer to handle + * aberrant readings. + * + * If you want to enable this feature for your hotend thermistor(s) + * uncomment and set values > 0 in the constants below + */ + +// The number of consecutive low temperature errors that can occur +// before a min_temp_error is triggered. (Shouldn't be more than 10.) +//#define MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED 0 + +// The number of milliseconds a hotend will preheat before starting to check +// the temperature. This value should NOT be set to the time it takes the +// hot end to reach the target temperature, but the time it takes to reach +// the minimum temperature your thermistor can read. The lower the better/safer. +// This shouldn't need to be more than 30 seconds (30000) +//#define MILLISECONDS_PREHEAT_TIME 0 + +// @section extruder + +// Extruder runout prevention. +// If the machine is idle and the temperature over MINTEMP +// then extrude some filament every couple of SECONDS. +//#define EXTRUDER_RUNOUT_PREVENT +#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_EXTRUDE 5 // mm +#endif + +// @section temperature + +//These defines help to calibrate the AD595 sensor in case you get wrong temperature measurements. +//The measured temperature is defined as "actualTemp = (measuredTemp * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET" +#define TEMP_SENSOR_AD595_OFFSET 0.0 +#define TEMP_SENSOR_AD595_GAIN 1.0 + +/** + * 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. + */ +//#define USE_CONTROLLER_FAN +#if ENABLED(USE_CONTROLLER_FAN) + //#define CONTROLLER_FAN_PIN FAN1_PIN // 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 +#endif + +// When first starting the main fan, run it at full speed for the +// given number of milliseconds. This gets the fan spinning reliably +// before setting a PWM value. (Does not work with software PWM for fan on Sanguinololu) +//#define FAN_KICKSTART_TIME 100 + +// This defines the minimal speed for the main fan, run in PWM mode +// to enable uncomment and set minimal PWM speed for reliable running (1-255) +// if fan speed is [1 - (FAN_MIN_PWM-1)] it is set to FAN_MIN_PWM +//#define FAN_MIN_PWM 50 + +// @section extruder + +/** + * Extruder cooling fans + * + * Extruder auto fans automatically turn on when their extruders' + * temperatures go above EXTRUDER_AUTO_FAN_TEMPERATURE. + * + * Your board's pins file specifies the recommended pins. Override those here + * or set to -1 to disable completely. + * + * Multiple extruders can be assigned to the same pin in which case + * the fan will turn on when any selected extruder is above the threshold. + */ +#define E0_AUTO_FAN_PIN -1 +#define E1_AUTO_FAN_PIN -1 +#define E2_AUTO_FAN_PIN -1 +#define E3_AUTO_FAN_PIN -1 +#define E4_AUTO_FAN_PIN -1 +#define EXTRUDER_AUTO_FAN_TEMPERATURE 50 +#define EXTRUDER_AUTO_FAN_SPEED 255 // == full speed + +/** + * M355 Case Light on-off / brightness + */ +//#define CASE_LIGHT_ENABLE +#if ENABLED(CASE_LIGHT_ENABLE) + //#define CASE_LIGHT_PIN 4 // Override the default pin if needed + #define INVERT_CASE_LIGHT false // Set true if Case Light is ON when pin is LOW + #define CASE_LIGHT_DEFAULT_ON true // Set default power-up state on + #define CASE_LIGHT_DEFAULT_BRIGHTNESS 105 // Set default power-up brightness (0-255, requires PWM pin) + //#define MENU_ITEM_CASE_LIGHT // Add a Case Light option to the LCD main menu +#endif + +//=========================================================================== +//============================ Mechanical Settings ========================== +//=========================================================================== + +// @section homing + +// If you want endstops to stay on (by default) even when not homing +// enable this option. Override at any time with M120, M121. +//#define ENDSTOPS_ALWAYS_ON_DEFAULT + +// @section extras + +//#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. + +// Dual X Steppers +// Uncomment this option to drive two X axis motors. +// The next unused E driver will be assigned to the second X stepper. +//#define X_DUAL_STEPPER_DRIVERS +#if ENABLED(X_DUAL_STEPPER_DRIVERS) + // Set true if the two X motors need to rotate in opposite directions + #define INVERT_X2_VS_X_DIR true +#endif + +// Dual Y Steppers +// Uncomment this option to drive two Y axis motors. +// The next unused E driver will be assigned to the second Y stepper. +//#define Y_DUAL_STEPPER_DRIVERS +#if ENABLED(Y_DUAL_STEPPER_DRIVERS) + // Set true if the two Y motors need to rotate in opposite directions + #define INVERT_Y2_VS_Y_DIR true +#endif + +// A single Z stepper driver is usually used to drive 2 stepper motors. +// Uncomment this option to use a separate stepper driver for each Z axis motor. +// The next unused E driver will be assigned to the second Z stepper. +//#define Z_DUAL_STEPPER_DRIVERS + +#if ENABLED(Z_DUAL_STEPPER_DRIVERS) + + // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper. + // That way the machine is capable to align the bed during home, since both Z steppers are homed. + // There is also an implementation of M666 (software endstops adjustment) to this feature. + // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed. + // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2. + // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive. + // Play a little bit with small adjustments (0.5mm) and check the behaviour. + // The M119 (endstops report) will start reporting the Z2 Endstop as well. + + //#define Z_DUAL_ENDSTOPS + + #if ENABLED(Z_DUAL_ENDSTOPS) + #define Z2_USE_ENDSTOP _XMAX_ + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 // Use M666 to determine/test this value + #endif + +#endif // Z_DUAL_STEPPER_DRIVERS + +// Enable this for dual x-carriage printers. +// A dual x-carriage design has the advantage that the inactive extruder can be parked which +// prevents hot-end ooze contaminating the print. It also reduces the weight of each x-carriage +// allowing faster printing speeds. Connect your X2 stepper to the first unused E plug. +//#define DUAL_X_CARRIAGE +#if ENABLED(DUAL_X_CARRIAGE) + // Configuration for second X-carriage + // Note: the first x-carriage is defined as the x-carriage which homes to the minimum endstop; + // the second x-carriage always homes to the maximum endstop. + #define X2_MIN_POS 80 // set minimum to ensure second x-carriage doesn't hit the parked first X-carriage + #define X2_MAX_POS 353 // set maximum to the distance between toolheads when both heads are homed + #define X2_HOME_DIR 1 // the second X-carriage always homes to the maximum endstop position + #define X2_HOME_POS X2_MAX_POS // default home position is the maximum carriage position + // However: In this mode the HOTEND_OFFSET_X value for the second extruder provides a software + // override for X2_HOME_POS. This also allow recalibration of the distance between the two endstops + // without modifying the firmware (through the "M218 T1 X???" command). + // Remember: you should set the second extruder x-offset to 0 in your slicer. + + // There are a few selectable movement modes for dual x-carriages using M605 S + // Mode 0 (DXC_FULL_CONTROL_MODE): Full control. The slicer has full control over both x-carriages and can achieve optimal travel results + // as long as it supports dual x-carriages. (M605 S0) + // Mode 1 (DXC_AUTO_PARK_MODE) : Auto-park mode. The firmware will automatically park and unpark the x-carriages on tool changes so + // that additional slicer support is not required. (M605 S1) + // Mode 2 (DXC_DUPLICATION_MODE) : Duplication mode. The firmware will transparently make the second x-carriage and extruder copy all + // actions of the first x-carriage. This allows the printer to print 2 arbitrary items at + // once. (2nd extruder x offset and temp offset are set using: M605 S2 [Xnnn] [Rmmm]) + + // This is the default power-up mode which can be later using M605. + #define DEFAULT_DUAL_X_CARRIAGE_MODE DXC_FULL_CONTROL_MODE + + // Default settings in "Auto-park Mode" + #define TOOLCHANGE_PARK_ZLIFT 0.2 // the distance to raise Z axis when parking an extruder + #define TOOLCHANGE_UNPARK_ZLIFT 1 // the distance to raise Z axis when unparking an extruder + + // Default x offset in duplication mode (typically set to half print bed width) + #define DEFAULT_DUPLICATION_X_OFFSET 100 + +#endif // DUAL_X_CARRIAGE + +// 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. +//#define EXT_SOLENOID + +// @section homing + +//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +#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 this is defined, if both x and y are to be homed, a diagonal move will be performed initially. + +// When G28 is called, this option will make Y home before X +//#define HOME_Y_BEFORE_X + +// @section machine + +#define AXIS_RELATIVE_MODES {false, false, false, false} + +// Allow duplication mode with a basic dual-nozzle extruder +//#define DUAL_NOZZLE_DUPLICATION_MODE + +// By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step. +#define INVERT_X_STEP_PIN false +#define INVERT_Y_STEP_PIN false +#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. +#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_E true + +#define DEFAULT_MINIMUMFEEDRATE 0.0 // minimum feedrate +#define DEFAULT_MINTRAVELFEEDRATE 0.0 + +//#define HOME_AFTER_DEACTIVATE // Require rehoming after steppers are deactivated + +// @section lcd + +#if ENABLED(ULTIPANEL) + #define MANUAL_FEEDRATE {50*60, 50*60, 4*60, 60} // Feedrates for manual moves along X, Y, Z, E from panel + #define ULTIPANEL_FEEDMULTIPLY // Comment to disable setting feedrate multiplier via encoder +#endif + +// @section extras + +// minimum time in microseconds that a movement needs to take if the buffer is emptied. +#define DEFAULT_MINSEGMENTTIME 20000 + +// If defined the movements slow down when the look ahead buffer is only half full +#define SLOWDOWN + +// Frequency limit +// See nophead's blog for more info +// Not working O +//#define XY_FREQUENCY_LIMIT 15 + +// 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 +// if unwanted behavior is observed on a user's machine when running at very slow speeds. +#define MINIMUM_PLANNER_SPEED 0.05 // (mm/sec) + +// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU. +#define MICROSTEP_MODES {16,16,16,16,16} // [1,2,4,8,16] + +/** + * @section stepper motor current + * + * Some boards have a means of setting the stepper motor current via firmware. + * + * The power on motor currents are set by: + * PWM_MOTOR_CURRENT - used by MINIRAMBO & ULTIMAIN_2 + * known compatible chips: A4982 + * DIGIPOT_MOTOR_CURRENT - used by BQ_ZUM_MEGA_3D, RAMBO & SCOOVO_X9H + * known compatible chips: AD5206 + * DAC_MOTOR_CURRENT_DEFAULT - used by PRINTRBOARD_REVF & RIGIDBOARD_V2 + * known compatible chips: MCP4728 + * DIGIPOT_I2C_MOTOR_CURRENTS - used by 5DPRINT, AZTEEG_X3_PRO, MIGHTYBOARD_REVE + * known compatible chips: MCP4451, MCP4018 + * + * Motor currents can also be set by M907 - M910 and by the LCD. + * M907 - applies to all. + * M908 - BQ_ZUM_MEGA_3D, RAMBO, PRINTRBOARD_REVF, RIGIDBOARD_V2 & SCOOVO_X9H + * M909, M910 & LCD - only PRINTRBOARD_REVF & RIGIDBOARD_V2 + */ +//#define PWM_MOTOR_CURRENT { 1300, 1300, 1250 } // Values in milliamps +//#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 + +// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +//#define DIGIPOT_I2C +//#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster +#define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 +// Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS +#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=========================== +//=========================================================================== + +#define ENCODER_RATE_MULTIPLIER // If defined, certain menu edit operations automatically multiply the steps when the encoder is moved quickly +#define ENCODER_10X_STEPS_PER_SEC 75 // If the encoder steps per sec exceeds this value, multiply steps moved x10 to quickly advance the value +#define ENCODER_100X_STEPS_PER_SEC 160 // If the encoder steps per sec exceeds this value, multiply steps moved x100 to really quickly advance the value + +//#define CHDK 4 //Pin for triggering CHDK to take a picture see how to use it here http://captain-slow.dk/2014/03/09/3d-printing-timelapses/ +#define CHDK_DELAY 50 //How long in ms the pin should stay HIGH before going LOW again + +// @section lcd + +// Include a page of printer information in the LCD Main Menu +//#define LCD_INFO_MENU + +// Scroll a longer status message into view +//#define STATUS_MESSAGE_SCROLLING + +// On the Info Screen, display XY with one decimal place when possible +//#define LCD_DECIMAL_SMALL_XY + +// The timeout (in ms) to return to the status screen from sub-menus +//#define LCD_TIMEOUT_TO_STATUS 15000 + +#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 + + #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? + #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. + + #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. + // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. + // using: + //#define MENU_ADDAUTOSTART + + /** + * Sort SD file listings in alphabetical order. + * + * With this option enabled, items on SD cards will be sorted + * by name for easier navigation. + * + * By default... + * + * - Use the slowest -but safest- method for sorting. + * - Folders are sorted to the top. + * - The sort key is statically allocated. + * - No added G-code (M34) support. + * - 40 item sorting limit. (Items after the first 40 are unsorted.) + * + * SD sorting uses static allocation (as set by SDSORT_LIMIT), allowing the + * compiler to calculate the worst-case usage and throw an error if the SRAM + * limit is exceeded. + * + * - SDSORT_USES_RAM provides faster sorting via a static directory buffer. + * - SDSORT_USES_STACK does the same, but uses a local stack-based buffer. + * - SDSORT_CACHE_NAMES will retain the sorted file listing in RAM. (Expensive!) + * - SDSORT_DYNAMIC_RAM only uses RAM when the SD menu is visible. (Use with caution!) + */ + //#define SDCARD_SORT_ALPHA + + // SD Card Sorting options + #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_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. + #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #endif + + // Show a progress bar on HD44780 LCDs for SD printing + //#define LCD_PROGRESS_BAR + + #if ENABLED(LCD_PROGRESS_BAR) + // Amount of time (ms) to show the bar + #define PROGRESS_BAR_BAR_TIME 2000 + // Amount of time (ms) to show the status message + #define PROGRESS_BAR_MSG_TIME 3000 + // Amount of time (ms) to retain the status message (0=forever) + #define PROGRESS_MSG_EXPIRE 0 + // Enable this to show messages for MSG_TIME then hide them + //#define PROGRESS_MSG_ONCE + // Add a menu item to test the progress bar: + //#define LCD_PROGRESS_BAR_TEST + #endif + + // This allows hosts to request long names for files and folders with M33 + //#define LONG_FILENAME_HOST_SUPPORT + + // This option allows you to abort SD printing when any endstop is triggered. + // This feature must be enabled with "M540 S1" or from the LCD menu. + // To have any effect, endstops must be enabled during SD printing. + //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + +#endif // SDSUPPORT + +/** + * Additional options for Graphical Displays + * + * Use the optimizations here to improve printing performance, + * which can be adversely affected by graphical display drawing, + * especially when doing several short moves, and when printing + * on DELTA and SCARA machines. + * + * Some of these options may result in the display lagging behind + * controller events, as there is a trade-off between reliable + * printing performance versus fast display updates. + */ +#if ENABLED(DOGLCD) + // Enable to save many cycles by drawing a hollow frame on the Info Screen + #define XYZ_HOLLOW_FRAME + + // Enable to save many cycles by drawing a hollow frame on Menu Screens + #define MENU_HOLLOW_FRAME + + // A bigger font is available for edit items. Costs 3120 bytes of PROGMEM. + // 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. + // 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 +#endif // DOGLCD + +// @section safety + +// The hardware watchdog should reset the microcontroller disabling all outputs, +// in case the firmware gets stuck and doesn't do temperature regulation. +#define USE_WATCHDOG + +#if ENABLED(USE_WATCHDOG) + // If you have a watchdog reboot in an ArduinoMega2560 then the device will hang forever, as a watchdog reset will leave the watchdog on. + // The "WATCHDOG_RESET_MANUAL" goes around this by not using the hardware reset. + // However, THIS FEATURE IS UNSAFE!, as it will only work if interrupts are disabled. And the code could hang in an interrupt routine with interrupts disabled. + //#define WATCHDOG_RESET_MANUAL +#endif + +// @section lcd + +/** + * Babystepping enables movement of the axes by tiny increments without changing + * the current position values. This feature is used primarily to adjust the Z + * axis in the first layer of a print in real-time. + * + * Warning: Does not respect endstops! + */ +//#define BABYSTEPPING +#if ENABLED(BABYSTEPPING) + //#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 100 // Babysteps are very small. Increase for faster motion. + //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping + //#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen 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_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor + //#define BABYSTEP_ZPROBE_GFX_REVERSE // Reverses the direction of the CW/CCW indicators +#endif + +// @section extruder + +/** + * Implementation of linear pressure control + * + * Assumption: advance = k * (delta velocity) + * K=0 means advance disabled. + * See Marlin documentation for calibration instructions. + */ +//#define LIN_ADVANCE + +#if ENABLED(LIN_ADVANCE) + #define LIN_ADVANCE_K 75 + + /** + * Some Slicers produce Gcode with randomly jumping extrusion widths occasionally. + * For example within a 0.4mm perimeter it may produce a single segment of 0.05mm width. + * While this is harmless for normal printing (the fluid nature of the filament will + * close this very, very tiny gap), it throws off the LIN_ADVANCE pressure adaption. + * + * For this case LIN_ADVANCE_E_D_RATIO can be used to set the extrusion:distance ratio + * to a fixed value. Note that using a fixed ratio will lead to wrong nozzle pressures + * if the slicer is using variable widths or layer heights within one print! + * + * This option sets the default E:D ratio at startup. Use `M900` to override this value. + * + * Example: `M900 W0.4 H0.2 D1.75`, where: + * - W is the extrusion width in mm + * - H is the layer height in mm + * - D is the filament diameter in mm + * + * Example: `M900 R0.0458` to set the ratio directly. + * + * Set to 0 to auto-detect the ratio based on given Gcode G1 print moves. + * + * Slic3r (including Průša Control) produces Gcode compatible with the automatic mode. + * Cura (as of this writing) may produce Gcode incompatible with the automatic mode. + */ + #define LIN_ADVANCE_E_D_RATIO 0 // The calculated ratio (or 0) according to the formula W * H / ((D / 2) ^ 2 * PI) + // Example: 0.4 * 0.2 / ((1.75 / 2) ^ 2 * PI) = 0.033260135 +#endif + +// @section leveling + +// Default mesh area is an area with an inset margin on the print area. +// Below are the macros that are used to define the borders for the mesh area, +// made available here for specialized needs, ie dual extruder setup. +#if ENABLED(MESH_BED_LEVELING) + #define MESH_MIN_X MESH_INSET + #define MESH_MAX_X (X_BED_SIZE - (MESH_INSET)) + #define MESH_MIN_Y MESH_INSET + #define MESH_MAX_Y (Y_BED_SIZE - (MESH_INSET)) +#elif ENABLED(AUTO_BED_LEVELING_UBL) + #define UBL_MESH_MIN_X UBL_MESH_INSET + #define UBL_MESH_MAX_X (X_BED_SIZE - (UBL_MESH_INSET)) + #define UBL_MESH_MIN_Y UBL_MESH_INSET + #define UBL_MESH_MAX_Y (Y_BED_SIZE - (UBL_MESH_INSET)) + + // If this is defined, the currently active mesh will be saved in the + // current slot on M500. + #define UBL_SAVE_ACTIVE_ON_M500 +#endif + +// @section extras + +// +// G2/G3 Arc Support +// +#define ARC_SUPPORT // Disable this feature to save ~3226 bytes +#if ENABLED(ARC_SUPPORT) + #define MM_PER_ARC_SEGMENT 1 // Length of each arc segment + #define N_ARC_CORRECTION 25 // Number of intertpolated 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 +#endif + +// Support for G5 with XYZE destination and IJPQ offsets. Requires ~2666 bytes. +//#define BEZIER_CURVE_SUPPORT + +// G38.2 and G38.3 Probe Target +// Enable PROBE_DOUBLE_TOUCH if you want G38 to double touch +//#define G38_PROBE_TARGET +#if ENABLED(G38_PROBE_TARGET) + #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) +#endif + +// Moves (or segments) with fewer steps than this will be joined with the next move +#define MIN_STEPS_PER_SEGMENT 6 + +// The minimum pulse width (in µs) for stepping a stepper. +// Set this if you find stepping unreliable, or if using a very fast CPU. +#define MINIMUM_STEPPER_PULSE 0 // (µs) The smallest stepper pulse allowed + +// @section temperature + +// Control heater 0 and heater 1 in parallel. +//#define HEATERS_PARALLEL + +//=========================================================================== +//================================= Buffers ================================= +//=========================================================================== + +// @section hidden + +// 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, i.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 +#else + #define BLOCK_BUFFER_SIZE 16 // maximize block buffer +#endif + +// @section serial + +// The ASCII buffer for serial input +#define MAX_CMD_SIZE 96 +#define BUFSIZE 4 + +// Transmission to Host Buffer Size +// To save 386 bytes of PROGMEM (and TX_BUFFER_SIZE+3 bytes of RAM) set to 0. +// To buffer a simple "ok" you need 4 bytes. +// For ADVANCED_OK (M105) you need 32 bytes. +// For debug-echo: 128 bytes for the optimal speed. +// Other output doesn't need to be that speedy. +// :[0, 2, 4, 8, 16, 32, 64, 128, 256] +#define TX_BUFFER_SIZE 0 + +// 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! +#define EMERGENCY_PARSER + +// Bad Serial-connections can miss a received command by sending an 'ok' +// Therefore some clients abort after 30 seconds in a timeout. +// Some other clients start sending commands while receiving a 'wait'. +// This "wait" is only sent when the buffer is empty. 1 second is a good value here. +//#define NO_TIMEOUTS 1000 // Milliseconds + +// Some clients will have this feature soon. This could make the NO_TIMEOUTS unnecessary. +//#define ADVANCED_OK + +// @section extras + +/** + * Firmware-based and LCD-controlled retract + * + * Add G10 / G11 commands for automatic firmware-based retract / recover. + * Use M207 and M208 to define parameters for retract / recover. + * + * Use M209 to enable or disable auto-retract. + * With auto-retract enabled, all G1 E moves within the set range + * will be converted to firmware-based retract/recover moves. + * + * Be sure to turn off auto-retract during filament change. + * + * Note that M207 / M208 / M209 settings are saved to EEPROM. + * + */ +//#define FWRETRACT // ONLY PARTIALLY TESTED +#if ENABLED(FWRETRACT) + #define MIN_AUTORETRACT 0.1 // When auto-retract is on, convert E moves of this length and over + #define MAX_AUTORETRACT 10.0 // Upper limit for auto-retract conversion + #define RETRACT_LENGTH 3 // Default retract length (positive mm) + #define RETRACT_LENGTH_SWAP 13 // Default swap retract length (positive mm), for extruder change + #define RETRACT_FEEDRATE 45 // Default feedrate for retracting (mm/s) + #define RETRACT_ZLIFT 0 // Default retract Z-lift + #define RETRACT_RECOVER_LENGTH 0 // Default additional recover length (mm, added to retract length when recovering) + #define RETRACT_RECOVER_LENGTH_SWAP 0 // Default additional swap recover length (mm, added to retract length when recovering from extruder change) + #define RETRACT_RECOVER_FEEDRATE 8 // Default feedrate for recovering from retraction (mm/s) + #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) +#endif + +/** + * Advanced Pause + * Experimental feature for filament change support and for parking the nozzle when paused. + * Adds the GCode M600 for initiating filament change. + * If PARK_HEAD_ON_PAUSE enabled, adds the GCode M125 to pause printing and park the nozzle. + * + * Requires an LCD display. + * This feature is required for the default FILAMENT_RUNOUT_SCRIPT. + */ +//#define ADVANCED_PAUSE_FEATURE +#if ENABLED(ADVANCED_PAUSE_FEATURE) + #define PAUSE_PARK_X_POS 3 // X position of hotend + #define PAUSE_PARK_Y_POS 3 // Y position of hotend + #define PAUSE_PARK_Z_ADD 10 // Z addition of hotend (lift) + #define PAUSE_PARK_XY_FEEDRATE 100 // X and Y axes feedrate in mm/s (also used for delta printers Z axis) + #define PAUSE_PARK_Z_FEEDRATE 5 // Z axis feedrate in mm/s (not used for delta printers) + #define PAUSE_PARK_RETRACT_FEEDRATE 60 // Initial retract feedrate in mm/s + #define PAUSE_PARK_RETRACT_LENGTH 2 // Initial retract in mm + // It is a short retract used immediately after print interrupt before move to filament exchange position + #define FILAMENT_CHANGE_UNLOAD_FEEDRATE 10 // Unload filament feedrate in mm/s - filament unloading can be fast + #define FILAMENT_CHANGE_UNLOAD_LENGTH 100 // Unload filament length from hotend in mm + // Longer length for bowden printers to unload filament from whole bowden tube, + // shorter length for printers without bowden to unload filament from extruder only, + // 0 to disable unloading for manual unloading + #define FILAMENT_CHANGE_LOAD_FEEDRATE 6 // Load filament feedrate in mm/s - filament loading into the bowden tube can be fast + #define FILAMENT_CHANGE_LOAD_LENGTH 0 // Load filament length over hotend in mm + // Longer length for bowden printers to fast load filament into whole bowden tube over the hotend, + // Short or zero length for printers without bowden where loading is not used + #define ADVANCED_PAUSE_EXTRUDE_FEEDRATE 3 // Extrude filament feedrate in mm/s - must be slower than load feedrate + #define ADVANCED_PAUSE_EXTRUDE_LENGTH 50 // Extrude filament length in mm after filament is loaded over the hotend, + // 0 to disable for manual extrusion + // Filament can be extruded repeatedly from the filament exchange menu to fill the hotend, + // or until outcoming filament color is not clear for filament color change + #define PAUSE_PARK_NOZZLE_TIMEOUT 45 // Turn off nozzle if user doesn't change filament within this time limit in seconds + #define FILAMENT_CHANGE_NUMBER_OF_ALERT_BEEPS 5 // Number of alert beeps before printer goes quiet + #define PAUSE_PARK_NO_STEPPER_TIMEOUT // Enable to have stepper motors hold position during filament change + // even if it takes longer than DEFAULT_STEPPER_DEACTIVE_TIME. + //#define PARK_HEAD_ON_PAUSE // Go to filament change position on pause, return to print position on resume + //#define HOME_BEFORE_FILAMENT_CHANGE // Ensure homing has been completed prior to parking for filament change +#endif + +// @section tmc + +/** + * Enable this section if you have TMC26X motor drivers. + * You will need to import the TMC26XStepper library into the Arduino IDE for this + * (https://github.com/trinamic/TMC26XStepper.git) + */ +//#define HAVE_TMCDRIVER + +#if ENABLED(HAVE_TMCDRIVER) + + //#define X_IS_TMC + //#define X2_IS_TMC + //#define Y_IS_TMC + //#define Y2_IS_TMC + //#define Z_IS_TMC + //#define Z2_IS_TMC + //#define E0_IS_TMC + //#define E1_IS_TMC + //#define E2_IS_TMC + //#define E3_IS_TMC + //#define E4_IS_TMC + + #define X_MAX_CURRENT 1000 // in mA + #define X_SENSE_RESISTOR 91 // in mOhms + #define X_MICROSTEPS 16 // number of microsteps + + #define X2_MAX_CURRENT 1000 + #define X2_SENSE_RESISTOR 91 + #define X2_MICROSTEPS 16 + + #define Y_MAX_CURRENT 1000 + #define Y_SENSE_RESISTOR 91 + #define Y_MICROSTEPS 16 + + #define Y2_MAX_CURRENT 1000 + #define Y2_SENSE_RESISTOR 91 + #define Y2_MICROSTEPS 16 + + #define Z_MAX_CURRENT 1000 + #define Z_SENSE_RESISTOR 91 + #define Z_MICROSTEPS 16 + + #define Z2_MAX_CURRENT 1000 + #define Z2_SENSE_RESISTOR 91 + #define Z2_MICROSTEPS 16 + + #define E0_MAX_CURRENT 1000 + #define E0_SENSE_RESISTOR 91 + #define E0_MICROSTEPS 16 + + #define E1_MAX_CURRENT 1000 + #define E1_SENSE_RESISTOR 91 + #define E1_MICROSTEPS 16 + + #define E2_MAX_CURRENT 1000 + #define E2_SENSE_RESISTOR 91 + #define E2_MICROSTEPS 16 + + #define E3_MAX_CURRENT 1000 + #define E3_SENSE_RESISTOR 91 + #define E3_MICROSTEPS 16 + + #define E4_MAX_CURRENT 1000 + #define E4_SENSE_RESISTOR 91 + #define E4_MICROSTEPS 16 + +#endif + +// @section TMC2130 + +/** + * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. + * + * You'll also need the TMC2130Stepper Arduino library + * (https://github.com/teemuatlut/TMC2130Stepper). + * + * To use TMC2130 stepper drivers in SPI mode connect your SPI2130 pins to + * the hardware SPI interface on your board and define the required CS pins + * in your `pins_MYBOARD.h` file. (e.g., RAMPS 1.4 uses AUX3 pins `X_CS_PIN 53`, `Y_CS_PIN 49`, etc.). + */ +//#define HAVE_TMC2130 + +#if ENABLED(HAVE_TMC2130) + + // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY + //#define X_IS_TMC2130 + //#define X2_IS_TMC2130 + //#define Y_IS_TMC2130 + //#define Y2_IS_TMC2130 + //#define Z_IS_TMC2130 + //#define Z2_IS_TMC2130 + //#define E0_IS_TMC2130 + //#define E1_IS_TMC2130 + //#define E2_IS_TMC2130 + //#define E3_IS_TMC2130 + //#define E4_IS_TMC2130 + + /** + * Stepper driver settings + */ + + #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 + #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current + #define INTERPOLATE 1 // Interpolate X/Y/Z_MICROSTEPS to 256 + + #define X_CURRENT 1000 // rms current in mA. Multiply by 1.41 for peak current. + #define X_MICROSTEPS 16 // 0..256 + + #define Y_CURRENT 1000 + #define Y_MICROSTEPS 16 + + #define Z_CURRENT 1000 + #define Z_MICROSTEPS 16 + + //#define X2_CURRENT 1000 + //#define X2_MICROSTEPS 16 + + //#define Y2_CURRENT 1000 + //#define Y2_MICROSTEPS 16 + + //#define Z2_CURRENT 1000 + //#define Z2_MICROSTEPS 16 + + //#define E0_CURRENT 1000 + //#define E0_MICROSTEPS 16 + + //#define E1_CURRENT 1000 + //#define E1_MICROSTEPS 16 + + //#define E2_CURRENT 1000 + //#define E2_MICROSTEPS 16 + + //#define E3_CURRENT 1000 + //#define E3_MICROSTEPS 16 + + //#define E4_CURRENT 1000 + //#define E4_MICROSTEPS 16 + + /** + * Use Trinamic's ultra quiet stepping mode. + * When disabled, Marlin will use spreadCycle stepping mode. + */ + #define STEALTHCHOP + + /** + * Let Marlin automatically control stepper current. + * This is still an experimental feature. + * Increase current every 5s by CURRENT_STEP until stepper temperature prewarn gets triggered, + * then decrease current by CURRENT_STEP until temperature prewarn is cleared. + * Adjusting starts from X/Y/Z/E_CURRENT but will not increase over AUTO_ADJUST_MAX + * 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. + * M906 S1 - Start adjusting current + * M906 S0 - Stop adjusting current + * M911 - Report stepper driver overtemperature pre-warn condition. + * M912 - Clear stepper driver overtemperature pre-warn condition flag. + */ + //#define AUTOMATIC_CURRENT_CONTROL + + #if ENABLED(AUTOMATIC_CURRENT_CONTROL) + #define CURRENT_STEP 50 // [mA] + #define AUTO_ADJUST_MAX 1300 // [mA], 1300mA_rms = 1840mA_peak + #define REPORT_CURRENT_CHANGE + #endif + + /** + * The driver will switch to spreadCycle when stepper speed is over HYBRID_THRESHOLD. + * This mode allows for faster movements at the expense of higher noise levels. + * STEALTHCHOP needs to be enabled. + * M913 X/Y/Z/E to live tune the setting + */ + //#define HYBRID_THRESHOLD + + #define X_HYBRID_THRESHOLD 100 // [mm/s] + #define X2_HYBRID_THRESHOLD 100 + #define Y_HYBRID_THRESHOLD 100 + #define Y2_HYBRID_THRESHOLD 100 + #define Z_HYBRID_THRESHOLD 4 + #define Z2_HYBRID_THRESHOLD 4 + #define E0_HYBRID_THRESHOLD 30 + #define E1_HYBRID_THRESHOLD 30 + #define E2_HYBRID_THRESHOLD 30 + #define E3_HYBRID_THRESHOLD 30 + #define E4_HYBRID_THRESHOLD 30 + + /** + * Use stallGuard2 to sense an obstacle and trigger an endstop. + * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. + * If used along with STEALTHCHOP, the movement will be louder when homing. This is normal. + * + * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. + * Higher values make the system LESS sensitive. + * Lower value make the system MORE sensitive. + * Too low values can lead to false positives, while too high values will collide the axis without triggering. + * It is advised to set X/Y_HOME_BUMP_MM to 0. + * M914 X/Y to live tune the setting + */ + //#define SENSORLESS_HOMING + + #if ENABLED(SENSORLESS_HOMING) + #define X_HOMING_SENSITIVITY 19 + #define Y_HOMING_SENSITIVITY 19 + #endif + + /** + * You can set your own advanced settings by filling in predefined functions. + * A list of available functions can be found on the library github page + * https://github.com/teemuatlut/TMC2130Stepper + * + * Example: + * #define TMC2130_ADV() { \ + * stepperX.diag0_temp_prewarn(1); \ + * stepperX.interpolate(0); \ + * } + */ + #define TMC2130_ADV() { } + +#endif // HAVE_TMC2130 + +// @section L6470 + +/** + * Enable this section if you have L6470 motor drivers. + * You need to import the L6470 library into the Arduino IDE for this. + * (https://github.com/ameyer/Arduino-L6470) + */ + +//#define HAVE_L6470DRIVER +#if ENABLED(HAVE_L6470DRIVER) + + //#define X_IS_L6470 + //#define X2_IS_L6470 + //#define Y_IS_L6470 + //#define Y2_IS_L6470 + //#define Z_IS_L6470 + //#define Z2_IS_L6470 + //#define E0_IS_L6470 + //#define E1_IS_L6470 + //#define E2_IS_L6470 + //#define E3_IS_L6470 + //#define E4_IS_L6470 + + #define X_MICROSTEPS 16 // number of microsteps + #define X_K_VAL 50 // 0 - 255, Higher values, are higher power. Be careful not to go too high + #define X_OVERCURRENT 2000 // maxc current in mA. If the current goes over this value, the driver will switch off + #define X_STALLCURRENT 1500 // current in mA where the driver will detect a stall + + #define X2_MICROSTEPS 16 + #define X2_K_VAL 50 + #define X2_OVERCURRENT 2000 + #define X2_STALLCURRENT 1500 + + #define Y_MICROSTEPS 16 + #define Y_K_VAL 50 + #define Y_OVERCURRENT 2000 + #define Y_STALLCURRENT 1500 + + #define Y2_MICROSTEPS 16 + #define Y2_K_VAL 50 + #define Y2_OVERCURRENT 2000 + #define Y2_STALLCURRENT 1500 + + #define Z_MICROSTEPS 16 + #define Z_K_VAL 50 + #define Z_OVERCURRENT 2000 + #define Z_STALLCURRENT 1500 + + #define Z2_MICROSTEPS 16 + #define Z2_K_VAL 50 + #define Z2_OVERCURRENT 2000 + #define Z2_STALLCURRENT 1500 + + #define E0_MICROSTEPS 16 + #define E0_K_VAL 50 + #define E0_OVERCURRENT 2000 + #define E0_STALLCURRENT 1500 + + #define E1_MICROSTEPS 16 + #define E1_K_VAL 50 + #define E1_OVERCURRENT 2000 + #define E1_STALLCURRENT 1500 + + #define E2_MICROSTEPS 16 + #define E2_K_VAL 50 + #define E2_OVERCURRENT 2000 + #define E2_STALLCURRENT 1500 + + #define E3_MICROSTEPS 16 + #define E3_K_VAL 50 + #define E3_OVERCURRENT 2000 + #define E3_STALLCURRENT 1500 + + #define E4_MICROSTEPS 16 + #define E4_K_VAL 50 + #define E4_OVERCURRENT 2000 + #define E4_STALLCURRENT 1500 + +#endif + +/** + * TWI/I2C BUS + * + * This feature is an EXPERIMENTAL feature so it shall not be used on production + * machines. Enabling this will allow you to send and receive I2C data from slave + * devices on the bus. + * + * ; Example #1 + * ; This macro send the string "Marlin" to the slave device with address 0x63 (99) + * ; It uses multiple M260 commands with one B arg + * M260 A99 ; Target slave address + * M260 B77 ; M + * M260 B97 ; a + * M260 B114 ; r + * M260 B108 ; l + * M260 B105 ; i + * M260 B110 ; n + * M260 S1 ; Send the current buffer + * + * ; Example #2 + * ; Request 6 bytes from slave device with address 0x63 (99) + * M261 A99 B5 + * + * ; Example #3 + * ; Example serial output of a M261 request + * echo:i2c-reply: from:99 bytes:5 data:hello + */ + +// @section i2cbus + +//#define EXPERIMENTAL_I2CBUS +#define I2C_SLAVE_ADDRESS 0 // Set a value from 8 to 127 to act as a slave + +// @section extras + +/** + * Spindle & Laser control + * + * Add the M3, M4, and M5 commands to turn the spindle/laser on and off, and + * to set spindle speed, spindle direction, and laser power. + * + * SuperPid is a router/spindle speed controller used in the CNC milling community. + * Marlin can be used to turn the spindle on and off. It can also be used to set + * the spindle speed from 5,000 to 30,000 RPM. + * + * 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. + */ +//#define SPINDLE_LASER_ENABLE +#if ENABLED(SPINDLE_LASER_ENABLE) + + #define SPINDLE_LASER_ENABLE_INVERT false // set to "true" if the on/off function is reversed + #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 // delay in milliseconds to allow the spindle/laser to come up to speed/power + #define SPINDLE_LASER_POWERDOWN_DELAY 5000 // delay in milliseconds to allow the spindle to stop + #define SPINDLE_DIR_CHANGE true // set to true if your spindle controller supports changing spindle direction + #define SPINDLE_INVERT_DIR false + #define SPINDLE_STOP_ON_DIR_CHANGE true // set to true if Marlin should stop the spindle before changing rotation direction + + /** + * The M3 & M4 commands use the following equation to convert PWM duty cycle to speed/power + * + * SPEED/POWER = PWM duty cycle * SPEED_POWER_SLOPE + SPEED_POWER_INTERCEPT + * where PWM duty cycle varies from 0 to 255 + * + * set the following for your controller (ALL MUST BE SET) + */ + + #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_SLOPE 0.3922 + //#define SPEED_POWER_INTERCEPT 0 + //#define SPEED_POWER_MIN 10 + //#define SPEED_POWER_MAX 100 // 0-100% +#endif + +/** + * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins + */ +//#define PINS_DEBUGGING + +/** + * Auto-report temperatures with M155 S + */ +#define AUTO_REPORT_TEMPERATURES + +/** + * Include capabilities in M115 output + */ +#define EXTENDED_CAPABILITIES_REPORT + +/** + * Volumetric extrusion default state + * 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. + */ +//#define VOLUMETRIC_DEFAULT_ON + +/** + * Enable this option for a leaner build of Marlin that removes all + * workspace offsets, simplifying coordinate transformations, leveling, etc. + * + * - M206 and M428 are disabled. + * - G92 will revert to its behavior from Marlin 1.0. + */ +#define NO_WORKSPACE_OFFSETS + +/** + * 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. + * + * For clients that use a fixed-width font (like OctoPrint), leave this set to 1.0. + * Otherwise, adjust according to your client and font. + */ +#define PROPORTIONAL_FONT_RATIO 1.0 + +/** + * Spend 28 bytes of SRAM to optimize the GCode parser + */ +#define FASTER_GCODE_PARSER + +/** + * User-defined menu items that execute custom GCode + */ +//#define CUSTOM_USER_MENUS +#if ENABLED(CUSTOM_USER_MENUS) + #define USER_SCRIPT_DONE "M117 User Script Done" + #define USER_SCRIPT_AUDIBLE_FEEDBACK + //#define USER_SCRIPT_RETURN // Return to status screen after a script + + #define USER_DESC_1 "Home & UBL Info" + #define USER_GCODE_1 "G28\nG29 W" + + #define USER_DESC_2 "Preheat for PLA" + #define USER_GCODE_2 "M140 S" STRINGIFY(PREHEAT_1_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND) + + #define USER_DESC_3 "Preheat for ABS" + #define USER_GCODE_3 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND) + + #define USER_DESC_4 "Heat Bed/Home/Level" + #define USER_GCODE_4 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nG28\nG29" + + #define USER_DESC_5 "Home & Info" + #define USER_GCODE_5 "G28\nM503" +#endif + +/** + * Specify an action command to send to the host when the printer is killed. + * Will be sent in the form '//action:ACTION_ON_KILL', e.g. '//action:poweroff'. + * The host must be configured to handle the action command. + */ +//#define ACTION_ON_KILL "poweroff" + +//=========================================================================== +//====================== I2C Position Encoder Settings ====================== +//=========================================================================== + +/** + * I2C position encoders for closed loop control. + * Developed by Chris Barr at Aus3D. + * + * Wiki: http://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/ + * + * Reilabuild encoders have been modified to improve reliability. + */ + +//#define I2C_POSITION_ENCODERS +#if ENABLED(I2C_POSITION_ENCODERS) + + #define I2CPE_ENCODER_CNT 1 // The number of encoders installed; max of 5 + // encoders supported currently. + + #define I2CPE_ENC_1_ADDR I2CPE_PRESET_ADDR_X // I2C address of the encoder. 30-200. + #define I2CPE_ENC_1_AXIS X_AXIS // Axis the encoder module is installed on. _AXIS. + #define I2CPE_ENC_1_TYPE I2CPE_ENC_TYPE_LINEAR // Type of encoder: I2CPE_ENC_TYPE_LINEAR -or- + // I2CPE_ENC_TYPE_ROTARY. + #define I2CPE_ENC_1_TICKS_UNIT 2048 // 1024 for magnetic strips with 2mm poles; 2048 for + // 1mm poles. For linear encoders this is ticks / mm, + // for rotary encoders this is ticks / revolution. + //#define I2CPE_ENC_1_TICKS_REV (16 * 200) // Only needed for rotary encoders; number of stepper + // steps per full revolution (motor steps/rev * microstepping) + //#define I2CPE_ENC_1_INVERT // Invert the direction of axis travel. + #define I2CPE_ENC_1_EC_METHOD I2CPE_ECM_NONE // Type of error error correction. + #define I2CPE_ENC_1_EC_THRESH 0.10 // Threshold size for error (in mm) above which the + // printer will attempt to correct the error; errors + // smaller than this are ignored to minimize effects of + // measurement noise / latency (filter). + + #define I2CPE_ENC_2_ADDR I2CPE_PRESET_ADDR_Y // Same as above, but for encoder 2. + #define I2CPE_ENC_2_AXIS Y_AXIS + #define I2CPE_ENC_2_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_ENC_2_TICKS_UNIT 2048 + //#define I2CPE_ENC_2_TICKS_REV (16 * 200) + //#define I2CPE_ENC_2_INVERT + #define I2CPE_ENC_2_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_ENC_2_EC_THRESH 0.10 + + #define I2CPE_ENC_3_ADDR I2CPE_PRESET_ADDR_Z // Encoder 3. Add additional configuration options + #define I2CPE_ENC_3_AXIS Z_AXIS // as above, or use defaults below. + + #define I2CPE_ENC_4_ADDR I2CPE_PRESET_ADDR_E // Encoder 4. + #define I2CPE_ENC_4_AXIS E_AXIS + + #define I2CPE_ENC_5_ADDR 34 // Encoder 5. + #define I2CPE_ENC_5_AXIS E_AXIS + + // Default settings for encoders which are enabled, but without settings configured above. + #define I2CPE_DEF_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_DEF_ENC_TICKS_UNIT 2048 + #define I2CPE_DEF_TICKS_REV (16 * 200) + #define I2CPE_DEF_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_DEF_EC_THRESH 0.1 + + //#define I2CPE_ERR_THRESH_ABORT 100.0 // Threshold size for error (in mm) error on any given + // axis after which the printer will abort. Comment out to + // disable abort behaviour. + + #define I2CPE_TIME_TRUSTED 10000 // After an encoder fault, there must be no further fault + // for this amount of time (in ms) before the encoder + // is trusted again. + + /** + * Position is checked every time a new command is executed from the buffer but during long moves, + * this setting determines the minimum update time between checks. A value of 100 works well with + * error rolling average when attempting to correct only for skips and not for vibration. + */ + #define I2CPE_MIN_UPD_TIME_MS 100 // Minimum time in miliseconds between encoder checks. + + // Use a rolling average to identify persistant errors that indicate skips, as opposed to vibration and noise. + #define I2CPE_ERR_ROLLING_AVERAGE + +#endif // I2C_POSITION_ENCODERS + +/** + * MAX7219 Debug Matrix + * + * Add support for a low-cost 8x8 LED Matrix based on the Max7219 chip, which can be used as a status + * display. Requires 3 signal wires. Some useful debug options are included to demonstrate its usage. + * + * Fully assembled MAX7219 boards can be found on the internet for under $2(US). + * For example, see https://www.ebay.com/sch/i.html?_nkw=332349290049 + */ +//#define MAX7219_DEBUG +#if ENABLED(MAX7219_DEBUG) + #define MAX7219_CLK_PIN 64 // 77 on Re-ARM // Configuration of the 3 pins to control the display + #define MAX7219_DIN_PIN 57 // 78 on Re-ARM + #define MAX7219_LOAD_PIN 44 // 79 on Re-ARM + + /** + * Sample debug features + * If you add more debug displays, be careful to avoid conflicts! + */ + #define MAX7219_DEBUG_PRINTER_ALIVE // Blink corner LED of 8x8 matrix to show that the firmware is functioning + #define MAX7219_DEBUG_STEPPER_HEAD 3 // Show the stepper queue head position on this and the next LED matrix row + #define MAX7219_DEBUG_STEPPER_TAIL 5 // Show the stepper queue tail position on this and the next LED matrix row + + #define MAX7219_DEBUG_STEPPER_QUEUE 0 // Show the current stepper queue depth on this and the next LED matrix row + // If you experience stuttering, reboots, etc. this option can reveal how + // tweaks made to the configuration are affecting the printer in real-time. +#endif + +#endif // CONFIGURATION_ADV_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/TinyBoy2/Configuration.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/TinyBoy2/Configuration.h new file mode 100644 index 00000000..2bfc23e5 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/TinyBoy2/Configuration.h @@ -0,0 +1,1756 @@ +/** + * 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 . + * + */ + +/** + * Configuration.h + * + * Basic settings such as: + * + * - Type of electronics + * - Type of temperature sensor + * - Printer geometry + * - Endstop configuration + * - LCD controller + * - Extra features + * + * Advanced settings can be found in Configuration_adv.h + * + */ +#ifndef CONFIGURATION_H +#define CONFIGURATION_H +#define CONFIGURATION_H_VERSION 010100 + +/** + * Sample configuration file for TinyBoy2 L10/L16 + * + * Compile from Arduino or using make: + * + * ARDUINO_INSTALL_DIR=/usr/share/java/Arduino-1.6.13/ \ + * HARDWARE_MOTHERBOARD=66 \ + * PATH=/usr/avr/bin/:$PATH make + * + * Please choose your hardware options for the TinyBoy2: + */ + +#define TB2_L10 +//#define TB2_L16 +#define TB2_HEATBED_MOD + +//=========================================================================== +//============================= Getting Started ============================= +//=========================================================================== + +/** + * Here are some standard links for getting your machine calibrated: + * + * http://reprap.org/wiki/Calibration + * http://youtu.be/wAL9d7FgInk + * http://calculator.josefprusa.cz + * http://reprap.org/wiki/Triffid_Hunter%27s_Calibration_Guide + * http://www.thingiverse.com/thing:5573 + * https://sites.google.com/site/repraplogphase/calibration-of-your-reprap + * http://www.thingiverse.com/thing:298812 + */ + +//=========================================================================== +//============================= DELTA Printer =============================== +//=========================================================================== +// For a Delta printer start with one of the configuration files in the +// example_configurations/delta directory and customize for your machine. +// + +//=========================================================================== +//============================= SCARA Printer =============================== +//=========================================================================== +// For a SCARA printer start with the configuration files in +// example_configurations/SCARA and customize for your machine. +// + +// @section info + +// User-specified version info of this build to display in [Pronterface, etc] terminal window during +// startup. Implementation of an idea by Prof Braino to inform user that any changes made to this +// build by the user have been successfully uploaded into firmware. +#define STRING_CONFIG_H_AUTHOR "(StefanB, TinyBoy2)" // Who made the changes. +#define SHOW_BOOTSCREEN +#define STRING_SPLASH_LINE1 SHORT_BUILD_VERSION // will be shown during bootup in line 1 +#define STRING_SPLASH_LINE2 WEBSITE_URL // will be shown during bootup in line 2 + +// +// *** VENDORS PLEASE READ ***************************************************** +// +// Marlin now allow you to have a vendor boot image to be displayed on machine +// start. When SHOW_CUSTOM_BOOTSCREEN is defined Marlin will first show your +// custom boot image and then the default Marlin boot image is shown. +// +// We suggest for you to take advantage of this new feature and keep the Marlin +// boot image unmodified. For an example have a look at the bq Hephestos 2 +// example configuration folder. +// +//#define SHOW_CUSTOM_BOOTSCREEN +// @section machine + +/** + * Select which serial port on the board will be used for communication with the host. + * This allows the connection of wireless adapters (for instance) to non-default port pins. + * Serial port 0 is always used by the Arduino bootloader regardless of this setting. + * + * :[0, 1, 2, 3, 4, 5, 6, 7] + */ +#define SERIAL_PORT 0 + +/** + * This setting determines the communication speed of the printer. + * + * 250000 works in most cases, but you might try a lower speed if + * you commonly experience drop-outs during host printing. + * You may try up to 1000000 to speed up SD file transfer. + * + * :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000] + */ +#define BAUDRATE 115200 + +// Enable the Bluetooth serial interface on AT90USB devices +//#define BLUETOOTH + +// The following define selects which electronics board you have. +// Please choose the name from boards.h that matches your setup +#ifndef MOTHERBOARD + #define MOTHERBOARD BOARD_MELZI +#endif + +// Optional custom name for your RepStrap or other custom machine +// Displayed in the LCD "Ready" message +#if ENABLED(TB2_L10) + #define CUSTOM_MACHINE_NAME "TinyBoy2 L10" +#elif ENABLED(TB2_L16) + #define CUSTOM_MACHINE_NAME "TinyBoy2 L16" +#else + #error "Please select TB2_L10 or TB2_L16" +#endif + +// Define this to set a unique identifier for this printer, (Used by some programs to differentiate between machines) +// You can use an online service to generate a random UUID. (eg http://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] +#define EXTRUDERS 1 + +// For Cyclops or any "multi-extruder" that shares a single nozzle. +//#define SINGLENOZZLE + +/** + * Průša MK2 Single Nozzle Multi-Material Multiplexer, and variants. + * + * This device allows one stepper driver on a control board to drive + * two to eight stepper motors, one at a time, in a manner suitable + * for extruders. + * + * This option only allows the multiplexer to switch on tool-change. + * Additional options to configure custom E moves are pending. + */ +//#define MK2_MULTIPLEXER +#if ENABLED(MK2_MULTIPLEXER) + // Override the default DIO selector pins here, if needed. + // Some pins files may provide defaults for these pins. + //#define E_MUX0_PIN 40 // Always Required + //#define E_MUX1_PIN 42 // Needed for 3 to 8 steppers + //#define E_MUX2_PIN 44 // Needed for 5 to 8 steppers +#endif + +// A dual extruder that uses a single stepper motor +//#define SWITCHING_EXTRUDER +#if ENABLED(SWITCHING_EXTRUDER) + #define SWITCHING_EXTRUDER_SERVO_NR 0 + #define SWITCHING_EXTRUDER_SERVO_ANGLES { 0, 90 } // Angles for E0, E1[, E2, E3] + #if EXTRUDERS > 3 + #define SWITCHING_EXTRUDER_E23_SERVO_NR 1 + #endif +#endif + +// A dual-nozzle that uses a servomotor to raise/lower one of the nozzles +//#define SWITCHING_NOZZLE +#if ENABLED(SWITCHING_NOZZLE) + #define SWITCHING_NOZZLE_SERVO_NR 0 + #define SWITCHING_NOZZLE_SERVO_ANGLES { 0, 90 } // Angles for E0, E1 + //#define HOTEND_OFFSET_Z { 0.0, 0.0 } +#endif + +/** + * Two separate X-carriages with extruders that connect to a moving part + * via a magnetic docking mechanism. Requires SOL1_PIN and SOL2_PIN. + */ +//#define PARKING_EXTRUDER +#if ENABLED(PARKING_EXTRUDER) + #define PARKING_EXTRUDER_SOLENOIDS_INVERT // If enabled, the solenoid is NOT magnetized with applied voltage + #define PARKING_EXTRUDER_SOLENOIDS_PINS_ACTIVE LOW // LOW or HIGH pin signal energizes the coil + #define PARKING_EXTRUDER_SOLENOIDS_DELAY 250 // Delay (ms) for magnetic field. No delay if 0 or not defined. + #define PARKING_EXTRUDER_PARKING_X { -78, 184 } // X positions for parking the extruders + #define PARKING_EXTRUDER_GRAB_DISTANCE 1 // mm to move beyond the parking point to grab the extruder + #define PARKING_EXTRUDER_SECURITY_RAISE 5 // Z-raise before parking + #define HOTEND_OFFSET_Z { 0.0, 1.3 } // Z-offsets of the two hotends. The first must be 0. +#endif + +/** + * "Mixing Extruder" + * - Adds a new code, M165, to set the current mix factors. + * - Extends the stepping routines to move multiple steppers in proportion to the mix. + * - Optional support for Repetier Firmware M163, M164, and virtual extruder. + * - This implementation supports only a single extruder. + * - Enable DIRECT_MIXING_IN_G1 for Pia Taubert's reference implementation + */ +//#define MIXING_EXTRUDER +#if ENABLED(MIXING_EXTRUDER) + #define MIXING_STEPPERS 2 // Number of steppers in your mixing extruder + #define MIXING_VIRTUAL_TOOLS 16 // Use the Virtual Tool method with M163 and M164 + //#define DIRECT_MIXING_IN_G1 // Allow ABCDHI mix factors in G1 movement commands +#endif + +// Offset of the extruders (uncomment if using more than one and relying on firmware to position when changing). +// The offset has to be X=0, Y=0 for the extruder 0 hotend (default extruder). +// For the other hotends it is their distance from the extruder 0 hotend. +//#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis +//#define HOTEND_OFFSET_Y {0.0, 5.00} // (in mm) for each extruder, offset of the hotend on the Y axis + +// @section machine + +/** + * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN + * + * 0 = No Power Switch + * 1 = ATX + * 2 = X-Box 360 203Watts (the blue wire connected to PS_ON and the red wire to VCC) + * + * :{ 0:'No power switch', 1:'ATX', 2:'X-Box 360' } + */ +#define POWER_SUPPLY 0 + +#if POWER_SUPPLY > 0 + // Enable this option to leave the PSU off at startup. + // Power to steppers and heaters will need to be turned on with M80. + //#define PS_DEFAULT_OFF +#endif + +// @section temperature + +//=========================================================================== +//============================= Thermal Settings ============================ +//=========================================================================== + +/** + * --NORMAL IS 4.7kohm PULLUP!-- 1kohm pullup can be used on hotend sensor, using correct resistor and table + * + * Temperature sensors available: + * + * -3 : thermocouple with MAX31855 (only for sensor 0) + * -2 : thermocouple with MAX6675 (only for sensor 0) + * -1 : thermocouple with AD595 + * 0 : not used + * 1 : 100k thermistor - best choice for EPCOS 100k (4.7k pullup) + * 2 : 200k thermistor - ATC Semitec 204GT-2 (4.7k pullup) + * 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 (Used in ParCan & J-Head) (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) + * 71 : 100k Honeywell thermistor 135-104LAF-J01 (4.7k pullup) + * 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) + * 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" + * 20 : the PT100 circuit found in the Ultimainboard V2.x + * 60 : 100k Maker's Tool Works Kapton Bed Thermistor beta=3950 + * 66 : 4.7M High Temperature thermistor from Dyze Design + * 70 : the 100K thermistor found in the bq Hephestos 2 + * 75 : 100k Generic Silicon Heat Pad with NTC 100K MGB18-104F39050L32 thermistor + * + * 1k ohm pullup tables - This is atypical, and requires changing out the 4.7k pullup for 1k. + * (but gives greater accuracy and more stable PID) + * 51 : 100k thermistor - EPCOS (1k pullup) + * 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 + * 1010 : Pt1000 with 1k pullup (non standard) + * 147 : Pt100 with 4k7 pullup + * 110 : Pt100 with 1k pullup (non standard) + * + * Use these for Testing or Development purposes. NEVER for production machine. + * 998 : Dummy Table that ALWAYS reads 25°C or the temperature defined below. + * 999 : Dummy Table that ALWAYS reads 100°C or the temperature defined below. + * + * :{ '0': "Not used", '1':"100k / 4.7k - EPCOS", '2':"200k / 4.7k - ATC Semitec 204GT-2", '3':"Mendel-parts / 4.7k", '4':"10k !! do not use for a hotend. Bad resolution at high temp. !!", '5':"100K / 4.7k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '6':"100k / 4.7k EPCOS - Not as accurate as Table 1", '7':"100k / 4.7k Honeywell 135-104LAG-J01", '8':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT", '9':"100k / 4.7k GE Sensing AL03006-58.2K-97-G1", '10':"100k / 4.7k RS 198-961", '11':"100k / 4.7k beta 3950 1%", '12':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT (calibrated for Makibox hot bed)", '13':"100k Hisens 3950 1% up to 300°C for hotend 'Simple ONE ' & hotend 'All In ONE'", '20':"PT100 (Ultimainboard V2.x)", '51':"100k / 1k - EPCOS", '52':"200k / 1k - ATC Semitec 204GT-2", '55':"100k / 1k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '60':"100k Maker's Tool Works Kapton Bed Thermistor beta=3950", '66':"Dyze Design 4.7M High Temperature thermistor", '70':"the 100K thermistor found in the bq Hephestos 2", '71':"100k / 4.7k Honeywell 135-104LAF-J01", '147':"Pt100 / 4.7k", '1047':"Pt1000 / 4.7k", '110':"Pt100 / 1k (non-standard)", '1010':"Pt1000 / 1k (non standard)", '-3':"Thermocouple + MAX31855 (only for sensor 0)", '-2':"Thermocouple + MAX6675 (only for sensor 0)", '-1':"Thermocouple + AD595",'998':"Dummy 1", '999':"Dummy 2" } + */ +#define TEMP_SENSOR_0 5 +#define TEMP_SENSOR_1 0 +#define TEMP_SENSOR_2 0 +#define TEMP_SENSOR_3 0 +#define TEMP_SENSOR_4 0 +#if ENABLED(TB2_HEATBED_MOD) + // K8200 Heatbed 1206/100k/3950K spare part + #define TEMP_SENSOR_BED 7 +#else + #define TEMP_SENSOR_BED 0 +#endif + +// Dummy thermistor constant temperature readings, for use with 998 and 999 +#define DUMMY_THERMISTOR_998_VALUE 25 +#define DUMMY_THERMISTOR_999_VALUE 100 + +// 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 +#define MAX_REDUNDANT_TEMP_SENSOR_DIFF 10 + +// Extruder temperature must be close to target for this long before M109 returns success +#define TEMP_RESIDENCY_TIME 10 // (seconds) +#define TEMP_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// Bed temperature must be close to target for this long before M190 returns success +#define TEMP_BED_RESIDENCY_TIME 10 // (seconds) +#define TEMP_BED_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_BED_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// The minimal temperature defines the temperature below which the heater will not be enabled It is used +// to check that the wiring to the thermistor is not broken. +// Otherwise this would lead to the heater being powered on all the time. +#define HEATER_0_MINTEMP 5 +#define HEATER_1_MINTEMP 5 +#define HEATER_2_MINTEMP 5 +#define HEATER_3_MINTEMP 5 +#define HEATER_4_MINTEMP 5 +#define BED_MINTEMP 5 + +// When temperature exceeds max temp, your heater will be switched off. +// This feature exists to protect your hotend from overheating accidentally, but *NOT* from thermistor short/failure! +// You should use MINTEMP for thermistor short/failure protection. +#define HEATER_0_MAXTEMP 250 +#define HEATER_1_MAXTEMP 275 +#define HEATER_2_MAXTEMP 275 +#define HEATER_3_MAXTEMP 275 +#define HEATER_4_MAXTEMP 275 +#define BED_MAXTEMP 100 + +//=========================================================================== +//============================= PID Settings ================================ +//=========================================================================== +// PID Tuning Guide here: http://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 +#if ENABLED(PIDTEMP) + //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. + //#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. + #define K1 0.95 //smoothing factor within the PID + + // 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 + + // TinyBoy2 Extruder - calculated with PID Autotune and tested + // "M303 E0 C8 S200" + //#define DEFAULT_Kp 25.63 + //#define DEFAULT_Ki 2.66 + //#define DEFAULT_Kd 61.73 + + // TinyBoy2 Extruder - same, but with fan @ 25% duty + #define DEFAULT_Kp 26.15 + #define DEFAULT_Ki 2.71 + #define DEFAULT_Kd 63.02 +#endif // PIDTEMP + +//=========================================================================== +//============================= PID > Bed Temperature Control =============== +//=========================================================================== +// Select PID or bang-bang with PIDTEMPBED. If bang-bang, BED_LIMIT_SWITCHING will enable hysteresis +// +// Uncomment this to enable PID on the bed. It uses the same frequency PWM as the extruder. +// If your PID_dT is the default, and correct for your hardware/configuration, that means 7.689Hz, +// which is fine for driving a square wave into a resistive load and does not significantly impact you FET heating. +// This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W heater. +// If your configuration is significantly different than this and you don't understand the issues involved, you probably +// shouldn't use bed PID until someone else verifies your hardware works. +// If this is enabled, find your own PID constants below. +#define PIDTEMPBED + +//#define BED_LIMIT_SWITCHING + +// This sets the max power delivered to the bed, and replaces the HEATER_BED_DUTY_CYCLE_DIVIDER option. +// all forms of bed control obey this (PID, bang-bang, bang-bang with hysteresis) +// setting this to anything other than 255 enables a form of PWM to the bed just like HEATER_BED_DUTY_CYCLE_DIVIDER did, +// so you shouldn't use it unless you are OK with PWM on your bed. (see the comment on enabling PIDTEMPBED) +#define MAX_BED_POWER 255 // limits duty cycle to bed; 255=full current + +#if ENABLED(PIDTEMPBED) + + //#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) + //#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. + + // TinyBoy2 heatbed - calculated with PID Autotune and tested + // "M303 E-1 C8 S75" + //#define DEFAULT_bedKp 421.80 + //#define DEFAULT_bedKi 82.51 + //#define DEFAULT_bedKd 539.06 + + // TinyBoy2 heatbed - same, but with fan @ 25% duty + // "M303 E-1 C8 S75" + #define DEFAULT_bedKp 267.54 + #define DEFAULT_bedKi 52.34 + #define DEFAULT_bedKd 341.92 + +#endif // PIDTEMPBED + +// @section extruder + +// This option prevents extrusion if the temperature is below EXTRUDE_MINTEMP. +// It also enables the M302 command to set the minimum extrusion temperature +// or to allow moving the extruder regardless of the hotend temperature. +// *** IT IS HIGHLY RECOMMENDED TO LEAVE THIS OPTION ENABLED! *** +#define PREVENT_COLD_EXTRUSION +#define EXTRUDE_MINTEMP 170 + +// This option prevents a single extrusion longer than EXTRUDE_MAXLENGTH. +// Note that for Bowden Extruders a too-small value here may prevent loading. +#define PREVENT_LENGTHY_EXTRUDE +#define EXTRUDE_MAXLENGTH 200 + +//=========================================================================== +//======================== Thermal Runaway Protection ======================= +//=========================================================================== + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * If you get "Thermal Runaway" or "Heating failed" errors the + * details can be tuned in Configuration_adv.h + */ + +#define THERMAL_PROTECTION_HOTENDS // Enable thermal protection for all extruders +#define THERMAL_PROTECTION_BED // Enable thermal protection for the heated bed + +//=========================================================================== +//============================= Mechanical Settings ========================= +//=========================================================================== + +// @section machine + +// Uncomment one of these options to enable CoreXY, CoreXZ, or CoreYZ kinematics +// either in the usual order or reversed +//#define COREXY +//#define COREXZ +//#define COREYZ +//#define COREYX +//#define COREZX +//#define COREZY + +//=========================================================================== +//============================== Endstop Settings =========================== +//=========================================================================== + +// @section homing + +// Specify here all the endstop connectors that are connected to any endstop or probe. +// Almost all printers will be using one per axis. Probes will use one or more of the +// extra connectors. Leave undefined any used for non-endstop and non-probe purposes. +// TB2 has X endstop on max, see also INVERT_X_DIR and X_HOME_DIR +//#define USE_XMIN_PLUG +#define USE_YMIN_PLUG +#define USE_ZMIN_PLUG +#define USE_XMAX_PLUG +//#define USE_YMAX_PLUG +//#define USE_ZMAX_PLUG + +// coarse Endstop Settings +#define ENDSTOPPULLUPS // Comment this out (using // at the start of the line) to disable the endstop pullup resistors + +#if DISABLED(ENDSTOPPULLUPS) + // fine endstop settings: Individual pullups. will be ignored if ENDSTOPPULLUPS is defined + //#define ENDSTOPPULLUP_XMAX + //#define ENDSTOPPULLUP_YMAX + //#define ENDSTOPPULLUP_ZMAX + //#define ENDSTOPPULLUP_XMIN + //#define ENDSTOPPULLUP_YMIN + //#define ENDSTOPPULLUP_ZMIN + //#define ENDSTOPPULLUP_ZMIN_PROBE +#endif + +// Mechanical endstop with COM to ground and NC to Signal uses "false" here (most common setup). +#define X_MIN_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Y_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define X_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Y_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MIN_PROBE_ENDSTOP_INVERTING false // set to true to invert the logic of the probe. + +// Enable this feature if all enabled endstop pins are interrupt-capable. +// This will remove the need to poll the interrupt pins, saving many CPU cycles. +#define ENDSTOP_INTERRUPTS_FEATURE + +//============================================================================= +//============================== Movement Settings ============================ +//============================================================================= +// @section motion + +/** + * Default Settings + * + * These settings can be reset by M502 + * + * Note that if EEPROM is enabled, saved values will override these. + */ + +/** + * With this option each E stepper can have its own factors for the + * following movement settings. If fewer factors are given than the + * total number of extruders, the last value applies to the rest. + */ +//#define DISTINCT_E_FACTORS + +/** + * Default Axis Steps Per Unit (steps/mm) + * Override with M92 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_AXIS_STEPS_PER_UNIT { 100, 100, 6400, 88.16 } + +/** + * Default Max Feed Rate (mm/s) + * Override with M203 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_FEEDRATE { 300, 300, 7, 35 } + +/** + * Default Max Acceleration (change/s) change = mm/s + * (Maximum start speed for accelerated moves) + * Override with M201 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_ACCELERATION { 3000, 3000, 100, 10000 } + +/** + * Default Acceleration (change/s) change = mm/s + * Override with M204 + * + * M204 P Acceleration + * M204 R Retract Acceleration + * M204 T Travel Acceleration + */ +#define DEFAULT_ACCELERATION 3000 // X, Y, Z and E acceleration for printing moves +#define DEFAULT_RETRACT_ACCELERATION 3000 // E acceleration for retracts +#define DEFAULT_TRAVEL_ACCELERATION 3000 // X, Y, Z acceleration for travel (non printing) moves + +/** + * Default Jerk (mm/s) + * Override with M205 X Y Z E + * + * "Jerk" specifies the minimum speed change that requires acceleration. + * When changing speed and direction, if the difference is less than the + * value set here, it may happen instantaneously. + */ +#define DEFAULT_XJERK 20.0 +#define DEFAULT_YJERK 20.0 +#define DEFAULT_ZJERK 0.4 +#define DEFAULT_EJERK 5.0 + +//=========================================================================== +//============================= Z Probe Options ============================= +//=========================================================================== +// @section probes + +// +// See http://marlinfw.org/configuration/probes.html +// + +/** + * Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + * + * Enable this option for a probe connected to the Z Min endstop pin. + */ +#define Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + +/** + * Z_MIN_PROBE_ENDSTOP + * + * Enable this option for a probe connected to any pin except Z-Min. + * (By default Marlin assumes the Z-Max endstop pin.) + * To use a custom Z Probe pin, set Z_MIN_PROBE_PIN below. + * + * - The simplest option is to use a free endstop connector. + * - Use 5V for powered (usually inductive) sensors. + * + * - RAMPS 1.3/1.4 boards may use the 5V, GND, and Aux4->D32 pin: + * - For simple switches connect... + * - normally-closed switches to GND and D32. + * - normally-open switches to 5V and D32. + * + * WARNING: Setting the wrong pin may have unexpected and potentially + * disastrous consequences. Use with caution and do your homework. + * + */ +//#define Z_MIN_PROBE_ENDSTOP + +/** + * Probe Type + * + * Allen Key Probes, Servo Probes, Z-Sled Probes, FIX_MOUNTED_PROBE, etc. + * Activate one of these to use Auto Bed Leveling below. + */ + +/** + * The "Manual Probe" provides a means to do "Auto" Bed Leveling without a probe. + * Use G29 repeatedly, adjusting the Z height at each point with movement commands + * or (with LCD_BED_LEVELING) the LCD controller. + */ +//#define PROBE_MANUALLY + +/** + * A Fix-Mounted Probe either doesn't deploy or needs manual deployment. + * (e.g., an inductive probe or a nozzle-based probe-switch.) + */ +//#define FIX_MOUNTED_PROBE + +/** + * Z Servo Probe, such as an endstop switch on a rotating arm. + */ +//#define Z_ENDSTOP_SERVO_NR 0 // Defaults to SERVO 0 connector. +//#define Z_SERVO_ANGLES {70,0} // Z Servo Deploy and Stow angles + +/** + * The BLTouch probe uses a Hall effect sensor and emulates a servo. + */ +//#define BLTOUCH +#if ENABLED(BLTOUCH) + //#define BLTOUCH_DELAY 375 // (ms) Enable and increase if needed +#endif + +/** + * Enable one or more of the following if probing seems unreliable. + * Heaters and/or fans can be disabled during probing to minimize electrical + * noise. A delay can also be added to allow noise and vibration to settle. + * These options are most useful for the BLTouch probe, but may also improve + * readings with inductive probes and piezo sensors. + */ +//#define PROBING_HEATERS_OFF // Turn heaters off when probing +//#define PROBING_FANS_OFF // Turn fans off when probing +//#define DELAY_BEFORE_PROBING 200 // (ms) To prevent vibrations from triggering piezo sensors + +// A probe that is deployed and stowed with a solenoid pin (SOL1_PIN) +//#define SOLENOID_PROBE + +// A sled-mounted probe like those designed by Charles Bell. +//#define Z_PROBE_SLED +//#define SLED_DOCKING_OFFSET 5 // The extra distance the X axis must travel to pickup the sled. 0 should be fine but you can push it further if you'd like. + +// +// For Z_PROBE_ALLEN_KEY see the Delta example configurations. +// + +/** + * Z Probe to nozzle (X,Y) offset, relative to (0, 0). + * X and Y offsets must be integers. + * + * In the following example the X and Y offsets are both positive: + * #define X_PROBE_OFFSET_FROM_EXTRUDER 10 + * #define Y_PROBE_OFFSET_FROM_EXTRUDER 10 + * + * +-- BACK ---+ + * | | + * L | (+) P | R <-- probe (20,20) + * E | | I + * F | (-) N (+) | G <-- nozzle (10,10) + * T | | H + * | (-) | T + * | | + * O-- FRONT --+ + * (0,0) + */ +#define X_PROBE_OFFSET_FROM_EXTRUDER 34 // X offset: -left +right [of the nozzle] +#define Y_PROBE_OFFSET_FROM_EXTRUDER 15 // Y offset: -front +behind [the nozzle] +#define Z_PROBE_OFFSET_FROM_EXTRUDER 0 // Z offset: -below +above [the nozzle] + +// X and Y axis travel speed (mm/m) between probes +#define XY_PROBE_SPEED 8000 + +// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +#define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z + +// Speed for the "accurate" probe of each point +#define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) + +// Use double touch for probing +//#define PROBE_DOUBLE_TOUCH + +/** + * Z probes require clearance when deploying, stowing, and moving between + * probe points to avoid hitting the bed and other hardware. + * Servo-mounted probes require extra space for the arm to rotate. + * Inductive probes need space to keep from triggering early. + * + * Use these settings to specify the distance (mm) to raise the probe (or + * lower the bed). The values set here apply over and above any (negative) + * probe Z Offset set with Z_PROBE_OFFSET_FROM_EXTRUDER, M851, or the LCD. + * Only integer values >= 1 are valid here. + * + * Example: `M851 Z-5` with a CLEARANCE of 4 => 9mm from bed to nozzle. + * But: `M851 Z+1` with a CLEARANCE of 2 => 2mm from bed to nozzle. + */ +#define Z_CLEARANCE_DEPLOY_PROBE 10 // Z Clearance for Deploy/Stow +#define Z_CLEARANCE_BETWEEN_PROBES 5 // Z Clearance between probe points + +// For M851 give a range for adjusting the Z probe offset +#define Z_PROBE_OFFSET_RANGE_MIN -20 +#define Z_PROBE_OFFSET_RANGE_MAX 20 + +// Enable the M48 repeatability test to test probe accuracy +//#define Z_MIN_PROBE_REPEATABILITY_TEST + +// For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1 +// :{ 0:'Low', 1:'High' } +#define X_ENABLE_ON 0 +#define Y_ENABLE_ON 0 +#define Z_ENABLE_ON 0 +#define E_ENABLE_ON 0 // For all extruders + +// Disables axis stepper immediately when it's not being used. +// 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 +//#define DISABLE_REDUCED_ACCURACY_WARNING + +// @section extruder + +#define DISABLE_E false // For all extruders +#define DISABLE_INACTIVE_EXTRUDER true // Keep only the active extruder enabled. + +// @section machine + +// Invert the stepper direction. Change (or reverse the motor connector) if an axis goes the wrong way. +#define INVERT_X_DIR true +#define INVERT_Y_DIR false +#define INVERT_Z_DIR false + +// Enable this option for Toshiba steppers +//#define CONFIG_STEPPERS_TOSHIBA + +// @section extruder + +// For direct drive extruder v9 set to true, for geared extruder set to false. +#define INVERT_E0_DIR true +#define INVERT_E1_DIR false +#define INVERT_E2_DIR false +#define INVERT_E3_DIR false +#define INVERT_E4_DIR false + +// @section homing + +//#define NO_MOTION_BEFORE_HOMING // Inhibit movement until all axes have been homed + +//#define Z_HOMING_HEIGHT 4 // (in mm) Minimal z height before homing (G28) for Z clearance above the bed, clamps, ... + // Be sure you have this distance over your Z_MAX_POS in case. + +// Direction of endstops when homing; 1=MAX, -1=MIN +// :[-1,1] +#define X_HOME_DIR 1 +#define Y_HOME_DIR -1 +#define Z_HOME_DIR -1 + +// @section machine + +// The size of the print bed +// Tinyboy2: 100mm are marketed, actual length between endstop and end of rail is 98mm +#define X_BED_SIZE 98 +#define Y_BED_SIZE 98 + +// Travel limits (mm) after homing, corresponding to endstop positions. +#define X_MIN_POS 0 +#define Y_MIN_POS 0 +#define Z_MIN_POS 0 +#define X_MAX_POS X_BED_SIZE +#define Y_MAX_POS Y_BED_SIZE +#if ENABLED(TB2_L10) + #define Z_MAX_POS 98 +#else + #define Z_MAX_POS 158 +#endif + +// If enabled, axes won't move below MIN_POS in response to movement commands. +#define MIN_SOFTWARE_ENDSTOPS +// If enabled, axes won't move above MAX_POS in response to movement commands. +#define MAX_SOFTWARE_ENDSTOPS + +/** + * Filament Runout Sensor + * A mechanical or opto endstop is used to check for the presence of filament. + * + * RAMPS-based boards use SERVO3_PIN. + * For other boards you may need to define FIL_RUNOUT_PIN. + * By default the firmware assumes HIGH = has filament, LOW = ran out + */ +//#define FILAMENT_RUNOUT_SENSOR +#if ENABLED(FILAMENT_RUNOUT_SENSOR) + #define FIL_RUNOUT_INVERTING false // set to true to invert the logic of the sensor. + #define ENDSTOPPULLUP_FIL_RUNOUT // Uncomment to use internal pullup for filament runout pins if the sensor is defined. + #define FILAMENT_RUNOUT_SCRIPT "M600" +#endif + +//=========================================================================== +//=============================== Bed Leveling ============================== +//=========================================================================== +// @section bedlevel + +/** + * Choose one of the options below to enable G29 Bed Leveling. The parameters + * and behavior of G29 will change depending on your selection. + * + * If using a Probe for Z Homing, enable Z_SAFE_HOMING also! + * + * - AUTO_BED_LEVELING_3POINT + * Probe 3 arbitrary points on the bed (that aren't collinear) + * You specify the XY coordinates of all 3 points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_LINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_BILINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a mesh, best for large or uneven beds. + * + * - AUTO_BED_LEVELING_UBL (Unified Bed Leveling) + * A comprehensive bed leveling system combining the features and benefits + * of other systems. UBL also includes integrated Mesh Generation, Mesh + * Validation and Mesh Editing systems. Currently, UBL is only checked out + * for Cartesian Printers. That said, it was primarily designed to correct + * poor quality Delta Printers. If you feel adventurous and have a Delta, + * please post an issue if something doesn't work correctly. Initially, + * you will need to set a reduced bed size so you have a rectangular area + * to test on. + * + * - MESH_BED_LEVELING + * Probe a grid manually + * The result is a mesh, suitable for large or uneven beds. (See BILINEAR.) + * For machines without a probe, Mesh Bed Leveling provides a method to perform + * leveling in steps so you can manually adjust the Z height at each grid-point. + * With an LCD controller the process is guided step-by-step. + */ +//#define AUTO_BED_LEVELING_3POINT +//#define AUTO_BED_LEVELING_LINEAR +//#define AUTO_BED_LEVELING_BILINEAR +//#define AUTO_BED_LEVELING_UBL +//#define MESH_BED_LEVELING + +/** + * Enable detailed logging of G28, G29, M48, etc. + * Turn on with the command 'M111 S32'. + * NOTE: Requires a lot of PROGMEM! + */ +//#define DEBUG_LEVELING_FEATURE + +#if ENABLED(MESH_BED_LEVELING) || ENABLED(AUTO_BED_LEVELING_BILINEAR) || ENABLED(AUTO_BED_LEVELING_UBL) + // Gradually reduce leveling correction until a set height is reached, + // at which point movement will be level to the machine's XY plane. + // The height can be set with M420 Z + #define ENABLE_LEVELING_FADE_HEIGHT +#endif + +#if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Set the number of grid points per dimension. + #define GRID_MAX_POINTS_X 3 + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + // Set the boundaries for probing (where the probe can reach). + #define LEFT_PROBE_BED_POSITION 15 + #define RIGHT_PROBE_BED_POSITION 170 + #define FRONT_PROBE_BED_POSITION 20 + #define BACK_PROBE_BED_POSITION 170 + + // The Z probe minimum outer margin (to validate G29 parameters). + #define MIN_PROBE_EDGE 10 + + // Probe along the Y axis, advancing X after each column + //#define PROBE_Y_FIRST + + #if ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Beyond the probed grid, continue the implied tilt? + // Default is to maintain the height of the nearest edge. + //#define EXTRAPOLATE_BEYOND_GRID + + // + // Experimental Subdivision of the grid by Catmull-Rom method. + // Synthesizes intermediate points to produce a more detailed mesh. + // + //#define ABL_BILINEAR_SUBDIVISION + #if ENABLED(ABL_BILINEAR_SUBDIVISION) + // Number of subdivisions between probe points + #define BILINEAR_SUBDIVISIONS 3 + #endif + + #endif + +#elif ENABLED(AUTO_BED_LEVELING_3POINT) + + // 3 arbitrary points to probe. + // A simple cross-product is used to estimate the plane of the bed. + #define ABL_PROBE_PT_1_X 15 + #define ABL_PROBE_PT_1_Y 180 + #define ABL_PROBE_PT_2_X 15 + #define ABL_PROBE_PT_2_Y 20 + #define ABL_PROBE_PT_3_X 170 + #define ABL_PROBE_PT_3_Y 20 + +#elif ENABLED(AUTO_BED_LEVELING_UBL) + + //=========================================================================== + //========================= Unified Bed Leveling ============================ + //=========================================================================== + + #define UBL_MESH_INSET 1 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 10 // Don't use more than 15 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + #define UBL_PROBE_PT_1_X 39 // Probing points for 3-Point leveling of the mesh + #define UBL_PROBE_PT_1_Y 180 + #define UBL_PROBE_PT_2_X 39 + #define UBL_PROBE_PT_2_Y 20 + #define UBL_PROBE_PT_3_X 180 + #define UBL_PROBE_PT_3_Y 20 + + #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation + #define UBL_MESH_EDIT_MOVES_Z // Sophisticated users prefer no movement of nozzle + +#elif ENABLED(MESH_BED_LEVELING) + + //=========================================================================== + //=================================== Mesh ================================== + //=========================================================================== + + #define MESH_INSET 10 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 3 // Don't use more than 7 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + //#define MESH_G28_REST_ORIGIN // After homing all axes ('G28' or 'G28 XYZ') rest Z at Z_MIN_POS + +#endif // BED_LEVELING + +/** + * Use the LCD controller for bed leveling + * Requires MESH_BED_LEVELING or PROBE_MANUALLY + */ +//#define LCD_BED_LEVELING + +#if ENABLED(LCD_BED_LEVELING) + #define MBL_Z_STEP 0.025 // Step size while manually probing Z axis. + #define LCD_PROBE_Z_RANGE 4 // Z Range centered on Z_MIN_POS for LCD Z adjustment +#endif + +// Add a menu item to move between bed corners for manual bed adjustment +//#define LEVEL_BED_CORNERS + +/** + * Commands to execute at the end of G29 probing. + * Useful to retract or move the Z probe out of the way. + */ +//#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) +//#define BED_CENTER_AT_0_0 + +// Manually set the home position. Leave these undefined for automatic settings. +// For DELTA this is the top-center of the Cartesian print volume. +//#define MANUAL_X_HOME_POS 0 +//#define MANUAL_Y_HOME_POS 0 +//#define MANUAL_Z_HOME_POS 0 + +// Use "Z Safe Homing" to avoid homing with a Z probe outside the bed area. +// +// With this feature enabled: +// +// - 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). +// - 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 axis (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). +#endif + +// Homing speeds (mm/m) +#define HOMING_FEEDRATE_XY (40*60) +#define HOMING_FEEDRATE_Z (3*60) + +//============================================================================= +//============================= Additional Features =========================== +//============================================================================= + +// @section extras + +// +// EEPROM +// +// The microcontroller can store settings in the EEPROM, e.g. max velocity... +// M500 - stores parameters in EEPROM +// M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily). +// M502 - reverts to the default "factory settings". You still need to store them in EEPROM afterwards if you want to. +// +#define EEPROM_SETTINGS // Enable for M500 and M501 commands +//#define DISABLE_M503 // Saves ~2700 bytes of PROGMEM. Disable for release! +#define EEPROM_CHITCHAT // Give feedback on EEPROM commands. Disable to save PROGMEM. + +// +// Host Keepalive +// +// When enabled Marlin will send a busy status message to the host +// every couple of seconds when it can't accept commands. +// +#define HOST_KEEPALIVE_FEATURE // Disable this if your host doesn't like keepalive messages +#define DEFAULT_KEEPALIVE_INTERVAL 2 // Number of seconds between "busy" messages. Set with M113. +#define BUSY_WHILE_HEATING // Some hosts require "busy" messages even during heating + +// +// M100 Free Memory Watcher +// +//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose + +// +// G20/G21 Inch mode support +// +//#define INCH_MODE_SUPPORT + +// +// M149 Set temperature units support +// +//#define TEMPERATURE_UNITS_SUPPORT + +// @section temperature + +// Preheat Constants +#define PREHEAT_1_TEMP_HOTEND 180 +#define PREHEAT_1_TEMP_BED 70 +#define PREHEAT_1_FAN_SPEED 0 // Value from 0 to 255 + +#define PREHEAT_2_TEMP_HOTEND 240 +#define PREHEAT_2_TEMP_BED 90 // TB2: ABS default 110, 90 is the maximum temp at 12V supply +#define PREHEAT_2_FAN_SPEED 0 // Value from 0 to 255 + +/** + * Nozzle Park -- EXPERIMENTAL + * + * Park the nozzle at the given XYZ position on idle or G27. + * + * The "P" parameter controls the action applied to the Z axis: + * + * P0 (Default) If Z is below park Z raise the nozzle. + * P1 Raise the nozzle always to Z-park height. + * P2 Raise the nozzle by Z-park amount, limited to Z_MAX_POS. + */ +#define NOZZLE_PARK_FEATURE + +#if ENABLED(NOZZLE_PARK_FEATURE) + // Specify a park position as { X, Y, Z } + #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 } +#endif + +/** + * Clean Nozzle Feature -- EXPERIMENTAL + * + * Adds the G12 command to perform a nozzle cleaning process. + * + * Parameters: + * P Pattern + * S Strokes / Repetitions + * T Triangles (P1 only) + * + * Patterns: + * P0 Straight line (default). This process requires a sponge type material + * at a fixed bed location. "S" specifies strokes (i.e. back-forth motions) + * between the start / end points. + * + * P1 Zig-zag pattern between (X0, Y0) and (X1, Y1), "T" specifies the + * number of zig-zag triangles to do. "S" defines the number of strokes. + * Zig-zags are done in whichever is the narrower dimension. + * For example, "G12 P1 S1 T3" will execute: + * + * -- + * | (X0, Y1) | /\ /\ /\ | (X1, Y1) + * | | / \ / \ / \ | + * A | | / \ / \ / \ | + * | | / \ / \ / \ | + * | (X0, Y0) | / \/ \/ \ | (X1, Y0) + * -- +--------------------------------+ + * |________|_________|_________| + * T1 T2 T3 + * + * P2 Circular pattern with middle at NOZZLE_CLEAN_CIRCLE_MIDDLE. + * "R" specifies the radius. "S" specifies the stroke count. + * Before starting, the nozzle moves to NOZZLE_CLEAN_START_POINT. + * + * Caveats: The ending Z should be the same as starting Z. + * Attention: EXPERIMENTAL. G-code arguments may change. + * + */ +//#define NOZZLE_CLEAN_FEATURE + +#if ENABLED(NOZZLE_CLEAN_FEATURE) + // Default number of pattern repetitions + #define NOZZLE_CLEAN_STROKES 12 + + // Default number of triangles + #define NOZZLE_CLEAN_TRIANGLES 3 + + // Specify positions as { X, Y, Z } + #define NOZZLE_CLEAN_START_POINT { 30, 30, (Z_MIN_POS + 1)} + #define NOZZLE_CLEAN_END_POINT {100, 60, (Z_MIN_POS + 1)} + + // Circular pattern radius + #define NOZZLE_CLEAN_CIRCLE_RADIUS 6.5 + // Circular pattern circle fragments number + #define NOZZLE_CLEAN_CIRCLE_FN 10 + // Middle point of circle + #define NOZZLE_CLEAN_CIRCLE_MIDDLE NOZZLE_CLEAN_START_POINT + + // Moves the nozzle to the initial position + #define NOZZLE_CLEAN_GOBACK +#endif + +/** + * Print Job Timer + * + * Automatically start and stop the print job timer on M104/M109/M190. + * + * M104 (hotend, no wait) - high temp = none, low temp = stop timer + * M109 (hotend, wait) - high temp = start timer, low temp = stop timer + * M190 (bed, wait) - high temp = start timer, low temp = none + * + * The timer can also be controlled with the following commands: + * + * M75 - Start the print job timer + * M76 - Pause the print job timer + * M77 - Stop the print job timer + */ +#define PRINTJOB_TIMER_AUTOSTART + +/** + * Print Counter + * + * Track statistical data such as: + * + * - Total print jobs + * - Total successful print jobs + * - Total failed print jobs + * - Total time printing + * + * View the current statistics with M78. + */ +#define PRINTCOUNTER + +//============================================================================= +//============================= LCD and SD support ============================ +//============================================================================= + +// @section lcd + +/** + * LCD LANGUAGE + * + * Select the language to display on the LCD. These languages are available: + * + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, + * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * tr, uk, zh_CN, zh_TW, test + * + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + */ +#define LCD_LANGUAGE en + +/** + * LCD Character Set + * + * Note: This option is NOT applicable to Graphical Displays. + * + * All character-based LCDs provide ASCII plus one of these + * language extensions: + * + * - JAPANESE ... the most common + * - WESTERN ... with more accented characters + * - CYRILLIC ... for the Russian language + * + * To determine the language extension installed on your controller: + * + * - Compile and upload with LCD_LANGUAGE set to 'test' + * - 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 + * + * :['JAPANESE', 'WESTERN', 'CYRILLIC'] + */ +#define DISPLAY_CHARSET_HD44780 JAPANESE + +/** + * LCD TYPE + * + * Enable ULTRA_LCD for a 16x2, 16x4, 20x2, or 20x4 character-based LCD. + * Enable DOGLCD for a 128x64 (ST7565R) Full Graphical Display. + * (These options will be enabled automatically for most displays.) + * + * IMPORTANT: The U8glib library is required for Full Graphic Display! + * https://github.com/olikraus/U8glib_Arduino + */ +//#define ULTRA_LCD // Character based +//#define DOGLCD // Full graphics display + +/** + * SD CARD + * + * 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 + +/** + * SD CARD: SPI SPEED + * + * Enable one of the following items for a slower SPI transfer speed. + * This may be required to resolve "volume init" errors. + */ +//#define SPI_SPEED SPI_HALF_SPEED +//#define SPI_SPEED SPI_QUARTER_SPEED +//#define SPI_SPEED SPI_EIGHTH_SPEED + +/** + * SD CARD: ENABLE CRC + * + * Use CRC checks and retries on the SD communication. + */ +#define SD_CHECK_AND_RETRY + +// +// ENCODER SETTINGS +// +// This option overrides the default number of encoder pulses needed to +// produce one step. Should be increased for high-resolution encoders. +// +#define ENCODER_PULSES_PER_STEP 4 + +// +// Use this option to override the number of step signals required to +// move between next/prev menu items. +// +#define ENCODER_STEPS_PER_MENU_ITEM 1 + +/** + * Encoder Direction Options + * + * Test your encoder's behavior first with both options disabled. + * + * Reversed Value Edit and Menu Nav? Enable REVERSE_ENCODER_DIRECTION. + * Reversed Menu Navigation only? Enable REVERSE_MENU_DIRECTION. + * Reversed Value Editing only? Enable BOTH options. + */ + +// +// This option reverses the encoder direction everywhere. +// +// Set this option if CLOCKWISE causes values to DECREASE +// +//#define REVERSE_ENCODER_DIRECTION + +// +// This option reverses the encoder direction for navigating LCD menus. +// +// If CLOCKWISE normally moves DOWN this makes it go UP. +// If CLOCKWISE normally moves UP this makes it go DOWN. +// +//#define REVERSE_MENU_DIRECTION + +// +// Individual Axis Homing +// +// Add individual axis homing items (Home X, Home Y, and Home Z) to the LCD menu. +// +//#define INDIVIDUAL_AXIS_HOMING_MENU + +// +// SPEAKER/BUZZER +// +// If you have a speaker that can produce tones, enable it here. +// By default Marlin assumes you have a buzzer with a fixed frequency. +// +//#define SPEAKER + +// +// The duration and frequency for the UI feedback sound. +// Set these to 0 to disable audio feedback in the LCD menus. +// +// Note: Test audio output with the G-Code: +// M300 S P +// +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 +//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 + +// +// CONTROLLER TYPE: Standard +// +// Marlin supports a wide variety of controllers. +// Enable one of the following options to specify your controller. +// + +// +// ULTIMAKER Controller. +// +//#define ULTIMAKERCONTROLLER + +// +// ULTIPANEL as seen on Thingiverse. +// +//#define ULTIPANEL + +// +// PanelOne from T3P3 (via RAMPS 1.4 AUX2/AUX3) +// http://reprap.org/wiki/PanelOne +// +//#define PANEL_ONE + +// +// MaKr3d Makr-Panel with graphic controller and SD support. +// http://reprap.org/wiki/MaKr3d_MaKrPanel +// +//#define MAKRPANEL + +// +// ReprapWorld Graphical LCD +// https://reprapworld.com/?products_details&products_id/1218 +// +//#define REPRAPWORLD_GRAPHICAL_LCD + +// +// Activate one of these if you have a Panucatt Devices +// Viki 2.0 or mini Viki with Graphic LCD +// http://panucatt.com +// +//#define VIKI2 +//#define miniVIKI + +// +// Adafruit ST7565 Full Graphic Controller. +// https://github.com/eboston/Adafruit-ST7565-Full-Graphic-Controller/ +// +//#define ELB_FULL_GRAPHIC_CONTROLLER + +// +// RepRapDiscount Smart Controller. +// http://reprap.org/wiki/RepRapDiscount_Smart_Controller +// +// Note: Usually sold with a white PCB. +// +//#define REPRAP_DISCOUNT_SMART_CONTROLLER + +// +// GADGETS3D G3D LCD/SD Controller +// http://reprap.org/wiki/RAMPS_1.3/1.4_GADGETS3D_Shield_with_Panel +// +// Note: Usually sold with a blue PCB. +// +//#define G3D_PANEL + +// +// RepRapDiscount FULL GRAPHIC Smart Controller +// http://reprap.org/wiki/RepRapDiscount_Full_Graphic_Smart_Controller +// +//#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER + +// +// MakerLab Mini Panel with graphic +// controller and SD support - http://reprap.org/wiki/Mini_panel +// +//#define MINIPANEL + +// +// RepRapWorld REPRAPWORLD_KEYPAD v1.1 +// http://reprapworld.com/?products_details&products_id=202&cPath=1591_1626 +// +// REPRAPWORLD_KEYPAD_MOVE_STEP sets how much should the robot move when a key +// is pressed, a value of 10.0 means 10mm per click. +// +//#define REPRAPWORLD_KEYPAD +//#define REPRAPWORLD_KEYPAD_MOVE_STEP 1.0 + +// +// RigidBot Panel V1.0 +// http://www.inventapart.com/ +// +//#define RIGIDBOT_PANEL + +// +// BQ LCD Smart Controller shipped by +// default with the BQ Hephestos 2 and Witbox 2. +// +//#define BQ_LCD_SMART_CONTROLLER + +// +// Cartesio UI +// http://mauk.cc/webshop/cartesio-shop/electronics/user-interface +// +//#define CARTESIO_UI + +// +// ANET_10 Controller supported displays. +// +//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. + // This LCD is known to be susceptible to electrical interference + // which scrambles the display. Pressing any button clears it up. +//#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 + // A clone of the RepRapDiscount full graphics display but with + // different pins/wiring (see pins_ANET_10.h). + +// +// LCD for Melzi Card with Graphical LCD +// +//#define LCD_FOR_MELZI + +// +// CONTROLLER TYPE: I2C +// +// Note: These controllers require the installation of Arduino's LiquidCrystal_I2C +// library. For more info: https://github.com/kiyoshigawa/LiquidCrystal_I2C +// + +// +// Elefu RA Board Control Panel +// http://www.elefu.com/index.php?route=product/product&product_id=53 +// +//#define RA_CONTROL_PANEL + +// +// Sainsmart YW Robot (LCM1602) LCD Display +// +// Note: This controller requires F.Malpartida's LiquidCrystal_I2C library +// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home +// +//#define LCD_I2C_SAINSMART_YWROBOT + +// +// Generic LCM1602 LCD adapter +// +//#define LCM1602 + +// +// PANELOLU2 LCD with status LEDs, +// separate encoder and click inputs. +// +// Note: This controller requires Arduino's LiquidTWI2 library v1.2.3 or later. +// For more info: https://github.com/lincomatic/LiquidTWI2 +// +// Note: The PANELOLU2 encoder click input can either be directly connected to +// a pin (if BTN_ENC defined to != -1) or read through I2C (when BTN_ENC == -1). +// +//#define LCD_I2C_PANELOLU2 + +// +// Panucatt VIKI LCD with status LEDs, +// integrated click & L/R/U/D buttons, separate encoder inputs. +// +//#define LCD_I2C_VIKI + +// +// SSD1306 OLED full graphics generic display +// +//#define U8GLIB_SSD1306 + +// +// SAV OLEd LCD module support using either SSD1306 or SH1106 based LCD modules +// +//#define SAV_3DGLCD +#if ENABLED(SAV_3DGLCD) + //#define U8GLIB_SSD1306 + #define U8GLIB_SH1106 +#endif + +// +// CONTROLLER TYPE: Shift register panels +// +// 2 wire Non-latching LCD SR from https://goo.gl/aJJ4sH +// LCD configuration: http://reprap.org/wiki/SAV_3D_LCD +// +//#define SAV_3DLCD + +// +// TinyBoy2 128x64 OLED / Encoder Panel +// +#define OLED_PANEL_TINYBOY2 + +// +// Makeboard 3D Printer Parts 3D Printer Mini Display 1602 Mini Controller +// https://www.aliexpress.com/item/Micromake-Makeboard-3D-Printer-Parts-3D-Printer-Mini-Display-1602-Mini-Controller-Compatible-with-Ramps-1/32765887917.html +// +//#define MAKEBOARD_MINI_2_LINE_DISPLAY_1602 + +// +// MKS MINI12864 with graphic controller and SD support +// http://reprap.org/wiki/MKS_MINI_12864 +// +//#define MKS_MINI_12864 + +// +// Factory display for Creality CR-10 +// https://www.aliexpress.com/item/Universal-LCD-12864-3D-Printer-Display-Screen-With-Encoder-For-CR-10-CR-7-Model/32833148327.html +// +// This is RAMPS-compatible using a single 10-pin connector. +// (For CR-10 owners who want to replace the Melzi Creality board but retain the display) +// +//#define CR10_STOCKDISPLAY + +// +// MKS OLED 1.3" 128 × 64 FULL GRAPHICS CONTROLLER +// http://reprap.org/wiki/MKS_12864OLED +// +// Tiny, but very sharp OLED display +// +//#define MKS_12864OLED + +//============================================================================= +//=============================== Extra Features ============================== +//============================================================================= + +// @section extras + +// Increase the FAN PWM frequency. Removes the PWM noise but increases heating in the FET/Arduino +//#define FAST_PWM_FAN + +// Use software PWM to drive the fan, as for the heaters. This uses a very low frequency +// which is not as annoying as with the hardware PWM. On the other hand, if this frequency +// is too low, you should also increment SOFT_PWM_SCALE. +//#define FAN_SOFT_PWM + +// Incrementing this by 1 will double the software PWM frequency, +// affecting heaters, and the fan if FAN_SOFT_PWM is enabled. +// However, control resolution will be halved for each increment; +// at zero value, there are 128 effective control positions. +#define SOFT_PWM_SCALE 0 + +// If SOFT_PWM_SCALE is set to a value higher than 0, dithering can +// be used to mitigate the associated resolution loss. If enabled, +// some of the PWM cycles are stretched so on average the desired +// duty cycle is attained. +//#define SOFT_PWM_DITHER + +// Temperature status LEDs that display the hotend and bed temperature. +// If all hotends, bed temperature, and target temperature are under 54C +// then the BLUE led is on. Otherwise the RED led is on. (1C hysteresis) +//#define TEMP_STAT_LEDS + +// M240 Triggers a camera by emulating a Canon RC-1 Remote +// Data from: http://www.doc-diy.net/photo/rc-1_hacked/ +//#define PHOTOGRAPH_PIN 23 + +// 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 + +// Support for BlinkM/CyzRgb +//#define BLINKM + +// Support for PCA9632 PWM LED driver +//#define PCA9632 + +/** + * RGB LED / LED Strip Control + * + * Enable support for an RGB LED connected to 5V digital pins, or + * an RGB Strip connected to MOSFETs controlled by digital pins. + * + * 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 overall brightness parameters is also available + * + * *** CAUTION *** + * LED Strips require a MOFSET 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! + * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino + * cannot handle such current, separate 5V power supply must be used + * *** CAUTION *** + * + * LED type. This options are mutualy exclusive. Uncomment only one. + * + */ +//#define RGB_LED +//#define RGBW_LED + +#if ENABLED(RGB_LED) || ENABLED(RGBW_LED) + #define RGB_LED_R_PIN 34 + #define RGB_LED_G_PIN 43 + #define RGB_LED_B_PIN 35 + #define RGB_LED_W_PIN -1 +#endif + +// 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 (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) + #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip + #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time + #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + //#define NEOPIXEL_STARTUP_TEST // Cycle through colors at startup +#endif + +/** + * Printer Event LEDs + * + * During printing, the LEDs will reflect the printer status: + * + * - Gradually change from blue to violet as the heated bed gets to target temp + * - Gradually change from violet to red as the hotend gets to temperature + * - Change to white to illuminate work surface + * - Change to green once print has finished + * - Turn off after the print has finished and the user has pushed a button + */ +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) + #define PRINTER_EVENT_LEDS +#endif + +/*********************************************************************\ +* R/C SERVO support +* Sponsored by TrinityLabs, Reworked by codexmas +**********************************************************************/ + +// Number of servos +// +// If you select a configuration below, this will receive a default value and does not need to be set manually +// set it manually if you have more servos than extruders and wish to manually control some +// leaving it undefined or defining as 0 will disable the servo subsystem +// If unsure, leave commented / disabled +// +//#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command + +// Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. +// 300ms is a good value but you can try less delay. +// If the servo can't reach the requested position, increase it. +#define SERVO_DELAY { 300 } + +// Servo deactivation +// +// With this option servos are powered only during movement, then turned off to prevent jitter. +//#define DEACTIVATE_SERVOS_AFTER_MOVE + +/** + * Filament Width Sensor + * + * Measures the filament width in real-time and adjusts + * flow rate to compensate for any irregularities. + * + * Also allows the measured filament diameter to set the + * extrusion rate, so the slicer only has to specify the + * volume. + * + * Only a single extruder is supported at this time. + * + * 34 RAMPS_14 : Analog input 5 on the AUX2 connector + * 81 PRINTRBOARD : Analog input 2 on the Exp1 connector (version B,C,D,E) + * 301 RAMBO : Analog input 3 + * + * Note: May require analog pins to be defined for other boards. + */ +//#define FILAMENT_WIDTH_SENSOR + +#define DEFAULT_NOMINAL_FILAMENT_DIA 1.75 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. + +#if ENABLED(FILAMENT_WIDTH_SENSOR) + #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) + #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber + + #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading + #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading + #define MAX_MEASUREMENT_DELAY 20 // (bytes) Buffer size for stored measurements (1 byte per cm). Must be larger than MEASUREMENT_DELAY_CM. + + #define DEFAULT_MEASURED_FILAMENT_DIA DEFAULT_NOMINAL_FILAMENT_DIA // Set measured to nominal initially + + // Display filament width on the LCD status line. Status messages will expire after 5 seconds. + //#define FILAMENT_LCD_DISPLAY +#endif + +#endif // CONFIGURATION_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/TinyBoy2/Configuration_adv.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/TinyBoy2/Configuration_adv.h new file mode 100644 index 00000000..197f909d --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/TinyBoy2/Configuration_adv.h @@ -0,0 +1,1424 @@ +/** + * 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 . + * + */ + +/** + * Configuration_adv.h + * + * Advanced settings. + * Only change these if you know exactly what you're doing. + * Some of these settings can damage your printer if improperly set! + * + * Basic settings can be found in Configuration.h + * + */ +#ifndef CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H_VERSION 010100 + +// @section temperature + +//=========================================================================== +//=============================Thermal Settings ============================ +//=========================================================================== + +#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 + #endif +#endif + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * The solution: Once the temperature reaches the target, start observing. + * If the temperature stays too far below the target (hysteresis) for too long (period), + * the firmware will halt the machine as a safety precaution. + * + * If you get false positives for "Thermal Runaway" increase THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD + */ +#if ENABLED(THERMAL_PROTECTION_HOTENDS) + #define THERMAL_PROTECTION_PERIOD 40 // Seconds + #define THERMAL_PROTECTION_HYSTERESIS 4 // Degrees Celsius + + /** + * Whenever an M104 or M109 increases the target temperature the firmware will wait for the + * WATCH_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get false positives for "Heating failed" increase WATCH_TEMP_PERIOD and/or decrease WATCH_TEMP_INCREASE + * WATCH_TEMP_INCREASE should not be below 2. + */ + #define WATCH_TEMP_PERIOD 20 // Seconds + #define WATCH_TEMP_INCREASE 2 // Degrees Celsius +#endif + +/** + * Thermal Protection parameters for the bed are just as above for hotends. + */ +#if ENABLED(THERMAL_PROTECTION_BED) + #define THERMAL_PROTECTION_BED_PERIOD 20 // Seconds + #define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius + + /** + * Whenever an M140 or M190 increases the target temperature the firmware will wait for the + * WATCH_BED_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_BED_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get too many "Heating failed" errors, increase WATCH_BED_TEMP_PERIOD and/or decrease + * WATCH_BED_TEMP_INCREASE. (WATCH_BED_TEMP_INCREASE should not be below 2.) + */ + #define WATCH_BED_TEMP_PERIOD 60 // Seconds + #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius +#endif + +#if ENABLED(PIDTEMP) + // this adds an experimental additional term to the heating power, proportional to the extrusion speed. + // if Kc is chosen well, the additional required power due to increased melting should be compensated. + //#define PID_EXTRUSION_SCALING + #if ENABLED(PID_EXTRUSION_SCALING) + #define DEFAULT_Kc (100) //heating power=Kc*(e_speed) + #define LPQ_MAX_LEN 50 + #endif +#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 + */ +#define AUTOTEMP +#if ENABLED(AUTOTEMP) + #define AUTOTEMP_OLDWEIGHT 0.98 +#endif + +// Show Temperature ADC value +// Enable for M105 to include ADC values read from temperature sensors. +//#define SHOW_TEMP_ADC_VALUES + +/** + * High Temperature Thermistor Support + * + * Thermistors able to support high temperature tend to have a hard time getting + * good readings at room and lower temperatures. This means HEATER_X_RAW_LO_TEMP + * will probably be caught when the heating element first turns on during the + * preheating process, which will trigger a min_temp_error as a safety measure + * and force stop everything. + * To circumvent this limitation, we allow for a preheat time (during which, + * min_temp_error won't be triggered) and add a min_temp buffer to handle + * aberrant readings. + * + * If you want to enable this feature for your hotend thermistor(s) + * uncomment and set values > 0 in the constants below + */ + +// The number of consecutive low temperature errors that can occur +// before a min_temp_error is triggered. (Shouldn't be more than 10.) +//#define MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED 0 + +// The number of milliseconds a hotend will preheat before starting to check +// the temperature. This value should NOT be set to the time it takes the +// hot end to reach the target temperature, but the time it takes to reach +// the minimum temperature your thermistor can read. The lower the better/safer. +// This shouldn't need to be more than 30 seconds (30000) +//#define MILLISECONDS_PREHEAT_TIME 0 + +// @section extruder + +// Extruder runout prevention. +// If the machine is idle and the temperature over MINTEMP +// then extrude some filament every couple of SECONDS. +//#define EXTRUDER_RUNOUT_PREVENT +#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_EXTRUDE 5 // mm +#endif + +// @section temperature + +//These defines help to calibrate the AD595 sensor in case you get wrong temperature measurements. +//The measured temperature is defined as "actualTemp = (measuredTemp * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET" +#define TEMP_SENSOR_AD595_OFFSET 0.0 +#define TEMP_SENSOR_AD595_GAIN 1.0 + +/** + * 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. + */ +//#define USE_CONTROLLER_FAN +#if ENABLED(USE_CONTROLLER_FAN) + //#define CONTROLLER_FAN_PIN FAN1_PIN // 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 +#endif + +// When first starting the main fan, run it at full speed for the +// given number of milliseconds. This gets the fan spinning reliably +// before setting a PWM value. (Does not work with software PWM for fan on Sanguinololu) +//#define FAN_KICKSTART_TIME 100 + +// This defines the minimal speed for the main fan, run in PWM mode +// to enable uncomment and set minimal PWM speed for reliable running (1-255) +// if fan speed is [1 - (FAN_MIN_PWM-1)] it is set to FAN_MIN_PWM +//#define FAN_MIN_PWM 50 + +// @section extruder + +/** + * Extruder cooling fans + * + * Extruder auto fans automatically turn on when their extruders' + * temperatures go above EXTRUDER_AUTO_FAN_TEMPERATURE. + * + * Your board's pins file specifies the recommended pins. Override those here + * or set to -1 to disable completely. + * + * Multiple extruders can be assigned to the same pin in which case + * the fan will turn on when any selected extruder is above the threshold. + */ +#define E0_AUTO_FAN_PIN -1 +#define E1_AUTO_FAN_PIN -1 +#define E2_AUTO_FAN_PIN -1 +#define E3_AUTO_FAN_PIN -1 +#define E4_AUTO_FAN_PIN -1 +#define EXTRUDER_AUTO_FAN_TEMPERATURE 50 +#define EXTRUDER_AUTO_FAN_SPEED 255 // == full speed + +/** + * Part-Cooling Fan Multiplexer + * + * This feature allows you to digitally multiplex the fan output. + * The multiplexer is automatically switched at tool-change. + * Set FANMUX[012]_PINs below for up to 2, 4, or 8 multiplexed fans. + */ +#define FANMUX0_PIN -1 +#define FANMUX1_PIN -1 +#define FANMUX2_PIN -1 + +/** + * M355 Case Light on-off / brightness + */ +//#define CASE_LIGHT_ENABLE +#if ENABLED(CASE_LIGHT_ENABLE) + //#define CASE_LIGHT_PIN 4 // Override the default pin if needed + #define INVERT_CASE_LIGHT false // Set true if Case Light is ON when pin is LOW + #define CASE_LIGHT_DEFAULT_ON true // Set default power-up state on + #define CASE_LIGHT_DEFAULT_BRIGHTNESS 105 // Set default power-up brightness (0-255, requires PWM pin) + //#define MENU_ITEM_CASE_LIGHT // Add a Case Light option to the LCD main menu +#endif + +//=========================================================================== +//============================ Mechanical Settings ========================== +//=========================================================================== + +// @section homing + +// If you want endstops to stay on (by default) even when not homing +// enable this option. Override at any time with M120, M121. +//#define ENDSTOPS_ALWAYS_ON_DEFAULT + +// @section extras + +//#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. + +// Dual X Steppers +// Uncomment this option to drive two X axis motors. +// The next unused E driver will be assigned to the second X stepper. +//#define X_DUAL_STEPPER_DRIVERS +#if ENABLED(X_DUAL_STEPPER_DRIVERS) + // Set true if the two X motors need to rotate in opposite directions + #define INVERT_X2_VS_X_DIR true +#endif + +// Dual Y Steppers +// Uncomment this option to drive two Y axis motors. +// The next unused E driver will be assigned to the second Y stepper. +//#define Y_DUAL_STEPPER_DRIVERS +#if ENABLED(Y_DUAL_STEPPER_DRIVERS) + // Set true if the two Y motors need to rotate in opposite directions + #define INVERT_Y2_VS_Y_DIR true +#endif + +// A single Z stepper driver is usually used to drive 2 stepper motors. +// Uncomment this option to use a separate stepper driver for each Z axis motor. +// The next unused E driver will be assigned to the second Z stepper. +//#define Z_DUAL_STEPPER_DRIVERS + +#if ENABLED(Z_DUAL_STEPPER_DRIVERS) + + // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper. + // That way the machine is capable to align the bed during home, since both Z steppers are homed. + // There is also an implementation of M666 (software endstops adjustment) to this feature. + // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed. + // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2. + // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive. + // Play a little bit with small adjustments (0.5mm) and check the behaviour. + // The M119 (endstops report) will start reporting the Z2 Endstop as well. + + //#define Z_DUAL_ENDSTOPS + + #if ENABLED(Z_DUAL_ENDSTOPS) + #define Z2_USE_ENDSTOP _XMAX_ + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 // Use M666 to determine/test this value + #endif + +#endif // Z_DUAL_STEPPER_DRIVERS + +// Enable this for dual x-carriage printers. +// A dual x-carriage design has the advantage that the inactive extruder can be parked which +// prevents hot-end ooze contaminating the print. It also reduces the weight of each x-carriage +// allowing faster printing speeds. Connect your X2 stepper to the first unused E plug. +//#define DUAL_X_CARRIAGE +#if ENABLED(DUAL_X_CARRIAGE) + // Configuration for second X-carriage + // Note: the first x-carriage is defined as the x-carriage which homes to the minimum endstop; + // the second x-carriage always homes to the maximum endstop. + #define X2_MIN_POS 80 // set minimum to ensure second x-carriage doesn't hit the parked first X-carriage + #define X2_MAX_POS 353 // set maximum to the distance between toolheads when both heads are homed + #define X2_HOME_DIR 1 // the second X-carriage always homes to the maximum endstop position + #define X2_HOME_POS X2_MAX_POS // default home position is the maximum carriage position + // However: In this mode the HOTEND_OFFSET_X value for the second extruder provides a software + // override for X2_HOME_POS. This also allow recalibration of the distance between the two endstops + // without modifying the firmware (through the "M218 T1 X???" command). + // Remember: you should set the second extruder x-offset to 0 in your slicer. + + // There are a few selectable movement modes for dual x-carriages using M605 S + // Mode 0 (DXC_FULL_CONTROL_MODE): Full control. The slicer has full control over both x-carriages and can achieve optimal travel results + // as long as it supports dual x-carriages. (M605 S0) + // Mode 1 (DXC_AUTO_PARK_MODE) : Auto-park mode. The firmware will automatically park and unpark the x-carriages on tool changes so + // that additional slicer support is not required. (M605 S1) + // Mode 2 (DXC_DUPLICATION_MODE) : Duplication mode. The firmware will transparently make the second x-carriage and extruder copy all + // actions of the first x-carriage. This allows the printer to print 2 arbitrary items at + // once. (2nd extruder x offset and temp offset are set using: M605 S2 [Xnnn] [Rmmm]) + + // This is the default power-up mode which can be later using M605. + #define DEFAULT_DUAL_X_CARRIAGE_MODE DXC_FULL_CONTROL_MODE + + // Default settings in "Auto-park Mode" + #define TOOLCHANGE_PARK_ZLIFT 0.2 // the distance to raise Z axis when parking an extruder + #define TOOLCHANGE_UNPARK_ZLIFT 1 // the distance to raise Z axis when unparking an extruder + + // Default x offset in duplication mode (typically set to half print bed width) + #define DEFAULT_DUPLICATION_X_OFFSET 100 + +#endif // DUAL_X_CARRIAGE + +// 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. +//#define EXT_SOLENOID + +// @section homing + +//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +#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 this is defined, if both x and y are to be homed, a diagonal move will be performed initially. + +// When G28 is called, this option will make Y home before X +//#define HOME_Y_BEFORE_X + +// @section machine + +#define AXIS_RELATIVE_MODES {false, false, false, false} + +// Allow duplication mode with a basic dual-nozzle extruder +//#define DUAL_NOZZLE_DUPLICATION_MODE + +// By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step. +#define INVERT_X_STEP_PIN false +#define INVERT_Y_STEP_PIN false +#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. +#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_E true + +#define DEFAULT_MINIMUMFEEDRATE 0.0 // minimum feedrate +#define DEFAULT_MINTRAVELFEEDRATE 0.0 + +//#define HOME_AFTER_DEACTIVATE // Require rehoming after steppers are deactivated + +// @section lcd + +#if ENABLED(ULTIPANEL) + #define MANUAL_FEEDRATE {50*60, 50*60, 4*60, 60} // Feedrates for manual moves along X, Y, Z, E from panel + #define ULTIPANEL_FEEDMULTIPLY // Comment to disable setting feedrate multiplier via encoder +#endif + +// @section extras + +// minimum time in microseconds that a movement needs to take if the buffer is emptied. +#define DEFAULT_MINSEGMENTTIME 20000 + +// If defined the movements slow down when the look ahead buffer is only half full +#define SLOWDOWN + +// Frequency limit +// See nophead's blog for more info +// Not working O +//#define XY_FREQUENCY_LIMIT 15 + +// 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 +// if unwanted behavior is observed on a user's machine when running at very slow speeds. +#define MINIMUM_PLANNER_SPEED 0.05 // (mm/sec) + +// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU. +#define MICROSTEP_MODES {16,16,16,16,16} // [1,2,4,8,16] + +/** + * @section stepper motor current + * + * Some boards have a means of setting the stepper motor current via firmware. + * + * The power on motor currents are set by: + * PWM_MOTOR_CURRENT - used by MINIRAMBO & ULTIMAIN_2 + * known compatible chips: A4982 + * DIGIPOT_MOTOR_CURRENT - used by BQ_ZUM_MEGA_3D, RAMBO & SCOOVO_X9H + * known compatible chips: AD5206 + * DAC_MOTOR_CURRENT_DEFAULT - used by PRINTRBOARD_REVF & RIGIDBOARD_V2 + * known compatible chips: MCP4728 + * DIGIPOT_I2C_MOTOR_CURRENTS - used by 5DPRINT, AZTEEG_X3_PRO, MIGHTYBOARD_REVE + * known compatible chips: MCP4451, MCP4018 + * + * Motor currents can also be set by M907 - M910 and by the LCD. + * M907 - applies to all. + * M908 - BQ_ZUM_MEGA_3D, RAMBO, PRINTRBOARD_REVF, RIGIDBOARD_V2 & SCOOVO_X9H + * M909, M910 & LCD - only PRINTRBOARD_REVF & RIGIDBOARD_V2 + */ +//#define PWM_MOTOR_CURRENT { 1300, 1300, 1250 } // Values in milliamps +//#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 + +// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +//#define DIGIPOT_I2C +//#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster +#define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 +// Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS +#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=========================== +//=========================================================================== + +#define ENCODER_RATE_MULTIPLIER // If defined, certain menu edit operations automatically multiply the steps when the encoder is moved quickly +#define ENCODER_10X_STEPS_PER_SEC 75 // If the encoder steps per sec exceeds this value, multiply steps moved x10 to quickly advance the value +#define ENCODER_100X_STEPS_PER_SEC 160 // If the encoder steps per sec exceeds this value, multiply steps moved x100 to really quickly advance the value + +//#define CHDK 4 //Pin for triggering CHDK to take a picture see how to use it here http://captain-slow.dk/2014/03/09/3d-printing-timelapses/ +#define CHDK_DELAY 50 //How long in ms the pin should stay HIGH before going LOW again + +// @section lcd + +// Include a page of printer information in the LCD Main Menu +#define LCD_INFO_MENU + +// Scroll a longer status message into view +//#define STATUS_MESSAGE_SCROLLING + +// On the Info Screen, display XY with one decimal place when possible +//#define LCD_DECIMAL_SMALL_XY + +// The timeout (in ms) to return to the status screen from sub-menus +//#define LCD_TIMEOUT_TO_STATUS 15000 + +#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 + + #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? + #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. + + #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. + // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. + // using: + //#define MENU_ADDAUTOSTART + + /** + * Sort SD file listings in alphabetical order. + * + * With this option enabled, items on SD cards will be sorted + * by name for easier navigation. + * + * By default... + * + * - Use the slowest -but safest- method for sorting. + * - Folders are sorted to the top. + * - The sort key is statically allocated. + * - No added G-code (M34) support. + * - 40 item sorting limit. (Items after the first 40 are unsorted.) + * + * SD sorting uses static allocation (as set by SDSORT_LIMIT), allowing the + * compiler to calculate the worst-case usage and throw an error if the SRAM + * limit is exceeded. + * + * - SDSORT_USES_RAM provides faster sorting via a static directory buffer. + * - SDSORT_USES_STACK does the same, but uses a local stack-based buffer. + * - SDSORT_CACHE_NAMES will retain the sorted file listing in RAM. (Expensive!) + * - SDSORT_DYNAMIC_RAM only uses RAM when the SD menu is visible. (Use with caution!) + */ + //#define SDCARD_SORT_ALPHA + + // SD Card Sorting options + #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_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. + #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #endif + + // Show a progress bar on HD44780 LCDs for SD printing + //#define LCD_PROGRESS_BAR + + #if ENABLED(LCD_PROGRESS_BAR) + // Amount of time (ms) to show the bar + #define PROGRESS_BAR_BAR_TIME 2000 + // Amount of time (ms) to show the status message + #define PROGRESS_BAR_MSG_TIME 3000 + // Amount of time (ms) to retain the status message (0=forever) + #define PROGRESS_MSG_EXPIRE 0 + // Enable this to show messages for MSG_TIME then hide them + //#define PROGRESS_MSG_ONCE + // Add a menu item to test the progress bar: + //#define LCD_PROGRESS_BAR_TEST + #endif + + // This allows hosts to request long names for files and folders with M33 + //#define LONG_FILENAME_HOST_SUPPORT + + // This option allows you to abort SD printing when any endstop is triggered. + // This feature must be enabled with "M540 S1" or from the LCD menu. + // To have any effect, endstops must be enabled during SD printing. + //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + +#endif // SDSUPPORT + +/** + * Additional options for Graphical Displays + * + * Use the optimizations here to improve printing performance, + * which can be adversely affected by graphical display drawing, + * especially when doing several short moves, and when printing + * on DELTA and SCARA machines. + * + * Some of these options may result in the display lagging behind + * controller events, as there is a trade-off between reliable + * printing performance versus fast display updates. + */ +#if ENABLED(DOGLCD) + // Enable to save many cycles by drawing a hollow frame on the Info Screen + #define XYZ_HOLLOW_FRAME + + // Enable to save many cycles by drawing a hollow frame on Menu Screens + #define MENU_HOLLOW_FRAME + + // A bigger font is available for edit items. Costs 3120 bytes of PROGMEM. + // 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. + // 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 +#endif // DOGLCD + +// @section safety + +// The hardware watchdog should reset the microcontroller disabling all outputs, +// in case the firmware gets stuck and doesn't do temperature regulation. +#define USE_WATCHDOG + +#if ENABLED(USE_WATCHDOG) + // If you have a watchdog reboot in an ArduinoMega2560 then the device will hang forever, as a watchdog reset will leave the watchdog on. + // The "WATCHDOG_RESET_MANUAL" goes around this by not using the hardware reset. + // However, THIS FEATURE IS UNSAFE!, as it will only work if interrupts are disabled. And the code could hang in an interrupt routine with interrupts disabled. + //#define WATCHDOG_RESET_MANUAL +#endif + +// @section lcd + +/** + * Babystepping enables movement of the axes by tiny increments without changing + * the current position values. This feature is used primarily to adjust the Z + * axis in the first layer of a print in real-time. + * + * Warning: Does not respect endstops! + */ +//#define BABYSTEPPING +#if ENABLED(BABYSTEPPING) + //#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 100 // Babysteps are very small. Increase for faster motion. + //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping + //#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen 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_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor + //#define BABYSTEP_ZPROBE_GFX_REVERSE // Reverses the direction of the CW/CCW indicators +#endif + +// @section extruder + +/** + * Implementation of linear pressure control + * + * Assumption: advance = k * (delta velocity) + * K=0 means advance disabled. + * See Marlin documentation for calibration instructions. + */ +//#define LIN_ADVANCE + +#if ENABLED(LIN_ADVANCE) + #define LIN_ADVANCE_K 75 + + /** + * Some Slicers produce Gcode with randomly jumping extrusion widths occasionally. + * For example within a 0.4mm perimeter it may produce a single segment of 0.05mm width. + * While this is harmless for normal printing (the fluid nature of the filament will + * close this very, very tiny gap), it throws off the LIN_ADVANCE pressure adaption. + * + * For this case LIN_ADVANCE_E_D_RATIO can be used to set the extrusion:distance ratio + * to a fixed value. Note that using a fixed ratio will lead to wrong nozzle pressures + * if the slicer is using variable widths or layer heights within one print! + * + * This option sets the default E:D ratio at startup. Use `M900` to override this value. + * + * Example: `M900 W0.4 H0.2 D1.75`, where: + * - W is the extrusion width in mm + * - H is the layer height in mm + * - D is the filament diameter in mm + * + * Example: `M900 R0.0458` to set the ratio directly. + * + * Set to 0 to auto-detect the ratio based on given Gcode G1 print moves. + * + * Slic3r (including Průša Control) produces Gcode compatible with the automatic mode. + * Cura (as of this writing) may produce Gcode incompatible with the automatic mode. + */ + #define LIN_ADVANCE_E_D_RATIO 0 // The calculated ratio (or 0) according to the formula W * H / ((D / 2) ^ 2 * PI) + // Example: 0.4 * 0.2 / ((1.75 / 2) ^ 2 * PI) = 0.033260135 +#endif + +// @section leveling + +// Default mesh area is an area with an inset margin on the print area. +// Below are the macros that are used to define the borders for the mesh area, +// made available here for specialized needs, ie dual extruder setup. +#if ENABLED(MESH_BED_LEVELING) + #define MESH_MIN_X MESH_INSET + #define MESH_MAX_X (X_BED_SIZE - (MESH_INSET)) + #define MESH_MIN_Y MESH_INSET + #define MESH_MAX_Y (Y_BED_SIZE - (MESH_INSET)) +#elif ENABLED(AUTO_BED_LEVELING_UBL) + #define UBL_MESH_MIN_X UBL_MESH_INSET + #define UBL_MESH_MAX_X (X_BED_SIZE - (UBL_MESH_INSET)) + #define UBL_MESH_MIN_Y UBL_MESH_INSET + #define UBL_MESH_MAX_Y (Y_BED_SIZE - (UBL_MESH_INSET)) + + // If this is defined, the currently active mesh will be saved in the + // current slot on M500. + #define UBL_SAVE_ACTIVE_ON_M500 +#endif + +// @section extras + +// +// G2/G3 Arc Support +// +#define ARC_SUPPORT // Disable this feature to save ~3226 bytes +#if ENABLED(ARC_SUPPORT) + #define MM_PER_ARC_SEGMENT 1 // Length of each arc segment + #define N_ARC_CORRECTION 25 // Number of intertpolated 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 +#endif + +// Support for G5 with XYZE destination and IJPQ offsets. Requires ~2666 bytes. +//#define BEZIER_CURVE_SUPPORT + +// G38.2 and G38.3 Probe Target +// Enable PROBE_DOUBLE_TOUCH if you want G38 to double touch +//#define G38_PROBE_TARGET +#if ENABLED(G38_PROBE_TARGET) + #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) +#endif + +// Moves (or segments) with fewer steps than this will be joined with the next move +#define MIN_STEPS_PER_SEGMENT 6 + +// The minimum pulse width (in µs) for stepping a stepper. +// Set this if you find stepping unreliable, or if using a very fast CPU. +#define MINIMUM_STEPPER_PULSE 0 // (µs) The smallest stepper pulse allowed + +// @section temperature + +// Control heater 0 and heater 1 in parallel. +//#define HEATERS_PARALLEL + +//=========================================================================== +//================================= Buffers ================================= +//=========================================================================== + +// @section hidden + +// 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, i.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 +#else + #define BLOCK_BUFFER_SIZE 16 // maximize block buffer +#endif + +// @section serial + +// The ASCII buffer for serial input +#define MAX_CMD_SIZE 96 +#define BUFSIZE 4 + +// Transmission to Host Buffer Size +// To save 386 bytes of PROGMEM (and TX_BUFFER_SIZE+3 bytes of RAM) set to 0. +// To buffer a simple "ok" you need 4 bytes. +// For ADVANCED_OK (M105) you need 32 bytes. +// For debug-echo: 128 bytes for the optimal speed. +// Other output doesn't need to be that speedy. +// :[0, 2, 4, 8, 16, 32, 64, 128, 256] +#define TX_BUFFER_SIZE 64 + +// Host Receive Buffer Size +// Without XON/XOFF flow control (see SERIAL_XON_XOFF below) 32 bytes should be enough. +// To use flow control, set this buffer size to at least 1024 bytes. +// :[0, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048] +//#define RX_BUFFER_SIZE 1024 + +#if RX_BUFFER_SIZE >= 1024 + // Enable to have the controller send XON/XOFF control characters to + // the host to signal the RX buffer is becoming full. + //#define SERIAL_XON_XOFF +#endif + +#if ENABLED(SDSUPPORT) + // Enable this option to collect and display the maximum + // RX queue usage after transferring a file to SD. + //#define SERIAL_STATS_MAX_RX_QUEUED + + // Enable this option to collect and display the number + // of dropped bytes after a file transfer to SD. + //#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! +//#define EMERGENCY_PARSER + +// Bad Serial-connections can miss a received command by sending an 'ok' +// Therefore some clients abort after 30 seconds in a timeout. +// Some other clients start sending commands while receiving a 'wait'. +// This "wait" is only sent when the buffer is empty. 1 second is a good value here. +//#define NO_TIMEOUTS 1000 // Milliseconds + +// Some clients will have this feature soon. This could make the NO_TIMEOUTS unnecessary. +//#define ADVANCED_OK + +// @section extras + +/** + * Firmware-based and LCD-controlled retract + * + * Add G10 / G11 commands for automatic firmware-based retract / recover. + * Use M207 and M208 to define parameters for retract / recover. + * + * Use M209 to enable or disable auto-retract. + * With auto-retract enabled, all G1 E moves within the set range + * will be converted to firmware-based retract/recover moves. + * + * Be sure to turn off auto-retract during filament change. + * + * Note that M207 / M208 / M209 settings are saved to EEPROM. + * + */ +//#define FWRETRACT // ONLY PARTIALLY TESTED +#if ENABLED(FWRETRACT) + #define MIN_AUTORETRACT 0.1 // When auto-retract is on, convert E moves of this length and over + #define MAX_AUTORETRACT 10.0 // Upper limit for auto-retract conversion + #define RETRACT_LENGTH 3 // Default retract length (positive mm) + #define RETRACT_LENGTH_SWAP 13 // Default swap retract length (positive mm), for extruder change + #define RETRACT_FEEDRATE 45 // Default feedrate for retracting (mm/s) + #define RETRACT_ZLIFT 0 // Default retract Z-lift + #define RETRACT_RECOVER_LENGTH 0 // Default additional recover length (mm, added to retract length when recovering) + #define RETRACT_RECOVER_LENGTH_SWAP 0 // Default additional swap recover length (mm, added to retract length when recovering from extruder change) + #define RETRACT_RECOVER_FEEDRATE 8 // Default feedrate for recovering from retraction (mm/s) + #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) +#endif + +/** + * Advanced Pause + * Experimental feature for filament change support and for parking the nozzle when paused. + * Adds the GCode M600 for initiating filament change. + * If PARK_HEAD_ON_PAUSE enabled, adds the GCode M125 to pause printing and park the nozzle. + * + * Requires an LCD display. + * This feature is required for the default FILAMENT_RUNOUT_SCRIPT. + */ +//#define ADVANCED_PAUSE_FEATURE +#if ENABLED(ADVANCED_PAUSE_FEATURE) + #define PAUSE_PARK_X_POS 3 // X position of hotend + #define PAUSE_PARK_Y_POS 3 // Y position of hotend + #define PAUSE_PARK_Z_ADD 10 // Z addition of hotend (lift) + #define PAUSE_PARK_XY_FEEDRATE 100 // X and Y axes feedrate in mm/s (also used for delta printers Z axis) + #define PAUSE_PARK_Z_FEEDRATE 5 // Z axis feedrate in mm/s (not used for delta printers) + #define PAUSE_PARK_RETRACT_FEEDRATE 60 // Initial retract feedrate in mm/s + #define PAUSE_PARK_RETRACT_LENGTH 2 // Initial retract in mm + // It is a short retract used immediately after print interrupt before move to filament exchange position + #define FILAMENT_CHANGE_UNLOAD_FEEDRATE 10 // Unload filament feedrate in mm/s - filament unloading can be fast + #define FILAMENT_CHANGE_UNLOAD_LENGTH 100 // Unload filament length from hotend in mm + // Longer length for bowden printers to unload filament from whole bowden tube, + // shorter length for printers without bowden to unload filament from extruder only, + // 0 to disable unloading for manual unloading + #define FILAMENT_CHANGE_LOAD_FEEDRATE 6 // Load filament feedrate in mm/s - filament loading into the bowden tube can be fast + #define FILAMENT_CHANGE_LOAD_LENGTH 0 // Load filament length over hotend in mm + // Longer length for bowden printers to fast load filament into whole bowden tube over the hotend, + // Short or zero length for printers without bowden where loading is not used + #define ADVANCED_PAUSE_EXTRUDE_FEEDRATE 3 // Extrude filament feedrate in mm/s - must be slower than load feedrate + #define ADVANCED_PAUSE_EXTRUDE_LENGTH 50 // Extrude filament length in mm after filament is loaded over the hotend, + // 0 to disable for manual extrusion + // Filament can be extruded repeatedly from the filament exchange menu to fill the hotend, + // or until outcoming filament color is not clear for filament color change + #define PAUSE_PARK_NOZZLE_TIMEOUT 45 // Turn off nozzle if user doesn't change filament within this time limit in seconds + #define FILAMENT_CHANGE_NUMBER_OF_ALERT_BEEPS 5 // Number of alert beeps before printer goes quiet + #define PAUSE_PARK_NO_STEPPER_TIMEOUT // Enable to have stepper motors hold position during filament change + // even if it takes longer than DEFAULT_STEPPER_DEACTIVE_TIME. + //#define PARK_HEAD_ON_PAUSE // Go to filament change position on pause, return to print position on resume + //#define HOME_BEFORE_FILAMENT_CHANGE // Ensure homing has been completed prior to parking for filament change +#endif + +// @section tmc + +/** + * Enable this section if you have TMC26X motor drivers. + * You will need to import the TMC26XStepper library into the Arduino IDE for this + * (https://github.com/trinamic/TMC26XStepper.git) + */ +//#define HAVE_TMCDRIVER + +#if ENABLED(HAVE_TMCDRIVER) + + //#define X_IS_TMC + //#define X2_IS_TMC + //#define Y_IS_TMC + //#define Y2_IS_TMC + //#define Z_IS_TMC + //#define Z2_IS_TMC + //#define E0_IS_TMC + //#define E1_IS_TMC + //#define E2_IS_TMC + //#define E3_IS_TMC + //#define E4_IS_TMC + + #define X_MAX_CURRENT 1000 // in mA + #define X_SENSE_RESISTOR 91 // in mOhms + #define X_MICROSTEPS 16 // number of microsteps + + #define X2_MAX_CURRENT 1000 + #define X2_SENSE_RESISTOR 91 + #define X2_MICROSTEPS 16 + + #define Y_MAX_CURRENT 1000 + #define Y_SENSE_RESISTOR 91 + #define Y_MICROSTEPS 16 + + #define Y2_MAX_CURRENT 1000 + #define Y2_SENSE_RESISTOR 91 + #define Y2_MICROSTEPS 16 + + #define Z_MAX_CURRENT 1000 + #define Z_SENSE_RESISTOR 91 + #define Z_MICROSTEPS 16 + + #define Z2_MAX_CURRENT 1000 + #define Z2_SENSE_RESISTOR 91 + #define Z2_MICROSTEPS 16 + + #define E0_MAX_CURRENT 1000 + #define E0_SENSE_RESISTOR 91 + #define E0_MICROSTEPS 16 + + #define E1_MAX_CURRENT 1000 + #define E1_SENSE_RESISTOR 91 + #define E1_MICROSTEPS 16 + + #define E2_MAX_CURRENT 1000 + #define E2_SENSE_RESISTOR 91 + #define E2_MICROSTEPS 16 + + #define E3_MAX_CURRENT 1000 + #define E3_SENSE_RESISTOR 91 + #define E3_MICROSTEPS 16 + + #define E4_MAX_CURRENT 1000 + #define E4_SENSE_RESISTOR 91 + #define E4_MICROSTEPS 16 + +#endif + +// @section TMC2130 + +/** + * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. + * + * You'll also need the TMC2130Stepper Arduino library + * (https://github.com/teemuatlut/TMC2130Stepper). + * + * To use TMC2130 stepper drivers in SPI mode connect your SPI2130 pins to + * the hardware SPI interface on your board and define the required CS pins + * in your `pins_MYBOARD.h` file. (e.g., RAMPS 1.4 uses AUX3 pins `X_CS_PIN 53`, `Y_CS_PIN 49`, etc.). + */ +//#define HAVE_TMC2130 + +#if ENABLED(HAVE_TMC2130) + + // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY + //#define X_IS_TMC2130 + //#define X2_IS_TMC2130 + //#define Y_IS_TMC2130 + //#define Y2_IS_TMC2130 + //#define Z_IS_TMC2130 + //#define Z2_IS_TMC2130 + //#define E0_IS_TMC2130 + //#define E1_IS_TMC2130 + //#define E2_IS_TMC2130 + //#define E3_IS_TMC2130 + //#define E4_IS_TMC2130 + + /** + * Stepper driver settings + */ + + #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 + #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current + #define INTERPOLATE 1 // Interpolate X/Y/Z_MICROSTEPS to 256 + + #define X_CURRENT 1000 // rms current in mA. Multiply by 1.41 for peak current. + #define X_MICROSTEPS 16 // 0..256 + + #define Y_CURRENT 1000 + #define Y_MICROSTEPS 16 + + #define Z_CURRENT 1000 + #define Z_MICROSTEPS 16 + + //#define X2_CURRENT 1000 + //#define X2_MICROSTEPS 16 + + //#define Y2_CURRENT 1000 + //#define Y2_MICROSTEPS 16 + + //#define Z2_CURRENT 1000 + //#define Z2_MICROSTEPS 16 + + //#define E0_CURRENT 1000 + //#define E0_MICROSTEPS 16 + + //#define E1_CURRENT 1000 + //#define E1_MICROSTEPS 16 + + //#define E2_CURRENT 1000 + //#define E2_MICROSTEPS 16 + + //#define E3_CURRENT 1000 + //#define E3_MICROSTEPS 16 + + //#define E4_CURRENT 1000 + //#define E4_MICROSTEPS 16 + + /** + * Use Trinamic's ultra quiet stepping mode. + * When disabled, Marlin will use spreadCycle stepping mode. + */ + #define STEALTHCHOP + + /** + * Let Marlin automatically control stepper current. + * This is still an experimental feature. + * Increase current every 5s by CURRENT_STEP until stepper temperature prewarn gets triggered, + * then decrease current by CURRENT_STEP until temperature prewarn is cleared. + * Adjusting starts from X/Y/Z/E_CURRENT but will not increase over AUTO_ADJUST_MAX + * 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. + * M906 S1 - Start adjusting current + * M906 S0 - Stop adjusting current + * M911 - Report stepper driver overtemperature pre-warn condition. + * M912 - Clear stepper driver overtemperature pre-warn condition flag. + */ + //#define AUTOMATIC_CURRENT_CONTROL + + #if ENABLED(AUTOMATIC_CURRENT_CONTROL) + #define CURRENT_STEP 50 // [mA] + #define AUTO_ADJUST_MAX 1300 // [mA], 1300mA_rms = 1840mA_peak + #define REPORT_CURRENT_CHANGE + #endif + + /** + * The driver will switch to spreadCycle when stepper speed is over HYBRID_THRESHOLD. + * This mode allows for faster movements at the expense of higher noise levels. + * STEALTHCHOP needs to be enabled. + * M913 X/Y/Z/E to live tune the setting + */ + //#define HYBRID_THRESHOLD + + #define X_HYBRID_THRESHOLD 100 // [mm/s] + #define X2_HYBRID_THRESHOLD 100 + #define Y_HYBRID_THRESHOLD 100 + #define Y2_HYBRID_THRESHOLD 100 + #define Z_HYBRID_THRESHOLD 4 + #define Z2_HYBRID_THRESHOLD 4 + #define E0_HYBRID_THRESHOLD 30 + #define E1_HYBRID_THRESHOLD 30 + #define E2_HYBRID_THRESHOLD 30 + #define E3_HYBRID_THRESHOLD 30 + #define E4_HYBRID_THRESHOLD 30 + + /** + * Use stallGuard2 to sense an obstacle and trigger an endstop. + * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. + * If used along with STEALTHCHOP, the movement will be louder when homing. This is normal. + * + * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. + * Higher values make the system LESS sensitive. + * Lower value make the system MORE sensitive. + * Too low values can lead to false positives, while too high values will collide the axis without triggering. + * It is advised to set X/Y_HOME_BUMP_MM to 0. + * M914 X/Y to live tune the setting + */ + //#define SENSORLESS_HOMING + + #if ENABLED(SENSORLESS_HOMING) + #define X_HOMING_SENSITIVITY 19 + #define Y_HOMING_SENSITIVITY 19 + #endif + + /** + * You can set your own advanced settings by filling in predefined functions. + * A list of available functions can be found on the library github page + * https://github.com/teemuatlut/TMC2130Stepper + * + * Example: + * #define TMC2130_ADV() { \ + * stepperX.diag0_temp_prewarn(1); \ + * stepperX.interpolate(0); \ + * } + */ + #define TMC2130_ADV() { } + +#endif // HAVE_TMC2130 + +// @section L6470 + +/** + * Enable this section if you have L6470 motor drivers. + * You need to import the L6470 library into the Arduino IDE for this. + * (https://github.com/ameyer/Arduino-L6470) + */ + +//#define HAVE_L6470DRIVER +#if ENABLED(HAVE_L6470DRIVER) + + //#define X_IS_L6470 + //#define X2_IS_L6470 + //#define Y_IS_L6470 + //#define Y2_IS_L6470 + //#define Z_IS_L6470 + //#define Z2_IS_L6470 + //#define E0_IS_L6470 + //#define E1_IS_L6470 + //#define E2_IS_L6470 + //#define E3_IS_L6470 + //#define E4_IS_L6470 + + #define X_MICROSTEPS 16 // number of microsteps + #define X_K_VAL 50 // 0 - 255, Higher values, are higher power. Be careful not to go too high + #define X_OVERCURRENT 2000 // maxc current in mA. If the current goes over this value, the driver will switch off + #define X_STALLCURRENT 1500 // current in mA where the driver will detect a stall + + #define X2_MICROSTEPS 16 + #define X2_K_VAL 50 + #define X2_OVERCURRENT 2000 + #define X2_STALLCURRENT 1500 + + #define Y_MICROSTEPS 16 + #define Y_K_VAL 50 + #define Y_OVERCURRENT 2000 + #define Y_STALLCURRENT 1500 + + #define Y2_MICROSTEPS 16 + #define Y2_K_VAL 50 + #define Y2_OVERCURRENT 2000 + #define Y2_STALLCURRENT 1500 + + #define Z_MICROSTEPS 16 + #define Z_K_VAL 50 + #define Z_OVERCURRENT 2000 + #define Z_STALLCURRENT 1500 + + #define Z2_MICROSTEPS 16 + #define Z2_K_VAL 50 + #define Z2_OVERCURRENT 2000 + #define Z2_STALLCURRENT 1500 + + #define E0_MICROSTEPS 16 + #define E0_K_VAL 50 + #define E0_OVERCURRENT 2000 + #define E0_STALLCURRENT 1500 + + #define E1_MICROSTEPS 16 + #define E1_K_VAL 50 + #define E1_OVERCURRENT 2000 + #define E1_STALLCURRENT 1500 + + #define E2_MICROSTEPS 16 + #define E2_K_VAL 50 + #define E2_OVERCURRENT 2000 + #define E2_STALLCURRENT 1500 + + #define E3_MICROSTEPS 16 + #define E3_K_VAL 50 + #define E3_OVERCURRENT 2000 + #define E3_STALLCURRENT 1500 + + #define E4_MICROSTEPS 16 + #define E4_K_VAL 50 + #define E4_OVERCURRENT 2000 + #define E4_STALLCURRENT 1500 + +#endif + +/** + * TWI/I2C BUS + * + * This feature is an EXPERIMENTAL feature so it shall not be used on production + * machines. Enabling this will allow you to send and receive I2C data from slave + * devices on the bus. + * + * ; Example #1 + * ; This macro send the string "Marlin" to the slave device with address 0x63 (99) + * ; It uses multiple M260 commands with one B arg + * M260 A99 ; Target slave address + * M260 B77 ; M + * M260 B97 ; a + * M260 B114 ; r + * M260 B108 ; l + * M260 B105 ; i + * M260 B110 ; n + * M260 S1 ; Send the current buffer + * + * ; Example #2 + * ; Request 6 bytes from slave device with address 0x63 (99) + * M261 A99 B5 + * + * ; Example #3 + * ; Example serial output of a M261 request + * echo:i2c-reply: from:99 bytes:5 data:hello + */ + +// @section i2cbus + +//#define EXPERIMENTAL_I2CBUS +#define I2C_SLAVE_ADDRESS 0 // Set a value from 8 to 127 to act as a slave + +// @section extras + +/** + * Spindle & Laser control + * + * Add the M3, M4, and M5 commands to turn the spindle/laser on and off, and + * to set spindle speed, spindle direction, and laser power. + * + * SuperPid is a router/spindle speed controller used in the CNC milling community. + * Marlin can be used to turn the spindle on and off. It can also be used to set + * the spindle speed from 5,000 to 30,000 RPM. + * + * 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. + */ +//#define SPINDLE_LASER_ENABLE +#if ENABLED(SPINDLE_LASER_ENABLE) + + #define SPINDLE_LASER_ENABLE_INVERT false // set to "true" if the on/off function is reversed + #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 // delay in milliseconds to allow the spindle/laser to come up to speed/power + #define SPINDLE_LASER_POWERDOWN_DELAY 5000 // delay in milliseconds to allow the spindle to stop + #define SPINDLE_DIR_CHANGE true // set to true if your spindle controller supports changing spindle direction + #define SPINDLE_INVERT_DIR false + #define SPINDLE_STOP_ON_DIR_CHANGE true // set to true if Marlin should stop the spindle before changing rotation direction + + /** + * The M3 & M4 commands use the following equation to convert PWM duty cycle to speed/power + * + * SPEED/POWER = PWM duty cycle * SPEED_POWER_SLOPE + SPEED_POWER_INTERCEPT + * where PWM duty cycle varies from 0 to 255 + * + * set the following for your controller (ALL MUST BE SET) + */ + + #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_SLOPE 0.3922 + //#define SPEED_POWER_INTERCEPT 0 + //#define SPEED_POWER_MIN 10 + //#define SPEED_POWER_MAX 100 // 0-100% +#endif + +/** + * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins + */ +//#define PINS_DEBUGGING + +/** + * Auto-report temperatures with M155 S + */ +#define AUTO_REPORT_TEMPERATURES + +/** + * Include capabilities in M115 output + */ +#define EXTENDED_CAPABILITIES_REPORT + +/** + * Volumetric extrusion default state + * 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. + */ +//#define VOLUMETRIC_DEFAULT_ON + +/** + * Enable this option for a leaner build of Marlin that removes all + * workspace offsets, simplifying coordinate transformations, leveling, etc. + * + * - M206 and M428 are disabled. + * - G92 will revert to its behavior from Marlin 1.0. + */ +//#define NO_WORKSPACE_OFFSETS + +/** + * 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. + * + * For clients that use a fixed-width font (like OctoPrint), leave this set to 1.0. + * Otherwise, adjust according to your client and font. + */ +#define PROPORTIONAL_FONT_RATIO 1.0 + +/** + * Spend 28 bytes of SRAM to optimize the GCode parser + */ +#define FASTER_GCODE_PARSER + +/** + * User-defined menu items that execute custom GCode + */ +//#define CUSTOM_USER_MENUS +#if ENABLED(CUSTOM_USER_MENUS) + #define USER_SCRIPT_DONE "M117 User Script Done" + #define USER_SCRIPT_AUDIBLE_FEEDBACK + //#define USER_SCRIPT_RETURN // Return to status screen after a script + + #define USER_DESC_1 "Home & UBL Info" + #define USER_GCODE_1 "G28\nG29 W" + + #define USER_DESC_2 "Preheat for PLA" + #define USER_GCODE_2 "M140 S" STRINGIFY(PREHEAT_1_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND) + + #define USER_DESC_3 "Preheat for ABS" + #define USER_GCODE_3 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND) + + #define USER_DESC_4 "Heat Bed/Home/Level" + #define USER_GCODE_4 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nG28\nG29" + + //#define USER_DESC_5 "Home & Info" + //#define USER_GCODE_5 "G28\nM503" +#endif + +/** + * Specify an action command to send to the host when the printer is killed. + * Will be sent in the form '//action:ACTION_ON_KILL', e.g. '//action:poweroff'. + * The host must be configured to handle the action command. + */ +//#define ACTION_ON_KILL "poweroff" + +//=========================================================================== +//====================== I2C Position Encoder Settings ====================== +//=========================================================================== + +/** + * I2C position encoders for closed loop control. + * Developed by Chris Barr at Aus3D. + * + * Wiki: http://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/ + * + * Reilabuild encoders have been modified to improve reliability. + */ + +//#define I2C_POSITION_ENCODERS +#if ENABLED(I2C_POSITION_ENCODERS) + + #define I2CPE_ENCODER_CNT 1 // The number of encoders installed; max of 5 + // encoders supported currently. + + #define I2CPE_ENC_1_ADDR I2CPE_PRESET_ADDR_X // I2C address of the encoder. 30-200. + #define I2CPE_ENC_1_AXIS X_AXIS // Axis the encoder module is installed on. _AXIS. + #define I2CPE_ENC_1_TYPE I2CPE_ENC_TYPE_LINEAR // Type of encoder: I2CPE_ENC_TYPE_LINEAR -or- + // I2CPE_ENC_TYPE_ROTARY. + #define I2CPE_ENC_1_TICKS_UNIT 2048 // 1024 for magnetic strips with 2mm poles; 2048 for + // 1mm poles. For linear encoders this is ticks / mm, + // for rotary encoders this is ticks / revolution. + //#define I2CPE_ENC_1_TICKS_REV (16 * 200) // Only needed for rotary encoders; number of stepper + // steps per full revolution (motor steps/rev * microstepping) + //#define I2CPE_ENC_1_INVERT // Invert the direction of axis travel. + #define I2CPE_ENC_1_EC_METHOD I2CPE_ECM_NONE // Type of error error correction. + #define I2CPE_ENC_1_EC_THRESH 0.10 // Threshold size for error (in mm) above which the + // printer will attempt to correct the error; errors + // smaller than this are ignored to minimize effects of + // measurement noise / latency (filter). + + #define I2CPE_ENC_2_ADDR I2CPE_PRESET_ADDR_Y // Same as above, but for encoder 2. + #define I2CPE_ENC_2_AXIS Y_AXIS + #define I2CPE_ENC_2_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_ENC_2_TICKS_UNIT 2048 + //#define I2CPE_ENC_2_TICKS_REV (16 * 200) + //#define I2CPE_ENC_2_INVERT + #define I2CPE_ENC_2_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_ENC_2_EC_THRESH 0.10 + + #define I2CPE_ENC_3_ADDR I2CPE_PRESET_ADDR_Z // Encoder 3. Add additional configuration options + #define I2CPE_ENC_3_AXIS Z_AXIS // as above, or use defaults below. + + #define I2CPE_ENC_4_ADDR I2CPE_PRESET_ADDR_E // Encoder 4. + #define I2CPE_ENC_4_AXIS E_AXIS + + #define I2CPE_ENC_5_ADDR 34 // Encoder 5. + #define I2CPE_ENC_5_AXIS E_AXIS + + // Default settings for encoders which are enabled, but without settings configured above. + #define I2CPE_DEF_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_DEF_ENC_TICKS_UNIT 2048 + #define I2CPE_DEF_TICKS_REV (16 * 200) + #define I2CPE_DEF_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_DEF_EC_THRESH 0.1 + + //#define I2CPE_ERR_THRESH_ABORT 100.0 // Threshold size for error (in mm) error on any given + // axis after which the printer will abort. Comment out to + // disable abort behaviour. + + #define I2CPE_TIME_TRUSTED 10000 // After an encoder fault, there must be no further fault + // for this amount of time (in ms) before the encoder + // is trusted again. + + /** + * Position is checked every time a new command is executed from the buffer but during long moves, + * this setting determines the minimum update time between checks. A value of 100 works well with + * error rolling average when attempting to correct only for skips and not for vibration. + */ + #define I2CPE_MIN_UPD_TIME_MS 100 // Minimum time in miliseconds between encoder checks. + + // Use a rolling average to identify persistant errors that indicate skips, as opposed to vibration and noise. + #define I2CPE_ERR_ROLLING_AVERAGE + +#endif // I2C_POSITION_ENCODERS + +/** + * MAX7219 Debug Matrix + * + * Add support for a low-cost 8x8 LED Matrix based on the Max7219 chip, which can be used as a status + * display. Requires 3 signal wires. Some useful debug options are included to demonstrate its usage. + * + * Fully assembled MAX7219 boards can be found on the internet for under $2(US). + * For example, see https://www.ebay.com/sch/i.html?_nkw=332349290049 + */ +//#define MAX7219_DEBUG +#if ENABLED(MAX7219_DEBUG) + #define MAX7219_CLK_PIN 64 // 77 on Re-ARM // Configuration of the 3 pins to control the display + #define MAX7219_DIN_PIN 57 // 78 on Re-ARM + #define MAX7219_LOAD_PIN 44 // 79 on Re-ARM + + /** + * Sample debug features + * If you add more debug displays, be careful to avoid conflicts! + */ + #define MAX7219_DEBUG_PRINTER_ALIVE // Blink corner LED of 8x8 matrix to show that the firmware is functioning + #define MAX7219_DEBUG_STEPPER_HEAD 3 // Show the stepper queue head position on this and the next LED matrix row + #define MAX7219_DEBUG_STEPPER_TAIL 5 // Show the stepper queue tail position on this and the next LED matrix row + + #define MAX7219_DEBUG_STEPPER_QUEUE 0 // Show the current stepper queue depth on this and the next LED matrix row + // If you experience stuttering, reboots, etc. this option can reveal how + // tweaks made to the configuration are affecting the printer in real-time. +#endif + +#endif // CONFIGURATION_ADV_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/Velleman/K8200/Configuration.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/Velleman/K8200/Configuration.h new file mode 100644 index 00000000..acd732e0 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/Velleman/K8200/Configuration.h @@ -0,0 +1,1735 @@ +/** + * 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 . + * + */ + +/** + * Configuration.h + * + * Basic settings such as: + * + * - Type of electronics + * - Type of temperature sensor + * - Printer geometry + * - Endstop configuration + * - LCD controller + * - Extra features + * + * Advanced settings can be found in Configuration_adv.h + * + */ +#ifndef CONFIGURATION_H +#define CONFIGURATION_H +#define CONFIGURATION_H_VERSION 010100 + +/** + * Sample configuration file for Vellemann K8200 + * tested on K8200 with VM8201 (Display) + * and Arduino 1.6.12 (Mac OS X) by @CONSULitAS, 2016-11-18 + * https://github.com/CONSULitAS/Marlin-K8200/archive/K8200_stable_2016-11-18.zip + * + * Please choose your hardware options for the K8200: + */ + +// VM8201 Display unit +#define K8200_VM8201 +// K8204 Z axis upgrade rod and coupler -> TODO +// #define K8200_K8204 +// K8203 direct drive extruder -> TODO +// #define K8200_K8203 + +//=========================================================================== +//============================= Getting Started ============================= +//=========================================================================== + +/** + * Here are some standard links for getting your machine calibrated: + * + * http://reprap.org/wiki/Calibration + * http://youtu.be/wAL9d7FgInk + * http://calculator.josefprusa.cz + * http://reprap.org/wiki/Triffid_Hunter%27s_Calibration_Guide + * http://www.thingiverse.com/thing:5573 + * https://sites.google.com/site/repraplogphase/calibration-of-your-reprap + * http://www.thingiverse.com/thing:298812 + */ + +//=========================================================================== +//============================= DELTA Printer =============================== +//=========================================================================== +// For a Delta printer start with one of the configuration files in the +// example_configurations/delta directory and customize for your machine. +// + +//=========================================================================== +//============================= SCARA Printer =============================== +//=========================================================================== +// For a SCARA printer start with the configuration files in +// example_configurations/SCARA and customize for your machine. +// + +// @section info + +// User-specified version info of this build to display in [Pronterface, etc] terminal window during +// startup. Implementation of an idea by Prof Braino to inform user that any changes made to this +// build by the user have been successfully uploaded into firmware. +#define STRING_CONFIG_H_AUTHOR "(K8200, @CONSULitAS)" // Who made the changes. +#define SHOW_BOOTSCREEN +#define STRING_SPLASH_LINE1 SHORT_BUILD_VERSION // will be shown during bootup in line 1 +#define STRING_SPLASH_LINE2 WEBSITE_URL // will be shown during bootup in line 2 + +// +// *** VENDORS PLEASE READ ***************************************************** +// +// Marlin now allow you to have a vendor boot image to be displayed on machine +// start. When SHOW_CUSTOM_BOOTSCREEN is defined Marlin will first show your +// custom boot image and then the default Marlin boot image is shown. +// +// We suggest for you to take advantage of this new feature and keep the Marlin +// boot image unmodified. For an example have a look at the bq Hephestos 2 +// example configuration folder. +// +//#define SHOW_CUSTOM_BOOTSCREEN +// @section machine + +/** + * Select which serial port on the board will be used for communication with the host. + * This allows the connection of wireless adapters (for instance) to non-default port pins. + * Serial port 0 is always used by the Arduino bootloader regardless of this setting. + * + * :[0, 1, 2, 3, 4, 5, 6, 7] + */ +#define SERIAL_PORT 0 + +/** + * This setting determines the communication speed of the printer. + * + * 250000 works in most cases, but you might try a lower speed if + * you commonly experience drop-outs during host printing. + * You may try up to 1000000 to speed up SD file transfer. + * + * :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000] + */ +#define BAUDRATE 250000 + +// Enable the Bluetooth serial interface on AT90USB devices +//#define BLUETOOTH + +// The following define selects which electronics board you have. +// Please choose the name from boards.h that matches your setup +#ifndef MOTHERBOARD + #define MOTHERBOARD BOARD_K8200 +#endif + +// Optional custom name for your RepStrap or other custom machine +// Displayed in the LCD "Ready" message +#define CUSTOM_MACHINE_NAME "K8200" + +// Define this to set a unique identifier for this printer, (Used by some programs to differentiate between machines) +// You can use an online service to generate a random UUID. (eg http://www.uuidgenerator.net/version4) +#if ENABLED(K8200_VM8201) + #define MACHINE_UUID "2b7dea3b-844e-4ab1-aa96-bb6406607d6e" // K8200 standard config with VM8201 (Display) +#else + #define MACHINE_UUID "92f72de1-c211-452e-9f2b-61ef88a4751e" // K8200 standard config without VM8201 (Display) +#endif + +// @section extruder + +// This defines the number of extruders +// :[1, 2, 3, 4, 5] +#define EXTRUDERS 1 + +// For Cyclops or any "multi-extruder" that shares a single nozzle. +//#define SINGLENOZZLE + +/** + * Průša MK2 Single Nozzle Multi-Material Multiplexer, and variants. + * + * This device allows one stepper driver on a control board to drive + * two to eight stepper motors, one at a time, in a manner suitable + * for extruders. + * + * This option only allows the multiplexer to switch on tool-change. + * Additional options to configure custom E moves are pending. + */ +//#define MK2_MULTIPLEXER +#if ENABLED(MK2_MULTIPLEXER) + // Override the default DIO selector pins here, if needed. + // Some pins files may provide defaults for these pins. + //#define E_MUX0_PIN 40 // Always Required + //#define E_MUX1_PIN 42 // Needed for 3 to 8 steppers + //#define E_MUX2_PIN 44 // Needed for 5 to 8 steppers +#endif + +// A dual extruder that uses a single stepper motor +//#define SWITCHING_EXTRUDER +#if ENABLED(SWITCHING_EXTRUDER) + #define SWITCHING_EXTRUDER_SERVO_NR 0 + #define SWITCHING_EXTRUDER_SERVO_ANGLES { 0, 90 } // Angles for E0, E1[, E2, E3] + #if EXTRUDERS > 3 + #define SWITCHING_EXTRUDER_E23_SERVO_NR 1 + #endif +#endif + +// A dual-nozzle that uses a servomotor to raise/lower one of the nozzles +//#define SWITCHING_NOZZLE +#if ENABLED(SWITCHING_NOZZLE) + #define SWITCHING_NOZZLE_SERVO_NR 0 + #define SWITCHING_NOZZLE_SERVO_ANGLES { 0, 90 } // Angles for E0, E1 + //#define HOTEND_OFFSET_Z { 0.0, 0.0 } +#endif + +/** + * Two separate X-carriages with extruders that connect to a moving part + * via a magnetic docking mechanism. Requires SOL1_PIN and SOL2_PIN. + */ +//#define PARKING_EXTRUDER +#if ENABLED(PARKING_EXTRUDER) + #define PARKING_EXTRUDER_SOLENOIDS_INVERT // If enabled, the solenoid is NOT magnetized with applied voltage + #define PARKING_EXTRUDER_SOLENOIDS_PINS_ACTIVE LOW // LOW or HIGH pin signal energizes the coil + #define PARKING_EXTRUDER_SOLENOIDS_DELAY 250 // Delay (ms) for magnetic field. No delay if 0 or not defined. + #define PARKING_EXTRUDER_PARKING_X { -78, 184 } // X positions for parking the extruders + #define PARKING_EXTRUDER_GRAB_DISTANCE 1 // mm to move beyond the parking point to grab the extruder + #define PARKING_EXTRUDER_SECURITY_RAISE 5 // Z-raise before parking + #define HOTEND_OFFSET_Z { 0.0, 1.3 } // Z-offsets of the two hotends. The first must be 0. +#endif + +/** + * "Mixing Extruder" + * - Adds a new code, M165, to set the current mix factors. + * - Extends the stepping routines to move multiple steppers in proportion to the mix. + * - Optional support for Repetier Firmware M163, M164, and virtual extruder. + * - This implementation supports only a single extruder. + * - Enable DIRECT_MIXING_IN_G1 for Pia Taubert's reference implementation + */ +//#define MIXING_EXTRUDER +#if ENABLED(MIXING_EXTRUDER) + #define MIXING_STEPPERS 2 // Number of steppers in your mixing extruder + #define MIXING_VIRTUAL_TOOLS 16 // Use the Virtual Tool method with M163 and M164 + //#define DIRECT_MIXING_IN_G1 // Allow ABCDHI mix factors in G1 movement commands +#endif + +// Offset of the extruders (uncomment if using more than one and relying on firmware to position when changing). +// The offset has to be X=0, Y=0 for the extruder 0 hotend (default extruder). +// For the other hotends it is their distance from the extruder 0 hotend. +//#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis +//#define HOTEND_OFFSET_Y {0.0, 5.00} // (in mm) for each extruder, offset of the hotend on the Y axis + +// @section machine + +/** + * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN + * + * 0 = No Power Switch + * 1 = ATX + * 2 = X-Box 360 203Watts (the blue wire connected to PS_ON and the red wire to VCC) + * + * :{ 0:'No power switch', 1:'ATX', 2:'X-Box 360' } + */ +#define POWER_SUPPLY 0 + +#if POWER_SUPPLY > 0 + // Enable this option to leave the PSU off at startup. + // Power to steppers and heaters will need to be turned on with M80. + //#define PS_DEFAULT_OFF +#endif + +// @section temperature + +//=========================================================================== +//============================= Thermal Settings ============================ +//=========================================================================== + +/** + * --NORMAL IS 4.7kohm PULLUP!-- 1kohm pullup can be used on hotend sensor, using correct resistor and table + * + * Temperature sensors available: + * + * -3 : thermocouple with MAX31855 (only for sensor 0) + * -2 : thermocouple with MAX6675 (only for sensor 0) + * -1 : thermocouple with AD595 + * 0 : not used + * 1 : 100k thermistor - best choice for EPCOS 100k (4.7k pullup) + * 2 : 200k thermistor - ATC Semitec 204GT-2 (4.7k pullup) + * 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 (Used in ParCan & J-Head) (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) + * 71 : 100k Honeywell thermistor 135-104LAF-J01 (4.7k pullup) + * 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) + * 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" + * 20 : the PT100 circuit found in the Ultimainboard V2.x + * 60 : 100k Maker's Tool Works Kapton Bed Thermistor beta=3950 + * 66 : 4.7M High Temperature thermistor from Dyze Design + * 70 : the 100K thermistor found in the bq Hephestos 2 + * 75 : 100k Generic Silicon Heat Pad with NTC 100K MGB18-104F39050L32 thermistor + * + * 1k ohm pullup tables - This is atypical, and requires changing out the 4.7k pullup for 1k. + * (but gives greater accuracy and more stable PID) + * 51 : 100k thermistor - EPCOS (1k pullup) + * 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 + * 1010 : Pt1000 with 1k pullup (non standard) + * 147 : Pt100 with 4k7 pullup + * 110 : Pt100 with 1k pullup (non standard) + * + * Use these for Testing or Development purposes. NEVER for production machine. + * 998 : Dummy Table that ALWAYS reads 25°C or the temperature defined below. + * 999 : Dummy Table that ALWAYS reads 100°C or the temperature defined below. + * + * :{ '0': "Not used", '1':"100k / 4.7k - EPCOS", '2':"200k / 4.7k - ATC Semitec 204GT-2", '3':"Mendel-parts / 4.7k", '4':"10k !! do not use for a hotend. Bad resolution at high temp. !!", '5':"100K / 4.7k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '6':"100k / 4.7k EPCOS - Not as accurate as Table 1", '7':"100k / 4.7k Honeywell 135-104LAG-J01", '8':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT", '9':"100k / 4.7k GE Sensing AL03006-58.2K-97-G1", '10':"100k / 4.7k RS 198-961", '11':"100k / 4.7k beta 3950 1%", '12':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT (calibrated for Makibox hot bed)", '13':"100k Hisens 3950 1% up to 300°C for hotend 'Simple ONE ' & hotend 'All In ONE'", '20':"PT100 (Ultimainboard V2.x)", '51':"100k / 1k - EPCOS", '52':"200k / 1k - ATC Semitec 204GT-2", '55':"100k / 1k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '60':"100k Maker's Tool Works Kapton Bed Thermistor beta=3950", '66':"Dyze Design 4.7M High Temperature thermistor", '70':"the 100K thermistor found in the bq Hephestos 2", '71':"100k / 4.7k Honeywell 135-104LAF-J01", '147':"Pt100 / 4.7k", '1047':"Pt1000 / 4.7k", '110':"Pt100 / 1k (non-standard)", '1010':"Pt1000 / 1k (non standard)", '-3':"Thermocouple + MAX31855 (only for sensor 0)", '-2':"Thermocouple + MAX6675 (only for sensor 0)", '-1':"Thermocouple + AD595",'998':"Dummy 1", '999':"Dummy 2" } + */ +#define TEMP_SENSOR_0 5 +#define TEMP_SENSOR_1 0 +#define TEMP_SENSOR_2 0 +#define TEMP_SENSOR_3 0 +#define TEMP_SENSOR_4 0 +#define TEMP_SENSOR_BED 5 + +// Dummy thermistor constant temperature readings, for use with 998 and 999 +#define DUMMY_THERMISTOR_998_VALUE 25 +#define DUMMY_THERMISTOR_999_VALUE 100 + +// 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 +#define MAX_REDUNDANT_TEMP_SENSOR_DIFF 10 + +// Extruder temperature must be close to target for this long before M109 returns success +#define TEMP_RESIDENCY_TIME 10 // (seconds) +#define TEMP_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// Bed temperature must be close to target for this long before M190 returns success +#define TEMP_BED_RESIDENCY_TIME 10 // (seconds) +#define TEMP_BED_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_BED_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// The minimal temperature defines the temperature below which the heater will not be enabled It is used +// to check that the wiring to the thermistor is not broken. +// Otherwise this would lead to the heater being powered on all the time. +#define HEATER_0_MINTEMP 5 +#define HEATER_1_MINTEMP 5 +#define HEATER_2_MINTEMP 5 +#define HEATER_3_MINTEMP 5 +#define HEATER_4_MINTEMP 5 +#define BED_MINTEMP 5 + +// When temperature exceeds max temp, your heater will be switched off. +// This feature exists to protect your hotend from overheating accidentally, but *NOT* from thermistor short/failure! +// You should use MINTEMP for thermistor short/failure protection. +#define HEATER_0_MAXTEMP 275 +#define HEATER_1_MAXTEMP 275 +#define HEATER_2_MAXTEMP 275 +#define HEATER_3_MAXTEMP 275 +#define HEATER_4_MAXTEMP 275 +#define BED_MAXTEMP 150 + +//=========================================================================== +//============================= PID Settings ================================ +//=========================================================================== +// PID Tuning Guide here: http://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 +#if ENABLED(PIDTEMP) + //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. + //#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. + #define K1 0.95 //smoothing factor within the PID + + // 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 + + // Vellemann K8200 Extruder - calculated with PID Autotune and tested + #define DEFAULT_Kp 24.29 + #define DEFAULT_Ki 1.58 + #define DEFAULT_Kd 93.51 +#endif // PIDTEMP + +//=========================================================================== +//============================= PID > Bed Temperature Control =============== +//=========================================================================== +// Select PID or bang-bang with PIDTEMPBED. If bang-bang, BED_LIMIT_SWITCHING will enable hysteresis +// +// Uncomment this to enable PID on the bed. It uses the same frequency PWM as the extruder. +// If your PID_dT is the default, and correct for your hardware/configuration, that means 7.689Hz, +// which is fine for driving a square wave into a resistive load and does not significantly impact you FET heating. +// This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W heater. +// If your configuration is significantly different than this and you don't understand the issues involved, you probably +// shouldn't use bed PID until someone else verifies your hardware works. +// If this is enabled, find your own PID constants below. +#define PIDTEMPBED + +//#define BED_LIMIT_SWITCHING + +// This sets the max power delivered to the bed, and replaces the HEATER_BED_DUTY_CYCLE_DIVIDER option. +// all forms of bed control obey this (PID, bang-bang, bang-bang with hysteresis) +// setting this to anything other than 255 enables a form of PWM to the bed just like HEATER_BED_DUTY_CYCLE_DIVIDER did, +// so you shouldn't use it unless you are OK with PWM on your bed. (see the comment on enabling PIDTEMPBED) +#define MAX_BED_POWER 255 // limits duty cycle to bed; 255=full current + +#if ENABLED(PIDTEMPBED) + + //#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) + //#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. + + // Vellemann K8200 PCB heatbed with standard PCU at 60 degreesC - calculated with PID Autotune and tested + // from pidautotune + #define DEFAULT_bedKp 341.88 + #define DEFAULT_bedKi 25.32 + #define DEFAULT_bedKd 1153.89 +#endif // PIDTEMPBED + +// @section extruder + +// This option prevents extrusion if the temperature is below EXTRUDE_MINTEMP. +// It also enables the M302 command to set the minimum extrusion temperature +// or to allow moving the extruder regardless of the hotend temperature. +// *** IT IS HIGHLY RECOMMENDED TO LEAVE THIS OPTION ENABLED! *** +#define PREVENT_COLD_EXTRUSION +#define EXTRUDE_MINTEMP 170 + +// This option prevents a single extrusion longer than EXTRUDE_MAXLENGTH. +// Note that for Bowden Extruders a too-small value here may prevent loading. +#define PREVENT_LENGTHY_EXTRUDE +#define EXTRUDE_MAXLENGTH 200 + +//=========================================================================== +//======================== Thermal Runaway Protection ======================= +//=========================================================================== + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * If you get "Thermal Runaway" or "Heating failed" errors the + * details can be tuned in Configuration_adv.h + */ + +#define THERMAL_PROTECTION_HOTENDS // Enable thermal protection for all extruders +#define THERMAL_PROTECTION_BED // Enable thermal protection for the heated bed + +//=========================================================================== +//============================= Mechanical Settings ========================= +//=========================================================================== + +// @section machine + +// Uncomment one of these options to enable CoreXY, CoreXZ, or CoreYZ kinematics +// either in the usual order or reversed +//#define COREXY +//#define COREXZ +//#define COREYZ +//#define COREYX +//#define COREZX +//#define COREZY + +//=========================================================================== +//============================== Endstop Settings =========================== +//=========================================================================== + +// @section homing + +// Specify here all the endstop connectors that are connected to any endstop or probe. +// Almost all printers will be using one per axis. Probes will use one or more of the +// extra connectors. Leave undefined any used for non-endstop and non-probe purposes. +#define USE_XMIN_PLUG +#define USE_YMIN_PLUG +#define USE_ZMIN_PLUG +//#define USE_XMAX_PLUG +//#define USE_YMAX_PLUG +//#define USE_ZMAX_PLUG + +// coarse Endstop Settings +#define ENDSTOPPULLUPS // Comment this out (using // at the start of the line) to disable the endstop pullup resistors + +#if DISABLED(ENDSTOPPULLUPS) + // fine endstop settings: Individual pullups. will be ignored if ENDSTOPPULLUPS is defined + //#define ENDSTOPPULLUP_XMAX + //#define ENDSTOPPULLUP_YMAX + //#define ENDSTOPPULLUP_ZMAX + #define ENDSTOPPULLUP_XMIN + #define ENDSTOPPULLUP_YMIN + #define ENDSTOPPULLUP_ZMIN + //#define ENDSTOPPULLUP_ZMIN_PROBE +#endif + +// Mechanical endstop with COM to ground and NC to Signal uses "false" here (most common setup). +#define X_MIN_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Y_MIN_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MIN_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define X_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Y_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MIN_PROBE_ENDSTOP_INVERTING false // set to true to invert the logic of the probe. + +// Enable this feature if all enabled endstop pins are interrupt-capable. +// This will remove the need to poll the interrupt pins, saving many CPU cycles. +//#define ENDSTOP_INTERRUPTS_FEATURE + +//============================================================================= +//============================== Movement Settings ============================ +//============================================================================= +// @section motion + +/** + * Default Settings + * + * These settings can be reset by M502 + * + * Note that if EEPROM is enabled, saved values will override these. + */ + +/** + * With this option each E stepper can have its own factors for the + * following movement settings. If fewer factors are given than the + * total number of extruders, the last value applies to the rest. + */ +//#define DISTINCT_E_FACTORS + +/** + * Default Axis Steps Per Unit (steps/mm) + * Override with M92 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_AXIS_STEPS_PER_UNIT { 64.25, 64.25, 2560, 600 } +/** + * Default Max Feed Rate (mm/s) + * Override with M203 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_FEEDRATE { 500, 500, 5, 25 } + +/** + * Default Max Acceleration (change/s) change = mm/s + * (Maximum start speed for accelerated moves) + * Override with M201 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_ACCELERATION { 9000, 9000, 100, 10000 } + +/** + * Default Acceleration (change/s) change = mm/s + * Override with M204 + * + * M204 P Acceleration + * M204 R Retract Acceleration + * M204 T Travel Acceleration + */ +#define DEFAULT_ACCELERATION 1000 // X, Y, Z and E acceleration for printing moves +#define DEFAULT_RETRACT_ACCELERATION 1000 // E acceleration for retracts +#define DEFAULT_TRAVEL_ACCELERATION 1000 // X, Y, Z acceleration for travel (non printing) moves + +/** + * Default Jerk (mm/s) + * Override with M205 X Y Z E + * + * "Jerk" specifies the minimum speed change that requires acceleration. + * When changing speed and direction, if the difference is less than the + * value set here, it may happen instantaneously. + */ +#define DEFAULT_XJERK 20.0 +#define DEFAULT_YJERK 20.0 +#define DEFAULT_ZJERK 0.4 +#define DEFAULT_EJERK 5.0 + +//=========================================================================== +//============================= Z Probe Options ============================= +//=========================================================================== +// @section probes + +// +// See http://marlinfw.org/configuration/probes.html +// + +/** + * Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + * + * Enable this option for a probe connected to the Z Min endstop pin. + */ +#define Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + +/** + * Z_MIN_PROBE_ENDSTOP + * + * Enable this option for a probe connected to any pin except Z-Min. + * (By default Marlin assumes the Z-Max endstop pin.) + * To use a custom Z Probe pin, set Z_MIN_PROBE_PIN below. + * + * - The simplest option is to use a free endstop connector. + * - Use 5V for powered (usually inductive) sensors. + * + * - RAMPS 1.3/1.4 boards may use the 5V, GND, and Aux4->D32 pin: + * - For simple switches connect... + * - normally-closed switches to GND and D32. + * - normally-open switches to 5V and D32. + * + * WARNING: Setting the wrong pin may have unexpected and potentially + * disastrous consequences. Use with caution and do your homework. + * + */ +//#define Z_MIN_PROBE_ENDSTOP + +/** + * Probe Type + * + * Allen Key Probes, Servo Probes, Z-Sled Probes, FIX_MOUNTED_PROBE, etc. + * Activate one of these to use Auto Bed Leveling below. + */ + +/** + * The "Manual Probe" provides a means to do "Auto" Bed Leveling without a probe. + * Use G29 repeatedly, adjusting the Z height at each point with movement commands + * or (with LCD_BED_LEVELING) the LCD controller. + */ +//#define PROBE_MANUALLY + +/** + * A Fix-Mounted Probe either doesn't deploy or needs manual deployment. + * (e.g., an inductive probe or a nozzle-based probe-switch.) + */ +//#define FIX_MOUNTED_PROBE + +/** + * Z Servo Probe, such as an endstop switch on a rotating arm. + */ +//#define Z_ENDSTOP_SERVO_NR 0 // Defaults to SERVO 0 connector. +//#define Z_SERVO_ANGLES {70,0} // Z Servo Deploy and Stow angles + +/** + * The BLTouch probe uses a Hall effect sensor and emulates a servo. + */ +//#define BLTOUCH +#if ENABLED(BLTOUCH) + //#define BLTOUCH_DELAY 375 // (ms) Enable and increase if needed +#endif + +/** + * Enable one or more of the following if probing seems unreliable. + * Heaters and/or fans can be disabled during probing to minimize electrical + * noise. A delay can also be added to allow noise and vibration to settle. + * These options are most useful for the BLTouch probe, but may also improve + * readings with inductive probes and piezo sensors. + */ +//#define PROBING_HEATERS_OFF // Turn heaters off when probing +//#define PROBING_FANS_OFF // Turn fans off when probing +//#define DELAY_BEFORE_PROBING 200 // (ms) To prevent vibrations from triggering piezo sensors + +// A probe that is deployed and stowed with a solenoid pin (SOL1_PIN) +//#define SOLENOID_PROBE + +// A sled-mounted probe like those designed by Charles Bell. +//#define Z_PROBE_SLED +//#define SLED_DOCKING_OFFSET 5 // The extra distance the X axis must travel to pickup the sled. 0 should be fine but you can push it further if you'd like. + +// +// For Z_PROBE_ALLEN_KEY see the Delta example configurations. +// + +/** + * Z Probe to nozzle (X,Y) offset, relative to (0, 0). + * X and Y offsets must be integers. + * + * In the following example the X and Y offsets are both positive: + * #define X_PROBE_OFFSET_FROM_EXTRUDER 10 + * #define Y_PROBE_OFFSET_FROM_EXTRUDER 10 + * + * +-- BACK ---+ + * | | + * L | (+) P | R <-- probe (20,20) + * E | | I + * F | (-) N (+) | G <-- nozzle (10,10) + * T | | H + * | (-) | T + * | | + * O-- FRONT --+ + * (0,0) + */ +#define X_PROBE_OFFSET_FROM_EXTRUDER 10 // X offset: -left +right [of the nozzle] +#define Y_PROBE_OFFSET_FROM_EXTRUDER 10 // Y offset: -front +behind [the nozzle] +#define Z_PROBE_OFFSET_FROM_EXTRUDER 0 // Z offset: -below +above [the nozzle] + +// X and Y axis travel speed (mm/m) between probes +#define XY_PROBE_SPEED 8000 + +// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +#define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z + +// Speed for the "accurate" probe of each point +#define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) + +// Use double touch for probing +//#define PROBE_DOUBLE_TOUCH + +/** + * Z probes require clearance when deploying, stowing, and moving between + * probe points to avoid hitting the bed and other hardware. + * Servo-mounted probes require extra space for the arm to rotate. + * Inductive probes need space to keep from triggering early. + * + * Use these settings to specify the distance (mm) to raise the probe (or + * lower the bed). The values set here apply over and above any (negative) + * probe Z Offset set with Z_PROBE_OFFSET_FROM_EXTRUDER, M851, or the LCD. + * Only integer values >= 1 are valid here. + * + * Example: `M851 Z-5` with a CLEARANCE of 4 => 9mm from bed to nozzle. + * But: `M851 Z+1` with a CLEARANCE of 2 => 2mm from bed to nozzle. + */ +#define Z_CLEARANCE_DEPLOY_PROBE 10 // Z Clearance for Deploy/Stow +#define Z_CLEARANCE_BETWEEN_PROBES 5 // Z Clearance between probe points + +// For M851 give a range for adjusting the Z probe offset +#define Z_PROBE_OFFSET_RANGE_MIN -20 +#define Z_PROBE_OFFSET_RANGE_MAX 20 + +// Enable the M48 repeatability test to test probe accuracy +//#define Z_MIN_PROBE_REPEATABILITY_TEST + +// For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1 +// :{ 0:'Low', 1:'High' } +#define X_ENABLE_ON 0 +#define Y_ENABLE_ON 0 +#define Z_ENABLE_ON 0 +#define E_ENABLE_ON 0 // For all extruders + +// Disables axis stepper immediately when it's not being used. +// 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 +//#define DISABLE_REDUCED_ACCURACY_WARNING + +// @section extruder + +#define DISABLE_E false // For all extruders +#define DISABLE_INACTIVE_EXTRUDER true // Keep only the active extruder enabled. + +// @section machine + +// Invert the stepper direction. Change (or reverse the motor connector) if an axis goes the wrong way. +#define INVERT_X_DIR false +#define INVERT_Y_DIR false // K8200: false +#define INVERT_Z_DIR false + +// Enable this option for Toshiba stepper drivers +//#define CONFIG_STEPPERS_TOSHIBA + +// @section extruder + +// For direct drive extruder v9 set to true, for geared extruder set to false. +#define INVERT_E0_DIR true // K8200: true for geared default extruder! +#define INVERT_E1_DIR true +#define INVERT_E2_DIR true +#define INVERT_E3_DIR true +#define INVERT_E4_DIR true + +// @section homing + +//#define NO_MOTION_BEFORE_HOMING // Inhibit movement until all axes have been homed + +// K8200: it is usual to have clamps for the glass plate on the heatbed +#define Z_HOMING_HEIGHT 4 // (in mm) Minimal z height before homing (G28) for Z clearance above the bed, clamps, ... + // Be sure you have this distance over your Z_MAX_POS in case. + +// Direction of endstops when homing; 1=MAX, -1=MIN +// :[-1,1] +#define X_HOME_DIR -1 +#define Y_HOME_DIR -1 +#define Z_HOME_DIR -1 + +// @section machine + +// The size of the print bed +#define X_BED_SIZE 200 +#define Y_BED_SIZE 200 + +// Travel limits (mm) after homing, corresponding to endstop positions. +#define X_MIN_POS 0 +#define Y_MIN_POS 0 +#define Z_MIN_POS 0 +#define X_MAX_POS X_BED_SIZE +#define Y_MAX_POS Y_BED_SIZE +#define Z_MAX_POS 200 + +// If enabled, axes won't move below MIN_POS in response to movement commands. +#define MIN_SOFTWARE_ENDSTOPS +// If enabled, axes won't move above MAX_POS in response to movement commands. +#define MAX_SOFTWARE_ENDSTOPS + +/** + * Filament Runout Sensor + * A mechanical or opto endstop is used to check for the presence of filament. + * + * RAMPS-based boards use SERVO3_PIN. + * For other boards you may need to define FIL_RUNOUT_PIN. + * By default the firmware assumes HIGH = has filament, LOW = ran out + */ +//#define FILAMENT_RUNOUT_SENSOR +#if ENABLED(FILAMENT_RUNOUT_SENSOR) + #define FIL_RUNOUT_INVERTING false // set to true to invert the logic of the sensor. + #define ENDSTOPPULLUP_FIL_RUNOUT // Uncomment to use internal pullup for filament runout pins if the sensor is defined. + #define FILAMENT_RUNOUT_SCRIPT "M600" +#endif + +//=========================================================================== +//=============================== Bed Leveling ============================== +//=========================================================================== +// @section bedlevel + +/** + * Choose one of the options below to enable G29 Bed Leveling. The parameters + * and behavior of G29 will change depending on your selection. + * + * If using a Probe for Z Homing, enable Z_SAFE_HOMING also! + * + * - AUTO_BED_LEVELING_3POINT + * Probe 3 arbitrary points on the bed (that aren't collinear) + * You specify the XY coordinates of all 3 points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_LINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_BILINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a mesh, best for large or uneven beds. + * + * - AUTO_BED_LEVELING_UBL (Unified Bed Leveling) + * A comprehensive bed leveling system combining the features and benefits + * of other systems. UBL also includes integrated Mesh Generation, Mesh + * Validation and Mesh Editing systems. Currently, UBL is only checked out + * for Cartesian Printers. That said, it was primarily designed to correct + * poor quality Delta Printers. If you feel adventurous and have a Delta, + * please post an issue if something doesn't work correctly. Initially, + * you will need to set a reduced bed size so you have a rectangular area + * to test on. + * + * - MESH_BED_LEVELING + * Probe a grid manually + * The result is a mesh, suitable for large or uneven beds. (See BILINEAR.) + * For machines without a probe, Mesh Bed Leveling provides a method to perform + * leveling in steps so you can manually adjust the Z height at each grid-point. + * With an LCD controller the process is guided step-by-step. + */ +//#define AUTO_BED_LEVELING_3POINT +//#define AUTO_BED_LEVELING_LINEAR +//#define AUTO_BED_LEVELING_BILINEAR +//#define AUTO_BED_LEVELING_UBL +//#define MESH_BED_LEVELING + +/** + * Enable detailed logging of G28, G29, M48, etc. + * Turn on with the command 'M111 S32'. + * NOTE: Requires a lot of PROGMEM! + */ +//#define DEBUG_LEVELING_FEATURE + +#if ENABLED(MESH_BED_LEVELING) || ENABLED(AUTO_BED_LEVELING_BILINEAR) || ENABLED(AUTO_BED_LEVELING_UBL) + // Gradually reduce leveling correction until a set height is reached, + // at which point movement will be level to the machine's XY plane. + // The height can be set with M420 Z + #define ENABLE_LEVELING_FADE_HEIGHT +#endif + +#if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Set the number of grid points per dimension. + #define GRID_MAX_POINTS_X 3 + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + // Set the boundaries for probing (where the probe can reach). + #define LEFT_PROBE_BED_POSITION 15 + #define RIGHT_PROBE_BED_POSITION 170 + #define FRONT_PROBE_BED_POSITION 20 + #define BACK_PROBE_BED_POSITION 170 + + // The Z probe minimum outer margin (to validate G29 parameters). + #define MIN_PROBE_EDGE 10 + + // Probe along the Y axis, advancing X after each column + //#define PROBE_Y_FIRST + + #if ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Beyond the probed grid, continue the implied tilt? + // Default is to maintain the height of the nearest edge. + //#define EXTRAPOLATE_BEYOND_GRID + + // + // Experimental Subdivision of the grid by Catmull-Rom method. + // Synthesizes intermediate points to produce a more detailed mesh. + // + //#define ABL_BILINEAR_SUBDIVISION + #if ENABLED(ABL_BILINEAR_SUBDIVISION) + // Number of subdivisions between probe points + #define BILINEAR_SUBDIVISIONS 3 + #endif + + #endif + +#elif ENABLED(AUTO_BED_LEVELING_3POINT) + + // 3 arbitrary points to probe. + // A simple cross-product is used to estimate the plane of the bed. + #define ABL_PROBE_PT_1_X 15 + #define ABL_PROBE_PT_1_Y 180 + #define ABL_PROBE_PT_2_X 15 + #define ABL_PROBE_PT_2_Y 20 + #define ABL_PROBE_PT_3_X 170 + #define ABL_PROBE_PT_3_Y 20 + +#elif ENABLED(AUTO_BED_LEVELING_UBL) + + //=========================================================================== + //========================= Unified Bed Leveling ============================ + //=========================================================================== + + #define UBL_MESH_INSET 1 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 10 // Don't use more than 15 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + #define UBL_PROBE_PT_1_X 39 // Probing points for 3-Point leveling of the mesh + #define UBL_PROBE_PT_1_Y 180 + #define UBL_PROBE_PT_2_X 39 + #define UBL_PROBE_PT_2_Y 20 + #define UBL_PROBE_PT_3_X 180 + #define UBL_PROBE_PT_3_Y 20 + + #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation + #define UBL_MESH_EDIT_MOVES_Z // Sophisticated users prefer no movement of nozzle + +#elif ENABLED(MESH_BED_LEVELING) + + //=========================================================================== + //=================================== Mesh ================================== + //=========================================================================== + + #define MESH_INSET 10 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 3 // Don't use more than 7 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + //#define MESH_G28_REST_ORIGIN // After homing all axes ('G28' or 'G28 XYZ') rest Z at Z_MIN_POS + +#endif // BED_LEVELING + +/** + * Use the LCD controller for bed leveling + * Requires MESH_BED_LEVELING or PROBE_MANUALLY + */ +//#define LCD_BED_LEVELING + +#if ENABLED(LCD_BED_LEVELING) + #define MBL_Z_STEP 0.025 // Step size while manually probing Z axis. + #define LCD_PROBE_Z_RANGE 4 // Z Range centered on Z_MIN_POS for LCD Z adjustment +#endif + +// Add a menu item to move between bed corners for manual bed adjustment +//#define LEVEL_BED_CORNERS + +/** + * Commands to execute at the end of G29 probing. + * Useful to retract or move the Z probe out of the way. + */ +//#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) +//#define BED_CENTER_AT_0_0 + +// Manually set the home position. Leave these undefined for automatic settings. +// For DELTA this is the top-center of the Cartesian print volume. +//#define MANUAL_X_HOME_POS 0 +//#define MANUAL_Y_HOME_POS 0 +//#define MANUAL_Z_HOME_POS 0 + +// Use "Z Safe Homing" to avoid homing with a Z probe outside the bed area. +// +// With this feature enabled: +// +// - 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). +// - 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 axis (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). +#endif + +// Homing speeds (mm/m) +#define HOMING_FEEDRATE_XY (50*60) +#define HOMING_FEEDRATE_Z (4*60) + +//============================================================================= +//============================= Additional Features =========================== +//============================================================================= + +// @section extras + +// +// EEPROM +// +// The microcontroller can store settings in the EEPROM, e.g. max velocity... +// M500 - stores parameters in EEPROM +// M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily). +// M502 - reverts to the default "factory settings". You still need to store them in EEPROM afterwards if you want to. +// +#define EEPROM_SETTINGS // Enable for M500 and M501 commands +//#define DISABLE_M503 // Saves ~2700 bytes of PROGMEM. Disable for release! +#define EEPROM_CHITCHAT // Give feedback on EEPROM commands. Disable to save PROGMEM. + +// +// Host Keepalive +// +// When enabled Marlin will send a busy status message to the host +// every couple of seconds when it can't accept commands. +// +#define HOST_KEEPALIVE_FEATURE // Disable this if your host doesn't like keepalive messages +#define DEFAULT_KEEPALIVE_INTERVAL 2 // Number of seconds between "busy" messages. Set with M113. +#define BUSY_WHILE_HEATING // Some hosts require "busy" messages even during heating + +// +// M100 Free Memory Watcher +// +//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose + +// +// G20/G21 Inch mode support +// +//#define INCH_MODE_SUPPORT + +// +// M149 Set temperature units support +// +//#define TEMPERATURE_UNITS_SUPPORT + +// @section temperature + +// Preheat Constants +#define PREHEAT_1_TEMP_HOTEND 180 +#define PREHEAT_1_TEMP_BED 50 // K8200: PLA / set back to 70 if you have an upgraded heatbed power supply +#define PREHEAT_1_FAN_SPEED 0 // Value from 0 to 255 + +#define PREHEAT_2_TEMP_HOTEND 240 +#define PREHEAT_2_TEMP_BED 60 // K8200: ABS / set back to 110 if you have an upgraded heatbed power supply +#define PREHEAT_2_FAN_SPEED 0 // Value from 0 to 255 + +/** + * Nozzle Park -- EXPERIMENTAL + * + * Park the nozzle at the given XYZ position on idle or G27. + * + * The "P" parameter controls the action applied to the Z axis: + * + * P0 (Default) If Z is below park Z raise the nozzle. + * P1 Raise the nozzle always to Z-park height. + * P2 Raise the nozzle by Z-park amount, limited to Z_MAX_POS. + */ +//#define NOZZLE_PARK_FEATURE + +#if ENABLED(NOZZLE_PARK_FEATURE) + // Specify a park position as { X, Y, Z } + #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 } +#endif + +/** + * Clean Nozzle Feature -- EXPERIMENTAL + * + * Adds the G12 command to perform a nozzle cleaning process. + * + * Parameters: + * P Pattern + * S Strokes / Repetitions + * T Triangles (P1 only) + * + * Patterns: + * P0 Straight line (default). This process requires a sponge type material + * at a fixed bed location. "S" specifies strokes (i.e. back-forth motions) + * between the start / end points. + * + * P1 Zig-zag pattern between (X0, Y0) and (X1, Y1), "T" specifies the + * number of zig-zag triangles to do. "S" defines the number of strokes. + * Zig-zags are done in whichever is the narrower dimension. + * For example, "G12 P1 S1 T3" will execute: + * + * -- + * | (X0, Y1) | /\ /\ /\ | (X1, Y1) + * | | / \ / \ / \ | + * A | | / \ / \ / \ | + * | | / \ / \ / \ | + * | (X0, Y0) | / \/ \/ \ | (X1, Y0) + * -- +--------------------------------+ + * |________|_________|_________| + * T1 T2 T3 + * + * P2 Circular pattern with middle at NOZZLE_CLEAN_CIRCLE_MIDDLE. + * "R" specifies the radius. "S" specifies the stroke count. + * Before starting, the nozzle moves to NOZZLE_CLEAN_START_POINT. + * + * Caveats: The ending Z should be the same as starting Z. + * Attention: EXPERIMENTAL. G-code arguments may change. + * + */ +//#define NOZZLE_CLEAN_FEATURE + +#if ENABLED(NOZZLE_CLEAN_FEATURE) + // Default number of pattern repetitions + #define NOZZLE_CLEAN_STROKES 12 + + // Default number of triangles + #define NOZZLE_CLEAN_TRIANGLES 3 + + // Specify positions as { X, Y, Z } + #define NOZZLE_CLEAN_START_POINT { 30, 30, (Z_MIN_POS + 1)} + #define NOZZLE_CLEAN_END_POINT {100, 60, (Z_MIN_POS + 1)} + + // Circular pattern radius + #define NOZZLE_CLEAN_CIRCLE_RADIUS 6.5 + // Circular pattern circle fragments number + #define NOZZLE_CLEAN_CIRCLE_FN 10 + // Middle point of circle + #define NOZZLE_CLEAN_CIRCLE_MIDDLE NOZZLE_CLEAN_START_POINT + + // Moves the nozzle to the initial position + #define NOZZLE_CLEAN_GOBACK +#endif + +/** + * Print Job Timer + * + * Automatically start and stop the print job timer on M104/M109/M190. + * + * M104 (hotend, no wait) - high temp = none, low temp = stop timer + * M109 (hotend, wait) - high temp = start timer, low temp = stop timer + * M190 (bed, wait) - high temp = start timer, low temp = none + * + * The timer can also be controlled with the following commands: + * + * M75 - Start the print job timer + * M76 - Pause the print job timer + * M77 - Stop the print job timer + */ +#define PRINTJOB_TIMER_AUTOSTART + +/** + * Print Counter + * + * Track statistical data such as: + * + * - Total print jobs + * - Total successful print jobs + * - Total failed print jobs + * - Total time printing + * + * View the current statistics with M78. + */ +#define PRINTCOUNTER + +//============================================================================= +//============================= LCD and SD support ============================ +//============================================================================= + +// @section lcd + +// K8200: for Display VM8201 with SD slot +#if ENABLED(K8200_VM8201) + +/** + * LCD LANGUAGE + * + * Select the language to display on the LCD. These languages are available: + * + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, + * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * tr, uk, zh_CN, zh_TW, test + * + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + */ +#define LCD_LANGUAGE en + +/** + * LCD Character Set + * + * Note: This option is NOT applicable to Graphical Displays. + * + * All character-based LCDs provide ASCII plus one of these + * language extensions: + * + * - JAPANESE ... the most common + * - WESTERN ... with more accented characters + * - CYRILLIC ... for the Russian language + * + * To determine the language extension installed on your controller: + * + * - Compile and upload with LCD_LANGUAGE set to 'test' + * - 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 + * + * :['JAPANESE', 'WESTERN', 'CYRILLIC'] + */ +#define DISPLAY_CHARSET_HD44780 JAPANESE // K8200: for Display VM8201 // this is the most common hardware + +/** + * LCD TYPE + * + * Enable ULTRA_LCD for a 16x2, 16x4, 20x2, or 20x4 character-based LCD. + * Enable DOGLCD for a 128x64 (ST7565R) Full Graphical Display. + * (These options will be enabled automatically for most displays.) + * + * IMPORTANT: The U8glib library is required for Full Graphic Display! + * https://github.com/olikraus/U8glib_Arduino + */ +//#define ULTRA_LCD // Character based +//#define DOGLCD // Full graphics display + +/** + * SD CARD + * + * 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 + +/** + * SD CARD: SPI SPEED + * + * Enable one of the following items for a slower SPI transfer speed. + * This may be required to resolve "volume init" errors. + */ +//#define SPI_SPEED SPI_HALF_SPEED +//#define SPI_SPEED SPI_QUARTER_SPEED +//#define SPI_SPEED SPI_EIGHTH_SPEED + +/** + * SD CARD: ENABLE CRC + * + * Use CRC checks and retries on the SD communication. + */ +#define SD_CHECK_AND_RETRY + +// +// ENCODER SETTINGS +// +// This option overrides the default number of encoder pulses needed to +// produce one step. Should be increased for high-resolution encoders. +// +#define ENCODER_PULSES_PER_STEP 4 // K8200_VM8201: four steps per encoder step + +// +// Use this option to override the number of step signals required to +// move between next/prev menu items. +// +#define ENCODER_STEPS_PER_MENU_ITEM 1 // K8200_VM8201: One step per menu item + +/** + * Encoder Direction Options + * + * Test your encoder's behavior first with both options disabled. + * + * Reversed Value Edit and Menu Nav? Enable REVERSE_ENCODER_DIRECTION. + * Reversed Menu Navigation only? Enable REVERSE_MENU_DIRECTION. + * Reversed Value Editing only? Enable BOTH options. + */ + +// +// This option reverses the encoder direction everywhere. +// +// Set this option if CLOCKWISE causes values to DECREASE +// +//#define REVERSE_ENCODER_DIRECTION + +// +// This option reverses the encoder direction for navigating LCD menus. +// +// If CLOCKWISE normally moves DOWN this makes it go UP. +// If CLOCKWISE normally moves UP this makes it go DOWN. +// +#define REVERSE_MENU_DIRECTION // K8200: for Display VM8201 encoder on right side + +// +// Individual Axis Homing +// +// Add individual axis homing items (Home X, Home Y, and Home Z) to the LCD menu. +// +#define INDIVIDUAL_AXIS_HOMING_MENU + +// +// SPEAKER/BUZZER +// +// If you have a speaker that can produce tones, enable it here. +// By default Marlin assumes you have a buzzer with a fixed frequency. +// +//#define SPEAKER + +// +// The duration and frequency for the UI feedback sound. +// Set these to 0 to disable audio feedback in the LCD menus. +// +// Note: Test audio output with the G-Code: +// M300 S P +// +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 +//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 + +// +// CONTROLLER TYPE: Standard +// +// Marlin supports a wide variety of controllers. +// Enable one of the following options to specify your controller. +// + +// +// ULTIMAKER Controller. +// +#define ULTIMAKERCONTROLLER // K8200: for Display VM8201 + +// +// ULTIPANEL as seen on Thingiverse. +// +//#define ULTIPANEL + +// +// PanelOne from T3P3 (via RAMPS 1.4 AUX2/AUX3) +// http://reprap.org/wiki/PanelOne +// +//#define PANEL_ONE + +// +// MaKr3d Makr-Panel with graphic controller and SD support. +// http://reprap.org/wiki/MaKr3d_MaKrPanel +// +//#define MAKRPANEL + +// +// ReprapWorld Graphical LCD +// https://reprapworld.com/?products_details&products_id/1218 +// +//#define REPRAPWORLD_GRAPHICAL_LCD + +// +// Activate one of these if you have a Panucatt Devices +// Viki 2.0 or mini Viki with Graphic LCD +// http://panucatt.com +// +//#define VIKI2 +//#define miniVIKI + +// +// Adafruit ST7565 Full Graphic Controller. +// https://github.com/eboston/Adafruit-ST7565-Full-Graphic-Controller/ +// +//#define ELB_FULL_GRAPHIC_CONTROLLER + +// +// RepRapDiscount Smart Controller. +// http://reprap.org/wiki/RepRapDiscount_Smart_Controller +// +// Note: Usually sold with a white PCB. +// +//#define REPRAP_DISCOUNT_SMART_CONTROLLER + +// +// GADGETS3D G3D LCD/SD Controller +// http://reprap.org/wiki/RAMPS_1.3/1.4_GADGETS3D_Shield_with_Panel +// +// Note: Usually sold with a blue PCB. +// +//#define G3D_PANEL + +// +// RepRapDiscount FULL GRAPHIC Smart Controller +// http://reprap.org/wiki/RepRapDiscount_Full_Graphic_Smart_Controller +// +//#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER + +// +// MakerLab Mini Panel with graphic +// controller and SD support - http://reprap.org/wiki/Mini_panel +// +//#define MINIPANEL + +// +// RepRapWorld REPRAPWORLD_KEYPAD v1.1 +// http://reprapworld.com/?products_details&products_id=202&cPath=1591_1626 +// +// REPRAPWORLD_KEYPAD_MOVE_STEP sets how much should the robot move when a key +// is pressed, a value of 10.0 means 10mm per click. +// +//#define REPRAPWORLD_KEYPAD +//#define REPRAPWORLD_KEYPAD_MOVE_STEP 1.0 + +// +// RigidBot Panel V1.0 +// http://www.inventapart.com/ +// +//#define RIGIDBOT_PANEL + +// +// BQ LCD Smart Controller shipped by +// default with the BQ Hephestos 2 and Witbox 2. +// +//#define BQ_LCD_SMART_CONTROLLER + +// +// Cartesio UI +// http://mauk.cc/webshop/cartesio-shop/electronics/user-interface +// +//#define CARTESIO_UI + +// +// ANET_10 Controller supported displays. +// +//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. + // This LCD is known to be susceptible to electrical interference + // which scrambles the display. Pressing any button clears it up. +//#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 + // A clone of the RepRapDiscount full graphics display but with + // different pins/wiring (see pins_ANET_10.h). + +// +// LCD for Melzi Card with Graphical LCD +// +//#define LCD_FOR_MELZI + +// +// CONTROLLER TYPE: I2C +// +// Note: These controllers require the installation of Arduino's LiquidCrystal_I2C +// library. For more info: https://github.com/kiyoshigawa/LiquidCrystal_I2C +// + +// +// Elefu RA Board Control Panel +// http://www.elefu.com/index.php?route=product/product&product_id=53 +// +//#define RA_CONTROL_PANEL + +// +// Sainsmart YW Robot (LCM1602) LCD Display +// +// Note: This controller requires F.Malpartida's LiquidCrystal_I2C library +// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home +// +//#define LCD_I2C_SAINSMART_YWROBOT + +// +// Generic LCM1602 LCD adapter +// +//#define LCM1602 + +// +// PANELOLU2 LCD with status LEDs, +// separate encoder and click inputs. +// +// Note: This controller requires Arduino's LiquidTWI2 library v1.2.3 or later. +// For more info: https://github.com/lincomatic/LiquidTWI2 +// +// Note: The PANELOLU2 encoder click input can either be directly connected to +// a pin (if BTN_ENC defined to != -1) or read through I2C (when BTN_ENC == -1). +// +//#define LCD_I2C_PANELOLU2 + +// +// Panucatt VIKI LCD with status LEDs, +// integrated click & L/R/U/D buttons, separate encoder inputs. +// +//#define LCD_I2C_VIKI + +// +// SSD1306 OLED full graphics generic display +// +//#define U8GLIB_SSD1306 + +// +// SAV OLEd LCD module support using either SSD1306 or SH1106 based LCD modules +// +//#define SAV_3DGLCD +#if ENABLED(SAV_3DGLCD) + //#define U8GLIB_SSD1306 + #define U8GLIB_SH1106 +#endif + +// +// CONTROLLER TYPE: Shift register panels +// +// 2 wire Non-latching LCD SR from https://goo.gl/aJJ4sH +// LCD configuration: http://reprap.org/wiki/SAV_3D_LCD +// +//#define SAV_3DLCD + +// +// TinyBoy2 128x64 OLED / Encoder Panel +// +//#define OLED_PANEL_TINYBOY2 + +// +// Makeboard 3D Printer Parts 3D Printer Mini Display 1602 Mini Controller +// https://www.aliexpress.com/item/Micromake-Makeboard-3D-Printer-Parts-3D-Printer-Mini-Display-1602-Mini-Controller-Compatible-with-Ramps-1/32765887917.html +// +//#define MAKEBOARD_MINI_2_LINE_DISPLAY_1602 + +// +// MKS MINI12864 with graphic controller and SD support +// http://reprap.org/wiki/MKS_MINI_12864 +// +//#define MKS_MINI_12864 + +// +// Factory display for Creality CR-10 +// https://www.aliexpress.com/item/Universal-LCD-12864-3D-Printer-Display-Screen-With-Encoder-For-CR-10-CR-7-Model/32833148327.html +// +// This is RAMPS-compatible using a single 10-pin connector. +// (For CR-10 owners who want to replace the Melzi Creality board but retain the display) +// +//#define CR10_STOCKDISPLAY + +// +// MKS OLED 1.3" 128 × 64 FULL GRAPHICS CONTROLLER +// http://reprap.org/wiki/MKS_12864OLED +// +// Tiny, but very sharp OLED display +// +//#define MKS_12864OLED + +#endif // K8200_VM8201 + +//============================================================================= +//=============================== Extra Features ============================== +//============================================================================= + +// @section extras + +// Increase the FAN PWM frequency. Removes the PWM noise but increases heating in the FET/Arduino +//#define FAST_PWM_FAN + +// Use software PWM to drive the fan, as for the heaters. This uses a very low frequency +// which is not as annoying as with the hardware PWM. On the other hand, if this frequency +// is too low, you should also increment SOFT_PWM_SCALE. +//#define FAN_SOFT_PWM + +// Incrementing this by 1 will double the software PWM frequency, +// affecting heaters, and the fan if FAN_SOFT_PWM is enabled. +// However, control resolution will be halved for each increment; +// at zero value, there are 128 effective control positions. +#define SOFT_PWM_SCALE 0 + +// If SOFT_PWM_SCALE is set to a value higher than 0, dithering can +// be used to mitigate the associated resolution loss. If enabled, +// some of the PWM cycles are stretched so on average the desired +// duty cycle is attained. +//#define SOFT_PWM_DITHER + +// Temperature status LEDs that display the hotend and bed temperature. +// If all hotends, bed temperature, and target temperature are under 54C +// then the BLUE led is on. Otherwise the RED led is on. (1C hysteresis) +//#define TEMP_STAT_LEDS + +// M240 Triggers a camera by emulating a Canon RC-1 Remote +// Data from: http://www.doc-diy.net/photo/rc-1_hacked/ +//#define PHOTOGRAPH_PIN 23 + +// 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 + +// Support for BlinkM/CyzRgb +//#define BLINKM + +// Support for PCA9632 PWM LED driver +//#define PCA9632 + +/** + * RGB LED / LED Strip Control + * + * Enable support for an RGB LED connected to 5V digital pins, or + * an RGB Strip connected to MOSFETs controlled by digital pins. + * + * 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 overall brightness parameters is also available + * + * *** CAUTION *** + * LED Strips require a MOFSET 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! + * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino + * cannot handle such current, separate 5V power supply must be used + * *** CAUTION *** + * + * LED type. This options are mutualy exclusive. Uncomment only one. + * + */ +//#define RGB_LED +//#define RGBW_LED + +#if ENABLED(RGB_LED) || ENABLED(RGBW_LED) + #define RGB_LED_R_PIN 34 + #define RGB_LED_G_PIN 43 + #define RGB_LED_B_PIN 35 + #define RGB_LED_W_PIN -1 +#endif + +// 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 (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) + #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip + #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time + #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + //#define NEOPIXEL_STARTUP_TEST // Cycle through colors at startup +#endif + +/** + * Printer Event LEDs + * + * During printing, the LEDs will reflect the printer status: + * + * - Gradually change from blue to violet as the heated bed gets to target temp + * - Gradually change from violet to red as the hotend gets to temperature + * - Change to white to illuminate work surface + * - Change to green once print has finished + * - Turn off after the print has finished and the user has pushed a button + */ +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) + #define PRINTER_EVENT_LEDS +#endif + +/*********************************************************************\ +* R/C SERVO support +* Sponsored by TrinityLabs, Reworked by codexmas +**********************************************************************/ + +// Number of servos +// +// If you select a configuration below, this will receive a default value and does not need to be set manually +// set it manually if you have more servos than extruders and wish to manually control some +// leaving it undefined or defining as 0 will disable the servo subsystem +// If unsure, leave commented / disabled +// +//#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command + +// Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. +// 300ms is a good value but you can try less delay. +// If the servo can't reach the requested position, increase it. +#define SERVO_DELAY { 300 } + +// Servo deactivation +// +// With this option servos are powered only during movement, then turned off to prevent jitter. +//#define DEACTIVATE_SERVOS_AFTER_MOVE + +/** + * Filament Width Sensor + * + * Measures the filament width in real-time and adjusts + * flow rate to compensate for any irregularities. + * + * Also allows the measured filament diameter to set the + * extrusion rate, so the slicer only has to specify the + * volume. + * + * Only a single extruder is supported at this time. + * + * 34 RAMPS_14 : Analog input 5 on the AUX2 connector + * 81 PRINTRBOARD : Analog input 2 on the Exp1 connector (version B,C,D,E) + * 301 RAMBO : Analog input 3 + * + * Note: May require analog pins to be defined for other boards. + */ +//#define FILAMENT_WIDTH_SENSOR + +#define DEFAULT_NOMINAL_FILAMENT_DIA 3.00 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. + +#if ENABLED(FILAMENT_WIDTH_SENSOR) + #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) + #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber + + #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading + #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading + #define MAX_MEASUREMENT_DELAY 20 // (bytes) Buffer size for stored measurements (1 byte per cm). Must be larger than MEASUREMENT_DELAY_CM. + + #define DEFAULT_MEASURED_FILAMENT_DIA DEFAULT_NOMINAL_FILAMENT_DIA // Set measured to nominal initially + + // Display filament width on the LCD status line. Status messages will expire after 5 seconds. + //#define FILAMENT_LCD_DISPLAY +#endif + +#endif // CONFIGURATION_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/Velleman/K8200/Configuration_adv.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/Velleman/K8200/Configuration_adv.h new file mode 100644 index 00000000..2e5fa1e7 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/Velleman/K8200/Configuration_adv.h @@ -0,0 +1,1437 @@ +/** + * 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 . + * + */ + +/** + * Configuration_adv.h + * + * Advanced settings. + * Only change these if you know exactly what you're doing. + * Some of these settings can damage your printer if improperly set! + * + * Basic settings can be found in Configuration.h + * + */ + + /** + * Sample configuration file for Vellemann K8200 + * tested on K8200 with VM8201 (Display) + * and Arduino 1.6.12 (Mac) by @CONSULitAS, 2016-11-18 + * https://github.com/CONSULitAS/Marlin-K8200/archive/K8200_stable_2016-11-18.zip + * + */ + +#ifndef CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H_VERSION 010100 + +// @section temperature + +//=========================================================================== +//=============================Thermal Settings ============================ +//=========================================================================== + +#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 + #endif +#endif + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * The solution: Once the temperature reaches the target, start observing. + * If the temperature stays too far below the target (hysteresis) for too long (period), + * the firmware will halt the machine as a safety precaution. + * + * If you get false positives for "Thermal Runaway" increase THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD + */ +#if ENABLED(THERMAL_PROTECTION_HOTENDS) + // K8200 has weak heaters/power supply by default, so you have to relax! + #define THERMAL_PROTECTION_PERIOD 60 // Seconds + #define THERMAL_PROTECTION_HYSTERESIS 8 // Degrees Celsius + + /** + * Whenever an M104 or M109 increases the target temperature the firmware will wait for the + * WATCH_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get false positives for "Heating failed" increase WATCH_TEMP_PERIOD and/or decrease WATCH_TEMP_INCREASE + * WATCH_TEMP_INCREASE should not be below 2. + */ + // K8200 has weak heaters/power supply by default, so you have to relax! + #define WATCH_TEMP_PERIOD 30 // Seconds + #define WATCH_TEMP_INCREASE 2 // Degrees Celsius +#endif + +/** + * Thermal Protection parameters for the bed are just as above for hotends. + */ +#if ENABLED(THERMAL_PROTECTION_BED) + // K8200 has weak heaters/power supply by default, so you have to relax! + // the default bed is so weak, that you can hardly go over 75°C + #define THERMAL_PROTECTION_BED_PERIOD 60 // Seconds + #define THERMAL_PROTECTION_BED_HYSTERESIS 10 // Degrees Celsius + + /** + * Whenever an M140 or M190 increases the target temperature the firmware will wait for the + * WATCH_BED_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_BED_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get too many "Heating failed" errors, increase WATCH_BED_TEMP_PERIOD and/or decrease + * WATCH_BED_TEMP_INCREASE. (WATCH_BED_TEMP_INCREASE should not be below 2.) + */ + #define WATCH_BED_TEMP_PERIOD 60 // Seconds + #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius +#endif + +#if ENABLED(PIDTEMP) + // this adds an experimental additional term to the heating power, proportional to the extrusion speed. + // if Kc is chosen well, the additional required power due to increased melting should be compensated. + //#define PID_EXTRUSION_SCALING + #if ENABLED(PID_EXTRUSION_SCALING) + #define DEFAULT_Kc (100) //heating power=Kc*(e_speed) + #define LPQ_MAX_LEN 50 + #endif +#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 + */ +#define AUTOTEMP +#if ENABLED(AUTOTEMP) + #define AUTOTEMP_OLDWEIGHT 0.98 +#endif + +// Show Temperature ADC value +// Enable for M105 to include ADC values read from temperature sensors. +//#define SHOW_TEMP_ADC_VALUES + +/** + * High Temperature Thermistor Support + * + * Thermistors able to support high temperature tend to have a hard time getting + * good readings at room and lower temperatures. This means HEATER_X_RAW_LO_TEMP + * will probably be caught when the heating element first turns on during the + * preheating process, which will trigger a min_temp_error as a safety measure + * and force stop everything. + * To circumvent this limitation, we allow for a preheat time (during which, + * min_temp_error won't be triggered) and add a min_temp buffer to handle + * aberrant readings. + * + * If you want to enable this feature for your hotend thermistor(s) + * uncomment and set values > 0 in the constants below + */ + +// The number of consecutive low temperature errors that can occur +// before a min_temp_error is triggered. (Shouldn't be more than 10.) +//#define MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED 0 + +// The number of milliseconds a hotend will preheat before starting to check +// the temperature. This value should NOT be set to the time it takes the +// hot end to reach the target temperature, but the time it takes to reach +// the minimum temperature your thermistor can read. The lower the better/safer. +// This shouldn't need to be more than 30 seconds (30000) +//#define MILLISECONDS_PREHEAT_TIME 0 + +// @section extruder + +// Extruder runout prevention. +// If the machine is idle and the temperature over MINTEMP +// then extrude some filament every couple of SECONDS. +//#define EXTRUDER_RUNOUT_PREVENT +#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_EXTRUDE 5 // mm +#endif + +// @section temperature + +//These defines help to calibrate the AD595 sensor in case you get wrong temperature measurements. +//The measured temperature is defined as "actualTemp = (measuredTemp * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET" +#define TEMP_SENSOR_AD595_OFFSET 0.0 +#define TEMP_SENSOR_AD595_GAIN 1.0 + +/** + * 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. + */ +//#define USE_CONTROLLER_FAN +#if ENABLED(USE_CONTROLLER_FAN) + //#define CONTROLLER_FAN_PIN FAN1_PIN // 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 +#endif + +// When first starting the main fan, run it at full speed for the +// given number of milliseconds. This gets the fan spinning reliably +// before setting a PWM value. (Does not work with software PWM for fan on Sanguinololu) +#define FAN_KICKSTART_TIME 500 + +// This defines the minimal speed for the main fan, run in PWM mode +// to enable uncomment and set minimal PWM speed for reliable running (1-255) +// if fan speed is [1 - (FAN_MIN_PWM-1)] it is set to FAN_MIN_PWM +#define FAN_MIN_PWM 50 + +// @section extruder + +/** + * Extruder cooling fans + * + * Extruder auto fans automatically turn on when their extruders' + * temperatures go above EXTRUDER_AUTO_FAN_TEMPERATURE. + * + * Your board's pins file specifies the recommended pins. Override those here + * or set to -1 to disable completely. + * + * Multiple extruders can be assigned to the same pin in which case + * the fan will turn on when any selected extruder is above the threshold. + */ +#define E0_AUTO_FAN_PIN -1 +#define E1_AUTO_FAN_PIN -1 +#define E2_AUTO_FAN_PIN -1 +#define E3_AUTO_FAN_PIN -1 +#define E4_AUTO_FAN_PIN -1 +#define EXTRUDER_AUTO_FAN_TEMPERATURE 50 +#define EXTRUDER_AUTO_FAN_SPEED 255 // == full speed + +/** + * Part-Cooling Fan Multiplexer + * + * This feature allows you to digitally multiplex the fan output. + * The multiplexer is automatically switched at tool-change. + * Set FANMUX[012]_PINs below for up to 2, 4, or 8 multiplexed fans. + */ +#define FANMUX0_PIN -1 +#define FANMUX1_PIN -1 +#define FANMUX2_PIN -1 + +/** + * M355 Case Light on-off / brightness + */ +//#define CASE_LIGHT_ENABLE +#if ENABLED(CASE_LIGHT_ENABLE) + //#define CASE_LIGHT_PIN 4 // Override the default pin if needed + #define INVERT_CASE_LIGHT false // Set true if Case Light is ON when pin is LOW + #define CASE_LIGHT_DEFAULT_ON true // Set default power-up state on + #define CASE_LIGHT_DEFAULT_BRIGHTNESS 105 // Set default power-up brightness (0-255, requires PWM pin) + //#define MENU_ITEM_CASE_LIGHT // Add a Case Light option to the LCD main menu +#endif + +//=========================================================================== +//============================ Mechanical Settings ========================== +//=========================================================================== + +// @section homing + +// If you want endstops to stay on (by default) even when not homing +// enable this option. Override at any time with M120, M121. +//#define ENDSTOPS_ALWAYS_ON_DEFAULT + +// @section extras + +//#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. + +// Dual X Steppers +// Uncomment this option to drive two X axis motors. +// The next unused E driver will be assigned to the second X stepper. +//#define X_DUAL_STEPPER_DRIVERS +#if ENABLED(X_DUAL_STEPPER_DRIVERS) + // Set true if the two X motors need to rotate in opposite directions + #define INVERT_X2_VS_X_DIR true +#endif + +// Dual Y Steppers +// Uncomment this option to drive two Y axis motors. +// The next unused E driver will be assigned to the second Y stepper. +//#define Y_DUAL_STEPPER_DRIVERS +#if ENABLED(Y_DUAL_STEPPER_DRIVERS) + // Set true if the two Y motors need to rotate in opposite directions + #define INVERT_Y2_VS_Y_DIR true +#endif + +// A single Z stepper driver is usually used to drive 2 stepper motors. +// Uncomment this option to use a separate stepper driver for each Z axis motor. +// The next unused E driver will be assigned to the second Z stepper. +//#define Z_DUAL_STEPPER_DRIVERS + +#if ENABLED(Z_DUAL_STEPPER_DRIVERS) + + // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper. + // That way the machine is capable to align the bed during home, since both Z steppers are homed. + // There is also an implementation of M666 (software endstops adjustment) to this feature. + // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed. + // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2. + // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive. + // Play a little bit with small adjustments (0.5mm) and check the behaviour. + // The M119 (endstops report) will start reporting the Z2 Endstop as well. + + //#define Z_DUAL_ENDSTOPS + + #if ENABLED(Z_DUAL_ENDSTOPS) + #define Z2_USE_ENDSTOP _XMAX_ + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 // Use M666 to determine/test this value + #endif + +#endif // Z_DUAL_STEPPER_DRIVERS + +// Enable this for dual x-carriage printers. +// A dual x-carriage design has the advantage that the inactive extruder can be parked which +// prevents hot-end ooze contaminating the print. It also reduces the weight of each x-carriage +// allowing faster printing speeds. Connect your X2 stepper to the first unused E plug. +//#define DUAL_X_CARRIAGE +#if ENABLED(DUAL_X_CARRIAGE) + // Configuration for second X-carriage + // Note: the first x-carriage is defined as the x-carriage which homes to the minimum endstop; + // the second x-carriage always homes to the maximum endstop. + #define X2_MIN_POS 80 // set minimum to ensure second x-carriage doesn't hit the parked first X-carriage + #define X2_MAX_POS 353 // set maximum to the distance between toolheads when both heads are homed + #define X2_HOME_DIR 1 // the second X-carriage always homes to the maximum endstop position + #define X2_HOME_POS X2_MAX_POS // default home position is the maximum carriage position + // However: In this mode the HOTEND_OFFSET_X value for the second extruder provides a software + // override for X2_HOME_POS. This also allow recalibration of the distance between the two endstops + // without modifying the firmware (through the "M218 T1 X???" command). + // Remember: you should set the second extruder x-offset to 0 in your slicer. + + // There are a few selectable movement modes for dual x-carriages using M605 S + // Mode 0 (DXC_FULL_CONTROL_MODE): Full control. The slicer has full control over both x-carriages and can achieve optimal travel results + // as long as it supports dual x-carriages. (M605 S0) + // Mode 1 (DXC_AUTO_PARK_MODE) : Auto-park mode. The firmware will automatically park and unpark the x-carriages on tool changes so + // that additional slicer support is not required. (M605 S1) + // Mode 2 (DXC_DUPLICATION_MODE) : Duplication mode. The firmware will transparently make the second x-carriage and extruder copy all + // actions of the first x-carriage. This allows the printer to print 2 arbitrary items at + // once. (2nd extruder x offset and temp offset are set using: M605 S2 [Xnnn] [Rmmm]) + + // This is the default power-up mode which can be later using M605. + #define DEFAULT_DUAL_X_CARRIAGE_MODE DXC_FULL_CONTROL_MODE + + // Default settings in "Auto-park Mode" + #define TOOLCHANGE_PARK_ZLIFT 0.2 // the distance to raise Z axis when parking an extruder + #define TOOLCHANGE_UNPARK_ZLIFT 1 // the distance to raise Z axis when unparking an extruder + + // Default x offset in duplication mode (typically set to half print bed width) + #define DEFAULT_DUPLICATION_X_OFFSET 100 + +#endif // DUAL_X_CARRIAGE + +// 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. +//#define EXT_SOLENOID + +// @section homing + +//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +#define X_HOME_BUMP_MM 5 +#define Y_HOME_BUMP_MM 5 +#define Z_HOME_BUMP_MM 2 +#define HOMING_BUMP_DIVISOR {4, 4, 8} // Re-Bump Speed Divisor (Divides the Homing Feedrate) +#define QUICK_HOME //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially. + +// When G28 is called, this option will make Y home before X +//#define HOME_Y_BEFORE_X + +// @section machine + +#define AXIS_RELATIVE_MODES {false, false, false, false} + +// Allow duplication mode with a basic dual-nozzle extruder +//#define DUAL_NOZZLE_DUPLICATION_MODE + +// By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step. +#define INVERT_X_STEP_PIN false +#define INVERT_Y_STEP_PIN false +#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. +#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_E true + +#define DEFAULT_MINIMUMFEEDRATE 0.0 // minimum feedrate +#define DEFAULT_MINTRAVELFEEDRATE 0.0 + +//#define HOME_AFTER_DEACTIVATE // Require rehoming after steppers are deactivated + +// @section lcd + +#if ENABLED(ULTIPANEL) + #define MANUAL_FEEDRATE {50*60, 50*60, 4*60, 60} // Feedrates for manual moves along X, Y, Z, E from panel + #define ULTIPANEL_FEEDMULTIPLY // Comment to disable setting feedrate multiplier via encoder +#endif + +// @section extras + +// minimum time in microseconds that a movement needs to take if the buffer is emptied. +#define DEFAULT_MINSEGMENTTIME 20000 + +// If defined the movements slow down when the look ahead buffer is only half full +#define SLOWDOWN + +// Frequency limit +// See nophead's blog for more info +// Not working O +//#define XY_FREQUENCY_LIMIT 15 + +// 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 +// if unwanted behavior is observed on a user's machine when running at very slow speeds. +#define MINIMUM_PLANNER_SPEED 0.05 // (mm/sec) + +// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU. +#define MICROSTEP_MODES {16,16,16,16,16} // [1,2,4,8,16] + +/** + * @section stepper motor current + * + * Some boards have a means of setting the stepper motor current via firmware. + * + * The power on motor currents are set by: + * PWM_MOTOR_CURRENT - used by MINIRAMBO & ULTIMAIN_2 + * known compatible chips: A4982 + * DIGIPOT_MOTOR_CURRENT - used by BQ_ZUM_MEGA_3D, RAMBO & SCOOVO_X9H + * known compatible chips: AD5206 + * DAC_MOTOR_CURRENT_DEFAULT - used by PRINTRBOARD_REVF & RIGIDBOARD_V2 + * known compatible chips: MCP4728 + * DIGIPOT_I2C_MOTOR_CURRENTS - used by 5DPRINT, AZTEEG_X3_PRO, MIGHTYBOARD_REVE + * known compatible chips: MCP4451, MCP4018 + * + * Motor currents can also be set by M907 - M910 and by the LCD. + * M907 - applies to all. + * M908 - BQ_ZUM_MEGA_3D, RAMBO, PRINTRBOARD_REVF, RIGIDBOARD_V2 & SCOOVO_X9H + * M909, M910 & LCD - only PRINTRBOARD_REVF & RIGIDBOARD_V2 + */ +//#define PWM_MOTOR_CURRENT { 1300, 1300, 1250 } // Values in milliamps +//#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 + +// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +//#define DIGIPOT_I2C +//#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster +#define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 +// Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS +#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=========================== +//=========================================================================== + +#define ENCODER_RATE_MULTIPLIER // If defined, certain menu edit operations automatically multiply the steps when the encoder is moved quickly +#define ENCODER_10X_STEPS_PER_SEC 75 // If the encoder steps per sec exceeds this value, multiply steps moved x10 to quickly advance the value +#define ENCODER_100X_STEPS_PER_SEC 160 // If the encoder steps per sec exceeds this value, multiply steps moved x100 to really quickly advance the value + +//#define CHDK 4 //Pin for triggering CHDK to take a picture see how to use it here http://captain-slow.dk/2014/03/09/3d-printing-timelapses/ +#define CHDK_DELAY 50 //How long in ms the pin should stay HIGH before going LOW again + +// @section lcd + +// Include a page of printer information in the LCD Main Menu +//#define LCD_INFO_MENU + +// Scroll a longer status message into view +//#define STATUS_MESSAGE_SCROLLING + +// On the Info Screen, display XY with one decimal place when possible +//#define LCD_DECIMAL_SMALL_XY + +// The timeout (in ms) to return to the status screen from sub-menus +//#define LCD_TIMEOUT_TO_STATUS 15000 + +#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 + + #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? + #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. + + #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. + // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. + // using: + #define MENU_ADDAUTOSTART + + /** + * Sort SD file listings in alphabetical order. + * + * With this option enabled, items on SD cards will be sorted + * by name for easier navigation. + * + * By default... + * + * - Use the slowest -but safest- method for sorting. + * - Folders are sorted to the top. + * - The sort key is statically allocated. + * - No added G-code (M34) support. + * - 40 item sorting limit. (Items after the first 40 are unsorted.) + * + * SD sorting uses static allocation (as set by SDSORT_LIMIT), allowing the + * compiler to calculate the worst-case usage and throw an error if the SRAM + * limit is exceeded. + * + * - SDSORT_USES_RAM provides faster sorting via a static directory buffer. + * - SDSORT_USES_STACK does the same, but uses a local stack-based buffer. + * - SDSORT_CACHE_NAMES will retain the sorted file listing in RAM. (Expensive!) + * - SDSORT_DYNAMIC_RAM only uses RAM when the SD menu is visible. (Use with caution!) + */ + //#define SDCARD_SORT_ALPHA + + // SD Card Sorting options + #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_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. + #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #endif + + // Show a progress bar on HD44780 LCDs for SD printing + #define LCD_PROGRESS_BAR + + #if ENABLED(LCD_PROGRESS_BAR) + // Amount of time (ms) to show the bar + #define PROGRESS_BAR_BAR_TIME 2000 + // Amount of time (ms) to show the status message + #define PROGRESS_BAR_MSG_TIME 3000 + // Amount of time (ms) to retain the status message (0=forever) + #define PROGRESS_MSG_EXPIRE 0 + // Enable this to show messages for MSG_TIME then hide them + //#define PROGRESS_MSG_ONCE + // Add a menu item to test the progress bar: + //#define LCD_PROGRESS_BAR_TEST + #endif + + // This allows hosts to request long names for files and folders with M33 + #define LONG_FILENAME_HOST_SUPPORT + + // This option allows you to abort SD printing when any endstop is triggered. + // This feature must be enabled with "M540 S1" or from the LCD menu. + // To have any effect, endstops must be enabled during SD printing. + //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + +#endif // SDSUPPORT + +/** + * Additional options for Graphical Displays + * + * Use the optimizations here to improve printing performance, + * which can be adversely affected by graphical display drawing, + * especially when doing several short moves, and when printing + * on DELTA and SCARA machines. + * + * Some of these options may result in the display lagging behind + * controller events, as there is a trade-off between reliable + * printing performance versus fast display updates. + */ +#if ENABLED(DOGLCD) + // Enable to save many cycles by drawing a hollow frame on the Info Screen + #define XYZ_HOLLOW_FRAME + + // Enable to save many cycles by drawing a hollow frame on Menu Screens + #define MENU_HOLLOW_FRAME + + // A bigger font is available for edit items. Costs 3120 bytes of PROGMEM. + // 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. + // 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 +#endif // DOGLCD + +// @section safety + +// The hardware watchdog should reset the microcontroller disabling all outputs, +// in case the firmware gets stuck and doesn't do temperature regulation. +#define USE_WATCHDOG + +#if ENABLED(USE_WATCHDOG) + // If you have a watchdog reboot in an ArduinoMega2560 then the device will hang forever, as a watchdog reset will leave the watchdog on. + // The "WATCHDOG_RESET_MANUAL" goes around this by not using the hardware reset. + // However, THIS FEATURE IS UNSAFE!, as it will only work if interrupts are disabled. And the code could hang in an interrupt routine with interrupts disabled. + //#define WATCHDOG_RESET_MANUAL +#endif + +// @section lcd + +/** + * Babystepping enables movement of the axes by tiny increments without changing + * the current position values. This feature is used primarily to adjust the Z + * axis in the first layer of a print in real-time. + * + * Warning: Does not respect endstops! + */ +#define BABYSTEPPING +#if ENABLED(BABYSTEPPING) + //#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 100 // Babysteps are very small. Increase for faster motion. + //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping + //#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen 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_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor + //#define BABYSTEP_ZPROBE_GFX_REVERSE // Reverses the direction of the CW/CCW indicators +#endif + +// @section extruder + +/** + * Implementation of linear pressure control + * + * Assumption: advance = k * (delta velocity) + * K=0 means advance disabled. + * See Marlin documentation for calibration instructions. + */ +//#define LIN_ADVANCE + +#if ENABLED(LIN_ADVANCE) + #define LIN_ADVANCE_K 140 // start value for PLA on K8200 + + /** + * Some Slicers produce Gcode with randomly jumping extrusion widths occasionally. + * For example within a 0.4mm perimeter it may produce a single segment of 0.05mm width. + * While this is harmless for normal printing (the fluid nature of the filament will + * close this very, very tiny gap), it throws off the LIN_ADVANCE pressure adaption. + * + * For this case LIN_ADVANCE_E_D_RATIO can be used to set the extrusion:distance ratio + * to a fixed value. Note that using a fixed ratio will lead to wrong nozzle pressures + * if the slicer is using variable widths or layer heights within one print! + * + * This option sets the default E:D ratio at startup. Use `M900` to override this value. + * + * Example: `M900 W0.4 H0.2 D1.75`, where: + * - W is the extrusion width in mm + * - H is the layer height in mm + * - D is the filament diameter in mm + * + * Example: `M900 R0.0458` to set the ratio directly. + * + * Set to 0 to auto-detect the ratio based on given Gcode G1 print moves. + * + * Slic3r (including Průša Control) produces Gcode compatible with the automatic mode. + * Cura (as of this writing) may produce Gcode incompatible with the automatic mode. + */ + #define LIN_ADVANCE_E_D_RATIO 0 // The calculated ratio (or 0) according to the formula W * H / ((D / 2) ^ 2 * PI) + // Example: 0.4 * 0.2 / ((1.75 / 2) ^ 2 * PI) = 0.033260135 +#endif + +// @section leveling + +// Default mesh area is an area with an inset margin on the print area. +// Below are the macros that are used to define the borders for the mesh area, +// made available here for specialized needs, ie dual extruder setup. +#if ENABLED(MESH_BED_LEVELING) + #define MESH_MIN_X MESH_INSET + #define MESH_MAX_X (X_BED_SIZE - (MESH_INSET)) + #define MESH_MIN_Y MESH_INSET + #define MESH_MAX_Y (Y_BED_SIZE - (MESH_INSET)) +#elif ENABLED(AUTO_BED_LEVELING_UBL) + #define UBL_MESH_MIN_X UBL_MESH_INSET + #define UBL_MESH_MAX_X (X_BED_SIZE - (UBL_MESH_INSET)) + #define UBL_MESH_MIN_Y UBL_MESH_INSET + #define UBL_MESH_MAX_Y (Y_BED_SIZE - (UBL_MESH_INSET)) + + // If this is defined, the currently active mesh will be saved in the + // current slot on M500. + #define UBL_SAVE_ACTIVE_ON_M500 +#endif + +// @section extras + +// +// G2/G3 Arc Support +// +#define ARC_SUPPORT // Disable this feature to save ~3226 bytes +#if ENABLED(ARC_SUPPORT) + #define MM_PER_ARC_SEGMENT 1 // Length of each arc segment + #define N_ARC_CORRECTION 25 // Number of intertpolated 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 +#endif + +// Support for G5 with XYZE destination and IJPQ offsets. Requires ~2666 bytes. +//#define BEZIER_CURVE_SUPPORT + +// G38.2 and G38.3 Probe Target +// Enable PROBE_DOUBLE_TOUCH if you want G38 to double touch +//#define G38_PROBE_TARGET +#if ENABLED(G38_PROBE_TARGET) + #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) +#endif + +// Moves (or segments) with fewer steps than this will be joined with the next move +#define MIN_STEPS_PER_SEGMENT 6 + +// The minimum pulse width (in µs) for stepping a stepper. +// Set this if you find stepping unreliable, or if using a very fast CPU. +#define MINIMUM_STEPPER_PULSE 0 // (µs) The smallest stepper pulse allowed + +// @section temperature + +// Control heater 0 and heater 1 in parallel. +//#define HEATERS_PARALLEL + +//=========================================================================== +//================================= Buffers ================================= +//=========================================================================== + +// @section hidden + +// 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, i.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 +#else + #define BLOCK_BUFFER_SIZE 32 // maximize block buffer +#endif + +// @section serial + +// The ASCII buffer for serial input +#define MAX_CMD_SIZE 96 +#define BUFSIZE 4 + +// Transmission to Host Buffer Size +// To save 386 bytes of PROGMEM (and TX_BUFFER_SIZE+3 bytes of RAM) set to 0. +// To buffer a simple "ok" you need 4 bytes. +// For ADVANCED_OK (M105) you need 32 bytes. +// For debug-echo: 128 bytes for the optimal speed. +// Other output doesn't need to be that speedy. +// :[0, 2, 4, 8, 16, 32, 64, 128, 256] +#define TX_BUFFER_SIZE 128 + +// Host Receive Buffer Size +// Without XON/XOFF flow control (see SERIAL_XON_XOFF below) 32 bytes should be enough. +// To use flow control, set this buffer size to at least 1024 bytes. +// :[0, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048] +//#define RX_BUFFER_SIZE 1024 + +#if RX_BUFFER_SIZE >= 1024 + // Enable to have the controller send XON/XOFF control characters to + // the host to signal the RX buffer is becoming full. + //#define SERIAL_XON_XOFF +#endif + +#if ENABLED(SDSUPPORT) + // Enable this option to collect and display the maximum + // RX queue usage after transferring a file to SD. + //#define SERIAL_STATS_MAX_RX_QUEUED + + // Enable this option to collect and display the number + // of dropped bytes after a file transfer to SD. + //#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! +//#define EMERGENCY_PARSER + +// Bad Serial-connections can miss a received command by sending an 'ok' +// Therefore some clients abort after 30 seconds in a timeout. +// Some other clients start sending commands while receiving a 'wait'. +// This "wait" is only sent when the buffer is empty. 1 second is a good value here. +//#define NO_TIMEOUTS 1000 // Milliseconds + +// Some clients will have this feature soon. This could make the NO_TIMEOUTS unnecessary. +//#define ADVANCED_OK + +// @section extras + +/** + * Firmware-based and LCD-controlled retract + * + * Add G10 / G11 commands for automatic firmware-based retract / recover. + * Use M207 and M208 to define parameters for retract / recover. + * + * Use M209 to enable or disable auto-retract. + * With auto-retract enabled, all G1 E moves within the set range + * will be converted to firmware-based retract/recover moves. + * + * Be sure to turn off auto-retract during filament change. + * + * Note that M207 / M208 / M209 settings are saved to EEPROM. + * + */ +//#define FWRETRACT // ONLY PARTIALLY TESTED +#if ENABLED(FWRETRACT) + #define MIN_AUTORETRACT 0.1 // When auto-retract is on, convert E moves of this length and over + #define MAX_AUTORETRACT 10.0 // Upper limit for auto-retract conversion + #define RETRACT_LENGTH 3 // Default retract length (positive mm) + #define RETRACT_LENGTH_SWAP 13 // Default swap retract length (positive mm), for extruder change + #define RETRACT_FEEDRATE 45 // Default feedrate for retracting (mm/s) + #define RETRACT_ZLIFT 0 // Default retract Z-lift + #define RETRACT_RECOVER_LENGTH 0 // Default additional recover length (mm, added to retract length when recovering) + #define RETRACT_RECOVER_LENGTH_SWAP 0 // Default additional swap recover length (mm, added to retract length when recovering from extruder change) + #define RETRACT_RECOVER_FEEDRATE 8 // Default feedrate for recovering from retraction (mm/s) + #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) +#endif + +/** + * Advanced Pause + * Experimental feature for filament change support and for parking the nozzle when paused. + * Adds the GCode M600 for initiating filament change. + * If PARK_HEAD_ON_PAUSE enabled, adds the GCode M125 to pause printing and park the nozzle. + * + * Requires an LCD display. + * This feature is required for the default FILAMENT_RUNOUT_SCRIPT. + */ +//#define ADVANCED_PAUSE_FEATURE +#if ENABLED(ADVANCED_PAUSE_FEATURE) + #define PAUSE_PARK_X_POS (X_MAX_POS-3) // X position of hotend + #define PAUSE_PARK_Y_POS 3 // Y position of hotend + #define PAUSE_PARK_Z_ADD 10 // Z addition of hotend (lift) + #define PAUSE_PARK_XY_FEEDRATE 100 // X and Y axes feedrate in mm/s (also used for delta printers Z axis) + #define PAUSE_PARK_Z_FEEDRATE 5 // Z axis feedrate in mm/s (not used for delta printers) + #define PAUSE_PARK_RETRACT_FEEDRATE 60 // Initial retract feedrate in mm/s + #define PAUSE_PARK_RETRACT_LENGTH 2 // Initial retract in mm + // It is a short retract used immediately after print interrupt before move to filament exchange position + #define FILAMENT_CHANGE_UNLOAD_FEEDRATE 10 // Unload filament feedrate in mm/s - filament unloading can be fast + #define FILAMENT_CHANGE_UNLOAD_LENGTH 100 // Unload filament length from hotend in mm + // Longer length for bowden printers to unload filament from whole bowden tube, + // shorter length for printers without bowden to unload filament from extruder only, + // 0 to disable unloading for manual unloading + #define FILAMENT_CHANGE_LOAD_FEEDRATE 6 // Load filament feedrate in mm/s - filament loading into the bowden tube can be fast + #define FILAMENT_CHANGE_LOAD_LENGTH 0 // Load filament length over hotend in mm + // Longer length for bowden printers to fast load filament into whole bowden tube over the hotend, + // Short or zero length for printers without bowden where loading is not used + #define ADVANCED_PAUSE_EXTRUDE_FEEDRATE 3 // Extrude filament feedrate in mm/s - must be slower than load feedrate + #define ADVANCED_PAUSE_EXTRUDE_LENGTH 50 // Extrude filament length in mm after filament is loaded over the hotend, + // 0 to disable for manual extrusion + // Filament can be extruded repeatedly from the filament exchange menu to fill the hotend, + // or until outcoming filament color is not clear for filament color change + #define PAUSE_PARK_NOZZLE_TIMEOUT 45 // Turn off nozzle if user doesn't change filament within this time limit in seconds + #define FILAMENT_CHANGE_NUMBER_OF_ALERT_BEEPS 5 // Number of alert beeps before printer goes quiet + #define PAUSE_PARK_NO_STEPPER_TIMEOUT // Enable to have stepper motors hold position during filament change + // even if it takes longer than DEFAULT_STEPPER_DEACTIVE_TIME. + //#define PARK_HEAD_ON_PAUSE // Go to filament change position on pause, return to print position on resume + //#define HOME_BEFORE_FILAMENT_CHANGE // Ensure homing has been completed prior to parking for filament change +#endif + +// @section tmc + +/** + * Enable this section if you have TMC26X motor drivers. + * You will need to import the TMC26XStepper library into the Arduino IDE for this + * (https://github.com/trinamic/TMC26XStepper.git) + */ +//#define HAVE_TMCDRIVER + +#if ENABLED(HAVE_TMCDRIVER) + + //#define X_IS_TMC + //#define X2_IS_TMC + //#define Y_IS_TMC + //#define Y2_IS_TMC + //#define Z_IS_TMC + //#define Z2_IS_TMC + //#define E0_IS_TMC + //#define E1_IS_TMC + //#define E2_IS_TMC + //#define E3_IS_TMC + //#define E4_IS_TMC + + #define X_MAX_CURRENT 1000 // in mA + #define X_SENSE_RESISTOR 91 // in mOhms + #define X_MICROSTEPS 16 // number of microsteps + + #define X2_MAX_CURRENT 1000 + #define X2_SENSE_RESISTOR 91 + #define X2_MICROSTEPS 16 + + #define Y_MAX_CURRENT 1000 + #define Y_SENSE_RESISTOR 91 + #define Y_MICROSTEPS 16 + + #define Y2_MAX_CURRENT 1000 + #define Y2_SENSE_RESISTOR 91 + #define Y2_MICROSTEPS 16 + + #define Z_MAX_CURRENT 1000 + #define Z_SENSE_RESISTOR 91 + #define Z_MICROSTEPS 16 + + #define Z2_MAX_CURRENT 1000 + #define Z2_SENSE_RESISTOR 91 + #define Z2_MICROSTEPS 16 + + #define E0_MAX_CURRENT 1000 + #define E0_SENSE_RESISTOR 91 + #define E0_MICROSTEPS 16 + + #define E1_MAX_CURRENT 1000 + #define E1_SENSE_RESISTOR 91 + #define E1_MICROSTEPS 16 + + #define E2_MAX_CURRENT 1000 + #define E2_SENSE_RESISTOR 91 + #define E2_MICROSTEPS 16 + + #define E3_MAX_CURRENT 1000 + #define E3_SENSE_RESISTOR 91 + #define E3_MICROSTEPS 16 + + #define E4_MAX_CURRENT 1000 + #define E4_SENSE_RESISTOR 91 + #define E4_MICROSTEPS 16 + +#endif + +// @section TMC2130 + +/** + * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. + * + * You'll also need the TMC2130Stepper Arduino library + * (https://github.com/teemuatlut/TMC2130Stepper). + * + * To use TMC2130 stepper drivers in SPI mode connect your SPI2130 pins to + * the hardware SPI interface on your board and define the required CS pins + * in your `pins_MYBOARD.h` file. (e.g., RAMPS 1.4 uses AUX3 pins `X_CS_PIN 53`, `Y_CS_PIN 49`, etc.). + */ +//#define HAVE_TMC2130 + +#if ENABLED(HAVE_TMC2130) + + // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY + //#define X_IS_TMC2130 + //#define X2_IS_TMC2130 + //#define Y_IS_TMC2130 + //#define Y2_IS_TMC2130 + //#define Z_IS_TMC2130 + //#define Z2_IS_TMC2130 + //#define E0_IS_TMC2130 + //#define E1_IS_TMC2130 + //#define E2_IS_TMC2130 + //#define E3_IS_TMC2130 + //#define E4_IS_TMC2130 + + /** + * Stepper driver settings + */ + + #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 + #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current + #define INTERPOLATE 1 // Interpolate X/Y/Z_MICROSTEPS to 256 + + #define X_CURRENT 1000 // rms current in mA. Multiply by 1.41 for peak current. + #define X_MICROSTEPS 16 // 0..256 + + #define Y_CURRENT 1000 + #define Y_MICROSTEPS 16 + + #define Z_CURRENT 1000 + #define Z_MICROSTEPS 16 + + //#define X2_CURRENT 1000 + //#define X2_MICROSTEPS 16 + + //#define Y2_CURRENT 1000 + //#define Y2_MICROSTEPS 16 + + //#define Z2_CURRENT 1000 + //#define Z2_MICROSTEPS 16 + + //#define E0_CURRENT 1000 + //#define E0_MICROSTEPS 16 + + //#define E1_CURRENT 1000 + //#define E1_MICROSTEPS 16 + + //#define E2_CURRENT 1000 + //#define E2_MICROSTEPS 16 + + //#define E3_CURRENT 1000 + //#define E3_MICROSTEPS 16 + + //#define E4_CURRENT 1000 + //#define E4_MICROSTEPS 16 + + /** + * Use Trinamic's ultra quiet stepping mode. + * When disabled, Marlin will use spreadCycle stepping mode. + */ + #define STEALTHCHOP + + /** + * Let Marlin automatically control stepper current. + * This is still an experimental feature. + * Increase current every 5s by CURRENT_STEP until stepper temperature prewarn gets triggered, + * then decrease current by CURRENT_STEP until temperature prewarn is cleared. + * Adjusting starts from X/Y/Z/E_CURRENT but will not increase over AUTO_ADJUST_MAX + * 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. + * M906 S1 - Start adjusting current + * M906 S0 - Stop adjusting current + * M911 - Report stepper driver overtemperature pre-warn condition. + * M912 - Clear stepper driver overtemperature pre-warn condition flag. + */ + //#define AUTOMATIC_CURRENT_CONTROL + + #if ENABLED(AUTOMATIC_CURRENT_CONTROL) + #define CURRENT_STEP 50 // [mA] + #define AUTO_ADJUST_MAX 1300 // [mA], 1300mA_rms = 1840mA_peak + #define REPORT_CURRENT_CHANGE + #endif + + /** + * The driver will switch to spreadCycle when stepper speed is over HYBRID_THRESHOLD. + * This mode allows for faster movements at the expense of higher noise levels. + * STEALTHCHOP needs to be enabled. + * M913 X/Y/Z/E to live tune the setting + */ + //#define HYBRID_THRESHOLD + + #define X_HYBRID_THRESHOLD 100 // [mm/s] + #define X2_HYBRID_THRESHOLD 100 + #define Y_HYBRID_THRESHOLD 100 + #define Y2_HYBRID_THRESHOLD 100 + #define Z_HYBRID_THRESHOLD 4 + #define Z2_HYBRID_THRESHOLD 4 + #define E0_HYBRID_THRESHOLD 30 + #define E1_HYBRID_THRESHOLD 30 + #define E2_HYBRID_THRESHOLD 30 + #define E3_HYBRID_THRESHOLD 30 + #define E4_HYBRID_THRESHOLD 30 + + /** + * Use stallGuard2 to sense an obstacle and trigger an endstop. + * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. + * If used along with STEALTHCHOP, the movement will be louder when homing. This is normal. + * + * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. + * Higher values make the system LESS sensitive. + * Lower value make the system MORE sensitive. + * Too low values can lead to false positives, while too high values will collide the axis without triggering. + * It is advised to set X/Y_HOME_BUMP_MM to 0. + * M914 X/Y to live tune the setting + */ + //#define SENSORLESS_HOMING + + #if ENABLED(SENSORLESS_HOMING) + #define X_HOMING_SENSITIVITY 19 + #define Y_HOMING_SENSITIVITY 19 + #endif + + /** + * You can set your own advanced settings by filling in predefined functions. + * A list of available functions can be found on the library github page + * https://github.com/teemuatlut/TMC2130Stepper + * + * Example: + * #define TMC2130_ADV() { \ + * stepperX.diag0_temp_prewarn(1); \ + * stepperX.interpolate(0); \ + * } + */ + #define TMC2130_ADV() { } + +#endif // HAVE_TMC2130 + +// @section L6470 + +/** + * Enable this section if you have L6470 motor drivers. + * You need to import the L6470 library into the Arduino IDE for this. + * (https://github.com/ameyer/Arduino-L6470) + */ + +//#define HAVE_L6470DRIVER +#if ENABLED(HAVE_L6470DRIVER) + + //#define X_IS_L6470 + //#define X2_IS_L6470 + //#define Y_IS_L6470 + //#define Y2_IS_L6470 + //#define Z_IS_L6470 + //#define Z2_IS_L6470 + //#define E0_IS_L6470 + //#define E1_IS_L6470 + //#define E2_IS_L6470 + //#define E3_IS_L6470 + //#define E4_IS_L6470 + + #define X_MICROSTEPS 16 // number of microsteps + #define X_K_VAL 50 // 0 - 255, Higher values, are higher power. Be careful not to go too high + #define X_OVERCURRENT 2000 // maxc current in mA. If the current goes over this value, the driver will switch off + #define X_STALLCURRENT 1500 // current in mA where the driver will detect a stall + + #define X2_MICROSTEPS 16 + #define X2_K_VAL 50 + #define X2_OVERCURRENT 2000 + #define X2_STALLCURRENT 1500 + + #define Y_MICROSTEPS 16 + #define Y_K_VAL 50 + #define Y_OVERCURRENT 2000 + #define Y_STALLCURRENT 1500 + + #define Y2_MICROSTEPS 16 + #define Y2_K_VAL 50 + #define Y2_OVERCURRENT 2000 + #define Y2_STALLCURRENT 1500 + + #define Z_MICROSTEPS 16 + #define Z_K_VAL 50 + #define Z_OVERCURRENT 2000 + #define Z_STALLCURRENT 1500 + + #define Z2_MICROSTEPS 16 + #define Z2_K_VAL 50 + #define Z2_OVERCURRENT 2000 + #define Z2_STALLCURRENT 1500 + + #define E0_MICROSTEPS 16 + #define E0_K_VAL 50 + #define E0_OVERCURRENT 2000 + #define E0_STALLCURRENT 1500 + + #define E1_MICROSTEPS 16 + #define E1_K_VAL 50 + #define E1_OVERCURRENT 2000 + #define E1_STALLCURRENT 1500 + + #define E2_MICROSTEPS 16 + #define E2_K_VAL 50 + #define E2_OVERCURRENT 2000 + #define E2_STALLCURRENT 1500 + + #define E3_MICROSTEPS 16 + #define E3_K_VAL 50 + #define E3_OVERCURRENT 2000 + #define E3_STALLCURRENT 1500 + + #define E4_MICROSTEPS 16 + #define E4_K_VAL 50 + #define E4_OVERCURRENT 2000 + #define E4_STALLCURRENT 1500 + +#endif + +/** + * TWI/I2C BUS + * + * This feature is an EXPERIMENTAL feature so it shall not be used on production + * machines. Enabling this will allow you to send and receive I2C data from slave + * devices on the bus. + * + * ; Example #1 + * ; This macro send the string "Marlin" to the slave device with address 0x63 (99) + * ; It uses multiple M260 commands with one B arg + * M260 A99 ; Target slave address + * M260 B77 ; M + * M260 B97 ; a + * M260 B114 ; r + * M260 B108 ; l + * M260 B105 ; i + * M260 B110 ; n + * M260 S1 ; Send the current buffer + * + * ; Example #2 + * ; Request 6 bytes from slave device with address 0x63 (99) + * M261 A99 B5 + * + * ; Example #3 + * ; Example serial output of a M261 request + * echo:i2c-reply: from:99 bytes:5 data:hello + */ + +// @section i2cbus + +//#define EXPERIMENTAL_I2CBUS +#define I2C_SLAVE_ADDRESS 0 // Set a value from 8 to 127 to act as a slave + +// @section extras + +/** + * Spindle & Laser control + * + * Add the M3, M4, and M5 commands to turn the spindle/laser on and off, and + * to set spindle speed, spindle direction, and laser power. + * + * SuperPid is a router/spindle speed controller used in the CNC milling community. + * Marlin can be used to turn the spindle on and off. It can also be used to set + * the spindle speed from 5,000 to 30,000 RPM. + * + * 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. + */ +//#define SPINDLE_LASER_ENABLE +#if ENABLED(SPINDLE_LASER_ENABLE) + + #define SPINDLE_LASER_ENABLE_INVERT false // set to "true" if the on/off function is reversed + #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 // delay in milliseconds to allow the spindle/laser to come up to speed/power + #define SPINDLE_LASER_POWERDOWN_DELAY 5000 // delay in milliseconds to allow the spindle to stop + #define SPINDLE_DIR_CHANGE true // set to true if your spindle controller supports changing spindle direction + #define SPINDLE_INVERT_DIR false + #define SPINDLE_STOP_ON_DIR_CHANGE true // set to true if Marlin should stop the spindle before changing rotation direction + + /** + * The M3 & M4 commands use the following equation to convert PWM duty cycle to speed/power + * + * SPEED/POWER = PWM duty cycle * SPEED_POWER_SLOPE + SPEED_POWER_INTERCEPT + * where PWM duty cycle varies from 0 to 255 + * + * set the following for your controller (ALL MUST BE SET) + */ + + #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_SLOPE 0.3922 + //#define SPEED_POWER_INTERCEPT 0 + //#define SPEED_POWER_MIN 10 + //#define SPEED_POWER_MAX 100 // 0-100% +#endif + +/** + * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins + */ +//#define PINS_DEBUGGING + +/** + * Auto-report temperatures with M155 S + */ +#define AUTO_REPORT_TEMPERATURES + +/** + * Include capabilities in M115 output + */ +#define EXTENDED_CAPABILITIES_REPORT + +/** + * Volumetric extrusion default state + * 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. + */ +//#define VOLUMETRIC_DEFAULT_ON + +/** + * Enable this option for a leaner build of Marlin that removes all + * workspace offsets, simplifying coordinate transformations, leveling, etc. + * + * - M206 and M428 are disabled. + * - G92 will revert to its behavior from Marlin 1.0. + */ +//#define NO_WORKSPACE_OFFSETS + +/** + * 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. + * + * For clients that use a fixed-width font (like OctoPrint), leave this set to 1.0. + * Otherwise, adjust according to your client and font. + */ +#define PROPORTIONAL_FONT_RATIO 1.0 + +/** + * Spend 28 bytes of SRAM to optimize the GCode parser + */ +#define FASTER_GCODE_PARSER + +/** + * User-defined menu items that execute custom GCode + */ +//#define CUSTOM_USER_MENUS +#if ENABLED(CUSTOM_USER_MENUS) + #define USER_SCRIPT_DONE "M117 User Script Done" + #define USER_SCRIPT_AUDIBLE_FEEDBACK + //#define USER_SCRIPT_RETURN // Return to status screen after a script + + #define USER_DESC_1 "Home & UBL Info" + #define USER_GCODE_1 "G28\nG29 W" + + #define USER_DESC_2 "Preheat for PLA" + #define USER_GCODE_2 "M140 S" STRINGIFY(PREHEAT_1_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND) + + #define USER_DESC_3 "Preheat for ABS" + #define USER_GCODE_3 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND) + + #define USER_DESC_4 "Heat Bed/Home/Level" + #define USER_GCODE_4 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nG28\nG29" + + //#define USER_DESC_5 "Home & Info" + //#define USER_GCODE_5 "G28\nM503" +#endif + +/** + * Specify an action command to send to the host when the printer is killed. + * Will be sent in the form '//action:ACTION_ON_KILL', e.g. '//action:poweroff'. + * The host must be configured to handle the action command. + */ +//#define ACTION_ON_KILL "poweroff" + +//=========================================================================== +//====================== I2C Position Encoder Settings ====================== +//=========================================================================== + +/** + * I2C position encoders for closed loop control. + * Developed by Chris Barr at Aus3D. + * + * Wiki: http://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/ + * + * Reilabuild encoders have been modified to improve reliability. + */ + +//#define I2C_POSITION_ENCODERS +#if ENABLED(I2C_POSITION_ENCODERS) + + #define I2CPE_ENCODER_CNT 1 // The number of encoders installed; max of 5 + // encoders supported currently. + + #define I2CPE_ENC_1_ADDR I2CPE_PRESET_ADDR_X // I2C address of the encoder. 30-200. + #define I2CPE_ENC_1_AXIS X_AXIS // Axis the encoder module is installed on. _AXIS. + #define I2CPE_ENC_1_TYPE I2CPE_ENC_TYPE_LINEAR // Type of encoder: I2CPE_ENC_TYPE_LINEAR -or- + // I2CPE_ENC_TYPE_ROTARY. + #define I2CPE_ENC_1_TICKS_UNIT 2048 // 1024 for magnetic strips with 2mm poles; 2048 for + // 1mm poles. For linear encoders this is ticks / mm, + // for rotary encoders this is ticks / revolution. + //#define I2CPE_ENC_1_TICKS_REV (16 * 200) // Only needed for rotary encoders; number of stepper + // steps per full revolution (motor steps/rev * microstepping) + //#define I2CPE_ENC_1_INVERT // Invert the direction of axis travel. + #define I2CPE_ENC_1_EC_METHOD I2CPE_ECM_NONE // Type of error error correction. + #define I2CPE_ENC_1_EC_THRESH 0.10 // Threshold size for error (in mm) above which the + // printer will attempt to correct the error; errors + // smaller than this are ignored to minimize effects of + // measurement noise / latency (filter). + + #define I2CPE_ENC_2_ADDR I2CPE_PRESET_ADDR_Y // Same as above, but for encoder 2. + #define I2CPE_ENC_2_AXIS Y_AXIS + #define I2CPE_ENC_2_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_ENC_2_TICKS_UNIT 2048 + //#define I2CPE_ENC_2_TICKS_REV (16 * 200) + //#define I2CPE_ENC_2_INVERT + #define I2CPE_ENC_2_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_ENC_2_EC_THRESH 0.10 + + #define I2CPE_ENC_3_ADDR I2CPE_PRESET_ADDR_Z // Encoder 3. Add additional configuration options + #define I2CPE_ENC_3_AXIS Z_AXIS // as above, or use defaults below. + + #define I2CPE_ENC_4_ADDR I2CPE_PRESET_ADDR_E // Encoder 4. + #define I2CPE_ENC_4_AXIS E_AXIS + + #define I2CPE_ENC_5_ADDR 34 // Encoder 5. + #define I2CPE_ENC_5_AXIS E_AXIS + + // Default settings for encoders which are enabled, but without settings configured above. + #define I2CPE_DEF_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_DEF_ENC_TICKS_UNIT 2048 + #define I2CPE_DEF_TICKS_REV (16 * 200) + #define I2CPE_DEF_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_DEF_EC_THRESH 0.1 + + //#define I2CPE_ERR_THRESH_ABORT 100.0 // Threshold size for error (in mm) error on any given + // axis after which the printer will abort. Comment out to + // disable abort behaviour. + + #define I2CPE_TIME_TRUSTED 10000 // After an encoder fault, there must be no further fault + // for this amount of time (in ms) before the encoder + // is trusted again. + + /** + * Position is checked every time a new command is executed from the buffer but during long moves, + * this setting determines the minimum update time between checks. A value of 100 works well with + * error rolling average when attempting to correct only for skips and not for vibration. + */ + #define I2CPE_MIN_UPD_TIME_MS 100 // Minimum time in miliseconds between encoder checks. + + // Use a rolling average to identify persistant errors that indicate skips, as opposed to vibration and noise. + #define I2CPE_ERR_ROLLING_AVERAGE + +#endif // I2C_POSITION_ENCODERS + +/** + * MAX7219 Debug Matrix + * + * Add support for a low-cost 8x8 LED Matrix based on the Max7219 chip, which can be used as a status + * display. Requires 3 signal wires. Some useful debug options are included to demonstrate its usage. + * + * Fully assembled MAX7219 boards can be found on the internet for under $2(US). + * For example, see https://www.ebay.com/sch/i.html?_nkw=332349290049 + */ +//#define MAX7219_DEBUG +#if ENABLED(MAX7219_DEBUG) + #define MAX7219_CLK_PIN 64 // 77 on Re-ARM // Configuration of the 3 pins to control the display + #define MAX7219_DIN_PIN 57 // 78 on Re-ARM + #define MAX7219_LOAD_PIN 44 // 79 on Re-ARM + + /** + * Sample debug features + * If you add more debug displays, be careful to avoid conflicts! + */ + #define MAX7219_DEBUG_PRINTER_ALIVE // Blink corner LED of 8x8 matrix to show that the firmware is functioning + #define MAX7219_DEBUG_STEPPER_HEAD 3 // Show the stepper queue head position on this and the next LED matrix row + #define MAX7219_DEBUG_STEPPER_TAIL 5 // Show the stepper queue tail position on this and the next LED matrix row + + #define MAX7219_DEBUG_STEPPER_QUEUE 0 // Show the current stepper queue depth on this and the next LED matrix row + // If you experience stuttering, reboots, etc. this option can reveal how + // tweaks made to the configuration are affecting the printer in real-time. +#endif + +#endif // CONFIGURATION_ADV_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/Velleman/K8200/README.md b/trunk/Arduino/Marlin_1.1.6/example_configurations/Velleman/K8200/README.md new file mode 100644 index 00000000..42cc1846 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/Velleman/K8200/README.md @@ -0,0 +1,20 @@ +# Example Configuration for Vellemann [K8200](http://www.k8200.eu/) +* Configuration files for **Vellemann K8200** (with [VM8201](http://www.vellemanprojects.eu/products/view/?id=416158) - LCD Option for K8200) +* K8200 is a 3Drag clone - configuration should work with 3Drag http://reprap.org/wiki/3drag, too. Please report. + +* updated manually with parameters from genuine Vellemann Firmware "firmware_k8200_marlinv2" based on the recent development branch + +* VM8201 uses "DISPLAY_CHARSET_HD44870 JAPANESE" and "ULTIMAKERCONTROLLER" +* german (de) translation with umlaut is supported now - thanks to @AnHardt for the great hardware based umlaut support + +I [@CONSULitAS](https://github.com/CONSULitAS) tested the changes on my K8200 with 20x4-LCD and Arduino 1.6.12 for Mac (SD library added to IDE manually), 2016-11-18 - everything works well. + +**Source for genuine [Vellemann Firmware](http://www.k8200.eu/support/downloads/)** +* V2.1.1 (for z axis upgrade, date branched: 2013-06-05): [firmware_k8200_v2.1.1.zip](http://www.k8200.eu/downloads/files/downloads/firmware_k8200_v2.1.1.zip) + * see also https://github.com/CONSULitAS/Marlin-K8200/tree/Vellemann_firmware_k8200_v2.1.1.zip + +* V2 (with LCD/SD-Support, date branched: 2013-06-05): [firmware_k8200_marlinv2.zip](http://www.k8200.eu/downloads/files/downloads/firmware_k8200_marlinv2.zip) + * see also https://github.com/CONSULitAS/Marlin-K8200/tree/Vellemann_firmware_k8200_marlinv2.zip + +* V1 (without LCD/SD-Support, date branched: 2012-10-02): [firmware_k8200_marlinv1.zip](http://www.k8200.eu/downloads/files/downloads/firmware_k8200_marlinv1.zip) + * see also https://github.com/CONSULitAS/Marlin-K8200/tree/Vellemann_firmware_k8200_marlinv1.zip diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/Velleman/K8400/Configuration.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/Velleman/K8400/Configuration.h new file mode 100644 index 00000000..27ac63fe --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/Velleman/K8400/Configuration.h @@ -0,0 +1,1700 @@ +/** + * 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 . + * + */ + +/** + * Configuration.h + * + * Basic settings such as: + * + * - Type of electronics + * - Type of temperature sensor + * - Printer geometry + * - Endstop configuration + * - LCD controller + * - Extra features + * + * Advanced settings can be found in Configuration_adv.h + * + */ +#ifndef CONFIGURATION_H +#define CONFIGURATION_H +#define CONFIGURATION_H_VERSION 010100 + +//=========================================================================== +//============================= Getting Started ============================= +//=========================================================================== + +/** + * Here are some standard links for getting your machine calibrated: + * + * http://reprap.org/wiki/Calibration + * http://youtu.be/wAL9d7FgInk + * http://calculator.josefprusa.cz + * http://reprap.org/wiki/Triffid_Hunter%27s_Calibration_Guide + * http://www.thingiverse.com/thing:5573 + * https://sites.google.com/site/repraplogphase/calibration-of-your-reprap + * http://www.thingiverse.com/thing:298812 + */ + +//=========================================================================== +//============================= DELTA Printer =============================== +//=========================================================================== +// For a Delta printer start with one of the configuration files in the +// example_configurations/delta directory and customize for your machine. +// + +//=========================================================================== +//============================= SCARA Printer =============================== +//=========================================================================== +// For a SCARA printer start with the configuration files in +// example_configurations/SCARA and customize for your machine. +// + +// @section info + +// User-specified version info of this build to display in [Pronterface, etc] terminal window during +// startup. Implementation of an idea by Prof Braino to inform user that any changes made to this +// build by the user have been successfully uploaded into firmware. +#define STRING_CONFIG_H_AUTHOR "(Anthony Birkett, default config)" // Who made the changes. +#define SHOW_BOOTSCREEN +#define STRING_SPLASH_LINE1 SHORT_BUILD_VERSION // will be shown during bootup in line 1 +#define STRING_SPLASH_LINE2 WEBSITE_URL // will be shown during bootup in line 2 + +// +// *** VENDORS PLEASE READ ***************************************************** +// +// Marlin now allow you to have a vendor boot image to be displayed on machine +// start. When SHOW_CUSTOM_BOOTSCREEN is defined Marlin will first show your +// custom boot image and then the default Marlin boot image is shown. +// +// We suggest for you to take advantage of this new feature and keep the Marlin +// boot image unmodified. For an example have a look at the bq Hephestos 2 +// example configuration folder. +// +//#define SHOW_CUSTOM_BOOTSCREEN +// @section machine + +/** + * Select which serial port on the board will be used for communication with the host. + * This allows the connection of wireless adapters (for instance) to non-default port pins. + * Serial port 0 is always used by the Arduino bootloader regardless of this setting. + * + * :[0, 1, 2, 3, 4, 5, 6, 7] + */ +#define SERIAL_PORT 0 + +/** + * This setting determines the communication speed of the printer. + * + * 250000 works in most cases, but you might try a lower speed if + * you commonly experience drop-outs during host printing. + * You may try up to 1000000 to speed up SD file transfer. + * + * :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000] + */ +#define BAUDRATE 250000 + +// Enable the Bluetooth serial interface on AT90USB devices +//#define BLUETOOTH + +// The following define selects which electronics board you have. +// Please choose the name from boards.h that matches your setup +#ifndef MOTHERBOARD + #define MOTHERBOARD BOARD_K8400 +#endif + +// Optional custom name for your RepStrap or other custom machine +// Displayed in the LCD "Ready" message +//#define CUSTOM_MACHINE_NAME "3D Printer" + +// Define this to set a unique identifier for this printer, (Used by some programs to differentiate between machines) +// You can use an online service to generate a random UUID. (eg http://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] +#define EXTRUDERS 1 + +// For Cyclops or any "multi-extruder" that shares a single nozzle. +//#define SINGLENOZZLE + +/** + * Průša MK2 Single Nozzle Multi-Material Multiplexer, and variants. + * + * This device allows one stepper driver on a control board to drive + * two to eight stepper motors, one at a time, in a manner suitable + * for extruders. + * + * This option only allows the multiplexer to switch on tool-change. + * Additional options to configure custom E moves are pending. + */ +//#define MK2_MULTIPLEXER +#if ENABLED(MK2_MULTIPLEXER) + // Override the default DIO selector pins here, if needed. + // Some pins files may provide defaults for these pins. + //#define E_MUX0_PIN 40 // Always Required + //#define E_MUX1_PIN 42 // Needed for 3 to 8 steppers + //#define E_MUX2_PIN 44 // Needed for 5 to 8 steppers +#endif + +// A dual extruder that uses a single stepper motor +//#define SWITCHING_EXTRUDER +#if ENABLED(SWITCHING_EXTRUDER) + #define SWITCHING_EXTRUDER_SERVO_NR 0 + #define SWITCHING_EXTRUDER_SERVO_ANGLES { 0, 90 } // Angles for E0, E1[, E2, E3] + #if EXTRUDERS > 3 + #define SWITCHING_EXTRUDER_E23_SERVO_NR 1 + #endif +#endif + +// A dual-nozzle that uses a servomotor to raise/lower one of the nozzles +//#define SWITCHING_NOZZLE +#if ENABLED(SWITCHING_NOZZLE) + #define SWITCHING_NOZZLE_SERVO_NR 0 + #define SWITCHING_NOZZLE_SERVO_ANGLES { 0, 90 } // Angles for E0, E1 + //#define HOTEND_OFFSET_Z { 0.0, 0.0 } +#endif + +/** + * Two separate X-carriages with extruders that connect to a moving part + * via a magnetic docking mechanism. Requires SOL1_PIN and SOL2_PIN. + */ +//#define PARKING_EXTRUDER +#if ENABLED(PARKING_EXTRUDER) + #define PARKING_EXTRUDER_SOLENOIDS_INVERT // If enabled, the solenoid is NOT magnetized with applied voltage + #define PARKING_EXTRUDER_SOLENOIDS_PINS_ACTIVE LOW // LOW or HIGH pin signal energizes the coil + #define PARKING_EXTRUDER_SOLENOIDS_DELAY 250 // Delay (ms) for magnetic field. No delay if 0 or not defined. + #define PARKING_EXTRUDER_PARKING_X { -78, 184 } // X positions for parking the extruders + #define PARKING_EXTRUDER_GRAB_DISTANCE 1 // mm to move beyond the parking point to grab the extruder + #define PARKING_EXTRUDER_SECURITY_RAISE 5 // Z-raise before parking + #define HOTEND_OFFSET_Z { 0.0, 1.3 } // Z-offsets of the two hotends. The first must be 0. +#endif + +/** + * "Mixing Extruder" + * - Adds a new code, M165, to set the current mix factors. + * - Extends the stepping routines to move multiple steppers in proportion to the mix. + * - Optional support for Repetier Firmware M163, M164, and virtual extruder. + * - This implementation supports only a single extruder. + * - Enable DIRECT_MIXING_IN_G1 for Pia Taubert's reference implementation + */ +//#define MIXING_EXTRUDER +#if ENABLED(MIXING_EXTRUDER) + #define MIXING_STEPPERS 2 // Number of steppers in your mixing extruder + #define MIXING_VIRTUAL_TOOLS 16 // Use the Virtual Tool method with M163 and M164 + //#define DIRECT_MIXING_IN_G1 // Allow ABCDHI mix factors in G1 movement commands +#endif + +// Offset of the extruders (uncomment if using more than one and relying on firmware to position when changing). +// The offset has to be X=0, Y=0 for the extruder 0 hotend (default extruder). +// For the other hotends it is their distance from the extruder 0 hotend. +//#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis +//#define HOTEND_OFFSET_Y {0.0, 5.00} // (in mm) for each extruder, offset of the hotend on the Y axis + +// @section machine + +/** + * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN + * + * 0 = No Power Switch + * 1 = ATX + * 2 = X-Box 360 203Watts (the blue wire connected to PS_ON and the red wire to VCC) + * + * :{ 0:'No power switch', 1:'ATX', 2:'X-Box 360' } + */ +#define POWER_SUPPLY 1 + +#if POWER_SUPPLY > 0 + // Enable this option to leave the PSU off at startup. + // Power to steppers and heaters will need to be turned on with M80. + //#define PS_DEFAULT_OFF +#endif + +// @section temperature + +//=========================================================================== +//============================= Thermal Settings ============================ +//=========================================================================== + +/** + * --NORMAL IS 4.7kohm PULLUP!-- 1kohm pullup can be used on hotend sensor, using correct resistor and table + * + * Temperature sensors available: + * + * -3 : thermocouple with MAX31855 (only for sensor 0) + * -2 : thermocouple with MAX6675 (only for sensor 0) + * -1 : thermocouple with AD595 + * 0 : not used + * 1 : 100k thermistor - best choice for EPCOS 100k (4.7k pullup) + * 2 : 200k thermistor - ATC Semitec 204GT-2 (4.7k pullup) + * 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 (Used in ParCan & J-Head) (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) + * 71 : 100k Honeywell thermistor 135-104LAF-J01 (4.7k pullup) + * 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) + * 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" + * 20 : the PT100 circuit found in the Ultimainboard V2.x + * 60 : 100k Maker's Tool Works Kapton Bed Thermistor beta=3950 + * 66 : 4.7M High Temperature thermistor from Dyze Design + * 70 : the 100K thermistor found in the bq Hephestos 2 + * 75 : 100k Generic Silicon Heat Pad with NTC 100K MGB18-104F39050L32 thermistor + * + * 1k ohm pullup tables - This is atypical, and requires changing out the 4.7k pullup for 1k. + * (but gives greater accuracy and more stable PID) + * 51 : 100k thermistor - EPCOS (1k pullup) + * 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 + * 1010 : Pt1000 with 1k pullup (non standard) + * 147 : Pt100 with 4k7 pullup + * 110 : Pt100 with 1k pullup (non standard) + * + * Use these for Testing or Development purposes. NEVER for production machine. + * 998 : Dummy Table that ALWAYS reads 25°C or the temperature defined below. + * 999 : Dummy Table that ALWAYS reads 100°C or the temperature defined below. + * + * :{ '0': "Not used", '1':"100k / 4.7k - EPCOS", '2':"200k / 4.7k - ATC Semitec 204GT-2", '3':"Mendel-parts / 4.7k", '4':"10k !! do not use for a hotend. Bad resolution at high temp. !!", '5':"100K / 4.7k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '6':"100k / 4.7k EPCOS - Not as accurate as Table 1", '7':"100k / 4.7k Honeywell 135-104LAG-J01", '8':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT", '9':"100k / 4.7k GE Sensing AL03006-58.2K-97-G1", '10':"100k / 4.7k RS 198-961", '11':"100k / 4.7k beta 3950 1%", '12':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT (calibrated for Makibox hot bed)", '13':"100k Hisens 3950 1% up to 300°C for hotend 'Simple ONE ' & hotend 'All In ONE'", '20':"PT100 (Ultimainboard V2.x)", '51':"100k / 1k - EPCOS", '52':"200k / 1k - ATC Semitec 204GT-2", '55':"100k / 1k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '60':"100k Maker's Tool Works Kapton Bed Thermistor beta=3950", '66':"Dyze Design 4.7M High Temperature thermistor", '70':"the 100K thermistor found in the bq Hephestos 2", '71':"100k / 4.7k Honeywell 135-104LAF-J01", '147':"Pt100 / 4.7k", '1047':"Pt1000 / 4.7k", '110':"Pt100 / 1k (non-standard)", '1010':"Pt1000 / 1k (non standard)", '-3':"Thermocouple + MAX31855 (only for sensor 0)", '-2':"Thermocouple + MAX6675 (only for sensor 0)", '-1':"Thermocouple + AD595",'998':"Dummy 1", '999':"Dummy 2" } + */ +#define TEMP_SENSOR_0 5 +#define TEMP_SENSOR_1 0 +#define TEMP_SENSOR_2 0 +#define TEMP_SENSOR_3 0 +#define TEMP_SENSOR_4 0 +#define TEMP_SENSOR_BED 0 + +// Dummy thermistor constant temperature readings, for use with 998 and 999 +#define DUMMY_THERMISTOR_998_VALUE 25 +#define DUMMY_THERMISTOR_999_VALUE 100 + +// 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 +#define MAX_REDUNDANT_TEMP_SENSOR_DIFF 10 + +// Extruder temperature must be close to target for this long before M109 returns success +#define TEMP_RESIDENCY_TIME 2 // (seconds) +#define TEMP_HYSTERESIS 5 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// Bed temperature must be close to target for this long before M190 returns success +#define TEMP_BED_RESIDENCY_TIME 10 // (seconds) +#define TEMP_BED_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_BED_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// The minimal temperature defines the temperature below which the heater will not be enabled It is used +// to check that the wiring to the thermistor is not broken. +// Otherwise this would lead to the heater being powered on all the time. +#define HEATER_0_MINTEMP 5 +#define HEATER_1_MINTEMP 5 +#define HEATER_2_MINTEMP 5 +#define HEATER_3_MINTEMP 5 +#define HEATER_4_MINTEMP 5 +#define BED_MINTEMP 5 + +// When temperature exceeds max temp, your heater will be switched off. +// This feature exists to protect your hotend from overheating accidentally, but *NOT* from thermistor short/failure! +// You should use MINTEMP for thermistor short/failure protection. +#define HEATER_0_MAXTEMP 275 +#define HEATER_1_MAXTEMP 275 +#define HEATER_2_MAXTEMP 275 +#define HEATER_3_MAXTEMP 275 +#define HEATER_4_MAXTEMP 275 +#define BED_MAXTEMP 150 + +//=========================================================================== +//============================= PID Settings ================================ +//=========================================================================== +// PID Tuning Guide here: http://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 +#if ENABLED(PIDTEMP) + //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. + //#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. + #define K1 0.95 //smoothing factor within the PID + + // 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 + +#endif // PIDTEMP + +//=========================================================================== +//============================= PID > Bed Temperature Control =============== +//=========================================================================== +// Select PID or bang-bang with PIDTEMPBED. If bang-bang, BED_LIMIT_SWITCHING will enable hysteresis +// +// Uncomment this to enable PID on the bed. It uses the same frequency PWM as the extruder. +// If your PID_dT is the default, and correct for your hardware/configuration, that means 7.689Hz, +// which is fine for driving a square wave into a resistive load and does not significantly impact you FET heating. +// This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W heater. +// If your configuration is significantly different than this and you don't understand the issues involved, you probably +// shouldn't use bed PID until someone else verifies your hardware works. +// If this is enabled, find your own PID constants below. +//#define PIDTEMPBED + +//#define BED_LIMIT_SWITCHING + +// This sets the max power delivered to the bed, and replaces the HEATER_BED_DUTY_CYCLE_DIVIDER option. +// all forms of bed control obey this (PID, bang-bang, bang-bang with hysteresis) +// setting this to anything other than 255 enables a form of PWM to the bed just like HEATER_BED_DUTY_CYCLE_DIVIDER did, +// so you shouldn't use it unless you are OK with PWM on your bed. (see the comment on enabling PIDTEMPBED) +#define MAX_BED_POWER 255 // limits duty cycle to bed; 255=full current + +#if ENABLED(PIDTEMPBED) + + //#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) + #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 + +// @section extruder + +// This option prevents extrusion if the temperature is below EXTRUDE_MINTEMP. +// It also enables the M302 command to set the minimum extrusion temperature +// or to allow moving the extruder regardless of the hotend temperature. +// *** IT IS HIGHLY RECOMMENDED TO LEAVE THIS OPTION ENABLED! *** +#define PREVENT_COLD_EXTRUSION +#define EXTRUDE_MINTEMP 170 + +// This option prevents a single extrusion longer than EXTRUDE_MAXLENGTH. +// Note that for Bowden Extruders a too-small value here may prevent loading. +#define PREVENT_LENGTHY_EXTRUDE +#define EXTRUDE_MAXLENGTH 200 + +//=========================================================================== +//======================== Thermal Runaway Protection ======================= +//=========================================================================== + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * If you get "Thermal Runaway" or "Heating failed" errors the + * details can be tuned in Configuration_adv.h + */ + +#define THERMAL_PROTECTION_HOTENDS // Enable thermal protection for all extruders +#define THERMAL_PROTECTION_BED // Enable thermal protection for the heated bed + +//=========================================================================== +//============================= Mechanical Settings ========================= +//=========================================================================== + +// @section machine + +// Uncomment one of these options to enable CoreXY, CoreXZ, or CoreYZ kinematics +// either in the usual order or reversed +//#define COREXY +//#define COREXZ +//#define COREYZ +//#define COREYX +//#define COREZX +//#define COREZY + +//=========================================================================== +//============================== Endstop Settings =========================== +//=========================================================================== + +// @section homing + +// Specify here all the endstop connectors that are connected to any endstop or probe. +// Almost all printers will be using one per axis. Probes will use one or more of the +// extra connectors. Leave undefined any used for non-endstop and non-probe purposes. +#define USE_XMIN_PLUG +#define USE_YMIN_PLUG +#define USE_ZMIN_PLUG +//#define USE_XMAX_PLUG +//#define USE_YMAX_PLUG +//#define USE_ZMAX_PLUG + +// coarse Endstop Settings +#define ENDSTOPPULLUPS // Comment this out (using // at the start of the line) to disable the endstop pullup resistors + +#if DISABLED(ENDSTOPPULLUPS) + // fine endstop settings: Individual pullups. will be ignored if ENDSTOPPULLUPS is defined + //#define ENDSTOPPULLUP_XMAX + //#define ENDSTOPPULLUP_YMAX + //#define ENDSTOPPULLUP_ZMAX + //#define ENDSTOPPULLUP_XMIN + //#define ENDSTOPPULLUP_YMIN + //#define ENDSTOPPULLUP_ZMIN + //#define ENDSTOPPULLUP_ZMIN_PROBE +#endif + +// Mechanical endstop with COM to ground and NC to Signal uses "false" here (most common setup). +#define X_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Y_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define X_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Y_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MIN_PROBE_ENDSTOP_INVERTING true // set to true to invert the logic of the probe. + +// Enable this feature if all enabled endstop pins are interrupt-capable. +// This will remove the need to poll the interrupt pins, saving many CPU cycles. +//#define ENDSTOP_INTERRUPTS_FEATURE + +//============================================================================= +//============================== Movement Settings ============================ +//============================================================================= +// @section motion + +/** + * Default Settings + * + * These settings can be reset by M502 + * + * Note that if EEPROM is enabled, saved values will override these. + */ + +/** + * With this option each E stepper can have its own factors for the + * following movement settings. If fewer factors are given than the + * total number of extruders, the last value applies to the rest. + */ +//#define DISTINCT_E_FACTORS + +/** + * Default Axis Steps Per Unit (steps/mm) + * Override with M92 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_AXIS_STEPS_PER_UNIT { 134.74, 134.74, 4266.66, 148.7 } + +/** + * Default Max Feed Rate (mm/s) + * Override with M203 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_FEEDRATE { 160, 160, 10, 10000 } + +/** + * Default Max Acceleration (change/s) change = mm/s + * (Maximum start speed for accelerated moves) + * Override with M201 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_ACCELERATION { 9000, 9000, 100, 10000 } + +/** + * Default Acceleration (change/s) change = mm/s + * Override with M204 + * + * M204 P Acceleration + * M204 R Retract Acceleration + * M204 T Travel Acceleration + */ +#define DEFAULT_ACCELERATION 6000 // X, Y, Z and E acceleration for printing moves +#define DEFAULT_RETRACT_ACCELERATION 6000 // E acceleration for retracts +#define DEFAULT_TRAVEL_ACCELERATION 3000 // X, Y, Z acceleration for travel (non printing) moves + +/** + * Default Jerk (mm/s) + * Override with M205 X Y Z E + * + * "Jerk" specifies the minimum speed change that requires acceleration. + * When changing speed and direction, if the difference is less than the + * value set here, it may happen instantaneously. + */ +#define DEFAULT_XJERK 10.0 +#define DEFAULT_YJERK 10.0 +#define DEFAULT_ZJERK 0.5 +#define DEFAULT_EJERK 20.0 + +//=========================================================================== +//============================= Z Probe Options ============================= +//=========================================================================== +// @section probes + +// +// See http://marlinfw.org/configuration/probes.html +// + +/** + * Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + * + * Enable this option for a probe connected to the Z Min endstop pin. + */ +#define Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + +/** + * Z_MIN_PROBE_ENDSTOP + * + * Enable this option for a probe connected to any pin except Z-Min. + * (By default Marlin assumes the Z-Max endstop pin.) + * To use a custom Z Probe pin, set Z_MIN_PROBE_PIN below. + * + * - The simplest option is to use a free endstop connector. + * - Use 5V for powered (usually inductive) sensors. + * + * - RAMPS 1.3/1.4 boards may use the 5V, GND, and Aux4->D32 pin: + * - For simple switches connect... + * - normally-closed switches to GND and D32. + * - normally-open switches to 5V and D32. + * + * WARNING: Setting the wrong pin may have unexpected and potentially + * disastrous consequences. Use with caution and do your homework. + * + */ +//#define Z_MIN_PROBE_ENDSTOP + +/** + * Probe Type + * + * Allen Key Probes, Servo Probes, Z-Sled Probes, FIX_MOUNTED_PROBE, etc. + * Activate one of these to use Auto Bed Leveling below. + */ + +/** + * The "Manual Probe" provides a means to do "Auto" Bed Leveling without a probe. + * Use G29 repeatedly, adjusting the Z height at each point with movement commands + * or (with LCD_BED_LEVELING) the LCD controller. + */ +//#define PROBE_MANUALLY + +/** + * A Fix-Mounted Probe either doesn't deploy or needs manual deployment. + * (e.g., an inductive probe or a nozzle-based probe-switch.) + */ +//#define FIX_MOUNTED_PROBE + +/** + * Z Servo Probe, such as an endstop switch on a rotating arm. + */ +//#define Z_ENDSTOP_SERVO_NR 0 // Defaults to SERVO 0 connector. +//#define Z_SERVO_ANGLES {70,0} // Z Servo Deploy and Stow angles + +/** + * The BLTouch probe uses a Hall effect sensor and emulates a servo. + */ +//#define BLTOUCH +#if ENABLED(BLTOUCH) + //#define BLTOUCH_DELAY 375 // (ms) Enable and increase if needed +#endif + +/** + * Enable one or more of the following if probing seems unreliable. + * Heaters and/or fans can be disabled during probing to minimize electrical + * noise. A delay can also be added to allow noise and vibration to settle. + * These options are most useful for the BLTouch probe, but may also improve + * readings with inductive probes and piezo sensors. + */ +//#define PROBING_HEATERS_OFF // Turn heaters off when probing +//#define PROBING_FANS_OFF // Turn fans off when probing +//#define DELAY_BEFORE_PROBING 200 // (ms) To prevent vibrations from triggering piezo sensors + +// A probe that is deployed and stowed with a solenoid pin (SOL1_PIN) +//#define SOLENOID_PROBE + +// A sled-mounted probe like those designed by Charles Bell. +//#define Z_PROBE_SLED +//#define SLED_DOCKING_OFFSET 5 // The extra distance the X axis must travel to pickup the sled. 0 should be fine but you can push it further if you'd like. + +// +// For Z_PROBE_ALLEN_KEY see the Delta example configurations. +// + +/** + * Z Probe to nozzle (X,Y) offset, relative to (0, 0). + * X and Y offsets must be integers. + * + * In the following example the X and Y offsets are both positive: + * #define X_PROBE_OFFSET_FROM_EXTRUDER 10 + * #define Y_PROBE_OFFSET_FROM_EXTRUDER 10 + * + * +-- BACK ---+ + * | | + * L | (+) P | R <-- probe (20,20) + * E | | I + * F | (-) N (+) | G <-- nozzle (10,10) + * T | | H + * | (-) | T + * | | + * O-- FRONT --+ + * (0,0) + */ +#define X_PROBE_OFFSET_FROM_EXTRUDER 10 // X offset: -left +right [of the nozzle] +#define Y_PROBE_OFFSET_FROM_EXTRUDER 10 // Y offset: -front +behind [the nozzle] +#define Z_PROBE_OFFSET_FROM_EXTRUDER 0 // Z offset: -below +above [the nozzle] + +// X and Y axis travel speed (mm/m) between probes +#define XY_PROBE_SPEED 8000 + +// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +#define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z + +// Speed for the "accurate" probe of each point +#define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) + +// Use double touch for probing +//#define PROBE_DOUBLE_TOUCH + +/** + * Z probes require clearance when deploying, stowing, and moving between + * probe points to avoid hitting the bed and other hardware. + * Servo-mounted probes require extra space for the arm to rotate. + * Inductive probes need space to keep from triggering early. + * + * Use these settings to specify the distance (mm) to raise the probe (or + * lower the bed). The values set here apply over and above any (negative) + * probe Z Offset set with Z_PROBE_OFFSET_FROM_EXTRUDER, M851, or the LCD. + * Only integer values >= 1 are valid here. + * + * Example: `M851 Z-5` with a CLEARANCE of 4 => 9mm from bed to nozzle. + * But: `M851 Z+1` with a CLEARANCE of 2 => 2mm from bed to nozzle. + */ +#define Z_CLEARANCE_DEPLOY_PROBE 15 // Z Clearance for Deploy/Stow +#define Z_CLEARANCE_BETWEEN_PROBES 5 // Z Clearance between probe points + +// For M851 give a range for adjusting the Z probe offset +#define Z_PROBE_OFFSET_RANGE_MIN -20 +#define Z_PROBE_OFFSET_RANGE_MAX 20 + +// Enable the M48 repeatability test to test probe accuracy +//#define Z_MIN_PROBE_REPEATABILITY_TEST + +// For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1 +// :{ 0:'Low', 1:'High' } +#define X_ENABLE_ON 0 +#define Y_ENABLE_ON 0 +#define Z_ENABLE_ON 0 +#define E_ENABLE_ON 0 // For all extruders + +// Disables axis stepper immediately when it's not being used. +// 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 +//#define DISABLE_REDUCED_ACCURACY_WARNING + +// @section extruder + +#define DISABLE_E false // For all extruders +#define DISABLE_INACTIVE_EXTRUDER true // Keep only the active extruder enabled. + +// @section machine + +// Invert the stepper direction. Change (or reverse the motor connector) if an axis goes the wrong way. +#define INVERT_X_DIR false +#define INVERT_Y_DIR true +#define INVERT_Z_DIR true + +// Enable this option for Toshiba stepper drivers +//#define CONFIG_STEPPERS_TOSHIBA + +// @section extruder + +// For direct drive extruder v9 set to true, for geared extruder set to false. +#define INVERT_E0_DIR false +#define INVERT_E1_DIR true +#define INVERT_E2_DIR false +#define INVERT_E3_DIR false +#define INVERT_E4_DIR false + +// @section homing + +//#define NO_MOTION_BEFORE_HOMING // Inhibit movement until all axes have been homed + +//#define Z_HOMING_HEIGHT 4 // (in mm) Minimal z height before homing (G28) for Z clearance above the bed, clamps, ... + // Be sure you have this distance over your Z_MAX_POS in case. + +// Direction of endstops when homing; 1=MAX, -1=MIN +// :[-1,1] +#define X_HOME_DIR -1 +#define Y_HOME_DIR -1 +#define Z_HOME_DIR -1 + +// @section machine + +// The size of the print bed +#define X_BED_SIZE 200 +#define Y_BED_SIZE 200 + +// Travel limits (mm) after homing, corresponding to endstop positions. +#define X_MIN_POS 0 +#define Y_MIN_POS 20 +#define Z_MIN_POS 0 +#define X_MAX_POS X_BED_SIZE +#define Y_MAX_POS Y_BED_SIZE +#define Z_MAX_POS 190 + +// If enabled, axes won't move below MIN_POS in response to movement commands. +#define MIN_SOFTWARE_ENDSTOPS +// If enabled, axes won't move above MAX_POS in response to movement commands. +#define MAX_SOFTWARE_ENDSTOPS + +/** + * Filament Runout Sensor + * A mechanical or opto endstop is used to check for the presence of filament. + * + * RAMPS-based boards use SERVO3_PIN. + * For other boards you may need to define FIL_RUNOUT_PIN. + * By default the firmware assumes HIGH = has filament, LOW = ran out + */ +//#define FILAMENT_RUNOUT_SENSOR +#if ENABLED(FILAMENT_RUNOUT_SENSOR) + #define FIL_RUNOUT_INVERTING false // set to true to invert the logic of the sensor. + #define ENDSTOPPULLUP_FIL_RUNOUT // Uncomment to use internal pullup for filament runout pins if the sensor is defined. + #define FILAMENT_RUNOUT_SCRIPT "M600" +#endif + +//=========================================================================== +//=============================== Bed Leveling ============================== +//=========================================================================== +// @section bedlevel + +/** + * Choose one of the options below to enable G29 Bed Leveling. The parameters + * and behavior of G29 will change depending on your selection. + * + * If using a Probe for Z Homing, enable Z_SAFE_HOMING also! + * + * - AUTO_BED_LEVELING_3POINT + * Probe 3 arbitrary points on the bed (that aren't collinear) + * You specify the XY coordinates of all 3 points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_LINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_BILINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a mesh, best for large or uneven beds. + * + * - AUTO_BED_LEVELING_UBL (Unified Bed Leveling) + * A comprehensive bed leveling system combining the features and benefits + * of other systems. UBL also includes integrated Mesh Generation, Mesh + * Validation and Mesh Editing systems. Currently, UBL is only checked out + * for Cartesian Printers. That said, it was primarily designed to correct + * poor quality Delta Printers. If you feel adventurous and have a Delta, + * please post an issue if something doesn't work correctly. Initially, + * you will need to set a reduced bed size so you have a rectangular area + * to test on. + * + * - MESH_BED_LEVELING + * Probe a grid manually + * The result is a mesh, suitable for large or uneven beds. (See BILINEAR.) + * For machines without a probe, Mesh Bed Leveling provides a method to perform + * leveling in steps so you can manually adjust the Z height at each grid-point. + * With an LCD controller the process is guided step-by-step. + */ +//#define AUTO_BED_LEVELING_3POINT +//#define AUTO_BED_LEVELING_LINEAR +//#define AUTO_BED_LEVELING_BILINEAR +//#define AUTO_BED_LEVELING_UBL +//#define MESH_BED_LEVELING + +/** + * Enable detailed logging of G28, G29, M48, etc. + * Turn on with the command 'M111 S32'. + * NOTE: Requires a lot of PROGMEM! + */ +//#define DEBUG_LEVELING_FEATURE + +#if ENABLED(MESH_BED_LEVELING) || ENABLED(AUTO_BED_LEVELING_BILINEAR) || ENABLED(AUTO_BED_LEVELING_UBL) + // Gradually reduce leveling correction until a set height is reached, + // at which point movement will be level to the machine's XY plane. + // The height can be set with M420 Z + #define ENABLE_LEVELING_FADE_HEIGHT +#endif + +#if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Set the number of grid points per dimension. + #define GRID_MAX_POINTS_X 3 + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + // Set the boundaries for probing (where the probe can reach). + #define LEFT_PROBE_BED_POSITION 15 + #define RIGHT_PROBE_BED_POSITION 170 + #define FRONT_PROBE_BED_POSITION 20 + #define BACK_PROBE_BED_POSITION 170 + + // The Z probe minimum outer margin (to validate G29 parameters). + #define MIN_PROBE_EDGE 10 + + // Probe along the Y axis, advancing X after each column + //#define PROBE_Y_FIRST + + #if ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Beyond the probed grid, continue the implied tilt? + // Default is to maintain the height of the nearest edge. + //#define EXTRAPOLATE_BEYOND_GRID + + // + // Experimental Subdivision of the grid by Catmull-Rom method. + // Synthesizes intermediate points to produce a more detailed mesh. + // + //#define ABL_BILINEAR_SUBDIVISION + #if ENABLED(ABL_BILINEAR_SUBDIVISION) + // Number of subdivisions between probe points + #define BILINEAR_SUBDIVISIONS 3 + #endif + + #endif + +#elif ENABLED(AUTO_BED_LEVELING_3POINT) + + // 3 arbitrary points to probe. + // A simple cross-product is used to estimate the plane of the bed. + #define ABL_PROBE_PT_1_X 15 + #define ABL_PROBE_PT_1_Y 180 + #define ABL_PROBE_PT_2_X 15 + #define ABL_PROBE_PT_2_Y 20 + #define ABL_PROBE_PT_3_X 170 + #define ABL_PROBE_PT_3_Y 20 + +#elif ENABLED(AUTO_BED_LEVELING_UBL) + + //=========================================================================== + //========================= Unified Bed Leveling ============================ + //=========================================================================== + + #define UBL_MESH_INSET 1 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 10 // Don't use more than 15 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + #define UBL_PROBE_PT_1_X 39 // Probing points for 3-Point leveling of the mesh + #define UBL_PROBE_PT_1_Y 180 + #define UBL_PROBE_PT_2_X 39 + #define UBL_PROBE_PT_2_Y 20 + #define UBL_PROBE_PT_3_X 180 + #define UBL_PROBE_PT_3_Y 20 + + #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation + #define UBL_MESH_EDIT_MOVES_Z // Sophisticated users prefer no movement of nozzle + +#elif ENABLED(MESH_BED_LEVELING) + + //=========================================================================== + //=================================== Mesh ================================== + //=========================================================================== + + #define MESH_INSET 10 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 3 // Don't use more than 7 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + //#define MESH_G28_REST_ORIGIN // After homing all axes ('G28' or 'G28 XYZ') rest Z at Z_MIN_POS + +#endif // BED_LEVELING + +/** + * Use the LCD controller for bed leveling + * Requires MESH_BED_LEVELING or PROBE_MANUALLY + */ +//#define LCD_BED_LEVELING + +#if ENABLED(LCD_BED_LEVELING) + #define MBL_Z_STEP 0.025 // Step size while manually probing Z axis. + #define LCD_PROBE_Z_RANGE 4 // Z Range centered on Z_MIN_POS for LCD Z adjustment +#endif + +// Add a menu item to move between bed corners for manual bed adjustment +//#define LEVEL_BED_CORNERS + +/** + * Commands to execute at the end of G29 probing. + * Useful to retract or move the Z probe out of the way. + */ +//#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) +//#define BED_CENTER_AT_0_0 + +// Manually set the home position. Leave these undefined for automatic settings. +// For DELTA this is the top-center of the Cartesian print volume. +//#define MANUAL_X_HOME_POS 0 +//#define MANUAL_Y_HOME_POS 0 +//#define MANUAL_Z_HOME_POS 0 + +// Use "Z Safe Homing" to avoid homing with a Z probe outside the bed area. +// +// With this feature enabled: +// +// - 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). +// - 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 axis (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). +#endif + +// Homing speeds (mm/m) +#define HOMING_FEEDRATE_XY (50*60) +#define HOMING_FEEDRATE_Z (8*60) + +//============================================================================= +//============================= Additional Features =========================== +//============================================================================= + +// @section extras + +// +// EEPROM +// +// The microcontroller can store settings in the EEPROM, e.g. max velocity... +// M500 - stores parameters in EEPROM +// M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily). +// M502 - reverts to the default "factory settings". You still need to store them in EEPROM afterwards if you want to. +// +#define EEPROM_SETTINGS // Enable for M500 and M501 commands +//#define DISABLE_M503 // Saves ~2700 bytes of PROGMEM. Disable for release! +#define EEPROM_CHITCHAT // Give feedback on EEPROM commands. Disable to save PROGMEM. + +// +// Host Keepalive +// +// When enabled Marlin will send a busy status message to the host +// every couple of seconds when it can't accept commands. +// +#define HOST_KEEPALIVE_FEATURE // Disable this if your host doesn't like keepalive messages +#define DEFAULT_KEEPALIVE_INTERVAL 2 // Number of seconds between "busy" messages. Set with M113. +#define BUSY_WHILE_HEATING // Some hosts require "busy" messages even during heating + +// +// M100 Free Memory Watcher +// +//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose + +// +// G20/G21 Inch mode support +// +//#define INCH_MODE_SUPPORT + +// +// M149 Set temperature units support +// +//#define TEMPERATURE_UNITS_SUPPORT + +// @section temperature + +// Preheat Constants +#define PREHEAT_1_TEMP_HOTEND 210 +#define PREHEAT_1_TEMP_BED 0 +#define PREHEAT_1_FAN_SPEED 165 // Value from 0 to 255 + +#define PREHEAT_2_TEMP_HOTEND 245 +#define PREHEAT_2_TEMP_BED 0 +#define PREHEAT_2_FAN_SPEED 165 // Value from 0 to 255 + +/** + * Nozzle Park -- EXPERIMENTAL + * + * Park the nozzle at the given XYZ position on idle or G27. + * + * The "P" parameter controls the action applied to the Z axis: + * + * P0 (Default) If Z is below park Z raise the nozzle. + * P1 Raise the nozzle always to Z-park height. + * P2 Raise the nozzle by Z-park amount, limited to Z_MAX_POS. + */ +//#define NOZZLE_PARK_FEATURE + +#if ENABLED(NOZZLE_PARK_FEATURE) + // Specify a park position as { X, Y, Z } + #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 } +#endif + +/** + * Clean Nozzle Feature -- EXPERIMENTAL + * + * Adds the G12 command to perform a nozzle cleaning process. + * + * Parameters: + * P Pattern + * S Strokes / Repetitions + * T Triangles (P1 only) + * + * Patterns: + * P0 Straight line (default). This process requires a sponge type material + * at a fixed bed location. "S" specifies strokes (i.e. back-forth motions) + * between the start / end points. + * + * P1 Zig-zag pattern between (X0, Y0) and (X1, Y1), "T" specifies the + * number of zig-zag triangles to do. "S" defines the number of strokes. + * Zig-zags are done in whichever is the narrower dimension. + * For example, "G12 P1 S1 T3" will execute: + * + * -- + * | (X0, Y1) | /\ /\ /\ | (X1, Y1) + * | | / \ / \ / \ | + * A | | / \ / \ / \ | + * | | / \ / \ / \ | + * | (X0, Y0) | / \/ \/ \ | (X1, Y0) + * -- +--------------------------------+ + * |________|_________|_________| + * T1 T2 T3 + * + * P2 Circular pattern with middle at NOZZLE_CLEAN_CIRCLE_MIDDLE. + * "R" specifies the radius. "S" specifies the stroke count. + * Before starting, the nozzle moves to NOZZLE_CLEAN_START_POINT. + * + * Caveats: The ending Z should be the same as starting Z. + * Attention: EXPERIMENTAL. G-code arguments may change. + * + */ +//#define NOZZLE_CLEAN_FEATURE + +#if ENABLED(NOZZLE_CLEAN_FEATURE) + // Default number of pattern repetitions + #define NOZZLE_CLEAN_STROKES 12 + + // Default number of triangles + #define NOZZLE_CLEAN_TRIANGLES 3 + + // Specify positions as { X, Y, Z } + #define NOZZLE_CLEAN_START_POINT { 30, 30, (Z_MIN_POS + 1)} + #define NOZZLE_CLEAN_END_POINT {100, 60, (Z_MIN_POS + 1)} + + // Circular pattern radius + #define NOZZLE_CLEAN_CIRCLE_RADIUS 6.5 + // Circular pattern circle fragments number + #define NOZZLE_CLEAN_CIRCLE_FN 10 + // Middle point of circle + #define NOZZLE_CLEAN_CIRCLE_MIDDLE NOZZLE_CLEAN_START_POINT + + // Moves the nozzle to the initial position + #define NOZZLE_CLEAN_GOBACK +#endif + +/** + * Print Job Timer + * + * Automatically start and stop the print job timer on M104/M109/M190. + * + * M104 (hotend, no wait) - high temp = none, low temp = stop timer + * M109 (hotend, wait) - high temp = start timer, low temp = stop timer + * M190 (bed, wait) - high temp = start timer, low temp = none + * + * The timer can also be controlled with the following commands: + * + * M75 - Start the print job timer + * M76 - Pause the print job timer + * M77 - Stop the print job timer + */ +#define PRINTJOB_TIMER_AUTOSTART + +/** + * Print Counter + * + * Track statistical data such as: + * + * - Total print jobs + * - Total successful print jobs + * - Total failed print jobs + * - Total time printing + * + * View the current statistics with M78. + */ +//#define PRINTCOUNTER + +//============================================================================= +//============================= LCD and SD support ============================ +//============================================================================= + +// @section lcd + +/** + * LCD LANGUAGE + * + * Select the language to display on the LCD. These languages are available: + * + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, + * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * tr, uk, zh_CN, zh_TW, test + * + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + */ +#define LCD_LANGUAGE en + +/** + * LCD Character Set + * + * Note: This option is NOT applicable to Graphical Displays. + * + * All character-based LCDs provide ASCII plus one of these + * language extensions: + * + * - JAPANESE ... the most common + * - WESTERN ... with more accented characters + * - CYRILLIC ... for the Russian language + * + * To determine the language extension installed on your controller: + * + * - Compile and upload with LCD_LANGUAGE set to 'test' + * - 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 + * + * :['JAPANESE', 'WESTERN', 'CYRILLIC'] + */ +#define DISPLAY_CHARSET_HD44780 JAPANESE + +/** + * LCD TYPE + * + * Enable ULTRA_LCD for a 16x2, 16x4, 20x2, or 20x4 character-based LCD. + * Enable DOGLCD for a 128x64 (ST7565R) Full Graphical Display. + * (These options will be enabled automatically for most displays.) + * + * IMPORTANT: The U8glib library is required for Full Graphic Display! + * https://github.com/olikraus/U8glib_Arduino + */ +//#define ULTRA_LCD // Character based +//#define DOGLCD // Full graphics display + +/** + * SD CARD + * + * 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 + +/** + * SD CARD: SPI SPEED + * + * Enable one of the following items for a slower SPI transfer speed. + * This may be required to resolve "volume init" errors. + */ +//#define SPI_SPEED SPI_HALF_SPEED +//#define SPI_SPEED SPI_QUARTER_SPEED +//#define SPI_SPEED SPI_EIGHTH_SPEED + +/** + * SD CARD: ENABLE CRC + * + * Use CRC checks and retries on the SD communication. + */ +//#define SD_CHECK_AND_RETRY + +// +// ENCODER SETTINGS +// +// This option overrides the default number of encoder pulses needed to +// produce one step. Should be increased for high-resolution encoders. +// +#define ENCODER_PULSES_PER_STEP 4 + +// +// Use this option to override the number of step signals required to +// move between next/prev menu items. +// +#define ENCODER_STEPS_PER_MENU_ITEM 1 + +/** + * Encoder Direction Options + * + * Test your encoder's behavior first with both options disabled. + * + * Reversed Value Edit and Menu Nav? Enable REVERSE_ENCODER_DIRECTION. + * Reversed Menu Navigation only? Enable REVERSE_MENU_DIRECTION. + * Reversed Value Editing only? Enable BOTH options. + */ + +// +// This option reverses the encoder direction everywhere. +// +// Set this option if CLOCKWISE causes values to DECREASE +// +//#define REVERSE_ENCODER_DIRECTION + +// +// This option reverses the encoder direction for navigating LCD menus. +// +// If CLOCKWISE normally moves DOWN this makes it go UP. +// If CLOCKWISE normally moves UP this makes it go DOWN. +// +#define REVERSE_MENU_DIRECTION + +// +// Individual Axis Homing +// +// Add individual axis homing items (Home X, Home Y, and Home Z) to the LCD menu. +// +//#define INDIVIDUAL_AXIS_HOMING_MENU + +// +// SPEAKER/BUZZER +// +// If you have a speaker that can produce tones, enable it here. +// By default Marlin assumes you have a buzzer with a fixed frequency. +// +//#define SPEAKER + +// +// The duration and frequency for the UI feedback sound. +// Set these to 0 to disable audio feedback in the LCD menus. +// +// Note: Test audio output with the G-Code: +// M300 S P +// +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 +//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 + +// +// CONTROLLER TYPE: Standard +// +// Marlin supports a wide variety of controllers. +// Enable one of the following options to specify your controller. +// + +// +// ULTIMAKER Controller. +// +#define ULTIMAKERCONTROLLER + +// +// ULTIPANEL as seen on Thingiverse. +// +//#define ULTIPANEL + +// +// PanelOne from T3P3 (via RAMPS 1.4 AUX2/AUX3) +// http://reprap.org/wiki/PanelOne +// +//#define PANEL_ONE + +// +// MaKr3d Makr-Panel with graphic controller and SD support. +// http://reprap.org/wiki/MaKr3d_MaKrPanel +// +//#define MAKRPANEL + +// +// ReprapWorld Graphical LCD +// https://reprapworld.com/?products_details&products_id/1218 +// +//#define REPRAPWORLD_GRAPHICAL_LCD + +// +// Activate one of these if you have a Panucatt Devices +// Viki 2.0 or mini Viki with Graphic LCD +// http://panucatt.com +// +//#define VIKI2 +//#define miniVIKI + +// +// Adafruit ST7565 Full Graphic Controller. +// https://github.com/eboston/Adafruit-ST7565-Full-Graphic-Controller/ +// +//#define ELB_FULL_GRAPHIC_CONTROLLER + +// +// RepRapDiscount Smart Controller. +// http://reprap.org/wiki/RepRapDiscount_Smart_Controller +// +// Note: Usually sold with a white PCB. +// +//#define REPRAP_DISCOUNT_SMART_CONTROLLER + +// +// GADGETS3D G3D LCD/SD Controller +// http://reprap.org/wiki/RAMPS_1.3/1.4_GADGETS3D_Shield_with_Panel +// +// Note: Usually sold with a blue PCB. +// +//#define G3D_PANEL + +// +// RepRapDiscount FULL GRAPHIC Smart Controller +// http://reprap.org/wiki/RepRapDiscount_Full_Graphic_Smart_Controller +// +//#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER + +// +// MakerLab Mini Panel with graphic +// controller and SD support - http://reprap.org/wiki/Mini_panel +// +//#define MINIPANEL + +// +// RepRapWorld REPRAPWORLD_KEYPAD v1.1 +// http://reprapworld.com/?products_details&products_id=202&cPath=1591_1626 +// +// REPRAPWORLD_KEYPAD_MOVE_STEP sets how much should the robot move when a key +// is pressed, a value of 10.0 means 10mm per click. +// +//#define REPRAPWORLD_KEYPAD +//#define REPRAPWORLD_KEYPAD_MOVE_STEP 10.0 + +// +// RigidBot Panel V1.0 +// http://www.inventapart.com/ +// +//#define RIGIDBOT_PANEL + +// +// BQ LCD Smart Controller shipped by +// default with the BQ Hephestos 2 and Witbox 2. +// +//#define BQ_LCD_SMART_CONTROLLER + +// +// Cartesio UI +// http://mauk.cc/webshop/cartesio-shop/electronics/user-interface +// +//#define CARTESIO_UI + +// +// ANET_10 Controller supported displays. +// +//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. + // This LCD is known to be susceptible to electrical interference + // which scrambles the display. Pressing any button clears it up. +//#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 + // A clone of the RepRapDiscount full graphics display but with + // different pins/wiring (see pins_ANET_10.h). + +// +// LCD for Melzi Card with Graphical LCD +// +//#define LCD_FOR_MELZI + +// +// CONTROLLER TYPE: I2C +// +// Note: These controllers require the installation of Arduino's LiquidCrystal_I2C +// library. For more info: https://github.com/kiyoshigawa/LiquidCrystal_I2C +// + +// +// Elefu RA Board Control Panel +// http://www.elefu.com/index.php?route=product/product&product_id=53 +// +//#define RA_CONTROL_PANEL + +// +// Sainsmart YW Robot (LCM1602) LCD Display +// +// Note: This controller requires F.Malpartida's LiquidCrystal_I2C library +// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home +// +//#define LCD_I2C_SAINSMART_YWROBOT + +// +// Generic LCM1602 LCD adapter +// +//#define LCM1602 + +// +// PANELOLU2 LCD with status LEDs, +// separate encoder and click inputs. +// +// Note: This controller requires Arduino's LiquidTWI2 library v1.2.3 or later. +// For more info: https://github.com/lincomatic/LiquidTWI2 +// +// Note: The PANELOLU2 encoder click input can either be directly connected to +// a pin (if BTN_ENC defined to != -1) or read through I2C (when BTN_ENC == -1). +// +//#define LCD_I2C_PANELOLU2 + +// +// Panucatt VIKI LCD with status LEDs, +// integrated click & L/R/U/D buttons, separate encoder inputs. +// +//#define LCD_I2C_VIKI + +// +// SSD1306 OLED full graphics generic display +// +//#define U8GLIB_SSD1306 + +// +// SAV OLEd LCD module support using either SSD1306 or SH1106 based LCD modules +// +//#define SAV_3DGLCD +#if ENABLED(SAV_3DGLCD) + //#define U8GLIB_SSD1306 + #define U8GLIB_SH1106 +#endif + +// +// CONTROLLER TYPE: Shift register panels +// +// 2 wire Non-latching LCD SR from https://goo.gl/aJJ4sH +// LCD configuration: http://reprap.org/wiki/SAV_3D_LCD +// +//#define SAV_3DLCD + +// +// TinyBoy2 128x64 OLED / Encoder Panel +// +//#define OLED_PANEL_TINYBOY2 + +// +// Makeboard 3D Printer Parts 3D Printer Mini Display 1602 Mini Controller +// https://www.aliexpress.com/item/Micromake-Makeboard-3D-Printer-Parts-3D-Printer-Mini-Display-1602-Mini-Controller-Compatible-with-Ramps-1/32765887917.html +// +//#define MAKEBOARD_MINI_2_LINE_DISPLAY_1602 + +// +// MKS MINI12864 with graphic controller and SD support +// http://reprap.org/wiki/MKS_MINI_12864 +// +//#define MKS_MINI_12864 + +// +// Factory display for Creality CR-10 +// https://www.aliexpress.com/item/Universal-LCD-12864-3D-Printer-Display-Screen-With-Encoder-For-CR-10-CR-7-Model/32833148327.html +// +// This is RAMPS-compatible using a single 10-pin connector. +// (For CR-10 owners who want to replace the Melzi Creality board but retain the display) +// +//#define CR10_STOCKDISPLAY + +// +// MKS OLED 1.3" 128 × 64 FULL GRAPHICS CONTROLLER +// http://reprap.org/wiki/MKS_12864OLED +// +// Tiny, but very sharp OLED display +// +//#define MKS_12864OLED + +//============================================================================= +//=============================== Extra Features ============================== +//============================================================================= + +// @section extras + +// Increase the FAN PWM frequency. Removes the PWM noise but increases heating in the FET/Arduino +//#define FAST_PWM_FAN + +// Use software PWM to drive the fan, as for the heaters. This uses a very low frequency +// which is not as annoying as with the hardware PWM. On the other hand, if this frequency +// is too low, you should also increment SOFT_PWM_SCALE. +//#define FAN_SOFT_PWM + +// Incrementing this by 1 will double the software PWM frequency, +// affecting heaters, and the fan if FAN_SOFT_PWM is enabled. +// However, control resolution will be halved for each increment; +// at zero value, there are 128 effective control positions. +#define SOFT_PWM_SCALE 0 + +// If SOFT_PWM_SCALE is set to a value higher than 0, dithering can +// be used to mitigate the associated resolution loss. If enabled, +// some of the PWM cycles are stretched so on average the desired +// duty cycle is attained. +//#define SOFT_PWM_DITHER + +// Temperature status LEDs that display the hotend and bed temperature. +// If all hotends, bed temperature, and target temperature are under 54C +// then the BLUE led is on. Otherwise the RED led is on. (1C hysteresis) +//#define TEMP_STAT_LEDS + +// M240 Triggers a camera by emulating a Canon RC-1 Remote +// Data from: http://www.doc-diy.net/photo/rc-1_hacked/ +//#define PHOTOGRAPH_PIN 23 + +// 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 + +// Support for BlinkM/CyzRgb +//#define BLINKM + +// Support for PCA9632 PWM LED driver +//#define PCA9632 + +/** + * RGB LED / LED Strip Control + * + * Enable support for an RGB LED connected to 5V digital pins, or + * an RGB Strip connected to MOSFETs controlled by digital pins. + * + * 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 overall brightness parameters is also available + * + * *** CAUTION *** + * LED Strips require a MOFSET 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! + * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino + * cannot handle such current, separate 5V power supply must be used + * *** CAUTION *** + * + * LED type. This options are mutualy exclusive. Uncomment only one. + * + */ +//#define RGB_LED +//#define RGBW_LED + +#if ENABLED(RGB_LED) || ENABLED(RGBW_LED) + #define RGB_LED_R_PIN 34 + #define RGB_LED_G_PIN 43 + #define RGB_LED_B_PIN 35 + #define RGB_LED_W_PIN -1 +#endif + +// 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 (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) + #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip + #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time + #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + //#define NEOPIXEL_STARTUP_TEST // Cycle through colors at startup +#endif + +/** + * Printer Event LEDs + * + * During printing, the LEDs will reflect the printer status: + * + * - Gradually change from blue to violet as the heated bed gets to target temp + * - Gradually change from violet to red as the hotend gets to temperature + * - Change to white to illuminate work surface + * - Change to green once print has finished + * - Turn off after the print has finished and the user has pushed a button + */ +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) + #define PRINTER_EVENT_LEDS +#endif + +/*********************************************************************\ +* R/C SERVO support +* Sponsored by TrinityLabs, Reworked by codexmas +**********************************************************************/ + +// Number of servos +// +// If you select a configuration below, this will receive a default value and does not need to be set manually +// set it manually if you have more servos than extruders and wish to manually control some +// leaving it undefined or defining as 0 will disable the servo subsystem +// If unsure, leave commented / disabled +// +//#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command + +// Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. +// 300ms is a good value but you can try less delay. +// If the servo can't reach the requested position, increase it. +#define SERVO_DELAY { 300 } + +// Servo deactivation +// +// With this option servos are powered only during movement, then turned off to prevent jitter. +//#define DEACTIVATE_SERVOS_AFTER_MOVE + +/** + * Filament Width Sensor + * + * Measures the filament width in real-time and adjusts + * flow rate to compensate for any irregularities. + * + * Also allows the measured filament diameter to set the + * extrusion rate, so the slicer only has to specify the + * volume. + * + * Only a single extruder is supported at this time. + * + * 34 RAMPS_14 : Analog input 5 on the AUX2 connector + * 81 PRINTRBOARD : Analog input 2 on the Exp1 connector (version B,C,D,E) + * 301 RAMBO : Analog input 3 + * + * Note: May require analog pins to be defined for other boards. + */ +//#define FILAMENT_WIDTH_SENSOR + +#define DEFAULT_NOMINAL_FILAMENT_DIA 3.00 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. + +#if ENABLED(FILAMENT_WIDTH_SENSOR) + #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) + #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber + + #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading + #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading + #define MAX_MEASUREMENT_DELAY 20 // (bytes) Buffer size for stored measurements (1 byte per cm). Must be larger than MEASUREMENT_DELAY_CM. + + #define DEFAULT_MEASURED_FILAMENT_DIA DEFAULT_NOMINAL_FILAMENT_DIA // Set measured to nominal initially + + // Display filament width on the LCD status line. Status messages will expire after 5 seconds. + //#define FILAMENT_LCD_DISPLAY +#endif + +#endif // CONFIGURATION_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/Velleman/K8400/Configuration_adv.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/Velleman/K8400/Configuration_adv.h new file mode 100644 index 00000000..b3cfc51b --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/Velleman/K8400/Configuration_adv.h @@ -0,0 +1,1424 @@ +/** + * 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 . + * + */ + +/** + * Configuration_adv.h + * + * Advanced settings. + * Only change these if you know exactly what you're doing. + * Some of these settings can damage your printer if improperly set! + * + * Basic settings can be found in Configuration.h + * + */ +#ifndef CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H_VERSION 010100 + +// @section temperature + +//=========================================================================== +//=============================Thermal Settings ============================ +//=========================================================================== + +#if DISABLED(PIDTEMPBED) + #define BED_CHECK_INTERVAL 1000 // ms between checks in bang-bang control + #if ENABLED(BED_LIMIT_SWITCHING) + #define BED_HYSTERESIS 1 // Only disable heating if T>target+BED_HYSTERESIS and enable heating if T>target-BED_HYSTERESIS + #endif +#endif + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * The solution: Once the temperature reaches the target, start observing. + * If the temperature stays too far below the target (hysteresis) for too long (period), + * the firmware will halt the machine as a safety precaution. + * + * If you get false positives for "Thermal Runaway" increase THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD + */ +#if ENABLED(THERMAL_PROTECTION_HOTENDS) + #define THERMAL_PROTECTION_PERIOD 40 // Seconds + #define THERMAL_PROTECTION_HYSTERESIS 4 // Degrees Celsius + + /** + * Whenever an M104 or M109 increases the target temperature the firmware will wait for the + * WATCH_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get false positives for "Heating failed" increase WATCH_TEMP_PERIOD and/or decrease WATCH_TEMP_INCREASE + * WATCH_TEMP_INCREASE should not be below 2. + */ + #define WATCH_TEMP_PERIOD 20 // Seconds + #define WATCH_TEMP_INCREASE 2 // Degrees Celsius +#endif + +/** + * Thermal Protection parameters for the bed are just as above for hotends. + */ +#if ENABLED(THERMAL_PROTECTION_BED) + #define THERMAL_PROTECTION_BED_PERIOD 20 // Seconds + #define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius + + /** + * Whenever an M140 or M190 increases the target temperature the firmware will wait for the + * WATCH_BED_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_BED_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get too many "Heating failed" errors, increase WATCH_BED_TEMP_PERIOD and/or decrease + * WATCH_BED_TEMP_INCREASE. (WATCH_BED_TEMP_INCREASE should not be below 2.) + */ + #define WATCH_BED_TEMP_PERIOD 60 // Seconds + #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius +#endif + +#if ENABLED(PIDTEMP) + // this adds an experimental additional term to the heating power, proportional to the extrusion speed. + // if Kc is chosen well, the additional required power due to increased melting should be compensated. + //#define PID_EXTRUSION_SCALING + #if ENABLED(PID_EXTRUSION_SCALING) + #define DEFAULT_Kc (100) //heating power=Kc*(e_speed) + #define LPQ_MAX_LEN 50 + #endif +#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 + */ +#define AUTOTEMP +#if ENABLED(AUTOTEMP) + #define AUTOTEMP_OLDWEIGHT 0.98 +#endif + +// Show Temperature ADC value +// Enable for M105 to include ADC values read from temperature sensors. +//#define SHOW_TEMP_ADC_VALUES + +/** + * High Temperature Thermistor Support + * + * Thermistors able to support high temperature tend to have a hard time getting + * good readings at room and lower temperatures. This means HEATER_X_RAW_LO_TEMP + * will probably be caught when the heating element first turns on during the + * preheating process, which will trigger a min_temp_error as a safety measure + * and force stop everything. + * To circumvent this limitation, we allow for a preheat time (during which, + * min_temp_error won't be triggered) and add a min_temp buffer to handle + * aberrant readings. + * + * If you want to enable this feature for your hotend thermistor(s) + * uncomment and set values > 0 in the constants below + */ + +// The number of consecutive low temperature errors that can occur +// before a min_temp_error is triggered. (Shouldn't be more than 10.) +//#define MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED 0 + +// The number of milliseconds a hotend will preheat before starting to check +// the temperature. This value should NOT be set to the time it takes the +// hot end to reach the target temperature, but the time it takes to reach +// the minimum temperature your thermistor can read. The lower the better/safer. +// This shouldn't need to be more than 30 seconds (30000) +//#define MILLISECONDS_PREHEAT_TIME 0 + +// @section extruder + +// Extruder runout prevention. +// If the machine is idle and the temperature over MINTEMP +// then extrude some filament every couple of SECONDS. +//#define EXTRUDER_RUNOUT_PREVENT +#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_EXTRUDE 5 // mm +#endif + +// @section temperature + +//These defines help to calibrate the AD595 sensor in case you get wrong temperature measurements. +//The measured temperature is defined as "actualTemp = (measuredTemp * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET" +#define TEMP_SENSOR_AD595_OFFSET 0.0 +#define TEMP_SENSOR_AD595_GAIN 1.0 + +/** + * 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. + */ +#define USE_CONTROLLER_FAN +#if ENABLED(USE_CONTROLLER_FAN) + #define CONTROLLER_FAN_PIN 2 // 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 +#endif + +// When first starting the main fan, run it at full speed for the +// given number of milliseconds. This gets the fan spinning reliably +// before setting a PWM value. (Does not work with software PWM for fan on Sanguinololu) +//#define FAN_KICKSTART_TIME 100 + +// This defines the minimal speed for the main fan, run in PWM mode +// to enable uncomment and set minimal PWM speed for reliable running (1-255) +// if fan speed is [1 - (FAN_MIN_PWM-1)] it is set to FAN_MIN_PWM +//#define FAN_MIN_PWM 50 + +// @section extruder + +/** + * Extruder cooling fans + * + * Extruder auto fans automatically turn on when their extruders' + * temperatures go above EXTRUDER_AUTO_FAN_TEMPERATURE. + * + * Your board's pins file specifies the recommended pins. Override those here + * or set to -1 to disable completely. + * + * Multiple extruders can be assigned to the same pin in which case + * the fan will turn on when any selected extruder is above the threshold. + */ +#define E0_AUTO_FAN_PIN -1 +#define E1_AUTO_FAN_PIN -1 +#define E2_AUTO_FAN_PIN -1 +#define E3_AUTO_FAN_PIN -1 +#define E4_AUTO_FAN_PIN -1 +#define EXTRUDER_AUTO_FAN_TEMPERATURE 50 +#define EXTRUDER_AUTO_FAN_SPEED 255 // == full speed + +/** + * Part-Cooling Fan Multiplexer + * + * This feature allows you to digitally multiplex the fan output. + * The multiplexer is automatically switched at tool-change. + * Set FANMUX[012]_PINs below for up to 2, 4, or 8 multiplexed fans. + */ +#define FANMUX0_PIN -1 +#define FANMUX1_PIN -1 +#define FANMUX2_PIN -1 + +/** + * M355 Case Light on-off / brightness + */ +//#define CASE_LIGHT_ENABLE +#if ENABLED(CASE_LIGHT_ENABLE) + //#define CASE_LIGHT_PIN 4 // Override the default pin if needed + #define INVERT_CASE_LIGHT false // Set true if Case Light is ON when pin is LOW + #define CASE_LIGHT_DEFAULT_ON true // Set default power-up state on + #define CASE_LIGHT_DEFAULT_BRIGHTNESS 105 // Set default power-up brightness (0-255, requires PWM pin) + //#define MENU_ITEM_CASE_LIGHT // Add a Case Light option to the LCD main menu +#endif + +//=========================================================================== +//============================ Mechanical Settings ========================== +//=========================================================================== + +// @section homing + +// If you want endstops to stay on (by default) even when not homing +// enable this option. Override at any time with M120, M121. +//#define ENDSTOPS_ALWAYS_ON_DEFAULT + +// @section extras + +//#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. + +// Dual X Steppers +// Uncomment this option to drive two X axis motors. +// The next unused E driver will be assigned to the second X stepper. +//#define X_DUAL_STEPPER_DRIVERS +#if ENABLED(X_DUAL_STEPPER_DRIVERS) + // Set true if the two X motors need to rotate in opposite directions + #define INVERT_X2_VS_X_DIR true +#endif + +// Dual Y Steppers +// Uncomment this option to drive two Y axis motors. +// The next unused E driver will be assigned to the second Y stepper. +//#define Y_DUAL_STEPPER_DRIVERS +#if ENABLED(Y_DUAL_STEPPER_DRIVERS) + // Set true if the two Y motors need to rotate in opposite directions + #define INVERT_Y2_VS_Y_DIR true +#endif + +// A single Z stepper driver is usually used to drive 2 stepper motors. +// Uncomment this option to use a separate stepper driver for each Z axis motor. +// The next unused E driver will be assigned to the second Z stepper. +//#define Z_DUAL_STEPPER_DRIVERS + +#if ENABLED(Z_DUAL_STEPPER_DRIVERS) + + // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper. + // That way the machine is capable to align the bed during home, since both Z steppers are homed. + // There is also an implementation of M666 (software endstops adjustment) to this feature. + // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed. + // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2. + // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive. + // Play a little bit with small adjustments (0.5mm) and check the behaviour. + // The M119 (endstops report) will start reporting the Z2 Endstop as well. + + //#define Z_DUAL_ENDSTOPS + + #if ENABLED(Z_DUAL_ENDSTOPS) + #define Z2_USE_ENDSTOP _XMAX_ + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 // Use M666 to determine/test this value + #endif + +#endif // Z_DUAL_STEPPER_DRIVERS + +// Enable this for dual x-carriage printers. +// A dual x-carriage design has the advantage that the inactive extruder can be parked which +// prevents hot-end ooze contaminating the print. It also reduces the weight of each x-carriage +// allowing faster printing speeds. Connect your X2 stepper to the first unused E plug. +//#define DUAL_X_CARRIAGE +#if ENABLED(DUAL_X_CARRIAGE) + // Configuration for second X-carriage + // Note: the first x-carriage is defined as the x-carriage which homes to the minimum endstop; + // the second x-carriage always homes to the maximum endstop. + #define X2_MIN_POS 80 // set minimum to ensure second x-carriage doesn't hit the parked first X-carriage + #define X2_MAX_POS 353 // set maximum to the distance between toolheads when both heads are homed + #define X2_HOME_DIR 1 // the second X-carriage always homes to the maximum endstop position + #define X2_HOME_POS X2_MAX_POS // default home position is the maximum carriage position + // However: In this mode the HOTEND_OFFSET_X value for the second extruder provides a software + // override for X2_HOME_POS. This also allow recalibration of the distance between the two endstops + // without modifying the firmware (through the "M218 T1 X???" command). + // Remember: you should set the second extruder x-offset to 0 in your slicer. + + // There are a few selectable movement modes for dual x-carriages using M605 S + // Mode 0 (DXC_FULL_CONTROL_MODE): Full control. The slicer has full control over both x-carriages and can achieve optimal travel results + // as long as it supports dual x-carriages. (M605 S0) + // Mode 1 (DXC_AUTO_PARK_MODE) : Auto-park mode. The firmware will automatically park and unpark the x-carriages on tool changes so + // that additional slicer support is not required. (M605 S1) + // Mode 2 (DXC_DUPLICATION_MODE) : Duplication mode. The firmware will transparently make the second x-carriage and extruder copy all + // actions of the first x-carriage. This allows the printer to print 2 arbitrary items at + // once. (2nd extruder x offset and temp offset are set using: M605 S2 [Xnnn] [Rmmm]) + + // This is the default power-up mode which can be later using M605. + #define DEFAULT_DUAL_X_CARRIAGE_MODE DXC_FULL_CONTROL_MODE + + // Default settings in "Auto-park Mode" + #define TOOLCHANGE_PARK_ZLIFT 0.2 // the distance to raise Z axis when parking an extruder + #define TOOLCHANGE_UNPARK_ZLIFT 1 // the distance to raise Z axis when unparking an extruder + + // Default x offset in duplication mode (typically set to half print bed width) + #define DEFAULT_DUPLICATION_X_OFFSET 100 + +#endif // DUAL_X_CARRIAGE + +// 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. +//#define EXT_SOLENOID + +// @section homing + +//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +#define X_HOME_BUMP_MM 10 +#define Y_HOME_BUMP_MM 10 +#define Z_HOME_BUMP_MM 3 +#define HOMING_BUMP_DIVISOR {2, 2, 4} // Re-Bump Speed Divisor (Divides the Homing Feedrate) +#define QUICK_HOME //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially. + +// When G28 is called, this option will make Y home before X +//#define HOME_Y_BEFORE_X + +// @section machine + +#define AXIS_RELATIVE_MODES {false, false, false, false} + +// Allow duplication mode with a basic dual-nozzle extruder +//#define DUAL_NOZZLE_DUPLICATION_MODE + +// By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step. +#define INVERT_X_STEP_PIN false +#define INVERT_Y_STEP_PIN false +#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. +#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_E true + +#define DEFAULT_MINIMUMFEEDRATE 0.0 // minimum feedrate +#define DEFAULT_MINTRAVELFEEDRATE 0.0 + +//#define HOME_AFTER_DEACTIVATE // Require rehoming after steppers are deactivated + +// @section lcd + +#if ENABLED(ULTIPANEL) + #define MANUAL_FEEDRATE {50*60, 50*60, 4*60, 60} // Feedrates for manual moves along X, Y, Z, E from panel + #define ULTIPANEL_FEEDMULTIPLY // Comment to disable setting feedrate multiplier via encoder +#endif + +// @section extras + +// minimum time in microseconds that a movement needs to take if the buffer is emptied. +#define DEFAULT_MINSEGMENTTIME 20000 + +// If defined the movements slow down when the look ahead buffer is only half full +#define SLOWDOWN + +// Frequency limit +// See nophead's blog for more info +// Not working O +//#define XY_FREQUENCY_LIMIT 15 + +// 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 +// if unwanted behavior is observed on a user's machine when running at very slow speeds. +#define MINIMUM_PLANNER_SPEED 0.05 // (mm/sec) + +// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU. +#define MICROSTEP_MODES {16,16,16,16,16} // [1,2,4,8,16] + +/** + * @section stepper motor current + * + * Some boards have a means of setting the stepper motor current via firmware. + * + * The power on motor currents are set by: + * PWM_MOTOR_CURRENT - used by MINIRAMBO & ULTIMAIN_2 + * known compatible chips: A4982 + * DIGIPOT_MOTOR_CURRENT - used by BQ_ZUM_MEGA_3D, RAMBO & SCOOVO_X9H + * known compatible chips: AD5206 + * DAC_MOTOR_CURRENT_DEFAULT - used by PRINTRBOARD_REVF & RIGIDBOARD_V2 + * known compatible chips: MCP4728 + * DIGIPOT_I2C_MOTOR_CURRENTS - used by 5DPRINT, AZTEEG_X3_PRO, MIGHTYBOARD_REVE + * known compatible chips: MCP4451, MCP4018 + * + * Motor currents can also be set by M907 - M910 and by the LCD. + * M907 - applies to all. + * M908 - BQ_ZUM_MEGA_3D, RAMBO, PRINTRBOARD_REVF, RIGIDBOARD_V2 & SCOOVO_X9H + * M909, M910 & LCD - only PRINTRBOARD_REVF & RIGIDBOARD_V2 + */ +//#define PWM_MOTOR_CURRENT { 1300, 1300, 1250 } // Values in milliamps +//#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 + +// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +//#define DIGIPOT_I2C +//#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster +#define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 +// Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS +#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=========================== +//=========================================================================== + +#define ENCODER_RATE_MULTIPLIER // If defined, certain menu edit operations automatically multiply the steps when the encoder is moved quickly +#define ENCODER_10X_STEPS_PER_SEC 75 // If the encoder steps per sec exceeds this value, multiply steps moved x10 to quickly advance the value +#define ENCODER_100X_STEPS_PER_SEC 160 // If the encoder steps per sec exceeds this value, multiply steps moved x100 to really quickly advance the value + +//#define CHDK 4 //Pin for triggering CHDK to take a picture see how to use it here http://captain-slow.dk/2014/03/09/3d-printing-timelapses/ +#define CHDK_DELAY 50 //How long in ms the pin should stay HIGH before going LOW again + +// @section lcd + +// Include a page of printer information in the LCD Main Menu +//#define LCD_INFO_MENU + +// Scroll a longer status message into view +//#define STATUS_MESSAGE_SCROLLING + +// On the Info Screen, display XY with one decimal place when possible +//#define LCD_DECIMAL_SMALL_XY + +// The timeout (in ms) to return to the status screen from sub-menus +//#define LCD_TIMEOUT_TO_STATUS 15000 + +#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 + + #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? + #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. + + #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. + // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. + // using: + //#define MENU_ADDAUTOSTART + + /** + * Sort SD file listings in alphabetical order. + * + * With this option enabled, items on SD cards will be sorted + * by name for easier navigation. + * + * By default... + * + * - Use the slowest -but safest- method for sorting. + * - Folders are sorted to the top. + * - The sort key is statically allocated. + * - No added G-code (M34) support. + * - 40 item sorting limit. (Items after the first 40 are unsorted.) + * + * SD sorting uses static allocation (as set by SDSORT_LIMIT), allowing the + * compiler to calculate the worst-case usage and throw an error if the SRAM + * limit is exceeded. + * + * - SDSORT_USES_RAM provides faster sorting via a static directory buffer. + * - SDSORT_USES_STACK does the same, but uses a local stack-based buffer. + * - SDSORT_CACHE_NAMES will retain the sorted file listing in RAM. (Expensive!) + * - SDSORT_DYNAMIC_RAM only uses RAM when the SD menu is visible. (Use with caution!) + */ + //#define SDCARD_SORT_ALPHA + + // SD Card Sorting options + #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_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. + #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #endif + + // Show a progress bar on HD44780 LCDs for SD printing + //#define LCD_PROGRESS_BAR + + #if ENABLED(LCD_PROGRESS_BAR) + // Amount of time (ms) to show the bar + #define PROGRESS_BAR_BAR_TIME 2000 + // Amount of time (ms) to show the status message + #define PROGRESS_BAR_MSG_TIME 3000 + // Amount of time (ms) to retain the status message (0=forever) + #define PROGRESS_MSG_EXPIRE 0 + // Enable this to show messages for MSG_TIME then hide them + //#define PROGRESS_MSG_ONCE + // Add a menu item to test the progress bar: + //#define LCD_PROGRESS_BAR_TEST + #endif + + // This allows hosts to request long names for files and folders with M33 + //#define LONG_FILENAME_HOST_SUPPORT + + // This option allows you to abort SD printing when any endstop is triggered. + // This feature must be enabled with "M540 S1" or from the LCD menu. + // To have any effect, endstops must be enabled during SD printing. + //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + +#endif // SDSUPPORT + +/** + * Additional options for Graphical Displays + * + * Use the optimizations here to improve printing performance, + * which can be adversely affected by graphical display drawing, + * especially when doing several short moves, and when printing + * on DELTA and SCARA machines. + * + * Some of these options may result in the display lagging behind + * controller events, as there is a trade-off between reliable + * printing performance versus fast display updates. + */ +#if ENABLED(DOGLCD) + // Enable to save many cycles by drawing a hollow frame on the Info Screen + #define XYZ_HOLLOW_FRAME + + // Enable to save many cycles by drawing a hollow frame on Menu Screens + #define MENU_HOLLOW_FRAME + + // A bigger font is available for edit items. Costs 3120 bytes of PROGMEM. + // 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. + // 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 +#endif // DOGLCD + +// @section safety + +// The hardware watchdog should reset the microcontroller disabling all outputs, +// in case the firmware gets stuck and doesn't do temperature regulation. +#define USE_WATCHDOG + +#if ENABLED(USE_WATCHDOG) + // If you have a watchdog reboot in an ArduinoMega2560 then the device will hang forever, as a watchdog reset will leave the watchdog on. + // The "WATCHDOG_RESET_MANUAL" goes around this by not using the hardware reset. + // However, THIS FEATURE IS UNSAFE!, as it will only work if interrupts are disabled. And the code could hang in an interrupt routine with interrupts disabled. + //#define WATCHDOG_RESET_MANUAL +#endif + +// @section lcd + +/** + * Babystepping enables movement of the axes by tiny increments without changing + * the current position values. This feature is used primarily to adjust the Z + * axis in the first layer of a print in real-time. + * + * Warning: Does not respect endstops! + */ +//#define BABYSTEPPING +#if ENABLED(BABYSTEPPING) + //#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 100 // Babysteps are very small. Increase for faster motion. + //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping + //#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen 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_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor + //#define BABYSTEP_ZPROBE_GFX_REVERSE // Reverses the direction of the CW/CCW indicators +#endif + +// @section extruder + +/** + * Implementation of linear pressure control + * + * Assumption: advance = k * (delta velocity) + * K=0 means advance disabled. + * See Marlin documentation for calibration instructions. + */ +//#define LIN_ADVANCE + +#if ENABLED(LIN_ADVANCE) + #define LIN_ADVANCE_K 75 + + /** + * Some Slicers produce Gcode with randomly jumping extrusion widths occasionally. + * For example within a 0.4mm perimeter it may produce a single segment of 0.05mm width. + * While this is harmless for normal printing (the fluid nature of the filament will + * close this very, very tiny gap), it throws off the LIN_ADVANCE pressure adaption. + * + * For this case LIN_ADVANCE_E_D_RATIO can be used to set the extrusion:distance ratio + * to a fixed value. Note that using a fixed ratio will lead to wrong nozzle pressures + * if the slicer is using variable widths or layer heights within one print! + * + * This option sets the default E:D ratio at startup. Use `M900` to override this value. + * + * Example: `M900 W0.4 H0.2 D1.75`, where: + * - W is the extrusion width in mm + * - H is the layer height in mm + * - D is the filament diameter in mm + * + * Example: `M900 R0.0458` to set the ratio directly. + * + * Set to 0 to auto-detect the ratio based on given Gcode G1 print moves. + * + * Slic3r (including Průša Control) produces Gcode compatible with the automatic mode. + * Cura (as of this writing) may produce Gcode incompatible with the automatic mode. + */ + #define LIN_ADVANCE_E_D_RATIO 0 // The calculated ratio (or 0) according to the formula W * H / ((D / 2) ^ 2 * PI) + // Example: 0.4 * 0.2 / ((1.75 / 2) ^ 2 * PI) = 0.033260135 +#endif + +// @section leveling + +// Default mesh area is an area with an inset margin on the print area. +// Below are the macros that are used to define the borders for the mesh area, +// made available here for specialized needs, ie dual extruder setup. +#if ENABLED(MESH_BED_LEVELING) + #define MESH_MIN_X MESH_INSET + #define MESH_MAX_X (X_BED_SIZE - (MESH_INSET)) + #define MESH_MIN_Y MESH_INSET + #define MESH_MAX_Y (Y_BED_SIZE - (MESH_INSET)) +#elif ENABLED(AUTO_BED_LEVELING_UBL) + #define UBL_MESH_MIN_X UBL_MESH_INSET + #define UBL_MESH_MAX_X (X_BED_SIZE - (UBL_MESH_INSET)) + #define UBL_MESH_MIN_Y UBL_MESH_INSET + #define UBL_MESH_MAX_Y (Y_BED_SIZE - (UBL_MESH_INSET)) + + // If this is defined, the currently active mesh will be saved in the + // current slot on M500. + #define UBL_SAVE_ACTIVE_ON_M500 +#endif + +// @section extras + +// +// G2/G3 Arc Support +// +#define ARC_SUPPORT // Disable this feature to save ~3226 bytes +#if ENABLED(ARC_SUPPORT) + #define MM_PER_ARC_SEGMENT 1 // Length of each arc segment + #define N_ARC_CORRECTION 25 // Number of intertpolated 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 +#endif + +// Support for G5 with XYZE destination and IJPQ offsets. Requires ~2666 bytes. +//#define BEZIER_CURVE_SUPPORT + +// G38.2 and G38.3 Probe Target +// Enable PROBE_DOUBLE_TOUCH if you want G38 to double touch +//#define G38_PROBE_TARGET +#if ENABLED(G38_PROBE_TARGET) + #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) +#endif + +// Moves (or segments) with fewer steps than this will be joined with the next move +#define MIN_STEPS_PER_SEGMENT 6 + +// The minimum pulse width (in µs) for stepping a stepper. +// Set this if you find stepping unreliable, or if using a very fast CPU. +#define MINIMUM_STEPPER_PULSE 0 // (µs) The smallest stepper pulse allowed + +// @section temperature + +// Control heater 0 and heater 1 in parallel. +//#define HEATERS_PARALLEL + +//=========================================================================== +//================================= Buffers ================================= +//=========================================================================== + +// @section hidden + +// 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, i.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 +#else + #define BLOCK_BUFFER_SIZE 16 // maximize block buffer +#endif + +// @section serial + +// The ASCII buffer for serial input +#define MAX_CMD_SIZE 96 +#define BUFSIZE 26 + +// Transmission to Host Buffer Size +// To save 386 bytes of PROGMEM (and TX_BUFFER_SIZE+3 bytes of RAM) set to 0. +// To buffer a simple "ok" you need 4 bytes. +// For ADVANCED_OK (M105) you need 32 bytes. +// For debug-echo: 128 bytes for the optimal speed. +// Other output doesn't need to be that speedy. +// :[0, 2, 4, 8, 16, 32, 64, 128, 256] +#define TX_BUFFER_SIZE 0 + +// Host Receive Buffer Size +// Without XON/XOFF flow control (see SERIAL_XON_XOFF below) 32 bytes should be enough. +// To use flow control, set this buffer size to at least 1024 bytes. +// :[0, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048] +//#define RX_BUFFER_SIZE 1024 + +#if RX_BUFFER_SIZE >= 1024 + // Enable to have the controller send XON/XOFF control characters to + // the host to signal the RX buffer is becoming full. + //#define SERIAL_XON_XOFF +#endif + +#if ENABLED(SDSUPPORT) + // Enable this option to collect and display the maximum + // RX queue usage after transferring a file to SD. + //#define SERIAL_STATS_MAX_RX_QUEUED + + // Enable this option to collect and display the number + // of dropped bytes after a file transfer to SD. + //#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! +//#define EMERGENCY_PARSER + +// Bad Serial-connections can miss a received command by sending an 'ok' +// Therefore some clients abort after 30 seconds in a timeout. +// Some other clients start sending commands while receiving a 'wait'. +// This "wait" is only sent when the buffer is empty. 1 second is a good value here. +//#define NO_TIMEOUTS 1000 // Milliseconds + +// Some clients will have this feature soon. This could make the NO_TIMEOUTS unnecessary. +//#define ADVANCED_OK + +// @section extras + +/** + * Firmware-based and LCD-controlled retract + * + * Add G10 / G11 commands for automatic firmware-based retract / recover. + * Use M207 and M208 to define parameters for retract / recover. + * + * Use M209 to enable or disable auto-retract. + * With auto-retract enabled, all G1 E moves within the set range + * will be converted to firmware-based retract/recover moves. + * + * Be sure to turn off auto-retract during filament change. + * + * Note that M207 / M208 / M209 settings are saved to EEPROM. + * + */ +//#define FWRETRACT // ONLY PARTIALLY TESTED +#if ENABLED(FWRETRACT) + #define MIN_AUTORETRACT 0.1 // When auto-retract is on, convert E moves of this length and over + #define MAX_AUTORETRACT 10.0 // Upper limit for auto-retract conversion + #define RETRACT_LENGTH 3 // Default retract length (positive mm) + #define RETRACT_LENGTH_SWAP 13 // Default swap retract length (positive mm), for extruder change + #define RETRACT_FEEDRATE 45 // Default feedrate for retracting (mm/s) + #define RETRACT_ZLIFT 0 // Default retract Z-lift + #define RETRACT_RECOVER_LENGTH 0 // Default additional recover length (mm, added to retract length when recovering) + #define RETRACT_RECOVER_LENGTH_SWAP 0 // Default additional swap recover length (mm, added to retract length when recovering from extruder change) + #define RETRACT_RECOVER_FEEDRATE 8 // Default feedrate for recovering from retraction (mm/s) + #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) +#endif + +/** + * Advanced Pause + * Experimental feature for filament change support and for parking the nozzle when paused. + * Adds the GCode M600 for initiating filament change. + * If PARK_HEAD_ON_PAUSE enabled, adds the GCode M125 to pause printing and park the nozzle. + * + * Requires an LCD display. + * This feature is required for the default FILAMENT_RUNOUT_SCRIPT. + */ +//#define ADVANCED_PAUSE_FEATURE +#if ENABLED(ADVANCED_PAUSE_FEATURE) + #define PAUSE_PARK_X_POS 100 // X position of hotend + #define PAUSE_PARK_Y_POS 100 // Y position of hotend + #define PAUSE_PARK_Z_ADD 20 // Z addition of hotend (lift) + #define PAUSE_PARK_XY_FEEDRATE 100 // X and Y axes feedrate in mm/s (also used for delta printers Z axis) + #define PAUSE_PARK_Z_FEEDRATE 5 // Z axis feedrate in mm/s (not used for delta printers) + #define PAUSE_PARK_RETRACT_FEEDRATE 60 // Initial retract feedrate in mm/s + #define PAUSE_PARK_RETRACT_LENGTH 5 // Initial retract in mm + // It is a short retract used immediately after print interrupt before move to filament exchange position + #define FILAMENT_CHANGE_UNLOAD_FEEDRATE 10 // Unload filament feedrate in mm/s - filament unloading can be fast + #define FILAMENT_CHANGE_UNLOAD_LENGTH 600 // Unload filament length from hotend in mm + // Longer length for bowden printers to unload filament from whole bowden tube, + // shorter length for printers without bowden to unload filament from extruder only, + // 0 to disable unloading for manual unloading + #define FILAMENT_CHANGE_LOAD_FEEDRATE 6 // Load filament feedrate in mm/s - filament loading into the bowden tube can be fast + #define FILAMENT_CHANGE_LOAD_LENGTH 0 // Load filament length over hotend in mm + // Longer length for bowden printers to fast load filament into whole bowden tube over the hotend, + // Short or zero length for printers without bowden where loading is not used + #define ADVANCED_PAUSE_EXTRUDE_FEEDRATE 3 // Extrude filament feedrate in mm/s - must be slower than load feedrate + #define ADVANCED_PAUSE_EXTRUDE_LENGTH 100 // Extrude filament length in mm after filament is loaded over the hotend, + // 0 to disable for manual extrusion + // Filament can be extruded repeatedly from the filament exchange menu to fill the hotend, + // or until outcoming filament color is not clear for filament color change + #define PAUSE_PARK_NOZZLE_TIMEOUT 45 // Turn off nozzle if user doesn't change filament within this time limit in seconds + #define FILAMENT_CHANGE_NUMBER_OF_ALERT_BEEPS 5 // Number of alert beeps before printer goes quiet + #define PAUSE_PARK_NO_STEPPER_TIMEOUT // Enable to have stepper motors hold position during filament change + // even if it takes longer than DEFAULT_STEPPER_DEACTIVE_TIME. + //#define PARK_HEAD_ON_PAUSE // Go to filament change position on pause, return to print position on resume + //#define HOME_BEFORE_FILAMENT_CHANGE // Ensure homing has been completed prior to parking for filament change +#endif + +// @section tmc + +/** + * Enable this section if you have TMC26X motor drivers. + * You will need to import the TMC26XStepper library into the Arduino IDE for this + * (https://github.com/trinamic/TMC26XStepper.git) + */ +//#define HAVE_TMCDRIVER + +#if ENABLED(HAVE_TMCDRIVER) + + //#define X_IS_TMC + //#define X2_IS_TMC + //#define Y_IS_TMC + //#define Y2_IS_TMC + //#define Z_IS_TMC + //#define Z2_IS_TMC + //#define E0_IS_TMC + //#define E1_IS_TMC + //#define E2_IS_TMC + //#define E3_IS_TMC + //#define E4_IS_TMC + + #define X_MAX_CURRENT 1000 // in mA + #define X_SENSE_RESISTOR 91 // in mOhms + #define X_MICROSTEPS 16 // number of microsteps + + #define X2_MAX_CURRENT 1000 + #define X2_SENSE_RESISTOR 91 + #define X2_MICROSTEPS 16 + + #define Y_MAX_CURRENT 1000 + #define Y_SENSE_RESISTOR 91 + #define Y_MICROSTEPS 16 + + #define Y2_MAX_CURRENT 1000 + #define Y2_SENSE_RESISTOR 91 + #define Y2_MICROSTEPS 16 + + #define Z_MAX_CURRENT 1000 + #define Z_SENSE_RESISTOR 91 + #define Z_MICROSTEPS 16 + + #define Z2_MAX_CURRENT 1000 + #define Z2_SENSE_RESISTOR 91 + #define Z2_MICROSTEPS 16 + + #define E0_MAX_CURRENT 1000 + #define E0_SENSE_RESISTOR 91 + #define E0_MICROSTEPS 16 + + #define E1_MAX_CURRENT 1000 + #define E1_SENSE_RESISTOR 91 + #define E1_MICROSTEPS 16 + + #define E2_MAX_CURRENT 1000 + #define E2_SENSE_RESISTOR 91 + #define E2_MICROSTEPS 16 + + #define E3_MAX_CURRENT 1000 + #define E3_SENSE_RESISTOR 91 + #define E3_MICROSTEPS 16 + + #define E4_MAX_CURRENT 1000 + #define E4_SENSE_RESISTOR 91 + #define E4_MICROSTEPS 16 + +#endif + +// @section TMC2130 + +/** + * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. + * + * You'll also need the TMC2130Stepper Arduino library + * (https://github.com/teemuatlut/TMC2130Stepper). + * + * To use TMC2130 stepper drivers in SPI mode connect your SPI2130 pins to + * the hardware SPI interface on your board and define the required CS pins + * in your `pins_MYBOARD.h` file. (e.g., RAMPS 1.4 uses AUX3 pins `X_CS_PIN 53`, `Y_CS_PIN 49`, etc.). + */ +//#define HAVE_TMC2130 + +#if ENABLED(HAVE_TMC2130) + + // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY + //#define X_IS_TMC2130 + //#define X2_IS_TMC2130 + //#define Y_IS_TMC2130 + //#define Y2_IS_TMC2130 + //#define Z_IS_TMC2130 + //#define Z2_IS_TMC2130 + //#define E0_IS_TMC2130 + //#define E1_IS_TMC2130 + //#define E2_IS_TMC2130 + //#define E3_IS_TMC2130 + //#define E4_IS_TMC2130 + + /** + * Stepper driver settings + */ + + #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 + #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current + #define INTERPOLATE 1 // Interpolate X/Y/Z_MICROSTEPS to 256 + + #define X_CURRENT 1000 // rms current in mA. Multiply by 1.41 for peak current. + #define X_MICROSTEPS 16 // 0..256 + + #define Y_CURRENT 1000 + #define Y_MICROSTEPS 16 + + #define Z_CURRENT 1000 + #define Z_MICROSTEPS 16 + + //#define X2_CURRENT 1000 + //#define X2_MICROSTEPS 16 + + //#define Y2_CURRENT 1000 + //#define Y2_MICROSTEPS 16 + + //#define Z2_CURRENT 1000 + //#define Z2_MICROSTEPS 16 + + //#define E0_CURRENT 1000 + //#define E0_MICROSTEPS 16 + + //#define E1_CURRENT 1000 + //#define E1_MICROSTEPS 16 + + //#define E2_CURRENT 1000 + //#define E2_MICROSTEPS 16 + + //#define E3_CURRENT 1000 + //#define E3_MICROSTEPS 16 + + //#define E4_CURRENT 1000 + //#define E4_MICROSTEPS 16 + + /** + * Use Trinamic's ultra quiet stepping mode. + * When disabled, Marlin will use spreadCycle stepping mode. + */ + #define STEALTHCHOP + + /** + * Let Marlin automatically control stepper current. + * This is still an experimental feature. + * Increase current every 5s by CURRENT_STEP until stepper temperature prewarn gets triggered, + * then decrease current by CURRENT_STEP until temperature prewarn is cleared. + * Adjusting starts from X/Y/Z/E_CURRENT but will not increase over AUTO_ADJUST_MAX + * 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. + * M906 S1 - Start adjusting current + * M906 S0 - Stop adjusting current + * M911 - Report stepper driver overtemperature pre-warn condition. + * M912 - Clear stepper driver overtemperature pre-warn condition flag. + */ + //#define AUTOMATIC_CURRENT_CONTROL + + #if ENABLED(AUTOMATIC_CURRENT_CONTROL) + #define CURRENT_STEP 50 // [mA] + #define AUTO_ADJUST_MAX 1300 // [mA], 1300mA_rms = 1840mA_peak + #define REPORT_CURRENT_CHANGE + #endif + + /** + * The driver will switch to spreadCycle when stepper speed is over HYBRID_THRESHOLD. + * This mode allows for faster movements at the expense of higher noise levels. + * STEALTHCHOP needs to be enabled. + * M913 X/Y/Z/E to live tune the setting + */ + //#define HYBRID_THRESHOLD + + #define X_HYBRID_THRESHOLD 100 // [mm/s] + #define X2_HYBRID_THRESHOLD 100 + #define Y_HYBRID_THRESHOLD 100 + #define Y2_HYBRID_THRESHOLD 100 + #define Z_HYBRID_THRESHOLD 4 + #define Z2_HYBRID_THRESHOLD 4 + #define E0_HYBRID_THRESHOLD 30 + #define E1_HYBRID_THRESHOLD 30 + #define E2_HYBRID_THRESHOLD 30 + #define E3_HYBRID_THRESHOLD 30 + #define E4_HYBRID_THRESHOLD 30 + + /** + * Use stallGuard2 to sense an obstacle and trigger an endstop. + * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. + * If used along with STEALTHCHOP, the movement will be louder when homing. This is normal. + * + * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. + * Higher values make the system LESS sensitive. + * Lower value make the system MORE sensitive. + * Too low values can lead to false positives, while too high values will collide the axis without triggering. + * It is advised to set X/Y_HOME_BUMP_MM to 0. + * M914 X/Y to live tune the setting + */ + //#define SENSORLESS_HOMING + + #if ENABLED(SENSORLESS_HOMING) + #define X_HOMING_SENSITIVITY 19 + #define Y_HOMING_SENSITIVITY 19 + #endif + + /** + * You can set your own advanced settings by filling in predefined functions. + * A list of available functions can be found on the library github page + * https://github.com/teemuatlut/TMC2130Stepper + * + * Example: + * #define TMC2130_ADV() { \ + * stepperX.diag0_temp_prewarn(1); \ + * stepperX.interpolate(0); \ + * } + */ + #define TMC2130_ADV() { } + +#endif // HAVE_TMC2130 + +// @section L6470 + +/** + * Enable this section if you have L6470 motor drivers. + * You need to import the L6470 library into the Arduino IDE for this. + * (https://github.com/ameyer/Arduino-L6470) + */ + +//#define HAVE_L6470DRIVER +#if ENABLED(HAVE_L6470DRIVER) + + //#define X_IS_L6470 + //#define X2_IS_L6470 + //#define Y_IS_L6470 + //#define Y2_IS_L6470 + //#define Z_IS_L6470 + //#define Z2_IS_L6470 + //#define E0_IS_L6470 + //#define E1_IS_L6470 + //#define E2_IS_L6470 + //#define E3_IS_L6470 + //#define E4_IS_L6470 + + #define X_MICROSTEPS 16 // number of microsteps + #define X_K_VAL 50 // 0 - 255, Higher values, are higher power. Be careful not to go too high + #define X_OVERCURRENT 2000 // maxc current in mA. If the current goes over this value, the driver will switch off + #define X_STALLCURRENT 1500 // current in mA where the driver will detect a stall + + #define X2_MICROSTEPS 16 + #define X2_K_VAL 50 + #define X2_OVERCURRENT 2000 + #define X2_STALLCURRENT 1500 + + #define Y_MICROSTEPS 16 + #define Y_K_VAL 50 + #define Y_OVERCURRENT 2000 + #define Y_STALLCURRENT 1500 + + #define Y2_MICROSTEPS 16 + #define Y2_K_VAL 50 + #define Y2_OVERCURRENT 2000 + #define Y2_STALLCURRENT 1500 + + #define Z_MICROSTEPS 16 + #define Z_K_VAL 50 + #define Z_OVERCURRENT 2000 + #define Z_STALLCURRENT 1500 + + #define Z2_MICROSTEPS 16 + #define Z2_K_VAL 50 + #define Z2_OVERCURRENT 2000 + #define Z2_STALLCURRENT 1500 + + #define E0_MICROSTEPS 16 + #define E0_K_VAL 50 + #define E0_OVERCURRENT 2000 + #define E0_STALLCURRENT 1500 + + #define E1_MICROSTEPS 16 + #define E1_K_VAL 50 + #define E1_OVERCURRENT 2000 + #define E1_STALLCURRENT 1500 + + #define E2_MICROSTEPS 16 + #define E2_K_VAL 50 + #define E2_OVERCURRENT 2000 + #define E2_STALLCURRENT 1500 + + #define E3_MICROSTEPS 16 + #define E3_K_VAL 50 + #define E3_OVERCURRENT 2000 + #define E3_STALLCURRENT 1500 + + #define E4_MICROSTEPS 16 + #define E4_K_VAL 50 + #define E4_OVERCURRENT 2000 + #define E4_STALLCURRENT 1500 + +#endif + +/** + * TWI/I2C BUS + * + * This feature is an EXPERIMENTAL feature so it shall not be used on production + * machines. Enabling this will allow you to send and receive I2C data from slave + * devices on the bus. + * + * ; Example #1 + * ; This macro send the string "Marlin" to the slave device with address 0x63 (99) + * ; It uses multiple M260 commands with one B arg + * M260 A99 ; Target slave address + * M260 B77 ; M + * M260 B97 ; a + * M260 B114 ; r + * M260 B108 ; l + * M260 B105 ; i + * M260 B110 ; n + * M260 S1 ; Send the current buffer + * + * ; Example #2 + * ; Request 6 bytes from slave device with address 0x63 (99) + * M261 A99 B5 + * + * ; Example #3 + * ; Example serial output of a M261 request + * echo:i2c-reply: from:99 bytes:5 data:hello + */ + +// @section i2cbus + +//#define EXPERIMENTAL_I2CBUS +#define I2C_SLAVE_ADDRESS 0 // Set a value from 8 to 127 to act as a slave + +// @section extras + +/** + * Spindle & Laser control + * + * Add the M3, M4, and M5 commands to turn the spindle/laser on and off, and + * to set spindle speed, spindle direction, and laser power. + * + * SuperPid is a router/spindle speed controller used in the CNC milling community. + * Marlin can be used to turn the spindle on and off. It can also be used to set + * the spindle speed from 5,000 to 30,000 RPM. + * + * 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. + */ +//#define SPINDLE_LASER_ENABLE +#if ENABLED(SPINDLE_LASER_ENABLE) + + #define SPINDLE_LASER_ENABLE_INVERT false // set to "true" if the on/off function is reversed + #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 // delay in milliseconds to allow the spindle/laser to come up to speed/power + #define SPINDLE_LASER_POWERDOWN_DELAY 5000 // delay in milliseconds to allow the spindle to stop + #define SPINDLE_DIR_CHANGE true // set to true if your spindle controller supports changing spindle direction + #define SPINDLE_INVERT_DIR false + #define SPINDLE_STOP_ON_DIR_CHANGE true // set to true if Marlin should stop the spindle before changing rotation direction + + /** + * The M3 & M4 commands use the following equation to convert PWM duty cycle to speed/power + * + * SPEED/POWER = PWM duty cycle * SPEED_POWER_SLOPE + SPEED_POWER_INTERCEPT + * where PWM duty cycle varies from 0 to 255 + * + * set the following for your controller (ALL MUST BE SET) + */ + + #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_SLOPE 0.3922 + //#define SPEED_POWER_INTERCEPT 0 + //#define SPEED_POWER_MIN 10 + //#define SPEED_POWER_MAX 100 // 0-100% +#endif + +/** + * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins + */ +//#define PINS_DEBUGGING + +/** + * Auto-report temperatures with M155 S + */ +#define AUTO_REPORT_TEMPERATURES + +/** + * Include capabilities in M115 output + */ +#define EXTENDED_CAPABILITIES_REPORT + +/** + * Volumetric extrusion default state + * 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. + */ +//#define VOLUMETRIC_DEFAULT_ON + +/** + * Enable this option for a leaner build of Marlin that removes all + * workspace offsets, simplifying coordinate transformations, leveling, etc. + * + * - M206 and M428 are disabled. + * - G92 will revert to its behavior from Marlin 1.0. + */ +//#define NO_WORKSPACE_OFFSETS + +/** + * 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. + * + * For clients that use a fixed-width font (like OctoPrint), leave this set to 1.0. + * Otherwise, adjust according to your client and font. + */ +#define PROPORTIONAL_FONT_RATIO 1.0 + +/** + * Spend 28 bytes of SRAM to optimize the GCode parser + */ +#define FASTER_GCODE_PARSER + +/** + * User-defined menu items that execute custom GCode + */ +//#define CUSTOM_USER_MENUS +#if ENABLED(CUSTOM_USER_MENUS) + #define USER_SCRIPT_DONE "M117 User Script Done" + #define USER_SCRIPT_AUDIBLE_FEEDBACK + //#define USER_SCRIPT_RETURN // Return to status screen after a script + + #define USER_DESC_1 "Home & UBL Info" + #define USER_GCODE_1 "G28\nG29 W" + + #define USER_DESC_2 "Preheat for PLA" + #define USER_GCODE_2 "M140 S" STRINGIFY(PREHEAT_1_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND) + + #define USER_DESC_3 "Preheat for ABS" + #define USER_GCODE_3 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND) + + #define USER_DESC_4 "Heat Bed/Home/Level" + #define USER_GCODE_4 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nG28\nG29" + + //#define USER_DESC_5 "Home & Info" + //#define USER_GCODE_5 "G28\nM503" +#endif + +/** + * Specify an action command to send to the host when the printer is killed. + * Will be sent in the form '//action:ACTION_ON_KILL', e.g. '//action:poweroff'. + * The host must be configured to handle the action command. + */ +//#define ACTION_ON_KILL "poweroff" + +//=========================================================================== +//====================== I2C Position Encoder Settings ====================== +//=========================================================================== + +/** + * I2C position encoders for closed loop control. + * Developed by Chris Barr at Aus3D. + * + * Wiki: http://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/ + * + * Reilabuild encoders have been modified to improve reliability. + */ + +//#define I2C_POSITION_ENCODERS +#if ENABLED(I2C_POSITION_ENCODERS) + + #define I2CPE_ENCODER_CNT 1 // The number of encoders installed; max of 5 + // encoders supported currently. + + #define I2CPE_ENC_1_ADDR I2CPE_PRESET_ADDR_X // I2C address of the encoder. 30-200. + #define I2CPE_ENC_1_AXIS X_AXIS // Axis the encoder module is installed on. _AXIS. + #define I2CPE_ENC_1_TYPE I2CPE_ENC_TYPE_LINEAR // Type of encoder: I2CPE_ENC_TYPE_LINEAR -or- + // I2CPE_ENC_TYPE_ROTARY. + #define I2CPE_ENC_1_TICKS_UNIT 2048 // 1024 for magnetic strips with 2mm poles; 2048 for + // 1mm poles. For linear encoders this is ticks / mm, + // for rotary encoders this is ticks / revolution. + //#define I2CPE_ENC_1_TICKS_REV (16 * 200) // Only needed for rotary encoders; number of stepper + // steps per full revolution (motor steps/rev * microstepping) + //#define I2CPE_ENC_1_INVERT // Invert the direction of axis travel. + #define I2CPE_ENC_1_EC_METHOD I2CPE_ECM_NONE // Type of error error correction. + #define I2CPE_ENC_1_EC_THRESH 0.10 // Threshold size for error (in mm) above which the + // printer will attempt to correct the error; errors + // smaller than this are ignored to minimize effects of + // measurement noise / latency (filter). + + #define I2CPE_ENC_2_ADDR I2CPE_PRESET_ADDR_Y // Same as above, but for encoder 2. + #define I2CPE_ENC_2_AXIS Y_AXIS + #define I2CPE_ENC_2_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_ENC_2_TICKS_UNIT 2048 + //#define I2CPE_ENC_2_TICKS_REV (16 * 200) + //#define I2CPE_ENC_2_INVERT + #define I2CPE_ENC_2_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_ENC_2_EC_THRESH 0.10 + + #define I2CPE_ENC_3_ADDR I2CPE_PRESET_ADDR_Z // Encoder 3. Add additional configuration options + #define I2CPE_ENC_3_AXIS Z_AXIS // as above, or use defaults below. + + #define I2CPE_ENC_4_ADDR I2CPE_PRESET_ADDR_E // Encoder 4. + #define I2CPE_ENC_4_AXIS E_AXIS + + #define I2CPE_ENC_5_ADDR 34 // Encoder 5. + #define I2CPE_ENC_5_AXIS E_AXIS + + // Default settings for encoders which are enabled, but without settings configured above. + #define I2CPE_DEF_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_DEF_ENC_TICKS_UNIT 2048 + #define I2CPE_DEF_TICKS_REV (16 * 200) + #define I2CPE_DEF_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_DEF_EC_THRESH 0.1 + + //#define I2CPE_ERR_THRESH_ABORT 100.0 // Threshold size for error (in mm) error on any given + // axis after which the printer will abort. Comment out to + // disable abort behaviour. + + #define I2CPE_TIME_TRUSTED 10000 // After an encoder fault, there must be no further fault + // for this amount of time (in ms) before the encoder + // is trusted again. + + /** + * Position is checked every time a new command is executed from the buffer but during long moves, + * this setting determines the minimum update time between checks. A value of 100 works well with + * error rolling average when attempting to correct only for skips and not for vibration. + */ + #define I2CPE_MIN_UPD_TIME_MS 100 // Minimum time in miliseconds between encoder checks. + + // Use a rolling average to identify persistant errors that indicate skips, as opposed to vibration and noise. + #define I2CPE_ERR_ROLLING_AVERAGE + +#endif // I2C_POSITION_ENCODERS + +/** + * MAX7219 Debug Matrix + * + * Add support for a low-cost 8x8 LED Matrix based on the Max7219 chip, which can be used as a status + * display. Requires 3 signal wires. Some useful debug options are included to demonstrate its usage. + * + * Fully assembled MAX7219 boards can be found on the internet for under $2(US). + * For example, see https://www.ebay.com/sch/i.html?_nkw=332349290049 + */ +//#define MAX7219_DEBUG +#if ENABLED(MAX7219_DEBUG) + #define MAX7219_CLK_PIN 64 // 77 on Re-ARM // Configuration of the 3 pins to control the display + #define MAX7219_DIN_PIN 57 // 78 on Re-ARM + #define MAX7219_LOAD_PIN 44 // 79 on Re-ARM + + /** + * Sample debug features + * If you add more debug displays, be careful to avoid conflicts! + */ + #define MAX7219_DEBUG_PRINTER_ALIVE // Blink corner LED of 8x8 matrix to show that the firmware is functioning + #define MAX7219_DEBUG_STEPPER_HEAD 3 // Show the stepper queue head position on this and the next LED matrix row + #define MAX7219_DEBUG_STEPPER_TAIL 5 // Show the stepper queue tail position on this and the next LED matrix row + + #define MAX7219_DEBUG_STEPPER_QUEUE 0 // Show the current stepper queue depth on this and the next LED matrix row + // If you experience stuttering, reboots, etc. this option can reveal how + // tweaks made to the configuration are affecting the printer in real-time. +#endif + +#endif // CONFIGURATION_ADV_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/Velleman/K8400/Dual-head/Configuration.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/Velleman/K8400/Dual-head/Configuration.h new file mode 100644 index 00000000..0bcc9574 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/Velleman/K8400/Dual-head/Configuration.h @@ -0,0 +1,1700 @@ +/** + * 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 . + * + */ + +/** + * Configuration.h + * + * Basic settings such as: + * + * - Type of electronics + * - Type of temperature sensor + * - Printer geometry + * - Endstop configuration + * - LCD controller + * - Extra features + * + * Advanced settings can be found in Configuration_adv.h + * + */ +#ifndef CONFIGURATION_H +#define CONFIGURATION_H +#define CONFIGURATION_H_VERSION 010100 + +//=========================================================================== +//============================= Getting Started ============================= +//=========================================================================== + +/** + * Here are some standard links for getting your machine calibrated: + * + * http://reprap.org/wiki/Calibration + * http://youtu.be/wAL9d7FgInk + * http://calculator.josefprusa.cz + * http://reprap.org/wiki/Triffid_Hunter%27s_Calibration_Guide + * http://www.thingiverse.com/thing:5573 + * https://sites.google.com/site/repraplogphase/calibration-of-your-reprap + * http://www.thingiverse.com/thing:298812 + */ + +//=========================================================================== +//============================= DELTA Printer =============================== +//=========================================================================== +// For a Delta printer start with one of the configuration files in the +// example_configurations/delta directory and customize for your machine. +// + +//=========================================================================== +//============================= SCARA Printer =============================== +//=========================================================================== +// For a SCARA printer start with the configuration files in +// example_configurations/SCARA and customize for your machine. +// + +// @section info + +// User-specified version info of this build to display in [Pronterface, etc] terminal window during +// startup. Implementation of an idea by Prof Braino to inform user that any changes made to this +// build by the user have been successfully uploaded into firmware. +#define STRING_CONFIG_H_AUTHOR "(Anthony Birkett, default config)" // Who made the changes. +#define SHOW_BOOTSCREEN +#define STRING_SPLASH_LINE1 SHORT_BUILD_VERSION // will be shown during bootup in line 1 +#define STRING_SPLASH_LINE2 WEBSITE_URL // will be shown during bootup in line 2 + +// +// *** VENDORS PLEASE READ ***************************************************** +// +// Marlin now allow you to have a vendor boot image to be displayed on machine +// start. When SHOW_CUSTOM_BOOTSCREEN is defined Marlin will first show your +// custom boot image and then the default Marlin boot image is shown. +// +// We suggest for you to take advantage of this new feature and keep the Marlin +// boot image unmodified. For an example have a look at the bq Hephestos 2 +// example configuration folder. +// +//#define SHOW_CUSTOM_BOOTSCREEN +// @section machine + +/** + * Select which serial port on the board will be used for communication with the host. + * This allows the connection of wireless adapters (for instance) to non-default port pins. + * Serial port 0 is always used by the Arduino bootloader regardless of this setting. + * + * :[0, 1, 2, 3, 4, 5, 6, 7] + */ +#define SERIAL_PORT 0 + +/** + * This setting determines the communication speed of the printer. + * + * 250000 works in most cases, but you might try a lower speed if + * you commonly experience drop-outs during host printing. + * You may try up to 1000000 to speed up SD file transfer. + * + * :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000] + */ +#define BAUDRATE 250000 + +// Enable the Bluetooth serial interface on AT90USB devices +//#define BLUETOOTH + +// The following define selects which electronics board you have. +// Please choose the name from boards.h that matches your setup +#ifndef MOTHERBOARD + #define MOTHERBOARD BOARD_K8400 +#endif + +// Optional custom name for your RepStrap or other custom machine +// Displayed in the LCD "Ready" message +//#define CUSTOM_MACHINE_NAME "3D Printer" + +// Define this to set a unique identifier for this printer, (Used by some programs to differentiate between machines) +// You can use an online service to generate a random UUID. (eg http://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] +#define EXTRUDERS 2 + +// For Cyclops or any "multi-extruder" that shares a single nozzle. +//#define SINGLENOZZLE + +/** + * Průša MK2 Single Nozzle Multi-Material Multiplexer, and variants. + * + * This device allows one stepper driver on a control board to drive + * two to eight stepper motors, one at a time, in a manner suitable + * for extruders. + * + * This option only allows the multiplexer to switch on tool-change. + * Additional options to configure custom E moves are pending. + */ +//#define MK2_MULTIPLEXER +#if ENABLED(MK2_MULTIPLEXER) + // Override the default DIO selector pins here, if needed. + // Some pins files may provide defaults for these pins. + //#define E_MUX0_PIN 40 // Always Required + //#define E_MUX1_PIN 42 // Needed for 3 to 8 steppers + //#define E_MUX2_PIN 44 // Needed for 5 to 8 steppers +#endif + +// A dual extruder that uses a single stepper motor +//#define SWITCHING_EXTRUDER +#if ENABLED(SWITCHING_EXTRUDER) + #define SWITCHING_EXTRUDER_SERVO_NR 0 + #define SWITCHING_EXTRUDER_SERVO_ANGLES { 0, 90 } // Angles for E0, E1[, E2, E3] + #if EXTRUDERS > 3 + #define SWITCHING_EXTRUDER_E23_SERVO_NR 1 + #endif +#endif + +// A dual-nozzle that uses a servomotor to raise/lower one of the nozzles +//#define SWITCHING_NOZZLE +#if ENABLED(SWITCHING_NOZZLE) + #define SWITCHING_NOZZLE_SERVO_NR 0 + #define SWITCHING_NOZZLE_SERVO_ANGLES { 0, 90 } // Angles for E0, E1 + //#define HOTEND_OFFSET_Z { 0.0, 0.0 } +#endif + +/** + * Two separate X-carriages with extruders that connect to a moving part + * via a magnetic docking mechanism. Requires SOL1_PIN and SOL2_PIN. + */ +//#define PARKING_EXTRUDER +#if ENABLED(PARKING_EXTRUDER) + #define PARKING_EXTRUDER_SOLENOIDS_INVERT // If enabled, the solenoid is NOT magnetized with applied voltage + #define PARKING_EXTRUDER_SOLENOIDS_PINS_ACTIVE LOW // LOW or HIGH pin signal energizes the coil + #define PARKING_EXTRUDER_SOLENOIDS_DELAY 250 // Delay (ms) for magnetic field. No delay if 0 or not defined. + #define PARKING_EXTRUDER_PARKING_X { -78, 184 } // X positions for parking the extruders + #define PARKING_EXTRUDER_GRAB_DISTANCE 1 // mm to move beyond the parking point to grab the extruder + #define PARKING_EXTRUDER_SECURITY_RAISE 5 // Z-raise before parking + #define HOTEND_OFFSET_Z { 0.0, 1.3 } // Z-offsets of the two hotends. The first must be 0. +#endif + +/** + * "Mixing Extruder" + * - Adds a new code, M165, to set the current mix factors. + * - Extends the stepping routines to move multiple steppers in proportion to the mix. + * - Optional support for Repetier Firmware M163, M164, and virtual extruder. + * - This implementation supports only a single extruder. + * - Enable DIRECT_MIXING_IN_G1 for Pia Taubert's reference implementation + */ +//#define MIXING_EXTRUDER +#if ENABLED(MIXING_EXTRUDER) + #define MIXING_STEPPERS 2 // Number of steppers in your mixing extruder + #define MIXING_VIRTUAL_TOOLS 16 // Use the Virtual Tool method with M163 and M164 + //#define DIRECT_MIXING_IN_G1 // Allow ABCDHI mix factors in G1 movement commands +#endif + +// Offset of the extruders (uncomment if using more than one and relying on firmware to position when changing). +// The offset has to be X=0, Y=0 for the extruder 0 hotend (default extruder). +// For the other hotends it is their distance from the extruder 0 hotend. +//#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis +//#define HOTEND_OFFSET_Y {0.0, 5.00} // (in mm) for each extruder, offset of the hotend on the Y axis + +// @section machine + +/** + * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN + * + * 0 = No Power Switch + * 1 = ATX + * 2 = X-Box 360 203Watts (the blue wire connected to PS_ON and the red wire to VCC) + * + * :{ 0:'No power switch', 1:'ATX', 2:'X-Box 360' } + */ +#define POWER_SUPPLY 1 + +#if POWER_SUPPLY > 0 + // Enable this option to leave the PSU off at startup. + // Power to steppers and heaters will need to be turned on with M80. + //#define PS_DEFAULT_OFF +#endif + +// @section temperature + +//=========================================================================== +//============================= Thermal Settings ============================ +//=========================================================================== + +/** + * --NORMAL IS 4.7kohm PULLUP!-- 1kohm pullup can be used on hotend sensor, using correct resistor and table + * + * Temperature sensors available: + * + * -3 : thermocouple with MAX31855 (only for sensor 0) + * -2 : thermocouple with MAX6675 (only for sensor 0) + * -1 : thermocouple with AD595 + * 0 : not used + * 1 : 100k thermistor - best choice for EPCOS 100k (4.7k pullup) + * 2 : 200k thermistor - ATC Semitec 204GT-2 (4.7k pullup) + * 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 (Used in ParCan & J-Head) (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) + * 71 : 100k Honeywell thermistor 135-104LAF-J01 (4.7k pullup) + * 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) + * 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" + * 20 : the PT100 circuit found in the Ultimainboard V2.x + * 60 : 100k Maker's Tool Works Kapton Bed Thermistor beta=3950 + * 66 : 4.7M High Temperature thermistor from Dyze Design + * 70 : the 100K thermistor found in the bq Hephestos 2 + * 75 : 100k Generic Silicon Heat Pad with NTC 100K MGB18-104F39050L32 thermistor + * + * 1k ohm pullup tables - This is atypical, and requires changing out the 4.7k pullup for 1k. + * (but gives greater accuracy and more stable PID) + * 51 : 100k thermistor - EPCOS (1k pullup) + * 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 + * 1010 : Pt1000 with 1k pullup (non standard) + * 147 : Pt100 with 4k7 pullup + * 110 : Pt100 with 1k pullup (non standard) + * + * Use these for Testing or Development purposes. NEVER for production machine. + * 998 : Dummy Table that ALWAYS reads 25°C or the temperature defined below. + * 999 : Dummy Table that ALWAYS reads 100°C or the temperature defined below. + * + * :{ '0': "Not used", '1':"100k / 4.7k - EPCOS", '2':"200k / 4.7k - ATC Semitec 204GT-2", '3':"Mendel-parts / 4.7k", '4':"10k !! do not use for a hotend. Bad resolution at high temp. !!", '5':"100K / 4.7k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '6':"100k / 4.7k EPCOS - Not as accurate as Table 1", '7':"100k / 4.7k Honeywell 135-104LAG-J01", '8':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT", '9':"100k / 4.7k GE Sensing AL03006-58.2K-97-G1", '10':"100k / 4.7k RS 198-961", '11':"100k / 4.7k beta 3950 1%", '12':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT (calibrated for Makibox hot bed)", '13':"100k Hisens 3950 1% up to 300°C for hotend 'Simple ONE ' & hotend 'All In ONE'", '20':"PT100 (Ultimainboard V2.x)", '51':"100k / 1k - EPCOS", '52':"200k / 1k - ATC Semitec 204GT-2", '55':"100k / 1k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '60':"100k Maker's Tool Works Kapton Bed Thermistor beta=3950", '66':"Dyze Design 4.7M High Temperature thermistor", '70':"the 100K thermistor found in the bq Hephestos 2", '71':"100k / 4.7k Honeywell 135-104LAF-J01", '147':"Pt100 / 4.7k", '1047':"Pt1000 / 4.7k", '110':"Pt100 / 1k (non-standard)", '1010':"Pt1000 / 1k (non standard)", '-3':"Thermocouple + MAX31855 (only for sensor 0)", '-2':"Thermocouple + MAX6675 (only for sensor 0)", '-1':"Thermocouple + AD595",'998':"Dummy 1", '999':"Dummy 2" } + */ +#define TEMP_SENSOR_0 5 +#define TEMP_SENSOR_1 5 +#define TEMP_SENSOR_2 0 +#define TEMP_SENSOR_3 0 +#define TEMP_SENSOR_4 0 +#define TEMP_SENSOR_BED 0 + +// Dummy thermistor constant temperature readings, for use with 998 and 999 +#define DUMMY_THERMISTOR_998_VALUE 25 +#define DUMMY_THERMISTOR_999_VALUE 100 + +// 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 +#define MAX_REDUNDANT_TEMP_SENSOR_DIFF 10 + +// Extruder temperature must be close to target for this long before M109 returns success +#define TEMP_RESIDENCY_TIME 2 // (seconds) +#define TEMP_HYSTERESIS 5 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// Bed temperature must be close to target for this long before M190 returns success +#define TEMP_BED_RESIDENCY_TIME 10 // (seconds) +#define TEMP_BED_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_BED_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// The minimal temperature defines the temperature below which the heater will not be enabled It is used +// to check that the wiring to the thermistor is not broken. +// Otherwise this would lead to the heater being powered on all the time. +#define HEATER_0_MINTEMP 5 +#define HEATER_1_MINTEMP 5 +#define HEATER_2_MINTEMP 5 +#define HEATER_3_MINTEMP 5 +#define HEATER_4_MINTEMP 5 +#define BED_MINTEMP 5 + +// When temperature exceeds max temp, your heater will be switched off. +// This feature exists to protect your hotend from overheating accidentally, but *NOT* from thermistor short/failure! +// You should use MINTEMP for thermistor short/failure protection. +#define HEATER_0_MAXTEMP 275 +#define HEATER_1_MAXTEMP 275 +#define HEATER_2_MAXTEMP 275 +#define HEATER_3_MAXTEMP 275 +#define HEATER_4_MAXTEMP 275 +#define BED_MAXTEMP 150 + +//=========================================================================== +//============================= PID Settings ================================ +//=========================================================================== +// PID Tuning Guide here: http://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 +#if ENABLED(PIDTEMP) + //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. + //#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. + #define K1 0.95 //smoothing factor within the PID + + // 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 + +#endif // PIDTEMP + +//=========================================================================== +//============================= PID > Bed Temperature Control =============== +//=========================================================================== +// Select PID or bang-bang with PIDTEMPBED. If bang-bang, BED_LIMIT_SWITCHING will enable hysteresis +// +// Uncomment this to enable PID on the bed. It uses the same frequency PWM as the extruder. +// If your PID_dT is the default, and correct for your hardware/configuration, that means 7.689Hz, +// which is fine for driving a square wave into a resistive load and does not significantly impact you FET heating. +// This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W heater. +// If your configuration is significantly different than this and you don't understand the issues involved, you probably +// shouldn't use bed PID until someone else verifies your hardware works. +// If this is enabled, find your own PID constants below. +//#define PIDTEMPBED + +//#define BED_LIMIT_SWITCHING + +// This sets the max power delivered to the bed, and replaces the HEATER_BED_DUTY_CYCLE_DIVIDER option. +// all forms of bed control obey this (PID, bang-bang, bang-bang with hysteresis) +// setting this to anything other than 255 enables a form of PWM to the bed just like HEATER_BED_DUTY_CYCLE_DIVIDER did, +// so you shouldn't use it unless you are OK with PWM on your bed. (see the comment on enabling PIDTEMPBED) +#define MAX_BED_POWER 255 // limits duty cycle to bed; 255=full current + +#if ENABLED(PIDTEMPBED) + + //#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) + #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 + +// @section extruder + +// This option prevents extrusion if the temperature is below EXTRUDE_MINTEMP. +// It also enables the M302 command to set the minimum extrusion temperature +// or to allow moving the extruder regardless of the hotend temperature. +// *** IT IS HIGHLY RECOMMENDED TO LEAVE THIS OPTION ENABLED! *** +#define PREVENT_COLD_EXTRUSION +#define EXTRUDE_MINTEMP 170 + +// This option prevents a single extrusion longer than EXTRUDE_MAXLENGTH. +// Note that for Bowden Extruders a too-small value here may prevent loading. +#define PREVENT_LENGTHY_EXTRUDE +#define EXTRUDE_MAXLENGTH 200 + +//=========================================================================== +//======================== Thermal Runaway Protection ======================= +//=========================================================================== + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * If you get "Thermal Runaway" or "Heating failed" errors the + * details can be tuned in Configuration_adv.h + */ + +#define THERMAL_PROTECTION_HOTENDS // Enable thermal protection for all extruders +#define THERMAL_PROTECTION_BED // Enable thermal protection for the heated bed + +//=========================================================================== +//============================= Mechanical Settings ========================= +//=========================================================================== + +// @section machine + +// Uncomment one of these options to enable CoreXY, CoreXZ, or CoreYZ kinematics +// either in the usual order or reversed +//#define COREXY +//#define COREXZ +//#define COREYZ +//#define COREYX +//#define COREZX +//#define COREZY + +//=========================================================================== +//============================== Endstop Settings =========================== +//=========================================================================== + +// @section homing + +// Specify here all the endstop connectors that are connected to any endstop or probe. +// Almost all printers will be using one per axis. Probes will use one or more of the +// extra connectors. Leave undefined any used for non-endstop and non-probe purposes. +#define USE_XMIN_PLUG +#define USE_YMIN_PLUG +#define USE_ZMIN_PLUG +//#define USE_XMAX_PLUG +//#define USE_YMAX_PLUG +//#define USE_ZMAX_PLUG + +// coarse Endstop Settings +#define ENDSTOPPULLUPS // Comment this out (using // at the start of the line) to disable the endstop pullup resistors + +#if DISABLED(ENDSTOPPULLUPS) + // fine endstop settings: Individual pullups. will be ignored if ENDSTOPPULLUPS is defined + //#define ENDSTOPPULLUP_XMAX + //#define ENDSTOPPULLUP_YMAX + //#define ENDSTOPPULLUP_ZMAX + //#define ENDSTOPPULLUP_XMIN + //#define ENDSTOPPULLUP_YMIN + //#define ENDSTOPPULLUP_ZMIN + //#define ENDSTOPPULLUP_ZMIN_PROBE +#endif + +// Mechanical endstop with COM to ground and NC to Signal uses "false" here (most common setup). +#define X_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Y_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define X_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Y_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MIN_PROBE_ENDSTOP_INVERTING true // set to true to invert the logic of the probe. + +// Enable this feature if all enabled endstop pins are interrupt-capable. +// This will remove the need to poll the interrupt pins, saving many CPU cycles. +//#define ENDSTOP_INTERRUPTS_FEATURE + +//============================================================================= +//============================== Movement Settings ============================ +//============================================================================= +// @section motion + +/** + * Default Settings + * + * These settings can be reset by M502 + * + * Note that if EEPROM is enabled, saved values will override these. + */ + +/** + * With this option each E stepper can have its own factors for the + * following movement settings. If fewer factors are given than the + * total number of extruders, the last value applies to the rest. + */ +//#define DISTINCT_E_FACTORS + +/** + * Default Axis Steps Per Unit (steps/mm) + * Override with M92 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_AXIS_STEPS_PER_UNIT { 134.74, 134.74, 4266.66, 148.7 } + +/** + * Default Max Feed Rate (mm/s) + * Override with M203 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_FEEDRATE { 160, 160, 10, 10000 } + +/** + * Default Max Acceleration (change/s) change = mm/s + * (Maximum start speed for accelerated moves) + * Override with M201 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_ACCELERATION { 9000, 9000, 100, 10000 } + +/** + * Default Acceleration (change/s) change = mm/s + * Override with M204 + * + * M204 P Acceleration + * M204 R Retract Acceleration + * M204 T Travel Acceleration + */ +#define DEFAULT_ACCELERATION 6000 // X, Y, Z and E acceleration for printing moves +#define DEFAULT_RETRACT_ACCELERATION 6000 // E acceleration for retracts +#define DEFAULT_TRAVEL_ACCELERATION 3000 // X, Y, Z acceleration for travel (non printing) moves + +/** + * Default Jerk (mm/s) + * Override with M205 X Y Z E + * + * "Jerk" specifies the minimum speed change that requires acceleration. + * When changing speed and direction, if the difference is less than the + * value set here, it may happen instantaneously. + */ +#define DEFAULT_XJERK 10.0 +#define DEFAULT_YJERK 10.0 +#define DEFAULT_ZJERK 0.5 +#define DEFAULT_EJERK 20.0 + +//=========================================================================== +//============================= Z Probe Options ============================= +//=========================================================================== +// @section probes + +// +// See http://marlinfw.org/configuration/probes.html +// + +/** + * Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + * + * Enable this option for a probe connected to the Z Min endstop pin. + */ +#define Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + +/** + * Z_MIN_PROBE_ENDSTOP + * + * Enable this option for a probe connected to any pin except Z-Min. + * (By default Marlin assumes the Z-Max endstop pin.) + * To use a custom Z Probe pin, set Z_MIN_PROBE_PIN below. + * + * - The simplest option is to use a free endstop connector. + * - Use 5V for powered (usually inductive) sensors. + * + * - RAMPS 1.3/1.4 boards may use the 5V, GND, and Aux4->D32 pin: + * - For simple switches connect... + * - normally-closed switches to GND and D32. + * - normally-open switches to 5V and D32. + * + * WARNING: Setting the wrong pin may have unexpected and potentially + * disastrous consequences. Use with caution and do your homework. + * + */ +//#define Z_MIN_PROBE_ENDSTOP + +/** + * Probe Type + * + * Allen Key Probes, Servo Probes, Z-Sled Probes, FIX_MOUNTED_PROBE, etc. + * Activate one of these to use Auto Bed Leveling below. + */ + +/** + * The "Manual Probe" provides a means to do "Auto" Bed Leveling without a probe. + * Use G29 repeatedly, adjusting the Z height at each point with movement commands + * or (with LCD_BED_LEVELING) the LCD controller. + */ +//#define PROBE_MANUALLY + +/** + * A Fix-Mounted Probe either doesn't deploy or needs manual deployment. + * (e.g., an inductive probe or a nozzle-based probe-switch.) + */ +//#define FIX_MOUNTED_PROBE + +/** + * Z Servo Probe, such as an endstop switch on a rotating arm. + */ +//#define Z_ENDSTOP_SERVO_NR 0 // Defaults to SERVO 0 connector. +//#define Z_SERVO_ANGLES {70,0} // Z Servo Deploy and Stow angles + +/** + * The BLTouch probe uses a Hall effect sensor and emulates a servo. + */ +//#define BLTOUCH +#if ENABLED(BLTOUCH) + //#define BLTOUCH_DELAY 375 // (ms) Enable and increase if needed +#endif + +/** + * Enable one or more of the following if probing seems unreliable. + * Heaters and/or fans can be disabled during probing to minimize electrical + * noise. A delay can also be added to allow noise and vibration to settle. + * These options are most useful for the BLTouch probe, but may also improve + * readings with inductive probes and piezo sensors. + */ +//#define PROBING_HEATERS_OFF // Turn heaters off when probing +//#define PROBING_FANS_OFF // Turn fans off when probing +//#define DELAY_BEFORE_PROBING 200 // (ms) To prevent vibrations from triggering piezo sensors + +// A probe that is deployed and stowed with a solenoid pin (SOL1_PIN) +//#define SOLENOID_PROBE + +// A sled-mounted probe like those designed by Charles Bell. +//#define Z_PROBE_SLED +//#define SLED_DOCKING_OFFSET 5 // The extra distance the X axis must travel to pickup the sled. 0 should be fine but you can push it further if you'd like. + +// +// For Z_PROBE_ALLEN_KEY see the Delta example configurations. +// + +/** + * Z Probe to nozzle (X,Y) offset, relative to (0, 0). + * X and Y offsets must be integers. + * + * In the following example the X and Y offsets are both positive: + * #define X_PROBE_OFFSET_FROM_EXTRUDER 10 + * #define Y_PROBE_OFFSET_FROM_EXTRUDER 10 + * + * +-- BACK ---+ + * | | + * L | (+) P | R <-- probe (20,20) + * E | | I + * F | (-) N (+) | G <-- nozzle (10,10) + * T | | H + * | (-) | T + * | | + * O-- FRONT --+ + * (0,0) + */ +#define X_PROBE_OFFSET_FROM_EXTRUDER 10 // X offset: -left +right [of the nozzle] +#define Y_PROBE_OFFSET_FROM_EXTRUDER 10 // Y offset: -front +behind [the nozzle] +#define Z_PROBE_OFFSET_FROM_EXTRUDER 0 // Z offset: -below +above [the nozzle] + +// X and Y axis travel speed (mm/m) between probes +#define XY_PROBE_SPEED 8000 + +// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +#define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z + +// Speed for the "accurate" probe of each point +#define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) + +// Use double touch for probing +//#define PROBE_DOUBLE_TOUCH + +/** + * Z probes require clearance when deploying, stowing, and moving between + * probe points to avoid hitting the bed and other hardware. + * Servo-mounted probes require extra space for the arm to rotate. + * Inductive probes need space to keep from triggering early. + * + * Use these settings to specify the distance (mm) to raise the probe (or + * lower the bed). The values set here apply over and above any (negative) + * probe Z Offset set with Z_PROBE_OFFSET_FROM_EXTRUDER, M851, or the LCD. + * Only integer values >= 1 are valid here. + * + * Example: `M851 Z-5` with a CLEARANCE of 4 => 9mm from bed to nozzle. + * But: `M851 Z+1` with a CLEARANCE of 2 => 2mm from bed to nozzle. + */ +#define Z_CLEARANCE_DEPLOY_PROBE 15 // Z Clearance for Deploy/Stow +#define Z_CLEARANCE_BETWEEN_PROBES 5 // Z Clearance between probe points + +// For M851 give a range for adjusting the Z probe offset +#define Z_PROBE_OFFSET_RANGE_MIN -20 +#define Z_PROBE_OFFSET_RANGE_MAX 20 + +// Enable the M48 repeatability test to test probe accuracy +//#define Z_MIN_PROBE_REPEATABILITY_TEST + +// For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1 +// :{ 0:'Low', 1:'High' } +#define X_ENABLE_ON 0 +#define Y_ENABLE_ON 0 +#define Z_ENABLE_ON 0 +#define E_ENABLE_ON 0 // For all extruders + +// Disables axis stepper immediately when it's not being used. +// 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 +//#define DISABLE_REDUCED_ACCURACY_WARNING + +// @section extruder + +#define DISABLE_E false // For all extruders +#define DISABLE_INACTIVE_EXTRUDER true // Keep only the active extruder enabled. + +// @section machine + +// Invert the stepper direction. Change (or reverse the motor connector) if an axis goes the wrong way. +#define INVERT_X_DIR false +#define INVERT_Y_DIR true +#define INVERT_Z_DIR true + +// Enable this option for Toshiba stepper drivers +//#define CONFIG_STEPPERS_TOSHIBA + +// @section extruder + +// For direct drive extruder v9 set to true, for geared extruder set to false. +#define INVERT_E0_DIR false +#define INVERT_E1_DIR true +#define INVERT_E2_DIR false +#define INVERT_E3_DIR false +#define INVERT_E4_DIR false + +// @section homing + +//#define NO_MOTION_BEFORE_HOMING // Inhibit movement until all axes have been homed + +//#define Z_HOMING_HEIGHT 4 // (in mm) Minimal z height before homing (G28) for Z clearance above the bed, clamps, ... + // Be sure you have this distance over your Z_MAX_POS in case. + +// Direction of endstops when homing; 1=MAX, -1=MIN +// :[-1,1] +#define X_HOME_DIR -1 +#define Y_HOME_DIR -1 +#define Z_HOME_DIR -1 + +// @section machine + +// The size of the print bed +#define X_BED_SIZE 200 +#define Y_BED_SIZE 200 + +// Travel limits (mm) after homing, corresponding to endstop positions. +#define X_MIN_POS 0 +#define Y_MIN_POS 20 +#define Z_MIN_POS 0 +#define X_MAX_POS X_BED_SIZE +#define Y_MAX_POS Y_BED_SIZE +#define Z_MAX_POS 190 + +// If enabled, axes won't move below MIN_POS in response to movement commands. +#define MIN_SOFTWARE_ENDSTOPS +// If enabled, axes won't move above MAX_POS in response to movement commands. +#define MAX_SOFTWARE_ENDSTOPS + +/** + * Filament Runout Sensor + * A mechanical or opto endstop is used to check for the presence of filament. + * + * RAMPS-based boards use SERVO3_PIN. + * For other boards you may need to define FIL_RUNOUT_PIN. + * By default the firmware assumes HIGH = has filament, LOW = ran out + */ +//#define FILAMENT_RUNOUT_SENSOR +#if ENABLED(FILAMENT_RUNOUT_SENSOR) + #define FIL_RUNOUT_INVERTING false // set to true to invert the logic of the sensor. + #define ENDSTOPPULLUP_FIL_RUNOUT // Uncomment to use internal pullup for filament runout pins if the sensor is defined. + #define FILAMENT_RUNOUT_SCRIPT "M600" +#endif + +//=========================================================================== +//=============================== Bed Leveling ============================== +//=========================================================================== +// @section bedlevel + +/** + * Choose one of the options below to enable G29 Bed Leveling. The parameters + * and behavior of G29 will change depending on your selection. + * + * If using a Probe for Z Homing, enable Z_SAFE_HOMING also! + * + * - AUTO_BED_LEVELING_3POINT + * Probe 3 arbitrary points on the bed (that aren't collinear) + * You specify the XY coordinates of all 3 points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_LINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_BILINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a mesh, best for large or uneven beds. + * + * - AUTO_BED_LEVELING_UBL (Unified Bed Leveling) + * A comprehensive bed leveling system combining the features and benefits + * of other systems. UBL also includes integrated Mesh Generation, Mesh + * Validation and Mesh Editing systems. Currently, UBL is only checked out + * for Cartesian Printers. That said, it was primarily designed to correct + * poor quality Delta Printers. If you feel adventurous and have a Delta, + * please post an issue if something doesn't work correctly. Initially, + * you will need to set a reduced bed size so you have a rectangular area + * to test on. + * + * - MESH_BED_LEVELING + * Probe a grid manually + * The result is a mesh, suitable for large or uneven beds. (See BILINEAR.) + * For machines without a probe, Mesh Bed Leveling provides a method to perform + * leveling in steps so you can manually adjust the Z height at each grid-point. + * With an LCD controller the process is guided step-by-step. + */ +//#define AUTO_BED_LEVELING_3POINT +//#define AUTO_BED_LEVELING_LINEAR +//#define AUTO_BED_LEVELING_BILINEAR +//#define AUTO_BED_LEVELING_UBL +//#define MESH_BED_LEVELING + +/** + * Enable detailed logging of G28, G29, M48, etc. + * Turn on with the command 'M111 S32'. + * NOTE: Requires a lot of PROGMEM! + */ +//#define DEBUG_LEVELING_FEATURE + +#if ENABLED(MESH_BED_LEVELING) || ENABLED(AUTO_BED_LEVELING_BILINEAR) || ENABLED(AUTO_BED_LEVELING_UBL) + // Gradually reduce leveling correction until a set height is reached, + // at which point movement will be level to the machine's XY plane. + // The height can be set with M420 Z + #define ENABLE_LEVELING_FADE_HEIGHT +#endif + +#if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Set the number of grid points per dimension. + #define GRID_MAX_POINTS_X 3 + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + // Set the boundaries for probing (where the probe can reach). + #define LEFT_PROBE_BED_POSITION 15 + #define RIGHT_PROBE_BED_POSITION 170 + #define FRONT_PROBE_BED_POSITION 20 + #define BACK_PROBE_BED_POSITION 170 + + // The Z probe minimum outer margin (to validate G29 parameters). + #define MIN_PROBE_EDGE 10 + + // Probe along the Y axis, advancing X after each column + //#define PROBE_Y_FIRST + + #if ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Beyond the probed grid, continue the implied tilt? + // Default is to maintain the height of the nearest edge. + //#define EXTRAPOLATE_BEYOND_GRID + + // + // Experimental Subdivision of the grid by Catmull-Rom method. + // Synthesizes intermediate points to produce a more detailed mesh. + // + //#define ABL_BILINEAR_SUBDIVISION + #if ENABLED(ABL_BILINEAR_SUBDIVISION) + // Number of subdivisions between probe points + #define BILINEAR_SUBDIVISIONS 3 + #endif + + #endif + +#elif ENABLED(AUTO_BED_LEVELING_3POINT) + + // 3 arbitrary points to probe. + // A simple cross-product is used to estimate the plane of the bed. + #define ABL_PROBE_PT_1_X 15 + #define ABL_PROBE_PT_1_Y 180 + #define ABL_PROBE_PT_2_X 15 + #define ABL_PROBE_PT_2_Y 20 + #define ABL_PROBE_PT_3_X 170 + #define ABL_PROBE_PT_3_Y 20 + +#elif ENABLED(AUTO_BED_LEVELING_UBL) + + //=========================================================================== + //========================= Unified Bed Leveling ============================ + //=========================================================================== + + #define UBL_MESH_INSET 1 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 10 // Don't use more than 15 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + #define UBL_PROBE_PT_1_X 39 // Probing points for 3-Point leveling of the mesh + #define UBL_PROBE_PT_1_Y 180 + #define UBL_PROBE_PT_2_X 39 + #define UBL_PROBE_PT_2_Y 20 + #define UBL_PROBE_PT_3_X 180 + #define UBL_PROBE_PT_3_Y 20 + + #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation + #define UBL_MESH_EDIT_MOVES_Z // Sophisticated users prefer no movement of nozzle + +#elif ENABLED(MESH_BED_LEVELING) + + //=========================================================================== + //=================================== Mesh ================================== + //=========================================================================== + + #define MESH_INSET 10 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 3 // Don't use more than 7 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + //#define MESH_G28_REST_ORIGIN // After homing all axes ('G28' or 'G28 XYZ') rest Z at Z_MIN_POS + +#endif // BED_LEVELING + +/** + * Use the LCD controller for bed leveling + * Requires MESH_BED_LEVELING or PROBE_MANUALLY + */ +//#define LCD_BED_LEVELING + +#if ENABLED(LCD_BED_LEVELING) + #define MBL_Z_STEP 0.025 // Step size while manually probing Z axis. + #define LCD_PROBE_Z_RANGE 4 // Z Range centered on Z_MIN_POS for LCD Z adjustment +#endif + +// Add a menu item to move between bed corners for manual bed adjustment +//#define LEVEL_BED_CORNERS + +/** + * Commands to execute at the end of G29 probing. + * Useful to retract or move the Z probe out of the way. + */ +//#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) +//#define BED_CENTER_AT_0_0 + +// Manually set the home position. Leave these undefined for automatic settings. +// For DELTA this is the top-center of the Cartesian print volume. +//#define MANUAL_X_HOME_POS 0 +//#define MANUAL_Y_HOME_POS 0 +//#define MANUAL_Z_HOME_POS 0 + +// Use "Z Safe Homing" to avoid homing with a Z probe outside the bed area. +// +// With this feature enabled: +// +// - 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). +// - 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 axis (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). +#endif + +// Homing speeds (mm/m) +#define HOMING_FEEDRATE_XY (50*60) +#define HOMING_FEEDRATE_Z (8*60) + +//============================================================================= +//============================= Additional Features =========================== +//============================================================================= + +// @section extras + +// +// EEPROM +// +// The microcontroller can store settings in the EEPROM, e.g. max velocity... +// M500 - stores parameters in EEPROM +// M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily). +// M502 - reverts to the default "factory settings". You still need to store them in EEPROM afterwards if you want to. +// +#define EEPROM_SETTINGS // Enable for M500 and M501 commands +//#define DISABLE_M503 // Saves ~2700 bytes of PROGMEM. Disable for release! +#define EEPROM_CHITCHAT // Give feedback on EEPROM commands. Disable to save PROGMEM. + +// +// Host Keepalive +// +// When enabled Marlin will send a busy status message to the host +// every couple of seconds when it can't accept commands. +// +#define HOST_KEEPALIVE_FEATURE // Disable this if your host doesn't like keepalive messages +#define DEFAULT_KEEPALIVE_INTERVAL 2 // Number of seconds between "busy" messages. Set with M113. +#define BUSY_WHILE_HEATING // Some hosts require "busy" messages even during heating + +// +// M100 Free Memory Watcher +// +//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose + +// +// G20/G21 Inch mode support +// +//#define INCH_MODE_SUPPORT + +// +// M149 Set temperature units support +// +//#define TEMPERATURE_UNITS_SUPPORT + +// @section temperature + +// Preheat Constants +#define PREHEAT_1_TEMP_HOTEND 210 +#define PREHEAT_1_TEMP_BED 0 +#define PREHEAT_1_FAN_SPEED 165 // Value from 0 to 255 + +#define PREHEAT_2_TEMP_HOTEND 245 +#define PREHEAT_2_TEMP_BED 0 +#define PREHEAT_2_FAN_SPEED 165 // Value from 0 to 255 + +/** + * Nozzle Park -- EXPERIMENTAL + * + * Park the nozzle at the given XYZ position on idle or G27. + * + * The "P" parameter controls the action applied to the Z axis: + * + * P0 (Default) If Z is below park Z raise the nozzle. + * P1 Raise the nozzle always to Z-park height. + * P2 Raise the nozzle by Z-park amount, limited to Z_MAX_POS. + */ +//#define NOZZLE_PARK_FEATURE + +#if ENABLED(NOZZLE_PARK_FEATURE) + // Specify a park position as { X, Y, Z } + #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 } +#endif + +/** + * Clean Nozzle Feature -- EXPERIMENTAL + * + * Adds the G12 command to perform a nozzle cleaning process. + * + * Parameters: + * P Pattern + * S Strokes / Repetitions + * T Triangles (P1 only) + * + * Patterns: + * P0 Straight line (default). This process requires a sponge type material + * at a fixed bed location. "S" specifies strokes (i.e. back-forth motions) + * between the start / end points. + * + * P1 Zig-zag pattern between (X0, Y0) and (X1, Y1), "T" specifies the + * number of zig-zag triangles to do. "S" defines the number of strokes. + * Zig-zags are done in whichever is the narrower dimension. + * For example, "G12 P1 S1 T3" will execute: + * + * -- + * | (X0, Y1) | /\ /\ /\ | (X1, Y1) + * | | / \ / \ / \ | + * A | | / \ / \ / \ | + * | | / \ / \ / \ | + * | (X0, Y0) | / \/ \/ \ | (X1, Y0) + * -- +--------------------------------+ + * |________|_________|_________| + * T1 T2 T3 + * + * P2 Circular pattern with middle at NOZZLE_CLEAN_CIRCLE_MIDDLE. + * "R" specifies the radius. "S" specifies the stroke count. + * Before starting, the nozzle moves to NOZZLE_CLEAN_START_POINT. + * + * Caveats: The ending Z should be the same as starting Z. + * Attention: EXPERIMENTAL. G-code arguments may change. + * + */ +//#define NOZZLE_CLEAN_FEATURE + +#if ENABLED(NOZZLE_CLEAN_FEATURE) + // Default number of pattern repetitions + #define NOZZLE_CLEAN_STROKES 12 + + // Default number of triangles + #define NOZZLE_CLEAN_TRIANGLES 3 + + // Specify positions as { X, Y, Z } + #define NOZZLE_CLEAN_START_POINT { 30, 30, (Z_MIN_POS + 1)} + #define NOZZLE_CLEAN_END_POINT {100, 60, (Z_MIN_POS + 1)} + + // Circular pattern radius + #define NOZZLE_CLEAN_CIRCLE_RADIUS 6.5 + // Circular pattern circle fragments number + #define NOZZLE_CLEAN_CIRCLE_FN 10 + // Middle point of circle + #define NOZZLE_CLEAN_CIRCLE_MIDDLE NOZZLE_CLEAN_START_POINT + + // Moves the nozzle to the initial position + #define NOZZLE_CLEAN_GOBACK +#endif + +/** + * Print Job Timer + * + * Automatically start and stop the print job timer on M104/M109/M190. + * + * M104 (hotend, no wait) - high temp = none, low temp = stop timer + * M109 (hotend, wait) - high temp = start timer, low temp = stop timer + * M190 (bed, wait) - high temp = start timer, low temp = none + * + * The timer can also be controlled with the following commands: + * + * M75 - Start the print job timer + * M76 - Pause the print job timer + * M77 - Stop the print job timer + */ +#define PRINTJOB_TIMER_AUTOSTART + +/** + * Print Counter + * + * Track statistical data such as: + * + * - Total print jobs + * - Total successful print jobs + * - Total failed print jobs + * - Total time printing + * + * View the current statistics with M78. + */ +//#define PRINTCOUNTER + +//============================================================================= +//============================= LCD and SD support ============================ +//============================================================================= + +// @section lcd + +/** + * LCD LANGUAGE + * + * Select the language to display on the LCD. These languages are available: + * + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, + * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * tr, uk, zh_CN, zh_TW, test + * + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + */ +#define LCD_LANGUAGE en + +/** + * LCD Character Set + * + * Note: This option is NOT applicable to Graphical Displays. + * + * All character-based LCDs provide ASCII plus one of these + * language extensions: + * + * - JAPANESE ... the most common + * - WESTERN ... with more accented characters + * - CYRILLIC ... for the Russian language + * + * To determine the language extension installed on your controller: + * + * - Compile and upload with LCD_LANGUAGE set to 'test' + * - 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 + * + * :['JAPANESE', 'WESTERN', 'CYRILLIC'] + */ +#define DISPLAY_CHARSET_HD44780 JAPANESE + +/** + * LCD TYPE + * + * Enable ULTRA_LCD for a 16x2, 16x4, 20x2, or 20x4 character-based LCD. + * Enable DOGLCD for a 128x64 (ST7565R) Full Graphical Display. + * (These options will be enabled automatically for most displays.) + * + * IMPORTANT: The U8glib library is required for Full Graphic Display! + * https://github.com/olikraus/U8glib_Arduino + */ +#define ULTRA_LCD // Character based +//#define DOGLCD // Full graphics display + +/** + * SD CARD + * + * 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 + +/** + * SD CARD: SPI SPEED + * + * Enable one of the following items for a slower SPI transfer speed. + * This may be required to resolve "volume init" errors. + */ +//#define SPI_SPEED SPI_HALF_SPEED +//#define SPI_SPEED SPI_QUARTER_SPEED +//#define SPI_SPEED SPI_EIGHTH_SPEED + +/** + * SD CARD: ENABLE CRC + * + * Use CRC checks and retries on the SD communication. + */ +//#define SD_CHECK_AND_RETRY + +// +// ENCODER SETTINGS +// +// This option overrides the default number of encoder pulses needed to +// produce one step. Should be increased for high-resolution encoders. +// +#define ENCODER_PULSES_PER_STEP 4 + +// +// Use this option to override the number of step signals required to +// move between next/prev menu items. +// +#define ENCODER_STEPS_PER_MENU_ITEM 1 + +/** + * Encoder Direction Options + * + * Test your encoder's behavior first with both options disabled. + * + * Reversed Value Edit and Menu Nav? Enable REVERSE_ENCODER_DIRECTION. + * Reversed Menu Navigation only? Enable REVERSE_MENU_DIRECTION. + * Reversed Value Editing only? Enable BOTH options. + */ + +// +// This option reverses the encoder direction everywhere. +// +// Set this option if CLOCKWISE causes values to DECREASE +// +//#define REVERSE_ENCODER_DIRECTION + +// +// This option reverses the encoder direction for navigating LCD menus. +// +// If CLOCKWISE normally moves DOWN this makes it go UP. +// If CLOCKWISE normally moves UP this makes it go DOWN. +// +#define REVERSE_MENU_DIRECTION + +// +// Individual Axis Homing +// +// Add individual axis homing items (Home X, Home Y, and Home Z) to the LCD menu. +// +//#define INDIVIDUAL_AXIS_HOMING_MENU + +// +// SPEAKER/BUZZER +// +// If you have a speaker that can produce tones, enable it here. +// By default Marlin assumes you have a buzzer with a fixed frequency. +// +//#define SPEAKER + +// +// The duration and frequency for the UI feedback sound. +// Set these to 0 to disable audio feedback in the LCD menus. +// +// Note: Test audio output with the G-Code: +// M300 S P +// +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 +//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 + +// +// CONTROLLER TYPE: Standard +// +// Marlin supports a wide variety of controllers. +// Enable one of the following options to specify your controller. +// + +// +// ULTIMAKER Controller. +// +#define ULTIMAKERCONTROLLER + +// +// ULTIPANEL as seen on Thingiverse. +// +//#define ULTIPANEL + +// +// PanelOne from T3P3 (via RAMPS 1.4 AUX2/AUX3) +// http://reprap.org/wiki/PanelOne +// +//#define PANEL_ONE + +// +// MaKr3d Makr-Panel with graphic controller and SD support. +// http://reprap.org/wiki/MaKr3d_MaKrPanel +// +//#define MAKRPANEL + +// +// ReprapWorld Graphical LCD +// https://reprapworld.com/?products_details&products_id/1218 +// +//#define REPRAPWORLD_GRAPHICAL_LCD + +// +// Activate one of these if you have a Panucatt Devices +// Viki 2.0 or mini Viki with Graphic LCD +// http://panucatt.com +// +//#define VIKI2 +//#define miniVIKI + +// +// Adafruit ST7565 Full Graphic Controller. +// https://github.com/eboston/Adafruit-ST7565-Full-Graphic-Controller/ +// +//#define ELB_FULL_GRAPHIC_CONTROLLER + +// +// RepRapDiscount Smart Controller. +// http://reprap.org/wiki/RepRapDiscount_Smart_Controller +// +// Note: Usually sold with a white PCB. +// +//#define REPRAP_DISCOUNT_SMART_CONTROLLER + +// +// GADGETS3D G3D LCD/SD Controller +// http://reprap.org/wiki/RAMPS_1.3/1.4_GADGETS3D_Shield_with_Panel +// +// Note: Usually sold with a blue PCB. +// +//#define G3D_PANEL + +// +// RepRapDiscount FULL GRAPHIC Smart Controller +// http://reprap.org/wiki/RepRapDiscount_Full_Graphic_Smart_Controller +// +//#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER + +// +// MakerLab Mini Panel with graphic +// controller and SD support - http://reprap.org/wiki/Mini_panel +// +//#define MINIPANEL + +// +// RepRapWorld REPRAPWORLD_KEYPAD v1.1 +// http://reprapworld.com/?products_details&products_id=202&cPath=1591_1626 +// +// REPRAPWORLD_KEYPAD_MOVE_STEP sets how much should the robot move when a key +// is pressed, a value of 10.0 means 10mm per click. +// +//#define REPRAPWORLD_KEYPAD +//#define REPRAPWORLD_KEYPAD_MOVE_STEP 10.0 + +// +// RigidBot Panel V1.0 +// http://www.inventapart.com/ +// +//#define RIGIDBOT_PANEL + +// +// BQ LCD Smart Controller shipped by +// default with the BQ Hephestos 2 and Witbox 2. +// +//#define BQ_LCD_SMART_CONTROLLER + +// +// Cartesio UI +// http://mauk.cc/webshop/cartesio-shop/electronics/user-interface +// +//#define CARTESIO_UI + +// +// ANET_10 Controller supported displays. +// +//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. + // This LCD is known to be susceptible to electrical interference + // which scrambles the display. Pressing any button clears it up. +//#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 + // A clone of the RepRapDiscount full graphics display but with + // different pins/wiring (see pins_ANET_10.h). + +// +// LCD for Melzi Card with Graphical LCD +// +//#define LCD_FOR_MELZI + +// +// CONTROLLER TYPE: I2C +// +// Note: These controllers require the installation of Arduino's LiquidCrystal_I2C +// library. For more info: https://github.com/kiyoshigawa/LiquidCrystal_I2C +// + +// +// Elefu RA Board Control Panel +// http://www.elefu.com/index.php?route=product/product&product_id=53 +// +//#define RA_CONTROL_PANEL + +// +// Sainsmart YW Robot (LCM1602) LCD Display +// +// Note: This controller requires F.Malpartida's LiquidCrystal_I2C library +// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home +// +//#define LCD_I2C_SAINSMART_YWROBOT + +// +// Generic LCM1602 LCD adapter +// +//#define LCM1602 + +// +// PANELOLU2 LCD with status LEDs, +// separate encoder and click inputs. +// +// Note: This controller requires Arduino's LiquidTWI2 library v1.2.3 or later. +// For more info: https://github.com/lincomatic/LiquidTWI2 +// +// Note: The PANELOLU2 encoder click input can either be directly connected to +// a pin (if BTN_ENC defined to != -1) or read through I2C (when BTN_ENC == -1). +// +//#define LCD_I2C_PANELOLU2 + +// +// Panucatt VIKI LCD with status LEDs, +// integrated click & L/R/U/D buttons, separate encoder inputs. +// +//#define LCD_I2C_VIKI + +// +// SSD1306 OLED full graphics generic display +// +//#define U8GLIB_SSD1306 + +// +// SAV OLEd LCD module support using either SSD1306 or SH1106 based LCD modules +// +//#define SAV_3DGLCD +#if ENABLED(SAV_3DGLCD) + //#define U8GLIB_SSD1306 + #define U8GLIB_SH1106 +#endif + +// +// CONTROLLER TYPE: Shift register panels +// +// 2 wire Non-latching LCD SR from https://goo.gl/aJJ4sH +// LCD configuration: http://reprap.org/wiki/SAV_3D_LCD +// +//#define SAV_3DLCD + +// +// TinyBoy2 128x64 OLED / Encoder Panel +// +//#define OLED_PANEL_TINYBOY2 + +// +// Makeboard 3D Printer Parts 3D Printer Mini Display 1602 Mini Controller +// https://www.aliexpress.com/item/Micromake-Makeboard-3D-Printer-Parts-3D-Printer-Mini-Display-1602-Mini-Controller-Compatible-with-Ramps-1/32765887917.html +// +//#define MAKEBOARD_MINI_2_LINE_DISPLAY_1602 + +// +// MKS MINI12864 with graphic controller and SD support +// http://reprap.org/wiki/MKS_MINI_12864 +// +//#define MKS_MINI_12864 + +// +// Factory display for Creality CR-10 +// https://www.aliexpress.com/item/Universal-LCD-12864-3D-Printer-Display-Screen-With-Encoder-For-CR-10-CR-7-Model/32833148327.html +// +// This is RAMPS-compatible using a single 10-pin connector. +// (For CR-10 owners who want to replace the Melzi Creality board but retain the display) +// +//#define CR10_STOCKDISPLAY + +// +// MKS OLED 1.3" 128 × 64 FULL GRAPHICS CONTROLLER +// http://reprap.org/wiki/MKS_12864OLED +// +// Tiny, but very sharp OLED display +// +//#define MKS_12864OLED + +//============================================================================= +//=============================== Extra Features ============================== +//============================================================================= + +// @section extras + +// Increase the FAN PWM frequency. Removes the PWM noise but increases heating in the FET/Arduino +//#define FAST_PWM_FAN + +// Use software PWM to drive the fan, as for the heaters. This uses a very low frequency +// which is not as annoying as with the hardware PWM. On the other hand, if this frequency +// is too low, you should also increment SOFT_PWM_SCALE. +//#define FAN_SOFT_PWM + +// Incrementing this by 1 will double the software PWM frequency, +// affecting heaters, and the fan if FAN_SOFT_PWM is enabled. +// However, control resolution will be halved for each increment; +// at zero value, there are 128 effective control positions. +#define SOFT_PWM_SCALE 0 + +// If SOFT_PWM_SCALE is set to a value higher than 0, dithering can +// be used to mitigate the associated resolution loss. If enabled, +// some of the PWM cycles are stretched so on average the desired +// duty cycle is attained. +//#define SOFT_PWM_DITHER + +// Temperature status LEDs that display the hotend and bed temperature. +// If all hotends, bed temperature, and target temperature are under 54C +// then the BLUE led is on. Otherwise the RED led is on. (1C hysteresis) +//#define TEMP_STAT_LEDS + +// M240 Triggers a camera by emulating a Canon RC-1 Remote +// Data from: http://www.doc-diy.net/photo/rc-1_hacked/ +//#define PHOTOGRAPH_PIN 23 + +// 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 + +// Support for BlinkM/CyzRgb +//#define BLINKM + +// Support for PCA9632 PWM LED driver +//#define PCA9632 + +/** + * RGB LED / LED Strip Control + * + * Enable support for an RGB LED connected to 5V digital pins, or + * an RGB Strip connected to MOSFETs controlled by digital pins. + * + * 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 overall brightness parameters is also available + * + * *** CAUTION *** + * LED Strips require a MOFSET 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! + * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino + * cannot handle such current, separate 5V power supply must be used + * *** CAUTION *** + * + * LED type. This options are mutualy exclusive. Uncomment only one. + * + */ +//#define RGB_LED +//#define RGBW_LED + +#if ENABLED(RGB_LED) || ENABLED(RGBW_LED) + #define RGB_LED_R_PIN 34 + #define RGB_LED_G_PIN 43 + #define RGB_LED_B_PIN 35 + #define RGB_LED_W_PIN -1 +#endif + +// 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 (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) + #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip + #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time + #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + //#define NEOPIXEL_STARTUP_TEST // Cycle through colors at startup +#endif + +/** + * Printer Event LEDs + * + * During printing, the LEDs will reflect the printer status: + * + * - Gradually change from blue to violet as the heated bed gets to target temp + * - Gradually change from violet to red as the hotend gets to temperature + * - Change to white to illuminate work surface + * - Change to green once print has finished + * - Turn off after the print has finished and the user has pushed a button + */ +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) + #define PRINTER_EVENT_LEDS +#endif + +/*********************************************************************\ +* R/C SERVO support +* Sponsored by TrinityLabs, Reworked by codexmas +**********************************************************************/ + +// Number of servos +// +// If you select a configuration below, this will receive a default value and does not need to be set manually +// set it manually if you have more servos than extruders and wish to manually control some +// leaving it undefined or defining as 0 will disable the servo subsystem +// If unsure, leave commented / disabled +// +//#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command + +// Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. +// 300ms is a good value but you can try less delay. +// If the servo can't reach the requested position, increase it. +#define SERVO_DELAY { 300 } + +// Servo deactivation +// +// With this option servos are powered only during movement, then turned off to prevent jitter. +//#define DEACTIVATE_SERVOS_AFTER_MOVE + +/** + * Filament Width Sensor + * + * Measures the filament width in real-time and adjusts + * flow rate to compensate for any irregularities. + * + * Also allows the measured filament diameter to set the + * extrusion rate, so the slicer only has to specify the + * volume. + * + * Only a single extruder is supported at this time. + * + * 34 RAMPS_14 : Analog input 5 on the AUX2 connector + * 81 PRINTRBOARD : Analog input 2 on the Exp1 connector (version B,C,D,E) + * 301 RAMBO : Analog input 3 + * + * Note: May require analog pins to be defined for other boards. + */ +//#define FILAMENT_WIDTH_SENSOR + +#define DEFAULT_NOMINAL_FILAMENT_DIA 3.00 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. + +#if ENABLED(FILAMENT_WIDTH_SENSOR) + #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) + #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber + + #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading + #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading + #define MAX_MEASUREMENT_DELAY 20 // (bytes) Buffer size for stored measurements (1 byte per cm). Must be larger than MEASUREMENT_DELAY_CM. + + #define DEFAULT_MEASURED_FILAMENT_DIA DEFAULT_NOMINAL_FILAMENT_DIA // Set measured to nominal initially + + // Display filament width on the LCD status line. Status messages will expire after 5 seconds. + //#define FILAMENT_LCD_DISPLAY +#endif + +#endif // CONFIGURATION_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/Velleman/K8400/README.md b/trunk/Arduino/Marlin_1.1.6/example_configurations/Velleman/K8400/README.md new file mode 100644 index 00000000..14c8f836 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/Velleman/K8400/README.md @@ -0,0 +1,15 @@ +# Configuration for Velleman K8400 Vertex +http://www.k8400.eu/ + +Configuration files for the K8400, ported upstream from the official Velleman firmware. +Like its predecessor, (K8200), the K8400 is a 3Drag clone. There are some minor differences, documented in pins_K8400.h. + +Single and dual head configurations provided. Copy the correct Configuration.h and Configuration_adv.h to the /Marlin/ directory. + +**NOTE: This configuration includes the community sourced feed rate fix. Use 100% feed rate in Repetier!** + +For implementation and updated K8400 firmware, see https://github.com/birkett/Velleman-K8400-Firmware + +### Original Sources +Credit to Velleman for the original 1.0.x based code:
    +http://www.vertex3dprinter.eu/downloads/files/vertex/firmware/vertex-m1-v1.4-h2.zip diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/adafruit/ST7565/Configuration.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/adafruit/ST7565/Configuration.h new file mode 100644 index 00000000..09354c0e --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/adafruit/ST7565/Configuration.h @@ -0,0 +1,1700 @@ +/** + * 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 . + * + */ + +/** + * Configuration.h + * + * Basic settings such as: + * + * - Type of electronics + * - Type of temperature sensor + * - Printer geometry + * - Endstop configuration + * - LCD controller + * - Extra features + * + * Advanced settings can be found in Configuration_adv.h + * + */ +#ifndef CONFIGURATION_H +#define CONFIGURATION_H +#define CONFIGURATION_H_VERSION 010100 + +//=========================================================================== +//============================= Getting Started ============================= +//=========================================================================== + +/** + * Here are some standard links for getting your machine calibrated: + * + * http://reprap.org/wiki/Calibration + * http://youtu.be/wAL9d7FgInk + * http://calculator.josefprusa.cz + * http://reprap.org/wiki/Triffid_Hunter%27s_Calibration_Guide + * http://www.thingiverse.com/thing:5573 + * https://sites.google.com/site/repraplogphase/calibration-of-your-reprap + * http://www.thingiverse.com/thing:298812 + */ + +//=========================================================================== +//============================= DELTA Printer =============================== +//=========================================================================== +// For a Delta printer start with one of the configuration files in the +// example_configurations/delta directory and customize for your machine. +// + +//=========================================================================== +//============================= SCARA Printer =============================== +//=========================================================================== +// For a SCARA printer start with the configuration files in +// example_configurations/SCARA and customize for your machine. +// + +// @section info + +// User-specified version info of this build to display in [Pronterface, etc] terminal window during +// startup. Implementation of an idea by Prof Braino to inform user that any changes made to this +// build by the user have been successfully uploaded into firmware. +#define STRING_CONFIG_H_AUTHOR "(none, default config)" // Who made the changes. +#define SHOW_BOOTSCREEN +#define STRING_SPLASH_LINE1 SHORT_BUILD_VERSION // will be shown during bootup in line 1 +#define STRING_SPLASH_LINE2 WEBSITE_URL // will be shown during bootup in line 2 + +// +// *** VENDORS PLEASE READ ***************************************************** +// +// Marlin now allow you to have a vendor boot image to be displayed on machine +// start. When SHOW_CUSTOM_BOOTSCREEN is defined Marlin will first show your +// custom boot image and then the default Marlin boot image is shown. +// +// We suggest for you to take advantage of this new feature and keep the Marlin +// boot image unmodified. For an example have a look at the bq Hephestos 2 +// example configuration folder. +// +//#define SHOW_CUSTOM_BOOTSCREEN +// @section machine + +/** + * Select which serial port on the board will be used for communication with the host. + * This allows the connection of wireless adapters (for instance) to non-default port pins. + * Serial port 0 is always used by the Arduino bootloader regardless of this setting. + * + * :[0, 1, 2, 3, 4, 5, 6, 7] + */ +#define SERIAL_PORT 0 + +/** + * This setting determines the communication speed of the printer. + * + * 250000 works in most cases, but you might try a lower speed if + * you commonly experience drop-outs during host printing. + * You may try up to 1000000 to speed up SD file transfer. + * + * :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000] + */ +#define BAUDRATE 250000 + +// Enable the Bluetooth serial interface on AT90USB devices +//#define BLUETOOTH + +// The following define selects which electronics board you have. +// Please choose the name from boards.h that matches your setup +#ifndef MOTHERBOARD + #define MOTHERBOARD BOARD_RAMPS_14_EFB +#endif + +// Optional custom name for your RepStrap or other custom machine +// Displayed in the LCD "Ready" message +//#define CUSTOM_MACHINE_NAME "3D Printer" + +// Define this to set a unique identifier for this printer, (Used by some programs to differentiate between machines) +// You can use an online service to generate a random UUID. (eg http://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] +#define EXTRUDERS 1 + +// For Cyclops or any "multi-extruder" that shares a single nozzle. +//#define SINGLENOZZLE + +/** + * Průša MK2 Single Nozzle Multi-Material Multiplexer, and variants. + * + * This device allows one stepper driver on a control board to drive + * two to eight stepper motors, one at a time, in a manner suitable + * for extruders. + * + * This option only allows the multiplexer to switch on tool-change. + * Additional options to configure custom E moves are pending. + */ +//#define MK2_MULTIPLEXER +#if ENABLED(MK2_MULTIPLEXER) + // Override the default DIO selector pins here, if needed. + // Some pins files may provide defaults for these pins. + //#define E_MUX0_PIN 40 // Always Required + //#define E_MUX1_PIN 42 // Needed for 3 to 8 steppers + //#define E_MUX2_PIN 44 // Needed for 5 to 8 steppers +#endif + +// A dual extruder that uses a single stepper motor +//#define SWITCHING_EXTRUDER +#if ENABLED(SWITCHING_EXTRUDER) + #define SWITCHING_EXTRUDER_SERVO_NR 0 + #define SWITCHING_EXTRUDER_SERVO_ANGLES { 0, 90 } // Angles for E0, E1[, E2, E3] + #if EXTRUDERS > 3 + #define SWITCHING_EXTRUDER_E23_SERVO_NR 1 + #endif +#endif + +// A dual-nozzle that uses a servomotor to raise/lower one of the nozzles +//#define SWITCHING_NOZZLE +#if ENABLED(SWITCHING_NOZZLE) + #define SWITCHING_NOZZLE_SERVO_NR 0 + #define SWITCHING_NOZZLE_SERVO_ANGLES { 0, 90 } // Angles for E0, E1 + //#define HOTEND_OFFSET_Z { 0.0, 0.0 } +#endif + +/** + * Two separate X-carriages with extruders that connect to a moving part + * via a magnetic docking mechanism. Requires SOL1_PIN and SOL2_PIN. + */ +//#define PARKING_EXTRUDER +#if ENABLED(PARKING_EXTRUDER) + #define PARKING_EXTRUDER_SOLENOIDS_INVERT // If enabled, the solenoid is NOT magnetized with applied voltage + #define PARKING_EXTRUDER_SOLENOIDS_PINS_ACTIVE LOW // LOW or HIGH pin signal energizes the coil + #define PARKING_EXTRUDER_SOLENOIDS_DELAY 250 // Delay (ms) for magnetic field. No delay if 0 or not defined. + #define PARKING_EXTRUDER_PARKING_X { -78, 184 } // X positions for parking the extruders + #define PARKING_EXTRUDER_GRAB_DISTANCE 1 // mm to move beyond the parking point to grab the extruder + #define PARKING_EXTRUDER_SECURITY_RAISE 5 // Z-raise before parking + #define HOTEND_OFFSET_Z { 0.0, 1.3 } // Z-offsets of the two hotends. The first must be 0. +#endif + +/** + * "Mixing Extruder" + * - Adds a new code, M165, to set the current mix factors. + * - Extends the stepping routines to move multiple steppers in proportion to the mix. + * - Optional support for Repetier Firmware M163, M164, and virtual extruder. + * - This implementation supports only a single extruder. + * - Enable DIRECT_MIXING_IN_G1 for Pia Taubert's reference implementation + */ +//#define MIXING_EXTRUDER +#if ENABLED(MIXING_EXTRUDER) + #define MIXING_STEPPERS 2 // Number of steppers in your mixing extruder + #define MIXING_VIRTUAL_TOOLS 16 // Use the Virtual Tool method with M163 and M164 + //#define DIRECT_MIXING_IN_G1 // Allow ABCDHI mix factors in G1 movement commands +#endif + +// Offset of the extruders (uncomment if using more than one and relying on firmware to position when changing). +// The offset has to be X=0, Y=0 for the extruder 0 hotend (default extruder). +// For the other hotends it is their distance from the extruder 0 hotend. +//#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis +//#define HOTEND_OFFSET_Y {0.0, 5.00} // (in mm) for each extruder, offset of the hotend on the Y axis + +// @section machine + +/** + * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN + * + * 0 = No Power Switch + * 1 = ATX + * 2 = X-Box 360 203Watts (the blue wire connected to PS_ON and the red wire to VCC) + * + * :{ 0:'No power switch', 1:'ATX', 2:'X-Box 360' } + */ +#define POWER_SUPPLY 1 + +#if POWER_SUPPLY > 0 + // Enable this option to leave the PSU off at startup. + // Power to steppers and heaters will need to be turned on with M80. + //#define PS_DEFAULT_OFF +#endif + +// @section temperature + +//=========================================================================== +//============================= Thermal Settings ============================ +//=========================================================================== + +/** + * --NORMAL IS 4.7kohm PULLUP!-- 1kohm pullup can be used on hotend sensor, using correct resistor and table + * + * Temperature sensors available: + * + * -3 : thermocouple with MAX31855 (only for sensor 0) + * -2 : thermocouple with MAX6675 (only for sensor 0) + * -1 : thermocouple with AD595 + * 0 : not used + * 1 : 100k thermistor - best choice for EPCOS 100k (4.7k pullup) + * 2 : 200k thermistor - ATC Semitec 204GT-2 (4.7k pullup) + * 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 (Used in ParCan & J-Head) (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) + * 71 : 100k Honeywell thermistor 135-104LAF-J01 (4.7k pullup) + * 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) + * 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" + * 20 : the PT100 circuit found in the Ultimainboard V2.x + * 60 : 100k Maker's Tool Works Kapton Bed Thermistor beta=3950 + * 66 : 4.7M High Temperature thermistor from Dyze Design + * 70 : the 100K thermistor found in the bq Hephestos 2 + * 75 : 100k Generic Silicon Heat Pad with NTC 100K MGB18-104F39050L32 thermistor + * + * 1k ohm pullup tables - This is atypical, and requires changing out the 4.7k pullup for 1k. + * (but gives greater accuracy and more stable PID) + * 51 : 100k thermistor - EPCOS (1k pullup) + * 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 + * 1010 : Pt1000 with 1k pullup (non standard) + * 147 : Pt100 with 4k7 pullup + * 110 : Pt100 with 1k pullup (non standard) + * + * Use these for Testing or Development purposes. NEVER for production machine. + * 998 : Dummy Table that ALWAYS reads 25°C or the temperature defined below. + * 999 : Dummy Table that ALWAYS reads 100°C or the temperature defined below. + * + * :{ '0': "Not used", '1':"100k / 4.7k - EPCOS", '2':"200k / 4.7k - ATC Semitec 204GT-2", '3':"Mendel-parts / 4.7k", '4':"10k !! do not use for a hotend. Bad resolution at high temp. !!", '5':"100K / 4.7k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '6':"100k / 4.7k EPCOS - Not as accurate as Table 1", '7':"100k / 4.7k Honeywell 135-104LAG-J01", '8':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT", '9':"100k / 4.7k GE Sensing AL03006-58.2K-97-G1", '10':"100k / 4.7k RS 198-961", '11':"100k / 4.7k beta 3950 1%", '12':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT (calibrated for Makibox hot bed)", '13':"100k Hisens 3950 1% up to 300°C for hotend 'Simple ONE ' & hotend 'All In ONE'", '20':"PT100 (Ultimainboard V2.x)", '51':"100k / 1k - EPCOS", '52':"200k / 1k - ATC Semitec 204GT-2", '55':"100k / 1k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '60':"100k Maker's Tool Works Kapton Bed Thermistor beta=3950", '66':"Dyze Design 4.7M High Temperature thermistor", '70':"the 100K thermistor found in the bq Hephestos 2", '71':"100k / 4.7k Honeywell 135-104LAF-J01", '147':"Pt100 / 4.7k", '1047':"Pt1000 / 4.7k", '110':"Pt100 / 1k (non-standard)", '1010':"Pt1000 / 1k (non standard)", '-3':"Thermocouple + MAX31855 (only for sensor 0)", '-2':"Thermocouple + MAX6675 (only for sensor 0)", '-1':"Thermocouple + AD595",'998':"Dummy 1", '999':"Dummy 2" } + */ +#define TEMP_SENSOR_0 1 +#define TEMP_SENSOR_1 0 +#define TEMP_SENSOR_2 0 +#define TEMP_SENSOR_3 0 +#define TEMP_SENSOR_4 0 +#define TEMP_SENSOR_BED 0 + +// Dummy thermistor constant temperature readings, for use with 998 and 999 +#define DUMMY_THERMISTOR_998_VALUE 25 +#define DUMMY_THERMISTOR_999_VALUE 100 + +// 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 +#define MAX_REDUNDANT_TEMP_SENSOR_DIFF 10 + +// Extruder temperature must be close to target for this long before M109 returns success +#define TEMP_RESIDENCY_TIME 10 // (seconds) +#define TEMP_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// Bed temperature must be close to target for this long before M190 returns success +#define TEMP_BED_RESIDENCY_TIME 0 // (seconds) +#define TEMP_BED_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_BED_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// The minimal temperature defines the temperature below which the heater will not be enabled It is used +// to check that the wiring to the thermistor is not broken. +// Otherwise this would lead to the heater being powered on all the time. +#define HEATER_0_MINTEMP 5 +#define HEATER_1_MINTEMP 5 +#define HEATER_2_MINTEMP 5 +#define HEATER_3_MINTEMP 5 +#define HEATER_4_MINTEMP 5 +#define BED_MINTEMP 5 + +// When temperature exceeds max temp, your heater will be switched off. +// This feature exists to protect your hotend from overheating accidentally, but *NOT* from thermistor short/failure! +// You should use MINTEMP for thermistor short/failure protection. +#define HEATER_0_MAXTEMP 275 +#define HEATER_1_MAXTEMP 275 +#define HEATER_2_MAXTEMP 275 +#define HEATER_3_MAXTEMP 275 +#define HEATER_4_MAXTEMP 275 +#define BED_MAXTEMP 150 + +//=========================================================================== +//============================= PID Settings ================================ +//=========================================================================== +// PID Tuning Guide here: http://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 +#if ENABLED(PIDTEMP) + //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. + //#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. + #define K1 0.95 //smoothing factor within the PID + + // 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 + +#endif // PIDTEMP + +//=========================================================================== +//============================= PID > Bed Temperature Control =============== +//=========================================================================== +// Select PID or bang-bang with PIDTEMPBED. If bang-bang, BED_LIMIT_SWITCHING will enable hysteresis +// +// Uncomment this to enable PID on the bed. It uses the same frequency PWM as the extruder. +// If your PID_dT is the default, and correct for your hardware/configuration, that means 7.689Hz, +// which is fine for driving a square wave into a resistive load and does not significantly impact you FET heating. +// This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W heater. +// If your configuration is significantly different than this and you don't understand the issues involved, you probably +// shouldn't use bed PID until someone else verifies your hardware works. +// If this is enabled, find your own PID constants below. +//#define PIDTEMPBED + +//#define BED_LIMIT_SWITCHING + +// This sets the max power delivered to the bed, and replaces the HEATER_BED_DUTY_CYCLE_DIVIDER option. +// all forms of bed control obey this (PID, bang-bang, bang-bang with hysteresis) +// setting this to anything other than 255 enables a form of PWM to the bed just like HEATER_BED_DUTY_CYCLE_DIVIDER did, +// so you shouldn't use it unless you are OK with PWM on your bed. (see the comment on enabling PIDTEMPBED) +#define MAX_BED_POWER 255 // limits duty cycle to bed; 255=full current + +#if ENABLED(PIDTEMPBED) + + //#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) + #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 + +// @section extruder + +// This option prevents extrusion if the temperature is below EXTRUDE_MINTEMP. +// It also enables the M302 command to set the minimum extrusion temperature +// or to allow moving the extruder regardless of the hotend temperature. +// *** IT IS HIGHLY RECOMMENDED TO LEAVE THIS OPTION ENABLED! *** +#define PREVENT_COLD_EXTRUSION +#define EXTRUDE_MINTEMP 170 + +// This option prevents a single extrusion longer than EXTRUDE_MAXLENGTH. +// Note that for Bowden Extruders a too-small value here may prevent loading. +#define PREVENT_LENGTHY_EXTRUDE +#define EXTRUDE_MAXLENGTH 200 + +//=========================================================================== +//======================== Thermal Runaway Protection ======================= +//=========================================================================== + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * If you get "Thermal Runaway" or "Heating failed" errors the + * details can be tuned in Configuration_adv.h + */ + +#define THERMAL_PROTECTION_HOTENDS // Enable thermal protection for all extruders +#define THERMAL_PROTECTION_BED // Enable thermal protection for the heated bed + +//=========================================================================== +//============================= Mechanical Settings ========================= +//=========================================================================== + +// @section machine + +// Uncomment one of these options to enable CoreXY, CoreXZ, or CoreYZ kinematics +// either in the usual order or reversed +//#define COREXY +//#define COREXZ +//#define COREYZ +//#define COREYX +//#define COREZX +//#define COREZY + +//=========================================================================== +//============================== Endstop Settings =========================== +//=========================================================================== + +// @section homing + +// Specify here all the endstop connectors that are connected to any endstop or probe. +// Almost all printers will be using one per axis. Probes will use one or more of the +// extra connectors. Leave undefined any used for non-endstop and non-probe purposes. +#define USE_XMIN_PLUG +#define USE_YMIN_PLUG +#define USE_ZMIN_PLUG +//#define USE_XMAX_PLUG +//#define USE_YMAX_PLUG +//#define USE_ZMAX_PLUG + +// coarse Endstop Settings +#define ENDSTOPPULLUPS // Comment this out (using // at the start of the line) to disable the endstop pullup resistors + +#if DISABLED(ENDSTOPPULLUPS) + // fine endstop settings: Individual pullups. will be ignored if ENDSTOPPULLUPS is defined + //#define ENDSTOPPULLUP_XMAX + //#define ENDSTOPPULLUP_YMAX + //#define ENDSTOPPULLUP_ZMAX + //#define ENDSTOPPULLUP_XMIN + //#define ENDSTOPPULLUP_YMIN + //#define ENDSTOPPULLUP_ZMIN + //#define ENDSTOPPULLUP_ZMIN_PROBE +#endif + +// Mechanical endstop with COM to ground and NC to Signal uses "false" here (most common setup). +#define X_MIN_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Y_MIN_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MIN_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define X_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Y_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MIN_PROBE_ENDSTOP_INVERTING false // set to true to invert the logic of the probe. + +// Enable this feature if all enabled endstop pins are interrupt-capable. +// This will remove the need to poll the interrupt pins, saving many CPU cycles. +//#define ENDSTOP_INTERRUPTS_FEATURE + +//============================================================================= +//============================== Movement Settings ============================ +//============================================================================= +// @section motion + +/** + * Default Settings + * + * These settings can be reset by M502 + * + * Note that if EEPROM is enabled, saved values will override these. + */ + +/** + * With this option each E stepper can have its own factors for the + * following movement settings. If fewer factors are given than the + * total number of extruders, the last value applies to the rest. + */ +//#define DISTINCT_E_FACTORS + +/** + * Default Axis Steps Per Unit (steps/mm) + * Override with M92 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_AXIS_STEPS_PER_UNIT { 80, 80, 4000, 500 } + +/** + * Default Max Feed Rate (mm/s) + * Override with M203 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_FEEDRATE { 300, 300, 5, 25 } + +/** + * Default Max Acceleration (change/s) change = mm/s + * (Maximum start speed for accelerated moves) + * Override with M201 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_ACCELERATION { 3000, 3000, 100, 10000 } + +/** + * Default Acceleration (change/s) change = mm/s + * Override with M204 + * + * M204 P Acceleration + * M204 R Retract Acceleration + * M204 T Travel Acceleration + */ +#define DEFAULT_ACCELERATION 3000 // X, Y, Z and E acceleration for printing moves +#define DEFAULT_RETRACT_ACCELERATION 3000 // E acceleration for retracts +#define DEFAULT_TRAVEL_ACCELERATION 3000 // X, Y, Z acceleration for travel (non printing) moves + +/** + * Default Jerk (mm/s) + * Override with M205 X Y Z E + * + * "Jerk" specifies the minimum speed change that requires acceleration. + * When changing speed and direction, if the difference is less than the + * value set here, it may happen instantaneously. + */ +#define DEFAULT_XJERK 20.0 +#define DEFAULT_YJERK 20.0 +#define DEFAULT_ZJERK 0.4 +#define DEFAULT_EJERK 5.0 + +//=========================================================================== +//============================= Z Probe Options ============================= +//=========================================================================== +// @section probes + +// +// See http://marlinfw.org/configuration/probes.html +// + +/** + * Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + * + * Enable this option for a probe connected to the Z Min endstop pin. + */ +#define Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + +/** + * Z_MIN_PROBE_ENDSTOP + * + * Enable this option for a probe connected to any pin except Z-Min. + * (By default Marlin assumes the Z-Max endstop pin.) + * To use a custom Z Probe pin, set Z_MIN_PROBE_PIN below. + * + * - The simplest option is to use a free endstop connector. + * - Use 5V for powered (usually inductive) sensors. + * + * - RAMPS 1.3/1.4 boards may use the 5V, GND, and Aux4->D32 pin: + * - For simple switches connect... + * - normally-closed switches to GND and D32. + * - normally-open switches to 5V and D32. + * + * WARNING: Setting the wrong pin may have unexpected and potentially + * disastrous consequences. Use with caution and do your homework. + * + */ +//#define Z_MIN_PROBE_ENDSTOP + +/** + * Probe Type + * + * Allen Key Probes, Servo Probes, Z-Sled Probes, FIX_MOUNTED_PROBE, etc. + * Activate one of these to use Auto Bed Leveling below. + */ + +/** + * The "Manual Probe" provides a means to do "Auto" Bed Leveling without a probe. + * Use G29 repeatedly, adjusting the Z height at each point with movement commands + * or (with LCD_BED_LEVELING) the LCD controller. + */ +//#define PROBE_MANUALLY + +/** + * A Fix-Mounted Probe either doesn't deploy or needs manual deployment. + * (e.g., an inductive probe or a nozzle-based probe-switch.) + */ +//#define FIX_MOUNTED_PROBE + +/** + * Z Servo Probe, such as an endstop switch on a rotating arm. + */ +//#define Z_ENDSTOP_SERVO_NR 0 // Defaults to SERVO 0 connector. +//#define Z_SERVO_ANGLES {70,0} // Z Servo Deploy and Stow angles + +/** + * The BLTouch probe uses a Hall effect sensor and emulates a servo. + */ +//#define BLTOUCH +#if ENABLED(BLTOUCH) + //#define BLTOUCH_DELAY 375 // (ms) Enable and increase if needed +#endif + +/** + * Enable one or more of the following if probing seems unreliable. + * Heaters and/or fans can be disabled during probing to minimize electrical + * noise. A delay can also be added to allow noise and vibration to settle. + * These options are most useful for the BLTouch probe, but may also improve + * readings with inductive probes and piezo sensors. + */ +//#define PROBING_HEATERS_OFF // Turn heaters off when probing +//#define PROBING_FANS_OFF // Turn fans off when probing +//#define DELAY_BEFORE_PROBING 200 // (ms) To prevent vibrations from triggering piezo sensors + +// A probe that is deployed and stowed with a solenoid pin (SOL1_PIN) +//#define SOLENOID_PROBE + +// A sled-mounted probe like those designed by Charles Bell. +//#define Z_PROBE_SLED +//#define SLED_DOCKING_OFFSET 5 // The extra distance the X axis must travel to pickup the sled. 0 should be fine but you can push it further if you'd like. + +// +// For Z_PROBE_ALLEN_KEY see the Delta example configurations. +// + +/** + * Z Probe to nozzle (X,Y) offset, relative to (0, 0). + * X and Y offsets must be integers. + * + * In the following example the X and Y offsets are both positive: + * #define X_PROBE_OFFSET_FROM_EXTRUDER 10 + * #define Y_PROBE_OFFSET_FROM_EXTRUDER 10 + * + * +-- BACK ---+ + * | | + * L | (+) P | R <-- probe (20,20) + * E | | I + * F | (-) N (+) | G <-- nozzle (10,10) + * T | | H + * | (-) | T + * | | + * O-- FRONT --+ + * (0,0) + */ +#define X_PROBE_OFFSET_FROM_EXTRUDER -25 // X offset: -left +right [of the nozzle] +#define Y_PROBE_OFFSET_FROM_EXTRUDER -29 // Y offset: -front +behind [the nozzle] +#define Z_PROBE_OFFSET_FROM_EXTRUDER -12.35 // Z offset: -below +above [the nozzle] + +// X and Y axis travel speed (mm/m) between probes +#define XY_PROBE_SPEED 8000 + +// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +#define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z + +// Speed for the "accurate" probe of each point +#define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) + +// Use double touch for probing +//#define PROBE_DOUBLE_TOUCH + +/** + * Z probes require clearance when deploying, stowing, and moving between + * probe points to avoid hitting the bed and other hardware. + * Servo-mounted probes require extra space for the arm to rotate. + * Inductive probes need space to keep from triggering early. + * + * Use these settings to specify the distance (mm) to raise the probe (or + * lower the bed). The values set here apply over and above any (negative) + * probe Z Offset set with Z_PROBE_OFFSET_FROM_EXTRUDER, M851, or the LCD. + * Only integer values >= 1 are valid here. + * + * Example: `M851 Z-5` with a CLEARANCE of 4 => 9mm from bed to nozzle. + * But: `M851 Z+1` with a CLEARANCE of 2 => 2mm from bed to nozzle. + */ +#define Z_CLEARANCE_DEPLOY_PROBE 15 // Z Clearance for Deploy/Stow +#define Z_CLEARANCE_BETWEEN_PROBES 5 // Z Clearance between probe points + +// For M851 give a range for adjusting the Z probe offset +#define Z_PROBE_OFFSET_RANGE_MIN -20 +#define Z_PROBE_OFFSET_RANGE_MAX 20 + +// Enable the M48 repeatability test to test probe accuracy +//#define Z_MIN_PROBE_REPEATABILITY_TEST + +// For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1 +// :{ 0:'Low', 1:'High' } +#define X_ENABLE_ON 0 +#define Y_ENABLE_ON 0 +#define Z_ENABLE_ON 0 +#define E_ENABLE_ON 0 // For all extruders + +// Disables axis stepper immediately when it's not being used. +// 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 +//#define DISABLE_REDUCED_ACCURACY_WARNING + +// @section extruder + +#define DISABLE_E false // For all extruders +#define DISABLE_INACTIVE_EXTRUDER true // Keep only the active extruder enabled. + +// @section machine + +// Invert the stepper direction. Change (or reverse the motor connector) if an axis goes the wrong way. +#define INVERT_X_DIR false +#define INVERT_Y_DIR true +#define INVERT_Z_DIR false + +// Enable this option for Toshiba stepper drivers +//#define CONFIG_STEPPERS_TOSHIBA + +// @section extruder + +// For direct drive extruder v9 set to true, for geared extruder set to false. +#define INVERT_E0_DIR false +#define INVERT_E1_DIR false +#define INVERT_E2_DIR false +#define INVERT_E3_DIR false +#define INVERT_E4_DIR false + +// @section homing + +//#define NO_MOTION_BEFORE_HOMING // Inhibit movement until all axes have been homed + +//#define Z_HOMING_HEIGHT 4 // (in mm) Minimal z height before homing (G28) for Z clearance above the bed, clamps, ... + // Be sure you have this distance over your Z_MAX_POS in case. + +// Direction of endstops when homing; 1=MAX, -1=MIN +// :[-1,1] +#define X_HOME_DIR -1 +#define Y_HOME_DIR -1 +#define Z_HOME_DIR -1 + +// @section machine + +// The size of the print bed +#define X_BED_SIZE 200 +#define Y_BED_SIZE 200 + +// Travel limits (mm) after homing, corresponding to endstop positions. +#define X_MIN_POS 0 +#define Y_MIN_POS 0 +#define Z_MIN_POS 0 +#define X_MAX_POS X_BED_SIZE +#define Y_MAX_POS Y_BED_SIZE +#define Z_MAX_POS 200 + +// If enabled, axes won't move below MIN_POS in response to movement commands. +#define MIN_SOFTWARE_ENDSTOPS +// If enabled, axes won't move above MAX_POS in response to movement commands. +#define MAX_SOFTWARE_ENDSTOPS + +/** + * Filament Runout Sensor + * A mechanical or opto endstop is used to check for the presence of filament. + * + * RAMPS-based boards use SERVO3_PIN. + * For other boards you may need to define FIL_RUNOUT_PIN. + * By default the firmware assumes HIGH = has filament, LOW = ran out + */ +//#define FILAMENT_RUNOUT_SENSOR +#if ENABLED(FILAMENT_RUNOUT_SENSOR) + #define FIL_RUNOUT_INVERTING false // set to true to invert the logic of the sensor. + #define ENDSTOPPULLUP_FIL_RUNOUT // Uncomment to use internal pullup for filament runout pins if the sensor is defined. + #define FILAMENT_RUNOUT_SCRIPT "M600" +#endif + +//=========================================================================== +//=============================== Bed Leveling ============================== +//=========================================================================== +// @section bedlevel + +/** + * Choose one of the options below to enable G29 Bed Leveling. The parameters + * and behavior of G29 will change depending on your selection. + * + * If using a Probe for Z Homing, enable Z_SAFE_HOMING also! + * + * - AUTO_BED_LEVELING_3POINT + * Probe 3 arbitrary points on the bed (that aren't collinear) + * You specify the XY coordinates of all 3 points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_LINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_BILINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a mesh, best for large or uneven beds. + * + * - AUTO_BED_LEVELING_UBL (Unified Bed Leveling) + * A comprehensive bed leveling system combining the features and benefits + * of other systems. UBL also includes integrated Mesh Generation, Mesh + * Validation and Mesh Editing systems. Currently, UBL is only checked out + * for Cartesian Printers. That said, it was primarily designed to correct + * poor quality Delta Printers. If you feel adventurous and have a Delta, + * please post an issue if something doesn't work correctly. Initially, + * you will need to set a reduced bed size so you have a rectangular area + * to test on. + * + * - MESH_BED_LEVELING + * Probe a grid manually + * The result is a mesh, suitable for large or uneven beds. (See BILINEAR.) + * For machines without a probe, Mesh Bed Leveling provides a method to perform + * leveling in steps so you can manually adjust the Z height at each grid-point. + * With an LCD controller the process is guided step-by-step. + */ +//#define AUTO_BED_LEVELING_3POINT +//#define AUTO_BED_LEVELING_LINEAR +//#define AUTO_BED_LEVELING_BILINEAR +//#define AUTO_BED_LEVELING_UBL +//#define MESH_BED_LEVELING + +/** + * Enable detailed logging of G28, G29, M48, etc. + * Turn on with the command 'M111 S32'. + * NOTE: Requires a lot of PROGMEM! + */ +//#define DEBUG_LEVELING_FEATURE + +#if ENABLED(MESH_BED_LEVELING) || ENABLED(AUTO_BED_LEVELING_BILINEAR) || ENABLED(AUTO_BED_LEVELING_UBL) + // Gradually reduce leveling correction until a set height is reached, + // at which point movement will be level to the machine's XY plane. + // The height can be set with M420 Z + #define ENABLE_LEVELING_FADE_HEIGHT +#endif + +#if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Set the number of grid points per dimension. + #define GRID_MAX_POINTS_X 3 + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + // Set the boundaries for probing (where the probe can reach). + #define LEFT_PROBE_BED_POSITION 15 + #define RIGHT_PROBE_BED_POSITION 170 + #define FRONT_PROBE_BED_POSITION 20 + #define BACK_PROBE_BED_POSITION 170 + + // The Z probe minimum outer margin (to validate G29 parameters). + #define MIN_PROBE_EDGE 10 + + // Probe along the Y axis, advancing X after each column + //#define PROBE_Y_FIRST + + #if ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Beyond the probed grid, continue the implied tilt? + // Default is to maintain the height of the nearest edge. + //#define EXTRAPOLATE_BEYOND_GRID + + // + // Experimental Subdivision of the grid by Catmull-Rom method. + // Synthesizes intermediate points to produce a more detailed mesh. + // + //#define ABL_BILINEAR_SUBDIVISION + #if ENABLED(ABL_BILINEAR_SUBDIVISION) + // Number of subdivisions between probe points + #define BILINEAR_SUBDIVISIONS 3 + #endif + + #endif + +#elif ENABLED(AUTO_BED_LEVELING_3POINT) + + // 3 arbitrary points to probe. + // A simple cross-product is used to estimate the plane of the bed. + #define ABL_PROBE_PT_1_X 15 + #define ABL_PROBE_PT_1_Y 180 + #define ABL_PROBE_PT_2_X 15 + #define ABL_PROBE_PT_2_Y 20 + #define ABL_PROBE_PT_3_X 170 + #define ABL_PROBE_PT_3_Y 20 + +#elif ENABLED(AUTO_BED_LEVELING_UBL) + + //=========================================================================== + //========================= Unified Bed Leveling ============================ + //=========================================================================== + + #define UBL_MESH_INSET 1 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 10 // Don't use more than 15 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + #define UBL_PROBE_PT_1_X 39 // Probing points for 3-Point leveling of the mesh + #define UBL_PROBE_PT_1_Y 180 + #define UBL_PROBE_PT_2_X 39 + #define UBL_PROBE_PT_2_Y 20 + #define UBL_PROBE_PT_3_X 180 + #define UBL_PROBE_PT_3_Y 20 + + #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation + #define UBL_MESH_EDIT_MOVES_Z // Sophisticated users prefer no movement of nozzle + +#elif ENABLED(MESH_BED_LEVELING) + + //=========================================================================== + //=================================== Mesh ================================== + //=========================================================================== + + #define MESH_INSET 10 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 3 // Don't use more than 7 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + //#define MESH_G28_REST_ORIGIN // After homing all axes ('G28' or 'G28 XYZ') rest Z at Z_MIN_POS + +#endif // BED_LEVELING + +/** + * Use the LCD controller for bed leveling + * Requires MESH_BED_LEVELING or PROBE_MANUALLY + */ +//#define LCD_BED_LEVELING + +#if ENABLED(LCD_BED_LEVELING) + #define MBL_Z_STEP 0.025 // Step size while manually probing Z axis. + #define LCD_PROBE_Z_RANGE 4 // Z Range centered on Z_MIN_POS for LCD Z adjustment +#endif + +// Add a menu item to move between bed corners for manual bed adjustment +//#define LEVEL_BED_CORNERS + +/** + * Commands to execute at the end of G29 probing. + * Useful to retract or move the Z probe out of the way. + */ +//#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) +//#define BED_CENTER_AT_0_0 + +// Manually set the home position. Leave these undefined for automatic settings. +// For DELTA this is the top-center of the Cartesian print volume. +//#define MANUAL_X_HOME_POS 0 +//#define MANUAL_Y_HOME_POS 0 +//#define MANUAL_Z_HOME_POS 0 + +// Use "Z Safe Homing" to avoid homing with a Z probe outside the bed area. +// +// With this feature enabled: +// +// - 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). +// - 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 axis (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). +#endif + +// Homing speeds (mm/m) +#define HOMING_FEEDRATE_XY (50*60) +#define HOMING_FEEDRATE_Z (4*60) + +//============================================================================= +//============================= Additional Features =========================== +//============================================================================= + +// @section extras + +// +// EEPROM +// +// The microcontroller can store settings in the EEPROM, e.g. max velocity... +// M500 - stores parameters in EEPROM +// M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily). +// M502 - reverts to the default "factory settings". You still need to store them in EEPROM afterwards if you want to. +// +//#define EEPROM_SETTINGS // Enable for M500 and M501 commands +//#define DISABLE_M503 // Saves ~2700 bytes of PROGMEM. Disable for release! +#define EEPROM_CHITCHAT // Give feedback on EEPROM commands. Disable to save PROGMEM. + +// +// Host Keepalive +// +// When enabled Marlin will send a busy status message to the host +// every couple of seconds when it can't accept commands. +// +#define HOST_KEEPALIVE_FEATURE // Disable this if your host doesn't like keepalive messages +#define DEFAULT_KEEPALIVE_INTERVAL 2 // Number of seconds between "busy" messages. Set with M113. +#define BUSY_WHILE_HEATING // Some hosts require "busy" messages even during heating + +// +// M100 Free Memory Watcher +// +//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose + +// +// G20/G21 Inch mode support +// +//#define INCH_MODE_SUPPORT + +// +// M149 Set temperature units support +// +//#define TEMPERATURE_UNITS_SUPPORT + +// @section temperature + +// Preheat Constants +#define PREHEAT_1_TEMP_HOTEND 180 +#define PREHEAT_1_TEMP_BED 70 +#define PREHEAT_1_FAN_SPEED 0 // Value from 0 to 255 + +#define PREHEAT_2_TEMP_HOTEND 240 +#define PREHEAT_2_TEMP_BED 110 +#define PREHEAT_2_FAN_SPEED 0 // Value from 0 to 255 + +/** + * Nozzle Park -- EXPERIMENTAL + * + * Park the nozzle at the given XYZ position on idle or G27. + * + * The "P" parameter controls the action applied to the Z axis: + * + * P0 (Default) If Z is below park Z raise the nozzle. + * P1 Raise the nozzle always to Z-park height. + * P2 Raise the nozzle by Z-park amount, limited to Z_MAX_POS. + */ +//#define NOZZLE_PARK_FEATURE + +#if ENABLED(NOZZLE_PARK_FEATURE) + // Specify a park position as { X, Y, Z } + #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 } +#endif + +/** + * Clean Nozzle Feature -- EXPERIMENTAL + * + * Adds the G12 command to perform a nozzle cleaning process. + * + * Parameters: + * P Pattern + * S Strokes / Repetitions + * T Triangles (P1 only) + * + * Patterns: + * P0 Straight line (default). This process requires a sponge type material + * at a fixed bed location. "S" specifies strokes (i.e. back-forth motions) + * between the start / end points. + * + * P1 Zig-zag pattern between (X0, Y0) and (X1, Y1), "T" specifies the + * number of zig-zag triangles to do. "S" defines the number of strokes. + * Zig-zags are done in whichever is the narrower dimension. + * For example, "G12 P1 S1 T3" will execute: + * + * -- + * | (X0, Y1) | /\ /\ /\ | (X1, Y1) + * | | / \ / \ / \ | + * A | | / \ / \ / \ | + * | | / \ / \ / \ | + * | (X0, Y0) | / \/ \/ \ | (X1, Y0) + * -- +--------------------------------+ + * |________|_________|_________| + * T1 T2 T3 + * + * P2 Circular pattern with middle at NOZZLE_CLEAN_CIRCLE_MIDDLE. + * "R" specifies the radius. "S" specifies the stroke count. + * Before starting, the nozzle moves to NOZZLE_CLEAN_START_POINT. + * + * Caveats: The ending Z should be the same as starting Z. + * Attention: EXPERIMENTAL. G-code arguments may change. + * + */ +//#define NOZZLE_CLEAN_FEATURE + +#if ENABLED(NOZZLE_CLEAN_FEATURE) + // Default number of pattern repetitions + #define NOZZLE_CLEAN_STROKES 12 + + // Default number of triangles + #define NOZZLE_CLEAN_TRIANGLES 3 + + // Specify positions as { X, Y, Z } + #define NOZZLE_CLEAN_START_POINT { 30, 30, (Z_MIN_POS + 1)} + #define NOZZLE_CLEAN_END_POINT {100, 60, (Z_MIN_POS + 1)} + + // Circular pattern radius + #define NOZZLE_CLEAN_CIRCLE_RADIUS 6.5 + // Circular pattern circle fragments number + #define NOZZLE_CLEAN_CIRCLE_FN 10 + // Middle point of circle + #define NOZZLE_CLEAN_CIRCLE_MIDDLE NOZZLE_CLEAN_START_POINT + + // Moves the nozzle to the initial position + #define NOZZLE_CLEAN_GOBACK +#endif + +/** + * Print Job Timer + * + * Automatically start and stop the print job timer on M104/M109/M190. + * + * M104 (hotend, no wait) - high temp = none, low temp = stop timer + * M109 (hotend, wait) - high temp = start timer, low temp = stop timer + * M190 (bed, wait) - high temp = start timer, low temp = none + * + * The timer can also be controlled with the following commands: + * + * M75 - Start the print job timer + * M76 - Pause the print job timer + * M77 - Stop the print job timer + */ +#define PRINTJOB_TIMER_AUTOSTART + +/** + * Print Counter + * + * Track statistical data such as: + * + * - Total print jobs + * - Total successful print jobs + * - Total failed print jobs + * - Total time printing + * + * View the current statistics with M78. + */ +//#define PRINTCOUNTER + +//============================================================================= +//============================= LCD and SD support ============================ +//============================================================================= + +// @section lcd + +/** + * LCD LANGUAGE + * + * Select the language to display on the LCD. These languages are available: + * + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, + * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * tr, uk, zh_CN, zh_TW, test + * + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + */ +#define LCD_LANGUAGE en + +/** + * LCD Character Set + * + * Note: This option is NOT applicable to Graphical Displays. + * + * All character-based LCDs provide ASCII plus one of these + * language extensions: + * + * - JAPANESE ... the most common + * - WESTERN ... with more accented characters + * - CYRILLIC ... for the Russian language + * + * To determine the language extension installed on your controller: + * + * - Compile and upload with LCD_LANGUAGE set to 'test' + * - 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 + * + * :['JAPANESE', 'WESTERN', 'CYRILLIC'] + */ +#define DISPLAY_CHARSET_HD44780 JAPANESE + +/** + * LCD TYPE + * + * Enable ULTRA_LCD for a 16x2, 16x4, 20x2, or 20x4 character-based LCD. + * Enable DOGLCD for a 128x64 (ST7565R) Full Graphical Display. + * (These options will be enabled automatically for most displays.) + * + * IMPORTANT: The U8glib library is required for Full Graphic Display! + * https://github.com/olikraus/U8glib_Arduino + */ +//#define ULTRA_LCD // Character based +//#define DOGLCD // Full graphics display + +/** + * SD CARD + * + * 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 + +/** + * SD CARD: SPI SPEED + * + * Enable one of the following items for a slower SPI transfer speed. + * This may be required to resolve "volume init" errors. + */ +#define SPI_SPEED SPI_HALF_SPEED +//#define SPI_SPEED SPI_QUARTER_SPEED +//#define SPI_SPEED SPI_EIGHTH_SPEED + +/** + * SD CARD: ENABLE CRC + * + * Use CRC checks and retries on the SD communication. + */ +//#define SD_CHECK_AND_RETRY + +// +// ENCODER SETTINGS +// +// This option overrides the default number of encoder pulses needed to +// produce one step. Should be increased for high-resolution encoders. +// +//#define ENCODER_PULSES_PER_STEP 1 + +// +// Use this option to override the number of step signals required to +// move between next/prev menu items. +// +//#define ENCODER_STEPS_PER_MENU_ITEM 5 + +/** + * Encoder Direction Options + * + * Test your encoder's behavior first with both options disabled. + * + * Reversed Value Edit and Menu Nav? Enable REVERSE_ENCODER_DIRECTION. + * Reversed Menu Navigation only? Enable REVERSE_MENU_DIRECTION. + * Reversed Value Editing only? Enable BOTH options. + */ + +// +// This option reverses the encoder direction everywhere. +// +// Set this option if CLOCKWISE causes values to DECREASE +// +//#define REVERSE_ENCODER_DIRECTION + +// +// This option reverses the encoder direction for navigating LCD menus. +// +// If CLOCKWISE normally moves DOWN this makes it go UP. +// If CLOCKWISE normally moves UP this makes it go DOWN. +// +//#define REVERSE_MENU_DIRECTION + +// +// Individual Axis Homing +// +// Add individual axis homing items (Home X, Home Y, and Home Z) to the LCD menu. +// +//#define INDIVIDUAL_AXIS_HOMING_MENU + +// +// SPEAKER/BUZZER +// +// If you have a speaker that can produce tones, enable it here. +// By default Marlin assumes you have a buzzer with a fixed frequency. +// +//#define SPEAKER + +// +// The duration and frequency for the UI feedback sound. +// Set these to 0 to disable audio feedback in the LCD menus. +// +// Note: Test audio output with the G-Code: +// M300 S P +// +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 +//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 + +// +// CONTROLLER TYPE: Standard +// +// Marlin supports a wide variety of controllers. +// Enable one of the following options to specify your controller. +// + +// +// ULTIMAKER Controller. +// +//#define ULTIMAKERCONTROLLER + +// +// ULTIPANEL as seen on Thingiverse. +// +//#define ULTIPANEL + +// +// PanelOne from T3P3 (via RAMPS 1.4 AUX2/AUX3) +// http://reprap.org/wiki/PanelOne +// +//#define PANEL_ONE + +// +// MaKr3d Makr-Panel with graphic controller and SD support. +// http://reprap.org/wiki/MaKr3d_MaKrPanel +// +//#define MAKRPANEL + +// +// ReprapWorld Graphical LCD +// https://reprapworld.com/?products_details&products_id/1218 +// +//#define REPRAPWORLD_GRAPHICAL_LCD + +// +// Activate one of these if you have a Panucatt Devices +// Viki 2.0 or mini Viki with Graphic LCD +// http://panucatt.com +// +//#define VIKI2 +//#define miniVIKI + +// +// Adafruit ST7565 Full Graphic Controller. +// https://github.com/eboston/Adafruit-ST7565-Full-Graphic-Controller/ +// +#define ELB_FULL_GRAPHIC_CONTROLLER + +// +// RepRapDiscount Smart Controller. +// http://reprap.org/wiki/RepRapDiscount_Smart_Controller +// +// Note: Usually sold with a white PCB. +// +//#define REPRAP_DISCOUNT_SMART_CONTROLLER + +// +// GADGETS3D G3D LCD/SD Controller +// http://reprap.org/wiki/RAMPS_1.3/1.4_GADGETS3D_Shield_with_Panel +// +// Note: Usually sold with a blue PCB. +// +//#define G3D_PANEL + +// +// RepRapDiscount FULL GRAPHIC Smart Controller +// http://reprap.org/wiki/RepRapDiscount_Full_Graphic_Smart_Controller +// +//#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER + +// +// MakerLab Mini Panel with graphic +// controller and SD support - http://reprap.org/wiki/Mini_panel +// +//#define MINIPANEL + +// +// RepRapWorld REPRAPWORLD_KEYPAD v1.1 +// http://reprapworld.com/?products_details&products_id=202&cPath=1591_1626 +// +// REPRAPWORLD_KEYPAD_MOVE_STEP sets how much should the robot move when a key +// is pressed, a value of 10.0 means 10mm per click. +// +//#define REPRAPWORLD_KEYPAD +//#define REPRAPWORLD_KEYPAD_MOVE_STEP 1.0 + +// +// RigidBot Panel V1.0 +// http://www.inventapart.com/ +// +//#define RIGIDBOT_PANEL + +// +// BQ LCD Smart Controller shipped by +// default with the BQ Hephestos 2 and Witbox 2. +// +//#define BQ_LCD_SMART_CONTROLLER + +// +// Cartesio UI +// http://mauk.cc/webshop/cartesio-shop/electronics/user-interface +// +//#define CARTESIO_UI + +// +// ANET_10 Controller supported displays. +// +//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. + // This LCD is known to be susceptible to electrical interference + // which scrambles the display. Pressing any button clears it up. +//#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 + // A clone of the RepRapDiscount full graphics display but with + // different pins/wiring (see pins_ANET_10.h). + +// +// LCD for Melzi Card with Graphical LCD +// +//#define LCD_FOR_MELZI + +// +// CONTROLLER TYPE: I2C +// +// Note: These controllers require the installation of Arduino's LiquidCrystal_I2C +// library. For more info: https://github.com/kiyoshigawa/LiquidCrystal_I2C +// + +// +// Elefu RA Board Control Panel +// http://www.elefu.com/index.php?route=product/product&product_id=53 +// +//#define RA_CONTROL_PANEL + +// +// Sainsmart YW Robot (LCM1602) LCD Display +// +// Note: This controller requires F.Malpartida's LiquidCrystal_I2C library +// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home +// +//#define LCD_I2C_SAINSMART_YWROBOT + +// +// Generic LCM1602 LCD adapter +// +//#define LCM1602 + +// +// PANELOLU2 LCD with status LEDs, +// separate encoder and click inputs. +// +// Note: This controller requires Arduino's LiquidTWI2 library v1.2.3 or later. +// For more info: https://github.com/lincomatic/LiquidTWI2 +// +// Note: The PANELOLU2 encoder click input can either be directly connected to +// a pin (if BTN_ENC defined to != -1) or read through I2C (when BTN_ENC == -1). +// +//#define LCD_I2C_PANELOLU2 + +// +// Panucatt VIKI LCD with status LEDs, +// integrated click & L/R/U/D buttons, separate encoder inputs. +// +//#define LCD_I2C_VIKI + +// +// SSD1306 OLED full graphics generic display +// +//#define U8GLIB_SSD1306 + +// +// SAV OLEd LCD module support using either SSD1306 or SH1106 based LCD modules +// +//#define SAV_3DGLCD +#if ENABLED(SAV_3DGLCD) + //#define U8GLIB_SSD1306 + #define U8GLIB_SH1106 +#endif + +// +// CONTROLLER TYPE: Shift register panels +// +// 2 wire Non-latching LCD SR from https://goo.gl/aJJ4sH +// LCD configuration: http://reprap.org/wiki/SAV_3D_LCD +// +//#define SAV_3DLCD + +// +// TinyBoy2 128x64 OLED / Encoder Panel +// +//#define OLED_PANEL_TINYBOY2 + +// +// Makeboard 3D Printer Parts 3D Printer Mini Display 1602 Mini Controller +// https://www.aliexpress.com/item/Micromake-Makeboard-3D-Printer-Parts-3D-Printer-Mini-Display-1602-Mini-Controller-Compatible-with-Ramps-1/32765887917.html +// +//#define MAKEBOARD_MINI_2_LINE_DISPLAY_1602 + +// +// MKS MINI12864 with graphic controller and SD support +// http://reprap.org/wiki/MKS_MINI_12864 +// +//#define MKS_MINI_12864 + +// +// Factory display for Creality CR-10 +// https://www.aliexpress.com/item/Universal-LCD-12864-3D-Printer-Display-Screen-With-Encoder-For-CR-10-CR-7-Model/32833148327.html +// +// This is RAMPS-compatible using a single 10-pin connector. +// (For CR-10 owners who want to replace the Melzi Creality board but retain the display) +// +//#define CR10_STOCKDISPLAY + +// +// MKS OLED 1.3" 128 × 64 FULL GRAPHICS CONTROLLER +// http://reprap.org/wiki/MKS_12864OLED +// +// Tiny, but very sharp OLED display +// +//#define MKS_12864OLED + +//============================================================================= +//=============================== Extra Features ============================== +//============================================================================= + +// @section extras + +// Increase the FAN PWM frequency. Removes the PWM noise but increases heating in the FET/Arduino +//#define FAST_PWM_FAN + +// Use software PWM to drive the fan, as for the heaters. This uses a very low frequency +// which is not as annoying as with the hardware PWM. On the other hand, if this frequency +// is too low, you should also increment SOFT_PWM_SCALE. +//#define FAN_SOFT_PWM + +// Incrementing this by 1 will double the software PWM frequency, +// affecting heaters, and the fan if FAN_SOFT_PWM is enabled. +// However, control resolution will be halved for each increment; +// at zero value, there are 128 effective control positions. +#define SOFT_PWM_SCALE 0 + +// If SOFT_PWM_SCALE is set to a value higher than 0, dithering can +// be used to mitigate the associated resolution loss. If enabled, +// some of the PWM cycles are stretched so on average the desired +// duty cycle is attained. +//#define SOFT_PWM_DITHER + +// Temperature status LEDs that display the hotend and bed temperature. +// If all hotends, bed temperature, and target temperature are under 54C +// then the BLUE led is on. Otherwise the RED led is on. (1C hysteresis) +//#define TEMP_STAT_LEDS + +// M240 Triggers a camera by emulating a Canon RC-1 Remote +// Data from: http://www.doc-diy.net/photo/rc-1_hacked/ +//#define PHOTOGRAPH_PIN 23 + +// 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 + +// Support for BlinkM/CyzRgb +//#define BLINKM + +// Support for PCA9632 PWM LED driver +//#define PCA9632 + +/** + * RGB LED / LED Strip Control + * + * Enable support for an RGB LED connected to 5V digital pins, or + * an RGB Strip connected to MOSFETs controlled by digital pins. + * + * 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 overall brightness parameters is also available + * + * *** CAUTION *** + * LED Strips require a MOFSET 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! + * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino + * cannot handle such current, separate 5V power supply must be used + * *** CAUTION *** + * + * LED type. This options are mutualy exclusive. Uncomment only one. + * + */ +//#define RGB_LED +//#define RGBW_LED + +#if ENABLED(RGB_LED) || ENABLED(RGBW_LED) + #define RGB_LED_R_PIN 34 + #define RGB_LED_G_PIN 43 + #define RGB_LED_B_PIN 35 + #define RGB_LED_W_PIN -1 +#endif + +// 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 (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) + #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip + #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time + #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + //#define NEOPIXEL_STARTUP_TEST // Cycle through colors at startup +#endif + +/** + * Printer Event LEDs + * + * During printing, the LEDs will reflect the printer status: + * + * - Gradually change from blue to violet as the heated bed gets to target temp + * - Gradually change from violet to red as the hotend gets to temperature + * - Change to white to illuminate work surface + * - Change to green once print has finished + * - Turn off after the print has finished and the user has pushed a button + */ +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) + #define PRINTER_EVENT_LEDS +#endif + +/*********************************************************************\ +* R/C SERVO support +* Sponsored by TrinityLabs, Reworked by codexmas +**********************************************************************/ + +// Number of servos +// +// If you select a configuration below, this will receive a default value and does not need to be set manually +// set it manually if you have more servos than extruders and wish to manually control some +// leaving it undefined or defining as 0 will disable the servo subsystem +// If unsure, leave commented / disabled +// +//#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command + +// Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. +// 300ms is a good value but you can try less delay. +// If the servo can't reach the requested position, increase it. +#define SERVO_DELAY { 300 } + +// Servo deactivation +// +// With this option servos are powered only during movement, then turned off to prevent jitter. +//#define DEACTIVATE_SERVOS_AFTER_MOVE + +/** + * Filament Width Sensor + * + * Measures the filament width in real-time and adjusts + * flow rate to compensate for any irregularities. + * + * Also allows the measured filament diameter to set the + * extrusion rate, so the slicer only has to specify the + * volume. + * + * Only a single extruder is supported at this time. + * + * 34 RAMPS_14 : Analog input 5 on the AUX2 connector + * 81 PRINTRBOARD : Analog input 2 on the Exp1 connector (version B,C,D,E) + * 301 RAMBO : Analog input 3 + * + * Note: May require analog pins to be defined for other boards. + */ +//#define FILAMENT_WIDTH_SENSOR + +#define DEFAULT_NOMINAL_FILAMENT_DIA 3.00 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. + +#if ENABLED(FILAMENT_WIDTH_SENSOR) + #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) + #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber + + #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading + #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading + #define MAX_MEASUREMENT_DELAY 20 // (bytes) Buffer size for stored measurements (1 byte per cm). Must be larger than MEASUREMENT_DELAY_CM. + + #define DEFAULT_MEASURED_FILAMENT_DIA DEFAULT_NOMINAL_FILAMENT_DIA // Set measured to nominal initially + + // Display filament width on the LCD status line. Status messages will expire after 5 seconds. + //#define FILAMENT_LCD_DISPLAY +#endif + +#endif // CONFIGURATION_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/delta/FLSUN/auto_calibrate/Configuration.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/delta/FLSUN/auto_calibrate/Configuration.h new file mode 100644 index 00000000..f79ce2b3 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/delta/FLSUN/auto_calibrate/Configuration.h @@ -0,0 +1,1828 @@ +/** + * 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 . + * + */ + +/** + * Configuration.h + * + * Basic settings such as: + * + * - Type of electronics + * - Type of temperature sensor + * - Printer geometry + * - Endstop configuration + * - LCD controller + * - Extra features + * + * Advanced settings can be found in Configuration_adv.h + * + */ +#ifndef CONFIGURATION_H +#define CONFIGURATION_H +#define CONFIGURATION_H_VERSION 010100 + +//=========================================================================== +//============================= Getting Started ============================= +//=========================================================================== + +/** + * Here are some standard links for getting your machine calibrated: + * + * http://reprap.org/wiki/Calibration + * http://youtu.be/wAL9d7FgInk + * http://calculator.josefprusa.cz + * http://reprap.org/wiki/Triffid_Hunter%27s_Calibration_Guide + * http://www.thingiverse.com/thing:5573 + * https://sites.google.com/site/repraplogphase/calibration-of-your-reprap + * http://www.thingiverse.com/thing:298812 + */ + +//=========================================================================== +//============================= DELTA Printer =============================== +//=========================================================================== +// For a Delta printer start with one of the configuration files in the +// example_configurations/delta directory and customize for your machine. +// + +//=========================================================================== +//============================= SCARA Printer =============================== +//=========================================================================== +// For a SCARA printer start with the configuration files in +// example_configurations/SCARA and customize for your machine. +// + +// @section info + +// User-specified version info of this build to display in [Pronterface, etc] terminal window during +// startup. Implementation of an idea by Prof Braino to inform user that any changes made to this +// build by the user have been successfully uploaded into firmware. +#define STRING_CONFIG_H_AUTHOR "(LVD, FLSUN-AC)" // Who made the changes. +#define SHOW_BOOTSCREEN +#define STRING_SPLASH_LINE1 SHORT_BUILD_VERSION // will be shown during bootup in line 1 +#define STRING_SPLASH_LINE2 WEBSITE_URL // will be shown during bootup in line 2 + +// +// *** VENDORS PLEASE READ ***************************************************** +// +// Marlin now allow you to have a vendor boot image to be displayed on machine +// start. When SHOW_CUSTOM_BOOTSCREEN is defined Marlin will first show your +// custom boot image and then the default Marlin boot image is shown. +// +// We suggest for you to take advantage of this new feature and keep the Marlin +// boot image unmodified. For an example have a look at the bq Hephestos 2 +// example configuration folder. +// +//#define SHOW_CUSTOM_BOOTSCREEN +// @section machine + +/** + * Select which serial port on the board will be used for communication with the host. + * This allows the connection of wireless adapters (for instance) to non-default port pins. + * Serial port 0 is always used by the Arduino bootloader regardless of this setting. + * + * :[0, 1, 2, 3, 4, 5, 6, 7] + */ +#define SERIAL_PORT 0 + +/** + * This setting determines the communication speed of the printer. + * + * 250000 works in most cases, but you might try a lower speed if + * you commonly experience drop-outs during host printing. + * You may try up to 1000000 to speed up SD file transfer. + * + * :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000] + */ +#define BAUDRATE 250000 + +// Enable the Bluetooth serial interface on AT90USB devices +//#define BLUETOOTH + +// The following define selects which electronics board you have. +// Please choose the name from boards.h that matches your setup +#ifndef MOTHERBOARD + #define MOTHERBOARD BOARD_RAMPS_13_EFB +#endif + +// Optional custom name for your RepStrap or other custom machine +// Displayed in the LCD "Ready" message +#define CUSTOM_MACHINE_NAME "FLSUN Kossel" + +// Define this to set a unique identifier for this printer, (Used by some programs to differentiate between machines) +// You can use an online service to generate a random UUID. (eg http://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] +#define EXTRUDERS 1 + +// For Cyclops or any "multi-extruder" that shares a single nozzle. +//#define SINGLENOZZLE + +/** + * Průša MK2 Single Nozzle Multi-Material Multiplexer, and variants. + * + * This device allows one stepper driver on a control board to drive + * two to eight stepper motors, one at a time, in a manner suitable + * for extruders. + * + * This option only allows the multiplexer to switch on tool-change. + * Additional options to configure custom E moves are pending. + */ +//#define MK2_MULTIPLEXER +#if ENABLED(MK2_MULTIPLEXER) + // Override the default DIO selector pins here, if needed. + // Some pins files may provide defaults for these pins. + //#define E_MUX0_PIN 40 // Always Required + //#define E_MUX1_PIN 42 // Needed for 3 to 8 steppers + //#define E_MUX2_PIN 44 // Needed for 5 to 8 steppers +#endif + +// A dual extruder that uses a single stepper motor +//#define SWITCHING_EXTRUDER +#if ENABLED(SWITCHING_EXTRUDER) + #define SWITCHING_EXTRUDER_SERVO_NR 0 + #define SWITCHING_EXTRUDER_SERVO_ANGLES { 0, 90 } // Angles for E0, E1[, E2, E3] + #if EXTRUDERS > 3 + #define SWITCHING_EXTRUDER_E23_SERVO_NR 1 + #endif +#endif + +// A dual-nozzle that uses a servomotor to raise/lower one of the nozzles +//#define SWITCHING_NOZZLE +#if ENABLED(SWITCHING_NOZZLE) + #define SWITCHING_NOZZLE_SERVO_NR 0 + #define SWITCHING_NOZZLE_SERVO_ANGLES { 0, 90 } // Angles for E0, E1 + //#define HOTEND_OFFSET_Z { 0.0, 0.0 } +#endif + +/** + * Two separate X-carriages with extruders that connect to a moving part + * via a magnetic docking mechanism. Requires SOL1_PIN and SOL2_PIN. + */ +//#define PARKING_EXTRUDER +#if ENABLED(PARKING_EXTRUDER) + #define PARKING_EXTRUDER_SOLENOIDS_INVERT // If enabled, the solenoid is NOT magnetized with applied voltage + #define PARKING_EXTRUDER_SOLENOIDS_PINS_ACTIVE LOW // LOW or HIGH pin signal energizes the coil + #define PARKING_EXTRUDER_SOLENOIDS_DELAY 250 // Delay (ms) for magnetic field. No delay if 0 or not defined. + #define PARKING_EXTRUDER_PARKING_X { -78, 184 } // X positions for parking the extruders + #define PARKING_EXTRUDER_GRAB_DISTANCE 1 // mm to move beyond the parking point to grab the extruder + #define PARKING_EXTRUDER_SECURITY_RAISE 5 // Z-raise before parking + #define HOTEND_OFFSET_Z { 0.0, 1.3 } // Z-offsets of the two hotends. The first must be 0. +#endif + +/** + * "Mixing Extruder" + * - Adds a new code, M165, to set the current mix factors. + * - Extends the stepping routines to move multiple steppers in proportion to the mix. + * - Optional support for Repetier Firmware M163, M164, and virtual extruder. + * - This implementation supports only a single extruder. + * - Enable DIRECT_MIXING_IN_G1 for Pia Taubert's reference implementation + */ +//#define MIXING_EXTRUDER +#if ENABLED(MIXING_EXTRUDER) + #define MIXING_STEPPERS 2 // Number of steppers in your mixing extruder + #define MIXING_VIRTUAL_TOOLS 16 // Use the Virtual Tool method with M163 and M164 + //#define DIRECT_MIXING_IN_G1 // Allow ABCDHI mix factors in G1 movement commands +#endif + +// Offset of the extruders (uncomment if using more than one and relying on firmware to position when changing). +// The offset has to be X=0, Y=0 for the extruder 0 hotend (default extruder). +// For the other hotends it is their distance from the extruder 0 hotend. +//#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis +//#define HOTEND_OFFSET_Y {0.0, 5.00} // (in mm) for each extruder, offset of the hotend on the Y axis + +// @section machine + +/** + * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN + * + * 0 = No Power Switch + * 1 = ATX + * 2 = X-Box 360 203Watts (the blue wire connected to PS_ON and the red wire to VCC) + * + * :{ 0:'No power switch', 1:'ATX', 2:'X-Box 360' } + */ +#define POWER_SUPPLY 0 + +#if POWER_SUPPLY > 0 + // Enable this option to leave the PSU off at startup. + // Power to steppers and heaters will need to be turned on with M80. + //#define PS_DEFAULT_OFF +#endif + +// @section temperature + +//=========================================================================== +//============================= Thermal Settings ============================ +//=========================================================================== + +/** + * --NORMAL IS 4.7kohm PULLUP!-- 1kohm pullup can be used on hotend sensor, using correct resistor and table + * + * Temperature sensors available: + * + * -3 : thermocouple with MAX31855 (only for sensor 0) + * -2 : thermocouple with MAX6675 (only for sensor 0) + * -1 : thermocouple with AD595 + * 0 : not used + * 1 : 100k thermistor - best choice for EPCOS 100k (4.7k pullup) + * 2 : 200k thermistor - ATC Semitec 204GT-2 (4.7k pullup) + * 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 (Used in ParCan & J-Head) (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) + * 71 : 100k Honeywell thermistor 135-104LAF-J01 (4.7k pullup) + * 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) + * 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" + * 20 : the PT100 circuit found in the Ultimainboard V2.x + * 60 : 100k Maker's Tool Works Kapton Bed Thermistor beta=3950 + * 66 : 4.7M High Temperature thermistor from Dyze Design + * 70 : the 100K thermistor found in the bq Hephestos 2 + * 75 : 100k Generic Silicon Heat Pad with NTC 100K MGB18-104F39050L32 thermistor + * + * 1k ohm pullup tables - This is atypical, and requires changing out the 4.7k pullup for 1k. + * (but gives greater accuracy and more stable PID) + * 51 : 100k thermistor - EPCOS (1k pullup) + * 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 + * 1010 : Pt1000 with 1k pullup (non standard) + * 147 : Pt100 with 4k7 pullup + * 110 : Pt100 with 1k pullup (non standard) + * + * Use these for Testing or Development purposes. NEVER for production machine. + * 998 : Dummy Table that ALWAYS reads 25°C or the temperature defined below. + * 999 : Dummy Table that ALWAYS reads 100°C or the temperature defined below. + * + * :{ '0': "Not used", '1':"100k / 4.7k - EPCOS", '2':"200k / 4.7k - ATC Semitec 204GT-2", '3':"Mendel-parts / 4.7k", '4':"10k !! do not use for a hotend. Bad resolution at high temp. !!", '5':"100K / 4.7k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '6':"100k / 4.7k EPCOS - Not as accurate as Table 1", '7':"100k / 4.7k Honeywell 135-104LAG-J01", '8':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT", '9':"100k / 4.7k GE Sensing AL03006-58.2K-97-G1", '10':"100k / 4.7k RS 198-961", '11':"100k / 4.7k beta 3950 1%", '12':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT (calibrated for Makibox hot bed)", '13':"100k Hisens 3950 1% up to 300°C for hotend 'Simple ONE ' & hotend 'All In ONE'", '20':"PT100 (Ultimainboard V2.x)", '51':"100k / 1k - EPCOS", '52':"200k / 1k - ATC Semitec 204GT-2", '55':"100k / 1k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '60':"100k Maker's Tool Works Kapton Bed Thermistor beta=3950", '66':"Dyze Design 4.7M High Temperature thermistor", '70':"the 100K thermistor found in the bq Hephestos 2", '71':"100k / 4.7k Honeywell 135-104LAF-J01", '147':"Pt100 / 4.7k", '1047':"Pt1000 / 4.7k", '110':"Pt100 / 1k (non-standard)", '1010':"Pt1000 / 1k (non standard)", '-3':"Thermocouple + MAX31855 (only for sensor 0)", '-2':"Thermocouple + MAX6675 (only for sensor 0)", '-1':"Thermocouple + AD595",'998':"Dummy 1", '999':"Dummy 2" } + */ +#define TEMP_SENSOR_0 5 +#define TEMP_SENSOR_1 0 +#define TEMP_SENSOR_2 0 +#define TEMP_SENSOR_3 0 +#define TEMP_SENSOR_4 0 +#define TEMP_SENSOR_BED 5 + +// Dummy thermistor constant temperature readings, for use with 998 and 999 +#define DUMMY_THERMISTOR_998_VALUE 25 +#define DUMMY_THERMISTOR_999_VALUE 100 + +// 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 +#define MAX_REDUNDANT_TEMP_SENSOR_DIFF 5 + +// Extruder temperature must be close to target for this long before M109 returns success +#define TEMP_RESIDENCY_TIME 10 // (seconds) +#define TEMP_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// Bed temperature must be close to target for this long before M190 returns success +#define TEMP_BED_RESIDENCY_TIME 1 // (seconds) +#define TEMP_BED_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_BED_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// The minimal temperature defines the temperature below which the heater will not be enabled It is used +// to check that the wiring to the thermistor is not broken. +// Otherwise this would lead to the heater being powered on all the time. +#define HEATER_0_MINTEMP 5 +#define HEATER_1_MINTEMP 5 +#define HEATER_2_MINTEMP 5 +#define HEATER_3_MINTEMP 5 +#define HEATER_4_MINTEMP 5 +#define BED_MINTEMP 5 + +// When temperature exceeds max temp, your heater will be switched off. +// This feature exists to protect your hotend from overheating accidentally, but *NOT* from thermistor short/failure! +// You should use MINTEMP for thermistor short/failure protection. +#define HEATER_0_MAXTEMP 250 +#define HEATER_1_MAXTEMP 250 +#define HEATER_2_MAXTEMP 250 +#define HEATER_3_MAXTEMP 250 +#define HEATER_4_MAXTEMP 250 +#define BED_MAXTEMP 115 + +//=========================================================================== +//============================= PID Settings ================================ +//=========================================================================== +// PID Tuning Guide here: http://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 +#if ENABLED(PIDTEMP) + #define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. + //#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. + #define K1 0.95 //smoothing factor within the PID + + // 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 + + //E3D with 30MM fan + #define DEFAULT_Kp 24.77 + #define DEFAULT_Ki 1.84 + #define DEFAULT_Kd 83.61 + +#endif // PIDTEMP + +//=========================================================================== +//============================= PID > Bed Temperature Control =============== +//=========================================================================== +// Select PID or bang-bang with PIDTEMPBED. If bang-bang, BED_LIMIT_SWITCHING will enable hysteresis +// +// Uncomment this to enable PID on the bed. It uses the same frequency PWM as the extruder. +// If your PID_dT is the default, and correct for your hardware/configuration, that means 7.689Hz, +// which is fine for driving a square wave into a resistive load and does not significantly impact you FET heating. +// This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W heater. +// If your configuration is significantly different than this and you don't understand the issues involved, you probably +// shouldn't use bed PID until someone else verifies your hardware works. +// If this is enabled, find your own PID constants below. +//#define PIDTEMPBED + +//#define BED_LIMIT_SWITCHING + +// This sets the max power delivered to the bed, and replaces the HEATER_BED_DUTY_CYCLE_DIVIDER option. +// all forms of bed control obey this (PID, bang-bang, bang-bang with hysteresis) +// setting this to anything other than 255 enables a form of PWM to the bed just like HEATER_BED_DUTY_CYCLE_DIVIDER did, +// so you shouldn't use it unless you are OK with PWM on your bed. (see the comment on enabling PIDTEMPBED) +#define MAX_BED_POWER 255 // limits duty cycle to bed; 255=full current + +#if ENABLED(PIDTEMPBED) + + //#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) + //#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 + + //D-force + #define DEFAULT_bedKp 22.97 + #define DEFAULT_bedKi 3.76 + #define DEFAULT_bedKd 29.2 + + // FIND YOUR OWN: "M303 E-1 C8 S90" to run autotune on the bed at 90 degreesC for 8 cycles. +#endif // PIDTEMPBED + +// @section extruder + +// This option prevents extrusion if the temperature is below EXTRUDE_MINTEMP. +// It also enables the M302 command to set the minimum extrusion temperature +// or to allow moving the extruder regardless of the hotend temperature. +// *** IT IS HIGHLY RECOMMENDED TO LEAVE THIS OPTION ENABLED! *** +#define PREVENT_COLD_EXTRUSION +#define EXTRUDE_MINTEMP 170 + +// This option prevents a single extrusion longer than EXTRUDE_MAXLENGTH. +// Note that for Bowden Extruders a too-small value here may prevent loading. +#define PREVENT_LENGTHY_EXTRUDE +#define EXTRUDE_MAXLENGTH 300 + +//=========================================================================== +//======================== Thermal Runaway Protection ======================= +//=========================================================================== + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * If you get "Thermal Runaway" or "Heating failed" errors the + * details can be tuned in Configuration_adv.h + */ + +#define THERMAL_PROTECTION_HOTENDS // Enable thermal protection for all extruders +#define THERMAL_PROTECTION_BED // Enable thermal protection for the heated bed + +//=========================================================================== +//============================= Mechanical Settings ========================= +//=========================================================================== + +// @section machine + +// Uncomment one of these options to enable CoreXY, CoreXZ, or CoreYZ kinematics +// either in the usual order or reversed +//#define COREXY +//#define COREXZ +//#define COREYZ +//#define COREYX +//#define COREZX +//#define COREZY + +//=========================================================================== +//============================== Delta Settings ============================= +//=========================================================================== +// Enable DELTA kinematics and most of the default configuration for Deltas +#define DELTA + +#if ENABLED(DELTA) + + // Make delta curves from many straight lines (linear interpolation). + // This is a trade-off between visible corners (not enough segments) + // and processor overload (too many expensive sqrt calls). + #define DELTA_SEGMENTS_PER_SECOND 160 + + // After homing move down to a height where XY movement is unconstrained + //#define DELTA_HOME_TO_SAFE_ZONE + + // Delta calibration menu + // uncomment to add three points calibration menu option. + // See http://minow.blogspot.com/index.html#4918805519571907051 + #define DELTA_CALIBRATION_MENU + + // uncomment to add G33 Delta Auto-Calibration (Enable EEPROM_SETTINGS to store results) + #define DELTA_AUTO_CALIBRATION + + // NOTE NB all values for DELTA_* values MUST be floating point, so always have a decimal point in them + + #if ENABLED(DELTA_AUTO_CALIBRATION) + // set the default number of probe points : n*n (1 -> 7) + #define DELTA_CALIBRATION_DEFAULT_POINTS 4 + #endif + + #if ENABLED(DELTA_AUTO_CALIBRATION) || ENABLED(DELTA_CALIBRATION_MENU) + // Set the radius for the calibration probe points - max DELTA_PRINTABLE_RADIUS*0.869 for non-eccentric probes + #define DELTA_CALIBRATION_RADIUS 73.5 // mm + // Set the steprate for papertest probing + #define PROBE_MANUALLY_STEP 0.025 + #endif + + // Print surface diameter/2 minus unreachable space (avoid collisions with vertical towers). + #define DELTA_PRINTABLE_RADIUS 85.0 // mm + + // Center-to-center distance of the holes in the diagonal push rods. + #define DELTA_DIAGONAL_ROD 218.0 // mm + + // height from z=0 to home position + #define DELTA_HEIGHT 295.00 // get this value from auto calibrate + + #define DELTA_ENDSTOP_ADJ { 0.0, 0.0, 0.0 } // get these from auto calibrate + + // Horizontal distance bridged by diagonal push rods when effector is centered. + #define DELTA_RADIUS 101.0 //mm Get this value from auto calibrate + + // Trim adjustments for individual towers + // tower angle corrections for X and Y tower / rotate XYZ so Z tower angle = 0 + // measured in degrees anticlockwise looking from above the printer + #define DELTA_TOWER_ANGLE_TRIM { 0.0, 0.0, 0.0 } // get these values from auto calibrate + + // delta radius and diaginal rod adjustments measured in mm + //#define DELTA_RADIUS_TRIM_TOWER { 0.0, 0.0, 0.0 } + //#define DELTA_DIAGONAL_ROD_TRIM_TOWER { 0.0, 0.0, 0.0 } + +#endif + +//=========================================================================== +//============================== Endstop Settings =========================== +//=========================================================================== + +// @section homing + +// Specify here all the endstop connectors that are connected to any endstop or probe. +// Almost all printers will be using one per axis. Probes will use one or more of the +// extra connectors. Leave undefined any used for non-endstop and non-probe purposes. +//#define USE_XMIN_PLUG +//#define USE_YMIN_PLUG +#define USE_ZMIN_PLUG +#define USE_XMAX_PLUG +#define USE_YMAX_PLUG +#define USE_ZMAX_PLUG + +// coarse Endstop Settings +#define ENDSTOPPULLUPS // Comment this out (using // at the start of the line) to disable the endstop pullup resistors + +#if DISABLED(ENDSTOPPULLUPS) + // fine endstop settings: Individual pullups. will be ignored if ENDSTOPPULLUPS is defined + //#define ENDSTOPPULLUP_XMAX + //#define ENDSTOPPULLUP_YMAX + //#define ENDSTOPPULLUP_ZMAX + //#define ENDSTOPPULLUP_XMIN + //#define ENDSTOPPULLUP_YMIN + //#define ENDSTOPPULLUP_ZMIN + //#define ENDSTOPPULLUP_ZMIN_PROBE +#endif + +// Mechanical endstop with COM to ground and NC to Signal uses "false" here (most common setup). +#define X_MIN_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Y_MIN_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define X_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Y_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MIN_PROBE_ENDSTOP_INVERTING true // set to true to invert the logic of the probe. + +// Enable this feature if all enabled endstop pins are interrupt-capable. +// This will remove the need to poll the interrupt pins, saving many CPU cycles. +//#define ENDSTOP_INTERRUPTS_FEATURE + +//============================================================================= +//============================== Movement Settings ============================ +//============================================================================= +// @section motion + +// delta speeds must be the same on xyz +/** + * Default Settings + * + * These settings can be reset by M502 + * + * Note that if EEPROM is enabled, saved values will override these. + */ + +/** + * With this option each E stepper can have its own factors for the + * following movement settings. If fewer factors are given than the + * total number of extruders, the last value applies to the rest. + */ +//#define DISTINCT_E_FACTORS + +/** + * Default Axis Steps Per Unit (steps/mm) + * Override with M92 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_AXIS_STEPS_PER_UNIT { 100, 100, 100, 100 } // default steps per unit for Kossel (GT2, 20 tooth) + +/** + * Default Max Feed Rate (mm/s) + * Override with M203 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_FEEDRATE { 200, 200, 200, 25 } + +/** + * Default Max Acceleration (change/s) change = mm/s + * (Maximum start speed for accelerated moves) + * Override with M201 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_ACCELERATION { 4000, 4000, 4000, 4000 } + +/** + * Default Acceleration (change/s) change = mm/s + * Override with M204 + * + * M204 P Acceleration + * M204 R Retract Acceleration + * M204 T Travel Acceleration + */ +#define DEFAULT_ACCELERATION 3000 // X, Y, Z and E acceleration for printing moves +#define DEFAULT_RETRACT_ACCELERATION 3000 // E acceleration for retracts +#define DEFAULT_TRAVEL_ACCELERATION 3000 // X, Y, Z acceleration for travel (non printing) moves + +/** + * Default Jerk (mm/s) + * Override with M205 X Y Z E + * + * "Jerk" specifies the minimum speed change that requires acceleration. + * When changing speed and direction, if the difference is less than the + * value set here, it may happen instantaneously. + */ +#define DEFAULT_XJERK 20.0 +#define DEFAULT_YJERK DEFAULT_XJERK +#define DEFAULT_ZJERK DEFAULT_YJERK // Must be same as XY for delta +#define DEFAULT_EJERK 5.0 + +//=========================================================================== +//============================= Z Probe Options ============================= +//=========================================================================== +// @section probes + +// +// See http://marlinfw.org/configuration/probes.html +// + +/** + * Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + * + * Enable this option for a probe connected to the Z Min endstop pin. + */ +#define Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + +/** + * Z_MIN_PROBE_ENDSTOP + * + * Enable this option for a probe connected to any pin except Z-Min. + * (By default Marlin assumes the Z-Max endstop pin.) + * To use a custom Z Probe pin, set Z_MIN_PROBE_PIN below. + * + * - The simplest option is to use a free endstop connector. + * - Use 5V for powered (usually inductive) sensors. + * + * - RAMPS 1.3/1.4 boards may use the 5V, GND, and Aux4->D32 pin: + * - For simple switches connect... + * - normally-closed switches to GND and D32. + * - normally-open switches to 5V and D32. + * + * WARNING: Setting the wrong pin may have unexpected and potentially + * disastrous consequences. Use with caution and do your homework. + * + */ +//#define Z_MIN_PROBE_ENDSTOP // A3K leave disabled! + +/** + * Probe Type + * + * Allen Key Probes, Servo Probes, Z-Sled Probes, FIX_MOUNTED_PROBE, etc. + * Activate one of these to use Auto Bed Leveling below. + */ + +/** + * The "Manual Probe" provides a means to do "Auto" Bed Leveling without a probe. + * Use G29 repeatedly, adjusting the Z height at each point with movement commands + * or (with LCD_BED_LEVELING) the LCD controller. + */ +//#define PROBE_MANUALLY + +/** + * A Fix-Mounted Probe either doesn't deploy or needs manual deployment. + * (e.g., an inductive probe or a nozzle-based probe-switch.) + */ +#define FIX_MOUNTED_PROBE + +/** + * Z Servo Probe, such as an endstop switch on a rotating arm. + */ +//#define Z_ENDSTOP_SERVO_NR 0 // Defaults to SERVO 0 connector. +//#define Z_SERVO_ANGLES {70,0} // Z Servo Deploy and Stow angles + +/** + * The BLTouch probe uses a Hall effect sensor and emulates a servo. + */ +//#define BLTOUCH +#if ENABLED(BLTOUCH) + //#define BLTOUCH_DELAY 375 // (ms) Enable and increase if needed +#endif + +/** + * Enable one or more of the following if probing seems unreliable. + * Heaters and/or fans can be disabled during probing to minimize electrical + * noise. A delay can also be added to allow noise and vibration to settle. + * These options are most useful for the BLTouch probe, but may also improve + * readings with inductive probes and piezo sensors. + */ +//#define PROBING_HEATERS_OFF // Turn heaters off when probing +//#define PROBING_FANS_OFF // Turn fans off when probing +//#define DELAY_BEFORE_PROBING 200 // (ms) To prevent vibrations from triggering piezo sensors + +// A probe that is deployed and stowed with a solenoid pin (SOL1_PIN) +//#define SOLENOID_PROBE + +// A sled-mounted probe like those designed by Charles Bell. +//#define Z_PROBE_SLED +//#define SLED_DOCKING_OFFSET 5 // The extra distance the X axis must travel to pickup the sled. 0 should be fine but you can push it further if you'd like. + +// +// For Z_PROBE_ALLEN_KEY see the Delta example configurations. +// + +/** + * Z Probe to nozzle (X,Y) offset, relative to (0, 0). + * X and Y offsets must be integers. + * + * In the following example the X and Y offsets are both positive: + * #define X_PROBE_OFFSET_FROM_EXTRUDER 10 + * #define Y_PROBE_OFFSET_FROM_EXTRUDER 10 + * + * +-- BACK ---+ + * | | + * L | (+) P | R <-- probe (20,20) + * E | | I + * F | (-) N (+) | G <-- nozzle (10,10) + * T | | H + * | (-) | T + * | | + * O-- FRONT --+ + * (0,0) + */ +#define X_PROBE_OFFSET_FROM_EXTRUDER 0 // X offset: -left +right [of the nozzle] +#define Y_PROBE_OFFSET_FROM_EXTRUDER 0 // Y offset: -front +behind [the nozzle] +#define Z_PROBE_OFFSET_FROM_EXTRUDER 0.10 // Z offset: -below +above [the nozzle] + +// X and Y axis travel speed (mm/m) between probes +#define XY_PROBE_SPEED 5000 + +// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +#define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z + +// Speed for the "accurate" probe of each point +#define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST) / 6 + +// Use double touch for probing +//#define PROBE_DOUBLE_TOUCH + +/** + * Allen key retractable z-probe as seen on many Kossel delta printers - http://reprap.org/wiki/Kossel#Automatic_bed_leveling_probe + * Deploys by touching z-axis belt. Retracts by pushing the probe down. Uses Z_MIN_PIN. + */ +//#define Z_PROBE_ALLEN_KEY + +#if ENABLED(Z_PROBE_ALLEN_KEY) + // 2 or 3 sets of coordinates for deploying and retracting the spring loaded touch probe on G29, + // if servo actuated touch probe is not defined. Uncomment as appropriate for your printer/probe. + + // Kossel Mini + #define Z_PROBE_ALLEN_KEY_DEPLOY_1_X 30.0 + #define Z_PROBE_ALLEN_KEY_DEPLOY_1_Y DELTA_PRINTABLE_RADIUS + #define Z_PROBE_ALLEN_KEY_DEPLOY_1_Z 100.0 + #define Z_PROBE_ALLEN_KEY_DEPLOY_1_FEEDRATE XY_PROBE_SPEED + + #define Z_PROBE_ALLEN_KEY_DEPLOY_2_X 0.0 + #define Z_PROBE_ALLEN_KEY_DEPLOY_2_Y DELTA_PRINTABLE_RADIUS + #define Z_PROBE_ALLEN_KEY_DEPLOY_2_Z 100.0 + #define Z_PROBE_ALLEN_KEY_DEPLOY_2_FEEDRATE (XY_PROBE_SPEED)/10 + + #define Z_PROBE_ALLEN_KEY_DEPLOY_3_X Z_PROBE_ALLEN_KEY_DEPLOY_2_X * 0.75 + #define Z_PROBE_ALLEN_KEY_DEPLOY_3_Y Z_PROBE_ALLEN_KEY_DEPLOY_2_Y * 0.75 + #define Z_PROBE_ALLEN_KEY_DEPLOY_3_Z Z_PROBE_ALLEN_KEY_DEPLOY_2_Z + #define Z_PROBE_ALLEN_KEY_DEPLOY_3_FEEDRATE XY_PROBE_SPEED + + #define Z_PROBE_ALLEN_KEY_STOW_DEPTH 20 + // Move the probe into position + #define Z_PROBE_ALLEN_KEY_STOW_1_X -64.0 + #define Z_PROBE_ALLEN_KEY_STOW_1_Y 56.0 + #define Z_PROBE_ALLEN_KEY_STOW_1_Z 23.0 + #define Z_PROBE_ALLEN_KEY_STOW_1_FEEDRATE XY_PROBE_SPEED + // Move the nozzle down further to push the probe into retracted position. + #define Z_PROBE_ALLEN_KEY_STOW_2_X Z_PROBE_ALLEN_KEY_STOW_1_X + #define Z_PROBE_ALLEN_KEY_STOW_2_Y Z_PROBE_ALLEN_KEY_STOW_1_Y + #define Z_PROBE_ALLEN_KEY_STOW_2_Z (Z_PROBE_ALLEN_KEY_STOW_1_Z-Z_PROBE_ALLEN_KEY_STOW_DEPTH) + #define Z_PROBE_ALLEN_KEY_STOW_2_FEEDRATE (XY_PROBE_SPEED/10) + // Raise things back up slightly so we don't bump into anything + #define Z_PROBE_ALLEN_KEY_STOW_3_X Z_PROBE_ALLEN_KEY_STOW_2_X + #define Z_PROBE_ALLEN_KEY_STOW_3_Y Z_PROBE_ALLEN_KEY_STOW_2_Y + #define Z_PROBE_ALLEN_KEY_STOW_3_Z (Z_PROBE_ALLEN_KEY_STOW_1_Z+Z_PROBE_ALLEN_KEY_STOW_DEPTH) + #define Z_PROBE_ALLEN_KEY_STOW_3_FEEDRATE (XY_PROBE_SPEED/2) + + #define Z_PROBE_ALLEN_KEY_STOW_4_X 0.0 + #define Z_PROBE_ALLEN_KEY_STOW_4_Y 0.0 + #define Z_PROBE_ALLEN_KEY_STOW_4_Z Z_PROBE_ALLEN_KEY_STOW_3_Z + #define Z_PROBE_ALLEN_KEY_STOW_4_FEEDRATE XY_PROBE_SPEED + +#endif // Z_PROBE_ALLEN_KEY + +/** + * Z probes require clearance when deploying, stowing, and moving between + * probe points to avoid hitting the bed and other hardware. + * Servo-mounted probes require extra space for the arm to rotate. + * Inductive probes need space to keep from triggering early. + * + * Use these settings to specify the distance (mm) to raise the probe (or + * lower the bed). The values set here apply over and above any (negative) + * probe Z Offset set with Z_PROBE_OFFSET_FROM_EXTRUDER, M851, or the LCD. + * Only integer values >= 1 are valid here. + * + * Example: `M851 Z-5` with a CLEARANCE of 4 => 9mm from bed to nozzle. + * But: `M851 Z+1` with a CLEARANCE of 2 => 2mm from bed to nozzle. + */ +#define Z_CLEARANCE_DEPLOY_PROBE 5 // Z Clearance for Deploy/Stow +#define Z_CLEARANCE_BETWEEN_PROBES 2 // Z Clearance between probe points + +// For M851 give a range for adjusting the Z probe offset +#define Z_PROBE_OFFSET_RANGE_MIN -20 +#define Z_PROBE_OFFSET_RANGE_MAX 20 + +// Enable the M48 repeatability test to test probe accuracy +//#define Z_MIN_PROBE_REPEATABILITY_TEST + +// For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1 +// :{ 0:'Low', 1:'High' } +#define X_ENABLE_ON 0 +#define Y_ENABLE_ON 0 +#define Z_ENABLE_ON 0 +#define E_ENABLE_ON 0 // For all extruders + +// Disables axis stepper immediately when it's not being used. +// 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 +//#define DISABLE_REDUCED_ACCURACY_WARNING + +// @section extruder + +#define DISABLE_E false // For all extruders +#define DISABLE_INACTIVE_EXTRUDER true // Keep only the active extruder enabled. + +// @section machine + +// Invert the stepper direction. Change (or reverse the motor connector) if an axis goes the wrong way. +#define INVERT_X_DIR true // DELTA does not invert +#define INVERT_Y_DIR true +#define INVERT_Z_DIR true + +// Enable this option for Toshiba stepper drivers +//#define CONFIG_STEPPERS_TOSHIBA + +// @section extruder + +// For direct drive extruder v9 set to true, for geared extruder set to false. +#define INVERT_E0_DIR false +#define INVERT_E1_DIR false +#define INVERT_E2_DIR false +#define INVERT_E3_DIR false +#define INVERT_E4_DIR false + +// @section homing + +//#define NO_MOTION_BEFORE_HOMING // Inhibit movement until all axes have been homed + +#define Z_HOMING_HEIGHT 15 // (in mm) Minimal z height before homing (G28) for Z clearance above the bed, clamps, ... + // Be sure you have this distance over your Z_MAX_POS in case. + +// Direction of endstops when homing; 1=MAX, -1=MIN +// :[-1,1] +#define X_HOME_DIR 1 // deltas always home to max +#define Y_HOME_DIR 1 +#define Z_HOME_DIR 1 + +// @section machine + +// The size of the print bed +#define X_BED_SIZE ((DELTA_PRINTABLE_RADIUS) * 2) +#define Y_BED_SIZE ((DELTA_PRINTABLE_RADIUS) * 2) + +// Travel limits (mm) after homing, corresponding to endstop positions. +#define X_MIN_POS -(DELTA_PRINTABLE_RADIUS) +#define Y_MIN_POS -(DELTA_PRINTABLE_RADIUS) +#define Z_MIN_POS 0 +#define X_MAX_POS DELTA_PRINTABLE_RADIUS +#define Y_MAX_POS DELTA_PRINTABLE_RADIUS +#define Z_MAX_POS MANUAL_Z_HOME_POS + +// If enabled, axes won't move below MIN_POS in response to movement commands. +//#define MIN_SOFTWARE_ENDSTOPS +// If enabled, axes won't move above MAX_POS in response to movement commands. +#define MAX_SOFTWARE_ENDSTOPS + +/** + * Filament Runout Sensor + * A mechanical or opto endstop is used to check for the presence of filament. + * + * RAMPS-based boards use SERVO3_PIN. + * For other boards you may need to define FIL_RUNOUT_PIN. + * By default the firmware assumes HIGH = has filament, LOW = ran out + */ +//#define FILAMENT_RUNOUT_SENSOR +#if ENABLED(FILAMENT_RUNOUT_SENSOR) + #define FIL_RUNOUT_INVERTING false // set to true to invert the logic of the sensor. + #define ENDSTOPPULLUP_FIL_RUNOUT // Uncomment to use internal pullup for filament runout pins if the sensor is defined. + #define FILAMENT_RUNOUT_SCRIPT "M600" +#endif + +//=========================================================================== +//=============================== Bed Leveling ============================== +//=========================================================================== +// @section bedlevel + +/** + * Choose one of the options below to enable G29 Bed Leveling. The parameters + * and behavior of G29 will change depending on your selection. + * + * If using a Probe for Z Homing, enable Z_SAFE_HOMING also! + * + * - AUTO_BED_LEVELING_3POINT + * Probe 3 arbitrary points on the bed (that aren't collinear) + * You specify the XY coordinates of all 3 points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_LINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_BILINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a mesh, best for large or uneven beds. + * + * - AUTO_BED_LEVELING_UBL (Unified Bed Leveling) + * A comprehensive bed leveling system combining the features and benefits + * of other systems. UBL also includes integrated Mesh Generation, Mesh + * Validation and Mesh Editing systems. Currently, UBL is only checked out + * for Cartesian Printers. That said, it was primarily designed to correct + * poor quality Delta Printers. If you feel adventurous and have a Delta, + * please post an issue if something doesn't work correctly. Initially, + * you will need to set a reduced bed size so you have a rectangular area + * to test on. + * + * - MESH_BED_LEVELING + * Probe a grid manually + * The result is a mesh, suitable for large or uneven beds. (See BILINEAR.) + * For machines without a probe, Mesh Bed Leveling provides a method to perform + * leveling in steps so you can manually adjust the Z height at each grid-point. + * With an LCD controller the process is guided step-by-step. + */ +//#define AUTO_BED_LEVELING_3POINT +//#define AUTO_BED_LEVELING_LINEAR +//#define AUTO_BED_LEVELING_BILINEAR +//#define AUTO_BED_LEVELING_UBL +//#define MESH_BED_LEVELING + +/** + * Enable detailed logging of G28, G29, M48, etc. + * Turn on with the command 'M111 S32'. + * NOTE: Requires a lot of PROGMEM! + */ +//#define DEBUG_LEVELING_FEATURE + +#if ENABLED(MESH_BED_LEVELING) || ENABLED(AUTO_BED_LEVELING_BILINEAR) || ENABLED(AUTO_BED_LEVELING_UBL) + // Gradually reduce leveling correction until a set height is reached, + // at which point movement will be level to the machine's XY plane. + // The height can be set with M420 Z + //#define ENABLE_LEVELING_FADE_HEIGHT +#endif + +#if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Set the number of grid points per dimension. + // Works best with 5 or more points in each dimension. + #define GRID_MAX_POINTS_X 7 + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + // Set the boundaries for probing (where the probe can reach). + #define DELTA_PROBEABLE_RADIUS (DELTA_PRINTABLE_RADIUS - 15) + #define LEFT_PROBE_BED_POSITION -(DELTA_PROBEABLE_RADIUS) + #define RIGHT_PROBE_BED_POSITION DELTA_PROBEABLE_RADIUS + #define FRONT_PROBE_BED_POSITION -(DELTA_PROBEABLE_RADIUS) + #define BACK_PROBE_BED_POSITION DELTA_PROBEABLE_RADIUS + + // The Z probe minimum outer margin (to validate G29 parameters). + #define MIN_PROBE_EDGE 20 + + // Probe along the Y axis, advancing X after each column + //#define PROBE_Y_FIRST + + #if ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Beyond the probed grid, continue the implied tilt? + // Default is to maintain the height of the nearest edge. + //#define EXTRAPOLATE_BEYOND_GRID + + // + // Experimental Subdivision of the grid by Catmull-Rom method. + // Synthesizes intermediate points to produce a more detailed mesh. + // + //#define ABL_BILINEAR_SUBDIVISION + #if ENABLED(ABL_BILINEAR_SUBDIVISION) + // Number of subdivisions between probe points + #define BILINEAR_SUBDIVISIONS 3 + #endif + + #endif + +#elif ENABLED(AUTO_BED_LEVELING_3POINT) + + // 3 arbitrary points to probe. + // A simple cross-product is used to estimate the plane of the bed. + #define ABL_PROBE_PT_1_X 15 + #define ABL_PROBE_PT_1_Y 180 + #define ABL_PROBE_PT_2_X 15 + #define ABL_PROBE_PT_2_Y 20 + #define ABL_PROBE_PT_3_X 170 + #define ABL_PROBE_PT_3_Y 20 + +#elif ENABLED(AUTO_BED_LEVELING_UBL) + + //=========================================================================== + //========================= Unified Bed Leveling ============================ + //=========================================================================== + + #define UBL_MESH_INSET 1 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 10 // Don't use more than 15 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + #define _PX(R,A) (R) * cos(RADIANS(A)) + #define _PY(R,A) (R) * sin(RADIANS(A)) + #define UBL_PROBE_PT_1_X _PX(DELTA_PROBEABLE_RADIUS, 0) // Probing points for 3-Point leveling of the mesh + #define UBL_PROBE_PT_1_Y _PY(DELTA_PROBEABLE_RADIUS, 0) + #define UBL_PROBE_PT_2_X _PX(DELTA_PROBEABLE_RADIUS, 120) + #define UBL_PROBE_PT_2_Y _PY(DELTA_PROBEABLE_RADIUS, 120) + #define UBL_PROBE_PT_3_X _PX(DELTA_PROBEABLE_RADIUS, 240) + #define UBL_PROBE_PT_3_Y _PY(DELTA_PROBEABLE_RADIUS, 240) + + #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation + #define UBL_MESH_EDIT_MOVES_Z // Sophisticated users prefer no movement of nozzle + +#elif ENABLED(MESH_BED_LEVELING) + + //=========================================================================== + //=================================== Mesh ================================== + //=========================================================================== + + #define MESH_INSET 10 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 3 // Don't use more than 7 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + //#define MESH_G28_REST_ORIGIN // After homing all axes ('G28' or 'G28 XYZ') rest Z at Z_MIN_POS + +#endif // BED_LEVELING + +/** + * Use the LCD controller for bed leveling + * Requires MESH_BED_LEVELING or PROBE_MANUALLY + */ +//#define LCD_BED_LEVELING + +#if ENABLED(LCD_BED_LEVELING) + #define MBL_Z_STEP 0.025 // Step size while manually probing Z axis. + #define LCD_PROBE_Z_RANGE 4 // Z Range centered on Z_MIN_POS for LCD Z adjustment +#endif + +// Add a menu item to move between bed corners for manual bed adjustment +//#define LEVEL_BED_CORNERS + +/** + * Commands to execute at the end of G29 probing. + * Useful to retract or move the Z probe out of the way. + */ +//#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) +#define BED_CENTER_AT_0_0 + +// Manually set the home position. Leave these undefined for automatic settings. +// For DELTA this is the top-center of the Cartesian print volume. +//#define MANUAL_X_HOME_POS 0 +//#define MANUAL_Y_HOME_POS 0 +#define MANUAL_Z_HOME_POS DELTA_HEIGHT // Distance between the nozzle to printbed after homing + +// Use "Z Safe Homing" to avoid homing with a Z probe outside the bed area. +// +// With this feature enabled: +// +// - 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). +// - 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 axis (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). +#endif + +// Delta only homes to Z +#define HOMING_FEEDRATE_Z (100*60) + +//============================================================================= +//============================= Additional Features =========================== +//============================================================================= + +// @section extras + +// +// EEPROM +// +// The microcontroller can store settings in the EEPROM, e.g. max velocity... +// M500 - stores parameters in EEPROM +// M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily). +// M502 - reverts to the default "factory settings". You still need to store them in EEPROM afterwards if you want to. +// +#define EEPROM_SETTINGS // Enable for M500 and M501 commands +//#define DISABLE_M503 // Saves ~2700 bytes of PROGMEM. Disable for release! +#define EEPROM_CHITCHAT // Give feedback on EEPROM commands. Disable to save PROGMEM. + +// +// Host Keepalive +// +// When enabled Marlin will send a busy status message to the host +// every couple of seconds when it can't accept commands. +// +#define HOST_KEEPALIVE_FEATURE // Disable this if your host doesn't like keepalive messages +#define DEFAULT_KEEPALIVE_INTERVAL 5 // Number of seconds between "busy" messages. Set with M113. +#define BUSY_WHILE_HEATING // Some hosts require "busy" messages even during heating + +// +// M100 Free Memory Watcher +// +//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose + +// +// G20/G21 Inch mode support +// +//#define INCH_MODE_SUPPORT + +// +// M149 Set temperature units support +// +//#define TEMPERATURE_UNITS_SUPPORT + +// @section temperature + +// Preheat Constants +#define PREHEAT_1_TEMP_HOTEND 195 +#define PREHEAT_1_TEMP_BED 60 +#define PREHEAT_1_FAN_SPEED 0 // Value from 0 to 255 + +#define PREHEAT_2_TEMP_HOTEND 240 +#define PREHEAT_2_TEMP_BED 100 +#define PREHEAT_2_FAN_SPEED 0 // Value from 0 to 255 + +/** + * Nozzle Park -- EXPERIMENTAL + * + * Park the nozzle at the given XYZ position on idle or G27. + * + * The "P" parameter controls the action applied to the Z axis: + * + * P0 (Default) If Z is below park Z raise the nozzle. + * P1 Raise the nozzle always to Z-park height. + * P2 Raise the nozzle by Z-park amount, limited to Z_MAX_POS. + */ +//#define NOZZLE_PARK_FEATURE + +#if ENABLED(NOZZLE_PARK_FEATURE) + // Specify a park position as { X, Y, Z } + #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 } +#endif + +/** + * Clean Nozzle Feature -- EXPERIMENTAL + * + * Adds the G12 command to perform a nozzle cleaning process. + * + * Parameters: + * P Pattern + * S Strokes / Repetitions + * T Triangles (P1 only) + * + * Patterns: + * P0 Straight line (default). This process requires a sponge type material + * at a fixed bed location. "S" specifies strokes (i.e. back-forth motions) + * between the start / end points. + * + * P1 Zig-zag pattern between (X0, Y0) and (X1, Y1), "T" specifies the + * number of zig-zag triangles to do. "S" defines the number of strokes. + * Zig-zags are done in whichever is the narrower dimension. + * For example, "G12 P1 S1 T3" will execute: + * + * -- + * | (X0, Y1) | /\ /\ /\ | (X1, Y1) + * | | / \ / \ / \ | + * A | | / \ / \ / \ | + * | | / \ / \ / \ | + * | (X0, Y0) | / \/ \/ \ | (X1, Y0) + * -- +--------------------------------+ + * |________|_________|_________| + * T1 T2 T3 + * + * P2 Circular pattern with middle at NOZZLE_CLEAN_CIRCLE_MIDDLE. + * "R" specifies the radius. "S" specifies the stroke count. + * Before starting, the nozzle moves to NOZZLE_CLEAN_START_POINT. + * + * Caveats: The ending Z should be the same as starting Z. + * Attention: EXPERIMENTAL. G-code arguments may change. + * + */ +//#define NOZZLE_CLEAN_FEATURE + +#if ENABLED(NOZZLE_CLEAN_FEATURE) + // Default number of pattern repetitions + #define NOZZLE_CLEAN_STROKES 12 + + // Default number of triangles + #define NOZZLE_CLEAN_TRIANGLES 3 + + // Specify positions as { X, Y, Z } + #define NOZZLE_CLEAN_START_POINT { 30, 30, (Z_MIN_POS + 1)} + #define NOZZLE_CLEAN_END_POINT {100, 60, (Z_MIN_POS + 1)} + + // Circular pattern radius + #define NOZZLE_CLEAN_CIRCLE_RADIUS 6.5 + // Circular pattern circle fragments number + #define NOZZLE_CLEAN_CIRCLE_FN 10 + // Middle point of circle + #define NOZZLE_CLEAN_CIRCLE_MIDDLE NOZZLE_CLEAN_START_POINT + + // Moves the nozzle to the initial position + #define NOZZLE_CLEAN_GOBACK +#endif + +/** + * Print Job Timer + * + * Automatically start and stop the print job timer on M104/M109/M190. + * + * M104 (hotend, no wait) - high temp = none, low temp = stop timer + * M109 (hotend, wait) - high temp = start timer, low temp = stop timer + * M190 (bed, wait) - high temp = start timer, low temp = none + * + * The timer can also be controlled with the following commands: + * + * M75 - Start the print job timer + * M76 - Pause the print job timer + * M77 - Stop the print job timer + */ +#define PRINTJOB_TIMER_AUTOSTART + +/** + * Print Counter + * + * Track statistical data such as: + * + * - Total print jobs + * - Total successful print jobs + * - Total failed print jobs + * - Total time printing + * + * View the current statistics with M78. + */ +#define PRINTCOUNTER + +//============================================================================= +//============================= LCD and SD support ============================ +//============================================================================= + +// @section lcd + +/** + * LCD LANGUAGE + * + * Select the language to display on the LCD. These languages are available: + * + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, + * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * tr, uk, zh_CN, zh_TW, test + * + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + */ +#define LCD_LANGUAGE en + +/** + * LCD Character Set + * + * Note: This option is NOT applicable to Graphical Displays. + * + * All character-based LCDs provide ASCII plus one of these + * language extensions: + * + * - JAPANESE ... the most common + * - WESTERN ... with more accented characters + * - CYRILLIC ... for the Russian language + * + * To determine the language extension installed on your controller: + * + * - Compile and upload with LCD_LANGUAGE set to 'test' + * - 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 + * + * :['JAPANESE', 'WESTERN', 'CYRILLIC'] + */ +#define DISPLAY_CHARSET_HD44780 WESTERN + +/** + * LCD TYPE + * + * Enable ULTRA_LCD for a 16x2, 16x4, 20x2, or 20x4 character-based LCD. + * Enable DOGLCD for a 128x64 (ST7565R) Full Graphical Display. + * (These options will be enabled automatically for most displays.) + * + * IMPORTANT: The U8glib library is required for Full Graphic Display! + * https://github.com/olikraus/U8glib_Arduino + */ +//#define ULTRA_LCD // Character based +//#define DOGLCD // Full graphics display + +/** + * SD CARD + * + * 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 + +/** + * SD CARD: SPI SPEED + * + * Enable one of the following items for a slower SPI transfer speed. + * This may be required to resolve "volume init" errors. + */ +//#define SPI_SPEED SPI_HALF_SPEED +//#define SPI_SPEED SPI_QUARTER_SPEED +//#define SPI_SPEED SPI_EIGHTH_SPEED + +/** + * SD CARD: ENABLE CRC + * + * Use CRC checks and retries on the SD communication. + */ +#define SD_CHECK_AND_RETRY + +// +// ENCODER SETTINGS +// +// This option overrides the default number of encoder pulses needed to +// produce one step. Should be increased for high-resolution encoders. +// +//#define ENCODER_PULSES_PER_STEP 1 + +// +// Use this option to override the number of step signals required to +// move between next/prev menu items. +// +//#define ENCODER_STEPS_PER_MENU_ITEM 5 + +/** + * Encoder Direction Options + * + * Test your encoder's behavior first with both options disabled. + * + * Reversed Value Edit and Menu Nav? Enable REVERSE_ENCODER_DIRECTION. + * Reversed Menu Navigation only? Enable REVERSE_MENU_DIRECTION. + * Reversed Value Editing only? Enable BOTH options. + */ + +// +// This option reverses the encoder direction everywhere. +// +// Set this option if CLOCKWISE causes values to DECREASE +// +//#define REVERSE_ENCODER_DIRECTION + +// +// This option reverses the encoder direction for navigating LCD menus. +// +// If CLOCKWISE normally moves DOWN this makes it go UP. +// If CLOCKWISE normally moves UP this makes it go DOWN. +// +//#define REVERSE_MENU_DIRECTION + +// +// Individual Axis Homing +// +// Add individual axis homing items (Home X, Home Y, and Home Z) to the LCD menu. +// +// INDIVIDUAL_AXIS_HOMING_MENU is incompatible with DELTA kinematics. +//#define INDIVIDUAL_AXIS_HOMING_MENU + +// +// SPEAKER/BUZZER +// +// If you have a speaker that can produce tones, enable it here. +// By default Marlin assumes you have a buzzer with a fixed frequency. +// +//#define SPEAKER + +// +// The duration and frequency for the UI feedback sound. +// Set these to 0 to disable audio feedback in the LCD menus. +// +// Note: Test audio output with the G-Code: +// M300 S P +// +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 +//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 + +// +// CONTROLLER TYPE: Standard +// +// Marlin supports a wide variety of controllers. +// Enable one of the following options to specify your controller. +// + +// +// ULTIMAKER Controller. +// +//#define ULTIMAKERCONTROLLER + +// +// ULTIPANEL as seen on Thingiverse. +// +//#define ULTIPANEL + +// +// PanelOne from T3P3 (via RAMPS 1.4 AUX2/AUX3) +// http://reprap.org/wiki/PanelOne +// +//#define PANEL_ONE + +// +// MaKr3d Makr-Panel with graphic controller and SD support. +// http://reprap.org/wiki/MaKr3d_MaKrPanel +// +//#define MAKRPANEL + +// +// ReprapWorld Graphical LCD +// https://reprapworld.com/?products_details&products_id/1218 +// +//#define REPRAPWORLD_GRAPHICAL_LCD + +// +// Activate one of these if you have a Panucatt Devices +// Viki 2.0 or mini Viki with Graphic LCD +// http://panucatt.com +// +//#define VIKI2 +//#define miniVIKI + +// +// Adafruit ST7565 Full Graphic Controller. +// https://github.com/eboston/Adafruit-ST7565-Full-Graphic-Controller/ +// +//#define ELB_FULL_GRAPHIC_CONTROLLER + +// +// RepRapDiscount Smart Controller. +// http://reprap.org/wiki/RepRapDiscount_Smart_Controller +// +// Note: Usually sold with a white PCB. +// +#define REPRAP_DISCOUNT_SMART_CONTROLLER + +// +// GADGETS3D G3D LCD/SD Controller +// http://reprap.org/wiki/RAMPS_1.3/1.4_GADGETS3D_Shield_with_Panel +// +// Note: Usually sold with a blue PCB. +// +//#define G3D_PANEL + +// +// RepRapDiscount FULL GRAPHIC Smart Controller +// http://reprap.org/wiki/RepRapDiscount_Full_Graphic_Smart_Controller +// +//#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER + +// +// MakerLab Mini Panel with graphic +// controller and SD support - http://reprap.org/wiki/Mini_panel +// +//#define MINIPANEL + +// +// RepRapWorld REPRAPWORLD_KEYPAD v1.1 +// http://reprapworld.com/?products_details&products_id=202&cPath=1591_1626 +// +// REPRAPWORLD_KEYPAD_MOVE_STEP sets how much should the robot move when a key +// is pressed, a value of 10.0 means 10mm per click. +// +//#define REPRAPWORLD_KEYPAD +//#define REPRAPWORLD_KEYPAD_MOVE_STEP 1.0 + +// +// RigidBot Panel V1.0 +// http://www.inventapart.com/ +// +//#define RIGIDBOT_PANEL + +// +// BQ LCD Smart Controller shipped by +// default with the BQ Hephestos 2 and Witbox 2. +// +//#define BQ_LCD_SMART_CONTROLLER + +// +// Cartesio UI +// http://mauk.cc/webshop/cartesio-shop/electronics/user-interface +// +//#define CARTESIO_UI + +// +// ANET_10 Controller supported displays. +// +//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. + // This LCD is known to be susceptible to electrical interference + // which scrambles the display. Pressing any button clears it up. +//#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 + // A clone of the RepRapDiscount full graphics display but with + // different pins/wiring (see pins_ANET_10.h). + +// +// LCD for Melzi Card with Graphical LCD +// +//#define LCD_FOR_MELZI + +// +// CONTROLLER TYPE: I2C +// +// Note: These controllers require the installation of Arduino's LiquidCrystal_I2C +// library. For more info: https://github.com/kiyoshigawa/LiquidCrystal_I2C +// + +// +// Elefu RA Board Control Panel +// http://www.elefu.com/index.php?route=product/product&product_id=53 +// +//#define RA_CONTROL_PANEL + +// +// Sainsmart YW Robot (LCM1602) LCD Display +// +// Note: This controller requires F.Malpartida's LiquidCrystal_I2C library +// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home +// +//#define LCD_I2C_SAINSMART_YWROBOT + +// +// Generic LCM1602 LCD adapter +// +//#define LCM1602 + +// +// PANELOLU2 LCD with status LEDs, +// separate encoder and click inputs. +// +// Note: This controller requires Arduino's LiquidTWI2 library v1.2.3 or later. +// For more info: https://github.com/lincomatic/LiquidTWI2 +// +// Note: The PANELOLU2 encoder click input can either be directly connected to +// a pin (if BTN_ENC defined to != -1) or read through I2C (when BTN_ENC == -1). +// +//#define LCD_I2C_PANELOLU2 + +// +// Panucatt VIKI LCD with status LEDs, +// integrated click & L/R/U/D buttons, separate encoder inputs. +// +//#define LCD_I2C_VIKI + +// +// SSD1306 OLED full graphics generic display +// +//#define U8GLIB_SSD1306 + +// +// SAV OLEd LCD module support using either SSD1306 or SH1106 based LCD modules +// +//#define SAV_3DGLCD +#if ENABLED(SAV_3DGLCD) + //#define U8GLIB_SSD1306 + #define U8GLIB_SH1106 +#endif + +// +// CONTROLLER TYPE: Shift register panels +// +// 2 wire Non-latching LCD SR from https://goo.gl/aJJ4sH +// LCD configuration: http://reprap.org/wiki/SAV_3D_LCD +// +//#define SAV_3DLCD + +// +// TinyBoy2 128x64 OLED / Encoder Panel +// +//#define OLED_PANEL_TINYBOY2 + +// +// Makeboard 3D Printer Parts 3D Printer Mini Display 1602 Mini Controller +// https://www.aliexpress.com/item/Micromake-Makeboard-3D-Printer-Parts-3D-Printer-Mini-Display-1602-Mini-Controller-Compatible-with-Ramps-1/32765887917.html +// +//#define MAKEBOARD_MINI_2_LINE_DISPLAY_1602 + +// +// MKS MINI12864 with graphic controller and SD support +// http://reprap.org/wiki/MKS_MINI_12864 +// +//#define MKS_MINI_12864 + +// +// Factory display for Creality CR-10 +// https://www.aliexpress.com/item/Universal-LCD-12864-3D-Printer-Display-Screen-With-Encoder-For-CR-10-CR-7-Model/32833148327.html +// +// This is RAMPS-compatible using a single 10-pin connector. +// (For CR-10 owners who want to replace the Melzi Creality board but retain the display) +// +//#define CR10_STOCKDISPLAY + +// +// MKS OLED 1.3" 128 × 64 FULL GRAPHICS CONTROLLER +// http://reprap.org/wiki/MKS_12864OLED +// +// Tiny, but very sharp OLED display +// +//#define MKS_12864OLED + +//============================================================================= +//=============================== Extra Features ============================== +//============================================================================= + +// @section extras + +// Increase the FAN PWM frequency. Removes the PWM noise but increases heating in the FET/Arduino +//#define FAST_PWM_FAN + +// Use software PWM to drive the fan, as for the heaters. This uses a very low frequency +// which is not as annoying as with the hardware PWM. On the other hand, if this frequency +// is too low, you should also increment SOFT_PWM_SCALE. +//#define FAN_SOFT_PWM + +// Incrementing this by 1 will double the software PWM frequency, +// affecting heaters, and the fan if FAN_SOFT_PWM is enabled. +// However, control resolution will be halved for each increment; +// at zero value, there are 128 effective control positions. +#define SOFT_PWM_SCALE 0 + +// If SOFT_PWM_SCALE is set to a value higher than 0, dithering can +// be used to mitigate the associated resolution loss. If enabled, +// some of the PWM cycles are stretched so on average the desired +// duty cycle is attained. +//#define SOFT_PWM_DITHER + +// Temperature status LEDs that display the hotend and bed temperature. +// If all hotends, bed temperature, and target temperature are under 54C +// then the BLUE led is on. Otherwise the RED led is on. (1C hysteresis) +//#define TEMP_STAT_LEDS + +// M240 Triggers a camera by emulating a Canon RC-1 Remote +// Data from: http://www.doc-diy.net/photo/rc-1_hacked/ +//#define PHOTOGRAPH_PIN 23 + +// 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 + +// Support for BlinkM/CyzRgb +//#define BLINKM + +// Support for PCA9632 PWM LED driver +//#define PCA9632 + +/** + * RGB LED / LED Strip Control + * + * Enable support for an RGB LED connected to 5V digital pins, or + * an RGB Strip connected to MOSFETs controlled by digital pins. + * + * 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 overall brightness parameters is also available + * + * *** CAUTION *** + * LED Strips require a MOFSET 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! + * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino + * cannot handle such current, separate 5V power supply must be used + * *** CAUTION *** + * + * LED type. This options are mutualy exclusive. Uncomment only one. + * + */ +//#define RGB_LED +//#define RGBW_LED + +#if ENABLED(RGB_LED) || ENABLED(RGBW_LED) + #define RGB_LED_R_PIN 34 + #define RGB_LED_G_PIN 43 + #define RGB_LED_B_PIN 35 + #define RGB_LED_W_PIN -1 +#endif + +// 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 (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) + #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip + #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time + #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + //#define NEOPIXEL_STARTUP_TEST // Cycle through colors at startup +#endif + +/** + * Printer Event LEDs + * + * During printing, the LEDs will reflect the printer status: + * + * - Gradually change from blue to violet as the heated bed gets to target temp + * - Gradually change from violet to red as the hotend gets to temperature + * - Change to white to illuminate work surface + * - Change to green once print has finished + * - Turn off after the print has finished and the user has pushed a button + */ +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) + #define PRINTER_EVENT_LEDS +#endif + +/*********************************************************************\ +* R/C SERVO support +* Sponsored by TrinityLabs, Reworked by codexmas +**********************************************************************/ + +// Number of servos +// +// If you select a configuration below, this will receive a default value and does not need to be set manually +// set it manually if you have more servos than extruders and wish to manually control some +// leaving it undefined or defining as 0 will disable the servo subsystem +// If unsure, leave commented / disabled +// +//#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command + +// Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. +// 300ms is a good value but you can try less delay. +// If the servo can't reach the requested position, increase it. +#define SERVO_DELAY { 300 } + +// Servo deactivation +// +// With this option servos are powered only during movement, then turned off to prevent jitter. +//#define DEACTIVATE_SERVOS_AFTER_MOVE + +/** + * Filament Width Sensor + * + * Measures the filament width in real-time and adjusts + * flow rate to compensate for any irregularities. + * + * Also allows the measured filament diameter to set the + * extrusion rate, so the slicer only has to specify the + * volume. + * + * Only a single extruder is supported at this time. + * + * 34 RAMPS_14 : Analog input 5 on the AUX2 connector + * 81 PRINTRBOARD : Analog input 2 on the Exp1 connector (version B,C,D,E) + * 301 RAMBO : Analog input 3 + * + * Note: May require analog pins to be defined for other boards. + */ +//#define FILAMENT_WIDTH_SENSOR + +#define DEFAULT_NOMINAL_FILAMENT_DIA 1.75 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. + +#if ENABLED(FILAMENT_WIDTH_SENSOR) + #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) + #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber + + #define MEASURED_UPPER_LIMIT 1.95 // (mm) Upper limit used to validate sensor reading + #define MEASURED_LOWER_LIMIT 1.20 // (mm) Lower limit used to validate sensor reading + #define MAX_MEASUREMENT_DELAY 20 // (bytes) Buffer size for stored measurements (1 byte per cm). Must be larger than MEASUREMENT_DELAY_CM. + + #define DEFAULT_MEASURED_FILAMENT_DIA DEFAULT_NOMINAL_FILAMENT_DIA // Set measured to nominal initially + + // Display filament width on the LCD status line. Status messages will expire after 5 seconds. + //#define FILAMENT_LCD_DISPLAY +#endif + +#endif // CONFIGURATION_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/delta/FLSUN/auto_calibrate/Configuration_adv.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/delta/FLSUN/auto_calibrate/Configuration_adv.h new file mode 100644 index 00000000..32860067 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/delta/FLSUN/auto_calibrate/Configuration_adv.h @@ -0,0 +1,1426 @@ +/** + * 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 . + * + */ + +/** + * Configuration_adv.h + * + * Advanced settings. + * Only change these if you know exactly what you're doing. + * Some of these settings can damage your printer if improperly set! + * + * Basic settings can be found in Configuration.h + * + */ +#ifndef CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H_VERSION 010100 + +// @section temperature + +//=========================================================================== +//=============================Thermal Settings ============================ +//=========================================================================== + +#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 + #endif +#endif + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * The solution: Once the temperature reaches the target, start observing. + * If the temperature stays too far below the target (hysteresis) for too long (period), + * the firmware will halt the machine as a safety precaution. + * + * If you get false positives for "Thermal Runaway" increase THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD + */ +#if ENABLED(THERMAL_PROTECTION_HOTENDS) + #define THERMAL_PROTECTION_PERIOD 40 // Seconds + #define THERMAL_PROTECTION_HYSTERESIS 4 // Degrees Celsius + + /** + * Whenever an M104 or M109 increases the target temperature the firmware will wait for the + * WATCH_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get false positives for "Heating failed" increase WATCH_TEMP_PERIOD and/or decrease WATCH_TEMP_INCREASE + * WATCH_TEMP_INCREASE should not be below 2. + */ + #define WATCH_TEMP_PERIOD 20 // Seconds + #define WATCH_TEMP_INCREASE 2 // Degrees Celsius +#endif + +/** + * Thermal Protection parameters for the bed are just as above for hotends. + */ +#if ENABLED(THERMAL_PROTECTION_BED) + #define THERMAL_PROTECTION_BED_PERIOD 20 // Seconds + #define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius + + /** + * Whenever an M140 or M190 increases the target temperature the firmware will wait for the + * WATCH_BED_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_BED_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get too many "Heating failed" errors, increase WATCH_BED_TEMP_PERIOD and/or decrease + * WATCH_BED_TEMP_INCREASE. (WATCH_BED_TEMP_INCREASE should not be below 2.) + */ + #define WATCH_BED_TEMP_PERIOD 60 // Seconds + #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius +#endif + +#if ENABLED(PIDTEMP) + // this adds an experimental additional term to the heating power, proportional to the extrusion speed. + // if Kc is chosen well, the additional required power due to increased melting should be compensated. + //#define PID_EXTRUSION_SCALING + #if ENABLED(PID_EXTRUSION_SCALING) + #define DEFAULT_Kc (100) //heating power=Kc*(e_speed) + #define LPQ_MAX_LEN 50 + #endif +#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 + */ +#define AUTOTEMP +#if ENABLED(AUTOTEMP) + #define AUTOTEMP_OLDWEIGHT 0.98 +#endif + +// Show Temperature ADC value +// Enable for M105 to include ADC values read from temperature sensors. +//#define SHOW_TEMP_ADC_VALUES + +/** + * High Temperature Thermistor Support + * + * Thermistors able to support high temperature tend to have a hard time getting + * good readings at room and lower temperatures. This means HEATER_X_RAW_LO_TEMP + * will probably be caught when the heating element first turns on during the + * preheating process, which will trigger a min_temp_error as a safety measure + * and force stop everything. + * To circumvent this limitation, we allow for a preheat time (during which, + * min_temp_error won't be triggered) and add a min_temp buffer to handle + * aberrant readings. + * + * If you want to enable this feature for your hotend thermistor(s) + * uncomment and set values > 0 in the constants below + */ + +// The number of consecutive low temperature errors that can occur +// before a min_temp_error is triggered. (Shouldn't be more than 10.) +//#define MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED 0 + +// The number of milliseconds a hotend will preheat before starting to check +// the temperature. This value should NOT be set to the time it takes the +// hot end to reach the target temperature, but the time it takes to reach +// the minimum temperature your thermistor can read. The lower the better/safer. +// This shouldn't need to be more than 30 seconds (30000) +//#define MILLISECONDS_PREHEAT_TIME 0 + +// @section extruder + +// Extruder runout prevention. +// If the machine is idle and the temperature over MINTEMP +// then extrude some filament every couple of SECONDS. +//#define EXTRUDER_RUNOUT_PREVENT +#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_EXTRUDE 5 // mm +#endif + +// @section temperature + +//These defines help to calibrate the AD595 sensor in case you get wrong temperature measurements. +//The measured temperature is defined as "actualTemp = (measuredTemp * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET" +#define TEMP_SENSOR_AD595_OFFSET 0.0 +#define TEMP_SENSOR_AD595_GAIN 1.0 + +/** + * 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. + */ +//#define USE_CONTROLLER_FAN +#if ENABLED(USE_CONTROLLER_FAN) + //#define CONTROLLER_FAN_PIN FAN1_PIN // 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 +#endif + +// When first starting the main fan, run it at full speed for the +// given number of milliseconds. This gets the fan spinning reliably +// before setting a PWM value. (Does not work with software PWM for fan on Sanguinololu) +//#define FAN_KICKSTART_TIME 100 + +// This defines the minimal speed for the main fan, run in PWM mode +// to enable uncomment and set minimal PWM speed for reliable running (1-255) +// if fan speed is [1 - (FAN_MIN_PWM-1)] it is set to FAN_MIN_PWM +//#define FAN_MIN_PWM 50 + +// @section extruder + +/** + * Extruder cooling fans + * + * Extruder auto fans automatically turn on when their extruders' + * temperatures go above EXTRUDER_AUTO_FAN_TEMPERATURE. + * + * Your board's pins file specifies the recommended pins. Override those here + * or set to -1 to disable completely. + * + * Multiple extruders can be assigned to the same pin in which case + * the fan will turn on when any selected extruder is above the threshold. + */ +#define E0_AUTO_FAN_PIN -1 +#define E1_AUTO_FAN_PIN -1 +#define E2_AUTO_FAN_PIN -1 +#define E3_AUTO_FAN_PIN -1 +#define E4_AUTO_FAN_PIN -1 +#define EXTRUDER_AUTO_FAN_TEMPERATURE 50 +#define EXTRUDER_AUTO_FAN_SPEED 255 // == full speed + +/** + * Part-Cooling Fan Multiplexer + * + * This feature allows you to digitally multiplex the fan output. + * The multiplexer is automatically switched at tool-change. + * Set FANMUX[012]_PINs below for up to 2, 4, or 8 multiplexed fans. + */ +#define FANMUX0_PIN -1 +#define FANMUX1_PIN -1 +#define FANMUX2_PIN -1 + +/** + * M355 Case Light on-off / brightness + */ +//#define CASE_LIGHT_ENABLE +#if ENABLED(CASE_LIGHT_ENABLE) + //#define CASE_LIGHT_PIN 4 // Override the default pin if needed + #define INVERT_CASE_LIGHT false // Set true if Case Light is ON when pin is LOW + #define CASE_LIGHT_DEFAULT_ON true // Set default power-up state on + #define CASE_LIGHT_DEFAULT_BRIGHTNESS 105 // Set default power-up brightness (0-255, requires PWM pin) + //#define MENU_ITEM_CASE_LIGHT // Add a Case Light option to the LCD main menu +#endif + +//=========================================================================== +//============================ Mechanical Settings ========================== +//=========================================================================== + +// @section homing + +// If you want endstops to stay on (by default) even when not homing +// enable this option. Override at any time with M120, M121. +//#define ENDSTOPS_ALWAYS_ON_DEFAULT + +// @section extras + +//#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. + +// Dual X Steppers +// Uncomment this option to drive two X axis motors. +// The next unused E driver will be assigned to the second X stepper. +//#define X_DUAL_STEPPER_DRIVERS +#if ENABLED(X_DUAL_STEPPER_DRIVERS) + // Set true if the two X motors need to rotate in opposite directions + #define INVERT_X2_VS_X_DIR true +#endif + +// Dual Y Steppers +// Uncomment this option to drive two Y axis motors. +// The next unused E driver will be assigned to the second Y stepper. +//#define Y_DUAL_STEPPER_DRIVERS +#if ENABLED(Y_DUAL_STEPPER_DRIVERS) + // Set true if the two Y motors need to rotate in opposite directions + #define INVERT_Y2_VS_Y_DIR true +#endif + +// A single Z stepper driver is usually used to drive 2 stepper motors. +// Uncomment this option to use a separate stepper driver for each Z axis motor. +// The next unused E driver will be assigned to the second Z stepper. +//#define Z_DUAL_STEPPER_DRIVERS + +#if ENABLED(Z_DUAL_STEPPER_DRIVERS) + + // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper. + // That way the machine is capable to align the bed during home, since both Z steppers are homed. + // There is also an implementation of M666 (software endstops adjustment) to this feature. + // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed. + // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2. + // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive. + // Play a little bit with small adjustments (0.5mm) and check the behaviour. + // The M119 (endstops report) will start reporting the Z2 Endstop as well. + + //#define Z_DUAL_ENDSTOPS + + #if ENABLED(Z_DUAL_ENDSTOPS) + #define Z2_USE_ENDSTOP _XMAX_ + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 // Use M666 to determine/test this value + #endif + +#endif // Z_DUAL_STEPPER_DRIVERS + +// Enable this for dual x-carriage printers. +// A dual x-carriage design has the advantage that the inactive extruder can be parked which +// prevents hot-end ooze contaminating the print. It also reduces the weight of each x-carriage +// allowing faster printing speeds. Connect your X2 stepper to the first unused E plug. +//#define DUAL_X_CARRIAGE +#if ENABLED(DUAL_X_CARRIAGE) + // Configuration for second X-carriage + // Note: the first x-carriage is defined as the x-carriage which homes to the minimum endstop; + // the second x-carriage always homes to the maximum endstop. + #define X2_MIN_POS 80 // set minimum to ensure second x-carriage doesn't hit the parked first X-carriage + #define X2_MAX_POS 353 // set maximum to the distance between toolheads when both heads are homed + #define X2_HOME_DIR 1 // the second X-carriage always homes to the maximum endstop position + #define X2_HOME_POS X2_MAX_POS // default home position is the maximum carriage position + // However: In this mode the HOTEND_OFFSET_X value for the second extruder provides a software + // override for X2_HOME_POS. This also allow recalibration of the distance between the two endstops + // without modifying the firmware (through the "M218 T1 X???" command). + // Remember: you should set the second extruder x-offset to 0 in your slicer. + + // There are a few selectable movement modes for dual x-carriages using M605 S + // Mode 0 (DXC_FULL_CONTROL_MODE): Full control. The slicer has full control over both x-carriages and can achieve optimal travel results + // as long as it supports dual x-carriages. (M605 S0) + // Mode 1 (DXC_AUTO_PARK_MODE) : Auto-park mode. The firmware will automatically park and unpark the x-carriages on tool changes so + // that additional slicer support is not required. (M605 S1) + // Mode 2 (DXC_DUPLICATION_MODE) : Duplication mode. The firmware will transparently make the second x-carriage and extruder copy all + // actions of the first x-carriage. This allows the printer to print 2 arbitrary items at + // once. (2nd extruder x offset and temp offset are set using: M605 S2 [Xnnn] [Rmmm]) + + // This is the default power-up mode which can be later using M605. + #define DEFAULT_DUAL_X_CARRIAGE_MODE DXC_FULL_CONTROL_MODE + + // Default settings in "Auto-park Mode" + #define TOOLCHANGE_PARK_ZLIFT 0.2 // the distance to raise Z axis when parking an extruder + #define TOOLCHANGE_UNPARK_ZLIFT 1 // the distance to raise Z axis when unparking an extruder + + // Default x offset in duplication mode (typically set to half print bed width) + #define DEFAULT_DUPLICATION_X_OFFSET 100 + +#endif // DUAL_X_CARRIAGE + +// 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. +//#define EXT_SOLENOID + +// @section homing + +//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +#define X_HOME_BUMP_MM 5 +#define Y_HOME_BUMP_MM 5 +#define Z_HOME_BUMP_MM 5 // deltas need the same for all three axes +#define HOMING_BUMP_DIVISOR {10, 10, 10} // Re-Bump Speed Divisor (Divides the Homing Feedrate) +//#define QUICK_HOME //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially. + +// When G28 is called, this option will make Y home before X +//#define HOME_Y_BEFORE_X + +// @section machine + +#define AXIS_RELATIVE_MODES {false, false, false, false} + +// Allow duplication mode with a basic dual-nozzle extruder +//#define DUAL_NOZZLE_DUPLICATION_MODE + +// By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step. +#define INVERT_X_STEP_PIN false +#define INVERT_Y_STEP_PIN false +#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. +#define DEFAULT_STEPPER_DEACTIVE_TIME 60 +#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_E true + +#define DEFAULT_MINIMUMFEEDRATE 0.0 // minimum feedrate +#define DEFAULT_MINTRAVELFEEDRATE 0.0 + +//#define HOME_AFTER_DEACTIVATE // Require rehoming after steppers are deactivated + +// @section lcd + +#if ENABLED(ULTIPANEL) + #define MANUAL_FEEDRATE_XYZ 50*60 + #define MANUAL_FEEDRATE { MANUAL_FEEDRATE_XYZ, MANUAL_FEEDRATE_XYZ, MANUAL_FEEDRATE_XYZ, 60 } // Feedrates for manual moves along X, Y, Z, E from panel + #define ULTIPANEL_FEEDMULTIPLY // Comment to disable setting feedrate multiplier via encoder +#endif + +// @section extras + +// minimum time in microseconds that a movement needs to take if the buffer is emptied. +#define DEFAULT_MINSEGMENTTIME 20000 + +// If defined the movements slow down when the look ahead buffer is only half full +// (don't use SLOWDOWN with DELTA because DELTA generates hundreds of segments per second) +//#define SLOWDOWN + +// Frequency limit +// See nophead's blog for more info +// Not working O +//#define XY_FREQUENCY_LIMIT 15 + +// 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 +// if unwanted behavior is observed on a user's machine when running at very slow speeds. +#define MINIMUM_PLANNER_SPEED 0.05 // (mm/sec) + +// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU. +#define MICROSTEP_MODES {16,16,16,16,16} // [1,2,4,8,16] + +/** + * @section stepper motor current + * + * Some boards have a means of setting the stepper motor current via firmware. + * + * The power on motor currents are set by: + * PWM_MOTOR_CURRENT - used by MINIRAMBO & ULTIMAIN_2 + * known compatible chips: A4982 + * DIGIPOT_MOTOR_CURRENT - used by BQ_ZUM_MEGA_3D, RAMBO & SCOOVO_X9H + * known compatible chips: AD5206 + * DAC_MOTOR_CURRENT_DEFAULT - used by PRINTRBOARD_REVF & RIGIDBOARD_V2 + * known compatible chips: MCP4728 + * DIGIPOT_I2C_MOTOR_CURRENTS - used by 5DPRINT, AZTEEG_X3_PRO, MIGHTYBOARD_REVE + * known compatible chips: MCP4451, MCP4018 + * + * Motor currents can also be set by M907 - M910 and by the LCD. + * M907 - applies to all. + * M908 - BQ_ZUM_MEGA_3D, RAMBO, PRINTRBOARD_REVF, RIGIDBOARD_V2 & SCOOVO_X9H + * M909, M910 & LCD - only PRINTRBOARD_REVF & RIGIDBOARD_V2 + */ +//#define PWM_MOTOR_CURRENT { 1300, 1300, 1250 } // Values in milliamps +#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 + +// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +//#define DIGIPOT_I2C +//#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster +#define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 +// Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS +#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=========================== +//=========================================================================== + +#define ENCODER_RATE_MULTIPLIER // If defined, certain menu edit operations automatically multiply the steps when the encoder is moved quickly +#define ENCODER_10X_STEPS_PER_SEC 75 // If the encoder steps per sec exceeds this value, multiply steps moved x10 to quickly advance the value +#define ENCODER_100X_STEPS_PER_SEC 160 // If the encoder steps per sec exceeds this value, multiply steps moved x100 to really quickly advance the value + +//#define CHDK 4 //Pin for triggering CHDK to take a picture see how to use it here http://captain-slow.dk/2014/03/09/3d-printing-timelapses/ +#define CHDK_DELAY 50 //How long in ms the pin should stay HIGH before going LOW again + +// @section lcd + +// Include a page of printer information in the LCD Main Menu +//#define LCD_INFO_MENU + +// Scroll a longer status message into view +//#define STATUS_MESSAGE_SCROLLING + +// On the Info Screen, display XY with one decimal place when possible +//#define LCD_DECIMAL_SMALL_XY + +// The timeout (in ms) to return to the status screen from sub-menus +//#define LCD_TIMEOUT_TO_STATUS 15000 + +#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 + + #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? + #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. + + #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. + // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. + // using: + //#define MENU_ADDAUTOSTART + + /** + * Sort SD file listings in alphabetical order. + * + * With this option enabled, items on SD cards will be sorted + * by name for easier navigation. + * + * By default... + * + * - Use the slowest -but safest- method for sorting. + * - Folders are sorted to the top. + * - The sort key is statically allocated. + * - No added G-code (M34) support. + * - 40 item sorting limit. (Items after the first 40 are unsorted.) + * + * SD sorting uses static allocation (as set by SDSORT_LIMIT), allowing the + * compiler to calculate the worst-case usage and throw an error if the SRAM + * limit is exceeded. + * + * - SDSORT_USES_RAM provides faster sorting via a static directory buffer. + * - SDSORT_USES_STACK does the same, but uses a local stack-based buffer. + * - SDSORT_CACHE_NAMES will retain the sorted file listing in RAM. (Expensive!) + * - SDSORT_DYNAMIC_RAM only uses RAM when the SD menu is visible. (Use with caution!) + */ + //#define SDCARD_SORT_ALPHA + + // SD Card Sorting options + #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_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. + #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #endif + + // Show a progress bar on HD44780 LCDs for SD printing + //#define LCD_PROGRESS_BAR + + #if ENABLED(LCD_PROGRESS_BAR) + // Amount of time (ms) to show the bar + #define PROGRESS_BAR_BAR_TIME 2000 + // Amount of time (ms) to show the status message + #define PROGRESS_BAR_MSG_TIME 3000 + // Amount of time (ms) to retain the status message (0=forever) + #define PROGRESS_MSG_EXPIRE 0 + // Enable this to show messages for MSG_TIME then hide them + //#define PROGRESS_MSG_ONCE + // Add a menu item to test the progress bar: + //#define LCD_PROGRESS_BAR_TEST + #endif + + // This allows hosts to request long names for files and folders with M33 + //#define LONG_FILENAME_HOST_SUPPORT + + // This option allows you to abort SD printing when any endstop is triggered. + // This feature must be enabled with "M540 S1" or from the LCD menu. + // To have any effect, endstops must be enabled during SD printing. + //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + +#endif // SDSUPPORT + +/** + * Additional options for Graphical Displays + * + * Use the optimizations here to improve printing performance, + * which can be adversely affected by graphical display drawing, + * especially when doing several short moves, and when printing + * on DELTA and SCARA machines. + * + * Some of these options may result in the display lagging behind + * controller events, as there is a trade-off between reliable + * printing performance versus fast display updates. + */ +#if ENABLED(DOGLCD) + // Enable to save many cycles by drawing a hollow frame on the Info Screen + #define XYZ_HOLLOW_FRAME + + // Enable to save many cycles by drawing a hollow frame on Menu Screens + #define MENU_HOLLOW_FRAME + + // A bigger font is available for edit items. Costs 3120 bytes of PROGMEM. + // 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. + // 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 +#endif // DOGLCD + +// @section safety + +// The hardware watchdog should reset the microcontroller disabling all outputs, +// in case the firmware gets stuck and doesn't do temperature regulation. +#define USE_WATCHDOG + +#if ENABLED(USE_WATCHDOG) + // If you have a watchdog reboot in an ArduinoMega2560 then the device will hang forever, as a watchdog reset will leave the watchdog on. + // The "WATCHDOG_RESET_MANUAL" goes around this by not using the hardware reset. + // However, THIS FEATURE IS UNSAFE!, as it will only work if interrupts are disabled. And the code could hang in an interrupt routine with interrupts disabled. + //#define WATCHDOG_RESET_MANUAL +#endif + +// @section lcd + +/** + * Babystepping enables movement of the axes by tiny increments without changing + * the current position values. This feature is used primarily to adjust the Z + * axis in the first layer of a print in real-time. + * + * Warning: Does not respect endstops! + */ +//#define BABYSTEPPING +#if ENABLED(BABYSTEPPING) + //#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 1 // Babysteps are very small. Increase for faster motion. + //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping + //#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen 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_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor + //#define BABYSTEP_ZPROBE_GFX_REVERSE // Reverses the direction of the CW/CCW indicators +#endif + +// @section extruder + +/** + * Implementation of linear pressure control + * + * Assumption: advance = k * (delta velocity) + * K=0 means advance disabled. + * See Marlin documentation for calibration instructions. + */ +//#define LIN_ADVANCE + +#if ENABLED(LIN_ADVANCE) + #define LIN_ADVANCE_K 75 + + /** + * Some Slicers produce Gcode with randomly jumping extrusion widths occasionally. + * For example within a 0.4mm perimeter it may produce a single segment of 0.05mm width. + * While this is harmless for normal printing (the fluid nature of the filament will + * close this very, very tiny gap), it throws off the LIN_ADVANCE pressure adaption. + * + * For this case LIN_ADVANCE_E_D_RATIO can be used to set the extrusion:distance ratio + * to a fixed value. Note that using a fixed ratio will lead to wrong nozzle pressures + * if the slicer is using variable widths or layer heights within one print! + * + * This option sets the default E:D ratio at startup. Use `M900` to override this value. + * + * Example: `M900 W0.4 H0.2 D1.75`, where: + * - W is the extrusion width in mm + * - H is the layer height in mm + * - D is the filament diameter in mm + * + * Example: `M900 R0.0458` to set the ratio directly. + * + * Set to 0 to auto-detect the ratio based on given Gcode G1 print moves. + * + * Slic3r (including Průša Control) produces Gcode compatible with the automatic mode. + * Cura (as of this writing) may produce Gcode incompatible with the automatic mode. + */ + #define LIN_ADVANCE_E_D_RATIO 0 // The calculated ratio (or 0) according to the formula W * H / ((D / 2) ^ 2 * PI) + // Example: 0.4 * 0.2 / ((1.75 / 2) ^ 2 * PI) = 0.033260135 +#endif + +// @section leveling + +// Default mesh area is an area with an inset margin on the print area. +// Below are the macros that are used to define the borders for the mesh area, +// made available here for specialized needs, ie dual extruder setup. +#if ENABLED(MESH_BED_LEVELING) + #define MESH_MIN_X MESH_INSET + #define MESH_MAX_X (X_BED_SIZE - (MESH_INSET)) + #define MESH_MIN_Y MESH_INSET + #define MESH_MAX_Y (Y_BED_SIZE - (MESH_INSET)) +#elif ENABLED(AUTO_BED_LEVELING_UBL) + #define UBL_MESH_MIN_X UBL_MESH_INSET + #define UBL_MESH_MAX_X (X_BED_SIZE - (UBL_MESH_INSET)) + #define UBL_MESH_MIN_Y UBL_MESH_INSET + #define UBL_MESH_MAX_Y (Y_BED_SIZE - (UBL_MESH_INSET)) + + // If this is defined, the currently active mesh will be saved in the + // current slot on M500. + #define UBL_SAVE_ACTIVE_ON_M500 +#endif + +// @section extras + +// +// G2/G3 Arc Support +// +#define ARC_SUPPORT // Disable this feature to save ~3226 bytes +#if ENABLED(ARC_SUPPORT) + #define MM_PER_ARC_SEGMENT 1 // Length of each arc segment + #define N_ARC_CORRECTION 25 // Number of intertpolated 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 +#endif + +// Support for G5 with XYZE destination and IJPQ offsets. Requires ~2666 bytes. +//#define BEZIER_CURVE_SUPPORT + +// G38.2 and G38.3 Probe Target +// Enable PROBE_DOUBLE_TOUCH if you want G38 to double touch +//#define G38_PROBE_TARGET +#if ENABLED(G38_PROBE_TARGET) + #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) +#endif + +// Moves (or segments) with fewer steps than this will be joined with the next move +#define MIN_STEPS_PER_SEGMENT 6 + +// The minimum pulse width (in µs) for stepping a stepper. +// Set this if you find stepping unreliable, or if using a very fast CPU. +#define MINIMUM_STEPPER_PULSE 0 // (µs) The smallest stepper pulse allowed + +// @section temperature + +// Control heater 0 and heater 1 in parallel. +//#define HEATERS_PARALLEL + +//=========================================================================== +//================================= Buffers ================================= +//=========================================================================== + +// @section hidden + +// 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, i.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 +#else + #define BLOCK_BUFFER_SIZE 16 // maximize block buffer +#endif + +// @section serial + +// The ASCII buffer for serial input +#define MAX_CMD_SIZE 96 +#define BUFSIZE 4 + +// Transmission to Host Buffer Size +// To save 386 bytes of PROGMEM (and TX_BUFFER_SIZE+3 bytes of RAM) set to 0. +// To buffer a simple "ok" you need 4 bytes. +// For ADVANCED_OK (M105) you need 32 bytes. +// For debug-echo: 128 bytes for the optimal speed. +// Other output doesn't need to be that speedy. +// :[0, 2, 4, 8, 16, 32, 64, 128, 256] +#define TX_BUFFER_SIZE 0 + +// Host Receive Buffer Size +// Without XON/XOFF flow control (see SERIAL_XON_XOFF below) 32 bytes should be enough. +// To use flow control, set this buffer size to at least 1024 bytes. +// :[0, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048] +//#define RX_BUFFER_SIZE 1024 + +#if RX_BUFFER_SIZE >= 1024 + // Enable to have the controller send XON/XOFF control characters to + // the host to signal the RX buffer is becoming full. + //#define SERIAL_XON_XOFF +#endif + +#if ENABLED(SDSUPPORT) + // Enable this option to collect and display the maximum + // RX queue usage after transferring a file to SD. + //#define SERIAL_STATS_MAX_RX_QUEUED + + // Enable this option to collect and display the number + // of dropped bytes after a file transfer to SD. + //#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! +//#define EMERGENCY_PARSER + +// Bad Serial-connections can miss a received command by sending an 'ok' +// Therefore some clients abort after 30 seconds in a timeout. +// Some other clients start sending commands while receiving a 'wait'. +// This "wait" is only sent when the buffer is empty. 1 second is a good value here. +//#define NO_TIMEOUTS 1000 // Milliseconds + +// Some clients will have this feature soon. This could make the NO_TIMEOUTS unnecessary. +//#define ADVANCED_OK + +// @section extras + +/** + * Firmware-based and LCD-controlled retract + * + * Add G10 / G11 commands for automatic firmware-based retract / recover. + * Use M207 and M208 to define parameters for retract / recover. + * + * Use M209 to enable or disable auto-retract. + * With auto-retract enabled, all G1 E moves within the set range + * will be converted to firmware-based retract/recover moves. + * + * Be sure to turn off auto-retract during filament change. + * + * Note that M207 / M208 / M209 settings are saved to EEPROM. + * + */ +//#define FWRETRACT // ONLY PARTIALLY TESTED +#if ENABLED(FWRETRACT) + #define MIN_AUTORETRACT 0.1 // When auto-retract is on, convert E moves of this length and over + #define MAX_AUTORETRACT 10.0 // Upper limit for auto-retract conversion + #define RETRACT_LENGTH 3 // Default retract length (positive mm) + #define RETRACT_LENGTH_SWAP 13 // Default swap retract length (positive mm), for extruder change + #define RETRACT_FEEDRATE 45 // Default feedrate for retracting (mm/s) + #define RETRACT_ZLIFT 0 // Default retract Z-lift + #define RETRACT_RECOVER_LENGTH 0 // Default additional recover length (mm, added to retract length when recovering) + #define RETRACT_RECOVER_LENGTH_SWAP 0 // Default additional swap recover length (mm, added to retract length when recovering from extruder change) + #define RETRACT_RECOVER_FEEDRATE 8 // Default feedrate for recovering from retraction (mm/s) + #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) +#endif + +/** + * Advanced Pause + * Experimental feature for filament change support and for parking the nozzle when paused. + * Adds the GCode M600 for initiating filament change. + * If PARK_HEAD_ON_PAUSE enabled, adds the GCode M125 to pause printing and park the nozzle. + * + * Requires an LCD display. + * This feature is required for the default FILAMENT_RUNOUT_SCRIPT. + */ +//#define ADVANCED_PAUSE_FEATURE +#if ENABLED(ADVANCED_PAUSE_FEATURE) + #define PAUSE_PARK_X_POS 3 // X position of hotend + #define PAUSE_PARK_Y_POS 3 // Y position of hotend + #define PAUSE_PARK_Z_ADD 10 // Z addition of hotend (lift) + #define PAUSE_PARK_XY_FEEDRATE 100 // X and Y axes feedrate in mm/s (also used for delta printers Z axis) + #define PAUSE_PARK_Z_FEEDRATE 5 // Z axis feedrate in mm/s (not used for delta printers) + #define PAUSE_PARK_RETRACT_FEEDRATE 60 // Initial retract feedrate in mm/s + #define PAUSE_PARK_RETRACT_LENGTH 2 // Initial retract in mm + // It is a short retract used immediately after print interrupt before move to filament exchange position + #define FILAMENT_CHANGE_UNLOAD_FEEDRATE 10 // Unload filament feedrate in mm/s - filament unloading can be fast + #define FILAMENT_CHANGE_UNLOAD_LENGTH 100 // Unload filament length from hotend in mm + // Longer length for bowden printers to unload filament from whole bowden tube, + // shorter length for printers without bowden to unload filament from extruder only, + // 0 to disable unloading for manual unloading + #define FILAMENT_CHANGE_LOAD_FEEDRATE 6 // Load filament feedrate in mm/s - filament loading into the bowden tube can be fast + #define FILAMENT_CHANGE_LOAD_LENGTH 0 // Load filament length over hotend in mm + // Longer length for bowden printers to fast load filament into whole bowden tube over the hotend, + // Short or zero length for printers without bowden where loading is not used + #define ADVANCED_PAUSE_EXTRUDE_FEEDRATE 3 // Extrude filament feedrate in mm/s - must be slower than load feedrate + #define ADVANCED_PAUSE_EXTRUDE_LENGTH 50 // Extrude filament length in mm after filament is loaded over the hotend, + // 0 to disable for manual extrusion + // Filament can be extruded repeatedly from the filament exchange menu to fill the hotend, + // or until outcoming filament color is not clear for filament color change + #define PAUSE_PARK_NOZZLE_TIMEOUT 45 // Turn off nozzle if user doesn't change filament within this time limit in seconds + #define FILAMENT_CHANGE_NUMBER_OF_ALERT_BEEPS 5 // Number of alert beeps before printer goes quiet + #define PAUSE_PARK_NO_STEPPER_TIMEOUT // Enable to have stepper motors hold position during filament change + // even if it takes longer than DEFAULT_STEPPER_DEACTIVE_TIME. + //#define PARK_HEAD_ON_PAUSE // Go to filament change position on pause, return to print position on resume + //#define HOME_BEFORE_FILAMENT_CHANGE // Ensure homing has been completed prior to parking for filament change +#endif + +// @section tmc + +/** + * Enable this section if you have TMC26X motor drivers. + * You will need to import the TMC26XStepper library into the Arduino IDE for this + * (https://github.com/trinamic/TMC26XStepper.git) + */ +//#define HAVE_TMCDRIVER + +#if ENABLED(HAVE_TMCDRIVER) + + //#define X_IS_TMC + //#define X2_IS_TMC + //#define Y_IS_TMC + //#define Y2_IS_TMC + //#define Z_IS_TMC + //#define Z2_IS_TMC + //#define E0_IS_TMC + //#define E1_IS_TMC + //#define E2_IS_TMC + //#define E3_IS_TMC + //#define E4_IS_TMC + + #define X_MAX_CURRENT 1000 // in mA + #define X_SENSE_RESISTOR 91 // in mOhms + #define X_MICROSTEPS 16 // number of microsteps + + #define X2_MAX_CURRENT 1000 + #define X2_SENSE_RESISTOR 91 + #define X2_MICROSTEPS 16 + + #define Y_MAX_CURRENT 1000 + #define Y_SENSE_RESISTOR 91 + #define Y_MICROSTEPS 16 + + #define Y2_MAX_CURRENT 1000 + #define Y2_SENSE_RESISTOR 91 + #define Y2_MICROSTEPS 16 + + #define Z_MAX_CURRENT 1000 + #define Z_SENSE_RESISTOR 91 + #define Z_MICROSTEPS 16 + + #define Z2_MAX_CURRENT 1000 + #define Z2_SENSE_RESISTOR 91 + #define Z2_MICROSTEPS 16 + + #define E0_MAX_CURRENT 1000 + #define E0_SENSE_RESISTOR 91 + #define E0_MICROSTEPS 16 + + #define E1_MAX_CURRENT 1000 + #define E1_SENSE_RESISTOR 91 + #define E1_MICROSTEPS 16 + + #define E2_MAX_CURRENT 1000 + #define E2_SENSE_RESISTOR 91 + #define E2_MICROSTEPS 16 + + #define E3_MAX_CURRENT 1000 + #define E3_SENSE_RESISTOR 91 + #define E3_MICROSTEPS 16 + + #define E4_MAX_CURRENT 1000 + #define E4_SENSE_RESISTOR 91 + #define E4_MICROSTEPS 16 + +#endif + +// @section TMC2130 + +/** + * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. + * + * You'll also need the TMC2130Stepper Arduino library + * (https://github.com/teemuatlut/TMC2130Stepper). + * + * To use TMC2130 stepper drivers in SPI mode connect your SPI2130 pins to + * the hardware SPI interface on your board and define the required CS pins + * in your `pins_MYBOARD.h` file. (e.g., RAMPS 1.4 uses AUX3 pins `X_CS_PIN 53`, `Y_CS_PIN 49`, etc.). + */ +//#define HAVE_TMC2130 + +#if ENABLED(HAVE_TMC2130) + + // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY + //#define X_IS_TMC2130 + //#define X2_IS_TMC2130 + //#define Y_IS_TMC2130 + //#define Y2_IS_TMC2130 + //#define Z_IS_TMC2130 + //#define Z2_IS_TMC2130 + //#define E0_IS_TMC2130 + //#define E1_IS_TMC2130 + //#define E2_IS_TMC2130 + //#define E3_IS_TMC2130 + //#define E4_IS_TMC2130 + + /** + * Stepper driver settings + */ + + #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 + #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current + #define INTERPOLATE 1 // Interpolate X/Y/Z_MICROSTEPS to 256 + + #define X_CURRENT 1000 // rms current in mA. Multiply by 1.41 for peak current. + #define X_MICROSTEPS 16 // 0..256 + + #define Y_CURRENT 1000 + #define Y_MICROSTEPS 16 + + #define Z_CURRENT 1000 + #define Z_MICROSTEPS 16 + + //#define X2_CURRENT 1000 + //#define X2_MICROSTEPS 16 + + //#define Y2_CURRENT 1000 + //#define Y2_MICROSTEPS 16 + + //#define Z2_CURRENT 1000 + //#define Z2_MICROSTEPS 16 + + //#define E0_CURRENT 1000 + //#define E0_MICROSTEPS 16 + + //#define E1_CURRENT 1000 + //#define E1_MICROSTEPS 16 + + //#define E2_CURRENT 1000 + //#define E2_MICROSTEPS 16 + + //#define E3_CURRENT 1000 + //#define E3_MICROSTEPS 16 + + //#define E4_CURRENT 1000 + //#define E4_MICROSTEPS 16 + + /** + * Use Trinamic's ultra quiet stepping mode. + * When disabled, Marlin will use spreadCycle stepping mode. + */ + #define STEALTHCHOP + + /** + * Let Marlin automatically control stepper current. + * This is still an experimental feature. + * Increase current every 5s by CURRENT_STEP until stepper temperature prewarn gets triggered, + * then decrease current by CURRENT_STEP until temperature prewarn is cleared. + * Adjusting starts from X/Y/Z/E_CURRENT but will not increase over AUTO_ADJUST_MAX + * 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. + * M906 S1 - Start adjusting current + * M906 S0 - Stop adjusting current + * M911 - Report stepper driver overtemperature pre-warn condition. + * M912 - Clear stepper driver overtemperature pre-warn condition flag. + */ + //#define AUTOMATIC_CURRENT_CONTROL + + #if ENABLED(AUTOMATIC_CURRENT_CONTROL) + #define CURRENT_STEP 50 // [mA] + #define AUTO_ADJUST_MAX 1300 // [mA], 1300mA_rms = 1840mA_peak + #define REPORT_CURRENT_CHANGE + #endif + + /** + * The driver will switch to spreadCycle when stepper speed is over HYBRID_THRESHOLD. + * This mode allows for faster movements at the expense of higher noise levels. + * STEALTHCHOP needs to be enabled. + * M913 X/Y/Z/E to live tune the setting + */ + //#define HYBRID_THRESHOLD + + #define X_HYBRID_THRESHOLD 100 // [mm/s] + #define X2_HYBRID_THRESHOLD 100 + #define Y_HYBRID_THRESHOLD 100 + #define Y2_HYBRID_THRESHOLD 100 + #define Z_HYBRID_THRESHOLD 4 + #define Z2_HYBRID_THRESHOLD 4 + #define E0_HYBRID_THRESHOLD 30 + #define E1_HYBRID_THRESHOLD 30 + #define E2_HYBRID_THRESHOLD 30 + #define E3_HYBRID_THRESHOLD 30 + #define E4_HYBRID_THRESHOLD 30 + + /** + * Use stallGuard2 to sense an obstacle and trigger an endstop. + * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. + * If used along with STEALTHCHOP, the movement will be louder when homing. This is normal. + * + * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. + * Higher values make the system LESS sensitive. + * Lower value make the system MORE sensitive. + * Too low values can lead to false positives, while too high values will collide the axis without triggering. + * It is advised to set X/Y_HOME_BUMP_MM to 0. + * M914 X/Y to live tune the setting + */ + //#define SENSORLESS_HOMING + + #if ENABLED(SENSORLESS_HOMING) + #define X_HOMING_SENSITIVITY 19 + #define Y_HOMING_SENSITIVITY 19 + #endif + + /** + * You can set your own advanced settings by filling in predefined functions. + * A list of available functions can be found on the library github page + * https://github.com/teemuatlut/TMC2130Stepper + * + * Example: + * #define TMC2130_ADV() { \ + * stepperX.diag0_temp_prewarn(1); \ + * stepperX.interpolate(0); \ + * } + */ + #define TMC2130_ADV() { } + +#endif // HAVE_TMC2130 + +// @section L6470 + +/** + * Enable this section if you have L6470 motor drivers. + * You need to import the L6470 library into the Arduino IDE for this. + * (https://github.com/ameyer/Arduino-L6470) + */ + +//#define HAVE_L6470DRIVER +#if ENABLED(HAVE_L6470DRIVER) + + //#define X_IS_L6470 + //#define X2_IS_L6470 + //#define Y_IS_L6470 + //#define Y2_IS_L6470 + //#define Z_IS_L6470 + //#define Z2_IS_L6470 + //#define E0_IS_L6470 + //#define E1_IS_L6470 + //#define E2_IS_L6470 + //#define E3_IS_L6470 + //#define E4_IS_L6470 + + #define X_MICROSTEPS 16 // number of microsteps + #define X_K_VAL 50 // 0 - 255, Higher values, are higher power. Be careful not to go too high + #define X_OVERCURRENT 2000 // maxc current in mA. If the current goes over this value, the driver will switch off + #define X_STALLCURRENT 1500 // current in mA where the driver will detect a stall + + #define X2_MICROSTEPS 16 + #define X2_K_VAL 50 + #define X2_OVERCURRENT 2000 + #define X2_STALLCURRENT 1500 + + #define Y_MICROSTEPS 16 + #define Y_K_VAL 50 + #define Y_OVERCURRENT 2000 + #define Y_STALLCURRENT 1500 + + #define Y2_MICROSTEPS 16 + #define Y2_K_VAL 50 + #define Y2_OVERCURRENT 2000 + #define Y2_STALLCURRENT 1500 + + #define Z_MICROSTEPS 16 + #define Z_K_VAL 50 + #define Z_OVERCURRENT 2000 + #define Z_STALLCURRENT 1500 + + #define Z2_MICROSTEPS 16 + #define Z2_K_VAL 50 + #define Z2_OVERCURRENT 2000 + #define Z2_STALLCURRENT 1500 + + #define E0_MICROSTEPS 16 + #define E0_K_VAL 50 + #define E0_OVERCURRENT 2000 + #define E0_STALLCURRENT 1500 + + #define E1_MICROSTEPS 16 + #define E1_K_VAL 50 + #define E1_OVERCURRENT 2000 + #define E1_STALLCURRENT 1500 + + #define E2_MICROSTEPS 16 + #define E2_K_VAL 50 + #define E2_OVERCURRENT 2000 + #define E2_STALLCURRENT 1500 + + #define E3_MICROSTEPS 16 + #define E3_K_VAL 50 + #define E3_OVERCURRENT 2000 + #define E3_STALLCURRENT 1500 + + #define E4_MICROSTEPS 16 + #define E4_K_VAL 50 + #define E4_OVERCURRENT 2000 + #define E4_STALLCURRENT 1500 + +#endif + +/** + * TWI/I2C BUS + * + * This feature is an EXPERIMENTAL feature so it shall not be used on production + * machines. Enabling this will allow you to send and receive I2C data from slave + * devices on the bus. + * + * ; Example #1 + * ; This macro send the string "Marlin" to the slave device with address 0x63 (99) + * ; It uses multiple M260 commands with one B arg + * M260 A99 ; Target slave address + * M260 B77 ; M + * M260 B97 ; a + * M260 B114 ; r + * M260 B108 ; l + * M260 B105 ; i + * M260 B110 ; n + * M260 S1 ; Send the current buffer + * + * ; Example #2 + * ; Request 6 bytes from slave device with address 0x63 (99) + * M261 A99 B5 + * + * ; Example #3 + * ; Example serial output of a M261 request + * echo:i2c-reply: from:99 bytes:5 data:hello + */ + +// @section i2cbus + +//#define EXPERIMENTAL_I2CBUS +#define I2C_SLAVE_ADDRESS 0 // Set a value from 8 to 127 to act as a slave + +// @section extras + +/** + * Spindle & Laser control + * + * Add the M3, M4, and M5 commands to turn the spindle/laser on and off, and + * to set spindle speed, spindle direction, and laser power. + * + * SuperPid is a router/spindle speed controller used in the CNC milling community. + * Marlin can be used to turn the spindle on and off. It can also be used to set + * the spindle speed from 5,000 to 30,000 RPM. + * + * 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. + */ +//#define SPINDLE_LASER_ENABLE +#if ENABLED(SPINDLE_LASER_ENABLE) + + #define SPINDLE_LASER_ENABLE_INVERT false // set to "true" if the on/off function is reversed + #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 // delay in milliseconds to allow the spindle/laser to come up to speed/power + #define SPINDLE_LASER_POWERDOWN_DELAY 5000 // delay in milliseconds to allow the spindle to stop + #define SPINDLE_DIR_CHANGE true // set to true if your spindle controller supports changing spindle direction + #define SPINDLE_INVERT_DIR false + #define SPINDLE_STOP_ON_DIR_CHANGE true // set to true if Marlin should stop the spindle before changing rotation direction + + /** + * The M3 & M4 commands use the following equation to convert PWM duty cycle to speed/power + * + * SPEED/POWER = PWM duty cycle * SPEED_POWER_SLOPE + SPEED_POWER_INTERCEPT + * where PWM duty cycle varies from 0 to 255 + * + * set the following for your controller (ALL MUST BE SET) + */ + + #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_SLOPE 0.3922 + //#define SPEED_POWER_INTERCEPT 0 + //#define SPEED_POWER_MIN 10 + //#define SPEED_POWER_MAX 100 // 0-100% +#endif + +/** + * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins + */ +//#define PINS_DEBUGGING + +/** + * Auto-report temperatures with M155 S + */ +#define AUTO_REPORT_TEMPERATURES + +/** + * Include capabilities in M115 output + */ +#define EXTENDED_CAPABILITIES_REPORT + +/** + * Volumetric extrusion default state + * 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. + */ +//#define VOLUMETRIC_DEFAULT_ON + +/** + * Enable this option for a leaner build of Marlin that removes all + * workspace offsets, simplifying coordinate transformations, leveling, etc. + * + * - M206 and M428 are disabled. + * - G92 will revert to its behavior from Marlin 1.0. + */ +//#define NO_WORKSPACE_OFFSETS + +/** + * 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. + * + * For clients that use a fixed-width font (like OctoPrint), leave this set to 1.0. + * Otherwise, adjust according to your client and font. + */ +#define PROPORTIONAL_FONT_RATIO 1.0 + +/** + * Spend 28 bytes of SRAM to optimize the GCode parser + */ +#define FASTER_GCODE_PARSER + +/** + * User-defined menu items that execute custom GCode + */ +//#define CUSTOM_USER_MENUS +#if ENABLED(CUSTOM_USER_MENUS) + #define USER_SCRIPT_DONE "M117 User Script Done" + #define USER_SCRIPT_AUDIBLE_FEEDBACK + //#define USER_SCRIPT_RETURN // Return to status screen after a script + + #define USER_DESC_1 "Home & UBL Info" + #define USER_GCODE_1 "G28\nG29 W" + + #define USER_DESC_2 "Preheat for PLA" + #define USER_GCODE_2 "M140 S" STRINGIFY(PREHEAT_1_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND) + + #define USER_DESC_3 "Preheat for ABS" + #define USER_GCODE_3 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND) + + #define USER_DESC_4 "Heat Bed/Home/Level" + #define USER_GCODE_4 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nG28\nG29" + + #define USER_DESC_5 "Home & Info" + #define USER_GCODE_5 "G28\nM503" +#endif + +/** + * Specify an action command to send to the host when the printer is killed. + * Will be sent in the form '//action:ACTION_ON_KILL', e.g. '//action:poweroff'. + * The host must be configured to handle the action command. + */ +//#define ACTION_ON_KILL "poweroff" + +//=========================================================================== +//====================== I2C Position Encoder Settings ====================== +//=========================================================================== + +/** + * I2C position encoders for closed loop control. + * Developed by Chris Barr at Aus3D. + * + * Wiki: http://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/ + * + * Reilabuild encoders have been modified to improve reliability. + */ + +//#define I2C_POSITION_ENCODERS +#if ENABLED(I2C_POSITION_ENCODERS) + + #define I2CPE_ENCODER_CNT 1 // The number of encoders installed; max of 5 + // encoders supported currently. + + #define I2CPE_ENC_1_ADDR I2CPE_PRESET_ADDR_X // I2C address of the encoder. 30-200. + #define I2CPE_ENC_1_AXIS X_AXIS // Axis the encoder module is installed on. _AXIS. + #define I2CPE_ENC_1_TYPE I2CPE_ENC_TYPE_LINEAR // Type of encoder: I2CPE_ENC_TYPE_LINEAR -or- + // I2CPE_ENC_TYPE_ROTARY. + #define I2CPE_ENC_1_TICKS_UNIT 2048 // 1024 for magnetic strips with 2mm poles; 2048 for + // 1mm poles. For linear encoders this is ticks / mm, + // for rotary encoders this is ticks / revolution. + //#define I2CPE_ENC_1_TICKS_REV (16 * 200) // Only needed for rotary encoders; number of stepper + // steps per full revolution (motor steps/rev * microstepping) + //#define I2CPE_ENC_1_INVERT // Invert the direction of axis travel. + #define I2CPE_ENC_1_EC_METHOD I2CPE_ECM_NONE // Type of error error correction. + #define I2CPE_ENC_1_EC_THRESH 0.10 // Threshold size for error (in mm) above which the + // printer will attempt to correct the error; errors + // smaller than this are ignored to minimize effects of + // measurement noise / latency (filter). + + #define I2CPE_ENC_2_ADDR I2CPE_PRESET_ADDR_Y // Same as above, but for encoder 2. + #define I2CPE_ENC_2_AXIS Y_AXIS + #define I2CPE_ENC_2_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_ENC_2_TICKS_UNIT 2048 + //#define I2CPE_ENC_2_TICKS_REV (16 * 200) + //#define I2CPE_ENC_2_INVERT + #define I2CPE_ENC_2_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_ENC_2_EC_THRESH 0.10 + + #define I2CPE_ENC_3_ADDR I2CPE_PRESET_ADDR_Z // Encoder 3. Add additional configuration options + #define I2CPE_ENC_3_AXIS Z_AXIS // as above, or use defaults below. + + #define I2CPE_ENC_4_ADDR I2CPE_PRESET_ADDR_E // Encoder 4. + #define I2CPE_ENC_4_AXIS E_AXIS + + #define I2CPE_ENC_5_ADDR 34 // Encoder 5. + #define I2CPE_ENC_5_AXIS E_AXIS + + // Default settings for encoders which are enabled, but without settings configured above. + #define I2CPE_DEF_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_DEF_ENC_TICKS_UNIT 2048 + #define I2CPE_DEF_TICKS_REV (16 * 200) + #define I2CPE_DEF_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_DEF_EC_THRESH 0.1 + + //#define I2CPE_ERR_THRESH_ABORT 100.0 // Threshold size for error (in mm) error on any given + // axis after which the printer will abort. Comment out to + // disable abort behaviour. + + #define I2CPE_TIME_TRUSTED 10000 // After an encoder fault, there must be no further fault + // for this amount of time (in ms) before the encoder + // is trusted again. + + /** + * Position is checked every time a new command is executed from the buffer but during long moves, + * this setting determines the minimum update time between checks. A value of 100 works well with + * error rolling average when attempting to correct only for skips and not for vibration. + */ + #define I2CPE_MIN_UPD_TIME_MS 100 // Minimum time in miliseconds between encoder checks. + + // Use a rolling average to identify persistant errors that indicate skips, as opposed to vibration and noise. + #define I2CPE_ERR_ROLLING_AVERAGE + +#endif // I2C_POSITION_ENCODERS + +/** + * MAX7219 Debug Matrix + * + * Add support for a low-cost 8x8 LED Matrix based on the Max7219 chip, which can be used as a status + * display. Requires 3 signal wires. Some useful debug options are included to demonstrate its usage. + * + * Fully assembled MAX7219 boards can be found on the internet for under $2(US). + * For example, see https://www.ebay.com/sch/i.html?_nkw=332349290049 + */ +//#define MAX7219_DEBUG +#if ENABLED(MAX7219_DEBUG) + #define MAX7219_CLK_PIN 64 // 77 on Re-ARM // Configuration of the 3 pins to control the display + #define MAX7219_DIN_PIN 57 // 78 on Re-ARM + #define MAX7219_LOAD_PIN 44 // 79 on Re-ARM + + /** + * Sample debug features + * If you add more debug displays, be careful to avoid conflicts! + */ + #define MAX7219_DEBUG_PRINTER_ALIVE // Blink corner LED of 8x8 matrix to show that the firmware is functioning + #define MAX7219_DEBUG_STEPPER_HEAD 3 // Show the stepper queue head position on this and the next LED matrix row + #define MAX7219_DEBUG_STEPPER_TAIL 5 // Show the stepper queue tail position on this and the next LED matrix row + + #define MAX7219_DEBUG_STEPPER_QUEUE 0 // Show the current stepper queue depth on this and the next LED matrix row + // If you experience stuttering, reboots, etc. this option can reveal how + // tweaks made to the configuration are affecting the printer in real-time. +#endif + +#endif // CONFIGURATION_ADV_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/delta/FLSUN/kossel_mini/Configuration.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/delta/FLSUN/kossel_mini/Configuration.h new file mode 100644 index 00000000..72e36a46 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/delta/FLSUN/kossel_mini/Configuration.h @@ -0,0 +1,1821 @@ +/** + * 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 . + * + */ + +/** + * Configuration.h + * + * Basic settings such as: + * + * - Type of electronics + * - Type of temperature sensor + * - Printer geometry + * - Endstop configuration + * - LCD controller + * - Extra features + * + * Advanced settings can be found in Configuration_adv.h + * + */ +#ifndef CONFIGURATION_H +#define CONFIGURATION_H +#define CONFIGURATION_H_VERSION 010100 + +//=========================================================================== +//============================= Getting Started ============================= +//=========================================================================== + +/** + * Here are some standard links for getting your machine calibrated: + * + * http://reprap.org/wiki/Calibration + * http://youtu.be/wAL9d7FgInk + * http://calculator.josefprusa.cz + * http://reprap.org/wiki/Triffid_Hunter%27s_Calibration_Guide + * http://www.thingiverse.com/thing:5573 + * https://sites.google.com/site/repraplogphase/calibration-of-your-reprap + * http://www.thingiverse.com/thing:298812 + */ + +//=========================================================================== +//============================= DELTA Printer =============================== +//=========================================================================== +// For a Delta printer start with one of the configuration files in the +// example_configurations/delta directory and customize for your machine. +// + +//=========================================================================== +//============================= SCARA Printer =============================== +//=========================================================================== +// For a SCARA printer start with the configuration files in +// example_configurations/SCARA and customize for your machine. +// + +// @section info + +// User-specified version info of this build to display in [Pronterface, etc] terminal window during +// startup. Implementation of an idea by Prof Braino to inform user that any changes made to this +// build by the user have been successfully uploaded into firmware. +#define STRING_CONFIG_H_AUTHOR "(Michael Henke, flsun Kossel Mini)" // Who made the changes. +#define SHOW_BOOTSCREEN +#define STRING_SPLASH_LINE1 SHORT_BUILD_VERSION // will be shown during bootup in line 1 +#define STRING_SPLASH_LINE2 WEBSITE_URL // will be shown during bootup in line 2 + +// +// *** VENDORS PLEASE READ ***************************************************** +// +// Marlin now allow you to have a vendor boot image to be displayed on machine +// start. When SHOW_CUSTOM_BOOTSCREEN is defined Marlin will first show your +// custom boot image and then the default Marlin boot image is shown. +// +// We suggest for you to take advantage of this new feature and keep the Marlin +// boot image unmodified. For an example have a look at the bq Hephestos 2 +// example configuration folder. +// +//#define SHOW_CUSTOM_BOOTSCREEN +// @section machine + +/** + * Select which serial port on the board will be used for communication with the host. + * This allows the connection of wireless adapters (for instance) to non-default port pins. + * Serial port 0 is always used by the Arduino bootloader regardless of this setting. + * + * :[0, 1, 2, 3, 4, 5, 6, 7] + */ +#define SERIAL_PORT 0 + +/** + * This setting determines the communication speed of the printer. + * + * 250000 works in most cases, but you might try a lower speed if + * you commonly experience drop-outs during host printing. + * You may try up to 1000000 to speed up SD file transfer. + * + * :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000] + */ +#define BAUDRATE 250000 + +// Enable the Bluetooth serial interface on AT90USB devices +//#define BLUETOOTH + +// The following define selects which electronics board you have. +// Please choose the name from boards.h that matches your setup +#ifndef MOTHERBOARD + #define MOTHERBOARD BOARD_RAMPS_13_EFB +#endif + +// Optional custom name for your RepStrap or other custom machine +// Displayed in the LCD "Ready" message +#define CUSTOM_MACHINE_NAME "Mini Kossel" + +// Define this to set a unique identifier for this printer, (Used by some programs to differentiate between machines) +// You can use an online service to generate a random UUID. (eg http://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] +#define EXTRUDERS 1 + +// For Cyclops or any "multi-extruder" that shares a single nozzle. +//#define SINGLENOZZLE + +/** + * Průša MK2 Single Nozzle Multi-Material Multiplexer, and variants. + * + * This device allows one stepper driver on a control board to drive + * two to eight stepper motors, one at a time, in a manner suitable + * for extruders. + * + * This option only allows the multiplexer to switch on tool-change. + * Additional options to configure custom E moves are pending. + */ +//#define MK2_MULTIPLEXER +#if ENABLED(MK2_MULTIPLEXER) + // Override the default DIO selector pins here, if needed. + // Some pins files may provide defaults for these pins. + //#define E_MUX0_PIN 40 // Always Required + //#define E_MUX1_PIN 42 // Needed for 3 to 8 steppers + //#define E_MUX2_PIN 44 // Needed for 5 to 8 steppers +#endif + +// A dual extruder that uses a single stepper motor +//#define SWITCHING_EXTRUDER +#if ENABLED(SWITCHING_EXTRUDER) + #define SWITCHING_EXTRUDER_SERVO_NR 0 + #define SWITCHING_EXTRUDER_SERVO_ANGLES { 0, 90 } // Angles for E0, E1[, E2, E3] + #if EXTRUDERS > 3 + #define SWITCHING_EXTRUDER_E23_SERVO_NR 1 + #endif +#endif + +// A dual-nozzle that uses a servomotor to raise/lower one of the nozzles +//#define SWITCHING_NOZZLE +#if ENABLED(SWITCHING_NOZZLE) + #define SWITCHING_NOZZLE_SERVO_NR 0 + #define SWITCHING_NOZZLE_SERVO_ANGLES { 0, 90 } // Angles for E0, E1 + //#define HOTEND_OFFSET_Z { 0.0, 0.0 } +#endif + +/** + * Two separate X-carriages with extruders that connect to a moving part + * via a magnetic docking mechanism. Requires SOL1_PIN and SOL2_PIN. + */ +//#define PARKING_EXTRUDER +#if ENABLED(PARKING_EXTRUDER) + #define PARKING_EXTRUDER_SOLENOIDS_INVERT // If enabled, the solenoid is NOT magnetized with applied voltage + #define PARKING_EXTRUDER_SOLENOIDS_PINS_ACTIVE LOW // LOW or HIGH pin signal energizes the coil + #define PARKING_EXTRUDER_SOLENOIDS_DELAY 250 // Delay (ms) for magnetic field. No delay if 0 or not defined. + #define PARKING_EXTRUDER_PARKING_X { -78, 184 } // X positions for parking the extruders + #define PARKING_EXTRUDER_GRAB_DISTANCE 1 // mm to move beyond the parking point to grab the extruder + #define PARKING_EXTRUDER_SECURITY_RAISE 5 // Z-raise before parking + #define HOTEND_OFFSET_Z { 0.0, 1.3 } // Z-offsets of the two hotends. The first must be 0. +#endif + +/** + * "Mixing Extruder" + * - Adds a new code, M165, to set the current mix factors. + * - Extends the stepping routines to move multiple steppers in proportion to the mix. + * - Optional support for Repetier Firmware M163, M164, and virtual extruder. + * - This implementation supports only a single extruder. + * - Enable DIRECT_MIXING_IN_G1 for Pia Taubert's reference implementation + */ +//#define MIXING_EXTRUDER +#if ENABLED(MIXING_EXTRUDER) + #define MIXING_STEPPERS 2 // Number of steppers in your mixing extruder + #define MIXING_VIRTUAL_TOOLS 16 // Use the Virtual Tool method with M163 and M164 + //#define DIRECT_MIXING_IN_G1 // Allow ABCDHI mix factors in G1 movement commands +#endif + +// Offset of the extruders (uncomment if using more than one and relying on firmware to position when changing). +// The offset has to be X=0, Y=0 for the extruder 0 hotend (default extruder). +// For the other hotends it is their distance from the extruder 0 hotend. +//#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis +//#define HOTEND_OFFSET_Y {0.0, 5.00} // (in mm) for each extruder, offset of the hotend on the Y axis + +// @section machine + +/** + * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN + * + * 0 = No Power Switch + * 1 = ATX + * 2 = X-Box 360 203Watts (the blue wire connected to PS_ON and the red wire to VCC) + * + * :{ 0:'No power switch', 1:'ATX', 2:'X-Box 360' } + */ +#define POWER_SUPPLY 0 + +#if POWER_SUPPLY > 0 + // Enable this option to leave the PSU off at startup. + // Power to steppers and heaters will need to be turned on with M80. + //#define PS_DEFAULT_OFF +#endif + +// @section temperature + +//=========================================================================== +//============================= Thermal Settings ============================ +//=========================================================================== + +/** + * --NORMAL IS 4.7kohm PULLUP!-- 1kohm pullup can be used on hotend sensor, using correct resistor and table + * + * Temperature sensors available: + * + * -3 : thermocouple with MAX31855 (only for sensor 0) + * -2 : thermocouple with MAX6675 (only for sensor 0) + * -1 : thermocouple with AD595 + * 0 : not used + * 1 : 100k thermistor - best choice for EPCOS 100k (4.7k pullup) + * 2 : 200k thermistor - ATC Semitec 204GT-2 (4.7k pullup) + * 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 (Used in ParCan & J-Head) (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) + * 71 : 100k Honeywell thermistor 135-104LAF-J01 (4.7k pullup) + * 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) + * 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" + * 20 : the PT100 circuit found in the Ultimainboard V2.x + * 60 : 100k Maker's Tool Works Kapton Bed Thermistor beta=3950 + * 66 : 4.7M High Temperature thermistor from Dyze Design + * 70 : the 100K thermistor found in the bq Hephestos 2 + * 75 : 100k Generic Silicon Heat Pad with NTC 100K MGB18-104F39050L32 thermistor + * + * 1k ohm pullup tables - This is atypical, and requires changing out the 4.7k pullup for 1k. + * (but gives greater accuracy and more stable PID) + * 51 : 100k thermistor - EPCOS (1k pullup) + * 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 + * 1010 : Pt1000 with 1k pullup (non standard) + * 147 : Pt100 with 4k7 pullup + * 110 : Pt100 with 1k pullup (non standard) + * + * Use these for Testing or Development purposes. NEVER for production machine. + * 998 : Dummy Table that ALWAYS reads 25°C or the temperature defined below. + * 999 : Dummy Table that ALWAYS reads 100°C or the temperature defined below. + * + * :{ '0': "Not used", '1':"100k / 4.7k - EPCOS", '2':"200k / 4.7k - ATC Semitec 204GT-2", '3':"Mendel-parts / 4.7k", '4':"10k !! do not use for a hotend. Bad resolution at high temp. !!", '5':"100K / 4.7k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '6':"100k / 4.7k EPCOS - Not as accurate as Table 1", '7':"100k / 4.7k Honeywell 135-104LAG-J01", '8':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT", '9':"100k / 4.7k GE Sensing AL03006-58.2K-97-G1", '10':"100k / 4.7k RS 198-961", '11':"100k / 4.7k beta 3950 1%", '12':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT (calibrated for Makibox hot bed)", '13':"100k Hisens 3950 1% up to 300°C for hotend 'Simple ONE ' & hotend 'All In ONE'", '20':"PT100 (Ultimainboard V2.x)", '51':"100k / 1k - EPCOS", '52':"200k / 1k - ATC Semitec 204GT-2", '55':"100k / 1k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '60':"100k Maker's Tool Works Kapton Bed Thermistor beta=3950", '66':"Dyze Design 4.7M High Temperature thermistor", '70':"the 100K thermistor found in the bq Hephestos 2", '71':"100k / 4.7k Honeywell 135-104LAF-J01", '147':"Pt100 / 4.7k", '1047':"Pt1000 / 4.7k", '110':"Pt100 / 1k (non-standard)", '1010':"Pt1000 / 1k (non standard)", '-3':"Thermocouple + MAX31855 (only for sensor 0)", '-2':"Thermocouple + MAX6675 (only for sensor 0)", '-1':"Thermocouple + AD595",'998':"Dummy 1", '999':"Dummy 2" } + */ +#define TEMP_SENSOR_0 1 +#define TEMP_SENSOR_1 0 +#define TEMP_SENSOR_2 0 +#define TEMP_SENSOR_3 0 +#define TEMP_SENSOR_4 0 +#define TEMP_SENSOR_BED 1 + +// Dummy thermistor constant temperature readings, for use with 998 and 999 +#define DUMMY_THERMISTOR_998_VALUE 25 +#define DUMMY_THERMISTOR_999_VALUE 100 + +// 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 +#define MAX_REDUNDANT_TEMP_SENSOR_DIFF 5 + +// Extruder temperature must be close to target for this long before M109 returns success +#define TEMP_RESIDENCY_TIME 10 // (seconds) +#define TEMP_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// Bed temperature must be close to target for this long before M190 returns success +#define TEMP_BED_RESIDENCY_TIME 1 // (seconds) +#define TEMP_BED_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_BED_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// The minimal temperature defines the temperature below which the heater will not be enabled It is used +// to check that the wiring to the thermistor is not broken. +// Otherwise this would lead to the heater being powered on all the time. +#define HEATER_0_MINTEMP 5 +#define HEATER_1_MINTEMP 5 +#define HEATER_2_MINTEMP 5 +#define HEATER_3_MINTEMP 5 +#define HEATER_4_MINTEMP 5 +#define BED_MINTEMP 5 + +// When temperature exceeds max temp, your heater will be switched off. +// This feature exists to protect your hotend from overheating accidentally, but *NOT* from thermistor short/failure! +// You should use MINTEMP for thermistor short/failure protection. +#define HEATER_0_MAXTEMP 275 +#define HEATER_1_MAXTEMP 275 +#define HEATER_2_MAXTEMP 275 +#define HEATER_3_MAXTEMP 275 +#define HEATER_4_MAXTEMP 275 +#define BED_MAXTEMP 150 + +//=========================================================================== +//============================= PID Settings ================================ +//=========================================================================== +// PID Tuning Guide here: http://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 +#if ENABLED(PIDTEMP) + #define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. + //#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. + #define K1 0.95 //smoothing factor within the PID + + // 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 + + //E3D with 30MM fan + #define DEFAULT_Kp 24.77 + #define DEFAULT_Ki 1.84 + #define DEFAULT_Kd 83.61 + +#endif // PIDTEMP + +//=========================================================================== +//============================= PID > Bed Temperature Control =============== +//=========================================================================== +// Select PID or bang-bang with PIDTEMPBED. If bang-bang, BED_LIMIT_SWITCHING will enable hysteresis +// +// Uncomment this to enable PID on the bed. It uses the same frequency PWM as the extruder. +// If your PID_dT is the default, and correct for your hardware/configuration, that means 7.689Hz, +// which is fine for driving a square wave into a resistive load and does not significantly impact you FET heating. +// This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W heater. +// If your configuration is significantly different than this and you don't understand the issues involved, you probably +// shouldn't use bed PID until someone else verifies your hardware works. +// If this is enabled, find your own PID constants below. +//#define PIDTEMPBED + +//#define BED_LIMIT_SWITCHING + +// This sets the max power delivered to the bed, and replaces the HEATER_BED_DUTY_CYCLE_DIVIDER option. +// all forms of bed control obey this (PID, bang-bang, bang-bang with hysteresis) +// setting this to anything other than 255 enables a form of PWM to the bed just like HEATER_BED_DUTY_CYCLE_DIVIDER did, +// so you shouldn't use it unless you are OK with PWM on your bed. (see the comment on enabling PIDTEMPBED) +#define MAX_BED_POWER 255 // limits duty cycle to bed; 255=full current + +#if ENABLED(PIDTEMPBED) + + //#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) + //#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 + + //D-force + #define DEFAULT_bedKp 22.97 + #define DEFAULT_bedKi 3.76 + #define DEFAULT_bedKd 29.2 + + // FIND YOUR OWN: "M303 E-1 C8 S90" to run autotune on the bed at 90 degreesC for 8 cycles. +#endif // PIDTEMPBED + +// @section extruder + +// This option prevents extrusion if the temperature is below EXTRUDE_MINTEMP. +// It also enables the M302 command to set the minimum extrusion temperature +// or to allow moving the extruder regardless of the hotend temperature. +// *** IT IS HIGHLY RECOMMENDED TO LEAVE THIS OPTION ENABLED! *** +#define PREVENT_COLD_EXTRUSION +#define EXTRUDE_MINTEMP 175 + +// This option prevents a single extrusion longer than EXTRUDE_MAXLENGTH. +// Note that for Bowden Extruders a too-small value here may prevent loading. +#define PREVENT_LENGTHY_EXTRUDE +#define EXTRUDE_MAXLENGTH 300 + +//=========================================================================== +//======================== Thermal Runaway Protection ======================= +//=========================================================================== + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * If you get "Thermal Runaway" or "Heating failed" errors the + * details can be tuned in Configuration_adv.h + */ + +#define THERMAL_PROTECTION_HOTENDS // Enable thermal protection for all extruders +#define THERMAL_PROTECTION_BED // Enable thermal protection for the heated bed + +//=========================================================================== +//============================= Mechanical Settings ========================= +//=========================================================================== + +// @section machine + +// Uncomment one of these options to enable CoreXY, CoreXZ, or CoreYZ kinematics +// either in the usual order or reversed +//#define COREXY +//#define COREXZ +//#define COREYZ +//#define COREYX +//#define COREZX +//#define COREZY + +//=========================================================================== +//============================== Delta Settings ============================= +//=========================================================================== +// Enable DELTA kinematics and most of the default configuration for Deltas +#define DELTA + +#if ENABLED(DELTA) + + // Make delta curves from many straight lines (linear interpolation). + // This is a trade-off between visible corners (not enough segments) + // and processor overload (too many expensive sqrt calls). + #define DELTA_SEGMENTS_PER_SECOND 160 + + // After homing move down to a height where XY movement is unconstrained + //#define DELTA_HOME_TO_SAFE_ZONE + + // Delta calibration menu + // uncomment to add three points calibration menu option. + // See http://minow.blogspot.com/index.html#4918805519571907051 + //#define DELTA_CALIBRATION_MENU + + // uncomment to add G33 Delta Auto-Calibration (Enable EEPROM_SETTINGS to store results) + //#define DELTA_AUTO_CALIBRATION + + // NOTE NB all values for DELTA_* values MUST be floating point, so always have a decimal point in them + + #if ENABLED(DELTA_AUTO_CALIBRATION) + // set the default number of probe points : n*n (1 -> 7) + #define DELTA_CALIBRATION_DEFAULT_POINTS 4 + #endif + + #if ENABLED(DELTA_AUTO_CALIBRATION) || ENABLED(DELTA_CALIBRATION_MENU) + // Set the radius for the calibration probe points - max DELTA_PRINTABLE_RADIUS*0.869 for non-eccentric probes + #define DELTA_CALIBRATION_RADIUS 73.5 // mm + // Set the steprate for papertest probing + #define PROBE_MANUALLY_STEP 0.025 + #endif + + // Print surface diameter/2 minus unreachable space (avoid collisions with vertical towers). + #define DELTA_PRINTABLE_RADIUS 85.0 // mm + + // Center-to-center distance of the holes in the diagonal push rods. + #define DELTA_DIAGONAL_ROD 218.0 // mm + + // height from z=0 to home position + #define DELTA_HEIGHT 280.00 // get this value from auto calibrate + + #define DELTA_ENDSTOP_ADJ { 0.0, 0.0, 0.0 } // get these from auto calibrate + + // Horizontal distance bridged by diagonal push rods when effector is centered. + #define DELTA_RADIUS 101.0 //mm Get this value from auto calibrate + + // Trim adjustments for individual towers + // tower angle corrections for X and Y tower / rotate XYZ so Z tower angle = 0 + // measured in degrees anticlockwise looking from above the printer + #define DELTA_TOWER_ANGLE_TRIM { 0.0, 0.0, 0.0 } // get these values from auto calibrate + + // delta radius and diaginal rod adjustments measured in mm + //#define DELTA_RADIUS_TRIM_TOWER { 0.0, 0.0, 0.0 } + //#define DELTA_DIAGONAL_ROD_TRIM_TOWER { 0.0, 0.0, 0.0 } + +#endif + +//=========================================================================== +//============================== Endstop Settings =========================== +//=========================================================================== + +// @section homing + +// Specify here all the endstop connectors that are connected to any endstop or probe. +// Almost all printers will be using one per axis. Probes will use one or more of the +// extra connectors. Leave undefined any used for non-endstop and non-probe purposes. +//#define USE_XMIN_PLUG +//#define USE_YMIN_PLUG +#define USE_ZMIN_PLUG +#define USE_XMAX_PLUG +#define USE_YMAX_PLUG +#define USE_ZMAX_PLUG + +// coarse Endstop Settings +#define ENDSTOPPULLUPS // Comment this out (using // at the start of the line) to disable the endstop pullup resistors + +#if DISABLED(ENDSTOPPULLUPS) + // fine endstop settings: Individual pullups. will be ignored if ENDSTOPPULLUPS is defined + //#define ENDSTOPPULLUP_XMAX + //#define ENDSTOPPULLUP_YMAX + //#define ENDSTOPPULLUP_ZMAX + //#define ENDSTOPPULLUP_XMIN + //#define ENDSTOPPULLUP_YMIN + //#define ENDSTOPPULLUP_ZMIN + //#define ENDSTOPPULLUP_ZMIN_PROBE +#endif + +// Mechanical endstop with COM to ground and NC to Signal uses "false" here (most common setup). +#define X_MIN_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Y_MIN_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MIN_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define X_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Y_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MIN_PROBE_ENDSTOP_INVERTING false // set to true to invert the logic of the probe. + +// Enable this feature if all enabled endstop pins are interrupt-capable. +// This will remove the need to poll the interrupt pins, saving many CPU cycles. +//#define ENDSTOP_INTERRUPTS_FEATURE + +//============================================================================= +//============================== Movement Settings ============================ +//============================================================================= +// @section motion + +// delta speeds must be the same on xyz +/** + * Default Settings + * + * These settings can be reset by M502 + * + * Note that if EEPROM is enabled, saved values will override these. + */ + +/** + * With this option each E stepper can have its own factors for the + * following movement settings. If fewer factors are given than the + * total number of extruders, the last value applies to the rest. + */ +//#define DISTINCT_E_FACTORS + +/** + * Default Axis Steps Per Unit (steps/mm) + * Override with M92 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_AXIS_STEPS_PER_UNIT { 100, 100, 100, 90 } // default steps per unit for Kossel (GT2, 20 tooth) + +/** + * Default Max Feed Rate (mm/s) + * Override with M203 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_FEEDRATE { 200, 200, 200, 200 } + +/** + * Default Max Acceleration (change/s) change = mm/s + * (Maximum start speed for accelerated moves) + * Override with M201 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_ACCELERATION { 4000, 4000, 4000, 4000 } + +/** + * Default Acceleration (change/s) change = mm/s + * Override with M204 + * + * M204 P Acceleration + * M204 R Retract Acceleration + * M204 T Travel Acceleration + */ +#define DEFAULT_ACCELERATION 2500 // X, Y, Z and E acceleration for printing moves +#define DEFAULT_RETRACT_ACCELERATION 3000 // E acceleration for retracts +#define DEFAULT_TRAVEL_ACCELERATION 3000 // X, Y, Z acceleration for travel (non printing) moves + +/** + * Default Jerk (mm/s) + * Override with M205 X Y Z E + * + * "Jerk" specifies the minimum speed change that requires acceleration. + * When changing speed and direction, if the difference is less than the + * value set here, it may happen instantaneously. + */ +#define DEFAULT_XJERK 20.0 +#define DEFAULT_YJERK DEFAULT_XJERK +#define DEFAULT_ZJERK DEFAULT_YJERK // Must be same as XY for delta +#define DEFAULT_EJERK 5.0 + +//=========================================================================== +//============================= Z Probe Options ============================= +//=========================================================================== +// @section probes + +// +// See http://marlinfw.org/configuration/probes.html +// + +/** + * Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + * + * Enable this option for a probe connected to the Z Min endstop pin. + */ +#define Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + +/** + * Z_MIN_PROBE_ENDSTOP + * + * Enable this option for a probe connected to any pin except Z-Min. + * (By default Marlin assumes the Z-Max endstop pin.) + * To use a custom Z Probe pin, set Z_MIN_PROBE_PIN below. + * + * - The simplest option is to use a free endstop connector. + * - Use 5V for powered (usually inductive) sensors. + * + * - RAMPS 1.3/1.4 boards may use the 5V, GND, and Aux4->D32 pin: + * - For simple switches connect... + * - normally-closed switches to GND and D32. + * - normally-open switches to 5V and D32. + * + * WARNING: Setting the wrong pin may have unexpected and potentially + * disastrous consequences. Use with caution and do your homework. + * + */ +//#define Z_MIN_PROBE_ENDSTOP // A3K leave disabled! + +/** + * Probe Type + * + * Allen Key Probes, Servo Probes, Z-Sled Probes, FIX_MOUNTED_PROBE, etc. + * Activate one of these to use Auto Bed Leveling below. + */ + +/** + * The "Manual Probe" provides a means to do "Auto" Bed Leveling without a probe. + * Use G29 repeatedly, adjusting the Z height at each point with movement commands + * or (with LCD_BED_LEVELING) the LCD controller. + */ +//#define PROBE_MANUALLY + +/** + * A Fix-Mounted Probe either doesn't deploy or needs manual deployment. + * (e.g., an inductive probe or a nozzle-based probe-switch.) + */ +#define FIX_MOUNTED_PROBE + +/** + * Z Servo Probe, such as an endstop switch on a rotating arm. + */ +//#define Z_ENDSTOP_SERVO_NR 0 // Defaults to SERVO 0 connector. +//#define Z_SERVO_ANGLES {70,0} // Z Servo Deploy and Stow angles + +/** + * The BLTouch probe uses a Hall effect sensor and emulates a servo. + */ +//#define BLTOUCH +#if ENABLED(BLTOUCH) + //#define BLTOUCH_DELAY 375 // (ms) Enable and increase if needed +#endif + +/** + * Enable one or more of the following if probing seems unreliable. + * Heaters and/or fans can be disabled during probing to minimize electrical + * noise. A delay can also be added to allow noise and vibration to settle. + * These options are most useful for the BLTouch probe, but may also improve + * readings with inductive probes and piezo sensors. + */ +//#define PROBING_HEATERS_OFF // Turn heaters off when probing +//#define PROBING_FANS_OFF // Turn fans off when probing +//#define DELAY_BEFORE_PROBING 200 // (ms) To prevent vibrations from triggering piezo sensors + +// A probe that is deployed and stowed with a solenoid pin (SOL1_PIN) +//#define SOLENOID_PROBE + +// A sled-mounted probe like those designed by Charles Bell. +//#define Z_PROBE_SLED +//#define SLED_DOCKING_OFFSET 5 // The extra distance the X axis must travel to pickup the sled. 0 should be fine but you can push it further if you'd like. + +// +// For Z_PROBE_ALLEN_KEY see the Delta example configurations. +// + +/** + * Z Probe to nozzle (X,Y) offset, relative to (0, 0). + * X and Y offsets must be integers. + * + * In the following example the X and Y offsets are both positive: + * #define X_PROBE_OFFSET_FROM_EXTRUDER 10 + * #define Y_PROBE_OFFSET_FROM_EXTRUDER 10 + * + * +-- BACK ---+ + * | | + * L | (+) P | R <-- probe (20,20) + * E | | I + * F | (-) N (+) | G <-- nozzle (10,10) + * T | | H + * | (-) | T + * | | + * O-- FRONT --+ + * (0,0) + */ +#define X_PROBE_OFFSET_FROM_EXTRUDER 0 // X offset: -left +right [of the nozzle] +#define Y_PROBE_OFFSET_FROM_EXTRUDER 0 // Y offset: -front +behind [the nozzle] +#define Z_PROBE_OFFSET_FROM_EXTRUDER 0.25 // Z offset: -below +above [the nozzle] + +// X and Y axis travel speed (mm/m) between probes +#define XY_PROBE_SPEED 2000 + +// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +#define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z + +// Speed for the "accurate" probe of each point +#define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) + +// Use double touch for probing +#define PROBE_DOUBLE_TOUCH + +/** + * Allen key retractable z-probe as seen on many Kossel delta printers - http://reprap.org/wiki/Kossel#Automatic_bed_leveling_probe + * Deploys by touching z-axis belt. Retracts by pushing the probe down. Uses Z_MIN_PIN. + */ +//#define Z_PROBE_ALLEN_KEY + +#if ENABLED(Z_PROBE_ALLEN_KEY) + // 2 or 3 sets of coordinates for deploying and retracting the spring loaded touch probe on G29, + // if servo actuated touch probe is not defined. Uncomment as appropriate for your printer/probe. + + // Kossel Mini + #define Z_PROBE_ALLEN_KEY_DEPLOY_1_X 30.0 + #define Z_PROBE_ALLEN_KEY_DEPLOY_1_Y DELTA_PRINTABLE_RADIUS + #define Z_PROBE_ALLEN_KEY_DEPLOY_1_Z 100.0 + #define Z_PROBE_ALLEN_KEY_DEPLOY_1_FEEDRATE XY_PROBE_SPEED + + #define Z_PROBE_ALLEN_KEY_DEPLOY_2_X 0.0 + #define Z_PROBE_ALLEN_KEY_DEPLOY_2_Y DELTA_PRINTABLE_RADIUS + #define Z_PROBE_ALLEN_KEY_DEPLOY_2_Z 100.0 + #define Z_PROBE_ALLEN_KEY_DEPLOY_2_FEEDRATE (XY_PROBE_SPEED/10) + + #define Z_PROBE_ALLEN_KEY_DEPLOY_3_X Z_PROBE_ALLEN_KEY_DEPLOY_2_X * 0.75 + #define Z_PROBE_ALLEN_KEY_DEPLOY_3_Y Z_PROBE_ALLEN_KEY_DEPLOY_2_Y * 0.75 + #define Z_PROBE_ALLEN_KEY_DEPLOY_3_Z Z_PROBE_ALLEN_KEY_DEPLOY_2_Z + #define Z_PROBE_ALLEN_KEY_DEPLOY_3_FEEDRATE XY_PROBE_SPEED + + #define Z_PROBE_ALLEN_KEY_STOW_DEPTH 20 + // Move the probe into position + #define Z_PROBE_ALLEN_KEY_STOW_1_X -64.0 + #define Z_PROBE_ALLEN_KEY_STOW_1_Y 56.0 + #define Z_PROBE_ALLEN_KEY_STOW_1_Z 23.0 + #define Z_PROBE_ALLEN_KEY_STOW_1_FEEDRATE XY_PROBE_SPEED + // Move the nozzle down further to push the probe into retracted position. + #define Z_PROBE_ALLEN_KEY_STOW_2_X Z_PROBE_ALLEN_KEY_STOW_1_X + #define Z_PROBE_ALLEN_KEY_STOW_2_Y Z_PROBE_ALLEN_KEY_STOW_1_Y + #define Z_PROBE_ALLEN_KEY_STOW_2_Z (Z_PROBE_ALLEN_KEY_STOW_1_Z-Z_PROBE_ALLEN_KEY_STOW_DEPTH) + #define Z_PROBE_ALLEN_KEY_STOW_2_FEEDRATE (XY_PROBE_SPEED/10) + // Raise things back up slightly so we don't bump into anything + #define Z_PROBE_ALLEN_KEY_STOW_3_X Z_PROBE_ALLEN_KEY_STOW_2_X + #define Z_PROBE_ALLEN_KEY_STOW_3_Y Z_PROBE_ALLEN_KEY_STOW_2_Y + #define Z_PROBE_ALLEN_KEY_STOW_3_Z (Z_PROBE_ALLEN_KEY_STOW_1_Z+Z_PROBE_ALLEN_KEY_STOW_DEPTH) + #define Z_PROBE_ALLEN_KEY_STOW_3_FEEDRATE (XY_PROBE_SPEED/2) + + #define Z_PROBE_ALLEN_KEY_STOW_4_X 0.0 + #define Z_PROBE_ALLEN_KEY_STOW_4_Y 0.0 + #define Z_PROBE_ALLEN_KEY_STOW_4_Z Z_PROBE_ALLEN_KEY_STOW_3_Z + #define Z_PROBE_ALLEN_KEY_STOW_4_FEEDRATE XY_PROBE_SPEED + +#endif // Z_PROBE_ALLEN_KEY + +/** + * Z probes require clearance when deploying, stowing, and moving between + * probe points to avoid hitting the bed and other hardware. + * Servo-mounted probes require extra space for the arm to rotate. + * Inductive probes need space to keep from triggering early. + * + * Use these settings to specify the distance (mm) to raise the probe (or + * lower the bed). The values set here apply over and above any (negative) + * probe Z Offset set with Z_PROBE_OFFSET_FROM_EXTRUDER, M851, or the LCD. + * Only integer values >= 1 are valid here. + * + * Example: `M851 Z-5` with a CLEARANCE of 4 => 9mm from bed to nozzle. + * But: `M851 Z+1` with a CLEARANCE of 2 => 2mm from bed to nozzle. + */ +#define Z_CLEARANCE_DEPLOY_PROBE 50 // Z Clearance for Deploy/Stow +#define Z_CLEARANCE_BETWEEN_PROBES 5 // Z Clearance between probe points + +// For M851 give a range for adjusting the Z probe offset +#define Z_PROBE_OFFSET_RANGE_MIN -20 +#define Z_PROBE_OFFSET_RANGE_MAX 20 + +// Enable the M48 repeatability test to test probe accuracy +#define Z_MIN_PROBE_REPEATABILITY_TEST + +// For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1 +// :{ 0:'Low', 1:'High' } +#define X_ENABLE_ON 0 +#define Y_ENABLE_ON 0 +#define Z_ENABLE_ON 0 +#define E_ENABLE_ON 0 // For all extruders + +// Disables axis stepper immediately when it's not being used. +// 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 +//#define DISABLE_REDUCED_ACCURACY_WARNING + +// @section extruder + +#define DISABLE_E false // For all extruders +#define DISABLE_INACTIVE_EXTRUDER true // Keep only the active extruder enabled. + +// @section machine + +// Invert the stepper direction. Change (or reverse the motor connector) if an axis goes the wrong way. +#define INVERT_X_DIR true // DELTA does not invert +#define INVERT_Y_DIR true +#define INVERT_Z_DIR true + +// Enable this option for Toshiba stepper drivers +//#define CONFIG_STEPPERS_TOSHIBA + +// @section extruder + +// For direct drive extruder v9 set to true, for geared extruder set to false. +#define INVERT_E0_DIR false +#define INVERT_E1_DIR false +#define INVERT_E2_DIR false +#define INVERT_E3_DIR false +#define INVERT_E4_DIR false + +// @section homing + +//#define NO_MOTION_BEFORE_HOMING // Inhibit movement until all axes have been homed + +#define Z_HOMING_HEIGHT 15 // (in mm) Minimal z height before homing (G28) for Z clearance above the bed, clamps, ... + // Be sure you have this distance over your Z_MAX_POS in case. + +// Direction of endstops when homing; 1=MAX, -1=MIN +// :[-1,1] +#define X_HOME_DIR 1 // deltas always home to max +#define Y_HOME_DIR 1 +#define Z_HOME_DIR 1 + +// @section machine + +// The size of the print bed +#define X_BED_SIZE ((DELTA_PRINTABLE_RADIUS) * 2) +#define Y_BED_SIZE ((DELTA_PRINTABLE_RADIUS) * 2) + +// Travel limits (mm) after homing, corresponding to endstop positions. +#define X_MIN_POS -(DELTA_PRINTABLE_RADIUS) +#define Y_MIN_POS -(DELTA_PRINTABLE_RADIUS) +#define Z_MIN_POS 0 +#define X_MAX_POS DELTA_PRINTABLE_RADIUS +#define Y_MAX_POS DELTA_PRINTABLE_RADIUS +#define Z_MAX_POS MANUAL_Z_HOME_POS + +// If enabled, axes won't move below MIN_POS in response to movement commands. +#define MIN_SOFTWARE_ENDSTOPS +// If enabled, axes won't move above MAX_POS in response to movement commands. +#define MAX_SOFTWARE_ENDSTOPS + +/** + * Filament Runout Sensor + * A mechanical or opto endstop is used to check for the presence of filament. + * + * RAMPS-based boards use SERVO3_PIN. + * For other boards you may need to define FIL_RUNOUT_PIN. + * By default the firmware assumes HIGH = has filament, LOW = ran out + */ +//#define FILAMENT_RUNOUT_SENSOR +#if ENABLED(FILAMENT_RUNOUT_SENSOR) + #define FIL_RUNOUT_INVERTING false // set to true to invert the logic of the sensor. + #define ENDSTOPPULLUP_FIL_RUNOUT // Uncomment to use internal pullup for filament runout pins if the sensor is defined. + #define FILAMENT_RUNOUT_SCRIPT "M600" +#endif + +//=========================================================================== +//=============================== Bed Leveling ============================== +//=========================================================================== +// @section bedlevel + +/** + * Choose one of the options below to enable G29 Bed Leveling. The parameters + * and behavior of G29 will change depending on your selection. + * + * If using a Probe for Z Homing, enable Z_SAFE_HOMING also! + * + * - AUTO_BED_LEVELING_3POINT + * Probe 3 arbitrary points on the bed (that aren't collinear) + * You specify the XY coordinates of all 3 points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_LINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_BILINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a mesh, best for large or uneven beds. + * + * - AUTO_BED_LEVELING_UBL (Unified Bed Leveling) + * A comprehensive bed leveling system combining the features and benefits + * of other systems. UBL also includes integrated Mesh Generation, Mesh + * Validation and Mesh Editing systems. Currently, UBL is only checked out + * for Cartesian Printers. That said, it was primarily designed to correct + * poor quality Delta Printers. If you feel adventurous and have a Delta, + * please post an issue if something doesn't work correctly. Initially, + * you will need to set a reduced bed size so you have a rectangular area + * to test on. + * + * - MESH_BED_LEVELING + * Probe a grid manually + * The result is a mesh, suitable for large or uneven beds. (See BILINEAR.) + * For machines without a probe, Mesh Bed Leveling provides a method to perform + * leveling in steps so you can manually adjust the Z height at each grid-point. + * With an LCD controller the process is guided step-by-step. + */ +//#define AUTO_BED_LEVELING_3POINT +//#define AUTO_BED_LEVELING_LINEAR +#define AUTO_BED_LEVELING_BILINEAR +//#define AUTO_BED_LEVELING_UBL +//#define MESH_BED_LEVELING + +/** + * Enable detailed logging of G28, G29, M48, etc. + * Turn on with the command 'M111 S32'. + * NOTE: Requires a lot of PROGMEM! + */ +//#define DEBUG_LEVELING_FEATURE + +#if ENABLED(MESH_BED_LEVELING) || ENABLED(AUTO_BED_LEVELING_BILINEAR) || ENABLED(AUTO_BED_LEVELING_UBL) + // Gradually reduce leveling correction until a set height is reached, + // at which point movement will be level to the machine's XY plane. + // The height can be set with M420 Z + //#define ENABLE_LEVELING_FADE_HEIGHT +#endif + +#if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Set the number of grid points per dimension. + #define GRID_MAX_POINTS_X 9 + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + // Set the boundaries for probing (where the probe can reach). + #define DELTA_PROBEABLE_RADIUS (DELTA_PRINTABLE_RADIUS - 15) + #define LEFT_PROBE_BED_POSITION -(DELTA_PROBEABLE_RADIUS) + #define RIGHT_PROBE_BED_POSITION DELTA_PROBEABLE_RADIUS + #define FRONT_PROBE_BED_POSITION -(DELTA_PROBEABLE_RADIUS) + #define BACK_PROBE_BED_POSITION DELTA_PROBEABLE_RADIUS + + // The Z probe minimum outer margin (to validate G29 parameters). + #define MIN_PROBE_EDGE 10 + + // Probe along the Y axis, advancing X after each column + //#define PROBE_Y_FIRST + + #if ENABLED(AUTO_BED_LEVELING_BILINEAR) + // + // Experimental Subdivision of the grid by Catmull-Rom method. + // Synthesizes intermediate points to produce a more detailed mesh. + // + //#define ABL_BILINEAR_SUBDIVISION + #if ENABLED(ABL_BILINEAR_SUBDIVISION) + // Number of subdivisions between probe points + #define BILINEAR_SUBDIVISIONS 3 + #endif + + #endif + +#elif ENABLED(AUTO_BED_LEVELING_3POINT) + + // 3 arbitrary points to probe. + // A simple cross-product is used to estimate the plane of the bed. + #define ABL_PROBE_PT_1_X 15 + #define ABL_PROBE_PT_1_Y 180 + #define ABL_PROBE_PT_2_X 15 + #define ABL_PROBE_PT_2_Y 20 + #define ABL_PROBE_PT_3_X 170 + #define ABL_PROBE_PT_3_Y 20 + +#elif ENABLED(AUTO_BED_LEVELING_UBL) + + //=========================================================================== + //========================= Unified Bed Leveling ============================ + //=========================================================================== + + #define UBL_MESH_INSET 1 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 10 // Don't use more than 15 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + #define _PX(R,A) (R) * cos(RADIANS(A)) + #define _PY(R,A) (R) * sin(RADIANS(A)) + #define UBL_PROBE_PT_1_X _PX(DELTA_PROBEABLE_RADIUS, 0) // Probing points for 3-Point leveling of the mesh + #define UBL_PROBE_PT_1_Y _PY(DELTA_PROBEABLE_RADIUS, 0) + #define UBL_PROBE_PT_2_X _PX(DELTA_PROBEABLE_RADIUS, 120) + #define UBL_PROBE_PT_2_Y _PY(DELTA_PROBEABLE_RADIUS, 120) + #define UBL_PROBE_PT_3_X _PX(DELTA_PROBEABLE_RADIUS, 240) + #define UBL_PROBE_PT_3_Y _PY(DELTA_PROBEABLE_RADIUS, 240) + + #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation + #define UBL_MESH_EDIT_MOVES_Z // Sophisticated users prefer no movement of nozzle + +#elif ENABLED(MESH_BED_LEVELING) + + //=========================================================================== + //=================================== Mesh ================================== + //=========================================================================== + + #define MESH_INSET 10 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 3 // Don't use more than 7 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + //#define MESH_G28_REST_ORIGIN // After homing all axes ('G28' or 'G28 XYZ') rest Z at Z_MIN_POS + +#endif // BED_LEVELING + +/** + * Use the LCD controller for bed leveling + * Requires MESH_BED_LEVELING or PROBE_MANUALLY + */ +//#define LCD_BED_LEVELING + +#if ENABLED(LCD_BED_LEVELING) + #define MBL_Z_STEP 0.025 // Step size while manually probing Z axis. + #define LCD_PROBE_Z_RANGE 4 // Z Range centered on Z_MIN_POS for LCD Z adjustment +#endif + +// Add a menu item to move between bed corners for manual bed adjustment +//#define LEVEL_BED_CORNERS + +/** + * Commands to execute at the end of G29 probing. + * Useful to retract or move the Z probe out of the way. + */ +//#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) +#define BED_CENTER_AT_0_0 + +// Manually set the home position. Leave these undefined for automatic settings. +// For DELTA this is the top-center of the Cartesian print volume. +//#define MANUAL_X_HOME_POS 0 +//#define MANUAL_Y_HOME_POS 0 +#define MANUAL_Z_HOME_POS DELTA_HEIGHT // Distance between the nozzle to printbed after homing + +// Use "Z Safe Homing" to avoid homing with a Z probe outside the bed area. +// +// With this feature enabled: +// +// - 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). +// - 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_MIN_POS + X_MAX_POS) / 2) // X point for Z homing when homing all axis (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_MIN_POS + Y_MAX_POS) / 2) // Y point for Z homing when homing all axis (G28). +#endif + +// Delta only homes to Z +#define HOMING_FEEDRATE_Z (45*60) + +//============================================================================= +//============================= Additional Features =========================== +//============================================================================= + +// @section extras + +// +// EEPROM +// +// The microcontroller can store settings in the EEPROM, e.g. max velocity... +// M500 - stores parameters in EEPROM +// M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily). +// M502 - reverts to the default "factory settings". You still need to store them in EEPROM afterwards if you want to. +// +#define EEPROM_SETTINGS // Enable for M500 and M501 commands +//#define DISABLE_M503 // Saves ~2700 bytes of PROGMEM. Disable for release! +#define EEPROM_CHITCHAT // Give feedback on EEPROM commands. Disable to save PROGMEM. + +// +// Host Keepalive +// +// When enabled Marlin will send a busy status message to the host +// every couple of seconds when it can't accept commands. +// +#define HOST_KEEPALIVE_FEATURE // Disable this if your host doesn't like keepalive messages +#define DEFAULT_KEEPALIVE_INTERVAL 5 // Number of seconds between "busy" messages. Set with M113. +#define BUSY_WHILE_HEATING // Some hosts require "busy" messages even during heating + +// +// M100 Free Memory Watcher +// +//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose + +// +// G20/G21 Inch mode support +// +//#define INCH_MODE_SUPPORT + +// +// M149 Set temperature units support +// +//#define TEMPERATURE_UNITS_SUPPORT + +// @section temperature + +// Preheat Constants +#define PREHEAT_1_TEMP_HOTEND 180 +#define PREHEAT_1_TEMP_BED 70 +#define PREHEAT_1_FAN_SPEED 0 // Value from 0 to 255 + +#define PREHEAT_2_TEMP_HOTEND 240 +#define PREHEAT_2_TEMP_BED 100 +#define PREHEAT_2_FAN_SPEED 0 // Value from 0 to 255 + +/** + * Nozzle Park -- EXPERIMENTAL + * + * Park the nozzle at the given XYZ position on idle or G27. + * + * The "P" parameter controls the action applied to the Z axis: + * + * P0 (Default) If Z is below park Z raise the nozzle. + * P1 Raise the nozzle always to Z-park height. + * P2 Raise the nozzle by Z-park amount, limited to Z_MAX_POS. + */ +//#define NOZZLE_PARK_FEATURE + +#if ENABLED(NOZZLE_PARK_FEATURE) + // Specify a park position as { X, Y, Z } + #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 } +#endif + +/** + * Clean Nozzle Feature -- EXPERIMENTAL + * + * Adds the G12 command to perform a nozzle cleaning process. + * + * Parameters: + * P Pattern + * S Strokes / Repetitions + * T Triangles (P1 only) + * + * Patterns: + * P0 Straight line (default). This process requires a sponge type material + * at a fixed bed location. "S" specifies strokes (i.e. back-forth motions) + * between the start / end points. + * + * P1 Zig-zag pattern between (X0, Y0) and (X1, Y1), "T" specifies the + * number of zig-zag triangles to do. "S" defines the number of strokes. + * Zig-zags are done in whichever is the narrower dimension. + * For example, "G12 P1 S1 T3" will execute: + * + * -- + * | (X0, Y1) | /\ /\ /\ | (X1, Y1) + * | | / \ / \ / \ | + * A | | / \ / \ / \ | + * | | / \ / \ / \ | + * | (X0, Y0) | / \/ \/ \ | (X1, Y0) + * -- +--------------------------------+ + * |________|_________|_________| + * T1 T2 T3 + * + * P2 Circular pattern with middle at NOZZLE_CLEAN_CIRCLE_MIDDLE. + * "R" specifies the radius. "S" specifies the stroke count. + * Before starting, the nozzle moves to NOZZLE_CLEAN_START_POINT. + * + * Caveats: The ending Z should be the same as starting Z. + * Attention: EXPERIMENTAL. G-code arguments may change. + * + */ +//#define NOZZLE_CLEAN_FEATURE + +#if ENABLED(NOZZLE_CLEAN_FEATURE) + // Default number of pattern repetitions + #define NOZZLE_CLEAN_STROKES 12 + + // Default number of triangles + #define NOZZLE_CLEAN_TRIANGLES 3 + + // Specify positions as { X, Y, Z } + #define NOZZLE_CLEAN_START_POINT { 30, 30, (Z_MIN_POS + 1)} + #define NOZZLE_CLEAN_END_POINT {100, 60, (Z_MIN_POS + 1)} + + // Circular pattern radius + #define NOZZLE_CLEAN_CIRCLE_RADIUS 6.5 + // Circular pattern circle fragments number + #define NOZZLE_CLEAN_CIRCLE_FN 10 + // Middle point of circle + #define NOZZLE_CLEAN_CIRCLE_MIDDLE NOZZLE_CLEAN_START_POINT + + // Moves the nozzle to the initial position + #define NOZZLE_CLEAN_GOBACK +#endif + +/** + * Print Job Timer + * + * Automatically start and stop the print job timer on M104/M109/M190. + * + * M104 (hotend, no wait) - high temp = none, low temp = stop timer + * M109 (hotend, wait) - high temp = start timer, low temp = stop timer + * M190 (bed, wait) - high temp = start timer, low temp = none + * + * The timer can also be controlled with the following commands: + * + * M75 - Start the print job timer + * M76 - Pause the print job timer + * M77 - Stop the print job timer + */ +#define PRINTJOB_TIMER_AUTOSTART + +/** + * Print Counter + * + * Track statistical data such as: + * + * - Total print jobs + * - Total successful print jobs + * - Total failed print jobs + * - Total time printing + * + * View the current statistics with M78. + */ +#define PRINTCOUNTER + +//============================================================================= +//============================= LCD and SD support ============================ +//============================================================================= + +// @section lcd + +/** + * LCD LANGUAGE + * + * Select the language to display on the LCD. These languages are available: + * + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, + * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * tr, uk, zh_CN, zh_TW, test + * + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + */ +#define LCD_LANGUAGE en + +/** + * LCD Character Set + * + * Note: This option is NOT applicable to Graphical Displays. + * + * All character-based LCDs provide ASCII plus one of these + * language extensions: + * + * - JAPANESE ... the most common + * - WESTERN ... with more accented characters + * - CYRILLIC ... for the Russian language + * + * To determine the language extension installed on your controller: + * + * - Compile and upload with LCD_LANGUAGE set to 'test' + * - 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 + * + * :['JAPANESE', 'WESTERN', 'CYRILLIC'] + */ +#define DISPLAY_CHARSET_HD44780 WESTERN + +/** + * LCD TYPE + * + * Enable ULTRA_LCD for a 16x2, 16x4, 20x2, or 20x4 character-based LCD. + * Enable DOGLCD for a 128x64 (ST7565R) Full Graphical Display. + * (These options will be enabled automatically for most displays.) + * + * IMPORTANT: The U8glib library is required for Full Graphic Display! + * https://github.com/olikraus/U8glib_Arduino + */ +//#define ULTRA_LCD // Character based +//#define DOGLCD // Full graphics display + +/** + * SD CARD + * + * 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 + +/** + * SD CARD: SPI SPEED + * + * Enable one of the following items for a slower SPI transfer speed. + * This may be required to resolve "volume init" errors. + */ +//#define SPI_SPEED SPI_HALF_SPEED +//#define SPI_SPEED SPI_QUARTER_SPEED +//#define SPI_SPEED SPI_EIGHTH_SPEED + +/** + * SD CARD: ENABLE CRC + * + * Use CRC checks and retries on the SD communication. + */ +//#define SD_CHECK_AND_RETRY + +// +// ENCODER SETTINGS +// +// This option overrides the default number of encoder pulses needed to +// produce one step. Should be increased for high-resolution encoders. +// +//#define ENCODER_PULSES_PER_STEP 1 + +// +// Use this option to override the number of step signals required to +// move between next/prev menu items. +// +//#define ENCODER_STEPS_PER_MENU_ITEM 5 + +/** + * Encoder Direction Options + * + * Test your encoder's behavior first with both options disabled. + * + * Reversed Value Edit and Menu Nav? Enable REVERSE_ENCODER_DIRECTION. + * Reversed Menu Navigation only? Enable REVERSE_MENU_DIRECTION. + * Reversed Value Editing only? Enable BOTH options. + */ + +// +// This option reverses the encoder direction everywhere. +// +// Set this option if CLOCKWISE causes values to DECREASE +// +//#define REVERSE_ENCODER_DIRECTION + +// +// This option reverses the encoder direction for navigating LCD menus. +// +// If CLOCKWISE normally moves DOWN this makes it go UP. +// If CLOCKWISE normally moves UP this makes it go DOWN. +// +//#define REVERSE_MENU_DIRECTION + +// +// Individual Axis Homing +// +// Add individual axis homing items (Home X, Home Y, and Home Z) to the LCD menu. +// +//#define INDIVIDUAL_AXIS_HOMING_MENU + +// +// SPEAKER/BUZZER +// +// If you have a speaker that can produce tones, enable it here. +// By default Marlin assumes you have a buzzer with a fixed frequency. +// +//#define SPEAKER + +// +// The duration and frequency for the UI feedback sound. +// Set these to 0 to disable audio feedback in the LCD menus. +// +// Note: Test audio output with the G-Code: +// M300 S P +// +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 +//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 + +// +// CONTROLLER TYPE: Standard +// +// Marlin supports a wide variety of controllers. +// Enable one of the following options to specify your controller. +// + +// +// ULTIMAKER Controller. +// +//#define ULTIMAKERCONTROLLER + +// +// ULTIPANEL as seen on Thingiverse. +// +//#define ULTIPANEL + +// +// PanelOne from T3P3 (via RAMPS 1.4 AUX2/AUX3) +// http://reprap.org/wiki/PanelOne +// +//#define PANEL_ONE + +// +// MaKr3d Makr-Panel with graphic controller and SD support. +// http://reprap.org/wiki/MaKr3d_MaKrPanel +// +//#define MAKRPANEL + +// +// ReprapWorld Graphical LCD +// https://reprapworld.com/?products_details&products_id/1218 +// +//#define REPRAPWORLD_GRAPHICAL_LCD + +// +// Activate one of these if you have a Panucatt Devices +// Viki 2.0 or mini Viki with Graphic LCD +// http://panucatt.com +// +//#define VIKI2 +//#define miniVIKI + +// +// Adafruit ST7565 Full Graphic Controller. +// https://github.com/eboston/Adafruit-ST7565-Full-Graphic-Controller/ +// +//#define ELB_FULL_GRAPHIC_CONTROLLER + +// +// RepRapDiscount Smart Controller. +// http://reprap.org/wiki/RepRapDiscount_Smart_Controller +// +// Note: Usually sold with a white PCB. +// +#define REPRAP_DISCOUNT_SMART_CONTROLLER + +// +// GADGETS3D G3D LCD/SD Controller +// http://reprap.org/wiki/RAMPS_1.3/1.4_GADGETS3D_Shield_with_Panel +// +// Note: Usually sold with a blue PCB. +// +//#define G3D_PANEL + +// +// RepRapDiscount FULL GRAPHIC Smart Controller +// http://reprap.org/wiki/RepRapDiscount_Full_Graphic_Smart_Controller +// +//#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER + +// +// MakerLab Mini Panel with graphic +// controller and SD support - http://reprap.org/wiki/Mini_panel +// +//#define MINIPANEL + +// +// RepRapWorld REPRAPWORLD_KEYPAD v1.1 +// http://reprapworld.com/?products_details&products_id=202&cPath=1591_1626 +// +// REPRAPWORLD_KEYPAD_MOVE_STEP sets how much should the robot move when a key +// is pressed, a value of 10.0 means 10mm per click. +// +//#define REPRAPWORLD_KEYPAD +//#define REPRAPWORLD_KEYPAD_MOVE_STEP 1.0 + +// +// RigidBot Panel V1.0 +// http://www.inventapart.com/ +// +//#define RIGIDBOT_PANEL + +// +// BQ LCD Smart Controller shipped by +// default with the BQ Hephestos 2 and Witbox 2. +// +//#define BQ_LCD_SMART_CONTROLLER + +// +// Cartesio UI +// http://mauk.cc/webshop/cartesio-shop/electronics/user-interface +// +//#define CARTESIO_UI + +// +// ANET_10 Controller supported displays. +// +//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. + // This LCD is known to be susceptible to electrical interference + // which scrambles the display. Pressing any button clears it up. +//#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 + // A clone of the RepRapDiscount full graphics display but with + // different pins/wiring (see pins_ANET_10.h). + +// +// LCD for Melzi Card with Graphical LCD +// +//#define LCD_FOR_MELZI + +// +// CONTROLLER TYPE: I2C +// +// Note: These controllers require the installation of Arduino's LiquidCrystal_I2C +// library. For more info: https://github.com/kiyoshigawa/LiquidCrystal_I2C +// + +// +// Elefu RA Board Control Panel +// http://www.elefu.com/index.php?route=product/product&product_id=53 +// +//#define RA_CONTROL_PANEL + +// +// Sainsmart YW Robot (LCM1602) LCD Display +// +// Note: This controller requires F.Malpartida's LiquidCrystal_I2C library +// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home +// +//#define LCD_I2C_SAINSMART_YWROBOT + +// +// Generic LCM1602 LCD adapter +// +//#define LCM1602 + +// +// PANELOLU2 LCD with status LEDs, +// separate encoder and click inputs. +// +// Note: This controller requires Arduino's LiquidTWI2 library v1.2.3 or later. +// For more info: https://github.com/lincomatic/LiquidTWI2 +// +// Note: The PANELOLU2 encoder click input can either be directly connected to +// a pin (if BTN_ENC defined to != -1) or read through I2C (when BTN_ENC == -1). +// +//#define LCD_I2C_PANELOLU2 + +// +// Panucatt VIKI LCD with status LEDs, +// integrated click & L/R/U/D buttons, separate encoder inputs. +// +//#define LCD_I2C_VIKI + +// +// SSD1306 OLED full graphics generic display +// +//#define U8GLIB_SSD1306 + +// +// SAV OLEd LCD module support using either SSD1306 or SH1106 based LCD modules +// +//#define SAV_3DGLCD +#if ENABLED(SAV_3DGLCD) + //#define U8GLIB_SSD1306 + #define U8GLIB_SH1106 +#endif + +// +// CONTROLLER TYPE: Shift register panels +// +// 2 wire Non-latching LCD SR from https://goo.gl/aJJ4sH +// LCD configuration: http://reprap.org/wiki/SAV_3D_LCD +// +//#define SAV_3DLCD + +// +// TinyBoy2 128x64 OLED / Encoder Panel +// +//#define OLED_PANEL_TINYBOY2 + +// +// Makeboard 3D Printer Parts 3D Printer Mini Display 1602 Mini Controller +// https://www.aliexpress.com/item/Micromake-Makeboard-3D-Printer-Parts-3D-Printer-Mini-Display-1602-Mini-Controller-Compatible-with-Ramps-1/32765887917.html +// +//#define MAKEBOARD_MINI_2_LINE_DISPLAY_1602 + +// +// MKS MINI12864 with graphic controller and SD support +// http://reprap.org/wiki/MKS_MINI_12864 +// +//#define MKS_MINI_12864 + +// +// Factory display for Creality CR-10 +// https://www.aliexpress.com/item/Universal-LCD-12864-3D-Printer-Display-Screen-With-Encoder-For-CR-10-CR-7-Model/32833148327.html +// +// This is RAMPS-compatible using a single 10-pin connector. +// (For CR-10 owners who want to replace the Melzi Creality board but retain the display) +// +//#define CR10_STOCKDISPLAY + +// +// MKS OLED 1.3" 128 × 64 FULL GRAPHICS CONTROLLER +// http://reprap.org/wiki/MKS_12864OLED +// +// Tiny, but very sharp OLED display +// +//#define MKS_12864OLED + +//============================================================================= +//=============================== Extra Features ============================== +//============================================================================= + +// @section extras + +// Increase the FAN PWM frequency. Removes the PWM noise but increases heating in the FET/Arduino +//#define FAST_PWM_FAN + +// Use software PWM to drive the fan, as for the heaters. This uses a very low frequency +// which is not as annoying as with the hardware PWM. On the other hand, if this frequency +// is too low, you should also increment SOFT_PWM_SCALE. +//#define FAN_SOFT_PWM + +// Incrementing this by 1 will double the software PWM frequency, +// affecting heaters, and the fan if FAN_SOFT_PWM is enabled. +// However, control resolution will be halved for each increment; +// at zero value, there are 128 effective control positions. +#define SOFT_PWM_SCALE 0 + +// If SOFT_PWM_SCALE is set to a value higher than 0, dithering can +// be used to mitigate the associated resolution loss. If enabled, +// some of the PWM cycles are stretched so on average the desired +// duty cycle is attained. +//#define SOFT_PWM_DITHER + +// Temperature status LEDs that display the hotend and bed temperature. +// If all hotends, bed temperature, and target temperature are under 54C +// then the BLUE led is on. Otherwise the RED led is on. (1C hysteresis) +//#define TEMP_STAT_LEDS + +// M240 Triggers a camera by emulating a Canon RC-1 Remote +// Data from: http://www.doc-diy.net/photo/rc-1_hacked/ +//#define PHOTOGRAPH_PIN 23 + +// 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 + +// Support for BlinkM/CyzRgb +//#define BLINKM + +// Support for PCA9632 PWM LED driver +//#define PCA9632 + +/** + * RGB LED / LED Strip Control + * + * Enable support for an RGB LED connected to 5V digital pins, or + * an RGB Strip connected to MOSFETs controlled by digital pins. + * + * 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 overall brightness parameters is also available + * + * *** CAUTION *** + * LED Strips require a MOFSET 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! + * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino + * cannot handle such current, separate 5V power supply must be used + * *** CAUTION *** + * + * LED type. This options are mutualy exclusive. Uncomment only one. + * + */ +//#define RGB_LED +//#define RGBW_LED + +#if ENABLED(RGB_LED) || ENABLED(RGBW_LED) + #define RGB_LED_R_PIN 34 + #define RGB_LED_G_PIN 43 + #define RGB_LED_B_PIN 35 + #define RGB_LED_W_PIN -1 +#endif + +// 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 (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) + #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip + #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time + #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + //#define NEOPIXEL_STARTUP_TEST // Cycle through colors at startup +#endif + +/** + * Printer Event LEDs + * + * During printing, the LEDs will reflect the printer status: + * + * - Gradually change from blue to violet as the heated bed gets to target temp + * - Gradually change from violet to red as the hotend gets to temperature + * - Change to white to illuminate work surface + * - Change to green once print has finished + * - Turn off after the print has finished and the user has pushed a button + */ +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) + #define PRINTER_EVENT_LEDS +#endif + +/*********************************************************************\ +* R/C SERVO support +* Sponsored by TrinityLabs, Reworked by codexmas +**********************************************************************/ + +// Number of servos +// +// If you select a configuration below, this will receive a default value and does not need to be set manually +// set it manually if you have more servos than extruders and wish to manually control some +// leaving it undefined or defining as 0 will disable the servo subsystem +// If unsure, leave commented / disabled +// +//#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command + +// Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. +// 300ms is a good value but you can try less delay. +// If the servo can't reach the requested position, increase it. +#define SERVO_DELAY { 300 } + +// Servo deactivation +// +// With this option servos are powered only during movement, then turned off to prevent jitter. +//#define DEACTIVATE_SERVOS_AFTER_MOVE + +/** + * Filament Width Sensor + * + * Measures the filament width in real-time and adjusts + * flow rate to compensate for any irregularities. + * + * Also allows the measured filament diameter to set the + * extrusion rate, so the slicer only has to specify the + * volume. + * + * Only a single extruder is supported at this time. + * + * 34 RAMPS_14 : Analog input 5 on the AUX2 connector + * 81 PRINTRBOARD : Analog input 2 on the Exp1 connector (version B,C,D,E) + * 301 RAMBO : Analog input 3 + * + * Note: May require analog pins to be defined for other boards. + */ +//#define FILAMENT_WIDTH_SENSOR + +#define DEFAULT_NOMINAL_FILAMENT_DIA 1.75 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. + +#if ENABLED(FILAMENT_WIDTH_SENSOR) + #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) + #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber + + #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading + #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading + #define MAX_MEASUREMENT_DELAY 20 // (bytes) Buffer size for stored measurements (1 byte per cm). Must be larger than MEASUREMENT_DELAY_CM. + + #define DEFAULT_MEASURED_FILAMENT_DIA DEFAULT_NOMINAL_FILAMENT_DIA // Set measured to nominal initially + + // Display filament width on the LCD status line. Status messages will expire after 5 seconds. + //#define FILAMENT_LCD_DISPLAY +#endif + +#endif // CONFIGURATION_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/delta/FLSUN/kossel_mini/Configuration_adv.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/delta/FLSUN/kossel_mini/Configuration_adv.h new file mode 100644 index 00000000..b7c896df --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/delta/FLSUN/kossel_mini/Configuration_adv.h @@ -0,0 +1,1426 @@ +/** + * 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 . + * + */ + +/** + * Configuration_adv.h + * + * Advanced settings. + * Only change these if you know exactly what you're doing. + * Some of these settings can damage your printer if improperly set! + * + * Basic settings can be found in Configuration.h + * + */ +#ifndef CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H_VERSION 010100 + +// @section temperature + +//=========================================================================== +//=============================Thermal Settings ============================ +//=========================================================================== + +#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 + #endif +#endif + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * The solution: Once the temperature reaches the target, start observing. + * If the temperature stays too far below the target (hysteresis) for too long (period), + * the firmware will halt the machine as a safety precaution. + * + * If you get false positives for "Thermal Runaway" increase THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD + */ +#if ENABLED(THERMAL_PROTECTION_HOTENDS) + #define THERMAL_PROTECTION_PERIOD 40 // Seconds + #define THERMAL_PROTECTION_HYSTERESIS 4 // Degrees Celsius + + /** + * Whenever an M104 or M109 increases the target temperature the firmware will wait for the + * WATCH_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get false positives for "Heating failed" increase WATCH_TEMP_PERIOD and/or decrease WATCH_TEMP_INCREASE + * WATCH_TEMP_INCREASE should not be below 2. + */ + #define WATCH_TEMP_PERIOD 20 // Seconds + #define WATCH_TEMP_INCREASE 2 // Degrees Celsius +#endif + +/** + * Thermal Protection parameters for the bed are just as above for hotends. + */ +#if ENABLED(THERMAL_PROTECTION_BED) + #define THERMAL_PROTECTION_BED_PERIOD 20 // Seconds + #define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius + + /** + * Whenever an M140 or M190 increases the target temperature the firmware will wait for the + * WATCH_BED_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_BED_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get too many "Heating failed" errors, increase WATCH_BED_TEMP_PERIOD and/or decrease + * WATCH_BED_TEMP_INCREASE. (WATCH_BED_TEMP_INCREASE should not be below 2.) + */ + #define WATCH_BED_TEMP_PERIOD 60 // Seconds + #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius +#endif + +#if ENABLED(PIDTEMP) + // this adds an experimental additional term to the heating power, proportional to the extrusion speed. + // if Kc is chosen well, the additional required power due to increased melting should be compensated. + //#define PID_EXTRUSION_SCALING + #if ENABLED(PID_EXTRUSION_SCALING) + #define DEFAULT_Kc (100) //heating power=Kc*(e_speed) + #define LPQ_MAX_LEN 50 + #endif +#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 + */ +#define AUTOTEMP +#if ENABLED(AUTOTEMP) + #define AUTOTEMP_OLDWEIGHT 0.98 +#endif + +// Show Temperature ADC value +// Enable for M105 to include ADC values read from temperature sensors. +//#define SHOW_TEMP_ADC_VALUES + +/** + * High Temperature Thermistor Support + * + * Thermistors able to support high temperature tend to have a hard time getting + * good readings at room and lower temperatures. This means HEATER_X_RAW_LO_TEMP + * will probably be caught when the heating element first turns on during the + * preheating process, which will trigger a min_temp_error as a safety measure + * and force stop everything. + * To circumvent this limitation, we allow for a preheat time (during which, + * min_temp_error won't be triggered) and add a min_temp buffer to handle + * aberrant readings. + * + * If you want to enable this feature for your hotend thermistor(s) + * uncomment and set values > 0 in the constants below + */ + +// The number of consecutive low temperature errors that can occur +// before a min_temp_error is triggered. (Shouldn't be more than 10.) +//#define MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED 0 + +// The number of milliseconds a hotend will preheat before starting to check +// the temperature. This value should NOT be set to the time it takes the +// hot end to reach the target temperature, but the time it takes to reach +// the minimum temperature your thermistor can read. The lower the better/safer. +// This shouldn't need to be more than 30 seconds (30000) +//#define MILLISECONDS_PREHEAT_TIME 0 + +// @section extruder + +// Extruder runout prevention. +// If the machine is idle and the temperature over MINTEMP +// then extrude some filament every couple of SECONDS. +//#define EXTRUDER_RUNOUT_PREVENT +#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_EXTRUDE 5 // mm +#endif + +// @section temperature + +//These defines help to calibrate the AD595 sensor in case you get wrong temperature measurements. +//The measured temperature is defined as "actualTemp = (measuredTemp * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET" +#define TEMP_SENSOR_AD595_OFFSET 0.0 +#define TEMP_SENSOR_AD595_GAIN 1.0 + +/** + * 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. + */ +//#define USE_CONTROLLER_FAN +#if ENABLED(USE_CONTROLLER_FAN) + //#define CONTROLLER_FAN_PIN FAN1_PIN // 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 +#endif + +// When first starting the main fan, run it at full speed for the +// given number of milliseconds. This gets the fan spinning reliably +// before setting a PWM value. (Does not work with software PWM for fan on Sanguinololu) +//#define FAN_KICKSTART_TIME 100 + +// This defines the minimal speed for the main fan, run in PWM mode +// to enable uncomment and set minimal PWM speed for reliable running (1-255) +// if fan speed is [1 - (FAN_MIN_PWM-1)] it is set to FAN_MIN_PWM +//#define FAN_MIN_PWM 50 + +// @section extruder + +/** + * Extruder cooling fans + * + * Extruder auto fans automatically turn on when their extruders' + * temperatures go above EXTRUDER_AUTO_FAN_TEMPERATURE. + * + * Your board's pins file specifies the recommended pins. Override those here + * or set to -1 to disable completely. + * + * Multiple extruders can be assigned to the same pin in which case + * the fan will turn on when any selected extruder is above the threshold. + */ +#define E0_AUTO_FAN_PIN -1 +#define E1_AUTO_FAN_PIN -1 +#define E2_AUTO_FAN_PIN -1 +#define E3_AUTO_FAN_PIN -1 +#define E4_AUTO_FAN_PIN -1 +#define EXTRUDER_AUTO_FAN_TEMPERATURE 50 +#define EXTRUDER_AUTO_FAN_SPEED 255 // == full speed + +/** + * Part-Cooling Fan Multiplexer + * + * This feature allows you to digitally multiplex the fan output. + * The multiplexer is automatically switched at tool-change. + * Set FANMUX[012]_PINs below for up to 2, 4, or 8 multiplexed fans. + */ +#define FANMUX0_PIN -1 +#define FANMUX1_PIN -1 +#define FANMUX2_PIN -1 + +/** + * M355 Case Light on-off / brightness + */ +//#define CASE_LIGHT_ENABLE +#if ENABLED(CASE_LIGHT_ENABLE) + //#define CASE_LIGHT_PIN 4 // Override the default pin if needed + #define INVERT_CASE_LIGHT false // Set true if Case Light is ON when pin is LOW + #define CASE_LIGHT_DEFAULT_ON true // Set default power-up state on + #define CASE_LIGHT_DEFAULT_BRIGHTNESS 105 // Set default power-up brightness (0-255, requires PWM pin) + //#define MENU_ITEM_CASE_LIGHT // Add a Case Light option to the LCD main menu +#endif + +//=========================================================================== +//============================ Mechanical Settings ========================== +//=========================================================================== + +// @section homing + +// If you want endstops to stay on (by default) even when not homing +// enable this option. Override at any time with M120, M121. +//#define ENDSTOPS_ALWAYS_ON_DEFAULT + +// @section extras + +//#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. + +// Dual X Steppers +// Uncomment this option to drive two X axis motors. +// The next unused E driver will be assigned to the second X stepper. +//#define X_DUAL_STEPPER_DRIVERS +#if ENABLED(X_DUAL_STEPPER_DRIVERS) + // Set true if the two X motors need to rotate in opposite directions + #define INVERT_X2_VS_X_DIR true +#endif + +// Dual Y Steppers +// Uncomment this option to drive two Y axis motors. +// The next unused E driver will be assigned to the second Y stepper. +//#define Y_DUAL_STEPPER_DRIVERS +#if ENABLED(Y_DUAL_STEPPER_DRIVERS) + // Set true if the two Y motors need to rotate in opposite directions + #define INVERT_Y2_VS_Y_DIR true +#endif + +// A single Z stepper driver is usually used to drive 2 stepper motors. +// Uncomment this option to use a separate stepper driver for each Z axis motor. +// The next unused E driver will be assigned to the second Z stepper. +//#define Z_DUAL_STEPPER_DRIVERS + +#if ENABLED(Z_DUAL_STEPPER_DRIVERS) + + // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper. + // That way the machine is capable to align the bed during home, since both Z steppers are homed. + // There is also an implementation of M666 (software endstops adjustment) to this feature. + // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed. + // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2. + // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive. + // Play a little bit with small adjustments (0.5mm) and check the behaviour. + // The M119 (endstops report) will start reporting the Z2 Endstop as well. + + //#define Z_DUAL_ENDSTOPS + + #if ENABLED(Z_DUAL_ENDSTOPS) + #define Z2_USE_ENDSTOP _XMAX_ + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 // Use M666 to determine/test this value + #endif + +#endif // Z_DUAL_STEPPER_DRIVERS + +// Enable this for dual x-carriage printers. +// A dual x-carriage design has the advantage that the inactive extruder can be parked which +// prevents hot-end ooze contaminating the print. It also reduces the weight of each x-carriage +// allowing faster printing speeds. Connect your X2 stepper to the first unused E plug. +//#define DUAL_X_CARRIAGE +#if ENABLED(DUAL_X_CARRIAGE) + // Configuration for second X-carriage + // Note: the first x-carriage is defined as the x-carriage which homes to the minimum endstop; + // the second x-carriage always homes to the maximum endstop. + #define X2_MIN_POS 80 // set minimum to ensure second x-carriage doesn't hit the parked first X-carriage + #define X2_MAX_POS 353 // set maximum to the distance between toolheads when both heads are homed + #define X2_HOME_DIR 1 // the second X-carriage always homes to the maximum endstop position + #define X2_HOME_POS X2_MAX_POS // default home position is the maximum carriage position + // However: In this mode the HOTEND_OFFSET_X value for the second extruder provides a software + // override for X2_HOME_POS. This also allow recalibration of the distance between the two endstops + // without modifying the firmware (through the "M218 T1 X???" command). + // Remember: you should set the second extruder x-offset to 0 in your slicer. + + // There are a few selectable movement modes for dual x-carriages using M605 S + // Mode 0 (DXC_FULL_CONTROL_MODE): Full control. The slicer has full control over both x-carriages and can achieve optimal travel results + // as long as it supports dual x-carriages. (M605 S0) + // Mode 1 (DXC_AUTO_PARK_MODE) : Auto-park mode. The firmware will automatically park and unpark the x-carriages on tool changes so + // that additional slicer support is not required. (M605 S1) + // Mode 2 (DXC_DUPLICATION_MODE) : Duplication mode. The firmware will transparently make the second x-carriage and extruder copy all + // actions of the first x-carriage. This allows the printer to print 2 arbitrary items at + // once. (2nd extruder x offset and temp offset are set using: M605 S2 [Xnnn] [Rmmm]) + + // This is the default power-up mode which can be later using M605. + #define DEFAULT_DUAL_X_CARRIAGE_MODE DXC_FULL_CONTROL_MODE + + // Default settings in "Auto-park Mode" + #define TOOLCHANGE_PARK_ZLIFT 0.2 // the distance to raise Z axis when parking an extruder + #define TOOLCHANGE_UNPARK_ZLIFT 1 // the distance to raise Z axis when unparking an extruder + + // Default x offset in duplication mode (typically set to half print bed width) + #define DEFAULT_DUPLICATION_X_OFFSET 100 + +#endif // DUAL_X_CARRIAGE + +// 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. +//#define EXT_SOLENOID + +// @section homing + +//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +#define X_HOME_BUMP_MM 5 +#define Y_HOME_BUMP_MM 5 +#define Z_HOME_BUMP_MM 5 // deltas need the same for all three axes +#define HOMING_BUMP_DIVISOR {10, 10, 10} // Re-Bump Speed Divisor (Divides the Homing Feedrate) +//#define QUICK_HOME //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially. + +// When G28 is called, this option will make Y home before X +//#define HOME_Y_BEFORE_X + +// @section machine + +#define AXIS_RELATIVE_MODES {false, false, false, false} + +// Allow duplication mode with a basic dual-nozzle extruder +//#define DUAL_NOZZLE_DUPLICATION_MODE + +// By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step. +#define INVERT_X_STEP_PIN false +#define INVERT_Y_STEP_PIN false +#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. +#define DEFAULT_STEPPER_DEACTIVE_TIME 60 +#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_E true + +#define DEFAULT_MINIMUMFEEDRATE 0.0 // minimum feedrate +#define DEFAULT_MINTRAVELFEEDRATE 0.0 + +//#define HOME_AFTER_DEACTIVATE // Require rehoming after steppers are deactivated + +// @section lcd + +#if ENABLED(ULTIPANEL) + #define MANUAL_FEEDRATE_XYZ 50*60 + #define MANUAL_FEEDRATE { MANUAL_FEEDRATE_XYZ, MANUAL_FEEDRATE_XYZ, MANUAL_FEEDRATE_XYZ, 60 } // Feedrates for manual moves along X, Y, Z, E from panel + #define ULTIPANEL_FEEDMULTIPLY // Comment to disable setting feedrate multiplier via encoder +#endif + +// @section extras + +// minimum time in microseconds that a movement needs to take if the buffer is emptied. +#define DEFAULT_MINSEGMENTTIME 20000 + +// If defined the movements slow down when the look ahead buffer is only half full +// (don't use SLOWDOWN with DELTA because DELTA generates hundreds of segments per second) +//#define SLOWDOWN + +// Frequency limit +// See nophead's blog for more info +// Not working O +//#define XY_FREQUENCY_LIMIT 15 + +// 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 +// if unwanted behavior is observed on a user's machine when running at very slow speeds. +#define MINIMUM_PLANNER_SPEED 0.05 // (mm/sec) + +// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU. +#define MICROSTEP_MODES {16,16,16,16,16} // [1,2,4,8,16] + +/** + * @section stepper motor current + * + * Some boards have a means of setting the stepper motor current via firmware. + * + * The power on motor currents are set by: + * PWM_MOTOR_CURRENT - used by MINIRAMBO & ULTIMAIN_2 + * known compatible chips: A4982 + * DIGIPOT_MOTOR_CURRENT - used by BQ_ZUM_MEGA_3D, RAMBO & SCOOVO_X9H + * known compatible chips: AD5206 + * DAC_MOTOR_CURRENT_DEFAULT - used by PRINTRBOARD_REVF & RIGIDBOARD_V2 + * known compatible chips: MCP4728 + * DIGIPOT_I2C_MOTOR_CURRENTS - used by 5DPRINT, AZTEEG_X3_PRO, MIGHTYBOARD_REVE + * known compatible chips: MCP4451, MCP4018 + * + * Motor currents can also be set by M907 - M910 and by the LCD. + * M907 - applies to all. + * M908 - BQ_ZUM_MEGA_3D, RAMBO, PRINTRBOARD_REVF, RIGIDBOARD_V2 & SCOOVO_X9H + * M909, M910 & LCD - only PRINTRBOARD_REVF & RIGIDBOARD_V2 + */ +//#define PWM_MOTOR_CURRENT { 1300, 1300, 1250 } // Values in milliamps +//#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 + +// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +//#define DIGIPOT_I2C +//#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster +#define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 +// Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS +#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=========================== +//=========================================================================== + +#define ENCODER_RATE_MULTIPLIER // If defined, certain menu edit operations automatically multiply the steps when the encoder is moved quickly +#define ENCODER_10X_STEPS_PER_SEC 75 // If the encoder steps per sec exceeds this value, multiply steps moved x10 to quickly advance the value +#define ENCODER_100X_STEPS_PER_SEC 160 // If the encoder steps per sec exceeds this value, multiply steps moved x100 to really quickly advance the value + +//#define CHDK 4 //Pin for triggering CHDK to take a picture see how to use it here http://captain-slow.dk/2014/03/09/3d-printing-timelapses/ +#define CHDK_DELAY 50 //How long in ms the pin should stay HIGH before going LOW again + +// @section lcd + +// Include a page of printer information in the LCD Main Menu +//#define LCD_INFO_MENU + +// Scroll a longer status message into view +//#define STATUS_MESSAGE_SCROLLING + +// On the Info Screen, display XY with one decimal place when possible +//#define LCD_DECIMAL_SMALL_XY + +// The timeout (in ms) to return to the status screen from sub-menus +//#define LCD_TIMEOUT_TO_STATUS 15000 + +#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 + + #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? + #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. + + #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. + // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. + // using: + //#define MENU_ADDAUTOSTART + + /** + * Sort SD file listings in alphabetical order. + * + * With this option enabled, items on SD cards will be sorted + * by name for easier navigation. + * + * By default... + * + * - Use the slowest -but safest- method for sorting. + * - Folders are sorted to the top. + * - The sort key is statically allocated. + * - No added G-code (M34) support. + * - 40 item sorting limit. (Items after the first 40 are unsorted.) + * + * SD sorting uses static allocation (as set by SDSORT_LIMIT), allowing the + * compiler to calculate the worst-case usage and throw an error if the SRAM + * limit is exceeded. + * + * - SDSORT_USES_RAM provides faster sorting via a static directory buffer. + * - SDSORT_USES_STACK does the same, but uses a local stack-based buffer. + * - SDSORT_CACHE_NAMES will retain the sorted file listing in RAM. (Expensive!) + * - SDSORT_DYNAMIC_RAM only uses RAM when the SD menu is visible. (Use with caution!) + */ + //#define SDCARD_SORT_ALPHA + + // SD Card Sorting options + #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_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. + #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #endif + + // Show a progress bar on HD44780 LCDs for SD printing + //#define LCD_PROGRESS_BAR + + #if ENABLED(LCD_PROGRESS_BAR) + // Amount of time (ms) to show the bar + #define PROGRESS_BAR_BAR_TIME 2000 + // Amount of time (ms) to show the status message + #define PROGRESS_BAR_MSG_TIME 3000 + // Amount of time (ms) to retain the status message (0=forever) + #define PROGRESS_MSG_EXPIRE 0 + // Enable this to show messages for MSG_TIME then hide them + //#define PROGRESS_MSG_ONCE + // Add a menu item to test the progress bar: + //#define LCD_PROGRESS_BAR_TEST + #endif + + // This allows hosts to request long names for files and folders with M33 + //#define LONG_FILENAME_HOST_SUPPORT + + // This option allows you to abort SD printing when any endstop is triggered. + // This feature must be enabled with "M540 S1" or from the LCD menu. + // To have any effect, endstops must be enabled during SD printing. + //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + +#endif // SDSUPPORT + +/** + * Additional options for Graphical Displays + * + * Use the optimizations here to improve printing performance, + * which can be adversely affected by graphical display drawing, + * especially when doing several short moves, and when printing + * on DELTA and SCARA machines. + * + * Some of these options may result in the display lagging behind + * controller events, as there is a trade-off between reliable + * printing performance versus fast display updates. + */ +#if ENABLED(DOGLCD) + // Enable to save many cycles by drawing a hollow frame on the Info Screen + #define XYZ_HOLLOW_FRAME + + // Enable to save many cycles by drawing a hollow frame on Menu Screens + #define MENU_HOLLOW_FRAME + + // A bigger font is available for edit items. Costs 3120 bytes of PROGMEM. + // 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. + // 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 +#endif // DOGLCD + +// @section safety + +// The hardware watchdog should reset the microcontroller disabling all outputs, +// in case the firmware gets stuck and doesn't do temperature regulation. +#define USE_WATCHDOG + +#if ENABLED(USE_WATCHDOG) + // If you have a watchdog reboot in an ArduinoMega2560 then the device will hang forever, as a watchdog reset will leave the watchdog on. + // The "WATCHDOG_RESET_MANUAL" goes around this by not using the hardware reset. + // However, THIS FEATURE IS UNSAFE!, as it will only work if interrupts are disabled. And the code could hang in an interrupt routine with interrupts disabled. + //#define WATCHDOG_RESET_MANUAL +#endif + +// @section lcd + +/** + * Babystepping enables movement of the axes by tiny increments without changing + * the current position values. This feature is used primarily to adjust the Z + * axis in the first layer of a print in real-time. + * + * Warning: Does not respect endstops! + */ +//#define BABYSTEPPING +#if ENABLED(BABYSTEPPING) + //#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 100 // Babysteps are very small. Increase for faster motion. + //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping + //#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen 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_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor + //#define BABYSTEP_ZPROBE_GFX_REVERSE // Reverses the direction of the CW/CCW indicators +#endif + +// @section extruder + +/** + * Implementation of linear pressure control + * + * Assumption: advance = k * (delta velocity) + * K=0 means advance disabled. + * See Marlin documentation for calibration instructions. + */ +//#define LIN_ADVANCE + +#if ENABLED(LIN_ADVANCE) + #define LIN_ADVANCE_K 75 + + /** + * Some Slicers produce Gcode with randomly jumping extrusion widths occasionally. + * For example within a 0.4mm perimeter it may produce a single segment of 0.05mm width. + * While this is harmless for normal printing (the fluid nature of the filament will + * close this very, very tiny gap), it throws off the LIN_ADVANCE pressure adaption. + * + * For this case LIN_ADVANCE_E_D_RATIO can be used to set the extrusion:distance ratio + * to a fixed value. Note that using a fixed ratio will lead to wrong nozzle pressures + * if the slicer is using variable widths or layer heights within one print! + * + * This option sets the default E:D ratio at startup. Use `M900` to override this value. + * + * Example: `M900 W0.4 H0.2 D1.75`, where: + * - W is the extrusion width in mm + * - H is the layer height in mm + * - D is the filament diameter in mm + * + * Example: `M900 R0.0458` to set the ratio directly. + * + * Set to 0 to auto-detect the ratio based on given Gcode G1 print moves. + * + * Slic3r (including Průša Control) produces Gcode compatible with the automatic mode. + * Cura (as of this writing) may produce Gcode incompatible with the automatic mode. + */ + #define LIN_ADVANCE_E_D_RATIO 0 // The calculated ratio (or 0) according to the formula W * H / ((D / 2) ^ 2 * PI) + // Example: 0.4 * 0.2 / ((1.75 / 2) ^ 2 * PI) = 0.033260135 +#endif + +// @section leveling + +// Default mesh area is an area with an inset margin on the print area. +// Below are the macros that are used to define the borders for the mesh area, +// made available here for specialized needs, ie dual extruder setup. +#if ENABLED(MESH_BED_LEVELING) + #define MESH_MIN_X MESH_INSET + #define MESH_MAX_X (X_BED_SIZE - (MESH_INSET)) + #define MESH_MIN_Y MESH_INSET + #define MESH_MAX_Y (Y_BED_SIZE - (MESH_INSET)) +#elif ENABLED(AUTO_BED_LEVELING_UBL) + #define UBL_MESH_MIN_X UBL_MESH_INSET + #define UBL_MESH_MAX_X (X_BED_SIZE - (UBL_MESH_INSET)) + #define UBL_MESH_MIN_Y UBL_MESH_INSET + #define UBL_MESH_MAX_Y (Y_BED_SIZE - (UBL_MESH_INSET)) + + // If this is defined, the currently active mesh will be saved in the + // current slot on M500. + #define UBL_SAVE_ACTIVE_ON_M500 +#endif + +// @section extras + +// +// G2/G3 Arc Support +// +#define ARC_SUPPORT // Disable this feature to save ~3226 bytes +#if ENABLED(ARC_SUPPORT) + #define MM_PER_ARC_SEGMENT 1 // Length of each arc segment + #define N_ARC_CORRECTION 25 // Number of intertpolated 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 +#endif + +// Support for G5 with XYZE destination and IJPQ offsets. Requires ~2666 bytes. +//#define BEZIER_CURVE_SUPPORT + +// G38.2 and G38.3 Probe Target +// Enable PROBE_DOUBLE_TOUCH if you want G38 to double touch +//#define G38_PROBE_TARGET +#if ENABLED(G38_PROBE_TARGET) + #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) +#endif + +// Moves (or segments) with fewer steps than this will be joined with the next move +#define MIN_STEPS_PER_SEGMENT 6 + +// The minimum pulse width (in µs) for stepping a stepper. +// Set this if you find stepping unreliable, or if using a very fast CPU. +#define MINIMUM_STEPPER_PULSE 0 // (µs) The smallest stepper pulse allowed + +// @section temperature + +// Control heater 0 and heater 1 in parallel. +//#define HEATERS_PARALLEL + +//=========================================================================== +//================================= Buffers ================================= +//=========================================================================== + +// @section hidden + +// 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, i.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 +#else + #define BLOCK_BUFFER_SIZE 16 // maximize block buffer +#endif + +// @section serial + +// The ASCII buffer for serial input +#define MAX_CMD_SIZE 96 +#define BUFSIZE 4 + +// Transmission to Host Buffer Size +// To save 386 bytes of PROGMEM (and TX_BUFFER_SIZE+3 bytes of RAM) set to 0. +// To buffer a simple "ok" you need 4 bytes. +// For ADVANCED_OK (M105) you need 32 bytes. +// For debug-echo: 128 bytes for the optimal speed. +// Other output doesn't need to be that speedy. +// :[0, 2, 4, 8, 16, 32, 64, 128, 256] +#define TX_BUFFER_SIZE 0 + +// Host Receive Buffer Size +// Without XON/XOFF flow control (see SERIAL_XON_XOFF below) 32 bytes should be enough. +// To use flow control, set this buffer size to at least 1024 bytes. +// :[0, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048] +//#define RX_BUFFER_SIZE 1024 + +#if RX_BUFFER_SIZE >= 1024 + // Enable to have the controller send XON/XOFF control characters to + // the host to signal the RX buffer is becoming full. + //#define SERIAL_XON_XOFF +#endif + +#if ENABLED(SDSUPPORT) + // Enable this option to collect and display the maximum + // RX queue usage after transferring a file to SD. + //#define SERIAL_STATS_MAX_RX_QUEUED + + // Enable this option to collect and display the number + // of dropped bytes after a file transfer to SD. + //#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! +//#define EMERGENCY_PARSER + +// Bad Serial-connections can miss a received command by sending an 'ok' +// Therefore some clients abort after 30 seconds in a timeout. +// Some other clients start sending commands while receiving a 'wait'. +// This "wait" is only sent when the buffer is empty. 1 second is a good value here. +//#define NO_TIMEOUTS 1000 // Milliseconds + +// Some clients will have this feature soon. This could make the NO_TIMEOUTS unnecessary. +//#define ADVANCED_OK + +// @section extras + +/** + * Firmware-based and LCD-controlled retract + * + * Add G10 / G11 commands for automatic firmware-based retract / recover. + * Use M207 and M208 to define parameters for retract / recover. + * + * Use M209 to enable or disable auto-retract. + * With auto-retract enabled, all G1 E moves within the set range + * will be converted to firmware-based retract/recover moves. + * + * Be sure to turn off auto-retract during filament change. + * + * Note that M207 / M208 / M209 settings are saved to EEPROM. + * + */ +//#define FWRETRACT // ONLY PARTIALLY TESTED +#if ENABLED(FWRETRACT) + #define MIN_AUTORETRACT 0.1 // When auto-retract is on, convert E moves of this length and over + #define MAX_AUTORETRACT 10.0 // Upper limit for auto-retract conversion + #define RETRACT_LENGTH 3 // Default retract length (positive mm) + #define RETRACT_LENGTH_SWAP 13 // Default swap retract length (positive mm), for extruder change + #define RETRACT_FEEDRATE 45 // Default feedrate for retracting (mm/s) + #define RETRACT_ZLIFT 0 // Default retract Z-lift + #define RETRACT_RECOVER_LENGTH 0 // Default additional recover length (mm, added to retract length when recovering) + #define RETRACT_RECOVER_LENGTH_SWAP 0 // Default additional swap recover length (mm, added to retract length when recovering from extruder change) + #define RETRACT_RECOVER_FEEDRATE 8 // Default feedrate for recovering from retraction (mm/s) + #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) +#endif + +/** + * Advanced Pause + * Experimental feature for filament change support and for parking the nozzle when paused. + * Adds the GCode M600 for initiating filament change. + * If PARK_HEAD_ON_PAUSE enabled, adds the GCode M125 to pause printing and park the nozzle. + * + * Requires an LCD display. + * This feature is required for the default FILAMENT_RUNOUT_SCRIPT. + */ +//#define ADVANCED_PAUSE_FEATURE +#if ENABLED(ADVANCED_PAUSE_FEATURE) + #define PAUSE_PARK_X_POS 3 // X position of hotend + #define PAUSE_PARK_Y_POS 3 // Y position of hotend + #define PAUSE_PARK_Z_ADD 10 // Z addition of hotend (lift) + #define PAUSE_PARK_XY_FEEDRATE 100 // X and Y axes feedrate in mm/s (also used for delta printers Z axis) + #define PAUSE_PARK_Z_FEEDRATE 5 // Z axis feedrate in mm/s (not used for delta printers) + #define PAUSE_PARK_RETRACT_FEEDRATE 60 // Initial retract feedrate in mm/s + #define PAUSE_PARK_RETRACT_LENGTH 2 // Initial retract in mm + // It is a short retract used immediately after print interrupt before move to filament exchange position + #define FILAMENT_CHANGE_UNLOAD_FEEDRATE 10 // Unload filament feedrate in mm/s - filament unloading can be fast + #define FILAMENT_CHANGE_UNLOAD_LENGTH 100 // Unload filament length from hotend in mm + // Longer length for bowden printers to unload filament from whole bowden tube, + // shorter length for printers without bowden to unload filament from extruder only, + // 0 to disable unloading for manual unloading + #define FILAMENT_CHANGE_LOAD_FEEDRATE 6 // Load filament feedrate in mm/s - filament loading into the bowden tube can be fast + #define FILAMENT_CHANGE_LOAD_LENGTH 0 // Load filament length over hotend in mm + // Longer length for bowden printers to fast load filament into whole bowden tube over the hotend, + // Short or zero length for printers without bowden where loading is not used + #define ADVANCED_PAUSE_EXTRUDE_FEEDRATE 3 // Extrude filament feedrate in mm/s - must be slower than load feedrate + #define ADVANCED_PAUSE_EXTRUDE_LENGTH 50 // Extrude filament length in mm after filament is loaded over the hotend, + // 0 to disable for manual extrusion + // Filament can be extruded repeatedly from the filament exchange menu to fill the hotend, + // or until outcoming filament color is not clear for filament color change + #define PAUSE_PARK_NOZZLE_TIMEOUT 45 // Turn off nozzle if user doesn't change filament within this time limit in seconds + #define FILAMENT_CHANGE_NUMBER_OF_ALERT_BEEPS 5 // Number of alert beeps before printer goes quiet + #define PAUSE_PARK_NO_STEPPER_TIMEOUT // Enable to have stepper motors hold position during filament change + // even if it takes longer than DEFAULT_STEPPER_DEACTIVE_TIME. + //#define PARK_HEAD_ON_PAUSE // Go to filament change position on pause, return to print position on resume + //#define HOME_BEFORE_FILAMENT_CHANGE // Ensure homing has been completed prior to parking for filament change +#endif + +// @section tmc + +/** + * Enable this section if you have TMC26X motor drivers. + * You will need to import the TMC26XStepper library into the Arduino IDE for this + * (https://github.com/trinamic/TMC26XStepper.git) + */ +//#define HAVE_TMCDRIVER + +#if ENABLED(HAVE_TMCDRIVER) + + //#define X_IS_TMC + //#define X2_IS_TMC + //#define Y_IS_TMC + //#define Y2_IS_TMC + //#define Z_IS_TMC + //#define Z2_IS_TMC + //#define E0_IS_TMC + //#define E1_IS_TMC + //#define E2_IS_TMC + //#define E3_IS_TMC + //#define E4_IS_TMC + + #define X_MAX_CURRENT 1000 // in mA + #define X_SENSE_RESISTOR 91 // in mOhms + #define X_MICROSTEPS 16 // number of microsteps + + #define X2_MAX_CURRENT 1000 + #define X2_SENSE_RESISTOR 91 + #define X2_MICROSTEPS 16 + + #define Y_MAX_CURRENT 1000 + #define Y_SENSE_RESISTOR 91 + #define Y_MICROSTEPS 16 + + #define Y2_MAX_CURRENT 1000 + #define Y2_SENSE_RESISTOR 91 + #define Y2_MICROSTEPS 16 + + #define Z_MAX_CURRENT 1000 + #define Z_SENSE_RESISTOR 91 + #define Z_MICROSTEPS 16 + + #define Z2_MAX_CURRENT 1000 + #define Z2_SENSE_RESISTOR 91 + #define Z2_MICROSTEPS 16 + + #define E0_MAX_CURRENT 1000 + #define E0_SENSE_RESISTOR 91 + #define E0_MICROSTEPS 16 + + #define E1_MAX_CURRENT 1000 + #define E1_SENSE_RESISTOR 91 + #define E1_MICROSTEPS 16 + + #define E2_MAX_CURRENT 1000 + #define E2_SENSE_RESISTOR 91 + #define E2_MICROSTEPS 16 + + #define E3_MAX_CURRENT 1000 + #define E3_SENSE_RESISTOR 91 + #define E3_MICROSTEPS 16 + + #define E4_MAX_CURRENT 1000 + #define E4_SENSE_RESISTOR 91 + #define E4_MICROSTEPS 16 + +#endif + +// @section TMC2130 + +/** + * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. + * + * You'll also need the TMC2130Stepper Arduino library + * (https://github.com/teemuatlut/TMC2130Stepper). + * + * To use TMC2130 stepper drivers in SPI mode connect your SPI2130 pins to + * the hardware SPI interface on your board and define the required CS pins + * in your `pins_MYBOARD.h` file. (e.g., RAMPS 1.4 uses AUX3 pins `X_CS_PIN 53`, `Y_CS_PIN 49`, etc.). + */ +//#define HAVE_TMC2130 + +#if ENABLED(HAVE_TMC2130) + + // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY + //#define X_IS_TMC2130 + //#define X2_IS_TMC2130 + //#define Y_IS_TMC2130 + //#define Y2_IS_TMC2130 + //#define Z_IS_TMC2130 + //#define Z2_IS_TMC2130 + //#define E0_IS_TMC2130 + //#define E1_IS_TMC2130 + //#define E2_IS_TMC2130 + //#define E3_IS_TMC2130 + //#define E4_IS_TMC2130 + + /** + * Stepper driver settings + */ + + #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 + #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current + #define INTERPOLATE 1 // Interpolate X/Y/Z_MICROSTEPS to 256 + + #define X_CURRENT 1000 // rms current in mA. Multiply by 1.41 for peak current. + #define X_MICROSTEPS 16 // 0..256 + + #define Y_CURRENT 1000 + #define Y_MICROSTEPS 16 + + #define Z_CURRENT 1000 + #define Z_MICROSTEPS 16 + + //#define X2_CURRENT 1000 + //#define X2_MICROSTEPS 16 + + //#define Y2_CURRENT 1000 + //#define Y2_MICROSTEPS 16 + + //#define Z2_CURRENT 1000 + //#define Z2_MICROSTEPS 16 + + //#define E0_CURRENT 1000 + //#define E0_MICROSTEPS 16 + + //#define E1_CURRENT 1000 + //#define E1_MICROSTEPS 16 + + //#define E2_CURRENT 1000 + //#define E2_MICROSTEPS 16 + + //#define E3_CURRENT 1000 + //#define E3_MICROSTEPS 16 + + //#define E4_CURRENT 1000 + //#define E4_MICROSTEPS 16 + + /** + * Use Trinamic's ultra quiet stepping mode. + * When disabled, Marlin will use spreadCycle stepping mode. + */ + #define STEALTHCHOP + + /** + * Let Marlin automatically control stepper current. + * This is still an experimental feature. + * Increase current every 5s by CURRENT_STEP until stepper temperature prewarn gets triggered, + * then decrease current by CURRENT_STEP until temperature prewarn is cleared. + * Adjusting starts from X/Y/Z/E_CURRENT but will not increase over AUTO_ADJUST_MAX + * 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. + * M906 S1 - Start adjusting current + * M906 S0 - Stop adjusting current + * M911 - Report stepper driver overtemperature pre-warn condition. + * M912 - Clear stepper driver overtemperature pre-warn condition flag. + */ + //#define AUTOMATIC_CURRENT_CONTROL + + #if ENABLED(AUTOMATIC_CURRENT_CONTROL) + #define CURRENT_STEP 50 // [mA] + #define AUTO_ADJUST_MAX 1300 // [mA], 1300mA_rms = 1840mA_peak + #define REPORT_CURRENT_CHANGE + #endif + + /** + * The driver will switch to spreadCycle when stepper speed is over HYBRID_THRESHOLD. + * This mode allows for faster movements at the expense of higher noise levels. + * STEALTHCHOP needs to be enabled. + * M913 X/Y/Z/E to live tune the setting + */ + //#define HYBRID_THRESHOLD + + #define X_HYBRID_THRESHOLD 100 // [mm/s] + #define X2_HYBRID_THRESHOLD 100 + #define Y_HYBRID_THRESHOLD 100 + #define Y2_HYBRID_THRESHOLD 100 + #define Z_HYBRID_THRESHOLD 4 + #define Z2_HYBRID_THRESHOLD 4 + #define E0_HYBRID_THRESHOLD 30 + #define E1_HYBRID_THRESHOLD 30 + #define E2_HYBRID_THRESHOLD 30 + #define E3_HYBRID_THRESHOLD 30 + #define E4_HYBRID_THRESHOLD 30 + + /** + * Use stallGuard2 to sense an obstacle and trigger an endstop. + * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. + * If used along with STEALTHCHOP, the movement will be louder when homing. This is normal. + * + * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. + * Higher values make the system LESS sensitive. + * Lower value make the system MORE sensitive. + * Too low values can lead to false positives, while too high values will collide the axis without triggering. + * It is advised to set X/Y_HOME_BUMP_MM to 0. + * M914 X/Y to live tune the setting + */ + //#define SENSORLESS_HOMING + + #if ENABLED(SENSORLESS_HOMING) + #define X_HOMING_SENSITIVITY 19 + #define Y_HOMING_SENSITIVITY 19 + #endif + + /** + * You can set your own advanced settings by filling in predefined functions. + * A list of available functions can be found on the library github page + * https://github.com/teemuatlut/TMC2130Stepper + * + * Example: + * #define TMC2130_ADV() { \ + * stepperX.diag0_temp_prewarn(1); \ + * stepperX.interpolate(0); \ + * } + */ + #define TMC2130_ADV() { } + +#endif // HAVE_TMC2130 + +// @section L6470 + +/** + * Enable this section if you have L6470 motor drivers. + * You need to import the L6470 library into the Arduino IDE for this. + * (https://github.com/ameyer/Arduino-L6470) + */ + +//#define HAVE_L6470DRIVER +#if ENABLED(HAVE_L6470DRIVER) + + //#define X_IS_L6470 + //#define X2_IS_L6470 + //#define Y_IS_L6470 + //#define Y2_IS_L6470 + //#define Z_IS_L6470 + //#define Z2_IS_L6470 + //#define E0_IS_L6470 + //#define E1_IS_L6470 + //#define E2_IS_L6470 + //#define E3_IS_L6470 + //#define E4_IS_L6470 + + #define X_MICROSTEPS 16 // number of microsteps + #define X_K_VAL 50 // 0 - 255, Higher values, are higher power. Be careful not to go too high + #define X_OVERCURRENT 2000 // maxc current in mA. If the current goes over this value, the driver will switch off + #define X_STALLCURRENT 1500 // current in mA where the driver will detect a stall + + #define X2_MICROSTEPS 16 + #define X2_K_VAL 50 + #define X2_OVERCURRENT 2000 + #define X2_STALLCURRENT 1500 + + #define Y_MICROSTEPS 16 + #define Y_K_VAL 50 + #define Y_OVERCURRENT 2000 + #define Y_STALLCURRENT 1500 + + #define Y2_MICROSTEPS 16 + #define Y2_K_VAL 50 + #define Y2_OVERCURRENT 2000 + #define Y2_STALLCURRENT 1500 + + #define Z_MICROSTEPS 16 + #define Z_K_VAL 50 + #define Z_OVERCURRENT 2000 + #define Z_STALLCURRENT 1500 + + #define Z2_MICROSTEPS 16 + #define Z2_K_VAL 50 + #define Z2_OVERCURRENT 2000 + #define Z2_STALLCURRENT 1500 + + #define E0_MICROSTEPS 16 + #define E0_K_VAL 50 + #define E0_OVERCURRENT 2000 + #define E0_STALLCURRENT 1500 + + #define E1_MICROSTEPS 16 + #define E1_K_VAL 50 + #define E1_OVERCURRENT 2000 + #define E1_STALLCURRENT 1500 + + #define E2_MICROSTEPS 16 + #define E2_K_VAL 50 + #define E2_OVERCURRENT 2000 + #define E2_STALLCURRENT 1500 + + #define E3_MICROSTEPS 16 + #define E3_K_VAL 50 + #define E3_OVERCURRENT 2000 + #define E3_STALLCURRENT 1500 + + #define E4_MICROSTEPS 16 + #define E4_K_VAL 50 + #define E4_OVERCURRENT 2000 + #define E4_STALLCURRENT 1500 + +#endif + +/** + * TWI/I2C BUS + * + * This feature is an EXPERIMENTAL feature so it shall not be used on production + * machines. Enabling this will allow you to send and receive I2C data from slave + * devices on the bus. + * + * ; Example #1 + * ; This macro send the string "Marlin" to the slave device with address 0x63 (99) + * ; It uses multiple M260 commands with one B arg + * M260 A99 ; Target slave address + * M260 B77 ; M + * M260 B97 ; a + * M260 B114 ; r + * M260 B108 ; l + * M260 B105 ; i + * M260 B110 ; n + * M260 S1 ; Send the current buffer + * + * ; Example #2 + * ; Request 6 bytes from slave device with address 0x63 (99) + * M261 A99 B5 + * + * ; Example #3 + * ; Example serial output of a M261 request + * echo:i2c-reply: from:99 bytes:5 data:hello + */ + +// @section i2cbus + +//#define EXPERIMENTAL_I2CBUS +#define I2C_SLAVE_ADDRESS 0 // Set a value from 8 to 127 to act as a slave + +// @section extras + +/** + * Spindle & Laser control + * + * Add the M3, M4, and M5 commands to turn the spindle/laser on and off, and + * to set spindle speed, spindle direction, and laser power. + * + * SuperPid is a router/spindle speed controller used in the CNC milling community. + * Marlin can be used to turn the spindle on and off. It can also be used to set + * the spindle speed from 5,000 to 30,000 RPM. + * + * 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. + */ +//#define SPINDLE_LASER_ENABLE +#if ENABLED(SPINDLE_LASER_ENABLE) + + #define SPINDLE_LASER_ENABLE_INVERT false // set to "true" if the on/off function is reversed + #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 // delay in milliseconds to allow the spindle/laser to come up to speed/power + #define SPINDLE_LASER_POWERDOWN_DELAY 5000 // delay in milliseconds to allow the spindle to stop + #define SPINDLE_DIR_CHANGE true // set to true if your spindle controller supports changing spindle direction + #define SPINDLE_INVERT_DIR false + #define SPINDLE_STOP_ON_DIR_CHANGE true // set to true if Marlin should stop the spindle before changing rotation direction + + /** + * The M3 & M4 commands use the following equation to convert PWM duty cycle to speed/power + * + * SPEED/POWER = PWM duty cycle * SPEED_POWER_SLOPE + SPEED_POWER_INTERCEPT + * where PWM duty cycle varies from 0 to 255 + * + * set the following for your controller (ALL MUST BE SET) + */ + + #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_SLOPE 0.3922 + //#define SPEED_POWER_INTERCEPT 0 + //#define SPEED_POWER_MIN 10 + //#define SPEED_POWER_MAX 100 // 0-100% +#endif + +/** + * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins + */ +//#define PINS_DEBUGGING + +/** + * Auto-report temperatures with M155 S + */ +#define AUTO_REPORT_TEMPERATURES + +/** + * Include capabilities in M115 output + */ +#define EXTENDED_CAPABILITIES_REPORT + +/** + * Volumetric extrusion default state + * 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. + */ +//#define VOLUMETRIC_DEFAULT_ON + +/** + * Enable this option for a leaner build of Marlin that removes all + * workspace offsets, simplifying coordinate transformations, leveling, etc. + * + * - M206 and M428 are disabled. + * - G92 will revert to its behavior from Marlin 1.0. + */ +//#define NO_WORKSPACE_OFFSETS + +/** + * 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. + * + * For clients that use a fixed-width font (like OctoPrint), leave this set to 1.0. + * Otherwise, adjust according to your client and font. + */ +#define PROPORTIONAL_FONT_RATIO 1.0 + +/** + * Spend 28 bytes of SRAM to optimize the GCode parser + */ +#define FASTER_GCODE_PARSER + +/** + * User-defined menu items that execute custom GCode + */ +//#define CUSTOM_USER_MENUS +#if ENABLED(CUSTOM_USER_MENUS) + #define USER_SCRIPT_DONE "M117 User Script Done" + #define USER_SCRIPT_AUDIBLE_FEEDBACK + //#define USER_SCRIPT_RETURN // Return to status screen after a script + + #define USER_DESC_1 "Home & UBL Info" + #define USER_GCODE_1 "G28\nG29 W" + + #define USER_DESC_2 "Preheat for PLA" + #define USER_GCODE_2 "M140 S" STRINGIFY(PREHEAT_1_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND) + + #define USER_DESC_3 "Preheat for ABS" + #define USER_GCODE_3 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND) + + #define USER_DESC_4 "Heat Bed/Home/Level" + #define USER_GCODE_4 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nG28\nG29" + + #define USER_DESC_5 "Home & Info" + #define USER_GCODE_5 "G28\nM503" +#endif + +/** + * Specify an action command to send to the host when the printer is killed. + * Will be sent in the form '//action:ACTION_ON_KILL', e.g. '//action:poweroff'. + * The host must be configured to handle the action command. + */ +//#define ACTION_ON_KILL "poweroff" + +//=========================================================================== +//====================== I2C Position Encoder Settings ====================== +//=========================================================================== + +/** + * I2C position encoders for closed loop control. + * Developed by Chris Barr at Aus3D. + * + * Wiki: http://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/ + * + * Reilabuild encoders have been modified to improve reliability. + */ + +//#define I2C_POSITION_ENCODERS +#if ENABLED(I2C_POSITION_ENCODERS) + + #define I2CPE_ENCODER_CNT 1 // The number of encoders installed; max of 5 + // encoders supported currently. + + #define I2CPE_ENC_1_ADDR I2CPE_PRESET_ADDR_X // I2C address of the encoder. 30-200. + #define I2CPE_ENC_1_AXIS X_AXIS // Axis the encoder module is installed on. _AXIS. + #define I2CPE_ENC_1_TYPE I2CPE_ENC_TYPE_LINEAR // Type of encoder: I2CPE_ENC_TYPE_LINEAR -or- + // I2CPE_ENC_TYPE_ROTARY. + #define I2CPE_ENC_1_TICKS_UNIT 2048 // 1024 for magnetic strips with 2mm poles; 2048 for + // 1mm poles. For linear encoders this is ticks / mm, + // for rotary encoders this is ticks / revolution. + //#define I2CPE_ENC_1_TICKS_REV (16 * 200) // Only needed for rotary encoders; number of stepper + // steps per full revolution (motor steps/rev * microstepping) + //#define I2CPE_ENC_1_INVERT // Invert the direction of axis travel. + #define I2CPE_ENC_1_EC_METHOD I2CPE_ECM_NONE // Type of error error correction. + #define I2CPE_ENC_1_EC_THRESH 0.10 // Threshold size for error (in mm) above which the + // printer will attempt to correct the error; errors + // smaller than this are ignored to minimize effects of + // measurement noise / latency (filter). + + #define I2CPE_ENC_2_ADDR I2CPE_PRESET_ADDR_Y // Same as above, but for encoder 2. + #define I2CPE_ENC_2_AXIS Y_AXIS + #define I2CPE_ENC_2_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_ENC_2_TICKS_UNIT 2048 + //#define I2CPE_ENC_2_TICKS_REV (16 * 200) + //#define I2CPE_ENC_2_INVERT + #define I2CPE_ENC_2_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_ENC_2_EC_THRESH 0.10 + + #define I2CPE_ENC_3_ADDR I2CPE_PRESET_ADDR_Z // Encoder 3. Add additional configuration options + #define I2CPE_ENC_3_AXIS Z_AXIS // as above, or use defaults below. + + #define I2CPE_ENC_4_ADDR I2CPE_PRESET_ADDR_E // Encoder 4. + #define I2CPE_ENC_4_AXIS E_AXIS + + #define I2CPE_ENC_5_ADDR 34 // Encoder 5. + #define I2CPE_ENC_5_AXIS E_AXIS + + // Default settings for encoders which are enabled, but without settings configured above. + #define I2CPE_DEF_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_DEF_ENC_TICKS_UNIT 2048 + #define I2CPE_DEF_TICKS_REV (16 * 200) + #define I2CPE_DEF_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_DEF_EC_THRESH 0.1 + + //#define I2CPE_ERR_THRESH_ABORT 100.0 // Threshold size for error (in mm) error on any given + // axis after which the printer will abort. Comment out to + // disable abort behaviour. + + #define I2CPE_TIME_TRUSTED 10000 // After an encoder fault, there must be no further fault + // for this amount of time (in ms) before the encoder + // is trusted again. + + /** + * Position is checked every time a new command is executed from the buffer but during long moves, + * this setting determines the minimum update time between checks. A value of 100 works well with + * error rolling average when attempting to correct only for skips and not for vibration. + */ + #define I2CPE_MIN_UPD_TIME_MS 100 // Minimum time in miliseconds between encoder checks. + + // Use a rolling average to identify persistant errors that indicate skips, as opposed to vibration and noise. + #define I2CPE_ERR_ROLLING_AVERAGE + +#endif // I2C_POSITION_ENCODERS + +/** + * MAX7219 Debug Matrix + * + * Add support for a low-cost 8x8 LED Matrix based on the Max7219 chip, which can be used as a status + * display. Requires 3 signal wires. Some useful debug options are included to demonstrate its usage. + * + * Fully assembled MAX7219 boards can be found on the internet for under $2(US). + * For example, see https://www.ebay.com/sch/i.html?_nkw=332349290049 + */ +//#define MAX7219_DEBUG +#if ENABLED(MAX7219_DEBUG) + #define MAX7219_CLK_PIN 64 // 77 on Re-ARM // Configuration of the 3 pins to control the display + #define MAX7219_DIN_PIN 57 // 78 on Re-ARM + #define MAX7219_LOAD_PIN 44 // 79 on Re-ARM + + /** + * Sample debug features + * If you add more debug displays, be careful to avoid conflicts! + */ + #define MAX7219_DEBUG_PRINTER_ALIVE // Blink corner LED of 8x8 matrix to show that the firmware is functioning + #define MAX7219_DEBUG_STEPPER_HEAD 3 // Show the stepper queue head position on this and the next LED matrix row + #define MAX7219_DEBUG_STEPPER_TAIL 5 // Show the stepper queue tail position on this and the next LED matrix row + + #define MAX7219_DEBUG_STEPPER_QUEUE 0 // Show the current stepper queue depth on this and the next LED matrix row + // If you experience stuttering, reboots, etc. this option can reveal how + // tweaks made to the configuration are affecting the printer in real-time. +#endif + +#endif // CONFIGURATION_ADV_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/delta/generic/Configuration.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/delta/generic/Configuration.h new file mode 100644 index 00000000..1bb3ad1d --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/delta/generic/Configuration.h @@ -0,0 +1,1816 @@ +/** + * 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 . + * + */ + +/** + * Configuration.h + * + * Basic settings such as: + * + * - Type of electronics + * - Type of temperature sensor + * - Printer geometry + * - Endstop configuration + * - LCD controller + * - Extra features + * + * Advanced settings can be found in Configuration_adv.h + * + */ +#ifndef CONFIGURATION_H +#define CONFIGURATION_H +#define CONFIGURATION_H_VERSION 010100 + +//=========================================================================== +//============================= Getting Started ============================= +//=========================================================================== + +/** + * Here are some standard links for getting your machine calibrated: + * + * http://reprap.org/wiki/Calibration + * http://youtu.be/wAL9d7FgInk + * http://calculator.josefprusa.cz + * http://reprap.org/wiki/Triffid_Hunter%27s_Calibration_Guide + * http://www.thingiverse.com/thing:5573 + * https://sites.google.com/site/repraplogphase/calibration-of-your-reprap + * http://www.thingiverse.com/thing:298812 + */ + +//=========================================================================== +//============================= DELTA Printer =============================== +//=========================================================================== +// For a Delta printer start with one of the configuration files in the +// example_configurations/delta directory and customize for your machine. +// + +//=========================================================================== +//============================= SCARA Printer =============================== +//=========================================================================== +// For a SCARA printer start with the configuration files in +// example_configurations/SCARA and customize for your machine. +// + +// @section info + +// User-specified version info of this build to display in [Pronterface, etc] terminal window during +// startup. Implementation of an idea by Prof Braino to inform user that any changes made to this +// build by the user have been successfully uploaded into firmware. +#define STRING_CONFIG_H_AUTHOR "(none, default config)" // Who made the changes. +#define SHOW_BOOTSCREEN +#define STRING_SPLASH_LINE1 SHORT_BUILD_VERSION // will be shown during bootup in line 1 +#define STRING_SPLASH_LINE2 WEBSITE_URL // will be shown during bootup in line 2 + +// +// *** VENDORS PLEASE READ ***************************************************** +// +// Marlin now allow you to have a vendor boot image to be displayed on machine +// start. When SHOW_CUSTOM_BOOTSCREEN is defined Marlin will first show your +// custom boot image and then the default Marlin boot image is shown. +// +// We suggest for you to take advantage of this new feature and keep the Marlin +// boot image unmodified. For an example have a look at the bq Hephestos 2 +// example configuration folder. +// +//#define SHOW_CUSTOM_BOOTSCREEN +// @section machine + +/** + * Select which serial port on the board will be used for communication with the host. + * This allows the connection of wireless adapters (for instance) to non-default port pins. + * Serial port 0 is always used by the Arduino bootloader regardless of this setting. + * + * :[0, 1, 2, 3, 4, 5, 6, 7] + */ +#define SERIAL_PORT 0 + +/** + * This setting determines the communication speed of the printer. + * + * 250000 works in most cases, but you might try a lower speed if + * you commonly experience drop-outs during host printing. + * You may try up to 1000000 to speed up SD file transfer. + * + * :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000] + */ +#define BAUDRATE 250000 + +// Enable the Bluetooth serial interface on AT90USB devices +//#define BLUETOOTH + +// The following define selects which electronics board you have. +// Please choose the name from boards.h that matches your setup +#ifndef MOTHERBOARD + #define MOTHERBOARD BOARD_RAMPS_14_EFB +#endif + +// Optional custom name for your RepStrap or other custom machine +// Displayed in the LCD "Ready" message +#define CUSTOM_MACHINE_NAME "Deltabot" + +// Define this to set a unique identifier for this printer, (Used by some programs to differentiate between machines) +// You can use an online service to generate a random UUID. (eg http://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] +#define EXTRUDERS 1 + +// For Cyclops or any "multi-extruder" that shares a single nozzle. +//#define SINGLENOZZLE + +/** + * Průša MK2 Single Nozzle Multi-Material Multiplexer, and variants. + * + * This device allows one stepper driver on a control board to drive + * two to eight stepper motors, one at a time, in a manner suitable + * for extruders. + * + * This option only allows the multiplexer to switch on tool-change. + * Additional options to configure custom E moves are pending. + */ +//#define MK2_MULTIPLEXER +#if ENABLED(MK2_MULTIPLEXER) + // Override the default DIO selector pins here, if needed. + // Some pins files may provide defaults for these pins. + //#define E_MUX0_PIN 40 // Always Required + //#define E_MUX1_PIN 42 // Needed for 3 to 8 steppers + //#define E_MUX2_PIN 44 // Needed for 5 to 8 steppers +#endif + +// A dual extruder that uses a single stepper motor +//#define SWITCHING_EXTRUDER +#if ENABLED(SWITCHING_EXTRUDER) + #define SWITCHING_EXTRUDER_SERVO_NR 0 + #define SWITCHING_EXTRUDER_SERVO_ANGLES { 0, 90 } // Angles for E0, E1[, E2, E3] + #if EXTRUDERS > 3 + #define SWITCHING_EXTRUDER_E23_SERVO_NR 1 + #endif +#endif + +// A dual-nozzle that uses a servomotor to raise/lower one of the nozzles +//#define SWITCHING_NOZZLE +#if ENABLED(SWITCHING_NOZZLE) + #define SWITCHING_NOZZLE_SERVO_NR 0 + #define SWITCHING_NOZZLE_SERVO_ANGLES { 0, 90 } // Angles for E0, E1 + //#define HOTEND_OFFSET_Z { 0.0, 0.0 } +#endif + +/** + * Two separate X-carriages with extruders that connect to a moving part + * via a magnetic docking mechanism. Requires SOL1_PIN and SOL2_PIN. + */ +//#define PARKING_EXTRUDER +#if ENABLED(PARKING_EXTRUDER) + #define PARKING_EXTRUDER_SOLENOIDS_INVERT // If enabled, the solenoid is NOT magnetized with applied voltage + #define PARKING_EXTRUDER_SOLENOIDS_PINS_ACTIVE LOW // LOW or HIGH pin signal energizes the coil + #define PARKING_EXTRUDER_SOLENOIDS_DELAY 250 // Delay (ms) for magnetic field. No delay if 0 or not defined. + #define PARKING_EXTRUDER_PARKING_X { -78, 184 } // X positions for parking the extruders + #define PARKING_EXTRUDER_GRAB_DISTANCE 1 // mm to move beyond the parking point to grab the extruder + #define PARKING_EXTRUDER_SECURITY_RAISE 5 // Z-raise before parking + #define HOTEND_OFFSET_Z { 0.0, 1.3 } // Z-offsets of the two hotends. The first must be 0. +#endif + +/** + * "Mixing Extruder" + * - Adds a new code, M165, to set the current mix factors. + * - Extends the stepping routines to move multiple steppers in proportion to the mix. + * - Optional support for Repetier Firmware M163, M164, and virtual extruder. + * - This implementation supports only a single extruder. + * - Enable DIRECT_MIXING_IN_G1 for Pia Taubert's reference implementation + */ +//#define MIXING_EXTRUDER +#if ENABLED(MIXING_EXTRUDER) + #define MIXING_STEPPERS 2 // Number of steppers in your mixing extruder + #define MIXING_VIRTUAL_TOOLS 16 // Use the Virtual Tool method with M163 and M164 + //#define DIRECT_MIXING_IN_G1 // Allow ABCDHI mix factors in G1 movement commands +#endif + +// Offset of the extruders (uncomment if using more than one and relying on firmware to position when changing). +// The offset has to be X=0, Y=0 for the extruder 0 hotend (default extruder). +// For the other hotends it is their distance from the extruder 0 hotend. +//#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis +//#define HOTEND_OFFSET_Y {0.0, 5.00} // (in mm) for each extruder, offset of the hotend on the Y axis + +// @section machine + +/** + * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN + * + * 0 = No Power Switch + * 1 = ATX + * 2 = X-Box 360 203Watts (the blue wire connected to PS_ON and the red wire to VCC) + * + * :{ 0:'No power switch', 1:'ATX', 2:'X-Box 360' } + */ +#define POWER_SUPPLY 1 + +#if POWER_SUPPLY > 0 + // Enable this option to leave the PSU off at startup. + // Power to steppers and heaters will need to be turned on with M80. + //#define PS_DEFAULT_OFF +#endif + +// @section temperature + +//=========================================================================== +//============================= Thermal Settings ============================ +//=========================================================================== + +/** + * --NORMAL IS 4.7kohm PULLUP!-- 1kohm pullup can be used on hotend sensor, using correct resistor and table + * + * Temperature sensors available: + * + * -3 : thermocouple with MAX31855 (only for sensor 0) + * -2 : thermocouple with MAX6675 (only for sensor 0) + * -1 : thermocouple with AD595 + * 0 : not used + * 1 : 100k thermistor - best choice for EPCOS 100k (4.7k pullup) + * 2 : 200k thermistor - ATC Semitec 204GT-2 (4.7k pullup) + * 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 (Used in ParCan & J-Head) (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) + * 71 : 100k Honeywell thermistor 135-104LAF-J01 (4.7k pullup) + * 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) + * 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" + * 20 : the PT100 circuit found in the Ultimainboard V2.x + * 60 : 100k Maker's Tool Works Kapton Bed Thermistor beta=3950 + * 66 : 4.7M High Temperature thermistor from Dyze Design + * 70 : the 100K thermistor found in the bq Hephestos 2 + * 75 : 100k Generic Silicon Heat Pad with NTC 100K MGB18-104F39050L32 thermistor + * + * 1k ohm pullup tables - This is atypical, and requires changing out the 4.7k pullup for 1k. + * (but gives greater accuracy and more stable PID) + * 51 : 100k thermistor - EPCOS (1k pullup) + * 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 + * 1010 : Pt1000 with 1k pullup (non standard) + * 147 : Pt100 with 4k7 pullup + * 110 : Pt100 with 1k pullup (non standard) + * + * Use these for Testing or Development purposes. NEVER for production machine. + * 998 : Dummy Table that ALWAYS reads 25°C or the temperature defined below. + * 999 : Dummy Table that ALWAYS reads 100°C or the temperature defined below. + * + * :{ '0': "Not used", '1':"100k / 4.7k - EPCOS", '2':"200k / 4.7k - ATC Semitec 204GT-2", '3':"Mendel-parts / 4.7k", '4':"10k !! do not use for a hotend. Bad resolution at high temp. !!", '5':"100K / 4.7k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '6':"100k / 4.7k EPCOS - Not as accurate as Table 1", '7':"100k / 4.7k Honeywell 135-104LAG-J01", '8':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT", '9':"100k / 4.7k GE Sensing AL03006-58.2K-97-G1", '10':"100k / 4.7k RS 198-961", '11':"100k / 4.7k beta 3950 1%", '12':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT (calibrated for Makibox hot bed)", '13':"100k Hisens 3950 1% up to 300°C for hotend 'Simple ONE ' & hotend 'All In ONE'", '20':"PT100 (Ultimainboard V2.x)", '51':"100k / 1k - EPCOS", '52':"200k / 1k - ATC Semitec 204GT-2", '55':"100k / 1k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '60':"100k Maker's Tool Works Kapton Bed Thermistor beta=3950", '66':"Dyze Design 4.7M High Temperature thermistor", '70':"the 100K thermistor found in the bq Hephestos 2", '71':"100k / 4.7k Honeywell 135-104LAF-J01", '147':"Pt100 / 4.7k", '1047':"Pt1000 / 4.7k", '110':"Pt100 / 1k (non-standard)", '1010':"Pt1000 / 1k (non standard)", '-3':"Thermocouple + MAX31855 (only for sensor 0)", '-2':"Thermocouple + MAX6675 (only for sensor 0)", '-1':"Thermocouple + AD595",'998':"Dummy 1", '999':"Dummy 2" } + */ +#define TEMP_SENSOR_0 -1 +#define TEMP_SENSOR_1 0 +#define TEMP_SENSOR_2 0 +#define TEMP_SENSOR_3 0 +#define TEMP_SENSOR_4 0 +#define TEMP_SENSOR_BED 0 + +// Dummy thermistor constant temperature readings, for use with 998 and 999 +#define DUMMY_THERMISTOR_998_VALUE 25 +#define DUMMY_THERMISTOR_999_VALUE 100 + +// 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 +#define MAX_REDUNDANT_TEMP_SENSOR_DIFF 10 + +// Extruder temperature must be close to target for this long before M109 returns success +#define TEMP_RESIDENCY_TIME 10 // (seconds) +#define TEMP_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// Bed temperature must be close to target for this long before M190 returns success +#define TEMP_BED_RESIDENCY_TIME 0 // (seconds) +#define TEMP_BED_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_BED_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// The minimal temperature defines the temperature below which the heater will not be enabled It is used +// to check that the wiring to the thermistor is not broken. +// Otherwise this would lead to the heater being powered on all the time. +#define HEATER_0_MINTEMP 5 +#define HEATER_1_MINTEMP 5 +#define HEATER_2_MINTEMP 5 +#define HEATER_3_MINTEMP 5 +#define HEATER_4_MINTEMP 5 +#define BED_MINTEMP 5 + +// When temperature exceeds max temp, your heater will be switched off. +// This feature exists to protect your hotend from overheating accidentally, but *NOT* from thermistor short/failure! +// You should use MINTEMP for thermistor short/failure protection. +#define HEATER_0_MAXTEMP 275 +#define HEATER_1_MAXTEMP 275 +#define HEATER_2_MAXTEMP 275 +#define HEATER_3_MAXTEMP 275 +#define HEATER_4_MAXTEMP 275 +#define BED_MAXTEMP 150 + +//=========================================================================== +//============================= PID Settings ================================ +//=========================================================================== +// PID Tuning Guide here: http://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 +#if ENABLED(PIDTEMP) + //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. + //#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. + #define K1 0.95 //smoothing factor within the PID + + // 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 + +#endif // PIDTEMP + +//=========================================================================== +//============================= PID > Bed Temperature Control =============== +//=========================================================================== +// Select PID or bang-bang with PIDTEMPBED. If bang-bang, BED_LIMIT_SWITCHING will enable hysteresis +// +// Uncomment this to enable PID on the bed. It uses the same frequency PWM as the extruder. +// If your PID_dT is the default, and correct for your hardware/configuration, that means 7.689Hz, +// which is fine for driving a square wave into a resistive load and does not significantly impact you FET heating. +// This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W heater. +// If your configuration is significantly different than this and you don't understand the issues involved, you probably +// shouldn't use bed PID until someone else verifies your hardware works. +// If this is enabled, find your own PID constants below. +//#define PIDTEMPBED + +//#define BED_LIMIT_SWITCHING + +// This sets the max power delivered to the bed, and replaces the HEATER_BED_DUTY_CYCLE_DIVIDER option. +// all forms of bed control obey this (PID, bang-bang, bang-bang with hysteresis) +// setting this to anything other than 255 enables a form of PWM to the bed just like HEATER_BED_DUTY_CYCLE_DIVIDER did, +// so you shouldn't use it unless you are OK with PWM on your bed. (see the comment on enabling PIDTEMPBED) +#define MAX_BED_POWER 255 // limits duty cycle to bed; 255=full current + +#if ENABLED(PIDTEMPBED) + + //#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) + #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 + +// @section extruder + +// This option prevents extrusion if the temperature is below EXTRUDE_MINTEMP. +// It also enables the M302 command to set the minimum extrusion temperature +// or to allow moving the extruder regardless of the hotend temperature. +// *** IT IS HIGHLY RECOMMENDED TO LEAVE THIS OPTION ENABLED! *** +#define PREVENT_COLD_EXTRUSION +#define EXTRUDE_MINTEMP 170 + +// This option prevents a single extrusion longer than EXTRUDE_MAXLENGTH. +// Note that for Bowden Extruders a too-small value here may prevent loading. +#define PREVENT_LENGTHY_EXTRUDE +#define EXTRUDE_MAXLENGTH 200 + +//=========================================================================== +//======================== Thermal Runaway Protection ======================= +//=========================================================================== + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * If you get "Thermal Runaway" or "Heating failed" errors the + * details can be tuned in Configuration_adv.h + */ + +#define THERMAL_PROTECTION_HOTENDS // Enable thermal protection for all extruders +#define THERMAL_PROTECTION_BED // Enable thermal protection for the heated bed + +//=========================================================================== +//============================= Mechanical Settings ========================= +//=========================================================================== + +// @section machine + +// Uncomment one of these options to enable CoreXY, CoreXZ, or CoreYZ kinematics +// either in the usual order or reversed +//#define COREXY +//#define COREXZ +//#define COREYZ +//#define COREYX +//#define COREZX +//#define COREZY + +//=========================================================================== +//============================== Delta Settings ============================= +//=========================================================================== +// Enable DELTA kinematics and most of the default configuration for Deltas +#define DELTA + +#if ENABLED(DELTA) + + // Make delta curves from many straight lines (linear interpolation). + // This is a trade-off between visible corners (not enough segments) + // and processor overload (too many expensive sqrt calls). + #define DELTA_SEGMENTS_PER_SECOND 200 + + // After homing move down to a height where XY movement is unconstrained + //#define DELTA_HOME_TO_SAFE_ZONE + + // Delta calibration menu + // uncomment to add three points calibration menu option. + // See http://minow.blogspot.com/index.html#4918805519571907051 + //#define DELTA_CALIBRATION_MENU + + // uncomment to add G33 Delta Auto-Calibration (Enable EEPROM_SETTINGS to store results) + //#define DELTA_AUTO_CALIBRATION + + // NOTE NB all values for DELTA_* values MUST be floating point, so always have a decimal point in them + + #if ENABLED(DELTA_AUTO_CALIBRATION) + // set the default number of probe points : n*n (1 -> 7) + #define DELTA_CALIBRATION_DEFAULT_POINTS 4 + #endif + + #if ENABLED(DELTA_AUTO_CALIBRATION) || ENABLED(DELTA_CALIBRATION_MENU) + // Set the radius for the calibration probe points - max DELTA_PRINTABLE_RADIUS*0.869 for non-eccentric probes + #define DELTA_CALIBRATION_RADIUS 121.5 // mm + // Set the steprate for papertest probing + #define PROBE_MANUALLY_STEP 0.025 + #endif + + // Print surface diameter/2 minus unreachable space (avoid collisions with vertical towers). + #define DELTA_PRINTABLE_RADIUS 140.0 // mm + + // Center-to-center distance of the holes in the diagonal push rods. + #define DELTA_DIAGONAL_ROD 250.0 // mm + + // height from z=0 to home position + #define DELTA_HEIGHT 250.00 // get this value from auto calibrate + + #define DELTA_ENDSTOP_ADJ { 0.0, 0.0, 0.0 } // get these from auto calibrate + + // Horizontal distance bridged by diagonal push rods when effector is centered. + #define DELTA_RADIUS 124.0 //mm Get this value from auto calibrate + + // Trim adjustments for individual towers + // tower angle corrections for X and Y tower / rotate XYZ so Z tower angle = 0 + // measured in degrees anticlockwise looking from above the printer + #define DELTA_TOWER_ANGLE_TRIM { 0.0, 0.0, 0.0 } // get these values from auto calibrate + + // delta radius and diaginal rod adjustments measured in mm + //#define DELTA_RADIUS_TRIM_TOWER { 0.0, 0.0, 0.0 } + //#define DELTA_DIAGONAL_ROD_TRIM_TOWER { 0.0, 0.0, 0.0 } + +#endif + +//=========================================================================== +//============================== Endstop Settings =========================== +//=========================================================================== + +// @section homing + +// Specify here all the endstop connectors that are connected to any endstop or probe. +// Almost all printers will be using one per axis. Probes will use one or more of the +// extra connectors. Leave undefined any used for non-endstop and non-probe purposes. +//#define USE_XMIN_PLUG +//#define USE_YMIN_PLUG +#define USE_ZMIN_PLUG // a Z probe +#define USE_XMAX_PLUG +#define USE_YMAX_PLUG +#define USE_ZMAX_PLUG + +// coarse Endstop Settings +#define ENDSTOPPULLUPS // Comment this out (using // at the start of the line) to disable the endstop pullup resistors + +#if DISABLED(ENDSTOPPULLUPS) + // fine endstop settings: Individual pullups. will be ignored if ENDSTOPPULLUPS is defined + //#define ENDSTOPPULLUP_XMAX + //#define ENDSTOPPULLUP_YMAX + //#define ENDSTOPPULLUP_ZMAX + //#define ENDSTOPPULLUP_XMIN + //#define ENDSTOPPULLUP_YMIN + //#define ENDSTOPPULLUP_ZMIN + //#define ENDSTOPPULLUP_ZMIN_PROBE +#endif + +// Mechanical endstop with COM to ground and NC to Signal uses "false" here (most common setup). +#define X_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Y_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define X_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Y_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MIN_PROBE_ENDSTOP_INVERTING true // set to true to invert the logic of the probe. + +// Enable this feature if all enabled endstop pins are interrupt-capable. +// This will remove the need to poll the interrupt pins, saving many CPU cycles. +//#define ENDSTOP_INTERRUPTS_FEATURE + +//============================================================================= +//============================== Movement Settings ============================ +//============================================================================= +// @section motion + +// delta speeds must be the same on xyz +/** + * Default Settings + * + * These settings can be reset by M502 + * + * Note that if EEPROM is enabled, saved values will override these. + */ + +/** + * With this option each E stepper can have its own factors for the + * following movement settings. If fewer factors are given than the + * total number of extruders, the last value applies to the rest. + */ +//#define DISTINCT_E_FACTORS + +/** + * Default Axis Steps Per Unit (steps/mm) + * Override with M92 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_AXIS_STEPS_PER_UNIT { 80, 80, 80, 760*1.1 } // default steps per unit for Kossel (GT2, 20 tooth) + +/** + * Default Max Feed Rate (mm/s) + * Override with M203 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_FEEDRATE { 500, 500, 500, 25 } + +/** + * Default Max Acceleration (change/s) change = mm/s + * (Maximum start speed for accelerated moves) + * Override with M201 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_ACCELERATION { 9000, 9000, 9000, 10000 } + +/** + * Default Acceleration (change/s) change = mm/s + * Override with M204 + * + * M204 P Acceleration + * M204 R Retract Acceleration + * M204 T Travel Acceleration + */ +#define DEFAULT_ACCELERATION 3000 // X, Y, Z and E acceleration for printing moves +#define DEFAULT_RETRACT_ACCELERATION 3000 // E acceleration for retracts +#define DEFAULT_TRAVEL_ACCELERATION 3000 // X, Y, Z acceleration for travel (non printing) moves + +/** + * Default Jerk (mm/s) + * Override with M205 X Y Z E + * + * "Jerk" specifies the minimum speed change that requires acceleration. + * When changing speed and direction, if the difference is less than the + * value set here, it may happen instantaneously. + */ +#define DEFAULT_XJERK 20.0 +#define DEFAULT_YJERK 20.0 +#define DEFAULT_ZJERK 20.0 // Must be same as XY for delta +#define DEFAULT_EJERK 5.0 + +//=========================================================================== +//============================= Z Probe Options ============================= +//=========================================================================== +// @section probes + +// +// See http://marlinfw.org/configuration/probes.html +// + +/** + * Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + * + * Enable this option for a probe connected to the Z Min endstop pin. + */ +//#define Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + +/** + * Z_MIN_PROBE_ENDSTOP + * + * Enable this option for a probe connected to any pin except Z-Min. + * (By default Marlin assumes the Z-Max endstop pin.) + * To use a custom Z Probe pin, set Z_MIN_PROBE_PIN below. + * + * - The simplest option is to use a free endstop connector. + * - Use 5V for powered (usually inductive) sensors. + * + * - RAMPS 1.3/1.4 boards may use the 5V, GND, and Aux4->D32 pin: + * - For simple switches connect... + * - normally-closed switches to GND and D32. + * - normally-open switches to 5V and D32. + * + * WARNING: Setting the wrong pin may have unexpected and potentially + * disastrous consequences. Use with caution and do your homework. + * + */ +#define Z_MIN_PROBE_ENDSTOP + +/** + * Probe Type + * + * Allen Key Probes, Servo Probes, Z-Sled Probes, FIX_MOUNTED_PROBE, etc. + * Activate one of these to use Auto Bed Leveling below. + */ + +/** + * The "Manual Probe" provides a means to do "Auto" Bed Leveling without a probe. + * Use G29 repeatedly, adjusting the Z height at each point with movement commands + * or (with LCD_BED_LEVELING) the LCD controller. + */ +//#define PROBE_MANUALLY + +/** + * A Fix-Mounted Probe either doesn't deploy or needs manual deployment. + * (e.g., an inductive probe or a nozzle-based probe-switch.) + */ +//#define FIX_MOUNTED_PROBE + +/** + * Z Servo Probe, such as an endstop switch on a rotating arm. + */ +//#define Z_ENDSTOP_SERVO_NR 0 // Defaults to SERVO 0 connector. +//#define Z_SERVO_ANGLES {70,0} // Z Servo Deploy and Stow angles + +/** + * The BLTouch probe uses a Hall effect sensor and emulates a servo. + */ +//#define BLTOUCH +#if ENABLED(BLTOUCH) + //#define BLTOUCH_DELAY 375 // (ms) Enable and increase if needed +#endif + +/** + * Enable one or more of the following if probing seems unreliable. + * Heaters and/or fans can be disabled during probing to minimize electrical + * noise. A delay can also be added to allow noise and vibration to settle. + * These options are most useful for the BLTouch probe, but may also improve + * readings with inductive probes and piezo sensors. + */ +//#define PROBING_HEATERS_OFF // Turn heaters off when probing +//#define PROBING_FANS_OFF // Turn fans off when probing +//#define DELAY_BEFORE_PROBING 200 // (ms) To prevent vibrations from triggering piezo sensors + +// A probe that is deployed and stowed with a solenoid pin (SOL1_PIN) +//#define SOLENOID_PROBE + +// A sled-mounted probe like those designed by Charles Bell. +//#define Z_PROBE_SLED +//#define SLED_DOCKING_OFFSET 5 // The extra distance the X axis must travel to pickup the sled. 0 should be fine but you can push it further if you'd like. + +// +// For Z_PROBE_ALLEN_KEY see the Delta example configurations. +// + +/** + * Z Probe to nozzle (X,Y) offset, relative to (0, 0). + * X and Y offsets must be integers. + * + * In the following example the X and Y offsets are both positive: + * #define X_PROBE_OFFSET_FROM_EXTRUDER 10 + * #define Y_PROBE_OFFSET_FROM_EXTRUDER 10 + * + * +-- BACK ---+ + * | | + * L | (+) P | R <-- probe (20,20) + * E | | I + * F | (-) N (+) | G <-- nozzle (10,10) + * T | | H + * | (-) | T + * | | + * O-- FRONT --+ + * (0,0) + */ +#define X_PROBE_OFFSET_FROM_EXTRUDER 0 // X offset: -left +right [of the nozzle] +#define Y_PROBE_OFFSET_FROM_EXTRUDER -10 // Y offset: -front +behind [the nozzle] +#define Z_PROBE_OFFSET_FROM_EXTRUDER -3.5 // Z offset: -below +above [the nozzle] + +// X and Y axis travel speed (mm/m) between probes +#define XY_PROBE_SPEED 4000 + +// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +#define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z + +// Speed for the "accurate" probe of each point +#define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) + +// Use double touch for probing +//#define PROBE_DOUBLE_TOUCH + +/** + * Allen key retractable z-probe as seen on many Kossel delta printers - http://reprap.org/wiki/Kossel#Automatic_bed_leveling_probe + * Deploys by touching z-axis belt. Retracts by pushing the probe down. Uses Z_MIN_PIN. + */ +//#define Z_PROBE_ALLEN_KEY + +#if ENABLED(Z_PROBE_ALLEN_KEY) + // 2 or 3 sets of coordinates for deploying and retracting the spring loaded touch probe on G29, + // if servo actuated touch probe is not defined. Uncomment as appropriate for your printer/probe. + + #define Z_PROBE_ALLEN_KEY_DEPLOY_1_X 30.0 + #define Z_PROBE_ALLEN_KEY_DEPLOY_1_Y DELTA_PRINTABLE_RADIUS + #define Z_PROBE_ALLEN_KEY_DEPLOY_1_Z 100.0 + #define Z_PROBE_ALLEN_KEY_DEPLOY_1_FEEDRATE XY_PROBE_SPEED + + #define Z_PROBE_ALLEN_KEY_DEPLOY_2_X 0.0 + #define Z_PROBE_ALLEN_KEY_DEPLOY_2_Y DELTA_PRINTABLE_RADIUS + #define Z_PROBE_ALLEN_KEY_DEPLOY_2_Z 100.0 + #define Z_PROBE_ALLEN_KEY_DEPLOY_2_FEEDRATE (XY_PROBE_SPEED)/10 + + #define Z_PROBE_ALLEN_KEY_DEPLOY_3_X Z_PROBE_ALLEN_KEY_DEPLOY_2_X * 0.75 + #define Z_PROBE_ALLEN_KEY_DEPLOY_3_Y Z_PROBE_ALLEN_KEY_DEPLOY_2_Y * 0.75 + #define Z_PROBE_ALLEN_KEY_DEPLOY_3_Z Z_PROBE_ALLEN_KEY_DEPLOY_2_Z + #define Z_PROBE_ALLEN_KEY_DEPLOY_3_FEEDRATE XY_PROBE_SPEED + + #define Z_PROBE_ALLEN_KEY_STOW_1_X -64.0 // Move the probe into position + #define Z_PROBE_ALLEN_KEY_STOW_1_Y 56.0 + #define Z_PROBE_ALLEN_KEY_STOW_1_Z 23.0 + #define Z_PROBE_ALLEN_KEY_STOW_1_FEEDRATE XY_PROBE_SPEED + + #define Z_PROBE_ALLEN_KEY_STOW_2_X -64.0 // Push it down + #define Z_PROBE_ALLEN_KEY_STOW_2_Y 56.0 + #define Z_PROBE_ALLEN_KEY_STOW_2_Z 3.0 + #define Z_PROBE_ALLEN_KEY_STOW_2_FEEDRATE (XY_PROBE_SPEED)/10 + + #define Z_PROBE_ALLEN_KEY_STOW_3_X -64.0 // Move it up to clear + #define Z_PROBE_ALLEN_KEY_STOW_3_Y 56.0 + #define Z_PROBE_ALLEN_KEY_STOW_3_Z 50.0 + #define Z_PROBE_ALLEN_KEY_STOW_3_FEEDRATE XY_PROBE_SPEED + + #define Z_PROBE_ALLEN_KEY_STOW_4_X 0.0 + #define Z_PROBE_ALLEN_KEY_STOW_4_Y 0.0 + #define Z_PROBE_ALLEN_KEY_STOW_4_Z Z_PROBE_ALLEN_KEY_STOW_3_Z + #define Z_PROBE_ALLEN_KEY_STOW_4_FEEDRATE XY_PROBE_SPEED + +#endif // Z_PROBE_ALLEN_KEY + +/** + * Z probes require clearance when deploying, stowing, and moving between + * probe points to avoid hitting the bed and other hardware. + * Servo-mounted probes require extra space for the arm to rotate. + * Inductive probes need space to keep from triggering early. + * + * Use these settings to specify the distance (mm) to raise the probe (or + * lower the bed). The values set here apply over and above any (negative) + * probe Z Offset set with Z_PROBE_OFFSET_FROM_EXTRUDER, M851, or the LCD. + * Only integer values >= 1 are valid here. + * + * Example: `M851 Z-5` with a CLEARANCE of 4 => 9mm from bed to nozzle. + * But: `M851 Z+1` with a CLEARANCE of 2 => 2mm from bed to nozzle. + */ +#define Z_CLEARANCE_DEPLOY_PROBE 15 // Z Clearance for Deploy/Stow +#define Z_CLEARANCE_BETWEEN_PROBES 5 // Z Clearance between probe points + +// For M851 give a range for adjusting the Z probe offset +#define Z_PROBE_OFFSET_RANGE_MIN -20 +#define Z_PROBE_OFFSET_RANGE_MAX 20 + +// Enable the M48 repeatability test to test probe accuracy +//#define Z_MIN_PROBE_REPEATABILITY_TEST + +// For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1 +// :{ 0:'Low', 1:'High' } +#define X_ENABLE_ON 0 +#define Y_ENABLE_ON 0 +#define Z_ENABLE_ON 0 +#define E_ENABLE_ON 0 // For all extruders + +// Disables axis stepper immediately when it's not being used. +// 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 +//#define DISABLE_REDUCED_ACCURACY_WARNING + +// @section extruder + +#define DISABLE_E false // For all extruders +#define DISABLE_INACTIVE_EXTRUDER true // Keep only the active extruder enabled. + +// @section machine + +// Invert the stepper direction. Change (or reverse the motor connector) if an axis goes the wrong way. +#define INVERT_X_DIR false // DELTA does not invert +#define INVERT_Y_DIR false +#define INVERT_Z_DIR false + +// Enable this option for Toshiba stepper drivers +//#define CONFIG_STEPPERS_TOSHIBA + +// @section extruder + +// For direct drive extruder v9 set to true, for geared extruder set to false. +#define INVERT_E0_DIR false +#define INVERT_E1_DIR false +#define INVERT_E2_DIR false +#define INVERT_E3_DIR false +#define INVERT_E4_DIR false + +// @section homing + +//#define NO_MOTION_BEFORE_HOMING // Inhibit movement until all axes have been homed + +//#define Z_HOMING_HEIGHT 4 // (in mm) Minimal z height before homing (G28) for Z clearance above the bed, clamps, ... + // Be sure you have this distance over your Z_MAX_POS in case. + +// Direction of endstops when homing; 1=MAX, -1=MIN +// :[-1,1] +#define X_HOME_DIR 1 // deltas always home to max +#define Y_HOME_DIR 1 +#define Z_HOME_DIR 1 + +// @section machine + +// The size of the print bed +#define X_BED_SIZE ((DELTA_PRINTABLE_RADIUS) * 2) +#define Y_BED_SIZE ((DELTA_PRINTABLE_RADIUS) * 2) + +// Travel limits (mm) after homing, corresponding to endstop positions. +#define X_MIN_POS -(DELTA_PRINTABLE_RADIUS) +#define Y_MIN_POS -(DELTA_PRINTABLE_RADIUS) +#define Z_MIN_POS 0 +#define X_MAX_POS DELTA_PRINTABLE_RADIUS +#define Y_MAX_POS DELTA_PRINTABLE_RADIUS +#define Z_MAX_POS MANUAL_Z_HOME_POS + +// If enabled, axes won't move below MIN_POS in response to movement commands. +#define MIN_SOFTWARE_ENDSTOPS +// If enabled, axes won't move above MAX_POS in response to movement commands. +#define MAX_SOFTWARE_ENDSTOPS + +/** + * Filament Runout Sensor + * A mechanical or opto endstop is used to check for the presence of filament. + * + * RAMPS-based boards use SERVO3_PIN. + * For other boards you may need to define FIL_RUNOUT_PIN. + * By default the firmware assumes HIGH = has filament, LOW = ran out + */ +//#define FILAMENT_RUNOUT_SENSOR +#if ENABLED(FILAMENT_RUNOUT_SENSOR) + #define FIL_RUNOUT_INVERTING false // set to true to invert the logic of the sensor. + #define ENDSTOPPULLUP_FIL_RUNOUT // Uncomment to use internal pullup for filament runout pins if the sensor is defined. + #define FILAMENT_RUNOUT_SCRIPT "M600" +#endif + +//=========================================================================== +//=============================== Bed Leveling ============================== +//=========================================================================== +// @section bedlevel + +/** + * Choose one of the options below to enable G29 Bed Leveling. The parameters + * and behavior of G29 will change depending on your selection. + * + * If using a Probe for Z Homing, enable Z_SAFE_HOMING also! + * + * - AUTO_BED_LEVELING_3POINT + * Probe 3 arbitrary points on the bed (that aren't collinear) + * You specify the XY coordinates of all 3 points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_LINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_BILINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a mesh, best for large or uneven beds. + * + * - AUTO_BED_LEVELING_UBL (Unified Bed Leveling) + * A comprehensive bed leveling system combining the features and benefits + * of other systems. UBL also includes integrated Mesh Generation, Mesh + * Validation and Mesh Editing systems. Currently, UBL is only checked out + * for Cartesian Printers. That said, it was primarily designed to correct + * poor quality Delta Printers. If you feel adventurous and have a Delta, + * please post an issue if something doesn't work correctly. Initially, + * you will need to set a reduced bed size so you have a rectangular area + * to test on. + * + * - MESH_BED_LEVELING + * Probe a grid manually + * The result is a mesh, suitable for large or uneven beds. (See BILINEAR.) + * For machines without a probe, Mesh Bed Leveling provides a method to perform + * leveling in steps so you can manually adjust the Z height at each grid-point. + * With an LCD controller the process is guided step-by-step. + */ +//#define AUTO_BED_LEVELING_3POINT +//#define AUTO_BED_LEVELING_LINEAR +//#define AUTO_BED_LEVELING_BILINEAR +//#define AUTO_BED_LEVELING_UBL +//#define MESH_BED_LEVELING + +/** + * Enable detailed logging of G28, G29, M48, etc. + * Turn on with the command 'M111 S32'. + * NOTE: Requires a lot of PROGMEM! + */ +//#define DEBUG_LEVELING_FEATURE + +#if ENABLED(MESH_BED_LEVELING) || ENABLED(AUTO_BED_LEVELING_BILINEAR) || ENABLED(AUTO_BED_LEVELING_UBL) + // Gradually reduce leveling correction until a set height is reached, + // at which point movement will be level to the machine's XY plane. + // The height can be set with M420 Z + //#define ENABLE_LEVELING_FADE_HEIGHT + + // Set the boundaries for probing (where the probe can reach). + #define DELTA_PROBEABLE_RADIUS (DELTA_PRINTABLE_RADIUS - 10) + +#endif + +#if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Set the number of grid points per dimension. + // Works best with 5 or more points in each dimension. + #define GRID_MAX_POINTS_X 9 + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + #define LEFT_PROBE_BED_POSITION -(DELTA_PROBEABLE_RADIUS) + #define RIGHT_PROBE_BED_POSITION DELTA_PROBEABLE_RADIUS + #define FRONT_PROBE_BED_POSITION -(DELTA_PROBEABLE_RADIUS) + #define BACK_PROBE_BED_POSITION DELTA_PROBEABLE_RADIUS + + // The Z probe minimum outer margin (to validate G29 parameters). + #define MIN_PROBE_EDGE 10 + + // Probe along the Y axis, advancing X after each column + //#define PROBE_Y_FIRST + + #if ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Beyond the probed grid, continue the implied tilt? + // Default is to maintain the height of the nearest edge. + //#define EXTRAPOLATE_BEYOND_GRID + + // + // Experimental Subdivision of the grid by Catmull-Rom method. + // Synthesizes intermediate points to produce a more detailed mesh. + // + //#define ABL_BILINEAR_SUBDIVISION + #if ENABLED(ABL_BILINEAR_SUBDIVISION) + // Number of subdivisions between probe points + #define BILINEAR_SUBDIVISIONS 3 + #endif + + #endif + +#elif ENABLED(AUTO_BED_LEVELING_3POINT) + + // 3 arbitrary points to probe. + // A simple cross-product is used to estimate the plane of the bed. + #define ABL_PROBE_PT_1_X 15 + #define ABL_PROBE_PT_1_Y 180 + #define ABL_PROBE_PT_2_X 15 + #define ABL_PROBE_PT_2_Y 20 + #define ABL_PROBE_PT_3_X 170 + #define ABL_PROBE_PT_3_Y 20 + +#elif ENABLED(AUTO_BED_LEVELING_UBL) + + //=========================================================================== + //========================= Unified Bed Leveling ============================ + //=========================================================================== + + #define UBL_MESH_INSET 1 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 10 // Don't use more than 15 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + #define _PX(R,A) (R) * cos(RADIANS(A)) + #define _PY(R,A) (R) * sin(RADIANS(A)) + #define UBL_PROBE_PT_1_X _PX(DELTA_PROBEABLE_RADIUS, 0) // Probing points for 3-Point leveling of the mesh + #define UBL_PROBE_PT_1_Y _PY(DELTA_PROBEABLE_RADIUS, 0) + #define UBL_PROBE_PT_2_X _PX(DELTA_PROBEABLE_RADIUS, 120) + #define UBL_PROBE_PT_2_Y _PY(DELTA_PROBEABLE_RADIUS, 120) + #define UBL_PROBE_PT_3_X _PX(DELTA_PROBEABLE_RADIUS, 240) + #define UBL_PROBE_PT_3_Y _PY(DELTA_PROBEABLE_RADIUS, 240) + + #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation + #define UBL_MESH_EDIT_MOVES_Z // Sophisticated users prefer no movement of nozzle + +#elif ENABLED(MESH_BED_LEVELING) + + //=========================================================================== + //=================================== Mesh ================================== + //=========================================================================== + + #define MESH_INSET 10 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 3 // Don't use more than 7 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + //#define MESH_G28_REST_ORIGIN // After homing all axes ('G28' or 'G28 XYZ') rest Z at Z_MIN_POS + +#endif // BED_LEVELING + +/** + * Use the LCD controller for bed leveling + * Requires MESH_BED_LEVELING or PROBE_MANUALLY + */ +//#define LCD_BED_LEVELING + +#if ENABLED(LCD_BED_LEVELING) + #define MBL_Z_STEP 0.025 // Step size while manually probing Z axis. + #define LCD_PROBE_Z_RANGE 4 // Z Range centered on Z_MIN_POS for LCD Z adjustment +#endif + +// Add a menu item to move between bed corners for manual bed adjustment +//#define LEVEL_BED_CORNERS + +/** + * Commands to execute at the end of G29 probing. + * Useful to retract or move the Z probe out of the way. + */ +//#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) +#define BED_CENTER_AT_0_0 + +// Manually set the home position. Leave these undefined for automatic settings. +// For DELTA this is the top-center of the Cartesian print volume. +//#define MANUAL_X_HOME_POS 0 +//#define MANUAL_Y_HOME_POS 0 +#define MANUAL_Z_HOME_POS DELTA_HEIGHT // Distance between the nozzle to printbed after homing + +// Use "Z Safe Homing" to avoid homing with a Z probe outside the bed area. +// +// With this feature enabled: +// +// - 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). +// - 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 axis (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). +#endif + +// Delta only homes to Z +#define HOMING_FEEDRATE_Z (200*60) + +//============================================================================= +//============================= Additional Features =========================== +//============================================================================= + +// @section extras + +// +// EEPROM +// +// The microcontroller can store settings in the EEPROM, e.g. max velocity... +// M500 - stores parameters in EEPROM +// M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily). +// M502 - reverts to the default "factory settings". You still need to store them in EEPROM afterwards if you want to. +// +//#define EEPROM_SETTINGS // Enable for M500 and M501 commands +//#define DISABLE_M503 // Saves ~2700 bytes of PROGMEM. Disable for release! +#define EEPROM_CHITCHAT // Give feedback on EEPROM commands. Disable to save PROGMEM. + +// +// Host Keepalive +// +// When enabled Marlin will send a busy status message to the host +// every couple of seconds when it can't accept commands. +// +#define HOST_KEEPALIVE_FEATURE // Disable this if your host doesn't like keepalive messages +#define DEFAULT_KEEPALIVE_INTERVAL 2 // Number of seconds between "busy" messages. Set with M113. +#define BUSY_WHILE_HEATING // Some hosts require "busy" messages even during heating + +// +// M100 Free Memory Watcher +// +//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose + +// +// G20/G21 Inch mode support +// +//#define INCH_MODE_SUPPORT + +// +// M149 Set temperature units support +// +//#define TEMPERATURE_UNITS_SUPPORT + +// @section temperature + +// Preheat Constants +#define PREHEAT_1_TEMP_HOTEND 180 +#define PREHEAT_1_TEMP_BED 70 +#define PREHEAT_1_FAN_SPEED 255 // Value from 0 to 255 + +#define PREHEAT_2_TEMP_HOTEND 240 +#define PREHEAT_2_TEMP_BED 100 +#define PREHEAT_2_FAN_SPEED 255 // Value from 0 to 255 + +/** + * Nozzle Park -- EXPERIMENTAL + * + * Park the nozzle at the given XYZ position on idle or G27. + * + * The "P" parameter controls the action applied to the Z axis: + * + * P0 (Default) If Z is below park Z raise the nozzle. + * P1 Raise the nozzle always to Z-park height. + * P2 Raise the nozzle by Z-park amount, limited to Z_MAX_POS. + */ +//#define NOZZLE_PARK_FEATURE + +#if ENABLED(NOZZLE_PARK_FEATURE) + // Specify a park position as { X, Y, Z } + #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 } +#endif + +/** + * Clean Nozzle Feature -- EXPERIMENTAL + * + * Adds the G12 command to perform a nozzle cleaning process. + * + * Parameters: + * P Pattern + * S Strokes / Repetitions + * T Triangles (P1 only) + * + * Patterns: + * P0 Straight line (default). This process requires a sponge type material + * at a fixed bed location. "S" specifies strokes (i.e. back-forth motions) + * between the start / end points. + * + * P1 Zig-zag pattern between (X0, Y0) and (X1, Y1), "T" specifies the + * number of zig-zag triangles to do. "S" defines the number of strokes. + * Zig-zags are done in whichever is the narrower dimension. + * For example, "G12 P1 S1 T3" will execute: + * + * -- + * | (X0, Y1) | /\ /\ /\ | (X1, Y1) + * | | / \ / \ / \ | + * A | | / \ / \ / \ | + * | | / \ / \ / \ | + * | (X0, Y0) | / \/ \/ \ | (X1, Y0) + * -- +--------------------------------+ + * |________|_________|_________| + * T1 T2 T3 + * + * P2 Circular pattern with middle at NOZZLE_CLEAN_CIRCLE_MIDDLE. + * "R" specifies the radius. "S" specifies the stroke count. + * Before starting, the nozzle moves to NOZZLE_CLEAN_START_POINT. + * + * Caveats: The ending Z should be the same as starting Z. + * Attention: EXPERIMENTAL. G-code arguments may change. + * + */ +//#define NOZZLE_CLEAN_FEATURE + +#if ENABLED(NOZZLE_CLEAN_FEATURE) + // Default number of pattern repetitions + #define NOZZLE_CLEAN_STROKES 12 + + // Default number of triangles + #define NOZZLE_CLEAN_TRIANGLES 3 + + // Specify positions as { X, Y, Z } + #define NOZZLE_CLEAN_START_POINT { 30, 30, (Z_MIN_POS + 1)} + #define NOZZLE_CLEAN_END_POINT {100, 60, (Z_MIN_POS + 1)} + + // Circular pattern radius + #define NOZZLE_CLEAN_CIRCLE_RADIUS 6.5 + // Circular pattern circle fragments number + #define NOZZLE_CLEAN_CIRCLE_FN 10 + // Middle point of circle + #define NOZZLE_CLEAN_CIRCLE_MIDDLE NOZZLE_CLEAN_START_POINT + + // Moves the nozzle to the initial position + #define NOZZLE_CLEAN_GOBACK +#endif + +/** + * Print Job Timer + * + * Automatically start and stop the print job timer on M104/M109/M190. + * + * M104 (hotend, no wait) - high temp = none, low temp = stop timer + * M109 (hotend, wait) - high temp = start timer, low temp = stop timer + * M190 (bed, wait) - high temp = start timer, low temp = none + * + * The timer can also be controlled with the following commands: + * + * M75 - Start the print job timer + * M76 - Pause the print job timer + * M77 - Stop the print job timer + */ +#define PRINTJOB_TIMER_AUTOSTART + +/** + * Print Counter + * + * Track statistical data such as: + * + * - Total print jobs + * - Total successful print jobs + * - Total failed print jobs + * - Total time printing + * + * View the current statistics with M78. + */ +//#define PRINTCOUNTER + +//============================================================================= +//============================= LCD and SD support ============================ +//============================================================================= + +// @section lcd + +/** + * LCD LANGUAGE + * + * Select the language to display on the LCD. These languages are available: + * + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, + * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * tr, uk, zh_CN, zh_TW, test + * + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + */ +#define LCD_LANGUAGE en + +/** + * LCD Character Set + * + * Note: This option is NOT applicable to Graphical Displays. + * + * All character-based LCDs provide ASCII plus one of these + * language extensions: + * + * - JAPANESE ... the most common + * - WESTERN ... with more accented characters + * - CYRILLIC ... for the Russian language + * + * To determine the language extension installed on your controller: + * + * - Compile and upload with LCD_LANGUAGE set to 'test' + * - 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 + * + * :['JAPANESE', 'WESTERN', 'CYRILLIC'] + */ +#define DISPLAY_CHARSET_HD44780 JAPANESE + +/** + * LCD TYPE + * + * Enable ULTRA_LCD for a 16x2, 16x4, 20x2, or 20x4 character-based LCD. + * Enable DOGLCD for a 128x64 (ST7565R) Full Graphical Display. + * (These options will be enabled automatically for most displays.) + * + * IMPORTANT: The U8glib library is required for Full Graphic Display! + * https://github.com/olikraus/U8glib_Arduino + */ +//#define ULTRA_LCD // Character based +//#define DOGLCD // Full graphics display + +/** + * SD CARD + * + * 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 + +/** + * SD CARD: SPI SPEED + * + * Enable one of the following items for a slower SPI transfer speed. + * This may be required to resolve "volume init" errors. + */ +//#define SPI_SPEED SPI_HALF_SPEED +//#define SPI_SPEED SPI_QUARTER_SPEED +//#define SPI_SPEED SPI_EIGHTH_SPEED + +/** + * SD CARD: ENABLE CRC + * + * Use CRC checks and retries on the SD communication. + */ +//#define SD_CHECK_AND_RETRY + +// +// ENCODER SETTINGS +// +// This option overrides the default number of encoder pulses needed to +// produce one step. Should be increased for high-resolution encoders. +// +//#define ENCODER_PULSES_PER_STEP 1 + +// +// Use this option to override the number of step signals required to +// move between next/prev menu items. +// +//#define ENCODER_STEPS_PER_MENU_ITEM 5 + +/** + * Encoder Direction Options + * + * Test your encoder's behavior first with both options disabled. + * + * Reversed Value Edit and Menu Nav? Enable REVERSE_ENCODER_DIRECTION. + * Reversed Menu Navigation only? Enable REVERSE_MENU_DIRECTION. + * Reversed Value Editing only? Enable BOTH options. + */ + +// +// This option reverses the encoder direction everywhere. +// +// Set this option if CLOCKWISE causes values to DECREASE +// +//#define REVERSE_ENCODER_DIRECTION + +// +// This option reverses the encoder direction for navigating LCD menus. +// +// If CLOCKWISE normally moves DOWN this makes it go UP. +// If CLOCKWISE normally moves UP this makes it go DOWN. +// +//#define REVERSE_MENU_DIRECTION + +// +// Individual Axis Homing +// +// Add individual axis homing items (Home X, Home Y, and Home Z) to the LCD menu. +// +//#define INDIVIDUAL_AXIS_HOMING_MENU + +// +// SPEAKER/BUZZER +// +// If you have a speaker that can produce tones, enable it here. +// By default Marlin assumes you have a buzzer with a fixed frequency. +// +//#define SPEAKER + +// +// The duration and frequency for the UI feedback sound. +// Set these to 0 to disable audio feedback in the LCD menus. +// +// Note: Test audio output with the G-Code: +// M300 S P +// +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 +//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 + +// +// CONTROLLER TYPE: Standard +// +// Marlin supports a wide variety of controllers. +// Enable one of the following options to specify your controller. +// + +// +// ULTIMAKER Controller. +// +//#define ULTIMAKERCONTROLLER + +// +// ULTIPANEL as seen on Thingiverse. +// +//#define ULTIPANEL + +// +// PanelOne from T3P3 (via RAMPS 1.4 AUX2/AUX3) +// http://reprap.org/wiki/PanelOne +// +//#define PANEL_ONE + +// +// MaKr3d Makr-Panel with graphic controller and SD support. +// http://reprap.org/wiki/MaKr3d_MaKrPanel +// +//#define MAKRPANEL + +// +// ReprapWorld Graphical LCD +// https://reprapworld.com/?products_details&products_id/1218 +// +//#define REPRAPWORLD_GRAPHICAL_LCD + +// +// Activate one of these if you have a Panucatt Devices +// Viki 2.0 or mini Viki with Graphic LCD +// http://panucatt.com +// +//#define VIKI2 +//#define miniVIKI + +// +// Adafruit ST7565 Full Graphic Controller. +// https://github.com/eboston/Adafruit-ST7565-Full-Graphic-Controller/ +// +//#define ELB_FULL_GRAPHIC_CONTROLLER + +// +// RepRapDiscount Smart Controller. +// http://reprap.org/wiki/RepRapDiscount_Smart_Controller +// +// Note: Usually sold with a white PCB. +// +//#define REPRAP_DISCOUNT_SMART_CONTROLLER + +// +// GADGETS3D G3D LCD/SD Controller +// http://reprap.org/wiki/RAMPS_1.3/1.4_GADGETS3D_Shield_with_Panel +// +// Note: Usually sold with a blue PCB. +// +//#define G3D_PANEL + +// +// RepRapDiscount FULL GRAPHIC Smart Controller +// http://reprap.org/wiki/RepRapDiscount_Full_Graphic_Smart_Controller +// +//#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER + +// +// MakerLab Mini Panel with graphic +// controller and SD support - http://reprap.org/wiki/Mini_panel +// +//#define MINIPANEL + +// +// RepRapWorld REPRAPWORLD_KEYPAD v1.1 +// http://reprapworld.com/?products_details&products_id=202&cPath=1591_1626 +// +// REPRAPWORLD_KEYPAD_MOVE_STEP sets how much should the robot move when a key +// is pressed, a value of 10.0 means 10mm per click. +// +//#define REPRAPWORLD_KEYPAD +//#define REPRAPWORLD_KEYPAD_MOVE_STEP 1.0 + +// +// RigidBot Panel V1.0 +// http://www.inventapart.com/ +// +//#define RIGIDBOT_PANEL + +// +// BQ LCD Smart Controller shipped by +// default with the BQ Hephestos 2 and Witbox 2. +// +//#define BQ_LCD_SMART_CONTROLLER + +// +// Cartesio UI +// http://mauk.cc/webshop/cartesio-shop/electronics/user-interface +// +//#define CARTESIO_UI + +// +// ANET_10 Controller supported displays. +// +//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. + // This LCD is known to be susceptible to electrical interference + // which scrambles the display. Pressing any button clears it up. +//#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 + // A clone of the RepRapDiscount full graphics display but with + // different pins/wiring (see pins_ANET_10.h). + +// +// LCD for Melzi Card with Graphical LCD +// +//#define LCD_FOR_MELZI + +// +// CONTROLLER TYPE: I2C +// +// Note: These controllers require the installation of Arduino's LiquidCrystal_I2C +// library. For more info: https://github.com/kiyoshigawa/LiquidCrystal_I2C +// + +// +// Elefu RA Board Control Panel +// http://www.elefu.com/index.php?route=product/product&product_id=53 +// +//#define RA_CONTROL_PANEL + +// +// Sainsmart YW Robot (LCM1602) LCD Display +// +// Note: This controller requires F.Malpartida's LiquidCrystal_I2C library +// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home +// +//#define LCD_I2C_SAINSMART_YWROBOT + +// +// Generic LCM1602 LCD adapter +// +//#define LCM1602 + +// +// PANELOLU2 LCD with status LEDs, +// separate encoder and click inputs. +// +// Note: This controller requires Arduino's LiquidTWI2 library v1.2.3 or later. +// For more info: https://github.com/lincomatic/LiquidTWI2 +// +// Note: The PANELOLU2 encoder click input can either be directly connected to +// a pin (if BTN_ENC defined to != -1) or read through I2C (when BTN_ENC == -1). +// +//#define LCD_I2C_PANELOLU2 + +// +// Panucatt VIKI LCD with status LEDs, +// integrated click & L/R/U/D buttons, separate encoder inputs. +// +//#define LCD_I2C_VIKI + +// +// SSD1306 OLED full graphics generic display +// +//#define U8GLIB_SSD1306 + +// +// SAV OLEd LCD module support using either SSD1306 or SH1106 based LCD modules +// +//#define SAV_3DGLCD +#if ENABLED(SAV_3DGLCD) + //#define U8GLIB_SSD1306 + #define U8GLIB_SH1106 +#endif + +// +// CONTROLLER TYPE: Shift register panels +// +// 2 wire Non-latching LCD SR from https://goo.gl/aJJ4sH +// LCD configuration: http://reprap.org/wiki/SAV_3D_LCD +// +//#define SAV_3DLCD + +// +// TinyBoy2 128x64 OLED / Encoder Panel +// +//#define OLED_PANEL_TINYBOY2 + +// +// Makeboard 3D Printer Parts 3D Printer Mini Display 1602 Mini Controller +// https://www.aliexpress.com/item/Micromake-Makeboard-3D-Printer-Parts-3D-Printer-Mini-Display-1602-Mini-Controller-Compatible-with-Ramps-1/32765887917.html +// +//#define MAKEBOARD_MINI_2_LINE_DISPLAY_1602 + +// +// MKS MINI12864 with graphic controller and SD support +// http://reprap.org/wiki/MKS_MINI_12864 +// +//#define MKS_MINI_12864 + +// +// Factory display for Creality CR-10 +// https://www.aliexpress.com/item/Universal-LCD-12864-3D-Printer-Display-Screen-With-Encoder-For-CR-10-CR-7-Model/32833148327.html +// +// This is RAMPS-compatible using a single 10-pin connector. +// (For CR-10 owners who want to replace the Melzi Creality board but retain the display) +// +//#define CR10_STOCKDISPLAY + +// +// MKS OLED 1.3" 128 × 64 FULL GRAPHICS CONTROLLER +// http://reprap.org/wiki/MKS_12864OLED +// +// Tiny, but very sharp OLED display +// +//#define MKS_12864OLED + +//============================================================================= +//=============================== Extra Features ============================== +//============================================================================= + +// @section extras + +// Increase the FAN PWM frequency. Removes the PWM noise but increases heating in the FET/Arduino +//#define FAST_PWM_FAN + +// Use software PWM to drive the fan, as for the heaters. This uses a very low frequency +// which is not as annoying as with the hardware PWM. On the other hand, if this frequency +// is too low, you should also increment SOFT_PWM_SCALE. +//#define FAN_SOFT_PWM + +// Incrementing this by 1 will double the software PWM frequency, +// affecting heaters, and the fan if FAN_SOFT_PWM is enabled. +// However, control resolution will be halved for each increment; +// at zero value, there are 128 effective control positions. +#define SOFT_PWM_SCALE 0 + +// If SOFT_PWM_SCALE is set to a value higher than 0, dithering can +// be used to mitigate the associated resolution loss. If enabled, +// some of the PWM cycles are stretched so on average the desired +// duty cycle is attained. +//#define SOFT_PWM_DITHER + +// Temperature status LEDs that display the hotend and bed temperature. +// If all hotends, bed temperature, and target temperature are under 54C +// then the BLUE led is on. Otherwise the RED led is on. (1C hysteresis) +//#define TEMP_STAT_LEDS + +// M240 Triggers a camera by emulating a Canon RC-1 Remote +// Data from: http://www.doc-diy.net/photo/rc-1_hacked/ +//#define PHOTOGRAPH_PIN 23 + +// 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 + +// Support for BlinkM/CyzRgb +//#define BLINKM + +// Support for PCA9632 PWM LED driver +//#define PCA9632 + +/** + * RGB LED / LED Strip Control + * + * Enable support for an RGB LED connected to 5V digital pins, or + * an RGB Strip connected to MOSFETs controlled by digital pins. + * + * 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 overall brightness parameters is also available + * + * *** CAUTION *** + * LED Strips require a MOFSET 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! + * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino + * cannot handle such current, separate 5V power supply must be used + * *** CAUTION *** + * + * LED type. This options are mutualy exclusive. Uncomment only one. + * + */ +//#define RGB_LED +//#define RGBW_LED + +#if ENABLED(RGB_LED) || ENABLED(RGBW_LED) + #define RGB_LED_R_PIN 34 + #define RGB_LED_G_PIN 43 + #define RGB_LED_B_PIN 35 + #define RGB_LED_W_PIN -1 +#endif + +// 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 (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) + #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip + #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time + #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + //#define NEOPIXEL_STARTUP_TEST // Cycle through colors at startup +#endif + +/** + * Printer Event LEDs + * + * During printing, the LEDs will reflect the printer status: + * + * - Gradually change from blue to violet as the heated bed gets to target temp + * - Gradually change from violet to red as the hotend gets to temperature + * - Change to white to illuminate work surface + * - Change to green once print has finished + * - Turn off after the print has finished and the user has pushed a button + */ +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) + #define PRINTER_EVENT_LEDS +#endif + +/*********************************************************************\ +* R/C SERVO support +* Sponsored by TrinityLabs, Reworked by codexmas +**********************************************************************/ + +// Number of servos +// +// If you select a configuration below, this will receive a default value and does not need to be set manually +// set it manually if you have more servos than extruders and wish to manually control some +// leaving it undefined or defining as 0 will disable the servo subsystem +// If unsure, leave commented / disabled +// +//#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command + +// Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. +// 300ms is a good value but you can try less delay. +// If the servo can't reach the requested position, increase it. +#define SERVO_DELAY { 300 } + +// Servo deactivation +// +// With this option servos are powered only during movement, then turned off to prevent jitter. +//#define DEACTIVATE_SERVOS_AFTER_MOVE + +/** + * Filament Width Sensor + * + * Measures the filament width in real-time and adjusts + * flow rate to compensate for any irregularities. + * + * Also allows the measured filament diameter to set the + * extrusion rate, so the slicer only has to specify the + * volume. + * + * Only a single extruder is supported at this time. + * + * 34 RAMPS_14 : Analog input 5 on the AUX2 connector + * 81 PRINTRBOARD : Analog input 2 on the Exp1 connector (version B,C,D,E) + * 301 RAMBO : Analog input 3 + * + * Note: May require analog pins to be defined for other boards. + */ +//#define FILAMENT_WIDTH_SENSOR + +#define DEFAULT_NOMINAL_FILAMENT_DIA 3.00 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. + +#if ENABLED(FILAMENT_WIDTH_SENSOR) + #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) + #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber + + #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading + #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading + #define MAX_MEASUREMENT_DELAY 20 // (bytes) Buffer size for stored measurements (1 byte per cm). Must be larger than MEASUREMENT_DELAY_CM. + + #define DEFAULT_MEASURED_FILAMENT_DIA DEFAULT_NOMINAL_FILAMENT_DIA // Set measured to nominal initially + + // Display filament width on the LCD status line. Status messages will expire after 5 seconds. + //#define FILAMENT_LCD_DISPLAY +#endif + +#endif // CONFIGURATION_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/delta/generic/Configuration_adv.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/delta/generic/Configuration_adv.h new file mode 100644 index 00000000..b7c896df --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/delta/generic/Configuration_adv.h @@ -0,0 +1,1426 @@ +/** + * 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 . + * + */ + +/** + * Configuration_adv.h + * + * Advanced settings. + * Only change these if you know exactly what you're doing. + * Some of these settings can damage your printer if improperly set! + * + * Basic settings can be found in Configuration.h + * + */ +#ifndef CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H_VERSION 010100 + +// @section temperature + +//=========================================================================== +//=============================Thermal Settings ============================ +//=========================================================================== + +#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 + #endif +#endif + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * The solution: Once the temperature reaches the target, start observing. + * If the temperature stays too far below the target (hysteresis) for too long (period), + * the firmware will halt the machine as a safety precaution. + * + * If you get false positives for "Thermal Runaway" increase THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD + */ +#if ENABLED(THERMAL_PROTECTION_HOTENDS) + #define THERMAL_PROTECTION_PERIOD 40 // Seconds + #define THERMAL_PROTECTION_HYSTERESIS 4 // Degrees Celsius + + /** + * Whenever an M104 or M109 increases the target temperature the firmware will wait for the + * WATCH_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get false positives for "Heating failed" increase WATCH_TEMP_PERIOD and/or decrease WATCH_TEMP_INCREASE + * WATCH_TEMP_INCREASE should not be below 2. + */ + #define WATCH_TEMP_PERIOD 20 // Seconds + #define WATCH_TEMP_INCREASE 2 // Degrees Celsius +#endif + +/** + * Thermal Protection parameters for the bed are just as above for hotends. + */ +#if ENABLED(THERMAL_PROTECTION_BED) + #define THERMAL_PROTECTION_BED_PERIOD 20 // Seconds + #define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius + + /** + * Whenever an M140 or M190 increases the target temperature the firmware will wait for the + * WATCH_BED_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_BED_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get too many "Heating failed" errors, increase WATCH_BED_TEMP_PERIOD and/or decrease + * WATCH_BED_TEMP_INCREASE. (WATCH_BED_TEMP_INCREASE should not be below 2.) + */ + #define WATCH_BED_TEMP_PERIOD 60 // Seconds + #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius +#endif + +#if ENABLED(PIDTEMP) + // this adds an experimental additional term to the heating power, proportional to the extrusion speed. + // if Kc is chosen well, the additional required power due to increased melting should be compensated. + //#define PID_EXTRUSION_SCALING + #if ENABLED(PID_EXTRUSION_SCALING) + #define DEFAULT_Kc (100) //heating power=Kc*(e_speed) + #define LPQ_MAX_LEN 50 + #endif +#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 + */ +#define AUTOTEMP +#if ENABLED(AUTOTEMP) + #define AUTOTEMP_OLDWEIGHT 0.98 +#endif + +// Show Temperature ADC value +// Enable for M105 to include ADC values read from temperature sensors. +//#define SHOW_TEMP_ADC_VALUES + +/** + * High Temperature Thermistor Support + * + * Thermistors able to support high temperature tend to have a hard time getting + * good readings at room and lower temperatures. This means HEATER_X_RAW_LO_TEMP + * will probably be caught when the heating element first turns on during the + * preheating process, which will trigger a min_temp_error as a safety measure + * and force stop everything. + * To circumvent this limitation, we allow for a preheat time (during which, + * min_temp_error won't be triggered) and add a min_temp buffer to handle + * aberrant readings. + * + * If you want to enable this feature for your hotend thermistor(s) + * uncomment and set values > 0 in the constants below + */ + +// The number of consecutive low temperature errors that can occur +// before a min_temp_error is triggered. (Shouldn't be more than 10.) +//#define MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED 0 + +// The number of milliseconds a hotend will preheat before starting to check +// the temperature. This value should NOT be set to the time it takes the +// hot end to reach the target temperature, but the time it takes to reach +// the minimum temperature your thermistor can read. The lower the better/safer. +// This shouldn't need to be more than 30 seconds (30000) +//#define MILLISECONDS_PREHEAT_TIME 0 + +// @section extruder + +// Extruder runout prevention. +// If the machine is idle and the temperature over MINTEMP +// then extrude some filament every couple of SECONDS. +//#define EXTRUDER_RUNOUT_PREVENT +#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_EXTRUDE 5 // mm +#endif + +// @section temperature + +//These defines help to calibrate the AD595 sensor in case you get wrong temperature measurements. +//The measured temperature is defined as "actualTemp = (measuredTemp * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET" +#define TEMP_SENSOR_AD595_OFFSET 0.0 +#define TEMP_SENSOR_AD595_GAIN 1.0 + +/** + * 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. + */ +//#define USE_CONTROLLER_FAN +#if ENABLED(USE_CONTROLLER_FAN) + //#define CONTROLLER_FAN_PIN FAN1_PIN // 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 +#endif + +// When first starting the main fan, run it at full speed for the +// given number of milliseconds. This gets the fan spinning reliably +// before setting a PWM value. (Does not work with software PWM for fan on Sanguinololu) +//#define FAN_KICKSTART_TIME 100 + +// This defines the minimal speed for the main fan, run in PWM mode +// to enable uncomment and set minimal PWM speed for reliable running (1-255) +// if fan speed is [1 - (FAN_MIN_PWM-1)] it is set to FAN_MIN_PWM +//#define FAN_MIN_PWM 50 + +// @section extruder + +/** + * Extruder cooling fans + * + * Extruder auto fans automatically turn on when their extruders' + * temperatures go above EXTRUDER_AUTO_FAN_TEMPERATURE. + * + * Your board's pins file specifies the recommended pins. Override those here + * or set to -1 to disable completely. + * + * Multiple extruders can be assigned to the same pin in which case + * the fan will turn on when any selected extruder is above the threshold. + */ +#define E0_AUTO_FAN_PIN -1 +#define E1_AUTO_FAN_PIN -1 +#define E2_AUTO_FAN_PIN -1 +#define E3_AUTO_FAN_PIN -1 +#define E4_AUTO_FAN_PIN -1 +#define EXTRUDER_AUTO_FAN_TEMPERATURE 50 +#define EXTRUDER_AUTO_FAN_SPEED 255 // == full speed + +/** + * Part-Cooling Fan Multiplexer + * + * This feature allows you to digitally multiplex the fan output. + * The multiplexer is automatically switched at tool-change. + * Set FANMUX[012]_PINs below for up to 2, 4, or 8 multiplexed fans. + */ +#define FANMUX0_PIN -1 +#define FANMUX1_PIN -1 +#define FANMUX2_PIN -1 + +/** + * M355 Case Light on-off / brightness + */ +//#define CASE_LIGHT_ENABLE +#if ENABLED(CASE_LIGHT_ENABLE) + //#define CASE_LIGHT_PIN 4 // Override the default pin if needed + #define INVERT_CASE_LIGHT false // Set true if Case Light is ON when pin is LOW + #define CASE_LIGHT_DEFAULT_ON true // Set default power-up state on + #define CASE_LIGHT_DEFAULT_BRIGHTNESS 105 // Set default power-up brightness (0-255, requires PWM pin) + //#define MENU_ITEM_CASE_LIGHT // Add a Case Light option to the LCD main menu +#endif + +//=========================================================================== +//============================ Mechanical Settings ========================== +//=========================================================================== + +// @section homing + +// If you want endstops to stay on (by default) even when not homing +// enable this option. Override at any time with M120, M121. +//#define ENDSTOPS_ALWAYS_ON_DEFAULT + +// @section extras + +//#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. + +// Dual X Steppers +// Uncomment this option to drive two X axis motors. +// The next unused E driver will be assigned to the second X stepper. +//#define X_DUAL_STEPPER_DRIVERS +#if ENABLED(X_DUAL_STEPPER_DRIVERS) + // Set true if the two X motors need to rotate in opposite directions + #define INVERT_X2_VS_X_DIR true +#endif + +// Dual Y Steppers +// Uncomment this option to drive two Y axis motors. +// The next unused E driver will be assigned to the second Y stepper. +//#define Y_DUAL_STEPPER_DRIVERS +#if ENABLED(Y_DUAL_STEPPER_DRIVERS) + // Set true if the two Y motors need to rotate in opposite directions + #define INVERT_Y2_VS_Y_DIR true +#endif + +// A single Z stepper driver is usually used to drive 2 stepper motors. +// Uncomment this option to use a separate stepper driver for each Z axis motor. +// The next unused E driver will be assigned to the second Z stepper. +//#define Z_DUAL_STEPPER_DRIVERS + +#if ENABLED(Z_DUAL_STEPPER_DRIVERS) + + // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper. + // That way the machine is capable to align the bed during home, since both Z steppers are homed. + // There is also an implementation of M666 (software endstops adjustment) to this feature. + // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed. + // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2. + // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive. + // Play a little bit with small adjustments (0.5mm) and check the behaviour. + // The M119 (endstops report) will start reporting the Z2 Endstop as well. + + //#define Z_DUAL_ENDSTOPS + + #if ENABLED(Z_DUAL_ENDSTOPS) + #define Z2_USE_ENDSTOP _XMAX_ + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 // Use M666 to determine/test this value + #endif + +#endif // Z_DUAL_STEPPER_DRIVERS + +// Enable this for dual x-carriage printers. +// A dual x-carriage design has the advantage that the inactive extruder can be parked which +// prevents hot-end ooze contaminating the print. It also reduces the weight of each x-carriage +// allowing faster printing speeds. Connect your X2 stepper to the first unused E plug. +//#define DUAL_X_CARRIAGE +#if ENABLED(DUAL_X_CARRIAGE) + // Configuration for second X-carriage + // Note: the first x-carriage is defined as the x-carriage which homes to the minimum endstop; + // the second x-carriage always homes to the maximum endstop. + #define X2_MIN_POS 80 // set minimum to ensure second x-carriage doesn't hit the parked first X-carriage + #define X2_MAX_POS 353 // set maximum to the distance between toolheads when both heads are homed + #define X2_HOME_DIR 1 // the second X-carriage always homes to the maximum endstop position + #define X2_HOME_POS X2_MAX_POS // default home position is the maximum carriage position + // However: In this mode the HOTEND_OFFSET_X value for the second extruder provides a software + // override for X2_HOME_POS. This also allow recalibration of the distance between the two endstops + // without modifying the firmware (through the "M218 T1 X???" command). + // Remember: you should set the second extruder x-offset to 0 in your slicer. + + // There are a few selectable movement modes for dual x-carriages using M605 S + // Mode 0 (DXC_FULL_CONTROL_MODE): Full control. The slicer has full control over both x-carriages and can achieve optimal travel results + // as long as it supports dual x-carriages. (M605 S0) + // Mode 1 (DXC_AUTO_PARK_MODE) : Auto-park mode. The firmware will automatically park and unpark the x-carriages on tool changes so + // that additional slicer support is not required. (M605 S1) + // Mode 2 (DXC_DUPLICATION_MODE) : Duplication mode. The firmware will transparently make the second x-carriage and extruder copy all + // actions of the first x-carriage. This allows the printer to print 2 arbitrary items at + // once. (2nd extruder x offset and temp offset are set using: M605 S2 [Xnnn] [Rmmm]) + + // This is the default power-up mode which can be later using M605. + #define DEFAULT_DUAL_X_CARRIAGE_MODE DXC_FULL_CONTROL_MODE + + // Default settings in "Auto-park Mode" + #define TOOLCHANGE_PARK_ZLIFT 0.2 // the distance to raise Z axis when parking an extruder + #define TOOLCHANGE_UNPARK_ZLIFT 1 // the distance to raise Z axis when unparking an extruder + + // Default x offset in duplication mode (typically set to half print bed width) + #define DEFAULT_DUPLICATION_X_OFFSET 100 + +#endif // DUAL_X_CARRIAGE + +// 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. +//#define EXT_SOLENOID + +// @section homing + +//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +#define X_HOME_BUMP_MM 5 +#define Y_HOME_BUMP_MM 5 +#define Z_HOME_BUMP_MM 5 // deltas need the same for all three axes +#define HOMING_BUMP_DIVISOR {10, 10, 10} // Re-Bump Speed Divisor (Divides the Homing Feedrate) +//#define QUICK_HOME //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially. + +// When G28 is called, this option will make Y home before X +//#define HOME_Y_BEFORE_X + +// @section machine + +#define AXIS_RELATIVE_MODES {false, false, false, false} + +// Allow duplication mode with a basic dual-nozzle extruder +//#define DUAL_NOZZLE_DUPLICATION_MODE + +// By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step. +#define INVERT_X_STEP_PIN false +#define INVERT_Y_STEP_PIN false +#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. +#define DEFAULT_STEPPER_DEACTIVE_TIME 60 +#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_E true + +#define DEFAULT_MINIMUMFEEDRATE 0.0 // minimum feedrate +#define DEFAULT_MINTRAVELFEEDRATE 0.0 + +//#define HOME_AFTER_DEACTIVATE // Require rehoming after steppers are deactivated + +// @section lcd + +#if ENABLED(ULTIPANEL) + #define MANUAL_FEEDRATE_XYZ 50*60 + #define MANUAL_FEEDRATE { MANUAL_FEEDRATE_XYZ, MANUAL_FEEDRATE_XYZ, MANUAL_FEEDRATE_XYZ, 60 } // Feedrates for manual moves along X, Y, Z, E from panel + #define ULTIPANEL_FEEDMULTIPLY // Comment to disable setting feedrate multiplier via encoder +#endif + +// @section extras + +// minimum time in microseconds that a movement needs to take if the buffer is emptied. +#define DEFAULT_MINSEGMENTTIME 20000 + +// If defined the movements slow down when the look ahead buffer is only half full +// (don't use SLOWDOWN with DELTA because DELTA generates hundreds of segments per second) +//#define SLOWDOWN + +// Frequency limit +// See nophead's blog for more info +// Not working O +//#define XY_FREQUENCY_LIMIT 15 + +// 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 +// if unwanted behavior is observed on a user's machine when running at very slow speeds. +#define MINIMUM_PLANNER_SPEED 0.05 // (mm/sec) + +// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU. +#define MICROSTEP_MODES {16,16,16,16,16} // [1,2,4,8,16] + +/** + * @section stepper motor current + * + * Some boards have a means of setting the stepper motor current via firmware. + * + * The power on motor currents are set by: + * PWM_MOTOR_CURRENT - used by MINIRAMBO & ULTIMAIN_2 + * known compatible chips: A4982 + * DIGIPOT_MOTOR_CURRENT - used by BQ_ZUM_MEGA_3D, RAMBO & SCOOVO_X9H + * known compatible chips: AD5206 + * DAC_MOTOR_CURRENT_DEFAULT - used by PRINTRBOARD_REVF & RIGIDBOARD_V2 + * known compatible chips: MCP4728 + * DIGIPOT_I2C_MOTOR_CURRENTS - used by 5DPRINT, AZTEEG_X3_PRO, MIGHTYBOARD_REVE + * known compatible chips: MCP4451, MCP4018 + * + * Motor currents can also be set by M907 - M910 and by the LCD. + * M907 - applies to all. + * M908 - BQ_ZUM_MEGA_3D, RAMBO, PRINTRBOARD_REVF, RIGIDBOARD_V2 & SCOOVO_X9H + * M909, M910 & LCD - only PRINTRBOARD_REVF & RIGIDBOARD_V2 + */ +//#define PWM_MOTOR_CURRENT { 1300, 1300, 1250 } // Values in milliamps +//#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 + +// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +//#define DIGIPOT_I2C +//#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster +#define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 +// Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS +#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=========================== +//=========================================================================== + +#define ENCODER_RATE_MULTIPLIER // If defined, certain menu edit operations automatically multiply the steps when the encoder is moved quickly +#define ENCODER_10X_STEPS_PER_SEC 75 // If the encoder steps per sec exceeds this value, multiply steps moved x10 to quickly advance the value +#define ENCODER_100X_STEPS_PER_SEC 160 // If the encoder steps per sec exceeds this value, multiply steps moved x100 to really quickly advance the value + +//#define CHDK 4 //Pin for triggering CHDK to take a picture see how to use it here http://captain-slow.dk/2014/03/09/3d-printing-timelapses/ +#define CHDK_DELAY 50 //How long in ms the pin should stay HIGH before going LOW again + +// @section lcd + +// Include a page of printer information in the LCD Main Menu +//#define LCD_INFO_MENU + +// Scroll a longer status message into view +//#define STATUS_MESSAGE_SCROLLING + +// On the Info Screen, display XY with one decimal place when possible +//#define LCD_DECIMAL_SMALL_XY + +// The timeout (in ms) to return to the status screen from sub-menus +//#define LCD_TIMEOUT_TO_STATUS 15000 + +#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 + + #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? + #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. + + #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. + // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. + // using: + //#define MENU_ADDAUTOSTART + + /** + * Sort SD file listings in alphabetical order. + * + * With this option enabled, items on SD cards will be sorted + * by name for easier navigation. + * + * By default... + * + * - Use the slowest -but safest- method for sorting. + * - Folders are sorted to the top. + * - The sort key is statically allocated. + * - No added G-code (M34) support. + * - 40 item sorting limit. (Items after the first 40 are unsorted.) + * + * SD sorting uses static allocation (as set by SDSORT_LIMIT), allowing the + * compiler to calculate the worst-case usage and throw an error if the SRAM + * limit is exceeded. + * + * - SDSORT_USES_RAM provides faster sorting via a static directory buffer. + * - SDSORT_USES_STACK does the same, but uses a local stack-based buffer. + * - SDSORT_CACHE_NAMES will retain the sorted file listing in RAM. (Expensive!) + * - SDSORT_DYNAMIC_RAM only uses RAM when the SD menu is visible. (Use with caution!) + */ + //#define SDCARD_SORT_ALPHA + + // SD Card Sorting options + #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_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. + #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #endif + + // Show a progress bar on HD44780 LCDs for SD printing + //#define LCD_PROGRESS_BAR + + #if ENABLED(LCD_PROGRESS_BAR) + // Amount of time (ms) to show the bar + #define PROGRESS_BAR_BAR_TIME 2000 + // Amount of time (ms) to show the status message + #define PROGRESS_BAR_MSG_TIME 3000 + // Amount of time (ms) to retain the status message (0=forever) + #define PROGRESS_MSG_EXPIRE 0 + // Enable this to show messages for MSG_TIME then hide them + //#define PROGRESS_MSG_ONCE + // Add a menu item to test the progress bar: + //#define LCD_PROGRESS_BAR_TEST + #endif + + // This allows hosts to request long names for files and folders with M33 + //#define LONG_FILENAME_HOST_SUPPORT + + // This option allows you to abort SD printing when any endstop is triggered. + // This feature must be enabled with "M540 S1" or from the LCD menu. + // To have any effect, endstops must be enabled during SD printing. + //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + +#endif // SDSUPPORT + +/** + * Additional options for Graphical Displays + * + * Use the optimizations here to improve printing performance, + * which can be adversely affected by graphical display drawing, + * especially when doing several short moves, and when printing + * on DELTA and SCARA machines. + * + * Some of these options may result in the display lagging behind + * controller events, as there is a trade-off between reliable + * printing performance versus fast display updates. + */ +#if ENABLED(DOGLCD) + // Enable to save many cycles by drawing a hollow frame on the Info Screen + #define XYZ_HOLLOW_FRAME + + // Enable to save many cycles by drawing a hollow frame on Menu Screens + #define MENU_HOLLOW_FRAME + + // A bigger font is available for edit items. Costs 3120 bytes of PROGMEM. + // 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. + // 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 +#endif // DOGLCD + +// @section safety + +// The hardware watchdog should reset the microcontroller disabling all outputs, +// in case the firmware gets stuck and doesn't do temperature regulation. +#define USE_WATCHDOG + +#if ENABLED(USE_WATCHDOG) + // If you have a watchdog reboot in an ArduinoMega2560 then the device will hang forever, as a watchdog reset will leave the watchdog on. + // The "WATCHDOG_RESET_MANUAL" goes around this by not using the hardware reset. + // However, THIS FEATURE IS UNSAFE!, as it will only work if interrupts are disabled. And the code could hang in an interrupt routine with interrupts disabled. + //#define WATCHDOG_RESET_MANUAL +#endif + +// @section lcd + +/** + * Babystepping enables movement of the axes by tiny increments without changing + * the current position values. This feature is used primarily to adjust the Z + * axis in the first layer of a print in real-time. + * + * Warning: Does not respect endstops! + */ +//#define BABYSTEPPING +#if ENABLED(BABYSTEPPING) + //#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 100 // Babysteps are very small. Increase for faster motion. + //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping + //#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen 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_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor + //#define BABYSTEP_ZPROBE_GFX_REVERSE // Reverses the direction of the CW/CCW indicators +#endif + +// @section extruder + +/** + * Implementation of linear pressure control + * + * Assumption: advance = k * (delta velocity) + * K=0 means advance disabled. + * See Marlin documentation for calibration instructions. + */ +//#define LIN_ADVANCE + +#if ENABLED(LIN_ADVANCE) + #define LIN_ADVANCE_K 75 + + /** + * Some Slicers produce Gcode with randomly jumping extrusion widths occasionally. + * For example within a 0.4mm perimeter it may produce a single segment of 0.05mm width. + * While this is harmless for normal printing (the fluid nature of the filament will + * close this very, very tiny gap), it throws off the LIN_ADVANCE pressure adaption. + * + * For this case LIN_ADVANCE_E_D_RATIO can be used to set the extrusion:distance ratio + * to a fixed value. Note that using a fixed ratio will lead to wrong nozzle pressures + * if the slicer is using variable widths or layer heights within one print! + * + * This option sets the default E:D ratio at startup. Use `M900` to override this value. + * + * Example: `M900 W0.4 H0.2 D1.75`, where: + * - W is the extrusion width in mm + * - H is the layer height in mm + * - D is the filament diameter in mm + * + * Example: `M900 R0.0458` to set the ratio directly. + * + * Set to 0 to auto-detect the ratio based on given Gcode G1 print moves. + * + * Slic3r (including Průša Control) produces Gcode compatible with the automatic mode. + * Cura (as of this writing) may produce Gcode incompatible with the automatic mode. + */ + #define LIN_ADVANCE_E_D_RATIO 0 // The calculated ratio (or 0) according to the formula W * H / ((D / 2) ^ 2 * PI) + // Example: 0.4 * 0.2 / ((1.75 / 2) ^ 2 * PI) = 0.033260135 +#endif + +// @section leveling + +// Default mesh area is an area with an inset margin on the print area. +// Below are the macros that are used to define the borders for the mesh area, +// made available here for specialized needs, ie dual extruder setup. +#if ENABLED(MESH_BED_LEVELING) + #define MESH_MIN_X MESH_INSET + #define MESH_MAX_X (X_BED_SIZE - (MESH_INSET)) + #define MESH_MIN_Y MESH_INSET + #define MESH_MAX_Y (Y_BED_SIZE - (MESH_INSET)) +#elif ENABLED(AUTO_BED_LEVELING_UBL) + #define UBL_MESH_MIN_X UBL_MESH_INSET + #define UBL_MESH_MAX_X (X_BED_SIZE - (UBL_MESH_INSET)) + #define UBL_MESH_MIN_Y UBL_MESH_INSET + #define UBL_MESH_MAX_Y (Y_BED_SIZE - (UBL_MESH_INSET)) + + // If this is defined, the currently active mesh will be saved in the + // current slot on M500. + #define UBL_SAVE_ACTIVE_ON_M500 +#endif + +// @section extras + +// +// G2/G3 Arc Support +// +#define ARC_SUPPORT // Disable this feature to save ~3226 bytes +#if ENABLED(ARC_SUPPORT) + #define MM_PER_ARC_SEGMENT 1 // Length of each arc segment + #define N_ARC_CORRECTION 25 // Number of intertpolated 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 +#endif + +// Support for G5 with XYZE destination and IJPQ offsets. Requires ~2666 bytes. +//#define BEZIER_CURVE_SUPPORT + +// G38.2 and G38.3 Probe Target +// Enable PROBE_DOUBLE_TOUCH if you want G38 to double touch +//#define G38_PROBE_TARGET +#if ENABLED(G38_PROBE_TARGET) + #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) +#endif + +// Moves (or segments) with fewer steps than this will be joined with the next move +#define MIN_STEPS_PER_SEGMENT 6 + +// The minimum pulse width (in µs) for stepping a stepper. +// Set this if you find stepping unreliable, or if using a very fast CPU. +#define MINIMUM_STEPPER_PULSE 0 // (µs) The smallest stepper pulse allowed + +// @section temperature + +// Control heater 0 and heater 1 in parallel. +//#define HEATERS_PARALLEL + +//=========================================================================== +//================================= Buffers ================================= +//=========================================================================== + +// @section hidden + +// 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, i.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 +#else + #define BLOCK_BUFFER_SIZE 16 // maximize block buffer +#endif + +// @section serial + +// The ASCII buffer for serial input +#define MAX_CMD_SIZE 96 +#define BUFSIZE 4 + +// Transmission to Host Buffer Size +// To save 386 bytes of PROGMEM (and TX_BUFFER_SIZE+3 bytes of RAM) set to 0. +// To buffer a simple "ok" you need 4 bytes. +// For ADVANCED_OK (M105) you need 32 bytes. +// For debug-echo: 128 bytes for the optimal speed. +// Other output doesn't need to be that speedy. +// :[0, 2, 4, 8, 16, 32, 64, 128, 256] +#define TX_BUFFER_SIZE 0 + +// Host Receive Buffer Size +// Without XON/XOFF flow control (see SERIAL_XON_XOFF below) 32 bytes should be enough. +// To use flow control, set this buffer size to at least 1024 bytes. +// :[0, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048] +//#define RX_BUFFER_SIZE 1024 + +#if RX_BUFFER_SIZE >= 1024 + // Enable to have the controller send XON/XOFF control characters to + // the host to signal the RX buffer is becoming full. + //#define SERIAL_XON_XOFF +#endif + +#if ENABLED(SDSUPPORT) + // Enable this option to collect and display the maximum + // RX queue usage after transferring a file to SD. + //#define SERIAL_STATS_MAX_RX_QUEUED + + // Enable this option to collect and display the number + // of dropped bytes after a file transfer to SD. + //#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! +//#define EMERGENCY_PARSER + +// Bad Serial-connections can miss a received command by sending an 'ok' +// Therefore some clients abort after 30 seconds in a timeout. +// Some other clients start sending commands while receiving a 'wait'. +// This "wait" is only sent when the buffer is empty. 1 second is a good value here. +//#define NO_TIMEOUTS 1000 // Milliseconds + +// Some clients will have this feature soon. This could make the NO_TIMEOUTS unnecessary. +//#define ADVANCED_OK + +// @section extras + +/** + * Firmware-based and LCD-controlled retract + * + * Add G10 / G11 commands for automatic firmware-based retract / recover. + * Use M207 and M208 to define parameters for retract / recover. + * + * Use M209 to enable or disable auto-retract. + * With auto-retract enabled, all G1 E moves within the set range + * will be converted to firmware-based retract/recover moves. + * + * Be sure to turn off auto-retract during filament change. + * + * Note that M207 / M208 / M209 settings are saved to EEPROM. + * + */ +//#define FWRETRACT // ONLY PARTIALLY TESTED +#if ENABLED(FWRETRACT) + #define MIN_AUTORETRACT 0.1 // When auto-retract is on, convert E moves of this length and over + #define MAX_AUTORETRACT 10.0 // Upper limit for auto-retract conversion + #define RETRACT_LENGTH 3 // Default retract length (positive mm) + #define RETRACT_LENGTH_SWAP 13 // Default swap retract length (positive mm), for extruder change + #define RETRACT_FEEDRATE 45 // Default feedrate for retracting (mm/s) + #define RETRACT_ZLIFT 0 // Default retract Z-lift + #define RETRACT_RECOVER_LENGTH 0 // Default additional recover length (mm, added to retract length when recovering) + #define RETRACT_RECOVER_LENGTH_SWAP 0 // Default additional swap recover length (mm, added to retract length when recovering from extruder change) + #define RETRACT_RECOVER_FEEDRATE 8 // Default feedrate for recovering from retraction (mm/s) + #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) +#endif + +/** + * Advanced Pause + * Experimental feature for filament change support and for parking the nozzle when paused. + * Adds the GCode M600 for initiating filament change. + * If PARK_HEAD_ON_PAUSE enabled, adds the GCode M125 to pause printing and park the nozzle. + * + * Requires an LCD display. + * This feature is required for the default FILAMENT_RUNOUT_SCRIPT. + */ +//#define ADVANCED_PAUSE_FEATURE +#if ENABLED(ADVANCED_PAUSE_FEATURE) + #define PAUSE_PARK_X_POS 3 // X position of hotend + #define PAUSE_PARK_Y_POS 3 // Y position of hotend + #define PAUSE_PARK_Z_ADD 10 // Z addition of hotend (lift) + #define PAUSE_PARK_XY_FEEDRATE 100 // X and Y axes feedrate in mm/s (also used for delta printers Z axis) + #define PAUSE_PARK_Z_FEEDRATE 5 // Z axis feedrate in mm/s (not used for delta printers) + #define PAUSE_PARK_RETRACT_FEEDRATE 60 // Initial retract feedrate in mm/s + #define PAUSE_PARK_RETRACT_LENGTH 2 // Initial retract in mm + // It is a short retract used immediately after print interrupt before move to filament exchange position + #define FILAMENT_CHANGE_UNLOAD_FEEDRATE 10 // Unload filament feedrate in mm/s - filament unloading can be fast + #define FILAMENT_CHANGE_UNLOAD_LENGTH 100 // Unload filament length from hotend in mm + // Longer length for bowden printers to unload filament from whole bowden tube, + // shorter length for printers without bowden to unload filament from extruder only, + // 0 to disable unloading for manual unloading + #define FILAMENT_CHANGE_LOAD_FEEDRATE 6 // Load filament feedrate in mm/s - filament loading into the bowden tube can be fast + #define FILAMENT_CHANGE_LOAD_LENGTH 0 // Load filament length over hotend in mm + // Longer length for bowden printers to fast load filament into whole bowden tube over the hotend, + // Short or zero length for printers without bowden where loading is not used + #define ADVANCED_PAUSE_EXTRUDE_FEEDRATE 3 // Extrude filament feedrate in mm/s - must be slower than load feedrate + #define ADVANCED_PAUSE_EXTRUDE_LENGTH 50 // Extrude filament length in mm after filament is loaded over the hotend, + // 0 to disable for manual extrusion + // Filament can be extruded repeatedly from the filament exchange menu to fill the hotend, + // or until outcoming filament color is not clear for filament color change + #define PAUSE_PARK_NOZZLE_TIMEOUT 45 // Turn off nozzle if user doesn't change filament within this time limit in seconds + #define FILAMENT_CHANGE_NUMBER_OF_ALERT_BEEPS 5 // Number of alert beeps before printer goes quiet + #define PAUSE_PARK_NO_STEPPER_TIMEOUT // Enable to have stepper motors hold position during filament change + // even if it takes longer than DEFAULT_STEPPER_DEACTIVE_TIME. + //#define PARK_HEAD_ON_PAUSE // Go to filament change position on pause, return to print position on resume + //#define HOME_BEFORE_FILAMENT_CHANGE // Ensure homing has been completed prior to parking for filament change +#endif + +// @section tmc + +/** + * Enable this section if you have TMC26X motor drivers. + * You will need to import the TMC26XStepper library into the Arduino IDE for this + * (https://github.com/trinamic/TMC26XStepper.git) + */ +//#define HAVE_TMCDRIVER + +#if ENABLED(HAVE_TMCDRIVER) + + //#define X_IS_TMC + //#define X2_IS_TMC + //#define Y_IS_TMC + //#define Y2_IS_TMC + //#define Z_IS_TMC + //#define Z2_IS_TMC + //#define E0_IS_TMC + //#define E1_IS_TMC + //#define E2_IS_TMC + //#define E3_IS_TMC + //#define E4_IS_TMC + + #define X_MAX_CURRENT 1000 // in mA + #define X_SENSE_RESISTOR 91 // in mOhms + #define X_MICROSTEPS 16 // number of microsteps + + #define X2_MAX_CURRENT 1000 + #define X2_SENSE_RESISTOR 91 + #define X2_MICROSTEPS 16 + + #define Y_MAX_CURRENT 1000 + #define Y_SENSE_RESISTOR 91 + #define Y_MICROSTEPS 16 + + #define Y2_MAX_CURRENT 1000 + #define Y2_SENSE_RESISTOR 91 + #define Y2_MICROSTEPS 16 + + #define Z_MAX_CURRENT 1000 + #define Z_SENSE_RESISTOR 91 + #define Z_MICROSTEPS 16 + + #define Z2_MAX_CURRENT 1000 + #define Z2_SENSE_RESISTOR 91 + #define Z2_MICROSTEPS 16 + + #define E0_MAX_CURRENT 1000 + #define E0_SENSE_RESISTOR 91 + #define E0_MICROSTEPS 16 + + #define E1_MAX_CURRENT 1000 + #define E1_SENSE_RESISTOR 91 + #define E1_MICROSTEPS 16 + + #define E2_MAX_CURRENT 1000 + #define E2_SENSE_RESISTOR 91 + #define E2_MICROSTEPS 16 + + #define E3_MAX_CURRENT 1000 + #define E3_SENSE_RESISTOR 91 + #define E3_MICROSTEPS 16 + + #define E4_MAX_CURRENT 1000 + #define E4_SENSE_RESISTOR 91 + #define E4_MICROSTEPS 16 + +#endif + +// @section TMC2130 + +/** + * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. + * + * You'll also need the TMC2130Stepper Arduino library + * (https://github.com/teemuatlut/TMC2130Stepper). + * + * To use TMC2130 stepper drivers in SPI mode connect your SPI2130 pins to + * the hardware SPI interface on your board and define the required CS pins + * in your `pins_MYBOARD.h` file. (e.g., RAMPS 1.4 uses AUX3 pins `X_CS_PIN 53`, `Y_CS_PIN 49`, etc.). + */ +//#define HAVE_TMC2130 + +#if ENABLED(HAVE_TMC2130) + + // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY + //#define X_IS_TMC2130 + //#define X2_IS_TMC2130 + //#define Y_IS_TMC2130 + //#define Y2_IS_TMC2130 + //#define Z_IS_TMC2130 + //#define Z2_IS_TMC2130 + //#define E0_IS_TMC2130 + //#define E1_IS_TMC2130 + //#define E2_IS_TMC2130 + //#define E3_IS_TMC2130 + //#define E4_IS_TMC2130 + + /** + * Stepper driver settings + */ + + #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 + #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current + #define INTERPOLATE 1 // Interpolate X/Y/Z_MICROSTEPS to 256 + + #define X_CURRENT 1000 // rms current in mA. Multiply by 1.41 for peak current. + #define X_MICROSTEPS 16 // 0..256 + + #define Y_CURRENT 1000 + #define Y_MICROSTEPS 16 + + #define Z_CURRENT 1000 + #define Z_MICROSTEPS 16 + + //#define X2_CURRENT 1000 + //#define X2_MICROSTEPS 16 + + //#define Y2_CURRENT 1000 + //#define Y2_MICROSTEPS 16 + + //#define Z2_CURRENT 1000 + //#define Z2_MICROSTEPS 16 + + //#define E0_CURRENT 1000 + //#define E0_MICROSTEPS 16 + + //#define E1_CURRENT 1000 + //#define E1_MICROSTEPS 16 + + //#define E2_CURRENT 1000 + //#define E2_MICROSTEPS 16 + + //#define E3_CURRENT 1000 + //#define E3_MICROSTEPS 16 + + //#define E4_CURRENT 1000 + //#define E4_MICROSTEPS 16 + + /** + * Use Trinamic's ultra quiet stepping mode. + * When disabled, Marlin will use spreadCycle stepping mode. + */ + #define STEALTHCHOP + + /** + * Let Marlin automatically control stepper current. + * This is still an experimental feature. + * Increase current every 5s by CURRENT_STEP until stepper temperature prewarn gets triggered, + * then decrease current by CURRENT_STEP until temperature prewarn is cleared. + * Adjusting starts from X/Y/Z/E_CURRENT but will not increase over AUTO_ADJUST_MAX + * 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. + * M906 S1 - Start adjusting current + * M906 S0 - Stop adjusting current + * M911 - Report stepper driver overtemperature pre-warn condition. + * M912 - Clear stepper driver overtemperature pre-warn condition flag. + */ + //#define AUTOMATIC_CURRENT_CONTROL + + #if ENABLED(AUTOMATIC_CURRENT_CONTROL) + #define CURRENT_STEP 50 // [mA] + #define AUTO_ADJUST_MAX 1300 // [mA], 1300mA_rms = 1840mA_peak + #define REPORT_CURRENT_CHANGE + #endif + + /** + * The driver will switch to spreadCycle when stepper speed is over HYBRID_THRESHOLD. + * This mode allows for faster movements at the expense of higher noise levels. + * STEALTHCHOP needs to be enabled. + * M913 X/Y/Z/E to live tune the setting + */ + //#define HYBRID_THRESHOLD + + #define X_HYBRID_THRESHOLD 100 // [mm/s] + #define X2_HYBRID_THRESHOLD 100 + #define Y_HYBRID_THRESHOLD 100 + #define Y2_HYBRID_THRESHOLD 100 + #define Z_HYBRID_THRESHOLD 4 + #define Z2_HYBRID_THRESHOLD 4 + #define E0_HYBRID_THRESHOLD 30 + #define E1_HYBRID_THRESHOLD 30 + #define E2_HYBRID_THRESHOLD 30 + #define E3_HYBRID_THRESHOLD 30 + #define E4_HYBRID_THRESHOLD 30 + + /** + * Use stallGuard2 to sense an obstacle and trigger an endstop. + * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. + * If used along with STEALTHCHOP, the movement will be louder when homing. This is normal. + * + * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. + * Higher values make the system LESS sensitive. + * Lower value make the system MORE sensitive. + * Too low values can lead to false positives, while too high values will collide the axis without triggering. + * It is advised to set X/Y_HOME_BUMP_MM to 0. + * M914 X/Y to live tune the setting + */ + //#define SENSORLESS_HOMING + + #if ENABLED(SENSORLESS_HOMING) + #define X_HOMING_SENSITIVITY 19 + #define Y_HOMING_SENSITIVITY 19 + #endif + + /** + * You can set your own advanced settings by filling in predefined functions. + * A list of available functions can be found on the library github page + * https://github.com/teemuatlut/TMC2130Stepper + * + * Example: + * #define TMC2130_ADV() { \ + * stepperX.diag0_temp_prewarn(1); \ + * stepperX.interpolate(0); \ + * } + */ + #define TMC2130_ADV() { } + +#endif // HAVE_TMC2130 + +// @section L6470 + +/** + * Enable this section if you have L6470 motor drivers. + * You need to import the L6470 library into the Arduino IDE for this. + * (https://github.com/ameyer/Arduino-L6470) + */ + +//#define HAVE_L6470DRIVER +#if ENABLED(HAVE_L6470DRIVER) + + //#define X_IS_L6470 + //#define X2_IS_L6470 + //#define Y_IS_L6470 + //#define Y2_IS_L6470 + //#define Z_IS_L6470 + //#define Z2_IS_L6470 + //#define E0_IS_L6470 + //#define E1_IS_L6470 + //#define E2_IS_L6470 + //#define E3_IS_L6470 + //#define E4_IS_L6470 + + #define X_MICROSTEPS 16 // number of microsteps + #define X_K_VAL 50 // 0 - 255, Higher values, are higher power. Be careful not to go too high + #define X_OVERCURRENT 2000 // maxc current in mA. If the current goes over this value, the driver will switch off + #define X_STALLCURRENT 1500 // current in mA where the driver will detect a stall + + #define X2_MICROSTEPS 16 + #define X2_K_VAL 50 + #define X2_OVERCURRENT 2000 + #define X2_STALLCURRENT 1500 + + #define Y_MICROSTEPS 16 + #define Y_K_VAL 50 + #define Y_OVERCURRENT 2000 + #define Y_STALLCURRENT 1500 + + #define Y2_MICROSTEPS 16 + #define Y2_K_VAL 50 + #define Y2_OVERCURRENT 2000 + #define Y2_STALLCURRENT 1500 + + #define Z_MICROSTEPS 16 + #define Z_K_VAL 50 + #define Z_OVERCURRENT 2000 + #define Z_STALLCURRENT 1500 + + #define Z2_MICROSTEPS 16 + #define Z2_K_VAL 50 + #define Z2_OVERCURRENT 2000 + #define Z2_STALLCURRENT 1500 + + #define E0_MICROSTEPS 16 + #define E0_K_VAL 50 + #define E0_OVERCURRENT 2000 + #define E0_STALLCURRENT 1500 + + #define E1_MICROSTEPS 16 + #define E1_K_VAL 50 + #define E1_OVERCURRENT 2000 + #define E1_STALLCURRENT 1500 + + #define E2_MICROSTEPS 16 + #define E2_K_VAL 50 + #define E2_OVERCURRENT 2000 + #define E2_STALLCURRENT 1500 + + #define E3_MICROSTEPS 16 + #define E3_K_VAL 50 + #define E3_OVERCURRENT 2000 + #define E3_STALLCURRENT 1500 + + #define E4_MICROSTEPS 16 + #define E4_K_VAL 50 + #define E4_OVERCURRENT 2000 + #define E4_STALLCURRENT 1500 + +#endif + +/** + * TWI/I2C BUS + * + * This feature is an EXPERIMENTAL feature so it shall not be used on production + * machines. Enabling this will allow you to send and receive I2C data from slave + * devices on the bus. + * + * ; Example #1 + * ; This macro send the string "Marlin" to the slave device with address 0x63 (99) + * ; It uses multiple M260 commands with one B arg + * M260 A99 ; Target slave address + * M260 B77 ; M + * M260 B97 ; a + * M260 B114 ; r + * M260 B108 ; l + * M260 B105 ; i + * M260 B110 ; n + * M260 S1 ; Send the current buffer + * + * ; Example #2 + * ; Request 6 bytes from slave device with address 0x63 (99) + * M261 A99 B5 + * + * ; Example #3 + * ; Example serial output of a M261 request + * echo:i2c-reply: from:99 bytes:5 data:hello + */ + +// @section i2cbus + +//#define EXPERIMENTAL_I2CBUS +#define I2C_SLAVE_ADDRESS 0 // Set a value from 8 to 127 to act as a slave + +// @section extras + +/** + * Spindle & Laser control + * + * Add the M3, M4, and M5 commands to turn the spindle/laser on and off, and + * to set spindle speed, spindle direction, and laser power. + * + * SuperPid is a router/spindle speed controller used in the CNC milling community. + * Marlin can be used to turn the spindle on and off. It can also be used to set + * the spindle speed from 5,000 to 30,000 RPM. + * + * 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. + */ +//#define SPINDLE_LASER_ENABLE +#if ENABLED(SPINDLE_LASER_ENABLE) + + #define SPINDLE_LASER_ENABLE_INVERT false // set to "true" if the on/off function is reversed + #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 // delay in milliseconds to allow the spindle/laser to come up to speed/power + #define SPINDLE_LASER_POWERDOWN_DELAY 5000 // delay in milliseconds to allow the spindle to stop + #define SPINDLE_DIR_CHANGE true // set to true if your spindle controller supports changing spindle direction + #define SPINDLE_INVERT_DIR false + #define SPINDLE_STOP_ON_DIR_CHANGE true // set to true if Marlin should stop the spindle before changing rotation direction + + /** + * The M3 & M4 commands use the following equation to convert PWM duty cycle to speed/power + * + * SPEED/POWER = PWM duty cycle * SPEED_POWER_SLOPE + SPEED_POWER_INTERCEPT + * where PWM duty cycle varies from 0 to 255 + * + * set the following for your controller (ALL MUST BE SET) + */ + + #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_SLOPE 0.3922 + //#define SPEED_POWER_INTERCEPT 0 + //#define SPEED_POWER_MIN 10 + //#define SPEED_POWER_MAX 100 // 0-100% +#endif + +/** + * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins + */ +//#define PINS_DEBUGGING + +/** + * Auto-report temperatures with M155 S + */ +#define AUTO_REPORT_TEMPERATURES + +/** + * Include capabilities in M115 output + */ +#define EXTENDED_CAPABILITIES_REPORT + +/** + * Volumetric extrusion default state + * 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. + */ +//#define VOLUMETRIC_DEFAULT_ON + +/** + * Enable this option for a leaner build of Marlin that removes all + * workspace offsets, simplifying coordinate transformations, leveling, etc. + * + * - M206 and M428 are disabled. + * - G92 will revert to its behavior from Marlin 1.0. + */ +//#define NO_WORKSPACE_OFFSETS + +/** + * 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. + * + * For clients that use a fixed-width font (like OctoPrint), leave this set to 1.0. + * Otherwise, adjust according to your client and font. + */ +#define PROPORTIONAL_FONT_RATIO 1.0 + +/** + * Spend 28 bytes of SRAM to optimize the GCode parser + */ +#define FASTER_GCODE_PARSER + +/** + * User-defined menu items that execute custom GCode + */ +//#define CUSTOM_USER_MENUS +#if ENABLED(CUSTOM_USER_MENUS) + #define USER_SCRIPT_DONE "M117 User Script Done" + #define USER_SCRIPT_AUDIBLE_FEEDBACK + //#define USER_SCRIPT_RETURN // Return to status screen after a script + + #define USER_DESC_1 "Home & UBL Info" + #define USER_GCODE_1 "G28\nG29 W" + + #define USER_DESC_2 "Preheat for PLA" + #define USER_GCODE_2 "M140 S" STRINGIFY(PREHEAT_1_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND) + + #define USER_DESC_3 "Preheat for ABS" + #define USER_GCODE_3 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND) + + #define USER_DESC_4 "Heat Bed/Home/Level" + #define USER_GCODE_4 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nG28\nG29" + + #define USER_DESC_5 "Home & Info" + #define USER_GCODE_5 "G28\nM503" +#endif + +/** + * Specify an action command to send to the host when the printer is killed. + * Will be sent in the form '//action:ACTION_ON_KILL', e.g. '//action:poweroff'. + * The host must be configured to handle the action command. + */ +//#define ACTION_ON_KILL "poweroff" + +//=========================================================================== +//====================== I2C Position Encoder Settings ====================== +//=========================================================================== + +/** + * I2C position encoders for closed loop control. + * Developed by Chris Barr at Aus3D. + * + * Wiki: http://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/ + * + * Reilabuild encoders have been modified to improve reliability. + */ + +//#define I2C_POSITION_ENCODERS +#if ENABLED(I2C_POSITION_ENCODERS) + + #define I2CPE_ENCODER_CNT 1 // The number of encoders installed; max of 5 + // encoders supported currently. + + #define I2CPE_ENC_1_ADDR I2CPE_PRESET_ADDR_X // I2C address of the encoder. 30-200. + #define I2CPE_ENC_1_AXIS X_AXIS // Axis the encoder module is installed on. _AXIS. + #define I2CPE_ENC_1_TYPE I2CPE_ENC_TYPE_LINEAR // Type of encoder: I2CPE_ENC_TYPE_LINEAR -or- + // I2CPE_ENC_TYPE_ROTARY. + #define I2CPE_ENC_1_TICKS_UNIT 2048 // 1024 for magnetic strips with 2mm poles; 2048 for + // 1mm poles. For linear encoders this is ticks / mm, + // for rotary encoders this is ticks / revolution. + //#define I2CPE_ENC_1_TICKS_REV (16 * 200) // Only needed for rotary encoders; number of stepper + // steps per full revolution (motor steps/rev * microstepping) + //#define I2CPE_ENC_1_INVERT // Invert the direction of axis travel. + #define I2CPE_ENC_1_EC_METHOD I2CPE_ECM_NONE // Type of error error correction. + #define I2CPE_ENC_1_EC_THRESH 0.10 // Threshold size for error (in mm) above which the + // printer will attempt to correct the error; errors + // smaller than this are ignored to minimize effects of + // measurement noise / latency (filter). + + #define I2CPE_ENC_2_ADDR I2CPE_PRESET_ADDR_Y // Same as above, but for encoder 2. + #define I2CPE_ENC_2_AXIS Y_AXIS + #define I2CPE_ENC_2_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_ENC_2_TICKS_UNIT 2048 + //#define I2CPE_ENC_2_TICKS_REV (16 * 200) + //#define I2CPE_ENC_2_INVERT + #define I2CPE_ENC_2_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_ENC_2_EC_THRESH 0.10 + + #define I2CPE_ENC_3_ADDR I2CPE_PRESET_ADDR_Z // Encoder 3. Add additional configuration options + #define I2CPE_ENC_3_AXIS Z_AXIS // as above, or use defaults below. + + #define I2CPE_ENC_4_ADDR I2CPE_PRESET_ADDR_E // Encoder 4. + #define I2CPE_ENC_4_AXIS E_AXIS + + #define I2CPE_ENC_5_ADDR 34 // Encoder 5. + #define I2CPE_ENC_5_AXIS E_AXIS + + // Default settings for encoders which are enabled, but without settings configured above. + #define I2CPE_DEF_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_DEF_ENC_TICKS_UNIT 2048 + #define I2CPE_DEF_TICKS_REV (16 * 200) + #define I2CPE_DEF_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_DEF_EC_THRESH 0.1 + + //#define I2CPE_ERR_THRESH_ABORT 100.0 // Threshold size for error (in mm) error on any given + // axis after which the printer will abort. Comment out to + // disable abort behaviour. + + #define I2CPE_TIME_TRUSTED 10000 // After an encoder fault, there must be no further fault + // for this amount of time (in ms) before the encoder + // is trusted again. + + /** + * Position is checked every time a new command is executed from the buffer but during long moves, + * this setting determines the minimum update time between checks. A value of 100 works well with + * error rolling average when attempting to correct only for skips and not for vibration. + */ + #define I2CPE_MIN_UPD_TIME_MS 100 // Minimum time in miliseconds between encoder checks. + + // Use a rolling average to identify persistant errors that indicate skips, as opposed to vibration and noise. + #define I2CPE_ERR_ROLLING_AVERAGE + +#endif // I2C_POSITION_ENCODERS + +/** + * MAX7219 Debug Matrix + * + * Add support for a low-cost 8x8 LED Matrix based on the Max7219 chip, which can be used as a status + * display. Requires 3 signal wires. Some useful debug options are included to demonstrate its usage. + * + * Fully assembled MAX7219 boards can be found on the internet for under $2(US). + * For example, see https://www.ebay.com/sch/i.html?_nkw=332349290049 + */ +//#define MAX7219_DEBUG +#if ENABLED(MAX7219_DEBUG) + #define MAX7219_CLK_PIN 64 // 77 on Re-ARM // Configuration of the 3 pins to control the display + #define MAX7219_DIN_PIN 57 // 78 on Re-ARM + #define MAX7219_LOAD_PIN 44 // 79 on Re-ARM + + /** + * Sample debug features + * If you add more debug displays, be careful to avoid conflicts! + */ + #define MAX7219_DEBUG_PRINTER_ALIVE // Blink corner LED of 8x8 matrix to show that the firmware is functioning + #define MAX7219_DEBUG_STEPPER_HEAD 3 // Show the stepper queue head position on this and the next LED matrix row + #define MAX7219_DEBUG_STEPPER_TAIL 5 // Show the stepper queue tail position on this and the next LED matrix row + + #define MAX7219_DEBUG_STEPPER_QUEUE 0 // Show the current stepper queue depth on this and the next LED matrix row + // If you experience stuttering, reboots, etc. this option can reveal how + // tweaks made to the configuration are affecting the printer in real-time. +#endif + +#endif // CONFIGURATION_ADV_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/delta/kossel_mini/Configuration.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/delta/kossel_mini/Configuration.h new file mode 100644 index 00000000..edf3c481 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/delta/kossel_mini/Configuration.h @@ -0,0 +1,1819 @@ +/** + * 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 . + * + */ + +/** + * Configuration.h + * + * Basic settings such as: + * + * - Type of electronics + * - Type of temperature sensor + * - Printer geometry + * - Endstop configuration + * - LCD controller + * - Extra features + * + * Advanced settings can be found in Configuration_adv.h + * + */ +#ifndef CONFIGURATION_H +#define CONFIGURATION_H +#define CONFIGURATION_H_VERSION 010100 + +//=========================================================================== +//============================= Getting Started ============================= +//=========================================================================== + +/** + * Here are some standard links for getting your machine calibrated: + * + * http://reprap.org/wiki/Calibration + * http://youtu.be/wAL9d7FgInk + * http://calculator.josefprusa.cz + * http://reprap.org/wiki/Triffid_Hunter%27s_Calibration_Guide + * http://www.thingiverse.com/thing:5573 + * https://sites.google.com/site/repraplogphase/calibration-of-your-reprap + * http://www.thingiverse.com/thing:298812 + */ + +//=========================================================================== +//============================= DELTA Printer =============================== +//=========================================================================== +// For a Delta printer start with one of the configuration files in the +// example_configurations/delta directory and customize for your machine. +// + +//=========================================================================== +//============================= SCARA Printer =============================== +//=========================================================================== +// For a SCARA printer start with the configuration files in +// example_configurations/SCARA and customize for your machine. +// + +// @section info + +// User-specified version info of this build to display in [Pronterface, etc] terminal window during +// startup. Implementation of an idea by Prof Braino to inform user that any changes made to this +// build by the user have been successfully uploaded into firmware. +#define STRING_CONFIG_H_AUTHOR "(none, default config)" // Who made the changes. +#define SHOW_BOOTSCREEN +#define STRING_SPLASH_LINE1 SHORT_BUILD_VERSION // will be shown during bootup in line 1 +#define STRING_SPLASH_LINE2 WEBSITE_URL // will be shown during bootup in line 2 + +// +// *** VENDORS PLEASE READ ***************************************************** +// +// Marlin now allow you to have a vendor boot image to be displayed on machine +// start. When SHOW_CUSTOM_BOOTSCREEN is defined Marlin will first show your +// custom boot image and then the default Marlin boot image is shown. +// +// We suggest for you to take advantage of this new feature and keep the Marlin +// boot image unmodified. For an example have a look at the bq Hephestos 2 +// example configuration folder. +// +//#define SHOW_CUSTOM_BOOTSCREEN +// @section machine + +/** + * Select which serial port on the board will be used for communication with the host. + * This allows the connection of wireless adapters (for instance) to non-default port pins. + * Serial port 0 is always used by the Arduino bootloader regardless of this setting. + * + * :[0, 1, 2, 3, 4, 5, 6, 7] + */ +#define SERIAL_PORT 0 + +/** + * This setting determines the communication speed of the printer. + * + * 250000 works in most cases, but you might try a lower speed if + * you commonly experience drop-outs during host printing. + * You may try up to 1000000 to speed up SD file transfer. + * + * :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000] + */ +#define BAUDRATE 250000 + +// Enable the Bluetooth serial interface on AT90USB devices +//#define BLUETOOTH + +// The following define selects which electronics board you have. +// Please choose the name from boards.h that matches your setup +#ifndef MOTHERBOARD + #define MOTHERBOARD BOARD_RAMPS_14_EFB +#endif + +// Optional custom name for your RepStrap or other custom machine +// Displayed in the LCD "Ready" message +#define CUSTOM_MACHINE_NAME "Mini Kossel" + +// Define this to set a unique identifier for this printer, (Used by some programs to differentiate between machines) +// You can use an online service to generate a random UUID. (eg http://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] +#define EXTRUDERS 1 + +// For Cyclops or any "multi-extruder" that shares a single nozzle. +//#define SINGLENOZZLE + +/** + * Průša MK2 Single Nozzle Multi-Material Multiplexer, and variants. + * + * This device allows one stepper driver on a control board to drive + * two to eight stepper motors, one at a time, in a manner suitable + * for extruders. + * + * This option only allows the multiplexer to switch on tool-change. + * Additional options to configure custom E moves are pending. + */ +//#define MK2_MULTIPLEXER +#if ENABLED(MK2_MULTIPLEXER) + // Override the default DIO selector pins here, if needed. + // Some pins files may provide defaults for these pins. + //#define E_MUX0_PIN 40 // Always Required + //#define E_MUX1_PIN 42 // Needed for 3 to 8 steppers + //#define E_MUX2_PIN 44 // Needed for 5 to 8 steppers +#endif + +// A dual extruder that uses a single stepper motor +//#define SWITCHING_EXTRUDER +#if ENABLED(SWITCHING_EXTRUDER) + #define SWITCHING_EXTRUDER_SERVO_NR 0 + #define SWITCHING_EXTRUDER_SERVO_ANGLES { 0, 90 } // Angles for E0, E1[, E2, E3] + #if EXTRUDERS > 3 + #define SWITCHING_EXTRUDER_E23_SERVO_NR 1 + #endif +#endif + +// A dual-nozzle that uses a servomotor to raise/lower one of the nozzles +//#define SWITCHING_NOZZLE +#if ENABLED(SWITCHING_NOZZLE) + #define SWITCHING_NOZZLE_SERVO_NR 0 + #define SWITCHING_NOZZLE_SERVO_ANGLES { 0, 90 } // Angles for E0, E1 + //#define HOTEND_OFFSET_Z { 0.0, 0.0 } +#endif + +/** + * Two separate X-carriages with extruders that connect to a moving part + * via a magnetic docking mechanism. Requires SOL1_PIN and SOL2_PIN. + */ +//#define PARKING_EXTRUDER +#if ENABLED(PARKING_EXTRUDER) + #define PARKING_EXTRUDER_SOLENOIDS_INVERT // If enabled, the solenoid is NOT magnetized with applied voltage + #define PARKING_EXTRUDER_SOLENOIDS_PINS_ACTIVE LOW // LOW or HIGH pin signal energizes the coil + #define PARKING_EXTRUDER_SOLENOIDS_DELAY 250 // Delay (ms) for magnetic field. No delay if 0 or not defined. + #define PARKING_EXTRUDER_PARKING_X { -78, 184 } // X positions for parking the extruders + #define PARKING_EXTRUDER_GRAB_DISTANCE 1 // mm to move beyond the parking point to grab the extruder + #define PARKING_EXTRUDER_SECURITY_RAISE 5 // Z-raise before parking + #define HOTEND_OFFSET_Z { 0.0, 1.3 } // Z-offsets of the two hotends. The first must be 0. +#endif + +/** + * "Mixing Extruder" + * - Adds a new code, M165, to set the current mix factors. + * - Extends the stepping routines to move multiple steppers in proportion to the mix. + * - Optional support for Repetier Firmware M163, M164, and virtual extruder. + * - This implementation supports only a single extruder. + * - Enable DIRECT_MIXING_IN_G1 for Pia Taubert's reference implementation + */ +//#define MIXING_EXTRUDER +#if ENABLED(MIXING_EXTRUDER) + #define MIXING_STEPPERS 2 // Number of steppers in your mixing extruder + #define MIXING_VIRTUAL_TOOLS 16 // Use the Virtual Tool method with M163 and M164 + //#define DIRECT_MIXING_IN_G1 // Allow ABCDHI mix factors in G1 movement commands +#endif + +// Offset of the extruders (uncomment if using more than one and relying on firmware to position when changing). +// The offset has to be X=0, Y=0 for the extruder 0 hotend (default extruder). +// For the other hotends it is their distance from the extruder 0 hotend. +//#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis +//#define HOTEND_OFFSET_Y {0.0, 5.00} // (in mm) for each extruder, offset of the hotend on the Y axis + +// @section machine + +/** + * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN + * + * 0 = No Power Switch + * 1 = ATX + * 2 = X-Box 360 203Watts (the blue wire connected to PS_ON and the red wire to VCC) + * + * :{ 0:'No power switch', 1:'ATX', 2:'X-Box 360' } + */ +#define POWER_SUPPLY 1 + +#if POWER_SUPPLY > 0 + // Enable this option to leave the PSU off at startup. + // Power to steppers and heaters will need to be turned on with M80. + //#define PS_DEFAULT_OFF +#endif + +// @section temperature + +//=========================================================================== +//============================= Thermal Settings ============================ +//=========================================================================== + +/** + * --NORMAL IS 4.7kohm PULLUP!-- 1kohm pullup can be used on hotend sensor, using correct resistor and table + * + * Temperature sensors available: + * + * -3 : thermocouple with MAX31855 (only for sensor 0) + * -2 : thermocouple with MAX6675 (only for sensor 0) + * -1 : thermocouple with AD595 + * 0 : not used + * 1 : 100k thermistor - best choice for EPCOS 100k (4.7k pullup) + * 2 : 200k thermistor - ATC Semitec 204GT-2 (4.7k pullup) + * 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 (Used in ParCan & J-Head) (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) + * 71 : 100k Honeywell thermistor 135-104LAF-J01 (4.7k pullup) + * 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) + * 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" + * 20 : the PT100 circuit found in the Ultimainboard V2.x + * 60 : 100k Maker's Tool Works Kapton Bed Thermistor beta=3950 + * 66 : 4.7M High Temperature thermistor from Dyze Design + * 70 : the 100K thermistor found in the bq Hephestos 2 + * 75 : 100k Generic Silicon Heat Pad with NTC 100K MGB18-104F39050L32 thermistor + * + * 1k ohm pullup tables - This is atypical, and requires changing out the 4.7k pullup for 1k. + * (but gives greater accuracy and more stable PID) + * 51 : 100k thermistor - EPCOS (1k pullup) + * 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 + * 1010 : Pt1000 with 1k pullup (non standard) + * 147 : Pt100 with 4k7 pullup + * 110 : Pt100 with 1k pullup (non standard) + * + * Use these for Testing or Development purposes. NEVER for production machine. + * 998 : Dummy Table that ALWAYS reads 25°C or the temperature defined below. + * 999 : Dummy Table that ALWAYS reads 100°C or the temperature defined below. + * + * :{ '0': "Not used", '1':"100k / 4.7k - EPCOS", '2':"200k / 4.7k - ATC Semitec 204GT-2", '3':"Mendel-parts / 4.7k", '4':"10k !! do not use for a hotend. Bad resolution at high temp. !!", '5':"100K / 4.7k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '6':"100k / 4.7k EPCOS - Not as accurate as Table 1", '7':"100k / 4.7k Honeywell 135-104LAG-J01", '8':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT", '9':"100k / 4.7k GE Sensing AL03006-58.2K-97-G1", '10':"100k / 4.7k RS 198-961", '11':"100k / 4.7k beta 3950 1%", '12':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT (calibrated for Makibox hot bed)", '13':"100k Hisens 3950 1% up to 300°C for hotend 'Simple ONE ' & hotend 'All In ONE'", '20':"PT100 (Ultimainboard V2.x)", '51':"100k / 1k - EPCOS", '52':"200k / 1k - ATC Semitec 204GT-2", '55':"100k / 1k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '60':"100k Maker's Tool Works Kapton Bed Thermistor beta=3950", '66':"Dyze Design 4.7M High Temperature thermistor", '70':"the 100K thermistor found in the bq Hephestos 2", '71':"100k / 4.7k Honeywell 135-104LAF-J01", '147':"Pt100 / 4.7k", '1047':"Pt1000 / 4.7k", '110':"Pt100 / 1k (non-standard)", '1010':"Pt1000 / 1k (non standard)", '-3':"Thermocouple + MAX31855 (only for sensor 0)", '-2':"Thermocouple + MAX6675 (only for sensor 0)", '-1':"Thermocouple + AD595",'998':"Dummy 1", '999':"Dummy 2" } + */ +#define TEMP_SENSOR_0 7 +#define TEMP_SENSOR_1 0 +#define TEMP_SENSOR_2 0 +#define TEMP_SENSOR_3 0 +#define TEMP_SENSOR_4 0 +#define TEMP_SENSOR_BED 11 + +// Dummy thermistor constant temperature readings, for use with 998 and 999 +#define DUMMY_THERMISTOR_998_VALUE 25 +#define DUMMY_THERMISTOR_999_VALUE 100 + +// 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 +#define MAX_REDUNDANT_TEMP_SENSOR_DIFF 5 + +// Extruder temperature must be close to target for this long before M109 returns success +#define TEMP_RESIDENCY_TIME 10 // (seconds) +#define TEMP_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// Bed temperature must be close to target for this long before M190 returns success +#define TEMP_BED_RESIDENCY_TIME 0 // (seconds) +#define TEMP_BED_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_BED_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// The minimal temperature defines the temperature below which the heater will not be enabled It is used +// to check that the wiring to the thermistor is not broken. +// Otherwise this would lead to the heater being powered on all the time. +#define HEATER_0_MINTEMP 5 +#define HEATER_1_MINTEMP 5 +#define HEATER_2_MINTEMP 5 +#define HEATER_3_MINTEMP 5 +#define HEATER_4_MINTEMP 5 +#define BED_MINTEMP 5 + +// When temperature exceeds max temp, your heater will be switched off. +// This feature exists to protect your hotend from overheating accidentally, but *NOT* from thermistor short/failure! +// You should use MINTEMP for thermistor short/failure protection. +#define HEATER_0_MAXTEMP 275 +#define HEATER_1_MAXTEMP 275 +#define HEATER_2_MAXTEMP 275 +#define HEATER_3_MAXTEMP 275 +#define HEATER_4_MAXTEMP 275 +#define BED_MAXTEMP 150 + +//=========================================================================== +//============================= PID Settings ================================ +//=========================================================================== +// PID Tuning Guide here: http://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 +#if ENABLED(PIDTEMP) + //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. + //#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. + #define K1 0.95 //smoothing factor within the PID + + // 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 + +#endif // PIDTEMP + +//=========================================================================== +//============================= PID > Bed Temperature Control =============== +//=========================================================================== +// Select PID or bang-bang with PIDTEMPBED. If bang-bang, BED_LIMIT_SWITCHING will enable hysteresis +// +// Uncomment this to enable PID on the bed. It uses the same frequency PWM as the extruder. +// If your PID_dT is the default, and correct for your hardware/configuration, that means 7.689Hz, +// which is fine for driving a square wave into a resistive load and does not significantly impact you FET heating. +// This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W heater. +// If your configuration is significantly different than this and you don't understand the issues involved, you probably +// shouldn't use bed PID until someone else verifies your hardware works. +// If this is enabled, find your own PID constants below. +//#define PIDTEMPBED + +//#define BED_LIMIT_SWITCHING + +// This sets the max power delivered to the bed, and replaces the HEATER_BED_DUTY_CYCLE_DIVIDER option. +// all forms of bed control obey this (PID, bang-bang, bang-bang with hysteresis) +// setting this to anything other than 255 enables a form of PWM to the bed just like HEATER_BED_DUTY_CYCLE_DIVIDER did, +// so you shouldn't use it unless you are OK with PWM on your bed. (see the comment on enabling PIDTEMPBED) +#define MAX_BED_POWER 255 // limits duty cycle to bed; 255=full current + +#if ENABLED(PIDTEMPBED) + + //#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) + #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 + +// @section extruder + +// This option prevents extrusion if the temperature is below EXTRUDE_MINTEMP. +// It also enables the M302 command to set the minimum extrusion temperature +// or to allow moving the extruder regardless of the hotend temperature. +// *** IT IS HIGHLY RECOMMENDED TO LEAVE THIS OPTION ENABLED! *** +#define PREVENT_COLD_EXTRUSION +#define EXTRUDE_MINTEMP 170 + +// This option prevents a single extrusion longer than EXTRUDE_MAXLENGTH. +// Note that for Bowden Extruders a too-small value here may prevent loading. +#define PREVENT_LENGTHY_EXTRUDE +#define EXTRUDE_MAXLENGTH 200 + +//=========================================================================== +//======================== Thermal Runaway Protection ======================= +//=========================================================================== + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * If you get "Thermal Runaway" or "Heating failed" errors the + * details can be tuned in Configuration_adv.h + */ + +#define THERMAL_PROTECTION_HOTENDS // Enable thermal protection for all extruders +#define THERMAL_PROTECTION_BED // Enable thermal protection for the heated bed + +//=========================================================================== +//============================= Mechanical Settings ========================= +//=========================================================================== + +// @section machine + +// Uncomment one of these options to enable CoreXY, CoreXZ, or CoreYZ kinematics +// either in the usual order or reversed +//#define COREXY +//#define COREXZ +//#define COREYZ +//#define COREYX +//#define COREZX +//#define COREZY + +//=========================================================================== +//============================== Delta Settings ============================= +//=========================================================================== +// Enable DELTA kinematics and most of the default configuration for Deltas +#define DELTA + +#if ENABLED(DELTA) + + // Make delta curves from many straight lines (linear interpolation). + // This is a trade-off between visible corners (not enough segments) + // and processor overload (too many expensive sqrt calls). + #define DELTA_SEGMENTS_PER_SECOND 200 + + // After homing move down to a height where XY movement is unconstrained + //#define DELTA_HOME_TO_SAFE_ZONE + + // Delta calibration menu + // uncomment to add three points calibration menu option. + // See http://minow.blogspot.com/index.html#4918805519571907051 + //#define DELTA_CALIBRATION_MENU + + // uncomment to add G33 Delta Auto-Calibration (Enable EEPROM_SETTINGS to store results) + //#define DELTA_AUTO_CALIBRATION + + // NOTE NB all values for DELTA_* values MUST be floating point, so always have a decimal point in them + + #if ENABLED(DELTA_AUTO_CALIBRATION) + // set the default number of probe points : n*n (1 -> 7) + #define DELTA_CALIBRATION_DEFAULT_POINTS 4 + #endif + + #if ENABLED(DELTA_AUTO_CALIBRATION) || ENABLED(DELTA_CALIBRATION_MENU) + // Set the radius for the calibration probe points - max DELTA_PRINTABLE_RADIUS*0.869 for non-eccentric probes + #define DELTA_CALIBRATION_RADIUS 78.0 // mm + // Set the steprate for papertest probing + #define PROBE_MANUALLY_STEP 0.025 + #endif + + // Print surface diameter/2 minus unreachable space (avoid collisions with vertical towers). + #define DELTA_PRINTABLE_RADIUS 90.0 // mm + + // Center-to-center distance of the holes in the diagonal push rods. + #define DELTA_DIAGONAL_ROD 215.0 // mm + + // height from z=0 to home position + #define DELTA_HEIGHT 250.00 // get this value from auto calibrate + + #define DELTA_ENDSTOP_ADJ { 0.0, 0.0, 0.0 } // get these from auto calibrate + + // Horizontal distance bridged by diagonal push rods when effector is centered. + #define DELTA_RADIUS 105.2 //mm Get this value from auto calibrate + + // Trim adjustments for individual towers + // tower angle corrections for X and Y tower / rotate XYZ so Z tower angle = 0 + // measured in degrees anticlockwise looking from above the printer + #define DELTA_TOWER_ANGLE_TRIM { 0.0, 0.0, 0.0 } // get these values from auto calibrate + + // delta radius and diaginal rod adjustments measured in mm + //#define DELTA_RADIUS_TRIM_TOWER { 0.0, 0.0, 0.0 } + //#define DELTA_DIAGONAL_ROD_TRIM_TOWER { 0.0, 0.0, 0.0 } + +#endif + +//=========================================================================== +//============================== Endstop Settings =========================== +//=========================================================================== + +// @section homing + +// Specify here all the endstop connectors that are connected to any endstop or probe. +// Almost all printers will be using one per axis. Probes will use one or more of the +// extra connectors. Leave undefined any used for non-endstop and non-probe purposes. +//#define USE_XMIN_PLUG +//#define USE_YMIN_PLUG +#define USE_ZMIN_PLUG // a Z probe +#define USE_XMAX_PLUG +#define USE_YMAX_PLUG +#define USE_ZMAX_PLUG + +// coarse Endstop Settings +#define ENDSTOPPULLUPS // Comment this out (using // at the start of the line) to disable the endstop pullup resistors + +#if DISABLED(ENDSTOPPULLUPS) + // fine endstop settings: Individual pullups. will be ignored if ENDSTOPPULLUPS is defined + //#define ENDSTOPPULLUP_XMAX + //#define ENDSTOPPULLUP_YMAX + //#define ENDSTOPPULLUP_ZMAX + //#define ENDSTOPPULLUP_XMIN + //#define ENDSTOPPULLUP_YMIN + //#define ENDSTOPPULLUP_ZMIN + //#define ENDSTOPPULLUP_ZMIN_PROBE +#endif + +// Mechanical endstop with COM to ground and NC to Signal uses "false" here (most common setup). +#define X_MIN_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Y_MIN_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MIN_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define X_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Y_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MIN_PROBE_ENDSTOP_INVERTING false // set to true to invert the logic of the probe. + +// Enable this feature if all enabled endstop pins are interrupt-capable. +// This will remove the need to poll the interrupt pins, saving many CPU cycles. +//#define ENDSTOP_INTERRUPTS_FEATURE + +//============================================================================= +//============================== Movement Settings ============================ +//============================================================================= +// @section motion + +// delta speeds must be the same on xyz +/** + * Default Settings + * + * These settings can be reset by M502 + * + * Note that if EEPROM is enabled, saved values will override these. + */ + +/** + * With this option each E stepper can have its own factors for the + * following movement settings. If fewer factors are given than the + * total number of extruders, the last value applies to the rest. + */ +//#define DISTINCT_E_FACTORS + +/** + * Default Axis Steps Per Unit (steps/mm) + * Override with M92 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_AXIS_STEPS_PER_UNIT { 80, 80, 80, 760*1.1 } // default steps per unit for Kossel (GT2, 20 tooth) + +/** + * Default Max Feed Rate (mm/s) + * Override with M203 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_FEEDRATE { 500, 500, 500, 25 } + +/** + * Default Max Acceleration (change/s) change = mm/s + * (Maximum start speed for accelerated moves) + * Override with M201 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_ACCELERATION { 9000, 9000, 9000, 10000 } + +/** + * Default Acceleration (change/s) change = mm/s + * Override with M204 + * + * M204 P Acceleration + * M204 R Retract Acceleration + * M204 T Travel Acceleration + */ +#define DEFAULT_ACCELERATION 3000 // X, Y, Z and E acceleration for printing moves +#define DEFAULT_RETRACT_ACCELERATION 3000 // E acceleration for retracts +#define DEFAULT_TRAVEL_ACCELERATION 3000 // X, Y, Z acceleration for travel (non printing) moves + +/** + * Default Jerk (mm/s) + * Override with M205 X Y Z E + * + * "Jerk" specifies the minimum speed change that requires acceleration. + * When changing speed and direction, if the difference is less than the + * value set here, it may happen instantaneously. + */ +#define DEFAULT_XJERK 20.0 +#define DEFAULT_YJERK 20.0 +#define DEFAULT_ZJERK 20.0 // Must be same as XY for delta +#define DEFAULT_EJERK 5.0 + +//=========================================================================== +//============================= Z Probe Options ============================= +//=========================================================================== +// @section probes + +// +// See http://marlinfw.org/configuration/probes.html +// + +/** + * Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + * + * Enable this option for a probe connected to the Z Min endstop pin. + */ +#define Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + +/** + * Z_MIN_PROBE_ENDSTOP + * + * Enable this option for a probe connected to any pin except Z-Min. + * (By default Marlin assumes the Z-Max endstop pin.) + * To use a custom Z Probe pin, set Z_MIN_PROBE_PIN below. + * + * - The simplest option is to use a free endstop connector. + * - Use 5V for powered (usually inductive) sensors. + * + * - RAMPS 1.3/1.4 boards may use the 5V, GND, and Aux4->D32 pin: + * - For simple switches connect... + * - normally-closed switches to GND and D32. + * - normally-open switches to 5V and D32. + * + * WARNING: Setting the wrong pin may have unexpected and potentially + * disastrous consequences. Use with caution and do your homework. + * + */ +//#define Z_MIN_PROBE_ENDSTOP + +/** + * Probe Type + * + * Allen Key Probes, Servo Probes, Z-Sled Probes, FIX_MOUNTED_PROBE, etc. + * Activate one of these to use Auto Bed Leveling below. + */ + +/** + * The "Manual Probe" provides a means to do "Auto" Bed Leveling without a probe. + * Use G29 repeatedly, adjusting the Z height at each point with movement commands + * or (with LCD_BED_LEVELING) the LCD controller. + */ +//#define PROBE_MANUALLY + +/** + * A Fix-Mounted Probe either doesn't deploy or needs manual deployment. + * (e.g., an inductive probe or a nozzle-based probe-switch.) + */ +//#define FIX_MOUNTED_PROBE + +/** + * Z Servo Probe, such as an endstop switch on a rotating arm. + */ +//#define Z_ENDSTOP_SERVO_NR 0 // Defaults to SERVO 0 connector. +//#define Z_SERVO_ANGLES {70,0} // Z Servo Deploy and Stow angles + +/** + * The BLTouch probe uses a Hall effect sensor and emulates a servo. + */ +//#define BLTOUCH +#if ENABLED(BLTOUCH) + //#define BLTOUCH_DELAY 375 // (ms) Enable and increase if needed +#endif + +/** + * Enable one or more of the following if probing seems unreliable. + * Heaters and/or fans can be disabled during probing to minimize electrical + * noise. A delay can also be added to allow noise and vibration to settle. + * These options are most useful for the BLTouch probe, but may also improve + * readings with inductive probes and piezo sensors. + */ +//#define PROBING_HEATERS_OFF // Turn heaters off when probing +//#define PROBING_FANS_OFF // Turn fans off when probing +//#define DELAY_BEFORE_PROBING 200 // (ms) To prevent vibrations from triggering piezo sensors + +// A probe that is deployed and stowed with a solenoid pin (SOL1_PIN) +//#define SOLENOID_PROBE + +// A sled-mounted probe like those designed by Charles Bell. +//#define Z_PROBE_SLED +//#define SLED_DOCKING_OFFSET 5 // The extra distance the X axis must travel to pickup the sled. 0 should be fine but you can push it further if you'd like. + +// +// For Z_PROBE_ALLEN_KEY see the Delta example configurations. +// + +/** + * Z Probe to nozzle (X,Y) offset, relative to (0, 0). + * X and Y offsets must be integers. + * + * In the following example the X and Y offsets are both positive: + * #define X_PROBE_OFFSET_FROM_EXTRUDER 10 + * #define Y_PROBE_OFFSET_FROM_EXTRUDER 10 + * + * +-- BACK ---+ + * | | + * L | (+) P | R <-- probe (20,20) + * E | | I + * F | (-) N (+) | G <-- nozzle (10,10) + * T | | H + * | (-) | T + * | | + * O-- FRONT --+ + * (0,0) + */ +#define X_PROBE_OFFSET_FROM_EXTRUDER 0 // X offset: -left +right [of the nozzle] +#define Y_PROBE_OFFSET_FROM_EXTRUDER -10 // Y offset: -front +behind [the nozzle] +#define Z_PROBE_OFFSET_FROM_EXTRUDER -3.5 // Z offset: -below +above [the nozzle] + +// X and Y axis travel speed (mm/m) between probes +#define XY_PROBE_SPEED 4000 + +// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +#define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z + +// Speed for the "accurate" probe of each point +#define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) + +// Use double touch for probing +//#define PROBE_DOUBLE_TOUCH + +/** + * Allen key retractable z-probe as seen on many Kossel delta printers - http://reprap.org/wiki/Kossel#Automatic_bed_leveling_probe + * Deploys by touching z-axis belt. Retracts by pushing the probe down. Uses Z_MIN_PIN. + */ +#define Z_PROBE_ALLEN_KEY + +#if ENABLED(Z_PROBE_ALLEN_KEY) + // 2 or 3 sets of coordinates for deploying and retracting the spring loaded touch probe on G29, + // if servo actuated touch probe is not defined. Uncomment as appropriate for your printer/probe. + + // Kossel Mini + #define Z_PROBE_ALLEN_KEY_DEPLOY_1_X 30.0 + #define Z_PROBE_ALLEN_KEY_DEPLOY_1_Y DELTA_PRINTABLE_RADIUS + #define Z_PROBE_ALLEN_KEY_DEPLOY_1_Z 100.0 + #define Z_PROBE_ALLEN_KEY_DEPLOY_1_FEEDRATE XY_PROBE_SPEED + + #define Z_PROBE_ALLEN_KEY_DEPLOY_2_X 0.0 + #define Z_PROBE_ALLEN_KEY_DEPLOY_2_Y DELTA_PRINTABLE_RADIUS + #define Z_PROBE_ALLEN_KEY_DEPLOY_2_Z 100.0 + #define Z_PROBE_ALLEN_KEY_DEPLOY_2_FEEDRATE (XY_PROBE_SPEED/10) + + #define Z_PROBE_ALLEN_KEY_DEPLOY_3_X Z_PROBE_ALLEN_KEY_DEPLOY_2_X * 0.75 + #define Z_PROBE_ALLEN_KEY_DEPLOY_3_Y Z_PROBE_ALLEN_KEY_DEPLOY_2_Y * 0.75 + #define Z_PROBE_ALLEN_KEY_DEPLOY_3_Z Z_PROBE_ALLEN_KEY_DEPLOY_2_Z + #define Z_PROBE_ALLEN_KEY_DEPLOY_3_FEEDRATE XY_PROBE_SPEED + + #define Z_PROBE_ALLEN_KEY_STOW_DEPTH 20 + // Move the probe into position + #define Z_PROBE_ALLEN_KEY_STOW_1_X -64.0 + #define Z_PROBE_ALLEN_KEY_STOW_1_Y 56.0 + #define Z_PROBE_ALLEN_KEY_STOW_1_Z 23.0 + #define Z_PROBE_ALLEN_KEY_STOW_1_FEEDRATE XY_PROBE_SPEED + // Move the nozzle down further to push the probe into retracted position. + #define Z_PROBE_ALLEN_KEY_STOW_2_X Z_PROBE_ALLEN_KEY_STOW_1_X + #define Z_PROBE_ALLEN_KEY_STOW_2_Y Z_PROBE_ALLEN_KEY_STOW_1_Y + #define Z_PROBE_ALLEN_KEY_STOW_2_Z (Z_PROBE_ALLEN_KEY_STOW_1_Z-Z_PROBE_ALLEN_KEY_STOW_DEPTH) + #define Z_PROBE_ALLEN_KEY_STOW_2_FEEDRATE (XY_PROBE_SPEED/10) + // Raise things back up slightly so we don't bump into anything + #define Z_PROBE_ALLEN_KEY_STOW_3_X Z_PROBE_ALLEN_KEY_STOW_2_X + #define Z_PROBE_ALLEN_KEY_STOW_3_Y Z_PROBE_ALLEN_KEY_STOW_2_Y + #define Z_PROBE_ALLEN_KEY_STOW_3_Z (Z_PROBE_ALLEN_KEY_STOW_1_Z+Z_PROBE_ALLEN_KEY_STOW_DEPTH) + #define Z_PROBE_ALLEN_KEY_STOW_3_FEEDRATE (XY_PROBE_SPEED/2) + + #define Z_PROBE_ALLEN_KEY_STOW_4_X 0.0 + #define Z_PROBE_ALLEN_KEY_STOW_4_Y 0.0 + #define Z_PROBE_ALLEN_KEY_STOW_4_Z Z_PROBE_ALLEN_KEY_STOW_3_Z + #define Z_PROBE_ALLEN_KEY_STOW_4_FEEDRATE XY_PROBE_SPEED + +#endif // Z_PROBE_ALLEN_KEY + +/** + * Z probes require clearance when deploying, stowing, and moving between + * probe points to avoid hitting the bed and other hardware. + * Servo-mounted probes require extra space for the arm to rotate. + * Inductive probes need space to keep from triggering early. + * + * Use these settings to specify the distance (mm) to raise the probe (or + * lower the bed). The values set here apply over and above any (negative) + * probe Z Offset set with Z_PROBE_OFFSET_FROM_EXTRUDER, M851, or the LCD. + * Only integer values >= 1 are valid here. + * + * Example: `M851 Z-5` with a CLEARANCE of 4 => 9mm from bed to nozzle. + * But: `M851 Z+1` with a CLEARANCE of 2 => 2mm from bed to nozzle. + */ +#define Z_CLEARANCE_DEPLOY_PROBE 50 // Z Clearance for Deploy/Stow +#define Z_CLEARANCE_BETWEEN_PROBES 5 // Z Clearance between probe points + +// For M851 give a range for adjusting the Z probe offset +#define Z_PROBE_OFFSET_RANGE_MIN -20 +#define Z_PROBE_OFFSET_RANGE_MAX 20 + +// Enable the M48 repeatability test to test probe accuracy +//#define Z_MIN_PROBE_REPEATABILITY_TEST + +// For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1 +// :{ 0:'Low', 1:'High' } +#define X_ENABLE_ON 0 +#define Y_ENABLE_ON 0 +#define Z_ENABLE_ON 0 +#define E_ENABLE_ON 0 // For all extruders + +// Disables axis stepper immediately when it's not being used. +// 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 +//#define DISABLE_REDUCED_ACCURACY_WARNING + +// @section extruder + +#define DISABLE_E false // For all extruders +#define DISABLE_INACTIVE_EXTRUDER true // Keep only the active extruder enabled. + +// @section machine + +// Invert the stepper direction. Change (or reverse the motor connector) if an axis goes the wrong way. +#define INVERT_X_DIR false // DELTA does not invert +#define INVERT_Y_DIR false +#define INVERT_Z_DIR false + +// Enable this option for Toshiba stepper drivers +//#define CONFIG_STEPPERS_TOSHIBA + +// @section extruder + +// For direct drive extruder v9 set to true, for geared extruder set to false. +#define INVERT_E0_DIR false +#define INVERT_E1_DIR false +#define INVERT_E2_DIR false +#define INVERT_E3_DIR false +#define INVERT_E4_DIR false + +// @section homing + +//#define NO_MOTION_BEFORE_HOMING // Inhibit movement until all axes have been homed + +//#define Z_HOMING_HEIGHT 15 // (in mm) Minimal z height before homing (G28) for Z clearance above the bed, clamps, ... + // Be sure you have this distance over your Z_MAX_POS in case. + +// Direction of endstops when homing; 1=MAX, -1=MIN +// :[-1,1] +#define X_HOME_DIR 1 // deltas always home to max +#define Y_HOME_DIR 1 +#define Z_HOME_DIR 1 + +// @section machine + +// The size of the print bed +#define X_BED_SIZE ((DELTA_PRINTABLE_RADIUS) * 2) +#define Y_BED_SIZE ((DELTA_PRINTABLE_RADIUS) * 2) + +// Travel limits (mm) after homing, corresponding to endstop positions. +#define X_MIN_POS -(DELTA_PRINTABLE_RADIUS) +#define Y_MIN_POS -(DELTA_PRINTABLE_RADIUS) +#define Z_MIN_POS 0 +#define X_MAX_POS DELTA_PRINTABLE_RADIUS +#define Y_MAX_POS DELTA_PRINTABLE_RADIUS +#define Z_MAX_POS MANUAL_Z_HOME_POS + +// If enabled, axes won't move below MIN_POS in response to movement commands. +#define MIN_SOFTWARE_ENDSTOPS +// If enabled, axes won't move above MAX_POS in response to movement commands. +#define MAX_SOFTWARE_ENDSTOPS + +/** + * Filament Runout Sensor + * A mechanical or opto endstop is used to check for the presence of filament. + * + * RAMPS-based boards use SERVO3_PIN. + * For other boards you may need to define FIL_RUNOUT_PIN. + * By default the firmware assumes HIGH = has filament, LOW = ran out + */ +//#define FILAMENT_RUNOUT_SENSOR +#if ENABLED(FILAMENT_RUNOUT_SENSOR) + #define FIL_RUNOUT_INVERTING false // set to true to invert the logic of the sensor. + #define ENDSTOPPULLUP_FIL_RUNOUT // Uncomment to use internal pullup for filament runout pins if the sensor is defined. + #define FILAMENT_RUNOUT_SCRIPT "M600" +#endif + +//=========================================================================== +//=============================== Bed Leveling ============================== +//=========================================================================== +// @section bedlevel + +/** + * Choose one of the options below to enable G29 Bed Leveling. The parameters + * and behavior of G29 will change depending on your selection. + * + * If using a Probe for Z Homing, enable Z_SAFE_HOMING also! + * + * - AUTO_BED_LEVELING_3POINT + * Probe 3 arbitrary points on the bed (that aren't collinear) + * You specify the XY coordinates of all 3 points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_LINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_BILINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a mesh, best for large or uneven beds. + * + * - AUTO_BED_LEVELING_UBL (Unified Bed Leveling) + * A comprehensive bed leveling system combining the features and benefits + * of other systems. UBL also includes integrated Mesh Generation, Mesh + * Validation and Mesh Editing systems. Currently, UBL is only checked out + * for Cartesian Printers. That said, it was primarily designed to correct + * poor quality Delta Printers. If you feel adventurous and have a Delta, + * please post an issue if something doesn't work correctly. Initially, + * you will need to set a reduced bed size so you have a rectangular area + * to test on. + * + * - MESH_BED_LEVELING + * Probe a grid manually + * The result is a mesh, suitable for large or uneven beds. (See BILINEAR.) + * For machines without a probe, Mesh Bed Leveling provides a method to perform + * leveling in steps so you can manually adjust the Z height at each grid-point. + * With an LCD controller the process is guided step-by-step. + */ +//#define AUTO_BED_LEVELING_3POINT +//#define AUTO_BED_LEVELING_LINEAR +//#define AUTO_BED_LEVELING_BILINEAR +//#define AUTO_BED_LEVELING_UBL +//#define MESH_BED_LEVELING + +/** + * Enable detailed logging of G28, G29, M48, etc. + * Turn on with the command 'M111 S32'. + * NOTE: Requires a lot of PROGMEM! + */ +//#define DEBUG_LEVELING_FEATURE + +#if ENABLED(MESH_BED_LEVELING) || ENABLED(AUTO_BED_LEVELING_BILINEAR) || ENABLED(AUTO_BED_LEVELING_UBL) + // Gradually reduce leveling correction until a set height is reached, + // at which point movement will be level to the machine's XY plane. + // The height can be set with M420 Z + //#define ENABLE_LEVELING_FADE_HEIGHT + + // Set the boundaries for probing (where the probe can reach). + #define DELTA_PROBEABLE_RADIUS (DELTA_PRINTABLE_RADIUS - 10) + +#endif + +#if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Set the number of grid points per dimension. + // Works best with 5 or more points in each dimension. + #define GRID_MAX_POINTS_X 9 + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + #define LEFT_PROBE_BED_POSITION -(DELTA_PROBEABLE_RADIUS) + #define RIGHT_PROBE_BED_POSITION DELTA_PROBEABLE_RADIUS + #define FRONT_PROBE_BED_POSITION -(DELTA_PROBEABLE_RADIUS) + #define BACK_PROBE_BED_POSITION DELTA_PROBEABLE_RADIUS + + // The Z probe minimum outer margin (to validate G29 parameters). + #define MIN_PROBE_EDGE 10 + + // Probe along the Y axis, advancing X after each column + //#define PROBE_Y_FIRST + + #if ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Beyond the probed grid, continue the implied tilt? + // Default is to maintain the height of the nearest edge. + //#define EXTRAPOLATE_BEYOND_GRID + + // + // Experimental Subdivision of the grid by Catmull-Rom method. + // Synthesizes intermediate points to produce a more detailed mesh. + // + //#define ABL_BILINEAR_SUBDIVISION + #if ENABLED(ABL_BILINEAR_SUBDIVISION) + // Number of subdivisions between probe points + #define BILINEAR_SUBDIVISIONS 3 + #endif + + #endif + +#elif ENABLED(AUTO_BED_LEVELING_3POINT) + + // 3 arbitrary points to probe. + // A simple cross-product is used to estimate the plane of the bed. + #define ABL_PROBE_PT_1_X 15 + #define ABL_PROBE_PT_1_Y 180 + #define ABL_PROBE_PT_2_X 15 + #define ABL_PROBE_PT_2_Y 20 + #define ABL_PROBE_PT_3_X 170 + #define ABL_PROBE_PT_3_Y 20 + +#elif ENABLED(AUTO_BED_LEVELING_UBL) + + //=========================================================================== + //========================= Unified Bed Leveling ============================ + //=========================================================================== + + #define UBL_MESH_INSET 1 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 10 // Don't use more than 15 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + #define _PX(R,A) (R) * cos(RADIANS(A)) + #define _PY(R,A) (R) * sin(RADIANS(A)) + #define UBL_PROBE_PT_1_X _PX(DELTA_PROBEABLE_RADIUS, 0) // Probing points for 3-Point leveling of the mesh + #define UBL_PROBE_PT_1_Y _PY(DELTA_PROBEABLE_RADIUS, 0) + #define UBL_PROBE_PT_2_X _PX(DELTA_PROBEABLE_RADIUS, 120) + #define UBL_PROBE_PT_2_Y _PY(DELTA_PROBEABLE_RADIUS, 120) + #define UBL_PROBE_PT_3_X _PX(DELTA_PROBEABLE_RADIUS, 240) + #define UBL_PROBE_PT_3_Y _PY(DELTA_PROBEABLE_RADIUS, 240) + + #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation + #define UBL_MESH_EDIT_MOVES_Z // Sophisticated users prefer no movement of nozzle + +#elif ENABLED(MESH_BED_LEVELING) + + //=========================================================================== + //=================================== Mesh ================================== + //=========================================================================== + + #define MESH_INSET 10 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 3 // Don't use more than 7 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + //#define MESH_G28_REST_ORIGIN // After homing all axes ('G28' or 'G28 XYZ') rest Z at Z_MIN_POS + +#endif // BED_LEVELING + +/** + * Use the LCD controller for bed leveling + * Requires MESH_BED_LEVELING or PROBE_MANUALLY + */ +//#define LCD_BED_LEVELING + +#if ENABLED(LCD_BED_LEVELING) + #define MBL_Z_STEP 0.025 // Step size while manually probing Z axis. + #define LCD_PROBE_Z_RANGE 4 // Z Range centered on Z_MIN_POS for LCD Z adjustment +#endif + +// Add a menu item to move between bed corners for manual bed adjustment +//#define LEVEL_BED_CORNERS + +/** + * Commands to execute at the end of G29 probing. + * Useful to retract or move the Z probe out of the way. + */ +//#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) +#define BED_CENTER_AT_0_0 + +// Manually set the home position. Leave these undefined for automatic settings. +// For DELTA this is the top-center of the Cartesian print volume. +//#define MANUAL_X_HOME_POS 0 +//#define MANUAL_Y_HOME_POS 0 +#define MANUAL_Z_HOME_POS DELTA_HEIGHT // Distance between the nozzle to printbed after homing + +// Use "Z Safe Homing" to avoid homing with a Z probe outside the bed area. +// +// With this feature enabled: +// +// - 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). +// - 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 axis (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). +#endif + +// Delta only homes to Z +#define HOMING_FEEDRATE_Z (200*60) + +//============================================================================= +//============================= Additional Features =========================== +//============================================================================= + +// @section extras + +// +// EEPROM +// +// The microcontroller can store settings in the EEPROM, e.g. max velocity... +// M500 - stores parameters in EEPROM +// M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily). +// M502 - reverts to the default "factory settings". You still need to store them in EEPROM afterwards if you want to. +// +//#define EEPROM_SETTINGS // Enable for M500 and M501 commands +//#define DISABLE_M503 // Saves ~2700 bytes of PROGMEM. Disable for release! +#define EEPROM_CHITCHAT // Give feedback on EEPROM commands. Disable to save PROGMEM. + +// +// Host Keepalive +// +// When enabled Marlin will send a busy status message to the host +// every couple of seconds when it can't accept commands. +// +#define HOST_KEEPALIVE_FEATURE // Disable this if your host doesn't like keepalive messages +#define DEFAULT_KEEPALIVE_INTERVAL 2 // Number of seconds between "busy" messages. Set with M113. +#define BUSY_WHILE_HEATING // Some hosts require "busy" messages even during heating + +// +// M100 Free Memory Watcher +// +//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose + +// +// G20/G21 Inch mode support +// +//#define INCH_MODE_SUPPORT + +// +// M149 Set temperature units support +// +//#define TEMPERATURE_UNITS_SUPPORT + +// @section temperature + +// Preheat Constants +#define PREHEAT_1_TEMP_HOTEND 180 +#define PREHEAT_1_TEMP_BED 70 +#define PREHEAT_1_FAN_SPEED 255 // Value from 0 to 255 + +#define PREHEAT_2_TEMP_HOTEND 240 +#define PREHEAT_2_TEMP_BED 100 +#define PREHEAT_2_FAN_SPEED 255 // Value from 0 to 255 + +/** + * Nozzle Park -- EXPERIMENTAL + * + * Park the nozzle at the given XYZ position on idle or G27. + * + * The "P" parameter controls the action applied to the Z axis: + * + * P0 (Default) If Z is below park Z raise the nozzle. + * P1 Raise the nozzle always to Z-park height. + * P2 Raise the nozzle by Z-park amount, limited to Z_MAX_POS. + */ +//#define NOZZLE_PARK_FEATURE + +#if ENABLED(NOZZLE_PARK_FEATURE) + // Specify a park position as { X, Y, Z } + #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 } +#endif + +/** + * Clean Nozzle Feature -- EXPERIMENTAL + * + * Adds the G12 command to perform a nozzle cleaning process. + * + * Parameters: + * P Pattern + * S Strokes / Repetitions + * T Triangles (P1 only) + * + * Patterns: + * P0 Straight line (default). This process requires a sponge type material + * at a fixed bed location. "S" specifies strokes (i.e. back-forth motions) + * between the start / end points. + * + * P1 Zig-zag pattern between (X0, Y0) and (X1, Y1), "T" specifies the + * number of zig-zag triangles to do. "S" defines the number of strokes. + * Zig-zags are done in whichever is the narrower dimension. + * For example, "G12 P1 S1 T3" will execute: + * + * -- + * | (X0, Y1) | /\ /\ /\ | (X1, Y1) + * | | / \ / \ / \ | + * A | | / \ / \ / \ | + * | | / \ / \ / \ | + * | (X0, Y0) | / \/ \/ \ | (X1, Y0) + * -- +--------------------------------+ + * |________|_________|_________| + * T1 T2 T3 + * + * P2 Circular pattern with middle at NOZZLE_CLEAN_CIRCLE_MIDDLE. + * "R" specifies the radius. "S" specifies the stroke count. + * Before starting, the nozzle moves to NOZZLE_CLEAN_START_POINT. + * + * Caveats: The ending Z should be the same as starting Z. + * Attention: EXPERIMENTAL. G-code arguments may change. + * + */ +//#define NOZZLE_CLEAN_FEATURE + +#if ENABLED(NOZZLE_CLEAN_FEATURE) + // Default number of pattern repetitions + #define NOZZLE_CLEAN_STROKES 12 + + // Default number of triangles + #define NOZZLE_CLEAN_TRIANGLES 3 + + // Specify positions as { X, Y, Z } + #define NOZZLE_CLEAN_START_POINT { 30, 30, (Z_MIN_POS + 1)} + #define NOZZLE_CLEAN_END_POINT {100, 60, (Z_MIN_POS + 1)} + + // Circular pattern radius + #define NOZZLE_CLEAN_CIRCLE_RADIUS 6.5 + // Circular pattern circle fragments number + #define NOZZLE_CLEAN_CIRCLE_FN 10 + // Middle point of circle + #define NOZZLE_CLEAN_CIRCLE_MIDDLE NOZZLE_CLEAN_START_POINT + + // Moves the nozzle to the initial position + #define NOZZLE_CLEAN_GOBACK +#endif + +/** + * Print Job Timer + * + * Automatically start and stop the print job timer on M104/M109/M190. + * + * M104 (hotend, no wait) - high temp = none, low temp = stop timer + * M109 (hotend, wait) - high temp = start timer, low temp = stop timer + * M190 (bed, wait) - high temp = start timer, low temp = none + * + * The timer can also be controlled with the following commands: + * + * M75 - Start the print job timer + * M76 - Pause the print job timer + * M77 - Stop the print job timer + */ +#define PRINTJOB_TIMER_AUTOSTART + +/** + * Print Counter + * + * Track statistical data such as: + * + * - Total print jobs + * - Total successful print jobs + * - Total failed print jobs + * - Total time printing + * + * View the current statistics with M78. + */ +//#define PRINTCOUNTER + +//============================================================================= +//============================= LCD and SD support ============================ +//============================================================================= + +// @section lcd + +/** + * LCD LANGUAGE + * + * Select the language to display on the LCD. These languages are available: + * + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, + * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * tr, uk, zh_CN, zh_TW, test + * + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + */ +#define LCD_LANGUAGE en + +/** + * LCD Character Set + * + * Note: This option is NOT applicable to Graphical Displays. + * + * All character-based LCDs provide ASCII plus one of these + * language extensions: + * + * - JAPANESE ... the most common + * - WESTERN ... with more accented characters + * - CYRILLIC ... for the Russian language + * + * To determine the language extension installed on your controller: + * + * - Compile and upload with LCD_LANGUAGE set to 'test' + * - 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 + * + * :['JAPANESE', 'WESTERN', 'CYRILLIC'] + */ +#define DISPLAY_CHARSET_HD44780 JAPANESE + +/** + * LCD TYPE + * + * Enable ULTRA_LCD for a 16x2, 16x4, 20x2, or 20x4 character-based LCD. + * Enable DOGLCD for a 128x64 (ST7565R) Full Graphical Display. + * (These options will be enabled automatically for most displays.) + * + * IMPORTANT: The U8glib library is required for Full Graphic Display! + * https://github.com/olikraus/U8glib_Arduino + */ +//#define ULTRA_LCD // Character based +//#define DOGLCD // Full graphics display + +/** + * SD CARD + * + * 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 + +/** + * SD CARD: SPI SPEED + * + * Enable one of the following items for a slower SPI transfer speed. + * This may be required to resolve "volume init" errors. + */ +//#define SPI_SPEED SPI_HALF_SPEED +//#define SPI_SPEED SPI_QUARTER_SPEED +//#define SPI_SPEED SPI_EIGHTH_SPEED + +/** + * SD CARD: ENABLE CRC + * + * Use CRC checks and retries on the SD communication. + */ +//#define SD_CHECK_AND_RETRY + +// +// ENCODER SETTINGS +// +// This option overrides the default number of encoder pulses needed to +// produce one step. Should be increased for high-resolution encoders. +// +//#define ENCODER_PULSES_PER_STEP 1 + +// +// Use this option to override the number of step signals required to +// move between next/prev menu items. +// +//#define ENCODER_STEPS_PER_MENU_ITEM 5 + +/** + * Encoder Direction Options + * + * Test your encoder's behavior first with both options disabled. + * + * Reversed Value Edit and Menu Nav? Enable REVERSE_ENCODER_DIRECTION. + * Reversed Menu Navigation only? Enable REVERSE_MENU_DIRECTION. + * Reversed Value Editing only? Enable BOTH options. + */ + +// +// This option reverses the encoder direction everywhere. +// +// Set this option if CLOCKWISE causes values to DECREASE +// +//#define REVERSE_ENCODER_DIRECTION + +// +// This option reverses the encoder direction for navigating LCD menus. +// +// If CLOCKWISE normally moves DOWN this makes it go UP. +// If CLOCKWISE normally moves UP this makes it go DOWN. +// +//#define REVERSE_MENU_DIRECTION + +// +// Individual Axis Homing +// +// Add individual axis homing items (Home X, Home Y, and Home Z) to the LCD menu. +// +//#define INDIVIDUAL_AXIS_HOMING_MENU + +// +// SPEAKER/BUZZER +// +// If you have a speaker that can produce tones, enable it here. +// By default Marlin assumes you have a buzzer with a fixed frequency. +// +//#define SPEAKER + +// +// The duration and frequency for the UI feedback sound. +// Set these to 0 to disable audio feedback in the LCD menus. +// +// Note: Test audio output with the G-Code: +// M300 S P +// +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 +//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 + +// +// CONTROLLER TYPE: Standard +// +// Marlin supports a wide variety of controllers. +// Enable one of the following options to specify your controller. +// + +// +// ULTIMAKER Controller. +// +//#define ULTIMAKERCONTROLLER + +// +// ULTIPANEL as seen on Thingiverse. +// +//#define ULTIPANEL + +// +// PanelOne from T3P3 (via RAMPS 1.4 AUX2/AUX3) +// http://reprap.org/wiki/PanelOne +// +#define PANEL_ONE + +// +// MaKr3d Makr-Panel with graphic controller and SD support. +// http://reprap.org/wiki/MaKr3d_MaKrPanel +// +//#define MAKRPANEL + +// +// ReprapWorld Graphical LCD +// https://reprapworld.com/?products_details&products_id/1218 +// +//#define REPRAPWORLD_GRAPHICAL_LCD + +// +// Activate one of these if you have a Panucatt Devices +// Viki 2.0 or mini Viki with Graphic LCD +// http://panucatt.com +// +//#define VIKI2 +//#define miniVIKI + +// +// Adafruit ST7565 Full Graphic Controller. +// https://github.com/eboston/Adafruit-ST7565-Full-Graphic-Controller/ +// +//#define ELB_FULL_GRAPHIC_CONTROLLER + +// +// RepRapDiscount Smart Controller. +// http://reprap.org/wiki/RepRapDiscount_Smart_Controller +// +// Note: Usually sold with a white PCB. +// +//#define REPRAP_DISCOUNT_SMART_CONTROLLER + +// +// GADGETS3D G3D LCD/SD Controller +// http://reprap.org/wiki/RAMPS_1.3/1.4_GADGETS3D_Shield_with_Panel +// +// Note: Usually sold with a blue PCB. +// +//#define G3D_PANEL + +// +// RepRapDiscount FULL GRAPHIC Smart Controller +// http://reprap.org/wiki/RepRapDiscount_Full_Graphic_Smart_Controller +// +//#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER + +// +// MakerLab Mini Panel with graphic +// controller and SD support - http://reprap.org/wiki/Mini_panel +// +//#define MINIPANEL + +// +// RepRapWorld REPRAPWORLD_KEYPAD v1.1 +// http://reprapworld.com/?products_details&products_id=202&cPath=1591_1626 +// +// REPRAPWORLD_KEYPAD_MOVE_STEP sets how much should the robot move when a key +// is pressed, a value of 10.0 means 10mm per click. +// +//#define REPRAPWORLD_KEYPAD +//#define REPRAPWORLD_KEYPAD_MOVE_STEP 1.0 + +// +// RigidBot Panel V1.0 +// http://www.inventapart.com/ +// +//#define RIGIDBOT_PANEL + +// +// BQ LCD Smart Controller shipped by +// default with the BQ Hephestos 2 and Witbox 2. +// +//#define BQ_LCD_SMART_CONTROLLER + +// +// Cartesio UI +// http://mauk.cc/webshop/cartesio-shop/electronics/user-interface +// +//#define CARTESIO_UI + +// +// ANET_10 Controller supported displays. +// +//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. + // This LCD is known to be susceptible to electrical interference + // which scrambles the display. Pressing any button clears it up. +//#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 + // A clone of the RepRapDiscount full graphics display but with + // different pins/wiring (see pins_ANET_10.h). + +// +// LCD for Melzi Card with Graphical LCD +// +//#define LCD_FOR_MELZI + +// +// CONTROLLER TYPE: I2C +// +// Note: These controllers require the installation of Arduino's LiquidCrystal_I2C +// library. For more info: https://github.com/kiyoshigawa/LiquidCrystal_I2C +// + +// +// Elefu RA Board Control Panel +// http://www.elefu.com/index.php?route=product/product&product_id=53 +// +//#define RA_CONTROL_PANEL + +// +// Sainsmart YW Robot (LCM1602) LCD Display +// +// Note: This controller requires F.Malpartida's LiquidCrystal_I2C library +// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home +// +//#define LCD_I2C_SAINSMART_YWROBOT + +// +// Generic LCM1602 LCD adapter +// +//#define LCM1602 + +// +// PANELOLU2 LCD with status LEDs, +// separate encoder and click inputs. +// +// Note: This controller requires Arduino's LiquidTWI2 library v1.2.3 or later. +// For more info: https://github.com/lincomatic/LiquidTWI2 +// +// Note: The PANELOLU2 encoder click input can either be directly connected to +// a pin (if BTN_ENC defined to != -1) or read through I2C (when BTN_ENC == -1). +// +//#define LCD_I2C_PANELOLU2 + +// +// Panucatt VIKI LCD with status LEDs, +// integrated click & L/R/U/D buttons, separate encoder inputs. +// +//#define LCD_I2C_VIKI + +// +// SSD1306 OLED full graphics generic display +// +//#define U8GLIB_SSD1306 + +// +// SAV OLEd LCD module support using either SSD1306 or SH1106 based LCD modules +// +//#define SAV_3DGLCD +#if ENABLED(SAV_3DGLCD) + //#define U8GLIB_SSD1306 + #define U8GLIB_SH1106 +#endif + +// +// CONTROLLER TYPE: Shift register panels +// +// 2 wire Non-latching LCD SR from https://goo.gl/aJJ4sH +// LCD configuration: http://reprap.org/wiki/SAV_3D_LCD +// +//#define SAV_3DLCD + +// +// TinyBoy2 128x64 OLED / Encoder Panel +// +//#define OLED_PANEL_TINYBOY2 + +// +// Makeboard 3D Printer Parts 3D Printer Mini Display 1602 Mini Controller +// https://www.aliexpress.com/item/Micromake-Makeboard-3D-Printer-Parts-3D-Printer-Mini-Display-1602-Mini-Controller-Compatible-with-Ramps-1/32765887917.html +// +//#define MAKEBOARD_MINI_2_LINE_DISPLAY_1602 + +// +// MKS MINI12864 with graphic controller and SD support +// http://reprap.org/wiki/MKS_MINI_12864 +// +//#define MKS_MINI_12864 + +// +// Factory display for Creality CR-10 +// https://www.aliexpress.com/item/Universal-LCD-12864-3D-Printer-Display-Screen-With-Encoder-For-CR-10-CR-7-Model/32833148327.html +// +// This is RAMPS-compatible using a single 10-pin connector. +// (For CR-10 owners who want to replace the Melzi Creality board but retain the display) +// +//#define CR10_STOCKDISPLAY + +// +// MKS OLED 1.3" 128 × 64 FULL GRAPHICS CONTROLLER +// http://reprap.org/wiki/MKS_12864OLED +// +// Tiny, but very sharp OLED display +// +//#define MKS_12864OLED + +//============================================================================= +//=============================== Extra Features ============================== +//============================================================================= + +// @section extras + +// Increase the FAN PWM frequency. Removes the PWM noise but increases heating in the FET/Arduino +//#define FAST_PWM_FAN + +// Use software PWM to drive the fan, as for the heaters. This uses a very low frequency +// which is not as annoying as with the hardware PWM. On the other hand, if this frequency +// is too low, you should also increment SOFT_PWM_SCALE. +//#define FAN_SOFT_PWM + +// Incrementing this by 1 will double the software PWM frequency, +// affecting heaters, and the fan if FAN_SOFT_PWM is enabled. +// However, control resolution will be halved for each increment; +// at zero value, there are 128 effective control positions. +#define SOFT_PWM_SCALE 0 + +// If SOFT_PWM_SCALE is set to a value higher than 0, dithering can +// be used to mitigate the associated resolution loss. If enabled, +// some of the PWM cycles are stretched so on average the desired +// duty cycle is attained. +//#define SOFT_PWM_DITHER + +// Temperature status LEDs that display the hotend and bed temperature. +// If all hotends, bed temperature, and target temperature are under 54C +// then the BLUE led is on. Otherwise the RED led is on. (1C hysteresis) +//#define TEMP_STAT_LEDS + +// M240 Triggers a camera by emulating a Canon RC-1 Remote +// Data from: http://www.doc-diy.net/photo/rc-1_hacked/ +//#define PHOTOGRAPH_PIN 23 + +// 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 + +// Support for BlinkM/CyzRgb +//#define BLINKM + +// Support for PCA9632 PWM LED driver +//#define PCA9632 + +/** + * RGB LED / LED Strip Control + * + * Enable support for an RGB LED connected to 5V digital pins, or + * an RGB Strip connected to MOSFETs controlled by digital pins. + * + * 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 overall brightness parameters is also available + * + * *** CAUTION *** + * LED Strips require a MOFSET 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! + * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino + * cannot handle such current, separate 5V power supply must be used + * *** CAUTION *** + * + * LED type. This options are mutualy exclusive. Uncomment only one. + * + */ +//#define RGB_LED +//#define RGBW_LED + +#if ENABLED(RGB_LED) || ENABLED(RGBW_LED) + #define RGB_LED_R_PIN 34 + #define RGB_LED_G_PIN 43 + #define RGB_LED_B_PIN 35 + #define RGB_LED_W_PIN -1 +#endif + +// 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 (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) + #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip + #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time + #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + //#define NEOPIXEL_STARTUP_TEST // Cycle through colors at startup +#endif + +/** + * Printer Event LEDs + * + * During printing, the LEDs will reflect the printer status: + * + * - Gradually change from blue to violet as the heated bed gets to target temp + * - Gradually change from violet to red as the hotend gets to temperature + * - Change to white to illuminate work surface + * - Change to green once print has finished + * - Turn off after the print has finished and the user has pushed a button + */ +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) + #define PRINTER_EVENT_LEDS +#endif + +/*********************************************************************\ +* R/C SERVO support +* Sponsored by TrinityLabs, Reworked by codexmas +**********************************************************************/ + +// Number of servos +// +// If you select a configuration below, this will receive a default value and does not need to be set manually +// set it manually if you have more servos than extruders and wish to manually control some +// leaving it undefined or defining as 0 will disable the servo subsystem +// If unsure, leave commented / disabled +// +//#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command + +// Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. +// 300ms is a good value but you can try less delay. +// If the servo can't reach the requested position, increase it. +#define SERVO_DELAY { 300 } + +// Servo deactivation +// +// With this option servos are powered only during movement, then turned off to prevent jitter. +//#define DEACTIVATE_SERVOS_AFTER_MOVE + +/** + * Filament Width Sensor + * + * Measures the filament width in real-time and adjusts + * flow rate to compensate for any irregularities. + * + * Also allows the measured filament diameter to set the + * extrusion rate, so the slicer only has to specify the + * volume. + * + * Only a single extruder is supported at this time. + * + * 34 RAMPS_14 : Analog input 5 on the AUX2 connector + * 81 PRINTRBOARD : Analog input 2 on the Exp1 connector (version B,C,D,E) + * 301 RAMBO : Analog input 3 + * + * Note: May require analog pins to be defined for other boards. + */ +//#define FILAMENT_WIDTH_SENSOR + +#define DEFAULT_NOMINAL_FILAMENT_DIA 3.00 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. + +#if ENABLED(FILAMENT_WIDTH_SENSOR) + #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) + #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber + + #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading + #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading + #define MAX_MEASUREMENT_DELAY 20 // (bytes) Buffer size for stored measurements (1 byte per cm). Must be larger than MEASUREMENT_DELAY_CM. + + #define DEFAULT_MEASURED_FILAMENT_DIA DEFAULT_NOMINAL_FILAMENT_DIA // Set measured to nominal initially + + // Display filament width on the LCD status line. Status messages will expire after 5 seconds. + //#define FILAMENT_LCD_DISPLAY +#endif + +#endif // CONFIGURATION_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/delta/kossel_mini/Configuration_adv.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/delta/kossel_mini/Configuration_adv.h new file mode 100644 index 00000000..b7c896df --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/delta/kossel_mini/Configuration_adv.h @@ -0,0 +1,1426 @@ +/** + * 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 . + * + */ + +/** + * Configuration_adv.h + * + * Advanced settings. + * Only change these if you know exactly what you're doing. + * Some of these settings can damage your printer if improperly set! + * + * Basic settings can be found in Configuration.h + * + */ +#ifndef CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H_VERSION 010100 + +// @section temperature + +//=========================================================================== +//=============================Thermal Settings ============================ +//=========================================================================== + +#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 + #endif +#endif + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * The solution: Once the temperature reaches the target, start observing. + * If the temperature stays too far below the target (hysteresis) for too long (period), + * the firmware will halt the machine as a safety precaution. + * + * If you get false positives for "Thermal Runaway" increase THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD + */ +#if ENABLED(THERMAL_PROTECTION_HOTENDS) + #define THERMAL_PROTECTION_PERIOD 40 // Seconds + #define THERMAL_PROTECTION_HYSTERESIS 4 // Degrees Celsius + + /** + * Whenever an M104 or M109 increases the target temperature the firmware will wait for the + * WATCH_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get false positives for "Heating failed" increase WATCH_TEMP_PERIOD and/or decrease WATCH_TEMP_INCREASE + * WATCH_TEMP_INCREASE should not be below 2. + */ + #define WATCH_TEMP_PERIOD 20 // Seconds + #define WATCH_TEMP_INCREASE 2 // Degrees Celsius +#endif + +/** + * Thermal Protection parameters for the bed are just as above for hotends. + */ +#if ENABLED(THERMAL_PROTECTION_BED) + #define THERMAL_PROTECTION_BED_PERIOD 20 // Seconds + #define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius + + /** + * Whenever an M140 or M190 increases the target temperature the firmware will wait for the + * WATCH_BED_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_BED_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get too many "Heating failed" errors, increase WATCH_BED_TEMP_PERIOD and/or decrease + * WATCH_BED_TEMP_INCREASE. (WATCH_BED_TEMP_INCREASE should not be below 2.) + */ + #define WATCH_BED_TEMP_PERIOD 60 // Seconds + #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius +#endif + +#if ENABLED(PIDTEMP) + // this adds an experimental additional term to the heating power, proportional to the extrusion speed. + // if Kc is chosen well, the additional required power due to increased melting should be compensated. + //#define PID_EXTRUSION_SCALING + #if ENABLED(PID_EXTRUSION_SCALING) + #define DEFAULT_Kc (100) //heating power=Kc*(e_speed) + #define LPQ_MAX_LEN 50 + #endif +#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 + */ +#define AUTOTEMP +#if ENABLED(AUTOTEMP) + #define AUTOTEMP_OLDWEIGHT 0.98 +#endif + +// Show Temperature ADC value +// Enable for M105 to include ADC values read from temperature sensors. +//#define SHOW_TEMP_ADC_VALUES + +/** + * High Temperature Thermistor Support + * + * Thermistors able to support high temperature tend to have a hard time getting + * good readings at room and lower temperatures. This means HEATER_X_RAW_LO_TEMP + * will probably be caught when the heating element first turns on during the + * preheating process, which will trigger a min_temp_error as a safety measure + * and force stop everything. + * To circumvent this limitation, we allow for a preheat time (during which, + * min_temp_error won't be triggered) and add a min_temp buffer to handle + * aberrant readings. + * + * If you want to enable this feature for your hotend thermistor(s) + * uncomment and set values > 0 in the constants below + */ + +// The number of consecutive low temperature errors that can occur +// before a min_temp_error is triggered. (Shouldn't be more than 10.) +//#define MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED 0 + +// The number of milliseconds a hotend will preheat before starting to check +// the temperature. This value should NOT be set to the time it takes the +// hot end to reach the target temperature, but the time it takes to reach +// the minimum temperature your thermistor can read. The lower the better/safer. +// This shouldn't need to be more than 30 seconds (30000) +//#define MILLISECONDS_PREHEAT_TIME 0 + +// @section extruder + +// Extruder runout prevention. +// If the machine is idle and the temperature over MINTEMP +// then extrude some filament every couple of SECONDS. +//#define EXTRUDER_RUNOUT_PREVENT +#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_EXTRUDE 5 // mm +#endif + +// @section temperature + +//These defines help to calibrate the AD595 sensor in case you get wrong temperature measurements. +//The measured temperature is defined as "actualTemp = (measuredTemp * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET" +#define TEMP_SENSOR_AD595_OFFSET 0.0 +#define TEMP_SENSOR_AD595_GAIN 1.0 + +/** + * 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. + */ +//#define USE_CONTROLLER_FAN +#if ENABLED(USE_CONTROLLER_FAN) + //#define CONTROLLER_FAN_PIN FAN1_PIN // 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 +#endif + +// When first starting the main fan, run it at full speed for the +// given number of milliseconds. This gets the fan spinning reliably +// before setting a PWM value. (Does not work with software PWM for fan on Sanguinololu) +//#define FAN_KICKSTART_TIME 100 + +// This defines the minimal speed for the main fan, run in PWM mode +// to enable uncomment and set minimal PWM speed for reliable running (1-255) +// if fan speed is [1 - (FAN_MIN_PWM-1)] it is set to FAN_MIN_PWM +//#define FAN_MIN_PWM 50 + +// @section extruder + +/** + * Extruder cooling fans + * + * Extruder auto fans automatically turn on when their extruders' + * temperatures go above EXTRUDER_AUTO_FAN_TEMPERATURE. + * + * Your board's pins file specifies the recommended pins. Override those here + * or set to -1 to disable completely. + * + * Multiple extruders can be assigned to the same pin in which case + * the fan will turn on when any selected extruder is above the threshold. + */ +#define E0_AUTO_FAN_PIN -1 +#define E1_AUTO_FAN_PIN -1 +#define E2_AUTO_FAN_PIN -1 +#define E3_AUTO_FAN_PIN -1 +#define E4_AUTO_FAN_PIN -1 +#define EXTRUDER_AUTO_FAN_TEMPERATURE 50 +#define EXTRUDER_AUTO_FAN_SPEED 255 // == full speed + +/** + * Part-Cooling Fan Multiplexer + * + * This feature allows you to digitally multiplex the fan output. + * The multiplexer is automatically switched at tool-change. + * Set FANMUX[012]_PINs below for up to 2, 4, or 8 multiplexed fans. + */ +#define FANMUX0_PIN -1 +#define FANMUX1_PIN -1 +#define FANMUX2_PIN -1 + +/** + * M355 Case Light on-off / brightness + */ +//#define CASE_LIGHT_ENABLE +#if ENABLED(CASE_LIGHT_ENABLE) + //#define CASE_LIGHT_PIN 4 // Override the default pin if needed + #define INVERT_CASE_LIGHT false // Set true if Case Light is ON when pin is LOW + #define CASE_LIGHT_DEFAULT_ON true // Set default power-up state on + #define CASE_LIGHT_DEFAULT_BRIGHTNESS 105 // Set default power-up brightness (0-255, requires PWM pin) + //#define MENU_ITEM_CASE_LIGHT // Add a Case Light option to the LCD main menu +#endif + +//=========================================================================== +//============================ Mechanical Settings ========================== +//=========================================================================== + +// @section homing + +// If you want endstops to stay on (by default) even when not homing +// enable this option. Override at any time with M120, M121. +//#define ENDSTOPS_ALWAYS_ON_DEFAULT + +// @section extras + +//#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. + +// Dual X Steppers +// Uncomment this option to drive two X axis motors. +// The next unused E driver will be assigned to the second X stepper. +//#define X_DUAL_STEPPER_DRIVERS +#if ENABLED(X_DUAL_STEPPER_DRIVERS) + // Set true if the two X motors need to rotate in opposite directions + #define INVERT_X2_VS_X_DIR true +#endif + +// Dual Y Steppers +// Uncomment this option to drive two Y axis motors. +// The next unused E driver will be assigned to the second Y stepper. +//#define Y_DUAL_STEPPER_DRIVERS +#if ENABLED(Y_DUAL_STEPPER_DRIVERS) + // Set true if the two Y motors need to rotate in opposite directions + #define INVERT_Y2_VS_Y_DIR true +#endif + +// A single Z stepper driver is usually used to drive 2 stepper motors. +// Uncomment this option to use a separate stepper driver for each Z axis motor. +// The next unused E driver will be assigned to the second Z stepper. +//#define Z_DUAL_STEPPER_DRIVERS + +#if ENABLED(Z_DUAL_STEPPER_DRIVERS) + + // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper. + // That way the machine is capable to align the bed during home, since both Z steppers are homed. + // There is also an implementation of M666 (software endstops adjustment) to this feature. + // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed. + // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2. + // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive. + // Play a little bit with small adjustments (0.5mm) and check the behaviour. + // The M119 (endstops report) will start reporting the Z2 Endstop as well. + + //#define Z_DUAL_ENDSTOPS + + #if ENABLED(Z_DUAL_ENDSTOPS) + #define Z2_USE_ENDSTOP _XMAX_ + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 // Use M666 to determine/test this value + #endif + +#endif // Z_DUAL_STEPPER_DRIVERS + +// Enable this for dual x-carriage printers. +// A dual x-carriage design has the advantage that the inactive extruder can be parked which +// prevents hot-end ooze contaminating the print. It also reduces the weight of each x-carriage +// allowing faster printing speeds. Connect your X2 stepper to the first unused E plug. +//#define DUAL_X_CARRIAGE +#if ENABLED(DUAL_X_CARRIAGE) + // Configuration for second X-carriage + // Note: the first x-carriage is defined as the x-carriage which homes to the minimum endstop; + // the second x-carriage always homes to the maximum endstop. + #define X2_MIN_POS 80 // set minimum to ensure second x-carriage doesn't hit the parked first X-carriage + #define X2_MAX_POS 353 // set maximum to the distance between toolheads when both heads are homed + #define X2_HOME_DIR 1 // the second X-carriage always homes to the maximum endstop position + #define X2_HOME_POS X2_MAX_POS // default home position is the maximum carriage position + // However: In this mode the HOTEND_OFFSET_X value for the second extruder provides a software + // override for X2_HOME_POS. This also allow recalibration of the distance between the two endstops + // without modifying the firmware (through the "M218 T1 X???" command). + // Remember: you should set the second extruder x-offset to 0 in your slicer. + + // There are a few selectable movement modes for dual x-carriages using M605 S + // Mode 0 (DXC_FULL_CONTROL_MODE): Full control. The slicer has full control over both x-carriages and can achieve optimal travel results + // as long as it supports dual x-carriages. (M605 S0) + // Mode 1 (DXC_AUTO_PARK_MODE) : Auto-park mode. The firmware will automatically park and unpark the x-carriages on tool changes so + // that additional slicer support is not required. (M605 S1) + // Mode 2 (DXC_DUPLICATION_MODE) : Duplication mode. The firmware will transparently make the second x-carriage and extruder copy all + // actions of the first x-carriage. This allows the printer to print 2 arbitrary items at + // once. (2nd extruder x offset and temp offset are set using: M605 S2 [Xnnn] [Rmmm]) + + // This is the default power-up mode which can be later using M605. + #define DEFAULT_DUAL_X_CARRIAGE_MODE DXC_FULL_CONTROL_MODE + + // Default settings in "Auto-park Mode" + #define TOOLCHANGE_PARK_ZLIFT 0.2 // the distance to raise Z axis when parking an extruder + #define TOOLCHANGE_UNPARK_ZLIFT 1 // the distance to raise Z axis when unparking an extruder + + // Default x offset in duplication mode (typically set to half print bed width) + #define DEFAULT_DUPLICATION_X_OFFSET 100 + +#endif // DUAL_X_CARRIAGE + +// 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. +//#define EXT_SOLENOID + +// @section homing + +//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +#define X_HOME_BUMP_MM 5 +#define Y_HOME_BUMP_MM 5 +#define Z_HOME_BUMP_MM 5 // deltas need the same for all three axes +#define HOMING_BUMP_DIVISOR {10, 10, 10} // Re-Bump Speed Divisor (Divides the Homing Feedrate) +//#define QUICK_HOME //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially. + +// When G28 is called, this option will make Y home before X +//#define HOME_Y_BEFORE_X + +// @section machine + +#define AXIS_RELATIVE_MODES {false, false, false, false} + +// Allow duplication mode with a basic dual-nozzle extruder +//#define DUAL_NOZZLE_DUPLICATION_MODE + +// By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step. +#define INVERT_X_STEP_PIN false +#define INVERT_Y_STEP_PIN false +#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. +#define DEFAULT_STEPPER_DEACTIVE_TIME 60 +#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_E true + +#define DEFAULT_MINIMUMFEEDRATE 0.0 // minimum feedrate +#define DEFAULT_MINTRAVELFEEDRATE 0.0 + +//#define HOME_AFTER_DEACTIVATE // Require rehoming after steppers are deactivated + +// @section lcd + +#if ENABLED(ULTIPANEL) + #define MANUAL_FEEDRATE_XYZ 50*60 + #define MANUAL_FEEDRATE { MANUAL_FEEDRATE_XYZ, MANUAL_FEEDRATE_XYZ, MANUAL_FEEDRATE_XYZ, 60 } // Feedrates for manual moves along X, Y, Z, E from panel + #define ULTIPANEL_FEEDMULTIPLY // Comment to disable setting feedrate multiplier via encoder +#endif + +// @section extras + +// minimum time in microseconds that a movement needs to take if the buffer is emptied. +#define DEFAULT_MINSEGMENTTIME 20000 + +// If defined the movements slow down when the look ahead buffer is only half full +// (don't use SLOWDOWN with DELTA because DELTA generates hundreds of segments per second) +//#define SLOWDOWN + +// Frequency limit +// See nophead's blog for more info +// Not working O +//#define XY_FREQUENCY_LIMIT 15 + +// 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 +// if unwanted behavior is observed on a user's machine when running at very slow speeds. +#define MINIMUM_PLANNER_SPEED 0.05 // (mm/sec) + +// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU. +#define MICROSTEP_MODES {16,16,16,16,16} // [1,2,4,8,16] + +/** + * @section stepper motor current + * + * Some boards have a means of setting the stepper motor current via firmware. + * + * The power on motor currents are set by: + * PWM_MOTOR_CURRENT - used by MINIRAMBO & ULTIMAIN_2 + * known compatible chips: A4982 + * DIGIPOT_MOTOR_CURRENT - used by BQ_ZUM_MEGA_3D, RAMBO & SCOOVO_X9H + * known compatible chips: AD5206 + * DAC_MOTOR_CURRENT_DEFAULT - used by PRINTRBOARD_REVF & RIGIDBOARD_V2 + * known compatible chips: MCP4728 + * DIGIPOT_I2C_MOTOR_CURRENTS - used by 5DPRINT, AZTEEG_X3_PRO, MIGHTYBOARD_REVE + * known compatible chips: MCP4451, MCP4018 + * + * Motor currents can also be set by M907 - M910 and by the LCD. + * M907 - applies to all. + * M908 - BQ_ZUM_MEGA_3D, RAMBO, PRINTRBOARD_REVF, RIGIDBOARD_V2 & SCOOVO_X9H + * M909, M910 & LCD - only PRINTRBOARD_REVF & RIGIDBOARD_V2 + */ +//#define PWM_MOTOR_CURRENT { 1300, 1300, 1250 } // Values in milliamps +//#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 + +// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +//#define DIGIPOT_I2C +//#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster +#define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 +// Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS +#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=========================== +//=========================================================================== + +#define ENCODER_RATE_MULTIPLIER // If defined, certain menu edit operations automatically multiply the steps when the encoder is moved quickly +#define ENCODER_10X_STEPS_PER_SEC 75 // If the encoder steps per sec exceeds this value, multiply steps moved x10 to quickly advance the value +#define ENCODER_100X_STEPS_PER_SEC 160 // If the encoder steps per sec exceeds this value, multiply steps moved x100 to really quickly advance the value + +//#define CHDK 4 //Pin for triggering CHDK to take a picture see how to use it here http://captain-slow.dk/2014/03/09/3d-printing-timelapses/ +#define CHDK_DELAY 50 //How long in ms the pin should stay HIGH before going LOW again + +// @section lcd + +// Include a page of printer information in the LCD Main Menu +//#define LCD_INFO_MENU + +// Scroll a longer status message into view +//#define STATUS_MESSAGE_SCROLLING + +// On the Info Screen, display XY with one decimal place when possible +//#define LCD_DECIMAL_SMALL_XY + +// The timeout (in ms) to return to the status screen from sub-menus +//#define LCD_TIMEOUT_TO_STATUS 15000 + +#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 + + #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? + #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. + + #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. + // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. + // using: + //#define MENU_ADDAUTOSTART + + /** + * Sort SD file listings in alphabetical order. + * + * With this option enabled, items on SD cards will be sorted + * by name for easier navigation. + * + * By default... + * + * - Use the slowest -but safest- method for sorting. + * - Folders are sorted to the top. + * - The sort key is statically allocated. + * - No added G-code (M34) support. + * - 40 item sorting limit. (Items after the first 40 are unsorted.) + * + * SD sorting uses static allocation (as set by SDSORT_LIMIT), allowing the + * compiler to calculate the worst-case usage and throw an error if the SRAM + * limit is exceeded. + * + * - SDSORT_USES_RAM provides faster sorting via a static directory buffer. + * - SDSORT_USES_STACK does the same, but uses a local stack-based buffer. + * - SDSORT_CACHE_NAMES will retain the sorted file listing in RAM. (Expensive!) + * - SDSORT_DYNAMIC_RAM only uses RAM when the SD menu is visible. (Use with caution!) + */ + //#define SDCARD_SORT_ALPHA + + // SD Card Sorting options + #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_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. + #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #endif + + // Show a progress bar on HD44780 LCDs for SD printing + //#define LCD_PROGRESS_BAR + + #if ENABLED(LCD_PROGRESS_BAR) + // Amount of time (ms) to show the bar + #define PROGRESS_BAR_BAR_TIME 2000 + // Amount of time (ms) to show the status message + #define PROGRESS_BAR_MSG_TIME 3000 + // Amount of time (ms) to retain the status message (0=forever) + #define PROGRESS_MSG_EXPIRE 0 + // Enable this to show messages for MSG_TIME then hide them + //#define PROGRESS_MSG_ONCE + // Add a menu item to test the progress bar: + //#define LCD_PROGRESS_BAR_TEST + #endif + + // This allows hosts to request long names for files and folders with M33 + //#define LONG_FILENAME_HOST_SUPPORT + + // This option allows you to abort SD printing when any endstop is triggered. + // This feature must be enabled with "M540 S1" or from the LCD menu. + // To have any effect, endstops must be enabled during SD printing. + //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + +#endif // SDSUPPORT + +/** + * Additional options for Graphical Displays + * + * Use the optimizations here to improve printing performance, + * which can be adversely affected by graphical display drawing, + * especially when doing several short moves, and when printing + * on DELTA and SCARA machines. + * + * Some of these options may result in the display lagging behind + * controller events, as there is a trade-off between reliable + * printing performance versus fast display updates. + */ +#if ENABLED(DOGLCD) + // Enable to save many cycles by drawing a hollow frame on the Info Screen + #define XYZ_HOLLOW_FRAME + + // Enable to save many cycles by drawing a hollow frame on Menu Screens + #define MENU_HOLLOW_FRAME + + // A bigger font is available for edit items. Costs 3120 bytes of PROGMEM. + // 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. + // 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 +#endif // DOGLCD + +// @section safety + +// The hardware watchdog should reset the microcontroller disabling all outputs, +// in case the firmware gets stuck and doesn't do temperature regulation. +#define USE_WATCHDOG + +#if ENABLED(USE_WATCHDOG) + // If you have a watchdog reboot in an ArduinoMega2560 then the device will hang forever, as a watchdog reset will leave the watchdog on. + // The "WATCHDOG_RESET_MANUAL" goes around this by not using the hardware reset. + // However, THIS FEATURE IS UNSAFE!, as it will only work if interrupts are disabled. And the code could hang in an interrupt routine with interrupts disabled. + //#define WATCHDOG_RESET_MANUAL +#endif + +// @section lcd + +/** + * Babystepping enables movement of the axes by tiny increments without changing + * the current position values. This feature is used primarily to adjust the Z + * axis in the first layer of a print in real-time. + * + * Warning: Does not respect endstops! + */ +//#define BABYSTEPPING +#if ENABLED(BABYSTEPPING) + //#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 100 // Babysteps are very small. Increase for faster motion. + //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping + //#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen 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_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor + //#define BABYSTEP_ZPROBE_GFX_REVERSE // Reverses the direction of the CW/CCW indicators +#endif + +// @section extruder + +/** + * Implementation of linear pressure control + * + * Assumption: advance = k * (delta velocity) + * K=0 means advance disabled. + * See Marlin documentation for calibration instructions. + */ +//#define LIN_ADVANCE + +#if ENABLED(LIN_ADVANCE) + #define LIN_ADVANCE_K 75 + + /** + * Some Slicers produce Gcode with randomly jumping extrusion widths occasionally. + * For example within a 0.4mm perimeter it may produce a single segment of 0.05mm width. + * While this is harmless for normal printing (the fluid nature of the filament will + * close this very, very tiny gap), it throws off the LIN_ADVANCE pressure adaption. + * + * For this case LIN_ADVANCE_E_D_RATIO can be used to set the extrusion:distance ratio + * to a fixed value. Note that using a fixed ratio will lead to wrong nozzle pressures + * if the slicer is using variable widths or layer heights within one print! + * + * This option sets the default E:D ratio at startup. Use `M900` to override this value. + * + * Example: `M900 W0.4 H0.2 D1.75`, where: + * - W is the extrusion width in mm + * - H is the layer height in mm + * - D is the filament diameter in mm + * + * Example: `M900 R0.0458` to set the ratio directly. + * + * Set to 0 to auto-detect the ratio based on given Gcode G1 print moves. + * + * Slic3r (including Průša Control) produces Gcode compatible with the automatic mode. + * Cura (as of this writing) may produce Gcode incompatible with the automatic mode. + */ + #define LIN_ADVANCE_E_D_RATIO 0 // The calculated ratio (or 0) according to the formula W * H / ((D / 2) ^ 2 * PI) + // Example: 0.4 * 0.2 / ((1.75 / 2) ^ 2 * PI) = 0.033260135 +#endif + +// @section leveling + +// Default mesh area is an area with an inset margin on the print area. +// Below are the macros that are used to define the borders for the mesh area, +// made available here for specialized needs, ie dual extruder setup. +#if ENABLED(MESH_BED_LEVELING) + #define MESH_MIN_X MESH_INSET + #define MESH_MAX_X (X_BED_SIZE - (MESH_INSET)) + #define MESH_MIN_Y MESH_INSET + #define MESH_MAX_Y (Y_BED_SIZE - (MESH_INSET)) +#elif ENABLED(AUTO_BED_LEVELING_UBL) + #define UBL_MESH_MIN_X UBL_MESH_INSET + #define UBL_MESH_MAX_X (X_BED_SIZE - (UBL_MESH_INSET)) + #define UBL_MESH_MIN_Y UBL_MESH_INSET + #define UBL_MESH_MAX_Y (Y_BED_SIZE - (UBL_MESH_INSET)) + + // If this is defined, the currently active mesh will be saved in the + // current slot on M500. + #define UBL_SAVE_ACTIVE_ON_M500 +#endif + +// @section extras + +// +// G2/G3 Arc Support +// +#define ARC_SUPPORT // Disable this feature to save ~3226 bytes +#if ENABLED(ARC_SUPPORT) + #define MM_PER_ARC_SEGMENT 1 // Length of each arc segment + #define N_ARC_CORRECTION 25 // Number of intertpolated 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 +#endif + +// Support for G5 with XYZE destination and IJPQ offsets. Requires ~2666 bytes. +//#define BEZIER_CURVE_SUPPORT + +// G38.2 and G38.3 Probe Target +// Enable PROBE_DOUBLE_TOUCH if you want G38 to double touch +//#define G38_PROBE_TARGET +#if ENABLED(G38_PROBE_TARGET) + #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) +#endif + +// Moves (or segments) with fewer steps than this will be joined with the next move +#define MIN_STEPS_PER_SEGMENT 6 + +// The minimum pulse width (in µs) for stepping a stepper. +// Set this if you find stepping unreliable, or if using a very fast CPU. +#define MINIMUM_STEPPER_PULSE 0 // (µs) The smallest stepper pulse allowed + +// @section temperature + +// Control heater 0 and heater 1 in parallel. +//#define HEATERS_PARALLEL + +//=========================================================================== +//================================= Buffers ================================= +//=========================================================================== + +// @section hidden + +// 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, i.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 +#else + #define BLOCK_BUFFER_SIZE 16 // maximize block buffer +#endif + +// @section serial + +// The ASCII buffer for serial input +#define MAX_CMD_SIZE 96 +#define BUFSIZE 4 + +// Transmission to Host Buffer Size +// To save 386 bytes of PROGMEM (and TX_BUFFER_SIZE+3 bytes of RAM) set to 0. +// To buffer a simple "ok" you need 4 bytes. +// For ADVANCED_OK (M105) you need 32 bytes. +// For debug-echo: 128 bytes for the optimal speed. +// Other output doesn't need to be that speedy. +// :[0, 2, 4, 8, 16, 32, 64, 128, 256] +#define TX_BUFFER_SIZE 0 + +// Host Receive Buffer Size +// Without XON/XOFF flow control (see SERIAL_XON_XOFF below) 32 bytes should be enough. +// To use flow control, set this buffer size to at least 1024 bytes. +// :[0, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048] +//#define RX_BUFFER_SIZE 1024 + +#if RX_BUFFER_SIZE >= 1024 + // Enable to have the controller send XON/XOFF control characters to + // the host to signal the RX buffer is becoming full. + //#define SERIAL_XON_XOFF +#endif + +#if ENABLED(SDSUPPORT) + // Enable this option to collect and display the maximum + // RX queue usage after transferring a file to SD. + //#define SERIAL_STATS_MAX_RX_QUEUED + + // Enable this option to collect and display the number + // of dropped bytes after a file transfer to SD. + //#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! +//#define EMERGENCY_PARSER + +// Bad Serial-connections can miss a received command by sending an 'ok' +// Therefore some clients abort after 30 seconds in a timeout. +// Some other clients start sending commands while receiving a 'wait'. +// This "wait" is only sent when the buffer is empty. 1 second is a good value here. +//#define NO_TIMEOUTS 1000 // Milliseconds + +// Some clients will have this feature soon. This could make the NO_TIMEOUTS unnecessary. +//#define ADVANCED_OK + +// @section extras + +/** + * Firmware-based and LCD-controlled retract + * + * Add G10 / G11 commands for automatic firmware-based retract / recover. + * Use M207 and M208 to define parameters for retract / recover. + * + * Use M209 to enable or disable auto-retract. + * With auto-retract enabled, all G1 E moves within the set range + * will be converted to firmware-based retract/recover moves. + * + * Be sure to turn off auto-retract during filament change. + * + * Note that M207 / M208 / M209 settings are saved to EEPROM. + * + */ +//#define FWRETRACT // ONLY PARTIALLY TESTED +#if ENABLED(FWRETRACT) + #define MIN_AUTORETRACT 0.1 // When auto-retract is on, convert E moves of this length and over + #define MAX_AUTORETRACT 10.0 // Upper limit for auto-retract conversion + #define RETRACT_LENGTH 3 // Default retract length (positive mm) + #define RETRACT_LENGTH_SWAP 13 // Default swap retract length (positive mm), for extruder change + #define RETRACT_FEEDRATE 45 // Default feedrate for retracting (mm/s) + #define RETRACT_ZLIFT 0 // Default retract Z-lift + #define RETRACT_RECOVER_LENGTH 0 // Default additional recover length (mm, added to retract length when recovering) + #define RETRACT_RECOVER_LENGTH_SWAP 0 // Default additional swap recover length (mm, added to retract length when recovering from extruder change) + #define RETRACT_RECOVER_FEEDRATE 8 // Default feedrate for recovering from retraction (mm/s) + #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) +#endif + +/** + * Advanced Pause + * Experimental feature for filament change support and for parking the nozzle when paused. + * Adds the GCode M600 for initiating filament change. + * If PARK_HEAD_ON_PAUSE enabled, adds the GCode M125 to pause printing and park the nozzle. + * + * Requires an LCD display. + * This feature is required for the default FILAMENT_RUNOUT_SCRIPT. + */ +//#define ADVANCED_PAUSE_FEATURE +#if ENABLED(ADVANCED_PAUSE_FEATURE) + #define PAUSE_PARK_X_POS 3 // X position of hotend + #define PAUSE_PARK_Y_POS 3 // Y position of hotend + #define PAUSE_PARK_Z_ADD 10 // Z addition of hotend (lift) + #define PAUSE_PARK_XY_FEEDRATE 100 // X and Y axes feedrate in mm/s (also used for delta printers Z axis) + #define PAUSE_PARK_Z_FEEDRATE 5 // Z axis feedrate in mm/s (not used for delta printers) + #define PAUSE_PARK_RETRACT_FEEDRATE 60 // Initial retract feedrate in mm/s + #define PAUSE_PARK_RETRACT_LENGTH 2 // Initial retract in mm + // It is a short retract used immediately after print interrupt before move to filament exchange position + #define FILAMENT_CHANGE_UNLOAD_FEEDRATE 10 // Unload filament feedrate in mm/s - filament unloading can be fast + #define FILAMENT_CHANGE_UNLOAD_LENGTH 100 // Unload filament length from hotend in mm + // Longer length for bowden printers to unload filament from whole bowden tube, + // shorter length for printers without bowden to unload filament from extruder only, + // 0 to disable unloading for manual unloading + #define FILAMENT_CHANGE_LOAD_FEEDRATE 6 // Load filament feedrate in mm/s - filament loading into the bowden tube can be fast + #define FILAMENT_CHANGE_LOAD_LENGTH 0 // Load filament length over hotend in mm + // Longer length for bowden printers to fast load filament into whole bowden tube over the hotend, + // Short or zero length for printers without bowden where loading is not used + #define ADVANCED_PAUSE_EXTRUDE_FEEDRATE 3 // Extrude filament feedrate in mm/s - must be slower than load feedrate + #define ADVANCED_PAUSE_EXTRUDE_LENGTH 50 // Extrude filament length in mm after filament is loaded over the hotend, + // 0 to disable for manual extrusion + // Filament can be extruded repeatedly from the filament exchange menu to fill the hotend, + // or until outcoming filament color is not clear for filament color change + #define PAUSE_PARK_NOZZLE_TIMEOUT 45 // Turn off nozzle if user doesn't change filament within this time limit in seconds + #define FILAMENT_CHANGE_NUMBER_OF_ALERT_BEEPS 5 // Number of alert beeps before printer goes quiet + #define PAUSE_PARK_NO_STEPPER_TIMEOUT // Enable to have stepper motors hold position during filament change + // even if it takes longer than DEFAULT_STEPPER_DEACTIVE_TIME. + //#define PARK_HEAD_ON_PAUSE // Go to filament change position on pause, return to print position on resume + //#define HOME_BEFORE_FILAMENT_CHANGE // Ensure homing has been completed prior to parking for filament change +#endif + +// @section tmc + +/** + * Enable this section if you have TMC26X motor drivers. + * You will need to import the TMC26XStepper library into the Arduino IDE for this + * (https://github.com/trinamic/TMC26XStepper.git) + */ +//#define HAVE_TMCDRIVER + +#if ENABLED(HAVE_TMCDRIVER) + + //#define X_IS_TMC + //#define X2_IS_TMC + //#define Y_IS_TMC + //#define Y2_IS_TMC + //#define Z_IS_TMC + //#define Z2_IS_TMC + //#define E0_IS_TMC + //#define E1_IS_TMC + //#define E2_IS_TMC + //#define E3_IS_TMC + //#define E4_IS_TMC + + #define X_MAX_CURRENT 1000 // in mA + #define X_SENSE_RESISTOR 91 // in mOhms + #define X_MICROSTEPS 16 // number of microsteps + + #define X2_MAX_CURRENT 1000 + #define X2_SENSE_RESISTOR 91 + #define X2_MICROSTEPS 16 + + #define Y_MAX_CURRENT 1000 + #define Y_SENSE_RESISTOR 91 + #define Y_MICROSTEPS 16 + + #define Y2_MAX_CURRENT 1000 + #define Y2_SENSE_RESISTOR 91 + #define Y2_MICROSTEPS 16 + + #define Z_MAX_CURRENT 1000 + #define Z_SENSE_RESISTOR 91 + #define Z_MICROSTEPS 16 + + #define Z2_MAX_CURRENT 1000 + #define Z2_SENSE_RESISTOR 91 + #define Z2_MICROSTEPS 16 + + #define E0_MAX_CURRENT 1000 + #define E0_SENSE_RESISTOR 91 + #define E0_MICROSTEPS 16 + + #define E1_MAX_CURRENT 1000 + #define E1_SENSE_RESISTOR 91 + #define E1_MICROSTEPS 16 + + #define E2_MAX_CURRENT 1000 + #define E2_SENSE_RESISTOR 91 + #define E2_MICROSTEPS 16 + + #define E3_MAX_CURRENT 1000 + #define E3_SENSE_RESISTOR 91 + #define E3_MICROSTEPS 16 + + #define E4_MAX_CURRENT 1000 + #define E4_SENSE_RESISTOR 91 + #define E4_MICROSTEPS 16 + +#endif + +// @section TMC2130 + +/** + * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. + * + * You'll also need the TMC2130Stepper Arduino library + * (https://github.com/teemuatlut/TMC2130Stepper). + * + * To use TMC2130 stepper drivers in SPI mode connect your SPI2130 pins to + * the hardware SPI interface on your board and define the required CS pins + * in your `pins_MYBOARD.h` file. (e.g., RAMPS 1.4 uses AUX3 pins `X_CS_PIN 53`, `Y_CS_PIN 49`, etc.). + */ +//#define HAVE_TMC2130 + +#if ENABLED(HAVE_TMC2130) + + // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY + //#define X_IS_TMC2130 + //#define X2_IS_TMC2130 + //#define Y_IS_TMC2130 + //#define Y2_IS_TMC2130 + //#define Z_IS_TMC2130 + //#define Z2_IS_TMC2130 + //#define E0_IS_TMC2130 + //#define E1_IS_TMC2130 + //#define E2_IS_TMC2130 + //#define E3_IS_TMC2130 + //#define E4_IS_TMC2130 + + /** + * Stepper driver settings + */ + + #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 + #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current + #define INTERPOLATE 1 // Interpolate X/Y/Z_MICROSTEPS to 256 + + #define X_CURRENT 1000 // rms current in mA. Multiply by 1.41 for peak current. + #define X_MICROSTEPS 16 // 0..256 + + #define Y_CURRENT 1000 + #define Y_MICROSTEPS 16 + + #define Z_CURRENT 1000 + #define Z_MICROSTEPS 16 + + //#define X2_CURRENT 1000 + //#define X2_MICROSTEPS 16 + + //#define Y2_CURRENT 1000 + //#define Y2_MICROSTEPS 16 + + //#define Z2_CURRENT 1000 + //#define Z2_MICROSTEPS 16 + + //#define E0_CURRENT 1000 + //#define E0_MICROSTEPS 16 + + //#define E1_CURRENT 1000 + //#define E1_MICROSTEPS 16 + + //#define E2_CURRENT 1000 + //#define E2_MICROSTEPS 16 + + //#define E3_CURRENT 1000 + //#define E3_MICROSTEPS 16 + + //#define E4_CURRENT 1000 + //#define E4_MICROSTEPS 16 + + /** + * Use Trinamic's ultra quiet stepping mode. + * When disabled, Marlin will use spreadCycle stepping mode. + */ + #define STEALTHCHOP + + /** + * Let Marlin automatically control stepper current. + * This is still an experimental feature. + * Increase current every 5s by CURRENT_STEP until stepper temperature prewarn gets triggered, + * then decrease current by CURRENT_STEP until temperature prewarn is cleared. + * Adjusting starts from X/Y/Z/E_CURRENT but will not increase over AUTO_ADJUST_MAX + * 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. + * M906 S1 - Start adjusting current + * M906 S0 - Stop adjusting current + * M911 - Report stepper driver overtemperature pre-warn condition. + * M912 - Clear stepper driver overtemperature pre-warn condition flag. + */ + //#define AUTOMATIC_CURRENT_CONTROL + + #if ENABLED(AUTOMATIC_CURRENT_CONTROL) + #define CURRENT_STEP 50 // [mA] + #define AUTO_ADJUST_MAX 1300 // [mA], 1300mA_rms = 1840mA_peak + #define REPORT_CURRENT_CHANGE + #endif + + /** + * The driver will switch to spreadCycle when stepper speed is over HYBRID_THRESHOLD. + * This mode allows for faster movements at the expense of higher noise levels. + * STEALTHCHOP needs to be enabled. + * M913 X/Y/Z/E to live tune the setting + */ + //#define HYBRID_THRESHOLD + + #define X_HYBRID_THRESHOLD 100 // [mm/s] + #define X2_HYBRID_THRESHOLD 100 + #define Y_HYBRID_THRESHOLD 100 + #define Y2_HYBRID_THRESHOLD 100 + #define Z_HYBRID_THRESHOLD 4 + #define Z2_HYBRID_THRESHOLD 4 + #define E0_HYBRID_THRESHOLD 30 + #define E1_HYBRID_THRESHOLD 30 + #define E2_HYBRID_THRESHOLD 30 + #define E3_HYBRID_THRESHOLD 30 + #define E4_HYBRID_THRESHOLD 30 + + /** + * Use stallGuard2 to sense an obstacle and trigger an endstop. + * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. + * If used along with STEALTHCHOP, the movement will be louder when homing. This is normal. + * + * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. + * Higher values make the system LESS sensitive. + * Lower value make the system MORE sensitive. + * Too low values can lead to false positives, while too high values will collide the axis without triggering. + * It is advised to set X/Y_HOME_BUMP_MM to 0. + * M914 X/Y to live tune the setting + */ + //#define SENSORLESS_HOMING + + #if ENABLED(SENSORLESS_HOMING) + #define X_HOMING_SENSITIVITY 19 + #define Y_HOMING_SENSITIVITY 19 + #endif + + /** + * You can set your own advanced settings by filling in predefined functions. + * A list of available functions can be found on the library github page + * https://github.com/teemuatlut/TMC2130Stepper + * + * Example: + * #define TMC2130_ADV() { \ + * stepperX.diag0_temp_prewarn(1); \ + * stepperX.interpolate(0); \ + * } + */ + #define TMC2130_ADV() { } + +#endif // HAVE_TMC2130 + +// @section L6470 + +/** + * Enable this section if you have L6470 motor drivers. + * You need to import the L6470 library into the Arduino IDE for this. + * (https://github.com/ameyer/Arduino-L6470) + */ + +//#define HAVE_L6470DRIVER +#if ENABLED(HAVE_L6470DRIVER) + + //#define X_IS_L6470 + //#define X2_IS_L6470 + //#define Y_IS_L6470 + //#define Y2_IS_L6470 + //#define Z_IS_L6470 + //#define Z2_IS_L6470 + //#define E0_IS_L6470 + //#define E1_IS_L6470 + //#define E2_IS_L6470 + //#define E3_IS_L6470 + //#define E4_IS_L6470 + + #define X_MICROSTEPS 16 // number of microsteps + #define X_K_VAL 50 // 0 - 255, Higher values, are higher power. Be careful not to go too high + #define X_OVERCURRENT 2000 // maxc current in mA. If the current goes over this value, the driver will switch off + #define X_STALLCURRENT 1500 // current in mA where the driver will detect a stall + + #define X2_MICROSTEPS 16 + #define X2_K_VAL 50 + #define X2_OVERCURRENT 2000 + #define X2_STALLCURRENT 1500 + + #define Y_MICROSTEPS 16 + #define Y_K_VAL 50 + #define Y_OVERCURRENT 2000 + #define Y_STALLCURRENT 1500 + + #define Y2_MICROSTEPS 16 + #define Y2_K_VAL 50 + #define Y2_OVERCURRENT 2000 + #define Y2_STALLCURRENT 1500 + + #define Z_MICROSTEPS 16 + #define Z_K_VAL 50 + #define Z_OVERCURRENT 2000 + #define Z_STALLCURRENT 1500 + + #define Z2_MICROSTEPS 16 + #define Z2_K_VAL 50 + #define Z2_OVERCURRENT 2000 + #define Z2_STALLCURRENT 1500 + + #define E0_MICROSTEPS 16 + #define E0_K_VAL 50 + #define E0_OVERCURRENT 2000 + #define E0_STALLCURRENT 1500 + + #define E1_MICROSTEPS 16 + #define E1_K_VAL 50 + #define E1_OVERCURRENT 2000 + #define E1_STALLCURRENT 1500 + + #define E2_MICROSTEPS 16 + #define E2_K_VAL 50 + #define E2_OVERCURRENT 2000 + #define E2_STALLCURRENT 1500 + + #define E3_MICROSTEPS 16 + #define E3_K_VAL 50 + #define E3_OVERCURRENT 2000 + #define E3_STALLCURRENT 1500 + + #define E4_MICROSTEPS 16 + #define E4_K_VAL 50 + #define E4_OVERCURRENT 2000 + #define E4_STALLCURRENT 1500 + +#endif + +/** + * TWI/I2C BUS + * + * This feature is an EXPERIMENTAL feature so it shall not be used on production + * machines. Enabling this will allow you to send and receive I2C data from slave + * devices on the bus. + * + * ; Example #1 + * ; This macro send the string "Marlin" to the slave device with address 0x63 (99) + * ; It uses multiple M260 commands with one B arg + * M260 A99 ; Target slave address + * M260 B77 ; M + * M260 B97 ; a + * M260 B114 ; r + * M260 B108 ; l + * M260 B105 ; i + * M260 B110 ; n + * M260 S1 ; Send the current buffer + * + * ; Example #2 + * ; Request 6 bytes from slave device with address 0x63 (99) + * M261 A99 B5 + * + * ; Example #3 + * ; Example serial output of a M261 request + * echo:i2c-reply: from:99 bytes:5 data:hello + */ + +// @section i2cbus + +//#define EXPERIMENTAL_I2CBUS +#define I2C_SLAVE_ADDRESS 0 // Set a value from 8 to 127 to act as a slave + +// @section extras + +/** + * Spindle & Laser control + * + * Add the M3, M4, and M5 commands to turn the spindle/laser on and off, and + * to set spindle speed, spindle direction, and laser power. + * + * SuperPid is a router/spindle speed controller used in the CNC milling community. + * Marlin can be used to turn the spindle on and off. It can also be used to set + * the spindle speed from 5,000 to 30,000 RPM. + * + * 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. + */ +//#define SPINDLE_LASER_ENABLE +#if ENABLED(SPINDLE_LASER_ENABLE) + + #define SPINDLE_LASER_ENABLE_INVERT false // set to "true" if the on/off function is reversed + #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 // delay in milliseconds to allow the spindle/laser to come up to speed/power + #define SPINDLE_LASER_POWERDOWN_DELAY 5000 // delay in milliseconds to allow the spindle to stop + #define SPINDLE_DIR_CHANGE true // set to true if your spindle controller supports changing spindle direction + #define SPINDLE_INVERT_DIR false + #define SPINDLE_STOP_ON_DIR_CHANGE true // set to true if Marlin should stop the spindle before changing rotation direction + + /** + * The M3 & M4 commands use the following equation to convert PWM duty cycle to speed/power + * + * SPEED/POWER = PWM duty cycle * SPEED_POWER_SLOPE + SPEED_POWER_INTERCEPT + * where PWM duty cycle varies from 0 to 255 + * + * set the following for your controller (ALL MUST BE SET) + */ + + #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_SLOPE 0.3922 + //#define SPEED_POWER_INTERCEPT 0 + //#define SPEED_POWER_MIN 10 + //#define SPEED_POWER_MAX 100 // 0-100% +#endif + +/** + * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins + */ +//#define PINS_DEBUGGING + +/** + * Auto-report temperatures with M155 S + */ +#define AUTO_REPORT_TEMPERATURES + +/** + * Include capabilities in M115 output + */ +#define EXTENDED_CAPABILITIES_REPORT + +/** + * Volumetric extrusion default state + * 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. + */ +//#define VOLUMETRIC_DEFAULT_ON + +/** + * Enable this option for a leaner build of Marlin that removes all + * workspace offsets, simplifying coordinate transformations, leveling, etc. + * + * - M206 and M428 are disabled. + * - G92 will revert to its behavior from Marlin 1.0. + */ +//#define NO_WORKSPACE_OFFSETS + +/** + * 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. + * + * For clients that use a fixed-width font (like OctoPrint), leave this set to 1.0. + * Otherwise, adjust according to your client and font. + */ +#define PROPORTIONAL_FONT_RATIO 1.0 + +/** + * Spend 28 bytes of SRAM to optimize the GCode parser + */ +#define FASTER_GCODE_PARSER + +/** + * User-defined menu items that execute custom GCode + */ +//#define CUSTOM_USER_MENUS +#if ENABLED(CUSTOM_USER_MENUS) + #define USER_SCRIPT_DONE "M117 User Script Done" + #define USER_SCRIPT_AUDIBLE_FEEDBACK + //#define USER_SCRIPT_RETURN // Return to status screen after a script + + #define USER_DESC_1 "Home & UBL Info" + #define USER_GCODE_1 "G28\nG29 W" + + #define USER_DESC_2 "Preheat for PLA" + #define USER_GCODE_2 "M140 S" STRINGIFY(PREHEAT_1_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND) + + #define USER_DESC_3 "Preheat for ABS" + #define USER_GCODE_3 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND) + + #define USER_DESC_4 "Heat Bed/Home/Level" + #define USER_GCODE_4 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nG28\nG29" + + #define USER_DESC_5 "Home & Info" + #define USER_GCODE_5 "G28\nM503" +#endif + +/** + * Specify an action command to send to the host when the printer is killed. + * Will be sent in the form '//action:ACTION_ON_KILL', e.g. '//action:poweroff'. + * The host must be configured to handle the action command. + */ +//#define ACTION_ON_KILL "poweroff" + +//=========================================================================== +//====================== I2C Position Encoder Settings ====================== +//=========================================================================== + +/** + * I2C position encoders for closed loop control. + * Developed by Chris Barr at Aus3D. + * + * Wiki: http://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/ + * + * Reilabuild encoders have been modified to improve reliability. + */ + +//#define I2C_POSITION_ENCODERS +#if ENABLED(I2C_POSITION_ENCODERS) + + #define I2CPE_ENCODER_CNT 1 // The number of encoders installed; max of 5 + // encoders supported currently. + + #define I2CPE_ENC_1_ADDR I2CPE_PRESET_ADDR_X // I2C address of the encoder. 30-200. + #define I2CPE_ENC_1_AXIS X_AXIS // Axis the encoder module is installed on. _AXIS. + #define I2CPE_ENC_1_TYPE I2CPE_ENC_TYPE_LINEAR // Type of encoder: I2CPE_ENC_TYPE_LINEAR -or- + // I2CPE_ENC_TYPE_ROTARY. + #define I2CPE_ENC_1_TICKS_UNIT 2048 // 1024 for magnetic strips with 2mm poles; 2048 for + // 1mm poles. For linear encoders this is ticks / mm, + // for rotary encoders this is ticks / revolution. + //#define I2CPE_ENC_1_TICKS_REV (16 * 200) // Only needed for rotary encoders; number of stepper + // steps per full revolution (motor steps/rev * microstepping) + //#define I2CPE_ENC_1_INVERT // Invert the direction of axis travel. + #define I2CPE_ENC_1_EC_METHOD I2CPE_ECM_NONE // Type of error error correction. + #define I2CPE_ENC_1_EC_THRESH 0.10 // Threshold size for error (in mm) above which the + // printer will attempt to correct the error; errors + // smaller than this are ignored to minimize effects of + // measurement noise / latency (filter). + + #define I2CPE_ENC_2_ADDR I2CPE_PRESET_ADDR_Y // Same as above, but for encoder 2. + #define I2CPE_ENC_2_AXIS Y_AXIS + #define I2CPE_ENC_2_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_ENC_2_TICKS_UNIT 2048 + //#define I2CPE_ENC_2_TICKS_REV (16 * 200) + //#define I2CPE_ENC_2_INVERT + #define I2CPE_ENC_2_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_ENC_2_EC_THRESH 0.10 + + #define I2CPE_ENC_3_ADDR I2CPE_PRESET_ADDR_Z // Encoder 3. Add additional configuration options + #define I2CPE_ENC_3_AXIS Z_AXIS // as above, or use defaults below. + + #define I2CPE_ENC_4_ADDR I2CPE_PRESET_ADDR_E // Encoder 4. + #define I2CPE_ENC_4_AXIS E_AXIS + + #define I2CPE_ENC_5_ADDR 34 // Encoder 5. + #define I2CPE_ENC_5_AXIS E_AXIS + + // Default settings for encoders which are enabled, but without settings configured above. + #define I2CPE_DEF_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_DEF_ENC_TICKS_UNIT 2048 + #define I2CPE_DEF_TICKS_REV (16 * 200) + #define I2CPE_DEF_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_DEF_EC_THRESH 0.1 + + //#define I2CPE_ERR_THRESH_ABORT 100.0 // Threshold size for error (in mm) error on any given + // axis after which the printer will abort. Comment out to + // disable abort behaviour. + + #define I2CPE_TIME_TRUSTED 10000 // After an encoder fault, there must be no further fault + // for this amount of time (in ms) before the encoder + // is trusted again. + + /** + * Position is checked every time a new command is executed from the buffer but during long moves, + * this setting determines the minimum update time between checks. A value of 100 works well with + * error rolling average when attempting to correct only for skips and not for vibration. + */ + #define I2CPE_MIN_UPD_TIME_MS 100 // Minimum time in miliseconds between encoder checks. + + // Use a rolling average to identify persistant errors that indicate skips, as opposed to vibration and noise. + #define I2CPE_ERR_ROLLING_AVERAGE + +#endif // I2C_POSITION_ENCODERS + +/** + * MAX7219 Debug Matrix + * + * Add support for a low-cost 8x8 LED Matrix based on the Max7219 chip, which can be used as a status + * display. Requires 3 signal wires. Some useful debug options are included to demonstrate its usage. + * + * Fully assembled MAX7219 boards can be found on the internet for under $2(US). + * For example, see https://www.ebay.com/sch/i.html?_nkw=332349290049 + */ +//#define MAX7219_DEBUG +#if ENABLED(MAX7219_DEBUG) + #define MAX7219_CLK_PIN 64 // 77 on Re-ARM // Configuration of the 3 pins to control the display + #define MAX7219_DIN_PIN 57 // 78 on Re-ARM + #define MAX7219_LOAD_PIN 44 // 79 on Re-ARM + + /** + * Sample debug features + * If you add more debug displays, be careful to avoid conflicts! + */ + #define MAX7219_DEBUG_PRINTER_ALIVE // Blink corner LED of 8x8 matrix to show that the firmware is functioning + #define MAX7219_DEBUG_STEPPER_HEAD 3 // Show the stepper queue head position on this and the next LED matrix row + #define MAX7219_DEBUG_STEPPER_TAIL 5 // Show the stepper queue tail position on this and the next LED matrix row + + #define MAX7219_DEBUG_STEPPER_QUEUE 0 // Show the current stepper queue depth on this and the next LED matrix row + // If you experience stuttering, reboots, etc. this option can reveal how + // tweaks made to the configuration are affecting the printer in real-time. +#endif + +#endif // CONFIGURATION_ADV_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/delta/kossel_pro/Configuration.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/delta/kossel_pro/Configuration.h new file mode 100644 index 00000000..e564fa8e --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/delta/kossel_pro/Configuration.h @@ -0,0 +1,1819 @@ +/** + * 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 . + * + */ + +/** + * Example configuration file for OpenBeam Kossel Pro + */ + +/** + * Configuration.h + * + * Basic settings such as: + * + * - Type of electronics + * - Type of temperature sensor + * - Printer geometry + * - Endstop configuration + * - LCD controller + * - Extra features + * + * Advanced settings can be found in Configuration_adv.h + * + */ +#ifndef CONFIGURATION_H +#define CONFIGURATION_H +#define CONFIGURATION_H_VERSION 010100 + +//=========================================================================== +//============================= Getting Started ============================= +//=========================================================================== + +/** + * Here are some standard links for getting your machine calibrated: + * + * http://reprap.org/wiki/Calibration + * http://youtu.be/wAL9d7FgInk + * http://calculator.josefprusa.cz + * http://reprap.org/wiki/Triffid_Hunter%27s_Calibration_Guide + * http://www.thingiverse.com/thing:5573 + * https://sites.google.com/site/repraplogphase/calibration-of-your-reprap + * http://www.thingiverse.com/thing:298812 + */ + +//=========================================================================== +//============================= DELTA Printer =============================== +//=========================================================================== +// For a Delta printer start with one of the configuration files in the +// example_configurations/delta directory and customize for your machine. +// + +//=========================================================================== +//============================= SCARA Printer =============================== +//=========================================================================== +// For a SCARA printer start with the configuration files in +// example_configurations/SCARA and customize for your machine. +// + +// @section info + +// User-specified version info of this build to display in [Pronterface, etc] terminal window during +// startup. Implementation of an idea by Prof Braino to inform user that any changes made to this +// build by the user have been successfully uploaded into firmware. +#define STRING_CONFIG_H_AUTHOR "(none, default config)" // Who made the changes. +#define SHOW_BOOTSCREEN +#define STRING_SPLASH_LINE1 SHORT_BUILD_VERSION // will be shown during bootup in line 1 +#define STRING_SPLASH_LINE2 WEBSITE_URL // will be shown during bootup in line 2 + +// +// *** VENDORS PLEASE READ ***************************************************** +// +// Marlin now allow you to have a vendor boot image to be displayed on machine +// start. When SHOW_CUSTOM_BOOTSCREEN is defined Marlin will first show your +// custom boot image and then the default Marlin boot image is shown. +// +// We suggest for you to take advantage of this new feature and keep the Marlin +// boot image unmodified. For an example have a look at the bq Hephestos 2 +// example configuration folder. +// +//#define SHOW_CUSTOM_BOOTSCREEN +// @section machine + +/** + * Select which serial port on the board will be used for communication with the host. + * This allows the connection of wireless adapters (for instance) to non-default port pins. + * Serial port 0 is always used by the Arduino bootloader regardless of this setting. + * + * :[0, 1, 2, 3, 4, 5, 6, 7] + */ +#define SERIAL_PORT 0 + +/** + * This setting determines the communication speed of the printer. + * + * 250000 works in most cases, but you might try a lower speed if + * you commonly experience drop-outs during host printing. + * You may try up to 1000000 to speed up SD file transfer. + * + * :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000] + */ +#define BAUDRATE 115200 + +// Enable the Bluetooth serial interface on AT90USB devices +//#define BLUETOOTH + +// The following define selects which electronics board you have. +// Please choose the name from boards.h that matches your setup +#ifndef MOTHERBOARD + #define MOTHERBOARD BOARD_BRAINWAVE_PRO +#endif + +// Optional custom name for your RepStrap or other custom machine +// Displayed in the LCD "Ready" message +#define CUSTOM_MACHINE_NAME "Kossel Pro" + +// Define this to set a unique identifier for this printer, (Used by some programs to differentiate between machines) +// You can use an online service to generate a random UUID. (eg http://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] +#define EXTRUDERS 1 + +// For Cyclops or any "multi-extruder" that shares a single nozzle. +//#define SINGLENOZZLE + +/** + * Průša MK2 Single Nozzle Multi-Material Multiplexer, and variants. + * + * This device allows one stepper driver on a control board to drive + * two to eight stepper motors, one at a time, in a manner suitable + * for extruders. + * + * This option only allows the multiplexer to switch on tool-change. + * Additional options to configure custom E moves are pending. + */ +//#define MK2_MULTIPLEXER +#if ENABLED(MK2_MULTIPLEXER) + // Override the default DIO selector pins here, if needed. + // Some pins files may provide defaults for these pins. + //#define E_MUX0_PIN 40 // Always Required + //#define E_MUX1_PIN 42 // Needed for 3 to 8 steppers + //#define E_MUX2_PIN 44 // Needed for 5 to 8 steppers +#endif + +// A dual extruder that uses a single stepper motor +//#define SWITCHING_EXTRUDER +#if ENABLED(SWITCHING_EXTRUDER) + #define SWITCHING_EXTRUDER_SERVO_NR 0 + #define SWITCHING_EXTRUDER_SERVO_ANGLES { 0, 90 } // Angles for E0, E1[, E2, E3] + #if EXTRUDERS > 3 + #define SWITCHING_EXTRUDER_E23_SERVO_NR 1 + #endif +#endif + +// A dual-nozzle that uses a servomotor to raise/lower one of the nozzles +//#define SWITCHING_NOZZLE +#if ENABLED(SWITCHING_NOZZLE) + #define SWITCHING_NOZZLE_SERVO_NR 0 + #define SWITCHING_NOZZLE_SERVO_ANGLES { 0, 90 } // Angles for E0, E1 + //#define HOTEND_OFFSET_Z { 0.0, 0.0 } +#endif + +/** + * Two separate X-carriages with extruders that connect to a moving part + * via a magnetic docking mechanism. Requires SOL1_PIN and SOL2_PIN. + */ +//#define PARKING_EXTRUDER +#if ENABLED(PARKING_EXTRUDER) + #define PARKING_EXTRUDER_SOLENOIDS_INVERT // If enabled, the solenoid is NOT magnetized with applied voltage + #define PARKING_EXTRUDER_SOLENOIDS_PINS_ACTIVE LOW // LOW or HIGH pin signal energizes the coil + #define PARKING_EXTRUDER_SOLENOIDS_DELAY 250 // Delay (ms) for magnetic field. No delay if 0 or not defined. + #define PARKING_EXTRUDER_PARKING_X { -78, 184 } // X positions for parking the extruders + #define PARKING_EXTRUDER_GRAB_DISTANCE 1 // mm to move beyond the parking point to grab the extruder + #define PARKING_EXTRUDER_SECURITY_RAISE 5 // Z-raise before parking + #define HOTEND_OFFSET_Z { 0.0, 1.3 } // Z-offsets of the two hotends. The first must be 0. +#endif + +/** + * "Mixing Extruder" + * - Adds a new code, M165, to set the current mix factors. + * - Extends the stepping routines to move multiple steppers in proportion to the mix. + * - Optional support for Repetier Firmware M163, M164, and virtual extruder. + * - This implementation supports only a single extruder. + * - Enable DIRECT_MIXING_IN_G1 for Pia Taubert's reference implementation + */ +//#define MIXING_EXTRUDER +#if ENABLED(MIXING_EXTRUDER) + #define MIXING_STEPPERS 2 // Number of steppers in your mixing extruder + #define MIXING_VIRTUAL_TOOLS 16 // Use the Virtual Tool method with M163 and M164 + //#define DIRECT_MIXING_IN_G1 // Allow ABCDHI mix factors in G1 movement commands +#endif + +// Offset of the extruders (uncomment if using more than one and relying on firmware to position when changing). +// The offset has to be X=0, Y=0 for the extruder 0 hotend (default extruder). +// For the other hotends it is their distance from the extruder 0 hotend. +//#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis +//#define HOTEND_OFFSET_Y {0.0, 5.00} // (in mm) for each extruder, offset of the hotend on the Y axis + +// @section machine + +/** + * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN + * + * 0 = No Power Switch + * 1 = ATX + * 2 = X-Box 360 203Watts (the blue wire connected to PS_ON and the red wire to VCC) + * + * :{ 0:'No power switch', 1:'ATX', 2:'X-Box 360' } + */ +#define POWER_SUPPLY 1 + +#if POWER_SUPPLY > 0 + // Enable this option to leave the PSU off at startup. + // Power to steppers and heaters will need to be turned on with M80. + //#define PS_DEFAULT_OFF +#endif + +// @section temperature + +//=========================================================================== +//============================= Thermal Settings ============================ +//=========================================================================== + +/** + * --NORMAL IS 4.7kohm PULLUP!-- 1kohm pullup can be used on hotend sensor, using correct resistor and table + * + * Temperature sensors available: + * + * -3 : thermocouple with MAX31855 (only for sensor 0) + * -2 : thermocouple with MAX6675 (only for sensor 0) + * -1 : thermocouple with AD595 + * 0 : not used + * 1 : 100k thermistor - best choice for EPCOS 100k (4.7k pullup) + * 2 : 200k thermistor - ATC Semitec 204GT-2 (4.7k pullup) + * 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 (Used in ParCan & J-Head) (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) + * 71 : 100k Honeywell thermistor 135-104LAF-J01 (4.7k pullup) + * 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) + * 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" + * 20 : the PT100 circuit found in the Ultimainboard V2.x + * 60 : 100k Maker's Tool Works Kapton Bed Thermistor beta=3950 + * 66 : 4.7M High Temperature thermistor from Dyze Design + * 70 : the 100K thermistor found in the bq Hephestos 2 + * 75 : 100k Generic Silicon Heat Pad with NTC 100K MGB18-104F39050L32 thermistor + * + * 1k ohm pullup tables - This is atypical, and requires changing out the 4.7k pullup for 1k. + * (but gives greater accuracy and more stable PID) + * 51 : 100k thermistor - EPCOS (1k pullup) + * 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 + * 1010 : Pt1000 with 1k pullup (non standard) + * 147 : Pt100 with 4k7 pullup + * 110 : Pt100 with 1k pullup (non standard) + * + * Use these for Testing or Development purposes. NEVER for production machine. + * 998 : Dummy Table that ALWAYS reads 25°C or the temperature defined below. + * 999 : Dummy Table that ALWAYS reads 100°C or the temperature defined below. + * + * :{ '0': "Not used", '1':"100k / 4.7k - EPCOS", '2':"200k / 4.7k - ATC Semitec 204GT-2", '3':"Mendel-parts / 4.7k", '4':"10k !! do not use for a hotend. Bad resolution at high temp. !!", '5':"100K / 4.7k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '6':"100k / 4.7k EPCOS - Not as accurate as Table 1", '7':"100k / 4.7k Honeywell 135-104LAG-J01", '8':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT", '9':"100k / 4.7k GE Sensing AL03006-58.2K-97-G1", '10':"100k / 4.7k RS 198-961", '11':"100k / 4.7k beta 3950 1%", '12':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT (calibrated for Makibox hot bed)", '13':"100k Hisens 3950 1% up to 300°C for hotend 'Simple ONE ' & hotend 'All In ONE'", '20':"PT100 (Ultimainboard V2.x)", '51':"100k / 1k - EPCOS", '52':"200k / 1k - ATC Semitec 204GT-2", '55':"100k / 1k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '60':"100k Maker's Tool Works Kapton Bed Thermistor beta=3950", '66':"Dyze Design 4.7M High Temperature thermistor", '70':"the 100K thermistor found in the bq Hephestos 2", '71':"100k / 4.7k Honeywell 135-104LAF-J01", '147':"Pt100 / 4.7k", '1047':"Pt1000 / 4.7k", '110':"Pt100 / 1k (non-standard)", '1010':"Pt1000 / 1k (non standard)", '-3':"Thermocouple + MAX31855 (only for sensor 0)", '-2':"Thermocouple + MAX6675 (only for sensor 0)", '-1':"Thermocouple + AD595",'998':"Dummy 1", '999':"Dummy 2" } + */ +#define TEMP_SENSOR_0 5 +#define TEMP_SENSOR_1 0 +#define TEMP_SENSOR_2 0 +#define TEMP_SENSOR_3 0 +#define TEMP_SENSOR_4 0 +#define TEMP_SENSOR_BED 5 + +// Dummy thermistor constant temperature readings, for use with 998 and 999 +#define DUMMY_THERMISTOR_998_VALUE 25 +#define DUMMY_THERMISTOR_999_VALUE 100 + +// 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 +#define MAX_REDUNDANT_TEMP_SENSOR_DIFF 10 + +// Extruder temperature must be close to target for this long before M109 returns success +#define TEMP_RESIDENCY_TIME 10 // (seconds) +#define TEMP_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// Bed temperature must be close to target for this long before M190 returns success +#define TEMP_BED_RESIDENCY_TIME 0 // (seconds) +#define TEMP_BED_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_BED_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// The minimal temperature defines the temperature below which the heater will not be enabled It is used +// to check that the wiring to the thermistor is not broken. +// Otherwise this would lead to the heater being powered on all the time. +#define HEATER_0_MINTEMP 5 +#define HEATER_1_MINTEMP 5 +#define HEATER_2_MINTEMP 5 +#define HEATER_3_MINTEMP 5 +#define HEATER_4_MINTEMP 5 +#define BED_MINTEMP 5 + +// When temperature exceeds max temp, your heater will be switched off. +// This feature exists to protect your hotend from overheating accidentally, but *NOT* from thermistor short/failure! +// You should use MINTEMP for thermistor short/failure protection. +#define HEATER_0_MAXTEMP 275 +#define HEATER_1_MAXTEMP 275 +#define HEATER_2_MAXTEMP 275 +#define HEATER_3_MAXTEMP 275 +#define HEATER_4_MAXTEMP 275 +#define BED_MAXTEMP 150 + +//=========================================================================== +//============================= PID Settings ================================ +//=========================================================================== +// PID Tuning Guide here: http://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 125 // limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#if ENABLED(PIDTEMP) + //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. + //#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 50 // 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. + #define K1 0.95 //smoothing factor within the PID + + // Kossel Pro + #define DEFAULT_Kp 19.30 + #define DEFAULT_Ki 3.51 + #define DEFAULT_Kd 26.56 + +#endif // PIDTEMP + +//=========================================================================== +//============================= PID > Bed Temperature Control =============== +//=========================================================================== +// Select PID or bang-bang with PIDTEMPBED. If bang-bang, BED_LIMIT_SWITCHING will enable hysteresis +// +// Uncomment this to enable PID on the bed. It uses the same frequency PWM as the extruder. +// If your PID_dT is the default, and correct for your hardware/configuration, that means 7.689Hz, +// which is fine for driving a square wave into a resistive load and does not significantly impact you FET heating. +// This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W heater. +// If your configuration is significantly different than this and you don't understand the issues involved, you probably +// shouldn't use bed PID until someone else verifies your hardware works. +// If this is enabled, find your own PID constants below. +#define PIDTEMPBED + +//#define BED_LIMIT_SWITCHING + +// This sets the max power delivered to the bed, and replaces the HEATER_BED_DUTY_CYCLE_DIVIDER option. +// all forms of bed control obey this (PID, bang-bang, bang-bang with hysteresis) +// setting this to anything other than 255 enables a form of PWM to the bed just like HEATER_BED_DUTY_CYCLE_DIVIDER did, +// so you shouldn't use it unless you are OK with PWM on your bed. (see the comment on enabling PIDTEMPBED) +#define MAX_BED_POWER 255 // limits duty cycle to bed; 255=full current + +#if ENABLED(PIDTEMPBED) + + //#define PID_BED_DEBUG // Sends debug data to the serial port. + + //Kossel Pro heated bed plate with borosilicate glass + //from pidautotune (M303 E-1 S60 C8) + #define DEFAULT_bedKp 370.25 + #define DEFAULT_bedKi 62.77 + #define DEFAULT_bedKd 545.98 + + // FIND YOUR OWN: "M303 E-1 C8 S90" to run autotune on the bed at 90 degreesC for 8 cycles. +#endif // PIDTEMPBED + +// @section extruder + +// This option prevents extrusion if the temperature is below EXTRUDE_MINTEMP. +// It also enables the M302 command to set the minimum extrusion temperature +// or to allow moving the extruder regardless of the hotend temperature. +// *** IT IS HIGHLY RECOMMENDED TO LEAVE THIS OPTION ENABLED! *** +#define PREVENT_COLD_EXTRUSION +#define EXTRUDE_MINTEMP 170 + +// This option prevents a single extrusion longer than EXTRUDE_MAXLENGTH. +// Note that for Bowden Extruders a too-small value here may prevent loading. +#define PREVENT_LENGTHY_EXTRUDE +#define EXTRUDE_MAXLENGTH 200 + +//=========================================================================== +//======================== Thermal Runaway Protection ======================= +//=========================================================================== + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * If you get "Thermal Runaway" or "Heating failed" errors the + * details can be tuned in Configuration_adv.h + */ + +#define THERMAL_PROTECTION_HOTENDS // Enable thermal protection for all extruders +#define THERMAL_PROTECTION_BED // Enable thermal protection for the heated bed + +//=========================================================================== +//============================= Mechanical Settings ========================= +//=========================================================================== + +// @section machine + +// Uncomment one of these options to enable CoreXY, CoreXZ, or CoreYZ kinematics +// either in the usual order or reversed +//#define COREXY +//#define COREXZ +//#define COREYZ +//#define COREYX +//#define COREZX +//#define COREZY + +//=========================================================================== +//============================== Delta Settings ============================= +//=========================================================================== +// Enable DELTA kinematics and most of the default configuration for Deltas +#define DELTA + +#if ENABLED(DELTA) + + // Make delta curves from many straight lines (linear interpolation). + // This is a trade-off between visible corners (not enough segments) + // and processor overload (too many expensive sqrt calls). + #define DELTA_SEGMENTS_PER_SECOND 160 + + // After homing move down to a height where XY movement is unconstrained + //#define DELTA_HOME_TO_SAFE_ZONE + + // Delta calibration menu + // uncomment to add three points calibration menu option. + // See http://minow.blogspot.com/index.html#4918805519571907051 + //#define DELTA_CALIBRATION_MENU + + // uncomment to add G33 Delta Auto-Calibration (Enable EEPROM_SETTINGS to store results) + //#define DELTA_AUTO_CALIBRATION + + // NOTE NB all values for DELTA_* values MUST be floating point, so always have a decimal point in them + + #if ENABLED(DELTA_AUTO_CALIBRATION) + // set the default number of probe points : n*n (1 -> 7) + #define DELTA_CALIBRATION_DEFAULT_POINTS 4 + #endif + + #if ENABLED(DELTA_AUTO_CALIBRATION) || ENABLED(DELTA_CALIBRATION_MENU) + // Set the radius for the calibration probe points - max DELTA_PRINTABLE_RADIUS*0.869 for non-eccentric probes + #define DELTA_CALIBRATION_RADIUS 110.0 // mm + // Set the steprate for papertest probing + #define PROBE_MANUALLY_STEP 0.025 + #endif + + // Print surface diameter/2 minus unreachable space (avoid collisions with vertical towers). + #define DELTA_PRINTABLE_RADIUS 127.0 // mm + + // Center-to-center distance of the holes in the diagonal push rods. + #define DELTA_DIAGONAL_ROD 301.0 // mm + + // height from z=0 to home position + #define DELTA_HEIGHT 277.00 // get this value from auto calibrate + + #define DELTA_ENDSTOP_ADJ { 0.0, 0.0, 0.0 } // get these from auto calibrate + + // Horizontal distance bridged by diagonal push rods when effector is centered. + #define DELTA_RADIUS 152.357 //mm Get this value from auto calibrate + + // Trim adjustments for individual towers + // tower angle corrections for X and Y tower / rotate XYZ so Z tower angle = 0 + // measured in degrees anticlockwise looking from above the printer + #define DELTA_TOWER_ANGLE_TRIM { 0.0, 0.0, 0.0 } // get these values from auto calibrate + + // delta radius and diaginal rod adjustments measured in mm + //#define DELTA_RADIUS_TRIM_TOWER { 0.0, 0.0, 0.0 } + //#define DELTA_DIAGONAL_ROD_TRIM_TOWER { 0.0, 0.0, 0.0 } + +#endif + +//=========================================================================== +//============================== Endstop Settings =========================== +//=========================================================================== + +// @section homing + +// Specify here all the endstop connectors that are connected to any endstop or probe. +// Almost all printers will be using one per axis. Probes will use one or more of the +// extra connectors. Leave undefined any used for non-endstop and non-probe purposes. +//#define USE_XMIN_PLUG +//#define USE_YMIN_PLUG +#define USE_ZMIN_PLUG // a Z probe +#define USE_XMAX_PLUG +#define USE_YMAX_PLUG +#define USE_ZMAX_PLUG + +// coarse Endstop Settings +#define ENDSTOPPULLUPS // Comment this out (using // at the start of the line) to disable the endstop pullup resistors + +#if DISABLED(ENDSTOPPULLUPS) + // fine endstop settings: Individual pullups. will be ignored if ENDSTOPPULLUPS is defined + //#define ENDSTOPPULLUP_XMAX + //#define ENDSTOPPULLUP_YMAX + //#define ENDSTOPPULLUP_ZMAX + //#define ENDSTOPPULLUP_XMIN + //#define ENDSTOPPULLUP_YMIN + //#define ENDSTOPPULLUP_ZMIN + //#define ENDSTOPPULLUP_ZMIN_PROBE +#endif + +// Mechanical endstop with COM to ground and NC to Signal uses "false" here (most common setup). +#define X_MIN_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Y_MIN_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MIN_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define X_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Y_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MIN_PROBE_ENDSTOP_INVERTING false // set to true to invert the logic of the probe. + +// Enable this feature if all enabled endstop pins are interrupt-capable. +// This will remove the need to poll the interrupt pins, saving many CPU cycles. +//#define ENDSTOP_INTERRUPTS_FEATURE + +//============================================================================= +//============================== Movement Settings ============================ +//============================================================================= +// @section motion + +#define XYZ_FULL_STEPS_PER_ROTATION 200 +#define XYZ_MICROSTEPS 32 +#define XYZ_BELT_PITCH 2 +#define XYZ_PULLEY_TEETH 20 + +// delta speeds must be the same on xyz +#define XYZ_STEPS ((XYZ_FULL_STEPS_PER_ROTATION) * (XYZ_MICROSTEPS) / double(XYZ_BELT_PITCH) / double(XYZ_PULLEY_TEETH)) + +/** + * Default Settings + * + * These settings can be reset by M502 + * + * Note that if EEPROM is enabled, saved values will override these. + */ + +/** + * With this option each E stepper can have its own factors for the + * following movement settings. If fewer factors are given than the + * total number of extruders, the last value applies to the rest. + */ +//#define DISTINCT_E_FACTORS + +/** + * Default Axis Steps Per Unit (steps/mm) + * Override with M92 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_AXIS_STEPS_PER_UNIT { XYZ_STEPS, XYZ_STEPS, XYZ_STEPS, 184.8 } + +/** + * Default Max Feed Rate (mm/s) + * Override with M203 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_FEEDRATE { 200, 200, 200, 200 } + +/** + * Default Max Acceleration (change/s) change = mm/s + * (Maximum start speed for accelerated moves) + * Override with M201 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_ACCELERATION { 9000, 9000, 9000, 9000 } + +/** + * Default Acceleration (change/s) change = mm/s + * Override with M204 + * + * M204 P Acceleration + * M204 R Retract Acceleration + * M204 T Travel Acceleration + */ +#define DEFAULT_ACCELERATION 3000 // X, Y, Z and E acceleration for printing moves +#define DEFAULT_RETRACT_ACCELERATION 3000 // E acceleration for retracts +#define DEFAULT_TRAVEL_ACCELERATION 3000 // X, Y, Z acceleration for travel (non printing) moves + +/** + * Default Jerk (mm/s) + * Override with M205 X Y Z E + * + * "Jerk" specifies the minimum speed change that requires acceleration. + * When changing speed and direction, if the difference is less than the + * value set here, it may happen instantaneously. + */ +#define DEFAULT_XJERK 20.0 +#define DEFAULT_YJERK 20.0 +#define DEFAULT_ZJERK 20.0 // Must be same as XY for delta +#define DEFAULT_EJERK 5.0 + +//=========================================================================== +//============================= Z Probe Options ============================= +//=========================================================================== +// @section probes + +// +// See http://marlinfw.org/configuration/probes.html +// + +/** + * Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + * + * Enable this option for a probe connected to the Z Min endstop pin. + */ +#define Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + +/** + * Z_MIN_PROBE_ENDSTOP + * + * Enable this option for a probe connected to any pin except Z-Min. + * (By default Marlin assumes the Z-Max endstop pin.) + * To use a custom Z Probe pin, set Z_MIN_PROBE_PIN below. + * + * - The simplest option is to use a free endstop connector. + * - Use 5V for powered (usually inductive) sensors. + * + * - RAMPS 1.3/1.4 boards may use the 5V, GND, and Aux4->D32 pin: + * - For simple switches connect... + * - normally-closed switches to GND and D32. + * - normally-open switches to 5V and D32. + * + * WARNING: Setting the wrong pin may have unexpected and potentially + * disastrous consequences. Use with caution and do your homework. + * + */ +//#define Z_MIN_PROBE_ENDSTOP + +/** + * Probe Type + * + * Allen Key Probes, Servo Probes, Z-Sled Probes, FIX_MOUNTED_PROBE, etc. + * Activate one of these to use Auto Bed Leveling below. + */ + +/** + * The "Manual Probe" provides a means to do "Auto" Bed Leveling without a probe. + * Use G29 repeatedly, adjusting the Z height at each point with movement commands + * or (with LCD_BED_LEVELING) the LCD controller. + */ +//#define PROBE_MANUALLY + +/** + * A Fix-Mounted Probe either doesn't deploy or needs manual deployment. + * (e.g., an inductive probe or a nozzle-based probe-switch.) + */ +//#define FIX_MOUNTED_PROBE + +/** + * Z Servo Probe, such as an endstop switch on a rotating arm. + */ +//#define Z_ENDSTOP_SERVO_NR 0 // Defaults to SERVO 0 connector. +//#define Z_SERVO_ANGLES {70,0} // Z Servo Deploy and Stow angles + +/** + * The BLTouch probe uses a Hall effect sensor and emulates a servo. + */ +//#define BLTOUCH +#if ENABLED(BLTOUCH) + //#define BLTOUCH_DELAY 375 // (ms) Enable and increase if needed +#endif + +/** + * Enable one or more of the following if probing seems unreliable. + * Heaters and/or fans can be disabled during probing to minimize electrical + * noise. A delay can also be added to allow noise and vibration to settle. + * These options are most useful for the BLTouch probe, but may also improve + * readings with inductive probes and piezo sensors. + */ +//#define PROBING_HEATERS_OFF // Turn heaters off when probing +//#define PROBING_FANS_OFF // Turn fans off when probing +//#define DELAY_BEFORE_PROBING 200 // (ms) To prevent vibrations from triggering piezo sensors + +// A probe that is deployed and stowed with a solenoid pin (SOL1_PIN) +//#define SOLENOID_PROBE + +// A sled-mounted probe like those designed by Charles Bell. +//#define Z_PROBE_SLED +//#define SLED_DOCKING_OFFSET 5 // The extra distance the X axis must travel to pickup the sled. 0 should be fine but you can push it further if you'd like. + +// +// For Z_PROBE_ALLEN_KEY see the Delta example configurations. +// + +/** + * Z Probe to nozzle (X,Y) offset, relative to (0, 0). + * X and Y offsets must be integers. + * + * In the following example the X and Y offsets are both positive: + * #define X_PROBE_OFFSET_FROM_EXTRUDER 10 + * #define Y_PROBE_OFFSET_FROM_EXTRUDER 10 + * + * +-- BACK ---+ + * | | + * L | (+) P | R <-- probe (20,20) + * E | | I + * F | (-) N (+) | G <-- nozzle (10,10) + * T | | H + * | (-) | T + * | | + * O-- FRONT --+ + * (0,0) + */ +#define X_PROBE_OFFSET_FROM_EXTRUDER -23 // KosselPro actual: -22.919 +#define Y_PROBE_OFFSET_FROM_EXTRUDER -6 // KosselPro actual: -6.304 +/** + * Kossel Pro note: The correct value is likely -17.45 but I'd rather err on the side of + * not giving someone a head crash. Use something like G29 Z-0.2 to adjust as needed. + */ +#define Z_PROBE_OFFSET_FROM_EXTRUDER -17.25 // Increase this if the first layer is too thin (remember: it's a negative number so increase means closer to zero). +// X and Y axis travel speed (mm/m) between probes +#define XY_PROBE_SPEED 8000 + +// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +#define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z + +// Speed for the "accurate" probe of each point +#define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) + +// Use double touch for probing +//#define PROBE_DOUBLE_TOUCH + +/** + * Allen key retractable z-probe as seen on many Kossel delta printers - http://reprap.org/wiki/Kossel#Automatic_bed_leveling_probe + * Deploys by touching z-axis belt. Retracts by pushing the probe down. Uses Z_MIN_PIN. + */ +#define Z_PROBE_ALLEN_KEY + +#if ENABLED(Z_PROBE_ALLEN_KEY) + // 2 or 3 sets of coordinates for deploying and retracting the spring loaded touch probe on G29, + // if servo actuated touch probe is not defined. Uncomment as appropriate for your printer/probe. + + // Kossel Pro + #define Z_PROBE_ALLEN_KEY_DEPLOY_1_X -105.00 // Move left but not quite so far that we'll bump the belt + #define Z_PROBE_ALLEN_KEY_DEPLOY_1_Y 0.00 + #define Z_PROBE_ALLEN_KEY_DEPLOY_1_Z 100.0 + #define Z_PROBE_ALLEN_KEY_DEPLOY_1_FEEDRATE XY_PROBE_SPEED + + #define Z_PROBE_ALLEN_KEY_DEPLOY_2_X -110.00 // Move outward to position deploy pin to the left of the arm + #define Z_PROBE_ALLEN_KEY_DEPLOY_2_Y -125.00 + #define Z_PROBE_ALLEN_KEY_DEPLOY_2_Z Z_PROBE_ALLEN_KEY_DEPLOY_1_Z + #define Z_PROBE_ALLEN_KEY_DEPLOY_2_FEEDRATE XY_PROBE_SPEED + + #define Z_PROBE_ALLEN_KEY_DEPLOY_3_X Z_PROBE_ALLEN_KEY_DEPLOY_2_X * 0.75 + #define Z_PROBE_ALLEN_KEY_DEPLOY_3_Y Z_PROBE_ALLEN_KEY_DEPLOY_2_Y * 0.75 + #define Z_PROBE_ALLEN_KEY_DEPLOY_3_Z Z_PROBE_ALLEN_KEY_DEPLOY_2_Z + #define Z_PROBE_ALLEN_KEY_DEPLOY_3_FEEDRATE XY_PROBE_SPEED + + #define Z_PROBE_ALLEN_KEY_DEPLOY_4_X 45.00 // Move right to trigger deploy pin + #define Z_PROBE_ALLEN_KEY_DEPLOY_4_Y -125.00 + #define Z_PROBE_ALLEN_KEY_DEPLOY_4_Z Z_PROBE_ALLEN_KEY_DEPLOY_3_Z + #define Z_PROBE_ALLEN_KEY_DEPLOY_4_FEEDRATE (XY_PROBE_SPEED)/2 + + #define Z_PROBE_ALLEN_KEY_STOW_1_X 36.00 // Line up with bed retaining clip + #define Z_PROBE_ALLEN_KEY_STOW_1_Y -125.00 + #define Z_PROBE_ALLEN_KEY_STOW_1_Z 75.0 + #define Z_PROBE_ALLEN_KEY_STOW_1_FEEDRATE XY_PROBE_SPEED + + #define Z_PROBE_ALLEN_KEY_STOW_2_X Z_PROBE_ALLEN_KEY_STOW_1_X // move down to retract probe + #define Z_PROBE_ALLEN_KEY_STOW_2_Y Z_PROBE_ALLEN_KEY_STOW_1_Y + #define Z_PROBE_ALLEN_KEY_STOW_2_Z 0.0 + #define Z_PROBE_ALLEN_KEY_STOW_2_FEEDRATE (XY_PROBE_SPEED)/2 + + #define Z_PROBE_ALLEN_KEY_STOW_3_X 0.0 // return to 0,0,100 + #define Z_PROBE_ALLEN_KEY_STOW_3_Y 0.0 + #define Z_PROBE_ALLEN_KEY_STOW_3_Z 100.0 + #define Z_PROBE_ALLEN_KEY_STOW_3_FEEDRATE XY_PROBE_SPEED + + #define Z_PROBE_ALLEN_KEY_STOW_4_X 0.0 + #define Z_PROBE_ALLEN_KEY_STOW_4_Y 0.0 + #define Z_PROBE_ALLEN_KEY_STOW_4_Z Z_PROBE_ALLEN_KEY_STOW_3_Z + #define Z_PROBE_ALLEN_KEY_STOW_4_FEEDRATE XY_PROBE_SPEED + +#endif // Z_PROBE_ALLEN_KEY + +/** + * Z probes require clearance when deploying, stowing, and moving between + * probe points to avoid hitting the bed and other hardware. + * Servo-mounted probes require extra space for the arm to rotate. + * Inductive probes need space to keep from triggering early. + * + * Use these settings to specify the distance (mm) to raise the probe (or + * lower the bed). The values set here apply over and above any (negative) + * probe Z Offset set with Z_PROBE_OFFSET_FROM_EXTRUDER, M851, or the LCD. + * Only integer values >= 1 are valid here. + * + * Example: `M851 Z-5` with a CLEARANCE of 4 => 9mm from bed to nozzle. + * But: `M851 Z+1` with a CLEARANCE of 2 => 2mm from bed to nozzle. + */ +#define Z_CLEARANCE_DEPLOY_PROBE 100 // Z Clearance for Deploy/Stow +#define Z_CLEARANCE_BETWEEN_PROBES 5 // Z Clearance between probe points + +// For M851 give a range for adjusting the Z probe offset + +#define Z_PROBE_OFFSET_RANGE_MIN -15 +#define Z_PROBE_OFFSET_RANGE_MAX 5 + +// Enable the M48 repeatability test to test probe accuracy +//#define Z_MIN_PROBE_REPEATABILITY_TEST + +// For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1 +// :{ 0:'Low', 1:'High' } +#define X_ENABLE_ON 0 +#define Y_ENABLE_ON 0 +#define Z_ENABLE_ON 0 +#define E_ENABLE_ON 0 // For all extruders + +// Disables axis stepper immediately when it's not being used. +// 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 +//#define DISABLE_REDUCED_ACCURACY_WARNING + +// @section extruder + +#define DISABLE_E false // For all extruders +#define DISABLE_INACTIVE_EXTRUDER true // Keep only the active extruder enabled. + +// @section machine + +// Invert the stepper direction. Change (or reverse the motor connector) if an axis goes the wrong way. +#define INVERT_X_DIR true +#define INVERT_Y_DIR true +#define INVERT_Z_DIR true + +// Enable this option for Toshiba stepper drivers +//#define CONFIG_STEPPERS_TOSHIBA + +// @section extruder + +// For direct drive extruder v9 set to true, for geared extruder set to false. +#define INVERT_E0_DIR true +#define INVERT_E1_DIR false +#define INVERT_E2_DIR false +#define INVERT_E3_DIR false +#define INVERT_E4_DIR false + +// @section homing + +//#define NO_MOTION_BEFORE_HOMING // Inhibit movement until all axes have been homed + +//#define Z_HOMING_HEIGHT 4 // (in mm) Minimal z height before homing (G28) for Z clearance above the bed, clamps, ... + // Be sure you have this distance over your Z_MAX_POS in case. + +// Direction of endstops when homing; 1=MAX, -1=MIN +// :[-1,1] +#define X_HOME_DIR 1 // deltas always home to max +#define Y_HOME_DIR 1 +#define Z_HOME_DIR 1 + +// @section machine + +// The size of the print bed +#define X_BED_SIZE ((DELTA_PRINTABLE_RADIUS) * 2) +#define Y_BED_SIZE ((DELTA_PRINTABLE_RADIUS) * 2) + +// Travel limits (mm) after homing, corresponding to endstop positions. +#define X_MIN_POS -(DELTA_PRINTABLE_RADIUS) +#define Y_MIN_POS -(DELTA_PRINTABLE_RADIUS) +#define Z_MIN_POS 0 +#define X_MAX_POS DELTA_PRINTABLE_RADIUS +#define Y_MAX_POS DELTA_PRINTABLE_RADIUS +#define Z_MAX_POS MANUAL_Z_HOME_POS + +// If enabled, axes won't move below MIN_POS in response to movement commands. +#define MIN_SOFTWARE_ENDSTOPS +// If enabled, axes won't move above MAX_POS in response to movement commands. +#define MAX_SOFTWARE_ENDSTOPS + +/** + * Filament Runout Sensor + * A mechanical or opto endstop is used to check for the presence of filament. + * + * RAMPS-based boards use SERVO3_PIN. + * For other boards you may need to define FIL_RUNOUT_PIN. + * By default the firmware assumes HIGH = has filament, LOW = ran out + */ +//#define FILAMENT_RUNOUT_SENSOR +#if ENABLED(FILAMENT_RUNOUT_SENSOR) + #define FIL_RUNOUT_INVERTING false // set to true to invert the logic of the sensor. + #define ENDSTOPPULLUP_FIL_RUNOUT // Uncomment to use internal pullup for filament runout pins if the sensor is defined. + #define FILAMENT_RUNOUT_SCRIPT "M600" +#endif + +//=========================================================================== +//=============================== Bed Leveling ============================== +//=========================================================================== +// @section bedlevel + +/** + * Choose one of the options below to enable G29 Bed Leveling. The parameters + * and behavior of G29 will change depending on your selection. + * + * If using a Probe for Z Homing, enable Z_SAFE_HOMING also! + * + * - AUTO_BED_LEVELING_3POINT + * Probe 3 arbitrary points on the bed (that aren't collinear) + * You specify the XY coordinates of all 3 points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_LINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_BILINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a mesh, best for large or uneven beds. + * + * - AUTO_BED_LEVELING_UBL (Unified Bed Leveling) + * A comprehensive bed leveling system combining the features and benefits + * of other systems. UBL also includes integrated Mesh Generation, Mesh + * Validation and Mesh Editing systems. Currently, UBL is only checked out + * for Cartesian Printers. That said, it was primarily designed to correct + * poor quality Delta Printers. If you feel adventurous and have a Delta, + * please post an issue if something doesn't work correctly. Initially, + * you will need to set a reduced bed size so you have a rectangular area + * to test on. + * + * - MESH_BED_LEVELING + * Probe a grid manually + * The result is a mesh, suitable for large or uneven beds. (See BILINEAR.) + * For machines without a probe, Mesh Bed Leveling provides a method to perform + * leveling in steps so you can manually adjust the Z height at each grid-point. + * With an LCD controller the process is guided step-by-step. + */ +//#define AUTO_BED_LEVELING_3POINT +//#define AUTO_BED_LEVELING_LINEAR +//#define AUTO_BED_LEVELING_BILINEAR +//#define AUTO_BED_LEVELING_UBL +//#define MESH_BED_LEVELING + +/** + * Enable detailed logging of G28, G29, M48, etc. + * Turn on with the command 'M111 S32'. + * NOTE: Requires a lot of PROGMEM! + */ +//#define DEBUG_LEVELING_FEATURE + +#if ENABLED(MESH_BED_LEVELING) || ENABLED(AUTO_BED_LEVELING_BILINEAR) || ENABLED(AUTO_BED_LEVELING_UBL) + // Gradually reduce leveling correction until a set height is reached, + // at which point movement will be level to the machine's XY plane. + // The height can be set with M420 Z + //#define ENABLE_LEVELING_FADE_HEIGHT + + // Set the boundaries for probing (where the probe can reach). + #define DELTA_PROBEABLE_RADIUS (DELTA_PRINTABLE_RADIUS - 10) + +#endif + +#if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Set the number of grid points per dimension. + // Works best with 5 or more points in each dimension. + #define GRID_MAX_POINTS_X 7 + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + #define LEFT_PROBE_BED_POSITION -(DELTA_PROBEABLE_RADIUS) + #define RIGHT_PROBE_BED_POSITION DELTA_PROBEABLE_RADIUS + #define FRONT_PROBE_BED_POSITION -(DELTA_PROBEABLE_RADIUS) + #define BACK_PROBE_BED_POSITION DELTA_PROBEABLE_RADIUS + + // The Z probe minimum outer margin (to validate G29 parameters). + #define MIN_PROBE_EDGE 10 + + // Probe along the Y axis, advancing X after each column + //#define PROBE_Y_FIRST + + #if ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Beyond the probed grid, continue the implied tilt? + // Default is to maintain the height of the nearest edge. + //#define EXTRAPOLATE_BEYOND_GRID + + // + // Experimental Subdivision of the grid by Catmull-Rom method. + // Synthesizes intermediate points to produce a more detailed mesh. + // + //#define ABL_BILINEAR_SUBDIVISION + #if ENABLED(ABL_BILINEAR_SUBDIVISION) + // Number of subdivisions between probe points + #define BILINEAR_SUBDIVISIONS 3 + #endif + + #endif + +#elif ENABLED(AUTO_BED_LEVELING_3POINT) + + // 3 arbitrary points to probe. + // A simple cross-product is used to estimate the plane of the bed. + #define ABL_PROBE_PT_1_X 15 + #define ABL_PROBE_PT_1_Y 180 + #define ABL_PROBE_PT_2_X 15 + #define ABL_PROBE_PT_2_Y 20 + #define ABL_PROBE_PT_3_X 170 + #define ABL_PROBE_PT_3_Y 20 + +#elif ENABLED(AUTO_BED_LEVELING_UBL) + + //=========================================================================== + //========================= Unified Bed Leveling ============================ + //=========================================================================== + + #define UBL_MESH_INSET 1 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 10 // Don't use more than 15 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + #define _PX(R,A) (R) * cos(RADIANS(A)) + #define _PY(R,A) (R) * sin(RADIANS(A)) + #define UBL_PROBE_PT_1_X _PX(DELTA_PROBEABLE_RADIUS, 0) // Probing points for 3-Point leveling of the mesh + #define UBL_PROBE_PT_1_Y _PY(DELTA_PROBEABLE_RADIUS, 0) + #define UBL_PROBE_PT_2_X _PX(DELTA_PROBEABLE_RADIUS, 120) + #define UBL_PROBE_PT_2_Y _PY(DELTA_PROBEABLE_RADIUS, 120) + #define UBL_PROBE_PT_3_X _PX(DELTA_PROBEABLE_RADIUS, 240) + #define UBL_PROBE_PT_3_Y _PY(DELTA_PROBEABLE_RADIUS, 240) + + #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation + #define UBL_MESH_EDIT_MOVES_Z // Sophisticated users prefer no movement of nozzle + +#elif ENABLED(MESH_BED_LEVELING) + + //=========================================================================== + //=================================== Mesh ================================== + //=========================================================================== + + #define MESH_INSET 10 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 3 // Don't use more than 7 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + //#define MESH_G28_REST_ORIGIN // After homing all axes ('G28' or 'G28 XYZ') rest Z at Z_MIN_POS + +#endif // BED_LEVELING + +/** + * Use the LCD controller for bed leveling + * Requires MESH_BED_LEVELING or PROBE_MANUALLY + */ +//#define LCD_BED_LEVELING + +#if ENABLED(LCD_BED_LEVELING) + #define MBL_Z_STEP 0.025 // Step size while manually probing Z axis. + #define LCD_PROBE_Z_RANGE 4 // Z Range centered on Z_MIN_POS for LCD Z adjustment +#endif + +// Add a menu item to move between bed corners for manual bed adjustment +//#define LEVEL_BED_CORNERS + +/** + * Commands to execute at the end of G29 probing. + * Useful to retract or move the Z probe out of the way. + */ +//#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) +#define BED_CENTER_AT_0_0 + +// Manually set the home position. Leave these undefined for automatic settings. +// For DELTA this is the top-center of the Cartesian print volume. +//#define MANUAL_X_HOME_POS 0 +//#define MANUAL_Y_HOME_POS 0 +#define MANUAL_Z_HOME_POS DELTA_HEIGHT // Distance between the nozzle to printbed after homing + +// Use "Z Safe Homing" to avoid homing with a Z probe outside the bed area. +// +// With this feature enabled: +// +// - 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). +// - 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 axis (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). +#endif + +// Delta only homes to Z +#define HOMING_FEEDRATE_Z (200*60) + +//============================================================================= +//============================= Additional Features =========================== +//============================================================================= + +// @section extras + +// +// EEPROM +// +// The microcontroller can store settings in the EEPROM, e.g. max velocity... +// M500 - stores parameters in EEPROM +// M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily). +// M502 - reverts to the default "factory settings". You still need to store them in EEPROM afterwards if you want to. +// +//#define EEPROM_SETTINGS // Enable for M500 and M501 commands +//#define DISABLE_M503 // Saves ~2700 bytes of PROGMEM. Disable for release! +#define EEPROM_CHITCHAT // Give feedback on EEPROM commands. Disable to save PROGMEM. + +// +// Host Keepalive +// +// When enabled Marlin will send a busy status message to the host +// every couple of seconds when it can't accept commands. +// +#define HOST_KEEPALIVE_FEATURE // Disable this if your host doesn't like keepalive messages +#define DEFAULT_KEEPALIVE_INTERVAL 2 // Number of seconds between "busy" messages. Set with M113. +#define BUSY_WHILE_HEATING // Some hosts require "busy" messages even during heating + +// +// M100 Free Memory Watcher +// +//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose + +// +// G20/G21 Inch mode support +// +//#define INCH_MODE_SUPPORT + +// +// M149 Set temperature units support +// +//#define TEMPERATURE_UNITS_SUPPORT + +// @section temperature + +// Preheat Constants +#define PREHEAT_1_TEMP_HOTEND 180 +#define PREHEAT_1_TEMP_BED 70 +#define PREHEAT_1_FAN_SPEED 255 // Value from 0 to 255 + +#define PREHEAT_2_TEMP_HOTEND 240 +#define PREHEAT_2_TEMP_BED 100 +#define PREHEAT_2_FAN_SPEED 255 // Value from 0 to 255 + +/** + * Nozzle Park -- EXPERIMENTAL + * + * Park the nozzle at the given XYZ position on idle or G27. + * + * The "P" parameter controls the action applied to the Z axis: + * + * P0 (Default) If Z is below park Z raise the nozzle. + * P1 Raise the nozzle always to Z-park height. + * P2 Raise the nozzle by Z-park amount, limited to Z_MAX_POS. + */ +//#define NOZZLE_PARK_FEATURE + +#if ENABLED(NOZZLE_PARK_FEATURE) + // Specify a park position as { X, Y, Z } + #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 } +#endif + +/** + * Clean Nozzle Feature -- EXPERIMENTAL + * + * Adds the G12 command to perform a nozzle cleaning process. + * + * Parameters: + * P Pattern + * S Strokes / Repetitions + * T Triangles (P1 only) + * + * Patterns: + * P0 Straight line (default). This process requires a sponge type material + * at a fixed bed location. "S" specifies strokes (i.e. back-forth motions) + * between the start / end points. + * + * P1 Zig-zag pattern between (X0, Y0) and (X1, Y1), "T" specifies the + * number of zig-zag triangles to do. "S" defines the number of strokes. + * Zig-zags are done in whichever is the narrower dimension. + * For example, "G12 P1 S1 T3" will execute: + * + * -- + * | (X0, Y1) | /\ /\ /\ | (X1, Y1) + * | | / \ / \ / \ | + * A | | / \ / \ / \ | + * | | / \ / \ / \ | + * | (X0, Y0) | / \/ \/ \ | (X1, Y0) + * -- +--------------------------------+ + * |________|_________|_________| + * T1 T2 T3 + * + * P2 Circular pattern with middle at NOZZLE_CLEAN_CIRCLE_MIDDLE. + * "R" specifies the radius. "S" specifies the stroke count. + * Before starting, the nozzle moves to NOZZLE_CLEAN_START_POINT. + * + * Caveats: The ending Z should be the same as starting Z. + * Attention: EXPERIMENTAL. G-code arguments may change. + * + */ +//#define NOZZLE_CLEAN_FEATURE + +#if ENABLED(NOZZLE_CLEAN_FEATURE) + // Default number of pattern repetitions + #define NOZZLE_CLEAN_STROKES 12 + + // Default number of triangles + #define NOZZLE_CLEAN_TRIANGLES 3 + + // Specify positions as { X, Y, Z } + #define NOZZLE_CLEAN_START_POINT { 30, 30, (Z_MIN_POS + 1)} + #define NOZZLE_CLEAN_END_POINT {100, 60, (Z_MIN_POS + 1)} + + // Circular pattern radius + #define NOZZLE_CLEAN_CIRCLE_RADIUS 6.5 + // Circular pattern circle fragments number + #define NOZZLE_CLEAN_CIRCLE_FN 10 + // Middle point of circle + #define NOZZLE_CLEAN_CIRCLE_MIDDLE NOZZLE_CLEAN_START_POINT + + // Moves the nozzle to the initial position + #define NOZZLE_CLEAN_GOBACK +#endif + +/** + * Print Job Timer + * + * Automatically start and stop the print job timer on M104/M109/M190. + * + * M104 (hotend, no wait) - high temp = none, low temp = stop timer + * M109 (hotend, wait) - high temp = start timer, low temp = stop timer + * M190 (bed, wait) - high temp = start timer, low temp = none + * + * The timer can also be controlled with the following commands: + * + * M75 - Start the print job timer + * M76 - Pause the print job timer + * M77 - Stop the print job timer + */ +#define PRINTJOB_TIMER_AUTOSTART + +/** + * Print Counter + * + * Track statistical data such as: + * + * - Total print jobs + * - Total successful print jobs + * - Total failed print jobs + * - Total time printing + * + * View the current statistics with M78. + */ +//#define PRINTCOUNTER + +//============================================================================= +//============================= LCD and SD support ============================ +//============================================================================= + +// @section lcd + +/** + * LCD LANGUAGE + * + * Select the language to display on the LCD. These languages are available: + * + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, + * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * tr, uk, zh_CN, zh_TW, test + * + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + */ +#define LCD_LANGUAGE en + +/** + * LCD Character Set + * + * Note: This option is NOT applicable to Graphical Displays. + * + * All character-based LCDs provide ASCII plus one of these + * language extensions: + * + * - JAPANESE ... the most common + * - WESTERN ... with more accented characters + * - CYRILLIC ... for the Russian language + * + * To determine the language extension installed on your controller: + * + * - Compile and upload with LCD_LANGUAGE set to 'test' + * - 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 + * + * :['JAPANESE', 'WESTERN', 'CYRILLIC'] + */ +#define DISPLAY_CHARSET_HD44780 JAPANESE + +/** + * LCD TYPE + * + * Enable ULTRA_LCD for a 16x2, 16x4, 20x2, or 20x4 character-based LCD. + * Enable DOGLCD for a 128x64 (ST7565R) Full Graphical Display. + * (These options will be enabled automatically for most displays.) + * + * IMPORTANT: The U8glib library is required for Full Graphic Display! + * https://github.com/olikraus/U8glib_Arduino + */ +//#define ULTRA_LCD // Character based +//#define DOGLCD // Full graphics display + +/** + * SD CARD + * + * 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 + +/** + * SD CARD: SPI SPEED + * + * Enable one of the following items for a slower SPI transfer speed. + * This may be required to resolve "volume init" errors. + */ +//#define SPI_SPEED SPI_HALF_SPEED +//#define SPI_SPEED SPI_QUARTER_SPEED +//#define SPI_SPEED SPI_EIGHTH_SPEED + +/** + * SD CARD: ENABLE CRC + * + * Use CRC checks and retries on the SD communication. + */ +//#define SD_CHECK_AND_RETRY + +// +// ENCODER SETTINGS +// +// This option overrides the default number of encoder pulses needed to +// produce one step. Should be increased for high-resolution encoders. +// +//#define ENCODER_PULSES_PER_STEP 1 + +// +// Use this option to override the number of step signals required to +// move between next/prev menu items. +// +//#define ENCODER_STEPS_PER_MENU_ITEM 5 + +/** + * Encoder Direction Options + * + * Test your encoder's behavior first with both options disabled. + * + * Reversed Value Edit and Menu Nav? Enable REVERSE_ENCODER_DIRECTION. + * Reversed Menu Navigation only? Enable REVERSE_MENU_DIRECTION. + * Reversed Value Editing only? Enable BOTH options. + */ + +// +// This option reverses the encoder direction everywhere. +// +// Set this option if CLOCKWISE causes values to DECREASE +// +//#define REVERSE_ENCODER_DIRECTION + +// +// This option reverses the encoder direction for navigating LCD menus. +// +// If CLOCKWISE normally moves DOWN this makes it go UP. +// If CLOCKWISE normally moves UP this makes it go DOWN. +// +//#define REVERSE_MENU_DIRECTION + +// +// Individual Axis Homing +// +// Add individual axis homing items (Home X, Home Y, and Home Z) to the LCD menu. +// +//#define INDIVIDUAL_AXIS_HOMING_MENU + +// +// SPEAKER/BUZZER +// +// If you have a speaker that can produce tones, enable it here. +// By default Marlin assumes you have a buzzer with a fixed frequency. +// +//#define SPEAKER + +// +// The duration and frequency for the UI feedback sound. +// Set these to 0 to disable audio feedback in the LCD menus. +// +// Note: Test audio output with the G-Code: +// M300 S P +// +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 +//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 + +// +// CONTROLLER TYPE: Standard +// +// Marlin supports a wide variety of controllers. +// Enable one of the following options to specify your controller. +// + +// +// ULTIMAKER Controller. +// +//#define ULTIMAKERCONTROLLER + +// +// ULTIPANEL as seen on Thingiverse. +// +//#define ULTIPANEL + +// +// PanelOne from T3P3 (via RAMPS 1.4 AUX2/AUX3) +// http://reprap.org/wiki/PanelOne +// +//#define PANEL_ONE + +// +// MaKr3d Makr-Panel with graphic controller and SD support. +// http://reprap.org/wiki/MaKr3d_MaKrPanel +// +//#define MAKRPANEL + +// +// ReprapWorld Graphical LCD +// https://reprapworld.com/?products_details&products_id/1218 +// +//#define REPRAPWORLD_GRAPHICAL_LCD + +// +// Activate one of these if you have a Panucatt Devices +// Viki 2.0 or mini Viki with Graphic LCD +// http://panucatt.com +// +//#define VIKI2 +//#define miniVIKI + +// +// Adafruit ST7565 Full Graphic Controller. +// https://github.com/eboston/Adafruit-ST7565-Full-Graphic-Controller/ +// +//#define ELB_FULL_GRAPHIC_CONTROLLER + +// +// RepRapDiscount Smart Controller. +// http://reprap.org/wiki/RepRapDiscount_Smart_Controller +// +// Note: Usually sold with a white PCB. +// +//#define REPRAP_DISCOUNT_SMART_CONTROLLER + +// +// GADGETS3D G3D LCD/SD Controller +// http://reprap.org/wiki/RAMPS_1.3/1.4_GADGETS3D_Shield_with_Panel +// +// Note: Usually sold with a blue PCB. +// +//#define G3D_PANEL + +// +// RepRapDiscount FULL GRAPHIC Smart Controller +// http://reprap.org/wiki/RepRapDiscount_Full_Graphic_Smart_Controller +// +//#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER + +// +// MakerLab Mini Panel with graphic +// controller and SD support - http://reprap.org/wiki/Mini_panel +// +//#define MINIPANEL + +// +// RepRapWorld REPRAPWORLD_KEYPAD v1.1 +// http://reprapworld.com/?products_details&products_id=202&cPath=1591_1626 +// +// REPRAPWORLD_KEYPAD_MOVE_STEP sets how much should the robot move when a key +// is pressed, a value of 10.0 means 10mm per click. +// +//#define REPRAPWORLD_KEYPAD +//#define REPRAPWORLD_KEYPAD_MOVE_STEP 1.0 + +// +// RigidBot Panel V1.0 +// http://www.inventapart.com/ +// +//#define RIGIDBOT_PANEL + +// +// BQ LCD Smart Controller shipped by +// default with the BQ Hephestos 2 and Witbox 2. +// +//#define BQ_LCD_SMART_CONTROLLER + +// +// Cartesio UI +// http://mauk.cc/webshop/cartesio-shop/electronics/user-interface +// +//#define CARTESIO_UI + +// +// ANET_10 Controller supported displays. +// +//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. + // This LCD is known to be susceptible to electrical interference + // which scrambles the display. Pressing any button clears it up. +//#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 + // A clone of the RepRapDiscount full graphics display but with + // different pins/wiring (see pins_ANET_10.h). + +// +// LCD for Melzi Card with Graphical LCD +// +//#define LCD_FOR_MELZI + +// +// CONTROLLER TYPE: I2C +// +// Note: These controllers require the installation of Arduino's LiquidCrystal_I2C +// library. For more info: https://github.com/kiyoshigawa/LiquidCrystal_I2C +// + +// +// Elefu RA Board Control Panel +// http://www.elefu.com/index.php?route=product/product&product_id=53 +// +//#define RA_CONTROL_PANEL + +// +// Sainsmart YW Robot (LCM1602) LCD Display +// +// Note: This controller requires F.Malpartida's LiquidCrystal_I2C library +// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home +// +//#define LCD_I2C_SAINSMART_YWROBOT + +// +// Generic LCM1602 LCD adapter +// +//#define LCM1602 + +// +// PANELOLU2 LCD with status LEDs, +// separate encoder and click inputs. +// +// Note: This controller requires Arduino's LiquidTWI2 library v1.2.3 or later. +// For more info: https://github.com/lincomatic/LiquidTWI2 +// +// Note: The PANELOLU2 encoder click input can either be directly connected to +// a pin (if BTN_ENC defined to != -1) or read through I2C (when BTN_ENC == -1). +// +//#define LCD_I2C_PANELOLU2 + +// +// Panucatt VIKI LCD with status LEDs, +// integrated click & L/R/U/D buttons, separate encoder inputs. +// +//#define LCD_I2C_VIKI + +// +// SSD1306 OLED full graphics generic display +// +//#define U8GLIB_SSD1306 + +// +// SAV OLEd LCD module support using either SSD1306 or SH1106 based LCD modules +// +//#define SAV_3DGLCD +#if ENABLED(SAV_3DGLCD) + //#define U8GLIB_SSD1306 + #define U8GLIB_SH1106 +#endif + +// +// CONTROLLER TYPE: Shift register panels +// +// 2 wire Non-latching LCD SR from https://goo.gl/aJJ4sH +// LCD configuration: http://reprap.org/wiki/SAV_3D_LCD +// +//#define SAV_3DLCD + +// +// TinyBoy2 128x64 OLED / Encoder Panel +// +//#define OLED_PANEL_TINYBOY2 + +// +// Makeboard 3D Printer Parts 3D Printer Mini Display 1602 Mini Controller +// https://www.aliexpress.com/item/Micromake-Makeboard-3D-Printer-Parts-3D-Printer-Mini-Display-1602-Mini-Controller-Compatible-with-Ramps-1/32765887917.html +// +//#define MAKEBOARD_MINI_2_LINE_DISPLAY_1602 + +// +// MKS MINI12864 with graphic controller and SD support +// http://reprap.org/wiki/MKS_MINI_12864 +// +//#define MKS_MINI_12864 + +// +// Factory display for Creality CR-10 +// https://www.aliexpress.com/item/Universal-LCD-12864-3D-Printer-Display-Screen-With-Encoder-For-CR-10-CR-7-Model/32833148327.html +// +// This is RAMPS-compatible using a single 10-pin connector. +// (For CR-10 owners who want to replace the Melzi Creality board but retain the display) +// +//#define CR10_STOCKDISPLAY + +// +// MKS OLED 1.3" 128 × 64 FULL GRAPHICS CONTROLLER +// http://reprap.org/wiki/MKS_12864OLED +// +// Tiny, but very sharp OLED display +// +//#define MKS_12864OLED + +//============================================================================= +//=============================== Extra Features ============================== +//============================================================================= + +// @section extras + +// Increase the FAN PWM frequency. Removes the PWM noise but increases heating in the FET/Arduino +//#define FAST_PWM_FAN + +// Use software PWM to drive the fan, as for the heaters. This uses a very low frequency +// which is not as annoying as with the hardware PWM. On the other hand, if this frequency +// is too low, you should also increment SOFT_PWM_SCALE. +//#define FAN_SOFT_PWM + +// Incrementing this by 1 will double the software PWM frequency, +// affecting heaters, and the fan if FAN_SOFT_PWM is enabled. +// However, control resolution will be halved for each increment; +// at zero value, there are 128 effective control positions. +#define SOFT_PWM_SCALE 0 + +// If SOFT_PWM_SCALE is set to a value higher than 0, dithering can +// be used to mitigate the associated resolution loss. If enabled, +// some of the PWM cycles are stretched so on average the desired +// duty cycle is attained. +//#define SOFT_PWM_DITHER + +// Temperature status LEDs that display the hotend and bed temperature. +// If all hotends, bed temperature, and target temperature are under 54C +// then the BLUE led is on. Otherwise the RED led is on. (1C hysteresis) +//#define TEMP_STAT_LEDS + +// M240 Triggers a camera by emulating a Canon RC-1 Remote +// Data from: http://www.doc-diy.net/photo/rc-1_hacked/ +//#define PHOTOGRAPH_PIN 23 + +// 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 + +// Support for BlinkM/CyzRgb +//#define BLINKM + +// Support for PCA9632 PWM LED driver +//#define PCA9632 + +/** + * RGB LED / LED Strip Control + * + * Enable support for an RGB LED connected to 5V digital pins, or + * an RGB Strip connected to MOSFETs controlled by digital pins. + * + * 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 overall brightness parameters is also available + * + * *** CAUTION *** + * LED Strips require a MOFSET 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! + * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino + * cannot handle such current, separate 5V power supply must be used + * *** CAUTION *** + * + * LED type. This options are mutualy exclusive. Uncomment only one. + * + */ +//#define RGB_LED +//#define RGBW_LED + +#if ENABLED(RGB_LED) || ENABLED(RGBW_LED) + #define RGB_LED_R_PIN 34 + #define RGB_LED_G_PIN 43 + #define RGB_LED_B_PIN 35 + #define RGB_LED_W_PIN -1 +#endif + +// 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 (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) + #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip + #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time + #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + //#define NEOPIXEL_STARTUP_TEST // Cycle through colors at startup +#endif + +/** + * Printer Event LEDs + * + * During printing, the LEDs will reflect the printer status: + * + * - Gradually change from blue to violet as the heated bed gets to target temp + * - Gradually change from violet to red as the hotend gets to temperature + * - Change to white to illuminate work surface + * - Change to green once print has finished + * - Turn off after the print has finished and the user has pushed a button + */ +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) + #define PRINTER_EVENT_LEDS +#endif + +/*********************************************************************\ +* R/C SERVO support +* Sponsored by TrinityLabs, Reworked by codexmas +**********************************************************************/ + +// Number of servos +// +// If you select a configuration below, this will receive a default value and does not need to be set manually +// set it manually if you have more servos than extruders and wish to manually control some +// leaving it undefined or defining as 0 will disable the servo subsystem +// If unsure, leave commented / disabled +// +//#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command + +// Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. +// 300ms is a good value but you can try less delay. +// If the servo can't reach the requested position, increase it. +#define SERVO_DELAY { 300 } + +// Servo deactivation +// +// With this option servos are powered only during movement, then turned off to prevent jitter. +//#define DEACTIVATE_SERVOS_AFTER_MOVE + +/** + * Filament Width Sensor + * + * Measures the filament width in real-time and adjusts + * flow rate to compensate for any irregularities. + * + * Also allows the measured filament diameter to set the + * extrusion rate, so the slicer only has to specify the + * volume. + * + * Only a single extruder is supported at this time. + * + * 34 RAMPS_14 : Analog input 5 on the AUX2 connector + * 81 PRINTRBOARD : Analog input 2 on the Exp1 connector (version B,C,D,E) + * 301 RAMBO : Analog input 3 + * + * Note: May require analog pins to be defined for other boards. + */ +//#define FILAMENT_WIDTH_SENSOR + +#define DEFAULT_NOMINAL_FILAMENT_DIA 3.00 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. + +#if ENABLED(FILAMENT_WIDTH_SENSOR) + #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) + #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber + + #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading + #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading + #define MAX_MEASUREMENT_DELAY 20 // (bytes) Buffer size for stored measurements (1 byte per cm). Must be larger than MEASUREMENT_DELAY_CM. + + #define DEFAULT_MEASURED_FILAMENT_DIA DEFAULT_NOMINAL_FILAMENT_DIA // Set measured to nominal initially + + // Display filament width on the LCD status line. Status messages will expire after 5 seconds. + //#define FILAMENT_LCD_DISPLAY +#endif + +#endif // CONFIGURATION_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/delta/kossel_pro/Configuration_adv.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/delta/kossel_pro/Configuration_adv.h new file mode 100644 index 00000000..9a519ec1 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/delta/kossel_pro/Configuration_adv.h @@ -0,0 +1,1431 @@ +/** + * 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 . + * + */ + +// Example configuration file for OpenBeam Kossel Pro +// tested on 2015-05-19 by @Wackerbarth +// using Arduino 1.6.5 (Mac) + + +/** + * Configuration_adv.h + * + * Advanced settings. + * Only change these if you know exactly what you're doing. + * Some of these settings can damage your printer if improperly set! + * + * Basic settings can be found in Configuration.h + * + */ +#ifndef CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H_VERSION 010100 + +// @section temperature + +//=========================================================================== +//=============================Thermal Settings ============================ +//=========================================================================== + +#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 + #endif +#endif + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * The solution: Once the temperature reaches the target, start observing. + * If the temperature stays too far below the target (hysteresis) for too long (period), + * the firmware will halt the machine as a safety precaution. + * + * If you get false positives for "Thermal Runaway" increase THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD + */ +#if ENABLED(THERMAL_PROTECTION_HOTENDS) + #define THERMAL_PROTECTION_PERIOD 40 // Seconds + #define THERMAL_PROTECTION_HYSTERESIS 4 // Degrees Celsius + + /** + * Whenever an M104 or M109 increases the target temperature the firmware will wait for the + * WATCH_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get false positives for "Heating failed" increase WATCH_TEMP_PERIOD and/or decrease WATCH_TEMP_INCREASE + * WATCH_TEMP_INCREASE should not be below 2. + */ + #define WATCH_TEMP_PERIOD 20 // Seconds + #define WATCH_TEMP_INCREASE 2 // Degrees Celsius +#endif + +/** + * Thermal Protection parameters for the bed are just as above for hotends. + */ +#if ENABLED(THERMAL_PROTECTION_BED) + #define THERMAL_PROTECTION_BED_PERIOD 20 // Seconds + #define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius + + /** + * Whenever an M140 or M190 increases the target temperature the firmware will wait for the + * WATCH_BED_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_BED_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get too many "Heating failed" errors, increase WATCH_BED_TEMP_PERIOD and/or decrease + * WATCH_BED_TEMP_INCREASE. (WATCH_BED_TEMP_INCREASE should not be below 2.) + */ + #define WATCH_BED_TEMP_PERIOD 60 // Seconds + #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius +#endif + +#if ENABLED(PIDTEMP) + // this adds an experimental additional term to the heating power, proportional to the extrusion speed. + // if Kc is chosen well, the additional required power due to increased melting should be compensated. + //#define PID_EXTRUSION_SCALING + #if ENABLED(PID_EXTRUSION_SCALING) + #define DEFAULT_Kc (100) //heating power=Kc*(e_speed) + #define LPQ_MAX_LEN 50 + #endif +#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 + */ +#define AUTOTEMP +#if ENABLED(AUTOTEMP) + #define AUTOTEMP_OLDWEIGHT 0.98 +#endif + +// Show Temperature ADC value +// Enable for M105 to include ADC values read from temperature sensors. +//#define SHOW_TEMP_ADC_VALUES + +/** + * High Temperature Thermistor Support + * + * Thermistors able to support high temperature tend to have a hard time getting + * good readings at room and lower temperatures. This means HEATER_X_RAW_LO_TEMP + * will probably be caught when the heating element first turns on during the + * preheating process, which will trigger a min_temp_error as a safety measure + * and force stop everything. + * To circumvent this limitation, we allow for a preheat time (during which, + * min_temp_error won't be triggered) and add a min_temp buffer to handle + * aberrant readings. + * + * If you want to enable this feature for your hotend thermistor(s) + * uncomment and set values > 0 in the constants below + */ + +// The number of consecutive low temperature errors that can occur +// before a min_temp_error is triggered. (Shouldn't be more than 10.) +//#define MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED 0 + +// The number of milliseconds a hotend will preheat before starting to check +// the temperature. This value should NOT be set to the time it takes the +// hot end to reach the target temperature, but the time it takes to reach +// the minimum temperature your thermistor can read. The lower the better/safer. +// This shouldn't need to be more than 30 seconds (30000) +//#define MILLISECONDS_PREHEAT_TIME 0 + +// @section extruder + +// Extruder runout prevention. +// If the machine is idle and the temperature over MINTEMP +// then extrude some filament every couple of SECONDS. +//#define EXTRUDER_RUNOUT_PREVENT +#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_EXTRUDE 5 // mm +#endif + +// @section temperature + +//These defines help to calibrate the AD595 sensor in case you get wrong temperature measurements. +//The measured temperature is defined as "actualTemp = (measuredTemp * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET" +#define TEMP_SENSOR_AD595_OFFSET 0.0 +#define TEMP_SENSOR_AD595_GAIN 1.0 + +/** + * 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. + */ +//#define USE_CONTROLLER_FAN +#if ENABLED(USE_CONTROLLER_FAN) + //#define CONTROLLER_FAN_PIN FAN1_PIN // 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 +#endif + +// When first starting the main fan, run it at full speed for the +// given number of milliseconds. This gets the fan spinning reliably +// before setting a PWM value. (Does not work with software PWM for fan on Sanguinololu) +//#define FAN_KICKSTART_TIME 100 + +// This defines the minimal speed for the main fan, run in PWM mode +// to enable uncomment and set minimal PWM speed for reliable running (1-255) +// if fan speed is [1 - (FAN_MIN_PWM-1)] it is set to FAN_MIN_PWM +//#define FAN_MIN_PWM 50 + +// @section extruder + +/** + * Extruder cooling fans + * + * Extruder auto fans automatically turn on when their extruders' + * temperatures go above EXTRUDER_AUTO_FAN_TEMPERATURE. + * + * Your board's pins file specifies the recommended pins. Override those here + * or set to -1 to disable completely. + * + * Multiple extruders can be assigned to the same pin in which case + * the fan will turn on when any selected extruder is above the threshold. + */ +#define E0_AUTO_FAN_PIN -1 +#define E1_AUTO_FAN_PIN -1 +#define E2_AUTO_FAN_PIN -1 +#define E3_AUTO_FAN_PIN -1 +#define E4_AUTO_FAN_PIN -1 +#define EXTRUDER_AUTO_FAN_TEMPERATURE 50 +#define EXTRUDER_AUTO_FAN_SPEED 255 // == full speed + +/** + * Part-Cooling Fan Multiplexer + * + * This feature allows you to digitally multiplex the fan output. + * The multiplexer is automatically switched at tool-change. + * Set FANMUX[012]_PINs below for up to 2, 4, or 8 multiplexed fans. + */ +#define FANMUX0_PIN -1 +#define FANMUX1_PIN -1 +#define FANMUX2_PIN -1 + +/** + * M355 Case Light on-off / brightness + */ +//#define CASE_LIGHT_ENABLE +#if ENABLED(CASE_LIGHT_ENABLE) + //#define CASE_LIGHT_PIN 4 // Override the default pin if needed + #define INVERT_CASE_LIGHT false // Set true if Case Light is ON when pin is LOW + #define CASE_LIGHT_DEFAULT_ON true // Set default power-up state on + #define CASE_LIGHT_DEFAULT_BRIGHTNESS 105 // Set default power-up brightness (0-255, requires PWM pin) + //#define MENU_ITEM_CASE_LIGHT // Add a Case Light option to the LCD main menu +#endif + +//=========================================================================== +//============================ Mechanical Settings ========================== +//=========================================================================== + +// @section homing + +// If you want endstops to stay on (by default) even when not homing +// enable this option. Override at any time with M120, M121. +//#define ENDSTOPS_ALWAYS_ON_DEFAULT + +// @section extras + +//#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. + +// Dual X Steppers +// Uncomment this option to drive two X axis motors. +// The next unused E driver will be assigned to the second X stepper. +//#define X_DUAL_STEPPER_DRIVERS +#if ENABLED(X_DUAL_STEPPER_DRIVERS) + // Set true if the two X motors need to rotate in opposite directions + #define INVERT_X2_VS_X_DIR true +#endif + +// Dual Y Steppers +// Uncomment this option to drive two Y axis motors. +// The next unused E driver will be assigned to the second Y stepper. +//#define Y_DUAL_STEPPER_DRIVERS +#if ENABLED(Y_DUAL_STEPPER_DRIVERS) + // Set true if the two Y motors need to rotate in opposite directions + #define INVERT_Y2_VS_Y_DIR true +#endif + +// A single Z stepper driver is usually used to drive 2 stepper motors. +// Uncomment this option to use a separate stepper driver for each Z axis motor. +// The next unused E driver will be assigned to the second Z stepper. +//#define Z_DUAL_STEPPER_DRIVERS + +#if ENABLED(Z_DUAL_STEPPER_DRIVERS) + + // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper. + // That way the machine is capable to align the bed during home, since both Z steppers are homed. + // There is also an implementation of M666 (software endstops adjustment) to this feature. + // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed. + // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2. + // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive. + // Play a little bit with small adjustments (0.5mm) and check the behaviour. + // The M119 (endstops report) will start reporting the Z2 Endstop as well. + + //#define Z_DUAL_ENDSTOPS + + #if ENABLED(Z_DUAL_ENDSTOPS) + #define Z2_USE_ENDSTOP _XMAX_ + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 // Use M666 to determine/test this value + #endif + +#endif // Z_DUAL_STEPPER_DRIVERS + +// Enable this for dual x-carriage printers. +// A dual x-carriage design has the advantage that the inactive extruder can be parked which +// prevents hot-end ooze contaminating the print. It also reduces the weight of each x-carriage +// allowing faster printing speeds. Connect your X2 stepper to the first unused E plug. +//#define DUAL_X_CARRIAGE +#if ENABLED(DUAL_X_CARRIAGE) + // Configuration for second X-carriage + // Note: the first x-carriage is defined as the x-carriage which homes to the minimum endstop; + // the second x-carriage always homes to the maximum endstop. + #define X2_MIN_POS 80 // set minimum to ensure second x-carriage doesn't hit the parked first X-carriage + #define X2_MAX_POS 353 // set maximum to the distance between toolheads when both heads are homed + #define X2_HOME_DIR 1 // the second X-carriage always homes to the maximum endstop position + #define X2_HOME_POS X2_MAX_POS // default home position is the maximum carriage position + // However: In this mode the HOTEND_OFFSET_X value for the second extruder provides a software + // override for X2_HOME_POS. This also allow recalibration of the distance between the two endstops + // without modifying the firmware (through the "M218 T1 X???" command). + // Remember: you should set the second extruder x-offset to 0 in your slicer. + + // There are a few selectable movement modes for dual x-carriages using M605 S + // Mode 0 (DXC_FULL_CONTROL_MODE): Full control. The slicer has full control over both x-carriages and can achieve optimal travel results + // as long as it supports dual x-carriages. (M605 S0) + // Mode 1 (DXC_AUTO_PARK_MODE) : Auto-park mode. The firmware will automatically park and unpark the x-carriages on tool changes so + // that additional slicer support is not required. (M605 S1) + // Mode 2 (DXC_DUPLICATION_MODE) : Duplication mode. The firmware will transparently make the second x-carriage and extruder copy all + // actions of the first x-carriage. This allows the printer to print 2 arbitrary items at + // once. (2nd extruder x offset and temp offset are set using: M605 S2 [Xnnn] [Rmmm]) + + // This is the default power-up mode which can be later using M605. + #define DEFAULT_DUAL_X_CARRIAGE_MODE DXC_FULL_CONTROL_MODE + + // Default settings in "Auto-park Mode" + #define TOOLCHANGE_PARK_ZLIFT 0.2 // the distance to raise Z axis when parking an extruder + #define TOOLCHANGE_UNPARK_ZLIFT 1 // the distance to raise Z axis when unparking an extruder + + // Default x offset in duplication mode (typically set to half print bed width) + #define DEFAULT_DUPLICATION_X_OFFSET 100 + +#endif // DUAL_X_CARRIAGE + +// 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. +//#define EXT_SOLENOID + +// @section homing + +//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +#define X_HOME_BUMP_MM 5 +#define Y_HOME_BUMP_MM 5 +#define Z_HOME_BUMP_MM 5 // deltas need the same for all three axes +#define HOMING_BUMP_DIVISOR {10, 10, 10} // Re-Bump Speed Divisor (Divides the Homing Feedrate) +//#define QUICK_HOME //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially. + +// When G28 is called, this option will make Y home before X +//#define HOME_Y_BEFORE_X + +// @section machine + +#define AXIS_RELATIVE_MODES {false, false, false, false} + +// Allow duplication mode with a basic dual-nozzle extruder +//#define DUAL_NOZZLE_DUPLICATION_MODE + +// By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step. +#define INVERT_X_STEP_PIN false +#define INVERT_Y_STEP_PIN false +#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. +#define DEFAULT_STEPPER_DEACTIVE_TIME 60 +#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_E true + +#define DEFAULT_MINIMUMFEEDRATE 0.0 // minimum feedrate +#define DEFAULT_MINTRAVELFEEDRATE 0.0 + +//#define HOME_AFTER_DEACTIVATE // Require rehoming after steppers are deactivated + +// @section lcd + +#if ENABLED(ULTIPANEL) + #define MANUAL_FEEDRATE_XYZ 50*60 + #define MANUAL_FEEDRATE { MANUAL_FEEDRATE_XYZ, MANUAL_FEEDRATE_XYZ, MANUAL_FEEDRATE_XYZ, 60 } // Feedrates for manual moves along X, Y, Z, E from panel + #define ULTIPANEL_FEEDMULTIPLY // Comment to disable setting feedrate multiplier via encoder +#endif + +// @section extras + +// minimum time in microseconds that a movement needs to take if the buffer is emptied. +#define DEFAULT_MINSEGMENTTIME 20000 + +// If defined the movements slow down when the look ahead buffer is only half full +// (don't use SLOWDOWN with DELTA because DELTA generates hundreds of segments per second) +//#define SLOWDOWN + +// Frequency limit +// See nophead's blog for more info +// Not working O +//#define XY_FREQUENCY_LIMIT 15 + +// 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 +// if unwanted behavior is observed on a user's machine when running at very slow speeds. +#define MINIMUM_PLANNER_SPEED 0.05 // (mm/sec) + +// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU. +#define MICROSTEP_MODES {16,16,16,16,16} // [1,2,4,8,16] + +/** + * @section stepper motor current + * + * Some boards have a means of setting the stepper motor current via firmware. + * + * The power on motor currents are set by: + * PWM_MOTOR_CURRENT - used by MINIRAMBO & ULTIMAIN_2 + * known compatible chips: A4982 + * DIGIPOT_MOTOR_CURRENT - used by BQ_ZUM_MEGA_3D, RAMBO & SCOOVO_X9H + * known compatible chips: AD5206 + * DAC_MOTOR_CURRENT_DEFAULT - used by PRINTRBOARD_REVF & RIGIDBOARD_V2 + * known compatible chips: MCP4728 + * DIGIPOT_I2C_MOTOR_CURRENTS - used by 5DPRINT, AZTEEG_X3_PRO, MIGHTYBOARD_REVE + * known compatible chips: MCP4451, MCP4018 + * + * Motor currents can also be set by M907 - M910 and by the LCD. + * M907 - applies to all. + * M908 - BQ_ZUM_MEGA_3D, RAMBO, PRINTRBOARD_REVF, RIGIDBOARD_V2 & SCOOVO_X9H + * M909, M910 & LCD - only PRINTRBOARD_REVF & RIGIDBOARD_V2 + */ +//#define PWM_MOTOR_CURRENT { 1300, 1300, 1250 } // Values in milliamps +//#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 + +// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +//#define DIGIPOT_I2C +//#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster +#define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 +// Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS +#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=========================== +//=========================================================================== + +#define ENCODER_RATE_MULTIPLIER // If defined, certain menu edit operations automatically multiply the steps when the encoder is moved quickly +#define ENCODER_10X_STEPS_PER_SEC 75 // If the encoder steps per sec exceeds this value, multiply steps moved x10 to quickly advance the value +#define ENCODER_100X_STEPS_PER_SEC 160 // If the encoder steps per sec exceeds this value, multiply steps moved x100 to really quickly advance the value + +//#define CHDK 4 //Pin for triggering CHDK to take a picture see how to use it here http://captain-slow.dk/2014/03/09/3d-printing-timelapses/ +#define CHDK_DELAY 50 //How long in ms the pin should stay HIGH before going LOW again + +// @section lcd + +// Include a page of printer information in the LCD Main Menu +//#define LCD_INFO_MENU + +// Scroll a longer status message into view +//#define STATUS_MESSAGE_SCROLLING + +// On the Info Screen, display XY with one decimal place when possible +//#define LCD_DECIMAL_SMALL_XY + +// The timeout (in ms) to return to the status screen from sub-menus +//#define LCD_TIMEOUT_TO_STATUS 15000 + +#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 + + #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? + #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. + + #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. + // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. + // using: + //#define MENU_ADDAUTOSTART + + /** + * Sort SD file listings in alphabetical order. + * + * With this option enabled, items on SD cards will be sorted + * by name for easier navigation. + * + * By default... + * + * - Use the slowest -but safest- method for sorting. + * - Folders are sorted to the top. + * - The sort key is statically allocated. + * - No added G-code (M34) support. + * - 40 item sorting limit. (Items after the first 40 are unsorted.) + * + * SD sorting uses static allocation (as set by SDSORT_LIMIT), allowing the + * compiler to calculate the worst-case usage and throw an error if the SRAM + * limit is exceeded. + * + * - SDSORT_USES_RAM provides faster sorting via a static directory buffer. + * - SDSORT_USES_STACK does the same, but uses a local stack-based buffer. + * - SDSORT_CACHE_NAMES will retain the sorted file listing in RAM. (Expensive!) + * - SDSORT_DYNAMIC_RAM only uses RAM when the SD menu is visible. (Use with caution!) + */ + //#define SDCARD_SORT_ALPHA + + // SD Card Sorting options + #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_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. + #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #endif + + // Show a progress bar on HD44780 LCDs for SD printing + //#define LCD_PROGRESS_BAR + + #if ENABLED(LCD_PROGRESS_BAR) + // Amount of time (ms) to show the bar + #define PROGRESS_BAR_BAR_TIME 2000 + // Amount of time (ms) to show the status message + #define PROGRESS_BAR_MSG_TIME 3000 + // Amount of time (ms) to retain the status message (0=forever) + #define PROGRESS_MSG_EXPIRE 0 + // Enable this to show messages for MSG_TIME then hide them + //#define PROGRESS_MSG_ONCE + // Add a menu item to test the progress bar: + //#define LCD_PROGRESS_BAR_TEST + #endif + + // This allows hosts to request long names for files and folders with M33 + //#define LONG_FILENAME_HOST_SUPPORT + + // This option allows you to abort SD printing when any endstop is triggered. + // This feature must be enabled with "M540 S1" or from the LCD menu. + // To have any effect, endstops must be enabled during SD printing. + //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + +#endif // SDSUPPORT + +/** + * Additional options for Graphical Displays + * + * Use the optimizations here to improve printing performance, + * which can be adversely affected by graphical display drawing, + * especially when doing several short moves, and when printing + * on DELTA and SCARA machines. + * + * Some of these options may result in the display lagging behind + * controller events, as there is a trade-off between reliable + * printing performance versus fast display updates. + */ +#if ENABLED(DOGLCD) + // Enable to save many cycles by drawing a hollow frame on the Info Screen + #define XYZ_HOLLOW_FRAME + + // Enable to save many cycles by drawing a hollow frame on Menu Screens + #define MENU_HOLLOW_FRAME + + // A bigger font is available for edit items. Costs 3120 bytes of PROGMEM. + // 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. + // 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 +#endif // DOGLCD + +// @section safety + +// The hardware watchdog should reset the microcontroller disabling all outputs, +// in case the firmware gets stuck and doesn't do temperature regulation. +#define USE_WATCHDOG + +#if ENABLED(USE_WATCHDOG) + // If you have a watchdog reboot in an ArduinoMega2560 then the device will hang forever, as a watchdog reset will leave the watchdog on. + // The "WATCHDOG_RESET_MANUAL" goes around this by not using the hardware reset. + // However, THIS FEATURE IS UNSAFE!, as it will only work if interrupts are disabled. And the code could hang in an interrupt routine with interrupts disabled. + //#define WATCHDOG_RESET_MANUAL +#endif + +// @section lcd + +/** + * Babystepping enables movement of the axes by tiny increments without changing + * the current position values. This feature is used primarily to adjust the Z + * axis in the first layer of a print in real-time. + * + * Warning: Does not respect endstops! + */ +//#define BABYSTEPPING +#if ENABLED(BABYSTEPPING) + //#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 100 // Babysteps are very small. Increase for faster motion. + //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping + //#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen 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_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor + //#define BABYSTEP_ZPROBE_GFX_REVERSE // Reverses the direction of the CW/CCW indicators +#endif + +// @section extruder + +/** + * Implementation of linear pressure control + * + * Assumption: advance = k * (delta velocity) + * K=0 means advance disabled. + * See Marlin documentation for calibration instructions. + */ +//#define LIN_ADVANCE + +#if ENABLED(LIN_ADVANCE) + #define LIN_ADVANCE_K 75 + + /** + * Some Slicers produce Gcode with randomly jumping extrusion widths occasionally. + * For example within a 0.4mm perimeter it may produce a single segment of 0.05mm width. + * While this is harmless for normal printing (the fluid nature of the filament will + * close this very, very tiny gap), it throws off the LIN_ADVANCE pressure adaption. + * + * For this case LIN_ADVANCE_E_D_RATIO can be used to set the extrusion:distance ratio + * to a fixed value. Note that using a fixed ratio will lead to wrong nozzle pressures + * if the slicer is using variable widths or layer heights within one print! + * + * This option sets the default E:D ratio at startup. Use `M900` to override this value. + * + * Example: `M900 W0.4 H0.2 D1.75`, where: + * - W is the extrusion width in mm + * - H is the layer height in mm + * - D is the filament diameter in mm + * + * Example: `M900 R0.0458` to set the ratio directly. + * + * Set to 0 to auto-detect the ratio based on given Gcode G1 print moves. + * + * Slic3r (including Průša Control) produces Gcode compatible with the automatic mode. + * Cura (as of this writing) may produce Gcode incompatible with the automatic mode. + */ + #define LIN_ADVANCE_E_D_RATIO 0 // The calculated ratio (or 0) according to the formula W * H / ((D / 2) ^ 2 * PI) + // Example: 0.4 * 0.2 / ((1.75 / 2) ^ 2 * PI) = 0.033260135 +#endif + +// @section leveling + +// Default mesh area is an area with an inset margin on the print area. +// Below are the macros that are used to define the borders for the mesh area, +// made available here for specialized needs, ie dual extruder setup. +#if ENABLED(MESH_BED_LEVELING) + #define MESH_MIN_X MESH_INSET + #define MESH_MAX_X (X_BED_SIZE - (MESH_INSET)) + #define MESH_MIN_Y MESH_INSET + #define MESH_MAX_Y (Y_BED_SIZE - (MESH_INSET)) +#elif ENABLED(AUTO_BED_LEVELING_UBL) + #define UBL_MESH_MIN_X UBL_MESH_INSET + #define UBL_MESH_MAX_X (X_BED_SIZE - (UBL_MESH_INSET)) + #define UBL_MESH_MIN_Y UBL_MESH_INSET + #define UBL_MESH_MAX_Y (Y_BED_SIZE - (UBL_MESH_INSET)) + + // If this is defined, the currently active mesh will be saved in the + // current slot on M500. + #define UBL_SAVE_ACTIVE_ON_M500 +#endif + +// @section extras + +// +// G2/G3 Arc Support +// +#define ARC_SUPPORT // Disable this feature to save ~3226 bytes +#if ENABLED(ARC_SUPPORT) + #define MM_PER_ARC_SEGMENT 1 // Length of each arc segment + #define N_ARC_CORRECTION 25 // Number of intertpolated 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 +#endif + +// Support for G5 with XYZE destination and IJPQ offsets. Requires ~2666 bytes. +//#define BEZIER_CURVE_SUPPORT + +// G38.2 and G38.3 Probe Target +// Enable PROBE_DOUBLE_TOUCH if you want G38 to double touch +//#define G38_PROBE_TARGET +#if ENABLED(G38_PROBE_TARGET) + #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) +#endif + +// Moves (or segments) with fewer steps than this will be joined with the next move +#define MIN_STEPS_PER_SEGMENT 6 + +// The minimum pulse width (in µs) for stepping a stepper. +// Set this if you find stepping unreliable, or if using a very fast CPU. +#define MINIMUM_STEPPER_PULSE 0 // (µs) The smallest stepper pulse allowed + +// @section temperature + +// Control heater 0 and heater 1 in parallel. +//#define HEATERS_PARALLEL + +//=========================================================================== +//================================= Buffers ================================= +//=========================================================================== + +// @section hidden + +// 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, i.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 +#else + #define BLOCK_BUFFER_SIZE 16 // maximize block buffer +#endif + +// @section serial + +// The ASCII buffer for serial input +#define MAX_CMD_SIZE 96 +#define BUFSIZE 4 + +// Transmission to Host Buffer Size +// To save 386 bytes of PROGMEM (and TX_BUFFER_SIZE+3 bytes of RAM) set to 0. +// To buffer a simple "ok" you need 4 bytes. +// For ADVANCED_OK (M105) you need 32 bytes. +// For debug-echo: 128 bytes for the optimal speed. +// Other output doesn't need to be that speedy. +// :[0, 2, 4, 8, 16, 32, 64, 128, 256] +#define TX_BUFFER_SIZE 0 + +// Host Receive Buffer Size +// Without XON/XOFF flow control (see SERIAL_XON_XOFF below) 32 bytes should be enough. +// To use flow control, set this buffer size to at least 1024 bytes. +// :[0, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048] +//#define RX_BUFFER_SIZE 1024 + +#if RX_BUFFER_SIZE >= 1024 + // Enable to have the controller send XON/XOFF control characters to + // the host to signal the RX buffer is becoming full. + //#define SERIAL_XON_XOFF +#endif + +#if ENABLED(SDSUPPORT) + // Enable this option to collect and display the maximum + // RX queue usage after transferring a file to SD. + //#define SERIAL_STATS_MAX_RX_QUEUED + + // Enable this option to collect and display the number + // of dropped bytes after a file transfer to SD. + //#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! +//#define EMERGENCY_PARSER + +// Bad Serial-connections can miss a received command by sending an 'ok' +// Therefore some clients abort after 30 seconds in a timeout. +// Some other clients start sending commands while receiving a 'wait'. +// This "wait" is only sent when the buffer is empty. 1 second is a good value here. +//#define NO_TIMEOUTS 1000 // Milliseconds + +// Some clients will have this feature soon. This could make the NO_TIMEOUTS unnecessary. +//#define ADVANCED_OK + +// @section extras + +/** + * Firmware-based and LCD-controlled retract + * + * Add G10 / G11 commands for automatic firmware-based retract / recover. + * Use M207 and M208 to define parameters for retract / recover. + * + * Use M209 to enable or disable auto-retract. + * With auto-retract enabled, all G1 E moves within the set range + * will be converted to firmware-based retract/recover moves. + * + * Be sure to turn off auto-retract during filament change. + * + * Note that M207 / M208 / M209 settings are saved to EEPROM. + * + */ +//#define FWRETRACT // ONLY PARTIALLY TESTED +#if ENABLED(FWRETRACT) + #define MIN_AUTORETRACT 0.1 // When auto-retract is on, convert E moves of this length and over + #define MAX_AUTORETRACT 10.0 // Upper limit for auto-retract conversion + #define RETRACT_LENGTH 3 // Default retract length (positive mm) + #define RETRACT_LENGTH_SWAP 13 // Default swap retract length (positive mm), for extruder change + #define RETRACT_FEEDRATE 45 // Default feedrate for retracting (mm/s) + #define RETRACT_ZLIFT 0 // Default retract Z-lift + #define RETRACT_RECOVER_LENGTH 0 // Default additional recover length (mm, added to retract length when recovering) + #define RETRACT_RECOVER_LENGTH_SWAP 0 // Default additional swap recover length (mm, added to retract length when recovering from extruder change) + #define RETRACT_RECOVER_FEEDRATE 8 // Default feedrate for recovering from retraction (mm/s) + #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) +#endif + +/** + * Advanced Pause + * Experimental feature for filament change support and for parking the nozzle when paused. + * Adds the GCode M600 for initiating filament change. + * If PARK_HEAD_ON_PAUSE enabled, adds the GCode M125 to pause printing and park the nozzle. + * + * Requires an LCD display. + * This feature is required for the default FILAMENT_RUNOUT_SCRIPT. + */ +//#define ADVANCED_PAUSE_FEATURE +#if ENABLED(ADVANCED_PAUSE_FEATURE) + #define PAUSE_PARK_X_POS 3 // X position of hotend + #define PAUSE_PARK_Y_POS 3 // Y position of hotend + #define PAUSE_PARK_Z_ADD 10 // Z addition of hotend (lift) + #define PAUSE_PARK_XY_FEEDRATE 100 // X and Y axes feedrate in mm/s (also used for delta printers Z axis) + #define PAUSE_PARK_Z_FEEDRATE 5 // Z axis feedrate in mm/s (not used for delta printers) + #define PAUSE_PARK_RETRACT_FEEDRATE 60 // Initial retract feedrate in mm/s + #define PAUSE_PARK_RETRACT_LENGTH 2 // Initial retract in mm + // It is a short retract used immediately after print interrupt before move to filament exchange position + #define FILAMENT_CHANGE_UNLOAD_FEEDRATE 10 // Unload filament feedrate in mm/s - filament unloading can be fast + #define FILAMENT_CHANGE_UNLOAD_LENGTH 100 // Unload filament length from hotend in mm + // Longer length for bowden printers to unload filament from whole bowden tube, + // shorter length for printers without bowden to unload filament from extruder only, + // 0 to disable unloading for manual unloading + #define FILAMENT_CHANGE_LOAD_FEEDRATE 6 // Load filament feedrate in mm/s - filament loading into the bowden tube can be fast + #define FILAMENT_CHANGE_LOAD_LENGTH 0 // Load filament length over hotend in mm + // Longer length for bowden printers to fast load filament into whole bowden tube over the hotend, + // Short or zero length for printers without bowden where loading is not used + #define ADVANCED_PAUSE_EXTRUDE_FEEDRATE 3 // Extrude filament feedrate in mm/s - must be slower than load feedrate + #define ADVANCED_PAUSE_EXTRUDE_LENGTH 50 // Extrude filament length in mm after filament is loaded over the hotend, + // 0 to disable for manual extrusion + // Filament can be extruded repeatedly from the filament exchange menu to fill the hotend, + // or until outcoming filament color is not clear for filament color change + #define PAUSE_PARK_NOZZLE_TIMEOUT 45 // Turn off nozzle if user doesn't change filament within this time limit in seconds + #define FILAMENT_CHANGE_NUMBER_OF_ALERT_BEEPS 5 // Number of alert beeps before printer goes quiet + #define PAUSE_PARK_NO_STEPPER_TIMEOUT // Enable to have stepper motors hold position during filament change + // even if it takes longer than DEFAULT_STEPPER_DEACTIVE_TIME. + //#define PARK_HEAD_ON_PAUSE // Go to filament change position on pause, return to print position on resume + //#define HOME_BEFORE_FILAMENT_CHANGE // Ensure homing has been completed prior to parking for filament change +#endif + +// @section tmc + +/** + * Enable this section if you have TMC26X motor drivers. + * You will need to import the TMC26XStepper library into the Arduino IDE for this + * (https://github.com/trinamic/TMC26XStepper.git) + */ +//#define HAVE_TMCDRIVER + +#if ENABLED(HAVE_TMCDRIVER) + + //#define X_IS_TMC + //#define X2_IS_TMC + //#define Y_IS_TMC + //#define Y2_IS_TMC + //#define Z_IS_TMC + //#define Z2_IS_TMC + //#define E0_IS_TMC + //#define E1_IS_TMC + //#define E2_IS_TMC + //#define E3_IS_TMC + //#define E4_IS_TMC + + #define X_MAX_CURRENT 1000 // in mA + #define X_SENSE_RESISTOR 91 // in mOhms + #define X_MICROSTEPS 16 // number of microsteps + + #define X2_MAX_CURRENT 1000 + #define X2_SENSE_RESISTOR 91 + #define X2_MICROSTEPS 16 + + #define Y_MAX_CURRENT 1000 + #define Y_SENSE_RESISTOR 91 + #define Y_MICROSTEPS 16 + + #define Y2_MAX_CURRENT 1000 + #define Y2_SENSE_RESISTOR 91 + #define Y2_MICROSTEPS 16 + + #define Z_MAX_CURRENT 1000 + #define Z_SENSE_RESISTOR 91 + #define Z_MICROSTEPS 16 + + #define Z2_MAX_CURRENT 1000 + #define Z2_SENSE_RESISTOR 91 + #define Z2_MICROSTEPS 16 + + #define E0_MAX_CURRENT 1000 + #define E0_SENSE_RESISTOR 91 + #define E0_MICROSTEPS 16 + + #define E1_MAX_CURRENT 1000 + #define E1_SENSE_RESISTOR 91 + #define E1_MICROSTEPS 16 + + #define E2_MAX_CURRENT 1000 + #define E2_SENSE_RESISTOR 91 + #define E2_MICROSTEPS 16 + + #define E3_MAX_CURRENT 1000 + #define E3_SENSE_RESISTOR 91 + #define E3_MICROSTEPS 16 + + #define E4_MAX_CURRENT 1000 + #define E4_SENSE_RESISTOR 91 + #define E4_MICROSTEPS 16 + +#endif + +// @section TMC2130 + +/** + * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. + * + * You'll also need the TMC2130Stepper Arduino library + * (https://github.com/teemuatlut/TMC2130Stepper). + * + * To use TMC2130 stepper drivers in SPI mode connect your SPI2130 pins to + * the hardware SPI interface on your board and define the required CS pins + * in your `pins_MYBOARD.h` file. (e.g., RAMPS 1.4 uses AUX3 pins `X_CS_PIN 53`, `Y_CS_PIN 49`, etc.). + */ +//#define HAVE_TMC2130 + +#if ENABLED(HAVE_TMC2130) + + // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY + //#define X_IS_TMC2130 + //#define X2_IS_TMC2130 + //#define Y_IS_TMC2130 + //#define Y2_IS_TMC2130 + //#define Z_IS_TMC2130 + //#define Z2_IS_TMC2130 + //#define E0_IS_TMC2130 + //#define E1_IS_TMC2130 + //#define E2_IS_TMC2130 + //#define E3_IS_TMC2130 + //#define E4_IS_TMC2130 + + /** + * Stepper driver settings + */ + + #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 + #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current + #define INTERPOLATE 1 // Interpolate X/Y/Z_MICROSTEPS to 256 + + #define X_CURRENT 1000 // rms current in mA. Multiply by 1.41 for peak current. + #define X_MICROSTEPS 16 // 0..256 + + #define Y_CURRENT 1000 + #define Y_MICROSTEPS 16 + + #define Z_CURRENT 1000 + #define Z_MICROSTEPS 16 + + //#define X2_CURRENT 1000 + //#define X2_MICROSTEPS 16 + + //#define Y2_CURRENT 1000 + //#define Y2_MICROSTEPS 16 + + //#define Z2_CURRENT 1000 + //#define Z2_MICROSTEPS 16 + + //#define E0_CURRENT 1000 + //#define E0_MICROSTEPS 16 + + //#define E1_CURRENT 1000 + //#define E1_MICROSTEPS 16 + + //#define E2_CURRENT 1000 + //#define E2_MICROSTEPS 16 + + //#define E3_CURRENT 1000 + //#define E3_MICROSTEPS 16 + + //#define E4_CURRENT 1000 + //#define E4_MICROSTEPS 16 + + /** + * Use Trinamic's ultra quiet stepping mode. + * When disabled, Marlin will use spreadCycle stepping mode. + */ + #define STEALTHCHOP + + /** + * Let Marlin automatically control stepper current. + * This is still an experimental feature. + * Increase current every 5s by CURRENT_STEP until stepper temperature prewarn gets triggered, + * then decrease current by CURRENT_STEP until temperature prewarn is cleared. + * Adjusting starts from X/Y/Z/E_CURRENT but will not increase over AUTO_ADJUST_MAX + * 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. + * M906 S1 - Start adjusting current + * M906 S0 - Stop adjusting current + * M911 - Report stepper driver overtemperature pre-warn condition. + * M912 - Clear stepper driver overtemperature pre-warn condition flag. + */ + //#define AUTOMATIC_CURRENT_CONTROL + + #if ENABLED(AUTOMATIC_CURRENT_CONTROL) + #define CURRENT_STEP 50 // [mA] + #define AUTO_ADJUST_MAX 1300 // [mA], 1300mA_rms = 1840mA_peak + #define REPORT_CURRENT_CHANGE + #endif + + /** + * The driver will switch to spreadCycle when stepper speed is over HYBRID_THRESHOLD. + * This mode allows for faster movements at the expense of higher noise levels. + * STEALTHCHOP needs to be enabled. + * M913 X/Y/Z/E to live tune the setting + */ + //#define HYBRID_THRESHOLD + + #define X_HYBRID_THRESHOLD 100 // [mm/s] + #define X2_HYBRID_THRESHOLD 100 + #define Y_HYBRID_THRESHOLD 100 + #define Y2_HYBRID_THRESHOLD 100 + #define Z_HYBRID_THRESHOLD 4 + #define Z2_HYBRID_THRESHOLD 4 + #define E0_HYBRID_THRESHOLD 30 + #define E1_HYBRID_THRESHOLD 30 + #define E2_HYBRID_THRESHOLD 30 + #define E3_HYBRID_THRESHOLD 30 + #define E4_HYBRID_THRESHOLD 30 + + /** + * Use stallGuard2 to sense an obstacle and trigger an endstop. + * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. + * If used along with STEALTHCHOP, the movement will be louder when homing. This is normal. + * + * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. + * Higher values make the system LESS sensitive. + * Lower value make the system MORE sensitive. + * Too low values can lead to false positives, while too high values will collide the axis without triggering. + * It is advised to set X/Y_HOME_BUMP_MM to 0. + * M914 X/Y to live tune the setting + */ + //#define SENSORLESS_HOMING + + #if ENABLED(SENSORLESS_HOMING) + #define X_HOMING_SENSITIVITY 19 + #define Y_HOMING_SENSITIVITY 19 + #endif + + /** + * You can set your own advanced settings by filling in predefined functions. + * A list of available functions can be found on the library github page + * https://github.com/teemuatlut/TMC2130Stepper + * + * Example: + * #define TMC2130_ADV() { \ + * stepperX.diag0_temp_prewarn(1); \ + * stepperX.interpolate(0); \ + * } + */ + #define TMC2130_ADV() { } + +#endif // HAVE_TMC2130 + +// @section L6470 + +/** + * Enable this section if you have L6470 motor drivers. + * You need to import the L6470 library into the Arduino IDE for this. + * (https://github.com/ameyer/Arduino-L6470) + */ + +//#define HAVE_L6470DRIVER +#if ENABLED(HAVE_L6470DRIVER) + + //#define X_IS_L6470 + //#define X2_IS_L6470 + //#define Y_IS_L6470 + //#define Y2_IS_L6470 + //#define Z_IS_L6470 + //#define Z2_IS_L6470 + //#define E0_IS_L6470 + //#define E1_IS_L6470 + //#define E2_IS_L6470 + //#define E3_IS_L6470 + //#define E4_IS_L6470 + + #define X_MICROSTEPS 16 // number of microsteps + #define X_K_VAL 50 // 0 - 255, Higher values, are higher power. Be careful not to go too high + #define X_OVERCURRENT 2000 // maxc current in mA. If the current goes over this value, the driver will switch off + #define X_STALLCURRENT 1500 // current in mA where the driver will detect a stall + + #define X2_MICROSTEPS 16 + #define X2_K_VAL 50 + #define X2_OVERCURRENT 2000 + #define X2_STALLCURRENT 1500 + + #define Y_MICROSTEPS 16 + #define Y_K_VAL 50 + #define Y_OVERCURRENT 2000 + #define Y_STALLCURRENT 1500 + + #define Y2_MICROSTEPS 16 + #define Y2_K_VAL 50 + #define Y2_OVERCURRENT 2000 + #define Y2_STALLCURRENT 1500 + + #define Z_MICROSTEPS 16 + #define Z_K_VAL 50 + #define Z_OVERCURRENT 2000 + #define Z_STALLCURRENT 1500 + + #define Z2_MICROSTEPS 16 + #define Z2_K_VAL 50 + #define Z2_OVERCURRENT 2000 + #define Z2_STALLCURRENT 1500 + + #define E0_MICROSTEPS 16 + #define E0_K_VAL 50 + #define E0_OVERCURRENT 2000 + #define E0_STALLCURRENT 1500 + + #define E1_MICROSTEPS 16 + #define E1_K_VAL 50 + #define E1_OVERCURRENT 2000 + #define E1_STALLCURRENT 1500 + + #define E2_MICROSTEPS 16 + #define E2_K_VAL 50 + #define E2_OVERCURRENT 2000 + #define E2_STALLCURRENT 1500 + + #define E3_MICROSTEPS 16 + #define E3_K_VAL 50 + #define E3_OVERCURRENT 2000 + #define E3_STALLCURRENT 1500 + + #define E4_MICROSTEPS 16 + #define E4_K_VAL 50 + #define E4_OVERCURRENT 2000 + #define E4_STALLCURRENT 1500 + +#endif + +/** + * TWI/I2C BUS + * + * This feature is an EXPERIMENTAL feature so it shall not be used on production + * machines. Enabling this will allow you to send and receive I2C data from slave + * devices on the bus. + * + * ; Example #1 + * ; This macro send the string "Marlin" to the slave device with address 0x63 (99) + * ; It uses multiple M260 commands with one B arg + * M260 A99 ; Target slave address + * M260 B77 ; M + * M260 B97 ; a + * M260 B114 ; r + * M260 B108 ; l + * M260 B105 ; i + * M260 B110 ; n + * M260 S1 ; Send the current buffer + * + * ; Example #2 + * ; Request 6 bytes from slave device with address 0x63 (99) + * M261 A99 B5 + * + * ; Example #3 + * ; Example serial output of a M261 request + * echo:i2c-reply: from:99 bytes:5 data:hello + */ + +// @section i2cbus + +//#define EXPERIMENTAL_I2CBUS +#define I2C_SLAVE_ADDRESS 0 // Set a value from 8 to 127 to act as a slave + +// @section extras + +/** + * Spindle & Laser control + * + * Add the M3, M4, and M5 commands to turn the spindle/laser on and off, and + * to set spindle speed, spindle direction, and laser power. + * + * SuperPid is a router/spindle speed controller used in the CNC milling community. + * Marlin can be used to turn the spindle on and off. It can also be used to set + * the spindle speed from 5,000 to 30,000 RPM. + * + * 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. + */ +//#define SPINDLE_LASER_ENABLE +#if ENABLED(SPINDLE_LASER_ENABLE) + + #define SPINDLE_LASER_ENABLE_INVERT false // set to "true" if the on/off function is reversed + #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 // delay in milliseconds to allow the spindle/laser to come up to speed/power + #define SPINDLE_LASER_POWERDOWN_DELAY 5000 // delay in milliseconds to allow the spindle to stop + #define SPINDLE_DIR_CHANGE true // set to true if your spindle controller supports changing spindle direction + #define SPINDLE_INVERT_DIR false + #define SPINDLE_STOP_ON_DIR_CHANGE true // set to true if Marlin should stop the spindle before changing rotation direction + + /** + * The M3 & M4 commands use the following equation to convert PWM duty cycle to speed/power + * + * SPEED/POWER = PWM duty cycle * SPEED_POWER_SLOPE + SPEED_POWER_INTERCEPT + * where PWM duty cycle varies from 0 to 255 + * + * set the following for your controller (ALL MUST BE SET) + */ + + #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_SLOPE 0.3922 + //#define SPEED_POWER_INTERCEPT 0 + //#define SPEED_POWER_MIN 10 + //#define SPEED_POWER_MAX 100 // 0-100% +#endif + +/** + * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins + */ +//#define PINS_DEBUGGING + +/** + * Auto-report temperatures with M155 S + */ +#define AUTO_REPORT_TEMPERATURES + +/** + * Include capabilities in M115 output + */ +#define EXTENDED_CAPABILITIES_REPORT + +/** + * Volumetric extrusion default state + * 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. + */ +//#define VOLUMETRIC_DEFAULT_ON + +/** + * Enable this option for a leaner build of Marlin that removes all + * workspace offsets, simplifying coordinate transformations, leveling, etc. + * + * - M206 and M428 are disabled. + * - G92 will revert to its behavior from Marlin 1.0. + */ +//#define NO_WORKSPACE_OFFSETS + +/** + * 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. + * + * For clients that use a fixed-width font (like OctoPrint), leave this set to 1.0. + * Otherwise, adjust according to your client and font. + */ +#define PROPORTIONAL_FONT_RATIO 1.0 + +/** + * Spend 28 bytes of SRAM to optimize the GCode parser + */ +#define FASTER_GCODE_PARSER + +/** + * User-defined menu items that execute custom GCode + */ +//#define CUSTOM_USER_MENUS +#if ENABLED(CUSTOM_USER_MENUS) + #define USER_SCRIPT_DONE "M117 User Script Done" + #define USER_SCRIPT_AUDIBLE_FEEDBACK + //#define USER_SCRIPT_RETURN // Return to status screen after a script + + #define USER_DESC_1 "Home & UBL Info" + #define USER_GCODE_1 "G28\nG29 W" + + #define USER_DESC_2 "Preheat for PLA" + #define USER_GCODE_2 "M140 S" STRINGIFY(PREHEAT_1_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND) + + #define USER_DESC_3 "Preheat for ABS" + #define USER_GCODE_3 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND) + + #define USER_DESC_4 "Heat Bed/Home/Level" + #define USER_GCODE_4 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nG28\nG29" + + #define USER_DESC_5 "Home & Info" + #define USER_GCODE_5 "G28\nM503" +#endif + +/** + * Specify an action command to send to the host when the printer is killed. + * Will be sent in the form '//action:ACTION_ON_KILL', e.g. '//action:poweroff'. + * The host must be configured to handle the action command. + */ +//#define ACTION_ON_KILL "poweroff" + +//=========================================================================== +//====================== I2C Position Encoder Settings ====================== +//=========================================================================== + +/** + * I2C position encoders for closed loop control. + * Developed by Chris Barr at Aus3D. + * + * Wiki: http://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/ + * + * Reilabuild encoders have been modified to improve reliability. + */ + +//#define I2C_POSITION_ENCODERS +#if ENABLED(I2C_POSITION_ENCODERS) + + #define I2CPE_ENCODER_CNT 1 // The number of encoders installed; max of 5 + // encoders supported currently. + + #define I2CPE_ENC_1_ADDR I2CPE_PRESET_ADDR_X // I2C address of the encoder. 30-200. + #define I2CPE_ENC_1_AXIS X_AXIS // Axis the encoder module is installed on. _AXIS. + #define I2CPE_ENC_1_TYPE I2CPE_ENC_TYPE_LINEAR // Type of encoder: I2CPE_ENC_TYPE_LINEAR -or- + // I2CPE_ENC_TYPE_ROTARY. + #define I2CPE_ENC_1_TICKS_UNIT 2048 // 1024 for magnetic strips with 2mm poles; 2048 for + // 1mm poles. For linear encoders this is ticks / mm, + // for rotary encoders this is ticks / revolution. + //#define I2CPE_ENC_1_TICKS_REV (16 * 200) // Only needed for rotary encoders; number of stepper + // steps per full revolution (motor steps/rev * microstepping) + //#define I2CPE_ENC_1_INVERT // Invert the direction of axis travel. + #define I2CPE_ENC_1_EC_METHOD I2CPE_ECM_NONE // Type of error error correction. + #define I2CPE_ENC_1_EC_THRESH 0.10 // Threshold size for error (in mm) above which the + // printer will attempt to correct the error; errors + // smaller than this are ignored to minimize effects of + // measurement noise / latency (filter). + + #define I2CPE_ENC_2_ADDR I2CPE_PRESET_ADDR_Y // Same as above, but for encoder 2. + #define I2CPE_ENC_2_AXIS Y_AXIS + #define I2CPE_ENC_2_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_ENC_2_TICKS_UNIT 2048 + //#define I2CPE_ENC_2_TICKS_REV (16 * 200) + //#define I2CPE_ENC_2_INVERT + #define I2CPE_ENC_2_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_ENC_2_EC_THRESH 0.10 + + #define I2CPE_ENC_3_ADDR I2CPE_PRESET_ADDR_Z // Encoder 3. Add additional configuration options + #define I2CPE_ENC_3_AXIS Z_AXIS // as above, or use defaults below. + + #define I2CPE_ENC_4_ADDR I2CPE_PRESET_ADDR_E // Encoder 4. + #define I2CPE_ENC_4_AXIS E_AXIS + + #define I2CPE_ENC_5_ADDR 34 // Encoder 5. + #define I2CPE_ENC_5_AXIS E_AXIS + + // Default settings for encoders which are enabled, but without settings configured above. + #define I2CPE_DEF_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_DEF_ENC_TICKS_UNIT 2048 + #define I2CPE_DEF_TICKS_REV (16 * 200) + #define I2CPE_DEF_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_DEF_EC_THRESH 0.1 + + //#define I2CPE_ERR_THRESH_ABORT 100.0 // Threshold size for error (in mm) error on any given + // axis after which the printer will abort. Comment out to + // disable abort behaviour. + + #define I2CPE_TIME_TRUSTED 10000 // After an encoder fault, there must be no further fault + // for this amount of time (in ms) before the encoder + // is trusted again. + + /** + * Position is checked every time a new command is executed from the buffer but during long moves, + * this setting determines the minimum update time between checks. A value of 100 works well with + * error rolling average when attempting to correct only for skips and not for vibration. + */ + #define I2CPE_MIN_UPD_TIME_MS 100 // Minimum time in miliseconds between encoder checks. + + // Use a rolling average to identify persistant errors that indicate skips, as opposed to vibration and noise. + #define I2CPE_ERR_ROLLING_AVERAGE + +#endif // I2C_POSITION_ENCODERS + +/** + * MAX7219 Debug Matrix + * + * Add support for a low-cost 8x8 LED Matrix based on the Max7219 chip, which can be used as a status + * display. Requires 3 signal wires. Some useful debug options are included to demonstrate its usage. + * + * Fully assembled MAX7219 boards can be found on the internet for under $2(US). + * For example, see https://www.ebay.com/sch/i.html?_nkw=332349290049 + */ +//#define MAX7219_DEBUG +#if ENABLED(MAX7219_DEBUG) + #define MAX7219_CLK_PIN 64 // 77 on Re-ARM // Configuration of the 3 pins to control the display + #define MAX7219_DIN_PIN 57 // 78 on Re-ARM + #define MAX7219_LOAD_PIN 44 // 79 on Re-ARM + + /** + * Sample debug features + * If you add more debug displays, be careful to avoid conflicts! + */ + #define MAX7219_DEBUG_PRINTER_ALIVE // Blink corner LED of 8x8 matrix to show that the firmware is functioning + #define MAX7219_DEBUG_STEPPER_HEAD 3 // Show the stepper queue head position on this and the next LED matrix row + #define MAX7219_DEBUG_STEPPER_TAIL 5 // Show the stepper queue tail position on this and the next LED matrix row + + #define MAX7219_DEBUG_STEPPER_QUEUE 0 // Show the current stepper queue depth on this and the next LED matrix row + // If you experience stuttering, reboots, etc. this option can reveal how + // tweaks made to the configuration are affecting the printer in real-time. +#endif + +#endif // CONFIGURATION_ADV_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/delta/kossel_pro/README.md b/trunk/Arduino/Marlin_1.1.6/example_configurations/delta/kossel_pro/README.md new file mode 100644 index 00000000..37b5ccf0 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/delta/kossel_pro/README.md @@ -0,0 +1,5 @@ +# Example Configuration for OpenBeam Kossel Pro [BRAINWAVE_PRO](http://www.openbeamusa.com/3d-printers/kossel/) +* Configuration files for the **Openbeam Kossel Pro** as delivered in their KickStarter distribution + +I [@Wackerbarth](https://github.com/Wackerbarth) tested this version on my Kossel Pro and Arduino 1.6.5 for Mac. +This configuration is a transition to merge Terence Tam's configuration with up-to-date Marlin source and a current Arduino IDE diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/delta/kossel_xl/Configuration.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/delta/kossel_xl/Configuration.h new file mode 100644 index 00000000..6107f8c5 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/delta/kossel_xl/Configuration.h @@ -0,0 +1,1828 @@ +/** + * 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 . + * + */ + +/** + * Configuration.h + * + * Basic settings such as: + * + * - Type of electronics + * - Type of temperature sensor + * - Printer geometry + * - Endstop configuration + * - LCD controller + * - Extra features + * + * Advanced settings can be found in Configuration_adv.h + * + */ +#ifndef CONFIGURATION_H +#define CONFIGURATION_H +#define CONFIGURATION_H_VERSION 010100 + +//=========================================================================== +//============================= Getting Started ============================= +//=========================================================================== + +/** + * Here are some standard links for getting your machine calibrated: + * + * http://reprap.org/wiki/Calibration + * http://youtu.be/wAL9d7FgInk + * http://calculator.josefprusa.cz + * http://reprap.org/wiki/Triffid_Hunter%27s_Calibration_Guide + * http://www.thingiverse.com/thing:5573 + * https://sites.google.com/site/repraplogphase/calibration-of-your-reprap + * http://www.thingiverse.com/thing:298812 + */ + +//=========================================================================== +//============================= DELTA Printer =============================== +//=========================================================================== +// For a Delta printer start with one of the configuration files in the +// example_configurations/delta directory and customize for your machine. +// + +//=========================================================================== +//============================= SCARA Printer =============================== +//=========================================================================== +// For a SCARA printer start with the configuration files in +// example_configurations/SCARA and customize for your machine. +// + +// @section info + +// User-specified version info of this build to display in [Pronterface, etc] terminal window during +// startup. Implementation of an idea by Prof Braino to inform user that any changes made to this +// build by the user have been successfully uploaded into firmware. +#define STRING_CONFIG_H_AUTHOR "(oxivanisher)" // Who made the changes. +#define SHOW_BOOTSCREEN +#define STRING_SPLASH_LINE1 SHORT_BUILD_VERSION // will be shown during bootup in line 1 +#define STRING_SPLASH_LINE2 WEBSITE_URL // will be shown during bootup in line 2 + +// +// *** VENDORS PLEASE READ ***************************************************** +// +// Marlin now allow you to have a vendor boot image to be displayed on machine +// start. When SHOW_CUSTOM_BOOTSCREEN is defined Marlin will first show your +// custom boot image and then the default Marlin boot image is shown. +// +// We suggest for you to take advantage of this new feature and keep the Marlin +// boot image unmodified. For an example have a look at the bq Hephestos 2 +// example configuration folder. +// +//#define SHOW_CUSTOM_BOOTSCREEN +// @section machine + +/** + * Select which serial port on the board will be used for communication with the host. + * This allows the connection of wireless adapters (for instance) to non-default port pins. + * Serial port 0 is always used by the Arduino bootloader regardless of this setting. + * + * :[0, 1, 2, 3, 4, 5, 6, 7] + */ +#define SERIAL_PORT 0 + +/** + * This setting determines the communication speed of the printer. + * + * 250000 works in most cases, but you might try a lower speed if + * you commonly experience drop-outs during host printing. + * You may try up to 1000000 to speed up SD file transfer. + * + * :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000] + */ +#define BAUDRATE 250000 + +// Enable the Bluetooth serial interface on AT90USB devices +//#define BLUETOOTH + +// The following define selects which electronics board you have. +// Please choose the name from boards.h that matches your setup +#ifndef MOTHERBOARD + #define MOTHERBOARD BOARD_RAMPS_14_EFB +#endif + +// Optional custom name for your RepStrap or other custom machine +// Displayed in the LCD "Ready" message +#define CUSTOM_MACHINE_NAME "Kossel k800XL" + +// Define this to set a unique identifier for this printer, (Used by some programs to differentiate between machines) +// You can use an online service to generate a random UUID. (eg http://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] +#define EXTRUDERS 1 + +// For Cyclops or any "multi-extruder" that shares a single nozzle. +//#define SINGLENOZZLE + +/** + * Průša MK2 Single Nozzle Multi-Material Multiplexer, and variants. + * + * This device allows one stepper driver on a control board to drive + * two to eight stepper motors, one at a time, in a manner suitable + * for extruders. + * + * This option only allows the multiplexer to switch on tool-change. + * Additional options to configure custom E moves are pending. + */ +//#define MK2_MULTIPLEXER +#if ENABLED(MK2_MULTIPLEXER) + // Override the default DIO selector pins here, if needed. + // Some pins files may provide defaults for these pins. + //#define E_MUX0_PIN 40 // Always Required + //#define E_MUX1_PIN 42 // Needed for 3 to 8 steppers + //#define E_MUX2_PIN 44 // Needed for 5 to 8 steppers +#endif + +// A dual extruder that uses a single stepper motor +//#define SWITCHING_EXTRUDER +#if ENABLED(SWITCHING_EXTRUDER) + #define SWITCHING_EXTRUDER_SERVO_NR 0 + #define SWITCHING_EXTRUDER_SERVO_ANGLES { 0, 90 } // Angles for E0, E1[, E2, E3] + #if EXTRUDERS > 3 + #define SWITCHING_EXTRUDER_E23_SERVO_NR 1 + #endif +#endif + +// A dual-nozzle that uses a servomotor to raise/lower one of the nozzles +//#define SWITCHING_NOZZLE +#if ENABLED(SWITCHING_NOZZLE) + #define SWITCHING_NOZZLE_SERVO_NR 0 + #define SWITCHING_NOZZLE_SERVO_ANGLES { 0, 90 } // Angles for E0, E1 + //#define HOTEND_OFFSET_Z { 0.0, 0.0 } +#endif + +/** + * Two separate X-carriages with extruders that connect to a moving part + * via a magnetic docking mechanism. Requires SOL1_PIN and SOL2_PIN. + */ +//#define PARKING_EXTRUDER +#if ENABLED(PARKING_EXTRUDER) + #define PARKING_EXTRUDER_SOLENOIDS_INVERT // If enabled, the solenoid is NOT magnetized with applied voltage + #define PARKING_EXTRUDER_SOLENOIDS_PINS_ACTIVE LOW // LOW or HIGH pin signal energizes the coil + #define PARKING_EXTRUDER_SOLENOIDS_DELAY 250 // Delay (ms) for magnetic field. No delay if 0 or not defined. + #define PARKING_EXTRUDER_PARKING_X { -78, 184 } // X positions for parking the extruders + #define PARKING_EXTRUDER_GRAB_DISTANCE 1 // mm to move beyond the parking point to grab the extruder + #define PARKING_EXTRUDER_SECURITY_RAISE 5 // Z-raise before parking + #define HOTEND_OFFSET_Z { 0.0, 1.3 } // Z-offsets of the two hotends. The first must be 0. +#endif + +/** + * "Mixing Extruder" + * - Adds a new code, M165, to set the current mix factors. + * - Extends the stepping routines to move multiple steppers in proportion to the mix. + * - Optional support for Repetier Firmware M163, M164, and virtual extruder. + * - This implementation supports only a single extruder. + * - Enable DIRECT_MIXING_IN_G1 for Pia Taubert's reference implementation + */ +//#define MIXING_EXTRUDER +#if ENABLED(MIXING_EXTRUDER) + #define MIXING_STEPPERS 2 // Number of steppers in your mixing extruder + #define MIXING_VIRTUAL_TOOLS 16 // Use the Virtual Tool method with M163 and M164 + //#define DIRECT_MIXING_IN_G1 // Allow ABCDHI mix factors in G1 movement commands +#endif + +// Offset of the extruders (uncomment if using more than one and relying on firmware to position when changing). +// The offset has to be X=0, Y=0 for the extruder 0 hotend (default extruder). +// For the other hotends it is their distance from the extruder 0 hotend. +//#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis +//#define HOTEND_OFFSET_Y {0.0, 5.00} // (in mm) for each extruder, offset of the hotend on the Y axis + +// @section machine + +/** + * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN + * + * 0 = No Power Switch + * 1 = ATX + * 2 = X-Box 360 203Watts (the blue wire connected to PS_ON and the red wire to VCC) + * + * :{ 0:'No power switch', 1:'ATX', 2:'X-Box 360' } + */ +#define POWER_SUPPLY 2 + +#if POWER_SUPPLY > 0 + // Enable this option to leave the PSU off at startup. + // Power to steppers and heaters will need to be turned on with M80. + #define PS_DEFAULT_OFF +#endif + +// @section temperature + +//=========================================================================== +//============================= Thermal Settings ============================ +//=========================================================================== + +/** + * --NORMAL IS 4.7kohm PULLUP!-- 1kohm pullup can be used on hotend sensor, using correct resistor and table + * + * Temperature sensors available: + * + * -3 : thermocouple with MAX31855 (only for sensor 0) + * -2 : thermocouple with MAX6675 (only for sensor 0) + * -1 : thermocouple with AD595 + * 0 : not used + * 1 : 100k thermistor - best choice for EPCOS 100k (4.7k pullup) + * 2 : 200k thermistor - ATC Semitec 204GT-2 (4.7k pullup) + * 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 (Used in ParCan & J-Head) (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) + * 71 : 100k Honeywell thermistor 135-104LAF-J01 (4.7k pullup) + * 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) + * 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" + * 20 : the PT100 circuit found in the Ultimainboard V2.x + * 60 : 100k Maker's Tool Works Kapton Bed Thermistor beta=3950 + * 66 : 4.7M High Temperature thermistor from Dyze Design + * 70 : the 100K thermistor found in the bq Hephestos 2 + * 75 : 100k Generic Silicon Heat Pad with NTC 100K MGB18-104F39050L32 thermistor + * + * 1k ohm pullup tables - This is atypical, and requires changing out the 4.7k pullup for 1k. + * (but gives greater accuracy and more stable PID) + * 51 : 100k thermistor - EPCOS (1k pullup) + * 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 + * 1010 : Pt1000 with 1k pullup (non standard) + * 147 : Pt100 with 4k7 pullup + * 110 : Pt100 with 1k pullup (non standard) + * + * Use these for Testing or Development purposes. NEVER for production machine. + * 998 : Dummy Table that ALWAYS reads 25°C or the temperature defined below. + * 999 : Dummy Table that ALWAYS reads 100°C or the temperature defined below. + * + * :{ '0': "Not used", '1':"100k / 4.7k - EPCOS", '2':"200k / 4.7k - ATC Semitec 204GT-2", '3':"Mendel-parts / 4.7k", '4':"10k !! do not use for a hotend. Bad resolution at high temp. !!", '5':"100K / 4.7k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '6':"100k / 4.7k EPCOS - Not as accurate as Table 1", '7':"100k / 4.7k Honeywell 135-104LAG-J01", '8':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT", '9':"100k / 4.7k GE Sensing AL03006-58.2K-97-G1", '10':"100k / 4.7k RS 198-961", '11':"100k / 4.7k beta 3950 1%", '12':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT (calibrated for Makibox hot bed)", '13':"100k Hisens 3950 1% up to 300°C for hotend 'Simple ONE ' & hotend 'All In ONE'", '20':"PT100 (Ultimainboard V2.x)", '51':"100k / 1k - EPCOS", '52':"200k / 1k - ATC Semitec 204GT-2", '55':"100k / 1k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '60':"100k Maker's Tool Works Kapton Bed Thermistor beta=3950", '66':"Dyze Design 4.7M High Temperature thermistor", '70':"the 100K thermistor found in the bq Hephestos 2", '71':"100k / 4.7k Honeywell 135-104LAF-J01", '147':"Pt100 / 4.7k", '1047':"Pt1000 / 4.7k", '110':"Pt100 / 1k (non-standard)", '1010':"Pt1000 / 1k (non standard)", '-3':"Thermocouple + MAX31855 (only for sensor 0)", '-2':"Thermocouple + MAX6675 (only for sensor 0)", '-1':"Thermocouple + AD595",'998':"Dummy 1", '999':"Dummy 2" } + */ +#define TEMP_SENSOR_0 5 +#define TEMP_SENSOR_1 0 +#define TEMP_SENSOR_2 0 +#define TEMP_SENSOR_3 0 +#define TEMP_SENSOR_4 0 +#define TEMP_SENSOR_BED 5 + +// Dummy thermistor constant temperature readings, for use with 998 and 999 +#define DUMMY_THERMISTOR_998_VALUE 25 +#define DUMMY_THERMISTOR_999_VALUE 100 + +// 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 +#define MAX_REDUNDANT_TEMP_SENSOR_DIFF 10 + +// Extruder temperature must be close to target for this long before M109 returns success +#define TEMP_RESIDENCY_TIME 10 // (seconds) +#define TEMP_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// Bed temperature must be close to target for this long before M190 returns success +#define TEMP_BED_RESIDENCY_TIME 0 // (seconds) +#define TEMP_BED_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_BED_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// The minimal temperature defines the temperature below which the heater will not be enabled It is used +// to check that the wiring to the thermistor is not broken. +// Otherwise this would lead to the heater being powered on all the time. +#define HEATER_0_MINTEMP 5 +#define HEATER_1_MINTEMP 5 +#define HEATER_2_MINTEMP 5 +#define HEATER_3_MINTEMP 5 +#define HEATER_4_MINTEMP 5 +#define BED_MINTEMP 5 + +// When temperature exceeds max temp, your heater will be switched off. +// This feature exists to protect your hotend from overheating accidentally, but *NOT* from thermistor short/failure! +// You should use MINTEMP for thermistor short/failure protection. +#define HEATER_0_MAXTEMP 275 +#define HEATER_1_MAXTEMP 275 +#define HEATER_2_MAXTEMP 275 +#define HEATER_3_MAXTEMP 275 +#define HEATER_4_MAXTEMP 275 +#define BED_MAXTEMP 150 + +//=========================================================================== +//============================= PID Settings ================================ +//=========================================================================== +// PID Tuning Guide here: http://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 +#if ENABLED(PIDTEMP) + //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. + //#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. + #define K1 0.95 //smoothing factor within the PID + + // If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it + // oXis Kossel k800 XL + #define DEFAULT_Kp 22.04 + #define DEFAULT_Ki 1.65 + #define DEFAULT_Kd 73.67 + + // Kossel k800 XL + //#define DEFAULT_Kp 22.25 + //#define DEFAULT_Ki 1.45 + //#define DEFAULT_Kd 85.30 + + // 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 + +#endif // PIDTEMP + +//=========================================================================== +//============================= PID > Bed Temperature Control =============== +//=========================================================================== +// Select PID or bang-bang with PIDTEMPBED. If bang-bang, BED_LIMIT_SWITCHING will enable hysteresis +// +// Uncomment this to enable PID on the bed. It uses the same frequency PWM as the extruder. +// If your PID_dT is the default, and correct for your hardware/configuration, that means 7.689Hz, +// which is fine for driving a square wave into a resistive load and does not significantly impact you FET heating. +// This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W heater. +// If your configuration is significantly different than this and you don't understand the issues involved, you probably +// shouldn't use bed PID until someone else verifies your hardware works. +// If this is enabled, find your own PID constants below. +//#define PIDTEMPBED + +//#define BED_LIMIT_SWITCHING + +// This sets the max power delivered to the bed, and replaces the HEATER_BED_DUTY_CYCLE_DIVIDER option. +// all forms of bed control obey this (PID, bang-bang, bang-bang with hysteresis) +// setting this to anything other than 255 enables a form of PWM to the bed just like HEATER_BED_DUTY_CYCLE_DIVIDER did, +// so you shouldn't use it unless you are OK with PWM on your bed. (see the comment on enabling PIDTEMPBED) +#define MAX_BED_POWER 255 // limits duty cycle to bed; 255=full current + +#if ENABLED(PIDTEMPBED) + + //#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) + #define DEFAULT_bedKp 15.00 + #define DEFAULT_bedKi .04 + #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 + +// @section extruder + +// This option prevents extrusion if the temperature is below EXTRUDE_MINTEMP. +// It also enables the M302 command to set the minimum extrusion temperature +// or to allow moving the extruder regardless of the hotend temperature. +// *** IT IS HIGHLY RECOMMENDED TO LEAVE THIS OPTION ENABLED! *** +#define PREVENT_COLD_EXTRUSION +#define EXTRUDE_MINTEMP 170 + +// This option prevents a single extrusion longer than EXTRUDE_MAXLENGTH. +// Note that for Bowden Extruders a too-small value here may prevent loading. +#define PREVENT_LENGTHY_EXTRUDE +#define EXTRUDE_MAXLENGTH 200 + +//=========================================================================== +//======================== Thermal Runaway Protection ======================= +//=========================================================================== + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * If you get "Thermal Runaway" or "Heating failed" errors the + * details can be tuned in Configuration_adv.h + */ + +#define THERMAL_PROTECTION_HOTENDS // Enable thermal protection for all extruders +#define THERMAL_PROTECTION_BED // Enable thermal protection for the heated bed + +//=========================================================================== +//============================= Mechanical Settings ========================= +//=========================================================================== + +// @section machine + +// Uncomment one of these options to enable CoreXY, CoreXZ, or CoreYZ kinematics +// either in the usual order or reversed +//#define COREXY +//#define COREXZ +//#define COREYZ +//#define COREYX +//#define COREZX +//#define COREZY + +//=========================================================================== +//============================== Delta Settings ============================= +//=========================================================================== +// Enable DELTA kinematics and most of the default configuration for Deltas +#define DELTA + +#if ENABLED(DELTA) + + // Make delta curves from many straight lines (linear interpolation). + // This is a trade-off between visible corners (not enough segments) + // and processor overload (too many expensive sqrt calls). + #define DELTA_SEGMENTS_PER_SECOND 160 + + // After homing move down to a height where XY movement is unconstrained + //#define DELTA_HOME_TO_SAFE_ZONE + + // Delta calibration menu + // uncomment to add three points calibration menu option. + // See http://minow.blogspot.com/index.html#4918805519571907051 + //#define DELTA_CALIBRATION_MENU + + // uncomment to add G33 Delta Auto-Calibration (Enable EEPROM_SETTINGS to store results) + //#define DELTA_AUTO_CALIBRATION + + // NOTE NB all values for DELTA_* values MUST be floating point, so always have a decimal point in them + + #if ENABLED(DELTA_AUTO_CALIBRATION) + // set the default number of probe points : n*n (1 -> 7) + #define DELTA_CALIBRATION_DEFAULT_POINTS 4 + #endif + + #if ENABLED(DELTA_AUTO_CALIBRATION) || ENABLED(DELTA_CALIBRATION_MENU) + // Set the radius for the calibration probe points - max DELTA_PRINTABLE_RADIUS*0.869 for non-eccentric probes + #define DELTA_CALIBRATION_RADIUS 121.5 // mm + // Set the steprate for papertest probing + #define PROBE_MANUALLY_STEP 0.025 + #endif + + // Print surface diameter/2 minus unreachable space (avoid collisions with vertical towers). + #define DELTA_PRINTABLE_RADIUS 140.0 // mm + + // Center-to-center distance of the holes in the diagonal push rods. + #define DELTA_DIAGONAL_ROD 319.5 // mm + + // height from z=0 to home position + #define DELTA_HEIGHT 380.00 // get this value from auto calibrate + + #define DELTA_ENDSTOP_ADJ { 0.0, 0.0, 0.0 } // get these from auto calibrate + + // Horizontal distance bridged by diagonal push rods when effector is centered. + #define DELTA_RADIUS 174.1 //mm Get this value from auto calibrate + + // Trim adjustments for individual towers + // tower angle corrections for X and Y tower / rotate XYZ so Z tower angle = 0 + // measured in degrees anticlockwise looking from above the printer + #define DELTA_TOWER_ANGLE_TRIM { 0.0, 0.0, 0.0 } // get these values from auto calibrate + + // delta radius and diaginal rod adjustments measured in mm + //#define DELTA_RADIUS_TRIM_TOWER { 0.0, 0.0, 0.0 } + //#define DELTA_DIAGONAL_ROD_TRIM_TOWER { 0.0, 0.0, 0.0 } + +#endif + +//=========================================================================== +//============================== Endstop Settings =========================== +//=========================================================================== + +// @section homing + +// Specify here all the endstop connectors that are connected to any endstop or probe. +// Almost all printers will be using one per axis. Probes will use one or more of the +// extra connectors. Leave undefined any used for non-endstop and non-probe purposes. +//#define USE_XMIN_PLUG +//#define USE_YMIN_PLUG +#define USE_ZMIN_PLUG // a Z probe +#define USE_XMAX_PLUG +#define USE_YMAX_PLUG +#define USE_ZMAX_PLUG + +// coarse Endstop Settings +//#define ENDSTOPPULLUPS // Comment this out (using // at the start of the line) to disable the endstop pullup resistors + +#if DISABLED(ENDSTOPPULLUPS) + // fine endstop settings: Individual pullups. will be ignored if ENDSTOPPULLUPS is defined + #define ENDSTOPPULLUP_XMAX + #define ENDSTOPPULLUP_YMAX + #define ENDSTOPPULLUP_ZMAX + //#define ENDSTOPPULLUP_XMIN + //#define ENDSTOPPULLUP_YMIN + #define ENDSTOPPULLUP_ZMIN + //#define ENDSTOPPULLUP_ZMIN_PROBE +#endif + +// Mechanical endstop with COM to ground and NC to Signal uses "false" here (most common setup). +#define X_MIN_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Y_MIN_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MIN_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define X_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Y_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MIN_PROBE_ENDSTOP_INVERTING false // set to true to invert the logic of the probe. + +// Enable this feature if all enabled endstop pins are interrupt-capable. +// This will remove the need to poll the interrupt pins, saving many CPU cycles. +//#define ENDSTOP_INTERRUPTS_FEATURE + +//============================================================================= +//============================== Movement Settings ============================ +//============================================================================= +// @section motion + +// variables to calculate steps +#define XYZ_FULL_STEPS_PER_ROTATION 200 +#define XYZ_MICROSTEPS 16 +#define XYZ_BELT_PITCH 2 +#define XYZ_PULLEY_TEETH 16 + +// delta speeds must be the same on xyz +#define XYZ_STEPS (XYZ_FULL_STEPS_PER_ROTATION * XYZ_MICROSTEPS / double(XYZ_BELT_PITCH) / double(XYZ_PULLEY_TEETH)) + +/** + * Default Settings + * + * These settings can be reset by M502 + * + * Note that if EEPROM is enabled, saved values will override these. + */ + +/** + * With this option each E stepper can have its own factors for the + * following movement settings. If fewer factors are given than the + * total number of extruders, the last value applies to the rest. + */ +//#define DISTINCT_E_FACTORS + +/** + * Default Axis Steps Per Unit (steps/mm) + * Override with M92 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_AXIS_STEPS_PER_UNIT { XYZ_STEPS, XYZ_STEPS, XYZ_STEPS, 158 } // default steps per unit for PowerWasp + +/** + * Default Max Feed Rate (mm/s) + * Override with M203 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_FEEDRATE { 200, 200, 200, 25 } + +/** + * Default Max Acceleration (change/s) change = mm/s + * (Maximum start speed for accelerated moves) + * Override with M201 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_ACCELERATION { 9000, 9000, 9000, 10000 } + +/** + * Default Acceleration (change/s) change = mm/s + * Override with M204 + * + * M204 P Acceleration + * M204 R Retract Acceleration + * M204 T Travel Acceleration + */ +#define DEFAULT_ACCELERATION 2000 // X, Y, Z and E acceleration for printing moves +#define DEFAULT_RETRACT_ACCELERATION 3000 // E acceleration for retracts +#define DEFAULT_TRAVEL_ACCELERATION 3000 // X, Y, Z acceleration for travel (non printing) moves + +/** + * Default Jerk (mm/s) + * Override with M205 X Y Z E + * + * "Jerk" specifies the minimum speed change that requires acceleration. + * When changing speed and direction, if the difference is less than the + * value set here, it may happen instantaneously. + */ +#define DEFAULT_XJERK 20.0 +#define DEFAULT_YJERK 20.0 +#define DEFAULT_ZJERK 20.0 +#define DEFAULT_EJERK 20.0 + +//=========================================================================== +//============================= Z Probe Options ============================= +//=========================================================================== +// @section probes + +// +// See http://marlinfw.org/configuration/probes.html +// + +/** + * Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + * + * Enable this option for a probe connected to the Z Min endstop pin. + */ +//#define Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + +/** + * Z_MIN_PROBE_ENDSTOP + * + * Enable this option for a probe connected to any pin except Z-Min. + * (By default Marlin assumes the Z-Max endstop pin.) + * To use a custom Z Probe pin, set Z_MIN_PROBE_PIN below. + * + * - The simplest option is to use a free endstop connector. + * - Use 5V for powered (usually inductive) sensors. + * + * - RAMPS 1.3/1.4 boards may use the 5V, GND, and Aux4->D32 pin: + * - For simple switches connect... + * - normally-closed switches to GND and D32. + * - normally-open switches to 5V and D32. + * + * WARNING: Setting the wrong pin may have unexpected and potentially + * disastrous consequences. Use with caution and do your homework. + * + */ +#define Z_MIN_PROBE_ENDSTOP + +/** + * Probe Type + * + * Allen Key Probes, Servo Probes, Z-Sled Probes, FIX_MOUNTED_PROBE, etc. + * Activate one of these to use Auto Bed Leveling below. + */ + +/** + * The "Manual Probe" provides a means to do "Auto" Bed Leveling without a probe. + * Use G29 repeatedly, adjusting the Z height at each point with movement commands + * or (with LCD_BED_LEVELING) the LCD controller. + */ +//#define PROBE_MANUALLY + +/** + * A Fix-Mounted Probe either doesn't deploy or needs manual deployment. + * (e.g., an inductive probe or a nozzle-based probe-switch.) + */ +#define FIX_MOUNTED_PROBE + +/** + * Z Servo Probe, such as an endstop switch on a rotating arm. + */ +//#define Z_ENDSTOP_SERVO_NR 0 // Defaults to SERVO 0 connector. +//#define Z_SERVO_ANGLES {70,0} // Z Servo Deploy and Stow angles + +/** + * The BLTouch probe uses a Hall effect sensor and emulates a servo. + */ +//#define BLTOUCH +#if ENABLED(BLTOUCH) + //#define BLTOUCH_DELAY 375 // (ms) Enable and increase if needed +#endif + +/** + * Enable one or more of the following if probing seems unreliable. + * Heaters and/or fans can be disabled during probing to minimize electrical + * noise. A delay can also be added to allow noise and vibration to settle. + * These options are most useful for the BLTouch probe, but may also improve + * readings with inductive probes and piezo sensors. + */ +//#define PROBING_HEATERS_OFF // Turn heaters off when probing +//#define PROBING_FANS_OFF // Turn fans off when probing +//#define DELAY_BEFORE_PROBING 200 // (ms) To prevent vibrations from triggering piezo sensors + +// A probe that is deployed and stowed with a solenoid pin (SOL1_PIN) +//#define SOLENOID_PROBE + +// A sled-mounted probe like those designed by Charles Bell. +//#define Z_PROBE_SLED +//#define SLED_DOCKING_OFFSET 5 // The extra distance the X axis must travel to pickup the sled. 0 should be fine but you can push it further if you'd like. + +// +// For Z_PROBE_ALLEN_KEY see the Delta example configurations. +// + +/** + * Z Probe to nozzle (X,Y) offset, relative to (0, 0). + * X and Y offsets must be integers. + * + * In the following example the X and Y offsets are both positive: + * #define X_PROBE_OFFSET_FROM_EXTRUDER 10 + * #define Y_PROBE_OFFSET_FROM_EXTRUDER 10 + * + * +-- BACK ---+ + * | | + * L | (+) P | R <-- probe (20,20) + * E | | I + * F | (-) N (+) | G <-- nozzle (10,10) + * T | | H + * | (-) | T + * | | + * O-- FRONT --+ + * (0,0) + */ +#define X_PROBE_OFFSET_FROM_EXTRUDER 0.0 // Z probe to nozzle X offset: -left +right +#define Y_PROBE_OFFSET_FROM_EXTRUDER 0.0 // Z probe to nozzle Y offset: -front +behind +#define Z_PROBE_OFFSET_FROM_EXTRUDER 0.3 // Z probe to nozzle Z offset: -below (always!) + +// X and Y axis travel speed (mm/m) between probes +#define XY_PROBE_SPEED 8000 + +// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +#define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z + +// Speed for the "accurate" probe of each point +#define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) + +// Use double touch for probing +//#define PROBE_DOUBLE_TOUCH + +/** + * Allen key retractable z-probe as seen on many Kossel delta printers - http://reprap.org/wiki/Kossel#Automatic_bed_leveling_probe + * Deploys by touching z-axis belt. Retracts by pushing the probe down. Uses Z_MIN_PIN. + */ +//#define Z_PROBE_ALLEN_KEY + +#if ENABLED(Z_PROBE_ALLEN_KEY) + // 2 or 3 sets of coordinates for deploying and retracting the spring loaded touch probe on G29, + // if servo actuated touch probe is not defined. Uncomment as appropriate for your printer/probe. + + //#define Z_PROBE_ALLEN_KEY_DEPLOY_1_X 30.0 + //#define Z_PROBE_ALLEN_KEY_DEPLOY_1_Y DELTA_PRINTABLE_RADIUS + //#define Z_PROBE_ALLEN_KEY_DEPLOY_1_Z 100.0 + //#define Z_PROBE_ALLEN_KEY_DEPLOY_1_FEEDRATE XY_PROBE_SPEED + + //#define Z_PROBE_ALLEN_KEY_DEPLOY_2_X 0.0 + //#define Z_PROBE_ALLEN_KEY_DEPLOY_2_Y DELTA_PRINTABLE_RADIUS + //#define Z_PROBE_ALLEN_KEY_DEPLOY_2_Z 100.0 + //#define Z_PROBE_ALLEN_KEY_DEPLOY_2_FEEDRATE (XY_PROBE_SPEED)/10 + + //#define Z_PROBE_ALLEN_KEY_DEPLOY_3_X Z_PROBE_ALLEN_KEY_DEPLOY_2_X * 0.75 + //#define Z_PROBE_ALLEN_KEY_DEPLOY_3_Y Z_PROBE_ALLEN_KEY_DEPLOY_2_Y * 0.75 + //#define Z_PROBE_ALLEN_KEY_DEPLOY_3_Z Z_PROBE_ALLEN_KEY_DEPLOY_2_Z + //#define Z_PROBE_ALLEN_KEY_DEPLOY_3_FEEDRATE XY_PROBE_SPEED + + //#define Z_PROBE_ALLEN_KEY_STOW_1_X -64.0 // Move the probe into position + //#define Z_PROBE_ALLEN_KEY_STOW_1_Y 56.0 + //#define Z_PROBE_ALLEN_KEY_STOW_1_Z 23.0 + //#define Z_PROBE_ALLEN_KEY_STOW_1_FEEDRATE XY_PROBE_SPEED + + //#define Z_PROBE_ALLEN_KEY_STOW_2_X -64.0 // Push it down + //#define Z_PROBE_ALLEN_KEY_STOW_2_Y 56.0 + //#define Z_PROBE_ALLEN_KEY_STOW_2_Z 3.0 + //#define Z_PROBE_ALLEN_KEY_STOW_2_FEEDRATE (XY_PROBE_SPEED)/10 + + //#define Z_PROBE_ALLEN_KEY_STOW_3_X -64.0 // Move it up to clear + //#define Z_PROBE_ALLEN_KEY_STOW_3_Y 56.0 + //#define Z_PROBE_ALLEN_KEY_STOW_3_Z 50.0 + //#define Z_PROBE_ALLEN_KEY_STOW_3_FEEDRATE XY_PROBE_SPEED + + //#define Z_PROBE_ALLEN_KEY_STOW_4_X 0.0 + //#define Z_PROBE_ALLEN_KEY_STOW_4_Y 0.0 + //#define Z_PROBE_ALLEN_KEY_STOW_4_Z Z_PROBE_ALLEN_KEY_STOW_3_Z + //#define Z_PROBE_ALLEN_KEY_STOW_4_FEEDRATE XY_PROBE_SPEED + +#endif // Z_PROBE_ALLEN_KEY + +/** + * Z probes require clearance when deploying, stowing, and moving between + * probe points to avoid hitting the bed and other hardware. + * Servo-mounted probes require extra space for the arm to rotate. + * Inductive probes need space to keep from triggering early. + * + * Use these settings to specify the distance (mm) to raise the probe (or + * lower the bed). The values set here apply over and above any (negative) + * probe Z Offset set with Z_PROBE_OFFSET_FROM_EXTRUDER, M851, or the LCD. + * Only integer values >= 1 are valid here. + * + * Example: `M851 Z-5` with a CLEARANCE of 4 => 9mm from bed to nozzle. + * But: `M851 Z+1` with a CLEARANCE of 2 => 2mm from bed to nozzle. + */ +#define Z_CLEARANCE_DEPLOY_PROBE 20 // Z Clearance for Deploy/Stow +#define Z_CLEARANCE_BETWEEN_PROBES 10 // Z Clearance between probe points + +// For M851 give a range for adjusting the Z probe offset +#define Z_PROBE_OFFSET_RANGE_MIN -20 +#define Z_PROBE_OFFSET_RANGE_MAX 20 + +// Enable the M48 repeatability test to test probe accuracy +//#define Z_MIN_PROBE_REPEATABILITY_TEST + +// For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1 +// :{ 0:'Low', 1:'High' } +#define X_ENABLE_ON 0 +#define Y_ENABLE_ON 0 +#define Z_ENABLE_ON 0 +#define E_ENABLE_ON 0 // For all extruders + +// Disables axis stepper immediately when it's not being used. +// 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 +//#define DISABLE_REDUCED_ACCURACY_WARNING + +// @section extruder + +#define DISABLE_E false // For all extruders +#define DISABLE_INACTIVE_EXTRUDER true // Keep only the active extruder enabled. + +// @section machine + +// Invert the stepper direction. Change (or reverse the motor connector) if an axis goes the wrong way. +#define INVERT_X_DIR false // DELTA does not invert +#define INVERT_Y_DIR false +#define INVERT_Z_DIR false + +// Enable this option for Toshiba stepper drivers +//#define CONFIG_STEPPERS_TOSHIBA + +// @section extruder + +// For direct drive extruder v9 set to true, for geared extruder set to false. +#define INVERT_E0_DIR true +#define INVERT_E1_DIR false +#define INVERT_E2_DIR false +#define INVERT_E3_DIR false +#define INVERT_E4_DIR false + +// @section homing + +//#define NO_MOTION_BEFORE_HOMING // Inhibit movement until all axes have been homed + +//#define Z_HOMING_HEIGHT 4 // (in mm) Minimal z height before homing (G28) for Z clearance above the bed, clamps, ... + // Be sure you have this distance over your Z_MAX_POS in case. + +// Direction of endstops when homing; 1=MAX, -1=MIN +// :[-1,1] +#define X_HOME_DIR 1 // deltas always home to max +#define Y_HOME_DIR 1 +#define Z_HOME_DIR 1 + +// @section machine + +// The size of the print bed +#define X_BED_SIZE ((DELTA_PRINTABLE_RADIUS) * 2) +#define Y_BED_SIZE ((DELTA_PRINTABLE_RADIUS) * 2) + +// Travel limits (mm) after homing, corresponding to endstop positions. +#define X_MIN_POS -(DELTA_PRINTABLE_RADIUS) +#define Y_MIN_POS -(DELTA_PRINTABLE_RADIUS) +#define Z_MIN_POS 0 +#define X_MAX_POS DELTA_PRINTABLE_RADIUS +#define Y_MAX_POS DELTA_PRINTABLE_RADIUS +#define Z_MAX_POS MANUAL_Z_HOME_POS + +// If enabled, axes won't move below MIN_POS in response to movement commands. +//#define MIN_SOFTWARE_ENDSTOPS +// If enabled, axes won't move above MAX_POS in response to movement commands. +#define MAX_SOFTWARE_ENDSTOPS + +/** + * Filament Runout Sensor + * A mechanical or opto endstop is used to check for the presence of filament. + * + * RAMPS-based boards use SERVO3_PIN. + * For other boards you may need to define FIL_RUNOUT_PIN. + * By default the firmware assumes HIGH = has filament, LOW = ran out + */ +//#define FILAMENT_RUNOUT_SENSOR +#if ENABLED(FILAMENT_RUNOUT_SENSOR) + #define FIL_RUNOUT_INVERTING false // set to true to invert the logic of the sensor. + #define ENDSTOPPULLUP_FIL_RUNOUT // Uncomment to use internal pullup for filament runout pins if the sensor is defined. + #define FILAMENT_RUNOUT_SCRIPT "M600" +#endif + +//=========================================================================== +//=============================== Bed Leveling ============================== +//=========================================================================== +// @section bedlevel + +/** + * Choose one of the options below to enable G29 Bed Leveling. The parameters + * and behavior of G29 will change depending on your selection. + * + * If using a Probe for Z Homing, enable Z_SAFE_HOMING also! + * + * - AUTO_BED_LEVELING_3POINT + * Probe 3 arbitrary points on the bed (that aren't collinear) + * You specify the XY coordinates of all 3 points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_LINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_BILINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a mesh, best for large or uneven beds. + * + * - AUTO_BED_LEVELING_UBL (Unified Bed Leveling) + * A comprehensive bed leveling system combining the features and benefits + * of other systems. UBL also includes integrated Mesh Generation, Mesh + * Validation and Mesh Editing systems. Currently, UBL is only checked out + * for Cartesian Printers. That said, it was primarily designed to correct + * poor quality Delta Printers. If you feel adventurous and have a Delta, + * please post an issue if something doesn't work correctly. Initially, + * you will need to set a reduced bed size so you have a rectangular area + * to test on. + * + * - MESH_BED_LEVELING + * Probe a grid manually + * The result is a mesh, suitable for large or uneven beds. (See BILINEAR.) + * For machines without a probe, Mesh Bed Leveling provides a method to perform + * leveling in steps so you can manually adjust the Z height at each grid-point. + * With an LCD controller the process is guided step-by-step. + */ +//#define AUTO_BED_LEVELING_3POINT +//#define AUTO_BED_LEVELING_LINEAR +//#define AUTO_BED_LEVELING_BILINEAR +//#define AUTO_BED_LEVELING_UBL +//#define MESH_BED_LEVELING + +/** + * Enable detailed logging of G28, G29, M48, etc. + * Turn on with the command 'M111 S32'. + * NOTE: Requires a lot of PROGMEM! + */ +//#define DEBUG_LEVELING_FEATURE + +#if ENABLED(MESH_BED_LEVELING) || ENABLED(AUTO_BED_LEVELING_BILINEAR) || ENABLED(AUTO_BED_LEVELING_UBL) + // Gradually reduce leveling correction until a set height is reached, + // at which point movement will be level to the machine's XY plane. + // The height can be set with M420 Z + //#define ENABLE_LEVELING_FADE_HEIGHT + + // Set the boundaries for probing (where the probe can reach). + #define DELTA_PROBEABLE_RADIUS (DELTA_PRINTABLE_RADIUS - 10) + +#endif + +#if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Set the number of grid points per dimension. + // Works best with 5 or more points in each dimension. + #define GRID_MAX_POINTS_X 5 + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + #define LEFT_PROBE_BED_POSITION -(DELTA_PROBEABLE_RADIUS) + #define RIGHT_PROBE_BED_POSITION DELTA_PROBEABLE_RADIUS + #define FRONT_PROBE_BED_POSITION - (DELTA_PROBEABLE_RADIUS - 20) + #define BACK_PROBE_BED_POSITION DELTA_PROBEABLE_RADIUS - 40 + + // The Z probe minimum outer margin (to validate G29 parameters). + #define MIN_PROBE_EDGE 10 + + // Probe along the Y axis, advancing X after each column + //#define PROBE_Y_FIRST + + #if ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Beyond the probed grid, continue the implied tilt? + // Default is to maintain the height of the nearest edge. + //#define EXTRAPOLATE_BEYOND_GRID + + // + // Experimental Subdivision of the grid by Catmull-Rom method. + // Synthesizes intermediate points to produce a more detailed mesh. + // + //#define ABL_BILINEAR_SUBDIVISION + #if ENABLED(ABL_BILINEAR_SUBDIVISION) + // Number of subdivisions between probe points + #define BILINEAR_SUBDIVISIONS 3 + #endif + + #endif + +#elif ENABLED(AUTO_BED_LEVELING_3POINT) + + // 3 arbitrary points to probe. + // A simple cross-product is used to estimate the plane of the bed. + #define ABL_PROBE_PT_1_X 15 + #define ABL_PROBE_PT_1_Y 180 + #define ABL_PROBE_PT_2_X 15 + #define ABL_PROBE_PT_2_Y 20 + #define ABL_PROBE_PT_3_X 170 + #define ABL_PROBE_PT_3_Y 20 + +#elif ENABLED(AUTO_BED_LEVELING_UBL) + + //=========================================================================== + //========================= Unified Bed Leveling ============================ + //=========================================================================== + + #define UBL_MESH_INSET 1 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 10 // Don't use more than 15 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + #define _PX(R,A) (R) * cos(RADIANS(A)) + #define _PY(R,A) (R) * sin(RADIANS(A)) + #define UBL_PROBE_PT_1_X _PX(DELTA_PROBEABLE_RADIUS, 0) // Probing points for 3-Point leveling of the mesh + #define UBL_PROBE_PT_1_Y _PY(DELTA_PROBEABLE_RADIUS, 0) + #define UBL_PROBE_PT_2_X _PX(DELTA_PROBEABLE_RADIUS, 120) + #define UBL_PROBE_PT_2_Y _PY(DELTA_PROBEABLE_RADIUS, 120) + #define UBL_PROBE_PT_3_X _PX(DELTA_PROBEABLE_RADIUS, 240) + #define UBL_PROBE_PT_3_Y _PY(DELTA_PROBEABLE_RADIUS, 240) + + #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation + #define UBL_MESH_EDIT_MOVES_Z // Sophisticated users prefer no movement of nozzle + +#elif ENABLED(MESH_BED_LEVELING) + + //=========================================================================== + //=================================== Mesh ================================== + //=========================================================================== + + #define MESH_INSET 10 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 3 // Don't use more than 7 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + //#define MESH_G28_REST_ORIGIN // After homing all axes ('G28' or 'G28 XYZ') rest Z at Z_MIN_POS + +#endif // BED_LEVELING + +/** + * Use the LCD controller for bed leveling + * Requires MESH_BED_LEVELING or PROBE_MANUALLY + */ +//#define LCD_BED_LEVELING + +#if ENABLED(LCD_BED_LEVELING) + #define MBL_Z_STEP 0.025 // Step size while manually probing Z axis. + #define LCD_PROBE_Z_RANGE 4 // Z Range centered on Z_MIN_POS for LCD Z adjustment +#endif + +// Add a menu item to move between bed corners for manual bed adjustment +//#define LEVEL_BED_CORNERS + +/** + * Commands to execute at the end of G29 probing. + * Useful to retract or move the Z probe out of the way. + */ +//#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) +#define BED_CENTER_AT_0_0 + +// Manually set the home position. Leave these undefined for automatic settings. +// For DELTA this is the top-center of the Cartesian print volume. +//#define MANUAL_X_HOME_POS 0 +//#define MANUAL_Y_HOME_POS 0 +#define MANUAL_Z_HOME_POS DELTA_HEIGHT // Distance between the nozzle to printbed after homing + +// Use "Z Safe Homing" to avoid homing with a Z probe outside the bed area. +// +// With this feature enabled: +// +// - 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). +// - 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 axis (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). +#endif + +// Delta only homes to Z +#define HOMING_FEEDRATE_Z (60*60) + +//============================================================================= +//============================= Additional Features =========================== +//============================================================================= + +// @section extras + +// +// EEPROM +// +// The microcontroller can store settings in the EEPROM, e.g. max velocity... +// M500 - stores parameters in EEPROM +// M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily). +// M502 - reverts to the default "factory settings". You still need to store them in EEPROM afterwards if you want to. +// +#define EEPROM_SETTINGS // Enable for M500 and M501 commands +//#define DISABLE_M503 // Saves ~2700 bytes of PROGMEM. Disable for release! +#define EEPROM_CHITCHAT // Give feedback on EEPROM commands. Disable to save PROGMEM. + +// +// Host Keepalive +// +// When enabled Marlin will send a busy status message to the host +// every couple of seconds when it can't accept commands. +// +#define HOST_KEEPALIVE_FEATURE // Disable this if your host doesn't like keepalive messages +#define DEFAULT_KEEPALIVE_INTERVAL 2 // Number of seconds between "busy" messages. Set with M113. +#define BUSY_WHILE_HEATING // Some hosts require "busy" messages even during heating + +// +// M100 Free Memory Watcher +// +//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose + +// +// G20/G21 Inch mode support +// +//#define INCH_MODE_SUPPORT + +// +// M149 Set temperature units support +// +//#define TEMPERATURE_UNITS_SUPPORT + +// @section temperature + +// Preheat Constants +#define PREHEAT_1_TEMP_HOTEND 180 +#define PREHEAT_1_TEMP_BED 70 +#define PREHEAT_1_FAN_SPEED 255 // Value from 0 to 255 + +#define PREHEAT_2_TEMP_HOTEND 240 +#define PREHEAT_2_TEMP_BED 100 +#define PREHEAT_2_FAN_SPEED 255 // Value from 0 to 255 + +/** + * Nozzle Park -- EXPERIMENTAL + * + * Park the nozzle at the given XYZ position on idle or G27. + * + * The "P" parameter controls the action applied to the Z axis: + * + * P0 (Default) If Z is below park Z raise the nozzle. + * P1 Raise the nozzle always to Z-park height. + * P2 Raise the nozzle by Z-park amount, limited to Z_MAX_POS. + */ +//#define NOZZLE_PARK_FEATURE + +#if ENABLED(NOZZLE_PARK_FEATURE) + // Specify a park position as { X, Y, Z } + #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 } +#endif + +/** + * Clean Nozzle Feature -- EXPERIMENTAL + * + * Adds the G12 command to perform a nozzle cleaning process. + * + * Parameters: + * P Pattern + * S Strokes / Repetitions + * T Triangles (P1 only) + * + * Patterns: + * P0 Straight line (default). This process requires a sponge type material + * at a fixed bed location. "S" specifies strokes (i.e. back-forth motions) + * between the start / end points. + * + * P1 Zig-zag pattern between (X0, Y0) and (X1, Y1), "T" specifies the + * number of zig-zag triangles to do. "S" defines the number of strokes. + * Zig-zags are done in whichever is the narrower dimension. + * For example, "G12 P1 S1 T3" will execute: + * + * -- + * | (X0, Y1) | /\ /\ /\ | (X1, Y1) + * | | / \ / \ / \ | + * A | | / \ / \ / \ | + * | | / \ / \ / \ | + * | (X0, Y0) | / \/ \/ \ | (X1, Y0) + * -- +--------------------------------+ + * |________|_________|_________| + * T1 T2 T3 + * + * P2 Circular pattern with middle at NOZZLE_CLEAN_CIRCLE_MIDDLE. + * "R" specifies the radius. "S" specifies the stroke count. + * Before starting, the nozzle moves to NOZZLE_CLEAN_START_POINT. + * + * Caveats: The ending Z should be the same as starting Z. + * Attention: EXPERIMENTAL. G-code arguments may change. + * + */ +//#define NOZZLE_CLEAN_FEATURE + +#if ENABLED(NOZZLE_CLEAN_FEATURE) + // Default number of pattern repetitions + #define NOZZLE_CLEAN_STROKES 12 + + // Default number of triangles + #define NOZZLE_CLEAN_TRIANGLES 3 + + // Specify positions as { X, Y, Z } + #define NOZZLE_CLEAN_START_POINT { 30, 30, (Z_MIN_POS + 1)} + #define NOZZLE_CLEAN_END_POINT {100, 60, (Z_MIN_POS + 1)} + + // Circular pattern radius + #define NOZZLE_CLEAN_CIRCLE_RADIUS 6.5 + // Circular pattern circle fragments number + #define NOZZLE_CLEAN_CIRCLE_FN 10 + // Middle point of circle + #define NOZZLE_CLEAN_CIRCLE_MIDDLE NOZZLE_CLEAN_START_POINT + + // Moves the nozzle to the initial position + #define NOZZLE_CLEAN_GOBACK +#endif + +/** + * Print Job Timer + * + * Automatically start and stop the print job timer on M104/M109/M190. + * + * M104 (hotend, no wait) - high temp = none, low temp = stop timer + * M109 (hotend, wait) - high temp = start timer, low temp = stop timer + * M190 (bed, wait) - high temp = start timer, low temp = none + * + * The timer can also be controlled with the following commands: + * + * M75 - Start the print job timer + * M76 - Pause the print job timer + * M77 - Stop the print job timer + */ +#define PRINTJOB_TIMER_AUTOSTART + +/** + * Print Counter + * + * Track statistical data such as: + * + * - Total print jobs + * - Total successful print jobs + * - Total failed print jobs + * - Total time printing + * + * View the current statistics with M78. + */ +//#define PRINTCOUNTER + +//============================================================================= +//============================= LCD and SD support ============================ +//============================================================================= + +// @section lcd + +/** + * LCD LANGUAGE + * + * Select the language to display on the LCD. These languages are available: + * + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, + * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * tr, uk, zh_CN, zh_TW, test + * + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + */ +#define LCD_LANGUAGE en + +/** + * LCD Character Set + * + * Note: This option is NOT applicable to Graphical Displays. + * + * All character-based LCDs provide ASCII plus one of these + * language extensions: + * + * - JAPANESE ... the most common + * - WESTERN ... with more accented characters + * - CYRILLIC ... for the Russian language + * + * To determine the language extension installed on your controller: + * + * - Compile and upload with LCD_LANGUAGE set to 'test' + * - 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 + * + * :['JAPANESE', 'WESTERN', 'CYRILLIC'] + */ +#define DISPLAY_CHARSET_HD44780 JAPANESE + +/** + * LCD TYPE + * + * Enable ULTRA_LCD for a 16x2, 16x4, 20x2, or 20x4 character-based LCD. + * Enable DOGLCD for a 128x64 (ST7565R) Full Graphical Display. + * (These options will be enabled automatically for most displays.) + * + * IMPORTANT: The U8glib library is required for Full Graphic Display! + * https://github.com/olikraus/U8glib_Arduino + */ +//#define ULTRA_LCD // Character based +//#define DOGLCD // Full graphics display + +/** + * SD CARD + * + * 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 + +/** + * SD CARD: SPI SPEED + * + * Enable one of the following items for a slower SPI transfer speed. + * This may be required to resolve "volume init" errors. + */ +//#define SPI_SPEED SPI_HALF_SPEED +//#define SPI_SPEED SPI_QUARTER_SPEED +//#define SPI_SPEED SPI_EIGHTH_SPEED + +/** + * SD CARD: ENABLE CRC + * + * Use CRC checks and retries on the SD communication. + */ +//#define SD_CHECK_AND_RETRY + +// +// ENCODER SETTINGS +// +// This option overrides the default number of encoder pulses needed to +// produce one step. Should be increased for high-resolution encoders. +// +//#define ENCODER_PULSES_PER_STEP 1 + +// +// Use this option to override the number of step signals required to +// move between next/prev menu items. +// +//#define ENCODER_STEPS_PER_MENU_ITEM 5 + +/** + * Encoder Direction Options + * + * Test your encoder's behavior first with both options disabled. + * + * Reversed Value Edit and Menu Nav? Enable REVERSE_ENCODER_DIRECTION. + * Reversed Menu Navigation only? Enable REVERSE_MENU_DIRECTION. + * Reversed Value Editing only? Enable BOTH options. + */ + +// +// This option reverses the encoder direction everywhere. +// +// Set this option if CLOCKWISE causes values to DECREASE +// +//#define REVERSE_ENCODER_DIRECTION + +// +// This option reverses the encoder direction for navigating LCD menus. +// +// If CLOCKWISE normally moves DOWN this makes it go UP. +// If CLOCKWISE normally moves UP this makes it go DOWN. +// +//#define REVERSE_MENU_DIRECTION + +// +// Individual Axis Homing +// +// Add individual axis homing items (Home X, Home Y, and Home Z) to the LCD menu. +// +//#define INDIVIDUAL_AXIS_HOMING_MENU + +// +// SPEAKER/BUZZER +// +// If you have a speaker that can produce tones, enable it here. +// By default Marlin assumes you have a buzzer with a fixed frequency. +// +//#define SPEAKER + +// +// The duration and frequency for the UI feedback sound. +// Set these to 0 to disable audio feedback in the LCD menus. +// +// Note: Test audio output with the G-Code: +// M300 S P +// +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 +//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 + +// +// CONTROLLER TYPE: Standard +// +// Marlin supports a wide variety of controllers. +// Enable one of the following options to specify your controller. +// + +// +// ULTIMAKER Controller. +// +//#define ULTIMAKERCONTROLLER + +// +// ULTIPANEL as seen on Thingiverse. +// +//#define ULTIPANEL + +// +// PanelOne from T3P3 (via RAMPS 1.4 AUX2/AUX3) +// http://reprap.org/wiki/PanelOne +// +//#define PANEL_ONE + +// +// MaKr3d Makr-Panel with graphic controller and SD support. +// http://reprap.org/wiki/MaKr3d_MaKrPanel +// +//#define MAKRPANEL + +// +// ReprapWorld Graphical LCD +// https://reprapworld.com/?products_details&products_id/1218 +// +//#define REPRAPWORLD_GRAPHICAL_LCD + +// +// Activate one of these if you have a Panucatt Devices +// Viki 2.0 or mini Viki with Graphic LCD +// http://panucatt.com +// +//#define VIKI2 +//#define miniVIKI + +// +// Adafruit ST7565 Full Graphic Controller. +// https://github.com/eboston/Adafruit-ST7565-Full-Graphic-Controller/ +// +//#define ELB_FULL_GRAPHIC_CONTROLLER + +// +// RepRapDiscount Smart Controller. +// http://reprap.org/wiki/RepRapDiscount_Smart_Controller +// +// Note: Usually sold with a white PCB. +// +#define REPRAP_DISCOUNT_SMART_CONTROLLER + +// +// GADGETS3D G3D LCD/SD Controller +// http://reprap.org/wiki/RAMPS_1.3/1.4_GADGETS3D_Shield_with_Panel +// +// Note: Usually sold with a blue PCB. +// +//#define G3D_PANEL + +// +// RepRapDiscount FULL GRAPHIC Smart Controller +// http://reprap.org/wiki/RepRapDiscount_Full_Graphic_Smart_Controller +// +//#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER + +// +// MakerLab Mini Panel with graphic +// controller and SD support - http://reprap.org/wiki/Mini_panel +// +//#define MINIPANEL + +// +// RepRapWorld REPRAPWORLD_KEYPAD v1.1 +// http://reprapworld.com/?products_details&products_id=202&cPath=1591_1626 +// +// REPRAPWORLD_KEYPAD_MOVE_STEP sets how much should the robot move when a key +// is pressed, a value of 10.0 means 10mm per click. +// +//#define REPRAPWORLD_KEYPAD +//#define REPRAPWORLD_KEYPAD_MOVE_STEP 1.0 + +// +// RigidBot Panel V1.0 +// http://www.inventapart.com/ +// +//#define RIGIDBOT_PANEL + +// +// BQ LCD Smart Controller shipped by +// default with the BQ Hephestos 2 and Witbox 2. +// +//#define BQ_LCD_SMART_CONTROLLER + +// +// Cartesio UI +// http://mauk.cc/webshop/cartesio-shop/electronics/user-interface +// +//#define CARTESIO_UI + +// +// ANET_10 Controller supported displays. +// +//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. + // This LCD is known to be susceptible to electrical interference + // which scrambles the display. Pressing any button clears it up. +//#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 + // A clone of the RepRapDiscount full graphics display but with + // different pins/wiring (see pins_ANET_10.h). + +// +// LCD for Melzi Card with Graphical LCD +// +//#define LCD_FOR_MELZI + +// +// CONTROLLER TYPE: I2C +// +// Note: These controllers require the installation of Arduino's LiquidCrystal_I2C +// library. For more info: https://github.com/kiyoshigawa/LiquidCrystal_I2C +// + +// +// Elefu RA Board Control Panel +// http://www.elefu.com/index.php?route=product/product&product_id=53 +// +//#define RA_CONTROL_PANEL + +// +// Sainsmart YW Robot (LCM1602) LCD Display +// +// Note: This controller requires F.Malpartida's LiquidCrystal_I2C library +// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home +// +//#define LCD_I2C_SAINSMART_YWROBOT + +// +// Generic LCM1602 LCD adapter +// +//#define LCM1602 + +// +// PANELOLU2 LCD with status LEDs, +// separate encoder and click inputs. +// +// Note: This controller requires Arduino's LiquidTWI2 library v1.2.3 or later. +// For more info: https://github.com/lincomatic/LiquidTWI2 +// +// Note: The PANELOLU2 encoder click input can either be directly connected to +// a pin (if BTN_ENC defined to != -1) or read through I2C (when BTN_ENC == -1). +// +//#define LCD_I2C_PANELOLU2 + +// +// Panucatt VIKI LCD with status LEDs, +// integrated click & L/R/U/D buttons, separate encoder inputs. +// +//#define LCD_I2C_VIKI + +// +// SSD1306 OLED full graphics generic display +// +//#define U8GLIB_SSD1306 + +// +// SAV OLEd LCD module support using either SSD1306 or SH1106 based LCD modules +// +//#define SAV_3DGLCD +#if ENABLED(SAV_3DGLCD) + //#define U8GLIB_SSD1306 + #define U8GLIB_SH1106 +#endif + +// +// CONTROLLER TYPE: Shift register panels +// +// 2 wire Non-latching LCD SR from https://goo.gl/aJJ4sH +// LCD configuration: http://reprap.org/wiki/SAV_3D_LCD +// +//#define SAV_3DLCD + +// +// TinyBoy2 128x64 OLED / Encoder Panel +// +//#define OLED_PANEL_TINYBOY2 + +// +// Makeboard 3D Printer Parts 3D Printer Mini Display 1602 Mini Controller +// https://www.aliexpress.com/item/Micromake-Makeboard-3D-Printer-Parts-3D-Printer-Mini-Display-1602-Mini-Controller-Compatible-with-Ramps-1/32765887917.html +// +//#define MAKEBOARD_MINI_2_LINE_DISPLAY_1602 + +// +// MKS MINI12864 with graphic controller and SD support +// http://reprap.org/wiki/MKS_MINI_12864 +// +//#define MKS_MINI_12864 + +// +// Factory display for Creality CR-10 +// https://www.aliexpress.com/item/Universal-LCD-12864-3D-Printer-Display-Screen-With-Encoder-For-CR-10-CR-7-Model/32833148327.html +// +// This is RAMPS-compatible using a single 10-pin connector. +// (For CR-10 owners who want to replace the Melzi Creality board but retain the display) +// +//#define CR10_STOCKDISPLAY + +// +// MKS OLED 1.3" 128 × 64 FULL GRAPHICS CONTROLLER +// http://reprap.org/wiki/MKS_12864OLED +// +// Tiny, but very sharp OLED display +// +//#define MKS_12864OLED + +//============================================================================= +//=============================== Extra Features ============================== +//============================================================================= + +// @section extras + +// Increase the FAN PWM frequency. Removes the PWM noise but increases heating in the FET/Arduino +//#define FAST_PWM_FAN + +// Use software PWM to drive the fan, as for the heaters. This uses a very low frequency +// which is not as annoying as with the hardware PWM. On the other hand, if this frequency +// is too low, you should also increment SOFT_PWM_SCALE. +//#define FAN_SOFT_PWM + +// Incrementing this by 1 will double the software PWM frequency, +// affecting heaters, and the fan if FAN_SOFT_PWM is enabled. +// However, control resolution will be halved for each increment; +// at zero value, there are 128 effective control positions. +#define SOFT_PWM_SCALE 0 + +// If SOFT_PWM_SCALE is set to a value higher than 0, dithering can +// be used to mitigate the associated resolution loss. If enabled, +// some of the PWM cycles are stretched so on average the desired +// duty cycle is attained. +//#define SOFT_PWM_DITHER + +// Temperature status LEDs that display the hotend and bed temperature. +// If all hotends, bed temperature, and target temperature are under 54C +// then the BLUE led is on. Otherwise the RED led is on. (1C hysteresis) +//#define TEMP_STAT_LEDS + +// M240 Triggers a camera by emulating a Canon RC-1 Remote +// Data from: http://www.doc-diy.net/photo/rc-1_hacked/ +//#define PHOTOGRAPH_PIN 23 + +// 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 + +// Support for BlinkM/CyzRgb +//#define BLINKM + +// Support for PCA9632 PWM LED driver +//#define PCA9632 + +/** + * RGB LED / LED Strip Control + * + * Enable support for an RGB LED connected to 5V digital pins, or + * an RGB Strip connected to MOSFETs controlled by digital pins. + * + * 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 overall brightness parameters is also available + * + * *** CAUTION *** + * LED Strips require a MOFSET 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! + * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino + * cannot handle such current, separate 5V power supply must be used + * *** CAUTION *** + * + * LED type. This options are mutualy exclusive. Uncomment only one. + * + */ +//#define RGB_LED +//#define RGBW_LED + +#if ENABLED(RGB_LED) || ENABLED(RGBW_LED) + #define RGB_LED_R_PIN 34 + #define RGB_LED_G_PIN 43 + #define RGB_LED_B_PIN 35 + #define RGB_LED_W_PIN -1 +#endif + +// 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 (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) + #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip + #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time + #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + //#define NEOPIXEL_STARTUP_TEST // Cycle through colors at startup +#endif + +/** + * Printer Event LEDs + * + * During printing, the LEDs will reflect the printer status: + * + * - Gradually change from blue to violet as the heated bed gets to target temp + * - Gradually change from violet to red as the hotend gets to temperature + * - Change to white to illuminate work surface + * - Change to green once print has finished + * - Turn off after the print has finished and the user has pushed a button + */ +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) + #define PRINTER_EVENT_LEDS +#endif + +/*********************************************************************\ +* R/C SERVO support +* Sponsored by TrinityLabs, Reworked by codexmas +**********************************************************************/ + +// Number of servos +// +// If you select a configuration below, this will receive a default value and does not need to be set manually +// set it manually if you have more servos than extruders and wish to manually control some +// leaving it undefined or defining as 0 will disable the servo subsystem +// If unsure, leave commented / disabled +// +//#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command + +// Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. +// 300ms is a good value but you can try less delay. +// If the servo can't reach the requested position, increase it. +#define SERVO_DELAY { 300 } + +// Servo deactivation +// +// With this option servos are powered only during movement, then turned off to prevent jitter. +//#define DEACTIVATE_SERVOS_AFTER_MOVE + +/** + * Filament Width Sensor + * + * Measures the filament width in real-time and adjusts + * flow rate to compensate for any irregularities. + * + * Also allows the measured filament diameter to set the + * extrusion rate, so the slicer only has to specify the + * volume. + * + * Only a single extruder is supported at this time. + * + * 34 RAMPS_14 : Analog input 5 on the AUX2 connector + * 81 PRINTRBOARD : Analog input 2 on the Exp1 connector (version B,C,D,E) + * 301 RAMBO : Analog input 3 + * + * Note: May require analog pins to be defined for other boards. + */ +//#define FILAMENT_WIDTH_SENSOR + +#define DEFAULT_NOMINAL_FILAMENT_DIA 3.00 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. + +#if ENABLED(FILAMENT_WIDTH_SENSOR) + #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) + #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber + + #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading + #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading + #define MAX_MEASUREMENT_DELAY 20 // (bytes) Buffer size for stored measurements (1 byte per cm). Must be larger than MEASUREMENT_DELAY_CM. + + #define DEFAULT_MEASURED_FILAMENT_DIA DEFAULT_NOMINAL_FILAMENT_DIA // Set measured to nominal initially + + // Display filament width on the LCD status line. Status messages will expire after 5 seconds. + //#define FILAMENT_LCD_DISPLAY +#endif + +#endif // CONFIGURATION_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/delta/kossel_xl/Configuration_adv.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/delta/kossel_xl/Configuration_adv.h new file mode 100644 index 00000000..0c04e6d9 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/delta/kossel_xl/Configuration_adv.h @@ -0,0 +1,1426 @@ +/** + * 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 . + * + */ + +/** + * Configuration_adv.h + * + * Advanced settings. + * Only change these if you know exactly what you're doing. + * Some of these settings can damage your printer if improperly set! + * + * Basic settings can be found in Configuration.h + * + */ +#ifndef CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H_VERSION 010100 + +// @section temperature + +//=========================================================================== +//=============================Thermal Settings ============================ +//=========================================================================== + +#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 + #endif +#endif + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * The solution: Once the temperature reaches the target, start observing. + * If the temperature stays too far below the target (hysteresis) for too long (period), + * the firmware will halt the machine as a safety precaution. + * + * If you get false positives for "Thermal Runaway" increase THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD + */ +#if ENABLED(THERMAL_PROTECTION_HOTENDS) + #define THERMAL_PROTECTION_PERIOD 40 // Seconds + #define THERMAL_PROTECTION_HYSTERESIS 4 // Degrees Celsius + + /** + * Whenever an M104 or M109 increases the target temperature the firmware will wait for the + * WATCH_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get false positives for "Heating failed" increase WATCH_TEMP_PERIOD and/or decrease WATCH_TEMP_INCREASE + * WATCH_TEMP_INCREASE should not be below 2. + */ + #define WATCH_TEMP_PERIOD 20 // Seconds + #define WATCH_TEMP_INCREASE 2 // Degrees Celsius +#endif + +/** + * Thermal Protection parameters for the bed are just as above for hotends. + */ +#if ENABLED(THERMAL_PROTECTION_BED) + #define THERMAL_PROTECTION_BED_PERIOD 20 // Seconds + #define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius + + /** + * Whenever an M140 or M190 increases the target temperature the firmware will wait for the + * WATCH_BED_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_BED_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get too many "Heating failed" errors, increase WATCH_BED_TEMP_PERIOD and/or decrease + * WATCH_BED_TEMP_INCREASE. (WATCH_BED_TEMP_INCREASE should not be below 2.) + */ + #define WATCH_BED_TEMP_PERIOD 60 // Seconds + #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius +#endif + +#if ENABLED(PIDTEMP) + // this adds an experimental additional term to the heating power, proportional to the extrusion speed. + // if Kc is chosen well, the additional required power due to increased melting should be compensated. + //#define PID_EXTRUSION_SCALING + #if ENABLED(PID_EXTRUSION_SCALING) + #define DEFAULT_Kc (100) //heating power=Kc*(e_speed) + #define LPQ_MAX_LEN 50 + #endif +#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 + */ +#define AUTOTEMP +#if ENABLED(AUTOTEMP) + #define AUTOTEMP_OLDWEIGHT 0.98 +#endif + +// Show Temperature ADC value +// Enable for M105 to include ADC values read from temperature sensors. +//#define SHOW_TEMP_ADC_VALUES + +/** + * High Temperature Thermistor Support + * + * Thermistors able to support high temperature tend to have a hard time getting + * good readings at room and lower temperatures. This means HEATER_X_RAW_LO_TEMP + * will probably be caught when the heating element first turns on during the + * preheating process, which will trigger a min_temp_error as a safety measure + * and force stop everything. + * To circumvent this limitation, we allow for a preheat time (during which, + * min_temp_error won't be triggered) and add a min_temp buffer to handle + * aberrant readings. + * + * If you want to enable this feature for your hotend thermistor(s) + * uncomment and set values > 0 in the constants below + */ + +// The number of consecutive low temperature errors that can occur +// before a min_temp_error is triggered. (Shouldn't be more than 10.) +//#define MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED 0 + +// The number of milliseconds a hotend will preheat before starting to check +// the temperature. This value should NOT be set to the time it takes the +// hot end to reach the target temperature, but the time it takes to reach +// the minimum temperature your thermistor can read. The lower the better/safer. +// This shouldn't need to be more than 30 seconds (30000) +//#define MILLISECONDS_PREHEAT_TIME 0 + +// @section extruder + +// Extruder runout prevention. +// If the machine is idle and the temperature over MINTEMP +// then extrude some filament every couple of SECONDS. +//#define EXTRUDER_RUNOUT_PREVENT +#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_EXTRUDE 5 // mm +#endif + +// @section temperature + +//These defines help to calibrate the AD595 sensor in case you get wrong temperature measurements. +//The measured temperature is defined as "actualTemp = (measuredTemp * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET" +#define TEMP_SENSOR_AD595_OFFSET 0.0 +#define TEMP_SENSOR_AD595_GAIN 1.0 + +/** + * 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. + */ +//#define USE_CONTROLLER_FAN +#if ENABLED(USE_CONTROLLER_FAN) + //#define CONTROLLER_FAN_PIN FAN1_PIN // 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 +#endif + +// When first starting the main fan, run it at full speed for the +// given number of milliseconds. This gets the fan spinning reliably +// before setting a PWM value. (Does not work with software PWM for fan on Sanguinololu) +//#define FAN_KICKSTART_TIME 100 + +// This defines the minimal speed for the main fan, run in PWM mode +// to enable uncomment and set minimal PWM speed for reliable running (1-255) +// if fan speed is [1 - (FAN_MIN_PWM-1)] it is set to FAN_MIN_PWM +//#define FAN_MIN_PWM 50 + +// @section extruder + +/** + * Extruder cooling fans + * + * Extruder auto fans automatically turn on when their extruders' + * temperatures go above EXTRUDER_AUTO_FAN_TEMPERATURE. + * + * Your board's pins file specifies the recommended pins. Override those here + * or set to -1 to disable completely. + * + * Multiple extruders can be assigned to the same pin in which case + * the fan will turn on when any selected extruder is above the threshold. + */ +#define E0_AUTO_FAN_PIN -1 +#define E1_AUTO_FAN_PIN -1 +#define E2_AUTO_FAN_PIN -1 +#define E3_AUTO_FAN_PIN -1 +#define E4_AUTO_FAN_PIN -1 +#define EXTRUDER_AUTO_FAN_TEMPERATURE 50 +#define EXTRUDER_AUTO_FAN_SPEED 255 // == full speed + +/** + * Part-Cooling Fan Multiplexer + * + * This feature allows you to digitally multiplex the fan output. + * The multiplexer is automatically switched at tool-change. + * Set FANMUX[012]_PINs below for up to 2, 4, or 8 multiplexed fans. + */ +#define FANMUX0_PIN -1 +#define FANMUX1_PIN -1 +#define FANMUX2_PIN -1 + +/** + * M355 Case Light on-off / brightness + */ +//#define CASE_LIGHT_ENABLE +#if ENABLED(CASE_LIGHT_ENABLE) + //#define CASE_LIGHT_PIN 4 // Override the default pin if needed + #define INVERT_CASE_LIGHT false // Set true if Case Light is ON when pin is LOW + #define CASE_LIGHT_DEFAULT_ON true // Set default power-up state on + #define CASE_LIGHT_DEFAULT_BRIGHTNESS 105 // Set default power-up brightness (0-255, requires PWM pin) + //#define MENU_ITEM_CASE_LIGHT // Add a Case Light option to the LCD main menu +#endif + +//=========================================================================== +//============================ Mechanical Settings ========================== +//=========================================================================== + +// @section homing + +// If you want endstops to stay on (by default) even when not homing +// enable this option. Override at any time with M120, M121. +//#define ENDSTOPS_ALWAYS_ON_DEFAULT + +// @section extras + +//#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. + +// Dual X Steppers +// Uncomment this option to drive two X axis motors. +// The next unused E driver will be assigned to the second X stepper. +//#define X_DUAL_STEPPER_DRIVERS +#if ENABLED(X_DUAL_STEPPER_DRIVERS) + // Set true if the two X motors need to rotate in opposite directions + #define INVERT_X2_VS_X_DIR true +#endif + +// Dual Y Steppers +// Uncomment this option to drive two Y axis motors. +// The next unused E driver will be assigned to the second Y stepper. +//#define Y_DUAL_STEPPER_DRIVERS +#if ENABLED(Y_DUAL_STEPPER_DRIVERS) + // Set true if the two Y motors need to rotate in opposite directions + #define INVERT_Y2_VS_Y_DIR true +#endif + +// A single Z stepper driver is usually used to drive 2 stepper motors. +// Uncomment this option to use a separate stepper driver for each Z axis motor. +// The next unused E driver will be assigned to the second Z stepper. +//#define Z_DUAL_STEPPER_DRIVERS + +#if ENABLED(Z_DUAL_STEPPER_DRIVERS) + + // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper. + // That way the machine is capable to align the bed during home, since both Z steppers are homed. + // There is also an implementation of M666 (software endstops adjustment) to this feature. + // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed. + // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2. + // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive. + // Play a little bit with small adjustments (0.5mm) and check the behaviour. + // The M119 (endstops report) will start reporting the Z2 Endstop as well. + + //#define Z_DUAL_ENDSTOPS + + #if ENABLED(Z_DUAL_ENDSTOPS) + #define Z2_USE_ENDSTOP _XMAX_ + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 // Use M666 to determine/test this value + #endif + +#endif // Z_DUAL_STEPPER_DRIVERS + +// Enable this for dual x-carriage printers. +// A dual x-carriage design has the advantage that the inactive extruder can be parked which +// prevents hot-end ooze contaminating the print. It also reduces the weight of each x-carriage +// allowing faster printing speeds. Connect your X2 stepper to the first unused E plug. +//#define DUAL_X_CARRIAGE +#if ENABLED(DUAL_X_CARRIAGE) + // Configuration for second X-carriage + // Note: the first x-carriage is defined as the x-carriage which homes to the minimum endstop; + // the second x-carriage always homes to the maximum endstop. + #define X2_MIN_POS 80 // set minimum to ensure second x-carriage doesn't hit the parked first X-carriage + #define X2_MAX_POS 353 // set maximum to the distance between toolheads when both heads are homed + #define X2_HOME_DIR 1 // the second X-carriage always homes to the maximum endstop position + #define X2_HOME_POS X2_MAX_POS // default home position is the maximum carriage position + // However: In this mode the HOTEND_OFFSET_X value for the second extruder provides a software + // override for X2_HOME_POS. This also allow recalibration of the distance between the two endstops + // without modifying the firmware (through the "M218 T1 X???" command). + // Remember: you should set the second extruder x-offset to 0 in your slicer. + + // There are a few selectable movement modes for dual x-carriages using M605 S + // Mode 0 (DXC_FULL_CONTROL_MODE): Full control. The slicer has full control over both x-carriages and can achieve optimal travel results + // as long as it supports dual x-carriages. (M605 S0) + // Mode 1 (DXC_AUTO_PARK_MODE) : Auto-park mode. The firmware will automatically park and unpark the x-carriages on tool changes so + // that additional slicer support is not required. (M605 S1) + // Mode 2 (DXC_DUPLICATION_MODE) : Duplication mode. The firmware will transparently make the second x-carriage and extruder copy all + // actions of the first x-carriage. This allows the printer to print 2 arbitrary items at + // once. (2nd extruder x offset and temp offset are set using: M605 S2 [Xnnn] [Rmmm]) + + // This is the default power-up mode which can be later using M605. + #define DEFAULT_DUAL_X_CARRIAGE_MODE DXC_FULL_CONTROL_MODE + + // Default settings in "Auto-park Mode" + #define TOOLCHANGE_PARK_ZLIFT 0.2 // the distance to raise Z axis when parking an extruder + #define TOOLCHANGE_UNPARK_ZLIFT 1 // the distance to raise Z axis when unparking an extruder + + // Default x offset in duplication mode (typically set to half print bed width) + #define DEFAULT_DUPLICATION_X_OFFSET 100 + +#endif // DUAL_X_CARRIAGE + +// 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. +//#define EXT_SOLENOID + +// @section homing + +//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +#define X_HOME_BUMP_MM 2 +#define Y_HOME_BUMP_MM 2 +#define Z_HOME_BUMP_MM 2 // deltas need the same for all three axes +#define HOMING_BUMP_DIVISOR {2, 2, 4} // Re-Bump Speed Divisor (Divides the Homing Feedrate) +//#define QUICK_HOME //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially. + +// When G28 is called, this option will make Y home before X +//#define HOME_Y_BEFORE_X + +// @section machine + +#define AXIS_RELATIVE_MODES {false, false, false, false} + +// Allow duplication mode with a basic dual-nozzle extruder +//#define DUAL_NOZZLE_DUPLICATION_MODE + +// By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step. +#define INVERT_X_STEP_PIN false +#define INVERT_Y_STEP_PIN false +#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. +#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_E true + +#define DEFAULT_MINIMUMFEEDRATE 0.0 // minimum feedrate +#define DEFAULT_MINTRAVELFEEDRATE 0.0 + +//#define HOME_AFTER_DEACTIVATE // Require rehoming after steppers are deactivated + +// @section lcd + +#if ENABLED(ULTIPANEL) + #define MANUAL_FEEDRATE_XYZ 50*60 + #define MANUAL_FEEDRATE { MANUAL_FEEDRATE_XYZ, MANUAL_FEEDRATE_XYZ, MANUAL_FEEDRATE_XYZ, 60 } // Feedrates for manual moves along X, Y, Z, E from panel + #define ULTIPANEL_FEEDMULTIPLY // Comment to disable setting feedrate multiplier via encoder +#endif + +// @section extras + +// minimum time in microseconds that a movement needs to take if the buffer is emptied. +#define DEFAULT_MINSEGMENTTIME 20000 + +// If defined the movements slow down when the look ahead buffer is only half full +// (don't use SLOWDOWN with DELTA because DELTA generates hundreds of segments per second) +//#define SLOWDOWN + +// Frequency limit +// See nophead's blog for more info +// Not working O +//#define XY_FREQUENCY_LIMIT 15 + +// 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 +// if unwanted behavior is observed on a user's machine when running at very slow speeds. +#define MINIMUM_PLANNER_SPEED 0.05 // (mm/sec) + +// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU. +#define MICROSTEP_MODES {16,16,16,16,16} // [1,2,4,8,16] + +/** + * @section stepper motor current + * + * Some boards have a means of setting the stepper motor current via firmware. + * + * The power on motor currents are set by: + * PWM_MOTOR_CURRENT - used by MINIRAMBO & ULTIMAIN_2 + * known compatible chips: A4982 + * DIGIPOT_MOTOR_CURRENT - used by BQ_ZUM_MEGA_3D, RAMBO & SCOOVO_X9H + * known compatible chips: AD5206 + * DAC_MOTOR_CURRENT_DEFAULT - used by PRINTRBOARD_REVF & RIGIDBOARD_V2 + * known compatible chips: MCP4728 + * DIGIPOT_I2C_MOTOR_CURRENTS - used by 5DPRINT, AZTEEG_X3_PRO, MIGHTYBOARD_REVE + * known compatible chips: MCP4451, MCP4018 + * + * Motor currents can also be set by M907 - M910 and by the LCD. + * M907 - applies to all. + * M908 - BQ_ZUM_MEGA_3D, RAMBO, PRINTRBOARD_REVF, RIGIDBOARD_V2 & SCOOVO_X9H + * M909, M910 & LCD - only PRINTRBOARD_REVF & RIGIDBOARD_V2 + */ +//#define PWM_MOTOR_CURRENT { 1300, 1300, 1250 } // Values in milliamps +//#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 + +// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +//#define DIGIPOT_I2C +//#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster +#define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 +// Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS +#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=========================== +//=========================================================================== + +#define ENCODER_RATE_MULTIPLIER // If defined, certain menu edit operations automatically multiply the steps when the encoder is moved quickly +#define ENCODER_10X_STEPS_PER_SEC 75 // If the encoder steps per sec exceeds this value, multiply steps moved x10 to quickly advance the value +#define ENCODER_100X_STEPS_PER_SEC 160 // If the encoder steps per sec exceeds this value, multiply steps moved x100 to really quickly advance the value + +//#define CHDK 4 //Pin for triggering CHDK to take a picture see how to use it here http://captain-slow.dk/2014/03/09/3d-printing-timelapses/ +#define CHDK_DELAY 50 //How long in ms the pin should stay HIGH before going LOW again + +// @section lcd + +// Include a page of printer information in the LCD Main Menu +//#define LCD_INFO_MENU + +// Scroll a longer status message into view +//#define STATUS_MESSAGE_SCROLLING + +// On the Info Screen, display XY with one decimal place when possible +//#define LCD_DECIMAL_SMALL_XY + +// The timeout (in ms) to return to the status screen from sub-menus +//#define LCD_TIMEOUT_TO_STATUS 15000 + +#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 + + #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? + #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. + + #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. + // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. + // using: + //#define MENU_ADDAUTOSTART + + /** + * Sort SD file listings in alphabetical order. + * + * With this option enabled, items on SD cards will be sorted + * by name for easier navigation. + * + * By default... + * + * - Use the slowest -but safest- method for sorting. + * - Folders are sorted to the top. + * - The sort key is statically allocated. + * - No added G-code (M34) support. + * - 40 item sorting limit. (Items after the first 40 are unsorted.) + * + * SD sorting uses static allocation (as set by SDSORT_LIMIT), allowing the + * compiler to calculate the worst-case usage and throw an error if the SRAM + * limit is exceeded. + * + * - SDSORT_USES_RAM provides faster sorting via a static directory buffer. + * - SDSORT_USES_STACK does the same, but uses a local stack-based buffer. + * - SDSORT_CACHE_NAMES will retain the sorted file listing in RAM. (Expensive!) + * - SDSORT_DYNAMIC_RAM only uses RAM when the SD menu is visible. (Use with caution!) + */ + //#define SDCARD_SORT_ALPHA + + // SD Card Sorting options + #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_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. + #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #endif + + // Show a progress bar on HD44780 LCDs for SD printing + //#define LCD_PROGRESS_BAR + + #if ENABLED(LCD_PROGRESS_BAR) + // Amount of time (ms) to show the bar + #define PROGRESS_BAR_BAR_TIME 2000 + // Amount of time (ms) to show the status message + #define PROGRESS_BAR_MSG_TIME 3000 + // Amount of time (ms) to retain the status message (0=forever) + #define PROGRESS_MSG_EXPIRE 0 + // Enable this to show messages for MSG_TIME then hide them + //#define PROGRESS_MSG_ONCE + // Add a menu item to test the progress bar: + //#define LCD_PROGRESS_BAR_TEST + #endif + + // This allows hosts to request long names for files and folders with M33 + //#define LONG_FILENAME_HOST_SUPPORT + + // This option allows you to abort SD printing when any endstop is triggered. + // This feature must be enabled with "M540 S1" or from the LCD menu. + // To have any effect, endstops must be enabled during SD printing. + //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + +#endif // SDSUPPORT + +/** + * Additional options for Graphical Displays + * + * Use the optimizations here to improve printing performance, + * which can be adversely affected by graphical display drawing, + * especially when doing several short moves, and when printing + * on DELTA and SCARA machines. + * + * Some of these options may result in the display lagging behind + * controller events, as there is a trade-off between reliable + * printing performance versus fast display updates. + */ +#if ENABLED(DOGLCD) + // Enable to save many cycles by drawing a hollow frame on the Info Screen + #define XYZ_HOLLOW_FRAME + + // Enable to save many cycles by drawing a hollow frame on Menu Screens + #define MENU_HOLLOW_FRAME + + // A bigger font is available for edit items. Costs 3120 bytes of PROGMEM. + // 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. + // 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 +#endif // DOGLCD + +// @section safety + +// The hardware watchdog should reset the microcontroller disabling all outputs, +// in case the firmware gets stuck and doesn't do temperature regulation. +#define USE_WATCHDOG + +#if ENABLED(USE_WATCHDOG) + // If you have a watchdog reboot in an ArduinoMega2560 then the device will hang forever, as a watchdog reset will leave the watchdog on. + // The "WATCHDOG_RESET_MANUAL" goes around this by not using the hardware reset. + // However, THIS FEATURE IS UNSAFE!, as it will only work if interrupts are disabled. And the code could hang in an interrupt routine with interrupts disabled. + //#define WATCHDOG_RESET_MANUAL +#endif + +// @section lcd + +/** + * Babystepping enables movement of the axes by tiny increments without changing + * the current position values. This feature is used primarily to adjust the Z + * axis in the first layer of a print in real-time. + * + * Warning: Does not respect endstops! + */ +//#define BABYSTEPPING +#if ENABLED(BABYSTEPPING) + //#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 100 // Babysteps are very small. Increase for faster motion. + //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping + //#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen 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_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor + //#define BABYSTEP_ZPROBE_GFX_REVERSE // Reverses the direction of the CW/CCW indicators +#endif + +// @section extruder + +/** + * Implementation of linear pressure control + * + * Assumption: advance = k * (delta velocity) + * K=0 means advance disabled. + * See Marlin documentation for calibration instructions. + */ +//#define LIN_ADVANCE + +#if ENABLED(LIN_ADVANCE) + #define LIN_ADVANCE_K 75 + + /** + * Some Slicers produce Gcode with randomly jumping extrusion widths occasionally. + * For example within a 0.4mm perimeter it may produce a single segment of 0.05mm width. + * While this is harmless for normal printing (the fluid nature of the filament will + * close this very, very tiny gap), it throws off the LIN_ADVANCE pressure adaption. + * + * For this case LIN_ADVANCE_E_D_RATIO can be used to set the extrusion:distance ratio + * to a fixed value. Note that using a fixed ratio will lead to wrong nozzle pressures + * if the slicer is using variable widths or layer heights within one print! + * + * This option sets the default E:D ratio at startup. Use `M900` to override this value. + * + * Example: `M900 W0.4 H0.2 D1.75`, where: + * - W is the extrusion width in mm + * - H is the layer height in mm + * - D is the filament diameter in mm + * + * Example: `M900 R0.0458` to set the ratio directly. + * + * Set to 0 to auto-detect the ratio based on given Gcode G1 print moves. + * + * Slic3r (including Průša Control) produces Gcode compatible with the automatic mode. + * Cura (as of this writing) may produce Gcode incompatible with the automatic mode. + */ + #define LIN_ADVANCE_E_D_RATIO 0 // The calculated ratio (or 0) according to the formula W * H / ((D / 2) ^ 2 * PI) + // Example: 0.4 * 0.2 / ((1.75 / 2) ^ 2 * PI) = 0.033260135 +#endif + +// @section leveling + +// Default mesh area is an area with an inset margin on the print area. +// Below are the macros that are used to define the borders for the mesh area, +// made available here for specialized needs, ie dual extruder setup. +#if ENABLED(MESH_BED_LEVELING) + #define MESH_MIN_X MESH_INSET + #define MESH_MAX_X (X_BED_SIZE - (MESH_INSET)) + #define MESH_MIN_Y MESH_INSET + #define MESH_MAX_Y (Y_BED_SIZE - (MESH_INSET)) +#elif ENABLED(AUTO_BED_LEVELING_UBL) + #define UBL_MESH_MIN_X UBL_MESH_INSET + #define UBL_MESH_MAX_X (X_BED_SIZE - (UBL_MESH_INSET)) + #define UBL_MESH_MIN_Y UBL_MESH_INSET + #define UBL_MESH_MAX_Y (Y_BED_SIZE - (UBL_MESH_INSET)) + + // If this is defined, the currently active mesh will be saved in the + // current slot on M500. + #define UBL_SAVE_ACTIVE_ON_M500 +#endif + +// @section extras + +// +// G2/G3 Arc Support +// +#define ARC_SUPPORT // Disable this feature to save ~3226 bytes +#if ENABLED(ARC_SUPPORT) + #define MM_PER_ARC_SEGMENT 1 // Length of each arc segment + #define N_ARC_CORRECTION 25 // Number of intertpolated 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 +#endif + +// Support for G5 with XYZE destination and IJPQ offsets. Requires ~2666 bytes. +//#define BEZIER_CURVE_SUPPORT + +// G38.2 and G38.3 Probe Target +// Enable PROBE_DOUBLE_TOUCH if you want G38 to double touch +//#define G38_PROBE_TARGET +#if ENABLED(G38_PROBE_TARGET) + #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) +#endif + +// Moves (or segments) with fewer steps than this will be joined with the next move +#define MIN_STEPS_PER_SEGMENT 6 + +// The minimum pulse width (in µs) for stepping a stepper. +// Set this if you find stepping unreliable, or if using a very fast CPU. +#define MINIMUM_STEPPER_PULSE 0 // (µs) The smallest stepper pulse allowed + +// @section temperature + +// Control heater 0 and heater 1 in parallel. +//#define HEATERS_PARALLEL + +//=========================================================================== +//================================= Buffers ================================= +//=========================================================================== + +// @section hidden + +// 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, i.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 +#else + #define BLOCK_BUFFER_SIZE 16 // maximize block buffer +#endif + +// @section serial + +// The ASCII buffer for serial input +#define MAX_CMD_SIZE 96 +#define BUFSIZE 4 + +// Transmission to Host Buffer Size +// To save 386 bytes of PROGMEM (and TX_BUFFER_SIZE+3 bytes of RAM) set to 0. +// To buffer a simple "ok" you need 4 bytes. +// For ADVANCED_OK (M105) you need 32 bytes. +// For debug-echo: 128 bytes for the optimal speed. +// Other output doesn't need to be that speedy. +// :[0, 2, 4, 8, 16, 32, 64, 128, 256] +#define TX_BUFFER_SIZE 0 + +// Host Receive Buffer Size +// Without XON/XOFF flow control (see SERIAL_XON_XOFF below) 32 bytes should be enough. +// To use flow control, set this buffer size to at least 1024 bytes. +// :[0, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048] +//#define RX_BUFFER_SIZE 1024 + +#if RX_BUFFER_SIZE >= 1024 + // Enable to have the controller send XON/XOFF control characters to + // the host to signal the RX buffer is becoming full. + //#define SERIAL_XON_XOFF +#endif + +#if ENABLED(SDSUPPORT) + // Enable this option to collect and display the maximum + // RX queue usage after transferring a file to SD. + //#define SERIAL_STATS_MAX_RX_QUEUED + + // Enable this option to collect and display the number + // of dropped bytes after a file transfer to SD. + //#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! +//#define EMERGENCY_PARSER + +// Bad Serial-connections can miss a received command by sending an 'ok' +// Therefore some clients abort after 30 seconds in a timeout. +// Some other clients start sending commands while receiving a 'wait'. +// This "wait" is only sent when the buffer is empty. 1 second is a good value here. +//#define NO_TIMEOUTS 1000 // Milliseconds + +// Some clients will have this feature soon. This could make the NO_TIMEOUTS unnecessary. +//#define ADVANCED_OK + +// @section extras + +/** + * Firmware-based and LCD-controlled retract + * + * Add G10 / G11 commands for automatic firmware-based retract / recover. + * Use M207 and M208 to define parameters for retract / recover. + * + * Use M209 to enable or disable auto-retract. + * With auto-retract enabled, all G1 E moves within the set range + * will be converted to firmware-based retract/recover moves. + * + * Be sure to turn off auto-retract during filament change. + * + * Note that M207 / M208 / M209 settings are saved to EEPROM. + * + */ +//#define FWRETRACT // ONLY PARTIALLY TESTED +#if ENABLED(FWRETRACT) + #define MIN_AUTORETRACT 0.1 // When auto-retract is on, convert E moves of this length and over + #define MAX_AUTORETRACT 10.0 // Upper limit for auto-retract conversion + #define RETRACT_LENGTH 3 // Default retract length (positive mm) + #define RETRACT_LENGTH_SWAP 13 // Default swap retract length (positive mm), for extruder change + #define RETRACT_FEEDRATE 45 // Default feedrate for retracting (mm/s) + #define RETRACT_ZLIFT 0 // Default retract Z-lift + #define RETRACT_RECOVER_LENGTH 0 // Default additional recover length (mm, added to retract length when recovering) + #define RETRACT_RECOVER_LENGTH_SWAP 0 // Default additional swap recover length (mm, added to retract length when recovering from extruder change) + #define RETRACT_RECOVER_FEEDRATE 8 // Default feedrate for recovering from retraction (mm/s) + #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) +#endif + +/** + * Advanced Pause + * Experimental feature for filament change support and for parking the nozzle when paused. + * Adds the GCode M600 for initiating filament change. + * If PARK_HEAD_ON_PAUSE enabled, adds the GCode M125 to pause printing and park the nozzle. + * + * Requires an LCD display. + * This feature is required for the default FILAMENT_RUNOUT_SCRIPT. + */ +//#define ADVANCED_PAUSE_FEATURE +#if ENABLED(ADVANCED_PAUSE_FEATURE) + #define PAUSE_PARK_X_POS 3 // X position of hotend + #define PAUSE_PARK_Y_POS 3 // Y position of hotend + #define PAUSE_PARK_Z_ADD 10 // Z addition of hotend (lift) + #define PAUSE_PARK_XY_FEEDRATE 100 // X and Y axes feedrate in mm/s (also used for delta printers Z axis) + #define PAUSE_PARK_Z_FEEDRATE 5 // Z axis feedrate in mm/s (not used for delta printers) + #define PAUSE_PARK_RETRACT_FEEDRATE 60 // Initial retract feedrate in mm/s + #define PAUSE_PARK_RETRACT_LENGTH 2 // Initial retract in mm + // It is a short retract used immediately after print interrupt before move to filament exchange position + #define FILAMENT_CHANGE_UNLOAD_FEEDRATE 10 // Unload filament feedrate in mm/s - filament unloading can be fast + #define FILAMENT_CHANGE_UNLOAD_LENGTH 100 // Unload filament length from hotend in mm + // Longer length for bowden printers to unload filament from whole bowden tube, + // shorter length for printers without bowden to unload filament from extruder only, + // 0 to disable unloading for manual unloading + #define FILAMENT_CHANGE_LOAD_FEEDRATE 6 // Load filament feedrate in mm/s - filament loading into the bowden tube can be fast + #define FILAMENT_CHANGE_LOAD_LENGTH 0 // Load filament length over hotend in mm + // Longer length for bowden printers to fast load filament into whole bowden tube over the hotend, + // Short or zero length for printers without bowden where loading is not used + #define ADVANCED_PAUSE_EXTRUDE_FEEDRATE 3 // Extrude filament feedrate in mm/s - must be slower than load feedrate + #define ADVANCED_PAUSE_EXTRUDE_LENGTH 50 // Extrude filament length in mm after filament is loaded over the hotend, + // 0 to disable for manual extrusion + // Filament can be extruded repeatedly from the filament exchange menu to fill the hotend, + // or until outcoming filament color is not clear for filament color change + #define PAUSE_PARK_NOZZLE_TIMEOUT 45 // Turn off nozzle if user doesn't change filament within this time limit in seconds + #define FILAMENT_CHANGE_NUMBER_OF_ALERT_BEEPS 5 // Number of alert beeps before printer goes quiet + #define PAUSE_PARK_NO_STEPPER_TIMEOUT // Enable to have stepper motors hold position during filament change + // even if it takes longer than DEFAULT_STEPPER_DEACTIVE_TIME. + //#define PARK_HEAD_ON_PAUSE // Go to filament change position on pause, return to print position on resume + //#define HOME_BEFORE_FILAMENT_CHANGE // Ensure homing has been completed prior to parking for filament change +#endif + +// @section tmc + +/** + * Enable this section if you have TMC26X motor drivers. + * You will need to import the TMC26XStepper library into the Arduino IDE for this + * (https://github.com/trinamic/TMC26XStepper.git) + */ +//#define HAVE_TMCDRIVER + +#if ENABLED(HAVE_TMCDRIVER) + + //#define X_IS_TMC + //#define X2_IS_TMC + //#define Y_IS_TMC + //#define Y2_IS_TMC + //#define Z_IS_TMC + //#define Z2_IS_TMC + //#define E0_IS_TMC + //#define E1_IS_TMC + //#define E2_IS_TMC + //#define E3_IS_TMC + //#define E4_IS_TMC + + #define X_MAX_CURRENT 1000 // in mA + #define X_SENSE_RESISTOR 91 // in mOhms + #define X_MICROSTEPS 16 // number of microsteps + + #define X2_MAX_CURRENT 1000 + #define X2_SENSE_RESISTOR 91 + #define X2_MICROSTEPS 16 + + #define Y_MAX_CURRENT 1000 + #define Y_SENSE_RESISTOR 91 + #define Y_MICROSTEPS 16 + + #define Y2_MAX_CURRENT 1000 + #define Y2_SENSE_RESISTOR 91 + #define Y2_MICROSTEPS 16 + + #define Z_MAX_CURRENT 1000 + #define Z_SENSE_RESISTOR 91 + #define Z_MICROSTEPS 16 + + #define Z2_MAX_CURRENT 1000 + #define Z2_SENSE_RESISTOR 91 + #define Z2_MICROSTEPS 16 + + #define E0_MAX_CURRENT 1000 + #define E0_SENSE_RESISTOR 91 + #define E0_MICROSTEPS 16 + + #define E1_MAX_CURRENT 1000 + #define E1_SENSE_RESISTOR 91 + #define E1_MICROSTEPS 16 + + #define E2_MAX_CURRENT 1000 + #define E2_SENSE_RESISTOR 91 + #define E2_MICROSTEPS 16 + + #define E3_MAX_CURRENT 1000 + #define E3_SENSE_RESISTOR 91 + #define E3_MICROSTEPS 16 + + #define E4_MAX_CURRENT 1000 + #define E4_SENSE_RESISTOR 91 + #define E4_MICROSTEPS 16 + +#endif + +// @section TMC2130 + +/** + * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. + * + * You'll also need the TMC2130Stepper Arduino library + * (https://github.com/teemuatlut/TMC2130Stepper). + * + * To use TMC2130 stepper drivers in SPI mode connect your SPI2130 pins to + * the hardware SPI interface on your board and define the required CS pins + * in your `pins_MYBOARD.h` file. (e.g., RAMPS 1.4 uses AUX3 pins `X_CS_PIN 53`, `Y_CS_PIN 49`, etc.). + */ +//#define HAVE_TMC2130 + +#if ENABLED(HAVE_TMC2130) + + // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY + //#define X_IS_TMC2130 + //#define X2_IS_TMC2130 + //#define Y_IS_TMC2130 + //#define Y2_IS_TMC2130 + //#define Z_IS_TMC2130 + //#define Z2_IS_TMC2130 + //#define E0_IS_TMC2130 + //#define E1_IS_TMC2130 + //#define E2_IS_TMC2130 + //#define E3_IS_TMC2130 + //#define E4_IS_TMC2130 + + /** + * Stepper driver settings + */ + + #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 + #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current + #define INTERPOLATE 1 // Interpolate X/Y/Z_MICROSTEPS to 256 + + #define X_CURRENT 1000 // rms current in mA. Multiply by 1.41 for peak current. + #define X_MICROSTEPS 16 // 0..256 + + #define Y_CURRENT 1000 + #define Y_MICROSTEPS 16 + + #define Z_CURRENT 1000 + #define Z_MICROSTEPS 16 + + //#define X2_CURRENT 1000 + //#define X2_MICROSTEPS 16 + + //#define Y2_CURRENT 1000 + //#define Y2_MICROSTEPS 16 + + //#define Z2_CURRENT 1000 + //#define Z2_MICROSTEPS 16 + + //#define E0_CURRENT 1000 + //#define E0_MICROSTEPS 16 + + //#define E1_CURRENT 1000 + //#define E1_MICROSTEPS 16 + + //#define E2_CURRENT 1000 + //#define E2_MICROSTEPS 16 + + //#define E3_CURRENT 1000 + //#define E3_MICROSTEPS 16 + + //#define E4_CURRENT 1000 + //#define E4_MICROSTEPS 16 + + /** + * Use Trinamic's ultra quiet stepping mode. + * When disabled, Marlin will use spreadCycle stepping mode. + */ + #define STEALTHCHOP + + /** + * Let Marlin automatically control stepper current. + * This is still an experimental feature. + * Increase current every 5s by CURRENT_STEP until stepper temperature prewarn gets triggered, + * then decrease current by CURRENT_STEP until temperature prewarn is cleared. + * Adjusting starts from X/Y/Z/E_CURRENT but will not increase over AUTO_ADJUST_MAX + * 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. + * M906 S1 - Start adjusting current + * M906 S0 - Stop adjusting current + * M911 - Report stepper driver overtemperature pre-warn condition. + * M912 - Clear stepper driver overtemperature pre-warn condition flag. + */ + //#define AUTOMATIC_CURRENT_CONTROL + + #if ENABLED(AUTOMATIC_CURRENT_CONTROL) + #define CURRENT_STEP 50 // [mA] + #define AUTO_ADJUST_MAX 1300 // [mA], 1300mA_rms = 1840mA_peak + #define REPORT_CURRENT_CHANGE + #endif + + /** + * The driver will switch to spreadCycle when stepper speed is over HYBRID_THRESHOLD. + * This mode allows for faster movements at the expense of higher noise levels. + * STEALTHCHOP needs to be enabled. + * M913 X/Y/Z/E to live tune the setting + */ + //#define HYBRID_THRESHOLD + + #define X_HYBRID_THRESHOLD 100 // [mm/s] + #define X2_HYBRID_THRESHOLD 100 + #define Y_HYBRID_THRESHOLD 100 + #define Y2_HYBRID_THRESHOLD 100 + #define Z_HYBRID_THRESHOLD 4 + #define Z2_HYBRID_THRESHOLD 4 + #define E0_HYBRID_THRESHOLD 30 + #define E1_HYBRID_THRESHOLD 30 + #define E2_HYBRID_THRESHOLD 30 + #define E3_HYBRID_THRESHOLD 30 + #define E4_HYBRID_THRESHOLD 30 + + /** + * Use stallGuard2 to sense an obstacle and trigger an endstop. + * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. + * If used along with STEALTHCHOP, the movement will be louder when homing. This is normal. + * + * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. + * Higher values make the system LESS sensitive. + * Lower value make the system MORE sensitive. + * Too low values can lead to false positives, while too high values will collide the axis without triggering. + * It is advised to set X/Y_HOME_BUMP_MM to 0. + * M914 X/Y to live tune the setting + */ + //#define SENSORLESS_HOMING + + #if ENABLED(SENSORLESS_HOMING) + #define X_HOMING_SENSITIVITY 19 + #define Y_HOMING_SENSITIVITY 19 + #endif + + /** + * You can set your own advanced settings by filling in predefined functions. + * A list of available functions can be found on the library github page + * https://github.com/teemuatlut/TMC2130Stepper + * + * Example: + * #define TMC2130_ADV() { \ + * stepperX.diag0_temp_prewarn(1); \ + * stepperX.interpolate(0); \ + * } + */ + #define TMC2130_ADV() { } + +#endif // HAVE_TMC2130 + +// @section L6470 + +/** + * Enable this section if you have L6470 motor drivers. + * You need to import the L6470 library into the Arduino IDE for this. + * (https://github.com/ameyer/Arduino-L6470) + */ + +//#define HAVE_L6470DRIVER +#if ENABLED(HAVE_L6470DRIVER) + + //#define X_IS_L6470 + //#define X2_IS_L6470 + //#define Y_IS_L6470 + //#define Y2_IS_L6470 + //#define Z_IS_L6470 + //#define Z2_IS_L6470 + //#define E0_IS_L6470 + //#define E1_IS_L6470 + //#define E2_IS_L6470 + //#define E3_IS_L6470 + //#define E4_IS_L6470 + + #define X_MICROSTEPS 16 // number of microsteps + #define X_K_VAL 50 // 0 - 255, Higher values, are higher power. Be careful not to go too high + #define X_OVERCURRENT 2000 // maxc current in mA. If the current goes over this value, the driver will switch off + #define X_STALLCURRENT 1500 // current in mA where the driver will detect a stall + + #define X2_MICROSTEPS 16 + #define X2_K_VAL 50 + #define X2_OVERCURRENT 2000 + #define X2_STALLCURRENT 1500 + + #define Y_MICROSTEPS 16 + #define Y_K_VAL 50 + #define Y_OVERCURRENT 2000 + #define Y_STALLCURRENT 1500 + + #define Y2_MICROSTEPS 16 + #define Y2_K_VAL 50 + #define Y2_OVERCURRENT 2000 + #define Y2_STALLCURRENT 1500 + + #define Z_MICROSTEPS 16 + #define Z_K_VAL 50 + #define Z_OVERCURRENT 2000 + #define Z_STALLCURRENT 1500 + + #define Z2_MICROSTEPS 16 + #define Z2_K_VAL 50 + #define Z2_OVERCURRENT 2000 + #define Z2_STALLCURRENT 1500 + + #define E0_MICROSTEPS 16 + #define E0_K_VAL 50 + #define E0_OVERCURRENT 2000 + #define E0_STALLCURRENT 1500 + + #define E1_MICROSTEPS 16 + #define E1_K_VAL 50 + #define E1_OVERCURRENT 2000 + #define E1_STALLCURRENT 1500 + + #define E2_MICROSTEPS 16 + #define E2_K_VAL 50 + #define E2_OVERCURRENT 2000 + #define E2_STALLCURRENT 1500 + + #define E3_MICROSTEPS 16 + #define E3_K_VAL 50 + #define E3_OVERCURRENT 2000 + #define E3_STALLCURRENT 1500 + + #define E4_MICROSTEPS 16 + #define E4_K_VAL 50 + #define E4_OVERCURRENT 2000 + #define E4_STALLCURRENT 1500 + +#endif + +/** + * TWI/I2C BUS + * + * This feature is an EXPERIMENTAL feature so it shall not be used on production + * machines. Enabling this will allow you to send and receive I2C data from slave + * devices on the bus. + * + * ; Example #1 + * ; This macro send the string "Marlin" to the slave device with address 0x63 (99) + * ; It uses multiple M260 commands with one B arg + * M260 A99 ; Target slave address + * M260 B77 ; M + * M260 B97 ; a + * M260 B114 ; r + * M260 B108 ; l + * M260 B105 ; i + * M260 B110 ; n + * M260 S1 ; Send the current buffer + * + * ; Example #2 + * ; Request 6 bytes from slave device with address 0x63 (99) + * M261 A99 B5 + * + * ; Example #3 + * ; Example serial output of a M261 request + * echo:i2c-reply: from:99 bytes:5 data:hello + */ + +// @section i2cbus + +//#define EXPERIMENTAL_I2CBUS +#define I2C_SLAVE_ADDRESS 0 // Set a value from 8 to 127 to act as a slave + +// @section extras + +/** + * Spindle & Laser control + * + * Add the M3, M4, and M5 commands to turn the spindle/laser on and off, and + * to set spindle speed, spindle direction, and laser power. + * + * SuperPid is a router/spindle speed controller used in the CNC milling community. + * Marlin can be used to turn the spindle on and off. It can also be used to set + * the spindle speed from 5,000 to 30,000 RPM. + * + * 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. + */ +//#define SPINDLE_LASER_ENABLE +#if ENABLED(SPINDLE_LASER_ENABLE) + + #define SPINDLE_LASER_ENABLE_INVERT false // set to "true" if the on/off function is reversed + #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 // delay in milliseconds to allow the spindle/laser to come up to speed/power + #define SPINDLE_LASER_POWERDOWN_DELAY 5000 // delay in milliseconds to allow the spindle to stop + #define SPINDLE_DIR_CHANGE true // set to true if your spindle controller supports changing spindle direction + #define SPINDLE_INVERT_DIR false + #define SPINDLE_STOP_ON_DIR_CHANGE true // set to true if Marlin should stop the spindle before changing rotation direction + + /** + * The M3 & M4 commands use the following equation to convert PWM duty cycle to speed/power + * + * SPEED/POWER = PWM duty cycle * SPEED_POWER_SLOPE + SPEED_POWER_INTERCEPT + * where PWM duty cycle varies from 0 to 255 + * + * set the following for your controller (ALL MUST BE SET) + */ + + #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_SLOPE 0.3922 + //#define SPEED_POWER_INTERCEPT 0 + //#define SPEED_POWER_MIN 10 + //#define SPEED_POWER_MAX 100 // 0-100% +#endif + +/** + * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins + */ +//#define PINS_DEBUGGING + +/** + * Auto-report temperatures with M155 S + */ +#define AUTO_REPORT_TEMPERATURES + +/** + * Include capabilities in M115 output + */ +#define EXTENDED_CAPABILITIES_REPORT + +/** + * Volumetric extrusion default state + * 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. + */ +//#define VOLUMETRIC_DEFAULT_ON + +/** + * Enable this option for a leaner build of Marlin that removes all + * workspace offsets, simplifying coordinate transformations, leveling, etc. + * + * - M206 and M428 are disabled. + * - G92 will revert to its behavior from Marlin 1.0. + */ +//#define NO_WORKSPACE_OFFSETS + +/** + * 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. + * + * For clients that use a fixed-width font (like OctoPrint), leave this set to 1.0. + * Otherwise, adjust according to your client and font. + */ +#define PROPORTIONAL_FONT_RATIO 1.0 + +/** + * Spend 28 bytes of SRAM to optimize the GCode parser + */ +#define FASTER_GCODE_PARSER + +/** + * User-defined menu items that execute custom GCode + */ +//#define CUSTOM_USER_MENUS +#if ENABLED(CUSTOM_USER_MENUS) + #define USER_SCRIPT_DONE "M117 User Script Done" + #define USER_SCRIPT_AUDIBLE_FEEDBACK + //#define USER_SCRIPT_RETURN // Return to status screen after a script + + #define USER_DESC_1 "Home & UBL Info" + #define USER_GCODE_1 "G28\nG29 W" + + #define USER_DESC_2 "Preheat for PLA" + #define USER_GCODE_2 "M140 S" STRINGIFY(PREHEAT_1_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND) + + #define USER_DESC_3 "Preheat for ABS" + #define USER_GCODE_3 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND) + + #define USER_DESC_4 "Heat Bed/Home/Level" + #define USER_GCODE_4 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nG28\nG29" + + //#define USER_DESC_5 "Home & Info" + //#define USER_GCODE_5 "G28\nM503" +#endif + +/** + * Specify an action command to send to the host when the printer is killed. + * Will be sent in the form '//action:ACTION_ON_KILL', e.g. '//action:poweroff'. + * The host must be configured to handle the action command. + */ +//#define ACTION_ON_KILL "poweroff" + +//=========================================================================== +//====================== I2C Position Encoder Settings ====================== +//=========================================================================== + +/** + * I2C position encoders for closed loop control. + * Developed by Chris Barr at Aus3D. + * + * Wiki: http://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/ + * + * Reilabuild encoders have been modified to improve reliability. + */ + +//#define I2C_POSITION_ENCODERS +#if ENABLED(I2C_POSITION_ENCODERS) + + #define I2CPE_ENCODER_CNT 1 // The number of encoders installed; max of 5 + // encoders supported currently. + + #define I2CPE_ENC_1_ADDR I2CPE_PRESET_ADDR_X // I2C address of the encoder. 30-200. + #define I2CPE_ENC_1_AXIS X_AXIS // Axis the encoder module is installed on. _AXIS. + #define I2CPE_ENC_1_TYPE I2CPE_ENC_TYPE_LINEAR // Type of encoder: I2CPE_ENC_TYPE_LINEAR -or- + // I2CPE_ENC_TYPE_ROTARY. + #define I2CPE_ENC_1_TICKS_UNIT 2048 // 1024 for magnetic strips with 2mm poles; 2048 for + // 1mm poles. For linear encoders this is ticks / mm, + // for rotary encoders this is ticks / revolution. + //#define I2CPE_ENC_1_TICKS_REV (16 * 200) // Only needed for rotary encoders; number of stepper + // steps per full revolution (motor steps/rev * microstepping) + //#define I2CPE_ENC_1_INVERT // Invert the direction of axis travel. + #define I2CPE_ENC_1_EC_METHOD I2CPE_ECM_NONE // Type of error error correction. + #define I2CPE_ENC_1_EC_THRESH 0.10 // Threshold size for error (in mm) above which the + // printer will attempt to correct the error; errors + // smaller than this are ignored to minimize effects of + // measurement noise / latency (filter). + + #define I2CPE_ENC_2_ADDR I2CPE_PRESET_ADDR_Y // Same as above, but for encoder 2. + #define I2CPE_ENC_2_AXIS Y_AXIS + #define I2CPE_ENC_2_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_ENC_2_TICKS_UNIT 2048 + //#define I2CPE_ENC_2_TICKS_REV (16 * 200) + //#define I2CPE_ENC_2_INVERT + #define I2CPE_ENC_2_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_ENC_2_EC_THRESH 0.10 + + #define I2CPE_ENC_3_ADDR I2CPE_PRESET_ADDR_Z // Encoder 3. Add additional configuration options + #define I2CPE_ENC_3_AXIS Z_AXIS // as above, or use defaults below. + + #define I2CPE_ENC_4_ADDR I2CPE_PRESET_ADDR_E // Encoder 4. + #define I2CPE_ENC_4_AXIS E_AXIS + + #define I2CPE_ENC_5_ADDR 34 // Encoder 5. + #define I2CPE_ENC_5_AXIS E_AXIS + + // Default settings for encoders which are enabled, but without settings configured above. + #define I2CPE_DEF_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_DEF_ENC_TICKS_UNIT 2048 + #define I2CPE_DEF_TICKS_REV (16 * 200) + #define I2CPE_DEF_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_DEF_EC_THRESH 0.1 + + //#define I2CPE_ERR_THRESH_ABORT 100.0 // Threshold size for error (in mm) error on any given + // axis after which the printer will abort. Comment out to + // disable abort behaviour. + + #define I2CPE_TIME_TRUSTED 10000 // After an encoder fault, there must be no further fault + // for this amount of time (in ms) before the encoder + // is trusted again. + + /** + * Position is checked every time a new command is executed from the buffer but during long moves, + * this setting determines the minimum update time between checks. A value of 100 works well with + * error rolling average when attempting to correct only for skips and not for vibration. + */ + #define I2CPE_MIN_UPD_TIME_MS 100 // Minimum time in miliseconds between encoder checks. + + // Use a rolling average to identify persistant errors that indicate skips, as opposed to vibration and noise. + #define I2CPE_ERR_ROLLING_AVERAGE + +#endif // I2C_POSITION_ENCODERS + +/** + * MAX7219 Debug Matrix + * + * Add support for a low-cost 8x8 LED Matrix based on the Max7219 chip, which can be used as a status + * display. Requires 3 signal wires. Some useful debug options are included to demonstrate its usage. + * + * Fully assembled MAX7219 boards can be found on the internet for under $2(US). + * For example, see https://www.ebay.com/sch/i.html?_nkw=332349290049 + */ +//#define MAX7219_DEBUG +#if ENABLED(MAX7219_DEBUG) + #define MAX7219_CLK_PIN 64 // 77 on Re-ARM // Configuration of the 3 pins to control the display + #define MAX7219_DIN_PIN 57 // 78 on Re-ARM + #define MAX7219_LOAD_PIN 44 // 79 on Re-ARM + + /** + * Sample debug features + * If you add more debug displays, be careful to avoid conflicts! + */ + #define MAX7219_DEBUG_PRINTER_ALIVE // Blink corner LED of 8x8 matrix to show that the firmware is functioning + #define MAX7219_DEBUG_STEPPER_HEAD 3 // Show the stepper queue head position on this and the next LED matrix row + #define MAX7219_DEBUG_STEPPER_TAIL 5 // Show the stepper queue tail position on this and the next LED matrix row + + #define MAX7219_DEBUG_STEPPER_QUEUE 0 // Show the current stepper queue depth on this and the next LED matrix row + // If you experience stuttering, reboots, etc. this option can reveal how + // tweaks made to the configuration are affecting the printer in real-time. +#endif + +#endif // CONFIGURATION_ADV_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/delta/kossel_xl/README.md b/trunk/Arduino/Marlin_1.1.6/example_configurations/delta/kossel_xl/README.md new file mode 100644 index 00000000..1cabcdb3 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/delta/kossel_xl/README.md @@ -0,0 +1,21 @@ +# Configuration for Kossel k800 XL +This example configuration is for a Kossel XL with a printable bed diameter of 280mm and a height of 380mm. It also has the auto bed leveling probe (with an endstop switch) and the heated bed activated. + +## Configuration +You might need (or want) to edit at least the following settings in `Configuration.h`: +* `MANUAL_Z_HOME_POS` - The available height of your printing space. Auto Bed Leveling makes it less important to have the exact value. +* `DELTA_PRINTABLE_RADIUS` - The printable radius is how far from the center the nozzle can reach. +* `DEFAULT_AXIS_STEPS_PER_UNIT` - Steps-per-millimeter for the delta steppers, and for the extruder [to optimize the amount of filament flow](http://zennmaster.com/makingstuff/reprap-101-calibrating-your-extruder-part-1-e-steps). + +### Fine tuning +* Increase `DELTA_RADIUS` if the model comes out convex (with a bulge in the middle) +* Increase `DELTA_DIAGONAL_ROD` if the model comes out larger than expected + +### [http://reprap.org/wiki/PID_Tuning](PID Tuning) +* `DEFAULT_Kp` - The proportional term +* `DEFAULT_Ki` - The integral term +* `DEFAULT_Kd` - The derivative term + +### PSU Options +* The power supply is configured to 2 (to use a relay to switch 12V on and off) +* It is configured to be off by default diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/gCreate/gMax1.5+/Configuration.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/gCreate/gMax1.5+/Configuration.h new file mode 100644 index 00000000..3fe6e47f --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/gCreate/gMax1.5+/Configuration.h @@ -0,0 +1,1714 @@ +/** + * 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 . + * + */ + +/** + * Configuration.h + * + * Basic settings such as: + * + * - Type of electronics + * - Type of temperature sensor + * - Printer geometry + * - Endstop configuration + * - LCD controller + * - Extra features + * + * Advanced settings can be found in Configuration_adv.h + * + */ +#ifndef CONFIGURATION_H +#define CONFIGURATION_H +#define CONFIGURATION_H_VERSION 010100 + +//=========================================================================== +//============================= Getting Started ============================= +//=========================================================================== + +/** + * Here are some standard links for getting your machine calibrated: + * + * http://reprap.org/wiki/Calibration + * http://youtu.be/wAL9d7FgInk + * http://calculator.josefprusa.cz + * http://reprap.org/wiki/Triffid_Hunter%27s_Calibration_Guide + * http://www.thingiverse.com/thing:5573 + * https://sites.google.com/site/repraplogphase/calibration-of-your-reprap + * http://www.thingiverse.com/thing:298812 + */ + +//=========================================================================== +//============================= DELTA Printer =============================== +//=========================================================================== +// For a Delta printer start with one of the configuration files in the +// example_configurations/delta directory and customize for your machine. +// + +//=========================================================================== +//============================= SCARA Printer =============================== +//=========================================================================== +// For a SCARA printer start with the configuration files in +// example_configurations/SCARA and customize for your machine. +// + +// @section info + +// User-specified version info of this build to display in [Pronterface, etc] terminal window during +// startup. Implementation of an idea by Prof Braino to inform user that any changes made to this +// build by the user have been successfully uploaded into firmware. +#define STRING_CONFIG_H_AUTHOR "(none, default config)" // Who made the changes. +#define SHOW_BOOTSCREEN +#define STRING_SPLASH_LINE1 SHORT_BUILD_VERSION // will be shown during bootup in line 1 +#define STRING_SPLASH_LINE2 WEBSITE_URL // will be shown during bootup in line 2 + +// +// *** VENDORS PLEASE READ ***************************************************** +// +// Marlin now allow you to have a vendor boot image to be displayed on machine +// start. When SHOW_CUSTOM_BOOTSCREEN is defined Marlin will first show your +// custom boot image and then the default Marlin boot image is shown. +// +// We suggest for you to take advantage of this new feature and keep the Marlin +// boot image unmodified. For an example have a look at the bq Hephestos 2 +// example configuration folder. +// +#define SHOW_CUSTOM_BOOTSCREEN +// @section machine + +/** + * Select which serial port on the board will be used for communication with the host. + * This allows the connection of wireless adapters (for instance) to non-default port pins. + * Serial port 0 is always used by the Arduino bootloader regardless of this setting. + * + * :[0, 1, 2, 3, 4, 5, 6, 7] + */ +#define SERIAL_PORT 0 + +/** + * This setting determines the communication speed of the printer. + * + * 250000 works in most cases, but you might try a lower speed if + * you commonly experience drop-outs during host printing. + * You may try up to 1000000 to speed up SD file transfer. + * + * :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000] + */ +#define BAUDRATE 250000 + +// Enable the Bluetooth serial interface on AT90USB devices +//#define BLUETOOTH + +// The following define selects which electronics board you have. +// Please choose the name from boards.h that matches your setup +#ifndef MOTHERBOARD + //#define MOTHERBOARD BOARD_RAMPS_14_EEF + #define MOTHERBOARD BOARD_RAMPS_14_EFB // gMax users please note: This is a Roxy modification. I print on glass and + // I use Marlin to control the bed's temperature. So, if you have a single nozzle + // machine, this will work fine for you. You just set the + // #define TEMP_SENSOR_BED 75 to 0 down below so Marlin doesn't mess with the bed + // temp. +#endif + +// Optional custom name for your RepStrap or other custom machine +// Displayed in the LCD "Ready" message +#define CUSTOM_MACHINE_NAME "gMax" + +// Define this to set a unique identifier for this printer, (Used by some programs to differentiate between machines) +// You can use an online service to generate a random UUID. (eg http://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] +#define EXTRUDERS 1 + +// For Cyclops or any "multi-extruder" that shares a single nozzle. +//#define SINGLENOZZLE + +/** + * Průša MK2 Single Nozzle Multi-Material Multiplexer, and variants. + * + * This device allows one stepper driver on a control board to drive + * two to eight stepper motors, one at a time, in a manner suitable + * for extruders. + * + * This option only allows the multiplexer to switch on tool-change. + * Additional options to configure custom E moves are pending. + */ +//#define MK2_MULTIPLEXER +#if ENABLED(MK2_MULTIPLEXER) + // Override the default DIO selector pins here, if needed. + // Some pins files may provide defaults for these pins. + //#define E_MUX0_PIN 40 // Always Required + //#define E_MUX1_PIN 42 // Needed for 3 to 8 steppers + //#define E_MUX2_PIN 44 // Needed for 5 to 8 steppers +#endif + +// A dual extruder that uses a single stepper motor +//#define SWITCHING_EXTRUDER +#if ENABLED(SWITCHING_EXTRUDER) + #define SWITCHING_EXTRUDER_SERVO_NR 0 + #define SWITCHING_EXTRUDER_SERVO_ANGLES { 0, 90 } // Angles for E0, E1[, E2, E3] + #if EXTRUDERS > 3 + #define SWITCHING_EXTRUDER_E23_SERVO_NR 1 + #endif +#endif + +// A dual-nozzle that uses a servomotor to raise/lower one of the nozzles +//#define SWITCHING_NOZZLE +#if ENABLED(SWITCHING_NOZZLE) + #define SWITCHING_NOZZLE_SERVO_NR 0 + #define SWITCHING_NOZZLE_SERVO_ANGLES { 0, 90 } // Angles for E0, E1 + //#define HOTEND_OFFSET_Z { 0.0, 0.0 } +#endif + +/** + * Two separate X-carriages with extruders that connect to a moving part + * via a magnetic docking mechanism. Requires SOL1_PIN and SOL2_PIN. + */ +//#define PARKING_EXTRUDER +#if ENABLED(PARKING_EXTRUDER) + #define PARKING_EXTRUDER_SOLENOIDS_INVERT // If enabled, the solenoid is NOT magnetized with applied voltage + #define PARKING_EXTRUDER_SOLENOIDS_PINS_ACTIVE LOW // LOW or HIGH pin signal energizes the coil + #define PARKING_EXTRUDER_SOLENOIDS_DELAY 250 // Delay (ms) for magnetic field. No delay if 0 or not defined. + #define PARKING_EXTRUDER_PARKING_X { -78, 184 } // X positions for parking the extruders + #define PARKING_EXTRUDER_GRAB_DISTANCE 1 // mm to move beyond the parking point to grab the extruder + #define PARKING_EXTRUDER_SECURITY_RAISE 5 // Z-raise before parking + #define HOTEND_OFFSET_Z { 0.0, 1.3 } // Z-offsets of the two hotends. The first must be 0. +#endif + +/** + * "Mixing Extruder" + * - Adds a new code, M165, to set the current mix factors. + * - Extends the stepping routines to move multiple steppers in proportion to the mix. + * - Optional support for Repetier Firmware M163, M164, and virtual extruder. + * - This implementation supports only a single extruder. + * - Enable DIRECT_MIXING_IN_G1 for Pia Taubert's reference implementation + */ +//#define MIXING_EXTRUDER +#if ENABLED(MIXING_EXTRUDER) + #define MIXING_STEPPERS 2 // Number of steppers in your mixing extruder + #define MIXING_VIRTUAL_TOOLS 16 // Use the Virtual Tool method with M163 and M164 + //#define DIRECT_MIXING_IN_G1 // Allow ABCDHI mix factors in G1 movement commands +#endif + +// Offset of the extruders (uncomment if using more than one and relying on firmware to position when changing). +// The offset has to be X=0, Y=0 for the extruder 0 hotend (default extruder). +// For the other hotends it is their distance from the extruder 0 hotend. +//#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis +//#define HOTEND_OFFSET_Y {0.0, 5.00} // (in mm) for each extruder, offset of the hotend on the Y axis + +// @section machine + +/** + * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN + * + * 0 = No Power Switch + * 1 = ATX + * 2 = X-Box 360 203Watts (the blue wire connected to PS_ON and the red wire to VCC) + * + * :{ 0:'No power switch', 1:'ATX', 2:'X-Box 360' } + */ +#define POWER_SUPPLY 0 + +#if POWER_SUPPLY > 0 + // Enable this option to leave the PSU off at startup. + // Power to steppers and heaters will need to be turned on with M80. + //#define PS_DEFAULT_OFF +#endif + +// @section temperature + +//=========================================================================== +//============================= Thermal Settings ============================ +//=========================================================================== + +/** + * --NORMAL IS 4.7kohm PULLUP!-- 1kohm pullup can be used on hotend sensor, using correct resistor and table + * + * Temperature sensors available: + * + * -3 : thermocouple with MAX31855 (only for sensor 0) + * -2 : thermocouple with MAX6675 (only for sensor 0) + * -1 : thermocouple with AD595 + * 0 : not used + * 1 : 100k thermistor - best choice for EPCOS 100k (4.7k pullup) + * 2 : 200k thermistor - ATC Semitec 204GT-2 (4.7k pullup) + * 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 (Used in ParCan & J-Head) (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) + * 71 : 100k Honeywell thermistor 135-104LAF-J01 (4.7k pullup) + * 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) + * 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" + * 20 : the PT100 circuit found in the Ultimainboard V2.x + * 60 : 100k Maker's Tool Works Kapton Bed Thermistor beta=3950 + * 66 : 4.7M High Temperature thermistor from Dyze Design + * 70 : the 100K thermistor found in the bq Hephestos 2 + * 75 : 100k Generic Silicon Heat Pad with NTC 100K MGB18-104F39050L32 thermistor + * + * 1k ohm pullup tables - This is atypical, and requires changing out the 4.7k pullup for 1k. + * (but gives greater accuracy and more stable PID) + * 51 : 100k thermistor - EPCOS (1k pullup) + * 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 + * 1010 : Pt1000 with 1k pullup (non standard) + * 147 : Pt100 with 4k7 pullup + * 110 : Pt100 with 1k pullup (non standard) + * + * Use these for Testing or Development purposes. NEVER for production machine. + * 998 : Dummy Table that ALWAYS reads 25°C or the temperature defined below. + * 999 : Dummy Table that ALWAYS reads 100°C or the temperature defined below. + * + * :{ '0': "Not used", '1':"100k / 4.7k - EPCOS", '2':"200k / 4.7k - ATC Semitec 204GT-2", '3':"Mendel-parts / 4.7k", '4':"10k !! do not use for a hotend. Bad resolution at high temp. !!", '5':"100K / 4.7k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '6':"100k / 4.7k EPCOS - Not as accurate as Table 1", '7':"100k / 4.7k Honeywell 135-104LAG-J01", '8':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT", '9':"100k / 4.7k GE Sensing AL03006-58.2K-97-G1", '10':"100k / 4.7k RS 198-961", '11':"100k / 4.7k beta 3950 1%", '12':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT (calibrated for Makibox hot bed)", '13':"100k Hisens 3950 1% up to 300°C for hotend 'Simple ONE ' & hotend 'All In ONE'", '20':"PT100 (Ultimainboard V2.x)", '51':"100k / 1k - EPCOS", '52':"200k / 1k - ATC Semitec 204GT-2", '55':"100k / 1k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '60':"100k Maker's Tool Works Kapton Bed Thermistor beta=3950", '66':"Dyze Design 4.7M High Temperature thermistor", '70':"the 100K thermistor found in the bq Hephestos 2", '71':"100k / 4.7k Honeywell 135-104LAF-J01", '147':"Pt100 / 4.7k", '1047':"Pt1000 / 4.7k", '110':"Pt100 / 1k (non-standard)", '1010':"Pt1000 / 1k (non standard)", '-3':"Thermocouple + MAX31855 (only for sensor 0)", '-2':"Thermocouple + MAX6675 (only for sensor 0)", '-1':"Thermocouple + AD595",'998':"Dummy 1", '999':"Dummy 2" } + */ +#define TEMP_SENSOR_0 5 +#define TEMP_SENSOR_1 0 +#define TEMP_SENSOR_2 0 +#define TEMP_SENSOR_3 0 +#define TEMP_SENSOR_4 0 +#define TEMP_SENSOR_BED 75 // gMax-1.5+ users please note: This is a Roxy modification to the printer. I want + // to print on glass. And I'm using a 400mm x 400mm silicon heat pad powered through + // a Fortek SSR to do it. If you are using an unaltered gCreate machine, this needs + // to be set to 0 + +// Dummy thermistor constant temperature readings, for use with 998 and 999 +#define DUMMY_THERMISTOR_998_VALUE 25 +#define DUMMY_THERMISTOR_999_VALUE 100 + +// 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 +#define MAX_REDUNDANT_TEMP_SENSOR_DIFF 10 + +// Extruder temperature must be close to target for this long before M109 returns success +#define TEMP_RESIDENCY_TIME 16 // (seconds) +#define TEMP_HYSTERESIS 12 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_WINDOW 5 // (degC) Window around target to start the residency timer x degC early. + +// Bed temperature must be close to target for this long before M190 returns success +#define TEMP_BED_RESIDENCY_TIME 10 // (seconds) +#define TEMP_BED_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_BED_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// The minimal temperature defines the temperature below which the heater will not be enabled It is used +// to check that the wiring to the thermistor is not broken. +// Otherwise this would lead to the heater being powered on all the time. +#define HEATER_0_MINTEMP 5 +#define HEATER_1_MINTEMP 5 +#define HEATER_2_MINTEMP 5 +#define HEATER_3_MINTEMP 5 +#define HEATER_4_MINTEMP 5 +#define BED_MINTEMP 5 + +// When temperature exceeds max temp, your heater will be switched off. +// This feature exists to protect your hotend from overheating accidentally, but *NOT* from thermistor short/failure! +// You should use MINTEMP for thermistor short/failure protection. +#define HEATER_0_MAXTEMP 245 +#define HEATER_1_MAXTEMP 245 +#define HEATER_2_MAXTEMP 245 +#define HEATER_3_MAXTEMP 245 +#define HEATER_4_MAXTEMP 245 +#define BED_MAXTEMP 115 + +//=========================================================================== +//============================= PID Settings ================================ +//=========================================================================== +// PID Tuning Guide here: http://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 +#if ENABLED(PIDTEMP) + //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. + //#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. + #define K1 0.95 //smoothing factor within the PID + + // If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it + + // gMax J-Head + #define DEFAULT_Kp 15.35 + #define DEFAULT_Ki 0.85 + #define DEFAULT_Kd 69.45 + + // 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 + +#endif // PIDTEMP + +//=========================================================================== +//============================= PID > Bed Temperature Control =============== +//=========================================================================== +// Select PID or bang-bang with PIDTEMPBED. If bang-bang, BED_LIMIT_SWITCHING will enable hysteresis +// +// Uncomment this to enable PID on the bed. It uses the same frequency PWM as the extruder. +// If your PID_dT is the default, and correct for your hardware/configuration, that means 7.689Hz, +// which is fine for driving a square wave into a resistive load and does not significantly impact you FET heating. +// This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W heater. +// If your configuration is significantly different than this and you don't understand the issues involved, you probably +// shouldn't use bed PID until someone else verifies your hardware works. +// If this is enabled, find your own PID constants below. +#define PIDTEMPBED + +//#define BED_LIMIT_SWITCHING + +// This sets the max power delivered to the bed, and replaces the HEATER_BED_DUTY_CYCLE_DIVIDER option. +// all forms of bed control obey this (PID, bang-bang, bang-bang with hysteresis) +// setting this to anything other than 255 enables a form of PWM to the bed just like HEATER_BED_DUTY_CYCLE_DIVIDER did, +// so you shouldn't use it unless you are OK with PWM on your bed. (see the comment on enabling PIDTEMPBED) +#define MAX_BED_POWER 255 // limits duty cycle to bed; 255=full current + +#if ENABLED(PIDTEMPBED) + + //#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) + #define DEFAULT_bedKp 135.44 + #define DEFAULT_bedKi 24.60 + #define DEFAULT_bedKd 186.40 + + //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 + +// @section extruder + +// This option prevents extrusion if the temperature is below EXTRUDE_MINTEMP. +// It also enables the M302 command to set the minimum extrusion temperature +// or to allow moving the extruder regardless of the hotend temperature. +// *** IT IS HIGHLY RECOMMENDED TO LEAVE THIS OPTION ENABLED! *** +#define PREVENT_COLD_EXTRUSION +#define EXTRUDE_MINTEMP 170 + +// This option prevents a single extrusion longer than EXTRUDE_MAXLENGTH. +// Note that for Bowden Extruders a too-small value here may prevent loading. +#define PREVENT_LENGTHY_EXTRUDE +#define EXTRUDE_MAXLENGTH 200 + +//=========================================================================== +//======================== Thermal Runaway Protection ======================= +//=========================================================================== + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * If you get "Thermal Runaway" or "Heating failed" errors the + * details can be tuned in Configuration_adv.h + */ + +#define THERMAL_PROTECTION_HOTENDS // Enable thermal protection for all extruders +#define THERMAL_PROTECTION_BED // Enable thermal protection for the heated bed + +//=========================================================================== +//============================= Mechanical Settings ========================= +//=========================================================================== + +// @section machine + +// Uncomment one of these options to enable CoreXY, CoreXZ, or CoreYZ kinematics +// either in the usual order or reversed +//#define COREXY +//#define COREXZ +//#define COREYZ +//#define COREYX +//#define COREZX +//#define COREZY + +//=========================================================================== +//============================== Endstop Settings =========================== +//=========================================================================== + +// @section homing + +// Specify here all the endstop connectors that are connected to any endstop or probe. +// Almost all printers will be using one per axis. Probes will use one or more of the +// extra connectors. Leave undefined any used for non-endstop and non-probe purposes. +#define USE_XMIN_PLUG +//#define USE_YMIN_PLUG +#define USE_ZMIN_PLUG +//#define USE_XMAX_PLUG +#define USE_YMAX_PLUG +//#define USE_ZMAX_PLUG + +// coarse Endstop Settings +//#define ENDSTOPPULLUPS // Comment this out (using // at the start of the line) to disable the endstop pullup resistors + +#if DISABLED(ENDSTOPPULLUPS) + // fine endstop settings: Individual pullups. will be ignored if ENDSTOPPULLUPS is defined + //#define ENDSTOPPULLUP_XMAX + //#define ENDSTOPPULLUP_YMAX + //#define ENDSTOPPULLUP_ZMAX + //#define ENDSTOPPULLUP_XMIN + //#define ENDSTOPPULLUP_YMIN + //#define ENDSTOPPULLUP_ZMIN + //#define ENDSTOPPULLUP_ZMIN_PROBE +#endif + +// Mechanical endstop with COM to ground and NC to Signal uses "false" here (most common setup). +#define X_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Y_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MIN_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define X_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Y_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MIN_PROBE_ENDSTOP_INVERTING false // set to true to invert the logic of the probe. + +// Enable this feature if all enabled endstop pins are interrupt-capable. +// This will remove the need to poll the interrupt pins, saving many CPU cycles. +#define ENDSTOP_INTERRUPTS_FEATURE + +//============================================================================= +//============================== Movement Settings ============================ +//============================================================================= +// @section motion + +/** + * Default Settings + * + * These settings can be reset by M502 + * + * Note that if EEPROM is enabled, saved values will override these. + */ + +/** + * With this option each E stepper can have its own factors for the + * following movement settings. If fewer factors are given than the + * total number of extruders, the last value applies to the rest. + */ +//#define DISTINCT_E_FACTORS + +/** + * Default Axis Steps Per Unit (steps/mm) + * Override with M92 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_AXIS_STEPS_PER_UNIT { 80, 80, 400, 96 } + +/** + * Default Max Feed Rate (mm/s) + * Override with M203 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_FEEDRATE { 500, 500, 25, 25 } + +/** + * Default Max Acceleration (change/s) change = mm/s + * (Maximum start speed for accelerated moves) + * Override with M201 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_ACCELERATION { 800, 800, 700, 10000 } + +/** + * Default Acceleration (change/s) change = mm/s + * Override with M204 + * + * M204 P Acceleration + * M204 R Retract Acceleration + * M204 T Travel Acceleration + */ +#define DEFAULT_ACCELERATION 500 // X, Y, Z and E acceleration for printing moves +#define DEFAULT_RETRACT_ACCELERATION 400 // E acceleration for retracts +#define DEFAULT_TRAVEL_ACCELERATION 400 // X, Y, Z acceleration for travel (non printing) moves + +/** + * Default Jerk (mm/s) + * Override with M205 X Y Z E + * + * "Jerk" specifies the minimum speed change that requires acceleration. + * When changing speed and direction, if the difference is less than the + * value set here, it may happen instantaneously. + */ +#define DEFAULT_XJERK 17.0 +#define DEFAULT_YJERK 17.0 +#define DEFAULT_ZJERK 1.0 +#define DEFAULT_EJERK 4.0 + +//=========================================================================== +//============================= Z Probe Options ============================= +//=========================================================================== +// @section probes + +// +// See http://marlinfw.org/configuration/probes.html +// + +/** + * Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + * + * Enable this option for a probe connected to the Z Min endstop pin. + */ +#define Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + +/** + * Z_MIN_PROBE_ENDSTOP + * + * Enable this option for a probe connected to any pin except Z-Min. + * (By default Marlin assumes the Z-Max endstop pin.) + * To use a custom Z Probe pin, set Z_MIN_PROBE_PIN below. + * + * - The simplest option is to use a free endstop connector. + * - Use 5V for powered (usually inductive) sensors. + * + * - RAMPS 1.3/1.4 boards may use the 5V, GND, and Aux4->D32 pin: + * - For simple switches connect... + * - normally-closed switches to GND and D32. + * - normally-open switches to 5V and D32. + * + * WARNING: Setting the wrong pin may have unexpected and potentially + * disastrous consequences. Use with caution and do your homework. + * + */ +//#define Z_MIN_PROBE_ENDSTOP + +/** + * Probe Type + * + * Allen Key Probes, Servo Probes, Z-Sled Probes, FIX_MOUNTED_PROBE, etc. + * Activate one of these to use Auto Bed Leveling below. + */ + +/** + * The "Manual Probe" provides a means to do "Auto" Bed Leveling without a probe. + * Use G29 repeatedly, adjusting the Z height at each point with movement commands + * or (with LCD_BED_LEVELING) the LCD controller. + */ +//#define PROBE_MANUALLY + +/** + * A Fix-Mounted Probe either doesn't deploy or needs manual deployment. + * (e.g., an inductive probe or a nozzle-based probe-switch.) + */ +//#define FIX_MOUNTED_PROBE + +/** + * Z Servo Probe, such as an endstop switch on a rotating arm. + */ +//#define Z_ENDSTOP_SERVO_NR 0 // Defaults to SERVO 0 connector. +//#define Z_SERVO_ANGLES {70,0} // Z Servo Deploy and Stow angles + +/** + * The BLTouch probe uses a Hall effect sensor and emulates a servo. + */ +#define BLTOUCH +#if ENABLED(BLTOUCH) + #define BLTOUCH_DELAY 500 // (ms) Enable and increase if needed +#endif + +/** + * Enable one or more of the following if probing seems unreliable. + * Heaters and/or fans can be disabled during probing to minimize electrical + * noise. A delay can also be added to allow noise and vibration to settle. + * These options are most useful for the BLTouch probe, but may also improve + * readings with inductive probes and piezo sensors. + */ +//#define PROBING_HEATERS_OFF // Turn heaters off when probing +//#define PROBING_FANS_OFF // Turn fans off when probing +//#define DELAY_BEFORE_PROBING 200 // (ms) To prevent vibrations from triggering piezo sensors + +// A probe that is deployed and stowed with a solenoid pin (SOL1_PIN) +//#define SOLENOID_PROBE + +// A sled-mounted probe like those designed by Charles Bell. +//#define Z_PROBE_SLED +//#define SLED_DOCKING_OFFSET 5 // The extra distance the X axis must travel to pickup the sled. 0 should be fine but you can push it further if you'd like. + +// +// For Z_PROBE_ALLEN_KEY see the Delta example configurations. +// + +/** + * Z Probe to nozzle (X,Y) offset, relative to (0, 0). + * X and Y offsets must be integers. + * + * In the following example the X and Y offsets are both positive: + * #define X_PROBE_OFFSET_FROM_EXTRUDER 10 + * #define Y_PROBE_OFFSET_FROM_EXTRUDER 10 + * + * +-- BACK ---+ + * | | + * L | (+) P | R <-- probe (20,20) + * E | | I + * F | (-) N (+) | G <-- nozzle (10,10) + * T | | H + * | (-) | T + * | | + * O-- FRONT --+ + * (0,0) + */ +#define X_PROBE_OFFSET_FROM_EXTRUDER -17 // X offset: -left +right [of the nozzle] +#define Y_PROBE_OFFSET_FROM_EXTRUDER -10 // Y offset: -front +behind [the nozzle] +#define Z_PROBE_OFFSET_FROM_EXTRUDER -1.027 // Z offset: -below +above [the nozzle] + +// X and Y axis travel speed (mm/m) between probes +#define XY_PROBE_SPEED 7500 + +// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +#define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z + +// Speed for the "accurate" probe of each point +#define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) + +// Use double touch for probing +//#define PROBE_DOUBLE_TOUCH + +/** + * Z probes require clearance when deploying, stowing, and moving between + * probe points to avoid hitting the bed and other hardware. + * Servo-mounted probes require extra space for the arm to rotate. + * Inductive probes need space to keep from triggering early. + * + * Use these settings to specify the distance (mm) to raise the probe (or + * lower the bed). The values set here apply over and above any (negative) + * probe Z Offset set with Z_PROBE_OFFSET_FROM_EXTRUDER, M851, or the LCD. + * Only integer values >= 1 are valid here. + * + * Example: `M851 Z-5` with a CLEARANCE of 4 => 9mm from bed to nozzle. + * But: `M851 Z+1` with a CLEARANCE of 2 => 2mm from bed to nozzle. + */ +#define Z_CLEARANCE_DEPLOY_PROBE 15 // Z Clearance for Deploy/Stow +#define Z_CLEARANCE_BETWEEN_PROBES 6 // Z Clearance between probe points + +// For M851 give a range for adjusting the Z probe offset +#define Z_PROBE_OFFSET_RANGE_MIN -20 +#define Z_PROBE_OFFSET_RANGE_MAX 20 + +// Enable the M48 repeatability test to test probe accuracy +#define Z_MIN_PROBE_REPEATABILITY_TEST + +// For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1 +// :{ 0:'Low', 1:'High' } +#define X_ENABLE_ON 0 +#define Y_ENABLE_ON 0 +#define Z_ENABLE_ON 0 +#define E_ENABLE_ON 0 // For all extruders + +// Disables axis stepper immediately when it's not being used. +// 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 +//#define DISABLE_REDUCED_ACCURACY_WARNING + +// @section extruder + +#define DISABLE_E false // For all extruders +#define DISABLE_INACTIVE_EXTRUDER true // Keep only the active extruder enabled. + +// @section machine + +// Invert the stepper direction. Change (or reverse the motor connector) if an axis goes the wrong way. +#define INVERT_X_DIR true +#define INVERT_Y_DIR true +#define INVERT_Z_DIR true + +// Enable this option for Toshiba stepper drivers +//#define CONFIG_STEPPERS_TOSHIBA + +// @section extruder + +// For direct drive extruder v9 set to true, for geared extruder set to false. +#define INVERT_E0_DIR false +#define INVERT_E1_DIR false +#define INVERT_E2_DIR false +#define INVERT_E3_DIR false +#define INVERT_E4_DIR false + +// @section homing + +//#define NO_MOTION_BEFORE_HOMING // Inhibit movement until all axes have been homed + +#define Z_HOMING_HEIGHT 10 // (in mm) Minimal z height before homing (G28) for Z clearance above the bed, clamps, ... + // Be sure you have this distance over your Z_MAX_POS in case. + +// Direction of endstops when homing; 1=MAX, -1=MIN +// :[-1,1] +#define X_HOME_DIR -1 +#define Y_HOME_DIR 1 +#define Z_HOME_DIR -1 + +// @section machine + +// The size of the print bed +#define X_BED_SIZE 420 // These numbers are not accurate for an unaltered gMax 1.5+ printer. My print bed +#define Y_BED_SIZE 420 // is inset a noticable amount from the edge of the bed. Combined with the inset, + // the nozzle can reach all cordinates of the mesh. + +// Travel limits (mm) after homing, corresponding to endstop positions. +#define X_MIN_POS 0 +#define Y_MIN_POS 0 +#define Z_MIN_POS 0 +#define X_MAX_POS X_BED_SIZE +#define Y_MAX_POS Y_BED_SIZE +#define Z_MAX_POS 500 + +// If enabled, axes won't move below MIN_POS in response to movement commands. +//#define MIN_SOFTWARE_ENDSTOPS +// If enabled, axes won't move above MAX_POS in response to movement commands. +#define MAX_SOFTWARE_ENDSTOPS + +/** + * Filament Runout Sensor + * A mechanical or opto endstop is used to check for the presence of filament. + * + * RAMPS-based boards use SERVO3_PIN. + * For other boards you may need to define FIL_RUNOUT_PIN. + * By default the firmware assumes HIGH = has filament, LOW = ran out + */ +#define FILAMENT_RUNOUT_SENSOR +#if ENABLED(FILAMENT_RUNOUT_SENSOR) + #define FIL_RUNOUT_INVERTING false // set to true to invert the logic of the sensor. + #define ENDSTOPPULLUP_FIL_RUNOUT // Uncomment to use internal pullup for filament runout pins if the sensor is defined. + #define FILAMENT_RUNOUT_SCRIPT "M600" +#endif + +//=========================================================================== +//=============================== Bed Leveling ============================== +//=========================================================================== +// @section bedlevel + +/** + * Choose one of the options below to enable G29 Bed Leveling. The parameters + * and behavior of G29 will change depending on your selection. + * + * If using a Probe for Z Homing, enable Z_SAFE_HOMING also! + * + * - AUTO_BED_LEVELING_3POINT + * Probe 3 arbitrary points on the bed (that aren't collinear) + * You specify the XY coordinates of all 3 points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_LINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_BILINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a mesh, best for large or uneven beds. + * + * - AUTO_BED_LEVELING_UBL (Unified Bed Leveling) + * A comprehensive bed leveling system combining the features and benefits + * of other systems. UBL also includes integrated Mesh Generation, Mesh + * Validation and Mesh Editing systems. Currently, UBL is only checked out + * for Cartesian Printers. That said, it was primarily designed to correct + * poor quality Delta Printers. If you feel adventurous and have a Delta, + * please post an issue if something doesn't work correctly. Initially, + * you will need to set a reduced bed size so you have a rectangular area + * to test on. + * + * - MESH_BED_LEVELING + * Probe a grid manually + * The result is a mesh, suitable for large or uneven beds. (See BILINEAR.) + * For machines without a probe, Mesh Bed Leveling provides a method to perform + * leveling in steps so you can manually adjust the Z height at each grid-point. + * With an LCD controller the process is guided step-by-step. + */ +//#define AUTO_BED_LEVELING_3POINT +//#define AUTO_BED_LEVELING_LINEAR +//#define AUTO_BED_LEVELING_BILINEAR +#define AUTO_BED_LEVELING_UBL +//#define MESH_BED_LEVELING + +/** + * Enable detailed logging of G28, G29, M48, etc. + * Turn on with the command 'M111 S32'. + * NOTE: Requires a lot of PROGMEM! + */ +#define DEBUG_LEVELING_FEATURE + +#if ENABLED(MESH_BED_LEVELING) || ENABLED(AUTO_BED_LEVELING_BILINEAR) || ENABLED(AUTO_BED_LEVELING_UBL) + // Gradually reduce leveling correction until a set height is reached, + // at which point movement will be level to the machine's XY plane. + // The height can be set with M420 Z + #define ENABLE_LEVELING_FADE_HEIGHT +#endif + +#if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Set the number of grid points per dimension. + #define GRID_MAX_POINTS_X 3 + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + // Set the boundaries for probing (where the probe can reach). + #define LEFT_PROBE_BED_POSITION 15 + #define RIGHT_PROBE_BED_POSITION 170 + #define FRONT_PROBE_BED_POSITION 20 + #define BACK_PROBE_BED_POSITION 170 + + // The Z probe minimum outer margin (to validate G29 parameters). + #define MIN_PROBE_EDGE 10 + + // Probe along the Y axis, advancing X after each column + //#define PROBE_Y_FIRST + + #if ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Beyond the probed grid, continue the implied tilt? + // Default is to maintain the height of the nearest edge. + //#define EXTRAPOLATE_BEYOND_GRID + + // + // Experimental Subdivision of the grid by Catmull-Rom method. + // Synthesizes intermediate points to produce a more detailed mesh. + // + //#define ABL_BILINEAR_SUBDIVISION + #if ENABLED(ABL_BILINEAR_SUBDIVISION) + // Number of subdivisions between probe points + #define BILINEAR_SUBDIVISIONS 3 + #endif + + #endif + +#elif ENABLED(AUTO_BED_LEVELING_3POINT) + + // 3 arbitrary points to probe. + // A simple cross-product is used to estimate the plane of the bed. + #define ABL_PROBE_PT_1_X 15 + #define ABL_PROBE_PT_1_Y 180 + #define ABL_PROBE_PT_2_X 15 + #define ABL_PROBE_PT_2_Y 20 + #define ABL_PROBE_PT_3_X 170 + #define ABL_PROBE_PT_3_Y 20 + +#elif ENABLED(AUTO_BED_LEVELING_UBL) + + //=========================================================================== + //========================= Unified Bed Leveling ============================ + //=========================================================================== + + #define UBL_MESH_INSET 45 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 10 // Don't use more than 15 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + #define UBL_PROBE_PT_1_X 53 // Probing points for 3-Point leveling of the mesh + #define UBL_PROBE_PT_1_Y 323 + #define UBL_PROBE_PT_2_X 53 + #define UBL_PROBE_PT_2_Y 63 + #define UBL_PROBE_PT_3_X 348 + #define UBL_PROBE_PT_3_Y 211 + + #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation + #define UBL_MESH_EDIT_MOVES_Z // Sophisticated users prefer no movement of nozzle + +#elif ENABLED(MESH_BED_LEVELING) + + //=========================================================================== + //=================================== Mesh ================================== + //=========================================================================== + + #define MESH_INSET 10 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 3 // Don't use more than 7 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + //#define MESH_G28_REST_ORIGIN // After homing all axes ('G28' or 'G28 XYZ') rest Z at Z_MIN_POS + +#endif // BED_LEVELING + +/** + * Use the LCD controller for bed leveling + * Requires MESH_BED_LEVELING or PROBE_MANUALLY + */ +//#define LCD_BED_LEVELING + +#if ENABLED(LCD_BED_LEVELING) + #define MBL_Z_STEP 0.025 // Step size while manually probing Z axis. + #define LCD_PROBE_Z_RANGE 4 // Z Range centered on Z_MIN_POS for LCD Z adjustment +#endif + +// Add a menu item to move between bed corners for manual bed adjustment +//#define LEVEL_BED_CORNERS + +/** + * Commands to execute at the end of G29 probing. + * Useful to retract or move the Z probe out of the way. + */ +//#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) +//#define BED_CENTER_AT_0_0 + +// Manually set the home position. Leave these undefined for automatic settings. +// For DELTA this is the top-center of the Cartesian print volume. +//#define MANUAL_X_HOME_POS 0 +//#define MANUAL_Y_HOME_POS 0 +//#define MANUAL_Z_HOME_POS 0 + +// Use "Z Safe Homing" to avoid homing with a Z probe outside the bed area. +// +// With this feature enabled: +// +// - 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). +// - 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 - 4) // X point for Z homing when homing all axis (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2 + 4) // Y point for Z homing when homing all axis (G28). +#endif + +// Homing speeds (mm/m) +#define HOMING_FEEDRATE_XY (60*60) +#define HOMING_FEEDRATE_Z (14*60) + +//============================================================================= +//============================= Additional Features =========================== +//============================================================================= + +// @section extras + +// +// EEPROM +// +// The microcontroller can store settings in the EEPROM, e.g. max velocity... +// M500 - stores parameters in EEPROM +// M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily). +// M502 - reverts to the default "factory settings". You still need to store them in EEPROM afterwards if you want to. +// +#define EEPROM_SETTINGS // Enable for M500 and M501 commands +//#define DISABLE_M503 // Saves ~2700 bytes of PROGMEM. Disable for release! +#define EEPROM_CHITCHAT // Give feedback on EEPROM commands. Disable to save PROGMEM. + +// +// Host Keepalive +// +// When enabled Marlin will send a busy status message to the host +// every couple of seconds when it can't accept commands. +// +//#define HOST_KEEPALIVE_FEATURE // Disable this if your host doesn't like keepalive messages +#define DEFAULT_KEEPALIVE_INTERVAL 2 // Number of seconds between "busy" messages. Set with M113. +#define BUSY_WHILE_HEATING // Some hosts require "busy" messages even during heating + +// +// M100 Free Memory Watcher +// +//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose + +// +// G20/G21 Inch mode support +// +//#define INCH_MODE_SUPPORT + +// +// M149 Set temperature units support +// +//#define TEMPERATURE_UNITS_SUPPORT + +// @section temperature + +// Preheat Constants +#define PREHEAT_1_TEMP_HOTEND 200 +#define PREHEAT_1_TEMP_BED 70 +#define PREHEAT_1_FAN_SPEED 0 // Value from 0 to 255 + +#define PREHEAT_2_TEMP_HOTEND 240 +#define PREHEAT_2_TEMP_BED 110 +#define PREHEAT_2_FAN_SPEED 0 // Value from 0 to 255 + +/** + * Nozzle Park -- EXPERIMENTAL + * + * Park the nozzle at the given XYZ position on idle or G27. + * + * The "P" parameter controls the action applied to the Z axis: + * + * P0 (Default) If Z is below park Z raise the nozzle. + * P1 Raise the nozzle always to Z-park height. + * P2 Raise the nozzle by Z-park amount, limited to Z_MAX_POS. + */ +//#define NOZZLE_PARK_FEATURE + +#if ENABLED(NOZZLE_PARK_FEATURE) + // Specify a park position as { X, Y, Z } + #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 } +#endif + +/** + * Clean Nozzle Feature -- EXPERIMENTAL + * + * Adds the G12 command to perform a nozzle cleaning process. + * + * Parameters: + * P Pattern + * S Strokes / Repetitions + * T Triangles (P1 only) + * + * Patterns: + * P0 Straight line (default). This process requires a sponge type material + * at a fixed bed location. "S" specifies strokes (i.e. back-forth motions) + * between the start / end points. + * + * P1 Zig-zag pattern between (X0, Y0) and (X1, Y1), "T" specifies the + * number of zig-zag triangles to do. "S" defines the number of strokes. + * Zig-zags are done in whichever is the narrower dimension. + * For example, "G12 P1 S1 T3" will execute: + * + * -- + * | (X0, Y1) | /\ /\ /\ | (X1, Y1) + * | | / \ / \ / \ | + * A | | / \ / \ / \ | + * | | / \ / \ / \ | + * | (X0, Y0) | / \/ \/ \ | (X1, Y0) + * -- +--------------------------------+ + * |________|_________|_________| + * T1 T2 T3 + * + * P2 Circular pattern with middle at NOZZLE_CLEAN_CIRCLE_MIDDLE. + * "R" specifies the radius. "S" specifies the stroke count. + * Before starting, the nozzle moves to NOZZLE_CLEAN_START_POINT. + * + * Caveats: The ending Z should be the same as starting Z. + * Attention: EXPERIMENTAL. G-code arguments may change. + * + */ +//#define NOZZLE_CLEAN_FEATURE + +#if ENABLED(NOZZLE_CLEAN_FEATURE) + // Default number of pattern repetitions + #define NOZZLE_CLEAN_STROKES 12 + + // Default number of triangles + #define NOZZLE_CLEAN_TRIANGLES 3 + + // Specify positions as { X, Y, Z } + #define NOZZLE_CLEAN_START_POINT { 30, 30, (Z_MIN_POS + 1)} + #define NOZZLE_CLEAN_END_POINT {100, 60, (Z_MIN_POS + 1)} + + // Circular pattern radius + #define NOZZLE_CLEAN_CIRCLE_RADIUS 6.5 + // Circular pattern circle fragments number + #define NOZZLE_CLEAN_CIRCLE_FN 10 + // Middle point of circle + #define NOZZLE_CLEAN_CIRCLE_MIDDLE NOZZLE_CLEAN_START_POINT + + // Moves the nozzle to the initial position + #define NOZZLE_CLEAN_GOBACK +#endif + +/** + * Print Job Timer + * + * Automatically start and stop the print job timer on M104/M109/M190. + * + * M104 (hotend, no wait) - high temp = none, low temp = stop timer + * M109 (hotend, wait) - high temp = start timer, low temp = stop timer + * M190 (bed, wait) - high temp = start timer, low temp = none + * + * The timer can also be controlled with the following commands: + * + * M75 - Start the print job timer + * M76 - Pause the print job timer + * M77 - Stop the print job timer + */ +#define PRINTJOB_TIMER_AUTOSTART + +/** + * Print Counter + * + * Track statistical data such as: + * + * - Total print jobs + * - Total successful print jobs + * - Total failed print jobs + * - Total time printing + * + * View the current statistics with M78. + */ +//#define PRINTCOUNTER + +//============================================================================= +//============================= LCD and SD support ============================ +//============================================================================= + +// @section lcd + +/** + * LCD LANGUAGE + * + * Select the language to display on the LCD. These languages are available: + * + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, + * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * tr, uk, zh_CN, zh_TW, test + * + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + */ +#define LCD_LANGUAGE en + +/** + * LCD Character Set + * + * Note: This option is NOT applicable to Graphical Displays. + * + * All character-based LCDs provide ASCII plus one of these + * language extensions: + * + * - JAPANESE ... the most common + * - WESTERN ... with more accented characters + * - CYRILLIC ... for the Russian language + * + * To determine the language extension installed on your controller: + * + * - Compile and upload with LCD_LANGUAGE set to 'test' + * - 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 + * + * :['JAPANESE', 'WESTERN', 'CYRILLIC'] + */ +#define DISPLAY_CHARSET_HD44780 JAPANESE + +/** + * LCD TYPE + * + * Enable ULTRA_LCD for a 16x2, 16x4, 20x2, or 20x4 character-based LCD. + * Enable DOGLCD for a 128x64 (ST7565R) Full Graphical Display. + * (These options will be enabled automatically for most displays.) + * + * IMPORTANT: The U8glib library is required for Full Graphic Display! + * https://github.com/olikraus/U8glib_Arduino + */ +//#define ULTRA_LCD // Character based +//#define DOGLCD // Full graphics display + +/** + * SD CARD + * + * 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 + +/** + * SD CARD: SPI SPEED + * + * Enable one of the following items for a slower SPI transfer speed. + * This may be required to resolve "volume init" errors. + */ +//#define SPI_SPEED SPI_HALF_SPEED +//#define SPI_SPEED SPI_QUARTER_SPEED +//#define SPI_SPEED SPI_EIGHTH_SPEED + +/** + * SD CARD: ENABLE CRC + * + * Use CRC checks and retries on the SD communication. + */ +#define SD_CHECK_AND_RETRY + +// +// ENCODER SETTINGS +// +// This option overrides the default number of encoder pulses needed to +// produce one step. Should be increased for high-resolution encoders. +// +#define ENCODER_PULSES_PER_STEP 1 + +// +// Use this option to override the number of step signals required to +// move between next/prev menu items. +// +#define ENCODER_STEPS_PER_MENU_ITEM 5 + +/** + * Encoder Direction Options + * + * Test your encoder's behavior first with both options disabled. + * + * Reversed Value Edit and Menu Nav? Enable REVERSE_ENCODER_DIRECTION. + * Reversed Menu Navigation only? Enable REVERSE_MENU_DIRECTION. + * Reversed Value Editing only? Enable BOTH options. + */ + +// +// This option reverses the encoder direction everywhere. +// +// Set this option if CLOCKWISE causes values to DECREASE +// +//#define REVERSE_ENCODER_DIRECTION + +// +// This option reverses the encoder direction for navigating LCD menus. +// +// If CLOCKWISE normally moves DOWN this makes it go UP. +// If CLOCKWISE normally moves UP this makes it go DOWN. +// +//#define REVERSE_MENU_DIRECTION + +// +// Individual Axis Homing +// +// Add individual axis homing items (Home X, Home Y, and Home Z) to the LCD menu. +// +//#define INDIVIDUAL_AXIS_HOMING_MENU + +// +// SPEAKER/BUZZER +// +// If you have a speaker that can produce tones, enable it here. +// By default Marlin assumes you have a buzzer with a fixed frequency. +// +//#define SPEAKER + +// +// The duration and frequency for the UI feedback sound. +// Set these to 0 to disable audio feedback in the LCD menus. +// +// Note: Test audio output with the G-Code: +// M300 S P +// +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 +//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 + +// +// CONTROLLER TYPE: Standard +// +// Marlin supports a wide variety of controllers. +// Enable one of the following options to specify your controller. +// + +// +// ULTIMAKER Controller. +// +//#define ULTIMAKERCONTROLLER + +// +// ULTIPANEL as seen on Thingiverse. +// +//#define ULTIPANEL + +// +// PanelOne from T3P3 (via RAMPS 1.4 AUX2/AUX3) +// http://reprap.org/wiki/PanelOne +// +//#define PANEL_ONE + +// +// MaKr3d Makr-Panel with graphic controller and SD support. +// http://reprap.org/wiki/MaKr3d_MaKrPanel +// +//#define MAKRPANEL + +// +// ReprapWorld Graphical LCD +// https://reprapworld.com/?products_details&products_id/1218 +// +//#define REPRAPWORLD_GRAPHICAL_LCD + +// +// Activate one of these if you have a Panucatt Devices +// Viki 2.0 or mini Viki with Graphic LCD +// http://panucatt.com +// +//#define VIKI2 +//#define miniVIKI + +// +// Adafruit ST7565 Full Graphic Controller. +// https://github.com/eboston/Adafruit-ST7565-Full-Graphic-Controller/ +// +//#define ELB_FULL_GRAPHIC_CONTROLLER + +// +// RepRapDiscount Smart Controller. +// http://reprap.org/wiki/RepRapDiscount_Smart_Controller +// +// Note: Usually sold with a white PCB. +// +//#define REPRAP_DISCOUNT_SMART_CONTROLLER + +// +// GADGETS3D G3D LCD/SD Controller +// http://reprap.org/wiki/RAMPS_1.3/1.4_GADGETS3D_Shield_with_Panel +// +// Note: Usually sold with a blue PCB. +// +//#define G3D_PANEL + +// +// RepRapDiscount FULL GRAPHIC Smart Controller +// http://reprap.org/wiki/RepRapDiscount_Full_Graphic_Smart_Controller +// +#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER + +// +// MakerLab Mini Panel with graphic +// controller and SD support - http://reprap.org/wiki/Mini_panel +// +//#define MINIPANEL + +// +// RepRapWorld REPRAPWORLD_KEYPAD v1.1 +// http://reprapworld.com/?products_details&products_id=202&cPath=1591_1626 +// +// REPRAPWORLD_KEYPAD_MOVE_STEP sets how much should the robot move when a key +// is pressed, a value of 10.0 means 10mm per click. +// +//#define REPRAPWORLD_KEYPAD +//#define REPRAPWORLD_KEYPAD_MOVE_STEP 1.0 + +// +// RigidBot Panel V1.0 +// http://www.inventapart.com/ +// +//#define RIGIDBOT_PANEL + +// +// BQ LCD Smart Controller shipped by +// default with the BQ Hephestos 2 and Witbox 2. +// +//#define BQ_LCD_SMART_CONTROLLER + +// +// Cartesio UI +// http://mauk.cc/webshop/cartesio-shop/electronics/user-interface +// +//#define CARTESIO_UI + +// +// ANET_10 Controller supported displays. +// +//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. + // This LCD is known to be susceptible to electrical interference + // which scrambles the display. Pressing any button clears it up. +//#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 + // A clone of the RepRapDiscount full graphics display but with + // different pins/wiring (see pins_ANET_10.h). + +// +// LCD for Melzi Card with Graphical LCD +// +//#define LCD_FOR_MELZI + +// +// CONTROLLER TYPE: I2C +// +// Note: These controllers require the installation of Arduino's LiquidCrystal_I2C +// library. For more info: https://github.com/kiyoshigawa/LiquidCrystal_I2C +// + +// +// Elefu RA Board Control Panel +// http://www.elefu.com/index.php?route=product/product&product_id=53 +// +//#define RA_CONTROL_PANEL + +// +// Sainsmart YW Robot (LCM1602) LCD Display +// +// Note: This controller requires F.Malpartida's LiquidCrystal_I2C library +// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home +// +//#define LCD_I2C_SAINSMART_YWROBOT + +// +// Generic LCM1602 LCD adapter +// +//#define LCM1602 + +// +// PANELOLU2 LCD with status LEDs, +// separate encoder and click inputs. +// +// Note: This controller requires Arduino's LiquidTWI2 library v1.2.3 or later. +// For more info: https://github.com/lincomatic/LiquidTWI2 +// +// Note: The PANELOLU2 encoder click input can either be directly connected to +// a pin (if BTN_ENC defined to != -1) or read through I2C (when BTN_ENC == -1). +// +//#define LCD_I2C_PANELOLU2 + +// +// Panucatt VIKI LCD with status LEDs, +// integrated click & L/R/U/D buttons, separate encoder inputs. +// +//#define LCD_I2C_VIKI + +// +// SSD1306 OLED full graphics generic display +// +//#define U8GLIB_SSD1306 + +// +// SAV OLEd LCD module support using either SSD1306 or SH1106 based LCD modules +// +//#define SAV_3DGLCD +#if ENABLED(SAV_3DGLCD) + //#define U8GLIB_SSD1306 + #define U8GLIB_SH1106 +#endif + +// +// CONTROLLER TYPE: Shift register panels +// +// 2 wire Non-latching LCD SR from https://goo.gl/aJJ4sH +// LCD configuration: http://reprap.org/wiki/SAV_3D_LCD +// +//#define SAV_3DLCD + +// +// TinyBoy2 128x64 OLED / Encoder Panel +// +//#define OLED_PANEL_TINYBOY2 + +// +// Makeboard 3D Printer Parts 3D Printer Mini Display 1602 Mini Controller +// https://www.aliexpress.com/item/Micromake-Makeboard-3D-Printer-Parts-3D-Printer-Mini-Display-1602-Mini-Controller-Compatible-with-Ramps-1/32765887917.html +// +//#define MAKEBOARD_MINI_2_LINE_DISPLAY_1602 + +// +// MKS MINI12864 with graphic controller and SD support +// http://reprap.org/wiki/MKS_MINI_12864 +// +//#define MKS_MINI_12864 + +// +// Factory display for Creality CR-10 +// https://www.aliexpress.com/item/Universal-LCD-12864-3D-Printer-Display-Screen-With-Encoder-For-CR-10-CR-7-Model/32833148327.html +// +// This is RAMPS-compatible using a single 10-pin connector. +// (For CR-10 owners who want to replace the Melzi Creality board but retain the display) +// +//#define CR10_STOCKDISPLAY + +// +// MKS OLED 1.3" 128 × 64 FULL GRAPHICS CONTROLLER +// http://reprap.org/wiki/MKS_12864OLED +// +// Tiny, but very sharp OLED display +// +//#define MKS_12864OLED + +//============================================================================= +//=============================== Extra Features ============================== +//============================================================================= + +// @section extras + +// Increase the FAN PWM frequency. Removes the PWM noise but increases heating in the FET/Arduino +//#define FAST_PWM_FAN + +// Use software PWM to drive the fan, as for the heaters. This uses a very low frequency +// which is not as annoying as with the hardware PWM. On the other hand, if this frequency +// is too low, you should also increment SOFT_PWM_SCALE. +//#define FAN_SOFT_PWM + +// Incrementing this by 1 will double the software PWM frequency, +// affecting heaters, and the fan if FAN_SOFT_PWM is enabled. +// However, control resolution will be halved for each increment; +// at zero value, there are 128 effective control positions. +#define SOFT_PWM_SCALE 0 + +// If SOFT_PWM_SCALE is set to a value higher than 0, dithering can +// be used to mitigate the associated resolution loss. If enabled, +// some of the PWM cycles are stretched so on average the desired +// duty cycle is attained. +//#define SOFT_PWM_DITHER + +// Temperature status LEDs that display the hotend and bed temperature. +// If all hotends, bed temperature, and target temperature are under 54C +// then the BLUE led is on. Otherwise the RED led is on. (1C hysteresis) +//#define TEMP_STAT_LEDS + +// M240 Triggers a camera by emulating a Canon RC-1 Remote +// Data from: http://www.doc-diy.net/photo/rc-1_hacked/ +//#define PHOTOGRAPH_PIN 23 + +// 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 + +// Support for BlinkM/CyzRgb +//#define BLINKM + +// Support for PCA9632 PWM LED driver +//#define PCA9632 + +/** + * RGB LED / LED Strip Control + * + * Enable support for an RGB LED connected to 5V digital pins, or + * an RGB Strip connected to MOSFETs controlled by digital pins. + * + * 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 overall brightness parameters is also available + * + * *** CAUTION *** + * LED Strips require a MOFSET 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! + * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino + * cannot handle such current, separate 5V power supply must be used + * *** CAUTION *** + * + * LED type. This options are mutualy exclusive. Uncomment only one. + * + */ +//#define RGB_LED +//#define RGBW_LED + +#if ENABLED(RGB_LED) || ENABLED(RGBW_LED) + #define RGB_LED_R_PIN 34 + #define RGB_LED_G_PIN 43 + #define RGB_LED_B_PIN 35 + #define RGB_LED_W_PIN -1 +#endif + +// 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 (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) + #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip + #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time + #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + //#define NEOPIXEL_STARTUP_TEST // Cycle through colors at startup +#endif + +/** + * Printer Event LEDs + * + * During printing, the LEDs will reflect the printer status: + * + * - Gradually change from blue to violet as the heated bed gets to target temp + * - Gradually change from violet to red as the hotend gets to temperature + * - Change to white to illuminate work surface + * - Change to green once print has finished + * - Turn off after the print has finished and the user has pushed a button + */ +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) + #define PRINTER_EVENT_LEDS +#endif + +/*********************************************************************\ +* R/C SERVO support +* Sponsored by TrinityLabs, Reworked by codexmas +**********************************************************************/ + +// Number of servos +// +// If you select a configuration below, this will receive a default value and does not need to be set manually +// set it manually if you have more servos than extruders and wish to manually control some +// leaving it undefined or defining as 0 will disable the servo subsystem +// If unsure, leave commented / disabled +// +#define NUM_SERVOS 2 // Servo index starts with 0 for M280 command + +// Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. +// 300ms is a good value but you can try less delay. +// If the servo can't reach the requested position, increase it. +#define SERVO_DELAY { 300, 300 } + +// Servo deactivation +// +// With this option servos are powered only during movement, then turned off to prevent jitter. +//#define DEACTIVATE_SERVOS_AFTER_MOVE + +/** + * Filament Width Sensor + * + * Measures the filament width in real-time and adjusts + * flow rate to compensate for any irregularities. + * + * Also allows the measured filament diameter to set the + * extrusion rate, so the slicer only has to specify the + * volume. + * + * Only a single extruder is supported at this time. + * + * 34 RAMPS_14 : Analog input 5 on the AUX2 connector + * 81 PRINTRBOARD : Analog input 2 on the Exp1 connector (version B,C,D,E) + * 301 RAMBO : Analog input 3 + * + * Note: May require analog pins to be defined for other boards. + */ +//#define FILAMENT_WIDTH_SENSOR + +#define DEFAULT_NOMINAL_FILAMENT_DIA 1.75 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. + +#if ENABLED(FILAMENT_WIDTH_SENSOR) + #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) + #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber + + #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading + #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading + #define MAX_MEASUREMENT_DELAY 20 // (bytes) Buffer size for stored measurements (1 byte per cm). Must be larger than MEASUREMENT_DELAY_CM. + + #define DEFAULT_MEASURED_FILAMENT_DIA DEFAULT_NOMINAL_FILAMENT_DIA // Set measured to nominal initially + + // Display filament width on the LCD status line. Status messages will expire after 5 seconds. + //#define FILAMENT_LCD_DISPLAY +#endif + +#endif // CONFIGURATION_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/gCreate/gMax1.5+/Configuration_adv.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/gCreate/gMax1.5+/Configuration_adv.h new file mode 100644 index 00000000..7bbc3347 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/gCreate/gMax1.5+/Configuration_adv.h @@ -0,0 +1,1425 @@ +/** + * 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 . + * + */ + +/** + * Configuration_adv.h + * + * Advanced settings. + * Only change these if you know exactly what you're doing. + * Some of these settings can damage your printer if improperly set! + * + * Basic settings can be found in Configuration.h + * + */ +#ifndef CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H_VERSION 010100 + +// @section temperature + +//=========================================================================== +//=============================Thermal Settings ============================ +//=========================================================================== + +#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 + #endif +#endif + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * The solution: Once the temperature reaches the target, start observing. + * If the temperature stays too far below the target (hysteresis) for too long (period), + * the firmware will halt the machine as a safety precaution. + * + * If you get false positives for "Thermal Runaway" increase THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD + */ +#if ENABLED(THERMAL_PROTECTION_HOTENDS) + #define THERMAL_PROTECTION_PERIOD 50 // Seconds + #define THERMAL_PROTECTION_HYSTERESIS 3 // Degrees Celsius + + /** + * Whenever an M104 or M109 increases the target temperature the firmware will wait for the + * WATCH_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get false positives for "Heating failed" increase WATCH_TEMP_PERIOD and/or decrease WATCH_TEMP_INCREASE + * WATCH_TEMP_INCREASE should not be below 2. + */ + #define WATCH_TEMP_PERIOD 50 // Seconds + #define WATCH_TEMP_INCREASE 2 // Degrees Celsius +#endif + +/** + * Thermal Protection parameters for the bed are just as above for hotends. + */ +#if ENABLED(THERMAL_PROTECTION_BED) + #define THERMAL_PROTECTION_BED_PERIOD 50 // Seconds + #define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius + + /** + * Whenever an M140 or M190 increases the target temperature the firmware will wait for the + * WATCH_BED_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_BED_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get too many "Heating failed" errors, increase WATCH_BED_TEMP_PERIOD and/or decrease + * WATCH_BED_TEMP_INCREASE. (WATCH_BED_TEMP_INCREASE should not be below 2.) + */ + #define WATCH_BED_TEMP_PERIOD 60 // Seconds + #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius +#endif + +#if ENABLED(PIDTEMP) + // this adds an experimental additional term to the heating power, proportional to the extrusion speed. + // if Kc is chosen well, the additional required power due to increased melting should be compensated. + //#define PID_EXTRUSION_SCALING + #if ENABLED(PID_EXTRUSION_SCALING) + #define DEFAULT_Kc (100) //heating power=Kc*(e_speed) + #define LPQ_MAX_LEN 50 + #endif +#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 + */ +#define AUTOTEMP +#if ENABLED(AUTOTEMP) + #define AUTOTEMP_OLDWEIGHT 0.98 +#endif + +// Show Temperature ADC value +// Enable for M105 to include ADC values read from temperature sensors. +//#define SHOW_TEMP_ADC_VALUES + +/** + * High Temperature Thermistor Support + * + * Thermistors able to support high temperature tend to have a hard time getting + * good readings at room and lower temperatures. This means HEATER_X_RAW_LO_TEMP + * will probably be caught when the heating element first turns on during the + * preheating process, which will trigger a min_temp_error as a safety measure + * and force stop everything. + * To circumvent this limitation, we allow for a preheat time (during which, + * min_temp_error won't be triggered) and add a min_temp buffer to handle + * aberrant readings. + * + * If you want to enable this feature for your hotend thermistor(s) + * uncomment and set values > 0 in the constants below + */ + +// The number of consecutive low temperature errors that can occur +// before a min_temp_error is triggered. (Shouldn't be more than 10.) +//#define MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED 0 + +// The number of milliseconds a hotend will preheat before starting to check +// the temperature. This value should NOT be set to the time it takes the +// hot end to reach the target temperature, but the time it takes to reach +// the minimum temperature your thermistor can read. The lower the better/safer. +// This shouldn't need to be more than 30 seconds (30000) +//#define MILLISECONDS_PREHEAT_TIME 0 + +// @section extruder + +// Extruder runout prevention. +// If the machine is idle and the temperature over MINTEMP +// then extrude some filament every couple of SECONDS. +//#define EXTRUDER_RUNOUT_PREVENT +#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_EXTRUDE 5 // mm +#endif + +// @section temperature + +//These defines help to calibrate the AD595 sensor in case you get wrong temperature measurements. +//The measured temperature is defined as "actualTemp = (measuredTemp * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET" +#define TEMP_SENSOR_AD595_OFFSET 0.0 +#define TEMP_SENSOR_AD595_GAIN 1.0 + +/** + * 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. + */ +//#define USE_CONTROLLER_FAN +#if ENABLED(USE_CONTROLLER_FAN) + //#define CONTROLLER_FAN_PIN FAN1_PIN // 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 +#endif + +// When first starting the main fan, run it at full speed for the +// given number of milliseconds. This gets the fan spinning reliably +// before setting a PWM value. (Does not work with software PWM for fan on Sanguinololu) +//#define FAN_KICKSTART_TIME 100 + +// This defines the minimal speed for the main fan, run in PWM mode +// to enable uncomment and set minimal PWM speed for reliable running (1-255) +// if fan speed is [1 - (FAN_MIN_PWM-1)] it is set to FAN_MIN_PWM +//#define FAN_MIN_PWM 50 + +// @section extruder + +/** + * Extruder cooling fans + * + * Extruder auto fans automatically turn on when their extruders' + * temperatures go above EXTRUDER_AUTO_FAN_TEMPERATURE. + * + * Your board's pins file specifies the recommended pins. Override those here + * or set to -1 to disable completely. + * + * Multiple extruders can be assigned to the same pin in which case + * the fan will turn on when any selected extruder is above the threshold. + */ +#define E0_AUTO_FAN_PIN -1 +#define E1_AUTO_FAN_PIN -1 +#define E2_AUTO_FAN_PIN -1 +#define E3_AUTO_FAN_PIN -1 +#define E4_AUTO_FAN_PIN -1 +#define EXTRUDER_AUTO_FAN_TEMPERATURE 50 +#define EXTRUDER_AUTO_FAN_SPEED 255 // == full speed + +/** + * Part-Cooling Fan Multiplexer + * + * This feature allows you to digitally multiplex the fan output. + * The multiplexer is automatically switched at tool-change. + * Set FANMUX[012]_PINs below for up to 2, 4, or 8 multiplexed fans. + */ +#define FANMUX0_PIN -1 +#define FANMUX1_PIN -1 +#define FANMUX2_PIN -1 + +/** + * M355 Case Light on-off / brightness + */ +//#define CASE_LIGHT_ENABLE +#if ENABLED(CASE_LIGHT_ENABLE) + //#define CASE_LIGHT_PIN 4 // Override the default pin if needed + #define INVERT_CASE_LIGHT false // Set true if Case Light is ON when pin is LOW + #define CASE_LIGHT_DEFAULT_ON true // Set default power-up state on + #define CASE_LIGHT_DEFAULT_BRIGHTNESS 105 // Set default power-up brightness (0-255, requires PWM pin) + //#define MENU_ITEM_CASE_LIGHT // Add a Case Light option to the LCD main menu +#endif + +//=========================================================================== +//============================ Mechanical Settings ========================== +//=========================================================================== + +// @section homing + +// If you want endstops to stay on (by default) even when not homing +// enable this option. Override at any time with M120, M121. +//#define ENDSTOPS_ALWAYS_ON_DEFAULT + +// @section extras + +//#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. + +// Dual X Steppers +// Uncomment this option to drive two X axis motors. +// The next unused E driver will be assigned to the second X stepper. +//#define X_DUAL_STEPPER_DRIVERS +#if ENABLED(X_DUAL_STEPPER_DRIVERS) + // Set true if the two X motors need to rotate in opposite directions + #define INVERT_X2_VS_X_DIR true +#endif + +// Dual Y Steppers +// Uncomment this option to drive two Y axis motors. +// The next unused E driver will be assigned to the second Y stepper. +//#define Y_DUAL_STEPPER_DRIVERS +#if ENABLED(Y_DUAL_STEPPER_DRIVERS) + // Set true if the two Y motors need to rotate in opposite directions + #define INVERT_Y2_VS_Y_DIR true +#endif + +// A single Z stepper driver is usually used to drive 2 stepper motors. +// Uncomment this option to use a separate stepper driver for each Z axis motor. +// The next unused E driver will be assigned to the second Z stepper. +//#define Z_DUAL_STEPPER_DRIVERS + +#if ENABLED(Z_DUAL_STEPPER_DRIVERS) + + // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper. + // That way the machine is capable to align the bed during home, since both Z steppers are homed. + // There is also an implementation of M666 (software endstops adjustment) to this feature. + // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed. + // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2. + // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive. + // Play a little bit with small adjustments (0.5mm) and check the behaviour. + // The M119 (endstops report) will start reporting the Z2 Endstop as well. + + //#define Z_DUAL_ENDSTOPS + + #if ENABLED(Z_DUAL_ENDSTOPS) + #define Z2_USE_ENDSTOP _XMAX_ + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 // Use M666 to determine/test this value + #endif + +#endif // Z_DUAL_STEPPER_DRIVERS + +// Enable this for dual x-carriage printers. +// A dual x-carriage design has the advantage that the inactive extruder can be parked which +// prevents hot-end ooze contaminating the print. It also reduces the weight of each x-carriage +// allowing faster printing speeds. Connect your X2 stepper to the first unused E plug. +//#define DUAL_X_CARRIAGE +#if ENABLED(DUAL_X_CARRIAGE) + // Configuration for second X-carriage + // Note: the first x-carriage is defined as the x-carriage which homes to the minimum endstop; + // the second x-carriage always homes to the maximum endstop. + #define X2_MIN_POS 80 // set minimum to ensure second x-carriage doesn't hit the parked first X-carriage + #define X2_MAX_POS 353 // set maximum to the distance between toolheads when both heads are homed + #define X2_HOME_DIR 1 // the second X-carriage always homes to the maximum endstop position + #define X2_HOME_POS X2_MAX_POS // default home position is the maximum carriage position + // However: In this mode the HOTEND_OFFSET_X value for the second extruder provides a software + // override for X2_HOME_POS. This also allow recalibration of the distance between the two endstops + // without modifying the firmware (through the "M218 T1 X???" command). + // Remember: you should set the second extruder x-offset to 0 in your slicer. + + // There are a few selectable movement modes for dual x-carriages using M605 S + // Mode 0 (DXC_FULL_CONTROL_MODE): Full control. The slicer has full control over both x-carriages and can achieve optimal travel results + // as long as it supports dual x-carriages. (M605 S0) + // Mode 1 (DXC_AUTO_PARK_MODE) : Auto-park mode. The firmware will automatically park and unpark the x-carriages on tool changes so + // that additional slicer support is not required. (M605 S1) + // Mode 2 (DXC_DUPLICATION_MODE) : Duplication mode. The firmware will transparently make the second x-carriage and extruder copy all + // actions of the first x-carriage. This allows the printer to print 2 arbitrary items at + // once. (2nd extruder x offset and temp offset are set using: M605 S2 [Xnnn] [Rmmm]) + + // This is the default power-up mode which can be later using M605. + #define DEFAULT_DUAL_X_CARRIAGE_MODE DXC_FULL_CONTROL_MODE + + // Default settings in "Auto-park Mode" + #define TOOLCHANGE_PARK_ZLIFT 0.2 // the distance to raise Z axis when parking an extruder + #define TOOLCHANGE_UNPARK_ZLIFT 1 // the distance to raise Z axis when unparking an extruder + + // Default x offset in duplication mode (typically set to half print bed width) + #define DEFAULT_DUPLICATION_X_OFFSET 100 + +#endif // DUAL_X_CARRIAGE + +// 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. +//#define EXT_SOLENOID + +// @section homing + +//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +#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 this is defined, if both x and y are to be homed, a diagonal move will be performed initially. + +// When G28 is called, this option will make Y home before X +//#define HOME_Y_BEFORE_X + +// @section machine + +#define AXIS_RELATIVE_MODES {false, false, false, false} + +// Allow duplication mode with a basic dual-nozzle extruder +//#define DUAL_NOZZLE_DUPLICATION_MODE + +// By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step. +#define INVERT_X_STEP_PIN false +#define INVERT_Y_STEP_PIN false +#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. +#define DEFAULT_STEPPER_DEACTIVE_TIME 0 // usually set to 120 seconds +#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_E true + +#define DEFAULT_MINIMUMFEEDRATE 0.0 // minimum feedrate +#define DEFAULT_MINTRAVELFEEDRATE 0.0 + +//#define HOME_AFTER_DEACTIVATE // Require rehoming after steppers are deactivated + +// @section lcd + +#if ENABLED(ULTIPANEL) + #define MANUAL_FEEDRATE {50*60, 50*60, 4*60, 60} // Feedrates for manual moves along X, Y, Z, E from panel + #define ULTIPANEL_FEEDMULTIPLY // Comment to disable setting feedrate multiplier via encoder +#endif + +// @section extras + +// minimum time in microseconds that a movement needs to take if the buffer is emptied. +#define DEFAULT_MINSEGMENTTIME 20000 + +// If defined the movements slow down when the look ahead buffer is only half full +#define SLOWDOWN + +// Frequency limit +// See nophead's blog for more info +// Not working O +//#define XY_FREQUENCY_LIMIT 15 + +// 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 +// if unwanted behavior is observed on a user's machine when running at very slow speeds. +#define MINIMUM_PLANNER_SPEED 0.05 // (mm/sec) + +// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU. +#define MICROSTEP_MODES {16,16,16,16,16} // [1,2,4,8,16] + +/** + * @section stepper motor current + * + * Some boards have a means of setting the stepper motor current via firmware. + * + * The power on motor currents are set by: + * PWM_MOTOR_CURRENT - used by MINIRAMBO & ULTIMAIN_2 + * known compatible chips: A4982 + * DIGIPOT_MOTOR_CURRENT - used by BQ_ZUM_MEGA_3D, RAMBO & SCOOVO_X9H + * known compatible chips: AD5206 + * DAC_MOTOR_CURRENT_DEFAULT - used by PRINTRBOARD_REVF & RIGIDBOARD_V2 + * known compatible chips: MCP4728 + * DIGIPOT_I2C_MOTOR_CURRENTS - used by 5DPRINT, AZTEEG_X3_PRO, MIGHTYBOARD_REVE + * known compatible chips: MCP4451, MCP4018 + * + * Motor currents can also be set by M907 - M910 and by the LCD. + * M907 - applies to all. + * M908 - BQ_ZUM_MEGA_3D, RAMBO, PRINTRBOARD_REVF, RIGIDBOARD_V2 & SCOOVO_X9H + * M909, M910 & LCD - only PRINTRBOARD_REVF & RIGIDBOARD_V2 + */ +//#define PWM_MOTOR_CURRENT { 1300, 1300, 1250 } // Values in milliamps +//#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 + +// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +//#define DIGIPOT_I2C +//#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster +#define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 +// Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS +#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=========================== +//=========================================================================== + +#define ENCODER_RATE_MULTIPLIER // If defined, certain menu edit operations automatically multiply the steps when the encoder is moved quickly +#define ENCODER_10X_STEPS_PER_SEC 75 // If the encoder steps per sec exceeds this value, multiply steps moved x10 to quickly advance the value +#define ENCODER_100X_STEPS_PER_SEC 160 // If the encoder steps per sec exceeds this value, multiply steps moved x100 to really quickly advance the value + +//#define CHDK 4 //Pin for triggering CHDK to take a picture see how to use it here http://captain-slow.dk/2014/03/09/3d-printing-timelapses/ +#define CHDK_DELAY 50 //How long in ms the pin should stay HIGH before going LOW again + +// @section lcd + +// Include a page of printer information in the LCD Main Menu +//#define LCD_INFO_MENU + +// Scroll a longer status message into view +//#define STATUS_MESSAGE_SCROLLING + +// On the Info Screen, display XY with one decimal place when possible +//#define LCD_DECIMAL_SMALL_XY + +// The timeout (in ms) to return to the status screen from sub-menus +//#define LCD_TIMEOUT_TO_STATUS 15000 + +#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 + + #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? + #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. + + #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. + // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. + // using: + //#define MENU_ADDAUTOSTART + + /** + * Sort SD file listings in alphabetical order. + * + * With this option enabled, items on SD cards will be sorted + * by name for easier navigation. + * + * By default... + * + * - Use the slowest -but safest- method for sorting. + * - Folders are sorted to the top. + * - The sort key is statically allocated. + * - No added G-code (M34) support. + * - 40 item sorting limit. (Items after the first 40 are unsorted.) + * + * SD sorting uses static allocation (as set by SDSORT_LIMIT), allowing the + * compiler to calculate the worst-case usage and throw an error if the SRAM + * limit is exceeded. + * + * - SDSORT_USES_RAM provides faster sorting via a static directory buffer. + * - SDSORT_USES_STACK does the same, but uses a local stack-based buffer. + * - SDSORT_CACHE_NAMES will retain the sorted file listing in RAM. (Expensive!) + * - SDSORT_DYNAMIC_RAM only uses RAM when the SD menu is visible. (Use with caution!) + */ + //#define SDCARD_SORT_ALPHA + + // SD Card Sorting options + #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_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. + #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #endif + + // Show a progress bar on HD44780 LCDs for SD printing + //#define LCD_PROGRESS_BAR + + #if ENABLED(LCD_PROGRESS_BAR) + // Amount of time (ms) to show the bar + #define PROGRESS_BAR_BAR_TIME 2000 + // Amount of time (ms) to show the status message + #define PROGRESS_BAR_MSG_TIME 3000 + // Amount of time (ms) to retain the status message (0=forever) + #define PROGRESS_MSG_EXPIRE 0 + // Enable this to show messages for MSG_TIME then hide them + //#define PROGRESS_MSG_ONCE + // Add a menu item to test the progress bar: + //#define LCD_PROGRESS_BAR_TEST + #endif + + // This allows hosts to request long names for files and folders with M33 + //#define LONG_FILENAME_HOST_SUPPORT + + // This option allows you to abort SD printing when any endstop is triggered. + // This feature must be enabled with "M540 S1" or from the LCD menu. + // To have any effect, endstops must be enabled during SD printing. + //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + +#endif // SDSUPPORT + +/** + * Additional options for Graphical Displays + * + * Use the optimizations here to improve printing performance, + * which can be adversely affected by graphical display drawing, + * especially when doing several short moves, and when printing + * on DELTA and SCARA machines. + * + * Some of these options may result in the display lagging behind + * controller events, as there is a trade-off between reliable + * printing performance versus fast display updates. + */ +#if ENABLED(DOGLCD) + // Enable to save many cycles by drawing a hollow frame on the Info Screen + #define XYZ_HOLLOW_FRAME + + // Enable to save many cycles by drawing a hollow frame on Menu Screens + #define MENU_HOLLOW_FRAME + + // A bigger font is available for edit items. Costs 3120 bytes of PROGMEM. + // 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. + // 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 +#endif // DOGLCD + +// @section safety + +// The hardware watchdog should reset the microcontroller disabling all outputs, +// in case the firmware gets stuck and doesn't do temperature regulation. +#define USE_WATCHDOG + +#if ENABLED(USE_WATCHDOG) + // If you have a watchdog reboot in an ArduinoMega2560 then the device will hang forever, as a watchdog reset will leave the watchdog on. + // The "WATCHDOG_RESET_MANUAL" goes around this by not using the hardware reset. + // However, THIS FEATURE IS UNSAFE!, as it will only work if interrupts are disabled. And the code could hang in an interrupt routine with interrupts disabled. + //#define WATCHDOG_RESET_MANUAL +#endif + +// @section lcd + +/** + * Babystepping enables movement of the axes by tiny increments without changing + * the current position values. This feature is used primarily to adjust the Z + * axis in the first layer of a print in real-time. + * + * Warning: Does not respect endstops! + */ +#define BABYSTEPPING +#if ENABLED(BABYSTEPPING) + //#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 1 // Babysteps are very small. Increase for faster motion. + //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping + #define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen 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_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor + //#define BABYSTEP_ZPROBE_GFX_REVERSE // Reverses the direction of the CW/CCW indicators +#endif + +// @section extruder + +/** + * Implementation of linear pressure control + * + * Assumption: advance = k * (delta velocity) + * K=0 means advance disabled. + * See Marlin documentation for calibration instructions. + */ +//#define LIN_ADVANCE + +#if ENABLED(LIN_ADVANCE) + #define LIN_ADVANCE_K 75 + + /** + * Some Slicers produce Gcode with randomly jumping extrusion widths occasionally. + * For example within a 0.4mm perimeter it may produce a single segment of 0.05mm width. + * While this is harmless for normal printing (the fluid nature of the filament will + * close this very, very tiny gap), it throws off the LIN_ADVANCE pressure adaption. + * + * For this case LIN_ADVANCE_E_D_RATIO can be used to set the extrusion:distance ratio + * to a fixed value. Note that using a fixed ratio will lead to wrong nozzle pressures + * if the slicer is using variable widths or layer heights within one print! + * + * This option sets the default E:D ratio at startup. Use `M900` to override this value. + * + * Example: `M900 W0.4 H0.2 D1.75`, where: + * - W is the extrusion width in mm + * - H is the layer height in mm + * - D is the filament diameter in mm + * + * Example: `M900 R0.0458` to set the ratio directly. + * + * Set to 0 to auto-detect the ratio based on given Gcode G1 print moves. + * + * Slic3r (including Průša Control) produces Gcode compatible with the automatic mode. + * Cura (as of this writing) may produce Gcode incompatible with the automatic mode. + */ + #define LIN_ADVANCE_E_D_RATIO 0 // The calculated ratio (or 0) according to the formula W * H / ((D / 2) ^ 2 * PI) + // Example: 0.4 * 0.2 / ((1.75 / 2) ^ 2 * PI) = 0.033260135 +#endif + +// @section leveling + +// Default mesh area is an area with an inset margin on the print area. +// Below are the macros that are used to define the borders for the mesh area, +// made available here for specialized needs, ie dual extruder setup. +#if ENABLED(MESH_BED_LEVELING) + #define MESH_MIN_X MESH_INSET + #define MESH_MAX_X (X_BED_SIZE - (MESH_INSET)) + #define MESH_MIN_Y MESH_INSET + #define MESH_MAX_Y (Y_BED_SIZE - (MESH_INSET)) +#elif ENABLED(AUTO_BED_LEVELING_UBL) + #define UBL_MESH_MIN_X UBL_MESH_INSET + #define UBL_MESH_MAX_X (X_BED_SIZE - (UBL_MESH_INSET)) + #define UBL_MESH_MIN_Y UBL_MESH_INSET + #define UBL_MESH_MAX_Y (Y_BED_SIZE - (UBL_MESH_INSET)) + + // If this is defined, the currently active mesh will be saved in the + // current slot on M500. + #define UBL_SAVE_ACTIVE_ON_M500 +#endif + +// @section extras + +// +// G2/G3 Arc Support +// +#define ARC_SUPPORT // Disable this feature to save ~3226 bytes +#if ENABLED(ARC_SUPPORT) + #define MM_PER_ARC_SEGMENT 1 // Length of each arc segment + #define N_ARC_CORRECTION 25 // Number of intertpolated 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 +#endif + +// Support for G5 with XYZE destination and IJPQ offsets. Requires ~2666 bytes. +//#define BEZIER_CURVE_SUPPORT + +// G38.2 and G38.3 Probe Target +// Enable PROBE_DOUBLE_TOUCH if you want G38 to double touch +//#define G38_PROBE_TARGET +#if ENABLED(G38_PROBE_TARGET) + #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) +#endif + +// Moves (or segments) with fewer steps than this will be joined with the next move +#define MIN_STEPS_PER_SEGMENT 6 + +// The minimum pulse width (in µs) for stepping a stepper. +// Set this if you find stepping unreliable, or if using a very fast CPU. +#define MINIMUM_STEPPER_PULSE 0 // (µs) The smallest stepper pulse allowed + +// @section temperature + +// Control heater 0 and heater 1 in parallel. +//#define HEATERS_PARALLEL + +//=========================================================================== +//================================= Buffers ================================= +//=========================================================================== + +// @section hidden + +// 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, i.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 +#else + #define BLOCK_BUFFER_SIZE 16 // maximize block buffer +#endif + +// @section serial + +// The ASCII buffer for serial input +#define MAX_CMD_SIZE 96 +#define BUFSIZE 4 + +// Transmission to Host Buffer Size +// To save 386 bytes of PROGMEM (and TX_BUFFER_SIZE+3 bytes of RAM) set to 0. +// To buffer a simple "ok" you need 4 bytes. +// For ADVANCED_OK (M105) you need 32 bytes. +// For debug-echo: 128 bytes for the optimal speed. +// Other output doesn't need to be that speedy. +// :[0, 2, 4, 8, 16, 32, 64, 128, 256] +#define TX_BUFFER_SIZE 32 + +// Host Receive Buffer Size +// Without XON/XOFF flow control (see SERIAL_XON_XOFF below) 32 bytes should be enough. +// To use flow control, set this buffer size to at least 1024 bytes. +// :[0, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048] +//#define RX_BUFFER_SIZE 1024 + +#if RX_BUFFER_SIZE >= 1024 + // Enable to have the controller send XON/XOFF control characters to + // the host to signal the RX buffer is becoming full. + //#define SERIAL_XON_XOFF +#endif + +#if ENABLED(SDSUPPORT) + // Enable this option to collect and display the maximum + // RX queue usage after transferring a file to SD. + //#define SERIAL_STATS_MAX_RX_QUEUED + + // Enable this option to collect and display the number + // of dropped bytes after a file transfer to SD. + //#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! +//#define EMERGENCY_PARSER + +// Bad Serial-connections can miss a received command by sending an 'ok' +// Therefore some clients abort after 30 seconds in a timeout. +// Some other clients start sending commands while receiving a 'wait'. +// This "wait" is only sent when the buffer is empty. 1 second is a good value here. +//#define NO_TIMEOUTS 1000 // Milliseconds + +// Some clients will have this feature soon. This could make the NO_TIMEOUTS unnecessary. +//#define ADVANCED_OK + +// @section extras + +/** + * Firmware-based and LCD-controlled retract + * + * Add G10 / G11 commands for automatic firmware-based retract / recover. + * Use M207 and M208 to define parameters for retract / recover. + * + * Use M209 to enable or disable auto-retract. + * With auto-retract enabled, all G1 E moves within the set range + * will be converted to firmware-based retract/recover moves. + * + * Be sure to turn off auto-retract during filament change. + * + * Note that M207 / M208 / M209 settings are saved to EEPROM. + * + */ +//#define FWRETRACT // ONLY PARTIALLY TESTED +#if ENABLED(FWRETRACT) + #define MIN_AUTORETRACT 0.1 // When auto-retract is on, convert E moves of this length and over + #define MAX_AUTORETRACT 10.0 // Upper limit for auto-retract conversion + #define RETRACT_LENGTH 3 // Default retract length (positive mm) + #define RETRACT_LENGTH_SWAP 13 // Default swap retract length (positive mm), for extruder change + #define RETRACT_FEEDRATE 45 // Default feedrate for retracting (mm/s) + #define RETRACT_ZLIFT 0 // Default retract Z-lift + #define RETRACT_RECOVER_LENGTH 0 // Default additional recover length (mm, added to retract length when recovering) + #define RETRACT_RECOVER_LENGTH_SWAP 0 // Default additional swap recover length (mm, added to retract length when recovering from extruder change) + #define RETRACT_RECOVER_FEEDRATE 8 // Default feedrate for recovering from retraction (mm/s) + #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) +#endif + +/** + * Advanced Pause + * Experimental feature for filament change support and for parking the nozzle when paused. + * Adds the GCode M600 for initiating filament change. + * If PARK_HEAD_ON_PAUSE enabled, adds the GCode M125 to pause printing and park the nozzle. + * + * Requires an LCD display. + * This feature is required for the default FILAMENT_RUNOUT_SCRIPT. + */ +#define ADVANCED_PAUSE_FEATURE +#if ENABLED(ADVANCED_PAUSE_FEATURE) + #define PAUSE_PARK_X_POS 75 // X position of hotend + #define PAUSE_PARK_Y_POS 75 // Y position of hotend + #define PAUSE_PARK_Z_ADD 10 // Z addition of hotend (lift) + #define PAUSE_PARK_XY_FEEDRATE 100 // X and Y axes feedrate in mm/s (also used for delta printers Z axis) + #define PAUSE_PARK_Z_FEEDRATE 5 // Z axis feedrate in mm/s (not used for delta printers) + #define PAUSE_PARK_RETRACT_FEEDRATE 60 // Initial retract feedrate in mm/s + #define PAUSE_PARK_RETRACT_LENGTH 2 // Initial retract in mm + // It is a short retract used immediately after print interrupt before move to filament exchange position + #define FILAMENT_CHANGE_UNLOAD_FEEDRATE 10 // Unload filament feedrate in mm/s - filament unloading can be fast + #define FILAMENT_CHANGE_UNLOAD_LENGTH 100 // Unload filament length from hotend in mm + // Longer length for bowden printers to unload filament from whole bowden tube, + // shorter length for printers without bowden to unload filament from extruder only, + // 0 to disable unloading for manual unloading + #define FILAMENT_CHANGE_LOAD_FEEDRATE 6 // Load filament feedrate in mm/s - filament loading into the bowden tube can be fast + #define FILAMENT_CHANGE_LOAD_LENGTH 0 // Load filament length over hotend in mm + // Longer length for bowden printers to fast load filament into whole bowden tube over the hotend, + // Short or zero length for printers without bowden where loading is not used + #define ADVANCED_PAUSE_EXTRUDE_FEEDRATE 3 // Extrude filament feedrate in mm/s - must be slower than load feedrate + #define ADVANCED_PAUSE_EXTRUDE_LENGTH 50 // Extrude filament length in mm after filament is loaded over the hotend, + // 0 to disable for manual extrusion + // Filament can be extruded repeatedly from the filament exchange menu to fill the hotend, + // or until outcoming filament color is not clear for filament color change + #define PAUSE_PARK_NOZZLE_TIMEOUT 45 // Turn off nozzle if user doesn't change filament within this time limit in seconds + #define FILAMENT_CHANGE_NUMBER_OF_ALERT_BEEPS 5 // Number of alert beeps before printer goes quiet + #define PAUSE_PARK_NO_STEPPER_TIMEOUT // Enable to have stepper motors hold position during filament change + // even if it takes longer than DEFAULT_STEPPER_DEACTIVE_TIME. + #define PARK_HEAD_ON_PAUSE // Go to filament change position on pause, return to print position on resume + //#define HOME_BEFORE_FILAMENT_CHANGE // Ensure homing has been completed prior to parking for filament change +#endif + +// @section tmc + +/** + * Enable this section if you have TMC26X motor drivers. + * You will need to import the TMC26XStepper library into the Arduino IDE for this + * (https://github.com/trinamic/TMC26XStepper.git) + */ +//#define HAVE_TMCDRIVER + +#if ENABLED(HAVE_TMCDRIVER) + + //#define X_IS_TMC + //#define X2_IS_TMC + //#define Y_IS_TMC + //#define Y2_IS_TMC + //#define Z_IS_TMC + //#define Z2_IS_TMC + //#define E0_IS_TMC + //#define E1_IS_TMC + //#define E2_IS_TMC + //#define E3_IS_TMC + //#define E4_IS_TMC + + #define X_MAX_CURRENT 1000 // in mA + #define X_SENSE_RESISTOR 91 // in mOhms + #define X_MICROSTEPS 16 // number of microsteps + + #define X2_MAX_CURRENT 1000 + #define X2_SENSE_RESISTOR 91 + #define X2_MICROSTEPS 16 + + #define Y_MAX_CURRENT 1000 + #define Y_SENSE_RESISTOR 91 + #define Y_MICROSTEPS 16 + + #define Y2_MAX_CURRENT 1000 + #define Y2_SENSE_RESISTOR 91 + #define Y2_MICROSTEPS 16 + + #define Z_MAX_CURRENT 1000 + #define Z_SENSE_RESISTOR 91 + #define Z_MICROSTEPS 16 + + #define Z2_MAX_CURRENT 1000 + #define Z2_SENSE_RESISTOR 91 + #define Z2_MICROSTEPS 16 + + #define E0_MAX_CURRENT 1000 + #define E0_SENSE_RESISTOR 91 + #define E0_MICROSTEPS 16 + + #define E1_MAX_CURRENT 1000 + #define E1_SENSE_RESISTOR 91 + #define E1_MICROSTEPS 16 + + #define E2_MAX_CURRENT 1000 + #define E2_SENSE_RESISTOR 91 + #define E2_MICROSTEPS 16 + + #define E3_MAX_CURRENT 1000 + #define E3_SENSE_RESISTOR 91 + #define E3_MICROSTEPS 16 + + #define E4_MAX_CURRENT 1000 + #define E4_SENSE_RESISTOR 91 + #define E4_MICROSTEPS 16 + +#endif + +// @section TMC2130 + +/** + * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. + * + * You'll also need the TMC2130Stepper Arduino library + * (https://github.com/teemuatlut/TMC2130Stepper). + * + * To use TMC2130 stepper drivers in SPI mode connect your SPI2130 pins to + * the hardware SPI interface on your board and define the required CS pins + * in your `pins_MYBOARD.h` file. (e.g., RAMPS 1.4 uses AUX3 pins `X_CS_PIN 53`, `Y_CS_PIN 49`, etc.). + */ +//#define HAVE_TMC2130 + +#if ENABLED(HAVE_TMC2130) + + // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY + //#define X_IS_TMC2130 + //#define X2_IS_TMC2130 + //#define Y_IS_TMC2130 + //#define Y2_IS_TMC2130 + //#define Z_IS_TMC2130 + //#define Z2_IS_TMC2130 + //#define E0_IS_TMC2130 + //#define E1_IS_TMC2130 + //#define E2_IS_TMC2130 + //#define E3_IS_TMC2130 + //#define E4_IS_TMC2130 + + /** + * Stepper driver settings + */ + + #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 + #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current + #define INTERPOLATE 1 // Interpolate X/Y/Z_MICROSTEPS to 256 + + #define X_CURRENT 1000 // rms current in mA. Multiply by 1.41 for peak current. + #define X_MICROSTEPS 16 // 0..256 + + #define Y_CURRENT 1000 + #define Y_MICROSTEPS 16 + + #define Z_CURRENT 1000 + #define Z_MICROSTEPS 16 + + //#define X2_CURRENT 1000 + //#define X2_MICROSTEPS 16 + + //#define Y2_CURRENT 1000 + //#define Y2_MICROSTEPS 16 + + //#define Z2_CURRENT 1000 + //#define Z2_MICROSTEPS 16 + + //#define E0_CURRENT 1000 + //#define E0_MICROSTEPS 16 + + //#define E1_CURRENT 1000 + //#define E1_MICROSTEPS 16 + + //#define E2_CURRENT 1000 + //#define E2_MICROSTEPS 16 + + //#define E3_CURRENT 1000 + //#define E3_MICROSTEPS 16 + + //#define E4_CURRENT 1000 + //#define E4_MICROSTEPS 16 + + /** + * Use Trinamic's ultra quiet stepping mode. + * When disabled, Marlin will use spreadCycle stepping mode. + */ + #define STEALTHCHOP + + /** + * Let Marlin automatically control stepper current. + * This is still an experimental feature. + * Increase current every 5s by CURRENT_STEP until stepper temperature prewarn gets triggered, + * then decrease current by CURRENT_STEP until temperature prewarn is cleared. + * Adjusting starts from X/Y/Z/E_CURRENT but will not increase over AUTO_ADJUST_MAX + * 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. + * M906 S1 - Start adjusting current + * M906 S0 - Stop adjusting current + * M911 - Report stepper driver overtemperature pre-warn condition. + * M912 - Clear stepper driver overtemperature pre-warn condition flag. + */ + //#define AUTOMATIC_CURRENT_CONTROL + + #if ENABLED(AUTOMATIC_CURRENT_CONTROL) + #define CURRENT_STEP 50 // [mA] + #define AUTO_ADJUST_MAX 1300 // [mA], 1300mA_rms = 1840mA_peak + #define REPORT_CURRENT_CHANGE + #endif + + /** + * The driver will switch to spreadCycle when stepper speed is over HYBRID_THRESHOLD. + * This mode allows for faster movements at the expense of higher noise levels. + * STEALTHCHOP needs to be enabled. + * M913 X/Y/Z/E to live tune the setting + */ + //#define HYBRID_THRESHOLD + + #define X_HYBRID_THRESHOLD 100 // [mm/s] + #define X2_HYBRID_THRESHOLD 100 + #define Y_HYBRID_THRESHOLD 100 + #define Y2_HYBRID_THRESHOLD 100 + #define Z_HYBRID_THRESHOLD 4 + #define Z2_HYBRID_THRESHOLD 4 + #define E0_HYBRID_THRESHOLD 30 + #define E1_HYBRID_THRESHOLD 30 + #define E2_HYBRID_THRESHOLD 30 + #define E3_HYBRID_THRESHOLD 30 + #define E4_HYBRID_THRESHOLD 30 + + /** + * Use stallGuard2 to sense an obstacle and trigger an endstop. + * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. + * If used along with STEALTHCHOP, the movement will be louder when homing. This is normal. + * + * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. + * Higher values make the system LESS sensitive. + * Lower value make the system MORE sensitive. + * Too low values can lead to false positives, while too high values will collide the axis without triggering. + * It is advised to set X/Y_HOME_BUMP_MM to 0. + * M914 X/Y to live tune the setting + */ + //#define SENSORLESS_HOMING + + #if ENABLED(SENSORLESS_HOMING) + #define X_HOMING_SENSITIVITY 19 + #define Y_HOMING_SENSITIVITY 19 + #endif + + /** + * You can set your own advanced settings by filling in predefined functions. + * A list of available functions can be found on the library github page + * https://github.com/teemuatlut/TMC2130Stepper + * + * Example: + * #define TMC2130_ADV() { \ + * stepperX.diag0_temp_prewarn(1); \ + * stepperX.interpolate(0); \ + * } + */ + #define TMC2130_ADV() { } + +#endif // HAVE_TMC2130 + +// @section L6470 + +/** + * Enable this section if you have L6470 motor drivers. + * You need to import the L6470 library into the Arduino IDE for this. + * (https://github.com/ameyer/Arduino-L6470) + */ + +//#define HAVE_L6470DRIVER +#if ENABLED(HAVE_L6470DRIVER) + + //#define X_IS_L6470 + //#define X2_IS_L6470 + //#define Y_IS_L6470 + //#define Y2_IS_L6470 + //#define Z_IS_L6470 + //#define Z2_IS_L6470 + //#define E0_IS_L6470 + //#define E1_IS_L6470 + //#define E2_IS_L6470 + //#define E3_IS_L6470 + //#define E4_IS_L6470 + + #define X_MICROSTEPS 16 // number of microsteps + #define X_K_VAL 50 // 0 - 255, Higher values, are higher power. Be careful not to go too high + #define X_OVERCURRENT 2000 // maxc current in mA. If the current goes over this value, the driver will switch off + #define X_STALLCURRENT 1500 // current in mA where the driver will detect a stall + + #define X2_MICROSTEPS 16 + #define X2_K_VAL 50 + #define X2_OVERCURRENT 2000 + #define X2_STALLCURRENT 1500 + + #define Y_MICROSTEPS 16 + #define Y_K_VAL 50 + #define Y_OVERCURRENT 2000 + #define Y_STALLCURRENT 1500 + + #define Y2_MICROSTEPS 16 + #define Y2_K_VAL 50 + #define Y2_OVERCURRENT 2000 + #define Y2_STALLCURRENT 1500 + + #define Z_MICROSTEPS 16 + #define Z_K_VAL 50 + #define Z_OVERCURRENT 2000 + #define Z_STALLCURRENT 1500 + + #define Z2_MICROSTEPS 16 + #define Z2_K_VAL 50 + #define Z2_OVERCURRENT 2000 + #define Z2_STALLCURRENT 1500 + + #define E0_MICROSTEPS 16 + #define E0_K_VAL 50 + #define E0_OVERCURRENT 2000 + #define E0_STALLCURRENT 1500 + + #define E1_MICROSTEPS 16 + #define E1_K_VAL 50 + #define E1_OVERCURRENT 2000 + #define E1_STALLCURRENT 1500 + + #define E2_MICROSTEPS 16 + #define E2_K_VAL 50 + #define E2_OVERCURRENT 2000 + #define E2_STALLCURRENT 1500 + + #define E3_MICROSTEPS 16 + #define E3_K_VAL 50 + #define E3_OVERCURRENT 2000 + #define E3_STALLCURRENT 1500 + + #define E4_MICROSTEPS 16 + #define E4_K_VAL 50 + #define E4_OVERCURRENT 2000 + #define E4_STALLCURRENT 1500 + +#endif + +/** + * TWI/I2C BUS + * + * This feature is an EXPERIMENTAL feature so it shall not be used on production + * machines. Enabling this will allow you to send and receive I2C data from slave + * devices on the bus. + * + * ; Example #1 + * ; This macro send the string "Marlin" to the slave device with address 0x63 (99) + * ; It uses multiple M260 commands with one B arg + * M260 A99 ; Target slave address + * M260 B77 ; M + * M260 B97 ; a + * M260 B114 ; r + * M260 B108 ; l + * M260 B105 ; i + * M260 B110 ; n + * M260 S1 ; Send the current buffer + * + * ; Example #2 + * ; Request 6 bytes from slave device with address 0x63 (99) + * M261 A99 B5 + * + * ; Example #3 + * ; Example serial output of a M261 request + * echo:i2c-reply: from:99 bytes:5 data:hello + */ + +// @section i2cbus + +//#define EXPERIMENTAL_I2CBUS +#define I2C_SLAVE_ADDRESS 0 // Set a value from 8 to 127 to act as a slave + +// @section extras + +/** + * Spindle & Laser control + * + * Add the M3, M4, and M5 commands to turn the spindle/laser on and off, and + * to set spindle speed, spindle direction, and laser power. + * + * SuperPid is a router/spindle speed controller used in the CNC milling community. + * Marlin can be used to turn the spindle on and off. It can also be used to set + * the spindle speed from 5,000 to 30,000 RPM. + * + * 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. + */ +//#define SPINDLE_LASER_ENABLE +#if ENABLED(SPINDLE_LASER_ENABLE) + + #define SPINDLE_LASER_ENABLE_INVERT false // set to "true" if the on/off function is reversed + #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 // delay in milliseconds to allow the spindle/laser to come up to speed/power + #define SPINDLE_LASER_POWERDOWN_DELAY 5000 // delay in milliseconds to allow the spindle to stop + #define SPINDLE_DIR_CHANGE true // set to true if your spindle controller supports changing spindle direction + #define SPINDLE_INVERT_DIR false + #define SPINDLE_STOP_ON_DIR_CHANGE true // set to true if Marlin should stop the spindle before changing rotation direction + + /** + * The M3 & M4 commands use the following equation to convert PWM duty cycle to speed/power + * + * SPEED/POWER = PWM duty cycle * SPEED_POWER_SLOPE + SPEED_POWER_INTERCEPT + * where PWM duty cycle varies from 0 to 255 + * + * set the following for your controller (ALL MUST BE SET) + */ + + #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_SLOPE 0.3922 + //#define SPEED_POWER_INTERCEPT 0 + //#define SPEED_POWER_MIN 10 + //#define SPEED_POWER_MAX 100 // 0-100% +#endif + +/** + * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins + */ +//#define PINS_DEBUGGING + +/** + * Auto-report temperatures with M155 S + */ +#define AUTO_REPORT_TEMPERATURES + +/** + * Include capabilities in M115 output + */ +#define EXTENDED_CAPABILITIES_REPORT + +/** + * Volumetric extrusion default state + * 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. + */ +//#define VOLUMETRIC_DEFAULT_ON + +/** + * Enable this option for a leaner build of Marlin that removes all + * workspace offsets, simplifying coordinate transformations, leveling, etc. + * + * - M206 and M428 are disabled. + * - G92 will revert to its behavior from Marlin 1.0. + */ +#define NO_WORKSPACE_OFFSETS + +/** + * 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. + * + * For clients that use a fixed-width font (like OctoPrint), leave this set to 1.0. + * Otherwise, adjust according to your client and font. + */ +#define PROPORTIONAL_FONT_RATIO 1.5 + +/** + * Spend 28 bytes of SRAM to optimize the GCode parser + */ +#define FASTER_GCODE_PARSER + +/** + * User-defined menu items that execute custom GCode + */ +//#define CUSTOM_USER_MENUS +#if ENABLED(CUSTOM_USER_MENUS) + #define USER_SCRIPT_DONE "M117 User Script Done" + #define USER_SCRIPT_AUDIBLE_FEEDBACK + //#define USER_SCRIPT_RETURN // Return to status screen after a script + + #define USER_DESC_1 "Home & UBL Info" + #define USER_GCODE_1 "G28\nG29 W" + + #define USER_DESC_2 "Preheat for PLA" + #define USER_GCODE_2 "M140 S" STRINGIFY(PREHEAT_1_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND) + + #define USER_DESC_3 "Preheat for ABS" + #define USER_GCODE_3 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND) + + #define USER_DESC_4 "Heat Bed/Home/Level" + #define USER_GCODE_4 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nG28\nG29" + + //#define USER_DESC_5 "Home & Info" + //#define USER_GCODE_5 "G28\nM503" +#endif + +/** + * Specify an action command to send to the host when the printer is killed. + * Will be sent in the form '//action:ACTION_ON_KILL', e.g. '//action:poweroff'. + * The host must be configured to handle the action command. + */ +//#define ACTION_ON_KILL "poweroff" + +//=========================================================================== +//====================== I2C Position Encoder Settings ====================== +//=========================================================================== + +/** + * I2C position encoders for closed loop control. + * Developed by Chris Barr at Aus3D. + * + * Wiki: http://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/ + * + * Reilabuild encoders have been modified to improve reliability. + */ + +//#define I2C_POSITION_ENCODERS +#if ENABLED(I2C_POSITION_ENCODERS) + + #define I2CPE_ENCODER_CNT 1 // The number of encoders installed; max of 5 + // encoders supported currently. + + #define I2CPE_ENC_1_ADDR I2CPE_PRESET_ADDR_X // I2C address of the encoder. 30-200. + #define I2CPE_ENC_1_AXIS X_AXIS // Axis the encoder module is installed on. _AXIS. + #define I2CPE_ENC_1_TYPE I2CPE_ENC_TYPE_LINEAR // Type of encoder: I2CPE_ENC_TYPE_LINEAR -or- + // I2CPE_ENC_TYPE_ROTARY. + #define I2CPE_ENC_1_TICKS_UNIT 2048 // 1024 for magnetic strips with 2mm poles; 2048 for + // 1mm poles. For linear encoders this is ticks / mm, + // for rotary encoders this is ticks / revolution. + //#define I2CPE_ENC_1_TICKS_REV (16 * 200) // Only needed for rotary encoders; number of stepper + // steps per full revolution (motor steps/rev * microstepping) + //#define I2CPE_ENC_1_INVERT // Invert the direction of axis travel. + #define I2CPE_ENC_1_EC_METHOD I2CPE_ECM_NONE // Type of error error correction. + #define I2CPE_ENC_1_EC_THRESH 0.10 // Threshold size for error (in mm) above which the + // printer will attempt to correct the error; errors + // smaller than this are ignored to minimize effects of + // measurement noise / latency (filter). + + #define I2CPE_ENC_2_ADDR I2CPE_PRESET_ADDR_Y // Same as above, but for encoder 2. + #define I2CPE_ENC_2_AXIS Y_AXIS + #define I2CPE_ENC_2_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_ENC_2_TICKS_UNIT 2048 + //#define I2CPE_ENC_2_TICKS_REV (16 * 200) + //#define I2CPE_ENC_2_INVERT + #define I2CPE_ENC_2_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_ENC_2_EC_THRESH 0.10 + + #define I2CPE_ENC_3_ADDR I2CPE_PRESET_ADDR_Z // Encoder 3. Add additional configuration options + #define I2CPE_ENC_3_AXIS Z_AXIS // as above, or use defaults below. + + #define I2CPE_ENC_4_ADDR I2CPE_PRESET_ADDR_E // Encoder 4. + #define I2CPE_ENC_4_AXIS E_AXIS + + #define I2CPE_ENC_5_ADDR 34 // Encoder 5. + #define I2CPE_ENC_5_AXIS E_AXIS + + // Default settings for encoders which are enabled, but without settings configured above. + #define I2CPE_DEF_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_DEF_ENC_TICKS_UNIT 2048 + #define I2CPE_DEF_TICKS_REV (16 * 200) + #define I2CPE_DEF_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_DEF_EC_THRESH 0.1 + + //#define I2CPE_ERR_THRESH_ABORT 100.0 // Threshold size for error (in mm) error on any given + // axis after which the printer will abort. Comment out to + // disable abort behaviour. + + #define I2CPE_TIME_TRUSTED 10000 // After an encoder fault, there must be no further fault + // for this amount of time (in ms) before the encoder + // is trusted again. + + /** + * Position is checked every time a new command is executed from the buffer but during long moves, + * this setting determines the minimum update time between checks. A value of 100 works well with + * error rolling average when attempting to correct only for skips and not for vibration. + */ + #define I2CPE_MIN_UPD_TIME_MS 100 // Minimum time in miliseconds between encoder checks. + + // Use a rolling average to identify persistant errors that indicate skips, as opposed to vibration and noise. + #define I2CPE_ERR_ROLLING_AVERAGE + +#endif // I2C_POSITION_ENCODERS + +/** + * MAX7219 Debug Matrix + * + * Add support for a low-cost 8x8 LED Matrix based on the Max7219 chip, which can be used as a status + * display. Requires 3 signal wires. Some useful debug options are included to demonstrate its usage. + * + * Fully assembled MAX7219 boards can be found on the internet for under $2(US). + * For example, see https://www.ebay.com/sch/i.html?_nkw=332349290049 + */ + +#define MAX7219_DEBUG +#if ENABLED(MAX7219_DEBUG) + #define MAX7219_CLK_PIN 64 // 77 on Re-ARM // Configuration of the 3 pins to control the display + #define MAX7219_DIN_PIN 57 // 78 on Re-ARM + #define MAX7219_LOAD_PIN 44 // 79 on Re-ARM + + /** + * Sample debug features + * If you add more debug displays, be careful to avoid conflicts! + */ + #define MAX7219_DEBUG_PRINTER_ALIVE // Blink corner LED of 8x8 matrix to show that the firmware is functioning + #define MAX7219_DEBUG_STEPPER_HEAD 3 // Show the stepper queue head position on this and the next LED matrix row + #define MAX7219_DEBUG_STEPPER_TAIL 5 // Show the stepper queue tail position on this and the next LED matrix row + + #define MAX7219_DEBUG_STEPPER_QUEUE 0 // Show the current stepper queue depth on this and the next LED matrix row + // If you experience stuttering, reboots, etc. this option can reveal how + // tweaks made to the configuration are affecting the printer in real-time. +#endif + +#endif // CONFIGURATION_ADV_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/gCreate/gMax1.5+/_Bootscreen.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/gCreate/gMax1.5+/_Bootscreen.h new file mode 100644 index 00000000..b691e816 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/gCreate/gMax1.5+/_Bootscreen.h @@ -0,0 +1,108 @@ +/** + * 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 . + * + */ + +/** + * Custom Bitmap for splashscreen + * + * You may use one of the following tools to generate the C++ bitmap array from + * a black and white image: + * + * - http://www.marlinfw.org/tools/u8glib/converter.html + * - http://www.digole.com/tools/PicturetoC_Hex_converter.php + */ +//custom screen can be up to 112 wide and 64 high + +#include + +#define CUSTOM_BOOTSCREEN_TIMEOUT 2500 +#define CUSTOM_BOOTSCREEN_BMPWIDTH 112 +#define CUSTOM_BOOTSCREEN_BMPHEIGHT 64 + +// Width: 112, Height: 64 +const unsigned char custom_start_bmp[896] PROGMEM = { + 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x80, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x80, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x80, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x80, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x80, 0x00, 0x00, 0x01, 0xf9, 0x00, 0x00, 0x03, 0xf8, 0x00, 0x00, 0x01, 0xc0, 0x01, + 0x80, 0x00, 0x00, 0x06, 0x4d, 0x00, 0x00, 0x07, 0x38, 0x00, 0x00, 0x01, 0xc0, 0x01, + 0x80, 0x00, 0x00, 0x0c, 0x26, 0x00, 0x0e, 0xe7, 0x39, 0xd3, 0xe1, 0xf3, 0xe7, 0xc1, + 0x80, 0x00, 0x00, 0x19, 0x12, 0x00, 0x0f, 0xe7, 0x39, 0xf7, 0xf3, 0xfb, 0xef, 0xe1, + 0x80, 0x00, 0x00, 0x37, 0xce, 0x00, 0x0e, 0xe7, 0x01, 0xf7, 0x73, 0xb9, 0xce, 0xe1, + 0x80, 0x00, 0x00, 0x64, 0x66, 0x00, 0x0e, 0xe7, 0x01, 0xc7, 0xf3, 0xb9, 0xcf, 0xe1, + 0x80, 0x00, 0x00, 0x4b, 0xa6, 0x00, 0x0e, 0xe7, 0x39, 0xc7, 0xf0, 0xf9, 0xcf, 0xe1, + 0x80, 0x00, 0x00, 0xca, 0xb4, 0x00, 0x0f, 0xe7, 0x39, 0xc7, 0x03, 0xf9, 0xce, 0x01, + 0x80, 0x00, 0x00, 0xcd, 0xa4, 0x00, 0x06, 0xe7, 0x39, 0xc7, 0x73, 0xb9, 0xce, 0xe1, + 0x80, 0x00, 0x03, 0xa6, 0x6c, 0x00, 0x00, 0xe7, 0x39, 0xc7, 0x73, 0xb9, 0xce, 0xe1, + 0x80, 0x00, 0xff, 0x13, 0xd8, 0x00, 0x0e, 0xe3, 0xf1, 0xc7, 0xf3, 0xf9, 0xef, 0xe1, + 0x80, 0x01, 0x21, 0x88, 0x18, 0x00, 0x0f, 0xe1, 0xe1, 0xc3, 0xe1, 0xb9, 0xe7, 0xc1, + 0x80, 0x06, 0x61, 0x16, 0x30, 0x00, 0x07, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x80, 0x04, 0x41, 0x23, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x80, 0x04, 0xfe, 0x41, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x80, 0x0b, 0x86, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x1f, 0x80, 0x00, 0x00, 0x01, + 0x80, 0x1e, 0x01, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x1f, 0x80, 0x00, 0x00, 0x01, + 0x80, 0x1c, 0x07, 0x22, 0x00, 0x00, 0x07, 0xbc, 0x3f, 0x9f, 0x81, 0xf8, 0xf1, 0xe1, + 0x80, 0x08, 0x1f, 0xe2, 0x00, 0x00, 0x0f, 0xfc, 0x3f, 0xbf, 0x87, 0xfe, 0x71, 0xc1, + 0x80, 0x00, 0x33, 0x62, 0x00, 0x00, 0x0f, 0x3c, 0x3d, 0xb7, 0x87, 0x9e, 0x7b, 0xc1, + 0x80, 0x00, 0xc2, 0x22, 0x00, 0x00, 0x0f, 0x3c, 0x3d, 0xb7, 0x87, 0x9e, 0x7b, 0xc1, + 0x80, 0x00, 0xc2, 0x3e, 0x00, 0x00, 0x0f, 0x3c, 0x3d, 0xf7, 0x80, 0x7e, 0x3b, 0x81, + 0x80, 0x01, 0xe6, 0x1e, 0x00, 0x00, 0x0f, 0x3c, 0x3d, 0xf7, 0x83, 0xfe, 0x3f, 0x81, + 0x80, 0x01, 0x3c, 0x12, 0x00, 0x00, 0x0f, 0x3c, 0x3d, 0xf7, 0x87, 0x9e, 0x3b, 0x81, + 0x80, 0x01, 0x1c, 0x26, 0x00, 0x00, 0x0f, 0xfc, 0x3d, 0xf7, 0x87, 0x9e, 0x7b, 0xc1, + 0x80, 0x01, 0x70, 0x64, 0x00, 0x00, 0x07, 0xbc, 0x3c, 0xe7, 0x87, 0x9e, 0x7b, 0xc1, + 0x80, 0x03, 0xc0, 0x58, 0x00, 0x00, 0x00, 0x3c, 0x3c, 0xe7, 0x87, 0xfe, 0x71, 0xc1, + 0x80, 0x0d, 0x80, 0xf0, 0x00, 0x00, 0x0f, 0x3c, 0x3c, 0xe7, 0x83, 0xde, 0xf1, 0xe1, + 0x80, 0x1a, 0x00, 0xe0, 0x00, 0x00, 0x0f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x80, 0x26, 0x00, 0x40, 0x00, 0x00, 0x03, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x80, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x80, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + + 0x81, 0x06, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1c, 0x03, 0xc0, 0x20, 0x10, 0x00, 0x01, + 0x83, 0x24, 0x00, 0x00, 0x00, 0x00, 0x08, 0x92, 0x02, 0x20, 0x00, 0x10, 0x00, 0x01, + 0x02, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x91, 0x02, 0x23, 0x27, 0x39, 0x8c, 0xe1, + 0x06, 0x38, 0x00, 0x00, 0x00, 0x00, 0x03, 0x11, 0x03, 0xc2, 0x24, 0x92, 0x49, 0x01, + 0x04, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x91, 0x02, 0x02, 0x24, 0x93, 0xc8, 0xc1, + 0x0d, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x08, 0x92, 0x02, 0x02, 0x24, 0x92, 0x08, 0x21, + 0x08, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1c, 0x02, 0x02, 0x24, 0x99, 0xc9, 0xc1, + 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + + 0x10, 0x30, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x0f, 0xe0, 0x0f, 0x00, 0x01, + 0x30, 0x20, 0x00, 0x37, 0x00, 0x00, 0x00, 0x12, 0x24, 0x08, 0x10, 0x09, 0x00, 0x01, + 0x20, 0x30, 0x00, 0x6d, 0x80, 0x00, 0x00, 0x12, 0x24, 0x09, 0x88, 0x09, 0x00, 0x01, + 0x10, 0x18, 0x1f, 0x60, 0xc0, 0x00, 0x00, 0x12, 0x24, 0x09, 0x48, 0x09, 0x00, 0x01, + 0x30, 0x0c, 0x39, 0xe0, 0x60, 0x00, 0x00, 0x12, 0x24, 0x09, 0x90, 0x09, 0x00, 0x01, + 0x30, 0x07, 0x90, 0x70, 0x60, 0x00, 0x00, 0x12, 0x24, 0x08, 0x60, 0x09, 0x00, 0x01, + 0x10, 0x16, 0xf0, 0x18, 0x20, 0x00, 0x00, 0x12, 0x24, 0x08, 0x10, 0x09, 0x00, 0x01, + 0x1a, 0x10, 0x60, 0x08, 0x30, 0x00, 0x00, 0x12, 0x24, 0x09, 0xc8, 0x09, 0x00, 0x01, + 0x0b, 0x09, 0x80, 0x00, 0x30, 0x00, 0x00, 0x12, 0x24, 0x09, 0x24, 0x09, 0x00, 0x01, + 0x0e, 0x07, 0x80, 0x00, 0x10, 0x00, 0x00, 0x13, 0xe4, 0x89, 0xc4, 0x89, 0xf9, 0x01, + 0x06, 0x1e, 0x40, 0x10, 0x10, 0x00, 0x00, 0x10, 0x05, 0xc8, 0x09, 0xc8, 0x0b, 0x81, + 0x06, 0x00, 0x40, 0x20, 0x10, 0x00, 0x00, 0x0f, 0xf8, 0x8f, 0xf0, 0x8f, 0xf9, 0x01, + 0x03, 0x80, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x01, 0xff, 0xff, 0xff, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +}; diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/makibox/Configuration.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/makibox/Configuration.h new file mode 100644 index 00000000..8e530c54 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/makibox/Configuration.h @@ -0,0 +1,1703 @@ +/** + * 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 . + * + */ + +/** + * Configuration.h + * + * Basic settings such as: + * + * - Type of electronics + * - Type of temperature sensor + * - Printer geometry + * - Endstop configuration + * - LCD controller + * - Extra features + * + * Advanced settings can be found in Configuration_adv.h + * + */ +#ifndef CONFIGURATION_H +#define CONFIGURATION_H +#define CONFIGURATION_H_VERSION 010100 + +//=========================================================================== +//============================= Getting Started ============================= +//=========================================================================== + +/** + * Here are some standard links for getting your machine calibrated: + * + * http://reprap.org/wiki/Calibration + * http://youtu.be/wAL9d7FgInk + * http://calculator.josefprusa.cz + * http://reprap.org/wiki/Triffid_Hunter%27s_Calibration_Guide + * http://www.thingiverse.com/thing:5573 + * https://sites.google.com/site/repraplogphase/calibration-of-your-reprap + * http://www.thingiverse.com/thing:298812 + */ + +//=========================================================================== +//============================= DELTA Printer =============================== +//=========================================================================== +// For a Delta printer start with one of the configuration files in the +// example_configurations/delta directory and customize for your machine. +// + +//=========================================================================== +//============================= SCARA Printer =============================== +//=========================================================================== +// For a SCARA printer start with the configuration files in +// example_configurations/SCARA and customize for your machine. +// + +// @section info + +// User-specified version info of this build to display in [Pronterface, etc] terminal window during +// startup. Implementation of an idea by Prof Braino to inform user that any changes made to this +// build by the user have been successfully uploaded into firmware. +#define STRING_CONFIG_H_AUTHOR "(none, default config)" // Who made the changes. +#define SHOW_BOOTSCREEN +#define STRING_SPLASH_LINE1 SHORT_BUILD_VERSION // will be shown during bootup in line 1 +#define STRING_SPLASH_LINE2 WEBSITE_URL // will be shown during bootup in line 2 + +// +// *** VENDORS PLEASE READ ***************************************************** +// +// Marlin now allow you to have a vendor boot image to be displayed on machine +// start. When SHOW_CUSTOM_BOOTSCREEN is defined Marlin will first show your +// custom boot image and then the default Marlin boot image is shown. +// +// We suggest for you to take advantage of this new feature and keep the Marlin +// boot image unmodified. For an example have a look at the bq Hephestos 2 +// example configuration folder. +// +//#define SHOW_CUSTOM_BOOTSCREEN +// @section machine + +/** + * Select which serial port on the board will be used for communication with the host. + * This allows the connection of wireless adapters (for instance) to non-default port pins. + * Serial port 0 is always used by the Arduino bootloader regardless of this setting. + * + * :[0, 1, 2, 3, 4, 5, 6, 7] + */ +#define SERIAL_PORT 0 + +/** + * This setting determines the communication speed of the printer. + * + * 250000 works in most cases, but you might try a lower speed if + * you commonly experience drop-outs during host printing. + * You may try up to 1000000 to speed up SD file transfer. + * + * :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000] + */ +#define BAUDRATE 250000 + +// Enable the Bluetooth serial interface on AT90USB devices +//#define BLUETOOTH + +// The following define selects which electronics board you have. +// Please choose the name from boards.h that matches your setup +#ifndef MOTHERBOARD + #define MOTHERBOARD BOARD_5DPRINT +#endif + +// Optional custom name for your RepStrap or other custom machine +// Displayed in the LCD "Ready" message +//#define CUSTOM_MACHINE_NAME "3D Printer" + +// Define this to set a unique identifier for this printer, (Used by some programs to differentiate between machines) +// You can use an online service to generate a random UUID. (eg http://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] +#define EXTRUDERS 1 + +// For Cyclops or any "multi-extruder" that shares a single nozzle. +//#define SINGLENOZZLE + +/** + * Průša MK2 Single Nozzle Multi-Material Multiplexer, and variants. + * + * This device allows one stepper driver on a control board to drive + * two to eight stepper motors, one at a time, in a manner suitable + * for extruders. + * + * This option only allows the multiplexer to switch on tool-change. + * Additional options to configure custom E moves are pending. + */ +//#define MK2_MULTIPLEXER +#if ENABLED(MK2_MULTIPLEXER) + // Override the default DIO selector pins here, if needed. + // Some pins files may provide defaults for these pins. + //#define E_MUX0_PIN 40 // Always Required + //#define E_MUX1_PIN 42 // Needed for 3 to 8 steppers + //#define E_MUX2_PIN 44 // Needed for 5 to 8 steppers +#endif + +// A dual extruder that uses a single stepper motor +//#define SWITCHING_EXTRUDER +#if ENABLED(SWITCHING_EXTRUDER) + #define SWITCHING_EXTRUDER_SERVO_NR 0 + #define SWITCHING_EXTRUDER_SERVO_ANGLES { 0, 90 } // Angles for E0, E1[, E2, E3] + #if EXTRUDERS > 3 + #define SWITCHING_EXTRUDER_E23_SERVO_NR 1 + #endif +#endif + +// A dual-nozzle that uses a servomotor to raise/lower one of the nozzles +//#define SWITCHING_NOZZLE +#if ENABLED(SWITCHING_NOZZLE) + #define SWITCHING_NOZZLE_SERVO_NR 0 + #define SWITCHING_NOZZLE_SERVO_ANGLES { 0, 90 } // Angles for E0, E1 + //#define HOTEND_OFFSET_Z { 0.0, 0.0 } +#endif + +/** + * Two separate X-carriages with extruders that connect to a moving part + * via a magnetic docking mechanism. Requires SOL1_PIN and SOL2_PIN. + */ +//#define PARKING_EXTRUDER +#if ENABLED(PARKING_EXTRUDER) + #define PARKING_EXTRUDER_SOLENOIDS_INVERT // If enabled, the solenoid is NOT magnetized with applied voltage + #define PARKING_EXTRUDER_SOLENOIDS_PINS_ACTIVE LOW // LOW or HIGH pin signal energizes the coil + #define PARKING_EXTRUDER_SOLENOIDS_DELAY 250 // Delay (ms) for magnetic field. No delay if 0 or not defined. + #define PARKING_EXTRUDER_PARKING_X { -78, 184 } // X positions for parking the extruders + #define PARKING_EXTRUDER_GRAB_DISTANCE 1 // mm to move beyond the parking point to grab the extruder + #define PARKING_EXTRUDER_SECURITY_RAISE 5 // Z-raise before parking + #define HOTEND_OFFSET_Z { 0.0, 1.3 } // Z-offsets of the two hotends. The first must be 0. +#endif + +/** + * "Mixing Extruder" + * - Adds a new code, M165, to set the current mix factors. + * - Extends the stepping routines to move multiple steppers in proportion to the mix. + * - Optional support for Repetier Firmware M163, M164, and virtual extruder. + * - This implementation supports only a single extruder. + * - Enable DIRECT_MIXING_IN_G1 for Pia Taubert's reference implementation + */ +//#define MIXING_EXTRUDER +#if ENABLED(MIXING_EXTRUDER) + #define MIXING_STEPPERS 2 // Number of steppers in your mixing extruder + #define MIXING_VIRTUAL_TOOLS 16 // Use the Virtual Tool method with M163 and M164 + //#define DIRECT_MIXING_IN_G1 // Allow ABCDHI mix factors in G1 movement commands +#endif + +// Offset of the extruders (uncomment if using more than one and relying on firmware to position when changing). +// The offset has to be X=0, Y=0 for the extruder 0 hotend (default extruder). +// For the other hotends it is their distance from the extruder 0 hotend. +//#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis +//#define HOTEND_OFFSET_Y {0.0, 5.00} // (in mm) for each extruder, offset of the hotend on the Y axis + +// @section machine + +/** + * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN + * + * 0 = No Power Switch + * 1 = ATX + * 2 = X-Box 360 203Watts (the blue wire connected to PS_ON and the red wire to VCC) + * + * :{ 0:'No power switch', 1:'ATX', 2:'X-Box 360' } + */ +#define POWER_SUPPLY 1 + +#if POWER_SUPPLY > 0 + // Enable this option to leave the PSU off at startup. + // Power to steppers and heaters will need to be turned on with M80. + //#define PS_DEFAULT_OFF +#endif + +// @section temperature + +//=========================================================================== +//============================= Thermal Settings ============================ +//=========================================================================== + +/** + * --NORMAL IS 4.7kohm PULLUP!-- 1kohm pullup can be used on hotend sensor, using correct resistor and table + * + * Temperature sensors available: + * + * -3 : thermocouple with MAX31855 (only for sensor 0) + * -2 : thermocouple with MAX6675 (only for sensor 0) + * -1 : thermocouple with AD595 + * 0 : not used + * 1 : 100k thermistor - best choice for EPCOS 100k (4.7k pullup) + * 2 : 200k thermistor - ATC Semitec 204GT-2 (4.7k pullup) + * 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 (Used in ParCan & J-Head) (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) + * 71 : 100k Honeywell thermistor 135-104LAF-J01 (4.7k pullup) + * 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) + * 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" + * 20 : the PT100 circuit found in the Ultimainboard V2.x + * 60 : 100k Maker's Tool Works Kapton Bed Thermistor beta=3950 + * 66 : 4.7M High Temperature thermistor from Dyze Design + * 70 : the 100K thermistor found in the bq Hephestos 2 + * 75 : 100k Generic Silicon Heat Pad with NTC 100K MGB18-104F39050L32 thermistor + * + * 1k ohm pullup tables - This is atypical, and requires changing out the 4.7k pullup for 1k. + * (but gives greater accuracy and more stable PID) + * 51 : 100k thermistor - EPCOS (1k pullup) + * 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 + * 1010 : Pt1000 with 1k pullup (non standard) + * 147 : Pt100 with 4k7 pullup + * 110 : Pt100 with 1k pullup (non standard) + * + * Use these for Testing or Development purposes. NEVER for production machine. + * 998 : Dummy Table that ALWAYS reads 25°C or the temperature defined below. + * 999 : Dummy Table that ALWAYS reads 100°C or the temperature defined below. + * + * :{ '0': "Not used", '1':"100k / 4.7k - EPCOS", '2':"200k / 4.7k - ATC Semitec 204GT-2", '3':"Mendel-parts / 4.7k", '4':"10k !! do not use for a hotend. Bad resolution at high temp. !!", '5':"100K / 4.7k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '6':"100k / 4.7k EPCOS - Not as accurate as Table 1", '7':"100k / 4.7k Honeywell 135-104LAG-J01", '8':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT", '9':"100k / 4.7k GE Sensing AL03006-58.2K-97-G1", '10':"100k / 4.7k RS 198-961", '11':"100k / 4.7k beta 3950 1%", '12':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT (calibrated for Makibox hot bed)", '13':"100k Hisens 3950 1% up to 300°C for hotend 'Simple ONE ' & hotend 'All In ONE'", '20':"PT100 (Ultimainboard V2.x)", '51':"100k / 1k - EPCOS", '52':"200k / 1k - ATC Semitec 204GT-2", '55':"100k / 1k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '60':"100k Maker's Tool Works Kapton Bed Thermistor beta=3950", '66':"Dyze Design 4.7M High Temperature thermistor", '70':"the 100K thermistor found in the bq Hephestos 2", '71':"100k / 4.7k Honeywell 135-104LAF-J01", '147':"Pt100 / 4.7k", '1047':"Pt1000 / 4.7k", '110':"Pt100 / 1k (non-standard)", '1010':"Pt1000 / 1k (non standard)", '-3':"Thermocouple + MAX31855 (only for sensor 0)", '-2':"Thermocouple + MAX6675 (only for sensor 0)", '-1':"Thermocouple + AD595",'998':"Dummy 1", '999':"Dummy 2" } + */ +#define TEMP_SENSOR_0 1 +#define TEMP_SENSOR_1 0 +#define TEMP_SENSOR_2 0 +#define TEMP_SENSOR_3 0 +#define TEMP_SENSOR_4 0 +#define TEMP_SENSOR_BED 12 + +// Dummy thermistor constant temperature readings, for use with 998 and 999 +#define DUMMY_THERMISTOR_998_VALUE 25 +#define DUMMY_THERMISTOR_999_VALUE 100 + +// 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 +#define MAX_REDUNDANT_TEMP_SENSOR_DIFF 10 + +// Extruder temperature must be close to target for this long before M109 returns success +#define TEMP_RESIDENCY_TIME 10 // (seconds) +#define TEMP_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// Bed temperature must be close to target for this long before M190 returns success +#define TEMP_BED_RESIDENCY_TIME 0 // (seconds) +#define TEMP_BED_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_BED_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// The minimal temperature defines the temperature below which the heater will not be enabled It is used +// to check that the wiring to the thermistor is not broken. +// Otherwise this would lead to the heater being powered on all the time. +#define HEATER_0_MINTEMP 5 +#define HEATER_1_MINTEMP 5 +#define HEATER_2_MINTEMP 5 +#define HEATER_3_MINTEMP 5 +#define HEATER_4_MINTEMP 5 +#define BED_MINTEMP 5 + +// When temperature exceeds max temp, your heater will be switched off. +// This feature exists to protect your hotend from overheating accidentally, but *NOT* from thermistor short/failure! +// You should use MINTEMP for thermistor short/failure protection. +#define HEATER_0_MAXTEMP 275 +#define HEATER_1_MAXTEMP 275 +#define HEATER_2_MAXTEMP 275 +#define HEATER_3_MAXTEMP 275 +#define HEATER_4_MAXTEMP 275 +#define BED_MAXTEMP 150 + +//=========================================================================== +//============================= PID Settings ================================ +//=========================================================================== +// PID Tuning Guide here: http://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 +#if ENABLED(PIDTEMP) + //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. + //#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. + #define K1 0.95 //smoothing factor within the PID + + // 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 + +#endif // PIDTEMP + +//=========================================================================== +//============================= PID > Bed Temperature Control =============== +//=========================================================================== +// Select PID or bang-bang with PIDTEMPBED. If bang-bang, BED_LIMIT_SWITCHING will enable hysteresis +// +// Uncomment this to enable PID on the bed. It uses the same frequency PWM as the extruder. +// If your PID_dT is the default, and correct for your hardware/configuration, that means 7.689Hz, +// which is fine for driving a square wave into a resistive load and does not significantly impact you FET heating. +// This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W heater. +// If your configuration is significantly different than this and you don't understand the issues involved, you probably +// shouldn't use bed PID until someone else verifies your hardware works. +// If this is enabled, find your own PID constants below. +//#define PIDTEMPBED + +//#define BED_LIMIT_SWITCHING + +// This sets the max power delivered to the bed, and replaces the HEATER_BED_DUTY_CYCLE_DIVIDER option. +// all forms of bed control obey this (PID, bang-bang, bang-bang with hysteresis) +// setting this to anything other than 255 enables a form of PWM to the bed just like HEATER_BED_DUTY_CYCLE_DIVIDER did, +// so you shouldn't use it unless you are OK with PWM on your bed. (see the comment on enabling PIDTEMPBED) +#define MAX_BED_POWER 175 // limits duty cycle to bed; 255=full current +// This limit is set to 175 by default in the Makibox configuration and it can be adjusted +// to increase the heatup rate. However, if changed, be aware of the safety concerns of +// drawing too much current from the power supply. + +#if ENABLED(PIDTEMPBED) + + //#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) + #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 + +// @section extruder + +// This option prevents extrusion if the temperature is below EXTRUDE_MINTEMP. +// It also enables the M302 command to set the minimum extrusion temperature +// or to allow moving the extruder regardless of the hotend temperature. +// *** IT IS HIGHLY RECOMMENDED TO LEAVE THIS OPTION ENABLED! *** +#define PREVENT_COLD_EXTRUSION +#define EXTRUDE_MINTEMP 170 + +// This option prevents a single extrusion longer than EXTRUDE_MAXLENGTH. +// Note that for Bowden Extruders a too-small value here may prevent loading. +#define PREVENT_LENGTHY_EXTRUDE +#define EXTRUDE_MAXLENGTH 200 + +//=========================================================================== +//======================== Thermal Runaway Protection ======================= +//=========================================================================== + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * If you get "Thermal Runaway" or "Heating failed" errors the + * details can be tuned in Configuration_adv.h + */ + +#define THERMAL_PROTECTION_HOTENDS // Enable thermal protection for all extruders +#define THERMAL_PROTECTION_BED // Enable thermal protection for the heated bed + +//=========================================================================== +//============================= Mechanical Settings ========================= +//=========================================================================== + +// @section machine + +// Uncomment one of these options to enable CoreXY, CoreXZ, or CoreYZ kinematics +// either in the usual order or reversed +//#define COREXY +//#define COREXZ +//#define COREYZ +//#define COREYX +//#define COREZX +//#define COREZY + +//=========================================================================== +//============================== Endstop Settings =========================== +//=========================================================================== + +// @section homing + +// Specify here all the endstop connectors that are connected to any endstop or probe. +// Almost all printers will be using one per axis. Probes will use one or more of the +// extra connectors. Leave undefined any used for non-endstop and non-probe purposes. +#define USE_XMIN_PLUG +#define USE_YMIN_PLUG +#define USE_ZMIN_PLUG +//#define USE_XMAX_PLUG +//#define USE_YMAX_PLUG +//#define USE_ZMAX_PLUG + +// coarse Endstop Settings +#define ENDSTOPPULLUPS // Comment this out (using // at the start of the line) to disable the endstop pullup resistors + +#if DISABLED(ENDSTOPPULLUPS) + // fine endstop settings: Individual pullups. will be ignored if ENDSTOPPULLUPS is defined + //#define ENDSTOPPULLUP_XMAX + //#define ENDSTOPPULLUP_YMAX + //#define ENDSTOPPULLUP_ZMAX + //#define ENDSTOPPULLUP_XMIN + //#define ENDSTOPPULLUP_YMIN + //#define ENDSTOPPULLUP_ZMIN + //#define ENDSTOPPULLUP_ZMIN_PROBE +#endif + +// Mechanical endstop with COM to ground and NC to Signal uses "false" here (most common setup). +#define X_MIN_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Y_MIN_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MIN_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define X_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Y_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MIN_PROBE_ENDSTOP_INVERTING false // set to true to invert the logic of the probe. + +// Enable this feature if all enabled endstop pins are interrupt-capable. +// This will remove the need to poll the interrupt pins, saving many CPU cycles. +//#define ENDSTOP_INTERRUPTS_FEATURE + +//============================================================================= +//============================== Movement Settings ============================ +//============================================================================= +// @section motion + +/** + * Default Settings + * + * These settings can be reset by M502 + * + * Note that if EEPROM is enabled, saved values will override these. + */ + +/** + * With this option each E stepper can have its own factors for the + * following movement settings. If fewer factors are given than the + * total number of extruders, the last value applies to the rest. + */ +//#define DISTINCT_E_FACTORS + +/** + * Default Axis Steps Per Unit (steps/mm) + * Override with M92 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_AXIS_STEPS_PER_UNIT { 400, 400, 400, 163 } // default steps per unit for ***** MakiBox A6 ***** + +/** + * Default Max Feed Rate (mm/s) + * Override with M203 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_FEEDRATE { 60, 60, 20, 45 } + +/** + * Default Max Acceleration (change/s) change = mm/s + * (Maximum start speed for accelerated moves) + * Override with M201 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_ACCELERATION { 2000, 2000, 30, 10000 } + +/** + * Default Acceleration (change/s) change = mm/s + * Override with M204 + * + * M204 P Acceleration + * M204 R Retract Acceleration + * M204 T Travel Acceleration + */ +#define DEFAULT_ACCELERATION 3000 // X, Y, Z and E acceleration for printing moves +#define DEFAULT_RETRACT_ACCELERATION 3000 // E acceleration for retracts +#define DEFAULT_TRAVEL_ACCELERATION 3000 // X, Y, Z acceleration for travel (non printing) moves + +/** + * Default Jerk (mm/s) + * Override with M205 X Y Z E + * + * "Jerk" specifies the minimum speed change that requires acceleration. + * When changing speed and direction, if the difference is less than the + * value set here, it may happen instantaneously. + */ +#define DEFAULT_XJERK 20.0 +#define DEFAULT_YJERK 20.0 +#define DEFAULT_ZJERK 0.4 +#define DEFAULT_EJERK 5.0 + +//=========================================================================== +//============================= Z Probe Options ============================= +//=========================================================================== +// @section probes + +// +// See http://marlinfw.org/configuration/probes.html +// + +/** + * Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + * + * Enable this option for a probe connected to the Z Min endstop pin. + */ +#define Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + +/** + * Z_MIN_PROBE_ENDSTOP + * + * Enable this option for a probe connected to any pin except Z-Min. + * (By default Marlin assumes the Z-Max endstop pin.) + * To use a custom Z Probe pin, set Z_MIN_PROBE_PIN below. + * + * - The simplest option is to use a free endstop connector. + * - Use 5V for powered (usually inductive) sensors. + * + * - RAMPS 1.3/1.4 boards may use the 5V, GND, and Aux4->D32 pin: + * - For simple switches connect... + * - normally-closed switches to GND and D32. + * - normally-open switches to 5V and D32. + * + * WARNING: Setting the wrong pin may have unexpected and potentially + * disastrous consequences. Use with caution and do your homework. + * + */ +//#define Z_MIN_PROBE_ENDSTOP + +/** + * Probe Type + * + * Allen Key Probes, Servo Probes, Z-Sled Probes, FIX_MOUNTED_PROBE, etc. + * Activate one of these to use Auto Bed Leveling below. + */ + +/** + * The "Manual Probe" provides a means to do "Auto" Bed Leveling without a probe. + * Use G29 repeatedly, adjusting the Z height at each point with movement commands + * or (with LCD_BED_LEVELING) the LCD controller. + */ +//#define PROBE_MANUALLY + +/** + * A Fix-Mounted Probe either doesn't deploy or needs manual deployment. + * (e.g., an inductive probe or a nozzle-based probe-switch.) + */ +//#define FIX_MOUNTED_PROBE + +/** + * Z Servo Probe, such as an endstop switch on a rotating arm. + */ +//#define Z_ENDSTOP_SERVO_NR 0 // Defaults to SERVO 0 connector. +//#define Z_SERVO_ANGLES {70,0} // Z Servo Deploy and Stow angles + +/** + * The BLTouch probe uses a Hall effect sensor and emulates a servo. + */ +//#define BLTOUCH +#if ENABLED(BLTOUCH) + //#define BLTOUCH_DELAY 375 // (ms) Enable and increase if needed +#endif + +/** + * Enable one or more of the following if probing seems unreliable. + * Heaters and/or fans can be disabled during probing to minimize electrical + * noise. A delay can also be added to allow noise and vibration to settle. + * These options are most useful for the BLTouch probe, but may also improve + * readings with inductive probes and piezo sensors. + */ +//#define PROBING_HEATERS_OFF // Turn heaters off when probing +//#define PROBING_FANS_OFF // Turn fans off when probing +//#define DELAY_BEFORE_PROBING 200 // (ms) To prevent vibrations from triggering piezo sensors + +// A probe that is deployed and stowed with a solenoid pin (SOL1_PIN) +//#define SOLENOID_PROBE + +// A sled-mounted probe like those designed by Charles Bell. +//#define Z_PROBE_SLED +//#define SLED_DOCKING_OFFSET 5 // The extra distance the X axis must travel to pickup the sled. 0 should be fine but you can push it further if you'd like. + +// +// For Z_PROBE_ALLEN_KEY see the Delta example configurations. +// + +/** + * Z Probe to nozzle (X,Y) offset, relative to (0, 0). + * X and Y offsets must be integers. + * + * In the following example the X and Y offsets are both positive: + * #define X_PROBE_OFFSET_FROM_EXTRUDER 10 + * #define Y_PROBE_OFFSET_FROM_EXTRUDER 10 + * + * +-- BACK ---+ + * | | + * L | (+) P | R <-- probe (20,20) + * E | | I + * F | (-) N (+) | G <-- nozzle (10,10) + * T | | H + * | (-) | T + * | | + * O-- FRONT --+ + * (0,0) + */ +#define X_PROBE_OFFSET_FROM_EXTRUDER -25 // X offset: -left +right [of the nozzle] +#define Y_PROBE_OFFSET_FROM_EXTRUDER -29 // Y offset: -front +behind [the nozzle] +#define Z_PROBE_OFFSET_FROM_EXTRUDER -12.35 // Z offset: -below +above [the nozzle] + +// X and Y axis travel speed (mm/m) between probes +#define XY_PROBE_SPEED 8000 + +// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +#define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z + +// Speed for the "accurate" probe of each point +#define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) + +// Use double touch for probing +//#define PROBE_DOUBLE_TOUCH + +/** + * Z probes require clearance when deploying, stowing, and moving between + * probe points to avoid hitting the bed and other hardware. + * Servo-mounted probes require extra space for the arm to rotate. + * Inductive probes need space to keep from triggering early. + * + * Use these settings to specify the distance (mm) to raise the probe (or + * lower the bed). The values set here apply over and above any (negative) + * probe Z Offset set with Z_PROBE_OFFSET_FROM_EXTRUDER, M851, or the LCD. + * Only integer values >= 1 are valid here. + * + * Example: `M851 Z-5` with a CLEARANCE of 4 => 9mm from bed to nozzle. + * But: `M851 Z+1` with a CLEARANCE of 2 => 2mm from bed to nozzle. + */ +#define Z_CLEARANCE_DEPLOY_PROBE 15 // Z Clearance for Deploy/Stow +#define Z_CLEARANCE_BETWEEN_PROBES 5 // Z Clearance between probe points + +// For M851 give a range for adjusting the Z probe offset +#define Z_PROBE_OFFSET_RANGE_MIN -20 +#define Z_PROBE_OFFSET_RANGE_MAX 20 + +// Enable the M48 repeatability test to test probe accuracy +//#define Z_MIN_PROBE_REPEATABILITY_TEST + +// For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1 +// :{ 0:'Low', 1:'High' } +#define X_ENABLE_ON 0 +#define Y_ENABLE_ON 0 +#define Z_ENABLE_ON 0 +#define E_ENABLE_ON 0 // For all extruders + +// Disables axis stepper immediately when it's not being used. +// 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 +//#define DISABLE_REDUCED_ACCURACY_WARNING + +// @section extruder + +#define DISABLE_E false // For all extruders +#define DISABLE_INACTIVE_EXTRUDER true // Keep only the active extruder enabled. + +// @section machine + +// Invert the stepper direction. Change (or reverse the motor connector) if an axis goes the wrong way. +#define INVERT_X_DIR false +#define INVERT_Y_DIR false +#define INVERT_Z_DIR false + +// Enable this option for Toshiba stepper drivers +//#define CONFIG_STEPPERS_TOSHIBA + +// @section extruder + +// For direct drive extruder v9 set to true, for geared extruder set to false. +#define INVERT_E0_DIR true +#define INVERT_E1_DIR false +#define INVERT_E2_DIR false +#define INVERT_E3_DIR false +#define INVERT_E4_DIR false + +// @section homing + +//#define NO_MOTION_BEFORE_HOMING // Inhibit movement until all axes have been homed + +//#define Z_HOMING_HEIGHT 4 // (in mm) Minimal z height before homing (G28) for Z clearance above the bed, clamps, ... + // Be sure you have this distance over your Z_MAX_POS in case. + +// Direction of endstops when homing; 1=MAX, -1=MIN +// :[-1,1] +#define X_HOME_DIR -1 +#define Y_HOME_DIR -1 +#define Z_HOME_DIR -1 + +// @section machine + +// The size of the print bed +#define X_BED_SIZE 110 +#define Y_BED_SIZE 150 + +// Travel limits (mm) after homing, corresponding to endstop positions. +#define X_MIN_POS 0 +#define Y_MIN_POS 0 +#define Z_MIN_POS 0 +#define X_MAX_POS X_BED_SIZE +#define Y_MAX_POS Y_BED_SIZE +#define Z_MAX_POS 86 + +// If enabled, axes won't move below MIN_POS in response to movement commands. +#define MIN_SOFTWARE_ENDSTOPS +// If enabled, axes won't move above MAX_POS in response to movement commands. +#define MAX_SOFTWARE_ENDSTOPS + +/** + * Filament Runout Sensor + * A mechanical or opto endstop is used to check for the presence of filament. + * + * RAMPS-based boards use SERVO3_PIN. + * For other boards you may need to define FIL_RUNOUT_PIN. + * By default the firmware assumes HIGH = has filament, LOW = ran out + */ +//#define FILAMENT_RUNOUT_SENSOR +#if ENABLED(FILAMENT_RUNOUT_SENSOR) + #define FIL_RUNOUT_INVERTING false // set to true to invert the logic of the sensor. + #define ENDSTOPPULLUP_FIL_RUNOUT // Uncomment to use internal pullup for filament runout pins if the sensor is defined. + #define FILAMENT_RUNOUT_SCRIPT "M600" +#endif + +//=========================================================================== +//=============================== Bed Leveling ============================== +//=========================================================================== +// @section bedlevel + +/** + * Choose one of the options below to enable G29 Bed Leveling. The parameters + * and behavior of G29 will change depending on your selection. + * + * If using a Probe for Z Homing, enable Z_SAFE_HOMING also! + * + * - AUTO_BED_LEVELING_3POINT + * Probe 3 arbitrary points on the bed (that aren't collinear) + * You specify the XY coordinates of all 3 points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_LINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_BILINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a mesh, best for large or uneven beds. + * + * - AUTO_BED_LEVELING_UBL (Unified Bed Leveling) + * A comprehensive bed leveling system combining the features and benefits + * of other systems. UBL also includes integrated Mesh Generation, Mesh + * Validation and Mesh Editing systems. Currently, UBL is only checked out + * for Cartesian Printers. That said, it was primarily designed to correct + * poor quality Delta Printers. If you feel adventurous and have a Delta, + * please post an issue if something doesn't work correctly. Initially, + * you will need to set a reduced bed size so you have a rectangular area + * to test on. + * + * - MESH_BED_LEVELING + * Probe a grid manually + * The result is a mesh, suitable for large or uneven beds. (See BILINEAR.) + * For machines without a probe, Mesh Bed Leveling provides a method to perform + * leveling in steps so you can manually adjust the Z height at each grid-point. + * With an LCD controller the process is guided step-by-step. + */ +//#define AUTO_BED_LEVELING_3POINT +//#define AUTO_BED_LEVELING_LINEAR +//#define AUTO_BED_LEVELING_BILINEAR +//#define AUTO_BED_LEVELING_UBL +//#define MESH_BED_LEVELING + +/** + * Enable detailed logging of G28, G29, M48, etc. + * Turn on with the command 'M111 S32'. + * NOTE: Requires a lot of PROGMEM! + */ +//#define DEBUG_LEVELING_FEATURE + +#if ENABLED(MESH_BED_LEVELING) || ENABLED(AUTO_BED_LEVELING_BILINEAR) || ENABLED(AUTO_BED_LEVELING_UBL) + // Gradually reduce leveling correction until a set height is reached, + // at which point movement will be level to the machine's XY plane. + // The height can be set with M420 Z + #define ENABLE_LEVELING_FADE_HEIGHT +#endif + +#if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Set the number of grid points per dimension. + #define GRID_MAX_POINTS_X 3 + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + // Set the boundaries for probing (where the probe can reach). + #define LEFT_PROBE_BED_POSITION 15 + #define RIGHT_PROBE_BED_POSITION 170 + #define FRONT_PROBE_BED_POSITION 20 + #define BACK_PROBE_BED_POSITION 170 + + // The Z probe minimum outer margin (to validate G29 parameters). + #define MIN_PROBE_EDGE 10 + + // Probe along the Y axis, advancing X after each column + //#define PROBE_Y_FIRST + + #if ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Beyond the probed grid, continue the implied tilt? + // Default is to maintain the height of the nearest edge. + //#define EXTRAPOLATE_BEYOND_GRID + + // + // Experimental Subdivision of the grid by Catmull-Rom method. + // Synthesizes intermediate points to produce a more detailed mesh. + // + //#define ABL_BILINEAR_SUBDIVISION + #if ENABLED(ABL_BILINEAR_SUBDIVISION) + // Number of subdivisions between probe points + #define BILINEAR_SUBDIVISIONS 3 + #endif + + #endif + +#elif ENABLED(AUTO_BED_LEVELING_3POINT) + + // 3 arbitrary points to probe. + // A simple cross-product is used to estimate the plane of the bed. + #define ABL_PROBE_PT_1_X 15 + #define ABL_PROBE_PT_1_Y 180 + #define ABL_PROBE_PT_2_X 15 + #define ABL_PROBE_PT_2_Y 20 + #define ABL_PROBE_PT_3_X 170 + #define ABL_PROBE_PT_3_Y 20 + +#elif ENABLED(AUTO_BED_LEVELING_UBL) + + //=========================================================================== + //========================= Unified Bed Leveling ============================ + //=========================================================================== + + #define UBL_MESH_INSET 1 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 10 // Don't use more than 15 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + #define UBL_PROBE_PT_1_X 39 // Probing points for 3-Point leveling of the mesh + #define UBL_PROBE_PT_1_Y 180 + #define UBL_PROBE_PT_2_X 39 + #define UBL_PROBE_PT_2_Y 20 + #define UBL_PROBE_PT_3_X 180 + #define UBL_PROBE_PT_3_Y 20 + + #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation + #define UBL_MESH_EDIT_MOVES_Z // Sophisticated users prefer no movement of nozzle + +#elif ENABLED(MESH_BED_LEVELING) + + //=========================================================================== + //=================================== Mesh ================================== + //=========================================================================== + + #define MESH_INSET 10 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 3 // Don't use more than 7 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + //#define MESH_G28_REST_ORIGIN // After homing all axes ('G28' or 'G28 XYZ') rest Z at Z_MIN_POS + +#endif // BED_LEVELING + +/** + * Use the LCD controller for bed leveling + * Requires MESH_BED_LEVELING or PROBE_MANUALLY + */ +//#define LCD_BED_LEVELING + +#if ENABLED(LCD_BED_LEVELING) + #define MBL_Z_STEP 0.025 // Step size while manually probing Z axis. + #define LCD_PROBE_Z_RANGE 4 // Z Range centered on Z_MIN_POS for LCD Z adjustment +#endif + +// Add a menu item to move between bed corners for manual bed adjustment +//#define LEVEL_BED_CORNERS + +/** + * Commands to execute at the end of G29 probing. + * Useful to retract or move the Z probe out of the way. + */ +//#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) +//#define BED_CENTER_AT_0_0 + +// Manually set the home position. Leave these undefined for automatic settings. +// For DELTA this is the top-center of the Cartesian print volume. +//#define MANUAL_X_HOME_POS 0 +//#define MANUAL_Y_HOME_POS 0 +//#define MANUAL_Z_HOME_POS 0 + +// Use "Z Safe Homing" to avoid homing with a Z probe outside the bed area. +// +// With this feature enabled: +// +// - 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). +// - 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 axis (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). +#endif + +// Homing speeds (mm/m) +#define HOMING_FEEDRATE_XY 1500 +#define HOMING_FEEDRATE_Z (2*60) + +//============================================================================= +//============================= Additional Features =========================== +//============================================================================= + +// @section extras + +// +// EEPROM +// +// The microcontroller can store settings in the EEPROM, e.g. max velocity... +// M500 - stores parameters in EEPROM +// M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily). +// M502 - reverts to the default "factory settings". You still need to store them in EEPROM afterwards if you want to. +// +#define EEPROM_SETTINGS // Enable for M500 and M501 commands +//#define DISABLE_M503 // Saves ~2700 bytes of PROGMEM. Disable for release! +#define EEPROM_CHITCHAT // Give feedback on EEPROM commands. Disable to save PROGMEM. + +// +// Host Keepalive +// +// When enabled Marlin will send a busy status message to the host +// every couple of seconds when it can't accept commands. +// +#define HOST_KEEPALIVE_FEATURE // Disable this if your host doesn't like keepalive messages +#define DEFAULT_KEEPALIVE_INTERVAL 2 // Number of seconds between "busy" messages. Set with M113. +#define BUSY_WHILE_HEATING // Some hosts require "busy" messages even during heating + +// +// M100 Free Memory Watcher +// +//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose + +// +// G20/G21 Inch mode support +// +//#define INCH_MODE_SUPPORT + +// +// M149 Set temperature units support +// +//#define TEMPERATURE_UNITS_SUPPORT + +// @section temperature + +// Preheat Constants +#define PREHEAT_1_TEMP_HOTEND 180 +#define PREHEAT_1_TEMP_BED 70 +#define PREHEAT_1_FAN_SPEED 255 // Value from 0 to 255 + +#define PREHEAT_2_TEMP_HOTEND 240 +#define PREHEAT_2_TEMP_BED 100 +#define PREHEAT_2_FAN_SPEED 255 // Value from 0 to 255 + +/** + * Nozzle Park -- EXPERIMENTAL + * + * Park the nozzle at the given XYZ position on idle or G27. + * + * The "P" parameter controls the action applied to the Z axis: + * + * P0 (Default) If Z is below park Z raise the nozzle. + * P1 Raise the nozzle always to Z-park height. + * P2 Raise the nozzle by Z-park amount, limited to Z_MAX_POS. + */ +//#define NOZZLE_PARK_FEATURE + +#if ENABLED(NOZZLE_PARK_FEATURE) + // Specify a park position as { X, Y, Z } + #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 } +#endif + +/** + * Clean Nozzle Feature -- EXPERIMENTAL + * + * Adds the G12 command to perform a nozzle cleaning process. + * + * Parameters: + * P Pattern + * S Strokes / Repetitions + * T Triangles (P1 only) + * + * Patterns: + * P0 Straight line (default). This process requires a sponge type material + * at a fixed bed location. "S" specifies strokes (i.e. back-forth motions) + * between the start / end points. + * + * P1 Zig-zag pattern between (X0, Y0) and (X1, Y1), "T" specifies the + * number of zig-zag triangles to do. "S" defines the number of strokes. + * Zig-zags are done in whichever is the narrower dimension. + * For example, "G12 P1 S1 T3" will execute: + * + * -- + * | (X0, Y1) | /\ /\ /\ | (X1, Y1) + * | | / \ / \ / \ | + * A | | / \ / \ / \ | + * | | / \ / \ / \ | + * | (X0, Y0) | / \/ \/ \ | (X1, Y0) + * -- +--------------------------------+ + * |________|_________|_________| + * T1 T2 T3 + * + * P2 Circular pattern with middle at NOZZLE_CLEAN_CIRCLE_MIDDLE. + * "R" specifies the radius. "S" specifies the stroke count. + * Before starting, the nozzle moves to NOZZLE_CLEAN_START_POINT. + * + * Caveats: The ending Z should be the same as starting Z. + * Attention: EXPERIMENTAL. G-code arguments may change. + * + */ +//#define NOZZLE_CLEAN_FEATURE + +#if ENABLED(NOZZLE_CLEAN_FEATURE) + // Default number of pattern repetitions + #define NOZZLE_CLEAN_STROKES 12 + + // Default number of triangles + #define NOZZLE_CLEAN_TRIANGLES 3 + + // Specify positions as { X, Y, Z } + #define NOZZLE_CLEAN_START_POINT { 30, 30, (Z_MIN_POS + 1)} + #define NOZZLE_CLEAN_END_POINT {100, 60, (Z_MIN_POS + 1)} + + // Circular pattern radius + #define NOZZLE_CLEAN_CIRCLE_RADIUS 6.5 + // Circular pattern circle fragments number + #define NOZZLE_CLEAN_CIRCLE_FN 10 + // Middle point of circle + #define NOZZLE_CLEAN_CIRCLE_MIDDLE NOZZLE_CLEAN_START_POINT + + // Moves the nozzle to the initial position + #define NOZZLE_CLEAN_GOBACK +#endif + +/** + * Print Job Timer + * + * Automatically start and stop the print job timer on M104/M109/M190. + * + * M104 (hotend, no wait) - high temp = none, low temp = stop timer + * M109 (hotend, wait) - high temp = start timer, low temp = stop timer + * M190 (bed, wait) - high temp = start timer, low temp = none + * + * The timer can also be controlled with the following commands: + * + * M75 - Start the print job timer + * M76 - Pause the print job timer + * M77 - Stop the print job timer + */ +#define PRINTJOB_TIMER_AUTOSTART + +/** + * Print Counter + * + * Track statistical data such as: + * + * - Total print jobs + * - Total successful print jobs + * - Total failed print jobs + * - Total time printing + * + * View the current statistics with M78. + */ +//#define PRINTCOUNTER + +//============================================================================= +//============================= LCD and SD support ============================ +//============================================================================= + +// @section lcd + +/** + * LCD LANGUAGE + * + * Select the language to display on the LCD. These languages are available: + * + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, + * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * tr, uk, zh_CN, zh_TW, test + * + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + */ +//#define LCD_LANGUAGE en + +/** + * LCD Character Set + * + * Note: This option is NOT applicable to Graphical Displays. + * + * All character-based LCDs provide ASCII plus one of these + * language extensions: + * + * - JAPANESE ... the most common + * - WESTERN ... with more accented characters + * - CYRILLIC ... for the Russian language + * + * To determine the language extension installed on your controller: + * + * - Compile and upload with LCD_LANGUAGE set to 'test' + * - 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 + * + * :['JAPANESE', 'WESTERN', 'CYRILLIC'] + */ +#define DISPLAY_CHARSET_HD44780 JAPANESE + +/** + * LCD TYPE + * + * Enable ULTRA_LCD for a 16x2, 16x4, 20x2, or 20x4 character-based LCD. + * Enable DOGLCD for a 128x64 (ST7565R) Full Graphical Display. + * (These options will be enabled automatically for most displays.) + * + * IMPORTANT: The U8glib library is required for Full Graphic Display! + * https://github.com/olikraus/U8glib_Arduino + */ +//#define ULTRA_LCD // Character based +//#define DOGLCD // Full graphics display + +/** + * SD CARD + * + * 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 + +/** + * SD CARD: SPI SPEED + * + * Enable one of the following items for a slower SPI transfer speed. + * This may be required to resolve "volume init" errors. + */ +#define SPI_SPEED SPI_HALF_SPEED +//#define SPI_SPEED SPI_QUARTER_SPEED +//#define SPI_SPEED SPI_EIGHTH_SPEED + +/** + * SD CARD: ENABLE CRC + * + * Use CRC checks and retries on the SD communication. + */ +//#define SD_CHECK_AND_RETRY + +// +// ENCODER SETTINGS +// +// This option overrides the default number of encoder pulses needed to +// produce one step. Should be increased for high-resolution encoders. +// +//#define ENCODER_PULSES_PER_STEP 1 + +// +// Use this option to override the number of step signals required to +// move between next/prev menu items. +// +//#define ENCODER_STEPS_PER_MENU_ITEM 5 + +/** + * Encoder Direction Options + * + * Test your encoder's behavior first with both options disabled. + * + * Reversed Value Edit and Menu Nav? Enable REVERSE_ENCODER_DIRECTION. + * Reversed Menu Navigation only? Enable REVERSE_MENU_DIRECTION. + * Reversed Value Editing only? Enable BOTH options. + */ + +// +// This option reverses the encoder direction everywhere. +// +// Set this option if CLOCKWISE causes values to DECREASE +// +//#define REVERSE_ENCODER_DIRECTION + +// +// This option reverses the encoder direction for navigating LCD menus. +// +// If CLOCKWISE normally moves DOWN this makes it go UP. +// If CLOCKWISE normally moves UP this makes it go DOWN. +// +//#define REVERSE_MENU_DIRECTION + +// +// Individual Axis Homing +// +// Add individual axis homing items (Home X, Home Y, and Home Z) to the LCD menu. +// +//#define INDIVIDUAL_AXIS_HOMING_MENU + +// +// SPEAKER/BUZZER +// +// If you have a speaker that can produce tones, enable it here. +// By default Marlin assumes you have a buzzer with a fixed frequency. +// +//#define SPEAKER + +// +// The duration and frequency for the UI feedback sound. +// Set these to 0 to disable audio feedback in the LCD menus. +// +// Note: Test audio output with the G-Code: +// M300 S P +// +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 +//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 + +// +// CONTROLLER TYPE: Standard +// +// Marlin supports a wide variety of controllers. +// Enable one of the following options to specify your controller. +// + +// +// ULTIMAKER Controller. +// +//#define ULTIMAKERCONTROLLER + +// +// ULTIPANEL as seen on Thingiverse. +// +//#define ULTIPANEL + +// +// PanelOne from T3P3 (via RAMPS 1.4 AUX2/AUX3) +// http://reprap.org/wiki/PanelOne +// +//#define PANEL_ONE + +// +// MaKr3d Makr-Panel with graphic controller and SD support. +// http://reprap.org/wiki/MaKr3d_MaKrPanel +// +//#define MAKRPANEL + +// +// ReprapWorld Graphical LCD +// https://reprapworld.com/?products_details&products_id/1218 +// +//#define REPRAPWORLD_GRAPHICAL_LCD + +// +// Activate one of these if you have a Panucatt Devices +// Viki 2.0 or mini Viki with Graphic LCD +// http://panucatt.com +// +//#define VIKI2 +//#define miniVIKI + +// +// Adafruit ST7565 Full Graphic Controller. +// https://github.com/eboston/Adafruit-ST7565-Full-Graphic-Controller/ +// +//#define ELB_FULL_GRAPHIC_CONTROLLER + +// +// RepRapDiscount Smart Controller. +// http://reprap.org/wiki/RepRapDiscount_Smart_Controller +// +// Note: Usually sold with a white PCB. +// +//#define REPRAP_DISCOUNT_SMART_CONTROLLER + +// +// GADGETS3D G3D LCD/SD Controller +// http://reprap.org/wiki/RAMPS_1.3/1.4_GADGETS3D_Shield_with_Panel +// +// Note: Usually sold with a blue PCB. +// +//#define G3D_PANEL + +// +// RepRapDiscount FULL GRAPHIC Smart Controller +// http://reprap.org/wiki/RepRapDiscount_Full_Graphic_Smart_Controller +// +//#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER + +// +// MakerLab Mini Panel with graphic +// controller and SD support - http://reprap.org/wiki/Mini_panel +// +//#define MINIPANEL + +// +// RepRapWorld REPRAPWORLD_KEYPAD v1.1 +// http://reprapworld.com/?products_details&products_id=202&cPath=1591_1626 +// +// REPRAPWORLD_KEYPAD_MOVE_STEP sets how much should the robot move when a key +// is pressed, a value of 10.0 means 10mm per click. +// +//#define REPRAPWORLD_KEYPAD +//#define REPRAPWORLD_KEYPAD_MOVE_STEP 1.0 + +// +// RigidBot Panel V1.0 +// http://www.inventapart.com/ +// +//#define RIGIDBOT_PANEL + +// +// BQ LCD Smart Controller shipped by +// default with the BQ Hephestos 2 and Witbox 2. +// +//#define BQ_LCD_SMART_CONTROLLER + +// +// Cartesio UI +// http://mauk.cc/webshop/cartesio-shop/electronics/user-interface +// +//#define CARTESIO_UI + +// +// ANET_10 Controller supported displays. +// +//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. + // This LCD is known to be susceptible to electrical interference + // which scrambles the display. Pressing any button clears it up. +//#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 + // A clone of the RepRapDiscount full graphics display but with + // different pins/wiring (see pins_ANET_10.h). + +// +// LCD for Melzi Card with Graphical LCD +// +//#define LCD_FOR_MELZI + +// +// CONTROLLER TYPE: I2C +// +// Note: These controllers require the installation of Arduino's LiquidCrystal_I2C +// library. For more info: https://github.com/kiyoshigawa/LiquidCrystal_I2C +// + +// +// Elefu RA Board Control Panel +// http://www.elefu.com/index.php?route=product/product&product_id=53 +// +//#define RA_CONTROL_PANEL + +// +// Sainsmart YW Robot (LCM1602) LCD Display +// +// Note: This controller requires F.Malpartida's LiquidCrystal_I2C library +// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home +// +//#define LCD_I2C_SAINSMART_YWROBOT + +// +// Generic LCM1602 LCD adapter +// +//#define LCM1602 + +// +// PANELOLU2 LCD with status LEDs, +// separate encoder and click inputs. +// +// Note: This controller requires Arduino's LiquidTWI2 library v1.2.3 or later. +// For more info: https://github.com/lincomatic/LiquidTWI2 +// +// Note: The PANELOLU2 encoder click input can either be directly connected to +// a pin (if BTN_ENC defined to != -1) or read through I2C (when BTN_ENC == -1). +// +//#define LCD_I2C_PANELOLU2 + +// +// Panucatt VIKI LCD with status LEDs, +// integrated click & L/R/U/D buttons, separate encoder inputs. +// +//#define LCD_I2C_VIKI + +// +// SSD1306 OLED full graphics generic display +// +//#define U8GLIB_SSD1306 + +// +// SAV OLEd LCD module support using either SSD1306 or SH1106 based LCD modules +// +//#define SAV_3DGLCD +#if ENABLED(SAV_3DGLCD) + //#define U8GLIB_SSD1306 + #define U8GLIB_SH1106 +#endif + +// +// CONTROLLER TYPE: Shift register panels +// +// 2 wire Non-latching LCD SR from https://goo.gl/aJJ4sH +// LCD configuration: http://reprap.org/wiki/SAV_3D_LCD +// +//#define SAV_3DLCD + +// +// TinyBoy2 128x64 OLED / Encoder Panel +// +//#define OLED_PANEL_TINYBOY2 + +// +// Makeboard 3D Printer Parts 3D Printer Mini Display 1602 Mini Controller +// https://www.aliexpress.com/item/Micromake-Makeboard-3D-Printer-Parts-3D-Printer-Mini-Display-1602-Mini-Controller-Compatible-with-Ramps-1/32765887917.html +// +//#define MAKEBOARD_MINI_2_LINE_DISPLAY_1602 + +// +// MKS MINI12864 with graphic controller and SD support +// http://reprap.org/wiki/MKS_MINI_12864 +// +//#define MKS_MINI_12864 + +// +// Factory display for Creality CR-10 +// https://www.aliexpress.com/item/Universal-LCD-12864-3D-Printer-Display-Screen-With-Encoder-For-CR-10-CR-7-Model/32833148327.html +// +// This is RAMPS-compatible using a single 10-pin connector. +// (For CR-10 owners who want to replace the Melzi Creality board but retain the display) +// +//#define CR10_STOCKDISPLAY + +// +// MKS OLED 1.3" 128 × 64 FULL GRAPHICS CONTROLLER +// http://reprap.org/wiki/MKS_12864OLED +// +// Tiny, but very sharp OLED display +// +//#define MKS_12864OLED + +//============================================================================= +//=============================== Extra Features ============================== +//============================================================================= + +// @section extras + +// Increase the FAN PWM frequency. Removes the PWM noise but increases heating in the FET/Arduino +//#define FAST_PWM_FAN + +// Use software PWM to drive the fan, as for the heaters. This uses a very low frequency +// which is not as annoying as with the hardware PWM. On the other hand, if this frequency +// is too low, you should also increment SOFT_PWM_SCALE. +//#define FAN_SOFT_PWM + +// Incrementing this by 1 will double the software PWM frequency, +// affecting heaters, and the fan if FAN_SOFT_PWM is enabled. +// However, control resolution will be halved for each increment; +// at zero value, there are 128 effective control positions. +#define SOFT_PWM_SCALE 0 + +// If SOFT_PWM_SCALE is set to a value higher than 0, dithering can +// be used to mitigate the associated resolution loss. If enabled, +// some of the PWM cycles are stretched so on average the desired +// duty cycle is attained. +//#define SOFT_PWM_DITHER + +// Temperature status LEDs that display the hotend and bed temperature. +// If all hotends, bed temperature, and target temperature are under 54C +// then the BLUE led is on. Otherwise the RED led is on. (1C hysteresis) +//#define TEMP_STAT_LEDS + +// M240 Triggers a camera by emulating a Canon RC-1 Remote +// Data from: http://www.doc-diy.net/photo/rc-1_hacked/ +//#define PHOTOGRAPH_PIN 23 + +// 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 + +// Support for BlinkM/CyzRgb +//#define BLINKM + +// Support for PCA9632 PWM LED driver +//#define PCA9632 + +/** + * RGB LED / LED Strip Control + * + * Enable support for an RGB LED connected to 5V digital pins, or + * an RGB Strip connected to MOSFETs controlled by digital pins. + * + * 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 overall brightness parameters is also available + * + * *** CAUTION *** + * LED Strips require a MOFSET 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! + * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino + * cannot handle such current, separate 5V power supply must be used + * *** CAUTION *** + * + * LED type. This options are mutualy exclusive. Uncomment only one. + * + */ +//#define RGB_LED +//#define RGBW_LED + +#if ENABLED(RGB_LED) || ENABLED(RGBW_LED) + #define RGB_LED_R_PIN 34 + #define RGB_LED_G_PIN 43 + #define RGB_LED_B_PIN 35 + #define RGB_LED_W_PIN -1 +#endif + +// 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 (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) + #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip + #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time + #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + //#define NEOPIXEL_STARTUP_TEST // Cycle through colors at startup +#endif + +/** + * Printer Event LEDs + * + * During printing, the LEDs will reflect the printer status: + * + * - Gradually change from blue to violet as the heated bed gets to target temp + * - Gradually change from violet to red as the hotend gets to temperature + * - Change to white to illuminate work surface + * - Change to green once print has finished + * - Turn off after the print has finished and the user has pushed a button + */ +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) + #define PRINTER_EVENT_LEDS +#endif + +/*********************************************************************\ +* R/C SERVO support +* Sponsored by TrinityLabs, Reworked by codexmas +**********************************************************************/ + +// Number of servos +// +// If you select a configuration below, this will receive a default value and does not need to be set manually +// set it manually if you have more servos than extruders and wish to manually control some +// leaving it undefined or defining as 0 will disable the servo subsystem +// If unsure, leave commented / disabled +// +//#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command + +// Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. +// 300ms is a good value but you can try less delay. +// If the servo can't reach the requested position, increase it. +#define SERVO_DELAY { 300 } + +// Servo deactivation +// +// With this option servos are powered only during movement, then turned off to prevent jitter. +//#define DEACTIVATE_SERVOS_AFTER_MOVE + +/** + * Filament Width Sensor + * + * Measures the filament width in real-time and adjusts + * flow rate to compensate for any irregularities. + * + * Also allows the measured filament diameter to set the + * extrusion rate, so the slicer only has to specify the + * volume. + * + * Only a single extruder is supported at this time. + * + * 34 RAMPS_14 : Analog input 5 on the AUX2 connector + * 81 PRINTRBOARD : Analog input 2 on the Exp1 connector (version B,C,D,E) + * 301 RAMBO : Analog input 3 + * + * Note: May require analog pins to be defined for other boards. + */ +//#define FILAMENT_WIDTH_SENSOR + +#define DEFAULT_NOMINAL_FILAMENT_DIA 3.00 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. + +#if ENABLED(FILAMENT_WIDTH_SENSOR) + #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) + #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber + + #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading + #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading + #define MAX_MEASUREMENT_DELAY 20 // (bytes) Buffer size for stored measurements (1 byte per cm). Must be larger than MEASUREMENT_DELAY_CM. + + #define DEFAULT_MEASURED_FILAMENT_DIA DEFAULT_NOMINAL_FILAMENT_DIA // Set measured to nominal initially + + // Display filament width on the LCD status line. Status messages will expire after 5 seconds. + //#define FILAMENT_LCD_DISPLAY +#endif + +#endif // CONFIGURATION_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/makibox/Configuration_adv.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/makibox/Configuration_adv.h new file mode 100644 index 00000000..e8188d66 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/makibox/Configuration_adv.h @@ -0,0 +1,1424 @@ +/** + * 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 . + * + */ + +/** + * Configuration_adv.h + * + * Advanced settings. + * Only change these if you know exactly what you're doing. + * Some of these settings can damage your printer if improperly set! + * + * Basic settings can be found in Configuration.h + * + */ +#ifndef CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H_VERSION 010100 + +// @section temperature + +//=========================================================================== +//=============================Thermal Settings ============================ +//=========================================================================== + +#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 + #endif +#endif + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * The solution: Once the temperature reaches the target, start observing. + * If the temperature stays too far below the target (hysteresis) for too long (period), + * the firmware will halt the machine as a safety precaution. + * + * If you get false positives for "Thermal Runaway" increase THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD + */ +#if ENABLED(THERMAL_PROTECTION_HOTENDS) + #define THERMAL_PROTECTION_PERIOD 40 // Seconds + #define THERMAL_PROTECTION_HYSTERESIS 4 // Degrees Celsius + + /** + * Whenever an M104 or M109 increases the target temperature the firmware will wait for the + * WATCH_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get false positives for "Heating failed" increase WATCH_TEMP_PERIOD and/or decrease WATCH_TEMP_INCREASE + * WATCH_TEMP_INCREASE should not be below 2. + */ + #define WATCH_TEMP_PERIOD 20 // Seconds + #define WATCH_TEMP_INCREASE 2 // Degrees Celsius +#endif + +/** + * Thermal Protection parameters for the bed are just as above for hotends. + */ +#if ENABLED(THERMAL_PROTECTION_BED) + #define THERMAL_PROTECTION_BED_PERIOD 20 // Seconds + #define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius + + /** + * Whenever an M140 or M190 increases the target temperature the firmware will wait for the + * WATCH_BED_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_BED_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get too many "Heating failed" errors, increase WATCH_BED_TEMP_PERIOD and/or decrease + * WATCH_BED_TEMP_INCREASE. (WATCH_BED_TEMP_INCREASE should not be below 2.) + */ + #define WATCH_BED_TEMP_PERIOD 60 // Seconds + #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius +#endif + +#if ENABLED(PIDTEMP) + // this adds an experimental additional term to the heating power, proportional to the extrusion speed. + // if Kc is chosen well, the additional required power due to increased melting should be compensated. + //#define PID_EXTRUSION_SCALING + #if ENABLED(PID_EXTRUSION_SCALING) + #define DEFAULT_Kc (100) //heating power=Kc*(e_speed) + #define LPQ_MAX_LEN 50 + #endif +#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 + */ +#define AUTOTEMP +#if ENABLED(AUTOTEMP) + #define AUTOTEMP_OLDWEIGHT 0.98 +#endif + +// Show Temperature ADC value +// Enable for M105 to include ADC values read from temperature sensors. +//#define SHOW_TEMP_ADC_VALUES + +/** + * High Temperature Thermistor Support + * + * Thermistors able to support high temperature tend to have a hard time getting + * good readings at room and lower temperatures. This means HEATER_X_RAW_LO_TEMP + * will probably be caught when the heating element first turns on during the + * preheating process, which will trigger a min_temp_error as a safety measure + * and force stop everything. + * To circumvent this limitation, we allow for a preheat time (during which, + * min_temp_error won't be triggered) and add a min_temp buffer to handle + * aberrant readings. + * + * If you want to enable this feature for your hotend thermistor(s) + * uncomment and set values > 0 in the constants below + */ + +// The number of consecutive low temperature errors that can occur +// before a min_temp_error is triggered. (Shouldn't be more than 10.) +//#define MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED 0 + +// The number of milliseconds a hotend will preheat before starting to check +// the temperature. This value should NOT be set to the time it takes the +// hot end to reach the target temperature, but the time it takes to reach +// the minimum temperature your thermistor can read. The lower the better/safer. +// This shouldn't need to be more than 30 seconds (30000) +//#define MILLISECONDS_PREHEAT_TIME 0 + +// @section extruder + +// Extruder runout prevention. +// If the machine is idle and the temperature over MINTEMP +// then extrude some filament every couple of SECONDS. +//#define EXTRUDER_RUNOUT_PREVENT +#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_EXTRUDE 5 // mm +#endif + +// @section temperature + +//These defines help to calibrate the AD595 sensor in case you get wrong temperature measurements. +//The measured temperature is defined as "actualTemp = (measuredTemp * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET" +#define TEMP_SENSOR_AD595_OFFSET 0.0 +#define TEMP_SENSOR_AD595_GAIN 1.0 + +/** + * 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. + */ +//#define USE_CONTROLLER_FAN +#if ENABLED(USE_CONTROLLER_FAN) + //#define CONTROLLER_FAN_PIN FAN1_PIN // 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 +#endif + +// When first starting the main fan, run it at full speed for the +// given number of milliseconds. This gets the fan spinning reliably +// before setting a PWM value. (Does not work with software PWM for fan on Sanguinololu) +//#define FAN_KICKSTART_TIME 100 + +// This defines the minimal speed for the main fan, run in PWM mode +// to enable uncomment and set minimal PWM speed for reliable running (1-255) +// if fan speed is [1 - (FAN_MIN_PWM-1)] it is set to FAN_MIN_PWM +//#define FAN_MIN_PWM 50 + +// @section extruder + +/** + * Extruder cooling fans + * + * Extruder auto fans automatically turn on when their extruders' + * temperatures go above EXTRUDER_AUTO_FAN_TEMPERATURE. + * + * Your board's pins file specifies the recommended pins. Override those here + * or set to -1 to disable completely. + * + * Multiple extruders can be assigned to the same pin in which case + * the fan will turn on when any selected extruder is above the threshold. + */ +#define E0_AUTO_FAN_PIN -1 +#define E1_AUTO_FAN_PIN -1 +#define E2_AUTO_FAN_PIN -1 +#define E3_AUTO_FAN_PIN -1 +#define E4_AUTO_FAN_PIN -1 +#define EXTRUDER_AUTO_FAN_TEMPERATURE 50 +#define EXTRUDER_AUTO_FAN_SPEED 255 // == full speed + +/** + * Part-Cooling Fan Multiplexer + * + * This feature allows you to digitally multiplex the fan output. + * The multiplexer is automatically switched at tool-change. + * Set FANMUX[012]_PINs below for up to 2, 4, or 8 multiplexed fans. + */ +#define FANMUX0_PIN -1 +#define FANMUX1_PIN -1 +#define FANMUX2_PIN -1 + +/** + * M355 Case Light on-off / brightness + */ +//#define CASE_LIGHT_ENABLE +#if ENABLED(CASE_LIGHT_ENABLE) + //#define CASE_LIGHT_PIN 4 // Override the default pin if needed + #define INVERT_CASE_LIGHT false // Set true if Case Light is ON when pin is LOW + #define CASE_LIGHT_DEFAULT_ON true // Set default power-up state on + #define CASE_LIGHT_DEFAULT_BRIGHTNESS 105 // Set default power-up brightness (0-255, requires PWM pin) + //#define MENU_ITEM_CASE_LIGHT // Add a Case Light option to the LCD main menu +#endif + +//=========================================================================== +//============================ Mechanical Settings ========================== +//=========================================================================== + +// @section homing + +// If you want endstops to stay on (by default) even when not homing +// enable this option. Override at any time with M120, M121. +//#define ENDSTOPS_ALWAYS_ON_DEFAULT + +// @section extras + +//#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. + +// Dual X Steppers +// Uncomment this option to drive two X axis motors. +// The next unused E driver will be assigned to the second X stepper. +//#define X_DUAL_STEPPER_DRIVERS +#if ENABLED(X_DUAL_STEPPER_DRIVERS) + // Set true if the two X motors need to rotate in opposite directions + #define INVERT_X2_VS_X_DIR true +#endif + +// Dual Y Steppers +// Uncomment this option to drive two Y axis motors. +// The next unused E driver will be assigned to the second Y stepper. +//#define Y_DUAL_STEPPER_DRIVERS +#if ENABLED(Y_DUAL_STEPPER_DRIVERS) + // Set true if the two Y motors need to rotate in opposite directions + #define INVERT_Y2_VS_Y_DIR true +#endif + +// A single Z stepper driver is usually used to drive 2 stepper motors. +// Uncomment this option to use a separate stepper driver for each Z axis motor. +// The next unused E driver will be assigned to the second Z stepper. +//#define Z_DUAL_STEPPER_DRIVERS + +#if ENABLED(Z_DUAL_STEPPER_DRIVERS) + + // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper. + // That way the machine is capable to align the bed during home, since both Z steppers are homed. + // There is also an implementation of M666 (software endstops adjustment) to this feature. + // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed. + // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2. + // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive. + // Play a little bit with small adjustments (0.5mm) and check the behaviour. + // The M119 (endstops report) will start reporting the Z2 Endstop as well. + + //#define Z_DUAL_ENDSTOPS + + #if ENABLED(Z_DUAL_ENDSTOPS) + #define Z2_USE_ENDSTOP _XMAX_ + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 // Use M666 to determine/test this value + #endif + +#endif // Z_DUAL_STEPPER_DRIVERS + +// Enable this for dual x-carriage printers. +// A dual x-carriage design has the advantage that the inactive extruder can be parked which +// prevents hot-end ooze contaminating the print. It also reduces the weight of each x-carriage +// allowing faster printing speeds. Connect your X2 stepper to the first unused E plug. +//#define DUAL_X_CARRIAGE +#if ENABLED(DUAL_X_CARRIAGE) + // Configuration for second X-carriage + // Note: the first x-carriage is defined as the x-carriage which homes to the minimum endstop; + // the second x-carriage always homes to the maximum endstop. + #define X2_MIN_POS 80 // set minimum to ensure second x-carriage doesn't hit the parked first X-carriage + #define X2_MAX_POS 353 // set maximum to the distance between toolheads when both heads are homed + #define X2_HOME_DIR 1 // the second X-carriage always homes to the maximum endstop position + #define X2_HOME_POS X2_MAX_POS // default home position is the maximum carriage position + // However: In this mode the HOTEND_OFFSET_X value for the second extruder provides a software + // override for X2_HOME_POS. This also allow recalibration of the distance between the two endstops + // without modifying the firmware (through the "M218 T1 X???" command). + // Remember: you should set the second extruder x-offset to 0 in your slicer. + + // There are a few selectable movement modes for dual x-carriages using M605 S + // Mode 0 (DXC_FULL_CONTROL_MODE): Full control. The slicer has full control over both x-carriages and can achieve optimal travel results + // as long as it supports dual x-carriages. (M605 S0) + // Mode 1 (DXC_AUTO_PARK_MODE) : Auto-park mode. The firmware will automatically park and unpark the x-carriages on tool changes so + // that additional slicer support is not required. (M605 S1) + // Mode 2 (DXC_DUPLICATION_MODE) : Duplication mode. The firmware will transparently make the second x-carriage and extruder copy all + // actions of the first x-carriage. This allows the printer to print 2 arbitrary items at + // once. (2nd extruder x offset and temp offset are set using: M605 S2 [Xnnn] [Rmmm]) + + // This is the default power-up mode which can be later using M605. + #define DEFAULT_DUAL_X_CARRIAGE_MODE DXC_FULL_CONTROL_MODE + + // Default settings in "Auto-park Mode" + #define TOOLCHANGE_PARK_ZLIFT 0.2 // the distance to raise Z axis when parking an extruder + #define TOOLCHANGE_UNPARK_ZLIFT 1 // the distance to raise Z axis when unparking an extruder + + // Default x offset in duplication mode (typically set to half print bed width) + #define DEFAULT_DUPLICATION_X_OFFSET 100 + +#endif // DUAL_X_CARRIAGE + +// 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. +//#define EXT_SOLENOID + +// @section homing + +//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +#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 this is defined, if both x and y are to be homed, a diagonal move will be performed initially. + +// When G28 is called, this option will make Y home before X +//#define HOME_Y_BEFORE_X + +// @section machine + +#define AXIS_RELATIVE_MODES {false, false, false, false} + +// Allow duplication mode with a basic dual-nozzle extruder +//#define DUAL_NOZZLE_DUPLICATION_MODE + +// By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step. +#define INVERT_X_STEP_PIN false +#define INVERT_Y_STEP_PIN false +#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. +#define DEFAULT_STEPPER_DEACTIVE_TIME 60 +#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_E true + +#define DEFAULT_MINIMUMFEEDRATE 0.0 // minimum feedrate +#define DEFAULT_MINTRAVELFEEDRATE 0.0 + +//#define HOME_AFTER_DEACTIVATE // Require rehoming after steppers are deactivated + +// @section lcd + +#if ENABLED(ULTIPANEL) + #define MANUAL_FEEDRATE {50*60, 50*60, 4*60, 60} // Feedrates for manual moves along X, Y, Z, E from panel + #define ULTIPANEL_FEEDMULTIPLY // Comment to disable setting feedrate multiplier via encoder +#endif + +// @section extras + +// minimum time in microseconds that a movement needs to take if the buffer is emptied. +#define DEFAULT_MINSEGMENTTIME 20000 + +// If defined the movements slow down when the look ahead buffer is only half full +#define SLOWDOWN + +// Frequency limit +// See nophead's blog for more info +// Not working O +//#define XY_FREQUENCY_LIMIT 15 + +// 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 +// if unwanted behavior is observed on a user's machine when running at very slow speeds. +#define MINIMUM_PLANNER_SPEED 0.05 // (mm/sec) + +// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU. +#define MICROSTEP_MODES {16,16,16,16,16} // [1,2,4,8,16] + +/** + * @section stepper motor current + * + * Some boards have a means of setting the stepper motor current via firmware. + * + * The power on motor currents are set by: + * PWM_MOTOR_CURRENT - used by MINIRAMBO & ULTIMAIN_2 + * known compatible chips: A4982 + * DIGIPOT_MOTOR_CURRENT - used by BQ_ZUM_MEGA_3D, RAMBO & SCOOVO_X9H + * known compatible chips: AD5206 + * DAC_MOTOR_CURRENT_DEFAULT - used by PRINTRBOARD_REVF & RIGIDBOARD_V2 + * known compatible chips: MCP4728 + * DIGIPOT_I2C_MOTOR_CURRENTS - used by 5DPRINT, AZTEEG_X3_PRO, MIGHTYBOARD_REVE + * known compatible chips: MCP4451, MCP4018 + * + * Motor currents can also be set by M907 - M910 and by the LCD. + * M907 - applies to all. + * M908 - BQ_ZUM_MEGA_3D, RAMBO, PRINTRBOARD_REVF, RIGIDBOARD_V2 & SCOOVO_X9H + * M909, M910 & LCD - only PRINTRBOARD_REVF & RIGIDBOARD_V2 + */ +//#define PWM_MOTOR_CURRENT { 1300, 1300, 1250 } // Values in milliamps +//#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 + +// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +//#define DIGIPOT_I2C +//#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster +#define DIGIPOT_I2C_NUM_CHANNELS 4 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 +// Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS +#define DIGIPOT_I2C_MOTOR_CURRENTS { 1.7, 1.7, 1.7, 1.7 } // 5DPRINT + +//=========================================================================== +//=============================Additional Features=========================== +//=========================================================================== + +#define ENCODER_RATE_MULTIPLIER // If defined, certain menu edit operations automatically multiply the steps when the encoder is moved quickly +#define ENCODER_10X_STEPS_PER_SEC 75 // If the encoder steps per sec exceeds this value, multiply steps moved x10 to quickly advance the value +#define ENCODER_100X_STEPS_PER_SEC 160 // If the encoder steps per sec exceeds this value, multiply steps moved x100 to really quickly advance the value + +//#define CHDK 4 //Pin for triggering CHDK to take a picture see how to use it here http://captain-slow.dk/2014/03/09/3d-printing-timelapses/ +#define CHDK_DELAY 50 //How long in ms the pin should stay HIGH before going LOW again + +// @section lcd + +// Include a page of printer information in the LCD Main Menu +//#define LCD_INFO_MENU + +// Scroll a longer status message into view +//#define STATUS_MESSAGE_SCROLLING + +// On the Info Screen, display XY with one decimal place when possible +//#define LCD_DECIMAL_SMALL_XY + +// The timeout (in ms) to return to the status screen from sub-menus +//#define LCD_TIMEOUT_TO_STATUS 15000 + +#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 + + #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? + #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. + + #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. + // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. + // using: + //#define MENU_ADDAUTOSTART + + /** + * Sort SD file listings in alphabetical order. + * + * With this option enabled, items on SD cards will be sorted + * by name for easier navigation. + * + * By default... + * + * - Use the slowest -but safest- method for sorting. + * - Folders are sorted to the top. + * - The sort key is statically allocated. + * - No added G-code (M34) support. + * - 40 item sorting limit. (Items after the first 40 are unsorted.) + * + * SD sorting uses static allocation (as set by SDSORT_LIMIT), allowing the + * compiler to calculate the worst-case usage and throw an error if the SRAM + * limit is exceeded. + * + * - SDSORT_USES_RAM provides faster sorting via a static directory buffer. + * - SDSORT_USES_STACK does the same, but uses a local stack-based buffer. + * - SDSORT_CACHE_NAMES will retain the sorted file listing in RAM. (Expensive!) + * - SDSORT_DYNAMIC_RAM only uses RAM when the SD menu is visible. (Use with caution!) + */ + //#define SDCARD_SORT_ALPHA + + // SD Card Sorting options + #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_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. + #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #endif + + // Show a progress bar on HD44780 LCDs for SD printing + //#define LCD_PROGRESS_BAR + + #if ENABLED(LCD_PROGRESS_BAR) + // Amount of time (ms) to show the bar + #define PROGRESS_BAR_BAR_TIME 2000 + // Amount of time (ms) to show the status message + #define PROGRESS_BAR_MSG_TIME 3000 + // Amount of time (ms) to retain the status message (0=forever) + #define PROGRESS_MSG_EXPIRE 0 + // Enable this to show messages for MSG_TIME then hide them + //#define PROGRESS_MSG_ONCE + // Add a menu item to test the progress bar: + //#define LCD_PROGRESS_BAR_TEST + #endif + + // This allows hosts to request long names for files and folders with M33 + //#define LONG_FILENAME_HOST_SUPPORT + + // This option allows you to abort SD printing when any endstop is triggered. + // This feature must be enabled with "M540 S1" or from the LCD menu. + // To have any effect, endstops must be enabled during SD printing. + //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + +#endif // SDSUPPORT + +/** + * Additional options for Graphical Displays + * + * Use the optimizations here to improve printing performance, + * which can be adversely affected by graphical display drawing, + * especially when doing several short moves, and when printing + * on DELTA and SCARA machines. + * + * Some of these options may result in the display lagging behind + * controller events, as there is a trade-off between reliable + * printing performance versus fast display updates. + */ +#if ENABLED(DOGLCD) + // Enable to save many cycles by drawing a hollow frame on the Info Screen + #define XYZ_HOLLOW_FRAME + + // Enable to save many cycles by drawing a hollow frame on Menu Screens + #define MENU_HOLLOW_FRAME + + // A bigger font is available for edit items. Costs 3120 bytes of PROGMEM. + // 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. + // 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 +#endif // DOGLCD + +// @section safety + +// The hardware watchdog should reset the microcontroller disabling all outputs, +// in case the firmware gets stuck and doesn't do temperature regulation. +#define USE_WATCHDOG + +#if ENABLED(USE_WATCHDOG) + // If you have a watchdog reboot in an ArduinoMega2560 then the device will hang forever, as a watchdog reset will leave the watchdog on. + // The "WATCHDOG_RESET_MANUAL" goes around this by not using the hardware reset. + // However, THIS FEATURE IS UNSAFE!, as it will only work if interrupts are disabled. And the code could hang in an interrupt routine with interrupts disabled. + //#define WATCHDOG_RESET_MANUAL +#endif + +// @section lcd + +/** + * Babystepping enables movement of the axes by tiny increments without changing + * the current position values. This feature is used primarily to adjust the Z + * axis in the first layer of a print in real-time. + * + * Warning: Does not respect endstops! + */ +//#define BABYSTEPPING +#if ENABLED(BABYSTEPPING) + //#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 100 // Babysteps are very small. Increase for faster motion. + //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping + //#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen 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_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor + //#define BABYSTEP_ZPROBE_GFX_REVERSE // Reverses the direction of the CW/CCW indicators +#endif + +// @section extruder + +/** + * Implementation of linear pressure control + * + * Assumption: advance = k * (delta velocity) + * K=0 means advance disabled. + * See Marlin documentation for calibration instructions. + */ +//#define LIN_ADVANCE + +#if ENABLED(LIN_ADVANCE) + #define LIN_ADVANCE_K 75 + + /** + * Some Slicers produce Gcode with randomly jumping extrusion widths occasionally. + * For example within a 0.4mm perimeter it may produce a single segment of 0.05mm width. + * While this is harmless for normal printing (the fluid nature of the filament will + * close this very, very tiny gap), it throws off the LIN_ADVANCE pressure adaption. + * + * For this case LIN_ADVANCE_E_D_RATIO can be used to set the extrusion:distance ratio + * to a fixed value. Note that using a fixed ratio will lead to wrong nozzle pressures + * if the slicer is using variable widths or layer heights within one print! + * + * This option sets the default E:D ratio at startup. Use `M900` to override this value. + * + * Example: `M900 W0.4 H0.2 D1.75`, where: + * - W is the extrusion width in mm + * - H is the layer height in mm + * - D is the filament diameter in mm + * + * Example: `M900 R0.0458` to set the ratio directly. + * + * Set to 0 to auto-detect the ratio based on given Gcode G1 print moves. + * + * Slic3r (including Průša Control) produces Gcode compatible with the automatic mode. + * Cura (as of this writing) may produce Gcode incompatible with the automatic mode. + */ + #define LIN_ADVANCE_E_D_RATIO 0 // The calculated ratio (or 0) according to the formula W * H / ((D / 2) ^ 2 * PI) + // Example: 0.4 * 0.2 / ((1.75 / 2) ^ 2 * PI) = 0.033260135 +#endif + +// @section leveling + +// Default mesh area is an area with an inset margin on the print area. +// Below are the macros that are used to define the borders for the mesh area, +// made available here for specialized needs, ie dual extruder setup. +#if ENABLED(MESH_BED_LEVELING) + #define MESH_MIN_X MESH_INSET + #define MESH_MAX_X (X_BED_SIZE - (MESH_INSET)) + #define MESH_MIN_Y MESH_INSET + #define MESH_MAX_Y (Y_BED_SIZE - (MESH_INSET)) +#elif ENABLED(AUTO_BED_LEVELING_UBL) + #define UBL_MESH_MIN_X UBL_MESH_INSET + #define UBL_MESH_MAX_X (X_BED_SIZE - (UBL_MESH_INSET)) + #define UBL_MESH_MIN_Y UBL_MESH_INSET + #define UBL_MESH_MAX_Y (Y_BED_SIZE - (UBL_MESH_INSET)) + + // If this is defined, the currently active mesh will be saved in the + // current slot on M500. + #define UBL_SAVE_ACTIVE_ON_M500 +#endif + +// @section extras + +// +// G2/G3 Arc Support +// +#define ARC_SUPPORT // Disable this feature to save ~3226 bytes +#if ENABLED(ARC_SUPPORT) + #define MM_PER_ARC_SEGMENT 1 // Length of each arc segment + #define N_ARC_CORRECTION 25 // Number of intertpolated 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 +#endif + +// Support for G5 with XYZE destination and IJPQ offsets. Requires ~2666 bytes. +//#define BEZIER_CURVE_SUPPORT + +// G38.2 and G38.3 Probe Target +// Enable PROBE_DOUBLE_TOUCH if you want G38 to double touch +//#define G38_PROBE_TARGET +#if ENABLED(G38_PROBE_TARGET) + #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) +#endif + +// Moves (or segments) with fewer steps than this will be joined with the next move +#define MIN_STEPS_PER_SEGMENT 6 + +// The minimum pulse width (in µs) for stepping a stepper. +// Set this if you find stepping unreliable, or if using a very fast CPU. +#define MINIMUM_STEPPER_PULSE 0 // (µs) The smallest stepper pulse allowed + +// @section temperature + +// Control heater 0 and heater 1 in parallel. +//#define HEATERS_PARALLEL + +//=========================================================================== +//================================= Buffers ================================= +//=========================================================================== + +// @section hidden + +// 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, i.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 +#else + #define BLOCK_BUFFER_SIZE 16 // maximize block buffer +#endif + +// @section serial + +// The ASCII buffer for serial input +#define MAX_CMD_SIZE 96 +#define BUFSIZE 4 + +// Transmission to Host Buffer Size +// To save 386 bytes of PROGMEM (and TX_BUFFER_SIZE+3 bytes of RAM) set to 0. +// To buffer a simple "ok" you need 4 bytes. +// For ADVANCED_OK (M105) you need 32 bytes. +// For debug-echo: 128 bytes for the optimal speed. +// Other output doesn't need to be that speedy. +// :[0, 2, 4, 8, 16, 32, 64, 128, 256] +#define TX_BUFFER_SIZE 0 + +// Host Receive Buffer Size +// Without XON/XOFF flow control (see SERIAL_XON_XOFF below) 32 bytes should be enough. +// To use flow control, set this buffer size to at least 1024 bytes. +// :[0, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048] +//#define RX_BUFFER_SIZE 1024 + +#if RX_BUFFER_SIZE >= 1024 + // Enable to have the controller send XON/XOFF control characters to + // the host to signal the RX buffer is becoming full. + //#define SERIAL_XON_XOFF +#endif + +#if ENABLED(SDSUPPORT) + // Enable this option to collect and display the maximum + // RX queue usage after transferring a file to SD. + //#define SERIAL_STATS_MAX_RX_QUEUED + + // Enable this option to collect and display the number + // of dropped bytes after a file transfer to SD. + //#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! +//#define EMERGENCY_PARSER + +// Bad Serial-connections can miss a received command by sending an 'ok' +// Therefore some clients abort after 30 seconds in a timeout. +// Some other clients start sending commands while receiving a 'wait'. +// This "wait" is only sent when the buffer is empty. 1 second is a good value here. +//#define NO_TIMEOUTS 1000 // Milliseconds + +// Some clients will have this feature soon. This could make the NO_TIMEOUTS unnecessary. +//#define ADVANCED_OK + +// @section extras + +/** + * Firmware-based and LCD-controlled retract + * + * Add G10 / G11 commands for automatic firmware-based retract / recover. + * Use M207 and M208 to define parameters for retract / recover. + * + * Use M209 to enable or disable auto-retract. + * With auto-retract enabled, all G1 E moves within the set range + * will be converted to firmware-based retract/recover moves. + * + * Be sure to turn off auto-retract during filament change. + * + * Note that M207 / M208 / M209 settings are saved to EEPROM. + * + */ +//#define FWRETRACT // ONLY PARTIALLY TESTED +#if ENABLED(FWRETRACT) + #define MIN_AUTORETRACT 0.1 // When auto-retract is on, convert E moves of this length and over + #define MAX_AUTORETRACT 10.0 // Upper limit for auto-retract conversion + #define RETRACT_LENGTH 3 // Default retract length (positive mm) + #define RETRACT_LENGTH_SWAP 13 // Default swap retract length (positive mm), for extruder change + #define RETRACT_FEEDRATE 45 // Default feedrate for retracting (mm/s) + #define RETRACT_ZLIFT 0 // Default retract Z-lift + #define RETRACT_RECOVER_LENGTH 0 // Default additional recover length (mm, added to retract length when recovering) + #define RETRACT_RECOVER_LENGTH_SWAP 0 // Default additional swap recover length (mm, added to retract length when recovering from extruder change) + #define RETRACT_RECOVER_FEEDRATE 8 // Default feedrate for recovering from retraction (mm/s) + #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) +#endif + +/** + * Advanced Pause + * Experimental feature for filament change support and for parking the nozzle when paused. + * Adds the GCode M600 for initiating filament change. + * If PARK_HEAD_ON_PAUSE enabled, adds the GCode M125 to pause printing and park the nozzle. + * + * Requires an LCD display. + * This feature is required for the default FILAMENT_RUNOUT_SCRIPT. + */ +//#define ADVANCED_PAUSE_FEATURE +#if ENABLED(ADVANCED_PAUSE_FEATURE) + #define PAUSE_PARK_X_POS 3 // X position of hotend + #define PAUSE_PARK_Y_POS 3 // Y position of hotend + #define PAUSE_PARK_Z_ADD 10 // Z addition of hotend (lift) + #define PAUSE_PARK_XY_FEEDRATE 100 // X and Y axes feedrate in mm/s (also used for delta printers Z axis) + #define PAUSE_PARK_Z_FEEDRATE 5 // Z axis feedrate in mm/s (not used for delta printers) + #define PAUSE_PARK_RETRACT_FEEDRATE 60 // Initial retract feedrate in mm/s + #define PAUSE_PARK_RETRACT_LENGTH 2 // Initial retract in mm + // It is a short retract used immediately after print interrupt before move to filament exchange position + #define FILAMENT_CHANGE_UNLOAD_FEEDRATE 10 // Unload filament feedrate in mm/s - filament unloading can be fast + #define FILAMENT_CHANGE_UNLOAD_LENGTH 100 // Unload filament length from hotend in mm + // Longer length for bowden printers to unload filament from whole bowden tube, + // shorter length for printers without bowden to unload filament from extruder only, + // 0 to disable unloading for manual unloading + #define FILAMENT_CHANGE_LOAD_FEEDRATE 6 // Load filament feedrate in mm/s - filament loading into the bowden tube can be fast + #define FILAMENT_CHANGE_LOAD_LENGTH 0 // Load filament length over hotend in mm + // Longer length for bowden printers to fast load filament into whole bowden tube over the hotend, + // Short or zero length for printers without bowden where loading is not used + #define ADVANCED_PAUSE_EXTRUDE_FEEDRATE 3 // Extrude filament feedrate in mm/s - must be slower than load feedrate + #define ADVANCED_PAUSE_EXTRUDE_LENGTH 50 // Extrude filament length in mm after filament is loaded over the hotend, + // 0 to disable for manual extrusion + // Filament can be extruded repeatedly from the filament exchange menu to fill the hotend, + // or until outcoming filament color is not clear for filament color change + #define PAUSE_PARK_NOZZLE_TIMEOUT 45 // Turn off nozzle if user doesn't change filament within this time limit in seconds + #define FILAMENT_CHANGE_NUMBER_OF_ALERT_BEEPS 5 // Number of alert beeps before printer goes quiet + #define PAUSE_PARK_NO_STEPPER_TIMEOUT // Enable to have stepper motors hold position during filament change + // even if it takes longer than DEFAULT_STEPPER_DEACTIVE_TIME. + //#define PARK_HEAD_ON_PAUSE // Go to filament change position on pause, return to print position on resume + //#define HOME_BEFORE_FILAMENT_CHANGE // Ensure homing has been completed prior to parking for filament change +#endif + +// @section tmc + +/** + * Enable this section if you have TMC26X motor drivers. + * You will need to import the TMC26XStepper library into the Arduino IDE for this + * (https://github.com/trinamic/TMC26XStepper.git) + */ +//#define HAVE_TMCDRIVER + +#if ENABLED(HAVE_TMCDRIVER) + + //#define X_IS_TMC + //#define X2_IS_TMC + //#define Y_IS_TMC + //#define Y2_IS_TMC + //#define Z_IS_TMC + //#define Z2_IS_TMC + //#define E0_IS_TMC + //#define E1_IS_TMC + //#define E2_IS_TMC + //#define E3_IS_TMC + //#define E4_IS_TMC + + #define X_MAX_CURRENT 1000 // in mA + #define X_SENSE_RESISTOR 91 // in mOhms + #define X_MICROSTEPS 16 // number of microsteps + + #define X2_MAX_CURRENT 1000 + #define X2_SENSE_RESISTOR 91 + #define X2_MICROSTEPS 16 + + #define Y_MAX_CURRENT 1000 + #define Y_SENSE_RESISTOR 91 + #define Y_MICROSTEPS 16 + + #define Y2_MAX_CURRENT 1000 + #define Y2_SENSE_RESISTOR 91 + #define Y2_MICROSTEPS 16 + + #define Z_MAX_CURRENT 1000 + #define Z_SENSE_RESISTOR 91 + #define Z_MICROSTEPS 16 + + #define Z2_MAX_CURRENT 1000 + #define Z2_SENSE_RESISTOR 91 + #define Z2_MICROSTEPS 16 + + #define E0_MAX_CURRENT 1000 + #define E0_SENSE_RESISTOR 91 + #define E0_MICROSTEPS 16 + + #define E1_MAX_CURRENT 1000 + #define E1_SENSE_RESISTOR 91 + #define E1_MICROSTEPS 16 + + #define E2_MAX_CURRENT 1000 + #define E2_SENSE_RESISTOR 91 + #define E2_MICROSTEPS 16 + + #define E3_MAX_CURRENT 1000 + #define E3_SENSE_RESISTOR 91 + #define E3_MICROSTEPS 16 + + #define E4_MAX_CURRENT 1000 + #define E4_SENSE_RESISTOR 91 + #define E4_MICROSTEPS 16 + +#endif + +// @section TMC2130 + +/** + * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. + * + * You'll also need the TMC2130Stepper Arduino library + * (https://github.com/teemuatlut/TMC2130Stepper). + * + * To use TMC2130 stepper drivers in SPI mode connect your SPI2130 pins to + * the hardware SPI interface on your board and define the required CS pins + * in your `pins_MYBOARD.h` file. (e.g., RAMPS 1.4 uses AUX3 pins `X_CS_PIN 53`, `Y_CS_PIN 49`, etc.). + */ +//#define HAVE_TMC2130 + +#if ENABLED(HAVE_TMC2130) + + // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY + //#define X_IS_TMC2130 + //#define X2_IS_TMC2130 + //#define Y_IS_TMC2130 + //#define Y2_IS_TMC2130 + //#define Z_IS_TMC2130 + //#define Z2_IS_TMC2130 + //#define E0_IS_TMC2130 + //#define E1_IS_TMC2130 + //#define E2_IS_TMC2130 + //#define E3_IS_TMC2130 + //#define E4_IS_TMC2130 + + /** + * Stepper driver settings + */ + + #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 + #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current + #define INTERPOLATE 1 // Interpolate X/Y/Z_MICROSTEPS to 256 + + #define X_CURRENT 1000 // rms current in mA. Multiply by 1.41 for peak current. + #define X_MICROSTEPS 16 // 0..256 + + #define Y_CURRENT 1000 + #define Y_MICROSTEPS 16 + + #define Z_CURRENT 1000 + #define Z_MICROSTEPS 16 + + //#define X2_CURRENT 1000 + //#define X2_MICROSTEPS 16 + + //#define Y2_CURRENT 1000 + //#define Y2_MICROSTEPS 16 + + //#define Z2_CURRENT 1000 + //#define Z2_MICROSTEPS 16 + + //#define E0_CURRENT 1000 + //#define E0_MICROSTEPS 16 + + //#define E1_CURRENT 1000 + //#define E1_MICROSTEPS 16 + + //#define E2_CURRENT 1000 + //#define E2_MICROSTEPS 16 + + //#define E3_CURRENT 1000 + //#define E3_MICROSTEPS 16 + + //#define E4_CURRENT 1000 + //#define E4_MICROSTEPS 16 + + /** + * Use Trinamic's ultra quiet stepping mode. + * When disabled, Marlin will use spreadCycle stepping mode. + */ + #define STEALTHCHOP + + /** + * Let Marlin automatically control stepper current. + * This is still an experimental feature. + * Increase current every 5s by CURRENT_STEP until stepper temperature prewarn gets triggered, + * then decrease current by CURRENT_STEP until temperature prewarn is cleared. + * Adjusting starts from X/Y/Z/E_CURRENT but will not increase over AUTO_ADJUST_MAX + * 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. + * M906 S1 - Start adjusting current + * M906 S0 - Stop adjusting current + * M911 - Report stepper driver overtemperature pre-warn condition. + * M912 - Clear stepper driver overtemperature pre-warn condition flag. + */ + //#define AUTOMATIC_CURRENT_CONTROL + + #if ENABLED(AUTOMATIC_CURRENT_CONTROL) + #define CURRENT_STEP 50 // [mA] + #define AUTO_ADJUST_MAX 1300 // [mA], 1300mA_rms = 1840mA_peak + #define REPORT_CURRENT_CHANGE + #endif + + /** + * The driver will switch to spreadCycle when stepper speed is over HYBRID_THRESHOLD. + * This mode allows for faster movements at the expense of higher noise levels. + * STEALTHCHOP needs to be enabled. + * M913 X/Y/Z/E to live tune the setting + */ + //#define HYBRID_THRESHOLD + + #define X_HYBRID_THRESHOLD 100 // [mm/s] + #define X2_HYBRID_THRESHOLD 100 + #define Y_HYBRID_THRESHOLD 100 + #define Y2_HYBRID_THRESHOLD 100 + #define Z_HYBRID_THRESHOLD 4 + #define Z2_HYBRID_THRESHOLD 4 + #define E0_HYBRID_THRESHOLD 30 + #define E1_HYBRID_THRESHOLD 30 + #define E2_HYBRID_THRESHOLD 30 + #define E3_HYBRID_THRESHOLD 30 + #define E4_HYBRID_THRESHOLD 30 + + /** + * Use stallGuard2 to sense an obstacle and trigger an endstop. + * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. + * If used along with STEALTHCHOP, the movement will be louder when homing. This is normal. + * + * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. + * Higher values make the system LESS sensitive. + * Lower value make the system MORE sensitive. + * Too low values can lead to false positives, while too high values will collide the axis without triggering. + * It is advised to set X/Y_HOME_BUMP_MM to 0. + * M914 X/Y to live tune the setting + */ + //#define SENSORLESS_HOMING + + #if ENABLED(SENSORLESS_HOMING) + #define X_HOMING_SENSITIVITY 19 + #define Y_HOMING_SENSITIVITY 19 + #endif + + /** + * You can set your own advanced settings by filling in predefined functions. + * A list of available functions can be found on the library github page + * https://github.com/teemuatlut/TMC2130Stepper + * + * Example: + * #define TMC2130_ADV() { \ + * stepperX.diag0_temp_prewarn(1); \ + * stepperX.interpolate(0); \ + * } + */ + #define TMC2130_ADV() { } + +#endif // HAVE_TMC2130 + +// @section L6470 + +/** + * Enable this section if you have L6470 motor drivers. + * You need to import the L6470 library into the Arduino IDE for this. + * (https://github.com/ameyer/Arduino-L6470) + */ + +//#define HAVE_L6470DRIVER +#if ENABLED(HAVE_L6470DRIVER) + + //#define X_IS_L6470 + //#define X2_IS_L6470 + //#define Y_IS_L6470 + //#define Y2_IS_L6470 + //#define Z_IS_L6470 + //#define Z2_IS_L6470 + //#define E0_IS_L6470 + //#define E1_IS_L6470 + //#define E2_IS_L6470 + //#define E3_IS_L6470 + //#define E4_IS_L6470 + + #define X_MICROSTEPS 16 // number of microsteps + #define X_K_VAL 50 // 0 - 255, Higher values, are higher power. Be careful not to go too high + #define X_OVERCURRENT 2000 // maxc current in mA. If the current goes over this value, the driver will switch off + #define X_STALLCURRENT 1500 // current in mA where the driver will detect a stall + + #define X2_MICROSTEPS 16 + #define X2_K_VAL 50 + #define X2_OVERCURRENT 2000 + #define X2_STALLCURRENT 1500 + + #define Y_MICROSTEPS 16 + #define Y_K_VAL 50 + #define Y_OVERCURRENT 2000 + #define Y_STALLCURRENT 1500 + + #define Y2_MICROSTEPS 16 + #define Y2_K_VAL 50 + #define Y2_OVERCURRENT 2000 + #define Y2_STALLCURRENT 1500 + + #define Z_MICROSTEPS 16 + #define Z_K_VAL 50 + #define Z_OVERCURRENT 2000 + #define Z_STALLCURRENT 1500 + + #define Z2_MICROSTEPS 16 + #define Z2_K_VAL 50 + #define Z2_OVERCURRENT 2000 + #define Z2_STALLCURRENT 1500 + + #define E0_MICROSTEPS 16 + #define E0_K_VAL 50 + #define E0_OVERCURRENT 2000 + #define E0_STALLCURRENT 1500 + + #define E1_MICROSTEPS 16 + #define E1_K_VAL 50 + #define E1_OVERCURRENT 2000 + #define E1_STALLCURRENT 1500 + + #define E2_MICROSTEPS 16 + #define E2_K_VAL 50 + #define E2_OVERCURRENT 2000 + #define E2_STALLCURRENT 1500 + + #define E3_MICROSTEPS 16 + #define E3_K_VAL 50 + #define E3_OVERCURRENT 2000 + #define E3_STALLCURRENT 1500 + + #define E4_MICROSTEPS 16 + #define E4_K_VAL 50 + #define E4_OVERCURRENT 2000 + #define E4_STALLCURRENT 1500 + +#endif + +/** + * TWI/I2C BUS + * + * This feature is an EXPERIMENTAL feature so it shall not be used on production + * machines. Enabling this will allow you to send and receive I2C data from slave + * devices on the bus. + * + * ; Example #1 + * ; This macro send the string "Marlin" to the slave device with address 0x63 (99) + * ; It uses multiple M260 commands with one B arg + * M260 A99 ; Target slave address + * M260 B77 ; M + * M260 B97 ; a + * M260 B114 ; r + * M260 B108 ; l + * M260 B105 ; i + * M260 B110 ; n + * M260 S1 ; Send the current buffer + * + * ; Example #2 + * ; Request 6 bytes from slave device with address 0x63 (99) + * M261 A99 B5 + * + * ; Example #3 + * ; Example serial output of a M261 request + * echo:i2c-reply: from:99 bytes:5 data:hello + */ + +// @section i2cbus + +//#define EXPERIMENTAL_I2CBUS +#define I2C_SLAVE_ADDRESS 0 // Set a value from 8 to 127 to act as a slave + +// @section extras + +/** + * Spindle & Laser control + * + * Add the M3, M4, and M5 commands to turn the spindle/laser on and off, and + * to set spindle speed, spindle direction, and laser power. + * + * SuperPid is a router/spindle speed controller used in the CNC milling community. + * Marlin can be used to turn the spindle on and off. It can also be used to set + * the spindle speed from 5,000 to 30,000 RPM. + * + * 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. + */ +//#define SPINDLE_LASER_ENABLE +#if ENABLED(SPINDLE_LASER_ENABLE) + + #define SPINDLE_LASER_ENABLE_INVERT false // set to "true" if the on/off function is reversed + #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 // delay in milliseconds to allow the spindle/laser to come up to speed/power + #define SPINDLE_LASER_POWERDOWN_DELAY 5000 // delay in milliseconds to allow the spindle to stop + #define SPINDLE_DIR_CHANGE true // set to true if your spindle controller supports changing spindle direction + #define SPINDLE_INVERT_DIR false + #define SPINDLE_STOP_ON_DIR_CHANGE true // set to true if Marlin should stop the spindle before changing rotation direction + + /** + * The M3 & M4 commands use the following equation to convert PWM duty cycle to speed/power + * + * SPEED/POWER = PWM duty cycle * SPEED_POWER_SLOPE + SPEED_POWER_INTERCEPT + * where PWM duty cycle varies from 0 to 255 + * + * set the following for your controller (ALL MUST BE SET) + */ + + #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_SLOPE 0.3922 + //#define SPEED_POWER_INTERCEPT 0 + //#define SPEED_POWER_MIN 10 + //#define SPEED_POWER_MAX 100 // 0-100% +#endif + +/** + * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins + */ +//#define PINS_DEBUGGING + +/** + * Auto-report temperatures with M155 S + */ +#define AUTO_REPORT_TEMPERATURES + +/** + * Include capabilities in M115 output + */ +#define EXTENDED_CAPABILITIES_REPORT + +/** + * Volumetric extrusion default state + * 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. + */ +//#define VOLUMETRIC_DEFAULT_ON + +/** + * Enable this option for a leaner build of Marlin that removes all + * workspace offsets, simplifying coordinate transformations, leveling, etc. + * + * - M206 and M428 are disabled. + * - G92 will revert to its behavior from Marlin 1.0. + */ +//#define NO_WORKSPACE_OFFSETS + +/** + * 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. + * + * For clients that use a fixed-width font (like OctoPrint), leave this set to 1.0. + * Otherwise, adjust according to your client and font. + */ +#define PROPORTIONAL_FONT_RATIO 1.0 + +/** + * Spend 28 bytes of SRAM to optimize the GCode parser + */ +#define FASTER_GCODE_PARSER + +/** + * User-defined menu items that execute custom GCode + */ +//#define CUSTOM_USER_MENUS +#if ENABLED(CUSTOM_USER_MENUS) + #define USER_SCRIPT_DONE "M117 User Script Done" + #define USER_SCRIPT_AUDIBLE_FEEDBACK + //#define USER_SCRIPT_RETURN // Return to status screen after a script + + #define USER_DESC_1 "Home & UBL Info" + #define USER_GCODE_1 "G28\nG29 W" + + #define USER_DESC_2 "Preheat for PLA" + #define USER_GCODE_2 "M140 S" STRINGIFY(PREHEAT_1_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND) + + #define USER_DESC_3 "Preheat for ABS" + #define USER_GCODE_3 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND) + + #define USER_DESC_4 "Heat Bed/Home/Level" + #define USER_GCODE_4 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nG28\nG29" + + //#define USER_DESC_5 "Home & Info" + //#define USER_GCODE_5 "G28\nM503" +#endif + +/** + * Specify an action command to send to the host when the printer is killed. + * Will be sent in the form '//action:ACTION_ON_KILL', e.g. '//action:poweroff'. + * The host must be configured to handle the action command. + */ +//#define ACTION_ON_KILL "poweroff" + +//=========================================================================== +//====================== I2C Position Encoder Settings ====================== +//=========================================================================== + +/** + * I2C position encoders for closed loop control. + * Developed by Chris Barr at Aus3D. + * + * Wiki: http://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/ + * + * Reilabuild encoders have been modified to improve reliability. + */ + +//#define I2C_POSITION_ENCODERS +#if ENABLED(I2C_POSITION_ENCODERS) + + #define I2CPE_ENCODER_CNT 1 // The number of encoders installed; max of 5 + // encoders supported currently. + + #define I2CPE_ENC_1_ADDR I2CPE_PRESET_ADDR_X // I2C address of the encoder. 30-200. + #define I2CPE_ENC_1_AXIS X_AXIS // Axis the encoder module is installed on. _AXIS. + #define I2CPE_ENC_1_TYPE I2CPE_ENC_TYPE_LINEAR // Type of encoder: I2CPE_ENC_TYPE_LINEAR -or- + // I2CPE_ENC_TYPE_ROTARY. + #define I2CPE_ENC_1_TICKS_UNIT 2048 // 1024 for magnetic strips with 2mm poles; 2048 for + // 1mm poles. For linear encoders this is ticks / mm, + // for rotary encoders this is ticks / revolution. + //#define I2CPE_ENC_1_TICKS_REV (16 * 200) // Only needed for rotary encoders; number of stepper + // steps per full revolution (motor steps/rev * microstepping) + //#define I2CPE_ENC_1_INVERT // Invert the direction of axis travel. + #define I2CPE_ENC_1_EC_METHOD I2CPE_ECM_NONE // Type of error error correction. + #define I2CPE_ENC_1_EC_THRESH 0.10 // Threshold size for error (in mm) above which the + // printer will attempt to correct the error; errors + // smaller than this are ignored to minimize effects of + // measurement noise / latency (filter). + + #define I2CPE_ENC_2_ADDR I2CPE_PRESET_ADDR_Y // Same as above, but for encoder 2. + #define I2CPE_ENC_2_AXIS Y_AXIS + #define I2CPE_ENC_2_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_ENC_2_TICKS_UNIT 2048 + //#define I2CPE_ENC_2_TICKS_REV (16 * 200) + //#define I2CPE_ENC_2_INVERT + #define I2CPE_ENC_2_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_ENC_2_EC_THRESH 0.10 + + #define I2CPE_ENC_3_ADDR I2CPE_PRESET_ADDR_Z // Encoder 3. Add additional configuration options + #define I2CPE_ENC_3_AXIS Z_AXIS // as above, or use defaults below. + + #define I2CPE_ENC_4_ADDR I2CPE_PRESET_ADDR_E // Encoder 4. + #define I2CPE_ENC_4_AXIS E_AXIS + + #define I2CPE_ENC_5_ADDR 34 // Encoder 5. + #define I2CPE_ENC_5_AXIS E_AXIS + + // Default settings for encoders which are enabled, but without settings configured above. + #define I2CPE_DEF_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_DEF_ENC_TICKS_UNIT 2048 + #define I2CPE_DEF_TICKS_REV (16 * 200) + #define I2CPE_DEF_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_DEF_EC_THRESH 0.1 + + //#define I2CPE_ERR_THRESH_ABORT 100.0 // Threshold size for error (in mm) error on any given + // axis after which the printer will abort. Comment out to + // disable abort behaviour. + + #define I2CPE_TIME_TRUSTED 10000 // After an encoder fault, there must be no further fault + // for this amount of time (in ms) before the encoder + // is trusted again. + + /** + * Position is checked every time a new command is executed from the buffer but during long moves, + * this setting determines the minimum update time between checks. A value of 100 works well with + * error rolling average when attempting to correct only for skips and not for vibration. + */ + #define I2CPE_MIN_UPD_TIME_MS 100 // Minimum time in miliseconds between encoder checks. + + // Use a rolling average to identify persistant errors that indicate skips, as opposed to vibration and noise. + #define I2CPE_ERR_ROLLING_AVERAGE + +#endif // I2C_POSITION_ENCODERS + +/** + * MAX7219 Debug Matrix + * + * Add support for a low-cost 8x8 LED Matrix based on the Max7219 chip, which can be used as a status + * display. Requires 3 signal wires. Some useful debug options are included to demonstrate its usage. + * + * Fully assembled MAX7219 boards can be found on the internet for under $2(US). + * For example, see https://www.ebay.com/sch/i.html?_nkw=332349290049 + */ +//#define MAX7219_DEBUG +#if ENABLED(MAX7219_DEBUG) + #define MAX7219_CLK_PIN 64 // 77 on Re-ARM // Configuration of the 3 pins to control the display + #define MAX7219_DIN_PIN 57 // 78 on Re-ARM + #define MAX7219_LOAD_PIN 44 // 79 on Re-ARM + + /** + * Sample debug features + * If you add more debug displays, be careful to avoid conflicts! + */ + #define MAX7219_DEBUG_PRINTER_ALIVE // Blink corner LED of 8x8 matrix to show that the firmware is functioning + #define MAX7219_DEBUG_STEPPER_HEAD 3 // Show the stepper queue head position on this and the next LED matrix row + #define MAX7219_DEBUG_STEPPER_TAIL 5 // Show the stepper queue tail position on this and the next LED matrix row + + #define MAX7219_DEBUG_STEPPER_QUEUE 0 // Show the current stepper queue depth on this and the next LED matrix row + // If you experience stuttering, reboots, etc. this option can reveal how + // tweaks made to the configuration are affecting the printer in real-time. +#endif + +#endif // CONFIGURATION_ADV_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/tvrrug/Round2/Configuration.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/tvrrug/Round2/Configuration.h new file mode 100644 index 00000000..d27812f5 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/tvrrug/Round2/Configuration.h @@ -0,0 +1,1695 @@ +/** + * 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 . + * + */ + +/** + * Configuration.h + * + * Basic settings such as: + * + * - Type of electronics + * - Type of temperature sensor + * - Printer geometry + * - Endstop configuration + * - LCD controller + * - Extra features + * + * Advanced settings can be found in Configuration_adv.h + * + */ +#ifndef CONFIGURATION_H +#define CONFIGURATION_H +#define CONFIGURATION_H_VERSION 010100 + +//=========================================================================== +//============================= Getting Started ============================= +//=========================================================================== + +/** + * Here are some standard links for getting your machine calibrated: + * + * http://reprap.org/wiki/Calibration + * http://youtu.be/wAL9d7FgInk + * http://calculator.josefprusa.cz + * http://reprap.org/wiki/Triffid_Hunter%27s_Calibration_Guide + * http://www.thingiverse.com/thing:5573 + * https://sites.google.com/site/repraplogphase/calibration-of-your-reprap + * http://www.thingiverse.com/thing:298812 + */ + +//=========================================================================== +//============================= DELTA Printer =============================== +//=========================================================================== +// For a Delta printer start with one of the configuration files in the +// example_configurations/delta directory and customize for your machine. +// + +//=========================================================================== +//============================= SCARA Printer =============================== +//=========================================================================== +// For a SCARA printer start with the configuration files in +// example_configurations/SCARA and customize for your machine. +// + +// @section info + +// User-specified version info of this build to display in [Pronterface, etc] terminal window during +// startup. Implementation of an idea by Prof Braino to inform user that any changes made to this +// build by the user have been successfully uploaded into firmware. +#define STRING_CONFIG_H_AUTHOR "(none, default config)" // Who made the changes. +#define SHOW_BOOTSCREEN +#define STRING_SPLASH_LINE1 SHORT_BUILD_VERSION // will be shown during bootup in line 1 +#define STRING_SPLASH_LINE2 WEBSITE_URL // will be shown during bootup in line 2 + +// +// *** VENDORS PLEASE READ ***************************************************** +// +// Marlin now allow you to have a vendor boot image to be displayed on machine +// start. When SHOW_CUSTOM_BOOTSCREEN is defined Marlin will first show your +// custom boot image and then the default Marlin boot image is shown. +// +// We suggest for you to take advantage of this new feature and keep the Marlin +// boot image unmodified. For an example have a look at the bq Hephestos 2 +// example configuration folder. +// +//#define SHOW_CUSTOM_BOOTSCREEN +// @section machine + +/** + * Select which serial port on the board will be used for communication with the host. + * This allows the connection of wireless adapters (for instance) to non-default port pins. + * Serial port 0 is always used by the Arduino bootloader regardless of this setting. + * + * :[0, 1, 2, 3, 4, 5, 6, 7] + */ +#define SERIAL_PORT 0 + +/** + * This setting determines the communication speed of the printer. + * + * 250000 works in most cases, but you might try a lower speed if + * you commonly experience drop-outs during host printing. + * You may try up to 1000000 to speed up SD file transfer. + * + * :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000] + */ +#define BAUDRATE 250000 + +// Enable the Bluetooth serial interface on AT90USB devices +//#define BLUETOOTH + +// The following define selects which electronics board you have. +// Please choose the name from boards.h that matches your setup +#ifndef MOTHERBOARD + #define MOTHERBOARD BOARD_OMCA +#endif + +// Optional custom name for your RepStrap or other custom machine +// Displayed in the LCD "Ready" message +//#define CUSTOM_MACHINE_NAME "3D Printer" + +// Define this to set a unique identifier for this printer, (Used by some programs to differentiate between machines) +// You can use an online service to generate a random UUID. (eg http://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] +#define EXTRUDERS 1 + +// For Cyclops or any "multi-extruder" that shares a single nozzle. +//#define SINGLENOZZLE + +/** + * Průša MK2 Single Nozzle Multi-Material Multiplexer, and variants. + * + * This device allows one stepper driver on a control board to drive + * two to eight stepper motors, one at a time, in a manner suitable + * for extruders. + * + * This option only allows the multiplexer to switch on tool-change. + * Additional options to configure custom E moves are pending. + */ +//#define MK2_MULTIPLEXER +#if ENABLED(MK2_MULTIPLEXER) + // Override the default DIO selector pins here, if needed. + // Some pins files may provide defaults for these pins. + //#define E_MUX0_PIN 40 // Always Required + //#define E_MUX1_PIN 42 // Needed for 3 to 8 steppers + //#define E_MUX2_PIN 44 // Needed for 5 to 8 steppers +#endif + +// A dual extruder that uses a single stepper motor +//#define SWITCHING_EXTRUDER +#if ENABLED(SWITCHING_EXTRUDER) + #define SWITCHING_EXTRUDER_SERVO_NR 0 + #define SWITCHING_EXTRUDER_SERVO_ANGLES { 0, 90 } // Angles for E0, E1[, E2, E3] + #if EXTRUDERS > 3 + #define SWITCHING_EXTRUDER_E23_SERVO_NR 1 + #endif +#endif + +// A dual-nozzle that uses a servomotor to raise/lower one of the nozzles +//#define SWITCHING_NOZZLE +#if ENABLED(SWITCHING_NOZZLE) + #define SWITCHING_NOZZLE_SERVO_NR 0 + #define SWITCHING_NOZZLE_SERVO_ANGLES { 0, 90 } // Angles for E0, E1 + //#define HOTEND_OFFSET_Z { 0.0, 0.0 } +#endif + +/** + * Two separate X-carriages with extruders that connect to a moving part + * via a magnetic docking mechanism. Requires SOL1_PIN and SOL2_PIN. + */ +//#define PARKING_EXTRUDER +#if ENABLED(PARKING_EXTRUDER) + #define PARKING_EXTRUDER_SOLENOIDS_INVERT // If enabled, the solenoid is NOT magnetized with applied voltage + #define PARKING_EXTRUDER_SOLENOIDS_PINS_ACTIVE LOW // LOW or HIGH pin signal energizes the coil + #define PARKING_EXTRUDER_SOLENOIDS_DELAY 250 // Delay (ms) for magnetic field. No delay if 0 or not defined. + #define PARKING_EXTRUDER_PARKING_X { -78, 184 } // X positions for parking the extruders + #define PARKING_EXTRUDER_GRAB_DISTANCE 1 // mm to move beyond the parking point to grab the extruder + #define PARKING_EXTRUDER_SECURITY_RAISE 5 // Z-raise before parking + #define HOTEND_OFFSET_Z { 0.0, 1.3 } // Z-offsets of the two hotends. The first must be 0. +#endif + +/** + * "Mixing Extruder" + * - Adds a new code, M165, to set the current mix factors. + * - Extends the stepping routines to move multiple steppers in proportion to the mix. + * - Optional support for Repetier Firmware M163, M164, and virtual extruder. + * - This implementation supports only a single extruder. + * - Enable DIRECT_MIXING_IN_G1 for Pia Taubert's reference implementation + */ +//#define MIXING_EXTRUDER +#if ENABLED(MIXING_EXTRUDER) + #define MIXING_STEPPERS 2 // Number of steppers in your mixing extruder + #define MIXING_VIRTUAL_TOOLS 16 // Use the Virtual Tool method with M163 and M164 + //#define DIRECT_MIXING_IN_G1 // Allow ABCDHI mix factors in G1 movement commands +#endif + +// Offset of the extruders (uncomment if using more than one and relying on firmware to position when changing). +// The offset has to be X=0, Y=0 for the extruder 0 hotend (default extruder). +// For the other hotends it is their distance from the extruder 0 hotend. +//#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis +//#define HOTEND_OFFSET_Y {0.0, 5.00} // (in mm) for each extruder, offset of the hotend on the Y axis + +// @section machine + +/** + * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN + * + * 0 = No Power Switch + * 1 = ATX + * 2 = X-Box 360 203Watts (the blue wire connected to PS_ON and the red wire to VCC) + * + * :{ 0:'No power switch', 1:'ATX', 2:'X-Box 360' } + */ +#define POWER_SUPPLY 1 + +#if POWER_SUPPLY > 0 + // Enable this option to leave the PSU off at startup. + // Power to steppers and heaters will need to be turned on with M80. + //#define PS_DEFAULT_OFF +#endif + +// @section temperature + +//=========================================================================== +//============================= Thermal Settings ============================ +//=========================================================================== + +/** + * --NORMAL IS 4.7kohm PULLUP!-- 1kohm pullup can be used on hotend sensor, using correct resistor and table + * + * Temperature sensors available: + * + * -3 : thermocouple with MAX31855 (only for sensor 0) + * -2 : thermocouple with MAX6675 (only for sensor 0) + * -1 : thermocouple with AD595 + * 0 : not used + * 1 : 100k thermistor - best choice for EPCOS 100k (4.7k pullup) + * 2 : 200k thermistor - ATC Semitec 204GT-2 (4.7k pullup) + * 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 (Used in ParCan & J-Head) (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) + * 71 : 100k Honeywell thermistor 135-104LAF-J01 (4.7k pullup) + * 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) + * 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" + * 20 : the PT100 circuit found in the Ultimainboard V2.x + * 60 : 100k Maker's Tool Works Kapton Bed Thermistor beta=3950 + * 66 : 4.7M High Temperature thermistor from Dyze Design + * 70 : the 100K thermistor found in the bq Hephestos 2 + * 75 : 100k Generic Silicon Heat Pad with NTC 100K MGB18-104F39050L32 thermistor + * + * 1k ohm pullup tables - This is atypical, and requires changing out the 4.7k pullup for 1k. + * (but gives greater accuracy and more stable PID) + * 51 : 100k thermistor - EPCOS (1k pullup) + * 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 + * 1010 : Pt1000 with 1k pullup (non standard) + * 147 : Pt100 with 4k7 pullup + * 110 : Pt100 with 1k pullup (non standard) + * + * Use these for Testing or Development purposes. NEVER for production machine. + * 998 : Dummy Table that ALWAYS reads 25°C or the temperature defined below. + * 999 : Dummy Table that ALWAYS reads 100°C or the temperature defined below. + * + * :{ '0': "Not used", '1':"100k / 4.7k - EPCOS", '2':"200k / 4.7k - ATC Semitec 204GT-2", '3':"Mendel-parts / 4.7k", '4':"10k !! do not use for a hotend. Bad resolution at high temp. !!", '5':"100K / 4.7k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '6':"100k / 4.7k EPCOS - Not as accurate as Table 1", '7':"100k / 4.7k Honeywell 135-104LAG-J01", '8':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT", '9':"100k / 4.7k GE Sensing AL03006-58.2K-97-G1", '10':"100k / 4.7k RS 198-961", '11':"100k / 4.7k beta 3950 1%", '12':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT (calibrated for Makibox hot bed)", '13':"100k Hisens 3950 1% up to 300°C for hotend 'Simple ONE ' & hotend 'All In ONE'", '20':"PT100 (Ultimainboard V2.x)", '51':"100k / 1k - EPCOS", '52':"200k / 1k - ATC Semitec 204GT-2", '55':"100k / 1k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '60':"100k Maker's Tool Works Kapton Bed Thermistor beta=3950", '66':"Dyze Design 4.7M High Temperature thermistor", '70':"the 100K thermistor found in the bq Hephestos 2", '71':"100k / 4.7k Honeywell 135-104LAF-J01", '147':"Pt100 / 4.7k", '1047':"Pt1000 / 4.7k", '110':"Pt100 / 1k (non-standard)", '1010':"Pt1000 / 1k (non standard)", '-3':"Thermocouple + MAX31855 (only for sensor 0)", '-2':"Thermocouple + MAX6675 (only for sensor 0)", '-1':"Thermocouple + AD595",'998':"Dummy 1", '999':"Dummy 2" } + */ +#define TEMP_SENSOR_0 5 +#define TEMP_SENSOR_1 0 +#define TEMP_SENSOR_2 0 +#define TEMP_SENSOR_3 0 +#define TEMP_SENSOR_4 0 +#define TEMP_SENSOR_BED 5 + +// Dummy thermistor constant temperature readings, for use with 998 and 999 +#define DUMMY_THERMISTOR_998_VALUE 25 +#define DUMMY_THERMISTOR_999_VALUE 100 + +// 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 +#define MAX_REDUNDANT_TEMP_SENSOR_DIFF 10 + +// Extruder temperature must be close to target for this long before M109 returns success +#define TEMP_RESIDENCY_TIME 10 // (seconds) +#define TEMP_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// Bed temperature must be close to target for this long before M190 returns success +#define TEMP_BED_RESIDENCY_TIME 0 // (seconds) +#define TEMP_BED_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_BED_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// The minimal temperature defines the temperature below which the heater will not be enabled It is used +// to check that the wiring to the thermistor is not broken. +// Otherwise this would lead to the heater being powered on all the time. +#define HEATER_0_MINTEMP 5 +#define HEATER_1_MINTEMP 5 +#define HEATER_2_MINTEMP 5 +#define HEATER_3_MINTEMP 5 +#define HEATER_4_MINTEMP 5 +#define BED_MINTEMP 5 + +// When temperature exceeds max temp, your heater will be switched off. +// This feature exists to protect your hotend from overheating accidentally, but *NOT* from thermistor short/failure! +// You should use MINTEMP for thermistor short/failure protection. +#define HEATER_0_MAXTEMP 275 +#define HEATER_1_MAXTEMP 275 +#define HEATER_2_MAXTEMP 275 +#define HEATER_3_MAXTEMP 275 +#define HEATER_4_MAXTEMP 275 +#define BED_MAXTEMP 150 + +//=========================================================================== +//============================= PID Settings ================================ +//=========================================================================== +// PID Tuning Guide here: http://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 +#if ENABLED(PIDTEMP) + //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. + //#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. + #define K1 0.95 //smoothing factor within the PID + + // If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it + // J-Head Mk V-B + #define DEFAULT_Kp 25.05 + #define DEFAULT_Ki 2.30 + #define DEFAULT_Kd 68.15 + +#endif // PIDTEMP + +//=========================================================================== +//============================= PID > Bed Temperature Control =============== +//=========================================================================== +// Select PID or bang-bang with PIDTEMPBED. If bang-bang, BED_LIMIT_SWITCHING will enable hysteresis +// +// Uncomment this to enable PID on the bed. It uses the same frequency PWM as the extruder. +// If your PID_dT is the default, and correct for your hardware/configuration, that means 7.689Hz, +// which is fine for driving a square wave into a resistive load and does not significantly impact you FET heating. +// This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W heater. +// If your configuration is significantly different than this and you don't understand the issues involved, you probably +// shouldn't use bed PID until someone else verifies your hardware works. +// If this is enabled, find your own PID constants below. +//#define PIDTEMPBED + +//#define BED_LIMIT_SWITCHING + +// This sets the max power delivered to the bed, and replaces the HEATER_BED_DUTY_CYCLE_DIVIDER option. +// all forms of bed control obey this (PID, bang-bang, bang-bang with hysteresis) +// setting this to anything other than 255 enables a form of PWM to the bed just like HEATER_BED_DUTY_CYCLE_DIVIDER did, +// so you shouldn't use it unless you are OK with PWM on your bed. (see the comment on enabling PIDTEMPBED) +#define MAX_BED_POWER 255 // limits duty cycle to bed; 255=full current + +#if ENABLED(PIDTEMPBED) + + //#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) + #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 + +// @section extruder + +// This option prevents extrusion if the temperature is below EXTRUDE_MINTEMP. +// It also enables the M302 command to set the minimum extrusion temperature +// or to allow moving the extruder regardless of the hotend temperature. +// *** IT IS HIGHLY RECOMMENDED TO LEAVE THIS OPTION ENABLED! *** +#define PREVENT_COLD_EXTRUSION +#define EXTRUDE_MINTEMP 170 + +// This option prevents a single extrusion longer than EXTRUDE_MAXLENGTH. +// Note that for Bowden Extruders a too-small value here may prevent loading. +#define PREVENT_LENGTHY_EXTRUDE +#define EXTRUDE_MAXLENGTH 200 + +//=========================================================================== +//======================== Thermal Runaway Protection ======================= +//=========================================================================== + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * If you get "Thermal Runaway" or "Heating failed" errors the + * details can be tuned in Configuration_adv.h + */ + +#define THERMAL_PROTECTION_HOTENDS // Enable thermal protection for all extruders +#define THERMAL_PROTECTION_BED // Enable thermal protection for the heated bed + +//=========================================================================== +//============================= Mechanical Settings ========================= +//=========================================================================== + +// @section machine + +// Uncomment one of these options to enable CoreXY, CoreXZ, or CoreYZ kinematics +// either in the usual order or reversed +//#define COREXY +//#define COREXZ +//#define COREYZ +//#define COREYX +//#define COREZX +//#define COREZY + +//=========================================================================== +//============================== Endstop Settings =========================== +//=========================================================================== + +// @section homing + +// Specify here all the endstop connectors that are connected to any endstop or probe. +// Almost all printers will be using one per axis. Probes will use one or more of the +// extra connectors. Leave undefined any used for non-endstop and non-probe purposes. +#define USE_XMIN_PLUG +#define USE_YMIN_PLUG +#define USE_ZMIN_PLUG +//#define USE_XMAX_PLUG +//#define USE_YMAX_PLUG +//#define USE_ZMAX_PLUG + +// coarse Endstop Settings +#define ENDSTOPPULLUPS // Comment this out (using // at the start of the line) to disable the endstop pullup resistors + +#if DISABLED(ENDSTOPPULLUPS) + // fine endstop settings: Individual pullups. will be ignored if ENDSTOPPULLUPS is defined + //#define ENDSTOPPULLUP_XMAX + //#define ENDSTOPPULLUP_YMAX + //#define ENDSTOPPULLUP_ZMAX + //#define ENDSTOPPULLUP_XMIN + //#define ENDSTOPPULLUP_YMIN + //#define ENDSTOPPULLUP_ZMIN + //#define ENDSTOPPULLUP_ZMIN_PROBE +#endif + +// Mechanical endstop with COM to ground and NC to Signal uses "false" here (most common setup). +#define X_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Y_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define X_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Y_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MIN_PROBE_ENDSTOP_INVERTING true // set to true to invert the logic of the probe. + +// Enable this feature if all enabled endstop pins are interrupt-capable. +// This will remove the need to poll the interrupt pins, saving many CPU cycles. +//#define ENDSTOP_INTERRUPTS_FEATURE + +//============================================================================= +//============================== Movement Settings ============================ +//============================================================================= +// @section motion + +/** + * Default Settings + * + * These settings can be reset by M502 + * + * Note that if EEPROM is enabled, saved values will override these. + */ + +/** + * With this option each E stepper can have its own factors for the + * following movement settings. If fewer factors are given than the + * total number of extruders, the last value applies to the rest. + */ +//#define DISTINCT_E_FACTORS + +/** + * Default Axis Steps Per Unit (steps/mm) + * Override with M92 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_AXIS_STEPS_PER_UNIT { 71.1, 71.1, 2560, 600 } // David TVRR + +//#define DEFAULT_AXIS_STEPS_PER_UNIT { 79.87, 79.87, 2566, 563.78 } // Al's TVRR +//#define DEFAULT_AXIS_STEPS_PER_UNIT { 81.26, 80.01, 2561, 599.14 } // Michel TVRR old +//#define DEFAULT_AXIS_STEPS_PER_UNIT { 71.1, 71.1, 2560, 739.65 } // Michel TVRR + +/** + * Default Max Feed Rate (mm/s) + * Override with M203 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_FEEDRATE { 500, 500, 5, 45 } // David TVRR + +/** + * Default Max Acceleration (change/s) change = mm/s + * (Maximum start speed for accelerated moves) + * Override with M201 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_ACCELERATION { 9000, 9000, 100, 10000 } + +/* MICHEL: This has an impact on the "ripples" in print walls */ + +/** + * Default Acceleration (change/s) change = mm/s + * Override with M204 + * + * M204 P Acceleration + * M204 R Retract Acceleration + * M204 T Travel Acceleration + */ +#define DEFAULT_ACCELERATION 500 // X, Y, Z and E acceleration for printing moves +#define DEFAULT_RETRACT_ACCELERATION 3000 // E acceleration for retracts +#define DEFAULT_TRAVEL_ACCELERATION 500 // X, Y, Z acceleration for travel (non printing) moves + +/** + * Default Jerk (mm/s) + * Override with M205 X Y Z E + * + * "Jerk" specifies the minimum speed change that requires acceleration. + * When changing speed and direction, if the difference is less than the + * value set here, it may happen instantaneously. + */ +#define DEFAULT_XJERK 20.0 +#define DEFAULT_YJERK 20.0 +#define DEFAULT_ZJERK 0.4 +#define DEFAULT_EJERK 5.0 + +//=========================================================================== +//============================= Z Probe Options ============================= +//=========================================================================== +// @section probes + +// +// See http://marlinfw.org/configuration/probes.html +// + +/** + * Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + * + * Enable this option for a probe connected to the Z Min endstop pin. + */ +#define Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + +/** + * Z_MIN_PROBE_ENDSTOP + * + * Enable this option for a probe connected to any pin except Z-Min. + * (By default Marlin assumes the Z-Max endstop pin.) + * To use a custom Z Probe pin, set Z_MIN_PROBE_PIN below. + * + * - The simplest option is to use a free endstop connector. + * - Use 5V for powered (usually inductive) sensors. + * + * - RAMPS 1.3/1.4 boards may use the 5V, GND, and Aux4->D32 pin: + * - For simple switches connect... + * - normally-closed switches to GND and D32. + * - normally-open switches to 5V and D32. + * + * WARNING: Setting the wrong pin may have unexpected and potentially + * disastrous consequences. Use with caution and do your homework. + * + */ +//#define Z_MIN_PROBE_ENDSTOP + +/** + * Probe Type + * + * Allen Key Probes, Servo Probes, Z-Sled Probes, FIX_MOUNTED_PROBE, etc. + * Activate one of these to use Auto Bed Leveling below. + */ + +/** + * The "Manual Probe" provides a means to do "Auto" Bed Leveling without a probe. + * Use G29 repeatedly, adjusting the Z height at each point with movement commands + * or (with LCD_BED_LEVELING) the LCD controller. + */ +//#define PROBE_MANUALLY + +/** + * A Fix-Mounted Probe either doesn't deploy or needs manual deployment. + * (e.g., an inductive probe or a nozzle-based probe-switch.) + */ +//#define FIX_MOUNTED_PROBE + +/** + * Z Servo Probe, such as an endstop switch on a rotating arm. + */ +//#define Z_ENDSTOP_SERVO_NR 0 // Defaults to SERVO 0 connector. +//#define Z_SERVO_ANGLES {70,0} // Z Servo Deploy and Stow angles + +/** + * The BLTouch probe uses a Hall effect sensor and emulates a servo. + */ +//#define BLTOUCH +#if ENABLED(BLTOUCH) + //#define BLTOUCH_DELAY 375 // (ms) Enable and increase if needed +#endif + +/** + * Enable one or more of the following if probing seems unreliable. + * Heaters and/or fans can be disabled during probing to minimize electrical + * noise. A delay can also be added to allow noise and vibration to settle. + * These options are most useful for the BLTouch probe, but may also improve + * readings with inductive probes and piezo sensors. + */ +//#define PROBING_HEATERS_OFF // Turn heaters off when probing +//#define PROBING_FANS_OFF // Turn fans off when probing +//#define DELAY_BEFORE_PROBING 200 // (ms) To prevent vibrations from triggering piezo sensors + +// A probe that is deployed and stowed with a solenoid pin (SOL1_PIN) +//#define SOLENOID_PROBE + +// A sled-mounted probe like those designed by Charles Bell. +//#define Z_PROBE_SLED +//#define SLED_DOCKING_OFFSET 5 // The extra distance the X axis must travel to pickup the sled. 0 should be fine but you can push it further if you'd like. + +// +// For Z_PROBE_ALLEN_KEY see the Delta example configurations. +// + +/** + * Z Probe to nozzle (X,Y) offset, relative to (0, 0). + * X and Y offsets must be integers. + * + * In the following example the X and Y offsets are both positive: + * #define X_PROBE_OFFSET_FROM_EXTRUDER 10 + * #define Y_PROBE_OFFSET_FROM_EXTRUDER 10 + * + * +-- BACK ---+ + * | | + * L | (+) P | R <-- probe (20,20) + * E | | I + * F | (-) N (+) | G <-- nozzle (10,10) + * T | | H + * | (-) | T + * | | + * O-- FRONT --+ + * (0,0) + */ +#define X_PROBE_OFFSET_FROM_EXTRUDER -25 // X offset: -left +right [of the nozzle] +#define Y_PROBE_OFFSET_FROM_EXTRUDER -29 // Y offset: -front +behind [the nozzle] +#define Z_PROBE_OFFSET_FROM_EXTRUDER -12.35 // Z offset: -below +above [the nozzle] + +// X and Y axis travel speed (mm/m) between probes +#define XY_PROBE_SPEED 8000 + +// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +#define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z + +// Speed for the "accurate" probe of each point +#define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) + +// Use double touch for probing +//#define PROBE_DOUBLE_TOUCH + +/** + * Z probes require clearance when deploying, stowing, and moving between + * probe points to avoid hitting the bed and other hardware. + * Servo-mounted probes require extra space for the arm to rotate. + * Inductive probes need space to keep from triggering early. + * + * Use these settings to specify the distance (mm) to raise the probe (or + * lower the bed). The values set here apply over and above any (negative) + * probe Z Offset set with Z_PROBE_OFFSET_FROM_EXTRUDER, M851, or the LCD. + * Only integer values >= 1 are valid here. + * + * Example: `M851 Z-5` with a CLEARANCE of 4 => 9mm from bed to nozzle. + * But: `M851 Z+1` with a CLEARANCE of 2 => 2mm from bed to nozzle. + */ +#define Z_CLEARANCE_DEPLOY_PROBE 15 // Z Clearance for Deploy/Stow +#define Z_CLEARANCE_BETWEEN_PROBES 5 // Z Clearance between probe points + +// For M851 give a range for adjusting the Z probe offset +#define Z_PROBE_OFFSET_RANGE_MIN -20 +#define Z_PROBE_OFFSET_RANGE_MAX 20 + +// Enable the M48 repeatability test to test probe accuracy +//#define Z_MIN_PROBE_REPEATABILITY_TEST + +// For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1 +// :{ 0:'Low', 1:'High' } +#define X_ENABLE_ON 1 +#define Y_ENABLE_ON 1 +#define Z_ENABLE_ON 1 +#define E_ENABLE_ON 1 // For all extruders + +// Disables axis stepper immediately when it's not being used. +// 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 +//#define DISABLE_REDUCED_ACCURACY_WARNING + +// @section extruder + +#define DISABLE_E false // For all extruders +#define DISABLE_INACTIVE_EXTRUDER true // Keep only the active extruder enabled. + +// @section machine + +// Invert the stepper direction. Change (or reverse the motor connector) if an axis goes the wrong way. +#define INVERT_X_DIR false +#define INVERT_Y_DIR false +#define INVERT_Z_DIR true + +// Enable this option for Toshiba stepper drivers +#define CONFIG_STEPPERS_TOSHIBA + +// @section extruder + +// For direct drive extruder v9 set to true, for geared extruder set to false. +#define INVERT_E0_DIR false +#define INVERT_E1_DIR false +#define INVERT_E2_DIR false +#define INVERT_E3_DIR false +#define INVERT_E4_DIR false + +// @section homing + +//#define NO_MOTION_BEFORE_HOMING // Inhibit movement until all axes have been homed + +//#define Z_HOMING_HEIGHT 4 // (in mm) Minimal z height before homing (G28) for Z clearance above the bed, clamps, ... + // Be sure you have this distance over your Z_MAX_POS in case. + +// Direction of endstops when homing; 1=MAX, -1=MIN +// :[-1,1] +#define X_HOME_DIR -1 +#define Y_HOME_DIR -1 +#define Z_HOME_DIR -1 + +// @section machine + +// The size of the print bed +#define X_BED_SIZE 205 +#define Y_BED_SIZE 205 + +// Travel limits (mm) after homing, corresponding to endstop positions. +#define X_MIN_POS 0 +#define Y_MIN_POS 0 +#define Z_MIN_POS 0 +#define X_MAX_POS X_BED_SIZE +#define Y_MAX_POS Y_BED_SIZE +#define Z_MAX_POS 120 + +// If enabled, axes won't move below MIN_POS in response to movement commands. +#define MIN_SOFTWARE_ENDSTOPS +// If enabled, axes won't move above MAX_POS in response to movement commands. +#define MAX_SOFTWARE_ENDSTOPS + +/** + * Filament Runout Sensor + * A mechanical or opto endstop is used to check for the presence of filament. + * + * RAMPS-based boards use SERVO3_PIN. + * For other boards you may need to define FIL_RUNOUT_PIN. + * By default the firmware assumes HIGH = has filament, LOW = ran out + */ +//#define FILAMENT_RUNOUT_SENSOR +#if ENABLED(FILAMENT_RUNOUT_SENSOR) + #define FIL_RUNOUT_INVERTING false // set to true to invert the logic of the sensor. + #define ENDSTOPPULLUP_FIL_RUNOUT // Uncomment to use internal pullup for filament runout pins if the sensor is defined. + #define FILAMENT_RUNOUT_SCRIPT "M600" +#endif + +//=========================================================================== +//=============================== Bed Leveling ============================== +//=========================================================================== +// @section bedlevel + +/** + * Choose one of the options below to enable G29 Bed Leveling. The parameters + * and behavior of G29 will change depending on your selection. + * + * If using a Probe for Z Homing, enable Z_SAFE_HOMING also! + * + * - AUTO_BED_LEVELING_3POINT + * Probe 3 arbitrary points on the bed (that aren't collinear) + * You specify the XY coordinates of all 3 points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_LINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_BILINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a mesh, best for large or uneven beds. + * + * - AUTO_BED_LEVELING_UBL (Unified Bed Leveling) + * A comprehensive bed leveling system combining the features and benefits + * of other systems. UBL also includes integrated Mesh Generation, Mesh + * Validation and Mesh Editing systems. Currently, UBL is only checked out + * for Cartesian Printers. That said, it was primarily designed to correct + * poor quality Delta Printers. If you feel adventurous and have a Delta, + * please post an issue if something doesn't work correctly. Initially, + * you will need to set a reduced bed size so you have a rectangular area + * to test on. + * + * - MESH_BED_LEVELING + * Probe a grid manually + * The result is a mesh, suitable for large or uneven beds. (See BILINEAR.) + * For machines without a probe, Mesh Bed Leveling provides a method to perform + * leveling in steps so you can manually adjust the Z height at each grid-point. + * With an LCD controller the process is guided step-by-step. + */ +//#define AUTO_BED_LEVELING_3POINT +//#define AUTO_BED_LEVELING_LINEAR +//#define AUTO_BED_LEVELING_BILINEAR +//#define AUTO_BED_LEVELING_UBL +//#define MESH_BED_LEVELING + +/** + * Enable detailed logging of G28, G29, M48, etc. + * Turn on with the command 'M111 S32'. + * NOTE: Requires a lot of PROGMEM! + */ +//#define DEBUG_LEVELING_FEATURE + +#if ENABLED(MESH_BED_LEVELING) || ENABLED(AUTO_BED_LEVELING_BILINEAR) || ENABLED(AUTO_BED_LEVELING_UBL) + // Gradually reduce leveling correction until a set height is reached, + // at which point movement will be level to the machine's XY plane. + // The height can be set with M420 Z + #define ENABLE_LEVELING_FADE_HEIGHT +#endif + +#if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Set the number of grid points per dimension. + #define GRID_MAX_POINTS_X 3 + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + // Set the boundaries for probing (where the probe can reach). + #define LEFT_PROBE_BED_POSITION 15 + #define RIGHT_PROBE_BED_POSITION 170 + #define FRONT_PROBE_BED_POSITION 20 + #define BACK_PROBE_BED_POSITION 170 + + // The Z probe minimum outer margin (to validate G29 parameters). + #define MIN_PROBE_EDGE 10 + + // Probe along the Y axis, advancing X after each column + //#define PROBE_Y_FIRST + + #if ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Beyond the probed grid, continue the implied tilt? + // Default is to maintain the height of the nearest edge. + //#define EXTRAPOLATE_BEYOND_GRID + + // + // Experimental Subdivision of the grid by Catmull-Rom method. + // Synthesizes intermediate points to produce a more detailed mesh. + // + //#define ABL_BILINEAR_SUBDIVISION + #if ENABLED(ABL_BILINEAR_SUBDIVISION) + // Number of subdivisions between probe points + #define BILINEAR_SUBDIVISIONS 3 + #endif + + #endif + +#elif ENABLED(AUTO_BED_LEVELING_3POINT) + + // 3 arbitrary points to probe. + // A simple cross-product is used to estimate the plane of the bed. + #define ABL_PROBE_PT_1_X 15 + #define ABL_PROBE_PT_1_Y 180 + #define ABL_PROBE_PT_2_X 15 + #define ABL_PROBE_PT_2_Y 20 + #define ABL_PROBE_PT_3_X 170 + #define ABL_PROBE_PT_3_Y 20 + +#elif ENABLED(AUTO_BED_LEVELING_UBL) + + //=========================================================================== + //========================= Unified Bed Leveling ============================ + //=========================================================================== + + #define UBL_MESH_INSET 1 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 10 // Don't use more than 15 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + #define UBL_PROBE_PT_1_X 39 // Probing points for 3-Point leveling of the mesh + #define UBL_PROBE_PT_1_Y 180 + #define UBL_PROBE_PT_2_X 39 + #define UBL_PROBE_PT_2_Y 20 + #define UBL_PROBE_PT_3_X 180 + #define UBL_PROBE_PT_3_Y 20 + + #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation + #define UBL_MESH_EDIT_MOVES_Z // Sophisticated users prefer no movement of nozzle + +#elif ENABLED(MESH_BED_LEVELING) + + //=========================================================================== + //=================================== Mesh ================================== + //=========================================================================== + + #define MESH_INSET 10 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 3 // Don't use more than 7 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + //#define MESH_G28_REST_ORIGIN // After homing all axes ('G28' or 'G28 XYZ') rest Z at Z_MIN_POS + +#endif // BED_LEVELING + +/** + * Use the LCD controller for bed leveling + * Requires MESH_BED_LEVELING or PROBE_MANUALLY + */ +//#define LCD_BED_LEVELING + +#if ENABLED(LCD_BED_LEVELING) + #define MBL_Z_STEP 0.025 // Step size while manually probing Z axis. + #define LCD_PROBE_Z_RANGE 4 // Z Range centered on Z_MIN_POS for LCD Z adjustment +#endif + +// Add a menu item to move between bed corners for manual bed adjustment +//#define LEVEL_BED_CORNERS + +/** + * Commands to execute at the end of G29 probing. + * Useful to retract or move the Z probe out of the way. + */ +//#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) +//#define BED_CENTER_AT_0_0 + +// Manually set the home position. Leave these undefined for automatic settings. +// For DELTA this is the top-center of the Cartesian print volume. +//#define MANUAL_X_HOME_POS 0 +//#define MANUAL_Y_HOME_POS 0 +//#define MANUAL_Z_HOME_POS 0 + +// Use "Z Safe Homing" to avoid homing with a Z probe outside the bed area. +// +// With this feature enabled: +// +// - 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). +// - 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 axis (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). +#endif + +// Homing speeds (mm/m) +#define HOMING_FEEDRATE_XY (50*60) +#define HOMING_FEEDRATE_Z (4*60) + +//============================================================================= +//============================= Additional Features =========================== +//============================================================================= + +// @section extras + +// +// EEPROM +// +// The microcontroller can store settings in the EEPROM, e.g. max velocity... +// M500 - stores parameters in EEPROM +// M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily). +// M502 - reverts to the default "factory settings". You still need to store them in EEPROM afterwards if you want to. +// +//#define EEPROM_SETTINGS // Enable for M500 and M501 commands +//#define DISABLE_M503 // Saves ~2700 bytes of PROGMEM. Disable for release! +#define EEPROM_CHITCHAT // Give feedback on EEPROM commands. Disable to save PROGMEM. + +// +// Host Keepalive +// +// When enabled Marlin will send a busy status message to the host +// every couple of seconds when it can't accept commands. +// +#define HOST_KEEPALIVE_FEATURE // Disable this if your host doesn't like keepalive messages +#define DEFAULT_KEEPALIVE_INTERVAL 2 // Number of seconds between "busy" messages. Set with M113. +#define BUSY_WHILE_HEATING // Some hosts require "busy" messages even during heating + +// +// M100 Free Memory Watcher +// +//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose + +// +// G20/G21 Inch mode support +// +//#define INCH_MODE_SUPPORT + +// +// M149 Set temperature units support +// +//#define TEMPERATURE_UNITS_SUPPORT + +// @section temperature + +// Preheat Constants +#define PREHEAT_1_TEMP_HOTEND 180 +#define PREHEAT_1_TEMP_BED 70 +#define PREHEAT_1_FAN_SPEED 255 // Value from 0 to 255 + +#define PREHEAT_2_TEMP_HOTEND 240 +#define PREHEAT_2_TEMP_BED 100 +#define PREHEAT_2_FAN_SPEED 255 // Value from 0 to 255 + +/** + * Nozzle Park -- EXPERIMENTAL + * + * Park the nozzle at the given XYZ position on idle or G27. + * + * The "P" parameter controls the action applied to the Z axis: + * + * P0 (Default) If Z is below park Z raise the nozzle. + * P1 Raise the nozzle always to Z-park height. + * P2 Raise the nozzle by Z-park amount, limited to Z_MAX_POS. + */ +//#define NOZZLE_PARK_FEATURE + +#if ENABLED(NOZZLE_PARK_FEATURE) + // Specify a park position as { X, Y, Z } + #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 } +#endif + +/** + * Clean Nozzle Feature -- EXPERIMENTAL + * + * Adds the G12 command to perform a nozzle cleaning process. + * + * Parameters: + * P Pattern + * S Strokes / Repetitions + * T Triangles (P1 only) + * + * Patterns: + * P0 Straight line (default). This process requires a sponge type material + * at a fixed bed location. "S" specifies strokes (i.e. back-forth motions) + * between the start / end points. + * + * P1 Zig-zag pattern between (X0, Y0) and (X1, Y1), "T" specifies the + * number of zig-zag triangles to do. "S" defines the number of strokes. + * Zig-zags are done in whichever is the narrower dimension. + * For example, "G12 P1 S1 T3" will execute: + * + * -- + * | (X0, Y1) | /\ /\ /\ | (X1, Y1) + * | | / \ / \ / \ | + * A | | / \ / \ / \ | + * | | / \ / \ / \ | + * | (X0, Y0) | / \/ \/ \ | (X1, Y0) + * -- +--------------------------------+ + * |________|_________|_________| + * T1 T2 T3 + * + * P2 Circular pattern with middle at NOZZLE_CLEAN_CIRCLE_MIDDLE. + * "R" specifies the radius. "S" specifies the stroke count. + * Before starting, the nozzle moves to NOZZLE_CLEAN_START_POINT. + * + * Caveats: The ending Z should be the same as starting Z. + * Attention: EXPERIMENTAL. G-code arguments may change. + * + */ +//#define NOZZLE_CLEAN_FEATURE + +#if ENABLED(NOZZLE_CLEAN_FEATURE) + // Default number of pattern repetitions + #define NOZZLE_CLEAN_STROKES 12 + + // Default number of triangles + #define NOZZLE_CLEAN_TRIANGLES 3 + + // Specify positions as { X, Y, Z } + #define NOZZLE_CLEAN_START_POINT { 30, 30, (Z_MIN_POS + 1)} + #define NOZZLE_CLEAN_END_POINT {100, 60, (Z_MIN_POS + 1)} + + // Circular pattern radius + #define NOZZLE_CLEAN_CIRCLE_RADIUS 6.5 + // Circular pattern circle fragments number + #define NOZZLE_CLEAN_CIRCLE_FN 10 + // Middle point of circle + #define NOZZLE_CLEAN_CIRCLE_MIDDLE NOZZLE_CLEAN_START_POINT + + // Moves the nozzle to the initial position + #define NOZZLE_CLEAN_GOBACK +#endif + +/** + * Print Job Timer + * + * Automatically start and stop the print job timer on M104/M109/M190. + * + * M104 (hotend, no wait) - high temp = none, low temp = stop timer + * M109 (hotend, wait) - high temp = start timer, low temp = stop timer + * M190 (bed, wait) - high temp = start timer, low temp = none + * + * The timer can also be controlled with the following commands: + * + * M75 - Start the print job timer + * M76 - Pause the print job timer + * M77 - Stop the print job timer + */ +#define PRINTJOB_TIMER_AUTOSTART + +/** + * Print Counter + * + * Track statistical data such as: + * + * - Total print jobs + * - Total successful print jobs + * - Total failed print jobs + * - Total time printing + * + * View the current statistics with M78. + */ +//#define PRINTCOUNTER + +//============================================================================= +//============================= LCD and SD support ============================ +//============================================================================= + +// @section lcd + +/** + * LCD LANGUAGE + * + * Select the language to display on the LCD. These languages are available: + * + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, + * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * tr, uk, zh_CN, zh_TW, test + * + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + */ +//#define LCD_LANGUAGE en + +/** + * LCD Character Set + * + * Note: This option is NOT applicable to Graphical Displays. + * + * All character-based LCDs provide ASCII plus one of these + * language extensions: + * + * - JAPANESE ... the most common + * - WESTERN ... with more accented characters + * - CYRILLIC ... for the Russian language + * + * To determine the language extension installed on your controller: + * + * - Compile and upload with LCD_LANGUAGE set to 'test' + * - 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 + * + * :['JAPANESE', 'WESTERN', 'CYRILLIC'] + */ +#define DISPLAY_CHARSET_HD44780 JAPANESE + +/** + * LCD TYPE + * + * Enable ULTRA_LCD for a 16x2, 16x4, 20x2, or 20x4 character-based LCD. + * Enable DOGLCD for a 128x64 (ST7565R) Full Graphical Display. + * (These options will be enabled automatically for most displays.) + * + * IMPORTANT: The U8glib library is required for Full Graphic Display! + * https://github.com/olikraus/U8glib_Arduino + */ +//#define ULTRA_LCD // Character based +//#define DOGLCD // Full graphics display + +/** + * SD CARD + * + * 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 + +/** + * SD CARD: SPI SPEED + * + * Enable one of the following items for a slower SPI transfer speed. + * This may be required to resolve "volume init" errors. + */ +//#define SPI_SPEED SPI_HALF_SPEED +//#define SPI_SPEED SPI_QUARTER_SPEED +//#define SPI_SPEED SPI_EIGHTH_SPEED + +/** + * SD CARD: ENABLE CRC + * + * Use CRC checks and retries on the SD communication. + */ +//#define SD_CHECK_AND_RETRY + +// +// ENCODER SETTINGS +// +// This option overrides the default number of encoder pulses needed to +// produce one step. Should be increased for high-resolution encoders. +// +//#define ENCODER_PULSES_PER_STEP 1 + +// +// Use this option to override the number of step signals required to +// move between next/prev menu items. +// +//#define ENCODER_STEPS_PER_MENU_ITEM 5 + +/** + * Encoder Direction Options + * + * Test your encoder's behavior first with both options disabled. + * + * Reversed Value Edit and Menu Nav? Enable REVERSE_ENCODER_DIRECTION. + * Reversed Menu Navigation only? Enable REVERSE_MENU_DIRECTION. + * Reversed Value Editing only? Enable BOTH options. + */ + +// +// This option reverses the encoder direction everywhere. +// +// Set this option if CLOCKWISE causes values to DECREASE +// +//#define REVERSE_ENCODER_DIRECTION + +// +// This option reverses the encoder direction for navigating LCD menus. +// +// If CLOCKWISE normally moves DOWN this makes it go UP. +// If CLOCKWISE normally moves UP this makes it go DOWN. +// +//#define REVERSE_MENU_DIRECTION + +// +// Individual Axis Homing +// +// Add individual axis homing items (Home X, Home Y, and Home Z) to the LCD menu. +// +//#define INDIVIDUAL_AXIS_HOMING_MENU + +// +// SPEAKER/BUZZER +// +// If you have a speaker that can produce tones, enable it here. +// By default Marlin assumes you have a buzzer with a fixed frequency. +// +//#define SPEAKER + +// +// The duration and frequency for the UI feedback sound. +// Set these to 0 to disable audio feedback in the LCD menus. +// +// Note: Test audio output with the G-Code: +// M300 S P +// +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 +//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 + +// +// CONTROLLER TYPE: Standard +// +// Marlin supports a wide variety of controllers. +// Enable one of the following options to specify your controller. +// + +// +// ULTIMAKER Controller. +// +//#define ULTIMAKERCONTROLLER + +// +// ULTIPANEL as seen on Thingiverse. +// +//#define ULTIPANEL + +// +// PanelOne from T3P3 (via RAMPS 1.4 AUX2/AUX3) +// http://reprap.org/wiki/PanelOne +// +//#define PANEL_ONE + +// +// MaKr3d Makr-Panel with graphic controller and SD support. +// http://reprap.org/wiki/MaKr3d_MaKrPanel +// +//#define MAKRPANEL + +// +// ReprapWorld Graphical LCD +// https://reprapworld.com/?products_details&products_id/1218 +// +//#define REPRAPWORLD_GRAPHICAL_LCD + +// +// Activate one of these if you have a Panucatt Devices +// Viki 2.0 or mini Viki with Graphic LCD +// http://panucatt.com +// +//#define VIKI2 +//#define miniVIKI + +// +// Adafruit ST7565 Full Graphic Controller. +// https://github.com/eboston/Adafruit-ST7565-Full-Graphic-Controller/ +// +//#define ELB_FULL_GRAPHIC_CONTROLLER + +// +// RepRapDiscount Smart Controller. +// http://reprap.org/wiki/RepRapDiscount_Smart_Controller +// +// Note: Usually sold with a white PCB. +// +//#define REPRAP_DISCOUNT_SMART_CONTROLLER + +// +// GADGETS3D G3D LCD/SD Controller +// http://reprap.org/wiki/RAMPS_1.3/1.4_GADGETS3D_Shield_with_Panel +// +// Note: Usually sold with a blue PCB. +// +//#define G3D_PANEL + +// +// RepRapDiscount FULL GRAPHIC Smart Controller +// http://reprap.org/wiki/RepRapDiscount_Full_Graphic_Smart_Controller +// +//#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER + +// +// MakerLab Mini Panel with graphic +// controller and SD support - http://reprap.org/wiki/Mini_panel +// +//#define MINIPANEL + +// +// RepRapWorld REPRAPWORLD_KEYPAD v1.1 +// http://reprapworld.com/?products_details&products_id=202&cPath=1591_1626 +// +// REPRAPWORLD_KEYPAD_MOVE_STEP sets how much should the robot move when a key +// is pressed, a value of 10.0 means 10mm per click. +// +//#define REPRAPWORLD_KEYPAD +//#define REPRAPWORLD_KEYPAD_MOVE_STEP 1.0 + +// +// RigidBot Panel V1.0 +// http://www.inventapart.com/ +// +//#define RIGIDBOT_PANEL + +// +// BQ LCD Smart Controller shipped by +// default with the BQ Hephestos 2 and Witbox 2. +// +//#define BQ_LCD_SMART_CONTROLLER + +// +// Cartesio UI +// http://mauk.cc/webshop/cartesio-shop/electronics/user-interface +// +//#define CARTESIO_UI + +// +// ANET_10 Controller supported displays. +// +//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. + // This LCD is known to be susceptible to electrical interference + // which scrambles the display. Pressing any button clears it up. +//#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 + // A clone of the RepRapDiscount full graphics display but with + // different pins/wiring (see pins_ANET_10.h). + +// +// LCD for Melzi Card with Graphical LCD +// +//#define LCD_FOR_MELZI + +// +// CONTROLLER TYPE: I2C +// +// Note: These controllers require the installation of Arduino's LiquidCrystal_I2C +// library. For more info: https://github.com/kiyoshigawa/LiquidCrystal_I2C +// + +// +// Elefu RA Board Control Panel +// http://www.elefu.com/index.php?route=product/product&product_id=53 +// +//#define RA_CONTROL_PANEL + +// +// Sainsmart YW Robot (LCM1602) LCD Display +// +// Note: This controller requires F.Malpartida's LiquidCrystal_I2C library +// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home +// +//#define LCD_I2C_SAINSMART_YWROBOT + +// +// Generic LCM1602 LCD adapter +// +//#define LCM1602 + +// +// PANELOLU2 LCD with status LEDs, +// separate encoder and click inputs. +// +// Note: This controller requires Arduino's LiquidTWI2 library v1.2.3 or later. +// For more info: https://github.com/lincomatic/LiquidTWI2 +// +// Note: The PANELOLU2 encoder click input can either be directly connected to +// a pin (if BTN_ENC defined to != -1) or read through I2C (when BTN_ENC == -1). +// +//#define LCD_I2C_PANELOLU2 + +// +// Panucatt VIKI LCD with status LEDs, +// integrated click & L/R/U/D buttons, separate encoder inputs. +// +//#define LCD_I2C_VIKI + +// +// SSD1306 OLED full graphics generic display +// +//#define U8GLIB_SSD1306 + +// +// SAV OLEd LCD module support using either SSD1306 or SH1106 based LCD modules +// +//#define SAV_3DGLCD +#if ENABLED(SAV_3DGLCD) + //#define U8GLIB_SSD1306 + #define U8GLIB_SH1106 +#endif + +// +// CONTROLLER TYPE: Shift register panels +// +// 2 wire Non-latching LCD SR from https://goo.gl/aJJ4sH +// LCD configuration: http://reprap.org/wiki/SAV_3D_LCD +// +//#define SAV_3DLCD + +// +// TinyBoy2 128x64 OLED / Encoder Panel +// +//#define OLED_PANEL_TINYBOY2 + +// +// Makeboard 3D Printer Parts 3D Printer Mini Display 1602 Mini Controller +// https://www.aliexpress.com/item/Micromake-Makeboard-3D-Printer-Parts-3D-Printer-Mini-Display-1602-Mini-Controller-Compatible-with-Ramps-1/32765887917.html +// +//#define MAKEBOARD_MINI_2_LINE_DISPLAY_1602 + +// +// MKS MINI12864 with graphic controller and SD support +// http://reprap.org/wiki/MKS_MINI_12864 +// +//#define MKS_MINI_12864 + +// +// Factory display for Creality CR-10 +// https://www.aliexpress.com/item/Universal-LCD-12864-3D-Printer-Display-Screen-With-Encoder-For-CR-10-CR-7-Model/32833148327.html +// +// This is RAMPS-compatible using a single 10-pin connector. +// (For CR-10 owners who want to replace the Melzi Creality board but retain the display) +// +//#define CR10_STOCKDISPLAY + +// +// MKS OLED 1.3" 128 × 64 FULL GRAPHICS CONTROLLER +// http://reprap.org/wiki/MKS_12864OLED +// +// Tiny, but very sharp OLED display +// +//#define MKS_12864OLED + +//============================================================================= +//=============================== Extra Features ============================== +//============================================================================= + +// @section extras + +// Increase the FAN PWM frequency. Removes the PWM noise but increases heating in the FET/Arduino +//#define FAST_PWM_FAN + +// Use software PWM to drive the fan, as for the heaters. This uses a very low frequency +// which is not as annoying as with the hardware PWM. On the other hand, if this frequency +// is too low, you should also increment SOFT_PWM_SCALE. +//#define FAN_SOFT_PWM + +// Incrementing this by 1 will double the software PWM frequency, +// affecting heaters, and the fan if FAN_SOFT_PWM is enabled. +// However, control resolution will be halved for each increment; +// at zero value, there are 128 effective control positions. +#define SOFT_PWM_SCALE 0 + +// If SOFT_PWM_SCALE is set to a value higher than 0, dithering can +// be used to mitigate the associated resolution loss. If enabled, +// some of the PWM cycles are stretched so on average the desired +// duty cycle is attained. +//#define SOFT_PWM_DITHER + +// Temperature status LEDs that display the hotend and bed temperature. +// If all hotends, bed temperature, and target temperature are under 54C +// then the BLUE led is on. Otherwise the RED led is on. (1C hysteresis) +//#define TEMP_STAT_LEDS + +// M240 Triggers a camera by emulating a Canon RC-1 Remote +// Data from: http://www.doc-diy.net/photo/rc-1_hacked/ +//#define PHOTOGRAPH_PIN 23 + +// 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 + +// Support for BlinkM/CyzRgb +//#define BLINKM + +// Support for PCA9632 PWM LED driver +//#define PCA9632 + +/** + * RGB LED / LED Strip Control + * + * Enable support for an RGB LED connected to 5V digital pins, or + * an RGB Strip connected to MOSFETs controlled by digital pins. + * + * 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 overall brightness parameters is also available + * + * *** CAUTION *** + * LED Strips require a MOFSET 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! + * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino + * cannot handle such current, separate 5V power supply must be used + * *** CAUTION *** + * + * LED type. This options are mutualy exclusive. Uncomment only one. + * + */ +//#define RGB_LED +//#define RGBW_LED + +#if ENABLED(RGB_LED) || ENABLED(RGBW_LED) + #define RGB_LED_R_PIN 34 + #define RGB_LED_G_PIN 43 + #define RGB_LED_B_PIN 35 + #define RGB_LED_W_PIN -1 +#endif + +// 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 (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) + #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip + #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time + #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + //#define NEOPIXEL_STARTUP_TEST // Cycle through colors at startup +#endif + +/** + * Printer Event LEDs + * + * During printing, the LEDs will reflect the printer status: + * + * - Gradually change from blue to violet as the heated bed gets to target temp + * - Gradually change from violet to red as the hotend gets to temperature + * - Change to white to illuminate work surface + * - Change to green once print has finished + * - Turn off after the print has finished and the user has pushed a button + */ +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) + #define PRINTER_EVENT_LEDS +#endif + +/*********************************************************************\ +* R/C SERVO support +* Sponsored by TrinityLabs, Reworked by codexmas +**********************************************************************/ + +// Number of servos +// +// If you select a configuration below, this will receive a default value and does not need to be set manually +// set it manually if you have more servos than extruders and wish to manually control some +// leaving it undefined or defining as 0 will disable the servo subsystem +// If unsure, leave commented / disabled +// +//#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command + +// Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. +// 300ms is a good value but you can try less delay. +// If the servo can't reach the requested position, increase it. +#define SERVO_DELAY { 300 } + +// Servo deactivation +// +// With this option servos are powered only during movement, then turned off to prevent jitter. +//#define DEACTIVATE_SERVOS_AFTER_MOVE + +/** + * Filament Width Sensor + * + * Measures the filament width in real-time and adjusts + * flow rate to compensate for any irregularities. + * + * Also allows the measured filament diameter to set the + * extrusion rate, so the slicer only has to specify the + * volume. + * + * Only a single extruder is supported at this time. + * + * 34 RAMPS_14 : Analog input 5 on the AUX2 connector + * 81 PRINTRBOARD : Analog input 2 on the Exp1 connector (version B,C,D,E) + * 301 RAMBO : Analog input 3 + * + * Note: May require analog pins to be defined for other boards. + */ +//#define FILAMENT_WIDTH_SENSOR + +#define DEFAULT_NOMINAL_FILAMENT_DIA 3.00 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. + +#if ENABLED(FILAMENT_WIDTH_SENSOR) + #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) + #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber + + #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading + #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading + #define MAX_MEASUREMENT_DELAY 20 // (bytes) Buffer size for stored measurements (1 byte per cm). Must be larger than MEASUREMENT_DELAY_CM. + + #define DEFAULT_MEASURED_FILAMENT_DIA DEFAULT_NOMINAL_FILAMENT_DIA // Set measured to nominal initially + + // Display filament width on the LCD status line. Status messages will expire after 5 seconds. + //#define FILAMENT_LCD_DISPLAY +#endif + +#endif // CONFIGURATION_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/tvrrug/Round2/Configuration_adv.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/tvrrug/Round2/Configuration_adv.h new file mode 100644 index 00000000..6dc73d62 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/tvrrug/Round2/Configuration_adv.h @@ -0,0 +1,1424 @@ +/** + * 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 . + * + */ + +/** + * Configuration_adv.h + * + * Advanced settings. + * Only change these if you know exactly what you're doing. + * Some of these settings can damage your printer if improperly set! + * + * Basic settings can be found in Configuration.h + * + */ +#ifndef CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H_VERSION 010100 + +// @section temperature + +//=========================================================================== +//=============================Thermal Settings ============================ +//=========================================================================== + +#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 + #endif +#endif + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * The solution: Once the temperature reaches the target, start observing. + * If the temperature stays too far below the target (hysteresis) for too long (period), + * the firmware will halt the machine as a safety precaution. + * + * If you get false positives for "Thermal Runaway" increase THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD + */ +#if ENABLED(THERMAL_PROTECTION_HOTENDS) + #define THERMAL_PROTECTION_PERIOD 40 // Seconds + #define THERMAL_PROTECTION_HYSTERESIS 4 // Degrees Celsius + + /** + * Whenever an M104 or M109 increases the target temperature the firmware will wait for the + * WATCH_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get false positives for "Heating failed" increase WATCH_TEMP_PERIOD and/or decrease WATCH_TEMP_INCREASE + * WATCH_TEMP_INCREASE should not be below 2. + */ + #define WATCH_TEMP_PERIOD 20 // Seconds + #define WATCH_TEMP_INCREASE 2 // Degrees Celsius +#endif + +/** + * Thermal Protection parameters for the bed are just as above for hotends. + */ +#if ENABLED(THERMAL_PROTECTION_BED) + #define THERMAL_PROTECTION_BED_PERIOD 20 // Seconds + #define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius + + /** + * Whenever an M140 or M190 increases the target temperature the firmware will wait for the + * WATCH_BED_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_BED_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get too many "Heating failed" errors, increase WATCH_BED_TEMP_PERIOD and/or decrease + * WATCH_BED_TEMP_INCREASE. (WATCH_BED_TEMP_INCREASE should not be below 2.) + */ + #define WATCH_BED_TEMP_PERIOD 60 // Seconds + #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius +#endif + +#if ENABLED(PIDTEMP) + // this adds an experimental additional term to the heating power, proportional to the extrusion speed. + // if Kc is chosen well, the additional required power due to increased melting should be compensated. + //#define PID_EXTRUSION_SCALING + #if ENABLED(PID_EXTRUSION_SCALING) + #define DEFAULT_Kc (100) //heating power=Kc*(e_speed) + #define LPQ_MAX_LEN 50 + #endif +#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 + */ +#define AUTOTEMP +#if ENABLED(AUTOTEMP) + #define AUTOTEMP_OLDWEIGHT 0.98 +#endif + +// Show Temperature ADC value +// Enable for M105 to include ADC values read from temperature sensors. +//#define SHOW_TEMP_ADC_VALUES + +/** + * High Temperature Thermistor Support + * + * Thermistors able to support high temperature tend to have a hard time getting + * good readings at room and lower temperatures. This means HEATER_X_RAW_LO_TEMP + * will probably be caught when the heating element first turns on during the + * preheating process, which will trigger a min_temp_error as a safety measure + * and force stop everything. + * To circumvent this limitation, we allow for a preheat time (during which, + * min_temp_error won't be triggered) and add a min_temp buffer to handle + * aberrant readings. + * + * If you want to enable this feature for your hotend thermistor(s) + * uncomment and set values > 0 in the constants below + */ + +// The number of consecutive low temperature errors that can occur +// before a min_temp_error is triggered. (Shouldn't be more than 10.) +//#define MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED 0 + +// The number of milliseconds a hotend will preheat before starting to check +// the temperature. This value should NOT be set to the time it takes the +// hot end to reach the target temperature, but the time it takes to reach +// the minimum temperature your thermistor can read. The lower the better/safer. +// This shouldn't need to be more than 30 seconds (30000) +//#define MILLISECONDS_PREHEAT_TIME 0 + +// @section extruder + +// Extruder runout prevention. +// If the machine is idle and the temperature over MINTEMP +// then extrude some filament every couple of SECONDS. +//#define EXTRUDER_RUNOUT_PREVENT +#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_EXTRUDE 5 // mm +#endif + +// @section temperature + +//These defines help to calibrate the AD595 sensor in case you get wrong temperature measurements. +//The measured temperature is defined as "actualTemp = (measuredTemp * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET" +#define TEMP_SENSOR_AD595_OFFSET 0.0 +#define TEMP_SENSOR_AD595_GAIN 1.0 + +/** + * 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. + */ +#define USE_CONTROLLER_FAN +#if ENABLED(USE_CONTROLLER_FAN) + #define CONTROLLER_FAN_PIN 23 // 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 +#endif + +// When first starting the main fan, run it at full speed for the +// given number of milliseconds. This gets the fan spinning reliably +// before setting a PWM value. (Does not work with software PWM for fan on Sanguinololu) +//#define FAN_KICKSTART_TIME 100 + +// This defines the minimal speed for the main fan, run in PWM mode +// to enable uncomment and set minimal PWM speed for reliable running (1-255) +// if fan speed is [1 - (FAN_MIN_PWM-1)] it is set to FAN_MIN_PWM +//#define FAN_MIN_PWM 50 + +// @section extruder + +/** + * Extruder cooling fans + * + * Extruder auto fans automatically turn on when their extruders' + * temperatures go above EXTRUDER_AUTO_FAN_TEMPERATURE. + * + * Your board's pins file specifies the recommended pins. Override those here + * or set to -1 to disable completely. + * + * Multiple extruders can be assigned to the same pin in which case + * the fan will turn on when any selected extruder is above the threshold. + */ +#define E0_AUTO_FAN_PIN -1 +#define E1_AUTO_FAN_PIN -1 +#define E2_AUTO_FAN_PIN -1 +#define E3_AUTO_FAN_PIN -1 +#define E4_AUTO_FAN_PIN -1 +#define EXTRUDER_AUTO_FAN_TEMPERATURE 50 +#define EXTRUDER_AUTO_FAN_SPEED 255 // == full speed + +/** + * Part-Cooling Fan Multiplexer + * + * This feature allows you to digitally multiplex the fan output. + * The multiplexer is automatically switched at tool-change. + * Set FANMUX[012]_PINs below for up to 2, 4, or 8 multiplexed fans. + */ +#define FANMUX0_PIN -1 +#define FANMUX1_PIN -1 +#define FANMUX2_PIN -1 + +/** + * M355 Case Light on-off / brightness + */ +//#define CASE_LIGHT_ENABLE +#if ENABLED(CASE_LIGHT_ENABLE) + //#define CASE_LIGHT_PIN 4 // Override the default pin if needed + #define INVERT_CASE_LIGHT false // Set true if Case Light is ON when pin is LOW + #define CASE_LIGHT_DEFAULT_ON true // Set default power-up state on + #define CASE_LIGHT_DEFAULT_BRIGHTNESS 105 // Set default power-up brightness (0-255, requires PWM pin) + //#define MENU_ITEM_CASE_LIGHT // Add a Case Light option to the LCD main menu +#endif + +//=========================================================================== +//============================ Mechanical Settings ========================== +//=========================================================================== + +// @section homing + +// If you want endstops to stay on (by default) even when not homing +// enable this option. Override at any time with M120, M121. +//#define ENDSTOPS_ALWAYS_ON_DEFAULT + +// @section extras + +//#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. + +// Dual X Steppers +// Uncomment this option to drive two X axis motors. +// The next unused E driver will be assigned to the second X stepper. +//#define X_DUAL_STEPPER_DRIVERS +#if ENABLED(X_DUAL_STEPPER_DRIVERS) + // Set true if the two X motors need to rotate in opposite directions + #define INVERT_X2_VS_X_DIR true +#endif + +// Dual Y Steppers +// Uncomment this option to drive two Y axis motors. +// The next unused E driver will be assigned to the second Y stepper. +//#define Y_DUAL_STEPPER_DRIVERS +#if ENABLED(Y_DUAL_STEPPER_DRIVERS) + // Set true if the two Y motors need to rotate in opposite directions + #define INVERT_Y2_VS_Y_DIR true +#endif + +// A single Z stepper driver is usually used to drive 2 stepper motors. +// Uncomment this option to use a separate stepper driver for each Z axis motor. +// The next unused E driver will be assigned to the second Z stepper. +//#define Z_DUAL_STEPPER_DRIVERS + +#if ENABLED(Z_DUAL_STEPPER_DRIVERS) + + // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper. + // That way the machine is capable to align the bed during home, since both Z steppers are homed. + // There is also an implementation of M666 (software endstops adjustment) to this feature. + // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed. + // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2. + // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive. + // Play a little bit with small adjustments (0.5mm) and check the behaviour. + // The M119 (endstops report) will start reporting the Z2 Endstop as well. + + //#define Z_DUAL_ENDSTOPS + + #if ENABLED(Z_DUAL_ENDSTOPS) + #define Z2_USE_ENDSTOP _XMAX_ + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 // Use M666 to determine/test this value + #endif + +#endif // Z_DUAL_STEPPER_DRIVERS + +// Enable this for dual x-carriage printers. +// A dual x-carriage design has the advantage that the inactive extruder can be parked which +// prevents hot-end ooze contaminating the print. It also reduces the weight of each x-carriage +// allowing faster printing speeds. Connect your X2 stepper to the first unused E plug. +//#define DUAL_X_CARRIAGE +#if ENABLED(DUAL_X_CARRIAGE) + // Configuration for second X-carriage + // Note: the first x-carriage is defined as the x-carriage which homes to the minimum endstop; + // the second x-carriage always homes to the maximum endstop. + #define X2_MIN_POS 80 // set minimum to ensure second x-carriage doesn't hit the parked first X-carriage + #define X2_MAX_POS 353 // set maximum to the distance between toolheads when both heads are homed + #define X2_HOME_DIR 1 // the second X-carriage always homes to the maximum endstop position + #define X2_HOME_POS X2_MAX_POS // default home position is the maximum carriage position + // However: In this mode the HOTEND_OFFSET_X value for the second extruder provides a software + // override for X2_HOME_POS. This also allow recalibration of the distance between the two endstops + // without modifying the firmware (through the "M218 T1 X???" command). + // Remember: you should set the second extruder x-offset to 0 in your slicer. + + // There are a few selectable movement modes for dual x-carriages using M605 S + // Mode 0 (DXC_FULL_CONTROL_MODE): Full control. The slicer has full control over both x-carriages and can achieve optimal travel results + // as long as it supports dual x-carriages. (M605 S0) + // Mode 1 (DXC_AUTO_PARK_MODE) : Auto-park mode. The firmware will automatically park and unpark the x-carriages on tool changes so + // that additional slicer support is not required. (M605 S1) + // Mode 2 (DXC_DUPLICATION_MODE) : Duplication mode. The firmware will transparently make the second x-carriage and extruder copy all + // actions of the first x-carriage. This allows the printer to print 2 arbitrary items at + // once. (2nd extruder x offset and temp offset are set using: M605 S2 [Xnnn] [Rmmm]) + + // This is the default power-up mode which can be later using M605. + #define DEFAULT_DUAL_X_CARRIAGE_MODE DXC_FULL_CONTROL_MODE + + // Default settings in "Auto-park Mode" + #define TOOLCHANGE_PARK_ZLIFT 0.2 // the distance to raise Z axis when parking an extruder + #define TOOLCHANGE_UNPARK_ZLIFT 1 // the distance to raise Z axis when unparking an extruder + + // Default x offset in duplication mode (typically set to half print bed width) + #define DEFAULT_DUPLICATION_X_OFFSET 100 + +#endif // DUAL_X_CARRIAGE + +// 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. +//#define EXT_SOLENOID + +// @section homing + +//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +#define X_HOME_BUMP_MM 5 +#define Y_HOME_BUMP_MM 5 +#define Z_HOME_BUMP_MM 1 +#define HOMING_BUMP_DIVISOR {2, 2, 4} // Re-Bump Speed Divisor (Divides the Homing Feedrate) +//#define QUICK_HOME //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially. + +// When G28 is called, this option will make Y home before X +//#define HOME_Y_BEFORE_X + +// @section machine + +#define AXIS_RELATIVE_MODES {false, false, false, false} + +// Allow duplication mode with a basic dual-nozzle extruder +//#define DUAL_NOZZLE_DUPLICATION_MODE + +// By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step. +#define INVERT_X_STEP_PIN false +#define INVERT_Y_STEP_PIN false +#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. +#define DEFAULT_STEPPER_DEACTIVE_TIME 60 +#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_E true + +#define DEFAULT_MINIMUMFEEDRATE 0.0 // minimum feedrate +#define DEFAULT_MINTRAVELFEEDRATE 0.0 + +//#define HOME_AFTER_DEACTIVATE // Require rehoming after steppers are deactivated + +// @section lcd + +#if ENABLED(ULTIPANEL) + #define MANUAL_FEEDRATE {50*60, 50*60, 4*60, 60} // Feedrates for manual moves along X, Y, Z, E from panel + #define ULTIPANEL_FEEDMULTIPLY // Comment to disable setting feedrate multiplier via encoder +#endif + +// @section extras + +// minimum time in microseconds that a movement needs to take if the buffer is emptied. +#define DEFAULT_MINSEGMENTTIME 20000 + +// If defined the movements slow down when the look ahead buffer is only half full +#define SLOWDOWN + +// Frequency limit +// See nophead's blog for more info +// Not working O +//#define XY_FREQUENCY_LIMIT 15 + +// 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 +// if unwanted behavior is observed on a user's machine when running at very slow speeds. +#define MINIMUM_PLANNER_SPEED 0.05 // (mm/sec) + +// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU. +#define MICROSTEP_MODES {16,16,16,16,16} // [1,2,4,8,16] + +/** + * @section stepper motor current + * + * Some boards have a means of setting the stepper motor current via firmware. + * + * The power on motor currents are set by: + * PWM_MOTOR_CURRENT - used by MINIRAMBO & ULTIMAIN_2 + * known compatible chips: A4982 + * DIGIPOT_MOTOR_CURRENT - used by BQ_ZUM_MEGA_3D, RAMBO & SCOOVO_X9H + * known compatible chips: AD5206 + * DAC_MOTOR_CURRENT_DEFAULT - used by PRINTRBOARD_REVF & RIGIDBOARD_V2 + * known compatible chips: MCP4728 + * DIGIPOT_I2C_MOTOR_CURRENTS - used by 5DPRINT, AZTEEG_X3_PRO, MIGHTYBOARD_REVE + * known compatible chips: MCP4451, MCP4018 + * + * Motor currents can also be set by M907 - M910 and by the LCD. + * M907 - applies to all. + * M908 - BQ_ZUM_MEGA_3D, RAMBO, PRINTRBOARD_REVF, RIGIDBOARD_V2 & SCOOVO_X9H + * M909, M910 & LCD - only PRINTRBOARD_REVF & RIGIDBOARD_V2 + */ +//#define PWM_MOTOR_CURRENT { 1300, 1300, 1250 } // Values in milliamps +//#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 + +// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +//#define DIGIPOT_I2C +//#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster +#define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 +// Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS +#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=========================== +//=========================================================================== + +#define ENCODER_RATE_MULTIPLIER // If defined, certain menu edit operations automatically multiply the steps when the encoder is moved quickly +#define ENCODER_10X_STEPS_PER_SEC 75 // If the encoder steps per sec exceeds this value, multiply steps moved x10 to quickly advance the value +#define ENCODER_100X_STEPS_PER_SEC 160 // If the encoder steps per sec exceeds this value, multiply steps moved x100 to really quickly advance the value + +//#define CHDK 4 //Pin for triggering CHDK to take a picture see how to use it here http://captain-slow.dk/2014/03/09/3d-printing-timelapses/ +#define CHDK_DELAY 50 //How long in ms the pin should stay HIGH before going LOW again + +// @section lcd + +// Include a page of printer information in the LCD Main Menu +//#define LCD_INFO_MENU + +// Scroll a longer status message into view +//#define STATUS_MESSAGE_SCROLLING + +// On the Info Screen, display XY with one decimal place when possible +//#define LCD_DECIMAL_SMALL_XY + +// The timeout (in ms) to return to the status screen from sub-menus +//#define LCD_TIMEOUT_TO_STATUS 15000 + +#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 + + #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? + #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. + + #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. + // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. + // using: + //#define MENU_ADDAUTOSTART + + /** + * Sort SD file listings in alphabetical order. + * + * With this option enabled, items on SD cards will be sorted + * by name for easier navigation. + * + * By default... + * + * - Use the slowest -but safest- method for sorting. + * - Folders are sorted to the top. + * - The sort key is statically allocated. + * - No added G-code (M34) support. + * - 40 item sorting limit. (Items after the first 40 are unsorted.) + * + * SD sorting uses static allocation (as set by SDSORT_LIMIT), allowing the + * compiler to calculate the worst-case usage and throw an error if the SRAM + * limit is exceeded. + * + * - SDSORT_USES_RAM provides faster sorting via a static directory buffer. + * - SDSORT_USES_STACK does the same, but uses a local stack-based buffer. + * - SDSORT_CACHE_NAMES will retain the sorted file listing in RAM. (Expensive!) + * - SDSORT_DYNAMIC_RAM only uses RAM when the SD menu is visible. (Use with caution!) + */ + //#define SDCARD_SORT_ALPHA + + // SD Card Sorting options + #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_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. + #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #endif + + // Show a progress bar on HD44780 LCDs for SD printing + //#define LCD_PROGRESS_BAR + + #if ENABLED(LCD_PROGRESS_BAR) + // Amount of time (ms) to show the bar + #define PROGRESS_BAR_BAR_TIME 2000 + // Amount of time (ms) to show the status message + #define PROGRESS_BAR_MSG_TIME 3000 + // Amount of time (ms) to retain the status message (0=forever) + #define PROGRESS_MSG_EXPIRE 0 + // Enable this to show messages for MSG_TIME then hide them + //#define PROGRESS_MSG_ONCE + // Add a menu item to test the progress bar: + //#define LCD_PROGRESS_BAR_TEST + #endif + + // This allows hosts to request long names for files and folders with M33 + //#define LONG_FILENAME_HOST_SUPPORT + + // This option allows you to abort SD printing when any endstop is triggered. + // This feature must be enabled with "M540 S1" or from the LCD menu. + // To have any effect, endstops must be enabled during SD printing. + //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + +#endif // SDSUPPORT + +/** + * Additional options for Graphical Displays + * + * Use the optimizations here to improve printing performance, + * which can be adversely affected by graphical display drawing, + * especially when doing several short moves, and when printing + * on DELTA and SCARA machines. + * + * Some of these options may result in the display lagging behind + * controller events, as there is a trade-off between reliable + * printing performance versus fast display updates. + */ +#if ENABLED(DOGLCD) + // Enable to save many cycles by drawing a hollow frame on the Info Screen + #define XYZ_HOLLOW_FRAME + + // Enable to save many cycles by drawing a hollow frame on Menu Screens + #define MENU_HOLLOW_FRAME + + // A bigger font is available for edit items. Costs 3120 bytes of PROGMEM. + // 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. + // 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 +#endif // DOGLCD + +// @section safety + +// The hardware watchdog should reset the microcontroller disabling all outputs, +// in case the firmware gets stuck and doesn't do temperature regulation. +#define USE_WATCHDOG + +#if ENABLED(USE_WATCHDOG) + // If you have a watchdog reboot in an ArduinoMega2560 then the device will hang forever, as a watchdog reset will leave the watchdog on. + // The "WATCHDOG_RESET_MANUAL" goes around this by not using the hardware reset. + // However, THIS FEATURE IS UNSAFE!, as it will only work if interrupts are disabled. And the code could hang in an interrupt routine with interrupts disabled. + //#define WATCHDOG_RESET_MANUAL +#endif + +// @section lcd + +/** + * Babystepping enables movement of the axes by tiny increments without changing + * the current position values. This feature is used primarily to adjust the Z + * axis in the first layer of a print in real-time. + * + * Warning: Does not respect endstops! + */ +//#define BABYSTEPPING +#if ENABLED(BABYSTEPPING) + //#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 100 // Babysteps are very small. Increase for faster motion. + //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping + //#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen 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_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor + //#define BABYSTEP_ZPROBE_GFX_REVERSE // Reverses the direction of the CW/CCW indicators +#endif + +// @section extruder + +/** + * Implementation of linear pressure control + * + * Assumption: advance = k * (delta velocity) + * K=0 means advance disabled. + * See Marlin documentation for calibration instructions. + */ +//#define LIN_ADVANCE + +#if ENABLED(LIN_ADVANCE) + #define LIN_ADVANCE_K 75 + + /** + * Some Slicers produce Gcode with randomly jumping extrusion widths occasionally. + * For example within a 0.4mm perimeter it may produce a single segment of 0.05mm width. + * While this is harmless for normal printing (the fluid nature of the filament will + * close this very, very tiny gap), it throws off the LIN_ADVANCE pressure adaption. + * + * For this case LIN_ADVANCE_E_D_RATIO can be used to set the extrusion:distance ratio + * to a fixed value. Note that using a fixed ratio will lead to wrong nozzle pressures + * if the slicer is using variable widths or layer heights within one print! + * + * This option sets the default E:D ratio at startup. Use `M900` to override this value. + * + * Example: `M900 W0.4 H0.2 D1.75`, where: + * - W is the extrusion width in mm + * - H is the layer height in mm + * - D is the filament diameter in mm + * + * Example: `M900 R0.0458` to set the ratio directly. + * + * Set to 0 to auto-detect the ratio based on given Gcode G1 print moves. + * + * Slic3r (including Průša Control) produces Gcode compatible with the automatic mode. + * Cura (as of this writing) may produce Gcode incompatible with the automatic mode. + */ + #define LIN_ADVANCE_E_D_RATIO 0 // The calculated ratio (or 0) according to the formula W * H / ((D / 2) ^ 2 * PI) + // Example: 0.4 * 0.2 / ((1.75 / 2) ^ 2 * PI) = 0.033260135 +#endif + +// @section leveling + +// Default mesh area is an area with an inset margin on the print area. +// Below are the macros that are used to define the borders for the mesh area, +// made available here for specialized needs, ie dual extruder setup. +#if ENABLED(MESH_BED_LEVELING) + #define MESH_MIN_X MESH_INSET + #define MESH_MAX_X (X_BED_SIZE - (MESH_INSET)) + #define MESH_MIN_Y MESH_INSET + #define MESH_MAX_Y (Y_BED_SIZE - (MESH_INSET)) +#elif ENABLED(AUTO_BED_LEVELING_UBL) + #define UBL_MESH_MIN_X UBL_MESH_INSET + #define UBL_MESH_MAX_X (X_BED_SIZE - (UBL_MESH_INSET)) + #define UBL_MESH_MIN_Y UBL_MESH_INSET + #define UBL_MESH_MAX_Y (Y_BED_SIZE - (UBL_MESH_INSET)) + + // If this is defined, the currently active mesh will be saved in the + // current slot on M500. + #define UBL_SAVE_ACTIVE_ON_M500 +#endif + +// @section extras + +// +// G2/G3 Arc Support +// +#define ARC_SUPPORT // Disable this feature to save ~3226 bytes +#if ENABLED(ARC_SUPPORT) + #define MM_PER_ARC_SEGMENT 1 // Length of each arc segment + #define N_ARC_CORRECTION 25 // Number of intertpolated 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 +#endif + +// Support for G5 with XYZE destination and IJPQ offsets. Requires ~2666 bytes. +//#define BEZIER_CURVE_SUPPORT + +// G38.2 and G38.3 Probe Target +// Enable PROBE_DOUBLE_TOUCH if you want G38 to double touch +//#define G38_PROBE_TARGET +#if ENABLED(G38_PROBE_TARGET) + #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) +#endif + +// Moves (or segments) with fewer steps than this will be joined with the next move +#define MIN_STEPS_PER_SEGMENT 6 + +// The minimum pulse width (in µs) for stepping a stepper. +// Set this if you find stepping unreliable, or if using a very fast CPU. +#define MINIMUM_STEPPER_PULSE 0 // (µs) The smallest stepper pulse allowed + +// @section temperature + +// Control heater 0 and heater 1 in parallel. +//#define HEATERS_PARALLEL + +//=========================================================================== +//================================= Buffers ================================= +//=========================================================================== + +// @section hidden + +// 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, i.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 +#else + #define BLOCK_BUFFER_SIZE 16 // maximize block buffer +#endif + +// @section serial + +// The ASCII buffer for serial input +#define MAX_CMD_SIZE 96 +#define BUFSIZE 4 + +// Transmission to Host Buffer Size +// To save 386 bytes of PROGMEM (and TX_BUFFER_SIZE+3 bytes of RAM) set to 0. +// To buffer a simple "ok" you need 4 bytes. +// For ADVANCED_OK (M105) you need 32 bytes. +// For debug-echo: 128 bytes for the optimal speed. +// Other output doesn't need to be that speedy. +// :[0, 2, 4, 8, 16, 32, 64, 128, 256] +#define TX_BUFFER_SIZE 0 + +// Host Receive Buffer Size +// Without XON/XOFF flow control (see SERIAL_XON_XOFF below) 32 bytes should be enough. +// To use flow control, set this buffer size to at least 1024 bytes. +// :[0, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048] +//#define RX_BUFFER_SIZE 1024 + +#if RX_BUFFER_SIZE >= 1024 + // Enable to have the controller send XON/XOFF control characters to + // the host to signal the RX buffer is becoming full. + //#define SERIAL_XON_XOFF +#endif + +#if ENABLED(SDSUPPORT) + // Enable this option to collect and display the maximum + // RX queue usage after transferring a file to SD. + //#define SERIAL_STATS_MAX_RX_QUEUED + + // Enable this option to collect and display the number + // of dropped bytes after a file transfer to SD. + //#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! +//#define EMERGENCY_PARSER + +// Bad Serial-connections can miss a received command by sending an 'ok' +// Therefore some clients abort after 30 seconds in a timeout. +// Some other clients start sending commands while receiving a 'wait'. +// This "wait" is only sent when the buffer is empty. 1 second is a good value here. +//#define NO_TIMEOUTS 1000 // Milliseconds + +// Some clients will have this feature soon. This could make the NO_TIMEOUTS unnecessary. +//#define ADVANCED_OK + +// @section extras + +/** + * Firmware-based and LCD-controlled retract + * + * Add G10 / G11 commands for automatic firmware-based retract / recover. + * Use M207 and M208 to define parameters for retract / recover. + * + * Use M209 to enable or disable auto-retract. + * With auto-retract enabled, all G1 E moves within the set range + * will be converted to firmware-based retract/recover moves. + * + * Be sure to turn off auto-retract during filament change. + * + * Note that M207 / M208 / M209 settings are saved to EEPROM. + * + */ +//#define FWRETRACT // ONLY PARTIALLY TESTED +#if ENABLED(FWRETRACT) + #define MIN_AUTORETRACT 0.1 // When auto-retract is on, convert E moves of this length and over + #define MAX_AUTORETRACT 10.0 // Upper limit for auto-retract conversion + #define RETRACT_LENGTH 3 // Default retract length (positive mm) + #define RETRACT_LENGTH_SWAP 13 // Default swap retract length (positive mm), for extruder change + #define RETRACT_FEEDRATE 45 // Default feedrate for retracting (mm/s) + #define RETRACT_ZLIFT 0 // Default retract Z-lift + #define RETRACT_RECOVER_LENGTH 0 // Default additional recover length (mm, added to retract length when recovering) + #define RETRACT_RECOVER_LENGTH_SWAP 0 // Default additional swap recover length (mm, added to retract length when recovering from extruder change) + #define RETRACT_RECOVER_FEEDRATE 8 // Default feedrate for recovering from retraction (mm/s) + #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) +#endif + +/** + * Advanced Pause + * Experimental feature for filament change support and for parking the nozzle when paused. + * Adds the GCode M600 for initiating filament change. + * If PARK_HEAD_ON_PAUSE enabled, adds the GCode M125 to pause printing and park the nozzle. + * + * Requires an LCD display. + * This feature is required for the default FILAMENT_RUNOUT_SCRIPT. + */ +//#define ADVANCED_PAUSE_FEATURE +#if ENABLED(ADVANCED_PAUSE_FEATURE) + #define PAUSE_PARK_X_POS 3 // X position of hotend + #define PAUSE_PARK_Y_POS 3 // Y position of hotend + #define PAUSE_PARK_Z_ADD 10 // Z addition of hotend (lift) + #define PAUSE_PARK_XY_FEEDRATE 100 // X and Y axes feedrate in mm/s (also used for delta printers Z axis) + #define PAUSE_PARK_Z_FEEDRATE 5 // Z axis feedrate in mm/s (not used for delta printers) + #define PAUSE_PARK_RETRACT_FEEDRATE 60 // Initial retract feedrate in mm/s + #define PAUSE_PARK_RETRACT_LENGTH 2 // Initial retract in mm + // It is a short retract used immediately after print interrupt before move to filament exchange position + #define FILAMENT_CHANGE_UNLOAD_FEEDRATE 10 // Unload filament feedrate in mm/s - filament unloading can be fast + #define FILAMENT_CHANGE_UNLOAD_LENGTH 100 // Unload filament length from hotend in mm + // Longer length for bowden printers to unload filament from whole bowden tube, + // shorter length for printers without bowden to unload filament from extruder only, + // 0 to disable unloading for manual unloading + #define FILAMENT_CHANGE_LOAD_FEEDRATE 6 // Load filament feedrate in mm/s - filament loading into the bowden tube can be fast + #define FILAMENT_CHANGE_LOAD_LENGTH 0 // Load filament length over hotend in mm + // Longer length for bowden printers to fast load filament into whole bowden tube over the hotend, + // Short or zero length for printers without bowden where loading is not used + #define ADVANCED_PAUSE_EXTRUDE_FEEDRATE 3 // Extrude filament feedrate in mm/s - must be slower than load feedrate + #define ADVANCED_PAUSE_EXTRUDE_LENGTH 50 // Extrude filament length in mm after filament is loaded over the hotend, + // 0 to disable for manual extrusion + // Filament can be extruded repeatedly from the filament exchange menu to fill the hotend, + // or until outcoming filament color is not clear for filament color change + #define PAUSE_PARK_NOZZLE_TIMEOUT 45 // Turn off nozzle if user doesn't change filament within this time limit in seconds + #define FILAMENT_CHANGE_NUMBER_OF_ALERT_BEEPS 5 // Number of alert beeps before printer goes quiet + #define PAUSE_PARK_NO_STEPPER_TIMEOUT // Enable to have stepper motors hold position during filament change + // even if it takes longer than DEFAULT_STEPPER_DEACTIVE_TIME. + //#define PARK_HEAD_ON_PAUSE // Go to filament change position on pause, return to print position on resume + //#define HOME_BEFORE_FILAMENT_CHANGE // Ensure homing has been completed prior to parking for filament change +#endif + +// @section tmc + +/** + * Enable this section if you have TMC26X motor drivers. + * You will need to import the TMC26XStepper library into the Arduino IDE for this + * (https://github.com/trinamic/TMC26XStepper.git) + */ +//#define HAVE_TMCDRIVER + +#if ENABLED(HAVE_TMCDRIVER) + + //#define X_IS_TMC + //#define X2_IS_TMC + //#define Y_IS_TMC + //#define Y2_IS_TMC + //#define Z_IS_TMC + //#define Z2_IS_TMC + //#define E0_IS_TMC + //#define E1_IS_TMC + //#define E2_IS_TMC + //#define E3_IS_TMC + //#define E4_IS_TMC + + #define X_MAX_CURRENT 1000 // in mA + #define X_SENSE_RESISTOR 91 // in mOhms + #define X_MICROSTEPS 16 // number of microsteps + + #define X2_MAX_CURRENT 1000 + #define X2_SENSE_RESISTOR 91 + #define X2_MICROSTEPS 16 + + #define Y_MAX_CURRENT 1000 + #define Y_SENSE_RESISTOR 91 + #define Y_MICROSTEPS 16 + + #define Y2_MAX_CURRENT 1000 + #define Y2_SENSE_RESISTOR 91 + #define Y2_MICROSTEPS 16 + + #define Z_MAX_CURRENT 1000 + #define Z_SENSE_RESISTOR 91 + #define Z_MICROSTEPS 16 + + #define Z2_MAX_CURRENT 1000 + #define Z2_SENSE_RESISTOR 91 + #define Z2_MICROSTEPS 16 + + #define E0_MAX_CURRENT 1000 + #define E0_SENSE_RESISTOR 91 + #define E0_MICROSTEPS 16 + + #define E1_MAX_CURRENT 1000 + #define E1_SENSE_RESISTOR 91 + #define E1_MICROSTEPS 16 + + #define E2_MAX_CURRENT 1000 + #define E2_SENSE_RESISTOR 91 + #define E2_MICROSTEPS 16 + + #define E3_MAX_CURRENT 1000 + #define E3_SENSE_RESISTOR 91 + #define E3_MICROSTEPS 16 + + #define E4_MAX_CURRENT 1000 + #define E4_SENSE_RESISTOR 91 + #define E4_MICROSTEPS 16 + +#endif + +// @section TMC2130 + +/** + * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. + * + * You'll also need the TMC2130Stepper Arduino library + * (https://github.com/teemuatlut/TMC2130Stepper). + * + * To use TMC2130 stepper drivers in SPI mode connect your SPI2130 pins to + * the hardware SPI interface on your board and define the required CS pins + * in your `pins_MYBOARD.h` file. (e.g., RAMPS 1.4 uses AUX3 pins `X_CS_PIN 53`, `Y_CS_PIN 49`, etc.). + */ +//#define HAVE_TMC2130 + +#if ENABLED(HAVE_TMC2130) + + // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY + //#define X_IS_TMC2130 + //#define X2_IS_TMC2130 + //#define Y_IS_TMC2130 + //#define Y2_IS_TMC2130 + //#define Z_IS_TMC2130 + //#define Z2_IS_TMC2130 + //#define E0_IS_TMC2130 + //#define E1_IS_TMC2130 + //#define E2_IS_TMC2130 + //#define E3_IS_TMC2130 + //#define E4_IS_TMC2130 + + /** + * Stepper driver settings + */ + + #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 + #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current + #define INTERPOLATE 1 // Interpolate X/Y/Z_MICROSTEPS to 256 + + #define X_CURRENT 1000 // rms current in mA. Multiply by 1.41 for peak current. + #define X_MICROSTEPS 16 // 0..256 + + #define Y_CURRENT 1000 + #define Y_MICROSTEPS 16 + + #define Z_CURRENT 1000 + #define Z_MICROSTEPS 16 + + //#define X2_CURRENT 1000 + //#define X2_MICROSTEPS 16 + + //#define Y2_CURRENT 1000 + //#define Y2_MICROSTEPS 16 + + //#define Z2_CURRENT 1000 + //#define Z2_MICROSTEPS 16 + + //#define E0_CURRENT 1000 + //#define E0_MICROSTEPS 16 + + //#define E1_CURRENT 1000 + //#define E1_MICROSTEPS 16 + + //#define E2_CURRENT 1000 + //#define E2_MICROSTEPS 16 + + //#define E3_CURRENT 1000 + //#define E3_MICROSTEPS 16 + + //#define E4_CURRENT 1000 + //#define E4_MICROSTEPS 16 + + /** + * Use Trinamic's ultra quiet stepping mode. + * When disabled, Marlin will use spreadCycle stepping mode. + */ + #define STEALTHCHOP + + /** + * Let Marlin automatically control stepper current. + * This is still an experimental feature. + * Increase current every 5s by CURRENT_STEP until stepper temperature prewarn gets triggered, + * then decrease current by CURRENT_STEP until temperature prewarn is cleared. + * Adjusting starts from X/Y/Z/E_CURRENT but will not increase over AUTO_ADJUST_MAX + * 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. + * M906 S1 - Start adjusting current + * M906 S0 - Stop adjusting current + * M911 - Report stepper driver overtemperature pre-warn condition. + * M912 - Clear stepper driver overtemperature pre-warn condition flag. + */ + //#define AUTOMATIC_CURRENT_CONTROL + + #if ENABLED(AUTOMATIC_CURRENT_CONTROL) + #define CURRENT_STEP 50 // [mA] + #define AUTO_ADJUST_MAX 1300 // [mA], 1300mA_rms = 1840mA_peak + #define REPORT_CURRENT_CHANGE + #endif + + /** + * The driver will switch to spreadCycle when stepper speed is over HYBRID_THRESHOLD. + * This mode allows for faster movements at the expense of higher noise levels. + * STEALTHCHOP needs to be enabled. + * M913 X/Y/Z/E to live tune the setting + */ + //#define HYBRID_THRESHOLD + + #define X_HYBRID_THRESHOLD 100 // [mm/s] + #define X2_HYBRID_THRESHOLD 100 + #define Y_HYBRID_THRESHOLD 100 + #define Y2_HYBRID_THRESHOLD 100 + #define Z_HYBRID_THRESHOLD 4 + #define Z2_HYBRID_THRESHOLD 4 + #define E0_HYBRID_THRESHOLD 30 + #define E1_HYBRID_THRESHOLD 30 + #define E2_HYBRID_THRESHOLD 30 + #define E3_HYBRID_THRESHOLD 30 + #define E4_HYBRID_THRESHOLD 30 + + /** + * Use stallGuard2 to sense an obstacle and trigger an endstop. + * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. + * If used along with STEALTHCHOP, the movement will be louder when homing. This is normal. + * + * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. + * Higher values make the system LESS sensitive. + * Lower value make the system MORE sensitive. + * Too low values can lead to false positives, while too high values will collide the axis without triggering. + * It is advised to set X/Y_HOME_BUMP_MM to 0. + * M914 X/Y to live tune the setting + */ + //#define SENSORLESS_HOMING + + #if ENABLED(SENSORLESS_HOMING) + #define X_HOMING_SENSITIVITY 19 + #define Y_HOMING_SENSITIVITY 19 + #endif + + /** + * You can set your own advanced settings by filling in predefined functions. + * A list of available functions can be found on the library github page + * https://github.com/teemuatlut/TMC2130Stepper + * + * Example: + * #define TMC2130_ADV() { \ + * stepperX.diag0_temp_prewarn(1); \ + * stepperX.interpolate(0); \ + * } + */ + #define TMC2130_ADV() { } + +#endif // HAVE_TMC2130 + +// @section L6470 + +/** + * Enable this section if you have L6470 motor drivers. + * You need to import the L6470 library into the Arduino IDE for this. + * (https://github.com/ameyer/Arduino-L6470) + */ + +//#define HAVE_L6470DRIVER +#if ENABLED(HAVE_L6470DRIVER) + + //#define X_IS_L6470 + //#define X2_IS_L6470 + //#define Y_IS_L6470 + //#define Y2_IS_L6470 + //#define Z_IS_L6470 + //#define Z2_IS_L6470 + //#define E0_IS_L6470 + //#define E1_IS_L6470 + //#define E2_IS_L6470 + //#define E3_IS_L6470 + //#define E4_IS_L6470 + + #define X_MICROSTEPS 16 // number of microsteps + #define X_K_VAL 50 // 0 - 255, Higher values, are higher power. Be careful not to go too high + #define X_OVERCURRENT 2000 // maxc current in mA. If the current goes over this value, the driver will switch off + #define X_STALLCURRENT 1500 // current in mA where the driver will detect a stall + + #define X2_MICROSTEPS 16 + #define X2_K_VAL 50 + #define X2_OVERCURRENT 2000 + #define X2_STALLCURRENT 1500 + + #define Y_MICROSTEPS 16 + #define Y_K_VAL 50 + #define Y_OVERCURRENT 2000 + #define Y_STALLCURRENT 1500 + + #define Y2_MICROSTEPS 16 + #define Y2_K_VAL 50 + #define Y2_OVERCURRENT 2000 + #define Y2_STALLCURRENT 1500 + + #define Z_MICROSTEPS 16 + #define Z_K_VAL 50 + #define Z_OVERCURRENT 2000 + #define Z_STALLCURRENT 1500 + + #define Z2_MICROSTEPS 16 + #define Z2_K_VAL 50 + #define Z2_OVERCURRENT 2000 + #define Z2_STALLCURRENT 1500 + + #define E0_MICROSTEPS 16 + #define E0_K_VAL 50 + #define E0_OVERCURRENT 2000 + #define E0_STALLCURRENT 1500 + + #define E1_MICROSTEPS 16 + #define E1_K_VAL 50 + #define E1_OVERCURRENT 2000 + #define E1_STALLCURRENT 1500 + + #define E2_MICROSTEPS 16 + #define E2_K_VAL 50 + #define E2_OVERCURRENT 2000 + #define E2_STALLCURRENT 1500 + + #define E3_MICROSTEPS 16 + #define E3_K_VAL 50 + #define E3_OVERCURRENT 2000 + #define E3_STALLCURRENT 1500 + + #define E4_MICROSTEPS 16 + #define E4_K_VAL 50 + #define E4_OVERCURRENT 2000 + #define E4_STALLCURRENT 1500 + +#endif + +/** + * TWI/I2C BUS + * + * This feature is an EXPERIMENTAL feature so it shall not be used on production + * machines. Enabling this will allow you to send and receive I2C data from slave + * devices on the bus. + * + * ; Example #1 + * ; This macro send the string "Marlin" to the slave device with address 0x63 (99) + * ; It uses multiple M260 commands with one B arg + * M260 A99 ; Target slave address + * M260 B77 ; M + * M260 B97 ; a + * M260 B114 ; r + * M260 B108 ; l + * M260 B105 ; i + * M260 B110 ; n + * M260 S1 ; Send the current buffer + * + * ; Example #2 + * ; Request 6 bytes from slave device with address 0x63 (99) + * M261 A99 B5 + * + * ; Example #3 + * ; Example serial output of a M261 request + * echo:i2c-reply: from:99 bytes:5 data:hello + */ + +// @section i2cbus + +//#define EXPERIMENTAL_I2CBUS +#define I2C_SLAVE_ADDRESS 0 // Set a value from 8 to 127 to act as a slave + +// @section extras + +/** + * Spindle & Laser control + * + * Add the M3, M4, and M5 commands to turn the spindle/laser on and off, and + * to set spindle speed, spindle direction, and laser power. + * + * SuperPid is a router/spindle speed controller used in the CNC milling community. + * Marlin can be used to turn the spindle on and off. It can also be used to set + * the spindle speed from 5,000 to 30,000 RPM. + * + * 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. + */ +//#define SPINDLE_LASER_ENABLE +#if ENABLED(SPINDLE_LASER_ENABLE) + + #define SPINDLE_LASER_ENABLE_INVERT false // set to "true" if the on/off function is reversed + #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 // delay in milliseconds to allow the spindle/laser to come up to speed/power + #define SPINDLE_LASER_POWERDOWN_DELAY 5000 // delay in milliseconds to allow the spindle to stop + #define SPINDLE_DIR_CHANGE true // set to true if your spindle controller supports changing spindle direction + #define SPINDLE_INVERT_DIR false + #define SPINDLE_STOP_ON_DIR_CHANGE true // set to true if Marlin should stop the spindle before changing rotation direction + + /** + * The M3 & M4 commands use the following equation to convert PWM duty cycle to speed/power + * + * SPEED/POWER = PWM duty cycle * SPEED_POWER_SLOPE + SPEED_POWER_INTERCEPT + * where PWM duty cycle varies from 0 to 255 + * + * set the following for your controller (ALL MUST BE SET) + */ + + #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_SLOPE 0.3922 + //#define SPEED_POWER_INTERCEPT 0 + //#define SPEED_POWER_MIN 10 + //#define SPEED_POWER_MAX 100 // 0-100% +#endif + +/** + * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins + */ +//#define PINS_DEBUGGING + +/** + * Auto-report temperatures with M155 S + */ +#define AUTO_REPORT_TEMPERATURES + +/** + * Include capabilities in M115 output + */ +#define EXTENDED_CAPABILITIES_REPORT + +/** + * Volumetric extrusion default state + * 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. + */ +//#define VOLUMETRIC_DEFAULT_ON + +/** + * Enable this option for a leaner build of Marlin that removes all + * workspace offsets, simplifying coordinate transformations, leveling, etc. + * + * - M206 and M428 are disabled. + * - G92 will revert to its behavior from Marlin 1.0. + */ +//#define NO_WORKSPACE_OFFSETS + +/** + * 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. + * + * For clients that use a fixed-width font (like OctoPrint), leave this set to 1.0. + * Otherwise, adjust according to your client and font. + */ +#define PROPORTIONAL_FONT_RATIO 1.0 + +/** + * Spend 28 bytes of SRAM to optimize the GCode parser + */ +#define FASTER_GCODE_PARSER + +/** + * User-defined menu items that execute custom GCode + */ +//#define CUSTOM_USER_MENUS +#if ENABLED(CUSTOM_USER_MENUS) + #define USER_SCRIPT_DONE "M117 User Script Done" + #define USER_SCRIPT_AUDIBLE_FEEDBACK + //#define USER_SCRIPT_RETURN // Return to status screen after a script + + #define USER_DESC_1 "Home & UBL Info" + #define USER_GCODE_1 "G28\nG29 W" + + #define USER_DESC_2 "Preheat for PLA" + #define USER_GCODE_2 "M140 S" STRINGIFY(PREHEAT_1_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND) + + #define USER_DESC_3 "Preheat for ABS" + #define USER_GCODE_3 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND) + + #define USER_DESC_4 "Heat Bed/Home/Level" + #define USER_GCODE_4 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nG28\nG29" + + //#define USER_DESC_5 "Home & Info" + //#define USER_GCODE_5 "G28\nM503" +#endif + +/** + * Specify an action command to send to the host when the printer is killed. + * Will be sent in the form '//action:ACTION_ON_KILL', e.g. '//action:poweroff'. + * The host must be configured to handle the action command. + */ +//#define ACTION_ON_KILL "poweroff" + +//=========================================================================== +//====================== I2C Position Encoder Settings ====================== +//=========================================================================== + +/** + * I2C position encoders for closed loop control. + * Developed by Chris Barr at Aus3D. + * + * Wiki: http://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/ + * + * Reilabuild encoders have been modified to improve reliability. + */ + +//#define I2C_POSITION_ENCODERS +#if ENABLED(I2C_POSITION_ENCODERS) + + #define I2CPE_ENCODER_CNT 1 // The number of encoders installed; max of 5 + // encoders supported currently. + + #define I2CPE_ENC_1_ADDR I2CPE_PRESET_ADDR_X // I2C address of the encoder. 30-200. + #define I2CPE_ENC_1_AXIS X_AXIS // Axis the encoder module is installed on. _AXIS. + #define I2CPE_ENC_1_TYPE I2CPE_ENC_TYPE_LINEAR // Type of encoder: I2CPE_ENC_TYPE_LINEAR -or- + // I2CPE_ENC_TYPE_ROTARY. + #define I2CPE_ENC_1_TICKS_UNIT 2048 // 1024 for magnetic strips with 2mm poles; 2048 for + // 1mm poles. For linear encoders this is ticks / mm, + // for rotary encoders this is ticks / revolution. + //#define I2CPE_ENC_1_TICKS_REV (16 * 200) // Only needed for rotary encoders; number of stepper + // steps per full revolution (motor steps/rev * microstepping) + //#define I2CPE_ENC_1_INVERT // Invert the direction of axis travel. + #define I2CPE_ENC_1_EC_METHOD I2CPE_ECM_NONE // Type of error error correction. + #define I2CPE_ENC_1_EC_THRESH 0.10 // Threshold size for error (in mm) above which the + // printer will attempt to correct the error; errors + // smaller than this are ignored to minimize effects of + // measurement noise / latency (filter). + + #define I2CPE_ENC_2_ADDR I2CPE_PRESET_ADDR_Y // Same as above, but for encoder 2. + #define I2CPE_ENC_2_AXIS Y_AXIS + #define I2CPE_ENC_2_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_ENC_2_TICKS_UNIT 2048 + //#define I2CPE_ENC_2_TICKS_REV (16 * 200) + //#define I2CPE_ENC_2_INVERT + #define I2CPE_ENC_2_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_ENC_2_EC_THRESH 0.10 + + #define I2CPE_ENC_3_ADDR I2CPE_PRESET_ADDR_Z // Encoder 3. Add additional configuration options + #define I2CPE_ENC_3_AXIS Z_AXIS // as above, or use defaults below. + + #define I2CPE_ENC_4_ADDR I2CPE_PRESET_ADDR_E // Encoder 4. + #define I2CPE_ENC_4_AXIS E_AXIS + + #define I2CPE_ENC_5_ADDR 34 // Encoder 5. + #define I2CPE_ENC_5_AXIS E_AXIS + + // Default settings for encoders which are enabled, but without settings configured above. + #define I2CPE_DEF_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_DEF_ENC_TICKS_UNIT 2048 + #define I2CPE_DEF_TICKS_REV (16 * 200) + #define I2CPE_DEF_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_DEF_EC_THRESH 0.1 + + //#define I2CPE_ERR_THRESH_ABORT 100.0 // Threshold size for error (in mm) error on any given + // axis after which the printer will abort. Comment out to + // disable abort behaviour. + + #define I2CPE_TIME_TRUSTED 10000 // After an encoder fault, there must be no further fault + // for this amount of time (in ms) before the encoder + // is trusted again. + + /** + * Position is checked every time a new command is executed from the buffer but during long moves, + * this setting determines the minimum update time between checks. A value of 100 works well with + * error rolling average when attempting to correct only for skips and not for vibration. + */ + #define I2CPE_MIN_UPD_TIME_MS 100 // Minimum time in miliseconds between encoder checks. + + // Use a rolling average to identify persistant errors that indicate skips, as opposed to vibration and noise. + #define I2CPE_ERR_ROLLING_AVERAGE + +#endif // I2C_POSITION_ENCODERS + +/** + * MAX7219 Debug Matrix + * + * Add support for a low-cost 8x8 LED Matrix based on the Max7219 chip, which can be used as a status + * display. Requires 3 signal wires. Some useful debug options are included to demonstrate its usage. + * + * Fully assembled MAX7219 boards can be found on the internet for under $2(US). + * For example, see https://www.ebay.com/sch/i.html?_nkw=332349290049 + */ +//#define MAX7219_DEBUG +#if ENABLED(MAX7219_DEBUG) + #define MAX7219_CLK_PIN 64 // 77 on Re-ARM // Configuration of the 3 pins to control the display + #define MAX7219_DIN_PIN 57 // 78 on Re-ARM + #define MAX7219_LOAD_PIN 44 // 79 on Re-ARM + + /** + * Sample debug features + * If you add more debug displays, be careful to avoid conflicts! + */ + #define MAX7219_DEBUG_PRINTER_ALIVE // Blink corner LED of 8x8 matrix to show that the firmware is functioning + #define MAX7219_DEBUG_STEPPER_HEAD 3 // Show the stepper queue head position on this and the next LED matrix row + #define MAX7219_DEBUG_STEPPER_TAIL 5 // Show the stepper queue tail position on this and the next LED matrix row + + #define MAX7219_DEBUG_STEPPER_QUEUE 0 // Show the current stepper queue depth on this and the next LED matrix row + // If you experience stuttering, reboots, etc. this option can reveal how + // tweaks made to the configuration are affecting the printer in real-time. +#endif + +#endif // CONFIGURATION_ADV_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/wt150/Configuration.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/wt150/Configuration.h new file mode 100644 index 00000000..b285ac0e --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/wt150/Configuration.h @@ -0,0 +1,1705 @@ +/** + * 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 . + * + */ + +/** + * Configuration.h + * + * Basic settings such as: + * + * - Type of electronics + * - Type of temperature sensor + * - Printer geometry + * - Endstop configuration + * - LCD controller + * - Extra features + * + * Advanced settings can be found in Configuration_adv.h + * + */ +#ifndef CONFIGURATION_H +#define CONFIGURATION_H +#define CONFIGURATION_H_VERSION 010100 + +//=========================================================================== +//============================= Getting Started ============================= +//=========================================================================== + +/** + * Here are some standard links for getting your machine calibrated: + * + * http://reprap.org/wiki/Calibration + * http://youtu.be/wAL9d7FgInk + * http://calculator.josefprusa.cz + * http://reprap.org/wiki/Triffid_Hunter%27s_Calibration_Guide + * http://www.thingiverse.com/thing:5573 + * https://sites.google.com/site/repraplogphase/calibration-of-your-reprap + * http://www.thingiverse.com/thing:298812 + */ + +//=========================================================================== +//============================= DELTA Printer =============================== +//=========================================================================== +// For a Delta printer start with one of the configuration files in the +// example_configurations/delta directory and customize for your machine. +// + +//=========================================================================== +//============================= SCARA Printer =============================== +//=========================================================================== +// For a SCARA printer start with the configuration files in +// example_configurations/SCARA and customize for your machine. +// + +// @section info + +// User-specified version info of this build to display in [Pronterface, etc] terminal window during +// startup. Implementation of an idea by Prof Braino to inform user that any changes made to this +// build by the user have been successfully uploaded into firmware. +#define STRING_CONFIG_H_AUTHOR "(none, wt150)" // Who made the changes. +#define SHOW_BOOTSCREEN +#define STRING_SPLASH_LINE1 SHORT_BUILD_VERSION // will be shown during bootup in line 1 +#define STRING_SPLASH_LINE2 WEBSITE_URL // will be shown during bootup in line 2 + +// +// *** VENDORS PLEASE READ ***************************************************** +// +// Marlin now allow you to have a vendor boot image to be displayed on machine +// start. When SHOW_CUSTOM_BOOTSCREEN is defined Marlin will first show your +// custom boot image and then the default Marlin boot image is shown. +// +// We suggest for you to take advantage of this new feature and keep the Marlin +// boot image unmodified. For an example have a look at the bq Hephestos 2 +// example configuration folder. +// +//#define SHOW_CUSTOM_BOOTSCREEN +// @section machine + +/** + * Select which serial port on the board will be used for communication with the host. + * This allows the connection of wireless adapters (for instance) to non-default port pins. + * Serial port 0 is always used by the Arduino bootloader regardless of this setting. + * + * :[0, 1, 2, 3, 4, 5, 6, 7] + */ +#define SERIAL_PORT 0 + +/** + * This setting determines the communication speed of the printer. + * + * 250000 works in most cases, but you might try a lower speed if + * you commonly experience drop-outs during host printing. + * You may try up to 1000000 to speed up SD file transfer. + * + * :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000] + */ +#define BAUDRATE 115200 + +// Enable the Bluetooth serial interface on AT90USB devices +//#define BLUETOOTH + +// The following define selects which electronics board you have. +// Please choose the name from boards.h that matches your setup +#ifndef MOTHERBOARD + #define MOTHERBOARD BOARD_MIGHTYBOARD_REVE +#endif + +// Optional custom name for your RepStrap or other custom machine +// Displayed in the LCD "Ready" message +//#define CUSTOM_MACHINE_NAME "Weistek WT150" + +// Define this to set a unique identifier for this printer, (Used by some programs to differentiate between machines) +// You can use an online service to generate a random UUID. (eg http://www.uuidgenerator.net/version4) +//#define MACHINE_UUID "5f0bb7a3-0e14-428c-812b-15ab0d3ecc71" + +// @section extruder + +// This defines the number of extruders +// :[1, 2, 3, 4, 5] +#define EXTRUDERS 1 + +// For Cyclops or any "multi-extruder" that shares a single nozzle. +//#define SINGLENOZZLE + +/** + * Průša MK2 Single Nozzle Multi-Material Multiplexer, and variants. + * + * This device allows one stepper driver on a control board to drive + * two to eight stepper motors, one at a time, in a manner suitable + * for extruders. + * + * This option only allows the multiplexer to switch on tool-change. + * Additional options to configure custom E moves are pending. + */ +//#define MK2_MULTIPLEXER +#if ENABLED(MK2_MULTIPLEXER) + // Override the default DIO selector pins here, if needed. + // Some pins files may provide defaults for these pins. + //#define E_MUX0_PIN 40 // Always Required + //#define E_MUX1_PIN 42 // Needed for 3 to 8 steppers + //#define E_MUX2_PIN 44 // Needed for 5 to 8 steppers +#endif + +// A dual extruder that uses a single stepper motor +//#define SWITCHING_EXTRUDER +#if ENABLED(SWITCHING_EXTRUDER) + #define SWITCHING_EXTRUDER_SERVO_NR 0 + #define SWITCHING_EXTRUDER_SERVO_ANGLES { 0, 90 } // Angles for E0, E1[, E2, E3] + #if EXTRUDERS > 3 + #define SWITCHING_EXTRUDER_E23_SERVO_NR 1 + #endif +#endif + +// A dual-nozzle that uses a servomotor to raise/lower one of the nozzles +//#define SWITCHING_NOZZLE +#if ENABLED(SWITCHING_NOZZLE) + #define SWITCHING_NOZZLE_SERVO_NR 0 + #define SWITCHING_NOZZLE_SERVO_ANGLES { 0, 90 } // Angles for E0, E1 + //#define HOTEND_OFFSET_Z { 0.0, 0.0 } +#endif + +/** + * Two separate X-carriages with extruders that connect to a moving part + * via a magnetic docking mechanism. Requires SOL1_PIN and SOL2_PIN. + */ +//#define PARKING_EXTRUDER +#if ENABLED(PARKING_EXTRUDER) + #define PARKING_EXTRUDER_SOLENOIDS_INVERT // If enabled, the solenoid is NOT magnetized with applied voltage + #define PARKING_EXTRUDER_SOLENOIDS_PINS_ACTIVE LOW // LOW or HIGH pin signal energizes the coil + #define PARKING_EXTRUDER_SOLENOIDS_DELAY 250 // Delay (ms) for magnetic field. No delay if 0 or not defined. + #define PARKING_EXTRUDER_PARKING_X { -78, 184 } // X positions for parking the extruders + #define PARKING_EXTRUDER_GRAB_DISTANCE 1 // mm to move beyond the parking point to grab the extruder + #define PARKING_EXTRUDER_SECURITY_RAISE 5 // Z-raise before parking + #define HOTEND_OFFSET_Z { 0.0, 1.3 } // Z-offsets of the two hotends. The first must be 0. +#endif + +/** + * "Mixing Extruder" + * - Adds a new code, M165, to set the current mix factors. + * - Extends the stepping routines to move multiple steppers in proportion to the mix. + * - Optional support for Repetier Firmware M163, M164, and virtual extruder. + * - This implementation supports only a single extruder. + * - Enable DIRECT_MIXING_IN_G1 for Pia Taubert's reference implementation + */ +//#define MIXING_EXTRUDER +#if ENABLED(MIXING_EXTRUDER) + #define MIXING_STEPPERS 2 // Number of steppers in your mixing extruder + #define MIXING_VIRTUAL_TOOLS 16 // Use the Virtual Tool method with M163 and M164 + //#define DIRECT_MIXING_IN_G1 // Allow ABCDHI mix factors in G1 movement commands +#endif + +// Offset of the extruders (uncomment if using more than one and relying on firmware to position when changing). +// The offset has to be X=0, Y=0 for the extruder 0 hotend (default extruder). +// For the other hotends it is their distance from the extruder 0 hotend. +//#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis +//#define HOTEND_OFFSET_Y {0.0, 5.00} // (in mm) for each extruder, offset of the hotend on the Y axis + +// @section machine + +/** + * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN + * + * 0 = No Power Switch + * 1 = ATX + * 2 = X-Box 360 203Watts (the blue wire connected to PS_ON and the red wire to VCC) + * + * :{ 0:'No power switch', 1:'ATX', 2:'X-Box 360' } + */ +#define POWER_SUPPLY 0 + +#if POWER_SUPPLY > 0 + // Enable this option to leave the PSU off at startup. + // Power to steppers and heaters will need to be turned on with M80. + //#define PS_DEFAULT_OFF +#endif + +// @section temperature + +//=========================================================================== +//============================= Thermal Settings ============================ +//=========================================================================== + +/** + * --NORMAL IS 4.7kohm PULLUP!-- 1kohm pullup can be used on hotend sensor, using correct resistor and table + * + * Temperature sensors available: + * + * -3 : thermocouple with MAX31855 (only for sensor 0) + * -2 : thermocouple with MAX6675 (only for sensor 0) + * -1 : thermocouple with AD595 + * 0 : not used + * 1 : 100k thermistor - best choice for EPCOS 100k (4.7k pullup) + * 2 : 200k thermistor - ATC Semitec 204GT-2 (4.7k pullup) + * 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 (Used in ParCan & J-Head) (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) + * 71 : 100k Honeywell thermistor 135-104LAF-J01 (4.7k pullup) + * 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) + * 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" + * 20 : the PT100 circuit found in the Ultimainboard V2.x + * 60 : 100k Maker's Tool Works Kapton Bed Thermistor beta=3950 + * 66 : 4.7M High Temperature thermistor from Dyze Design + * 70 : the 100K thermistor found in the bq Hephestos 2 + * 75 : 100k Generic Silicon Heat Pad with NTC 100K MGB18-104F39050L32 thermistor + * + * 1k ohm pullup tables - This is atypical, and requires changing out the 4.7k pullup for 1k. + * (but gives greater accuracy and more stable PID) + * 51 : 100k thermistor - EPCOS (1k pullup) + * 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 + * 1010 : Pt1000 with 1k pullup (non standard) + * 147 : Pt100 with 4k7 pullup + * 110 : Pt100 with 1k pullup (non standard) + * + * Use these for Testing or Development purposes. NEVER for production machine. + * 998 : Dummy Table that ALWAYS reads 25°C or the temperature defined below. + * 999 : Dummy Table that ALWAYS reads 100°C or the temperature defined below. + * + * :{ '0': "Not used", '1':"100k / 4.7k - EPCOS", '2':"200k / 4.7k - ATC Semitec 204GT-2", '3':"Mendel-parts / 4.7k", '4':"10k !! do not use for a hotend. Bad resolution at high temp. !!", '5':"100K / 4.7k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '6':"100k / 4.7k EPCOS - Not as accurate as Table 1", '7':"100k / 4.7k Honeywell 135-104LAG-J01", '8':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT", '9':"100k / 4.7k GE Sensing AL03006-58.2K-97-G1", '10':"100k / 4.7k RS 198-961", '11':"100k / 4.7k beta 3950 1%", '12':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT (calibrated for Makibox hot bed)", '13':"100k Hisens 3950 1% up to 300°C for hotend 'Simple ONE ' & hotend 'All In ONE'", '20':"PT100 (Ultimainboard V2.x)", '51':"100k / 1k - EPCOS", '52':"200k / 1k - ATC Semitec 204GT-2", '55':"100k / 1k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '60':"100k Maker's Tool Works Kapton Bed Thermistor beta=3950", '66':"Dyze Design 4.7M High Temperature thermistor", '70':"the 100K thermistor found in the bq Hephestos 2", '71':"100k / 4.7k Honeywell 135-104LAF-J01", '147':"Pt100 / 4.7k", '1047':"Pt1000 / 4.7k", '110':"Pt100 / 1k (non-standard)", '1010':"Pt1000 / 1k (non standard)", '-3':"Thermocouple + MAX31855 (only for sensor 0)", '-2':"Thermocouple + MAX6675 (only for sensor 0)", '-1':"Thermocouple + AD595",'998':"Dummy 1", '999':"Dummy 2" } + */ +#define TEMP_SENSOR_0 -2 +#define TEMP_SENSOR_1 0 +#define TEMP_SENSOR_2 0 +#define TEMP_SENSOR_3 0 +#define TEMP_SENSOR_4 0 +#define TEMP_SENSOR_BED 0 + +// Dummy thermistor constant temperature readings, for use with 998 and 999 +#define DUMMY_THERMISTOR_998_VALUE 25 +#define DUMMY_THERMISTOR_999_VALUE 100 + +// 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 +#define MAX_REDUNDANT_TEMP_SENSOR_DIFF 10 + +// Extruder temperature must be close to target for this long before M109 returns success +#define TEMP_RESIDENCY_TIME 10 // (seconds) +#define TEMP_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// Bed temperature must be close to target for this long before M190 returns success +#define TEMP_BED_RESIDENCY_TIME 10 // (seconds) +#define TEMP_BED_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_BED_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// The minimal temperature defines the temperature below which the heater will not be enabled It is used +// to check that the wiring to the thermistor is not broken. +// Otherwise this would lead to the heater being powered on all the time. +#define HEATER_0_MINTEMP 5 +#define HEATER_1_MINTEMP 5 +#define HEATER_2_MINTEMP 5 +#define HEATER_3_MINTEMP 5 +#define HEATER_4_MINTEMP 5 +#define BED_MINTEMP 5 + +// When temperature exceeds max temp, your heater will be switched off. +// This feature exists to protect your hotend from overheating accidentally, but *NOT* from thermistor short/failure! +// You should use MINTEMP for thermistor short/failure protection. +#define HEATER_0_MAXTEMP 275 +#define HEATER_1_MAXTEMP 275 +#define HEATER_2_MAXTEMP 275 +#define HEATER_3_MAXTEMP 275 +#define HEATER_4_MAXTEMP 275 +#define BED_MAXTEMP 150 + +//=========================================================================== +//============================= PID Settings ================================ +//=========================================================================== +// PID Tuning Guide here: http://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 +#if ENABLED(PIDTEMP) + //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. + //#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. + #define K1 0.95 //smoothing factor within the PID + + // If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it + + //WT150, based on: M303 E0 S220 C8 + #define DEFAULT_Kp 22.10 + #define DEFAULT_Ki 1.10 + #define DEFAULT_Kd 110.78 + + // 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 + +#endif // PIDTEMP + +//=========================================================================== +//============================= PID > Bed Temperature Control =============== +//=========================================================================== +// Select PID or bang-bang with PIDTEMPBED. If bang-bang, BED_LIMIT_SWITCHING will enable hysteresis +// +// Uncomment this to enable PID on the bed. It uses the same frequency PWM as the extruder. +// If your PID_dT is the default, and correct for your hardware/configuration, that means 7.689Hz, +// which is fine for driving a square wave into a resistive load and does not significantly impact you FET heating. +// This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W heater. +// If your configuration is significantly different than this and you don't understand the issues involved, you probably +// shouldn't use bed PID until someone else verifies your hardware works. +// If this is enabled, find your own PID constants below. +//#define PIDTEMPBED + +//#define BED_LIMIT_SWITCHING + +// This sets the max power delivered to the bed, and replaces the HEATER_BED_DUTY_CYCLE_DIVIDER option. +// all forms of bed control obey this (PID, bang-bang, bang-bang with hysteresis) +// setting this to anything other than 255 enables a form of PWM to the bed just like HEATER_BED_DUTY_CYCLE_DIVIDER did, +// so you shouldn't use it unless you are OK with PWM on your bed. (see the comment on enabling PIDTEMPBED) +#define MAX_BED_POWER 255 // limits duty cycle to bed; 255=full current + +#if ENABLED(PIDTEMPBED) + + //#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) + #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 + +// @section extruder + +// This option prevents extrusion if the temperature is below EXTRUDE_MINTEMP. +// It also enables the M302 command to set the minimum extrusion temperature +// or to allow moving the extruder regardless of the hotend temperature. +// *** IT IS HIGHLY RECOMMENDED TO LEAVE THIS OPTION ENABLED! *** +#define PREVENT_COLD_EXTRUSION +#define EXTRUDE_MINTEMP 170 + +// This option prevents a single extrusion longer than EXTRUDE_MAXLENGTH. +// Note that for Bowden Extruders a too-small value here may prevent loading. +#define PREVENT_LENGTHY_EXTRUDE +#define EXTRUDE_MAXLENGTH 200 + +//=========================================================================== +//======================== Thermal Runaway Protection ======================= +//=========================================================================== + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * If you get "Thermal Runaway" or "Heating failed" errors the + * details can be tuned in Configuration_adv.h + */ + +#define THERMAL_PROTECTION_HOTENDS // Enable thermal protection for all extruders +#define THERMAL_PROTECTION_BED // Enable thermal protection for the heated bed + +//=========================================================================== +//============================= Mechanical Settings ========================= +//=========================================================================== + +// @section machine + +// Uncomment one of these options to enable CoreXY, CoreXZ, or CoreYZ kinematics +// either in the usual order or reversed +//#define COREXY +//#define COREXZ +//#define COREYZ +//#define COREYX +//#define COREZX +//#define COREZY + +//=========================================================================== +//============================== Endstop Settings =========================== +//=========================================================================== + +// @section homing + +// Specify here all the endstop connectors that are connected to any endstop or probe. +// Almost all printers will be using one per axis. Probes will use one or more of the +// extra connectors. Leave undefined any used for non-endstop and non-probe purposes. +#define USE_XMIN_PLUG +#define USE_YMIN_PLUG +//#define USE_ZMIN_PLUG +//#define USE_XMAX_PLUG +//#define USE_YMAX_PLUG +#define USE_ZMAX_PLUG + +// coarse Endstop Settings +//#define ENDSTOPPULLUPS // Comment this out (using // at the start of the line) to disable the endstop pullup resistors + +#if DISABLED(ENDSTOPPULLUPS) + // fine endstop settings: Individual pullups. will be ignored if ENDSTOPPULLUPS is defined + //#define ENDSTOPPULLUP_XMAX + //#define ENDSTOPPULLUP_YMAX + //#define ENDSTOPPULLUP_ZMAX + //#define ENDSTOPPULLUP_XMIN + //#define ENDSTOPPULLUP_YMIN + //#define ENDSTOPPULLUP_ZMIN + //#define ENDSTOPPULLUP_ZMIN_PROBE +#endif + +// Mechanical endstop with COM to ground and NC to Signal uses "false" here (most common setup). +#define X_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Y_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MIN_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define X_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Y_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MIN_PROBE_ENDSTOP_INVERTING false // set to true to invert the logic of the probe. + +// Enable this feature if all enabled endstop pins are interrupt-capable. +// This will remove the need to poll the interrupt pins, saving many CPU cycles. +//#define ENDSTOP_INTERRUPTS_FEATURE + +//============================================================================= +//============================== Movement Settings ============================ +//============================================================================= +// @section motion + +/** + * Default Settings + * + * These settings can be reset by M502 + * + * Note that if EEPROM is enabled, saved values will override these. + */ + +/** + * With this option each E stepper can have its own factors for the + * following movement settings. If fewer factors are given than the + * total number of extruders, the last value applies to the rest. + */ +//#define DISTINCT_E_FACTORS + +/** + * Default Axis Steps Per Unit (steps/mm) + * Override with M92 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_AXIS_STEPS_PER_UNIT { 71.699959, 71.699959, 71.699959, 100.470955 } + +/** + * Default Max Feed Rate (mm/s) + * Override with M203 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_FEEDRATE { 83.333333, 83.333333, 19.5, 26.666666 } + +/** + * Default Max Acceleration (change/s) change = mm/s + * (Maximum start speed for accelerated moves) + * Override with M201 + * X, Y, Z, E0 [, E1[, E2[, E3[, E4]]]] + */ +#define DEFAULT_MAX_ACCELERATION { 1200, 1200, 100, 10000 } + +/** + * Default Acceleration (change/s) change = mm/s + * Override with M204 + * + * M204 P Acceleration + * M204 R Retract Acceleration + * M204 T Travel Acceleration + */ +#define DEFAULT_ACCELERATION 1200 // X, Y, Z and E acceleration for printing moves +#define DEFAULT_RETRACT_ACCELERATION 1200 // E acceleration for retracts +#define DEFAULT_TRAVEL_ACCELERATION 1200 // X, Y, Z acceleration for travel (non printing) moves + +/** + * Default Jerk (mm/s) + * Override with M205 X Y Z E + * + * "Jerk" specifies the minimum speed change that requires acceleration. + * When changing speed and direction, if the difference is less than the + * value set here, it may happen instantaneously. + */ +#define DEFAULT_XJERK 8.0 +#define DEFAULT_YJERK 8.0 +#define DEFAULT_ZJERK 0.4 +#define DEFAULT_EJERK 5.0 + +//=========================================================================== +//============================= Z Probe Options ============================= +//=========================================================================== +// @section probes + +// +// See http://marlinfw.org/configuration/probes.html +// + +/** + * Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + * + * Enable this option for a probe connected to the Z Min endstop pin. + */ +#define Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + +/** + * Z_MIN_PROBE_ENDSTOP + * + * Enable this option for a probe connected to any pin except Z-Min. + * (By default Marlin assumes the Z-Max endstop pin.) + * To use a custom Z Probe pin, set Z_MIN_PROBE_PIN below. + * + * - The simplest option is to use a free endstop connector. + * - Use 5V for powered (usually inductive) sensors. + * + * - RAMPS 1.3/1.4 boards may use the 5V, GND, and Aux4->D32 pin: + * - For simple switches connect... + * - normally-closed switches to GND and D32. + * - normally-open switches to 5V and D32. + * + * WARNING: Setting the wrong pin may have unexpected and potentially + * disastrous consequences. Use with caution and do your homework. + * + */ +//#define Z_MIN_PROBE_ENDSTOP + +/** + * Probe Type + * + * Allen Key Probes, Servo Probes, Z-Sled Probes, FIX_MOUNTED_PROBE, etc. + * Activate one of these to use Auto Bed Leveling below. + */ + +/** + * The "Manual Probe" provides a means to do "Auto" Bed Leveling without a probe. + * Use G29 repeatedly, adjusting the Z height at each point with movement commands + * or (with LCD_BED_LEVELING) the LCD controller. + */ +//#define PROBE_MANUALLY + +/** + * A Fix-Mounted Probe either doesn't deploy or needs manual deployment. + * (e.g., an inductive probe or a nozzle-based probe-switch.) + */ +//#define FIX_MOUNTED_PROBE + +/** + * Z Servo Probe, such as an endstop switch on a rotating arm. + */ +//#define Z_ENDSTOP_SERVO_NR 0 // Defaults to SERVO 0 connector. +//#define Z_SERVO_ANGLES {70,0} // Z Servo Deploy and Stow angles + +/** + * The BLTouch probe uses a Hall effect sensor and emulates a servo. + */ +//#define BLTOUCH +#if ENABLED(BLTOUCH) + //#define BLTOUCH_DELAY 375 // (ms) Enable and increase if needed +#endif + +/** + * Enable one or more of the following if probing seems unreliable. + * Heaters and/or fans can be disabled during probing to minimize electrical + * noise. A delay can also be added to allow noise and vibration to settle. + * These options are most useful for the BLTouch probe, but may also improve + * readings with inductive probes and piezo sensors. + */ +//#define PROBING_HEATERS_OFF // Turn heaters off when probing +//#define PROBING_FANS_OFF // Turn fans off when probing +//#define DELAY_BEFORE_PROBING 200 // (ms) To prevent vibrations from triggering piezo sensors + +// A probe that is deployed and stowed with a solenoid pin (SOL1_PIN) +//#define SOLENOID_PROBE + +// A sled-mounted probe like those designed by Charles Bell. +//#define Z_PROBE_SLED +//#define SLED_DOCKING_OFFSET 5 // The extra distance the X axis must travel to pickup the sled. 0 should be fine but you can push it further if you'd like. + +// +// For Z_PROBE_ALLEN_KEY see the Delta example configurations. +// + +/** + * Z Probe to nozzle (X,Y) offset, relative to (0, 0). + * X and Y offsets must be integers. + * + * In the following example the X and Y offsets are both positive: + * #define X_PROBE_OFFSET_FROM_EXTRUDER 10 + * #define Y_PROBE_OFFSET_FROM_EXTRUDER 10 + * + * +-- BACK ---+ + * | | + * L | (+) P | R <-- probe (20,20) + * E | | I + * F | (-) N (+) | G <-- nozzle (10,10) + * T | | H + * | (-) | T + * | | + * O-- FRONT --+ + * (0,0) + */ +#define X_PROBE_OFFSET_FROM_EXTRUDER 10 // X offset: -left +right [of the nozzle] +#define Y_PROBE_OFFSET_FROM_EXTRUDER 10 // Y offset: -front +behind [the nozzle] +#define Z_PROBE_OFFSET_FROM_EXTRUDER 0 // Z offset: -below +above [the nozzle] + +// X and Y axis travel speed (mm/m) between probes +#define XY_PROBE_SPEED 8000 + +// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +#define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z + +// Speed for the "accurate" probe of each point +#define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) + +// Use double touch for probing +//#define PROBE_DOUBLE_TOUCH + +/** + * Z probes require clearance when deploying, stowing, and moving between + * probe points to avoid hitting the bed and other hardware. + * Servo-mounted probes require extra space for the arm to rotate. + * Inductive probes need space to keep from triggering early. + * + * Use these settings to specify the distance (mm) to raise the probe (or + * lower the bed). The values set here apply over and above any (negative) + * probe Z Offset set with Z_PROBE_OFFSET_FROM_EXTRUDER, M851, or the LCD. + * Only integer values >= 1 are valid here. + * + * Example: `M851 Z-5` with a CLEARANCE of 4 => 9mm from bed to nozzle. + * But: `M851 Z+1` with a CLEARANCE of 2 => 2mm from bed to nozzle. + */ +#define Z_CLEARANCE_DEPLOY_PROBE 10 // Z Clearance for Deploy/Stow +#define Z_CLEARANCE_BETWEEN_PROBES 5 // Z Clearance between probe points + +// For M851 give a range for adjusting the Z probe offset +#define Z_PROBE_OFFSET_RANGE_MIN -20 +#define Z_PROBE_OFFSET_RANGE_MAX 20 + +// Enable the M48 repeatability test to test probe accuracy +//#define Z_MIN_PROBE_REPEATABILITY_TEST + +// For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1 +// :{ 0:'Low', 1:'High' } +#define X_ENABLE_ON 0 +#define Y_ENABLE_ON 0 +#define Z_ENABLE_ON 0 +#define E_ENABLE_ON 0 // For all extruders + +// Disables axis stepper immediately when it's not being used. +// 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 +//#define DISABLE_REDUCED_ACCURACY_WARNING + +// @section extruder + +#define DISABLE_E false // For all extruders +#define DISABLE_INACTIVE_EXTRUDER true // Keep only the active extruder enabled. + +// @section machine + +// Invert the stepper direction. Change (or reverse the motor connector) if an axis goes the wrong way. +#define INVERT_X_DIR true +#define INVERT_Y_DIR false +#define INVERT_Z_DIR false + +// Enable this option for Toshiba steppers +//#define CONFIG_STEPPERS_TOSHIBA + +// @section extruder + +// For direct drive extruder v9 set to true, for geared extruder set to false. +#define INVERT_E0_DIR false +#define INVERT_E1_DIR false +#define INVERT_E2_DIR false +#define INVERT_E3_DIR false +#define INVERT_E4_DIR false + +// @section homing + +//#define NO_MOTION_BEFORE_HOMING // Inhibit movement until all axes have been homed + +//#define Z_HOMING_HEIGHT 4 // (in mm) Minimal z height before homing (G28) for Z clearance above the bed, clamps, ... + // Be sure you have this distance over your Z_MAX_POS in case. + +// Direction of endstops when homing; 1=MAX, -1=MIN +// :[-1,1] +#define X_HOME_DIR -1 +#define Y_HOME_DIR -1 +#define Z_HOME_DIR 1 + +// @section machine + +// The size of the print bed +#define X_BED_SIZE 150 +#define Y_BED_SIZE 150 + +// Travel limits (mm) after homing, corresponding to endstop positions. +#define X_MIN_POS 0 +#define Y_MIN_POS 0 +#define Z_MIN_POS 0 +#define X_MAX_POS X_BED_SIZE +#define Y_MAX_POS Y_BED_SIZE +#define Z_MAX_POS 143.0 + +// If enabled, axes won't move below MIN_POS in response to movement commands. +#define MIN_SOFTWARE_ENDSTOPS +// If enabled, axes won't move above MAX_POS in response to movement commands. +#define MAX_SOFTWARE_ENDSTOPS + +/** + * Filament Runout Sensor + * A mechanical or opto endstop is used to check for the presence of filament. + * + * RAMPS-based boards use SERVO3_PIN. + * For other boards you may need to define FIL_RUNOUT_PIN. + * By default the firmware assumes HIGH = has filament, LOW = ran out + */ +//#define FILAMENT_RUNOUT_SENSOR +#if ENABLED(FILAMENT_RUNOUT_SENSOR) + #define FIL_RUNOUT_INVERTING false // set to true to invert the logic of the sensor. + #define ENDSTOPPULLUP_FIL_RUNOUT // Uncomment to use internal pullup for filament runout pins if the sensor is defined. + #define FILAMENT_RUNOUT_SCRIPT "M600" +#endif + +//=========================================================================== +//=============================== Bed Leveling ============================== +//=========================================================================== +// @section bedlevel + +/** + * Choose one of the options below to enable G29 Bed Leveling. The parameters + * and behavior of G29 will change depending on your selection. + * + * If using a Probe for Z Homing, enable Z_SAFE_HOMING also! + * + * - AUTO_BED_LEVELING_3POINT + * Probe 3 arbitrary points on the bed (that aren't collinear) + * You specify the XY coordinates of all 3 points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_LINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a single tilted plane. Best for a flat bed. + * + * - AUTO_BED_LEVELING_BILINEAR + * Probe several points in a grid. + * You specify the rectangle and the density of sample points. + * The result is a mesh, best for large or uneven beds. + * + * - AUTO_BED_LEVELING_UBL (Unified Bed Leveling) + * A comprehensive bed leveling system combining the features and benefits + * of other systems. UBL also includes integrated Mesh Generation, Mesh + * Validation and Mesh Editing systems. Currently, UBL is only checked out + * for Cartesian Printers. That said, it was primarily designed to correct + * poor quality Delta Printers. If you feel adventurous and have a Delta, + * please post an issue if something doesn't work correctly. Initially, + * you will need to set a reduced bed size so you have a rectangular area + * to test on. + * + * - MESH_BED_LEVELING + * Probe a grid manually + * The result is a mesh, suitable for large or uneven beds. (See BILINEAR.) + * For machines without a probe, Mesh Bed Leveling provides a method to perform + * leveling in steps so you can manually adjust the Z height at each grid-point. + * With an LCD controller the process is guided step-by-step. + */ +//#define AUTO_BED_LEVELING_3POINT +//#define AUTO_BED_LEVELING_LINEAR +//#define AUTO_BED_LEVELING_BILINEAR +//#define AUTO_BED_LEVELING_UBL +//#define MESH_BED_LEVELING + +/** + * Enable detailed logging of G28, G29, M48, etc. + * Turn on with the command 'M111 S32'. + * NOTE: Requires a lot of PROGMEM! + */ +//#define DEBUG_LEVELING_FEATURE + +#if ENABLED(MESH_BED_LEVELING) || ENABLED(AUTO_BED_LEVELING_BILINEAR) || ENABLED(AUTO_BED_LEVELING_UBL) + // Gradually reduce leveling correction until a set height is reached, + // at which point movement will be level to the machine's XY plane. + // The height can be set with M420 Z + #define ENABLE_LEVELING_FADE_HEIGHT +#endif + +#if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Set the number of grid points per dimension. + #define GRID_MAX_POINTS_X 3 + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + // Set the boundaries for probing (where the probe can reach). + #define LEFT_PROBE_BED_POSITION 15 + #define RIGHT_PROBE_BED_POSITION 170 + #define FRONT_PROBE_BED_POSITION 20 + #define BACK_PROBE_BED_POSITION 170 + + // The Z probe minimum outer margin (to validate G29 parameters). + #define MIN_PROBE_EDGE 10 + + // Probe along the Y axis, advancing X after each column + //#define PROBE_Y_FIRST + + #if ENABLED(AUTO_BED_LEVELING_BILINEAR) + + // Beyond the probed grid, continue the implied tilt? + // Default is to maintain the height of the nearest edge. + //#define EXTRAPOLATE_BEYOND_GRID + + // + // Experimental Subdivision of the grid by Catmull-Rom method. + // Synthesizes intermediate points to produce a more detailed mesh. + // + //#define ABL_BILINEAR_SUBDIVISION + #if ENABLED(ABL_BILINEAR_SUBDIVISION) + // Number of subdivisions between probe points + #define BILINEAR_SUBDIVISIONS 3 + #endif + + #endif + +#elif ENABLED(AUTO_BED_LEVELING_3POINT) + + // 3 arbitrary points to probe. + // A simple cross-product is used to estimate the plane of the bed. + #define ABL_PROBE_PT_1_X 15 + #define ABL_PROBE_PT_1_Y 180 + #define ABL_PROBE_PT_2_X 15 + #define ABL_PROBE_PT_2_Y 20 + #define ABL_PROBE_PT_3_X 170 + #define ABL_PROBE_PT_3_Y 20 + +#elif ENABLED(AUTO_BED_LEVELING_UBL) + + //=========================================================================== + //========================= Unified Bed Leveling ============================ + //=========================================================================== + + #define UBL_MESH_INSET 1 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 10 // Don't use more than 15 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + #define UBL_PROBE_PT_1_X 39 // Probing points for 3-Point leveling of the mesh + #define UBL_PROBE_PT_1_Y 180 + #define UBL_PROBE_PT_2_X 39 + #define UBL_PROBE_PT_2_Y 20 + #define UBL_PROBE_PT_3_X 180 + #define UBL_PROBE_PT_3_Y 20 + + #define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation + #define UBL_MESH_EDIT_MOVES_Z // Sophisticated users prefer no movement of nozzle + +#elif ENABLED(MESH_BED_LEVELING) + + //=========================================================================== + //=================================== Mesh ================================== + //=========================================================================== + + #define MESH_INSET 10 // Mesh inset margin on print area + #define GRID_MAX_POINTS_X 3 // Don't use more than 7 points per axis, implementation limited. + #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X + + //#define MESH_G28_REST_ORIGIN // After homing all axes ('G28' or 'G28 XYZ') rest Z at Z_MIN_POS + +#endif // BED_LEVELING + +/** + * Use the LCD controller for bed leveling + * Requires MESH_BED_LEVELING or PROBE_MANUALLY + */ +//#define LCD_BED_LEVELING + +#if ENABLED(LCD_BED_LEVELING) + #define MBL_Z_STEP 0.025 // Step size while manually probing Z axis. + #define LCD_PROBE_Z_RANGE 4 // Z Range centered on Z_MIN_POS for LCD Z adjustment +#endif + +// Add a menu item to move between bed corners for manual bed adjustment +//#define LEVEL_BED_CORNERS + +/** + * Commands to execute at the end of G29 probing. + * Useful to retract or move the Z probe out of the way. + */ +//#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) +//#define BED_CENTER_AT_0_0 + +// Manually set the home position. Leave these undefined for automatic settings. +// For DELTA this is the top-center of the Cartesian print volume. +//#define MANUAL_X_HOME_POS 0 +//#define MANUAL_Y_HOME_POS 0 +//#define MANUAL_Z_HOME_POS 0 + +// Use "Z Safe Homing" to avoid homing with a Z probe outside the bed area. +// +// With this feature enabled: +// +// - 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). +// - 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 axis (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2) // Y point for Z homing when homing all axis (G28). +#endif + +// Homing speeds (mm/m) +#define HOMING_FEEDRATE_XY (50*60) +#define HOMING_FEEDRATE_Z (4*60) + +//============================================================================= +//============================= Additional Features =========================== +//============================================================================= + +// @section extras + +// +// EEPROM +// +// The microcontroller can store settings in the EEPROM, e.g. max velocity... +// M500 - stores parameters in EEPROM +// M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily). +// M502 - reverts to the default "factory settings". You still need to store them in EEPROM afterwards if you want to. +// +#define EEPROM_SETTINGS // Enable for M500 and M501 commands +//#define DISABLE_M503 // Saves ~2700 bytes of PROGMEM. Disable for release! +#define EEPROM_CHITCHAT // Give feedback on EEPROM commands. Disable to save PROGMEM. + +// +// Host Keepalive +// +// When enabled Marlin will send a busy status message to the host +// every couple of seconds when it can't accept commands. +// +#define HOST_KEEPALIVE_FEATURE // Disable this if your host doesn't like keepalive messages +#define DEFAULT_KEEPALIVE_INTERVAL 2 // Number of seconds between "busy" messages. Set with M113. +#define BUSY_WHILE_HEATING // Some hosts require "busy" messages even during heating + +// +// M100 Free Memory Watcher +// +//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose + +// +// G20/G21 Inch mode support +// +//#define INCH_MODE_SUPPORT + +// +// M149 Set temperature units support +// +//#define TEMPERATURE_UNITS_SUPPORT + +// @section temperature + +// Preheat Constants +#define PREHEAT_1_TEMP_HOTEND 180 +#define PREHEAT_1_TEMP_BED 70 +#define PREHEAT_1_FAN_SPEED 0 // Value from 0 to 255 + +#define PREHEAT_2_TEMP_HOTEND 240 +#define PREHEAT_2_TEMP_BED 110 +#define PREHEAT_2_FAN_SPEED 0 // Value from 0 to 255 + +/** + * Nozzle Park -- EXPERIMENTAL + * + * Park the nozzle at the given XYZ position on idle or G27. + * + * The "P" parameter controls the action applied to the Z axis: + * + * P0 (Default) If Z is below park Z raise the nozzle. + * P1 Raise the nozzle always to Z-park height. + * P2 Raise the nozzle by Z-park amount, limited to Z_MAX_POS. + */ +//#define NOZZLE_PARK_FEATURE + +#if ENABLED(NOZZLE_PARK_FEATURE) + // Specify a park position as { X, Y, Z } + #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 } +#endif + +/** + * Clean Nozzle Feature -- EXPERIMENTAL + * + * Adds the G12 command to perform a nozzle cleaning process. + * + * Parameters: + * P Pattern + * S Strokes / Repetitions + * T Triangles (P1 only) + * + * Patterns: + * P0 Straight line (default). This process requires a sponge type material + * at a fixed bed location. "S" specifies strokes (i.e. back-forth motions) + * between the start / end points. + * + * P1 Zig-zag pattern between (X0, Y0) and (X1, Y1), "T" specifies the + * number of zig-zag triangles to do. "S" defines the number of strokes. + * Zig-zags are done in whichever is the narrower dimension. + * For example, "G12 P1 S1 T3" will execute: + * + * -- + * | (X0, Y1) | /\ /\ /\ | (X1, Y1) + * | | / \ / \ / \ | + * A | | / \ / \ / \ | + * | | / \ / \ / \ | + * | (X0, Y0) | / \/ \/ \ | (X1, Y0) + * -- +--------------------------------+ + * |________|_________|_________| + * T1 T2 T3 + * + * P2 Circular pattern with middle at NOZZLE_CLEAN_CIRCLE_MIDDLE. + * "R" specifies the radius. "S" specifies the stroke count. + * Before starting, the nozzle moves to NOZZLE_CLEAN_START_POINT. + * + * Caveats: The ending Z should be the same as starting Z. + * Attention: EXPERIMENTAL. G-code arguments may change. + * + */ +//#define NOZZLE_CLEAN_FEATURE + +#if ENABLED(NOZZLE_CLEAN_FEATURE) + // Default number of pattern repetitions + #define NOZZLE_CLEAN_STROKES 12 + + // Default number of triangles + #define NOZZLE_CLEAN_TRIANGLES 3 + + // Specify positions as { X, Y, Z } + #define NOZZLE_CLEAN_START_POINT { 30, 30, (Z_MIN_POS + 1)} + #define NOZZLE_CLEAN_END_POINT {100, 60, (Z_MIN_POS + 1)} + + // Circular pattern radius + #define NOZZLE_CLEAN_CIRCLE_RADIUS 6.5 + // Circular pattern circle fragments number + #define NOZZLE_CLEAN_CIRCLE_FN 10 + // Middle point of circle + #define NOZZLE_CLEAN_CIRCLE_MIDDLE NOZZLE_CLEAN_START_POINT + + // Moves the nozzle to the initial position + #define NOZZLE_CLEAN_GOBACK +#endif + +/** + * Print Job Timer + * + * Automatically start and stop the print job timer on M104/M109/M190. + * + * M104 (hotend, no wait) - high temp = none, low temp = stop timer + * M109 (hotend, wait) - high temp = start timer, low temp = stop timer + * M190 (bed, wait) - high temp = start timer, low temp = none + * + * The timer can also be controlled with the following commands: + * + * M75 - Start the print job timer + * M76 - Pause the print job timer + * M77 - Stop the print job timer + */ +#define PRINTJOB_TIMER_AUTOSTART + +/** + * Print Counter + * + * Track statistical data such as: + * + * - Total print jobs + * - Total successful print jobs + * - Total failed print jobs + * - Total time printing + * + * View the current statistics with M78. + */ +#define PRINTCOUNTER + +//============================================================================= +//============================= LCD and SD support ============================ +//============================================================================= + +// @section lcd + +/** + * LCD LANGUAGE + * + * Select the language to display on the LCD. These languages are available: + * + * en, an, bg, ca, cn, cz, cz_utf8, de, el, el-gr, es, eu, fi, fr, gl, hr, + * it, kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, sk_utf8, + * tr, uk, zh_CN, zh_TW, test + * + * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cn':'Chinese', 'cz':'Czech', 'cz_utf8':'Czech (UTF8)', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'kana':'Japanese', 'kana_utf8':'Japanese (UTF8)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'pt-br_utf8':'Portuguese (Brazilian UTF8)', 'pt_utf8':'Portuguese (UTF8)', 'ru':'Russian', 'sk_utf8':'Slovak (UTF8)', 'tr':'Turkish', 'uk':'Ukrainian', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Taiwan)', test':'TEST' } + */ +#define LCD_LANGUAGE en + +/** + * LCD Character Set + * + * Note: This option is NOT applicable to Graphical Displays. + * + * All character-based LCDs provide ASCII plus one of these + * language extensions: + * + * - JAPANESE ... the most common + * - WESTERN ... with more accented characters + * - CYRILLIC ... for the Russian language + * + * To determine the language extension installed on your controller: + * + * - Compile and upload with LCD_LANGUAGE set to 'test' + * - 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 + * + * :['JAPANESE', 'WESTERN', 'CYRILLIC'] + */ +#define DISPLAY_CHARSET_HD44780 JAPANESE + +/** + * LCD TYPE + * + * Enable ULTRA_LCD for a 16x2, 16x4, 20x2, or 20x4 character-based LCD. + * Enable DOGLCD for a 128x64 (ST7565R) Full Graphical Display. + * (These options will be enabled automatically for most displays.) + * + * IMPORTANT: The U8glib library is required for Full Graphic Display! + * https://github.com/olikraus/U8glib_Arduino + */ +//#define ULTRA_LCD // Character based +//#define DOGLCD // Full graphics display + +/** + * SD CARD + * + * 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 + +/** + * SD CARD: SPI SPEED + * + * Enable one of the following items for a slower SPI transfer speed. + * This may be required to resolve "volume init" errors. + */ +//#define SPI_SPEED SPI_HALF_SPEED +//#define SPI_SPEED SPI_QUARTER_SPEED +//#define SPI_SPEED SPI_EIGHTH_SPEED + +/** + * SD CARD: ENABLE CRC + * + * Use CRC checks and retries on the SD communication. + */ +//#define SD_CHECK_AND_RETRY + +// +// ENCODER SETTINGS +// +// This option overrides the default number of encoder pulses needed to +// produce one step. Should be increased for high-resolution encoders. +// +#define ENCODER_PULSES_PER_STEP 4 + +// +// Use this option to override the number of step signals required to +// move between next/prev menu items. +// +#define ENCODER_STEPS_PER_MENU_ITEM 1 + +/** + * Encoder Direction Options + * + * Test your encoder's behavior first with both options disabled. + * + * Reversed Value Edit and Menu Nav? Enable REVERSE_ENCODER_DIRECTION. + * Reversed Menu Navigation only? Enable REVERSE_MENU_DIRECTION. + * Reversed Value Editing only? Enable BOTH options. + */ + +// +// This option reverses the encoder direction everywhere. +// +// Set this option if CLOCKWISE causes values to DECREASE +// +//#define REVERSE_ENCODER_DIRECTION + +// +// This option reverses the encoder direction for navigating LCD menus. +// +// If CLOCKWISE normally moves DOWN this makes it go UP. +// If CLOCKWISE normally moves UP this makes it go DOWN. +// +//#define REVERSE_MENU_DIRECTION + +// +// Individual Axis Homing +// +// Add individual axis homing items (Home X, Home Y, and Home Z) to the LCD menu. +// +//#define INDIVIDUAL_AXIS_HOMING_MENU + +// +// SPEAKER/BUZZER +// +// If you have a speaker that can produce tones, enable it here. +// By default Marlin assumes you have a buzzer with a fixed frequency. +// +//#define SPEAKER + +// +// The duration and frequency for the UI feedback sound. +// Set these to 0 to disable audio feedback in the LCD menus. +// +// Note: Test audio output with the G-Code: +// M300 S P +// +//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 +//#define LCD_FEEDBACK_FREQUENCY_HZ 1000 + +// +// CONTROLLER TYPE: Standard +// +// Marlin supports a wide variety of controllers. +// Enable one of the following options to specify your controller. +// + +// +// ULTIMAKER Controller. +// +//#define ULTIMAKERCONTROLLER + +// +// ULTIPANEL as seen on Thingiverse. +// +//#define ULTIPANEL + +// +// PanelOne from T3P3 (via RAMPS 1.4 AUX2/AUX3) +// http://reprap.org/wiki/PanelOne +// +//#define PANEL_ONE + +// +// MaKr3d Makr-Panel with graphic controller and SD support. +// http://reprap.org/wiki/MaKr3d_MaKrPanel +// +//#define MAKRPANEL + +// +// ReprapWorld Graphical LCD +// https://reprapworld.com/?products_details&products_id/1218 +// +//#define REPRAPWORLD_GRAPHICAL_LCD + +// +// Activate one of these if you have a Panucatt Devices +// Viki 2.0 or mini Viki with Graphic LCD +// http://panucatt.com +// +//#define VIKI2 +//#define miniVIKI + +// +// Adafruit ST7565 Full Graphic Controller. +// https://github.com/eboston/Adafruit-ST7565-Full-Graphic-Controller/ +// +//#define ELB_FULL_GRAPHIC_CONTROLLER + +// +// RepRapDiscount Smart Controller. +// http://reprap.org/wiki/RepRapDiscount_Smart_Controller +// +// Note: Usually sold with a white PCB. +// +//#define REPRAP_DISCOUNT_SMART_CONTROLLER + +// +// GADGETS3D G3D LCD/SD Controller +// http://reprap.org/wiki/RAMPS_1.3/1.4_GADGETS3D_Shield_with_Panel +// +// Note: Usually sold with a blue PCB. +// +//#define G3D_PANEL + +// +// RepRapDiscount FULL GRAPHIC Smart Controller +// http://reprap.org/wiki/RepRapDiscount_Full_Graphic_Smart_Controller +// +#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER + +// +// MakerLab Mini Panel with graphic +// controller and SD support - http://reprap.org/wiki/Mini_panel +// +//#define MINIPANEL + +// +// RepRapWorld REPRAPWORLD_KEYPAD v1.1 +// http://reprapworld.com/?products_details&products_id=202&cPath=1591_1626 +// +// REPRAPWORLD_KEYPAD_MOVE_STEP sets how much should the robot move when a key +// is pressed, a value of 10.0 means 10mm per click. +// +//#define REPRAPWORLD_KEYPAD +//#define REPRAPWORLD_KEYPAD_MOVE_STEP 1.0 + +// +// RigidBot Panel V1.0 +// http://www.inventapart.com/ +// +//#define RIGIDBOT_PANEL + +// +// BQ LCD Smart Controller shipped by +// default with the BQ Hephestos 2 and Witbox 2. +// +//#define BQ_LCD_SMART_CONTROLLER + +// +// Cartesio UI +// http://mauk.cc/webshop/cartesio-shop/electronics/user-interface +// +//#define CARTESIO_UI + +// +// ANET_10 Controller supported displays. +// +//#define ANET_KEYPAD_LCD // Requires ADC_KEYPAD_PIN to be assigned to an analog pin. + // This LCD is known to be susceptible to electrical interference + // which scrambles the display. Pressing any button clears it up. +//#define ANET_FULL_GRAPHICS_LCD // Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6 + // A clone of the RepRapDiscount full graphics display but with + // different pins/wiring (see pins_ANET_10.h). + +// +// LCD for Melzi Card with Graphical LCD +// +//#define LCD_FOR_MELZI + +// +// CONTROLLER TYPE: I2C +// +// Note: These controllers require the installation of Arduino's LiquidCrystal_I2C +// library. For more info: https://github.com/kiyoshigawa/LiquidCrystal_I2C +// + +// +// Elefu RA Board Control Panel +// http://www.elefu.com/index.php?route=product/product&product_id=53 +// +//#define RA_CONTROL_PANEL + +// +// Sainsmart YW Robot (LCM1602) LCD Display +// +// Note: This controller requires F.Malpartida's LiquidCrystal_I2C library +// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home +// +//#define LCD_I2C_SAINSMART_YWROBOT + +// +// Generic LCM1602 LCD adapter +// +//#define LCM1602 + +// +// PANELOLU2 LCD with status LEDs, +// separate encoder and click inputs. +// +// Note: This controller requires Arduino's LiquidTWI2 library v1.2.3 or later. +// For more info: https://github.com/lincomatic/LiquidTWI2 +// +// Note: The PANELOLU2 encoder click input can either be directly connected to +// a pin (if BTN_ENC defined to != -1) or read through I2C (when BTN_ENC == -1). +// +//#define LCD_I2C_PANELOLU2 + +// +// Panucatt VIKI LCD with status LEDs, +// integrated click & L/R/U/D buttons, separate encoder inputs. +// +//#define LCD_I2C_VIKI + +// +// SSD1306 OLED full graphics generic display +// +//#define U8GLIB_SSD1306 + +// +// SAV OLEd LCD module support using either SSD1306 or SH1106 based LCD modules +// +//#define SAV_3DGLCD +#if ENABLED(SAV_3DGLCD) + //#define U8GLIB_SSD1306 + #define U8GLIB_SH1106 +#endif + +// +// CONTROLLER TYPE: Shift register panels +// +// 2 wire Non-latching LCD SR from https://goo.gl/aJJ4sH +// LCD configuration: http://reprap.org/wiki/SAV_3D_LCD +// +//#define SAV_3DLCD + +// +// TinyBoy2 128x64 OLED / Encoder Panel +// +//#define OLED_PANEL_TINYBOY2 + +// +// Makeboard 3D Printer Parts 3D Printer Mini Display 1602 Mini Controller +// https://www.aliexpress.com/item/Micromake-Makeboard-3D-Printer-Parts-3D-Printer-Mini-Display-1602-Mini-Controller-Compatible-with-Ramps-1/32765887917.html +// +//#define MAKEBOARD_MINI_2_LINE_DISPLAY_1602 + +// +// MKS MINI12864 with graphic controller and SD support +// http://reprap.org/wiki/MKS_MINI_12864 +// +//#define MKS_MINI_12864 + +// +// Factory display for Creality CR-10 +// https://www.aliexpress.com/item/Universal-LCD-12864-3D-Printer-Display-Screen-With-Encoder-For-CR-10-CR-7-Model/32833148327.html +// +// This is RAMPS-compatible using a single 10-pin connector. +// (For CR-10 owners who want to replace the Melzi Creality board but retain the display) +// +//#define CR10_STOCKDISPLAY + +// +// MKS OLED 1.3" 128 × 64 FULL GRAPHICS CONTROLLER +// http://reprap.org/wiki/MKS_12864OLED +// +// Tiny, but very sharp OLED display +// +//#define MKS_12864OLED + +//============================================================================= +//=============================== Extra Features ============================== +//============================================================================= + +// @section extras + +// Increase the FAN PWM frequency. Removes the PWM noise but increases heating in the FET/Arduino +//#define FAST_PWM_FAN + +// Use software PWM to drive the fan, as for the heaters. This uses a very low frequency +// which is not as annoying as with the hardware PWM. On the other hand, if this frequency +// is too low, you should also increment SOFT_PWM_SCALE. +//#define FAN_SOFT_PWM + +// Incrementing this by 1 will double the software PWM frequency, +// affecting heaters, and the fan if FAN_SOFT_PWM is enabled. +// However, control resolution will be halved for each increment; +// at zero value, there are 128 effective control positions. +#define SOFT_PWM_SCALE 0 + +// If SOFT_PWM_SCALE is set to a value higher than 0, dithering can +// be used to mitigate the associated resolution loss. If enabled, +// some of the PWM cycles are stretched so on average the desired +// duty cycle is attained. +//#define SOFT_PWM_DITHER + +// Temperature status LEDs that display the hotend and bed temperature. +// If all hotends, bed temperature, and target temperature are under 54C +// then the BLUE led is on. Otherwise the RED led is on. (1C hysteresis) +//#define TEMP_STAT_LEDS + +// M240 Triggers a camera by emulating a Canon RC-1 Remote +// Data from: http://www.doc-diy.net/photo/rc-1_hacked/ +//#define PHOTOGRAPH_PIN 23 + +// 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 + +// Support for BlinkM/CyzRgb +//#define BLINKM + +// Support for PCA9632 PWM LED driver +//#define PCA9632 + +/** + * RGB LED / LED Strip Control + * + * Enable support for an RGB LED connected to 5V digital pins, or + * an RGB Strip connected to MOSFETs controlled by digital pins. + * + * 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 overall brightness parameters is also available + * + * *** CAUTION *** + * LED Strips require a MOFSET 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! + * The Neopixel LED is 5V powered, but linear 5V regulator on Arduino + * cannot handle such current, separate 5V power supply must be used + * *** CAUTION *** + * + * LED type. This options are mutualy exclusive. Uncomment only one. + * + */ +//#define RGB_LED +//#define RGBW_LED + +#if ENABLED(RGB_LED) || ENABLED(RGBW_LED) + #define RGB_LED_R_PIN 34 + #define RGB_LED_G_PIN 43 + #define RGB_LED_B_PIN 35 + #define RGB_LED_W_PIN -1 +#endif + +// 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 (definned in Adafruit_NeoPixel.h) + #define NEOPIXEL_PIN 4 // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba) + #define NEOPIXEL_PIXELS 30 // Number of LEDs on strip + #define NEOPIXEL_IS_SEQUENTIAL // Sequent display for temperature change - LED by LED. Comment out for change all LED at time + #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness 0-255 + //#define NEOPIXEL_STARTUP_TEST // Cycle through colors at startup +#endif + +/** + * Printer Event LEDs + * + * During printing, the LEDs will reflect the printer status: + * + * - Gradually change from blue to violet as the heated bed gets to target temp + * - Gradually change from violet to red as the hotend gets to temperature + * - Change to white to illuminate work surface + * - Change to green once print has finished + * - Turn off after the print has finished and the user has pushed a button + */ +#if ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_RGBW_LED) + #define PRINTER_EVENT_LEDS +#endif + +/*********************************************************************\ +* R/C SERVO support +* Sponsored by TrinityLabs, Reworked by codexmas +**********************************************************************/ + +// Number of servos +// +// If you select a configuration below, this will receive a default value and does not need to be set manually +// set it manually if you have more servos than extruders and wish to manually control some +// leaving it undefined or defining as 0 will disable the servo subsystem +// If unsure, leave commented / disabled +// +//#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command + +// Delay (in milliseconds) before the next move will start, to give the servo time to reach its target angle. +// 300ms is a good value but you can try less delay. +// If the servo can't reach the requested position, increase it. +#define SERVO_DELAY { 300 } + +// Servo deactivation +// +// With this option servos are powered only during movement, then turned off to prevent jitter. +//#define DEACTIVATE_SERVOS_AFTER_MOVE + +/** + * Filament Width Sensor + * + * Measures the filament width in real-time and adjusts + * flow rate to compensate for any irregularities. + * + * Also allows the measured filament diameter to set the + * extrusion rate, so the slicer only has to specify the + * volume. + * + * Only a single extruder is supported at this time. + * + * 34 RAMPS_14 : Analog input 5 on the AUX2 connector + * 81 PRINTRBOARD : Analog input 2 on the Exp1 connector (version B,C,D,E) + * 301 RAMBO : Analog input 3 + * + * Note: May require analog pins to be defined for other boards. + */ +//#define FILAMENT_WIDTH_SENSOR + +#define DEFAULT_NOMINAL_FILAMENT_DIA 3.00 // (mm) Diameter of the filament generally used (3.0 or 1.75mm), also used in the slicer. Used to validate sensor reading. + +#if ENABLED(FILAMENT_WIDTH_SENSOR) + #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor (0,1,2,3) + #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber + + #define MEASURED_UPPER_LIMIT 3.30 // (mm) Upper limit used to validate sensor reading + #define MEASURED_LOWER_LIMIT 1.90 // (mm) Lower limit used to validate sensor reading + #define MAX_MEASUREMENT_DELAY 20 // (bytes) Buffer size for stored measurements (1 byte per cm). Must be larger than MEASUREMENT_DELAY_CM. + + #define DEFAULT_MEASURED_FILAMENT_DIA DEFAULT_NOMINAL_FILAMENT_DIA // Set measured to nominal initially + + // Display filament width on the LCD status line. Status messages will expire after 5 seconds. + //#define FILAMENT_LCD_DISPLAY +#endif + +#endif // CONFIGURATION_H diff --git a/trunk/Arduino/Marlin_1.1.6/example_configurations/wt150/Configuration_adv.h b/trunk/Arduino/Marlin_1.1.6/example_configurations/wt150/Configuration_adv.h new file mode 100644 index 00000000..aed0fee4 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/example_configurations/wt150/Configuration_adv.h @@ -0,0 +1,1424 @@ +/** + * 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 . + * + */ + +/** + * Configuration_adv.h + * + * Advanced settings. + * Only change these if you know exactly what you're doing. + * Some of these settings can damage your printer if improperly set! + * + * Basic settings can be found in Configuration.h + * + */ +#ifndef CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H_VERSION 010100 + +// @section temperature + +//=========================================================================== +//=============================Thermal Settings ============================ +//=========================================================================== + +#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 + #endif +#endif + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * The solution: Once the temperature reaches the target, start observing. + * If the temperature stays too far below the target (hysteresis) for too long (period), + * the firmware will halt the machine as a safety precaution. + * + * If you get false positives for "Thermal Runaway" increase THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD + */ +#if ENABLED(THERMAL_PROTECTION_HOTENDS) + #define THERMAL_PROTECTION_PERIOD 40 // Seconds + #define THERMAL_PROTECTION_HYSTERESIS 4 // Degrees Celsius + + /** + * Whenever an M104 or M109 increases the target temperature the firmware will wait for the + * WATCH_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get false positives for "Heating failed" increase WATCH_TEMP_PERIOD and/or decrease WATCH_TEMP_INCREASE + * WATCH_TEMP_INCREASE should not be below 2. + */ + #define WATCH_TEMP_PERIOD 20 // Seconds + #define WATCH_TEMP_INCREASE 2 // Degrees Celsius +#endif + +/** + * Thermal Protection parameters for the bed are just as above for hotends. + */ +#if ENABLED(THERMAL_PROTECTION_BED) + #define THERMAL_PROTECTION_BED_PERIOD 20 // Seconds + #define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius + + /** + * Whenever an M140 or M190 increases the target temperature the firmware will wait for the + * WATCH_BED_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_BED_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get too many "Heating failed" errors, increase WATCH_BED_TEMP_PERIOD and/or decrease + * WATCH_BED_TEMP_INCREASE. (WATCH_BED_TEMP_INCREASE should not be below 2.) + */ + #define WATCH_BED_TEMP_PERIOD 60 // Seconds + #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius +#endif + +#if ENABLED(PIDTEMP) + // this adds an experimental additional term to the heating power, proportional to the extrusion speed. + // if Kc is chosen well, the additional required power due to increased melting should be compensated. + //#define PID_EXTRUSION_SCALING + #if ENABLED(PID_EXTRUSION_SCALING) + #define DEFAULT_Kc (100) //heating power=Kc*(e_speed) + #define LPQ_MAX_LEN 50 + #endif +#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 + */ +#define AUTOTEMP +#if ENABLED(AUTOTEMP) + #define AUTOTEMP_OLDWEIGHT 0.98 +#endif + +// Show Temperature ADC value +// Enable for M105 to include ADC values read from temperature sensors. +//#define SHOW_TEMP_ADC_VALUES + +/** + * High Temperature Thermistor Support + * + * Thermistors able to support high temperature tend to have a hard time getting + * good readings at room and lower temperatures. This means HEATER_X_RAW_LO_TEMP + * will probably be caught when the heating element first turns on during the + * preheating process, which will trigger a min_temp_error as a safety measure + * and force stop everything. + * To circumvent this limitation, we allow for a preheat time (during which, + * min_temp_error won't be triggered) and add a min_temp buffer to handle + * aberrant readings. + * + * If you want to enable this feature for your hotend thermistor(s) + * uncomment and set values > 0 in the constants below + */ + +// The number of consecutive low temperature errors that can occur +// before a min_temp_error is triggered. (Shouldn't be more than 10.) +//#define MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED 0 + +// The number of milliseconds a hotend will preheat before starting to check +// the temperature. This value should NOT be set to the time it takes the +// hot end to reach the target temperature, but the time it takes to reach +// the minimum temperature your thermistor can read. The lower the better/safer. +// This shouldn't need to be more than 30 seconds (30000) +//#define MILLISECONDS_PREHEAT_TIME 0 + +// @section extruder + +// Extruder runout prevention. +// If the machine is idle and the temperature over MINTEMP +// then extrude some filament every couple of SECONDS. +//#define EXTRUDER_RUNOUT_PREVENT +#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_EXTRUDE 5 // mm +#endif + +// @section temperature + +//These defines help to calibrate the AD595 sensor in case you get wrong temperature measurements. +//The measured temperature is defined as "actualTemp = (measuredTemp * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET" +#define TEMP_SENSOR_AD595_OFFSET 0.0 +#define TEMP_SENSOR_AD595_GAIN 1.0 + +/** + * 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. + */ +//#define USE_CONTROLLER_FAN +#if ENABLED(USE_CONTROLLER_FAN) + //#define CONTROLLER_FAN_PIN FAN1_PIN // 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 +#endif + +// When first starting the main fan, run it at full speed for the +// given number of milliseconds. This gets the fan spinning reliably +// before setting a PWM value. (Does not work with software PWM for fan on Sanguinololu) +//#define FAN_KICKSTART_TIME 100 + +// This defines the minimal speed for the main fan, run in PWM mode +// to enable uncomment and set minimal PWM speed for reliable running (1-255) +// if fan speed is [1 - (FAN_MIN_PWM-1)] it is set to FAN_MIN_PWM +//#define FAN_MIN_PWM 50 + +// @section extruder + +/** + * Extruder cooling fans + * + * Extruder auto fans automatically turn on when their extruders' + * temperatures go above EXTRUDER_AUTO_FAN_TEMPERATURE. + * + * Your board's pins file specifies the recommended pins. Override those here + * or set to -1 to disable completely. + * + * Multiple extruders can be assigned to the same pin in which case + * the fan will turn on when any selected extruder is above the threshold. + */ +//#define E0_AUTO_FAN_PIN -1 +#define E1_AUTO_FAN_PIN -1 +#define E2_AUTO_FAN_PIN -1 +#define E3_AUTO_FAN_PIN -1 +#define E4_AUTO_FAN_PIN -1 +#define EXTRUDER_AUTO_FAN_TEMPERATURE 50 +#define EXTRUDER_AUTO_FAN_SPEED 255 // == full speed + +/** + * Part-Cooling Fan Multiplexer + * + * This feature allows you to digitally multiplex the fan output. + * The multiplexer is automatically switched at tool-change. + * Set FANMUX[012]_PINs below for up to 2, 4, or 8 multiplexed fans. + */ +#define FANMUX0_PIN -1 +#define FANMUX1_PIN -1 +#define FANMUX2_PIN -1 + +/** + * M355 Case Light on-off / brightness + */ +//#define CASE_LIGHT_ENABLE +#if ENABLED(CASE_LIGHT_ENABLE) + //#define CASE_LIGHT_PIN 4 // Override the default pin if needed + #define INVERT_CASE_LIGHT false // Set true if Case Light is ON when pin is LOW + #define CASE_LIGHT_DEFAULT_ON true // Set default power-up state on + #define CASE_LIGHT_DEFAULT_BRIGHTNESS 105 // Set default power-up brightness (0-255, requires PWM pin) + //#define MENU_ITEM_CASE_LIGHT // Add a Case Light option to the LCD main menu +#endif + +//=========================================================================== +//============================ Mechanical Settings ========================== +//=========================================================================== + +// @section homing + +// If you want endstops to stay on (by default) even when not homing +// enable this option. Override at any time with M120, M121. +//#define ENDSTOPS_ALWAYS_ON_DEFAULT + +// @section extras + +//#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. + +// Dual X Steppers +// Uncomment this option to drive two X axis motors. +// The next unused E driver will be assigned to the second X stepper. +//#define X_DUAL_STEPPER_DRIVERS +#if ENABLED(X_DUAL_STEPPER_DRIVERS) + // Set true if the two X motors need to rotate in opposite directions + #define INVERT_X2_VS_X_DIR true +#endif + +// Dual Y Steppers +// Uncomment this option to drive two Y axis motors. +// The next unused E driver will be assigned to the second Y stepper. +//#define Y_DUAL_STEPPER_DRIVERS +#if ENABLED(Y_DUAL_STEPPER_DRIVERS) + // Set true if the two Y motors need to rotate in opposite directions + #define INVERT_Y2_VS_Y_DIR true +#endif + +// A single Z stepper driver is usually used to drive 2 stepper motors. +// Uncomment this option to use a separate stepper driver for each Z axis motor. +// The next unused E driver will be assigned to the second Z stepper. +//#define Z_DUAL_STEPPER_DRIVERS + +#if ENABLED(Z_DUAL_STEPPER_DRIVERS) + + // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper. + // That way the machine is capable to align the bed during home, since both Z steppers are homed. + // There is also an implementation of M666 (software endstops adjustment) to this feature. + // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed. + // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2. + // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive. + // Play a little bit with small adjustments (0.5mm) and check the behaviour. + // The M119 (endstops report) will start reporting the Z2 Endstop as well. + + //#define Z_DUAL_ENDSTOPS + + #if ENABLED(Z_DUAL_ENDSTOPS) + #define Z2_USE_ENDSTOP _XMAX_ + #define Z_DUAL_ENDSTOPS_ADJUSTMENT 0 // Use M666 to determine/test this value + #endif + +#endif // Z_DUAL_STEPPER_DRIVERS + +// Enable this for dual x-carriage printers. +// A dual x-carriage design has the advantage that the inactive extruder can be parked which +// prevents hot-end ooze contaminating the print. It also reduces the weight of each x-carriage +// allowing faster printing speeds. Connect your X2 stepper to the first unused E plug. +//#define DUAL_X_CARRIAGE +#if ENABLED(DUAL_X_CARRIAGE) + // Configuration for second X-carriage + // Note: the first x-carriage is defined as the x-carriage which homes to the minimum endstop; + // the second x-carriage always homes to the maximum endstop. + #define X2_MIN_POS 80 // set minimum to ensure second x-carriage doesn't hit the parked first X-carriage + #define X2_MAX_POS 353 // set maximum to the distance between toolheads when both heads are homed + #define X2_HOME_DIR 1 // the second X-carriage always homes to the maximum endstop position + #define X2_HOME_POS X2_MAX_POS // default home position is the maximum carriage position + // However: In this mode the HOTEND_OFFSET_X value for the second extruder provides a software + // override for X2_HOME_POS. This also allow recalibration of the distance between the two endstops + // without modifying the firmware (through the "M218 T1 X???" command). + // Remember: you should set the second extruder x-offset to 0 in your slicer. + + // There are a few selectable movement modes for dual x-carriages using M605 S + // Mode 0 (DXC_FULL_CONTROL_MODE): Full control. The slicer has full control over both x-carriages and can achieve optimal travel results + // as long as it supports dual x-carriages. (M605 S0) + // Mode 1 (DXC_AUTO_PARK_MODE) : Auto-park mode. The firmware will automatically park and unpark the x-carriages on tool changes so + // that additional slicer support is not required. (M605 S1) + // Mode 2 (DXC_DUPLICATION_MODE) : Duplication mode. The firmware will transparently make the second x-carriage and extruder copy all + // actions of the first x-carriage. This allows the printer to print 2 arbitrary items at + // once. (2nd extruder x offset and temp offset are set using: M605 S2 [Xnnn] [Rmmm]) + + // This is the default power-up mode which can be later using M605. + #define DEFAULT_DUAL_X_CARRIAGE_MODE DXC_FULL_CONTROL_MODE + + // Default settings in "Auto-park Mode" + #define TOOLCHANGE_PARK_ZLIFT 0.2 // the distance to raise Z axis when parking an extruder + #define TOOLCHANGE_UNPARK_ZLIFT 1 // the distance to raise Z axis when unparking an extruder + + // Default x offset in duplication mode (typically set to half print bed width) + #define DEFAULT_DUPLICATION_X_OFFSET 100 + +#endif // DUAL_X_CARRIAGE + +// 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. +//#define EXT_SOLENOID + +// @section homing + +//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +#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 this is defined, if both x and y are to be homed, a diagonal move will be performed initially. + +// When G28 is called, this option will make Y home before X +//#define HOME_Y_BEFORE_X + +// @section machine + +#define AXIS_RELATIVE_MODES {false, false, false, false} + +// Allow duplication mode with a basic dual-nozzle extruder +//#define DUAL_NOZZLE_DUPLICATION_MODE + +// By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step. +#define INVERT_X_STEP_PIN false +#define INVERT_Y_STEP_PIN false +#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. +#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_E true + +#define DEFAULT_MINIMUMFEEDRATE 0.0 // minimum feedrate +#define DEFAULT_MINTRAVELFEEDRATE 0.0 + +//#define HOME_AFTER_DEACTIVATE // Require rehoming after steppers are deactivated + +// @section lcd + +#if ENABLED(ULTIPANEL) + #define MANUAL_FEEDRATE {50*60, 50*60, 4*60, 60} // Feedrates for manual moves along X, Y, Z, E from panel + #define ULTIPANEL_FEEDMULTIPLY // Comment to disable setting feedrate multiplier via encoder +#endif + +// @section extras + +// minimum time in microseconds that a movement needs to take if the buffer is emptied. +#define DEFAULT_MINSEGMENTTIME 20000 + +// If defined the movements slow down when the look ahead buffer is only half full +#define SLOWDOWN + +// Frequency limit +// See nophead's blog for more info +// Not working O +//#define XY_FREQUENCY_LIMIT 15 + +// 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 +// if unwanted behavior is observed on a user's machine when running at very slow speeds. +#define MINIMUM_PLANNER_SPEED 0.05 // (mm/sec) + +// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU. +#define MICROSTEP_MODES {16,16,16,16,16} // [1,2,4,8,16] + +/** + * @section stepper motor current + * + * Some boards have a means of setting the stepper motor current via firmware. + * + * The power on motor currents are set by: + * PWM_MOTOR_CURRENT - used by MINIRAMBO & ULTIMAIN_2 + * known compatible chips: A4982 + * DIGIPOT_MOTOR_CURRENT - used by BQ_ZUM_MEGA_3D, RAMBO & SCOOVO_X9H + * known compatible chips: AD5206 + * DAC_MOTOR_CURRENT_DEFAULT - used by PRINTRBOARD_REVF & RIGIDBOARD_V2 + * known compatible chips: MCP4728 + * DIGIPOT_I2C_MOTOR_CURRENTS - used by 5DPRINT, AZTEEG_X3_PRO, MIGHTYBOARD_REVE + * known compatible chips: MCP4451, MCP4018 + * + * Motor currents can also be set by M907 - M910 and by the LCD. + * M907 - applies to all. + * M908 - BQ_ZUM_MEGA_3D, RAMBO, PRINTRBOARD_REVF, RIGIDBOARD_V2 & SCOOVO_X9H + * M909, M910 & LCD - only PRINTRBOARD_REVF & RIGIDBOARD_V2 + */ +//#define PWM_MOTOR_CURRENT { 1300, 1300, 1250 } // Values in milliamps +//#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 + +// Uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +#define DIGIPOT_I2C +#define DIGIPOT_MCP4018 // Requires library from https://github.com/stawel/SlowSoftI2CMaster +#define DIGIPOT_I2C_NUM_CHANNELS 5 // 5DPRINT: 4 AZTEEG_X3_PRO: 8 +// Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS +#define DIGIPOT_I2C_MOTOR_CURRENTS {0.22, 0.22, 0.39, 0.42, 0.42} + +//=========================================================================== +//=============================Additional Features=========================== +//=========================================================================== + +#define ENCODER_RATE_MULTIPLIER // If defined, certain menu edit operations automatically multiply the steps when the encoder is moved quickly +#define ENCODER_10X_STEPS_PER_SEC 75 // If the encoder steps per sec exceeds this value, multiply steps moved x10 to quickly advance the value +#define ENCODER_100X_STEPS_PER_SEC 160 // If the encoder steps per sec exceeds this value, multiply steps moved x100 to really quickly advance the value + +//#define CHDK 4 //Pin for triggering CHDK to take a picture see how to use it here http://captain-slow.dk/2014/03/09/3d-printing-timelapses/ +#define CHDK_DELAY 50 //How long in ms the pin should stay HIGH before going LOW again + +// @section lcd + +// Include a page of printer information in the LCD Main Menu +#define LCD_INFO_MENU + +// Scroll a longer status message into view +//#define STATUS_MESSAGE_SCROLLING + +// On the Info Screen, display XY with one decimal place when possible +//#define LCD_DECIMAL_SMALL_XY + +// The timeout (in ms) to return to the status screen from sub-menus +//#define LCD_TIMEOUT_TO_STATUS 15000 + +#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 + + #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? + #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. + + #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. + // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. + // using: + //#define MENU_ADDAUTOSTART + + /** + * Sort SD file listings in alphabetical order. + * + * With this option enabled, items on SD cards will be sorted + * by name for easier navigation. + * + * By default... + * + * - Use the slowest -but safest- method for sorting. + * - Folders are sorted to the top. + * - The sort key is statically allocated. + * - No added G-code (M34) support. + * - 40 item sorting limit. (Items after the first 40 are unsorted.) + * + * SD sorting uses static allocation (as set by SDSORT_LIMIT), allowing the + * compiler to calculate the worst-case usage and throw an error if the SRAM + * limit is exceeded. + * + * - SDSORT_USES_RAM provides faster sorting via a static directory buffer. + * - SDSORT_USES_STACK does the same, but uses a local stack-based buffer. + * - SDSORT_CACHE_NAMES will retain the sorted file listing in RAM. (Expensive!) + * - SDSORT_DYNAMIC_RAM only uses RAM when the SD menu is visible. (Use with caution!) + */ + //#define SDCARD_SORT_ALPHA + + // SD Card Sorting options + #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_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. + #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! + #endif + + // Show a progress bar on HD44780 LCDs for SD printing + //#define LCD_PROGRESS_BAR + + #if ENABLED(LCD_PROGRESS_BAR) + // Amount of time (ms) to show the bar + #define PROGRESS_BAR_BAR_TIME 2000 + // Amount of time (ms) to show the status message + #define PROGRESS_BAR_MSG_TIME 3000 + // Amount of time (ms) to retain the status message (0=forever) + #define PROGRESS_MSG_EXPIRE 0 + // Enable this to show messages for MSG_TIME then hide them + //#define PROGRESS_MSG_ONCE + // Add a menu item to test the progress bar: + //#define LCD_PROGRESS_BAR_TEST + #endif + + // This allows hosts to request long names for files and folders with M33 + //#define LONG_FILENAME_HOST_SUPPORT + + // This option allows you to abort SD printing when any endstop is triggered. + // This feature must be enabled with "M540 S1" or from the LCD menu. + // To have any effect, endstops must be enabled during SD printing. + //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + +#endif // SDSUPPORT + +/** + * Additional options for Graphical Displays + * + * Use the optimizations here to improve printing performance, + * which can be adversely affected by graphical display drawing, + * especially when doing several short moves, and when printing + * on DELTA and SCARA machines. + * + * Some of these options may result in the display lagging behind + * controller events, as there is a trade-off between reliable + * printing performance versus fast display updates. + */ +#if ENABLED(DOGLCD) + // Enable to save many cycles by drawing a hollow frame on the Info Screen + #define XYZ_HOLLOW_FRAME + + // Enable to save many cycles by drawing a hollow frame on Menu Screens + #define MENU_HOLLOW_FRAME + + // A bigger font is available for edit items. Costs 3120 bytes of PROGMEM. + // 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. + // 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 +#endif // DOGLCD + +// @section safety + +// The hardware watchdog should reset the microcontroller disabling all outputs, +// in case the firmware gets stuck and doesn't do temperature regulation. +#define USE_WATCHDOG + +#if ENABLED(USE_WATCHDOG) + // If you have a watchdog reboot in an ArduinoMega2560 then the device will hang forever, as a watchdog reset will leave the watchdog on. + // The "WATCHDOG_RESET_MANUAL" goes around this by not using the hardware reset. + // However, THIS FEATURE IS UNSAFE!, as it will only work if interrupts are disabled. And the code could hang in an interrupt routine with interrupts disabled. + //#define WATCHDOG_RESET_MANUAL +#endif + +// @section lcd + +/** + * Babystepping enables movement of the axes by tiny increments without changing + * the current position values. This feature is used primarily to adjust the Z + * axis in the first layer of a print in real-time. + * + * Warning: Does not respect endstops! + */ +//#define BABYSTEPPING +#if ENABLED(BABYSTEPPING) + //#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 100 // Babysteps are very small. Increase for faster motion. + //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping + //#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen 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_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor + //#define BABYSTEP_ZPROBE_GFX_REVERSE // Reverses the direction of the CW/CCW indicators +#endif + +// @section extruder + +/** + * Implementation of linear pressure control + * + * Assumption: advance = k * (delta velocity) + * K=0 means advance disabled. + * See Marlin documentation for calibration instructions. + */ +//#define LIN_ADVANCE + +#if ENABLED(LIN_ADVANCE) + #define LIN_ADVANCE_K 75 + + /** + * Some Slicers produce Gcode with randomly jumping extrusion widths occasionally. + * For example within a 0.4mm perimeter it may produce a single segment of 0.05mm width. + * While this is harmless for normal printing (the fluid nature of the filament will + * close this very, very tiny gap), it throws off the LIN_ADVANCE pressure adaption. + * + * For this case LIN_ADVANCE_E_D_RATIO can be used to set the extrusion:distance ratio + * to a fixed value. Note that using a fixed ratio will lead to wrong nozzle pressures + * if the slicer is using variable widths or layer heights within one print! + * + * This option sets the default E:D ratio at startup. Use `M900` to override this value. + * + * Example: `M900 W0.4 H0.2 D1.75`, where: + * - W is the extrusion width in mm + * - H is the layer height in mm + * - D is the filament diameter in mm + * + * Example: `M900 R0.0458` to set the ratio directly. + * + * Set to 0 to auto-detect the ratio based on given Gcode G1 print moves. + * + * Slic3r (including Průša Control) produces Gcode compatible with the automatic mode. + * Cura (as of this writing) may produce Gcode incompatible with the automatic mode. + */ + #define LIN_ADVANCE_E_D_RATIO 0 // The calculated ratio (or 0) according to the formula W * H / ((D / 2) ^ 2 * PI) + // Example: 0.4 * 0.2 / ((1.75 / 2) ^ 2 * PI) = 0.033260135 +#endif + +// @section leveling + +// Default mesh area is an area with an inset margin on the print area. +// Below are the macros that are used to define the borders for the mesh area, +// made available here for specialized needs, ie dual extruder setup. +#if ENABLED(MESH_BED_LEVELING) + #define MESH_MIN_X MESH_INSET + #define MESH_MAX_X (X_BED_SIZE - (MESH_INSET)) + #define MESH_MIN_Y MESH_INSET + #define MESH_MAX_Y (Y_BED_SIZE - (MESH_INSET)) +#elif ENABLED(AUTO_BED_LEVELING_UBL) + #define UBL_MESH_MIN_X UBL_MESH_INSET + #define UBL_MESH_MAX_X (X_BED_SIZE - (UBL_MESH_INSET)) + #define UBL_MESH_MIN_Y UBL_MESH_INSET + #define UBL_MESH_MAX_Y (Y_BED_SIZE - (UBL_MESH_INSET)) + + // If this is defined, the currently active mesh will be saved in the + // current slot on M500. + #define UBL_SAVE_ACTIVE_ON_M500 +#endif + +// @section extras + +// +// G2/G3 Arc Support +// +#define ARC_SUPPORT // Disable this feature to save ~3226 bytes +#if ENABLED(ARC_SUPPORT) + #define MM_PER_ARC_SEGMENT 1 // Length of each arc segment + #define N_ARC_CORRECTION 25 // Number of intertpolated 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 +#endif + +// Support for G5 with XYZE destination and IJPQ offsets. Requires ~2666 bytes. +//#define BEZIER_CURVE_SUPPORT + +// G38.2 and G38.3 Probe Target +// Enable PROBE_DOUBLE_TOUCH if you want G38 to double touch +//#define G38_PROBE_TARGET +#if ENABLED(G38_PROBE_TARGET) + #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) +#endif + +// Moves (or segments) with fewer steps than this will be joined with the next move +#define MIN_STEPS_PER_SEGMENT 6 + +// The minimum pulse width (in µs) for stepping a stepper. +// Set this if you find stepping unreliable, or if using a very fast CPU. +#define MINIMUM_STEPPER_PULSE 0 // (µs) The smallest stepper pulse allowed + +// @section temperature + +// Control heater 0 and heater 1 in parallel. +//#define HEATERS_PARALLEL + +//=========================================================================== +//================================= Buffers ================================= +//=========================================================================== + +// @section hidden + +// 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, i.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 +#else + #define BLOCK_BUFFER_SIZE 16 // maximize block buffer +#endif + +// @section serial + +// The ASCII buffer for serial input +#define MAX_CMD_SIZE 96 +#define BUFSIZE 4 + +// Transmission to Host Buffer Size +// To save 386 bytes of PROGMEM (and TX_BUFFER_SIZE+3 bytes of RAM) set to 0. +// To buffer a simple "ok" you need 4 bytes. +// For ADVANCED_OK (M105) you need 32 bytes. +// For debug-echo: 128 bytes for the optimal speed. +// Other output doesn't need to be that speedy. +// :[0, 2, 4, 8, 16, 32, 64, 128, 256] +#define TX_BUFFER_SIZE 0 + +// Host Receive Buffer Size +// Without XON/XOFF flow control (see SERIAL_XON_XOFF below) 32 bytes should be enough. +// To use flow control, set this buffer size to at least 1024 bytes. +// :[0, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048] +//#define RX_BUFFER_SIZE 1024 + +#if RX_BUFFER_SIZE >= 1024 + // Enable to have the controller send XON/XOFF control characters to + // the host to signal the RX buffer is becoming full. + //#define SERIAL_XON_XOFF +#endif + +#if ENABLED(SDSUPPORT) + // Enable this option to collect and display the maximum + // RX queue usage after transferring a file to SD. + //#define SERIAL_STATS_MAX_RX_QUEUED + + // Enable this option to collect and display the number + // of dropped bytes after a file transfer to SD. + //#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! +//#define EMERGENCY_PARSER + +// Bad Serial-connections can miss a received command by sending an 'ok' +// Therefore some clients abort after 30 seconds in a timeout. +// Some other clients start sending commands while receiving a 'wait'. +// This "wait" is only sent when the buffer is empty. 1 second is a good value here. +//#define NO_TIMEOUTS 1000 // Milliseconds + +// Some clients will have this feature soon. This could make the NO_TIMEOUTS unnecessary. +//#define ADVANCED_OK + +// @section extras + +/** + * Firmware-based and LCD-controlled retract + * + * Add G10 / G11 commands for automatic firmware-based retract / recover. + * Use M207 and M208 to define parameters for retract / recover. + * + * Use M209 to enable or disable auto-retract. + * With auto-retract enabled, all G1 E moves within the set range + * will be converted to firmware-based retract/recover moves. + * + * Be sure to turn off auto-retract during filament change. + * + * Note that M207 / M208 / M209 settings are saved to EEPROM. + * + */ +//#define FWRETRACT // ONLY PARTIALLY TESTED +#if ENABLED(FWRETRACT) + #define MIN_AUTORETRACT 0.1 // When auto-retract is on, convert E moves of this length and over + #define MAX_AUTORETRACT 10.0 // Upper limit for auto-retract conversion + #define RETRACT_LENGTH 3 // Default retract length (positive mm) + #define RETRACT_LENGTH_SWAP 13 // Default swap retract length (positive mm), for extruder change + #define RETRACT_FEEDRATE 45 // Default feedrate for retracting (mm/s) + #define RETRACT_ZLIFT 0 // Default retract Z-lift + #define RETRACT_RECOVER_LENGTH 0 // Default additional recover length (mm, added to retract length when recovering) + #define RETRACT_RECOVER_LENGTH_SWAP 0 // Default additional swap recover length (mm, added to retract length when recovering from extruder change) + #define RETRACT_RECOVER_FEEDRATE 8 // Default feedrate for recovering from retraction (mm/s) + #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // Default feedrate for recovering from swap retraction (mm/s) +#endif + +/** + * Advanced Pause + * Experimental feature for filament change support and for parking the nozzle when paused. + * Adds the GCode M600 for initiating filament change. + * If PARK_HEAD_ON_PAUSE enabled, adds the GCode M125 to pause printing and park the nozzle. + * + * Requires an LCD display. + * This feature is required for the default FILAMENT_RUNOUT_SCRIPT. + */ +//#define ADVANCED_PAUSE_FEATURE +#if ENABLED(ADVANCED_PAUSE_FEATURE) + #define PAUSE_PARK_X_POS 3 // X position of hotend + #define PAUSE_PARK_Y_POS 3 // Y position of hotend + #define PAUSE_PARK_Z_ADD 10 // Z addition of hotend (lift) + #define PAUSE_PARK_XY_FEEDRATE 100 // X and Y axes feedrate in mm/s (also used for delta printers Z axis) + #define PAUSE_PARK_Z_FEEDRATE 5 // Z axis feedrate in mm/s (not used for delta printers) + #define PAUSE_PARK_RETRACT_FEEDRATE 60 // Initial retract feedrate in mm/s + #define PAUSE_PARK_RETRACT_LENGTH 2 // Initial retract in mm + // It is a short retract used immediately after print interrupt before move to filament exchange position + #define FILAMENT_CHANGE_UNLOAD_FEEDRATE 10 // Unload filament feedrate in mm/s - filament unloading can be fast + #define FILAMENT_CHANGE_UNLOAD_LENGTH 100 // Unload filament length from hotend in mm + // Longer length for bowden printers to unload filament from whole bowden tube, + // shorter length for printers without bowden to unload filament from extruder only, + // 0 to disable unloading for manual unloading + #define FILAMENT_CHANGE_LOAD_FEEDRATE 6 // Load filament feedrate in mm/s - filament loading into the bowden tube can be fast + #define FILAMENT_CHANGE_LOAD_LENGTH 0 // Load filament length over hotend in mm + // Longer length for bowden printers to fast load filament into whole bowden tube over the hotend, + // Short or zero length for printers without bowden where loading is not used + #define ADVANCED_PAUSE_EXTRUDE_FEEDRATE 3 // Extrude filament feedrate in mm/s - must be slower than load feedrate + #define ADVANCED_PAUSE_EXTRUDE_LENGTH 50 // Extrude filament length in mm after filament is loaded over the hotend, + // 0 to disable for manual extrusion + // Filament can be extruded repeatedly from the filament exchange menu to fill the hotend, + // or until outcoming filament color is not clear for filament color change + #define PAUSE_PARK_NOZZLE_TIMEOUT 45 // Turn off nozzle if user doesn't change filament within this time limit in seconds + #define FILAMENT_CHANGE_NUMBER_OF_ALERT_BEEPS 5 // Number of alert beeps before printer goes quiet + #define PAUSE_PARK_NO_STEPPER_TIMEOUT // Enable to have stepper motors hold position during filament change + // even if it takes longer than DEFAULT_STEPPER_DEACTIVE_TIME. + //#define PARK_HEAD_ON_PAUSE // Go to filament change position on pause, return to print position on resume + //#define HOME_BEFORE_FILAMENT_CHANGE // Ensure homing has been completed prior to parking for filament change +#endif + +// @section tmc + +/** + * Enable this section if you have TMC26X motor drivers. + * You will need to import the TMC26XStepper library into the Arduino IDE for this + * (https://github.com/trinamic/TMC26XStepper.git) + */ +//#define HAVE_TMCDRIVER + +#if ENABLED(HAVE_TMCDRIVER) + + //#define X_IS_TMC + //#define X2_IS_TMC + //#define Y_IS_TMC + //#define Y2_IS_TMC + //#define Z_IS_TMC + //#define Z2_IS_TMC + //#define E0_IS_TMC + //#define E1_IS_TMC + //#define E2_IS_TMC + //#define E3_IS_TMC + //#define E4_IS_TMC + + #define X_MAX_CURRENT 1000 // in mA + #define X_SENSE_RESISTOR 91 // in mOhms + #define X_MICROSTEPS 16 // number of microsteps + + #define X2_MAX_CURRENT 1000 + #define X2_SENSE_RESISTOR 91 + #define X2_MICROSTEPS 16 + + #define Y_MAX_CURRENT 1000 + #define Y_SENSE_RESISTOR 91 + #define Y_MICROSTEPS 16 + + #define Y2_MAX_CURRENT 1000 + #define Y2_SENSE_RESISTOR 91 + #define Y2_MICROSTEPS 16 + + #define Z_MAX_CURRENT 1000 + #define Z_SENSE_RESISTOR 91 + #define Z_MICROSTEPS 16 + + #define Z2_MAX_CURRENT 1000 + #define Z2_SENSE_RESISTOR 91 + #define Z2_MICROSTEPS 16 + + #define E0_MAX_CURRENT 1000 + #define E0_SENSE_RESISTOR 91 + #define E0_MICROSTEPS 16 + + #define E1_MAX_CURRENT 1000 + #define E1_SENSE_RESISTOR 91 + #define E1_MICROSTEPS 16 + + #define E2_MAX_CURRENT 1000 + #define E2_SENSE_RESISTOR 91 + #define E2_MICROSTEPS 16 + + #define E3_MAX_CURRENT 1000 + #define E3_SENSE_RESISTOR 91 + #define E3_MICROSTEPS 16 + + #define E4_MAX_CURRENT 1000 + #define E4_SENSE_RESISTOR 91 + #define E4_MICROSTEPS 16 + +#endif + +// @section TMC2130 + +/** + * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. + * + * You'll also need the TMC2130Stepper Arduino library + * (https://github.com/teemuatlut/TMC2130Stepper). + * + * To use TMC2130 stepper drivers in SPI mode connect your SPI2130 pins to + * the hardware SPI interface on your board and define the required CS pins + * in your `pins_MYBOARD.h` file. (e.g., RAMPS 1.4 uses AUX3 pins `X_CS_PIN 53`, `Y_CS_PIN 49`, etc.). + */ +//#define HAVE_TMC2130 + +#if ENABLED(HAVE_TMC2130) + + // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY + //#define X_IS_TMC2130 + //#define X2_IS_TMC2130 + //#define Y_IS_TMC2130 + //#define Y2_IS_TMC2130 + //#define Z_IS_TMC2130 + //#define Z2_IS_TMC2130 + //#define E0_IS_TMC2130 + //#define E1_IS_TMC2130 + //#define E2_IS_TMC2130 + //#define E3_IS_TMC2130 + //#define E4_IS_TMC2130 + + /** + * Stepper driver settings + */ + + #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 + #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current + #define INTERPOLATE 1 // Interpolate X/Y/Z_MICROSTEPS to 256 + + #define X_CURRENT 1000 // rms current in mA. Multiply by 1.41 for peak current. + #define X_MICROSTEPS 16 // 0..256 + + #define Y_CURRENT 1000 + #define Y_MICROSTEPS 16 + + #define Z_CURRENT 1000 + #define Z_MICROSTEPS 16 + + //#define X2_CURRENT 1000 + //#define X2_MICROSTEPS 16 + + //#define Y2_CURRENT 1000 + //#define Y2_MICROSTEPS 16 + + //#define Z2_CURRENT 1000 + //#define Z2_MICROSTEPS 16 + + //#define E0_CURRENT 1000 + //#define E0_MICROSTEPS 16 + + //#define E1_CURRENT 1000 + //#define E1_MICROSTEPS 16 + + //#define E2_CURRENT 1000 + //#define E2_MICROSTEPS 16 + + //#define E3_CURRENT 1000 + //#define E3_MICROSTEPS 16 + + //#define E4_CURRENT 1000 + //#define E4_MICROSTEPS 16 + + /** + * Use Trinamic's ultra quiet stepping mode. + * When disabled, Marlin will use spreadCycle stepping mode. + */ + #define STEALTHCHOP + + /** + * Let Marlin automatically control stepper current. + * This is still an experimental feature. + * Increase current every 5s by CURRENT_STEP until stepper temperature prewarn gets triggered, + * then decrease current by CURRENT_STEP until temperature prewarn is cleared. + * Adjusting starts from X/Y/Z/E_CURRENT but will not increase over AUTO_ADJUST_MAX + * 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. + * M906 S1 - Start adjusting current + * M906 S0 - Stop adjusting current + * M911 - Report stepper driver overtemperature pre-warn condition. + * M912 - Clear stepper driver overtemperature pre-warn condition flag. + */ + //#define AUTOMATIC_CURRENT_CONTROL + + #if ENABLED(AUTOMATIC_CURRENT_CONTROL) + #define CURRENT_STEP 50 // [mA] + #define AUTO_ADJUST_MAX 1300 // [mA], 1300mA_rms = 1840mA_peak + #define REPORT_CURRENT_CHANGE + #endif + + /** + * The driver will switch to spreadCycle when stepper speed is over HYBRID_THRESHOLD. + * This mode allows for faster movements at the expense of higher noise levels. + * STEALTHCHOP needs to be enabled. + * M913 X/Y/Z/E to live tune the setting + */ + //#define HYBRID_THRESHOLD + + #define X_HYBRID_THRESHOLD 100 // [mm/s] + #define X2_HYBRID_THRESHOLD 100 + #define Y_HYBRID_THRESHOLD 100 + #define Y2_HYBRID_THRESHOLD 100 + #define Z_HYBRID_THRESHOLD 4 + #define Z2_HYBRID_THRESHOLD 4 + #define E0_HYBRID_THRESHOLD 30 + #define E1_HYBRID_THRESHOLD 30 + #define E2_HYBRID_THRESHOLD 30 + #define E3_HYBRID_THRESHOLD 30 + #define E4_HYBRID_THRESHOLD 30 + + /** + * Use stallGuard2 to sense an obstacle and trigger an endstop. + * You need to place a wire from the driver's DIAG1 pin to the X/Y endstop pin. + * If used along with STEALTHCHOP, the movement will be louder when homing. This is normal. + * + * X/Y_HOMING_SENSITIVITY is used for tuning the trigger sensitivity. + * Higher values make the system LESS sensitive. + * Lower value make the system MORE sensitive. + * Too low values can lead to false positives, while too high values will collide the axis without triggering. + * It is advised to set X/Y_HOME_BUMP_MM to 0. + * M914 X/Y to live tune the setting + */ + //#define SENSORLESS_HOMING + + #if ENABLED(SENSORLESS_HOMING) + #define X_HOMING_SENSITIVITY 19 + #define Y_HOMING_SENSITIVITY 19 + #endif + + /** + * You can set your own advanced settings by filling in predefined functions. + * A list of available functions can be found on the library github page + * https://github.com/teemuatlut/TMC2130Stepper + * + * Example: + * #define TMC2130_ADV() { \ + * stepperX.diag0_temp_prewarn(1); \ + * stepperX.interpolate(0); \ + * } + */ + #define TMC2130_ADV() { } + +#endif // HAVE_TMC2130 + +// @section L6470 + +/** + * Enable this section if you have L6470 motor drivers. + * You need to import the L6470 library into the Arduino IDE for this. + * (https://github.com/ameyer/Arduino-L6470) + */ + +//#define HAVE_L6470DRIVER +#if ENABLED(HAVE_L6470DRIVER) + + //#define X_IS_L6470 + //#define X2_IS_L6470 + //#define Y_IS_L6470 + //#define Y2_IS_L6470 + //#define Z_IS_L6470 + //#define Z2_IS_L6470 + //#define E0_IS_L6470 + //#define E1_IS_L6470 + //#define E2_IS_L6470 + //#define E3_IS_L6470 + //#define E4_IS_L6470 + + #define X_MICROSTEPS 16 // number of microsteps + #define X_K_VAL 50 // 0 - 255, Higher values, are higher power. Be careful not to go too high + #define X_OVERCURRENT 2000 // maxc current in mA. If the current goes over this value, the driver will switch off + #define X_STALLCURRENT 1500 // current in mA where the driver will detect a stall + + #define X2_MICROSTEPS 16 + #define X2_K_VAL 50 + #define X2_OVERCURRENT 2000 + #define X2_STALLCURRENT 1500 + + #define Y_MICROSTEPS 16 + #define Y_K_VAL 50 + #define Y_OVERCURRENT 2000 + #define Y_STALLCURRENT 1500 + + #define Y2_MICROSTEPS 16 + #define Y2_K_VAL 50 + #define Y2_OVERCURRENT 2000 + #define Y2_STALLCURRENT 1500 + + #define Z_MICROSTEPS 16 + #define Z_K_VAL 50 + #define Z_OVERCURRENT 2000 + #define Z_STALLCURRENT 1500 + + #define Z2_MICROSTEPS 16 + #define Z2_K_VAL 50 + #define Z2_OVERCURRENT 2000 + #define Z2_STALLCURRENT 1500 + + #define E0_MICROSTEPS 16 + #define E0_K_VAL 50 + #define E0_OVERCURRENT 2000 + #define E0_STALLCURRENT 1500 + + #define E1_MICROSTEPS 16 + #define E1_K_VAL 50 + #define E1_OVERCURRENT 2000 + #define E1_STALLCURRENT 1500 + + #define E2_MICROSTEPS 16 + #define E2_K_VAL 50 + #define E2_OVERCURRENT 2000 + #define E2_STALLCURRENT 1500 + + #define E3_MICROSTEPS 16 + #define E3_K_VAL 50 + #define E3_OVERCURRENT 2000 + #define E3_STALLCURRENT 1500 + + #define E4_MICROSTEPS 16 + #define E4_K_VAL 50 + #define E4_OVERCURRENT 2000 + #define E4_STALLCURRENT 1500 + +#endif + +/** + * TWI/I2C BUS + * + * This feature is an EXPERIMENTAL feature so it shall not be used on production + * machines. Enabling this will allow you to send and receive I2C data from slave + * devices on the bus. + * + * ; Example #1 + * ; This macro send the string "Marlin" to the slave device with address 0x63 (99) + * ; It uses multiple M260 commands with one B arg + * M260 A99 ; Target slave address + * M260 B77 ; M + * M260 B97 ; a + * M260 B114 ; r + * M260 B108 ; l + * M260 B105 ; i + * M260 B110 ; n + * M260 S1 ; Send the current buffer + * + * ; Example #2 + * ; Request 6 bytes from slave device with address 0x63 (99) + * M261 A99 B5 + * + * ; Example #3 + * ; Example serial output of a M261 request + * echo:i2c-reply: from:99 bytes:5 data:hello + */ + +// @section i2cbus + +//#define EXPERIMENTAL_I2CBUS +#define I2C_SLAVE_ADDRESS 0 // Set a value from 8 to 127 to act as a slave + +// @section extras + +/** + * Spindle & Laser control + * + * Add the M3, M4, and M5 commands to turn the spindle/laser on and off, and + * to set spindle speed, spindle direction, and laser power. + * + * SuperPid is a router/spindle speed controller used in the CNC milling community. + * Marlin can be used to turn the spindle on and off. It can also be used to set + * the spindle speed from 5,000 to 30,000 RPM. + * + * 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. + */ +//#define SPINDLE_LASER_ENABLE +#if ENABLED(SPINDLE_LASER_ENABLE) + + #define SPINDLE_LASER_ENABLE_INVERT false // set to "true" if the on/off function is reversed + #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 // delay in milliseconds to allow the spindle/laser to come up to speed/power + #define SPINDLE_LASER_POWERDOWN_DELAY 5000 // delay in milliseconds to allow the spindle to stop + #define SPINDLE_DIR_CHANGE true // set to true if your spindle controller supports changing spindle direction + #define SPINDLE_INVERT_DIR false + #define SPINDLE_STOP_ON_DIR_CHANGE true // set to true if Marlin should stop the spindle before changing rotation direction + + /** + * The M3 & M4 commands use the following equation to convert PWM duty cycle to speed/power + * + * SPEED/POWER = PWM duty cycle * SPEED_POWER_SLOPE + SPEED_POWER_INTERCEPT + * where PWM duty cycle varies from 0 to 255 + * + * set the following for your controller (ALL MUST BE SET) + */ + + #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_SLOPE 0.3922 + //#define SPEED_POWER_INTERCEPT 0 + //#define SPEED_POWER_MIN 10 + //#define SPEED_POWER_MAX 100 // 0-100% +#endif + +/** + * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins + */ +//#define PINS_DEBUGGING + +/** + * Auto-report temperatures with M155 S + */ +#define AUTO_REPORT_TEMPERATURES + +/** + * Include capabilities in M115 output + */ +#define EXTENDED_CAPABILITIES_REPORT + +/** + * Volumetric extrusion default state + * 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. + */ +//#define VOLUMETRIC_DEFAULT_ON + +/** + * Enable this option for a leaner build of Marlin that removes all + * workspace offsets, simplifying coordinate transformations, leveling, etc. + * + * - M206 and M428 are disabled. + * - G92 will revert to its behavior from Marlin 1.0. + */ +//#define NO_WORKSPACE_OFFSETS + +/** + * 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. + * + * For clients that use a fixed-width font (like OctoPrint), leave this set to 1.0. + * Otherwise, adjust according to your client and font. + */ +#define PROPORTIONAL_FONT_RATIO 1.0 + +/** + * Spend 28 bytes of SRAM to optimize the GCode parser + */ +#define FASTER_GCODE_PARSER + +/** + * User-defined menu items that execute custom GCode + */ +//#define CUSTOM_USER_MENUS +#if ENABLED(CUSTOM_USER_MENUS) + #define USER_SCRIPT_DONE "M117 User Script Done" + #define USER_SCRIPT_AUDIBLE_FEEDBACK + //#define USER_SCRIPT_RETURN // Return to status screen after a script + + #define USER_DESC_1 "Home & UBL Info" + #define USER_GCODE_1 "G28\nG29 W" + + #define USER_DESC_2 "Preheat for PLA" + #define USER_GCODE_2 "M140 S" STRINGIFY(PREHEAT_1_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND) + + #define USER_DESC_3 "Preheat for ABS" + #define USER_GCODE_3 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND) + + #define USER_DESC_4 "Heat Bed/Home/Level" + #define USER_GCODE_4 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nG28\nG29" + + #define USER_DESC_5 "Home & Info" + #define USER_GCODE_5 "G28\nM503" +#endif + +/** + * Specify an action command to send to the host when the printer is killed. + * Will be sent in the form '//action:ACTION_ON_KILL', e.g. '//action:poweroff'. + * The host must be configured to handle the action command. + */ +//#define ACTION_ON_KILL "poweroff" + +//=========================================================================== +//====================== I2C Position Encoder Settings ====================== +//=========================================================================== + +/** + * I2C position encoders for closed loop control. + * Developed by Chris Barr at Aus3D. + * + * Wiki: http://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/ + * + * Reilabuild encoders have been modified to improve reliability. + */ + +//#define I2C_POSITION_ENCODERS +#if ENABLED(I2C_POSITION_ENCODERS) + + #define I2CPE_ENCODER_CNT 1 // The number of encoders installed; max of 5 + // encoders supported currently. + + #define I2CPE_ENC_1_ADDR I2CPE_PRESET_ADDR_X // I2C address of the encoder. 30-200. + #define I2CPE_ENC_1_AXIS X_AXIS // Axis the encoder module is installed on. _AXIS. + #define I2CPE_ENC_1_TYPE I2CPE_ENC_TYPE_LINEAR // Type of encoder: I2CPE_ENC_TYPE_LINEAR -or- + // I2CPE_ENC_TYPE_ROTARY. + #define I2CPE_ENC_1_TICKS_UNIT 2048 // 1024 for magnetic strips with 2mm poles; 2048 for + // 1mm poles. For linear encoders this is ticks / mm, + // for rotary encoders this is ticks / revolution. + //#define I2CPE_ENC_1_TICKS_REV (16 * 200) // Only needed for rotary encoders; number of stepper + // steps per full revolution (motor steps/rev * microstepping) + //#define I2CPE_ENC_1_INVERT // Invert the direction of axis travel. + #define I2CPE_ENC_1_EC_METHOD I2CPE_ECM_NONE // Type of error error correction. + #define I2CPE_ENC_1_EC_THRESH 0.10 // Threshold size for error (in mm) above which the + // printer will attempt to correct the error; errors + // smaller than this are ignored to minimize effects of + // measurement noise / latency (filter). + + #define I2CPE_ENC_2_ADDR I2CPE_PRESET_ADDR_Y // Same as above, but for encoder 2. + #define I2CPE_ENC_2_AXIS Y_AXIS + #define I2CPE_ENC_2_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_ENC_2_TICKS_UNIT 2048 + //#define I2CPE_ENC_2_TICKS_REV (16 * 200) + //#define I2CPE_ENC_2_INVERT + #define I2CPE_ENC_2_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_ENC_2_EC_THRESH 0.10 + + #define I2CPE_ENC_3_ADDR I2CPE_PRESET_ADDR_Z // Encoder 3. Add additional configuration options + #define I2CPE_ENC_3_AXIS Z_AXIS // as above, or use defaults below. + + #define I2CPE_ENC_4_ADDR I2CPE_PRESET_ADDR_E // Encoder 4. + #define I2CPE_ENC_4_AXIS E_AXIS + + #define I2CPE_ENC_5_ADDR 34 // Encoder 5. + #define I2CPE_ENC_5_AXIS E_AXIS + + // Default settings for encoders which are enabled, but without settings configured above. + #define I2CPE_DEF_TYPE I2CPE_ENC_TYPE_LINEAR + #define I2CPE_DEF_ENC_TICKS_UNIT 2048 + #define I2CPE_DEF_TICKS_REV (16 * 200) + #define I2CPE_DEF_EC_METHOD I2CPE_ECM_NONE + #define I2CPE_DEF_EC_THRESH 0.1 + + //#define I2CPE_ERR_THRESH_ABORT 100.0 // Threshold size for error (in mm) error on any given + // axis after which the printer will abort. Comment out to + // disable abort behaviour. + + #define I2CPE_TIME_TRUSTED 10000 // After an encoder fault, there must be no further fault + // for this amount of time (in ms) before the encoder + // is trusted again. + + /** + * Position is checked every time a new command is executed from the buffer but during long moves, + * this setting determines the minimum update time between checks. A value of 100 works well with + * error rolling average when attempting to correct only for skips and not for vibration. + */ + #define I2CPE_MIN_UPD_TIME_MS 100 // Minimum time in miliseconds between encoder checks. + + // Use a rolling average to identify persistant errors that indicate skips, as opposed to vibration and noise. + #define I2CPE_ERR_ROLLING_AVERAGE + +#endif // I2C_POSITION_ENCODERS + +/** + * MAX7219 Debug Matrix + * + * Add support for a low-cost 8x8 LED Matrix based on the Max7219 chip, which can be used as a status + * display. Requires 3 signal wires. Some useful debug options are included to demonstrate its usage. + * + * Fully assembled MAX7219 boards can be found on the internet for under $2(US). + * For example, see https://www.ebay.com/sch/i.html?_nkw=332349290049 + */ +//#define MAX7219_DEBUG +#if ENABLED(MAX7219_DEBUG) + #define MAX7219_CLK_PIN 64 // 77 on Re-ARM // Configuration of the 3 pins to control the display + #define MAX7219_DIN_PIN 57 // 78 on Re-ARM + #define MAX7219_LOAD_PIN 44 // 79 on Re-ARM + + /** + * Sample debug features + * If you add more debug displays, be careful to avoid conflicts! + */ + #define MAX7219_DEBUG_PRINTER_ALIVE // Blink corner LED of 8x8 matrix to show that the firmware is functioning + #define MAX7219_DEBUG_STEPPER_HEAD 3 // Show the stepper queue head position on this and the next LED matrix row + #define MAX7219_DEBUG_STEPPER_TAIL 5 // Show the stepper queue tail position on this and the next LED matrix row + + #define MAX7219_DEBUG_STEPPER_QUEUE 0 // Show the current stepper queue depth on this and the next LED matrix row + // If you experience stuttering, reboots, etc. this option can reveal how + // tweaks made to the configuration are affecting the printer in real-time. +#endif + +#endif // CONFIGURATION_ADV_H diff --git a/trunk/Arduino/Marlin_1.1.6/fastio.h b/trunk/Arduino/Marlin_1.1.6/fastio.h new file mode 100644 index 00000000..d5ae8f2c --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/fastio.h @@ -0,0 +1,320 @@ +/** + * 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 . + * + */ + +/** + * Fast I/O Routines + * Use direct port manipulation to save scads of processor time. + * Contributed by Triffid_Hunter. Modified by Kliment and the Marlin team. + */ + +#ifndef _FASTIO_ARDUINO_H +#define _FASTIO_ARDUINO_H + +#include +#include "macros.h" + +#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__)) + + +/** + * Include Ports and Functions + */ +#if AVR_ATmega328_FAMILY + #include "fastio_168.h" +#elif AVR_ATmega1284_FAMILY + #include "fastio_644.h" +#elif AVR_ATmega2560_FAMILY + #include "fastio_1280.h" +#elif AVR_AT90USB1286_FAMILY + #include "fastio_AT90USB.h" +#elif AVR_ATmega2561_FAMILY + #include "fastio_1281.h" +#else + #error "Pins for this chip not defined in Arduino.h! If you have a working pins definition, please contribute!" +#endif + +#ifndef _BV + #define _BV(PIN) (1UL << PIN) +#endif + +/** + * Magic I/O routines + * + * 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 + */ + +#define _READ(IO) ((bool)(DIO ## IO ## _RPORT & _BV(DIO ## IO ## _PIN))) + +// On some boards pins > 0x100 are used. These are not converted to atomic actions. A critical section is needed. + +#define _WRITE_NC(IO, v) do { if (v) {DIO ## IO ## _WPORT |= _BV(DIO ## IO ## _PIN); } else {DIO ## IO ## _WPORT &= ~_BV(DIO ## IO ## _PIN); }; } while (0) + +#define _WRITE_C(IO, v) do { if (v) { \ + CRITICAL_SECTION_START; \ + {DIO ## IO ## _WPORT |= _BV(DIO ## IO ## _PIN); } \ + CRITICAL_SECTION_END; \ + } \ + else { \ + CRITICAL_SECTION_START; \ + {DIO ## IO ## _WPORT &= ~_BV(DIO ## IO ## _PIN); } \ + CRITICAL_SECTION_END; \ + } \ + } \ + while (0) + +#define _WRITE(IO, v) do { if (&(DIO ## IO ## _RPORT) >= (uint8_t *)0x100) {_WRITE_C(IO, v); } else {_WRITE_NC(IO, v); }; } while (0) + +#define _TOGGLE(IO) do {DIO ## IO ## _RPORT ^= _BV(DIO ## IO ## _PIN); } while (0) + +#define _SET_INPUT(IO) do {DIO ## IO ## _DDR &= ~_BV(DIO ## IO ## _PIN); } while (0) +#define _SET_OUTPUT(IO) do {DIO ## IO ## _DDR |= _BV(DIO ## IO ## _PIN); } while (0) + +#define _GET_INPUT(IO) ((DIO ## IO ## _DDR & _BV(DIO ## IO ## _PIN)) == 0) +#define _GET_OUTPUT(IO) ((DIO ## IO ## _DDR & _BV(DIO ## IO ## _PIN)) != 0) +#define _GET_TIMER(IO) (DIO ## IO ## _PWM) + +#define READ(IO) _READ(IO) +#define WRITE(IO,V) _WRITE(IO,V) +#define TOGGLE(IO) _TOGGLE(IO) + +#define SET_INPUT(IO) _SET_INPUT(IO) +#define SET_INPUT_PULLUP(IO) do{ _SET_INPUT(IO); _WRITE(IO, HIGH); }while(0) +#define SET_OUTPUT(IO) _SET_OUTPUT(IO) + +#define GET_INPUT(IO) _GET_INPUT(IO) +#define GET_OUTPUT(IO) _GET_OUTPUT(IO) +#define GET_TIMER(IO) _GET_TIMER(IO) + +#define OUT_WRITE(IO, v) do{ SET_OUTPUT(IO); WRITE(IO, v); }while(0) + +/** + * Timer and Interrupt Control + */ + +// Waveform Generation Modes +typedef enum { + WGM_NORMAL, // 0 + WGM_PWM_PC_8, // 1 + WGM_PWM_PC_9, // 2 + WGM_PWM_PC_10, // 3 + WGM_CTC_OCRnA, // 4 COM OCnx + WGM_FAST_PWM_8, // 5 + WGM_FAST_PWM_9, // 6 + WGM_FAST_PWM_10, // 7 + WGM_PWM_PC_FC_ICRn, // 8 + WGM_PWM_PC_FC_OCRnA, // 9 COM OCnA + WGM_PWM_PC_ICRn, // 10 + WGM_PWM_PC_OCRnA, // 11 COM OCnA + WGM_CTC_ICRn, // 12 COM OCnx + WGM_reserved, // 13 + WGM_FAST_PWM_ICRn, // 14 COM OCnA + WGM_FAST_PWM_OCRnA // 15 COM OCnA +} WaveGenMode; + +// Compare Modes +typedef enum { + COM_NORMAL, // 0 + COM_TOGGLE, // 1 Non-PWM: OCnx ... Both PWM (WGM 9,11,14,15): OCnA only ... else NORMAL + COM_CLEAR_SET, // 2 Non-PWM: OCnx ... Fast PWM: OCnx/Bottom ... PF-FC: OCnx Up/Down + COM_SET_CLEAR // 3 Non-PWM: OCnx ... Fast PWM: OCnx/Bottom ... PF-FC: OCnx Up/Down +} CompareMode; + +// Clock Sources +typedef enum { + CS_NONE, // 0 + CS_PRESCALER_1, // 1 + CS_PRESCALER_8, // 2 + CS_PRESCALER_64, // 3 + CS_PRESCALER_256, // 4 + CS_PRESCALER_1024, // 5 + CS_EXT_FALLING, // 6 + CS_EXT_RISING // 7 +} ClockSource; + +// Clock Sources (Timer 2 only) +typedef enum { + CS2_NONE, // 0 + CS2_PRESCALER_1, // 1 + CS2_PRESCALER_8, // 2 + CS2_PRESCALER_32, // 3 + CS2_PRESCALER_64, // 4 + CS2_PRESCALER_128, // 5 + CS2_PRESCALER_256, // 6 + CS2_PRESCALER_1024 // 7 +} ClockSource2; + +// Get interrupt bits in an orderly way +#define GET_WGM(T) (((TCCR##T##A >> WGM##T##0) & 0x3) | ((TCCR##T##B >> WGM##T##2 << 2) & 0xC)) +#define GET_CS(T) ((TCCR##T##B >> CS##T##0) & 0x7) +#define GET_COM(T,Q) ((TCCR##T##Q >> COM##T##Q##0) & 0x3) +#define GET_COMA(T) GET_COM(T,A) +#define GET_COMB(T) GET_COM(T,B) +#define GET_COMC(T) GET_COM(T,C) +#define GET_ICNC(T) (!!(TCCR##T##B & _BV(ICNC##T))) +#define GET_ICES(T) (!!(TCCR##T##B & _BV(ICES##T))) +#define GET_FOC(T,Q) (!!(TCCR##T##C & _BV(FOC##T##Q))) +#define GET_FOCA(T) GET_FOC(T,A) +#define GET_FOCB(T) GET_FOC(T,B) +#define GET_FOCC(T) GET_FOC(T,C) + +// Set Wave Generation Mode bits +#define _SET_WGM(T,V) do{ \ + TCCR##T##A = (TCCR##T##A & ~(0x3 << WGM##T##0)) | (( int(V) & 0x3) << WGM##T##0); \ + TCCR##T##B = (TCCR##T##B & ~(0x3 << WGM##T##2)) | (((int(V) >> 2) & 0x3) << WGM##T##2); \ + }while(0) +#define SET_WGM(T,V) _SET_WGM(T,WGM_##V) + +// Set Clock Select bits +#define _SET_CS(T,V) (TCCR##T##B = (TCCR##T##B & ~(0x7 << CS##T##0)) | ((int(V) & 0x7) << CS##T##0)) +#define _SET_CS0(V) _SET_CS(0,V) +#define _SET_CS1(V) _SET_CS(1,V) +#ifdef TCCR2 + #define _SET_CS2(V) (TCCR2 = (TCCR2 & ~(0x7 << CS20)) | (int(V) << CS20)) +#else + #define _SET_CS2(V) _SET_CS(2,V) +#endif +#define _SET_CS3(V) _SET_CS(3,V) +#define _SET_CS4(V) _SET_CS(4,V) +#define _SET_CS5(V) _SET_CS(5,V) +#define SET_CS0(V) _SET_CS0(CS_##V) +#define SET_CS1(V) _SET_CS1(CS_##V) +#ifdef TCCR2 + #define SET_CS2(V) _SET_CS2(CS2_##V) +#else + #define SET_CS2(V) _SET_CS2(CS_##V) +#endif +#define SET_CS3(V) _SET_CS3(CS_##V) +#define SET_CS4(V) _SET_CS4(CS_##V) +#define SET_CS5(V) _SET_CS5(CS_##V) +#define SET_CS(T,V) SET_CS##T(V) + +// Set Compare Mode bits +#define _SET_COM(T,Q,V) (TCCR##T##Q = (TCCR##T##Q & ~(0x3 << COM##T##Q##0)) | (int(V) << COM##T##Q##0)) +#define SET_COM(T,Q,V) _SET_COM(T,Q,COM_##V) +#define SET_COMA(T,V) SET_COM(T,A,V) +#define SET_COMB(T,V) SET_COM(T,B,V) +#define SET_COMC(T,V) SET_COM(T,C,V) +#define SET_COMS(T,V1,V2,V3) do{ SET_COMA(T,V1); SET_COMB(T,V2); SET_COMC(T,V3); }while(0) + +// Set Noise Canceler bit +#define SET_ICNC(T,V) (TCCR##T##B = (V) ? TCCR##T##B | _BV(ICNC##T) : TCCR##T##B & ~_BV(ICNC##T)) + +// Set Input Capture Edge Select bit +#define SET_ICES(T,V) (TCCR##T##B = (V) ? TCCR##T##B | _BV(ICES##T) : TCCR##T##B & ~_BV(ICES##T)) + +// Set Force Output Compare bit +#define SET_FOC(T,Q,V) (TCCR##T##C = (V) ? TCCR##T##C | _BV(FOC##T##Q) : TCCR##T##C & ~_BV(FOC##T##Q)) +#define SET_FOCA(T,V) SET_FOC(T,A,V) +#define SET_FOCB(T,V) SET_FOC(T,B,V) +#define SET_FOCC(T,V) SET_FOC(T,C,V) + + +/** + * PWM availability macros + */ + +//find out which harware PWMs are already in use +#if PIN_EXISTS(CONTROLLER_FAN) + #define PWM_CHK_FAN_B(p) (p == CONTROLLER_FAN_PIN || p == E0_AUTO_FAN_PIN || p == E1_AUTO_FAN_PIN || p == E2_AUTO_FAN_PIN || p == E3_AUTO_FAN_PIN || p == E4_AUTO_FAN_PIN) +#else + #define PWM_CHK_FAN_B(p) (p == E0_AUTO_FAN_PIN || p == E1_AUTO_FAN_PIN || p == E2_AUTO_FAN_PIN || p == E3_AUTO_FAN_PIN || p == E4_AUTO_FAN_PIN) +#endif + +#if PIN_EXISTS(FAN) || PIN_EXISTS(FAN1) || PIN_EXISTS(FAN2) + #if PIN_EXISTS(FAN2) + #define PWM_CHK_FAN_A(p) (p == FAN_PIN || p == FAN1_PIN || p == FAN2_PIN) + #elif PIN_EXISTS(FAN1) + #define PWM_CHK_FAN_A(p) (p == FAN_PIN || p == FAN1_PIN) + #else + #define PWM_CHK_FAN_A(p) p == FAN_PIN + #endif +#else + #define PWM_CHK_FAN_A(p) false +#endif + +#if HAS_MOTOR_CURRENT_PWM + #if PIN_EXISTS(MOTOR_CURRENT_PWM_XY) + #define PWM_CHK_MOTOR_CURRENT(p) (p == MOTOR_CURRENT_PWM_E || p == MOTOR_CURRENT_PWM_Z || p == MOTOR_CURRENT_PWM_XY) + #elif PIN_EXISTS(MOTOR_CURRENT_PWM_Z) + #define PWM_CHK_MOTOR_CURRENT(p) (p == MOTOR_CURRENT_PWM_E || p == MOTOR_CURRENT_PWM_Z) + #else + #define PWM_CHK_MOTOR_CURRENT(p) (p == MOTOR_CURRENT_PWM_E) + #endif +#else + #define PWM_CHK_MOTOR_CURRENT(p) false +#endif + +#if defined(NUM_SERVOS) + #if AVR_ATmega2560_FAMILY + #define PWM_CHK_SERVO(p) ( p == 5 || NUM_SERVOS > 12 && p == 6 || NUM_SERVOS > 24 && p == 46) //PWMS 3A, 4A & 5A + #elif AVR_ATmega2561_FAMILY + #define PWM_CHK_SERVO(p) p == 5 //PWM3A + #elif AVR_ATmega1284_FAMILY + #define PWM_CHK_SERVO(p) false + #elif AVR_AT90USB1286_FAMILY + #define PWM_CHK_SERVO(p) p == 16 //PWM3A + #elif AVR_ATmega328_FAMILY + #define PWM_CHK_SERVO(p) false + #endif +#else + #define PWM_CHK_SERVO(p) false +#endif + +#if ENABLED(BARICUDA) + #if HAS_HEATER_1 && HAS_HEATER_2 + #define PWM_CHK_HEATER(p) (p == HEATER_1_PIN || p == HEATER_2_PIN) + #elif HAS_HEATER_1 + #define PWM_CHK_HEATER(p) (p == HEATER_1_PIN) + #endif +#else + #define PWM_CHK_HEATER(p) false +#endif + +#define PWM_CHK(p) (PWM_CHK_HEATER(p) || PWM_CHK_SERVO(p) || PWM_CHK_MOTOR_CURRENT(p)\ + || PWM_CHK_FAN_A(p) || PWM_CHK_FAN_B(p)) + +// define which hardware PWMs are available for the current CPU +// all timer 1 PWMS deleted from this list because they are never available +#if AVR_ATmega2560_FAMILY + #define PWM_PINS(p) ((p >= 2 && p <= 10 ) || p == 13 || p == 44 || p == 45 || p == 46 ) +#elif AVR_ATmega2561_FAMILY + #define PWM_PINS(p) ((p >= 2 && p <= 6 ) || p == 9) +#elif AVR_ATmega1284_FAMILY + #define PWM_PINS(p) (p == 3 || p == 4 || p == 14 || p == 15) +#elif AVR_AT90USB1286_FAMILY + #define PWM_PINS(p) (p == 0 || p == 1 || p == 14 || p == 15 || p == 16 || p == 24) +#elif AVR_ATmega328_FAMILY + #define PWM_PINS(p) (p == 3 || p == 5 || p == 6 || p == 11) +#else + #error "unknown CPU" +#endif + +// finally - the macro that tells us if a pin is an available hardware PWM +#define USEABLE_HARDWARE_PWM(p) (PWM_PINS(p) && !PWM_CHK(p)) + +#endif // _FASTIO_ARDUINO_H diff --git a/trunk/Arduino/Marlin_1.1.6/fastio_1280.h b/trunk/Arduino/Marlin_1.1.6/fastio_1280.h new file mode 100644 index 00000000..f9f56c8a --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/fastio_1280.h @@ -0,0 +1,1115 @@ +/** + * 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 . + * + */ + +/** + * Pin mapping for the 1280 and 2560 + * + * 1280 22 23 24 25 26 27 28 29 53 52 51 50 10 11 12 13 37 36 35 34 33 32 31 30 21 20 19 18 81 82 83 38 00 01 78 05 02 03 79 80 54 55 56 57 58 59 60 61 41 40 39 71 70 04 17 16 84 06 07 08 09 85 15 14 72 73 75 76 77 74 62 63 64 65 66 67 68 69 49 48 47 46 45 44 43 42 + * Port A0 A1 A2 A3 A4 A5 A6 A7 B0 B1 B2 B3 B4 B5 B6 B7 C0 C1 C2 C3 C4 C5 C6 C7 D0 D1 D2 D3 D4 D5 D6 D7 E0 E1 E2 E3 E4 E5 E6 E7 F0 F1 F2 F3 F4 F5 F6 F7 G0 G1 G2 G3 G4 G5 H0 H1 H2 H3 H4 H5 H6 H7 J0 J1 J2 J3 J4 J5 J6 J7 K0 K1 K2 K3 K4 K5 K6 K7 L0 L1 L2 L3 L4 L5 L6 L7 + * Marlin 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 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 + */ + +#ifndef _FASTIO_1280 +#define _FASTIO_1280 + +#include "fastio.h" + +// change for your board +#define DEBUG_LED DIO21 + +// UART +#define RXD DIO0 +#define TXD DIO1 + +// SPI +#define SCK DIO52 +#define MISO DIO50 +#define MOSI DIO51 +#define SS DIO53 + +// TWI (I2C) +#define SCL DIO21 +#define SDA DIO20 + +// Timers and PWM +#define OC0A DIO13 +#define OC0B DIO4 +#define OC1A DIO11 +#define OC1B DIO12 +#define OC2A DIO10 +#define OC2B DIO9 +#define OC3A DIO5 +#define OC3B DIO2 +#define OC3C DIO3 +#define OC4A DIO6 +#define OC4B DIO7 +#define OC4C DIO8 +#define OC5A DIO46 +#define OC5B DIO45 +#define OC5C DIO44 + +// Digital I/O + +#define DIO0_PIN PINE0 +#define DIO0_RPORT PINE +#define DIO0_WPORT PORTE +#define DIO0_DDR DDRE +#define DIO0_PWM NULL + +#define DIO1_PIN PINE1 +#define DIO1_RPORT PINE +#define DIO1_WPORT PORTE +#define DIO1_DDR DDRE +#define DIO1_PWM NULL + +#define DIO2_PIN PINE4 +#define DIO2_RPORT PINE +#define DIO2_WPORT PORTE +#define DIO2_DDR DDRE +#define DIO2_PWM &OCR3BL + +#define DIO3_PIN PINE5 +#define DIO3_RPORT PINE +#define DIO3_WPORT PORTE +#define DIO3_DDR DDRE +#define DIO3_PWM &OCR3CL + +#define DIO4_PIN PING5 +#define DIO4_RPORT PING +#define DIO4_WPORT PORTG +#define DIO4_DDR DDRG +#define DIO4_PWM &OCR0B + +#define DIO5_PIN PINE3 +#define DIO5_RPORT PINE +#define DIO5_WPORT PORTE +#define DIO5_DDR DDRE +#define DIO5_PWM &OCR3AL + +#define DIO6_PIN PINH3 +#define DIO6_RPORT PINH +#define DIO6_WPORT PORTH +#define DIO6_DDR DDRH +#define DIO6_PWM &OCR4AL + +#define DIO7_PIN PINH4 +#define DIO7_RPORT PINH +#define DIO7_WPORT PORTH +#define DIO7_DDR DDRH +#define DIO7_PWM &OCR4BL + +#define DIO8_PIN PINH5 +#define DIO8_RPORT PINH +#define DIO8_WPORT PORTH +#define DIO8_DDR DDRH +#define DIO8_PWM &OCR4CL + +#define DIO9_PIN PINH6 +#define DIO9_RPORT PINH +#define DIO9_WPORT PORTH +#define DIO9_DDR DDRH +#define DIO9_PWM &OCR2B + +#define DIO10_PIN PINB4 +#define DIO10_RPORT PINB +#define DIO10_WPORT PORTB +#define DIO10_DDR DDRB +#define DIO10_PWM &OCR2A + +#define DIO11_PIN PINB5 +#define DIO11_RPORT PINB +#define DIO11_WPORT PORTB +#define DIO11_DDR DDRB +#define DIO11_PWM NULL + +#define DIO12_PIN PINB6 +#define DIO12_RPORT PINB +#define DIO12_WPORT PORTB +#define DIO12_DDR DDRB +#define DIO12_PWM NULL + +#define DIO13_PIN PINB7 +#define DIO13_RPORT PINB +#define DIO13_WPORT PORTB +#define DIO13_DDR DDRB +#define DIO13_PWM &OCR0A + +#define DIO14_PIN PINJ1 +#define DIO14_RPORT PINJ +#define DIO14_WPORT PORTJ +#define DIO14_DDR DDRJ +#define DIO14_PWM NULL + +#define DIO15_PIN PINJ0 +#define DIO15_RPORT PINJ +#define DIO15_WPORT PORTJ +#define DIO15_DDR DDRJ +#define DIO15_PWM NULL + +#define DIO16_PIN PINH1 +#define DIO16_RPORT PINH +#define DIO16_WPORT PORTH +#define DIO16_DDR DDRH +#define DIO16_PWM NULL + +#define DIO17_PIN PINH0 +#define DIO17_RPORT PINH +#define DIO17_WPORT PORTH +#define DIO17_DDR DDRH +#define DIO17_PWM NULL + +#define DIO18_PIN PIND3 +#define DIO18_RPORT PIND +#define DIO18_WPORT PORTD +#define DIO18_DDR DDRD +#define DIO18_PWM NULL + +#define DIO19_PIN PIND2 +#define DIO19_RPORT PIND +#define DIO19_WPORT PORTD +#define DIO19_DDR DDRD +#define DIO19_PWM NULL + +#define DIO20_PIN PIND1 +#define DIO20_RPORT PIND +#define DIO20_WPORT PORTD +#define DIO20_DDR DDRD +#define DIO20_PWM NULL + +#define DIO21_PIN PIND0 +#define DIO21_RPORT PIND +#define DIO21_WPORT PORTD +#define DIO21_DDR DDRD +#define DIO21_PWM NULL + +#define DIO22_PIN PINA0 +#define DIO22_RPORT PINA +#define DIO22_WPORT PORTA +#define DIO22_DDR DDRA +#define DIO22_PWM NULL + +#define DIO23_PIN PINA1 +#define DIO23_RPORT PINA +#define DIO23_WPORT PORTA +#define DIO23_DDR DDRA +#define DIO23_PWM NULL + +#define DIO24_PIN PINA2 +#define DIO24_RPORT PINA +#define DIO24_WPORT PORTA +#define DIO24_DDR DDRA +#define DIO24_PWM NULL + +#define DIO25_PIN PINA3 +#define DIO25_RPORT PINA +#define DIO25_WPORT PORTA +#define DIO25_DDR DDRA +#define DIO25_PWM NULL + +#define DIO26_PIN PINA4 +#define DIO26_RPORT PINA +#define DIO26_WPORT PORTA +#define DIO26_DDR DDRA +#define DIO26_PWM NULL + +#define DIO27_PIN PINA5 +#define DIO27_RPORT PINA +#define DIO27_WPORT PORTA +#define DIO27_DDR DDRA +#define DIO27_PWM NULL + +#define DIO28_PIN PINA6 +#define DIO28_RPORT PINA +#define DIO28_WPORT PORTA +#define DIO28_DDR DDRA +#define DIO28_PWM NULL + +#define DIO29_PIN PINA7 +#define DIO29_RPORT PINA +#define DIO29_WPORT PORTA +#define DIO29_DDR DDRA +#define DIO29_PWM NULL + +#define DIO30_PIN PINC7 +#define DIO30_RPORT PINC +#define DIO30_WPORT PORTC +#define DIO30_DDR DDRC +#define DIO30_PWM NULL + +#define DIO31_PIN PINC6 +#define DIO31_RPORT PINC +#define DIO31_WPORT PORTC +#define DIO31_DDR DDRC +#define DIO31_PWM NULL + +#define DIO32_PIN PINC5 +#define DIO32_RPORT PINC +#define DIO32_WPORT PORTC +#define DIO32_DDR DDRC +#define DIO32_PWM NULL + +#define DIO33_PIN PINC4 +#define DIO33_RPORT PINC +#define DIO33_WPORT PORTC +#define DIO33_DDR DDRC +#define DIO33_PWM NULL + +#define DIO34_PIN PINC3 +#define DIO34_RPORT PINC +#define DIO34_WPORT PORTC +#define DIO34_DDR DDRC +#define DIO34_PWM NULL + +#define DIO35_PIN PINC2 +#define DIO35_RPORT PINC +#define DIO35_WPORT PORTC +#define DIO35_DDR DDRC +#define DIO35_PWM NULL + +#define DIO36_PIN PINC1 +#define DIO36_RPORT PINC +#define DIO36_WPORT PORTC +#define DIO36_DDR DDRC +#define DIO36_PWM NULL + +#define DIO37_PIN PINC0 +#define DIO37_RPORT PINC +#define DIO37_WPORT PORTC +#define DIO37_DDR DDRC +#define DIO37_PWM NULL + +#define DIO38_PIN PIND7 +#define DIO38_RPORT PIND +#define DIO38_WPORT PORTD +#define DIO38_DDR DDRD +#define DIO38_PWM NULL + +#define DIO39_PIN PING2 +#define DIO39_RPORT PING +#define DIO39_WPORT PORTG +#define DIO39_DDR DDRG +#define DIO39_PWM NULL + +#define DIO40_PIN PING1 +#define DIO40_RPORT PING +#define DIO40_WPORT PORTG +#define DIO40_DDR DDRG +#define DIO40_PWM NULL + +#define DIO41_PIN PING0 +#define DIO41_RPORT PING +#define DIO41_WPORT PORTG +#define DIO41_DDR DDRG +#define DIO41_PWM NULL + +#define DIO42_PIN PINL7 +#define DIO42_RPORT PINL +#define DIO42_WPORT PORTL +#define DIO42_DDR DDRL +#define DIO42_PWM NULL + +#define DIO43_PIN PINL6 +#define DIO43_RPORT PINL +#define DIO43_WPORT PORTL +#define DIO43_DDR DDRL +#define DIO43_PWM NULL + +#define DIO44_PIN PINL5 +#define DIO44_RPORT PINL +#define DIO44_WPORT PORTL +#define DIO44_DDR DDRL +#define DIO44_PWM &OCR5CL + +#define DIO45_PIN PINL4 +#define DIO45_RPORT PINL +#define DIO45_WPORT PORTL +#define DIO45_DDR DDRL +#define DIO45_PWM &OCR5BL + +#define DIO46_PIN PINL3 +#define DIO46_RPORT PINL +#define DIO46_WPORT PORTL +#define DIO46_DDR DDRL +#define DIO46_PWM &OCR5AL + +#define DIO47_PIN PINL2 +#define DIO47_RPORT PINL +#define DIO47_WPORT PORTL +#define DIO47_DDR DDRL +#define DIO47_PWM NULL + +#define DIO48_PIN PINL1 +#define DIO48_RPORT PINL +#define DIO48_WPORT PORTL +#define DIO48_DDR DDRL +#define DIO48_PWM NULL + +#define DIO49_PIN PINL0 +#define DIO49_RPORT PINL +#define DIO49_WPORT PORTL +#define DIO49_DDR DDRL +#define DIO49_PWM NULL + +#define DIO50_PIN PINB3 +#define DIO50_RPORT PINB +#define DIO50_WPORT PORTB +#define DIO50_DDR DDRB +#define DIO50_PWM NULL + +#define DIO51_PIN PINB2 +#define DIO51_RPORT PINB +#define DIO51_WPORT PORTB +#define DIO51_DDR DDRB +#define DIO51_PWM NULL + +#define DIO52_PIN PINB1 +#define DIO52_RPORT PINB +#define DIO52_WPORT PORTB +#define DIO52_DDR DDRB +#define DIO52_PWM NULL + +#define DIO53_PIN PINB0 +#define DIO53_RPORT PINB +#define DIO53_WPORT PORTB +#define DIO53_DDR DDRB +#define DIO53_PWM NULL + +#define DIO54_PIN PINF0 +#define DIO54_RPORT PINF +#define DIO54_WPORT PORTF +#define DIO54_DDR DDRF +#define DIO54_PWM NULL + +#define DIO55_PIN PINF1 +#define DIO55_RPORT PINF +#define DIO55_WPORT PORTF +#define DIO55_DDR DDRF +#define DIO55_PWM NULL + +#define DIO56_PIN PINF2 +#define DIO56_RPORT PINF +#define DIO56_WPORT PORTF +#define DIO56_DDR DDRF +#define DIO56_PWM NULL + +#define DIO57_PIN PINF3 +#define DIO57_RPORT PINF +#define DIO57_WPORT PORTF +#define DIO57_DDR DDRF +#define DIO57_PWM NULL + +#define DIO58_PIN PINF4 +#define DIO58_RPORT PINF +#define DIO58_WPORT PORTF +#define DIO58_DDR DDRF +#define DIO58_PWM NULL + +#define DIO59_PIN PINF5 +#define DIO59_RPORT PINF +#define DIO59_WPORT PORTF +#define DIO59_DDR DDRF +#define DIO59_PWM NULL + +#define DIO60_PIN PINF6 +#define DIO60_RPORT PINF +#define DIO60_WPORT PORTF +#define DIO60_DDR DDRF +#define DIO60_PWM NULL + +#define DIO61_PIN PINF7 +#define DIO61_RPORT PINF +#define DIO61_WPORT PORTF +#define DIO61_DDR DDRF +#define DIO61_PWM NULL + +#define DIO62_PIN PINK0 +#define DIO62_RPORT PINK +#define DIO62_WPORT PORTK +#define DIO62_DDR DDRK +#define DIO62_PWM NULL + +#define DIO63_PIN PINK1 +#define DIO63_RPORT PINK +#define DIO63_WPORT PORTK +#define DIO63_DDR DDRK +#define DIO63_PWM NULL + +#define DIO64_PIN PINK2 +#define DIO64_RPORT PINK +#define DIO64_WPORT PORTK +#define DIO64_DDR DDRK +#define DIO64_PWM NULL + +#define DIO65_PIN PINK3 +#define DIO65_RPORT PINK +#define DIO65_WPORT PORTK +#define DIO65_DDR DDRK +#define DIO65_PWM NULL + +#define DIO66_PIN PINK4 +#define DIO66_RPORT PINK +#define DIO66_WPORT PORTK +#define DIO66_DDR DDRK +#define DIO66_PWM NULL + +#define DIO67_PIN PINK5 +#define DIO67_RPORT PINK +#define DIO67_WPORT PORTK +#define DIO67_DDR DDRK +#define DIO67_PWM NULL + +#define DIO68_PIN PINK6 +#define DIO68_RPORT PINK +#define DIO68_WPORT PORTK +#define DIO68_DDR DDRK +#define DIO68_PWM NULL + +#define DIO69_PIN PINK7 +#define DIO69_RPORT PINK +#define DIO69_WPORT PORTK +#define DIO69_DDR DDRK +#define DIO69_PWM NULL + +#define DIO70_PIN PING4 +#define DIO70_RPORT PING +#define DIO70_WPORT PORTG +#define DIO70_DDR DDRG +#define DIO70_PWM NULL + +#define DIO71_PIN PING3 +#define DIO71_RPORT PING +#define DIO71_WPORT PORTG +#define DIO71_DDR DDRG +#define DIO71_PWM NULL + +#define DIO72_PIN PINJ2 +#define DIO72_RPORT PINJ +#define DIO72_WPORT PORTJ +#define DIO72_DDR DDRJ +#define DIO72_PWM NULL + +#define DIO73_PIN PINJ3 +#define DIO73_RPORT PINJ +#define DIO73_WPORT PORTJ +#define DIO73_DDR DDRJ +#define DIO73_PWM NULL + +#define DIO74_PIN PINJ7 +#define DIO74_RPORT PINJ +#define DIO74_WPORT PORTJ +#define DIO74_DDR DDRJ +#define DIO74_PWM NULL + +#define DIO75_PIN PINJ4 +#define DIO75_RPORT PINJ +#define DIO75_WPORT PORTJ +#define DIO75_DDR DDRJ +#define DIO75_PWM NULL + +#define DIO76_PIN PINJ5 +#define DIO76_RPORT PINJ +#define DIO76_WPORT PORTJ +#define DIO76_DDR DDRJ +#define DIO76_PWM NULL + +#define DIO77_PIN PINJ6 +#define DIO77_RPORT PINJ +#define DIO77_WPORT PORTJ +#define DIO77_DDR DDRJ +#define DIO77_PWM NULL + +#define DIO78_PIN PINE2 +#define DIO78_RPORT PINE +#define DIO78_WPORT PORTE +#define DIO78_DDR DDRE +#define DIO78_PWM NULL + +#define DIO79_PIN PINE6 +#define DIO79_RPORT PINE +#define DIO79_WPORT PORTE +#define DIO79_DDR DDRE +#define DIO79_PWM NULL + +#define DIO80_PIN PINE7 +#define DIO80_RPORT PINE +#define DIO80_WPORT PORTE +#define DIO80_DDR DDRE +#define DIO80_PWM NULL + +#define DIO81_PIN PIND4 +#define DIO81_RPORT PIND +#define DIO81_WPORT PORTD +#define DIO81_DDR DDRD +#define DIO81_PWM NULL + +#define DIO82_PIN PIND5 +#define DIO82_RPORT PIND +#define DIO82_WPORT PORTD +#define DIO82_DDR DDRD +#define DIO82_PWM NULL + +#define DIO83_PIN PIND6 +#define DIO83_RPORT PIND +#define DIO83_WPORT PORTD +#define DIO83_DDR DDRD +#define DIO83_PWM NULL + +#define DIO84_PIN PINH2 +#define DIO84_RPORT PINH +#define DIO84_WPORT PORTH +#define DIO84_DDR DDRH +#define DIO84_PWM NULL + +#define DIO85_PIN PINH7 +#define DIO85_RPORT PINH +#define DIO85_WPORT PORTH +#define DIO85_DDR DDRH +#define DIO85_PWM NULL + +#undef PA0 +#define PA0_PIN PINA0 +#define PA0_RPORT PINA +#define PA0_WPORT PORTA +#define PA0_DDR DDRA +#define PA0_PWM NULL +#undef PA1 +#define PA1_PIN PINA1 +#define PA1_RPORT PINA +#define PA1_WPORT PORTA +#define PA1_DDR DDRA +#define PA1_PWM NULL +#undef PA2 +#define PA2_PIN PINA2 +#define PA2_RPORT PINA +#define PA2_WPORT PORTA +#define PA2_DDR DDRA +#define PA2_PWM NULL +#undef PA3 +#define PA3_PIN PINA3 +#define PA3_RPORT PINA +#define PA3_WPORT PORTA +#define PA3_DDR DDRA +#define PA3_PWM NULL +#undef PA4 +#define PA4_PIN PINA4 +#define PA4_RPORT PINA +#define PA4_WPORT PORTA +#define PA4_DDR DDRA +#define PA4_PWM NULL +#undef PA5 +#define PA5_PIN PINA5 +#define PA5_RPORT PINA +#define PA5_WPORT PORTA +#define PA5_DDR DDRA +#define PA5_PWM NULL +#undef PA6 +#define PA6_PIN PINA6 +#define PA6_RPORT PINA +#define PA6_WPORT PORTA +#define PA6_DDR DDRA +#define PA6_PWM NULL +#undef PA7 +#define PA7_PIN PINA7 +#define PA7_RPORT PINA +#define PA7_WPORT PORTA +#define PA7_DDR DDRA +#define PA7_PWM NULL + +#undef PB0 +#define PB0_PIN PINB0 +#define PB0_RPORT PINB +#define PB0_WPORT PORTB +#define PB0_DDR DDRB +#define PB0_PWM NULL +#undef PB1 +#define PB1_PIN PINB1 +#define PB1_RPORT PINB +#define PB1_WPORT PORTB +#define PB1_DDR DDRB +#define PB1_PWM NULL +#undef PB2 +#define PB2_PIN PINB2 +#define PB2_RPORT PINB +#define PB2_WPORT PORTB +#define PB2_DDR DDRB +#define PB2_PWM NULL +#undef PB3 +#define PB3_PIN PINB3 +#define PB3_RPORT PINB +#define PB3_WPORT PORTB +#define PB3_DDR DDRB +#define PB3_PWM NULL +#undef PB4 +#define PB4_PIN PINB4 +#define PB4_RPORT PINB +#define PB4_WPORT PORTB +#define PB4_DDR DDRB +#define PB4_PWM &OCR2A +#undef PB5 +#define PB5_PIN PINB5 +#define PB5_RPORT PINB +#define PB5_WPORT PORTB +#define PB5_DDR DDRB +#define PB5_PWM NULL +#undef PB6 +#define PB6_PIN PINB6 +#define PB6_RPORT PINB +#define PB6_WPORT PORTB +#define PB6_DDR DDRB +#define PB6_PWM NULL +#undef PB7 +#define PB7_PIN PINB7 +#define PB7_RPORT PINB +#define PB7_WPORT PORTB +#define PB7_DDR DDRB +#define PB7_PWM &OCR0A + +#undef PC0 +#define PC0_PIN PINC0 +#define PC0_RPORT PINC +#define PC0_WPORT PORTC +#define PC0_DDR DDRC +#define PC0_PWM NULL +#undef PC1 +#define PC1_PIN PINC1 +#define PC1_RPORT PINC +#define PC1_WPORT PORTC +#define PC1_DDR DDRC +#define PC1_PWM NULL +#undef PC2 +#define PC2_PIN PINC2 +#define PC2_RPORT PINC +#define PC2_WPORT PORTC +#define PC2_DDR DDRC +#define PC2_PWM NULL +#undef PC3 +#define PC3_PIN PINC3 +#define PC3_RPORT PINC +#define PC3_WPORT PORTC +#define PC3_DDR DDRC +#define PC3_PWM NULL +#undef PC4 +#define PC4_PIN PINC4 +#define PC4_RPORT PINC +#define PC4_WPORT PORTC +#define PC4_DDR DDRC +#define PC4_PWM NULL +#undef PC5 +#define PC5_PIN PINC5 +#define PC5_RPORT PINC +#define PC5_WPORT PORTC +#define PC5_DDR DDRC +#define PC5_PWM NULL +#undef PC6 +#define PC6_PIN PINC6 +#define PC6_RPORT PINC +#define PC6_WPORT PORTC +#define PC6_DDR DDRC +#define PC6_PWM NULL +#undef PC7 +#define PC7_PIN PINC7 +#define PC7_RPORT PINC +#define PC7_WPORT PORTC +#define PC7_DDR DDRC +#define PC7_PWM NULL + +#undef PD0 +#define PD0_PIN PIND0 +#define PD0_RPORT PIND +#define PD0_WPORT PORTD +#define PD0_DDR DDRD +#define PD0_PWM NULL +#undef PD1 +#define PD1_PIN PIND1 +#define PD1_RPORT PIND +#define PD1_WPORT PORTD +#define PD1_DDR DDRD +#define PD1_PWM NULL +#undef PD2 +#define PD2_PIN PIND2 +#define PD2_RPORT PIND +#define PD2_WPORT PORTD +#define PD2_DDR DDRD +#define PD2_PWM NULL +#undef PD3 +#define PD3_PIN PIND3 +#define PD3_RPORT PIND +#define PD3_WPORT PORTD +#define PD3_DDR DDRD +#define PD3_PWM NULL +#undef PD4 +#define PD4_PIN PIND4 +#define PD4_RPORT PIND +#define PD4_WPORT PORTD +#define PD4_DDR DDRD +#define PD4_PWM NULL +#undef PD5 +#define PD5_PIN PIND5 +#define PD5_RPORT PIND +#define PD5_WPORT PORTD +#define PD5_DDR DDRD +#define PD5_PWM NULL +#undef PD6 +#define PD6_PIN PIND6 +#define PD6_RPORT PIND +#define PD6_WPORT PORTD +#define PD6_DDR DDRD +#define PD6_PWM NULL +#undef PD7 +#define PD7_PIN PIND7 +#define PD7_RPORT PIND +#define PD7_WPORT PORTD +#define PD7_DDR DDRD +#define PD7_PWM NULL + +#undef PE0 +#define PE0_PIN PINE0 +#define PE0_RPORT PINE +#define PE0_WPORT PORTE +#define PE0_DDR DDRE +#define PE0_PWM NULL +#undef PE1 +#define PE1_PIN PINE1 +#define PE1_RPORT PINE +#define PE1_WPORT PORTE +#define PE1_DDR DDRE +#define PE1_PWM NULL +#undef PE2 +#define PE2_PIN PINE2 +#define PE2_RPORT PINE +#define PE2_WPORT PORTE +#define PE2_DDR DDRE +#define PE2_PWM NULL +#undef PE3 +#define PE3_PIN PINE3 +#define PE3_RPORT PINE +#define PE3_WPORT PORTE +#define PE3_DDR DDRE +#define PE3_PWM &OCR3AL +#undef PE4 +#define PE4_PIN PINE4 +#define PE4_RPORT PINE +#define PE4_WPORT PORTE +#define PE4_DDR DDRE +#define PE4_PWM &OCR3BL +#undef PE5 +#define PE5_PIN PINE5 +#define PE5_RPORT PINE +#define PE5_WPORT PORTE +#define PE5_DDR DDRE +#define PE5_PWM &OCR3CL +#undef PE6 +#define PE6_PIN PINE6 +#define PE6_RPORT PINE +#define PE6_WPORT PORTE +#define PE6_DDR DDRE +#define PE6_PWM NULL +#undef PE7 +#define PE7_PIN PINE7 +#define PE7_RPORT PINE +#define PE7_WPORT PORTE +#define PE7_DDR DDRE +#define PE7_PWM NULL + +#undef PF0 +#define PF0_PIN PINF0 +#define PF0_RPORT PINF +#define PF0_WPORT PORTF +#define PF0_DDR DDRF +#define PF0_PWM NULL +#undef PF1 +#define PF1_PIN PINF1 +#define PF1_RPORT PINF +#define PF1_WPORT PORTF +#define PF1_DDR DDRF +#define PF1_PWM NULL +#undef PF2 +#define PF2_PIN PINF2 +#define PF2_RPORT PINF +#define PF2_WPORT PORTF +#define PF2_DDR DDRF +#define PF2_PWM NULL +#undef PF3 +#define PF3_PIN PINF3 +#define PF3_RPORT PINF +#define PF3_WPORT PORTF +#define PF3_DDR DDRF +#define PF3_PWM NULL +#undef PF4 +#define PF4_PIN PINF4 +#define PF4_RPORT PINF +#define PF4_WPORT PORTF +#define PF4_DDR DDRF +#define PF4_PWM NULL +#undef PF5 +#define PF5_PIN PINF5 +#define PF5_RPORT PINF +#define PF5_WPORT PORTF +#define PF5_DDR DDRF +#define PF5_PWM NULL +#undef PF6 +#define PF6_PIN PINF6 +#define PF6_RPORT PINF +#define PF6_WPORT PORTF +#define PF6_DDR DDRF +#define PF6_PWM NULL +#undef PF7 +#define PF7_PIN PINF7 +#define PF7_RPORT PINF +#define PF7_WPORT PORTF +#define PF7_DDR DDRF +#define PF7_PWM NULL + +#undef PG0 +#define PG0_PIN PING0 +#define PG0_RPORT PING +#define PG0_WPORT PORTG +#define PG0_DDR DDRG +#define PG0_PWM NULL +#undef PG1 +#define PG1_PIN PING1 +#define PG1_RPORT PING +#define PG1_WPORT PORTG +#define PG1_DDR DDRG +#define PG1_PWM NULL +#undef PG2 +#define PG2_PIN PING2 +#define PG2_RPORT PING +#define PG2_WPORT PORTG +#define PG2_DDR DDRG +#define PG2_PWM NULL +#undef PG3 +#define PG3_PIN PING3 +#define PG3_RPORT PING +#define PG3_WPORT PORTG +#define PG3_DDR DDRG +#define PG3_PWM NULL +#undef PG4 +#define PG4_PIN PING4 +#define PG4_RPORT PING +#define PG4_WPORT PORTG +#define PG4_DDR DDRG +#define PG4_PWM NULL +#undef PG5 +#define PG5_PIN PING5 +#define PG5_RPORT PING +#define PG5_WPORT PORTG +#define PG5_DDR DDRG +#define PG5_PWM &OCR0B + +#undef PH0 +#define PH0_PIN PINH0 +#define PH0_RPORT PINH +#define PH0_WPORT PORTH +#define PH0_DDR DDRH +#define PH0_PWM NULL +#undef PH1 +#define PH1_PIN PINH1 +#define PH1_RPORT PINH +#define PH1_WPORT PORTH +#define PH1_DDR DDRH +#define PH1_PWM NULL +#undef PH2 +#define PH2_PIN PINH2 +#define PH2_RPORT PINH +#define PH2_WPORT PORTH +#define PH2_DDR DDRH +#define PH2_PWM NULL +#undef PH3 +#define PH3_PIN PINH3 +#define PH3_RPORT PINH +#define PH3_WPORT PORTH +#define PH3_DDR DDRH +#define PH3_PWM &OCR4AL +#undef PH4 +#define PH4_PIN PINH4 +#define PH4_RPORT PINH +#define PH4_WPORT PORTH +#define PH4_DDR DDRH +#define PH4_PWM &OCR4BL +#undef PH5 +#define PH5_PIN PINH5 +#define PH5_RPORT PINH +#define PH5_WPORT PORTH +#define PH5_DDR DDRH +#define PH5_PWM &OCR4CL +#undef PH6 +#define PH6_PIN PINH6 +#define PH6_RPORT PINH +#define PH6_WPORT PORTH +#define PH6_DDR DDRH +#define PH6_PWM &OCR2B +#undef PH7 +#define PH7_PIN PINH7 +#define PH7_RPORT PINH +#define PH7_WPORT PORTH +#define PH7_DDR DDRH +#define PH7_PWM NULL + +#undef PJ0 +#define PJ0_PIN PINJ0 +#define PJ0_RPORT PINJ +#define PJ0_WPORT PORTJ +#define PJ0_DDR DDRJ +#define PJ0_PWM NULL +#undef PJ1 +#define PJ1_PIN PINJ1 +#define PJ1_RPORT PINJ +#define PJ1_WPORT PORTJ +#define PJ1_DDR DDRJ +#define PJ1_PWM NULL +#undef PJ2 +#define PJ2_PIN PINJ2 +#define PJ2_RPORT PINJ +#define PJ2_WPORT PORTJ +#define PJ2_DDR DDRJ +#define PJ2_PWM NULL +#undef PJ3 +#define PJ3_PIN PINJ3 +#define PJ3_RPORT PINJ +#define PJ3_WPORT PORTJ +#define PJ3_DDR DDRJ +#define PJ3_PWM NULL +#undef PJ4 +#define PJ4_PIN PINJ4 +#define PJ4_RPORT PINJ +#define PJ4_WPORT PORTJ +#define PJ4_DDR DDRJ +#define PJ4_PWM NULL +#undef PJ5 +#define PJ5_PIN PINJ5 +#define PJ5_RPORT PINJ +#define PJ5_WPORT PORTJ +#define PJ5_DDR DDRJ +#define PJ5_PWM NULL +#undef PJ6 +#define PJ6_PIN PINJ6 +#define PJ6_RPORT PINJ +#define PJ6_WPORT PORTJ +#define PJ6_DDR DDRJ +#define PJ6_PWM NULL +#undef PJ7 +#define PJ7_PIN PINJ7 +#define PJ7_RPORT PINJ +#define PJ7_WPORT PORTJ +#define PJ7_DDR DDRJ +#define PJ7_PWM NULL + +#undef PK0 +#define PK0_PIN PINK0 +#define PK0_RPORT PINK +#define PK0_WPORT PORTK +#define PK0_DDR DDRK +#define PK0_PWM NULL +#undef PK1 +#define PK1_PIN PINK1 +#define PK1_RPORT PINK +#define PK1_WPORT PORTK +#define PK1_DDR DDRK +#define PK1_PWM NULL +#undef PK2 +#define PK2_PIN PINK2 +#define PK2_RPORT PINK +#define PK2_WPORT PORTK +#define PK2_DDR DDRK +#define PK2_PWM NULL +#undef PK3 +#define PK3_PIN PINK3 +#define PK3_RPORT PINK +#define PK3_WPORT PORTK +#define PK3_DDR DDRK +#define PK3_PWM NULL +#undef PK4 +#define PK4_PIN PINK4 +#define PK4_RPORT PINK +#define PK4_WPORT PORTK +#define PK4_DDR DDRK +#define PK4_PWM NULL +#undef PK5 +#define PK5_PIN PINK5 +#define PK5_RPORT PINK +#define PK5_WPORT PORTK +#define PK5_DDR DDRK +#define PK5_PWM NULL +#undef PK6 +#define PK6_PIN PINK6 +#define PK6_RPORT PINK +#define PK6_WPORT PORTK +#define PK6_DDR DDRK +#define PK6_PWM NULL +#undef PK7 +#define PK7_PIN PINK7 +#define PK7_RPORT PINK +#define PK7_WPORT PORTK +#define PK7_DDR DDRK +#define PK7_PWM NULL + +#undef PL0 +#define PL0_PIN PINL0 +#define PL0_RPORT PINL +#define PL0_WPORT PORTL +#define PL0_DDR DDRL +#define PL0_PWM NULL +#undef PL1 +#define PL1_PIN PINL1 +#define PL1_RPORT PINL +#define PL1_WPORT PORTL +#define PL1_DDR DDRL +#define PL1_PWM NULL +#undef PL2 +#define PL2_PIN PINL2 +#define PL2_RPORT PINL +#define PL2_WPORT PORTL +#define PL2_DDR DDRL +#define PL2_PWM NULL +#undef PL3 +#define PL3_PIN PINL3 +#define PL3_RPORT PINL +#define PL3_WPORT PORTL +#define PL3_DDR DDRL +#define PL3_PWM &OCR5AL +#undef PL4 +#define PL4_PIN PINL4 +#define PL4_RPORT PINL +#define PL4_WPORT PORTL +#define PL4_DDR DDRL +#define PL4_PWM &OCR5BL +#undef PL5 +#define PL5_PIN PINL5 +#define PL5_RPORT PINL +#define PL5_WPORT PORTL +#define PL5_DDR DDRL +#define PL5_PWM &OCR5CL +#undef PL6 +#define PL6_PIN PINL6 +#define PL6_RPORT PINL +#define PL6_WPORT PORTL +#define PL6_DDR DDRL +#define PL6_PWM NULL +#undef PL7 +#define PL7_PIN PINL7 +#define PL7_RPORT PINL +#define PL7_WPORT PORTL +#define PL7_DDR DDRL +#define PL7_PWM NULL + +#endif // _FASTIO_1280 diff --git a/trunk/Arduino/Marlin_1.1.6/fastio_1281.h b/trunk/Arduino/Marlin_1.1.6/fastio_1281.h new file mode 100644 index 00000000..85d2c4ef --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/fastio_1281.h @@ -0,0 +1,720 @@ +/** + * 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 . + * + */ + +/** + * Pin mapping for the 1281 and 2561 + * + * 1281 38 39 40 41 42 43 44 45 16 10 11 12 06 07 08 09 30 31 32 33 34 35 36 37 17 18 19 20 21 22 23 24 00 01 13 05 02 03 14 15 46 47 48 49 50 51 52 53 25 26 27 28 29 04 + * Port A0 A1 A2 A3 A4 A5 A6 A7 B0 B1 B2 B3 B4 B5 B6 B7 C0 C1 C2 C3 C4 C5 C6 C7 D0 D1 D2 D3 D4 D5 D6 D7 E0 E1 E2 E3 E4 E5 E6 E7 F0 F1 F2 F3 F4 F5 F6 F7 G0 G1 G2 G3 G4 G5 + * Marlin 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 + */ + +#ifndef _FASTIO_1281 +#define _FASTIO_1281 + +#include "fastio.h" + +// change for your board +#define DEBUG_LED DIO46 + +// UART +#define RXD DIO0 +#define TXD DIO1 + +// SPI +#define SCK DIO10 +#define MISO DIO12 +#define MOSI DIO11 +#define SS DIO16 + +// TWI (I2C) +#define SCL DIO17 +#define SDA DIO18 + +// Timers and PWM +#define OC0A DIO9 +#define OC0B DIO4 +#define OC1A DIO7 +#define OC1B DIO8 +#define OC2A DIO6 +#define OC3A DIO5 +#define OC3B DIO2 +#define OC3C DIO3 + +// Digital I/O + +#define DIO0_PIN PINE0 +#define DIO0_RPORT PINE +#define DIO0_WPORT PORTE +#define DIO0_DDR DDRE +#define DIO0_PWM NULL + +#define DIO1_PIN PINE1 +#define DIO1_RPORT PINE +#define DIO1_WPORT PORTE +#define DIO1_DDR DDRE +#define DIO1_PWM NULL + +#define DIO2_PIN PINE4 +#define DIO2_RPORT PINE +#define DIO2_WPORT PORTE +#define DIO2_DDR DDRE +#define DIO2_PWM &OCR3BL + +#define DIO3_PIN PINE5 +#define DIO3_RPORT PINE +#define DIO3_WPORT PORTE +#define DIO3_DDR DDRE +#define DIO3_PWM &OCR3CL + +#define DIO4_PIN PING5 +#define DIO4_RPORT PING +#define DIO4_WPORT PORTG +#define DIO4_DDR DDRG +#define DIO4_PWM &OCR0B + +#define DIO5_PIN PINE3 +#define DIO5_RPORT PINE +#define DIO5_WPORT PORTE +#define DIO5_DDR DDRE +#define DIO5_PWM &OCR3AL + +#define DIO6_PIN PINB4 +#define DIO6_RPORT PINB +#define DIO6_WPORT PORTB +#define DIO6_DDR DDRB +#define DIO6_PWM &OCR2AL + +#define DIO7_PIN PINB5 +#define DIO7_RPORT PINB +#define DIO7_WPORT PORTB +#define DIO7_DDR DDRB +#define DIO7_PWM &OCR1AL + +#define DIO8_PIN PINB6 +#define DIO8_RPORT PINB +#define DIO8_WPORT PORTB +#define DIO8_DDR DDRB +#define DIO8_PWM &OCR1BL + +#define DIO9_PIN PINB7 +#define DIO9_RPORT PINB +#define DIO9_WPORT PORTB +#define DIO9_DDR DDRB +#define DIO9_PWM &OCR0AL + +#define DIO10_PIN PINB1 +#define DIO10_RPORT PINB +#define DIO10_WPORT PORTB +#define DIO10_DDR DDRB +#define DIO10_PWM NULL + +#define DIO11_PIN PINB2 +#define DIO11_RPORT PINB +#define DIO11_WPORT PORTB +#define DIO11_DDR DDRB +#define DIO11_PWM NULL + +#define DIO12_PIN PINB3 +#define DIO12_RPORT PINB +#define DIO12_WPORT PORTB +#define DIO12_DDR DDRB +#define DIO12_PWM NULL + +#define DIO13_PIN PINE2 +#define DIO13_RPORT PINE +#define DIO13_WPORT PORTE +#define DIO13_DDR DDRE +#define DIO13_PWM NULL + +#define DIO14_PIN PINE6 +#define DIO14_RPORT PINE +#define DIO14_WPORT PORTE +#define DIO14_DDR DDRE +#define DIO14_PWM NULL + +#define DIO15_PIN PINE7 +#define DIO15_RPORT PINE +#define DIO15_WPORT PORTE +#define DIO15_DDR DDRE +#define DIO15_PWM NULL + +#define DIO16_PIN PINB0 +#define DIO16_RPORT PINB +#define DIO16_WPORT PORTB +#define DIO16_DDR DDRB +#define DIO16_PWM NULL + +#define DIO17_PIN PIND0 +#define DIO17_RPORT PIND +#define DIO17_WPORT PORTD +#define DIO17_DDR DDRD +#define DIO17_PWM NULL + +#define DIO18_PIN PIND1 +#define DIO18_RPORT PIND +#define DIO18_WPORT PORTD +#define DIO18_DDR DDRD +#define DIO18_PWM NULL + +#define DIO19_PIN PIND2 +#define DIO19_RPORT PIND +#define DIO19_WPORT PORTD +#define DIO19_DDR DDRD +#define DIO19_PWM NULL + +#define DIO20_PIN PIND3 +#define DIO20_RPORT PIND +#define DIO20_WPORT PORTD +#define DIO20_DDR DDRD +#define DIO20_PWM NULL + +#define DIO21_PIN PIND4 +#define DIO21_RPORT PIND +#define DIO21_WPORT PORTD +#define DIO21_DDR DDRD +#define DIO21_PWM NULL + +#define DIO22_PIN PIND5 +#define DIO22_RPORT PIND +#define DIO22_WPORT PORTD +#define DIO22_DDR DDRD +#define DIO22_PWM NULL + +#define DIO23_PIN PIND6 +#define DIO23_RPORT PIND +#define DIO23_WPORT PORTD +#define DIO23_DDR DDRD +#define DIO23_PWM NULL + +#define DIO24_PIN PIND7 +#define DIO24_RPORT PIND +#define DIO24_WPORT PORTD +#define DIO24_DDR DDRD +#define DIO24_PWM NULL + +#define DIO25_PIN PING0 +#define DIO25_RPORT PING +#define DIO25_WPORT PORTG +#define DIO25_DDR DDRG +#define DIO25_PWM NULL + +#define DIO26_PIN PING1 +#define DIO26_RPORT PING +#define DIO26_WPORT PORTG +#define DIO26_DDR DDRG +#define DIO26_PWM NULL + +#define DIO27_PIN PING2 +#define DIO27_RPORT PING +#define DIO27_WPORT PORTG +#define DIO27_DDR DDRG +#define DIO27_PWM NULL + +#define DIO28_PIN PING3 +#define DIO28_RPORT PING +#define DIO28_WPORT PORTG +#define DIO28_DDR DDRG +#define DIO28_PWM NULL + +#define DIO29_PIN PING4 +#define DIO29_RPORT PING +#define DIO29_WPORT PORTG +#define DIO29_DDR DDRG +#define DIO29_PWM NULL + +#define DIO30_PIN PINC0 +#define DIO30_RPORT PINC +#define DIO30_WPORT PORTC +#define DIO30_DDR DDRC +#define DIO30_PWM NULL + +#define DIO31_PIN PINC1 +#define DIO31_RPORT PINC +#define DIO31_WPORT PORTC +#define DIO31_DDR DDRC +#define DIO31_PWM NULL + +#define DIO32_PIN PINC2 +#define DIO32_RPORT PINC +#define DIO32_WPORT PORTC +#define DIO32_DDR DDRC +#define DIO32_PWM NULL + +#define DIO33_PIN PINC3 +#define DIO33_RPORT PINC +#define DIO33_WPORT PORTC +#define DIO33_DDR DDRC +#define DIO33_PWM NULL + +#define DIO34_PIN PINC4 +#define DIO34_RPORT PINC +#define DIO34_WPORT PORTC +#define DIO34_DDR DDRC +#define DIO34_PWM NULL + +#define DIO35_PIN PINC5 +#define DIO35_RPORT PINC +#define DIO35_WPORT PORTC +#define DIO35_DDR DDRC +#define DIO35_PWM NULL + +#define DIO36_PIN PINC6 +#define DIO36_RPORT PINC +#define DIO36_WPORT PORTC +#define DIO36_DDR DDRC +#define DIO36_PWM NULL + +#define DIO37_PIN PINC7 +#define DIO37_RPORT PINC +#define DIO37_WPORT PORTC +#define DIO37_DDR DDRC +#define DIO37_PWM NULL + +#define DIO38_PIN PINA0 +#define DIO38_RPORT PINA +#define DIO38_WPORT PORTA +#define DIO38_DDR DDRA +#define DIO38_PWM NULL + +#define DIO39_PIN PINA1 +#define DIO39_RPORT PINA +#define DIO39_WPORT PORTA +#define DIO39_DDR DDRA +#define DIO39_PWM NULL + +#define DIO40_PIN PINA2 +#define DIO40_RPORT PINA +#define DIO40_WPORT PORTA +#define DIO40_DDR DDRA +#define DIO40_PWM NULL + +#define DIO41_PIN PINA3 +#define DIO41_RPORT PINA +#define DIO41_WPORT PORTA +#define DIO41_DDR DDRA +#define DIO41_PWM NULL + +#define DIO42_PIN PINA4 +#define DIO42_RPORT PINA +#define DIO42_WPORT PORTA +#define DIO42_DDR DDRA +#define DIO42_PWM NULL + +#define DIO43_PIN PINA5 +#define DIO43_RPORT PINA +#define DIO43_WPORT PORTA +#define DIO43_DDR DDRA +#define DIO43_PWM NULL + +#define DIO44_PIN PINA6 +#define DIO44_RPORT PINA +#define DIO44_WPORT PORTA +#define DIO44_DDR DDRA +#define DIO44_PWM NULL + +#define DIO45_PIN PINA7 +#define DIO45_RPORT PINA +#define DIO45_WPORT PORTA +#define DIO45_DDR DDRA +#define DIO45_PWM NULL + +#define DIO46_PIN PINF0 +#define DIO46_RPORT PINF +#define DIO46_WPORT PORTF +#define DIO46_DDR DDRF +#define DIO46_PWM NULL + +#define DIO47_PIN PINF1 +#define DIO47_RPORT PINF +#define DIO47_WPORT PORTF +#define DIO47_DDR DDRF +#define DIO47_PWM NULL + +#define DIO48_PIN PINF2 +#define DIO48_RPORT PINF +#define DIO48_WPORT PORTF +#define DIO48_DDR DDRF +#define DIO48_PWM NULL + +#define DIO49_PIN PINF3 +#define DIO49_RPORT PINF +#define DIO49_WPORT PORTF +#define DIO49_DDR DDRF +#define DIO49_PWM NULL + +#define DIO50_PIN PINF4 +#define DIO50_RPORT PINF +#define DIO50_WPORT PORTF +#define DIO50_DDR DDRF +#define DIO50_PWM NULL + +#define DIO51_PIN PINF5 +#define DIO51_RPORT PINF +#define DIO51_WPORT PORTF +#define DIO51_DDR DDRF +#define DIO51_PWM NULL + +#define DIO52_PIN PINF6 +#define DIO52_RPORT PINF +#define DIO52_WPORT PORTF +#define DIO52_DDR DDRF +#define DIO52_PWM NULL + +#define DIO53_PIN PINF7 +#define DIO53_RPORT PINF +#define DIO53_WPORT PORTF +#define DIO53_DDR DDRF +#define DIO53_PWM NULL + +#undef PA0 +#define PA0_PIN PINA0 +#define PA0_RPORT PINA +#define PA0_WPORT PORTA +#define PA0_DDR DDRA +#define PA0_PWM NULL +#undef PA1 +#define PA1_PIN PINA1 +#define PA1_RPORT PINA +#define PA1_WPORT PORTA +#define PA1_DDR DDRA +#define PA1_PWM NULL +#undef PA2 +#define PA2_PIN PINA2 +#define PA2_RPORT PINA +#define PA2_WPORT PORTA +#define PA2_DDR DDRA +#define PA2_PWM NULL +#undef PA3 +#define PA3_PIN PINA3 +#define PA3_RPORT PINA +#define PA3_WPORT PORTA +#define PA3_DDR DDRA +#define PA3_PWM NULL +#undef PA4 +#define PA4_PIN PINA4 +#define PA4_RPORT PINA +#define PA4_WPORT PORTA +#define PA4_DDR DDRA +#define PA4_PWM NULL +#undef PA5 +#define PA5_PIN PINA5 +#define PA5_RPORT PINA +#define PA5_WPORT PORTA +#define PA5_DDR DDRA +#define PA5_PWM NULL +#undef PA6 +#define PA6_PIN PINA6 +#define PA6_RPORT PINA +#define PA6_WPORT PORTA +#define PA6_DDR DDRA +#define PA6_PWM NULL +#undef PA7 +#define PA7_PIN PINA7 +#define PA7_RPORT PINA +#define PA7_WPORT PORTA +#define PA7_DDR DDRA +#define PA7_PWM NULL + +#undef PB0 +#define PB0_PIN PINB0 +#define PB0_RPORT PINB +#define PB0_WPORT PORTB +#define PB0_DDR DDRB +#define PB0_PWM NULL +#undef PB1 +#define PB1_PIN PINB1 +#define PB1_RPORT PINB +#define PB1_WPORT PORTB +#define PB1_DDR DDRB +#define PB1_PWM NULL +#undef PB2 +#define PB2_PIN PINB2 +#define PB2_RPORT PINB +#define PB2_WPORT PORTB +#define PB2_DDR DDRB +#define PB2_PWM NULL +#undef PB3 +#define PB3_PIN PINB3 +#define PB3_RPORT PINB +#define PB3_WPORT PORTB +#define PB3_DDR DDRB +#define PB3_PWM NULL +#undef PB4 +#define PB4_PIN PINB4 +#define PB4_RPORT PINB +#define PB4_WPORT PORTB +#define PB4_DDR DDRB +#define PB4_PWM &OCR2A +#undef PB5 +#define PB5_PIN PINB5 +#define PB5_RPORT PINB +#define PB5_WPORT PORTB +#define PB5_DDR DDRB +#define PB5_PWM NULL +#undef PB6 +#define PB6_PIN PINB6 +#define PB6_RPORT PINB +#define PB6_WPORT PORTB +#define PB6_DDR DDRB +#define PB6_PWM NULL +#undef PB7 +#define PB7_PIN PINB7 +#define PB7_RPORT PINB +#define PB7_WPORT PORTB +#define PB7_DDR DDRB +#define PB7_PWM &OCR0A + +#undef PC0 +#define PC0_PIN PINC0 +#define PC0_RPORT PINC +#define PC0_WPORT PORTC +#define PC0_DDR DDRC +#define PC0_PWM NULL +#undef PC1 +#define PC1_PIN PINC1 +#define PC1_RPORT PINC +#define PC1_WPORT PORTC +#define PC1_DDR DDRC +#define PC1_PWM NULL +#undef PC2 +#define PC2_PIN PINC2 +#define PC2_RPORT PINC +#define PC2_WPORT PORTC +#define PC2_DDR DDRC +#define PC2_PWM NULL +#undef PC3 +#define PC3_PIN PINC3 +#define PC3_RPORT PINC +#define PC3_WPORT PORTC +#define PC3_DDR DDRC +#define PC3_PWM NULL +#undef PC4 +#define PC4_PIN PINC4 +#define PC4_RPORT PINC +#define PC4_WPORT PORTC +#define PC4_DDR DDRC +#define PC4_PWM NULL +#undef PC5 +#define PC5_PIN PINC5 +#define PC5_RPORT PINC +#define PC5_WPORT PORTC +#define PC5_DDR DDRC +#define PC5_PWM NULL +#undef PC6 +#define PC6_PIN PINC6 +#define PC6_RPORT PINC +#define PC6_WPORT PORTC +#define PC6_DDR DDRC +#define PC6_PWM NULL +#undef PC7 +#define PC7_PIN PINC7 +#define PC7_RPORT PINC +#define PC7_WPORT PORTC +#define PC7_DDR DDRC +#define PC7_PWM NULL + +#undef PD0 +#define PD0_PIN PIND0 +#define PD0_RPORT PIND +#define PD0_WPORT PORTD +#define PD0_DDR DDRD +#define PD0_PWM NULL +#undef PD1 +#define PD1_PIN PIND1 +#define PD1_RPORT PIND +#define PD1_WPORT PORTD +#define PD1_DDR DDRD +#define PD1_PWM NULL +#undef PD2 +#define PD2_PIN PIND2 +#define PD2_RPORT PIND +#define PD2_WPORT PORTD +#define PD2_DDR DDRD +#define PD2_PWM NULL +#undef PD3 +#define PD3_PIN PIND3 +#define PD3_RPORT PIND +#define PD3_WPORT PORTD +#define PD3_DDR DDRD +#define PD3_PWM NULL +#undef PD4 +#define PD4_PIN PIND4 +#define PD4_RPORT PIND +#define PD4_WPORT PORTD +#define PD4_DDR DDRD +#define PD4_PWM NULL +#undef PD5 +#define PD5_PIN PIND5 +#define PD5_RPORT PIND +#define PD5_WPORT PORTD +#define PD5_DDR DDRD +#define PD5_PWM NULL +#undef PD6 +#define PD6_PIN PIND6 +#define PD6_RPORT PIND +#define PD6_WPORT PORTD +#define PD6_DDR DDRD +#define PD6_PWM NULL +#undef PD7 +#define PD7_PIN PIND7 +#define PD7_RPORT PIND +#define PD7_WPORT PORTD +#define PD7_DDR DDRD +#define PD7_PWM NULL + +#undef PE0 +#define PE0_PIN PINE0 +#define PE0_RPORT PINE +#define PE0_WPORT PORTE +#define PE0_DDR DDRE +#define PE0_PWM NULL +#undef PE1 +#define PE1_PIN PINE1 +#define PE1_RPORT PINE +#define PE1_WPORT PORTE +#define PE1_DDR DDRE +#define PE1_PWM NULL +#undef PE2 +#define PE2_PIN PINE2 +#define PE2_RPORT PINE +#define PE2_WPORT PORTE +#define PE2_DDR DDRE +#define PE2_PWM NULL +#undef PE3 +#define PE3_PIN PINE3 +#define PE3_RPORT PINE +#define PE3_WPORT PORTE +#define PE3_DDR DDRE +#define PE3_PWM &OCR3AL +#undef PE4 +#define PE4_PIN PINE4 +#define PE4_RPORT PINE +#define PE4_WPORT PORTE +#define PE4_DDR DDRE +#define PE4_PWM &OCR3BL +#undef PE5 +#define PE5_PIN PINE5 +#define PE5_RPORT PINE +#define PE5_WPORT PORTE +#define PE5_DDR DDRE +#define PE5_PWM &OCR3CL +#undef PE6 +#define PE6_PIN PINE6 +#define PE6_RPORT PINE +#define PE6_WPORT PORTE +#define PE6_DDR DDRE +#define PE6_PWM NULL +#undef PE7 +#define PE7_PIN PINE7 +#define PE7_RPORT PINE +#define PE7_WPORT PORTE +#define PE7_DDR DDRE +#define PE7_PWM NULL + +#undef PF0 +#define PF0_PIN PINF0 +#define PF0_RPORT PINF +#define PF0_WPORT PORTF +#define PF0_DDR DDRF +#define PF0_PWM NULL +#undef PF1 +#define PF1_PIN PINF1 +#define PF1_RPORT PINF +#define PF1_WPORT PORTF +#define PF1_DDR DDRF +#define PF1_PWM NULL +#undef PF2 +#define PF2_PIN PINF2 +#define PF2_RPORT PINF +#define PF2_WPORT PORTF +#define PF2_DDR DDRF +#define PF2_PWM NULL +#undef PF3 +#define PF3_PIN PINF3 +#define PF3_RPORT PINF +#define PF3_WPORT PORTF +#define PF3_DDR DDRF +#define PF3_PWM NULL +#undef PF4 +#define PF4_PIN PINF4 +#define PF4_RPORT PINF +#define PF4_WPORT PORTF +#define PF4_DDR DDRF +#define PF4_PWM NULL +#undef PF5 +#define PF5_PIN PINF5 +#define PF5_RPORT PINF +#define PF5_WPORT PORTF +#define PF5_DDR DDRF +#define PF5_PWM NULL +#undef PF6 +#define PF6_PIN PINF6 +#define PF6_RPORT PINF +#define PF6_WPORT PORTF +#define PF6_DDR DDRF +#define PF6_PWM NULL +#undef PF7 +#define PF7_PIN PINF7 +#define PF7_RPORT PINF +#define PF7_WPORT PORTF +#define PF7_DDR DDRF +#define PF7_PWM NULL + +#undef PG0 +#define PG0_PIN PING0 +#define PG0_RPORT PING +#define PG0_WPORT PORTG +#define PG0_DDR DDRG +#define PG0_PWM NULL +#undef PG1 +#define PG1_PIN PING1 +#define PG1_RPORT PING +#define PG1_WPORT PORTG +#define PG1_DDR DDRG +#define PG1_PWM NULL +#undef PG2 +#define PG2_PIN PING2 +#define PG2_RPORT PING +#define PG2_WPORT PORTG +#define PG2_DDR DDRG +#define PG2_PWM NULL +#undef PG3 +#define PG3_PIN PING3 +#define PG3_RPORT PING +#define PG3_WPORT PORTG +#define PG3_DDR DDRG +#define PG3_PWM NULL +#undef PG4 +#define PG4_PIN PING4 +#define PG4_RPORT PING +#define PG4_WPORT PORTG +#define PG4_DDR DDRG +#define PG4_PWM NULL +#undef PG5 +#define PG5_PIN PING5 +#define PG5_RPORT PING +#define PG5_WPORT PORTG +#define PG5_DDR DDRG +#define PG5_PWM &OCR0B + +#endif // _FASTIO_1281 diff --git a/trunk/Arduino/Marlin_1.1.6/fastio_168.h b/trunk/Arduino/Marlin_1.1.6/fastio_168.h new file mode 100644 index 00000000..4ee67a32 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/fastio_168.h @@ -0,0 +1,362 @@ +/** + * 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 . + * + */ + +/** + * Pin mapping for the 168, 328, and 328P + * + * 168 08 09 10 11 12 13 14 15 16 17 18 19 20 21 00 01 02 03 04 05 06 07 + * Port B0 B1 B2 B3 B4 B5 C0 C1 C2 C3 C4 C5 C6 C7 D0 D1 D2 D3 D4 D5 D6 D7 + * Marlin 08 09 10 11 12 13 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 + */ + +#ifndef _FASTIO_168 +#define _FASTIO_168 + +#include "fastio.h" + +#define DEBUG_LED AIO5 + +// UART +#define RXD DIO0 +#define TXD DIO1 + +// SPI +#define SCK DIO13 +#define MISO DIO12 +#define MOSI DIO11 +#define SS DIO10 + +// TWI (I2C) +#define SCL AIO5 +#define SDA AIO4 + +// Timers and PWM +#define OC0A DIO6 +#define OC0B DIO5 +#define OC1A DIO9 +#define OC1B DIO10 +#define OC2A DIO11 +#define OC2B DIO3 + +// Digital I/O + +#define DIO0_PIN PIND0 +#define DIO0_RPORT PIND +#define DIO0_WPORT PORTD +#define DIO0_DDR DDRD +#define DIO0_PWM NULL + +#define DIO1_PIN PIND1 +#define DIO1_RPORT PIND +#define DIO1_WPORT PORTD +#define DIO1_DDR DDRD +#define DIO1_PWM NULL + +#define DIO2_PIN PIND2 +#define DIO2_RPORT PIND +#define DIO2_WPORT PORTD +#define DIO2_DDR DDRD +#define DIO2_PWM NULL + +#define DIO3_PIN PIND3 +#define DIO3_RPORT PIND +#define DIO3_WPORT PORTD +#define DIO3_DDR DDRD +#define DIO3_PWM &OCR2B + +#define DIO4_PIN PIND4 +#define DIO4_RPORT PIND +#define DIO4_WPORT PORTD +#define DIO4_DDR DDRD +#define DIO4_PWM NULL + +#define DIO5_PIN PIND5 +#define DIO5_RPORT PIND +#define DIO5_WPORT PORTD +#define DIO5_DDR DDRD +#define DIO5_PWM &OCR0B + +#define DIO6_PIN PIND6 +#define DIO6_RPORT PIND +#define DIO6_WPORT PORTD +#define DIO6_DDR DDRD +#define DIO6_PWM &OCR0A + +#define DIO7_PIN PIND7 +#define DIO7_RPORT PIND +#define DIO7_WPORT PORTD +#define DIO7_DDR DDRD +#define DIO7_PWM NULL + +#define DIO8_PIN PINB0 +#define DIO8_RPORT PINB +#define DIO8_WPORT PORTB +#define DIO8_DDR DDRB +#define DIO8_PWM NULL + +#define DIO9_PIN PINB1 +#define DIO9_RPORT PINB +#define DIO9_WPORT PORTB +#define DIO9_DDR DDRB +#define DIO9_PWM NULL + +#define DIO10_PIN PINB2 +#define DIO10_RPORT PINB +#define DIO10_WPORT PORTB +#define DIO10_DDR DDRB +#define DIO10_PWM NULL + +#define DIO11_PIN PINB3 +#define DIO11_RPORT PINB +#define DIO11_WPORT PORTB +#define DIO11_DDR DDRB +#define DIO11_PWM &OCR2A + +#define DIO12_PIN PINB4 +#define DIO12_RPORT PINB +#define DIO12_WPORT PORTB +#define DIO12_DDR DDRB +#define DIO12_PWM NULL + +#define DIO13_PIN PINB5 +#define DIO13_RPORT PINB +#define DIO13_WPORT PORTB +#define DIO13_DDR DDRB +#define DIO13_PWM NULL + +#define DIO14_PIN PINC0 +#define DIO14_RPORT PINC +#define DIO14_WPORT PORTC +#define DIO14_DDR DDRC +#define DIO14_PWM NULL + +#define DIO15_PIN PINC1 +#define DIO15_RPORT PINC +#define DIO15_WPORT PORTC +#define DIO15_DDR DDRC +#define DIO15_PWM NULL + +#define DIO16_PIN PINC2 +#define DIO16_RPORT PINC +#define DIO16_WPORT PORTC +#define DIO16_DDR DDRC +#define DIO16_PWM NULL + +#define DIO17_PIN PINC3 +#define DIO17_RPORT PINC +#define DIO17_WPORT PORTC +#define DIO17_DDR DDRC +#define DIO17_PWM NULL + +#define DIO18_PIN PINC4 +#define DIO18_RPORT PINC +#define DIO18_WPORT PORTC +#define DIO18_DDR DDRC +#define DIO18_PWM NULL + +#define DIO19_PIN PINC5 +#define DIO19_RPORT PINC +#define DIO19_WPORT PORTC +#define DIO19_DDR DDRC +#define DIO19_PWM NULL + +#define DIO20_PIN PINC6 +#define DIO20_RPORT PINC +#define DIO20_WPORT PORTC +#define DIO20_DDR DDRC +#define DIO20_PWM NULL + +#define DIO21_PIN PINC7 +#define DIO21_RPORT PINC +#define DIO21_WPORT PORTC +#define DIO21_DDR DDRC +#define DIO21_PWM NULL + +#undef PB0 +#define PB0_PIN PINB0 +#define PB0_RPORT PINB +#define PB0_WPORT PORTB +#define PB0_DDR DDRB +#define PB0_PWM NULL + +#undef PB1 +#define PB1_PIN PINB1 +#define PB1_RPORT PINB +#define PB1_WPORT PORTB +#define PB1_DDR DDRB +#define PB1_PWM NULL + +#undef PB2 +#define PB2_PIN PINB2 +#define PB2_RPORT PINB +#define PB2_WPORT PORTB +#define PB2_DDR DDRB +#define PB2_PWM NULL + +#undef PB3 +#define PB3_PIN PINB3 +#define PB3_RPORT PINB +#define PB3_WPORT PORTB +#define PB3_DDR DDRB +#define PB3_PWM &OCR2A + +#undef PB4 +#define PB4_PIN PINB4 +#define PB4_RPORT PINB +#define PB4_WPORT PORTB +#define PB4_DDR DDRB +#define PB4_PWM NULL + +#undef PB5 +#define PB5_PIN PINB5 +#define PB5_RPORT PINB +#define PB5_WPORT PORTB +#define PB5_DDR DDRB +#define PB5_PWM NULL + +#undef PB6 +#define PB6_PIN PINB6 +#define PB6_RPORT PINB +#define PB6_WPORT PORTB +#define PB6_DDR DDRB +#define PB6_PWM NULL + +#undef PB7 +#define PB7_PIN PINB7 +#define PB7_RPORT PINB +#define PB7_WPORT PORTB +#define PB7_DDR DDRB +#define PB7_PWM NULL + +#undef PC0 +#define PC0_PIN PINC0 +#define PC0_RPORT PINC +#define PC0_WPORT PORTC +#define PC0_DDR DDRC +#define PC0_PWM NULL + +#undef PC1 +#define PC1_PIN PINC1 +#define PC1_RPORT PINC +#define PC1_WPORT PORTC +#define PC1_DDR DDRC +#define PC1_PWM NULL + +#undef PC2 +#define PC2_PIN PINC2 +#define PC2_RPORT PINC +#define PC2_WPORT PORTC +#define PC2_DDR DDRC +#define PC2_PWM NULL + +#undef PC3 +#define PC3_PIN PINC3 +#define PC3_RPORT PINC +#define PC3_WPORT PORTC +#define PC3_DDR DDRC +#define PC3_PWM NULL + +#undef PC4 +#define PC4_PIN PINC4 +#define PC4_RPORT PINC +#define PC4_WPORT PORTC +#define PC4_DDR DDRC +#define PC4_PWM NULL + +#undef PC5 +#define PC5_PIN PINC5 +#define PC5_RPORT PINC +#define PC5_WPORT PORTC +#define PC5_DDR DDRC +#define PC5_PWM NULL + +#undef PC6 +#define PC6_PIN PINC6 +#define PC6_RPORT PINC +#define PC6_WPORT PORTC +#define PC6_DDR DDRC +#define PC6_PWM NULL + +#undef PC7 +#define PC7_PIN PINC7 +#define PC7_RPORT PINC +#define PC7_WPORT PORTC +#define PC7_DDR DDRC +#define PC7_PWM NULL + +#undef PD0 +#define PD0_PIN PIND0 +#define PD0_RPORT PIND +#define PD0_WPORT PORTD +#define PD0_DDR DDRD +#define PD0_PWM NULL + +#undef PD1 +#define PD1_PIN PIND1 +#define PD1_RPORT PIND +#define PD1_WPORT PORTD +#define PD1_DDR DDRD +#define PD1_PWM NULL + +#undef PD2 +#define PD2_PIN PIND2 +#define PD2_RPORT PIND +#define PD2_WPORT PORTD +#define PD2_DDR DDRD +#define PD2_PWM NULL + +#undef PD3 +#define PD3_PIN PIND3 +#define PD3_RPORT PIND +#define PD3_WPORT PORTD +#define PD3_DDR DDRD +#define PD3_PWM &OCR2B + +#undef PD4 +#define PD4_PIN PIND4 +#define PD4_RPORT PIND +#define PD4_WPORT PORTD +#define PD4_DDR DDRD +#define PD4_PWM NULL + +#undef PD5 +#define PD5_PIN PIND5 +#define PD5_RPORT PIND +#define PD5_WPORT PORTD +#define PD5_DDR DDRD +#define PD5_PWM &OCR0B + +#undef PD6 +#define PD6_PIN PIND6 +#define PD6_RPORT PIND +#define PD6_WPORT PORTD +#define PD6_DDR DDRD +#define PD6_PWM &OCR0A + +#undef PD7 +#define PD7_PIN PIND7 +#define PD7_RPORT PIND +#define PD7_WPORT PORTD +#define PD7_DDR DDRD +#define PD7_PWM NULL + +#endif // _FASTIO_168 diff --git a/trunk/Arduino/Marlin_1.1.6/fastio_644.h b/trunk/Arduino/Marlin_1.1.6/fastio_644.h new file mode 100644 index 00000000..6465738d --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/fastio_644.h @@ -0,0 +1,531 @@ +/** + * 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 . + * + */ + +/** + * Pin mapping for the 644, 644p, 644pa, and 1284p + * + * 644p 31 30 29 28 27 26 25 24 00 01 02 03 04 05 06 07 16 17 18 19 20 21 22 23 08 09 10 11 12 13 14 15 + * Port A0 A1 A2 A3 A4 A5 A6 A7 B0 B1 B2 B3 B4 B5 B6 B7 C0 C1 C2 C3 C4 C5 C6 C7 D0 D1 D2 D3 D4 D5 D6 D7 + * Marlin 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 + */ + +#ifndef _FASTIO_644 +#define _FASTIO_644 + +#include "fastio.h" + +#define DEBUG_LED DIO0 + +// UART +#define RXD DIO8 +#define TXD DIO9 +#define RXD0 DIO8 +#define TXD0 DIO9 + +#define RXD1 DIO10 +#define TXD1 DIO11 + +// SPI +#define SCK DIO7 +#define MISO DIO6 +#define MOSI DIO5 +#define SS DIO4 + +// TWI (I2C) +#define SCL DIO16 +#define SDA DIO17 + +// Timers and PWM +#define OC0A DIO3 +#define OC0B DIO4 +#define OC1A DIO13 +#define OC1B DIO12 +#define OC2A DIO15 +#define OC2B DIO14 + +// Digital I/O + +#define DIO0_PIN PINB0 +#define DIO0_RPORT PINB +#define DIO0_WPORT PORTB +#define DIO0_DDR DDRB +#define DIO0_PWM NULL + +#define DIO1_PIN PINB1 +#define DIO1_RPORT PINB +#define DIO1_WPORT PORTB +#define DIO1_DDR DDRB +#define DIO1_PWM NULL + +#define DIO2_PIN PINB2 +#define DIO2_RPORT PINB +#define DIO2_WPORT PORTB +#define DIO2_DDR DDRB +#define DIO2_PWM NULL + +#define DIO3_PIN PINB3 +#define DIO3_RPORT PINB +#define DIO3_WPORT PORTB +#define DIO3_DDR DDRB +#define DIO3_PWM OCR0A + +#define DIO4_PIN PINB4 +#define DIO4_RPORT PINB +#define DIO4_WPORT PORTB +#define DIO4_DDR DDRB +#define DIO4_PWM OCR0B + +#define DIO5_PIN PINB5 +#define DIO5_RPORT PINB +#define DIO5_WPORT PORTB +#define DIO5_DDR DDRB +#define DIO5_PWM NULL + +#define DIO6_PIN PINB6 +#define DIO6_RPORT PINB +#define DIO6_WPORT PORTB +#define DIO6_DDR DDRB +#define DIO6_PWM NULL + +#define DIO7_PIN PINB7 +#define DIO7_RPORT PINB +#define DIO7_WPORT PORTB +#define DIO7_DDR DDRB +#define DIO7_PWM NULL + +#define DIO8_PIN PIND0 +#define DIO8_RPORT PIND +#define DIO8_WPORT PORTD +#define DIO8_DDR DDRD +#define DIO8_PWM NULL + +#define DIO9_PIN PIND1 +#define DIO9_RPORT PIND +#define DIO9_WPORT PORTD +#define DIO9_DDR DDRD +#define DIO9_PWM NULL + +#define DIO10_PIN PIND2 +#define DIO10_RPORT PIND +#define DIO10_WPORT PORTD +#define DIO10_DDR DDRD +#define DIO10_PWM NULL + +#define DIO11_PIN PIND3 +#define DIO11_RPORT PIND +#define DIO11_WPORT PORTD +#define DIO11_DDR DDRD +#define DIO11_PWM NULL + +#define DIO12_PIN PIND4 +#define DIO12_RPORT PIND +#define DIO12_WPORT PORTD +#define DIO12_DDR DDRD +#define DIO12_PWM OCR1B + +#define DIO13_PIN PIND5 +#define DIO13_RPORT PIND +#define DIO13_WPORT PORTD +#define DIO13_DDR DDRD +#define DIO13_PWM OCR1A + +#define DIO14_PIN PIND6 +#define DIO14_RPORT PIND +#define DIO14_WPORT PORTD +#define DIO14_DDR DDRD +#define DIO14_PWM OCR2B + +#define DIO15_PIN PIND7 +#define DIO15_RPORT PIND +#define DIO15_WPORT PORTD +#define DIO15_DDR DDRD +#define DIO15_PWM OCR2A + +#define DIO16_PIN PINC0 +#define DIO16_RPORT PINC +#define DIO16_WPORT PORTC +#define DIO16_DDR DDRC +#define DIO16_PWM NULL + +#define DIO17_PIN PINC1 +#define DIO17_RPORT PINC +#define DIO17_WPORT PORTC +#define DIO17_DDR DDRC +#define DIO17_PWM NULL + +#define DIO18_PIN PINC2 +#define DIO18_RPORT PINC +#define DIO18_WPORT PORTC +#define DIO18_DDR DDRC +#define DIO18_PWM NULL + +#define DIO19_PIN PINC3 +#define DIO19_RPORT PINC +#define DIO19_WPORT PORTC +#define DIO19_DDR DDRC +#define DIO19_PWM NULL + +#define DIO20_PIN PINC4 +#define DIO20_RPORT PINC +#define DIO20_WPORT PORTC +#define DIO20_DDR DDRC +#define DIO20_PWM NULL + +#define DIO21_PIN PINC5 +#define DIO21_RPORT PINC +#define DIO21_WPORT PORTC +#define DIO21_DDR DDRC +#define DIO21_PWM NULL + +#define DIO22_PIN PINC6 +#define DIO22_RPORT PINC +#define DIO22_WPORT PORTC +#define DIO22_DDR DDRC +#define DIO22_PWM NULL + +#define DIO23_PIN PINC7 +#define DIO23_RPORT PINC +#define DIO23_WPORT PORTC +#define DIO23_DDR DDRC +#define DIO23_PWM NULL + +#define DIO24_PIN PINA7 +#define DIO24_RPORT PINA +#define DIO24_WPORT PORTA +#define DIO24_DDR DDRA +#define DIO24_PWM NULL + +#define DIO25_PIN PINA6 +#define DIO25_RPORT PINA +#define DIO25_WPORT PORTA +#define DIO25_DDR DDRA +#define DIO25_PWM NULL + +#define DIO26_PIN PINA5 +#define DIO26_RPORT PINA +#define DIO26_WPORT PORTA +#define DIO26_DDR DDRA +#define DIO26_PWM NULL + +#define DIO27_PIN PINA4 +#define DIO27_RPORT PINA +#define DIO27_WPORT PORTA +#define DIO27_DDR DDRA +#define DIO27_PWM NULL + +#define DIO28_PIN PINA3 +#define DIO28_RPORT PINA +#define DIO28_WPORT PORTA +#define DIO28_DDR DDRA +#define DIO28_PWM NULL + +#define DIO29_PIN PINA2 +#define DIO29_RPORT PINA +#define DIO29_WPORT PORTA +#define DIO29_DDR DDRA +#define DIO29_PWM NULL + +#define DIO30_PIN PINA1 +#define DIO30_RPORT PINA +#define DIO30_WPORT PORTA +#define DIO30_DDR DDRA +#define DIO30_PWM NULL + +#define DIO31_PIN PINA0 +#define DIO31_RPORT PINA +#define DIO31_WPORT PORTA +#define DIO31_DDR DDRA +#define DIO31_PWM NULL + +#define AIO0_PIN PINA0 +#define AIO0_RPORT PINA +#define AIO0_WPORT PORTA +#define AIO0_DDR DDRA +#define AIO0_PWM NULL + +#define AIO1_PIN PINA1 +#define AIO1_RPORT PINA +#define AIO1_WPORT PORTA +#define AIO1_DDR DDRA +#define AIO1_PWM NULL + +#define AIO2_PIN PINA2 +#define AIO2_RPORT PINA +#define AIO2_WPORT PORTA +#define AIO2_DDR DDRA +#define AIO2_PWM NULL + +#define AIO3_PIN PINA3 +#define AIO3_RPORT PINA +#define AIO3_WPORT PORTA +#define AIO3_DDR DDRA +#define AIO3_PWM NULL + +#define AIO4_PIN PINA4 +#define AIO4_RPORT PINA +#define AIO4_WPORT PORTA +#define AIO4_DDR DDRA +#define AIO4_PWM NULL + +#define AIO5_PIN PINA5 +#define AIO5_RPORT PINA +#define AIO5_WPORT PORTA +#define AIO5_DDR DDRA +#define AIO5_PWM NULL + +#define AIO6_PIN PINA6 +#define AIO6_RPORT PINA +#define AIO6_WPORT PORTA +#define AIO6_DDR DDRA +#define AIO6_PWM NULL + +#define AIO7_PIN PINA7 +#define AIO7_RPORT PINA +#define AIO7_WPORT PORTA +#define AIO7_DDR DDRA +#define AIO7_PWM NULL + +#undef PA0 +#define PA0_PIN PINA0 +#define PA0_RPORT PINA +#define PA0_WPORT PORTA +#define PA0_DDR DDRA +#define PA0_PWM NULL + +#undef PA1 +#define PA1_PIN PINA1 +#define PA1_RPORT PINA +#define PA1_WPORT PORTA +#define PA1_DDR DDRA +#define PA1_PWM NULL + +#undef PA2 +#define PA2_PIN PINA2 +#define PA2_RPORT PINA +#define PA2_WPORT PORTA +#define PA2_DDR DDRA +#define PA2_PWM NULL + +#undef PA3 +#define PA3_PIN PINA3 +#define PA3_RPORT PINA +#define PA3_WPORT PORTA +#define PA3_DDR DDRA +#define PA3_PWM NULL + +#undef PA4 +#define PA4_PIN PINA4 +#define PA4_RPORT PINA +#define PA4_WPORT PORTA +#define PA4_DDR DDRA +#define PA4_PWM NULL + +#undef PA5 +#define PA5_PIN PINA5 +#define PA5_RPORT PINA +#define PA5_WPORT PORTA +#define PA5_DDR DDRA +#define PA5_PWM NULL + +#undef PA6 +#define PA6_PIN PINA6 +#define PA6_RPORT PINA +#define PA6_WPORT PORTA +#define PA6_DDR DDRA +#define PA6_PWM NULL + +#undef PA7 +#define PA7_PIN PINA7 +#define PA7_RPORT PINA +#define PA7_WPORT PORTA +#define PA7_DDR DDRA +#define PA7_PWM NULL + +#undef PB0 +#define PB0_PIN PINB0 +#define PB0_RPORT PINB +#define PB0_WPORT PORTB +#define PB0_DDR DDRB +#define PB0_PWM NULL + +#undef PB1 +#define PB1_PIN PINB1 +#define PB1_RPORT PINB +#define PB1_WPORT PORTB +#define PB1_DDR DDRB +#define PB1_PWM NULL + +#undef PB2 +#define PB2_PIN PINB2 +#define PB2_RPORT PINB +#define PB2_WPORT PORTB +#define PB2_DDR DDRB +#define PB2_PWM NULL + +#undef PB3 +#define PB3_PIN PINB3 +#define PB3_RPORT PINB +#define PB3_WPORT PORTB +#define PB3_DDR DDRB +#define PB3_PWM OCR0A + +#undef PB4 +#define PB4_PIN PINB4 +#define PB4_RPORT PINB +#define PB4_WPORT PORTB +#define PB4_DDR DDRB +#define PB4_PWM OCR0B + +#undef PB5 +#define PB5_PIN PINB5 +#define PB5_RPORT PINB +#define PB5_WPORT PORTB +#define PB5_DDR DDRB +#define PB5_PWM NULL + +#undef PB6 +#define PB6_PIN PINB6 +#define PB6_RPORT PINB +#define PB6_WPORT PORTB +#define PB6_DDR DDRB +#define PB6_PWM NULL + +#undef PB7 +#define PB7_PIN PINB7 +#define PB7_RPORT PINB +#define PB7_WPORT PORTB +#define PB7_DDR DDRB +#define PB7_PWM NULL + +#undef PC0 +#define PC0_PIN PINC0 +#define PC0_RPORT PINC +#define PC0_WPORT PORTC +#define PC0_DDR DDRC +#define PC0_PWM NULL + +#undef PC1 +#define PC1_PIN PINC1 +#define PC1_RPORT PINC +#define PC1_WPORT PORTC +#define PC1_DDR DDRC +#define PC1_PWM NULL + +#undef PC2 +#define PC2_PIN PINC2 +#define PC2_RPORT PINC +#define PC2_WPORT PORTC +#define PC2_DDR DDRC +#define PC2_PWM NULL + +#undef PC3 +#define PC3_PIN PINC3 +#define PC3_RPORT PINC +#define PC3_WPORT PORTC +#define PC3_DDR DDRC +#define PC3_PWM NULL + +#undef PC4 +#define PC4_PIN PINC4 +#define PC4_RPORT PINC +#define PC4_WPORT PORTC +#define PC4_DDR DDRC +#define PC4_PWM NULL + +#undef PC5 +#define PC5_PIN PINC5 +#define PC5_RPORT PINC +#define PC5_WPORT PORTC +#define PC5_DDR DDRC +#define PC5_PWM NULL + +#undef PC6 +#define PC6_PIN PINC6 +#define PC6_RPORT PINC +#define PC6_WPORT PORTC +#define PC6_DDR DDRC +#define PC6_PWM NULL + +#undef PC7 +#define PC7_PIN PINC7 +#define PC7_RPORT PINC +#define PC7_WPORT PORTC +#define PC7_DDR DDRC +#define PC7_PWM NULL + +#undef PD0 +#define PD0_PIN PIND0 +#define PD0_RPORT PIND +#define PD0_WPORT PORTD +#define PD0_DDR DDRD +#define PD0_PWM NULL + +#undef PD1 +#define PD1_PIN PIND1 +#define PD1_RPORT PIND +#define PD1_WPORT PORTD +#define PD1_DDR DDRD +#define PD1_PWM NULL + +#undef PD2 +#define PD2_PIN PIND2 +#define PD2_RPORT PIND +#define PD2_WPORT PORTD +#define PD2_DDR DDRD +#define PD2_PWM NULL + +#undef PD3 +#define PD3_PIN PIND3 +#define PD3_RPORT PIND +#define PD3_WPORT PORTD +#define PD3_DDR DDRD +#define PD3_PWM NULL + +#undef PD4 +#define PD4_PIN PIND4 +#define PD4_RPORT PIND +#define PD4_WPORT PORTD +#define PD4_DDR DDRD +#define PD4_PWM NULL + +#undef PD5 +#define PD5_PIN PIND5 +#define PD5_RPORT PIND +#define PD5_WPORT PORTD +#define PD5_DDR DDRD +#define PD5_PWM NULL + +#undef PD6 +#define PD6_PIN PIND6 +#define PD6_RPORT PIND +#define PD6_WPORT PORTD +#define PD6_DDR DDRD +#define PD6_PWM OCR2B + +#undef PD7 +#define PD7_PIN PIND7 +#define PD7_RPORT PIND +#define PD7_WPORT PORTD +#define PD7_DDR DDRD +#define PD7_PWM OCR2A + +#endif // _FASTIO_644 diff --git a/trunk/Arduino/Marlin_1.1.6/fastio_AT90USB.h b/trunk/Arduino/Marlin_1.1.6/fastio_AT90USB.h new file mode 100644 index 00000000..68463e18 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/fastio_AT90USB.h @@ -0,0 +1,702 @@ +/** + * 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 . + * + */ + +/** + * Pin mapping (Teensy) for AT90USB646, 647, 1286, and 1287 + * + * AT90USB 51 50 49 48 47 46 45 44 10 11 12 13 14 15 16 17 35 36 37 38 39 40 41 42 25 26 27 28 29 30 31 32 33 34 43 09 18 19 01 02 61 60 59 58 57 56 55 54 + * > Teensy 28 29 30 31 32 33 34 35 20 21 22 23 24 25 26 27 10 11 12 13 14 15 16 17 00 01 02 03 04 05 06 07 08 09(46*47)36 37 18 19 38 39 40 41 42 43 44 45 + * Port A0 A1 A2 A3 A4 A5 A6 A7 B0 B1 B2 B3 B4 B5 B6 B7 C0 C1 C2 C3 C4 C5 C6 C7 D0 D1 D2 D3 D4 D5 D6 D7 E0 E1 E2 E3 E4 E5 E6 E7 F0 F1 F2 F3 F4 F5 F6 F7 + * The pins 46 and 47 are not supported by Teensyduino, but are supported below as E2 and E3 + */ + +#ifndef _FASTIO_AT90USB +#define _FASTIO_AT90USB + +#include "fastio.h" + +// change for your board +#define DEBUG_LED DIO31 /* led D5 red */ + +// SPI +#define SCK DIO21 // 9 +#define MISO DIO23 // 11 +#define MOSI DIO22 // 10 +#define SS DIO20 // 8 + +// Digital I/O + +#define DIO0_PIN PIND0 +#define DIO0_RPORT PIND +#define DIO0_WPORT PORTD +#define DIO0_PWM NULL +#define DIO0_DDR DDRD + +#define DIO1_PIN PIND1 +#define DIO1_RPORT PIND +#define DIO1_WPORT PORTD +#define DIO1_PWM NULL +#define DIO1_DDR DDRD + +#define DIO2_PIN PIND2 +#define DIO2_RPORT PIND +#define DIO2_WPORT PORTD +#define DIO2_PWM NULL +#define DIO2_DDR DDRD + +#define DIO3_PIN PIND3 +#define DIO3_RPORT PIND +#define DIO3_WPORT PORTD +#define DIO3_PWM NULL +#define DIO3_DDR DDRD + +#define DIO4_PIN PIND4 +#define DIO4_RPORT PIND +#define DIO4_WPORT PORTD +#define DIO4_PWM NULL +#define DIO4_DDR DDRD + +#define DIO5_PIN PIND5 +#define DIO5_RPORT PIND +#define DIO5_WPORT PORTD +#define DIO5_PWM NULL +#define DIO5_DDR DDRD + +#define DIO6_PIN PIND6 +#define DIO6_RPORT PIND +#define DIO6_WPORT PORTD +#define DIO6_PWM NULL +#define DIO6_DDR DDRD + +#define DIO7_PIN PIND7 +#define DIO7_RPORT PIND +#define DIO7_WPORT PORTD +#define DIO7_PWM NULL +#define DIO7_DDR DDRD + +#define DIO8_PIN PINE0 +#define DIO8_RPORT PINE +#define DIO8_WPORT PORTE +#define DIO8_PWM NULL +#define DIO8_DDR DDRE + +#define DIO9_PIN PINE1 +#define DIO9_RPORT PINE +#define DIO9_WPORT PORTE +#define DIO9_PWM NULL +#define DIO9_DDR DDRE + +#define DIO10_PIN PINC0 +#define DIO10_RPORT PINC +#define DIO10_WPORT PORTC +#define DIO10_PWM NULL +#define DIO10_DDR DDRC + +#define DIO11_PIN PINC1 +#define DIO11_RPORT PINC +#define DIO11_WPORT PORTC +#define DIO11_PWM NULL +#define DIO11_DDR DDRC + +#define DIO12_PIN PINC2 +#define DIO12_RPORT PINC +#define DIO12_WPORT PORTC +#define DIO12_PWM NULL +#define DIO12_DDR DDRC + +#define DIO13_PIN PINC3 +#define DIO13_RPORT PINC +#define DIO13_WPORT PORTC +#define DIO13_PWM NULL +#define DIO13_DDR DDRC + +#define DIO14_PIN PINC4 +#define DIO14_RPORT PINC +#define DIO14_WPORT PORTC +#define DIO14_PWM NULL +#define DIO14_DDR DDRC + +#define DIO15_PIN PINC5 +#define DIO15_RPORT PINC +#define DIO15_WPORT PORTC +#define DIO15_PWM NULL +#define DIO15_DDR DDRC + +#define DIO16_PIN PINC6 +#define DIO16_RPORT PINC +#define DIO16_WPORT PORTC +#define DIO16_PWM NULL +#define DIO16_DDR DDRC + +#define DIO17_PIN PINC7 +#define DIO17_RPORT PINC +#define DIO17_WPORT PORTC +#define DIO17_PWM NULL +#define DIO17_DDR DDRC + +#define DIO18_PIN PINE6 +#define DIO18_RPORT PINE +#define DIO18_WPORT PORTE +#define DIO18_PWM NULL +#define DIO18_DDR DDRE + +#define DIO19_PIN PINE7 +#define DIO19_RPORT PINE +#define DIO19_WPORT PORTE +#define DIO19_PWM NULL +#define DIO19_DDR DDRE + +#define DIO20_PIN PINB0 +#define DIO20_RPORT PINB +#define DIO20_WPORT PORTB +#define DIO20_PWM NULL +#define DIO20_DDR DDRB + +#define DIO21_PIN PINB1 +#define DIO21_RPORT PINB +#define DIO21_WPORT PORTB +#define DIO21_PWM NULL +#define DIO21_DDR DDRB + +#define DIO22_PIN PINB2 +#define DIO22_RPORT PINB +#define DIO22_WPORT PORTB +#define DIO22_PWM NULL +#define DIO22_DDR DDRB + +#define DIO23_PIN PINB3 +#define DIO23_RPORT PINB +#define DIO23_WPORT PORTB +#define DIO23_PWM NULL +#define DIO23_DDR DDRB + +#define DIO24_PIN PINB4 +#define DIO24_RPORT PINB +#define DIO24_WPORT PORTB +#define DIO24_PWM NULL +#define DIO24_DDR DDRB + +#define DIO25_PIN PINB5 +#define DIO25_RPORT PINB +#define DIO25_WPORT PORTB +#define DIO25_PWM NULL +#define DIO25_DDR DDRB + +#define DIO26_PIN PINB6 +#define DIO26_RPORT PINB +#define DIO26_WPORT PORTB +#define DIO26_PWM NULL +#define DIO26_DDR DDRB + +#define DIO27_PIN PINB7 +#define DIO27_RPORT PINB +#define DIO27_WPORT PORTB +#define DIO27_PWM NULL +#define DIO27_DDR DDRB + +#define DIO28_PIN PINA0 +#define DIO28_RPORT PINA +#define DIO28_WPORT PORTA +#define DIO28_PWM NULL +#define DIO28_DDR DDRA + +#define DIO29_PIN PINA1 +#define DIO29_RPORT PINA +#define DIO29_WPORT PORTA +#define DIO29_PWM NULL +#define DIO29_DDR DDRA + +#define DIO30_PIN PINA2 +#define DIO30_RPORT PINA +#define DIO30_WPORT PORTA +#define DIO30_PWM NULL +#define DIO30_DDR DDRA + +#define DIO31_PIN PINA3 +#define DIO31_RPORT PINA +#define DIO31_WPORT PORTA +#define DIO31_PWM NULL +#define DIO31_DDR DDRA + +#define DIO32_PIN PINA4 +#define DIO32_RPORT PINA +#define DIO32_WPORT PORTA +#define DIO32_PWM NULL +#define DIO32_DDR DDRA + +#define DIO33_PIN PINA5 +#define DIO33_RPORT PINA +#define DIO33_WPORT PORTA +#define DIO33_PWM NULL +#define DIO33_DDR DDRA + +#define DIO34_PIN PINA6 +#define DIO34_RPORT PINA +#define DIO34_WPORT PORTA +#define DIO34_PWM NULL +#define DIO34_DDR DDRA + +#define DIO35_PIN PINA7 +#define DIO35_RPORT PINA +#define DIO35_WPORT PORTA +#define DIO35_PWM NULL +#define DIO35_DDR DDRA + +#define DIO36_PIN PINE4 +#define DIO36_RPORT PINE +#define DIO36_WPORT PORTE +#define DIO36_PWM NULL +#define DIO36_DDR DDRE + +#define DIO37_PIN PINE5 +#define DIO37_RPORT PINE +#define DIO37_WPORT PORTE +#define DIO37_PWM NULL +#define DIO37_DDR DDRE + +#define DIO38_PIN PINF0 +#define DIO38_RPORT PINF +#define DIO38_WPORT PORTF +#define DIO38_PWM NULL +#define DIO38_DDR DDRF + +#define DIO39_PIN PINF1 +#define DIO39_RPORT PINF +#define DIO39_WPORT PORTF +#define DIO39_PWM NULL +#define DIO39_DDR DDRF + +#define DIO40_PIN PINF2 +#define DIO40_RPORT PINF +#define DIO40_WPORT PORTF +#define DIO40_PWM NULL +#define DIO40_DDR DDRF + +#define DIO41_PIN PINF3 +#define DIO41_RPORT PINF +#define DIO41_WPORT PORTF +#define DIO41_PWM NULL +#define DIO41_DDR DDRF + +#define DIO42_PIN PINF4 +#define DIO42_RPORT PINF +#define DIO42_WPORT PORTF +#define DIO42_PWM NULL +#define DIO42_DDR DDRF + +#define DIO43_PIN PINF5 +#define DIO43_RPORT PINF +#define DIO43_WPORT PORTF +#define DIO43_PWM NULL +#define DIO43_DDR DDRF + +#define DIO44_PIN PINF6 +#define DIO44_RPORT PINF +#define DIO44_WPORT PORTF +#define DIO44_PWM NULL +#define DIO44_DDR DDRF + +#define DIO45_PIN PINF7 +#define DIO45_RPORT PINF +#define DIO45_WPORT PORTF +#define DIO45_PWM NULL +#define DIO45_DDR DDRF + +#define AIO0_PIN PINF0 +#define AIO0_RPORT PINF +#define AIO0_WPORT PORTF +#define AIO0_PWM NULL +#define AIO0_DDR DDRF + +#define AIO1_PIN PINF1 +#define AIO1_RPORT PINF +#define AIO1_WPORT PORTF +#define AIO1_PWM NULL +#define AIO1_DDR DDRF + +#define AIO2_PIN PINF2 +#define AIO2_RPORT PINF +#define AIO2_WPORT PORTF +#define AIO2_PWM NULL +#define AIO2_DDR DDRF + +#define AIO3_PIN PINF3 +#define AIO3_RPORT PINF +#define AIO3_WPORT PORTF +#define AIO3_PWM NULL +#define AIO3_DDR DDRF + +#define AIO4_PIN PINF4 +#define AIO4_RPORT PINF +#define AIO4_WPORT PORTF +#define AIO4_PWM NULL +#define AIO4_DDR DDRF + +#define AIO5_PIN PINF5 +#define AIO5_RPORT PINF +#define AIO5_WPORT PORTF +#define AIO5_PWM NULL +#define AIO5_DDR DDRF + +#define AIO6_PIN PINF6 +#define AIO6_RPORT PINF +#define AIO6_WPORT PORTF +#define AIO6_PWM NULL +#define AIO6_DDR DDRF + +#define AIO7_PIN PINF7 +#define AIO7_RPORT PINF +#define AIO7_WPORT PORTF +#define AIO7_PWM NULL +#define AIO7_DDR DDRF + +//-- Begin not supported by Teensyduino +//-- don't use Arduino functions on these pins pinMode/digitalWrite/etc +#define DIO46_PIN PINE2 +#define DIO46_RPORT PINE +#define DIO46_WPORT PORTE +#define DIO46_PWM NULL +#define DIO46_DDR DDRE + +#define DIO47_PIN PINE3 +#define DIO47_RPORT PINE +#define DIO47_WPORT PORTE +#define DIO47_PWM NULL +#define DIO47_DDR DDRE + +#define TEENSY_E2 46 +#define TEENSY_E3 47 + +//-- end not supported by Teensyduino + +#undef PA0 +#define PA0_PIN PINA0 +#define PA0_RPORT PINA +#define PA0_WPORT PORTA +#define PA0_PWM NULL +#define PA0_DDR DDRA +#undef PA1 +#define PA1_PIN PINA1 +#define PA1_RPORT PINA +#define PA1_WPORT PORTA +#define PA1_PWM NULL +#define PA1_DDR DDRA +#undef PA2 +#define PA2_PIN PINA2 +#define PA2_RPORT PINA +#define PA2_WPORT PORTA +#define PA2_PWM NULL +#define PA2_DDR DDRA +#undef PA3 +#define PA3_PIN PINA3 +#define PA3_RPORT PINA +#define PA3_WPORT PORTA +#define PA3_PWM NULL +#define PA3_DDR DDRA +#undef PA4 +#define PA4_PIN PINA4 +#define PA4_RPORT PINA +#define PA4_WPORT PORTA +#define PA4_PWM NULL +#define PA4_DDR DDRA +#undef PA5 +#define PA5_PIN PINA5 +#define PA5_RPORT PINA +#define PA5_WPORT PORTA +#define PA5_PWM NULL +#define PA5_DDR DDRA +#undef PA6 +#define PA6_PIN PINA6 +#define PA6_RPORT PINA +#define PA6_WPORT PORTA +#define PA6_PWM NULL +#define PA6_DDR DDRA +#undef PA7 +#define PA7_PIN PINA7 +#define PA7_RPORT PINA +#define PA7_WPORT PORTA +#define PA7_PWM NULL +#define PA7_DDR DDRA + +#undef PB0 +#define PB0_PIN PINB0 +#define PB0_RPORT PINB +#define PB0_WPORT PORTB +#define PB0_PWM NULL +#define PB0_DDR DDRB +#undef PB1 +#define PB1_PIN PINB1 +#define PB1_RPORT PINB +#define PB1_WPORT PORTB +#define PB1_PWM NULL +#define PB1_DDR DDRB +#undef PB2 +#define PB2_PIN PINB2 +#define PB2_RPORT PINB +#define PB2_WPORT PORTB +#define PB2_PWM NULL +#define PB2_DDR DDRB +#undef PB3 +#define PB3_PIN PINB3 +#define PB3_RPORT PINB +#define PB3_WPORT PORTB +#define PB3_PWM NULL +#define PB3_DDR DDRB +#undef PB4 +#define PB4_PIN PINB4 +#define PB4_RPORT PINB +#define PB4_WPORT PORTB +#define PB4_PWM NULL +#define PB4_DDR DDRB +#undef PB5 +#define PB5_PIN PINB5 +#define PB5_RPORT PINB +#define PB5_WPORT PORTB +#define PB5_PWM NULL +#define PB5_DDR DDRB +#undef PB6 +#define PB6_PIN PINB6 +#define PB6_RPORT PINB +#define PB6_WPORT PORTB +#define PB6_PWM NULL +#define PB6_DDR DDRB +#undef PB7 +#define PB7_PIN PINB7 +#define PB7_RPORT PINB +#define PB7_WPORT PORTB +#define PB7_PWM NULL +#define PB7_DDR DDRB + +#undef PC0 +#define PC0_PIN PINC0 +#define PC0_RPORT PINC +#define PC0_WPORT PORTC +#define PC0_PWM NULL +#define PC0_DDR DDRC +#undef PC1 +#define PC1_PIN PINC1 +#define PC1_RPORT PINC +#define PC1_WPORT PORTC +#define PC1_PWM NULL +#define PC1_DDR DDRC +#undef PC2 +#define PC2_PIN PINC2 +#define PC2_RPORT PINC +#define PC2_WPORT PORTC +#define PC2_PWM NULL +#define PC2_DDR DDRC +#undef PC3 +#define PC3_PIN PINC3 +#define PC3_RPORT PINC +#define PC3_WPORT PORTC +#define PC3_PWM NULL +#define PC3_DDR DDRC +#undef PC4 +#define PC4_PIN PINC4 +#define PC4_RPORT PINC +#define PC4_WPORT PORTC +#define PC4_PWM NULL +#define PC4_DDR DDRC +#undef PC5 +#define PC5_PIN PINC5 +#define PC5_RPORT PINC +#define PC5_WPORT PORTC +#define PC5_PWM NULL +#define PC5_DDR DDRC +#undef PC6 +#define PC6_PIN PINC6 +#define PC6_RPORT PINC +#define PC6_WPORT PORTC +#define PC6_PWM NULL +#define PC6_DDR DDRC +#undef PC7 +#define PC7_PIN PINC7 +#define PC7_RPORT PINC +#define PC7_WPORT PORTC +#define PC7_PWM NULL +#define PC7_DDR DDRC + +#undef PD0 +#define PD0_PIN PIND0 +#define PD0_RPORT PIND +#define PD0_WPORT PORTD +#define PD0_PWM NULL +#define PD0_DDR DDRD +#undef PD1 +#define PD1_PIN PIND1 +#define PD1_RPORT PIND +#define PD1_WPORT PORTD +#define PD1_PWM NULL +#define PD1_DDR DDRD +#undef PD2 +#define PD2_PIN PIND2 +#define PD2_RPORT PIND +#define PD2_WPORT PORTD +#define PD2_PWM NULL +#define PD2_DDR DDRD +#undef PD3 +#define PD3_PIN PIND3 +#define PD3_RPORT PIND +#define PD3_WPORT PORTD +#define PD3_PWM NULL +#define PD3_DDR DDRD +#undef PD4 +#define PD4_PIN PIND4 +#define PD4_RPORT PIND +#define PD4_WPORT PORTD +#define PD4_PWM NULL +#define PD4_DDR DDRD +#undef PD5 +#define PD5_PIN PIND5 +#define PD5_RPORT PIND +#define PD5_WPORT PORTD +#define PD5_PWM NULL +#define PD5_DDR DDRD +#undef PD6 +#define PD6_PIN PIND6 +#define PD6_RPORT PIND +#define PD6_WPORT PORTD +#define PD6_PWM NULL +#define PD6_DDR DDRD +#undef PD7 +#define PD7_PIN PIND7 +#define PD7_RPORT PIND +#define PD7_WPORT PORTD +#define PD7_PWM NULL +#define PD7_DDR DDRD + +#undef PE0 +#define PE0_PIN PINE0 +#define PE0_RPORT PINE +#define PE0_WPORT PORTE +#define PE0_PWM NULL +#define PE0_DDR DDRE +#undef PE1 +#define PE1_PIN PINE1 +#define PE1_RPORT PINE +#define PE1_WPORT PORTE +#define PE1_PWM NULL +#define PE1_DDR DDRE +#undef PE2 +#define PE2_PIN PINE2 +#define PE2_RPORT PINE +#define PE2_WPORT PORTE +#define PE2_PWM NULL +#define PE2_DDR DDRE +#undef PE3 +#define PE3_PIN PINE3 +#define PE3_RPORT PINE +#define PE3_WPORT PORTE +#define PE3_PWM NULL +#define PE3_DDR DDRE +#undef PE4 +#define PE4_PIN PINE4 +#define PE4_RPORT PINE +#define PE4_WPORT PORTE +#define PE4_PWM NULL +#define PE4_DDR DDRE +#undef PE5 +#define PE5_PIN PINE5 +#define PE5_RPORT PINE +#define PE5_WPORT PORTE +#define PE5_PWM NULL +#define PE5_DDR DDRE +#undef PE6 +#define PE6_PIN PINE6 +#define PE6_RPORT PINE +#define PE6_WPORT PORTE +#define PE6_PWM NULL +#define PE6_DDR DDRE +#undef PE7 +#define PE7_PIN PINE7 +#define PE7_RPORT PINE +#define PE7_WPORT PORTE +#define PE7_PWM NULL +#define PE7_DDR DDRE + +#undef PF0 +#define PF0_PIN PINF0 +#define PF0_RPORT PINF +#define PF0_WPORT PORTF +#define PF0_PWM NULL +#define PF0_DDR DDRF +#undef PF1 +#define PF1_PIN PINF1 +#define PF1_RPORT PINF +#define PF1_WPORT PORTF +#define PF1_PWM NULL +#define PF1_DDR DDRF +#undef PF2 +#define PF2_PIN PINF2 +#define PF2_RPORT PINF +#define PF2_WPORT PORTF +#define PF2_PWM NULL +#define PF2_DDR DDRF +#undef PF3 +#define PF3_PIN PINF3 +#define PF3_RPORT PINF +#define PF3_WPORT PORTF +#define PF3_PWM NULL +#define PF3_DDR DDRF +#undef PF4 +#define PF4_PIN PINF4 +#define PF4_RPORT PINF +#define PF4_WPORT PORTF +#define PF4_PWM NULL +#define PF4_DDR DDRF +#undef PF5 +#define PF5_PIN PINF5 +#define PF5_RPORT PINF +#define PF5_WPORT PORTF +#define PF5_PWM NULL +#define PF5_DDR DDRF +#undef PF6 +#define PF6_PIN PINF6 +#define PF6_RPORT PINF +#define PF6_WPORT PORTF +#define PF6_PWM NULL +#define PF6_DDR DDRF +#undef PF7 +#define PF7_PIN PINF7 +#define PF7_RPORT PINF +#define PF7_WPORT PORTF +#define PF7_PWM NULL +#define PF7_DDR DDRF + + +/** + * some of the pin mapping functions of the Teensduino extension to the Arduino IDE + * do not function the same as the other Arduino extensions + */ + +//digitalPinToTimer(pin) function works like Arduino but Timers are not defined +#define TIMER0B 1 +#define TIMER1A 7 +#define TIMER1B 8 +#define TIMER1C 9 +#define TIMER2A 6 +#define TIMER2B 2 +#define TIMER3A 5 +#define TIMER3B 4 +#define TIMER3C 3 + +#endif // _FASTIO_AT90USB diff --git a/trunk/Arduino/Marlin_1.1.6/gcode.cpp b/trunk/Arduino/Marlin_1.1.6/gcode.cpp new file mode 100644 index 00000000..edeb00e2 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/gcode.cpp @@ -0,0 +1,282 @@ +/** + * 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 . + * + */ + +/** + * gcode.cpp - Parser for a GCode line, providing a parameter interface. + */ + +#include "gcode.h" + +#include "Marlin.h" +#include "language.h" + +// Must be declared for allocation and to satisfy the linker +// Zero values need no initialization. + +#if ENABLED(INCH_MODE_SUPPORT) + float GCodeParser::linear_unit_factor, GCodeParser::volumetric_unit_factor; +#endif + +#if ENABLED(TEMPERATURE_UNITS_SUPPORT) + TempUnit GCodeParser::input_temp_units; +#endif + +char *GCodeParser::command_ptr, + *GCodeParser::string_arg, + *GCodeParser::value_ptr; +char GCodeParser::command_letter; +int GCodeParser::codenum; +#if USE_GCODE_SUBCODES + uint8_t GCodeParser::subcode; +#endif + +#if ENABLED(FASTER_GCODE_PARSER) + // Optimized Parameters + byte GCodeParser::codebits[4]; // found bits + uint8_t GCodeParser::param[26]; // parameter offsets from command_ptr +#else + char *GCodeParser::command_args; // start of parameters +#endif + +// Create a global instance of the GCode parser singleton +GCodeParser parser; + +/** + * Clear all code-seen (and value pointers) + * + * Since each param is set/cleared on seen codes, + * this may be optimized by commenting out ZERO(param) + */ +void GCodeParser::reset() { + string_arg = NULL; // No whole line argument + command_letter = '?'; // No command letter + codenum = 0; // No command code + #if USE_GCODE_SUBCODES + subcode = 0; // No command sub-code + #endif + #if ENABLED(FASTER_GCODE_PARSER) + ZERO(codebits); // No codes yet + //ZERO(param); // No parameters (should be safe to comment out this line) + #endif +} + +// Populate all fields by parsing a single line of GCode +// 58 bytes of SRAM are used to speed up seen/value +void GCodeParser::parse(char *p) { + + reset(); // No codes to report + + // Skip spaces + while (*p == ' ') ++p; + + // Skip N[-0-9] if included in the command line + if (*p == 'N' && NUMERIC_SIGNED(p[1])) { + #if ENABLED(FASTER_GCODE_PARSER) + //set('N', p + 1); // (optional) Set the 'N' parameter value + #endif + p += 2; // skip N[-0-9] + while (NUMERIC(*p)) ++p; // skip [0-9]* + while (*p == ' ') ++p; // skip [ ]* + } + + // *p now points to the current command, which should be G, M, or T + command_ptr = p; + + // Get the command letter, which must be G, M, or T + const char letter = *p++; + + // Nullify asterisk and trailing whitespace + char *starpos = strchr(p, '*'); + if (starpos) { + --starpos; // * + while (*starpos == ' ') --starpos; // spaces... + starpos[1] = '\0'; + } + + // Bail if the letter is not G, M, or T + switch (letter) { case 'G': case 'M': case 'T': break; default: return; } + + // Skip spaces to get the numeric part + while (*p == ' ') p++; + + // Bail if there's no command code number + if (!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)); + + // Allow for decimal point in command + #if USE_GCODE_SUBCODES + if (*p == '.') { + p++; + while (NUMERIC(*p)) + subcode *= 10, subcode += *p++ - '0'; + } + #endif + + // Skip all spaces to get to the first argument, or nul + while (*p == ' ') p++; + + // The command parameters (if any) start here, for sure! + + #if DISABLED(FASTER_GCODE_PARSER) + command_args = p; // Scan for parameters in seen() + #endif + + // Only use string_arg for these M codes + if (letter == 'M') switch (codenum) { case 23: case 28: case 30: case 117: case 118: case 928: string_arg = p; return; default: break; } + + #if ENABLED(DEBUG_GCODE_PARSER) + const bool debug = codenum == 800; + #endif + + /** + * Find all parameters, set flags and pointers for fast parsing + * + * Most codes ignore 'string_arg', but those that want a string will get the right pointer. + * The following loop assigns the first "parameter" having no numeric value to 'string_arg'. + * This allows M0/M1 with expire time to work: "M0 S5 You Win!" + */ + string_arg = NULL; + while (char code = *p++) { // Get the next parameter. A NUL ends the loop + + // Special handling for M32 [P] !/path/to/file.g# + // The path must be the last parameter + if (code == '!' && letter == 'M' && codenum == 32) { + string_arg = p; // Name starts after '!' + char * const lb = strchr(p, '#'); // Already seen '#' as SD char (to pause buffering) + if (lb) *lb = '\0'; // Safe to mark the end of the filename + return; + } + + // Arguments MUST be uppercase for fast GCode parsing + #if ENABLED(FASTER_GCODE_PARSER) + #define PARAM_TEST WITHIN(code, 'A', 'Z') + #else + #define PARAM_TEST true + #endif + + if (PARAM_TEST) { + + while (*p == ' ') p++; // Skip spaces between parameters & values + const bool has_num = DECIMAL_SIGNED(*p); // The parameter has a number [-+0-9.] + + #if ENABLED(DEBUG_GCODE_PARSER) + if (debug) { + SERIAL_ECHOPAIR("Got letter ", code); // DEBUG + SERIAL_ECHOPAIR(" at index ", (int)(p - command_ptr - 1)); // DEBUG + if (has_num) SERIAL_ECHOPGM(" (has_num)"); + } + #endif + + if (!has_num && !string_arg) { // No value? First time, keep as string_arg + string_arg = p - 1; + #if ENABLED(DEBUG_GCODE_PARSER) + if (debug) SERIAL_ECHOPAIR(" string_arg: ", hex_address((void*)string_arg)); // DEBUG + #endif + } + + #if ENABLED(DEBUG_GCODE_PARSER) + if (debug) SERIAL_EOL(); + #endif + + #if ENABLED(FASTER_GCODE_PARSER) + set(code, has_num ? p : NULL // Set parameter exists and pointer (NULL for no number) + #if ENABLED(DEBUG_GCODE_PARSER) + , debug + #endif + ); + #endif + } + else if (!string_arg) { // Not A-Z? First time, keep as the string_arg + string_arg = p - 1; + #if ENABLED(DEBUG_GCODE_PARSER) + if (debug) SERIAL_ECHOPAIR(" string_arg: ", hex_address((void*)string_arg)); // DEBUG + #endif + } + + if (!WITHIN(*p, 'A', 'Z')) { + while (*p && NUMERIC(*p)) p++; // Skip over the value section of a parameter + while (*p == ' ') p++; // Skip over all spaces + } + } +} + +void GCodeParser::unknown_command_error() { + SERIAL_ECHO_START(); + SERIAL_ECHOPAIR(MSG_UNKNOWN_COMMAND, command_ptr); + SERIAL_CHAR('"'); + SERIAL_EOL(); +} + +#if ENABLED(DEBUG_GCODE_PARSER) + + void GCodeParser::debug() { + SERIAL_ECHOPAIR("Command: ", command_ptr); + SERIAL_ECHOPAIR(" (", command_letter); + SERIAL_ECHO(codenum); + SERIAL_ECHOLNPGM(")"); + #if ENABLED(FASTER_GCODE_PARSER) + SERIAL_ECHO(" args: \""); + for (char c = 'A'; c <= 'Z'; ++c) + if (seen(c)) { SERIAL_CHAR(c); SERIAL_CHAR(' '); } + #else + SERIAL_ECHOPAIR(" args: \"", command_args); + #endif + SERIAL_ECHOPGM("\""); + if (string_arg) { + SERIAL_ECHOPGM(" string: \""); + SERIAL_ECHO(string_arg); + SERIAL_CHAR('"'); + } + SERIAL_ECHOPGM("\n\n"); + for (char c = 'A'; c <= 'Z'; ++c) { + if (seen(c)) { + SERIAL_ECHOPAIR("Code '", c); SERIAL_ECHOPGM("':"); + if (has_value()) { + SERIAL_ECHOPAIR("\n float: ", value_float()); + SERIAL_ECHOPAIR("\n long: ", value_long()); + SERIAL_ECHOPAIR("\n ulong: ", value_ulong()); + SERIAL_ECHOPAIR("\n millis: ", value_millis()); + SERIAL_ECHOPAIR("\n sec-ms: ", value_millis_from_seconds()); + SERIAL_ECHOPAIR("\n int: ", value_int()); + SERIAL_ECHOPAIR("\n ushort: ", value_ushort()); + SERIAL_ECHOPAIR("\n byte: ", (int)value_byte()); + SERIAL_ECHOPAIR("\n bool: ", (int)value_bool()); + SERIAL_ECHOPAIR("\n linear: ", value_linear_units()); + SERIAL_ECHOPAIR("\n celsius: ", value_celsius()); + } + else + SERIAL_ECHOPGM(" (no value)"); + SERIAL_ECHOPGM("\n\n"); + } + } + } + +#endif // DEBUG_GCODE_PARSER diff --git a/trunk/Arduino/Marlin_1.1.6/gcode.h b/trunk/Arduino/Marlin_1.1.6/gcode.h new file mode 100644 index 00000000..36549b85 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/gcode.h @@ -0,0 +1,323 @@ +/** + * 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 . + * + */ + +/** + * gcode.h - Parser for a GCode line, providing a parameter interface. + * Codes like M149 control the way the GCode parser behaves, + * so settings for these codes are located in this class. + */ + +#ifndef GCODE_H +#define GCODE_H + +#include "enum.h" +#include "types.h" +#include "MarlinConfig.h" + +//#define DEBUG_GCODE_PARSER + +#if ENABLED(DEBUG_GCODE_PARSER) + #if ENABLED(AUTO_BED_LEVELING_UBL) + extern char* hex_address(const void * const w); + #else + #include "hex_print_routines.h" + #endif + #include "serial.h" +#endif + +#if ENABLED(INCH_MODE_SUPPORT) + extern bool volumetric_enabled; +#endif + +/** + * GCode parser + * + * - Parse a single gcode line for its letter, code, subcode, and parameters + * - FASTER_GCODE_PARSER: + * - Flags existing params (1 bit each) + * - Stores value offsets (1 byte each) + * - Provide accessors for parameters: + * - Parameter exists + * - Parameter has value + * - Parameter value in different units and types + */ +class GCodeParser { + +private: + static char *value_ptr; // Set by seen, used to fetch the value + + #if ENABLED(FASTER_GCODE_PARSER) + static byte codebits[4]; // Parameters pre-scanned + static uint8_t param[26]; // For A-Z, offsets into command args + #else + static char *command_args; // Args start here, for slow scan + #endif + +public: + + // Global states for GCode-level units features + + #if ENABLED(INCH_MODE_SUPPORT) + static float linear_unit_factor, volumetric_unit_factor; + #endif + + #if ENABLED(TEMPERATURE_UNITS_SUPPORT) + static TempUnit input_temp_units; + #endif + + // Command line state + static char *command_ptr, // The command, so it can be echoed + *string_arg; // string of command line + + static char command_letter; // G, M, or T + static int codenum; // 123 + #if USE_GCODE_SUBCODES + static uint8_t subcode; // .1 + #endif + + #if ENABLED(DEBUG_GCODE_PARSER) + void debug(); + #endif + + // Reset is done before parsing + static void reset(); + + // Index so that 'X' falls on index 24 + #define PARAM_IND(N) ((N) >> 3) + #define PARAM_BIT(N) ((N) & 0x7) + #define LETTER_OFF(N) ((N) - 'A') + #define LETTER_IND(N) PARAM_IND(LETTER_OFF(N)) + #define LETTER_BIT(N) PARAM_BIT(LETTER_OFF(N)) + + #if ENABLED(FASTER_GCODE_PARSER) + + // Set the flag and pointer for a parameter + static void set(const char c, char * const ptr + #if ENABLED(DEBUG_GCODE_PARSER) + , const bool debug=false + #endif + ) { + const uint8_t ind = LETTER_OFF(c); + if (ind >= COUNT(param)) return; // Only A-Z + SBI(codebits[PARAM_IND(ind)], PARAM_BIT(ind)); // parameter exists + param[ind] = ptr ? ptr - command_ptr : 0; // parameter offset or 0 + #if ENABLED(DEBUG_GCODE_PARSER) + if (debug) { + SERIAL_ECHOPAIR("Set bit ", (int)PARAM_BIT(ind)); + SERIAL_ECHOPAIR(" of index ", (int)PARAM_IND(ind)); + SERIAL_ECHOLNPAIR(" | param = ", (int)param[ind]); + } + #endif + } + + // Code seen bit was set. If not found, value_ptr is unchanged. + // This allows "if (seen('A')||seen('B'))" to use the last-found value. + static bool seen(const char c) { + const uint8_t ind = LETTER_OFF(c); + if (ind >= COUNT(param)) return false; // Only A-Z + const bool b = TEST(codebits[PARAM_IND(ind)], PARAM_BIT(ind)); + if (b) value_ptr = param[ind] ? command_ptr + param[ind] : (char*)NULL; + return b; + } + + static bool seen_any() { return codebits[3] || codebits[2] || codebits[1] || codebits[0]; } + + #define SEEN_TEST(L) TEST(codebits[LETTER_IND(L)], LETTER_BIT(L)) + + #else // !FASTER_GCODE_PARSER + + // Code is found in the string. If not found, value_ptr is unchanged. + // This allows "if (seen('A')||seen('B'))" to use the last-found value. + static bool seen(const char c) { + const char *p = strchr(command_args, c); + const bool b = !!p; + if (b) value_ptr = DECIMAL_SIGNED(p[1]) ? &p[1] : (char*)NULL; + return b; + } + + static bool seen_any() { return *command_args == '\0'; } + + #define SEEN_TEST(L) !!strchr(command_args, L) + + #endif // !FASTER_GCODE_PARSER + + // Seen any axis parameter + static bool seen_axis() { + return SEEN_TEST('X') || SEEN_TEST('Y') || SEEN_TEST('Z') || SEEN_TEST('E'); + } + + // Populate all fields by parsing a single line of GCode + // This uses 54 bytes of SRAM to speed up seen/value + static void parse(char * p); + + // The code value pointer was set + FORCE_INLINE static bool has_value() { return value_ptr != NULL; } + + // Seen a parameter with a value + inline static bool seenval(const char c) { return seen(c) && has_value(); } + + // Float removes 'E' to prevent scientific notation interpretation + inline static float value_float() { + if (value_ptr) { + char *e = value_ptr; + for (;;) { + const char c = *e; + if (c == '\0' || c == ' ') break; + if (c == 'E' || c == 'e') { + *e = '\0'; + const float ret = strtod(value_ptr, NULL); + *e = c; + return ret; + } + ++e; + } + return strtod(value_ptr, NULL); + } + return 0.0; + } + + // Code value as a long or ulong + inline static int32_t value_long() { return value_ptr ? strtol(value_ptr, NULL, 10) : 0L; } + inline static uint32_t value_ulong() { return value_ptr ? strtoul(value_ptr, NULL, 10) : 0UL; } + + // Code value for use as time + FORCE_INLINE static millis_t value_millis() { return value_ulong(); } + FORCE_INLINE static millis_t value_millis_from_seconds() { return value_float() * 1000UL; } + + // Reduce to fewer bits + FORCE_INLINE static int16_t value_int() { return (int16_t)value_long(); } + FORCE_INLINE static uint16_t value_ushort() { return (uint16_t)value_long(); } + inline static uint8_t value_byte() { return (uint8_t)constrain(value_long(), 0, 255); } + + // Bool is true with no value or non-zero + inline static bool value_bool() { return !has_value() || value_byte(); } + + // Units modes: Inches, Fahrenheit, Kelvin + + #if ENABLED(INCH_MODE_SUPPORT) + + inline static void set_input_linear_units(const LinearUnit units) { + switch (units) { + case LINEARUNIT_INCH: + linear_unit_factor = 25.4; + break; + case LINEARUNIT_MM: + default: + linear_unit_factor = 1.0; + break; + } + volumetric_unit_factor = POW(linear_unit_factor, 3.0); + } + + inline static float axis_unit_factor(const AxisEnum axis) { + return (axis >= E_AXIS && volumetric_enabled ? volumetric_unit_factor : linear_unit_factor); + } + + inline static float value_linear_units() { return value_float() * linear_unit_factor; } + inline static float value_axis_units(const AxisEnum axis) { return value_float() * axis_unit_factor(axis); } + inline static float value_per_axis_unit(const AxisEnum axis) { return value_float() / axis_unit_factor(axis); } + + #else + + FORCE_INLINE static float value_linear_units() { return value_float(); } + FORCE_INLINE static float value_axis_units(const AxisEnum a) { UNUSED(a); return value_float(); } + FORCE_INLINE static float value_per_axis_unit(const AxisEnum a) { UNUSED(a); return value_float(); } + + #endif + + #if ENABLED(TEMPERATURE_UNITS_SUPPORT) + + inline static void set_input_temp_units(TempUnit units) { input_temp_units = units; } + + #if ENABLED(ULTIPANEL) && DISABLED(DISABLE_M503) + + FORCE_INLINE static char temp_units_code() { + return input_temp_units == TEMPUNIT_K ? 'K' : input_temp_units == TEMPUNIT_F ? 'F' : 'C'; + } + FORCE_INLINE static char* temp_units_name() { + return input_temp_units == TEMPUNIT_K ? PSTR("Kelvin") : input_temp_units == TEMPUNIT_F ? PSTR("Fahrenheit") : PSTR("Celsius"); + } + inline static float to_temp_units(const float &f) { + switch (input_temp_units) { + case TEMPUNIT_F: + return f * 0.5555555556 + 32.0; + case TEMPUNIT_K: + return f + 273.15; + case TEMPUNIT_C: + default: + return f; + } + } + + #endif // ULTIPANEL && !DISABLE_M503 + + inline static float value_celsius() { + const float f = value_float(); + switch (input_temp_units) { + case TEMPUNIT_F: + return (f - 32.0) * 0.5555555556; + case TEMPUNIT_K: + return f - 273.15; + case TEMPUNIT_C: + default: + return f; + } + } + + inline static float value_celsius_diff() { + switch (input_temp_units) { + case TEMPUNIT_F: + return value_float() * 0.5555555556; + case TEMPUNIT_C: + case TEMPUNIT_K: + default: + return value_float(); + } + } + + #else // !TEMPERATURE_UNITS_SUPPORT + + FORCE_INLINE static float value_celsius() { return value_float(); } + FORCE_INLINE static float value_celsius_diff() { return value_float(); } + + #endif // !TEMPERATURE_UNITS_SUPPORT + + FORCE_INLINE static float value_feedrate() { return value_linear_units(); } + + void unknown_command_error(); + + // Provide simple value accessors with default option + FORCE_INLINE static float floatval(const char c, const float dval=0.0) { return seenval(c) ? value_float() : dval; } + FORCE_INLINE static bool boolval(const char c, const bool dval=false) { return seen(c) ? value_bool() : dval; } + FORCE_INLINE static uint8_t byteval(const char c, const uint8_t dval=0) { return seenval(c) ? value_byte() : dval; } + FORCE_INLINE static int16_t intval(const char c, const int16_t dval=0) { return seenval(c) ? value_int() : dval; } + FORCE_INLINE static uint16_t ushortval(const char c, const uint16_t dval=0) { return seenval(c) ? value_ushort() : dval; } + FORCE_INLINE static int32_t longval(const char c, const int32_t dval=0) { return seenval(c) ? value_long() : dval; } + FORCE_INLINE static uint32_t ulongval(const char c, const uint32_t dval=0) { return seenval(c) ? value_ulong() : dval; } + FORCE_INLINE static float linearval(const char c, const float dval=0.0) { return seenval(c) ? value_linear_units() : dval; } + FORCE_INLINE static float celsiusval(const char c, const float dval=0.0) { return seenval(c) ? value_celsius() : dval; } + +}; + +extern GCodeParser parser; + +#endif // GCODE_H diff --git a/trunk/Arduino/Marlin_1.1.6/hex_print_routines.cpp b/trunk/Arduino/Marlin_1.1.6/hex_print_routines.cpp new file mode 100644 index 00000000..65b97fc1 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/hex_print_routines.cpp @@ -0,0 +1,55 @@ +/** + * 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 . + * + */ +#include "Marlin.h" +#include "gcode.h" + +#if ENABLED(AUTO_BED_LEVELING_UBL) || ENABLED(M100_FREE_MEMORY_WATCHER) || ENABLED(DEBUG_GCODE_PARSER) + +#include "hex_print_routines.h" + +static char _hex[7] = "0x0000"; + +char* hex_byte(const uint8_t b) { + _hex[4] = hex_nybble(b >> 4); + _hex[5] = hex_nybble(b); + return &_hex[4]; +} + +char* hex_word(const uint16_t w) { + _hex[2] = hex_nybble(w >> 12); + _hex[3] = hex_nybble(w >> 8); + _hex[4] = hex_nybble(w >> 4); + _hex[5] = hex_nybble(w); + return &_hex[2]; +} + +char* hex_address(const void * const w) { + (void)hex_word((uint16_t)w); + 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)); } + +#endif // AUTO_BED_LEVELING_UBL || M100_FREE_MEMORY_WATCHER || DEBUG_GCODE_PARSER diff --git a/trunk/Arduino/Marlin_1.1.6/hex_print_routines.h b/trunk/Arduino/Marlin_1.1.6/hex_print_routines.h new file mode 100644 index 00000000..1ca61e31 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/hex_print_routines.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 . + * + */ + +#ifndef HEX_PRINT_ROUTINES_H +#define HEX_PRINT_ROUTINES_H + +#include "MarlinConfig.h" +#include "gcode.h" + +#if ENABLED(AUTO_BED_LEVELING_UBL) || ENABLED(M100_FREE_MEMORY_WATCHER) || ENABLED(DEBUG_GCODE_PARSER) + +// +// Utility functions to create and print hex strings as nybble, byte, and word. +// + +inline char hex_nybble(const uint8_t n) { + return (n & 0xF) + ((n & 0xF) < 10 ? '0' : 'A' - 10); +} +char* hex_byte(const uint8_t b); +char* hex_word(const uint16_t w); +char* hex_address(const void * const w); + +void print_hex_nybble(const uint8_t n); +void print_hex_byte(const uint8_t b); +void print_hex_word(const uint16_t w); +void print_hex_address(const void * const w); + +#endif // AUTO_BED_LEVELING_UBL || M100_FREE_MEMORY_WATCHER || DEBUG_GCODE_PARSER +#endif // HEX_PRINT_ROUTINES_H diff --git a/trunk/Arduino/Marlin_1.1.6/language.h b/trunk/Arduino/Marlin_1.1.6/language.h new file mode 100644 index 00000000..0ff6bade --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/language.h @@ -0,0 +1,312 @@ +/** + * 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 . + * + */ + +#ifndef LANGUAGE_H +#define LANGUAGE_H + +#include "MarlinConfig.h" + +#define _UxGT(a) a + +// Define SIMULATE_ROMFONT to see what is seen on the character based display defined in Configuration.h +//#define SIMULATE_ROMFONT + +// Fallback if no language is set. DON'T CHANGE +#ifndef LCD_LANGUAGE + #define LCD_LANGUAGE en +#endif + +// For character-based LCD controllers (DISPLAY_CHARSET_HD44780) +#define JAPANESE 1 +#define WESTERN 2 +#define CYRILLIC 3 + +// NOTE: IF YOU CHANGE LANGUAGE FILES OR MERGE A FILE WITH CHANGES +// +// ==> ALWAYS TRY TO COMPILE MARLIN WITH/WITHOUT "ULTIPANEL" / "ULTRALCD" / "SDSUPPORT" #define IN "Configuration.h" +// ==> ALSO TRY ALL AVAILABLE LANGUAGE OPTIONS +// See also http://marlinfw.org/docs/development/lcd_language.html + +// Languages +// an Aragonese +// bg Bulgarian +// ca Catalan +// cn Chinese +// cz Czech +// cz_utf8 Czech (UTF8) +// de German +// el Greek +// el-gr Greek (Greece) +// en English +// es Spanish +// eu Basque-Euskera +// fi Finnish +// fr French +// gl Galician +// hr Croatian +// it Italian +// kana Japanese +// kana_utf8 Japanese (UTF8) +// nl Dutch +// pl Polish +// pt Portuguese +// pt-br Portuguese (Brazilian) +// pt-br_utf8 Portuguese (Brazilian) (UTF8) +// pt_utf8 Portuguese (UTF8) +// ru Russian +// sk Slovak (UTF8) +// tr Turkish +// uk Ukrainian +// zh_CN Chinese (Simplified) +// zh_TW Chinese (Taiwan) + +#ifdef DEFAULT_SOURCE_CODE_URL + #undef SOURCE_CODE_URL + #define SOURCE_CODE_URL DEFAULT_SOURCE_CODE_URL +#endif + +#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 +#endif + +#ifndef MACHINE_UUID + #define MACHINE_UUID DEFAULT_MACHINE_UUID +#endif + +#ifdef DEFAULT_WEBSITE_URL + #undef WEBSITE_URL + #define WEBSITE_URL DEFAULT_WEBSITE_URL +#endif + +// Common LCD messages + + /* nothing here yet */ + +// Common serial messages +#define MSG_MARLIN "Marlin" + +// Serial Console Messages (do not translate those!) + +#define MSG_ENQUEUEING "enqueueing \"" +#define MSG_POWERUP "PowerUp" +#define MSG_EXTERNAL_RESET " External Reset" +#define MSG_BROWNOUT_RESET " Brown out Reset" +#define MSG_WATCHDOG_RESET " Watchdog Reset" +#define MSG_SOFTWARE_RESET " Software Reset" +#define MSG_AUTHOR " | Author: " +#define MSG_CONFIGURATION_VER " Last Updated: " +#define MSG_FREE_MEMORY " Free Memory: " +#define MSG_PLANNER_BUFFER_BYTES " PlannerBufferBytes: " +#define MSG_OK "ok" +#define MSG_WAIT "wait" +#define MSG_STATS "Stats: " +#define MSG_FILE_SAVED "Done saving file." +#define MSG_ERR_LINE_NO "Line Number is not Last Line Number+1, Last Line: " +#define MSG_ERR_CHECKSUM_MISMATCH "checksum mismatch, Last Line: " +#define MSG_ERR_NO_CHECKSUM "No Checksum with line number, Last Line: " +#define MSG_ERR_NO_LINENUMBER_WITH_CHECKSUM "No Line Number with checksum, Last Line: " +#define MSG_FILE_PRINTED "Done printing file" +#define MSG_BEGIN_FILE_LIST "Begin file list" +#define MSG_END_FILE_LIST "End file list" +#define MSG_INVALID_EXTRUDER "Invalid extruder" +#define MSG_INVALID_SOLENOID "Invalid solenoid" +#define MSG_ERR_NO_THERMISTORS "No thermistors - no temperature" +#define MSG_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 MSG_COUNT_X " Count X:" +#define MSG_COUNT_A " Count A:" +#define MSG_ERR_KILLED "Printer halted. kill() called!" +#define MSG_ERR_STOPPED "Printer stopped due to errors. Fix the error and use M999 to restart. (Temperature is reset. Set it after restarting)" +#define MSG_BUSY_PROCESSING "busy: processing" +#define MSG_BUSY_PAUSED_FOR_USER "busy: paused for user" +#define MSG_BUSY_PAUSED_FOR_INPUT "busy: paused for input" +#define MSG_RESEND "Resend: " +#define MSG_UNKNOWN_COMMAND "Unknown command: \"" +#define MSG_ACTIVE_EXTRUDER "Active Extruder: " +#define MSG_X_MIN "x_min: " +#define MSG_X_MAX "x_max: " +#define MSG_Y_MIN "y_min: " +#define MSG_Y_MAX "y_max: " +#define MSG_Z_MIN "z_min: " +#define MSG_Z_MAX "z_max: " +#define MSG_Z2_MIN "z2_min: " +#define MSG_Z2_MAX "z2_max: " +#define MSG_Z_PROBE "z_probe: " +#define MSG_FILAMENT_RUNOUT_SENSOR "filament: " +#define MSG_ERR_MATERIAL_INDEX "M145 S out of range (0-1)" +#define MSG_ERR_M355_NONE "No case light" +#define MSG_ERR_M421_PARAMETERS "M421 incorrect parameter usage" +#define MSG_ERR_BAD_PLANE_MODE "G5 requires XY plane mode" +#define MSG_ERR_MESH_XY "Mesh point cannot be resolved" +#define MSG_ERR_ARC_ARGS "G2/G3 bad parameters" +#define MSG_ERR_PROTECTED_PIN "Protected Pin" +#define MSG_ERR_M420_FAILED "Failed to enable Bed Leveling" +#define MSG_ERR_M428_TOO_FAR "Too far from reference point" +#define MSG_ERR_M303_DISABLED "PIDTEMP disabled" +#define MSG_M119_REPORT "Reporting endstop status" +#define MSG_ENDSTOP_HIT "TRIGGERED" +#define MSG_ENDSTOP_OPEN "open" +#define MSG_HOTEND_OFFSET "Hotend offsets:" +#define MSG_DUPLICATION_MODE "Duplication mode: " +#define MSG_SOFT_ENDSTOPS "Soft endstops: " +#define MSG_SOFT_MIN " Min: " +#define MSG_SOFT_MAX " Max: " + +#define MSG_SD_CANT_OPEN_SUBDIR "Cannot open subdir " +#define MSG_SD_INIT_FAIL "SD init fail" +#define MSG_SD_VOL_INIT_FAIL "volume.init failed" +#define MSG_SD_OPENROOT_FAIL "openRoot failed" +#define MSG_SD_CARD_OK "SD card ok" +#define MSG_SD_WORKDIR_FAIL "workDir open failed" +#define MSG_SD_OPEN_FILE_FAIL "open failed, File: " +#define MSG_SD_FILE_OPENED "File opened: " +#define MSG_SD_SIZE " Size: " +#define MSG_SD_FILE_SELECTED "File selected" +#define MSG_SD_WRITE_TO_FILE "Writing to file: " +#define MSG_SD_PRINTING_BYTE "SD printing byte " +#define MSG_SD_NOT_PRINTING "Not SD printing" +#define MSG_SD_ERR_WRITE_TO_FILE "error writing to file" +#define MSG_SD_ERR_READ "SD read error" +#define MSG_SD_CANT_ENTER_SUBDIR "Cannot enter subdir: " + +#define MSG_STEPPER_TOO_HIGH "Steprate too high: " +#define MSG_ENDSTOPS_HIT "endstops hit: " +#define MSG_ERR_COLD_EXTRUDE_STOP " cold extrusion prevented" +#define MSG_ERR_LONG_EXTRUDE_STOP " too long extrusion prevented" +#define MSG_TOO_COLD_FOR_M600 "M600 Hotend too cold to change filament" +#define MSG_SERIAL_ERROR_MENU_STRUCTURE "Error in menu structure" + +#define MSG_ERR_EEPROM_WRITE "Error writing to EEPROM!" + +#define MSG_STOP_BLTOUCH "STOP called because of BLTouch error - restart with M999" +#define MSG_STOP_UNHOMED "STOP called because of unhomed error - restart with M999" +#define MSG_KILL_INACTIVE_TIME "KILL caused by too much inactive time - current command: " +#define MSG_KILL_BUTTON "KILL caused by KILL button/pin" + +// temperature.cpp strings +#define MSG_PID_AUTOTUNE "PID Autotune" +#define MSG_PID_AUTOTUNE_START MSG_PID_AUTOTUNE " start" +#define MSG_PID_AUTOTUNE_FAILED MSG_PID_AUTOTUNE " failed!" +#define MSG_PID_BAD_EXTRUDER_NUM MSG_PID_AUTOTUNE_FAILED " Bad extruder number" +#define MSG_PID_TEMP_TOO_HIGH MSG_PID_AUTOTUNE_FAILED " Temperature too high" +#define MSG_PID_TIMEOUT MSG_PID_AUTOTUNE_FAILED " timeout" +#define MSG_BIAS " bias: " +#define MSG_D " d: " +#define MSG_T_MIN " min: " +#define MSG_T_MAX " max: " +#define MSG_KU " Ku: " +#define MSG_TU " Tu: " +#define MSG_CLASSIC_PID " Classic PID " +#define MSG_KP " Kp: " +#define MSG_KI " Ki: " +#define MSG_KD " Kd: " +#define MSG_B "B:" +#define MSG_T "T:" +#define MSG_AT " @:" +#define MSG_PID_AUTOTUNE_FINISHED MSG_PID_AUTOTUNE " finished! Put the last Kp, Ki and Kd constants from below into Configuration.h" +#define MSG_PID_DEBUG " PID_DEBUG " +#define MSG_PID_DEBUG_INPUT ": Input " +#define MSG_PID_DEBUG_OUTPUT " Output " +#define MSG_PID_DEBUG_PTERM " pTerm " +#define MSG_PID_DEBUG_ITERM " iTerm " +#define MSG_PID_DEBUG_DTERM " dTerm " +#define MSG_PID_DEBUG_CTERM " cTerm " +#define MSG_INVALID_EXTRUDER_NUM " - Invalid extruder number !" + +#define MSG_HEATER_BED "bed" +#define MSG_STOPPED_HEATER ", system stopped! Heater_ID: " +#define MSG_REDUNDANCY "Heater switched off. Temperature difference between temp sensors is too high !" +#define MSG_T_HEATING_FAILED "Heating failed" +#define MSG_T_THERMAL_RUNAWAY "Thermal Runaway" +#define MSG_T_MAXTEMP "MAXTEMP triggered" +#define MSG_T_MINTEMP "MINTEMP triggered" + +// Debug +#define MSG_DEBUG_PREFIX "DEBUG:" +#define MSG_DEBUG_OFF "off" +#define MSG_DEBUG_ECHO "ECHO" +#define MSG_DEBUG_INFO "INFO" +#define MSG_DEBUG_ERRORS "ERRORS" +#define MSG_DEBUG_DRYRUN "DRYRUN" +#define MSG_DEBUG_COMMUNICATION "COMMUNICATION" +#define MSG_DEBUG_LEVELING "LEVELING" + +// LCD Menu Messages + +#define LANGUAGE_INCL_(M) STRINGIFY_(language_##M.h) +#define LANGUAGE_INCL(M) LANGUAGE_INCL_(M) +#define INCLUDE_LANGUAGE LANGUAGE_INCL(LCD_LANGUAGE) + +// Never translate these strings +#define MSG_X "X" +#define MSG_Y "Y" +#define MSG_Z "Z" +#define MSG_E "E" +#define MSG_H1 "1" +#define MSG_H2 "2" +#define MSG_H3 "3" +#define MSG_H4 "4" +#define MSG_H5 "5" +#define MSG_N1 " 1" +#define MSG_N2 " 2" +#define MSG_N3 " 3" +#define MSG_N4 " 4" +#define MSG_N5 " 5" +#define MSG_E1 "E1" +#define MSG_E2 "E2" +#define MSG_E3 "E3" +#define MSG_E4 "E4" +#define MSG_E5 "E5" +#define MSG_MOVE_E1 "1" +#define MSG_MOVE_E2 "2" +#define MSG_MOVE_E3 "3" +#define MSG_MOVE_E4 "4" +#define MSG_MOVE_E5 "5" +#define MSG_DIAM_E1 " 1" +#define MSG_DIAM_E2 " 2" +#define MSG_DIAM_E3 " 3" +#define MSG_DIAM_E4 " 4" +#define MSG_DIAM_E5 " 5" + +#include INCLUDE_LANGUAGE + +#if DISABLED(SIMULATE_ROMFONT) \ + && DISABLED(DISPLAY_CHARSET_ISO10646_1) \ + && DISABLED(DISPLAY_CHARSET_ISO10646_5) \ + && DISABLED(DISPLAY_CHARSET_ISO10646_KANA) \ + && DISABLED(DISPLAY_CHARSET_ISO10646_GREEK) \ + && DISABLED(DISPLAY_CHARSET_ISO10646_CN) \ + && DISABLED(DISPLAY_CHARSET_ISO10646_TR) \ + && DISABLED(DISPLAY_CHARSET_ISO10646_PL) \ + && DISABLED(DISPLAY_CHARSET_ISO10646_CZ) \ + && DISABLED(DISPLAY_CHARSET_ISO10646_SK) + #define DISPLAY_CHARSET_ISO10646_1 // use the better font on full graphic displays. +#endif + +#include "language_en.h" + +#endif // __LANGUAGE_H diff --git a/trunk/Arduino/Marlin_1.1.6/language_an.h b/trunk/Arduino/Marlin_1.1.6/language_an.h new file mode 100644 index 00000000..be3b04b3 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/language_an.h @@ -0,0 +1,253 @@ +/** + * 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 . + * + */ + +/** + * Aragonese + * + * LCD Menu Messages + * See also http://marlinfw.org/docs/development/lcd_language.html + * + */ +#ifndef LANGUAGE_AN_H +#define LANGUAGE_AN_H + +#define DISPLAY_CHARSET_ISO10646_1 + +#define WELCOME_MSG MACHINE_NAME _UxGT(" parada.") +#define MSG_SD_INSERTED _UxGT("Tarcheta mesa") +#define MSG_SD_REMOVED _UxGT("Tarcheta sacada") +#define MSG_LCD_ENDSTOPS _UxGT("Endstops") // Max length 8 characters +#define MSG_MAIN _UxGT("Menu prencipal") +#define MSG_AUTOSTART _UxGT("Inicio automatico") +#define MSG_DISABLE_STEPPERS _UxGT("Amortar motors") +#define MSG_AUTO_HOME _UxGT("Levar a l'orichen") +#define MSG_AUTO_HOME_X _UxGT("Orichen X") +#define MSG_AUTO_HOME_Y _UxGT("Orichen Y") +#define MSG_AUTO_HOME_Z _UxGT("Orichen Z") +#define MSG_LEVEL_BED_HOMING _UxGT("Orichen XYZ") +#define MSG_LEVEL_BED_WAITING _UxGT("Encetar (pretar)") +#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Vinient punto") +#define MSG_LEVEL_BED_DONE _UxGT("Nivelacion feita!") +#define MSG_SET_HOME_OFFSETS _UxGT("Achustar desfases") +#define MSG_HOME_OFFSETS_APPLIED _UxGT("Desfase aplicau") +#define MSG_SET_ORIGIN _UxGT("Establir orichen") +#define MSG_PREHEAT_1 _UxGT("Precalentar PLA") +#define MSG_PREHEAT_1_N MSG_PREHEAT_1 _UxGT(" ") +#define MSG_PREHEAT_1_ALL MSG_PREHEAT_1 _UxGT(" Tot") +#define MSG_PREHEAT_1_BEDONLY MSG_PREHEAT_1 _UxGT(" Base") +#define MSG_PREHEAT_1_SETTINGS MSG_PREHEAT_1 _UxGT(" Conf") +#define MSG_PREHEAT_2 _UxGT("Precalentar ABS") +#define MSG_PREHEAT_2_N MSG_PREHEAT_2 _UxGT(" ") +#define MSG_PREHEAT_2_ALL MSG_PREHEAT_2 _UxGT(" Tot") +#define MSG_PREHEAT_2_BEDONLY MSG_PREHEAT_2 _UxGT(" Base") +#define MSG_PREHEAT_2_SETTINGS MSG_PREHEAT_2 _UxGT(" Conf") +#define MSG_COOLDOWN _UxGT("Enfriar") +#define MSG_SWITCH_PS_ON _UxGT("Enchegar Fuent") +#define MSG_SWITCH_PS_OFF _UxGT("Amortar Fuent") +#define MSG_EXTRUDE _UxGT("Extruir") +#define MSG_RETRACT _UxGT("Retraer") +#define MSG_MOVE_AXIS _UxGT("Mover Eixes") +#define MSG_BED_LEVELING _UxGT("Nivelar base") +#define MSG_LEVEL_BED _UxGT("Nivelar base") +#define MSG_MOVE_X _UxGT("Mover X") +#define MSG_MOVE_Y _UxGT("Mover Y") +#define MSG_MOVE_Z _UxGT("Mover Z") +#define MSG_MOVE_E _UxGT("Extrusor") +#define MSG_MOVE_01MM _UxGT("Mover 0.1mm") +#define MSG_MOVE_1MM _UxGT("Mover 1mm") +#define MSG_MOVE_10MM _UxGT("Mover 10mm") +#define MSG_SPEED _UxGT("Velocidat") +#define MSG_BED_Z _UxGT("Base Z") +#define MSG_NOZZLE _UxGT("Boquilla") +#define MSG_BED _UxGT("Base") +#define MSG_FAN_SPEED _UxGT("Ixoriador") +#define MSG_FLOW _UxGT("Fluxo") +#define MSG_CONTROL _UxGT("Control") +#define MSG_MIN _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" Min") +#define MSG_MAX _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" Max") +#define MSG_FACTOR _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" Fact") +#define MSG_AUTOTEMP _UxGT("Temperatura Auto.") +#define MSG_ON _UxGT("On") +#define MSG_OFF _UxGT("Off") +#define MSG_PID_P _UxGT("PID-P") +#define MSG_PID_I _UxGT("PID-I") +#define MSG_PID_D _UxGT("PID-D") +#define MSG_PID_C _UxGT("PID-C") +#define MSG_SELECT _UxGT("Trigar") +#define MSG_ACC _UxGT("Aceleracion") +#define MSG_JERK _UxGT("Jerk") +#define MSG_VX_JERK _UxGT("Vx-jerk") +#define MSG_VY_JERK _UxGT("Vy-jerk") +#define MSG_VZ_JERK _UxGT("Vz-jerk") +#define MSG_VE_JERK _UxGT("Ve-jerk") +#define MSG_VMAX _UxGT("Vmax") +#define MSG_VMIN _UxGT("Vmin") +#define MSG_VTRAV_MIN _UxGT("Vel. viache min") +#define MSG_ACCELERATION MSG_ACC +#define MSG_AMAX _UxGT("Acel. max") +#define MSG_A_RETRACT _UxGT("Acel. retrac.") +#define MSG_A_TRAVEL _UxGT("Acel. Viaje") +#define MSG_STEPS_PER_MM _UxGT("Trangos/mm") +#define MSG_XSTEPS _UxGT("X trangos/mm") +#define MSG_YSTEPS _UxGT("Y trangos/mm") +#define MSG_ZSTEPS _UxGT("Z trangos/mm") +#define MSG_ESTEPS _UxGT("E trangos/mm") +#define MSG_E1STEPS _UxGT("E1 trangos/mm") +#define MSG_E2STEPS _UxGT("E2 trangos/mm") +#define MSG_E3STEPS _UxGT("E3 trangos/mm") +#define MSG_E4STEPS _UxGT("E4 trangos/mm") +#define MSG_E5STEPS _UxGT("E5 trangos/mm") +#define MSG_TEMPERATURE _UxGT("Temperatura") +#define MSG_MOTION _UxGT("Movimiento") +#define MSG_FILAMENT _UxGT("Filamento") +#define MSG_VOLUMETRIC_ENABLED _UxGT("E in mm3") +#define MSG_FILAMENT_DIAM _UxGT("Fil. Dia.") +#define MSG_CONTRAST _UxGT("Contraste") +#define MSG_STORE_EEPROM _UxGT("Alzar memoria") +#define MSG_LOAD_EEPROM _UxGT("Cargar memoria") +#define MSG_RESTORE_FAILSAFE _UxGT("Restaurar memoria") +#define MSG_REFRESH _UxGT("Tornar a cargar") +#define MSG_WATCH _UxGT("Informacion") +#define MSG_PREPARE _UxGT("Preparar") +#define MSG_TUNE _UxGT("Achustar") +#define MSG_PAUSE_PRINT _UxGT("Pausar impresion") +#define MSG_RESUME_PRINT _UxGT("Contin. impresion") +#define MSG_STOP_PRINT _UxGT("Detener Impresion") +#define MSG_CARD_MENU _UxGT("Menu de SD") +#define MSG_NO_CARD _UxGT("No i hai tarcheta") +#define MSG_DWELL _UxGT("Reposo...") +#define MSG_USERWAIT _UxGT("Aguardand ordines") +#define MSG_RESUMING _UxGT("Contin. impresion") +#define MSG_PRINT_ABORTED _UxGT("Impres. cancelada") +#define MSG_NO_MOVE _UxGT("Sin movimiento") +#define MSG_KILLED _UxGT("Aturada d'emerch.") +#define MSG_STOPPED _UxGT("Aturada.") +#define MSG_CONTROL_RETRACT _UxGT("Retraer mm") +#define MSG_CONTROL_RETRACT_SWAP _UxGT("Swap Retraer mm") +#define MSG_CONTROL_RETRACTF _UxGT("Retraer F") +#define MSG_CONTROL_RETRACT_ZLIFT _UxGT("Devantar mm") +#define MSG_CONTROL_RETRACT_RECOVER _UxGT("DesRet mm") +#define MSG_CONTROL_RETRACT_RECOVER_SWAP _UxGT("Swap DesRet mm") +#define MSG_CONTROL_RETRACT_RECOVERF _UxGT("DesRet F") +#define MSG_AUTORETRACT _UxGT("Retraccion auto.") +#define MSG_FILAMENTCHANGE _UxGT("Cambear filamento") +#define MSG_INIT_SDCARD _UxGT("Encetan. tarcheta") +#define MSG_CNG_SDCARD _UxGT("Cambiar tarcheta") +#define MSG_ZPROBE_OUT _UxGT("Sonda Z fuera") +#define MSG_BLTOUCH_SELFTEST _UxGT("BLTouch Auto-Test") +#define MSG_BLTOUCH_RESET _UxGT("Reset BLTouch") +#define MSG_HOME _UxGT("Home") // Used as MSG_HOME " " MSG_X MSG_Y MSG_Z " " MSG_FIRST +#define MSG_FIRST _UxGT("first") +#define MSG_ZPROBE_ZOFFSET _UxGT("Desfase Z") +#define MSG_BABYSTEP_X _UxGT("Micropaso X") +#define MSG_BABYSTEP_Y _UxGT("Micropaso Y") +#define MSG_BABYSTEP_Z _UxGT("Micropaso Z") +#define MSG_ENDSTOP_ABORT _UxGT("Cancelado - Endstop") +#define MSG_HEATING_FAILED_LCD _UxGT("Error: en calentar") +#define MSG_ERR_REDUNDANT_TEMP _UxGT("Error: temperatura") +#define MSG_THERMAL_RUNAWAY _UxGT("Error de temperatura") +#define MSG_ERR_MAXTEMP _UxGT("Error: Temp Maxima") +#define MSG_ERR_MINTEMP _UxGT("Error: Temp Menima") +#define MSG_ERR_MAXTEMP_BED _UxGT("Error: Temp Max base") +#define MSG_ERR_MINTEMP_BED _UxGT("Error: Temp Min base") +#define MSG_ERR_Z_HOMING _UxGT("G28 Z vedau") +#define MSG_HALTED _UxGT("IMPRESORA ATURADA") +#define MSG_PLEASE_RESET _UxGT("Per favor reinic.") +#define MSG_SHORT_DAY _UxGT("d") +#define MSG_SHORT_HOUR _UxGT("h") +#define MSG_SHORT_MINUTE _UxGT("m") +#define MSG_HEATING _UxGT("Calentando...") +#define MSG_HEATING_COMPLETE _UxGT("Calentamiento listo") +#define MSG_BED_HEATING _UxGT("Calentando base...") +#define MSG_BED_DONE _UxGT("Base calient") +#define MSG_DELTA_CALIBRATE _UxGT("Calibracion Delta") +#define MSG_DELTA_CALIBRATE_X _UxGT("Calibrar X") +#define MSG_DELTA_CALIBRATE_Y _UxGT("Calibrar Y") +#define MSG_DELTA_CALIBRATE_Z _UxGT("Calibrar Z") +#define MSG_DELTA_CALIBRATE_CENTER _UxGT("Calibrar Centro") + +#define MSG_INFO_MENU _UxGT("Inf. Impresora") +#define MSG_INFO_PRINTER_MENU _UxGT("Inf. Impresora") +#define MSG_INFO_STATS_MENU _UxGT("Estadisticas Imp.") +#define MSG_INFO_BOARD_MENU _UxGT("Inf. Controlador") +#define MSG_INFO_THERMISTOR_MENU _UxGT("Termistors") +#define MSG_INFO_EXTRUDERS _UxGT("Extrusors") +#define MSG_INFO_BAUDRATE _UxGT("Baudios") +#define MSG_INFO_PROTOCOL _UxGT("Protocolo") +#define MSG_CASE_LIGHT _UxGT("Luz") + +#if LCD_WIDTH >= 20 + #define MSG_INFO_PRINT_COUNT _UxGT("Conteo de impresion") + #define MSG_INFO_COMPLETED_PRINTS _UxGT("Completadas") + #define MSG_INFO_PRINT_TIME _UxGT("Tiempo total d'imp.") + #define MSG_INFO_PRINT_LONGEST _UxGT("Impresion mas larga") + #define MSG_INFO_PRINT_FILAMENT _UxGT("Total d'extrusion") +#else + #define MSG_INFO_PRINT_COUNT _UxGT("Impresions") + #define MSG_INFO_COMPLETED_PRINTS _UxGT("Completadas") + #define MSG_INFO_PRINT_TIME _UxGT("Total") + #define MSG_INFO_PRINT_LONGEST _UxGT("Mas larga") + #define MSG_INFO_PRINT_FILAMENT _UxGT("Extrusion") +#endif + +#define MSG_INFO_MIN_TEMP _UxGT("Temperatura menima") +#define MSG_INFO_MAX_TEMP _UxGT("Temperatura maxima") +#define MSG_INFO_PSU _UxGT("Fuente de aliment") + +#define MSG_DRIVE_STRENGTH _UxGT("Fuerza d'o driver") +#define MSG_DAC_PERCENT _UxGT("Driver %") +#define MSG_DAC_EEPROM_WRITE _UxGT("Escri. DAC EEPROM") +#define MSG_FILAMENT_CHANGE_HEADER _UxGT("PRINT PAUSED") +#define MSG_FILAMENT_CHANGE_OPTION_HEADER _UxGT("RESUME OPTIONS:") +#define MSG_FILAMENT_CHANGE_OPTION_EXTRUDE _UxGT("Extruir mas") +#define MSG_FILAMENT_CHANGE_OPTION_RESUME _UxGT("Resumir imp.") + +// +// Filament Change screens show up to 3 lines on a 4-line display +// ...or up to 2 lines on a 3-line display +// +#define MSG_FILAMENT_CHANGE_INIT_1 _UxGT("Aguardand iniciar") + +#define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("Meta o filamento") +#define MSG_FILAMENT_CHANGE_INSERT_2 _UxGT("y prete lo boton") + +#if LCD_HEIGHT >= 4 + // Up to 3 lines allowed + #define MSG_FILAMENT_CHANGE_INIT_2 _UxGT("d'o filamento") + #define MSG_FILAMENT_CHANGE_INIT_3 _UxGT("cambear") + #define MSG_FILAMENT_CHANGE_INSERT_3 _UxGT("pa continar...") +#else // LCD_HEIGHT < 4 + // Up to 2 lines allowed + #define MSG_FILAMENT_CHANGE_INIT_2 _UxGT("d'o fil. cambear") + #define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("Meta o filamento") +#endif // LCD_HEIGHT < 4 + +#define MSG_FILAMENT_CHANGE_UNLOAD_1 _UxGT("Aguardando a") +#define MSG_FILAMENT_CHANGE_UNLOAD_2 _UxGT("expulsar filament") +#define MSG_FILAMENT_CHANGE_LOAD_1 _UxGT("Aguardando a") +#define MSG_FILAMENT_CHANGE_LOAD_2 _UxGT("cargar filamento") +#define MSG_FILAMENT_CHANGE_EXTRUDE_1 _UxGT("Aguardando a") +#define MSG_FILAMENT_CHANGE_EXTRUDE_2 _UxGT("extruir filamento") +#define MSG_FILAMENT_CHANGE_RESUME_1 _UxGT("Aguardando impre.") +#define MSG_FILAMENT_CHANGE_RESUME_2 _UxGT("pa continar") + +#endif // LANGUAGE_AN_H diff --git a/trunk/Arduino/Marlin_1.1.6/language_bg.h b/trunk/Arduino/Marlin_1.1.6/language_bg.h new file mode 100644 index 00000000..d256af8f --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/language_bg.h @@ -0,0 +1,143 @@ +/** + * 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 . + * + */ + +/** + * Bulgarian + * + * LCD Menu Messages + * See also http://marlinfw.org/docs/development/lcd_language.html + * + */ +#ifndef LANGUAGE_BG_H +#define LANGUAGE_BG_H + +#define MAPPER_D0D1 // For Cyrillic +#define DISPLAY_CHARSET_ISO10646_5 + +#define WELCOME_MSG MACHINE_NAME _UxGT(" Готов.") +#define MSG_SD_INSERTED _UxGT("Картата е поставена") +#define MSG_SD_REMOVED _UxGT("Картата е извадена") +#define MSG_MAIN _UxGT("Меню") +#define MSG_AUTOSTART _UxGT("Автостарт") +#define MSG_DISABLE_STEPPERS _UxGT("Изкл. двигатели") +#define MSG_AUTO_HOME _UxGT("Паркиране") +#define MSG_SET_HOME_OFFSETS _UxGT("Задай Начало") +#define MSG_SET_ORIGIN _UxGT("Изходна точка") +#define MSG_PREHEAT_1 _UxGT("Подгряване PLA") +#define MSG_PREHEAT_1_N _UxGT("Подгряване PLA") +#define MSG_PREHEAT_1_ALL _UxGT("Подгр. PLA Всички") +#define MSG_PREHEAT_1_BEDONLY _UxGT("Подгр. PLA Легло") +#define MSG_PREHEAT_1_SETTINGS _UxGT("Настройки PLA") +#define MSG_PREHEAT_2 _UxGT("Подгряване ABS") +#define MSG_PREHEAT_2_N _UxGT("Подгряване ABS") +#define MSG_PREHEAT_2_ALL _UxGT("Подгр. ABS Всички") +#define MSG_PREHEAT_2_BEDONLY _UxGT("Подгр. ABS Легло") +#define MSG_PREHEAT_2_SETTINGS _UxGT("Настройки ABS") +#define MSG_COOLDOWN _UxGT("Охлаждане") +#define MSG_SWITCH_PS_ON _UxGT("Вкл. захранване") +#define MSG_SWITCH_PS_OFF _UxGT("Изкл. захранване") +#define MSG_EXTRUDE _UxGT("Екструзия") +#define MSG_RETRACT _UxGT("Откат") +#define MSG_MOVE_AXIS _UxGT("Движение по ос") +#define MSG_BED_LEVELING _UxGT("Нивелиране") +#define MSG_LEVEL_BED _UxGT("Нивелиране") +#define MSG_MOVE_X _UxGT("Движение по X") +#define MSG_MOVE_Y _UxGT("Движение по Y") +#define MSG_MOVE_Z _UxGT("Движение по Z") +#define MSG_MOVE_E _UxGT("Екструдер") +#define MSG_MOVE_01MM _UxGT("Премести с 0.1mm") +#define MSG_MOVE_1MM _UxGT("Премести с 1mm") +#define MSG_MOVE_10MM _UxGT("Премести с 10mm") +#define MSG_SPEED _UxGT("Скорост") +#define MSG_BED_Z _UxGT("Bed Z") +#define MSG_NOZZLE LCD_STR_THERMOMETER _UxGT(" Дюза") +#define MSG_BED LCD_STR_THERMOMETER _UxGT(" Легло") +#define MSG_FAN_SPEED _UxGT("Вентилатор") +#define MSG_FLOW _UxGT("Поток") +#define MSG_CONTROL _UxGT("Управление") +#define MSG_MIN LCD_STR_THERMOMETER _UxGT(" Минимум") +#define MSG_MAX LCD_STR_THERMOMETER _UxGT(" Максимум") +#define MSG_FACTOR LCD_STR_THERMOMETER _UxGT(" Фактор") +#define MSG_AUTOTEMP _UxGT("Авто-темп.") +#define MSG_ON _UxGT("Вкл. ") +#define MSG_OFF _UxGT("Изкл. ") +#define MSG_A_RETRACT _UxGT("A-откат") +#define MSG_A_TRAVEL _UxGT("A-travel") +#define MSG_STEPS_PER_MM _UxGT("Стъпки/mm") +#define MSG_XSTEPS _UxGT("X стъпки/mm") +#define MSG_YSTEPS _UxGT("Y стъпки/mm") +#define MSG_ZSTEPS _UxGT("Z стъпки/mm") +#define MSG_ESTEPS _UxGT("E стъпки/mm") +#define MSG_E1STEPS _UxGT("E1 стъпки/mm") +#define MSG_E2STEPS _UxGT("E2 стъпки/mm") +#define MSG_E3STEPS _UxGT("E3 стъпки/mm") +#define MSG_E4STEPS _UxGT("E4 стъпки/mm") +#define MSG_E5STEPS _UxGT("E5 стъпки/mm") +#define MSG_TEMPERATURE _UxGT("Температура") +#define MSG_MOTION _UxGT("Движение") +#define MSG_FILAMENT _UxGT("Нишка") +#define MSG_VOLUMETRIC_ENABLED _UxGT("E in mm3") +#define MSG_FILAMENT_DIAM _UxGT("Диам. нишка") +#define MSG_CONTRAST _UxGT("LCD контраст") +#define MSG_STORE_EEPROM _UxGT("Запази в EPROM") +#define MSG_LOAD_EEPROM _UxGT("Зареди от EPROM") +#define MSG_RESTORE_FAILSAFE _UxGT("Фабрични настройки") +#define MSG_REFRESH LCD_STR_REFRESH _UxGT("Обнови") +#define MSG_WATCH _UxGT("Преглед") +#define MSG_PREPARE _UxGT("Действия") +#define MSG_TUNE _UxGT("Настройка") +#define MSG_PAUSE_PRINT _UxGT("Пауза") +#define MSG_RESUME_PRINT _UxGT("Възобнови печата") +#define MSG_STOP_PRINT _UxGT("Спри печата") +#define MSG_CARD_MENU _UxGT("Меню карта") +#define MSG_NO_CARD _UxGT("Няма карта") +#define MSG_DWELL _UxGT("Почивка...") +#define MSG_USERWAIT _UxGT("Изчакване") +#define MSG_RESUMING _UxGT("Продълж. печата") +#define MSG_PRINT_ABORTED _UxGT("Печатът е прекъснат") +#define MSG_NO_MOVE _UxGT("Няма движение") +#define MSG_KILLED _UxGT("УБИТО.") +#define MSG_STOPPED _UxGT("СПРЯНО.") +#define MSG_CONTROL_RETRACT _UxGT("Откат mm") +#define MSG_CONTROL_RETRACT_SWAP _UxGT("Смяна Откат mm") +#define MSG_CONTROL_RETRACTF _UxGT("Откат V") +#define MSG_CONTROL_RETRACT_ZLIFT _UxGT("Скок mm") +#define MSG_CONTROL_RETRACT_RECOVER _UxGT("Възврат mm") +#define MSG_CONTROL_RETRACT_RECOVER_SWAP _UxGT("Смяна Възврат mm") +#define MSG_CONTROL_RETRACT_RECOVERF _UxGT("Възврат V") +#define MSG_AUTORETRACT _UxGT("Автоoткат") +#define MSG_FILAMENTCHANGE _UxGT("Смяна нишка") +#define MSG_INIT_SDCARD _UxGT("Иниц. SD-Карта") +#define MSG_CNG_SDCARD _UxGT("Смяна SD-Карта") +#define MSG_ZPROBE_OUT _UxGT("Z-сондата е извадена") +#define MSG_ZPROBE_ZOFFSET _UxGT("Z Отстояние") +#define MSG_BABYSTEP_X _UxGT("Министъпка X") +#define MSG_BABYSTEP_Y _UxGT("Министъпка Y") +#define MSG_BABYSTEP_Z _UxGT("Министъпка Z") +#define MSG_ENDSTOP_ABORT _UxGT("Стоп Кр.Изключватели") +#define MSG_DELTA_CALIBRATE _UxGT("Делта Калибровка") +#define MSG_DELTA_CALIBRATE_X _UxGT("Калибровка X") +#define MSG_DELTA_CALIBRATE_Y _UxGT("Калибровка Y") +#define MSG_DELTA_CALIBRATE_Z _UxGT("Калибровка Z") +#define MSG_DELTA_CALIBRATE_CENTER _UxGT("Калибровка Център") + +#endif // LANGUAGE_BG_H diff --git a/trunk/Arduino/Marlin_1.1.6/language_ca.h b/trunk/Arduino/Marlin_1.1.6/language_ca.h new file mode 100644 index 00000000..54137f7d --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/language_ca.h @@ -0,0 +1,261 @@ +/** + * 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 . + * + */ + +/** + * Catalan + * + * LCD Menu Messages + * See also http://marlinfw.org/docs/development/lcd_language.html + * + */ +#ifndef LANGUAGE_CA_H +#define LANGUAGE_CA_H + +#define MAPPER_C2C3 // because of "ó" +#define DISPLAY_CHARSET_ISO10646_1 + +#define WELCOME_MSG MACHINE_NAME _UxGT(" preparada.") +#define MSG_SD_INSERTED _UxGT("Targeta detectada.") +#define MSG_SD_REMOVED _UxGT("Targeta extreta.") +#define MSG_LCD_ENDSTOPS _UxGT("Endstops") +#define MSG_MAIN _UxGT("Menú principal") +#define MSG_AUTOSTART _UxGT("Inici automatic") +#define MSG_DISABLE_STEPPERS _UxGT("Desactiva motors") +#define MSG_DEBUG_MENU _UxGT("Menu de depuracio") +#define MSG_PROGRESS_BAR_TEST _UxGT("Test barra progres") +#define MSG_AUTO_HOME _UxGT("Ves a l'origen") +#define MSG_AUTO_HOME_X _UxGT("X a origen") +#define MSG_AUTO_HOME_Y _UxGT("Y a origen") +#define MSG_AUTO_HOME_Z _UxGT("Z a origen") +#define MSG_LEVEL_BED_HOMING _UxGT("Origen XYZ") +#define MSG_LEVEL_BED_WAITING _UxGT("Premeu per iniciar") +#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Següent punt") +#define MSG_LEVEL_BED_DONE _UxGT("Anivellament fet!") +#define MSG_SET_HOME_OFFSETS _UxGT("Ajusta decalatge") +#define MSG_HOME_OFFSETS_APPLIED _UxGT("Decalatge aplicat") +#define MSG_SET_ORIGIN _UxGT("Estableix origen") +#define MSG_PREHEAT_1 _UxGT("Preescalfa PLA") +#define MSG_PREHEAT_1_N MSG_PREHEAT_1 _UxGT(" ") +#define MSG_PREHEAT_1_ALL MSG_PREHEAT_1 _UxGT(" Tot") +#define MSG_PREHEAT_1_BEDONLY MSG_PREHEAT_1 _UxGT(" Llit") +#define MSG_PREHEAT_1_SETTINGS MSG_PREHEAT_1 _UxGT(" Conf.") +#define MSG_PREHEAT_2 _UxGT("Preescalfa ABS") +#define MSG_PREHEAT_2_N MSG_PREHEAT_2 _UxGT(" ") +#define MSG_PREHEAT_2_ALL MSG_PREHEAT_2 _UxGT(" Tot") +#define MSG_PREHEAT_2_BEDONLY MSG_PREHEAT_2 _UxGT(" Llit") +#define MSG_PREHEAT_2_SETTINGS MSG_PREHEAT_2 _UxGT(" Conf.") +#define MSG_COOLDOWN _UxGT("Refreda") +#define MSG_SWITCH_PS_ON _UxGT("Switch power on") +#define MSG_SWITCH_PS_OFF _UxGT("Switch power off") +#define MSG_EXTRUDE _UxGT("Extrudeix") +#define MSG_RETRACT _UxGT("Retreu") +#define MSG_MOVE_AXIS _UxGT("Mou eixos") +#define MSG_BED_LEVELING _UxGT("Anivella llit") +#define MSG_LEVEL_BED _UxGT("Anivella llit") +#define MSG_MOVING _UxGT("Movent..") +#define MSG_FREE_XY _UxGT("XY lliures") +#define MSG_MOVE_X _UxGT("Mou X") +#define MSG_MOVE_Y _UxGT("Mou Y") +#define MSG_MOVE_Z _UxGT("Mou Z") +#define MSG_MOVE_E _UxGT("Extrusor") +#define MSG_MOVE_01MM _UxGT("Mou 0.1mm") +#define MSG_MOVE_1MM _UxGT("Mou 1mm") +#define MSG_MOVE_10MM _UxGT("Mou 10mm") +#define MSG_SPEED _UxGT("Velocitat") +#define MSG_BED_Z _UxGT("Llit Z") +#define MSG_NOZZLE _UxGT("Nozzle") +#define MSG_BED _UxGT("Llit") +#define MSG_FAN_SPEED _UxGT("Vel. Ventilador") +#define MSG_FLOW _UxGT("Flux") +#define MSG_CONTROL _UxGT("Control") +#define MSG_MIN LCD_STR_THERMOMETER _UxGT(" Min") +#define MSG_MAX LCD_STR_THERMOMETER _UxGT(" Max") +#define MSG_FACTOR LCD_STR_THERMOMETER _UxGT(" Fact") +#define MSG_AUTOTEMP _UxGT("Autotemp") +#define MSG_ON _UxGT("On ") +#define MSG_OFF _UxGT("Off") +#define MSG_PID_P _UxGT("PID-P") +#define MSG_PID_I _UxGT("PID-I") +#define MSG_PID_D _UxGT("PID-D") +#define MSG_PID_C _UxGT("PID-C") +#define MSG_SELECT _UxGT("Select") +#define MSG_ACC _UxGT("Accel") +#define MSG_JERK _UxGT("Jerk") +#define MSG_VX_JERK _UxGT("Vx-jerk") +#define MSG_VY_JERK _UxGT("Vy-jerk") +#define MSG_VZ_JERK _UxGT("Vz-jerk") +#define MSG_VE_JERK _UxGT("Ve-jerk") +#define MSG_VMAX _UxGT("Vmax ") +#define MSG_VMIN _UxGT("Vmin") +#define MSG_VTRAV_MIN _UxGT("VViatge min") +#define MSG_AMAX _UxGT("Accel. max ") +#define MSG_A_RETRACT _UxGT("Accel. retracc") +#define MSG_A_TRAVEL _UxGT("Accel. Viatge") +#define MSG_STEPS_PER_MM _UxGT("Passos/mm") +#define MSG_XSTEPS _UxGT("Xpassos/mm") +#define MSG_YSTEPS _UxGT("Ypassos/mm") +#define MSG_ZSTEPS _UxGT("Zpassos/mm") +#define MSG_ESTEPS _UxGT("Epassos/mm") +#define MSG_E1STEPS _UxGT("E1passos/mm") +#define MSG_E2STEPS _UxGT("E2passos/mm") +#define MSG_E3STEPS _UxGT("E3passos/mm") +#define MSG_E4STEPS _UxGT("E4passos/mm") +#define MSG_E5STEPS _UxGT("E5passos/mm") +#define MSG_TEMPERATURE _UxGT("Temperatura") +#define MSG_MOTION _UxGT("Moviment") +#define MSG_FILAMENT _UxGT("Filament") +#define MSG_VOLUMETRIC_ENABLED _UxGT("E en mm3") +#define MSG_FILAMENT_DIAM _UxGT("Diam. Fil.") +#define MSG_CONTRAST _UxGT("Contrast de LCD") +#define MSG_STORE_EEPROM _UxGT("Desa memoria") +#define MSG_LOAD_EEPROM _UxGT("Carrega memoria") +#define MSG_RESTORE_FAILSAFE _UxGT("Restaura valors") +#define MSG_REFRESH _UxGT("Actualitza") +#define MSG_WATCH _UxGT("Pantalla Info.") +#define MSG_PREPARE _UxGT("Prepara") +#define MSG_TUNE _UxGT("Ajusta") +#define MSG_PAUSE_PRINT _UxGT("Pausa impressio") +#define MSG_RESUME_PRINT _UxGT("Repren impressio") +#define MSG_STOP_PRINT _UxGT("Atura impressio.") +#define MSG_CARD_MENU _UxGT("Imprimeix de SD") +#define MSG_NO_CARD _UxGT("No hi ha targeta") +#define MSG_DWELL _UxGT("En repos...") +#define MSG_USERWAIT _UxGT("Esperant usuari..") +#define MSG_RESUMING _UxGT("Reprenent imp.") +#define MSG_PRINT_ABORTED _UxGT("Imp. cancelada") +#define MSG_NO_MOVE _UxGT("Sense moviment.") +#define MSG_KILLED _UxGT("MATAT.") +#define MSG_STOPPED _UxGT("ATURADA.") +#define MSG_CONTROL_RETRACT _UxGT("Retreu mm") +#define MSG_CONTROL_RETRACT_SWAP _UxGT("Swap Retreure mm") +#define MSG_CONTROL_RETRACTF _UxGT("Retreu V") +#define MSG_CONTROL_RETRACT_ZLIFT _UxGT("Aixeca mm") +#define MSG_CONTROL_RETRACT_RECOVER _UxGT("DesRet +mm") +#define MSG_CONTROL_RETRACT_RECOVER_SWAP _UxGT("Swap DesRet +mm") +#define MSG_CONTROL_RETRACT_RECOVERF _UxGT("DesRet V") +#define MSG_AUTORETRACT _UxGT("Auto retraccio") +#define MSG_FILAMENTCHANGE _UxGT("Canvia filament") +#define MSG_INIT_SDCARD _UxGT("Inicialitza SD") +#define MSG_CNG_SDCARD _UxGT("Canvia SD") +#define MSG_ZPROBE_OUT _UxGT("Sonda Z fora") +#define MSG_BLTOUCH_RESET _UxGT("Reinicia BLTouch") +#define MSG_HOME _UxGT("Home") // Used as MSG_HOME " " MSG_X MSG_Y MSG_Z " " MSG_FIRST +#define MSG_FIRST _UxGT("primer") +#define MSG_ZPROBE_ZOFFSET _UxGT("Decalatge Z") +#define MSG_BABYSTEP_X _UxGT("Micropas X") +#define MSG_BABYSTEP_Y _UxGT("Micropas Y") +#define MSG_BABYSTEP_Z _UxGT("Micropas Z") +#define MSG_ENDSTOP_ABORT _UxGT("Cancel. Endstop") +#define MSG_HEATING_FAILED_LCD _UxGT("Error al escalfar") +#define MSG_ERR_REDUNDANT_TEMP _UxGT("Err: TEMP REDUNDANT") +#define MSG_THERMAL_RUNAWAY _UxGT("THERMAL RUNAWAY") +#define MSG_ERR_MAXTEMP _UxGT("Err: TEMP MAXIMA") +#define MSG_ERR_MINTEMP _UxGT("Err: TEMP MINIMA") +#define MSG_ERR_MAXTEMP_BED _UxGT("Err: TEMPMAX LLIT") +#define MSG_ERR_MINTEMP_BED _UxGT("Err: TEMPMIN LLIT") +#define MSG_ERR_Z_HOMING _UxGT("G28 Z No permes") +#define MSG_HALTED _UxGT("IMPRESSORA PARADA") +#define MSG_PLEASE_RESET _UxGT("Reinicieu") +#define MSG_SHORT_DAY _UxGT("d") // One character only +#define MSG_SHORT_HOUR _UxGT("h") // One character only +#define MSG_SHORT_MINUTE _UxGT("m") // One character only +#define MSG_HEATING _UxGT("Escalfant...") +#define MSG_HEATING_COMPLETE _UxGT("Escalfament fet.") +#define MSG_BED_HEATING _UxGT("Escalfant llit") +#define MSG_BED_DONE _UxGT("Llit fet.") +#define MSG_DELTA_CALIBRATE _UxGT("Calibratge Delta") +#define MSG_DELTA_CALIBRATE_X _UxGT("Calibra X") +#define MSG_DELTA_CALIBRATE_Y _UxGT("Calibra Y") +#define MSG_DELTA_CALIBRATE_Z _UxGT("Calibra Z") +#define MSG_DELTA_CALIBRATE_CENTER _UxGT("Calibra el centre") + +#define MSG_INFO_MENU _UxGT("Quant a la impr.") +#define MSG_INFO_PRINTER_MENU _UxGT("Info Impressora") +#define MSG_INFO_STATS_MENU _UxGT("Estadistiques") +#define MSG_INFO_BOARD_MENU _UxGT("Info placa") +#define MSG_INFO_THERMISTOR_MENU _UxGT("Termistors") +#define MSG_INFO_EXTRUDERS _UxGT("Extrusors") +#define MSG_INFO_BAUDRATE _UxGT("Baud") +#define MSG_INFO_PROTOCOL _UxGT("Protocol") +#define MSG_CASE_LIGHT _UxGT("Llum") + +#if LCD_WIDTH >= 20 + #define MSG_INFO_PRINT_COUNT _UxGT("Total impressions") + #define MSG_INFO_COMPLETED_PRINTS _UxGT("Acabades") + #define MSG_INFO_PRINT_TIME _UxGT("Temps imprimint") + #define MSG_INFO_PRINT_LONGEST _UxGT("Treball mes llarg") + #define MSG_INFO_PRINT_FILAMENT _UxGT("Total extrudit") +#else + #define MSG_INFO_PRINT_COUNT _UxGT("Impressions") + #define MSG_INFO_COMPLETED_PRINTS _UxGT("Acabades") + #define MSG_INFO_PRINT_TIME _UxGT("Total") + #define MSG_INFO_PRINT_LONGEST _UxGT("Mes llarg") + #define MSG_INFO_PRINT_FILAMENT _UxGT("Extrudit") +#endif + +#define MSG_INFO_MIN_TEMP _UxGT("Temp. mínima") +#define MSG_INFO_MAX_TEMP _UxGT("Temp. màxima") +#define MSG_INFO_PSU _UxGT("Font alimentacio") + +#define MSG_DRIVE_STRENGTH _UxGT("Força motor") +#define MSG_DAC_PERCENT _UxGT("Driver %") +#define MSG_DAC_EEPROM_WRITE _UxGT("DAC EEPROM Write") +#define MSG_FILAMENT_CHANGE_HEADER _UxGT("PRINT PAUSED") +#define MSG_FILAMENT_CHANGE_OPTION_HEADER _UxGT("RESUME OPTIONS:") +#define MSG_FILAMENT_CHANGE_OPTION_EXTRUDE _UxGT("Extrudeix mes") +#define MSG_FILAMENT_CHANGE_OPTION_RESUME _UxGT("Repren impressió") +#define MSG_FILAMENT_CHANGE_MINTEMP _UxGT("Temp minima es ") + +// +// 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 + #define MSG_FILAMENT_CHANGE_INIT_1 _UxGT("Esperant per") + #define MSG_FILAMENT_CHANGE_INIT_2 _UxGT("iniciar el canvi") + #define MSG_FILAMENT_CHANGE_INIT_3 _UxGT("de filament") + #define MSG_FILAMENT_CHANGE_UNLOAD_1 _UxGT("Esperant per") + #define MSG_FILAMENT_CHANGE_UNLOAD_2 _UxGT("treure filament") + #define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("Poseu filament") + #define MSG_FILAMENT_CHANGE_INSERT_2 _UxGT("i premeu el boto") + #define MSG_FILAMENT_CHANGE_INSERT_3 _UxGT("per continuar...") + #define MSG_FILAMENT_CHANGE_HEAT_1 _UxGT("Premeu boto per") + #define MSG_FILAMENT_CHANGE_HEAT_2 _UxGT("escalfar nozzle.") + #define MSG_FILAMENT_CHANGE_HEATING_1 _UxGT("Escalfant nozzle") + #define MSG_FILAMENT_CHANGE_HEATING_2 _UxGT("Espereu...") + #define MSG_FILAMENT_CHANGE_LOAD_1 _UxGT("Esperant carrega") + #define MSG_FILAMENT_CHANGE_LOAD_2 _UxGT("de filament") + #define MSG_FILAMENT_CHANGE_EXTRUDE_1 _UxGT("Esperant per") + #define MSG_FILAMENT_CHANGE_EXTRUDE_2 _UxGT("extreure filament") + #define MSG_FILAMENT_CHANGE_RESUME_1 _UxGT("Esperant per") + #define MSG_FILAMENT_CHANGE_RESUME_2 _UxGT("reprendre") +#else // LCD_HEIGHT < 4 + #define MSG_FILAMENT_CHANGE_INIT_1 _UxGT("Espereu...") + #define MSG_FILAMENT_CHANGE_UNLOAD_1 _UxGT("Expulsant...") + #define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("Insereix i prem") + #define MSG_FILAMENT_CHANGE_HEATING_1 _UxGT("Escalfant...") + #define MSG_FILAMENT_CHANGE_LOAD_1 _UxGT("Carregant...") + #define MSG_FILAMENT_CHANGE_EXTRUDE_1 _UxGT("Extrudint...") + #define MSG_FILAMENT_CHANGE_RESUME_1 _UxGT("Reprenent...") +#endif // LCD_HEIGHT < 4 + +#endif // LANGUAGE_CA_H diff --git a/trunk/Arduino/Marlin_1.1.6/language_cn.h b/trunk/Arduino/Marlin_1.1.6/language_cn.h new file mode 100644 index 00000000..f6230a01 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/language_cn.h @@ -0,0 +1,167 @@ +/** + * 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 . + * + */ + +/** + * Chinese + * + * LCD Menu Messages + * See also http://marlinfw.org/docs/development/lcd_language.html + * + */ +#ifndef LANGUAGE_CN_H +#define LANGUAGE_CN_H + +#define DISPLAY_CHARSET_ISO10646_CN + +#define WELCOME_MSG "\xa4\xa5\xa6\xa7" +#define MSG_SD_INSERTED "\xa8\xa9\xaa\xab" +#define MSG_SD_REMOVED "\xa8\xa9\xac\xad" +#define MSG_MAIN "\xae\xaf\xb0" +#define MSG_AUTOSTART "\xb1\xb2\xb3\xb4" +#define MSG_DISABLE_STEPPERS "\xb5\xb6\xb7\xb8\xb9\xba" +#define MSG_AUTO_HOME "\xbb\xbc\xbd" +#define MSG_LEVEL_BED_HOMING "Homing XYZ" +#define MSG_LEVEL_BED_WAITING "Click to Begin" +#define MSG_LEVEL_BED_DONE "Leveling Done!" +#define MSG_SET_HOME_OFFSETS "\xbe\xbf\xbb\xbc\xbd\xc0\xc1" +#define MSG_HOME_OFFSETS_APPLIED "Offsets applied" +#define MSG_SET_ORIGIN "\xbe\xbf\xbc\xbd" +#define MSG_PREHEAT_1 "\xc3\xc4 PLA" +#define MSG_PREHEAT_1_N MSG_PREHEAT_1 " " +#define MSG_PREHEAT_1_ALL MSG_PREHEAT_1 " \xc5\xc6" +#define MSG_PREHEAT_1_BEDONLY MSG_PREHEAT_1 " \xc4\xc7" +#define MSG_PREHEAT_1_SETTINGS MSG_PREHEAT_1 " \xbe\xbf" +#define MSG_PREHEAT_2 "\xc3\xc4 ABS" +#define MSG_PREHEAT_2_N MSG_PREHEAT_2 " " +#define MSG_PREHEAT_2_ALL MSG_PREHEAT_2 " \xc5\xc6" +#define MSG_PREHEAT_2_BEDONLY MSG_PREHEAT_2 " \xbe\xc6" +#define MSG_PREHEAT_2_SETTINGS MSG_PREHEAT_2 " \xbe\xbf" +#define MSG_COOLDOWN "\xc8\xc9" +#define MSG_SWITCH_PS_ON "\xb9\xcb\xca\xb3" +#define MSG_SWITCH_PS_OFF "\xb9\xcb\xb5\xb6" +#define MSG_EXTRUDE "\xcc\xad" +#define MSG_RETRACT "\xbb\xcd" +#define MSG_MOVE_AXIS "\xc1\xb2\xce" +#define MSG_BED_LEVELING "\xcf\xe0\xc4\xc7" +#define MSG_LEVEL_BED "\xcf\xe0\xc4\xc7" +#define MSG_MOVE_X "\xc1\xb2 X" +#define MSG_MOVE_Y "\xc1\xb2 Y" +#define MSG_MOVE_Z "\xc1\xb2 Z" +#define MSG_MOVE_E "\xcc\xad\xba" +#define MSG_MOVE_01MM "\xc1\xb2 0.1mm" +#define MSG_MOVE_1MM "\xc1\xb2 1mm" +#define MSG_MOVE_10MM "\xc1\xb2 10mm" +#define MSG_SPEED "\xd1\xd2" +#define MSG_NOZZLE "\xd3\xd4" +#define MSG_BED "\xc4\xc7" +#define MSG_FAN_SPEED "\xd5\xd6\xd1\xd2" +#define MSG_FLOW "\xcc\xad\xd1\xd2" +#define MSG_CONTROL "\xd8\xd9" +#define MSG_MIN LCD_STR_THERMOMETER " \xda\xdb" +#define MSG_MAX LCD_STR_THERMOMETER " \xda\xdc" +#define MSG_FACTOR LCD_STR_THERMOMETER " \xdd\xde" +#define MSG_AUTOTEMP "\xb1\xb2\xd8\xc9" +#define MSG_ON "\xb3 " // intentional space to shift wide symbol to the left +#define MSG_OFF "\xb5 " // intentional space to shift wide symbol to the left +#define MSG_PID_P "PID-P" +#define MSG_PID_I "PID-I" +#define MSG_PID_D "PID-D" +#define MSG_PID_C "PID-C" +#define MSG_ACC "Accel" +#define MSG_JERK "Jerk" +#define MSG_VX_JERK "Vx-jerk" +#define MSG_VY_JERK "Vy-jerk" +#define MSG_VZ_JERK "Vz-jerk" +#define MSG_VE_JERK "Ve-jerk" +#define MSG_VMAX "Vmax " +#define MSG_VMIN "Vmin" +#define MSG_VTRAV_MIN "VTrav min" +#define MSG_AMAX "Amax " +#define MSG_A_RETRACT "A-retract" +#define MSG_A_TRAVEL "A-travel" +#define MSG_STEPS_PER_MM "Steps/mm" +#define MSG_XSTEPS "Xsteps/mm" +#define MSG_YSTEPS "Ysteps/mm" +#define MSG_ZSTEPS "Zsteps/mm" +#define MSG_ESTEPS "Esteps/mm" +#define MSG_E1STEPS "E1steps/mm" +#define MSG_E2STEPS "E2steps/mm" +#define MSG_E3STEPS "E3steps/mm" +#define MSG_E4STEPS "E4steps/mm" +#define MSG_E5STEPS "E5steps/mm" +#define MSG_TEMPERATURE "\xc9\xd2" +#define MSG_MOTION "\xdf\xb2" +#define MSG_FILAMENT "Filament" +#define MSG_VOLUMETRIC_ENABLED "E in mm3" +#define MSG_FILAMENT_DIAM "Fil. Dia." +#define MSG_CONTRAST "LCD contrast" +#define MSG_STORE_EEPROM "Store memory" +#define MSG_LOAD_EEPROM "Load memory" +#define MSG_RESTORE_FAILSAFE "Restore failsafe" +#define MSG_REFRESH "Refresh" +#define MSG_WATCH "\xec\xed\xee\xef" +#define MSG_PREPARE "\xa4\xa5" +#define MSG_TUNE "\xcf\xf0" +#define MSG_PAUSE_PRINT "\xf1\xf2\xca\xf3" +#define MSG_RESUME_PRINT "\xf4\xf5\xca\xf3" +#define MSG_STOP_PRINT "\xf2\xf6\xca\xf3" +#define MSG_CARD_MENU "\xaf\xb0" +#define MSG_NO_CARD "\xf9\xa8" +#define MSG_DWELL "Sleep..." +#define MSG_USERWAIT "Wait for user..." +#define MSG_RESUMING "Resuming print" +#define MSG_PRINT_ABORTED "Print aborted" +#define MSG_NO_MOVE "No move." +#define MSG_KILLED "KILLED. " +#define MSG_STOPPED "STOPPED. " +#define MSG_CONTROL_RETRACT "Retract mm" +#define MSG_CONTROL_RETRACT_SWAP "Swap Re.mm" +#define MSG_CONTROL_RETRACTF "Retract V" +#define MSG_CONTROL_RETRACT_ZLIFT "Hop mm" +#define MSG_CONTROL_RETRACT_RECOVER "UnRet mm" +#define MSG_CONTROL_RETRACT_RECOVER_SWAP "S UnRet mm" +#define MSG_CONTROL_RETRACT_RECOVERF "UnRet V" +#define MSG_AUTORETRACT "AutoRetr." +#define MSG_FILAMENTCHANGE "Change filament" +#define MSG_INIT_SDCARD "Init. SD card" +#define MSG_CNG_SDCARD "Change SD card" +#define MSG_ZPROBE_OUT "Z probe out. bed" +#define MSG_HOME "Home" // Used as MSG_HOME " " MSG_X MSG_Y MSG_Z " " MSG_FIRST +#define MSG_FIRST "first" +#define MSG_ZPROBE_ZOFFSET "Z Offset" +#define MSG_BABYSTEP_X "Babystep X" +#define MSG_BABYSTEP_Y "Babystep Y" +#define MSG_BABYSTEP_Z "Babystep Z" +#define MSG_ENDSTOP_ABORT "Endstop abort" +#define MSG_HEATING_FAILED_LCD "Heating failed" +#define MSG_ERR_REDUNDANT_TEMP "Err: REDUNDANT TEMP" +#define MSG_THERMAL_RUNAWAY "THERMAL RUNAWAY" +#define MSG_ERR_MAXTEMP "Err: MAXTEMP" +#define MSG_ERR_MINTEMP "Err: MINTEMP" +#define MSG_ERR_MAXTEMP_BED "Err: MAXTEMP BED" +#define MSG_DELTA_CALIBRATE "Delta Calibration" +#define MSG_DELTA_CALIBRATE_X "Calibrate X" +#define MSG_DELTA_CALIBRATE_Y "Calibrate Y" +#define MSG_DELTA_CALIBRATE_Z "Calibrate Z" +#define MSG_DELTA_CALIBRATE_CENTER "Calibrate Center" + +#endif // LANGUAGE_CN_H diff --git a/trunk/Arduino/Marlin_1.1.6/language_cz.h b/trunk/Arduino/Marlin_1.1.6/language_cz.h new file mode 100644 index 00000000..edcc9610 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/language_cz.h @@ -0,0 +1,349 @@ +/** + * 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 . + * + */ + +/** + * Czech + * + * LCD Menu Messages + * See also http://marlinfw.org/docs/development/lcd_language.html + * + * Translated by Petr Zahradnik, Computer Laboratory + * Blog and video blog Zahradnik se bavi + * http://www.zahradniksebavi.cz + * + */ +#ifndef LANGUAGE_CZ_H +#define LANGUAGE_CZ_H + +#define DISPLAY_CHARSET_ISO10646_1 + +#define WELCOME_MSG MACHINE_NAME _UxGT(" pripraven.") +#define MSG_BACK _UxGT("Zpet") +#define MSG_SD_INSERTED _UxGT("Karta vlozena") +#define MSG_SD_REMOVED _UxGT("Karta vyjmuta") +#define MSG_LCD_ENDSTOPS _UxGT("Endstopy") // max 8 znaku +#define MSG_MAIN _UxGT("Hlavni nabidka") +#define MSG_AUTOSTART _UxGT("Autostart") +#define MSG_DISABLE_STEPPERS _UxGT("Uvolnit motory") +#define MSG_DEBUG_MENU _UxGT("Nabidka ladeni") +#define MSG_PROGRESS_BAR_TEST _UxGT("Test uk.prubehu") +#define MSG_AUTO_HOME _UxGT("Domovska pozice") +#define MSG_AUTO_HOME_X _UxGT("Domu osa X") +#define MSG_AUTO_HOME_Y _UxGT("Domu osa Y") +#define MSG_AUTO_HOME_Z _UxGT("Domu osa Z") +#define MSG_LEVEL_BED_HOMING _UxGT("Mereni podlozky") +#define MSG_LEVEL_BED_WAITING _UxGT("Kliknutim spustte") +#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Dalsi bod") +#define MSG_LEVEL_BED_DONE _UxGT("Mereni hotovo!") +#define MSG_Z_FADE_HEIGHT _UxGT("Vyska srovnavani") +#define MSG_SET_HOME_OFFSETS _UxGT("Nastavit ofsety") +#define MSG_HOME_OFFSETS_APPLIED _UxGT("Ofsety nastaveny") +#define MSG_SET_ORIGIN _UxGT("Nastavit pocatek") +#define MSG_PREHEAT_1 _UxGT("Zahrat PLA") +#define MSG_PREHEAT_1_N MSG_PREHEAT_1 _UxGT(" ") +#define MSG_PREHEAT_1_ALL MSG_PREHEAT_1 _UxGT(" vse") +#define MSG_PREHEAT_1_END MSG_PREHEAT_1 _UxGT(" hotend") +#define MSG_PREHEAT_1_BEDONLY MSG_PREHEAT_1 _UxGT(" podloz") +#define MSG_PREHEAT_1_SETTINGS MSG_PREHEAT_1 _UxGT(" nast") +#define MSG_PREHEAT_2 _UxGT("Zahrat ABS") +#define MSG_PREHEAT_2_N MSG_PREHEAT_2 _UxGT(" ") +#define MSG_PREHEAT_2_ALL MSG_PREHEAT_2 _UxGT(" vse") +#define MSG_PREHEAT_2_END MSG_PREHEAT_2 _UxGT(" hotend") +#define MSG_PREHEAT_2_BEDONLY MSG_PREHEAT_2 _UxGT(" podloz") +#define MSG_PREHEAT_2_SETTINGS MSG_PREHEAT_2 _UxGT(" nast") +#define MSG_COOLDOWN _UxGT("Zchladit") +#define MSG_SWITCH_PS_ON _UxGT("Zapnout napajeni") +#define MSG_SWITCH_PS_OFF _UxGT("Vypnout napajeni") +#define MSG_EXTRUDE _UxGT("Vytlacit (extr.)") +#define MSG_RETRACT _UxGT("Zatlacit (retr.)") +#define MSG_MOVE_AXIS _UxGT("Posunout osy") +#define MSG_BED_LEVELING _UxGT("Vyrovnat podlozku") +#define MSG_LEVEL_BED _UxGT("Vyrovnat podlozku") +#define MSG_EDITING_STOPPED _UxGT("Konec uprav site") + +#define MSG_UBL_DOING_G29 _UxGT("Provadim G29") +#define MSG_UBL_UNHOMED _UxGT("Prejedte domu") +#define MSG_UBL_TOOLS _UxGT("UBL nastroje") +#define MSG_UBL_LEVEL_BED _UxGT("Unified Bed Leveling") +#define MSG_UBL_MANUAL_MESH _UxGT("Manualni sit bodu") +#define MSG_UBL_BC_INSERT _UxGT("Vlozte kartu, zmerte") +#define MSG_UBL_BC_INSERT2 _UxGT("Zmerte") +#define MSG_UBL_BC_REMOVE _UxGT("Odstrante a zmerte") +#define MSG_UBL_MOVING_TO_NEXT _UxGT("Presoun na dalsi") +#define MSG_UBL_ACTIVATE_MESH _UxGT("Aktivovat UBL") +#define MSG_UBL_DEACTIVATE_MESH _UxGT("Deaktivovat UBL") +#define MSG_UBL_SET_BED_TEMP _UxGT("Teplota podlozky") +#define MSG_UBL_CUSTOM_BED_TEMP MSG_UBL_SET_BED_TEMP +#define MSG_UBL_SET_HOTEND_TEMP _UxGT("Teplota hotendu") +#define MSG_UBL_CUSTOM_HOTEND_TEMP MSG_UBL_SET_HOTEND_TEMP +#define MSG_UBL_EDIT_CUSTOM_MESH _UxGT("Upravit vlastni sit") +#define MSG_UBL_FINE_TUNE_MESH _UxGT("Doladit sit bodu") +#define MSG_UBL_DONE_EDITING_MESH _UxGT("Konec uprav site") +#define MSG_UBL_BUILD_CUSTOM_MESH _UxGT("Vlastni sit") +#define MSG_UBL_BUILD_MESH_MENU _UxGT("Vytvorit sit") +#define MSG_UBL_BUILD_PLA_MESH _UxGT("Sit bodu PLA") +#define MSG_UBL_BUILD_ABS_MESH _UxGT("Sit bodu ABS") +#define MSG_UBL_BUILD_COLD_MESH _UxGT("Studena sit bodu") +#define MSG_UBL_MESH_HEIGHT_ADJUST _UxGT("Upravit vysku site") +#define MSG_UBL_MESH_HEIGHT_AMOUNT _UxGT("Vyska") +#define MSG_UBL_VALIDATE_MESH_MENU _UxGT("Zkontrolovat sit") +#define MSG_UBL_VALIDATE_PLA_MESH _UxGT("Kontrola site PLA") +#define MSG_UBL_VALIDATE_ABS_MESH _UxGT("Kontrola site ABS") +#define MSG_UBL_VALIDATE_CUSTOM_MESH _UxGT("Kontrola vlast. site") +#define MSG_UBL_CONTINUE_MESH _UxGT("Pokracovat v siti") +#define MSG_UBL_MESH_LEVELING _UxGT("Sitove rovnani") +#define MSG_UBL_3POINT_MESH_LEVELING _UxGT("3-bodove rovnani") +#define MSG_UBL_GRID_MESH_LEVELING _UxGT("Mrizkove rovnani") +#define MSG_UBL_MESH_LEVEL _UxGT("Srovnat podlozku") +#define MSG_UBL_SIDE_POINTS _UxGT("Postranni body") +#define MSG_UBL_MAP_TYPE _UxGT("Typ site bodu") +#define MSG_UBL_OUTPUT_MAP _UxGT("Exportovat sit") +#define MSG_UBL_OUTPUT_MAP_HOST _UxGT("Exportovat do PC") +#define MSG_UBL_OUTPUT_MAP_CSV _UxGT("Exportovat do CSV") +#define MSG_UBL_OUTPUT_MAP_BACKUP _UxGT("Zaloha do PC") +#define MSG_UBL_INFO_UBL _UxGT("Info o UBL do PC") +#define MSG_UBL_EDIT_MESH_MENU _UxGT("Upravit sit dobu") +#define MSG_UBL_FILLIN_AMOUNT _UxGT("Hustota mrizky") +#define MSG_UBL_MANUAL_FILLIN _UxGT("Rucni hustota") +#define MSG_UBL_SMART_FILLIN _UxGT("Chytra hustota") +#define MSG_UBL_FILLIN_MESH _UxGT("Zaplnit mrizku") +#define MSG_UBL_INVALIDATE_ALL _UxGT("Zrusit vsechno") +#define MSG_UBL_INVALIDATE_CLOSEST _UxGT("Zrusit posledni") +#define MSG_UBL_FINE_TUNE_ALL _UxGT("Upravit vsechny") +#define MSG_UBL_FINE_TUNE_CLOSEST _UxGT("Upravit posledni") +#define MSG_UBL_STORAGE_MESH_MENU _UxGT("Uloziste siti") +#define MSG_UBL_STORAGE_SLOT _UxGT("Pametovy slot") +#define MSG_UBL_LOAD_MESH _UxGT("Nacist sit bodu") +#define MSG_UBL_SAVE_MESH _UxGT("Ulozit sit bodu") +#define MSG_UBL_SAVE_ERROR _UxGT("Err: Ulozit UBL") +#define MSG_UBL_RESTORE_ERROR _UxGT("Err: Obnovit UBL") +#define MSG_UBL_Z_OFFSET_STOPPED _UxGT("Konec Z-Offsetu") +#define MSG_UBL_STEP_BY_STEP_MENU _UxGT("UBL Postupne") + +#define MSG_USER_MENU _UxGT("Vlastni prikazy") +#define MSG_MOVING _UxGT("Posunování...") +#define MSG_FREE_XY _UxGT("Uvolnit XY") +#define MSG_MOVE_X _UxGT("Posunout X") +#define MSG_MOVE_Y _UxGT("Posunout Y") +#define MSG_MOVE_Z _UxGT("Posunout Z") +#define MSG_MOVE_E _UxGT("Extruder") +#define MSG_MOVE_01MM _UxGT("Posunout o 0,1mm") +#define MSG_MOVE_1MM _UxGT("Posunout o 1mm") +#define MSG_MOVE_10MM _UxGT("Posunout o 10mm") +#define MSG_SPEED _UxGT("Rychlost") +#define MSG_BED_Z _UxGT("Vyska podl.") +#define MSG_NOZZLE _UxGT("Tryska") +#define MSG_BED _UxGT("Podlozka") +#define MSG_FAN_SPEED _UxGT("Rychlost vent.") +#define MSG_FLOW _UxGT("Prutok") +#define MSG_CONTROL _UxGT("Ovladani") +#define MSG_MIN _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" Min") +#define MSG_MAX _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" Max") +#define MSG_FACTOR _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" Fakt") +#define MSG_AUTOTEMP _UxGT("Autoteplota") +#define MSG_ON _UxGT("Zap") +#define MSG_OFF _UxGT("Vyp") +#define MSG_PID_P _UxGT("PID-P") +#define MSG_PID_I _UxGT("PID-I") +#define MSG_PID_D _UxGT("PID-D") +#define MSG_PID_C _UxGT("PID-C") +#define MSG_SELECT _UxGT("Vybrat") +#define MSG_ACC _UxGT("Zrychl") +#define MSG_JERK _UxGT("Jerk") +#define MSG_VX_JERK _UxGT("Vx-jerk") +#define MSG_VY_JERK _UxGT("Vy-jerk") +#define MSG_VZ_JERK _UxGT("Vz-jerk") +#define MSG_VE_JERK _UxGT("Ve-jerk") +#define MSG_VELOCITY _UxGT("Rychlost") +#define MSG_VMAX _UxGT("Vmax ") +#define MSG_VMIN _UxGT("Vmin") +#define MSG_VTRAV_MIN _UxGT("VTrav min") +#define MSG_ACCELERATION _UxGT("Akcelerace") +#define MSG_AMAX _UxGT("Amax ") +#define MSG_A_RETRACT _UxGT("A-retrakt") +#define MSG_A_TRAVEL _UxGT("A-prejezd") +#define MSG_STEPS_PER_MM _UxGT("Kroku/mm") +#define MSG_XSTEPS _UxGT("Xkroku/mm") +#define MSG_YSTEPS _UxGT("Ykroku/mm") +#define MSG_ZSTEPS _UxGT("Zkroku/mm") +#define MSG_ESTEPS _UxGT("Ekroku/mm") +#define MSG_E1STEPS _UxGT("E1kroku/mm") +#define MSG_E2STEPS _UxGT("E2kroku/mm") +#define MSG_E3STEPS _UxGT("E3kroku/mm") +#define MSG_E4STEPS _UxGT("E4kroku/mm") +#define MSG_E5STEPS _UxGT("E5kroku/mm") +#define MSG_TEMPERATURE _UxGT("Teplota") +#define MSG_MOTION _UxGT("Pohyb") +#define MSG_FILAMENT _UxGT("Filament") +#define MSG_VOLUMETRIC_ENABLED _UxGT("E na mm3") +#define MSG_FILAMENT_DIAM _UxGT("Fil. Prum.") +#define MSG_ADVANCE_K _UxGT("K pro posun") +#define MSG_CONTRAST _UxGT("Kontrast LCD") +#define MSG_STORE_EEPROM _UxGT("Ulozit nastaveni") +#define MSG_LOAD_EEPROM _UxGT("Nacist nastaveni") +#define MSG_RESTORE_FAILSAFE _UxGT("Obnovit vychozi") +#define MSG_INIT_EEPROM _UxGT("Inic. EEPROM") +#define MSG_REFRESH _UxGT("Obnovit") +#define MSG_WATCH _UxGT("Info obrazovka") +#define MSG_PREPARE _UxGT("Priprava tisku") +#define MSG_TUNE _UxGT("Doladeni tisku") +#define MSG_PAUSE_PRINT _UxGT("Pozastavit tisk") +#define MSG_RESUME_PRINT _UxGT("Obnovit tisk") +#define MSG_STOP_PRINT _UxGT("Zastavit tisk") +#define MSG_CARD_MENU _UxGT("Tisknout z SD") +#define MSG_NO_CARD _UxGT("Zadna SD karta") +#define MSG_DWELL _UxGT("Uspano...") +#define MSG_USERWAIT _UxGT("Cekani na uziv...") +#define MSG_PRINT_PAUSED _UxGT("Tisk pozastaven") +#define MSG_RESUMING _UxGT("Obnovovani tisku") +#define MSG_PRINT_ABORTED _UxGT("Tisk zrusen") +#define MSG_NO_MOVE _UxGT("Zadny pohyb.") +#define MSG_KILLED _UxGT("PRERUSENO. ") +#define MSG_STOPPED _UxGT("ZASTAVENO. ") +#define MSG_CONTROL_RETRACT _UxGT("Retrakt mm") +#define MSG_CONTROL_RETRACT_SWAP _UxGT("Vymena Re.mm") +#define MSG_CONTROL_RETRACTF _UxGT("Retraktovat V") +#define MSG_CONTROL_RETRACT_ZLIFT _UxGT("Zvednuti Z mm") +#define MSG_CONTROL_RETRACT_RECOVER _UxGT("UnRet mm") +#define MSG_CONTROL_RETRACT_RECOVER_SWAP _UxGT("S UnRet mm") +#define MSG_CONTROL_RETRACT_RECOVERF _UxGT("UnRet V") +#define MSG_AUTORETRACT _UxGT("AutoRetr.") +#define MSG_FILAMENTCHANGE _UxGT("Vymenit filament") +#define MSG_INIT_SDCARD _UxGT("Nacist SD kartu") +#define MSG_CNG_SDCARD _UxGT("Vymenit SD kartu") +#define MSG_ZPROBE_OUT _UxGT("Sonda Z mimo podl") +#define MSG_BLTOUCH _UxGT("BLTouch") +#define MSG_BLTOUCH_SELFTEST _UxGT("BLTouch Self-Test") +#define MSG_BLTOUCH_RESET _UxGT("BLTouch Reset") +#define MSG_BLTOUCH_DEPLOY _UxGT("BLTouch Vysunout") +#define MSG_BLTOUCH_STOW _UxGT("BLTouch Zasunout") +#define MSG_HOME _UxGT("Domu") // Used as MSG_HOME " " MSG_X MSG_Y MSG_Z " " MSG_FIRST +#define MSG_FIRST _UxGT("prvni") +#define MSG_ZPROBE_ZOFFSET _UxGT("Z ofset") +#define MSG_BABYSTEP_X _UxGT("Babystep X") +#define MSG_BABYSTEP_Y _UxGT("Babystep Y") +#define MSG_BABYSTEP_Z _UxGT("Babystep Z") +#define MSG_ENDSTOP_ABORT _UxGT("Endstop abort") +#define MSG_HEATING_FAILED_LCD _UxGT("Chyba zahrivani") +#define MSG_ERR_REDUNDANT_TEMP _UxGT("REDUND. TEPLOTA") +#define MSG_THERMAL_RUNAWAY _UxGT("TEPLOTNI SKOK") +#define MSG_ERR_MAXTEMP _UxGT("VYSOKA TEPLOTA") +#define MSG_ERR_MINTEMP _UxGT("NIZKA TEPLOTA") +#define MSG_ERR_MAXTEMP_BED _UxGT("VYS. TEPL. PODL.") +#define MSG_ERR_MINTEMP_BED _UxGT("NIZ. TEPL. PODL.") +#define MSG_ERR_Z_HOMING _UxGT("G28 Z ZAKAZANO") +#define MSG_HALTED _UxGT("TISK. ZASTAVENA") +#define MSG_PLEASE_RESET _UxGT("Provedte reset") +#define MSG_SHORT_DAY _UxGT("d") +#define MSG_SHORT_HOUR _UxGT("h") +#define MSG_SHORT_MINUTE _UxGT("m") +#define MSG_HEATING _UxGT("Zahrivani...") +#define MSG_HEATING_COMPLETE _UxGT("Zahrati hotovo.") +#define MSG_BED_HEATING _UxGT("Zahrivani podl.") +#define MSG_BED_DONE _UxGT("Podlozka hotova.") +#define MSG_DELTA_CALIBRATE _UxGT("Delta Kalibrace") +#define MSG_DELTA_CALIBRATE_X _UxGT("Kalibrovat X") +#define MSG_DELTA_CALIBRATE_Y _UxGT("Kalibrovat Y") +#define MSG_DELTA_CALIBRATE_Z _UxGT("Kalibrovat Z") +#define MSG_DELTA_CALIBRATE_CENTER _UxGT("Kalibrovat Stred") +#define MSG_DELTA_AUTO_CALIBRATE _UxGT("Autokalibrace") +#define MSG_DELTA_HEIGHT_CALIBRATE _UxGT("Nast.vysku delty") +#define MSG_INFO_MENU _UxGT("O tiskarne") +#define MSG_INFO_PRINTER_MENU _UxGT("Info o tiskarne") +#define MSG_3POINT_LEVELING _UxGT("3-bodove rovnani") +#define MSG_LINEAR_LEVELING _UxGT("Linearni rovnani") +#define MSG_BILINEAR_LEVELING _UxGT("Bilinearni rovnani") +#define MSG_UBL_LEVELING _UxGT("Unified Bed Leveling") +#define MSG_MESH_LEVELING _UxGT("Mrizkove rovnani") +#define MSG_INFO_STATS_MENU _UxGT("Statistika") +#define MSG_INFO_BOARD_MENU _UxGT("Info o desce") +#define MSG_INFO_THERMISTOR_MENU _UxGT("Termistory") +#define MSG_INFO_EXTRUDERS _UxGT("Extrudery") +#define MSG_INFO_BAUDRATE _UxGT("Rychlost") +#define MSG_INFO_PROTOCOL _UxGT("Protokol") +#define MSG_CASE_LIGHT _UxGT("Osvetleni") +#define MSG_CASE_LIGHT_BRIGHTNESS _UxGT("Jas svetla") + +#if LCD_WIDTH >= 20 + #define MSG_INFO_PRINT_COUNT _UxGT("Pocet tisku") + #define MSG_INFO_COMPLETED_PRINTS _UxGT("Dokonceno") + #define MSG_INFO_PRINT_TIME _UxGT("Celkovy cas") + #define MSG_INFO_PRINT_LONGEST _UxGT("Nejdelsi tisk") + #define MSG_INFO_PRINT_FILAMENT _UxGT("Celkem vytlaceno") +#else + #define MSG_INFO_PRINT_COUNT _UxGT("Tisky") + #define MSG_INFO_COMPLETED_PRINTS _UxGT("Hotovo") + #define MSG_INFO_PRINT_TIME _UxGT("Cas") + #define MSG_INFO_PRINT_LONGEST _UxGT("Nejdelsi") + #define MSG_INFO_PRINT_FILAMENT _UxGT("Vytlaceno") +#endif + +#define MSG_INFO_MIN_TEMP _UxGT("Teplota min") +#define MSG_INFO_MAX_TEMP _UxGT("Teplota max") +#define MSG_INFO_PSU _UxGT("Nap. zdroj") +#define MSG_DRIVE_STRENGTH _UxGT("Buzeni motoru") +#define MSG_DAC_PERCENT _UxGT("Motor %") +#define MSG_DAC_EEPROM_WRITE _UxGT("Ulozit do EEPROM") + +#define MSG_FILAMENT_CHANGE_HEADER _UxGT("PRINT PAUSED") +#define MSG_FILAMENT_CHANGE_OPTION_HEADER _UxGT("RESUME OPTIONS:") +#define MSG_FILAMENT_CHANGE_OPTION_EXTRUDE _UxGT("Jeste vytlacit") +#define MSG_FILAMENT_CHANGE_OPTION_RESUME _UxGT("Obnovit tisk") +#define MSG_FILAMENT_CHANGE_MINTEMP _UxGT("Min. teplota je ") +#define MSG_FILAMENT_CHANGE_NOZZLE _UxGT(" Tryska: ") + +#if LCD_HEIGHT >= 4 + // Up to 3 lines allowed + #define MSG_FILAMENT_CHANGE_INIT_1 _UxGT("Cekejte prosim") + #define MSG_FILAMENT_CHANGE_INIT_2 _UxGT("na zahajeni") + #define MSG_FILAMENT_CHANGE_INIT_3 _UxGT("vymeny filamentu") + #define MSG_FILAMENT_CHANGE_UNLOAD_1 _UxGT("Cekejte prosim") + #define MSG_FILAMENT_CHANGE_UNLOAD_2 _UxGT("na vysunuti") + #define MSG_FILAMENT_CHANGE_UNLOAD_3 _UxGT("filamentu") + #define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("Vlozte filament") + #define MSG_FILAMENT_CHANGE_INSERT_2 _UxGT("a stisknete") + #define MSG_FILAMENT_CHANGE_INSERT_3 _UxGT("tlacitko...") + #define MSG_FILAMENT_CHANGE_HEAT_1 _UxGT("Kliknete pro") + #define MSG_FILAMENT_CHANGE_HEAT_2 _UxGT("nahrati trysky") + #define MSG_FILAMENT_CHANGE_HEATING_1 _UxGT("Cekejte prosim") + #define MSG_FILAMENT_CHANGE_HEATING_2 _UxGT("na nahrati tr.") + #define MSG_FILAMENT_CHANGE_LOAD_1 _UxGT("Cekejte prosim") + #define MSG_FILAMENT_CHANGE_LOAD_2 _UxGT("na zavedeni") + #define MSG_FILAMENT_CHANGE_LOAD_3 _UxGT("filamentu") + #define MSG_FILAMENT_CHANGE_EXTRUDE_1 _UxGT("Cekejte prosim") + #define MSG_FILAMENT_CHANGE_EXTRUDE_2 _UxGT("na vytlaceni") + #define MSG_FILAMENT_CHANGE_EXTRUDE_3 _UxGT("filamentu") + #define MSG_FILAMENT_CHANGE_RESUME_1 _UxGT("Cekejte prosim") + #define MSG_FILAMENT_CHANGE_RESUME_2 _UxGT("na pokracovani") + #define MSG_FILAMENT_CHANGE_RESUME_3 _UxGT("tisku") +#else // LCD_HEIGHT < 4 + // Up to 2 lines allowed + #define MSG_FILAMENT_CHANGE_INIT_1 _UxGT("Cekejte...") + #define MSG_FILAMENT_CHANGE_UNLOAD_1 _UxGT("Vysouvani...") + #define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("Vlozte, kliknete") + #define MSG_FILAMENT_CHANGE_HEATING_1 _UxGT("Nahrivani...") + #define MSG_FILAMENT_CHANGE_LOAD_1 _UxGT("Zavadeni...") + #define MSG_FILAMENT_CHANGE_EXTRUDE_1 _UxGT("Vytlacovani...") + #define MSG_FILAMENT_CHANGE_RESUME_1 _UxGT("Pokracovani...") +#endif // LCD_HEIGHT < 4 + +#endif // LANGUAGE_CZ_H diff --git a/trunk/Arduino/Marlin_1.1.6/language_cz_utf8.h b/trunk/Arduino/Marlin_1.1.6/language_cz_utf8.h new file mode 100644 index 00000000..09f9954a --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/language_cz_utf8.h @@ -0,0 +1,351 @@ +/** + * 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 . + * + */ + +/** + * Czech + * UTF-8 for Graphical Display + * + * LCD Menu Messages + * See also http://marlinfw.org/docs/development/lcd_language.html + * + * Translated by Petr Zahradnik, Computer Laboratory + * Blog and video blog Zahradnik se bavi + * http://www.zahradniksebavi.cz + * + */ +#ifndef LANGUAGE_CZ_UTF_H +#define LANGUAGE_CZ_UTF_H + +#define MAPPER_C3C4C5_CZ +#define DISPLAY_CHARSET_ISO10646_CZ + +#define WELCOME_MSG MACHINE_NAME _UxGT(" připraven.") +#define MSG_BACK _UxGT("Zpět") +#define MSG_SD_INSERTED _UxGT("Karta vložena") +#define MSG_SD_REMOVED _UxGT("Karta vyjmuta") +#define MSG_LCD_ENDSTOPS _UxGT("Endstopy") // max 8 znaku +#define MSG_MAIN _UxGT("Hlavní nabídka") +#define MSG_AUTOSTART _UxGT("Autostart") +#define MSG_DISABLE_STEPPERS _UxGT("Uvolnit motory") +#define MSG_DEBUG_MENU _UxGT("Nabídka ladění") +#define MSG_PROGRESS_BAR_TEST _UxGT("Test uk. průběhu") +#define MSG_AUTO_HOME _UxGT("Domovská pozice") +#define MSG_AUTO_HOME_X _UxGT("Domů osa X") +#define MSG_AUTO_HOME_Y _UxGT("Domů osa Y") +#define MSG_AUTO_HOME_Z _UxGT("Domů osa Z") +#define MSG_LEVEL_BED_HOMING _UxGT("Měření podložky") +#define MSG_LEVEL_BED_WAITING _UxGT("Kliknutím spusťte") +#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Další bod") +#define MSG_LEVEL_BED_DONE _UxGT("Měření hotovo!") +#define MSG_Z_FADE_HEIGHT _UxGT("Výška srovnávání") +#define MSG_SET_HOME_OFFSETS _UxGT("Nastavit ofsety") +#define MSG_HOME_OFFSETS_APPLIED _UxGT("Ofsety nastaveny") +#define MSG_SET_ORIGIN _UxGT("Nastavit počátek") +#define MSG_PREHEAT_1 _UxGT("Zahřát PLA") +#define MSG_PREHEAT_1_N MSG_PREHEAT_1 _UxGT(" ") +#define MSG_PREHEAT_1_ALL MSG_PREHEAT_1 _UxGT(" vše") +#define MSG_PREHEAT_1_END MSG_PREHEAT_1 _UxGT(" hotend") +#define MSG_PREHEAT_1_BEDONLY MSG_PREHEAT_1 _UxGT(" podlož") +#define MSG_PREHEAT_1_SETTINGS MSG_PREHEAT_1 _UxGT(" nast") +#define MSG_PREHEAT_2 _UxGT("Zahřát ABS") +#define MSG_PREHEAT_2_N MSG_PREHEAT_2 _UxGT(" ") +#define MSG_PREHEAT_2_ALL MSG_PREHEAT_2 _UxGT(" vše") +#define MSG_PREHEAT_2_END MSG_PREHEAT_2 _UxGT(" hotend") +#define MSG_PREHEAT_2_BEDONLY MSG_PREHEAT_2 _UxGT(" podlož") +#define MSG_PREHEAT_2_SETTINGS MSG_PREHEAT_2 _UxGT(" nast") +#define MSG_COOLDOWN _UxGT("Zchladit") +#define MSG_SWITCH_PS_ON _UxGT("Zapnout napájení") +#define MSG_SWITCH_PS_OFF _UxGT("Vypnout napájení") +#define MSG_EXTRUDE _UxGT("Vytlačit (extr.)") +#define MSG_RETRACT _UxGT("Zatlačit (retr.)") +#define MSG_MOVE_AXIS _UxGT("Posunout osy") +#define MSG_BED_LEVELING _UxGT("Vyrovnat podložku") +#define MSG_LEVEL_BED _UxGT("Vyrovnat podložku") +#define MSG_EDITING_STOPPED _UxGT("Konec úprav sítě") + +#define MSG_UBL_DOING_G29 _UxGT("Provádím G29") +#define MSG_UBL_UNHOMED _UxGT("Přejeďte domů") +#define MSG_UBL_TOOLS _UxGT("UBL nástroje") +#define MSG_UBL_LEVEL_BED _UxGT("Unified Bed Leveling") +#define MSG_UBL_MANUAL_MESH _UxGT("Manuální síť bodů") +#define MSG_UBL_BC_INSERT _UxGT("Vložte kartu, změřte") +#define MSG_UBL_BC_INSERT2 _UxGT("Změřte") +#define MSG_UBL_BC_REMOVE _UxGT("Odstraňte a změřte") +#define MSG_UBL_MOVING_TO_NEXT _UxGT("Přesun na další") +#define MSG_UBL_ACTIVATE_MESH _UxGT("Aktivovat UBL") +#define MSG_UBL_DEACTIVATE_MESH _UxGT("Deaktivovat UBL") +#define MSG_UBL_SET_BED_TEMP _UxGT("Teplota podložky") +#define MSG_UBL_CUSTOM_BED_TEMP MSG_UBL_SET_BED_TEMP +#define MSG_UBL_SET_HOTEND_TEMP _UxGT("Teplota hotendu") +#define MSG_UBL_CUSTOM_HOTEND_TEMP MSG_UBL_SET_HOTEND_TEMP +#define MSG_UBL_EDIT_CUSTOM_MESH _UxGT("Upravit vlastní síť") +#define MSG_UBL_FINE_TUNE_MESH _UxGT("Doladit síť bodů") +#define MSG_UBL_DONE_EDITING_MESH _UxGT("Konec úprav sítě") +#define MSG_UBL_BUILD_CUSTOM_MESH _UxGT("Vlastní síť") +#define MSG_UBL_BUILD_MESH_MENU _UxGT("Vytvořit síť") +#define MSG_UBL_BUILD_PLA_MESH _UxGT("Síť bodu PLA") +#define MSG_UBL_BUILD_ABS_MESH _UxGT("Síť bodu ABS") +#define MSG_UBL_BUILD_COLD_MESH _UxGT("Studená síť bodu") +#define MSG_UBL_MESH_HEIGHT_ADJUST _UxGT("Upravit výšku sítě") +#define MSG_UBL_MESH_HEIGHT_AMOUNT _UxGT("Výška") +#define MSG_UBL_VALIDATE_MESH_MENU _UxGT("Zkontrolovat síť") +#define MSG_UBL_VALIDATE_PLA_MESH _UxGT("Kontrola sítě PLA") +#define MSG_UBL_VALIDATE_ABS_MESH _UxGT("Kontrola sítě ABS") +#define MSG_UBL_VALIDATE_CUSTOM_MESH _UxGT("Kontrola vlast. sítě") +#define MSG_UBL_CONTINUE_MESH _UxGT("Pokračovat v síťi") +#define MSG_UBL_MESH_LEVELING _UxGT("Síťové rovnání") +#define MSG_UBL_3POINT_MESH_LEVELING _UxGT("3-bodove rovnání") +#define MSG_UBL_GRID_MESH_LEVELING _UxGT("Mrizkove rovnání") +#define MSG_UBL_MESH_LEVEL _UxGT("Srovnat podložku") +#define MSG_UBL_SIDE_POINTS _UxGT("Postranní body") +#define MSG_UBL_MAP_TYPE _UxGT("Typ sítě bodu") +#define MSG_UBL_OUTPUT_MAP _UxGT("Exportovat síť") +#define MSG_UBL_OUTPUT_MAP_HOST _UxGT("Exportovat do PC") +#define MSG_UBL_OUTPUT_MAP_CSV _UxGT("Exportovat do CSV") +#define MSG_UBL_OUTPUT_MAP_BACKUP _UxGT("Záloha do PC") +#define MSG_UBL_INFO_UBL _UxGT("Info o UBL do PC") +#define MSG_UBL_EDIT_MESH_MENU _UxGT("Upravit síť bodů") +#define MSG_UBL_FILLIN_AMOUNT _UxGT("Hustota mřížky") +#define MSG_UBL_MANUAL_FILLIN _UxGT("Ruční hustota") +#define MSG_UBL_SMART_FILLIN _UxGT("Chytrá hustota") +#define MSG_UBL_FILLIN_MESH _UxGT("Zaplnit mřížku") +#define MSG_UBL_INVALIDATE_ALL _UxGT("Zrušit všechno") +#define MSG_UBL_INVALIDATE_CLOSEST _UxGT("Zrušit poslední") +#define MSG_UBL_FINE_TUNE_ALL _UxGT("Upravit všechny") +#define MSG_UBL_FINE_TUNE_CLOSEST _UxGT("Upravit poslední") +#define MSG_UBL_STORAGE_MESH_MENU _UxGT("Uložiště sítí") +#define MSG_UBL_STORAGE_SLOT _UxGT("Paměťový slot") +#define MSG_UBL_LOAD_MESH _UxGT("Načíst síť bodů") +#define MSG_UBL_SAVE_MESH _UxGT("Uložit síť bodů") +#define MSG_UBL_SAVE_ERROR _UxGT("Err: Uložit UBL") +#define MSG_UBL_RESTORE_ERROR _UxGT("Err: Obnovit UBL") +#define MSG_UBL_Z_OFFSET_STOPPED _UxGT("Konec Z-Offsetu") +#define MSG_UBL_STEP_BY_STEP_MENU _UxGT("UBL Postupně") + +#define MSG_USER_MENU _UxGT("Vlastní příkazy") +#define MSG_MOVING _UxGT("Posouvání...") +#define MSG_FREE_XY _UxGT("Uvolnit XY") +#define MSG_MOVE_X _UxGT("Posunout X") +#define MSG_MOVE_Y _UxGT("Posunout Y") +#define MSG_MOVE_Z _UxGT("Posunout Z") +#define MSG_MOVE_E _UxGT("Extrudér") +#define MSG_MOVE_01MM _UxGT("Posunout o 0,1mm") +#define MSG_MOVE_1MM _UxGT("Posunout o 1mm") +#define MSG_MOVE_10MM _UxGT("Posunout o 10mm") +#define MSG_SPEED _UxGT("Rychlost") +#define MSG_BED_Z _UxGT("Výška podl.") +#define MSG_NOZZLE _UxGT("Tryska") +#define MSG_BED _UxGT("Podložka") +#define MSG_FAN_SPEED _UxGT("Rychlost vent.") +#define MSG_FLOW _UxGT("Průtok") +#define MSG_CONTROL _UxGT("Ovládaní") +#define MSG_MIN _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" Min") +#define MSG_MAX _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" Max") +#define MSG_FACTOR _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" Fakt") +#define MSG_AUTOTEMP _UxGT("Autoteplota") +#define MSG_ON _UxGT("Zap") +#define MSG_OFF _UxGT("Vyp") +#define MSG_PID_P _UxGT("PID-P") +#define MSG_PID_I _UxGT("PID-I") +#define MSG_PID_D _UxGT("PID-D") +#define MSG_PID_C _UxGT("PID-C") +#define MSG_SELECT _UxGT("Vybrat") +#define MSG_ACC _UxGT("Zrychl") +#define MSG_JERK _UxGT("Jerk") +#define MSG_VX_JERK _UxGT("Vx-jerk") +#define MSG_VY_JERK _UxGT("Vy-jerk") +#define MSG_VZ_JERK _UxGT("Vz-jerk") +#define MSG_VE_JERK _UxGT("Ve-jerk") +#define MSG_VELOCITY _UxGT("Rychlost") +#define MSG_VMAX _UxGT("Vmax ") +#define MSG_VMIN _UxGT("Vmin") +#define MSG_VTRAV_MIN _UxGT("VTrav min") +#define MSG_ACCELERATION _UxGT("Akcelerace") +#define MSG_AMAX _UxGT("Amax ") +#define MSG_A_RETRACT _UxGT("A-retrakt") +#define MSG_A_TRAVEL _UxGT("A-přejezd") +#define MSG_STEPS_PER_MM _UxGT("Kroků/mm") +#define MSG_XSTEPS _UxGT("Xkroků/mm") +#define MSG_YSTEPS _UxGT("Ykroků/mm") +#define MSG_ZSTEPS _UxGT("Zkroků/mm") +#define MSG_ESTEPS _UxGT("Ekroků/mm") +#define MSG_E1STEPS _UxGT("E1kroků/mm") +#define MSG_E2STEPS _UxGT("E2kroků/mm") +#define MSG_E3STEPS _UxGT("E3kroků/mm") +#define MSG_E4STEPS _UxGT("E4kroků/mm") +#define MSG_E5STEPS _UxGT("E5kroků/mm") +#define MSG_TEMPERATURE _UxGT("Teplota") +#define MSG_MOTION _UxGT("Pohyb") +#define MSG_FILAMENT _UxGT("Filament") +#define MSG_VOLUMETRIC_ENABLED _UxGT("E na mm3") +#define MSG_FILAMENT_DIAM _UxGT("Fil. Prum.") +#define MSG_ADVANCE_K _UxGT("K pro posun") +#define MSG_CONTRAST _UxGT("Kontrast LCD") +#define MSG_STORE_EEPROM _UxGT("Uložit nastavení") +#define MSG_LOAD_EEPROM _UxGT("Načíst nastavení") +#define MSG_RESTORE_FAILSAFE _UxGT("Obnovit výchozí") +#define MSG_INIT_EEPROM _UxGT("Inic. EEPROM") +#define MSG_REFRESH _UxGT("Obnovit") +#define MSG_WATCH _UxGT("Info obrazovka") +#define MSG_PREPARE _UxGT("Připrava tisku") +#define MSG_TUNE _UxGT("Doladění tisku") +#define MSG_PAUSE_PRINT _UxGT("Pozastavit tisk") +#define MSG_RESUME_PRINT _UxGT("Obnovit tisk") +#define MSG_STOP_PRINT _UxGT("Zastavit tisk") +#define MSG_CARD_MENU _UxGT("Tisknout z SD") +#define MSG_NO_CARD _UxGT("Žádná SD karta") +#define MSG_DWELL _UxGT("Uspáno...") +#define MSG_USERWAIT _UxGT("Čekání na uživ...") +#define MSG_PRINT_PAUSED _UxGT("Tisk pozastaven") +#define MSG_RESUMING _UxGT("Obnovování tisku") +#define MSG_PRINT_ABORTED _UxGT("Tisk zrušen") +#define MSG_NO_MOVE _UxGT("Žádný pohyb.") +#define MSG_KILLED _UxGT("PŘERUSENO. ") +#define MSG_STOPPED _UxGT("ZASTAVENO. ") +#define MSG_CONTROL_RETRACT _UxGT("Retrakt mm") +#define MSG_CONTROL_RETRACT_SWAP _UxGT("Výměna Re.mm") +#define MSG_CONTROL_RETRACTF _UxGT("Retraktovat V") +#define MSG_CONTROL_RETRACT_ZLIFT _UxGT("Zvednuti Z mm") +#define MSG_CONTROL_RETRACT_RECOVER _UxGT("UnRet mm") +#define MSG_CONTROL_RETRACT_RECOVER_SWAP _UxGT("S UnRet mm") +#define MSG_CONTROL_RETRACT_RECOVERF _UxGT("UnRet V") +#define MSG_AUTORETRACT _UxGT("AutoRetr.") +#define MSG_FILAMENTCHANGE _UxGT("Vyměnit filament") +#define MSG_INIT_SDCARD _UxGT("Načíst SD kartu") +#define MSG_CNG_SDCARD _UxGT("Vyměnit SD kartu") +#define MSG_ZPROBE_OUT _UxGT("Sonda Z mimo podl") +#define MSG_BLTOUCH _UxGT("BLTouch") +#define MSG_BLTOUCH_SELFTEST _UxGT("BLTouch Self-Test") +#define MSG_BLTOUCH_RESET _UxGT("BLTouch Reset") +#define MSG_BLTOUCH_DEPLOY _UxGT("BLTouch Vysunout") +#define MSG_BLTOUCH_STOW _UxGT("BLTouch Zasunout") +#define MSG_HOME _UxGT("Domů") // Used as MSG_HOME " " MSG_X MSG_Y MSG_Z " " MSG_FIRST +#define MSG_FIRST _UxGT("první") +#define MSG_ZPROBE_ZOFFSET _UxGT("Z ofset") +#define MSG_BABYSTEP_X _UxGT("Babystep X") +#define MSG_BABYSTEP_Y _UxGT("Babystep Y") +#define MSG_BABYSTEP_Z _UxGT("Babystep Z") +#define MSG_ENDSTOP_ABORT _UxGT("Endstop abort") +#define MSG_HEATING_FAILED_LCD _UxGT("Chyba zahřívání") +#define MSG_ERR_REDUNDANT_TEMP _UxGT("REDUND. TEPLOTA") +#define MSG_THERMAL_RUNAWAY _UxGT("TEPLOTNÍ SKOK") +#define MSG_ERR_MAXTEMP _UxGT("VYSOKÁ TEPLOTA") +#define MSG_ERR_MINTEMP _UxGT("NÍZKA TEPLOTA") +#define MSG_ERR_MAXTEMP_BED _UxGT("VYS. TEPL. PODL.") +#define MSG_ERR_MINTEMP_BED _UxGT("NÍZ. TEPL. PODL.") +#define MSG_ERR_Z_HOMING _UxGT("G28 Z ZAKÁZÁNO") +#define MSG_HALTED _UxGT("TISK. ZASTAVENA") +#define MSG_PLEASE_RESET _UxGT("Proveďte reset") +#define MSG_SHORT_DAY _UxGT("d") +#define MSG_SHORT_HOUR _UxGT("h") +#define MSG_SHORT_MINUTE _UxGT("m") +#define MSG_HEATING _UxGT("Zahřívání...") +#define MSG_HEATING_COMPLETE _UxGT("Zahřáti hotovo.") +#define MSG_BED_HEATING _UxGT("Zahřívání podl.") +#define MSG_BED_DONE _UxGT("Podložka hotova.") +#define MSG_DELTA_CALIBRATE _UxGT("Delta Kalibrace") +#define MSG_DELTA_CALIBRATE_X _UxGT("Kalibrovat X") +#define MSG_DELTA_CALIBRATE_Y _UxGT("Kalibrovat Y") +#define MSG_DELTA_CALIBRATE_Z _UxGT("Kalibrovat Z") +#define MSG_DELTA_CALIBRATE_CENTER _UxGT("Kalibrovat Střed") +#define MSG_DELTA_AUTO_CALIBRATE _UxGT("Autokalibrace") +#define MSG_DELTA_HEIGHT_CALIBRATE _UxGT("Nast.výšku delty") +#define MSG_INFO_MENU _UxGT("O tiskárně") +#define MSG_INFO_PRINTER_MENU _UxGT("Info o tiskárně") +#define MSG_3POINT_LEVELING _UxGT("3-bodové rovnání") +#define MSG_LINEAR_LEVELING _UxGT("Lineárni rovnání") +#define MSG_BILINEAR_LEVELING _UxGT("Bilineární rovnání") +#define MSG_UBL_LEVELING _UxGT("Unified Bed Leveling") +#define MSG_MESH_LEVELING _UxGT("Mřížkové rovnání") +#define MSG_INFO_STATS_MENU _UxGT("Statistika") +#define MSG_INFO_BOARD_MENU _UxGT("Info o desce") +#define MSG_INFO_THERMISTOR_MENU _UxGT("Termistory") +#define MSG_INFO_EXTRUDERS _UxGT("Extrudéry") +#define MSG_INFO_BAUDRATE _UxGT("Rychlost") +#define MSG_INFO_PROTOCOL _UxGT("Protokol") +#define MSG_CASE_LIGHT _UxGT("Osvětlení") +#define MSG_CASE_LIGHT_BRIGHTNESS _UxGT("Jas světla") + +#if LCD_WIDTH >= 20 + #define MSG_INFO_PRINT_COUNT _UxGT("Počet tisků") + #define MSG_INFO_COMPLETED_PRINTS _UxGT("Dokončeno") + #define MSG_INFO_PRINT_TIME _UxGT("Celkový čas") + #define MSG_INFO_PRINT_LONGEST _UxGT("Nejdelší tisk") + #define MSG_INFO_PRINT_FILAMENT _UxGT("Celkem vytlačeno") +#else + #define MSG_INFO_PRINT_COUNT _UxGT("Tisky") + #define MSG_INFO_COMPLETED_PRINTS _UxGT("Hotovo") + #define MSG_INFO_PRINT_TIME _UxGT("Čas") + #define MSG_INFO_PRINT_LONGEST _UxGT("Nejdelší") + #define MSG_INFO_PRINT_FILAMENT _UxGT("Vytlačeno") +#endif + +#define MSG_INFO_MIN_TEMP _UxGT("Teplota min") +#define MSG_INFO_MAX_TEMP _UxGT("Teplota max") +#define MSG_INFO_PSU _UxGT("Nap. zdroj") +#define MSG_DRIVE_STRENGTH _UxGT("Buzení motorů") +#define MSG_DAC_PERCENT _UxGT("Motor %") +#define MSG_DAC_EEPROM_WRITE _UxGT("Uložit do EEPROM") + +#define MSG_FILAMENT_CHANGE_HEADER _UxGT("PRINT PAUSED") +#define MSG_FILAMENT_CHANGE_OPTION_HEADER _UxGT("RESUME OPTIONS:") +#define MSG_FILAMENT_CHANGE_OPTION_EXTRUDE _UxGT("Ještě vytlačit") +#define MSG_FILAMENT_CHANGE_OPTION_RESUME _UxGT("Obnovit tisk") +#define MSG_FILAMENT_CHANGE_MINTEMP _UxGT("Min. teplota je ") +#define MSG_FILAMENT_CHANGE_NOZZLE _UxGT(" Tryska: ") + +#if LCD_HEIGHT >= 4 + // Up to 3 lines allowed + #define MSG_FILAMENT_CHANGE_INIT_1 _UxGT("Čekejte prosím") + #define MSG_FILAMENT_CHANGE_INIT_2 _UxGT("na zahájení") + #define MSG_FILAMENT_CHANGE_INIT_3 _UxGT("výměny filamentu") + #define MSG_FILAMENT_CHANGE_UNLOAD_1 _UxGT("Čekejte prosím") + #define MSG_FILAMENT_CHANGE_UNLOAD_2 _UxGT("na vysunuti") + #define MSG_FILAMENT_CHANGE_UNLOAD_3 _UxGT("filamentu") + #define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("Vložte filament") + #define MSG_FILAMENT_CHANGE_INSERT_2 _UxGT("a stiskněte") + #define MSG_FILAMENT_CHANGE_INSERT_3 _UxGT("tlačítko...") + #define MSG_FILAMENT_CHANGE_HEAT_1 _UxGT("Klikněte pro") + #define MSG_FILAMENT_CHANGE_HEAT_2 _UxGT("nahřátí trysky") + #define MSG_FILAMENT_CHANGE_HEATING_1 _UxGT("Čekejte prosím") + #define MSG_FILAMENT_CHANGE_HEATING_2 _UxGT("na nahřátí tr.") + #define MSG_FILAMENT_CHANGE_LOAD_1 _UxGT("Čekejte prosím") + #define MSG_FILAMENT_CHANGE_LOAD_2 _UxGT("na zavedení") + #define MSG_FILAMENT_CHANGE_LOAD_3 _UxGT("filamentu") + #define MSG_FILAMENT_CHANGE_EXTRUDE_1 _UxGT("Čekejte prosím") + #define MSG_FILAMENT_CHANGE_EXTRUDE_2 _UxGT("na vytlačení") + #define MSG_FILAMENT_CHANGE_EXTRUDE_3 _UxGT("filamentu") + #define MSG_FILAMENT_CHANGE_RESUME_1 _UxGT("Čekejte prosím") + #define MSG_FILAMENT_CHANGE_RESUME_2 _UxGT("na pokračování") + #define MSG_FILAMENT_CHANGE_RESUME_3 _UxGT("tisku") +#else // LCD_HEIGHT < 4 + // Up to 2 lines allowed + #define MSG_FILAMENT_CHANGE_INIT_1 _UxGT("Čekejte...") + #define MSG_FILAMENT_CHANGE_UNLOAD_1 _UxGT("Vysouvání...") + #define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("Vložte, klikněte") + #define MSG_FILAMENT_CHANGE_HEATING_1 _UxGT("Nahřívání...") + #define MSG_FILAMENT_CHANGE_LOAD_1 _UxGT("Zavádění...") + #define MSG_FILAMENT_CHANGE_EXTRUDE_1 _UxGT("Vytlačování...") + #define MSG_FILAMENT_CHANGE_RESUME_1 _UxGT("Pokračování...") +#endif // LCD_HEIGHT < 4 + +#endif // LANGUAGE_CZ_UTF_H diff --git a/trunk/Arduino/Marlin_1.1.6/language_da.h b/trunk/Arduino/Marlin_1.1.6/language_da.h new file mode 100644 index 00000000..1a3fdd44 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/language_da.h @@ -0,0 +1,249 @@ +/** + * 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 . + * + */ + +/** + * Danish + * + * LCD Menu Messages + * See also http://marlinfw.org/docs/development/lcd_language.html + * + */ +#ifndef LANGUAGE_DA_H +#define LANGUAGE_DA_H + +#define MAPPER_C2C3 +#define DISPLAY_CHARSET_ISO10646_1 + +#define WELCOME_MSG MACHINE_NAME _UxGT(" er klar") +#define MSG_SD_INSERTED _UxGT("Kort isat") +#define MSG_SD_REMOVED _UxGT("Kort fjernet") +#define MSG_LCD_ENDSTOPS _UxGT("Endstops") // Max length 8 characters +#define MSG_MAIN _UxGT("Menu") +#define MSG_AUTOSTART _UxGT("Autostart") +#define MSG_DISABLE_STEPPERS _UxGT("Slå alle steppere fra") +#define MSG_AUTO_HOME _UxGT("Auto Home") // G28 +#define MSG_AUTO_HOME_X _UxGT("Home X") +#define MSG_AUTO_HOME_Y _UxGT("Home Y") +#define MSG_AUTO_HOME_Z _UxGT("Home Z") +#define MSG_LEVEL_BED_HOMING _UxGT("Homing XYZ") +#define MSG_LEVEL_BED_WAITING _UxGT("Klik når du er klar") +#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Næste punkt") +#define MSG_LEVEL_BED_DONE _UxGT("Bed level er færdig!") +#define MSG_SET_HOME_OFFSETS _UxGT("Sæt forsk. af home") +#define MSG_HOME_OFFSETS_APPLIED _UxGT("Forsk. er nu aktiv") +#define MSG_SET_ORIGIN _UxGT("Sæt origin") +#define MSG_PREHEAT_1 _UxGT("Forvarm PLA") +#define MSG_PREHEAT_1_N _UxGT("Forvarm PLA ") +#define MSG_PREHEAT_1_ALL _UxGT("Forvarm PLA Alle") +#define MSG_PREHEAT_1_BEDONLY _UxGT("Forvarm PLA Bed") +#define MSG_PREHEAT_1_SETTINGS _UxGT("Forvarm PLA conf") +#define MSG_PREHEAT_2 _UxGT("Forvarm ABS") +#define MSG_PREHEAT_2_N _UxGT("Forvarm ABS ") +#define MSG_PREHEAT_2_ALL _UxGT("Forvarm ABS Alle") +#define MSG_PREHEAT_2_BEDONLY _UxGT("Forvarm ABS Bed") +#define MSG_PREHEAT_2_SETTINGS _UxGT("Forvarm ABS conf") +#define MSG_COOLDOWN _UxGT("Afkøl") +#define MSG_SWITCH_PS_ON _UxGT("Slå strøm til") +#define MSG_SWITCH_PS_OFF _UxGT("Slå strøm fra") +#define MSG_EXTRUDE _UxGT("Extruder") +#define MSG_RETRACT _UxGT("Retract") +#define MSG_MOVE_AXIS _UxGT("Flyt akser") +#define MSG_BED_LEVELING _UxGT("Juster bed") +#define MSG_LEVEL_BED _UxGT("Juster bed") +#define MSG_MOVE_X _UxGT("Flyt X") +#define MSG_MOVE_Y _UxGT("Flyt Y") +#define MSG_MOVE_Z _UxGT("Flyt Z") +#define MSG_MOVE_E _UxGT("Extruder") +#define MSG_MOVE_01MM _UxGT("Flyt 0.1mm") +#define MSG_MOVE_1MM _UxGT("Flyt 1mm") +#define MSG_MOVE_10MM _UxGT("Flyt 10mm") +#define MSG_SPEED _UxGT("Hastighed") +#define MSG_BED_Z _UxGT("Plade Z") +#define MSG_NOZZLE _UxGT("Dyse") + +#define MSG_BED _UxGT("Plade") +#define MSG_FAN_SPEED _UxGT("Blæser hastighed") +#define MSG_FLOW _UxGT("Flow") +#define MSG_CONTROL _UxGT("Kontrol") +#define MSG_MIN _UxGT(" \002 Min") +#define MSG_MAX _UxGT(" \002 Max") +#define MSG_FACTOR _UxGT(" \002 Fact") +#define MSG_AUTOTEMP _UxGT("Autotemp") +#define MSG_ON _UxGT("Til ") +#define MSG_OFF _UxGT("Fra") +#define MSG_PID_P _UxGT("PID-P") +#define MSG_PID_I _UxGT("PID-I") +#define MSG_PID_D _UxGT("PID-D") +#define MSG_PID_C _UxGT("PID-C") +#define MSG_SELECT _UxGT("Vælg") +#define MSG_ACC _UxGT("Accel") +#define MSG_JERK _UxGT("Jerk") +#define MSG_VX_JERK _UxGT("Vx-jerk") +#define MSG_VY_JERK _UxGT("Vy-jerk") +#define MSG_VZ_JERK _UxGT("Vz-jerk") +#define MSG_VE_JERK _UxGT("Ve-jerk") +#define MSG_VMAX _UxGT("Vmax ") +#define MSG_VMIN _UxGT("Vmin") +#define MSG_VTRAV_MIN _UxGT("VTrav min") +#define MSG_AMAX _UxGT("Amax ") +#define MSG_A_RETRACT _UxGT("A-retract") +#define MSG_A_TRAVEL _UxGT("A-rejse") +#define MSG_STEPS_PER_MM _UxGT("Steps/mm") +#define MSG_XSTEPS _UxGT("Xsteps/mm") +#define MSG_YSTEPS _UxGT("Ysteps/mm") +#define MSG_ZSTEPS _UxGT("Zsteps/mm") +#define MSG_ESTEPS _UxGT("Esteps/mm") +#define MSG_E1STEPS _UxGT("E1steps/mm") +#define MSG_E2STEPS _UxGT("E2steps/mm") +#define MSG_E3STEPS _UxGT("E3steps/mm") +#define MSG_E4STEPS _UxGT("E4steps/mm") +#define MSG_E5STEPS _UxGT("E5steps/mm") +#define MSG_TEMPERATURE _UxGT("Temperatur") +#define MSG_MOTION _UxGT("Bevægelse") +#define MSG_FILAMENT _UxGT("Filament") +#define MSG_VOLUMETRIC_ENABLED _UxGT("E i mm3") +#define MSG_FILAMENT_DIAM _UxGT("Fil. Dia.") +#define MSG_CONTRAST _UxGT("LCD kontrast") +#define MSG_STORE_EEPROM _UxGT("Gem i EEPROM") +#define MSG_LOAD_EEPROM _UxGT("Hent fra EEPROM") +#define MSG_RESTORE_FAILSAFE _UxGT("Gendan failsafe") +#define MSG_REFRESH _UxGT("Genopfrisk") +#define MSG_WATCH _UxGT("Info skærm") +#define MSG_PREPARE _UxGT("Forbered") +#define MSG_TUNE _UxGT("Tune") +#define MSG_PAUSE_PRINT _UxGT("Pause printet") +#define MSG_RESUME_PRINT _UxGT("Forsæt printet") +#define MSG_STOP_PRINT _UxGT("Stop printet") +#define MSG_CARD_MENU _UxGT("Print fra SD") +#define MSG_NO_CARD _UxGT("Intet SD kort") +#define MSG_DWELL _UxGT("Dvale...") +#define MSG_USERWAIT _UxGT("Venter på bruger...") +#define MSG_RESUMING _UxGT("Forsætter printet") +#define MSG_PRINT_ABORTED _UxGT("Print annulleret") +#define MSG_NO_MOVE _UxGT("Ingen bevægelse.") +#define MSG_KILLED _UxGT("DRÆBT. ") +#define MSG_STOPPED _UxGT("STOPPET. ") +#define MSG_CONTROL_RETRACT _UxGT("Tilbagetræk mm") +#define MSG_CONTROL_RETRACT_SWAP _UxGT("Skift Re.mm") +#define MSG_CONTROL_RETRACTF _UxGT("Tilbagetræk V") +#define MSG_CONTROL_RETRACT_ZLIFT _UxGT("Hop mm") +#define MSG_CONTROL_RETRACT_RECOVER _UxGT("UnRet mm") +#define MSG_CONTROL_RETRACT_RECOVER_SWAP _UxGT("Skift UnRet mm") +#define MSG_CONTROL_RETRACT_RECOVERF _UxGT("UnRet V") +#define MSG_AUTORETRACT _UxGT("AutoRetr.") +#define MSG_FILAMENTCHANGE _UxGT("Skift filament") +#define MSG_INIT_SDCARD _UxGT("Init. SD card") +#define MSG_CNG_SDCARD _UxGT("Skift SD kort") +#define MSG_ZPROBE_OUT _UxGT("Probe udenfor plade") +#define MSG_BLTOUCH_SELFTEST _UxGT("BLTouch Selv-Test") +#define MSG_BLTOUCH_RESET _UxGT("Reset BLTouch") +#define MSG_HOME _UxGT("Home") // Used as MSG_HOME " " MSG_X MSG_Y MSG_Z " " MSG_FIRST +#define MSG_FIRST _UxGT("først") +#define MSG_ZPROBE_ZOFFSET _UxGT("Z Offset") +#define MSG_BABYSTEP_X _UxGT("Babystep X") +#define MSG_BABYSTEP_Y _UxGT("Babystep Y") +#define MSG_BABYSTEP_Z _UxGT("Babystep Z") +#define MSG_ENDSTOP_ABORT _UxGT("Endstop abort") +#define MSG_HEATING_FAILED_LCD _UxGT("Opvarmning fejlet") +#define MSG_ERR_REDUNDANT_TEMP _UxGT("Fejl: reserve temp") +#define MSG_THERMAL_RUNAWAY _UxGT("Temp løber løbsk") +#define MSG_ERR_MAXTEMP _UxGT("Fejl: Maks temp") +#define MSG_ERR_MINTEMP _UxGT("Fejl: Min temp") +#define MSG_ERR_MAXTEMP_BED _UxGT("Fejl: Maks Plade temp") +#define MSG_ERR_MINTEMP_BED _UxGT("Fejl: Min Plade temp") +#define MSG_ERR_Z_HOMING _UxGT("G28 Z Forbudt") +#define MSG_HALTED _UxGT("PRINTER STOPPET") +#define MSG_PLEASE_RESET _UxGT("Reset Venligst") +#define MSG_SHORT_DAY _UxGT("d") // Kun et bogstav +#define MSG_SHORT_HOUR _UxGT("h") // Kun et bogstav +#define MSG_SHORT_MINUTE _UxGT("m") // Kun et bogstav +#define MSG_HEATING _UxGT("Opvarmer...") +#define MSG_HEATING_COMPLETE _UxGT("Opvarmet") +#define MSG_BED_HEATING _UxGT("Opvarmer plade") +#define MSG_BED_DONE _UxGT("Plade opvarmet") +#define MSG_DELTA_CALIBRATE _UxGT("Delta Kalibrering") +#define MSG_DELTA_CALIBRATE_X _UxGT("Kalibrer X") +#define MSG_DELTA_CALIBRATE_Y _UxGT("Kalibrer Y") +#define MSG_DELTA_CALIBRATE_Z _UxGT("Kalibrer Z") +#define MSG_DELTA_CALIBRATE_CENTER _UxGT("Kalibrerings Center") + +#define MSG_INFO_MENU _UxGT("Om Printer") +#define MSG_INFO_PRINTER_MENU _UxGT("Printer Info") +#define MSG_INFO_STATS_MENU _UxGT("Printer Stats") +#define MSG_INFO_BOARD_MENU _UxGT("Kort Info") +#define MSG_INFO_THERMISTOR_MENU _UxGT("Thermistors") +#define MSG_INFO_EXTRUDERS _UxGT("Extruders") +#define MSG_INFO_BAUDRATE _UxGT("Baud") +#define MSG_INFO_PROTOCOL _UxGT("Protocol") + +#if LCD_WIDTH >= 20 + #define MSG_INFO_PRINT_COUNT _UxGT("Ant. Prints") + #define MSG_INFO_COMPLETED_PRINTS _UxGT("Færdige") + #define MSG_INFO_PRINT_TIME _UxGT("Total print tid") + #define MSG_INFO_PRINT_LONGEST _UxGT("Længste print") + #define MSG_INFO_PRINT_FILAMENT _UxGT("Total Extruderet") +#else + #define MSG_INFO_PRINT_COUNT _UxGT("Prints") + #define MSG_INFO_COMPLETED_PRINTS _UxGT("Færdige") + #define MSG_INFO_PRINT_TIME _UxGT("Total") + #define MSG_INFO_PRINT_LONGEST _UxGT("Længste") + #define MSG_INFO_PRINT_FILAMENT _UxGT("Extruderet") +#endif + +#define MSG_INFO_MIN_TEMP _UxGT("Min Temp") +#define MSG_INFO_MAX_TEMP _UxGT("Max Temp") +#define MSG_INFO_PSU _UxGT("Strømfors.") + +#define MSG_DRIVE_STRENGTH _UxGT("Driv Styrke") +#define MSG_DAC_PERCENT _UxGT("Driv %") +#define MSG_DAC_EEPROM_WRITE _UxGT("DAC EEPROM Skriv") + +#define MSG_FILAMENT_CHANGE_HEADER _UxGT("PRINT PAUSED") +#define MSG_FILAMENT_CHANGE_OPTION_HEADER _UxGT("RESUME OPTIONS:") +#define MSG_FILAMENT_CHANGE_OPTION_EXTRUDE _UxGT("Extruder mere") +#define MSG_FILAMENT_CHANGE_OPTION_RESUME _UxGT("Forsæt print") + +#if LCD_HEIGHT >= 4 + #define MSG_FILAMENT_CHANGE_INIT_1 _UxGT("Vent på start") + #define MSG_FILAMENT_CHANGE_INIT_2 _UxGT("af filament") + #define MSG_FILAMENT_CHANGE_INIT_3 _UxGT("skift") + #define MSG_FILAMENT_CHANGE_UNLOAD_1 _UxGT("Vent på") + #define MSG_FILAMENT_CHANGE_UNLOAD_2 _UxGT("filament udskyd.") + #define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("Indsæt filament") + #define MSG_FILAMENT_CHANGE_INSERT_2 _UxGT("og tryk på knap") + #define MSG_FILAMENT_CHANGE_INSERT_3 _UxGT("for at fortsætte...") + #define MSG_FILAMENT_CHANGE_LOAD_1 _UxGT("Vent på") + #define MSG_FILAMENT_CHANGE_LOAD_2 _UxGT("filament indtag") + #define MSG_FILAMENT_CHANGE_EXTRUDE_1 _UxGT("Vent på") + #define MSG_FILAMENT_CHANGE_EXTRUDE_2 _UxGT("filament extrudering") + #define MSG_FILAMENT_CHANGE_RESUME_1 _UxGT("Vent på at print") + #define MSG_FILAMENT_CHANGE_RESUME_2 _UxGT("fortsætter") +#else // LCD_HEIGHT < 4 + #define MSG_FILAMENT_CHANGE_INIT_1 _UxGT("Vent venligst...") + #define MSG_FILAMENT_CHANGE_UNLOAD_1 _UxGT("Udskyder...") + #define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("Indsæt og klik") + #define MSG_FILAMENT_CHANGE_LOAD_1 _UxGT("Indtager...") + #define MSG_FILAMENT_CHANGE_EXTRUDE_1 _UxGT("Extrudere...") + #define MSG_FILAMENT_CHANGE_RESUME_1 _UxGT("Fortsætter...") +#endif // LCD_HEIGHT < 4 + +#endif // LANGUAGE_DA_H diff --git a/trunk/Arduino/Marlin_1.1.6/language_de.h b/trunk/Arduino/Marlin_1.1.6/language_de.h new file mode 100644 index 00000000..c57605a0 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/language_de.h @@ -0,0 +1,351 @@ +/** + * 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 . + * + */ + +/** + * German + * + * LCD Menu Messages + * See also http://marlinfw.org/docs/development/lcd_language.html + * + */ +#ifndef LANGUAGE_DE_H +#define LANGUAGE_DE_H + +#define MAPPER_C2C3 +#define DISPLAY_CHARSET_ISO10646_1 + +#define THIS_LANGUAGES_SPECIAL_SYMBOLS _UxGT("ÄäÖöÜüß²³") + +#define WELCOME_MSG MACHINE_NAME _UxGT(" bereit") +#define MSG_BACK _UxGT("Zurück") +#define MSG_SD_INSERTED _UxGT("SD-Karte erkannt") +#define MSG_SD_REMOVED _UxGT("SD-Karte entfernt") +#define MSG_LCD_ENDSTOPS _UxGT("Endstopp") // Max length 8 characters +#define MSG_MAIN _UxGT("Hauptmenü") +#define MSG_AUTOSTART _UxGT("Autostart") +#define MSG_DISABLE_STEPPERS _UxGT("Motoren deaktivieren") // M84 +#define MSG_DEBUG_MENU _UxGT("Debug Menu") +#define MSG_PROGRESS_BAR_TEST _UxGT("Fortschrittsb. Test") +#define MSG_AUTO_HOME _UxGT("Home") // G28 +#define MSG_AUTO_HOME_X _UxGT("Home X") +#define MSG_AUTO_HOME_Y _UxGT("Home Y") +#define MSG_AUTO_HOME_Z _UxGT("Home Z") +#define MSG_LEVEL_BED_HOMING _UxGT("Homing XYZ") +#define MSG_LEVEL_BED_WAITING _UxGT("Klick für Start") +#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Nächste Koordinate") +#define MSG_LEVEL_BED_DONE _UxGT("Fertig") +#define MSG_Z_FADE_HEIGHT _UxGT("Niv. Ausblendhöhe") +#define MSG_SET_HOME_OFFSETS _UxGT("Setze Homeversatz") +#define MSG_HOME_OFFSETS_APPLIED _UxGT("Homeversatz aktiv") +#define MSG_SET_ORIGIN _UxGT("Setze Nullpunkt") //"G92 X0 Y0 Z0" commented out in ultralcd.cpp +#define MSG_PREHEAT_1 _UxGT("Vorwärmen PLA") +#define MSG_PREHEAT_1_N _UxGT("Vorwärmen PLA ") +#define MSG_PREHEAT_1_ALL _UxGT("Vorw. PLA Alle") +#define MSG_PREHEAT_1_END _UxGT("Vorw. PLA Extr.") +#define MSG_PREHEAT_1_BEDONLY _UxGT("Vorw. PLA Bett") +#define MSG_PREHEAT_1_SETTINGS _UxGT("Vorw. PLA Einst.") +#define MSG_PREHEAT_2 _UxGT("Vorwärmen ABS") +#define MSG_PREHEAT_2_N _UxGT("Vorwärmen ABS ") +#define MSG_PREHEAT_2_ALL _UxGT("Vorw. ABS Alle") +#define MSG_PREHEAT_2_END _UxGT("Vorw. ABS Extr.") +#define MSG_PREHEAT_2_BEDONLY _UxGT("Vorw. ABS Bett") +#define MSG_PREHEAT_2_SETTINGS _UxGT("Vorw. ABS Einst.") +#define MSG_COOLDOWN _UxGT("Abkühlen") +#define MSG_SWITCH_PS_ON _UxGT("Netzteil ein") +#define MSG_SWITCH_PS_OFF _UxGT("Netzteil aus") +#define MSG_EXTRUDE _UxGT("Extrudieren") +#define MSG_RETRACT _UxGT("Retract") +#define MSG_MOVE_AXIS _UxGT("Bewegen") +#define MSG_BED_LEVELING _UxGT("Bett Nivellierung") +#define MSG_LEVEL_BED _UxGT("Bett nivellieren") +#define MSG_EDITING_STOPPED _UxGT("Netzbearb. angeh.") +#define MSG_USER_MENU _UxGT("Benutzer Menü") +#define MSG_MOVING _UxGT("In Bewegung...") +#define MSG_FREE_XY _UxGT("Abstand XY") +#define MSG_MOVE_X _UxGT("X") +#define MSG_MOVE_Y _UxGT("Y") +#define MSG_MOVE_Z _UxGT("Z") +#define MSG_MOVE_E _UxGT("Extruder ") +#define MSG_MOVE_01MM _UxGT(" 0,1 mm") +#define MSG_MOVE_1MM _UxGT(" 1,0 mm") +#define MSG_MOVE_10MM _UxGT("10,0 mm") +#define MSG_SPEED _UxGT("Geschw.") +#define MSG_BED_Z _UxGT("Bett Z") +#define MSG_NOZZLE _UxGT("Düse") +#define MSG_BED _UxGT("Bett") +#define MSG_FAN_SPEED _UxGT("Lüfter") +#define MSG_FLOW _UxGT("Flussrate") +#define MSG_CONTROL _UxGT("Einstellungen") +#define MSG_MIN LCD_STR_THERMOMETER _UxGT(" min") +#define MSG_MAX LCD_STR_THERMOMETER _UxGT(" max") +#define MSG_FACTOR LCD_STR_THERMOMETER _UxGT(" Faktor") +#define MSG_AUTOTEMP _UxGT("AutoTemp") +#define MSG_ON _UxGT("Ein") +#define MSG_OFF _UxGT("Aus") +#define MSG_PID_P _UxGT("PID P") +#define MSG_PID_I _UxGT("PID I") +#define MSG_PID_D _UxGT("PID D") +#define MSG_PID_C _UxGT("PID C") +#define MSG_SELECT _UxGT("Auswählen") +#define MSG_ACC _UxGT("A") +#define MSG_JERK _UxGT("Jerk") +#define MSG_VX_JERK _UxGT("V X Jerk") +#define MSG_VY_JERK _UxGT("V Y Jerk") +#define MSG_VZ_JERK _UxGT("V Z Jerk") +#define MSG_VE_JERK _UxGT("V E Jerk") +#define MSG_VELOCITY _UxGT("Geschwindigkeit") +#define MSG_VMAX _UxGT("V max ") // space by purpose +#define MSG_VMIN _UxGT("V min") +#define MSG_VTRAV_MIN _UxGT("V min Leerfahrt") +#define MSG_ACCELERATION _UxGT("Beschleunigung") +#define MSG_AMAX _UxGT("A max ") // space by purpose +#define MSG_A_RETRACT _UxGT("A Retract") +#define MSG_A_TRAVEL _UxGT("A Leerfahrt") +#define MSG_STEPS_PER_MM _UxGT("Steps/mm") +#define MSG_XSTEPS _UxGT("X Steps/mm") +#define MSG_YSTEPS _UxGT("Y Steps/mm") +#define MSG_ZSTEPS _UxGT("Z Steps/mm") +#define MSG_ESTEPS _UxGT("E Steps/mm") +#define MSG_E1STEPS _UxGT("E1 Steps/mm") +#define MSG_E2STEPS _UxGT("E2 Steps/mm") +#define MSG_E3STEPS _UxGT("E3 Steps/mm") +#define MSG_E4STEPS _UxGT("E4 Steps/mm") +#define MSG_E5STEPS _UxGT("E5 Steps/mm") +#define MSG_TEMPERATURE _UxGT("Temperatur") +#define MSG_MOTION _UxGT("Bewegung") +#define MSG_FILAMENT _UxGT("Filament") +#define MSG_VOLUMETRIC_ENABLED _UxGT("E in mm³") +#define MSG_FILAMENT_DIAM _UxGT("D Fil.") +#define MSG_ADVANCE_K _UxGT("Advance Faktor") +#define MSG_CONTRAST _UxGT("LCD Kontrast") +#define MSG_STORE_EEPROM _UxGT("Konfig. speichern") +#define MSG_LOAD_EEPROM _UxGT("Konfig. laden") +#define MSG_RESTORE_FAILSAFE _UxGT("Standardwerte laden") +#define MSG_INIT_EEPROM _UxGT("Werkseinstellungen") +#define MSG_REFRESH _UxGT("Aktualisieren") +#define MSG_WATCH _UxGT("Info") +#define MSG_PREPARE _UxGT("Vorbereitung") +#define MSG_TUNE _UxGT("Justierung") +#define MSG_PAUSE_PRINT _UxGT("SD-Druck Pause") +#define MSG_RESUME_PRINT _UxGT("SD-Druck Fortsetzung") +#define MSG_STOP_PRINT _UxGT("SD-Druck Abbruch") +#define MSG_CARD_MENU _UxGT("SD-Karte") +#define MSG_NO_CARD _UxGT("Keine SD-Karte") +#define MSG_DWELL _UxGT("Warten...") +#define MSG_USERWAIT _UxGT("Warte auf Nutzer") +#define MSG_PRINT_PAUSED _UxGT("Druck pausiert") +#define MSG_RESUMING _UxGT("Druckfortsetzung") +#define MSG_PRINT_ABORTED _UxGT("Druck abgebrochen") +#define MSG_NO_MOVE _UxGT("Motoren eingeschaltet") +#define MSG_KILLED _UxGT("ABGEBROCHEN") +#define MSG_STOPPED _UxGT("ANGEHALTEN") +#define MSG_CONTROL_RETRACT _UxGT("Retract mm") +#define MSG_CONTROL_RETRACT_SWAP _UxGT("Wechs. Retract mm") +#define MSG_CONTROL_RETRACTF _UxGT("Retract V") +#define MSG_CONTROL_RETRACT_ZLIFT _UxGT("Z-Hop mm") +#define MSG_CONTROL_RETRACT_RECOVER _UxGT("UnRet mm") +#define MSG_CONTROL_RETRACT_RECOVER_SWAP _UxGT("Wechs. UnRet mm") +#define MSG_CONTROL_RETRACT_RECOVERF _UxGT("UnRet V") +#define MSG_AUTORETRACT _UxGT("Autom. Retract") +#define MSG_FILAMENTCHANGE _UxGT("Filament wechseln") +#define MSG_INIT_SDCARD _UxGT("SD-Karte erkennen") // Manually initialize the SD-card via user interface +#define MSG_CNG_SDCARD _UxGT("SD-Karte getauscht") // SD-card changed by user. For machines with no autocarddetect. Both send "M21" +#define MSG_ZPROBE_OUT _UxGT("Sensor ausserhalb") +#define MSG_BLTOUCH _UxGT("BLTouch") +#define MSG_BLTOUCH_SELFTEST _UxGT("BLTouch Test") +#define MSG_BLTOUCH_RESET _UxGT("BLTouch Reset") +#define MSG_BLTOUCH_DEPLOY _UxGT("BLTouch ausfahren") +#define MSG_BLTOUCH_STOW _UxGT("BLTouch einfahren") +#define MSG_HOME _UxGT("Vorher") // Used as MSG_HOME " " MSG_X MSG_Y MSG_Z " " MSG_FIRST +#define MSG_FIRST _UxGT("homen") +#define MSG_ZPROBE_ZOFFSET _UxGT("Z Versatz") +#define MSG_BABYSTEP_X _UxGT("Babystep X") +#define MSG_BABYSTEP_Y _UxGT("Babystep Y") +#define MSG_BABYSTEP_Z _UxGT("Babystep Z") +#define MSG_ENDSTOP_ABORT _UxGT("Endstopp-Abbr.") +#define MSG_HEATING_FAILED_LCD _UxGT("HEIZEN FEHLGESCHLAGEN") +#define MSG_ERR_REDUNDANT_TEMP _UxGT("REDUND. TEMPERATURABWEICHUNG") +#define MSG_THERMAL_RUNAWAY LCD_STR_THERMOMETER _UxGT(" NICHT ERREICHT") +#define MSG_ERR_MAXTEMP LCD_STR_THERMOMETER _UxGT(" ÜBERSCHRITTEN") +#define MSG_ERR_MINTEMP LCD_STR_THERMOMETER _UxGT(" UNTERSCHRITTEN") +#define MSG_ERR_MAXTEMP_BED _UxGT("BETT ") LCD_STR_THERMOMETER _UxGT(" ÜBERSCHRITTEN") +#define MSG_ERR_MINTEMP_BED _UxGT("BETT ") LCD_STR_THERMOMETER _UxGT(" UNTERSCHRITTEN") +#define MSG_ERR_Z_HOMING _UxGT("G28 Z verboten") +#define MSG_HALTED _UxGT("DRUCKER STOPP") +#define MSG_PLEASE_RESET _UxGT("Bitte Resetten") +#define MSG_SHORT_DAY _UxGT("t") // One character only +#define MSG_SHORT_HOUR _UxGT("h") // One character only +#define MSG_SHORT_MINUTE _UxGT("m") // One character only +#define MSG_HEATING _UxGT("Extr. heizt...") +#define MSG_HEATING_COMPLETE _UxGT("Extr. aufgeheizt") +#define MSG_BED_HEATING _UxGT("Bett heizt...") +#define MSG_BED_DONE _UxGT("Bett aufgeheizt") +#define MSG_DELTA_CALIBRATE _UxGT("Delta kalibrieren") +#define MSG_DELTA_CALIBRATE_X _UxGT("Kalibriere X") +#define MSG_DELTA_CALIBRATE_Y _UxGT("Kalibriere Y") +#define MSG_DELTA_CALIBRATE_Z _UxGT("Kalibriere Z") +#define MSG_DELTA_CALIBRATE_CENTER _UxGT("Kalibriere Mitte") +#define MSG_DELTA_SETTINGS _UxGT("Delta Einst. anzeig.") +#define MSG_DELTA_AUTO_CALIBRATE _UxGT("Autom. Kalibrierung") +#define MSG_DELTA_HEIGHT_CALIBRATE _UxGT("Delta Höhe setzen") + +#define MSG_INFO_MENU _UxGT("Über den Drucker") +#define MSG_INFO_PRINTER_MENU _UxGT("Drucker Info") +#define MSG_3POINT_LEVELING _UxGT("3-Punkt Nivellierung") +#define MSG_LINEAR_LEVELING _UxGT("Lineare Nivellierung") +#define MSG_BILINEAR_LEVELING _UxGT("Bilineare Nivell.") +#define MSG_UBL_LEVELING _UxGT("Unified Bed Leveling") +#define MSG_MESH_LEVELING _UxGT("Netz Nivellierung") +#define MSG_INFO_STATS_MENU _UxGT("Drucker Statistik") +#define MSG_INFO_BOARD_MENU _UxGT("Board Info") +#define MSG_INFO_THERMISTOR_MENU _UxGT("Thermistoren") +#define MSG_INFO_EXTRUDERS _UxGT("Extruder") +#define MSG_INFO_BAUDRATE _UxGT("Baud") +#define MSG_INFO_PROTOCOL _UxGT("Protokoll") +#define MSG_CASE_LIGHT _UxGT("Beleuchtung") +#define MSG_CASE_LIGHT_BRIGHTNESS _UxGT("Helligkeit") + +#define MSG_UBL_DOING_G29 _UxGT("G29 UBL läuft!") +#define MSG_UBL_UNHOMED _UxGT("Erst XYZ homen") +#define MSG_UBL_TOOLS _UxGT("UBL Tools") +#define MSG_UBL_LEVEL_BED _UxGT("Unified Bed Leveling") +#define MSG_UBL_MANUAL_MESH _UxGT("Netz manuell erst.") +#define MSG_UBL_BC_INSERT _UxGT("Unterlegen & messen") +#define MSG_UBL_BC_INSERT2 _UxGT("Messen") +#define MSG_UBL_BC_REMOVE _UxGT("Entfernen & messen") +#define MSG_UBL_MOVING_TO_NEXT _UxGT("Nächster Punkt...") +#define MSG_UBL_ACTIVATE_MESH _UxGT("UBL aktivieren") +#define MSG_UBL_DEACTIVATE_MESH _UxGT("UBL deaktivieren") +#define MSG_UBL_SET_BED_TEMP _UxGT("Bett Temp.") +#define MSG_UBL_CUSTOM_BED_TEMP MSG_UBL_SET_BED_TEMP +#define MSG_UBL_SET_HOTEND_TEMP _UxGT("Hotend Temp.") +#define MSG_UBL_CUSTOM_HOTEND_TEMP MSG_UBL_SET_HOTEND_TEMP +#define MSG_UBL_MESH_EDIT _UxGT("Netz bearbeiten") +#define MSG_UBL_EDIT_CUSTOM_MESH _UxGT("Eigenes Netz bearb.") +#define MSG_UBL_FINE_TUNE_MESH _UxGT("Feineinstellung...") +#define MSG_UBL_DONE_EDITING_MESH _UxGT("Bearbeitung beendet") +#define MSG_UBL_BUILD_CUSTOM_MESH _UxGT("Eigenes Netz erst.") +#define MSG_UBL_BUILD_MESH_MENU _UxGT("Netz erstellen") +#define MSG_UBL_BUILD_PLA_MESH _UxGT("Netz erstellen PLA") +#define MSG_UBL_BUILD_ABS_MESH _UxGT("Netz erstellen ABS") +#define MSG_UBL_BUILD_COLD_MESH _UxGT("Netz erstellen kalt") +#define MSG_UBL_MESH_HEIGHT_ADJUST _UxGT("Netz Höhe einst.") +#define MSG_UBL_MESH_HEIGHT_AMOUNT _UxGT("Height Amount") +#define MSG_UBL_VALIDATE_MESH_MENU _UxGT("Netz validieren") +#define MSG_UBL_VALIDATE_PLA_MESH _UxGT("Netz validieren PLA") +#define MSG_UBL_VALIDATE_ABS_MESH _UxGT("Netz validieren ABS") +#define MSG_UBL_VALIDATE_CUSTOM_MESH _UxGT("Eig. Netz validieren") +#define MSG_UBL_CONTINUE_MESH _UxGT("Netzerst. forts.") +#define MSG_UBL_MESH_LEVELING _UxGT("Netz Nivellierung") +#define MSG_UBL_3POINT_MESH_LEVELING _UxGT("3-Punkt Nivellierung") +#define MSG_UBL_GRID_MESH_LEVELING _UxGT("Gitternetz Nivell.") +#define MSG_UBL_MESH_LEVEL _UxGT("Netz nivellieren") +#define MSG_UBL_SIDE_POINTS _UxGT("Eckpunkte") +#define MSG_UBL_MAP_TYPE _UxGT("Kartentyp") +#define MSG_UBL_OUTPUT_MAP _UxGT("Karte ausgeben") +#define MSG_UBL_OUTPUT_MAP_HOST _UxGT("Ausgabe für Host") +#define MSG_UBL_OUTPUT_MAP_CSV _UxGT("Ausgabe für CSV") +#define MSG_UBL_OUTPUT_MAP_BACKUP _UxGT("Externe Sicherung") +#define MSG_UBL_INFO_UBL _UxGT("UBL Info ausgeben") +#define MSG_UBL_EDIT_MESH_MENU _UxGT("Netz bearbeiten") +#define MSG_UBL_FILLIN_AMOUNT _UxGT("Menge an Fill-in") +#define MSG_UBL_MANUAL_FILLIN _UxGT("Manuelles Fill-in") +#define MSG_UBL_SMART_FILLIN _UxGT("Kluges Fill-in") +#define MSG_UBL_FILLIN_MESH _UxGT("Fill-in Netz") +#define MSG_UBL_INVALIDATE_ALL _UxGT("Alles annullieren") +#define MSG_UBL_INVALIDATE_CLOSEST _UxGT("Nächstlieg. ann.") +#define MSG_UBL_FINE_TUNE_ALL _UxGT("Feineinstellung Alle") +#define MSG_UBL_FINE_TUNE_CLOSEST _UxGT("Feineinst. Nächstl.") +#define MSG_UBL_STORAGE_MESH_MENU _UxGT("Netz Speicherplatz") +#define MSG_UBL_STORAGE_SLOT _UxGT("Memory Slot") +#define MSG_UBL_LOAD_MESH _UxGT("Bett Netz laden") +#define MSG_UBL_SAVE_MESH _UxGT("Bett Netz speichern") +#define MSG_UBL_SAVE_ERROR _UxGT("ERR:UBL speichern") +#define MSG_UBL_RESTORE_ERROR _UxGT("ERR:UBL wiederherst.") +#define MSG_UBL_Z_OFFSET_STOPPED _UxGT("Z-Versatz angehalten") +#define MSG_UBL_STEP_BY_STEP_MENU _UxGT("Schrittweises UBL") + +#if LCD_WIDTH >= 20 + #define MSG_INFO_PRINT_COUNT _UxGT("Gesamte Drucke") + #define MSG_INFO_COMPLETED_PRINTS _UxGT("Beendete Drucke") + #define MSG_INFO_PRINT_TIME _UxGT("Gesamte Druckzeit") + #define MSG_INFO_PRINT_LONGEST _UxGT("Längster Druckjob") + #define MSG_INFO_PRINT_FILAMENT _UxGT("Gesamt Extrudiert") +#else + #define MSG_INFO_PRINT_COUNT _UxGT("Drucke") + #define MSG_INFO_COMPLETED_PRINTS _UxGT("Komplett") + #define MSG_INFO_PRINT_TIME _UxGT("Gesamt ") + #define MSG_INFO_PRINT_LONGEST _UxGT("Längster") + #define MSG_INFO_PRINT_FILAMENT _UxGT("Extrud.") +#endif + +#define MSG_INFO_MIN_TEMP _UxGT("Min Temp") +#define MSG_INFO_MAX_TEMP _UxGT("Max Temp") +#define MSG_INFO_PSU _UxGT("Stromversorgung") + +#define MSG_DRIVE_STRENGTH _UxGT("Motorströme") +#define MSG_DAC_PERCENT _UxGT("Treiber %") +#define MSG_DAC_EEPROM_WRITE _UxGT("Werte speichern") + +#define MSG_FILAMENT_CHANGE_HEADER _UxGT("DRUCK PAUSIERT") +#define MSG_FILAMENT_CHANGE_OPTION_HEADER _UxGT("FORTS. OPTIONEN:") +#define MSG_FILAMENT_CHANGE_OPTION_EXTRUDE _UxGT("Extrude mehr") +#define MSG_FILAMENT_CHANGE_OPTION_RESUME _UxGT("Drucke weiter") +#define MSG_FILAMENT_CHANGE_MINTEMP _UxGT("Min. Temperatur ist ") +#define MSG_FILAMENT_CHANGE_NOZZLE _UxGT(" Düse: ") + +#if LCD_HEIGHT >= 4 + // Up to 3 lines allowed + #define MSG_FILAMENT_CHANGE_INIT_1 _UxGT("Warte auf den") + #define MSG_FILAMENT_CHANGE_INIT_2 _UxGT("Start des") + #define MSG_FILAMENT_CHANGE_INIT_3 _UxGT("Filamentwechsels") + #define MSG_FILAMENT_CHANGE_UNLOAD_1 _UxGT("Warte auf") + #define MSG_FILAMENT_CHANGE_UNLOAD_2 _UxGT("Herausnahme") + #define MSG_FILAMENT_CHANGE_UNLOAD_3 _UxGT("des Filaments...") + #define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("Filament einlegen") + #define MSG_FILAMENT_CHANGE_INSERT_2 _UxGT("und Knopf") + #define MSG_FILAMENT_CHANGE_INSERT_3 _UxGT("drücken...") + #define MSG_FILAMENT_CHANGE_HEAT_1 _UxGT("Knopf drücken um") + #define MSG_FILAMENT_CHANGE_HEAT_2 _UxGT("Düse aufzuheizen.") + #define MSG_FILAMENT_CHANGE_HEATING_1 _UxGT("Düse heizt auf...") + #define MSG_FILAMENT_CHANGE_HEATING_2 _UxGT("Bitte warten...") + #define MSG_FILAMENT_CHANGE_LOAD_1 _UxGT("Warte auf") + #define MSG_FILAMENT_CHANGE_LOAD_2 _UxGT("Laden des") + #define MSG_FILAMENT_CHANGE_LOAD_3 _UxGT("Filaments") + #define MSG_FILAMENT_CHANGE_EXTRUDE_1 _UxGT("Warte auf") + #define MSG_FILAMENT_CHANGE_EXTRUDE_2 _UxGT("Extrusion des") + #define MSG_FILAMENT_CHANGE_EXTRUDE_3 _UxGT("Filaments") + #define MSG_FILAMENT_CHANGE_RESUME_1 _UxGT("Warte auf") + #define MSG_FILAMENT_CHANGE_RESUME_2 _UxGT("Fortsetzung des") + #define MSG_FILAMENT_CHANGE_RESUME_3 _UxGT("Druckes...") +#else // LCD_HEIGHT < 4 + // Up to 2 lines allowed + #define MSG_FILAMENT_CHANGE_INIT_1 _UxGT("Bitte warten...") + #define MSG_FILAMENT_CHANGE_UNLOAD_1 _UxGT("Auswerfen...") + #define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("Laden und Klick") + #define MSG_FILAMENT_CHANGE_HEATING_1 _UxGT("Heizen...") + #define MSG_FILAMENT_CHANGE_LOAD_1 _UxGT("Laden...") + #define MSG_FILAMENT_CHANGE_EXTRUDE_1 _UxGT("Extrudieren...") + #define MSG_FILAMENT_CHANGE_RESUME_1 _UxGT("Fortsetzen...") +#endif // LCD_HEIGHT < 4 + +#endif // LANGUAGE_DE_H diff --git a/trunk/Arduino/Marlin_1.1.6/language_el-gr.h b/trunk/Arduino/Marlin_1.1.6/language_el-gr.h new file mode 100644 index 00000000..2ad323de --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/language_el-gr.h @@ -0,0 +1,180 @@ +/** + * 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 . + * + */ + +/** + * Greek (Greece) + * + * LCD Menu Messages + * See also http://marlinfw.org/docs/development/lcd_language.html + * + */ +#ifndef LANGUAGE_EL_GR_H +#define LANGUAGE_EL_GR_H + +#define MAPPER_CECF +#define DISPLAY_CHARSET_ISO10646_GREEK + +#define WELCOME_MSG MACHINE_NAME _UxGT(" έτοιμο.") +#define MSG_SD_INSERTED _UxGT("Εισαγωγή κάρτας") +#define MSG_SD_REMOVED _UxGT("Αφαίρεση κάρτας") +#define MSG_LCD_ENDSTOPS _UxGT("Endstops") // Max length 8 characters +#define MSG_MAIN _UxGT("Βασική Οθόνη") +#define MSG_AUTOSTART _UxGT("Αυτόματη εκκίνηση") +#define MSG_DISABLE_STEPPERS _UxGT("Απενεργοποίηση βηματιστή") +#define MSG_AUTO_HOME _UxGT("Αυτομ. επαναφορά στο αρχικό σημείο") +#define MSG_AUTO_HOME_X _UxGT("Αρχικό σημείο X") +#define MSG_AUTO_HOME_Y _UxGT("Αρχικό σημείο Y") +#define MSG_AUTO_HOME_Z _UxGT("Αρχικό σημείο Z") +#define MSG_LEVEL_BED_HOMING _UxGT("Επαναφορά στο αρχικό σημείο ΧΥΖ") +#define MSG_LEVEL_BED_WAITING _UxGT("Κάντε κλικ για να ξεκινήσετε") +#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Επόμενο σημείο") +#define MSG_LEVEL_BED_DONE _UxGT("Ολοκλήρωση επιπεδοποίησης!") +#define MSG_SET_HOME_OFFSETS _UxGT("Ορισμός βασικών μετατοπίσεων") +#define MSG_HOME_OFFSETS_APPLIED _UxGT("Εφαρμόστηκαν οι μετατοπίσεις") +#define MSG_SET_ORIGIN _UxGT("Ορισμός προέλευσης") +#define MSG_PREHEAT_1 _UxGT("Προθέρμανση PLA") +#define MSG_PREHEAT_1_N MSG_PREHEAT_1 _UxGT(" ") +#define MSG_PREHEAT_1_ALL MSG_PREHEAT_1 _UxGT(" όλα") +#define MSG_PREHEAT_1_BEDONLY MSG_PREHEAT_1 _UxGT(" κλίνη") +#define MSG_PREHEAT_1_SETTINGS MSG_PREHEAT_1 _UxGT(" επιβεβαίωση") +#define MSG_PREHEAT_2 _UxGT("Προθέρμανση ABS") +#define MSG_PREHEAT_2_N MSG_PREHEAT_2 _UxGT(" ") +#define MSG_PREHEAT_2_ALL MSG_PREHEAT_2 _UxGT(" όλα") +#define MSG_PREHEAT_2_BEDONLY MSG_PREHEAT_2 _UxGT(" Bed") +#define MSG_PREHEAT_2_SETTINGS MSG_PREHEAT_2 _UxGT(" επιβεβαίωση") +#define MSG_COOLDOWN _UxGT("Μειωση θερμοκρασιας") +#define MSG_SWITCH_PS_ON _UxGT("Ενεργοποίηση") +#define MSG_SWITCH_PS_OFF _UxGT("Απενεργοποίηση") +#define MSG_EXTRUDE _UxGT("Εξώθηση") +#define MSG_RETRACT _UxGT("Ανάσυρση") +#define MSG_MOVE_AXIS _UxGT("Μετακίνηση άξονα") +#define MSG_BED_LEVELING _UxGT("Επιπεδοποίηση κλίνης") +#define MSG_LEVEL_BED _UxGT("Επιπεδοποίηση κλίνης") +#define MSG_MOVE_X _UxGT("Μετακίνηση X") +#define MSG_MOVE_Y _UxGT("Μετακίνηση Y") +#define MSG_MOVE_Z _UxGT("Μετακίνηση Z") +#define MSG_MOVE_E _UxGT("Εξωθητήρας") +#define MSG_MOVE_01MM _UxGT("Μετακίνηση 0,1 μμ") +#define MSG_MOVE_1MM _UxGT("Μετακίνηση 1 μμ") +#define MSG_MOVE_10MM _UxGT("Μετακίνηση 10 μμ") +#define MSG_SPEED _UxGT("Ταχύτητα") +#define MSG_BED_Z _UxGT("Κλίνη Z") +#define MSG_NOZZLE _UxGT("Ακροφύσιο") +#define MSG_BED _UxGT("Κλίνη") +#define MSG_FAN_SPEED _UxGT("Ταχύτητα ανεμιστήρα") +#define MSG_FLOW _UxGT("Ροή") +#define MSG_CONTROL _UxGT("Έλεγχος") +#define MSG_MIN _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" Min") +#define MSG_MAX _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" Max") +#define MSG_FACTOR _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" Fact") +#define MSG_AUTOTEMP _UxGT("Αυτομ. ρύθμιση θερμοκρασίας") +#define MSG_ON _UxGT("Ενεργοποιημένο") +#define MSG_OFF _UxGT("Απενεργοποιημένο") +#define MSG_PID_P _UxGT("PID-P") +#define MSG_PID_I _UxGT("PID-I") +#define MSG_PID_D _UxGT("PID-D") +#define MSG_PID_C _UxGT("PID-C") +#define MSG_ACC _UxGT("Επιτάχυνση") +#define MSG_JERK _UxGT("Vαντίδραση") +#define MSG_VX_JERK _UxGT("Vαντίδραση x") +#define MSG_VY_JERK _UxGT("Vαντίδραση y") +#define MSG_VZ_JERK _UxGT("Vαντίδραση z") +#define MSG_VE_JERK _UxGT("Vαντίδραση e") +#define MSG_VMAX _UxGT("Vμεγ ") +#define MSG_VMIN _UxGT("Vελαχ") +#define MSG_VTRAV_MIN _UxGT("Vελάχ. μετατόπιση") +#define MSG_ACCELERATION MSG_ACC +#define MSG_AMAX _UxGT("Aμεγ ") +#define MSG_A_RETRACT _UxGT("Α-ανάσυρση") +#define MSG_A_TRAVEL _UxGT("Α-μετατόπιση") +#define MSG_STEPS_PER_MM _UxGT("Bήματα ανά μμ") +#define MSG_XSTEPS _UxGT("Bήματα X ανά μμ") +#define MSG_YSTEPS _UxGT("Bήματα Υ ανά μμ") +#define MSG_ZSTEPS _UxGT("Bήματα Ζ ανά μμ") +#define MSG_ESTEPS _UxGT("Bήματα Ε ανά μμ") +#define MSG_E1STEPS _UxGT("Bήματα Ε1 ανά μμ") +#define MSG_E2STEPS _UxGT("Bήματα Ε2 ανά μμ") +#define MSG_E3STEPS _UxGT("Bήματα Ε3 ανά μμ") +#define MSG_E4STEPS _UxGT("Bήματα Ε4 ανά μμ") +#define MSG_E5STEPS _UxGT("Bήματα Ε5 ανά μμ") +#define MSG_TEMPERATURE _UxGT("Θερμοκρασία") +#define MSG_MOTION _UxGT("Κίνηση") +#define MSG_FILAMENT _UxGT("Νήμα") +#define MSG_VOLUMETRIC_ENABLED _UxGT("Ε σε μμ3") +#define MSG_FILAMENT_DIAM _UxGT("Διάμετρος νήματος") +#define MSG_CONTRAST _UxGT("Κοντράστ LCD") +#define MSG_STORE_EEPROM _UxGT("Αποθήκευση") +#define MSG_LOAD_EEPROM _UxGT("Φόρτωση") +#define MSG_RESTORE_FAILSAFE _UxGT("Επαναφορά ασφαλούς αντιγράφου") +#define MSG_REFRESH _UxGT("Ανανέωση") +#define MSG_WATCH _UxGT("Οθόνη πληροφόρησης") +#define MSG_PREPARE _UxGT("Προετοιμασία") +#define MSG_TUNE _UxGT("Συντονισμός") +#define MSG_PAUSE_PRINT _UxGT("Παύση εκτύπωσης") +#define MSG_RESUME_PRINT _UxGT("Συνέχιση εκτύπωσης") +#define MSG_STOP_PRINT _UxGT("Διακοπή εκτύπωσης") +#define MSG_CARD_MENU _UxGT("Εκτύπωση από SD") +#define MSG_NO_CARD _UxGT("Δεν βρέθηκε SD") +#define MSG_DWELL _UxGT("Αναστολή λειτουργίας...") +#define MSG_USERWAIT _UxGT("Αναμονή για χρήστη…") +#define MSG_RESUMING _UxGT("Συνεχίζεται η εκτύπωση") +#define MSG_PRINT_ABORTED _UxGT("Διακόπτεται η εκτύπωση") +#define MSG_NO_MOVE _UxGT("Καμία κίνηση.") +#define MSG_KILLED _UxGT("ΤΕΡΜΑΤΙΣΜΟΣ. ") +#define MSG_STOPPED _UxGT("ΔΙΑΚΟΠΗ. ") +#define MSG_CONTROL_RETRACT _UxGT("Ανάσυρση μμ") +#define MSG_CONTROL_RETRACT_SWAP _UxGT("Εναλλαγή ανάσυρσης μμ") +#define MSG_CONTROL_RETRACTF _UxGT("Ανάσυρση V") +#define MSG_CONTROL_RETRACT_ZLIFT _UxGT("Μεταπήδηση μμ") +#define MSG_CONTROL_RETRACT_RECOVER _UxGT("UnRet mm") +#define MSG_CONTROL_RETRACT_RECOVER_SWAP _UxGT("S UnRet mm") +#define MSG_CONTROL_RETRACT_RECOVERF _UxGT("UnRet V") +#define MSG_AUTORETRACT _UxGT("Αυτόματη ανάσυρση") +#define MSG_FILAMENTCHANGE _UxGT("Αλλαγή νήματος") +#define MSG_INIT_SDCARD _UxGT("Προετοιμασία κάρτας SD") +#define MSG_CNG_SDCARD _UxGT("Αλλαγή κάρτας SD") +#define MSG_ZPROBE_OUT _UxGT("Διερεύνηση Z εκτός κλίνης") +#define MSG_YX_UNHOMED _UxGT("Επαναφορά Χ/Υ πριν από Ζ") +#define MSG_XYZ_UNHOMED _UxGT("Επαναφορά ΧΥΖ πρώτα") +#define MSG_ZPROBE_ZOFFSET _UxGT("Μετατόπιση Ζ") +#define MSG_BABYSTEP_X _UxGT("Μικρό βήμα Χ") +#define MSG_BABYSTEP_Y _UxGT("Μικρό βήμα Υ") +#define MSG_BABYSTEP_Z _UxGT("Μικρό βήμα Ζ") +#define MSG_ENDSTOP_ABORT _UxGT("Ματαίωση endstop ") +#define MSG_HEATING_FAILED_LCD _UxGT("Ανεπιτυχής θέρμανση") +#define MSG_ERR_REDUNDANT_TEMP _UxGT("Λάθος: ΠΛΕΟΝΑΖΟΥΣΑ ΘΕΡΜΟΤΗΤΑ") +#define MSG_THERMAL_RUNAWAY _UxGT("ΔΙΑΦΥΓΗ ΘΕΡΜΟΤΗΤΑΣ") +#define MSG_ERR_MAXTEMP _UxGT("Λάθος: ΜΕΓΙΣΤΗ ΘΕΡΜΟΤΗΤΑ") +#define MSG_ERR_MINTEMP _UxGT("Λάθος: ΕΛΑΧΙΣΤΗ ΘΕΡΜΟΤΗΤΑ") +#define MSG_ERR_MAXTEMP_BED _UxGT("Λάθος: ΜΕΓΙΣΤΗ ΘΕΡΜΟΤΗΤΑ ΚΛΙΝΗΣ") +#define MSG_ERR_MINTEMP_BED _UxGT("Λάθος: ΕΛΑΧΙΣΤΗ ΘΕΡΜΟΤΗΤΑ ΚΛΙΝΗΣ") +#define MSG_HEATING _UxGT("Θερμαίνεται…") +#define MSG_HEATING_COMPLETE _UxGT("Η θέρμανση ολοκληρώθηκε.") +#define MSG_BED_HEATING _UxGT("Θέρμανση κλίνης.") +#define MSG_BED_DONE _UxGT("Η κλίνη ολοκληρώθηκε.") +#define MSG_DELTA_CALIBRATE _UxGT("Βαθμονόμηση Delta") +#define MSG_DELTA_CALIBRATE_X _UxGT("Βαθμονόμηση X") +#define MSG_DELTA_CALIBRATE_Y _UxGT("Βαθμονόμηση Y") +#define MSG_DELTA_CALIBRATE_Z _UxGT("Βαθμονόμηση Z") +#define MSG_DELTA_CALIBRATE_CENTER _UxGT("Βαθμονόμηση κέντρου") + +#endif // LANGUAGE_EL_GR_H diff --git a/trunk/Arduino/Marlin_1.1.6/language_el.h b/trunk/Arduino/Marlin_1.1.6/language_el.h new file mode 100644 index 00000000..1ae2a5b9 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/language_el.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 . + * + */ + +/** + * Greek + * + * LCD Menu Messages + * See also http://marlinfw.org/docs/development/lcd_language.html + * + */ +#ifndef LANGUAGE_EL_H +#define LANGUAGE_EL_H + +#define MAPPER_CECF +#define DISPLAY_CHARSET_ISO10646_GREEK + +#define WELCOME_MSG MACHINE_NAME _UxGT(" έτοιμο.") +#define MSG_SD_INSERTED _UxGT("Εισαγωγή κάρτας") +#define MSG_SD_REMOVED _UxGT("Αφαίρεση κάρτας") +#define MSG_LCD_ENDSTOPS _UxGT("Endstops") // Max length 8 characters +#define MSG_MAIN _UxGT("Βασική Οθόνη") +#define MSG_AUTOSTART _UxGT("Αυτόματη εκκίνηση") +#define MSG_DISABLE_STEPPERS _UxGT("Απενεργοποίηση Μοτέρ") +#define MSG_AUTO_HOME _UxGT("Αυτομ. επαναφορά στο αρχικό σημείο") //SHORTEN +#define MSG_AUTO_HOME_X _UxGT("Αρχικό σημείο X") +#define MSG_AUTO_HOME_Y _UxGT("Αρχικό σημείο Y") +#define MSG_AUTO_HOME_Z _UxGT("Αρχικό σημείο Z") +#define MSG_LEVEL_BED_HOMING _UxGT("Επαναφορά Επ. Εκτύπωσης") //SHORTEN +#define MSG_LEVEL_BED_WAITING _UxGT("Επιπεδοποίηση επ. Εκτύπωσης περιμενει") //SHORTEN +#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Επόμενο σημείο") +#define MSG_LEVEL_BED_DONE _UxGT("Ολοκλήρωση επιπεδοποίησης!") //SHORTEN +#define MSG_SET_HOME_OFFSETS _UxGT("Ορισμός βασικών μετατοπίσεων") //SHORTEN +#define MSG_HOME_OFFSETS_APPLIED _UxGT("Εφαρμόστηκαν οι μετατοπίσεις") //SHORTEN +#define MSG_SET_ORIGIN _UxGT("Ορισμός προέλευσης") +#define MSG_PREHEAT_1 _UxGT("Προθέρμανση PLA") +#define MSG_PREHEAT_1_N MSG_PREHEAT_1 _UxGT(" ") +#define MSG_PREHEAT_1_ALL MSG_PREHEAT_1 _UxGT(" όλα") +#define MSG_PREHEAT_1_BEDONLY MSG_PREHEAT_1 _UxGT(" bed") //SHORTEN +#define MSG_PREHEAT_1_SETTINGS MSG_PREHEAT_1 _UxGT(" επιβεβαίωση") //SHORTEN +#define MSG_PREHEAT_2 _UxGT("Προθέρμανση ABS") +#define MSG_PREHEAT_2_N MSG_PREHEAT_2 _UxGT(" ") +#define MSG_PREHEAT_2_ALL MSG_PREHEAT_2 _UxGT(" όλα") +#define MSG_PREHEAT_2_BEDONLY MSG_PREHEAT_2 _UxGT(" bed") //SHORTEN +#define MSG_PREHEAT_2_SETTINGS MSG_PREHEAT_2 _UxGT(" επιβεβαίωση") //SHORTEN +#define MSG_COOLDOWN _UxGT("Μειωση θερμοκρασιας") +#define MSG_SWITCH_PS_ON _UxGT("Ενεργοποίηση") +#define MSG_SWITCH_PS_OFF _UxGT("Απενεργοποίηση") +#define MSG_EXTRUDE _UxGT("Εξώθηση") +#define MSG_RETRACT _UxGT("Ανάσυρση") +#define MSG_MOVE_AXIS _UxGT("Μετακίνηση άξονα") +#define MSG_BED_LEVELING _UxGT("Επιπεδοποίηση Επ. Εκτύπωσης") //SHORTEN +#define MSG_LEVEL_BED _UxGT("Επιπεδοποίηση Επ. Εκτύπωσης") //SHORTEN +#define MSG_MOVE_X _UxGT("Μετακίνηση X") +#define MSG_MOVE_Y _UxGT("Μετακίνηση Y") +#define MSG_MOVE_Z _UxGT("Μετακίνηση Z") +#define MSG_MOVE_E _UxGT("Εξωθητήρας") +#define MSG_MOVE_01MM _UxGT("Μετακίνηση 0,1μμ") +#define MSG_MOVE_1MM _UxGT("Μετακίνηση 1μμ") +#define MSG_MOVE_10MM _UxGT("Μετακίνηση 10μμ") +#define MSG_SPEED _UxGT("Ταχύτητα") +#define MSG_BED_Z _UxGT("Επ. Εκτύπωσης Z") +#define MSG_NOZZLE _UxGT("Ακροφύσιο") +#define MSG_BED _UxGT("Κλίνη") +#define MSG_FAN_SPEED _UxGT("Ταχύτητα ανεμιστήρα") +#define MSG_FLOW _UxGT("Ροή") +#define MSG_CONTROL _UxGT("Έλεγχος") +#define MSG_MIN _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" Min") +#define MSG_MAX _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" Max") +#define MSG_FACTOR _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" Fact") +#define MSG_AUTOTEMP _UxGT("Αυτομ ρύθμιση θερ/σίας") //SHORTEN +#define MSG_ON _UxGT("Ενεργοποιημένο") +#define MSG_OFF _UxGT("Απενεργοποιημένο") +#define MSG_PID_P _UxGT("PID-P") +#define MSG_PID_I _UxGT("PID-I") +#define MSG_PID_D _UxGT("PID-D") +#define MSG_PID_C _UxGT("PID-C") +#define MSG_ACC _UxGT("Επιτάχυνση") +#define MSG_JERK _UxGT("Jerk") +#define MSG_VX_JERK _UxGT("Vαντίδραση x") +#define MSG_VY_JERK _UxGT("Vαντίδραση y") +#define MSG_VZ_JERK _UxGT("Vαντίδραση z") +#define MSG_VE_JERK _UxGT("Vαντίδραση e") +#define MSG_VMAX _UxGT("V Μέγιστο") +#define MSG_VMIN _UxGT("V Ελάχιστο") +#define MSG_VTRAV_MIN _UxGT("Vελάχ. μετατόπιση") +#define MSG_ACCELERATION MSG_ACC +#define MSG_AMAX _UxGT("Aμεγ ") +#define MSG_A_RETRACT _UxGT("Α-ανάσυρση") +#define MSG_A_TRAVEL _UxGT("Α-μετατόπιση") +#define MSG_STEPS_PER_MM _UxGT("Bήματα ανά μμ") +#define MSG_XSTEPS _UxGT("Bήματα X ανά μμ") +#define MSG_YSTEPS _UxGT("Bήματα Υ ανά μμ") +#define MSG_ZSTEPS _UxGT("Bήματα Ζ ανά μμ") +#define MSG_ESTEPS _UxGT("Bήματα Ε ανά μμ") +#define MSG_E1STEPS _UxGT("Bήματα Ε1 ανά μμ") +#define MSG_E2STEPS _UxGT("Bήματα Ε2 ανά μμ") +#define MSG_E3STEPS _UxGT("Bήματα Ε3 ανά μμ") +#define MSG_E4STEPS _UxGT("Bήματα Ε4 ανά μμ") +#define MSG_E5STEPS _UxGT("Bήματα Ε5 ανά μμ") +#define MSG_TEMPERATURE _UxGT("Θερμοκρασία") +#define MSG_MOTION _UxGT("Κίνηση") +#define MSG_FILAMENT _UxGT("Νήμα") +#define MSG_VOLUMETRIC_ENABLED _UxGT("Ε σε μμ3") +#define MSG_FILAMENT_DIAM _UxGT("Διάμετρος νήματος") +#define MSG_CONTRAST _UxGT("Κοντράστ LCD") +#define MSG_STORE_EEPROM _UxGT("Αποθήκευση") +#define MSG_LOAD_EEPROM _UxGT("Φόρτωση") +#define MSG_RESTORE_FAILSAFE _UxGT("Επαναφορά ασφαλούς αντιγράφου") //SHORTEN +#define MSG_REFRESH _UxGT("Ανανέωση") +#define MSG_WATCH _UxGT("Οθόνη πληροφόρησης") +#define MSG_PREPARE _UxGT("Προετοιμασία") +#define MSG_TUNE _UxGT("Συντονισμός") +#define MSG_PAUSE_PRINT _UxGT("Παύση εκτύπωσης") +#define MSG_RESUME_PRINT _UxGT("Συνέχιση εκτύπωσης") +#define MSG_STOP_PRINT _UxGT("Διακοπή εκτύπωσης") +#define MSG_CARD_MENU _UxGT("Εκτύπωση από SD") +#define MSG_NO_CARD _UxGT("Δεν βρέθηκε SD") +#define MSG_DWELL _UxGT("Αναστολή λειτουργίας") +#define MSG_USERWAIT _UxGT("Αναμονή για χρήστη") +#define MSG_RESUMING _UxGT("Συνεχίζεται η εκτύπωση") //SHORTEN +#define MSG_PRINT_ABORTED _UxGT("Διακόπτεται η εκτύπωση") //SHORTEN +#define MSG_NO_MOVE _UxGT("Καμία κίνηση.") +#define MSG_KILLED _UxGT("ΤΕΡΜΑΤΙΣΜΟΣ. ") +#define MSG_STOPPED _UxGT("ΔΙΑΚΟΠΗ. ") +#define MSG_CONTROL_RETRACT _UxGT("Ανάσυρση μμ") +#define MSG_CONTROL_RETRACT_SWAP _UxGT("Εναλλαγή ανάσυρσης μμ") //SHORTEN +#define MSG_CONTROL_RETRACTF _UxGT("Ανάσυρση V") +#define MSG_CONTROL_RETRACT_ZLIFT _UxGT("Μεταπήδηση μμ") +#define MSG_CONTROL_RETRACT_RECOVER _UxGT("UnRet mm") +#define MSG_CONTROL_RETRACT_RECOVER_SWAP _UxGT("S UnRet mm") +#define MSG_CONTROL_RETRACT_RECOVERF _UxGT("UnRet V") +#define MSG_AUTORETRACT _UxGT("Αυτόματη ανάσυρση") +#define MSG_FILAMENTCHANGE _UxGT("Αλλαγή νήματος") +#define MSG_INIT_SDCARD _UxGT("Προετοιμασία κάρτας SD") //SHORTEN +#define MSG_CNG_SDCARD _UxGT("Αλλαγή κάρτας SD") +#define MSG_ZPROBE_OUT _UxGT("Διερεύνηση Z εκτός Επ.Εκτύπωσης") //SHORTEN +#define MSG_YX_UNHOMED _UxGT("Επαναφορά Χ/Υ πριν από Ζ") //SHORTEN +#define MSG_XYZ_UNHOMED _UxGT("Επαναφορά ΧΥΖ πρώτα") +#define MSG_ZPROBE_ZOFFSET _UxGT("Μετατόπιση Ζ") +#define MSG_BABYSTEP_X _UxGT("Μικρό βήμα Χ") +#define MSG_BABYSTEP_Y _UxGT("Μικρό βήμα Υ") +#define MSG_BABYSTEP_Z _UxGT("Μικρό βήμα Ζ") +#define MSG_ENDSTOP_ABORT _UxGT("Ακύρωση endstop ") +#define MSG_HEATING_FAILED_LCD _UxGT("Ανεπιτυχής θέρμανση") +#define MSG_ERR_REDUNDANT_TEMP _UxGT("ΠΛΕΟΝΑΖΟΥΣΑ ΘΕΡΜΟΤΗΤΑ") +#define MSG_THERMAL_RUNAWAY _UxGT("ΔΙΑΦΥΓΗ ΘΕΡΜΟΚΡΑΣΙΑΣ") +#define MSG_ERR_MAXTEMP _UxGT("ΠΕΡΙΤΗ ΘΕΡΜΟΚΡΑΣΙΑ") +#define MSG_ERR_MINTEMP _UxGT("ΜΗ ΕΠΑΡΚΗΣ ΘΕΡΜΟΚΡΑΣΙΑΣ") //SHORTEN +#define MSG_ERR_MAXTEMP_BED _UxGT("ΜΕΓΙΣΤΗ ΘΕΡΜΟΚΡΑΣΙΑΣ ΕΠ. ΕΚΤΥΠΩΣΗΣ") //SHORTEN +#define MSG_ERR_MINTEMP_BED _UxGT("ΕΛΑΧΙΣΤΗ ΘΕΡΜΟΚΡΑΣΙΑΣ ΕΠ. ΕΚΤΥΠΩΣΗΣ") //SHORTEN +#define MSG_HALTED _UxGT("H εκτύπωση διακόπηκε") +#define MSG_PLEASE_RESET _UxGT("PLEASE RESET") //TRANSLATE +#define MSG_HEATING _UxGT("Θερμαίνεται…") +#define MSG_HEATING_COMPLETE _UxGT("Η θέρμανση ολοκληρώθηκε.") //SHORTEN +#define MSG_BED_HEATING _UxGT("Θέρμανση ΕΠ. Εκτύπωσης") //SHORTEN +#define MSG_BED_DONE _UxGT("Η Επ. Εκτύπωσης ολοκληρώθηκε") //SHORTEN +#define MSG_DELTA_CALIBRATE _UxGT("Βαθμονόμηση Delta") +#define MSG_DELTA_CALIBRATE_X _UxGT("Βαθμονόμηση X") +#define MSG_DELTA_CALIBRATE_Y _UxGT("Βαθμονόμηση Y") +#define MSG_DELTA_CALIBRATE_Z _UxGT("Βαθμονόμηση Z") +#define MSG_DELTA_CALIBRATE_CENTER _UxGT("Βαθμονόμηση κέντρου") + +#define MSG_INFO_MENU _UxGT("About Printer") +#define MSG_INFO_PRINTER_MENU _UxGT("Printer Info") +#define MSG_INFO_STATS_MENU _UxGT("Printer Stats") +#define MSG_INFO_BOARD_MENU _UxGT("Board Info") +#define MSG_INFO_THERMISTOR_MENU _UxGT("Thermistors") +#define MSG_INFO_EXTRUDERS _UxGT("Extruders") +#define MSG_INFO_BAUDRATE _UxGT("Baud") +#define MSG_INFO_PROTOCOL _UxGT("Protocol") + +#if LCD_WIDTH >= 20 + #define MSG_INFO_PRINT_COUNT _UxGT("Print Count") + #define MSG_INFO_COMPLETED_PRINTS _UxGT("Completed ") + #define MSG_INFO_PRINT_TIME _UxGT("Total Time ") +#else + #define MSG_INFO_PRINT_COUNT _UxGT("Prints ") + #define MSG_INFO_COMPLETED_PRINTS _UxGT("Completed") + #define MSG_INFO_PRINT_TIME _UxGT("Duration ") +#endif +#define MSG_INFO_MIN_TEMP _UxGT("Min Temp") +#define MSG_INFO_MAX_TEMP _UxGT("Max Temp") +#define MSG_INFO_PSU _UxGT("PSU") + +#define MSG_FILAMENT_CHANGE_HEADER _UxGT("CHANGE FILAMENT") +#define MSG_FILAMENT_CHANGE_OPTION_EXTRUDE _UxGT("Extrude more") +#define MSG_FILAMENT_CHANGE_OPTION_RESUME _UxGT("Resume print") + +#if LCD_HEIGHT >= 4 + // Up to 3 lines allowed + #define MSG_FILAMENT_CHANGE_INIT_1 _UxGT("Wait for start") + #define MSG_FILAMENT_CHANGE_INIT_2 _UxGT("of the filament") + #define MSG_FILAMENT_CHANGE_INIT_3 _UxGT("change") + #define MSG_FILAMENT_CHANGE_UNLOAD_1 _UxGT("Wait for") + #define MSG_FILAMENT_CHANGE_UNLOAD_2 _UxGT("filament unload") + #define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("Insert filament") + #define MSG_FILAMENT_CHANGE_INSERT_2 _UxGT("and press button") + #define MSG_FILAMENT_CHANGE_INSERT_3 _UxGT("to continue...") + #define MSG_FILAMENT_CHANGE_LOAD_1 _UxGT("Wait for") + #define MSG_FILAMENT_CHANGE_LOAD_2 _UxGT("filament load") + #define MSG_FILAMENT_CHANGE_EXTRUDE_1 _UxGT("Wait for") + #define MSG_FILAMENT_CHANGE_EXTRUDE_2 _UxGT("filament extrude") + #define MSG_FILAMENT_CHANGE_RESUME_1 _UxGT("Wait for print") + #define MSG_FILAMENT_CHANGE_RESUME_2 _UxGT("to resume") +#else // LCD_HEIGHT < 4 + // Up to 2 lines allowed + #define MSG_FILAMENT_CHANGE_INIT_1 _UxGT("Please wait...") + #define MSG_FILAMENT_CHANGE_UNLOAD_1 _UxGT("Ejecting...") + #define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("Insert and Click") + #define MSG_FILAMENT_CHANGE_LOAD_1 _UxGT("Loading...") + #define MSG_FILAMENT_CHANGE_EXTRUDE_1 _UxGT("Extruding...") + #define MSG_FILAMENT_CHANGE_RESUME_1 _UxGT("Resuming...") +#endif + +#endif // LANGUAGE_EL_H diff --git a/trunk/Arduino/Marlin_1.1.6/language_en.h b/trunk/Arduino/Marlin_1.1.6/language_en.h new file mode 100644 index 00000000..811b132f --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/language_en.h @@ -0,0 +1,937 @@ +/** + * 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 . + * + */ + +/** + * English + * + * LCD Menu Messages + * See also http://marlinfw.org/docs/development/lcd_language.html + * + */ +#ifndef LANGUAGE_EN_H +#define LANGUAGE_EN_H + +#ifndef WELCOME_MSG + #define WELCOME_MSG MACHINE_NAME _UxGT(" ready.") +#endif +#ifndef MSG_BACK + #define MSG_BACK _UxGT("Back") +#endif +#ifndef MSG_SD_INSERTED + #define MSG_SD_INSERTED _UxGT("Card inserted") +#endif +#ifndef MSG_SD_REMOVED + #define MSG_SD_REMOVED _UxGT("Card removed") +#endif +#ifndef MSG_LCD_ENDSTOPS + #define MSG_LCD_ENDSTOPS _UxGT("Endstops") // Max length 8 characters +#endif +#ifndef MSG_MAIN + #define MSG_MAIN _UxGT("Main") +#endif +#ifndef MSG_AUTOSTART + #define MSG_AUTOSTART _UxGT("Autostart") +#endif +#ifndef MSG_DISABLE_STEPPERS + #define MSG_DISABLE_STEPPERS _UxGT("Disable steppers") +#endif +#ifndef MSG_DEBUG_MENU + #define MSG_DEBUG_MENU _UxGT("Debug Menu") +#endif +#ifndef MSG_PROGRESS_BAR_TEST + #define MSG_PROGRESS_BAR_TEST _UxGT("Progress Bar Test") +#endif +#ifndef MSG_AUTO_HOME + #define MSG_AUTO_HOME _UxGT("Auto home") +#endif +#ifndef MSG_AUTO_HOME_X + #define MSG_AUTO_HOME_X _UxGT("Home X") +#endif +#ifndef MSG_AUTO_HOME_Y + #define MSG_AUTO_HOME_Y _UxGT("Home Y") +#endif +#ifndef MSG_AUTO_HOME_Z + #define MSG_AUTO_HOME_Z _UxGT("Home Z") +#endif +#ifndef MSG_LEVEL_BED_HOMING + #define MSG_LEVEL_BED_HOMING _UxGT("Homing XYZ") +#endif +#ifndef MSG_LEVEL_BED_WAITING + #define MSG_LEVEL_BED_WAITING _UxGT("Click to Begin") +#endif +#ifndef MSG_LEVEL_BED_NEXT_POINT + #define MSG_LEVEL_BED_NEXT_POINT _UxGT("Next Point") +#endif +#ifndef MSG_LEVEL_BED_DONE + #define MSG_LEVEL_BED_DONE _UxGT("Leveling Done!") +#endif +#ifndef MSG_Z_FADE_HEIGHT + #define MSG_Z_FADE_HEIGHT _UxGT("Fade Height") +#endif +#ifndef MSG_SET_HOME_OFFSETS + #define MSG_SET_HOME_OFFSETS _UxGT("Set home offsets") +#endif +#ifndef MSG_HOME_OFFSETS_APPLIED + #define MSG_HOME_OFFSETS_APPLIED _UxGT("Offsets applied") +#endif +#ifndef MSG_SET_ORIGIN + #define MSG_SET_ORIGIN _UxGT("Set origin") +#endif +#ifndef MSG_PREHEAT_1 + #define MSG_PREHEAT_1 _UxGT("Preheat PLA") +#endif +#ifndef MSG_PREHEAT_1_N + #define MSG_PREHEAT_1_N MSG_PREHEAT_1 _UxGT(" ") +#endif +#ifndef MSG_PREHEAT_1_ALL + #define MSG_PREHEAT_1_ALL MSG_PREHEAT_1 _UxGT(" All") +#endif +#ifndef MSG_PREHEAT_1_END + #define MSG_PREHEAT_1_END MSG_PREHEAT_1 _UxGT(" End") +#endif +#ifndef MSG_PREHEAT_1_BEDONLY + #define MSG_PREHEAT_1_BEDONLY MSG_PREHEAT_1 _UxGT(" Bed") +#endif +#ifndef MSG_PREHEAT_1_SETTINGS + #define MSG_PREHEAT_1_SETTINGS MSG_PREHEAT_1 _UxGT(" conf") +#endif +#ifndef MSG_PREHEAT_2 + #define MSG_PREHEAT_2 _UxGT("Preheat ABS") +#endif +#ifndef MSG_PREHEAT_2_N + #define MSG_PREHEAT_2_N MSG_PREHEAT_2 _UxGT(" ") +#endif +#ifndef MSG_PREHEAT_2_ALL + #define MSG_PREHEAT_2_ALL MSG_PREHEAT_2 _UxGT(" All") +#endif +#ifndef MSG_PREHEAT_2_END + #define MSG_PREHEAT_2_END MSG_PREHEAT_2 _UxGT(" End") +#endif +#ifndef MSG_PREHEAT_2_BEDONLY + #define MSG_PREHEAT_2_BEDONLY MSG_PREHEAT_2 _UxGT(" Bed") +#endif +#ifndef MSG_PREHEAT_2_SETTINGS + #define MSG_PREHEAT_2_SETTINGS MSG_PREHEAT_2 _UxGT(" conf") +#endif +#ifndef MSG_COOLDOWN + #define MSG_COOLDOWN _UxGT("Cooldown") +#endif +#ifndef MSG_SWITCH_PS_ON + #define MSG_SWITCH_PS_ON _UxGT("Switch power on") +#endif +#ifndef MSG_SWITCH_PS_OFF + #define MSG_SWITCH_PS_OFF _UxGT("Switch power off") +#endif +#ifndef MSG_EXTRUDE + #define MSG_EXTRUDE _UxGT("Extrude") +#endif +#ifndef MSG_RETRACT + #define MSG_RETRACT _UxGT("Retract") +#endif +#ifndef MSG_MOVE_AXIS + #define MSG_MOVE_AXIS _UxGT("Move axis") +#endif +#ifndef MSG_BED_LEVELING + #define MSG_BED_LEVELING _UxGT("Bed Leveling") +#endif +#ifndef MSG_LEVEL_BED + #define MSG_LEVEL_BED _UxGT("Level bed") +#endif +#ifndef MSG_LEVEL_CORNERS + #define MSG_LEVEL_CORNERS _UxGT("Level corners") +#endif +#ifndef MSG_NEXT_CORNER + #define MSG_NEXT_CORNER _UxGT("Next corner") +#endif +#ifndef MSG_EDITING_STOPPED + #define MSG_EDITING_STOPPED _UxGT("Mesh Editing Stopped") +#endif +#ifndef MSG_USER_MENU + #define MSG_USER_MENU _UxGT("Custom Commands") +#endif + +#ifndef MSG_UBL_DOING_G29 + #define MSG_UBL_DOING_G29 _UxGT("Doing G29") +#endif +#ifndef MSG_UBL_UNHOMED + #define MSG_UBL_UNHOMED _UxGT("Home XYZ first") +#endif +#ifndef MSG_UBL_TOOLS + #define MSG_UBL_TOOLS _UxGT("UBL Tools") +#endif +#ifndef MSG_UBL_LEVEL_BED + #define MSG_UBL_LEVEL_BED _UxGT("Unified Bed Leveling") +#endif +#ifndef MSG_UBL_MANUAL_MESH + #define MSG_UBL_MANUAL_MESH _UxGT("Manually Build Mesh") +#endif +#ifndef MSG_UBL_BC_INSERT + #define MSG_UBL_BC_INSERT _UxGT("Place shim & measure") +#endif +#ifndef MSG_UBL_BC_INSERT2 + #define MSG_UBL_BC_INSERT2 _UxGT("Measure") +#endif +#ifndef MSG_UBL_BC_REMOVE + #define MSG_UBL_BC_REMOVE _UxGT("Remove & measure bed") +#endif +#ifndef MSG_UBL_MOVING_TO_NEXT + #define MSG_UBL_MOVING_TO_NEXT _UxGT("Moving to next") +#endif +#ifndef MSG_UBL_ACTIVATE_MESH + #define MSG_UBL_ACTIVATE_MESH _UxGT("Activate UBL") +#endif +#ifndef MSG_UBL_DEACTIVATE_MESH + #define MSG_UBL_DEACTIVATE_MESH _UxGT("Deactivate UBL") +#endif +#ifndef MSG_UBL_SET_BED_TEMP + #define MSG_UBL_SET_BED_TEMP _UxGT("Bed Temp") +#endif +#ifndef MSG_UBL_CUSTOM_BED_TEMP + #define MSG_UBL_CUSTOM_BED_TEMP MSG_UBL_SET_BED_TEMP +#endif +#ifndef MSG_UBL_SET_HOTEND_TEMP + #define MSG_UBL_SET_HOTEND_TEMP _UxGT("Hotend Temp") +#endif +#ifndef MSG_UBL_CUSTOM_HOTEND_TEMP + #define MSG_UBL_CUSTOM_HOTEND_TEMP MSG_UBL_SET_HOTEND_TEMP +#endif +#ifndef MSG_UBL_MESH_EDIT + #define MSG_UBL_MESH_EDIT _UxGT("Mesh Edit") +#endif +#ifndef MSG_UBL_EDIT_CUSTOM_MESH + #define MSG_UBL_EDIT_CUSTOM_MESH _UxGT("Edit Custom Mesh") +#endif +#ifndef MSG_UBL_FINE_TUNE_MESH + #define MSG_UBL_FINE_TUNE_MESH _UxGT("Fine Tuning Mesh") +#endif +#ifndef MSG_UBL_DONE_EDITING_MESH + #define MSG_UBL_DONE_EDITING_MESH _UxGT("Done Editing Mesh") +#endif +#ifndef MSG_UBL_BUILD_CUSTOM_MESH + #define MSG_UBL_BUILD_CUSTOM_MESH _UxGT("Build Custom Mesh") +#endif +#ifndef MSG_UBL_BUILD_MESH_MENU + #define MSG_UBL_BUILD_MESH_MENU _UxGT("Build Mesh") +#endif +#ifndef MSG_UBL_BUILD_PLA_MESH + #define MSG_UBL_BUILD_PLA_MESH _UxGT("Build PLA Mesh") +#endif +#ifndef MSG_UBL_BUILD_ABS_MESH + #define MSG_UBL_BUILD_ABS_MESH _UxGT("Build ABS Mesh") +#endif +#ifndef MSG_UBL_BUILD_COLD_MESH + #define MSG_UBL_BUILD_COLD_MESH _UxGT("Build Cold Mesh") +#endif +#ifndef MSG_UBL_MESH_HEIGHT_ADJUST + #define MSG_UBL_MESH_HEIGHT_ADJUST _UxGT("Adjust Mesh Height") +#endif +#ifndef MSG_UBL_MESH_HEIGHT_AMOUNT + #define MSG_UBL_MESH_HEIGHT_AMOUNT _UxGT("Height Amount") +#endif +#ifndef MSG_UBL_VALIDATE_MESH_MENU + #define MSG_UBL_VALIDATE_MESH_MENU _UxGT("Validate Mesh") +#endif +#ifndef MSG_UBL_VALIDATE_PLA_MESH + #define MSG_UBL_VALIDATE_PLA_MESH _UxGT("Validate PLA Mesh") +#endif +#ifndef MSG_UBL_VALIDATE_ABS_MESH + #define MSG_UBL_VALIDATE_ABS_MESH _UxGT("Validate ABS Mesh") +#endif +#ifndef MSG_UBL_VALIDATE_CUSTOM_MESH + #define MSG_UBL_VALIDATE_CUSTOM_MESH _UxGT("Validate Custom Mesh") +#endif +#ifndef MSG_UBL_CONTINUE_MESH + #define MSG_UBL_CONTINUE_MESH _UxGT("Continue Bed Mesh") +#endif +#ifndef MSG_UBL_MESH_LEVELING + #define MSG_UBL_MESH_LEVELING _UxGT("Mesh Leveling") +#endif +#ifndef MSG_UBL_3POINT_MESH_LEVELING + #define MSG_UBL_3POINT_MESH_LEVELING _UxGT("3-Point Leveling") +#endif +#ifndef MSG_UBL_GRID_MESH_LEVELING + #define MSG_UBL_GRID_MESH_LEVELING _UxGT("Grid Mesh Leveling") +#endif +#ifndef MSG_UBL_MESH_LEVEL + #define MSG_UBL_MESH_LEVEL _UxGT("Level Mesh") +#endif +#ifndef MSG_UBL_SIDE_POINTS + #define MSG_UBL_SIDE_POINTS _UxGT("Side Points") +#endif +#ifndef MSG_UBL_MAP_TYPE + #define MSG_UBL_MAP_TYPE _UxGT("Map Type") +#endif +#ifndef MSG_UBL_OUTPUT_MAP + #define MSG_UBL_OUTPUT_MAP _UxGT("Output Mesh Map") +#endif +#ifndef MSG_UBL_OUTPUT_MAP_HOST + #define MSG_UBL_OUTPUT_MAP_HOST _UxGT("Output for Host") +#endif +#ifndef MSG_UBL_OUTPUT_MAP_CSV + #define MSG_UBL_OUTPUT_MAP_CSV _UxGT("Output for CSV") +#endif +#ifndef MSG_UBL_OUTPUT_MAP_BACKUP + #define MSG_UBL_OUTPUT_MAP_BACKUP _UxGT("Off Printer Backup") +#endif +#ifndef MSG_UBL_INFO_UBL + #define MSG_UBL_INFO_UBL _UxGT("Output UBL Info") +#endif +#ifndef MSG_UBL_EDIT_MESH_MENU + #define MSG_UBL_EDIT_MESH_MENU _UxGT("Edit Mesh") +#endif +#ifndef MSG_UBL_FILLIN_AMOUNT + #define MSG_UBL_FILLIN_AMOUNT _UxGT("Fill-in Amount") +#endif +#ifndef MSG_UBL_MANUAL_FILLIN + #define MSG_UBL_MANUAL_FILLIN _UxGT("Manual Fill-in") +#endif +#ifndef MSG_UBL_SMART_FILLIN + #define MSG_UBL_SMART_FILLIN _UxGT("Smart Fill-in") +#endif +#ifndef MSG_UBL_FILLIN_MESH + #define MSG_UBL_FILLIN_MESH _UxGT("Fill-in Mesh") +#endif +#ifndef MSG_UBL_INVALIDATE_ALL + #define MSG_UBL_INVALIDATE_ALL _UxGT("Invalidate All") +#endif +#ifndef MSG_UBL_INVALIDATE_CLOSEST + #define MSG_UBL_INVALIDATE_CLOSEST _UxGT("Invalidate Closest") +#endif +#ifndef MSG_UBL_FINE_TUNE_ALL + #define MSG_UBL_FINE_TUNE_ALL _UxGT("Fine Tune All") +#endif +#ifndef MSG_UBL_FINE_TUNE_CLOSEST + #define MSG_UBL_FINE_TUNE_CLOSEST _UxGT("Fine Tune Closest") +#endif +#ifndef MSG_UBL_STORAGE_MESH_MENU + #define MSG_UBL_STORAGE_MESH_MENU _UxGT("Mesh Storage") +#endif +#ifndef MSG_UBL_STORAGE_SLOT + #define MSG_UBL_STORAGE_SLOT _UxGT("Memory Slot") +#endif +#ifndef MSG_UBL_LOAD_MESH + #define MSG_UBL_LOAD_MESH _UxGT("Load Bed Mesh") +#endif +#ifndef MSG_UBL_SAVE_MESH + #define MSG_UBL_SAVE_MESH _UxGT("Save Bed Mesh") +#endif +#ifndef MSG_MESH_LOADED + #define MSG_MESH_LOADED _UxGT("Mesh %i loaded") +#endif +#ifndef MSG_MESH_SAVED + #define MSG_MESH_SAVED _UxGT("Mesh %i saved") +#endif +#ifndef MSG_NO_STORAGE + #define MSG_NO_STORAGE _UxGT("No storage") +#endif +#ifndef MSG_UBL_SAVE_ERROR + #define MSG_UBL_SAVE_ERROR _UxGT("Err: UBL Save") +#endif +#ifndef MSG_UBL_RESTORE_ERROR + #define MSG_UBL_RESTORE_ERROR _UxGT("Err: UBL Restore") +#endif +#ifndef MSG_UBL_Z_OFFSET_STOPPED + #define MSG_UBL_Z_OFFSET_STOPPED _UxGT("Z-Offset Stopped") +#endif +#ifndef MSG_UBL_STEP_BY_STEP_MENU + #define MSG_UBL_STEP_BY_STEP_MENU _UxGT("Step-By-Step UBL") +#endif + +#ifndef MSG_MOVING + #define MSG_MOVING _UxGT("Moving...") +#endif +#ifndef MSG_FREE_XY + #define MSG_FREE_XY _UxGT("Free XY") +#endif +#ifndef MSG_MOVE_X + #define MSG_MOVE_X _UxGT("Move X") +#endif +#ifndef MSG_MOVE_Y + #define MSG_MOVE_Y _UxGT("Move Y") +#endif +#ifndef MSG_MOVE_Z + #define MSG_MOVE_Z _UxGT("Move Z") +#endif +#ifndef MSG_MOVE_E + #define MSG_MOVE_E _UxGT("Extruder") +#endif +#ifndef MSG_MOVE_01MM + #define MSG_MOVE_01MM _UxGT("Move 0.1mm") +#endif +#ifndef MSG_MOVE_1MM + #define MSG_MOVE_1MM _UxGT("Move 1mm") +#endif +#ifndef MSG_MOVE_10MM + #define MSG_MOVE_10MM _UxGT("Move 10mm") +#endif +#ifndef MSG_SPEED + #define MSG_SPEED _UxGT("Speed") +#endif +#ifndef MSG_BED_Z + #define MSG_BED_Z _UxGT("Bed Z") +#endif +#ifndef MSG_NOZZLE + #define MSG_NOZZLE _UxGT("Nozzle") +#endif +#ifndef MSG_BED + #define MSG_BED _UxGT("Bed") +#endif +#ifndef MSG_FAN_SPEED + #define MSG_FAN_SPEED _UxGT("Fan speed") +#endif +#ifndef MSG_FLOW + #define MSG_FLOW _UxGT("Flow") +#endif +#ifndef MSG_CONTROL + #define MSG_CONTROL _UxGT("Control") +#endif +#ifndef MSG_MIN + #define MSG_MIN _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" Min") +#endif +#ifndef MSG_MAX + #define MSG_MAX _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" Max") +#endif +#ifndef MSG_FACTOR + #define MSG_FACTOR _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" Fact") +#endif +#ifndef MSG_AUTOTEMP + #define MSG_AUTOTEMP _UxGT("Autotemp") +#endif +#ifndef MSG_ON + #define MSG_ON _UxGT("On ") +#endif +#ifndef MSG_OFF + #define MSG_OFF _UxGT("Off") +#endif +#ifndef MSG_PID_P + #define MSG_PID_P _UxGT("PID-P") +#endif +#ifndef MSG_PID_I + #define MSG_PID_I _UxGT("PID-I") +#endif +#ifndef MSG_PID_D + #define MSG_PID_D _UxGT("PID-D") +#endif +#ifndef MSG_PID_C + #define MSG_PID_C _UxGT("PID-C") +#endif +#ifndef MSG_SELECT + #define MSG_SELECT _UxGT("Select") +#endif +#ifndef MSG_ACC + #define MSG_ACC _UxGT("Accel") +#endif +#ifndef MSG_JERK + #define MSG_JERK _UxGT("Jerk") +#endif +#ifndef MSG_VX_JERK + #define MSG_VX_JERK _UxGT("Vx-jerk") +#endif +#ifndef MSG_VY_JERK + #define MSG_VY_JERK _UxGT("Vy-jerk") +#endif +#ifndef MSG_VZ_JERK + #define MSG_VZ_JERK _UxGT("Vz-jerk") +#endif +#ifndef MSG_VE_JERK + #define MSG_VE_JERK _UxGT("Ve-jerk") +#endif +#ifndef MSG_VELOCITY + #define MSG_VELOCITY _UxGT("Velocity") +#endif +#ifndef MSG_VMAX + #define MSG_VMAX _UxGT("Vmax ") +#endif +#ifndef MSG_VMIN + #define MSG_VMIN _UxGT("Vmin") +#endif +#ifndef MSG_VTRAV_MIN + #define MSG_VTRAV_MIN _UxGT("VTrav min") +#endif +#ifndef MSG_ACCELERATION + #define MSG_ACCELERATION _UxGT("Acceleration") +#endif +#ifndef MSG_AMAX + #define MSG_AMAX _UxGT("Amax ") +#endif +#ifndef MSG_A_RETRACT + #define MSG_A_RETRACT _UxGT("A-retract") +#endif +#ifndef MSG_A_TRAVEL + #define MSG_A_TRAVEL _UxGT("A-travel") +#endif +#ifndef MSG_STEPS_PER_MM + #define MSG_STEPS_PER_MM _UxGT("Steps/mm") +#endif +#ifndef MSG_XSTEPS + #define MSG_XSTEPS _UxGT("Xsteps/mm") +#endif +#ifndef MSG_YSTEPS + #define MSG_YSTEPS _UxGT("Ysteps/mm") +#endif +#ifndef MSG_ZSTEPS + #define MSG_ZSTEPS _UxGT("Zsteps/mm") +#endif +#ifndef MSG_ESTEPS + #define MSG_ESTEPS _UxGT("Esteps/mm") +#endif +#ifndef MSG_E1STEPS + #define MSG_E1STEPS _UxGT("E1steps/mm") +#endif +#ifndef MSG_E2STEPS + #define MSG_E2STEPS _UxGT("E2steps/mm") +#endif +#ifndef MSG_E3STEPS + #define MSG_E3STEPS _UxGT("E3steps/mm") +#endif +#ifndef MSG_E4STEPS + #define MSG_E4STEPS _UxGT("E4steps/mm") +#endif +#ifndef MSG_E5STEPS + #define MSG_E5STEPS _UxGT("E5steps/mm") +#endif +#ifndef MSG_TEMPERATURE + #define MSG_TEMPERATURE _UxGT("Temperature") +#endif +#ifndef MSG_MOTION + #define MSG_MOTION _UxGT("Motion") +#endif +#ifndef MSG_FILAMENT + #define MSG_FILAMENT _UxGT("Filament") +#endif +#ifndef MSG_VOLUMETRIC_ENABLED + #define MSG_VOLUMETRIC_ENABLED _UxGT("E in mm3") +#endif +#ifndef MSG_FILAMENT_DIAM + #define MSG_FILAMENT_DIAM _UxGT("Fil. Dia.") +#endif +#ifndef MSG_ADVANCE_K + #define MSG_ADVANCE_K _UxGT("Advance K") +#endif +#ifndef MSG_CONTRAST + #define MSG_CONTRAST _UxGT("LCD contrast") +#endif +#ifndef MSG_STORE_EEPROM + #define MSG_STORE_EEPROM _UxGT("Store settings") +#endif +#ifndef MSG_LOAD_EEPROM + #define MSG_LOAD_EEPROM _UxGT("Load settings") +#endif +#ifndef MSG_RESTORE_FAILSAFE + #define MSG_RESTORE_FAILSAFE _UxGT("Restore failsafe") +#endif +#ifndef MSG_INIT_EEPROM + #define MSG_INIT_EEPROM _UxGT("Initialize EEPROM") +#endif +#ifndef MSG_REFRESH + #define MSG_REFRESH _UxGT("Refresh") +#endif +#ifndef MSG_WATCH + #define MSG_WATCH _UxGT("Info screen") +#endif +#ifndef MSG_PREPARE + #define MSG_PREPARE _UxGT("Prepare") +#endif +#ifndef MSG_TUNE + #define MSG_TUNE _UxGT("Tune") +#endif +#ifndef MSG_PAUSE_PRINT + #define MSG_PAUSE_PRINT _UxGT("Pause print") +#endif +#ifndef MSG_RESUME_PRINT + #define MSG_RESUME_PRINT _UxGT("Resume print") +#endif +#ifndef MSG_STOP_PRINT + #define MSG_STOP_PRINT _UxGT("Stop print") +#endif +#ifndef MSG_CARD_MENU + #define MSG_CARD_MENU _UxGT("Print from SD") +#endif +#ifndef MSG_NO_CARD + #define MSG_NO_CARD _UxGT("No SD card") +#endif +#ifndef MSG_DWELL + #define MSG_DWELL _UxGT("Sleep...") +#endif +#ifndef MSG_USERWAIT + #define MSG_USERWAIT _UxGT("Click to resume...") +#endif +#ifndef MSG_PRINT_PAUSED + #define MSG_PRINT_PAUSED _UxGT("Print paused") +#endif +#ifndef MSG_RESUMING + #define MSG_RESUMING _UxGT("Resuming print") +#endif +#ifndef MSG_PRINT_ABORTED + #define MSG_PRINT_ABORTED _UxGT("Print aborted") +#endif +#ifndef MSG_NO_MOVE + #define MSG_NO_MOVE _UxGT("No move.") +#endif +#ifndef MSG_KILLED + #define MSG_KILLED _UxGT("KILLED. ") +#endif +#ifndef MSG_STOPPED + #define MSG_STOPPED _UxGT("STOPPED. ") +#endif +#ifndef MSG_CONTROL_RETRACT + #define MSG_CONTROL_RETRACT _UxGT("Retract mm") +#endif +#ifndef MSG_CONTROL_RETRACT_SWAP + #define MSG_CONTROL_RETRACT_SWAP _UxGT("Swap Re.mm") +#endif +#ifndef MSG_CONTROL_RETRACTF + #define MSG_CONTROL_RETRACTF _UxGT("Retract V") +#endif +#ifndef MSG_CONTROL_RETRACT_ZLIFT + #define MSG_CONTROL_RETRACT_ZLIFT _UxGT("Hop mm") +#endif +#ifndef MSG_CONTROL_RETRACT_RECOVER + #define MSG_CONTROL_RETRACT_RECOVER _UxGT("UnRet mm") +#endif +#ifndef MSG_CONTROL_RETRACT_RECOVER_SWAP + #define MSG_CONTROL_RETRACT_RECOVER_SWAP _UxGT("S UnRet mm") +#endif +#ifndef MSG_CONTROL_RETRACT_RECOVERF + #define MSG_CONTROL_RETRACT_RECOVERF _UxGT("UnRet V") +#endif +#ifndef MSG_AUTORETRACT + #define MSG_AUTORETRACT _UxGT("AutoRetr.") +#endif +#ifndef MSG_FILAMENTCHANGE + #define MSG_FILAMENTCHANGE _UxGT("Change filament") +#endif +#ifndef MSG_INIT_SDCARD + #define MSG_INIT_SDCARD _UxGT("Init. SD card") +#endif +#ifndef MSG_CNG_SDCARD + #define MSG_CNG_SDCARD _UxGT("Change SD card") +#endif +#ifndef MSG_ZPROBE_OUT + #define MSG_ZPROBE_OUT _UxGT("Z probe out. bed") +#endif +#ifndef MSG_BLTOUCH + #define MSG_BLTOUCH _UxGT("BLTouch") +#endif +#ifndef MSG_BLTOUCH_SELFTEST + #define MSG_BLTOUCH_SELFTEST _UxGT("BLTouch Self-Test") +#endif +#ifndef MSG_BLTOUCH_RESET + #define MSG_BLTOUCH_RESET _UxGT("Reset BLTouch") +#endif +#ifndef MSG_BLTOUCH_DEPLOY + #define MSG_BLTOUCH_DEPLOY _UxGT("Deploy BLTouch") +#endif +#ifndef MSG_BLTOUCH_STOW + #define MSG_BLTOUCH_STOW _UxGT("Stow BLTouch") +#endif +#ifndef MSG_HOME + #define MSG_HOME _UxGT("Home") // Used as MSG_HOME " " MSG_X MSG_Y MSG_Z " " MSG_FIRST +#endif +#ifndef MSG_FIRST + #define MSG_FIRST _UxGT("first") +#endif +#ifndef MSG_ZPROBE_ZOFFSET + #define MSG_ZPROBE_ZOFFSET _UxGT("Z Offset") +#endif +#ifndef MSG_BABYSTEP_X + #define MSG_BABYSTEP_X _UxGT("Babystep X") +#endif +#ifndef MSG_BABYSTEP_Y + #define MSG_BABYSTEP_Y _UxGT("Babystep Y") +#endif +#ifndef MSG_BABYSTEP_Z + #define MSG_BABYSTEP_Z _UxGT("Babystep Z") +#endif +#ifndef MSG_ENDSTOP_ABORT + #define MSG_ENDSTOP_ABORT _UxGT("Endstop abort") +#endif +#ifndef MSG_HEATING_FAILED_LCD + #define MSG_HEATING_FAILED_LCD _UxGT("Heating failed") +#endif +#ifndef MSG_ERR_REDUNDANT_TEMP + #define MSG_ERR_REDUNDANT_TEMP _UxGT("Err: REDUNDANT TEMP") +#endif +#ifndef MSG_THERMAL_RUNAWAY + #define MSG_THERMAL_RUNAWAY _UxGT("THERMAL RUNAWAY") +#endif +#ifndef MSG_ERR_MAXTEMP + #define MSG_ERR_MAXTEMP _UxGT("Err: MAXTEMP") +#endif +#ifndef MSG_ERR_MINTEMP + #define MSG_ERR_MINTEMP _UxGT("Err: MINTEMP") +#endif +#ifndef MSG_ERR_MAXTEMP_BED + #define MSG_ERR_MAXTEMP_BED _UxGT("Err: MAXTEMP BED") +#endif +#ifndef MSG_ERR_MINTEMP_BED + #define MSG_ERR_MINTEMP_BED _UxGT("Err: MINTEMP BED") +#endif +#ifndef MSG_ERR_Z_HOMING + #define MSG_ERR_Z_HOMING _UxGT("G28 Z Forbidden") +#endif +#ifndef MSG_HALTED + #define MSG_HALTED _UxGT("PRINTER HALTED") +#endif +#ifndef MSG_PLEASE_RESET + #define MSG_PLEASE_RESET _UxGT("Please reset") +#endif +#ifndef MSG_SHORT_DAY + #define MSG_SHORT_DAY _UxGT("d") // One character only +#endif +#ifndef MSG_SHORT_HOUR + #define MSG_SHORT_HOUR _UxGT("h") // One character only +#endif +#ifndef MSG_SHORT_MINUTE + #define MSG_SHORT_MINUTE _UxGT("m") // One character only +#endif +#ifndef MSG_HEATING + #define MSG_HEATING _UxGT("Heating...") +#endif +#ifndef MSG_HEATING_COMPLETE + #define MSG_HEATING_COMPLETE _UxGT("Heating done.") +#endif +#ifndef MSG_BED_HEATING + #define MSG_BED_HEATING _UxGT("Bed Heating.") +#endif +#ifndef MSG_BED_DONE + #define MSG_BED_DONE _UxGT("Bed done.") +#endif +#ifndef MSG_DELTA_CALIBRATE + #define MSG_DELTA_CALIBRATE _UxGT("Delta Calibration") +#endif +#ifndef MSG_DELTA_CALIBRATE_X + #define MSG_DELTA_CALIBRATE_X _UxGT("Calibrate X") +#endif +#ifndef MSG_DELTA_CALIBRATE_Y + #define MSG_DELTA_CALIBRATE_Y _UxGT("Calibrate Y") +#endif +#ifndef MSG_DELTA_CALIBRATE_Z + #define MSG_DELTA_CALIBRATE_Z _UxGT("Calibrate Z") +#endif +#ifndef MSG_DELTA_CALIBRATE_CENTER + #define MSG_DELTA_CALIBRATE_CENTER _UxGT("Calibrate Center") +#endif +#ifndef MSG_DELTA_SETTINGS + #define MSG_DELTA_SETTINGS _UxGT("Delta Settings") +#endif +#ifndef MSG_DELTA_AUTO_CALIBRATE + #define MSG_DELTA_AUTO_CALIBRATE _UxGT("Auto Calibration") +#endif +#ifndef MSG_DELTA_HEIGHT_CALIBRATE + #define MSG_DELTA_HEIGHT_CALIBRATE _UxGT("Set Delta Height") +#endif +#ifndef MSG_DELTA_DIAG_ROG + #define MSG_DELTA_DIAG_ROG _UxGT("Diag Rod") +#endif +#ifndef MSG_DELTA_HEIGHT + #define MSG_DELTA_HEIGHT _UxGT("Height") +#endif +#ifndef MSG_DELTA_RADIUS + #define MSG_DELTA_RADIUS _UxGT("Radius") +#endif +#ifndef MSG_INFO_MENU + #define MSG_INFO_MENU _UxGT("About Printer") +#endif +#ifndef MSG_INFO_PRINTER_MENU + #define MSG_INFO_PRINTER_MENU _UxGT("Printer Info") +#endif +#ifndef MSG_3POINT_LEVELING + #define MSG_3POINT_LEVELING _UxGT("3-Point Leveling") +#endif +#ifndef MSG_LINEAR_LEVELING + #define MSG_LINEAR_LEVELING _UxGT("Linear Leveling") +#endif +#ifndef MSG_BILINEAR_LEVELING + #define MSG_BILINEAR_LEVELING _UxGT("Bilinear Leveling") +#endif +#ifndef MSG_UBL_LEVELING + #define MSG_UBL_LEVELING _UxGT("Unified Bed Leveling") +#endif +#ifndef MSG_MESH_LEVELING + #define MSG_MESH_LEVELING _UxGT("Mesh Leveling") +#endif +#ifndef MSG_INFO_STATS_MENU + #define MSG_INFO_STATS_MENU _UxGT("Printer Stats") +#endif +#ifndef MSG_INFO_BOARD_MENU + #define MSG_INFO_BOARD_MENU _UxGT("Board Info") +#endif +#ifndef MSG_INFO_THERMISTOR_MENU + #define MSG_INFO_THERMISTOR_MENU _UxGT("Thermistors") +#endif +#ifndef MSG_INFO_EXTRUDERS + #define MSG_INFO_EXTRUDERS _UxGT("Extruders") +#endif +#ifndef MSG_INFO_BAUDRATE + #define MSG_INFO_BAUDRATE _UxGT("Baud") +#endif +#ifndef MSG_INFO_PROTOCOL + #define MSG_INFO_PROTOCOL _UxGT("Protocol") +#endif +#ifndef MSG_CASE_LIGHT + #define MSG_CASE_LIGHT _UxGT("Case light") +#endif +#ifndef MSG_CASE_LIGHT_BRIGHTNESS + #define MSG_CASE_LIGHT_BRIGHTNESS _UxGT("Light BRIGHTNESS") +#endif +#if LCD_WIDTH >= 20 + #ifndef MSG_INFO_PRINT_COUNT + #define MSG_INFO_PRINT_COUNT _UxGT("Print Count") + #endif + #ifndef MSG_INFO_COMPLETED_PRINTS + #define MSG_INFO_COMPLETED_PRINTS _UxGT("Completed") + #endif + #ifndef MSG_INFO_PRINT_TIME + #define MSG_INFO_PRINT_TIME _UxGT("Total print time") + #endif + #ifndef MSG_INFO_PRINT_LONGEST + #define MSG_INFO_PRINT_LONGEST _UxGT("Longest job time") + #endif + #ifndef MSG_INFO_PRINT_FILAMENT + #define MSG_INFO_PRINT_FILAMENT _UxGT("Extruded total") + #endif +#else + #ifndef MSG_INFO_PRINT_COUNT + #define MSG_INFO_PRINT_COUNT _UxGT("Prints") + #endif + #ifndef MSG_INFO_COMPLETED_PRINTS + #define MSG_INFO_COMPLETED_PRINTS _UxGT("Completed") + #endif + #ifndef MSG_INFO_PRINT_TIME + #define MSG_INFO_PRINT_TIME _UxGT("Total") + #endif + #ifndef MSG_INFO_PRINT_LONGEST + #define MSG_INFO_PRINT_LONGEST _UxGT("Longest") + #endif + #ifndef MSG_INFO_PRINT_FILAMENT + #define MSG_INFO_PRINT_FILAMENT _UxGT("Extruded") + #endif +#endif + +#ifndef MSG_INFO_MIN_TEMP + #define MSG_INFO_MIN_TEMP _UxGT("Min Temp") +#endif +#ifndef MSG_INFO_MAX_TEMP + #define MSG_INFO_MAX_TEMP _UxGT("Max Temp") +#endif +#ifndef MSG_INFO_PSU + #define MSG_INFO_PSU _UxGT("PSU") +#endif +#ifndef MSG_DRIVE_STRENGTH + #define MSG_DRIVE_STRENGTH _UxGT("Drive Strength") +#endif +#ifndef MSG_DAC_PERCENT + #define MSG_DAC_PERCENT _UxGT("Driver %") +#endif +#ifndef MSG_DAC_EEPROM_WRITE + #define MSG_DAC_EEPROM_WRITE _UxGT("DAC EEPROM Write") +#endif +#ifndef MSG_FILAMENT_CHANGE_HEADER + #define MSG_FILAMENT_CHANGE_HEADER _UxGT("PRINT PAUSED") +#endif +#ifndef MSG_FILAMENT_CHANGE_OPTION_HEADER + #define MSG_FILAMENT_CHANGE_OPTION_HEADER _UxGT("RESUME OPTIONS:") +#endif +#ifndef MSG_FILAMENT_CHANGE_OPTION_EXTRUDE + #define MSG_FILAMENT_CHANGE_OPTION_EXTRUDE _UxGT("Extrude more") +#endif +#ifndef MSG_FILAMENT_CHANGE_OPTION_RESUME + #define MSG_FILAMENT_CHANGE_OPTION_RESUME _UxGT("Resume print") +#endif +#ifndef MSG_FILAMENT_CHANGE_MINTEMP + #define MSG_FILAMENT_CHANGE_MINTEMP _UxGT("Minimum Temp is ") +#endif +#ifndef MSG_FILAMENT_CHANGE_NOZZLE + #define MSG_FILAMENT_CHANGE_NOZZLE _UxGT(" Nozzle: ") +#endif +#ifndef MSG_ERR_HOMING_FAILED + #define MSG_ERR_HOMING_FAILED _UxGT("Homing failed") +#endif +#ifndef MSG_ERR_PROBING_FAILED + #define MSG_ERR_PROBING_FAILED _UxGT("Probing failed") +#endif + +// +// 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 + #ifndef MSG_FILAMENT_CHANGE_INIT_1 + #define MSG_FILAMENT_CHANGE_INIT_1 _UxGT("Wait for start") + #define MSG_FILAMENT_CHANGE_INIT_2 _UxGT("of the filament") + #define MSG_FILAMENT_CHANGE_INIT_3 _UxGT("change") + #endif + #ifndef MSG_FILAMENT_CHANGE_UNLOAD_1 + #define MSG_FILAMENT_CHANGE_UNLOAD_1 _UxGT("Wait for") + #define MSG_FILAMENT_CHANGE_UNLOAD_2 _UxGT("filament unload") + #endif + #ifndef MSG_FILAMENT_CHANGE_INSERT_1 + #define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("Insert filament") + #define MSG_FILAMENT_CHANGE_INSERT_2 _UxGT("and press button") + #define MSG_FILAMENT_CHANGE_INSERT_3 _UxGT("to continue...") + #endif + #ifndef MSG_FILAMENT_CHANGE_HEAT_1 + #define MSG_FILAMENT_CHANGE_HEAT_1 _UxGT("Press button to") + #define MSG_FILAMENT_CHANGE_HEAT_2 _UxGT("heat nozzle.") + #endif + #ifndef MSG_FILAMENT_CHANGE_HEATING_1 + #define MSG_FILAMENT_CHANGE_HEATING_1 _UxGT("Heating nozzle") + #define MSG_FILAMENT_CHANGE_HEATING_2 _UxGT("Please wait...") + #endif + #ifndef MSG_FILAMENT_CHANGE_LOAD_1 + #define MSG_FILAMENT_CHANGE_LOAD_1 _UxGT("Wait for") + #define MSG_FILAMENT_CHANGE_LOAD_2 _UxGT("filament load") + #endif + #ifndef MSG_FILAMENT_CHANGE_EXTRUDE_1 + #define MSG_FILAMENT_CHANGE_EXTRUDE_1 _UxGT("Wait for") + #define MSG_FILAMENT_CHANGE_EXTRUDE_2 _UxGT("filament extrude") + #endif + #ifndef MSG_FILAMENT_CHANGE_RESUME_1 + #define MSG_FILAMENT_CHANGE_RESUME_1 _UxGT("Wait for print") + #define MSG_FILAMENT_CHANGE_RESUME_2 _UxGT("to resume") + #endif +#else // LCD_HEIGHT < 4 + #ifndef MSG_FILAMENT_CHANGE_INIT_1 + #define MSG_FILAMENT_CHANGE_INIT_1 _UxGT("Please wait...") + #endif + #ifndef MSG_FILAMENT_CHANGE_UNLOAD_1 + #define MSG_FILAMENT_CHANGE_UNLOAD_1 _UxGT("Ejecting...") + #endif + #ifndef MSG_FILAMENT_CHANGE_INSERT_1 + #define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("Insert and Click") + #endif + #ifndef MSG_FILAMENT_CHANGE_HEATING_1 + #define MSG_FILAMENT_CHANGE_HEATING_1 _UxGT("Heating...") + #endif + #ifndef MSG_FILAMENT_CHANGE_LOAD_1 + #define MSG_FILAMENT_CHANGE_LOAD_1 _UxGT("Loading...") + #endif + #ifndef MSG_FILAMENT_CHANGE_EXTRUDE_1 + #define MSG_FILAMENT_CHANGE_EXTRUDE_1 _UxGT("Extruding...") + #endif + #ifndef MSG_FILAMENT_CHANGE_RESUME_1 + #define MSG_FILAMENT_CHANGE_RESUME_1 _UxGT("Resuming...") + #endif +#endif // LCD_HEIGHT < 4 + +#endif // LANGUAGE_EN_H diff --git a/trunk/Arduino/Marlin_1.1.6/language_es.h b/trunk/Arduino/Marlin_1.1.6/language_es.h new file mode 100644 index 00000000..2983cf24 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/language_es.h @@ -0,0 +1,265 @@ +/** + * 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 . + * + */ + +/** + * Spanish + * + * LCD Menu Messages + * See also http://marlinfw.org/docs/development/lcd_language.html + * + */ +#ifndef LANGUAGE_ES_H +#define LANGUAGE_ES_H + +#define DISPLAY_CHARSET_ISO10646_1 + +#define WELCOME_MSG MACHINE_NAME _UxGT(" lista.") +#define MSG_BACK _UxGT("Atras") +#define MSG_SD_INSERTED _UxGT("Tarjeta colocada") +#define MSG_SD_REMOVED _UxGT("Tarjeta retirada") +#define MSG_LCD_ENDSTOPS _UxGT("Endstops") // Max length 8 characters +#define MSG_MAIN _UxGT("Menu principal") +#define MSG_AUTOSTART _UxGT("Inicio automatico") +#define MSG_DISABLE_STEPPERS _UxGT("Apagar motores") +#define MSG_DEBUG_MENU _UxGT("Menu depurar") +#define MSG_PROGRESS_BAR_TEST _UxGT("Prueba barra avance") +#define MSG_AUTO_HOME _UxGT("Llevar al origen") +#define MSG_AUTO_HOME_X _UxGT("Origen X") +#define MSG_AUTO_HOME_Y _UxGT("Origen Y") +#define MSG_AUTO_HOME_Z _UxGT("Origen Z") +#define MSG_LEVEL_BED_HOMING _UxGT("Origen XYZ") +#define MSG_LEVEL_BED_WAITING _UxGT("Iniciar (Presione)") +#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Siguiente punto") +#define MSG_LEVEL_BED_DONE _UxGT("Nivelacion lista!") +#define MSG_SET_HOME_OFFSETS _UxGT("Ajustar desfases") +#define MSG_HOME_OFFSETS_APPLIED _UxGT("Desfase aplicado") +#define MSG_SET_ORIGIN _UxGT("Establecer origen") +#define MSG_PREHEAT_1 _UxGT("Precalentar PLA") +#define MSG_PREHEAT_1_N MSG_PREHEAT_1 _UxGT(" ") +#define MSG_PREHEAT_1_ALL MSG_PREHEAT_1 _UxGT("Todo") +#define MSG_PREHEAT_1_END MSG_PREHEAT_1 _UxGT(" End") +#define MSG_PREHEAT_1_BEDONLY MSG_PREHEAT_1 _UxGT("Plataforma") +#define MSG_PREHEAT_1_SETTINGS MSG_PREHEAT_1 _UxGT("Config") +#define MSG_PREHEAT_2 _UxGT("Precalentar ABS") +#define MSG_PREHEAT_2_N MSG_PREHEAT_2 _UxGT(" ") +#define MSG_PREHEAT_2_ALL MSG_PREHEAT_2 _UxGT("Todo") +#define MSG_PREHEAT_2_END MSG_PREHEAT_2 _UxGT(" End") +#define MSG_PREHEAT_2_BEDONLY MSG_PREHEAT_2 _UxGT("Plataforma") +#define MSG_PREHEAT_2_SETTINGS MSG_PREHEAT_2 _UxGT("Config") +#define MSG_COOLDOWN _UxGT("Enfriar") +#define MSG_SWITCH_PS_ON _UxGT("Encender") +#define MSG_SWITCH_PS_OFF _UxGT("Apagar") +#define MSG_EXTRUDE _UxGT("Extruir") +#define MSG_RETRACT _UxGT("Retraer") +#define MSG_MOVE_AXIS _UxGT("Mover ejes") +#define MSG_BED_LEVELING _UxGT("Nivelar plataforma") +#define MSG_LEVEL_BED _UxGT("Nivelar plataforma") +#define MSG_MOVING _UxGT("Moviendo...") +#define MSG_FREE_XY _UxGT("Libre XY") +#define MSG_MOVE_X _UxGT("Mover X") +#define MSG_MOVE_Y _UxGT("Mover Y") +#define MSG_MOVE_Z _UxGT("Mover Z") +#define MSG_MOVE_E _UxGT("Extrusor") +#define MSG_MOVE_01MM _UxGT("Mover 0.1mm") +#define MSG_MOVE_1MM _UxGT("Mover 1mm") +#define MSG_MOVE_10MM _UxGT("Mover 10mm") +#define MSG_SPEED _UxGT("Velocidad") +#define MSG_BED_Z _UxGT("Plataforma Z") +#define MSG_NOZZLE _UxGT("Boquilla") +#define MSG_BED _UxGT("Plataforma") +#define MSG_FAN_SPEED _UxGT("Ventilador") +#define MSG_FLOW _UxGT("Flujo") +#define MSG_CONTROL _UxGT("Control") +#define MSG_MIN _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" Min") +#define MSG_MAX _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" Max") +#define MSG_FACTOR _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" Fact") +#define MSG_AUTOTEMP _UxGT("Temperatura Auto.") +#define MSG_ON _UxGT("Encender") +#define MSG_OFF _UxGT("Apagar") +#define MSG_PID_P _UxGT("PID-P") +#define MSG_PID_I _UxGT("PID-I") +#define MSG_PID_D _UxGT("PID-D") +#define MSG_PID_C _UxGT("PID-C") +#define MSG_SELECT _UxGT("Seleccionar") +#define MSG_ACC _UxGT("Aceleracion") +#define MSG_JERK _UxGT("Jerk") +#define MSG_VX_JERK _UxGT("Vx-jerk") +#define MSG_VY_JERK _UxGT("Vy-jerk") +#define MSG_VZ_JERK _UxGT("Vz-jerk") +#define MSG_VE_JERK _UxGT("Ve-jerk") +#define MSG_VMAX _UxGT("Vmax") +#define MSG_VMIN _UxGT("Vmin") +#define MSG_VTRAV_MIN _UxGT("Vel. viaje min") +#define MSG_ACCELERATION MSG_ACC +#define MSG_AMAX _UxGT("Acel. max") +#define MSG_A_RETRACT _UxGT("Acel. retrac.") +#define MSG_A_TRAVEL _UxGT("Acel. Viaje") +#define MSG_STEPS_PER_MM _UxGT("Pasos/mm") +#define MSG_XSTEPS _UxGT("X pasos/mm") +#define MSG_YSTEPS _UxGT("Y pasos/mm") +#define MSG_ZSTEPS _UxGT("Z pasos/mm") +#define MSG_ESTEPS _UxGT("E pasos/mm") +#define MSG_E1STEPS _UxGT("E1 pasos/mm") +#define MSG_E2STEPS _UxGT("E2 pasos/mm") +#define MSG_E3STEPS _UxGT("E3 pasos/mm") +#define MSG_E4STEPS _UxGT("E4 pasos/mm") +#define MSG_E5STEPS _UxGT("E5 pasos/mm") +#define MSG_TEMPERATURE _UxGT("Temperatura") +#define MSG_MOTION _UxGT("Movimiento") +#define MSG_FILAMENT _UxGT("Filamento") +#define MSG_VOLUMETRIC_ENABLED _UxGT("E in mm3") +#define MSG_FILAMENT_DIAM _UxGT("Fil. Dia.") +#define MSG_ADVANCE_K _UxGT("Avance K") +#define MSG_CONTRAST _UxGT("Contraste") +#define MSG_STORE_EEPROM _UxGT("Guardar memoria") +#define MSG_LOAD_EEPROM _UxGT("Cargar memoria") +#define MSG_RESTORE_FAILSAFE _UxGT("Restaurar memoria") +#define MSG_REFRESH _UxGT("Volver a cargar") +#define MSG_WATCH _UxGT("Informacion") +#define MSG_PREPARE _UxGT("Preparar") +#define MSG_TUNE _UxGT("Ajustar") +#define MSG_PAUSE_PRINT _UxGT("Pausar impresion") +#define MSG_RESUME_PRINT _UxGT("Reanudar impresion") +#define MSG_STOP_PRINT _UxGT("Detener impresion") +#define MSG_CARD_MENU _UxGT("Menu de SD") +#define MSG_NO_CARD _UxGT("No hay tarjeta SD") +#define MSG_DWELL _UxGT("Reposo...") +#define MSG_USERWAIT _UxGT("Esperando ordenes") +#define MSG_RESUMING _UxGT("Resumiendo impre.") +#define MSG_PRINT_ABORTED _UxGT("Impresion cancelada") +#define MSG_NO_MOVE _UxGT("Sin movimiento") +#define MSG_KILLED _UxGT("Parada de emergencia") +#define MSG_STOPPED _UxGT("Detenida") +#define MSG_CONTROL_RETRACT _UxGT("Retraer mm") +#define MSG_CONTROL_RETRACT_SWAP _UxGT("Interc. Retraer mm") +#define MSG_CONTROL_RETRACTF _UxGT("Retraer V") +#define MSG_CONTROL_RETRACT_ZLIFT _UxGT("Levantar mm") +#define MSG_CONTROL_RETRACT_RECOVER _UxGT("DesRet mm") +#define MSG_CONTROL_RETRACT_RECOVER_SWAP _UxGT("Interc. DesRet mm") +#define MSG_CONTROL_RETRACT_RECOVERF _UxGT("DesRet V") +#define MSG_AUTORETRACT _UxGT("Retraccion Auto.") +#define MSG_FILAMENTCHANGE _UxGT("Cambiar filamento") +#define MSG_INIT_SDCARD _UxGT("Iniciando tarjeta") +#define MSG_CNG_SDCARD _UxGT("Cambiar tarjeta") +#define MSG_ZPROBE_OUT _UxGT("Sonda Z fuera") +#define MSG_BLTOUCH_SELFTEST _UxGT("BLTouch Auto-Prueba") +#define MSG_BLTOUCH_RESET _UxGT("Reiniciar BLTouch") +#define MSG_HOME _UxGT("Home") // Used as MSG_HOME " " MSG_X MSG_Y MSG_Z " " MSG_FIRST +#define MSG_FIRST _UxGT("inic.") +#define MSG_ZPROBE_ZOFFSET _UxGT("Desfase Z") +#define MSG_BABYSTEP_X _UxGT("Micropaso X") +#define MSG_BABYSTEP_Y _UxGT("Micropaso Y") +#define MSG_BABYSTEP_Z _UxGT("Micropaso Z") +#define MSG_ENDSTOP_ABORT _UxGT("Cancelado - Endstop") +#define MSG_HEATING_FAILED_LCD _UxGT("Error: al calentar") +#define MSG_ERR_REDUNDANT_TEMP _UxGT("Error: temperatura") +#define MSG_THERMAL_RUNAWAY _UxGT("Error: temperatura") +#define MSG_ERR_MAXTEMP _UxGT("Error: Temp Maxima") +#define MSG_ERR_MINTEMP _UxGT("Error: Temp Minima") +#define MSG_ERR_MAXTEMP_BED _UxGT("Error: Temp Max Plat") +#define MSG_ERR_MINTEMP_BED _UxGT("Error: Temp Min Plat") +#define MSG_ERR_Z_HOMING _UxGT("G28 Z Prohibido") +#define MSG_HALTED _UxGT("IMPRESORA PARADA") +#define MSG_PLEASE_RESET _UxGT("Por favor, reinicie") +#define MSG_SHORT_DAY _UxGT("d") // One character only +#define MSG_SHORT_HOUR _UxGT("h") // One character only +#define MSG_SHORT_MINUTE _UxGT("m") // One character only +#define MSG_HEATING _UxGT("Calentando...") +#define MSG_HEATING_COMPLETE _UxGT("Calentamiento listo") +#define MSG_BED_HEATING _UxGT("Calentando Plat...") +#define MSG_BED_DONE _UxGT("Plataforma Caliente") +#define MSG_DELTA_CALIBRATE _UxGT("Calibracion Delta") +#define MSG_DELTA_CALIBRATE_X _UxGT("Calibrar X") +#define MSG_DELTA_CALIBRATE_Y _UxGT("Calibrar Y") +#define MSG_DELTA_CALIBRATE_Z _UxGT("Calibrar Z") +#define MSG_DELTA_CALIBRATE_CENTER _UxGT("Calibrar Centro") +#define MSG_DELTA_AUTO_CALIBRATE _UxGT("Auto Calibracion") +#define MSG_DELTA_HEIGHT_CALIBRATE _UxGT("Est. Altura Delta") +#define MSG_INFO_MENU _UxGT("Inf. Impresora") +#define MSG_INFO_PRINTER_MENU _UxGT("Inf. Impresora") +#define MSG_INFO_STATS_MENU _UxGT("Estadisticas Imp.") +#define MSG_INFO_BOARD_MENU _UxGT("Inf. Controlador") +#define MSG_INFO_THERMISTOR_MENU _UxGT("Termistores") +#define MSG_INFO_EXTRUDERS _UxGT("Extrusores") +#define MSG_INFO_BAUDRATE _UxGT("Baudios") +#define MSG_INFO_PROTOCOL _UxGT("Protocolo") +#define MSG_CASE_LIGHT _UxGT("Luz cabina") + +#if LCD_WIDTH > 19 + #define MSG_INFO_PRINT_COUNT _UxGT("Conteo de impresion") + #define MSG_INFO_COMPLETED_PRINTS _UxGT("Completadas") + #define MSG_INFO_PRINT_TIME _UxGT("Tiempo total de imp.") + #define MSG_INFO_PRINT_LONGEST _UxGT("Impresion mas larga") + #define MSG_INFO_PRINT_FILAMENT _UxGT("Total de Extrusion") +#else + #define MSG_INFO_PRINT_COUNT _UxGT("Impresiones") + #define MSG_INFO_COMPLETED_PRINTS _UxGT("Completadas") + #define MSG_INFO_PRINT_TIME _UxGT("Total") + #define MSG_INFO_PRINT_LONGEST _UxGT("Mas larga") + #define MSG_INFO_PRINT_FILAMENT _UxGT("Extrusion") +#endif + +#define MSG_INFO_MIN_TEMP _UxGT("Temperatura minima") +#define MSG_INFO_MAX_TEMP _UxGT("Temperatura maxima") +#define MSG_INFO_PSU _UxGT("Fuente de poder") +#define MSG_DRIVE_STRENGTH _UxGT("Potencia driver") +#define MSG_DAC_PERCENT _UxGT("Driver %") +#define MSG_DAC_EEPROM_WRITE _UxGT("Escribe DAC EEPROM") + +#define MSG_FILAMENT_CHANGE_HEADER _UxGT("IMPR. PAUSADA") +#define MSG_FILAMENT_CHANGE_OPTION_HEADER _UxGT("OPC. REINICIO:") +#define MSG_FILAMENT_CHANGE_OPTION_EXTRUDE _UxGT("Extruir mas") +#define MSG_FILAMENT_CHANGE_OPTION_RESUME _UxGT("Resumir imp.") + +#define MSG_FILAMENT_CHANGE_MINTEMP _UxGT("Temp Minima es ") +#define MSG_FILAMENT_CHANGE_NOZZLE _UxGT(" Boquilla: ") + +#define MSG_FILAMENT_CHANGE_INIT_1 _UxGT("Esperando iniciar") + +#define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("Inserte filamento") +#define MSG_FILAMENT_CHANGE_INSERT_2 _UxGT("y presione el boton") + +#if LCD_HEIGHT >= 4 + // Up to 3 lines allowed + #define MSG_FILAMENT_CHANGE_INIT_2 _UxGT("del filamento") + #define MSG_FILAMENT_CHANGE_INIT_3 _UxGT("cambiar") + #define MSG_FILAMENT_CHANGE_INSERT_3 _UxGT("para continuar...") +#else // LCD_HEIGHT < 4 + // Up to 2 lines allowed + #define MSG_FILAMENT_CHANGE_INIT_2 _UxGT("del fil. cambiar") + #define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("Inserte filamento") +#endif // LCD_HEIGHT < 4 + +#define MSG_FILAMENT_CHANGE_UNLOAD_1 _UxGT("Esperado por") +#define MSG_FILAMENT_CHANGE_UNLOAD_2 _UxGT("filamento expulsado") +#define MSG_FILAMENT_CHANGE_LOAD_1 _UxGT("Esperado por") +#define MSG_FILAMENT_CHANGE_LOAD_2 _UxGT("Cargar filamento") +#define MSG_FILAMENT_CHANGE_EXTRUDE_1 _UxGT("Esperado por") +#define MSG_FILAMENT_CHANGE_EXTRUDE_2 _UxGT("Extruir filamento") +#define MSG_FILAMENT_CHANGE_RESUME_1 _UxGT("Esperando imp.") +#define MSG_FILAMENT_CHANGE_RESUME_2 _UxGT("para resumir") +#define MSG_FILAMENT_CHANGE_HEAT_1 _UxGT("Oprima boton para") +#define MSG_FILAMENT_CHANGE_HEAT_2 _UxGT("Calentar la boquilla") +#define MSG_FILAMENT_CHANGE_HEATING_1 _UxGT("Calentando boquilla") +#define MSG_FILAMENT_CHANGE_HEATING_2 _UxGT("Espere por favor") + +#endif // LANGUAGE_ES_H diff --git a/trunk/Arduino/Marlin_1.1.6/language_eu.h b/trunk/Arduino/Marlin_1.1.6/language_eu.h new file mode 100644 index 00000000..c4fe4ba4 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/language_eu.h @@ -0,0 +1,235 @@ +/** + * 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 . + * + */ + +/** + * Basque-Euskera + * + * LCD Menu Messages + * See also http://marlinfw.org/docs/development/lcd_language.html + * + */ +#ifndef LANGUAGE_EU_H +#define LANGUAGE_EU_H + +#define DISPLAY_CHARSET_ISO10646_1 + +#define WELCOME_MSG MACHINE_NAME _UxGT(" prest.") +#define MSG_BACK _UxGT("Atzera") +#define MSG_SD_INSERTED _UxGT("Txartela sartuta") +#define MSG_SD_REMOVED _UxGT("Txartela kenduta") +#define MSG_LCD_ENDSTOPS _UxGT("Endstops") // Max length 8 characters +#define MSG_MAIN _UxGT("Menu nagusia") +#define MSG_AUTOSTART _UxGT("Auto hasiera") +#define MSG_DISABLE_STEPPERS _UxGT("Itzali motoreak") +#define MSG_DEBUG_MENU _UxGT("Arazketa Menua") +#define MSG_PROGRESS_BAR_TEST _UxGT("Prog. Barra Proba") +#define MSG_AUTO_HOME _UxGT("Hasierara joan") +#define MSG_AUTO_HOME_X _UxGT("X jatorria") +#define MSG_AUTO_HOME_Y _UxGT("Y jatorria") +#define MSG_AUTO_HOME_Z _UxGT("Z jatorria") +#define MSG_LEVEL_BED_HOMING _UxGT("XYZ hasieraratzen") +#define MSG_LEVEL_BED_WAITING _UxGT("Klik egin hasteko") +#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Hurrengo Puntua") +#define MSG_LEVEL_BED_DONE _UxGT("Berdintzea eginda") +#define MSG_SET_HOME_OFFSETS _UxGT("Etxe. offset eza.") +#define MSG_HOME_OFFSETS_APPLIED _UxGT("Offsetak ezarrita") +#define MSG_SET_ORIGIN _UxGT("Hasiera ipini") +#define MSG_PREHEAT_1 _UxGT("Berotu PLA") +#define MSG_PREHEAT_1_N MSG_PREHEAT_1 _UxGT(" ") +#define MSG_PREHEAT_1_ALL MSG_PREHEAT_1 _UxGT(" Guztia") +#define MSG_PREHEAT_1_END MSG_PREHEAT_1 _UxGT(" Amaia") +#define MSG_PREHEAT_1_BEDONLY MSG_PREHEAT_1 _UxGT(" Ohea") +#define MSG_PREHEAT_1_SETTINGS MSG_PREHEAT_1 _UxGT(" konf.") +#define MSG_PREHEAT_2 _UxGT("Berotu ABS") +#define MSG_PREHEAT_2_N MSG_PREHEAT_1 _UxGT(" ") +#define MSG_PREHEAT_2_ALL MSG_PREHEAT_1 _UxGT(" Guztia") +#define MSG_PREHEAT_2_END MSG_PREHEAT_2 _UxGT(" Amaia") +#define MSG_PREHEAT_2_BEDONLY MSG_PREHEAT_1 _UxGT(" Ohea") +#define MSG_PREHEAT_2_SETTINGS MSG_PREHEAT_1 _UxGT(" konf.") +#define MSG_COOLDOWN _UxGT("Hoztu") +#define MSG_SWITCH_PS_ON _UxGT("Energia piztu") +#define MSG_SWITCH_PS_OFF _UxGT("Energia itzali") +#define MSG_EXTRUDE _UxGT("Estruitu") +#define MSG_RETRACT _UxGT("Atzera eragin") +#define MSG_MOVE_AXIS _UxGT("Ardatzak mugitu") +#define MSG_BED_LEVELING _UxGT("Ohea Berdindu") +#define MSG_LEVEL_BED _UxGT("Ohea Berdindu") +#define MSG_MOVING _UxGT("Mugitzen...") +#define MSG_FREE_XY _UxGT("Askatu XY") +#define MSG_MOVE_X _UxGT("Mugitu X") +#define MSG_MOVE_Y _UxGT("Mugitu Y") +#define MSG_MOVE_Z _UxGT("Mugitu Z") +#define MSG_MOVE_E _UxGT("Estrusorea") +#define MSG_MOVE_01MM _UxGT("Mugitu 0.1mm") +#define MSG_MOVE_1MM _UxGT("Mugitu 1mm") +#define MSG_MOVE_10MM _UxGT("Mugitu 10mm") +#define MSG_SPEED _UxGT("Abiadura") +#define MSG_BED_Z _UxGT("Z Ohea") +#define MSG_NOZZLE _UxGT("Pita") +#define MSG_BED _UxGT("Ohea") +#define MSG_FAN_SPEED _UxGT("Haizagailu abiada") +#define MSG_FLOW _UxGT("Fluxua") +#define MSG_CONTROL _UxGT("Kontrola") +#define MSG_MIN _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" Min") +#define MSG_MAX _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" Max") +#define MSG_FACTOR _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" Fakt") +#define MSG_AUTOTEMP _UxGT("Auto tenperatura") +#define MSG_ON _UxGT("On ") +#define MSG_OFF _UxGT("Off") +#define MSG_PID_P _UxGT("PID-P") +#define MSG_PID_I _UxGT("PID-I") +#define MSG_PID_D _UxGT("PID-D") +#define MSG_PID_C _UxGT("PID-C") +#define MSG_SELECT _UxGT("Aukeratu") +#define MSG_ACC _UxGT("Azelerazioa") +#define MSG_JERK _UxGT("Astindua") +#define MSG_VX_JERK _UxGT("Vx-astindua") +#define MSG_VY_JERK _UxGT("Vy-astindua") +#define MSG_VZ_JERK _UxGT("Vz-astindua") +#define MSG_VE_JERK _UxGT("Ve-astindua") +#define MSG_VMAX _UxGT("Vmax ") +#define MSG_VMIN _UxGT("Vmin") +#define MSG_VTRAV_MIN _UxGT("VBidaia min") +#define MSG_ACCELERATION MSG_ACC +#define MSG_AMAX _UxGT("Amax ") +#define MSG_A_RETRACT _UxGT("A-retrakt") +#define MSG_A_TRAVEL _UxGT("A-bidaia") +#define MSG_STEPS_PER_MM _UxGT("Pausoak/mm") +#define MSG_XSTEPS _UxGT("X pausoak/mm") +#define MSG_YSTEPS _UxGT("Y pausoak/mm") +#define MSG_ZSTEPS _UxGT("Z pausoak/mm") +#define MSG_ESTEPS _UxGT("E pausoak/mm") +#define MSG_E1STEPS _UxGT("E1 pausoak/mm") +#define MSG_E2STEPS _UxGT("E2 pausoak/mm") +#define MSG_E3STEPS _UxGT("E3 pausoak/mm") +#define MSG_E4STEPS _UxGT("E4 pausoak/mm") +#define MSG_E5STEPS _UxGT("E5 pausoak/mm") +#define MSG_TEMPERATURE _UxGT("Tenperatura") +#define MSG_MOTION _UxGT("Mugimendua") +#define MSG_FILAMENT _UxGT("Harizpia") +#define MSG_VOLUMETRIC_ENABLED _UxGT("E mm3-tan") +#define MSG_FILAMENT_DIAM _UxGT("Hariz. Dia.") +#define MSG_ADVANCE_K _UxGT("K Aurrerapena") +#define MSG_CONTRAST _UxGT("LCD kontrastea") +#define MSG_STORE_EEPROM _UxGT("Gorde memoria") +#define MSG_LOAD_EEPROM _UxGT("Kargatu memoria") +#define MSG_RESTORE_FAILSAFE _UxGT("Larri. berriz.") +#define MSG_REFRESH _UxGT("Berriz kargatu") +#define MSG_WATCH _UxGT("Pantaila info") +#define MSG_PREPARE _UxGT("Prestatu") +#define MSG_TUNE _UxGT("Doitu") +#define MSG_PAUSE_PRINT _UxGT("Pausatu inprimak.") +#define MSG_RESUME_PRINT _UxGT("Jarraitu inprima.") +#define MSG_STOP_PRINT _UxGT("Gelditu inprima.") +#define MSG_CARD_MENU _UxGT("SD-tik inprimatu") +#define MSG_NO_CARD _UxGT("Ez dago SD-rik") +#define MSG_DWELL _UxGT("Lo egin...") +#define MSG_USERWAIT _UxGT("Aginduak zain...") +#define MSG_RESUMING _UxGT("Jarraitzen inpri.") +#define MSG_PRINT_ABORTED _UxGT("Inprim. deusezta.") +#define MSG_NO_MOVE _UxGT("Mugimendu gabe.") +#define MSG_KILLED _UxGT("AKABATUTA. ") +#define MSG_STOPPED _UxGT("GELDITUTA. ") +#define MSG_CONTROL_RETRACT _UxGT("Atzera egin mm") +#define MSG_CONTROL_RETRACT_SWAP _UxGT("Swap Atzera mm") +#define MSG_CONTROL_RETRACTF _UxGT("Atzera egin V") +#define MSG_CONTROL_RETRACT_ZLIFT _UxGT("Igo mm") +#define MSG_CONTROL_RETRACT_RECOVER _UxGT("Atzera egin mm") +#define MSG_CONTROL_RETRACT_RECOVER_SWAP _UxGT("Swap Atzera mm") +#define MSG_CONTROL_RETRACT_RECOVERF _UxGT("Atzera egin V") +#define MSG_AUTORETRACT _UxGT("Atzera egin") +#define MSG_FILAMENTCHANGE _UxGT("Aldatu harizpia") +#define MSG_INIT_SDCARD _UxGT("Hasieratu SD-a") +#define MSG_CNG_SDCARD _UxGT("Aldatu txartela") +#define MSG_ZPROBE_OUT _UxGT("Z zunda kanpora") +#define MSG_BLTOUCH_SELFTEST _UxGT("BLTouch AutoProba") +#define MSG_BLTOUCH_RESET _UxGT("BLTouch berrabia.") +#define MSG_HOME _UxGT("Etxera") // Used as MSG_HOME " " MSG_X MSG_Y MSG_Z " " MSG_FIRST +#define MSG_FIRST _UxGT("lehenengo") +#define MSG_ZPROBE_ZOFFSET _UxGT("Z Konpentsatu") +#define MSG_BABYSTEP_X _UxGT("Mikro-urratsa X") +#define MSG_BABYSTEP_Y _UxGT("Mikro-urratsa Y") +#define MSG_BABYSTEP_Z _UxGT("Mikro-urratsa Z") +#define MSG_ENDSTOP_ABORT _UxGT("Endstop deusezta.") +#define MSG_HEATING_FAILED_LCD _UxGT("Err: Beroketa") +#define MSG_ERR_REDUNDANT_TEMP _UxGT("Err: Tenperatura") +#define MSG_THERMAL_RUNAWAY _UxGT("TENP. KONTROL EZA") +#define MSG_ERR_MAXTEMP _UxGT("Err: Tenp Maximoa") +#define MSG_ERR_MINTEMP _UxGT("Err: Tenp Minimoa") +#define MSG_ERR_MAXTEMP_BED _UxGT("Err: Ohe Tenp Max") +#define MSG_ERR_MINTEMP_BED _UxGT("Err: Ohe Tenp Min") +#define MSG_ERR_Z_HOMING _UxGT("G28 Z Debekatua") +#define MSG_HALTED _UxGT("INPRIMA. GELDIRIK") +#define MSG_PLEASE_RESET _UxGT("Berrabia. Mesedez") +#define MSG_SHORT_DAY _UxGT("d") // One character only +#define MSG_SHORT_HOUR _UxGT("h") // One character only +#define MSG_SHORT_MINUTE _UxGT("m") // One character only +#define MSG_HEATING _UxGT("Berotzen...") +#define MSG_HEATING_COMPLETE _UxGT("Berotzea prest.") +#define MSG_BED_HEATING _UxGT("Ohea Berotzen.") +#define MSG_BED_DONE _UxGT("Ohea Berotuta.") +#define MSG_DELTA_CALIBRATE _UxGT("Delta Kalibraketa") +#define MSG_DELTA_CALIBRATE_X _UxGT("Kalibratu X") +#define MSG_DELTA_CALIBRATE_Y _UxGT("Kalibratu Y") +#define MSG_DELTA_CALIBRATE_Z _UxGT("Kalibratu Z") +#define MSG_DELTA_CALIBRATE_CENTER _UxGT("Kalibratu Zentrua") +#define MSG_DELTA_AUTO_CALIBRATE _UxGT("Auto Kalibraketa") +#define MSG_DELTA_HEIGHT_CALIBRATE _UxGT("Delta Alt. Ezar.") +#define MSG_INFO_MENU _UxGT("Inprimagailu Inf.") +#define MSG_INFO_PRINTER_MENU _UxGT("Inprimagailu Inf.") +#define MSG_INFO_STATS_MENU _UxGT("Inprima. estatis.") +#define MSG_INFO_BOARD_MENU _UxGT("Txartelaren Info.") +#define MSG_INFO_THERMISTOR_MENU _UxGT("Termistoreak") +#define MSG_INFO_EXTRUDERS _UxGT("Estrusoreak") +#define MSG_INFO_BAUDRATE _UxGT("Baudioak") +#define MSG_INFO_PROTOCOL _UxGT("Protokoloa") +#define MSG_CASE_LIGHT _UxGT("Kabina Argia") + +#if LCD_WIDTH > 19 + #define MSG_INFO_PRINT_COUNT _UxGT("Inprim. Zenbaketa") + #define MSG_INFO_COMPLETED_PRINTS _UxGT("Burututa") + #define MSG_INFO_PRINT_TIME _UxGT("Inprim. denbora") + #define MSG_INFO_PRINT_LONGEST _UxGT("Imprimatze luzeena") + #define MSG_INFO_PRINT_FILAMENT _UxGT("Estruituta guztira") +#else + #define MSG_INFO_PRINT_COUNT _UxGT("Inprimatze") + #define MSG_INFO_COMPLETED_PRINTS _UxGT("Burututa") + #define MSG_INFO_PRINT_TIME _UxGT("Guztira") + #define MSG_INFO_PRINT_LONGEST _UxGT("Luzeena") + #define MSG_INFO_PRINT_FILAMENT _UxGT("Estrusio") +#endif +#define MSG_INFO_MIN_TEMP _UxGT("Tenp. Minimoa") +#define MSG_INFO_MAX_TEMP _UxGT("Tenp. Maximoa") +#define MSG_INFO_PSU _UxGT("Elikadura Iturria") +#define MSG_DRIVE_STRENGTH _UxGT("Driver Potentzia") +#define MSG_DAC_PERCENT _UxGT("Driver %") +#define MSG_DAC_EEPROM_WRITE _UxGT("Idatzi DAC EEPROM") + +#define MSG_FILAMENT_CHANGE_HEADER _UxGT("HARIZPIA ALDATU") +#define MSG_FILAMENT_CHANGE_OPTION_HEADER _UxGT("ALDAKETA AUKERAK:") +#define MSG_FILAMENT_CHANGE_OPTION_EXTRUDE _UxGT("Gehiago estruitu") +#define MSG_FILAMENT_CHANGE_OPTION_RESUME _UxGT("Inprima. jarraitu") + +#define MSG_FILAMENT_CHANGE_MINTEMP _UxGT("Tenp Minimoa ") +#define MSG_FILAMENT_CHANGE_NOZZLE _UxGT(" Pita: ") + +#endif // LANGUAGE_EU_H diff --git a/trunk/Arduino/Marlin_1.1.6/language_fi.h b/trunk/Arduino/Marlin_1.1.6/language_fi.h new file mode 100644 index 00000000..f04b0501 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/language_fi.h @@ -0,0 +1,160 @@ +/** + * 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 . + * + */ + +/** + * Finnish + * + * LCD Menu Messages + * See also http://marlinfw.org/docs/development/lcd_language.html + * + */ +#ifndef LANGUAGE_FI_H +#define LANGUAGE_FI_H + +#define MAPPER_C2C3 +#define DISPLAY_CHARSET_ISO10646_1 + +#define WELCOME_MSG MACHINE_NAME _UxGT(" valmis.") +#define MSG_SD_INSERTED _UxGT("Kortti asetettu") +#define MSG_SD_REMOVED _UxGT("Kortti poistettu") +#define MSG_MAIN _UxGT("Palaa") +#define MSG_AUTOSTART _UxGT("Automaatti") +#define MSG_DISABLE_STEPPERS _UxGT("Vapauta moottorit") +#define MSG_AUTO_HOME _UxGT("Aja referenssiin") +#define MSG_LEVEL_BED_HOMING _UxGT("Homing XYZ") +#define MSG_LEVEL_BED_WAITING _UxGT("Click to Begin") +#define MSG_LEVEL_BED_DONE _UxGT("Leveling Done!") +#define MSG_SET_HOME_OFFSETS _UxGT("Set home offsets") +#define MSG_HOME_OFFSETS_APPLIED _UxGT("Offsets applied") +#define MSG_SET_ORIGIN _UxGT("Aseta origo") +#define MSG_PREHEAT_1 _UxGT("Esilämmitä PLA") +#define MSG_PREHEAT_1_N _UxGT("Esilämmitä PLA ") +#define MSG_PREHEAT_1_ALL _UxGT("Esilä. PLA Kaikki") +#define MSG_PREHEAT_1_BEDONLY _UxGT("Esilä. PLA Alusta") +#define MSG_PREHEAT_1_SETTINGS _UxGT("Esilämm. PLA konf") +#define MSG_PREHEAT_2 _UxGT("Esilämmitä ABS") +#define MSG_PREHEAT_2_N _UxGT("Esilämmitä ABS ") +#define MSG_PREHEAT_2_ALL _UxGT("Esilä. ABS Kaikki") +#define MSG_PREHEAT_2_BEDONLY _UxGT("Esilä. ABS Alusta") +#define MSG_PREHEAT_2_SETTINGS _UxGT("Esilämm. ABS konf") +#define MSG_COOLDOWN _UxGT("Jäähdytä") +#define MSG_SWITCH_PS_ON _UxGT("Virta päälle") +#define MSG_SWITCH_PS_OFF _UxGT("Virta pois") +#define MSG_EXTRUDE _UxGT("Pursota") +#define MSG_RETRACT _UxGT("Vedä takaisin") +#define MSG_MOVE_AXIS _UxGT("Liikuta akseleita") +#define MSG_MOVE_X _UxGT("Liikuta X") +#define MSG_MOVE_Y _UxGT("Liikuta Y") +#define MSG_MOVE_Z _UxGT("Liikuta Z") +#define MSG_MOVE_E _UxGT("Extruder") +#define MSG_MOVE_01MM _UxGT("Liikuta 0.1mm") +#define MSG_MOVE_1MM _UxGT("Liikuta 1mm") +#define MSG_MOVE_10MM _UxGT("Liikuta 10mm") +#define MSG_SPEED _UxGT("Nopeus") +#define MSG_NOZZLE _UxGT("Suutin") +#define MSG_BED _UxGT("Alusta") +#define MSG_FAN_SPEED _UxGT("Tuul. nopeus") +#define MSG_FLOW _UxGT("Virtaus") +#define MSG_CONTROL _UxGT("Kontrolli") +#define MSG_MIN LCD_STR_THERMOMETER _UxGT(" Min") +#define MSG_MAX LCD_STR_THERMOMETER _UxGT(" Max") +#define MSG_FACTOR LCD_STR_THERMOMETER _UxGT(" Kerr") +#define MSG_AUTOTEMP _UxGT("Autotemp") +#define MSG_ON _UxGT("On ") +#define MSG_OFF _UxGT("Off") +#define MSG_PID_P _UxGT("PID-P") +#define MSG_PID_I _UxGT("PID-I") +#define MSG_PID_D _UxGT("PID-D") +#define MSG_PID_C _UxGT("PID-C") +#define MSG_ACC _UxGT("Kiihtyv") +#define MSG_JERK _UxGT("Jerk") +#define MSG_VX_JERK _UxGT("Vx-jerk") +#define MSG_VY_JERK _UxGT("Vy-jerk") +#define MSG_VZ_JERK _UxGT("Vz-jerk") +#define MSG_VE_JERK _UxGT("Ve-jerk") +#define MSG_VMAX _UxGT("Vmax ") +#define MSG_VMIN _UxGT("Vmin") +#define MSG_VTRAV_MIN _UxGT("VLiike min") +#define MSG_ACCELERATION MSG_ACC +#define MSG_AMAX _UxGT("Amax ") +#define MSG_A_RETRACT _UxGT("A-peruuta") +#define MSG_STEPS_PER_MM _UxGT("Steps/mm") +#define MSG_XSTEPS _UxGT("Xsteps/mm") +#define MSG_YSTEPS _UxGT("Ysteps/mm") +#define MSG_ZSTEPS _UxGT("Zsteps/mm") +#define MSG_ESTEPS _UxGT("Esteps/mm") +#define MSG_E1STEPS _UxGT("E1steps/mm") +#define MSG_E2STEPS _UxGT("E2steps/mm") +#define MSG_E3STEPS _UxGT("E3steps/mm") +#define MSG_E4STEPS _UxGT("E4steps/mm") +#define MSG_E5STEPS _UxGT("E5steps/mm") +#define MSG_TEMPERATURE _UxGT("Lämpötila") +#define MSG_MOTION _UxGT("Liike") +#define MSG_FILAMENT _UxGT("Filament") +#define MSG_VOLUMETRIC_ENABLED _UxGT("E in mm³") +#define MSG_FILAMENT_DIAM _UxGT("Fil. Dia.") +#define MSG_CONTRAST _UxGT("LCD kontrasti") +#define MSG_STORE_EEPROM _UxGT("Tallenna muistiin") +#define MSG_LOAD_EEPROM _UxGT("Lataa muistista") +#define MSG_RESTORE_FAILSAFE _UxGT("Palauta oletus") +#define MSG_REFRESH _UxGT("Päivitä") +#define MSG_WATCH _UxGT("Seuraa") +#define MSG_PREPARE _UxGT("Valmistele") +#define MSG_TUNE _UxGT("Säädä") +#define MSG_PAUSE_PRINT _UxGT("Keskeytä tulostus") +#define MSG_RESUME_PRINT _UxGT("Jatka tulostusta") +#define MSG_STOP_PRINT _UxGT("Pysäytä tulostus") +#define MSG_CARD_MENU _UxGT("Korttivalikko") +#define MSG_NO_CARD _UxGT("Ei korttia") +#define MSG_DWELL _UxGT("Nukkumassa...") +#define MSG_USERWAIT _UxGT("Odotet. valintaa") +#define MSG_RESUMING _UxGT("Jatke. tulostusta") +#define MSG_PRINT_ABORTED _UxGT("Print aborted") +#define MSG_NO_MOVE _UxGT("Ei liiketta.") +#define MSG_KILLED _UxGT("KILLED. ") +#define MSG_STOPPED _UxGT("STOPPED. ") +#define MSG_CONTROL_RETRACT _UxGT("Vedä mm") +#define MSG_CONTROL_RETRACT_SWAP _UxGT("Va. Vedä mm") +#define MSG_CONTROL_RETRACTF _UxGT("Vedä V") +#define MSG_CONTROL_RETRACT_ZLIFT _UxGT("Z mm") +#define MSG_CONTROL_RETRACT_RECOVER _UxGT("UnRet mm") +#define MSG_CONTROL_RETRACT_RECOVER_SWAP _UxGT("Va. UnRet mm") +#define MSG_CONTROL_RETRACT_RECOVERF _UxGT("UnRet V") +#define MSG_AUTORETRACT _UxGT("AutoVeto.") +#define MSG_FILAMENTCHANGE _UxGT("Change filament") +#define MSG_INIT_SDCARD _UxGT("Init. SD-Card") +#define MSG_CNG_SDCARD _UxGT("Change SD-Card") +#define MSG_ZPROBE_OUT _UxGT("Z probe out. bed") +#define MSG_HOME _UxGT("Home") // Used as MSG_HOME " " MSG_X MSG_Y MSG_Z " " MSG_FIRST +#define MSG_FIRST _UxGT("first") +#define MSG_ZPROBE_ZOFFSET _UxGT("Z Offset") +#define MSG_BABYSTEP_X _UxGT("Babystep X") +#define MSG_BABYSTEP_Y _UxGT("Babystep Y") +#define MSG_BABYSTEP_Z _UxGT("Babystep Z") +#define MSG_ENDSTOP_ABORT _UxGT("Endstop abort") +#define MSG_DELTA_CALIBRATE _UxGT("Delta Kalibrointi") +#define MSG_DELTA_CALIBRATE_X _UxGT("Kalibroi X") +#define MSG_DELTA_CALIBRATE_Y _UxGT("Kalibroi Y") +#define MSG_DELTA_CALIBRATE_Z _UxGT("Kalibroi Z") +#define MSG_DELTA_CALIBRATE_CENTER _UxGT("Kalibroi Center") + +#endif // LANGUAGE_FI_H diff --git a/trunk/Arduino/Marlin_1.1.6/language_fr.h b/trunk/Arduino/Marlin_1.1.6/language_fr.h new file mode 100644 index 00000000..d448cf91 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/language_fr.h @@ -0,0 +1,344 @@ +/** + * 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 . + * + */ + +/** + * French + * + * LCD Menu Messages + * See also http://marlinfw.org/docs/development/lcd_language.html + * + */ +#ifndef LANGUAGE_FR_H +#define LANGUAGE_FR_H + +#define MAPPER_C2C3 +#define DISPLAY_CHARSET_ISO10646_1 + +#define WELCOME_MSG MACHINE_NAME _UxGT(" prête.") +#define MSG_BACK _UxGT("Retour") +#define MSG_SD_INSERTED _UxGT("Carte insérée") +#define MSG_SD_REMOVED _UxGT("Carte retirée") +#define MSG_LCD_ENDSTOPS _UxGT("Butées") // Max length 8 characters +#define MSG_MAIN _UxGT("Menu principal") +#define MSG_AUTOSTART _UxGT("Demarrage auto") +#define MSG_DISABLE_STEPPERS _UxGT("Arrêter moteurs") +#define MSG_DEBUG_MENU _UxGT("Menu debug") +#define MSG_PROGRESS_BAR_TEST _UxGT("Test barre progress.") +#define MSG_AUTO_HOME _UxGT("Origine auto.") +#define MSG_AUTO_HOME_X _UxGT("Origine X Auto.") +#define MSG_AUTO_HOME_Y _UxGT("Origine Y Auto.") +#define MSG_AUTO_HOME_Z _UxGT("Origine Z Auto.") +#define MSG_LEVEL_BED_HOMING _UxGT("Origine XYZ") +#define MSG_LEVEL_BED_WAITING _UxGT("Clic pour commencer") +#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Point suivant") +#define MSG_LEVEL_BED_DONE _UxGT("Mise à niveau OK!") +#define MSG_Z_FADE_HEIGHT _UxGT("Adoucir hauteur") +#define MSG_SET_HOME_OFFSETS _UxGT("Regl. décal. origine") +#define MSG_HOME_OFFSETS_APPLIED _UxGT("Décalages appliqués") +#define MSG_SET_ORIGIN _UxGT("Régler origine") +#define MSG_PREHEAT_1 _UxGT("Préchauffage PLA") +#define MSG_PREHEAT_1_N _UxGT("Préchauff. PLA ") +#define MSG_PREHEAT_1_ALL _UxGT("Préch. PLA Tout") +#define MSG_PREHEAT_1_END MSG_PREHEAT_1 _UxGT(" fini") +#define MSG_PREHEAT_1_BEDONLY _UxGT("Préch. PLA lit") +#define MSG_PREHEAT_1_SETTINGS _UxGT("Regl. prech. PLA") +#define MSG_PREHEAT_2 _UxGT("Préchauffage ABS") +#define MSG_PREHEAT_2_N _UxGT("Préchauff. ABS ") +#define MSG_PREHEAT_2_ALL _UxGT("Préch. ABS Tout") +#define MSG_PREHEAT_2_END MSG_PREHEAT_2 _UxGT(" fini") +#define MSG_PREHEAT_2_BEDONLY _UxGT("Préch. ABS lit") +#define MSG_PREHEAT_2_SETTINGS _UxGT("Regl. prech. ABS") +#define MSG_COOLDOWN _UxGT("Refroidir") +#define MSG_SWITCH_PS_ON _UxGT("Allumer alim.") +#define MSG_SWITCH_PS_OFF _UxGT("Éteindre alim.") +#define MSG_EXTRUDE _UxGT("Éxtrusion") +#define MSG_RETRACT _UxGT("Rétraction") +#define MSG_MOVE_AXIS _UxGT("Déplacer un axe") +#define MSG_BED_LEVELING _UxGT("Règl. Niv. lit") +#define MSG_LEVEL_BED _UxGT("Règl. Niv. lit") +#define MSG_EDITING_STOPPED _UxGT("Arrêt edit. maillage") +#define MSG_USER_MENU _UxGT("Commandes perso") + +#define MSG_UBL_DOING_G29 _UxGT("G29 en cours") +#define MSG_UBL_UNHOMED _UxGT("Origine XYZ d'abord") +#define MSG_UBL_TOOLS _UxGT("Outils UBL") +#define MSG_UBL_LEVEL_BED _UxGT("Niveau lit unifié") +#define MSG_UBL_MANUAL_MESH _UxGT("Maillage manuel") +#define MSG_UBL_BC_INSERT _UxGT("Poser câle & mesurer") +#define MSG_UBL_BC_INSERT2 _UxGT("Mesure") +#define MSG_UBL_BC_REMOVE _UxGT("ôter et mesurer lit") +#define MSG_UBL_MOVING_TO_NEXT _UxGT("Aller au suivant") +#define MSG_UBL_ACTIVATE_MESH _UxGT("Activer l'UBL") +#define MSG_UBL_DEACTIVATE_MESH _UxGT("Désactiver l'UBL") +#define MSG_UBL_SET_BED_TEMP _UxGT("Température lit") +#define MSG_UBL_CUSTOM_BED_TEMP MSG_UBL_SET_BED_TEMP +#define MSG_UBL_SET_HOTEND_TEMP _UxGT("Température buse") +#define MSG_UBL_CUSTOM_HOTEND_TEMP MSG_UBL_SET_HOTEND_TEMP +#define MSG_UBL_EDIT_CUSTOM_MESH _UxGT("Editer maille perso") +#define MSG_UBL_FINE_TUNE_MESH _UxGT("Réglage fin maille") +#define MSG_UBL_DONE_EDITING_MESH _UxGT("Termier maille") +#define MSG_UBL_BUILD_CUSTOM_MESH _UxGT("Créer maille perso") +#define MSG_UBL_BUILD_MESH_MENU _UxGT("Créer maille") +#define MSG_UBL_BUILD_PLA_MESH _UxGT("Créer maille PLA") +#define MSG_UBL_BUILD_ABS_MESH _UxGT("Créer maille ABS") +#define MSG_UBL_BUILD_COLD_MESH _UxGT("Créer maille froide") +#define MSG_UBL_MESH_HEIGHT_ADJUST _UxGT("Ajuster haut. maille") +#define MSG_UBL_MESH_HEIGHT_AMOUNT _UxGT("Hauteur") +#define MSG_UBL_VALIDATE_MESH_MENU _UxGT("Valider maille") +#define MSG_UBL_VALIDATE_PLA_MESH _UxGT("Valider maille PLA") +#define MSG_UBL_VALIDATE_ABS_MESH _UxGT("Valider maille ABS") +#define MSG_UBL_VALIDATE_CUSTOM_MESH _UxGT("Valider maille perso") +#define MSG_UBL_CONTINUE_MESH _UxGT("Continuer maille") +#define MSG_UBL_MESH_LEVELING _UxGT("Niveau par maille") +#define MSG_UBL_3POINT_MESH_LEVELING _UxGT("Niveau à 3 points") +#define MSG_UBL_GRID_MESH_LEVELING _UxGT("Niveau grille") +#define MSG_UBL_MESH_LEVEL _UxGT("Maille de niveau") +#define MSG_UBL_SIDE_POINTS _UxGT("Point latéral") +#define MSG_UBL_MAP_TYPE _UxGT("Type de carte") +#define MSG_UBL_OUTPUT_MAP _UxGT("Voir maille") +#define MSG_UBL_OUTPUT_MAP_HOST _UxGT("Voir pour hôte") +#define MSG_UBL_OUTPUT_MAP_CSV _UxGT("Voir pour CSV") +#define MSG_UBL_OUTPUT_MAP_BACKUP _UxGT("Off Printer Backup") +#define MSG_UBL_INFO_UBL _UxGT("Voir info UBL") +#define MSG_UBL_EDIT_MESH_MENU _UxGT("Modifier maille") +#define MSG_UBL_FILLIN_AMOUNT _UxGT("Taux de remplissage") +#define MSG_UBL_MANUAL_FILLIN _UxGT("Remplissage manuel") +#define MSG_UBL_SMART_FILLIN _UxGT("Remplissage auto") +#define MSG_UBL_FILLIN_MESH _UxGT("Maille remplissage") +#define MSG_UBL_INVALIDATE_ALL _UxGT("Annuler tout") +#define MSG_UBL_INVALIDATE_CLOSEST _UxGT("Annuler le plus près") +#define MSG_UBL_FINE_TUNE_ALL _UxGT("Réglage fin (tous)") +#define MSG_UBL_FINE_TUNE_CLOSEST _UxGT("Réglage fin (proche)") +#define MSG_UBL_STORAGE_MESH_MENU _UxGT("Stockage maille") +#define MSG_UBL_STORAGE_SLOT _UxGT("Slot mémoire") +#define MSG_UBL_LOAD_MESH _UxGT("Charger maille") +#define MSG_UBL_SAVE_MESH _UxGT("Sauver maille") +#define MSG_UBL_SAVE_ERROR _UxGT("Err: Enreg. UBL") +#define MSG_UBL_RESTORE_ERROR _UxGT("Err: Ouvrir UBL") +#define MSG_UBL_Z_OFFSET_STOPPED _UxGT("Offset Z arrêté") + + +#define MSG_MOVING _UxGT("Déplacement...") +#define MSG_FREE_XY _UxGT("Débloquer XY") +#define MSG_MOVE_X _UxGT("Dépl. X") +#define MSG_MOVE_Y _UxGT("Dépl. Y") +#define MSG_MOVE_Z _UxGT("Dépl. Z") +#define MSG_MOVE_E _UxGT("Extruder") +#define MSG_MOVE_01MM _UxGT("Dépl. 0.1mm") +#define MSG_MOVE_1MM _UxGT("Dépl. 1mm") +#define MSG_MOVE_10MM _UxGT("Dépl. 10mm") +#define MSG_SPEED _UxGT(" Vitesse") +#define MSG_BED_Z _UxGT("Lit Z") +#define MSG_NOZZLE _UxGT("Buse") +#define MSG_BED _UxGT("Lit") +#define MSG_FAN_SPEED _UxGT("Vitesse ventil.") +#define MSG_FLOW _UxGT("Flux") +#define MSG_CONTROL _UxGT("Contrôler") +#define MSG_MIN LCD_STR_THERMOMETER _UxGT(" Min") +#define MSG_MAX LCD_STR_THERMOMETER _UxGT(" Max") +#define MSG_FACTOR LCD_STR_THERMOMETER _UxGT(" Facteur") +#define MSG_AUTOTEMP _UxGT("Temp. Auto.") +#define MSG_ON _UxGT("Marche ") +#define MSG_OFF _UxGT("Arrêt") +#define MSG_PID_P _UxGT("PID-P") +#define MSG_PID_I _UxGT("PID-I") +#define MSG_PID_D _UxGT("PID-D") +#define MSG_PID_C _UxGT("PID-C") +#define MSG_SELECT _UxGT("Sélectionner") +#define MSG_ACC _UxGT("Accélération") +#define MSG_JERK _UxGT("Jerk") +#define MSG_VX_JERK _UxGT("Vx-jerk") +#define MSG_VY_JERK _UxGT("Vy-jerk") +#define MSG_VZ_JERK _UxGT("Vz-jerk") +#define MSG_VE_JERK _UxGT("Ve-jerk") +#define MSG_VELOCITY _UxGT("Vélocité") +#define MSG_VMAX _UxGT("Vmax") +#define MSG_VMIN _UxGT("Vmin") +#define MSG_VTRAV_MIN _UxGT("Vdepl min") +#define MSG_ACCELERATION _UxGT("Accélération") +#define MSG_AMAX _UxGT("Amax ") +#define MSG_A_RETRACT _UxGT("A-retract") +#define MSG_A_TRAVEL _UxGT("A-Dépl.") +#define MSG_STEPS_PER_MM _UxGT("Pas/mm") +#define MSG_XSTEPS _UxGT("Xpas/mm") +#define MSG_YSTEPS _UxGT("Ypas/mm") +#define MSG_ZSTEPS _UxGT("Zpas/mm") +#define MSG_ESTEPS _UxGT("Epas/mm") +#define MSG_E1STEPS _UxGT("E1pas/mm") +#define MSG_E2STEPS _UxGT("E2pas/mm") +#define MSG_E3STEPS _UxGT("E3pas/mm") +#define MSG_E4STEPS _UxGT("E4pas/mm") +#define MSG_E5STEPS _UxGT("E5pas/mm") +#define MSG_TEMPERATURE _UxGT("Température") +#define MSG_MOTION _UxGT("Mouvement") +#define MSG_FILAMENT _UxGT("Filament") +#define MSG_VOLUMETRIC_ENABLED _UxGT("E en mm3") +#define MSG_FILAMENT_DIAM _UxGT("Diam. Fil.") +#define MSG_ADVANCE_K _UxGT("Advance K") +#define MSG_CONTRAST _UxGT("Contraste LCD") +#define MSG_STORE_EEPROM _UxGT("Sauver config") +#define MSG_LOAD_EEPROM _UxGT("Lire config") +#define MSG_RESTORE_FAILSAFE _UxGT("Restaurer défauts") +#define MSG_INIT_EEPROM _UxGT("Initialiser EEPROM") +#define MSG_REFRESH _UxGT("Actualiser") +#define MSG_WATCH _UxGT("Surveiller") +#define MSG_PREPARE _UxGT("Préparer") +#define MSG_TUNE _UxGT("Régler") +#define MSG_PAUSE_PRINT _UxGT("Interrompre impr.") +#define MSG_RESUME_PRINT _UxGT("Reprendre impr.") +#define MSG_STOP_PRINT _UxGT("Arrêter impr.") +#define MSG_CARD_MENU _UxGT("Impr. depuis SD") +#define MSG_NO_CARD _UxGT("Pas de carte") +#define MSG_DWELL _UxGT("Repos...") +#define MSG_USERWAIT _UxGT("Atten. de l'util.") +#define MSG_PRINT_PAUSED _UxGT("Impr. en pause") +#define MSG_RESUMING _UxGT("Repri. de l'impr.") +#define MSG_PRINT_ABORTED _UxGT("Impr. Annulée") +#define MSG_NO_MOVE _UxGT("Moteurs bloqués.") +#define MSG_KILLED _UxGT("MORT.") +#define MSG_STOPPED _UxGT("STOPPÉ.") +#define MSG_CONTROL_RETRACT _UxGT("Retraction mm") +#define MSG_CONTROL_RETRACT_SWAP _UxGT("Ech. Retr. mm") +#define MSG_CONTROL_RETRACTF _UxGT("Rétraction V") +#define MSG_CONTROL_RETRACT_ZLIFT _UxGT("Saut Z mm") +#define MSG_CONTROL_RETRACT_RECOVER _UxGT("UnRet mm") +#define MSG_CONTROL_RETRACT_RECOVER_SWAP _UxGT("Ech. UnRet mm") +#define MSG_CONTROL_RETRACT_RECOVERF _UxGT("UnRet V") +#define MSG_AUTORETRACT _UxGT("Rétract. Auto.") +#define MSG_FILAMENTCHANGE _UxGT("Changer filament") +#define MSG_INIT_SDCARD _UxGT("Init. la carte SD") +#define MSG_CNG_SDCARD _UxGT("Changer de carte") +#define MSG_ZPROBE_OUT _UxGT("Z sonde extè. lit") +#define MSG_BLTOUCH _UxGT("BLTouch") +#define MSG_BLTOUCH_SELFTEST _UxGT("Autotest BLTouch") +#define MSG_BLTOUCH_RESET _UxGT("RaZ BLTouch") +#define MSG_BLTOUCH_DEPLOY _UxGT("Déployer BLTouch") +#define MSG_BLTOUCH_STOW _UxGT("Ranger BLTouch") +#define MSG_HOME _UxGT("Origine") // Used as MSG_HOME " " MSG_X MSG_Y MSG_Z " " MSG_FIRST +#define MSG_FIRST _UxGT("Premier") +#define MSG_ZPROBE_ZOFFSET _UxGT("Décalage Z") +#define MSG_BABYSTEP_X _UxGT("Babystep X") +#define MSG_BABYSTEP_Y _UxGT("Babystep Y") +#define MSG_BABYSTEP_Z _UxGT("Babystep Z") +#define MSG_ENDSTOP_ABORT _UxGT("Butée abandon") +#define MSG_HEATING_FAILED_LCD _UxGT("Erreur de chauffe") +#define MSG_ERR_REDUNDANT_TEMP _UxGT("Err: TEMP. REDONDANT") +#define MSG_THERMAL_RUNAWAY _UxGT("EMBALLEMENT THERM.") +#define MSG_ERR_MAXTEMP _UxGT("Err: TEMP. MAX") +#define MSG_ERR_MINTEMP _UxGT("Err: TEMP. MIN") +#define MSG_ERR_MAXTEMP_BED _UxGT("Err: TEMP. MAX LIT") +#define MSG_ERR_MINTEMP_BED _UxGT("Err: TEMP. MIN LIT") +#define MSG_ERR_Z_HOMING _UxGT("G28 Z interdit") + +#define MSG_HALTED _UxGT("IMPR. STOPPÉE") +#define MSG_PLEASE_RESET _UxGT("RaZ. SVP") +#define MSG_SHORT_DAY _UxGT("j") // One character only +#define MSG_SHORT_HOUR _UxGT("h") // One character only +#define MSG_SHORT_MINUTE _UxGT("m") // One character only + +#define MSG_HEATING _UxGT("En chauffe...") +#define MSG_HEATING_COMPLETE _UxGT("Chauffe terminée") +#define MSG_BED_HEATING _UxGT("Lit en chauffe..") +#define MSG_BED_DONE _UxGT("Chauffe lit terminée") +#define MSG_DELTA_CALIBRATE _UxGT("Calibration Delta") +#define MSG_DELTA_CALIBRATE_X _UxGT("Calibrer X") +#define MSG_DELTA_CALIBRATE_Y _UxGT("Calibrer Y") +#define MSG_DELTA_CALIBRATE_Z _UxGT("Calibrer Z") +#define MSG_DELTA_CALIBRATE_CENTER _UxGT("Calibrer centre") +#define MSG_DELTA_AUTO_CALIBRATE _UxGT("Calibration Auto") +#define MSG_DELTA_HEIGHT_CALIBRATE _UxGT("Hauteur Delta") + +#define MSG_INFO_MENU _UxGT("Infos imprimante") +#define MSG_INFO_PRINTER_MENU _UxGT("Infos imprimante") +#define MSG_3POINT_LEVELING _UxGT("Niveau à 3 points") +#define MSG_LINEAR_LEVELING _UxGT("Niveau linéaire") +#define MSG_BILINEAR_LEVELING _UxGT("Niveau bilinéaire") +#define MSG_UBL_LEVELING _UxGT("Niveau lit unifié") +#define MSG_MESH_LEVELING _UxGT("Niveau maillage") +#define MSG_INFO_STATS_MENU _UxGT("Stats. imprimante") +#define MSG_INFO_BOARD_MENU _UxGT("Infos carte") +#define MSG_INFO_THERMISTOR_MENU _UxGT("Thermistors") +#define MSG_INFO_EXTRUDERS _UxGT("Extrudeurs") +#define MSG_INFO_BAUDRATE _UxGT("Baud") +#define MSG_INFO_PROTOCOL _UxGT("Protocole") +#define MSG_CASE_LIGHT _UxGT("Lumière caisson") +#define MSG_CASE_LIGHT_BRIGHTNESS _UxGT("Luminosité") + +#if LCD_WIDTH >= 20 + #define MSG_INFO_PRINT_COUNT _UxGT("Nbre impressions") + #define MSG_INFO_COMPLETED_PRINTS _UxGT("Terminées") + #define MSG_INFO_PRINT_TIME _UxGT("Tps impr. total") + #define MSG_INFO_PRINT_LONGEST _UxGT("Impr. la + longue") + #define MSG_INFO_PRINT_FILAMENT _UxGT("Total filament") +#else + #define MSG_INFO_PRINT_COUNT _UxGT("Impressions") + #define MSG_INFO_COMPLETED_PRINTS _UxGT("Terminées") + #define MSG_INFO_PRINT_TIME _UxGT("Total") + #define MSG_INFO_PRINT_LONGEST _UxGT("+ long") + #define MSG_INFO_PRINT_FILAMENT _UxGT("Filament") +#endif + +#define MSG_INFO_MIN_TEMP _UxGT("Temp Min") +#define MSG_INFO_MAX_TEMP _UxGT("Temp Max") +#define MSG_INFO_PSU _UxGT("Alimentation") +#define MSG_DRIVE_STRENGTH _UxGT("Puiss. moteur ") +#define MSG_DAC_PERCENT _UxGT("Driver %") +#define MSG_DAC_EEPROM_WRITE _UxGT("DAC EEPROM sauv.") + +#define MSG_FILAMENT_CHANGE_HEADER _UxGT("PRINT PAUSED") +#define MSG_FILAMENT_CHANGE_OPTION_HEADER _UxGT("RESUME OPTIONS:") +#define MSG_FILAMENT_CHANGE_OPTION_EXTRUDE _UxGT("+ extrusion") +#define MSG_FILAMENT_CHANGE_OPTION_RESUME _UxGT("Reprendre impr.") +#define MSG_FILAMENT_CHANGE_MINTEMP _UxGT("La temp. minimum est ") +#define MSG_FILAMENT_CHANGE_NOZZLE _UxGT(" Buse: ") + +#if LCD_HEIGHT >= 4 + // Up to 3 lines allowed + #define MSG_FILAMENT_CHANGE_INIT_1 _UxGT("Attente Démarrage") + #define MSG_FILAMENT_CHANGE_INIT_2 _UxGT("du filament") + #define MSG_FILAMENT_CHANGE_INIT_3 _UxGT("changer") + #define MSG_FILAMENT_CHANGE_UNLOAD_1 _UxGT("attente de") + #define MSG_FILAMENT_CHANGE_UNLOAD_2 _UxGT("décharger filament") + #define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("insérer filament") + #define MSG_FILAMENT_CHANGE_INSERT_2 _UxGT("et app. bouton") + #define MSG_FILAMENT_CHANGE_INSERT_3 _UxGT("pour continuer...") + #define MSG_FILAMENT_CHANGE_HEAT_1 _UxGT("Presser le bouton...") + #define MSG_FILAMENT_CHANGE_HEAT_2 _UxGT("Pr chauffer la buse") + #define MSG_FILAMENT_CHANGE_HEATING_1 _UxGT("Buse en chauffe") + #define MSG_FILAMENT_CHANGE_HEATING_2 _UxGT("Patientez SVP...") + #define MSG_FILAMENT_CHANGE_LOAD_1 _UxGT("attente de") + #define MSG_FILAMENT_CHANGE_LOAD_2 _UxGT("chargement filament") + #define MSG_FILAMENT_CHANGE_EXTRUDE_1 _UxGT("attente de") + #define MSG_FILAMENT_CHANGE_EXTRUDE_2 _UxGT("extrusion filament") + #define MSG_FILAMENT_CHANGE_RESUME_1 _UxGT("attente impression") + #define MSG_FILAMENT_CHANGE_RESUME_2 _UxGT("pour reprendre") +#else // LCD_HEIGHT < 4 + // Up to 2 lines allowed + #define MSG_FILAMENT_CHANGE_INIT_1 _UxGT("Patientez...") + #define MSG_FILAMENT_CHANGE_UNLOAD_1 _UxGT("Ejection...") + #define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("Insérer et clic") + #define MSG_FILAMENT_CHANGE_LOAD_1 _UxGT("Chargement...") + #define MSG_FILAMENT_CHANGE_EXTRUDE_1 _UxGT("Extrusion...") + #define MSG_FILAMENT_CHANGE_RESUME_1 _UxGT("Reprise...") +#endif // LCD_HEIGHT < 4 + +#endif // LANGUAGE_FR_H diff --git a/trunk/Arduino/Marlin_1.1.6/language_gl.h b/trunk/Arduino/Marlin_1.1.6/language_gl.h new file mode 100644 index 00000000..4797297f --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/language_gl.h @@ -0,0 +1,252 @@ +/** + * 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 . + * + */ + +/** + * Galician language (ISO "gl") + * + * LCD Menu Messages + * See also http://marlinfw.org/docs/development/lcd_language.html + * + */ +#ifndef LANGUAGE_GL_H +#define LANGUAGE_GL_H + +#define MAPPER_C2C3 +#define DISPLAY_CHARSET_ISO10646_1 + +#define WELCOME_MSG MACHINE_NAME _UxGT(" lista.") +#define MSG_SD_INSERTED _UxGT("Tarxeta inserida") +#define MSG_SD_REMOVED _UxGT("Tarxeta retirada") +#define MSG_LCD_ENDSTOPS _UxGT("FinCarro") +#define MSG_MAIN _UxGT("Menu principal") +#define MSG_AUTOSTART _UxGT("Autoarranque") +#define MSG_DISABLE_STEPPERS _UxGT("Apagar motores") +#define MSG_AUTO_HOME _UxGT("Ir a orixe") +#define MSG_AUTO_HOME_X _UxGT("Ir orixe X") +#define MSG_AUTO_HOME_Y _UxGT("Ir orixe Y") +#define MSG_AUTO_HOME_Z _UxGT("Ir orixe Z") +#define MSG_LEVEL_BED_HOMING _UxGT("Ir orixes XYZ") +#define MSG_LEVEL_BED_WAITING _UxGT("Prema pulsador") +#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Seguinte punto") +#define MSG_LEVEL_BED_DONE _UxGT("Nivelado feito") +#define MSG_SET_HOME_OFFSETS _UxGT("Offsets na orixe") +#define MSG_HOME_OFFSETS_APPLIED _UxGT("Offsets fixados") +#define MSG_SET_ORIGIN _UxGT("Fixar orixe") +#define MSG_PREHEAT_1 _UxGT("Prequentar PLA") +#define MSG_PREHEAT_1_N _UxGT("Prequentar PLA ") +#define MSG_PREHEAT_1_ALL _UxGT("Preque. PLA Todo") +#define MSG_PREHEAT_1_BEDONLY _UxGT("Preque. PLA Cama") +#define MSG_PREHEAT_1_SETTINGS _UxGT("Preque. PLA conf") +#define MSG_PREHEAT_2 _UxGT("Prequentar ABS") +#define MSG_PREHEAT_2_N _UxGT("Prequentar ABS ") +#define MSG_PREHEAT_2_ALL _UxGT("Preque. ABS Todo") +#define MSG_PREHEAT_2_BEDONLY _UxGT("Preque. ABS Cama") +#define MSG_PREHEAT_2_SETTINGS _UxGT("Preque. ABS conf") +#define MSG_COOLDOWN _UxGT("Arrefriar") +#define MSG_SWITCH_PS_ON _UxGT("Acender") +#define MSG_SWITCH_PS_OFF _UxGT("Apagar") +#define MSG_EXTRUDE _UxGT("Extrudir") +#define MSG_RETRACT _UxGT("Retraer") +#define MSG_MOVE_AXIS _UxGT("Mover eixe") +#define MSG_BED_LEVELING _UxGT("Nivelar cama") +#define MSG_LEVEL_BED _UxGT("Nivelar cama") +#define MSG_MOVE_X _UxGT("Mover X") +#define MSG_MOVE_Y _UxGT("Mover Y") +#define MSG_MOVE_Z _UxGT("Mover Z") +#define MSG_MOVE_E _UxGT("Extrusor") +#define MSG_MOVE_01MM _UxGT("Mover 0.1mm") +#define MSG_MOVE_1MM _UxGT("Mover 1mm") +#define MSG_MOVE_10MM _UxGT("Mover 10mm") +#define MSG_SPEED _UxGT("Velocidade") +#define MSG_BED_Z _UxGT("Cama Z") +#define MSG_NOZZLE _UxGT("Bico") +#define MSG_BED _UxGT("Cama") +#define MSG_FAN_SPEED _UxGT("Velocidade vent.") +#define MSG_FLOW _UxGT("Fluxo") +#define MSG_CONTROL _UxGT("Control") +#define MSG_MIN _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" Min") +#define MSG_MAX _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" Max") +#define MSG_FACTOR _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" Fact") +#define MSG_AUTOTEMP _UxGT("Autotemp") +#define MSG_ON _UxGT("On ") +#define MSG_OFF _UxGT("Off") +#define MSG_PID_P _UxGT("PID-P") +#define MSG_PID_I _UxGT("PID-I") +#define MSG_PID_D _UxGT("PID-D") +#define MSG_PID_C _UxGT("PID-C") +#define MSG_SELECT _UxGT("Escolla") +#define MSG_ACC _UxGT("Acel") +#define MSG_JERK _UxGT("Jerk") +#define MSG_VX_JERK _UxGT("Vx-jerk") +#define MSG_VY_JERK _UxGT("Vy-jerk") +#define MSG_VZ_JERK _UxGT("Vz-jerk") +#define MSG_VE_JERK _UxGT("Ve-jerk") +#define MSG_VMAX _UxGT("Vmax ") +#define MSG_VMIN _UxGT("Vmin") +#define MSG_VTRAV_MIN _UxGT("VTrav min") +#define MSG_AMAX _UxGT("Amax ") +#define MSG_A_RETRACT _UxGT("A-retract") +#define MSG_A_TRAVEL _UxGT("A-travel") +#define MSG_STEPS_PER_MM _UxGT("Pasos/mm") +#define MSG_XSTEPS _UxGT("Xpasos/mm") +#define MSG_YSTEPS _UxGT("Ypasos/mm") +#define MSG_ZSTEPS _UxGT("Zpasos/mm") +#define MSG_ESTEPS _UxGT("Epasos/mm") +#define MSG_E1STEPS _UxGT("E1pasos/mm") +#define MSG_E2STEPS _UxGT("E2pasos/mm") +#define MSG_E3STEPS _UxGT("E3pasos/mm") +#define MSG_E4STEPS _UxGT("E4pasos/mm") +#define MSG_E5STEPS _UxGT("E5pasos/mm") +#define MSG_TEMPERATURE _UxGT("Temperatura") +#define MSG_MOTION _UxGT("Movemento") +#define MSG_FILAMENT _UxGT("Filamento") +#define MSG_VOLUMETRIC_ENABLED _UxGT("E en mm3") +#define MSG_FILAMENT_DIAM _UxGT("Diam. fil.") +#define MSG_CONTRAST _UxGT("Constraste LCD") +#define MSG_STORE_EEPROM _UxGT("Gardar en memo.") +#define MSG_LOAD_EEPROM _UxGT("Cargar de memo.") +#define MSG_RESTORE_FAILSAFE _UxGT("Cargar de firm.") +#define MSG_REFRESH _UxGT("Volver a cargar") +#define MSG_WATCH _UxGT("Monitorizacion") +#define MSG_PREPARE _UxGT("Preparar") +#define MSG_TUNE _UxGT("Axustar") +#define MSG_PAUSE_PRINT _UxGT("Pausar impres.") +#define MSG_RESUME_PRINT _UxGT("Seguir impres.") +#define MSG_STOP_PRINT _UxGT("Deter impres.") +#define MSG_CARD_MENU _UxGT("Tarxeta SD") +#define MSG_NO_CARD _UxGT("Sen tarxeta SD") +#define MSG_DWELL _UxGT("En repouso...") +#define MSG_USERWAIT _UxGT("A espera...") +#define MSG_RESUMING _UxGT("Imprimindo...") +#define MSG_PRINT_ABORTED _UxGT("Impre. cancelada") +#define MSG_NO_MOVE _UxGT("Sen movemento.") +#define MSG_KILLED _UxGT("PROGRAMA MORTO") +#define MSG_STOPPED _UxGT("PROGRAMA PARADO") +#define MSG_CONTROL_RETRACT _UxGT("Retraccion mm") +#define MSG_CONTROL_RETRACT_SWAP _UxGT("Cambio retra. mm") +#define MSG_CONTROL_RETRACTF _UxGT("Retraccion V") +#define MSG_CONTROL_RETRACT_ZLIFT _UxGT("Alzar Z mm") +#define MSG_CONTROL_RETRACT_RECOVER _UxGT("Recup. retra. mm") +#define MSG_CONTROL_RETRACT_RECOVER_SWAP _UxGT("Cambio recup. mm") +#define MSG_CONTROL_RETRACT_RECOVERF _UxGT("Recuperacion V") +#define MSG_AUTORETRACT _UxGT("Retraccion auto.") +#define MSG_FILAMENTCHANGE _UxGT("Cambiar filamen.") +#define MSG_INIT_SDCARD _UxGT("Iniciando SD") +#define MSG_CNG_SDCARD _UxGT("Cambiar SD") +#define MSG_ZPROBE_OUT _UxGT("Sonda-Z sen cama") +#define MSG_HOME _UxGT("Home") // Used as MSG_HOME " " MSG_X MSG_Y MSG_Z " " MSG_FIRST +#define MSG_BLTOUCH_SELFTEST _UxGT("Comprobar BLTouch") +#define MSG_BLTOUCH_RESET _UxGT("Iniciar BLTouch") +#define MSG_FIRST _UxGT("first") +#define MSG_ZPROBE_ZOFFSET _UxGT("Offset Z") +#define MSG_BABYSTEP_X _UxGT("Micropaso X") +#define MSG_BABYSTEP_Y _UxGT("Micropaso Y") +#define MSG_BABYSTEP_Z _UxGT("Micropaso Z") +#define MSG_ENDSTOP_ABORT _UxGT("Erro fin carro") +#define MSG_HEATING_FAILED_LCD _UxGT("Fallo quentando") +#define MSG_ERR_REDUNDANT_TEMP _UxGT("Erro temperatura") +#define MSG_THERMAL_RUNAWAY _UxGT("Temp. excesiva") +#define MSG_ERR_MAXTEMP _UxGT("Err: temp. max.") +#define MSG_ERR_MINTEMP _UxGT("Err: temp. min.") +#define MSG_ERR_MAXTEMP_BED _UxGT("Err: MAXTEMP BED") +#define MSG_ERR_MINTEMP_BED _UxGT("Err: MINTEMP BED") +#define MSG_ERR_Z_HOMING _UxGT("G28 Z impedido") +#define MSG_HALTED _UxGT("SISTEMA MORTO") +#define MSG_PLEASE_RESET _UxGT("Debe reiniciar!") +#define MSG_SHORT_DAY _UxGT("d") // One character only +#define MSG_SHORT_HOUR _UxGT("h") // One character only +#define MSG_SHORT_MINUTE _UxGT("m") // One character only +#define MSG_HEATING _UxGT("Quentando...") +#define MSG_HEATING_COMPLETE _UxGT("Xa esta quente") +#define MSG_BED_HEATING _UxGT("Quentando cama") +#define MSG_BED_DONE _UxGT("Cama esta quente") +#define MSG_DELTA_CALIBRATE _UxGT("Calibracion Delta") +#define MSG_DELTA_CALIBRATE_X _UxGT("Calibrar X") +#define MSG_DELTA_CALIBRATE_Y _UxGT("Calibrar Y") +#define MSG_DELTA_CALIBRATE_Z _UxGT("Calibrar Z") +#define MSG_DELTA_CALIBRATE_CENTER _UxGT("Calibrar Centro") +#define MSG_INFO_MENU _UxGT("Acerca de...") +#define MSG_INFO_PRINTER_MENU _UxGT("Informacion") +#define MSG_INFO_STATS_MENU _UxGT("Estadisticas") +#define MSG_INFO_BOARD_MENU _UxGT("Placa nai") +#define MSG_INFO_THERMISTOR_MENU _UxGT("Termistores") +#define MSG_INFO_EXTRUDERS _UxGT("Extrusores") +#define MSG_INFO_BAUDRATE _UxGT("Baudios") +#define MSG_INFO_PROTOCOL _UxGT("Protocolo") +#define MSG_CASE_LIGHT _UxGT("Luz") +#if LCD_WIDTH >= 20 + #define MSG_INFO_PRINT_COUNT _UxGT("Total traballos") + #define MSG_INFO_COMPLETED_PRINTS _UxGT("Total completos") + #define MSG_INFO_PRINT_TIME _UxGT("Tempo impresion") + #define MSG_INFO_PRINT_LONGEST _UxGT("Traballo +longo") + #define MSG_INFO_PRINT_FILAMENT _UxGT("Total extruido") +#else + #define MSG_INFO_PRINT_COUNT _UxGT("Traballos") + #define MSG_INFO_COMPLETED_PRINTS _UxGT("Completos") + #define MSG_INFO_PRINT_TIME _UxGT("Tempo") + #define MSG_INFO_PRINT_LONGEST _UxGT("O +longo") + #define MSG_INFO_PRINT_FILAMENT _UxGT("Extruido") +#endif +#define MSG_INFO_MIN_TEMP _UxGT("Min Temp") +#define MSG_INFO_MAX_TEMP _UxGT("Max Temp") +#define MSG_INFO_PSU _UxGT("Fonte alime.") +#define MSG_DRIVE_STRENGTH _UxGT("Potencia motor") +#define MSG_DAC_PERCENT _UxGT("Motor %") +#define MSG_DAC_EEPROM_WRITE _UxGT("Garda DAC EEPROM") + +#define MSG_FILAMENT_CHANGE_HEADER _UxGT("PRINT PAUSED") +#define MSG_FILAMENT_CHANGE_OPTION_HEADER _UxGT("RESUME OPTIONS:") +#define MSG_FILAMENT_CHANGE_OPTION_EXTRUDE _UxGT("Extruir mais") +#define MSG_FILAMENT_CHANGE_OPTION_RESUME _UxGT("Segue traballo") + +#if LCD_HEIGHT >= 4 + // Up to 3 lines allowed + #define MSG_FILAMENT_CHANGE_INIT_1 _UxGT("Agarde para") + #define MSG_FILAMENT_CHANGE_INIT_2 _UxGT("iniciar troco") + #define MSG_FILAMENT_CHANGE_INIT_3 _UxGT("de filamento") + #define MSG_FILAMENT_CHANGE_UNLOAD_1 _UxGT("Agarde pola") + #define MSG_FILAMENT_CHANGE_UNLOAD_2 _UxGT("descarga do") + #define MSG_FILAMENT_CHANGE_UNLOAD_3 _UxGT("filamento") + #define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("Introduza o") + #define MSG_FILAMENT_CHANGE_INSERT_2 _UxGT("filamento e") + #define MSG_FILAMENT_CHANGE_INSERT_3 _UxGT("faga click") + #define MSG_FILAMENT_CHANGE_LOAD_1 _UxGT("Agarde pola") + #define MSG_FILAMENT_CHANGE_LOAD_2 _UxGT("carga do") + #define MSG_FILAMENT_CHANGE_LOAD_3 _UxGT("filamento") + #define MSG_FILAMENT_CHANGE_EXTRUDE_1 _UxGT("Agarde pola") + #define MSG_FILAMENT_CHANGE_EXTRUDE_2 _UxGT("extrusion do") + #define MSG_FILAMENT_CHANGE_EXTRUDE_3 _UxGT("filamento") + #define MSG_FILAMENT_CHANGE_RESUME_1 _UxGT("Agarde para") + #define MSG_FILAMENT_CHANGE_RESUME_2 _UxGT("seguir co") + #define MSG_FILAMENT_CHANGE_RESUME_3 _UxGT("traballo") +#else // LCD_HEIGHT < 4 + // Up to 2 lines allowed + #define MSG_FILAMENT_CHANGE_INIT_1 _UxGT("Agarde...") + #define MSG_FILAMENT_CHANGE_UNLOAD_1 _UxGT("Descargando...") + #define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("Introduza e click") + #define MSG_FILAMENT_CHANGE_LOAD_1 _UxGT("Cargando...") + #define MSG_FILAMENT_CHANGE_EXTRUDE_1 _UxGT("Extruindo...") + #define MSG_FILAMENT_CHANGE_RESUME_1 _UxGT("Seguindo...") +#endif // LCD_HEIGHT < 4 + +#endif // LANGUAGE_GL_H + diff --git a/trunk/Arduino/Marlin_1.1.6/language_hr.h b/trunk/Arduino/Marlin_1.1.6/language_hr.h new file mode 100644 index 00000000..64de7492 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/language_hr.h @@ -0,0 +1,248 @@ +/** + * 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 . + * + */ + +/** + * Croatian (Hrvatski) + * + * LCD Menu Messages + * See also http://marlinfw.org/docs/development/lcd_language.html + * + */ +#ifndef LANGUAGE_HR_H +#define LANGUAGE_HR_H + +#define DISPLAY_CHARSET_ISO10646_1 // use the better font on full graphic displays. + +#define WELCOME_MSG MACHINE_NAME _UxGT(" spreman.") +#define MSG_SD_INSERTED _UxGT("SD kartica umetnuta") +#define MSG_SD_REMOVED _UxGT("SD kartica uklonjena") +#define MSG_LCD_ENDSTOPS _UxGT("Endstops") // Max length 8 characters +#define MSG_MAIN _UxGT("Main") +#define MSG_AUTOSTART _UxGT("Auto pokretanje") +#define MSG_DISABLE_STEPPERS _UxGT("Ugasi steppere") +#define MSG_AUTO_HOME _UxGT("Automatski homing") +#define MSG_AUTO_HOME_X _UxGT("Home-aj X") +#define MSG_AUTO_HOME_Y _UxGT("Home-aj Y") +#define MSG_AUTO_HOME_Z _UxGT("Home-aj Z") +#define MSG_LEVEL_BED_HOMING _UxGT("Home-aj XYZ") +#define MSG_LEVEL_BED_WAITING _UxGT("Klikni za početak") +#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Sljedeća točka") +#define MSG_LEVEL_BED_DONE _UxGT("Niveliranje gotovo!") +#define MSG_SET_HOME_OFFSETS _UxGT("Postavi home offsete") +#define MSG_HOME_OFFSETS_APPLIED _UxGT("Offsets postavljeni") +#define MSG_SET_ORIGIN _UxGT("Postavi ishodište") +#define MSG_PREHEAT_1 _UxGT("Predgrij PLA") +#define MSG_PREHEAT_1_N MSG_PREHEAT_1 _UxGT(" ") +#define MSG_PREHEAT_1_ALL MSG_PREHEAT_1 _UxGT(" Sve") +#define MSG_PREHEAT_1_BEDONLY MSG_PREHEAT_1 _UxGT(" Bed") +#define MSG_PREHEAT_1_SETTINGS MSG_PREHEAT_1 _UxGT(" conf") +#define MSG_PREHEAT_2 _UxGT("Predgrij ABS") +#define MSG_PREHEAT_2_N MSG_PREHEAT_2 _UxGT(" ") +#define MSG_PREHEAT_2_ALL MSG_PREHEAT_2 _UxGT(" Sve") +#define MSG_PREHEAT_2_BEDONLY MSG_PREHEAT_2 _UxGT(" Bed") +#define MSG_PREHEAT_2_SETTINGS MSG_PREHEAT_2 _UxGT(" conf") +#define MSG_COOLDOWN _UxGT("Hlađenje") +#define MSG_SWITCH_PS_ON _UxGT("Uključi napajanje") +#define MSG_SWITCH_PS_OFF _UxGT("Isključi napajanje") +#define MSG_EXTRUDE _UxGT("Extrude") +#define MSG_RETRACT _UxGT("Retract") +#define MSG_MOVE_AXIS _UxGT("Miči os") +#define MSG_BED_LEVELING _UxGT("Niveliraj bed") +#define MSG_LEVEL_BED _UxGT("Niveliraj bed") +#define MSG_MOVE_X _UxGT("Miči X") +#define MSG_MOVE_Y _UxGT("Miči Y") +#define MSG_MOVE_Z _UxGT("Miči Z") +#define MSG_MOVE_E _UxGT("Extruder") +#define MSG_MOVE_01MM _UxGT("Miči 0.1mm") +#define MSG_MOVE_1MM _UxGT("Miči 1mm") +#define MSG_MOVE_10MM _UxGT("Miči 10mm") +#define MSG_SPEED _UxGT("Brzina") +#define MSG_BED_Z _UxGT("Bed Z") +#define MSG_NOZZLE _UxGT("Dizna") +#define MSG_BED _UxGT("Bed") +#define MSG_FAN_SPEED _UxGT("Brzina ventilatora") +#define MSG_FLOW _UxGT("Flow") +#define MSG_CONTROL _UxGT("Control") +#define MSG_MIN _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" Min") +#define MSG_MAX _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" Max") +#define MSG_FACTOR _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" Fact") +#define MSG_AUTOTEMP _UxGT("Autotemp") +#define MSG_ON _UxGT("On ") +#define MSG_OFF _UxGT("Off") +#define MSG_PID_P _UxGT("PID-P") +#define MSG_PID_I _UxGT("PID-I") +#define MSG_PID_D _UxGT("PID-D") +#define MSG_PID_C _UxGT("PID-C") +#define MSG_SELECT _UxGT("Odaberi") +#define MSG_ACC _UxGT("Accel") +#define MSG_JERK _UxGT("Jerk") +#define MSG_VX_JERK _UxGT("Vx-jerk") +#define MSG_VY_JERK _UxGT("Vy-jerk") +#define MSG_VZ_JERK _UxGT("Vz-jerk") +#define MSG_VE_JERK _UxGT("Ve-jerk") +#define MSG_VMAX _UxGT("Vmax ") +#define MSG_VMIN _UxGT("Vmin") +#define MSG_VTRAV_MIN _UxGT("VTrav min") +#define MSG_AMAX _UxGT("Amax ") +#define MSG_A_RETRACT _UxGT("A-retract") +#define MSG_A_TRAVEL _UxGT("A-travel") +#define MSG_STEPS_PER_MM _UxGT("Steps/mm") +#define MSG_XSTEPS _UxGT("Xsteps/mm") +#define MSG_YSTEPS _UxGT("Ysteps/mm") +#define MSG_ZSTEPS _UxGT("Zsteps/mm") +#define MSG_ESTEPS _UxGT("Esteps/mm") +#define MSG_E1STEPS _UxGT("E1steps/mm") +#define MSG_E2STEPS _UxGT("E2steps/mm") +#define MSG_E3STEPS _UxGT("E3steps/mm") +#define MSG_E4STEPS _UxGT("E4steps/mm") +#define MSG_E5STEPS _UxGT("E5steps/mm") +#define MSG_TEMPERATURE _UxGT("Temperature") +#define MSG_MOTION _UxGT("Gibanje") +#define MSG_FILAMENT _UxGT("Filament") +#define MSG_VOLUMETRIC_ENABLED _UxGT("E in mm3") +#define MSG_FILAMENT_DIAM _UxGT("Fil. Dia.") +#define MSG_CONTRAST _UxGT("Kontrast LCD-a") +#define MSG_STORE_EEPROM _UxGT("Pohrani u memoriju") +#define MSG_LOAD_EEPROM _UxGT("Učitaj memoriju") +#define MSG_RESTORE_FAILSAFE _UxGT("Učitaj failsafe") +#define MSG_REFRESH _UxGT("Osvježi") +#define MSG_WATCH _UxGT("Info screen") +#define MSG_PREPARE _UxGT("Pripremi") +#define MSG_TUNE _UxGT("Tune") +#define MSG_PAUSE_PRINT _UxGT("Pauziraj print") +#define MSG_RESUME_PRINT _UxGT("Nastavi print") +#define MSG_STOP_PRINT _UxGT("Zaustavi print") +#define MSG_CARD_MENU _UxGT("Printaj s SD kartice") +#define MSG_NO_CARD _UxGT("Nema SD kartice") +#define MSG_DWELL _UxGT("Sleep...") +#define MSG_USERWAIT _UxGT("Čekaj korisnika...") +#define MSG_RESUMING _UxGT("Nastavljam print") +#define MSG_PRINT_ABORTED _UxGT("Print otkazan") +#define MSG_NO_MOVE _UxGT("No move.") +#define MSG_KILLED _UxGT("KILLED. ") +#define MSG_STOPPED _UxGT("ZAUSTAVLJEN. ") +#define MSG_CONTROL_RETRACT _UxGT("Retract mm") +#define MSG_CONTROL_RETRACT_SWAP _UxGT("Swap Re.mm") +#define MSG_CONTROL_RETRACTF _UxGT("Retract V") +#define MSG_CONTROL_RETRACT_ZLIFT _UxGT("Hop mm") +#define MSG_CONTROL_RETRACT_RECOVER _UxGT("UnRet mm") +#define MSG_CONTROL_RETRACT_RECOVER_SWAP _UxGT("S UnRet mm") +#define MSG_CONTROL_RETRACT_RECOVERF _UxGT("UnRet V") +#define MSG_AUTORETRACT _UxGT("AutoRetr.") +#define MSG_FILAMENTCHANGE _UxGT("Promijeni filament") +#define MSG_INIT_SDCARD _UxGT("Init. SD karticu") +#define MSG_CNG_SDCARD _UxGT("Promijeni SD karticu") +#define MSG_ZPROBE_OUT _UxGT("Z probe out. bed") +#define MSG_BLTOUCH_SELFTEST _UxGT("BLTouch Self-Test") +#define MSG_BLTOUCH_RESET _UxGT("Reset BLTouch") +#define MSG_HOME _UxGT("Home") // Used as MSG_HOME " " MSG_X MSG_Y MSG_Z " " MSG_FIRST +#define MSG_FIRST _UxGT("first") +#define MSG_ZPROBE_ZOFFSET _UxGT("Z Offset") +#define MSG_BABYSTEP_X _UxGT("Babystep X") +#define MSG_BABYSTEP_Y _UxGT("Babystep Y") +#define MSG_BABYSTEP_Z _UxGT("Babystep Z") +#define MSG_ENDSTOP_ABORT _UxGT("Endstop abort") +#define MSG_HEATING_FAILED_LCD _UxGT("Grijanje neuspješno") +#define MSG_ERR_REDUNDANT_TEMP _UxGT("Err: REDUNDANT TEMP") +#define MSG_THERMAL_RUNAWAY _UxGT("THERMAL RUNAWAY") +#define MSG_ERR_MAXTEMP _UxGT("Err: MAXTEMP") +#define MSG_ERR_MINTEMP _UxGT("Err: MINTEMP") +#define MSG_ERR_MAXTEMP_BED _UxGT("Err: MAXTEMP BED") +#define MSG_ERR_MINTEMP_BED _UxGT("Err: MINTEMP BED") +#define MSG_ERR_Z_HOMING _UxGT("G28 Z Forbidden") +#define MSG_HALTED _UxGT("PRINTER HALTED") +#define MSG_PLEASE_RESET _UxGT("Please reset") +#define MSG_SHORT_DAY _UxGT("d") // One character only +#define MSG_SHORT_HOUR _UxGT("h") // One character only +#define MSG_SHORT_MINUTE _UxGT("m") // One character only +#define MSG_HEATING _UxGT("Grijanje...") +#define MSG_HEATING_COMPLETE _UxGT("Grijanje gotovo.") +#define MSG_BED_HEATING _UxGT("Grijanje Bed-a.") +#define MSG_BED_DONE _UxGT("Bed gotov.") +#define MSG_DELTA_CALIBRATE _UxGT("Delta Kalibracija") +#define MSG_DELTA_CALIBRATE_X _UxGT("Kalibriraj X") +#define MSG_DELTA_CALIBRATE_Y _UxGT("Kalibriraj Y") +#define MSG_DELTA_CALIBRATE_Z _UxGT("Kalibriraj Z") +#define MSG_DELTA_CALIBRATE_CENTER _UxGT("Kalibriraj Središte") +#define MSG_INFO_MENU _UxGT("O printeru") +#define MSG_INFO_PRINTER_MENU _UxGT("Podaci o printeru") +#define MSG_INFO_STATS_MENU _UxGT("Statistika printera") +#define MSG_INFO_BOARD_MENU _UxGT("Podaci o elektronici") +#define MSG_INFO_THERMISTOR_MENU _UxGT("Termistori") +#define MSG_INFO_EXTRUDERS _UxGT("Extruderi") +#define MSG_INFO_BAUDRATE _UxGT("Baud") +#define MSG_INFO_PROTOCOL _UxGT("Protokol") +#define MSG_CASE_LIGHT _UxGT("Osvjetljenje") + +#if LCD_WIDTH >= 20 + #define MSG_INFO_PRINT_COUNT _UxGT("Broj printova") + #define MSG_INFO_COMPLETED_PRINTS _UxGT("Završeni") + #define MSG_INFO_PRINT_TIME _UxGT("Ukupno printanja") + #define MSG_INFO_PRINT_LONGEST _UxGT("Najduži print") + #define MSG_INFO_PRINT_FILAMENT _UxGT("Extrudirano ukupno") +#else + #define MSG_INFO_PRINT_COUNT _UxGT("Printovi") + #define MSG_INFO_COMPLETED_PRINTS _UxGT("Završeni") + #define MSG_INFO_PRINT_TIME _UxGT("Ukupno") + #define MSG_INFO_PRINT_LONGEST _UxGT("Najduži") + #define MSG_INFO_PRINT_FILAMENT _UxGT("Extrudirano") +#endif + +#define MSG_INFO_MIN_TEMP _UxGT("Min Temp") +#define MSG_INFO_MAX_TEMP _UxGT("Max Temp") +#define MSG_INFO_PSU _UxGT("Napajanje") +#define MSG_DRIVE_STRENGTH _UxGT("Drive Strength") +#define MSG_DAC_PERCENT _UxGT("Driver %") +#define MSG_DAC_EEPROM_WRITE _UxGT("DAC EEPROM Write") + +#define MSG_FILAMENT_CHANGE_HEADER _UxGT("PRINT PAUSED") +#define MSG_FILAMENT_CHANGE_OPTION_HEADER _UxGT("RESUME OPTIONS:") +#define MSG_FILAMENT_CHANGE_OPTION_EXTRUDE _UxGT("Extrudiraj više") +#define MSG_FILAMENT_CHANGE_OPTION_RESUME _UxGT("Nastavi print") + +#if LCD_HEIGHT >= 4 + // Up to 3 lines allowed + #define MSG_FILAMENT_CHANGE_INIT_1 _UxGT("Čekaj početak") + #define MSG_FILAMENT_CHANGE_INIT_2 _UxGT("filamenta") + #define MSG_FILAMENT_CHANGE_INIT_3 _UxGT("promijeni") + #define MSG_FILAMENT_CHANGE_UNLOAD_1 _UxGT("Čekaj") + #define MSG_FILAMENT_CHANGE_UNLOAD_2 _UxGT("filament unload") + #define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("Umetni filament") + #define MSG_FILAMENT_CHANGE_INSERT_2 _UxGT("i pritisni tipku") + #define MSG_FILAMENT_CHANGE_INSERT_3 _UxGT("za nastavak...") + #define MSG_FILAMENT_CHANGE_LOAD_1 _UxGT("Pričekaj") + #define MSG_FILAMENT_CHANGE_LOAD_2 _UxGT("filament load") + #define MSG_FILAMENT_CHANGE_EXTRUDE_1 _UxGT("Pričekaj") + #define MSG_FILAMENT_CHANGE_EXTRUDE_2 _UxGT("filament extrude") + #define MSG_FILAMENT_CHANGE_RESUME_1 _UxGT("Wait for print") + #define MSG_FILAMENT_CHANGE_RESUME_2 _UxGT("to resume") +#else // LCD_HEIGHT < 4 + // Up to 2 lines allowed + #define MSG_FILAMENT_CHANGE_INIT_1 _UxGT("Pričekaj...") + #define MSG_FILAMENT_CHANGE_UNLOAD_1 _UxGT("Ejecting...") + #define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("Insert and Click") + #define MSG_FILAMENT_CHANGE_LOAD_1 _UxGT("Loading...") + #define MSG_FILAMENT_CHANGE_EXTRUDE_1 _UxGT("Extrudiranje...") + #define MSG_FILAMENT_CHANGE_RESUME_1 _UxGT("Nastavljam...") +#endif // LCD_HEIGHT < 4 + +#endif // LANGUAGE_HR_H diff --git a/trunk/Arduino/Marlin_1.1.6/language_it.h b/trunk/Arduino/Marlin_1.1.6/language_it.h new file mode 100644 index 00000000..fae438ce --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/language_it.h @@ -0,0 +1,346 @@ +/** + * 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 . + * + */ + +/** + * Italian + * + * LCD Menu Messages + * See also http://marlinfw.org/docs/development/lcd_language.html + * + */ +#ifndef LANGUAGE_IT_H +#define LANGUAGE_IT_H + +#define MAPPER_C2C3 +#define DISPLAY_CHARSET_ISO10646_1 + +#define WELCOME_MSG MACHINE_NAME _UxGT(" pronto.") +#define MSG_BACK _UxGT("Indietro") +#define MSG_SD_INSERTED _UxGT("SD Card inserita") +#define MSG_SD_REMOVED _UxGT("SD Card rimossa") +#define MSG_LCD_ENDSTOPS _UxGT("Endstop") +#define MSG_MAIN _UxGT("Menu principale") +#define MSG_AUTOSTART _UxGT("Autostart") +#define MSG_DISABLE_STEPPERS _UxGT("Disabilita Motori") +#define MSG_DEBUG_MENU _UxGT("Menu di debug") +#define MSG_PROGRESS_BAR_TEST _UxGT("Test barra avanzamento") +#define MSG_AUTO_HOME _UxGT("Auto Home") +#define MSG_AUTO_HOME_X _UxGT("Home asse X") +#define MSG_AUTO_HOME_Y _UxGT("Home asse Y") +#define MSG_AUTO_HOME_Z _UxGT("Home asse Z") +#define MSG_LEVEL_BED_HOMING _UxGT("Home assi XYZ") +#define MSG_LEVEL_BED_WAITING _UxGT("Premi per iniziare") +#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Punto successivo") +#define MSG_LEVEL_BED_DONE _UxGT("Livel. terminato!") +#define MSG_Z_FADE_HEIGHT _UxGT("Fade Height") +#define MSG_SET_HOME_OFFSETS _UxGT("Imp. offset home") +#define MSG_HOME_OFFSETS_APPLIED _UxGT("Offset applicato") +#define MSG_SET_ORIGIN _UxGT("Imposta Origine") +#define MSG_PREHEAT_1 _UxGT("Preriscalda PLA") +#define MSG_PREHEAT_1_N _UxGT("Prerisc.PLA ") +#define MSG_PREHEAT_1_ALL MSG_PREHEAT_1_N _UxGT("Tutto") +#define MSG_PREHEAT_1_END MSG_PREHEAT_1_N _UxGT("Ugello") +#define MSG_PREHEAT_1_BEDONLY MSG_PREHEAT_1_N _UxGT("Piatto") +#define MSG_PREHEAT_1_SETTINGS MSG_PREHEAT_1_N _UxGT("conf") +#define MSG_PREHEAT_2 _UxGT("Preriscalda ABS") +#define MSG_PREHEAT_2_N _UxGT("Prerisc.ABS ") +#define MSG_PREHEAT_2_ALL MSG_PREHEAT_2_N _UxGT("Tutto") +#define MSG_PREHEAT_2_END MSG_PREHEAT_2_N _UxGT("Ugello") +#define MSG_PREHEAT_2_BEDONLY MSG_PREHEAT_2_N _UxGT("Piatto") +#define MSG_PREHEAT_2_SETTINGS MSG_PREHEAT_2_N _UxGT("conf") +#define MSG_COOLDOWN _UxGT("Raffredda") +#define MSG_SWITCH_PS_ON _UxGT("Accendi aliment.") +#define MSG_SWITCH_PS_OFF _UxGT("Spegni aliment.") +#define MSG_EXTRUDE _UxGT("Estrudi") +#define MSG_RETRACT _UxGT("Ritrai") +#define MSG_MOVE_AXIS _UxGT("Muovi Asse") +#define MSG_BED_LEVELING _UxGT("Livella piano") +#define MSG_LEVEL_BED _UxGT("Livella piano") +#define MSG_EDITING_STOPPED _UxGT("Modifica Mesh Fermata") +#define MSG_USER_MENU _UxGT("Comandi Utente") + +#define MSG_UBL_DOING_G29 _UxGT("G29 in corso") +#define MSG_UBL_UNHOMED _UxGT("Home XYZ prima") +#define MSG_UBL_TOOLS _UxGT("Strumenti UBL") +#define MSG_UBL_LEVEL_BED _UxGT("Unified Bed Leveling") +#define MSG_UBL_MANUAL_MESH _UxGT("Mesh Manuale") +#define MSG_UBL_BC_INSERT _UxGT("Metti spessore & misura") +#define MSG_UBL_BC_INSERT2 _UxGT("Misura") +#define MSG_UBL_BC_REMOVE _UxGT("Rimuovi & misura piatto") +#define MSG_UBL_MOVING_TO_NEXT _UxGT("Spostamento sucessivo") +#define MSG_UBL_ACTIVATE_MESH _UxGT("Attiva UBL") +#define MSG_UBL_DEACTIVATE_MESH _UxGT("Disattiva UBL") +#define MSG_UBL_SET_BED_TEMP _UxGT("Temp Piatto") +#define MSG_UBL_CUSTOM_BED_TEMP MSG_UBL_SET_BED_TEMP +#define MSG_UBL_SET_HOTEND_TEMP _UxGT("Temp Ugello") +#define MSG_UBL_CUSTOM_HOTEND_TEMP MSG_UBL_SET_HOTEND_TEMP +#define MSG_UBL_EDIT_CUSTOM_MESH _UxGT("Modif Custom Mesh") +#define MSG_UBL_FINE_TUNE_MESH _UxGT("Ritocca Mesh") +#define MSG_UBL_DONE_EDITING_MESH _UxGT("Done Editing Mesh") +#define MSG_UBL_BUILD_CUSTOM_MESH _UxGT("Crea Custom Mesh") +#define MSG_UBL_BUILD_MESH_MENU _UxGT("Crea Mesh") +#define MSG_UBL_BUILD_PLA_MESH _UxGT("Crea PLA Mesh") +#define MSG_UBL_BUILD_ABS_MESH _UxGT("Crea ABS Mesh") +#define MSG_UBL_BUILD_COLD_MESH _UxGT("Crea Cold Mesh") +#define MSG_UBL_MESH_HEIGHT_ADJUST _UxGT("Aggiusta Altezza Mesh") +#define MSG_UBL_MESH_HEIGHT_AMOUNT _UxGT("Altezza") +#define MSG_UBL_VALIDATE_MESH_MENU _UxGT("Valida Mesh") +#define MSG_UBL_VALIDATE_PLA_MESH _UxGT("Valida PLA Mesh") +#define MSG_UBL_VALIDATE_ABS_MESH _UxGT("Valida ABS Mesh") +#define MSG_UBL_VALIDATE_CUSTOM_MESH _UxGT("Valida Custom Mesh") +#define MSG_UBL_CONTINUE_MESH _UxGT("Continua Mesh") +#define MSG_UBL_MESH_LEVELING _UxGT("Livell. Mesh") +#define MSG_UBL_3POINT_MESH_LEVELING _UxGT("Livell. 3 Punti") +#define MSG_UBL_GRID_MESH_LEVELING _UxGT("Livell. Griglia Mesh") +#define MSG_UBL_MESH_LEVEL _UxGT("Livella Mesh") +#define MSG_UBL_SIDE_POINTS _UxGT("Punti laterali") +#define MSG_UBL_MAP_TYPE _UxGT("Tipo di Mappa") +#define MSG_UBL_OUTPUT_MAP _UxGT("Esporta Mappa") +#define MSG_UBL_OUTPUT_MAP_HOST _UxGT("Esporta per Host") +#define MSG_UBL_OUTPUT_MAP_CSV _UxGT("Esporta in CSV") +#define MSG_UBL_OUTPUT_MAP_BACKUP _UxGT("Backup esterno") +#define MSG_UBL_INFO_UBL _UxGT("Esporta Info UBL") +#define MSG_UBL_EDIT_MESH_MENU _UxGT("Modifica Mesh") +#define MSG_UBL_FILLIN_AMOUNT _UxGT("Riempimento") +#define MSG_UBL_MANUAL_FILLIN _UxGT("Riempimento Manuale") +#define MSG_UBL_SMART_FILLIN _UxGT("Riempimento Smart") +#define MSG_UBL_FILLIN_MESH _UxGT("Riempimento Mesh") +#define MSG_UBL_INVALIDATE_ALL _UxGT("Invalida Tutto") +#define MSG_UBL_INVALIDATE_CLOSEST _UxGT("Invalida Punto Vicino") +#define MSG_UBL_FINE_TUNE_ALL _UxGT("Ritocca All") +#define MSG_UBL_FINE_TUNE_CLOSEST _UxGT("Ritocca Punto Vicino") +#define MSG_UBL_STORAGE_MESH_MENU _UxGT("Mesh Salvate") +#define MSG_UBL_STORAGE_SLOT _UxGT("Slot di memoria") +#define MSG_UBL_LOAD_MESH _UxGT("Carica Mesh Piatto") +#define MSG_UBL_SAVE_MESH _UxGT("Salva Mesh Piatto") +#define MSG_UBL_SAVE_ERROR _UxGT("Err: Salvataggio UBL") +#define MSG_UBL_RESTORE_ERROR _UxGT("Err: Ripristino UBL") +#define MSG_UBL_Z_OFFSET_STOPPED _UxGT("Z-Offset Fermato") +#define MSG_UBL_STEP_BY_STEP_MENU _UxGT("UBL passo passo") + +#define MSG_MOVING _UxGT("In movimento...") +#define MSG_FREE_XY _UxGT("XY liberi") +#define MSG_MOVE_X _UxGT("Muovi X") +#define MSG_MOVE_Y _UxGT("Muovi Y") +#define MSG_MOVE_Z _UxGT("Muovi Z") +#define MSG_MOVE_E _UxGT("Estrusore") +#define MSG_MOVE_01MM _UxGT("Muovi di 0.1mm") +#define MSG_MOVE_1MM _UxGT("Muovi di 1mm") +#define MSG_MOVE_10MM _UxGT("Muovi di 10mm") +#define MSG_SPEED _UxGT("Velocità") +#define MSG_BED_Z _UxGT("piatto Z") +#define MSG_NOZZLE _UxGT("Ugello") +#define MSG_BED _UxGT("Piatto") +#define MSG_FAN_SPEED _UxGT("Velocità ventola") +#define MSG_FLOW _UxGT("Flusso") +#define MSG_CONTROL _UxGT("Controllo") +#define MSG_MIN LCD_STR_THERMOMETER _UxGT(" Min") +#define MSG_MAX LCD_STR_THERMOMETER _UxGT(" Max") +#define MSG_FACTOR LCD_STR_THERMOMETER _UxGT(" Fact") +#define MSG_AUTOTEMP _UxGT("Autotemp") +#define MSG_ON _UxGT("On ") +#define MSG_OFF _UxGT("Off") +#define MSG_PID_P _UxGT("PID-P") +#define MSG_PID_I _UxGT("PID-I") +#define MSG_PID_D _UxGT("PID-D") +#define MSG_PID_C _UxGT("PID-C") +#define MSG_SELECT _UxGT("Seleziona") +#define MSG_ACC _UxGT("Accel") +#define MSG_JERK _UxGT("Jerk") +#define MSG_VX_JERK _UxGT("Vx-jerk") +#define MSG_VY_JERK _UxGT("Vy-jerk") +#define MSG_VZ_JERK _UxGT("Vz-jerk") +#define MSG_VE_JERK _UxGT("Ve-jerk") +#define MSG_VELOCITY _UxGT("Velocità") +#define MSG_VMAX _UxGT("Vmax ") +#define MSG_VMIN _UxGT("Vmin") +#define MSG_VTRAV_MIN _UxGT("VTrav min") +#define MSG_ACCELERATION _UxGT("Accelerazione") +#define MSG_AMAX _UxGT("Amax ") +#define MSG_A_RETRACT _UxGT("A-retract") +#define MSG_A_TRAVEL _UxGT("A-Spostamento") +#define MSG_STEPS_PER_MM _UxGT("Passi/mm") +#define MSG_XSTEPS _UxGT("Xpassi/mm") +#define MSG_YSTEPS _UxGT("Ypassi/mm") +#define MSG_ZSTEPS _UxGT("Zpassi/mm") +#define MSG_ESTEPS _UxGT("Epassi/mm") +#define MSG_E1STEPS _UxGT("E1passi/mm") +#define MSG_E2STEPS _UxGT("E2passi/mm") +#define MSG_E3STEPS _UxGT("E3passi/mm") +#define MSG_E4STEPS _UxGT("E4passi/mm") +#define MSG_E5STEPS _UxGT("E5passi/mm") +#define MSG_TEMPERATURE _UxGT("Temperatura") +#define MSG_MOTION _UxGT("Movimento") +#define MSG_FILAMENT _UxGT("Filamento") +#define MSG_VOLUMETRIC_ENABLED _UxGT("E in mm3") +#define MSG_FILAMENT_DIAM _UxGT("Diam. filo") +#define MSG_ADVANCE_K _UxGT("K Avanzamento") +#define MSG_CONTRAST _UxGT("Contrasto LCD") +#define MSG_STORE_EEPROM _UxGT("Salva in memoria") +#define MSG_LOAD_EEPROM _UxGT("Carica da memoria") +#define MSG_RESTORE_FAILSAFE _UxGT("Ripristina imp.") +#define MSG_INIT_EEPROM _UxGT("Inizializza EEPROM") +#define MSG_REFRESH _UxGT("Aggiorna") +#define MSG_WATCH _UxGT("Guarda") +#define MSG_PREPARE _UxGT("Prepara") +#define MSG_TUNE _UxGT("Regola") +#define MSG_PAUSE_PRINT _UxGT("Pausa") +#define MSG_RESUME_PRINT _UxGT("Riprendi stampa") +#define MSG_STOP_PRINT _UxGT("Arresta stampa") +#define MSG_CARD_MENU _UxGT("Stampa da SD") +#define MSG_NO_CARD _UxGT("SD non presente") +#define MSG_DWELL _UxGT("Sospensione...") +#define MSG_USERWAIT _UxGT("Premi tasto..") +#define MSG_PRINT_PAUSED _UxGT("Stampa sospesa") +#define MSG_RESUMING _UxGT("Riprendi Stampa") +#define MSG_PRINT_ABORTED _UxGT("Stampa annullata") +#define MSG_NO_MOVE _UxGT("Nessun Movimento") +#define MSG_KILLED _UxGT("UCCISO. ") +#define MSG_STOPPED _UxGT("ARRESTATO. ") +#define MSG_CONTROL_RETRACT _UxGT("Ritrai mm") +#define MSG_CONTROL_RETRACT_SWAP _UxGT("Scamb. Ritrai mm") +#define MSG_CONTROL_RETRACTF _UxGT("Ritrai V") +#define MSG_CONTROL_RETRACT_ZLIFT _UxGT("Salta mm") +#define MSG_CONTROL_RETRACT_RECOVER _UxGT("UnRet mm") +#define MSG_CONTROL_RETRACT_RECOVER_SWAP _UxGT("Scamb. UnRet mm") +#define MSG_CONTROL_RETRACT_RECOVERF _UxGT("UnRet V") +#define MSG_AUTORETRACT _UxGT("AutoRitrai") +#define MSG_FILAMENTCHANGE _UxGT("Cambia filamento") +#define MSG_INIT_SDCARD _UxGT("Iniz. SD-Card") +#define MSG_CNG_SDCARD _UxGT("Cambia SD-Card") +#define MSG_ZPROBE_OUT _UxGT("Z probe out. bed") +#define MSG_BLTOUCH _UxGT("BLTouch") +#define MSG_BLTOUCH_SELFTEST _UxGT("Autotest BLTouch") +#define MSG_BLTOUCH_RESET _UxGT("Resetta BLTouch") +#define MSG_BLTOUCH_DEPLOY _UxGT("Estendi BLTouch") +#define MSG_BLTOUCH_STOW _UxGT("Ritrai BLTouch") +#define MSG_HOME _UxGT("Home") // Used as MSG_HOME " " MSG_X MSG_Y MSG_Z " " MSG_FIRST +#define MSG_FIRST _UxGT("prima") +#define MSG_ZPROBE_ZOFFSET _UxGT("Z Offset") +#define MSG_BABYSTEP_X _UxGT("Babystep X") +#define MSG_BABYSTEP_Y _UxGT("Babystep Y") +#define MSG_BABYSTEP_Z _UxGT("Babystep Z") +#define MSG_ENDSTOP_ABORT _UxGT("Finecorsa abort") +#define MSG_HEATING_FAILED_LCD _UxGT("Riscald. Fallito") +#define MSG_ERR_REDUNDANT_TEMP _UxGT("Err: TEMP RIDONDANTI") +#define MSG_THERMAL_RUNAWAY _UxGT("TEMP FUORI CONTROLLO") +#define MSG_ERR_MAXTEMP _UxGT("Err: TEMP MASSIMA") +#define MSG_ERR_MINTEMP _UxGT("Err: TEMP MINIMA") +#define MSG_ERR_MAXTEMP_BED _UxGT("Err: TEMP MASSIMA PIATTO") +#define MSG_ERR_MINTEMP_BED _UxGT("Err: TEMP MINIMA PIATTO") +#define MSG_ERR_Z_HOMING _UxGT("G28 Z Vietato") +#define MSG_HALTED _UxGT("STAMPANTE FERMATA") +#define MSG_PLEASE_RESET _UxGT("Riavviare prego") +#define MSG_SHORT_DAY _UxGT("g") // One character only +#define MSG_SHORT_HOUR _UxGT("h") // One character only +#define MSG_SHORT_MINUTE _UxGT("m") // One character only +#define MSG_HEATING _UxGT("Riscaldamento..") +#define MSG_HEATING_COMPLETE _UxGT("Risc. completato") +#define MSG_BED_HEATING _UxGT("Risc. Piatto..") +#define MSG_BED_DONE _UxGT("Piatto Pronto") +#define MSG_DELTA_CALIBRATE _UxGT("Calibraz. Delta") +#define MSG_DELTA_CALIBRATE_X _UxGT("Calibra X") +#define MSG_DELTA_CALIBRATE_Y _UxGT("Calibra Y") +#define MSG_DELTA_CALIBRATE_Z _UxGT("Calibra Z") +#define MSG_DELTA_CALIBRATE_CENTER _UxGT("Calibra Center") +#define MSG_DELTA_AUTO_CALIBRATE _UxGT("Auto calibrazione") +#define MSG_DELTA_HEIGHT_CALIBRATE _UxGT("Imp. altezza Delta") +#define MSG_INFO_MENU _UxGT("Riguardo stampante") +#define MSG_INFO_PRINTER_MENU _UxGT("Info. stampante") +#define MSG_3POINT_LEVELING _UxGT("Livel. a 3 punti") +#define MSG_LINEAR_LEVELING _UxGT("Livel. Lineare") +#define MSG_BILINEAR_LEVELING _UxGT("Livel. Biliniare") +#define MSG_UBL_LEVELING _UxGT("Livel. UBL") +#define MSG_MESH_LEVELING _UxGT("Livel. Mesh") +#define MSG_INFO_STATS_MENU _UxGT("Statistiche") +#define MSG_INFO_BOARD_MENU _UxGT("Info. scheda") +#define MSG_INFO_THERMISTOR_MENU _UxGT("Termistori") +#define MSG_INFO_EXTRUDERS _UxGT("Estrusori") +#define MSG_INFO_BAUDRATE _UxGT("Baud") +#define MSG_INFO_PROTOCOL _UxGT("Protocollo") +#define MSG_CASE_LIGHT _UxGT("Luci Case") +#define MSG_CASE_LIGHT_BRIGHTNESS _UxGT("Luminosità Luci") + +#if LCD_WIDTH >= 20 + #define MSG_INFO_PRINT_COUNT _UxGT("Contat. stampa") + #define MSG_INFO_COMPLETED_PRINTS _UxGT("Completati") + #define MSG_INFO_PRINT_TIME _UxGT("Tempo totale") + #define MSG_INFO_PRINT_LONGEST _UxGT("Lavoro più lungo") + #define MSG_INFO_PRINT_FILAMENT _UxGT("Totale estruso") +#else + #define MSG_INFO_PRINT_COUNT _UxGT("Stampe") + #define MSG_INFO_COMPLETED_PRINTS _UxGT("Completati") + #define MSG_INFO_PRINT_TIME _UxGT("Durata") + #define MSG_INFO_PRINT_LONGEST _UxGT("Più lungo") + #define MSG_INFO_PRINT_FILAMENT _UxGT("Estruso") +#endif +#define MSG_INFO_MIN_TEMP _UxGT("Temp min") +#define MSG_INFO_MAX_TEMP _UxGT("Temp max") +#define MSG_INFO_PSU _UxGT("Alimentatore") + +#define MSG_DRIVE_STRENGTH _UxGT("Potenza Drive") +#define MSG_DAC_PERCENT _UxGT("Driver %") +#define MSG_DAC_EEPROM_WRITE _UxGT("Scrivi DAC EEPROM") + +#define MSG_FILAMENT_CHANGE_HEADER _UxGT("STAMPA IN PAUSA") +#define MSG_FILAMENT_CHANGE_OPTION_HEADER _UxGT("OPZIONI:") +#define MSG_FILAMENT_CHANGE_OPTION_EXTRUDE _UxGT("Estrudi ancora") +#define MSG_FILAMENT_CHANGE_OPTION_RESUME _UxGT("Riprendi stampa") +#define MSG_FILAMENT_CHANGE_MINTEMP _UxGT("Temp minima è ") +#define MSG_FILAMENT_CHANGE_NOZZLE _UxGT(" Ugello: ") + +#if LCD_HEIGHT >= 4 + // Up to 3 lines allowed + #define MSG_FILAMENT_CHANGE_INIT_1 _UxGT("Attendere avvio") + #define MSG_FILAMENT_CHANGE_INIT_2 _UxGT("del cambio") + #define MSG_FILAMENT_CHANGE_INIT_3 _UxGT("di filamento") + #define MSG_FILAMENT_CHANGE_UNLOAD_1 _UxGT("Attendere") + #define MSG_FILAMENT_CHANGE_UNLOAD_2 _UxGT("l'espulsione") + #define MSG_FILAMENT_CHANGE_UNLOAD_3 _UxGT("del filamento") + #define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("Inserisci il") + #define MSG_FILAMENT_CHANGE_INSERT_2 _UxGT("filamento e") + #define MSG_FILAMENT_CHANGE_INSERT_3 _UxGT("premi per cont") + #define MSG_FILAMENT_CHANGE_HEAT_1 _UxGT("Premi per") + #define MSG_FILAMENT_CHANGE_HEAT_2 _UxGT("riscald ugello.") + #define MSG_FILAMENT_CHANGE_HEATING_1 _UxGT("Riscald. ugello") + #define MSG_FILAMENT_CHANGE_HEATING_2 _UxGT("Attendere...") + #define MSG_FILAMENT_CHANGE_LOAD_1 _UxGT("Attendere") + #define MSG_FILAMENT_CHANGE_LOAD_2 _UxGT("il caricamento") + #define MSG_FILAMENT_CHANGE_LOAD_3 _UxGT("del filamento") + #define MSG_FILAMENT_CHANGE_EXTRUDE_1 _UxGT("Attendere") + #define MSG_FILAMENT_CHANGE_EXTRUDE_2 _UxGT("l'estrusione") + #define MSG_FILAMENT_CHANGE_EXTRUDE_3 _UxGT("del filamento") + #define MSG_FILAMENT_CHANGE_RESUME_1 _UxGT("Attendere") + #define MSG_FILAMENT_CHANGE_RESUME_2 _UxGT("la ripresa") + #define MSG_FILAMENT_CHANGE_RESUME_3 _UxGT("della stampa") +#else // LCD_HEIGHT < 4 + // Up to 2 lines allowed + #define MSG_FILAMENT_CHANGE_INIT_1 _UxGT("Attendere...") + #define MSG_FILAMENT_CHANGE_UNLOAD_1 _UxGT("Espulsione...") + #define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("Inserisci e premi") + #define MSG_FILAMENT_CHANGE_HEATING_1 _UxGT("Riscaldamento...") + #define MSG_FILAMENT_CHANGE_LOAD_1 _UxGT("Caricamento...") + #define MSG_FILAMENT_CHANGE_EXTRUDE_1 _UxGT("Estrusione...") + #define MSG_FILAMENT_CHANGE_RESUME_1 _UxGT("Ripresa...") +#endif // LCD_HEIGHT < 4 + +#endif // LANGUAGE_IT_H diff --git a/trunk/Arduino/Marlin_1.1.6/language_kana.h b/trunk/Arduino/Marlin_1.1.6/language_kana.h new file mode 100644 index 00000000..200aed4e --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/language_kana.h @@ -0,0 +1,322 @@ +/** + * 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 . + * + */ + +/** + * Japanese (Kana) + * + * LCD Menu Messages + * See also http://marlinfw.org/docs/development/lcd_language.html + * + */ + +#ifndef LANGUAGE_KANA_H +#define LANGUAGE_KANA_H + +// Define SIMULATE_ROMFONT to see what is seen on the character based display defined in Configuration.h +#define SIMULATE_ROMFONT +#define DISPLAY_CHARSET_ISO10646_KANA + +// 片仮名表示定義 +#define WELCOME_MSG MACHINE_NAME " ready." +#define MSG_SD_INSERTED "\xb6\xb0\xc4\xde\xb6\xde\xbf\xb3\xc6\xad\xb3\xbb\xda\xcf\xbc\xc0" // "カードガソウニュウサレマシタ" ("Card inserted") +#define MSG_SD_REMOVED "\xb6\xb0\xc4\xde\xb6\xde\xb1\xd8\xcf\xbe\xdd" // "カードガアリマセン" ("Card removed") +#define MSG_LCD_ENDSTOPS "Endstops" // Max length 8 characters +#define MSG_MAIN "\xd2\xb2\xdd" // "メイン" ("Main") +#define MSG_AUTOSTART "\xbc\xde\xc4\xde\xb3\xb6\xb2\xbc" // "ジドウカイシ" ("Autostart") +#define MSG_DISABLE_STEPPERS "\xd3\xb0\xc0\xb0\xc3\xde\xdd\xb9\xde\xdd\x20\xb5\xcc" // "モーターデンゲン オフ" ("Disable steppers") +#define MSG_DEBUG_MENU "\xc3\xde\xca\xde\xaf\xb8\xde\xd2\xc6\xad\xb0" // "デバッグメニュー" ("Debug Menu") +#define MSG_PROGRESS_BAR_TEST "\xcc\xdf\xdb\xb8\xde\xda\xbd\xca\xde\xb0\x20\xc3\xbd\xc4" // "プログレスバー テスト" ("Progress Bar Test") +#define MSG_AUTO_HOME "\xb9\xde\xdd\xc3\xdd\xcc\xaf\xb7" // "ゲンテンフッキ" ("Auto home") +#define MSG_AUTO_HOME_X "X\xbc\xde\xb8\x20\xb9\xde\xdd\xc3\xdd\xcc\xaf\xb7" // "Xジク ゲンテンフッキ" ("Home X") +#define MSG_AUTO_HOME_Y "Y\xbc\xde\xb8\x20\xb9\xde\xdd\xc3\xdd\xcc\xaf\xb7" // "Yジク ゲンテンフッキ" ("Home Y") +#define MSG_AUTO_HOME_Z "Z\xbc\xde\xb8\x20\xb9\xde\xdd\xc3\xdd\xcc\xaf\xb7" // "Zジク ゲンテンフッキ" ("Home Z") +#define MSG_LEVEL_BED_HOMING "\xb9\xde\xdd\xc3\xdd\xcc\xaf\xb7\xc1\xad\xb3" // "ゲンテンフッキチュウ" ("Homing XYZ") +#define MSG_LEVEL_BED_WAITING "\xda\xcd\xde\xd8\xdd\xb8\xde\xb6\xb2\xbc" // "レベリングカイシ" ("Click to Begin") +#define MSG_LEVEL_BED_NEXT_POINT "\xc2\xb7\xde\xc9\xbf\xb8\xc3\xb2\xc3\xdd\xcd" // "ツギノソクテイテンヘ" ("Next Point") +#define MSG_LEVEL_BED_DONE "\xda\xcd\xde\xd8\xdd\xb8\xde\xb6\xdd\xd8\xae\xb3" // "レベリングカンリョウ" ("Leveling Done!") +#define MSG_SET_HOME_OFFSETS "\xb7\xbc\xde\xad\xdd\xb5\xcc\xbe\xaf\xc4\xbe\xaf\xc3\xb2" // "キジュンオフセットセッテイ" ("Set home offsets") +#define MSG_HOME_OFFSETS_APPLIED "\xb5\xcc\xbe\xaf\xc4\xb6\xde\xc3\xb7\xd6\xb3\xbb\xda\xcf\xbc\xc0" // "オフセットガテキヨウサレマシタ" ("Offsets applied") +#define MSG_SET_ORIGIN "\xb7\xbc\xde\xad\xdd\xbe\xaf\xc4" // "キジュンセット" ("Set origin") +#define MSG_PREHEAT_1 "PLA \xd6\xc8\xc2" // "PLA ヨネツ" ("Preheat PLA") +#define MSG_PREHEAT_1_N MSG_PREHEAT_1 " " +#define MSG_PREHEAT_1_ALL "PLA \xbd\xcd\xde\xc3\xd6\xc8\xc2" // "PLA スベテヨネツ" (" All") +#define MSG_PREHEAT_1_BEDONLY "PLA \xcd\xde\xaf\xc4\xde\xd6\xc8\xc2" // "PLA ベッドヨネツ" (" Bed") +#define MSG_PREHEAT_1_SETTINGS MSG_PREHEAT_1 "\xbe\xaf\xc3\xb2" // "セッテイ" (" conf") +#define MSG_PREHEAT_2 "ABS \xd6\xc8\xc2" // "ABS ヨネツ" ("Preheat ABS") +#define MSG_PREHEAT_2_N MSG_PREHEAT_2 " " +#define MSG_PREHEAT_2_ALL "ABS \xbd\xcd\xde\xc3\xd6\xc8\xc2" // "ABS スベテヨネツ" (" All") +#define MSG_PREHEAT_2_BEDONLY "ABS \xcd\xde\xaf\xc4\xde\xd6\xc8\xc2" // "ABS ベッドヨネツ" (" Bed") +#define MSG_PREHEAT_2_SETTINGS MSG_PREHEAT_2 "\xbe\xaf\xc3\xb2" // "セッテイ" (" conf") +#define MSG_COOLDOWN "\xb6\xc8\xc2\xc3\xb2\xbc" // "カネツテイシ" ("Cooldown") +#define MSG_SWITCH_PS_ON "\xc3\xde\xdd\xb9\xde\xdd\x20\xb5\xdd" // "デンゲン オン" ("Switch power on") +#define MSG_SWITCH_PS_OFF "\xc3\xde\xdd\xb9\xde\xdd\x20\xb5\xcc" // "デンゲン オフ" ("Switch power off") +#define MSG_EXTRUDE "\xb5\xbc\xc0\xde\xbc" // "オシダシ" ("Extrude") +#define MSG_RETRACT "\xcb\xb7\xba\xd0\xbe\xaf\xc3\xb2" // "ヒキコミセッテイ" ("Retract") +#define MSG_MOVE_AXIS "\xbc\xde\xb8\xb2\xc4\xde\xb3" // "ジクイドウ" ("Move axis") +#define MSG_BED_LEVELING "\xcd\xde\xaf\xc4\xde\xda\xcd\xde\xd8\xdd\xb8\xde" // "ベッドレベリング" ("Bed Leveling") +#define MSG_LEVEL_BED "\xcd\xde\xaf\xc4\xde\xda\xcd\xde\xd8\xdd\xb8\xde" // "ベッドレベリング" ("Level bed") +#define MSG_MOVING "\xb2\xc4\xde\xb3\xc1\xad\xb3" // "イドウチュウ" ("Moving...") +#define MSG_FREE_XY "XY\xbc\xde\xb8\x20\xb6\xb2\xce\xb3" // "XYジク カイホウ" ("Free XY") +#define MSG_MOVE_X "X\xbc\xde\xb8\x20\xb2\xc4\xde\xb3" // "Xジク イドウ" ("Move X") +#define MSG_MOVE_Y "Y\xbc\xde\xb8\x20\xb2\xc4\xde\xb3" // "Yジク イドウ" ("Move Y") +#define MSG_MOVE_Z "Z\xbc\xde\xb8\x20\xb2\xc4\xde\xb3" // "Zジク イドウ" ("Move Z") +#define MSG_MOVE_E "\xb4\xb8\xbd\xc4\xd9\xb0\xc0\xde\xb0" // "エクストルーダー" ("Extruder") +#define MSG_MOVE_01MM "0.1mm \xb2\xc4\xde\xb3" // "0.1mm イドウ" ("Move 0.1mm") +#define MSG_MOVE_1MM " 1mm \xb2\xc4\xde\xb3" // " 1mm イドウ" ("Move 1mm") +#define MSG_MOVE_10MM " 10mm \xb2\xc4\xde\xb3" // " 10mm イドウ" ("Move 10mm") +#define MSG_SPEED "\xbf\xb8\xc4\xde" // "ソクド" ("Speed") +#define MSG_BED_Z "Z\xb5\xcc\xbe\xaf\xc4" // "Zオフセット" ("Bed Z") +#define MSG_NOZZLE "\xc9\xbd\xde\xd9" // "ノズル" ("Nozzle") +#define MSG_BED "\xcd\xde\xaf\xc4\xde" // "ベッド" ("Bed") +#define MSG_FAN_SPEED "\xcc\xa7\xdd\xbf\xb8\xc4\xde" // "ファンソクド" ("Fan speed") +#define MSG_FLOW "\xc4\xbc\xad\xc2\xd8\xae\xb3" // "トシュツリョウ" ("Flow") +#define MSG_CONTROL "\xbe\xb2\xb7\xde\xae" // "セイギョ" ("Control") +#define MSG_MIN LCD_STR_THERMOMETER " \xbb\xb2\xc3\xb2" // " サイテイ" (" Min") +#define MSG_MAX LCD_STR_THERMOMETER " \xbb\xb2\xba\xb3" // " サイコウ" (" Max") +#define MSG_FACTOR LCD_STR_THERMOMETER " \xcc\xa7\xb8\xc0\xb0" // " ファクター" (" Fact") +#if LCD_WIDTH >= 20 + #define MSG_AUTOTEMP "\xbc\xde\xc4\xde\xb3\xb5\xdd\xc4\xde\xbe\xb2\xb7\xde\xae" // "ジドウオンドセイギョ" ("Autotemp") +#else + #define MSG_AUTOTEMP "\xbc\xde\xc4\xde\xb3\xb5\xdd\xc4\xde" // "ジドウオンド" ("Autotemp") +#endif +#define MSG_ON "\xb5\xdd " // "オン " ("On ") +#define MSG_OFF "\xb5\xcc " // "オフ " ("Off") +#define MSG_PID_P "PID-P" +#define MSG_PID_I "PID-I" +#define MSG_PID_D "PID-D" +#define MSG_PID_C "PID-C" +#define MSG_SELECT "\xbe\xdd\xc0\xb8" // "センタク" ("Select") +#if LCD_WIDTH >= 20 + #define MSG_ACC "\xb6\xbf\xb8\xc4\xde mm/s2" // "カソクド mm/s2" ("Accel") + #define MSG_VX_JERK "X\xbc\xde\xb8\x20\xd4\xb8\xc4\xde mm/s" // "Xジク ヤクド mm/s" ("Vx-jerk") + #define MSG_VY_JERK "Y\xbc\xde\xb8\x20\xd4\xb8\xc4\xde mm/s" // "Yジク ヤクド mm/s" ("Vy-jerk") + #define MSG_VZ_JERK "Z\xbc\xde\xb8\x20\xd4\xb8\xc4\xde mm/s" // "Zジク ヤクド mm/s" ("Vz-jerk") + #define MSG_VE_JERK "\xb4\xb8\xbd\xc4\xd9\xb0\xc0\xde\xb0\x20\xd4\xb8\xc4\xde" // "エクストルーダー ヤクド" ("Ve-jerk") + #define MSG_VMAX "\xbb\xb2\xc0\xde\xb2\xb5\xb8\xd8\xbf\xb8\xc4\xde " // "サイダイオクリソクド " ("Vmax ") + #define MSG_VMIN "\xbb\xb2\xbc\xae\xb3\xb5\xb8\xd8\xbf\xb8\xc4\xde" // "サイショウオクリソクド" ("Vmin") + #define MSG_VTRAV_MIN "\xbb\xb2\xbc\xae\xb3\xb2\xc4\xde\xb3\xbf\xb8\xc4\xde" // "サイショウイドウソクド" ("VTrav min") + #define MSG_AMAX "\xbb\xb2\xc0\xde\xb2\xb6\xbf\xb8\xc4\xde " // "サイダイカソクド " ("Amax ") +#else + #define MSG_ACC "\xb6\xbf\xb8\xc4\xde" // "カソクド" ("Accel") + #define MSG_VX_JERK "X\xbc\xde\xb8\x20\xd4\xb8\xc4\xde" // "XYジク ヤクド" ("Vx-jerk") + #define MSG_VY_JERK "Y\xbc\xde\xb8\x20\xd4\xb8\xc4\xde" // "XYジク ヤクド" ("Vy-jerk") + #define MSG_VZ_JERK "Z\xbc\xde\xb8\x20\xd4\xb8\xc4\xde" // "Zジク ヤクド" ("Vz-jerk") + #define MSG_VE_JERK "E\x20\xd4\xb8\xc4\xde" // "E ヤクド" ("Ve-jerk") + #define MSG_VMAX "max\xb5\xb8\xd8\xbf\xb8\xc4\xde " // "maxオクリソクド" ("Vmax ") + #define MSG_VMIN "min\xb5\xb8\xd8\xbf\xb8\xc4\xde" // "minオクリソクド" ("Vmin") + #define MSG_VTRAV_MIN "min\xb2\xc4\xde\xb3\xbf\xb8\xc4\xde" // "minイドウソクド" ("VTrav min") + #define MSG_AMAX "max\xb6\xbf\xb8 " // "maxカソク " ("Amax ") +#endif +#define MSG_A_RETRACT "\xcb\xb7\xba\xd0\xb6\xbf\xb8\xc4\xde" // "ヒキコミカソクド" ("A-retract") +#define MSG_A_TRAVEL "\xb2\xc4\xde\xb3\xb6\xbf\xb8\xc4\xde" // "イドウカソクド" ("A-travel") +#if LCD_WIDTH >= 20 + #define MSG_STEPS_PER_MM "Steps/mm" + #define MSG_XSTEPS "Xsteps/mm" + #define MSG_YSTEPS "Ysteps/mm" + #define MSG_ZSTEPS "Zsteps/mm" + #define MSG_ESTEPS "Esteps/mm" + #define MSG_E1STEPS "E1steps/mm" + #define MSG_E2STEPS "E2steps/mm" + #define MSG_E3STEPS "E3steps/mm" + #define MSG_E4STEPS "E4steps/mm" + #define MSG_E5STEPS "E5steps/mm" +#else + #define MSG_STEPS_PER_MM "Steps" + #define MSG_XSTEPS "Xsteps" + #define MSG_YSTEPS "Ysteps" + #define MSG_ZSTEPS "Zsteps" + #define MSG_ESTEPS "Esteps" + #define MSG_E1STEPS "E1steps" + #define MSG_E2STEPS "E2steps" + #define MSG_E3STEPS "E3steps" + #define MSG_E4STEPS "E4steps" + #define MSG_E5STEPS "E5steps" +#endif +#define MSG_TEMPERATURE "\xb5\xdd\xc4\xde" // "オンド" ("Temperature") +#define MSG_MOTION "\xb3\xba\xde\xb7\xbe\xaf\xc3\xb2" // "ウゴキセッテイ" ("Motion") +#define MSG_FILAMENT "\xcc\xa8\xd7\xd2\xdd\xc4" // "フィラメント" ("Filament") +#define MSG_VOLUMETRIC_ENABLED "E in mm3" +#if LCD_WIDTH >= 20 + #define MSG_FILAMENT_DIAM "\xcc\xa8\xd7\xd2\xdd\xc4\xc1\xae\xaf\xb9\xb2" // "フィラメントチョッケイ" ("Fil. Dia.") +#else + #define MSG_FILAMENT_DIAM "\xcc\xa8\xd7\xd2\xdd\xc4\xb9\xb2" // "フィラメントケイ" ("Fil. Dia.") +#endif +#define MSG_CONTRAST "LCD\xba\xdd\xc4\xd7\xbd\xc4" // "LCDコントラスト" ("LCD contrast") +#define MSG_STORE_EEPROM "\xd2\xd3\xd8\xcd\xb6\xb8\xc9\xb3" // "メモリヘカクノウ" ("Store memory") +#define MSG_LOAD_EEPROM "\xd2\xd3\xd8\xb6\xd7\xd6\xd0\xba\xd0" // "メモリカラヨミコミ" ("Load memory") +#define MSG_RESTORE_FAILSAFE "\xbe\xaf\xc3\xb2\xd8\xbe\xaf\xc4" // "セッテイリセット" ("Restore failsafe") +#define MSG_REFRESH "\xd8\xcc\xda\xaf\xbc\xad" // "リフレッシュ" ("Refresh") +#define MSG_WATCH "\xbc\xde\xae\xb3\xce\xb3\xb6\xde\xd2\xdd" // "ジョウホウガメン" ("Info screen") +#define MSG_PREPARE "\xbc\xde\xad\xdd\xcb\xde\xbe\xaf\xc3\xb2" // "ジュンビセッテイ" ("Prepare") +#define MSG_TUNE "\xc1\xae\xb3\xbe\xb2" // "チョウセイ" ("Tune") +#define MSG_PAUSE_PRINT "\xb2\xc1\xbc\xde\xc3\xb2\xbc" // "イチジテイシ" ("Pause print") +#define MSG_RESUME_PRINT "\xcc\xdf\xd8\xdd\xc4\xbb\xb2\xb6\xb2" // "プリントサイカイ" ("Resume print") +#define MSG_STOP_PRINT "\xcc\xdf\xd8\xdd\xc4\xc3\xb2\xbc" // "プリントテイシ" ("Stop print") +#define MSG_CARD_MENU "SD\xb6\xb0\xc4\xde\xb6\xd7\xcc\xdf\xd8\xdd\xc4" // "SDカードカラプリント" ("Print from SD") +#define MSG_NO_CARD "SD\xb6\xb0\xc4\xde\xb6\xde\xb1\xd8\xcf\xbe\xdd" // "SDカードガアリマセン" ("No SD card") +#define MSG_DWELL "\xb7\xad\xb3\xbc" // "キュウシ" ("Sleep...") +#define MSG_USERWAIT "\xbc\xca\xde\xd7\xb8\xb5\xcf\xc1\xb8\xc0\xde\xbb\xb2" // "シバラクオマチクダサイ" ("Wait for user...") +#define MSG_RESUMING "\xcc\xdf\xd8\xdd\xc4\xbb\xb2\xb6\xb2" // "プリントサイカイ" ("Resuming print") +#define MSG_PRINT_ABORTED "\xcc\xdf\xd8\xdd\xc4\xb6\xde\xc1\xad\xb3\xbc\xbb\xda\xcf\xbc\xc0" // "プリントガチュウシサレマシタ" ("Print aborted") +#define MSG_NO_MOVE "\xb3\xba\xde\xb7\xcf\xbe\xdd" // "ウゴキマセン" ("No move.") +#define MSG_KILLED "\xcb\xbc\xde\xae\xb3\xc3\xb2\xbc" // "ヒジョウテイシ" ("KILLED. ") +#define MSG_STOPPED "\xc3\xb2\xbc\xbc\xcf\xbc\xc0" // "テイシシマシタ" ("STOPPED. ") +#if LCD_WIDTH >= 20 + #define MSG_CONTROL_RETRACT "\xcb\xb7\xba\xd0\xd8\xae\xb3 mm" // "ヒキコミリョウ mm" ("Retract mm") + #define MSG_CONTROL_RETRACT_SWAP "\xcb\xb7\xba\xd0\xd8\xae\xb3S mm" // "ヒキコミリョウS mm" ("Swap Re.mm") + #define MSG_CONTROL_RETRACTF "\xcb\xb7\xba\xd0\xbf\xb8\xc4\xde mm/s" // "ヒキコミソクド mm/s" ("Retract V") + #define MSG_CONTROL_RETRACT_ZLIFT "\xc9\xbd\xde\xd9\xc0\xb2\xcb mm" // "ノズルタイヒ mm" ("Hop mm") + #define MSG_CONTROL_RETRACT_RECOVER "\xce\xbc\xae\xb3\xd8\xae\xb3 mm" // "ホショウリョウ mm" ("UnRet mm") + #define MSG_CONTROL_RETRACT_RECOVER_SWAP "\xce\xbc\xae\xb3\xd8\xae\xb3S mm" // "ホショウリョウS mm" ("S UnRet mm") + #define MSG_CONTROL_RETRACT_RECOVERF "\xce\xbc\xae\xb3\xbf\xb8\xc4\xde mm/s" // "ホショウソクド mm/s" ("UnRet V") +#else + #define MSG_CONTROL_RETRACT "\xcb\xb7\xba\xd0\xd8\xae\xb3" // "ヒキコミリョウ" ("Retract mm") + #define MSG_CONTROL_RETRACT_SWAP "\xcb\xb7\xba\xd0\xd8\xae\xb3S" // "ヒキコミリョウS" ("Swap Re.mm") + #define MSG_CONTROL_RETRACTF "\xcb\xb7\xba\xd0\xbf\xb8\xc4\xde" // "ヒキコミソクド" ("Retract V") + #define MSG_CONTROL_RETRACT_ZLIFT "\xc9\xbd\xde\xd9\xc0\xb2\xcb" // "ノズルタイヒ" ("Hop mm") + #define MSG_CONTROL_RETRACT_RECOVER "\xce\xbc\xae\xb3\xd8\xae\xb3" // "ホショウリョウ" ("UnRet mm") + #define MSG_CONTROL_RETRACT_RECOVER_SWAP "\xce\xbc\xae\xb3\xd8\xae\xb3S" // "ホショウリョウS" ("S UnRet mm") + #define MSG_CONTROL_RETRACT_RECOVERF "\xce\xbc\xae\xb3\xbf\xb8\xc4\xde" // "ホショウソクド" ("UnRet V") +#endif +#define MSG_AUTORETRACT "\xbc\xde\xc4\xde\xb3\xcb\xb7\xba\xd0" // "ジドウヒキコミ" ("AutoRetr.") +#define MSG_FILAMENTCHANGE "\xcc\xa8\xd7\xd2\xdd\xc4\xba\xb3\xb6\xdd" // "フィラメントコウカン" ("Change filament") +#define MSG_INIT_SDCARD "SD\xb6\xb0\xc4\xde\xbb\xb2\xd6\xd0\xba\xd0" // "SDカードサイヨミコミ" ("Init. SD card") +#define MSG_CNG_SDCARD "SD\xb6\xb0\xc4\xde\xba\xb3\xb6\xdd" // "SDカードコウカン" ("Change SD card") +#define MSG_ZPROBE_OUT "Z\xcc\xdf\xdb\xb0\xcc\xde\x20\xcd\xde\xaf\xc4\xde\xb6\xde\xb2" // "Zプローブ ベッドガイ" ("Z probe out. bed") +#if LCD_WIDTH >= 20 + #define MSG_BLTOUCH_SELFTEST "BLTouch \xbc\xde\xba\xbc\xdd\xc0\xde\xdd" // "BLTouch ジコシンダン" ("BLTouch Self-Test") +#else + #define MSG_BLTOUCH_SELFTEST "BLTouch \xbe\xd9\xcc\xc3\xbd\xc4" // "BLTouch セルフテスト" ("BLTouch Self-Test") +#endif +#define MSG_BLTOUCH_RESET "BLTouch \xd8\xbe\xaf\xc4" // "BLTouch リセット" ("Reset BLTouch") +#define MSG_HOME "\xbb\xb7\xc6" // "サキニ" ("Home") // Used as MSG_HOME " " MSG_X MSG_Y MSG_Z " " MSG_FIRST +#if LCD_WIDTH >= 20 + #define MSG_FIRST "\xa6\xcc\xaf\xb7\xbb\xbe\xc3\xb8\xc0\xde\xbb\xb2" // "ヲフッキサセテクダサイ" ("first") +#else + #define MSG_FIRST "\xa6\xcc\xaf\xb7\xbb\xbe\xd6" // "ヲフッキサセヨ" ("first") +#endif +#define MSG_ZPROBE_ZOFFSET "Z\xb5\xcc\xbe\xaf\xc4" // "Zオフセット" ("Z Offset") +#define MSG_BABYSTEP_X "X\xbc\xde\xb8\x20\xcb\xde\xc4\xde\xb3" // "Xジク ビドウ" ("Babystep X") +#define MSG_BABYSTEP_Y "Y\xbc\xde\xb8\x20\xcb\xde\xc4\xde\xb3" // "Yジク ビドウ" ("Babystep Y") +#define MSG_BABYSTEP_Z "Z\xbc\xde\xb8\x20\xcb\xde\xc4\xde\xb3" // "Zジク ビドウ" ("Babystep Z") +#if LCD_WIDTH >= 20 + #define MSG_ENDSTOP_ABORT "\xb2\xc4\xde\xb3\xb9\xde\xdd\xb6\xb2\xb9\xdd\xc1\xb7\xc9\xb3" // "イドウゲンカイケンチキノウ" ("Endstop abort") +#else + #define MSG_ENDSTOP_ABORT "\xb2\xc4\xde\xb3\xb9\xde\xdd\xb6\xb2\xb9\xdd\xc1" // "イドウゲンカイケンチ" ("Endstop abort") +#endif +#define MSG_HEATING_FAILED_LCD "\xb6\xc8\xc2\xbc\xaf\xca\xdf\xb2" // "カネツシッパイ" ("Heating failed") +#if LCD_WIDTH >= 20 + #define MSG_ERR_REDUNDANT_TEMP "\xb4\xd7\xb0:\xbc\xde\xae\xb3\xc1\xae\xb3\xbb\xb0\xd0\xbd\xc0\xb0\xb7\xc9\xb3" // "エラー:ジョウチョウサーミスターキノウ" ("Err: REDUNDANT TEMP") +#else + #define MSG_ERR_REDUNDANT_TEMP "\xb4\xd7\xb0:\xbc\xde\xae\xb3\xc1\xae\xb3\xbb\xb0\xd0\xbd\xc0" // "エラー:ジョウチョウサーミスタ" ("Err: REDUNDANT TEMP") +#endif +#define MSG_THERMAL_RUNAWAY "\xc8\xc2\xce\xde\xb3\xbf\xb3" // "ネツボウソウ" ("THERMAL RUNAWAY") +#define MSG_ERR_MAXTEMP "\xb4\xd7\xb0:\xbb\xb2\xba\xb3\xb5\xdd\xc1\xae\xb3\xb6" // "エラー:サイコウオンチョウカ" ("Err: MAXTEMP") +#define MSG_ERR_MINTEMP "\xb4\xd7\xb0:\xbb\xb2\xc3\xb2\xb5\xdd\xd0\xcf\xdd" // "エラー:サイテイオンミマン" ("Err: MINTEMP") +#if LCD_WIDTH >= 20 + #define MSG_ERR_MAXTEMP_BED "\xb4\xd7\xb0:\xcd\xde\xaf\xc4\xde\x20\xbb\xb2\xba\xb3\xb5\xdd\xc1\xae\xb3\xb6" // "エラー:ベッド サイコウオンチョウカ" ("Err: MAXTEMP BED") + #define MSG_ERR_MINTEMP_BED "\xb4\xd7\xb0:\xcd\xde\xaf\xc4\xde\x20\xbb\xb2\xc3\xb2\xb5\xdd\xd0\xcf\xdd" // "エラー:ベッド サイテイオンミマン" ("Err: MINTEMP BED") +#else + #define MSG_ERR_MAXTEMP_BED "\xb4\xd7\xb0:\xcd\xde\xaf\xc4\xde\x20\xbb\xb2\xba\xb3\xb5\xdd" // "エラー:ベッド サイコウオン" ("Err: MAXTEMP BED") + #define MSG_ERR_MINTEMP_BED "\xb4\xd7\xb0:\xcd\xde\xaf\xc4\xde\x20\xbb\xb2\xc3\xb2\xb5\xdd" // "エラー:ベッド サイテイオン" ("Err: MINTEMP BED") +#endif +#define MSG_ERR_Z_HOMING MSG_HOME " " MSG_X MSG_Y " " MSG_FIRST // "サキニ XY ヲフッキサセテクダサイ" or "サキニ XY ヲフッキサセヨ" ("G28 Z Forbidden") +#define MSG_HALTED "\xcc\xdf\xd8\xdd\xc0\xb0\xca\xc3\xb2\xbc\xbc\xcf\xbc\xc0" // "プリンターハテイシシマシタ" ("PRINTER HALTED") +#define MSG_PLEASE_RESET "\xd8\xbe\xaf\xc4\xbc\xc3\xb8\xc0\xde\xbb\xb2" // "リセットシテクダサイ" ("Please reset") +#define MSG_SHORT_DAY "d" // One character only +#define MSG_SHORT_HOUR "h" // One character only +#define MSG_SHORT_MINUTE "m" // One character only +#define MSG_HEATING "\xb6\xc8\xc2\xc1\xad\xb3" // "カネツチュウ" ("Heating...") +#define MSG_HEATING_COMPLETE "\xb6\xc8\xc2\xb6\xdd\xd8\xae\xb3" // "カネツカンリョウ" ("Heating done.") +#define MSG_BED_HEATING "\xcd\xde\xaf\xc4\xde\x20\xb6\xc8\xc2\xc1\xad\xb3" // "ベッド カネツチュウ" ("Bed Heating.") +#define MSG_BED_DONE "\xcd\xde\xaf\xc4\xde\x20\xb6\xc8\xc2\xb6\xdd\xd8\xae\xb3" // "ベッド カネツカンリョウ" ("Bed done.") +#define MSG_DELTA_CALIBRATE "\xc3\xde\xd9\xc0\x20\xba\xb3\xbe\xb2" // "デルタ コウセイ" ("Delta Calibration") +#define MSG_DELTA_CALIBRATE_X "X\xbc\xde\xb8\x20\xba\xb3\xbe\xb2" // "Xジク コウセイ" ("Calibrate X") +#define MSG_DELTA_CALIBRATE_Y "Y\xbc\xde\xb8\x20\xba\xb3\xbe\xb2" // "Yジク コウセイ" ("Calibrate Y") +#define MSG_DELTA_CALIBRATE_Z "Z\xbc\xde\xb8\x20\xba\xb3\xbe\xb2" // "Zジク コウセイ" ("Calibrate Z") +#define MSG_DELTA_CALIBRATE_CENTER "\xc1\xad\xb3\xbc\xdd\x20\xba\xb3\xbe\xb2" // "チュウシン コウセイ" ("Calibrate Center") +#define MSG_INFO_MENU "\xba\xc9\xcc\xdf\xd8\xdd\xc0\xb0\xc6\xc2\xb2\xc3" // "コノプリンターニツイテ" ("About Printer") +#define MSG_INFO_PRINTER_MENU "\xcc\xdf\xd8\xdd\xc0\xb0\xbc\xde\xae\xb3\xce\xb3" // "プリンタージョウホウ" ("Printer Info") +#define MSG_INFO_STATS_MENU "\xcc\xdf\xd8\xdd\xc4\xbc\xde\xae\xb3\xb7\xae\xb3" // "プリントジョウキョウ" ("Printer Stats") +#define MSG_INFO_BOARD_MENU "\xbe\xb2\xb7\xde\xae\xb9\xb2\xbc\xde\xae\xb3\xce\xb3" // "セイギョケイジョウホウ" ("Board Info") +#define MSG_INFO_THERMISTOR_MENU "\xbb\xb0\xd0\xbd\xc0\xb0" // "サーミスター" ("Thermistors") +#define MSG_INFO_EXTRUDERS "\xb4\xb8\xbd\xc4\xd9\xb0\xc0\xde\xb0\xbd\xb3" // "エクストルーダースウ" ("Extruders") +#define MSG_INFO_BAUDRATE "\xce\xde\xb0\xda\xb0\xc4" // "ボーレート" ("Baud") +#define MSG_INFO_PROTOCOL "\xcc\xdf\xdb\xc4\xba\xd9" // "プロトコル" ("Protocol") +#define MSG_CASE_LIGHT "\xb7\xae\xb3\xc0\xb2\xc5\xb2\xbc\xae\xb3\xd2\xb2" // "キョウタイナイショウメイ" ("Case light") +#define MSG_INFO_PRINT_COUNT "\xcc\xdf\xd8\xdd\xc4\xbd\xb3" // "プリントスウ" ("Print Count") +#define MSG_INFO_COMPLETED_PRINTS "\xb6\xdd\xd8\xae\xb3\xbd\xb3" // "カンリョウスウ" ("Completed") +#define MSG_INFO_PRINT_TIME "\xcc\xdf\xd8\xdd\xc4\xbc\xde\xb6\xdd\xd9\xb2\xb9\xb2" // "プリントジカンルイケイ" ("Total print time") +#define MSG_INFO_PRINT_LONGEST "\xbb\xb2\xc1\xae\xb3\xcc\xdf\xd8\xdd\xc4\xbc\xde\xb6\xdd" // "サイチョウプリントジカン" ("Longest job time") +#if LCD_WIDTH >= 20 + #define MSG_INFO_PRINT_FILAMENT "\xcc\xa8\xd7\xd2\xdd\xc4\xbc\xd6\xb3\xd8\xae\xb3\xd9\xb2\xb9\xb2" // "フィラメントシヨウリョウルイケイ" ("Extruded total") +#else + #define MSG_INFO_PRINT_FILAMENT "\xcc\xa8\xd7\xd2\xdd\xc4\xbf\xb3\xbc\xd6\xb3\xd8\xae\xb3" // "フィラメントソウシヨウリョウ" ("Extruded") +#endif +#define MSG_INFO_MIN_TEMP "\xbe\xaf\xc3\xb2\xbb\xb2\xc3\xb2\xb5\xdd" // "セッテイサイテイオン" ("Min Temp") +#define MSG_INFO_MAX_TEMP "\xbe\xaf\xc3\xb2\xbb\xb2\xba\xb3\xb5\xdd" // "セッテイサイコウオン" ("Max Temp") +#if LCD_WIDTH >= 20 + #define MSG_INFO_PSU "\xc3\xde\xdd\xb9\xde\xdd\xbc\xad\xcd\xde\xc2" // "デンゲンシュベツ" ("Power Supply") +#else + #define MSG_INFO_PSU "\xc3\xde\xdd\xb9\xde\xdd" // "デンゲン" ("Power Supply") +#endif +#define MSG_DRIVE_STRENGTH "\xd3\xb0\xc0\xb0\xb8\xc4\xde\xb3\xd8\xae\xb8" // "モータークドウリョク" ("Drive Strength") +#if LCD_WIDTH >= 20 + #define MSG_DAC_PERCENT "DAC\xbc\xad\xc2\xd8\xae\xb8 %" // "DACシュツリョク %" ("Driver %") +#else + #define MSG_DAC_PERCENT "DAC\xbc\xad\xc2\xd8\xae\xb8" // "DACシュツリョク" ("Driver %") +#endif +#define MSG_DAC_EEPROM_WRITE MSG_STORE_EPROM // "メモリヘカクノウ" ("DAC EEPROM Write") +#define MSG_FILAMENT_CHANGE_HEADER "PRINT PAUSED" +#define MSG_FILAMENT_CHANGE_OPTION_HEADER "RESUME OPTIONS:" +#define MSG_FILAMENT_CHANGE_OPTION_EXTRUDE "\xbb\xd7\xc6\xb5\xbc\xc0\xde\xbd" // "サラニオシダス" ("Extrude more") +#define MSG_FILAMENT_CHANGE_OPTION_RESUME "\xcc\xdf\xd8\xdd\xc4\xbb\xb2\xb6\xb2" // "プリントサイカイ" ("Resume print") + +#if LCD_HEIGHT >= 4 + // Up to 3 lines allowed + #define MSG_FILAMENT_CHANGE_INIT_1 "\xba\xb3\xb6\xdd\xa6\xb6\xb2\xbc\xbc\xcf\xbd" // "コウカンヲカイシシマス" ("Wait for start") + #define MSG_FILAMENT_CHANGE_INIT_2 "\xbc\xca\xde\xd7\xb8\xb5\xcf\xc1\xb8\xc0\xde\xbb\xb2" // "シバラクオマチクダサイ" ("of the filament") + #define MSG_FILAMENT_CHANGE_UNLOAD_1 "\xcc\xa8\xd7\xd2\xdd\xc4\xc7\xb7\xc0\xde\xbc\xc1\xad\xb3" // "フィラメントヌキダシチュウ" ("Wait for") + #define MSG_FILAMENT_CHANGE_UNLOAD_2 "\xbc\xca\xde\xd7\xb8\xb5\xcf\xc1\xb8\xc0\xde\xbb\xb2" // "シバラクオマチクダサイ" ("filament unload") + #define MSG_FILAMENT_CHANGE_INSERT_1 "\xcc\xa8\xd7\xd2\xdd\xc4\xa6\xbf\xb3\xc6\xad\xb3\xbc," // "フィラメントヲソウニュウシ," ("Insert filament") + #define MSG_FILAMENT_CHANGE_INSERT_2 "\xb8\xd8\xaf\xb8\xbd\xd9\xc4\xbf\xde\xaf\xba\xb3\xbc\xcf\xbd" // "クリックスルトゾッコウシマス" ("and press button") + #define MSG_FILAMENT_CHANGE_LOAD_1 "\xcc\xa8\xd7\xd2\xdd\xc4\xbf\xb3\xc3\xdd\xc1\xad\xb3" // "フィラメントソウテンチュウ" ("Wait for") + #define MSG_FILAMENT_CHANGE_LOAD_2 "\xbc\xca\xde\xd7\xb8\xb5\xcf\xc1\xb8\xc0\xde\xbb\xb2" // "シバラクオマチクダサイ" ("filament load") + #define MSG_FILAMENT_CHANGE_EXTRUDE_1 "\xcc\xa8\xd7\xd2\xdd\xc4\xb5\xbc\xc0\xde\xbc\xc1\xad\xb3" // "フィラメントオシダシチュウ" ("Wait for") + #define MSG_FILAMENT_CHANGE_EXTRUDE_2 "\xbc\xca\xde\xd7\xb8\xb5\xcf\xc1\xb8\xc0\xde\xbb\xb2" // "シバラクオマチクダサイ" ("filament extrude") + #define MSG_FILAMENT_CHANGE_RESUME_1 "\xcc\xdf\xd8\xdd\xc4\xa6\xbb\xb2\xb6\xb2\xbc\xcf\xbd" // "プリントヲサイカイシマス" ("Wait for print") + #define MSG_FILAMENT_CHANGE_RESUME_2 "\xbc\xca\xde\xd7\xb8\xb5\xcf\xc1\xb8\xc0\xde\xbb\xb2" // "シバラクオマチクダサイ" ("to resume") +#else // LCD_HEIGHT < 4 + // Up to 2 lines allowed + #define MSG_FILAMENT_CHANGE_INIT_1 "\xba\xb3\xb6\xdd\xa6\xb6\xb2\xbc\xbc\xcf\xbd" // "コウカンヲカイシシマス" ("Please wait...") + #define MSG_FILAMENT_CHANGE_UNLOAD_1 "\xcc\xa8\xd7\xd2\xdd\xc4\xc7\xb7\xc0\xde\xbc\xc1\xad\xb3" // "フィラメントヌキダシチュウ" ("Ejecting...") + #if LCD_WIDTH >= 20 + #define MSG_FILAMENT_CHANGE_INSERT_1 "\xbf\xb3\xc6\xad\xb3\xbc\x2c\xb8\xd8\xaf\xb8\xbc\xc3\xb8\xc0\xde\xbb\xb2" // "ソウニュウシ,クリックシテクダサイ" ("Insert and Click") + #else + #define MSG_FILAMENT_CHANGE_INSERT_1 "\xbf\xb3\xc6\xad\xb3\xbc\x2c\xb8\xd8\xaf\xb8\xbe\xd6" // "ソウニュウシ,クリックセヨ" ("Insert and Click") + #endif + #define MSG_FILAMENT_CHANGE_LOAD_1 "\xcc\xa8\xd7\xd2\xdd\xc4\xbf\xb3\xc3\xdd\xc1\xad\xb3" // "フィラメントソウテンチュウ" ("Loading...") + #define MSG_FILAMENT_CHANGE_EXTRUDE_1 "\xcc\xa8\xd7\xd2\xdd\xc4\xb5\xbc\xc0\xde\xbc\xc1\xad\xb3" // "フィラメントオシダシチュウ" ("Extruding...") + #define MSG_FILAMENT_CHANGE_RESUME_1 "\xcc\xdf\xd8\xdd\xc4\xa6\xbb\xb2\xb6\xb2\xbc\xcf\xbd" // "プリントヲサイカイシマス" ("Resuming...") +#endif // LCD_HEIGHT < 4 + +#endif // LANGUAGE_KANA_H diff --git a/trunk/Arduino/Marlin_1.1.6/language_kana_utf8.h b/trunk/Arduino/Marlin_1.1.6/language_kana_utf8.h new file mode 100644 index 00000000..b07aa409 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/language_kana_utf8.h @@ -0,0 +1,225 @@ +/** + * 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 . + * + */ + +/** + * Japanese (Kana) + * UTF-8 for Graphical Display + * + * LCD Menu Messages + * See also http://marlinfw.org/docs/development/lcd_language.html + * + */ + +#ifndef LANGUAGE_KANA_UTF_H +#define LANGUAGE_KANA_UTF_H + +#define MAPPER_E382E383 +#define DISPLAY_CHARSET_ISO10646_KANA + +// This just to show the potential benefit of unicode. +// This translation can be improved by using the full charset of unicode codeblock U+30A0 to U+30FF. + +// 片仮名表示定義 +#define WELCOME_MSG MACHINE_NAME _UxGT(" ready.") +#define MSG_SD_INSERTED _UxGT("カードガソウニュウサレマシタ") // "Card inserted" +#define MSG_SD_REMOVED _UxGT("カードガアリマセン") // "Card removed" +#define MSG_LCD_ENDSTOPS _UxGT("エンドストップ") // "Endstops" // Max length 8 characters +#define MSG_MAIN _UxGT("メイン") // "Main" +#define MSG_AUTOSTART _UxGT("ジドウカイシ") // "Autostart" +#define MSG_DISABLE_STEPPERS _UxGT("モーターデンゲン オフ") // "Disable steppers" +#define MSG_DEBUG_MENU _UxGT("デバッグメニュー") // "Debug Menu" +#define MSG_PROGRESS_BAR_TEST _UxGT("プログレスバー テスト") // "Progress Bar Test" +#define MSG_AUTO_HOME _UxGT("ゲンテンフッキ") // "Auto home" +#define MSG_AUTO_HOME_X _UxGT("Xジク ゲンテンフッキ") // "Home X" +#define MSG_AUTO_HOME_Y _UxGT("Yジク ゲンテンフッキ") // "Home Y" +#define MSG_AUTO_HOME_Z _UxGT("Zジク ゲンテンフッキ") // "Home Z" +#define MSG_LEVEL_BED_HOMING _UxGT("ゲンテンフッキチュウ") // "Homing XYZ" +#define MSG_LEVEL_BED_WAITING _UxGT("レベリングカイシ") // "Click to Begin" +#define MSG_LEVEL_BED_NEXT_POINT _UxGT("ツギノソクテイテンヘ") // "Next Point" +#define MSG_LEVEL_BED_DONE _UxGT("レベリングカンリョウ") // "Leveling Done!" +#define MSG_SET_HOME_OFFSETS _UxGT("キジュンオフセットセッテイ") // "Set home offsets" +#define MSG_HOME_OFFSETS_APPLIED _UxGT("オフセットガテキヨウサレマシタ") // "Offsets applied" +#define MSG_SET_ORIGIN _UxGT("キジュンセット") // "Set origin" +#define MSG_PREHEAT_1 _UxGT("PLA ヨネツ") // "Preheat PLA" +#define MSG_PREHEAT_1_N MSG_PREHEAT_1 _UxGT(" ") +#define MSG_PREHEAT_1_ALL _UxGT("PLA スベテヨネツ") // " All" +#define MSG_PREHEAT_1_BEDONLY _UxGT("PLA ベッドヨネツ") // " Bed" +#define MSG_PREHEAT_1_SETTINGS MSG_PREHEAT_1 _UxGT("セッテイ") // " conf" +#define MSG_PREHEAT_2 _UxGT("ABS ヨネツ") // "Preheat ABS" +#define MSG_PREHEAT_2_N MSG_PREHEAT_2 _UxGT(" ") +#define MSG_PREHEAT_2_ALL _UxGT("ABS スベテヨネツ") // " All" +#define MSG_PREHEAT_2_BEDONLY _UxGT("ABS ベッドヨネツ") // " Bed" +#define MSG_PREHEAT_2_SETTINGS MSG_PREHEAT_2 _UxGT("セッテイ") // " conf" +#define MSG_COOLDOWN _UxGT("カネツテイシ") // "Cooldown" +#define MSG_SWITCH_PS_ON _UxGT("デンゲン オン") // "Switch power on" +#define MSG_SWITCH_PS_OFF _UxGT("デンゲン オフ") // "Switch power off" +#define MSG_EXTRUDE _UxGT("オシダシ") // "Extrude" +#define MSG_RETRACT _UxGT("ヒキコミセッテイ") // "Retract" +#define MSG_MOVE_AXIS _UxGT("ジクイドウ") // "Move axis" +#define MSG_BED_LEVELING _UxGT("ベッドレベリング") // "Bed leveling" +#define MSG_LEVEL_BED _UxGT("ベッドレベリング") // "Level bed" +#define MSG_MOVING _UxGT("イドウチュウ") // "Moving..." +#define MSG_FREE_XY _UxGT("XYジク カイホウ") // "Free XY" +#define MSG_MOVE_X _UxGT("Xジク イドウ") // "Move X" +#define MSG_MOVE_Y _UxGT("Yジク イドウ") // "Move Y" +#define MSG_MOVE_Z _UxGT("Zジク イドウ") // "Move Z" +#define MSG_MOVE_E _UxGT("エクストルーダー") // "Extruder" +#define MSG_MOVE_01MM _UxGT("0.1mm イドウ") // "Move 0.1mm" +#define MSG_MOVE_1MM _UxGT(" 1mm イドウ") // "Move 1mm" +#define MSG_MOVE_10MM _UxGT(" 10mm イドウ") // "Move 10mm" +#define MSG_SPEED _UxGT("ソクド") // "Speed" +#define MSG_BED_Z _UxGT("Zオフセット") // "Bed Z" +#define MSG_NOZZLE _UxGT("ノズル") // "Nozzle" +#define MSG_BED _UxGT("ベッド") // "Bed" +#define MSG_FAN_SPEED _UxGT("ファンソクド") // "Fan speed" +#define MSG_FLOW _UxGT("トシュツリョウ") // "Flow" +#define MSG_CONTROL _UxGT("セイギョ") // "Control" +#define MSG_MIN _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" サイテイ") // " Min" +#define MSG_MAX _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" サイコウ") // " Max" +#define MSG_FACTOR _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" ファクター") // " Fact" +#define MSG_AUTOTEMP _UxGT("ジドウオンドセイギョ") // "Autotemp" +#define MSG_ON _UxGT("オン ") // "On " +#define MSG_OFF _UxGT("オフ ") // "Off" +#define MSG_PID_P _UxGT("PID-P") +#define MSG_PID_I _UxGT("PID-I") +#define MSG_PID_D _UxGT("PID-D") +#define MSG_PID_C _UxGT("PID-C") +#define MSG_SELECT _UxGT("センタク") // "Select" +#define MSG_ACC _UxGT("カソクド mm/s2") // "Accel" +#define MSG_JERK _UxGT("ヤクド mm/s") // "Jerk" +#define MSG_VX_JERK _UxGT("Xジク ヤクド mm/s") // "Vx-jerk" +#define MSG_VY_JERK _UxGT("Yジク ヤクド mm/s") // "Vy-jerk" +#define MSG_VZ_JERK _UxGT("Zジク ヤクド mm/s") // "Vz-jerk" +#define MSG_VE_JERK _UxGT("エクストルーダー ヤクド") // "Ve-jerk" +#define MSG_VMAX _UxGT("サイダイオクリソクド ") // "Vmax " +#define MSG_VMIN _UxGT("サイショウオクリソクド") // "Vmin" +#define MSG_VTRAV_MIN _UxGT("サイショウイドウソクド") // "VTrav min" +#define MSG_ACCELERATION MSG_ACC +#define MSG_AMAX _UxGT("サイダイカソクド ") // "Amax " +#define MSG_A_RETRACT _UxGT("ヒキコミカソクド") // "A-retract" +#define MSG_A_TRAVEL _UxGT("イドウカソクド") // "A-travel" +#define MSG_TEMPERATURE _UxGT("オンド") // "Temperature" +#define MSG_MOTION _UxGT("ウゴキセッテイ") // "Motion" +#define MSG_FILAMENT _UxGT("フィラメント") // "Filament" +#define MSG_VOLUMETRIC_ENABLED _UxGT("E in mm3") +#define MSG_FILAMENT_DIAM _UxGT("フィラメントチョッケイ") // "Fil. Dia." +#define MSG_CONTRAST _UxGT("LCDコントラスト") // "LCD contrast" +#define MSG_STORE_EEPROM _UxGT("メモリヘカクノウ") // "Store memory" +#define MSG_LOAD_EEPROM _UxGT("メモリカラヨミコミ") // "Load memory" +#define MSG_RESTORE_FAILSAFE _UxGT("セッテイリセット") // "Restore failsafe" +#define MSG_REFRESH _UxGT("リフレッシュ") // "Refresh" +#define MSG_WATCH _UxGT("ジョウホウガメン") // "Info screen" +#define MSG_PREPARE _UxGT("ジュンビセッテイ") // "Prepare" +#define MSG_TUNE _UxGT("チョウセイ") // "Tune" +#define MSG_PAUSE_PRINT _UxGT("イチジテイシ") // "Pause print" +#define MSG_RESUME_PRINT _UxGT("プリントサイカイ") // "Resume print" +#define MSG_STOP_PRINT _UxGT("プリントテイシ") // "Stop print" +#define MSG_CARD_MENU _UxGT("SDカードカラプリント") // "Print from SD" +#define MSG_NO_CARD _UxGT("SDカードガアリマセン") // "No SD card" +#define MSG_DWELL _UxGT("キュウシ") // "Sleep..." +#define MSG_USERWAIT _UxGT("シバラクオマチクダサイ") // "Wait for user..." +#define MSG_RESUMING _UxGT("プリントサイカイ") // "Resuming print" +#define MSG_PRINT_ABORTED _UxGT("プリントガチュウシサレマシタ") // "Print aborted" +#define MSG_NO_MOVE _UxGT("ウゴキマセン") // "No move." +#define MSG_KILLED _UxGT("ヒジョウテイシ") // "KILLED. " +#define MSG_STOPPED _UxGT("テイシシマシタ") // "STOPPED. " +#define MSG_CONTROL_RETRACT _UxGT("ヒキコミリョウ mm") // "Retract mm" +#define MSG_CONTROL_RETRACT_SWAP _UxGT("ヒキコミリョウS mm") // "Swap Re.mm" +#define MSG_CONTROL_RETRACTF _UxGT("ヒキコミソクド mm/s") // "Retract V" +#define MSG_CONTROL_RETRACT_ZLIFT _UxGT("ノズルタイヒ mm") // "Hop mm" +#define MSG_CONTROL_RETRACT_RECOVER _UxGT("ホショウリョウ mm") // "UnRet mm" +#define MSG_CONTROL_RETRACT_RECOVER_SWAP _UxGT("ホショウリョウS mm") // "S UnRet mm" +#define MSG_CONTROL_RETRACT_RECOVERF _UxGT("ホショウソクド mm/s") // "UnRet V" +#define MSG_AUTORETRACT _UxGT("ジドウヒキコミ") // "AutoRetr." +#define MSG_FILAMENTCHANGE _UxGT("フィラメントコウカン") // "Change filament" +#define MSG_INIT_SDCARD _UxGT("SDカードサイヨミコミ") // "Init. SD card" +#define MSG_CNG_SDCARD _UxGT("SDカードコウカン") // "Change SD card" +#define MSG_ZPROBE_OUT _UxGT("Zプローブ ベッドガイ") // "Z probe out. bed" +#define MSG_BLTOUCH_SELFTEST _UxGT("BLTouch ジコシンダン") // "BLTouch Self-Test" +#define MSG_BLTOUCH_RESET _UxGT("BLTouch リセット") // "Reset BLTouch" +#define MSG_HOME _UxGT("サキニ") // "Home" // Used as MSG_HOME " " MSG_X MSG_Y MSG_Z " " MSG_FIRST +#define MSG_FIRST _UxGT("ヲフッキサセテクダサイ") // "first" +#define MSG_ZPROBE_ZOFFSET _UxGT("Zオフセット") // "Z Offset" +#define MSG_BABYSTEP_X _UxGT("Xジク ビドウ") // "Babystep X" +#define MSG_BABYSTEP_Y _UxGT("Yジク ビドウ") // "Babystep Y" +#define MSG_BABYSTEP_Z _UxGT("Zジク ビドウ") // "Babystep Z" +#define MSG_ENDSTOP_ABORT _UxGT("イドウゲンカイケンチキノウ") // "Endstop abort" +#define MSG_HEATING_FAILED_LCD _UxGT("カネツシッパイ") // "Heating failed" +#define MSG_ERR_REDUNDANT_TEMP _UxGT("エラー:ジョウチョウサーミスターキノウ") // "Err: REDUNDANT TEMP" +#define MSG_THERMAL_RUNAWAY _UxGT("ネツボウソウ") // "THERMAL RUNAWAY" +#define MSG_ERR_MAXTEMP _UxGT("エラー:サイコウオンチョウカ") // "Err: MAXTEMP" +#define MSG_ERR_MINTEMP _UxGT("エラー:サイテイオンミマン") // "Err: MINTEMP" +#define MSG_ERR_MAXTEMP_BED _UxGT("エラー:ベッド サイコウオンチョウカ") // "Err: MAXTEMP BED" +#define MSG_ERR_MINTEMP_BED _UxGT("エラー:ベッド サイテイオンミマン") // "Err: MINTEMP BED" +#define MSG_ERR_Z_HOMING MSG_HOME _UxGT(" ") MSG_X MSG_Y _UxGT(" ") MSG_FIRST // "G28 Z Forbidden" +#define MSG_HALTED _UxGT("プリンターハテイシシマシタ") // "PRINTER HALTED" +#define MSG_PLEASE_RESET _UxGT("リセットシテクダサイ") // "Please reset" +#define MSG_SHORT_DAY _UxGT("d") // One character only +#define MSG_SHORT_HOUR _UxGT("h") // One character only +#define MSG_SHORT_MINUTE _UxGT("m") // One character only +#define MSG_HEATING _UxGT("カネツチュウ") // "Heating..." +#define MSG_HEATING_COMPLETE _UxGT("カネツカンリョウ") // "Heating done." +#define MSG_BED_HEATING _UxGT("ベッド カネツチュウ") // "Bed Heating." +#define MSG_BED_DONE _UxGT("ベッド カネツカンリョウ") // "Bed done." +#define MSG_DELTA_CALIBRATE _UxGT("デルタ コウセイ") // "Delta Calibration" +#define MSG_DELTA_CALIBRATE_X _UxGT("Xジク コウセイ") // "Calibrate X" +#define MSG_DELTA_CALIBRATE_Y _UxGT("Yジク コウセイ") // "Calibrate Y" +#define MSG_DELTA_CALIBRATE_Z _UxGT("Zジク コウセイ") // "Calibrate Z" +#define MSG_DELTA_CALIBRATE_CENTER _UxGT("チュウシン コウセイ") // "Calibrate Center" +#define MSG_INFO_MENU _UxGT("コノプリンターニツイテ") // "About Printer" +#define MSG_INFO_PRINTER_MENU _UxGT("プリンタージョウホウ") // "Printer Info" +#define MSG_INFO_STATS_MENU _UxGT("プリントジョウキョウ") // "Printer Stats" +#define MSG_INFO_BOARD_MENU _UxGT("セイギョケイジョウホウ") // "Board Info" +#define MSG_INFO_THERMISTOR_MENU _UxGT("サーミスター") // "Thermistors" +#define MSG_INFO_EXTRUDERS _UxGT("エクストルーダースウ") // "Extruders" +#define MSG_INFO_BAUDRATE _UxGT("ボーレート") // "Baud" +#define MSG_INFO_PROTOCOL _UxGT("プロトコル") // "Protocol" +#define MSG_CASE_LIGHT _UxGT("キョウタイナイショウメイ") // "Case light" +#define MSG_INFO_PRINT_COUNT _UxGT("プリントスウ ") // "Print Count" +#define MSG_INFO_COMPLETED_PRINTS _UxGT("カンリョウスウ") // "Completed" +#define MSG_INFO_PRINT_TIME _UxGT("プリントジカンルイケイ") // "Total print time" +#define MSG_INFO_PRINT_LONGEST _UxGT("サイチョウプリントジカン") // "Longest job time" +#define MSG_INFO_PRINT_FILAMENT _UxGT("フィラメントシヨウリョウルイケイ") // "Extruded total" +#define MSG_INFO_MIN_TEMP _UxGT("セッテイサイテイオン") // "Min Temp" +#define MSG_INFO_MAX_TEMP _UxGT("セッテイサイコウオン") // "Max Temp" +#define MSG_INFO_PSU _UxGT("デンゲンシュベツ") // "Power Supply" +#define MSG_DRIVE_STRENGTH _UxGT("モータークドウリョク") // "Drive Strength" +#define MSG_DAC_PERCENT _UxGT("DACシュツリョク %") // "Driver %" +#define MSG_DAC_EEPROM_WRITE MSG_STORE_EPROM // "DAC EEPROM Write" +#define MSG_FILAMENT_CHANGE_HEADER _UxGT("PRINT PAUSED") +#define MSG_FILAMENT_CHANGE_OPTION_HEADER _UxGT("RESUME OPTIONS:") +#define MSG_FILAMENT_CHANGE_OPTION_EXTRUDE _UxGT("サラニオシダス") // "Extrude more" +#define MSG_FILAMENT_CHANGE_OPTION_RESUME _UxGT("プリントサイカイ") // "Resume print" +#define MSG_FILAMENT_CHANGE_INIT_1 _UxGT("コウカンヲカイシシマス") // "Wait for start" +#define MSG_FILAMENT_CHANGE_INIT_2 _UxGT("シバラクオマチクダサイ") // "of the filament" +#define MSG_FILAMENT_CHANGE_UNLOAD_1 _UxGT("フィラメントヌキダシチュウ") // "Wait for" +#define MSG_FILAMENT_CHANGE_UNLOAD_2 _UxGT("シバラクオマチクダサイ") // "filament unload" +#define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("フィラメントヲソウニュウシ,") // "Insert filament" +#define MSG_FILAMENT_CHANGE_INSERT_2 _UxGT("クリックスルトゾッコウシマス") // "and press button" +#define MSG_FILAMENT_CHANGE_LOAD_1 _UxGT("フィラメントソウテンチュウ") // "Wait for" +#define MSG_FILAMENT_CHANGE_LOAD_2 _UxGT("シバラクオマチクダサイ") // "filament load" +#define MSG_FILAMENT_CHANGE_EXTRUDE_1 _UxGT("フィラメントオシダシチュウ") // "Wait for" +#define MSG_FILAMENT_CHANGE_EXTRUDE_2 _UxGT("シバラクオマチクダサイ") // "filament extrude" +#define MSG_FILAMENT_CHANGE_RESUME_1 _UxGT("プリントヲサイカイシマス") // "Wait for print" +#define MSG_FILAMENT_CHANGE_RESUME_2 _UxGT("シバラクオマチクダサイ") // "to resume" + +#endif // LANGUAGE_KANA_UTF_H diff --git a/trunk/Arduino/Marlin_1.1.6/language_nl.h b/trunk/Arduino/Marlin_1.1.6/language_nl.h new file mode 100644 index 00000000..7a605018 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/language_nl.h @@ -0,0 +1,281 @@ +/** + * 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 . + * + */ + +/** + * Dutch + * + * LCD Menu Messages + * See also http://marlinfw.org/docs/development/lcd_language.html + * + */ +#ifndef LANGUAGE_NL_H +#define LANGUAGE_NL_H + +#define DISPLAY_CHARSET_ISO10646_1 + +#define WELCOME_MSG MACHINE_NAME _UxGT(" gereed.") +#define MSG_BACK _UxGT("Terug") +#define MSG_SD_INSERTED _UxGT("Kaart ingestoken") +#define MSG_SD_REMOVED _UxGT("Kaart verwijderd") +#define MSG_LCD_ENDSTOPS _UxGT("Endstops") // Max length 8 characters +#define MSG_MAIN _UxGT("Hoofdmenu") +#define MSG_AUTOSTART _UxGT("Autostart") +#define MSG_DISABLE_STEPPERS _UxGT("Motoren uit") +#define MSG_DEBUG_MENU _UxGT("Debug Menu") //accepted English terms +#define MSG_PROGRESS_BAR_TEST _UxGT("Vooruitgang Test") +#define MSG_AUTO_HOME _UxGT("Auto home") +#define MSG_AUTO_HOME_X _UxGT("Home X") +#define MSG_AUTO_HOME_Y _UxGT("Home Y") +#define MSG_AUTO_HOME_Z _UxGT("Home Z") +#define MSG_LEVEL_BED_HOMING _UxGT("Homing XYZ") +#define MSG_LEVEL_BED_WAITING _UxGT("Klik voor begin") +#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Volgende Plaats") +#define MSG_LEVEL_BED_DONE _UxGT("Bed level kompl.") +#define MSG_SET_HOME_OFFSETS _UxGT("Zet home offsets") +#define MSG_HOME_OFFSETS_APPLIED _UxGT("H offset toegep.") +#define MSG_SET_ORIGIN _UxGT("Nulpunt instellen") +#define MSG_PREHEAT_1 _UxGT("PLA voorverwarmen") +#define MSG_PREHEAT_1_N _UxGT("PLA voorverw. ") +#define MSG_PREHEAT_1_ALL MSG_PREHEAT_1_N _UxGT("aan") +#define MSG_PREHEAT_1_END MSG_PREHEAT_1 _UxGT(" Einde") +#define MSG_PREHEAT_1_BEDONLY MSG_PREHEAT_1_N _UxGT("Bed") +#define MSG_PREHEAT_1_SETTINGS _UxGT("PLA verw. conf") +#define MSG_PREHEAT_2 _UxGT("ABS voorverwarmen") +#define MSG_PREHEAT_2_N _UxGT("ABS voorverw. ") +#define MSG_PREHEAT_2_ALL MSG_PREHEAT_2_N _UxGT("aan") +#define MSG_PREHEAT_2_END MSG_PREHEAT_2 _UxGT(" Einde") +#define MSG_PREHEAT_2_BEDONLY MSG_PREHEAT_2_N _UxGT("Bed") +#define MSG_PREHEAT_2_SETTINGS _UxGT("ABS verw. conf") +#define MSG_COOLDOWN _UxGT("Afkoelen") +#define MSG_SWITCH_PS_ON _UxGT("Stroom aan") +#define MSG_SWITCH_PS_OFF _UxGT("Stroom uit") +#define MSG_EXTRUDE _UxGT("Extrude") +#define MSG_RETRACT _UxGT("Retract") +#define MSG_MOVE_AXIS _UxGT("As verplaatsen") +#define MSG_BED_LEVELING _UxGT("Bed Leveling") +#define MSG_LEVEL_BED _UxGT("Level bed") +#define MSG_MOVING _UxGT("Verplaatsen...") +#define MSG_FREE_XY _UxGT("Vrij XY") +#define MSG_MOVE_X _UxGT("Verplaats X") +#define MSG_MOVE_Y _UxGT("Verplaats Y") +#define MSG_MOVE_Z _UxGT("Verplaats Z") +#define MSG_MOVE_E _UxGT("Extruder") +#define MSG_MOVE_01MM _UxGT("Verplaats 0.1mm") +#define MSG_MOVE_1MM _UxGT("Verplaats 1mm") +#define MSG_MOVE_10MM _UxGT("Verplaats 10mm") +#define MSG_SPEED _UxGT("Snelheid") +#define MSG_BED_Z _UxGT("Bed Z") +#define MSG_NOZZLE _UxGT("Nozzle") +#define MSG_BED _UxGT("Bed") +#define MSG_FAN_SPEED _UxGT("Fan snelheid") +#define MSG_FLOW _UxGT("Flow") +#define MSG_CONTROL _UxGT("Control") +#define MSG_MIN _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" Min") +#define MSG_MAX _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" Max") +#define MSG_FACTOR _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" Fact") +#define MSG_AUTOTEMP _UxGT("Autotemp") +#define MSG_ON _UxGT("Aan ") +#define MSG_OFF _UxGT("Uit") +#define MSG_PID_P _UxGT("PID-P") +#define MSG_PID_I _UxGT("PID-I") +#define MSG_PID_D _UxGT("PID-D") +#define MSG_PID_C _UxGT("PID-C") +#define MSG_SELECT _UxGT("Selecteer") +#define MSG_ACC _UxGT("Versn") +#define MSG_JERK _UxGT("Jerk") +#define MSG_VX_JERK _UxGT("Vx-jerk") +#define MSG_VY_JERK _UxGT("Vy-jerk") +#define MSG_VZ_JERK _UxGT("Vz-jerk") +#define MSG_VE_JERK _UxGT("Ve-jerk") +#define MSG_VMAX _UxGT("Vmax ") +#define MSG_VMIN _UxGT("Vmin") +#define MSG_VTRAV_MIN _UxGT("VTrav min") +#define MSG_AMAX _UxGT("Amax ") +#define MSG_A_RETRACT _UxGT("A-retract") +#define MSG_A_TRAVEL _UxGT("A-travel") +#define MSG_STEPS_PER_MM _UxGT("Steps/mm") +#define MSG_XSTEPS _UxGT("Xsteps/mm") +#define MSG_YSTEPS _UxGT("Ysteps/mm") +#define MSG_ZSTEPS _UxGT("Zsteps/mm") +#define MSG_ESTEPS _UxGT("Esteps/mm") +#define MSG_E1STEPS _UxGT("E1steps/mm") +#define MSG_E2STEPS _UxGT("E2steps/mm") +#define MSG_E3STEPS _UxGT("E3steps/mm") +#define MSG_E4STEPS _UxGT("E4steps/mm") +#define MSG_E5STEPS _UxGT("E5steps/mm") +#define MSG_TEMPERATURE _UxGT("Temperatuur") +#define MSG_MOTION _UxGT("Beweging") +#define MSG_FILAMENT _UxGT("Filament") +#define MSG_ADVANCE_K _UxGT("Advance K") //accepted english dutch +#define MSG_VOLUMETRIC_ENABLED _UxGT("E in mm3") +#define MSG_FILAMENT_DIAM _UxGT("Fil. Dia.") +#define MSG_CONTRAST _UxGT("LCD contrast") +#define MSG_STORE_EEPROM _UxGT("Geheugen opslaan") +#define MSG_LOAD_EEPROM _UxGT("Geheugen laden") +#define MSG_RESTORE_FAILSAFE _UxGT("Noodstop reset") +#define MSG_REFRESH _UxGT("Ververs") +#define MSG_WATCH _UxGT("Info scherm") +#define MSG_PREPARE _UxGT("Voorbereiden") +#define MSG_TUNE _UxGT("Afstellen") +#define MSG_PAUSE_PRINT _UxGT("Print pauzeren") +#define MSG_RESUME_PRINT _UxGT("Print hervatten") +#define MSG_STOP_PRINT _UxGT("Print stoppen") +#define MSG_CARD_MENU _UxGT("Print van SD") +#define MSG_NO_CARD _UxGT("Geen SD kaart") +#define MSG_DWELL _UxGT("Slapen...") +#define MSG_USERWAIT _UxGT("Wachten...") +#define MSG_RESUMING _UxGT("Print hervatten") +#define MSG_PRINT_ABORTED _UxGT("Print afgebroken") +#define MSG_NO_MOVE _UxGT("Geen beweging.") +#define MSG_KILLED _UxGT("Afgebroken. ") +#define MSG_STOPPED _UxGT("Gestopt. ") +#define MSG_CONTROL_RETRACT _UxGT("Retract mm") //accepted English term in Dutch +#define MSG_CONTROL_RETRACT_SWAP _UxGT("Ruil Retract mm") +#define MSG_CONTROL_RETRACTF _UxGT("Retract F") +#define MSG_CONTROL_RETRACT_ZLIFT _UxGT("Hop mm") +#define MSG_CONTROL_RETRACT_RECOVER _UxGT("UnRet mm") +#define MSG_CONTROL_RETRACT_RECOVER_SWAP _UxGT("Ruil UnRet mm") +#define MSG_CONTROL_RETRACT_RECOVERF _UxGT("UnRet F") +#define MSG_AUTORETRACT _UxGT("AutoRetr.") +#define MSG_FILAMENTCHANGE _UxGT("Verv. Filament") +#define MSG_INIT_SDCARD _UxGT("Init. SD kaart") +#define MSG_CNG_SDCARD _UxGT("Verv. SD Kaart") +#define MSG_ZPROBE_OUT _UxGT("Z probe uit. bed") +#define MSG_BLTOUCH_SELFTEST _UxGT("BLTouch Zelf-Test") +#define MSG_BLTOUCH_RESET _UxGT("Reset BLTouch") +#define MSG_HOME _UxGT("Home") // Used as MSG_HOME " " MSG_X MSG_Y MSG_Z " " MSG_FIRST +#define MSG_FIRST _UxGT("Eerst") +#define MSG_ZPROBE_ZOFFSET _UxGT("Z Offset") //accepted English term in Dutch +#define MSG_BABYSTEP_X _UxGT("Babystap X") +#define MSG_BABYSTEP_Y _UxGT("Babystap Y") +#define MSG_BABYSTEP_Z _UxGT("Babystap Z") +#define MSG_ENDSTOP_ABORT _UxGT("Endstop afbr.") +#define MSG_HEATING_FAILED_LCD _UxGT("Voorverw. fout") +#define MSG_ERR_REDUNDANT_TEMP _UxGT("Redun. temp fout") +#define MSG_THERMAL_RUNAWAY _UxGT("Therm. wegloop") +#define MSG_ERR_MAXTEMP _UxGT("Err: Max. temp") +#define MSG_ERR_MINTEMP _UxGT("Err: Min. temp") +#define MSG_ERR_MAXTEMP_BED _UxGT("Err: Max.tmp bed") +#define MSG_ERR_MINTEMP_BED _UxGT("Err: Min.tmp bed") +#define MSG_ERR_Z_HOMING _UxGT("Fout Z homing") +#define MSG_HALTED _UxGT("PRINTER GESTOPT") +#define MSG_PLEASE_RESET _UxGT("Reset A.U.B.") +#define MSG_SHORT_DAY _UxGT("d") // One character only. Keep English standard +#define MSG_SHORT_HOUR _UxGT("h") // One character only +#define MSG_SHORT_MINUTE _UxGT("m") // One character only +#define MSG_HEATING _UxGT("Voorwarmen...") +#define MSG_HEATING_COMPLETE _UxGT("Voorverw. kompl.") +#define MSG_BED_HEATING _UxGT("Bed voorverw.") +#define MSG_BED_DONE _UxGT("Bed is voorverw.") +#define MSG_DELTA_CALIBRATE _UxGT("Delta Calibratie") +#define MSG_DELTA_CALIBRATE_X _UxGT("Kalibreer X") +#define MSG_DELTA_CALIBRATE_Y _UxGT("Kalibreer Y") +#define MSG_DELTA_CALIBRATE_Z _UxGT("Kalibreer Z") +#define MSG_DELTA_CALIBRATE_CENTER _UxGT("Kalibreer Midden") +#define MSG_DELTA_AUTO_CALIBRATE _UxGT("Auto Calibratie") +#define MSG_DELTA_HEIGHT_CALIBRATE _UxGT("Zet Delta Hoogte") + +#define MSG_INFO_STATS_MENU _UxGT("Printer Stats") +#define MSG_INFO_BOARD_MENU _UxGT("Board Info") //accepted English term in Dutch +#define MSG_INFO_THERMISTOR_MENU _UxGT("Thermistors") +#define MSG_INFO_EXTRUDERS _UxGT("Extruders") +#define MSG_INFO_BAUDRATE _UxGT("Baud") +#define MSG_INFO_MENU _UxGT("Over Printer") +#define MSG_INFO_PRINTER_MENU _UxGT("Printer Info") +#define MSG_INFO_PROTOCOL _UxGT("Protocol") +#define MSG_CASE_LIGHT _UxGT("Case licht") + +#if LCD_WIDTH >= 20 + #define MSG_INFO_PRINT_COUNT _UxGT("Printed Aantal") + #define MSG_INFO_COMPLETED_PRINTS _UxGT("Totaal Voltooid") + #define MSG_INFO_PRINT_TIME _UxGT("Totale Printtijd") + #define MSG_INFO_PRINT_LONGEST _UxGT("Langste Printtijd") + #define MSG_INFO_PRINT_FILAMENT _UxGT("Totaal Extrudeert") +#else + #define MSG_INFO_PRINT_COUNT _UxGT("Aantal") + #define MSG_INFO_COMPLETED_PRINTS _UxGT("Voltooid") + #define MSG_INFO_PRINT_TIME _UxGT("Printtijd ") + #define MSG_INFO_PRINT_LONGEST _UxGT("Langste") + #define MSG_INFO_PRINT_FILAMENT _UxGT("Extrud.") +#endif + +#define MSG_INFO_MIN_TEMP _UxGT("Min Temp") +#define MSG_INFO_MAX_TEMP _UxGT("Max Temp") +#define MSG_INFO_PSU _UxGT("PSU") //accepted English term in Dutch + +#define MSG_DRIVE_STRENGTH _UxGT("Motorstroom") +#define MSG_DAC_PERCENT _UxGT("Driver %") //accepted English term in Dutch +#define MSG_DAC_EEPROM_WRITE _UxGT("DAC Opslaan") +#define MSG_FILAMENT_CHANGE_HEADER _UxGT("PRINT PAUSED") +#define MSG_FILAMENT_CHANGE_OPTION_HEADER _UxGT("RESUME OPTIONS:") +#define MSG_FILAMENT_CHANGE_OPTION_EXTRUDE _UxGT("Extrudeer meer") +#define MSG_FILAMENT_CHANGE_OPTION_RESUME _UxGT("Hervat print") +#define MSG_FILAMENT_CHANGE_MINTEMP _UxGT("Minimum Temp is ") +#define MSG_FILAMENT_CHANGE_NOZZLE _UxGT(" Nozzle: ") //accepeted 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 +// +#if LCD_HEIGHT >= 4 + // Up to 3 lines + #define MSG_FILAMENT_CHANGE_INIT_1 _UxGT("Wacht voor start") + #define MSG_FILAMENT_CHANGE_INIT_2 _UxGT("filament te") + #define MSG_FILAMENT_CHANGE_INIT_3 _UxGT("verwisselen") + #define MSG_FILAMENT_CHANGE_UNLOAD_1 _UxGT("Wacht voor") + #define MSG_FILAMENT_CHANGE_UNLOAD_2 _UxGT("filament uit") + #define MSG_FILAMENT_CHANGE_UNLOAD_3 _UxGT("te laden") + #define MSG_FILAMENT_CHANGE_HEAT_1 _UxGT("Klik knop om...") + #define MSG_FILAMENT_CHANGE_HEAT_2 _UxGT("verw. nozzle.") //nozzle accepted English term + #define MSG_FILAMENT_CHANGE_HEATING_1 _UxGT("Nozzle verw.") + #define MSG_FILAMENT_CHANGE_HEATING_2 _UxGT("Wacht a.u.b.") + #define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("Laad filament") + #define MSG_FILAMENT_CHANGE_INSERT_2 _UxGT("en druk knop") + #define MSG_FILAMENT_CHANGE_INSERT_3 _UxGT("om verder...") + #define MSG_FILAMENT_CHANGE_LOAD_1 _UxGT("Wacht voor") + #define MSG_FILAMENT_CHANGE_LOAD_2 _UxGT("filament te") + #define MSG_FILAMENT_CHANGE_LOAD_3 _UxGT("laden") + #define MSG_FILAMENT_CHANGE_EXTRUDE_1 _UxGT("Wacht voor") + #define MSG_FILAMENT_CHANGE_EXTRUDE_2 _UxGT("filament te") + #define MSG_FILAMENT_CHANGE_EXTRUDE_3 _UxGT("extruderen") + #define MSG_FILAMENT_CHANGE_RESUME_1 _UxGT("Wacht voor print") + #define MSG_FILAMENT_CHANGE_RESUME_2 _UxGT("om verder") + #define MSG_FILAMENT_CHANGE_RESUME_3 _UxGT("te gaan") +#else // LCD_HEIGHT < 4 + // Up to 2 lines + #define MSG_FILAMENT_CHANGE_INIT_1 _UxGT("Wacht voor") + #define MSG_FILAMENT_CHANGE_INIT_2 _UxGT("start...") + #define MSG_FILAMENT_CHANGE_UNLOAD_1 _UxGT("Wacht voor") + #define MSG_FILAMENT_CHANGE_UNLOAD_2 _UxGT("uitladen...") + #define MSG_FILAMENT_CHANGE_HEAT_1 _UxGT("Klik knop om...") + #define MSG_FILAMENT_CHANGE_HEAT_2 _UxGT("verw. nozzle.") //nozzle accepted English term + #define MSG_FILAMENT_CHANGE_HEATING_1 _UxGT("Verwarmen...") + #define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("Laad filament") + #define MSG_FILAMENT_CHANGE_INSERT_2 _UxGT("en druk knop") + #define MSG_FILAMENT_CHANGE_LOAD_1 _UxGT("Wacht voor") + #define MSG_FILAMENT_CHANGE_LOAD_2 _UxGT("inladen...") + #define MSG_FILAMENT_CHANGE_EXTRUDE_1 _UxGT("Wacht voor") + #define MSG_FILAMENT_CHANGE_EXTRUDE_2 _UxGT("extrudering") + #define MSG_FILAMENT_CHANGE_RESUME_1 _UxGT("Wacht voor") + #define MSG_FILAMENT_CHANGE_RESUME_2 _UxGT("printing...") +#endif // LCD_HEIGHT < 4 + +#endif // LANGUAGE_NL_H diff --git a/trunk/Arduino/Marlin_1.1.6/language_pl-DOGM.h b/trunk/Arduino/Marlin_1.1.6/language_pl-DOGM.h new file mode 100644 index 00000000..d93cfa45 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/language_pl-DOGM.h @@ -0,0 +1,240 @@ +/** + * 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 . + * + */ + +/** + * Polish for DOGM display - includes accented characters + */ + +#define WELCOME_MSG MACHINE_NAME _UxGT(" gotowy.") +#define MSG_SD_INSERTED _UxGT("Karta włożona") +#define MSG_SD_REMOVED _UxGT("Karta usunięta") +#define MSG_LCD_ENDSTOPS _UxGT("Kranców.") // Max length 8 characters +#define MSG_MAIN _UxGT("Menu główne") +#define MSG_AUTOSTART _UxGT("Autostart") +#define MSG_DISABLE_STEPPERS _UxGT("Wyłącz silniki") +#define MSG_AUTO_HOME _UxGT("Pozycja zerowa") +#define MSG_AUTO_HOME_X _UxGT("Zeruj X") +#define MSG_AUTO_HOME_Y _UxGT("Zeruj Y") +#define MSG_AUTO_HOME_Z _UxGT("Zeruj Z") +#define MSG_LEVEL_BED _UxGT("Poziom. stołu") +#define MSG_LEVEL_BED_HOMING _UxGT("Pozycja zerowa") +#define MSG_LEVEL_BED_WAITING _UxGT("Kliknij by rozp.") +#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Następny punkt") +#define MSG_LEVEL_BED_DONE _UxGT("Wypoziomowano!") +#define MSG_SET_HOME_OFFSETS _UxGT("Ust. poz. zer.") +#define MSG_HOME_OFFSETS_APPLIED _UxGT("Poz. zerowa ust.") +#define MSG_SET_ORIGIN _UxGT("Ustaw punkt zero") +#define MSG_PREHEAT_1 _UxGT("Rozgrzej PLA") +#define MSG_PREHEAT_1_N MSG_PREHEAT_1 _UxGT(" ") +#define MSG_PREHEAT_1_ALL MSG_PREHEAT_1 _UxGT(" wsz.") +#define MSG_PREHEAT_1_BEDONLY _UxGT("Rozgrzej stół PLA") +#define MSG_PREHEAT_1_SETTINGS _UxGT("Ustaw. rozg. PLA") +#define MSG_PREHEAT_2 _UxGT("Rozgrzej ABS") +#define MSG_PREHEAT_2_N MSG_PREHEAT_2 _UxGT(" ") +#define MSG_PREHEAT_2_ALL MSG_PREHEAT_2 _UxGT(" wsz.") +#define MSG_PREHEAT_2_BEDONLY _UxGT("Rozgrzej stół ABS") +#define MSG_PREHEAT_2_SETTINGS _UxGT("Ustaw. rozg. ABS") +#define MSG_COOLDOWN _UxGT("Chłodzenie") +#define MSG_SWITCH_PS_ON _UxGT("Włącz zasilacz") +#define MSG_SWITCH_PS_OFF _UxGT("Wyłącz zasilacz") +#define MSG_EXTRUDE _UxGT("Ekstruzja") +#define MSG_RETRACT _UxGT("Wycofanie") +#define MSG_MOVE_AXIS _UxGT("Ruch osi") +#define MSG_BED_LEVELING _UxGT("Poziom. stołu") +#define MSG_MOVE_X _UxGT("Przesuń w X") +#define MSG_MOVE_Y _UxGT("Przesuń w Y") +#define MSG_MOVE_Z _UxGT("Przesuń w Z") +#define MSG_MOVE_E _UxGT("Ekstruzja (os E)") +#define MSG_MOVE_01MM _UxGT("Przesuń co .1mm") +#define MSG_MOVE_1MM _UxGT("Przesuń co 1mm") +#define MSG_MOVE_10MM _UxGT("Przesuń co 10mm") +#define MSG_SPEED _UxGT("Predkość") +#define MSG_BED_Z _UxGT("Stół Z") +#define MSG_NOZZLE _UxGT("Dysza") +#define MSG_BED _UxGT("Stół") +#define MSG_FAN_SPEED _UxGT("Obroty wiatraka") +#define MSG_FLOW _UxGT("Przepływ") +#define MSG_CONTROL _UxGT("Ustawienia") +#define MSG_MIN LCD_STR_THERMOMETER _UxGT(" Min") +#define MSG_MAX LCD_STR_THERMOMETER _UxGT(" Max") +#define MSG_FACTOR LCD_STR_THERMOMETER _UxGT(" Mnożnik") +#define MSG_AUTOTEMP _UxGT("Auto. temperatura") +#define MSG_ON _UxGT("Wł. ") +#define MSG_OFF _UxGT("Wył.") +#define MSG_PID_P _UxGT("PID-P") +#define MSG_PID_I _UxGT("PID-I") +#define MSG_PID_D _UxGT("PID-D") +#define MSG_PID_C _UxGT("PID-C") +#define MSG_SELECT _UxGT("Select") +#define MSG_ACC _UxGT("Przyśpieszenie") +#define MSG_JERK _UxGT("Zryw") +#define MSG_VX_JERK _UxGT("Zryw Vx") +#define MSG_VY_JERK _UxGT("Zryw Vy") +#define MSG_VZ_JERK _UxGT("Zryw Vz") +#define MSG_VE_JERK _UxGT("Zryw Ve") +#define MSG_VMAX _UxGT("Vmax ") +#define MSG_VMIN _UxGT("Vmin") +#define MSG_VTRAV_MIN _UxGT("Vskok min") +#define MSG_ACCELERATION MSG_ACC +#define MSG_AMAX _UxGT("Amax") +#define MSG_A_RETRACT _UxGT("A-wycofanie") +#define MSG_A_TRAVEL _UxGT("A-przesuń.") +#define MSG_STEPS_PER_MM _UxGT("kroki/mm") +#define MSG_XSTEPS _UxGT("krokiX/mm") +#define MSG_YSTEPS _UxGT("krokiY/mm") +#define MSG_ZSTEPS _UxGT("krokiZ/mm") +#define MSG_ESTEPS _UxGT("krokiE/mm") +#define MSG_E1STEPS _UxGT("krokiE1/mm") +#define MSG_E2STEPS _UxGT("krokiE2/mm") +#define MSG_E3STEPS _UxGT("krokiE3/mm") +#define MSG_E4STEPS _UxGT("krokiE4/mm") +#define MSG_E5STEPS _UxGT("krokiE5/mm") +#define MSG_TEMPERATURE _UxGT("Temperatura") +#define MSG_MOTION _UxGT("Ruch") +#define MSG_FILAMENT _UxGT("Filament") +#define MSG_VOLUMETRIC_ENABLED _UxGT("E w mm3") +#define MSG_FILAMENT_DIAM _UxGT("Śr. fil.") +#define MSG_CONTRAST _UxGT("Kontrast LCD") +#define MSG_STORE_EEPROM _UxGT("Zapisz w pamięci") +#define MSG_LOAD_EEPROM _UxGT("Wczytaj z pamięci") +#define MSG_RESTORE_FAILSAFE _UxGT("Ustaw. fabryczne") +#define MSG_REFRESH _UxGT("Odswież") +#define MSG_WATCH _UxGT("Ekran główny") +#define MSG_PREPARE _UxGT("Przygotuj") +#define MSG_TUNE _UxGT("Strojenie") +#define MSG_PAUSE_PRINT _UxGT("Pauza") +#define MSG_RESUME_PRINT _UxGT("Wznowienie") +#define MSG_STOP_PRINT _UxGT("Stop") +#define MSG_CARD_MENU _UxGT("Karta SD") +#define MSG_NO_CARD _UxGT("Brak karty") +#define MSG_DWELL _UxGT("Uśpij...") +#define MSG_USERWAIT _UxGT("Oczekiwanie...") +#define MSG_RESUMING _UxGT("Wznawianie druku") +#define MSG_PRINT_ABORTED _UxGT("Druk przerwany") +#define MSG_NO_MOVE _UxGT("Brak ruchu") +#define MSG_KILLED _UxGT("Ubity. ") +#define MSG_STOPPED _UxGT("Zatrzymany. ") +#define MSG_CONTROL_RETRACT _UxGT("Wycofaj mm") +#define MSG_CONTROL_RETRACT_SWAP _UxGT("Z Wycof. mm") +#define MSG_CONTROL_RETRACTF _UxGT("Wycofaj V") +#define MSG_CONTROL_RETRACT_ZLIFT _UxGT("Skok Z mm") +#define MSG_CONTROL_RETRACT_RECOVER _UxGT("Cof. wycof. mm") +#define MSG_CONTROL_RETRACT_RECOVER_SWAP _UxGT("Z Cof. wyc. mm") +#define MSG_CONTROL_RETRACT_RECOVERF _UxGT("Cof. wycof. V") +#define MSG_AUTORETRACT _UxGT("Auto. wycofanie") +#define MSG_FILAMENTCHANGE _UxGT("Zmień filament") +#define MSG_INIT_SDCARD _UxGT("Inicjal. karty SD") +#define MSG_CNG_SDCARD _UxGT("Zmiana karty SD") +#define MSG_ZPROBE_OUT _UxGT("Sonda Z za stołem") +#define MSG_BLTOUCH_SELFTEST _UxGT("BLTouch Self-Test") +#define MSG_BLTOUCH_RESET _UxGT("Reset BLTouch") +#define MSG_HOME _UxGT("Home") // Used as MSG_HOME " " MSG_X MSG_Y MSG_Z " " MSG_FIRST +#define MSG_FIRST _UxGT("first") +#define MSG_ZPROBE_ZOFFSET _UxGT("Offset Z") +#define MSG_BABYSTEP_X _UxGT("Babystep X") +#define MSG_BABYSTEP_Y _UxGT("Babystep Y") +#define MSG_BABYSTEP_Z _UxGT("Babystep Z") +#define MSG_ENDSTOP_ABORT _UxGT("Błąd krańcówki") +#define MSG_HEATING_FAILED_LCD _UxGT("Rozgrz. nieudane") +#define MSG_ERR_REDUNDANT_TEMP _UxGT("Błąd temperatury") +#define MSG_THERMAL_RUNAWAY _UxGT("Zanik temp.") +#define MSG_ERR_MAXTEMP _UxGT("Err max temp") +#define MSG_ERR_MINTEMP _UxGT("Err min temp") +#define MSG_ERR_MAXTEMP_BED _UxGT("Err max temp stołu") +#define MSG_ERR_MINTEMP_BED _UxGT("Err min temp stołu") +#define MSG_ERR_Z_HOMING _UxGT("G28 Z Forbidden") +#define MSG_HALTED _UxGT("Drukarka zatrzym.") +#define MSG_PLEASE_RESET _UxGT("Proszę zresetować") +#define MSG_SHORT_DAY _UxGT("d") // One character only +#define MSG_SHORT_HOUR _UxGT("g") // One character only +#define MSG_SHORT_MINUTE _UxGT("m") // One character only +#define MSG_HEATING _UxGT("Rozgrzewanie...") +#define MSG_HEATING_COMPLETE _UxGT("Rozgrzano") +#define MSG_BED_HEATING _UxGT("Rozgrzewanie stołu...") +#define MSG_BED_DONE _UxGT("Rozgrzano stół") +#define MSG_DELTA_CALIBRATE _UxGT("Kalibrowanie Delty") +#define MSG_DELTA_CALIBRATE_X _UxGT("Kalibruj X") +#define MSG_DELTA_CALIBRATE_Y _UxGT("Kalibruj Y") +#define MSG_DELTA_CALIBRATE_Z _UxGT("Kalibruj Z") +#define MSG_DELTA_CALIBRATE_CENTER _UxGT("Kalibruj środek") + +#define MSG_INFO_MENU _UxGT("O drukarce") +#define MSG_INFO_PRINTER_MENU _UxGT("Info drukarki") +#define MSG_INFO_STATS_MENU _UxGT("Statystyki") +#define MSG_INFO_BOARD_MENU _UxGT("Board Info") +#define MSG_INFO_THERMISTOR_MENU _UxGT("Thermistory") +#define MSG_INFO_EXTRUDERS _UxGT("Ekstrudery") +#define MSG_INFO_BAUDRATE _UxGT("Predkość USB") +#define MSG_INFO_PROTOCOL _UxGT("Protokół") +#define MSG_CASE_LIGHT _UxGT("Oświetlenie") + +#if LCD_WIDTH >= 20 + #define MSG_INFO_PRINT_COUNT _UxGT("Wydrukowano") + #define MSG_INFO_COMPLETED_PRINTS _UxGT("Ukończono") + #define MSG_INFO_PRINT_TIME _UxGT("Czas druku") + #define MSG_INFO_PRINT_LONGEST _UxGT("Najdł. druk") + #define MSG_INFO_PRINT_FILAMENT _UxGT("Użyty fil.") +#else + #define MSG_INFO_PRINT_COUNT _UxGT("Wydrukowano") + #define MSG_INFO_COMPLETED_PRINTS _UxGT("Ukończono") + #define MSG_INFO_PRINT_TIME _UxGT("Razem") + #define MSG_INFO_PRINT_LONGEST _UxGT("Najdł. druk") + #define MSG_INFO_PRINT_FILAMENT _UxGT("Użyty fil.") +#endif + +#define MSG_INFO_MIN_TEMP _UxGT("Min Temp") +#define MSG_INFO_MAX_TEMP _UxGT("Max Temp") +#define MSG_INFO_PSU _UxGT("Zasilacz") + +#define MSG_DRIVE_STRENGTH _UxGT("Siła silnika") +#define MSG_DAC_PERCENT _UxGT("Siła %") +#define MSG_DAC_EEPROM_WRITE _UxGT("Zapisz DAC EEPROM") + +#define MSG_FILAMENT_CHANGE_HEADER _UxGT("ZMIEŃ FILAMENT") +#define MSG_FILAMENT_CHANGE_OPTION_HEADER _UxGT("ZMIEŃ OPCJE:") +#define MSG_FILAMENT_CHANGE_OPTION_EXTRUDE _UxGT("Ekstruduj więcej") +#define MSG_FILAMENT_CHANGE_OPTION_RESUME _UxGT("Wznów drukowanie") + +#if LCD_HEIGHT >= 4 + // Up to 3 lines allowed + #define MSG_FILAMENT_CHANGE_INIT_1 _UxGT("Czekam na ") + #define MSG_FILAMENT_CHANGE_INIT_2 _UxGT("zmianę filamentu") + #define MSG_FILAMENT_CHANGE_UNLOAD_1 _UxGT("Czekam na") + #define MSG_FILAMENT_CHANGE_UNLOAD_2 _UxGT("wyjęcie filamentu") + #define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("Włóz filament") + #define MSG_FILAMENT_CHANGE_INSERT_2 _UxGT("i naciśnij przycisk") + #define MSG_FILAMENT_CHANGE_INSERT_3 _UxGT("aby kontynuować...") + #define MSG_FILAMENT_CHANGE_LOAD_1 _UxGT("Czekam na") + #define MSG_FILAMENT_CHANGE_LOAD_2 _UxGT("włożenie filamentu") + #define MSG_FILAMENT_CHANGE_EXTRUDE_1 _UxGT("Czekam na") + #define MSG_FILAMENT_CHANGE_EXTRUDE_2 _UxGT("ekstruzję filamentu") + #define MSG_FILAMENT_CHANGE_RESUME_1 _UxGT("Czekam na") + #define MSG_FILAMENT_CHANGE_RESUME_2 _UxGT("wznowienie druku") +#else // LCD_HEIGHT < 4 + // Up to 2 lines allowed + #define MSG_FILAMENT_CHANGE_INIT_1 _UxGT("Proszę czekać...") + #define MSG_FILAMENT_CHANGE_UNLOAD_1 _UxGT("Wysuwanie...") + #define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("Włóż i naciśnij prz.") + #define MSG_FILAMENT_CHANGE_LOAD_1 _UxGT("Ładowanie...") + #define MSG_FILAMENT_CHANGE_EXTRUDE_1 _UxGT("Ekstruzja...") + #define MSG_FILAMENT_CHANGE_RESUME_1 _UxGT("Wznowienie...") +#endif // LCD_HEIGHT < 4 diff --git a/trunk/Arduino/Marlin_1.1.6/language_pl-HD44780.h b/trunk/Arduino/Marlin_1.1.6/language_pl-HD44780.h new file mode 100644 index 00000000..7c5ea083 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/language_pl-HD44780.h @@ -0,0 +1,265 @@ +/** + * 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 . + * + */ + +/** + * Polish for HD44780 display - no accented characters + */ + +#define WELCOME_MSG MACHINE_NAME _UxGT(" gotowy.") +#define MSG_SD_INSERTED _UxGT("Karta wlozona") +#define MSG_SD_REMOVED _UxGT("Karta usunieta") +#define MSG_LCD_ENDSTOPS _UxGT("Krancow.") // Max length 8 characters +#define MSG_MAIN _UxGT("Menu glowne") +#define MSG_AUTOSTART _UxGT("Autostart") +#define MSG_DISABLE_STEPPERS _UxGT("Wylacz silniki") +#define MSG_AUTO_HOME _UxGT("Pozycja zerowa") +#define MSG_AUTO_HOME_X _UxGT("Zeruj X") +#define MSG_AUTO_HOME_Y _UxGT("Zeruj Y") +#define MSG_AUTO_HOME_Z _UxGT("Zeruj Z") +#define MSG_LEVEL_BED _UxGT("Poziom. stolu") +#define MSG_LEVEL_BED_HOMING _UxGT("Pozycja zerowa") +#define MSG_LEVEL_BED_WAITING _UxGT("Kliknij by rozp.") +#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Nastepny punkt") +#define MSG_LEVEL_BED_DONE _UxGT("Wypoziomowano!") +#define MSG_SET_HOME_OFFSETS _UxGT("Ust. poz. zer.") +#define MSG_HOME_OFFSETS_APPLIED _UxGT("Poz. zerowa ust.") +#define MSG_SET_ORIGIN _UxGT("Ustaw punkt zero") +#define MSG_PREHEAT_1 _UxGT("Rozgrzej PLA") +#define MSG_PREHEAT_1_N MSG_PREHEAT_1 _UxGT(" ") +#define MSG_PREHEAT_1_ALL MSG_PREHEAT_1 _UxGT(" wsz.") +#define MSG_PREHEAT_1_BEDONLY _UxGT("Rozgrzej stol PLA") +#define MSG_PREHEAT_1_SETTINGS _UxGT("Ustaw. rozg. PLA") +#define MSG_PREHEAT_2 _UxGT("Rozgrzej ABS") +#define MSG_PREHEAT_2_N MSG_PREHEAT_2 _UxGT(" ") +#define MSG_PREHEAT_2_ALL MSG_PREHEAT_2 _UxGT(" wsz.") +#define MSG_PREHEAT_2_BEDONLY _UxGT("Rozgrzej stol ABS") +#define MSG_PREHEAT_2_SETTINGS _UxGT("Ustaw. rozg. ABS") +#define MSG_COOLDOWN _UxGT("Chlodzenie") +#define MSG_SWITCH_PS_ON _UxGT("Wlacz zasilacz") +#define MSG_SWITCH_PS_OFF _UxGT("Wylacz zasilacz") +#define MSG_EXTRUDE _UxGT("Ekstruzja") +#define MSG_RETRACT _UxGT("Wycofanie") +#define MSG_MOVE_AXIS _UxGT("Ruch osi") +#define MSG_BED_LEVELING _UxGT("Poziom. stolu") +#define MSG_MOVE_X _UxGT("Przesun w X") +#define MSG_MOVE_Y _UxGT("Przesun w Y") +#define MSG_MOVE_Z _UxGT("Przesun w Z") +#define MSG_MOVE_E _UxGT("Ekstruzja (os E)") +#define MSG_MOVE_01MM _UxGT("Przesun co .1mm") +#define MSG_MOVE_1MM _UxGT("Przesun co 1mm") +#define MSG_MOVE_10MM _UxGT("Przesun co 10mm") +#define MSG_SPEED _UxGT("Predkosc") +#define MSG_BED_Z _UxGT("Stol Z") +#define MSG_NOZZLE _UxGT("Dysza") +#define MSG_BED _UxGT("Stol") +#define MSG_FAN_SPEED _UxGT("Obroty wiatraka") +#define MSG_FLOW _UxGT("Przeplyw") +#define MSG_CONTROL _UxGT("Ustawienia") +#define MSG_MIN LCD_STR_THERMOMETER _UxGT(" Min") +#define MSG_MAX LCD_STR_THERMOMETER _UxGT(" Max") +#define MSG_FACTOR LCD_STR_THERMOMETER _UxGT(" Mnoznik") +#define MSG_AUTOTEMP _UxGT("Auto. temperatura") +#define MSG_ON _UxGT("Wl. ") +#define MSG_OFF _UxGT("Wyl.") +#define MSG_PID_P _UxGT("PID-P") +#define MSG_PID_I _UxGT("PID-I") +#define MSG_PID_D _UxGT("PID-D") +#define MSG_PID_C _UxGT("PID-C") +#define MSG_SELECT _UxGT("Select") +#define MSG_ACC _UxGT("Przyspieszenie") +#define MSG_JERK _UxGT("Zryw") +#define MSG_VX_JERK _UxGT("Zryw Vx") +#define MSG_VY_JERK _UxGT("Zryw Vy") +#define MSG_VZ_JERK _UxGT("Zryw Vz") +#define MSG_VE_JERK _UxGT("Zryw Ve") +#define MSG_VMAX _UxGT("Vmax ") +#define MSG_VMIN _UxGT("Vmin") +#define MSG_VTRAV_MIN _UxGT("Vskok min") +#define MSG_ACCELERATION MSG_ACC +#define MSG_AMAX _UxGT("Amax") +#define MSG_A_RETRACT _UxGT("A-wycofanie") +#define MSG_A_TRAVEL _UxGT("A-przesun.") +#define MSG_STEPS_PER_MM _UxGT("kroki/mm") +#define MSG_XSTEPS _UxGT("krokiX/mm") +#define MSG_YSTEPS _UxGT("krokiY/mm") +#define MSG_ZSTEPS _UxGT("krokiZ/mm") +#define MSG_ESTEPS _UxGT("krokiE/mm") +#define MSG_E1STEPS _UxGT("krokiE1/mm") +#define MSG_E2STEPS _UxGT("krokiE2/mm") +#define MSG_E3STEPS _UxGT("krokiE3/mm") +#define MSG_E4STEPS _UxGT("krokiE4/mm") +#define MSG_E5STEPS _UxGT("krokiE5/mm") +#define MSG_TEMPERATURE _UxGT("Temperatura") +#define MSG_MOTION _UxGT("Ruch") +#define MSG_FILAMENT _UxGT("Filament") +#define MSG_VOLUMETRIC_ENABLED _UxGT("E w mm3") +#define MSG_FILAMENT_DIAM _UxGT("Sr. fil.") +#define MSG_CONTRAST _UxGT("Kontrast LCD") +#define MSG_STORE_EEPROM _UxGT("Zapisz w pamieci") +#define MSG_LOAD_EEPROM _UxGT("Wczytaj z pamieci") +#define MSG_RESTORE_FAILSAFE _UxGT("Ustaw. fabryczne") +#define MSG_REFRESH _UxGT("Odswiez") +#define MSG_WATCH _UxGT("Ekran glowny") +#define MSG_PREPARE _UxGT("Przygotuj") +#define MSG_TUNE _UxGT("Strojenie") +#define MSG_PAUSE_PRINT _UxGT("Pauza") +#define MSG_RESUME_PRINT _UxGT("Wznowienie") +#define MSG_STOP_PRINT _UxGT("Stop") +#define MSG_CARD_MENU _UxGT("Karta SD") +#define MSG_NO_CARD _UxGT("Brak karty") +#define MSG_DWELL _UxGT("Uspij...") +#define MSG_USERWAIT _UxGT("Oczekiwanie...") +#define MSG_RESUMING _UxGT("Wznawianie druku") +#define MSG_PRINT_ABORTED _UxGT("Druk przerwany") +#define MSG_NO_MOVE _UxGT("Brak ruchu") +#define MSG_KILLED _UxGT("Ubity. ") +#define MSG_STOPPED _UxGT("Zatrzymany. ") +#define MSG_CONTROL_RETRACT _UxGT("Wycofaj mm") +#define MSG_CONTROL_RETRACT_SWAP _UxGT("Z Wycof. mm") +#define MSG_CONTROL_RETRACTF _UxGT("Wycofaj V") +#define MSG_CONTROL_RETRACT_ZLIFT _UxGT("Skok Z mm") +#define MSG_CONTROL_RETRACT_RECOVER _UxGT("Cof. wycof. mm") +#define MSG_CONTROL_RETRACT_RECOVER_SWAP _UxGT("Z Cof. wyc. mm") +#define MSG_CONTROL_RETRACT_RECOVERF _UxGT("Cof. wycof. V") +#define MSG_AUTORETRACT _UxGT("Auto. wycofanie") +#define MSG_FILAMENTCHANGE _UxGT("Zmien filament") +#define MSG_INIT_SDCARD _UxGT("Inicjal. karty SD") +#define MSG_CNG_SDCARD _UxGT("Zmiana karty SD") +#define MSG_ZPROBE_OUT _UxGT("Sonda Z za stolem") +#define MSG_BLTOUCH_SELFTEST _UxGT("BLTouch Self-Test") +#define MSG_BLTOUCH_RESET _UxGT("Reset BLTouch") +#define MSG_HOME _UxGT("Home") // Used as MSG_HOME " " MSG_X MSG_Y MSG_Z " " MSG_FIRST +#define MSG_FIRST _UxGT("first") +#define MSG_ZPROBE_ZOFFSET _UxGT("Offset Z") +#define MSG_BABYSTEP_X _UxGT("Babystep X") +#define MSG_BABYSTEP_Y _UxGT("Babystep Y") +#define MSG_BABYSTEP_Z _UxGT("Babystep Z") +#define MSG_ENDSTOP_ABORT _UxGT("Blad krancowki") +#define MSG_HEATING_FAILED_LCD _UxGT("Rozgrz. nieudane") +#define MSG_ERR_REDUNDANT_TEMP _UxGT("Blad temperatury") +#define MSG_THERMAL_RUNAWAY _UxGT("Zanik temp.") +#define MSG_ERR_MAXTEMP _UxGT("Err max temp") +#define MSG_ERR_MINTEMP _UxGT("Err min temp") +#define MSG_ERR_MAXTEMP_BED _UxGT("Err max temp stolu") +#define MSG_ERR_MINTEMP_BED _UxGT("Err min temp stolu") +#define MSG_ERR_Z_HOMING _UxGT("G28 Z Forbidden") +#define MSG_HALTED _UxGT("Drukarka zatrzym.") +#define MSG_PLEASE_RESET _UxGT("Prosze zresetowac") +#define MSG_SHORT_DAY _UxGT("d") // One character only +#define MSG_SHORT_HOUR _UxGT("g") // One character only +#define MSG_SHORT_MINUTE _UxGT("m") // One character only +#define MSG_HEATING _UxGT("Rozgrzewanie...") +#define MSG_HEATING_COMPLETE _UxGT("Rozgrzano") +#define MSG_BED_HEATING _UxGT("Rozgrzewanie stolu...") +#define MSG_BED_DONE _UxGT("Rozgrzano stol") +#define MSG_DELTA_CALIBRATE _UxGT("Kalibrowanie Delty") +#define MSG_DELTA_CALIBRATE_X _UxGT("Kalibruj X") +#define MSG_DELTA_CALIBRATE_Y _UxGT("Kalibruj Y") +#define MSG_DELTA_CALIBRATE_Z _UxGT("Kalibruj Z") +#define MSG_DELTA_CALIBRATE_CENTER _UxGT("Kalibruj srodek") + +#define MSG_INFO_MENU _UxGT("O drukarce") +#define MSG_INFO_PRINTER_MENU _UxGT("Info drukarki") +#define MSG_INFO_STATS_MENU _UxGT("Statystyki") +#define MSG_INFO_BOARD_MENU _UxGT("Board Info") +#define MSG_INFO_THERMISTOR_MENU _UxGT("Thermistory") +#define MSG_INFO_EXTRUDERS _UxGT("Ekstrudery") +#define MSG_INFO_BAUDRATE _UxGT("Predkosc USB") +#define MSG_INFO_PROTOCOL _UxGT("Protokol") +#define MSG_CASE_LIGHT _UxGT("Oswietlenie") + +#if LCD_WIDTH >= 20 + #define MSG_INFO_PRINT_COUNT _UxGT("Wydrukowano") + #define MSG_INFO_COMPLETED_PRINTS _UxGT("Ukonczono") + #define MSG_INFO_PRINT_TIME _UxGT("Czas druku") + #define MSG_INFO_PRINT_LONGEST _UxGT("Najdl. druk") + #define MSG_INFO_PRINT_FILAMENT _UxGT("Uzyty fil.") +#else + #define MSG_INFO_PRINT_COUNT _UxGT("Wydrukowano") + #define MSG_INFO_COMPLETED_PRINTS _UxGT("Ukonczono") + #define MSG_INFO_PRINT_TIME _UxGT("Razem") + #define MSG_INFO_PRINT_LONGEST _UxGT("Najdl. druk") + #define MSG_INFO_PRINT_FILAMENT _UxGT("Uzyty fil.") +#endif + +#define MSG_INFO_MIN_TEMP _UxGT("Min Temp") +#define MSG_INFO_MAX_TEMP _UxGT("Max Temp") +#define MSG_INFO_PSU _UxGT("Zasilacz") + +#define MSG_DRIVE_STRENGTH _UxGT("Sila silnika") +#define MSG_DAC_PERCENT _UxGT("Sila %") +#define MSG_DAC_EEPROM_WRITE _UxGT("Zapisz DAC EEPROM") + +#define MSG_FILAMENT_CHANGE_HEADER _UxGT("ZMIEN FILAMENT") +#define MSG_FILAMENT_CHANGE_OPTION_HEADER _UxGT("ZMIEN OPCJE:") +#define MSG_FILAMENT_CHANGE_OPTION_EXTRUDE _UxGT("Ekstruduj wiecej") +#define MSG_FILAMENT_CHANGE_OPTION_RESUME _UxGT("Wznow drukowanie") + +#if LCD_HEIGHT >= 4 + // Up to 3 lines allowed + #define MSG_FILAMENT_CHANGE_INIT_1 _UxGT("Czekam na ") + #define MSG_FILAMENT_CHANGE_INIT_2 _UxGT("zmiane filamentu") + #define MSG_FILAMENT_CHANGE_UNLOAD_1 _UxGT("Czekam na") + #define MSG_FILAMENT_CHANGE_UNLOAD_2 _UxGT("wyjecie filamentu") + #define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("Wloz filament") + #define MSG_FILAMENT_CHANGE_INSERT_2 _UxGT("i nacisnij przycisk") + #define MSG_FILAMENT_CHANGE_INSERT_3 _UxGT("aby kontynuowac...") + #define MSG_FILAMENT_CHANGE_LOAD_1 _UxGT("Czekam na") + #define MSG_FILAMENT_CHANGE_LOAD_2 _UxGT("wlozenie filamentu") + #define MSG_FILAMENT_CHANGE_EXTRUDE_1 _UxGT("Czekam na") + #define MSG_FILAMENT_CHANGE_EXTRUDE_2 _UxGT("ekstruzje filamentu") + #define MSG_FILAMENT_CHANGE_RESUME_1 _UxGT("Czekam na") + #define MSG_FILAMENT_CHANGE_RESUME_2 _UxGT("wznowienie druku") +#else // LCD_HEIGHT < 4 + // Up to 2 lines allowed + #define MSG_FILAMENT_CHANGE_INIT_1 _UxGT("Prosze czekac...") + #define MSG_FILAMENT_CHANGE_UNLOAD_1 _UxGT("Wysuwanie...") + #define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("Wloz i nacisnij prz.") + #define MSG_FILAMENT_CHANGE_LOAD_1 _UxGT("Ladowanie...") + #define MSG_FILAMENT_CHANGE_EXTRUDE_1 _UxGT("Ekstruzja...") + #define MSG_FILAMENT_CHANGE_RESUME_1 _UxGT("Wznowienie...") +#endif // LCD_HEIGHT < 4 + +#if LCD_HEIGHT >= 4 + // Up to 3 lines allowed + #define MSG_FILAMENT_CHANGE_INIT_1 _UxGT("Czekam na ") + #define MSG_FILAMENT_CHANGE_INIT_2 _UxGT("zmiane filamentu") + #define MSG_FILAMENT_CHANGE_UNLOAD_1 _UxGT("Czekam na") + #define MSG_FILAMENT_CHANGE_UNLOAD_2 _UxGT("wyjecie filamentu") + #define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("Wloz filament") + #define MSG_FILAMENT_CHANGE_INSERT_2 _UxGT("i nacisnij przycisk") + #define MSG_FILAMENT_CHANGE_INSERT_3 _UxGT("aby kontynuowac...") + #define MSG_FILAMENT_CHANGE_LOAD_1 _UxGT("Czekam na") + #define MSG_FILAMENT_CHANGE_LOAD_2 _UxGT("wlozenie filamentu") + #define MSG_FILAMENT_CHANGE_EXTRUDE_1 _UxGT("Czekam na") + #define MSG_FILAMENT_CHANGE_EXTRUDE_2 _UxGT("ekstruzje filamentu") + #define MSG_FILAMENT_CHANGE_RESUME_1 _UxGT("Czekam na") + #define MSG_FILAMENT_CHANGE_RESUME_2 _UxGT("wznowienie druku") +#else // LCD_HEIGHT < 4 + // Up to 2 lines allowed + #define MSG_FILAMENT_CHANGE_INIT_1 _UxGT("Prosze czekac...") + #define MSG_FILAMENT_CHANGE_UNLOAD_1 _UxGT("Wysuwanie...") + #define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("Wloz i nacisnij prz.") + #define MSG_FILAMENT_CHANGE_LOAD_1 _UxGT("Ladowanie...") + #define MSG_FILAMENT_CHANGE_EXTRUDE_1 _UxGT("Ekstruzja...") + #define MSG_FILAMENT_CHANGE_RESUME_1 _UxGT("Wznowienie...") +#endif // LCD_HEIGHT < 4 diff --git a/trunk/Arduino/Marlin_1.1.6/language_pl.h b/trunk/Arduino/Marlin_1.1.6/language_pl.h new file mode 100644 index 00000000..3bc79271 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/language_pl.h @@ -0,0 +1,45 @@ +/** + * 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 . + * + */ + +/** + * Polish + * + * LCD Menu Messages + * See also http://marlinfw.org/docs/development/lcd_language.html + * + */ +#ifndef LANGUAGE_PL_H +#define LANGUAGE_PL_H + +#define MAPPER_C3C4C5_PL +#define DISPLAY_CHARSET_ISO10646_PL + +/** + * One version with accented characters and one without + */ +#if ENABLED(DOGLCD) + #include "language_pl-DOGM.h" +#else + #include "language_pl-HD44780.h" +#endif + +#endif // LANGUAGE_PL_H diff --git a/trunk/Arduino/Marlin_1.1.6/language_pt-br.h b/trunk/Arduino/Marlin_1.1.6/language_pt-br.h new file mode 100644 index 00000000..fa92224f --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/language_pt-br.h @@ -0,0 +1,171 @@ +/** + * 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 . + * + */ + +/** + * Portuguese (Brazil) + * + * LCD Menu Messages + * See also http://marlinfw.org/docs/development/lcd_language.html + * + */ +#ifndef LANGUAGE_PT_BR_H +#define LANGUAGE_PT_BR_H + +#define DISPLAY_CHARSET_ISO10646_1 + +#define WELCOME_MSG MACHINE_NAME " pronto." +#define MSG_SD_INSERTED "Cartao inserido" +#define MSG_SD_REMOVED "Cartao removido" +#define MSG_MAIN "Menu principal" +#define MSG_AUTOSTART "Autostart" +#define MSG_DISABLE_STEPPERS "Desabi. motores" +#define MSG_AUTO_HOME "Ir para origen" +#define MSG_LEVEL_BED_HOMING "Homing XYZ" +#define MSG_LEVEL_BED_WAITING "Click to Begin" +#define MSG_LEVEL_BED_DONE "Leveling Done!" +#define MSG_SET_HOME_OFFSETS "Ajustar Jogo" +#define MSG_HOME_OFFSETS_APPLIED "Offsets applied" +#define MSG_SET_ORIGIN "Ajustar orig." +#define MSG_PREHEAT_1 "Pre-aquecer PLA" +#define MSG_PREHEAT_1_N "Pre-aquecer PLA" +#define MSG_PREHEAT_1_ALL "Pre-aq.Todo PLA" +#define MSG_PREHEAT_1_BEDONLY "Pre-aq. PLA " LCD_STR_THERMOMETER "Base" +#define MSG_PREHEAT_1_SETTINGS "Ajustar PLA" +#define MSG_PREHEAT_2 "Pre-aquecer ABS" +#define MSG_PREHEAT_2_N "Pre-aquecer ABS" +#define MSG_PREHEAT_2_ALL "Pre-aq.Todo ABS" +#define MSG_PREHEAT_2_BEDONLY "Pre-aq. ABS " LCD_STR_THERMOMETER "Base" +#define MSG_PREHEAT_2_SETTINGS "Ajustar ABS" +#define MSG_COOLDOWN "Esfriar" +#define MSG_SWITCH_PS_ON "Ligar" +#define MSG_SWITCH_PS_OFF "Desligar" +#define MSG_EXTRUDE "Extrudar" +#define MSG_RETRACT "Retrair" +#define MSG_MOVE_AXIS "Mover eixo" +#define MSG_MOVE_X "Mover X" +#define MSG_MOVE_Y "Mover Y" +#define MSG_MOVE_Z "Mover Z" +#define MSG_MOVE_E "Mover Extrusor" +#define MSG_MOVE_01MM "Mover 0.1mm" +#define MSG_MOVE_1MM "Mover 1mm" +#define MSG_MOVE_10MM "Mover 10mm" +#define MSG_SPEED "Velocidade" +#define MSG_BED_Z "Base Z" +#define MSG_NOZZLE LCD_STR_THERMOMETER " Bocal" +#define MSG_BED LCD_STR_THERMOMETER " Base" +#define MSG_FAN_SPEED "Vel. Ventoinha" +#define MSG_FLOW "Fluxo" +#define MSG_CONTROL "Controle" +#define MSG_MIN LCD_STR_THERMOMETER " Min" +#define MSG_MAX LCD_STR_THERMOMETER " Max" +#define MSG_FACTOR LCD_STR_THERMOMETER " Fact" +#define MSG_AUTOTEMP "Temp. Automatica" +#define MSG_ON "Ligado " +#define MSG_OFF "Desligado" +#define MSG_PID_P "PID-P" +#define MSG_PID_I "PID-I" +#define MSG_PID_D "PID-D" +#define MSG_PID_C "PID-C" +#define MSG_ACC "Acc" +#define MSG_JERK "Jogo" +#define MSG_VX_JERK "jogo VX" +#define MSG_VY_JERK "jogo VY" +#define MSG_VZ_JERK "jogo VZ" +#define MSG_VE_JERK "jogo VE" +#define MSG_VMAX " Vmax " +#define MSG_VMIN "Vmin" +#define MSG_VTRAV_MIN "VTrav min" +#define MSG_AMAX "Amax " +#define MSG_A_RETRACT "Retrair A" +#define MSG_A_TRAVEL "A-movimento" +#define MSG_STEPS_PER_MM "Passo/mm" +#define MSG_XSTEPS "Passo X/mm" +#define MSG_YSTEPS "Passo Y/mm" +#define MSG_ZSTEPS "Passo Z/mm" +#define MSG_ESTEPS "E/mm" +#define MSG_E1STEPS "E1/mm" +#define MSG_E2STEPS "E2/mm" +#define MSG_E3STEPS "E3/mm" +#define MSG_E4STEPS "E4/mm" +#define MSG_E5STEPS "E5/mm" +#define MSG_TEMPERATURE "Temperatura" +#define MSG_MOTION "Movimento" +#define MSG_FILAMENT "Filamento" +#define MSG_VOLUMETRIC_ENABLED "Extr. em mm3" +#define MSG_FILAMENT_DIAM "Diametro Fil." +#define MSG_CONTRAST "Contraste" +#define MSG_STORE_EEPROM "Salvar" +#define MSG_LOAD_EEPROM "Ler" +#define MSG_RESTORE_FAILSAFE "Rest. de emerg." +#define MSG_REFRESH LCD_STR_REFRESH " Restaurar" +#define MSG_WATCH "Monitorar" +#define MSG_PREPARE "Preparar" +#define MSG_TUNE "Afinar" +#define MSG_PAUSE_PRINT "Pausar impressao" +#define MSG_RESUME_PRINT "Resumir impressao" +#define MSG_STOP_PRINT "Parar impressao" +#define MSG_CARD_MENU "Imprimir do SD" +#define MSG_NO_CARD "Sem cartao SD" +#define MSG_DWELL "Repouso..." +#define MSG_USERWAIT "Esperando ordem" +#define MSG_RESUMING "Resumindo Impres." +#define MSG_PRINT_ABORTED "Impres. Abortada." +#define MSG_NO_MOVE "Sem movimento" +#define MSG_KILLED "PARADA DE EMERG." +#define MSG_STOPPED "PARADA. " +#define MSG_CONTROL_RETRACT "Retrair mm" +#define MSG_CONTROL_RETRACT_SWAP "Retrair Troca mm" +#define MSG_CONTROL_RETRACTF "Retrair V" +#define MSG_CONTROL_RETRACT_ZLIFT "Levantar mm" +#define MSG_CONTROL_RETRACT_RECOVER "Des Retrair mm" +#define MSG_CONTROL_RETRACT_RECOVER_SWAP "Des RetTroca mm" +#define MSG_CONTROL_RETRACT_RECOVERF "Des Retrair V" +#define MSG_AUTORETRACT "Retracao Autom." +#define MSG_FILAMENTCHANGE "Trocar Filamento" +#define MSG_INIT_SDCARD "Iniciar SD" +#define MSG_CNG_SDCARD "Trocar SD" +#define MSG_ZPROBE_OUT "Son. fora da mesa" +#define MSG_HOME "Home" // Used as MSG_HOME " " MSG_X MSG_Y MSG_Z " " MSG_FIRST +#define MSG_FIRST "first" +#define MSG_ZPROBE_ZOFFSET "Deslocamento no Z" +#define MSG_BABYSTEP_X "Passinho X" +#define MSG_BABYSTEP_Y "Passinho Y" +#define MSG_BABYSTEP_Z "Passinho Z" +#define MSG_ENDSTOP_ABORT "Fim de Curso" +#define MSG_HEATING_FAILED_LCD "Aquecimento falhou" +#define MSG_ERR_REDUNDANT_TEMP "Err: REDUNDANT TEMP" +#define MSG_THERMAL_RUNAWAY "THERMAL RUNAWAY" +#define MSG_ERR_MAXTEMP "Err: T Maxima" +#define MSG_ERR_MINTEMP "Err: T Minima" +#define MSG_ERR_MAXTEMP_BED "Err: T Base Maxima" +#define MSG_ERR_MINTEMP_BED "Err: T Base Minima" +#define MSG_HEATING "Aquecendo..." +#define MSG_HEATING_COMPLETE "Aquecida." +#define MSG_BED_HEATING "Aquecendo base.." +#define MSG_BED_DONE "Base aquecida." +#define MSG_DELTA_CALIBRATE "Calibrar Delta" +#define MSG_DELTA_CALIBRATE_X "Calibrar X" +#define MSG_DELTA_CALIBRATE_Y "Calibrar Y" +#define MSG_DELTA_CALIBRATE_Z "Calibrar Z" +#define MSG_DELTA_CALIBRATE_CENTER "Calibrar Centro" + +#endif // LANGUAGE_PT_BR_H diff --git a/trunk/Arduino/Marlin_1.1.6/language_pt-br_utf8.h b/trunk/Arduino/Marlin_1.1.6/language_pt-br_utf8.h new file mode 100644 index 00000000..9c4c9d79 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/language_pt-br_utf8.h @@ -0,0 +1,172 @@ +/** + * 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 . + * + */ + +/** + * Portuguese (Brazil) + * UTF-8 for Graphical Display + * + * LCD Menu Messages + * See also http://marlinfw.org/docs/development/lcd_language.html + * + */ +#ifndef LANGUAGE_PT_BR_UTF_H +#define LANGUAGE_PT_BR_UTF_H + +#define DISPLAY_CHARSET_ISO10646_1 + +#define WELCOME_MSG MACHINE_NAME _UxGT(" pronto.") +#define MSG_SD_INSERTED _UxGT("Cartão inserido") +#define MSG_SD_REMOVED _UxGT("Cartão removido") +#define MSG_MAIN _UxGT("Menu principal") +#define MSG_AUTOSTART _UxGT("Autostart") +#define MSG_DISABLE_STEPPERS _UxGT("Desabi. motores") +#define MSG_AUTO_HOME _UxGT("Ir para origen") +#define MSG_LEVEL_BED_HOMING _UxGT("Indo para origem") +#define MSG_LEVEL_BED_WAITING _UxGT("Click to Begin") +#define MSG_LEVEL_BED_DONE _UxGT("Leveling Done!") +#define MSG_SET_HOME_OFFSETS _UxGT("Ajustar Jogo") +#define MSG_HOME_OFFSETS_APPLIED _UxGT("Offsets applied") +#define MSG_SET_ORIGIN _UxGT("Ajustar orig.") +#define MSG_PREHEAT_1 _UxGT("Pre-aquecer PLA") +#define MSG_PREHEAT_1_N _UxGT("Pre-aquecer PLA") +#define MSG_PREHEAT_1_ALL _UxGT("Pre-aq.Todo PLA") +#define MSG_PREHEAT_1_BEDONLY _UxGT("Pre-aq. PLA ") LCD_STR_THERMOMETER _UxGT("Base") +#define MSG_PREHEAT_1_SETTINGS _UxGT("Ajustar PLA") +#define MSG_PREHEAT_2 _UxGT("Pre-aquecer ABS") +#define MSG_PREHEAT_2_N _UxGT("Pre-aquecer ABS") +#define MSG_PREHEAT_2_ALL _UxGT("Pre-aq.Todo ABS") +#define MSG_PREHEAT_2_BEDONLY _UxGT("Pre-aq. ABS ") LCD_STR_THERMOMETER _UxGT("Base") +#define MSG_PREHEAT_2_SETTINGS _UxGT("Ajustar ABS") +#define MSG_COOLDOWN _UxGT("Esfriar") +#define MSG_SWITCH_PS_ON _UxGT("Ligar") +#define MSG_SWITCH_PS_OFF _UxGT("Desligar") +#define MSG_EXTRUDE _UxGT("Extrudar") +#define MSG_RETRACT _UxGT("Retrair") +#define MSG_MOVE_AXIS _UxGT("Mover eixo") +#define MSG_MOVE_X _UxGT("Mover X") +#define MSG_MOVE_Y _UxGT("Mover Y") +#define MSG_MOVE_Z _UxGT("Mover Z") +#define MSG_MOVE_E _UxGT("Mover Extrusor") +#define MSG_MOVE_01MM _UxGT("Mover 0.1mm") +#define MSG_MOVE_1MM _UxGT("Mover 1mm") +#define MSG_MOVE_10MM _UxGT("Mover 10mm") +#define MSG_SPEED _UxGT("Velocidade") +#define MSG_BED_Z _UxGT("Base Z") +#define MSG_NOZZLE LCD_STR_THERMOMETER _UxGT(" Bocal") +#define MSG_BED LCD_STR_THERMOMETER _UxGT(" Base") +#define MSG_FAN_SPEED _UxGT("Vel. Ventoinha") +#define MSG_FLOW _UxGT("Fluxo") +#define MSG_CONTROL _UxGT("Controle") +#define MSG_MIN LCD_STR_THERMOMETER _UxGT(" Min") +#define MSG_MAX LCD_STR_THERMOMETER _UxGT(" Max") +#define MSG_FACTOR LCD_STR_THERMOMETER _UxGT(" Fact") +#define MSG_AUTOTEMP _UxGT("Temp. Automática") +#define MSG_ON _UxGT("Ligado ") +#define MSG_OFF _UxGT("Desligado") +#define MSG_PID_P _UxGT("PID-P") +#define MSG_PID_I _UxGT("PID-I") +#define MSG_PID_D _UxGT("PID-D") +#define MSG_PID_C _UxGT("PID-C") +#define MSG_ACC _UxGT("Acc") +#define MSG_JERK _UxGT("Jogo") +#define MSG_VX_JERK _UxGT("jogo VX") +#define MSG_VY_JERK _UxGT("jogo VY") +#define MSG_VZ_JERK _UxGT("jogo VZ") +#define MSG_VE_JERK _UxGT("jogo VE") +#define MSG_VMAX _UxGT(" Vmax ") +#define MSG_VMIN _UxGT("Vmin") +#define MSG_VTRAV_MIN _UxGT("VTrav min") +#define MSG_AMAX _UxGT("Amax ") +#define MSG_A_RETRACT _UxGT("Retrair A") +#define MSG_A_TRAVEL _UxGT("A-movimento") +#define MSG_STEPS_PER_MM _UxGT("Passo/mm") +#define MSG_XSTEPS _UxGT("Passo X/mm") +#define MSG_YSTEPS _UxGT("Passo Y/mm") +#define MSG_ZSTEPS _UxGT("Passo Z/mm") +#define MSG_ESTEPS _UxGT("E/mm") +#define MSG_E1STEPS _UxGT("E1/mm") +#define MSG_E2STEPS _UxGT("E2/mm") +#define MSG_E3STEPS _UxGT("E3/mm") +#define MSG_E4STEPS _UxGT("E4/mm") +#define MSG_E5STEPS _UxGT("E5/mm") +#define MSG_TEMPERATURE _UxGT("Temperatura") +#define MSG_MOTION _UxGT("Movimento") +#define MSG_FILAMENT _UxGT("Filamento") +#define MSG_VOLUMETRIC_ENABLED _UxGT("Extr. em mm3") +#define MSG_FILAMENT_DIAM _UxGT("Diametro Fil.") +#define MSG_CONTRAST _UxGT("Contraste") +#define MSG_STORE_EEPROM _UxGT("Salvar") +#define MSG_LOAD_EEPROM _UxGT("Ler") +#define MSG_RESTORE_FAILSAFE _UxGT("Rest. de emerg.") +#define MSG_REFRESH LCD_STR_REFRESH _UxGT(" Restaurar") +#define MSG_WATCH _UxGT("Monitorar") +#define MSG_PREPARE _UxGT("Preparar") +#define MSG_TUNE _UxGT("Afinar") +#define MSG_PAUSE_PRINT _UxGT("Pausar impressão") +#define MSG_RESUME_PRINT _UxGT("Resumir impressão") +#define MSG_STOP_PRINT _UxGT("Parar impressão") +#define MSG_CARD_MENU _UxGT("Imprimir do SD") +#define MSG_NO_CARD _UxGT("Sem cartão SD") +#define MSG_DWELL _UxGT("Repouso...") +#define MSG_USERWAIT _UxGT("Esperando ordem") +#define MSG_RESUMING _UxGT("Resumindo Impres.") +#define MSG_PRINT_ABORTED _UxGT("Impres. Abortada.") +#define MSG_NO_MOVE _UxGT("Sem movimento") +#define MSG_KILLED _UxGT("PARADA DE EMERG.") +#define MSG_STOPPED _UxGT("PARADA. ") +#define MSG_CONTROL_RETRACT _UxGT("Retrair mm") +#define MSG_CONTROL_RETRACT_SWAP _UxGT("Retrair Troca mm") +#define MSG_CONTROL_RETRACTF _UxGT("Retrair V") +#define MSG_CONTROL_RETRACT_ZLIFT _UxGT("Levantar mm") +#define MSG_CONTROL_RETRACT_RECOVER _UxGT("Des Retrair mm") +#define MSG_CONTROL_RETRACT_RECOVER_SWAP _UxGT("Des RetTroca mm") +#define MSG_CONTROL_RETRACT_RECOVERF _UxGT("Des Retrair V") +#define MSG_AUTORETRACT _UxGT("Retração Autom.") +#define MSG_FILAMENTCHANGE _UxGT("Trocar Filamento") +#define MSG_INIT_SDCARD _UxGT("Iniciar SD") +#define MSG_CNG_SDCARD _UxGT("Trocar SD") +#define MSG_ZPROBE_OUT _UxGT("Son. fora da mesa") +#define MSG_HOME _UxGT("Home") // Used as MSG_HOME " " MSG_X MSG_Y MSG_Z " " MSG_FIRST +#define MSG_FIRST _UxGT("first") +#define MSG_ZPROBE_ZOFFSET _UxGT("Deslocamento no Z") +#define MSG_BABYSTEP_X _UxGT("Passinho X") +#define MSG_BABYSTEP_Y _UxGT("Passinho Y") +#define MSG_BABYSTEP_Z _UxGT("Passinho Z") +#define MSG_ENDSTOP_ABORT _UxGT("Fim de Curso") +#define MSG_HEATING_FAILED_LCD _UxGT("Aquecimento falhou") +#define MSG_ERR_REDUNDANT_TEMP _UxGT("Err: REDUNDANT TEMP") +#define MSG_THERMAL_RUNAWAY _UxGT("THERMAL RUNAWAY") +#define MSG_ERR_MAXTEMP _UxGT("Err: T Máxima") +#define MSG_ERR_MINTEMP _UxGT("Err: T Mínima") +#define MSG_ERR_MAXTEMP_BED _UxGT("Err: T Base Máxima") +#define MSG_ERR_MINTEMP_BED _UxGT("Err: T Base Mínima") +#define MSG_HEATING _UxGT("Aquecendo...") +#define MSG_HEATING_COMPLETE _UxGT("Aquecida.") +#define MSG_BED_HEATING _UxGT("Aquecendo base..") +#define MSG_BED_DONE _UxGT("Base aquecida.") +#define MSG_DELTA_CALIBRATE _UxGT("Calibrar Delta") +#define MSG_DELTA_CALIBRATE_X _UxGT("Calibrar X") +#define MSG_DELTA_CALIBRATE_Y _UxGT("Calibrar Y") +#define MSG_DELTA_CALIBRATE_Z _UxGT("Calibrar Z") +#define MSG_DELTA_CALIBRATE_CENTER _UxGT("Calibrar Centro") + +#endif // LANGUAGE_PT_BR_UTF_H diff --git a/trunk/Arduino/Marlin_1.1.6/language_pt.h b/trunk/Arduino/Marlin_1.1.6/language_pt.h new file mode 100644 index 00000000..06c46848 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/language_pt.h @@ -0,0 +1,177 @@ +/** + * 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 . + * + */ + +/** + * Portuguese + * + * LCD Menu Messages + * See also http://marlinfw.org/docs/development/lcd_language.html + * + */ +#ifndef LANGUAGE_PT_H +#define LANGUAGE_PT_H + +#define DISPLAY_CHARSET_ISO10646_1 + +#define WELCOME_MSG MACHINE_NAME " pronto." +#define MSG_SD_INSERTED "Cartao inserido" +#define MSG_SD_REMOVED "Cartao removido" +#define MSG_MAIN "Menu principal" +#define MSG_AUTOSTART "Autostart" +#define MSG_DISABLE_STEPPERS "Desactivar motores" +#define MSG_AUTO_HOME "Ir para origem" +#define MSG_AUTO_HOME_X "Ir para origem X" +#define MSG_AUTO_HOME_Y "Ir para origem Y" +#define MSG_AUTO_HOME_Z "Ir para origem Z" +#define MSG_LEVEL_BED_HOMING "Indo para origem" +#define MSG_LEVEL_BED_WAITING "Click para iniciar" +#define MSG_LEVEL_BED_NEXT_POINT "Proximo ponto" +#define MSG_LEVEL_BED_DONE "Pronto !" +#define MSG_SET_HOME_OFFSETS "Definir desvio" +#define MSG_HOME_OFFSETS_APPLIED "Offsets applied" +#define MSG_SET_ORIGIN "Definir origem" +#define MSG_PREHEAT_1 "Pre-aquecer PLA" +#define MSG_PREHEAT_1_N "Pre-aquecer PLA" +#define MSG_PREHEAT_1_ALL "Pre-aq. PLA Tudo" +#define MSG_PREHEAT_1_BEDONLY "Pre-aq. PLA " LCD_STR_THERMOMETER "Base" +#define MSG_PREHEAT_1_SETTINGS "Definicoes PLA" +#define MSG_PREHEAT_2 "Pre-aquecer ABS" +#define MSG_PREHEAT_2_N "Pre-aquecer ABS " +#define MSG_PREHEAT_2_ALL "Pre-aq. ABS Tudo" +#define MSG_PREHEAT_2_BEDONLY "Pre-aq. ABS " LCD_STR_THERMOMETER "Base" +#define MSG_PREHEAT_2_SETTINGS "Definicoes ABS" +#define MSG_COOLDOWN "Arrefecer" +#define MSG_SWITCH_PS_ON "Ligar" +#define MSG_SWITCH_PS_OFF "Desligar" +#define MSG_EXTRUDE "Extrudir" +#define MSG_RETRACT "Retrair" +#define MSG_MOVE_AXIS "Mover eixo" +#define MSG_MOVE_X "Mover X" +#define MSG_MOVE_Y "Mover Y" +#define MSG_MOVE_Z "Mover Z" +#define MSG_MOVE_E "Mover Extrusor" +#define MSG_MOVE_01MM "Mover 0.1mm" +#define MSG_MOVE_1MM "Mover 1mm" +#define MSG_MOVE_10MM "Mover 10mm" +#define MSG_SPEED "Velocidade" +#define MSG_BED_Z "Base Z" +#define MSG_NOZZLE LCD_STR_THERMOMETER " Bico" +#define MSG_BED LCD_STR_THERMOMETER " Base" +#define MSG_FAN_SPEED "Vel. ventoinha" +#define MSG_FLOW "Fluxo" +#define MSG_CONTROL "Controlo" +#define MSG_MIN LCD_STR_THERMOMETER " Min" +#define MSG_MAX LCD_STR_THERMOMETER " Max" +#define MSG_FACTOR LCD_STR_THERMOMETER " Fact" +#define MSG_AUTOTEMP "Temp. Automatica" +#define MSG_ON "On " +#define MSG_OFF "Off" +#define MSG_PID_P "PID-P" +#define MSG_PID_I "PID-I" +#define MSG_PID_D "PID-D" +#define MSG_PID_C "PID-C" +#define MSG_ACC "Acc" +#define MSG_JERK _UxGT("Jerk") +#define MSG_VX_JERK "Vx-jerk" +#define MSG_VY_JERK "Vy-jerk" +#define MSG_VZ_JERK "Vz-jerk" +#define MSG_VE_JERK "Ve-jerk" +#define MSG_VMAX " Vmax " +#define MSG_VMIN "Vmin" +#define MSG_VTRAV_MIN "VTrav min" +#define MSG_AMAX "Amax " +#define MSG_A_RETRACT "A-retraccao" +#define MSG_A_TRAVEL "A-movimento" +#define MSG_STEPS_PER_MM "Passo/mm" +#define MSG_XSTEPS "X passo/mm" +#define MSG_YSTEPS "Y passo/mm" +#define MSG_ZSTEPS "Z passo/mm" +#define MSG_ESTEPS "E passo/mm" +#define MSG_E1STEPS "E1 passo/mm" +#define MSG_E2STEPS "E2 passo/mm" +#define MSG_E3STEPS "E3 passo/mm" +#define MSG_E4STEPS "E4 passo/mm" +#define MSG_E5STEPS "E5 passo/mm" +#define MSG_TEMPERATURE "Temperatura" +#define MSG_MOTION "Movimento" +#define MSG_FILAMENT "Filamento" +#define MSG_VOLUMETRIC_ENABLED "E em mm3" +#define MSG_FILAMENT_DIAM "Fil. Diam." +#define MSG_CONTRAST "Contraste" +#define MSG_STORE_EEPROM "Guardar na memoria" +#define MSG_LOAD_EEPROM "Carregar da memoria" +#define MSG_RESTORE_FAILSAFE "Rest. de emergen." +#define MSG_REFRESH LCD_STR_REFRESH " Recarregar" +#define MSG_WATCH "Monitorizar" +#define MSG_PREPARE "Preparar" +#define MSG_TUNE "Afinar" +#define MSG_PAUSE_PRINT "Pausar impressao" +#define MSG_RESUME_PRINT "Retomar impressao" +#define MSG_STOP_PRINT "Parar impressao" +#define MSG_CARD_MENU "Imprimir do SD" +#define MSG_NO_CARD "Sem cartao SD" +#define MSG_DWELL "Em espera..." +#define MSG_USERWAIT "A espera de ordem" +#define MSG_RESUMING "Retomando impressao" +#define MSG_PRINT_ABORTED "Impressao cancelada" +#define MSG_NO_MOVE "Sem movimento" +#define MSG_KILLED "EMERGENCIA. " +#define MSG_STOPPED "PARADO. " +#define MSG_CONTROL_RETRACT " Retrair mm" +#define MSG_CONTROL_RETRACT_SWAP "Troca Retrair mm" +#define MSG_CONTROL_RETRACTF " Retrair V" +#define MSG_CONTROL_RETRACT_ZLIFT " Levantar mm" +#define MSG_CONTROL_RETRACT_RECOVER " DesRet mm" +#define MSG_CONTROL_RETRACT_RECOVER_SWAP "Troca DesRet mm" +#define MSG_CONTROL_RETRACT_RECOVERF " DesRet V" +#define MSG_AUTORETRACT " AutoRetr." +#define MSG_FILAMENTCHANGE "Trocar filamento" +#define MSG_INIT_SDCARD "Inici. cartao SD" +#define MSG_CNG_SDCARD "Trocar cartao SD" +#define MSG_ZPROBE_OUT "Sensor fora/base" +#define MSG_HOME "Home" // Used as MSG_HOME " " MSG_X MSG_Y MSG_Z " " MSG_FIRST +#define MSG_FIRST "first" +#define MSG_ZPROBE_ZOFFSET "Desvio Z" +#define MSG_BABYSTEP_X "Babystep X" +#define MSG_BABYSTEP_Y "Babystep Y" +#define MSG_BABYSTEP_Z "Babystep Z" +#define MSG_ENDSTOP_ABORT "Fim de curso" +#define MSG_HEATING_FAILED_LCD "Aquecimento falhou" +#define MSG_ERR_REDUNDANT_TEMP "Err: REDUNDANT TEMP" +#define MSG_THERMAL_RUNAWAY "THERMAL RUNAWAY" +#define MSG_ERR_MAXTEMP "Err: T Maxima" +#define MSG_ERR_MINTEMP "Err: T Minima" +#define MSG_ERR_MAXTEMP_BED "Err: T Base Maxima" +#define MSG_ERR_MINTEMP_BED "Err: T Base Minima" +#define MSG_HEATING "Aquecendo..." +#define MSG_HEATING_COMPLETE "Aquecida." +#define MSG_BED_HEATING "Aquecendo base.." +#define MSG_BED_DONE "Base aquecida." +#define MSG_DELTA_CALIBRATE "Calibracao Delta" +#define MSG_DELTA_CALIBRATE_X "Calibrar X" +#define MSG_DELTA_CALIBRATE_Y "Calibrar Y" +#define MSG_DELTA_CALIBRATE_Z "Calibrar Z" +#define MSG_DELTA_CALIBRATE_CENTER "Calibrar Centro" + +#define MSG_LCD_ENDSTOPS "Fim de curso" + +#endif // LANGUAGE_PT_H diff --git a/trunk/Arduino/Marlin_1.1.6/language_pt_utf8.h b/trunk/Arduino/Marlin_1.1.6/language_pt_utf8.h new file mode 100644 index 00000000..4d18ae82 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/language_pt_utf8.h @@ -0,0 +1,178 @@ +/** + * 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 . + * + */ + +/** + * Portuguese + * UTF-8 for Graphical Display + * + * LCD Menu Messages + * See also http://marlinfw.org/docs/development/lcd_language.html + * + */ +#ifndef LANGUAGE_PT_UTF_H +#define LANGUAGE_PT_UTF_H + +#define DISPLAY_CHARSET_ISO10646_1 + +#define WELCOME_MSG MACHINE_NAME _UxGT(" pronto.") +#define MSG_SD_INSERTED _UxGT("Cartão inserido") +#define MSG_SD_REMOVED _UxGT("Cartão removido") +#define MSG_MAIN _UxGT("Menu principal") +#define MSG_AUTOSTART _UxGT("Autostart") +#define MSG_DISABLE_STEPPERS _UxGT("Desactivar motores") +#define MSG_AUTO_HOME _UxGT("Ir para origem") +#define MSG_AUTO_HOME_X _UxGT("Ir para origem X") +#define MSG_AUTO_HOME_Y _UxGT("Ir para origem Y") +#define MSG_AUTO_HOME_Z _UxGT("Ir para origem Z") +#define MSG_LEVEL_BED_HOMING _UxGT("Indo para origem") +#define MSG_LEVEL_BED_WAITING _UxGT("Click para iniciar") +#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Próximo ponto") +#define MSG_LEVEL_BED_DONE _UxGT("Pronto !") +#define MSG_SET_HOME_OFFSETS _UxGT("Definir desvio") +#define MSG_HOME_OFFSETS_APPLIED _UxGT("Offsets aplicados") +#define MSG_SET_ORIGIN _UxGT("Definir origem") +#define MSG_PREHEAT_1 _UxGT("Pre-aquecer PLA") +#define MSG_PREHEAT_1_N _UxGT("Pre-aquecer PLA") +#define MSG_PREHEAT_1_ALL _UxGT("Pre-aq. PLA Tudo") +#define MSG_PREHEAT_1_BEDONLY _UxGT("Pre-aq. PLA ") LCD_STR_THERMOMETER _UxGT("Base") +#define MSG_PREHEAT_1_SETTINGS _UxGT("Definições PLA") +#define MSG_PREHEAT_2 _UxGT("Pre-aquecer ABS") +#define MSG_PREHEAT_2_N _UxGT("Pre-aquecer ABS ") +#define MSG_PREHEAT_2_ALL _UxGT("Pre-aq. ABS Tudo") +#define MSG_PREHEAT_2_BEDONLY _UxGT("Pre-aq. ABS ") LCD_STR_THERMOMETER _UxGT("Base") +#define MSG_PREHEAT_2_SETTINGS _UxGT("Definições ABS") +#define MSG_COOLDOWN _UxGT("Arrefecer") +#define MSG_SWITCH_PS_ON _UxGT("Ligar") +#define MSG_SWITCH_PS_OFF _UxGT("Desligar") +#define MSG_EXTRUDE _UxGT("Extrudir") +#define MSG_RETRACT _UxGT("Retrair") +#define MSG_MOVE_AXIS _UxGT("Mover eixo") +#define MSG_MOVE_X _UxGT("Mover X") +#define MSG_MOVE_Y _UxGT("Mover Y") +#define MSG_MOVE_Z _UxGT("Mover Z") +#define MSG_MOVE_E _UxGT("Mover Extrusor") +#define MSG_MOVE_01MM _UxGT("Mover 0.1mm") +#define MSG_MOVE_1MM _UxGT("Mover 1mm") +#define MSG_MOVE_10MM _UxGT("Mover 10mm") +#define MSG_SPEED _UxGT("Velocidade") +#define MSG_BED_Z _UxGT("Base Z") +#define MSG_NOZZLE _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" Bico") +#define MSG_BED _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" Base") +#define MSG_FAN_SPEED _UxGT("Vel. ventoinha") +#define MSG_FLOW _UxGT("Fluxo") +#define MSG_CONTROL _UxGT("Controlo") +#define MSG_MIN _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" Min") +#define MSG_MAX _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" Max") +#define MSG_FACTOR _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" Fact") +#define MSG_AUTOTEMP _UxGT("Temp. Automática") +#define MSG_ON _UxGT("On ") +#define MSG_OFF _UxGT("Off") +#define MSG_PID_P _UxGT("PID-P") +#define MSG_PID_I _UxGT("PID-I") +#define MSG_PID_D _UxGT("PID-D") +#define MSG_PID_C _UxGT("PID-C") +#define MSG_ACC _UxGT("Acc") +#define MSG_JERK _UxGT("Jerk") +#define MSG_VX_JERK _UxGT("Vx-jerk") +#define MSG_VY_JERK _UxGT("Vy-jerk") +#define MSG_VZ_JERK _UxGT("Vz-jerk") +#define MSG_VE_JERK _UxGT("Ve-jerk") +#define MSG_VMAX _UxGT(" Vmax ") +#define MSG_VMIN _UxGT("Vmin") +#define MSG_VTRAV_MIN _UxGT("VTrav min") +#define MSG_AMAX _UxGT("Amax ") +#define MSG_A_RETRACT _UxGT("A-retracção") +#define MSG_A_TRAVEL _UxGT("A-movimento") +#define MSG_STEPS_PER_MM _UxGT("Passo/mm") +#define MSG_XSTEPS _UxGT("X passo/mm") +#define MSG_YSTEPS _UxGT("Y passo/mm") +#define MSG_ZSTEPS _UxGT("Z passo/mm") +#define MSG_ESTEPS _UxGT("E passo/mm") +#define MSG_E1STEPS _UxGT("E1 passo/mm") +#define MSG_E2STEPS _UxGT("E2 passo/mm") +#define MSG_E3STEPS _UxGT("E3 passo/mm") +#define MSG_E4STEPS _UxGT("E4 passo/mm") +#define MSG_E5STEPS _UxGT("E5 passo/mm") +#define MSG_TEMPERATURE _UxGT("Temperatura") +#define MSG_MOTION _UxGT("Movimento") +#define MSG_FILAMENT _UxGT("Filamento") +#define MSG_VOLUMETRIC_ENABLED _UxGT("E em mm3") +#define MSG_FILAMENT_DIAM _UxGT("Fil. Diam.") +#define MSG_CONTRAST _UxGT("Contraste") +#define MSG_STORE_EEPROM _UxGT("Guardar na memoria") +#define MSG_LOAD_EEPROM _UxGT("Carregar da memoria") +#define MSG_RESTORE_FAILSAFE _UxGT("Rest. de emergen.") +#define MSG_REFRESH LCD_STR_REFRESH _UxGT(" Recarregar") +#define MSG_WATCH _UxGT("Monitorizar") +#define MSG_PREPARE _UxGT("Preparar") +#define MSG_TUNE _UxGT("Afinar") +#define MSG_PAUSE_PRINT _UxGT("Pausar impressão") +#define MSG_RESUME_PRINT _UxGT("Retomar impressão") +#define MSG_STOP_PRINT _UxGT("Parar impressão") +#define MSG_CARD_MENU _UxGT("Imprimir do SD") +#define MSG_NO_CARD _UxGT("Sem cartão SD") +#define MSG_DWELL _UxGT("Em espera...") +#define MSG_USERWAIT _UxGT("Á espera de ordem") +#define MSG_RESUMING _UxGT("Retomando impressão") +#define MSG_PRINT_ABORTED _UxGT("Impressão cancelada") +#define MSG_NO_MOVE _UxGT("Sem movimento") +#define MSG_KILLED _UxGT("EMERGÊNCIA. ") +#define MSG_STOPPED _UxGT("PARADO. ") +#define MSG_CONTROL_RETRACT _UxGT(" Retrair mm") +#define MSG_CONTROL_RETRACT_SWAP _UxGT("Troca Retrair mm") +#define MSG_CONTROL_RETRACTF _UxGT(" Retrair V") +#define MSG_CONTROL_RETRACT_ZLIFT _UxGT(" Levantar mm") +#define MSG_CONTROL_RETRACT_RECOVER _UxGT(" DesRet mm") +#define MSG_CONTROL_RETRACT_RECOVER_SWAP _UxGT("Troca DesRet mm") +#define MSG_CONTROL_RETRACT_RECOVERF _UxGT(" DesRet V") +#define MSG_AUTORETRACT _UxGT(" AutoRetr.") +#define MSG_FILAMENTCHANGE _UxGT("Trocar filamento") +#define MSG_INIT_SDCARD _UxGT("Inici. cartão SD") +#define MSG_CNG_SDCARD _UxGT("Trocar cartão SD") +#define MSG_ZPROBE_OUT _UxGT("Sensor fora/base") +#define MSG_HOME _UxGT("Home") // Used as MSG_HOME " " MSG_X MSG_Y MSG_Z " " MSG_FIRST +#define MSG_FIRST _UxGT("first") +#define MSG_ZPROBE_ZOFFSET _UxGT("Desvio Z") +#define MSG_BABYSTEP_X _UxGT("Babystep X") +#define MSG_BABYSTEP_Y _UxGT("Babystep Y") +#define MSG_BABYSTEP_Z _UxGT("Babystep Z") +#define MSG_ENDSTOP_ABORT _UxGT("Fim de curso") +#define MSG_HEATING_FAILED_LCD _UxGT("Aquecimento falhou") +#define MSG_ERR_REDUNDANT_TEMP _UxGT("Err: REDUNDANT TEMP") +#define MSG_THERMAL_RUNAWAY _UxGT("THERMAL RUNAWAY") +#define MSG_ERR_MAXTEMP _UxGT("Err: T Máxima") +#define MSG_ERR_MINTEMP _UxGT("Err: T Mínima") +#define MSG_ERR_MAXTEMP_BED _UxGT("Err: T Base Máxima") +#define MSG_ERR_MINTEMP_BED _UxGT("Err: T Base Mínima") +#define MSG_HEATING _UxGT("Aquecendo...") +#define MSG_HEATING_COMPLETE _UxGT("Aquecida.") +#define MSG_BED_HEATING _UxGT("Aquecendo base..") +#define MSG_BED_DONE _UxGT("Base aquecida.") +#define MSG_DELTA_CALIBRATE _UxGT("Calibração Delta") +#define MSG_DELTA_CALIBRATE_X _UxGT("Calibrar X") +#define MSG_DELTA_CALIBRATE_Y _UxGT("Calibrar Y") +#define MSG_DELTA_CALIBRATE_Z _UxGT("Calibrar Z") +#define MSG_DELTA_CALIBRATE_CENTER _UxGT("Calibrar Centro") + +#define MSG_LCD_ENDSTOPS _UxGT("Fim de curso") + +#endif // LANGUAGE_PT_UTF_H diff --git a/trunk/Arduino/Marlin_1.1.6/language_ru.h b/trunk/Arduino/Marlin_1.1.6/language_ru.h new file mode 100644 index 00000000..32819877 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/language_ru.h @@ -0,0 +1,336 @@ +/** + * 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 . + * + */ + +/** + * Russian + * + * LCD Menu Messages + * See also http://marlinfw.org/docs/development/lcd_language.html + * + */ +#ifndef LANGUAGE_RU_H +#define LANGUAGE_RU_H + +#define MAPPER_D0D1 // For Cyrillic +#define DISPLAY_CHARSET_ISO10646_5 + +#define WELCOME_MSG MACHINE_NAME _UxGT(" Готов.") +#define MSG_BACK _UxGT("Назад") +#define MSG_SD_INSERTED _UxGT("Карта вставлена") +#define MSG_SD_REMOVED _UxGT("Карта извлечена") +#define MSG_LCD_ENDSTOPS _UxGT("Концевики") +#define MSG_MAIN _UxGT("Меню") +#define MSG_AUTOSTART _UxGT("Автостарт") +#define MSG_DISABLE_STEPPERS _UxGT("Выкл. двигатели") +#define MSG_DEBUG_MENU _UxGT("Меню отладки") +#define MSG_PROGRESS_BAR_TEST _UxGT("Тест индикатора") +#define MSG_AUTO_HOME _UxGT("Авто Парковка") +#define MSG_AUTO_HOME_X _UxGT("Парковка X") +#define MSG_AUTO_HOME_Y _UxGT("Парковка Y") +#define MSG_AUTO_HOME_Z _UxGT("Парковка Z") +#define MSG_LEVEL_BED_HOMING _UxGT("Нулевое полож") +#define MSG_LEVEL_BED_WAITING _UxGT("Нажмите начать") +#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Следующая точка") +#define MSG_LEVEL_BED_DONE _UxGT("Выравнинваие готово!") +#define MSG_Z_FADE_HEIGHT _UxGT("Высота спада") +#define MSG_SET_HOME_OFFSETS _UxGT("Запомнить парковку") +#define MSG_HOME_OFFSETS_APPLIED _UxGT("Коррекции примен") +#define MSG_SET_ORIGIN _UxGT("Запомнить ноль") +#define MSG_PREHEAT_1 _UxGT("Преднагрев PLA") +#define MSG_PREHEAT_1_N MSG_PREHEAT_1 _UxGT(" ") +#define MSG_PREHEAT_1_ALL MSG_PREHEAT_1 _UxGT(" Всё") +#define MSG_PREHEAT_1_END MSG_PREHEAT_1 _UxGT(" Сопло") +#define MSG_PREHEAT_1_BEDONLY MSG_PREHEAT_1 _UxGT(" Стол") +#define MSG_PREHEAT_1_SETTINGS MSG_PREHEAT_1 _UxGT(" Настр.") +#define MSG_PREHEAT_2 _UxGT("Преднагрев ABS") +#define MSG_PREHEAT_2_N MSG_PREHEAT_2 _UxGT(" ") +#define MSG_PREHEAT_2_ALL MSG_PREHEAT_2 _UxGT(" Всё") +#define MSG_PREHEAT_2_END MSG_PREHEAT_2 _UxGT(" Сопло") +#define MSG_PREHEAT_2_BEDONLY MSG_PREHEAT_2 _UxGT(" Стол") +#define MSG_PREHEAT_2_SETTINGS MSG_PREHEAT_2 _UxGT(" Настр.") +#define MSG_COOLDOWN _UxGT("Охлаждение") +#define MSG_SWITCH_PS_ON _UxGT("Включить Питание") +#define MSG_SWITCH_PS_OFF _UxGT("Отключить Питание") +#define MSG_EXTRUDE _UxGT("Экструзия") +#define MSG_RETRACT _UxGT("Втягивание") +#define MSG_MOVE_AXIS _UxGT("Движение по осям") +#define MSG_BED_LEVELING _UxGT("Калибровать стол") +#define MSG_LEVEL_BED _UxGT("Калибровать стол") +#define MSG_EDITING_STOPPED _UxGT("Ред. сетки завершена") +#define MSG_USER_MENU _UxGT("Свои комманды") +#define MSG_UBL_DOING_G29 _UxGT("Выполняем G29") +#define MSG_UBL_UNHOMED _UxGT("Паркуем сначала XYZ") +#define MSG_UBL_TOOLS _UxGT("Утилиты UBL") +#define MSG_UBL_LEVEL_BED _UxGT("Калибровка UBL") +#define MSG_UBL_MANUAL_MESH _UxGT("Постр. сетку от руки") +#define MSG_UBL_BC_INSERT _UxGT("Пост. шимм и измер.") +#define MSG_UBL_BC_INSERT2 _UxGT("Измерение") +#define MSG_UBL_BC_REMOVE _UxGT("Удал. и измер. стол") +#define MSG_UBL_MOVING_TO_NEXT _UxGT("Двигаемся дальше") +#define MSG_UBL_ACTIVATE_MESH _UxGT("Активировать UBL") +#define MSG_UBL_DEACTIVATE_MESH _UxGT("Выключить UBL") +#define MSG_UBL_SET_BED_TEMP _UxGT("Температура стола") +#define MSG_UBL_CUSTOM_BED_TEMP MSG_UBL_SET_BED_TEMP +#define MSG_UBL_SET_HOTEND_TEMP _UxGT("Температура сопла") +#define MSG_UBL_CUSTOM_HOTEND_TEMP MSG_UBL_SET_HOTEND_TEMP +#define MSG_UBL_MESH_EDIT _UxGT("Редактор сеток") +#define MSG_UBL_EDIT_CUSTOM_MESH _UxGT("Редакт. свою сетку") +#define MSG_UBL_FINE_TUNE_MESH _UxGT("Точ. настройка сетки") +#define MSG_UBL_DONE_EDITING_MESH _UxGT("Ред. сетки завершено") +#define MSG_UBL_BUILD_CUSTOM_MESH _UxGT("Построить свою сетку") +#define MSG_UBL_BUILD_MESH_MENU _UxGT("Построить сетку") +#define MSG_UBL_BUILD_PLA_MESH _UxGT("Построить сетку PLA") +#define MSG_UBL_BUILD_ABS_MESH _UxGT("Построить сетку ABS") +#define MSG_UBL_BUILD_COLD_MESH _UxGT("Построить хол. сетку") +#define MSG_UBL_MESH_HEIGHT_ADJUST _UxGT("Устан. высоту сетки") +#define MSG_UBL_MESH_HEIGHT_AMOUNT _UxGT("Высота") +#define MSG_UBL_VALIDATE_MESH_MENU _UxGT("Проверить сетку") +#define MSG_UBL_VALIDATE_PLA_MESH _UxGT("Проверить сетку PLA") +#define MSG_UBL_VALIDATE_ABS_MESH _UxGT("Проверить сетку ABS") +#define MSG_UBL_VALIDATE_CUSTOM_MESH _UxGT("Проверить свою сетку") +#define MSG_UBL_CONTINUE_MESH _UxGT("Продолжить сетку") +#define MSG_UBL_MESH_LEVELING _UxGT("Калибровка сетки") +#define MSG_UBL_3POINT_MESH_LEVELING _UxGT("Калибровка 3-х точек") +#define MSG_UBL_GRID_MESH_LEVELING _UxGT("Калибровка растера") +#define MSG_UBL_MESH_LEVEL _UxGT("Выровнить сетку") +#define MSG_UBL_SIDE_POINTS _UxGT("Крайние точки") +#define MSG_UBL_MAP_TYPE _UxGT("Тип карты") +#define MSG_UBL_OUTPUT_MAP _UxGT("Вывести карту сетки") +#define MSG_UBL_OUTPUT_MAP_HOST _UxGT("Вывести на хост") +#define MSG_UBL_OUTPUT_MAP_CSV _UxGT("Вывести в CSV") +#define MSG_UBL_OUTPUT_MAP_BACKUP _UxGT("Забекапить сетку") +#define MSG_UBL_INFO_UBL _UxGT("Выдача инфор. UBL") +#define MSG_UBL_EDIT_MESH_MENU _UxGT("Редактировать сетку") +#define MSG_UBL_FILLIN_AMOUNT _UxGT("Заполнить значения") +#define MSG_UBL_MANUAL_FILLIN _UxGT("Ручное заполнение") +#define MSG_UBL_SMART_FILLIN _UxGT("Уменое заполнение") +#define MSG_UBL_FILLIN_MESH _UxGT("Заполнить сетку") +#define MSG_UBL_INVALIDATE_ALL _UxGT("Аннулировать всё") +#define MSG_UBL_INVALIDATE_CLOSEST _UxGT("Аннулир. ближ. точку") +#define MSG_UBL_FINE_TUNE_ALL _UxGT("Точ. настройка всего") +#define MSG_UBL_FINE_TUNE_CLOSEST _UxGT("Настр. ближ. точки") +#define MSG_UBL_STORAGE_MESH_MENU _UxGT("Хранилище сетей") +#define MSG_UBL_STORAGE_SLOT _UxGT("Слот памяти") +#define MSG_UBL_LOAD_MESH _UxGT("Загрузить стол сетки") +#define MSG_UBL_SAVE_MESH _UxGT("Сохранить стол сетки") +#define MSG_UBL_SAVE_ERROR _UxGT("Ошибка: Сохр. UBL") +#define MSG_UBL_RESTORE_ERROR _UxGT("Ошибка: Загрузки UBL") +#define MSG_UBL_Z_OFFSET_STOPPED _UxGT("Смещение Z останов.") +#define MSG_UBL_STEP_BY_STEP_MENU _UxGT("Пошаговый UBL") +#define MSG_MOVING _UxGT("Движемся...") +#define MSG_FREE_XY _UxGT("Освобождаем XY") +#define MSG_MOVE_X _UxGT("Движение по X") +#define MSG_MOVE_Y _UxGT("Движение по Y") +#define MSG_MOVE_Z _UxGT("Движение по Z") +#define MSG_MOVE_E _UxGT("Экструдер") +#define MSG_MOVE_01MM _UxGT("Движение 0.1mm") +#define MSG_MOVE_1MM _UxGT("Движение 1mm") +#define MSG_MOVE_10MM _UxGT("Движение 10mm") +#define MSG_SPEED _UxGT("Скорость") +#define MSG_BED_Z _UxGT("Z стола") +#define MSG_NOZZLE LCD_STR_THERMOMETER _UxGT(" Сопло") +#define MSG_BED LCD_STR_THERMOMETER _UxGT(" Стол") +#define MSG_FAN_SPEED _UxGT("Кулер") +#define MSG_FLOW _UxGT("Поток") +#define MSG_CONTROL _UxGT("Настройки") +#define MSG_MIN LCD_STR_THERMOMETER _UxGT(" Минимум") +#define MSG_MAX LCD_STR_THERMOMETER _UxGT(" Максимум") +#define MSG_FACTOR LCD_STR_THERMOMETER _UxGT(" Фактор") +#define MSG_AUTOTEMP _UxGT("Автотемпература") +#define MSG_ON _UxGT("Вкл. ") +#define MSG_OFF _UxGT("Откл. ") +#define MSG_PID_P _UxGT("PID-P") +#define MSG_PID_I _UxGT("PID-I") +#define MSG_PID_D _UxGT("PID-D") +#define MSG_PID_C _UxGT("PID-C") +#define MSG_SELECT _UxGT("Выбор") +#define MSG_ACC _UxGT("Ускорение") +#define MSG_JERK _UxGT("Рывок") +#define MSG_VX_JERK _UxGT("Vx-рывок") +#define MSG_VY_JERK _UxGT("Vy-рывок") +#define MSG_VZ_JERK _UxGT("Vz-рывок") +#define MSG_VE_JERK _UxGT("Ve-рывок") +#define MSG_VELOCITY _UxGT("Скорость") +#define MSG_VMAX _UxGT("Vмакс ") +#define MSG_VMIN _UxGT("Vмин") +#define MSG_VTRAV_MIN _UxGT("Vпутеш. мин") +#define MSG_ACCELERATION _UxGT("Ускорение") +#define MSG_AMAX _UxGT("Aмакс") +#define MSG_A_RETRACT _UxGT("A-втягивание") +#define MSG_A_TRAVEL _UxGT("A-путеш.") +#define MSG_STEPS_PER_MM _UxGT("Шаг/мм") +#define MSG_XSTEPS _UxGT("X шаг/мм") +#define MSG_YSTEPS _UxGT("Y шаг/мм") +#define MSG_ZSTEPS _UxGT("Z шаг/мм") +#define MSG_ESTEPS _UxGT("E шаг/мм") +#define MSG_E1STEPS _UxGT("E1 шаг/мм") +#define MSG_E2STEPS _UxGT("E2 шаг/мм") +#define MSG_E3STEPS _UxGT("E3 шаг/мм") +#define MSG_E4STEPS _UxGT("E4 шаг/мм") +#define MSG_E5STEPS _UxGT("E5 шаг/мм") +#define MSG_TEMPERATURE _UxGT("Температура") +#define MSG_MOTION _UxGT("Механика") +#define MSG_FILAMENT _UxGT("Пруток") +#define MSG_VOLUMETRIC_ENABLED _UxGT("E в mm3") +#define MSG_FILAMENT_DIAM _UxGT("Диаметр прутка") +#define MSG_ADVANCE_K _UxGT("K продвижения") +#define MSG_CONTRAST _UxGT("Контраст LCD") +#define MSG_STORE_EEPROM _UxGT("Сохранить в EEPROM") +#define MSG_LOAD_EEPROM _UxGT("Считать из EEPROM") +#define MSG_RESTORE_FAILSAFE _UxGT("Сброс EEPROM") +#define MSG_INIT_EEPROM _UxGT("Иниц. EEPROM") +#define MSG_REFRESH _UxGT("Обновить") +#define MSG_WATCH _UxGT("Обзор") +#define MSG_PREPARE _UxGT("Действия") +#define MSG_TUNE _UxGT("Настройки") +#define MSG_PAUSE_PRINT _UxGT("Пауза печати") +#define MSG_RESUME_PRINT _UxGT("Продолжить печать") +#define MSG_STOP_PRINT _UxGT("Остановить печать") +#define MSG_CARD_MENU _UxGT("Обзор карты") +#define MSG_NO_CARD _UxGT("Нет карты") +#define MSG_DWELL _UxGT("Сон...") +#define MSG_USERWAIT _UxGT("Продолжить...") +#define MSG_PRINT_PAUSED _UxGT("Печать остановлена") +#define MSG_RESUMING _UxGT("Возобновление...") +#define MSG_PRINT_ABORTED _UxGT("Отмена печати") +#define MSG_NO_MOVE _UxGT("Нет движения.") +#define MSG_KILLED _UxGT("УБИТО.") +#define MSG_STOPPED _UxGT("ОСТАНОВЛЕНО.") +#define MSG_CONTROL_RETRACT _UxGT("Втягивание mm") +#define MSG_CONTROL_RETRACT_SWAP _UxGT("Втяг. смены mm") +#define MSG_CONTROL_RETRACTF _UxGT("Втягивание V") +#define MSG_CONTROL_RETRACT_ZLIFT _UxGT("Втяг. прыжка mm") +#define MSG_CONTROL_RETRACT_RECOVER _UxGT("Возврат mm") +#define MSG_CONTROL_RETRACT_RECOVER_SWAP _UxGT("Возврат смены mm") +#define MSG_CONTROL_RETRACT_RECOVERF _UxGT("Возврат V") +#define MSG_AUTORETRACT _UxGT("Авто Втягивание") +#define MSG_FILAMENTCHANGE _UxGT("Смена прутка") +#define MSG_INIT_SDCARD _UxGT("Иниц. карту") +#define MSG_CNG_SDCARD _UxGT("Сменить карту") +#define MSG_ZPROBE_OUT _UxGT("Z датчик вне стола") +#define MSG_BLTOUCH _UxGT("BLTouch") +#define MSG_BLTOUCH_SELFTEST _UxGT("Тестирование BLTouch") +#define MSG_BLTOUCH_RESET _UxGT("Сброс BLTouch") +#define MSG_BLTOUCH_DEPLOY _UxGT("Установка BLTouch") +#define MSG_BLTOUCH_STOW _UxGT("Набивка BLTouch") +#define MSG_HOME _UxGT("Паркуй") +#define MSG_FIRST _UxGT("первый") +#define MSG_ZPROBE_ZOFFSET _UxGT("Смещение Z") +#define MSG_BABYSTEP_X _UxGT("Микрошаг X") +#define MSG_BABYSTEP_Y _UxGT("Микрошаг Y") +#define MSG_BABYSTEP_Z _UxGT("Микрошаг Z") +#define MSG_ENDSTOP_ABORT _UxGT("Сработал концевик") +#define MSG_HEATING_FAILED_LCD _UxGT("Разогрев не удался") +#define MSG_ERR_REDUNDANT_TEMP _UxGT("Ошибка: T ред.") +#define MSG_THERMAL_RUNAWAY _UxGT("ТЕПЛО УБЕГАНИЯ!") +#define MSG_ERR_MAXTEMP _UxGT("Ошибка: Т макс.") +#define MSG_ERR_MINTEMP _UxGT("Ошибка: Т мин.") +#define MSG_ERR_MAXTEMP_BED _UxGT("Ошибка:Т макс.стол") +#define MSG_ERR_MINTEMP_BED _UxGT("Ошибка:Т мин.стол") +#define MSG_ERR_Z_HOMING _UxGT("G28 Z Запрещено") +#define MSG_HALTED _UxGT("ПРИНТЕР ОСТАНОВЛЕН") +#define MSG_PLEASE_RESET _UxGT("Нажмите ресет") +#define MSG_SHORT_DAY _UxGT("д") // One character only +#define MSG_SHORT_HOUR _UxGT("ч") // One character only +#define MSG_SHORT_MINUTE _UxGT("м") // One character only +#define MSG_HEATING _UxGT("Нагреваю сопло...") +#define MSG_HEATING_COMPLETE _UxGT("Нагрев выполнен") +#define MSG_BED_HEATING _UxGT("Нагреваю стол") +#define MSG_BED_DONE _UxGT("Стол разогрет") +#define MSG_DELTA_CALIBRATE _UxGT("Калибровка Delta") +#define MSG_DELTA_CALIBRATE_X _UxGT("Калибровать X") +#define MSG_DELTA_CALIBRATE_Y _UxGT("Калибровать Y") +#define MSG_DELTA_CALIBRATE_Z _UxGT("Калибровать Z") +#define MSG_DELTA_CALIBRATE_CENTER _UxGT("Калибровать центр") +#define MSG_DELTA_SETTINGS _UxGT("Пок. настройки Delta") +#define MSG_DELTA_AUTO_CALIBRATE _UxGT("Авто калибровка") +#define MSG_DELTA_HEIGHT_CALIBRATE _UxGT("Задать высоту Delta") +#define MSG_INFO_MENU _UxGT("О принтере") +#define MSG_INFO_PRINTER_MENU _UxGT("Инф. о принтере") +#define MSG_3POINT_LEVELING _UxGT("Калибровка 3-х точек") +#define MSG_LINEAR_LEVELING _UxGT("Линейная калибровка") +#define MSG_BILINEAR_LEVELING _UxGT("Билинейная калибр.") +#define MSG_UBL_LEVELING _UxGT("Калибровка UBL") +#define MSG_MESH_LEVELING _UxGT("Калибровка сетки") +#define MSG_INFO_STATS_MENU _UxGT("Статистика принтера") +#define MSG_INFO_BOARD_MENU _UxGT("Информация о плате") +#define MSG_INFO_THERMISTOR_MENU _UxGT("Термисторы") +#define MSG_INFO_EXTRUDERS _UxGT("Экструдеры") +#define MSG_INFO_BAUDRATE _UxGT("Бод") +#define MSG_INFO_PROTOCOL _UxGT("Протокол") +#define MSG_CASE_LIGHT _UxGT("Корпусное освещение") +#define MSG_CASE_LIGHT_BRIGHTNESS _UxGT("Яркость освещения") +#if LCD_WIDTH >= 20 + #define MSG_INFO_COMPLETED_PRINTS _UxGT("Закончено") + #define MSG_INFO_PRINT_TIME _UxGT("Полное время печати") + #define MSG_INFO_PRINT_FILAMENT _UxGT("Длинна филамента") +#else + #define MSG_INFO_PRINT_COUNT _UxGT("Отпечатков") + #define MSG_INFO_COMPLETED_PRINTS _UxGT("Закончено") + #define MSG_INFO_PRINT_TIME _UxGT("Всего") + #define MSG_INFO_PRINT_LONGEST _UxGT("Наибольшее") + #define MSG_INFO_PRINT_FILAMENT _UxGT("Выдавлено") +#endif +#define MSG_INFO_MIN_TEMP _UxGT("Мин. Т") +#define MSG_INFO_MAX_TEMP _UxGT("Макс. Т") +#define MSG_INFO_PSU _UxGT("Блок питания") +#define MSG_DRIVE_STRENGTH _UxGT("Сила привода") +#define MSG_DAC_PERCENT _UxGT("Привод %") +#define MSG_DAC_EEPROM_WRITE _UxGT("Записи DAC EEPROM") +#define MSG_FILAMENT_CHANGE_HEADER _UxGT("ПЕЧАТЬ ОСТАНОВЛЕНА") +#define MSG_FILAMENT_CHANGE_OPTION_HEADER _UxGT("ОПЦИИ ВОЗОБНОВЛЕНИЯ:") +#define MSG_FILAMENT_CHANGE_OPTION_EXTRUDE _UxGT("Выдавить ещё") +#define MSG_FILAMENT_CHANGE_OPTION_RESUME _UxGT("Возобновить печать") +#define MSG_FILAMENT_CHANGE_MINTEMP _UxGT("Мин. температура") +#define MSG_FILAMENT_CHANGE_NOZZLE _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 + #define MSG_FILAMENT_CHANGE_INIT_1 _UxGT("Ожидайте") + #define MSG_FILAMENT_CHANGE_INIT_2 _UxGT("начала смены") + #define MSG_FILAMENT_CHANGE_INIT_3 _UxGT("филамента") + #define MSG_FILAMENT_CHANGE_UNLOAD_1 _UxGT("Ожидайте") + #define MSG_FILAMENT_CHANGE_UNLOAD_2 _UxGT("выгрузки филамента") + #define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("Вставьте филамент") + #define MSG_FILAMENT_CHANGE_INSERT_2 _UxGT("и нажмите кнопку") + #define MSG_FILAMENT_CHANGE_INSERT_3 _UxGT("для продолжения...") + #define MSG_FILAMENT_CHANGE_HEAT_1 _UxGT("Нажмите кнопку для") + #define MSG_FILAMENT_CHANGE_HEAT_2 _UxGT("нагрева сопла...") + #define MSG_FILAMENT_CHANGE_HEATING_1 _UxGT("Нагрев сопла") + #define MSG_FILAMENT_CHANGE_HEATING_2 _UxGT("Ждите...") + #define MSG_FILAMENT_CHANGE_LOAD_1 _UxGT("Ожидайте") + #define MSG_FILAMENT_CHANGE_LOAD_2 _UxGT("загрузки филамента") + #define MSG_FILAMENT_CHANGE_RESUME_1 _UxGT("Ожидайте") + #define MSG_FILAMENT_CHANGE_RESUME_2 _UxGT("возобновления") +#else // LCD_HEIGHT < 4 + #define MSG_FILAMENT_CHANGE_INIT_1 _UxGT("Ожидайте...") + #define MSG_FILAMENT_CHANGE_UNLOAD_1 _UxGT("Выгрузка...") + #define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("Вставь и нажми") + #define MSG_FILAMENT_CHANGE_HEATING_1 _UxGT("Нагрев...") + #define MSG_FILAMENT_CHANGE_LOAD_1 _UxGT("Загрузка...") + #define MSG_FILAMENT_CHANGE_EXTRUDE_1 _UxGT("Выдавливание...") + #define MSG_FILAMENT_CHANGE_RESUME_1 _UxGT("Возобновление...") +#endif // LCD_HEIGHT < 4 + +#endif // LANGUAGE_RU_H diff --git a/trunk/Arduino/Marlin_1.1.6/language_sk_utf8.h b/trunk/Arduino/Marlin_1.1.6/language_sk_utf8.h new file mode 100644 index 00000000..d7157ca4 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/language_sk_utf8.h @@ -0,0 +1,350 @@ +/** + * 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 . + * + */ + +/** + * Slovak + * UTF-8 for Graphical Display + * + * LCD Menu Messages + * See also http://marlinfw.org/docs/development/lcd_language.html + * + * Translated by Michal Holeš, Farma MaM + * http://www.facebook.com/farmamam + * + */ +#ifndef LANGUAGE_SK_UTF_H +#define LANGUAGE_SK_UTF_H + +#define MAPPER_C3C4C5_SK +#define DISPLAY_CHARSET_ISO10646_SK + +#define WELCOME_MSG MACHINE_NAME _UxGT(" pripravená.") +#define MSG_BACK _UxGT("Naspať") +#define MSG_SD_INSERTED _UxGT("Karta vložená") +#define MSG_SD_REMOVED _UxGT("Karta vybratá") +#define MSG_LCD_ENDSTOPS _UxGT("Endstopy") // max 8 znakov +#define MSG_MAIN _UxGT("Hlavná ponuka") +#define MSG_AUTOSTART _UxGT("Autoštart") +#define MSG_DISABLE_STEPPERS _UxGT("Uvolniť motory") +#define MSG_DEBUG_MENU _UxGT("Ponuka ladenia") +#define MSG_PROGRESS_BAR_TEST _UxGT("Test uk. priebehu") +#define MSG_AUTO_HOME _UxGT("Domovská pozícia") +#define MSG_AUTO_HOME_X _UxGT("Domov os X") +#define MSG_AUTO_HOME_Y _UxGT("Domov os Y") +#define MSG_AUTO_HOME_Z _UxGT("Domov os Z") +#define MSG_LEVEL_BED_HOMING _UxGT("Meranie podložky") +#define MSG_LEVEL_BED_WAITING _UxGT("Kliknutím spusťte") +#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Ďalší bod") +#define MSG_LEVEL_BED_DONE _UxGT("Meranie hotové!") +#define MSG_Z_FADE_HEIGHT _UxGT("Výška merania") +#define MSG_SET_HOME_OFFSETS _UxGT("Nastaviť offsety") +#define MSG_HOME_OFFSETS_APPLIED _UxGT("Offsety nastavené") +#define MSG_SET_ORIGIN _UxGT("Nastaviť začiatok") +#define MSG_PREHEAT_1 _UxGT("Zahriať PLA") +#define MSG_PREHEAT_1_N MSG_PREHEAT_1 _UxGT(" ") +#define MSG_PREHEAT_1_ALL MSG_PREHEAT_1 _UxGT(" všetko") +#define MSG_PREHEAT_1_END MSG_PREHEAT_1 _UxGT(" hotend") +#define MSG_PREHEAT_1_BEDONLY MSG_PREHEAT_1 _UxGT(" podlož") +#define MSG_PREHEAT_1_SETTINGS MSG_PREHEAT_1 _UxGT(" nast") +#define MSG_PREHEAT_2 _UxGT("Zahriať ABS") +#define MSG_PREHEAT_2_N MSG_PREHEAT_2 _UxGT(" ") +#define MSG_PREHEAT_2_ALL MSG_PREHEAT_2 _UxGT(" všetko") +#define MSG_PREHEAT_2_END MSG_PREHEAT_2 _UxGT(" hotend") +#define MSG_PREHEAT_2_BEDONLY MSG_PREHEAT_2 _UxGT(" podlož") +#define MSG_PREHEAT_2_SETTINGS MSG_PREHEAT_2 _UxGT(" nast") +#define MSG_COOLDOWN _UxGT("Schladiť") +#define MSG_SWITCH_PS_ON _UxGT("Zapnúť napájanie") +#define MSG_SWITCH_PS_OFF _UxGT("Vypnúť napájanie") +#define MSG_EXTRUDE _UxGT("Vytlačiť (extr.)") +#define MSG_RETRACT _UxGT("Vytiahnuť (retr.)") +#define MSG_MOVE_AXIS _UxGT("Posunúť osy") +#define MSG_BED_LEVELING _UxGT("Vyrovnať podložku") +#define MSG_LEVEL_BED _UxGT("Vyrovnať podložku") +#define MSG_EDITING_STOPPED _UxGT("Koniec úprav siete") + +#define MSG_UBL_DOING_G29 _UxGT("Vykonávam G29") +#define MSG_UBL_UNHOMED _UxGT("Prejdite domov") +#define MSG_UBL_TOOLS _UxGT("UBL nástroje") +#define MSG_UBL_LEVEL_BED _UxGT("Unified Bed Leveling") +#define MSG_UBL_MANUAL_MESH _UxGT("Manuálna sieť bodov") +#define MSG_UBL_BC_INSERT _UxGT("Vložte kartu, zmerajte") +#define MSG_UBL_BC_INSERT2 _UxGT("Zmerajte") +#define MSG_UBL_BC_REMOVE _UxGT("Odstráňte a zmerajte") +#define MSG_UBL_MOVING_TO_NEXT _UxGT("Presun na ďalší") +#define MSG_UBL_ACTIVATE_MESH _UxGT("Aktivovať UBL") +#define MSG_UBL_DEACTIVATE_MESH _UxGT("Deaktivovať UBL") +#define MSG_UBL_SET_BED_TEMP _UxGT("Teplota podložky") +#define MSG_UBL_CUSTOM_BED_TEMP MSG_UBL_SET_BED_TEMP +#define MSG_UBL_SET_HOTEND_TEMP _UxGT("Teplota hotendu") +#define MSG_UBL_CUSTOM_HOTEND_TEMP MSG_UBL_SET_HOTEND_TEMP +#define MSG_UBL_EDIT_CUSTOM_MESH _UxGT("Upraviť vlastnú sieť") +#define MSG_UBL_FINE_TUNE_MESH _UxGT("Doladiť sieť bodov") +#define MSG_UBL_DONE_EDITING_MESH _UxGT("Koniec úprav siete") +#define MSG_UBL_BUILD_CUSTOM_MESH _UxGT("Vlastná sieť") +#define MSG_UBL_BUILD_MESH_MENU _UxGT("Vytvoriť sieť") +#define MSG_UBL_BUILD_PLA_MESH _UxGT("Sieť bodov PLA") +#define MSG_UBL_BUILD_ABS_MESH _UxGT("Sieť bodov ABS") +#define MSG_UBL_BUILD_COLD_MESH _UxGT("Studená sieť bodov") +#define MSG_UBL_MESH_HEIGHT_ADJUST _UxGT("Upraviť výšku siete") +#define MSG_UBL_MESH_HEIGHT_AMOUNT _UxGT("Výška") +#define MSG_UBL_VALIDATE_MESH_MENU _UxGT("Skontrolovať sieť") +#define MSG_UBL_VALIDATE_PLA_MESH _UxGT("Kontrola siete PLA") +#define MSG_UBL_VALIDATE_ABS_MESH _UxGT("Kontrola siete ABS") +#define MSG_UBL_VALIDATE_CUSTOM_MESH _UxGT("Kontrola vlast. siete") +#define MSG_UBL_CONTINUE_MESH _UxGT("Pokračovať v sieti") +#define MSG_UBL_MESH_LEVELING _UxGT("Sieťové rovnanie") +#define MSG_UBL_3POINT_MESH_LEVELING _UxGT("3-bodove rovnanie") +#define MSG_UBL_GRID_MESH_LEVELING _UxGT("Mriežkové rovnanie") +#define MSG_UBL_MESH_LEVEL _UxGT("Vyrovnať podložku") +#define MSG_UBL_SIDE_POINTS _UxGT("Postranné body") +#define MSG_UBL_MAP_TYPE _UxGT("Typ siete bodov") +#define MSG_UBL_OUTPUT_MAP _UxGT("Exportovať sieť") +#define MSG_UBL_OUTPUT_MAP_HOST _UxGT("Exportovať do PC") +#define MSG_UBL_OUTPUT_MAP_CSV _UxGT("Exportovať do CSV") +#define MSG_UBL_OUTPUT_MAP_BACKUP _UxGT("Záloha do PC") +#define MSG_UBL_INFO_UBL _UxGT("Info o UBL do PC") +#define MSG_UBL_EDIT_MESH_MENU _UxGT("Upraviť sieť bodov") +#define MSG_UBL_FILLIN_AMOUNT _UxGT("Hustota mriežky") +#define MSG_UBL_MANUAL_FILLIN _UxGT("Ručná hustota") +#define MSG_UBL_SMART_FILLIN _UxGT("Smart hustota") +#define MSG_UBL_FILLIN_MESH _UxGT("Zaplniť mriežku") +#define MSG_UBL_INVALIDATE_ALL _UxGT("Zrušiť všetko") +#define MSG_UBL_INVALIDATE_CLOSEST _UxGT("Zrušiť posledný") +#define MSG_UBL_FINE_TUNE_ALL _UxGT("Upraviť všetky") +#define MSG_UBL_FINE_TUNE_CLOSEST _UxGT("Upraviť posledný") +#define MSG_UBL_STORAGE_MESH_MENU _UxGT("Uložisko sietí") +#define MSG_UBL_STORAGE_SLOT _UxGT("Pamaťový slot") +#define MSG_UBL_LOAD_MESH _UxGT("Načítať sieť bodov") +#define MSG_UBL_SAVE_MESH _UxGT("Uložiť sieť bodov") +#define MSG_UBL_SAVE_ERROR _UxGT("Err: Uložiť UBL") +#define MSG_UBL_RESTORE_ERROR _UxGT("Err: Obnoviť UBL") +#define MSG_UBL_Z_OFFSET_STOPPED _UxGT("Koniec Z-Offsetu") +#define MSG_UBL_STEP_BY_STEP_MENU _UxGT("UBL Postupne") + +#define MSG_USER_MENU _UxGT("Vlastné príkazy") +#define MSG_MOVING _UxGT("Posun...") +#define MSG_FREE_XY _UxGT("Uvolniť XY") +#define MSG_MOVE_X _UxGT("Posunúť X") +#define MSG_MOVE_Y _UxGT("Posunúť Y") +#define MSG_MOVE_Z _UxGT("Posunúť Z") +#define MSG_MOVE_E _UxGT("Extrúder") +#define MSG_MOVE_01MM _UxGT("Posunúť o 0,1mm") +#define MSG_MOVE_1MM _UxGT("Posunúť o 1mm") +#define MSG_MOVE_10MM _UxGT("Posunúť o 10mm") +#define MSG_SPEED _UxGT("Rýchlosť") +#define MSG_BED_Z _UxGT("Výška podl.") +#define MSG_NOZZLE _UxGT("Tryska") +#define MSG_BED _UxGT("Podložka") +#define MSG_FAN_SPEED _UxGT("Rýchlosť vent.") +#define MSG_FLOW _UxGT("Prietok") +#define MSG_CONTROL _UxGT("Ovládanie") +#define MSG_MIN _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" Min") +#define MSG_MAX _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" Max") +#define MSG_FACTOR _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" Fakt") +#define MSG_AUTOTEMP _UxGT("Autoteplota") +#define MSG_ON _UxGT("Zap") +#define MSG_OFF _UxGT("Vyp") +#define MSG_PID_P _UxGT("PID-P") +#define MSG_PID_I _UxGT("PID-I") +#define MSG_PID_D _UxGT("PID-D") +#define MSG_PID_C _UxGT("PID-C") +#define MSG_SELECT _UxGT("Vybrať") +#define MSG_ACC _UxGT("Zrýchl") +#define MSG_JERK _UxGT("Skok") +#define MSG_VX_JERK _UxGT("Vx-skok") +#define MSG_VY_JERK _UxGT("Vy-skok") +#define MSG_VZ_JERK _UxGT("Vz-skok") +#define MSG_VE_JERK _UxGT("Ve-skok") +#define MSG_VELOCITY _UxGT("Rýchlosť") +#define MSG_VMAX _UxGT("Vmax ") +#define MSG_VMIN _UxGT("Vmin") +#define MSG_VTRAV_MIN _UxGT("VTrav min") +#define MSG_ACCELERATION _UxGT("Akcelerácia") +#define MSG_AMAX _UxGT("Amax ") +#define MSG_A_RETRACT _UxGT("A-retrakt") +#define MSG_A_TRAVEL _UxGT("A-prejazd") +#define MSG_STEPS_PER_MM _UxGT("Krokov/mm") +#define MSG_XSTEPS _UxGT("Xkrokov/mm") +#define MSG_YSTEPS _UxGT("Ykrokov/mm") +#define MSG_ZSTEPS _UxGT("Zkrokov/mm") +#define MSG_ESTEPS _UxGT("Ekrokov/mm") +#define MSG_E1STEPS _UxGT("E1krokov/mm") +#define MSG_E2STEPS _UxGT("E2krokov/mm") +#define MSG_E3STEPS _UxGT("E3krokov/mm") +#define MSG_E4STEPS _UxGT("E4krokov/mm") +#define MSG_E5STEPS _UxGT("E5kroků/mm") +#define MSG_TEMPERATURE _UxGT("Teplota") +#define MSG_MOTION _UxGT("Pohyb") +#define MSG_FILAMENT _UxGT("Filament") +#define MSG_VOLUMETRIC_ENABLED _UxGT("E na mm3") +#define MSG_FILAMENT_DIAM _UxGT("Fil. Priem.") +#define MSG_ADVANCE_K _UxGT("K pro posun") +#define MSG_CONTRAST _UxGT("Kontrast LCD") +#define MSG_STORE_EEPROM _UxGT("Uložiť nastavenie") +#define MSG_LOAD_EEPROM _UxGT("Načítať nastaveníe") +#define MSG_RESTORE_FAILSAFE _UxGT("Obnoviť nastavenie") +#define MSG_INIT_EEPROM _UxGT("Inic. EEPROM") +#define MSG_REFRESH _UxGT("Obnoviť") +#define MSG_WATCH _UxGT("Info obrazovka") +#define MSG_PREPARE _UxGT("Príprava tlače") +#define MSG_TUNE _UxGT("Doladenie tlače") +#define MSG_PAUSE_PRINT _UxGT("Pozastaviť tlač") +#define MSG_RESUME_PRINT _UxGT("Obnoviť tlač") +#define MSG_STOP_PRINT _UxGT("Zastaviť tlač") +#define MSG_CARD_MENU _UxGT("Tlačiť z SD") +#define MSG_NO_CARD _UxGT("Žiadna SD karta") +#define MSG_DWELL _UxGT("Spím...") +#define MSG_USERWAIT _UxGT("Čakám...") +#define MSG_PRINT_PAUSED _UxGT("Tlač pozastavená") +#define MSG_RESUMING _UxGT("Obnovovanie tlače") +#define MSG_PRINT_ABORTED _UxGT("Tlač zrušená") +#define MSG_NO_MOVE _UxGT("Žiadny pohyb.") +#define MSG_KILLED _UxGT("PRERUŠENÉ. ") +#define MSG_STOPPED _UxGT("ZASTAVENÉ. ") +#define MSG_CONTROL_RETRACT _UxGT("Retrakt mm") +#define MSG_CONTROL_RETRACT_SWAP _UxGT("Výmena Re.mm") +#define MSG_CONTROL_RETRACTF _UxGT("Retraktovať V") +#define MSG_CONTROL_RETRACT_ZLIFT _UxGT("Zdvih Z mm") +#define MSG_CONTROL_RETRACT_RECOVER _UxGT("UnRet mm") +#define MSG_CONTROL_RETRACT_RECOVER_SWAP _UxGT("S UnRet mm") +#define MSG_CONTROL_RETRACT_RECOVERF _UxGT("UnRet V") +#define MSG_AUTORETRACT _UxGT("AutoRetr.") +#define MSG_FILAMENTCHANGE _UxGT("Vymeniť filament") +#define MSG_INIT_SDCARD _UxGT("Načítať SD kartu") +#define MSG_CNG_SDCARD _UxGT("Vymeniť SD kartu") +#define MSG_ZPROBE_OUT _UxGT("Sonda Z mimo podl") +#define MSG_BLTOUCH _UxGT("BLTouch") +#define MSG_BLTOUCH_SELFTEST _UxGT("BLTouch Self-Test") +#define MSG_BLTOUCH_RESET _UxGT("BLTouch Reset") +#define MSG_BLTOUCH_DEPLOY _UxGT("BLTouch Vysunúť") +#define MSG_BLTOUCH_STOW _UxGT("BLTouch Zasunúť") +#define MSG_HOME _UxGT("Najprv") // Used as MSG_HOME " " MSG_X MSG_Y MSG_Z " " MSG_FIRST +#define MSG_FIRST _UxGT("domov") +#define MSG_ZPROBE_ZOFFSET _UxGT("Z offset") +#define MSG_BABYSTEP_X _UxGT("Babystep X") +#define MSG_BABYSTEP_Y _UxGT("Babystep Y") +#define MSG_BABYSTEP_Z _UxGT("Babystep Z") +#define MSG_ENDSTOP_ABORT _UxGT("Endstop zastavil") +#define MSG_HEATING_FAILED_LCD _UxGT("Chyba ohrevu") +#define MSG_ERR_REDUNDANT_TEMP _UxGT("REDUND. TEPLOTA") +#define MSG_THERMAL_RUNAWAY _UxGT("TEPLOTNÝ SKOK") +#define MSG_ERR_MAXTEMP _UxGT("VYSOKÁ TEPLOTA") +#define MSG_ERR_MINTEMP _UxGT("NÍZKA TEPLOTA") +#define MSG_ERR_MAXTEMP_BED _UxGT("VYS. TEPL. PODL.") +#define MSG_ERR_MINTEMP_BED _UxGT("NÍZ. TEPL. PODL.") +#define MSG_ERR_Z_HOMING _UxGT("G28 Z ZAKÁZANÉ") +#define MSG_HALTED _UxGT("TLAČ. ZASTAVENÁ") +#define MSG_PLEASE_RESET _UxGT("Spravte reset") +#define MSG_SHORT_DAY _UxGT("d") +#define MSG_SHORT_HOUR _UxGT("h") +#define MSG_SHORT_MINUTE _UxGT("m") +#define MSG_HEATING _UxGT("Ohrev...") +#define MSG_HEATING_COMPLETE _UxGT("Ohrev prebehol.") +#define MSG_BED_HEATING _UxGT("Ohrev podl.") +#define MSG_BED_DONE _UxGT("Podložka hotová.") +#define MSG_DELTA_CALIBRATE _UxGT("Delta Kalibrácia") +#define MSG_DELTA_CALIBRATE_X _UxGT("Kalibrovať X") +#define MSG_DELTA_CALIBRATE_Y _UxGT("Kalibrovať Y") +#define MSG_DELTA_CALIBRATE_Z _UxGT("Kalibrovať Z") +#define MSG_DELTA_CALIBRATE_CENTER _UxGT("Kalibrovať Stred") +#define MSG_DELTA_AUTO_CALIBRATE _UxGT("Autokalibrácia") +#define MSG_DELTA_HEIGHT_CALIBRATE _UxGT("Nast.výšku delty") +#define MSG_INFO_MENU _UxGT("O tlačiarni") +#define MSG_INFO_PRINTER_MENU _UxGT("Info o tlačiarni") +#define MSG_3POINT_LEVELING _UxGT("3-bodové rovnanie") +#define MSG_LINEAR_LEVELING _UxGT("Lineárne rovnanie") +#define MSG_BILINEAR_LEVELING _UxGT("Bilineárne rovnanie") +#define MSG_UBL_LEVELING _UxGT("Unified Bed Leveling") +#define MSG_MESH_LEVELING _UxGT("Mriežkové rovnanie") +#define MSG_INFO_STATS_MENU _UxGT("Štatistika") +#define MSG_INFO_BOARD_MENU _UxGT("Info o doske") +#define MSG_INFO_THERMISTOR_MENU _UxGT("Termistory") +#define MSG_INFO_EXTRUDERS _UxGT("Extrudéry") +#define MSG_INFO_BAUDRATE _UxGT("Rýchlosť") +#define MSG_INFO_PROTOCOL _UxGT("Protokol") +#define MSG_CASE_LIGHT _UxGT("Osvetlenie") +#define MSG_CASE_LIGHT_BRIGHTNESS _UxGT("Jas svetla") + +#if LCD_WIDTH >= 20 + #define MSG_INFO_PRINT_COUNT _UxGT("Počet tlačí") + #define MSG_INFO_COMPLETED_PRINTS _UxGT("Dokončené") + #define MSG_INFO_PRINT_TIME _UxGT("Celkový čas") + #define MSG_INFO_PRINT_LONGEST _UxGT("Najdlhšia tlač") + #define MSG_INFO_PRINT_FILAMENT _UxGT("Celkom vytlačené") +#else + #define MSG_INFO_PRINT_COUNT _UxGT("Tlače") + #define MSG_INFO_COMPLETED_PRINTS _UxGT("Hotovo") + #define MSG_INFO_PRINT_TIME _UxGT("Čas") + #define MSG_INFO_PRINT_LONGEST _UxGT("Najdlhšia") + #define MSG_INFO_PRINT_FILAMENT _UxGT("Vytlačené") +#endif + +#define MSG_INFO_MIN_TEMP _UxGT("Teplota min") +#define MSG_INFO_MAX_TEMP _UxGT("Teplota max") +#define MSG_INFO_PSU _UxGT("Nap. zdroj") +#define MSG_DRIVE_STRENGTH _UxGT("Budenie motorov") +#define MSG_DAC_PERCENT _UxGT("Motor %") +#define MSG_DAC_EEPROM_WRITE _UxGT("Uložiť do EEPROM") + +#define MSG_FILAMENT_CHANGE_HEADER _UxGT("PAUZA TLAČE") +#define MSG_FILAMENT_CHANGE_OPTION_HEADER _UxGT("MOŽN. POKRAČ.:") +#define MSG_FILAMENT_CHANGE_OPTION_EXTRUDE _UxGT("Ešte vytlačiť") +#define MSG_FILAMENT_CHANGE_OPTION_RESUME _UxGT("Obnoviť tlač") +#define MSG_FILAMENT_CHANGE_MINTEMP _UxGT("Min. teplota je ") +#define MSG_FILAMENT_CHANGE_NOZZLE _UxGT(" Tryska: ") + +#if LCD_HEIGHT >= 4 + // Up to 3 lines allowed + #define MSG_FILAMENT_CHANGE_INIT_1 _UxGT("Čakajte prosím") + #define MSG_FILAMENT_CHANGE_INIT_2 _UxGT("na spustenie") + #define MSG_FILAMENT_CHANGE_INIT_3 _UxGT("výmeny filamentu") + #define MSG_FILAMENT_CHANGE_UNLOAD_1 _UxGT("Čakejte prosím") + #define MSG_FILAMENT_CHANGE_UNLOAD_2 _UxGT("na vysunutie") + #define MSG_FILAMENT_CHANGE_UNLOAD_3 _UxGT("filamentu") + #define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("Vložte filament") + #define MSG_FILAMENT_CHANGE_INSERT_2 _UxGT("a stlačte") + #define MSG_FILAMENT_CHANGE_INSERT_3 _UxGT("tlačidlo...") + #define MSG_FILAMENT_CHANGE_HEAT_1 _UxGT("Kliknite pre") + #define MSG_FILAMENT_CHANGE_HEAT_2 _UxGT("ohrev trysky") + #define MSG_FILAMENT_CHANGE_HEATING_1 _UxGT("Čakajte prosím") + #define MSG_FILAMENT_CHANGE_HEATING_2 _UxGT("na teplotu tr.") + #define MSG_FILAMENT_CHANGE_LOAD_1 _UxGT("Čakajte prosím") + #define MSG_FILAMENT_CHANGE_LOAD_2 _UxGT("na zavedenie") + #define MSG_FILAMENT_CHANGE_LOAD_3 _UxGT("filamentu") + #define MSG_FILAMENT_CHANGE_EXTRUDE_1 _UxGT("Čakajte prosím") + #define MSG_FILAMENT_CHANGE_EXTRUDE_2 _UxGT("na vytlačenie") + #define MSG_FILAMENT_CHANGE_EXTRUDE_3 _UxGT("filamentu") + #define MSG_FILAMENT_CHANGE_RESUME_1 _UxGT("Čakajte prosím") + #define MSG_FILAMENT_CHANGE_RESUME_2 _UxGT("na pokračovanie") + #define MSG_FILAMENT_CHANGE_RESUME_3 _UxGT("tlače") +#else // LCD_HEIGHT < 4 + // Up to 2 lines allowed + #define MSG_FILAMENT_CHANGE_INIT_1 _UxGT("Čakajte...") + #define MSG_FILAMENT_CHANGE_UNLOAD_1 _UxGT("Vysúvanie...") + #define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("Vložte, kliknite") + #define MSG_FILAMENT_CHANGE_HEATING_1 _UxGT("Ohrev...") + #define MSG_FILAMENT_CHANGE_LOAD_1 _UxGT("Zavádzanie...") + #define MSG_FILAMENT_CHANGE_EXTRUDE_1 _UxGT("Vytlačovanie...") + #define MSG_FILAMENT_CHANGE_RESUME_1 _UxGT("Pokračovanie...") +#endif // LCD_HEIGHT < 4 + +#endif // LANGUAGE_SK_UTF_H diff --git a/trunk/Arduino/Marlin_1.1.6/language_test.h b/trunk/Arduino/Marlin_1.1.6/language_test.h new file mode 100644 index 00000000..8823bd5f --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/language_test.h @@ -0,0 +1,235 @@ +/** + * 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 . + * + */ + +/** + * TEST + * + * LCD Menu Messages + * See also http://marlinfw.org/docs/development/lcd_language.html + * + */ +#ifndef LANGUAGE_TEST_H +#define LANGUAGE_TEST_H + +// Select ONE of the following Mappers. +// They decide what to do with a symbol in the area of [0x80:0xFF]. They take a symbol of this language file and make them point +// into an array with 128 cells, where they'll find the place of the symbol of the font in use. +// +// a.)For ASCII coded Language_xx.h files like (en) there are no occurrences of symbols above 0x7F so no mapper is needed. +// If such a symbol appears it is mapped directly into the font. This is the case for the language files we used until now, with all the STR_XX or +// "\xxx" symbols. All Symbols are only one byte long. +// b.) For Unicoded Language_xx.h files (currently ru, de and kana_utf8 ) the non ASCII [0x00-0x7F] symbols are represented by more than one byte. +// In the case of two bytes the first is pointing to a 'codepage' and the second to a place in the codepage. These codepages contain 64 symbols. +// So two of them can be mapped. For most of the European languages the necessary symbols are contained in the pages C2 and C3. Cyrillic uses D0 +// and D1. +// c.) For katakana (one of the Japanese symbol sets) Unicode uses 3 bytes. Here the second byte also points to a codepage and byte 3 to the symbol. +// I hope the pages E282 and E283 are sufficient to write katakana. +// Kanji (an other Japanese symbol set) uses far more than two codepages. So currently I don't see a chance to map the Unicodes. Its not +// impossible to have a close to direct mapping but will need giant conversion tables and fonts (we don't want to have in a embedded system). + +//#define MAPPER_C2C3 // For most European languages when language file is in utf8 +//#define MAPPER_D0D1 // For Cyrillic +//#define MAPPER_E382E383 // For Katakana +//#define MAPPER_NON // For direct ascii codes. Fall back mapper - if no other is defined. + + +// Select the better font for full graphic displays. +//#define DISPLAY_CHARSET_ISO10646_1 +//#define DISPLAY_CHARSET_ISO10646_5 +//#define DISPLAY_CHARSET_ISO10646_GREEK +//#define DISPLAY_CHARSET_ISO10646_KANA + + + +// next 5 lines select variants in this file only +#define DISPLAYTEST +//#define WEST +//#define CYRIL +//#define KANA + + +// TESTSTRINGS + +#define STRG_ASCII_2 " !\"#$%&'()*+,-./" +#define STRG_ASCII_3 "0123456789:;<=>?" +#define STRG_ASCII_4 "@ABCDEFGHIJKLMNO" +#define STRG_ASCII_5 "PQRSTUVWXYZ[\]^_" +#define STRG_ASCII_6 "`abcdefghijklmno" +#define STRG_ASCII_7 "pqrstuvwxyz{|}~" + +#define STRG_C2_8 "" +#define STRG_C2_9 "" +#define STRG_C2_a " ¡¢£¤¥¦§¨©ª«¬­®¯" +#define STRG_C2_b "°±²³´µ¶·¸¹º»¼½¾¿" +#define STRG_C3_8 "ÈÁÂÃÄÅÆÇÈÉÊËÌÍÎÏ" +#define STRG_C3_9 "ÐÑÒÓÔÕÖרÙÚÛÜÝÞß" +#define STRG_C3_a "àáâãäåæçèéêëìíîï" +#define STRG_C3_b "ðñòóôõö÷øùúûüýþÿ" + +#define STRG_D0_8 "ЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏ" +#define STRG_D0_9 "АБВГДЕЖЗИЙКЛМНОП" +#define STRG_D0_a "РСТУФХЦЧШЩЪЫЬЭЮЯ" +#define STRG_D0_b "абвгдежзийклмноп" +#define STRG_D1_8 "рстуфхцчшщъыьэюя" +#define STRG_D1_9 "ѐёђѓєѕіїјљњћќѝўџ" +#define STRG_D1_a "ѠѡѢѣѤѥѦѧѨѩѪѫѬѭѮѯ" +#define STRG_D1_b "ѰѱѲѳѴѵѶѷѸѹѺѻѼѽѾѿ" + +#define STRG_E382_8 "よめもゃやゅゆょよらりるれろゎわ" +#define STRG_E382_9 "ゐゑをんゔゕゖ゗゘゙゚゛ ゜ゝゞゟ" +#define STRG_E382_a "゠ァアィイゥウェエォオカガキギク" +#define STRG_E382_b "グケゲコゴサザシジスズセゼソゾタ" +#define STRG_E383_8 "トチヂッツヅテデトドナニヌネノハ" +#define STRG_E383_9 "バパヒビピフブプヘベペホボポマミ" +#define STRG_E383_a "ムメモャヤュユョヨラリルレロヮワ" +#define STRG_E383_b "ヰヱヲンヴヵヶヷヸヹヺ・ーヽヾヿ" + +#define STRG_OKTAL_0 "\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017" +#define STRG_OKTAL_1 "\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" +#define STRG_OKTAL_2 "\040\041\042\043\044\045\046\047\050\051\052\053\054\055\056\057" +#define STRG_OKTAL_3 "\060\061\062\063\064\065\066\067\070\071\072\073\074\075\076\077" +#define STRG_OKTAL_4 "\100\101\102\103\104\105\106\107\110\111\112\113\114\115\116\117" +#define STRG_OKTAL_5 "\120\121\122\123\124\125\126\127\130\131\132\133\134\135\136\137" +#define STRG_OKTAL_6 "\140\141\142\143\144\145\146\147\150\151\152\153\154\155\156\157" +#define STRG_OKTAL_7 "\160\161\162\163\164\165\166\167\170\171\172\173\174\175\176\177" +#define STRG_OKTAL_8 "\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217" +#define STRG_OKTAL_9 "\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237" +#define STRG_OKTAL_a "\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257" +#define STRG_OKTAL_b "\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277" +#define STRG_OKTAL_c "\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317" +#define STRG_OKTAL_d "\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337" +#define STRG_OKTAL_e "\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357" +#define STRG_OKTAL_f "\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377" + +#if ENABLED(DISPLAYTEST) + #define WELCOME_MSG "Language TEST" + + #define MSG_WATCH "Display test" + #define MSG_PREPARE STRG_OKTAL_b + #define MSG_CONTROL STRG_OKTAL_c +#endif + +#if ENABLED(WEST) + #define WELCOME_MSG "Language TEST" + + #define MSG_WATCH "\001\002\003\004\005\006\007\010\011" + #define MSG_PREPARE "UTF8" + #define MSG_CONTROL "ASCII" + + //#define MSG_MAIN ".." + #define MSG_DISABLE_STEPPERS STRG_C2_8 + #define MSG_AUTO_HOME STRG_C2_9 + #define MSG_SET_HOME_OFFSETS STRG_C2_a + #define MSG_PREHEAT_1 STRG_C2_b + #define MSG_PREHEAT_2 STRG_C3_8 + #define MSG_COOLDOWN STRG_C3_9 + #define MSG_SWITCH_PS_OFF STRG_C3_a + #define MSG_MOVE_AXIS STRG_C3_b + + #define MSG_MAIN STRG_OKTAL_2 + #define MSG_TEMPERATURE STRG_OKTAL_3 + #define MSG_MOTION STRG_OKTAL_4 + #define MSG_FILAMENT STRG_OKTAL_5 + #define MSG_CONTRAST STRG_OKTAL_6 + #define MSG_RESTORE_FAILSAFE STRG_OKTAL_7 + + #define MSG_NOZZLE STRG_OKTAL_8 + #define MSG_FAN_SPEED STRG_OKTAL_9 + #define MSG_AUTOTEMP STRG_OKTAL_a + #define MSG_MIN STRG_OKTAL_b + #define MSG_MAX STRG_OKTAL_c + #define MSG_FACTOR STRG_OKTAL_d + #define MSG_PID_P STRG_OKTAL_e + #define MSG_PID_I STRG_OKTAL_f + +#endif + +#if ENABLED(CYRIL) + #define WELCOME_MSG "Language TEST" + + #define MSG_WATCH "\001\002\003\004\005\006\007\010\011" + #define MSG_PREPARE "UTF8" + #define MSG_CONTROL "ASCII" + + //#define MSG_MAIN ".." + #define MSG_DISABLE_STEPPERS STRG_D0_8 + #define MSG_AUTO_HOME STRG_D0_9 + #define MSG_SET_HOME_OFFSETS STRG_D0_a + #define MSG_PREHEAT_1 STRG_D0_b + #define MSG_PREHEAT_2 STRG_D1_8 + #define MSG_COOLDOWN STRG_D1_9 + #define MSG_SWITCH_PS_OFF STRG_D1_a + #define MSG_MOVE_AXIS STRG_D1_b + + #define MSG_MAIN STRG_OKTAL_2 + #define MSG_TEMPERATURE STRG_OKTAL_3 + #define MSG_MOTION STRG_OKTAL_4 + #define MSG_FILAMENT STRG_OKTAL_5 + #define MSG_CONTRAST STRG_OKTAL_6 + #define MSG_RESTORE_FAILSAFE STRG_OKTAL_7 + + #define MSG_NOZZLE STRG_OKTAL_8 + #define MSG_FAN_SPEED STRG_OKTAL_9 + #define MSG_AUTOTEMP STRG_OKTAL_a + #define MSG_MIN STRG_OKTAL_b + #define MSG_MAX STRG_OKTAL_c + #define MSG_FACTOR STRG_OKTAL_d + #define MSG_PID_P STRG_OKTAL_e + #define MSG_PID_I STRG_OKTAL_f + +#endif + +#if ENABLED(KANA) + #define WELCOME_MSG "Language TEST" + + #define MSG_WATCH "\001\002\003\004\005\006\007\010\011" + #define MSG_PREPARE "UTF8" + #define MSG_CONTROL "ASCII" + + //#define MSG_MAIN ".." + #define MSG_DISABLE_STEPPERS STRG_E382_8 + #define MSG_AUTO_HOME STRG_E382_9 + #define MSG_SET_HOME_OFFSETS STRG_E382_a + #define MSG_PREHEAT_1 STRG_E382_b + #define MSG_PREHEAT_2 STRG_E383_8 + #define MSG_COOLDOWN STRG_E383_9 + #define MSG_SWITCH_PS_OFF STRG_E383_a + #define MSG_MOVE_AXIS STRG_E383_b + + #define MSG_MAIN STRG_OKTAL_2 + #define MSG_TEMPERATURE STRG_OKTAL_3 + #define MSG_MOTION STRG_OKTAL_4 + #define MSG_FILAMENT STRG_OKTAL_5 + #define MSG_CONTRAST STRG_OKTAL_6 + #define MSG_RESTORE_FAILSAFE STRG_OKTAL_7 + + #define MSG_NOZZLE STRG_OKTAL_8 + #define MSG_FAN_SPEED STRG_OKTAL_9 + #define MSG_AUTOTEMP STRG_OKTAL_a + #define MSG_MIN STRG_OKTAL_b + #define MSG_MAX STRG_OKTAL_c + #define MSG_FACTOR STRG_OKTAL_d + #define MSG_PID_P STRG_OKTAL_e + #define MSG_PID_I STRG_OKTAL_f +#endif + +#endif // LANGUAGE_TEST_H diff --git a/trunk/Arduino/Marlin_1.1.6/language_tr.h b/trunk/Arduino/Marlin_1.1.6/language_tr.h new file mode 100644 index 00000000..daaa4c56 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/language_tr.h @@ -0,0 +1,269 @@ +/** + * 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 . + * + */ + +/** + * Turkish + * + * LCD Menu Messages + * See also http://marlinfw.org/docs/development/lcd_language.html + * + */ +#ifndef LANGUAGE_TR_H +#define LANGUAGE_TR_H + +#define MAPPER_C2C3_TR +#define DISPLAY_CHARSET_ISO10646_TR + +#if DISABLED(DOGLCD) + #error "Turkish needs a graphical display." +#endif + +#define WELCOME_MSG MACHINE_NAME _UxGT(" hazır.") // hazır. +#define MSG_SD_INSERTED _UxGT("SD Yerleşti.") // SD Yerleşti. +#define MSG_SD_REMOVED _UxGT("SD Çıkarıldı.") // SD Çıkarıldı. +#define MSG_LCD_ENDSTOPS _UxGT("Endstops") // Max length 8 characters // Endstops +#define MSG_MAIN _UxGT("Ana") // Ana +#define MSG_BACK _UxGT("Geri") // Geri +#define MSG_AUTOSTART _UxGT("Otobaşlat") // Otobaşlat +#define MSG_DISABLE_STEPPERS _UxGT("Motorları Durdur") // Motorları Durdur +#define MSG_DEBUG_MENU _UxGT("Hata Ayıklama") // Hata Ayıklama +#define MSG_PROGRESS_BAR_TEST _UxGT("Durum Çubuğu Testi") // Durum Çubuğu Testi +#define MSG_AUTO_HOME _UxGT("Eksenleri Sıfırla") // Eksenleri Sıfırla +#define MSG_AUTO_HOME_X _UxGT("X Sıfırla") // X Sıfırla +#define MSG_AUTO_HOME_Y _UxGT("Y Sıfırla") // Y Sıfırla +#define MSG_AUTO_HOME_Z _UxGT("Z Sıfırla") // Z Sıfırla +#define MSG_LEVEL_BED_HOMING _UxGT("XYZ Sıfırlanıyor") // XYZ Sıfırlanıyor +#define MSG_LEVEL_BED_WAITING _UxGT("Başlatmak için tıkla") // Başlatmak için tıkla +#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Sıradaki Nokta") // Sıradaki Nokta +#define MSG_LEVEL_BED_DONE _UxGT("Seviyeleme Tamam!") // Seviyeleme Tamam! +#define MSG_SET_HOME_OFFSETS _UxGT("Offset Ayarla") // Offset Ayarla +#define MSG_HOME_OFFSETS_APPLIED _UxGT("Offset Tamam") // Offset Tamam +#define MSG_SET_ORIGIN _UxGT("Sıfır Belirle") // Sıfır Belirle +#define MSG_PREHEAT_1 _UxGT("Ön Isınma PLA") // Ön Isınma PLA +#define MSG_PREHEAT_1_N MSG_PREHEAT_1 _UxGT(" ") // +#define MSG_PREHEAT_1_ALL MSG_PREHEAT_1 _UxGT(" Tüm") // Tüm +#define MSG_PREHEAT_1_END MSG_PREHEAT_1 _UxGT(" Nozül") // Nozül +#define MSG_PREHEAT_1_BEDONLY MSG_PREHEAT_1 _UxGT(" Tabla") // Tabla +#define MSG_PREHEAT_1_SETTINGS MSG_PREHEAT_1 _UxGT(" Ayar") // Ayar +#define MSG_PREHEAT_2 _UxGT("Ön Isınma ABS") // Ön Isınma ABS +#define MSG_PREHEAT_2_N MSG_PREHEAT_2 _UxGT(" ") // +#define MSG_PREHEAT_2_ALL MSG_PREHEAT_2 _UxGT(" Tüm") // Tüm +#define MSG_PREHEAT_2_END MSG_PREHEAT_2 _UxGT(" Nozül") // Nozül +#define MSG_PREHEAT_2_BEDONLY MSG_PREHEAT_2 _UxGT(" Tabla") // Tabla +#define MSG_PREHEAT_2_SETTINGS MSG_PREHEAT_2 _UxGT(" Ayar") // Ayar +#define MSG_COOLDOWN _UxGT("Soğut") // Soğut +#define MSG_SWITCH_PS_ON _UxGT("Gücü Aç") // Gücü Aç +#define MSG_SWITCH_PS_OFF _UxGT("Gücü Kapat") // Gücü Kapat +#define MSG_EXTRUDE _UxGT("Extrude") // Extrude +#define MSG_RETRACT _UxGT("Geri Çek") // Geri Çek +#define MSG_MOVE_AXIS _UxGT("Eksen Yönet") // Eksenleri Yönet +#define MSG_BED_LEVELING _UxGT("Tabla Seviyele") // Tabla Seviyele +#define MSG_LEVEL_BED _UxGT("Tabla Seviyele") // Tabla Seviyele +#define MSG_MOVING _UxGT("Konumlanıyor...") // Konumlanıyor... +#define MSG_FREE_XY _UxGT("Durdur XY") // Durdur XY +#define MSG_MOVE_X _UxGT("X") // X +#define MSG_MOVE_Y _UxGT("Y") // Y +#define MSG_MOVE_Z _UxGT("Z") // Z +#define MSG_MOVE_E _UxGT("Ekstruder") // Ekstruder +#define MSG_MOVE_01MM _UxGT("0.1mm") // 0.1mm +#define MSG_MOVE_1MM _UxGT("1mm") // 1mm +#define MSG_MOVE_10MM _UxGT("10mm") // 10mm +#define MSG_SPEED _UxGT("Hız") // Hız +#define MSG_BED_Z _UxGT("Z Mesafesi") // Z Mesafesi +#define MSG_NOZZLE _UxGT("Nozül") // Nozül +#define MSG_BED _UxGT("Tabla") // Tabla +#define MSG_FAN_SPEED _UxGT("Fan Hızı") // Fan Hızı +#define MSG_FLOW _UxGT("Akış") // Akış +#define MSG_CONTROL _UxGT("Kontrol") // Kontrol +#define MSG_MIN _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" Min") // Min +#define MSG_MAX _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" Max") // Max +#define MSG_FACTOR _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" Çarpan") // Çarpan +#define MSG_AUTOTEMP _UxGT("Autotemp") // Autotemp +#define MSG_ON _UxGT("On ") // On +#define MSG_OFF _UxGT("Off") // Off +#define MSG_PID_P _UxGT("PID-P") // PID-P +#define MSG_PID_I _UxGT("PID-I") // PID-I +#define MSG_PID_D _UxGT("PID-D") // PID-D +#define MSG_PID_C _UxGT("PID-C") // PID-C +#define MSG_SELECT _UxGT("Seç") // Seç +#define MSG_ACC _UxGT("İvme") // İvme +#define MSG_JERK _UxGT("Jerk") +#define MSG_VX_JERK _UxGT("Vx-Jerk") // Vx-Jerk +#define MSG_VY_JERK _UxGT("Vy-Jerk") // Vy-Jerk +#define MSG_VZ_JERK _UxGT("Vz-jerk") // Vz-Jerk +#define MSG_VE_JERK _UxGT("Ve-jerk") // Ve-Jerk +#define MSG_VMAX _UxGT("Vmax ") // Vmax +#define MSG_VMIN _UxGT("Vmin") // Vmin +#define MSG_VTRAV_MIN _UxGT("VTrav min") // Vtrav min +#define MSG_AMAX _UxGT("Amax ") // Amax +#define MSG_A_RETRACT _UxGT("A-retract") // A-retract +#define MSG_A_TRAVEL _UxGT("A-travel") // A-travel +#define MSG_STEPS_PER_MM _UxGT("Steps/mm") // Xsteps/mm +#define MSG_XSTEPS _UxGT("Xsteps/mm") // Xsteps/mm +#define MSG_YSTEPS _UxGT("Ysteps/mm") // Ysteps/mm +#define MSG_ZSTEPS _UxGT("Zsteps/mm") // Zsteps/mm +#define MSG_ESTEPS _UxGT("Esteps/mm") // Esteps/mm +#define MSG_E1STEPS _UxGT("E1steps/mm") // E1steps/mm +#define MSG_E2STEPS _UxGT("E2steps/mm") // E2steps/mm +#define MSG_E3STEPS _UxGT("E3steps/mm") // E3steps/mm +#define MSG_E4STEPS _UxGT("E4steps/mm") // E4steps/mm +#define MSG_E5STEPS _UxGT("E5steps/mm") // E4steps/mm +#define MSG_TEMPERATURE _UxGT("Sıcaklık") // Sıcaklık +#define MSG_MOTION _UxGT("Hareket") // Hareket +#define MSG_FILAMENT _UxGT("Filaman") // Filaman +#define MSG_VOLUMETRIC_ENABLED _UxGT("E in mm3") // E in mm3 +#define MSG_FILAMENT_DIAM _UxGT("Fil. Çap") // Fil. Çap +#define MSG_ADVANCE_K _UxGT("K İlerlet") // K İlerlet +#define MSG_CONTRAST _UxGT("LCD Kontrast") // LCD Kontrast +#define MSG_STORE_EEPROM _UxGT("Hafızaya Al") // Hafızaya Al +#define MSG_LOAD_EEPROM _UxGT("Hafızadan Yükle") // Hafızadan Yükle +#define MSG_RESTORE_FAILSAFE _UxGT("Fabrika Ayarları") // Fabrika Ayarları +#define MSG_REFRESH _UxGT("Yenile") // Yenile +#define MSG_WATCH _UxGT("Bilgi Ekranı") // Bilgi Ekranı +#define MSG_PREPARE _UxGT("Hazırlık") // Hazırlık +#define MSG_TUNE _UxGT("Ayar") // Ayar +#define MSG_PAUSE_PRINT _UxGT("Duraklat") // Duraklat +#define MSG_RESUME_PRINT _UxGT("Sürdür") // Sürdür +#define MSG_STOP_PRINT _UxGT("Durdur") // Durdur +#define MSG_CARD_MENU _UxGT("SD den Yazdır") // SD den Yazdır +#define MSG_NO_CARD _UxGT("SD Kart Yok") // SD Kart Yok +#define MSG_DWELL _UxGT("Uyku...") // Uyku... +#define MSG_USERWAIT _UxGT("Operatör bekleniyor...") // Operatör bekleniyor... +#define MSG_RESUMING _UxGT("Baskı Sürdürülüyor") // Baskı Sürdürülüyor +#define MSG_PRINT_ABORTED _UxGT("Baskı Durduruldu") // Baskı Durduruldu +#define MSG_NO_MOVE _UxGT("İşlem yok.") // İşlem yok. +#define MSG_KILLED _UxGT("Kilitlendi. ") // Kilitlendi. +#define MSG_STOPPED _UxGT("Durdu. ") // Durdu. +#define MSG_CONTROL_RETRACT _UxGT("Geri Çek mm") // Geri Çek mm +#define MSG_CONTROL_RETRACT_SWAP _UxGT("Swap Re.mm") // Swap Re.mm +#define MSG_CONTROL_RETRACTF _UxGT("Geri Çekme V") // Geri Çekme V +#define MSG_CONTROL_RETRACT_ZLIFT _UxGT("Hop mm") // Hop mm +#define MSG_CONTROL_RETRACT_RECOVER _UxGT("UnRet mm") // UnRet mm +#define MSG_CONTROL_RETRACT_RECOVER_SWAP _UxGT("S UnRet mm") // S UnRetmm +#define MSG_CONTROL_RETRACT_RECOVERF _UxGT("UnRet V") // UnRet V +#define MSG_AUTORETRACT _UxGT("AutoRetr.") // AutoRetr. +#define MSG_FILAMENTCHANGE _UxGT("Filaman Değiştir") // Filaman Değiştir +#define MSG_INIT_SDCARD _UxGT("Init. SD") // Init. SD +#define MSG_CNG_SDCARD _UxGT("SD Değiştir") // SD Değiştir +#define MSG_ZPROBE_OUT _UxGT("Z Prob Açık. Tabla") // Z Prob Açık. Tabla +#define MSG_BLTOUCH_SELFTEST _UxGT("BLTouch Self-Test") // BLTouch Self-Test +#define MSG_BLTOUCH_RESET _UxGT("Sıfırla BLTouch") // Sıfırla BLTouch +#define MSG_HOME _UxGT("Sıfırla") // Sıfırla +#define MSG_FIRST _UxGT("önce") // Önce +#define MSG_ZPROBE_ZOFFSET _UxGT("Z Offset") // Z Offset +#define MSG_BABYSTEP_X _UxGT("Miniadım X") // Miniadım X +#define MSG_BABYSTEP_Y _UxGT("Miniadım Y") // Miniadım Y +#define MSG_BABYSTEP_Z _UxGT("Miniadım Z") // Miniadım Z +#define MSG_ENDSTOP_ABORT _UxGT("Endstop iptal") // Endstop iptal +#define MSG_HEATING_FAILED_LCD _UxGT("Isınma başarısız") // Isınma başarısız +#define MSG_ERR_REDUNDANT_TEMP _UxGT("Hata: Geçersiz Sıcaklık") // Hata: Geçersiz Sıcaklık +#define MSG_THERMAL_RUNAWAY _UxGT("TERMAL PROBLEM") // TERMAL PROBLEM +#define MSG_ERR_MAXTEMP _UxGT("Hata: MAXSICAKLIK") // Hata: MAXSICAKLIK +#define MSG_ERR_MINTEMP _UxGT("Hata: MINSICAKLIK") // Hata: MINSICAKLIK +#define MSG_ERR_MAXTEMP_BED _UxGT("Hata: MAXSIC. TABLA") // Hata: MAXSIC. TABLA +#define MSG_ERR_MINTEMP_BED _UxGT("Hata: MINSIC. TABLA") // Hata: MINSIC. TABLA +#define MSG_ERR_Z_HOMING _UxGT("G28 Z Yapılamaz") // G28 Z Yapılamaz +#define MSG_HALTED _UxGT("YAZICI DURDURULDU") // YAZICI DURDURULDU +#define MSG_PLEASE_RESET _UxGT("Lütfen resetleyin") // Lütfen resetleyin +#define MSG_SHORT_DAY _UxGT("G") // One character only // G +#define MSG_SHORT_HOUR _UxGT("S") // One character only // S +#define MSG_SHORT_MINUTE _UxGT("D") // One character only // D +#define MSG_HEATING _UxGT("Isınıyor...") // Isınıyor... +#define MSG_HEATING_COMPLETE _UxGT("Isınma tamam.") // Isınma tamam. +#define MSG_BED_HEATING _UxGT("Tabla Isınıyor.") // Tabla Isınıyor. +#define MSG_BED_DONE _UxGT("Tabla hazır.") // Tabla hazır. +#define MSG_DELTA_CALIBRATE _UxGT("Delta Kalibrasyonu") // Delta Kalibrasyonu +#define MSG_DELTA_CALIBRATE_X _UxGT("Ayarla X") // Ayarla X +#define MSG_DELTA_CALIBRATE_Y _UxGT("Ayarla Y") // Ayarla Y +#define MSG_DELTA_CALIBRATE_Z _UxGT("Ayarla Z") // Ayarla Z +#define MSG_DELTA_CALIBRATE_CENTER _UxGT("Ayarla Merkez") // Ayarla Merkez +#define MSG_DELTA_AUTO_CALIBRATE _UxGT("Oto Kalibrasyon") // Oto Kalibrasyon +#define MSG_DELTA_HEIGHT_CALIBRATE _UxGT("Delta Yük. Ayarla") // Delta Yük. Ayarla +#define MSG_INFO_MENU _UxGT("Yazıcı Hakkında") // Yazıcı Hakkında +#define MSG_INFO_PRINTER_MENU _UxGT("Yazıcı Bilgisi") // Yazıcı Bilgisi +#define MSG_INFO_STATS_MENU _UxGT("İstatistikler") // İstatistikler +#define MSG_INFO_BOARD_MENU _UxGT("Kontrolör Bilgisi") // Kontrol Bilgisi +#define MSG_INFO_THERMISTOR_MENU _UxGT("Termistörler") // Termistörler +#define MSG_INFO_EXTRUDERS _UxGT("Ekstruderler") // Ekstruderler +#define MSG_INFO_BAUDRATE _UxGT("İletişim Hızı") // İletişim Hızı +#define MSG_INFO_PROTOCOL _UxGT("Protokol") // Protokol +#define MSG_CASE_LIGHT _UxGT("Aydınlatmayı") // Aydınlatmayı Aç + +#if LCD_WIDTH >= 20 + #define MSG_INFO_PRINT_COUNT _UxGT("Baskı Sayısı") // Baskı Sayısı + #define MSG_INFO_COMPLETED_PRINTS _UxGT("Tamamlanan") // Tamamlanan + #define MSG_INFO_PRINT_TIME _UxGT("Toplam Baskı Süresi") // Toplam Baskı Süresi + #define MSG_INFO_PRINT_LONGEST _UxGT("En Uzun Baskı Süresi") // En Uzun Baskı Süresi + #define MSG_INFO_PRINT_FILAMENT _UxGT("Toplam Filaman") // Toplam Filaman +#else + #define MSG_INFO_PRINT_COUNT _UxGT("Baskı") // Baskı + #define MSG_INFO_COMPLETED_PRINTS _UxGT("Tamamlanan") // Tamamlanan + #define MSG_INFO_PRINT_TIME _UxGT("Süre") // Süre + #define MSG_INFO_PRINT_LONGEST _UxGT("En Uzun") // En Uzun + #define MSG_INFO_PRINT_FILAMENT _UxGT("Filaman") // Filaman +#endif + +#define MSG_INFO_MIN_TEMP _UxGT("Min Sıc.") // Min Sıcak. +#define MSG_INFO_MAX_TEMP _UxGT("Max Sıc.") // Max Sıcak. +#define MSG_INFO_PSU _UxGT("Güç Kaynağı") // Güç Kaynağı + +#define MSG_DRIVE_STRENGTH _UxGT("Sürücü Gücü") // Sürücü Gücü +#define MSG_DAC_PERCENT _UxGT("Sürücü %") // Sürücü % +#define MSG_FILAMENT_CHANGE_HEADER _UxGT("PRINT PAUSED") +#define MSG_FILAMENT_CHANGE_OPTION_HEADER _UxGT("RESUME OPTIONS:") +#define MSG_FILAMENT_CHANGE_OPTION_HEADER _UxGT("Seçenekler:") // Seçenekler: +#define MSG_FILAMENT_CHANGE_OPTION_EXTRUDE _UxGT("Daha Akıt") // Daha Akıt +#define MSG_FILAMENT_CHANGE_OPTION_RESUME _UxGT("Baskıyı sürdür") // Baskıyı sürdür +#define MSG_FILAMENT_CHANGE_MINTEMP _UxGT("Min. Sıcaklık") // Min. Sıcaklık: +#define MSG_FILAMENT_CHANGE_NOZZLE _UxGT(" Nozül: ") // Nozül: + +#if LCD_HEIGHT >= 4 + // Up to 3 lines allowed + #define MSG_FILAMENT_CHANGE_INIT_1 _UxGT("Başlama bekleniyor") // Başlama bekleniyor + #define MSG_FILAMENT_CHANGE_INIT_2 _UxGT("filamanın") // filamanın + #define MSG_FILAMENT_CHANGE_INIT_3 _UxGT("değişimi") // değişimi + #define MSG_FILAMENT_CHANGE_UNLOAD_1 _UxGT("Bekleniyor") // Bekleniyor + #define MSG_FILAMENT_CHANGE_UNLOAD_2 _UxGT("filamanın çıkması") // filamanın çıkması + #define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("Filamanı yükle") // Filamanı yükle + #define MSG_FILAMENT_CHANGE_INSERT_2 _UxGT("ve devam için") // ve devam için + #define MSG_FILAMENT_CHANGE_INSERT_3 _UxGT("tuşa bas...") // tuşa bas... + #define MSG_FILAMENT_CHANGE_HEAT_1 _UxGT("Nozülü Isıtmak için") // Nozülü Isıtmak için + #define MSG_FILAMENT_CHANGE_HEAT_2 _UxGT("Butona Bas.") // Butona Bas. + #define MSG_FILAMENT_CHANGE_HEATING_1 _UxGT("Nozül Isınıyor") // Nozül Isınıyor + #define MSG_FILAMENT_CHANGE_HEATING_2 _UxGT("Lütfen Bekleyin...") // Lütfen Bekleyin... + #define MSG_FILAMENT_CHANGE_LOAD_1 _UxGT("Bekleniyor") // Bekleniyor + #define MSG_FILAMENT_CHANGE_LOAD_2 _UxGT("filamanın yüklenmesi") // filamanın yüklenmesi + #define MSG_FILAMENT_CHANGE_EXTRUDE_1 _UxGT("Bekleniyor") // Bekleniyor + #define MSG_FILAMENT_CHANGE_EXTRUDE_2 _UxGT("filaman akması") // filaman akması + #define MSG_FILAMENT_CHANGE_RESUME_1 _UxGT("Baskının sürdürülmesini") // Baskının sürdürülmesini + #define MSG_FILAMENT_CHANGE_RESUME_2 _UxGT("bekle") // bekle +#else // LCD_HEIGHT < 4 + // Up to 2 lines allowed + #define MSG_FILAMENT_CHANGE_INIT_1 _UxGT("Lütfen bekleyiniz...") // Lütfen bekleyiniz... + #define MSG_FILAMENT_CHANGE_UNLOAD_1 _UxGT("Çıkartılıyor...") // Çıkartılıyor... + #define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("Yükle ve bas") // Yükle ve bas + #define MSG_FILAMENT_CHANGE_LOAD_1 _UxGT("Yüklüyor...") // Yüklüyor... + #define MSG_FILAMENT_CHANGE_EXTRUDE_1 _UxGT("Akıtılıyor...") // Akıtılıyor... + #define MSG_FILAMENT_CHANGE_RESUME_1 _UxGT("Sürdürülüyor...") // Sürdürülüyor... +#endif // LCD_HEIGHT < 4 + +#endif // LANGUAGE_TR_H diff --git a/trunk/Arduino/Marlin_1.1.6/language_uk.h b/trunk/Arduino/Marlin_1.1.6/language_uk.h new file mode 100644 index 00000000..e687e49b --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/language_uk.h @@ -0,0 +1,240 @@ +/** + * 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 . + * + */ + +/** + * Ukrainian + * + * LCD Menu Messages + * See also http://marlinfw.org/docs/development/lcd_language.html + * + */ +#ifndef LANGUAGE_UK_H +#define LANGUAGE_UK_H + +#define MAPPER_D0D1 // For Cyrillic +#define DISPLAY_CHARSET_ISO10646_5 + +#define WELCOME_MSG MACHINE_NAME _UxGT(" готовий.") +#define MSG_SD_INSERTED _UxGT("Картка вставлена") +#define MSG_SD_REMOVED _UxGT("Картка видалена") +#define MSG_LCD_ENDSTOPS _UxGT("Кінцевик") // Max length 8 characters +#define MSG_MAIN _UxGT("Меню") +#define MSG_AUTOSTART _UxGT("Автостарт") +#define MSG_DISABLE_STEPPERS _UxGT("Вимк. двигуни") +#define MSG_AUTO_HOME _UxGT("Авто паркування") +#define MSG_AUTO_HOME_X _UxGT("Паркування X") +#define MSG_AUTO_HOME_Y _UxGT("Паркування Y") +#define MSG_AUTO_HOME_Z _UxGT("Паркування Z") +#define MSG_LEVEL_BED_HOMING _UxGT("Паркування XYZ") +#define MSG_LEVEL_BED_WAITING _UxGT("Почати") +#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Слідуюча Точка") +#define MSG_LEVEL_BED_DONE _UxGT("Завершено!") +#define MSG_SET_HOME_OFFSETS _UxGT("Зберегти паркув.") +#define MSG_HOME_OFFSETS_APPLIED _UxGT("Зміщення застос.") +#define MSG_SET_ORIGIN _UxGT("Встанов. початок") +#define MSG_PREHEAT_1 _UxGT("Нагрів PLA") +#define MSG_PREHEAT_1_N MSG_PREHEAT_1 _UxGT(" ") +#define MSG_PREHEAT_1_ALL MSG_PREHEAT_1 _UxGT(" Все") +#define MSG_PREHEAT_1_BEDONLY MSG_PREHEAT_1 _UxGT(" Стіл") +#define MSG_PREHEAT_1_SETTINGS MSG_PREHEAT_1 _UxGT(" нал.") +#define MSG_PREHEAT_2 _UxGT("Нагрів ABS") +#define MSG_PREHEAT_2_N MSG_PREHEAT_2 _UxGT(" ") +#define MSG_PREHEAT_2_ALL MSG_PREHEAT_2 _UxGT(" Все") +#define MSG_PREHEAT_2_BEDONLY MSG_PREHEAT_2 _UxGT(" Стіл") +#define MSG_PREHEAT_2_SETTINGS MSG_PREHEAT_2 _UxGT(" нал.") +#define MSG_COOLDOWN _UxGT("Охолодження") +#define MSG_SWITCH_PS_ON _UxGT("Увімкнути живлення") +#define MSG_SWITCH_PS_OFF _UxGT("Вимкнути живлення") +#define MSG_EXTRUDE _UxGT("Екструзія") +#define MSG_RETRACT _UxGT("Втягування") +#define MSG_MOVE_AXIS _UxGT("Рух по осям") +#define MSG_BED_LEVELING _UxGT("Нівелювання столу") +#define MSG_LEVEL_BED _UxGT("Нівелювання столу") +#define MSG_MOVE_X _UxGT("Рух по X") +#define MSG_MOVE_Y _UxGT("Рух по Y") +#define MSG_MOVE_Z _UxGT("Рух по Z") +#define MSG_MOVE_E _UxGT("Екструдер") +#define MSG_MOVE_01MM _UxGT("Рух по 0.1mm") +#define MSG_MOVE_1MM _UxGT("Рух по 1mm") +#define MSG_MOVE_10MM _UxGT("Рух по 10mm") +#define MSG_SPEED _UxGT("Швидкість") +#define MSG_BED_Z _UxGT("Z Столу") +#define MSG_NOZZLE _UxGT("Сопло") +#define MSG_BED _UxGT("Стіл") +#define MSG_FAN_SPEED _UxGT("Охолодж.") +#define MSG_FLOW _UxGT("Потік") +#define MSG_CONTROL _UxGT("Налаштування") +#define MSG_MIN _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" Мін") +#define MSG_MAX _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" Макс") +#define MSG_FACTOR _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" Факт") +#define MSG_AUTOTEMP _UxGT("Автотемпер.") +#define MSG_ON _UxGT("Увімк.") +#define MSG_OFF _UxGT("Вимк. ") +#define MSG_PID_P _UxGT("PID-P") +#define MSG_PID_I _UxGT("PID-I") +#define MSG_PID_D _UxGT("PID-D") +#define MSG_PID_C _UxGT("PID-C") +#define MSG_SELECT _UxGT("Вибрати") +#define MSG_ACC _UxGT("Приск.") +#define MSG_JERK _UxGT("Ривок") +#define MSG_VX_JERK _UxGT("Vx-ривок") +#define MSG_VY_JERK _UxGT("Vy-ривок") +#define MSG_VZ_JERK _UxGT("Vz-ривок") +#define MSG_VE_JERK _UxGT("Ve-ривок") +#define MSG_VMAX _UxGT("Vмакс") +#define MSG_VMIN _UxGT("Vмін") +#define MSG_VTRAV_MIN _UxGT("Vруху мін") +#define MSG_AMAX _UxGT("Aмакс ") +#define MSG_A_RETRACT _UxGT("A-втягув.") +#define MSG_A_TRAVEL _UxGT("A-руху") +#define MSG_STEPS_PER_MM _UxGT("Кроків/мм") +#define MSG_XSTEPS _UxGT("Xкроків/мм") +#define MSG_YSTEPS _UxGT("Yкроків/мм") +#define MSG_ZSTEPS _UxGT("Zкроків/мм") +#define MSG_ESTEPS _UxGT("Eкроків/мм") +#define MSG_E1STEPS _UxGT("E1кроків/мм") +#define MSG_E2STEPS _UxGT("E2кроків/мм") +#define MSG_E3STEPS _UxGT("E3кроків/мм") +#define MSG_E4STEPS _UxGT("E4кроків/мм") +#define MSG_E5STEPS _UxGT("E5кроків/мм") +#define MSG_TEMPERATURE _UxGT("Температура") +#define MSG_MOTION _UxGT("Рух") +#define MSG_FILAMENT _UxGT("Волокно") +#define MSG_VOLUMETRIC_ENABLED _UxGT("E в мм3") +#define MSG_FILAMENT_DIAM _UxGT("Діам. волок.") +#define MSG_CONTRAST _UxGT("контраст LCD") +#define MSG_STORE_EEPROM _UxGT("Зберегти в ПЗП") +#define MSG_LOAD_EEPROM _UxGT("Зчитати з ПЗП") +#define MSG_RESTORE_FAILSAFE _UxGT("Відновити базові") +#define MSG_REFRESH _UxGT("Поновити") +#define MSG_WATCH _UxGT("Інформація") +#define MSG_PREPARE _UxGT("Підготувати") +#define MSG_TUNE _UxGT("Підлаштування") +#define MSG_PAUSE_PRINT _UxGT("Призупинити друк") +#define MSG_RESUME_PRINT _UxGT("Відновити друк") +#define MSG_STOP_PRINT _UxGT("Скасувати друк") +#define MSG_CARD_MENU _UxGT("Друкувати з SD") +#define MSG_NO_CARD _UxGT("Відсутня SD карт.") +#define MSG_DWELL _UxGT("Сплячка...") +#define MSG_USERWAIT _UxGT("Очікування дій...") +#define MSG_RESUMING _UxGT("Відновлення друку") +#define MSG_PRINT_ABORTED _UxGT("Друк скасовано") +#define MSG_NO_MOVE _UxGT("Немає руху.") +#define MSG_KILLED _UxGT("ПЕРЕРВАНО. ") +#define MSG_STOPPED _UxGT("ЗУПИНЕНО. ") +#define MSG_FILAMENTCHANGE _UxGT("Зміна волокна") +#define MSG_INIT_SDCARD _UxGT("Старт SD картки") +#define MSG_CNG_SDCARD _UxGT("Заміна SD карти") +#define MSG_ZPROBE_OUT _UxGT("Z дет. не в межах") +#define MSG_BLTOUCH_SELFTEST _UxGT("BLTouch Само-Тест") +#define MSG_BLTOUCH_RESET _UxGT("Скинути BLTouch") +#define MSG_HOME _UxGT("Дім") // Used as MSG_HOME " " MSG_X MSG_Y MSG_Z " " MSG_FIRST +#define MSG_FIRST _UxGT("перший") +#define MSG_ZPROBE_ZOFFSET _UxGT("Зміщення Z") +#define MSG_BABYSTEP_X _UxGT("Мікрокрок X") +#define MSG_BABYSTEP_Y _UxGT("Мікрокрок Y") +#define MSG_BABYSTEP_Z _UxGT("Мікрокрок Z") +#define MSG_ENDSTOP_ABORT _UxGT("невдача кінцевика") +#define MSG_HEATING_FAILED_LCD _UxGT("Невдалий нагрів") +#define MSG_THERMAL_RUNAWAY _UxGT("ЗБІЙ ТЕМПЕРАТУРИ") +#define MSG_ERR_Z_HOMING _UxGT("G28 Z Відмовлено") +#define MSG_HALTED _UxGT("ПРИНТЕР ЗУПИНЕНО") +#define MSG_PLEASE_RESET _UxGT("Перезавантажте") +#define MSG_SHORT_DAY _UxGT("д") // One character only +#define MSG_SHORT_HOUR _UxGT("г") // One character only +#define MSG_SHORT_MINUTE _UxGT("х") // One character only +#define MSG_HEATING _UxGT("Нагрівання...") +#define MSG_HEATING_COMPLETE _UxGT("Нагріто.") +#define MSG_BED_HEATING _UxGT("Нагрівання столу.") +#define MSG_BED_DONE _UxGT("Стіл нагрітий.") +#define MSG_DELTA_CALIBRATE _UxGT("Калібр. Delta") +#define MSG_DELTA_CALIBRATE_X _UxGT("Калібрування X") +#define MSG_DELTA_CALIBRATE_Y _UxGT("Калібрування Y") +#define MSG_DELTA_CALIBRATE_Z _UxGT("Калібрування Z") +#define MSG_DELTA_CALIBRATE_CENTER _UxGT("Калібр. Центру") + +#define MSG_INFO_MENU _UxGT("Про принтер") +#define MSG_INFO_PRINTER_MENU _UxGT("Інформація") +#define MSG_INFO_STATS_MENU _UxGT("Статистика") +#define MSG_INFO_BOARD_MENU _UxGT("Про плату") +#define MSG_INFO_THERMISTOR_MENU _UxGT("Термістори") +#define MSG_INFO_EXTRUDERS _UxGT("Екструдери") +#define MSG_INFO_BAUDRATE _UxGT("біт/с") +#define MSG_INFO_PROTOCOL _UxGT("Протокол") +#define MSG_CASE_LIGHT _UxGT("Підсвітка") + +#if LCD_WIDTH >= 20 + #define MSG_INFO_PRINT_COUNT _UxGT("К-сть друків") + #define MSG_INFO_COMPLETED_PRINTS _UxGT("Завершено") + #define MSG_INFO_PRINT_TIME _UxGT("Весь час друку") + #define MSG_INFO_PRINT_LONGEST _UxGT("Найдовший час") + #define MSG_INFO_PRINT_FILAMENT _UxGT("Екструдовано") +#else + #define MSG_INFO_PRINT_COUNT _UxGT("Друків") + #define MSG_INFO_COMPLETED_PRINTS _UxGT("Завершено") + #define MSG_INFO_PRINT_TIME _UxGT("Загалом") + #define MSG_INFO_PRINT_LONGEST _UxGT("Найдовший") + #define MSG_INFO_PRINT_FILAMENT _UxGT("Ексдруд.") +#endif + +#define MSG_INFO_MIN_TEMP _UxGT("Мін Темп.") +#define MSG_INFO_MAX_TEMP _UxGT("Макс Темп.") +#define MSG_INFO_PSU _UxGT("Джерело жив.") + +#define MSG_DRIVE_STRENGTH _UxGT("Сила мотору") +#define MSG_DAC_PERCENT _UxGT("% мотору") +#define MSG_DAC_EEPROM_WRITE _UxGT("Запис ЦАП на ПЗП") + +#define MSG_FILAMENT_CHANGE_HEADER _UxGT("PRINT PAUSED") +#define MSG_FILAMENT_CHANGE_OPTION_HEADER _UxGT("RESUME OPTIONS:") +#define MSG_FILAMENT_CHANGE_OPTION_EXTRUDE _UxGT("Екструдувати") +#define MSG_FILAMENT_CHANGE_OPTION_RESUME _UxGT("Відновити друк") + +#if LCD_HEIGHT >= 4 + // Up to 3 lines allowed + #define MSG_FILAMENT_CHANGE_INIT_1 _UxGT("Зачекайте на") + #define MSG_FILAMENT_CHANGE_INIT_2 _UxGT("початок заміни") + #define MSG_FILAMENT_CHANGE_INIT_3 _UxGT("волокна") + #define MSG_FILAMENT_CHANGE_UNLOAD_1 _UxGT("Зачекайте на") + #define MSG_FILAMENT_CHANGE_UNLOAD_2 _UxGT("вивід волокна") + #define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("Вставте волокно") + #define MSG_FILAMENT_CHANGE_INSERT_2 _UxGT("та натисніть для") + #define MSG_FILAMENT_CHANGE_INSERT_3 _UxGT("продовження...") + #define MSG_FILAMENT_CHANGE_LOAD_1 _UxGT("Зачекайте на") + #define MSG_FILAMENT_CHANGE_LOAD_2 _UxGT("ввід волокна") + #define MSG_FILAMENT_CHANGE_EXTRUDE_1 _UxGT("Зачекайте на") + #define MSG_FILAMENT_CHANGE_EXTRUDE_2 _UxGT("екструзію") + #define MSG_FILAMENT_CHANGE_EXTRUDE_3 _UxGT("волокна") + #define MSG_FILAMENT_CHANGE_RESUME_1 _UxGT("Зачекайте на") + #define MSG_FILAMENT_CHANGE_RESUME_2 _UxGT("відновлення") + #define MSG_FILAMENT_CHANGE_RESUME_3 _UxGT("друку") +#else // LCD_HEIGHT < 4 + // Up to 2 lines allowed + #define MSG_FILAMENT_CHANGE_INIT_1 _UxGT("Зачекайте...") + #define MSG_FILAMENT_CHANGE_UNLOAD_1 _UxGT("Вивід...") + #define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("Вставте і нат.") + #define MSG_FILAMENT_CHANGE_LOAD_1 _UxGT("Ввід...") + #define MSG_FILAMENT_CHANGE_EXTRUDE_1 _UxGT("Екструзія...") + #define MSG_FILAMENT_CHANGE_RESUME_1 _UxGT("Відновлення...") +#endif // LCD_HEIGHT < 4 + +#endif // LANGUAGE_UK_H diff --git a/trunk/Arduino/Marlin_1.1.6/language_zh_CN.h b/trunk/Arduino/Marlin_1.1.6/language_zh_CN.h new file mode 100644 index 00000000..af5454b1 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/language_zh_CN.h @@ -0,0 +1,238 @@ +/** + * 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 . + * + */ + +/** + * Simplified Chinese + * + * LCD Menu Messages + * See also http://marlinfw.org/docs/development/lcd_language.html + * + */ +#ifndef LANGUAGE_ZH_CN_H +#define LANGUAGE_ZH_CN_H + +#define WELCOME_MSG MACHINE_NAME _UxGT("已就绪.") //" ready." +#define MSG_SD_INSERTED _UxGT("存储卡已插入") //"Card inserted" +#define MSG_SD_REMOVED _UxGT("存储卡被拔出") //"Card removed" +#define MSG_LCD_ENDSTOPS _UxGT("挡块") //"Endstops" // Max length 8 characters +#define MSG_MAIN _UxGT("主菜单") //"Main" +#define MSG_AUTOSTART _UxGT("自动开始") //"Autostart" +#define MSG_DISABLE_STEPPERS _UxGT("关闭步进电机") //"Disable steppers" +#define MSG_AUTO_HOME _UxGT("回原点") //"Auto home" +#define MSG_AUTO_HOME_X _UxGT("回X原位") //"Home X" +#define MSG_AUTO_HOME_Y _UxGT("回Y原位") //"Home Y" +#define MSG_AUTO_HOME_Z _UxGT("回Z原位") //"Home Z" +#define MSG_LEVEL_BED_HOMING _UxGT("平台调平XYZ归原位") //"Homing XYZ" +#define MSG_LEVEL_BED_WAITING _UxGT("单击开始热床调平") //"Click to Begin" +#define MSG_LEVEL_BED_NEXT_POINT _UxGT("下个热床调平点") //"Next Point" +#define MSG_LEVEL_BED_DONE _UxGT("完成热床调平") //"Leveling Done!" +#define MSG_SET_HOME_OFFSETS _UxGT("设置原点偏移") //"Set home offsets" +#define MSG_HOME_OFFSETS_APPLIED _UxGT("偏移已启用") //"Offsets applied" +#define MSG_SET_ORIGIN _UxGT("设置原点") //"Set origin" +#define MSG_PREHEAT_1 _UxGT("预热PLA") //"Preheat PLA" +#define MSG_PREHEAT_1_N MSG_PREHEAT_1 _UxGT(" ") //MSG_PREHEAT_1 " " +#define MSG_PREHEAT_1_ALL MSG_PREHEAT_1 _UxGT(" 全部") //MSG_PREHEAT_1 " All" +#define MSG_PREHEAT_1_BEDONLY MSG_PREHEAT_1 _UxGT(" 热床") //MSG_PREHEAT_1 " Bed" +#define MSG_PREHEAT_1_SETTINGS MSG_PREHEAT_1 _UxGT(" 设置") //MSG_PREHEAT_1 " conf" +#define MSG_PREHEAT_2 _UxGT("预热ABS") //"Preheat ABS" +#define MSG_PREHEAT_2_N MSG_PREHEAT_2 _UxGT(" ") //MSG_PREHEAT_2 " " +#define MSG_PREHEAT_2_ALL MSG_PREHEAT_2 _UxGT(" 全部") //MSG_PREHEAT_2 " All" +#define MSG_PREHEAT_2_BEDONLY MSG_PREHEAT_2 _UxGT(" 热床") //MSG_PREHEAT_2 " Bed" +#define MSG_PREHEAT_2_SETTINGS MSG_PREHEAT_2 _UxGT(" 设置") //MSG_PREHEAT_2 " conf" +#define MSG_COOLDOWN _UxGT("降温") //"Cooldown" +#define MSG_SWITCH_PS_ON _UxGT("电源打开") //"Switch power on" +#define MSG_SWITCH_PS_OFF _UxGT("电源关闭") //"Switch power off" +#define MSG_EXTRUDE _UxGT("挤出") //"Extrude" +#define MSG_RETRACT _UxGT("回抽") //"Retract" +#define MSG_MOVE_AXIS _UxGT("移动轴") //"Move axis" +#define MSG_BED_LEVELING _UxGT("调平热床") //"Bed leveling" +#define MSG_LEVEL_BED _UxGT("调平热床") //"Level bed" +#define MSG_MOVE_X _UxGT("移动X") //"Move X" +#define MSG_MOVE_Y _UxGT("移动Y") //"Move Y" +#define MSG_MOVE_Z _UxGT("移动Z") //"Move Z" +#define MSG_MOVE_E _UxGT("挤出机") //"Extruder" +#define MSG_MOVE_01MM _UxGT("移动 0.1 mm") //"Move 0.1mm" +#define MSG_MOVE_1MM _UxGT("移动 1 mm") //"Move 1mm" +#define MSG_MOVE_10MM _UxGT("移动 10 mm") //"Move 10mm" +#define MSG_SPEED _UxGT("速率") //"Speed" +#define MSG_BED_Z _UxGT("热床Z") //"Bed Z" +#define MSG_NOZZLE _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" 喷嘴") //"Nozzle" 噴嘴 +#define MSG_BED _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" 热床") //"Bed" +#define MSG_FAN_SPEED _UxGT("风扇速率") //"Fan speed" +#define MSG_FLOW _UxGT("挤出速率") //"Flow" +#define MSG_CONTROL _UxGT("控制") //"Control" +#define MSG_MIN _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" 最小") //" " LCD_STR_THERMOMETER " Min" +#define MSG_MAX _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" 最大") //" " LCD_STR_THERMOMETER " Max" +#define MSG_FACTOR _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" 因数") //" " LCD_STR_THERMOMETER " Fact" +#define MSG_AUTOTEMP _UxGT("自动控温") //"Autotemp" +#define MSG_ON _UxGT("开 ") //"On " +#define MSG_OFF _UxGT("关 ") //"Off" +#define MSG_PID_P _UxGT("PID-P") //"PID-P" +#define MSG_PID_I _UxGT("PID-I") //"PID-I" +#define MSG_PID_D _UxGT("PID-D") //"PID-D" +#define MSG_PID_C _UxGT("PID-C") //"PID-C" +#define MSG_SELECT _UxGT("选择") //"Select" +#define MSG_ACC _UxGT("加速度") //"Accel" acceleration +#define MSG_JERK _UxGT("抖动速率") // "Jerk" +#define MSG_VX_JERK _UxGT("X轴抖动速率") //"Vx-jerk" +#define MSG_VY_JERK _UxGT("Y轴抖动速率") //"Vy-jerk" +#define MSG_VZ_JERK _UxGT("Z轴抖动速率") //"Vz-jerk" +#define MSG_VE_JERK _UxGT("挤出机抖动速率") //"Ve-jerk" +#define MSG_VMAX _UxGT("最大进料速率") //"Vmax " max_feedrate_mm_s +#define MSG_VMIN _UxGT("最小进料速率") //"Vmin" min_feedrate_mm_s +#define MSG_VTRAV_MIN _UxGT("最小移动速率") //"VTrav min" min_travel_feedrate_mm_s, (target) speed of the move +#define MSG_AMAX _UxGT("最大打印加速度") //"Amax " max_acceleration_mm_per_s2, acceleration in units/s^2 for print moves +#define MSG_A_RETRACT _UxGT("收进加速度") //"A-retract" retract_acceleration, E acceleration in mm/s^2 for retracts +#define MSG_A_TRAVEL _UxGT("非打印移动加速度") //"A-travel" travel_acceleration, X, Y, Z acceleration in mm/s^2 for travel (non printing) moves +#define MSG_STEPS_PER_MM _UxGT("轴步数/mm") //"Steps/mm" axis_steps_per_mm, axis steps-per-unit G92 +#define MSG_XSTEPS _UxGT("X轴步数/mm") //"Xsteps/mm" axis_steps_per_mm, axis steps-per-unit G92 +#define MSG_YSTEPS _UxGT("Y轴步数/mm") //"Ysteps/mm" +#define MSG_ZSTEPS _UxGT("Z轴步数/mm") //"Zsteps/mm" +#define MSG_ESTEPS _UxGT("挤出机步数/mm") //"Esteps/mm" +#define MSG_TEMPERATURE _UxGT("温度") //"Temperature" +#define MSG_MOTION _UxGT("运动") //"Motion" +#define MSG_FILAMENT _UxGT("丝料测容") //"Filament" lcd_control_volumetric_menu +#define MSG_VOLUMETRIC_ENABLED _UxGT("测容积mm³") //"E in mm3" volumetric_enabled +#define MSG_FILAMENT_DIAM _UxGT("丝料直径") //"Fil. Dia." +#define MSG_CONTRAST _UxGT("LCD对比度") //"LCD contrast" +#define MSG_STORE_EEPROM _UxGT("保存设置") //"Store memory" +#define MSG_LOAD_EEPROM _UxGT("装载设置") //"Load memory" +#define MSG_RESTORE_FAILSAFE _UxGT("恢复安全值") //"Restore failsafe" +#define MSG_REFRESH _UxGT("刷新") //"Refresh" +#define MSG_WATCH _UxGT("信息屏") //"Info screen" +#define MSG_PREPARE _UxGT("准备") //"Prepare" +#define MSG_TUNE _UxGT("调整") //"Tune" +#define MSG_PAUSE_PRINT _UxGT("暂停打印") //"Pause print" +#define MSG_RESUME_PRINT _UxGT("恢复打印") //"Resume print" +#define MSG_STOP_PRINT _UxGT("停止打印") //"Stop print" +#define MSG_CARD_MENU _UxGT("从存储卡上打印") //"Print from SD" +#define MSG_NO_CARD _UxGT("无存储卡") //"No SD card" +#define MSG_DWELL _UxGT("休眠中 ...") //"Sleep..." +#define MSG_USERWAIT _UxGT("等待用户 ...") //"Wait for user..." +#define MSG_RESUMING _UxGT("恢复打印中") //"Resuming print" +#define MSG_PRINT_ABORTED _UxGT("打印已取消") //"Print aborted" +#define MSG_NO_MOVE _UxGT("无移动") //"No move." +#define MSG_KILLED _UxGT("已杀掉") //"KILLED. " +#define MSG_STOPPED _UxGT("已停止") //"STOPPED. " +#define MSG_CONTROL_RETRACT _UxGT("回抽长度mm") //"Retract mm" retract_length, retract length (positive mm) +#define MSG_CONTROL_RETRACT_SWAP _UxGT("换手回抽长度mm") //"Swap Re.mm" swap_retract_length, swap retract length (positive mm), for extruder change +#define MSG_CONTROL_RETRACTF _UxGT("回抽速率mm/s") //"Retract V" retract_feedrate_mm_s, feedrate for retracting (mm/s) +#define MSG_CONTROL_RETRACT_ZLIFT _UxGT("Hop mm") //"Hop mm" retract_zlift, retract Z-lift +#define MSG_CONTROL_RETRACT_RECOVER _UxGT("回抽恢复长度mm") //"UnRet +mm" retract_recover_length, additional recover length (mm, added to retract length when recovering) +#define MSG_CONTROL_RETRACT_RECOVER_SWAP _UxGT("换手回抽恢复长度mm") //"S UnRet+mm" swap_retract_recover_length, additional swap recover length (mm, added to retract length when recovering from extruder change) +#define MSG_CONTROL_RETRACT_RECOVERF _UxGT("回抽恢复后进料速率mm/s") //"UnRet V" retract_recover_feedrate_mm_s, feedrate for recovering from retraction (mm/s) +#define MSG_AUTORETRACT _UxGT("自动抽回") //"AutoRetr." autoretract_enabled, +#define MSG_FILAMENTCHANGE _UxGT("更换丝料") //"Change filament" +#define MSG_INIT_SDCARD _UxGT("初始化存储卡") //"Init. SD card" +#define MSG_CNG_SDCARD _UxGT("更换存储卡") //"Change SD card" +#define MSG_ZPROBE_OUT _UxGT("Z探针在热床之外") //"Z probe out. bed" Z probe is not within the physical limits +#define MSG_HOME _UxGT("归位") //"Home" // Used as MSG_HOME " " MSG_X MSG_Y MSG_Z " " MSG_FIRST +#define MSG_FIRST _UxGT("先") //"first" +#define MSG_ZPROBE_ZOFFSET _UxGT("Z偏移") //"Z Offset" +#define MSG_BABYSTEP_X _UxGT("微量调整X轴") //"Babystep X" lcd_babystep_x, Babystepping enables the user to control the axis in tiny amounts +#define MSG_BABYSTEP_Y _UxGT("微量调整Y轴") //"Babystep Y" +#define MSG_BABYSTEP_Z _UxGT("微量调整Z轴") //"Babystep Z" +#define MSG_ENDSTOP_ABORT _UxGT("挡块终止") //"Endstop abort" +#define MSG_HEATING_FAILED_LCD _UxGT("加热失败") //"Heating failed" +#define MSG_ERR_REDUNDANT_TEMP _UxGT("错误:REDUNDANT TEMP") //"Err: REDUNDANT TEMP" +#define MSG_THERMAL_RUNAWAY _UxGT("温控失控") //"THERMAL RUNAWAY" +#define MSG_ERR_MAXTEMP _UxGT("错误:最高温度") //"Err: MAXTEMP" +#define MSG_ERR_MINTEMP _UxGT("错误:最低温度") //"Err: MINTEMP" +#define MSG_ERR_MAXTEMP_BED _UxGT("错误:最高热床温度") //"Err: MAXTEMP BED" +#define MSG_ERR_MINTEMP_BED _UxGT("错误:最低热床温度") //"Err: MINTEMP BED" +#define MSG_HALTED _UxGT("打印停机") //"PRINTER HALTED" +#define MSG_PLEASE_RESET _UxGT("请重置") //"Please reset" +#define MSG_SHORT_DAY _UxGT("天") //"d" // One character only +#define MSG_SHORT_HOUR _UxGT("时") //"h" // One character only +#define MSG_SHORT_MINUTE _UxGT("分") //"m" // One character only +#define MSG_HEATING _UxGT("加热中 ...") //"Heating..." +#define MSG_HEATING_COMPLETE _UxGT("完成加热") //"Heating done." +#define MSG_BED_HEATING _UxGT("加热热床中") //"Bed Heating." +#define MSG_BED_DONE _UxGT("完成加热热床") //"Bed done." +#define MSG_DELTA_CALIBRATE _UxGT("⊿校准") //"Delta Calibration" +#define MSG_DELTA_CALIBRATE_X _UxGT("校准X") //"Calibrate X" +#define MSG_DELTA_CALIBRATE_Y _UxGT("校准Y") //"Calibrate Y" +#define MSG_DELTA_CALIBRATE_Z _UxGT("校准Z") //"Calibrate Z" +#define MSG_DELTA_CALIBRATE_CENTER _UxGT("校准中心") //"Calibrate Center" + +#define MSG_INFO_MENU _UxGT("关于打印机") //"About Printer" +#define MSG_INFO_PRINTER_MENU _UxGT("打印机信息") //"Printer Info" +#define MSG_INFO_STATS_MENU _UxGT("打印机统计") //"Printer Stats" +#define MSG_INFO_BOARD_MENU _UxGT("主板信息") //"Board Info" +#define MSG_INFO_THERMISTOR_MENU _UxGT("温度计") //"Thermistors" +#define MSG_INFO_EXTRUDERS _UxGT("挤出机") //"Extruders" +#define MSG_INFO_BAUDRATE _UxGT("波特率") //"Baud" +#define MSG_INFO_PROTOCOL _UxGT("协议") //"Protocol" + +#if LCD_WIDTH > 19 +#define MSG_INFO_PRINT_COUNT _UxGT("打印计数") //"Print Count" +#define MSG_INFO_COMPLETED_PRINTS _UxGT("完成了") //"Completed" +#define MSG_INFO_PRINT_TIME _UxGT("总打印时间") //"Total print time" +#define MSG_INFO_PRINT_LONGEST _UxGT("最长工作时间") //"Longest job time" +#define MSG_INFO_PRINT_FILAMENT _UxGT("总计挤出") //"Extruded total" +#else +#define MSG_INFO_PRINT_COUNT _UxGT("打印数") //"Prints" +#define MSG_INFO_COMPLETED_PRINTS _UxGT("完成") //"Completed" +#define MSG_INFO_PRINT_TIME _UxGT("总共") //"Total" +#define MSG_INFO_PRINT_LONGEST _UxGT("最长") //"Longest" +#define MSG_INFO_PRINT_FILAMENT _UxGT("已挤出") //"Extruded" +#endif + +#define MSG_INFO_MIN_TEMP _UxGT("最低温度") //"Min Temp" +#define MSG_INFO_MAX_TEMP _UxGT("最高温度") //"Max Temp" +#define MSG_INFO_PSU _UxGT("电源供应") //"Power Supply" + +#define MSG_FILAMENT_CHANGE_HEADER _UxGT("PRINT PAUSED") +#define MSG_FILAMENT_CHANGE_OPTION_HEADER _UxGT("RESUME OPTIONS:") +#define MSG_FILAMENT_CHANGE_OPTION_EXTRUDE _UxGT("挤出更多") //"Extrude more" +#define MSG_FILAMENT_CHANGE_OPTION_RESUME _UxGT("恢复打印") //"Resume print" + +#if LCD_HEIGHT >= 4 +#define MSG_FILAMENT_CHANGE_INIT_1 _UxGT("等待开始") //"Wait for start" +#define MSG_FILAMENT_CHANGE_INIT_2 _UxGT("丝料") //"of the filament" +#define MSG_FILAMENT_CHANGE_INIT_3 _UxGT("变更") //"change" +#define MSG_FILAMENT_CHANGE_UNLOAD_1 _UxGT("等待") //"Wait for" +#define MSG_FILAMENT_CHANGE_UNLOAD_2 _UxGT("卸下丝料") //"filament unload" +#define MSG_FILAMENT_CHANGE_UNLOAD_3 _UxGT("") //"" +#define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("插入丝料") //"Insert filament" +#define MSG_FILAMENT_CHANGE_INSERT_2 _UxGT("并按键") //"and press button" +#define MSG_FILAMENT_CHANGE_INSERT_3 _UxGT("来继续 ...") //"to continue..." +#define MSG_FILAMENT_CHANGE_LOAD_1 _UxGT("等待") //"Wait for" +#define MSG_FILAMENT_CHANGE_LOAD_2 _UxGT("进料") //"filament load" +#define MSG_FILAMENT_CHANGE_LOAD_3 _UxGT("") //"" +#define MSG_FILAMENT_CHANGE_EXTRUDE_1 _UxGT("等待") //"Wait for" +#define MSG_FILAMENT_CHANGE_EXTRUDE_2 _UxGT("丝料挤出") //"filament extrude" +#define MSG_FILAMENT_CHANGE_EXTRUDE_3 _UxGT("") //"" +#define MSG_FILAMENT_CHANGE_RESUME_1 _UxGT("等待打印") //"Wait for print" +#define MSG_FILAMENT_CHANGE_RESUME_2 _UxGT("恢复") //"to resume" +#define MSG_FILAMENT_CHANGE_RESUME_3 _UxGT("") //"" + +#else // LCD_HEIGHT < 4 +#define MSG_FILAMENT_CHANGE_INIT_1 _UxGT("请等待 ...") //"Please wait..." +#define MSG_FILAMENT_CHANGE_UNLOAD_1 _UxGT("退出中 ...") //"Ejecting..." +#define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("插入并单击") //"Insert and Click" +#define MSG_FILAMENT_CHANGE_LOAD_1 _UxGT("装载中 ...") //"Loading..." +#define MSG_FILAMENT_CHANGE_EXTRUDE_1 _UxGT("挤出中 ...") //"Extruding..." +#define MSG_FILAMENT_CHANGE_RESUME_1 _UxGT("恢复中 ...") //"Resuming..." +#endif // LCD_HEIGHT < 4 + +#endif // LANGUAGE_ZH_CN_H diff --git a/trunk/Arduino/Marlin_1.1.6/language_zh_TW.h b/trunk/Arduino/Marlin_1.1.6/language_zh_TW.h new file mode 100644 index 00000000..777c0931 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/language_zh_TW.h @@ -0,0 +1,238 @@ +/** + * 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 . + * + */ + +/** + * Traditional Chinese + * + * LCD Menu Messages + * See also http://marlinfw.org/docs/development/lcd_language.html + * + */ +#ifndef LANGUAGE_ZH_TW_H +#define LANGUAGE_ZH_TW_H + +#define WELCOME_MSG MACHINE_NAME _UxGT("已就緒.") //" ready." +#define MSG_SD_INSERTED _UxGT("記憶卡已插入") //"Card inserted" +#define MSG_SD_REMOVED _UxGT("記憶卡被拔出") //"Card removed" +#define MSG_LCD_ENDSTOPS _UxGT("擋塊") //"Endstops" // Max length 8 characters +#define MSG_MAIN _UxGT("主選單") //"Main" +#define MSG_AUTOSTART _UxGT("自動開始") //"Autostart" +#define MSG_DISABLE_STEPPERS _UxGT("關閉步進驅動") //"Disable steppers" +#define MSG_AUTO_HOME _UxGT("自動回原點") //"Auto home" +#define MSG_AUTO_HOME_X _UxGT("回X原位") //"Home X" +#define MSG_AUTO_HOME_Y _UxGT("回Y原位") //"Home Y" +#define MSG_AUTO_HOME_Z _UxGT("回Z原位") //"Home Z" +#define MSG_LEVEL_BED_HOMING _UxGT("平台調平XYZ歸原位") //"Homing XYZ" +#define MSG_LEVEL_BED_WAITING _UxGT("單擊開始熱床調平") //"Click to Begin" +#define MSG_LEVEL_BED_NEXT_POINT _UxGT("下個熱床調平點") //"Next Point" +#define MSG_LEVEL_BED_DONE _UxGT("完成熱床調平") //"Leveling Done!" +#define MSG_SET_HOME_OFFSETS _UxGT("設置原點偏移") //"Set home offsets" +#define MSG_HOME_OFFSETS_APPLIED _UxGT("偏移已啟用") //"Offsets applied" +#define MSG_SET_ORIGIN _UxGT("設置原點") //"Set origin" +#define MSG_PREHEAT_1 _UxGT("預熱PLA") //"Preheat PLA" +#define MSG_PREHEAT_1_N MSG_PREHEAT_1 _UxGT(" ") //MSG_PREHEAT_1 " " +#define MSG_PREHEAT_1_ALL MSG_PREHEAT_1 _UxGT(" 全部") //MSG_PREHEAT_1 " All" +#define MSG_PREHEAT_1_BEDONLY MSG_PREHEAT_1 _UxGT(" 熱床") //MSG_PREHEAT_1 " Bed" +#define MSG_PREHEAT_1_SETTINGS MSG_PREHEAT_1 _UxGT(" 設置") //MSG_PREHEAT_1 " conf" +#define MSG_PREHEAT_2 _UxGT("預熱ABS") //"Preheat ABS" +#define MSG_PREHEAT_2_N MSG_PREHEAT_2 _UxGT(" ") //MSG_PREHEAT_2 " " +#define MSG_PREHEAT_2_ALL MSG_PREHEAT_2 _UxGT(" 全部") //MSG_PREHEAT_2 " All" +#define MSG_PREHEAT_2_BEDONLY MSG_PREHEAT_2 _UxGT(" 熱床") //MSG_PREHEAT_2 " Bed" +#define MSG_PREHEAT_2_SETTINGS MSG_PREHEAT_2 _UxGT(" 設置") //MSG_PREHEAT_2 " conf" +#define MSG_COOLDOWN _UxGT("降溫") //"Cooldown" +#define MSG_SWITCH_PS_ON _UxGT("電源打開") //"Switch power on" +#define MSG_SWITCH_PS_OFF _UxGT("電源關閉") //"Switch power off" +#define MSG_EXTRUDE _UxGT("擠出") //"Extrude" +#define MSG_RETRACT _UxGT("回抽") //"Retract" +#define MSG_MOVE_AXIS _UxGT("移動軸") //"Move axis" +#define MSG_BED_LEVELING _UxGT("調平熱床") //"Bed leveling" +#define MSG_LEVEL_BED _UxGT("調平熱床") //"Level bed" +#define MSG_MOVE_X _UxGT("移動X") //"Move X" +#define MSG_MOVE_Y _UxGT("移動Y") //"Move Y" +#define MSG_MOVE_Z _UxGT("移動Z") //"Move Z" +#define MSG_MOVE_E _UxGT("擠出機") //"Extruder" +#define MSG_MOVE_01MM _UxGT("移動 0.1 mm") //"Move 0.1mm" +#define MSG_MOVE_1MM _UxGT("移動 1 mm") //"Move 1mm" +#define MSG_MOVE_10MM _UxGT("移動 10 mm") //"Move 10mm" +#define MSG_SPEED _UxGT("速率") //"Speed" +#define MSG_BED_Z _UxGT("熱床Z") //"Bed Z" +#define MSG_NOZZLE _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" 噴嘴") //"Nozzle" 噴嘴 +#define MSG_BED _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" 熱床") //"Bed" +#define MSG_FAN_SPEED _UxGT("風扇速率") //"Fan speed" +#define MSG_FLOW _UxGT("擠出速率") //"Flow" +#define MSG_CONTROL _UxGT("控制") //"Control" +#define MSG_MIN _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" 最小") //" " LCD_STR_THERMOMETER " Min" +#define MSG_MAX _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" 最大") //" " LCD_STR_THERMOMETER " Max" +#define MSG_FACTOR _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" 系數") //" " LCD_STR_THERMOMETER " Fact" +#define MSG_AUTOTEMP _UxGT("自動控溫") //"Autotemp" +#define MSG_ON _UxGT("開 ") //"On " +#define MSG_OFF _UxGT("關 ") //"Off" +#define MSG_PID_P _UxGT("PID-P") //"PID-P" +#define MSG_PID_I _UxGT("PID-I") //"PID-I" +#define MSG_PID_D _UxGT("PID-D") //"PID-D" +#define MSG_PID_C _UxGT("PID-C") //"PID-C" +#define MSG_SELECT _UxGT("選擇") //"Select" +#define MSG_ACC _UxGT("加速度") //"Accel" acceleration +#define MSG_JERK _UxGT("抖動速率") //"Jerk" +#define MSG_VX_JERK _UxGT("X軸抖動速率") //"Vx-jerk" +#define MSG_VY_JERK _UxGT("Y軸抖動速率") //"Vy-jerk" +#define MSG_VZ_JERK _UxGT("Z軸抖動速率") //"Vz-jerk" +#define MSG_VE_JERK _UxGT("擠出機抖動速率") //"Ve-jerk" +#define MSG_VMAX _UxGT("最大進料速率") //"Vmax " max_feedrate_mm_s +#define MSG_VMIN _UxGT("最小進料速率") //"Vmin" min_feedrate_mm_s +#define MSG_VTRAV_MIN _UxGT("最小移動速率") //"VTrav min" min_travel_feedrate_mm_s, (target) speed of the move +#define MSG_AMAX _UxGT("最大列印加速度") //"Amax " max_acceleration_mm_per_s2, acceleration in units/s^2 for print moves +#define MSG_A_RETRACT _UxGT("收進加速度") //"A-retract" retract_acceleration, E acceleration in mm/s^2 for retracts +#define MSG_A_TRAVEL _UxGT("非列印移動加速度") //"A-travel" travel_acceleration, X, Y, Z acceleration in mm/s^2 for travel (non printing) moves +#define MSG_STEPS_PER_MM _UxGT("軸步數/mm") //"Steps/mm" axis_steps_per_mm, axis steps-per-unit G92 +#define MSG_XSTEPS _UxGT("X軸步數/mm") //"Xsteps/mm" axis_steps_per_mm, axis steps-per-unit G92 +#define MSG_YSTEPS _UxGT("Y軸步數/mm") //"Ysteps/mm" +#define MSG_ZSTEPS _UxGT("Z軸步數/mm") //"Zsteps/mm" +#define MSG_ESTEPS _UxGT("擠出機步數/mm") //"Esteps/mm" +#define MSG_TEMPERATURE _UxGT("溫度") //"Temperature" +#define MSG_MOTION _UxGT("運動") //"Motion" +#define MSG_FILAMENT _UxGT("絲料測容") //"Filament" lcd_control_volumetric_menu +#define MSG_VOLUMETRIC_ENABLED _UxGT("測容積mm³") //"E in mm3" volumetric_enabled +#define MSG_FILAMENT_DIAM _UxGT("絲料直徑") //"Fil. Dia." +#define MSG_CONTRAST _UxGT("LCD對比度") //"LCD contrast" +#define MSG_STORE_EEPROM _UxGT("保存設置") //"Store memory" +#define MSG_LOAD_EEPROM _UxGT("裝載設置") //"Load memory" +#define MSG_RESTORE_FAILSAFE _UxGT("恢複安全值") //"Restore failsafe" +#define MSG_REFRESH _UxGT("刷新") //"Refresh" +#define MSG_WATCH _UxGT("資訊界面") //"Info screen" +#define MSG_PREPARE _UxGT("準備") //"Prepare" +#define MSG_TUNE _UxGT("調整") //"Tune" +#define MSG_PAUSE_PRINT _UxGT("暫停列印") //"Pause print" +#define MSG_RESUME_PRINT _UxGT("恢複列印") //"Resume print" +#define MSG_STOP_PRINT _UxGT("停止列印") //"Stop print" +#define MSG_CARD_MENU _UxGT("從記憶卡上列印") //"Print from SD" +#define MSG_NO_CARD _UxGT("無記憶卡") //"No SD card" +#define MSG_DWELL _UxGT("休眠 ...") //"Sleep..." +#define MSG_USERWAIT _UxGT("等待用戶 ...") //"Wait for user..." +#define MSG_RESUMING _UxGT("恢複列印中") //"Resuming print" +#define MSG_PRINT_ABORTED _UxGT("列印已取消") //"Print aborted" +#define MSG_NO_MOVE _UxGT("無移動") //"No move." +#define MSG_KILLED _UxGT("已殺掉") //"KILLED. " +#define MSG_STOPPED _UxGT("已停止") //"STOPPED. " +#define MSG_CONTROL_RETRACT _UxGT("回抽長度mm") //"Retract mm" retract_length, retract length (positive mm) +#define MSG_CONTROL_RETRACT_SWAP _UxGT("換手回抽長度mm") //"Swap Re.mm" swap_retract_length, swap retract length (positive mm), for extruder change +#define MSG_CONTROL_RETRACTF _UxGT("回抽速率mm/s") //"Retract V" retract_feedrate_mm_s, feedrate for retracting (mm/s) +#define MSG_CONTROL_RETRACT_ZLIFT _UxGT("Hop mm") //"Hop mm" retract_zlift, retract Z-lift +#define MSG_CONTROL_RETRACT_RECOVER _UxGT("回抽恢複長度mm") //"UnRet +mm" retract_recover_length, additional recover length (mm, added to retract length when recovering) +#define MSG_CONTROL_RETRACT_RECOVER_SWAP _UxGT("換手回抽恢複長度mm") //"S UnRet+mm" swap_retract_recover_length, additional swap recover length (mm, added to retract length when recovering from extruder change) +#define MSG_CONTROL_RETRACT_RECOVERF _UxGT("回抽恢複後進料速率mm/s") //"UnRet V" retract_recover_feedrate_mm_s, feedrate for recovering from retraction (mm/s) +#define MSG_AUTORETRACT _UxGT("自動抽回") //"AutoRetr." autoretract_enabled, +#define MSG_FILAMENTCHANGE _UxGT("更換絲料") //"Change filament" +#define MSG_INIT_SDCARD _UxGT("初始化記憶卡") //"Init. SD card" +#define MSG_CNG_SDCARD _UxGT("更換記憶卡") //"Change SD card" +#define MSG_ZPROBE_OUT _UxGT("Z探針在熱床之外") //"Z probe out. bed" Z probe is not within the physical limits +#define MSG_HOME _UxGT("歸位") //"Home" // Used as MSG_HOME " " MSG_X MSG_Y MSG_Z " " MSG_FIRST +#define MSG_FIRST _UxGT("先") //"first" +#define MSG_ZPROBE_ZOFFSET _UxGT("Z偏移") //"Z Offset" +#define MSG_BABYSTEP_X _UxGT("微量調整X軸") //"Babystep X" lcd_babystep_x, Babystepping enables the user to control the axis in tiny amounts +#define MSG_BABYSTEP_Y _UxGT("微量調整Y軸") //"Babystep Y" +#define MSG_BABYSTEP_Z _UxGT("微量調整Z軸") //"Babystep Z" +#define MSG_ENDSTOP_ABORT _UxGT("擋塊終止") //"Endstop abort" +#define MSG_HEATING_FAILED_LCD _UxGT("加熱失敗") //"Heating failed" +#define MSG_ERR_REDUNDANT_TEMP _UxGT("錯誤:REDUNDANT TEMP") //"Err: REDUNDANT TEMP" +#define MSG_THERMAL_RUNAWAY _UxGT("溫控失控") //"THERMAL RUNAWAY" +#define MSG_ERR_MAXTEMP _UxGT("錯誤:最高溫度") //"Err: MAXTEMP" +#define MSG_ERR_MINTEMP _UxGT("錯誤:最低溫度") //"Err: MINTEMP" +#define MSG_ERR_MAXTEMP_BED _UxGT("錯誤:最高熱床溫度") //"Err: MAXTEMP BED" +#define MSG_ERR_MINTEMP_BED _UxGT("錯誤:最低熱床溫度") //"Err: MINTEMP BED" +#define MSG_HALTED _UxGT("印表機停機") //"PRINTER HALTED" +#define MSG_PLEASE_RESET _UxGT("請重置") //"Please reset" +#define MSG_SHORT_DAY _UxGT("天") //"d" // One character only +#define MSG_SHORT_HOUR _UxGT("時") //"h" // One character only +#define MSG_SHORT_MINUTE _UxGT("分") //"m" // One character only +#define MSG_HEATING _UxGT("加熱中 ...") //"Heating..." +#define MSG_HEATING_COMPLETE _UxGT("完成加熱") //"Heating done." +#define MSG_BED_HEATING _UxGT("加熱熱床中") //"Bed Heating." +#define MSG_BED_DONE _UxGT("完成加熱熱床") //"Bed done." +#define MSG_DELTA_CALIBRATE _UxGT("⊿校準") //"Delta Calibration" +#define MSG_DELTA_CALIBRATE_X _UxGT("校準X") //"Calibrate X" +#define MSG_DELTA_CALIBRATE_Y _UxGT("校準Y") //"Calibrate Y" +#define MSG_DELTA_CALIBRATE_Z _UxGT("校準Z") //"Calibrate Z" +#define MSG_DELTA_CALIBRATE_CENTER _UxGT("校準中心") //"Calibrate Center" + +#define MSG_INFO_MENU _UxGT("關於印表機") //"About Printer" +#define MSG_INFO_PRINTER_MENU _UxGT("印表機信息") //"Printer Info" +#define MSG_INFO_STATS_MENU _UxGT("印表機統計") //"Printer Stats" +#define MSG_INFO_BOARD_MENU _UxGT("主板信息") //"Board Info" +#define MSG_INFO_THERMISTOR_MENU _UxGT("溫度計") //"Thermistors" +#define MSG_INFO_EXTRUDERS _UxGT("擠出機") //"Extruders" +#define MSG_INFO_BAUDRATE _UxGT("波特率") //"Baud" +#define MSG_INFO_PROTOCOL _UxGT("協議") //"Protocol" + +#if LCD_WIDTH > 19 +#define MSG_INFO_PRINT_COUNT _UxGT("列印計數") //"Print Count" +#define MSG_INFO_COMPLETED_PRINTS _UxGT("完成了") //"Completed" +#define MSG_INFO_PRINT_TIME _UxGT("總列印時間") //"Total print time" +#define MSG_INFO_PRINT_LONGEST _UxGT("最長工作時間") //"Longest job time" +#define MSG_INFO_PRINT_FILAMENT _UxGT("總計擠出") //"Extruded total" +#else +#define MSG_INFO_PRINT_COUNT _UxGT("列印數") //"Prints" +#define MSG_INFO_COMPLETED_PRINTS _UxGT("完成") //"Completed" +#define MSG_INFO_PRINT_TIME _UxGT("總共") //"Total" +#define MSG_INFO_PRINT_LONGEST _UxGT("最長") //"Longest" +#define MSG_INFO_PRINT_FILAMENT _UxGT("已擠出") //"Extruded" +#endif + +#define MSG_INFO_MIN_TEMP _UxGT("最低溫度") //"Min Temp" +#define MSG_INFO_MAX_TEMP _UxGT("最高溫度") //"Max Temp" +#define MSG_INFO_PSU _UxGT("電源供應") //"Power Supply" + +#define MSG_FILAMENT_CHANGE_HEADER _UxGT("PRINT PAUSED") +#define MSG_FILAMENT_CHANGE_OPTION_HEADER _UxGT("RESUME OPTIONS:") +#define MSG_FILAMENT_CHANGE_OPTION_EXTRUDE _UxGT("擠出更多") //"Extrude more" +#define MSG_FILAMENT_CHANGE_OPTION_RESUME _UxGT("恢複列印") //"Resume print" + +#if LCD_HEIGHT >= 4 +#define MSG_FILAMENT_CHANGE_INIT_1 _UxGT("等待開始") //"Wait for start" +#define MSG_FILAMENT_CHANGE_INIT_2 _UxGT("絲料") //"of the filament" +#define MSG_FILAMENT_CHANGE_INIT_3 _UxGT("變更") //"change" +#define MSG_FILAMENT_CHANGE_UNLOAD_1 _UxGT("等待") //"Wait for" +#define MSG_FILAMENT_CHANGE_UNLOAD_2 _UxGT("卸下絲料") //"filament unload" +#define MSG_FILAMENT_CHANGE_UNLOAD_3 _UxGT("") //"" +#define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("插入絲料") //"Insert filament" +#define MSG_FILAMENT_CHANGE_INSERT_2 _UxGT("並按鍵") //"and press button" +#define MSG_FILAMENT_CHANGE_INSERT_3 _UxGT("來繼續 ...") //"to continue..." +#define MSG_FILAMENT_CHANGE_LOAD_1 _UxGT("等待") //"Wait for" +#define MSG_FILAMENT_CHANGE_LOAD_2 _UxGT("進料") //"filament load" +#define MSG_FILAMENT_CHANGE_LOAD_3 _UxGT("") //"" +#define MSG_FILAMENT_CHANGE_EXTRUDE_1 _UxGT("等待") //"Wait for" +#define MSG_FILAMENT_CHANGE_EXTRUDE_2 _UxGT("絲料擠出") //"filament extrude" +#define MSG_FILAMENT_CHANGE_EXTRUDE_3 _UxGT("") //"" +#define MSG_FILAMENT_CHANGE_RESUME_1 _UxGT("等待列印") //"Wait for print" +#define MSG_FILAMENT_CHANGE_RESUME_2 _UxGT("恢複") //"to resume" +#define MSG_FILAMENT_CHANGE_RESUME_3 _UxGT("") //"" + +#else // LCD_HEIGHT < 4 +#define MSG_FILAMENT_CHANGE_INIT_1 _UxGT("請等待 ...") //"Please wait..." +#define MSG_FILAMENT_CHANGE_UNLOAD_1 _UxGT("退出中 ...") //"Ejecting..." +#define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("插入並單擊") //"Insert and Click" +#define MSG_FILAMENT_CHANGE_LOAD_1 _UxGT("裝載中 ...") //"Loading..." +#define MSG_FILAMENT_CHANGE_EXTRUDE_1 _UxGT("擠出中 ...") //"Extruding..." +#define MSG_FILAMENT_CHANGE_RESUME_1 _UxGT("恢複中 ...") //"Resuming..." +#endif // LCD_HEIGHT < 4 + +#endif // LANGUAGE_ZH_TW_H diff --git a/trunk/Arduino/Marlin_1.1.6/least_squares_fit.cpp b/trunk/Arduino/Marlin_1.1.6/least_squares_fit.cpp new file mode 100644 index 00000000..66821ce5 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/least_squares_fit.cpp @@ -0,0 +1,71 @@ +/** + * 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 . + * + */ + +/** + * Least Squares Best Fit by Roxy and Ed Williams + * + * This algorithm is high speed and has a very small code footprint. + * Its results are identical to both the Iterative Least-Squares published + * earlier by Roxy and the QR_SOLVE solution. If used in place of QR_SOLVE + * 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 "MarlinConfig.h" + +#if ENABLED(AUTO_BED_LEVELING_UBL) || ENABLED(AUTO_BED_LEVELING_LINEAR) + +#include "macros.h" +#include + +#include "least_squares_fit.h" + +int finish_incremental_LSF(struct linear_fit_data *lsf) { + + const float N = lsf->N; + + if (N == 0.0) + return 1; + + lsf->xbar /= N; + lsf->ybar /= N; + lsf->zbar /= N; + lsf->x2bar = lsf->x2bar / N - sq(lsf->xbar); + lsf->y2bar = lsf->y2bar / N - sq(lsf->ybar); + lsf->z2bar = lsf->z2bar / N - sq(lsf->zbar); + lsf->xybar = lsf->xybar / N - lsf->xbar * lsf->ybar; + lsf->yzbar = lsf->yzbar / N - lsf->ybar * lsf->zbar; + lsf->xzbar = lsf->xzbar / N - lsf->xbar * lsf->zbar; + const float DD = lsf->x2bar * lsf->y2bar - sq(lsf->xybar); + + if (FABS(DD) <= 1e-10 * (lsf->max_absx + lsf->max_absy)) + return 1; + + lsf->A = (lsf->yzbar * lsf->xybar - lsf->xzbar * lsf->y2bar) / DD; + lsf->B = (lsf->xzbar * lsf->xybar - lsf->yzbar * lsf->x2bar) / DD; + lsf->D = -(lsf->zbar + lsf->A * lsf->xbar + lsf->B * lsf->ybar); + return 0; +} + +#endif // AUTO_BED_LEVELING_UBL || ENABLED(AUTO_BED_LEVELING_LINEAR) diff --git a/trunk/Arduino/Marlin_1.1.6/least_squares_fit.h b/trunk/Arduino/Marlin_1.1.6/least_squares_fit.h new file mode 100644 index 00000000..9ed923ab --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/least_squares_fit.h @@ -0,0 +1,90 @@ +/** + * 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 . + * + */ + +/** + * Incremental Least Squares Best Fit By Roxy and Ed Williams + * + * This algorithm is high speed and has a very small code footprint. + * Its results are identical to both the Iterative Least-Squares published + * earlier by Roxy and the QR_SOLVE solution. If used in place of QR_SOLVE + * 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 "MarlinConfig.h" + +#if ENABLED(AUTO_BED_LEVELING_UBL) || ENABLED(AUTO_BED_LEVELING_LINEAR) + +#include "Marlin.h" +#include "macros.h" +#include + +struct linear_fit_data { + float xbar, ybar, zbar, + x2bar, y2bar, z2bar, + xybar, xzbar, yzbar, + max_absx, max_absy, + A, B, D, N; +}; + +void inline incremental_LSF_reset(struct linear_fit_data *lsf) { + memset(lsf, 0, sizeof(linear_fit_data)); +} + +void inline incremental_WLSF(struct linear_fit_data *lsf, const float &x, const float &y, const float &z, const float &w) { + // weight each accumulator by factor w, including the "number" of samples + // (analagous to calling inc_LSF twice with same values to weight it by 2X) + lsf->xbar += w * x; + lsf->ybar += w * y; + lsf->zbar += w * z; + lsf->x2bar += w * x * x; // don't use sq(x) -- let compiler re-use w*x four times + lsf->y2bar += w * y * y; + lsf->z2bar += w * z * z; + lsf->xybar += w * x * y; + lsf->xzbar += w * x * z; + lsf->yzbar += w * y * z; + lsf->N += w; + lsf->max_absx = max(FABS(w * x), lsf->max_absx); + lsf->max_absy = max(FABS(w * y), lsf->max_absy); +} + +void inline incremental_LSF(struct linear_fit_data *lsf, const float &x, const float &y, const float &z) { + lsf->xbar += x; + lsf->ybar += y; + lsf->zbar += z; + lsf->x2bar += sq(x); + lsf->y2bar += sq(y); + lsf->z2bar += sq(z); + lsf->xybar += x * y; + lsf->xzbar += x * z; + lsf->yzbar += y * z; + lsf->max_absx = max(FABS(x), lsf->max_absx); + lsf->max_absy = max(FABS(y), lsf->max_absy); + lsf->N += 1.0; +} + +int finish_incremental_LSF(struct linear_fit_data *); + +#endif + diff --git a/trunk/Arduino/Marlin_1.1.6/macros.h b/trunk/Arduino/Marlin_1.1.6/macros.h new file mode 100644 index 00000000..05433597 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/macros.h @@ -0,0 +1,211 @@ +/** + * 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 . + * + */ + +#ifndef MACROS_H +#define MACROS_H + +#define NUM_AXIS 4 +#define XYZE 4 +#define ABC 3 +#define XYZ 3 + +#define FORCE_INLINE __attribute__((always_inline)) inline +#define _UNUSED __attribute__((unused)) +#define _O0 __attribute__((optimize("O0"))) +#define _Os __attribute__((optimize("Os"))) +#define _O1 __attribute__((optimize("O1"))) +#define _O2 __attribute__((optimize("O2"))) +#define _O3 __attribute__((optimize("O3"))) + +// Bracket code that shouldn't be interrupted +#ifndef CRITICAL_SECTION_START + #define CRITICAL_SECTION_START unsigned char _sreg = SREG; cli(); + #define CRITICAL_SECTION_END SREG = _sreg; +#endif + +// Clock speed factors +#define CYCLES_PER_MICROSECOND (F_CPU / 1000000L) // 16 or 20 +#define INT0_PRESCALER 8 + +// Highly granular delays for step pulses, etc. +#define DELAY_0_NOP NOOP +#define DELAY_1_NOP __asm__("nop\n\t") +#define DELAY_2_NOP DELAY_1_NOP; DELAY_1_NOP +#define DELAY_3_NOP DELAY_1_NOP; DELAY_2_NOP +#define DELAY_4_NOP DELAY_1_NOP; DELAY_3_NOP +#define DELAY_5_NOP DELAY_1_NOP; DELAY_4_NOP + +#define DELAY_NOPS(X) \ + switch (X) { \ + case 20: DELAY_1_NOP; case 19: DELAY_1_NOP; \ + case 18: DELAY_1_NOP; case 17: DELAY_1_NOP; \ + case 16: DELAY_1_NOP; case 15: DELAY_1_NOP; \ + case 14: DELAY_1_NOP; case 13: DELAY_1_NOP; \ + case 12: DELAY_1_NOP; case 11: DELAY_1_NOP; \ + case 10: DELAY_1_NOP; case 9: DELAY_1_NOP; \ + case 8: DELAY_1_NOP; case 7: DELAY_1_NOP; \ + case 6: DELAY_1_NOP; case 5: DELAY_1_NOP; \ + case 4: DELAY_1_NOP; case 3: DELAY_1_NOP; \ + case 2: DELAY_1_NOP; case 1: DELAY_1_NOP; \ + } + +#define DELAY_10_NOP DELAY_5_NOP; DELAY_5_NOP +#define DELAY_20_NOP DELAY_10_NOP; DELAY_10_NOP + +#if CYCLES_PER_MICROSECOND == 16 + #define DELAY_1US DELAY_10_NOP; DELAY_5_NOP; DELAY_1_NOP +#else + #define DELAY_1US DELAY_20_NOP +#endif +#define DELAY_2US DELAY_1US; DELAY_1US +#define DELAY_3US DELAY_1US; DELAY_2US +#define DELAY_4US DELAY_1US; DELAY_3US +#define DELAY_5US DELAY_1US; DELAY_4US +#define DELAY_6US DELAY_1US; DELAY_5US +#define DELAY_7US DELAY_1US; DELAY_6US +#define DELAY_8US DELAY_1US; DELAY_7US +#define DELAY_9US DELAY_1US; DELAY_8US +#define DELAY_10US DELAY_1US; DELAY_9US + +// Remove compiler warning on an unused variable +#define UNUSED(x) (void) (x) + +// Macros to make a string from a macro +#define STRINGIFY_(M) #M +#define STRINGIFY(M) STRINGIFY_(M) + +// Macros for bit masks +#define TEST(n,b) (((n)&_BV(b))!=0) +#define SBI(n,b) (n |= _BV(b)) +#define CBI(n,b) (n &= ~_BV(b)) +#define SET_BIT(n,b,value) (n) ^= ((-value)^(n)) & (_BV(b)) + +// Macro to check that a number if a power if 2 +#define IS_POWER_OF_2(x) ((x) && !((x) & ((x) - 1))) + +// Macros for maths shortcuts +#ifndef M_PI + #define M_PI 3.14159265358979323846 +#endif +#define RADIANS(d) ((d)*M_PI/180.0) +#define DEGREES(r) ((r)*180.0/M_PI) +#define HYPOT2(x,y) (sq(x)+sq(y)) + +#define SIGN(a) ((a>0)-(a<0)) + +// Macros to contrain values +#define NOLESS(v,n) do{ if (v < n) v = n; }while(0) +#define NOMORE(v,n) do{ if (v > n) v = n; }while(0) + +// Macros to support option testing +#define _CAT(a, ...) a ## __VA_ARGS__ +#define SWITCH_ENABLED_false 0 +#define SWITCH_ENABLED_true 1 +#define SWITCH_ENABLED_0 0 +#define SWITCH_ENABLED_1 1 +#define SWITCH_ENABLED_ 1 +#define ENABLED(b) _CAT(SWITCH_ENABLED_, b) +#define DISABLED(b) (!_CAT(SWITCH_ENABLED_, b)) + +#define WITHIN(V,L,H) ((V) >= (L) && (V) <= (H)) +#define NUMERIC(a) WITHIN(a, '0', '9') +#define DECIMAL(a) (NUMERIC(a) || a == '.') +#define NUMERIC_SIGNED(a) (NUMERIC(a) || (a) == '-' || (a) == '+') +#define DECIMAL_SIGNED(a) (DECIMAL(a) || (a) == '-' || (a) == '+') +#define COUNT(a) (sizeof(a)/sizeof(*a)) +#define ZERO(a) memset(a,0,sizeof(a)) +#define COPY(a,b) memcpy(a,b,min(sizeof(a),sizeof(b))) + +// Macros for initializing arrays +#define ARRAY_6(v1, v2, v3, v4, v5, v6, ...) { v1, v2, v3, v4, v5, v6 } +#define ARRAY_5(v1, v2, v3, v4, v5, ...) { v1, v2, v3, v4, v5 } +#define ARRAY_4(v1, v2, v3, v4, ...) { v1, v2, v3, v4 } +#define ARRAY_3(v1, v2, v3, ...) { v1, v2, v3 } +#define ARRAY_2(v1, v2, ...) { v1, v2 } +#define ARRAY_1(v1, ...) { v1 } + +#define _ARRAY_N(N, ...) ARRAY_ ##N(__VA_ARGS__) +#define ARRAY_N(N, ...) _ARRAY_N(N, __VA_ARGS__) + +// 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 INCREMENT_(n) INC_ ##n +#define INCREMENT(n) INCREMENT_(n) + +// Macros for subtracting +#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 DECREMENT_(n) DEC_ ##n +#define DECREMENT(n) DECREMENT_(n) + +#define PIN_EXISTS(PN) (defined(PN ##_PIN) && PN ##_PIN >= 0) + +#define PENDING(NOW,SOON) ((long)(NOW-(SOON))<0) +#define ELAPSED(NOW,SOON) (!PENDING(NOW,SOON)) + +#define NOOP do{} while(0) + +#define CEILING(x,y) (((x) + (y) - 1) / (y)) + +#define MIN3(a, b, c) min(min(a, b), c) +#define MIN4(a, b, c, d) min(MIN3(a, b, c), d) +#define MIN5(a, b, c, d, e) min(MIN4(a, b, c, d), e) +#define MAX3(a, b, c) max(max(a, b), c) +#define MAX4(a, b, c, d) max(MAX3(a, b, c), d) +#define MAX5(a, b, c, d, e) max(MAX4(a, b, c, d), e) + +#define UNEAR_ZERO(x) ((x) < 0.000001) +#define NEAR_ZERO(x) WITHIN(x, -0.000001, 0.000001) +#define NEAR(x,y) NEAR_ZERO((x)-(y)) + +#define RECIPROCAL(x) (NEAR_ZERO(x) ? 0.0 : 1.0 / (x)) +#define FIXFLOAT(f) (f + 0.00001) + +// +// Maths macros that can be overridden by HAL +// +#define ATAN2(y, x) atan2(y, x) +#define FABS(x) fabs(x) +#define POW(x, y) pow(x, y) +#define SQRT(x) sqrt(x) +#define CEIL(x) ceil(x) +#define FLOOR(x) floor(x) +#define LROUND(x) lround(x) +#define FMOD(x, y) fmod(x, y) +#define HYPOT(x,y) SQRT(HYPOT2(x,y)) + +#endif //__MACROS_H diff --git a/trunk/Arduino/Marlin_1.1.6/mesh_bed_leveling.cpp b/trunk/Arduino/Marlin_1.1.6/mesh_bed_leveling.cpp new file mode 100644 index 00000000..3da19d97 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/mesh_bed_leveling.cpp @@ -0,0 +1,50 @@ +/** + * 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 . + * + */ + +#include "mesh_bed_leveling.h" + +#if ENABLED(MESH_BED_LEVELING) + + mesh_bed_leveling mbl; + + uint8_t mesh_bed_leveling::status; + + float mesh_bed_leveling::z_offset, + mesh_bed_leveling::z_values[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y], + mesh_bed_leveling::index_to_xpos[GRID_MAX_POINTS_X], + 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) + index_to_xpos[i] = MESH_MIN_X + i * (MESH_X_DIST); + for (uint8_t i = 0; i < GRID_MAX_POINTS_Y; ++i) + index_to_ypos[i] = MESH_MIN_Y + i * (MESH_Y_DIST); + reset(); + } + + void mesh_bed_leveling::reset() { + status = MBL_STATUS_NONE; + z_offset = 0; + ZERO(z_values); + } + +#endif // MESH_BED_LEVELING diff --git a/trunk/Arduino/Marlin_1.1.6/mesh_bed_leveling.h b/trunk/Arduino/Marlin_1.1.6/mesh_bed_leveling.h new file mode 100644 index 00000000..f7b701bf --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/mesh_bed_leveling.h @@ -0,0 +1,122 @@ +/** + * 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 . + * + */ + +#include "Marlin.h" + +#if ENABLED(MESH_BED_LEVELING) + + enum MeshLevelingState { + MeshReport, + MeshStart, + MeshNext, + MeshSet, + MeshSetZOffset, + MeshReset + }; + + enum MBLStatus { + MBL_STATUS_NONE = 0, + MBL_STATUS_HAS_MESH_BIT = 0, + MBL_STATUS_ACTIVE_BIT = 1 + }; + + #define MESH_X_DIST ((MESH_MAX_X - (MESH_MIN_X)) / (GRID_MAX_POINTS_X - 1)) + #define MESH_Y_DIST ((MESH_MAX_Y - (MESH_MIN_Y)) / (GRID_MAX_POINTS_Y - 1)) + + class mesh_bed_leveling { + public: + static uint8_t status; // Has Mesh and Is Active bits + static float z_offset, + z_values[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y], + index_to_xpos[GRID_MAX_POINTS_X], + index_to_ypos[GRID_MAX_POINTS_Y]; + + mesh_bed_leveling(); + + static void reset(); + + static void set_z(const int8_t px, const int8_t py, const float &z) { z_values[px][py] = z; } + + static bool active() { return TEST(status, MBL_STATUS_ACTIVE_BIT); } + static void set_active(const bool onOff) { onOff ? SBI(status, MBL_STATUS_ACTIVE_BIT) : CBI(status, MBL_STATUS_ACTIVE_BIT); } + static bool has_mesh() { return TEST(status, MBL_STATUS_HAS_MESH_BIT); } + static void set_has_mesh(const bool onOff) { onOff ? SBI(status, MBL_STATUS_HAS_MESH_BIT) : CBI(status, MBL_STATUS_HAS_MESH_BIT); } + + static inline void zigzag(const int8_t index, int8_t &px, int8_t &py) { + px = index % (GRID_MAX_POINTS_X); + py = index / (GRID_MAX_POINTS_X); + if (py & 1) px = (GRID_MAX_POINTS_X - 1) - px; // Zig zag + } + + static void set_zigzag_z(const int8_t index, const float &z) { + int8_t px, py; + zigzag(index, px, py); + set_z(px, py, z); + } + + static int8_t cell_index_x(const float &x) { + int8_t cx = (x - (MESH_MIN_X)) * (1.0 / (MESH_X_DIST)); + return constrain(cx, 0, (GRID_MAX_POINTS_X) - 2); + } + + static int8_t cell_index_y(const float &y) { + int8_t cy = (y - (MESH_MIN_Y)) * (1.0 / (MESH_Y_DIST)); + return constrain(cy, 0, (GRID_MAX_POINTS_Y) - 2); + } + + static int8_t probe_index_x(const float &x) { + int8_t px = (x - (MESH_MIN_X) + 0.5 * (MESH_X_DIST)) * (1.0 / (MESH_X_DIST)); + return WITHIN(px, 0, GRID_MAX_POINTS_X - 1) ? px : -1; + } + + static int8_t probe_index_y(const float &y) { + int8_t py = (y - (MESH_MIN_Y) + 0.5 * (MESH_Y_DIST)) * (1.0 / (MESH_Y_DIST)); + return WITHIN(py, 0, GRID_MAX_POINTS_Y - 1) ? py : -1; + } + + static float calc_z0(const float &a0, const float &a1, const float &z1, const float &a2, const float &z2) { + const float delta_z = (z2 - z1) / (a2 - a1), + delta_a = a0 - a1; + return z1 + delta_a * delta_z; + } + + static float get_z(const float &x0, const float &y0 + #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) + , const float &factor + #endif + ) { + const int8_t cx = cell_index_x(x0), cy = cell_index_y(y0); + const float z1 = calc_z0(x0, index_to_xpos[cx], z_values[cx][cy], index_to_xpos[cx + 1], z_values[cx + 1][cy]), + z2 = calc_z0(x0, index_to_xpos[cx], z_values[cx][cy + 1], index_to_xpos[cx + 1], z_values[cx + 1][cy + 1]), + z0 = calc_z0(y0, index_to_ypos[cy], z1, index_to_ypos[cy + 1], z2); + + return z_offset + z0 + #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) + * factor + #endif + ; + } + }; + + extern mesh_bed_leveling mbl; + +#endif // MESH_BED_LEVELING diff --git a/trunk/Arduino/Marlin_1.1.6/nozzle.cpp b/trunk/Arduino/Marlin_1.1.6/nozzle.cpp new file mode 100644 index 00000000..eec8bfa3 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/nozzle.cpp @@ -0,0 +1,238 @@ +#include "nozzle.h" + +#include "Marlin.h" +#include "point_t.h" + +/** + * @brief Stroke clean pattern + * @details Wipes the nozzle back and forth in a linear movement + * + * @param start point_t defining the starting point + * @param end point_t defining the ending point + * @param strokes number of strokes to execute + */ +void Nozzle::stroke( + _UNUSED point_t const &start, + _UNUSED point_t const &end, + _UNUSED uint8_t const &strokes +) { + #if ENABLED(NOZZLE_CLEAN_FEATURE) + + #if ENABLED(NOZZLE_CLEAN_GOBACK) + // Store the current coords + point_t const initial = { + current_position[X_AXIS], + current_position[Y_AXIS], + current_position[Z_AXIS], + current_position[E_AXIS] + }; + #endif // NOZZLE_CLEAN_GOBACK + + // Move to the starting point + do_blocking_move_to_xy(start.x, start.y); + do_blocking_move_to_z(start.z); + + // Start the stroke pattern + for (uint8_t i = 0; i < (strokes >>1); i++) { + do_blocking_move_to_xy(end.x, end.y); + do_blocking_move_to_xy(start.x, start.y); + } + + #if ENABLED(NOZZLE_CLEAN_GOBACK) + // Move the nozzle to the initial point + do_blocking_move_to(initial.x, initial.y, initial.z); + #endif // NOZZLE_CLEAN_GOBACK + + #endif // NOZZLE_CLEAN_FEATURE +} + +/** + * @brief Zig-zag clean pattern + * @details Apply a zig-zag cleanning pattern + * + * @param start point_t defining the starting point + * @param end point_t defining the ending point + * @param strokes number of strokes to execute + * @param objects number of objects to create + */ +void Nozzle::zigzag( + _UNUSED point_t const &start, + _UNUSED point_t const &end, + _UNUSED uint8_t const &strokes, + _UNUSED uint8_t const &objects +) { + #if ENABLED(NOZZLE_CLEAN_FEATURE) + const float A = nozzle_clean_horizontal ? nozzle_clean_height : nozzle_clean_length, // [twice the] Amplitude + P = (nozzle_clean_horizontal ? nozzle_clean_length : nozzle_clean_height) / (objects << 1); // Period + + // Don't allow impossible triangles + if (A <= 0.0f || P <= 0.0f ) return; + + #if ENABLED(NOZZLE_CLEAN_GOBACK) + // Store the current coords + point_t const initial = { + current_position[X_AXIS], + current_position[Y_AXIS], + current_position[Z_AXIS], + current_position[E_AXIS] + }; + #endif // NOZZLE_CLEAN_GOBACK + + for (uint8_t j = 0; j < strokes; j++) { + for (uint8_t i = 0; i < (objects << 1); i++) { + float const x = start.x + ( nozzle_clean_horizontal ? i * P : (A/P) * (P - FABS(FMOD((i*P), (2*P)) - P)) ); + float const y = start.y + (!nozzle_clean_horizontal ? i * P : (A/P) * (P - FABS(FMOD((i*P), (2*P)) - P)) ); + + do_blocking_move_to_xy(x, y); + if (i == 0) do_blocking_move_to_z(start.z); + } + + for (int i = (objects << 1); i > -1; i--) { + float const x = start.x + ( nozzle_clean_horizontal ? i * P : (A/P) * (P - FABS(FMOD((i*P), (2*P)) - P)) ); + float const y = start.y + (!nozzle_clean_horizontal ? i * P : (A/P) * (P - FABS(FMOD((i*P), (2*P)) - P)) ); + + do_blocking_move_to_xy(x, y); + } + } + + #if ENABLED(NOZZLE_CLEAN_GOBACK) + // Move the nozzle to the initial point + do_blocking_move_to_z(initial.z); + do_blocking_move_to_xy(initial.x, initial.y); + #endif // NOZZLE_CLEAN_GOBACK + + #endif // NOZZLE_CLEAN_FEATURE +} + + +/** + * @brief Circular clean pattern + * @details Apply a circular cleaning pattern + * + * @param start point_t defining the middle of circle + * @param strokes number of strokes to execute + * @param radius radius of circle + */ +void Nozzle::circle( + _UNUSED point_t const &start, + _UNUSED point_t const &middle, + _UNUSED uint8_t const &strokes, + _UNUSED float const &radius +) { + #if ENABLED(NOZZLE_CLEAN_FEATURE) + if (strokes == 0) return; + + #if ENABLED(NOZZLE_CLEAN_GOBACK) + // Store the current coords + point_t const initial = { + current_position[X_AXIS], + current_position[Y_AXIS], + current_position[Z_AXIS], + current_position[E_AXIS] + }; + #endif // NOZZLE_CLEAN_GOBACK + + if (start.z <= current_position[Z_AXIS]) { + // Order of movement is pretty darn important here + do_blocking_move_to_xy(start.x, start.y); + do_blocking_move_to_z(start.z); + } + else { + do_blocking_move_to_z(start.z); + do_blocking_move_to_xy(start.x, start.y); + } + + float x, y; + for (uint8_t s = 0; s < strokes; s++) { + for (uint8_t i = 0; i < NOZZLE_CLEAN_CIRCLE_FN; i++) { + x = middle.x + sin((M_2_PI / NOZZLE_CLEAN_CIRCLE_FN) * i) * radius; + y = middle.y + cos((M_2_PI / NOZZLE_CLEAN_CIRCLE_FN) * i) * radius; + + do_blocking_move_to_xy(x, y); + } + } + + // Let's be safe + do_blocking_move_to_xy(start.x, start.y); + + #if ENABLED(NOZZLE_CLEAN_GOBACK) + // Move the nozzle to the initial point + if (start.z <= initial.z) { + // As above order is important + do_blocking_move_to_z(initial.z); + do_blocking_move_to_xy(initial.x, initial.y); + } + else { + do_blocking_move_to_xy(initial.x, initial.y); + do_blocking_move_to_z(initial.z); + } + #endif // NOZZLE_CLEAN_GOBACK + + #endif // NOZZLE_CLEAN_FEATURE +} + +/** + * @brief Clean the nozzle + * @details Starts the selected clean procedure pattern + * + * @param pattern one of the available patterns + * @param argument depends on the cleaning pattern + */ +void Nozzle::clean( + _UNUSED uint8_t const &pattern, + _UNUSED uint8_t const &strokes, + _UNUSED float const &radius, + _UNUSED uint8_t const &objects +) { + #if ENABLED(NOZZLE_CLEAN_FEATURE) + #if ENABLED(DELTA) + if (current_position[Z_AXIS] > delta_clip_start_height) + do_blocking_move_to_z(delta_clip_start_height); + #endif + switch (pattern) { + case 1: + Nozzle::zigzag( + NOZZLE_CLEAN_START_POINT, + NOZZLE_CLEAN_END_POINT, strokes, objects); + break; + + case 2: + Nozzle::circle( + NOZZLE_CLEAN_START_POINT, + NOZZLE_CLEAN_CIRCLE_MIDDLE, strokes, radius); + break; + + default: + Nozzle::stroke( + NOZZLE_CLEAN_START_POINT, + NOZZLE_CLEAN_END_POINT, strokes); + } + #endif // NOZZLE_CLEAN_FEATURE +} + +void Nozzle::park( + _UNUSED uint8_t const &z_action +) { + #if ENABLED(NOZZLE_PARK_FEATURE) + float const z = current_position[Z_AXIS]; + point_t const park = NOZZLE_PARK_POINT; + + switch(z_action) { + case 1: // force Z-park height + do_blocking_move_to_z(park.z); + break; + + case 2: // Raise by Z-park height + do_blocking_move_to_z( + (z + park.z > Z_MAX_POS) ? Z_MAX_POS : z + park.z); + break; + + default: // Raise to Z-park height if lower + if (current_position[Z_AXIS] < park.z) + do_blocking_move_to_z(park.z); + } + + do_blocking_move_to_xy(park.x, park.y); + + #endif // NOZZLE_PARK_FEATURE +} diff --git a/trunk/Arduino/Marlin_1.1.6/nozzle.h b/trunk/Arduino/Marlin_1.1.6/nozzle.h new file mode 100644 index 00000000..2fbe98fb --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/nozzle.h @@ -0,0 +1,109 @@ +/** + * 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 . + * + */ + +#ifndef __NOZZLE_H__ +#define __NOZZLE_H__ + +#include "Marlin.h" +#include "point_t.h" + +#if ENABLED(NOZZLE_CLEAN_FEATURE) + constexpr float nozzle_clean_start_point[4] = NOZZLE_CLEAN_START_POINT, + nozzle_clean_end_point[4] = NOZZLE_CLEAN_END_POINT, + nozzle_clean_length = FABS(nozzle_clean_start_point[X_AXIS] - nozzle_clean_end_point[X_AXIS]), //abs x size of wipe pad + nozzle_clean_height = FABS(nozzle_clean_start_point[Y_AXIS] - nozzle_clean_end_point[Y_AXIS]); //abs y size of wipe pad + constexpr bool nozzle_clean_horizontal = nozzle_clean_length >= nozzle_clean_height; //whether to zig-zag horizontally or vertically +#endif // NOZZLE_CLEAN_FEATURE + +/** + * @brief Nozzle class + * + * @todo: Do not ignore the end.z value and allow XYZ movements + */ +class Nozzle { + private: + /** + * @brief Stroke clean pattern + * @details Wipes the nozzle back and forth in a linear movement + * + * @param start point_t defining the starting point + * @param end point_t defining the ending point + * @param strokes number of strokes to execute + */ + static void stroke( + _UNUSED point_t const &start, + _UNUSED point_t const &end, + _UNUSED uint8_t const &strokes + ) _Os; + + /** + * @brief Zig-zag clean pattern + * @details Apply a zig-zag cleaning pattern + * + * @param start point_t defining the starting point + * @param end point_t defining the ending point + * @param strokes number of strokes to execute + * @param objects number of objects to create + */ + static void zigzag( + _UNUSED point_t const &start, + _UNUSED point_t const &end, + _UNUSED uint8_t const &strokes, + _UNUSED uint8_t const &objects + ) _Os; + + /** + * @brief Circular clean pattern + * @details Apply a circular cleaning pattern + * + * @param start point_t defining the middle of circle + * @param strokes number of strokes to execute + * @param radius radius of circle + */ + static void circle( + _UNUSED point_t const &start, + _UNUSED point_t const &middle, + _UNUSED uint8_t const &strokes, + _UNUSED float const &radius + ) _Os; + + public: + /** + * @brief Clean the nozzle + * @details Starts the selected clean procedure pattern + * + * @param pattern one of the available patterns + * @param argument depends on the cleaning pattern + */ + static void clean( + _UNUSED uint8_t const &pattern, + _UNUSED uint8_t const &strokes, + _UNUSED float const &radius, + _UNUSED uint8_t const &objects = 0 + ) _Os; + + static void park( + _UNUSED uint8_t const &z_action + ) _Os; +}; + +#endif diff --git a/trunk/Arduino/Marlin_1.1.6/pca9632.cpp b/trunk/Arduino/Marlin_1.1.6/pca9632.cpp new file mode 100644 index 00000000..37f7bd7d --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pca9632.cpp @@ -0,0 +1,117 @@ +/** + * 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 . + * + */ + +/* + * Driver for the Philips PCA9632 LED driver. + * Written by Robert Mendon Feb 2017. + */ + +#include "MarlinConfig.h" + +#if ENABLED(PCA9632) + +#include "pca9632.h" + +#define PCA9632_MODE1_VALUE 0b00000001 //(ALLCALL) +#define PCA9632_MODE2_VALUE 0b00010101 //(DIMMING, INVERT, CHANGE ON STOP,TOTEM) +#define PCA9632_LEDOUT_VALUE 0b00101010 + + +/* Register addresses */ +#define PCA9632_MODE1 0x00 +#define PCA9632_MODE2 0x01 +#define PCA9632_PWM0 0x02 +#define PCA9632_PWM1 0x03 +#define PCA9632_PWM2 0x04 +#define PCA9632_PWM3 0x05 +#define PCA9632_GRPPWM 0x06 +#define PCA9632_GRPFREQ 0x07 +#define PCA9632_LEDOUT 0x08 +#define PCA9632_SUBADR1 0x09 +#define PCA9632_SUBADR2 0x0A +#define PCA9632_SUBADR3 0x0B +#define PCA9632_ALLCALLADDR 0x0C + +#define PCA9632_NO_AUTOINC 0x00 +#define PCA9632_AUTO_ALL 0x80 +#define PCA9632_AUTO_IND 0xA0 +#define PCA9632_AUTOGLO 0xC0 +#define PCA9632_AUTOGI 0xE0 + +// Red LED0 +// Green LED1 +// Blue LED2 +#define PCA9632_RED 0x00 +#define PCA9632_GRN 0x02 +#define PCA9632_BLU 0x04 + +#define LED_OFF 0x00 +#define LED_ON 0x01 +#define LED_PWM 0x02 + +#define PCA9632_ADDRESS 0b01100000 + +byte PCA_init = 0; + +static void PCA9632_WriteRegister(const byte addr, const byte regadd, const byte value) { + Wire.beginTransmission(addr); + Wire.write(regadd); + Wire.write(value); + Wire.endTransmission(); +} + +static void PCA9632_WriteAllRegisters(const byte addr, const byte regadd, const byte value1, const byte value2, const byte value3) { + Wire.beginTransmission(addr); + Wire.write(PCA9632_AUTO_IND | regadd); + Wire.write(value1); + Wire.write(value2); + Wire.write(value3); + Wire.endTransmission(); +} + +#if 0 + static byte PCA9632_ReadRegister(const byte addr, const byte regadd) { + Wire.beginTransmission(addr); + Wire.write(regadd); + const byte value = Wire.read(); + Wire.endTransmission(); + return value; + } +#endif + +void PCA9632_SetColor(const byte r, const byte g, const byte b) { + if (!PCA_init) { + PCA_init = 1; + Wire.begin(); + PCA9632_WriteRegister(PCA9632_ADDRESS,PCA9632_MODE1, PCA9632_MODE1_VALUE); + PCA9632_WriteRegister(PCA9632_ADDRESS,PCA9632_MODE2, PCA9632_MODE2_VALUE); + } + + const byte LEDOUT = (r ? LED_PWM << PCA9632_RED : 0) + | (g ? LED_PWM << PCA9632_GRN : 0) + | (b ? LED_PWM << PCA9632_BLU : 0); + + PCA9632_WriteAllRegisters(PCA9632_ADDRESS,PCA9632_PWM0, r, g, b); + PCA9632_WriteRegister(PCA9632_ADDRESS,PCA9632_LEDOUT, LEDOUT); +} + +#endif // PCA9632 diff --git a/trunk/Arduino/Marlin_1.1.6/pca9632.h b/trunk/Arduino/Marlin_1.1.6/pca9632.h new file mode 100644 index 00000000..b8c78f06 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pca9632.h @@ -0,0 +1,36 @@ +/** + * 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 . + * + */ + +/* + * Driver for the Philips PCA9632 LED driver. + * Written by Robert Mendon Feb 2017. + */ + +#ifndef __PCA9632_H__ +#define __PCA9632_H__ + +#include "Arduino.h" +#include "Wire.h" + +void PCA9632_SetColor(const byte r, const byte g, const byte b); + +#endif // __PCA9632_H__ diff --git a/trunk/Arduino/Marlin_1.1.6/pins.h b/trunk/Arduino/Marlin_1.1.6/pins.h new file mode 100644 index 00000000..fbf2331d --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins.h @@ -0,0 +1,652 @@ +/** + * 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 . + * + */ + +/** + * Include pins definitions + * + * Pins numbering schemes: + * + * - Digital I/O pin number if used by READ/WRITE macros. (e.g., X_STEP_DIR) + * The FastIO headers map digital pins to their ports and functions. + * + * - Analog Input number if used by analogRead or DAC. (e.g., TEMP_n_PIN) + * These numbers are the same in any pin mapping. + */ + +#ifndef __PINS_H__ +#define __PINS_H__ + +// +// RAMPS 1.3 / 1.4 - ATmega1280, ATmega2560 +// + +#if MB(RAMPS_OLD) + #include "pins_RAMPS_OLD.h" +#elif MB(RAMPS_13_EFB) + #define IS_RAMPS_EFB + #include "pins_RAMPS_13.h" +#elif MB(RAMPS_13_EEB) + #define IS_RAMPS_EEB + #include "pins_RAMPS_13.h" +#elif MB(RAMPS_13_EFF) + #define IS_RAMPS_EFF + #include "pins_RAMPS_13.h" +#elif MB(RAMPS_13_EEF) + #define IS_RAMPS_EEF + #include "pins_RAMPS_13.h" +#elif MB(RAMPS_13_SF) + #define IS_RAMPS_SF + #include "pins_RAMPS_13.h" +#elif MB(RAMPS_14_EFB) + #define IS_RAMPS_EFB + #include "pins_RAMPS.h" +#elif MB(RAMPS_14_EEB) + #define IS_RAMPS_EEB + #include "pins_RAMPS.h" +#elif MB(RAMPS_14_EFF) + #define IS_RAMPS_EFF + #include "pins_RAMPS.h" +#elif MB(RAMPS_14_EEF) + #define IS_RAMPS_EEF + #include "pins_RAMPS.h" +#elif MB(RAMPS_14_SF) + #define IS_RAMPS_SF + #include "pins_RAMPS.h" + +// +// RAMPS Derivatives - ATmega1280, ATmega2560 +// + +#elif MB(3DRAG) + #include "pins_3DRAG.h" // ATmega1280, ATmega2560 +#elif MB(K8200) + #include "pins_K8200.h" // ATmega1280, ATmega2560 (3DRAG) +#elif MB(K8400) + #include "pins_K8400.h" // ATmega1280, ATmega2560 (3DRAG) +#elif MB(BAM_DICE) + #include "pins_RAMPS.h" // ATmega1280, ATmega2560 +#elif MB(BAM_DICE_DUE) + #include "pins_BAM_DICE_DUE.h" // ATmega1280, ATmega2560 +#elif MB(MKS_BASE) + #include "pins_MKS_BASE.h" // ATmega1280, ATmega2560 +#elif MB(MKS_13) + #include "pins_MKS_13.h" // ATmega1280, ATmega2560 +#elif MB(ZRIB_V20) + #include "pins_ZRIB_V20.h" // ATmega1280, ATmega2560 (MKS_13) +#elif MB(FELIX2) + #include "pins_FELIX2.h" // ATmega1280, ATmega2560 +#elif MB(RIGIDBOARD) + #include "pins_RIGIDBOARD.h" // ATmega1280, ATmega2560 +#elif MB(RIGIDBOARD_V2) + #include "pins_RIGIDBOARD_V2.h" // ATmega1280, ATmega2560 +#elif MB(SAINSMART_2IN1) + #include "pins_SAINSMART_2IN1.h" // ATmega1280, ATmega2560 +#elif MB(ULTIMAKER) + #include "pins_ULTIMAKER.h" // ATmega1280, ATmega2560 +#elif MB(ULTIMAKER_OLD) + #include "pins_ULTIMAKER_OLD.h" // ATmega1280, ATmega2560 +#elif MB(AZTEEG_X3) + #include "pins_AZTEEG_X3.h" // ATmega2560 +#elif MB(AZTEEG_X3_PRO) + #include "pins_AZTEEG_X3_PRO.h" // ATmega2560 +#elif MB(ULTIMAIN_2) + #include "pins_ULTIMAIN_2.h" // ATmega2560 +#elif MB(RUMBA) + #include "pins_RUMBA.h" // ATmega2560 +#elif MB(BQ_ZUM_MEGA_3D) + #include "pins_BQ_ZUM_MEGA_3D.h" // ATmega2560 + +// +// Other ATmega1280, ATmega2560 +// + +#elif MB(CNCONTROLS_11) + #include "pins_CNCONTROLS_11.h" // ATmega1280, ATmega2560 +#elif MB(CNCONTROLS_12) + #include "pins_CNCONTROLS_12.h" // ATmega1280, ATmega2560 +#elif MB(MIGHTYBOARD_REVE) + #include "pins_MIGHTYBOARD_REVE.h" // ATmega1280, ATmega2560 +#elif MB(CHEAPTRONIC) + #include "pins_CHEAPTRONIC.h" // ATmega2560 +#elif MB(CHEAPTRONIC_V2) + #include "pins_CHEAPTRONICv2.h" // ATmega2560 +#elif MB(MEGATRONICS) + #include "pins_MEGATRONICS.h" // ATmega2560 +#elif MB(MEGATRONICS_2) + #include "pins_MEGATRONICS_2.h" // ATmega2560 +#elif MB(MEGATRONICS_3) + #include "pins_MEGATRONICS_3.h" // ATmega2560 +#elif MB(MEGATRONICS_31) + #define MEGATRONICS_31 + #include "pins_MEGATRONICS_3.h" // ATmega2560 +#elif MB(RAMBO) + #include "pins_RAMBO.h" // ATmega2560 +#elif MB(MINIRAMBO) + #include "pins_MINIRAMBO.h" // ATmega2560 +#elif MB(ELEFU_3) + #include "pins_ELEFU_3.h" // ATmega2560 +#elif MB(LEAPFROG) + #include "pins_LEAPFROG.h" // ATmega1280, ATmega2560 +#elif MB(MEGACONTROLLER) + #include "pins_MEGACONTROLLER.h" // ATmega2560 +#elif MB(SCOOVO_X9H) + #include "pins_SCOOVO_X9H.h" // ATmega2560 +#elif MB(GT2560_REV_A) + #include "pins_GT2560_REV_A.h" // ATmega1280, ATmega2560 +#elif MB(GT2560_REV_A_PLUS) + #include "pins_GT2560_REV_A_PLUS.h" // ATmega1280, ATmega2560 + +// +// ATmega1281, ATmega2561 +// + +#elif MB(MINITRONICS) + #include "pins_MINITRONICS.h" // ATmega1281 + +// +// Sanguinololu and Derivatives - ATmega644P, ATmega1284P +// + +#elif MB(SANGUINOLOLU_11) + #include "pins_SANGUINOLOLU_11.h" // ATmega644P, ATmega1284P +#elif MB(SANGUINOLOLU_12) + #include "pins_SANGUINOLOLU_12.h" // ATmega644P, ATmega1284P +#elif MB(MELZI) + #include "pins_MELZI.h" // ATmega644P, ATmega1284P +#elif MB(MELZI_MAKR3D) + #include "pins_MELZI_MAKR3D.h" // ATmega644P, ATmega1284P +#elif MB(MELZI_CREALITY) + #include "pins_MELZI_CREALITY.h" // ATmega644P, ATmega1284P +#elif MB(STB_11) + #include "pins_STB_11.h" // ATmega644P, ATmega1284P +#elif MB(AZTEEG_X1) + #include "pins_AZTEEG_X1.h" // ATmega644P, ATmega1284P + +// +// Other ATmega644P, ATmega644, ATmega1284P +// + +#elif MB(GEN3_MONOLITHIC) + #include "pins_GEN3_MONOLITHIC.h" // ATmega644P +#elif MB(GEN3_PLUS) + #include "pins_GEN3_PLUS.h" // ATmega644P, ATmega1284P +#elif MB(GEN6) + #include "pins_GEN6.h" // ATmega644P, ATmega1284P +#elif MB(GEN6_DELUXE) + #include "pins_GEN6_DELUXE.h" // ATmega644P, ATmega1284P +#elif MB(GEN7_CUSTOM) + #include "pins_GEN7_CUSTOM.h" // ATmega644P, ATmega644, ATmega1284P +#elif MB(GEN7_12) + #include "pins_GEN7_12.h" // ATmega644P, ATmega644, ATmega1284P +#elif MB(GEN7_13) + #include "pins_GEN7_13.h" // ATmega644P, ATmega644, ATmega1284P +#elif MB(GEN7_14) + #include "pins_GEN7_14.h" // ATmega644P, ATmega644, ATmega1284P +#elif MB(OMCA_A) + #include "pins_OMCA_A.h" // ATmega644 +#elif MB(OMCA) + #include "pins_OMCA.h" // ATmega644P, ATmega644 +#elif MB(ANET_10) + #include "pins_ANET_10.h" // ATmega1284P +#elif MB(SETHI) + #include "pins_SETHI.h" // ATmega644P, ATmega644, ATmega1284P + +// +// Teensyduino - AT90USB1286, AT90USB1286P +// + +#elif MB(TEENSYLU) + #include "pins_TEENSYLU.h" // AT90USB1286, AT90USB1286P +#elif MB(PRINTRBOARD) + #include "pins_PRINTRBOARD.h" // AT90USB1286 +#elif MB(PRINTRBOARD_REVF) + #include "pins_PRINTRBOARD_REVF.h" // AT90USB1286 +#elif MB(BRAINWAVE) + #include "pins_BRAINWAVE.h" // AT90USB646 +#elif MB(BRAINWAVE_PRO) + #include "pins_BRAINWAVE_PRO.h" // AT90USB1286 +#elif MB(SAV_MKI) + #include "pins_SAV_MKI.h" // AT90USB1286 +#elif MB(TEENSY2) + #include "pins_TEENSY2.h" // AT90USB1286 +#elif MB(5DPRINT) + #include "pins_5DPRINT.h" // AT90USB1286 + +#else + #error "Unknown MOTHERBOARD value set in Configuration.h" +#endif + +// Define certain undefined pins +#ifndef X_MS1_PIN + #define X_MS1_PIN -1 +#endif +#ifndef X_MS2_PIN + #define X_MS2_PIN -1 +#endif +#ifndef Y_MS1_PIN + #define Y_MS1_PIN -1 +#endif +#ifndef Y_MS2_PIN + #define Y_MS2_PIN -1 +#endif +#ifndef Z_MS1_PIN + #define Z_MS1_PIN -1 +#endif +#ifndef Z_MS2_PIN + #define Z_MS2_PIN -1 +#endif +#ifndef E0_MS1_PIN + #define E0_MS1_PIN -1 +#endif +#ifndef E0_MS2_PIN + #define E0_MS2_PIN -1 +#endif +#ifndef E1_MS1_PIN + #define E1_MS1_PIN -1 +#endif +#ifndef E1_MS2_PIN + #define E1_MS2_PIN -1 +#endif + +#ifndef FAN_PIN + #define FAN_PIN -1 +#endif +#ifndef FAN1_PIN + #define FAN1_PIN -1 +#endif +#ifndef FAN2_PIN + #define FAN2_PIN -1 +#endif +#ifndef CONTROLLER_FAN_PIN + #define CONTROLLER_FAN_PIN -1 +#endif + +#ifndef FANMUX0_PIN + #define FANMUX0_PIN -1 +#endif +#ifndef FANMUX1_PIN + #define FANMUX1_PIN -1 +#endif +#ifndef FANMUX2_PIN + #define FANMUX2_PIN -1 +#endif + +#ifndef HEATER_0_PIN + #define HEATER_0_PIN -1 +#endif +#ifndef HEATER_1_PIN + #define HEATER_1_PIN -1 +#endif +#ifndef HEATER_2_PIN + #define HEATER_2_PIN -1 +#endif +#ifndef HEATER_3_PIN + #define HEATER_3_PIN -1 +#endif +#ifndef HEATER_4_PIN + #define HEATER_4_PIN -1 +#endif +#ifndef HEATER_BED_PIN + #define HEATER_BED_PIN -1 +#endif + +#ifndef TEMP_0_PIN + #define TEMP_0_PIN -1 +#endif +#ifndef TEMP_1_PIN + #define TEMP_1_PIN -1 +#endif +#ifndef TEMP_2_PIN + #define TEMP_2_PIN -1 +#endif +#ifndef TEMP_3_PIN + #define TEMP_3_PIN -1 +#endif +#ifndef TEMP_4_PIN + #define TEMP_4_PIN -1 +#endif +#ifndef TEMP_BED_PIN + #define TEMP_BED_PIN -1 +#endif + +#ifndef SD_DETECT_PIN + #define SD_DETECT_PIN -1 +#endif +#ifndef SDPOWER + #define SDPOWER -1 +#endif +#ifndef SDSS + #define SDSS -1 +#endif +#ifndef LED_PIN + #define LED_PIN -1 +#endif +#ifndef PS_ON_PIN + #define PS_ON_PIN -1 +#endif +#ifndef KILL_PIN + #define KILL_PIN -1 +#endif +#ifndef SUICIDE_PIN + #define SUICIDE_PIN -1 +#endif + +#ifndef MAX_EXTRUDERS + #define MAX_EXTRUDERS 5 +#endif + +// Marlin needs to account for pins that equal -1 +#define marlinAnalogInputToDigitalPin(p) ((p) == -1 ? -1 : analogInputToDigitalPin(p)) + +// +// Assign auto fan pins if needed +// +#if !defined(E0_AUTO_FAN_PIN) && defined(ORIG_E0_AUTO_FAN_PIN) + #define E0_AUTO_FAN_PIN ORIG_E0_AUTO_FAN_PIN +#endif +#if !defined(E1_AUTO_FAN_PIN) && defined(ORIG_E1_AUTO_FAN_PIN) + #define E1_AUTO_FAN_PIN ORIG_E1_AUTO_FAN_PIN +#endif +#if !defined(E2_AUTO_FAN_PIN) && defined(ORIG_E2_AUTO_FAN_PIN) + #define E2_AUTO_FAN_PIN ORIG_E2_AUTO_FAN_PIN +#endif +#if !defined(E3_AUTO_FAN_PIN) && defined(ORIG_E3_AUTO_FAN_PIN) + #define E3_AUTO_FAN_PIN ORIG_E3_AUTO_FAN_PIN +#endif +#if !defined(E4_AUTO_FAN_PIN) && defined(ORIG_E4_AUTO_FAN_PIN) + #define E4_AUTO_FAN_PIN ORIG_E4_AUTO_FAN_PIN +#endif + +// List of pins which to ignore when asked to change by gcode, 0 and 1 are RX and TX, do not mess with those! +#define _E0_PINS E0_STEP_PIN, E0_DIR_PIN, E0_ENABLE_PIN, E0_MS1_PIN, E0_MS2_PIN, +#define _E1_PINS +#define _E2_PINS +#define _E3_PINS +#define _E4_PINS + +#if ENABLED(SWITCHING_EXTRUDER) + // Tools 0 and 1 use E0 + #if EXTRUDERS > 2 // Tools 2 and 3 use E1 + #undef _E1_PINS + #define _E1_PINS E1_STEP_PIN, E1_DIR_PIN, E1_ENABLE_PIN, E1_MS1_PIN, E1_MS2_PIN, + #if EXTRUDERS > 4 // Tools 4 and 5 use E2 + #undef _E2_PINS + #define _E2_PINS E2_STEP_PIN, E2_DIR_PIN, E2_ENABLE_PIN, + #endif + #endif +#elif EXTRUDERS > 1 + #undef _E1_PINS + #define _E1_PINS E1_STEP_PIN, E1_DIR_PIN, E1_ENABLE_PIN, E1_MS1_PIN, E1_MS2_PIN, + #if EXTRUDERS > 2 + #undef _E2_PINS + #define _E2_PINS E2_STEP_PIN, E2_DIR_PIN, E2_ENABLE_PIN, + #if EXTRUDERS > 3 + #undef _E3_PINS + #define _E3_PINS E3_STEP_PIN, E3_DIR_PIN, E3_ENABLE_PIN, + #if EXTRUDERS > 4 + #undef _E4_PINS + #define _E4_PINS E4_STEP_PIN, E4_DIR_PIN, E4_ENABLE_PIN, + #endif // EXTRUDERS > 4 + #endif // EXTRUDERS > 3 + #endif // EXTRUDERS > 2 +#endif // EXTRUDERS > 1 + +#define _H0_PINS HEATER_0_PIN, E0_AUTO_FAN_PIN, marlinAnalogInputToDigitalPin(TEMP_0_PIN), +#define _H1_PINS +#define _H2_PINS +#define _H3_PINS +#define _H4_PINS + +#if HOTENDS > 1 + #undef _H1_PINS + #define _H1_PINS HEATER_1_PIN, E1_AUTO_FAN_PIN, marlinAnalogInputToDigitalPin(TEMP_1_PIN), + #if HOTENDS > 2 + #undef _H2_PINS + #define _H2_PINS HEATER_2_PIN, E2_AUTO_FAN_PIN, marlinAnalogInputToDigitalPin(TEMP_2_PIN), + #if HOTENDS > 3 + #undef _H3_PINS + #define _H3_PINS HEATER_3_PIN, E3_AUTO_FAN_PIN, marlinAnalogInputToDigitalPin(TEMP_3_PIN), + #if HOTENDS > 4 + #undef _H4_PINS + #define _H4_PINS HEATER_4_PIN, marlinAnalogInputToDigitalPin(TEMP_4_PIN), + #endif // HOTENDS > 4 + #endif // HOTENDS > 3 + #endif // HOTENDS > 2 +#elif ENABLED(MIXING_EXTRUDER) + #undef _E1_PINS + #define _E1_PINS E1_STEP_PIN, E1_DIR_PIN, E1_ENABLE_PIN, + #if MIXING_STEPPERS > 2 + #undef _E2_PINS + #define _E2_PINS E2_STEP_PIN, E2_DIR_PIN, E2_ENABLE_PIN, + #if MIXING_STEPPERS > 3 + #undef _E3_PINS + #define _E3_PINS E3_STEP_PIN, E3_DIR_PIN, E3_ENABLE_PIN, + #if MIXING_STEPPERS > 4 + #undef _E4_PINS + #define _E4_PINS E4_STEP_PIN, E4_DIR_PIN, E4_ENABLE_PIN, + #endif // MIXING_STEPPERS > 4 + #endif // MIXING_STEPPERS > 3 + #endif // MIXING_STEPPERS > 2 +#endif // MIXING_STEPPERS > 1 + +#define BED_PINS HEATER_BED_PIN, marlinAnalogInputToDigitalPin(TEMP_BED_PIN), + +// +// Assign endstop pins for boards with only 3 connectors +// +#ifdef X_STOP_PIN + #if X_HOME_DIR < 0 + #define X_MIN_PIN X_STOP_PIN + #define X_MAX_PIN -1 + #else + #define X_MIN_PIN -1 + #define X_MAX_PIN X_STOP_PIN + #endif +#endif + +#ifdef Y_STOP_PIN + #if Y_HOME_DIR < 0 + #define Y_MIN_PIN Y_STOP_PIN + #define Y_MAX_PIN -1 + #else + #define Y_MIN_PIN -1 + #define Y_MAX_PIN Y_STOP_PIN + #endif +#endif + +#ifdef Z_STOP_PIN + #if Z_HOME_DIR < 0 + #define Z_MIN_PIN Z_STOP_PIN + #define Z_MAX_PIN -1 + #else + #define Z_MIN_PIN -1 + #define Z_MAX_PIN Z_STOP_PIN + #endif +#endif + +// +// Disable unused endstop / probe pins +// +#if DISABLED(Z_MIN_PROBE_ENDSTOP) + #undef Z_MIN_PROBE_PIN + #define Z_MIN_PROBE_PIN -1 +#endif + +#if DISABLED(USE_XMAX_PLUG) + #undef X_MAX_PIN + #define X_MAX_PIN -1 +#endif + +#if DISABLED(USE_YMAX_PLUG) + #undef Y_MAX_PIN + #define Y_MAX_PIN -1 +#endif + +#if DISABLED(USE_ZMAX_PLUG) + #undef Z_MAX_PIN + #define Z_MAX_PIN -1 +#endif + +#if DISABLED(USE_XMIN_PLUG) + #undef X_MIN_PIN + #define X_MIN_PIN -1 +#endif + +#if DISABLED(USE_YMIN_PLUG) + #undef Y_MIN_PIN + #define Y_MIN_PIN -1 +#endif + +#if DISABLED(USE_ZMIN_PLUG) + #undef Z_MIN_PIN + #define Z_MIN_PIN -1 +#endif + +#ifndef LCD_PINS_D4 + #define LCD_PINS_D4 -1 +#endif +#ifndef LCD_PINS_D5 + #define LCD_PINS_D5 -1 +#endif +#ifndef LCD_PINS_D6 + #define LCD_PINS_D6 -1 +#endif +#ifndef LCD_PINS_D7 + #define LCD_PINS_D7 -1 +#endif + +// +// Dual X-carriage, Dual Y, Dual Z support +// + +#define _X2_PINS +#define _Y2_PINS +#define _Z2_PINS + +#define __EPIN(p,q) E##p##_##q##_PIN +#define _EPIN(p,q) __EPIN(p,q) + +// The X2 axis, if any, should be the next open extruder port +#if ENABLED(DUAL_X_CARRIAGE) || ENABLED(X_DUAL_STEPPER_DRIVERS) + #ifndef X2_STEP_PIN + #define X2_STEP_PIN _EPIN(E_STEPPERS, STEP) + #define X2_DIR_PIN _EPIN(E_STEPPERS, DIR) + #define X2_ENABLE_PIN _EPIN(E_STEPPERS, ENABLE) + #if X2_ENABLE_PIN == 0 + #error "No E stepper plug left for X2!" + #endif + #endif + #undef _X2_PINS + #define _X2_PINS X2_STEP_PIN, X2_DIR_PIN, X2_ENABLE_PIN, + #define Y2_E_INDEX INCREMENT(E_STEPPERS) +#else + #define Y2_E_INDEX E_STEPPERS +#endif + +// The Y2 axis, if any, should be the next open extruder port +#if ENABLED(Y_DUAL_STEPPER_DRIVERS) + #ifndef Y2_STEP_PIN + #define Y2_STEP_PIN _EPIN(Y2_E_INDEX, STEP) + #define Y2_DIR_PIN _EPIN(Y2_E_INDEX, DIR) + #define Y2_ENABLE_PIN _EPIN(Y2_E_INDEX, ENABLE) + #if Y2_ENABLE_PIN == 0 + #error "No E stepper plug left for Y2!" + #endif + #endif + #undef _Y2_PINS + #define _Y2_PINS Y2_STEP_PIN, Y2_DIR_PIN, Y2_ENABLE_PIN, + #define Z2_E_INDEX INCREMENT(Y2_E_INDEX) +#else + #define Z2_E_INDEX Y2_E_INDEX +#endif + +// The Z2 axis, if any, should be the next open extruder port +#if ENABLED(Z_DUAL_STEPPER_DRIVERS) + #ifndef Z2_STEP_PIN + #define Z2_STEP_PIN _EPIN(Z2_E_INDEX, STEP) + #define Z2_DIR_PIN _EPIN(Z2_E_INDEX, DIR) + #define Z2_ENABLE_PIN _EPIN(Z2_E_INDEX, ENABLE) + #if Z2_ENABLE_PIN == 0 + #error "No E stepper plug left for Z2!" + #endif + #endif + #undef _Z2_PINS + #define _Z2_PINS Z2_STEP_PIN, Z2_DIR_PIN, Z2_ENABLE_PIN, +#endif + +#define SENSITIVE_PINS { 0, 1, \ + X_STEP_PIN, X_DIR_PIN, X_ENABLE_PIN, X_MIN_PIN, X_MAX_PIN, \ + Y_STEP_PIN, Y_DIR_PIN, Y_ENABLE_PIN, Y_MIN_PIN, Y_MAX_PIN, \ + Z_STEP_PIN, Z_DIR_PIN, Z_ENABLE_PIN, Z_MIN_PIN, Z_MAX_PIN, Z_MIN_PROBE_PIN, \ + PS_ON_PIN, HEATER_BED_PIN, FAN_PIN, FAN1_PIN, FAN2_PIN, CONTROLLER_FAN_PIN, \ + _E0_PINS _E1_PINS _E2_PINS _E3_PINS _E4_PINS BED_PINS \ + _H0_PINS _H1_PINS _H2_PINS _H3_PINS _H4_PINS \ + _X2_PINS _Y2_PINS _Z2_PINS \ + X_MS1_PIN, X_MS2_PIN, Y_MS1_PIN, Y_MS2_PIN, Z_MS1_PIN, Z_MS2_PIN \ + } + +#define HAS_DIGIPOTSS (PIN_EXISTS(DIGIPOTSS)) + +/** + * Define SPI Pins: SCK, MISO, MOSI, SS + */ +#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328__) || defined(__AVR_ATmega328P__) + #define AVR_SCK_PIN 13 + #define AVR_MISO_PIN 12 + #define AVR_MOSI_PIN 11 + #define AVR_SS_PIN 10 +#elif defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__) || defined(__AVR_ATmega1284P__) + #define AVR_SCK_PIN 7 + #define AVR_MISO_PIN 6 + #define AVR_MOSI_PIN 5 + #define AVR_SS_PIN 4 +#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) + #define AVR_SCK_PIN 52 + #define AVR_MISO_PIN 50 + #define AVR_MOSI_PIN 51 + #define AVR_SS_PIN 53 +#elif defined(__AVR_AT90USB1287__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) + #define AVR_SCK_PIN 21 + #define AVR_MISO_PIN 23 + #define AVR_MOSI_PIN 22 + #define AVR_SS_PIN 20 +#elif defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__) + #define AVR_SCK_PIN 10 + #define AVR_MISO_PIN 12 + #define AVR_MOSI_PIN 11 + #define AVR_SS_PIN 16 +#endif + +#ifndef SCK_PIN + #define SCK_PIN AVR_SCK_PIN +#endif +#ifndef MISO_PIN + #define MISO_PIN AVR_MISO_PIN +#endif +#ifndef MOSI_PIN + #define MOSI_PIN AVR_MOSI_PIN +#endif +#ifndef SS_PIN + #define SS_PIN AVR_SS_PIN +#endif + +#endif // __PINS_H__ diff --git a/trunk/Arduino/Marlin_1.1.6/pinsDebug.h b/trunk/Arduino/Marlin_1.1.6/pinsDebug.h new file mode 100644 index 00000000..56f0916d --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pinsDebug.h @@ -0,0 +1,583 @@ +/** + * 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 . + * + */ + +bool endstop_monitor_flag = false; + +#define NAME_FORMAT "%-35s" // one place to specify the format of all the sources of names + // "-" left justify, "28" minimum width of name, pad with blanks + +#define IS_ANALOG(P) ((P) >= analogInputToDigitalPin(0) && ((P) <= analogInputToDigitalPin(15) || (P) <= analogInputToDigitalPin(7))) + +/** + * This routine minimizes RAM usage by creating a FLASH resident array to + * store the pin names, pin numbers and analog/digital flag. + * + * Creating the array in FLASH is a two pass process. The first pass puts the + * name strings into FLASH. The second pass actually creates the array. + * + * 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 + +#define _ADD_PIN_2(PIN_NAME, ENTRY_NAME) static const char ENTRY_NAME[] PROGMEM = { PIN_NAME }; +#define _ADD_PIN(PIN_NAME, COUNTER) _ADD_PIN_2(PIN_NAME, entry_NAME_##COUNTER) +#define REPORT_NAME_DIGITAL(NAME, COUNTER) _ADD_PIN(#NAME, COUNTER) +#define REPORT_NAME_ANALOG(NAME, COUNTER) _ADD_PIN(#NAME, COUNTER) + +#include "pinsDebug_list.h" +#line 51 + +// manually add pins that have names that are macros which don't play well with these macros +#if SERIAL_PORT == 0 && (AVR_ATmega2560_FAMILY || AVR_ATmega1284_FAMILY) + static const char RXD_NAME[] PROGMEM = { "RXD" }; + static const char TXD_NAME[] PROGMEM = { "TXD" }; +#endif + +///////////////////////////////////////////////////////////////////////////// + +// second pass - create the array + +#undef _ADD_PIN_2 +#undef _ADD_PIN +#undef REPORT_NAME_DIGITAL +#undef REPORT_NAME_ANALOG + +#define _ADD_PIN_2(ENTRY_NAME, NAME, IS_DIGITAL) { ENTRY_NAME, NAME, IS_DIGITAL }, +#define _ADD_PIN(NAME, COUNTER, IS_DIGITAL) _ADD_PIN_2(entry_NAME_##COUNTER, NAME, IS_DIGITAL) +#define REPORT_NAME_DIGITAL(NAME, COUNTER) _ADD_PIN(NAME, COUNTER, true) +#define REPORT_NAME_ANALOG(NAME, COUNTER) _ADD_PIN(analogInputToDigitalPin(NAME), COUNTER, false) + +typedef struct { + const char * const name; + uint8_t pin; + bool is_digital; +} PinInfo; + +const PinInfo pin_array[] PROGMEM = { + + /** + * [pin name] [pin number] [is digital or analog] 1 = digital, 0 = analog + * Each entry takes up 6 bytes in FLASH: + * 2 byte pointer to location of the name string + * 2 bytes containing the pin number + * analog pin numbers were convereted to digital when the array was created + * 2 bytes containing the digital/analog bool flag + */ + + // manually add pins ... + #if SERIAL_PORT == 0 + #if AVR_ATmega2560_FAMILY + { RXD_NAME, 0, true }, + { TXD_NAME, 1, true }, + #elif AVR_ATmega1284_FAMILY + { RXD_NAME, 8, true }, + { TXD_NAME, 9, true }, + #endif + #endif + + #include "pinsDebug_list.h" + #line 102 + +}; + +#define AVR_ATmega2560_FAMILY_PLUS_70 (MOTHERBOARD == BOARD_BQ_ZUM_MEGA_3D \ +|| MOTHERBOARD == BOARD_MIGHTYBOARD_REVE \ +|| MOTHERBOARD == BOARD_MINIRAMBO \ +|| MOTHERBOARD == BOARD_SCOOVO_X9H) + +#if AVR_AT90USB1286_FAMILY + // Working with Teensyduino extension so need to re-define some things + #include "pinsDebug_Teensyduino.h" + // Can't use the "digitalPinToPort" function from the Teensyduino type IDEs + // portModeRegister takes a different argument + #define digitalPinToTimer_DEBUG(p) digitalPinToTimer(p) + #define digitalPinToBitMask_DEBUG(p) digitalPinToBitMask(p) + #define digitalPinToPort_DEBUG(p) digitalPinToPort_Teensy(p) + #define get_pinMode(pin) (*portModeRegister(pin) & digitalPinToBitMask_DEBUG(pin)) +#elif AVR_ATmega2560_FAMILY_PLUS_70 // So we can access/display all the pins on boards using more than 70 + #include "pinsDebug_plus_70.h" + #define digitalPinToTimer_DEBUG(p) digitalPinToTimer_plus_70(p) + #define digitalPinToBitMask_DEBUG(p) digitalPinToBitMask_plus_70(p) + #define digitalPinToPort_DEBUG(p) digitalPinToPort_plus_70(p) + bool get_pinMode(int8_t pin) {return *portModeRegister(digitalPinToPort_DEBUG(pin)) & digitalPinToBitMask_DEBUG(pin); } +#else + #define digitalPinToTimer_DEBUG(p) digitalPinToTimer(p) + #define digitalPinToBitMask_DEBUG(p) digitalPinToBitMask(p) + #define digitalPinToPort_DEBUG(p) digitalPinToPort(p) + bool get_pinMode(int8_t pin) {return *portModeRegister(digitalPinToPort_DEBUG(pin)) & digitalPinToBitMask_DEBUG(pin); } +#endif + +#if defined(__AVR_ATmega1284P__) // 1284 IDE extensions set this to the number of + #undef NUM_DIGITAL_PINS // digital only pins while all other CPUs have it + #define NUM_DIGITAL_PINS 32 // set to digital only + digital/analog +#endif + +#define PWM_PRINT(V) do{ sprintf_P(buffer, PSTR("PWM: %4d"), V); SERIAL_ECHO(buffer); }while(0) +#define PWM_CASE(N,Z) \ + case TIMER##N##Z: \ + if (TCCR##N##A & (_BV(COM##N##Z##1) | _BV(COM##N##Z##0))) { \ + PWM_PRINT(OCR##N##Z); \ + return true; \ + } else return false + +/** + * Print a pin's PWM status. + * Return true if it's currently a PWM pin. + */ +static bool pwm_status(uint8_t pin) { + char buffer[20]; // for the sprintf statements + + switch (digitalPinToTimer_DEBUG(pin)) { + + #if defined(TCCR0A) && defined(COM0A1) + #ifdef TIMER0A + #if !AVR_AT90USB1286_FAMILY // not available in Teensyduino type IDEs + PWM_CASE(0, A); + #endif + #endif + PWM_CASE(0, B); + #endif + + #if defined(TCCR1A) && defined(COM1A1) + PWM_CASE(1, A); + PWM_CASE(1, B); + #if defined(COM1C1) && defined(TIMER1C) + PWM_CASE(1, C); + #endif + #endif + + #if defined(TCCR2A) && defined(COM2A1) + PWM_CASE(2, A); + PWM_CASE(2, B); + #endif + + #if defined(TCCR3A) && defined(COM3A1) + PWM_CASE(3, A); + PWM_CASE(3, B); + #ifdef COM3C1 + PWM_CASE(3, C); + #endif + #endif + + #ifdef TCCR4A + PWM_CASE(4, A); + PWM_CASE(4, B); + PWM_CASE(4, C); + #endif + + #if defined(TCCR5A) && defined(COM5A1) + PWM_CASE(5, A); + PWM_CASE(5, B); + PWM_CASE(5, C); + #endif + + case NOT_ON_TIMER: + default: + return false; + } + SERIAL_PROTOCOL_SP(2); +} // pwm_status + + +const volatile uint8_t* const PWM_other[][3] PROGMEM = { + { &TCCR0A, &TCCR0B, &TIMSK0 }, + { &TCCR1A, &TCCR1B, &TIMSK1 }, + #if defined(TCCR2A) && defined(COM2A1) + { &TCCR2A, &TCCR2B, &TIMSK2 }, + #endif + #if defined(TCCR3A) && defined(COM3A1) + { &TCCR3A, &TCCR3B, &TIMSK3 }, + #endif + #ifdef TCCR4A + { &TCCR4A, &TCCR4B, &TIMSK4 }, + #endif + #if defined(TCCR5A) && defined(COM5A1) + { &TCCR5A, &TCCR5B, &TIMSK5 }, + #endif +}; + + +const volatile uint8_t* const PWM_OCR[][3] PROGMEM = { + + #ifdef TIMER0A + { &OCR0A, &OCR0B, 0 }, + #else + { 0, &OCR0B, 0 }, + #endif + + #if defined(COM1C1) && defined(TIMER1C) + { (const uint8_t*)&OCR1A, (const uint8_t*)&OCR1B, (const uint8_t*)&OCR1C }, + #else + { (const uint8_t*)&OCR1A, (const uint8_t*)&OCR1B, 0 }, + #endif + + #if defined(TCCR2A) && defined(COM2A1) + { &OCR2A, &OCR2B, 0 }, + #endif + + #if defined(TCCR3A) && defined(COM3A1) + #ifdef COM3C1 + { (const uint8_t*)&OCR3A, (const uint8_t*)&OCR3B, (const uint8_t*)&OCR3C }, + #else + { (const uint8_t*)&OCR3A, (const uint8_t*)&OCR3B, 0 }, + #endif + #endif + + #ifdef TCCR4A + { (const uint8_t*)&OCR4A, (const uint8_t*)&OCR4B, (const uint8_t*)&OCR4C }, + #endif + + #if defined(TCCR5A) && defined(COM5A1) + { (const uint8_t*)&OCR5A, (const uint8_t*)&OCR5B, (const uint8_t*)&OCR5C }, + #endif +}; + + +#define TCCR_A(T) pgm_read_word(&PWM_other[T][0]) +#define TCCR_B(T) pgm_read_word(&PWM_other[T][1]) +#define TIMSK(T) pgm_read_word(&PWM_other[T][2]) +#define CS_0 0 +#define CS_1 1 +#define CS_2 2 +#define WGM_0 0 +#define WGM_1 1 +#define WGM_2 3 +#define WGM_3 4 +#define TOIE 0 + +#define OCR_VAL(T, L) pgm_read_word(&PWM_OCR[T][L]) + +static void err_is_counter() { SERIAL_PROTOCOLPGM(" non-standard PWM mode"); } +static void err_is_interrupt() { SERIAL_PROTOCOLPGM(" compare interrupt enabled"); } +static void err_prob_interrupt() { SERIAL_PROTOCOLPGM(" overflow interrupt enabled"); } + +#if AVR_ATmega2560_FAMILY || AVR_AT90USB1286_FAMILY + static void print_is_also_tied() { SERIAL_PROTOCOLPGM(" is also tied to this pin"); SERIAL_PROTOCOL_SP(14); } +#endif + +void com_print(uint8_t N, uint8_t Z) { + const uint8_t *TCCRA = (uint8_t*)TCCR_A(N); + SERIAL_PROTOCOLPGM(" COM"); + SERIAL_PROTOCOLCHAR(N + '0'); + switch (Z) { + case 'A': + SERIAL_PROTOCOLPAIR("A: ", ((*TCCRA & (_BV(7) | _BV(6))) >> 6)); + break; + case 'B': + SERIAL_PROTOCOLPAIR("B: ", ((*TCCRA & (_BV(5) | _BV(4))) >> 4)); + break; + case 'C': + SERIAL_PROTOCOLPAIR("C: ", ((*TCCRA & (_BV(3) | _BV(2))) >> 2)); + break; + } +} + +void timer_prefix(uint8_t T, char L, uint8_t N) { // T - timer L - pwm N - WGM bit layout + char buffer[20]; // for the sprintf statements + const uint8_t *TCCRB = (uint8_t*)TCCR_B(T), + *TCCRA = (uint8_t*)TCCR_A(T); + uint8_t WGM = (((*TCCRB & _BV(WGM_2)) >> 1) | (*TCCRA & (_BV(WGM_0) | _BV(WGM_1)))); + if (N == 4) WGM |= ((*TCCRB & _BV(WGM_3)) >> 1); + + SERIAL_PROTOCOLPGM(" TIMER"); + SERIAL_PROTOCOLCHAR(T + '0'); + SERIAL_PROTOCOLCHAR(L); + SERIAL_PROTOCOL_SP(3); + + if (N == 3) { + const uint8_t *OCRVAL8 = (uint8_t*)OCR_VAL(T, L - 'A'); + PWM_PRINT(*OCRVAL8); + } + else { + const uint16_t *OCRVAL16 = (uint16_t*)OCR_VAL(T, L - 'A'); + PWM_PRINT(*OCRVAL16); + } + SERIAL_PROTOCOLPAIR(" WGM: ", WGM); + com_print(T,L); + SERIAL_PROTOCOLPAIR(" CS: ", (*TCCRB & (_BV(CS_0) | _BV(CS_1) | _BV(CS_2)) )); + + SERIAL_PROTOCOLPGM(" TCCR"); + SERIAL_PROTOCOLCHAR(T + '0'); + SERIAL_PROTOCOLPAIR("A: ", *TCCRA); + + SERIAL_PROTOCOLPGM(" TCCR"); + SERIAL_PROTOCOLCHAR(T + '0'); + SERIAL_PROTOCOLPAIR("B: ", *TCCRB); + + const uint8_t *TMSK = (uint8_t*)TIMSK(T); + SERIAL_PROTOCOLPGM(" TIMSK"); + SERIAL_PROTOCOLCHAR(T + '0'); + SERIAL_PROTOCOLPAIR(": ", *TMSK); + + const uint8_t OCIE = L - 'A' + 1; + if (N == 3) { if (WGM == 0 || WGM == 2 || WGM == 4 || WGM == 6) err_is_counter(); } + else { if (WGM == 0 || WGM == 4 || WGM == 12 || WGM == 13) err_is_counter(); } + if (TEST(*TMSK, OCIE)) err_is_interrupt(); + if (TEST(*TMSK, TOIE)) err_prob_interrupt(); +} + +static void pwm_details(uint8_t pin) { + switch (digitalPinToTimer_DEBUG(pin)) { + + #if defined(TCCR0A) && defined(COM0A1) + #ifdef TIMER0A + #if !AVR_AT90USB1286_FAMILY // not available in Teensyduino type IDEs + case TIMER0A: timer_prefix(0, 'A', 3); break; + #endif + #endif + case TIMER0B: timer_prefix(0, 'B', 3); break; + #endif + + #if defined(TCCR1A) && defined(COM1A1) + case TIMER1A: timer_prefix(1, 'A', 4); break; + case TIMER1B: timer_prefix(1, 'B', 4); break; + #if defined(COM1C1) && defined(TIMER1C) + case TIMER1C: timer_prefix(1, 'C', 4); break; + #endif + #endif + + #if defined(TCCR2A) && defined(COM2A1) + case TIMER2A: timer_prefix(2, 'A', 3); break; + case TIMER2B: timer_prefix(2, 'B', 3); break; + #endif + + #if defined(TCCR3A) && defined(COM3A1) + case TIMER3A: timer_prefix(3, 'A', 4); break; + case TIMER3B: timer_prefix(3, 'B', 4); break; + #ifdef COM3C1 + case TIMER3C: timer_prefix(3, 'C', 4); break; + #endif + #endif + + #ifdef TCCR4A + case TIMER4A: timer_prefix(4, 'A', 4); break; + case TIMER4B: timer_prefix(4, 'B', 4); break; + case TIMER4C: timer_prefix(4, 'C', 4); break; + #endif + + #if defined(TCCR5A) && defined(COM5A1) + case TIMER5A: timer_prefix(5, 'A', 4); break; + case TIMER5B: timer_prefix(5, 'B', 4); break; + case TIMER5C: timer_prefix(5, 'C', 4); break; + #endif + + case NOT_ON_TIMER: break; + + } + SERIAL_PROTOCOLPGM(" "); + + // on pins that have two PWMs, print info on second PWM + #if AVR_ATmega2560_FAMILY || AVR_AT90USB1286_FAMILY + // looking for port B7 - PWMs 0A and 1C + if (digitalPinToPort_DEBUG(pin) == 'B' - 64 && 0x80 == digitalPinToBitMask_DEBUG(pin)) { + #if !AVR_AT90USB1286_FAMILY + SERIAL_PROTOCOLPGM("\n ."); + SERIAL_PROTOCOL_SP(18); + SERIAL_PROTOCOLPGM("TIMER1C"); + print_is_also_tied(); + timer_prefix(1, 'C', 4); + #else + SERIAL_PROTOCOLPGM("\n ."); + SERIAL_PROTOCOL_SP(18); + SERIAL_PROTOCOLPGM("TIMER0A"); + print_is_also_tied(); + timer_prefix(0, 'A', 3); + #endif + } + #endif +} // pwm_details + +#ifndef digitalRead_mod // Use Teensyduino's version of digitalRead - it doesn't disable the PWMs + int digitalRead_mod(const int8_t pin) { // same as digitalRead except the PWM stop section has been removed + const uint8_t port = digitalPinToPort_DEBUG(pin); + return (port != NOT_A_PIN) && (*portInputRegister(port) & digitalPinToBitMask_DEBUG(pin)) ? HIGH : LOW; + } +#endif + +void print_port(int8_t pin) { // print port number + #ifdef digitalPinToPort_DEBUG + uint8_t x; + SERIAL_PROTOCOLPGM(" Port: "); + #if AVR_AT90USB1286_FAMILY + x = (pin == 46 || pin == 47) ? 'E' : digitalPinToPort_DEBUG(pin) + 64; + #else + x = digitalPinToPort_DEBUG(pin) + 64; + #endif + SERIAL_CHAR(x); + + #if AVR_AT90USB1286_FAMILY + if (pin == 46) + x = '2'; + else if (pin == 47) + x = '3'; + else { + uint8_t temp = digitalPinToBitMask_DEBUG(pin); + for (x = '0'; x < '9' && temp != 1; x++) temp >>= 1; + } + #else + uint8_t temp = digitalPinToBitMask_DEBUG(pin); + for (x = '0'; x < '9' && temp != 1; x++) temp >>= 1; + #endif + SERIAL_CHAR(x); + #else + SERIAL_PROTOCOL_SP(10); + #endif +} + +static void print_input_or_output(const bool isout) { + serialprintPGM(isout ? PSTR("Output = ") : PSTR("Input = ")); +} + +// pretty report with PWM info +inline void report_pin_state_extended(int8_t pin, bool ignore, bool extended = false, const char *start_string = "") { + uint8_t temp_char; + char *name_mem_pointer, buffer[30]; // 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 + if (pgm_read_byte(&pin_array[x].pin) == pin) { + if (found) multi_name_pin = true; + found = true; + if (!multi_name_pin) { // report digitial and analog pin number only on the first time through + sprintf_P(buffer, PSTR("%sPIN: %3d "), start_string, pin); // digital pin number + SERIAL_ECHO(buffer); + print_port(pin); + if (IS_ANALOG(pin)) { + sprintf_P(buffer, PSTR(" (A%2d) "), int(pin - analogInputToDigitalPin(0))); // analog pin number + SERIAL_ECHO(buffer); + } + else SERIAL_ECHO_SP(8); // add padding if not an analog pin + } + else { + SERIAL_CHAR('.'); + SERIAL_ECHO_SP(26 + strlen(start_string)); // add padding if not the first instance found + } + name_mem_pointer = (char*)pgm_read_word(&pin_array[x].name); + for (uint8_t y = 0; y < 28; y++) { // always print pin name + temp_char = pgm_read_byte(name_mem_pointer + y); + if (temp_char != 0) + MYSERIAL.write(temp_char); + else { + for (uint8_t i = 0; i < 28 - y; i++) MYSERIAL.write(' '); + break; + } + } + 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(GET_OUTPUT(46)); + SERIAL_PROTOCOL(READ(46)); + } + else if (pin == 47) { + print_input_or_output(GET_OUTPUT(47)); + SERIAL_PROTOCOL(READ(47)); + } + } + else + #endif + { + if (!(pgm_read_byte(&pin_array[x].is_digital))) { + sprintf_P(buffer, PSTR("Analog in = %5d"), analogRead(pin - analogInputToDigitalPin(0))); + SERIAL_ECHO(buffer); + } + else { + + if (!get_pinMode(pin)) { + //pinMode(pin, INPUT_PULLUP); // make sure input isn't floating - stopped doing this + // because this could interfere with inductive/capacitive + // sensors (high impedance voltage divider) and with PT100 amplifier + print_input_or_output(false); + SERIAL_PROTOCOL(digitalRead_mod(pin)); + } + else if (pwm_status(pin)) { + // do nothing + } + else { + print_input_or_output(true); + SERIAL_PROTOCOL(digitalRead_mod(pin)); + } + } + if (!multi_name_pin && extended) pwm_details(pin); // report PWM capabilities only on the first pass & only if doing an extended report + } + } + } + SERIAL_EOL(); + } // end of IF + } // end of for loop + + if (!found) { + sprintf_P(buffer, PSTR("%sPIN: %3d "), start_string, pin); + SERIAL_ECHO(buffer); + print_port(pin); + if (IS_ANALOG(pin)) { + sprintf_P(buffer, PSTR(" (A%2d) "), int(pin - analogInputToDigitalPin(0))); // analog pin number + SERIAL_ECHO(buffer); + } + else + 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_PROTOCOL_SP(12); + if (pin == 46) { + print_input_or_output(GET_OUTPUT(46)); + SERIAL_PROTOCOL(READ(46)); + } + else { + print_input_or_output(GET_OUTPUT(47)); + SERIAL_PROTOCOL(READ(47)); + } + } + else + #endif + { + if (get_pinMode(pin)) { + SERIAL_PROTOCOL_SP(12); + print_input_or_output(true); + SERIAL_PROTOCOL(digitalRead_mod(pin)); + } + else { + if (IS_ANALOG(pin)) { + sprintf_P(buffer, PSTR(" Analog in = %5d"), analogRead(pin - analogInputToDigitalPin(0))); + SERIAL_ECHO(buffer); + SERIAL_ECHOPGM(" "); + } + else + SERIAL_ECHO_SP(12); // add padding if not an analog pin + + print_input_or_output(false); + SERIAL_PROTOCOL(digitalRead_mod(pin)); + } + //if (!pwm_status(pin)) SERIAL_CHAR(' '); // add padding if it's not a PWM pin + if (extended) pwm_details(pin); // report PWM capabilities only if doing an extended report + } + } + SERIAL_EOL(); + } +} diff --git a/trunk/Arduino/Marlin_1.1.6/pinsDebug_Teensyduino.h b/trunk/Arduino/Marlin_1.1.6/pinsDebug_Teensyduino.h new file mode 100644 index 00000000..797a2cd7 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pinsDebug_Teensyduino.h @@ -0,0 +1,106 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2017 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +// +// some of the pin mapping functions of the Teensduino extension to the Arduino IDE +// do not function the same as the other Arduino extensions +// + +#ifndef __PINSDEBUG_TEENSYDUINO_H__ +#define __PINSDEBUG_TEENSYDUINO_H__ + +#undef NUM_DIGITAL_PINS +#define NUM_DIGITAL_PINS 48 // Teensy says 46 but FASTIO is 48 + +// "digitalPinToPort" function just returns the pin number so need to create our own. +// Can't use the name "digitalPinToPort" for our own because it interferes with the +// FAST_PWM_FAN function if we do + +#define PA 1 +#define PB 2 +#define PC 3 +#define PD 4 +#define PE 5 +#define PF 6 + + +const uint8_t PROGMEM digital_pin_to_port_PGM_Teensy[] = { + PD, // 0 - PD0 - INT0 - PWM + PD, // 1 - PD1 - INT1 - PWM + PD, // 2 - PD2 - INT2 - RX + PD, // 3 - PD3 - INT3 - TX + PD, // 4 - PD4 + PD, // 5 - PD5 + PD, // 6 - PD6 + PD, // 7 - PD7 + PE, // 8 - PE0 + PE, // 9 - PE1 + PC, // 10 - PC0 + PC, // 11 - PC1 + PC, // 12 - PC2 + PC, // 13 - PC3 + PC, // 14 - PC4 - PWM + PC, // 15 - PC5 - PWM + PC, // 16 - PC6 - PWM + PC, // 17 - PC7 + PE, // 18 - PE6 - INT6 + PE, // 19 - PE7 - INT7 + PB, // 20 - PB0 + PB, // 21 - PB1 + PB, // 22 - PB2 + PB, // 23 - PB3 + PB, // 24 - PB4 - PWM + PB, // 25 - PB5 - PWM + PB, // 26 - PB6 - PWM + PB, // 27 - PB7 - PWM + PA, // 28 - PA0 + PA, // 29 - PA1 + PA, // 30 - PA2 + PA, // 31 - PA3 + PA, // 32 - PA4 + PA, // 33 - PA5 + PA, // 34 - PA6 + PA, // 35 - PA7 + PE, // 36 - PE4 - INT4 + PE, // 37 - PE5 - INT5 + PF, // 38 - PF0 - A0 + PF, // 39 - PF1 - A1 + PF, // 40 - PF2 - A2 + PF, // 41 - PF3 - A3 + PF, // 42 - PF4 - A4 + PF, // 43 - PF5 - A5 + PF, // 44 - PF6 - A6 + PF, // 45 - PF7 - A7 + PE, // 46 - PE2 (not defined in teensyduino) + PE, // 47 - PE3 (not defined in teensyduino) +}; + +#define digitalPinToPort_Teensy(P) ( pgm_read_byte( digital_pin_to_port_PGM_Teensy + (P) ) ) + +// digitalPinToBitMask(pin) is OK + +#define digitalRead_mod(p) digitalRead(p) // Teensyduino's version of digitalRead doesn't + // disable the PWMs so we can use it as is + +// portModeRegister(pin) is OK + +#endif // __PINSDEBUG_TEENSYDUINO_H__ diff --git a/trunk/Arduino/Marlin_1.1.6/pinsDebug_list.h b/trunk/Arduino/Marlin_1.1.6/pinsDebug_list.h new file mode 100644 index 00000000..b4cc4c29 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pinsDebug_list.h @@ -0,0 +1,779 @@ +/** + * 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 . + * + */ + +// Please update this list when adding new pins to Marlin. +// The order doesn't matter. +// Following this pattern is a must. +// If the new pin name is over 28 characters long then pinsDebug.h will need to be modified. + +// Pin list updated from 18 FEB 2017 RCBugfix branch - max length of pin name is 24 + +#line 0 // set __LINE__ to a known value for both passes + +#if PIN_EXISTS(ADC_KEYPAD) && ADC_KEYPAD_PIN < NUM_ANALOG_INPUTS + REPORT_NAME_ANALOG(ADC_KEYPAD_PIN, __LINE__ ) +#endif +#if defined(__FD) && __FD >= 0 + REPORT_NAME_DIGITAL(__FD, __LINE__ ) +#endif +#if defined(__FS) && __FS >= 0 + REPORT_NAME_DIGITAL(__FS, __LINE__ ) +#endif +#if defined(__GD) && __GD >= 0 + REPORT_NAME_DIGITAL(__GD, __LINE__ ) +#endif +#if defined(__GS) && __GS >= 0 + REPORT_NAME_DIGITAL(__GS, __LINE__ ) +#endif +#if PIN_EXISTS(ADC_KEYPAD) + REPORT_NAME_ANALOG(ADC_KEYPAD_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(AVR_MISO) + REPORT_NAME_DIGITAL(AVR_MISO_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(AVR_MOSI) + REPORT_NAME_DIGITAL(AVR_MOSI_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(AVR_SCK) + REPORT_NAME_DIGITAL(AVR_SCK_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(AVR_SS) + REPORT_NAME_DIGITAL(AVR_SS_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(BEEPER) + REPORT_NAME_DIGITAL(BEEPER_PIN, __LINE__ ) +#endif +#if defined(BTN_CENTER) && BTN_CENTER >= 0 + REPORT_NAME_DIGITAL(BTN_CENTER, __LINE__ ) +#endif +#if defined(BTN_DOWN) && BTN_DOWN >= 0 + REPORT_NAME_DIGITAL(BTN_DOWN, __LINE__ ) +#endif +#if defined(BTN_DWN) && BTN_DWN >= 0 + REPORT_NAME_DIGITAL(BTN_DWN, __LINE__ ) +#endif +#if defined(BTN_EN1) && BTN_EN1 >= 0 + REPORT_NAME_DIGITAL(BTN_EN1, __LINE__ ) +#endif +#if defined(BTN_EN2) && BTN_EN2 >= 0 + REPORT_NAME_DIGITAL(BTN_EN2, __LINE__ ) +#endif +#if defined(BTN_ENC) && BTN_ENC >= 0 + REPORT_NAME_DIGITAL(BTN_ENC, __LINE__ ) +#endif +#if defined(BTN_HOME) && BTN_HOME >= 0 + REPORT_NAME_DIGITAL(BTN_HOME, __LINE__ ) +#endif +#if defined(BTN_LEFT) && BTN_LEFT >= 0 + REPORT_NAME_DIGITAL(BTN_LEFT, __LINE__ ) +#endif +#if defined(BTN_LFT) && BTN_LFT >= 0 + REPORT_NAME_DIGITAL(BTN_LFT, __LINE__ ) +#endif +#if defined(BTN_RIGHT) && BTN_RIGHT >= 0 + REPORT_NAME_DIGITAL(BTN_RIGHT, __LINE__ ) +#endif +#if defined(BTN_RT) && BTN_RT >= 0 + REPORT_NAME_DIGITAL(BTN_RT, __LINE__ ) +#endif +#if defined(BTN_UP) && BTN_UP >= 0 + REPORT_NAME_DIGITAL(BTN_UP, __LINE__ ) +#endif +#if PIN_EXISTS(CASE_LIGHT) + REPORT_NAME_DIGITAL(CASE_LIGHT_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(CONTROLLER_FAN) + REPORT_NAME_DIGITAL(CONTROLLER_FAN_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(CUTOFF_RESET) + REPORT_NAME_DIGITAL(CUTOFF_RESET_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(CUTOFF_TEST) + REPORT_NAME_DIGITAL(CUTOFF_TEST_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(DAC_DISABLE) + REPORT_NAME_DIGITAL(DAC_DISABLE_PIN, __LINE__ ) +#endif +#if defined(DAC_STEPPER_VREF) && DAC_STEPPER_VREF >= 0 + REPORT_NAME_DIGITAL(DAC_STEPPER_VREF, __LINE__ ) +#endif +#if PIN_EXISTS(DEBUG) + REPORT_NAME_DIGITAL(DEBUG_PIN, __LINE__ ) +#endif +#if defined(DIGIPOTS_I2C_SCL) && DIGIPOTS_I2C_SCL >= 0 + REPORT_NAME_DIGITAL(DIGIPOTS_I2C_SCL, __LINE__ ) +#endif +#if defined(DIGIPOTS_I2C_SDA_E0) && DIGIPOTS_I2C_SDA_E0 >= 0 + REPORT_NAME_DIGITAL(DIGIPOTS_I2C_SDA_E0, __LINE__ ) +#endif +#if defined(DIGIPOTS_I2C_SDA_E1) && DIGIPOTS_I2C_SDA_E1 >= 0 + REPORT_NAME_DIGITAL(DIGIPOTS_I2C_SDA_E1, __LINE__ ) +#endif +#if defined(DIGIPOTS_I2C_SDA_X) && DIGIPOTS_I2C_SDA_X >= 0 + REPORT_NAME_DIGITAL(DIGIPOTS_I2C_SDA_X, __LINE__ ) +#endif +#if defined(DIGIPOTS_I2C_SDA_Y) && DIGIPOTS_I2C_SDA_Y >= 0 + REPORT_NAME_DIGITAL(DIGIPOTS_I2C_SDA_Y, __LINE__ ) +#endif +#if defined(DIGIPOTS_I2C_SDA_Z) && DIGIPOTS_I2C_SDA_Z >= 0 + REPORT_NAME_DIGITAL(DIGIPOTS_I2C_SDA_Z, __LINE__ ) +#endif +#if PIN_EXISTS(DIGIPOTSS) + REPORT_NAME_DIGITAL(DIGIPOTSS_PIN, __LINE__ ) +#endif +#if defined(DOGLCD_A0) && DOGLCD_A0 >= 0 + REPORT_NAME_DIGITAL(DOGLCD_A0, __LINE__ ) +#endif +#if defined(DOGLCD_CS) && DOGLCD_CS >= 0 + REPORT_NAME_DIGITAL(DOGLCD_CS, __LINE__ ) +#endif +#if defined(DOGLCD_MOSI) && DOGLCD_MOSI >= 0 + REPORT_NAME_DIGITAL(DOGLCD_MOSI, __LINE__ ) +#endif +#if defined(DOGLCD_SCK) && DOGLCD_SCK >= 0 + REPORT_NAME_DIGITAL(DOGLCD_SCK, __LINE__ ) +#endif +#if PIN_EXISTS(E0_ATT) + REPORT_NAME_DIGITAL(E0_ATT_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(E0_AUTO_FAN) + REPORT_NAME_DIGITAL(E0_AUTO_FAN_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(E0_CS) + REPORT_NAME_DIGITAL(E0_CS_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(E0_DIR) + REPORT_NAME_DIGITAL(E0_DIR_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(E0_ENABLE) + REPORT_NAME_DIGITAL(E0_ENABLE_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(E0_MS1) + REPORT_NAME_DIGITAL(E0_MS1_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(E0_MS2) + REPORT_NAME_DIGITAL(E0_MS2_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(E0_STEP) + REPORT_NAME_DIGITAL(E0_STEP_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(E1_AUTO_FAN) + REPORT_NAME_DIGITAL(E1_AUTO_FAN_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(E1_CS) + REPORT_NAME_DIGITAL(E1_CS_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(E1_DIR) + REPORT_NAME_DIGITAL(E1_DIR_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(E1_ENABLE) + REPORT_NAME_DIGITAL(E1_ENABLE_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(E1_MS1) + REPORT_NAME_DIGITAL(E1_MS1_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(E1_MS2) + REPORT_NAME_DIGITAL(E1_MS2_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(E1_STEP) + REPORT_NAME_DIGITAL(E1_STEP_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(E2_AUTO_FAN) + REPORT_NAME_DIGITAL(E2_AUTO_FAN_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(E2_DIR) + REPORT_NAME_DIGITAL(E2_DIR_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(E2_ENABLE) + REPORT_NAME_DIGITAL(E2_ENABLE_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(E2_STEP) + REPORT_NAME_DIGITAL(E2_STEP_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(E3_AUTO_FAN) + REPORT_NAME_DIGITAL(E3_AUTO_FAN_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(E3_DIR) + REPORT_NAME_DIGITAL(E3_DIR_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(E3_ENABLE) + REPORT_NAME_DIGITAL(E3_ENABLE_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(E3_STEP) + REPORT_NAME_DIGITAL(E3_STEP_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(E4_AUTO_FAN) + REPORT_NAME_DIGITAL(E4_AUTO_FAN_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(E4_DIR) + REPORT_NAME_DIGITAL(E4_DIR_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(E4_ENABLE) + REPORT_NAME_DIGITAL(E4_ENABLE_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(E4_STEP) + REPORT_NAME_DIGITAL(E4_STEP_PIN, __LINE__ ) +#endif +#if defined(EXT_AUX_A0) && EXT_AUX_A0 >= 0 && EXT_AUX_A0 < NUM_ANALOG_INPUTS + REPORT_NAME_ANALOG(EXT_AUX_A0, __LINE__ ) +#endif +#if defined(EXT_AUX_A0) && EXT_AUX_A0 >= 0 && EXT_AUX_A0 >= NUM_ANALOG_INPUTS + REPORT_NAME_DIGITAL(EXT_AUX_A0, __LINE__ ) +#endif +#if defined(EXT_AUX_A0_IO) && EXT_AUX_A0_IO >= 0 + REPORT_NAME_DIGITAL(EXT_AUX_A0_IO, __LINE__ ) +#endif +#if defined(EXT_AUX_A1) && EXT_AUX_A1 >= 0 && EXT_AUX_A1 < NUM_ANALOG_INPUTS + REPORT_NAME_ANALOG(EXT_AUX_A1, __LINE__ ) +#endif +#if defined(EXT_AUX_A1) && EXT_AUX_A1 >= 0 && EXT_AUX_A1 >= NUM_ANALOG_INPUTS + REPORT_NAME_DIGITAL(EXT_AUX_A1, __LINE__ ) +#endif +#if defined(EXT_AUX_A1_IO) && EXT_AUX_A1_IO >= 0 + REPORT_NAME_DIGITAL(EXT_AUX_A1_IO, __LINE__ ) +#endif +#if defined(EXT_AUX_A2) && EXT_AUX_A2 >= 0 && EXT_AUX_A2 < NUM_ANALOG_INPUTS + REPORT_NAME_ANALOG(EXT_AUX_A2, __LINE__ ) +#endif +#if defined(EXT_AUX_A2) && EXT_AUX_A2 >= 0 && EXT_AUX_A2 >= NUM_ANALOG_INPUTS + REPORT_NAME_DIGITAL(EXT_AUX_A2, __LINE__ ) +#endif +#if defined(EXT_AUX_A2_IO) && EXT_AUX_A2_IO >= 0 + REPORT_NAME_DIGITAL(EXT_AUX_A2_IO, __LINE__ ) +#endif +#if defined(EXT_AUX_A3) && EXT_AUX_A3 >= 0 && EXT_AUX_A3 < NUM_ANALOG_INPUTS + REPORT_NAME_ANALOG(EXT_AUX_A3, __LINE__ ) +#endif +#if defined(EXT_AUX_A3) && EXT_AUX_A3 >= 0 && EXT_AUX_A3 >= NUM_ANALOG_INPUTS + REPORT_NAME_DIGITAL(EXT_AUX_A3, __LINE__ ) +#endif +#if defined(EXT_AUX_A3_IO) && EXT_AUX_A3_IO >= 0 + REPORT_NAME_DIGITAL(EXT_AUX_A3_IO, __LINE__ ) +#endif +#if defined(EXT_AUX_A4) && EXT_AUX_A4 >= 0 && EXT_AUX_A4 < NUM_ANALOG_INPUTS + REPORT_NAME_ANALOG(EXT_AUX_A4, __LINE__ ) +#endif +#if defined(EXT_AUX_A4) && EXT_AUX_A4 >= 0 && EXT_AUX_A4 >= NUM_ANALOG_INPUTS + REPORT_NAME_DIGITAL(EXT_AUX_A4, __LINE__ ) +#endif +#if defined(EXT_AUX_A4_IO) && EXT_AUX_A4_IO >= 0 + REPORT_NAME_DIGITAL(EXT_AUX_A4_IO, __LINE__ ) +#endif +#if defined(EXT_AUX_PWM_D24) && EXT_AUX_PWM_D24 >= 0 + REPORT_NAME_DIGITAL(EXT_AUX_PWM_D24, __LINE__ ) +#endif +#if defined(EXT_AUX_RX1_D2) && EXT_AUX_RX1_D2 >= 0 + REPORT_NAME_DIGITAL(EXT_AUX_RX1_D2, __LINE__ ) +#endif +#if defined(EXT_AUX_SCL_D0) && EXT_AUX_SCL_D0 >= 0 + REPORT_NAME_DIGITAL(EXT_AUX_SCL_D0, __LINE__ ) +#endif +#if defined(EXT_AUX_SDA_D1) && EXT_AUX_SDA_D1 >= 0 + REPORT_NAME_DIGITAL(EXT_AUX_SDA_D1, __LINE__ ) +#endif +#if defined(EXT_AUX_TX1_D3) && EXT_AUX_TX1_D3 >= 0 + REPORT_NAME_DIGITAL(EXT_AUX_TX1_D3, __LINE__ ) +#endif +#if defined(EXTRUDER_0_AUTO_FAN) && EXTRUDER_0_AUTO_FAN >= 0 + REPORT_NAME_DIGITAL(EXTRUDER_0_AUTO_FAN, __LINE__ ) +#endif +#if defined(EXTRUDER_1_AUTO_FAN) && EXTRUDER_1_AUTO_FAN >= 0 + REPORT_NAME_DIGITAL(EXTRUDER_1_AUTO_FAN, __LINE__ ) +#endif +#if PIN_EXISTS(FAN) + REPORT_NAME_DIGITAL(FAN_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(FAN1) + REPORT_NAME_DIGITAL(FAN1_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(FAN2) + REPORT_NAME_DIGITAL(FAN2_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(FIL_RUNOUT) + REPORT_NAME_DIGITAL(FIL_RUNOUT_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(FILWIDTH) && FILWIDTH_PIN < NUM_ANALOG_INPUTS + REPORT_NAME_ANALOG(FILWIDTH_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(HEATER_0) + REPORT_NAME_DIGITAL(HEATER_0_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(HEATER_1) + REPORT_NAME_DIGITAL(HEATER_1_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(HEATER_2) + REPORT_NAME_DIGITAL(HEATER_2_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(HEATER_3) + REPORT_NAME_DIGITAL(HEATER_3_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(HEATER_4) + REPORT_NAME_DIGITAL(HEATER_4_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(HEATER_5) + REPORT_NAME_DIGITAL(HEATER_5_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(HEATER_6) + REPORT_NAME_DIGITAL(HEATER_6_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(HEATER_7) + REPORT_NAME_DIGITAL(HEATER_7_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(HEATER_BED) + REPORT_NAME_DIGITAL(HEATER_BED_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(HOME) + REPORT_NAME_DIGITAL(HOME_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(I2C_SCL) + REPORT_NAME_DIGITAL(I2C_SCL_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(I2C_SDA) + REPORT_NAME_DIGITAL(I2C_SDA_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(KILL) + REPORT_NAME_DIGITAL(KILL_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(LCD_BACKLIGHT) + REPORT_NAME_DIGITAL(LCD_BACKLIGHT_PIN, __LINE__ ) +#endif +#if defined(LCD_CONTRAST) && LCD_CONTRAST >= 0 + REPORT_NAME_DIGITAL(LCD_CONTRAST, __LINE__ ) +#endif +#if defined(LCD_PINS_D4) && LCD_PINS_D4 >= 0 + REPORT_NAME_DIGITAL(LCD_PINS_D4, __LINE__ ) +#endif +#if defined(LCD_PINS_D5) && LCD_PINS_D5 >= 0 + REPORT_NAME_DIGITAL(LCD_PINS_D5, __LINE__ ) +#endif +#if defined(LCD_PINS_D6) && LCD_PINS_D6 >= 0 + REPORT_NAME_DIGITAL(LCD_PINS_D6, __LINE__ ) +#endif +#if defined(LCD_PINS_D7) && LCD_PINS_D7 >= 0 + REPORT_NAME_DIGITAL(LCD_PINS_D7, __LINE__ ) +#endif +#if defined(LCD_PINS_ENABLE) && LCD_PINS_ENABLE >= 0 + REPORT_NAME_DIGITAL(LCD_PINS_ENABLE, __LINE__ ) +#endif +#if defined(LCD_PINS_RS) && LCD_PINS_RS >= 0 + REPORT_NAME_DIGITAL(LCD_PINS_RS, __LINE__ ) +#endif +#if defined(LCD_SDSS) && LCD_SDSS >= 0 + REPORT_NAME_DIGITAL(LCD_SDSS, __LINE__ ) +#endif +#if PIN_EXISTS(LED) + REPORT_NAME_DIGITAL(LED_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(MAIN_VOLTAGE_MEASURE) && MAIN_VOLTAGE_MEASURE_PIN < NUM_ANALOG_INPUTS + REPORT_NAME_ANALOG(MAIN_VOLTAGE_MEASURE_PIN, __LINE__ ) +#endif +#if defined(MAX6675_SS) && MAX6675_SS >= 0 + REPORT_NAME_DIGITAL(MAX6675_SS, __LINE__ ) +#endif +#if PIN_EXISTS(MISO) + REPORT_NAME_DIGITAL(MISO_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(MOSFET_A) + REPORT_NAME_DIGITAL(MOSFET_A_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(MOSFET_B) + REPORT_NAME_DIGITAL(MOSFET_B_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(MOSFET_C) + REPORT_NAME_DIGITAL(MOSFET_C_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(MOSFET_D) + REPORT_NAME_DIGITAL(MOSFET_D_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(MOSI) + REPORT_NAME_DIGITAL(MOSI_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(MOTOR_CURRENT_PWM_E) + REPORT_NAME_DIGITAL(MOTOR_CURRENT_PWM_E_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(MOTOR_CURRENT_PWM_XY) + REPORT_NAME_DIGITAL(MOTOR_CURRENT_PWM_XY_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(MOTOR_CURRENT_PWM_Z) + REPORT_NAME_DIGITAL(MOTOR_CURRENT_PWM_Z_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(ORIG_E0_AUTO_FAN) + REPORT_NAME_DIGITAL(ORIG_E0_AUTO_FAN_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(ORIG_E1_AUTO_FAN) + REPORT_NAME_DIGITAL(ORIG_E1_AUTO_FAN_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(ORIG_E2_AUTO_FAN) + REPORT_NAME_DIGITAL(ORIG_E2_AUTO_FAN_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(ORIG_E3_AUTO_FAN) + REPORT_NAME_DIGITAL(ORIG_E3_AUTO_FAN_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(ORIG_E4_AUTO_FAN) + REPORT_NAME_DIGITAL(ORIG_E4_AUTO_FAN_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(PHOTOGRAPH) + REPORT_NAME_DIGITAL(PHOTOGRAPH_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(PS_ON) + REPORT_NAME_DIGITAL(PS_ON_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(PWM_1) + REPORT_NAME_DIGITAL(PWM_1_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(PWM_2) + REPORT_NAME_DIGITAL(PWM_2_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(RAMPS_D10) + REPORT_NAME_DIGITAL(RAMPS_D10_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(RAMPS_D8) + REPORT_NAME_DIGITAL(RAMPS_D8_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(RAMPS_D9) + REPORT_NAME_DIGITAL(RAMPS_D9_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(RGB_LED_R) + REPORT_NAME_DIGITAL(RGB_LED_R_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(RGB_LED_G) + REPORT_NAME_DIGITAL(RGB_LED_G_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(RGB_LED_B) + REPORT_NAME_DIGITAL(RGB_LED_B_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(RGB_LED_W) + REPORT_NAME_DIGITAL(RGB_LED_W_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(RX_ENABLE) + REPORT_NAME_DIGITAL(RX_ENABLE_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(SAFETY_TRIGGERED) + REPORT_NAME_DIGITAL(SAFETY_TRIGGERED_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(SCK) + REPORT_NAME_DIGITAL(SCK_PIN, __LINE__ ) +#endif +#if defined(SCL) && SCL >= 0 + REPORT_NAME_DIGITAL(SCL, __LINE__ ) +#endif +#if PIN_EXISTS(SD_DETECT) + REPORT_NAME_DIGITAL(SD_DETECT_PIN, __LINE__ ) +#endif +#if defined(SDA) && SDA >= 0 + REPORT_NAME_DIGITAL(SDA, __LINE__ ) +#endif +#if defined(SDPOWER) && SDPOWER >= 0 + REPORT_NAME_DIGITAL(SDPOWER, __LINE__ ) +#endif +#if defined(SDSS) && SDSS >= 0 + REPORT_NAME_DIGITAL(SDSS, __LINE__ ) +#endif +#if PIN_EXISTS(SERVO0) + REPORT_NAME_DIGITAL(SERVO0_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(SERVO1) + REPORT_NAME_DIGITAL(SERVO1_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(SERVO2) + REPORT_NAME_DIGITAL(SERVO2_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(SERVO3) + REPORT_NAME_DIGITAL(SERVO3_PIN, __LINE__ ) +#endif +#if defined(SHIFT_CLK) && SHIFT_CLK >= 0 + REPORT_NAME_DIGITAL(SHIFT_CLK, __LINE__ ) +#endif +#if defined(SHIFT_EN) && SHIFT_EN >= 0 + REPORT_NAME_DIGITAL(SHIFT_EN, __LINE__ ) +#endif +#if defined(SHIFT_LD) && SHIFT_LD >= 0 + REPORT_NAME_DIGITAL(SHIFT_LD, __LINE__ ) +#endif +#if defined(SHIFT_OUT) && SHIFT_OUT >= 0 + REPORT_NAME_DIGITAL(SHIFT_OUT, __LINE__ ) +#endif +#if PIN_EXISTS(SLED) + REPORT_NAME_DIGITAL(SLED_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(SLEEP_WAKE) + REPORT_NAME_DIGITAL(SLEEP_WAKE_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(SOL0) + REPORT_NAME_DIGITAL(SOL0_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(SOL1) + REPORT_NAME_DIGITAL(SOL1_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(SOL2) + REPORT_NAME_DIGITAL(SOL2_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(SOL3) + REPORT_NAME_DIGITAL(SOL3_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(SOL4) + REPORT_NAME_DIGITAL(SOL4_PIN, __LINE__ ) +#endif +#if defined(SPARE_IO) && SPARE_IO >= 0 + REPORT_NAME_DIGITAL(SPARE_IO, __LINE__ ) +#endif +#if PIN_EXISTS(SPINDLE_DIR) + REPORT_NAME_DIGITAL(SPINDLE_DIR_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(SPINDLE_LASER_ENABLE) + REPORT_NAME_DIGITAL(SPINDLE_LASER_ENABLE_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(SPINDLE_LASER_PWM) + REPORT_NAME_DIGITAL(SPINDLE_LASER_PWM_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(SR_CLK) + REPORT_NAME_DIGITAL(SR_CLK_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(SR_DATA) + REPORT_NAME_DIGITAL(SR_DATA_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(SR_STROBE) + REPORT_NAME_DIGITAL(SR_STROBE_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(SS) + REPORT_NAME_DIGITAL(SS_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(STAT_LED_BLUE) + REPORT_NAME_DIGITAL(STAT_LED_BLUE_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(STAT_LED_RED) + REPORT_NAME_DIGITAL(STAT_LED_RED_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(STEPPER_RESET) + REPORT_NAME_DIGITAL(STEPPER_RESET_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(SUICIDE) + REPORT_NAME_DIGITAL(SUICIDE_PIN, __LINE__ ) +#endif +#if defined(TC1) && TC1 >= 0 && TC1 < NUM_ANALOG_INPUTS + REPORT_NAME_ANALOG(TC1, __LINE__ ) +#endif +#if defined(TC2) && TC2 >= 0 && TC2 < NUM_ANALOG_INPUTS + REPORT_NAME_ANALOG(TC2, __LINE__ ) +#endif +#if PIN_EXISTS(TEMP_0) && TEMP_0_PIN < NUM_ANALOG_INPUTS + REPORT_NAME_ANALOG(TEMP_0_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(TEMP_1) && TEMP_1_PIN < NUM_ANALOG_INPUTS + REPORT_NAME_ANALOG(TEMP_1_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(TEMP_2) && TEMP_2_PIN < NUM_ANALOG_INPUTS + REPORT_NAME_ANALOG(TEMP_2_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(TEMP_3) && TEMP_3_PIN < NUM_ANALOG_INPUTS + REPORT_NAME_ANALOG(TEMP_3_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(TEMP_4) && TEMP_4_PIN < NUM_ANALOG_INPUTS + REPORT_NAME_ANALOG(TEMP_4_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(TEMP_BED) && TEMP_BED_PIN < NUM_ANALOG_INPUTS + REPORT_NAME_ANALOG(TEMP_BED_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(TEMP_CHAMBER) && TEMP_CHAMBER_PIN < NUM_ANALOG_INPUTS + REPORT_NAME_ANALOG(TEMP_CHAMBER_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(TEMP_X) && TEMP_X_PIN < NUM_ANALOG_INPUTS + REPORT_NAME_ANALOG(TEMP_X_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(THERMO_DO) + REPORT_NAME_DIGITAL(THERMO_DO_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(THERMO_SCK) + REPORT_NAME_DIGITAL(THERMO_SCK_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(TLC_BLANK) + REPORT_NAME_DIGITAL(TLC_BLANK_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(TLC_CLOCK) + REPORT_NAME_DIGITAL(TLC_CLOCK_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(TLC_DATA) + REPORT_NAME_DIGITAL(TLC_DATA_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(TLC_XLAT) + REPORT_NAME_DIGITAL(TLC_XLAT_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(TOOL_0) + REPORT_NAME_DIGITAL(TOOL_0_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(TOOL_0_PWM) + REPORT_NAME_DIGITAL(TOOL_0_PWM_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(TOOL_1) + REPORT_NAME_DIGITAL(TOOL_1_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(TOOL_1_PWM) + REPORT_NAME_DIGITAL(TOOL_1_PWM_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(TOOL_2) + REPORT_NAME_DIGITAL(TOOL_2_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(TOOL_2_PWM) + REPORT_NAME_DIGITAL(TOOL_2_PWM_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(TOOL_3) + REPORT_NAME_DIGITAL(TOOL_3_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(TOOL_3_PWM) + REPORT_NAME_DIGITAL(TOOL_3_PWM_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(TOOL_PWM) + REPORT_NAME_DIGITAL(TOOL_PWM_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(TX_ENABLE) + REPORT_NAME_DIGITAL(TX_ENABLE_PIN, __LINE__ ) +#endif +#if defined(UI1) && UI1 >= 0 + REPORT_NAME_DIGITAL(UI1, __LINE__ ) +#endif +#if defined(UI2) && UI2 >= 0 + REPORT_NAME_DIGITAL(UI2, __LINE__ ) +#endif +#if defined(UNUSED_PWM) && UNUSED_PWM >= 0 + REPORT_NAME_DIGITAL(UNUSED_PWM, __LINE__ ) +#endif +#if PIN_EXISTS(X_ATT) + REPORT_NAME_DIGITAL(X_ATT_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(X_CS) + REPORT_NAME_DIGITAL(X_CS_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(X_DIR) + REPORT_NAME_DIGITAL(X_DIR_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(X_ENABLE) + REPORT_NAME_DIGITAL(X_ENABLE_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(X_MAX) + REPORT_NAME_DIGITAL(X_MAX_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(X_MIN) + REPORT_NAME_DIGITAL(X_MIN_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(X_MS1) + REPORT_NAME_DIGITAL(X_MS1_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(X_MS2) + REPORT_NAME_DIGITAL(X_MS2_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(X_STEP) + REPORT_NAME_DIGITAL(X_STEP_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(X_STOP) + REPORT_NAME_DIGITAL(X_STOP_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(X2_DIR) + REPORT_NAME_DIGITAL(X2_DIR_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(X2_ENABLE) + REPORT_NAME_DIGITAL(X2_ENABLE_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(X2_STEP) + REPORT_NAME_DIGITAL(X2_STEP_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(Y_ATT) + REPORT_NAME_DIGITAL(Y_ATT_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(Y_CS) + REPORT_NAME_DIGITAL(Y_CS_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(Y_DIR) + REPORT_NAME_DIGITAL(Y_DIR_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(Y_ENABLE) + REPORT_NAME_DIGITAL(Y_ENABLE_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(Y_MAX) + REPORT_NAME_DIGITAL(Y_MAX_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(Y_MIN) + REPORT_NAME_DIGITAL(Y_MIN_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(Y_MS1) + REPORT_NAME_DIGITAL(Y_MS1_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(Y_MS2) + REPORT_NAME_DIGITAL(Y_MS2_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(Y_STEP) + REPORT_NAME_DIGITAL(Y_STEP_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(Y_STOP) + REPORT_NAME_DIGITAL(Y_STOP_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(Y2_DIR) + REPORT_NAME_DIGITAL(Y2_DIR_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(Y2_ENABLE) + REPORT_NAME_DIGITAL(Y2_ENABLE_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(Y2_STEP) + REPORT_NAME_DIGITAL(Y2_STEP_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(Z_ATT) + REPORT_NAME_DIGITAL(Z_ATT_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(Z_CS) + REPORT_NAME_DIGITAL(Z_CS_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(Z_DIR) + REPORT_NAME_DIGITAL(Z_DIR_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(Z_ENABLE) + REPORT_NAME_DIGITAL(Z_ENABLE_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(Z_MAX) + REPORT_NAME_DIGITAL(Z_MAX_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(Z_MIN) + REPORT_NAME_DIGITAL(Z_MIN_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(Z_MIN_PROBE) + REPORT_NAME_DIGITAL(Z_MIN_PROBE_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(Z_MS1) + REPORT_NAME_DIGITAL(Z_MS1_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(Z_MS2) + REPORT_NAME_DIGITAL(Z_MS2_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(Z_STEP) + REPORT_NAME_DIGITAL(Z_STEP_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(Z_STOP) + REPORT_NAME_DIGITAL(Z_STOP_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(Z2_DIR) + REPORT_NAME_DIGITAL(Z2_DIR_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(Z2_ENABLE) + REPORT_NAME_DIGITAL(Z2_ENABLE_PIN, __LINE__ ) +#endif +#if PIN_EXISTS(Z2_STEP) + REPORT_NAME_DIGITAL(Z2_STEP_PIN, __LINE__ ) +#endif + diff --git a/trunk/Arduino/Marlin_1.1.6/pinsDebug_plus_70.h b/trunk/Arduino/Marlin_1.1.6/pinsDebug_plus_70.h new file mode 100644 index 00000000..1a905bd4 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pinsDebug_plus_70.h @@ -0,0 +1,341 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2017 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * 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 . + * + */ + +/** + * structurs for 2560 family boards that use morre than 70 pins + */ + +#ifndef __PINSDEBUG_PLUS_70_H__ +#define __PINSDEBUG_PLUS_70_H__ + +#undef NUM_DIGITAL_PINS +#if MOTHERBOARD == BOARD_BQ_ZUM_MEGA_3D + #define NUM_DIGITAL_PINS 85 +#elif MOTHERBOARD == BOARD_MIGHTYBOARD_REVE + #define NUM_DIGITAL_PINS 80 +#elif MOTHERBOARD == BOARD_MINIRAMBO + #define NUM_DIGITAL_PINS 85 +#elif MOTHERBOARD == BOARD_SCOOVO_X9H + #define NUM_DIGITAL_PINS 85 +#endif + +#define PA 1 +#define PB 2 +#define PC 3 +#define PD 4 +#define PE 5 +#define PF 6 +#define PG 7 +#define PH 8 +#define PJ 10 +#define PK 11 +#define PL 12 + +const uint8_t PROGMEM digital_pin_to_port_PGM_plus_70[] = { + // 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 ** + PG , // PG 3 ** 71 ** + PJ , // PJ 2 ** 72 ** + PJ , // PJ 3 ** 73 ** + PJ , // PJ 7 ** 74 ** + PJ , // PJ 4 ** 75 ** + PJ , // PJ 5 ** 76 ** + PJ , // PJ 6 ** 77 ** + PE , // PE 2 ** 78 ** + PE , // PE 6 ** 79 ** + PE , // PE 7 ** 80 ** + PD , // PD 4 ** 81 ** + PD , // PD 5 ** 82 ** + PD , // PD 6 ** 83 ** + PH , // PH 2 ** 84 ** + PH , // PH 7 ** 85 ** +}; + +#define digitalPinToPort_plus_70(P) ( pgm_read_byte( digital_pin_to_port_PGM_plus_70 + (P) ) ) + +const uint8_t PROGMEM digital_pin_to_bit_mask_PGM_plus_70[] = { + // 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 ** + _BV( 3 ) , // PG 3 ** 71 ** + _BV( 2 ) , // PJ 2 ** 72 ** + _BV( 3 ) , // PJ 3 ** 73 ** + _BV( 7 ) , // PJ 7 ** 74 ** + _BV( 4 ) , // PJ 4 ** 75 ** + _BV( 5 ) , // PJ 5 ** 76 ** + _BV( 6 ) , // PJ 6 ** 77 ** + _BV( 2 ) , // PE 2 ** 78 ** + _BV( 6 ) , // PE 6 ** 79 ** + _BV( 7 ) , // PE 7 ** 80 ** + _BV( 4 ) , // PD 4 ** 81 ** + _BV( 5 ) , // PD 5 ** 82 ** + _BV( 6 ) , // PD 6 ** 83 ** + _BV( 2 ) , // PH 2 ** 84 ** + _BV( 7 ) , // PH 7 ** 85 ** +}; + +#define digitalPinToBitMask_plus_70(P) ( pgm_read_byte( digital_pin_to_bit_mask_PGM_plus_70 + (P) ) ) + + +const uint8_t PROGMEM digital_pin_to_timer_PGM_plus_70[] = { + // 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 ** + NOT_ON_TIMER , // PG 3 ** 71 ** + NOT_ON_TIMER , // PJ 2 ** 72 ** + NOT_ON_TIMER , // PJ 3 ** 73 ** + NOT_ON_TIMER , // PJ 7 ** 74 ** + NOT_ON_TIMER , // PJ 4 ** 75 ** + NOT_ON_TIMER , // PJ 5 ** 76 ** + NOT_ON_TIMER , // PJ 6 ** 77 ** + NOT_ON_TIMER , // PE 2 ** 78 ** + NOT_ON_TIMER , // PE 6 ** 79 ** +}; + +#define digitalPinToTimer_plus_70(P) ( pgm_read_byte( digital_pin_to_timer_PGM_plus_70 + (P) ) ) + +/** + * Interrupts that are not implemented + * + * INT6 E6 79 + * INT7 E7 80 + * PCINT11 J2 72 + * PCINT12 J3 73 + * PCINT13 J4 75 + * PCINT14 J5 76 + * PCINT15 J6 77 + */ + + +#endif // __PINSDEBUG_PLUS_70_H__ diff --git a/trunk/Arduino/Marlin_1.1.6/pins_3DRAG.h b/trunk/Arduino/Marlin_1.1.6/pins_3DRAG.h new file mode 100644 index 00000000..feadea4e --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_3DRAG.h @@ -0,0 +1,163 @@ +/** + * 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 . + * + */ + +/** + * 3DRAG (and K8200 / K8400) Arduino Mega with RAMPS v1.4 pin assignments + */ + +#ifndef BOARD_NAME + #define BOARD_NAME "3Drag" +#endif + +#ifndef DEFAULT_MACHINE_NAME + #define DEFAULT_MACHINE_NAME "3Drag" +#endif + +#ifndef DEFAULT_SOURCE_CODE_URL + #define DEFAULT_SOURCE_CODE_URL "http://3dprint.elettronicain.it/" +#endif + +// +// Heaters / Fans +// +#define RAMPS_D8_PIN 9 +#define RAMPS_D9_PIN 8 +#define MOSFET_D_PIN 12 + +#define CASE_LIGHT_PIN -1 // MUST BE HARDWARE PWM but one is not available on expansion header + +#include "pins_RAMPS.h" + +// +// Limit Switches +// +#undef Z_MAX_PIN +#define Z_MAX_PIN -1 + +// +// Steppers +// +#undef Z_ENABLE_PIN +#define Z_ENABLE_PIN 63 + +// +// Heaters / Fans +// +#define HEATER_2_PIN 6 + +// +// Misc. Functions +// +#undef SDSS +#define SDSS 25 + +#undef SD_DETECT_PIN +#define SD_DETECT_PIN 53 + +// +// LCD / Controller +// +#if ENABLED(ULTRA_LCD) && ENABLED(NEWPANEL) + #undef BEEPER_PIN + #define BEEPER_PIN -1 + + #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 16 + #define BTN_EN2 17 + #define BTN_ENC 23 + +#else + + #define BEEPER_PIN 33 + +#endif // ULTRA_LCD && NEWPANEL + +/** + * M3/M4/M5 - Spindle/Laser Control + * + * If you want to control the speed of your spindle then you'll have + * have to sacrifce the Extruder and pull some signals off the Z stepper + * driver socket. + * + * The following assumes: + * - the Z stepper driver socket is empty + * - the extruder driver socket has a driver board plugged into it + * - the Z stepper wires are attached the the extruder connector + * + * If you want to keep the extruder AND don't have a LCD display then + * you can still control the power on/off and spindle direction. + * + * Where to get spindle signals + * + * stepper signal socket name socket name + * ------- + * SPINDLE_LASER_ENABLE_PIN /ENABLE O| |O VMOT + * MS1 O| |O GND + * MS2 O| |O 2B + * MS3 O| |O 2A + * /RESET O| |O 1A + * /SLEEP O| |O 1B + * SPINDLE_LASER_PWM_PIN STEP O| |O VDD + * SPINDLE_DIR_PIN DIR O| |O GND + * ------- + * + * 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_ENABLE_PIN +#undef SPINDLE_DIR_PIN + +#if ENABLED(SPINDLE_LASER_ENABLE) + #if !EXTRUDERS + #undef E0_DIR_PIN + #undef E0_ENABLE_PIN + #undef E0_STEP_PIN + #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 // MUST BE HARDWARE PWM + #define SPINDLE_LASER_ENABLE_PIN 62 // Pin should have a pullup! + #define SPINDLE_DIR_PIN 48 + #elif !(ENABLED(ULTRA_LCD) && ENABLED(NEWPANEL)) // use expansion header if no LCD in use + #define SPINDLE_LASER_ENABLE_PIN 16 // Pin should have a pullup/pulldown! + #define SPINDLE_DIR_PIN 17 + #endif +#endif diff --git a/trunk/Arduino/Marlin_1.1.6/pins_5DPRINT.h b/trunk/Arduino/Marlin_1.1.6/pins_5DPRINT.h new file mode 100644 index 00000000..e99047f6 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_5DPRINT.h @@ -0,0 +1,132 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2017 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** + * Rev B 2 JUN 2017 + * + * Converted to Arduino pin numbering + */ + +/** + * 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 + * Select Teensy++ 2.0 in Arduino IDE from the 'Tools -> Boards' menu + * + * Installation instructions are at the above URL. Don't bother loading the + * libraries - they are not used with the Marlin software. + * + * Printrboard - https://github.com/scwimbush/Printrboard-HID-Arduino-IDE-Support + * + * Installation: + * + * 1. Go to the above URL, click on the "Clone or Download" button and then + * click on "Download ZIP" button. + * 2. Unzip the file, find the "printrboard" directory and then copy it to the + * hardware directory in Arduino. The Arduino hardware directory will probably + * be located in a path similar to this: C:\Program Files (x86)\Arduino\hardware. + * 3. Restart Arduino. + * 4. Select "Printrboard" from the 'Tools -> Boards' menu. + * + * Teensyduino is the most popular option. Printrboard is used if your board doesn't have + * the Teensyduino bootloader on it. + */ + +/** + * To burn the bootloader that comes with Printrboard: + * + * 1. Connect your programmer to the board. + * 2. In the Arduino IDE select "Printrboard" and then select the programmer. + * 3. In the Arduino IDE click on "burn bootloader". Don't worry about the "verify failed at 1F000" error message. + * 4. The programmer is no longer needed. Remove it. + */ + +/** + * 5DPrint D8 Driver board pin assignments + * + * https://bitbucket.org/makible/5dprint-d8-controller-board + */ + +#ifndef __AVR_AT90USB1286__ + #error "Oops! Make sure you have 'Teensy++ 2.0' or 'Printrboard' selected from the 'Tools -> Boards' menu." +#endif + +#define DEFAULT_MACHINE_NAME "Makibox" +#define BOARD_NAME "5DPrint D8" + +#define LARGE_FLASH true + +// +// Limit Switches +// +#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 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 E0_STEP_PIN 34 // A6 +#define E0_DIR_PIN 35 // A7 +#define E0_ENABLE_PIN 11 // C1 + + +#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 + +// +// Heaters / Fans +// +#define HEATER_0_PIN 15 // C5 +#define HEATER_BED_PIN 14 // C4 + +#define FAN_PIN 16 // C6 PWM3A + +// +// Misc. Functions +// +#define SDSS 20 // B0 diff --git a/trunk/Arduino/Marlin_1.1.6/pins_ANET_10.h b/trunk/Arduino/Marlin_1.1.6/pins_ANET_10.h new file mode 100644 index 00000000..8668681b --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_ANET_10.h @@ -0,0 +1,270 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2017 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** + * Anet V1.0 board pin assignments + */ + +/** + * Rev B 16 JUN 2017 + * + * 1) no longer uses Sanguino files to define some of the pins + * 2) added pointers to useable Arduino IDE extensions + * + */ + +/** + * The standard Arduino IDE extension (board manager) for this board + * is located at https://github.com/SkyNet3D/anet-board. + * + * Installation instructions are on that page. + * + * After copying the files to the appropriate location, restart Arduino and + * you'll see "Anet V1.0" and "Anet V1.0 (Optiboot)" in the boards list. + * + * "Anet V1.0" uses the bootloader that was installed on the board when + * it shipped from the factory. + * + * "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. + * + */ + +/** + * Another usable Arduino IDE extension (board manager) can be found at + * https://github.com/Lauszus/Sanguino + * + * This extension has been tested on Arduino 1.6.12 & 1.8.0 + * + * Here's the JSON path: + * https://raw.githubusercontent.com/Lauszus/Sanguino/master/package_lauszus_sanguino_index.json + * + * When installing select 1.0.2 + * + * Installation instructions can be found at https://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. + * + */ + +/** + * To burn a new bootloader: + * + * 1. Connect your programmer to the board. + * 2. In the Arduino IDE select the board and then select the programmer. + * 3. In the Arduino IDE click on "burn bootloader". Don't worry about the "verify failed at 1F000" error message. + * 4. The programmer is no longer needed. Remove it. + */ + +/** + * Additional info: + * + * Anet Schematics - https://github.com/ralf-e/ANET-3D-Board-V1.0 + * Wiring RRDFG Smart Controller - http://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. +*/ + +#if !defined(__AVR_ATmega1284P__) + #error "Oops! Make sure you have 'Anet V1.0', 'Anet V1.0 (Optiboot)' or 'Sanguino' selected from the 'Tools -> Boards' menu." +#endif + +#ifndef BOARD_NAME + #define BOARD_NAME "Anet" +#endif + +#define LARGE_FLASH true + +// +// Limit Switches +// +#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 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 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) + +// +// Heaters / Fans +// +#define HEATER_0_PIN 13 // (extruder) +#define HEATER_BED_PIN 12 // (bed) +#define FAN_PIN 4 + +// +// Misc. Functions +// +#define SDSS 31 +#define LED_PIN -1 + +/** + * LCD / Controller + * + * Only the following displays are supported: + * ANET_KEYPAD_LCD + * ANET_FULL_GRAPHICS_LCD + * REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER +*/ + +#if ENABLED(ULTRA_LCD) && ENABLED(NEWPANEL) + #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 BTN_EN1 -1 + #define BTN_EN2 -1 + #define BTN_ENC -1 + #define ADC_KEYPAD_PIN 1 + #define ENCODER_FEEDRATE_DEADZONE 2 + #elif ENABLED(REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER) || ENABLED(ANET_FULL_GRAPHICS_LCD) + // 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 ST7920_DELAY_1 DELAY_0_NOP + #define ST7920_DELAY_2 DELAY_1_NOP + #define ST7920_DELAY_3 DELAY_2_NOP + #define STD_ENCODER_PULSES_PER_STEP 4 + #define STD_ENCODER_STEPS_PER_MENU_ITEM 1 + #endif +#endif // ULTRA_LCD && NEWPANEL + +/** + * ==================================================================== + * =============== Alternative RepRapDiscount Wiring ================== + * ==================================================================== + * + * An alternative wiring scheme for the RepRapDiscount Full Graphics Display is + * published by oderwat on Thingiverse at https://www.thingiverse.com/thing:2103748. + * + * Using that adapter requires changing the pin definition as follows: + * #define SERVO0_PIN 27 // free for BLTouch/3D-Touch + * #define BEEPER_PIN 28 + * #define LCD_PINS_RS 30 + * #define LCD_PINS_ENABLE 29 + * #define LCD_PINS_D4 17 + * + * The BLTouch pin becomes LCD:3 + */ + +/** + * ==================================================================== + * ===================== LCD PINOUTS ================================== + * ==================================================================== + * + * Anet V1.0 controller | ANET_KEYPAD_LCD | ANET_FULL_ | RepRapDiscount Full | Thingiverse RepRap wiring + * physical logical alt | | GRAPHICS_LCD | Graphics Display Wiring | http://www.thingiverse + * pin pin functions | | | | .com/thing:2103748 + *------------------------------------------------------------------------------------------------------------------------ + * ANET-J3.1 8 *** | N/A | J3_TX *** | | + * ANET-J3.2 9 *** | N/A | J3_RX *** | | + * ANET-J3.3 6 MISO | N/A | MISO *** | EXP2.1 MISO | EXP2.1 MISO + * ANET-J3.4 +5V | N/A | +5V | | + * ANET-J3.5 7 SCK | N/A | SCK *** | EXP2.2 SCK | EXP2.2 SCK + * ANET-J3.6 5 MOSI | N/A | MOSI *** | EXP2.6 MOSI | EXP2.6 MOSI + * ANET-J3.7 !RESET | N/A | button | EXP2.8 panel button | EXP2.8 panel button + * ANET-J3.8 GND | N/A | GND | EXP2.9 GND | EXP2.9 GND + * ANET-J3.9 4 Don't use | N/A | N/C | | + * ANET-J3.10 +3.3V | N/A | +3.3V *** | | + * | | | | + * | | | | + * ANET-LCD.1 GND | GND | GND | EXP1.9 GND | EXP1.9 GND + * ANET-LCD.2 +5V | +5V | +5V | EXP1.10 +5V | EXP1.10 +5V + * ANET-LCD.3 27 A4 | N/C * | LCD_PINS_RS | EXP1.4 LCD_PINS_RS | EXP2.4 SDSS or N/C * + * ANET-LCD.4 10 | LCD_PINS_D4 | BTN_EN2 | EXP2.3 BTN_EN2 | EXP2.3 BTN_EN2 + * ANET-LCD.5 28 A3 | LCD_PINS_RS | LCD_PINS_ENABLE | EXP1.3 LCD_PINS_ENABLE | EXP1.1 BEEPER_PIN + * ANET-LCD.6 11 | LCD_PINS_D5 | BTN_EN1 | EXP2.5 BTN_EN1 | EXP2.5 BTN_EN1 + * ANET-LCD.7 29 A2 | LCD_PINS_ENABLE | N/C * | EXP2.4 SDSS or N/C * | EXP1.3 LCD_PINS_ENABLE + * ANET-LCD.8 16 SCL | LCD_PINS_D6 | BTN_ENC | EXP1.2 BTN_ENC | EXP1.2 BTN_ENC + * ANET-LCD.9 30 A1 | ADC_KEYPAD_PIN ** | LCD_PINS_D4 | EXP1.5 LCD_PINS_D4 | EXP1.4 LCD_PINS_RS + * ANET-LCD.10 17 SDA | LCD_PINS_D7 | BEEPER_PIN | EXP1.1 BEEPER_PIN | EXP1.5 LCD_PINS_D4 + * + * N/C * - if not connected to the LCD can be used for BLTouch servo input + * ** - analog pin -WITHOUT a pullup + * *** - only connected to something if the Bluetooth module is populated + */ + +/** + * REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER + * physical pin function + * EXP1.1 BEEPER + * EXP1.2 BTN_ENC + * EXP1.3 LCD_PINS_ENABLE + * EXP1.4 LCD_PINS_RS + * EXP1.5 LCD_PINS_D4 + * EXP1.6 LCD_PINS_D5 (not used) + * EXP1.7 LCD_PINS_D6 (not used) + * EXP1.8 LCD_PINS_D7 (not used) + * EXP1.9 GND + * EXP1.10 VCC + * + * + * EXP2.1 MISO + * EXP2.2 SCK + * EXP2.3 BTN_EN2 + * EXP2.4 SDSS + * EXP2.5 BTN_EN1 + * EXP2.6 MOSI + * EXP2.7 SD_DETECT_PIN + * EXP2.8 button + * EXP2.9 GND + * EXP2.10 NC + */ diff --git a/trunk/Arduino/Marlin_1.1.6/pins_AZTEEG_X1.h b/trunk/Arduino/Marlin_1.1.6/pins_AZTEEG_X1.h new file mode 100644 index 00000000..17290d11 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_AZTEEG_X1.h @@ -0,0 +1,29 @@ +/** + * 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 . + * + */ + +/** + * Azteeg X1 pin assignments + */ + +#define BOARD_NAME "Azteeg X1" + +#include "pins_SANGUINOLOLU_12.h" diff --git a/trunk/Arduino/Marlin_1.1.6/pins_AZTEEG_X3.h b/trunk/Arduino/Marlin_1.1.6/pins_AZTEEG_X3.h new file mode 100644 index 00000000..86ccbd92 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_AZTEEG_X3.h @@ -0,0 +1,99 @@ +/** + * 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 . + * + */ + +/** + * AZTEEG_X3 Arduino Mega with RAMPS v1.4 pin assignments + */ + +#ifndef __AVR_ATmega2560__ + #error "Oops! Make sure you have 'Arduino Mega 2560' selected from the 'Tools -> Boards' menu." +#endif + +#if 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 // must define it here or else RAMPS will define it +#endif +#define BOARD_NAME "Azteeg X3" + +#include "pins_RAMPS_13.h" + +// +// Servos +// +#undef SERVO0_PIN +#undef SERVO1_PIN +#define SERVO0_PIN 44 // SERVO1 port +#define SERVO1_PIN 55 // SERVO2 port + +// +// LCD / Controller +// +#undef STAT_LED_RED_PIN +#undef STAT_LED_BLUE_PIN + +#if ENABLED(VIKI2) || ENABLED(miniVIKI) + + #undef DOGLCD_A0 + #undef DOGLCD_CS + #undef BTN_ENC + #define DOGLCD_A0 31 + #define DOGLCD_CS 32 + #define BTN_ENC 12 + + #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 + +#endif + +// +// Misc +// +#if ENABLED(CASE_LIGHT_ENABLE) && PIN_EXISTS(CASE_LIGHT) && PIN_EXISTS(STAT_LED_RED) && STAT_LED_RED_PIN == CASE_LIGHT_PIN + #undef STAT_LED_RED_PIN +#endif + +// +// 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_ENABLE_PIN +#undef SPINDLE_DIR_PIN + +#if ENABLED(SPINDLE_LASER_ENABLE) + #undef SDA // use EXP3 header + #undef SCL + #if SERVO0_PIN == 7 + #undef SERVO0_PIN + #def SERVO0_PIN 11 + #endif + #define SPINDLE_LASER_PWM_PIN 7 // MUST BE HARDWARE PWM + #define SPINDLE_LASER_ENABLE_PIN 20 // Pin should have a pullup! + #define SPINDLE_DIR_PIN 21 +#endif diff --git a/trunk/Arduino/Marlin_1.1.6/pins_AZTEEG_X3_PRO.h b/trunk/Arduino/Marlin_1.1.6/pins_AZTEEG_X3_PRO.h new file mode 100644 index 00000000..0e76a2a2 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_AZTEEG_X3_PRO.h @@ -0,0 +1,170 @@ +/** + * 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 . + * + */ + +/** + * AZTEEG_X3_PRO (Arduino Mega) pin assignments + */ + +#if HOTENDS > 5 || E_STEPPERS > 5 + #error "Azteeg X3 Pro supports up to 5 hotends / E-steppers. Comment out this line to continue." +#endif + +#if ENABLED(CASE_LIGHT_ENABLE) && !PIN_EXISTS(CASE_LIGHT) + #define CASE_LIGHT_PIN 44 // must define it here or else RAMPS will define it +#endif + + +#define BOARD_NAME "Azteeg X3 Pro" + +#include "pins_RAMPS.h" + +#ifndef __AVR_ATmega2560__ + #error "Oops! Make sure you have 'Arduino Mega 2560' selected from the 'Tools -> Boards' menu." +#endif + +// +// Servos +// +// Tested this pin with bed leveling on a Delta with 1 servo. +// Physical wire attachment on EXT1: GND, 5V, D47. +// +#undef SERVO0_PIN +#define SERVO0_PIN 47 + +// +// Limit Switches +// +// Swap the MIN and MAX endstop pins because the X3 Pro comes with only +// MIN endstop pin headers soldered onto the board. +// +#if ENABLED(DELTA) + #undef X_MIN_PIN + #undef X_MAX_PIN + #undef Y_MIN_PIN + #undef Y_MAX_PIN + #undef Z_MIN_PIN + #undef Z_MAX_PIN + + #define X_MIN_PIN 2 + #define X_MAX_PIN 3 + #define Y_MIN_PIN 15 + #define Y_MAX_PIN 14 + #define Z_MIN_PIN 19 + #define Z_MAX_PIN 18 +#endif + +// +// Z Probe (when not Z_MIN_PIN) +// +#ifndef Z_MIN_PROBE_PIN + #define Z_MIN_PROBE_PIN 18 +#endif + +// +// Steppers +// +#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 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) + +// +// 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 + +#undef FAN_PIN +#define FAN_PIN 6 // Part Cooling System + +#ifndef CONTROLLER_FAN_PIN + #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 + +// +// LCD / Controller +// +#undef BEEPER_PIN +#define BEEPER_PIN 33 + +#if ENABLED(VIKI2) || ENABLED(miniVIKI) + #undef SD_DETECT_PIN + #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 +#else + #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 + // 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_ENABLE_PIN +#undef SPINDLE_DIR_PIN + +#if ENABLED(SPINDLE_LASER_ENABLE) // use EXP2 header + #if ENABLED(VIKI2) || ENABLED(miniVIKI) + #undef BTN_EN2 + #define BTN_EN2 31 // need 7 for the spindle speed PWM + #endif + #define SPINDLE_LASER_PWM_PIN 7 // must have a hardware PWM + #define SPINDLE_LASER_ENABLE_PIN 20 // Pin should have a pullup! + #define SPINDLE_DIR_PIN 21 +#endif + diff --git a/trunk/Arduino/Marlin_1.1.6/pins_BAM_DICE_DUE.h b/trunk/Arduino/Marlin_1.1.6/pins_BAM_DICE_DUE.h new file mode 100644 index 00000000..2b34cddd --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_BAM_DICE_DUE.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 . + * + */ + +/** + * BAM&DICE Due (Arduino Mega) pin assignments + */ + +#if HOTENDS > 2 || E_STEPPERS > 2 + #error "2PrintBeta Due supports up to 2 hotends / E-steppers. Comment out this line to continue." +#endif + +#define BOARD_NAME "2PrintBeta Due" + +// +// M3/M4/M5 - Spindle/Laser Control +// +#define SPINDLE_LASER_ENABLE_PIN 66 // Pin should have a pullup/pulldown! +#define SPINDLE_DIR_PIN 67 +#define SPINDLE_LASER_PWM_PIN 44 // MUST BE HARDWARE PWM + +#include "pins_RAMPS.h" + +// +// Temperature Sensors +// +#undef TEMP_0_PIN +#undef TEMP_1_PIN +#define TEMP_0_PIN 9 // Analog Input +#define TEMP_1_PIN 11 // Analog Input diff --git a/trunk/Arduino/Marlin_1.1.6/pins_BQ_ZUM_MEGA_3D.h b/trunk/Arduino/Marlin_1.1.6/pins_BQ_ZUM_MEGA_3D.h new file mode 100644 index 00000000..f20f9b54 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_BQ_ZUM_MEGA_3D.h @@ -0,0 +1,118 @@ +/** + * 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 . + * + */ + +/** + * bq ZUM Mega 3D board definition + */ + +#ifndef __AVR_ATmega2560__ + #error "Oops! Make sure you have 'Arduino Mega 2560' selected from the 'Tools -> Boards' menu." +#endif + +#define BOARD_NAME "ZUM Mega 3D" + +// +// Heaters / Fans +// +#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 + +// +// Misc. Functions +// +#define CASE_LIGHT_PIN 44 // MUST BE HARDWARE PWM + +// +// M3/M4/M5 - Spindle/Laser Control +// +#define SPINDLE_LASER_ENABLE_PIN 40 // Pin should have a pullup/pulldown! +#define SPINDLE_LASER_PWM_PIN 44 // MUST BE HARDWARE PWM +#define SPINDLE_DIR_PIN 42 + +#include "pins_RAMPS_13.h" + +// +// Limit Switches +// +#undef X_MAX_PIN +#define X_MAX_PIN 79 // 2 + +// +// Z Probe (when not Z_MIN_PIN) +// +#undef Z_MIN_PROBE_PIN +#define Z_MIN_PROBE_PIN 19 // IND_S_5V + +#undef Z_ENABLE_PIN +#define Z_ENABLE_PIN 77 // 62 + +// +// Steppers +// +#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) + +#undef TEMP_BED_PIN +#define TEMP_BED_PIN 15 // Analog Input (14) + +// +// Misc. Functions +// +#undef PS_ON_PIN // 12 +#define PS_ON_PIN 81 // External Power Supply + + +// 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 +// endstop and the instruction manual advises the user to connect the probe to +// IND_S_5V the option Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN will not work. +#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 +#endif + + +// +// This pin is used by the official Hephestos 2 heated bed upgrade kit +// +#if ENABLED(HEPHESTOS2_HEATED_BED_KIT) + #undef HEATER_BED_PIN + #define HEATER_BED_PIN 8 +#endif diff --git a/trunk/Arduino/Marlin_1.1.6/pins_BRAINWAVE.h b/trunk/Arduino/Marlin_1.1.6/pins_BRAINWAVE.h new file mode 100644 index 00000000..93261976 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_BRAINWAVE.h @@ -0,0 +1,123 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2017 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** + * Brainwave 1.0 pin assignments (AT90USB646) + * + * Requires hardware bundle for Arduino: + * https://github.com/unrepentantgeek/brainwave-arduino + */ + +/** + * Rev B 16 JAN 2017 + * + * Added pointer to a currently available Arduino IDE extension that will + * allow this board to use the latest Marlin software + */ + +/** + * Rev C 2 JUN 2017 + * + * Converted to Arduino pin numbering + */ + +/** + * Marlin_AT90USB - https://github.com/Bob-the-Kuhn/Marlin_AT90USB + * This is the only known IDE extension that is compatible with the pin definitions + * in this file, Adrduino 1.6.12 and the latest mainstream Marlin software. + * + * "Marlin_AT90USB" makes PWM0A available rather than the usual PWM1C. These PWMs share + * the same physical pin. Marlin uses TIMER1 to generate interrupts and sets it up such + * that PWM1A, PWM1B & PWM1C can't be used. + * + * Installation: + * + * 1. In the Arduino IDE, under Files -> Preferences paste the following URL + * https://rawgit.com/Bob-the-Kuhn/Marlin_AT90USB/master/package_MARLIN_AT90USB_index.json + * 2. Under Tools -> Board -> Boards manager, scroll to the bottom, click on MARLIN_AT90USB + * and then click on "Install" + * 3. Select "AT90USB646_TEENSYPP" from the 'Tools -> Boards' menu. + */ + +/** + * To burn the bootloader that comes with Marlin_AT90USB: + * + * 1. Connect your programmer to the board. + * 2. In Arduino IDE select "AT90USB646_TEENSYPP" and then select the programmer. + * 3. In Arduino IDE click on "burn bootloader". Don't worry about the "verify failed at 1F000" error message. + * 4. The programmer is no longer needed. Remove it. + */ + +#ifndef __AVR_AT90USB646__ + #error "Oops! Make sure you have 'AT90USB646_TEENSYPP' selected from the 'Tools -> Boards' menu." +#endif + +#define BOARD_NAME "Brainwave" + +// +// Limit Switches +// +#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 + +// +// Temperature Sensors +// +#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 FAN_PIN 31 // A3 Fan + +// +// Misc. Functions +// +#define LED_PIN 19 // E7 diff --git a/trunk/Arduino/Marlin_1.1.6/pins_BRAINWAVE_PRO.h b/trunk/Arduino/Marlin_1.1.6/pins_BRAINWAVE_PRO.h new file mode 100644 index 00000000..acf8642e --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_BRAINWAVE_PRO.h @@ -0,0 +1,137 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2017 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** + * Brainwave Pro pin assignments (AT90USB1286) + * + * Requires hardware bundle for Arduino: + * https://github.com/unrepentantgeek/brainwave-arduino + */ + +/** + * Rev B 16 JAN 2017 + * + * Added pointers to currently available Arduino IDE extensions that will + * allow this board to use the latest Marlin software + * + * + * Rev C 2 JUN 2017 + * + * Converted to Arduino pin numbering + */ + +/** + * 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 + * Select Teensy++ 2.0 in Arduino IDE from the 'Tools -> Boards' menu + * + * Installation instructions are at the above URL. Don't bother loading the + * libraries - they are not used with the Marlin software. + * + * Printrboard - https://github.com/scwimbush/Printrboard-HID-Arduino-IDE-Support + * + * Installation: + * + * 1. Go to the above URL, click on the "Clone or Download" button and then + * click on "Download ZIP" button. + * 2. Unzip the file, find the "printrboard" directory and then copy it to the + * hardware directory in Arduino. The Arduino hardware directory will probably + * be located in a path similar to this: C:\Program Files (x86)\Arduino\hardware. + * 3. Restart Arduino. + * 4. Select "Printrboard" from the 'Tools -> Boards' menu. + * + * Teensyduino is the most popular option. Printrboard is used if your board doesn't have + * the Teensyduino bootloader on it. + */ + +/** + * To burn the bootloader that comes with Printrboard: + * + * 1. Connect your programmer to the board. + * 2. In the Arduino IDE select "Printrboard" and then select the programmer. + * 3. In the Arduino IDE click on "burn bootloader". Don't worry about the "verify failed at 1F000" error message. + * 4. The programmer is no longer needed. Remove it. + */ + +#ifndef __AVR_AT90USB1286__ + #error "Oops! Make sure you have 'Teensy++ 2.0' or 'Printrboard' selected from the 'Tools -> Boards' menu." +#endif + +#define BOARD_NAME "Brainwave Pro" + +#define LARGE_FLASH true + +// +// Limit Switches +// +#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 +#endif + +// +// Steppers +// +#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 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 + +// +// 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 + +// +// Heaters / Fans +// +#define HEATER_0_PIN 27 // B7 +#define HEATER_BED_PIN 26 // B6 Bed +#define FAN_PIN 16 // C6 Fan, PWM3A + +// +// Misc. Functions +// +#define SDSS 20 // B0 +#define SD_DETECT_PIN 24 // B4 +#define LED_PIN 13 // C3 diff --git a/trunk/Arduino/Marlin_1.1.6/pins_CHEAPTRONIC.h b/trunk/Arduino/Marlin_1.1.6/pins_CHEAPTRONIC.h new file mode 100644 index 00000000..a354a279 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_CHEAPTRONIC.h @@ -0,0 +1,88 @@ +/** + * 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 . + * + */ + +/** + * Cheaptronic v1.0 pin assignments + */ + +#ifndef __AVR_ATmega2560__ + #error "Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu." +#endif + +#define BOARD_NAME "Cheaptronic v1.0" +#define LARGE_FLASH true + +// +// Limit Switches +// +#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 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 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 + +// +// Temperature sensors +// +#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 + +// +// LCD / Controller +// +// Cheaptronic v1.0 doesn't support LCD +#define LCD_PINS_RS -1 +#define LCD_PINS_ENABLE -1 + +// Cheaptronic v1.0 doesn't support keypad +#define BTN_EN1 -1 +#define BTN_EN2 -1 +#define BTN_ENC -1 diff --git a/trunk/Arduino/Marlin_1.1.6/pins_CHEAPTRONICv2.h b/trunk/Arduino/Marlin_1.1.6/pins_CHEAPTRONICv2.h new file mode 100644 index 00000000..257380dd --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_CHEAPTRONICv2.h @@ -0,0 +1,122 @@ +/** + * 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 . + * + */ + +/** + * Cheaptronic v2.0 pin assignments + * Built and sold by Michal Dyntar - RRO + * www.reprapobchod.cz + */ + +#ifndef __AVR_ATmega2560__ + #error "Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu." +#endif + +#define BOARD_NAME "Cheaptronic v2.0" +#define LARGE_FLASH true + +// +// 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 + +// +// Steppers +// +#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 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 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 + +// +// Temperature sensors +// +#define TEMP_0_PIN 15 +#define TEMP_1_PIN 13 +#define TEMP_2_PIN 14 +#define TEMP_3_PIN 11 +#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 + +// +// LCD +// +#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 + +// +// SD CARD, ROTARY ENCODER, BEEPER +// +#define SDPOWER -1 +#define SDSS 53 +#define SD_DETECT_PIN 49 +#define BEEPER_PIN 44 +#define BTN_EN1 11 +#define BTN_EN2 12 +#define BTN_ENC 43 + +// +// Other board specific pins +// +#define LED_PIN 13 +#define SPINDLE_ENABLE_PIN 4 +#define FAN_PIN 3 +#define PS_ON_PIN 45 +#define KILL_PIN 46 + +#ifndef FILWIDTH_PIN + #define FILWIDTH_PIN 37 // should be Analog Input (0-15) +#endif diff --git a/trunk/Arduino/Marlin_1.1.6/pins_CNCONTROLS_11.h b/trunk/Arduino/Marlin_1.1.6/pins_CNCONTROLS_11.h new file mode 100644 index 00000000..fdf6c317 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_CNCONTROLS_11.h @@ -0,0 +1,122 @@ +/** + * CartesioV11 pin assignments + */ + +#if !defined(__AVR_ATmega1280__) && !defined(__AVR_ATmega2560__) + #error Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu. +#endif + +#define BOARD_NAME "CN Controls V11" + +//#define LARGE_FLASH true + +// +// Limit Switches +// +#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 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 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 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 + +// +// 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_CHAMBER_PIN 2 // Analog Input + +// +// 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 FAN_PIN 7 // common PWM pin for all tools + +#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 + +// +// Misc. Functions +// +#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 + +// Common I/O + +//#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 + +// Pins for DOGM SPI LCD Support +#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 + +// Hardware buttons for manual movement of XYZ +#define SHIFT_OUT 19 +#define SHIFT_LD 18 +#define SHIFT_CLK 17 + +//#define UI1 31 +//#define UI2 22 + +#define STAT_LED_BLUE_PIN -1 +#define STAT_LED_RED_PIN 31 diff --git a/trunk/Arduino/Marlin_1.1.6/pins_CNCONTROLS_12.h b/trunk/Arduino/Marlin_1.1.6/pins_CNCONTROLS_12.h new file mode 100644 index 00000000..809d1a6d --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_CNCONTROLS_12.h @@ -0,0 +1,127 @@ +/** + * CartesioV12 pin assignments + */ + +#if !defined(__AVR_ATmega1280__) && !defined(__AVR_ATmega2560__) + #error Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu. +#endif + +#define BOARD_NAME "CN Controls V12" + +//#define LARGE_FLASH true + +// +// Limit Switches +// +#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 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 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 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 + +// +// 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_CHAMBER_PIN 13 // Analog Input + +// +// 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 FAN_PIN 5 // 5 is PWMtool3 -> 7 is common PWM pin for all tools + +#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 + +// +// Misc. Functions +// +#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 + +// Common I/O + +#define FIL_RUNOUT_PIN 18 +//#define PWM_1_PIN 12 +//#define PWM_2_PIN 13 +//#define SPARE_IO 17 + +// +// LCD / Controller +// +#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 LCD_SCREEN_ROT_180 + +// The encoder and click button +#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 UI1 43 +//#define UI2 37 + +#define STAT_LED_BLUE_PIN -1 +#define STAT_LED_RED_PIN 10 // TOOL_0_PWM_PIN diff --git a/trunk/Arduino/Marlin_1.1.6/pins_ELEFU_3.h b/trunk/Arduino/Marlin_1.1.6/pins_ELEFU_3.h new file mode 100644 index 00000000..51bd0786 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_ELEFU_3.h @@ -0,0 +1,149 @@ +/** + * 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 . + * + */ + +/** + * Elefu RA Board Pin Assignments + */ + +#ifndef __AVR_ATmega2560__ + #error "Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu." +#endif + +#define BOARD_NAME "Elefu Ra v3" + +// +// 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 + +// +// Z Probe (when not Z_MIN_PIN) +// +#ifndef Z_MIN_PROBE_PIN + #define Z_MIN_PROBE_PIN 30 +#endif + +// +// Steppers +// +#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 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 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 + +// +// 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 + +// +// 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 FAN_PIN 16 // 5V PWM + +// +// 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 + +// +// LCD / Controller +// +#define BEEPER_PIN 36 + +#if ENABLED(RA_CONTROL_PANEL) + + #define SDSS 53 + #define SD_DETECT_PIN 28 + + #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 + + // 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 // bit 3 on port A + #define TLC_CLOCK_PORT &PORTA // bit 3 on port A + + #define TLC_BLANK_BIT 1 // bit 1 on port A + #define TLC_BLANK_PORT &PORTA // bit 1 on port A + + #define TLC_DATA_BIT 2 // bit 2 on port A + #define TLC_DATA_PORT &PORTA // bit 2 on port A + + #define TLC_XLAT_BIT 0 // bit 0 on port A + #define TLC_XLAT_PORT &PORTA // bit 0 on port A + + // 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 + + // 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. + // NOTE: the array should be 8 long for every TLC you have. These defaults assume (2) TLCs. + #define TRANS_ARRAY {0, 1, 2, 3, 4, 5, 6, 7, 15, 14, 13, 12, 11, 10, 9, 8} //forwards + //#define TRANS_ARRAY {7, 6, 5, 4, 3, 2, 1, 0, 8, 9, 10, 11, 12, 13, 14, 15} //backwards +#endif // RA_DISCO diff --git a/trunk/Arduino/Marlin_1.1.6/pins_FELIX2.h b/trunk/Arduino/Marlin_1.1.6/pins_FELIX2.h new file mode 100644 index 00000000..5d6765c8 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_FELIX2.h @@ -0,0 +1,63 @@ +/** + * 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 . + * + */ + +/** + * FELIXprinters v2.0/3.0 (RAMPS v1.4) pin assignments + */ + +#if HOTENDS > 2 || E_STEPPERS > 2 + #error "Felix 2.0+ supports up to 2 hotends / E-steppers. Comment out this line to continue." +#endif + +#define BOARD_NAME "Felix 2.0+" + +// +// Heaters / Fans +// +// Power outputs EFBF or EFBE +#define MOSFET_D_PIN 7 + +#include "pins_RAMPS.h" + +// +// Misc. Functions +// +#undef SDPOWER +#define SDPOWER 1 + +#define PS_ON_PIN 12 + +// +// LCD / Controller +// +#if ENABLED(ULTRA_LCD) && ENABLED(NEWPANEL) + + #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_ENABLE_PIN +#undef SPINDLE_DIR_PIN diff --git a/trunk/Arduino/Marlin_1.1.6/pins_GEN3_MONOLITHIC.h b/trunk/Arduino/Marlin_1.1.6/pins_GEN3_MONOLITHIC.h new file mode 100644 index 00000000..dae4046f --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_GEN3_MONOLITHIC.h @@ -0,0 +1,101 @@ +/** + * 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 . + * + */ + +/** + * Gen3 Monolithic Electronics pin assignments + */ + +/** + * Rev B 26 DEC 2016 + * + * added pointer to a current Arduino IDE extension + * + */ + +/** + * A useable Arduino IDE extension (board manager) can be found at + * https://github.com/Lauszus/Sanguino + * + * This extension has been tested on Arduino 1.6.12 & 1.8.0 + * + * Here's the JSON path: + * https://raw.githubusercontent.com/Lauszus/Sanguino/master/package_lauszus_sanguino_index.json + * + * When installing select 1.0.2 + * + * Installation instructions can be found at https://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. + * + */ + +#ifndef __AVR_ATmega644P__ + #error "Oops! Make sure you have 'Sanguino' selected from the 'Tools -> Boards' menu." +#endif + +#define BOARD_NAME "Gen3 Monolithic" +#define DEBUG_PIN 0 + +// +// Limit Switches +// +#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 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 E0_STEP_PIN 12 +#define E0_DIR_PIN 17 +#define E0_ENABLE_PIN 3 + +// +// Temperature Sensors +// +#define TEMP_0_PIN 0 // Analog Input + +// +// Heaters +// +#define HEATER_0_PIN 16 + +// +// Misc. Functions +// +#define PS_ON_PIN 14 // Alex, does this work on the card? + +// Alex extras from Gen3+ + diff --git a/trunk/Arduino/Marlin_1.1.6/pins_GEN3_PLUS.h b/trunk/Arduino/Marlin_1.1.6/pins_GEN3_PLUS.h new file mode 100644 index 00000000..85c47305 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_GEN3_PLUS.h @@ -0,0 +1,101 @@ +/** + * 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 . + * + */ + +/** + * Gen3+ pin assignments + */ + +/** + * Rev B 26 DEC 2016 + * + * added pointer to a current Arduino IDE extension + * + */ + +/** + * A useable Arduino IDE extension (board manager) can be found at + * https://github.com/Lauszus/Sanguino + * + * This extension has been tested on Arduino 1.6.12 & 1.8.0 + * + * Here's the JSON path: + * https://raw.githubusercontent.com/Lauszus/Sanguino/master/package_lauszus_sanguino_index.json + * + * When installing select 1.0.2 + * + * Installation instructions can be found at https://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_ATmega1284P__) + #error "Oops! Make sure you have 'Sanguino' selected from the 'Tools -> Boards' menu." +#endif + +#define BOARD_NAME "Gen3+" + +// +// Limit Switches +// +#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 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 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) + +// +// Heaters +// +#define HEATER_0_PIN 12 +#define HEATER_BED_PIN 16 + +// +// Misc. Functions +// +#define SDSS 4 +#define PS_ON_PIN 14 diff --git a/trunk/Arduino/Marlin_1.1.6/pins_GEN6.h b/trunk/Arduino/Marlin_1.1.6/pins_GEN6.h new file mode 100644 index 00000000..1c5e2069 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_GEN6.h @@ -0,0 +1,119 @@ +/** + * 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 . + * + */ + +/** + * Gen6 pin assignments + */ + + /** + * Rev B 26 DEC 2016 + * + * 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 + * + */ + +/** + * A useable Arduino IDE extension (board manager) can be found at + * https://github.com/Lauszus/Sanguino + * + * This extension has been tested on Arduino 1.6.12 & 1.8.0 + * + * Here's the JSON path: + * https://raw.githubusercontent.com/Lauszus/Sanguino/master/package_lauszus_sanguino_index.json + * + * When installing select 1.0.2 + * + * Installation instructions can be found at https://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_ATmega1284P__) + #error "Oops! Make sure you have 'Sanguino' selected from the 'Tools -> Boards' menu." +#endif + +#ifndef BOARD_NAME + #define BOARD_NAME "Gen6" +#endif + +// +// Limit Switches +// +#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 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 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 + +// +// Heaters +// +#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 +#endif + +// +// Misc. Functions +// +#define SDSS 17 +#define DEBUG_PIN 0 +#define CASE_LIGHT_PIN 16 // MUST BE HARDWARE PWM + +// RS485 pins +#define TX_ENABLE_PIN 12 +#define RX_ENABLE_PIN 13 + +// +// M3/M4/M5 - Spindle/Laser Control +// +#define SPINDLE_LASER_ENABLE_PIN 5 // Pin should have a pullup/pulldown! +#define SPINDLE_LASER_PWM_PIN 16 // MUST BE HARDWARE PWM +#define SPINDLE_DIR_PIN 6 diff --git a/trunk/Arduino/Marlin_1.1.6/pins_GEN6_DELUXE.h b/trunk/Arduino/Marlin_1.1.6/pins_GEN6_DELUXE.h new file mode 100644 index 00000000..58340686 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_GEN6_DELUXE.h @@ -0,0 +1,55 @@ +/** + * 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 . + * + */ + +/** + * Gen6 Deluxe pin assignments + */ + +/** + * Rev B 26 DEC 2016 + * + * added pointer to a current Arduino IDE extension + * + */ + +/** + * A useable Arduino IDE extension (board manager) can be found at + * https://github.com/Lauszus/Sanguino + * + * This extension has been tested on Arduino 1.6.12 & 1.8.0 + * + * Here's the JSON path: + * https://raw.githubusercontent.com/Lauszus/Sanguino/master/package_lauszus_sanguino_index.json + * + * When installing select 1.0.2 + * + * Installation instructions can be found at https://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. + * + */ + + +#define BOARD_NAME "Gen6 Deluxe" + +#include "pins_GEN6.h" diff --git a/trunk/Arduino/Marlin_1.1.6/pins_GEN7_12.h b/trunk/Arduino/Marlin_1.1.6/pins_GEN7_12.h new file mode 100644 index 00000000..b0f178ff --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_GEN7_12.h @@ -0,0 +1,149 @@ +/** + * 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 . + * + */ + +/** + * Gen7 v1.1, v1.2, v1.3 pin assignments + */ + + /** + * Rev B 26 DEC 2016 + * + * 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 + * + */ + +/** + * A useable Arduino IDE extension (board manager) can be found at + * https://github.com/Lauszus/Sanguino + * + * This extension has been tested on Arduino 1.6.12 & 1.8.0 + * + * Here's the JSON path: + * https://raw.githubusercontent.com/Lauszus/Sanguino/master/package_lauszus_sanguino_index.json + * + * When installing select 1.0.2 + * + * Installation instructions can be found at https://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__) && !defined(__AVR_ATmega1284P__) + #error "Oops! Make sure you have 'Sanguino' selected from the 'Tools -> Boards' menu." +#endif + +#ifndef BOARD_NAME + #define BOARD_NAME "Gen7 v1.1 / 1.2" +#endif + +#ifndef GEN7_VERSION + #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 + + +// +// Z Probe (when not Z_MIN_PIN) +// +#ifndef Z_MIN_PROBE_PIN + #define Z_MIN_PROBE_PIN 0 +#endif + +// +// Steppers +// +#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 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 + +// +// Temperature Sensors +// +#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 + +#if GEN7_VERSION < 13 // Gen7 v1.3 removed the fan pin + #define FAN_PIN 31 +#endif + +// +// Misc. Functions +// +#define PS_ON_PIN 15 + +#if GEN7_VERSION < 13 + #define CASE_LIGHT_PIN 16 // MUST BE 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 // MUST BE HARDWARE PWM +#endif + +// All these generations of Gen7 supply thermistor power +// via PS_ON, so ignore bad thermistor readings +#define BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE + +#define DEBUG_PIN 0 + +// RS485 pins +#define TX_ENABLE_PIN 12 +#define RX_ENABLE_PIN 13 + +// +// M3/M4/M5 - Spindle/Laser Control +// +#define SPINDLE_LASER_ENABLE_PIN 10 // Pin should have a pullup/pulldown! +#define SPINDLE_DIR_PIN 11 +#if GEN7_VERSION < 13 + #define SPINDLE_LASER_PWM_PIN 16 // MUST BE 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 // MUST BE HARDWARE PWM +#endif diff --git a/trunk/Arduino/Marlin_1.1.6/pins_GEN7_13.h b/trunk/Arduino/Marlin_1.1.6/pins_GEN7_13.h new file mode 100644 index 00000000..03ea131f --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_GEN7_13.h @@ -0,0 +1,55 @@ +/** + * 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 . + * + */ + +/** + * Gen7 v1.3 pin assignments + */ + + /** + * Rev B 26 DEC 2016 + * + * added pointer to a current Arduino IDE extension + * + */ + +/** + * A useable Arduino IDE extension (board manager) can be found at + * https://github.com/Lauszus/Sanguino + * + * This extension has been tested on Arduino 1.6.12 & 1.8.0 + * + * Here's the JSON path: + * https://raw.githubusercontent.com/Lauszus/Sanguino/master/package_lauszus_sanguino_index.json + * + * When installing select 1.0.2 + * + * Installation instructions can be found at https://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. + * + */ + +#define BOARD_NAME "Gen7 v1.3" + +#define GEN7_VERSION 13 // v1.3 +#include "pins_GEN7_12.h" diff --git a/trunk/Arduino/Marlin_1.1.6/pins_GEN7_14.h b/trunk/Arduino/Marlin_1.1.6/pins_GEN7_14.h new file mode 100644 index 00000000..9d4e16af --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_GEN7_14.h @@ -0,0 +1,118 @@ +/** + * 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 . + * + */ + +/** + * Gen7 v1.4 pin assignments + */ + +/** + * Rev B 26 DEC 2016 + * + * 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 + * + */ + +/** + * A useable Arduino IDE extension (board manager) can be found at + * https://github.com/Lauszus/Sanguino + * + * This extension has been tested on Arduino 1.6.12 & 1.8.0 + * + * Here's the JSON path: + * https://raw.githubusercontent.com/Lauszus/Sanguino/master/package_lauszus_sanguino_index.json + * + * When installing select 1.0.2 + * + * Installation instructions can be found at https://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__) && !defined(__AVR_ATmega1284P__) + #error "Oops! Make sure you have 'Sanguino' selected from the 'Tools -> Boards' menu." +#endif + +#define BOARD_NAME "Gen7 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 + +// +// Steppers +// +#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 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 + +// +// Temperature Sensors +// +#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 + +// +// Misc. Functions +// +#define PS_ON_PIN 15 +#define CASE_LIGHT_PIN 15 // MUST BE HARDWARE PWM + +// A pin for debugging +#define DEBUG_PIN 0 + +// RS485 pins +#define TX_ENABLE_PIN 12 +#define RX_ENABLE_PIN 13 + +// +// M3/M4/M5 - Spindle/Laser Control +// +#define SPINDLE_LASER_ENABLE_PIN 20 // Pin should have a pullup/pulldown! +#define SPINDLE_LASER_PWM_PIN 16 // MUST BE HARDWARE PWM +#define SPINDLE_DIR_PIN 21 diff --git a/trunk/Arduino/Marlin_1.1.6/pins_GEN7_CUSTOM.h b/trunk/Arduino/Marlin_1.1.6/pins_GEN7_CUSTOM.h new file mode 100644 index 00000000..d64e94e2 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_GEN7_CUSTOM.h @@ -0,0 +1,138 @@ +/** + * 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 . + * + */ + +/** + * Gen7 Alfons3 board pin assignments + * + * These Pins are assigned for the modified GEN7 Board from Alfons3. + * Please review the pins and adjust them for your needs. + */ + +/** + * Rev B 26 DEC 2016 + * + * 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 + * + */ + +/** + * A useable Arduino IDE extension (board manager) can be found at + * https://github.com/Lauszus/Sanguino + * + * This extension has been tested on Arduino 1.6.12 & 1.8.0 + * + * Here's the JSON path: + * https://raw.githubusercontent.com/Lauszus/Sanguino/master/package_lauszus_sanguino_index.json + * + * When installing select 1.0.2 + * + * Installation instructions can be found at https://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__) && !defined(__AVR_ATmega1284P__) + #error "Oops! Make sure you have 'Sanguino' selected from the 'Tools -> Boards' menu." +#endif + +#define BOARD_NAME "Gen7 Custom" + +// +// Limit Switches +// +#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 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 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) + +// +// Heaters +// +#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 // MUST BE HARDWARE PWM + +// A pin for debugging +#define DEBUG_PIN -1 + +// +// LCD / Controller +// +#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 + +// Buttons are directly attached +#define BTN_EN1 11 +#define BTN_EN2 10 +#define BTN_ENC 12 + +// RS485 pins +//#define TX_ENABLE_PIN 12 +//#define RX_ENABLE_PIN 13 + +// +// M3/M4/M5 - Spindle/Laser Control +// +#define SPINDLE_LASER_ENABLE_PIN 5 // Pin should have a pullup/pulldown! +#define SPINDLE_LASER_PWM_PIN 16 // MUST BE HARDWARE PWM +#define SPINDLE_DIR_PIN 6 diff --git a/trunk/Arduino/Marlin_1.1.6/pins_GT2560_REV_A.h b/trunk/Arduino/Marlin_1.1.6/pins_GT2560_REV_A.h new file mode 100644 index 00000000..0c420cfa --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_GT2560_REV_A.h @@ -0,0 +1,133 @@ +/** + * 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 . + * + */ + +/** + * Geeetech GT2560 Revision A board pin assignments, based on the work of + * George Robles (https://georges3dprinters.com) and + * Richard Smith + */ + +#if !defined(__AVR_ATmega1280__) && !defined(__AVR_ATmega2560__) + #error "Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu." +#endif + +#define BOARD_NAME "GT2560 Rev.A" +#define DEFAULT_MACHINE_NAME "Prusa i3 Pro B" +#define LARGE_FLASH true + +// +// 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 + +// +// Steppers +// +#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 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 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 + +// +// Heaters / Fans +// +#define HEATER_0_PIN 2 +#define HEATER_1_PIN 3 +#define HEATER_BED_PIN 4 +#define FAN_PIN 7 + +// +// Misc. Functions +// +#define SDPOWER -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 ENABLED(ULTRA_LCD) + + #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 + + // Buttons are directly attached + #define BTN_EN1 42 + #define BTN_EN2 40 + #define BTN_ENC 19 + + #define SD_DETECT_PIN 38 + + #else // !NEWPANEL + + #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 SD_DETECT_PIN -1 + + #endif // !NEWPANEL + +#endif // ULTRA_LCD diff --git a/trunk/Arduino/Marlin_1.1.6/pins_GT2560_REV_A_PLUS.h b/trunk/Arduino/Marlin_1.1.6/pins_GT2560_REV_A_PLUS.h new file mode 100644 index 00000000..16660e0d --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_GT2560_REV_A_PLUS.h @@ -0,0 +1,36 @@ +/** + * 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 . + * + */ + +/** + * Geeetech GT2560 Revision A+ board pin assignments + */ + +#include "pins_GT2560_REV_A.h" + +#undef BOARD_NAME +#define BOARD_NAME "GT2560 Rev.A+" + +#if ENABLED(BLTOUCH) + #define SERVO0_PIN 32 +#else + #define SERVO0_PIN 11 +#endif diff --git a/trunk/Arduino/Marlin_1.1.6/pins_K8200.h b/trunk/Arduino/Marlin_1.1.6/pins_K8200.h new file mode 100644 index 00000000..cc3e7311 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_K8200.h @@ -0,0 +1,32 @@ +/** + * 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 . + * + */ + +/** + * K8200 Arduino Mega with RAMPS v1.3 pin assignments + * Identical to 3DRAG + */ + +#define BOARD_NAME "Velleman K8200" +#define DEFAULT_MACHINE_NAME "K8200" +#define DEFAULT_SOURCE_CODE_URL "https://github.com/CONSULitAS/Marlin-K8200" + +#include "pins_3DRAG.h" diff --git a/trunk/Arduino/Marlin_1.1.6/pins_K8400.h b/trunk/Arduino/Marlin_1.1.6/pins_K8400.h new file mode 100644 index 00000000..3e2cd4b2 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_K8400.h @@ -0,0 +1,73 @@ +/** + * 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 . + * + */ + +/** + * Velleman K8400 (Vertex) + * 3DRAG clone + * + * K8400 has some minor differences over a normal 3Drag: + * - No X/Y max endstops + * - Second extruder step pin has moved + * - No power supply control + * - Second heater has moved pin + */ + +#define BOARD_NAME "K8400" +#define DEFAULT_MACHINE_NAME "Vertex" +#define DEFAULT_SOURCE_CODE_URL "https://github.com/birkett/Vertex-K8400-Firmware" + +#include "pins_3DRAG.h" + +// +// Limit Switches +// +#define X_STOP_PIN 3 +#define Y_STOP_PIN 14 + +#undef X_MIN_PIN +#undef X_MAX_PIN +#undef Y_MIN_PIN +#undef Y_MAX_PIN + +// +// Steppers +// +#undef E1_STEP_PIN +#define E1_STEP_PIN 32 + +// +// Heaters / Fans +// +#undef HEATER_1_PIN +#define HEATER_1_PIN 11 + +// +// Misc. Functions +// +#undef PS_ON_PIN +#undef KILL_PIN +#undef SD_DETECT_PIN + +#if Z_STEP_PIN == 26 + #undef Z_STEP_PIN + #define Z_STEP_PIN 32 +#endif diff --git a/trunk/Arduino/Marlin_1.1.6/pins_LEAPFROG.h b/trunk/Arduino/Marlin_1.1.6/pins_LEAPFROG.h new file mode 100644 index 00000000..a7fffa53 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_LEAPFROG.h @@ -0,0 +1,91 @@ +/** + * 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 . + * + */ + +/** + * Leapfrog Driver board pin assignments + */ + +#if !defined(__AVR_ATmega1280__) && !defined(__AVR_ATmega2560__) + #error "Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu." +#endif + +#define BOARD_NAME "Leapfrog" + +// +// 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 + +// +// Steppers +// +#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 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 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) + +// +// 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 FAN_PIN 7 + +// +// Misc. Functions +// +#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/trunk/Arduino/Marlin_1.1.6/pins_MEGACONTROLLER.h b/trunk/Arduino/Marlin_1.1.6/pins_MEGACONTROLLER.h new file mode 100644 index 00000000..c4a10705 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_MEGACONTROLLER.h @@ -0,0 +1,162 @@ +/** + * 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 . + * + */ + +/** + * Mega controller pin assignments + */ + +#ifndef __AVR_ATmega2560__ + #error "Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu." +#endif + +#if HOTENDS > 2 || E_STEPPERS > 2 + #error "Mega Controller supports up to 2 hotends / E-steppers. Comment out this line to continue." +#endif + +#define BOARD_NAME "Mega Controller" + +// +// Servos +// +#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 + +// +// Z Probe (when not Z_MIN_PIN) +// +#ifndef Z_MIN_PROBE_PIN + #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 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 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 + +// +// Temperature Sensors +// +#if TEMP_SENSOR_0 == -1 + #define TEMP_0_PIN 4 // Analog Input +#else + #define TEMP_0_PIN 0 // Analog Input +#endif + +#if TEMP_SENSOR_1 == -1 + #define TEMP_1_PIN 5 // Analog Input +#else + #define TEMP_1_PIN 2 // Analog Input +#endif + +#define TEMP_2_PIN 3 // Analog Input + +#if TEMP_SENSOR_BED == -1 + #define TEMP_BED_PIN 6 // Analog Input +#else + #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 FAN_PIN 39 +#define FAN1_PIN 35 +#define FAN2_PIN 36 + +#ifndef CONTROLLER_FAN_PIN + #define CONTROLLER_FAN_PIN FAN2_PIN +#endif + +#define FAN_SOFT_PWM + +// +// Misc. Functions +// +#define SDSS 53 +#define LED_PIN 13 +#define CASE_LIGHT_PIN 2 + +// +// LCD / Controller +// +#if ENABLED(MINIPANEL) + #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 KILL_PIN 12 + // GLCD features + //#define LCD_CONTRAST 190 + // 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 SD_DETECT_PIN 49 +#endif // MINIPANEL + +// +// M3/M4/M5 - Spindle/Laser Control +// +#define SPINDLE_LASER_PWM_PIN 6 // MUST BE HARDWARE PWM +#define SPINDLE_LASER_ENABLE_PIN 7 // Pin should have a pullup! +#define SPINDLE_DIR_PIN 8 diff --git a/trunk/Arduino/Marlin_1.1.6/pins_MEGATRONICS.h b/trunk/Arduino/Marlin_1.1.6/pins_MEGATRONICS.h new file mode 100644 index 00000000..ba97fa25 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_MEGATRONICS.h @@ -0,0 +1,130 @@ +/** + * 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 . + * + */ + +/** + * MegaTronics pin assignments + */ + +#ifndef __AVR_ATmega2560__ + #error "Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu." +#endif + +#define BOARD_NAME "Megatronics" +#define LARGE_FLASH true + +// +// 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 + +// +// Z Probe (when not Z_MIN_PIN) +// +#ifndef Z_MIN_PROBE_PIN + #define Z_MIN_PROBE_PIN 19 +#endif + +// +// Steppers +// +#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 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 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 +#else + #define TEMP_0_PIN 13 // Analog Input +#endif +#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 FAN_PIN 7 // IO pin. Buffer needed + +// +// Misc. Functions +// +#define SDSS 53 +#define LED_PIN 13 +#define PS_ON_PIN 12 +#define CASE_LIGHT_PIN 2 + +// +// LCD / Controller +// +#define BEEPER_PIN 33 + +#if ENABLED(ULTRA_LCD) && ENABLED(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 + + // Buttons directly attached using AUX-2 + #define BTN_EN1 59 + #define BTN_EN2 64 + #define BTN_ENC 43 + + #define SD_DETECT_PIN -1 // RAMPS doesn't use this + +#endif // ULTRA_LCD && NEWPANEL + +// +// M3/M4/M5 - Spindle/Laser Control +// +#define SPINDLE_LASER_PWM_PIN 3 // MUST BE HARDWARE PWM +#define SPINDLE_LASER_ENABLE_PIN 4 // Pin should have a pullup! +#define SPINDLE_DIR_PIN 11 diff --git a/trunk/Arduino/Marlin_1.1.6/pins_MEGATRONICS_2.h b/trunk/Arduino/Marlin_1.1.6/pins_MEGATRONICS_2.h new file mode 100644 index 00000000..6db1489b --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_MEGATRONICS_2.h @@ -0,0 +1,145 @@ +/** + * 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 . + * + */ + +/** + * MegaTronics v2.0 pin assignments + */ + +#ifndef __AVR_ATmega2560__ + #error "Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu." +#endif + +#define BOARD_NAME "Megatronics v2.0" +#define LARGE_FLASH true + +// +// 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 + +// +// Z Probe (when not Z_MIN_PIN) +// +#ifndef Z_MIN_PROBE_PIN + #define Z_MIN_PROBE_PIN 19 +#endif + +// +// Steppers +// +#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 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 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 + +// +// Temperature Sensors +// +#if TEMP_SENSOR_0 == -1 + #define TEMP_0_PIN 4 // Analog Input +#else + #define TEMP_0_PIN 13 // Analog Input +#endif + +#if TEMP_SENSOR_1 == -1 + #define TEMP_1_PIN 8 // Analog Input +#else + #define TEMP_1_PIN 15 // Analog Input +#endif + +#if TEMP_SENSOR_BED == -1 + #define TEMP_BED_PIN 8 // Analog Input +#else + #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 FAN_PIN 7 +#define FAN1_PIN 6 + +// +// Misc. Functions +// +#define SDSS 53 +#define LED_PIN 13 +#define PS_ON_PIN 12 +#define CASE_LIGHT_PIN 2 + +// +// LCD / Controller +// +#define BEEPER_PIN 64 + +#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 + +// Buttons are directly attached using keypad +#define BTN_EN1 61 +#define BTN_EN2 59 +#define BTN_ENC 43 + +// Buttons that are attached using shift register of reprapworld keypad v1.1 +#define SHIFT_CLK 63 +#define SHIFT_LD 42 +#define SHIFT_OUT 17 +#define SHIFT_EN 17 + +// +// M3/M4/M5 - Spindle/Laser Control +// +#define SPINDLE_LASER_PWM_PIN 3 // MUST BE HARDWARE PWM +#define SPINDLE_LASER_ENABLE_PIN 16 // Pin should have a pullup! +#define SPINDLE_DIR_PIN 11 diff --git a/trunk/Arduino/Marlin_1.1.6/pins_MEGATRONICS_3.h b/trunk/Arduino/Marlin_1.1.6/pins_MEGATRONICS_3.h new file mode 100644 index 00000000..2ebb209b --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_MEGATRONICS_3.h @@ -0,0 +1,196 @@ +/** + * 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 . + * + */ + +/** + * MegaTronics v3.0 pin assignments + */ + +#ifndef __AVR_ATmega2560__ + #error "Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu." +#endif + +#define MEGATRONICS_31 + +#if ENABLED(MEGATRONICS_31) + #define BOARD_NAME "Megatronics v3.1" +#else + #define BOARD_NAME "Megatronics v3.0" +#endif + +#define LARGE_FLASH true + +// +// 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 + +// +// 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 + +// +// Z Probe (when not Z_MIN_PIN) +// +#ifndef Z_MIN_PROBE_PIN + #define Z_MIN_PROBE_PIN 19 +#endif + +// +// Steppers +// +#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 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 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 + +// +// Temperature Sensors +// +#if TEMP_SENSOR_0 == -1 + #define TEMP_0_PIN 11 // Analog Input +#else + #define TEMP_0_PIN 15 // Analog Input +#endif +#if TEMP_SENSOR_1 == -1 + #define TEMP_1_PIN 10 // Analog Input +#else + #define TEMP_1_PIN 13 // Analog Input +#endif +#if TEMP_SENSOR_2 == -1 + #define TEMP_2_PIN 9 // Analog Input +#else + #define TEMP_2_PIN 12 // Analog Input +#endif +#if TEMP_SENSOR_BED == -1 + #define TEMP_BED_PIN 8 // Analog Input +#else + #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 FAN_PIN 6 +#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 + +// +// LCD / Controller +// +#define BEEPER_PIN 61 + +#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 + +#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 SHIFT_CLK 43 + #define SHIFT_LD 35 + #define SHIFT_OUT 34 + #define SHIFT_EN 44 + + #if ENABLED(MEGATRONICS_31) + #define SD_DETECT_PIN 56 + #else + #define SD_DETECT_PIN -1 + #endif + +#endif + +// +// M3/M4/M5 - Spindle/Laser Control +// +#if DISABLED(REPRAPWORLD_KEYPAD) // try to use the keypad connector first + #define SPINDLE_LASER_PWM_PIN 44 // MUST BE HARDWARE PWM + #define SPINDLE_LASER_ENABLE_PIN 43 // Pin should have a 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 // MUST BE HARDWARE PWM + #define SPINDLE_LASER_ENABLE_PIN 17 // Pin should have a pullup! + #define SPINDLE_DIR_PIN 5 +#endif diff --git a/trunk/Arduino/Marlin_1.1.6/pins_MELZI.h b/trunk/Arduino/Marlin_1.1.6/pins_MELZI.h new file mode 100644 index 00000000..4f6ccb5e --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_MELZI.h @@ -0,0 +1,29 @@ +/** + * 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 . + * + */ + +/** + * Melzi pin assignments + */ + +#define BOARD_NAME "Melzi" +#define IS_MELZI +#include "pins_SANGUINOLOLU_12.h" diff --git a/trunk/Arduino/Marlin_1.1.6/pins_MELZI_CREALITY.h b/trunk/Arduino/Marlin_1.1.6/pins_MELZI_CREALITY.h new file mode 100644 index 00000000..7981e4a4 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_MELZI_CREALITY.h @@ -0,0 +1,107 @@ +/** + * 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 . + * + */ + +/** + * Melzi (Creality) pin assignments + * + * The Creality 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/ + */ + +#define BOARD_NAME "Melzi (Creality)" +#define IS_MELZI + +#include "pins_SANGUINOLOLU_12.h" + +// For the stock CR-10 use the REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER +// option for the display in Configuration.h + +#undef LCD_SDSS +#undef LED_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 +#undef FIL_RUNOUT_PIN + +#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 FIL_RUNOUT_PIN -1 // Uses Beeper/LED Pin Pulled to GND + +// 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 + +/** + PIN: 0 Port: B0 E0_DIR_PIN protected + PIN: 1 Port: B1 E0_STEP_PIN protected + PIN: 2 Port: B2 Z_DIR_PIN protected + PIN: 3 Port: B3 Z_STEP_PIN protected + PIN: 4 Port: B4 AVR_SS_PIN protected + . FAN_PIN protected + . SS_PIN protected + PIN: 5 Port: B5 AVR_MOSI_PIN Output = 1 + . MOSI_PIN Output = 1 + PIN: 6 Port: B6 AVR_MISO_PIN Input = 0 TIMER3A PWM: 0 WGM: 1 COM3A: 0 CS: 3 TCCR3A: 1 TCCR3B: 3 TIMSK3: 0 + . MISO_PIN Input = 0 + PIN: 7 Port: B7 AVR_SCK_PIN Output = 0 TIMER3B PWM: 0 WGM: 1 COM3B: 0 CS: 3 TCCR3A: 1 TCCR3B: 3 TIMSK3: 0 + . SCK_PIN Output = 0 + PIN: 8 Port: D0 RXD Input = 1 + PIN: 9 Port: D1 TXD Input = 0 + PIN: 10 Port: D2 BTN_EN2 Input = 1 + PIN: 11 Port: D3 BTN_EN1 Input = 1 + PIN: 12 Port: D4 HEATER_BED_PIN protected + PIN: 13 Port: D5 HEATER_0_PIN protected + PIN: 14 Port: D6 E0_ENABLE_PIN protected + . X_ENABLE_PIN protected + . Y_ENABLE_PIN protected + PIN: 15 Port: D7 X_STEP_PIN protected + PIN: 16 Port: C0 BTN_ENC Input = 1 + . SCL Input = 1 + PIN: 17 Port: C1 LCD_PINS_ENABLE Output = 0 + . SDA Output = 0 + PIN: 18 Port: C2 X_MIN_PIN protected + . X_STOP_PIN protected + PIN: 19 Port: C3 Y_MIN_PIN protected + . Y_STOP_PIN protected + PIN: 20 Port: C4 Z_MIN_PIN protected + . Z_STOP_PIN protected + PIN: 21 Port: C5 X_DIR_PIN protected + PIN: 22 Port: C6 Y_STEP_PIN protected + PIN: 23 Port: C7 Y_DIR_PIN protected + PIN: 24 Port: A7 TEMP_0_PIN protected + PIN: 25 Port: A6 TEMP_BED_PIN protected + PIN: 26 Port: A5 Z_ENABLE_PIN protected + PIN: 27 Port: A4 BEEPER_PIN Output = 0 + PIN: 28 Port: A3 LCD_PINS_RS Output = 0 + PIN: 29 Port: A2 Input = 0 + PIN: 30 Port: A1 LCD_PINS_D4 Output = 1 + PIN: 31 Port: A0 SDSS Output = 1 +*/ diff --git a/trunk/Arduino/Marlin_1.1.6/pins_MELZI_MAKR3D.h b/trunk/Arduino/Marlin_1.1.6/pins_MELZI_MAKR3D.h new file mode 100644 index 00000000..556f9ce8 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_MELZI_MAKR3D.h @@ -0,0 +1,29 @@ +/** + * 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 . + * + */ + +/** + * Melzi with ATmega1284 (MaKr3d version) pin assignments + */ + +#define BOARD_NAME "Melzi (ATmega1284)" +#define IS_MELZI +#include "pins_SANGUINOLOLU_12.h" diff --git a/trunk/Arduino/Marlin_1.1.6/pins_MIGHTYBOARD_REVE.h b/trunk/Arduino/Marlin_1.1.6/pins_MIGHTYBOARD_REVE.h new file mode 100644 index 00000000..5b5d6e7e --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_MIGHTYBOARD_REVE.h @@ -0,0 +1,333 @@ +/** + * 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 . + * + */ + +/** + * Mightyboard Rev.E pin assignments + */ + +/** + * + * This is a starting-point to support the Makerbot Replicator series of 3D printers. + * It's not functional because Marlin has limited support for some features. + * Marlin will need the following augmentations before it will be supportable: + * + * - Support for two or more MAX6675 thermocouples + * - Support for multiple i2c buses to control the MCP4018 digital pots + * - Support for one additional unidirectional SPI bus, to read the thermocouples + * - Support for an RGB LED that may work differently from BLINKM + * + * The MCP4018 requires separate I2C buses because it has a fixed address (0x2F << 1 = 0x5E) + * The thermocouples share the same SCK and DO pins, with their own CS pins. + * The controller interface port connects to a 3-wire shift-register display controller + * + */ + +/** + * Rev B 2 JAN 2017 + * + * Added pin definitions for: + * M3, M4 & M5 spindle control commands + * case light + * + * Corrected pin assignment for MOSFET_B_PIN pin. Changed it from 9 to 11. The port + * number (B5) agrees with the schematic but B5 is assigned to logical pin 11. + */ + +#if !defined(__AVR_ATmega1280__) && !defined(__AVR_ATmega2560__) + #error "Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu." +#endif + +#define DEFAULT_MACHINE_NAME "MB Replicator" +#define BOARD_NAME "Mightyboard" + +#define LARGE_FLASH true + +// +// 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) + +// +// 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 + +// +// Z Probe (when not Z_MIN_PIN) +// +#ifndef Z_MIN_PROBE_PIN + #define Z_MIN_PROBE_PIN 42 +#endif + +// +// Steppers +// +#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 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 E1_STEP_PIN 29 // A7 +#define E1_DIR_PIN 28 // A6 +#define E1_ENABLE_PIN 39 // G2 + +// +// I2C Digipots - MCP4018 +// Address 5E (2F << 1) +// 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 + +// +// Temperature Sensors +// +#define TEMP_BED_PIN 69 // K7 + +// SPI for Max6675 or Max31855 Thermocouple +// Uses a separate SPI bus +// +// 3 E5 DO (SO) +// 5 E3 CS1 +// 2 E4 CS2 +// 78 E2 SCK +// +#define THERMO_SCK_PIN 78 // E2 +#define THERMO_DO_PIN 3 // E5 +#define THERMO_CS1 5 // E3 +#define THERMO_CS2 2 // E4 + +#define MAX6675_SS THERMO_CS1 +#define MAX6675_SCK_PIN THERMO_SCK_PIN +#define MAX6675_DO_PIN THERMO_DO_PIN +// +// Augmentation for auto-assigning plugs +// +// Two thermocouple connectors allows for either +// 2 extruders or 1 extruder and a heated bed. +// With no heated bed, an additional 24V fan is possible. +// +#define MOSFET_A_PIN 6 // H3 +#define MOSFET_B_PIN 11 // B5 - Rev A of this file had this pin assigned to 9 +#define MOSFET_C_PIN 45 // L4 +#define MOSFET_D_PIN 44 // L5 + +#if HOTENDS > 1 + #if TEMP_SENSOR_BED + #define IS_EEB + #else + #define IS_EEF + #endif +#elif TEMP_SENSOR_BED + #define IS_EFB +#else + #define IS_EFF +#endif + +// +// Heaters / Fans (24V) +// +#define HEATER_0_PIN MOSFET_A_PIN + +#if ENABLED(IS_EFB) // Hotend, Fan, Bed + #define FAN_PIN MOSFET_B_PIN + #define HEATER_BED_PIN MOSFET_C_PIN +#elif ENABLED(IS_EEF) // Hotend, Hotend, Fan + #define HEATER_1_PIN MOSFET_B_PIN + #define FAN_PIN MOSFET_C_PIN +#elif ENABLED(IS_EEB) // Hotend, Hotend, Bed + #define HEATER_1_PIN MOSFET_B_PIN + #define HEATER_BED_PIN MOSFET_C_PIN +#elif ENABLED(IS_EFF) // Hotend, Fan, Fan + #define FAN_PIN MOSFET_B_PIN + #define FAN1_PIN MOSFET_C_PIN +#elif ENABLED(IS_SF) // Spindle, Fan + #define FAN_PIN MOSFET_C_PIN +#endif + +#ifndef FAN_PIN + #define FAN_PIN MOSFET_D_PIN +#endif + +// +// Extruder Auto Fan Pins +// +#define ORIG_E0_AUTO_FAN_PIN 7 // H4 +#define ORIG_E1_AUTO_FAN_PIN 12 // B6 + +// +// Misc. Functions +// +#define LED_PIN 13 // B7 +#define CUTOFF_RESET_PIN 16 // H1 +#define CUTOFF_TEST_PIN 17 // H0 +#define CASE_LIGHT_PIN 44 // L5 MUST BE HARDWARE PWM + +// +// LCD / Controller +// +#ifdef 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 BTN_EN2 75 // J4, UP + #define BTN_EN1 73 // J3, DOWN + //STOP button connected as KILL_PIN + #define KILL_PIN 14 // J1, RIGHT + //KILL - not connected + + #define BEEPER_PIN 8 // H5, SD_WP + + #define BTN_CENTER 15 // J0 + #define BTN_ENC BTN_CENTER + + //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) + +#else + // Replicator uses a 3-wire SR controller with HD44780 + // For now, pretend it's the SAV + // + + #define SAV_3DLCD + #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_DOWN 73 // J3 + #define BTN_LEFT 72 // J2 + #define BTN_RIGHT 14 // J1 + #define BTN_CENTER 15 // J0 + #define BTN_ENC BTN_CENTER + + #define BEEPER_PIN 4 // G5 + + #define STAT_LED_RED_PIN 32 // C5 + #define STAT_LED_BLUE_PIN 31 // C6 (Actually green) + +#endif + +// +// SD Card +// +#define SDSS 53 // B0 +#define SD_DETECT_PIN 9 // H6 + +#define MAX_PIN THERMO_SCK_PIN + +// +// M3/M4/M5 - Spindle/Laser Control +// +#define SPINDLE_LASER_ENABLE_PIN 66 // K4 Pin should have a pullup! +#define SPINDLE_LASER_PWM_PIN 8 // H5 MUST BE HARDWARE PWM +#define SPINDLE_DIR_PIN 67 // K5 + + + + +// Check if all pins are defined in mega/pins_arduino.h +#include +static_assert(NUM_DIGITAL_PINS > MAX_PIN, "add missing pins to [arduino dir]/hardware/arduino/avr/variants/mega/pins_arduino.h based on fastio.h" + "to digital_pin_to_port_PGM, digital_pin_to_bit_mask_PGM, digital_pin_to_timer_PGM, NUM_DIGITAL_PINS, see below"); + +/* in [arduino dir]/hardware/arduino/avr/variants/mega/pins_arduino.h +change: +#define NUM_DIGITAL_PINS 70 +to: +#define NUM_DIGITAL_PINS 80 + +to digital_pin_to_port_PGM add at the end: +const uint8_t PROGMEM digital_pin_to_port_PGM[] = { +.... + PG , // PG 4 ** 70 ** + PG , // PG 3 ** 71 ** + PJ , // PJ 2 ** 72 ** + PJ , // PJ 3 ** 73 ** + PJ , // PJ 7 ** 74 ** + PJ , // PJ 4 ** 75 ** + PJ , // PJ 5 ** 76 ** + PJ , // PJ 6 ** 77 ** + PE , // PE 2 ** 78 ** + PE , // PE 6 ** 79 ** +}; + +to digital_pin_to_bit_mask_PGM add at the end: +const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] = { +.... + _BV( 4 ) , // PG 4 ** 70 ** + _BV( 3 ) , // PG 3 ** 71 ** + _BV( 2 ) , // PJ 2 ** 72 ** + _BV( 3 ) , // PJ 3 ** 73 ** + _BV( 7 ) , // PJ 7 ** 74 ** + _BV( 4 ) , // PJ 4 ** 75 ** + _BV( 5 ) , // PJ 5 ** 76 ** + _BV( 6 ) , // PJ 6 ** 77 ** + _BV( 2 ) , // PE 2 ** 78 ** + _BV( 6 ) , // PE 6 ** 79 ** +}; + +to digital_pin_to_timer_PGM add at the end: +const uint8_t PROGMEM digital_pin_to_timer_PGM[] = { +.... + NOT_ON_TIMER , // PG 4 ** 70 ** + NOT_ON_TIMER , // PG 3 ** 71 ** + NOT_ON_TIMER , // PJ 2 ** 72 ** + NOT_ON_TIMER , // PJ 3 ** 73 ** + NOT_ON_TIMER , // PJ 7 ** 74 ** + NOT_ON_TIMER , // PJ 4 ** 75 ** + NOT_ON_TIMER , // PJ 5 ** 76 ** + NOT_ON_TIMER , // PJ 6 ** 77 ** + NOT_ON_TIMER , // PE 2 ** 78 ** + NOT_ON_TIMER , // PE 6 ** 79 ** +}; +*/ diff --git a/trunk/Arduino/Marlin_1.1.6/pins_MINIRAMBO.h b/trunk/Arduino/Marlin_1.1.6/pins_MINIRAMBO.h new file mode 100644 index 00000000..9ff32207 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_MINIRAMBO.h @@ -0,0 +1,160 @@ +/** + * 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 . + * + */ + +/** + * Mini-Rambo pin assignments + */ + +#ifndef __AVR_ATmega2560__ + #error "Oops! Make sure you have 'Arduino Mega 2560 or Rambo' selected from the 'Tools -> Boards' menu." +#endif + +#define BOARD_NAME "Mini Rambo" +#define LARGE_FLASH true + +// +// 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 + +// +// Z Probe (when not Z_MIN_PIN) +// +#ifndef Z_MIN_PROBE_PIN + #define Z_MIN_PROBE_PIN 23 +#endif + +// +// Steppers +// +#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 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 E1_STEP_PIN -1 +#define E1_DIR_PIN -1 +#define E1_ENABLE_PIN -1 + +// 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 +// 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 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_2_PIN 6 +#define HEATER_BED_PIN 4 + +#define FAN_PIN 8 +#define FAN1_PIN 6 + +// +// Misc. Functions +// +#define SDSS 53 +#define LED_PIN 13 +#define CASE_LIGHT_PIN 9 + +// +// M3/M4/M5 - Spindle/Laser Control +// +// use P1 connector for spindle pins +#define SPINDLE_LASER_PWM_PIN 9 // MUST BE HARDWARE PWM +#define SPINDLE_LASER_ENABLE_PIN 18 // Pin should have a 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 + +// +// LCD / Controller +// +#if ENABLED(ULTRA_LCD) + + #define KILL_PIN 32 + + #if ENABLED(NEWPANEL) + + // Beeper on AUX-4 + #define BEEPER_PIN 84 + + #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 + + // buttons are directly attached using AUX-2 + #define BTN_EN1 14 + #define BTN_EN2 72 + #define BTN_ENC 9 // the click + + #define SD_DETECT_PIN 15 + + #endif // NEWPANEL +#endif // ULTRA_LCD diff --git a/trunk/Arduino/Marlin_1.1.6/pins_MINITRONICS.h b/trunk/Arduino/Marlin_1.1.6/pins_MINITRONICS.h new file mode 100644 index 00000000..f224f200 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_MINITRONICS.h @@ -0,0 +1,144 @@ +/** + * 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 . + * + */ + +/** + * Minitronics v1.0/1.1 pin assignments + */ + +/** + * Rev B 2 JAN 2017 + * + * Added pin definitions for M3, M4 & M5 spindle control commands + * + */ + +#ifndef __AVR_ATmega1281__ + #error "Oops! Make sure you have 'Minitronics' selected from the 'Tools -> Boards' menu." +#endif + +#if HOTENDS > 2 || E_STEPPERS > 2 + #error "Minitronics supports up to 2 hotends / E-steppers. Comment out this line to continue." +#endif + +#define BOARD_NAME "Minitronics v1.0 / v1.1" +#define LARGE_FLASH true + +// +// 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 + +// +// Steppers +// +#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 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 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 + +// +// Heaters / Fans +// +#define HEATER_0_PIN 7 // EXTRUDER 1 +#define HEATER_1_PIN 8 // EXTRUDER 2 +#define HEATER_BED_PIN 3 // BED + +#define FAN_PIN 9 + +// +// Misc. Functions +// +#define SDSS 16 +#define LED_PIN 46 + +// +// LCD / Controller +// +#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 BTN_EN1 18 + #define BTN_EN2 17 + #define BTN_ENC 25 + + #define SD_DETECT_PIN 30 + +#else + + #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 SD_DETECT_PIN -1 // Minitronics doesn't use this +#endif + +// +// M3/M4/M5 - Spindle/Laser Control +// +#if ENABLED(SPINDLE_LASER_ENABLE) // 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_ENABLE_PIN 52 // using A6 because it already has a pull up on it + #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/trunk/Arduino/Marlin_1.1.6/pins_MKS_13.h b/trunk/Arduino/Marlin_1.1.6/pins_MKS_13.h new file mode 100644 index 00000000..07aa6581 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_MKS_13.h @@ -0,0 +1,144 @@ +/** + * 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 . + * + */ + +/** + * Arduino Mega with RAMPS v1.4 adjusted pin assignments + * + * MKS v1.3 (Extruder, Fan, Bed) + * MKS v1.3 (Extruder, Extruder, Fan, Bed) + * MKS v1.4 (Extruder, Fan, Bed) + * MKS v1.4 (Extruder, Extruder, Fan, Bed) + */ + +#if HOTENDS > 2 || E_STEPPERS > 2 + #error "MKS 1.3/1.4 supports up to 2 hotends / E-steppers. Comment out this line to continue." +#endif + +#define BOARD_NAME "MKS > v1.3" + +// +// Heaters / Fans +// +// Power outputs EFBF or EFBE +#define MOSFET_D_PIN 7 + +// +// PSU / SERVO +// +// If POWER_SUPPLY is specified, always hijack Servo 3 +// +#if POWER_SUPPLY > 0 + #define SERVO3_PIN -1 + #define PS_ON_PIN 4 +#endif + +#include "pins_RAMPS.h" + +// +// LCD / Controller +// +#if ENABLED(VIKI2) || ENABLED(miniVIKI) + /** + * VIKI2 Has two groups of wires with... + * + * +Vin + Input supply, requires 120ma for LCD and mSD card + * GND Ground Pin + * MOSI Data input for LCD and SD + * MISO Data output for SD + * SCK Clock for LCD and SD + * AO Reg. Sel for LCD + * LCS Chip Select for LCD + * SDCS Chip Select for SD + * SDCD Card Detect pin for SD + * ENCA Encoder output A + * ENCB Encoder output B + * ENCBTN Encoder button switch + * + * BTN Panel mounted button switch + * BUZZER Piezo buzzer + * BLUE-LED Blue LED ring pin (3 to 5v, mosfet buffered) + * RED-LED Red LED ring pin (3 to 5v, mosfet buffered) + * + * This configuration uses the following arrangement: + * + * EXP1 D37 = EN2 D35 = EN1 EXP2 D50 = MISO D52 = SCK + * D17 = BLUE D16 = RED D31 = ENC D53 = SDCS + * D23 = KILL D25 = BUZZ D33 = --- D51 = MOSI + * D27 = A0 D29 = LCS D49 = SDCD RST = --- + * GND = GND 5V = 5V GND = --- D41 = --- + */ + + #undef BTN_EN1 + #undef BTN_EN2 + #undef BTN_ENC + #undef DOGLCD_A0 + #undef DOGLCD_CS + #undef SD_DETECT_PIN + #undef BEEPER_PIN + #undef KILL_PIN + + // + // VIKI2 12-wire lead + // + + // orange/white SDCD + #define SD_DETECT_PIN 49 + + // white ENCA + #define BTN_EN1 35 + + // green ENCB + #define BTN_EN2 37 + + // purple ENCBTN + #define BTN_ENC 31 + + // brown A0 + #define DOGLCD_A0 27 + + // green/white LCS + #define DOGLCD_CS 29 + + // 50 gray MISO + // 51 yellow MOSI + // 52 orange SCK + + // blue SDCS + //#define SDSS 53 + + // + // VIKI2 4-wire lead + // + + // blue BTN + #define KILL_PIN 23 + + // green BUZZER + #define BEEPER_PIN 25 + + // yellow RED-LED + #define STAT_LED_RED_PIN 16 + + // white BLUE-LED + #define STAT_LED_BLUE_PIN 17 + +#endif diff --git a/trunk/Arduino/Marlin_1.1.6/pins_MKS_BASE.h b/trunk/Arduino/Marlin_1.1.6/pins_MKS_BASE.h new file mode 100644 index 00000000..dcf9b90f --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_MKS_BASE.h @@ -0,0 +1,50 @@ +/** + * 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 . + * + */ + +/** + * MKS BASE 1.0 – Arduino Mega2560 with RAMPS v1.4 pin assignments + * + * Rev B - Override pin definitions for CASE_LIGHT and M3/M4/M5 spindle control + */ + +#if HOTENDS > 2 || E_STEPPERS > 2 + #error "MKS BASE 1.0 supports up to 2 hotends / E-steppers. Comment out this line to continue." +#endif + +#define BOARD_NAME "MKS BASE 1.0" + +// +// Heaters / Fans +// +// Power outputs EFBF or EFBE +#define MOSFET_D_PIN 7 + +#define CASE_LIGHT_PIN 2 + +// +// M3/M4/M5 - Spindle/Laser Control +// +#define SPINDLE_LASER_PWM_PIN 2 // MUST BE HARDWARE PWM +#define SPINDLE_LASER_ENABLE_PIN 15 // Pin should have a pullup! +#define SPINDLE_DIR_PIN 19 + +#include "pins_RAMPS.h" diff --git a/trunk/Arduino/Marlin_1.1.6/pins_OMCA.h b/trunk/Arduino/Marlin_1.1.6/pins_OMCA.h new file mode 100644 index 00000000..8715efcd --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_OMCA.h @@ -0,0 +1,148 @@ +/** + * 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 . + * + */ + +/** + * Open Motion controller with enable based extruders (Final!) + * + * ATMega644 + * + * +---\/---+ + * (D 0) PB0 1| |40 PA0 (AI 0 / D31) + * (D 1) PB1 2| |39 PA1 (AI 1 / D30) + * INT2 (D 2) PB2 3| |38 PA2 (AI 2 / D29) + * PWM (D 3) PB3 4| |37 PA3 (AI 3 / D28) + * PWM (D 4) PB4 5| |36 PA4 (AI 4 / D27) + * MOSI (D 5) PB5 6| |35 PA5 (AI 5 / D26) + * MISO (D 6) PB6 7| |34 PA6 (AI 6 / D25) + * SCK (D 7) PB7 8| |33 PA7 (AI 7 / D24) + * RST 9| |32 AREF + * VCC 10| |31 GND + * GND 11| |30 AVCC + * XTAL2 12| |29 PC7 (D 23) + * XTAL1 13| |28 PC6 (D 22) + * RX0 (D 8) PD0 14| |27 PC5 (D 21) TDI + * TX0 (D 9) PD1 15| |26 PC4 (D 20) TDO + * INT0 RX1 (D 10) PD2 16| |25 PC3 (D 19) TMS + * INT1 TX1 (D 11) PD3 17| |24 PC2 (D 18) TCK + * PWM (D 12) PD4 18| |23 PC1 (D 17) SDA + * PWM (D 13) PD5 19| |22 PC0 (D 16) SCL + * PWM (D 14) PD6 20| |21 PD7 (D 15) PWM + * +--------+ + * + * REF http://sanguino.cc/hardware + */ + +/** + * Rev B 26 DEC 2016 + * + * added pointer to a current Arduino IDE extension + * + */ + +/** + * A useable Arduino IDE extension (board manager) can be found at + * https://github.com/Lauszus/Sanguino + * + * This extension has been tested on Arduino 1.6.12 & 1.8.0 + * + * Here's the JSON path: + * https://raw.githubusercontent.com/Lauszus/Sanguino/master/package_lauszus_sanguino_index.json + * + * When installing select 1.0.2 + * + * Installation instructions can be found at https://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__) + #error "Oops! Make sure you have 'Sanguino' selected from the 'Tools -> Boards' menu. (Final OMCA board)" +#endif + +#define BOARD_NAME "Final OMCA" + +// +// Limit Switches +// +#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 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 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 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) + +// +// Heaters / Fans +// +#define HEATER_0_PIN 3 // DONE PWM on RIGHT connector +#define HEATER_BED_PIN 4 + +#define FAN_PIN 14 // PWM on MIDDLE connector + +// +// Misc. Functions +// +#define SDSS 11 + +#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 UNUSED_PWM 14 // PWM on LEFT connector diff --git a/trunk/Arduino/Marlin_1.1.6/pins_OMCA_A.h b/trunk/Arduino/Marlin_1.1.6/pins_OMCA_A.h new file mode 100644 index 00000000..3686973c --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_OMCA_A.h @@ -0,0 +1,135 @@ +/** + * 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 . + * + */ + +/** + * Open Motion controller with enable based extruders (Alpha!) + * + * ATMega644 + * + * +---\/---+ + * (D 0) PB0 1| |40 PA0 (AI 0 / D31) + * (D 1) PB1 2| |39 PA1 (AI 1 / D30) + * INT2 (D 2) PB2 3| |38 PA2 (AI 2 / D29) + * PWM (D 3) PB3 4| |37 PA3 (AI 3 / D28) + * PWM (D 4) PB4 5| |36 PA4 (AI 4 / D27) + * MOSI (D 5) PB5 6| |35 PA5 (AI 5 / D26) + * MISO (D 6) PB6 7| |34 PA6 (AI 6 / D25) + * SCK (D 7) PB7 8| |33 PA7 (AI 7 / D24) + * RST 9| |32 AREF + * VCC 10| |31 GND + * GND 11| |30 AVCC + * XTAL2 12| |29 PC7 (D 23) + * XTAL1 13| |28 PC6 (D 22) + * RX0 (D 8) PD0 14| |27 PC5 (D 21) TDI + * TX0 (D 9) PD1 15| |26 PC4 (D 20) TDO + * INT0 RX1 (D 10) PD2 16| |25 PC3 (D 19) TMS + * INT1 TX1 (D 11) PD3 17| |24 PC2 (D 18) TCK + * PWM (D 12) PD4 18| |23 PC1 (D 17) SDA + * 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 + * + */ + +/** + * A useable Arduino IDE extension (board manager) can be found at + * https://github.com/Lauszus/Sanguino + * + * This extension has been tested on Arduino 1.6.12 & 1.8.0 + * + * Here's the JSON path: + * https://raw.githubusercontent.com/Lauszus/Sanguino/master/package_lauszus_sanguino_index.json + * + * When installing select 1.0.2 + * + * Installation instructions can be found at https://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. + * + */ + +#ifndef __AVR_ATmega644__ + #error "Oops! Make sure you have 'Sanguino' selected from the 'Tools -> Boards' menu." +#endif + +#define BOARD_NAME "Alpha OMCA" + +// +// Limit Switches +// +#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 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 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 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) + +// +// Heaters / Fans +// +#define HEATER_0_PIN 4 + +#define FAN_PIN 3 + +// +// Misc. Functions +// +#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/trunk/Arduino/Marlin_1.1.6/pins_PRINTRBOARD.h b/trunk/Arduino/Marlin_1.1.6/pins_PRINTRBOARD.h new file mode 100644 index 00000000..9681e095 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_PRINTRBOARD.h @@ -0,0 +1,177 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2017 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** + * Rev B 2 JUN 2017 + * + * Converted to Arduino pin numbering + */ + +/** + * 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 + * Select Teensy++ 2.0 in Arduino IDE from the 'Tools -> Boards' menu + * + * Installation instructions are at the above URL. Don't bother loading the + * libraries - they are not used with the Marlin software. + * + * Printrboard - https://github.com/scwimbush/Printrboard-HID-Arduino-IDE-Support + * + * Installation: + * + * 1. Go to the above URL, click on the "Clone or Download" button and then + * click on "Download ZIP" button. + * 2. Unzip the file, find the "printrboard" directory and then copy it to the + * hardware directory in Arduino. The Arduino hardware directory will probably + * be located in a path similar to this: C:\Program Files (x86)\Arduino\hardware. + * 3. Restart Arduino. + * 4. Select "Printrboard" from the 'Tools -> Boards' menu. + * + * Teensyduino is the most popular option. Printrboard is used if your board doesn't have + * the Teensyduino bootloader on it. + */ + +/** + * To burn the bootloader that comes with Printrboard: + * + * 1. Connect your programmer to the board. + * 2. In the Arduino IDE select "Printrboard" and then select the programmer. + * 3. In the Arduino IDE click on "burn bootloader". Don't worry about the "verify failed at 1F000" error message. + * 4. The programmer is no longer needed. Remove it. + */ + +#ifndef __AVR_AT90USB1286__ + #error "Oops! Make sure you have 'Teensy++ 2.0' or 'Printrboard' selected from the 'Tools -> Boards' menu." +#endif + +#define BOARD_NAME "Printrboard" + +#define LARGE_FLASH true + +// Disable JTAG pins so they can be used for the Extrudrboard +#define DISABLE_JTAG true + +// +// Limit Switches +// +#define X_STOP_PIN 47 // E3 +#if ENABLED(SDSUPPORT) + #define Y_STOP_PIN 37 // E5 - Move Ystop to Estop socket +#else + #define Y_STOP_PIN 20 // B0 SS - Ystop in Ystop socket +#endif +#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 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 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 + +// +// 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 FAN_PIN 16 // C6 PWM3A + +// +// Misc. Functions +// +#define SDSS 20 // B0 SS +#define FILWIDTH_PIN 2 // Analog Input + +// +// LCD / Controller +// +#if ENABLED(ULTRA_LCD) && ENABLED(NEWPANEL) + // we have no buzzer installed + #define BEEPER_PIN -1 + + // LCD Pins + #if 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 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 + #endif + + // not connected + #define SD_DETECT_PIN -1 + + #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 + +#endif // ULTRA_LCD && NEWPANEL + +#if ENABLED(VIKI2) || ENABLED(miniVIKI) + #define BEEPER_PIN 8 // E0 JP11-10 + // Pins for DOGM SPI LCD Support + #define DOGLCD_A0 40 // F2 JP2-2 + #define DOGLCD_CS 41 // F3 JP2-4 + #define LCD_SCREEN_ROT_180 + + // The encoder and click button + #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 43 // F5 TMS JP2-8 + #define SD_DETECT_PIN -1 + + #define STAT_LED_RED_PIN 12 // C2 JP11-14 + #define STAT_LED_BLUE_PIN 10 // C0 JP11-12 + +#endif diff --git a/trunk/Arduino/Marlin_1.1.6/pins_PRINTRBOARD_REVF.h b/trunk/Arduino/Marlin_1.1.6/pins_PRINTRBOARD_REVF.h new file mode 100644 index 00000000..0f1772c8 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_PRINTRBOARD_REVF.h @@ -0,0 +1,219 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2017 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** + * Rev B 2 JUN 2017 + * + * Converted to Arduino pin numbering + */ + +/** + * 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 + * Installation instructions are at the above URL. + * + * Select Teensy++ 2.0 in Arduino IDE from the 'Tools -> Boards' menu + * + * Note: With Teensyduino extension, the Arduino IDE will report 130048 bytes of program storage space available, + * but there is actually only 122880 bytes due to the larger DFU bootloader shipped by default on all Printrboard RevF. + * + * Printrboard - https://github.com/scwimbush/Printrboard-HID-Arduino-IDE-Support + * + * Installation: + * + * 1. Go to the above URL, click on the "Clone or Download" button and then + * click on "Download ZIP" button. + * 2. Unzip the file, find the "printrboard" directory and then copy it to the + * hardware directory in Arduino. The Arduino hardware directory will probably + * be located in a path similar to this: C:\Program Files (x86)\Arduino\hardware. + * 3. Restart Arduino. + * 4. Select "Printrboard" from the 'Tools -> Boards' menu. + * + * Teensyduino is the most popular and easiest option. + */ + +/** + * To burn the bootloader that comes with Printrboard HID extension: + * + * 1. Connect your programmer to the board. + * 2. In the Arduino IDE select "Printrboard" and then select the programmer. + * 3. In the Arduino IDE click on "burn bootloader". Don't worry about the "verify failed at 1F000" error message. + * 4. The programmer is no longer needed. Remove it. + */ + +#ifndef __AVR_AT90USB1286__ + #error "Oops! Make sure you have 'Teensy++ 2.0' or 'Printrboard' selected from the 'Tools -> Boards' menu." +#endif + +#define BOARD_NAME "Printrboard Rev F" +#define LARGE_FLASH true + +// +// Limit Switches +// +#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 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 E0_STEP_PIN 34 // A6 +#define E0_DIR_PIN 35 // A7 +#define E0_ENABLE_PIN 13 // C3 + +// Enable control of stepper motor currents with the I2C based MCP4728 DAC used on Printrboard REVF +#define DAC_STEPPER_CURRENT + +// Set default drive strength percents if not already defined - X, Y, Z, E axis +#ifndef DAC_MOTOR_CURRENT_DEFAULT + #define DAC_MOTOR_CURRENT_DEFAULT { 70, 70, 50, 70 } +#endif + +// Number of channels available for DAC +#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 + +// +// Temperature Sensors +// +#define TEMP_0_PIN 1 // Analog Input (Extruder) +#define TEMP_BED_PIN 0 // Analog Input (Bed) + +// +// 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 FAN_PIN 16 // C6 PWM3A + +// +// LCD / Controller +// +//#define USE_INTERNAL_SD + +#if ENABLED(ULTRA_LCD) + #define BEEPER_PIN -1 + + #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 BTN_EN1 10 // C0 JP11-12 + #define BTN_EN2 11 // C1 JP11-13 + #define BTN_ENC 12 // C2 JP11-14 + + #define SD_DETECT_PIN -1 +#endif + +#if ENABLED(VIKI2) || ENABLED(miniVIKI) + #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 SDSS 43 // F5 TMS JP2-8 + #define SD_DETECT_PIN -1 + + #define STAT_LED_RED_PIN 12 // C2 JP11-14 + #define STAT_LED_BLUE_PIN 10 // C0 JP11-12 +#endif + +#if ENABLED(MINIPANEL) + #if ENABLED(USE_INTERNAL_SD) + // PIN FASTIO PIN# ATUSB90 PIN# Teensy2.0++ PIN# + #define SDSS 20 // 10 B0 + #define SD_DETECT_PIN -1 // no auto-detect SD insertion on built-in Printrboard SD reader + #else + // 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 + #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 + + // encoder connections present + #define BLEN_A 0 + #define BLEN_B 1 + #define BLEN_C 2 + + // encoder rotation values + #define encrot0 0 + #define encrot1 2 + #define encrot2 3 + #define encrot3 1 + + // increase delays to max + #define ST7920_DELAY_1 DELAY_5_NOP + #define ST7920_DELAY_2 DELAY_5_NOP + #define ST7920_DELAY_3 DELAY_5_NOP +#endif + +// +// Misc. Functions +// +#ifndef SDSS + #define SDSS 20 // B0 SS +#endif + +#define FILWIDTH_PIN 2 // Analog Input diff --git a/trunk/Arduino/Marlin_1.1.6/pins_RAMBO.h b/trunk/Arduino/Marlin_1.1.6/pins_RAMBO.h new file mode 100644 index 00000000..6ddd305e --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_RAMBO.h @@ -0,0 +1,228 @@ +/** + * 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 . + * + */ + +/** + * IMPORTANT NOTE: + * Rambo users should be sure to compile Marlin using either the RAMBo + * board type if using the Arduino IDE - available via the link below - or + * the 'rambo' environment if using platformio, by specifying '-e rambo' on + * the command line or by changing the value of the 'env_default' variable to + * 'rambo' in the supplied platformio.ini. + * + * If you don't compile using the proper board type, the RAMBo's extended + * pins will likely be unavailable and accessories/addons may not work. + * + * Instructions for installing the Arduino RAMBo board type for the + * Arduino IDE are available at: + * http://reprap.org/wiki/Rambo_firmware + */ + +/** + * Rambo pin assignments + */ + +#ifndef __AVR_ATmega2560__ + #error "Oops! Make sure you have 'Arduino Mega 2560' selected from the 'Tools -> Boards' menu." +#endif + +#define BOARD_NAME "Rambo" + +#define LARGE_FLASH true + +// +// 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 + +// +// Z Probe (when not Z_MIN_PIN) +// +#ifndef Z_MIN_PROBE_PIN + #define Z_MIN_PROBE_PIN 30 +#endif + +// +// 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 + +// +// Steppers +// +#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 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 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 + +// +// Temperature Sensors +// +#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 FAN_PIN 8 +#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 + +#ifndef FILWIDTH_PIN + #define FILWIDTH_PIN 3 // Analog Input +#endif + +// +// M3/M4/M5 - Spindle/Laser Control +// +#define SPINDLE_LASER_PWM_PIN 45 // MUST BE HARDWARE PWM +#define SPINDLE_LASER_ENABLE_PIN 31 // Pin should have a pullup! +#define SPINDLE_DIR_PIN 32 + +// +// 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 + +// +// LCD / Controller +// +#if ENABLED(ULTRA_LCD) + + #define KILL_PIN 80 + + #if ENABLED(NEWPANEL) + + #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 ENABLED(VIKI2) || ENABLED(miniVIKI) + #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 LCD_SCREEN_ROT_180 + + #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 STAT_LED_RED_PIN 22 + #define STAT_LED_BLUE_PIN 32 + + #else + + #define BEEPER_PIN 79 // AUX-4 + + // AUX-2 + #define BTN_EN1 76 + #define BTN_EN2 77 + #define BTN_ENC 78 + + #define SD_DETECT_PIN 81 + + #endif // VIKI2/miniVIKI + + #else // !NEWPANEL - old style panel with shift register + + // No Beeper added + #define BEEPER_PIN 33 + + // buttons are 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 + + #endif // !NEWPANEL + +#endif // ULTRA_LCD diff --git a/trunk/Arduino/Marlin_1.1.6/pins_RAMPS.h b/trunk/Arduino/Marlin_1.1.6/pins_RAMPS.h new file mode 100644 index 00000000..b0f66d01 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_RAMPS.h @@ -0,0 +1,485 @@ +/** + * 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 . + * + */ + +/** + * Arduino Mega with RAMPS v1.4 (or v1.3) pin assignments + * + * Applies to the following boards: + * + * RAMPS_14_EFB (Hotend, Fan, Bed) + * RAMPS_14_EEB (Hotend0, Hotend1, Bed) + * RAMPS_14_EFF (Hotend, Fan0, Fan1) + * RAMPS_14_EEF (Hotend0, Hotend1, Fan) + * RAMPS_14_SF (Spindle, Controller Fan) + * + * RAMPS_13_EFB (Hotend, Fan, Bed) + * RAMPS_13_EEB (Hotend0, Hotend1, Bed) + * RAMPS_13_EFF (Hotend, Fan0, Fan1) + * RAMPS_13_EEF (Hotend0, Hotend1, Fan) + * RAMPS_13_SF (Spindle, Controller Fan) + * + * Other pins_MYBOARD.h files may override these defaults + * + * Differences between + * RAMPS_13 | RAMPS_14 + * 7 | 11 + */ + +#if !defined(__AVR_ATmega1280__) && !defined(__AVR_ATmega2560__) + #error "Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu." +#endif + +#ifndef BOARD_NAME + #define BOARD_NAME "RAMPS 1.4" +#endif + +#define LARGE_FLASH true + +// +// Servos +// +#ifdef IS_RAMPS_13 + #define SERVO0_PIN 7 // RAMPS_13 // Will conflict with BTN_EN2 on LCD_I2C_VIKI +#else + #define SERVO0_PIN 11 +#endif +#define SERVO1_PIN 6 +#define SERVO2_PIN 5 +#ifndef SERVO3_PIN + #define SERVO3_PIN 4 +#endif + +// +// Limit Switches +// +#define X_MIN_PIN 3 +#ifndef X_MAX_PIN + #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 + +// +// Z Probe (when not Z_MIN_PIN) +// +#ifndef Z_MIN_PROBE_PIN + #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_CS_PIN 53 + +#define Y_STEP_PIN 60 +#define Y_DIR_PIN 61 +#define Y_ENABLE_PIN 56 +#define Y_CS_PIN 49 + +#define Z_STEP_PIN 46 +#define Z_DIR_PIN 48 +#define Z_ENABLE_PIN 62 +#define Z_CS_PIN 40 + +#define E0_STEP_PIN 26 +#define E0_DIR_PIN 28 +#define E0_ENABLE_PIN 24 +#define E0_CS_PIN 42 + +#define E1_STEP_PIN 36 +#define E1_DIR_PIN 34 +#define E1_ENABLE_PIN 30 +#define E1_CS_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 66 // Do not use pin 53 if there is even the remote possibility of using Display/SD card +#else + #define MAX6675_SS 66 // Do not 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 + +// +// Augmentation for auto-assigning RAMPS plugs +// +#if DISABLED(IS_RAMPS_EEB) && DISABLED(IS_RAMPS_EEF) && DISABLED(IS_RAMPS_EFB) && DISABLED(IS_RAMPS_EFF) && DISABLED(IS_RAMPS_SF) && !PIN_EXISTS(MOSFET_D) + #if HOTENDS > 1 + #if TEMP_SENSOR_BED + #define IS_RAMPS_EEB + #else + #define IS_RAMPS_EEF + #endif + #elif TEMP_SENSOR_BED + #define IS_RAMPS_EFB + #else + #define IS_RAMPS_EFF + #endif +#endif + +// +// Heaters / Fans +// +#ifndef MOSFET_D_PIN + #define MOSFET_D_PIN -1 +#endif +#ifndef RAMPS_D8_PIN + #define RAMPS_D8_PIN 8 +#endif +#ifndef RAMPS_D9_PIN + #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 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 + #else + #define HEATER_1_PIN MOSFET_D_PIN + #endif +#endif + +#ifndef FAN_PIN + #define FAN_PIN 4 // IO pin. Buffer needed +#endif + +// +// Misc. Functions +// +#define SDSS 53 +#define LED_PIN 13 + +#ifndef FILWIDTH_PIN + #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 +#define FIL_RUNOUT_PIN 4 + +#ifndef PS_ON_PIN + #define PS_ON_PIN 12 +#endif + +#if ENABLED(CASE_LIGHT_ENABLE) && !PIN_EXISTS(CASE_LIGHT) && !defined(SPINDLE_LASER_ENABLE_PIN) + #if !defined(NUM_SERVOS) || NUM_SERVOS == 0 // try to use servo connector first + #define CASE_LIGHT_PIN 6 // MUST BE HARDWARE PWM + #elif !(ENABLED(ULTRA_LCD) && ENABLED(NEWPANEL) \ + && (ENABLED(PANEL_ONE) || ENABLED(VIKI2) || ENABLED(miniVIKI) || ENABLED(MINIPANEL) || ENABLED(REPRAPWORLD_KEYPAD))) // try to use AUX 2 + #define CASE_LIGHT_PIN 44 // MUST BE HARDWARE PWM + #endif +#endif + +// +// M3/M4/M5 - Spindle/Laser Control +// +#if ENABLED(SPINDLE_LASER_ENABLE) && !PIN_EXISTS(SPINDLE_LASER_ENABLE) + #if !defined(NUM_SERVOS) || NUM_SERVOS == 0 // try to use servo connector first + #define SPINDLE_LASER_ENABLE_PIN 4 // Pin should have a pullup/pulldown! + #define SPINDLE_LASER_PWM_PIN 6 // MUST BE HARDWARE PWM + #define SPINDLE_DIR_PIN 5 + #elif !(ENABLED(ULTRA_LCD) && ENABLED(NEWPANEL) \ + && (ENABLED(PANEL_ONE) || ENABLED(VIKI2) || ENABLED(miniVIKI) || ENABLED(MINIPANEL) || ENABLED(REPRAPWORLD_KEYPAD))) // try to use AUX 2 + #define SPINDLE_LASER_ENABLE_PIN 40 // Pin should have a pullup/pulldown! + #define SPINDLE_LASER_PWM_PIN 44 // MUST BE HARDWARE PWM + #define SPINDLE_DIR_PIN 65 + #endif +#endif + +// +// Průša i3 MK2 Multiplexer Support +// +#ifndef E_MUX0_PIN + #define E_MUX0_PIN 40 // Z_CS_PIN +#endif +#ifndef E_MUX1_PIN + #define E_MUX1_PIN 42 // E0_CS_PIN +#endif +#ifndef E_MUX2_PIN + #define E_MUX2_PIN 44 // E1_CS_PIN +#endif + +////////////////////////// +// LCDs and Controllers // +////////////////////////// + +#if ENABLED(ULTRA_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 + + #elif ENABLED(NEWPANEL) && ENABLED(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 + + #else + + #if ENABLED(CR10_STOCKDISPLAY) + + #define LCD_PINS_RS 27 + #define LCD_PINS_ENABLE 29 + #define LCD_PINS_D4 25 + + #if DISABLED(NEWPANEL) + #define BEEPER_PIN 37 + #endif + + #else + + #if ENABLED(MKS_12864OLED) + #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 + #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 + #endif + + #define LCD_PINS_D7 29 + + #if DISABLED(NEWPANEL) + #define BEEPER_PIN 33 + #endif + + #endif + + #if DISABLED(NEWPANEL) + // Buttons are 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 + + // + // LCD Display input pins + // + #if ENABLED(NEWPANEL) + + #if ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER) + + #define BEEPER_PIN 37 + + #if ENABLED(CR10_STOCKDISPLAY) + #define BTN_EN1 17 + #define BTN_EN2 23 + #else + #define BTN_EN1 31 + #define BTN_EN2 33 + #endif + + #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 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 ENABLED(VIKI2) || ENABLED(miniVIKI) + + #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 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 + + #elif ENABLED(ELB_FULL_GRAPHIC_CONTROLLER) + + #define DOGLCD_CS 29 + #define DOGLCD_A0 27 + + #define BEEPER_PIN 23 + #define LCD_BACKLIGHT_PIN 33 + + #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 + + #elif ENABLED(MKS_MINI_12864) // Added in Marlin 1.1.6 + + #define DOGLCD_A0 27 + #define DOGLCD_CS 25 + + // GLCD features + //#define LCD_CONTRAST 190 + // Uncomment screen orientation + //#define LCD_SCREEN_ROT_90 + //#define LCD_SCREEN_ROT_180 + //#define LCD_SCREEN_ROT_270 + + #define BEEPER_PIN 37 + // not connected to a pin + #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 + + #elif ENABLED(MINIPANEL) + + #define BEEPER_PIN 42 + // not connected to a pin + #define LCD_BACKLIGHT_PIN 65 // backlight LED on A11/D65 + + #define DOGLCD_A0 44 + #define DOGLCD_CS 66 + + // GLCD features + //#define LCD_CONTRAST 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 SDSS 53 + #define SD_DETECT_PIN 49 + #define KILL_PIN 64 + + #else + + // Beeper on AUX-4 + #define BEEPER_PIN 33 + + // Buttons are directly attached using 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 + #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 + #endif + + #endif + #endif // NEWPANEL + +#endif // ULTRA_LCD diff --git a/trunk/Arduino/Marlin_1.1.6/pins_RAMPS_13.h b/trunk/Arduino/Marlin_1.1.6/pins_RAMPS_13.h new file mode 100644 index 00000000..effce907 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_RAMPS_13.h @@ -0,0 +1,41 @@ +/** + * 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 . + * + */ + +/** + * Arduino Mega with RAMPS v1.3 pin assignments + * + * Applies to the following boards: + * + * RAMPS_13_EFB (Extruder, Fan, Bed) + * RAMPS_13_EEB (Extruder, Extruder, Bed) + * RAMPS_13_EFF (Extruder, Fan, Fan) + * RAMPS_13_EEF (Extruder, Extruder, Fan) + * RAMPS_13_SF (Spindle, Controller Fan) + * + */ + +#ifndef BOARD_NAME + #define BOARD_NAME "RAMPS 1.3" +#endif + +#define IS_RAMPS_13 +#include "pins_RAMPS.h" diff --git a/trunk/Arduino/Marlin_1.1.6/pins_RAMPS_OLD.h b/trunk/Arduino/Marlin_1.1.6/pins_RAMPS_OLD.h new file mode 100644 index 00000000..870f2fbd --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_RAMPS_OLD.h @@ -0,0 +1,111 @@ +/** + * 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 . + * + */ + +/** + * Arduino Mega with RAMPS v1.0, v1.1, v1.2 pin assignments + */ + +#if !defined(__AVR_ATmega1280__) && !defined(__AVR_ATmega2560__) + #error "Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu." +#endif + +#define BOARD_NAME "MEGA/RAMPS <1.2" + +// Uncomment the following line for RAMPS v1.0 +//#define RAMPS_V_1_0 + +// +// 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 + +// +// Z Probe (when not Z_MIN_PIN) +// +#ifndef Z_MIN_PROBE_PIN + #define Z_MIN_PROBE_PIN 19 +#endif + +// +// Steppers +// +#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 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 + +// +// Temperature Sensors +// +#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 66 // Do not use pin 53 if there is even the remote possibility of using Display/SD card +#else + #define MAX6675_SS 66 // Do not 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 +// +#if ENABLED(RAMPS_V_1_0) + #define HEATER_0_PIN 12 + #define HEATER_BED_PIN -1 + #define FAN_PIN 11 +#else // RAMPS_V_1_1 or RAMPS_V_1_2 + #define HEATER_0_PIN 10 + #define HEATER_BED_PIN 8 + #define FAN_PIN 9 +#endif + +// +// Misc. Functions +// +#define SDPOWER 48 +#define SDSS 53 +#define LED_PIN 13 +#define CASE_LIGHT_PIN 45 // MUST BE HARDWARE PWM + +// +// M3/M4/M5 - Spindle/Laser Control +// +#define SPINDLE_LASER_ENABLE_PIN 41 // Pin should have a pullup/pulldown! +#define SPINDLE_LASER_PWM_PIN 45 // MUST BE HARDWARE PWM +#define SPINDLE_DIR_PIN 43 diff --git a/trunk/Arduino/Marlin_1.1.6/pins_RIGIDBOARD.h b/trunk/Arduino/Marlin_1.1.6/pins_RIGIDBOARD.h new file mode 100644 index 00000000..5bd06e40 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_RIGIDBOARD.h @@ -0,0 +1,133 @@ +/** + * 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 . + * + */ + +/** + * RIGIDBOARD Arduino Mega with RAMPS v1.4 pin assignments + */ + +#define BOARD_NAME "RigidBoard" + +// +// Z Probe (when not Z_MIN_PIN) +// +#ifndef Z_MIN_PROBE_PIN + #define Z_MIN_PROBE_PIN 19 // Z-MAX pin J14 End Stops +#endif + +// +// MOSFET changes +// +#define RAMPS_D10_PIN 9 // EXTRUDER 1 +#define MOSFET_D_PIN 12 // EXTRUDER 2 or FAN + +#include "pins_RAMPS.h" + +// +// Steppers +// +// RigidBot swaps E0 / E1 plugs vs RAMPS 1.3 +#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 + +#define STEPPER_RESET_PIN 41 // Stepper drivers have a reset on RigidBot + +// +// Temperature Sensors +// +#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 + +// SPI for Max6675 or Max31855 Thermocouple +#undef MAX6675_SS +#if DISABLED(SDSUPPORT) + #define MAX6675_SS 53 // Don't use pin 53 if there is even the remote possibility of using Display/SD card +#else + #define MAX6675_SS 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 + +#undef FAN_PIN +#define FAN_PIN 8 // Same as RAMPS_13_EEF + +// +// Misc. Functions +// +#undef PS_ON_PIN +#define PS_ON_PIN -1 + +// +// LCD / Controller +// +// LCD Panel options for the RigidBoard +#if ENABLED(RIGIDBOT_PANEL) + + #undef BEEPER_PIN + #define BEEPER_PIN -1 + + // Direction buttons + #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 + + // 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 + +#elif ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER) + + #undef SD_DETECT_PIN + #define SD_DETECT_PIN 22 + + #undef KILL_PIN + #define KILL_PIN 32 + +#endif diff --git a/trunk/Arduino/Marlin_1.1.6/pins_RIGIDBOARD_V2.h b/trunk/Arduino/Marlin_1.1.6/pins_RIGIDBOARD_V2.h new file mode 100644 index 00000000..dfac7051 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_RIGIDBOARD_V2.h @@ -0,0 +1,52 @@ +/** + * 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 . + * + */ + +/** + * RIGIDBOARD V2 Arduino Mega with RAMPS v1.4 pin assignments + */ + +#include "pins_RIGIDBOARD.h" + +#undef BOARD_NAME +#define BOARD_NAME "RigidBoard V2" + +// +// Steppers +// + +// I2C based DAC like on the Printrboard REVF +#define DAC_STEPPER_CURRENT + +// 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 + +#ifndef DAC_MOTOR_CURRENT_DEFAULT + #define DAC_MOTOR_CURRENT_DEFAULT { 70, 80, 90, 80 } // Default drive percent - X, Y, Z, E axis +#endif diff --git a/trunk/Arduino/Marlin_1.1.6/pins_RUMBA.h b/trunk/Arduino/Marlin_1.1.6/pins_RUMBA.h new file mode 100644 index 00000000..5f567783 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_RUMBA.h @@ -0,0 +1,158 @@ +/** + * 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 . + * + */ + +/** + * RUMBA pin assignments + */ + +#ifndef __AVR_ATmega2560__ + #error "Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu." +#endif + +#if HOTENDS > 3 || E_STEPPERS > 3 + #error "RUMBA supports up to 3 hotends / E-steppers. Comment out this line to continue." +#endif + +#define DEFAULT_MACHINE_NAME "Rumba" +#define BOARD_NAME "Rumba" + +// +// Servos +// +#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 + +// +// Z Probe (when not Z_MIN_PIN) +// +#ifndef Z_MIN_PROBE_PIN + #define Z_MIN_PROBE_PIN 32 +#endif + +// +// Steppers +// +#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 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 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 + +// +// Temperature Sensors +// +#if TEMP_SENSOR_0 == -1 + #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) +#endif + +#if TEMP_SENSOR_1 == -1 + #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) +#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) +#else + #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) + +#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) +#else + #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 FAN_PIN 7 +#define FAN1_PIN 8 + +// +// Misc. Functions +// +#define SDSS 53 +#define LED_PIN 13 +#define PS_ON_PIN 45 +#define KILL_PIN 46 +#define CASE_LIGHT_PIN 45 + +// +// LCD / Controller +// +#define SD_DETECT_PIN 49 +#define BEEPER_PIN 44 +#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 BTN_EN1 11 +#define BTN_EN2 12 +#define BTN_ENC 43 + +// +// M3/M4/M5 - Spindle/Laser Control +// +#define SPINDLE_LASER_PWM_PIN 4 // MUST BE HARDWARE PWM +#define SPINDLE_LASER_ENABLE_PIN 14 // Pin should have a pullup! +#define SPINDLE_DIR_PIN 15 diff --git a/trunk/Arduino/Marlin_1.1.6/pins_SAINSMART_2IN1.h b/trunk/Arduino/Marlin_1.1.6/pins_SAINSMART_2IN1.h new file mode 100644 index 00000000..bf01a9e0 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_SAINSMART_2IN1.h @@ -0,0 +1,41 @@ +/** + * 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 . + * + */ + +/** + * Sainsmart 2-in-1 pin assignments + */ + +#if HOTENDS > 2 || E_STEPPERS > 2 + #error "Sainsmart 2-in-1 supports up to 2 hotends / E-steppers. Comment out this line to continue." +#endif + +#define BOARD_NAME "Sainsmart" + +// +// Heaters / Fans +// +#define RAMPS_D10_PIN 9 // E +#define RAMPS_D9_PIN 7 // F PART FAN in front of board next to Extruder heat + // RAMPS_D8_PIN 8 // B +#define MOSFET_D_PIN 10 // F / E + +#include "pins_RAMPS.h" diff --git a/trunk/Arduino/Marlin_1.1.6/pins_SANGUINOLOLU_11.h b/trunk/Arduino/Marlin_1.1.6/pins_SANGUINOLOLU_11.h new file mode 100644 index 00000000..0506d78c --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_SANGUINOLOLU_11.h @@ -0,0 +1,310 @@ +/** + * 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 . + * + */ + +/** + * Sanguinololu board pin assignments + */ + +/** + * Rev B 26 DEC 2016 + * + * 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 + * + */ + +/** + * A useable Arduino IDE extension (board manager) can be found at + * https://github.com/Lauszus/Sanguino + * + * This extension has been tested on Arduino 1.6.12 & 1.8.0 + * + * Here's the JSON path: + * https://raw.githubusercontent.com/Lauszus/Sanguino/master/package_lauszus_sanguino_index.json + * + * When installing select 1.0.2 + * + * Installation instructions can be found at https://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_ATmega1284P__) + #error "Oops! Make sure you have 'Sanguino' selected from the 'Tools -> Boards' menu." +#endif + +#ifndef BOARD_NAME + #define BOARD_NAME "Sanguinololu <1.2" +#endif + +#ifdef __AVR_ATmega1284P__ + #define LARGE_FLASH true +#endif + +// +// Limit Switches +// +#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 Y_STEP_PIN 22 +#define Y_DIR_PIN 23 + +#define Z_STEP_PIN 3 +#define Z_DIR_PIN 2 + +#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) + +// +// Heaters / Fans +// +#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 + + #if ENABLED(LCD_I2C_PANELOLU2) + #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 + +#endif + +#if MB(AZTEEG_X1) || MB(STB_11) || ENABLED(IS_MELZI) + #define FAN_PIN 4 // Works for Panelolu2 too +#endif + +// +// Misc. Functions +// + +/** + * In some versions of the Sanguino libraries the pin + * definitions are wrong, with SDSS = 24 and LED_PIN = 28 (Melzi). + * If you encounter issues with these pins, upgrade your + * Sanguino libraries! See #368. + */ +//#define SDSS 24 +#define SDSS 31 + +#if ENABLED(IS_MELZI) + #define LED_PIN 27 +#elif MB(STB_11) + #define LCD_BACKLIGHT_PIN 17 // LCD backlight LED +#endif + +#if DISABLED(SPINDLE_LASER_ENABLE) && ENABLED(SANGUINOLOLU_V_1_2) && !(ENABLED(ULTRA_LCD) && ENABLED(NEWPANEL)) // try to use IO Header + #define CASE_LIGHT_PIN 4 // MUST BE HARDWARE PWM - see if IO Header is available +#endif + +/** + * Sanguinololu 1.4 AUX pins: + * + * PWM TX1 RX1 SDA SCL + * 12V 5V D12 D11 D10 D17 D16 + * GND GND D31 D30 D29 D28 D27 + * A4 A3 A2 A1 A0 + */ + +// +// LCD / Controller +// +#if ENABLED(ULTRA_LCD) && ENABLED(NEWPANEL) + + #if ENABLED(DOGLCD) + + #if ENABLED(U8GLIB_ST7920) // SPI GLCD 12864 ST7920 ( like [www.digole.com] ) For Melzi V2.0 + + #if ENABLED(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 + // 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 + #endif + + #else // DOGM SPI LCD Support + + #define DOGLCD_A0 30 + #define LCD_CONTRAST 1 + + #if ENABLED(MAKRPANEL) + + #define BEEPER_PIN 29 + #define DOGLCD_CS 17 + #define LCD_BACKLIGHT_PIN 28 // PA3 + + #else // !MAKRPANEL + + #define DOGLCD_CS 29 + + #endif + + #endif + + // Uncomment screen orientation + #define LCD_SCREEN_ROT_0 + //#define LCD_SCREEN_ROT_90 + //#define LCD_SCREEN_ROT_180 + //#define LCD_SCREEN_ROT_270 + + #else // !DOGLCD + + #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 // !DOGLCD + + #define BTN_EN1 11 + #define BTN_EN2 10 + + #if ENABLED(LCD_I2C_PANELOLU2) + + #if ENABLED(IS_MELZI) + #define BTN_ENC 29 + #define LCD_SDSS 30 // Panelolu2 SD card reader rather than the Melzi + #else + #define BTN_ENC 30 + #endif + + #elif ENABLED(LCD_FOR_MELZI) + + #define LCD_PINS_RS 17 + #define LCD_PINS_ENABLE 16 + #define LCD_PINS_D4 11 + #define BTN_ENC 28 + #define BTN_EN1 29 + #define BTN_EN2 30 + + #ifndef ST7920_DELAY_1 + #define ST7920_DELAY_1 DELAY_0_NOP + #endif + #ifndef ST7920_DELAY_2 + #define ST7920_DELAY_2 DELAY_3_NOP + #endif + #ifndef ST7920_DELAY_3 + #define ST7920_DELAY_3 DELAY_0_NOP + #endif + + #else // !LCD_I2C_PANELOLU2 && !LCD_FOR_MELZI + + #define BTN_ENC 16 + #define LCD_SDSS 28 // Smart Controller SD card reader rather than the Melzi + + #endif + + #define SD_DETECT_PIN -1 + +#endif // ULTRA_LCD && NEWPANEL + +// +// M3/M4/M5 - Spindle/Laser Control +// +#if ENABLED(SPINDLE_LASER_ENABLE) + #if !MB(AZTEEG_X1) && ENABLED(SANGUINOLOLU_V_1_2) && !(ENABLED(ULTRA_LCD) && ENABLED(NEWPANEL)) // try to use IO Header + + #define SPINDLE_LASER_ENABLE_PIN 10 // Pin should have a pullup/pulldown! + #define SPINDLE_LASER_PWM_PIN 4 // MUST BE HARDWARE PWM + #define SPINDLE_DIR_PIN 11 + + #elif !MB(MELZI) // use X stepper motor socket + + /** + * To control the spindle speed and have an LCD you must sacrifice + * the Extruder and pull some signals off the X stepper driver socket. + * + * The following assumes: + * - The X stepper driver socket is empty + * - The extruder driver socket has a driver board plugged into it + * - The X stepper wires are attached the the extruder connector + */ + + /** + * Where to get the spindle signals + * + * spindle signal socket name socket name + * ------- + * /ENABLE O| |O VMOT + * MS1 O| |O GND + * MS2 O| |O 2B + * MS3 O| |O 2A + * /RESET O| |O 1A + * /SLEEP O| |O 1B + * SPINDLE_LASER_PWM_PIN STEP O| |O VDD + * SPINDLE_LASER_ENABLE_PIN DIR O| |O GND + * ------- + * + * Note: Socket names vary from vendor to vendor. + */ + #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 // MUST BE HARDWARE PWM + #define SPINDLE_LASER_ENABLE_PIN 21 // Pin should have a pullup! + #define SPINDLE_DIR_PIN -1 // No pin available on the socket for the direction pin + #endif +#endif // SPINDLE_LASER_ENABLE diff --git a/trunk/Arduino/Marlin_1.1.6/pins_SANGUINOLOLU_12.h b/trunk/Arduino/Marlin_1.1.6/pins_SANGUINOLOLU_12.h new file mode 100644 index 00000000..f648dce0 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_SANGUINOLOLU_12.h @@ -0,0 +1,41 @@ +/** + * 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 . + * + */ + +/** + * Sanguinololu V1.2 pin assignments + * + * Applies to the following boards: + * + * AZTEEG_X1 + * MELZI + * MELZI_CREALITY + * MELZI_MAKR3D + * SANGUINOLOLU_12 + * STB_11 + */ + +#ifndef BOARD_NAME + #define BOARD_NAME "Sanguinololu 1.2" +#endif + +#define SANGUINOLOLU_V_1_2 +#include "pins_SANGUINOLOLU_11.h" diff --git a/trunk/Arduino/Marlin_1.1.6/pins_SAV_MKI.h b/trunk/Arduino/Marlin_1.1.6/pins_SAV_MKI.h new file mode 100644 index 00000000..aecd58af --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_SAV_MKI.h @@ -0,0 +1,184 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2017 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** + * Rev B 2 JUN 2017 + * + * Converted to Arduino pin numbering + */ + +/** + * 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 + * Select Teensy++ 2.0 in Arduino IDE from the 'Tools -> Boards' menu + * + * Installation instructions are at the above URL. Don't bother loading the + * libraries - they are not used with the Marlin software. + * + * Printrboard - https://github.com/scwimbush/Printrboard-HID-Arduino-IDE-Support + * + * Installation: + * + * 1. Go to the above URL, click on the "Clone or Download" button and then + * click on "Download ZIP" button. + * 2. Unzip the file, find the "printrboard" directory and then copy it to the + * hardware directory in Arduino. The Arduino hardware directory will probably + * be located in a path similar to this: C:\Program Files (x86)\Arduino\hardware. + * 3. Restart Arduino. + * 4. Select "Printrboard" from the 'Tools -> Boards' menu. + * + * Teensyduino is the most popular option. Printrboard is used if your board doesn't have + * the Teensyduino bootloader on it. + */ + +/** + * To burn the bootloader that comes with Printrboard: + * + * 1. Connect your programmer to the board. + * 2. In the Arduino IDE select "Printrboard" and then select the programmer. + * 3. In the Arduino IDE click on "burn bootloader". Don't worry about the "verify failed at 1F000" error message. + * 4. The programmer is no longer needed. Remove it. + */ + +#ifndef __AVR_AT90USB1286__ + #error "Oops! Make sure you have 'Teensy++ 2.0' or 'Printrboard' selected from the 'Tools -> Boards' menu." +#endif + +#define DEFAULT_MACHINE_NAME "SAV MkI" +#define DEFAULT_SOURCE_CODE_URL "https://github.com/fmalpartida/Marlin/tree/SAV-MkI-config" +#define BOARD_NAME "SAV MkI" + +#define LARGE_FLASH true + +// +// Servos +// +#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 + +// +// Steppers +// +#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 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 + +// +// Temperature Sensors +// +#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 FAN_PIN 16 // C6 PWM3A + +// +// Misc. Functions +// +#define SDSS 20 // B0 + +// Extension header pin mapping +// ---------------------------- +// SCL (I2C)-D0 A0 (An), IO +// SDA (I2C)-D1 A1 (An), IO +// RX1-D2 A2 (An), IO +// TX1-D3 A3 (An), IO +// 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 + +// +// LCD / Controller +// +#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 +#endif + +#if ENABLED(SAV_3DLCD) || ENABLED(SAV_3DGLCD) + + #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 + +#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_ENABLE_PIN 39 // F1 Pin should have a pullup! + #define SPINDLE_DIR_PIN 40 // F2 + + #define CASE_LIGHT_PIN 0 // D0 PWM0B + +#endif diff --git a/trunk/Arduino/Marlin_1.1.6/pins_SCOOVO_X9H.h b/trunk/Arduino/Marlin_1.1.6/pins_SCOOVO_X9H.h new file mode 100644 index 00000000..6b7cf4f8 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_SCOOVO_X9H.h @@ -0,0 +1,158 @@ +/** + * 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 . + * + */ + +/************************************************ + * Rambo pin assignments MODIFIED FOR Scoovo X9H + ************************************************/ + +#ifndef __AVR_ATmega2560__ + #error "Oops! Make sure you have 'Arduino Mega 2560' selected from the 'Tools -> Boards' menu." +#endif + +#define BOARD_NAME "Scoovo X9H" + +#define LARGE_FLASH true + +// +// 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 + +// +// 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 + +// +// Z Probe (when not Z_MIN_PIN) +// +#ifndef Z_MIN_PROBE_PIN + #define Z_MIN_PROBE_PIN 30 +#endif + +// +// Steppers +// +#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 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 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 + +// +// Temperature Sensors +// +#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 FAN_PIN 8 +#define FAN1_PIN 6 +#define FAN2_PIN 2 + +// +// Misc. Functions +// +#define SDSS 53 +#define LED_PIN 13 +#define PS_ON_PIN 4 + +#ifndef FILWIDTH_PIN + #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 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 + +#if ENABLED(VIKI2) || ENABLED(miniVIKI) + #define BEEPER_PIN 44 + // Pins for DOGM SPI LCD Support + #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 STAT_LED_RED_PIN 22 + #define STAT_LED_BLUE_PIN 32 +#endif // VIKI2/miniVIKI diff --git a/trunk/Arduino/Marlin_1.1.6/pins_SETHI.h b/trunk/Arduino/Marlin_1.1.6/pins_SETHI.h new file mode 100644 index 00000000..ac570fd2 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_SETHI.h @@ -0,0 +1,123 @@ +/** + * 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 . + * + */ + +/** + * Sethi 3D_1 pin assignments - www.sethi3d.com.br + */ + +/** + * Rev B 26 DEC 2016 + * + * added pointer to a current Arduino IDE extension + * this assumes that this board uses the Sanguino pin map + */ + +/** + * A useable Arduino IDE extension (board manager) can be found at + * https://github.com/Lauszus/Sanguino + * + * This extension has been tested on Arduino 1.6.12 & 1.8.0 + * + * Here's the JSON path: + * https://raw.githubusercontent.com/Lauszus/Sanguino/master/package_lauszus_sanguino_index.json + * + * When installing select 1.0.2 + * + * Installation instructions can be found at https://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__) && !defined(__AVR_ATmega1284P__) + #error "Oops! Make sure you have 'Sethi 3D' selected from the 'Tools -> Boards' menu." +#endif + +#define BOARD_NAME "Sethi 3D_1" + +#ifndef GEN7_VERSION + #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 + +// +// Steppers +// +#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 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 + +// +// Temperature Sensors +// +#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 + + +#if GEN7_VERSION >= 13 + // Gen7 v1.3 removed the fan pin + #define FAN_PIN -1 +#else + #define FAN_PIN 31 +#endif + +// +// Misc. Functions +// +#define PS_ON_PIN 15 + +// All these generations of Gen7 supply thermistor power +// via PS_ON, so ignore bad thermistor readings +#define BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE + +// our pin for debugging. +#define DEBUG_PIN 0 + +// our RS485 pins +#define TX_ENABLE_PIN 12 +#define RX_ENABLE_PIN 13 diff --git a/trunk/Arduino/Marlin_1.1.6/pins_STB_11.h b/trunk/Arduino/Marlin_1.1.6/pins_STB_11.h new file mode 100644 index 00000000..de769fcb --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_STB_11.h @@ -0,0 +1,28 @@ +/** + * 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 . + * + */ + +/** + * STB V1.1 pin assignments + */ + +#define BOARD_NAME "STB V1.1" +#include "pins_SANGUINOLOLU_12.h" diff --git a/trunk/Arduino/Marlin_1.1.6/pins_TEENSY2.h b/trunk/Arduino/Marlin_1.1.6/pins_TEENSY2.h new file mode 100644 index 00000000..d5eb893a --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_TEENSY2.h @@ -0,0 +1,184 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2017 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** + * Rev B 2 JUN 2017 + * + * Converted to Arduino pin numbering + */ + +/** + * 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 + * Select Teensy++ 2.0 in Arduino IDE from the 'Tools -> Boards' menu + * + * Installation instructions are at the above URL. Don't bother loading the + * libraries - they are not used with the Marlin software. + * + * Printrboard - https://github.com/scwimbush/Printrboard-HID-Arduino-IDE-Support + * + * Installation: + * + * 1. Go to the above URL, click on the "Clone or Download" button and then + * click on "Download ZIP" button. + * 2. Unzip the file, find the "printrboard" directory and then copy it to the + * hardware directory in Arduino. The Arduino hardware directory will probably + * be located in a path similar to this: C:\Program Files (x86)\Arduino\hardware. + * 3. Restart Arduino. + * 4. Select "Printrboard" from the 'Tools -> Boards' menu. + * + * Teensyduino is the most popular option. Printrboard is used if your board doesn't have + * the Teensyduino bootloader on it. + */ + +/** + * To burn the bootloader that comes with Printrboard: + * + * 1. Connect your programmer to the board. + * 2. In the Arduino IDE select "Printrboard" and then select the programmer. + * 3. In the Arduino IDE click on "burn bootloader". Don't worry about the "verify failed at 1F000" error message. + * 4. The programmer is no longer needed. Remove it. + */ + +/** + * 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 + * + * CLI build: HARDWARE_MOTHERBOARD=84 make + * + * DaveX plan for Teensylu/printrboard-type pinouts for a TeensyBreadboard: + * (ref teensylu & sprinter) + * + * USB + * GND GND |-----#####-----| +5V ATX +5SB + * ATX PS_ON PWM 27 |b7 ##### b6| 26 PWM* Stepper Enable + * PWM 0 |d0 b5| 25 PWM* + * PWM 1 |d1 b4| 24 PWM + * X_MIN 2 |d2 b3| 23 MISO_PIN + * Y_MIN 3 |d3 b2| 22 MOSI_PIN + * Z_MIN 4 |d4 * * b1| 21 SCK_PIN + * 5 |d5 e e b0| 20 SDSS + * LED 6 |d6 5 4 e7| 19 + * 7 |d7 e6| 18 + * LCD RS 8 |e0 | GND + * LCD EN 9 |e1 a4 a0 R| AREF + * LCD D4 10 |c0 a5 a1 f0| 38 A0 ENC_1 + * LCD D5 11 |c1 a6 a2 f1| 39 A1 ENC_2 + * LCD D6 12 |c2 a7 a3 f2| 40 A2 ENC_CLK + * LCD D6 13 |c3 f3| 41 A3 + * Bed Heat PWM 14 |c4 V G R f4| 42 A4 + * Extruder Heat PWM 15 |c5 c n S f5| 43 A5 + * Fan PWM 16 |c6 c d T f6| 44 A6 Bed TC + * 17 |c7 * * * f7| 45 A7 Extruder TC * 4.7k * +5 + * ----------------- + * + * Interior E4: 36, INT4 + * Interior E5: 37, INT5 + * Interior PA0-7: 28-35 -- Printrboard and Teensylu use these pins for step & direction: + * T++ PA Signal Marlin + * + * Z STEP 32 a4 a0 28 X STEP + * Z DIR 33 a5 a1 29 X DIR + * E STEP 34 a6 a2 30 Y STEP + * E DIR 35 a7 a3 31 Y DIR + */ + +#ifndef __AVR_AT90USB1286__ + #error "Oops! Make sure you have 'Teensy++ 2.0' or 'Printrboard' selected from the 'Tools -> Boards' menu." +#endif + +#define BOARD_NAME "Teensy++2.0" + +#define LARGE_FLASH true + +// +// Limit Switches +// +#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 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 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) + +// +// Heaters / Fans +// +#define HEATER_0_PIN 15 // C5 PWM3B Extruder +#define HEATER_BED_PIN 14 // C4 PWM3C +#define FAN_PIN 16 // C6 PWM3A Fan + +// +// 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 + +// +// 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 +#endif + +// +// M3/M4/M5 - Spindle/Laser Control +// +#define SPINDLE_LASER_ENABLE_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/trunk/Arduino/Marlin_1.1.6/pins_TEENSYLU.h b/trunk/Arduino/Marlin_1.1.6/pins_TEENSYLU.h new file mode 100644 index 00000000..0c2ded63 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_TEENSYLU.h @@ -0,0 +1,164 @@ +/** + * 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 . + * + */ + +/** + * Rev C 2 JUN 2017 + * + * Converted to Arduino pin numbering + */ + +/** + * 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 + * Select Teensy++ 2.0 in Arduino IDE from the 'Tools -> Boards' menu + * + * Installation instructions are at the above URL. Don't bother loading the + * libraries - they are not used with the Marlin software. + * + * Printrboard - https://github.com/scwimbush/Printrboard-HID-Arduino-IDE-Support + * This is basically Teensyduino but with a bootloader that can handle image sizes + * larger than 64K. + * + * Installation: + * + * 1. Go to the above URL, click on the "Clone or Download" button and then + * click on "Download ZIP" button. + * 2. Unzip the file, find the "printrboard" directory and then copy it to the + * hardware directory in Arduino. The Arduino hardware directory will probably + * be located in a path similar to this: C:\Program Files (x86)\Arduino\hardware. + * 3. Restart Arduino. + * 4. Select "Printrboard" from the 'Tools -> Boards' menu. + * + * Teensyduino is the most popular option. Printrboard is used if your board doesn't have + * the Teensyduino bootloader on it. + */ + +/** + * To burn the bootloader that comes with Printrboard: + * + * 1. Connect your programmer to the board. + * 2. In the Arduino IDE select "Printrboard" and then select the programmer. + * 3. In the Arduino IDE click on "burn bootloader". Don't worry about the "verify failed at 1F000" error message. + * 4. The programmer is no longer needed. Remove it. + */ + + /** + * SILKSCREEN ERROR + * + * The silkscreen for the endstops do NOT match the schematic. The silkscreen SHOULD + * read (from left to right) X-STOP, Y-STOP, Z-STOP & E-STOP. The silkscreen actually + * reads E-STOP, X-STOP, Y-STOP & Z-STOP. + * + * The pin assignments in this file match the silkscreen. + */ + +#if !defined(__AVR_AT90USB1286__) && !defined(__AVR_AT90USB1286P__) + #error "Oops! Make sure you have 'Teensy++ 2.0' or 'Printrboard' selected from the 'Tools -> Boards' menu." +#endif + +#define BOARD_NAME "Teensylu" + +#define LARGE_FLASH true + + +// +// 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 + + +// +// 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 + +// +// Steppers +// +#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 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 + +// +// Temperature Sensors +// +#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 FAN_PIN 16 // C6 PWM3A + +// +// Misc. Functions +// +#define SDSS 20 // B0 JP31-6 +#define CASE_LIGHT_PIN 0 // D0 IO-14 PWM0B + +// +// LCD / Controller +// +#if ENABLED(ULTRA_LCD) && ENABLED(NEWPANEL) + + #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 + #endif + + #define SD_DETECT_PIN -1 + +#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_ENABLE_PIN 39 // F1 IO-11 - Pin should have a pullup! +#define SPINDLE_DIR_PIN 40 // F2 IO-9 diff --git a/trunk/Arduino/Marlin_1.1.6/pins_ULTIMAIN_2.h b/trunk/Arduino/Marlin_1.1.6/pins_ULTIMAIN_2.h new file mode 100644 index 00000000..4ac26c6a --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_ULTIMAIN_2.h @@ -0,0 +1,135 @@ +/** + * 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 . + * + */ + +/** + * Ultiboard v2.0 pin assignments + */ + +/** + * Rev B 2 JAN 2017 + * + * Added pin definitions for: + * M3, M4 & M5 spindle control commands + * case light + */ + +#ifndef __AVR_ATmega2560__ + #error "Oops! Make sure you have 'Arduino Mega 2560' selected from the 'Tools -> Boards' menu." +#endif + +#define DEFAULT_MACHINE_NAME "Ultimaker" +#define DEFAULT_SOURCE_CODE_URL "https://github.com/Ultimaker/Marlin" +#define BOARD_NAME "Ultimaker 2.x" + +// +// Limit Switches +// +#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 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 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_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 +#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 + +// +// Heaters / Fans +// +#define HEATER_0_PIN 2 +#define HEATER_1_PIN 3 +#define HEATER_BED_PIN 4 + +#define FAN_PIN 7 + +// +// 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. + +// +// LCD / Controller +// +#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 + +// Buttons are directly attached +#define BTN_EN1 40 +#define BTN_EN2 41 +#define BTN_ENC 19 + +// +// M3/M4/M5 - Spindle/Laser Control +// +#if ENABLED(SPINDLE_LASER_ENABLE) // use the LED_PIN for spindle speed control or case light + #undef LED_PIN + #define SPINDLE_DIR_PIN 16 + #define SPINDLE_LASER_ENABLE_PIN 17 // Pin should have a pullup! + #define SPINDLE_LASER_PWM_PIN 8 // MUST BE HARDWARE PWM +#else + #undef LED_PIN + #define CASE_LIGHT_PIN 8 +#endif diff --git a/trunk/Arduino/Marlin_1.1.6/pins_ULTIMAKER.h b/trunk/Arduino/Marlin_1.1.6/pins_ULTIMAKER.h new file mode 100644 index 00000000..d8e7d26b --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_ULTIMAKER.h @@ -0,0 +1,164 @@ +/** + * 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 . + * + */ + +/** + * Ultimaker pin assignments + */ + +/** + * Rev B 2 JAN 2017 + * + * Added pin definitions for: + * M3, M4 & M5 spindle control commands + * case light + */ + +#if !defined(__AVR_ATmega1280__) && !defined(__AVR_ATmega2560__) + #error "Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu." +#endif + +#define DEFAULT_MACHINE_NAME "Ultimaker" +#define DEFAULT_SOURCE_CODE_URL "https://github.com/Ultimaker/Marlin" +#define BOARD_NAME "Ultimaker" + +#define LARGE_FLASH true + +// +// Servos +// +#define SERVO0_PIN 13 // untested + +// +// 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 + +// +// Z Probe (when not Z_MIN_PIN) +// +#ifndef Z_MIN_PROBE_PIN + #define Z_MIN_PROBE_PIN 32 +#endif + +// +// Steppers +// +#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 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 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 + +// +// Heaters / Fans +// +#define HEATER_0_PIN 2 +#define HEATER_1_PIN 3 +#define HEATER_BED_PIN 4 + +#define FAN_PIN 7 + +// +// 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 + +// +// LCD / Controller +// +#if ENABLED(ULTRA_LCD) + + #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 + + // buttons are directly attached + #define BTN_EN1 40 + #define BTN_EN2 42 + #define BTN_ENC 19 + + #define SD_DETECT_PIN 38 + + #else // !NEWPANEL - Old style panel with shift register + + // buttons are 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 SD_DETECT_PIN -1 + + #endif // !NEWPANEL + +#endif // ULTRA_LCD + +// +// M3/M4/M5 - Spindle/Laser Control +// +#define SPINDLE_LASER_PWM_PIN 9 // MUST BE HARDWARE PWM +#define SPINDLE_LASER_ENABLE_PIN 10 // Pin should have a pullup! +#define SPINDLE_DIR_PIN 11 // use the EXP3 PWM header diff --git a/trunk/Arduino/Marlin_1.1.6/pins_ULTIMAKER_OLD.h b/trunk/Arduino/Marlin_1.1.6/pins_ULTIMAKER_OLD.h new file mode 100644 index 00000000..5dafda2d --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_ULTIMAKER_OLD.h @@ -0,0 +1,283 @@ +/** + * 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 . + * + */ + +/** + * Ultimaker pin assignments (Old electronics) + */ + + /** + * Rev B 3 JAN 2017 + * + * Details on pin definitions for M3, M4 & M5 spindle control commands and for + * the CASE_LIGHT_PIN are at the end of this file. + * + * This started out as an attempt to add pin definitions for M3, M4 & M5 spindle + * control commands but quickly turned into a head scratcher as the sources for + * the revisions provided inconsistent information. + * + * As best I can determine: + * 1.5.3 boards should use the pins_ULTIMAKER.h file which means the BOARD_NAME + * define in this file should say 1.5.3 rather than 1.5.4 + * This file is meant for 1.1 - 1.3 boards. + * The endstops for the 1.0 boards use different definitions than on the 1.1 - 1.3 + * boards. + * + * I've added sections that have the 1.0 and 1.5.3 + endstop definitions so you can + * easily switch if needed. I've also copied over the 1.5.3 + LCD definitions. + * + * To be 100% sure of the board you have: + * 1. In Configuration_adv.h enable "PINS_DEBUGGING" + * 2. Compile & uploade + * 3. Enter the command "M43 W1 I1". This command will report that pin nmumber and + * name of any pin that changes state. + * 4. Using a 1k (approximately) resistor pull the endstops and some of the LCD pins + * to ground and see what is reported. + * 5. If the reported pin doesn't match the file then try a different board revision + * and repeat steps 2 - 5 + */ + +#define board_rev_1_1_TO_1_3 +//#define board_rev_1_0 +//#define board_rev_1_5 + + +#if !defined(__AVR_ATmega1280__) && !defined(__AVR_ATmega2560__) + #error "Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu." +#endif + +#define DEFAULT_MACHINE_NAME "Ultimaker" +#define DEFAULT_SOURCE_CODE_URL "https://github.com/Ultimaker/Marlin" +#define BOARD_NAME "Ultimaker <1.5.4" + +#define LARGE_FLASH true + +// +// 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 +#endif + +#if ENABLED(board_rev_1_0) + #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 + +#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 +#endif + +// +// Z Probe (when not Z_MIN_PIN) +// +#ifndef Z_MIN_PROBE_PIN + #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 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 E0_STEP_PIN 43 +#define E0_DIR_PIN 45 +#define E0_ENABLE_PIN 41 + +#define E1_STEP_PIN -1 // 49 +#define E1_DIR_PIN -1 // 47 +#define E1_ENABLE_PIN -1 // 48 + +// +// Temperature Sensors +// +#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 + +// +// LCD / Controller +// +#if ENABLED(board_rev_1_0) || ENABLED(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 +#elif ENABLED(board_rev_1_5) && ENABLED(ULTRA_LCD) + + #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 + + // buttons are directly attached + #define BTN_EN1 40 + #define BTN_EN2 42 + #define BTN_ENC 19 + + #define SD_DETECT_PIN 38 + + #else // !NEWPANEL - Old style panel with shift register + + // buttons are 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 SD_DETECT_PIN -1 + + #endif // !NEWPANEL + +#endif // ULTRA_LCD + +// +// 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 +#endif + +// +// M3/M4/M5 - Spindle/Laser Control +// +#if ENABLED(SPINDLE_LASER_ENABLE) + + #if ENABLED(board_rev_1_0) // use the last three SW positions + + #undef Z_MIN_PROBE_PIN + #undef X_MIN_PIN // SW1 + #undef X_MAX_PIN // SW2 + #undef Y_MIN_PIN // SW3 + #undef Y_MAX_PIN // SW4 + #undef Z_MIN_PIN // SW5 + #undef Z_MAX_PIN // SW6 + + #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 SPINDLE_DIR_PIN 10 // SW4 + #define SPINDLE_LASER_PWM_PIN 9 // SW5 MUST BE HARDWARE PWM + #define SPINDLE_LASER_ENABLE_PIN 8 // SW6 Pin should have a pullup! + + #elif ENABLED(board_rev_1_5) // use the same pins - but now they are on a different connector + + #define SPINDLE_DIR_PIN 10 // EXP3-6 (silkscreen says 10) + #define SPINDLE_LASER_PWM_PIN 9 // EXP3-7 (silkscreen says 9) MUST BE HARDWARE PWM + #define SPINDLE_LASER_ENABLE_PIN 8 // EXP3-8 (silkscreen says 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: + * + * HEATER_0_PIN 2 silkscreen varies - usually "PWM 1" or "HEATER1" + * HEATER_1_PIN 3 silkscreen varies - usually "PWM 2" or "HEATER2" + * HEATER_BED_PIN 4 silkscreen varies - usually "PWM 3" or "HEATED BED" + * E0_DIR_PIN 45 + * + * If one of the heaters is used then special precautions will usually be needed. + * They have an LED and resistor pullup to +24V which could damage 3.3V-5V ICs. + */ + #if EXTRUDERS == 1 // Move E0 stepper module to the spare and get signals from E0 + #undef E0_STEP_PIN + #undef E0_DIR_PIN + #undef E0_ENABLE_PIN + #define E0_STEP_PIN 49 + #define E0_DIR_PIN 47 + #define E0_ENABLE_PIN 48 + #define SPINDLE_DIR_PIN 43 + #define SPINDLE_LASER_PWM_PIN 45 // MUST BE HARDWARE PWM + #define SPINDLE_LASER_ENABLE_PIN 41 // Pin should have a 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 // MUST BE HARDWARE PWM - Special precautions usually needed. + #define SPINDLE_LASER_ENABLE_PIN 40 // Pin should have a pullup! (Probably pin 6 on the 10-pin + // connector closest to the E0 socket) + #endif + #endif +#endif + +/** + * Where to get the spindle signals on the E0 socket + * + * spindle signal socket name socket name + * ------- + * SPINDLE_LASER_ENABLE_PIN /ENABLE *| |O VMOT + * MS1 O| |O GND + * MS2 O| |O 2B + * MS3 O| |O 2A + * /RESET O| |O 1A + * /SLEEP O| |O 1B + * SPINDLE_DIR_PIN STEP O| |O VDD + * SPINDLE_LASER_PWM_PIN DIR O| |O GND + * ------- + * * - pin closest to MS1, MS2 & MS3 jumpers on the board + * + * Note: Socket names vary from vendor to vendor. + */ diff --git a/trunk/Arduino/Marlin_1.1.6/pins_ZRIB_V20.h b/trunk/Arduino/Marlin_1.1.6/pins_ZRIB_V20.h new file mode 100644 index 00000000..1437c718 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/pins_ZRIB_V20.h @@ -0,0 +1,39 @@ +/** + * 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 . + * + */ + +/** + * ZRIB V2.0 pin assignments + */ + +#define ZRIB_V20_D6_PIN 6 +#define ZRIB_V20_D9_PIN 9 +#define RAMPS_D9_PIN ZRIB_V20_D6_PIN +#define ORIG_E0_AUTO_FAN_PIN ZRIB_V20_D9_PIN +#define ORIG_E1_AUTO_FAN_PIN ZRIB_V20_D9_PIN +#define ORIG_E2_AUTO_FAN_PIN ZRIB_V20_D9_PIN +#define ORIG_E3_AUTO_FAN_PIN ZRIB_V20_D9_PIN + +#ifndef FILWIDTH_PIN + #define FILWIDTH_PIN 11 // Analog Input +#endif + +#include "pins_MKS_13.h" diff --git a/trunk/Arduino/Marlin_1.1.6/planner.cpp b/trunk/Arduino/Marlin_1.1.6/planner.cpp new file mode 100644 index 00000000..74068e86 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/planner.cpp @@ -0,0 +1,1535 @@ +/** + * 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 . + * + */ + +/** + * planner.cpp + * + * Buffer movement commands and manage the acceleration profile plan + * + * Derived from Grbl + * Copyright (c) 2009-2011 Simen Svale Skogsrud + * + * The ring buffer implementation gleaned from the wiring_serial library by David A. Mellis. + * + * + * Reasoning behind the mathematics in this module (in the key of 'Mathematica'): + * + * s == speed, a == acceleration, t == time, d == distance + * + * Basic definitions: + * Speed[s_, a_, t_] := s + (a*t) + * Travel[s_, a_, t_] := Integrate[Speed[s, a, t], t] + * + * Distance to reach a specific speed with a constant acceleration: + * Solve[{Speed[s, a, t] == m, Travel[s, a, t] == d}, d, t] + * d -> (m^2 - s^2)/(2 a) --> estimate_acceleration_distance() + * + * Speed after a given distance of travel with constant acceleration: + * Solve[{Speed[s, a, t] == m, Travel[s, a, t] == d}, m, t] + * m -> Sqrt[2 a d + s^2] + * + * DestinationSpeed[s_, a_, d_] := Sqrt[2 a d + s^2] + * + * When to start braking (di) to reach a specified destination speed (s2) after accelerating + * from initial speed s1 without ever stopping at a plateau: + * Solve[{DestinationSpeed[s1, a, di] == DestinationSpeed[s2, a, d - di]}, di] + * di -> (2 a d - s1^2 + s2^2)/(4 a) --> intersection_distance() + * + * IntersectionDistance[s1_, s2_, a_, d_] := (2 a d - s1^2 + s2^2)/(4 a) + * + */ + +#include "planner.h" +#include "stepper.h" +#include "temperature.h" +#include "ultralcd.h" +#include "language.h" +#include "ubl.h" +#include "gcode.h" + +#include "Marlin.h" + +#if ENABLED(MESH_BED_LEVELING) + #include "mesh_bed_leveling.h" +#endif + +Planner planner; + + // public: + +/** + * A ring buffer of moves described in steps + */ +block_t Planner::block_buffer[BLOCK_BUFFER_SIZE]; +volatile uint8_t Planner::block_buffer_head = 0, // Index of the next block to be pushed + Planner::block_buffer_tail = 0; + +float Planner::max_feedrate_mm_s[XYZE_N], // Max speeds in mm per second + Planner::axis_steps_per_mm[XYZE_N], + Planner::steps_to_mm[XYZE_N]; + +#if ENABLED(DISTINCT_E_FACTORS) + uint8_t Planner::last_extruder = 0; // Respond to extruder change +#endif + +uint32_t Planner::max_acceleration_steps_per_s2[XYZE_N], + Planner::max_acceleration_mm_per_s2[XYZE_N]; // Use M201 to override by software + +millis_t Planner::min_segment_time; + +// Initialized by settings.load() +float Planner::min_feedrate_mm_s, + Planner::acceleration, // Normal acceleration mm/s^2 DEFAULT ACCELERATION for all printing moves. M204 SXXXX + Planner::retract_acceleration, // Retract acceleration mm/s^2 filament pull-back and push-forward while standing still in the other axes M204 TXXXX + Planner::travel_acceleration, // Travel acceleration mm/s^2 DEFAULT ACCELERATION for all NON printing moves. M204 MXXXX + Planner::max_jerk[XYZE], // The largest speed change requiring no acceleration + Planner::min_travel_feedrate_mm_s; + +#if HAS_ABL + bool Planner::abl_enabled = false; // Flag that auto bed leveling is enabled +#endif + +#if ABL_PLANAR + matrix_3x3 Planner::bed_level_matrix; // Transform to compensate for bed level +#endif + +#if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) + float Planner::z_fade_height, // Initialized by settings.load() + Planner::inverse_z_fade_height; +#endif + +#if ENABLED(AUTOTEMP) + float Planner::autotemp_max = 250, + Planner::autotemp_min = 210, + Planner::autotemp_factor = 0.1; + bool Planner::autotemp_enabled = false; +#endif + +// private: + +long Planner::position[NUM_AXIS] = { 0 }; + +uint32_t Planner::cutoff_long; + +float Planner::previous_speed[NUM_AXIS], + Planner::previous_nominal_speed; + +#if ENABLED(DISABLE_INACTIVE_EXTRUDER) + uint8_t Planner::g_uc_extruder_last_move[EXTRUDERS] = { 0 }; +#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 + long Planner::axis_segment_time[2][3] = { {MAX_FREQ_TIME + 1, 0, 0}, {MAX_FREQ_TIME + 1, 0, 0} }; +#endif + +#if ENABLED(LIN_ADVANCE) + float Planner::extruder_advance_k, // Initialized by settings.load() + Planner::advance_ed_ratio, // Initialized by settings.load() + Planner::position_float[NUM_AXIS] = { 0 }; +#endif + +#if ENABLED(ULTRA_LCD) + volatile uint32_t Planner::block_buffer_runtime_us = 0; +#endif + +/** + * Class and Instance Methods + */ + +Planner::Planner() { init(); } + +void Planner::init() { + block_buffer_head = block_buffer_tail = 0; + ZERO(position); + #if ENABLED(LIN_ADVANCE) + ZERO(position_float); + #endif + ZERO(previous_speed); + previous_nominal_speed = 0.0; + #if ABL_PLANAR + bed_level_matrix.set_to_identity(); + #endif +} + +#define MINIMAL_STEP_RATE 120 + +/** + * Calculate trapezoid parameters, multiplying the entry- and exit-speeds + * by the provided factors. + */ +void Planner::calculate_trapezoid_for_block(block_t* const block, const float &entry_factor, const float &exit_factor) { + uint32_t initial_rate = CEIL(block->nominal_rate * entry_factor), + final_rate = CEIL(block->nominal_rate * exit_factor); // (steps per second) + + // Limit minimal step rate (Otherwise the timer will overflow.) + NOLESS(initial_rate, MINIMAL_STEP_RATE); + NOLESS(final_rate, MINIMAL_STEP_RATE); + + int32_t accel = block->acceleration_steps_per_s2, + accelerate_steps = CEIL(estimate_acceleration_distance(initial_rate, block->nominal_rate, accel)), + decelerate_steps = FLOOR(estimate_acceleration_distance(block->nominal_rate, final_rate, -accel)), + plateau_steps = block->step_event_count - accelerate_steps - decelerate_steps; + + // Is the Plateau of Nominal Rate smaller than nothing? That means no cruising, and we will + // have to use intersection_distance() to calculate when to abort accel and start braking + // in order to reach the final_rate exactly at the end of this block. + if (plateau_steps < 0) { + accelerate_steps = CEIL(intersection_distance(initial_rate, final_rate, accel, block->step_event_count)); + NOLESS(accelerate_steps, 0); // Check limits due to numerical round-off + accelerate_steps = min((uint32_t)accelerate_steps, block->step_event_count);//(We can cast here to unsigned, because the above line ensures that we are above zero) + plateau_steps = 0; + } + + // block->accelerate_until = accelerate_steps; + // block->decelerate_after = accelerate_steps+plateau_steps; + + CRITICAL_SECTION_START; // Fill variables used by the stepper in a critical section + if (!TEST(block->flag, BLOCK_BIT_BUSY)) { // Don't update variables if block is busy. + block->accelerate_until = accelerate_steps; + block->decelerate_after = accelerate_steps + plateau_steps; + block->initial_rate = initial_rate; + block->final_rate = final_rate; + } + CRITICAL_SECTION_END; +} + +// "Junction jerk" in this context is the immediate change in speed at the junction of two blocks. +// This method will calculate the junction jerk as the euclidean distance between the nominal +// velocities of the respective blocks. +//inline float junction_jerk(block_t *before, block_t *after) { +// return SQRT( +// POW((before->speed_x-after->speed_x), 2)+POW((before->speed_y-after->speed_y), 2)); +//} + + +// The kernel called by recalculate() when scanning the plan from last to first entry. +void Planner::reverse_pass_kernel(block_t* const current, const block_t *next) { + if (!current || !next) return; + // If entry speed is already at the maximum entry speed, no need to recheck. Block is cruising. + // If not, block in state of acceleration or deceleration. Reset entry speed to maximum and + // check for maximum allowable speed reductions to ensure maximum possible planned speed. + float max_entry_speed = current->max_entry_speed; + if (current->entry_speed != max_entry_speed) { + // If nominal length true, max junction speed is guaranteed to be reached. Only compute + // for max allowable speed if block is decelerating and nominal length is false. + current->entry_speed = (TEST(current->flag, BLOCK_BIT_NOMINAL_LENGTH) || max_entry_speed <= next->entry_speed) + ? max_entry_speed + : min(max_entry_speed, max_allowable_speed(-current->acceleration, next->entry_speed, current->millimeters)); + SBI(current->flag, BLOCK_BIT_RECALCULATE); + } +} + +/** + * recalculate() needs to go over the current plan twice. + * Once in reverse and once forward. This implements the reverse pass. + */ +void Planner::reverse_pass() { + + if (movesplanned() > 3) { + + block_t* block[3] = { NULL, NULL, NULL }; + + // Make a local copy of block_buffer_tail, because the interrupt can alter it + // Is a critical section REALLY needed for a single byte change? + //CRITICAL_SECTION_START; + uint8_t tail = block_buffer_tail; + //CRITICAL_SECTION_END + + uint8_t b = BLOCK_MOD(block_buffer_head - 3); + while (b != tail) { + if (block[0] && TEST(block[0]->flag, BLOCK_BIT_START_FROM_FULL_HALT)) break; + b = prev_block_index(b); + block[2] = block[1]; + block[1] = block[0]; + block[0] = &block_buffer[b]; + reverse_pass_kernel(block[1], block[2]); + } + } +} + +// The kernel called by recalculate() when scanning the plan from first to last entry. +void Planner::forward_pass_kernel(const block_t* previous, block_t* const current) { + if (!previous) return; + + // If the previous block is an acceleration block, but it is not long enough to complete the + // full speed change within the block, we need to adjust the entry speed accordingly. Entry + // speeds have already been reset, maximized, and reverse planned by reverse planner. + // If nominal length is true, max junction speed is guaranteed to be reached. No need to recheck. + if (!TEST(previous->flag, BLOCK_BIT_NOMINAL_LENGTH)) { + if (previous->entry_speed < current->entry_speed) { + float entry_speed = min(current->entry_speed, + max_allowable_speed(-previous->acceleration, previous->entry_speed, previous->millimeters)); + // Check for junction speed change + if (current->entry_speed != entry_speed) { + current->entry_speed = entry_speed; + SBI(current->flag, BLOCK_BIT_RECALCULATE); + } + } + } +} + +/** + * recalculate() needs to go over the current plan twice. + * Once in reverse and once forward. This implements the forward pass. + */ +void Planner::forward_pass() { + block_t* block[3] = { NULL, NULL, NULL }; + + for (uint8_t b = block_buffer_tail; b != block_buffer_head; b = next_block_index(b)) { + block[0] = block[1]; + block[1] = block[2]; + block[2] = &block_buffer[b]; + forward_pass_kernel(block[0], block[1]); + } + forward_pass_kernel(block[1], block[2]); +} + +/** + * Recalculate the trapezoid speed profiles for all blocks in the plan + * according to the entry_factor for each junction. Must be called by + * recalculate() after updating the blocks. + */ +void Planner::recalculate_trapezoids() { + int8_t block_index = block_buffer_tail; + block_t *current, *next = NULL; + + while (block_index != block_buffer_head) { + current = next; + next = &block_buffer[block_index]; + if (current) { + // Recalculate if current block entry or exit junction speed has changed. + if (TEST(current->flag, BLOCK_BIT_RECALCULATE) || TEST(next->flag, BLOCK_BIT_RECALCULATE)) { + // NOTE: Entry and exit factors always > 0 by all previous logic operations. + float nom = current->nominal_speed; + calculate_trapezoid_for_block(current, current->entry_speed / nom, next->entry_speed / nom); + CBI(current->flag, BLOCK_BIT_RECALCULATE); // Reset current only to ensure next trapezoid is computed + } + } + block_index = next_block_index(block_index); + } + // Last/newest block in buffer. Exit speed is set with MINIMUM_PLANNER_SPEED. Always recalculated. + if (next) { + float nom = next->nominal_speed; + calculate_trapezoid_for_block(next, next->entry_speed / nom, (MINIMUM_PLANNER_SPEED) / nom); + CBI(next->flag, BLOCK_BIT_RECALCULATE); + } +} + +/* + * Recalculate the motion plan according to the following algorithm: + * + * 1. Go over every block in reverse order... + * + * Calculate a junction speed reduction (block_t.entry_factor) so: + * + * a. The junction jerk is within the set limit, and + * + * b. No speed reduction within one block requires faster + * deceleration than the one, true constant acceleration. + * + * 2. Go over every block in chronological order... + * + * Dial down junction speed reduction values if: + * a. The speed increase within one block would require faster + * acceleration than the one, true constant acceleration. + * + * After that, all blocks will have an entry_factor allowing all speed changes to + * be performed using only the one, true constant acceleration, and where no junction + * jerk is jerkier than the set limit, Jerky. Finally it will: + * + * 3. Recalculate "trapezoids" for all blocks. + */ +void Planner::recalculate() { + reverse_pass(); + forward_pass(); + recalculate_trapezoids(); +} + + +#if ENABLED(AUTOTEMP) + + void Planner::getHighESpeed() { + static float oldt = 0; + + if (!autotemp_enabled) return; + if (thermalManager.degTargetHotend(0) + 2 < autotemp_min) return; // probably temperature set to zero. + + float high = 0.0; + for (uint8_t b = block_buffer_tail; b != block_buffer_head; b = next_block_index(b)) { + block_t* block = &block_buffer[b]; + if (block->steps[X_AXIS] || block->steps[Y_AXIS] || block->steps[Z_AXIS]) { + float se = (float)block->steps[E_AXIS] / block->step_event_count * block->nominal_speed; // mm/sec; + NOLESS(high, se); + } + } + + float t = autotemp_min + high * autotemp_factor; + t = constrain(t, autotemp_min, autotemp_max); + if (t < oldt) t = t * (1 - (AUTOTEMP_OLDWEIGHT)) + oldt * (AUTOTEMP_OLDWEIGHT); + oldt = t; + thermalManager.setTargetHotend(t, 0); + } + +#endif // AUTOTEMP + +/** + * Maintain fans, paste extruder pressure, + */ +void Planner::check_axes_activity() { + unsigned char axis_active[NUM_AXIS] = { 0 }, + tail_fan_speed[FAN_COUNT]; + + #if FAN_COUNT > 0 + for (uint8_t i = 0; i < FAN_COUNT; i++) tail_fan_speed[i] = fanSpeeds[i]; + #endif + + #if ENABLED(BARICUDA) + #if HAS_HEATER_1 + uint8_t tail_valve_pressure = baricuda_valve_pressure; + #endif + #if HAS_HEATER_2 + uint8_t tail_e_to_p_pressure = baricuda_e_to_p_pressure; + #endif + #endif + + if (blocks_queued()) { + + #if FAN_COUNT > 0 + for (uint8_t i = 0; i < FAN_COUNT; i++) tail_fan_speed[i] = block_buffer[block_buffer_tail].fan_speed[i]; + #endif + + block_t* block; + + #if ENABLED(BARICUDA) + block = &block_buffer[block_buffer_tail]; + #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 + #endif + + for (uint8_t b = block_buffer_tail; b != block_buffer_head; b = next_block_index(b)) { + block = &block_buffer[b]; + LOOP_XYZE(i) if (block->steps[i]) axis_active[i]++; + } + } + #if ENABLED(DISABLE_X) + if (!axis_active[X_AXIS]) disable_X(); + #endif + #if ENABLED(DISABLE_Y) + if (!axis_active[Y_AXIS]) disable_Y(); + #endif + #if ENABLED(DISABLE_Z) + if (!axis_active[Z_AXIS]) disable_Z(); + #endif + #if ENABLED(DISABLE_E) + if (!axis_active[E_AXIS]) disable_e_steppers(); + #endif + + #if FAN_COUNT > 0 + + #ifdef FAN_MIN_PWM + #define CALC_FAN_SPEED(f) (tail_fan_speed[f] ? ( FAN_MIN_PWM + (tail_fan_speed[f] * (255 - FAN_MIN_PWM)) / 255 ) : 0) + #else + #define CALC_FAN_SPEED(f) tail_fan_speed[f] + #endif + + #ifdef FAN_KICKSTART_TIME + + static millis_t fan_kick_end[FAN_COUNT] = { 0 }; + + #define KICKSTART_FAN(f) \ + if (tail_fan_speed[f]) { \ + millis_t ms = millis(); \ + if (fan_kick_end[f] == 0) { \ + fan_kick_end[f] = ms + FAN_KICKSTART_TIME; \ + tail_fan_speed[f] = 255; \ + } else if (PENDING(ms, fan_kick_end[f])) \ + tail_fan_speed[f] = 255; \ + } else fan_kick_end[f] = 0 + + #if HAS_FAN0 + KICKSTART_FAN(0); + #endif + #if HAS_FAN1 + KICKSTART_FAN(1); + #endif + #if HAS_FAN2 + KICKSTART_FAN(2); + #endif + + #endif // FAN_KICKSTART_TIME + + #if ENABLED(FAN_SOFT_PWM) + #if HAS_FAN0 + thermalManager.soft_pwm_amount_fan[0] = CALC_FAN_SPEED(0); + #endif + #if HAS_FAN1 + thermalManager.soft_pwm_amount_fan[1] = CALC_FAN_SPEED(1); + #endif + #if HAS_FAN2 + thermalManager.soft_pwm_amount_fan[2] = CALC_FAN_SPEED(2); + #endif + #else + #if HAS_FAN0 + analogWrite(FAN_PIN, CALC_FAN_SPEED(0)); + #endif + #if HAS_FAN1 + analogWrite(FAN1_PIN, CALC_FAN_SPEED(1)); + #endif + #if HAS_FAN2 + analogWrite(FAN2_PIN, CALC_FAN_SPEED(2)); + #endif + #endif + + #endif // FAN_COUNT > 0 + + #if ENABLED(AUTOTEMP) + getHighESpeed(); + #endif + + #if ENABLED(BARICUDA) + #if HAS_HEATER_1 + analogWrite(HEATER_1_PIN, tail_valve_pressure); + #endif + #if HAS_HEATER_2 + analogWrite(HEATER_2_PIN, tail_e_to_p_pressure); + #endif + #endif +} + +#if PLANNER_LEVELING + /** + * lx, ly, lz - logical (cartesian, not delta) positions in mm + */ + void Planner::apply_leveling(float &lx, float &ly, float &lz) { + + #if ENABLED(AUTO_BED_LEVELING_UBL) + if (!ubl.state.active) return; + #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) + // if z_fade_height enabled (nonzero) and raw_z above it, no leveling required + if (planner.z_fade_height && planner.z_fade_height <= RAW_Z_POSITION(lz)) return; + lz += ubl.state.z_offset + ubl.get_z_correction(lx, ly) * ubl.fade_scaling_factor_for_z(lz); + #else // no fade + lz += ubl.state.z_offset + ubl.get_z_correction(lx, ly); + #endif // FADE + #endif // UBL + + #if HAS_ABL + if (!abl_enabled) return; + #endif + + #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) && DISABLED(AUTO_BED_LEVELING_UBL) + static float z_fade_factor = 1.0, last_raw_lz = -999.0; + if (z_fade_height) { + const float raw_lz = RAW_Z_POSITION(lz); + if (raw_lz >= z_fade_height) return; + if (last_raw_lz != raw_lz) { + last_raw_lz = raw_lz; + z_fade_factor = 1.0 - raw_lz * inverse_z_fade_height; + } + } + else + z_fade_factor = 1.0; + #endif + + #if ENABLED(MESH_BED_LEVELING) + + if (mbl.active()) + lz += mbl.get_z(RAW_X_POSITION(lx), RAW_Y_POSITION(ly) + #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) + , z_fade_factor + #endif + ); + + #elif ABL_PLANAR + + float dx = RAW_X_POSITION(lx) - (X_TILT_FULCRUM), + dy = RAW_Y_POSITION(ly) - (Y_TILT_FULCRUM), + dz = RAW_Z_POSITION(lz); + + apply_rotation_xyz(bed_level_matrix, dx, dy, dz); + + lx = LOGICAL_X_POSITION(dx + X_TILT_FULCRUM); + ly = LOGICAL_Y_POSITION(dy + Y_TILT_FULCRUM); + lz = LOGICAL_Z_POSITION(dz); + + #elif ENABLED(AUTO_BED_LEVELING_BILINEAR) + + float tmp[XYZ] = { lx, ly, 0 }; + lz += bilinear_z_offset(tmp) + #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) + * z_fade_factor + #endif + ; + + #endif + } + + void Planner::unapply_leveling(float logical[XYZ]) { + + #if ENABLED(AUTO_BED_LEVELING_UBL) + + if (ubl.state.active) { + + const float z_physical = RAW_Z_POSITION(logical[Z_AXIS]), + z_correct = ubl.get_z_correction(logical[X_AXIS], logical[Y_AXIS]), + z_virtual = z_physical - ubl.state.z_offset - z_correct; + float z_logical = LOGICAL_Z_POSITION(z_virtual); + + #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) + + // for P=physical_z, L=logical_z, M=mesh_z, O=z_offset, H=fade_height, + // Given P=L+O+M(1-L/H) (faded mesh correction formula for L= planner.z_fade_height) + z_logical = LOGICAL_Z_POSITION(z_physical - ubl.state.z_offset); + else + z_logical /= 1.0 - z_correct * planner.inverse_z_fade_height; + } + + #endif // ENABLE_LEVELING_FADE_HEIGHT + + logical[Z_AXIS] = z_logical; + } + + return; // don't fall thru to other ENABLE_LEVELING_FADE_HEIGHT logic + + #endif + + #if HAS_ABL + if (!abl_enabled) return; + #endif + + #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) + if (z_fade_height && RAW_Z_POSITION(logical[Z_AXIS]) >= z_fade_height) return; + #endif + + #if ENABLED(MESH_BED_LEVELING) + + if (mbl.active()) { + #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) + const float c = mbl.get_z(RAW_X_POSITION(logical[X_AXIS]), RAW_Y_POSITION(logical[Y_AXIS]), 1.0); + logical[Z_AXIS] = (z_fade_height * (RAW_Z_POSITION(logical[Z_AXIS]) - c)) / (z_fade_height - c); + #else + logical[Z_AXIS] -= mbl.get_z(RAW_X_POSITION(logical[X_AXIS]), RAW_Y_POSITION(logical[Y_AXIS])); + #endif + } + + #elif ABL_PLANAR + + matrix_3x3 inverse = matrix_3x3::transpose(bed_level_matrix); + + float dx = RAW_X_POSITION(logical[X_AXIS]) - (X_TILT_FULCRUM), + dy = RAW_Y_POSITION(logical[Y_AXIS]) - (Y_TILT_FULCRUM), + dz = RAW_Z_POSITION(logical[Z_AXIS]); + + apply_rotation_xyz(inverse, dx, dy, dz); + + logical[X_AXIS] = LOGICAL_X_POSITION(dx + X_TILT_FULCRUM); + logical[Y_AXIS] = LOGICAL_Y_POSITION(dy + Y_TILT_FULCRUM); + logical[Z_AXIS] = LOGICAL_Z_POSITION(dz); + + #elif ENABLED(AUTO_BED_LEVELING_BILINEAR) + + #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) + const float c = bilinear_z_offset(logical); + logical[Z_AXIS] = (z_fade_height * (RAW_Z_POSITION(logical[Z_AXIS]) - c)) / (z_fade_height - c); + #else + logical[Z_AXIS] -= bilinear_z_offset(logical); + #endif + + #endif + } + +#endif // PLANNER_LEVELING + +/** + * Planner::_buffer_line + * + * Add a new linear movement to the buffer. + * + * Leveling and kinematics should be applied ahead of calling this. + * + * a,b,c,e - target positions in mm or degrees + * fr_mm_s - (target) speed of the move + * extruder - target extruder + */ +void Planner::_buffer_line(const float &a, const float &b, const float &c, const float &e, float fr_mm_s, const uint8_t extruder) { + + // The target position of the tool in absolute steps + // Calculate target position in absolute steps + //this should be done after the wait, because otherwise a M92 code within the gcode disrupts this calculation somehow + const long target[XYZE] = { + LROUND(a * axis_steps_per_mm[X_AXIS]), + LROUND(b * axis_steps_per_mm[Y_AXIS]), + LROUND(c * axis_steps_per_mm[Z_AXIS]), + LROUND(e * axis_steps_per_mm[E_AXIS_N]) + }; + + // When changing extruders recalculate steps corresponding to the E position + #if ENABLED(DISTINCT_E_FACTORS) + if (last_extruder != extruder && axis_steps_per_mm[E_AXIS_N] != axis_steps_per_mm[E_AXIS + last_extruder]) { + position[E_AXIS] = LROUND(position[E_AXIS] * axis_steps_per_mm[E_AXIS_N] * steps_to_mm[E_AXIS + last_extruder]); + last_extruder = extruder; + } + #endif + + #if ENABLED(LIN_ADVANCE) + const float mm_D_float = SQRT(sq(a - position_float[X_AXIS]) + sq(b - position_float[Y_AXIS])); + #endif + + const long da = target[X_AXIS] - position[X_AXIS], + db = target[Y_AXIS] - position[Y_AXIS], + dc = target[Z_AXIS] - position[Z_AXIS]; + + /* + SERIAL_ECHOPAIR(" Planner FR:", fr_mm_s); + SERIAL_CHAR(' '); + #if IS_KINEMATIC + SERIAL_ECHOPAIR("A:", a); + SERIAL_ECHOPAIR(" (", da); + SERIAL_ECHOPAIR(") B:", b); + #else + SERIAL_ECHOPAIR("X:", a); + SERIAL_ECHOPAIR(" (", da); + SERIAL_ECHOPAIR(") Y:", b); + #endif + SERIAL_ECHOPAIR(" (", db); + #if ENABLED(DELTA) + SERIAL_ECHOPAIR(") C:", c); + #else + SERIAL_ECHOPAIR(") Z:", c); + #endif + SERIAL_ECHOPAIR(" (", dc); + SERIAL_CHAR(')'); + SERIAL_EOL(); + //*/ + + // DRYRUN ignores all temperature constraints and assures that the extruder is instantly satisfied + if (DEBUGGING(DRYRUN)) { + position[E_AXIS] = target[E_AXIS]; + #if ENABLED(LIN_ADVANCE) + position_float[E_AXIS] = e; + #endif + } + + long de = target[E_AXIS] - position[E_AXIS]; + + #if ENABLED(LIN_ADVANCE) + float de_float = e - position_float[E_AXIS]; + #endif + + #if ENABLED(PREVENT_COLD_EXTRUSION) + if (de) { + if (thermalManager.tooColdToExtrude(extruder)) { + position[E_AXIS] = target[E_AXIS]; // Behave as if the move really took place, but ignore E part + de = 0; // no difference + #if ENABLED(LIN_ADVANCE) + position_float[E_AXIS] = e; + de_float = 0; + #endif + SERIAL_ECHO_START(); + SERIAL_ECHOLNPGM(MSG_ERR_COLD_EXTRUDE_STOP); + } + #if ENABLED(PREVENT_LENGTHY_EXTRUDE) + if (labs(de) > (int32_t)axis_steps_per_mm[E_AXIS_N] * (EXTRUDE_MAXLENGTH)) { // It's not important to get max. extrusion length in a precision < 1mm, so save some cycles and cast to int + position[E_AXIS] = target[E_AXIS]; // Behave as if the move really took place, but ignore E part + de = 0; // no difference + #if ENABLED(LIN_ADVANCE) + position_float[E_AXIS] = e; + de_float = 0; + #endif + SERIAL_ECHO_START(); + SERIAL_ECHOLNPGM(MSG_ERR_LONG_EXTRUDE_STOP); + } + #endif + } + #endif + + // Compute direction bit-mask for this block + uint8_t dm = 0; + #if CORE_IS_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 (CORESIGN(da - db) < 0) SBI(dm, B_AXIS); // Motor B direction + #elif CORE_IS_XZ + if (da < 0) SBI(dm, X_HEAD); // Save the real Extruder (head) direction in X Axis + if (db < 0) SBI(dm, Y_AXIS); + if (dc < 0) SBI(dm, Z_HEAD); // ...and Z + if (da + dc < 0) SBI(dm, A_AXIS); // Motor A direction + if (CORESIGN(da - dc) < 0) SBI(dm, C_AXIS); // Motor C direction + #elif CORE_IS_YZ + if (da < 0) SBI(dm, X_AXIS); + if (db < 0) SBI(dm, Y_HEAD); // Save the real Extruder (head) direction in Y Axis + 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 + #else + if (da < 0) SBI(dm, X_AXIS); + if (db < 0) SBI(dm, Y_AXIS); + if (dc < 0) SBI(dm, Z_AXIS); + #endif + if (de < 0) SBI(dm, E_AXIS); + + const float esteps_float = de * volumetric_multiplier[extruder] * flow_percentage[extruder] * 0.01; + const int32_t esteps = abs(esteps_float) + 0.5; + + // Calculate the buffer head after we push this byte + const uint8_t next_buffer_head = next_block_index(block_buffer_head); + + // If the buffer is full: good! That means we are well ahead of the robot. + // Rest here until there is room in the buffer. + while (block_buffer_tail == next_buffer_head) idle(); + + // Prepare to set up new block + block_t* block = &block_buffer[block_buffer_head]; + + // Clear all flags, including the "busy" bit + block->flag = 0; + + // Set direction bits + block->direction_bits = dm; + + // Number of steps for each axis + // See http://www.corexy.com/theory.html + #if CORE_IS_XY + block->steps[A_AXIS] = labs(da + db); + block->steps[B_AXIS] = labs(da - db); + block->steps[Z_AXIS] = labs(dc); + #elif CORE_IS_XZ + block->steps[A_AXIS] = labs(da + dc); + block->steps[Y_AXIS] = labs(db); + block->steps[C_AXIS] = labs(da - dc); + #elif CORE_IS_YZ + block->steps[X_AXIS] = labs(da); + block->steps[B_AXIS] = labs(db + dc); + block->steps[C_AXIS] = labs(db - dc); + #else + // default non-h-bot planning + block->steps[X_AXIS] = labs(da); + block->steps[Y_AXIS] = labs(db); + block->steps[Z_AXIS] = labs(dc); + #endif + + block->steps[E_AXIS] = esteps; + block->step_event_count = MAX4(block->steps[X_AXIS], block->steps[Y_AXIS], block->steps[Z_AXIS], esteps); + + // Bail if this is a zero-length block + if (block->step_event_count < MIN_STEPS_PER_SEGMENT) return; + + // For a mixing extruder, get a magnified step_event_count for each + #if ENABLED(MIXING_EXTRUDER) + for (uint8_t i = 0; i < MIXING_STEPPERS; i++) + block->mix_event_count[i] = mixing_factor[i] * block->step_event_count; + #endif + + #if FAN_COUNT > 0 + for (uint8_t i = 0; i < FAN_COUNT; i++) block->fan_speed[i] = fanSpeeds[i]; + #endif + + #if ENABLED(BARICUDA) + block->valve_pressure = baricuda_valve_pressure; + block->e_to_p_pressure = baricuda_e_to_p_pressure; + #endif + + block->active_extruder = extruder; + + //enable active axes + #if CORE_IS_XY + if (block->steps[A_AXIS] || block->steps[B_AXIS]) { + enable_X(); + enable_Y(); + } + #if DISABLED(Z_LATE_ENABLE) + if (block->steps[Z_AXIS]) enable_Z(); + #endif + #elif CORE_IS_XZ + if (block->steps[A_AXIS] || block->steps[C_AXIS]) { + enable_X(); + enable_Z(); + } + if (block->steps[Y_AXIS]) enable_Y(); + #elif CORE_IS_YZ + if (block->steps[B_AXIS] || block->steps[C_AXIS]) { + enable_Y(); + enable_Z(); + } + if (block->steps[X_AXIS]) enable_X(); + #else + if (block->steps[X_AXIS]) enable_X(); + if (block->steps[Y_AXIS]) enable_Y(); + #if DISABLED(Z_LATE_ENABLE) + if (block->steps[Z_AXIS]) enable_Z(); + #endif + #endif + + // Enable extruder(s) + if (esteps) { + + #if ENABLED(DISABLE_INACTIVE_EXTRUDER) // Enable only the selected extruder + + #define DISABLE_IDLE_E(N) if (!g_uc_extruder_last_move[N]) disable_E##N(); + + for (uint8_t i = 0; i < EXTRUDERS; i++) + if (g_uc_extruder_last_move[i] > 0) g_uc_extruder_last_move[i]--; + + switch(extruder) { + case 0: + enable_E0(); + g_uc_extruder_last_move[0] = (BLOCK_BUFFER_SIZE) * 2; + #if ENABLED(DUAL_X_CARRIAGE) || ENABLED(DUAL_NOZZLE_DUPLICATION_MODE) + if (extruder_duplication_enabled) { + enable_E1(); + g_uc_extruder_last_move[1] = (BLOCK_BUFFER_SIZE) * 2; + } + #endif + #if EXTRUDERS > 1 + DISABLE_IDLE_E(1); + #if EXTRUDERS > 2 + DISABLE_IDLE_E(2); + #if EXTRUDERS > 3 + DISABLE_IDLE_E(3); + #if EXTRUDERS > 4 + DISABLE_IDLE_E(4); + #endif // EXTRUDERS > 4 + #endif // EXTRUDERS > 3 + #endif // EXTRUDERS > 2 + #endif // EXTRUDERS > 1 + break; + #if EXTRUDERS > 1 + case 1: + enable_E1(); + g_uc_extruder_last_move[1] = (BLOCK_BUFFER_SIZE) * 2; + DISABLE_IDLE_E(0); + #if EXTRUDERS > 2 + DISABLE_IDLE_E(2); + #if EXTRUDERS > 3 + DISABLE_IDLE_E(3); + #if EXTRUDERS > 4 + DISABLE_IDLE_E(4); + #endif // EXTRUDERS > 4 + #endif // EXTRUDERS > 3 + #endif // EXTRUDERS > 2 + break; + #if EXTRUDERS > 2 + case 2: + enable_E2(); + g_uc_extruder_last_move[2] = (BLOCK_BUFFER_SIZE) * 2; + DISABLE_IDLE_E(0); + DISABLE_IDLE_E(1); + #if EXTRUDERS > 3 + DISABLE_IDLE_E(3); + #if EXTRUDERS > 4 + DISABLE_IDLE_E(4); + #endif + #endif + break; + #if EXTRUDERS > 3 + case 3: + enable_E3(); + g_uc_extruder_last_move[3] = (BLOCK_BUFFER_SIZE) * 2; + DISABLE_IDLE_E(0); + DISABLE_IDLE_E(1); + DISABLE_IDLE_E(2); + #if EXTRUDERS > 4 + DISABLE_IDLE_E(4); + #endif + break; + #if EXTRUDERS > 4 + case 4: + enable_E4(); + g_uc_extruder_last_move[4] = (BLOCK_BUFFER_SIZE) * 2; + DISABLE_IDLE_E(0); + DISABLE_IDLE_E(1); + DISABLE_IDLE_E(2); + DISABLE_IDLE_E(3); + break; + #endif // EXTRUDERS > 4 + #endif // EXTRUDERS > 3 + #endif // EXTRUDERS > 2 + #endif // EXTRUDERS > 1 + } + #else + enable_E0(); + enable_E1(); + enable_E2(); + enable_E3(); + enable_E4(); + #endif + } + + if (esteps) + NOLESS(fr_mm_s, min_feedrate_mm_s); + else + NOLESS(fr_mm_s, min_travel_feedrate_mm_s); + + /** + * This part of the code calculates the total length of the movement. + * For cartesian bots, the X_AXIS is the real X movement and same for Y_AXIS. + * But for corexy bots, that is not true. The "X_AXIS" and "Y_AXIS" motors (that should be named to A_AXIS + * and B_AXIS) cannot be used for X and Y length, because A=X+Y and B=X-Y. + * 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. + */ + #if IS_CORE + float delta_mm[Z_HEAD + 1]; + #if CORE_IS_XY + delta_mm[X_HEAD] = da * steps_to_mm[A_AXIS]; + delta_mm[Y_HEAD] = db * steps_to_mm[B_AXIS]; + delta_mm[Z_AXIS] = dc * steps_to_mm[Z_AXIS]; + delta_mm[A_AXIS] = (da + db) * steps_to_mm[A_AXIS]; + delta_mm[B_AXIS] = CORESIGN(da - db) * steps_to_mm[B_AXIS]; + #elif CORE_IS_XZ + delta_mm[X_HEAD] = da * steps_to_mm[A_AXIS]; + delta_mm[Y_AXIS] = db * steps_to_mm[Y_AXIS]; + delta_mm[Z_HEAD] = dc * steps_to_mm[C_AXIS]; + delta_mm[A_AXIS] = (da + dc) * steps_to_mm[A_AXIS]; + delta_mm[C_AXIS] = CORESIGN(da - dc) * steps_to_mm[C_AXIS]; + #elif CORE_IS_YZ + delta_mm[X_AXIS] = da * steps_to_mm[X_AXIS]; + delta_mm[Y_HEAD] = db * steps_to_mm[B_AXIS]; + delta_mm[Z_HEAD] = dc * steps_to_mm[C_AXIS]; + delta_mm[B_AXIS] = (db + dc) * steps_to_mm[B_AXIS]; + delta_mm[C_AXIS] = CORESIGN(db - dc) * steps_to_mm[C_AXIS]; + #endif + #else + float delta_mm[XYZE]; + delta_mm[X_AXIS] = da * steps_to_mm[X_AXIS]; + delta_mm[Y_AXIS] = db * steps_to_mm[Y_AXIS]; + delta_mm[Z_AXIS] = dc * steps_to_mm[Z_AXIS]; + #endif + delta_mm[E_AXIS] = esteps_float * steps_to_mm[E_AXIS_N]; + + if (block->steps[X_AXIS] < MIN_STEPS_PER_SEGMENT && block->steps[Y_AXIS] < MIN_STEPS_PER_SEGMENT && block->steps[Z_AXIS] < MIN_STEPS_PER_SEGMENT) { + block->millimeters = FABS(delta_mm[E_AXIS]); + } + else { + block->millimeters = SQRT( + #if CORE_IS_XY + sq(delta_mm[X_HEAD]) + sq(delta_mm[Y_HEAD]) + sq(delta_mm[Z_AXIS]) + #elif CORE_IS_XZ + sq(delta_mm[X_HEAD]) + sq(delta_mm[Y_AXIS]) + sq(delta_mm[Z_HEAD]) + #elif CORE_IS_YZ + sq(delta_mm[X_AXIS]) + sq(delta_mm[Y_HEAD]) + sq(delta_mm[Z_HEAD]) + #else + sq(delta_mm[X_AXIS]) + sq(delta_mm[Y_AXIS]) + sq(delta_mm[Z_AXIS]) + #endif + ); + } + float inverse_millimeters = 1.0 / block->millimeters; // Inverse millimeters to remove multiple divides + + // Calculate moves/second for this move. No divide by zero due to previous checks. + float inverse_mm_s = fr_mm_s * inverse_millimeters; + + const uint8_t moves_queued = movesplanned(); + + // Slow down when the buffer starts to empty, rather than wait at the corner for a buffer refill + #if ENABLED(SLOWDOWN) || ENABLED(ULTRA_LCD) || defined(XY_FREQUENCY_LIMIT) + // Segment time im micro seconds + unsigned long segment_time = LROUND(1000000.0 / inverse_mm_s); + #endif + #if ENABLED(SLOWDOWN) + if (WITHIN(moves_queued, 2, (BLOCK_BUFFER_SIZE) / 2 - 1)) { + if (segment_time < min_segment_time) { + // buffer is draining, add extra time. The amount of time added increases if the buffer is still emptied more. + inverse_mm_s = 1000000.0 / (segment_time + LROUND(2 * (min_segment_time - segment_time) / moves_queued)); + #if defined(XY_FREQUENCY_LIMIT) || ENABLED(ULTRA_LCD) + segment_time = LROUND(1000000.0 / inverse_mm_s); + #endif + } + } + #endif + + #if ENABLED(ULTRA_LCD) + CRITICAL_SECTION_START + block_buffer_runtime_us += segment_time; + CRITICAL_SECTION_END + #endif + + block->nominal_speed = block->millimeters * inverse_mm_s; // (mm/sec) Always > 0 + block->nominal_rate = CEIL(block->step_event_count * inverse_mm_s); // (step/sec) Always > 0 + + #if ENABLED(FILAMENT_WIDTH_SENSOR) + static float filwidth_e_count = 0, filwidth_delay_dist = 0; + + //FMM update ring buffer used for delay with filament measurements + if (extruder == FILAMENT_SENSOR_EXTRUDER_NUM && filwidth_delay_index[1] >= 0) { //only for extruder with filament sensor and if ring buffer is initialized + + const int MMD_CM = MAX_MEASUREMENT_DELAY + 1, MMD_MM = MMD_CM * 10; + + // increment counters with next move in e axis + filwidth_e_count += delta_mm[E_AXIS]; + filwidth_delay_dist += delta_mm[E_AXIS]; + + // Only get new measurements on forward E movement + if (filwidth_e_count > 0.0001) { + + // Loop the delay distance counter (modulus by the mm length) + while (filwidth_delay_dist >= MMD_MM) filwidth_delay_dist -= MMD_MM; + + // Convert into an index into the measurement array + filwidth_delay_index[0] = int8_t(filwidth_delay_dist * 0.1); + + // If the index has changed (must have gone forward)... + if (filwidth_delay_index[0] != filwidth_delay_index[1]) { + filwidth_e_count = 0; // Reset the E movement counter + const uint8_t meas_sample = thermalManager.widthFil_to_size_ratio() - 100; // Subtract 100 to reduce magnitude - to store in a signed char + do { + filwidth_delay_index[1] = (filwidth_delay_index[1] + 1) % MMD_CM; // The next unused slot + measurement_delay[filwidth_delay_index[1]] = meas_sample; // Store the measurement + } while (filwidth_delay_index[0] != filwidth_delay_index[1]); // More slots to fill? + } + } + } + #endif + + // Calculate and limit speed in mm/sec for each axis + float current_speed[NUM_AXIS], speed_factor = 1.0; // factor <1 decreases speed + LOOP_XYZE(i) { + const float cs = FABS(current_speed[i] = delta_mm[i] * inverse_mm_s); + #if ENABLED(DISTINCT_E_FACTORS) + if (i == E_AXIS) i += extruder; + #endif + if (cs > max_feedrate_mm_s[i]) NOMORE(speed_factor, max_feedrate_mm_s[i] / cs); + } + + // 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 = LROUND((float)segment_time / speed_factor); + + long xs0 = axis_segment_time[X_AXIS][0], + xs1 = axis_segment_time[X_AXIS][1], + xs2 = axis_segment_time[X_AXIS][2], + ys0 = axis_segment_time[Y_AXIS][0], + ys1 = axis_segment_time[Y_AXIS][1], + ys2 = axis_segment_time[Y_AXIS][2]; + + if (TEST(direction_change, X_AXIS)) { + xs2 = axis_segment_time[X_AXIS][2] = xs1; + xs1 = axis_segment_time[X_AXIS][1] = xs0; + xs0 = 0; + } + xs0 = axis_segment_time[X_AXIS][0] = xs0 + segment_time; + + if (TEST(direction_change, Y_AXIS)) { + ys2 = axis_segment_time[Y_AXIS][2] = axis_segment_time[Y_AXIS][1]; + ys1 = axis_segment_time[Y_AXIS][1] = axis_segment_time[Y_AXIS][0]; + ys0 = 0; + } + ys0 = axis_segment_time[Y_AXIS][0] = ys0 + segment_time; + + const long max_x_segment_time = MAX3(xs0, xs1, xs2), + max_y_segment_time = MAX3(ys0, ys1, ys2), + min_xy_segment_time = min(max_x_segment_time, max_y_segment_time); + if (min_xy_segment_time < MAX_FREQ_TIME) { + const float low_sf = speed_factor * min_xy_segment_time / (MAX_FREQ_TIME); + NOMORE(speed_factor, low_sf); + } + #endif // XY_FREQUENCY_LIMIT + + // Correct the speed + if (speed_factor < 1.0) { + LOOP_XYZE(i) current_speed[i] *= speed_factor; + block->nominal_speed *= speed_factor; + block->nominal_rate *= speed_factor; + } + + // Compute and limit the acceleration rate for the trapezoid generator. + const float steps_per_mm = block->step_event_count * inverse_millimeters; + uint32_t accel; + if (!block->steps[X_AXIS] && !block->steps[Y_AXIS] && !block->steps[Z_AXIS]) { + // convert to: acceleration steps/sec^2 + accel = CEIL(retract_acceleration * steps_per_mm); + } + else { + #define LIMIT_ACCEL_LONG(AXIS,INDX) do{ \ + if (block->steps[AXIS] && max_acceleration_steps_per_s2[AXIS+INDX] < accel) { \ + const uint32_t comp = max_acceleration_steps_per_s2[AXIS+INDX] * block->step_event_count; \ + if (accel * block->steps[AXIS] > comp) accel = comp / block->steps[AXIS]; \ + } \ + }while(0) + + #define LIMIT_ACCEL_FLOAT(AXIS,INDX) do{ \ + if (block->steps[AXIS] && max_acceleration_steps_per_s2[AXIS+INDX] < accel) { \ + const float comp = (float)max_acceleration_steps_per_s2[AXIS+INDX] * (float)block->step_event_count; \ + if ((float)accel * (float)block->steps[AXIS] > comp) accel = comp / (float)block->steps[AXIS]; \ + } \ + }while(0) + + // Start with print or travel acceleration + accel = CEIL((esteps ? acceleration : travel_acceleration) * steps_per_mm); + + #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(X_AXIS, 0); + LIMIT_ACCEL_LONG(Y_AXIS, 0); + LIMIT_ACCEL_LONG(Z_AXIS, 0); + LIMIT_ACCEL_LONG(E_AXIS, ACCEL_IDX); + } + else { + LIMIT_ACCEL_FLOAT(X_AXIS, 0); + LIMIT_ACCEL_FLOAT(Y_AXIS, 0); + LIMIT_ACCEL_FLOAT(Z_AXIS, 0); + LIMIT_ACCEL_FLOAT(E_AXIS, ACCEL_IDX); + } + } + block->acceleration_steps_per_s2 = accel; + block->acceleration = accel / steps_per_mm; + block->acceleration_rate = (long)(accel * 16777216.0 / ((F_CPU) * 0.125)); // * 8.388608 + + // Initial limit on the segment entry velocity + float vmax_junction; + + #if 0 // Use old jerk for now + + float junction_deviation = 0.1; + + // Compute path unit vector + double unit_vec[XYZ] = { + delta_mm[X_AXIS] * inverse_millimeters, + delta_mm[Y_AXIS] * inverse_millimeters, + delta_mm[Z_AXIS] * inverse_millimeters + }; + + /* + 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 + deviation is defined as the distance from the junction to the closest edge of the circle, + collinear with the circle center. + + The circular segment joining the two paths represents the path of centripetal acceleration. + Solve for max velocity based on max acceleration about the radius of the circle, defined + indirectly by junction deviation. + + This may be also viewed as path width or max_jerk in the previous grbl version. This approach + does not actually deviate from path, but used as a robust way to compute cornering speeds, as + it takes into account the nonlinearities of both the junction angle and junction velocity. + */ + + vmax_junction = MINIMUM_PLANNER_SPEED; // Set default max junction speed + + // Skip first block or when previous_nominal_speed is used as a flag for homing and offset cycles. + if (block_buffer_head != block_buffer_tail && previous_nominal_speed > 0.0) { + // Compute cosine of angle between previous and current path. (prev_unit_vec is negative) + // NOTE: Max junction velocity is computed without sin() or acos() by trig half angle identity. + float cos_theta = - previous_unit_vec[X_AXIS] * unit_vec[X_AXIS] + - previous_unit_vec[Y_AXIS] * unit_vec[Y_AXIS] + - previous_unit_vec[Z_AXIS] * unit_vec[Z_AXIS] ; + // Skip and use default max junction speed for 0 degree acute junction. + if (cos_theta < 0.95) { + vmax_junction = min(previous_nominal_speed, block->nominal_speed); + // Skip and avoid divide by zero for straight junctions at 180 degrees. Limit to min() of nominal speeds. + if (cos_theta > -0.95) { + // Compute maximum junction velocity based on maximum acceleration and junction deviation + float sin_theta_d2 = SQRT(0.5 * (1.0 - cos_theta)); // Trig half angle identity. Always positive. + NOMORE(vmax_junction, SQRT(block->acceleration * junction_deviation * sin_theta_d2 / (1.0 - sin_theta_d2))); + } + } + } + #endif + + /** + * Adapted from Průša MKS firmware + * https://github.com/prusa3d/Prusa-Firmware + * + * Start with a safe speed (from which the machine may halt to stop immediately). + */ + + // Exit speed limited by a jerk to full halt of a previous last segment + static float previous_safe_speed; + + float safe_speed = block->nominal_speed; + uint8_t limited = 0; + LOOP_XYZE(i) { + const float jerk = FABS(current_speed[i]), maxj = max_jerk[i]; + if (jerk > maxj) { + if (limited) { + const float mjerk = maxj * block->nominal_speed; + if (jerk * safe_speed > mjerk) safe_speed = mjerk / jerk; + } + else { + ++limited; + safe_speed = maxj; + } + } + } + + if (moves_queued > 1 && previous_nominal_speed > 0.0001) { + // Estimate a maximum velocity allowed at a joint of two successive segments. + // If this maximum velocity allowed is lower than the minimum of the entry / exit safe velocities, + // then the machine is not coasting anymore and the safe entry / exit velocities shall be used. + + // The junction velocity will be shared between successive segments. Limit the junction velocity to their minimum. + bool prev_speed_larger = previous_nominal_speed > block->nominal_speed; + float smaller_speed_factor = prev_speed_larger ? (block->nominal_speed / previous_nominal_speed) : (previous_nominal_speed / block->nominal_speed); + // Pick the smaller of the nominal speeds. Higher speed shall not be achieved at the junction during coasting. + vmax_junction = prev_speed_larger ? block->nominal_speed : previous_nominal_speed; + // Factor to multiply the previous / current nominal velocities to get componentwise limited velocities. + float v_factor = 1.f; + limited = 0; + // Now limit the jerk in all axes. + LOOP_XYZE(axis) { + // Limit an axis. We have to differentiate: coasting, reversal of an axis, full stop. + float v_exit = previous_speed[axis], v_entry = current_speed[axis]; + if (prev_speed_larger) v_exit *= smaller_speed_factor; + if (limited) { + v_exit *= v_factor; + v_entry *= v_factor; + } + + // Calculate jerk depending on whether the axis is coasting in the same direction or reversing. + const float jerk = (v_exit > v_entry) + ? // coasting axis reversal + ( (v_entry > 0.f || v_exit < 0.f) ? (v_exit - v_entry) : max(v_exit, -v_entry) ) + : // v_exit <= v_entry coasting axis reversal + ( (v_entry < 0.f || v_exit > 0.f) ? (v_entry - v_exit) : max(-v_exit, v_entry) ); + + if (jerk > max_jerk[axis]) { + v_factor *= max_jerk[axis] / jerk; + ++limited; + } + } + if (limited) vmax_junction *= v_factor; + // Now the transition velocity is known, which maximizes the shared exit / entry velocity while + // respecting the jerk factors, it may be possible, that applying separate safe exit / entry velocities will achieve faster prints. + const float vmax_junction_threshold = vmax_junction * 0.99f; + if (previous_safe_speed > vmax_junction_threshold && safe_speed > vmax_junction_threshold) { + // Not coasting. The machine will stop and start the movements anyway, + // better to start the segment from start. + SBI(block->flag, BLOCK_BIT_START_FROM_FULL_HALT); + vmax_junction = safe_speed; + } + } + else { + SBI(block->flag, BLOCK_BIT_START_FROM_FULL_HALT); + vmax_junction = safe_speed; + } + + // Max entry speed of this block equals the max exit speed of the previous block. + block->max_entry_speed = vmax_junction; + + // Initialize block entry speed. Compute based on deceleration to user-defined MINIMUM_PLANNER_SPEED. + const float v_allowable = max_allowable_speed(-block->acceleration, MINIMUM_PLANNER_SPEED, block->millimeters); + block->entry_speed = min(vmax_junction, v_allowable); + + // Initialize planner efficiency flags + // Set flag if block will always reach maximum junction speed regardless of entry/exit speeds. + // If a block can de/ac-celerate from nominal speed to zero within the length of the block, then + // the current block and next block junction speeds are guaranteed to always be at their maximum + // junction speeds in deceleration and acceleration, respectively. This is due to how the current + // block nominal speed limits both the current and next maximum junction speeds. Hence, in both + // the reverse and forward planners, the corresponding block junction speed will always be at the + // the maximum junction speed and may always be ignored for any speed reduction checks. + block->flag |= BLOCK_FLAG_RECALCULATE | (block->nominal_speed <= v_allowable ? BLOCK_FLAG_NOMINAL_LENGTH : 0); + + // Update previous path unit_vector and nominal speed + COPY(previous_speed, current_speed); + previous_nominal_speed = block->nominal_speed; + previous_safe_speed = safe_speed; + + #if ENABLED(LIN_ADVANCE) + + // + // Use LIN_ADVANCE for blocks if all these are true: + // + // esteps : We have E steps todo (a printing move) + // + // block->steps[X_AXIS] || block->steps[Y_AXIS] : We have a movement in XY direction (i.e., not retract / prime). + // + // extruder_advance_k : There is an advance factor set. + // + // block->steps[E_AXIS] != block->step_event_count : A problem occurs if the move before a retract is too small. + // In that case, the retract and move will be executed together. + // This leads to too many advance steps due to a huge e_acceleration. + // The math is good, but we must avoid retract moves with advance! + // de_float > 0.0 : Extruder is running forward (e.g., for "Wipe while retracting" (Slic3r) or "Combing" (Cura) moves) + // + block->use_advance_lead = esteps + && (block->steps[X_AXIS] || block->steps[Y_AXIS]) + && extruder_advance_k + && (uint32_t)esteps != block->step_event_count + && de_float > 0.0; + if (block->use_advance_lead) + block->abs_adv_steps_multiplier8 = LROUND( + extruder_advance_k + * (UNEAR_ZERO(advance_ed_ratio) ? de_float / mm_D_float : advance_ed_ratio) // Use the fixed ratio, if set + * (block->nominal_speed / (float)block->nominal_rate) + * axis_steps_per_mm[E_AXIS_N] * 256.0 + ); + + #endif // LIN_ADVANCE + + calculate_trapezoid_for_block(block, block->entry_speed / block->nominal_speed, safe_speed / block->nominal_speed); + + // Move buffer head + block_buffer_head = next_buffer_head; + + // Update the position (only when a move was queued) + COPY(position, target); + #if ENABLED(LIN_ADVANCE) + position_float[X_AXIS] = a; + position_float[Y_AXIS] = b; + position_float[Z_AXIS] = c; + position_float[E_AXIS] = e; + #endif + + recalculate(); + + stepper.wake_up(); + +} // buffer_line() + +/** + * Directly set the planner XYZ position (and stepper positions) + * converting mm (or angles for SCARA) into steps. + * + * On CORE machines stepper ABC will be translated from the given XYZ. + */ + +void Planner::_set_position_mm(const float &a, const float &b, const float &c, const float &e) { + #if ENABLED(DISTINCT_E_FACTORS) + #define _EINDEX (E_AXIS + active_extruder) + last_extruder = active_extruder; + #else + #define _EINDEX E_AXIS + #endif + long na = position[X_AXIS] = LROUND(a * axis_steps_per_mm[X_AXIS]), + nb = position[Y_AXIS] = LROUND(b * axis_steps_per_mm[Y_AXIS]), + nc = position[Z_AXIS] = LROUND(c * axis_steps_per_mm[Z_AXIS]), + ne = position[E_AXIS] = LROUND(e * axis_steps_per_mm[_EINDEX]); + #if ENABLED(LIN_ADVANCE) + position_float[X_AXIS] = a; + position_float[Y_AXIS] = b; + position_float[Z_AXIS] = c; + position_float[E_AXIS] = e; + #endif + stepper.set_position(na, nb, nc, ne); + previous_nominal_speed = 0.0; // Resets planner junction speeds. Assumes start from rest. + ZERO(previous_speed); +} + +void Planner::set_position_mm_kinematic(const float position[NUM_AXIS]) { + #if PLANNER_LEVELING + float lpos[XYZ] = { position[X_AXIS], position[Y_AXIS], position[Z_AXIS] }; + apply_leveling(lpos); + #else + const float * const lpos = position; + #endif + #if IS_KINEMATIC + inverse_kinematics(lpos); + _set_position_mm(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], position[E_AXIS]); + #else + _set_position_mm(lpos[X_AXIS], lpos[Y_AXIS], lpos[Z_AXIS], position[E_AXIS]); + #endif +} + +/** + * Sync from the stepper positions. (e.g., after an interrupted move) + */ +void Planner::sync_from_steppers() { + LOOP_XYZE(i) { + position[i] = stepper.position((AxisEnum)i); + #if ENABLED(LIN_ADVANCE) + position_float[i] = position[i] * steps_to_mm[i + #if ENABLED(DISTINCT_E_FACTORS) + + (i == E_AXIS ? active_extruder : 0) + #endif + ]; + #endif + } +} + +/** + * Setters for planner position (also setting stepper position). + */ +void Planner::set_position_mm(const AxisEnum axis, const float &v) { + #if ENABLED(DISTINCT_E_FACTORS) + const uint8_t axis_index = axis + (axis == E_AXIS ? active_extruder : 0); + last_extruder = active_extruder; + #else + const uint8_t axis_index = axis; + #endif + position[axis] = LROUND(v * axis_steps_per_mm[axis_index]); + #if ENABLED(LIN_ADVANCE) + position_float[axis] = v; + #endif + stepper.set_position(axis, v); + previous_speed[axis] = 0.0; +} + +// Recalculate the steps/s^2 acceleration rates, based on the mm/s^2 +void Planner::reset_acceleration_rates() { + #if ENABLED(DISTINCT_E_FACTORS) + #define HIGHEST_CONDITION (i < E_AXIS || i == E_AXIS + active_extruder) + #else + #define HIGHEST_CONDITION true + #endif + uint32_t highest_rate = 1; + LOOP_XYZE_N(i) { + max_acceleration_steps_per_s2[i] = max_acceleration_mm_per_s2[i] * axis_steps_per_mm[i]; + if (HIGHEST_CONDITION) NOLESS(highest_rate, max_acceleration_steps_per_s2[i]); + } + cutoff_long = 4294967295UL / highest_rate; +} + +// Recalculate position, steps_to_mm if axis_steps_per_mm changes! +void Planner::refresh_positioning() { + LOOP_XYZE_N(i) steps_to_mm[i] = 1.0 / axis_steps_per_mm[i]; + set_position_mm_kinematic(current_position); + reset_acceleration_rates(); +} + +#if ENABLED(AUTOTEMP) + + void Planner::autotemp_M104_M109() { + autotemp_enabled = parser.seen('F'); + if (autotemp_enabled) autotemp_factor = parser.value_celsius_diff(); + if (parser.seen('S')) autotemp_min = parser.value_celsius(); + if (parser.seen('B')) autotemp_max = parser.value_celsius(); + } + +#endif diff --git a/trunk/Arduino/Marlin_1.1.6/planner.h b/trunk/Arduino/Marlin_1.1.6/planner.h new file mode 100644 index 00000000..c47eebd8 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/planner.h @@ -0,0 +1,473 @@ +/** + * 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 . + * + */ + +/** + * planner.h + * + * Buffer movement commands and manage the acceleration profile plan + * + * Derived from Grbl + * Copyright (c) 2009-2011 Simen Svale Skogsrud + */ + +#ifndef PLANNER_H +#define PLANNER_H + +#include "types.h" +#include "enum.h" +#include "Marlin.h" + +#if HAS_ABL + #include "vector_3.h" +#endif + +enum BlockFlagBit { + // Recalculate trapezoids on entry junction. For optimization. + BLOCK_BIT_RECALCULATE, + + // Nominal speed always reached. + // i.e., The segment is long enough, so the nominal speed is reachable if accelerating + // from a safe speed (in consideration of jerking from zero speed). + BLOCK_BIT_NOMINAL_LENGTH, + + // Start from a halt at the start of this block, respecting the maximum allowed jerk. + BLOCK_BIT_START_FROM_FULL_HALT, + + // The block is busy + BLOCK_BIT_BUSY +}; + +enum BlockFlag { + BLOCK_FLAG_RECALCULATE = _BV(BLOCK_BIT_RECALCULATE), + BLOCK_FLAG_NOMINAL_LENGTH = _BV(BLOCK_BIT_NOMINAL_LENGTH), + BLOCK_FLAG_START_FROM_FULL_HALT = _BV(BLOCK_BIT_START_FROM_FULL_HALT), + BLOCK_FLAG_BUSY = _BV(BLOCK_BIT_BUSY) +}; + +/** + * struct block_t + * + * A single entry in the planner buffer. + * Tracks linear movement over multiple axes. + * + * The "nominal" values are as-specified by gcode, and + * may never actually be reached due to acceleration limits. + */ +typedef struct { + + uint8_t flag; // Block flags (See BlockFlag enum above) + + unsigned char active_extruder; // The extruder to move (if E move) + + // Fields used by the Bresenham algorithm for tracing the line + int32_t steps[NUM_AXIS]; // Step count along each axis + uint32_t step_event_count; // The number of step events required to complete this block + + #if ENABLED(MIXING_EXTRUDER) + uint32_t mix_event_count[MIXING_STEPPERS]; // Scaled step_event_count for the mixing steppers + #endif + + int32_t accelerate_until, // The index of the step event on which to stop acceleration + decelerate_after, // The index of the step event on which to start decelerating + acceleration_rate; // The acceleration rate used for acceleration calculation + + uint8_t direction_bits; // The direction bit set for this block (refers to *_DIRECTION_BIT in config.h) + + // Advance extrusion + #if ENABLED(LIN_ADVANCE) + bool use_advance_lead; + uint32_t abs_adv_steps_multiplier8; // Factorised by 2^8 to avoid float + #endif + + // Fields used by the motion planner to manage acceleration + float nominal_speed, // The nominal speed for this block in mm/sec + entry_speed, // Entry speed at previous-current junction in mm/sec + max_entry_speed, // Maximum allowable junction entry speed in mm/sec + millimeters, // The total travel of this block in mm + acceleration; // acceleration mm/sec^2 + + // Settings for the trapezoid generator + uint32_t nominal_rate, // The nominal step rate for this block in step_events/sec + initial_rate, // The jerk-adjusted step rate at start of block + final_rate, // The minimal rate at exit + acceleration_steps_per_s2; // acceleration steps/sec^2 + + #if FAN_COUNT > 0 + uint16_t fan_speed[FAN_COUNT]; + #endif + + #if ENABLED(BARICUDA) + uint8_t valve_pressure, e_to_p_pressure; + #endif + + uint32_t segment_time; + +} block_t; + +#define BLOCK_MOD(n) ((n)&(BLOCK_BUFFER_SIZE-1)) + +class Planner { + + public: + + /** + * A ring buffer of moves described in steps + */ + static block_t block_buffer[BLOCK_BUFFER_SIZE]; + static volatile uint8_t block_buffer_head, // Index of the next block to be pushed + block_buffer_tail; + + #if ENABLED(DISTINCT_E_FACTORS) + static uint8_t last_extruder; // Respond to extruder change + #endif + + static float max_feedrate_mm_s[XYZE_N], // Max speeds in mm per second + axis_steps_per_mm[XYZE_N], + steps_to_mm[XYZE_N]; + static uint32_t max_acceleration_steps_per_s2[XYZE_N], + max_acceleration_mm_per_s2[XYZE_N]; // Use M201 to override by software + + static millis_t min_segment_time; + static float min_feedrate_mm_s, + acceleration, // Normal acceleration mm/s^2 DEFAULT ACCELERATION for all printing moves. M204 SXXXX + retract_acceleration, // Retract acceleration mm/s^2 filament pull-back and push-forward while standing still in the other axes M204 TXXXX + travel_acceleration, // Travel acceleration mm/s^2 DEFAULT ACCELERATION for all NON printing moves. M204 MXXXX + max_jerk[XYZE], // The largest speed change requiring no acceleration + min_travel_feedrate_mm_s; + + #if HAS_ABL + static bool abl_enabled; // Flag that bed leveling is enabled + #if ABL_PLANAR + static matrix_3x3 bed_level_matrix; // Transform to compensate for bed level + #endif + #endif + + #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) + static float z_fade_height, inverse_z_fade_height; + #endif + + #if ENABLED(LIN_ADVANCE) + static float extruder_advance_k, advance_ed_ratio; + #endif + + private: + + /** + * The current position of the tool in absolute steps + * Recalculated if any axis_steps_per_mm are changed by gcode + */ + static long position[NUM_AXIS]; + + /** + * Speed of previous path line segment + */ + static float previous_speed[NUM_AXIS]; + + /** + * Nominal speed of previous path line segment + */ + static float previous_nominal_speed; + + /** + * Limit where 64bit math is necessary for acceleration calculation + */ + static uint32_t cutoff_long; + + #if ENABLED(DISABLE_INACTIVE_EXTRUDER) + /** + * 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 long(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 long axis_segment_time[2][3]; + #endif + + #if ENABLED(LIN_ADVANCE) + static float position_float[NUM_AXIS]; + #endif + + #if ENABLED(ULTRA_LCD) + volatile static uint32_t block_buffer_runtime_us; //Theoretical block buffer runtime in µs + #endif + + public: + + /** + * Instance Methods + */ + + Planner(); + + void init(); + + /** + * Static (class) Methods + */ + + static void reset_acceleration_rates(); + static void refresh_positioning(); + + // Manage fans, paste pressure, etc. + static void check_axes_activity(); + + /** + * Number of moves currently in the planner + */ + static uint8_t movesplanned() { return BLOCK_MOD(block_buffer_head - block_buffer_tail + BLOCK_BUFFER_SIZE); } + + static bool is_full() { return (block_buffer_tail == BLOCK_MOD(block_buffer_head + 1)); } + + #if PLANNER_LEVELING + + #define ARG_X float lx + #define ARG_Y float ly + #define ARG_Z float lz + + /** + * Apply leveling to transform a cartesian position + * as it will be given to the planner and steppers. + */ + static void apply_leveling(float &lx, float &ly, float &lz); + static void apply_leveling(float logical[XYZ]) { apply_leveling(logical[X_AXIS], logical[Y_AXIS], logical[Z_AXIS]); } + static void unapply_leveling(float logical[XYZ]); + + #else + + #define ARG_X const float &lx + #define ARG_Y const float &ly + #define ARG_Z const float &lz + + #endif + + /** + * Planner::_buffer_line + * + * Add a new direct linear movement to the buffer. + * + * Leveling and kinematics should be applied ahead of this. + * + * a,b,c,e - target position in mm or degrees + * fr_mm_s - (target) speed of the move (mm/s) + * extruder - target extruder + */ + static void _buffer_line(const float &a, const float &b, const float &c, const float &e, float fr_mm_s, const uint8_t extruder); + + static void _set_position_mm(const float &a, const float &b, const float &c, const float &e); + + /** + * Add a new linear movement to the buffer. + * The target is NOT translated to delta/scara + * + * Leveling will be applied to input on cartesians. + * Kinematic machines should call buffer_line_kinematic (for leveled moves). + * (Cartesians may also call buffer_line_kinematic.) + * + * lx,ly,lz,e - target position in mm or degrees + * fr_mm_s - (target) speed of the move (mm/s) + * extruder - target extruder + */ + static FORCE_INLINE void buffer_line(ARG_X, ARG_Y, ARG_Z, const float &e, const float &fr_mm_s, const uint8_t extruder) { + #if PLANNER_LEVELING && IS_CARTESIAN + apply_leveling(lx, ly, lz); + #endif + _buffer_line(lx, ly, lz, e, fr_mm_s, extruder); + } + + /** + * Add a new linear movement to the buffer. + * The target is cartesian, it's translated to delta/scara if + * needed. + * + * ltarget - x,y,z,e CARTESIAN target in mm + * fr_mm_s - (target) speed of the move (mm/s) + * extruder - target extruder + */ + static FORCE_INLINE void buffer_line_kinematic(const float ltarget[XYZE], const float &fr_mm_s, const uint8_t extruder) { + #if PLANNER_LEVELING + float lpos[XYZ] = { ltarget[X_AXIS], ltarget[Y_AXIS], ltarget[Z_AXIS] }; + apply_leveling(lpos); + #else + const float * const lpos = ltarget; + #endif + #if IS_KINEMATIC + inverse_kinematics(lpos); + _buffer_line(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], ltarget[E_AXIS], fr_mm_s, extruder); + #else + _buffer_line(lpos[X_AXIS], lpos[Y_AXIS], lpos[Z_AXIS], ltarget[E_AXIS], fr_mm_s, extruder); + #endif + } + + /** + * Set the planner.position and individual stepper positions. + * Used by G92, G28, G29, and other procedures. + * + * Multiplies by axis_steps_per_mm[] and does necessary conversion + * for COREXY / COREXZ / COREYZ to set the corresponding stepper positions. + * + * Clears previous speed values. + */ + static FORCE_INLINE void set_position_mm(ARG_X, ARG_Y, ARG_Z, const float &e) { + #if PLANNER_LEVELING && IS_CARTESIAN + apply_leveling(lx, ly, lz); + #endif + _set_position_mm(lx, ly, lz, e); + } + static void set_position_mm_kinematic(const float position[NUM_AXIS]); + static void set_position_mm(const AxisEnum axis, const float &v); + static FORCE_INLINE void set_z_position_mm(const float &z) { set_position_mm(Z_AXIS, z); } + static FORCE_INLINE void set_e_position_mm(const float &e) { set_position_mm(AxisEnum(E_AXIS), e); } + + /** + * Sync from the stepper positions. (e.g., after an interrupted move) + */ + static void sync_from_steppers(); + + /** + * Does the buffer have any blocks queued? + */ + static bool blocks_queued() { return (block_buffer_head != block_buffer_tail); } + + /** + * "Discards" the block and "releases" the memory. + * Called when the current block is no longer needed. + */ + static void discard_current_block() { + if (blocks_queued()) + block_buffer_tail = BLOCK_MOD(block_buffer_tail + 1); + } + + /** + * The current block. NULL if the buffer is empty. + * This also marks the block as busy. + */ + static block_t* get_current_block() { + if (blocks_queued()) { + block_t* block = &block_buffer[block_buffer_tail]; + #if ENABLED(ULTRA_LCD) + block_buffer_runtime_us -= block->segment_time; //We can't be sure how long an active block will take, so don't count it. + #endif + SBI(block->flag, BLOCK_BIT_BUSY); + return block; + } + else { + #if ENABLED(ULTRA_LCD) + clear_block_buffer_runtime(); // paranoia. Buffer is empty now - so reset accumulated time to zero. + #endif + return NULL; + } + } + + #if ENABLED(ULTRA_LCD) + + static uint16_t block_buffer_runtime() { + CRITICAL_SECTION_START + millis_t bbru = block_buffer_runtime_us; + CRITICAL_SECTION_END + // To translate µs to ms a division by 1000 would be required. + // We introduce 2.4% error here by dividing by 1024. + // Doesn't matter because block_buffer_runtime_us is already too small an estimation. + bbru >>= 10; + // limit to about a minute. + NOMORE(bbru, 0xFFFFul); + return bbru; + } + + static void clear_block_buffer_runtime(){ + CRITICAL_SECTION_START + block_buffer_runtime_us = 0; + CRITICAL_SECTION_END + } + + #endif + + #if ENABLED(AUTOTEMP) + static float autotemp_min, autotemp_max, autotemp_factor; + static bool autotemp_enabled; + static void getHighESpeed(); + static void autotemp_M104_M109(); + #endif + + private: + + /** + * Get the index of the next / previous block in the ring buffer + */ + static int8_t next_block_index(int8_t block_index) { return BLOCK_MOD(block_index + 1); } + static int8_t prev_block_index(int8_t block_index) { return BLOCK_MOD(block_index - 1); } + + /** + * Calculate the distance (not time) it takes to accelerate + * from initial_rate to target_rate using the given acceleration: + */ + static float estimate_acceleration_distance(const float &initial_rate, const float &target_rate, const float &accel) { + if (accel == 0) return 0; // accel was 0, set acceleration distance to 0 + return (sq(target_rate) - sq(initial_rate)) / (accel * 2); + } + + /** + * Return the point at which you must start braking (at the rate of -'acceleration') if + * you start at 'initial_rate', accelerate (until reaching the point), and want to end at + * 'final_rate' after traveling 'distance'. + * + * This is used to compute the intersection point between acceleration and deceleration + * in cases where the "trapezoid" has no plateau (i.e., never reaches maximum speed) + */ + static float intersection_distance(const float &initial_rate, const float &final_rate, const float &accel, const float &distance) { + if (accel == 0) return 0; // accel was 0, set intersection distance to 0 + return (accel * 2 * distance - sq(initial_rate) + sq(final_rate)) / (accel * 4); + } + + /** + * Calculate the maximum allowable speed at this point, in order + * to reach 'target_velocity' using 'acceleration' within a given + * 'distance'. + */ + static float max_allowable_speed(const float &accel, const float &target_velocity, const float &distance) { + return SQRT(sq(target_velocity) - 2 * accel * distance); + } + + static void calculate_trapezoid_for_block(block_t* const block, const float &entry_factor, const float &exit_factor); + + static void reverse_pass_kernel(block_t* const current, const block_t *next); + static void forward_pass_kernel(const block_t *previous, block_t* const current); + + static void reverse_pass(); + static void forward_pass(); + + static void recalculate_trapezoids(); + + static void recalculate(); + +}; + +#define PLANNER_XY_FEEDRATE() (min(planner.max_feedrate_mm_s[X_AXIS], planner.max_feedrate_mm_s[Y_AXIS])) + +extern Planner planner; + +#endif // PLANNER_H diff --git a/trunk/Arduino/Marlin_1.1.6/planner_bezier.cpp b/trunk/Arduino/Marlin_1.1.6/planner_bezier.cpp new file mode 100644 index 00000000..71697e04 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/planner_bezier.cpp @@ -0,0 +1,194 @@ +/** + * 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 . + * + */ + +/** + * planner_bezier.cpp + * + * Compute and buffer movement commands for bezier curves + * + */ + +#include "Marlin.h" + +#if ENABLED(BEZIER_CURVE_SUPPORT) + +#include "planner.h" +#include "language.h" +#include "temperature.h" + +// See the meaning in the documentation of cubic_b_spline(). +#define MIN_STEP 0.002 +#define MAX_STEP 0.1 +#define SIGMA 0.1 + +/* Compute the linear interpolation between to real numbers. +*/ +inline static float interp(float a, float b, float t) { return (1.0 - t) * a + t * b; } + +/** + * Compute a Bézier curve using the De Casteljau's algorithm (see + * https://en.wikipedia.org/wiki/De_Casteljau%27s_algorithm), which is + * easy to code and has good numerical stability (very important, + * since Arudino works with limited precision real numbers). + */ +inline static float eval_bezier(float a, float b, float c, float d, float t) { + float iab = interp(a, b, t); + float ibc = interp(b, c, t); + float icd = interp(c, d, t); + float iabc = interp(iab, ibc, t); + float ibcd = interp(ibc, icd, t); + float iabcd = interp(iabc, ibcd, t); + return iabcd; +} + +/** + * We approximate Euclidean distance with the sum of the coordinates + * offset (so-called "norm 1"), which is quicker to compute. + */ +inline static float dist1(float x1, float y1, float x2, float y2) { return FABS(x1 - x2) + FABS(y1 - y2); } + +/** + * The algorithm for computing the step is loosely based on the one in Kig + * (See https://sources.debian.net/src/kig/4:15.08.3-1/misc/kigpainter.cpp/#L759) + * However, we do not use the stack. + * + * The algorithm goes as it follows: the parameters t runs from 0.0 to + * 1.0 describing the curve, which is evaluated by eval_bezier(). At + * each iteration we have to choose a step, i.e., the increment of the + * t variable. By default the step of the previous iteration is taken, + * and then it is enlarged or reduced depending on how straight the + * curve locally is. The step is always clamped between MIN_STEP/2 and + * 2*MAX_STEP. MAX_STEP is taken at the first iteration. + * + * For some t, the step value is considered acceptable if the curve in + * the interval [t, t+step] is sufficiently straight, i.e., + * sufficiently close to linear interpolation. In practice the + * following test is performed: the distance between eval_bezier(..., + * t+step/2) is evaluated and compared with 0.5*(eval_bezier(..., + * t)+eval_bezier(..., t+step)). If it is smaller than SIGMA, then the + * step value is considered acceptable, otherwise it is not. The code + * seeks to find the larger step value which is considered acceptable. + * + * At every iteration the recorded step value is considered and then + * iteratively halved until it becomes acceptable. If it was already + * acceptable in the beginning (i.e., no halving were done), then + * maybe it was necessary to enlarge it; then it is iteratively + * doubled while it remains acceptable. The last acceptable value + * found is taken, provided that it is between MIN_STEP and MAX_STEP + * and does not bring t over 1.0. + * + * Caveat: this algorithm is not perfect, since it can happen that a + * step is considered acceptable even when the curve is not linear at + * all in the interval [t, t+step] (but its mid point coincides "by + * chance" with the midpoint according to the parametrization). This + * kind of glitches can be eliminated with proper first derivative + * estimates; however, given the improbability of such configurations, + * the mitigation offered by MIN_STEP and the small computational + * power available on Arduino, I think it is not wise to implement it. + */ +void cubic_b_spline(const float position[NUM_AXIS], const float target[NUM_AXIS], const float offset[4], float fr_mm_s, uint8_t extruder) { + // Absolute first and second control points are recovered. + float first0 = position[X_AXIS] + offset[0]; + float first1 = position[Y_AXIS] + offset[1]; + float second0 = target[X_AXIS] + offset[2]; + float second1 = target[Y_AXIS] + offset[3]; + float t = 0.0; + + float bez_target[4]; + bez_target[X_AXIS] = position[X_AXIS]; + bez_target[Y_AXIS] = position[Y_AXIS]; + float step = MAX_STEP; + + millis_t next_idle_ms = millis() + 200UL; + + while (t < 1.0) { + + thermalManager.manage_heater(); + millis_t now = millis(); + if (ELAPSED(now, next_idle_ms)) { + next_idle_ms = now + 200UL; + idle(); + } + + // First try to reduce the step in order to make it sufficiently + // close to a linear interpolation. + bool did_reduce = false; + float new_t = t + step; + NOMORE(new_t, 1.0); + float new_pos0 = eval_bezier(position[X_AXIS], first0, second0, target[X_AXIS], new_t); + float new_pos1 = eval_bezier(position[Y_AXIS], first1, second1, target[Y_AXIS], new_t); + for (;;) { + if (new_t - t < (MIN_STEP)) break; + float candidate_t = 0.5 * (t + new_t); + float candidate_pos0 = eval_bezier(position[X_AXIS], first0, second0, target[X_AXIS], candidate_t); + float candidate_pos1 = eval_bezier(position[Y_AXIS], first1, second1, target[Y_AXIS], candidate_t); + float interp_pos0 = 0.5 * (bez_target[X_AXIS] + new_pos0); + float interp_pos1 = 0.5 * (bez_target[Y_AXIS] + new_pos1); + if (dist1(candidate_pos0, candidate_pos1, interp_pos0, interp_pos1) <= (SIGMA)) break; + new_t = candidate_t; + new_pos0 = candidate_pos0; + new_pos1 = candidate_pos1; + did_reduce = true; + } + + // If we did not reduce the step, maybe we should enlarge it. + if (!did_reduce) for (;;) { + if (new_t - t > MAX_STEP) break; + float candidate_t = t + 2.0 * (new_t - t); + if (candidate_t >= 1.0) break; + float candidate_pos0 = eval_bezier(position[X_AXIS], first0, second0, target[X_AXIS], candidate_t); + float candidate_pos1 = eval_bezier(position[Y_AXIS], first1, second1, target[Y_AXIS], candidate_t); + float interp_pos0 = 0.5 * (bez_target[X_AXIS] + candidate_pos0); + float interp_pos1 = 0.5 * (bez_target[Y_AXIS] + candidate_pos1); + if (dist1(new_pos0, new_pos1, interp_pos0, interp_pos1) > (SIGMA)) break; + new_t = candidate_t; + new_pos0 = candidate_pos0; + new_pos1 = candidate_pos1; + } + + // Check some postcondition; they are disabled in the actual + // Marlin build, but if you test the same code on a computer you + // may want to check they are respect. + /* + assert(new_t <= 1.0); + if (new_t < 1.0) { + assert(new_t - t >= (MIN_STEP) / 2.0); + assert(new_t - t <= (MAX_STEP) * 2.0); + } + */ + + step = new_t - t; + t = new_t; + + // Compute and send new position + bez_target[X_AXIS] = new_pos0; + bez_target[Y_AXIS] = new_pos1; + // FIXME. The following two are wrong, since the parameter t is + // not linear in the distance. + bez_target[Z_AXIS] = interp(position[Z_AXIS], target[Z_AXIS], t); + bez_target[E_AXIS] = interp(position[E_AXIS], target[E_AXIS], t); + clamp_to_software_endstops(bez_target); + planner.buffer_line_kinematic(bez_target, fr_mm_s, extruder); + } +} + +#endif // BEZIER_CURVE_SUPPORT diff --git a/trunk/Arduino/Marlin_1.1.6/planner_bezier.h b/trunk/Arduino/Marlin_1.1.6/planner_bezier.h new file mode 100644 index 00000000..d17e7c80 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/planner_bezier.h @@ -0,0 +1,43 @@ +/** + * 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 . + * + */ + +/** + * planner_bezier.h + * + * Compute and buffer movement commands for bezier curves + * + */ + +#ifndef PLANNER_BEZIER_H +#define PLANNER_BEZIER_H + +#include "Marlin.h" + +void cubic_b_spline( + const float position[NUM_AXIS], // current position + const float target[NUM_AXIS], // target position + const float offset[4], // a pair of offsets + float fr_mm_s, + uint8_t extruder + ); + +#endif // PLANNER_BEZIER_H diff --git a/trunk/Arduino/Marlin_1.1.6/point_t.h b/trunk/Arduino/Marlin_1.1.6/point_t.h new file mode 100644 index 00000000..360abce6 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/point_t.h @@ -0,0 +1,77 @@ +/** + * 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 . + * + */ + +#ifndef __POINT_T__ +#define __POINT_T__ + +/** + * @brief Cartesian Point + * @details Represents a three dimensional point on Cartesian coordinate system, + * using an additional fourth dimension for the extrusion length. + * + * @param x The x-coordinate of the point. + * @param y The y-coordinate of the point. + * @param z The z-coordinate of the point. + * @param e The e-coordinate of the point. + */ +struct point_t { + float x; + float y; + float z; + float e; + + /** + * @brief Two dimensional point constructor + * + * @param x The x-coordinate of the point. + * @param y The y-coordinate of the point. + */ + point_t(float const x, float const y) + : point_t(x, y, NAN, NAN) {} + + /** + * @brief Three dimensional point constructor + * + * @param x The x-coordinate of the point. + * @param y The y-coordinate of the point. + * @param z The z-coordinate of the point. + */ + point_t(float const x, float const y, float const z) + : point_t(x, y, z, NAN) {} + + /** + * @brief Tree dimensional point constructor with extrusion length + * + * @param x The x-coordinate of the point. + * @param y The y-coordinate of the point. + * @param z The z-coordinate of the point. + * @param e The e-coordinate of the point. + */ + point_t(float const x, float const y, float const z, float const e) { + this->x = x; + this->y = y; + this->z = z; + this->e = e; + } +}; + +#endif // __POINT_T__ diff --git a/trunk/Arduino/Marlin_1.1.6/printcounter.cpp b/trunk/Arduino/Marlin_1.1.6/printcounter.cpp new file mode 100644 index 00000000..6edc0ac8 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/printcounter.cpp @@ -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 . + * + */ + +#include "Marlin.h" +#include "printcounter.h" +#include "duration_t.h" + +PrintCounter::PrintCounter(): super() { + this->loadStats(); +} + +millis_t PrintCounter::deltaDuration() { + #if ENABLED(DEBUG_PRINTCOUNTER) + PrintCounter::debug(PSTR("deltaDuration")); + #endif + + millis_t tmp = this->lastDuration; + this->lastDuration = this->duration(); + return this->lastDuration - tmp; +} + +bool PrintCounter::isLoaded() { + return this->loaded; +} + +void PrintCounter::incFilamentUsed(double const &amount) { + #if ENABLED(DEBUG_PRINTCOUNTER) + PrintCounter::debug(PSTR("incFilamentUsed")); + #endif + + // Refuses to update data if object is not loaded + if (!this->isLoaded()) return; + + this->data.filamentUsed += amount; // mm +} + + +void PrintCounter::initStats() { + #if ENABLED(DEBUG_PRINTCOUNTER) + PrintCounter::debug(PSTR("initStats")); + #endif + + this->loaded = true; + this->data = { 0, 0, 0, 0, 0.0 }; + + this->saveStats(); + eeprom_write_byte((uint8_t *) this->address, 0x16); +} + +void PrintCounter::loadStats() { + #if ENABLED(DEBUG_PRINTCOUNTER) + PrintCounter::debug(PSTR("loadStats")); + #endif + + // Checks if the EEPROM block is initialized + if (eeprom_read_byte((uint8_t *) this->address) != 0x16) this->initStats(); + else eeprom_read_block(&this->data, + (void *)(this->address + sizeof(uint8_t)), sizeof(printStatistics)); + + this->loaded = true; +} + +void PrintCounter::saveStats() { + #if ENABLED(DEBUG_PRINTCOUNTER) + PrintCounter::debug(PSTR("saveStats")); + #endif + + // Refuses to save data if object is not loaded + if (!this->isLoaded()) return; + + // Saves the struct to EEPROM + eeprom_update_block(&this->data, + (void *)(this->address + sizeof(uint8_t)), sizeof(printStatistics)); +} + +void PrintCounter::showStats() { + char buffer[21]; + duration_t elapsed; + + SERIAL_PROTOCOLPGM(MSG_STATS); + + SERIAL_ECHOPGM("Prints: "); + SERIAL_ECHO(this->data.totalPrints); + + SERIAL_ECHOPGM(", Finished: "); + SERIAL_ECHO(this->data.finishedPrints); + + SERIAL_ECHOPGM(", Failed: "); // Note: Removes 1 from failures with an active counter + SERIAL_ECHO(this->data.totalPrints - this->data.finishedPrints + - ((this->isRunning() || this->isPaused()) ? 1 : 0)); + + SERIAL_EOL(); + SERIAL_PROTOCOLPGM(MSG_STATS); + + elapsed = this->data.printTime; + elapsed.toString(buffer); + + SERIAL_ECHOPGM("Total time: "); + SERIAL_ECHO(buffer); + + #if ENABLED(DEBUG_PRINTCOUNTER) + SERIAL_ECHOPGM(" ("); + SERIAL_ECHO(this->data.printTime); + SERIAL_CHAR(')'); + #endif + + elapsed = this->data.longestPrint; + elapsed.toString(buffer); + + SERIAL_ECHOPGM(", Longest job: "); + SERIAL_ECHO(buffer); + + #if ENABLED(DEBUG_PRINTCOUNTER) + SERIAL_ECHOPGM(" ("); + SERIAL_ECHO(this->data.longestPrint); + SERIAL_CHAR(')'); + #endif + + SERIAL_EOL(); + SERIAL_PROTOCOLPGM(MSG_STATS); + + SERIAL_ECHOPGM("Filament used: "); + SERIAL_ECHO(this->data.filamentUsed / 1000); + SERIAL_ECHOPGM("m"); + + SERIAL_EOL(); +} + +void PrintCounter::tick() { + if (!this->isRunning()) return; + + static uint32_t update_last = millis(), + eeprom_last = millis(); + + millis_t now = millis(); + + // Trying to get the amount of calculations down to the bare min + const static uint16_t i = this->updateInterval * 1000; + + if (now - update_last >= i) { + #if ENABLED(DEBUG_PRINTCOUNTER) + PrintCounter::debug(PSTR("tick")); + #endif + + this->data.printTime += this->deltaDuration(); + update_last = now; + } + + // Trying to get the amount of calculations down to the bare min + const static millis_t j = this->saveInterval * 1000; + if (now - eeprom_last >= j) { + eeprom_last = now; + this->saveStats(); + } +} + +// @Override +bool PrintCounter::start() { + #if ENABLED(DEBUG_PRINTCOUNTER) + PrintCounter::debug(PSTR("start")); + #endif + + bool paused = this->isPaused(); + + if (super::start()) { + if (!paused) { + this->data.totalPrints++; + this->lastDuration = 0; + } + return true; + } + + return false; +} + +// @Override +bool PrintCounter::stop() { + #if ENABLED(DEBUG_PRINTCOUNTER) + PrintCounter::debug(PSTR("stop")); + #endif + + if (super::stop()) { + this->data.finishedPrints++; + this->data.printTime += this->deltaDuration(); + + if (this->duration() > this->data.longestPrint) + this->data.longestPrint = this->duration(); + + this->saveStats(); + return true; + } + else return false; +} + +// @Override +void PrintCounter::reset() { + #if ENABLED(DEBUG_PRINTCOUNTER) + PrintCounter::debug(PSTR("stop")); + #endif + + super::reset(); + this->lastDuration = 0; +} + +#if ENABLED(DEBUG_PRINTCOUNTER) + + void PrintCounter::debug(const char func[]) { + if (DEBUGGING(INFO)) { + SERIAL_ECHOPGM("PrintCounter::"); + serialprintPGM(func); + SERIAL_ECHOLNPGM("()"); + } + } + +#endif diff --git a/trunk/Arduino/Marlin_1.1.6/printcounter.h b/trunk/Arduino/Marlin_1.1.6/printcounter.h new file mode 100644 index 00000000..0eeded9d --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/printcounter.h @@ -0,0 +1,175 @@ +/** + * 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 . + * + */ + +#ifndef PRINTCOUNTER_H +#define PRINTCOUNTER_H + +#include "macros.h" +#include "language.h" +#include "stopwatch.h" +#include + + +// Print debug messages with M111 S2 +//#define DEBUG_PRINTCOUNTER + +struct printStatistics { // 16 bytes (20 with real doubles) + //const uint8_t magic; // Magic header, it will always be 0x16 + uint16_t totalPrints; // Number of prints + uint16_t finishedPrints; // Number of complete prints + uint32_t printTime; // Accumulated printing time + uint32_t longestPrint; // Longest successful print job + double filamentUsed; // Accumulated filament consumed in mm +}; + +class PrintCounter: public Stopwatch { + private: + typedef Stopwatch super; + + printStatistics data; + + /** + * @brief EEPROM address + * @details Defines the start offset address where the data is stored. + */ + const uint16_t address = 0x32; + + /** + * @brief Interval in seconds between counter updates + * @details This const value defines what will be the time between each + * accumulator update. This is different from the EEPROM save interval. + * + * @note The max value for this option is 60(s), otherwise integer + * overflow will happen. + */ + const uint16_t updateInterval = 10; + + /** + * @brief Interval in seconds between EEPROM saves + * @details This const value defines what will be the time between each + * EEPROM save cycle, the development team recommends to set this value + * no lower than 3600 secs (1 hour). + */ + const uint16_t saveInterval = 3600; + + /** + * @brief Timestamp of the last call to deltaDuration() + * @details Stores the timestamp of the last deltaDuration(), this is + * required due to the updateInterval cycle. + */ + millis_t lastDuration; + + /** + * @brief Stats were loaded from EERPROM + * @details If set to true it indicates if the statistical data was already + * loaded from the EEPROM. + */ + bool loaded = false; + + protected: + /** + * @brief dT since the last call + * @details Returns the elapsed time in seconds since the last call, this is + * used internally for print statistics accounting is not intended to be a + * user callable function. + */ + millis_t deltaDuration(); + + public: + /** + * @brief Class constructor + */ + PrintCounter(); + + /** + * @brief Checks if Print Statistics has been loaded + * @details Returns true if the statistical data has been loaded. + * @return bool + */ + bool isLoaded(); + + /** + * @brief Increments the total filament used + * @details The total filament used counter will be incremented by "amount". + * + * @param amount The amount of filament used in mm + */ + void incFilamentUsed(double const &amount); + + /** + * @brief Resets the Print Statistics + * @details Resets the statistics to zero and saves them to EEPROM creating + * also the magic header. + */ + void initStats(); + + /** + * @brief Loads the Print Statistics + * @details Loads the statistics from EEPROM + */ + void loadStats(); + + /** + * @brief Saves the Print Statistics + * @details Saves the statistics to EEPROM + */ + void saveStats(); + + /** + * @brief Serial output the Print Statistics + * @details This function may change in the future, for now it directly + * prints the statistical data to serial. + */ + void showStats(); + + /** + * @brief Return the currently loaded statistics + * @details Return the raw data, in the same structure used internally + */ + printStatistics getStats() { return this->data; } + + /** + * @brief Loop function + * @details This function should be called at loop, it will take care of + * periodically save the statistical data to EEPROM and do time keeping. + */ + void tick(); + + /** + * The following functions are being overridden + */ + bool start(); + bool stop(); + void reset(); + + #if ENABLED(DEBUG_PRINTCOUNTER) + + /** + * @brief Prints a debug message + * @details Prints a simple debug message "PrintCounter::function" + */ + static void debug(const char func[]); + + #endif +}; + +#endif // PRINTCOUNTER_H diff --git a/trunk/Arduino/Marlin_1.1.6/serial.cpp b/trunk/Arduino/Marlin_1.1.6/serial.cpp new file mode 100644 index 00000000..232a85c3 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/serial.cpp @@ -0,0 +1,36 @@ +/** + * 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 . + * + */ + +#include "serial.h" + +const char errormagic[] PROGMEM = "Error:"; +const char echomagic[] PROGMEM = "echo:"; + +void serial_echopair_P(const char* s_P, const char *v) { serialprintPGM(s_P); SERIAL_ECHO(v); } +void serial_echopair_P(const char* s_P, char v) { serialprintPGM(s_P); SERIAL_CHAR(v); } +void serial_echopair_P(const char* s_P, int v) { serialprintPGM(s_P); SERIAL_ECHO(v); } +void serial_echopair_P(const char* s_P, long v) { serialprintPGM(s_P); SERIAL_ECHO(v); } +void serial_echopair_P(const char* s_P, float v) { serialprintPGM(s_P); SERIAL_ECHO(v); } +void serial_echopair_P(const char* s_P, double v) { serialprintPGM(s_P); SERIAL_ECHO(v); } +void serial_echopair_P(const char* s_P, unsigned long v) { serialprintPGM(s_P); SERIAL_ECHO(v); } + +void serial_spaces(uint8_t count) { count *= (PROPORTIONAL_FONT_RATIO); while (count--) MYSERIAL.write(' '); } diff --git a/trunk/Arduino/Marlin_1.1.6/serial.h b/trunk/Arduino/Marlin_1.1.6/serial.h new file mode 100644 index 00000000..a4b6799d --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/serial.h @@ -0,0 +1,101 @@ +/** + * 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 . + * + */ + +#ifndef __SERIAL_H__ +#define __SERIAL_H__ + +#include "MarlinConfig.h" + +#ifdef USBCON + #include "HardwareSerial.h" + #if ENABLED(BLUETOOTH) + #define MYSERIAL bluetoothSerial + #else + #define MYSERIAL Serial + #endif // BLUETOOTH +#else + #include "MarlinSerial.h" + #define MYSERIAL customizedSerial +#endif + +extern const char echomagic[] PROGMEM; +extern const char errormagic[] PROGMEM; + +#define SERIAL_CHAR(x) ((void)MYSERIAL.write(x)) +#define SERIAL_EOL() SERIAL_CHAR('\n') + +#define SERIAL_PROTOCOLCHAR(x) SERIAL_CHAR(x) +#define SERIAL_PROTOCOL(x) (MYSERIAL.print(x)) +#define SERIAL_PROTOCOL_F(x,y) (MYSERIAL.print(x,y)) +#define SERIAL_PROTOCOLPGM(x) (serialprintPGM(PSTR(x))) +#define SERIAL_PROTOCOLLN(x) do{ MYSERIAL.print(x); SERIAL_EOL(); }while(0) +#define SERIAL_PROTOCOLLNPGM(x) (serialprintPGM(PSTR(x "\n"))) +#define SERIAL_PROTOCOLPAIR(name, value) (serial_echopair_P(PSTR(name),(value))) +#define SERIAL_PROTOCOLLNPAIR(name, value) do{ SERIAL_PROTOCOLPAIR(name, value); SERIAL_EOL(); }while(0) + +#define SERIAL_ECHO_START() (serialprintPGM(echomagic)) +#define SERIAL_ECHO(x) SERIAL_PROTOCOL(x) +#define SERIAL_ECHOPGM(x) SERIAL_PROTOCOLPGM(x) +#define SERIAL_ECHOLN(x) SERIAL_PROTOCOLLN(x) +#define SERIAL_ECHOLNPGM(x) SERIAL_PROTOCOLLNPGM(x) +#define SERIAL_ECHOPAIR(pre,value) SERIAL_PROTOCOLPAIR(pre, value) +#define SERIAL_ECHOLNPAIR(pre,value) SERIAL_PROTOCOLLNPAIR(pre, value) +#define SERIAL_ECHO_F(x,y) SERIAL_PROTOCOL_F(x,y) + +#define SERIAL_ERROR_START() (serialprintPGM(errormagic)) +#define SERIAL_ERROR(x) SERIAL_PROTOCOL(x) +#define SERIAL_ERRORPGM(x) SERIAL_PROTOCOLPGM(x) +#define SERIAL_ERRORLN(x) SERIAL_PROTOCOLLN(x) +#define SERIAL_ERRORLNPGM(x) SERIAL_PROTOCOLLNPGM(x) + +// These macros compensate for float imprecision +#define SERIAL_PROTOCOLPAIR_F(pre, value) SERIAL_PROTOCOLPAIR(pre, FIXFLOAT(value)) +#define SERIAL_PROTOCOLLNPAIR_F(pre, value) SERIAL_PROTOCOLLNPAIR(pre, FIXFLOAT(value)) +#define SERIAL_ECHOPAIR_F(pre,value) SERIAL_ECHOPAIR(pre, FIXFLOAT(value)) +#define SERIAL_ECHOLNPAIR_F(pre, value) SERIAL_ECHOLNPAIR(pre, FIXFLOAT(value)) + +void serial_echopair_P(const char* s_P, const char *v); +void serial_echopair_P(const char* s_P, char v); +void serial_echopair_P(const char* s_P, int v); +void serial_echopair_P(const char* s_P, long v); +void serial_echopair_P(const char* s_P, float v); +void serial_echopair_P(const char* s_P, double v); +void serial_echopair_P(const char* s_P, unsigned int v); +void serial_echopair_P(const char* s_P, unsigned long v); +FORCE_INLINE void serial_echopair_P(const char* s_P, uint8_t v) { serial_echopair_P(s_P, (int)v); } +FORCE_INLINE void serial_echopair_P(const char* s_P, uint16_t v) { serial_echopair_P(s_P, (int)v); } +FORCE_INLINE void serial_echopair_P(const char* s_P, bool v) { serial_echopair_P(s_P, (int)v); } +FORCE_INLINE void serial_echopair_P(const char* s_P, void *v) { serial_echopair_P(s_P, (unsigned long)v); } + +void serial_spaces(uint8_t count); +#define SERIAL_ECHO_SP(C) serial_spaces(C) +#define SERIAL_ERROR_SP(C) serial_spaces(C) +#define SERIAL_PROTOCOL_SP(C) serial_spaces(C) + +// +// Functions for serial printing from PROGMEM. (Saves loads of SRAM.) +// +FORCE_INLINE void serialprintPGM(const char* str) { + while (char ch = pgm_read_byte(str++)) MYSERIAL.write(ch); +} + +#endif // __SERIAL_H__ diff --git a/trunk/Arduino/Marlin_1.1.6/servo.cpp b/trunk/Arduino/Marlin_1.1.6/servo.cpp new file mode 100644 index 00000000..d6b7b700 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/servo.cpp @@ -0,0 +1,322 @@ +/** + * 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 . + * + */ + +/** + * servo.cpp - Interrupt driven Servo library for Arduino using 16 bit timers- Version 2 + * Copyright (c) 2009 Michael Margolis. All right reserved. + */ + +/** + * 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 + * + * Note that analogWrite of PWM on pins associated with the timer are disabled when the first servo is attached. + * Timers are seized as needed in groups of 12 servos - 24 servos use two timers, 48 servos will use four. + * + * The methods are: + * + * Servo - Class for manipulating servo motors connected to Arduino pins. + * + * attach(pin) - Attach a servo motor to an i/o pin. + * attach(pin, min, max) - Attach to a pin, setting min and max values in microseconds + * Default min is 544, max is 2400 + * + * write() - Set the servo angle in degrees. (Invalid angles —over MIN_PULSE_WIDTH— are treated as µs.) + * writeMicroseconds() - Set the servo pulse width in microseconds. + * move(pin, angle) - Sequence of attach(pin), write(angle), delay(SERVO_DELAY). + * With DEACTIVATE_SERVOS_AFTER_MOVE it detaches after SERVO_DELAY. + * read() - Get the last-written servo pulse width as an angle between 0 and 180. + * 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 "MarlinConfig.h" + +#if HAS_SERVOS + +#include +#include + +#include "servo.h" + +#define usToTicks(_us) (( clockCyclesPerMicrosecond()* _us) / 8) // converts microseconds to tick (assumes prescale of 8) // 12 Aug 2009 +#define ticksToUs(_ticks) (( (unsigned)_ticks * 8)/ clockCyclesPerMicrosecond() ) // converts from ticks back to microseconds + +#define TRIM_DURATION 2 // compensation ticks to trim adjust for digitalWrite delays // 12 August 2009 + +//#define NBR_TIMERS ((MAX_SERVOS) / (SERVOS_PER_TIMER)) + +static ServoInfo_t servo_info[MAX_SERVOS]; // static array of servo info structures +static volatile int8_t Channel[_Nbr_16timers ]; // counter for the servo being pulsed for each timer (or -1 if refresh interval) + +uint8_t ServoCount = 0; // the total number of attached servos + + +// convenience macros +#define SERVO_INDEX_TO_TIMER(_servo_nbr) ((timer16_Sequence_t)(_servo_nbr / (SERVOS_PER_TIMER))) // returns the timer controlling this servo +#define SERVO_INDEX_TO_CHANNEL(_servo_nbr) (_servo_nbr % (SERVOS_PER_TIMER)) // returns the index of the servo on this timer +#define SERVO_INDEX(_timer,_channel) ((_timer*(SERVOS_PER_TIMER)) + _channel) // macro to access servo index by timer and channel +#define SERVO(_timer,_channel) (servo_info[SERVO_INDEX(_timer,_channel)]) // macro to access servo class by timer and channel + +#define SERVO_MIN() (MIN_PULSE_WIDTH - this->min * 4) // minimum value in uS for this servo +#define SERVO_MAX() (MAX_PULSE_WIDTH - this->max * 4) // maximum value in uS for this servo + +/************ static functions common to all instances ***********************/ + +static inline void handle_interrupts(timer16_Sequence_t timer, volatile uint16_t* TCNTn, volatile uint16_t* OCRnA) { + if (Channel[timer] < 0) + *TCNTn = 0; // channel set to -1 indicated that refresh interval completed so reset the timer + else { + if (SERVO_INDEX(timer, Channel[timer]) < ServoCount && SERVO(timer, Channel[timer]).Pin.isActive) + digitalWrite(SERVO(timer, Channel[timer]).Pin.nbr, LOW); // pulse this channel low if activated + } + + Channel[timer]++; // increment to the next channel + if (SERVO_INDEX(timer, Channel[timer]) < ServoCount && Channel[timer] < SERVOS_PER_TIMER) { + *OCRnA = *TCNTn + SERVO(timer, Channel[timer]).ticks; + if (SERVO(timer, Channel[timer]).Pin.isActive) // check if activated + digitalWrite(SERVO(timer, Channel[timer]).Pin.nbr, HIGH); // it's an active channel so pulse it high + } + else { + // finished all channels so wait for the refresh period to expire before starting over + if (((unsigned)*TCNTn) + 4 < usToTicks(REFRESH_INTERVAL)) // allow a few ticks to ensure the next OCR1A not missed + *OCRnA = (unsigned int)usToTicks(REFRESH_INTERVAL); + else + *OCRnA = *TCNTn + 4; // at least REFRESH_INTERVAL has elapsed + Channel[timer] = -1; // this will get incremented at the end of the refresh period to start again at the first channel + } +} + +#ifndef WIRING // Wiring pre-defines signal handlers so don't define any if compiling for the Wiring platform + + // Interrupt handlers for Arduino + #if ENABLED(_useTimer1) + SIGNAL (TIMER1_COMPA_vect) { handle_interrupts(_timer1, &TCNT1, &OCR1A); } + #endif + + #if ENABLED(_useTimer3) + SIGNAL (TIMER3_COMPA_vect) { handle_interrupts(_timer3, &TCNT3, &OCR3A); } + #endif + + #if ENABLED(_useTimer4) + SIGNAL (TIMER4_COMPA_vect) { handle_interrupts(_timer4, &TCNT4, &OCR4A); } + #endif + + #if ENABLED(_useTimer5) + SIGNAL (TIMER5_COMPA_vect) { handle_interrupts(_timer5, &TCNT5, &OCR5A); } + #endif + +#else // WIRING + + // Interrupt handlers for Wiring + #if ENABLED(_useTimer1) + void Timer1Service() { handle_interrupts(_timer1, &TCNT1, &OCR1A); } + #endif + #if ENABLED(_useTimer3) + void Timer3Service() { handle_interrupts(_timer3, &TCNT3, &OCR3A); } + #endif + +#endif // WIRING + + +static void initISR(timer16_Sequence_t timer) { + #if ENABLED(_useTimer1) + if (timer == _timer1) { + TCCR1A = 0; // normal counting mode + TCCR1B = _BV(CS11); // set prescaler of 8 + TCNT1 = 0; // clear the timer count + #if defined(__AVR_ATmega8__)|| defined(__AVR_ATmega128__) + SBI(TIFR, OCF1A); // clear any pending interrupts; + SBI(TIMSK, OCIE1A); // enable the output compare interrupt + #else + // here if not ATmega8 or ATmega128 + SBI(TIFR1, OCF1A); // clear any pending interrupts; + SBI(TIMSK1, OCIE1A); // enable the output compare interrupt + #endif + #ifdef WIRING + timerAttach(TIMER1OUTCOMPAREA_INT, Timer1Service); + #endif + } + #endif + + #if ENABLED(_useTimer3) + if (timer == _timer3) { + TCCR3A = 0; // normal counting mode + TCCR3B = _BV(CS31); // set prescaler of 8 + TCNT3 = 0; // clear the timer count + #ifdef __AVR_ATmega128__ + SBI(TIFR, OCF3A); // clear any pending interrupts; + SBI(ETIMSK, OCIE3A); // enable the output compare interrupt + #else + SBI(TIFR3, OCF3A); // clear any pending interrupts; + SBI(TIMSK3, OCIE3A); // enable the output compare interrupt + #endif + #ifdef WIRING + timerAttach(TIMER3OUTCOMPAREA_INT, Timer3Service); // for Wiring platform only + #endif + } + #endif + + #if ENABLED(_useTimer4) + if (timer == _timer4) { + TCCR4A = 0; // normal counting mode + TCCR4B = _BV(CS41); // set prescaler of 8 + TCNT4 = 0; // clear the timer count + TIFR4 = _BV(OCF4A); // clear any pending interrupts; + TIMSK4 = _BV(OCIE4A); // enable the output compare interrupt + } + #endif + + #if ENABLED(_useTimer5) + if (timer == _timer5) { + TCCR5A = 0; // normal counting mode + TCCR5B = _BV(CS51); // set prescaler of 8 + TCNT5 = 0; // clear the timer count + TIFR5 = _BV(OCF5A); // clear any pending interrupts; + TIMSK5 = _BV(OCIE5A); // enable the output compare interrupt + } + #endif +} + +static void finISR(timer16_Sequence_t timer) { + // Disable use of the given timer + #ifdef WIRING + if (timer == _timer1) { + CBI( + #if defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__) + TIMSK1 + #else + TIMSK + #endif + , OCIE1A); // disable timer 1 output compare interrupt + timerDetach(TIMER1OUTCOMPAREA_INT); + } + else if (timer == _timer3) { + CBI( + #if defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__) + TIMSK3 + #else + ETIMSK + #endif + , OCIE3A); // disable the timer3 output compare A interrupt + timerDetach(TIMER3OUTCOMPAREA_INT); + } + #else // !WIRING + // For arduino - in future: call here to a currently undefined function to reset the timer + UNUSED(timer); + #endif +} + +static bool 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++) { + if (SERVO(timer, channel).Pin.isActive) + return true; + } + return false; +} + + +/****************** end of static functions ******************************/ + +Servo::Servo() { + if (ServoCount < MAX_SERVOS) { + this->servoIndex = ServoCount++; // assign a servo index to this instance + servo_info[this->servoIndex].ticks = usToTicks(DEFAULT_PULSE_WIDTH); // store default values - 12 Aug 2009 + } + else + this->servoIndex = INVALID_SERVO; // too many servos +} + +int8_t Servo::attach(int pin) { + return this->attach(pin, MIN_PULSE_WIDTH, MAX_PULSE_WIDTH); +} + +int8_t Servo::attach(int pin, int min, int max) { + + if (this->servoIndex >= MAX_SERVOS) return -1; + + if (pin > 0) servo_info[this->servoIndex].Pin.nbr = pin; + pinMode(servo_info[this->servoIndex].Pin.nbr, OUTPUT); // set servo pin to output + + // todo min/max check: abs(min - MIN_PULSE_WIDTH) /4 < 128 + this->min = (MIN_PULSE_WIDTH - min) / 4; //resolution of min/max is 4 uS + this->max = (MAX_PULSE_WIDTH - max) / 4; + + // initialize the timer if it has not already been initialized + timer16_Sequence_t timer = SERVO_INDEX_TO_TIMER(servoIndex); + if (!isTimerActive(timer)) initISR(timer); + servo_info[this->servoIndex].Pin.isActive = true; // this must be set after the check for isTimerActive + + return this->servoIndex; +} + +void Servo::detach() { + servo_info[this->servoIndex].Pin.isActive = false; + timer16_Sequence_t timer = SERVO_INDEX_TO_TIMER(servoIndex); + if (!isTimerActive(timer)) finISR(timer); +} + +void Servo::write(int value) { + if (value < MIN_PULSE_WIDTH) { // treat values less than 544 as angles in degrees (valid values in microseconds are handled as microseconds) + value = map(constrain(value, 0, 180), 0, 180, SERVO_MIN(), SERVO_MAX()); + } + this->writeMicroseconds(value); +} + +void Servo::writeMicroseconds(int value) { + // calculate and store the values for the given channel + byte channel = this->servoIndex; + if (channel < MAX_SERVOS) { // ensure channel is valid + // ensure pulse width is valid + value = constrain(value, SERVO_MIN(), SERVO_MAX()) - (TRIM_DURATION); + value = usToTicks(value); // convert to ticks after compensating for interrupt overhead - 12 Aug 2009 + + CRITICAL_SECTION_START; + servo_info[channel].ticks = value; + CRITICAL_SECTION_END; + } +} + +// return the value as degrees +int Servo::read() { return map(this->readMicroseconds() + 1, SERVO_MIN(), SERVO_MAX(), 0, 180); } + +int Servo::readMicroseconds() { + return (this->servoIndex == INVALID_SERVO) ? 0 : ticksToUs(servo_info[this->servoIndex].ticks) + TRIM_DURATION; +} + +bool Servo::attached() { return servo_info[this->servoIndex].Pin.isActive; } + +void Servo::move(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 (this->attach(0) >= 0) { + this->write(value); + delay(servo_delay[this->servoIndex]); + #if ENABLED(DEACTIVATE_SERVOS_AFTER_MOVE) + this->detach(); + #endif + } +} + +#endif diff --git a/trunk/Arduino/Marlin_1.1.6/servo.h b/trunk/Arduino/Marlin_1.1.6/servo.h new file mode 100644 index 00000000..ad75b6ba --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/servo.h @@ -0,0 +1,161 @@ +/** + * 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 . + * + */ + +/** + servo.h - Interrupt driven Servo library for Arduino using 16 bit timers- Version 2 + Copyright (c) 2009 Michael Margolis. 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 +*/ + +/** + + 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 + + Note that analogWrite of PWM on pins associated with the timer are disabled when the first servo is attached. + Timers are seized as needed in groups of 12 servos - 24 servos use two timers, 48 servos will use four. + The sequence used to seize timers is defined in timers.h + + The methods are: + + Servo - Class for manipulating servo motors connected to Arduino pins. + + attach(pin ) - Attaches a servo motor to an i/o pin. + attach(pin, min, max ) - Attaches to a pin setting min and max values in microseconds + default min is 544, max is 2400 + + write() - Sets the servo angle in degrees. (invalid angle that is valid as pulse in microseconds is treated as microseconds) + writeMicroseconds() - Sets the servo pulse width in microseconds + read() - Gets the last written servo pulse width as an angle between 0 and 180. + readMicroseconds() - Gets the last written servo pulse width in microseconds. (was read_us() in first release) + attached() - Returns true if there is a servo attached. + detach() - Stops an attached servos from pulsing its i/o pin. + move(angle) - Sequence of attach(0), write(angle), + With DEACTIVATE_SERVOS_AFTER_MOVE wait SERVO_DELAY and detach. + */ + +#ifndef servo_h +#define servo_h + +#include + +/** + * Defines for 16 bit timers used with Servo library + * + * If _useTimerX is defined then TimerX is a 16 bit timer on the current board + * timer16_Sequence_t enumerates the sequence that the timers should be allocated + * _Nbr_16timers indicates how many 16 bit timers are available. + * + */ + +// Say which 16 bit timers can be used and in what order +#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) + //#define _useTimer1 // Timer 1 is used by the stepper ISR + #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. + #endif +#elif defined(__AVR_ATmega32U4__) + #define _useTimer3 +#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) + #define _useTimer3 +#elif defined(__AVR_ATmega128__) || defined(__AVR_ATmega1281__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega2561__) + #define _useTimer3 +#else + // everything else +#endif + +typedef enum { + #if ENABLED(_useTimer1) + _timer1, + #endif + #if ENABLED(_useTimer3) + _timer3, + #endif + #if ENABLED(_useTimer4) + _timer4, + #endif + #if ENABLED(_useTimer5) + _timer5, + #endif + _Nbr_16timers +} timer16_Sequence_t; + + +#define Servo_VERSION 2 // software version of this library + +#define MIN_PULSE_WIDTH 544 // the shortest pulse sent to a servo +#define MAX_PULSE_WIDTH 2400 // the longest pulse sent to a servo +#define DEFAULT_PULSE_WIDTH 1500 // default pulse width when servo is attached +#define REFRESH_INTERVAL 20000 // minimum time to refresh servos in microseconds + +#define SERVOS_PER_TIMER 12 // the maximum number of servos controlled by one timer +#define MAX_SERVOS (_Nbr_16timers * SERVOS_PER_TIMER) + +#define INVALID_SERVO 255 // flag indicating an invalid servo index + +typedef struct { + uint8_t nbr : 6 ; // a pin number from 0 to 63 + uint8_t isActive : 1 ; // true if this channel is enabled, pin not pulsed if false +} ServoPin_t; + +typedef struct { + ServoPin_t Pin; + unsigned int ticks; +} ServoInfo_t; + +class Servo { + public: + Servo(); + int8_t attach(int pin); // attach the given pin to the next free channel, set pinMode, return channel number (-1 on fail) + int8_t attach(int pin, int min, int max); // as above but also sets min and max values for writes. + void detach(); + void write(int value); // if value is < 200 it is treated as an angle, otherwise as pulse width in microseconds + void writeMicroseconds(int value); // write pulse width in microseconds + void move(int value); // attach the servo, then move to value + // if value is < 200 it is treated as an angle, otherwise as pulse width in microseconds + // if DEACTIVATE_SERVOS_AFTER_MOVE wait SERVO_DELAY, then detach + int read(); // returns current pulse width as an angle between 0 and 180 degrees + int readMicroseconds(); // returns current pulse width in microseconds for this servo (was read_us() in first release) + bool attached(); // return true if this servo is attached, otherwise false + + private: + uint8_t servoIndex; // index into the channel data for this servo + int8_t min; // minimum is this value times 4 added to MIN_PULSE_WIDTH + int8_t max; // maximum is this value times 4 added to MAX_PULSE_WIDTH +}; + +#endif diff --git a/trunk/Arduino/Marlin_1.1.6/softspi.h b/trunk/Arduino/Marlin_1.1.6/softspi.h new file mode 100644 index 00000000..3b77e443 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/softspi.h @@ -0,0 +1,770 @@ +//https://github.com/niteris/ArduinoSoftSpi + +#include +#ifdef __arm__ +#ifdef CORE_TEENSY +//------------------------------------------------------------------------------ +/** read pin value + * @param[in] pin Arduino pin number + * @return value read + */ +static inline __attribute__((always_inline)) +bool fastDigitalRead(uint8_t pin) { + return *portInputRegister(pin); +} +//------------------------------------------------------------------------------ +/** Set pin value + * @param[in] pin Arduino pin number + * @param[in] level value to write + */ +static inline __attribute__((always_inline)) +void fastDigitalWrite(uint8_t pin, bool value) { + if (value) { + *portSetRegister(pin) = 1; + } else { + *portClearRegister(pin) = 1; + } +} +#else // CORE_TEENSY +//------------------------------------------------------------------------------ +/** read pin value + * @param[in] pin Arduino pin number + * @return value read + */ +static inline __attribute__((always_inline)) +bool fastDigitalRead(uint8_t pin){ + return g_APinDescription[pin].pPort->PIO_PDSR & g_APinDescription[pin].ulPin; +} +//------------------------------------------------------------------------------ +/** Set pin value + * @param[in] pin Arduino pin number + * @param[in] level value to write + */ +static inline __attribute__((always_inline)) +void fastDigitalWrite(uint8_t pin, bool value){ + if(value) { + g_APinDescription[pin].pPort->PIO_SODR = g_APinDescription[pin].ulPin; + } else { + g_APinDescription[pin].pPort->PIO_CODR = g_APinDescription[pin].ulPin; + } +} +#endif // CORE_TEENSY +//------------------------------------------------------------------------------ +inline void fastDigitalToggle(uint8_t pin) { + fastDigitalWrite(pin, !fastDigitalRead(pin)); + } +//------------------------------------------------------------------------------ +inline void fastPinMode(uint8_t pin, bool mode) {pinMode(pin, mode);} +#else // __arm__ +#include +#include +//------------------------------------------------------------------------------ +/** + * @class pin_map_t + * @brief struct for mapping digital pins + */ +struct pin_map_t { + volatile uint8_t* ddr; /**< address of DDR for this pin */ + volatile uint8_t* pin; /**< address of PIN for this pin */ + volatile uint8_t* port; /**< address of PORT for this pin */ + uint8_t bit; /**< bit number for this pin */ +}; +//------------------------------------------------------------------------------ +#if defined(__AVR_ATmega168__)\ +||defined(__AVR_ATmega168P__)\ +||defined(__AVR_ATmega328P__) +// 168 and 328 Arduinos +const static pin_map_t pinMap[] = { + {&DDRD, &PIND, &PORTD, 0}, // D0 0 + {&DDRD, &PIND, &PORTD, 1}, // D1 1 + {&DDRD, &PIND, &PORTD, 2}, // D2 2 + {&DDRD, &PIND, &PORTD, 3}, // D3 3 + {&DDRD, &PIND, &PORTD, 4}, // D4 4 + {&DDRD, &PIND, &PORTD, 5}, // D5 5 + {&DDRD, &PIND, &PORTD, 6}, // D6 6 + {&DDRD, &PIND, &PORTD, 7}, // D7 7 + {&DDRB, &PINB, &PORTB, 0}, // B0 8 + {&DDRB, &PINB, &PORTB, 1}, // B1 9 + {&DDRB, &PINB, &PORTB, 2}, // B2 10 + {&DDRB, &PINB, &PORTB, 3}, // B3 11 + {&DDRB, &PINB, &PORTB, 4}, // B4 12 + {&DDRB, &PINB, &PORTB, 5}, // B5 13 + {&DDRC, &PINC, &PORTC, 0}, // C0 14 + {&DDRC, &PINC, &PORTC, 1}, // C1 15 + {&DDRC, &PINC, &PORTC, 2}, // C2 16 + {&DDRC, &PINC, &PORTC, 3}, // C3 17 + {&DDRC, &PINC, &PORTC, 4}, // C4 18 + {&DDRC, &PINC, &PORTC, 5} // C5 19 +}; +//------------------------------------------------------------------------------ +#elif defined(__AVR_ATmega1280__)\ +|| defined(__AVR_ATmega2560__) +// Mega +static const pin_map_t pinMap[] = { + {&DDRE, &PINE, &PORTE, 0}, // E0 0 + {&DDRE, &PINE, &PORTE, 1}, // E1 1 + {&DDRE, &PINE, &PORTE, 4}, // E4 2 + {&DDRE, &PINE, &PORTE, 5}, // E5 3 + {&DDRG, &PING, &PORTG, 5}, // G5 4 + {&DDRE, &PINE, &PORTE, 3}, // E3 5 + {&DDRH, &PINH, &PORTH, 3}, // H3 6 + {&DDRH, &PINH, &PORTH, 4}, // H4 7 + {&DDRH, &PINH, &PORTH, 5}, // H5 8 + {&DDRH, &PINH, &PORTH, 6}, // H6 9 + {&DDRB, &PINB, &PORTB, 4}, // B4 10 + {&DDRB, &PINB, &PORTB, 5}, // B5 11 + {&DDRB, &PINB, &PORTB, 6}, // B6 12 + {&DDRB, &PINB, &PORTB, 7}, // B7 13 + {&DDRJ, &PINJ, &PORTJ, 1}, // J1 14 + {&DDRJ, &PINJ, &PORTJ, 0}, // J0 15 + {&DDRH, &PINH, &PORTH, 1}, // H1 16 + {&DDRH, &PINH, &PORTH, 0}, // H0 17 + {&DDRD, &PIND, &PORTD, 3}, // D3 18 + {&DDRD, &PIND, &PORTD, 2}, // D2 19 + {&DDRD, &PIND, &PORTD, 1}, // D1 20 + {&DDRD, &PIND, &PORTD, 0}, // D0 21 + {&DDRA, &PINA, &PORTA, 0}, // A0 22 + {&DDRA, &PINA, &PORTA, 1}, // A1 23 + {&DDRA, &PINA, &PORTA, 2}, // A2 24 + {&DDRA, &PINA, &PORTA, 3}, // A3 25 + {&DDRA, &PINA, &PORTA, 4}, // A4 26 + {&DDRA, &PINA, &PORTA, 5}, // A5 27 + {&DDRA, &PINA, &PORTA, 6}, // A6 28 + {&DDRA, &PINA, &PORTA, 7}, // A7 29 + {&DDRC, &PINC, &PORTC, 7}, // C7 30 + {&DDRC, &PINC, &PORTC, 6}, // C6 31 + {&DDRC, &PINC, &PORTC, 5}, // C5 32 + {&DDRC, &PINC, &PORTC, 4}, // C4 33 + {&DDRC, &PINC, &PORTC, 3}, // C3 34 + {&DDRC, &PINC, &PORTC, 2}, // C2 35 + {&DDRC, &PINC, &PORTC, 1}, // C1 36 + {&DDRC, &PINC, &PORTC, 0}, // C0 37 + {&DDRD, &PIND, &PORTD, 7}, // D7 38 + {&DDRG, &PING, &PORTG, 2}, // G2 39 + {&DDRG, &PING, &PORTG, 1}, // G1 40 + {&DDRG, &PING, &PORTG, 0}, // G0 41 + {&DDRL, &PINL, &PORTL, 7}, // L7 42 + {&DDRL, &PINL, &PORTL, 6}, // L6 43 + {&DDRL, &PINL, &PORTL, 5}, // L5 44 + {&DDRL, &PINL, &PORTL, 4}, // L4 45 + {&DDRL, &PINL, &PORTL, 3}, // L3 46 + {&DDRL, &PINL, &PORTL, 2}, // L2 47 + {&DDRL, &PINL, &PORTL, 1}, // L1 48 + {&DDRL, &PINL, &PORTL, 0}, // L0 49 + {&DDRB, &PINB, &PORTB, 3}, // B3 50 + {&DDRB, &PINB, &PORTB, 2}, // B2 51 + {&DDRB, &PINB, &PORTB, 1}, // B1 52 + {&DDRB, &PINB, &PORTB, 0}, // B0 53 + {&DDRF, &PINF, &PORTF, 0}, // F0 54 + {&DDRF, &PINF, &PORTF, 1}, // F1 55 + {&DDRF, &PINF, &PORTF, 2}, // F2 56 + {&DDRF, &PINF, &PORTF, 3}, // F3 57 + {&DDRF, &PINF, &PORTF, 4}, // F4 58 + {&DDRF, &PINF, &PORTF, 5}, // F5 59 + {&DDRF, &PINF, &PORTF, 6}, // F6 60 + {&DDRF, &PINF, &PORTF, 7}, // F7 61 + {&DDRK, &PINK, &PORTK, 0}, // K0 62 + {&DDRK, &PINK, &PORTK, 1}, // K1 63 + {&DDRK, &PINK, &PORTK, 2}, // K2 64 + {&DDRK, &PINK, &PORTK, 3}, // K3 65 + {&DDRK, &PINK, &PORTK, 4}, // K4 66 + {&DDRK, &PINK, &PORTK, 5}, // K5 67 + {&DDRK, &PINK, &PORTK, 6}, // K6 68 + {&DDRK, &PINK, &PORTK, 7}, // K7 69 + +//pins_MIGHTYBOARD_REVE.h + {&DDRG, &PING, &PORTG, 4}, // G4 70 + {&DDRG, &PING, &PORTG, 3}, // G3 71 + {&DDRJ, &PINJ, &PORTJ, 2}, // J2 72 + {&DDRJ, &PINJ, &PORTJ, 3}, // J3 73 + {&DDRJ, &PINJ, &PORTJ, 7}, // J7 74 + {&DDRJ, &PINJ, &PORTJ, 4}, // J4 75 + {&DDRJ, &PINJ, &PORTJ, 5}, // J5 76 + {&DDRJ, &PINJ, &PORTJ, 6}, // J6 77 + {&DDRE, &PINE, &PORTE, 2}, // E2 78 + {&DDRE, &PINE, &PORTE, 6} // E6 79 + +}; +//------------------------------------------------------------------------------ +#elif defined(__AVR_ATmega1284P__)\ +|| defined(__AVR_ATmega1284__)\ +|| defined(__AVR_ATmega644P__)\ +|| defined(__AVR_ATmega644__)\ +|| defined(__AVR_ATmega64__)\ +|| defined(__AVR_ATmega32__)\ +|| defined(__AVR_ATmega324__)\ +|| defined(__AVR_ATmega16__) + +#if defined(VARIANT_MIGHTY) +// Mighty Layout +static const pin_map_t pinMap[] = { + {&DDRB, &PINB, &PORTB, 0}, // B0 0 + {&DDRB, &PINB, &PORTB, 1}, // B1 1 + {&DDRB, &PINB, &PORTB, 2}, // B2 2 + {&DDRB, &PINB, &PORTB, 3}, // B3 3 + {&DDRB, &PINB, &PORTB, 4}, // B4 4 + {&DDRB, &PINB, &PORTB, 5}, // B5 5 + {&DDRB, &PINB, &PORTB, 6}, // B6 6 + {&DDRB, &PINB, &PORTB, 7}, // B7 7 + {&DDRD, &PIND, &PORTD, 0}, // D0 8 + {&DDRD, &PIND, &PORTD, 1}, // D1 9 + {&DDRD, &PIND, &PORTD, 2}, // D2 10 + {&DDRD, &PIND, &PORTD, 3}, // D3 11 + {&DDRD, &PIND, &PORTD, 4}, // D4 12 + {&DDRD, &PIND, &PORTD, 5}, // D5 13 + {&DDRD, &PIND, &PORTD, 6}, // D6 14 + {&DDRD, &PIND, &PORTD, 7}, // D7 15 + {&DDRC, &PINC, &PORTC, 0}, // C0 16 + {&DDRC, &PINC, &PORTC, 1}, // C1 17 + {&DDRC, &PINC, &PORTC, 2}, // C2 18 + {&DDRC, &PINC, &PORTC, 3}, // C3 19 + {&DDRC, &PINC, &PORTC, 4}, // C4 20 + {&DDRC, &PINC, &PORTC, 5}, // C5 21 + {&DDRC, &PINC, &PORTC, 6}, // C6 22 + {&DDRC, &PINC, &PORTC, 7}, // C7 23 + {&DDRA, &PINA, &PORTA, 0}, // A0 24 + {&DDRA, &PINA, &PORTA, 1}, // A1 25 + {&DDRA, &PINA, &PORTA, 2}, // A2 26 + {&DDRA, &PINA, &PORTA, 3}, // A3 27 + {&DDRA, &PINA, &PORTA, 4}, // A4 28 + {&DDRA, &PINA, &PORTA, 5}, // A5 29 + {&DDRA, &PINA, &PORTA, 6}, // A6 30 + {&DDRA, &PINA, &PORTA, 7} // A7 31 +}; +#elif defined(VARIANT_BOBUINO) +// Bobuino Layout +static const pin_map_t pinMap[] = { + {&DDRD, &PIND, &PORTD, 0}, // D0 0 + {&DDRD, &PIND, &PORTD, 1}, // D1 1 + {&DDRD, &PIND, &PORTD, 2}, // D2 2 + {&DDRD, &PIND, &PORTD, 3}, // D3 3 + {&DDRB, &PINB, &PORTB, 0}, // B0 4 + {&DDRB, &PINB, &PORTB, 1}, // B1 5 + {&DDRB, &PINB, &PORTB, 2}, // B2 6 + {&DDRB, &PINB, &PORTB, 3}, // B3 7 + {&DDRD, &PIND, &PORTD, 5}, // D5 8 + {&DDRD, &PIND, &PORTD, 6}, // D6 9 + {&DDRB, &PINB, &PORTB, 4}, // B4 10 + {&DDRB, &PINB, &PORTB, 5}, // B5 11 + {&DDRB, &PINB, &PORTB, 6}, // B6 12 + {&DDRB, &PINB, &PORTB, 7}, // B7 13 + {&DDRA, &PINA, &PORTA, 7}, // A7 14 + {&DDRA, &PINA, &PORTA, 6}, // A6 15 + {&DDRA, &PINA, &PORTA, 5}, // A5 16 + {&DDRA, &PINA, &PORTA, 4}, // A4 17 + {&DDRA, &PINA, &PORTA, 3}, // A3 18 + {&DDRA, &PINA, &PORTA, 2}, // A2 19 + {&DDRA, &PINA, &PORTA, 1}, // A1 20 + {&DDRA, &PINA, &PORTA, 0}, // A0 21 + {&DDRC, &PINC, &PORTC, 0}, // C0 22 + {&DDRC, &PINC, &PORTC, 1}, // C1 23 + {&DDRC, &PINC, &PORTC, 2}, // C2 24 + {&DDRC, &PINC, &PORTC, 3}, // C3 25 + {&DDRC, &PINC, &PORTC, 4}, // C4 26 + {&DDRC, &PINC, &PORTC, 5}, // C5 27 + {&DDRC, &PINC, &PORTC, 6}, // C6 28 + {&DDRC, &PINC, &PORTC, 7}, // C7 29 + {&DDRD, &PIND, &PORTD, 4}, // D4 30 + {&DDRD, &PIND, &PORTD, 7} // D7 31 +}; +#elif defined(VARIANT_STANDARD) +// Standard Layout +static const pin_map_t pinMap[] = { + {&DDRB, &PINB, &PORTB, 0}, // B0 0 + {&DDRB, &PINB, &PORTB, 1}, // B1 1 + {&DDRB, &PINB, &PORTB, 2}, // B2 2 + {&DDRB, &PINB, &PORTB, 3}, // B3 3 + {&DDRB, &PINB, &PORTB, 4}, // B4 4 + {&DDRB, &PINB, &PORTB, 5}, // B5 5 + {&DDRB, &PINB, &PORTB, 6}, // B6 6 + {&DDRB, &PINB, &PORTB, 7}, // B7 7 + {&DDRD, &PIND, &PORTD, 0}, // D0 8 + {&DDRD, &PIND, &PORTD, 1}, // D1 9 + {&DDRD, &PIND, &PORTD, 2}, // D2 10 + {&DDRD, &PIND, &PORTD, 3}, // D3 11 + {&DDRD, &PIND, &PORTD, 4}, // D4 12 + {&DDRD, &PIND, &PORTD, 5}, // D5 13 + {&DDRD, &PIND, &PORTD, 6}, // D6 14 + {&DDRD, &PIND, &PORTD, 7}, // D7 15 + {&DDRC, &PINC, &PORTC, 0}, // C0 16 + {&DDRC, &PINC, &PORTC, 1}, // C1 17 + {&DDRC, &PINC, &PORTC, 2}, // C2 18 + {&DDRC, &PINC, &PORTC, 3}, // C3 19 + {&DDRC, &PINC, &PORTC, 4}, // C4 20 + {&DDRC, &PINC, &PORTC, 5}, // C5 21 + {&DDRC, &PINC, &PORTC, 6}, // C6 22 + {&DDRC, &PINC, &PORTC, 7}, // C7 23 + {&DDRA, &PINA, &PORTA, 7}, // A7 24 + {&DDRA, &PINA, &PORTA, 6}, // A6 25 + {&DDRA, &PINA, &PORTA, 5}, // A5 26 + {&DDRA, &PINA, &PORTA, 4}, // A4 27 + {&DDRA, &PINA, &PORTA, 3}, // A3 28 + {&DDRA, &PINA, &PORTA, 2}, // A2 29 + {&DDRA, &PINA, &PORTA, 1}, // A1 30 + {&DDRA, &PINA, &PORTA, 0} // A0 31 +}; +#else // VARIANT_MIGHTY +#error Undefined variant 1284, 644, 324, 64, 32 +#endif // VARIANT_MIGHTY +//------------------------------------------------------------------------------ +#elif defined(__AVR_ATmega32U4__) +#ifdef CORE_TEENSY +// Teensy 2.0 +static const pin_map_t pinMap[] = { + {&DDRB, &PINB, &PORTB, 0}, // B0 0 + {&DDRB, &PINB, &PORTB, 1}, // B1 1 + {&DDRB, &PINB, &PORTB, 2}, // B2 2 + {&DDRB, &PINB, &PORTB, 3}, // B3 3 + {&DDRB, &PINB, &PORTB, 7}, // B7 4 + {&DDRD, &PIND, &PORTD, 0}, // D0 5 + {&DDRD, &PIND, &PORTD, 1}, // D1 6 + {&DDRD, &PIND, &PORTD, 2}, // D2 7 + {&DDRD, &PIND, &PORTD, 3}, // D3 8 + {&DDRC, &PINC, &PORTC, 6}, // C6 9 + {&DDRC, &PINC, &PORTC, 7}, // C7 10 + {&DDRD, &PIND, &PORTD, 6}, // D6 11 + {&DDRD, &PIND, &PORTD, 7}, // D7 12 + {&DDRB, &PINB, &PORTB, 4}, // B4 13 + {&DDRB, &PINB, &PORTB, 5}, // B5 14 + {&DDRB, &PINB, &PORTB, 6}, // B6 15 + {&DDRF, &PINF, &PORTF, 7}, // F7 16 + {&DDRF, &PINF, &PORTF, 6}, // F6 17 + {&DDRF, &PINF, &PORTF, 5}, // F5 18 + {&DDRF, &PINF, &PORTF, 4}, // F4 19 + {&DDRF, &PINF, &PORTF, 1}, // F1 20 + {&DDRF, &PINF, &PORTF, 0}, // F0 21 + {&DDRD, &PIND, &PORTD, 4}, // D4 22 + {&DDRD, &PIND, &PORTD, 5}, // D5 23 + {&DDRE, &PINE, &PORTE, 6} // E6 24 +}; +//------------------------------------------------------------------------------ +#else // CORE_TEENSY +// Leonardo +static const pin_map_t pinMap[] = { + {&DDRD, &PIND, &PORTD, 2}, // D2 0 + {&DDRD, &PIND, &PORTD, 3}, // D3 1 + {&DDRD, &PIND, &PORTD, 1}, // D1 2 + {&DDRD, &PIND, &PORTD, 0}, // D0 3 + {&DDRD, &PIND, &PORTD, 4}, // D4 4 + {&DDRC, &PINC, &PORTC, 6}, // C6 5 + {&DDRD, &PIND, &PORTD, 7}, // D7 6 + {&DDRE, &PINE, &PORTE, 6}, // E6 7 + {&DDRB, &PINB, &PORTB, 4}, // B4 8 + {&DDRB, &PINB, &PORTB, 5}, // B5 9 + {&DDRB, &PINB, &PORTB, 6}, // B6 10 + {&DDRB, &PINB, &PORTB, 7}, // B7 11 + {&DDRD, &PIND, &PORTD, 6}, // D6 12 + {&DDRC, &PINC, &PORTC, 7}, // C7 13 + {&DDRB, &PINB, &PORTB, 3}, // B3 14 + {&DDRB, &PINB, &PORTB, 1}, // B1 15 + {&DDRB, &PINB, &PORTB, 2}, // B2 16 + {&DDRB, &PINB, &PORTB, 0}, // B0 17 + {&DDRF, &PINF, &PORTF, 7}, // F7 18 + {&DDRF, &PINF, &PORTF, 6}, // F6 19 + {&DDRF, &PINF, &PORTF, 5}, // F5 20 + {&DDRF, &PINF, &PORTF, 4}, // F4 21 + {&DDRF, &PINF, &PORTF, 1}, // F1 22 + {&DDRF, &PINF, &PORTF, 0}, // F0 23 + {&DDRD, &PIND, &PORTD, 4}, // D4 24 + {&DDRD, &PIND, &PORTD, 7}, // D7 25 + {&DDRB, &PINB, &PORTB, 4}, // B4 26 + {&DDRB, &PINB, &PORTB, 5}, // B5 27 + {&DDRB, &PINB, &PORTB, 6}, // B6 28 + {&DDRD, &PIND, &PORTD, 6} // D6 29 +}; +#endif // CORE_TEENSY +//------------------------------------------------------------------------------ +#elif defined(__AVR_AT90USB646__)\ +|| defined(__AVR_AT90USB1286__) +// Teensy++ 1.0 & 2.0 +static const pin_map_t pinMap[] = { + {&DDRD, &PIND, &PORTD, 0}, // D0 0 + {&DDRD, &PIND, &PORTD, 1}, // D1 1 + {&DDRD, &PIND, &PORTD, 2}, // D2 2 + {&DDRD, &PIND, &PORTD, 3}, // D3 3 + {&DDRD, &PIND, &PORTD, 4}, // D4 4 + {&DDRD, &PIND, &PORTD, 5}, // D5 5 + {&DDRD, &PIND, &PORTD, 6}, // D6 6 + {&DDRD, &PIND, &PORTD, 7}, // D7 7 + {&DDRE, &PINE, &PORTE, 0}, // E0 8 + {&DDRE, &PINE, &PORTE, 1}, // E1 9 + {&DDRC, &PINC, &PORTC, 0}, // C0 10 + {&DDRC, &PINC, &PORTC, 1}, // C1 11 + {&DDRC, &PINC, &PORTC, 2}, // C2 12 + {&DDRC, &PINC, &PORTC, 3}, // C3 13 + {&DDRC, &PINC, &PORTC, 4}, // C4 14 + {&DDRC, &PINC, &PORTC, 5}, // C5 15 + {&DDRC, &PINC, &PORTC, 6}, // C6 16 + {&DDRC, &PINC, &PORTC, 7}, // C7 17 + {&DDRE, &PINE, &PORTE, 6}, // E6 18 + {&DDRE, &PINE, &PORTE, 7}, // E7 19 + {&DDRB, &PINB, &PORTB, 0}, // B0 20 + {&DDRB, &PINB, &PORTB, 1}, // B1 21 + {&DDRB, &PINB, &PORTB, 2}, // B2 22 + {&DDRB, &PINB, &PORTB, 3}, // B3 23 + {&DDRB, &PINB, &PORTB, 4}, // B4 24 + {&DDRB, &PINB, &PORTB, 5}, // B5 25 + {&DDRB, &PINB, &PORTB, 6}, // B6 26 + {&DDRB, &PINB, &PORTB, 7}, // B7 27 + {&DDRA, &PINA, &PORTA, 0}, // A0 28 + {&DDRA, &PINA, &PORTA, 1}, // A1 29 + {&DDRA, &PINA, &PORTA, 2}, // A2 30 + {&DDRA, &PINA, &PORTA, 3}, // A3 31 + {&DDRA, &PINA, &PORTA, 4}, // A4 32 + {&DDRA, &PINA, &PORTA, 5}, // A5 33 + {&DDRA, &PINA, &PORTA, 6}, // A6 34 + {&DDRA, &PINA, &PORTA, 7}, // A7 35 + {&DDRE, &PINE, &PORTE, 4}, // E4 36 + {&DDRE, &PINE, &PORTE, 5}, // E5 37 + {&DDRF, &PINF, &PORTF, 0}, // F0 38 + {&DDRF, &PINF, &PORTF, 1}, // F1 39 + {&DDRF, &PINF, &PORTF, 2}, // F2 40 + {&DDRF, &PINF, &PORTF, 3}, // F3 41 + {&DDRF, &PINF, &PORTF, 4}, // F4 42 + {&DDRF, &PINF, &PORTF, 5}, // F5 43 + {&DDRF, &PINF, &PORTF, 6}, // F6 44 + {&DDRF, &PINF, &PORTF, 7} // F7 45 +}; +//------------------------------------------------------------------------------ +#else // CPU type +#error unknown CPU type +#endif // CPU type +//------------------------------------------------------------------------------ +/** count of pins */ +static const uint8_t digitalPinCount = sizeof(pinMap)/sizeof(pin_map_t); +//============================================================================== +/** generate bad pin number error */ +void badPinNumber(void) + __attribute__((error("Pin number is too large or not a constant"))); +//------------------------------------------------------------------------------ +/** Check for valid pin number + * @param[in] pin Number of pin to be checked. + */ +static inline __attribute__((always_inline)) +void badPinCheck(uint8_t pin) { + if (!__builtin_constant_p(pin) || pin >= digitalPinCount) { + badPinNumber(); + } +} +//------------------------------------------------------------------------------ +/** fast write helper + * @param[in] address I/O register address + * @param[in] bit bit number to write + * @param[in] level value for bit + */ +static inline __attribute__((always_inline)) +void fastBitWriteSafe(volatile uint8_t* address, uint8_t bit, bool level) { + uint8_t oldSREG; + if (address > (uint8_t*)0x5F) { + oldSREG = SREG; + cli(); + } + if (level) { + *address |= 1 << bit; + } else { + *address &= ~(1 << bit); + } + if (address > (uint8_t*)0x5F) { + SREG = oldSREG; + } +} +//------------------------------------------------------------------------------ +/** read pin value + * @param[in] pin Arduino pin number + * @return value read + */ +static inline __attribute__((always_inline)) +bool fastDigitalRead(uint8_t pin) { + badPinCheck(pin); + return (*pinMap[pin].pin >> pinMap[pin].bit) & 1; +} +//------------------------------------------------------------------------------ +/** toggle a pin + * @param[in] pin Arduino pin number + * + * If the pin is in output mode toggle the pin level. + * If the pin is in input mode toggle the state of the 20K pullup. + */ +static inline __attribute__((always_inline)) +void fastDigitalToggle(uint8_t pin) { + badPinCheck(pin); + if (pinMap[pin].pin > (uint8_t*)0x5F) { + // must write bit to high address port + *pinMap[pin].pin = 1 << pinMap[pin].bit; + } else { + // will compile to sbi and PIN register will not be read. + *pinMap[pin].pin |= 1 << pinMap[pin].bit; + } +} +//------------------------------------------------------------------------------ +/** Set pin value + * @param[in] pin Arduino pin number + * @param[in] level value to write + */ +static inline __attribute__((always_inline)) +void fastDigitalWrite(uint8_t pin, bool level) { + badPinCheck(pin); + fastBitWriteSafe(pinMap[pin].port, pinMap[pin].bit, level); +} +//------------------------------------------------------------------------------ +/** set pin mode + * @param[in] pin Arduino pin number + * @param[in] mode if true set output mode else input mode + * + * fastPinMode does not enable or disable the 20K pullup for input mode. + */ +static inline __attribute__((always_inline)) +void fastPinMode(uint8_t pin, bool mode) { + badPinCheck(pin); + fastBitWriteSafe(pinMap[pin].ddr, pinMap[pin].bit, mode); +} + +#endif // __arm__ +//------------------------------------------------------------------------------ +/** set pin configuration + * @param[in] pin Arduino pin number + * @param[in] mode If true set output mode else input mode + * @param[in] level If mode is output, set level high/low. + * If mode is input, enable or disable the pin's 20K pullup. + */ +static inline __attribute__((always_inline)) +void fastPinConfig(uint8_t pin, bool mode, bool level) { + fastPinMode(pin, mode); + fastDigitalWrite(pin, level); +} +//============================================================================== +/** + * @class DigitalPin + * @brief Fast digital port I/O + */ +template +class DigitalPin { + public: + //---------------------------------------------------------------------------- + /** Constructor */ + DigitalPin() {} + //---------------------------------------------------------------------------- + /** Constructor + * @param[in] pinMode if true set output mode else input mode. + */ + explicit DigitalPin(bool pinMode) { + mode(pinMode); + } + //---------------------------------------------------------------------------- + /** Constructor + * @param[in] mode If true set output mode else input mode + * @param[in] level If mode is output, set level high/low. + * If mode is input, enable or disable the pin's 20K pullup. + */ + DigitalPin(bool mode, bool level) { + config(mode, level); + } + //---------------------------------------------------------------------------- + /** Asignment operator + * @param[in] value If true set the pin's level high else set the + * pin's level low. + * + * @return This DigitalPin instance. + */ + inline DigitalPin & operator = (bool value) __attribute__((always_inline)) { + write(value); + return *this; + } + //---------------------------------------------------------------------------- + /** Parenthesis operator + * @return Pin's level + */ + inline operator bool () const __attribute__((always_inline)) { + return read(); + } + //---------------------------------------------------------------------------- + /** set pin configuration + * @param[in] mode If true set output mode else input mode + * @param[in] level If mode is output, set level high/low. + * If mode is input, enable or disable the pin's 20K pullup. + */ + inline __attribute__((always_inline)) + void config(bool mode, bool level) { + fastPinConfig(PinNumber, mode, level); + } + //---------------------------------------------------------------------------- + /** + * Set pin level high if output mode or enable 20K pullup if input mode. + */ + inline __attribute__((always_inline)) + void high() {write(true);} + //---------------------------------------------------------------------------- + /** + * Set pin level low if output mode or disable 20K pullup if input mode. + */ + inline __attribute__((always_inline)) + void low() {write(false);} + //---------------------------------------------------------------------------- + /** + * Set pin mode + * @param[in] pinMode if true set output mode else input mode. + * + * mode() does not enable or disable the 20K pullup for input mode. + */ + inline __attribute__((always_inline)) + void mode(bool pinMode) { + fastPinMode(PinNumber, pinMode); + } + //---------------------------------------------------------------------------- + /** @return Pin's level */ + inline __attribute__((always_inline)) + bool read() const { + return fastDigitalRead(PinNumber); + } + //---------------------------------------------------------------------------- + /** toggle a pin + * + * If the pin is in output mode toggle the pin's level. + * If the pin is in input mode toggle the state of the 20K pullup. + */ + inline __attribute__((always_inline)) + void toggle() { + fastDigitalToggle(PinNumber); + } + //---------------------------------------------------------------------------- + /** Write the pin's level. + * @param[in] value If true set the pin's level high else set the + * pin's level low. + */ + inline __attribute__((always_inline)) + void write(bool value) { + fastDigitalWrite(PinNumber, value); + } +}; + +//------------------------------------------------------------------------------ +/** Nop for timing. */ +#define nop asm volatile ("nop\n\t") +//------------------------------------------------------------------------------ +/** Pin Mode for MISO is input.*/ +const bool MISO_MODE = false; +/** Pullups disabled for MISO are disabled. */ +const bool MISO_LEVEL = false; +/** Pin Mode for MOSI is output.*/ +const bool MOSI_MODE = true; +/** Pin Mode for SCK is output. */ +const bool SCK_MODE = true; +//------------------------------------------------------------------------------ +/** + * @class SoftSPI + * @brief Fast software SPI. + */ +template +class SoftSPI { + public: + //---------------------------------------------------------------------------- + /** Initialize SoftSPI pins. */ + void begin() { + fastPinConfig(MisoPin, MISO_MODE, MISO_LEVEL); + fastPinConfig(MosiPin, MOSI_MODE, !MODE_CPHA(Mode)); + fastPinConfig(SckPin, SCK_MODE, MODE_CPOL(Mode)); + } + //---------------------------------------------------------------------------- + /** Soft SPI receive byte. + * @return Data byte received. + */ + inline __attribute__((always_inline)) + uint8_t receive() { + uint8_t data = 0; + receiveBit(7, &data); + receiveBit(6, &data); + receiveBit(5, &data); + receiveBit(4, &data); + receiveBit(3, &data); + receiveBit(2, &data); + receiveBit(1, &data); + receiveBit(0, &data); + return data; + } + //---------------------------------------------------------------------------- + /** Soft SPI send byte. + * @param[in] data Data byte to send. + */ + inline __attribute__((always_inline)) + void send(uint8_t data) { + sendBit(7, data); + sendBit(6, data); + sendBit(5, data); + sendBit(4, data); + sendBit(3, data); + sendBit(2, data); + sendBit(1, data); + sendBit(0, data); + } + //---------------------------------------------------------------------------- + /** Soft SPI transfer byte. + * @param[in] txData Data byte to send. + * @return Data byte received. + */ + inline __attribute__((always_inline)) + uint8_t transfer(uint8_t txData) { + uint8_t rxData = 0; + transferBit(7, &rxData, txData); + transferBit(6, &rxData, txData); + transferBit(5, &rxData, txData); + transferBit(4, &rxData, txData); + transferBit(3, &rxData, txData); + transferBit(2, &rxData, txData); + transferBit(1, &rxData, txData); + transferBit(0, &rxData, txData); + return rxData; + } + + private: + //---------------------------------------------------------------------------- + inline __attribute__((always_inline)) + bool MODE_CPHA(uint8_t mode) {return (mode & 1) != 0;} + inline __attribute__((always_inline)) + bool MODE_CPOL(uint8_t mode) {return (mode & 2) != 0;} + inline __attribute__((always_inline)) + void receiveBit(uint8_t bit, uint8_t* data) { + if (MODE_CPHA(Mode)) { + fastDigitalWrite(SckPin, !MODE_CPOL(Mode)); + } + nop; + nop; + fastDigitalWrite(SckPin, + MODE_CPHA(Mode) ? MODE_CPOL(Mode) : !MODE_CPOL(Mode)); + if (fastDigitalRead(MisoPin)) *data |= 1 << bit; + if (!MODE_CPHA(Mode)) { + fastDigitalWrite(SckPin, MODE_CPOL(Mode)); + } + } + //---------------------------------------------------------------------------- + inline __attribute__((always_inline)) + void sendBit(uint8_t bit, uint8_t data) { + if (MODE_CPHA(Mode)) { + fastDigitalWrite(SckPin, !MODE_CPOL(Mode)); + } + fastDigitalWrite(MosiPin, data & (1 << bit)); + fastDigitalWrite(SckPin, + MODE_CPHA(Mode) ? MODE_CPOL(Mode) : !MODE_CPOL(Mode)); + nop; + nop; + if (!MODE_CPHA(Mode)) { + fastDigitalWrite(SckPin, MODE_CPOL(Mode)); + } + } + //---------------------------------------------------------------------------- + inline __attribute__((always_inline)) + void transferBit(uint8_t bit, uint8_t* rxData, uint8_t txData) { + if (MODE_CPHA(Mode)) { + fastDigitalWrite(SckPin, !MODE_CPOL(Mode)); + } + fastDigitalWrite(MosiPin, txData & (1 << bit)); + fastDigitalWrite(SckPin, + MODE_CPHA(Mode) ? MODE_CPOL(Mode) : !MODE_CPOL(Mode)); + if (fastDigitalRead(MisoPin)) *rxData |= 1 << bit; + if (!MODE_CPHA(Mode)) { + fastDigitalWrite(SckPin, MODE_CPOL(Mode)); + } + } + //---------------------------------------------------------------------------- +}; + + diff --git a/trunk/Arduino/Marlin_1.1.6/speed_lookuptable.h b/trunk/Arduino/Marlin_1.1.6/speed_lookuptable.h new file mode 100644 index 00000000..f29199b7 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/speed_lookuptable.h @@ -0,0 +1,174 @@ +/** + * 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 . + * + */ + +#ifndef SPEED_LOOKUPTABLE_H +#define SPEED_LOOKUPTABLE_H + +#include "Marlin.h" + +#if F_CPU == 16000000 + + const uint16_t speed_lookuptable_fast[256][2] PROGMEM = { + { 62500, 55556}, { 6944, 3268}, { 3676, 1176}, { 2500, 607}, { 1893, 369}, { 1524, 249}, { 1275, 179}, { 1096, 135}, + { 961, 105}, { 856, 85}, { 771, 69}, { 702, 58}, { 644, 49}, { 595, 42}, { 553, 37}, { 516, 32}, + { 484, 28}, { 456, 25}, { 431, 23}, { 408, 20}, { 388, 19}, { 369, 16}, { 353, 16}, { 337, 14}, + { 323, 13}, { 310, 11}, { 299, 11}, { 288, 11}, { 277, 9}, { 268, 9}, { 259, 8}, { 251, 8}, + { 243, 8}, { 235, 7}, { 228, 6}, { 222, 6}, { 216, 6}, { 210, 6}, { 204, 5}, { 199, 5}, + { 194, 5}, { 189, 4}, { 185, 4}, { 181, 4}, { 177, 4}, { 173, 4}, { 169, 4}, { 165, 3}, + { 162, 3}, { 159, 4}, { 155, 3}, { 152, 3}, { 149, 2}, { 147, 3}, { 144, 3}, { 141, 2}, + { 139, 3}, { 136, 2}, { 134, 2}, { 132, 3}, { 129, 2}, { 127, 2}, { 125, 2}, { 123, 2}, + { 121, 2}, { 119, 1}, { 118, 2}, { 116, 2}, { 114, 1}, { 113, 2}, { 111, 2}, { 109, 1}, + { 108, 2}, { 106, 1}, { 105, 2}, { 103, 1}, { 102, 1}, { 101, 1}, { 100, 2}, { 98, 1}, + { 97, 1}, { 96, 1}, { 95, 2}, { 93, 1}, { 92, 1}, { 91, 1}, { 90, 1}, { 89, 1}, + { 88, 1}, { 87, 1}, { 86, 1}, { 85, 1}, { 84, 1}, { 83, 0}, { 83, 1}, { 82, 1}, + { 81, 1}, { 80, 1}, { 79, 1}, { 78, 0}, { 78, 1}, { 77, 1}, { 76, 1}, { 75, 0}, + { 75, 1}, { 74, 1}, { 73, 1}, { 72, 0}, { 72, 1}, { 71, 1}, { 70, 0}, { 70, 1}, + { 69, 0}, { 69, 1}, { 68, 1}, { 67, 0}, { 67, 1}, { 66, 0}, { 66, 1}, { 65, 0}, + { 65, 1}, { 64, 1}, { 63, 0}, { 63, 1}, { 62, 0}, { 62, 1}, { 61, 0}, { 61, 1}, + { 60, 0}, { 60, 0}, { 60, 1}, { 59, 0}, { 59, 1}, { 58, 0}, { 58, 1}, { 57, 0}, + { 57, 1}, { 56, 0}, { 56, 0}, { 56, 1}, { 55, 0}, { 55, 1}, { 54, 0}, { 54, 0}, + { 54, 1}, { 53, 0}, { 53, 0}, { 53, 1}, { 52, 0}, { 52, 0}, { 52, 1}, { 51, 0}, + { 51, 0}, { 51, 1}, { 50, 0}, { 50, 0}, { 50, 1}, { 49, 0}, { 49, 0}, { 49, 1}, + { 48, 0}, { 48, 0}, { 48, 1}, { 47, 0}, { 47, 0}, { 47, 0}, { 47, 1}, { 46, 0}, + { 46, 0}, { 46, 1}, { 45, 0}, { 45, 0}, { 45, 0}, { 45, 1}, { 44, 0}, { 44, 0}, + { 44, 0}, { 44, 1}, { 43, 0}, { 43, 0}, { 43, 0}, { 43, 1}, { 42, 0}, { 42, 0}, + { 42, 0}, { 42, 1}, { 41, 0}, { 41, 0}, { 41, 0}, { 41, 0}, { 41, 1}, { 40, 0}, + { 40, 0}, { 40, 0}, { 40, 0}, { 40, 1}, { 39, 0}, { 39, 0}, { 39, 0}, { 39, 0}, + { 39, 1}, { 38, 0}, { 38, 0}, { 38, 0}, { 38, 0}, { 38, 1}, { 37, 0}, { 37, 0}, + { 37, 0}, { 37, 0}, { 37, 0}, { 37, 1}, { 36, 0}, { 36, 0}, { 36, 0}, { 36, 0}, + { 36, 1}, { 35, 0}, { 35, 0}, { 35, 0}, { 35, 0}, { 35, 0}, { 35, 0}, { 35, 1}, + { 34, 0}, { 34, 0}, { 34, 0}, { 34, 0}, { 34, 0}, { 34, 1}, { 33, 0}, { 33, 0}, + { 33, 0}, { 33, 0}, { 33, 0}, { 33, 0}, { 33, 1}, { 32, 0}, { 32, 0}, { 32, 0}, + { 32, 0}, { 32, 0}, { 32, 0}, { 32, 0}, { 32, 1}, { 31, 0}, { 31, 0}, { 31, 0}, + { 31, 0}, { 31, 0}, { 31, 0}, { 31, 1}, { 30, 0}, { 30, 0}, { 30, 0}, { 30, 0} + }; + + const uint16_t speed_lookuptable_slow[256][2] PROGMEM = { + { 62500, 12500}, { 50000, 8334}, { 41666, 5952}, { 35714, 4464}, { 31250, 3473}, { 27777, 2777}, { 25000, 2273}, { 22727, 1894}, + { 20833, 1603}, { 19230, 1373}, { 17857, 1191}, { 16666, 1041}, { 15625, 920}, { 14705, 817}, { 13888, 731}, { 13157, 657}, + { 12500, 596}, { 11904, 541}, { 11363, 494}, { 10869, 453}, { 10416, 416}, { 10000, 385}, { 9615, 356}, { 9259, 331}, + { 8928, 308}, { 8620, 287}, { 8333, 269}, { 8064, 252}, { 7812, 237}, { 7575, 223}, { 7352, 210}, { 7142, 198}, + { 6944, 188}, { 6756, 178}, { 6578, 168}, { 6410, 160}, { 6250, 153}, { 6097, 145}, { 5952, 139}, { 5813, 132}, + { 5681, 126}, { 5555, 121}, { 5434, 115}, { 5319, 111}, { 5208, 106}, { 5102, 102}, { 5000, 99}, { 4901, 94}, + { 4807, 91}, { 4716, 87}, { 4629, 84}, { 4545, 81}, { 4464, 79}, { 4385, 75}, { 4310, 73}, { 4237, 71}, + { 4166, 68}, { 4098, 66}, { 4032, 64}, { 3968, 62}, { 3906, 60}, { 3846, 59}, { 3787, 56}, { 3731, 55}, + { 3676, 53}, { 3623, 52}, { 3571, 50}, { 3521, 49}, { 3472, 48}, { 3424, 46}, { 3378, 45}, { 3333, 44}, + { 3289, 43}, { 3246, 41}, { 3205, 41}, { 3164, 39}, { 3125, 39}, { 3086, 38}, { 3048, 36}, { 3012, 36}, + { 2976, 35}, { 2941, 35}, { 2906, 33}, { 2873, 33}, { 2840, 32}, { 2808, 31}, { 2777, 30}, { 2747, 30}, + { 2717, 29}, { 2688, 29}, { 2659, 28}, { 2631, 27}, { 2604, 27}, { 2577, 26}, { 2551, 26}, { 2525, 25}, + { 2500, 25}, { 2475, 25}, { 2450, 23}, { 2427, 24}, { 2403, 23}, { 2380, 22}, { 2358, 22}, { 2336, 22}, + { 2314, 21}, { 2293, 21}, { 2272, 20}, { 2252, 20}, { 2232, 20}, { 2212, 20}, { 2192, 19}, { 2173, 18}, + { 2155, 19}, { 2136, 18}, { 2118, 18}, { 2100, 17}, { 2083, 17}, { 2066, 17}, { 2049, 17}, { 2032, 16}, + { 2016, 16}, { 2000, 16}, { 1984, 16}, { 1968, 15}, { 1953, 16}, { 1937, 14}, { 1923, 15}, { 1908, 15}, + { 1893, 14}, { 1879, 14}, { 1865, 14}, { 1851, 13}, { 1838, 14}, { 1824, 13}, { 1811, 13}, { 1798, 13}, + { 1785, 12}, { 1773, 13}, { 1760, 12}, { 1748, 12}, { 1736, 12}, { 1724, 12}, { 1712, 12}, { 1700, 11}, + { 1689, 12}, { 1677, 11}, { 1666, 11}, { 1655, 11}, { 1644, 11}, { 1633, 10}, { 1623, 11}, { 1612, 10}, + { 1602, 10}, { 1592, 10}, { 1582, 10}, { 1572, 10}, { 1562, 10}, { 1552, 9}, { 1543, 10}, { 1533, 9}, + { 1524, 9}, { 1515, 9}, { 1506, 9}, { 1497, 9}, { 1488, 9}, { 1479, 9}, { 1470, 9}, { 1461, 8}, + { 1453, 8}, { 1445, 9}, { 1436, 8}, { 1428, 8}, { 1420, 8}, { 1412, 8}, { 1404, 8}, { 1396, 8}, + { 1388, 7}, { 1381, 8}, { 1373, 7}, { 1366, 8}, { 1358, 7}, { 1351, 7}, { 1344, 8}, { 1336, 7}, + { 1329, 7}, { 1322, 7}, { 1315, 7}, { 1308, 6}, { 1302, 7}, { 1295, 7}, { 1288, 6}, { 1282, 7}, + { 1275, 6}, { 1269, 7}, { 1262, 6}, { 1256, 6}, { 1250, 7}, { 1243, 6}, { 1237, 6}, { 1231, 6}, + { 1225, 6}, { 1219, 6}, { 1213, 6}, { 1207, 6}, { 1201, 5}, { 1196, 6}, { 1190, 6}, { 1184, 5}, + { 1179, 6}, { 1173, 5}, { 1168, 6}, { 1162, 5}, { 1157, 5}, { 1152, 6}, { 1146, 5}, { 1141, 5}, + { 1136, 5}, { 1131, 5}, { 1126, 5}, { 1121, 5}, { 1116, 5}, { 1111, 5}, { 1106, 5}, { 1101, 5}, + { 1096, 5}, { 1091, 5}, { 1086, 4}, { 1082, 5}, { 1077, 5}, { 1072, 4}, { 1068, 5}, { 1063, 4}, + { 1059, 5}, { 1054, 4}, { 1050, 4}, { 1046, 5}, { 1041, 4}, { 1037, 4}, { 1033, 5}, { 1028, 4}, + { 1024, 4}, { 1020, 4}, { 1016, 4}, { 1012, 4}, { 1008, 4}, { 1004, 4}, { 1000, 4}, { 996, 4}, + { 992, 4}, { 988, 4}, { 984, 4}, { 980, 4}, { 976, 4}, { 972, 4}, { 968, 3}, { 965, 3} + }; + +#elif F_CPU == 20000000 + + const uint16_t speed_lookuptable_fast[256][2] PROGMEM = { + {62500, 54055}, {8445, 3917}, {4528, 1434}, {3094, 745}, {2349, 456}, {1893, 307}, {1586, 222}, {1364, 167}, + {1197, 131}, {1066, 105}, {961, 86}, {875, 72}, {803, 61}, {742, 53}, {689, 45}, {644, 40}, + {604, 35}, {569, 32}, {537, 28}, {509, 25}, {484, 23}, {461, 21}, {440, 19}, {421, 17}, + {404, 16}, {388, 15}, {373, 14}, {359, 13}, {346, 12}, {334, 11}, {323, 10}, {313, 10}, + {303, 9}, {294, 9}, {285, 8}, {277, 7}, {270, 8}, {262, 7}, {255, 6}, {249, 6}, + {243, 6}, {237, 6}, {231, 5}, {226, 5}, {221, 5}, {216, 5}, {211, 4}, {207, 5}, + {202, 4}, {198, 4}, {194, 4}, {190, 3}, {187, 4}, {183, 3}, {180, 3}, {177, 4}, + {173, 3}, {170, 3}, {167, 2}, {165, 3}, {162, 3}, {159, 2}, {157, 3}, {154, 2}, + {152, 3}, {149, 2}, {147, 2}, {145, 2}, {143, 2}, {141, 2}, {139, 2}, {137, 2}, + {135, 2}, {133, 2}, {131, 2}, {129, 1}, {128, 2}, {126, 2}, {124, 1}, {123, 2}, + {121, 1}, {120, 2}, {118, 1}, {117, 1}, {116, 2}, {114, 1}, {113, 1}, {112, 2}, + {110, 1}, {109, 1}, {108, 1}, {107, 2}, {105, 1}, {104, 1}, {103, 1}, {102, 1}, + {101, 1}, {100, 1}, {99, 1}, {98, 1}, {97, 1}, {96, 1}, {95, 1}, {94, 1}, + {93, 1}, {92, 1}, {91, 0}, {91, 1}, {90, 1}, {89, 1}, {88, 1}, {87, 0}, + {87, 1}, {86, 1}, {85, 1}, {84, 0}, {84, 1}, {83, 1}, {82, 1}, {81, 0}, + {81, 1}, {80, 1}, {79, 0}, {79, 1}, {78, 0}, {78, 1}, {77, 1}, {76, 0}, + {76, 1}, {75, 0}, {75, 1}, {74, 1}, {73, 0}, {73, 1}, {72, 0}, {72, 1}, + {71, 0}, {71, 1}, {70, 0}, {70, 1}, {69, 0}, {69, 1}, {68, 0}, {68, 1}, + {67, 0}, {67, 1}, {66, 0}, {66, 1}, {65, 0}, {65, 0}, {65, 1}, {64, 0}, + {64, 1}, {63, 0}, {63, 1}, {62, 0}, {62, 0}, {62, 1}, {61, 0}, {61, 1}, + {60, 0}, {60, 0}, {60, 1}, {59, 0}, {59, 0}, {59, 1}, {58, 0}, {58, 0}, + {58, 1}, {57, 0}, {57, 0}, {57, 1}, {56, 0}, {56, 0}, {56, 1}, {55, 0}, + {55, 0}, {55, 1}, {54, 0}, {54, 0}, {54, 1}, {53, 0}, {53, 0}, {53, 0}, + {53, 1}, {52, 0}, {52, 0}, {52, 1}, {51, 0}, {51, 0}, {51, 0}, {51, 1}, + {50, 0}, {50, 0}, {50, 0}, {50, 1}, {49, 0}, {49, 0}, {49, 0}, {49, 1}, + {48, 0}, {48, 0}, {48, 0}, {48, 1}, {47, 0}, {47, 0}, {47, 0}, {47, 1}, + {46, 0}, {46, 0}, {46, 0}, {46, 0}, {46, 1}, {45, 0}, {45, 0}, {45, 0}, + {45, 1}, {44, 0}, {44, 0}, {44, 0}, {44, 0}, {44, 1}, {43, 0}, {43, 0}, + {43, 0}, {43, 0}, {43, 1}, {42, 0}, {42, 0}, {42, 0}, {42, 0}, {42, 0}, + {42, 1}, {41, 0}, {41, 0}, {41, 0}, {41, 0}, {41, 0}, {41, 1}, {40, 0}, + {40, 0}, {40, 0}, {40, 0}, {40, 1}, {39, 0}, {39, 0}, {39, 0}, {39, 0}, + {39, 0}, {39, 0}, {39, 1}, {38, 0}, {38, 0}, {38, 0}, {38, 0}, {38, 0}, + }; + + const uint16_t speed_lookuptable_slow[256][2] PROGMEM = { + {62500, 10417}, {52083, 7441}, {44642, 5580}, {39062, 4340}, {34722, 3472}, {31250, 2841}, {28409, 2368}, {26041, 2003}, + {24038, 1717}, {22321, 1488}, {20833, 1302}, {19531, 1149}, {18382, 1021}, {17361, 914}, {16447, 822}, {15625, 745}, + {14880, 676}, {14204, 618}, {13586, 566}, {13020, 520}, {12500, 481}, {12019, 445}, {11574, 414}, {11160, 385}, + {10775, 359}, {10416, 336}, {10080, 315}, {9765, 296}, {9469, 278}, {9191, 263}, {8928, 248}, {8680, 235}, + {8445, 222}, {8223, 211}, {8012, 200}, {7812, 191}, {7621, 181}, {7440, 173}, {7267, 165}, {7102, 158}, + {6944, 151}, {6793, 145}, {6648, 138}, {6510, 133}, {6377, 127}, {6250, 123}, {6127, 118}, {6009, 113}, + {5896, 109}, {5787, 106}, {5681, 101}, {5580, 98}, {5482, 95}, {5387, 91}, {5296, 88}, {5208, 86}, + {5122, 82}, {5040, 80}, {4960, 78}, {4882, 75}, {4807, 73}, {4734, 70}, {4664, 69}, {4595, 67}, + {4528, 64}, {4464, 63}, {4401, 61}, {4340, 60}, {4280, 58}, {4222, 56}, {4166, 55}, {4111, 53}, + {4058, 52}, {4006, 51}, {3955, 49}, {3906, 48}, {3858, 48}, {3810, 45}, {3765, 45}, {3720, 44}, + {3676, 43}, {3633, 42}, {3591, 40}, {3551, 40}, {3511, 39}, {3472, 38}, {3434, 38}, {3396, 36}, + {3360, 36}, {3324, 35}, {3289, 34}, {3255, 34}, {3221, 33}, {3188, 32}, {3156, 31}, {3125, 31}, + {3094, 31}, {3063, 30}, {3033, 29}, {3004, 28}, {2976, 28}, {2948, 28}, {2920, 27}, {2893, 27}, + {2866, 26}, {2840, 25}, {2815, 25}, {2790, 25}, {2765, 24}, {2741, 24}, {2717, 24}, {2693, 23}, + {2670, 22}, {2648, 22}, {2626, 22}, {2604, 22}, {2582, 21}, {2561, 21}, {2540, 20}, {2520, 20}, + {2500, 20}, {2480, 20}, {2460, 19}, {2441, 19}, {2422, 19}, {2403, 18}, {2385, 18}, {2367, 18}, + {2349, 17}, {2332, 18}, {2314, 17}, {2297, 16}, {2281, 17}, {2264, 16}, {2248, 16}, {2232, 16}, + {2216, 16}, {2200, 15}, {2185, 15}, {2170, 15}, {2155, 15}, {2140, 15}, {2125, 14}, {2111, 14}, + {2097, 14}, {2083, 14}, {2069, 14}, {2055, 13}, {2042, 13}, {2029, 13}, {2016, 13}, {2003, 13}, + {1990, 13}, {1977, 12}, {1965, 12}, {1953, 13}, {1940, 11}, {1929, 12}, {1917, 12}, {1905, 12}, + {1893, 11}, {1882, 11}, {1871, 11}, {1860, 11}, {1849, 11}, {1838, 11}, {1827, 11}, {1816, 10}, + {1806, 11}, {1795, 10}, {1785, 10}, {1775, 10}, {1765, 10}, {1755, 10}, {1745, 9}, {1736, 10}, + {1726, 9}, {1717, 10}, {1707, 9}, {1698, 9}, {1689, 9}, {1680, 9}, {1671, 9}, {1662, 9}, + {1653, 9}, {1644, 8}, {1636, 9}, {1627, 8}, {1619, 9}, {1610, 8}, {1602, 8}, {1594, 8}, + {1586, 8}, {1578, 8}, {1570, 8}, {1562, 8}, {1554, 7}, {1547, 8}, {1539, 8}, {1531, 7}, + {1524, 8}, {1516, 7}, {1509, 7}, {1502, 7}, {1495, 7}, {1488, 7}, {1481, 7}, {1474, 7}, + {1467, 7}, {1460, 7}, {1453, 7}, {1446, 6}, {1440, 7}, {1433, 7}, {1426, 6}, {1420, 6}, + {1414, 7}, {1407, 6}, {1401, 6}, {1395, 7}, {1388, 6}, {1382, 6}, {1376, 6}, {1370, 6}, + {1364, 6}, {1358, 6}, {1352, 6}, {1346, 5}, {1341, 6}, {1335, 6}, {1329, 5}, {1324, 6}, + {1318, 5}, {1313, 6}, {1307, 5}, {1302, 6}, {1296, 5}, {1291, 5}, {1286, 6}, {1280, 5}, + {1275, 5}, {1270, 5}, {1265, 5}, {1260, 5}, {1255, 5}, {1250, 5}, {1245, 5}, {1240, 5}, + {1235, 5}, {1230, 5}, {1225, 5}, {1220, 5}, {1215, 4}, {1211, 5}, {1206, 5}, {1201, 5}, + }; + +#endif + +#endif // SPEED_LOOKUPTABLE_H diff --git a/trunk/Arduino/Marlin_1.1.6/spi.h b/trunk/Arduino/Marlin_1.1.6/spi.h new file mode 100644 index 00000000..c4b86005 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/spi.h @@ -0,0 +1,57 @@ +/** + * 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 . + * + */ + +#ifndef __SPI_H__ +#define __SPI_H__ + +#include +#include "softspi.h" + +template +class SPI { + static SoftSPI softSPI; + public: + FORCE_INLINE static void init() { softSPI.begin(); } + FORCE_INLINE static void send(uint8_t data) { softSPI.send(data); } + FORCE_INLINE static uint8_t receive() { return softSPI.receive(); } +}; + + +// Hardware SPI +template<> +class SPI { + public: + FORCE_INLINE static void init() { + OUT_WRITE(SCK_PIN, LOW); + OUT_WRITE(MOSI_PIN, HIGH); + SET_INPUT(MISO_PIN); + WRITE(MISO_PIN, HIGH); + } + FORCE_INLINE static uint8_t receive() { + SPDR = 0; + for (;!TEST(SPSR, SPIF);); + return SPDR; + } + +}; + +#endif // __SPI_H__ diff --git a/trunk/Arduino/Marlin_1.1.6/stepper.cpp b/trunk/Arduino/Marlin_1.1.6/stepper.cpp new file mode 100644 index 00000000..2b86c428 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/stepper.cpp @@ -0,0 +1,1626 @@ +/** + * 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 . + * + */ + +/** + * stepper.cpp - A singleton object to execute motion plans using stepper motors + * Marlin Firmware + * + * Derived from Grbl + * Copyright (c) 2009-2011 Simen Svale Skogsrud + * + * Grbl is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Grbl is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * 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 . + */ + +/* The timer calculations of this module informed by the 'RepRap cartesian firmware' by Zack Smith + and Philipp Tiefenbacher. */ + +#include "Marlin.h" +#include "stepper.h" +#include "endstops.h" +#include "planner.h" +#include "temperature.h" +#include "ultralcd.h" +#include "language.h" +#include "cardreader.h" +#include "speed_lookuptable.h" + +#if HAS_DIGIPOTSS + #include +#endif + +Stepper stepper; // Singleton + +// public: + +#if ENABLED(AUTO_BED_LEVELING_UBL) && ENABLED(ULTIPANEL) + extern bool ubl_lcd_map_control; +#endif + +block_t* Stepper::current_block = NULL; // A pointer to the block currently being traced + +#if ENABLED(ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED) + bool Stepper::abort_on_endstop_hit = false; +#endif + +#if ENABLED(Z_DUAL_ENDSTOPS) + bool Stepper::performing_homing = false; +#endif + +#if HAS_MOTOR_CURRENT_PWM + uint32_t Stepper::motor_current_setting[3]; // Initialized by settings.load() +#endif + +// private: + +uint8_t Stepper::last_direction_bits = 0; // The next stepping-bits to be output +uint16_t Stepper::cleaning_buffer_counter = 0; + +#if ENABLED(Z_DUAL_ENDSTOPS) + bool Stepper::locked_z_motor = false; + bool Stepper::locked_z2_motor = false; +#endif + +long Stepper::counter_X = 0, + Stepper::counter_Y = 0, + Stepper::counter_Z = 0, + Stepper::counter_E = 0; + +volatile uint32_t Stepper::step_events_completed = 0; // The number of step events executed in the current block + +#if ENABLED(LIN_ADVANCE) + + constexpr uint16_t ADV_NEVER = 65535; + + uint16_t Stepper::nextMainISR = 0, + Stepper::nextAdvanceISR = ADV_NEVER, + Stepper::eISR_Rate = ADV_NEVER; + + volatile int Stepper::e_steps[E_STEPPERS]; + int Stepper::final_estep_rate, + Stepper::current_estep_rate[E_STEPPERS], + Stepper::current_adv_steps[E_STEPPERS]; + + /** + * See https://github.com/MarlinFirmware/Marlin/issues/5699#issuecomment-309264382 + * + * This fix isn't perfect and may lose steps - but better than locking up completely + * in future the planner should slow down if advance stepping rate would be too high + */ + FORCE_INLINE uint16_t adv_rate(const int steps, const uint16_t timer, const uint8_t loops) { + if (steps) { + const uint16_t rate = (timer * loops) / abs(steps); + //return constrain(rate, 1, ADV_NEVER - 1) + return rate ? rate : 1; + } + return ADV_NEVER; + } + +#endif // LIN_ADVANCE + +long Stepper::acceleration_time, Stepper::deceleration_time; + +volatile long Stepper::count_position[NUM_AXIS] = { 0 }; +volatile signed char Stepper::count_direction[NUM_AXIS] = { 1, 1, 1, 1 }; + +#if ENABLED(MIXING_EXTRUDER) + long Stepper::counter_m[MIXING_STEPPERS]; +#endif + +unsigned short Stepper::acc_step_rate; // needed for deceleration start point +uint8_t Stepper::step_loops, Stepper::step_loops_nominal; +unsigned short Stepper::OCR1A_nominal; + +volatile long Stepper::endstops_trigsteps[XYZ]; + +#if ENABLED(X_DUAL_STEPPER_DRIVERS) + #define X_APPLY_DIR(v,Q) do{ X_DIR_WRITE(v); X2_DIR_WRITE((v) != INVERT_X2_VS_X_DIR); }while(0) + #define X_APPLY_STEP(v,Q) do{ X_STEP_WRITE(v); X2_STEP_WRITE(v); }while(0) +#elif ENABLED(DUAL_X_CARRIAGE) + #define X_APPLY_DIR(v,ALWAYS) \ + if (extruder_duplication_enabled || ALWAYS) { \ + X_DIR_WRITE(v); \ + X2_DIR_WRITE(v); \ + } \ + else { \ + if (current_block->active_extruder) X2_DIR_WRITE(v); else X_DIR_WRITE(v); \ + } + #define X_APPLY_STEP(v,ALWAYS) \ + if (extruder_duplication_enabled || ALWAYS) { \ + X_STEP_WRITE(v); \ + X2_STEP_WRITE(v); \ + } \ + else { \ + if (current_block->active_extruder) X2_STEP_WRITE(v); else X_STEP_WRITE(v); \ + } +#else + #define X_APPLY_DIR(v,Q) X_DIR_WRITE(v) + #define X_APPLY_STEP(v,Q) X_STEP_WRITE(v) +#endif + +#if ENABLED(Y_DUAL_STEPPER_DRIVERS) + #define Y_APPLY_DIR(v,Q) do{ Y_DIR_WRITE(v); Y2_DIR_WRITE((v) != INVERT_Y2_VS_Y_DIR); }while(0) + #define Y_APPLY_STEP(v,Q) do{ Y_STEP_WRITE(v); Y2_STEP_WRITE(v); }while(0) +#else + #define Y_APPLY_DIR(v,Q) Y_DIR_WRITE(v) + #define Y_APPLY_STEP(v,Q) Y_STEP_WRITE(v) +#endif + +#if ENABLED(Z_DUAL_STEPPER_DRIVERS) + #define Z_APPLY_DIR(v,Q) do{ Z_DIR_WRITE(v); Z2_DIR_WRITE(v); }while(0) + #if ENABLED(Z_DUAL_ENDSTOPS) + #define Z_APPLY_STEP(v,Q) \ + if (performing_homing) { \ + if (Z_HOME_DIR < 0) { \ + if (!(TEST(endstops.old_endstop_bits, Z_MIN) && (count_direction[Z_AXIS] < 0)) && !locked_z_motor) Z_STEP_WRITE(v); \ + if (!(TEST(endstops.old_endstop_bits, Z2_MIN) && (count_direction[Z_AXIS] < 0)) && !locked_z2_motor) Z2_STEP_WRITE(v); \ + } \ + else { \ + if (!(TEST(endstops.old_endstop_bits, Z_MAX) && (count_direction[Z_AXIS] > 0)) && !locked_z_motor) Z_STEP_WRITE(v); \ + if (!(TEST(endstops.old_endstop_bits, Z2_MAX) && (count_direction[Z_AXIS] > 0)) && !locked_z2_motor) Z2_STEP_WRITE(v); \ + } \ + } \ + else { \ + Z_STEP_WRITE(v); \ + Z2_STEP_WRITE(v); \ + } + #else + #define Z_APPLY_STEP(v,Q) do{ Z_STEP_WRITE(v); Z2_STEP_WRITE(v); }while(0) + #endif +#else + #define Z_APPLY_DIR(v,Q) Z_DIR_WRITE(v) + #define Z_APPLY_STEP(v,Q) Z_STEP_WRITE(v) +#endif + +#if DISABLED(MIXING_EXTRUDER) + #define E_APPLY_STEP(v,Q) E_STEP_WRITE(v) +#endif + +// intRes = longIn1 * longIn2 >> 24 +// uses: +// r26 to store 0 +// r27 to store bits 16-23 of the 48bit result. The top bit is used to round the two byte result. +// note that the lower two bytes and the upper byte of the 48bit result are not calculated. +// this can cause the result to be out by one as the lower bytes may cause carries into the upper ones. +// B0 A0 are bits 24-39 and are the returned value +// C1 B1 A1 is longIn1 +// D2 C2 B2 A2 is longIn2 +// +#define MultiU24X32toH16(intRes, longIn1, longIn2) \ + asm volatile ( \ + "clr r26 \n\t" \ + "mul %A1, %B2 \n\t" \ + "mov r27, r1 \n\t" \ + "mul %B1, %C2 \n\t" \ + "movw %A0, r0 \n\t" \ + "mul %C1, %C2 \n\t" \ + "add %B0, r0 \n\t" \ + "mul %C1, %B2 \n\t" \ + "add %A0, r0 \n\t" \ + "adc %B0, r1 \n\t" \ + "mul %A1, %C2 \n\t" \ + "add r27, r0 \n\t" \ + "adc %A0, r1 \n\t" \ + "adc %B0, r26 \n\t" \ + "mul %B1, %B2 \n\t" \ + "add r27, r0 \n\t" \ + "adc %A0, r1 \n\t" \ + "adc %B0, r26 \n\t" \ + "mul %C1, %A2 \n\t" \ + "add r27, r0 \n\t" \ + "adc %A0, r1 \n\t" \ + "adc %B0, r26 \n\t" \ + "mul %B1, %A2 \n\t" \ + "add r27, r1 \n\t" \ + "adc %A0, r26 \n\t" \ + "adc %B0, r26 \n\t" \ + "lsr r27 \n\t" \ + "adc %A0, r26 \n\t" \ + "adc %B0, r26 \n\t" \ + "mul %D2, %A1 \n\t" \ + "add %A0, r0 \n\t" \ + "adc %B0, r1 \n\t" \ + "mul %D2, %B1 \n\t" \ + "add %B0, r0 \n\t" \ + "clr r1 \n\t" \ + : \ + "=&r" (intRes) \ + : \ + "d" (longIn1), \ + "d" (longIn2) \ + : \ + "r26" , "r27" \ + ) + +// Some useful constants + +#define ENABLE_STEPPER_DRIVER_INTERRUPT() SBI(TIMSK1, OCIE1A) +#define DISABLE_STEPPER_DRIVER_INTERRUPT() CBI(TIMSK1, OCIE1A) + +/** + * __________________________ + * /| |\ _________________ ^ + * / | | \ /| |\ | + * / | | \ / | | \ s + * / | | | | | \ p + * / | | | | | \ e + * +-----+------------------------+---+--+---------------+----+ e + * | BLOCK 1 | BLOCK 2 | d + * + * time -----> + * + * The trapezoid is the shape the speed curve over time. It starts at block->initial_rate, accelerates + * first block->accelerate_until step_events_completed, then keeps going at constant speed until + * step_events_completed reaches block->decelerate_after after which it decelerates until the trapezoid generator is reset. + * The slope of acceleration is calculated using v = u + at where t is the accumulated timer values of the steps so far. + */ +void Stepper::wake_up() { + // TCNT1 = 0; + ENABLE_STEPPER_DRIVER_INTERRUPT(); +} + +/** + * Set the stepper direction of each axis + * + * COREXY: X_AXIS=A_AXIS and Y_AXIS=B_AXIS + * COREXZ: X_AXIS=A_AXIS and Z_AXIS=C_AXIS + * COREYZ: Y_AXIS=B_AXIS and Z_AXIS=C_AXIS + */ +void Stepper::set_directions() { + + #define SET_STEP_DIR(AXIS) \ + if (motor_direction(AXIS ##_AXIS)) { \ + AXIS ##_APPLY_DIR(INVERT_## AXIS ##_DIR, false); \ + count_direction[AXIS ##_AXIS] = -1; \ + } \ + else { \ + AXIS ##_APPLY_DIR(!INVERT_## AXIS ##_DIR, false); \ + count_direction[AXIS ##_AXIS] = 1; \ + } + + #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 + + #if DISABLED(LIN_ADVANCE) + if (motor_direction(E_AXIS)) { + REV_E_DIR(); + count_direction[E_AXIS] = -1; + } + else { + NORM_E_DIR(); + count_direction[E_AXIS] = 1; + } + #endif // !LIN_ADVANCE +} + +#if ENABLED(ENDSTOP_INTERRUPTS_FEATURE) + extern volatile uint8_t e_hit; +#endif + +/** + * Stepper Driver Interrupt + * + * Directly pulses the stepper motors at high frequency. + * Timer 1 runs at a base frequency of 2MHz, with this ISR using OCR1A compare mode. + * + * OCR1A Frequency + * 1 2 MHz + * 50 40 KHz + * 100 20 KHz - capped max rate + * 200 10 KHz - nominal max rate + * 2000 1 KHz - sleep rate + * 4000 500 Hz - init rate + */ +ISR(TIMER1_COMPA_vect) { + #if ENABLED(LIN_ADVANCE) + Stepper::advance_isr_scheduler(); + #else + Stepper::isr(); + #endif +} + +#define _ENABLE_ISRs() do { cli(); if (thermalManager.in_temp_isr) CBI(TIMSK0, OCIE0B); else SBI(TIMSK0, OCIE0B); ENABLE_STEPPER_DRIVER_INTERRUPT(); } while(0) + +void Stepper::isr() { + + uint16_t ocr_val; + + #define ENDSTOP_NOMINAL_OCR_VAL 3000 // check endstops every 1.5ms to guarantee two stepper ISRs within 5ms for BLTouch + #define OCR_VAL_TOLERANCE 1000 // First max delay is 2.0ms, last min delay is 0.5ms, all others 1.5ms + + #if DISABLED(LIN_ADVANCE) + // Disable Timer0 ISRs and enable global ISR again to capture UART events (incoming chars) + CBI(TIMSK0, OCIE0B); // Temperature ISR + DISABLE_STEPPER_DRIVER_INTERRUPT(); + sei(); + #endif + + #define _SPLIT(L) (ocr_val = (uint16_t)L) + #if ENABLED(ENDSTOP_INTERRUPTS_FEATURE) + #define SPLIT(L) _SPLIT(L) + #else // sample endstops in between step pulses + static uint32_t step_remaining = 0; + #define SPLIT(L) do { \ + _SPLIT(L); \ + if (ENDSTOPS_ENABLED && L > ENDSTOP_NOMINAL_OCR_VAL) { \ + const uint16_t remainder = (uint16_t)L % (ENDSTOP_NOMINAL_OCR_VAL); \ + ocr_val = (remainder < OCR_VAL_TOLERANCE) ? ENDSTOP_NOMINAL_OCR_VAL + remainder : ENDSTOP_NOMINAL_OCR_VAL; \ + step_remaining = (uint16_t)L - ocr_val; \ + } \ + }while(0) + + if (step_remaining && ENDSTOPS_ENABLED) { // Just check endstops - not yet time for a step + endstops.update(); + if (step_remaining > ENDSTOP_NOMINAL_OCR_VAL) { + step_remaining -= ENDSTOP_NOMINAL_OCR_VAL; + ocr_val = ENDSTOP_NOMINAL_OCR_VAL; + } + else { + ocr_val = step_remaining; + step_remaining = 0; // last one before the ISR that does the step + } + + _NEXT_ISR(ocr_val); + + NOLESS(OCR1A, TCNT1 + 16); + + _ENABLE_ISRs(); // re-enable ISRs + return; + } + #endif + + if (cleaning_buffer_counter) { + --cleaning_buffer_counter; + current_block = NULL; + planner.discard_current_block(); + #ifdef SD_FINISHED_RELEASECOMMAND + if (!cleaning_buffer_counter && (SD_FINISHED_STEPPERRELEASE)) enqueue_and_echo_commands_P(PSTR(SD_FINISHED_RELEASECOMMAND)); + #endif + _NEXT_ISR(200); // Run at max speed - 10 KHz + _ENABLE_ISRs(); // re-enable ISRs + return; + } + + // If there is no current block, attempt to pop one from the buffer + if (!current_block) { + // Anything in the buffer? + current_block = planner.get_current_block(); + if (current_block) { + trapezoid_generator_reset(); + + // Initialize Bresenham counters to 1/2 the ceiling + counter_X = counter_Y = counter_Z = counter_E = -(current_block->step_event_count >> 1); + + #if ENABLED(MIXING_EXTRUDER) + MIXING_STEPPERS_LOOP(i) + counter_m[i] = -(current_block->mix_event_count[i] >> 1); + #endif + + step_events_completed = 0; + + #if ENABLED(ENDSTOP_INTERRUPTS_FEATURE) + e_hit = 2; // Needed for the case an endstop is already triggered before the new move begins. + // No 'change' can be detected. + #endif + + #if ENABLED(Z_LATE_ENABLE) + if (current_block->steps[Z_AXIS] > 0) { + enable_Z(); + _NEXT_ISR(2000); // Run at slow speed - 1 KHz + _ENABLE_ISRs(); // re-enable ISRs + return; + } + #endif + } + else { + _NEXT_ISR(2000); // Run at slow speed - 1 KHz + _ENABLE_ISRs(); // re-enable ISRs + return; + } + } + + // Update endstops state, if enabled + #if ENABLED(ENDSTOP_INTERRUPTS_FEATURE) + if (e_hit && ENDSTOPS_ENABLED) { + endstops.update(); + e_hit--; + } + #else + if (ENDSTOPS_ENABLED) endstops.update(); + #endif + + // Take multiple steps per interrupt (For high speed moves) + bool all_steps_done = false; + for (uint8_t i = step_loops; i--;) { + #if ENABLED(LIN_ADVANCE) + + counter_E += current_block->steps[E_AXIS]; + if (counter_E > 0) { + counter_E -= current_block->step_event_count; + #if DISABLED(MIXING_EXTRUDER) + // Don't step E here for mixing extruder + count_position[E_AXIS] += count_direction[E_AXIS]; + motor_direction(E_AXIS) ? --e_steps[TOOL_E_INDEX] : ++e_steps[TOOL_E_INDEX]; + #endif + } + + #if ENABLED(MIXING_EXTRUDER) + // Step mixing steppers proportionally + const bool dir = motor_direction(E_AXIS); + MIXING_STEPPERS_LOOP(j) { + counter_m[j] += current_block->steps[E_AXIS]; + if (counter_m[j] > 0) { + counter_m[j] -= current_block->mix_event_count[j]; + dir ? --e_steps[j] : ++e_steps[j]; + } + } + #endif + + #endif // LIN_ADVANCE + + #define _COUNTER(AXIS) counter_## AXIS + #define _APPLY_STEP(AXIS) AXIS ##_APPLY_STEP + #define _INVERT_STEP_PIN(AXIS) INVERT_## AXIS ##_STEP_PIN + + // Advance the Bresenham counter; start a pulse if the axis needs a step + #define PULSE_START(AXIS) \ + _COUNTER(AXIS) += current_block->steps[_AXIS(AXIS)]; \ + if (_COUNTER(AXIS) > 0) { _APPLY_STEP(AXIS)(!_INVERT_STEP_PIN(AXIS),0); } + + // Stop an active pulse, reset the Bresenham counter, update the position + #define PULSE_STOP(AXIS) \ + if (_COUNTER(AXIS) > 0) { \ + _COUNTER(AXIS) -= current_block->step_event_count; \ + count_position[_AXIS(AXIS)] += count_direction[_AXIS(AXIS)]; \ + _APPLY_STEP(AXIS)(_INVERT_STEP_PIN(AXIS),0); \ + } + + /** + * Estimate the number of cycles that the stepper logic already takes + * up between the start and stop of the X stepper pulse. + * + * Currently this uses very modest estimates of around 5 cycles. + * True values may be derived by careful testing. + * + * Once any delay is added, the cost of the delay code itself + * may be subtracted from this value to get a more accurate delay. + * Delays under 20 cycles (1.25µs) will be very accurate, using NOPs. + * Longer delays use a loop. The resolution is 8 cycles. + */ + #if HAS_X_STEP + #define _CYCLE_APPROX_1 5 + #else + #define _CYCLE_APPROX_1 0 + #endif + #if ENABLED(X_DUAL_STEPPER_DRIVERS) + #define _CYCLE_APPROX_2 _CYCLE_APPROX_1 + 4 + #else + #define _CYCLE_APPROX_2 _CYCLE_APPROX_1 + #endif + #if HAS_Y_STEP + #define _CYCLE_APPROX_3 _CYCLE_APPROX_2 + 5 + #else + #define _CYCLE_APPROX_3 _CYCLE_APPROX_2 + #endif + #if ENABLED(Y_DUAL_STEPPER_DRIVERS) + #define _CYCLE_APPROX_4 _CYCLE_APPROX_3 + 4 + #else + #define _CYCLE_APPROX_4 _CYCLE_APPROX_3 + #endif + #if HAS_Z_STEP + #define _CYCLE_APPROX_5 _CYCLE_APPROX_4 + 5 + #else + #define _CYCLE_APPROX_5 _CYCLE_APPROX_4 + #endif + #if ENABLED(Z_DUAL_STEPPER_DRIVERS) + #define _CYCLE_APPROX_6 _CYCLE_APPROX_5 + 4 + #else + #define _CYCLE_APPROX_6 _CYCLE_APPROX_5 + #endif + #if DISABLED(LIN_ADVANCE) + #if ENABLED(MIXING_EXTRUDER) + #define _CYCLE_APPROX_7 _CYCLE_APPROX_6 + (MIXING_STEPPERS) * 6 + #else + #define _CYCLE_APPROX_7 _CYCLE_APPROX_6 + 5 + #endif + #else + #define _CYCLE_APPROX_7 _CYCLE_APPROX_6 + #endif + + #define CYCLES_EATEN_XYZE _CYCLE_APPROX_7 + #define EXTRA_CYCLES_XYZE (STEP_PULSE_CYCLES - (CYCLES_EATEN_XYZE)) + + /** + * If a minimum pulse time was specified get the timer 0 value. + * + * TCNT0 has an 8x prescaler, so it increments every 8 cycles. + * That's every 0.5µs on 16MHz and every 0.4µs on 20MHz. + * 20 counts of TCNT0 -by itself- is a good pulse delay. + * 10µs = 160 or 200 cycles. + */ + #if EXTRA_CYCLES_XYZE > 20 + uint32_t pulse_start = TCNT0; + #endif + + #if HAS_X_STEP + PULSE_START(X); + #endif + #if HAS_Y_STEP + PULSE_START(Y); + #endif + #if HAS_Z_STEP + PULSE_START(Z); + #endif + + // For non-advance use linear interpolation for E also + #if DISABLED(LIN_ADVANCE) + #if ENABLED(MIXING_EXTRUDER) + // Keep updating the single E axis + counter_E += current_block->steps[E_AXIS]; + // Tick the counters used for this mix + MIXING_STEPPERS_LOOP(j) { + // Step mixing steppers (proportionally) + counter_m[j] += current_block->steps[E_AXIS]; + // Step when the counter goes over zero + if (counter_m[j] > 0) En_STEP_WRITE(j, !INVERT_E_STEP_PIN); + } + #else // !MIXING_EXTRUDER + PULSE_START(E); + #endif + #endif // !LIN_ADVANCE + + // For minimum pulse time wait before stopping pulses + #if EXTRA_CYCLES_XYZE > 20 + while (EXTRA_CYCLES_XYZE > (uint32_t)(TCNT0 - pulse_start) * (INT0_PRESCALER)) { /* nada */ } + pulse_start = TCNT0; + #elif EXTRA_CYCLES_XYZE > 0 + DELAY_NOPS(EXTRA_CYCLES_XYZE); + #endif + + #if HAS_X_STEP + PULSE_STOP(X); + #endif + #if HAS_Y_STEP + PULSE_STOP(Y); + #endif + #if HAS_Z_STEP + PULSE_STOP(Z); + #endif + + #if DISABLED(LIN_ADVANCE) + #if ENABLED(MIXING_EXTRUDER) + // Always step the single E axis + if (counter_E > 0) { + counter_E -= current_block->step_event_count; + count_position[E_AXIS] += count_direction[E_AXIS]; + } + MIXING_STEPPERS_LOOP(j) { + if (counter_m[j] > 0) { + counter_m[j] -= current_block->mix_event_count[j]; + En_STEP_WRITE(j, INVERT_E_STEP_PIN); + } + } + #else // !MIXING_EXTRUDER + PULSE_STOP(E); + #endif + #endif // !LIN_ADVANCE + + if (++step_events_completed >= current_block->step_event_count) { + all_steps_done = true; + break; + } + + // For minimum pulse time wait after stopping pulses also + #if EXTRA_CYCLES_XYZE > 20 + if (i) while (EXTRA_CYCLES_XYZE > (uint32_t)(TCNT0 - pulse_start) * (INT0_PRESCALER)) { /* nada */ } + #elif EXTRA_CYCLES_XYZE > 0 + if (i) DELAY_NOPS(EXTRA_CYCLES_XYZE); + #endif + + } // steps_loop + + #if ENABLED(LIN_ADVANCE) + + if (current_block->use_advance_lead) { + const int delta_adv_steps = current_estep_rate[TOOL_E_INDEX] - current_adv_steps[TOOL_E_INDEX]; + current_adv_steps[TOOL_E_INDEX] += delta_adv_steps; + #if ENABLED(MIXING_EXTRUDER) + // Mixing extruders apply advance lead proportionally + MIXING_STEPPERS_LOOP(j) + e_steps[j] += delta_adv_steps * current_block->step_event_count / current_block->mix_event_count[j]; + #else + // For most extruders, advance the single E stepper + e_steps[TOOL_E_INDEX] += delta_adv_steps; + #endif + } + // If we have esteps to execute, fire the next advance_isr "now" + if (e_steps[TOOL_E_INDEX]) nextAdvanceISR = 0; + + #endif // LIN_ADVANCE + + // Calculate new timer value + if (step_events_completed <= (uint32_t)current_block->accelerate_until) { + + MultiU24X32toH16(acc_step_rate, acceleration_time, current_block->acceleration_rate); + acc_step_rate += current_block->initial_rate; + + // upper limit + NOMORE(acc_step_rate, current_block->nominal_rate); + + // step_rate to timer interval + const uint16_t timer = calc_timer(acc_step_rate); + + SPLIT(timer); // split step into multiple ISRs if larger than ENDSTOP_NOMINAL_OCR_VAL + _NEXT_ISR(ocr_val); + + acceleration_time += timer; + + #if ENABLED(LIN_ADVANCE) + + if (current_block->use_advance_lead) { + #if ENABLED(MIXING_EXTRUDER) + MIXING_STEPPERS_LOOP(j) + current_estep_rate[j] = ((uint32_t)acc_step_rate * current_block->abs_adv_steps_multiplier8 * current_block->step_event_count / current_block->mix_event_count[j]) >> 17; + #else + current_estep_rate[TOOL_E_INDEX] = ((uint32_t)acc_step_rate * current_block->abs_adv_steps_multiplier8) >> 17; + #endif + } + eISR_Rate = adv_rate(e_steps[TOOL_E_INDEX], timer, step_loops); + + #endif // LIN_ADVANCE + } + else if (step_events_completed > (uint32_t)current_block->decelerate_after) { + uint16_t step_rate; + MultiU24X32toH16(step_rate, deceleration_time, current_block->acceleration_rate); + + if (step_rate < acc_step_rate) { // Still decelerating? + step_rate = acc_step_rate - step_rate; + NOLESS(step_rate, current_block->final_rate); + } + else + step_rate = current_block->final_rate; + + // step_rate to timer interval + const uint16_t timer = calc_timer(step_rate); + + SPLIT(timer); // split step into multiple ISRs if larger than ENDSTOP_NOMINAL_OCR_VAL + _NEXT_ISR(ocr_val); + + deceleration_time += timer; + + #if ENABLED(LIN_ADVANCE) + + if (current_block->use_advance_lead) { + #if ENABLED(MIXING_EXTRUDER) + MIXING_STEPPERS_LOOP(j) + current_estep_rate[j] = ((uint32_t)step_rate * current_block->abs_adv_steps_multiplier8 * current_block->step_event_count / current_block->mix_event_count[j]) >> 17; + #else + current_estep_rate[TOOL_E_INDEX] = ((uint32_t)step_rate * current_block->abs_adv_steps_multiplier8) >> 17; + #endif + } + eISR_Rate = adv_rate(e_steps[TOOL_E_INDEX], timer, step_loops); + + #endif // LIN_ADVANCE + } + else { + + #if ENABLED(LIN_ADVANCE) + + if (current_block->use_advance_lead) + current_estep_rate[TOOL_E_INDEX] = final_estep_rate; + + eISR_Rate = adv_rate(e_steps[TOOL_E_INDEX], OCR1A_nominal, step_loops_nominal); + + #endif + + SPLIT(OCR1A_nominal); // split step into multiple ISRs if larger than ENDSTOP_NOMINAL_OCR_VAL + _NEXT_ISR(ocr_val); + + // ensure we're running at the correct step rate, even if we just came off an acceleration + step_loops = step_loops_nominal; + } + + #if DISABLED(LIN_ADVANCE) + NOLESS(OCR1A, TCNT1 + 16); + #endif + + // If current block is finished, reset pointer + if (all_steps_done) { + current_block = NULL; + planner.discard_current_block(); + } + #if DISABLED(LIN_ADVANCE) + _ENABLE_ISRs(); // re-enable ISRs + #endif +} + +#if ENABLED(LIN_ADVANCE) + + #define CYCLES_EATEN_E (E_STEPPERS * 5) + #define EXTRA_CYCLES_E (STEP_PULSE_CYCLES - (CYCLES_EATEN_E)) + + // Timer interrupt for E. e_steps is set in the main routine; + + void Stepper::advance_isr() { + + nextAdvanceISR = eISR_Rate; + + #if ENABLED(MK2_MULTIPLEXER) + // Even-numbered steppers are reversed + #define SET_E_STEP_DIR(INDEX) \ + if (e_steps[INDEX]) E## INDEX ##_DIR_WRITE(e_steps[INDEX] < 0 ? !INVERT_E## INDEX ##_DIR ^ TEST(INDEX, 0) : INVERT_E## INDEX ##_DIR ^ TEST(INDEX, 0)) + #else + #define SET_E_STEP_DIR(INDEX) \ + if (e_steps[INDEX]) E## INDEX ##_DIR_WRITE(e_steps[INDEX] < 0 ? INVERT_E## INDEX ##_DIR : !INVERT_E## INDEX ##_DIR) + #endif + + #define START_E_PULSE(INDEX) \ + if (e_steps[INDEX]) E## INDEX ##_STEP_WRITE(!INVERT_E_STEP_PIN) + + #define STOP_E_PULSE(INDEX) \ + if (e_steps[INDEX]) { \ + e_steps[INDEX] < 0 ? ++e_steps[INDEX] : --e_steps[INDEX]; \ + E## INDEX ##_STEP_WRITE(INVERT_E_STEP_PIN); \ + } + + SET_E_STEP_DIR(0); + #if E_STEPPERS > 1 + SET_E_STEP_DIR(1); + #if E_STEPPERS > 2 + SET_E_STEP_DIR(2); + #if E_STEPPERS > 3 + SET_E_STEP_DIR(3); + #if E_STEPPERS > 4 + SET_E_STEP_DIR(4); + #endif + #endif + #endif + #endif + + // Step all E steppers that have steps + for (uint8_t i = step_loops; i--;) { + + #if EXTRA_CYCLES_E > 20 + uint32_t pulse_start = TCNT0; + #endif + + START_E_PULSE(0); + #if E_STEPPERS > 1 + START_E_PULSE(1); + #if E_STEPPERS > 2 + START_E_PULSE(2); + #if E_STEPPERS > 3 + START_E_PULSE(3); + #if E_STEPPERS > 4 + START_E_PULSE(4); + #endif + #endif + #endif + #endif + + // For minimum pulse time wait before stopping pulses + #if EXTRA_CYCLES_E > 20 + while (EXTRA_CYCLES_E > (uint32_t)(TCNT0 - pulse_start) * (INT0_PRESCALER)) { /* nada */ } + pulse_start = TCNT0; + #elif EXTRA_CYCLES_E > 0 + DELAY_NOPS(EXTRA_CYCLES_E); + #endif + + STOP_E_PULSE(0); + #if E_STEPPERS > 1 + STOP_E_PULSE(1); + #if E_STEPPERS > 2 + STOP_E_PULSE(2); + #if E_STEPPERS > 3 + STOP_E_PULSE(3); + #if E_STEPPERS > 4 + STOP_E_PULSE(4); + #endif + #endif + #endif + #endif + + // For minimum pulse time wait before looping + #if EXTRA_CYCLES_E > 20 + if (i) while (EXTRA_CYCLES_E > (uint32_t)(TCNT0 - pulse_start) * (INT0_PRESCALER)) { /* nada */ } + #elif EXTRA_CYCLES_E > 0 + if (i) DELAY_NOPS(EXTRA_CYCLES_E); + #endif + + } // steps_loop + } + + void Stepper::advance_isr_scheduler() { + // Disable Timer0 ISRs and enable global ISR again to capture UART events (incoming chars) + CBI(TIMSK0, OCIE0B); // Temperature ISR + DISABLE_STEPPER_DRIVER_INTERRUPT(); + sei(); + + // Run main stepping ISR if flagged + if (!nextMainISR) isr(); + + // Run Advance stepping ISR if flagged + if (!nextAdvanceISR) advance_isr(); + + // Is the next advance ISR scheduled before the next main ISR? + if (nextAdvanceISR <= nextMainISR) { + // Set up the next interrupt + OCR1A = nextAdvanceISR; + // New interval for the next main ISR + if (nextMainISR) nextMainISR -= nextAdvanceISR; + // Will call Stepper::advance_isr on the next interrupt + nextAdvanceISR = 0; + } + else { + // The next main ISR comes first + OCR1A = nextMainISR; + // New interval for the next advance ISR, if any + if (nextAdvanceISR && nextAdvanceISR != ADV_NEVER) + nextAdvanceISR -= nextMainISR; + // Will call Stepper::isr on the next interrupt + nextMainISR = 0; + } + + // Don't run the ISR faster than possible + NOLESS(OCR1A, TCNT1 + 16); + + // Restore original ISR settings + _ENABLE_ISRs(); + } + +#endif // LIN_ADVANCE + +void Stepper::init() { + + // Init Digipot Motor Current + #if HAS_DIGIPOTSS || HAS_MOTOR_CURRENT_PWM + digipot_init(); + #endif + + // Init Microstepping Pins + #if HAS_MICROSTEPS + microstep_init(); + #endif + + // Init TMC Steppers + #if ENABLED(HAVE_TMCDRIVER) + tmc_init(); + #endif + + // Init TMC2130 Steppers + #if ENABLED(HAVE_TMC2130) + tmc2130_init(); + #endif + + // Init L6470 Steppers + #if ENABLED(HAVE_L6470DRIVER) + L6470_init(); + #endif + + // Init Dir Pins + #if HAS_X_DIR + X_DIR_INIT; + #endif + #if HAS_X2_DIR + X2_DIR_INIT; + #endif + #if HAS_Y_DIR + Y_DIR_INIT; + #if ENABLED(Y_DUAL_STEPPER_DRIVERS) && HAS_Y2_DIR + Y2_DIR_INIT; + #endif + #endif + #if HAS_Z_DIR + Z_DIR_INIT; + #if ENABLED(Z_DUAL_STEPPER_DRIVERS) && HAS_Z2_DIR + Z2_DIR_INIT; + #endif + #endif + #if HAS_E0_DIR + E0_DIR_INIT; + #endif + #if HAS_E1_DIR + E1_DIR_INIT; + #endif + #if HAS_E2_DIR + E2_DIR_INIT; + #endif + #if HAS_E3_DIR + E3_DIR_INIT; + #endif + #if HAS_E4_DIR + E4_DIR_INIT; + #endif + + // Init Enable Pins - steppers default to disabled. + #if HAS_X_ENABLE + X_ENABLE_INIT; + if (!X_ENABLE_ON) X_ENABLE_WRITE(HIGH); + #if ENABLED(DUAL_X_CARRIAGE) && HAS_X2_ENABLE + X2_ENABLE_INIT; + if (!X_ENABLE_ON) X2_ENABLE_WRITE(HIGH); + #endif + #endif + #if HAS_Y_ENABLE + Y_ENABLE_INIT; + if (!Y_ENABLE_ON) Y_ENABLE_WRITE(HIGH); + #if ENABLED(Y_DUAL_STEPPER_DRIVERS) && HAS_Y2_ENABLE + Y2_ENABLE_INIT; + if (!Y_ENABLE_ON) Y2_ENABLE_WRITE(HIGH); + #endif + #endif + #if HAS_Z_ENABLE + Z_ENABLE_INIT; + if (!Z_ENABLE_ON) Z_ENABLE_WRITE(HIGH); + #if ENABLED(Z_DUAL_STEPPER_DRIVERS) && HAS_Z2_ENABLE + Z2_ENABLE_INIT; + if (!Z_ENABLE_ON) Z2_ENABLE_WRITE(HIGH); + #endif + #endif + #if HAS_E0_ENABLE + E0_ENABLE_INIT; + if (!E_ENABLE_ON) E0_ENABLE_WRITE(HIGH); + #endif + #if HAS_E1_ENABLE + E1_ENABLE_INIT; + if (!E_ENABLE_ON) E1_ENABLE_WRITE(HIGH); + #endif + #if HAS_E2_ENABLE + E2_ENABLE_INIT; + if (!E_ENABLE_ON) E2_ENABLE_WRITE(HIGH); + #endif + #if HAS_E3_ENABLE + E3_ENABLE_INIT; + if (!E_ENABLE_ON) E3_ENABLE_WRITE(HIGH); + #endif + #if HAS_E4_ENABLE + E4_ENABLE_INIT; + if (!E_ENABLE_ON) E4_ENABLE_WRITE(HIGH); + #endif + + // Init endstops and pullups + endstops.init(); + + #define _STEP_INIT(AXIS) AXIS ##_STEP_INIT + #define _WRITE_STEP(AXIS, HIGHLOW) AXIS ##_STEP_WRITE(HIGHLOW) + #define _DISABLE(AXIS) disable_## AXIS() + + #define AXIS_INIT(AXIS, PIN) \ + _STEP_INIT(AXIS); \ + _WRITE_STEP(AXIS, _INVERT_STEP_PIN(PIN)); \ + _DISABLE(AXIS) + + #define E_AXIS_INIT(NUM) AXIS_INIT(E## NUM, E) + + // Init Step Pins + #if HAS_X_STEP + #if ENABLED(X_DUAL_STEPPER_DRIVERS) || ENABLED(DUAL_X_CARRIAGE) + X2_STEP_INIT; + X2_STEP_WRITE(INVERT_X_STEP_PIN); + #endif + AXIS_INIT(X, X); + #endif + + #if HAS_Y_STEP + #if ENABLED(Y_DUAL_STEPPER_DRIVERS) + Y2_STEP_INIT; + Y2_STEP_WRITE(INVERT_Y_STEP_PIN); + #endif + AXIS_INIT(Y, Y); + #endif + + #if HAS_Z_STEP + #if ENABLED(Z_DUAL_STEPPER_DRIVERS) + Z2_STEP_INIT; + Z2_STEP_WRITE(INVERT_Z_STEP_PIN); + #endif + AXIS_INIT(Z, Z); + #endif + + #if HAS_E0_STEP + E_AXIS_INIT(0); + #endif + #if HAS_E1_STEP + E_AXIS_INIT(1); + #endif + #if HAS_E2_STEP + E_AXIS_INIT(2); + #endif + #if HAS_E3_STEP + E_AXIS_INIT(3); + #endif + #if HAS_E4_STEP + E_AXIS_INIT(4); + #endif + + // waveform generation = 0100 = CTC + SET_WGM(1, CTC_OCRnA); + + // output mode = 00 (disconnected) + SET_COMA(1, NORMAL); + + // Set the timer pre-scaler + // Generally we use a divider of 8, resulting in a 2MHz timer + // frequency on a 16MHz MCU. If you are going to change this, be + // sure to regenerate speed_lookuptable.h with + // create_speed_lookuptable.py + SET_CS(1, PRESCALER_8); // CS 2 = 1/8 prescaler + + // Init Stepper ISR to 122 Hz for quick starting + OCR1A = 0x4000; + TCNT1 = 0; + ENABLE_STEPPER_DRIVER_INTERRUPT(); + + #if ENABLED(LIN_ADVANCE) + for (uint8_t i = 0; i < COUNT(e_steps); i++) e_steps[i] = 0; + ZERO(current_adv_steps); + #endif + + endstops.enable(true); // Start with endstops active. After homing they can be disabled + sei(); + + set_directions(); // Init directions to last_direction_bits = 0 +} + + +/** + * Block until all buffered steps are executed + */ +void Stepper::synchronize() { while (planner.blocks_queued()) idle(); } + +/** + * Set the stepper positions directly in steps + * + * The input is based on the typical per-axis XYZ steps. + * For CORE machines XYZ needs to be translated to ABC. + * + * This allows get_axis_position_mm to correctly + * derive the current XYZ position later on. + */ +void Stepper::set_position(const long &a, const long &b, const long &c, const long &e) { + + synchronize(); // Bad to set stepper counts in the middle of a move + + CRITICAL_SECTION_START; + + #if CORE_IS_XY + // corexy positioning + // these equations follow the form of the dA and dB equations on http://www.corexy.com/theory.html + count_position[A_AXIS] = a + b; + count_position[B_AXIS] = CORESIGN(a - b); + count_position[Z_AXIS] = c; + #elif CORE_IS_XZ + // corexz planning + count_position[A_AXIS] = a + c; + count_position[Y_AXIS] = b; + count_position[C_AXIS] = CORESIGN(a - c); + #elif CORE_IS_YZ + // coreyz planning + count_position[X_AXIS] = a; + count_position[B_AXIS] = b + c; + count_position[C_AXIS] = CORESIGN(b - c); + #else + // default non-h-bot planning + count_position[X_AXIS] = a; + count_position[Y_AXIS] = b; + count_position[Z_AXIS] = c; + #endif + + count_position[E_AXIS] = e; + CRITICAL_SECTION_END; +} + +void Stepper::set_position(const AxisEnum &axis, const long &v) { + CRITICAL_SECTION_START; + count_position[axis] = v; + CRITICAL_SECTION_END; +} + +void Stepper::set_e_position(const long &e) { + CRITICAL_SECTION_START; + count_position[E_AXIS] = e; + CRITICAL_SECTION_END; +} + +/** + * Get a stepper's position in steps. + */ +long Stepper::position(AxisEnum axis) { + CRITICAL_SECTION_START; + const long count_pos = count_position[axis]; + CRITICAL_SECTION_END; + return count_pos; +} + +/** + * Get an axis position according to stepper position(s) + * For CORE machines apply translation from ABC to XYZ. + */ +float Stepper::get_axis_position_mm(AxisEnum axis) { + float axis_steps; + #if IS_CORE + // Requesting one of the "core" axes? + if (axis == CORE_AXIS_1 || axis == CORE_AXIS_2) { + CRITICAL_SECTION_START; + // ((a1+a2)+(a1-a2))/2 -> (a1+a2+a1-a2)/2 -> (a1+a1)/2 -> a1 + // ((a1+a2)-(a1-a2))/2 -> (a1+a2-a1+a2)/2 -> (a2+a2)/2 -> a2 + axis_steps = 0.5f * ( + axis == CORE_AXIS_2 ? CORESIGN(count_position[CORE_AXIS_1] - count_position[CORE_AXIS_2]) + : count_position[CORE_AXIS_1] + count_position[CORE_AXIS_2] + ); + CRITICAL_SECTION_END; + } + else + axis_steps = position(axis); + #else + axis_steps = position(axis); + #endif + return axis_steps * planner.steps_to_mm[axis]; +} + +void Stepper::finish_and_disable() { + synchronize(); + disable_all_steppers(); +} + +void Stepper::quick_stop() { + #if ENABLED(AUTO_BED_LEVELING_UBL) && ENABLED(ULTIPANEL) + if (!ubl_lcd_map_control) + cleaning_buffer_counter = 5000; + #else + cleaning_buffer_counter = 5000; + #endif + DISABLE_STEPPER_DRIVER_INTERRUPT(); + while (planner.blocks_queued()) planner.discard_current_block(); + current_block = NULL; + ENABLE_STEPPER_DRIVER_INTERRUPT(); + #if ENABLED(ULTRA_LCD) + planner.clear_block_buffer_runtime(); + #endif +} + +void Stepper::endstop_triggered(AxisEnum axis) { + + #if IS_CORE + + endstops_trigsteps[axis] = 0.5f * ( + axis == CORE_AXIS_2 ? CORESIGN(count_position[CORE_AXIS_1] - count_position[CORE_AXIS_2]) + : count_position[CORE_AXIS_1] + count_position[CORE_AXIS_2] + ); + + #else // !COREXY && !COREXZ && !COREYZ + + endstops_trigsteps[axis] = count_position[axis]; + + #endif // !COREXY && !COREXZ && !COREYZ + + kill_current_block(); +} + +void Stepper::report_positions() { + CRITICAL_SECTION_START; + const long xpos = count_position[X_AXIS], + ypos = count_position[Y_AXIS], + zpos = count_position[Z_AXIS]; + CRITICAL_SECTION_END; + + #if CORE_IS_XY || CORE_IS_XZ || IS_SCARA + SERIAL_PROTOCOLPGM(MSG_COUNT_A); + #else + SERIAL_PROTOCOLPGM(MSG_COUNT_X); + #endif + SERIAL_PROTOCOL(xpos); + + #if CORE_IS_XY || CORE_IS_YZ || IS_SCARA + SERIAL_PROTOCOLPGM(" B:"); + #else + SERIAL_PROTOCOLPGM(" Y:"); + #endif + SERIAL_PROTOCOL(ypos); + + #if CORE_IS_XZ || CORE_IS_YZ + SERIAL_PROTOCOLPGM(" C:"); + #else + SERIAL_PROTOCOLPGM(" Z:"); + #endif + SERIAL_PROTOCOL(zpos); + + SERIAL_EOL(); +} + +#if ENABLED(BABYSTEPPING) + + #if ENABLED(DELTA) + #define CYCLES_EATEN_BABYSTEP (2 * 15) + #else + #define CYCLES_EATEN_BABYSTEP 0 + #endif + #define EXTRA_CYCLES_BABYSTEP (STEP_PULSE_CYCLES - (CYCLES_EATEN_BABYSTEP)) + + #define _ENABLE(AXIS) enable_## AXIS() + #define _READ_DIR(AXIS) AXIS ##_DIR_READ + #define _INVERT_DIR(AXIS) INVERT_## AXIS ##_DIR + #define _APPLY_DIR(AXIS, INVERT) AXIS ##_APPLY_DIR(INVERT, true) + + #if EXTRA_CYCLES_BABYSTEP > 20 + #define _SAVE_START const uint32_t pulse_start = TCNT0 + #define _PULSE_WAIT while (EXTRA_CYCLES_BABYSTEP > (uint32_t)(TCNT0 - pulse_start) * (INT0_PRESCALER)) { /* nada */ } + #else + #define _SAVE_START NOOP + #if EXTRA_CYCLES_BABYSTEP > 0 + #define _PULSE_WAIT DELAY_NOPS(EXTRA_CYCLES_BABYSTEP) + #elif STEP_PULSE_CYCLES > 0 + #define _PULSE_WAIT NOOP + #elif ENABLED(DELTA) + #define _PULSE_WAIT delayMicroseconds(2); + #else + #define _PULSE_WAIT delayMicroseconds(4); + #endif + #endif + + #define BABYSTEP_AXIS(AXIS, INVERT) { \ + const uint8_t old_dir = _READ_DIR(AXIS); \ + _ENABLE(AXIS); \ + _SAVE_START; \ + _APPLY_DIR(AXIS, _INVERT_DIR(AXIS)^direction^INVERT); \ + _APPLY_STEP(AXIS)(!_INVERT_STEP_PIN(AXIS), true); \ + _PULSE_WAIT; \ + _APPLY_STEP(AXIS)(_INVERT_STEP_PIN(AXIS), true); \ + _APPLY_DIR(AXIS, old_dir); \ + } + + // MUST ONLY BE CALLED BY AN ISR, + // No other ISR should ever interrupt this! + void Stepper::babystep(const AxisEnum axis, const bool direction) { + cli(); + + switch (axis) { + + #if ENABLED(BABYSTEP_XY) + + case X_AXIS: + BABYSTEP_AXIS(X, false); + break; + + case Y_AXIS: + BABYSTEP_AXIS(Y, false); + break; + + #endif + + case Z_AXIS: { + + #if DISABLED(DELTA) + + BABYSTEP_AXIS(Z, BABYSTEP_INVERT_Z); + + #else // DELTA + + const bool z_direction = direction ^ BABYSTEP_INVERT_Z; + + enable_X(); + enable_Y(); + enable_Z(); + + const uint8_t old_x_dir_pin = X_DIR_READ, + old_y_dir_pin = Y_DIR_READ, + old_z_dir_pin = Z_DIR_READ; + + X_DIR_WRITE(INVERT_X_DIR ^ z_direction); + Y_DIR_WRITE(INVERT_Y_DIR ^ z_direction); + Z_DIR_WRITE(INVERT_Z_DIR ^ z_direction); + + _SAVE_START; + + X_STEP_WRITE(!INVERT_X_STEP_PIN); + Y_STEP_WRITE(!INVERT_Y_STEP_PIN); + Z_STEP_WRITE(!INVERT_Z_STEP_PIN); + + _PULSE_WAIT; + + X_STEP_WRITE(INVERT_X_STEP_PIN); + Y_STEP_WRITE(INVERT_Y_STEP_PIN); + Z_STEP_WRITE(INVERT_Z_STEP_PIN); + + // Restore direction bits + X_DIR_WRITE(old_x_dir_pin); + Y_DIR_WRITE(old_y_dir_pin); + Z_DIR_WRITE(old_z_dir_pin); + + #endif + + } break; + + default: break; + } + sei(); + } + +#endif // BABYSTEPPING + +/** + * Software-controlled Stepper Motor Current + */ + +#if HAS_DIGIPOTSS + + // From Arduino DigitalPotControl example + void Stepper::digitalPotWrite(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); + WRITE(DIGIPOTSS_PIN, HIGH); // Take the SS pin high to de-select the chip + //delay(10); + } + +#endif // HAS_DIGIPOTSS + +#if HAS_MOTOR_CURRENT_PWM + + void Stepper::refresh_motor_power() { + for (uint8_t i = 0; i < COUNT(motor_current_setting); ++i) { + switch (i) { + #if PIN_EXISTS(MOTOR_CURRENT_PWM_XY) + case 0: + #endif + #if PIN_EXISTS(MOTOR_CURRENT_PWM_Z) + case 1: + #endif + #if PIN_EXISTS(MOTOR_CURRENT_PWM_E) + case 2: + #endif + digipot_current(i, motor_current_setting[i]); + default: break; + } + } + } + +#endif // HAS_MOTOR_CURRENT_PWM + +#if HAS_DIGIPOTSS || HAS_MOTOR_CURRENT_PWM + + void Stepper::digipot_current(const uint8_t driver, const int current) { + + #if HAS_DIGIPOTSS + + const uint8_t digipot_ch[] = DIGIPOT_CHANNELS; + digitalPotWrite(digipot_ch[driver], current); + + #elif HAS_MOTOR_CURRENT_PWM + + if (WITHIN(driver, 0, 2)) + motor_current_setting[driver] = current; // update motor_current_setting + + #define _WRITE_CURRENT_PWM(P) analogWrite(MOTOR_CURRENT_PWM_## P ##_PIN, 255L * current / (MOTOR_CURRENT_PWM_RANGE)) + switch (driver) { + #if PIN_EXISTS(MOTOR_CURRENT_PWM_XY) + case 0: _WRITE_CURRENT_PWM(XY); break; + #endif + #if PIN_EXISTS(MOTOR_CURRENT_PWM_Z) + case 1: _WRITE_CURRENT_PWM(Z); break; + #endif + #if PIN_EXISTS(MOTOR_CURRENT_PWM_E) + case 2: _WRITE_CURRENT_PWM(E); break; + #endif + } + #endif + } + + void Stepper::digipot_init() { + + #if HAS_DIGIPOTSS + + static const uint8_t digipot_motor_current[] = DIGIPOT_MOTOR_CURRENT; + + 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]); + } + + #elif HAS_MOTOR_CURRENT_PWM + + #if PIN_EXISTS(MOTOR_CURRENT_PWM_XY) + SET_OUTPUT(MOTOR_CURRENT_PWM_XY_PIN); + #endif + #if PIN_EXISTS(MOTOR_CURRENT_PWM_Z) + SET_OUTPUT(MOTOR_CURRENT_PWM_Z_PIN); + #endif + #if PIN_EXISTS(MOTOR_CURRENT_PWM_E) + SET_OUTPUT(MOTOR_CURRENT_PWM_E_PIN); + #endif + + refresh_motor_power(); + + // Set Timer5 to 31khz so the PWM of the motor power is as constant as possible. (removes a buzzing noise) + SET_CS5(PRESCALER_1); + + #endif + } + +#endif + +#if HAS_MICROSTEPS + + /** + * Software-controlled Microstepping + */ + + void Stepper::microstep_init() { + SET_OUTPUT(X_MS1_PIN); + SET_OUTPUT(X_MS2_PIN); + #if HAS_Y_MICROSTEPS + SET_OUTPUT(Y_MS1_PIN); + SET_OUTPUT(Y_MS2_PIN); + #endif + #if HAS_Z_MICROSTEPS + SET_OUTPUT(Z_MS1_PIN); + SET_OUTPUT(Z_MS2_PIN); + #endif + #if HAS_E0_MICROSTEPS + SET_OUTPUT(E0_MS1_PIN); + SET_OUTPUT(E0_MS2_PIN); + #endif + #if HAS_E1_MICROSTEPS + SET_OUTPUT(E1_MS1_PIN); + SET_OUTPUT(E1_MS2_PIN); + #endif + #if HAS_E2_MICROSTEPS + SET_OUTPUT(E2_MS1_PIN); + SET_OUTPUT(E2_MS2_PIN); + #endif + #if HAS_E3_MICROSTEPS + SET_OUTPUT(E3_MS1_PIN); + SET_OUTPUT(E3_MS2_PIN); + #endif + #if HAS_E4_MICROSTEPS + SET_OUTPUT(E4_MS1_PIN); + SET_OUTPUT(E4_MS2_PIN); + #endif + static const uint8_t microstep_modes[] = MICROSTEP_MODES; + for (uint16_t i = 0; i < COUNT(microstep_modes); i++) + microstep_mode(i, microstep_modes[i]); + } + + void Stepper::microstep_ms(const uint8_t driver, const int8_t ms1, const int8_t ms2) { + if (ms1 >= 0) switch (driver) { + case 0: WRITE(X_MS1_PIN, ms1); break; + #if HAS_Y_MICROSTEPS + case 1: WRITE(Y_MS1_PIN, ms1); break; + #endif + #if HAS_Z_MICROSTEPS + case 2: WRITE(Z_MS1_PIN, ms1); break; + #endif + #if HAS_E0_MICROSTEPS + case 3: WRITE(E0_MS1_PIN, ms1); break; + #endif + #if HAS_E1_MICROSTEPS + case 4: WRITE(E1_MS1_PIN, ms1); break; + #endif + #if HAS_E2_MICROSTEPS + case 5: WRITE(E2_MS1_PIN, ms1); break; + #endif + #if HAS_E3_MICROSTEPS + case 6: WRITE(E3_MS1_PIN, ms1); break; + #endif + #if HAS_E4_MICROSTEPS + case 7: WRITE(E4_MS1_PIN, ms1); break; + #endif + } + if (ms2 >= 0) switch (driver) { + case 0: WRITE(X_MS2_PIN, ms2); break; + #if HAS_Y_MICROSTEPS + case 1: WRITE(Y_MS2_PIN, ms2); break; + #endif + #if HAS_Z_MICROSTEPS + case 2: WRITE(Z_MS2_PIN, ms2); break; + #endif + #if HAS_E0_MICROSTEPS + case 3: WRITE(E0_MS2_PIN, ms2); break; + #endif + #if HAS_E1_MICROSTEPS + case 4: WRITE(E1_MS2_PIN, ms2); break; + #endif + #if HAS_E2_MICROSTEPS + case 5: WRITE(E2_MS2_PIN, ms2); break; + #endif + #if HAS_E3_MICROSTEPS + case 6: WRITE(E3_MS2_PIN, ms2); break; + #endif + #if HAS_E4_MICROSTEPS + case 7: WRITE(E4_MS2_PIN, ms2); break; + #endif + } + } + + void Stepper::microstep_mode(const uint8_t driver, const uint8_t stepping_mode) { + switch (stepping_mode) { + case 1: microstep_ms(driver, MICROSTEP1); break; + case 2: microstep_ms(driver, MICROSTEP2); break; + case 4: microstep_ms(driver, MICROSTEP4); break; + case 8: microstep_ms(driver, MICROSTEP8); break; + case 16: microstep_ms(driver, MICROSTEP16); break; + } + } + + void Stepper::microstep_readings() { + SERIAL_PROTOCOLLNPGM("MS1,MS2 Pins"); + SERIAL_PROTOCOLPGM("X: "); + SERIAL_PROTOCOL(READ(X_MS1_PIN)); + SERIAL_PROTOCOLLN(READ(X_MS2_PIN)); + #if HAS_Y_MICROSTEPS + SERIAL_PROTOCOLPGM("Y: "); + SERIAL_PROTOCOL(READ(Y_MS1_PIN)); + SERIAL_PROTOCOLLN(READ(Y_MS2_PIN)); + #endif + #if HAS_Z_MICROSTEPS + SERIAL_PROTOCOLPGM("Z: "); + SERIAL_PROTOCOL(READ(Z_MS1_PIN)); + SERIAL_PROTOCOLLN(READ(Z_MS2_PIN)); + #endif + #if HAS_E0_MICROSTEPS + SERIAL_PROTOCOLPGM("E0: "); + SERIAL_PROTOCOL(READ(E0_MS1_PIN)); + SERIAL_PROTOCOLLN(READ(E0_MS2_PIN)); + #endif + #if HAS_E1_MICROSTEPS + SERIAL_PROTOCOLPGM("E1: "); + SERIAL_PROTOCOL(READ(E1_MS1_PIN)); + SERIAL_PROTOCOLLN(READ(E1_MS2_PIN)); + #endif + #if HAS_E2_MICROSTEPS + SERIAL_PROTOCOLPGM("E2: "); + SERIAL_PROTOCOL(READ(E2_MS1_PIN)); + SERIAL_PROTOCOLLN(READ(E2_MS2_PIN)); + #endif + #if HAS_E3_MICROSTEPS + SERIAL_PROTOCOLPGM("E3: "); + SERIAL_PROTOCOL(READ(E3_MS1_PIN)); + SERIAL_PROTOCOLLN(READ(E3_MS2_PIN)); + #endif + #if HAS_E4_MICROSTEPS + SERIAL_PROTOCOLPGM("E4: "); + SERIAL_PROTOCOL(READ(E4_MS1_PIN)); + SERIAL_PROTOCOLLN(READ(E4_MS2_PIN)); + #endif + } + +#endif // HAS_MICROSTEPS diff --git a/trunk/Arduino/Marlin_1.1.6/stepper.h b/trunk/Arduino/Marlin_1.1.6/stepper.h new file mode 100644 index 00000000..682d684f --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/stepper.h @@ -0,0 +1,374 @@ +/** + * 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 . + * + */ + +/** + * stepper.h - stepper motor driver: executes motion plans of planner.c using the stepper motors + * Derived from Grbl + * + * Copyright (c) 2009-2011 Simen Svale Skogsrud + * + * Grbl is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Grbl is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * 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 . + */ + +#ifndef STEPPER_H +#define STEPPER_H + +#include "planner.h" +#include "speed_lookuptable.h" +#include "stepper_indirection.h" +#include "language.h" +#include "types.h" + +class Stepper; +extern Stepper stepper; + +// intRes = intIn1 * intIn2 >> 16 +// uses: +// r26 to store 0 +// r27 to store the byte 1 of the 24 bit result +#define MultiU16X8toH16(intRes, charIn1, intIn2) \ + asm volatile ( \ + "clr r26 \n\t" \ + "mul %A1, %B2 \n\t" \ + "movw %A0, r0 \n\t" \ + "mul %A1, %A2 \n\t" \ + "add %A0, r1 \n\t" \ + "adc %B0, r26 \n\t" \ + "lsr r0 \n\t" \ + "adc %A0, r26 \n\t" \ + "adc %B0, r26 \n\t" \ + "clr r1 \n\t" \ + : \ + "=&r" (intRes) \ + : \ + "d" (charIn1), \ + "d" (intIn2) \ + : \ + "r26" \ + ) + +class Stepper { + + public: + + static block_t* current_block; // A pointer to the block currently being traced + + #if ENABLED(ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED) + static bool abort_on_endstop_hit; + #endif + + #if ENABLED(Z_DUAL_ENDSTOPS) + static bool performing_homing; + #endif + + #if HAS_MOTOR_CURRENT_PWM + #ifndef PWM_MOTOR_CURRENT + #define PWM_MOTOR_CURRENT DEFAULT_PWM_MOTOR_CURRENT + #endif + static uint32_t motor_current_setting[3]; + #endif + + private: + + static uint8_t last_direction_bits; // The next stepping-bits to be output + static uint16_t cleaning_buffer_counter; + + #if ENABLED(Z_DUAL_ENDSTOPS) + static bool locked_z_motor, locked_z2_motor; + #endif + + // Counter variables for the Bresenham line tracer + static long counter_X, counter_Y, counter_Z, counter_E; + static volatile uint32_t step_events_completed; // The number of step events executed in the current block + + #if ENABLED(LIN_ADVANCE) + + static uint16_t nextMainISR, nextAdvanceISR, eISR_Rate; + #define _NEXT_ISR(T) nextMainISR = T + static volatile int e_steps[E_STEPPERS]; + static int final_estep_rate; + static int current_estep_rate[E_STEPPERS]; // Actual extruder speed [steps/s] + static int current_adv_steps[E_STEPPERS]; // The amount of current added esteps due to advance. + // i.e., the current amount of pressure applied + // to the spring (=filament). + #else // !LIN_ADVANCE + + #define _NEXT_ISR(T) OCR1A = T + + #endif // !LIN_ADVANCE + + static long acceleration_time, deceleration_time; + //unsigned long accelerate_until, decelerate_after, acceleration_rate, initial_rate, final_rate, nominal_rate; + static unsigned short acc_step_rate; // needed for deceleration start point + static uint8_t step_loops, step_loops_nominal; + static unsigned short OCR1A_nominal; + + static volatile long endstops_trigsteps[XYZ]; + static volatile long endstops_stepsTotal, endstops_stepsDone; + + // + // Positions of stepper motors, in step units + // + static volatile long count_position[NUM_AXIS]; + + // + // Current direction of stepper motors (+1 or -1) + // + static volatile signed char count_direction[NUM_AXIS]; + + // + // Mixing extruder mix counters + // + #if ENABLED(MIXING_EXTRUDER) + static long counter_m[MIXING_STEPPERS]; + #define MIXING_STEPPERS_LOOP(VAR) \ + for (uint8_t VAR = 0; VAR < MIXING_STEPPERS; VAR++) \ + if (current_block->mix_event_count[VAR]) + #endif + + public: + + // + // Constructor / initializer + // + Stepper() { }; + + // + // Initialize stepper hardware + // + static void init(); + + // + // Interrupt Service Routines + // + + static void isr(); + + #if ENABLED(LIN_ADVANCE) + static void advance_isr(); + static void advance_isr_scheduler(); + #endif + + // + // Block until all buffered steps are executed + // + static void synchronize(); + + // + // Set the current position in steps + // + static void set_position(const long &a, const long &b, const long &c, const long &e); + static void set_position(const AxisEnum &a, const long &v); + static void set_e_position(const long &e); + + // + // Set direction bits for all steppers + // + static void set_directions(); + + // + // Get the position of a stepper, in steps + // + static long position(AxisEnum axis); + + // + // Report the positions of the steppers, in steps + // + static void report_positions(); + + // + // Get the position (mm) of an axis based on stepper position(s) + // + static float get_axis_position_mm(AxisEnum axis); + + // + // SCARA AB axes are in degrees, not mm + // + #if IS_SCARA + static FORCE_INLINE float get_axis_position_degrees(AxisEnum axis) { return get_axis_position_mm(axis); } + #endif + + // + // The stepper subsystem goes to sleep when it runs out of things to execute. Call this + // to notify the subsystem that it is time to go to work. + // + static void wake_up(); + + // + // Wait for moves to finish and disable all steppers + // + static void finish_and_disable(); + + // + // Quickly stop all steppers and clear the blocks queue + // + static void quick_stop(); + + // + // The direction of a single motor + // + static FORCE_INLINE bool motor_direction(AxisEnum axis) { return TEST(last_direction_bits, 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); + #endif + + #if HAS_MICROSTEPS + static void microstep_ms(const uint8_t driver, const int8_t ms1, const int8_t ms2); + static void microstep_mode(const uint8_t driver, const uint8_t stepping); + static void microstep_readings(); + #endif + + #if ENABLED(Z_DUAL_ENDSTOPS) + static FORCE_INLINE void set_homing_flag(const bool state) { performing_homing = state; } + static FORCE_INLINE void set_z_lock(const bool state) { locked_z_motor = state; } + static FORCE_INLINE void set_z2_lock(const bool state) { locked_z2_motor = state; } + #endif + + #if ENABLED(BABYSTEPPING) + static void babystep(const AxisEnum axis, const bool direction); // perform a short step with a single stepper motor, outside of any convention + #endif + + static inline void kill_current_block() { + step_events_completed = current_block->step_event_count; + } + + // + // Handle a triggered endstop + // + static void endstop_triggered(AxisEnum axis); + + // + // Triggered position of an axis in mm (not core-savvy) + // + static FORCE_INLINE float triggered_position_mm(AxisEnum axis) { + return endstops_trigsteps[axis] * planner.steps_to_mm[axis]; + } + + #if HAS_MOTOR_CURRENT_PWM + static void refresh_motor_power(); + #endif + + private: + + static FORCE_INLINE unsigned short calc_timer(unsigned short step_rate) { + unsigned short timer; + + NOMORE(step_rate, MAX_STEP_FREQUENCY); + + if (step_rate > 20000) { // If steprate > 20kHz >> step 4 times + step_rate >>= 2; + step_loops = 4; + } + else if (step_rate > 10000) { // If steprate > 10kHz >> step 2 times + step_rate >>= 1; + step_loops = 2; + } + else { + step_loops = 1; + } + + NOLESS(step_rate, F_CPU / 500000); + step_rate -= F_CPU / 500000; // Correct for minimal speed + if (step_rate >= (8 * 256)) { // higher step rate + unsigned short table_address = (unsigned short)&speed_lookuptable_fast[(unsigned char)(step_rate >> 8)][0]; + unsigned char tmp_step_rate = (step_rate & 0x00FF); + unsigned short gain = (unsigned short)pgm_read_word_near(table_address + 2); + MultiU16X8toH16(timer, tmp_step_rate, gain); + timer = (unsigned short)pgm_read_word_near(table_address) - timer; + } + else { // lower step rates + unsigned short table_address = (unsigned short)&speed_lookuptable_slow[0][0]; + table_address += ((step_rate) >> 1) & 0xFFFC; + timer = (unsigned short)pgm_read_word_near(table_address); + timer -= (((unsigned short)pgm_read_word_near(table_address + 2) * (unsigned char)(step_rate & 0x0007)) >> 3); + } + if (timer < 100) { // (20kHz - this should never happen) + timer = 100; + MYSERIAL.print(MSG_STEPPER_TOO_HIGH); + MYSERIAL.println(step_rate); + } + return timer; + } + + // Initialize the trapezoid generator from the current block. + // Called whenever a new block begins. + static FORCE_INLINE void trapezoid_generator_reset() { + + static int8_t last_extruder = -1; + + if (current_block->direction_bits != last_direction_bits || current_block->active_extruder != last_extruder) { + last_direction_bits = current_block->direction_bits; + last_extruder = current_block->active_extruder; + set_directions(); + } + + deceleration_time = 0; + // step_rate to timer interval + OCR1A_nominal = calc_timer(current_block->nominal_rate); + // make a note of the number of step loops required at nominal speed + step_loops_nominal = step_loops; + acc_step_rate = current_block->initial_rate; + acceleration_time = calc_timer(acc_step_rate); + _NEXT_ISR(acceleration_time); + + #if ENABLED(LIN_ADVANCE) + if (current_block->use_advance_lead) { + current_estep_rate[current_block->active_extruder] = ((unsigned long)acc_step_rate * current_block->abs_adv_steps_multiplier8) >> 17; + final_estep_rate = (current_block->nominal_rate * current_block->abs_adv_steps_multiplier8) >> 17; + } + #endif + + // SERIAL_ECHO_START(); + // SERIAL_ECHOPGM("advance :"); + // SERIAL_ECHO(current_block->advance/256.0); + // SERIAL_ECHOPGM("advance rate :"); + // SERIAL_ECHO(current_block->advance_rate/256.0); + // SERIAL_ECHOPGM("initial advance :"); + // SERIAL_ECHO(current_block->initial_advance/256.0); + // SERIAL_ECHOPGM("final advance :"); + // SERIAL_ECHOLN(current_block->final_advance/256.0); + } + + #if HAS_DIGIPOTSS || HAS_MOTOR_CURRENT_PWM + static void digipot_init(); + #endif + + #if HAS_MICROSTEPS + static void microstep_init(); + #endif + +}; + +#endif // STEPPER_H diff --git a/trunk/Arduino/Marlin_1.1.6/stepper_dac.cpp b/trunk/Arduino/Marlin_1.1.6/stepper_dac.cpp new file mode 100644 index 00000000..6ea8b83b --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/stepper_dac.cpp @@ -0,0 +1,125 @@ +/** + * 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 . + * + */ + +/** + stepper_dac.cpp - To set stepper current via DAC + + Part of Marlin + + Copyright (c) 2016 MarlinFirmware + + Marlin is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Marlin is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Marlin. If not, see . +*/ + +#include "Marlin.h" + +#if ENABLED(DAC_STEPPER_CURRENT) + + #include "stepper_dac.h" + + bool dac_present = false; + const uint8_t dac_order[NUM_AXIS] = DAC_STEPPER_ORDER; + uint8_t dac_channel_pct[XYZE] = DAC_MOTOR_CURRENT_DEFAULT; + + int dac_init() { + #if PIN_EXISTS(DAC_DISABLE) + OUT_WRITE(DAC_DISABLE_PIN, LOW); // set pin low to enable DAC + #endif + + mcp4728_init(); + + if (mcp4728_simpleCommand(RESET)) return -1; + + dac_present = true; + + 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(); + } + + return 0; + } + + void dac_current_percent(uint8_t channel, float val) { + if (!dac_present) return; + + NOMORE(val, 100); + + mcp4728_analogWrite(dac_order[channel], val * 0.01 * (DAC_STEPPER_MAX)); + mcp4728_simpleCommand(UPDATE); + } + + void dac_current_raw(uint8_t channel, uint16_t val) { + if (!dac_present) return; + + NOMORE(val, DAC_STEPPER_MAX); + + mcp4728_analogWrite(dac_order[channel], val); + mcp4728_simpleCommand(UPDATE); + } + + static float dac_perc(int8_t n) { return 100.0 * mcp4728_getValue(dac_order[n]) * (1.0 / (DAC_STEPPER_MAX)); } + static float dac_amps(int8_t n) { return mcp4728_getDrvPct(dac_order[n]) * (DAC_STEPPER_MAX) * 0.125 * (1.0 / (DAC_STEPPER_SENSE)); } + + uint8_t dac_current_get_percent(AxisEnum axis) { return mcp4728_getDrvPct(dac_order[axis]); } + void dac_current_set_percents(const uint8_t pct[XYZE]) { + LOOP_XYZE(i) dac_channel_pct[i] = pct[dac_order[i]]; + mcp4728_setDrvPct(dac_channel_pct); + } + + void dac_print_values() { + if (!dac_present) return; + + SERIAL_ECHO_START(); + SERIAL_ECHOLNPGM("Stepper current values in % (Amps):"); + SERIAL_ECHO_START(); + SERIAL_ECHOPAIR(" X:", dac_perc(X_AXIS)); + SERIAL_ECHOPAIR(" (", dac_amps(X_AXIS)); + SERIAL_ECHOPAIR(") Y:", dac_perc(Y_AXIS)); + SERIAL_ECHOPAIR(" (", dac_amps(Y_AXIS)); + SERIAL_ECHOPAIR(") Z:", dac_perc(Z_AXIS)); + SERIAL_ECHOPAIR(" (", dac_amps(Z_AXIS)); + SERIAL_ECHOPAIR(") E:", dac_perc(E_AXIS)); + SERIAL_ECHOPAIR(" (", dac_amps(E_AXIS)); + SERIAL_ECHOLN(")"); + } + + void dac_commit_eeprom() { + if (!dac_present) return; + mcp4728_eepromWrite(); + } + +#endif // DAC_STEPPER_CURRENT diff --git a/trunk/Arduino/Marlin_1.1.6/stepper_dac.h b/trunk/Arduino/Marlin_1.1.6/stepper_dac.h new file mode 100644 index 00000000..58803504 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/stepper_dac.h @@ -0,0 +1,57 @@ +/** + * 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 . + * + */ + +/** + stepper_dac.h - To set stepper current via DAC + + Part of Marlin + + Copyright (c) 2016 MarlinFirmware + + Marlin is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Marlin is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Marlin. If not, see . +*/ + +#ifndef STEPPER_DAC_H +#define STEPPER_DAC_H + +#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(const uint8_t pct[XYZE]); + +#endif // STEPPER_DAC_H diff --git a/trunk/Arduino/Marlin_1.1.6/stepper_indirection.cpp b/trunk/Arduino/Marlin_1.1.6/stepper_indirection.cpp new file mode 100644 index 00000000..9e9d3bf9 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/stepper_indirection.cpp @@ -0,0 +1,338 @@ +/** + * 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 . + * + */ + +/** + * stepper_indirection.cpp + * + * Stepper motor driver indirection to allow some stepper functions to + * be done via SPI/I2c instead of direct pin manipulation. + * + * Part of Marlin + * + * Copyright (c) 2015 Dominik Wenger + */ + +#include "stepper_indirection.h" + +#include "MarlinConfig.h" + +// +// TMC26X Driver objects and inits +// +#if ENABLED(HAVE_TMCDRIVER) + + #include + #include + + #define _TMC_DEFINE(ST) TMC26XStepper stepper##ST(200, ST##_ENABLE_PIN, ST##_STEP_PIN, ST##_DIR_PIN, ST##_MAX_CURRENT, ST##_SENSE_RESISTOR) + + #if ENABLED(X_IS_TMC) + _TMC_DEFINE(X); + #endif + #if ENABLED(X2_IS_TMC) + _TMC_DEFINE(X2); + #endif + #if ENABLED(Y_IS_TMC) + _TMC_DEFINE(Y); + #endif + #if ENABLED(Y2_IS_TMC) + _TMC_DEFINE(Y2); + #endif + #if ENABLED(Z_IS_TMC) + _TMC_DEFINE(Z); + #endif + #if ENABLED(Z2_IS_TMC) + _TMC_DEFINE(Z2); + #endif + #if ENABLED(E0_IS_TMC) + _TMC_DEFINE(E0); + #endif + #if ENABLED(E1_IS_TMC) + _TMC_DEFINE(E1); + #endif + #if ENABLED(E2_IS_TMC) + _TMC_DEFINE(E2); + #endif + #if ENABLED(E3_IS_TMC) + _TMC_DEFINE(E3); + #endif + #if ENABLED(E4_IS_TMC) + _TMC_DEFINE(E4); + #endif + + #define _TMC_INIT(A) do{ \ + stepper##A.setMicrosteps(A##_MICROSTEPS); \ + stepper##A.start(); \ + }while(0) + + void tmc_init() { + #if ENABLED(X_IS_TMC) + _TMC_INIT(X); + #endif + #if ENABLED(X2_IS_TMC) + _TMC_INIT(X2); + #endif + #if ENABLED(Y_IS_TMC) + _TMC_INIT(Y); + #endif + #if ENABLED(Y2_IS_TMC) + _TMC_INIT(Y2); + #endif + #if ENABLED(Z_IS_TMC) + _TMC_INIT(Z); + #endif + #if ENABLED(Z2_IS_TMC) + _TMC_INIT(Z2); + #endif + #if ENABLED(E0_IS_TMC) + _TMC_INIT(E0); + #endif + #if ENABLED(E1_IS_TMC) + _TMC_INIT(E1); + #endif + #if ENABLED(E2_IS_TMC) + _TMC_INIT(E2); + #endif + #if ENABLED(E3_IS_TMC) + _TMC_INIT(E3); + #endif + #if ENABLED(E4_IS_TMC) + _TMC_INIT(E4); + #endif + } + +#endif // HAVE_TMCDRIVER + +// +// TMC2130 Driver objects and inits +// +#if ENABLED(HAVE_TMC2130) + + #include + #include + #include "enum.h" + + #define _TMC2130_DEFINE(ST) TMC2130Stepper stepper##ST(ST##_ENABLE_PIN, ST##_DIR_PIN, ST##_STEP_PIN, ST##_CS_PIN) + + // Stepper objects of TMC2130 steppers used + #if ENABLED(X_IS_TMC2130) + _TMC2130_DEFINE(X); + #endif + #if ENABLED(X2_IS_TMC2130) + _TMC2130_DEFINE(X2); + #endif + #if ENABLED(Y_IS_TMC2130) + _TMC2130_DEFINE(Y); + #endif + #if ENABLED(Y2_IS_TMC2130) + _TMC2130_DEFINE(Y2); + #endif + #if ENABLED(Z_IS_TMC2130) + _TMC2130_DEFINE(Z); + #endif + #if ENABLED(Z2_IS_TMC2130) + _TMC2130_DEFINE(Z2); + #endif + #if ENABLED(E0_IS_TMC2130) + _TMC2130_DEFINE(E0); + #endif + #if ENABLED(E1_IS_TMC2130) + _TMC2130_DEFINE(E1); + #endif + #if ENABLED(E2_IS_TMC2130) + _TMC2130_DEFINE(E2); + #endif + #if ENABLED(E3_IS_TMC2130) + _TMC2130_DEFINE(E3); + #endif + #if ENABLED(E4_IS_TMC2130) + _TMC2130_DEFINE(E4); + #endif + + // Use internal reference voltage for current calculations. This is the default. + // Following values from Trinamic's spreadsheet with values for a NEMA17 (42BYGHW609) + // https://www.trinamic.com/products/integrated-circuits/details/tmc2130/ + void tmc2130_init(TMC2130Stepper &st, const uint16_t microsteps, const uint32_t thrs, const float &spmm) { + st.begin(); + st.setCurrent(st.getCurrent(), R_SENSE, HOLD_MULTIPLIER); + st.microsteps(microsteps); + st.blank_time(36); + st.off_time(5); // Only enables the driver if used with stealthChop + st.interpolate(INTERPOLATE); + st.power_down_delay(128); // ~2s until driver lowers to hold current + st.hysterisis_start(0); // HSTRT = 1 + st.hysterisis_low(1); // HEND = -2 + st.diag1_active_high(1); // For sensorless homing + #if ENABLED(STEALTHCHOP) + st.stealth_freq(1); // f_pwm = 2/683 f_clk + st.stealth_autoscale(1); + st.stealth_gradient(5); + st.stealth_amplitude(255); + st.stealthChop(1); + #if ENABLED(HYBRID_THRESHOLD) + st.stealth_max_speed(12650000UL*st.microsteps()/(256*thrs*spmm)); + #endif + #elif ENABLED(SENSORLESS_HOMING) + st.coolstep_min_speed(1024UL * 1024UL - 1UL); + #endif + } + + #define _TMC2130_INIT(ST, SPMM) tmc2130_init(stepper##ST, ST##_MICROSTEPS, ST##_HYBRID_THRESHOLD, SPMM) + + void tmc2130_init() { + constexpr float steps_per_mm[] = DEFAULT_AXIS_STEPS_PER_UNIT; + #if ENABLED(X_IS_TMC2130) + _TMC2130_INIT( X, steps_per_mm[X_AXIS]); + #if ENABLED(SENSORLESS_HOMING) + stepperX.sg_stall_value(X_HOMING_SENSITIVITY); + #endif + #endif + #if ENABLED(X2_IS_TMC2130) + _TMC2130_INIT(X2, steps_per_mm[X_AXIS]); + #endif + #if ENABLED(Y_IS_TMC2130) + _TMC2130_INIT( Y, steps_per_mm[Y_AXIS]); + #if ENABLED(SENSORLESS_HOMING) + stepperY.sg_stall_value(Y_HOMING_SENSITIVITY); + #endif + #endif + #if ENABLED(Y2_IS_TMC2130) + _TMC2130_INIT(Y2, steps_per_mm[Y_AXIS]); + #endif + #if ENABLED(Z_IS_TMC2130) + _TMC2130_INIT( Z, steps_per_mm[Z_AXIS]); + #endif + #if ENABLED(Z2_IS_TMC2130) + _TMC2130_INIT(Z2, steps_per_mm[Z_AXIS]); + #endif + #if ENABLED(E0_IS_TMC2130) + _TMC2130_INIT(E0, steps_per_mm[E_AXIS]); + #endif + #if ENABLED(E1_IS_TMC2130) + { constexpr int extruder = 1; _TMC2130_INIT(E1, steps_per_mm[E_AXIS_N]); } + #endif + #if ENABLED(E2_IS_TMC2130) + { constexpr int extruder = 2; _TMC2130_INIT(E2, steps_per_mm[E_AXIS_N]); } + #endif + #if ENABLED(E3_IS_TMC2130) + { constexpr int extruder = 3; _TMC2130_INIT(E3, steps_per_mm[E_AXIS_N]); } + #endif + #if ENABLED(E4_IS_TMC2130) + { constexpr int extruder = 4; _TMC2130_INIT(E4, steps_per_mm[E_AXIS_N]); } + #endif + + TMC2130_ADV() + } +#endif // HAVE_TMC2130 + + +// +// L6470 Driver objects and inits +// +#if ENABLED(HAVE_L6470DRIVER) + + #include + #include + + #define _L6470_DEFINE(ST) L6470 stepper##ST(ST##_ENABLE_PIN) + + // L6470 Stepper objects + #if ENABLED(X_IS_L6470) + _L6470_DEFINE(X); + #endif + #if ENABLED(X2_IS_L6470) + _L6470_DEFINE(X2); + #endif + #if ENABLED(Y_IS_L6470) + _L6470_DEFINE(Y); + #endif + #if ENABLED(Y2_IS_L6470) + _L6470_DEFINE(Y2); + #endif + #if ENABLED(Z_IS_L6470) + _L6470_DEFINE(Z); + #endif + #if ENABLED(Z2_IS_L6470) + _L6470_DEFINE(Z2); + #endif + #if ENABLED(E0_IS_L6470) + _L6470_DEFINE(E0); + #endif + #if ENABLED(E1_IS_L6470) + _L6470_DEFINE(E1); + #endif + #if ENABLED(E2_IS_L6470) + _L6470_DEFINE(E2); + #endif + #if ENABLED(E3_IS_L6470) + _L6470_DEFINE(E3); + #endif + #if ENABLED(E4_IS_L6470) + _L6470_DEFINE(E4); + #endif + + #define _L6470_INIT(A) do{ \ + stepper##A.init(A##_K_VAL); \ + stepper##A.softFree(); \ + stepper##A.setMicroSteps(A##_MICROSTEPS); \ + stepper##A.setOverCurrent(A##_OVERCURRENT); \ + stepper##A.setStallCurrent(A##_STALLCURRENT); \ + }while(0) + + void L6470_init() { + #if ENABLED(X_IS_L6470) + _L6470_INIT(X); + #endif + #if ENABLED(X2_IS_L6470) + _L6470_INIT(X2); + #endif + #if ENABLED(Y_IS_L6470) + _L6470_INIT(Y); + #endif + #if ENABLED(Y2_IS_L6470) + _L6470_INIT(Y2); + #endif + #if ENABLED(Z_IS_L6470) + _L6470_INIT(Z); + #endif + #if ENABLED(Z2_IS_L6470) + _L6470_INIT(Z2); + #endif + #if ENABLED(E0_IS_L6470) + _L6470_INIT(E0); + #endif + #if ENABLED(E1_IS_L6470) + _L6470_INIT(E1); + #endif + #if ENABLED(E2_IS_L6470) + _L6470_INIT(E2); + #endif + #if ENABLED(E3_IS_L6470) + _L6470_INIT(E3); + #endif + #if ENABLED(E4_IS_L6470) + _L6470_INIT(E4); + #endif + } + +#endif // HAVE_L6470DRIVER + diff --git a/trunk/Arduino/Marlin_1.1.6/stepper_indirection.h b/trunk/Arduino/Marlin_1.1.6/stepper_indirection.h new file mode 100644 index 00000000..8b862464 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/stepper_indirection.h @@ -0,0 +1,485 @@ +/** + * 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 . + * + */ + +/** + stepper_indirection.h - stepper motor driver indirection macros + to allow some stepper functions to be done via SPI/I2c instead of direct pin manipulation + Part of Marlin + + Copyright (c) 2015 Dominik Wenger + + Marlin is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Marlin is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Marlin. If not, see . +*/ + +#ifndef STEPPER_INDIRECTION_H +#define STEPPER_INDIRECTION_H + +#include "MarlinConfig.h" + +// TMC26X drivers have STEP/DIR on normal pins, but ENABLE via SPI +#if ENABLED(HAVE_TMCDRIVER) + #include + #include + void tmc_init(); +#endif + +#if ENABLED(HAVE_TMC2130) + #include + void tmc2130_init(); +#endif + +// L6470 has STEP on normal pins, but DIR/ENABLE via SPI +#if ENABLED(HAVE_L6470DRIVER) + #include + #include + void L6470_init(); +#endif + +// X Stepper +#if ENABLED(HAVE_L6470DRIVER) && ENABLED(X_IS_L6470) + extern L6470 stepperX; + #define X_ENABLE_INIT NOOP + #define X_ENABLE_WRITE(STATE) do{if(STATE) stepperX.Step_Clock(stepperX.getStatus() & STATUS_HIZ); else stepperX.softFree();}while(0) + #define X_ENABLE_READ (stepperX.getStatus() & STATUS_HIZ) + #define X_DIR_INIT NOOP + #define X_DIR_WRITE(STATE) stepperX.Step_Clock(STATE) + #define X_DIR_READ (stepperX.getStatus() & STATUS_DIR) +#else + #if ENABLED(HAVE_TMCDRIVER) && ENABLED(X_IS_TMC) + extern TMC26XStepper stepperX; + #define X_ENABLE_INIT NOOP + #define X_ENABLE_WRITE(STATE) stepperX.setEnabled(STATE) + #define X_ENABLE_READ stepperX.isEnabled() + #else + #if ENABLED(HAVE_TMC2130) && ENABLED(X_IS_TMC2130) + extern TMC2130Stepper stepperX; + #endif + #define X_ENABLE_INIT SET_OUTPUT(X_ENABLE_PIN) + #define X_ENABLE_WRITE(STATE) WRITE(X_ENABLE_PIN,STATE) + #define X_ENABLE_READ READ(X_ENABLE_PIN) + #endif + #define X_DIR_INIT SET_OUTPUT(X_DIR_PIN) + #define X_DIR_WRITE(STATE) WRITE(X_DIR_PIN,STATE) + #define X_DIR_READ READ(X_DIR_PIN) +#endif +#define X_STEP_INIT SET_OUTPUT(X_STEP_PIN) +#define X_STEP_WRITE(STATE) WRITE(X_STEP_PIN,STATE) +#define X_STEP_READ READ(X_STEP_PIN) + +// Y Stepper +#if ENABLED(HAVE_L6470DRIVER) && ENABLED(Y_IS_L6470) + extern L6470 stepperY; + #define Y_ENABLE_INIT NOOP + #define Y_ENABLE_WRITE(STATE) do{if(STATE) stepperY.Step_Clock(stepperY.getStatus() & STATUS_HIZ); else stepperY.softFree();}while(0) + #define Y_ENABLE_READ (stepperY.getStatus() & STATUS_HIZ) + #define Y_DIR_INIT NOOP + #define Y_DIR_WRITE(STATE) stepperY.Step_Clock(STATE) + #define Y_DIR_READ (stepperY.getStatus() & STATUS_DIR) +#else + #if ENABLED(HAVE_TMCDRIVER) && ENABLED(Y_IS_TMC) + extern TMC26XStepper stepperY; + #define Y_ENABLE_INIT NOOP + #define Y_ENABLE_WRITE(STATE) stepperY.setEnabled(STATE) + #define Y_ENABLE_READ stepperY.isEnabled() + #else + #if ENABLED(HAVE_TMC2130) && ENABLED(Y_IS_TMC2130) + extern TMC2130Stepper stepperY; + #endif + #define Y_ENABLE_INIT SET_OUTPUT(Y_ENABLE_PIN) + #define Y_ENABLE_WRITE(STATE) WRITE(Y_ENABLE_PIN,STATE) + #define Y_ENABLE_READ READ(Y_ENABLE_PIN) + #endif + #define Y_DIR_INIT SET_OUTPUT(Y_DIR_PIN) + #define Y_DIR_WRITE(STATE) WRITE(Y_DIR_PIN,STATE) + #define Y_DIR_READ READ(Y_DIR_PIN) +#endif +#define Y_STEP_INIT SET_OUTPUT(Y_STEP_PIN) +#define Y_STEP_WRITE(STATE) WRITE(Y_STEP_PIN,STATE) +#define Y_STEP_READ READ(Y_STEP_PIN) + +// Z Stepper +#if ENABLED(HAVE_L6470DRIVER) && ENABLED(Z_IS_L6470) + extern L6470 stepperZ; + #define Z_ENABLE_INIT NOOP + #define Z_ENABLE_WRITE(STATE) do{if(STATE) stepperZ.Step_Clock(stepperZ.getStatus() & STATUS_HIZ); else stepperZ.softFree();}while(0) + #define Z_ENABLE_READ (stepperZ.getStatus() & STATUS_HIZ) + #define Z_DIR_INIT NOOP + #define Z_DIR_WRITE(STATE) stepperZ.Step_Clock(STATE) + #define Z_DIR_READ (stepperZ.getStatus() & STATUS_DIR) +#else + #if ENABLED(HAVE_TMCDRIVER) && ENABLED(Z_IS_TMC) + extern TMC26XStepper stepperZ; + #define Z_ENABLE_INIT NOOP + #define Z_ENABLE_WRITE(STATE) stepperZ.setEnabled(STATE) + #define Z_ENABLE_READ stepperZ.isEnabled() + #else + #if ENABLED(HAVE_TMC2130) && ENABLED(Z_IS_TMC2130) + extern TMC2130Stepper stepperZ; + #endif + #define Z_ENABLE_INIT SET_OUTPUT(Z_ENABLE_PIN) + #define Z_ENABLE_WRITE(STATE) WRITE(Z_ENABLE_PIN,STATE) + #define Z_ENABLE_READ READ(Z_ENABLE_PIN) + #endif + #define Z_DIR_INIT SET_OUTPUT(Z_DIR_PIN) + #define Z_DIR_WRITE(STATE) WRITE(Z_DIR_PIN,STATE) + #define Z_DIR_READ READ(Z_DIR_PIN) +#endif +#define Z_STEP_INIT SET_OUTPUT(Z_STEP_PIN) +#define Z_STEP_WRITE(STATE) WRITE(Z_STEP_PIN,STATE) +#define Z_STEP_READ READ(Z_STEP_PIN) + +// X2 Stepper +#if HAS_X2_ENABLE + #if ENABLED(HAVE_L6470DRIVER) && ENABLED(X2_IS_L6470) + extern L6470 stepperX2; + #define X2_ENABLE_INIT NOOP + #define X2_ENABLE_WRITE(STATE) do{if(STATE) stepperX2.Step_Clock(stepperX2.getStatus() & STATUS_HIZ); else stepperX2.softFree();}while(0) + #define X2_ENABLE_READ (stepperX2.getStatus() & STATUS_HIZ) + #define X2_DIR_INIT NOOP + #define X2_DIR_WRITE(STATE) stepperX2.Step_Clock(STATE) + #define X2_DIR_READ (stepperX2.getStatus() & STATUS_DIR) + #else + #if ENABLED(HAVE_TMCDRIVER) && ENABLED(X2_IS_TMC) + extern TMC26XStepper stepperX2; + #define X2_ENABLE_INIT NOOP + #define X2_ENABLE_WRITE(STATE) stepperX2.setEnabled(STATE) + #define X2_ENABLE_READ stepperX2.isEnabled() + #else + #if ENABLED(HAVE_TMC2130) && ENABLED(X2_IS_TMC2130) + extern TMC2130Stepper stepperX2; + #endif + #define X2_ENABLE_INIT SET_OUTPUT(X2_ENABLE_PIN) + #define X2_ENABLE_WRITE(STATE) WRITE(X2_ENABLE_PIN,STATE) + #define X2_ENABLE_READ READ(X2_ENABLE_PIN) + #endif + #define X2_DIR_INIT SET_OUTPUT(X2_DIR_PIN) + #define X2_DIR_WRITE(STATE) WRITE(X2_DIR_PIN,STATE) + #define X2_DIR_READ READ(X2_DIR_PIN) + #endif + #define X2_STEP_INIT SET_OUTPUT(X2_STEP_PIN) + #define X2_STEP_WRITE(STATE) WRITE(X2_STEP_PIN,STATE) + #define X2_STEP_READ READ(X2_STEP_PIN) +#endif + +// Y2 Stepper +#if HAS_Y2_ENABLE + #if ENABLED(HAVE_L6470DRIVER) && ENABLED(Y2_IS_L6470) + extern L6470 stepperY2; + #define Y2_ENABLE_INIT NOOP + #define Y2_ENABLE_WRITE(STATE) do{if(STATE) stepperY2.Step_Clock(stepperY2.getStatus() & STATUS_HIZ); else stepperY2.softFree();}while(0) + #define Y2_ENABLE_READ (stepperY2.getStatus() & STATUS_HIZ) + #define Y2_DIR_INIT NOOP + #define Y2_DIR_WRITE(STATE) stepperY2.Step_Clock(STATE) + #define Y2_DIR_READ (stepperY2.getStatus() & STATUS_DIR) + #else + #if ENABLED(HAVE_TMCDRIVER) && ENABLED(Y2_IS_TMC) + extern TMC26XStepper stepperY2; + #define Y2_ENABLE_INIT NOOP + #define Y2_ENABLE_WRITE(STATE) stepperY2.setEnabled(STATE) + #define Y2_ENABLE_READ stepperY2.isEnabled() + #else + #if ENABLED(HAVE_TMC2130) && ENABLED(Y2_IS_TMC2130) + extern TMC2130Stepper stepperY2; + #endif + #define Y2_ENABLE_INIT SET_OUTPUT(Y2_ENABLE_PIN) + #define Y2_ENABLE_WRITE(STATE) WRITE(Y2_ENABLE_PIN,STATE) + #define Y2_ENABLE_READ READ(Y2_ENABLE_PIN) + #endif + #define Y2_DIR_INIT SET_OUTPUT(Y2_DIR_PIN) + #define Y2_DIR_WRITE(STATE) WRITE(Y2_DIR_PIN,STATE) + #define Y2_DIR_READ READ(Y2_DIR_PIN) + #endif + #define Y2_STEP_INIT SET_OUTPUT(Y2_STEP_PIN) + #define Y2_STEP_WRITE(STATE) WRITE(Y2_STEP_PIN,STATE) + #define Y2_STEP_READ READ(Y2_STEP_PIN) +#endif + +// Z2 Stepper +#if HAS_Z2_ENABLE + #if ENABLED(HAVE_L6470DRIVER) && ENABLED(Z2_IS_L6470) + extern L6470 stepperZ2; + #define Z2_ENABLE_INIT NOOP + #define Z2_ENABLE_WRITE(STATE) do{if(STATE) stepperZ2.Step_Clock(stepperZ2.getStatus() & STATUS_HIZ); else stepperZ2.softFree();}while(0) + #define Z2_ENABLE_READ (stepperZ2.getStatus() & STATUS_HIZ) + #define Z2_DIR_INIT NOOP + #define Z2_DIR_WRITE(STATE) stepperZ2.Step_Clock(STATE) + #define Z2_DIR_READ (stepperZ2.getStatus() & STATUS_DIR) + #else + #if ENABLED(HAVE_TMCDRIVER) && ENABLED(Z2_IS_TMC) + extern TMC26XStepper stepperZ2; + #define Z2_ENABLE_INIT NOOP + #define Z2_ENABLE_WRITE(STATE) stepperZ2.setEnabled(STATE) + #define Z2_ENABLE_READ stepperZ2.isEnabled() + #else + #if ENABLED(HAVE_TMC2130) && ENABLED(Z2_IS_TMC2130) + extern TMC2130Stepper stepperZ2; + #endif + #define Z2_ENABLE_INIT SET_OUTPUT(Z2_ENABLE_PIN) + #define Z2_ENABLE_WRITE(STATE) WRITE(Z2_ENABLE_PIN,STATE) + #define Z2_ENABLE_READ READ(Z2_ENABLE_PIN) + #endif + #define Z2_DIR_INIT SET_OUTPUT(Z2_DIR_PIN) + #define Z2_DIR_WRITE(STATE) WRITE(Z2_DIR_PIN,STATE) + #define Z2_DIR_READ READ(Z2_DIR_PIN) + #endif + #define Z2_STEP_INIT SET_OUTPUT(Z2_STEP_PIN) + #define Z2_STEP_WRITE(STATE) WRITE(Z2_STEP_PIN,STATE) + #define Z2_STEP_READ READ(Z2_STEP_PIN) +#endif + +// E0 Stepper +#if ENABLED(HAVE_L6470DRIVER) && ENABLED(E0_IS_L6470) + extern L6470 stepperE0; + #define E0_ENABLE_INIT NOOP + #define E0_ENABLE_WRITE(STATE) do{if(STATE) stepperE0.Step_Clock(stepperE0.getStatus() & STATUS_HIZ); else stepperE0.softFree();}while(0) + #define E0_ENABLE_READ (stepperE0.getStatus() & STATUS_HIZ) + #define E0_DIR_INIT NOOP + #define E0_DIR_WRITE(STATE) stepperE0.Step_Clock(STATE) + #define E0_DIR_READ (stepperE0.getStatus() & STATUS_DIR) +#else + #if ENABLED(HAVE_TMCDRIVER) && ENABLED(E0_IS_TMC) + extern TMC26XStepper stepperE0; + #define E0_ENABLE_INIT NOOP + #define E0_ENABLE_WRITE(STATE) stepperE0.setEnabled(STATE) + #define E0_ENABLE_READ stepperE0.isEnabled() + #else + #if ENABLED(HAVE_TMC2130) && ENABLED(E0_IS_TMC2130) + extern TMC2130Stepper stepperE0; + #endif + #define E0_ENABLE_INIT SET_OUTPUT(E0_ENABLE_PIN) + #define E0_ENABLE_WRITE(STATE) WRITE(E0_ENABLE_PIN,STATE) + #define E0_ENABLE_READ READ(E0_ENABLE_PIN) + #endif + #define E0_DIR_INIT SET_OUTPUT(E0_DIR_PIN) + #define E0_DIR_WRITE(STATE) WRITE(E0_DIR_PIN,STATE) + #define E0_DIR_READ READ(E0_DIR_PIN) +#endif +#define E0_STEP_INIT SET_OUTPUT(E0_STEP_PIN) +#define E0_STEP_WRITE(STATE) WRITE(E0_STEP_PIN,STATE) +#define E0_STEP_READ READ(E0_STEP_PIN) + +// E1 Stepper +#if ENABLED(HAVE_L6470DRIVER) && ENABLED(E1_IS_L6470) + extern L6470 stepperE1; + #define E1_ENABLE_INIT NOOP + #define E1_ENABLE_WRITE(STATE) do{if(STATE) stepperE1.Step_Clock(stepperE1.getStatus() & STATUS_HIZ); else stepperE1.softFree();}while(0) + #define E1_ENABLE_READ (stepperE1.getStatus() & STATUS_HIZ) + #define E1_DIR_INIT NOOP + #define E1_DIR_WRITE(STATE) stepperE1.Step_Clock(STATE) + #define E1_DIR_READ (stepperE1.getStatus() & STATUS_DIR) +#else + #if ENABLED(HAVE_TMCDRIVER) && ENABLED(E1_IS_TMC) + extern TMC26XStepper stepperE1; + #define E1_ENABLE_INIT NOOP + #define E1_ENABLE_WRITE(STATE) stepperE1.setEnabled(STATE) + #define E1_ENABLE_READ stepperE1.isEnabled() + #else + #if ENABLED(HAVE_TMC2130) && ENABLED(E1_IS_TMC2130) + extern TMC2130Stepper stepperE1; + #endif + #define E1_ENABLE_INIT SET_OUTPUT(E1_ENABLE_PIN) + #define E1_ENABLE_WRITE(STATE) WRITE(E1_ENABLE_PIN,STATE) + #define E1_ENABLE_READ READ(E1_ENABLE_PIN) + #endif + #define E1_DIR_INIT SET_OUTPUT(E1_DIR_PIN) + #define E1_DIR_WRITE(STATE) WRITE(E1_DIR_PIN,STATE) + #define E1_DIR_READ READ(E1_DIR_PIN) +#endif +#define E1_STEP_INIT SET_OUTPUT(E1_STEP_PIN) +#define E1_STEP_WRITE(STATE) WRITE(E1_STEP_PIN,STATE) +#define E1_STEP_READ READ(E1_STEP_PIN) + +// E2 Stepper +#if ENABLED(HAVE_L6470DRIVER) && ENABLED(E2_IS_L6470) + extern L6470 stepperE2; + #define E2_ENABLE_INIT NOOP + #define E2_ENABLE_WRITE(STATE) do{if(STATE) stepperE2.Step_Clock(stepperE2.getStatus() & STATUS_HIZ); else stepperE2.softFree();}while(0) + #define E2_ENABLE_READ (stepperE2.getStatus() & STATUS_HIZ) + #define E2_DIR_INIT NOOP + #define E2_DIR_WRITE(STATE) stepperE2.Step_Clock(STATE) + #define E2_DIR_READ (stepperE2.getStatus() & STATUS_DIR) +#else + #if ENABLED(HAVE_TMCDRIVER) && ENABLED(E2_IS_TMC) + extern TMC26XStepper stepperE2; + #define E2_ENABLE_INIT NOOP + #define E2_ENABLE_WRITE(STATE) stepperE2.setEnabled(STATE) + #define E2_ENABLE_READ stepperE2.isEnabled() + #else + #if ENABLED(HAVE_TMC2130) && ENABLED(E2_IS_TMC2130) + extern TMC2130Stepper stepperE2; + #endif + #define E2_ENABLE_INIT SET_OUTPUT(E2_ENABLE_PIN) + #define E2_ENABLE_WRITE(STATE) WRITE(E2_ENABLE_PIN,STATE) + #define E2_ENABLE_READ READ(E2_ENABLE_PIN) + #endif + #define E2_DIR_INIT SET_OUTPUT(E2_DIR_PIN) + #define E2_DIR_WRITE(STATE) WRITE(E2_DIR_PIN,STATE) + #define E2_DIR_READ READ(E2_DIR_PIN) +#endif +#define E2_STEP_INIT SET_OUTPUT(E2_STEP_PIN) +#define E2_STEP_WRITE(STATE) WRITE(E2_STEP_PIN,STATE) +#define E2_STEP_READ READ(E2_STEP_PIN) + +// E3 Stepper +#if ENABLED(HAVE_L6470DRIVER) && ENABLED(E3_IS_L6470) + extern L6470 stepperE3; + #define E3_ENABLE_INIT NOOP + #define E3_ENABLE_WRITE(STATE) do{if(STATE) stepperE3.Step_Clock(stepperE3.getStatus() & STATUS_HIZ); else stepperE3.softFree();}while(0) + #define E3_ENABLE_READ (stepperE3.getStatus() & STATUS_HIZ) + #define E3_DIR_INIT NOOP + #define E3_DIR_WRITE(STATE) stepperE3.Step_Clock(STATE) + #define E3_DIR_READ (stepperE3.getStatus() & STATUS_DIR) +#else + #if ENABLED(HAVE_TMCDRIVER) && ENABLED(E3_IS_TMC) + extern TMC26XStepper stepperE3; + #define E3_ENABLE_INIT NOOP + #define E3_ENABLE_WRITE(STATE) stepperE3.setEnabled(STATE) + #define E3_ENABLE_READ stepperE3.isEnabled() + #else + #if ENABLED(HAVE_TMC2130) && ENABLED(E3_IS_TMC2130) + extern TMC2130Stepper stepperE3; + #endif + #define E3_ENABLE_INIT SET_OUTPUT(E3_ENABLE_PIN) + #define E3_ENABLE_WRITE(STATE) WRITE(E3_ENABLE_PIN,STATE) + #define E3_ENABLE_READ READ(E3_ENABLE_PIN) + #endif + #define E3_DIR_INIT SET_OUTPUT(E3_DIR_PIN) + #define E3_DIR_WRITE(STATE) WRITE(E3_DIR_PIN,STATE) + #define E3_DIR_READ READ(E3_DIR_PIN) +#endif +#define E3_STEP_INIT SET_OUTPUT(E3_STEP_PIN) +#define E3_STEP_WRITE(STATE) WRITE(E3_STEP_PIN,STATE) +#define E3_STEP_READ READ(E3_STEP_PIN) + +// E4 Stepper +#if ENABLED(HAVE_L6470DRIVER) && ENABLED(E4_IS_L6470) + extern L6470 stepperE4; + #define E4_ENABLE_INIT NOOP + #define E4_ENABLE_WRITE(STATE) do{ if (STATE) stepperE4.Step_Clock(stepperE4.getStatus() & STATUS_HIZ); else stepperE4.softFree(); }while(0) + #define E4_ENABLE_READ (stepperE4.getStatus() & STATUS_HIZ) + #define E4_DIR_INIT NOOP + #define E4_DIR_WRITE(STATE) stepperE4.Step_Clock(STATE) + #define E4_DIR_READ (stepperE4.getStatus() & STATUS_DIR) +#else + #if ENABLED(HAVE_TMCDRIVER) && ENABLED(E4_IS_TMC) + extern TMC26XStepper stepperE4; + #define E4_ENABLE_INIT NOOP + #define E4_ENABLE_WRITE(STATE) stepperE4.setEnabled(STATE) + #define E4_ENABLE_READ stepperE4.isEnabled() + #else + #if ENABLED(HAVE_TMC2130) && ENABLED(E4_IS_TMC2130) + extern TMC2130Stepper stepperE4; + #endif + #define E4_ENABLE_INIT SET_OUTPUT(E4_ENABLE_PIN) + #define E4_ENABLE_WRITE(STATE) WRITE(E4_ENABLE_PIN,STATE) + #define E4_ENABLE_READ READ(E4_ENABLE_PIN) + #endif + #define E4_DIR_INIT SET_OUTPUT(E4_DIR_PIN) + #define E4_DIR_WRITE(STATE) WRITE(E4_DIR_PIN,STATE) + #define E4_DIR_READ READ(E4_DIR_PIN) +#endif +#define E4_STEP_INIT SET_OUTPUT(E4_STEP_PIN) +#define E4_STEP_WRITE(STATE) WRITE(E4_STEP_PIN,STATE) +#define E4_STEP_READ READ(E4_STEP_PIN) + +/** + * Extruder indirection for the single E axis + */ +#if ENABLED(SWITCHING_EXTRUDER) + #if EXTRUDERS == 2 + #define E_STEP_WRITE(v) E0_STEP_WRITE(v) + #define NORM_E_DIR() E0_DIR_WRITE(current_block->active_extruder ? INVERT_E0_DIR : !INVERT_E0_DIR) + #define REV_E_DIR() E0_DIR_WRITE(current_block->active_extruder ? !INVERT_E0_DIR : INVERT_E0_DIR) + #elif EXTRUDERS > 4 + #define E_STEP_WRITE(v) { if (current_block->active_extruder < 2) E0_STEP_WRITE(v); else if (current_block->active_extruder < 4) E1_STEP_WRITE(v); else E2_STEP_WRITE(v); } + #define NORM_E_DIR() { switch (current_block->active_extruder) { case 0: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 1: E0_DIR_WRITE(INVERT_E0_DIR); break; case 2: E1_DIR_WRITE(!INVERT_E1_DIR); break; case 3: E1_DIR_WRITE(INVERT_E1_DIR); break; case 4: E2_DIR_WRITE(!INVERT_E2_DIR); } } + #define REV_E_DIR() { switch (current_block->active_extruder) { case 0: E0_DIR_WRITE(INVERT_E0_DIR); break; case 1: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 2: E1_DIR_WRITE(INVERT_E1_DIR); break; case 3: E1_DIR_WRITE(!INVERT_E1_DIR); break; case 4: E2_DIR_WRITE(INVERT_E2_DIR); } } + #elif EXTRUDERS > 2 + #define E_STEP_WRITE(v) { if (current_block->active_extruder < 2) E0_STEP_WRITE(v); else if (current_block->active_extruder < 4) E1_STEP_WRITE(v); else E1_STEP_WRITE(v); } + #define NORM_E_DIR() { switch (current_block->active_extruder) { case 0: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 1: E0_DIR_WRITE(INVERT_E0_DIR); break; case 2: E1_DIR_WRITE(!INVERT_E1_DIR); break; case 3: E1_DIR_WRITE(INVERT_E1_DIR); } } + #define REV_E_DIR() { switch (current_block->active_extruder) { case 0: E0_DIR_WRITE(INVERT_E0_DIR); break; case 1: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 2: E1_DIR_WRITE(INVERT_E1_DIR); break; case 3: E1_DIR_WRITE(!INVERT_E1_DIR); } } + #endif +#elif EXTRUDERS > 4 + #define E_STEP_WRITE(v) { switch (current_block->active_extruder) { case 0: E0_STEP_WRITE(v); break; case 1: E1_STEP_WRITE(v); break; case 2: E2_STEP_WRITE(v); break; case 3: E3_STEP_WRITE(v); break; case 4: E4_STEP_WRITE(v); } } + #define NORM_E_DIR() { switch (current_block->active_extruder) { case 0: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 1: E1_DIR_WRITE(!INVERT_E1_DIR); break; case 2: E2_DIR_WRITE(!INVERT_E2_DIR); break; case 3: E3_DIR_WRITE(!INVERT_E3_DIR); break; case 4: E4_DIR_WRITE(!INVERT_E4_DIR); } } + #define REV_E_DIR() { switch (current_block->active_extruder) { case 0: E0_DIR_WRITE(INVERT_E0_DIR); break; case 1: E1_DIR_WRITE(INVERT_E1_DIR); break; case 2: E2_DIR_WRITE(INVERT_E2_DIR); break; case 3: E3_DIR_WRITE(INVERT_E3_DIR); break; case 4: E4_DIR_WRITE(INVERT_E4_DIR); } } +#elif EXTRUDERS > 3 + #define E_STEP_WRITE(v) { switch (current_block->active_extruder) { case 0: E0_STEP_WRITE(v); break; case 1: E1_STEP_WRITE(v); break; case 2: E2_STEP_WRITE(v); break; case 3: E3_STEP_WRITE(v); } } + #define NORM_E_DIR() { switch (current_block->active_extruder) { case 0: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 1: E1_DIR_WRITE(!INVERT_E1_DIR); break; case 2: E2_DIR_WRITE(!INVERT_E2_DIR); break; case 3: E3_DIR_WRITE(!INVERT_E3_DIR); } } + #define REV_E_DIR() { switch (current_block->active_extruder) { case 0: E0_DIR_WRITE(INVERT_E0_DIR); break; case 1: E1_DIR_WRITE(INVERT_E1_DIR); break; case 2: E2_DIR_WRITE(INVERT_E2_DIR); break; case 3: E3_DIR_WRITE(INVERT_E3_DIR); } } +#elif EXTRUDERS > 2 + #define E_STEP_WRITE(v) { switch (current_block->active_extruder) { case 0: E0_STEP_WRITE(v); break; case 1: E1_STEP_WRITE(v); break; case 2: E2_STEP_WRITE(v); } } + #define NORM_E_DIR() { switch (current_block->active_extruder) { case 0: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 1: E1_DIR_WRITE(!INVERT_E1_DIR); break; case 2: E2_DIR_WRITE(!INVERT_E2_DIR); } } + #define REV_E_DIR() { switch (current_block->active_extruder) { case 0: E0_DIR_WRITE(INVERT_E0_DIR); break; case 1: E1_DIR_WRITE(INVERT_E1_DIR); break; case 2: E2_DIR_WRITE(INVERT_E2_DIR); } } +#elif EXTRUDERS > 1 + #if ENABLED(DUAL_X_CARRIAGE) || ENABLED(DUAL_NOZZLE_DUPLICATION_MODE) + #define E_STEP_WRITE(v) { if (extruder_duplication_enabled) { E0_STEP_WRITE(v); E1_STEP_WRITE(v); } else if (current_block->active_extruder == 0) { E0_STEP_WRITE(v); } else { E1_STEP_WRITE(v); } } + #define NORM_E_DIR() { if (extruder_duplication_enabled) { E0_DIR_WRITE(!INVERT_E0_DIR); E1_DIR_WRITE(!INVERT_E1_DIR); } else if (current_block->active_extruder == 0) { E0_DIR_WRITE(!INVERT_E0_DIR); } else { E1_DIR_WRITE(!INVERT_E1_DIR); } } + #define REV_E_DIR() { if (extruder_duplication_enabled) { E0_DIR_WRITE(INVERT_E0_DIR); E1_DIR_WRITE(INVERT_E1_DIR); } else if (current_block->active_extruder == 0) { E0_DIR_WRITE(INVERT_E0_DIR); } else { E1_DIR_WRITE(INVERT_E1_DIR); } } + #else + #define E_STEP_WRITE(v) { if (current_block->active_extruder == 0) { E0_STEP_WRITE(v); } else { E1_STEP_WRITE(v); } } + #define NORM_E_DIR() { if (current_block->active_extruder == 0) { E0_DIR_WRITE(!INVERT_E0_DIR); } else { E1_DIR_WRITE(!INVERT_E1_DIR); } } + #define REV_E_DIR() { if (current_block->active_extruder == 0) { E0_DIR_WRITE(INVERT_E0_DIR); } else { E1_DIR_WRITE(INVERT_E1_DIR); } } + #endif +#elif ENABLED(MIXING_EXTRUDER) + #define E_STEP_WRITE(v) NOOP /* not used for mixing extruders! */ + #if MIXING_STEPPERS > 4 + #define En_STEP_WRITE(n,v) { switch (n) { case 0: E0_STEP_WRITE(v); break; case 1: E1_STEP_WRITE(v); break; case 2: E2_STEP_WRITE(v); break; case 3: E3_STEP_WRITE(v); break; case 4: E4_STEP_WRITE(v); } } + #define NORM_E_DIR() { E0_DIR_WRITE(!INVERT_E0_DIR); E1_DIR_WRITE(!INVERT_E1_DIR); E2_DIR_WRITE(!INVERT_E2_DIR); E3_DIR_WRITE(!INVERT_E3_DIR); E4_DIR_WRITE(!INVERT_E4_DIR); } + #define REV_E_DIR() { E0_DIR_WRITE( INVERT_E0_DIR); E1_DIR_WRITE( INVERT_E1_DIR); E2_DIR_WRITE( INVERT_E2_DIR); E3_DIR_WRITE( INVERT_E3_DIR); E4_DIR_WRITE( INVERT_E4_DIR); } + #elif MIXING_STEPPERS > 3 + #define En_STEP_WRITE(n,v) { switch (n) { case 0: E0_STEP_WRITE(v); break; case 1: E1_STEP_WRITE(v); break; case 2: E2_STEP_WRITE(v); break; case 3: E3_STEP_WRITE(v); } } + #define NORM_E_DIR() { E0_DIR_WRITE(!INVERT_E0_DIR); E1_DIR_WRITE(!INVERT_E1_DIR); E2_DIR_WRITE(!INVERT_E2_DIR); E3_DIR_WRITE(!INVERT_E3_DIR); } + #define REV_E_DIR() { E0_DIR_WRITE( INVERT_E0_DIR); E1_DIR_WRITE( INVERT_E1_DIR); E2_DIR_WRITE( INVERT_E2_DIR); E3_DIR_WRITE( INVERT_E3_DIR); } + #elif MIXING_STEPPERS > 2 + #define En_STEP_WRITE(n,v) { switch (n) { case 0: E0_STEP_WRITE(v); break; case 1: E1_STEP_WRITE(v); break; case 2: E2_STEP_WRITE(v); } } + #define NORM_E_DIR() { E0_DIR_WRITE(!INVERT_E0_DIR); E1_DIR_WRITE(!INVERT_E1_DIR); E2_DIR_WRITE(!INVERT_E2_DIR); } + #define REV_E_DIR() { E0_DIR_WRITE( INVERT_E0_DIR); E1_DIR_WRITE( INVERT_E1_DIR); E2_DIR_WRITE( INVERT_E2_DIR); } + #else + #define En_STEP_WRITE(n,v) { switch (n) { case 0: E0_STEP_WRITE(v); break; case 1: E1_STEP_WRITE(v); } } + #define NORM_E_DIR() { E0_DIR_WRITE(!INVERT_E0_DIR); E1_DIR_WRITE(!INVERT_E1_DIR); } + #define REV_E_DIR() { E0_DIR_WRITE( INVERT_E0_DIR); E1_DIR_WRITE( INVERT_E1_DIR); } + #endif +#else + #define E_STEP_WRITE(v) E0_STEP_WRITE(v) + #if ENABLED(MK2_MULTIPLEXER) + // Even-numbered steppers are reversed + #define NORM_E_DIR() E0_DIR_WRITE(TEST(current_block->active_extruder, 0) ? !INVERT_E0_DIR: INVERT_E0_DIR) + #define REV_E_DIR() E0_DIR_WRITE(TEST(current_block->active_extruder, 0) ? INVERT_E0_DIR: !INVERT_E0_DIR) + #else + #define NORM_E_DIR() E0_DIR_WRITE(!INVERT_E0_DIR) + #define REV_E_DIR() E0_DIR_WRITE(INVERT_E0_DIR) + #endif +#endif + +#endif // STEPPER_INDIRECTION_H diff --git a/trunk/Arduino/Marlin_1.1.6/stopwatch.cpp b/trunk/Arduino/Marlin_1.1.6/stopwatch.cpp new file mode 100644 index 00000000..5958000f --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/stopwatch.cpp @@ -0,0 +1,106 @@ +/** + * 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 . + * + */ + +#include "Marlin.h" +#include "stopwatch.h" + +Stopwatch::Stopwatch() { + this->reset(); +} + +bool Stopwatch::stop() { + #if ENABLED(DEBUG_STOPWATCH) + Stopwatch::debug(PSTR("stop")); + #endif + + if (this->isRunning() || this->isPaused()) { + this->state = STOPPED; + this->stopTimestamp = millis(); + return true; + } + else return false; +} + +bool Stopwatch::pause() { + #if ENABLED(DEBUG_STOPWATCH) + Stopwatch::debug(PSTR("pause")); + #endif + + if (this->isRunning()) { + this->state = PAUSED; + this->stopTimestamp = millis(); + return true; + } + else return false; +} + +bool Stopwatch::start() { + #if ENABLED(DEBUG_STOPWATCH) + Stopwatch::debug(PSTR("start")); + #endif + + if (!this->isRunning()) { + if (this->isPaused()) this->accumulator = this->duration(); + else this->reset(); + + this->state = RUNNING; + this->startTimestamp = millis(); + return true; + } + else return false; +} + +void Stopwatch::reset() { + #if ENABLED(DEBUG_STOPWATCH) + Stopwatch::debug(PSTR("reset")); + #endif + + this->state = STOPPED; + this->startTimestamp = 0; + this->stopTimestamp = 0; + this->accumulator = 0; +} + +bool Stopwatch::isRunning() { + return (this->state == RUNNING) ? true : false; +} + +bool Stopwatch::isPaused() { + return (this->state == PAUSED) ? true : false; +} + +millis_t Stopwatch::duration() { + return (((this->isRunning()) ? millis() : this->stopTimestamp) + - this->startTimestamp) / 1000UL + this->accumulator; +} + +#if ENABLED(DEBUG_STOPWATCH) + + void Stopwatch::debug(const char func[]) { + if (DEBUGGING(INFO)) { + SERIAL_ECHOPGM("Stopwatch::"); + serialprintPGM(func); + SERIAL_ECHOLNPGM("()"); + } + } + +#endif diff --git a/trunk/Arduino/Marlin_1.1.6/stopwatch.h b/trunk/Arduino/Marlin_1.1.6/stopwatch.h new file mode 100644 index 00000000..ae3c998f --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/stopwatch.h @@ -0,0 +1,117 @@ +/** + * 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 . + * + */ + +#ifndef STOPWATCH_H +#define STOPWATCH_H + +#include "macros.h" + +// Print debug messages with M111 S2 (Uses 156 bytes of PROGMEM) +//#define DEBUG_STOPWATCH + +/** + * @brief Stopwatch class + * @details This class acts as a timer proving stopwatch functionality including + * the ability to pause the running time counter. + */ +class Stopwatch { + private: + enum State { + STOPPED, + RUNNING, + PAUSED + }; + + Stopwatch::State state; + millis_t accumulator; + millis_t startTimestamp; + millis_t stopTimestamp; + + public: + /** + * @brief Class constructor + */ + Stopwatch(); + + /** + * @brief Stops the stopwatch + * @details Stops the running timer, it will silently ignore the request if + * no timer is currently running. + * @return true is method was successful + */ + bool stop(); + + /** + * @brief Pause the stopwatch + * @details Pauses the running timer, it will silently ignore the request if + * no timer is currently running. + * @return true is method was successful + */ + bool pause(); + + /** + * @brief Starts the stopwatch + * @details Starts the timer, it will silently ignore the request if the + * timer is already running. + * @return true is method was successful + */ + bool start(); + + /** + * @brief Resets the stopwatch + * @details Resets all settings to their default values. + */ + void reset(); + + /** + * @brief Checks if the timer is running + * @details Returns true if the timer is currently running, false otherwise. + * @return true if stopwatch is running + */ + bool isRunning(); + + /** + * @brief Checks if the timer is paused + * @details Returns true if the timer is currently paused, false otherwise. + * @return true if stopwatch is paused + */ + bool isPaused(); + + /** + * @brief Gets the running time + * @details Returns the total number of seconds the timer has been running. + * @return the delta since starting the stopwatch + */ + millis_t duration(); + + #if ENABLED(DEBUG_STOPWATCH) + + /** + * @brief Prints a debug message + * @details Prints a simple debug message "Stopwatch::function" + */ + static void debug(const char func[]); + + #endif +}; + +#endif // STOPWATCH_H diff --git a/trunk/Arduino/Marlin_1.1.6/temperature.cpp b/trunk/Arduino/Marlin_1.1.6/temperature.cpp new file mode 100644 index 00000000..e2ea5378 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/temperature.cpp @@ -0,0 +1,2133 @@ +/** + * 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 . + * + */ + +/** + * temperature.cpp - temperature control + */ + +#include "Marlin.h" +#include "temperature.h" +#include "thermistortables.h" +#include "ultralcd.h" +#include "planner.h" +#include "language.h" + +#if ENABLED(HEATER_0_USES_MAX6675) + #include "spi.h" +#endif + +#if ENABLED(BABYSTEPPING) + #include "stepper.h" +#endif + +#if ENABLED(ENDSTOP_INTERRUPTS_FEATURE) + #include "endstops.h" +#endif + +#if ENABLED(USE_WATCHDOG) + #include "watchdog.h" +#endif + +#ifdef K1 // Defined in Configuration.h in the PID settings + #define K2 (1.0-K1) +#endif + +#if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT) + static void* heater_ttbl_map[2] = { (void*)HEATER_0_TEMPTABLE, (void*)HEATER_1_TEMPTABLE }; + static 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); + static 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); +#endif + +Temperature thermalManager; + +// public: + +float Temperature::current_temperature[HOTENDS] = { 0.0 }, + Temperature::current_temperature_bed = 0.0; +int16_t Temperature::current_temperature_raw[HOTENDS] = { 0 }, + Temperature::target_temperature[HOTENDS] = { 0 }, + Temperature::current_temperature_bed_raw = 0; + +#if HAS_HEATER_BED + int16_t Temperature::target_temperature_bed = 0; +#endif + +// Initialized by settings.load() +#if ENABLED(PIDTEMP) + #if ENABLED(PID_PARAMS_PER_HOTEND) && HOTENDS > 1 + float Temperature::Kp[HOTENDS], Temperature::Ki[HOTENDS], Temperature::Kd[HOTENDS]; + #if ENABLED(PID_EXTRUSION_SCALING) + float Temperature::Kc[HOTENDS]; + #endif + #else + float Temperature::Kp, Temperature::Ki, Temperature::Kd; + #if ENABLED(PID_EXTRUSION_SCALING) + float Temperature::Kc; + #endif + #endif +#endif + +// Initialized by settings.load() +#if ENABLED(PIDTEMPBED) + float Temperature::bedKp, Temperature::bedKi, Temperature::bedKd; +#endif + +#if ENABLED(BABYSTEPPING) + volatile int Temperature::babystepsTodo[XYZ] = { 0 }; +#endif + +#if WATCH_HOTENDS + uint16_t Temperature::watch_target_temp[HOTENDS] = { 0 }; + millis_t Temperature::watch_heater_next_ms[HOTENDS] = { 0 }; +#endif + +#if WATCH_THE_BED + uint16_t Temperature::watch_target_bed_temp = 0; + millis_t Temperature::watch_bed_next_ms = 0; +#endif + +#if ENABLED(PREVENT_COLD_EXTRUSION) + bool Temperature::allow_cold_extrude = false; + int16_t Temperature::extrude_min_temp = EXTRUDE_MINTEMP; +#endif + +// private: + +#if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT) + uint16_t Temperature::redundant_temperature_raw = 0; + float Temperature::redundant_temperature = 0.0; +#endif + +volatile bool Temperature::temp_meas_ready = false; + +#if ENABLED(PIDTEMP) + float Temperature::temp_iState[HOTENDS] = { 0 }, + Temperature::temp_dState[HOTENDS] = { 0 }, + Temperature::pTerm[HOTENDS], + Temperature::iTerm[HOTENDS], + Temperature::dTerm[HOTENDS]; + + #if ENABLED(PID_EXTRUSION_SCALING) + float Temperature::cTerm[HOTENDS]; + long Temperature::last_e_position; + long Temperature::lpq[LPQ_MAX_LEN]; + int Temperature::lpq_ptr = 0; + #endif + + float Temperature::pid_error[HOTENDS]; + bool Temperature::pid_reset[HOTENDS]; +#endif + +#if ENABLED(PIDTEMPBED) + float Temperature::temp_iState_bed = { 0 }, + Temperature::temp_dState_bed = { 0 }, + Temperature::pTerm_bed, + Temperature::iTerm_bed, + Temperature::dTerm_bed, + Temperature::pid_error_bed; +#else + millis_t Temperature::next_bed_check_ms; +#endif + +uint16_t Temperature::raw_temp_value[MAX_EXTRUDERS] = { 0 }, + Temperature::raw_temp_bed_value = 0; + +// Init min and max temp with extreme values to prevent false errors during startup +int16_t Temperature::minttemp_raw[HOTENDS] = ARRAY_BY_HOTENDS(HEATER_0_RAW_LO_TEMP , HEATER_1_RAW_LO_TEMP , HEATER_2_RAW_LO_TEMP, HEATER_3_RAW_LO_TEMP, HEATER_4_RAW_LO_TEMP), + Temperature::maxttemp_raw[HOTENDS] = ARRAY_BY_HOTENDS(HEATER_0_RAW_HI_TEMP , HEATER_1_RAW_HI_TEMP , HEATER_2_RAW_HI_TEMP, HEATER_3_RAW_HI_TEMP, HEATER_4_RAW_HI_TEMP), + Temperature::minttemp[HOTENDS] = { 0 }, + Temperature::maxttemp[HOTENDS] = ARRAY_BY_HOTENDS1(16383); + +#ifdef MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED + uint8_t Temperature::consecutive_low_temperature_error[HOTENDS] = { 0 }; +#endif + +#ifdef MILLISECONDS_PREHEAT_TIME + millis_t Temperature::preheat_end_time[HOTENDS] = { 0 }; +#endif + +#ifdef BED_MINTEMP + int16_t Temperature::bed_minttemp_raw = HEATER_BED_RAW_LO_TEMP; +#endif + +#ifdef BED_MAXTEMP + int16_t Temperature::bed_maxttemp_raw = HEATER_BED_RAW_HI_TEMP; +#endif + +#if ENABLED(FILAMENT_WIDTH_SENSOR) + int8_t Temperature::meas_shift_index; // Index of a delayed sample in buffer +#endif + +#if HAS_AUTO_FAN + millis_t Temperature::next_auto_fan_check_ms = 0; +#endif + +uint8_t Temperature::soft_pwm_amount[HOTENDS], + Temperature::soft_pwm_amount_bed; + +#if ENABLED(FAN_SOFT_PWM) + uint8_t Temperature::soft_pwm_amount_fan[FAN_COUNT], + Temperature::soft_pwm_count_fan[FAN_COUNT]; +#endif + +#if ENABLED(FILAMENT_WIDTH_SENSOR) + uint16_t Temperature::current_raw_filwidth = 0; // Measured filament diameter - one extruder only +#endif + +#if ENABLED(PROBING_HEATERS_OFF) + bool Temperature::paused; +#endif + +#if HEATER_IDLE_HANDLER + millis_t Temperature::heater_idle_timeout_ms[HOTENDS] = { 0 }; + bool Temperature::heater_idle_timeout_exceeded[HOTENDS] = { false }; + #if HAS_TEMP_BED + millis_t Temperature::bed_idle_timeout_ms = 0; + bool Temperature::bed_idle_timeout_exceeded = false; + #endif +#endif + +#if ENABLED(ADC_KEYPAD) + uint32_t Temperature::current_ADCKey_raw = 0; + uint8_t Temperature::ADCKey_count = 0; +#endif + +#if HAS_PID_HEATING + + void Temperature::PID_autotune(float temp, int hotend, int ncycles, bool set_result/*=false*/) { + float input = 0.0; + int cycles = 0; + bool heating = true; + + millis_t temp_ms = millis(), t1 = temp_ms, t2 = temp_ms; + long t_high = 0, t_low = 0; + + long bias, d; + float Ku, Tu; + float workKp = 0, workKi = 0, workKd = 0; + float max = 0, min = 10000; + + #if HAS_AUTO_FAN + next_auto_fan_check_ms = temp_ms + 2500UL; + #endif + + if (hotend >= + #if ENABLED(PIDTEMP) + HOTENDS + #else + 0 + #endif + || hotend < + #if ENABLED(PIDTEMPBED) + -1 + #else + 0 + #endif + ) { + SERIAL_ECHOLN(MSG_PID_BAD_EXTRUDER_NUM); + return; + } + + SERIAL_ECHOLN(MSG_PID_AUTOTUNE_START); + + disable_all_heaters(); // switch off all heaters. + + #if HAS_PID_FOR_BOTH + if (hotend < 0) + soft_pwm_amount_bed = bias = d = (MAX_BED_POWER) >> 1; + else + soft_pwm_amount[hotend] = bias = d = (PID_MAX) >> 1; + #elif ENABLED(PIDTEMP) + soft_pwm_amount[hotend] = bias = d = (PID_MAX) >> 1; + #else + soft_pwm_amount_bed = bias = d = (MAX_BED_POWER) >> 1; + #endif + + wait_for_heatup = true; + + // PID Tuning loop + while (wait_for_heatup) { + + millis_t ms = millis(); + + if (temp_meas_ready) { // temp sample ready + updateTemperaturesFromRawValues(); + + input = + #if HAS_PID_FOR_BOTH + hotend < 0 ? current_temperature_bed : current_temperature[hotend] + #elif ENABLED(PIDTEMP) + current_temperature[hotend] + #else + current_temperature_bed + #endif + ; + + NOLESS(max, input); + NOMORE(min, input); + + #if HAS_AUTO_FAN + if (ELAPSED(ms, next_auto_fan_check_ms)) { + checkExtruderAutoFans(); + next_auto_fan_check_ms = ms + 2500UL; + } + #endif + + if (heating && input > temp) { + if (ELAPSED(ms, t2 + 5000UL)) { + heating = false; + #if HAS_PID_FOR_BOTH + if (hotend < 0) + soft_pwm_amount_bed = (bias - d) >> 1; + else + soft_pwm_amount[hotend] = (bias - d) >> 1; + #elif ENABLED(PIDTEMP) + soft_pwm_amount[hotend] = (bias - d) >> 1; + #elif ENABLED(PIDTEMPBED) + soft_pwm_amount_bed = (bias - d) >> 1; + #endif + t1 = ms; + t_high = t1 - t2; + max = temp; + } + } + + if (!heating && input < temp) { + if (ELAPSED(ms, t1 + 5000UL)) { + heating = true; + t2 = ms; + t_low = t2 - t1; + if (cycles > 0) { + long max_pow = + #if HAS_PID_FOR_BOTH + hotend < 0 ? MAX_BED_POWER : PID_MAX + #elif ENABLED(PIDTEMP) + PID_MAX + #else + MAX_BED_POWER + #endif + ; + bias += (d * (t_high - t_low)) / (t_low + t_high); + bias = constrain(bias, 20, max_pow - 20); + d = (bias > max_pow / 2) ? max_pow - 1 - bias : bias; + + SERIAL_PROTOCOLPAIR(MSG_BIAS, bias); + SERIAL_PROTOCOLPAIR(MSG_D, d); + SERIAL_PROTOCOLPAIR(MSG_T_MIN, min); + SERIAL_PROTOCOLPAIR(MSG_T_MAX, max); + if (cycles > 2) { + Ku = (4.0 * d) / (M_PI * (max - min) * 0.5); + Tu = ((float)(t_low + t_high) * 0.001); + SERIAL_PROTOCOLPAIR(MSG_KU, Ku); + SERIAL_PROTOCOLPAIR(MSG_TU, Tu); + workKp = 0.6 * Ku; + workKi = 2 * workKp / Tu; + workKd = workKp * Tu * 0.125; + SERIAL_PROTOCOLLNPGM("\n" MSG_CLASSIC_PID); + SERIAL_PROTOCOLPAIR(MSG_KP, workKp); + SERIAL_PROTOCOLPAIR(MSG_KI, workKi); + SERIAL_PROTOCOLLNPAIR(MSG_KD, workKd); + /** + workKp = 0.33*Ku; + workKi = workKp/Tu; + workKd = workKp*Tu/3; + SERIAL_PROTOCOLLNPGM(" Some overshoot"); + SERIAL_PROTOCOLPAIR(" Kp: ", workKp); + SERIAL_PROTOCOLPAIR(" Ki: ", workKi); + SERIAL_PROTOCOLPAIR(" Kd: ", workKd); + workKp = 0.2*Ku; + workKi = 2*workKp/Tu; + workKd = workKp*Tu/3; + SERIAL_PROTOCOLLNPGM(" No overshoot"); + SERIAL_PROTOCOLPAIR(" Kp: ", workKp); + SERIAL_PROTOCOLPAIR(" Ki: ", workKi); + SERIAL_PROTOCOLPAIR(" Kd: ", workKd); + */ + } + } + #if HAS_PID_FOR_BOTH + if (hotend < 0) + soft_pwm_amount_bed = (bias + d) >> 1; + else + soft_pwm_amount[hotend] = (bias + d) >> 1; + #elif ENABLED(PIDTEMP) + soft_pwm_amount[hotend] = (bias + d) >> 1; + #else + soft_pwm_amount_bed = (bias + d) >> 1; + #endif + cycles++; + min = temp; + } + } + } + #define MAX_OVERSHOOT_PID_AUTOTUNE 20 + if (input > temp + MAX_OVERSHOOT_PID_AUTOTUNE) { + SERIAL_PROTOCOLLNPGM(MSG_PID_TEMP_TOO_HIGH); + return; + } + // Every 2 seconds... + if (ELAPSED(ms, temp_ms + 2000UL)) { + #if HAS_TEMP_HOTEND || HAS_TEMP_BED + print_heaterstates(); + SERIAL_EOL(); + #endif + + temp_ms = ms; + } // every 2 seconds + // Over 2 minutes? + if (((ms - t1) + (ms - t2)) > (10L * 60L * 1000L * 2L)) { + SERIAL_PROTOCOLLNPGM(MSG_PID_TIMEOUT); + return; + } + if (cycles > ncycles) { + SERIAL_PROTOCOLLNPGM(MSG_PID_AUTOTUNE_FINISHED); + + #if HAS_PID_FOR_BOTH + const char* estring = hotend < 0 ? "bed" : ""; + SERIAL_PROTOCOLPAIR("#define DEFAULT_", estring); SERIAL_PROTOCOLPAIR("Kp ", workKp); SERIAL_EOL(); + SERIAL_PROTOCOLPAIR("#define DEFAULT_", estring); SERIAL_PROTOCOLPAIR("Ki ", workKi); SERIAL_EOL(); + SERIAL_PROTOCOLPAIR("#define DEFAULT_", estring); SERIAL_PROTOCOLPAIR("Kd ", workKd); SERIAL_EOL(); + #elif ENABLED(PIDTEMP) + SERIAL_PROTOCOLPAIR("#define DEFAULT_Kp ", workKp); SERIAL_EOL(); + SERIAL_PROTOCOLPAIR("#define DEFAULT_Ki ", workKi); SERIAL_EOL(); + SERIAL_PROTOCOLPAIR("#define DEFAULT_Kd ", workKd); SERIAL_EOL(); + #else + SERIAL_PROTOCOLPAIR("#define DEFAULT_bedKp ", workKp); SERIAL_EOL(); + SERIAL_PROTOCOLPAIR("#define DEFAULT_bedKi ", workKi); SERIAL_EOL(); + SERIAL_PROTOCOLPAIR("#define DEFAULT_bedKd ", workKd); SERIAL_EOL(); + #endif + + #define _SET_BED_PID() do { \ + bedKp = workKp; \ + bedKi = scalePID_i(workKi); \ + bedKd = scalePID_d(workKd); \ + updatePID(); }while(0) + + #define _SET_EXTRUDER_PID() do { \ + PID_PARAM(Kp, hotend) = workKp; \ + PID_PARAM(Ki, hotend) = scalePID_i(workKi); \ + PID_PARAM(Kd, hotend) = scalePID_d(workKd); \ + updatePID(); }while(0) + + // Use the result? (As with "M303 U1") + if (set_result) { + #if HAS_PID_FOR_BOTH + if (hotend < 0) + _SET_BED_PID(); + else + _SET_EXTRUDER_PID(); + #elif ENABLED(PIDTEMP) + _SET_EXTRUDER_PID(); + #else + _SET_BED_PID(); + #endif + } + return; + } + lcd_update(); + } + if (!wait_for_heatup) disable_all_heaters(); + } + +#endif // HAS_PID_HEATING + +/** + * Class and Instance Methods + */ + +Temperature::Temperature() { } + +void Temperature::updatePID() { + #if ENABLED(PIDTEMP) + #if ENABLED(PID_EXTRUSION_SCALING) + last_e_position = 0; + #endif + #endif +} + +int Temperature::getHeaterPower(int heater) { + return heater < 0 ? soft_pwm_amount_bed : soft_pwm_amount[heater]; +} + +#if HAS_AUTO_FAN + + void Temperature::checkExtruderAutoFans() { + static const int8_t fanPin[] PROGMEM = { E0_AUTO_FAN_PIN, E1_AUTO_FAN_PIN, E2_AUTO_FAN_PIN, E3_AUTO_FAN_PIN, E4_AUTO_FAN_PIN }; + static const uint8_t fanBit[] PROGMEM = { + 0, + AUTO_1_IS_0 ? 0 : 1, + AUTO_2_IS_0 ? 0 : AUTO_2_IS_1 ? 1 : 2, + AUTO_3_IS_0 ? 0 : AUTO_3_IS_1 ? 1 : AUTO_3_IS_2 ? 2 : 3, + AUTO_4_IS_0 ? 0 : AUTO_4_IS_1 ? 1 : AUTO_4_IS_2 ? 2 : AUTO_4_IS_3 ? 3 : 4 + }; + uint8_t fanState = 0; + + HOTEND_LOOP() + if (current_temperature[e] > EXTRUDER_AUTO_FAN_TEMPERATURE) + SBI(fanState, pgm_read_byte(&fanBit[e])); + + uint8_t fanDone = 0; + for (uint8_t f = 0; f < COUNT(fanPin); f++) { + int8_t pin = pgm_read_byte(&fanPin[f]); + const uint8_t bit = pgm_read_byte(&fanBit[f]); + if (pin >= 0 && !TEST(fanDone, bit)) { + uint8_t newFanSpeed = TEST(fanState, bit) ? EXTRUDER_AUTO_FAN_SPEED : 0; + // this idiom allows both digital and PWM fan outputs (see M42 handling). + digitalWrite(pin, newFanSpeed); + analogWrite(pin, newFanSpeed); + SBI(fanDone, bit); + } + } + } + +#endif // HAS_AUTO_FAN + +// +// Temperature Error Handlers +// +void Temperature::_temp_error(const int8_t e, const char * const serial_msg, const char * const lcd_msg) { + static bool killed = false; + if (IsRunning()) { + SERIAL_ERROR_START(); + serialprintPGM(serial_msg); + SERIAL_ERRORPGM(MSG_STOPPED_HEATER); + if (e >= 0) SERIAL_ERRORLN((int)e); else SERIAL_ERRORLNPGM(MSG_HEATER_BED); + } + #if DISABLED(BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE) + if (!killed) { + Running = false; + killed = true; + kill(lcd_msg); + } + else + disable_all_heaters(); // paranoia + #endif +} + +void Temperature::max_temp_error(const int8_t e) { + #if HAS_TEMP_BED + _temp_error(e, PSTR(MSG_T_MAXTEMP), e >= 0 ? PSTR(MSG_ERR_MAXTEMP) : PSTR(MSG_ERR_MAXTEMP_BED)); + #else + _temp_error(HOTEND_INDEX, PSTR(MSG_T_MAXTEMP), PSTR(MSG_ERR_MAXTEMP)); + #if HOTENDS == 1 + UNUSED(e); + #endif + #endif +} +void Temperature::min_temp_error(const int8_t e) { + #if HAS_TEMP_BED + _temp_error(e, PSTR(MSG_T_MINTEMP), e >= 0 ? PSTR(MSG_ERR_MINTEMP) : PSTR(MSG_ERR_MINTEMP_BED)); + #else + _temp_error(HOTEND_INDEX, PSTR(MSG_T_MINTEMP), PSTR(MSG_ERR_MINTEMP)); + #if HOTENDS == 1 + UNUSED(e); + #endif + #endif +} + +float Temperature::get_pid_output(const int8_t e) { + #if HOTENDS == 1 + UNUSED(e); + #define _HOTEND_TEST true + #else + #define _HOTEND_TEST e == active_extruder + #endif + float pid_output; + #if ENABLED(PIDTEMP) + #if DISABLED(PID_OPENLOOP) + pid_error[HOTEND_INDEX] = target_temperature[HOTEND_INDEX] - current_temperature[HOTEND_INDEX]; + dTerm[HOTEND_INDEX] = K2 * PID_PARAM(Kd, HOTEND_INDEX) * (current_temperature[HOTEND_INDEX] - temp_dState[HOTEND_INDEX]) + K1 * dTerm[HOTEND_INDEX]; + temp_dState[HOTEND_INDEX] = current_temperature[HOTEND_INDEX]; + #if HEATER_IDLE_HANDLER + if (heater_idle_timeout_exceeded[HOTEND_INDEX]) { + pid_output = 0; + pid_reset[HOTEND_INDEX] = true; + } + else + #endif + if (pid_error[HOTEND_INDEX] > PID_FUNCTIONAL_RANGE) { + pid_output = BANG_MAX; + pid_reset[HOTEND_INDEX] = true; + } + else if (pid_error[HOTEND_INDEX] < -(PID_FUNCTIONAL_RANGE) || target_temperature[HOTEND_INDEX] == 0 + #if HEATER_IDLE_HANDLER + || heater_idle_timeout_exceeded[HOTEND_INDEX] + #endif + ) { + pid_output = 0; + pid_reset[HOTEND_INDEX] = true; + } + else { + if (pid_reset[HOTEND_INDEX]) { + temp_iState[HOTEND_INDEX] = 0.0; + pid_reset[HOTEND_INDEX] = false; + } + pTerm[HOTEND_INDEX] = PID_PARAM(Kp, HOTEND_INDEX) * pid_error[HOTEND_INDEX]; + temp_iState[HOTEND_INDEX] += pid_error[HOTEND_INDEX]; + iTerm[HOTEND_INDEX] = PID_PARAM(Ki, HOTEND_INDEX) * temp_iState[HOTEND_INDEX]; + + pid_output = pTerm[HOTEND_INDEX] + iTerm[HOTEND_INDEX] - dTerm[HOTEND_INDEX]; + + #if ENABLED(PID_EXTRUSION_SCALING) + cTerm[HOTEND_INDEX] = 0; + if (_HOTEND_TEST) { + long e_position = stepper.position(E_AXIS); + if (e_position > last_e_position) { + lpq[lpq_ptr] = e_position - last_e_position; + last_e_position = e_position; + } + else { + lpq[lpq_ptr] = 0; + } + if (++lpq_ptr >= lpq_len) lpq_ptr = 0; + cTerm[HOTEND_INDEX] = (lpq[lpq_ptr] * planner.steps_to_mm[E_AXIS]) * PID_PARAM(Kc, HOTEND_INDEX); + pid_output += cTerm[HOTEND_INDEX]; + } + #endif // PID_EXTRUSION_SCALING + + if (pid_output > PID_MAX) { + if (pid_error[HOTEND_INDEX] > 0) temp_iState[HOTEND_INDEX] -= pid_error[HOTEND_INDEX]; // conditional un-integration + pid_output = PID_MAX; + } + else if (pid_output < 0) { + if (pid_error[HOTEND_INDEX] < 0) temp_iState[HOTEND_INDEX] -= pid_error[HOTEND_INDEX]; // conditional un-integration + pid_output = 0; + } + } + #else + pid_output = constrain(target_temperature[HOTEND_INDEX], 0, PID_MAX); + #endif // PID_OPENLOOP + + #if ENABLED(PID_DEBUG) + SERIAL_ECHO_START(); + SERIAL_ECHOPAIR(MSG_PID_DEBUG, HOTEND_INDEX); + SERIAL_ECHOPAIR(MSG_PID_DEBUG_INPUT, current_temperature[HOTEND_INDEX]); + SERIAL_ECHOPAIR(MSG_PID_DEBUG_OUTPUT, pid_output); + SERIAL_ECHOPAIR(MSG_PID_DEBUG_PTERM, pTerm[HOTEND_INDEX]); + SERIAL_ECHOPAIR(MSG_PID_DEBUG_ITERM, iTerm[HOTEND_INDEX]); + SERIAL_ECHOPAIR(MSG_PID_DEBUG_DTERM, dTerm[HOTEND_INDEX]); + #if ENABLED(PID_EXTRUSION_SCALING) + SERIAL_ECHOPAIR(MSG_PID_DEBUG_CTERM, cTerm[HOTEND_INDEX]); + #endif + SERIAL_EOL(); + #endif // PID_DEBUG + + #else /* PID off */ + #if HEATER_IDLE_HANDLER + if (heater_idle_timeout_exceeded[HOTEND_INDEX]) + pid_output = 0; + else + #endif + pid_output = (current_temperature[HOTEND_INDEX] < target_temperature[HOTEND_INDEX]) ? PID_MAX : 0; + #endif + + return pid_output; +} + +#if ENABLED(PIDTEMPBED) + float Temperature::get_pid_output_bed() { + float pid_output; + #if DISABLED(PID_OPENLOOP) + pid_error_bed = target_temperature_bed - current_temperature_bed; + pTerm_bed = bedKp * pid_error_bed; + temp_iState_bed += pid_error_bed; + iTerm_bed = bedKi * temp_iState_bed; + + dTerm_bed = K2 * bedKd * (current_temperature_bed - temp_dState_bed) + K1 * dTerm_bed; + temp_dState_bed = current_temperature_bed; + + pid_output = pTerm_bed + iTerm_bed - dTerm_bed; + if (pid_output > MAX_BED_POWER) { + if (pid_error_bed > 0) temp_iState_bed -= pid_error_bed; // conditional un-integration + pid_output = MAX_BED_POWER; + } + else if (pid_output < 0) { + if (pid_error_bed < 0) temp_iState_bed -= pid_error_bed; // conditional un-integration + pid_output = 0; + } + #else + pid_output = constrain(target_temperature_bed, 0, MAX_BED_POWER); + #endif // PID_OPENLOOP + + #if ENABLED(PID_BED_DEBUG) + SERIAL_ECHO_START(); + SERIAL_ECHOPGM(" PID_BED_DEBUG "); + SERIAL_ECHOPGM(": Input "); + SERIAL_ECHO(current_temperature_bed); + SERIAL_ECHOPGM(" Output "); + SERIAL_ECHO(pid_output); + SERIAL_ECHOPGM(" pTerm "); + SERIAL_ECHO(pTerm_bed); + SERIAL_ECHOPGM(" iTerm "); + SERIAL_ECHO(iTerm_bed); + SERIAL_ECHOPGM(" dTerm "); + SERIAL_ECHOLN(dTerm_bed); + #endif // PID_BED_DEBUG + + return pid_output; + } +#endif // PIDTEMPBED + +/** + * Manage heating activities for extruder hot-ends and a heated bed + * - Acquire updated temperature readings + * - Also resets the watchdog timer + * - Invoke thermal runaway protection + * - Manage extruder auto-fan + * - Apply filament width to the extrusion rate (may move) + * - Update the heated bed PID output value + */ + +/** + * The following line SOMETIMES results in the dreaded "unable to find a register to spill in class 'POINTER_REGS'" + * compile error. + * thermal_runaway_protection(&thermal_runaway_state_machine[e], &thermal_runaway_timer[e], current_temperature[e], target_temperature[e], e, THERMAL_PROTECTION_PERIOD, THERMAL_PROTECTION_HYSTERESIS); + * + * This is due to a bug in the C++ compiler used by the Arduino IDE from 1.6.10 to at least 1.8.1. + * + * The work around is to add the compiler flag "__attribute__((__optimize__("O2")))" to the declaration for manage_heater() + */ +//void Temperature::manage_heater() __attribute__((__optimize__("O2"))); +void Temperature::manage_heater() { + + if (!temp_meas_ready) return; + + updateTemperaturesFromRawValues(); // also resets the watchdog + + #if ENABLED(HEATER_0_USES_MAX6675) + if (current_temperature[0] > min(HEATER_0_MAXTEMP, MAX6675_TMAX - 1.0)) max_temp_error(0); + if (current_temperature[0] < max(HEATER_0_MINTEMP, MAX6675_TMIN + .01)) min_temp_error(0); + #endif + + #if WATCH_HOTENDS || WATCH_THE_BED || DISABLED(PIDTEMPBED) || HAS_AUTO_FAN || HEATER_IDLE_HANDLER + millis_t ms = millis(); + #endif + + HOTEND_LOOP() { + + #if HEATER_IDLE_HANDLER + if (!heater_idle_timeout_exceeded[e] && heater_idle_timeout_ms[e] && ELAPSED(ms, heater_idle_timeout_ms[e])) + heater_idle_timeout_exceeded[e] = true; + #endif + + #if ENABLED(THERMAL_PROTECTION_HOTENDS) + // Check for thermal runaway + thermal_runaway_protection(&thermal_runaway_state_machine[e], &thermal_runaway_timer[e], current_temperature[e], target_temperature[e], e, THERMAL_PROTECTION_PERIOD, THERMAL_PROTECTION_HYSTERESIS); + #endif + + soft_pwm_amount[e] = (current_temperature[e] > minttemp[e] || is_preheating(e)) && current_temperature[e] < maxttemp[e] ? (int)get_pid_output(e) >> 1 : 0; + + #if WATCH_HOTENDS + // Make sure temperature is increasing + if (watch_heater_next_ms[e] && ELAPSED(ms, watch_heater_next_ms[e])) { // Time to check this extruder? + if (degHotend(e) < watch_target_temp[e]) // Failed to increase enough? + _temp_error(e, PSTR(MSG_T_HEATING_FAILED), PSTR(MSG_HEATING_FAILED_LCD)); + else // Start again if the target is still far off + start_watching_heater(e); + } + #endif + + #if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT) + // Make sure measured temperatures are close together + if (FABS(current_temperature[0] - redundant_temperature) > MAX_REDUNDANT_TEMP_SENSOR_DIFF) + _temp_error(0, PSTR(MSG_REDUNDANCY), PSTR(MSG_ERR_REDUNDANT_TEMP)); + #endif + + } // HOTEND_LOOP + + #if HAS_AUTO_FAN + if (ELAPSED(ms, next_auto_fan_check_ms)) { // only need to check fan state very infrequently + checkExtruderAutoFans(); + next_auto_fan_check_ms = ms + 2500UL; + } + #endif + + // Control the extruder rate based on the width sensor + #if ENABLED(FILAMENT_WIDTH_SENSOR) + if (filament_sensor) { + meas_shift_index = filwidth_delay_index[0] - meas_delay_cm; + if (meas_shift_index < 0) meas_shift_index += MAX_MEASUREMENT_DELAY + 1; //loop around buffer if needed + meas_shift_index = constrain(meas_shift_index, 0, MAX_MEASUREMENT_DELAY); + + // Get the delayed info and add 100 to reconstitute to a percent of + // the nominal filament diameter then square it to get an area + const float vmroot = measurement_delay[meas_shift_index] * 0.01 + 1.0; + volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM] = vmroot <= 0.1 ? 0.01 : sq(vmroot); + } + #endif // FILAMENT_WIDTH_SENSOR + + #if WATCH_THE_BED + // Make sure temperature is increasing + if (watch_bed_next_ms && ELAPSED(ms, watch_bed_next_ms)) { // Time to check the bed? + if (degBed() < watch_target_bed_temp) // Failed to increase enough? + _temp_error(-1, PSTR(MSG_T_HEATING_FAILED), PSTR(MSG_HEATING_FAILED_LCD)); + else // Start again if the target is still far off + start_watching_bed(); + } + #endif // WATCH_THE_BED + + #if DISABLED(PIDTEMPBED) + if (PENDING(ms, next_bed_check_ms)) return; + next_bed_check_ms = ms + BED_CHECK_INTERVAL; + #endif + + #if HAS_TEMP_BED + + #if HEATER_IDLE_HANDLER + if (!bed_idle_timeout_exceeded && bed_idle_timeout_ms && ELAPSED(ms, bed_idle_timeout_ms)) + bed_idle_timeout_exceeded = true; + #endif + + #if HAS_THERMALLY_PROTECTED_BED + thermal_runaway_protection(&thermal_runaway_bed_state_machine, &thermal_runaway_bed_timer, current_temperature_bed, target_temperature_bed, -1, THERMAL_PROTECTION_BED_PERIOD, THERMAL_PROTECTION_BED_HYSTERESIS); + #endif + + #if HEATER_IDLE_HANDLER + if (bed_idle_timeout_exceeded) + { + soft_pwm_amount_bed = 0; + + #if DISABLED(PIDTEMPBED) + WRITE_HEATER_BED(LOW); + #endif + } + else + #endif + { + #if ENABLED(PIDTEMPBED) + soft_pwm_amount_bed = WITHIN(current_temperature_bed, BED_MINTEMP, BED_MAXTEMP) ? (int)get_pid_output_bed() >> 1 : 0; + + #elif ENABLED(BED_LIMIT_SWITCHING) + // Check if temperature is within the correct band + if (WITHIN(current_temperature_bed, BED_MINTEMP, BED_MAXTEMP)) { + if (current_temperature_bed >= target_temperature_bed + BED_HYSTERESIS) + soft_pwm_amount_bed = 0; + else if (current_temperature_bed <= target_temperature_bed - (BED_HYSTERESIS)) + soft_pwm_amount_bed = MAX_BED_POWER >> 1; + } + else { + soft_pwm_amount_bed = 0; + WRITE_HEATER_BED(LOW); + } + #else // !PIDTEMPBED && !BED_LIMIT_SWITCHING + // Check if temperature is within the correct range + if (WITHIN(current_temperature_bed, BED_MINTEMP, BED_MAXTEMP)) { + soft_pwm_amount_bed = current_temperature_bed < target_temperature_bed ? MAX_BED_POWER >> 1 : 0; + } + else { + soft_pwm_amount_bed = 0; + WRITE_HEATER_BED(LOW); + } + #endif + } + #endif // HAS_TEMP_BED +} + +#define PGM_RD_W(x) (short)pgm_read_word(&x) + +// Derived from RepRap FiveD extruder::getTemperature() +// For hot end temperature measurement. +float Temperature::analog2temp(int raw, uint8_t e) { + #if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT) + if (e > HOTENDS) + #else + if (e >= HOTENDS) + #endif + { + SERIAL_ERROR_START(); + SERIAL_ERROR((int)e); + SERIAL_ERRORLNPGM(MSG_INVALID_EXTRUDER_NUM); + kill(PSTR(MSG_KILLED)); + return 0.0; + } + + #if ENABLED(HEATER_0_USES_MAX6675) + if (e == 0) return 0.25 * raw; + #endif + + if (heater_ttbl_map[e] != NULL) { + float celsius = 0; + uint8_t i; + short(*tt)[][2] = (short(*)[][2])(heater_ttbl_map[e]); + + for (i = 1; i < heater_ttbllen_map[e]; i++) { + if (PGM_RD_W((*tt)[i][0]) > raw) { + celsius = PGM_RD_W((*tt)[i - 1][1]) + + (raw - PGM_RD_W((*tt)[i - 1][0])) * + (float)(PGM_RD_W((*tt)[i][1]) - PGM_RD_W((*tt)[i - 1][1])) / + (float)(PGM_RD_W((*tt)[i][0]) - PGM_RD_W((*tt)[i - 1][0])); + break; + } + } + + // Overflow: Set to last value in the table + if (i == heater_ttbllen_map[e]) celsius = PGM_RD_W((*tt)[i - 1][1]); + + return celsius; + } + return ((raw * ((5.0 * 100.0) / 1024.0) / OVERSAMPLENR) * (TEMP_SENSOR_AD595_GAIN)) + TEMP_SENSOR_AD595_OFFSET; +} + +// Derived from RepRap FiveD extruder::getTemperature() +// For bed temperature measurement. +float Temperature::analog2tempBed(const int raw) { + #if ENABLED(BED_USES_THERMISTOR) + float celsius = 0; + byte i; + + for (i = 1; i < BEDTEMPTABLE_LEN; i++) { + if (PGM_RD_W(BEDTEMPTABLE[i][0]) > raw) { + celsius = PGM_RD_W(BEDTEMPTABLE[i - 1][1]) + + (raw - PGM_RD_W(BEDTEMPTABLE[i - 1][0])) * + (float)(PGM_RD_W(BEDTEMPTABLE[i][1]) - PGM_RD_W(BEDTEMPTABLE[i - 1][1])) / + (float)(PGM_RD_W(BEDTEMPTABLE[i][0]) - PGM_RD_W(BEDTEMPTABLE[i - 1][0])); + break; + } + } + + // Overflow: Set to last value in the table + if (i == BEDTEMPTABLE_LEN) celsius = PGM_RD_W(BEDTEMPTABLE[i - 1][1]); + + return celsius; + + #elif defined(BED_USES_AD595) + + return ((raw * ((5.0 * 100.0) / 1024.0) / OVERSAMPLENR) * (TEMP_SENSOR_AD595_GAIN)) + TEMP_SENSOR_AD595_OFFSET; + + #else + + UNUSED(raw); + return 0; + + #endif +} + +/** + * Get the raw values into the actual temperatures. + * The raw values are created in interrupt context, + * and this function is called from normal context + * as it would block the stepper routine. + */ +void Temperature::updateTemperaturesFromRawValues() { + #if ENABLED(HEATER_0_USES_MAX6675) + current_temperature_raw[0] = read_max6675(); + #endif + HOTEND_LOOP() + current_temperature[e] = Temperature::analog2temp(current_temperature_raw[e], e); + current_temperature_bed = Temperature::analog2tempBed(current_temperature_bed_raw); + #if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT) + redundant_temperature = Temperature::analog2temp(redundant_temperature_raw, 1); + #endif + #if ENABLED(FILAMENT_WIDTH_SENSOR) + filament_width_meas = analog2widthFil(); + #endif + + #if ENABLED(USE_WATCHDOG) + // Reset the watchdog after we know we have a temperature measurement. + watchdog_reset(); + #endif + + CRITICAL_SECTION_START; + temp_meas_ready = false; + CRITICAL_SECTION_END; +} + + +#if ENABLED(FILAMENT_WIDTH_SENSOR) + + // Convert raw Filament Width to millimeters + float Temperature::analog2widthFil() { + return current_raw_filwidth * 5.0 * (1.0 / 16383.0); + //return current_raw_filwidth; + } + + // Convert raw Filament Width to a ratio + int Temperature::widthFil_to_size_ratio() { + float temp = filament_width_meas; + if (temp < MEASURED_LOWER_LIMIT) temp = filament_width_nominal; //assume sensor cut out + else NOMORE(temp, MEASURED_UPPER_LIMIT); + return filament_width_nominal / temp * 100; + } + +#endif + +#if ENABLED(HEATER_0_USES_MAX6675) + #ifndef MAX6675_SCK_PIN + #define MAX6675_SCK_PIN SCK_PIN + #endif + #ifndef MAX6675_DO_PIN + #define MAX6675_DO_PIN MISO_PIN + #endif + SPI max6675_spi; +#endif + +/** + * Initialize the temperature manager + * The manager is implemented by periodic calls to manage_heater() + */ +void Temperature::init() { + + #if MB(RUMBA) && (TEMP_SENSOR_0 == -1 || TEMP_SENSOR_1 == -1 || TEMP_SENSOR_2 == -1 || TEMP_SENSOR_BED == -1) + // Disable RUMBA JTAG in case the thermocouple extension is plugged on top of JTAG connector + MCUCR = _BV(JTD); + MCUCR = _BV(JTD); + #endif + + // Finish init of mult hotend arrays + HOTEND_LOOP() maxttemp[e] = maxttemp[0]; + + #if ENABLED(PIDTEMP) && ENABLED(PID_EXTRUSION_SCALING) + last_e_position = 0; + #endif + + #if HAS_HEATER_0 + SET_OUTPUT(HEATER_0_PIN); + #endif + #if HAS_HEATER_1 + SET_OUTPUT(HEATER_1_PIN); + #endif + #if HAS_HEATER_2 + SET_OUTPUT(HEATER_2_PIN); + #endif + #if HAS_HEATER_3 + SET_OUTPUT(HEATER_3_PIN); + #endif + #if HAS_HEATER_4 + SET_OUTPUT(HEATER_3_PIN); + #endif + #if HAS_HEATER_BED + SET_OUTPUT(HEATER_BED_PIN); + #endif + + #if HAS_FAN0 + SET_OUTPUT(FAN_PIN); + #if ENABLED(FAST_PWM_FAN) + setPwmFrequency(FAN_PIN, 1); // No prescaling. Pwm frequency = F_CPU/256/8 + #endif + #endif + + #if HAS_FAN1 + SET_OUTPUT(FAN1_PIN); + #if ENABLED(FAST_PWM_FAN) + setPwmFrequency(FAN1_PIN, 1); // No prescaling. Pwm frequency = F_CPU/256/8 + #endif + #endif + + #if HAS_FAN2 + SET_OUTPUT(FAN2_PIN); + #if ENABLED(FAST_PWM_FAN) + setPwmFrequency(FAN2_PIN, 1); // No prescaling. Pwm frequency = F_CPU/256/8 + #endif + #endif + + #if ENABLED(HEATER_0_USES_MAX6675) + + OUT_WRITE(SCK_PIN, LOW); + OUT_WRITE(MOSI_PIN, HIGH); + SET_INPUT_PULLUP(MISO_PIN); + + max6675_spi.init(); + + OUT_WRITE(SS_PIN, HIGH); + OUT_WRITE(MAX6675_SS, HIGH); + + #endif // HEATER_0_USES_MAX6675 + + #ifdef DIDR2 + #define ANALOG_SELECT(pin) do{ if (pin < 8) SBI(DIDR0, pin); else SBI(DIDR2, pin - 8); }while(0) + #else + #define ANALOG_SELECT(pin) do{ SBI(DIDR0, pin); }while(0) + #endif + + // Set analog inputs + ADCSRA = _BV(ADEN) | _BV(ADSC) | _BV(ADIF) | 0x07; + DIDR0 = 0; + #ifdef DIDR2 + DIDR2 = 0; + #endif + #if HAS_TEMP_0 + ANALOG_SELECT(TEMP_0_PIN); + #endif + #if HAS_TEMP_1 + ANALOG_SELECT(TEMP_1_PIN); + #endif + #if HAS_TEMP_2 + ANALOG_SELECT(TEMP_2_PIN); + #endif + #if HAS_TEMP_3 + ANALOG_SELECT(TEMP_3_PIN); + #endif + #if HAS_TEMP_4 + ANALOG_SELECT(TEMP_4_PIN); + #endif + #if HAS_TEMP_BED + ANALOG_SELECT(TEMP_BED_PIN); + #endif + #if ENABLED(FILAMENT_WIDTH_SENSOR) + ANALOG_SELECT(FILWIDTH_PIN); + #endif + + #if HAS_AUTO_FAN_0 + #if E0_AUTO_FAN_PIN == FAN1_PIN + SET_OUTPUT(E0_AUTO_FAN_PIN); + #if ENABLED(FAST_PWM_FAN) + setPwmFrequency(E0_AUTO_FAN_PIN, 1); // No prescaling. Pwm frequency = F_CPU/256/8 + #endif + #else + SET_OUTPUT(E0_AUTO_FAN_PIN); + #endif + #endif + #if HAS_AUTO_FAN_1 && !AUTO_1_IS_0 + #if E1_AUTO_FAN_PIN == FAN1_PIN + SET_OUTPUT(E1_AUTO_FAN_PIN); + #if ENABLED(FAST_PWM_FAN) + setPwmFrequency(E1_AUTO_FAN_PIN, 1); // No prescaling. Pwm frequency = F_CPU/256/8 + #endif + #else + SET_OUTPUT(E1_AUTO_FAN_PIN); + #endif + #endif + #if HAS_AUTO_FAN_2 && !AUTO_2_IS_0 && !AUTO_2_IS_1 + #if E2_AUTO_FAN_PIN == FAN1_PIN + SET_OUTPUT(E2_AUTO_FAN_PIN); + #if ENABLED(FAST_PWM_FAN) + setPwmFrequency(E2_AUTO_FAN_PIN, 1); // No prescaling. Pwm frequency = F_CPU/256/8 + #endif + #else + SET_OUTPUT(E2_AUTO_FAN_PIN); + #endif + #endif + #if HAS_AUTO_FAN_3 && !AUTO_3_IS_0 && !AUTO_3_IS_1 && !AUTO_3_IS_2 + #if E3_AUTO_FAN_PIN == FAN1_PIN + SET_OUTPUT(E3_AUTO_FAN_PIN); + #if ENABLED(FAST_PWM_FAN) + setPwmFrequency(E3_AUTO_FAN_PIN, 1); // No prescaling. Pwm frequency = F_CPU/256/8 + #endif + #else + SET_OUTPUT(E3_AUTO_FAN_PIN); + #endif + #endif + #if HAS_AUTO_FAN_4 && !AUTO_4_IS_0 && !AUTO_4_IS_1 && !AUTO_4_IS_2 && !AUTO_4_IS_3 + #if E4_AUTO_FAN_PIN == FAN1_PIN + SET_OUTPUT(E4_AUTO_FAN_PIN); + #if ENABLED(FAST_PWM_FAN) + setPwmFrequency(E4_AUTO_FAN_PIN, 1); // No prescaling. Pwm frequency = F_CPU/256/8 + #endif + #else + SET_OUTPUT(E4_AUTO_FAN_PIN); + #endif + #endif + + // Use timer0 for temperature measurement + // Interleave temperature interrupt with millies interrupt + OCR0B = 128; + SBI(TIMSK0, OCIE0B); + + // Wait for temperature measurement to settle + delay(250); + + #define TEMP_MIN_ROUTINE(NR) \ + minttemp[NR] = HEATER_ ##NR## _MINTEMP; \ + while (analog2temp(minttemp_raw[NR], NR) < HEATER_ ##NR## _MINTEMP) { \ + if (HEATER_ ##NR## _RAW_LO_TEMP < HEATER_ ##NR## _RAW_HI_TEMP) \ + minttemp_raw[NR] += OVERSAMPLENR; \ + else \ + minttemp_raw[NR] -= OVERSAMPLENR; \ + } + #define TEMP_MAX_ROUTINE(NR) \ + maxttemp[NR] = HEATER_ ##NR## _MAXTEMP; \ + while (analog2temp(maxttemp_raw[NR], NR) > HEATER_ ##NR## _MAXTEMP) { \ + if (HEATER_ ##NR## _RAW_LO_TEMP < HEATER_ ##NR## _RAW_HI_TEMP) \ + maxttemp_raw[NR] -= OVERSAMPLENR; \ + else \ + maxttemp_raw[NR] += OVERSAMPLENR; \ + } + + #ifdef HEATER_0_MINTEMP + TEMP_MIN_ROUTINE(0); + #endif + #ifdef HEATER_0_MAXTEMP + TEMP_MAX_ROUTINE(0); + #endif + #if HOTENDS > 1 + #ifdef HEATER_1_MINTEMP + TEMP_MIN_ROUTINE(1); + #endif + #ifdef HEATER_1_MAXTEMP + TEMP_MAX_ROUTINE(1); + #endif + #if HOTENDS > 2 + #ifdef HEATER_2_MINTEMP + TEMP_MIN_ROUTINE(2); + #endif + #ifdef HEATER_2_MAXTEMP + TEMP_MAX_ROUTINE(2); + #endif + #if HOTENDS > 3 + #ifdef HEATER_3_MINTEMP + TEMP_MIN_ROUTINE(3); + #endif + #ifdef HEATER_3_MAXTEMP + TEMP_MAX_ROUTINE(3); + #endif + #if HOTENDS > 4 + #ifdef HEATER_4_MINTEMP + TEMP_MIN_ROUTINE(4); + #endif + #ifdef HEATER_4_MAXTEMP + TEMP_MAX_ROUTINE(4); + #endif + #endif // HOTENDS > 4 + #endif // HOTENDS > 3 + #endif // HOTENDS > 2 + #endif // HOTENDS > 1 + + #ifdef BED_MINTEMP + while (analog2tempBed(bed_minttemp_raw) < BED_MINTEMP) { + #if HEATER_BED_RAW_LO_TEMP < HEATER_BED_RAW_HI_TEMP + bed_minttemp_raw += OVERSAMPLENR; + #else + bed_minttemp_raw -= OVERSAMPLENR; + #endif + } + #endif // BED_MINTEMP + #ifdef BED_MAXTEMP + while (analog2tempBed(bed_maxttemp_raw) > BED_MAXTEMP) { + #if HEATER_BED_RAW_LO_TEMP < HEATER_BED_RAW_HI_TEMP + bed_maxttemp_raw -= OVERSAMPLENR; + #else + bed_maxttemp_raw += OVERSAMPLENR; + #endif + } + #endif // BED_MAXTEMP + + #if ENABLED(PROBING_HEATERS_OFF) + paused = false; + #endif +} + +#if WATCH_HOTENDS + /** + * Start Heating Sanity Check for hotends that are below + * their target temperature by a configurable margin. + * This is called when the temperature is set. (M104, M109) + */ + void Temperature::start_watching_heater(uint8_t e) { + #if HOTENDS == 1 + UNUSED(e); + #endif + if (degHotend(HOTEND_INDEX) < degTargetHotend(HOTEND_INDEX) - (WATCH_TEMP_INCREASE + TEMP_HYSTERESIS + 1)) { + watch_target_temp[HOTEND_INDEX] = degHotend(HOTEND_INDEX) + WATCH_TEMP_INCREASE; + watch_heater_next_ms[HOTEND_INDEX] = millis() + (WATCH_TEMP_PERIOD) * 1000UL; + } + else + watch_heater_next_ms[HOTEND_INDEX] = 0; + } +#endif + +#if WATCH_THE_BED + /** + * Start Heating Sanity Check for hotends that are below + * their target temperature by a configurable margin. + * This is called when the temperature is set. (M140, M190) + */ + void Temperature::start_watching_bed() { + if (degBed() < degTargetBed() - (WATCH_BED_TEMP_INCREASE + TEMP_BED_HYSTERESIS + 1)) { + watch_target_bed_temp = degBed() + WATCH_BED_TEMP_INCREASE; + watch_bed_next_ms = millis() + (WATCH_BED_TEMP_PERIOD) * 1000UL; + } + else + watch_bed_next_ms = 0; + } +#endif + +#if ENABLED(THERMAL_PROTECTION_HOTENDS) || HAS_THERMALLY_PROTECTED_BED + + #if ENABLED(THERMAL_PROTECTION_HOTENDS) + Temperature::TRState Temperature::thermal_runaway_state_machine[HOTENDS] = { TRInactive }; + millis_t Temperature::thermal_runaway_timer[HOTENDS] = { 0 }; + #endif + + #if HAS_THERMALLY_PROTECTED_BED + Temperature::TRState Temperature::thermal_runaway_bed_state_machine = TRInactive; + millis_t Temperature::thermal_runaway_bed_timer; + #endif + + void Temperature::thermal_runaway_protection(Temperature::TRState* state, millis_t* timer, float current, float target, int heater_id, int period_seconds, int hysteresis_degc) { + + static float tr_target_temperature[HOTENDS + 1] = { 0.0 }; + + /** + SERIAL_ECHO_START(); + SERIAL_ECHOPGM("Thermal Thermal Runaway Running. Heater ID: "); + if (heater_id < 0) SERIAL_ECHOPGM("bed"); else SERIAL_ECHO(heater_id); + SERIAL_ECHOPAIR(" ; State:", *state); + SERIAL_ECHOPAIR(" ; Timer:", *timer); + SERIAL_ECHOPAIR(" ; Temperature:", current); + SERIAL_ECHOPAIR(" ; Target Temp:", target); + if (heater_id >= 0) + SERIAL_ECHOPAIR(" ; Idle Timeout:", heater_idle_timeout_exceeded[heater_id]); + else + SERIAL_ECHOPAIR(" ; Idle Timeout:", bed_idle_timeout_exceeded); + SERIAL_EOL(); + */ + + 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 && heater_idle_timeout_exceeded[heater_id]) { + *state = TRInactive; + tr_target_temperature[heater_index] = 0; + } + #if HAS_TEMP_BED + else if (heater_id < 0 && bed_idle_timeout_exceeded) { + *state = TRInactive; + tr_target_temperature[heater_index] = 0; + } + #endif + else + #endif + // If the target temperature changes, restart + if (tr_target_temperature[heater_index] != target) { + tr_target_temperature[heater_index] = target; + *state = target > 0 ? TRFirstHeating : TRInactive; + } + + 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; + *state = TRStable; + // While the temperature is stable watch for a bad temperature + case TRStable: + if (current >= tr_target_temperature[heater_index] - hysteresis_degc) { + *timer = millis() + period_seconds * 1000UL; + break; + } + else if (PENDING(millis(), *timer)) break; + *state = TRRunaway; + case TRRunaway: + _temp_error(heater_id, PSTR(MSG_T_THERMAL_RUNAWAY), PSTR(MSG_THERMAL_RUNAWAY)); + } + } + +#endif // THERMAL_PROTECTION_HOTENDS || THERMAL_PROTECTION_BED + +void Temperature::disable_all_heaters() { + + #if ENABLED(AUTOTEMP) + planner.autotemp_enabled = false; + #endif + + HOTEND_LOOP() setTargetHotend(0, e); + setTargetBed(0); + + // Unpause and reset everything + #if ENABLED(PROBING_HEATERS_OFF) + pause(false); + #endif + + // If all heaters go down then for sure our print job has stopped + print_job_timer.stop(); + + #define DISABLE_HEATER(NR) { \ + setTargetHotend(0, NR); \ + soft_pwm_amount[NR] = 0; \ + WRITE_HEATER_ ##NR (LOW); \ + } + + #if HAS_TEMP_HOTEND + DISABLE_HEATER(0); + #if HOTENDS > 1 + DISABLE_HEATER(1); + #if HOTENDS > 2 + DISABLE_HEATER(2); + #if HOTENDS > 3 + DISABLE_HEATER(3); + #if HOTENDS > 4 + DISABLE_HEATER(4); + #endif // HOTENDS > 4 + #endif // HOTENDS > 3 + #endif // HOTENDS > 2 + #endif // HOTENDS > 1 + #endif + + #if HAS_TEMP_BED + target_temperature_bed = 0; + soft_pwm_amount_bed = 0; + #if HAS_HEATER_BED + WRITE_HEATER_BED(LOW); + #endif + #endif +} + +#if ENABLED(PROBING_HEATERS_OFF) + + void Temperature::pause(const bool p) { + if (p != paused) { + paused = p; + if (p) { + HOTEND_LOOP() start_heater_idle_timer(e, 0); // timeout immediately + #if HAS_TEMP_BED + start_bed_idle_timer(0); // timeout immediately + #endif + } + else { + HOTEND_LOOP() reset_heater_idle_timer(e); + #if HAS_TEMP_BED + reset_bed_idle_timer(); + #endif + } + } + } + +#endif // PROBING_HEATERS_OFF + +#if ENABLED(HEATER_0_USES_MAX6675) + + #define MAX6675_HEAT_INTERVAL 250u + + #if ENABLED(MAX6675_IS_MAX31855) + uint32_t max6675_temp = 2000; + #define MAX6675_ERROR_MASK 7 + #define MAX6675_DISCARD_BITS 18 + #define MAX6675_SPEED_BITS (_BV(SPR1)) // clock ÷ 64 + #else + uint16_t max6675_temp = 2000; + #define MAX6675_ERROR_MASK 4 + #define MAX6675_DISCARD_BITS 3 + #define MAX6675_SPEED_BITS (_BV(SPR0)) // clock ÷ 16 + #endif + + int Temperature::read_max6675() { + + static millis_t next_max6675_ms = 0; + + millis_t ms = millis(); + + if (PENDING(ms, next_max6675_ms)) return (int)max6675_temp; + + next_max6675_ms = ms + MAX6675_HEAT_INTERVAL; + + CBI( + #ifdef PRR + PRR + #elif defined(PRR0) + PRR0 + #endif + , PRSPI); + SPCR = _BV(MSTR) | _BV(SPE) | MAX6675_SPEED_BITS; + + WRITE(MAX6675_SS, 0); // enable TT_MAX6675 + + // ensure 100ns delay - a bit extra is fine + asm("nop");//50ns on 20Mhz, 62.5ns on 16Mhz + asm("nop");//50ns on 20Mhz, 62.5ns on 16Mhz + + // Read a big-endian temperature value + max6675_temp = 0; + for (uint8_t i = sizeof(max6675_temp); i--;) { + max6675_temp |= max6675_spi.receive(); + if (i > 0) max6675_temp <<= 8; // shift left if not the last byte + } + + WRITE(MAX6675_SS, 1); // disable TT_MAX6675 + + if (max6675_temp & MAX6675_ERROR_MASK) { + SERIAL_ERROR_START(); + SERIAL_ERRORPGM("Temp measurement error! "); + #if MAX6675_ERROR_MASK == 7 + SERIAL_ERRORPGM("MAX31855 "); + if (max6675_temp & 1) + SERIAL_ERRORLNPGM("Open Circuit"); + else if (max6675_temp & 2) + SERIAL_ERRORLNPGM("Short to GND"); + else if (max6675_temp & 4) + SERIAL_ERRORLNPGM("Short to VCC"); + #else + SERIAL_ERRORLNPGM("MAX6675"); + #endif + max6675_temp = MAX6675_TMAX * 4; // thermocouple open + } + else + max6675_temp >>= MAX6675_DISCARD_BITS; + #if ENABLED(MAX6675_IS_MAX31855) + // Support negative temperature + if (max6675_temp & 0x00002000) max6675_temp |= 0xFFFFC000; + #endif + + return (int)max6675_temp; + } + +#endif // HEATER_0_USES_MAX6675 + +/** + * Get raw temperatures + */ +void Temperature::set_current_temp_raw() { + #if HAS_TEMP_0 && DISABLED(HEATER_0_USES_MAX6675) + current_temperature_raw[0] = raw_temp_value[0]; + #endif + #if HAS_TEMP_1 + #if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT) + redundant_temperature_raw = raw_temp_value[1]; + #else + current_temperature_raw[1] = raw_temp_value[1]; + #endif + #if HAS_TEMP_2 + current_temperature_raw[2] = raw_temp_value[2]; + #if HAS_TEMP_3 + current_temperature_raw[3] = raw_temp_value[3]; + #if HAS_TEMP_4 + current_temperature_raw[4] = raw_temp_value[4]; + #endif + #endif + #endif + #endif + current_temperature_bed_raw = raw_temp_bed_value; + temp_meas_ready = true; +} + +#if ENABLED(PINS_DEBUGGING) + /** + * monitors endstops & Z probe for changes + * + * If a change is detected then the LED is toggled and + * a message is sent out the serial port + * + * Yes, we could miss a rapid back & forth change but + * that won't matter because this is all manual. + * + */ + void endstop_monitor() { + static uint16_t old_endstop_bits_local = 0; + static uint8_t local_LED_status = 0; + uint16_t current_endstop_bits_local = 0; + #if HAS_X_MIN + if (READ(X_MIN_PIN)) SBI(current_endstop_bits_local, X_MIN); + #endif + #if HAS_X_MAX + if (READ(X_MAX_PIN)) SBI(current_endstop_bits_local, X_MAX); + #endif + #if HAS_Y_MIN + if (READ(Y_MIN_PIN)) SBI(current_endstop_bits_local, Y_MIN); + #endif + #if HAS_Y_MAX + if (READ(Y_MAX_PIN)) SBI(current_endstop_bits_local, Y_MAX); + #endif + #if HAS_Z_MIN + if (READ(Z_MIN_PIN)) SBI(current_endstop_bits_local, Z_MIN); + #endif + #if HAS_Z_MAX + if (READ(Z_MAX_PIN)) SBI(current_endstop_bits_local, Z_MAX); + #endif + #if HAS_Z_MIN_PROBE_PIN + if (READ(Z_MIN_PROBE_PIN)) SBI(current_endstop_bits_local, Z_MIN_PROBE); + #endif + #if HAS_Z2_MIN + if (READ(Z2_MIN_PIN)) SBI(current_endstop_bits_local, Z2_MIN); + #endif + #if HAS_Z2_MAX + if (READ(Z2_MAX_PIN)) SBI(current_endstop_bits_local, Z2_MAX); + #endif + + uint16_t endstop_change = current_endstop_bits_local ^ old_endstop_bits_local; + + if (endstop_change) { + #if HAS_X_MIN + if (TEST(endstop_change, X_MIN)) SERIAL_PROTOCOLPAIR(" X_MIN:", !!TEST(current_endstop_bits_local, X_MIN)); + #endif + #if HAS_X_MAX + if (TEST(endstop_change, X_MAX)) SERIAL_PROTOCOLPAIR(" X_MAX:", !!TEST(current_endstop_bits_local, X_MAX)); + #endif + #if HAS_Y_MIN + if (TEST(endstop_change, Y_MIN)) SERIAL_PROTOCOLPAIR(" Y_MIN:", !!TEST(current_endstop_bits_local, Y_MIN)); + #endif + #if HAS_Y_MAX + if (TEST(endstop_change, Y_MAX)) SERIAL_PROTOCOLPAIR(" Y_MAX:", !!TEST(current_endstop_bits_local, Y_MAX)); + #endif + #if HAS_Z_MIN + if (TEST(endstop_change, Z_MIN)) SERIAL_PROTOCOLPAIR(" Z_MIN:", !!TEST(current_endstop_bits_local, Z_MIN)); + #endif + #if HAS_Z_MAX + if (TEST(endstop_change, Z_MAX)) SERIAL_PROTOCOLPAIR(" Z_MAX:", !!TEST(current_endstop_bits_local, Z_MAX)); + #endif + #if HAS_Z_MIN_PROBE_PIN + if (TEST(endstop_change, Z_MIN_PROBE)) SERIAL_PROTOCOLPAIR(" PROBE:", !!TEST(current_endstop_bits_local, Z_MIN_PROBE)); + #endif + #if HAS_Z2_MIN + if (TEST(endstop_change, Z2_MIN)) SERIAL_PROTOCOLPAIR(" Z2_MIN:", !!TEST(current_endstop_bits_local, Z2_MIN)); + #endif + #if HAS_Z2_MAX + if (TEST(endstop_change, Z2_MAX)) SERIAL_PROTOCOLPAIR(" Z2_MAX:", !!TEST(current_endstop_bits_local, Z2_MAX)); + #endif + SERIAL_PROTOCOLPGM("\n\n"); + analogWrite(LED_PIN, local_LED_status); + local_LED_status ^= 255; + old_endstop_bits_local = current_endstop_bits_local; + } + } +#endif // PINS_DEBUGGING + +/** + * Timer 0 is shared with millies so don't change the prescaler. + * + * This ISR uses the compare method so it runs at the base + * frequency (16 MHz / 64 / 256 = 976.5625 Hz), but at the TCNT0 set + * in OCR0B above (128 or halfway between OVFs). + * + * - Manage PWM to all the heaters and fan + * - Prepare or Measure one of the raw ADC sensor values + * - Check new temperature values for MIN/MAX errors (kill on error) + * - Step the babysteps value for each axis towards 0 + * - For PINS_DEBUGGING, monitor and report endstop pins + * - For ENDSTOP_INTERRUPTS_FEATURE check endstops if flagged + */ +ISR(TIMER0_COMPB_vect) { Temperature::isr(); } + +volatile bool Temperature::in_temp_isr = false; + +void Temperature::isr() { + // The stepper ISR can interrupt this ISR. When it does it re-enables this ISR + // at the end of its run, potentially causing re-entry. This flag prevents it. + if (in_temp_isr) return; + in_temp_isr = true; + + // Allow UART and stepper ISRs + CBI(TIMSK0, OCIE0B); //Disable Temperature ISR + sei(); + + static int8_t temp_count = -1; + static ADCSensorState adc_sensor_state = StartupDelay; + static uint8_t pwm_count = _BV(SOFT_PWM_SCALE); + // avoid multiple loads of pwm_count + uint8_t pwm_count_tmp = pwm_count; + #if ENABLED(ADC_KEYPAD) + static unsigned int raw_ADCKey_value = 0; + #endif + + // Static members for each heater + #if ENABLED(SLOW_PWM_HEATERS) + static uint8_t slow_pwm_count = 0; + #define ISR_STATICS(n) \ + static uint8_t soft_pwm_count_ ## n, \ + state_heater_ ## n = 0, \ + state_timer_heater_ ## n = 0 + #else + #define ISR_STATICS(n) static uint8_t soft_pwm_count_ ## n = 0 + #endif + + // Statics per heater + ISR_STATICS(0); + #if HOTENDS > 1 + ISR_STATICS(1); + #if HOTENDS > 2 + ISR_STATICS(2); + #if HOTENDS > 3 + ISR_STATICS(3); + #if HOTENDS > 4 + ISR_STATICS(4); + #endif // HOTENDS > 4 + #endif // HOTENDS > 3 + #endif // HOTENDS > 2 + #endif // HOTENDS > 1 + #if HAS_HEATER_BED + ISR_STATICS(BED); + #endif + + #if ENABLED(FILAMENT_WIDTH_SENSOR) + static unsigned long raw_filwidth_value = 0; + #endif + + #if DISABLED(SLOW_PWM_HEATERS) + constexpr uint8_t pwm_mask = + #if ENABLED(SOFT_PWM_DITHER) + _BV(SOFT_PWM_SCALE) - 1 + #else + 0 + #endif + ; + + /** + * Standard PWM modulation + */ + if (pwm_count_tmp >= 127) { + pwm_count_tmp -= 127; + soft_pwm_count_0 = (soft_pwm_count_0 & pwm_mask) + soft_pwm_amount[0]; + WRITE_HEATER_0(soft_pwm_count_0 > pwm_mask ? HIGH : LOW); + #if HOTENDS > 1 + soft_pwm_count_1 = (soft_pwm_count_1 & pwm_mask) + soft_pwm_amount[1]; + WRITE_HEATER_1(soft_pwm_count_1 > pwm_mask ? HIGH : LOW); + #if HOTENDS > 2 + soft_pwm_count_2 = (soft_pwm_count_2 & pwm_mask) + soft_pwm_amount[2]; + WRITE_HEATER_2(soft_pwm_count_2 > pwm_mask ? HIGH : LOW); + #if HOTENDS > 3 + soft_pwm_count_3 = (soft_pwm_count_3 & pwm_mask) + soft_pwm_amount[3]; + WRITE_HEATER_3(soft_pwm_count_3 > pwm_mask ? HIGH : LOW); + #if HOTENDS > 4 + soft_pwm_count_4 = (soft_pwm_count_4 & pwm_mask) + soft_pwm_amount[4]; + WRITE_HEATER_4(soft_pwm_count_4 > pwm_mask ? HIGH : LOW); + #endif // HOTENDS > 4 + #endif // HOTENDS > 3 + #endif // HOTENDS > 2 + #endif // HOTENDS > 1 + + #if HAS_HEATER_BED + soft_pwm_count_BED = (soft_pwm_count_BED & pwm_mask) + soft_pwm_amount_bed; + WRITE_HEATER_BED(soft_pwm_count_BED > pwm_mask ? HIGH : LOW); + #endif + + #if ENABLED(FAN_SOFT_PWM) + #if HAS_FAN0 + soft_pwm_count_fan[0] = (soft_pwm_count_fan[0] & pwm_mask) + soft_pwm_amount_fan[0] >> 1; + WRITE_FAN(soft_pwm_count_fan[0] > pwm_mask ? HIGH : LOW); + #endif + #if HAS_FAN1 + soft_pwm_count_fan[1] = (soft_pwm_count_fan[1] & pwm_mask) + soft_pwm_amount_fan[1] >> 1; + WRITE_FAN1(soft_pwm_count_fan[1] > pwm_mask ? HIGH : LOW); + #endif + #if HAS_FAN2 + soft_pwm_count_fan[2] = (soft_pwm_count_fan[2] & pwm_mask) + soft_pwm_amount_fan[2] >> 1; + WRITE_FAN2(soft_pwm_count_fan[2] > pwm_mask ? HIGH : LOW); + #endif + #endif + } + else { + if (soft_pwm_count_0 <= pwm_count_tmp) WRITE_HEATER_0(LOW); + #if HOTENDS > 1 + if (soft_pwm_count_1 <= pwm_count_tmp) WRITE_HEATER_1(LOW); + #if HOTENDS > 2 + if (soft_pwm_count_2 <= pwm_count_tmp) WRITE_HEATER_2(LOW); + #if HOTENDS > 3 + if (soft_pwm_count_3 <= pwm_count_tmp) WRITE_HEATER_3(LOW); + #if HOTENDS > 4 + if (soft_pwm_count_4 <= pwm_count_tmp) WRITE_HEATER_4(LOW); + #endif // HOTENDS > 4 + #endif // HOTENDS > 3 + #endif // HOTENDS > 2 + #endif // HOTENDS > 1 + + #if HAS_HEATER_BED + if (soft_pwm_count_BED <= pwm_count_tmp) WRITE_HEATER_BED(LOW); + #endif + + #if ENABLED(FAN_SOFT_PWM) + #if HAS_FAN0 + if (soft_pwm_count_fan[0] <= pwm_count_tmp) WRITE_FAN(LOW); + #endif + #if HAS_FAN1 + if (soft_pwm_count_fan[1] <= pwm_count_tmp) WRITE_FAN1(LOW); + #endif + #if HAS_FAN2 + if (soft_pwm_count_fan[2] <= pwm_count_tmp) WRITE_FAN2(LOW); + #endif + #endif + } + + // SOFT_PWM_SCALE to frequency: + // + // 0: 16000000/64/256/128 = 7.6294 Hz + // 1: / 64 = 15.2588 Hz + // 2: / 32 = 30.5176 Hz + // 3: / 16 = 61.0352 Hz + // 4: / 8 = 122.0703 Hz + // 5: / 4 = 244.1406 Hz + pwm_count = pwm_count_tmp + _BV(SOFT_PWM_SCALE); + + #else // SLOW_PWM_HEATERS + + /** + * SLOW PWM HEATERS + * + * For relay-driven heaters + */ + #ifndef MIN_STATE_TIME + #define MIN_STATE_TIME 16 // MIN_STATE_TIME * 65.5 = time in milliseconds + #endif + + // Macros for Slow PWM timer logic + #define _SLOW_PWM_ROUTINE(NR, src) \ + soft_pwm_ ##NR = src; \ + if (soft_pwm_ ##NR > 0) { \ + if (state_timer_heater_ ##NR == 0) { \ + if (state_heater_ ##NR == 0) state_timer_heater_ ##NR = MIN_STATE_TIME; \ + state_heater_ ##NR = 1; \ + WRITE_HEATER_ ##NR(1); \ + } \ + } \ + else { \ + if (state_timer_heater_ ##NR == 0) { \ + if (state_heater_ ##NR == 1) state_timer_heater_ ##NR = MIN_STATE_TIME; \ + state_heater_ ##NR = 0; \ + WRITE_HEATER_ ##NR(0); \ + } \ + } + #define SLOW_PWM_ROUTINE(n) _SLOW_PWM_ROUTINE(n, soft_pwm_amount[n]) + + #define PWM_OFF_ROUTINE(NR) \ + if (soft_pwm_ ##NR < slow_pwm_count) { \ + if (state_timer_heater_ ##NR == 0) { \ + if (state_heater_ ##NR == 1) state_timer_heater_ ##NR = MIN_STATE_TIME; \ + state_heater_ ##NR = 0; \ + WRITE_HEATER_ ##NR (0); \ + } \ + } + + if (slow_pwm_count == 0) { + + SLOW_PWM_ROUTINE(0); + #if HOTENDS > 1 + SLOW_PWM_ROUTINE(1); + #if HOTENDS > 2 + SLOW_PWM_ROUTINE(2); + #if HOTENDS > 3 + SLOW_PWM_ROUTINE(3); + #if HOTENDS > 4 + SLOW_PWM_ROUTINE(4); + #endif // HOTENDS > 4 + #endif // HOTENDS > 3 + #endif // HOTENDS > 2 + #endif // HOTENDS > 1 + #if HAS_HEATER_BED + _SLOW_PWM_ROUTINE(BED, soft_pwm_amount_bed); // BED + #endif + + } // slow_pwm_count == 0 + + PWM_OFF_ROUTINE(0); + #if HOTENDS > 1 + PWM_OFF_ROUTINE(1); + #if HOTENDS > 2 + PWM_OFF_ROUTINE(2); + #if HOTENDS > 3 + PWM_OFF_ROUTINE(3); + #if HOTENDS > 4 + PWM_OFF_ROUTINE(4); + #endif // HOTENDS > 4 + #endif // HOTENDS > 3 + #endif // HOTENDS > 2 + #endif // HOTENDS > 1 + #if HAS_HEATER_BED + PWM_OFF_ROUTINE(BED); // BED + #endif + + #if ENABLED(FAN_SOFT_PWM) + if (pwm_count_tmp >= 127) { + pwm_count_tmp = 0; + #if HAS_FAN0 + soft_pwm_count_fan[0] = soft_pwm_amount_fan[0] >> 1; + WRITE_FAN(soft_pwm_count_fan[0] > 0 ? HIGH : LOW); + #endif + #if HAS_FAN1 + soft_pwm_count_fan[1] = soft_pwm_amount_fan[1] >> 1; + WRITE_FAN1(soft_pwm_count_fan[1] > 0 ? HIGH : LOW); + #endif + #if HAS_FAN2 + soft_pwm_count_fan[2] = soft_pwm_amount_fan[2] >> 1; + WRITE_FAN2(soft_pwm_count_fan[2] > 0 ? HIGH : LOW); + #endif + } + #if HAS_FAN0 + if (soft_pwm_count_fan[0] <= pwm_count_tmp) WRITE_FAN(LOW); + #endif + #if HAS_FAN1 + if (soft_pwm_count_fan[1] <= pwm_count_tmp) WRITE_FAN1(LOW); + #endif + #if HAS_FAN2 + if (soft_pwm_count_fan[2] <= pwm_count_tmp) WRITE_FAN2(LOW); + #endif + #endif // FAN_SOFT_PWM + + // SOFT_PWM_SCALE to frequency: + // + // 0: 16000000/64/256/128 = 7.6294 Hz + // 1: / 64 = 15.2588 Hz + // 2: / 32 = 30.5176 Hz + // 3: / 16 = 61.0352 Hz + // 4: / 8 = 122.0703 Hz + // 5: / 4 = 244.1406 Hz + pwm_count = pwm_count_tmp + _BV(SOFT_PWM_SCALE); + + // increment slow_pwm_count only every 64th pwm_count, + // i.e. yielding a PWM frequency of 16/128 Hz (8s). + if (((pwm_count >> SOFT_PWM_SCALE) & 0x3F) == 0) { + slow_pwm_count++; + slow_pwm_count &= 0x7F; + + if (state_timer_heater_0 > 0) state_timer_heater_0--; + #if HOTENDS > 1 + if (state_timer_heater_1 > 0) state_timer_heater_1--; + #if HOTENDS > 2 + if (state_timer_heater_2 > 0) state_timer_heater_2--; + #if HOTENDS > 3 + if (state_timer_heater_3 > 0) state_timer_heater_3--; + #if HOTENDS > 4 + if (state_timer_heater_4 > 0) state_timer_heater_4--; + #endif // HOTENDS > 4 + #endif // HOTENDS > 3 + #endif // HOTENDS > 2 + #endif // HOTENDS > 1 + #if HAS_HEATER_BED + if (state_timer_heater_BED > 0) state_timer_heater_BED--; + #endif + } // ((pwm_count >> SOFT_PWM_SCALE) & 0x3F) == 0 + + #endif // SLOW_PWM_HEATERS + + // + // Update lcd buttons 488 times per second + // + static bool do_buttons; + if ((do_buttons ^= true)) lcd_buttons_update(); + + /** + * One sensor is sampled on every other call of the ISR. + * Each sensor is read 16 (OVERSAMPLENR) times, taking the average. + * + * On each Prepare pass, ADC is started for a sensor pin. + * On the next pass, the ADC value is read and accumulated. + * + * This gives each ADC 0.9765ms to charge up. + */ + + #define SET_ADMUX_ADCSRA(pin) ADMUX = _BV(REFS0) | (pin & 0x07); SBI(ADCSRA, ADSC) + #ifdef MUX5 + #define START_ADC(pin) if (pin > 7) ADCSRB = _BV(MUX5); else ADCSRB = 0; SET_ADMUX_ADCSRA(pin) + #else + #define START_ADC(pin) ADCSRB = 0; SET_ADMUX_ADCSRA(pin) + #endif + + switch (adc_sensor_state) { + + case SensorsReady: { + // All sensors have been read. Stay in this state for a few + // ISRs to save on calls to temp update/checking code below. + constexpr int8_t extra_loops = MIN_ADC_ISR_LOOPS - (int8_t)SensorsReady; + static uint8_t delay_count = 0; + if (extra_loops > 0) { + if (delay_count == 0) delay_count = extra_loops; // Init this delay + if (--delay_count) // While delaying... + adc_sensor_state = (ADCSensorState)(int(SensorsReady) - 1); // retain this state (else, next state will be 0) + break; + } + else + adc_sensor_state = (ADCSensorState)0; // Fall-through to start first sensor now + } + + #if HAS_TEMP_0 + case PrepareTemp_0: + START_ADC(TEMP_0_PIN); + break; + case MeasureTemp_0: + raw_temp_value[0] += ADC; + break; + #endif + + #if HAS_TEMP_BED + case PrepareTemp_BED: + START_ADC(TEMP_BED_PIN); + break; + case MeasureTemp_BED: + raw_temp_bed_value += ADC; + break; + #endif + + #if HAS_TEMP_1 + case PrepareTemp_1: + START_ADC(TEMP_1_PIN); + break; + case MeasureTemp_1: + raw_temp_value[1] += ADC; + break; + #endif + + #if HAS_TEMP_2 + case PrepareTemp_2: + START_ADC(TEMP_2_PIN); + break; + case MeasureTemp_2: + raw_temp_value[2] += ADC; + break; + #endif + + #if HAS_TEMP_3 + case PrepareTemp_3: + START_ADC(TEMP_3_PIN); + break; + case MeasureTemp_3: + raw_temp_value[3] += ADC; + break; + #endif + + #if HAS_TEMP_4 + case PrepareTemp_4: + START_ADC(TEMP_4_PIN); + break; + case MeasureTemp_4: + raw_temp_value[4] += ADC; + break; + #endif + + #if ENABLED(FILAMENT_WIDTH_SENSOR) + case Prepare_FILWIDTH: + START_ADC(FILWIDTH_PIN); + break; + case Measure_FILWIDTH: + if (ADC > 102) { // Make sure ADC is reading > 0.5 volts, otherwise don't read. + raw_filwidth_value -= (raw_filwidth_value >> 7); // Subtract 1/128th of the raw_filwidth_value + raw_filwidth_value += ((unsigned long)ADC << 7); // Add new ADC reading, scaled by 128 + } + break; + #endif + + #if ENABLED(ADC_KEYPAD) + case Prepare_ADC_KEY: + START_ADC(ADC_KEYPAD_PIN); + break; + case Measure_ADC_KEY: + if (ADCKey_count < 16) { + raw_ADCKey_value = ADC; + if (raw_ADCKey_value > 900) { + //ADC Key release + ADCKey_count = 0; + current_ADCKey_raw = 0; + } + else { + current_ADCKey_raw += raw_ADCKey_value; + ADCKey_count++; + } + } + break; + #endif // ADC_KEYPAD + + case StartupDelay: break; + + } // switch(adc_sensor_state) + + if (!adc_sensor_state && ++temp_count >= OVERSAMPLENR) { // 10 * 16 * 1/(16000000/64/256) = 164ms. + + temp_count = 0; + + // Update the raw values if they've been read. Else we could be updating them during reading. + if (!temp_meas_ready) set_current_temp_raw(); + + // Filament Sensor - can be read any time since IIR filtering is used + #if ENABLED(FILAMENT_WIDTH_SENSOR) + current_raw_filwidth = raw_filwidth_value >> 10; // Divide to get to 0-16384 range since we used 1/128 IIR filter approach + #endif + + ZERO(raw_temp_value); + raw_temp_bed_value = 0; + + #define TEMPDIR(N) ((HEATER_##N##_RAW_LO_TEMP) > (HEATER_##N##_RAW_HI_TEMP) ? -1 : 1) + + int constexpr temp_dir[] = { + #if ENABLED(HEATER_0_USES_MAX6675) + 0 + #else + TEMPDIR(0) + #endif + #if HOTENDS > 1 + , TEMPDIR(1) + #if HOTENDS > 2 + , TEMPDIR(2) + #if HOTENDS > 3 + , TEMPDIR(3) + #if HOTENDS > 4 + , TEMPDIR(4) + #endif // HOTENDS > 4 + #endif // HOTENDS > 3 + #endif // HOTENDS > 2 + #endif // HOTENDS > 1 + }; + + for (uint8_t e = 0; e < COUNT(temp_dir); e++) { + const int16_t tdir = temp_dir[e], rawtemp = current_temperature_raw[e] * tdir; + if (rawtemp > maxttemp_raw[e] * tdir && target_temperature[e] > 0) max_temp_error(e); + if (rawtemp < minttemp_raw[e] * tdir && !is_preheating(e) && target_temperature[e] > 0) { + #ifdef MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED + if (++consecutive_low_temperature_error[e] >= MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED) + #endif + min_temp_error(e); + } + #ifdef MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED + else + consecutive_low_temperature_error[e] = 0; + #endif + } + + #if HAS_TEMP_BED + #if HEATER_BED_RAW_LO_TEMP > HEATER_BED_RAW_HI_TEMP + #define GEBED <= + #else + #define GEBED >= + #endif + if (current_temperature_bed_raw GEBED bed_maxttemp_raw && target_temperature_bed > 0) max_temp_error(-1); + if (bed_minttemp_raw GEBED current_temperature_bed_raw && target_temperature_bed > 0) min_temp_error(-1); + #endif + + } // temp_count >= OVERSAMPLENR + + // Go to the next state, up to SensorsReady + adc_sensor_state = (ADCSensorState)((int(adc_sensor_state) + 1) % int(StartupDelay)); + + #if ENABLED(BABYSTEPPING) + LOOP_XYZ(axis) { + const int curTodo = babystepsTodo[axis]; // get rid of volatile for performance + if (curTodo) { + stepper.babystep((AxisEnum)axis, curTodo > 0); + if (curTodo > 0) babystepsTodo[axis]--; + else babystepsTodo[axis]++; + } + } + #endif // BABYSTEPPING + + #if ENABLED(PINS_DEBUGGING) + extern bool endstop_monitor_flag; + // run the endstop monitor at 15Hz + static uint8_t endstop_monitor_count = 16; // offset this check from the others + if (endstop_monitor_flag) { + endstop_monitor_count += _BV(1); // 15 Hz + endstop_monitor_count &= 0x7F; + if (!endstop_monitor_count) endstop_monitor(); // report changes in endstop status + } + #endif + + #if ENABLED(ENDSTOP_INTERRUPTS_FEATURE) + + extern volatile uint8_t e_hit; + + if (e_hit && ENDSTOPS_ENABLED) { + endstops.update(); // call endstop update routine + e_hit--; + } + #endif + + cli(); + in_temp_isr = false; + SBI(TIMSK0, OCIE0B); //re-enable Temperature ISR +} diff --git a/trunk/Arduino/Marlin_1.1.6/temperature.h b/trunk/Arduino/Marlin_1.1.6/temperature.h new file mode 100644 index 00000000..6ce644d8 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/temperature.h @@ -0,0 +1,578 @@ +/** + * 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 . + * + */ + +/** + * temperature.h - temperature controller + */ + +#ifndef TEMPERATURE_H +#define TEMPERATURE_H + +#include "thermistortables.h" + +#include "MarlinConfig.h" + +#if ENABLED(PID_EXTRUSION_SCALING) + #include "stepper.h" +#endif + +#ifndef SOFT_PWM_SCALE + #define SOFT_PWM_SCALE 0 +#endif + +#define HOTEND_LOOP() for (int8_t e = 0; e < HOTENDS; e++) + +#if HOTENDS == 1 + #define HOTEND_INDEX 0 + #define EXTRUDER_IDX 0 +#else + #define HOTEND_INDEX e + #define EXTRUDER_IDX active_extruder +#endif + +/** + * States for ADC reading in the ISR + */ +enum ADCSensorState { + #if HAS_TEMP_0 + PrepareTemp_0, + MeasureTemp_0, + #endif + #if HAS_TEMP_1 + PrepareTemp_1, + MeasureTemp_1, + #endif + #if HAS_TEMP_2 + PrepareTemp_2, + MeasureTemp_2, + #endif + #if HAS_TEMP_3 + PrepareTemp_3, + MeasureTemp_3, + #endif + #if HAS_TEMP_4 + PrepareTemp_4, + MeasureTemp_4, + #endif + #if HAS_TEMP_BED + PrepareTemp_BED, + MeasureTemp_BED, + #endif + #if ENABLED(FILAMENT_WIDTH_SENSOR) + Prepare_FILWIDTH, + Measure_FILWIDTH, + #endif + #if ENABLED(ADC_KEYPAD) + Prepare_ADC_KEY, + Measure_ADC_KEY, + #endif + SensorsReady, // Temperatures ready. Delay the next round of readings to let ADC pins settle. + StartupDelay // Startup, delay initial temp reading a tiny bit so the hardware can settle +}; + +// Minimum number of Temperature::ISR loops between sensor readings. +// Multiplied by 16 (OVERSAMPLENR) to obtain the total time to +// get all oversampled sensor readings +#define MIN_ADC_ISR_LOOPS 10 + +#define ACTUAL_ADC_SAMPLES max(int(MIN_ADC_ISR_LOOPS), int(SensorsReady)) + +#if !HAS_HEATER_BED + constexpr int16_t target_temperature_bed = 0; +#endif + +class Temperature { + + public: + + static float current_temperature[HOTENDS], + current_temperature_bed; + static int16_t current_temperature_raw[HOTENDS], + target_temperature[HOTENDS], + current_temperature_bed_raw; + + #if HAS_HEATER_BED + static int16_t target_temperature_bed; + #endif + + static volatile bool in_temp_isr; + + static uint8_t soft_pwm_amount[HOTENDS], + soft_pwm_amount_bed; + + #if ENABLED(FAN_SOFT_PWM) + static uint8_t soft_pwm_amount_fan[FAN_COUNT], + soft_pwm_count_fan[FAN_COUNT]; + #endif + + #if ENABLED(PIDTEMP) || ENABLED(PIDTEMPBED) + #define PID_dT ((OVERSAMPLENR * float(ACTUAL_ADC_SAMPLES)) / (F_CPU / 64.0 / 256.0)) + #endif + + #if ENABLED(PIDTEMP) + + #if ENABLED(PID_PARAMS_PER_HOTEND) && HOTENDS > 1 + + static float Kp[HOTENDS], Ki[HOTENDS], Kd[HOTENDS]; + #if ENABLED(PID_EXTRUSION_SCALING) + static float Kc[HOTENDS]; + #endif + #define PID_PARAM(param, h) Temperature::param[h] + + #else + + static float Kp, Ki, Kd; + #if ENABLED(PID_EXTRUSION_SCALING) + static float Kc; + #endif + #define PID_PARAM(param, h) Temperature::param + + #endif // PID_PARAMS_PER_HOTEND + + // Apply the scale factors to the PID values + #define scalePID_i(i) ( (i) * PID_dT ) + #define unscalePID_i(i) ( (i) / PID_dT ) + #define scalePID_d(d) ( (d) / PID_dT ) + #define unscalePID_d(d) ( (d) * PID_dT ) + + #endif + + #if ENABLED(PIDTEMPBED) + static float bedKp, bedKi, bedKd; + #endif + + #if ENABLED(BABYSTEPPING) + static volatile int babystepsTodo[3]; + #endif + + #if WATCH_HOTENDS + static uint16_t watch_target_temp[HOTENDS]; + static millis_t watch_heater_next_ms[HOTENDS]; + #endif + + #if WATCH_THE_BED + static uint16_t watch_target_bed_temp; + static millis_t watch_bed_next_ms; + #endif + + #if ENABLED(PREVENT_COLD_EXTRUSION) + static bool allow_cold_extrude; + static int16_t extrude_min_temp; + static bool tooColdToExtrude(uint8_t e) { + #if HOTENDS == 1 + UNUSED(e); + #endif + return allow_cold_extrude ? false : degHotend(HOTEND_INDEX) < extrude_min_temp; + } + #else + static bool tooColdToExtrude(uint8_t e) { UNUSED(e); return false; } + #endif + + private: + + #if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT) + static uint16_t redundant_temperature_raw; + static float redundant_temperature; + #endif + + static volatile bool temp_meas_ready; + + #if ENABLED(PIDTEMP) + static float temp_iState[HOTENDS], + temp_dState[HOTENDS], + pTerm[HOTENDS], + iTerm[HOTENDS], + dTerm[HOTENDS]; + + #if ENABLED(PID_EXTRUSION_SCALING) + static float cTerm[HOTENDS]; + static long last_e_position; + static long lpq[LPQ_MAX_LEN]; + static int lpq_ptr; + #endif + + static float pid_error[HOTENDS]; + static bool pid_reset[HOTENDS]; + #endif + + #if ENABLED(PIDTEMPBED) + static float temp_iState_bed, + temp_dState_bed, + pTerm_bed, + iTerm_bed, + dTerm_bed, + pid_error_bed; + #else + static millis_t next_bed_check_ms; + #endif + + static uint16_t raw_temp_value[MAX_EXTRUDERS], + raw_temp_bed_value; + + // Init min and max temp with extreme values to prevent false errors during startup + static int16_t minttemp_raw[HOTENDS], + maxttemp_raw[HOTENDS], + minttemp[HOTENDS], + maxttemp[HOTENDS]; + + #ifdef MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED + static uint8_t consecutive_low_temperature_error[HOTENDS]; + #endif + + #ifdef MILLISECONDS_PREHEAT_TIME + static millis_t preheat_end_time[HOTENDS]; + #endif + + #ifdef BED_MINTEMP + static int16_t bed_minttemp_raw; + #endif + + #ifdef BED_MAXTEMP + static int16_t bed_maxttemp_raw; + #endif + + #if ENABLED(FILAMENT_WIDTH_SENSOR) + static int8_t meas_shift_index; // Index of a delayed sample in buffer + #endif + + #if HAS_AUTO_FAN + static millis_t next_auto_fan_check_ms; + #endif + + #if ENABLED(FILAMENT_WIDTH_SENSOR) + static uint16_t current_raw_filwidth; // Measured filament diameter - one extruder only + #endif + + #if ENABLED(PROBING_HEATERS_OFF) + static bool paused; + #endif + + #if HEATER_IDLE_HANDLER + static millis_t heater_idle_timeout_ms[HOTENDS]; + static bool heater_idle_timeout_exceeded[HOTENDS]; + #if HAS_TEMP_BED + static millis_t bed_idle_timeout_ms; + static bool bed_idle_timeout_exceeded; + #endif + #endif + + public: + #if ENABLED(ADC_KEYPAD) + static uint32_t current_ADCKey_raw; + static uint8_t ADCKey_count; + #endif + + /** + * Instance Methods + */ + + Temperature(); + + void init(); + + /** + * Static (class) methods + */ + static float analog2temp(int raw, uint8_t e); + static float analog2tempBed(int raw); + + /** + * Called from the Temperature ISR + */ + static void isr(); + + /** + * Call periodically to manage heaters + */ + static void manage_heater() _O2; // Added _O2 to work around a compiler error + + /** + * Preheating hotends + */ + #ifdef MILLISECONDS_PREHEAT_TIME + static bool is_preheating(uint8_t e) { + #if HOTENDS == 1 + UNUSED(e); + #endif + return preheat_end_time[HOTEND_INDEX] && PENDING(millis(), preheat_end_time[HOTEND_INDEX]); + } + static void start_preheat_time(uint8_t e) { + #if HOTENDS == 1 + UNUSED(e); + #endif + preheat_end_time[HOTEND_INDEX] = millis() + MILLISECONDS_PREHEAT_TIME; + } + static void reset_preheat_time(uint8_t e) { + #if HOTENDS == 1 + UNUSED(e); + #endif + preheat_end_time[HOTEND_INDEX] = 0; + } + #else + #define is_preheating(n) (false) + #endif + + #if ENABLED(FILAMENT_WIDTH_SENSOR) + static float analog2widthFil(); // Convert raw Filament Width to millimeters + static int widthFil_to_size_ratio(); // Convert raw Filament Width to an extrusion ratio + #endif + + + //high level conversion routines, for use outside of temperature.cpp + //inline so that there is no performance decrease. + //deg=degreeCelsius + + static float degHotend(uint8_t e) { + #if HOTENDS == 1 + UNUSED(e); + #endif + return current_temperature[HOTEND_INDEX]; + } + static float degBed() { return current_temperature_bed; } + + #if ENABLED(SHOW_TEMP_ADC_VALUES) + static int16_t rawHotendTemp(uint8_t e) { + #if HOTENDS == 1 + UNUSED(e); + #endif + return current_temperature_raw[HOTEND_INDEX]; + } + static int16_t rawBedTemp() { return current_temperature_bed_raw; } + #endif + + static int16_t degTargetHotend(uint8_t e) { + #if HOTENDS == 1 + UNUSED(e); + #endif + return target_temperature[HOTEND_INDEX]; + } + + static int16_t degTargetBed() { return target_temperature_bed; } + + #if WATCH_HOTENDS + static void start_watching_heater(uint8_t e = 0); + #endif + + #if WATCH_THE_BED + static void start_watching_bed(); + #endif + + static void setTargetHotend(const int16_t celsius, uint8_t e) { + #if HOTENDS == 1 + UNUSED(e); + #endif + #ifdef MILLISECONDS_PREHEAT_TIME + if (celsius == 0) + reset_preheat_time(HOTEND_INDEX); + else if (target_temperature[HOTEND_INDEX] == 0) + start_preheat_time(HOTEND_INDEX); + #endif + target_temperature[HOTEND_INDEX] = celsius; + #if WATCH_HOTENDS + start_watching_heater(HOTEND_INDEX); + #endif + } + + static void setTargetBed(const int16_t celsius) { + #if HAS_HEATER_BED + target_temperature_bed = + #ifdef BED_MAXTEMP + min(celsius, BED_MAXTEMP) + #else + celsius + #endif + ; + #if WATCH_THE_BED + start_watching_bed(); + #endif + #endif + } + + static bool isHeatingHotend(uint8_t e) { + #if HOTENDS == 1 + UNUSED(e); + #endif + return target_temperature[HOTEND_INDEX] > current_temperature[HOTEND_INDEX]; + } + static bool isHeatingBed() { return target_temperature_bed > current_temperature_bed; } + + static bool isCoolingHotend(uint8_t e) { + #if HOTENDS == 1 + UNUSED(e); + #endif + return target_temperature[HOTEND_INDEX] < current_temperature[HOTEND_INDEX]; + } + static bool isCoolingBed() { return target_temperature_bed < current_temperature_bed; } + + /** + * The software PWM power for a heater + */ + static int getHeaterPower(int heater); + + /** + * Switch off all heaters, set all target temperatures to 0 + */ + static void disable_all_heaters(); + + /** + * Perform auto-tuning for hotend or bed in response to M303 + */ + #if HAS_PID_HEATING + static void PID_autotune(float temp, int hotend, int ncycles, bool set_result=false); + #endif + + /** + * Update the temp manager when PID values change + */ + static void updatePID(); + + #if ENABLED(BABYSTEPPING) + + static void babystep_axis(const AxisEnum axis, const int distance) { + if (axis_known_position[axis]) { + #if IS_CORE + #if ENABLED(BABYSTEP_XY) + switch (axis) { + case CORE_AXIS_1: // X on CoreXY and CoreXZ, Y on CoreYZ + babystepsTodo[CORE_AXIS_1] += distance * 2; + babystepsTodo[CORE_AXIS_2] += distance * 2; + break; + case CORE_AXIS_2: // Y on CoreXY, Z on CoreXZ and CoreYZ + babystepsTodo[CORE_AXIS_1] += CORESIGN(distance * 2); + babystepsTodo[CORE_AXIS_2] -= CORESIGN(distance * 2); + break; + case NORMAL_AXIS: // Z on CoreXY, Y on CoreXZ, X on CoreYZ + babystepsTodo[NORMAL_AXIS] += distance; + break; + } + #elif CORE_IS_XZ || CORE_IS_YZ + // Only Z stepping needs to be handled here + babystepsTodo[CORE_AXIS_1] += CORESIGN(distance * 2); + babystepsTodo[CORE_AXIS_2] -= CORESIGN(distance * 2); + #else + babystepsTodo[Z_AXIS] += distance; + #endif + #else + babystepsTodo[axis] += distance; + #endif + } + } + + #endif // BABYSTEPPING + + #if ENABLED(PROBING_HEATERS_OFF) + static void pause(const bool p); + static bool is_paused() { return paused; } + #endif + + #if HEATER_IDLE_HANDLER + static void start_heater_idle_timer(uint8_t e, millis_t timeout_ms) { + #if HOTENDS == 1 + UNUSED(e); + #endif + heater_idle_timeout_ms[HOTEND_INDEX] = millis() + timeout_ms; + heater_idle_timeout_exceeded[HOTEND_INDEX] = false; + } + + static void reset_heater_idle_timer(uint8_t e) { + #if HOTENDS == 1 + UNUSED(e); + #endif + heater_idle_timeout_ms[HOTEND_INDEX] = 0; + heater_idle_timeout_exceeded[HOTEND_INDEX] = false; + #if WATCH_HOTENDS + start_watching_heater(HOTEND_INDEX); + #endif + } + + static bool is_heater_idle(uint8_t e) { + #if HOTENDS == 1 + UNUSED(e); + #endif + return heater_idle_timeout_exceeded[HOTEND_INDEX]; + } + + #if HAS_TEMP_BED + static void start_bed_idle_timer(millis_t timeout_ms) { + bed_idle_timeout_ms = millis() + timeout_ms; + bed_idle_timeout_exceeded = false; + } + + static void reset_bed_idle_timer() { + bed_idle_timeout_ms = 0; + bed_idle_timeout_exceeded = false; + #if WATCH_THE_BED + start_watching_bed(); + #endif + } + + static bool is_bed_idle() { + return bed_idle_timeout_exceeded; + } + #endif + #endif + + private: + + static void set_current_temp_raw(); + + static void updateTemperaturesFromRawValues(); + + #if ENABLED(HEATER_0_USES_MAX6675) + static int read_max6675(); + #endif + + static void checkExtruderAutoFans(); + + static float get_pid_output(const int8_t e); + + #if ENABLED(PIDTEMPBED) + static float get_pid_output_bed(); + #endif + + static void _temp_error(const int8_t e, const char * const serial_msg, const char * const lcd_msg); + static void min_temp_error(const int8_t e); + static void max_temp_error(const int8_t e); + + #if ENABLED(THERMAL_PROTECTION_HOTENDS) || HAS_THERMALLY_PROTECTED_BED + + typedef enum TRState { TRInactive, TRFirstHeating, TRStable, TRRunaway } TRstate; + + static void thermal_runaway_protection(TRState* state, millis_t* timer, float temperature, float target_temperature, int heater_id, int period_seconds, int hysteresis_degc); + + #if ENABLED(THERMAL_PROTECTION_HOTENDS) + static TRState thermal_runaway_state_machine[HOTENDS]; + static millis_t thermal_runaway_timer[HOTENDS]; + #endif + + #if HAS_THERMALLY_PROTECTED_BED + static TRState thermal_runaway_bed_state_machine; + static millis_t thermal_runaway_bed_timer; + #endif + + #endif // THERMAL_PROTECTION + +}; + +extern Temperature thermalManager; + +#endif // TEMPERATURE_H diff --git a/trunk/Arduino/Marlin_1.1.6/thermistornames.h b/trunk/Arduino/Marlin_1.1.6/thermistornames.h new file mode 100644 index 00000000..2e672a45 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/thermistornames.h @@ -0,0 +1,97 @@ +/** + * 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 . + * + */ + +#undef THERMISTOR_NAME + +// Thermcouples +#if THERMISTOR_ID == -3 + #define THERMISTOR_NAME "MAX31855" +#elif THERMISTOR_ID == -2 + #define THERMISTOR_NAME "MAX6675" +#elif THERMISTOR_ID == -1 + #define THERMISTOR_NAME "AD595" + +// Standard thermistors +#elif THERMISTOR_ID == 1 + #define THERMISTOR_NAME "EPCOS 100K" +#elif THERMISTOR_ID == 2 + #define THERMISTOR_NAME "ATC 204GT-2" +#elif THERMISTOR_ID == 3 + #define THERMISTOR_NAME "Mendel-parts" +#elif THERMISTOR_ID == 4 + #define THERMISTOR_NAME "Generic 10K" +#elif THERMISTOR_ID == 5 + #define THERMISTOR_NAME "ATC 104GT-2" +#elif THERMISTOR_ID == 6 + #define THERMISTOR_NAME "EPCOS (alt)" +#elif THERMISTOR_ID == 7 + #define THERMISTOR_NAME "HW 104LAG" +#elif THERMISTOR_ID == 71 + #define THERMISTOR_NAME "HW 104LAF" +#elif THERMISTOR_ID == 8 + #define THERMISTOR_NAME "E3104FXT" +#elif THERMISTOR_ID == 9 + #define THERMISTOR_NAME "GE AL03006" +#elif THERMISTOR_ID == 10 + #define THERMISTOR_NAME "RS 198-961" +#elif THERMISTOR_ID == 11 + #define THERMISTOR_NAME "1% beta 3950" +#elif THERMISTOR_ID == 12 + #define THERMISTOR_NAME "E3104FXT (alt)" +#elif THERMISTOR_ID == 13 + #define THERMISTOR_NAME "Hisens 3950" +#elif THERMISTOR_ID == 20 + #define THERMISTOR_NAME "PT100 UltiMB" +#elif THERMISTOR_ID == 60 + #define THERMISTOR_NAME "Makers Tool" +#elif THERMISTOR_ID == 70 + #define THERMISTOR_NAME "Hephestos 2" +#elif THERMISTOR_ID == 75 + #define THERMISTOR_NAME "MGB18" + +// Modified thermistors +#elif THERMISTOR_ID == 51 + #define THERMISTOR_NAME "EPCOS 1K" +#elif THERMISTOR_ID == 52 + #define THERMISTOR_NAME "ATC204GT-2 1K" +#elif THERMISTOR_ID == 55 + #define THERMISTOR_NAME "ATC104GT-2 1K" +#elif THERMISTOR_ID == 1047 + #define THERMISTOR_NAME "PT1000 4K7" +#elif THERMISTOR_ID == 1010 + #define THERMISTOR_NAME "PT1000 1K" +#elif THERMISTOR_ID == 147 + #define THERMISTOR_NAME "PT100 4K7" +#elif THERMISTOR_ID == 110 + #define THERMISTOR_NAME "PT100 1K" + +// High Temperature thermistors +#elif THERMISTOR_ID == 66 + #define THERMISTOR_NAME "Dyze 4.7M" + +// Dummies for dev testing +#elif THERMISTOR_ID == 998 + #define THERMISTOR_NAME "Dummy 1" +#elif THERMISTOR_ID == 999 + #define THERMISTOR_NAME "Dummy 2" + +#endif // THERMISTOR_ID diff --git a/trunk/Arduino/Marlin_1.1.6/thermistortable_1.h b/trunk/Arduino/Marlin_1.1.6/thermistortable_1.h new file mode 100644 index 00000000..b1a91b5e --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/thermistortable_1.h @@ -0,0 +1,89 @@ +/** + * 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 . + * + */ + +// 100k bed thermistor +const short temptable_1[][2] PROGMEM = { + { 23 * OVERSAMPLENR, 300 }, + { 25 * OVERSAMPLENR, 295 }, + { 27 * OVERSAMPLENR, 290 }, + { 28 * OVERSAMPLENR, 285 }, + { 31 * OVERSAMPLENR, 280 }, + { 33 * OVERSAMPLENR, 275 }, + { 35 * OVERSAMPLENR, 270 }, + { 38 * OVERSAMPLENR, 265 }, + { 41 * OVERSAMPLENR, 260 }, + { 44 * OVERSAMPLENR, 255 }, + { 48 * OVERSAMPLENR, 250 }, + { 52 * OVERSAMPLENR, 245 }, + { 56 * OVERSAMPLENR, 240 }, + { 61 * OVERSAMPLENR, 235 }, + { 66 * OVERSAMPLENR, 230 }, + { 71 * OVERSAMPLENR, 225 }, + { 78 * OVERSAMPLENR, 220 }, + { 84 * OVERSAMPLENR, 215 }, + { 92 * OVERSAMPLENR, 210 }, + { 100 * OVERSAMPLENR, 205 }, + { 109 * OVERSAMPLENR, 200 }, + { 120 * OVERSAMPLENR, 195 }, + { 131 * OVERSAMPLENR, 190 }, + { 143 * OVERSAMPLENR, 185 }, + { 156 * OVERSAMPLENR, 180 }, + { 171 * OVERSAMPLENR, 175 }, + { 187 * OVERSAMPLENR, 170 }, + { 205 * OVERSAMPLENR, 165 }, + { 224 * OVERSAMPLENR, 160 }, + { 245 * OVERSAMPLENR, 155 }, + { 268 * OVERSAMPLENR, 150 }, + { 293 * OVERSAMPLENR, 145 }, + { 320 * OVERSAMPLENR, 140 }, + { 348 * OVERSAMPLENR, 135 }, + { 379 * OVERSAMPLENR, 130 }, + { 411 * OVERSAMPLENR, 125 }, + { 445 * OVERSAMPLENR, 120 }, + { 480 * OVERSAMPLENR, 115 }, + { 516 * OVERSAMPLENR, 110 }, + { 553 * OVERSAMPLENR, 105 }, + { 591 * OVERSAMPLENR, 100 }, + { 628 * OVERSAMPLENR, 95 }, + { 665 * OVERSAMPLENR, 90 }, + { 702 * OVERSAMPLENR, 85 }, + { 737 * OVERSAMPLENR, 80 }, + { 770 * OVERSAMPLENR, 75 }, + { 801 * OVERSAMPLENR, 70 }, + { 830 * OVERSAMPLENR, 65 }, + { 857 * OVERSAMPLENR, 60 }, + { 881 * OVERSAMPLENR, 55 }, + { 903 * OVERSAMPLENR, 50 }, + { 922 * OVERSAMPLENR, 45 }, + { 939 * OVERSAMPLENR, 40 }, + { 954 * OVERSAMPLENR, 35 }, + { 966 * OVERSAMPLENR, 30 }, + { 977 * OVERSAMPLENR, 25 }, + { 985 * OVERSAMPLENR, 20 }, + { 993 * OVERSAMPLENR, 15 }, + { 999 * OVERSAMPLENR, 10 }, + { 1004 * OVERSAMPLENR, 5 }, + { 1008 * OVERSAMPLENR, 0 }, + { 1012 * OVERSAMPLENR, -5 }, + { 1016 * OVERSAMPLENR, -10 }, + { 1020 * OVERSAMPLENR, -15 } +}; diff --git a/trunk/Arduino/Marlin_1.1.6/thermistortable_10.h b/trunk/Arduino/Marlin_1.1.6/thermistortable_10.h new file mode 100644 index 00000000..a031648a --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/thermistortable_10.h @@ -0,0 +1,56 @@ +/** + * 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 . + * + */ + +// 100k RS thermistor 198-961 (4.7k pullup) +const short temptable_10[][2] PROGMEM = { + { 1 * OVERSAMPLENR, 929 }, + { 36 * OVERSAMPLENR, 299 }, + { 71 * OVERSAMPLENR, 246 }, + { 106 * OVERSAMPLENR, 217 }, + { 141 * OVERSAMPLENR, 198 }, + { 176 * OVERSAMPLENR, 184 }, + { 211 * OVERSAMPLENR, 173 }, + { 246 * OVERSAMPLENR, 163 }, + { 281 * OVERSAMPLENR, 154 }, + { 316 * OVERSAMPLENR, 147 }, + { 351 * OVERSAMPLENR, 140 }, + { 386 * OVERSAMPLENR, 134 }, + { 421 * OVERSAMPLENR, 128 }, + { 456 * OVERSAMPLENR, 122 }, + { 491 * OVERSAMPLENR, 117 }, + { 526 * OVERSAMPLENR, 112 }, + { 561 * OVERSAMPLENR, 107 }, + { 596 * OVERSAMPLENR, 102 }, + { 631 * OVERSAMPLENR, 97 }, + { 666 * OVERSAMPLENR, 91 }, + { 701 * OVERSAMPLENR, 86 }, + { 736 * OVERSAMPLENR, 81 }, + { 771 * OVERSAMPLENR, 76 }, + { 806 * OVERSAMPLENR, 70 }, + { 841 * OVERSAMPLENR, 63 }, + { 876 * OVERSAMPLENR, 56 }, + { 911 * OVERSAMPLENR, 48 }, + { 946 * OVERSAMPLENR, 38 }, + { 981 * OVERSAMPLENR, 23 }, + { 1005 * OVERSAMPLENR, 5 }, + { 1016 * OVERSAMPLENR, 0 } +}; diff --git a/trunk/Arduino/Marlin_1.1.6/thermistortable_1010.h b/trunk/Arduino/Marlin_1.1.6/thermistortable_1010.h new file mode 100644 index 00000000..79a55795 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/thermistortable_1010.h @@ -0,0 +1,38 @@ +/** + * 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 . + * + */ + +// Pt1000 with 1k0 pullup +const short temptable_1010[][2] PROGMEM = { + PtLine( 0, 1000, 1000) + PtLine( 25, 1000, 1000) + PtLine( 50, 1000, 1000) + PtLine( 75, 1000, 1000) + PtLine(100, 1000, 1000) + PtLine(125, 1000, 1000) + PtLine(150, 1000, 1000) + PtLine(175, 1000, 1000) + PtLine(200, 1000, 1000) + PtLine(225, 1000, 1000) + PtLine(250, 1000, 1000) + PtLine(275, 1000, 1000) + PtLine(300, 1000, 1000) +}; diff --git a/trunk/Arduino/Marlin_1.1.6/thermistortable_1047.h b/trunk/Arduino/Marlin_1.1.6/thermistortable_1047.h new file mode 100644 index 00000000..01997abc --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/thermistortable_1047.h @@ -0,0 +1,33 @@ +/** + * 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 . + * + */ + +// Pt1000 with 4k7 pullup +const short temptable_1047[][2] PROGMEM = { + // only a few values are needed as the curve is very flat + PtLine( 0, 1000, 4700) + PtLine( 50, 1000, 4700) + PtLine(100, 1000, 4700) + PtLine(150, 1000, 4700) + PtLine(200, 1000, 4700) + PtLine(250, 1000, 4700) + PtLine(300, 1000, 4700) +}; diff --git a/trunk/Arduino/Marlin_1.1.6/thermistortable_11.h b/trunk/Arduino/Marlin_1.1.6/thermistortable_11.h new file mode 100644 index 00000000..f0f26973 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/thermistortable_11.h @@ -0,0 +1,75 @@ +/** + * 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 . + * + */ + +// QU-BD silicone bed QWG-104F-3950 thermistor +const short temptable_11[][2] PROGMEM = { + { 1 * OVERSAMPLENR, 938 }, + { 31 * OVERSAMPLENR, 314 }, + { 41 * OVERSAMPLENR, 290 }, + { 51 * OVERSAMPLENR, 272 }, + { 61 * OVERSAMPLENR, 258 }, + { 71 * OVERSAMPLENR, 247 }, + { 81 * OVERSAMPLENR, 237 }, + { 91 * OVERSAMPLENR, 229 }, + { 101 * OVERSAMPLENR, 221 }, + { 111 * OVERSAMPLENR, 215 }, + { 121 * OVERSAMPLENR, 209 }, + { 131 * OVERSAMPLENR, 204 }, + { 141 * OVERSAMPLENR, 199 }, + { 151 * OVERSAMPLENR, 195 }, + { 161 * OVERSAMPLENR, 190 }, + { 171 * OVERSAMPLENR, 187 }, + { 181 * OVERSAMPLENR, 183 }, + { 191 * OVERSAMPLENR, 179 }, + { 201 * OVERSAMPLENR, 176 }, + { 221 * OVERSAMPLENR, 170 }, + { 241 * OVERSAMPLENR, 165 }, + { 261 * OVERSAMPLENR, 160 }, + { 281 * OVERSAMPLENR, 155 }, + { 301 * OVERSAMPLENR, 150 }, + { 331 * OVERSAMPLENR, 144 }, + { 361 * OVERSAMPLENR, 139 }, + { 391 * OVERSAMPLENR, 133 }, + { 421 * OVERSAMPLENR, 128 }, + { 451 * OVERSAMPLENR, 123 }, + { 491 * OVERSAMPLENR, 117 }, + { 531 * OVERSAMPLENR, 111 }, + { 571 * OVERSAMPLENR, 105 }, + { 611 * OVERSAMPLENR, 100 }, + { 641 * OVERSAMPLENR, 95 }, + { 681 * OVERSAMPLENR, 90 }, + { 711 * OVERSAMPLENR, 85 }, + { 751 * OVERSAMPLENR, 79 }, + { 791 * OVERSAMPLENR, 72 }, + { 811 * OVERSAMPLENR, 69 }, + { 831 * OVERSAMPLENR, 65 }, + { 871 * OVERSAMPLENR, 57 }, + { 881 * OVERSAMPLENR, 55 }, + { 901 * OVERSAMPLENR, 51 }, + { 921 * OVERSAMPLENR, 45 }, + { 941 * OVERSAMPLENR, 39 }, + { 971 * OVERSAMPLENR, 28 }, + { 981 * OVERSAMPLENR, 23 }, + { 991 * OVERSAMPLENR, 17 }, + { 1001 * OVERSAMPLENR, 9 }, + { 1021 * OVERSAMPLENR, -27 } +}; diff --git a/trunk/Arduino/Marlin_1.1.6/thermistortable_110.h b/trunk/Arduino/Marlin_1.1.6/thermistortable_110.h new file mode 100644 index 00000000..7a4c80df --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/thermistortable_110.h @@ -0,0 +1,33 @@ +/** + * 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 . + * + */ + +// Pt100 with 1k0 pullup +const short temptable_110[][2] PROGMEM = { + // only a few values are needed as the curve is very flat + PtLine( 0, 100, 1000) + PtLine( 50, 100, 1000) + PtLine(100, 100, 1000) + PtLine(150, 100, 1000) + PtLine(200, 100, 1000) + PtLine(250, 100, 1000) + PtLine(300, 100, 1000) +}; diff --git a/trunk/Arduino/Marlin_1.1.6/thermistortable_12.h b/trunk/Arduino/Marlin_1.1.6/thermistortable_12.h new file mode 100644 index 00000000..802c1d37 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/thermistortable_12.h @@ -0,0 +1,55 @@ +/** + * 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 . + * + */ + +// 100k 0603 SMD Vishay NTCS0603E3104FXT (4.7k pullup) (calibrated for Makibox hot bed) +const short temptable_12[][2] PROGMEM = { + { 35 * OVERSAMPLENR, 180 }, // top rating 180C + { 211 * OVERSAMPLENR, 140 }, + { 233 * OVERSAMPLENR, 135 }, + { 261 * OVERSAMPLENR, 130 }, + { 290 * OVERSAMPLENR, 125 }, + { 328 * OVERSAMPLENR, 120 }, + { 362 * OVERSAMPLENR, 115 }, + { 406 * OVERSAMPLENR, 110 }, + { 446 * OVERSAMPLENR, 105 }, + { 496 * OVERSAMPLENR, 100 }, + { 539 * OVERSAMPLENR, 95 }, + { 585 * OVERSAMPLENR, 90 }, + { 629 * OVERSAMPLENR, 85 }, + { 675 * OVERSAMPLENR, 80 }, + { 718 * OVERSAMPLENR, 75 }, + { 758 * OVERSAMPLENR, 70 }, + { 793 * OVERSAMPLENR, 65 }, + { 822 * OVERSAMPLENR, 60 }, + { 841 * OVERSAMPLENR, 55 }, + { 875 * OVERSAMPLENR, 50 }, + { 899 * OVERSAMPLENR, 45 }, + { 926 * OVERSAMPLENR, 40 }, + { 946 * OVERSAMPLENR, 35 }, + { 962 * OVERSAMPLENR, 30 }, + { 977 * OVERSAMPLENR, 25 }, + { 987 * OVERSAMPLENR, 20 }, + { 995 * OVERSAMPLENR, 15 }, + { 1001 * OVERSAMPLENR, 10 }, + { 1010 * OVERSAMPLENR, 0 }, + { 1023 * OVERSAMPLENR, -40 } +}; diff --git a/trunk/Arduino/Marlin_1.1.6/thermistortable_13.h b/trunk/Arduino/Marlin_1.1.6/thermistortable_13.h new file mode 100644 index 00000000..1269c356 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/thermistortable_13.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 . + * + */ + +// Hisens thermistor B25/50 =3950 +/-1% +const short temptable_13[][2] PROGMEM = { + { 20.04 * OVERSAMPLENR, 300 }, + { 23.19 * OVERSAMPLENR, 290 }, + { 26.71 * OVERSAMPLENR, 280 }, + { 31.23 * OVERSAMPLENR, 270 }, + { 36.52 * OVERSAMPLENR, 260 }, + { 42.75 * OVERSAMPLENR, 250 }, + { 50.68 * OVERSAMPLENR, 240 }, + { 60.22 * OVERSAMPLENR, 230 }, + { 72.03 * OVERSAMPLENR, 220 }, + { 86.84 * OVERSAMPLENR, 210 }, + { 102.79 * OVERSAMPLENR, 200 }, + { 124.46 * OVERSAMPLENR, 190 }, + { 151.02 * OVERSAMPLENR, 180 }, + { 182.86 * OVERSAMPLENR, 170 }, + { 220.72 * OVERSAMPLENR, 160 }, + { 316.96 * OVERSAMPLENR, 140 }, + { 447.17 * OVERSAMPLENR, 120 }, + { 590.61 * OVERSAMPLENR, 100 }, + { 737.31 * OVERSAMPLENR, 80 }, + { 857.77 * OVERSAMPLENR, 60 }, + { 939.52 * OVERSAMPLENR, 40 }, + { 986.03 * OVERSAMPLENR, 20 }, + { 1008.7 * OVERSAMPLENR, 0 } +}; diff --git a/trunk/Arduino/Marlin_1.1.6/thermistortable_147.h b/trunk/Arduino/Marlin_1.1.6/thermistortable_147.h new file mode 100644 index 00000000..7e4a3b6f --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/thermistortable_147.h @@ -0,0 +1,33 @@ +/** + * 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 . + * + */ + +// Pt100 with 4k7 pullup +const short temptable_147[][2] PROGMEM = { + // only a few values are needed as the curve is very flat + PtLine( 0, 100, 4700) + PtLine( 50, 100, 4700) + PtLine(100, 100, 4700) + PtLine(150, 100, 4700) + PtLine(200, 100, 4700) + PtLine(250, 100, 4700) + PtLine(300, 100, 4700) +}; diff --git a/trunk/Arduino/Marlin_1.1.6/thermistortable_2.h b/trunk/Arduino/Marlin_1.1.6/thermistortable_2.h new file mode 100644 index 00000000..1b56faed --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/thermistortable_2.h @@ -0,0 +1,61 @@ +/** + * 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 . + * + */ + +// +// 200k ATC Semitec 204GT-2 +// Verified by linagee. Source: http://shop.arcol.hu/static/datasheets/thermistors.pdf +// Calculated using 4.7kohm pullup, voltage divider math, and manufacturer provided temp/resistance +// +const short temptable_2[][2] PROGMEM = { + { 1 * OVERSAMPLENR, 848 }, + { 30 * OVERSAMPLENR, 300 }, // top rating 300C + { 34 * OVERSAMPLENR, 290 }, + { 39 * OVERSAMPLENR, 280 }, + { 46 * OVERSAMPLENR, 270 }, + { 53 * OVERSAMPLENR, 260 }, + { 63 * OVERSAMPLENR, 250 }, + { 74 * OVERSAMPLENR, 240 }, + { 87 * OVERSAMPLENR, 230 }, + { 104 * OVERSAMPLENR, 220 }, + { 124 * OVERSAMPLENR, 210 }, + { 148 * OVERSAMPLENR, 200 }, + { 176 * OVERSAMPLENR, 190 }, + { 211 * OVERSAMPLENR, 180 }, + { 252 * OVERSAMPLENR, 170 }, + { 301 * OVERSAMPLENR, 160 }, + { 357 * OVERSAMPLENR, 150 }, + { 420 * OVERSAMPLENR, 140 }, + { 489 * OVERSAMPLENR, 130 }, + { 562 * OVERSAMPLENR, 120 }, + { 636 * OVERSAMPLENR, 110 }, + { 708 * OVERSAMPLENR, 100 }, + { 775 * OVERSAMPLENR, 90 }, + { 835 * OVERSAMPLENR, 80 }, + { 884 * OVERSAMPLENR, 70 }, + { 924 * OVERSAMPLENR, 60 }, + { 955 * OVERSAMPLENR, 50 }, + { 977 * OVERSAMPLENR, 40 }, + { 993 * OVERSAMPLENR, 30 }, + { 1004 * OVERSAMPLENR, 20 }, + { 1012 * OVERSAMPLENR, 10 }, + { 1016 * OVERSAMPLENR, 0 } +}; diff --git a/trunk/Arduino/Marlin_1.1.6/thermistortable_20.h b/trunk/Arduino/Marlin_1.1.6/thermistortable_20.h new file mode 100644 index 00000000..1c274195 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/thermistortable_20.h @@ -0,0 +1,100 @@ +/** + * 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 . + * + */ + +// PT100 with INA826 amp on Ultimaker v2.0 electronics +// The PT100 in the Ultimaker v2.0 electronics has a high sample value for a high temperature. +// This does not match the normal thermistor behaviour so we need to set the following defines +#if THERMISTORHEATER_0 == 20 + #define HEATER_0_RAW_HI_TEMP 16383 + #define HEATER_0_RAW_LO_TEMP 0 +#endif +#if THERMISTORHEATER_1 == 20 + #define HEATER_1_RAW_HI_TEMP 16383 + #define HEATER_1_RAW_LO_TEMP 0 +#endif +#if THERMISTORHEATER_2 == 20 + #define HEATER_2_RAW_HI_TEMP 16383 + #define HEATER_2_RAW_LO_TEMP 0 +#endif +#if THERMISTORHEATER_3 == 20 + #define HEATER_3_RAW_HI_TEMP 16383 + #define HEATER_3_RAW_LO_TEMP 0 +#endif +#if THERMISTORHEATER_4 == 20 + #define HEATER_4_RAW_HI_TEMP 16383 + #define HEATER_4_RAW_LO_TEMP 0 +#endif +#if THERMISTORBED == 20 + #define HEATER_BED_RAW_HI_TEMP 16383 + #define HEATER_BED_RAW_LO_TEMP 0 +#endif +const short temptable_20[][2] PROGMEM = { + { 0 * OVERSAMPLENR, 0 }, + { 227 * OVERSAMPLENR, 1 }, + { 236 * OVERSAMPLENR, 10 }, + { 245 * OVERSAMPLENR, 20 }, + { 253 * OVERSAMPLENR, 30 }, + { 262 * OVERSAMPLENR, 40 }, + { 270 * OVERSAMPLENR, 50 }, + { 279 * OVERSAMPLENR, 60 }, + { 287 * OVERSAMPLENR, 70 }, + { 295 * OVERSAMPLENR, 80 }, + { 304 * OVERSAMPLENR, 90 }, + { 312 * OVERSAMPLENR, 100 }, + { 320 * OVERSAMPLENR, 110 }, + { 329 * OVERSAMPLENR, 120 }, + { 337 * OVERSAMPLENR, 130 }, + { 345 * OVERSAMPLENR, 140 }, + { 353 * OVERSAMPLENR, 150 }, + { 361 * OVERSAMPLENR, 160 }, + { 369 * OVERSAMPLENR, 170 }, + { 377 * OVERSAMPLENR, 180 }, + { 385 * OVERSAMPLENR, 190 }, + { 393 * OVERSAMPLENR, 200 }, + { 401 * OVERSAMPLENR, 210 }, + { 409 * OVERSAMPLENR, 220 }, + { 417 * OVERSAMPLENR, 230 }, + { 424 * OVERSAMPLENR, 240 }, + { 432 * OVERSAMPLENR, 250 }, + { 440 * OVERSAMPLENR, 260 }, + { 447 * OVERSAMPLENR, 270 }, + { 455 * OVERSAMPLENR, 280 }, + { 463 * OVERSAMPLENR, 290 }, + { 470 * OVERSAMPLENR, 300 }, + { 478 * OVERSAMPLENR, 310 }, + { 485 * OVERSAMPLENR, 320 }, + { 493 * OVERSAMPLENR, 330 }, + { 500 * OVERSAMPLENR, 340 }, + { 507 * OVERSAMPLENR, 350 }, + { 515 * OVERSAMPLENR, 360 }, + { 522 * OVERSAMPLENR, 370 }, + { 529 * OVERSAMPLENR, 380 }, + { 537 * OVERSAMPLENR, 390 }, + { 544 * OVERSAMPLENR, 400 }, + { 614 * OVERSAMPLENR, 500 }, + { 681 * OVERSAMPLENR, 600 }, + { 744 * OVERSAMPLENR, 700 }, + { 805 * OVERSAMPLENR, 800 }, + { 862 * OVERSAMPLENR, 900 }, + { 917 * OVERSAMPLENR, 1000 }, + { 968 * OVERSAMPLENR, 1100 } +}; diff --git a/trunk/Arduino/Marlin_1.1.6/thermistortable_3.h b/trunk/Arduino/Marlin_1.1.6/thermistortable_3.h new file mode 100644 index 00000000..0fc16d4b --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/thermistortable_3.h @@ -0,0 +1,53 @@ +/** + * 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 . + * + */ + +// mendel-parts +const short temptable_3[][2] PROGMEM = { + { 1 * OVERSAMPLENR, 864 }, + { 21 * OVERSAMPLENR, 300 }, + { 25 * OVERSAMPLENR, 290 }, + { 29 * OVERSAMPLENR, 280 }, + { 33 * OVERSAMPLENR, 270 }, + { 39 * OVERSAMPLENR, 260 }, + { 46 * OVERSAMPLENR, 250 }, + { 54 * OVERSAMPLENR, 240 }, + { 64 * OVERSAMPLENR, 230 }, + { 75 * OVERSAMPLENR, 220 }, + { 90 * OVERSAMPLENR, 210 }, + { 107 * OVERSAMPLENR, 200 }, + { 128 * OVERSAMPLENR, 190 }, + { 154 * OVERSAMPLENR, 180 }, + { 184 * OVERSAMPLENR, 170 }, + { 221 * OVERSAMPLENR, 160 }, + { 265 * OVERSAMPLENR, 150 }, + { 316 * OVERSAMPLENR, 140 }, + { 375 * OVERSAMPLENR, 130 }, + { 441 * OVERSAMPLENR, 120 }, + { 513 * OVERSAMPLENR, 110 }, + { 588 * OVERSAMPLENR, 100 }, + { 734 * OVERSAMPLENR, 80 }, + { 856 * OVERSAMPLENR, 60 }, + { 938 * OVERSAMPLENR, 40 }, + { 986 * OVERSAMPLENR, 20 }, + { 1008 * OVERSAMPLENR, 0 }, + { 1018 * OVERSAMPLENR, -20 } +}; diff --git a/trunk/Arduino/Marlin_1.1.6/thermistortable_4.h b/trunk/Arduino/Marlin_1.1.6/thermistortable_4.h new file mode 100644 index 00000000..83e60cd6 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/thermistortable_4.h @@ -0,0 +1,45 @@ +/** + * 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 . + * + */ + +// 10k thermistor +const short temptable_4[][2] PROGMEM = { + { 1 * OVERSAMPLENR, 430 }, + { 54 * OVERSAMPLENR, 137 }, + { 107 * OVERSAMPLENR, 107 }, + { 160 * OVERSAMPLENR, 91 }, + { 213 * OVERSAMPLENR, 80 }, + { 266 * OVERSAMPLENR, 71 }, + { 319 * OVERSAMPLENR, 64 }, + { 372 * OVERSAMPLENR, 57 }, + { 425 * OVERSAMPLENR, 51 }, + { 478 * OVERSAMPLENR, 46 }, + { 531 * OVERSAMPLENR, 41 }, + { 584 * OVERSAMPLENR, 35 }, + { 637 * OVERSAMPLENR, 30 }, + { 690 * OVERSAMPLENR, 25 }, + { 743 * OVERSAMPLENR, 20 }, + { 796 * OVERSAMPLENR, 14 }, + { 849 * OVERSAMPLENR, 7 }, + { 902 * OVERSAMPLENR, 0 }, + { 955 * OVERSAMPLENR, -11 }, + { 1008 * OVERSAMPLENR, -35 } +}; diff --git a/trunk/Arduino/Marlin_1.1.6/thermistortable_5.h b/trunk/Arduino/Marlin_1.1.6/thermistortable_5.h new file mode 100644 index 00000000..8bad7130 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/thermistortable_5.h @@ -0,0 +1,60 @@ +/** + * 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 . + * + */ + +// 100k ParCan thermistor (104GT-2) +// ATC Semitec 104GT-2 (Used in ParCan) +// Verified by linagee. Source: http://shop.arcol.hu/static/datasheets/thermistors.pdf +// Calculated using 4.7kohm pullup, voltage divider math, and manufacturer provided temp/resistance +const short temptable_5[][2] PROGMEM = { + { 1 * OVERSAMPLENR, 713 }, + { 17 * OVERSAMPLENR, 300 }, // top rating 300C + { 20 * OVERSAMPLENR, 290 }, + { 23 * OVERSAMPLENR, 280 }, + { 27 * OVERSAMPLENR, 270 }, + { 31 * OVERSAMPLENR, 260 }, + { 37 * OVERSAMPLENR, 250 }, + { 43 * OVERSAMPLENR, 240 }, + { 51 * OVERSAMPLENR, 230 }, + { 61 * OVERSAMPLENR, 220 }, + { 73 * OVERSAMPLENR, 210 }, + { 87 * OVERSAMPLENR, 200 }, + { 106 * OVERSAMPLENR, 190 }, + { 128 * OVERSAMPLENR, 180 }, + { 155 * OVERSAMPLENR, 170 }, + { 189 * OVERSAMPLENR, 160 }, + { 230 * OVERSAMPLENR, 150 }, + { 278 * OVERSAMPLENR, 140 }, + { 336 * OVERSAMPLENR, 130 }, + { 402 * OVERSAMPLENR, 120 }, + { 476 * OVERSAMPLENR, 110 }, + { 554 * OVERSAMPLENR, 100 }, + { 635 * OVERSAMPLENR, 90 }, + { 713 * OVERSAMPLENR, 80 }, + { 784 * OVERSAMPLENR, 70 }, + { 846 * OVERSAMPLENR, 60 }, + { 897 * OVERSAMPLENR, 50 }, + { 937 * OVERSAMPLENR, 40 }, + { 966 * OVERSAMPLENR, 30 }, + { 986 * OVERSAMPLENR, 20 }, + { 1000 * OVERSAMPLENR, 10 }, + { 1010 * OVERSAMPLENR, 0 } +}; diff --git a/trunk/Arduino/Marlin_1.1.6/thermistortable_51.h b/trunk/Arduino/Marlin_1.1.6/thermistortable_51.h new file mode 100644 index 00000000..44f7142b --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/thermistortable_51.h @@ -0,0 +1,81 @@ +/** + * 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 . + * + */ + +// 100k EPCOS (WITH 1kohm RESISTOR FOR PULLUP, R9 ON SANGUINOLOLU! NOT FOR 4.7kohm PULLUP! THIS IS NOT NORMAL!) +// 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 = { + { 1 * OVERSAMPLENR, 350 }, + { 190 * OVERSAMPLENR, 250 }, // top rating 250C + { 203 * OVERSAMPLENR, 245 }, + { 217 * OVERSAMPLENR, 240 }, + { 232 * OVERSAMPLENR, 235 }, + { 248 * OVERSAMPLENR, 230 }, + { 265 * OVERSAMPLENR, 225 }, + { 283 * OVERSAMPLENR, 220 }, + { 302 * OVERSAMPLENR, 215 }, + { 322 * OVERSAMPLENR, 210 }, + { 344 * OVERSAMPLENR, 205 }, + { 366 * OVERSAMPLENR, 200 }, + { 390 * OVERSAMPLENR, 195 }, + { 415 * OVERSAMPLENR, 190 }, + { 440 * OVERSAMPLENR, 185 }, + { 467 * OVERSAMPLENR, 180 }, + { 494 * OVERSAMPLENR, 175 }, + { 522 * OVERSAMPLENR, 170 }, + { 551 * OVERSAMPLENR, 165 }, + { 580 * OVERSAMPLENR, 160 }, + { 609 * OVERSAMPLENR, 155 }, + { 638 * OVERSAMPLENR, 150 }, + { 666 * OVERSAMPLENR, 145 }, + { 695 * OVERSAMPLENR, 140 }, + { 722 * OVERSAMPLENR, 135 }, + { 749 * OVERSAMPLENR, 130 }, + { 775 * OVERSAMPLENR, 125 }, + { 800 * OVERSAMPLENR, 120 }, + { 823 * OVERSAMPLENR, 115 }, + { 845 * OVERSAMPLENR, 110 }, + { 865 * OVERSAMPLENR, 105 }, + { 884 * OVERSAMPLENR, 100 }, + { 901 * OVERSAMPLENR, 95 }, + { 917 * OVERSAMPLENR, 90 }, + { 932 * OVERSAMPLENR, 85 }, + { 944 * OVERSAMPLENR, 80 }, + { 956 * OVERSAMPLENR, 75 }, + { 966 * OVERSAMPLENR, 70 }, + { 975 * OVERSAMPLENR, 65 }, + { 982 * OVERSAMPLENR, 60 }, + { 989 * OVERSAMPLENR, 55 }, + { 995 * OVERSAMPLENR, 50 }, + { 1000 * OVERSAMPLENR, 45 }, + { 1004 * OVERSAMPLENR, 40 }, + { 1007 * OVERSAMPLENR, 35 }, + { 1010 * OVERSAMPLENR, 30 }, + { 1013 * OVERSAMPLENR, 25 }, + { 1015 * OVERSAMPLENR, 20 }, + { 1017 * OVERSAMPLENR, 15 }, + { 1018 * OVERSAMPLENR, 10 }, + { 1019 * OVERSAMPLENR, 5 }, + { 1020 * OVERSAMPLENR, 0 }, + { 1021 * OVERSAMPLENR, -5 } +}; diff --git a/trunk/Arduino/Marlin_1.1.6/thermistortable_52.h b/trunk/Arduino/Marlin_1.1.6/thermistortable_52.h new file mode 100644 index 00000000..bf4e6a9e --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/thermistortable_52.h @@ -0,0 +1,60 @@ +/** + * 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 . + * + */ + +// 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 +// 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 = { + { 1 * OVERSAMPLENR, 500 }, + { 125 * OVERSAMPLENR, 300 }, // top rating 300C + { 142 * OVERSAMPLENR, 290 }, + { 162 * OVERSAMPLENR, 280 }, + { 185 * OVERSAMPLENR, 270 }, + { 211 * OVERSAMPLENR, 260 }, + { 240 * OVERSAMPLENR, 250 }, + { 274 * OVERSAMPLENR, 240 }, + { 312 * OVERSAMPLENR, 230 }, + { 355 * OVERSAMPLENR, 220 }, + { 401 * OVERSAMPLENR, 210 }, + { 452 * OVERSAMPLENR, 200 }, + { 506 * OVERSAMPLENR, 190 }, + { 563 * OVERSAMPLENR, 180 }, + { 620 * OVERSAMPLENR, 170 }, + { 677 * OVERSAMPLENR, 160 }, + { 732 * OVERSAMPLENR, 150 }, + { 783 * OVERSAMPLENR, 140 }, + { 830 * OVERSAMPLENR, 130 }, + { 871 * OVERSAMPLENR, 120 }, + { 906 * OVERSAMPLENR, 110 }, + { 935 * OVERSAMPLENR, 100 }, + { 958 * OVERSAMPLENR, 90 }, + { 976 * OVERSAMPLENR, 80 }, + { 990 * OVERSAMPLENR, 70 }, + { 1000 * OVERSAMPLENR, 60 }, + { 1008 * OVERSAMPLENR, 50 }, + { 1013 * OVERSAMPLENR, 40 }, + { 1017 * OVERSAMPLENR, 30 }, + { 1019 * OVERSAMPLENR, 20 }, + { 1021 * OVERSAMPLENR, 10 }, + { 1022 * OVERSAMPLENR, 0 } +}; diff --git a/trunk/Arduino/Marlin_1.1.6/thermistortable_55.h b/trunk/Arduino/Marlin_1.1.6/thermistortable_55.h new file mode 100644 index 00000000..76e43db6 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/thermistortable_55.h @@ -0,0 +1,60 @@ +/** + * 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 . + * + */ + +// 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 +// 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 = { + { 1 * OVERSAMPLENR, 500 }, + { 76 * OVERSAMPLENR, 300 }, + { 87 * OVERSAMPLENR, 290 }, + { 100 * OVERSAMPLENR, 280 }, + { 114 * OVERSAMPLENR, 270 }, + { 131 * OVERSAMPLENR, 260 }, + { 152 * OVERSAMPLENR, 250 }, + { 175 * OVERSAMPLENR, 240 }, + { 202 * OVERSAMPLENR, 230 }, + { 234 * OVERSAMPLENR, 220 }, + { 271 * OVERSAMPLENR, 210 }, + { 312 * OVERSAMPLENR, 200 }, + { 359 * OVERSAMPLENR, 190 }, + { 411 * OVERSAMPLENR, 180 }, + { 467 * OVERSAMPLENR, 170 }, + { 527 * OVERSAMPLENR, 160 }, + { 590 * OVERSAMPLENR, 150 }, + { 652 * OVERSAMPLENR, 140 }, + { 713 * OVERSAMPLENR, 130 }, + { 770 * OVERSAMPLENR, 120 }, + { 822 * OVERSAMPLENR, 110 }, + { 867 * OVERSAMPLENR, 100 }, + { 905 * OVERSAMPLENR, 90 }, + { 936 * OVERSAMPLENR, 80 }, + { 961 * OVERSAMPLENR, 70 }, + { 979 * OVERSAMPLENR, 60 }, + { 993 * OVERSAMPLENR, 50 }, + { 1003 * OVERSAMPLENR, 40 }, + { 1010 * OVERSAMPLENR, 30 }, + { 1015 * OVERSAMPLENR, 20 }, + { 1018 * OVERSAMPLENR, 10 }, + { 1020 * OVERSAMPLENR, 0 } +}; diff --git a/trunk/Arduino/Marlin_1.1.6/thermistortable_6.h b/trunk/Arduino/Marlin_1.1.6/thermistortable_6.h new file mode 100644 index 00000000..d270b60d --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/thermistortable_6.h @@ -0,0 +1,63 @@ +/** + * 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 . + * + */ + +// 100k Epcos thermistor +const short temptable_6[][2] PROGMEM = { + { 1 * OVERSAMPLENR, 350 }, + { 28 * OVERSAMPLENR, 250 }, // top rating 250C + { 31 * OVERSAMPLENR, 245 }, + { 35 * OVERSAMPLENR, 240 }, + { 39 * OVERSAMPLENR, 235 }, + { 42 * OVERSAMPLENR, 230 }, + { 44 * OVERSAMPLENR, 225 }, + { 49 * OVERSAMPLENR, 220 }, + { 53 * OVERSAMPLENR, 215 }, + { 62 * OVERSAMPLENR, 210 }, + { 71 * OVERSAMPLENR, 205 }, // fitted graphically + { 78 * OVERSAMPLENR, 200 }, // fitted graphically + { 94 * OVERSAMPLENR, 190 }, + { 102 * OVERSAMPLENR, 185 }, + { 116 * OVERSAMPLENR, 170 }, + { 143 * OVERSAMPLENR, 160 }, + { 183 * OVERSAMPLENR, 150 }, + { 223 * OVERSAMPLENR, 140 }, + { 270 * OVERSAMPLENR, 130 }, + { 318 * OVERSAMPLENR, 120 }, + { 383 * OVERSAMPLENR, 110 }, + { 413 * OVERSAMPLENR, 105 }, + { 439 * OVERSAMPLENR, 100 }, + { 484 * OVERSAMPLENR, 95 }, + { 513 * OVERSAMPLENR, 90 }, + { 607 * OVERSAMPLENR, 80 }, + { 664 * OVERSAMPLENR, 70 }, + { 781 * OVERSAMPLENR, 60 }, + { 810 * OVERSAMPLENR, 55 }, + { 849 * OVERSAMPLENR, 50 }, + { 914 * OVERSAMPLENR, 45 }, + { 914 * OVERSAMPLENR, 40 }, + { 935 * OVERSAMPLENR, 35 }, + { 954 * OVERSAMPLENR, 30 }, + { 970 * OVERSAMPLENR, 25 }, + { 978 * OVERSAMPLENR, 22 }, + { 1008 * OVERSAMPLENR, 3 }, + { 1023 * OVERSAMPLENR, 0 } // to allow internal 0 degrees C +}; diff --git a/trunk/Arduino/Marlin_1.1.6/thermistortable_60.h b/trunk/Arduino/Marlin_1.1.6/thermistortable_60.h new file mode 100644 index 00000000..a1c2645b --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/thermistortable_60.h @@ -0,0 +1,105 @@ +/** + * 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 . + * + */ + +// Maker's Tool Works Kapton Bed Thermistor +// ./createTemperatureLookup.py --r0=100000 --t0=25 --r1=0 --r2=4700 --beta=3950 +// r0: 100000 +// t0: 25 +// r1: 0 (parallel with rTherm) +// r2: 4700 (series with rTherm) +// beta: 3950 +// min adc: 1 at 0.0048828125 V +// max adc: 1023 at 4.9951171875 V +const short temptable_60[][2] PROGMEM = { + { 51 * OVERSAMPLENR, 272 }, + { 61 * OVERSAMPLENR, 258 }, + { 71 * OVERSAMPLENR, 247 }, + { 81 * OVERSAMPLENR, 237 }, + { 91 * OVERSAMPLENR, 229 }, + { 101 * OVERSAMPLENR, 221 }, + { 131 * OVERSAMPLENR, 204 }, + { 161 * OVERSAMPLENR, 190 }, + { 191 * OVERSAMPLENR, 179 }, + { 231 * OVERSAMPLENR, 167 }, + { 271 * OVERSAMPLENR, 157 }, + { 311 * OVERSAMPLENR, 148 }, + { 351 * OVERSAMPLENR, 140 }, + { 381 * OVERSAMPLENR, 135 }, + { 411 * OVERSAMPLENR, 130 }, + { 441 * OVERSAMPLENR, 125 }, + { 451 * OVERSAMPLENR, 123 }, + { 461 * OVERSAMPLENR, 122 }, + { 471 * OVERSAMPLENR, 120 }, + { 481 * OVERSAMPLENR, 119 }, + { 491 * OVERSAMPLENR, 117 }, + { 501 * OVERSAMPLENR, 116 }, + { 511 * OVERSAMPLENR, 114 }, + { 521 * OVERSAMPLENR, 113 }, + { 531 * OVERSAMPLENR, 111 }, + { 541 * OVERSAMPLENR, 110 }, + { 551 * OVERSAMPLENR, 108 }, + { 561 * OVERSAMPLENR, 107 }, + { 571 * OVERSAMPLENR, 105 }, + { 581 * OVERSAMPLENR, 104 }, + { 591 * OVERSAMPLENR, 102 }, + { 601 * OVERSAMPLENR, 101 }, + { 611 * OVERSAMPLENR, 100 }, + { 621 * OVERSAMPLENR, 98 }, + { 631 * OVERSAMPLENR, 97 }, + { 641 * OVERSAMPLENR, 95 }, + { 651 * OVERSAMPLENR, 94 }, + { 661 * OVERSAMPLENR, 92 }, + { 671 * OVERSAMPLENR, 91 }, + { 681 * OVERSAMPLENR, 90 }, + { 691 * OVERSAMPLENR, 88 }, + { 701 * OVERSAMPLENR, 87 }, + { 711 * OVERSAMPLENR, 85 }, + { 721 * OVERSAMPLENR, 84 }, + { 731 * OVERSAMPLENR, 82 }, + { 741 * OVERSAMPLENR, 81 }, + { 751 * OVERSAMPLENR, 79 }, + { 761 * OVERSAMPLENR, 77 }, + { 771 * OVERSAMPLENR, 76 }, + { 781 * OVERSAMPLENR, 74 }, + { 791 * OVERSAMPLENR, 72 }, + { 801 * OVERSAMPLENR, 71 }, + { 811 * OVERSAMPLENR, 69 }, + { 821 * OVERSAMPLENR, 67 }, + { 831 * OVERSAMPLENR, 65 }, + { 841 * OVERSAMPLENR, 63 }, + { 851 * OVERSAMPLENR, 62 }, + { 861 * OVERSAMPLENR, 60 }, + { 871 * OVERSAMPLENR, 57 }, + { 881 * OVERSAMPLENR, 55 }, + { 891 * OVERSAMPLENR, 53 }, + { 901 * OVERSAMPLENR, 51 }, + { 911 * OVERSAMPLENR, 48 }, + { 921 * OVERSAMPLENR, 45 }, + { 931 * OVERSAMPLENR, 42 }, + { 941 * OVERSAMPLENR, 39 }, + { 951 * OVERSAMPLENR, 36 }, + { 961 * OVERSAMPLENR, 32 }, + { 981 * OVERSAMPLENR, 23 }, + { 991 * OVERSAMPLENR, 17 }, + { 1001 * OVERSAMPLENR, 9 }, + { 1008 * OVERSAMPLENR, 0 } +}; diff --git a/trunk/Arduino/Marlin_1.1.6/thermistortable_66.h b/trunk/Arduino/Marlin_1.1.6/thermistortable_66.h new file mode 100644 index 00000000..b23961d1 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/thermistortable_66.h @@ -0,0 +1,52 @@ +/** + * 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 . + * + */ + +// DyzeDesign 500°C Thermistor +const short temptable_66[][2] PROGMEM = { + { 17.5 * OVERSAMPLENR, 850 }, + { 17.9 * OVERSAMPLENR, 500 }, + { 21.7 * OVERSAMPLENR, 480 }, + { 26.6 * OVERSAMPLENR, 460 }, + { 33.1 * OVERSAMPLENR, 440 }, + { 41.0 * OVERSAMPLENR, 420 }, + { 52.3 * OVERSAMPLENR, 400 }, + { 67.7 * OVERSAMPLENR, 380 }, + { 86.5 * OVERSAMPLENR, 360 }, + { 112.0 * OVERSAMPLENR, 340 }, + { 147.2 * OVERSAMPLENR, 320 }, + { 194.0 * OVERSAMPLENR, 300 }, + { 254.3 * OVERSAMPLENR, 280 }, + { 330.2 * OVERSAMPLENR, 260 }, + { 427.9 * OVERSAMPLENR, 240 }, + { 533.4 * OVERSAMPLENR, 220 }, + { 646.5 * OVERSAMPLENR, 200 }, + { 754.4 * OVERSAMPLENR, 180 }, + { 844.3 * OVERSAMPLENR, 160 }, + { 911.7 * OVERSAMPLENR, 140 }, + { 958.6 * OVERSAMPLENR, 120 }, + { 988.8 * OVERSAMPLENR, 100 }, + { 1006.6 * OVERSAMPLENR, 80 }, + { 1015.8 * OVERSAMPLENR, 60 }, + { 1021.3 * OVERSAMPLENR, 30 }, + { 1023 * OVERSAMPLENR - 1, 25}, + { 1023 * OVERSAMPLENR, 20} +}; diff --git a/trunk/Arduino/Marlin_1.1.6/thermistortable_7.h b/trunk/Arduino/Marlin_1.1.6/thermistortable_7.h new file mode 100644 index 00000000..3b4f63b7 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/thermistortable_7.h @@ -0,0 +1,83 @@ +/** + * 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 . + * + */ + +// 100k Honeywell 135-104LAG-J01 +const short temptable_7[][2] PROGMEM = { + { 1 * OVERSAMPLENR, 941 }, + { 19 * OVERSAMPLENR, 362 }, + { 37 * OVERSAMPLENR, 299 }, // top rating 300C + { 55 * OVERSAMPLENR, 266 }, + { 73 * OVERSAMPLENR, 245 }, + { 91 * OVERSAMPLENR, 229 }, + { 109 * OVERSAMPLENR, 216 }, + { 127 * OVERSAMPLENR, 206 }, + { 145 * OVERSAMPLENR, 197 }, + { 163 * OVERSAMPLENR, 190 }, + { 181 * OVERSAMPLENR, 183 }, + { 199 * OVERSAMPLENR, 177 }, + { 217 * OVERSAMPLENR, 171 }, + { 235 * OVERSAMPLENR, 166 }, + { 253 * OVERSAMPLENR, 162 }, + { 271 * OVERSAMPLENR, 157 }, + { 289 * OVERSAMPLENR, 153 }, + { 307 * OVERSAMPLENR, 149 }, + { 325 * OVERSAMPLENR, 146 }, + { 343 * OVERSAMPLENR, 142 }, + { 361 * OVERSAMPLENR, 139 }, + { 379 * OVERSAMPLENR, 135 }, + { 397 * OVERSAMPLENR, 132 }, + { 415 * OVERSAMPLENR, 129 }, + { 433 * OVERSAMPLENR, 126 }, + { 451 * OVERSAMPLENR, 123 }, + { 469 * OVERSAMPLENR, 121 }, + { 487 * OVERSAMPLENR, 118 }, + { 505 * OVERSAMPLENR, 115 }, + { 523 * OVERSAMPLENR, 112 }, + { 541 * OVERSAMPLENR, 110 }, + { 559 * OVERSAMPLENR, 107 }, + { 577 * OVERSAMPLENR, 105 }, + { 595 * OVERSAMPLENR, 102 }, + { 613 * OVERSAMPLENR, 99 }, + { 631 * OVERSAMPLENR, 97 }, + { 649 * OVERSAMPLENR, 94 }, + { 667 * OVERSAMPLENR, 92 }, + { 685 * OVERSAMPLENR, 89 }, + { 703 * OVERSAMPLENR, 86 }, + { 721 * OVERSAMPLENR, 84 }, + { 739 * OVERSAMPLENR, 81 }, + { 757 * OVERSAMPLENR, 78 }, + { 775 * OVERSAMPLENR, 75 }, + { 793 * OVERSAMPLENR, 72 }, + { 811 * OVERSAMPLENR, 69 }, + { 829 * OVERSAMPLENR, 66 }, + { 847 * OVERSAMPLENR, 62 }, + { 865 * OVERSAMPLENR, 59 }, + { 883 * OVERSAMPLENR, 55 }, + { 901 * OVERSAMPLENR, 51 }, + { 919 * OVERSAMPLENR, 46 }, + { 937 * OVERSAMPLENR, 41 }, + { 955 * OVERSAMPLENR, 35 }, + { 973 * OVERSAMPLENR, 27 }, + { 991 * OVERSAMPLENR, 17 }, + { 1009 * OVERSAMPLENR, 1 }, + { 1023 * OVERSAMPLENR, 0 } // to allow internal 0 degrees C +}; diff --git a/trunk/Arduino/Marlin_1.1.6/thermistortable_70.h b/trunk/Arduino/Marlin_1.1.6/thermistortable_70.h new file mode 100644 index 00000000..70440590 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/thermistortable_70.h @@ -0,0 +1,86 @@ +/** + * 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 . + * + */ + +// bqh2 stock thermistor +const short temptable_70[][2] PROGMEM = { + { 22 * OVERSAMPLENR, 300 }, + { 24 * OVERSAMPLENR, 295 }, + { 25 * OVERSAMPLENR, 290 }, + { 27 * OVERSAMPLENR, 285 }, + { 29 * OVERSAMPLENR, 280 }, + { 32 * OVERSAMPLENR, 275 }, + { 34 * OVERSAMPLENR, 270 }, + { 37 * OVERSAMPLENR, 265 }, + { 40 * OVERSAMPLENR, 260 }, + { 43 * OVERSAMPLENR, 255 }, + { 46 * OVERSAMPLENR, 250 }, + { 50 * OVERSAMPLENR, 245 }, + { 54 * OVERSAMPLENR, 240 }, + { 59 * OVERSAMPLENR, 235 }, + { 64 * OVERSAMPLENR, 230 }, + { 70 * OVERSAMPLENR, 225 }, + { 76 * OVERSAMPLENR, 220 }, + { 83 * OVERSAMPLENR, 215 }, + { 90 * OVERSAMPLENR, 210 }, + { 99 * OVERSAMPLENR, 205 }, + { 108 * OVERSAMPLENR, 200 }, + { 118 * OVERSAMPLENR, 195 }, + { 129 * OVERSAMPLENR, 190 }, + { 141 * OVERSAMPLENR, 185 }, + { 154 * OVERSAMPLENR, 180 }, + { 169 * OVERSAMPLENR, 175 }, + { 185 * OVERSAMPLENR, 170 }, + { 203 * OVERSAMPLENR, 165 }, + { 222 * OVERSAMPLENR, 160 }, + { 243 * OVERSAMPLENR, 155 }, + { 266 * OVERSAMPLENR, 150 }, + { 290 * OVERSAMPLENR, 145 }, + { 317 * OVERSAMPLENR, 140 }, + { 346 * OVERSAMPLENR, 135 }, + { 376 * OVERSAMPLENR, 130 }, + { 408 * OVERSAMPLENR, 125 }, + { 442 * OVERSAMPLENR, 120 }, + { 477 * OVERSAMPLENR, 115 }, + { 513 * OVERSAMPLENR, 110 }, + { 551 * OVERSAMPLENR, 105 }, + { 588 * OVERSAMPLENR, 100 }, + { 626 * OVERSAMPLENR, 95 }, + { 663 * OVERSAMPLENR, 90 }, + { 699 * OVERSAMPLENR, 85 }, + { 735 * OVERSAMPLENR, 80 }, + { 768 * OVERSAMPLENR, 75 }, + { 800 * OVERSAMPLENR, 70 }, + { 829 * OVERSAMPLENR, 65 }, + { 856 * OVERSAMPLENR, 60 }, + { 881 * OVERSAMPLENR, 55 }, + { 903 * OVERSAMPLENR, 50 }, + { 922 * OVERSAMPLENR, 45 }, + { 939 * OVERSAMPLENR, 40 }, + { 954 * OVERSAMPLENR, 35 }, + { 966 * OVERSAMPLENR, 30 }, + { 977 * OVERSAMPLENR, 25 }, + { 986 * OVERSAMPLENR, 20 }, + { 994 * OVERSAMPLENR, 15 }, + { 1000 * OVERSAMPLENR, 10 }, + { 1005 * OVERSAMPLENR, 5 }, + { 1009 * OVERSAMPLENR, 0 } // safety +}; diff --git a/trunk/Arduino/Marlin_1.1.6/thermistortable_71.h b/trunk/Arduino/Marlin_1.1.6/thermistortable_71.h new file mode 100644 index 00000000..9d90e87b --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/thermistortable_71.h @@ -0,0 +1,171 @@ +/** + * 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 . + * + */ + +// 100k Honeywell 135-104LAF-J01 +// R0 = 100000 Ohm +// T0 = 25 °C +// Beta = 3974 +// R1 = 0 Ohm +// R2 = 4700 Ohm +const short temptable_71[][2] PROGMEM = { + { 35 * OVERSAMPLENR, 300 }, + { 51 * OVERSAMPLENR, 270 }, + { 54 * OVERSAMPLENR, 265 }, + { 58 * OVERSAMPLENR, 260 }, + { 59 * OVERSAMPLENR, 258 }, + { 61 * OVERSAMPLENR, 256 }, + { 63 * OVERSAMPLENR, 254 }, + { 64 * OVERSAMPLENR, 252 }, + { 66 * OVERSAMPLENR, 250 }, + { 67 * OVERSAMPLENR, 249 }, + { 68 * OVERSAMPLENR, 248 }, + { 69 * OVERSAMPLENR, 247 }, + { 70 * OVERSAMPLENR, 246 }, + { 71 * OVERSAMPLENR, 245 }, + { 72 * OVERSAMPLENR, 244 }, + { 73 * OVERSAMPLENR, 243 }, + { 74 * OVERSAMPLENR, 242 }, + { 75 * OVERSAMPLENR, 241 }, + { 76 * OVERSAMPLENR, 240 }, + { 77 * OVERSAMPLENR, 239 }, + { 78 * OVERSAMPLENR, 238 }, + { 79 * OVERSAMPLENR, 237 }, + { 80 * OVERSAMPLENR, 236 }, + { 81 * OVERSAMPLENR, 235 }, + { 82 * OVERSAMPLENR, 234 }, + { 84 * OVERSAMPLENR, 233 }, + { 85 * OVERSAMPLENR, 232 }, + { 86 * OVERSAMPLENR, 231 }, + { 87 * OVERSAMPLENR, 230 }, + { 89 * OVERSAMPLENR, 229 }, + { 90 * OVERSAMPLENR, 228 }, + { 91 * OVERSAMPLENR, 227 }, + { 92 * OVERSAMPLENR, 226 }, + { 94 * OVERSAMPLENR, 225 }, + { 95 * OVERSAMPLENR, 224 }, + { 97 * OVERSAMPLENR, 223 }, + { 98 * OVERSAMPLENR, 222 }, + { 99 * OVERSAMPLENR, 221 }, + { 101 * OVERSAMPLENR, 220 }, + { 102 * OVERSAMPLENR, 219 }, + { 104 * OVERSAMPLENR, 218 }, + { 106 * OVERSAMPLENR, 217 }, + { 107 * OVERSAMPLENR, 216 }, + { 109 * OVERSAMPLENR, 215 }, + { 110 * OVERSAMPLENR, 214 }, + { 112 * OVERSAMPLENR, 213 }, + { 114 * OVERSAMPLENR, 212 }, + { 115 * OVERSAMPLENR, 211 }, + { 117 * OVERSAMPLENR, 210 }, + { 119 * OVERSAMPLENR, 209 }, + { 121 * OVERSAMPLENR, 208 }, + { 123 * OVERSAMPLENR, 207 }, + { 125 * OVERSAMPLENR, 206 }, + { 126 * OVERSAMPLENR, 205 }, + { 128 * OVERSAMPLENR, 204 }, + { 130 * OVERSAMPLENR, 203 }, + { 132 * OVERSAMPLENR, 202 }, + { 134 * OVERSAMPLENR, 201 }, + { 136 * OVERSAMPLENR, 200 }, + { 139 * OVERSAMPLENR, 199 }, + { 141 * OVERSAMPLENR, 198 }, + { 143 * OVERSAMPLENR, 197 }, + { 145 * OVERSAMPLENR, 196 }, + { 147 * OVERSAMPLENR, 195 }, + { 150 * OVERSAMPLENR, 194 }, + { 152 * OVERSAMPLENR, 193 }, + { 154 * OVERSAMPLENR, 192 }, + { 157 * OVERSAMPLENR, 191 }, + { 159 * OVERSAMPLENR, 190 }, + { 162 * OVERSAMPLENR, 189 }, + { 164 * OVERSAMPLENR, 188 }, + { 167 * OVERSAMPLENR, 187 }, + { 170 * OVERSAMPLENR, 186 }, + { 172 * OVERSAMPLENR, 185 }, + { 175 * OVERSAMPLENR, 184 }, + { 178 * OVERSAMPLENR, 183 }, + { 181 * OVERSAMPLENR, 182 }, + { 184 * OVERSAMPLENR, 181 }, + { 187 * OVERSAMPLENR, 180 }, + { 190 * OVERSAMPLENR, 179 }, + { 193 * OVERSAMPLENR, 178 }, + { 196 * OVERSAMPLENR, 177 }, + { 199 * OVERSAMPLENR, 176 }, + { 202 * OVERSAMPLENR, 175 }, + { 205 * OVERSAMPLENR, 174 }, + { 208 * OVERSAMPLENR, 173 }, + { 212 * OVERSAMPLENR, 172 }, + { 215 * OVERSAMPLENR, 171 }, + { 219 * OVERSAMPLENR, 170 }, + { 237 * OVERSAMPLENR, 165 }, + { 256 * OVERSAMPLENR, 160 }, + { 300 * OVERSAMPLENR, 150 }, + { 351 * OVERSAMPLENR, 140 }, + { 470 * OVERSAMPLENR, 120 }, + { 504 * OVERSAMPLENR, 115 }, + { 538 * OVERSAMPLENR, 110 }, + { 552 * OVERSAMPLENR, 108 }, + { 566 * OVERSAMPLENR, 106 }, + { 580 * OVERSAMPLENR, 104 }, + { 594 * OVERSAMPLENR, 102 }, + { 608 * OVERSAMPLENR, 100 }, + { 622 * OVERSAMPLENR, 98 }, + { 636 * OVERSAMPLENR, 96 }, + { 650 * OVERSAMPLENR, 94 }, + { 664 * OVERSAMPLENR, 92 }, + { 678 * OVERSAMPLENR, 90 }, + { 712 * OVERSAMPLENR, 85 }, + { 745 * OVERSAMPLENR, 80 }, + { 758 * OVERSAMPLENR, 78 }, + { 770 * OVERSAMPLENR, 76 }, + { 783 * OVERSAMPLENR, 74 }, + { 795 * OVERSAMPLENR, 72 }, + { 806 * OVERSAMPLENR, 70 }, + { 818 * OVERSAMPLENR, 68 }, + { 829 * OVERSAMPLENR, 66 }, + { 840 * OVERSAMPLENR, 64 }, + { 850 * OVERSAMPLENR, 62 }, + { 860 * OVERSAMPLENR, 60 }, + { 870 * OVERSAMPLENR, 58 }, + { 879 * OVERSAMPLENR, 56 }, + { 888 * OVERSAMPLENR, 54 }, + { 897 * OVERSAMPLENR, 52 }, + { 905 * OVERSAMPLENR, 50 }, + { 924 * OVERSAMPLENR, 45 }, + { 940 * OVERSAMPLENR, 40 }, + { 955 * OVERSAMPLENR, 35 }, + { 967 * OVERSAMPLENR, 30 }, + { 970 * OVERSAMPLENR, 29 }, + { 972 * OVERSAMPLENR, 28 }, + { 974 * OVERSAMPLENR, 27 }, + { 976 * OVERSAMPLENR, 26 }, + { 978 * OVERSAMPLENR, 25 }, + { 980 * OVERSAMPLENR, 24 }, + { 982 * OVERSAMPLENR, 23 }, + { 984 * OVERSAMPLENR, 22 }, + { 985 * OVERSAMPLENR, 21 }, + { 987 * OVERSAMPLENR, 20 }, + { 995 * OVERSAMPLENR, 15 }, + { 1001 * OVERSAMPLENR, 10 }, + { 1006 * OVERSAMPLENR, 5 }, + { 1010 * OVERSAMPLENR, 0 } +}; diff --git a/trunk/Arduino/Marlin_1.1.6/thermistortable_75.h b/trunk/Arduino/Marlin_1.1.6/thermistortable_75.h new file mode 100644 index 00000000..01be6114 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/thermistortable_75.h @@ -0,0 +1,69 @@ +/** + * 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 . + * + */ + +// Generic Silicon Heat Pad with NTC 100K thermistor ( Beta 25/50 3950K) +// +// Many of the generic silicon heat pads use the MGB18-104F39050L32 Thermistor It is used for various +// wattage and voltage heat pads. This table is correct if this part is used. It has been +// optimized to provide good granularity around the 60 C. and 110 C. which corrisponds to bed temperatures +// for PLA and ABS. If you are printing higher temperature filament such as nylon you can uncomment +// the higher earlier entries in the table to give better accuracy. But for speed reasons, if these +// temperatures are not going to be used, it is better to leave them commented out. + +const short temptable_75[][2] PROGMEM = { // Generic Silicon Heat Pad with NTC 100K MGB18-104F39050L32 thermistor + { (short) ( 111.06 * OVERSAMPLENR ), 200 }, // v=0.542 r=571.747 res=0.501 degC/count +// { (short) ( 174.87 * OVERSAMPLENR ), 175 }, // v=0.854 r=967.950 res=0.311 degC/count These values are valid. But they serve no +// { (short) ( 191.64 * OVERSAMPLENR ), 170 }, // v=0.936 r=1082.139 res=0.284 degC/count purpose. It is better to delete them so +// { (short) ( 209.99 * OVERSAMPLENR ), 165 }, // v=1.025 r=1212.472 res=0.260 degC/count the search is quicker and get to the meaningful +// { (short) ( 230.02 * OVERSAMPLENR ), 160 }, // v=1.123 r=1361.590 res=0.239 degC/count part of the table sooner. +// { (short) ( 251.80 * OVERSAMPLENR ), 155 }, // v=1.230 r=1532.621 res=0.220 degC/count + { (short) ( 275.43 * OVERSAMPLENR ), 150 }, // v=1.345 r=1729.283 res=0.203 degC/count +// { (short) ( 300.92 * OVERSAMPLENR ), 145 }, // v=1.469 r=1956.004 res=0.189 degC/coun + { (short) ( 328.32 * OVERSAMPLENR ), 140 }, // v=1.603 r=2218.081 res=0.176 degC/count + { (short) ( 388.65 * OVERSAMPLENR ), 130 }, // v=1.898 r=2874.980 res=0.156 degC/count + { (short) ( 421.39 * OVERSAMPLENR ), 125 }, // v=2.058 r=3286.644 res=0.149 degC/count + { (short) ( 455.65 * OVERSAMPLENR ), 120 }, // v=2.225 r=3768.002 res=0.143 degC/count + { (short) ( 491.17 * OVERSAMPLENR ), 115 }, // v=2.398 r=4332.590 res=0.139 degC/count + { (short) ( 527.68 * OVERSAMPLENR ), 110 }, // v=2.577 r=4996.905 res=0.136 degC/count + { (short) ( 564.81 * OVERSAMPLENR ), 105 }, // v=2.758 r=5781.120 res=0.134 degC/count + { (short) ( 602.19 * OVERSAMPLENR ), 100 }, // v=2.940 r=6710.000 res=0.134 degC/count + { (short) ( 676.03 * OVERSAMPLENR ), 90 }, // v=3.301 r=9131.018 res=0.138 degC/count + { (short) ( 745.85 * OVERSAMPLENR ), 80 }, // v=3.642 r=12602.693 res=0.150 degC/count + { (short) ( 778.31 * OVERSAMPLENR ), 75 }, // v=3.800 r=14889.001 res=0.159 degC/count + { (short) ( 808.75 * OVERSAMPLENR ), 70 }, // v=3.949 r=17658.700 res=0.171 degC/count + { (short) ( 836.94 * OVERSAMPLENR ), 65 }, // v=4.087 r=21028.040 res=0.185 degC/count + { (short) ( 862.74 * OVERSAMPLENR ), 60 }, // v=4.213 r=25144.568 res=0.204 degC/count + { (short) ( 886.08 * OVERSAMPLENR ), 55 }, // v=4.327 r=30196.449 res=0.227 degC/count + { (short) ( 906.97 * OVERSAMPLENR ), 50 }, // v=4.429 r=36424.838 res=0.255 degC/count + { (short) ( 941.65 * OVERSAMPLENR ), 40 }, // v=4.598 r=53745.337 res=0.333 degC/count + { (short) ( 967.76 * OVERSAMPLENR ), 30 }, // v=4.725 r=80880.630 res=0.452 degC/count + { (short) ( 978.03 * OVERSAMPLENR ), 25 }, // v=4.776 r=100000.000 res=0.535 degC/count + { (short) ( 981.68 * OVERSAMPLENR ), 23 }, // v=4.793 r=109024.395 res=0.573 degC/count + { (short) ( 983.41 * OVERSAMPLENR ), 22 }, // v=4.802 r=113875.430 res=0.594 degC/count + { (short) ( 985.08 * OVERSAMPLENR ), 21 }, // v=4.810 r=118968.955 res=0.616 degC/count + { (short) ( 986.70 * OVERSAMPLENR ), 20 }, // v=4.818 r=124318.354 res=0.638 degC/count + { (short) ( 993.94 * OVERSAMPLENR ), 15 }, // v=4.853 r=155431.302 res=0.768 degC/count + { (short) ( 999.96 * OVERSAMPLENR ), 10 }, // v=4.883 r=195480.023 res=0.934 degC/count + { (short) (1008.95 * OVERSAMPLENR ), 0 } // v=4.926 r=314997.575 res=1.418 degC/count +}; + + diff --git a/trunk/Arduino/Marlin_1.1.6/thermistortable_8.h b/trunk/Arduino/Marlin_1.1.6/thermistortable_8.h new file mode 100644 index 00000000..f1892bf8 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/thermistortable_8.h @@ -0,0 +1,45 @@ +/** + * 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 . + * + */ + +// 100k 0603 SMD Vishay NTCS0603E3104FXT (4.7k pullup) +const short temptable_8[][2] PROGMEM = { + { 1 * OVERSAMPLENR, 704 }, + { 54 * OVERSAMPLENR, 216 }, + { 107 * OVERSAMPLENR, 175 }, + { 160 * OVERSAMPLENR, 152 }, + { 213 * OVERSAMPLENR, 137 }, + { 266 * OVERSAMPLENR, 125 }, + { 319 * OVERSAMPLENR, 115 }, + { 372 * OVERSAMPLENR, 106 }, + { 425 * OVERSAMPLENR, 99 }, + { 478 * OVERSAMPLENR, 91 }, + { 531 * OVERSAMPLENR, 85 }, + { 584 * OVERSAMPLENR, 78 }, + { 637 * OVERSAMPLENR, 71 }, + { 690 * OVERSAMPLENR, 65 }, + { 743 * OVERSAMPLENR, 58 }, + { 796 * OVERSAMPLENR, 50 }, + { 849 * OVERSAMPLENR, 42 }, + { 902 * OVERSAMPLENR, 31 }, + { 955 * OVERSAMPLENR, 17 }, + { 1008 * OVERSAMPLENR, 0 } +}; diff --git a/trunk/Arduino/Marlin_1.1.6/thermistortable_9.h b/trunk/Arduino/Marlin_1.1.6/thermistortable_9.h new file mode 100644 index 00000000..e3b0e7b4 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/thermistortable_9.h @@ -0,0 +1,56 @@ +/** + * 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 . + * + */ + +// 100k GE Sensing AL03006-58.2K-97-G1 (4.7k pullup) +const short temptable_9[][2] PROGMEM = { + { 1 * OVERSAMPLENR, 936 }, + { 36 * OVERSAMPLENR, 300 }, + { 71 * OVERSAMPLENR, 246 }, + { 106 * OVERSAMPLENR, 218 }, + { 141 * OVERSAMPLENR, 199 }, + { 176 * OVERSAMPLENR, 185 }, + { 211 * OVERSAMPLENR, 173 }, + { 246 * OVERSAMPLENR, 163 }, + { 281 * OVERSAMPLENR, 155 }, + { 316 * OVERSAMPLENR, 147 }, + { 351 * OVERSAMPLENR, 140 }, + { 386 * OVERSAMPLENR, 134 }, + { 421 * OVERSAMPLENR, 128 }, + { 456 * OVERSAMPLENR, 122 }, + { 491 * OVERSAMPLENR, 117 }, + { 526 * OVERSAMPLENR, 112 }, + { 561 * OVERSAMPLENR, 107 }, + { 596 * OVERSAMPLENR, 102 }, + { 631 * OVERSAMPLENR, 97 }, + { 666 * OVERSAMPLENR, 92 }, + { 701 * OVERSAMPLENR, 87 }, + { 736 * OVERSAMPLENR, 81 }, + { 771 * OVERSAMPLENR, 76 }, + { 806 * OVERSAMPLENR, 70 }, + { 841 * OVERSAMPLENR, 63 }, + { 876 * OVERSAMPLENR, 56 }, + { 911 * OVERSAMPLENR, 48 }, + { 946 * OVERSAMPLENR, 38 }, + { 981 * OVERSAMPLENR, 23 }, + { 1005 * OVERSAMPLENR, 5 }, + { 1016 * OVERSAMPLENR, 0 } +}; diff --git a/trunk/Arduino/Marlin_1.1.6/thermistortable_998.h b/trunk/Arduino/Marlin_1.1.6/thermistortable_998.h new file mode 100644 index 00000000..0e0be8c4 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/thermistortable_998.h @@ -0,0 +1,32 @@ +/** + * 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 . + * + */ + +// User-defined table 1 +// Dummy Thermistor table.. It will ALWAYS read a fixed value. +#ifndef DUMMY_THERMISTOR_998_VALUE + #define DUMMY_THERMISTOR_998_VALUE 25 +#endif + +const short temptable_998[][2] PROGMEM = { + { 1 * OVERSAMPLENR, DUMMY_THERMISTOR_998_VALUE }, + { 1023 * OVERSAMPLENR, DUMMY_THERMISTOR_998_VALUE } +}; diff --git a/trunk/Arduino/Marlin_1.1.6/thermistortable_999.h b/trunk/Arduino/Marlin_1.1.6/thermistortable_999.h new file mode 100644 index 00000000..d98018bc --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/thermistortable_999.h @@ -0,0 +1,32 @@ +/** + * 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 . + * + */ + +// User-defined table 2 +// Dummy Thermistor table.. It will ALWAYS read a fixed value. +#ifndef DUMMY_THERMISTOR_999_VALUE + #define DUMMY_THERMISTOR_999_VALUE 25 +#endif + +const short temptable_999[][2] PROGMEM = { + { 1 * OVERSAMPLENR, DUMMY_THERMISTOR_999_VALUE }, + { 1023 * OVERSAMPLENR, DUMMY_THERMISTOR_999_VALUE } +}; diff --git a/trunk/Arduino/Marlin_1.1.6/thermistortables.h b/trunk/Arduino/Marlin_1.1.6/thermistortables.h new file mode 100644 index 00000000..164afa5e --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/thermistortables.h @@ -0,0 +1,248 @@ +/** + * 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 . + * + */ + +#ifndef THERMISTORTABLES_H_ +#define THERMISTORTABLES_H_ + +#include "Marlin.h" +#include "macros.h" + +#define OVERSAMPLENR 16 + +#define ANY_THERMISTOR_IS(n) (THERMISTORHEATER_0 == n || THERMISTORHEATER_1 == n || THERMISTORHEATER_2 == n || THERMISTORHEATER_3 == n || THERMISTORHEATER_4 == n || THERMISTORBED == n) + +// Pt1000 and Pt100 handling +// +// Rt=R0*(1+a*T+b*T*T) [for T>0] +// a=3.9083E-3, b=-5.775E-7 +#define PtA 3.9083E-3 +#define PtB -5.775E-7 +#define PtRt(T,R0) ((R0)*(1.0+(PtA)*(T)+(PtB)*(T)*(T))) +#define PtAdVal(T,R0,Rup) (short)(1024/(Rup/PtRt(T,R0)+1)) +#define PtLine(T,R0,Rup) { PtAdVal(T,R0,Rup)*OVERSAMPLENR, T }, + +#if ANY_THERMISTOR_IS(1) // 100k bed thermistor + #include "thermistortable_1.h" +#endif +#if ANY_THERMISTOR_IS(2) // 200k bed thermistor + #include "thermistortable_2.h" +#endif +#if ANY_THERMISTOR_IS(3) // mendel-parts + #include "thermistortable_3.h" +#endif +#if ANY_THERMISTOR_IS(4) // 10k thermistor + #include "thermistortable_4.h" +#endif +#if ANY_THERMISTOR_IS(5) // 100k ParCan thermistor (104GT-2) + #include "thermistortable_5.h" +#endif +#if ANY_THERMISTOR_IS(6) // 100k Epcos thermistor + #include "thermistortable_6.h" +#endif +#if ANY_THERMISTOR_IS(7) // 100k Honeywell 135-104LAG-J01 + #include "thermistortable_7.h" +#endif +#if ANY_THERMISTOR_IS(71) // 100k Honeywell 135-104LAF-J01 + #include "thermistortable_71.h" +#endif +#if ANY_THERMISTOR_IS(8) // 100k 0603 SMD Vishay NTCS0603E3104FXT (4.7k pullup) + #include "thermistortable_8.h" +#endif +#if ANY_THERMISTOR_IS(9) // 100k GE Sensing AL03006-58.2K-97-G1 (4.7k pullup) + #include "thermistortable_9.h" +#endif +#if ANY_THERMISTOR_IS(10) // 100k RS thermistor 198-961 (4.7k pullup) + #include "thermistortable_10.h" +#endif +#if ANY_THERMISTOR_IS(11) // QU-BD silicone bed QWG-104F-3950 thermistor + #include "thermistortable_11.h" +#endif +#if ANY_THERMISTOR_IS(13) // Hisens thermistor B25/50 =3950 +/-1% + #include "thermistortable_13.h" +#endif +#if ANY_THERMISTOR_IS(20) // PT100 with INA826 amp on Ultimaker v2.0 electronics + #include "thermistortable_20.h" +#endif +#if ANY_THERMISTOR_IS(51) // 100k EPCOS (WITH 1kohm RESISTOR FOR PULLUP, R9 ON SANGUINOLOLU! NOT FOR 4.7kohm PULLUP! THIS IS NOT NORMAL!) + #include "thermistortable_51.h" +#endif +#if ANY_THERMISTOR_IS(52) // 200k ATC Semitec 204GT-2 (WITH 1kohm RESISTOR FOR PULLUP, R9 ON SANGUINOLOLU! NOT FOR 4.7kohm PULLUP! THIS IS NOT NORMAL!) + #include "thermistortable_52.h" +#endif +#if ANY_THERMISTOR_IS(55) // 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!) + #include "thermistortable_55.h" +#endif +#if ANY_THERMISTOR_IS(60) // Maker's Tool Works Kapton Bed Thermistor + #include "thermistortable_60.h" +#endif +#if ANY_THERMISTOR_IS(66) // DyzeDesign 500°C Thermistor + #include "thermistortable_66.h" +#endif +#if ANY_THERMISTOR_IS(12) // 100k 0603 SMD Vishay NTCS0603E3104FXT (4.7k pullup) (calibrated for Makibox hot bed) + #include "thermistortable_12.h" +#endif +#if ANY_THERMISTOR_IS(70) // bqh2 stock thermistor + #include "thermistortable_70.h" +#endif +#if ANY_THERMISTOR_IS(75) // Many of the generic silicon heat pads use the MGB18-104F39050L32 Thermistor + #include "thermistortable_75.h" +#endif +#if ANY_THERMISTOR_IS(110) // Pt100 with 1k0 pullup + #include "thermistortable_110.h" +#endif +#if ANY_THERMISTOR_IS(147) // Pt100 with 4k7 pullup + #include "thermistortable_147.h" +#endif +#if ANY_THERMISTOR_IS(1010) // Pt1000 with 1k0 pullup + #include "thermistortable_1010.h" +#endif +#if ANY_THERMISTOR_IS(1047) // Pt1000 with 4k7 pullup + #include "thermistortable_1047.h" +#endif +#if ANY_THERMISTOR_IS(998) // User-defined table 1 + #include "thermistortable_998.h" +#endif +#if ANY_THERMISTOR_IS(999) // User-defined table 2 + #include "thermistortable_999.h" +#endif + +#define _TT_NAME(_N) temptable_ ## _N +#define TT_NAME(_N) _TT_NAME(_N) + +#ifdef THERMISTORHEATER_0 + #define HEATER_0_TEMPTABLE TT_NAME(THERMISTORHEATER_0) + #define HEATER_0_TEMPTABLE_LEN COUNT(HEATER_0_TEMPTABLE) +#elif defined(HEATER_0_USES_THERMISTOR) + #error "No heater 0 thermistor table specified" +#else + #define HEATER_0_TEMPTABLE NULL + #define HEATER_0_TEMPTABLE_LEN 0 +#endif + +#ifdef THERMISTORHEATER_1 + #define HEATER_1_TEMPTABLE TT_NAME(THERMISTORHEATER_1) + #define HEATER_1_TEMPTABLE_LEN COUNT(HEATER_1_TEMPTABLE) +#elif defined(HEATER_1_USES_THERMISTOR) + #error "No heater 1 thermistor table specified" +#else + #define HEATER_1_TEMPTABLE NULL + #define HEATER_1_TEMPTABLE_LEN 0 +#endif + +#ifdef THERMISTORHEATER_2 + #define HEATER_2_TEMPTABLE TT_NAME(THERMISTORHEATER_2) + #define HEATER_2_TEMPTABLE_LEN COUNT(HEATER_2_TEMPTABLE) +#elif defined(HEATER_2_USES_THERMISTOR) + #error "No heater 2 thermistor table specified" +#else + #define HEATER_2_TEMPTABLE NULL + #define HEATER_2_TEMPTABLE_LEN 0 +#endif + +#ifdef THERMISTORHEATER_3 + #define HEATER_3_TEMPTABLE TT_NAME(THERMISTORHEATER_3) + #define HEATER_3_TEMPTABLE_LEN COUNT(HEATER_3_TEMPTABLE) +#elif defined(HEATER_3_USES_THERMISTOR) + #error "No heater 3 thermistor table specified" +#else + #define HEATER_3_TEMPTABLE NULL + #define HEATER_3_TEMPTABLE_LEN 0 +#endif + +#ifdef THERMISTORHEATER_4 + #define HEATER_4_TEMPTABLE TT_NAME(THERMISTORHEATER_4) + #define HEATER_4_TEMPTABLE_LEN COUNT(HEATER_4_TEMPTABLE) +#elif defined(HEATER_4_USES_THERMISTOR) + #error "No heater 4 thermistor table specified" +#else + #define HEATER_4_TEMPTABLE NULL + #define HEATER_4_TEMPTABLE_LEN 0 +#endif + +#ifdef THERMISTORBED + #define BEDTEMPTABLE TT_NAME(THERMISTORBED) + #define BEDTEMPTABLE_LEN COUNT(BEDTEMPTABLE) +#else + #ifdef BED_USES_THERMISTOR + #error "No bed thermistor table specified" + #endif +#endif + +// 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 +#ifndef HEATER_0_RAW_HI_TEMP + #ifdef HEATER_0_USES_THERMISTOR + #define HEATER_0_RAW_HI_TEMP 0 + #define HEATER_0_RAW_LO_TEMP 16383 + #else + #define HEATER_0_RAW_HI_TEMP 16383 + #define HEATER_0_RAW_LO_TEMP 0 + #endif +#endif +#ifndef HEATER_1_RAW_HI_TEMP + #ifdef HEATER_1_USES_THERMISTOR + #define HEATER_1_RAW_HI_TEMP 0 + #define HEATER_1_RAW_LO_TEMP 16383 + #else + #define HEATER_1_RAW_HI_TEMP 16383 + #define HEATER_1_RAW_LO_TEMP 0 + #endif +#endif +#ifndef HEATER_2_RAW_HI_TEMP + #ifdef HEATER_2_USES_THERMISTOR + #define HEATER_2_RAW_HI_TEMP 0 + #define HEATER_2_RAW_LO_TEMP 16383 + #else + #define HEATER_2_RAW_HI_TEMP 16383 + #define HEATER_2_RAW_LO_TEMP 0 + #endif +#endif +#ifndef HEATER_3_RAW_HI_TEMP + #ifdef HEATER_3_USES_THERMISTOR + #define HEATER_3_RAW_HI_TEMP 0 + #define HEATER_3_RAW_LO_TEMP 16383 + #else + #define HEATER_3_RAW_HI_TEMP 16383 + #define HEATER_3_RAW_LO_TEMP 0 + #endif +#endif +#ifndef HEATER_4_RAW_HI_TEMP + #ifdef HEATER_4_USES_THERMISTOR + #define HEATER_4_RAW_HI_TEMP 0 + #define HEATER_4_RAW_LO_TEMP 16383 + #else + #define HEATER_4_RAW_HI_TEMP 16383 + #define HEATER_4_RAW_LO_TEMP 0 + #endif +#endif +#ifndef HEATER_BED_RAW_HI_TEMP + #ifdef BED_USES_THERMISTOR + #define HEATER_BED_RAW_HI_TEMP 0 + #define HEATER_BED_RAW_LO_TEMP 16383 + #else + #define HEATER_BED_RAW_HI_TEMP 16383 + #define HEATER_BED_RAW_LO_TEMP 0 + #endif +#endif + +#endif // THERMISTORTABLES_H_ diff --git a/trunk/Arduino/Marlin_1.1.6/twibus.cpp b/trunk/Arduino/Marlin_1.1.6/twibus.cpp new file mode 100644 index 00000000..4e29ef88 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/twibus.cpp @@ -0,0 +1,204 @@ +/** + * 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 . + * + */ + +#include "Marlin.h" + +#if ENABLED(EXPERIMENTAL_I2CBUS) + +#include "twibus.h" +#include + +TWIBus::TWIBus() { + #if I2C_SLAVE_ADDRESS == 0 + Wire.begin(); // No address joins the BUS as the master + #else + Wire.begin(I2C_SLAVE_ADDRESS); // Join the bus as a slave + #endif + this->reset(); +} + +void TWIBus::reset() { + this->buffer_s = 0; + this->buffer[0] = 0x00; +} + +void TWIBus::address(const uint8_t adr) { + if (!WITHIN(adr, 8, 127)) { + SERIAL_ECHO_START(); + SERIAL_ECHOLNPGM("Bad I2C address (8-127)"); + } + + this->addr = adr; + + #if ENABLED(DEBUG_TWIBUS) + debug(PSTR("address"), adr); + #endif +} + +void TWIBus::addbyte(const char c) { + if (this->buffer_s >= COUNT(this->buffer)) return; + this->buffer[this->buffer_s++] = c; + #if ENABLED(DEBUG_TWIBUS) + debug(PSTR("addbyte"), c); + #endif +} + +void TWIBus::addbytes(char src[], uint8_t bytes) { + #if ENABLED(DEBUG_TWIBUS) + debug(PSTR("addbytes"), bytes); + #endif + while (bytes--) this->addbyte(*src++); +} + +void TWIBus::addstring(char str[]) { + #if ENABLED(DEBUG_TWIBUS) + debug(PSTR("addstring"), str); + #endif + while (char c = *str++) this->addbyte(c); +} + +void TWIBus::send() { + #if ENABLED(DEBUG_TWIBUS) + debug(PSTR("send"), this->addr); + #endif + + Wire.beginTransmission(this->addr); + Wire.write(this->buffer, this->buffer_s); + Wire.endTransmission(); + + this->reset(); +} + +// static +void TWIBus::echoprefix(uint8_t bytes, const char prefix[], uint8_t adr) { + SERIAL_ECHO_START(); + serialprintPGM(prefix); + SERIAL_ECHOPAIR(": from:", adr); + SERIAL_ECHOPAIR(" bytes:", bytes); + SERIAL_ECHOPGM (" data:"); +} + +// static +void TWIBus::echodata(uint8_t bytes, const char prefix[], uint8_t adr) { + echoprefix(bytes, prefix, adr); + while (bytes-- && Wire.available()) SERIAL_CHAR(Wire.read()); + SERIAL_EOL(); +} + +void TWIBus::echobuffer(const char prefix[], uint8_t adr) { + echoprefix(this->buffer_s, prefix, adr); + for (uint8_t i = 0; i < this->buffer_s; i++) SERIAL_CHAR(this->buffer[i]); + SERIAL_EOL(); +} + +bool TWIBus::request(const uint8_t bytes) { + if (!this->addr) return false; + + #if ENABLED(DEBUG_TWIBUS) + debug(PSTR("request"), bytes); + #endif + + // requestFrom() is a blocking function + if (Wire.requestFrom(this->addr, bytes) == 0) { + #if ENABLED(DEBUG_TWIBUS) + debug("request fail", this->addr); + #endif + return false; + } + + return true; +} + +void TWIBus::relay(const uint8_t bytes) { + #if ENABLED(DEBUG_TWIBUS) + debug(PSTR("relay"), bytes); + #endif + + if (this->request(bytes)) + echodata(bytes, PSTR("i2c-reply"), this->addr); +} + +uint8_t TWIBus::capture(char *dst, const uint8_t bytes) { + this->reset(); + uint8_t count = 0; + while (count < bytes && Wire.available()) + dst[count++] = Wire.read(); + + #if ENABLED(DEBUG_TWIBUS) + debug(PSTR("capture"), count); + #endif + + return count; +} + +// static +void TWIBus::flush() { + while (Wire.available()) Wire.read(); +} + +#if I2C_SLAVE_ADDRESS > 0 + + void TWIBus::receive(uint8_t bytes) { + #if ENABLED(DEBUG_TWIBUS) + debug(PSTR("receive"), bytes); + #endif + echodata(bytes, PSTR("i2c-receive"), 0); + } + + void TWIBus::reply(char str[]/*=NULL*/) { + #if ENABLED(DEBUG_TWIBUS) + debug(PSTR("reply"), str); + #endif + + if (str) { + this->reset(); + this->addstring(str); + } + + Wire.write(this->buffer, this->buffer_s); + + this->reset(); + } + +#endif + +#if ENABLED(DEBUG_TWIBUS) + + // static + void TWIBus::prefix(const char func[]) { + SERIAL_ECHOPGM("TWIBus::"); + serialprintPGM(func); + SERIAL_ECHOPGM(": "); + } + void TWIBus::debug(const char func[], uint32_t adr) { + if (DEBUGGING(INFO)) { prefix(func); SERIAL_ECHOLN(adr); } + } + void TWIBus::debug(const char func[], char c) { + if (DEBUGGING(INFO)) { prefix(func); SERIAL_ECHOLN(c); } + } + void TWIBus::debug(const char func[], char str[]) { + if (DEBUGGING(INFO)) { prefix(func); SERIAL_ECHOLN(str); } + } + +#endif + +#endif // EXPERIMENTAL_I2CBUS diff --git a/trunk/Arduino/Marlin_1.1.6/twibus.h b/trunk/Arduino/Marlin_1.1.6/twibus.h new file mode 100644 index 00000000..03763972 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/twibus.h @@ -0,0 +1,242 @@ +/** + * 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 . + * + */ + +#ifndef TWIBUS_H +#define TWIBUS_H + +#include "macros.h" + +#include + +// Print debug messages with M111 S2 (Uses 236 bytes of PROGMEM) +//#define DEBUG_TWIBUS + +typedef void (*twiReceiveFunc_t)(int bytes); +typedef void (*twiRequestFunc_t)(); + +#define TWIBUS_BUFFER_SIZE 32 + +/** + * TWIBUS class + * + * This class implements a wrapper around the two wire (I2C) bus, allowing + * Marlin to send and request data from any slave device on the bus. + * + * The two main consumers of this class are M260 and M261. M260 provides a way + * to send an I2C packet to a device (no repeated starts) by caching up to 32 + * bytes in a buffer and then sending the buffer. + * M261 requests data from a device. The received data is relayed to serial out + * for the host to interpret. + * + * For more information see + * - http://marlinfw.org/docs/gcode/M260.html + * - http://marlinfw.org/docs/gcode/M261.html + * + */ +class TWIBus { + private: + /** + * @brief Number of bytes on buffer + * @description Number of bytes in the buffer waiting to be flushed to the bus + */ + uint8_t buffer_s = 0; + + /** + * @brief Internal buffer + * @details A fixed buffer. TWI commands can be no longer than this. + */ + char buffer[TWIBUS_BUFFER_SIZE]; + + + public: + /** + * @brief Target device address + * @description The target device address. Persists until changed. + */ + uint8_t addr = 0; + + /** + * @brief Class constructor + * @details Initialize the TWI bus and clear the buffer + */ + TWIBus(); + + /** + * @brief Reset the buffer + * @details Set the buffer to a known-empty state + */ + void reset(); + + /** + * @brief Send the buffer data to the bus + * @details Flush the buffer to the target address + */ + void send(); + + /** + * @brief Add one byte to the buffer + * @details Add a byte to the end of the buffer. + * Silently fails if the buffer is full. + * + * @param c a data byte + */ + void addbyte(const char c); + + /** + * @brief Add some bytes to the buffer + * @details Add bytes to the end of the buffer. + * Concatenates at the buffer size. + * + * @param src source data address + * @param bytes the number of bytes to add + */ + void addbytes(char src[], uint8_t bytes); + + /** + * @brief Add a null-terminated string to the buffer + * @details Add bytes to the end of the buffer up to a nul. + * Concatenates at the buffer size. + * + * @param str source string address + */ + void addstring(char str[]); + + /** + * @brief Set the target slave address + * @details The target slave address for sending the full packet + * + * @param adr 7-bit integer address + */ + void address(const uint8_t adr); + + /** + * @brief Prefix for echo to serial + * @details Echo a label, length, address, and "data:" + * + * @param bytes the number of bytes to request + */ + static void echoprefix(uint8_t bytes, const char prefix[], uint8_t adr); + + /** + * @brief Echo data on the bus to serial + * @details Echo some number of bytes from the bus + * to serial in a parser-friendly format. + * + * @param bytes the number of bytes to request + */ + static void echodata(uint8_t bytes, const char prefix[], uint8_t adr); + + /** + * @brief Echo data in the buffer to serial + * @details Echo the entire buffer to serial + * to serial in a parser-friendly format. + * + * @param bytes the number of bytes to request + */ + void echobuffer(const char prefix[], uint8_t adr); + + /** + * @brief Request data from the slave device and wait. + * @details Request a number of bytes from a slave device. + * Wait for the data to arrive, and return true + * on success. + * + * @param bytes the number of bytes to request + * @return status of the request: true=success, false=fail + */ + bool request(const uint8_t bytes); + + /** + * @brief Capture data from the bus into the buffer. + * @details Capture data after a request has succeeded. + * + * @param bytes the number of bytes to request + * @return the number of bytes captured to the buffer + */ + uint8_t capture(char *dst, const uint8_t bytes); + + /** + * @brief Flush the i2c bus. + * @details Get all bytes on the bus and throw them away. + */ + static void flush(); + + /** + * @brief Request data from the slave device, echo to serial. + * @details Request a number of bytes from a slave device and output + * the returned data to serial in a parser-friendly format. + * + * @param bytes the number of bytes to request + */ + void relay(const uint8_t bytes); + + #if I2C_SLAVE_ADDRESS > 0 + + /** + * @brief Register a slave receive handler + * @details Set a handler to receive data addressed to us + * + * @param handler A function to handle receiving bytes + */ + inline void onReceive(const twiReceiveFunc_t handler) { Wire.onReceive(handler); } + + /** + * @brief Register a slave request handler + * @details Set a handler to send data requested from us + * + * @param handler A function to handle receiving bytes + */ + inline void onRequest(const twiRequestFunc_t handler) { Wire.onRequest(handler); } + + /** + * @brief Default handler to receive + * @details Receive bytes sent to our slave address + * and simply echo them to serial. + */ + void receive(uint8_t bytes); + + /** + * @brief Send a reply to the bus + * @details Send the buffer and clear it. + * If a string is passed, write it into the buffer first. + */ + void reply(char str[]=NULL); + inline void reply(const char str[]) { this->reply((char*)str); } + + #endif + + #if ENABLED(DEBUG_TWIBUS) + + /** + * @brief Prints a debug message + * @details Prints a simple debug message "TWIBus::function: value" + */ + static void prefix(const char func[]); + static void debug(const char func[], uint32_t adr); + 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); } + + #endif +}; + +#endif // TWIBUS_H diff --git a/trunk/Arduino/Marlin_1.1.6/types.h b/trunk/Arduino/Marlin_1.1.6/types.h new file mode 100644 index 00000000..8ab7beeb --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/types.h @@ -0,0 +1,28 @@ +/** + * 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 . + * + */ + +#ifndef __TYPES_H__ +#define __TYPES_H__ + +typedef unsigned long millis_t; + +#endif diff --git a/trunk/Arduino/Marlin_1.1.6/ubl.cpp b/trunk/Arduino/Marlin_1.1.6/ubl.cpp new file mode 100644 index 00000000..9805aff3 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/ubl.cpp @@ -0,0 +1,196 @@ +/** + * 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 . + * + */ + +#include "Marlin.h" +#include "math.h" + +#if ENABLED(AUTO_BED_LEVELING_UBL) + + #include "ubl.h" + #include "hex_print_routines.h" + #include "temperature.h" + + extern Planner planner; + + /** + * These support functions allow the use of large bit arrays of flags that take very + * little RAM. Currently they are limited to being 16x16 in size. Changing the declaration + * to unsigned long will allow us to go to 32x32 if higher resolution Mesh's are needed + * in the future. + */ + void bit_clear(uint16_t bits[16], uint8_t x, uint8_t y) { CBI(bits[y], x); } + void bit_set(uint16_t bits[16], uint8_t x, uint8_t y) { SBI(bits[y], x); } + bool is_bit_set(uint16_t bits[16], uint8_t x, uint8_t y) { return TEST(bits[y], x); } + + uint8_t ubl_cnt = 0; + + void unified_bed_leveling::echo_name() { SERIAL_PROTOCOLPGM("Unified Bed Leveling"); } + + void unified_bed_leveling::report_state() { + echo_name(); + SERIAL_PROTOCOLPGM(" System v" UBL_VERSION " "); + if (!state.active) SERIAL_PROTOCOLPGM("in"); + SERIAL_PROTOCOLLNPGM("active."); + safe_delay(50); + } + + static void serial_echo_xy(const int16_t x, const int16_t y) { + SERIAL_CHAR('('); + SERIAL_ECHO(x); + SERIAL_CHAR(','); + SERIAL_ECHO(y); + SERIAL_CHAR(')'); + safe_delay(10); + } + + ubl_state unified_bed_leveling::state; + + float unified_bed_leveling::z_values[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y], + unified_bed_leveling::last_specified_z; + + // 15 is the maximum nubmer of grid points supported + 1 safety margin for now, + // until determinism prevails + constexpr float unified_bed_leveling::_mesh_index_to_xpos[16], + unified_bed_leveling::_mesh_index_to_ypos[16]; + + bool unified_bed_leveling::g26_debug_flag = false, + unified_bed_leveling::has_control_of_lcd_panel = false; + + volatile int unified_bed_leveling::encoder_diff; + + unified_bed_leveling::unified_bed_leveling() { + ubl_cnt++; // Debug counter to insure we only have one UBL object present in memory. We can eliminate this (and all references to ubl_cnt) very soon. + reset(); + } + + void unified_bed_leveling::reset() { + set_bed_leveling_enabled(false); + state.z_offset = 0; + state.storage_slot = -1; + #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) + planner.z_fade_height = 10.0; + #endif + ZERO(z_values); + last_specified_z = -999.9; + } + + void unified_bed_leveling::invalidate() { + set_bed_leveling_enabled(false); + state.z_offset = 0; + set_all_mesh_points_to_value(NAN); + } + + void unified_bed_leveling::set_all_mesh_points_to_value(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; + } + } + } + + // display_map() currently produces three different mesh map types + // 0 : suitable for PronterFace and Repetier's serial console + // 1 : .CSV file suitable for importation into various spread sheets + // 2 : disply of the map data on a RepRap Graphical LCD Panel + + void unified_bed_leveling::display_map(const int map_type) { + constexpr uint8_t spaces = 8 * (GRID_MAX_POINTS_X - 2); + + SERIAL_PROTOCOLPGM("\nBed Topography Report"); + if (map_type == 0) { + SERIAL_PROTOCOLPGM(":\n\n"); + serial_echo_xy(0, GRID_MAX_POINTS_Y - 1); + SERIAL_ECHO_SP(spaces + 3); + serial_echo_xy(GRID_MAX_POINTS_X - 1, GRID_MAX_POINTS_Y - 1); + SERIAL_EOL(); + serial_echo_xy(UBL_MESH_MIN_X, UBL_MESH_MAX_Y); + SERIAL_ECHO_SP(spaces); + serial_echo_xy(UBL_MESH_MAX_X, UBL_MESH_MAX_Y); + SERIAL_EOL(); + } + else { + SERIAL_PROTOCOLPGM(" for "); + serialprintPGM(map_type == 1 ? PSTR("CSV:\n\n") : PSTR("LCD:\n\n")); + } + + const float current_xi = get_cell_index_x(current_position[X_AXIS] + (MESH_X_DIST) / 2.0), + current_yi = get_cell_index_y(current_position[Y_AXIS] + (MESH_Y_DIST) / 2.0); + + for (int8_t j = GRID_MAX_POINTS_Y - 1; j >= 0; j--) { + for (uint8_t i = 0; i < GRID_MAX_POINTS_X; i++) { + const bool is_current = i == current_xi && j == current_yi; + + // is the nozzle here? then mark the number + if (map_type == 0) SERIAL_CHAR(is_current ? '[' : ' '); + + const float f = z_values[i][j]; + if (isnan(f)) { + serialprintPGM(map_type == 0 ? PSTR(" . ") : PSTR("NAN")); + } + else if (map_type <= 1) { + // if we don't do this, the columns won't line up nicely + if (map_type == 0 && f >= 0.0) SERIAL_CHAR(' '); + SERIAL_PROTOCOL_F(f, 3); + } + idle(); + if (map_type == 1 && i < GRID_MAX_POINTS_X - 1) SERIAL_CHAR(','); + + #if TX_BUFFER_SIZE > 0 + MYSERIAL.flushTX(); + #endif + safe_delay(15); + if (map_type == 0) { + SERIAL_CHAR(is_current ? ']' : ' '); + SERIAL_CHAR(' '); + } + } + SERIAL_EOL(); + if (j && map_type == 0) { // we want the (0,0) up tight against the block of numbers + SERIAL_CHAR(' '); + SERIAL_EOL(); + } + } + + if (map_type == 0) { + serial_echo_xy(UBL_MESH_MIN_X, UBL_MESH_MIN_Y); + SERIAL_ECHO_SP(spaces + 4); + serial_echo_xy(UBL_MESH_MAX_X, UBL_MESH_MIN_Y); + SERIAL_EOL(); + serial_echo_xy(0, 0); + SERIAL_ECHO_SP(spaces + 5); + serial_echo_xy(GRID_MAX_POINTS_X - 1, 0); + SERIAL_EOL(); + } + } + + bool unified_bed_leveling::sanity_check() { + uint8_t error_flag = 0; + + if (settings.calc_num_meshes() < 1) { + SERIAL_PROTOCOLLNPGM("?Insufficient EEPROM storage for a mesh of this size."); + error_flag++; + } + + return !!error_flag; + } + +#endif // AUTO_BED_LEVELING_UBL diff --git a/trunk/Arduino/Marlin_1.1.6/ubl.h b/trunk/Arduino/Marlin_1.1.6/ubl.h new file mode 100644 index 00000000..e11c743b --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/ubl.h @@ -0,0 +1,412 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2016, 2017 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#ifndef UNIFIED_BED_LEVELING_H +#define UNIFIED_BED_LEVELING_H + +#include "MarlinConfig.h" + +#if ENABLED(AUTO_BED_LEVELING_UBL) + #include "Marlin.h" + #include "planner.h" + #include "math.h" + #include "vector_3.h" + #include "configuration_store.h" + + #define UBL_VERSION "1.01" + #define UBL_OK false + #define UBL_ERR true + + #define USE_NOZZLE_AS_REFERENCE 0 + #define USE_PROBE_AS_REFERENCE 1 + + typedef struct { + int8_t x_index, y_index; + float distance; // When populated, the distance from the search location + } mesh_index_pair; + + // ubl.cpp + + void bit_clear(uint16_t bits[16], uint8_t x, uint8_t y); + void bit_set(uint16_t bits[16], uint8_t x, uint8_t y); + bool is_bit_set(uint16_t bits[16], uint8_t x, uint8_t y); + + // ubl_motion.cpp + + void debug_current_and_destination(const char * const title); + + // ubl_G29.cpp + + enum MeshPointType { INVALID, REAL, SET_IN_BITMAP }; + + // External references + + char *ftostr43sign(const float&, char); + bool ubl_lcd_clicked(); + void home_all_axes(); + + extern uint8_t ubl_cnt; + + /////////////////////////////////////////////////////////////////////////////////////////////////////// + + #if ENABLED(ULTRA_LCD) + extern char lcd_status_message[]; + void lcd_quick_feedback(); + #endif + + #define MESH_X_DIST (float(UBL_MESH_MAX_X - (UBL_MESH_MIN_X)) / float(GRID_MAX_POINTS_X - 1)) + #define MESH_Y_DIST (float(UBL_MESH_MAX_Y - (UBL_MESH_MIN_Y)) / float(GRID_MAX_POINTS_Y - 1)) + + typedef struct { + bool active = false; + float z_offset = 0.0; + int8_t storage_slot = -1; + } ubl_state; + + class unified_bed_leveling { + private: + + static float last_specified_z; + + static int g29_verbose_level, + g29_phase_value, + g29_repetition_cnt, + g29_storage_slot, + g29_map_type; + static bool g29_c_flag, g29_x_flag, g29_y_flag; + static float g29_x_pos, g29_y_pos, + g29_card_thickness, + g29_constant; + + #if HAS_BED_PROBE + static int g29_grid_size; + #endif + + #if ENABLED(UBL_G26_MESH_VALIDATION) + static float g26_extrusion_multiplier, + g26_retraction_multiplier, + g26_nozzle, + g26_filament_diameter, + g26_prime_length, + g26_x_pos, g26_y_pos, + g26_ooze_amount, + g26_layer_height; + static int16_t g26_bed_temp, + g26_hotend_temp, + g26_repeats; + static int8_t g26_prime_flag; + static bool g26_continue_with_closest, g26_keep_heaters_on; + #endif + + static float measure_point_with_encoder(); + static float measure_business_card_thickness(float); + static bool g29_parameter_parsing(); + static void find_mean_mesh_height(); + static void shift_mesh_height(); + static void probe_entire_mesh(const float &lx, const float &ly, const bool do_ubl_mesh_map, const bool stow_probe, bool do_furthest); + static void manually_probe_remaining_mesh(const float&, const float&, const float&, const float&, const bool); + static void tilt_mesh_based_on_3pts(const float &z1, const float &z2, const float &z3); + static void tilt_mesh_based_on_probed_grid(const bool do_ubl_mesh_map); + static void g29_what_command(); + static void g29_eeprom_dump(); + static void g29_compare_current_mesh_to_stored_mesh(); + static void fine_tune_mesh(const float &lx, const float &ly, const bool do_ubl_mesh_map); + static bool smart_fill_one(const uint8_t x, const uint8_t y, const int8_t xdir, const int8_t ydir); + static void smart_fill_mesh(); + + #if ENABLED(UBL_G26_MESH_VALIDATION) + static bool exit_from_g26(); + static bool parse_G26_parameters(); + static void G26_line_to_destination(const float &feed_rate); + static mesh_index_pair find_closest_circle_to_print(const float&, const float&); + static bool look_for_lines_to_connect(); + static bool turn_on_heaters(); + static bool prime_nozzle(); + static void retract_filament(const float where[XYZE]); + static void recover_filament(const float where[XYZE]); + static void print_line_from_here_to_there(const float&, const float&, const float&, const float&, const float&, const float&); + static void move_to(const float&, const float&, const float&, const float&); + inline static void move_to(const float where[XYZE], const float &de) { move_to(where[X_AXIS], where[Y_AXIS], where[Z_AXIS], de); } + #endif + + public: + + static void echo_name(); + static void report_state(); + static void save_ubl_active_state_and_disable(); + static void restore_ubl_active_state_and_leave(); + static void display_map(const int); + static mesh_index_pair find_closest_mesh_point_of_type(const MeshPointType, const float&, const float&, const bool, uint16_t[16], bool); + static void reset(); + static void invalidate(); + static void set_all_mesh_points_to_value(float); + static bool sanity_check(); + + static void G29() _O0; // O0 for no optimization + static void smart_fill_wlsf(const float &) _O2; // O2 gives smaller code than Os on A2560 + + #if ENABLED(UBL_G26_MESH_VALIDATION) + static void G26(); + #endif + + static ubl_state state; + + static float z_values[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y]; + + // 15 is the maximum nubmer of grid points supported + 1 safety margin for now, + // until determinism prevails + constexpr static float _mesh_index_to_xpos[16] PROGMEM = { + UBL_MESH_MIN_X + 0 * (MESH_X_DIST), UBL_MESH_MIN_X + 1 * (MESH_X_DIST), + UBL_MESH_MIN_X + 2 * (MESH_X_DIST), UBL_MESH_MIN_X + 3 * (MESH_X_DIST), + UBL_MESH_MIN_X + 4 * (MESH_X_DIST), UBL_MESH_MIN_X + 5 * (MESH_X_DIST), + UBL_MESH_MIN_X + 6 * (MESH_X_DIST), UBL_MESH_MIN_X + 7 * (MESH_X_DIST), + UBL_MESH_MIN_X + 8 * (MESH_X_DIST), UBL_MESH_MIN_X + 9 * (MESH_X_DIST), + UBL_MESH_MIN_X + 10 * (MESH_X_DIST), UBL_MESH_MIN_X + 11 * (MESH_X_DIST), + UBL_MESH_MIN_X + 12 * (MESH_X_DIST), UBL_MESH_MIN_X + 13 * (MESH_X_DIST), + UBL_MESH_MIN_X + 14 * (MESH_X_DIST), UBL_MESH_MIN_X + 15 * (MESH_X_DIST) + }; + + constexpr static float _mesh_index_to_ypos[16] PROGMEM = { + UBL_MESH_MIN_Y + 0 * (MESH_Y_DIST), UBL_MESH_MIN_Y + 1 * (MESH_Y_DIST), + UBL_MESH_MIN_Y + 2 * (MESH_Y_DIST), UBL_MESH_MIN_Y + 3 * (MESH_Y_DIST), + UBL_MESH_MIN_Y + 4 * (MESH_Y_DIST), UBL_MESH_MIN_Y + 5 * (MESH_Y_DIST), + UBL_MESH_MIN_Y + 6 * (MESH_Y_DIST), UBL_MESH_MIN_Y + 7 * (MESH_Y_DIST), + UBL_MESH_MIN_Y + 8 * (MESH_Y_DIST), UBL_MESH_MIN_Y + 9 * (MESH_Y_DIST), + UBL_MESH_MIN_Y + 10 * (MESH_Y_DIST), UBL_MESH_MIN_Y + 11 * (MESH_Y_DIST), + UBL_MESH_MIN_Y + 12 * (MESH_Y_DIST), UBL_MESH_MIN_Y + 13 * (MESH_Y_DIST), + UBL_MESH_MIN_Y + 14 * (MESH_Y_DIST), UBL_MESH_MIN_Y + 15 * (MESH_Y_DIST) + }; + + static bool g26_debug_flag, has_control_of_lcd_panel; + + static volatile int encoder_diff; // Volatile because it's changed at interrupt time. + + unified_bed_leveling(); + + FORCE_INLINE static void set_z(const int8_t px, const int8_t py, const float &z) { z_values[px][py] = z; } + + static int8_t get_cell_index_x(const float &x) { + const int8_t cx = (x - (UBL_MESH_MIN_X)) * (1.0 / (MESH_X_DIST)); + return constrain(cx, 0, (GRID_MAX_POINTS_X) - 1); // -1 is appropriate if we want all movement to the X_MAX + } // position. But with this defined this way, it is possible + // to extrapolate off of this point even further out. Probably + // that is OK because something else should be keeping that from + // happening and should not be worried about at this level. + static int8_t get_cell_index_y(const float &y) { + const int8_t cy = (y - (UBL_MESH_MIN_Y)) * (1.0 / (MESH_Y_DIST)); + return constrain(cy, 0, (GRID_MAX_POINTS_Y) - 1); // -1 is appropriate if we want all movement to the Y_MAX + } // position. But with this defined this way, it is possible + // to extrapolate off of this point even further out. Probably + // that is OK because something else should be keeping that from + // happening and should not be worried about at this level. + + static int8_t find_closest_x_index(const float &x) { + const int8_t px = (x - (UBL_MESH_MIN_X) + (MESH_X_DIST) * 0.5) * (1.0 / (MESH_X_DIST)); + return WITHIN(px, 0, GRID_MAX_POINTS_X - 1) ? px : -1; + } + + static int8_t find_closest_y_index(const float &y) { + const int8_t py = (y - (UBL_MESH_MIN_Y) + (MESH_Y_DIST) * 0.5) * (1.0 / (MESH_Y_DIST)); + return WITHIN(py, 0, GRID_MAX_POINTS_Y - 1) ? py : -1; + } + + /** + * z2 --| + * z0 | | + * | | + (z2-z1) + * z1 | | | + * ---+-------------+--------+-- --| + * a1 a0 a2 + * |<---delta_a---------->| + * + * calc_z0 is the basis for all the Mesh Based correction. It is used to + * find the expected Z Height at a position between two known Z-Height locations. + * + * It is fairly expensive with its 4 floating point additions and 2 floating point + * multiplications. + */ + FORCE_INLINE static float calc_z0(const float &a0, const float &a1, const float &z1, const float &a2, const float &z2) { + return z1 + (z2 - z1) * (a0 - a1) / (a2 - a1); + } + + /** + * z_correction_for_x_on_horizontal_mesh_line is an optimization for + * the case where the printer is making a vertical line that only crosses horizontal mesh lines. + */ + inline static float z_correction_for_x_on_horizontal_mesh_line(const float &lx0, const int x1_i, const int yi) { + if (!WITHIN(x1_i, 0, GRID_MAX_POINTS_X - 2) || !WITHIN(yi, 0, GRID_MAX_POINTS_Y - 1)) { + serialprintPGM( !WITHIN(x1_i, 0, GRID_MAX_POINTS_X - 1) ? PSTR("x1l_i") : PSTR("yi") ); + SERIAL_ECHOPAIR(" out of bounds in z_correction_for_x_on_horizontal_mesh_line(lx0=", lx0); + SERIAL_ECHOPAIR(",x1_i=", x1_i); + SERIAL_ECHOPAIR(",yi=", yi); + SERIAL_CHAR(')'); + SERIAL_EOL(); + return NAN; + } + + const float xratio = (RAW_X_POSITION(lx0) - mesh_index_to_xpos(x1_i)) * (1.0 / (MESH_X_DIST)), + z1 = z_values[x1_i][yi]; + + return z1 + xratio * (z_values[x1_i + 1][yi] - z1); + } + + // + // See comments above for z_correction_for_x_on_horizontal_mesh_line + // + inline static float z_correction_for_y_on_vertical_mesh_line(const float &ly0, const int xi, const int y1_i) { + if (!WITHIN(xi, 0, GRID_MAX_POINTS_X - 1) || !WITHIN(y1_i, 0, GRID_MAX_POINTS_Y - 2)) { + serialprintPGM( !WITHIN(xi, 0, GRID_MAX_POINTS_X - 1) ? PSTR("xi") : PSTR("yl_i") ); + SERIAL_ECHOPAIR(" out of bounds in z_correction_for_y_on_vertical_mesh_line(ly0=", ly0); + SERIAL_ECHOPAIR(", xi=", xi); + SERIAL_ECHOPAIR(", y1_i=", y1_i); + SERIAL_CHAR(')'); + SERIAL_EOL(); + return NAN; + } + + const float yratio = (RAW_Y_POSITION(ly0) - mesh_index_to_ypos(y1_i)) * (1.0 / (MESH_Y_DIST)), + z1 = z_values[xi][y1_i]; + + return z1 + yratio * (z_values[xi][y1_i + 1] - z1); + } + + /** + * This is the generic Z-Correction. It works anywhere within a Mesh Cell. It first + * does a linear interpolation along both of the bounding X-Mesh-Lines to find the + * Z-Height at both ends. Then it does a linear interpolation of these heights based + * on the Y position within the cell. + */ + static float get_z_correction(const float &lx0, const float &ly0) { + const int8_t cx = get_cell_index_x(RAW_X_POSITION(lx0)), + cy = get_cell_index_y(RAW_Y_POSITION(ly0)); + + if (!WITHIN(cx, 0, GRID_MAX_POINTS_X - 2) || !WITHIN(cy, 0, GRID_MAX_POINTS_Y - 2)) { + + SERIAL_ECHOPAIR("? in get_z_correction(lx0=", lx0); + SERIAL_ECHOPAIR(", ly0=", ly0); + SERIAL_CHAR(')'); + SERIAL_EOL(); + + #if ENABLED(ULTRA_LCD) + strcpy(lcd_status_message, "get_z_correction() indexes out of range."); + lcd_quick_feedback(); + #endif + return NAN; // this used to return state.z_offset + } + + const float z1 = calc_z0(RAW_X_POSITION(lx0), + mesh_index_to_xpos(cx), z_values[cx][cy], + mesh_index_to_xpos(cx + 1), z_values[cx + 1][cy]); + + const float z2 = calc_z0(RAW_X_POSITION(lx0), + mesh_index_to_xpos(cx), z_values[cx][cy + 1], + mesh_index_to_xpos(cx + 1), z_values[cx + 1][cy + 1]); + + float z0 = calc_z0(RAW_Y_POSITION(ly0), + mesh_index_to_ypos(cy), z1, + mesh_index_to_ypos(cy + 1), z2); + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(MESH_ADJUST)) { + SERIAL_ECHOPAIR(" raw get_z_correction(", lx0); + SERIAL_CHAR(','); + SERIAL_ECHO(ly0); + SERIAL_ECHOPGM(") = "); + SERIAL_ECHO_F(z0, 6); + } + #endif + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(MESH_ADJUST)) { + SERIAL_ECHOPGM(" >>>---> "); + SERIAL_ECHO_F(z0, 6); + SERIAL_EOL(); + } + #endif + + if (isnan(z0)) { // if part of the Mesh is undefined, it will show up as NAN + z0 = 0.0; // in ubl.z_values[][] and propagate through the + // calculations. If our correction is NAN, we throw it out + // because part of the Mesh is undefined and we don't have the + // information we need to complete the height correction. + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(MESH_ADJUST)) { + SERIAL_ECHOPAIR("??? Yikes! NAN in get_z_correction(", lx0); + SERIAL_CHAR(','); + SERIAL_ECHO(ly0); + SERIAL_CHAR(')'); + SERIAL_EOL(); + } + #endif + } + return z0; // there used to be a +state.z_offset on this line + } + + /** + * This function sets the Z leveling fade factor based on the given Z height, + * only re-calculating when necessary. + * + * Returns 1.0 if planner.z_fade_height is 0.0. + * Returns 0.0 if Z is past the specified 'Fade Height'. + */ + #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) + static inline float fade_scaling_factor_for_z(const float &lz) { + if (planner.z_fade_height == 0.0) return 1.0; + static float fade_scaling_factor = 1.0; + const float rz = RAW_Z_POSITION(lz); + if (last_specified_z != rz) { + last_specified_z = rz; + fade_scaling_factor = + rz < planner.z_fade_height + ? 1.0 - (rz * planner.inverse_z_fade_height) + : 0.0; + } + return fade_scaling_factor; + } + #else + FORCE_INLINE static float fade_scaling_factor_for_z(const float &lz) { return 1.0; } + #endif + + FORCE_INLINE static float mesh_index_to_xpos(const uint8_t i) { + return i < GRID_MAX_POINTS_X ? pgm_read_float(&_mesh_index_to_xpos[i]) : UBL_MESH_MIN_X + i * (MESH_X_DIST); + } + + FORCE_INLINE static float mesh_index_to_ypos(const uint8_t i) { + return i < GRID_MAX_POINTS_Y ? pgm_read_float(&_mesh_index_to_ypos[i]) : UBL_MESH_MIN_Y + i * (MESH_Y_DIST); + } + + static bool prepare_segmented_line_to(const float ltarget[XYZE], const float &feedrate); + static void line_to_destination_cartesian(const float &fr, uint8_t e); + + }; // class unified_bed_leveling + + extern unified_bed_leveling ubl; + + #if ENABLED(UBL_G26_MESH_VALIDATION) + FORCE_INLINE void gcode_G26() { ubl.G26(); } + #endif + + FORCE_INLINE void gcode_G29() { ubl.G29(); } + +#endif // AUTO_BED_LEVELING_UBL +#endif // UNIFIED_BED_LEVELING_H diff --git a/trunk/Arduino/Marlin_1.1.6/ubl_G29.cpp b/trunk/Arduino/Marlin_1.1.6/ubl_G29.cpp new file mode 100644 index 00000000..3ec507a6 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/ubl_G29.cpp @@ -0,0 +1,1859 @@ +/** + * 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 . + * + */ + +#include "MarlinConfig.h" + +#if ENABLED(AUTO_BED_LEVELING_UBL) + + #include "ubl.h" + #include "Marlin.h" + #include "hex_print_routines.h" + #include "configuration_store.h" + #include "ultralcd.h" + #include "stepper.h" + #include "planner.h" + #include "gcode.h" + + #include + #include "least_squares_fit.h" + + #define UBL_G29_P31 + + extern float destination[XYZE], current_position[XYZE]; + + #if ENABLED(NEWPANEL) + void lcd_return_to_status(); + void lcd_mesh_edit_setup(float initial); + float lcd_mesh_edit(); + void lcd_z_offset_edit_setup(float); + extern void _lcd_ubl_output_map_lcd(); + float lcd_z_offset_edit(); + #endif + + extern float meshedit_done; + extern long babysteps_done; + extern float probe_pt(const float &lx, const float &ly, const bool, const uint8_t, const bool=true); + extern bool set_probe_deployed(bool); + extern void set_bed_leveling_enabled(bool); + typedef void (*screenFunc_t)(); + extern void lcd_goto_screen(screenFunc_t screen, const uint32_t encoder = 0); + + #define SIZE_OF_LITTLE_RAISE 1 + #define BIG_RAISE_NOT_NEEDED 0 + + int unified_bed_leveling::g29_verbose_level, + unified_bed_leveling::g29_phase_value, + unified_bed_leveling::g29_repetition_cnt, + unified_bed_leveling::g29_storage_slot = 0, + unified_bed_leveling::g29_map_type; + bool unified_bed_leveling::g29_c_flag, + unified_bed_leveling::g29_x_flag, + unified_bed_leveling::g29_y_flag; + float unified_bed_leveling::g29_x_pos, + unified_bed_leveling::g29_y_pos, + unified_bed_leveling::g29_card_thickness = 0.0, + unified_bed_leveling::g29_constant = 0.0; + + #if HAS_BED_PROBE + int unified_bed_leveling::g29_grid_size; + #endif + + /** + * G29: Unified Bed Leveling by Roxy + * + * Parameters understood by this leveling system: + * + * A Activate Activate the Unified Bed Leveling system. + * + * B # Business Use the 'Business Card' mode of the Manual Probe subsystem with P2. + * Note: A non-compressible Spark Gap feeler gauge is recommended over a business card. + * In this mode of G29 P2, a business or index card is used as a shim that the nozzle can + * grab onto as it is lowered. In principle, the nozzle-bed distance is the same when the + * same resistance is felt in the shim. You can omit the numerical value on first invocation + * of G29 P2 B to measure shim thickness. Subsequent use of 'B' will apply the previously- + * measured thickness by default. + * + * C Continue G29 P1 C continues the generation of a partially-constructed Mesh without invalidating + * previous measurements. + * + * C Constant G29 P2 C specifies a Constant and tells the Manual Probe subsystem to use the current + * location in its search for the closest unmeasured Mesh Point. + * + * G29 P3 C specifies the Constant for the fill. Otherwise, uses a "reasonable" value. + * + * C Current G29 Z C uses the Current location (instead of bed center or nearest edge). + * + * D Disable Disable the Unified Bed Leveling system. + * + * E Stow_probe Stow the probe after each sampled point. + * + * F # Fade Fade the amount of Mesh Based Compensation over a specified height. At the + * specified height, no correction is applied and natural printer kenimatics take over. If no + * number is specified for the command, 10mm is assumed to be reasonable. + * + * H # Height With P2, 'H' specifies the Height to raise the nozzle after each manual probe of the bed. + * If omitted, the nozzle will raise by Z_CLEARANCE_BETWEEN_PROBES. + * + * H # Offset With P4, 'H' specifies the Offset above the mesh height to place the nozzle. + * If omitted, Z_CLEARANCE_BETWEEN_PROBES will be used. + * + * I # Invalidate Invalidate the specified number of Mesh Points near the given 'X' 'Y'. If X or Y are omitted, + * the nozzle location is used. If no 'I' value is given, only the point nearest to the location + * is invalidated. Use 'T' to produce a map afterward. This command is useful to invalidate a + * portion of the Mesh so it can be adjusted using other UBL tools. When attempting to invalidate + * an isolated bad mesh point, the 'T' option shows the nozzle position in the Mesh with (#). You + * can move the nozzle around and use this feature to select the center of the area (or cell) to + * invalidate. + * + * J # Grid Perform a Grid Based Leveling of the current Mesh using a grid with n points on a side. + * Not specifying a grid size will invoke the 3-Point leveling function. + * + * K # Kompare Kompare current Mesh with stored Mesh # replacing current Mesh with the result. This + * command literally performs a diff between two Meshes. + * + * L Load Load Mesh from the previously activated location in the EEPROM. + * + * L # Load Load Mesh from the specified location in the EEPROM. Set this location as activated + * for subsequent Load and Store operations. + * + * The P or Phase commands are used for the bulk of the work to setup a Mesh. In general, your Mesh will + * start off being initialized with a G29 P0 or a G29 P1. Further refinement of the Mesh happens with + * each additional Phase that processes it. + * + * P0 Phase 0 Zero Mesh Data and turn off the Mesh Compensation System. This reverts the + * 3D Printer to the same state it was in before the Unified Bed Leveling Compensation + * was turned on. Setting the entire Mesh to Zero is a special case that allows + * a subsequent G or T leveling operation for backward compatibility. + * + * P1 Phase 1 Invalidate entire Mesh and continue with automatic generation of the Mesh data using + * the Z-Probe. Usually the probe can't reach all areas that the nozzle can reach. On + * Cartesian printers, points within the X_PROBE_OFFSET_FROM_EXTRUDER and Y_PROBE_OFFSET_FROM_EXTRUDER + * area cannot be automatically probed. For Delta printers the area in which DELTA_PROBEABLE_RADIUS + * and DELTA_PRINTABLE_RADIUS do not overlap will not be automatically probed. + * + * Unreachable points will be handled in Phase 2 and Phase 3. + * + * Use 'C' to leave the previous mesh intact and automatically probe needed points. This allows you + * to invalidate parts of the Mesh but still use Automatic Probing. + * + * The 'X' and 'Y' parameters prioritize where to try and measure points. If omitted, the current + * probe position is used. + * + * Use 'T' (Topology) to generate a report of mesh generation. + * + * P1 will suspend Mesh generation if the controller button is held down. Note that you may need + * to press and hold the switch for several seconds if moves are underway. + * + * P2 Phase 2 Probe unreachable points. + * + * Use 'H' to set the height between Mesh points. If omitted, Z_CLEARANCE_BETWEEN_PROBES is used. + * Smaller values will be quicker. Move the nozzle down till it barely touches the bed. Make sure the + * nozzle is clean and unobstructed. Use caution and move slowly. This can damage your printer! + * (Uses SIZE_OF_LITTLE_RAISE mm if the nozzle is moving less than BIG_RAISE_NOT_NEEDED mm.) + * + * The 'H' value can be negative if the Mesh dips in a large area. Press and hold the + * controller button to terminate the current Phase 2 command. You can then re-issue "G29 P 2" + * with an 'H' parameter more suitable for the area you're manually probing. Note that the command + * tries to start in a corner of the bed where movement will be predictable. Override the distance + * calculation location with the X and Y parameters. You can print a Mesh Map (G29 T) to see where + * the mesh is invalidated and where the nozzle needs to move to complete the command. Use 'C' to + * indicate that the search should be based on the current position. + * + * The 'B' parameter for this command is described above. It places the manual probe subsystem into + * Business Card mode where the thickness of a business card is measured and then used to accurately + * set the nozzle height in all manual probing for the duration of the command. A Business card can + * be used, but you'll get better results with a flexible Shim that doesn't compress. This makes it + * easier to produce similar amounts of force and get more accurate measurements. Google if you're + * not sure how to use a shim. + * + * The 'T' (Map) parameter helps track Mesh building progress. + * + * NOTE: P2 requires an LCD controller! + * + * P3 Phase 3 Fill the unpopulated regions of the Mesh with a fixed value. There are two different paths to + * go down: + * + * - If a 'C' constant is specified, the closest invalid mesh points to the nozzle will be filled, + * and a repeat count can then also be specified with 'R'. + * + * - Leaving out 'C' invokes Smart Fill, which scans the mesh from the edges inward looking for + * invalid mesh points. Adjacent points are used to determine the bed slope. If the bed is sloped + * upward from the invalid point, it takes the value of the nearest point. If sloped downward, it's + * replaced by a value that puts all three points in a line. This version of G29 P3 is a quick, easy + * and (usually) safe way to populate unprobed mesh regions before continuing to G26 Mesh Validation + * Pattern. Note that this populates the mesh with unverified values. Pay attention and use caution. + * + * P4 Phase 4 Fine tune the Mesh. The Delta Mesh Compensation System assumes the existence of + * an LCD Panel. It is possible to fine tune the mesh without an LCD Panel using + * G42 and M421. See the UBL documentation for further details. + * + * Phase 4 is meant to be used with G26 Mesh Validation to fine tune the mesh by direct editing + * of Mesh Points. Raise and lower points to fine tune the mesh until it gives consistently reliable + * adhesion. + * + * P4 moves to the closest Mesh Point (and/or the given X Y), raises the nozzle above the mesh height + * by the given 'H' offset (or default Z_CLEARANCE_BETWEEN_PROBES), and waits while the controller is + * used to adjust the nozzle height. On click the displayed height is saved in the mesh. + * + * Start Phase 4 at a specific location with X and Y. Adjust a specific number of Mesh Points with + * the 'R' (Repeat) parameter. (If 'R' is left out, the whole matrix is assumed.) This command can be + * terminated early (e.g., after editing the area of interest) by pressing and holding the encoder button. + * + * The general form is G29 P4 [R points] [X position] [Y position] + * + * The H [offset] parameter is useful if a shim is used to fine-tune the mesh. For a 0.4mm shim the + * command would be G29 P4 H0.4. The nozzle is moved to the shim height, you adjust height to the shim, + * and on click the height minus the shim thickness will be saved in the mesh. + * + * !!Use with caution, as a very poor mesh could cause the nozzle to crash into the bed!! + * + * NOTE: P4 is not available unless you have LCD support enabled! + * + * P5 Phase 5 Find Mean Mesh Height and Standard Deviation. Typically, it is easier to use and + * work with the Mesh if it is Mean Adjusted. You can specify a C parameter to + * Correct the Mesh to a 0.00 Mean Height. Adding a C parameter will automatically + * execute a G29 P6 C . + * + * P6 Phase 6 Shift Mesh height. The entire Mesh's height is adjusted by the height specified + * with the C parameter. Being able to adjust the height of a Mesh is useful tool. It + * can be used to compensate for poorly calibrated Z-Probes and other errors. Ideally, + * you should have the Mesh adjusted for a Mean Height of 0.00 and the Z-Probe measuring + * 0.000 at the Z Home location. + * + * Q Test Load specified Test Pattern to assist in checking correct operation of system. This + * command is not anticipated to be of much value to the typical user. It is intended + * for developers to help them verify correct operation of the Unified Bed Leveling System. + * + * R # Repeat Repeat this command the specified number of times. If no number is specified the + * command will be repeated GRID_MAX_POINTS_X * GRID_MAX_POINTS_Y times. + * + * S Store Store the current Mesh in the Activated area of the EEPROM. It will also store the + * current state of the Unified Bed Leveling system in the EEPROM. + * + * S # Store Store the current Mesh at the specified location in EEPROM. Activate this location + * for subsequent Load and Store operations. Valid storage slot numbers begin at 0 and + * extend to a limit related to the available EEPROM storage. + * + * S -1 Store Store the current Mesh as a print out that is suitable to be feed back into the system + * at a later date. The GCode output can be saved and later replayed by the host software + * to reconstruct the current mesh on another machine. + * + * T Topology Display the Mesh Map Topology. + * 'T' can be used alone (e.g., G29 T) or in combination with most of the other commands. + * This option works with all Phase commands (e.g., G29 P4 R 5 T X 50 Y100 C -.1 O) + * This parameter can also specify a Map Type. T0 (the default) is user-readable. T1 can + * is suitable to paste into a spreadsheet for a 3D graph of the mesh. + * + * U Unlevel Perform a probe of the outer perimeter to assist in physically leveling unlevel beds. + * Only used for G29 P1 T U. This speeds up the probing of the edge of the bed. Useful + * when the entire bed doesn't need to be probed because it will be adjusted. + * + * V # Verbosity Set the verbosity level (0-4) for extra details. (Default 0) + * + * W What? Display valuable Unified Bed Leveling System data. + * + * X # X Location for this command + * + * Y # Y Location for this command + * + * + * Release Notes: + * You MUST do M502, M500 to initialize the storage. Failure to do this will cause all + * kinds of problems. Enabling EEPROM Storage is highly recommended. With EEPROM Storage + * of the mesh, you are limited to 3-Point and Grid Leveling. (G29 P0 T and G29 P0 G + * respectively.) + * + * When you do a G28 and then a G29 P1 to automatically build your first mesh, you are going to notice + * the Unified Bed Leveling probes points further and further away from the starting location. (The + * starting location defaults to the center of the bed.) The original Grid and Mesh leveling used + * a Zig Zag pattern. The new pattern is better, especially for people with Delta printers. This + * allows you to get the center area of the Mesh populated (and edited) quicker. This allows you to + * perform a small print and check out your settings quicker. You do not need to populate the + * entire mesh to use it. (You don't want to spend a lot of time generating a mesh only to realize + * you don't have the resolution or zprobe_zoffset set correctly. The Mesh generation + * gathers points closest to where the nozzle is located unless you specify an (X,Y) coordinate pair. + * + * The Unified Bed Leveling uses a lot of EEPROM storage to hold its data. And it takes some effort + * to get this Mesh data correct for a user's printer. We do not want this data destroyed as + * new versions of Marlin add or subtract to the items stored in EEPROM. So, for the benefit of + * the users, we store the Mesh data at the end of the EEPROM and do not keep it contiguous with the + * other data stored in the EEPROM. (For sure the developers are going to complain about this, but + * this is going to be helpful to the users!) + * + * The foundation of this Bed Leveling System is built on Epatel's Mesh Bed Leveling code. A big + * 'Thanks!' to him and the creators of 3-Point and Grid Based leveling. Combining their contributions + * we now have the functionality and features of all three systems combined. + */ + + void unified_bed_leveling::G29() { + + if (!settings.calc_num_meshes()) { + SERIAL_PROTOCOLLNPGM("?You need to enable your EEPROM and initialize it"); + SERIAL_PROTOCOLLNPGM("with M502, M500, M501 in that order.\n"); + return; + } + + if (g29_parameter_parsing()) return; // abort if parsing the simple parameters causes a problem, + + // Check for commands that require the printer to be homed + if (axis_unhomed_error()) { + const int8_t p_val = parser.intval('P', -1); + if (p_val == 1 || p_val == 2 || p_val == 4 || parser.seen('J')) + home_all_axes(); + } + + // Invalidate Mesh Points. This command is a little bit asymmetrical because + // it directly specifies the repetition count and does not use the 'R' parameter. + if (parser.seen('I')) { + uint8_t cnt = 0; + g29_repetition_cnt = parser.has_value() ? parser.value_int() : 1; + if (g29_repetition_cnt >= GRID_MAX_POINTS) { + set_all_mesh_points_to_value(NAN); + } + else { + while (g29_repetition_cnt--) { + if (cnt > 20) { cnt = 0; idle(); } + const mesh_index_pair location = find_closest_mesh_point_of_type(REAL, g29_x_pos, g29_y_pos, USE_NOZZLE_AS_REFERENCE, NULL, false); + if (location.x_index < 0) { + // No more REACHABLE mesh points to invalidate, so we ASSUME the user + // meant to invalidate the ENTIRE mesh, which cannot be done with + // find_closest_mesh_point loop which only returns REACHABLE points. + set_all_mesh_points_to_value(NAN); + SERIAL_PROTOCOLLNPGM("Entire Mesh invalidated.\n"); + break; // No more invalid Mesh Points to populate + } + z_values[location.x_index][location.y_index] = NAN; + cnt++; + } + } + SERIAL_PROTOCOLLNPGM("Locations invalidated.\n"); + } + + if (parser.seen('Q')) { + const int test_pattern = parser.has_value() ? parser.value_int() : -99; + if (!WITHIN(test_pattern, -1, 2)) { + SERIAL_PROTOCOLLNPGM("Invalid test_pattern value. (-1 to 2)\n"); + return; + } + SERIAL_PROTOCOLLNPGM("Loading test_pattern values.\n"); + switch (test_pattern) { + case -1: + g29_eeprom_dump(); + break; + 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.5 * (GRID_MAX_POINTS_X) - x, + p2 = 0.5 * (GRID_MAX_POINTS_Y) - y; + z_values[x][y] += 2.0 * HYPOT(p1, p2); + } + } + 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 + z_values[x][x] += 9.999; + z_values[x][x + (x < GRID_MAX_POINTS_Y - 1) ? 1 : -1] += 9.999; // We want the altered line several mesh points thick + } + break; + case 2: + // Allow the user to specify the height because 10mm is a little extreme in some cases. + 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.99; + break; + } + } + + #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(parser.seen('T')); + restore_ubl_active_state_and_leave(); + } + else { // grid_size == 0 : A 3-Point leveling has been requested + float z3, z2, z1 = probe_pt(LOGICAL_X_POSITION(UBL_PROBE_PT_1_X), LOGICAL_Y_POSITION(UBL_PROBE_PT_1_Y), false, g29_verbose_level); + if (!isnan(z1)) { + z2 = probe_pt(LOGICAL_X_POSITION(UBL_PROBE_PT_2_X), LOGICAL_Y_POSITION(UBL_PROBE_PT_2_Y), false, g29_verbose_level); + if (!isnan(z2)) + z3 = probe_pt(LOGICAL_X_POSITION(UBL_PROBE_PT_3_X), LOGICAL_Y_POSITION(UBL_PROBE_PT_3_Y), true, g29_verbose_level); + } + + if (isnan(z1) || isnan(z2) || isnan(z3)) { // probe_pt will return NAN if unreachable + SERIAL_ERROR_START(); + SERIAL_ERRORLNPGM("Attempt to probe off the bed."); + goto LEAVE; + } + + // Adjust z1, z2, z3 by the Mesh Height at these points. Just because they're non-zero + // doesn't mean the Mesh is tilted! (Compensate each probe point by what the Mesh says + // its height is.) + + save_ubl_active_state_and_disable(); + z1 -= get_z_correction(LOGICAL_X_POSITION(UBL_PROBE_PT_1_X), LOGICAL_Y_POSITION(UBL_PROBE_PT_1_Y)) /* + zprobe_zoffset */ ; + z2 -= get_z_correction(LOGICAL_X_POSITION(UBL_PROBE_PT_2_X), LOGICAL_Y_POSITION(UBL_PROBE_PT_2_Y)) /* + zprobe_zoffset */ ; + z3 -= get_z_correction(LOGICAL_X_POSITION(UBL_PROBE_PT_3_X), LOGICAL_Y_POSITION(UBL_PROBE_PT_3_Y)) /* + zprobe_zoffset */ ; + + do_blocking_move_to_xy(0.5 * (UBL_MESH_MAX_X - (UBL_MESH_MIN_X)), 0.5 * (UBL_MESH_MAX_Y - (UBL_MESH_MIN_Y))); + tilt_mesh_based_on_3pts(z1, z2, z3); + restore_ubl_active_state_and_leave(); + } + } + + #endif // HAS_BED_PROBE + + if (parser.seen('P')) { + if (WITHIN(g29_phase_value, 0, 1) && state.storage_slot == -1) { + state.storage_slot = 0; + SERIAL_PROTOCOLLNPGM("Default storage slot 0 selected."); + } + + switch (g29_phase_value) { + case 0: + // + // Zero Mesh Data + // + reset(); + SERIAL_PROTOCOLLNPGM("Mesh zeroed."); + break; + + #if HAS_BED_PROBE + + case 1: + // + // Invalidate Entire Mesh and Automatically Probe Mesh in areas that can be reached by the probe + // + if (!parser.seen('C')) { + invalidate(); + SERIAL_PROTOCOLLNPGM("Mesh invalidated. Probing mesh."); + } + if (g29_verbose_level > 1) { + SERIAL_PROTOCOLPAIR("Probing Mesh Points Closest to (", g29_x_pos); + SERIAL_PROTOCOLCHAR(','); + SERIAL_PROTOCOL(g29_y_pos); + SERIAL_PROTOCOLLNPGM(").\n"); + } + probe_entire_mesh(g29_x_pos + X_PROBE_OFFSET_FROM_EXTRUDER, g29_y_pos + Y_PROBE_OFFSET_FROM_EXTRUDER, + parser.seen('T'), parser.seen('E'), parser.seen('U')); + break; + + #endif // HAS_BED_PROBE + + case 2: { + #if ENABLED(NEWPANEL) + // + // Manually Probe Mesh in areas that can't be reached by the probe + // + SERIAL_PROTOCOLLNPGM("Manually probing unreachable mesh locations."); + do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES); + if (!g29_x_flag && !g29_y_flag) { + /** + * Use a good default location for the path. + * The flipped > and < operators in these comparisons is intentional. + * It should cause the probed points to follow a nice path on Cartesian printers. + * It may make sense to have Delta printers default to the center of the bed. + * Until that is decided, this can be forced with the X and Y parameters. + */ + #if IS_KINEMATIC + g29_x_pos = X_HOME_POS; + g29_y_pos = Y_HOME_POS; + #else // cartesian + g29_x_pos = X_PROBE_OFFSET_FROM_EXTRUDER > 0 ? X_BED_SIZE : 0; + g29_y_pos = Y_PROBE_OFFSET_FROM_EXTRUDER < 0 ? Y_BED_SIZE : 0; + #endif + } + + if (parser.seen('C')) { + g29_x_pos = current_position[X_AXIS]; + g29_y_pos = current_position[Y_AXIS]; + } + + if (parser.seen('B')) { + g29_card_thickness = parser.has_value() ? parser.value_float() : measure_business_card_thickness(Z_CLEARANCE_BETWEEN_PROBES); + if (FABS(g29_card_thickness) > 1.5) { + SERIAL_PROTOCOLLNPGM("?Error in Business Card measurement."); + return; + } + } + + if (!position_is_reachable_xy(g29_x_pos, g29_y_pos)) { + SERIAL_PROTOCOLLNPGM("XY outside printable radius."); + return; + } + + const float height = parser.floatval('H', Z_CLEARANCE_BETWEEN_PROBES); + manually_probe_remaining_mesh(g29_x_pos, g29_y_pos, height, g29_card_thickness, parser.seen('T')); + + SERIAL_PROTOCOLLNPGM("G29 P2 finished."); + + #else + + SERIAL_PROTOCOLLNPGM("?P2 is only available when an LCD is present."); + return; + + #endif + } break; + + case 3: { + /** + * Populate invalid mesh areas. Proceed with caution. + * Two choices are available: + * - Specify a constant with the 'C' parameter. + * - Allow 'G29 P3' to choose a 'reasonable' constant. + */ + + if (g29_c_flag) { + if (g29_repetition_cnt >= GRID_MAX_POINTS) { + set_all_mesh_points_to_value(g29_constant); + } + else { + while (g29_repetition_cnt--) { // this only populates reachable mesh points near + const mesh_index_pair location = find_closest_mesh_point_of_type(INVALID, g29_x_pos, g29_y_pos, USE_NOZZLE_AS_REFERENCE, NULL, false); + if (location.x_index < 0) { + // No more REACHABLE 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; + break; // No more invalid Mesh Points to populate + } + z_values[location.x_index][location.y_index] = g29_constant; + } + } + } + else { + const float cvf = parser.value_float(); + switch((int)truncf(cvf * 10.0) - 30) { // 3.1 -> 1 + #if ENABLED(UBL_G29_P31) + case 1: { + + // P3.1 use least squares fit to fill missing mesh values + // P3.10 zero weighting for distance, all grid points equal, best fit tilted plane + // P3.11 10X weighting for nearest grid points versus farthest grid points + // P3.12 100X distance weighting + // P3.13 1000X distance weighting, approaches simple average of nearest points + + const float weight_power = (cvf - 3.10) * 100.0, // 3.12345 -> 2.345 + weight_factor = weight_power ? POW(10.0, weight_power) : 0; + smart_fill_wlsf(weight_factor); + } + break; + #endif + case 0: // P3 or P3.0 + default: // and anything P3.x that's not P3.1 + smart_fill_mesh(); // Do a 'Smart' fill using nearby known values + break; + } + } + break; + } + + case 4: // Fine Tune (i.e., Edit) the Mesh + #if ENABLED(NEWPANEL) + fine_tune_mesh(g29_x_pos, g29_y_pos, parser.seen('T')); + #else + SERIAL_PROTOCOLLNPGM("?P4 is only available when an LCD is present."); + return; + #endif + break; + + case 5: find_mean_mesh_height(); break; + + case 6: shift_mesh_height(); break; + } + } + + // + // Much of the 'What?' command can be eliminated. But until we are fully debugged, it is + // good to have the extra information. Soon... we prune this to just a few items + // + if (parser.seen('W')) g29_what_command(); + + // + // When we are fully debugged, this may go away. But there are some valid + // use cases for the users. So we can wait and see what to do with it. + // + + if (parser.seen('K')) // Kompare Current Mesh Data to Specified Stored Mesh + g29_compare_current_mesh_to_stored_mesh(); + + // + // Load a Mesh from the EEPROM + // + + if (parser.seen('L')) { // Load Current Mesh Data + g29_storage_slot = parser.has_value() ? parser.value_int() : state.storage_slot; + + int16_t a = settings.calc_num_meshes(); + + if (!a) { + SERIAL_PROTOCOLLNPGM("?EEPROM storage not available."); + return; + } + + if (!WITHIN(g29_storage_slot, 0, a - 1)) { + SERIAL_PROTOCOLLNPGM("?Invalid storage slot."); + SERIAL_PROTOCOLLNPAIR("?Use 0 to ", a - 1); + return; + } + + settings.load_mesh(g29_storage_slot); + state.storage_slot = g29_storage_slot; + + SERIAL_PROTOCOLLNPGM("Done."); + } + + // + // Store a Mesh in the EEPROM + // + + if (parser.seen('S')) { // Store (or Save) Current Mesh Data + g29_storage_slot = parser.has_value() ? parser.value_int() : state.storage_slot; + + if (g29_storage_slot == -1) { // Special case, we are going to 'Export' the mesh to the + SERIAL_ECHOLNPGM("G29 I 999"); // host in a form it can be reconstructed on a different machine + 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_ECHOPAIR("M421 I ", x); + SERIAL_ECHOPAIR(" J ", y); + SERIAL_ECHOPGM(" Z "); + SERIAL_ECHO_F(z_values[x][y], 6); + SERIAL_ECHOPAIR(" ; X ", LOGICAL_X_POSITION(mesh_index_to_xpos(x))); + SERIAL_ECHOPAIR(", Y ", LOGICAL_Y_POSITION(mesh_index_to_ypos(y))); + SERIAL_EOL(); + } + return; + } + + int16_t a = settings.calc_num_meshes(); + + if (!a) { + SERIAL_PROTOCOLLNPGM("?EEPROM storage not available."); + goto LEAVE; + } + + if (!WITHIN(g29_storage_slot, 0, a - 1)) { + SERIAL_PROTOCOLLNPGM("?Invalid storage slot."); + SERIAL_PROTOCOLLNPAIR("?Use 0 to ", a - 1); + goto LEAVE; + } + + settings.store_mesh(g29_storage_slot); + state.storage_slot = g29_storage_slot; + + SERIAL_PROTOCOLLNPGM("Done."); + } + + if (parser.seen('T')) + display_map(parser.has_value() ? parser.value_int() : 0); + + /** + * This code may not be needed... Prepare for its removal... + * + */ + #if 0 + if (parser.seen('Z')) { + if (parser.has_value()) + state.z_offset = parser.value_float(); // do the simple case. Just lock in the specified value + else { + save_ubl_active_state_and_disable(); + //float measured_z = probe_pt(g29_x_pos + X_PROBE_OFFSET_FROM_EXTRUDER, g29_y_pos + Y_PROBE_OFFSET_FROM_EXTRUDER, ProbeDeployAndStow, g29_verbose_level); + + has_control_of_lcd_panel = true; // Grab the LCD Hardware + float measured_z = 1.5; + do_blocking_move_to_z(measured_z); // Get close to the bed, but leave some space so we don't damage anything + // The user is not going to be locking in a new Z-Offset very often so + // it won't be that painful to spin the Encoder Wheel for 1.5mm + lcd_refresh(); + lcd_z_offset_edit_setup(measured_z); + + KEEPALIVE_STATE(PAUSED_FOR_USER); + + do { + measured_z = lcd_z_offset_edit(); + idle(); + do_blocking_move_to_z(measured_z); + } while (!ubl_lcd_clicked()); + + has_control_of_lcd_panel = true; // There is a race condition for the encoder click. + // It could get detected in lcd_mesh_edit (actually _lcd_mesh_fine_tune) + // or here. So, until we are done looking for a long encoder press, + // we need to take control of the panel + + KEEPALIVE_STATE(IN_HANDLER); + + lcd_return_to_status(); + + const millis_t nxt = millis() + 1500UL; + while (ubl_lcd_clicked()) { // debounce and watch for abort + idle(); + if (ELAPSED(millis(), nxt)) { + SERIAL_PROTOCOLLNPGM("\nZ-Offset Adjustment Stopped."); + do_blocking_move_to_z(Z_CLEARANCE_DEPLOY_PROBE); + LCD_MESSAGEPGM(MSG_UBL_Z_OFFSET_STOPPED); + restore_ubl_active_state_and_leave(); + goto LEAVE; + } + } + has_control_of_lcd_panel = false; + safe_delay(20); // We don't want any switch noise. + + state.z_offset = measured_z; + + lcd_refresh(); + restore_ubl_active_state_and_leave(); + } + } + #endif + + LEAVE: + + #if ENABLED(NEWPANEL) + lcd_reset_alert_level(); + LCD_MESSAGEPGM(""); + lcd_quick_feedback(); + + has_control_of_lcd_panel = false; + #endif + + return; + } + + void unified_bed_leveling::find_mean_mesh_height() { + float sum = 0.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++; + } + + const float mean = sum / n; + + // + // Sum the squares of difference from mean + // + float sum_of_diff_squared = 0.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); + + SERIAL_ECHOLNPAIR("# of samples: ", n); + SERIAL_ECHOPGM("Mean Mesh Height: "); + SERIAL_ECHO_F(mean, 6); + SERIAL_EOL(); + + const float sigma = SQRT(sum_of_diff_squared / (n + 1)); + SERIAL_ECHOPGM("Standard Deviation: "); + SERIAL_ECHO_F(sigma, 6); + SERIAL_EOL(); + + if (g29_c_flag) + 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 + g29_constant; + } + + 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 HAS_BED_PROBE + /** + * Probe all invalidated locations of the mesh that can be reached by the probe. + * This attempts to fill in locations closest to the nozzle's start location first. + */ + void unified_bed_leveling::probe_entire_mesh(const float &lx, const float &ly, const bool do_ubl_mesh_map, const bool stow_probe, bool close_or_far) { + mesh_index_pair location; + + has_control_of_lcd_panel = true; + save_ubl_active_state_and_disable(); // we don't do bed level correction because we want the raw data when we probe + DEPLOY_PROBE(); + + uint16_t max_iterations = GRID_MAX_POINTS; + + do { + #if ENABLED(NEWPANEL) + if (ubl_lcd_clicked()) { + SERIAL_PROTOCOLLNPGM("\nMesh only partially populated.\n"); + lcd_quick_feedback(); + STOW_PROBE(); + while (ubl_lcd_clicked()) idle(); + has_control_of_lcd_panel = false; + restore_ubl_active_state_and_leave(); + safe_delay(50); // Debounce the Encoder wheel + return; + } + #endif + + location = find_closest_mesh_point_of_type(INVALID, lx, ly, USE_PROBE_AS_REFERENCE, NULL, close_or_far); + + if (location.x_index >= 0) { // mesh point found and is reachable by probe + const float rawx = mesh_index_to_xpos(location.x_index), + rawy = mesh_index_to_ypos(location.y_index); + + const float measured_z = probe_pt(LOGICAL_X_POSITION(rawx), LOGICAL_Y_POSITION(rawy), stow_probe, g29_verbose_level); // TODO: Needs error handling + z_values[location.x_index][location.y_index] = measured_z; + } + + if (do_ubl_mesh_map) display_map(g29_map_type); + + } while (location.x_index >= 0 && --max_iterations); + + STOW_PROBE(); + restore_ubl_active_state_and_leave(); + + do_blocking_move_to_xy( + constrain(lx - (X_PROBE_OFFSET_FROM_EXTRUDER), UBL_MESH_MIN_X, UBL_MESH_MAX_X), + constrain(ly - (Y_PROBE_OFFSET_FROM_EXTRUDER), UBL_MESH_MIN_Y, UBL_MESH_MAX_Y) + ); + } + + void unified_bed_leveling::tilt_mesh_based_on_3pts(const float &z1, const float &z2, const float &z3) { + matrix_3x3 rotation; + vector_3 v1 = vector_3( (UBL_PROBE_PT_1_X - UBL_PROBE_PT_2_X), + (UBL_PROBE_PT_1_Y - UBL_PROBE_PT_2_Y), + (z1 - z2) ), + + v2 = vector_3( (UBL_PROBE_PT_3_X - UBL_PROBE_PT_2_X), + (UBL_PROBE_PT_3_Y - UBL_PROBE_PT_2_Y), + (z3 - z2) ), + + normal = vector_3::cross(v1, v2); + + normal = normal.get_normal(); + + /** + * This vector is normal to the tilted plane. + * However, we don't know its direction. We need it to point up. So if + * Z is negative, we need to invert the sign of all components of the vector + */ + if (normal.z < 0.0) { + normal.x = -normal.x; + normal.y = -normal.y; + normal.z = -normal.z; + } + + rotation = matrix_3x3::create_look_at(vector_3(normal.x, normal.y, 1)); + + if (g29_verbose_level > 2) { + SERIAL_ECHOPGM("bed plane normal = ["); + SERIAL_PROTOCOL_F(normal.x, 7); + SERIAL_PROTOCOLCHAR(','); + SERIAL_PROTOCOL_F(normal.y, 7); + SERIAL_PROTOCOLCHAR(','); + SERIAL_PROTOCOL_F(normal.z, 7); + SERIAL_ECHOLNPGM("]"); + rotation.debug(PSTR("rotation matrix:")); + } + + // + // All of 3 of these points should give us the same d constant + // + + float t = normal.x * (UBL_PROBE_PT_1_X) + normal.y * (UBL_PROBE_PT_1_Y), + d = t + normal.z * z1; + + if (g29_verbose_level>2) { + SERIAL_ECHOPGM("D constant: "); + SERIAL_PROTOCOL_F(d, 7); + SERIAL_ECHOLNPGM(" "); + } + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOPGM("d from 1st point: "); + SERIAL_ECHO_F(d, 6); + SERIAL_EOL(); + t = normal.x * (UBL_PROBE_PT_2_X) + normal.y * (UBL_PROBE_PT_2_Y); + d = t + normal.z * z2; + SERIAL_ECHOPGM("d from 2nd point: "); + SERIAL_ECHO_F(d, 6); + SERIAL_EOL(); + t = normal.x * (UBL_PROBE_PT_3_X) + normal.y * (UBL_PROBE_PT_3_Y); + d = t + normal.z * z3; + SERIAL_ECHOPGM("d from 3rd point: "); + SERIAL_ECHO_F(d, 6); + SERIAL_EOL(); + } + #endif + + for (uint8_t i = 0; i < GRID_MAX_POINTS_X; i++) { + for (uint8_t j = 0; j < GRID_MAX_POINTS_Y; j++) { + float x_tmp = mesh_index_to_xpos(i), + y_tmp = mesh_index_to_ypos(j), + z_tmp = z_values[i][j]; + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOPGM("before rotation = ["); + SERIAL_PROTOCOL_F(x_tmp, 7); + SERIAL_PROTOCOLCHAR(','); + SERIAL_PROTOCOL_F(y_tmp, 7); + SERIAL_PROTOCOLCHAR(','); + SERIAL_PROTOCOL_F(z_tmp, 7); + SERIAL_ECHOPGM("] ---> "); + safe_delay(20); + } + #endif + apply_rotation_xyz(rotation, x_tmp, y_tmp, z_tmp); + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOPGM("after rotation = ["); + SERIAL_PROTOCOL_F(x_tmp, 7); + SERIAL_PROTOCOLCHAR(','); + SERIAL_PROTOCOL_F(y_tmp, 7); + SERIAL_PROTOCOLCHAR(','); + SERIAL_PROTOCOL_F(z_tmp, 7); + SERIAL_ECHOLNPGM("]"); + safe_delay(55); + } + #endif + z_values[i][j] += z_tmp - d; + } + } + } + #endif // HAS_BED_PROBE + + #if ENABLED(NEWPANEL) + float unified_bed_leveling::measure_point_with_encoder() { + + while (ubl_lcd_clicked()) delay(50); // wait for user to release encoder wheel + delay(50); // debounce + + KEEPALIVE_STATE(PAUSED_FOR_USER); + while (!ubl_lcd_clicked()) { // we need the loop to move the nozzle based on the encoder wheel here! + idle(); + if (encoder_diff) { + do_blocking_move_to_z(current_position[Z_AXIS] + 0.01 * float(encoder_diff)); + encoder_diff = 0; + } + } + KEEPALIVE_STATE(IN_HANDLER); + return current_position[Z_AXIS]; + } + + static void echo_and_take_a_measurement() { SERIAL_PROTOCOLLNPGM(" and take a measurement."); } + + float unified_bed_leveling::measure_business_card_thickness(float in_height) { + has_control_of_lcd_panel = true; + save_ubl_active_state_and_disable(); // Disable bed level correction for probing + + do_blocking_move_to_z(in_height); + do_blocking_move_to_xy(0.5 * (UBL_MESH_MAX_X - (UBL_MESH_MIN_X)), 0.5 * (UBL_MESH_MAX_Y - (UBL_MESH_MIN_Y))); + //, min(planner.max_feedrate_mm_s[X_AXIS], planner.max_feedrate_mm_s[Y_AXIS]) / 2.0); + stepper.synchronize(); + + SERIAL_PROTOCOLPGM("Place shim under nozzle"); + LCD_MESSAGEPGM(MSG_UBL_BC_INSERT); + lcd_return_to_status(); + echo_and_take_a_measurement(); + + const float z1 = measure_point_with_encoder(); + do_blocking_move_to_z(current_position[Z_AXIS] + SIZE_OF_LITTLE_RAISE); + stepper.synchronize(); + + SERIAL_PROTOCOLPGM("Remove shim"); + LCD_MESSAGEPGM(MSG_UBL_BC_REMOVE); + echo_and_take_a_measurement(); + + const float z2 = measure_point_with_encoder(); + + do_blocking_move_to_z(current_position[Z_AXIS] + Z_CLEARANCE_BETWEEN_PROBES); + + const float thickness = abs(z1 - z2); + + if (g29_verbose_level > 1) { + SERIAL_PROTOCOLPGM("Business Card is "); + SERIAL_PROTOCOL_F(thickness, 4); + SERIAL_PROTOCOLLNPGM("mm thick."); + } + + in_height = current_position[Z_AXIS]; // do manual probing at lower height + + has_control_of_lcd_panel = false; + + restore_ubl_active_state_and_leave(); + + return thickness; + } + + void unified_bed_leveling::manually_probe_remaining_mesh(const float &lx, const float &ly, const float &z_clearance, const float &thick, const bool do_ubl_mesh_map) { + + has_control_of_lcd_panel = true; + + save_ubl_active_state_and_disable(); // we don't do bed level correction because we want the raw data when we probe + do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES); + do_blocking_move_to_xy(lx, ly); + + lcd_return_to_status(); + + mesh_index_pair location; + do { + location = find_closest_mesh_point_of_type(INVALID, lx, ly, USE_NOZZLE_AS_REFERENCE, NULL, false); + // It doesn't matter if the probe can't reach the NAN location. This is a manual probe. + if (location.x_index < 0 && location.y_index < 0) continue; + + const float rawx = mesh_index_to_xpos(location.x_index), + rawy = mesh_index_to_ypos(location.y_index), + xProbe = LOGICAL_X_POSITION(rawx), + yProbe = LOGICAL_Y_POSITION(rawy); + + if (!position_is_reachable_raw_xy(rawx, rawy)) break; // SHOULD NOT OCCUR (find_closest_mesh_point only returns reachable points) + + do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES); + + LCD_MESSAGEPGM(MSG_UBL_MOVING_TO_NEXT); + + do_blocking_move_to_xy(xProbe, yProbe); + do_blocking_move_to_z(z_clearance); + + KEEPALIVE_STATE(PAUSED_FOR_USER); + has_control_of_lcd_panel = true; + + if (do_ubl_mesh_map) display_map(g29_map_type); // show user where we're probing + + serialprintPGM(parser.seen('B') ? PSTR(MSG_UBL_BC_INSERT) : PSTR(MSG_UBL_BC_INSERT2)); + + const float z_step = 0.01; // existing behavior: 0.01mm per click, occasionally step + //const float z_step = 1.0 / planner.axis_steps_per_mm[Z_AXIS]; // approx one step each click + + while (ubl_lcd_clicked()) delay(50); // wait for user to release encoder wheel + delay(50); // debounce + while (!ubl_lcd_clicked()) { // we need the loop to move the nozzle based on the encoder wheel here! + idle(); + if (encoder_diff) { + do_blocking_move_to_z(current_position[Z_AXIS] + float(encoder_diff) * z_step); + encoder_diff = 0; + } + } + + // this sequence to detect an ubl_lcd_clicked() debounce it and leave if it is + // a Press and Hold is repeated in a lot of places (including G26_Mesh_Validation.cpp). This + // should be redone and compressed. + const millis_t nxt = millis() + 1500L; + while (ubl_lcd_clicked()) { // debounce and watch for abort + idle(); + if (ELAPSED(millis(), nxt)) { + SERIAL_PROTOCOLLNPGM("\nMesh only partially populated."); + do_blocking_move_to_z(Z_CLEARANCE_DEPLOY_PROBE); + + #if ENABLED(NEWPANEL) + lcd_quick_feedback(); + while (ubl_lcd_clicked()) idle(); + has_control_of_lcd_panel = false; + #endif + + KEEPALIVE_STATE(IN_HANDLER); + restore_ubl_active_state_and_leave(); + return; + } + } + + z_values[location.x_index][location.y_index] = current_position[Z_AXIS] - thick; + if (g29_verbose_level > 2) { + SERIAL_PROTOCOLPGM("Mesh Point Measured at: "); + SERIAL_PROTOCOL_F(z_values[location.x_index][location.y_index], 6); + SERIAL_EOL(); + } + } while (location.x_index >= 0 && location.y_index >= 0); + + if (do_ubl_mesh_map) display_map(g29_map_type); + + restore_ubl_active_state_and_leave(); + KEEPALIVE_STATE(IN_HANDLER); + do_blocking_move_to_z(Z_CLEARANCE_DEPLOY_PROBE); + do_blocking_move_to_xy(lx, ly); + } + #endif // NEWPANEL + + bool unified_bed_leveling::g29_parameter_parsing() { + bool err_flag = false; + + #if ENABLED(NEWPANEL) + LCD_MESSAGEPGM(MSG_UBL_DOING_G29); + lcd_quick_feedback(); + #endif + + g29_constant = 0.0; + g29_repetition_cnt = 0; + + g29_x_flag = parser.seenval('X'); + g29_x_pos = g29_x_flag ? parser.value_float() : current_position[X_AXIS]; + g29_y_flag = parser.seenval('Y'); + g29_y_pos = g29_y_flag ? parser.value_float() : current_position[Y_AXIS]; + + if (parser.seen('R')) { + g29_repetition_cnt = parser.has_value() ? parser.value_int() : GRID_MAX_POINTS; + NOMORE(g29_repetition_cnt, GRID_MAX_POINTS); + if (g29_repetition_cnt < 1) { + SERIAL_PROTOCOLLNPGM("?(R)epetition count invalid (1+).\n"); + return UBL_ERR; + } + } + + g29_verbose_level = parser.seen('V') ? parser.value_int() : 0; + if (!WITHIN(g29_verbose_level, 0, 4)) { + SERIAL_PROTOCOLLNPGM("?(V)erbose level is implausible (0-4).\n"); + err_flag = true; + } + + if (parser.seen('P')) { + const int pv = parser.value_int(); + #if !HAS_BED_PROBE + if (pv == 1) { + SERIAL_PROTOCOLLNPGM("G29 P1 requires a probe.\n"); + err_flag = true; + } + else + #endif + { + g29_phase_value = pv; + if (!WITHIN(g29_phase_value, 0, 6)) { + SERIAL_PROTOCOLLNPGM("?(P)hase value invalid (0-6).\n"); + err_flag = true; + } + } + } + + if (parser.seen('J')) { + #if HAS_BED_PROBE + g29_grid_size = parser.has_value() ? parser.value_int() : 0; + if (g29_grid_size && !WITHIN(g29_grid_size, 2, 9)) { + SERIAL_PROTOCOLLNPGM("?Invalid grid size (J) specified (2-9).\n"); + err_flag = true; + } + #else + SERIAL_PROTOCOLLNPGM("G29 J action requires a probe.\n"); + err_flag = true; + #endif + } + + if (g29_x_flag != g29_y_flag) { + SERIAL_PROTOCOLLNPGM("Both X & Y locations must be specified.\n"); + err_flag = true; + } + + // If X or Y are not valid, use center of the bed values + if (!WITHIN(RAW_X_POSITION(g29_x_pos), X_MIN_BED, X_MAX_BED)) g29_x_pos = LOGICAL_X_POSITION(X_CENTER); + if (!WITHIN(RAW_Y_POSITION(g29_y_pos), Y_MIN_BED, Y_MAX_BED)) g29_y_pos = LOGICAL_Y_POSITION(Y_CENTER); + + if (err_flag) return UBL_ERR; + + /** + * Activate or deactivate UBL + * Note: UBL's G29 restores the state set here when done. + * Leveling is being enabled here with old data, possibly + * none. Error handling should disable for safety... + */ + if (parser.seen('A')) { + if (parser.seen('D')) { + SERIAL_PROTOCOLLNPGM("?Can't activate and deactivate at the same time.\n"); + return UBL_ERR; + } + set_bed_leveling_enabled(true); + report_state(); + } + else if (parser.seen('D')) { + set_bed_leveling_enabled(false); + report_state(); + } + + // Set global 'C' flag and its value + if ((g29_c_flag = parser.seen('C'))) + g29_constant = parser.value_float(); + + #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) + if (parser.seenval('F')) { + const float fh = parser.value_float(); + if (!WITHIN(fh, 0.0, 100.0)) { + SERIAL_PROTOCOLLNPGM("?(F)ade height for Bed Level Correction not plausible.\n"); + return UBL_ERR; + } + set_z_fade_height(fh); + } + #endif + + g29_map_type = parser.intval('T'); + if (!WITHIN(g29_map_type, 0, 2)) { + SERIAL_PROTOCOLLNPGM("Invalid map type.\n"); + return UBL_ERR; + } + return UBL_OK; + } + + static int ubl_state_at_invocation = 0, + ubl_state_recursion_chk = 0; + + void unified_bed_leveling::save_ubl_active_state_and_disable() { + 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 ENABLED(NEWPANEL) + LCD_MESSAGEPGM(MSG_UBL_SAVE_ERROR); + lcd_quick_feedback(); + #endif + + return; + } + ubl_state_at_invocation = state.active; + set_bed_leveling_enabled(false); + } + + void unified_bed_leveling::restore_ubl_active_state_and_leave() { + if (--ubl_state_recursion_chk) { + SERIAL_ECHOLNPGM("restore_ubl_active_state_and_leave() called too many times."); + + #if ENABLED(NEWPANEL) + LCD_MESSAGEPGM(MSG_UBL_RESTORE_ERROR); + lcd_quick_feedback(); + #endif + + return; + } + set_bed_leveling_enabled(ubl_state_at_invocation); + } + + /** + * Much of the 'What?' command can be eliminated. But until we are fully debugged, it is + * good to have the extra information. Soon... we prune this to just a few items + */ + void unified_bed_leveling::g29_what_command() { + report_state(); + + if (state.storage_slot == -1) + SERIAL_PROTOCOLPGM("No Mesh Loaded."); + else { + SERIAL_PROTOCOLPAIR("Mesh ", state.storage_slot); + SERIAL_PROTOCOLPGM(" Loaded."); + } + SERIAL_EOL(); + safe_delay(50); + + SERIAL_PROTOCOLLNPAIR("UBL object count: ", (int)ubl_cnt); + + #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) + SERIAL_PROTOCOL("planner.z_fade_height : "); + SERIAL_PROTOCOL_F(planner.z_fade_height, 4); + SERIAL_EOL(); + #endif + + find_mean_mesh_height(); + + #if HAS_BED_PROBE + SERIAL_PROTOCOLPGM("zprobe_zoffset: "); + SERIAL_PROTOCOL_F(zprobe_zoffset, 7); + SERIAL_EOL(); + #endif + + SERIAL_ECHOLNPAIR("UBL_MESH_MIN_X " STRINGIFY(UBL_MESH_MIN_X) "=", UBL_MESH_MIN_X); + SERIAL_ECHOLNPAIR("UBL_MESH_MIN_Y " STRINGIFY(UBL_MESH_MIN_Y) "=", UBL_MESH_MIN_Y); + safe_delay(25); + SERIAL_ECHOLNPAIR("UBL_MESH_MAX_X " STRINGIFY(UBL_MESH_MAX_X) "=", UBL_MESH_MAX_X); + SERIAL_ECHOLNPAIR("UBL_MESH_MAX_Y " STRINGIFY(UBL_MESH_MAX_Y) "=", UBL_MESH_MAX_Y); + safe_delay(25); + SERIAL_ECHOLNPAIR("GRID_MAX_POINTS_X ", GRID_MAX_POINTS_X); + SERIAL_ECHOLNPAIR("GRID_MAX_POINTS_Y ", GRID_MAX_POINTS_Y); + safe_delay(25); + SERIAL_ECHOLNPAIR("MESH_X_DIST ", MESH_X_DIST); + SERIAL_ECHOLNPAIR("MESH_Y_DIST ", MESH_Y_DIST); + safe_delay(25); + + SERIAL_PROTOCOLPGM("X-Axis Mesh Points at: "); + for (uint8_t i = 0; i < GRID_MAX_POINTS_X; i++) { + SERIAL_PROTOCOL_F(LOGICAL_X_POSITION(mesh_index_to_xpos(i)), 3); + SERIAL_PROTOCOLPGM(" "); + safe_delay(25); + } + SERIAL_EOL(); + + SERIAL_PROTOCOLPGM("Y-Axis Mesh Points at: "); + for (uint8_t i = 0; i < GRID_MAX_POINTS_Y; i++) { + SERIAL_PROTOCOL_F(LOGICAL_Y_POSITION(mesh_index_to_ypos(i)), 3); + SERIAL_PROTOCOLPGM(" "); + safe_delay(25); + } + SERIAL_EOL(); + + #if HAS_KILL + SERIAL_PROTOCOLPAIR("Kill pin on :", KILL_PIN); + SERIAL_PROTOCOLLNPAIR(" state:", READ(KILL_PIN)); + #endif + SERIAL_EOL(); + safe_delay(50); + + SERIAL_PROTOCOLLNPAIR("ubl_state_at_invocation :", ubl_state_at_invocation); + SERIAL_EOL(); + SERIAL_PROTOCOLLNPAIR("ubl_state_recursion_chk :", ubl_state_recursion_chk); + SERIAL_EOL(); + safe_delay(50); + + SERIAL_PROTOCOLPAIR("Meshes go from ", hex_address((void*)settings.get_start_of_meshes())); + SERIAL_PROTOCOLLNPAIR(" to ", hex_address((void*)settings.get_end_of_meshes())); + safe_delay(50); + + SERIAL_PROTOCOLLNPAIR("sizeof(ubl) : ", (int)sizeof(ubl)); + SERIAL_EOL(); + SERIAL_PROTOCOLLNPAIR("z_value[][] size: ", (int)sizeof(z_values)); + SERIAL_EOL(); + safe_delay(25); + + SERIAL_PROTOCOLLNPAIR("EEPROM free for UBL: ", hex_address((void*)(settings.get_end_of_meshes() - settings.get_start_of_meshes()))); + safe_delay(50); + + SERIAL_PROTOCOLPAIR("EEPROM can hold ", settings.calc_num_meshes()); + SERIAL_PROTOCOLLNPGM(" meshes.\n"); + safe_delay(25); + + if (!sanity_check()) { + echo_name(); + SERIAL_PROTOCOLLNPGM(" sanity checks passed."); + } + } + + /** + * When we are fully debugged, the EEPROM dump command will get deleted also. But + * right now, it is good to have the extra information. Soon... we prune this. + */ + void unified_bed_leveling::g29_eeprom_dump() { + unsigned char cccc; + uint16_t kkkk; + + SERIAL_ECHO_START(); + SERIAL_ECHOLNPGM("EEPROM Dump:"); + for (uint16_t i = 0; i < E2END + 1; i += 16) { + if (!(i & 0x3)) idle(); + print_hex_word(i); + SERIAL_ECHOPGM(": "); + for (uint16_t j = 0; j < 16; j++) { + kkkk = i + j; + eeprom_read_block(&cccc, (void *)kkkk, 1); + print_hex_byte(cccc); + SERIAL_ECHO(' '); + } + SERIAL_EOL(); + } + SERIAL_EOL(); + } + + /** + * When we are fully debugged, this may go away. But there are some valid + * use cases for the users. So we can wait and see what to do with it. + */ + void unified_bed_leveling::g29_compare_current_mesh_to_stored_mesh() { + int16_t a = settings.calc_num_meshes(); + + if (!a) { + SERIAL_PROTOCOLLNPGM("?EEPROM storage not available."); + return; + } + + if (!parser.has_value()) { + SERIAL_PROTOCOLLNPGM("?Storage slot # required."); + SERIAL_PROTOCOLLNPAIR("?Use 0 to ", a - 1); + return; + } + + g29_storage_slot = parser.value_int(); + + if (!WITHIN(g29_storage_slot, 0, a - 1)) { + SERIAL_PROTOCOLLNPGM("?Invalid storage slot."); + SERIAL_PROTOCOLLNPAIR("?Use 0 to ", a - 1); + return; + } + + float tmp_z_values[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y]; + settings.load_mesh(g29_storage_slot, &tmp_z_values); + + SERIAL_PROTOCOLPAIR("Subtracting mesh in slot ", g29_storage_slot); + SERIAL_PROTOCOLLNPGM(" 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]; + } + + mesh_index_pair unified_bed_leveling::find_closest_mesh_point_of_type(const MeshPointType type, const float &lx, const float &ly, const bool probe_as_reference, unsigned int bits[16], const bool far_flag) { + mesh_index_pair out_mesh; + out_mesh.x_index = out_mesh.y_index = -1; + + // Get our reference position. Either the nozzle or probe location. + const float px = RAW_X_POSITION(lx) - (probe_as_reference == USE_PROBE_AS_REFERENCE ? X_PROBE_OFFSET_FROM_EXTRUDER : 0), + py = RAW_Y_POSITION(ly) - (probe_as_reference == USE_PROBE_AS_REFERENCE ? Y_PROBE_OFFSET_FROM_EXTRUDER : 0); + + float best_so_far = far_flag ? -99999.99 : 99999.99; + + for (uint8_t i = 0; i < GRID_MAX_POINTS_X; i++) { + for (uint8_t j = 0; j < GRID_MAX_POINTS_Y; j++) { + + if ( (type == INVALID && isnan(z_values[i][j])) // Check to see if this location holds the right thing + || (type == REAL && !isnan(z_values[i][j])) + || (type == SET_IN_BITMAP && is_bit_set(bits, i, j)) + ) { + // We only get here if we found a Mesh Point of the specified type + + float raw_x = RAW_CURRENT_POSITION(X), raw_y = RAW_CURRENT_POSITION(Y); + const float mx = mesh_index_to_xpos(i), + my = 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 (probe_as_reference ? !position_is_reachable_by_probe_raw_xy(mx, my) : !position_is_reachable_raw_xy(mx, my)) + continue; + + // Reachable. Check if it's the best_so_far location to the nozzle. + // Add in a weighting factor that considers the current location of the nozzle. + + float distance = HYPOT(px - mx, py - my); + + /** + * If doing the far_flag action, we want to be as far as possible + * from the starting point and from any other probed points. We + * want the next point spread out and filling in any blank spaces + * in the mesh. So we add in some of the distance to every probed + * point we can find. + */ + if (far_flag) { + for (uint8_t k = 0; k < GRID_MAX_POINTS_X; k++) { + for (uint8_t l = 0; l < GRID_MAX_POINTS_Y; l++) { + if (i != k && j != l && !isnan(z_values[k][l])) { + //distance += pow((float) abs(i - k) * (MESH_X_DIST), 2) + pow((float) abs(j - l) * (MESH_Y_DIST), 2); // working here + distance += HYPOT(MESH_X_DIST, MESH_Y_DIST) / log(HYPOT((i - k) * (MESH_X_DIST) + .001, (j - l) * (MESH_Y_DIST)) + .001); + } + } + } + } + else + // factor in the distance from the current location for the normal case + // so the nozzle isn't running all over the bed. + distance += HYPOT(raw_x - mx, raw_y - my) * 0.1; + + // if far_flag, look for farthest point + if (far_flag == (distance > best_so_far) && distance != best_so_far) { + best_so_far = distance; // We found a closer/farther location with + out_mesh.x_index = i; // the specified type of mesh value. + out_mesh.y_index = j; + out_mesh.distance = best_so_far; + } + } + } // for j + } // for i + + return out_mesh; + } + + #if ENABLED(NEWPANEL) + + void unified_bed_leveling::fine_tune_mesh(const float &lx, const float &ly, const bool do_ubl_mesh_map) { + if (!parser.seen('R')) // fine_tune_mesh() is special. If no repetition count flag is specified + g29_repetition_cnt = 1; // do exactly one mesh location. Otherwise use what the parser decided. + + #if ENABLED(UBL_MESH_EDIT_MOVES_Z) + const bool is_offset = parser.seen('H'); + const float h_offset = is_offset ? parser.value_linear_units() : Z_CLEARANCE_BETWEEN_PROBES; + if (is_offset && !WITHIN(h_offset, 0, 10)) { + SERIAL_PROTOCOLLNPGM("Offset out of bounds. (0 to 10mm)\n"); + return; + } + #endif + + mesh_index_pair location; + + if (!position_is_reachable_xy(lx, ly)) { + SERIAL_PROTOCOLLNPGM("(X,Y) outside printable radius."); + return; + } + + save_ubl_active_state_and_disable(); + + LCD_MESSAGEPGM(MSG_UBL_FINE_TUNE_MESH); + + do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES); + do_blocking_move_to_xy(lx, ly); + + uint16_t not_done[16]; + memset(not_done, 0xFF, sizeof(not_done)); + do { + location = find_closest_mesh_point_of_type(SET_IN_BITMAP, lx, ly, USE_NOZZLE_AS_REFERENCE, not_done, false); + + if (location.x_index < 0) break; // stop when we can't find any more reachable points. + + bit_clear(not_done, location.x_index, location.y_index); // Mark this location as 'adjusted' so we will find a + // different location the next time through the loop + + const float rawx = mesh_index_to_xpos(location.x_index), + rawy = mesh_index_to_ypos(location.y_index); + + if (!position_is_reachable_raw_xy(rawx, rawy)) // SHOULD NOT OCCUR because find_closest_mesh_point_of_type will only return reachable + break; + + float new_z = z_values[location.x_index][location.y_index]; + + if (isnan(new_z)) // if the mesh point is invalid, set it to 0.0 so it can be edited + new_z = 0.0; + + do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES); // Move the nozzle to where we are going to edit + do_blocking_move_to_xy(LOGICAL_X_POSITION(rawx), LOGICAL_Y_POSITION(rawy)); + + new_z = FLOOR(new_z * 1000.0) * 0.001; // Chop off digits after the 1000ths place + + KEEPALIVE_STATE(PAUSED_FOR_USER); + has_control_of_lcd_panel = true; + + if (do_ubl_mesh_map) display_map(g29_map_type); // show the user which point is being adjusted + + lcd_refresh(); + + lcd_mesh_edit_setup(new_z); + + 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(); + } while (!ubl_lcd_clicked()); + + if (!ubl_lcd_map_control) lcd_return_to_status(); + + // The technique used here generates a race condition for the encoder click. + // It could get detected in lcd_mesh_edit (actually _lcd_mesh_fine_tune) or here. + // Let's work on specifying a proper API for the LCD ASAP, OK? + has_control_of_lcd_panel = true; + + // this sequence to detect an ubl_lcd_clicked() debounce it and leave if it is + // a Press and Hold is repeated in a lot of places (including G26_Mesh_Validation.cpp). This + // should be redone and compressed. + const millis_t nxt = millis() + 1500UL; + while (ubl_lcd_clicked()) { // debounce and watch for abort + idle(); + if (ELAPSED(millis(), nxt)) { + lcd_return_to_status(); + do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES); + LCD_MESSAGEPGM(MSG_EDITING_STOPPED); + + while (ubl_lcd_clicked()) idle(); + + goto FINE_TUNE_EXIT; + } + } + + safe_delay(20); // We don't want any switch noise. + + z_values[location.x_index][location.y_index] = new_z; + + lcd_refresh(); + + } while (location.x_index >= 0 && --g29_repetition_cnt > 0); + + FINE_TUNE_EXIT: + + has_control_of_lcd_panel = false; + KEEPALIVE_STATE(IN_HANDLER); + + if (do_ubl_mesh_map) display_map(g29_map_type); + restore_ubl_active_state_and_leave(); + do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES); + + do_blocking_move_to_xy(lx, ly); + + LCD_MESSAGEPGM(MSG_UBL_DONE_EDITING_MESH); + SERIAL_ECHOLNPGM("Done Editing Mesh"); + + if (ubl_lcd_map_control) + lcd_goto_screen(_lcd_ubl_output_map_lcd); + else + lcd_return_to_status(); + } + + #endif // NEWPANEL + + /** + * 'Smart Fill': Scan from the outward edges of the mesh towards the center. + * If an invalid location is found, use the next two points (if valid) to + * calculate a 'reasonable' value for the unprobed mesh point. + */ + + bool unified_bed_leveling::smart_fill_one(const uint8_t x, const uint8_t y, const int8_t xdir, const int8_t ydir) { + const int8_t x1 = x + xdir, x2 = x1 + xdir, + y1 = y + ydir, y2 = y1 + ydir; + // A NAN next to a pair of real values? + if (isnan(z_values[x][y]) && !isnan(z_values[x1][y1]) && !isnan(z_values[x2][y2])) { + if (z_values[x1][y1] < z_values[x2][y2]) // Angled downward? + z_values[x][y] = z_values[x1][y1]; // Use nearest (maybe a little too high.) + else + z_values[x][y] = 2.0 * z_values[x1][y1] - z_values[x2][y2]; // Angled upward... + return true; + } + return false; + } + + typedef struct { uint8_t sx, ex, sy, ey; bool yfirst; } smart_fill_info; + + void unified_bed_leveling::smart_fill_mesh() { + static const smart_fill_info + info0 PROGMEM = { 0, GRID_MAX_POINTS_X, 0, GRID_MAX_POINTS_Y - 2, false }, // Bottom of the mesh looking up + info1 PROGMEM = { 0, GRID_MAX_POINTS_X, GRID_MAX_POINTS_Y - 1, 0, false }, // Top of the mesh looking down + info2 PROGMEM = { 0, GRID_MAX_POINTS_X - 2, 0, GRID_MAX_POINTS_Y, true }, // Left side of the mesh looking right + 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 }; + + // static const smart_fill_info info[] PROGMEM = { + // { 0, GRID_MAX_POINTS_X, 0, GRID_MAX_POINTS_Y - 2, false } PROGMEM, // Bottom of the mesh looking up + // { 0, GRID_MAX_POINTS_X, GRID_MAX_POINTS_Y - 1, 0, false } PROGMEM, // Top of the mesh looking down + // { 0, GRID_MAX_POINTS_X - 2, 0, GRID_MAX_POINTS_Y, true } PROGMEM, // Left side of the mesh looking right + // { GRID_MAX_POINTS_X - 1, 0, 0, GRID_MAX_POINTS_Y, true } PROGMEM // Right side of the mesh looking left + // }; + for (uint8_t i = 0; i < COUNT(info); ++i) { + const smart_fill_info *f = (smart_fill_info*)pgm_read_word(&info[i]); + const int8_t sx = pgm_read_word(&f->sx), sy = pgm_read_word(&f->sy), + ex = pgm_read_word(&f->ex), ey = pgm_read_word(&f->ey); + if (pgm_read_byte(&f->yfirst)) { + const int8_t dir = ex > sx ? 1 : -1; + for (uint8_t y = sy; y != ey; ++y) + for (uint8_t x = sx; x != ex; x += dir) + if (smart_fill_one(x, y, dir, 0)) break; + } + else { + const int8_t dir = ey > sy ? 1 : -1; + for (uint8_t x = sx; x != ex; ++x) + for (uint8_t y = sy; y != ey; y += dir) + if (smart_fill_one(x, y, 0, dir)) break; + } + } + } + + #if HAS_BED_PROBE + + void unified_bed_leveling::tilt_mesh_based_on_probed_grid(const bool do_ubl_mesh_map) { + constexpr int16_t x_min = max(MIN_PROBE_X, UBL_MESH_MIN_X), + x_max = min(MAX_PROBE_X, UBL_MESH_MAX_X), + y_min = max(MIN_PROBE_Y, UBL_MESH_MIN_Y), + y_max = min(MAX_PROBE_Y, UBL_MESH_MAX_Y); + + const float dx = float(x_max - x_min) / (g29_grid_size - 1.0), + dy = float(y_max - y_min) / (g29_grid_size - 1.0); + + struct linear_fit_data lsf_results; + incremental_LSF_reset(&lsf_results); + + bool zig_zag = false; + for (uint8_t ix = 0; ix < g29_grid_size; ix++) { + const float x = float(x_min) + ix * dx; + for (int8_t iy = 0; iy < g29_grid_size; iy++) { + const float y = float(y_min) + dy * (zig_zag ? g29_grid_size - 1 - iy : iy); + float measured_z = probe_pt(LOGICAL_X_POSITION(x), LOGICAL_Y_POSITION(y), parser.seen('E'), g29_verbose_level); // TODO: Needs error handling + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_CHAR('('); + SERIAL_PROTOCOL_F(x, 7); + SERIAL_CHAR(','); + SERIAL_PROTOCOL_F(y, 7); + SERIAL_ECHOPGM(") logical: "); + SERIAL_CHAR('('); + SERIAL_PROTOCOL_F(LOGICAL_X_POSITION(x), 7); + SERIAL_CHAR(','); + SERIAL_PROTOCOL_F(LOGICAL_X_POSITION(y), 7); + SERIAL_ECHOPGM(") measured: "); + SERIAL_PROTOCOL_F(measured_z, 7); + SERIAL_ECHOPGM(" correction: "); + SERIAL_PROTOCOL_F(get_z_correction(LOGICAL_X_POSITION(x), LOGICAL_Y_POSITION(y)), 7); + } + #endif + + measured_z -= get_z_correction(LOGICAL_X_POSITION(x), LOGICAL_Y_POSITION(y)) /* + zprobe_zoffset */ ; + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOPGM(" final >>>---> "); + SERIAL_PROTOCOL_F(measured_z, 7); + SERIAL_EOL(); + } + #endif + + incremental_LSF(&lsf_results, x, y, measured_z); + } + + zig_zag ^= true; + } + + if (finish_incremental_LSF(&lsf_results)) { + SERIAL_ECHOPGM("Could not complete LSF!"); + return; + } + + if (g29_verbose_level > 3) { + SERIAL_ECHOPGM("LSF Results A="); + SERIAL_PROTOCOL_F(lsf_results.A, 7); + SERIAL_ECHOPGM(" B="); + SERIAL_PROTOCOL_F(lsf_results.B, 7); + SERIAL_ECHOPGM(" D="); + SERIAL_PROTOCOL_F(lsf_results.D, 7); + SERIAL_EOL(); + } + + vector_3 normal = vector_3(lsf_results.A, lsf_results.B, 1.0000).get_normal(); + + if (g29_verbose_level > 2) { + SERIAL_ECHOPGM("bed plane normal = ["); + SERIAL_PROTOCOL_F(normal.x, 7); + SERIAL_PROTOCOLCHAR(','); + SERIAL_PROTOCOL_F(normal.y, 7); + SERIAL_PROTOCOLCHAR(','); + SERIAL_PROTOCOL_F(normal.z, 7); + SERIAL_ECHOLNPGM("]"); + } + + 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 x_tmp = mesh_index_to_xpos(i), + y_tmp = mesh_index_to_ypos(j), + z_tmp = z_values[i][j]; + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOPGM("before rotation = ["); + SERIAL_PROTOCOL_F(x_tmp, 7); + SERIAL_PROTOCOLCHAR(','); + SERIAL_PROTOCOL_F(y_tmp, 7); + SERIAL_PROTOCOLCHAR(','); + SERIAL_PROTOCOL_F(z_tmp, 7); + SERIAL_ECHOPGM("] ---> "); + safe_delay(20); + } + #endif + + apply_rotation_xyz(rotation, x_tmp, y_tmp, z_tmp); + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOPGM("after rotation = ["); + SERIAL_PROTOCOL_F(x_tmp, 7); + SERIAL_PROTOCOLCHAR(','); + SERIAL_PROTOCOL_F(y_tmp, 7); + SERIAL_PROTOCOLCHAR(','); + SERIAL_PROTOCOL_F(z_tmp, 7); + SERIAL_ECHOLNPGM("]"); + safe_delay(55); + } + #endif + + z_values[i][j] += z_tmp - lsf_results.D; + } + } + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + rotation.debug(PSTR("rotation matrix:")); + SERIAL_ECHOPGM("LSF Results A="); + SERIAL_PROTOCOL_F(lsf_results.A, 7); + SERIAL_ECHOPGM(" B="); + SERIAL_PROTOCOL_F(lsf_results.B, 7); + SERIAL_ECHOPGM(" D="); + SERIAL_PROTOCOL_F(lsf_results.D, 7); + SERIAL_EOL(); + safe_delay(55); + + SERIAL_ECHOPGM("bed plane normal = ["); + SERIAL_PROTOCOL_F(normal.x, 7); + SERIAL_PROTOCOLCHAR(','); + SERIAL_PROTOCOL_F(normal.y, 7); + SERIAL_PROTOCOLCHAR(','); + SERIAL_PROTOCOL_F(normal.z, 7); + SERIAL_ECHOPGM("]\n"); + SERIAL_EOL(); + } + #endif + + if (do_ubl_mesh_map) display_map(g29_map_type); + } + + #endif // HAS_BED_PROBE + + #if ENABLED(UBL_G29_P31) + void unified_bed_leveling::smart_fill_wlsf(const float &weight_factor) { + + // For each undefined mesh point, compute a distance-weighted least squares fit + // from all the originally populated mesh points, weighted toward the point + // 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"); + uint16_t bitmap[GRID_MAX_POINTS_X] = { 0 }; + struct linear_fit_data lsf_results; + + SERIAL_ECHOPGM("Extrapolating mesh..."); + + 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); + + for (uint8_t ix = 0; ix < GRID_MAX_POINTS_X; ix++) { + const float px = mesh_index_to_xpos(ix); + for (uint8_t iy = 0; iy < GRID_MAX_POINTS_Y; iy++) { + const float py = mesh_index_to_ypos(iy); + if (isnan(z_values[ix][iy])) { + // undefined mesh point at (px,py), compute weighted LSF from original valid mesh points. + incremental_LSF_reset(&lsf_results); + for (uint8_t jx = 0; jx < GRID_MAX_POINTS_X; jx++) { + const float rx = mesh_index_to_xpos(jx); + for (uint8_t jy = 0; jy < GRID_MAX_POINTS_Y; jy++) { + if (TEST(bitmap[jx], jy)) { + const float ry = mesh_index_to_ypos(jy), + rz = z_values[jx][jy], + w = 1.0 + weight_scaled / HYPOT((rx - px), (ry - py)); + incremental_WLSF(&lsf_results, rx, ry, rz, w); + } + } + } + if (finish_incremental_LSF(&lsf_results)) { + SERIAL_ECHOLNPGM("Insufficient data"); + return; + } + const float ez = -lsf_results.D - lsf_results.A * px - lsf_results.B * py; + z_values[ix][iy] = ez; + idle(); // housekeeping + } + } + } + + SERIAL_ECHOLNPGM("done"); + } + #endif // UBL_G29_P31 + +#endif // AUTO_BED_LEVELING_UBL diff --git a/trunk/Arduino/Marlin_1.1.6/ubl_motion.cpp b/trunk/Arduino/Marlin_1.1.6/ubl_motion.cpp new file mode 100644 index 00000000..b9f85301 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/ubl_motion.cpp @@ -0,0 +1,740 @@ +/** + * 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 . + * + */ +#include "MarlinConfig.h" + +#if ENABLED(AUTO_BED_LEVELING_UBL) + + #include "Marlin.h" + #include "ubl.h" + #include "planner.h" + #include "stepper.h" + #include + #include + + extern float destination[XYZE]; + + #if AVR_AT90USB1286_FAMILY // Teensyduino & Printrboard IDE extensions have compile errors without this + inline void set_current_to_destination() { COPY(current_position, destination); } + #else + extern void set_current_to_destination(); + #endif + +#if ENABLED(DELTA) + + extern float delta[ABC], + endstop_adj[ABC]; + + extern float delta_radius, + delta_tower_angle_trim[ABC], + delta_tower[ABC][2], + delta_diagonal_rod, + delta_calibration_radius, + delta_diagonal_rod_2_tower[ABC], + delta_segments_per_second, + delta_clip_start_height; + + extern float delta_safe_distance_from_top(); + +#endif + + + static void debug_echo_axis(const AxisEnum axis) { + if (current_position[axis] == destination[axis]) + SERIAL_ECHOPGM("-------------"); + else + SERIAL_ECHO_F(destination[X_AXIS], 6); + } + + void debug_current_and_destination(const char *title) { + + // if the title message starts with a '!' it is so important, we are going to + // ignore the status of the g26_debug_flag + if (*title != '!' && !ubl.g26_debug_flag) return; + + const float de = destination[E_AXIS] - current_position[E_AXIS]; + + if (de == 0.0) return; // Printing moves only + + const float dx = destination[X_AXIS] - current_position[X_AXIS], + dy = destination[Y_AXIS] - current_position[Y_AXIS], + xy_dist = HYPOT(dx, dy); + + if (xy_dist == 0.0) return; + + SERIAL_ECHOPGM(" fpmm="); + const float fpmm = de / xy_dist; + SERIAL_ECHO_F(fpmm, 6); + + SERIAL_ECHOPGM(" current=( "); + SERIAL_ECHO_F(current_position[X_AXIS], 6); + SERIAL_ECHOPGM(", "); + SERIAL_ECHO_F(current_position[Y_AXIS], 6); + SERIAL_ECHOPGM(", "); + SERIAL_ECHO_F(current_position[Z_AXIS], 6); + SERIAL_ECHOPGM(", "); + SERIAL_ECHO_F(current_position[E_AXIS], 6); + SERIAL_ECHOPGM(" ) destination=( "); + debug_echo_axis(X_AXIS); + SERIAL_ECHOPGM(", "); + debug_echo_axis(Y_AXIS); + SERIAL_ECHOPGM(", "); + debug_echo_axis(Z_AXIS); + SERIAL_ECHOPGM(", "); + debug_echo_axis(E_AXIS); + SERIAL_ECHOPGM(" ) "); + SERIAL_ECHO(title); + SERIAL_EOL(); + + } + + void unified_bed_leveling::line_to_destination_cartesian(const float &feed_rate, uint8_t extruder) { + /** + * Much of the nozzle movement will be within the same cell. So we will do as little computation + * as possible to determine if this is the case. If this move is within the same cell, we will + * just do the required Z-Height correction, call the Planner's buffer_line() routine, and leave + */ + const float start[XYZE] = { + current_position[X_AXIS], + current_position[Y_AXIS], + current_position[Z_AXIS], + current_position[E_AXIS] + }, + end[XYZE] = { + destination[X_AXIS], + destination[Y_AXIS], + destination[Z_AXIS], + destination[E_AXIS] + }; + + const int cell_start_xi = get_cell_index_x(RAW_X_POSITION(start[X_AXIS])), + cell_start_yi = get_cell_index_y(RAW_Y_POSITION(start[Y_AXIS])), + cell_dest_xi = get_cell_index_x(RAW_X_POSITION(end[X_AXIS])), + cell_dest_yi = get_cell_index_y(RAW_Y_POSITION(end[Y_AXIS])); + + if (g26_debug_flag) { + SERIAL_ECHOPAIR(" ubl.line_to_destination(xe=", end[X_AXIS]); + SERIAL_ECHOPAIR(", ye=", end[Y_AXIS]); + SERIAL_ECHOPAIR(", ze=", end[Z_AXIS]); + SERIAL_ECHOPAIR(", ee=", end[E_AXIS]); + SERIAL_CHAR(')'); + SERIAL_EOL(); + debug_current_and_destination(PSTR("Start of ubl.line_to_destination()")); + } + + if (cell_start_xi == cell_dest_xi && cell_start_yi == cell_dest_yi) { // if the whole move is within the same cell, + /** + * we don't need to break up the move + * + * If we are moving off the print bed, we are going to allow the move at this level. + * But we detect it and isolate it. For now, we just pass along the request. + */ + + if (!WITHIN(cell_dest_xi, 0, GRID_MAX_POINTS_X - 1) || !WITHIN(cell_dest_yi, 0, GRID_MAX_POINTS_Y - 1)) { + + // Note: There is no Z Correction in this case. We are off the grid and don't know what + // a reasonable correction would be. + + planner._buffer_line(end[X_AXIS], end[Y_AXIS], end[Z_AXIS] + state.z_offset, end[E_AXIS], feed_rate, extruder); + set_current_to_destination(); + + if (g26_debug_flag) + debug_current_and_destination(PSTR("out of bounds in ubl.line_to_destination()")); + + return; + } + + FINAL_MOVE: + + /** + * Optimize some floating point operations here. We could call float get_z_correction(float x0, float y0) to + * generate the correction for us. But we can lighten the load on the CPU by doing a modified version of the function. + * We are going to only calculate the amount we are from the first mesh line towards the second mesh line once. + * We will use this fraction in both of the original two Z Height calculations for the bi-linear interpolation. And, + * instead of doing a generic divide of the distance, we know the distance is MESH_X_DIST so we can use the preprocessor + * to create a 1-over number for us. That will allow us to do a floating point multiply instead of a floating point divide. + */ + + const float xratio = (RAW_X_POSITION(end[X_AXIS]) - mesh_index_to_xpos(cell_dest_xi)) * (1.0 / (MESH_X_DIST)); + + float z1 = z_values[cell_dest_xi ][cell_dest_yi ] + xratio * + (z_values[cell_dest_xi + 1][cell_dest_yi ] - z_values[cell_dest_xi][cell_dest_yi ]), + z2 = z_values[cell_dest_xi ][cell_dest_yi + 1] + xratio * + (z_values[cell_dest_xi + 1][cell_dest_yi + 1] - z_values[cell_dest_xi][cell_dest_yi + 1]); + + if (cell_dest_xi >= GRID_MAX_POINTS_X - 1) z1 = z2 = 0.0; + + // we are done with the fractional X distance into the cell. Now with the two Z-Heights we have calculated, we + // are going to apply the Y-Distance into the cell to interpolate the final Z correction. + + const float yratio = (RAW_Y_POSITION(end[Y_AXIS]) - mesh_index_to_ypos(cell_dest_yi)) * (1.0 / (MESH_Y_DIST)); + float z0 = cell_dest_yi < GRID_MAX_POINTS_Y - 1 ? (z1 + (z2 - z1) * yratio) * fade_scaling_factor_for_z(end[Z_AXIS]) : 0.0; + + /** + * If part of the Mesh is undefined, it will show up as NAN + * in z_values[][] and propagate through the + * calculations. If our correction is NAN, we throw it out + * because part of the Mesh is undefined and we don't have the + * information we need to complete the height correction. + */ + if (isnan(z0)) z0 = 0.0; + + planner._buffer_line(end[X_AXIS], end[Y_AXIS], end[Z_AXIS] + z0 + state.z_offset, end[E_AXIS], feed_rate, extruder); + + if (g26_debug_flag) + debug_current_and_destination(PSTR("FINAL_MOVE in ubl.line_to_destination()")); + + set_current_to_destination(); + return; + } + + /** + * If we get here, we are processing a move that crosses at least one Mesh Line. We will check + * for the simple case of just crossing X or just crossing Y Mesh Lines after we get all the details + * of the move figured out. We can process the easy case of just crossing an X or Y Mesh Line with less + * computation and in fact most lines are of this nature. We will check for that in the following + * blocks of code: + */ + + const float dx = end[X_AXIS] - start[X_AXIS], + dy = end[Y_AXIS] - start[Y_AXIS]; + + const int left_flag = dx < 0.0 ? 1 : 0, + down_flag = dy < 0.0 ? 1 : 0; + + const float adx = left_flag ? -dx : dx, + ady = down_flag ? -dy : dy; + + const int dxi = cell_start_xi == cell_dest_xi ? 0 : left_flag ? -1 : 1, + dyi = cell_start_yi == cell_dest_yi ? 0 : down_flag ? -1 : 1; + + /** + * Compute the scaling factor for the extruder for each partial move. + * We need to watch out for zero length moves because it will cause us to + * have an infinate scaling factor. We are stuck doing a floating point + * divide to get our scaling factor, but after that, we just multiply by this + * number. We also pick our scaling factor based on whether the X or Y + * component is larger. We use the biggest of the two to preserve precision. + */ + + const bool use_x_dist = adx > ady; + + float on_axis_distance = use_x_dist ? dx : dy, + e_position = end[E_AXIS] - start[E_AXIS], + z_position = end[Z_AXIS] - start[Z_AXIS]; + + const float e_normalized_dist = e_position / on_axis_distance, + z_normalized_dist = z_position / on_axis_distance; + + int current_xi = cell_start_xi, + current_yi = cell_start_yi; + + const float m = dy / dx, + c = start[Y_AXIS] - m * start[X_AXIS]; + + const bool inf_normalized_flag = (isinf(e_normalized_dist) != 0), + inf_m_flag = (isinf(m) != 0); + /** + * This block handles vertical lines. These are lines that stay within the same + * X Cell column. They do not need to be perfectly vertical. They just can + * not cross into another X Cell column. + */ + if (dxi == 0) { // Check for a vertical line + current_yi += down_flag; // Line is heading down, we just want to go to the bottom + while (current_yi != cell_dest_yi + down_flag) { + current_yi += dyi; + const float next_mesh_line_y = LOGICAL_Y_POSITION(mesh_index_to_ypos(current_yi)); + + /** + * if the slope of the line is infinite, we won't do the calculations + * else, we know the next X is the same so we can recover and continue! + * Calculate X at the next Y mesh line + */ + const float x = inf_m_flag ? start[X_AXIS] : (next_mesh_line_y - c) / m; + + float z0 = z_correction_for_x_on_horizontal_mesh_line(x, current_xi, current_yi); + + z0 *= fade_scaling_factor_for_z(end[Z_AXIS]); + + /** + * If part of the Mesh is undefined, it will show up as NAN + * in z_values[][] and propagate through the + * calculations. If our correction is NAN, we throw it out + * because part of the Mesh is undefined and we don't have the + * information we need to complete the height correction. + */ + if (isnan(z0)) z0 = 0.0; + + const float y = LOGICAL_Y_POSITION(mesh_index_to_ypos(current_yi)); + + /** + * Without this check, it is possible for the algorithm to generate a zero length move in the case + * where the line is heading down and it is starting right on a Mesh Line boundary. For how often that + * happens, it might be best to remove the check and always 'schedule' the move because + * the planner._buffer_line() routine will filter it if that happens. + */ + if (y != start[Y_AXIS]) { + if (!inf_normalized_flag) { + on_axis_distance = use_x_dist ? x - start[X_AXIS] : y - start[Y_AXIS]; + e_position = start[E_AXIS] + on_axis_distance * e_normalized_dist; + z_position = start[Z_AXIS] + on_axis_distance * z_normalized_dist; + } + else { + e_position = end[E_AXIS]; + z_position = end[Z_AXIS]; + } + + planner._buffer_line(x, y, z_position + z0 + state.z_offset, e_position, feed_rate, extruder); + } //else printf("FIRST MOVE PRUNED "); + } + + if (g26_debug_flag) + debug_current_and_destination(PSTR("vertical move done in ubl.line_to_destination()")); + + // + // Check if we are at the final destination. Usually, we won't be, but if it is on a Y Mesh Line, we are done. + // + if (current_position[X_AXIS] != end[X_AXIS] || current_position[Y_AXIS] != end[Y_AXIS]) + goto FINAL_MOVE; + + set_current_to_destination(); + return; + } + + /** + * + * This block handles horizontal lines. These are lines that stay within the same + * Y Cell row. They do not need to be perfectly horizontal. They just can + * not cross into another Y Cell row. + * + */ + + if (dyi == 0) { // Check for a horizontal line + current_xi += left_flag; // Line is heading left, we just want to go to the left + // edge of this cell for the first move. + while (current_xi != cell_dest_xi + left_flag) { + current_xi += dxi; + const float next_mesh_line_x = LOGICAL_X_POSITION(mesh_index_to_xpos(current_xi)), + y = m * next_mesh_line_x + c; // Calculate Y at the next X mesh line + + float z0 = z_correction_for_y_on_vertical_mesh_line(y, current_xi, current_yi); + + z0 *= fade_scaling_factor_for_z(end[Z_AXIS]); + + /** + * If part of the Mesh is undefined, it will show up as NAN + * in z_values[][] and propagate through the + * calculations. If our correction is NAN, we throw it out + * because part of the Mesh is undefined and we don't have the + * information we need to complete the height correction. + */ + if (isnan(z0)) z0 = 0.0; + + const float x = LOGICAL_X_POSITION(mesh_index_to_xpos(current_xi)); + + /** + * Without this check, it is possible for the algorithm to generate a zero length move in the case + * where the line is heading left and it is starting right on a Mesh Line boundary. For how often + * that happens, it might be best to remove the check and always 'schedule' the move because + * the planner._buffer_line() routine will filter it if that happens. + */ + if (x != start[X_AXIS]) { + if (!inf_normalized_flag) { + on_axis_distance = use_x_dist ? x - start[X_AXIS] : y - start[Y_AXIS]; + e_position = start[E_AXIS] + on_axis_distance * e_normalized_dist; // is based on X or Y because this is a horizontal move + z_position = start[Z_AXIS] + on_axis_distance * z_normalized_dist; + } + else { + e_position = end[E_AXIS]; + z_position = end[Z_AXIS]; + } + + planner._buffer_line(x, y, z_position + z0 + state.z_offset, e_position, feed_rate, extruder); + } //else printf("FIRST MOVE PRUNED "); + } + + if (g26_debug_flag) + debug_current_and_destination(PSTR("horizontal move done in ubl.line_to_destination()")); + + if (current_position[X_AXIS] != end[X_AXIS] || current_position[Y_AXIS] != end[Y_AXIS]) + goto FINAL_MOVE; + + set_current_to_destination(); + return; + } + + /** + * + * This block handles the generic case of a line crossing both X and Y Mesh lines. + * + */ + + int xi_cnt = cell_start_xi - cell_dest_xi, + yi_cnt = cell_start_yi - cell_dest_yi; + + if (xi_cnt < 0) xi_cnt = -xi_cnt; + if (yi_cnt < 0) yi_cnt = -yi_cnt; + + current_xi += left_flag; + current_yi += down_flag; + + while (xi_cnt > 0 || yi_cnt > 0) { + + const float next_mesh_line_x = LOGICAL_X_POSITION(mesh_index_to_xpos(current_xi + dxi)), + next_mesh_line_y = LOGICAL_Y_POSITION(mesh_index_to_ypos(current_yi + dyi)), + y = m * next_mesh_line_x + c, // Calculate Y at the next X mesh line + x = (next_mesh_line_y - c) / m; // Calculate X at the next Y mesh line + // (No need to worry about m being zero. + // If that was the case, it was already detected + // as a vertical line move above.) + + if (left_flag == (x > next_mesh_line_x)) { // Check if we hit the Y line first + // Yes! Crossing a Y Mesh Line next + float z0 = z_correction_for_x_on_horizontal_mesh_line(x, current_xi - left_flag, current_yi + dyi); + + z0 *= fade_scaling_factor_for_z(end[Z_AXIS]); + + /** + * If part of the Mesh is undefined, it will show up as NAN + * in z_values[][] and propagate through the + * calculations. If our correction is NAN, we throw it out + * because part of the Mesh is undefined and we don't have the + * information we need to complete the height correction. + */ + if (isnan(z0)) z0 = 0.0; + + if (!inf_normalized_flag) { + on_axis_distance = use_x_dist ? x - start[X_AXIS] : next_mesh_line_y - start[Y_AXIS]; + e_position = start[E_AXIS] + on_axis_distance * e_normalized_dist; + z_position = start[Z_AXIS] + on_axis_distance * z_normalized_dist; + } + else { + e_position = end[E_AXIS]; + z_position = end[Z_AXIS]; + } + planner._buffer_line(x, next_mesh_line_y, z_position + z0 + state.z_offset, e_position, feed_rate, extruder); + current_yi += dyi; + yi_cnt--; + } + else { + // Yes! Crossing a X Mesh Line next + float z0 = z_correction_for_y_on_vertical_mesh_line(y, current_xi + dxi, current_yi - down_flag); + + z0 *= fade_scaling_factor_for_z(end[Z_AXIS]); + + /** + * If part of the Mesh is undefined, it will show up as NAN + * in z_values[][] and propagate through the + * calculations. If our correction is NAN, we throw it out + * because part of the Mesh is undefined and we don't have the + * information we need to complete the height correction. + */ + if (isnan(z0)) z0 = 0.0; + + if (!inf_normalized_flag) { + on_axis_distance = use_x_dist ? next_mesh_line_x - start[X_AXIS] : y - start[Y_AXIS]; + e_position = start[E_AXIS] + on_axis_distance * e_normalized_dist; + z_position = start[Z_AXIS] + on_axis_distance * z_normalized_dist; + } + else { + e_position = end[E_AXIS]; + z_position = end[Z_AXIS]; + } + + planner._buffer_line(next_mesh_line_x, y, z_position + z0 + state.z_offset, e_position, feed_rate, extruder); + current_xi += dxi; + xi_cnt--; + } + + if (xi_cnt < 0 || yi_cnt < 0) break; // we've gone too far, so exit the loop and move on to FINAL_MOVE + } + + if (g26_debug_flag) + debug_current_and_destination(PSTR("generic move done in ubl.line_to_destination()")); + + if (current_position[X_AXIS] != end[X_AXIS] || current_position[Y_AXIS] != end[Y_AXIS]) + goto FINAL_MOVE; + + set_current_to_destination(); + } + + #if UBL_DELTA + + // macro to inline copy exactly 4 floats, don't rely on sizeof operator + #define COPY_XYZE( target, source ) { \ + target[X_AXIS] = source[X_AXIS]; \ + target[Y_AXIS] = source[Y_AXIS]; \ + target[Z_AXIS] = source[Z_AXIS]; \ + target[E_AXIS] = source[E_AXIS]; \ + } + + #if IS_SCARA // scale the feed rate from mm/s to degrees/s + static float scara_feed_factor, scara_oldA, scara_oldB; + #endif + + // We don't want additional apply_leveling() performed by regular buffer_line or buffer_line_kinematic, + // so we call _buffer_line directly here. Per-segmented leveling and kinematics performed first. + + inline void _O2 ubl_buffer_segment_raw( float rx, float ry, float rz, float le, float fr ) { + + #if ENABLED(DELTA) // apply delta inverse_kinematics + + const float delta_A = rz + SQRT( delta_diagonal_rod_2_tower[A_AXIS] + - HYPOT2( delta_tower[A_AXIS][X_AXIS] - rx, + delta_tower[A_AXIS][Y_AXIS] - ry )); + + const float delta_B = rz + SQRT( delta_diagonal_rod_2_tower[B_AXIS] + - HYPOT2( delta_tower[B_AXIS][X_AXIS] - rx, + delta_tower[B_AXIS][Y_AXIS] - ry )); + + const float delta_C = rz + SQRT( delta_diagonal_rod_2_tower[C_AXIS] + - HYPOT2( delta_tower[C_AXIS][X_AXIS] - rx, + delta_tower[C_AXIS][Y_AXIS] - ry )); + + planner._buffer_line(delta_A, delta_B, delta_C, le, fr, active_extruder); + + #elif IS_SCARA // apply scara inverse_kinematics (should be changed to save raw->logical->raw) + + const float lseg[XYZ] = { LOGICAL_X_POSITION(rx), + LOGICAL_Y_POSITION(ry), + LOGICAL_Z_POSITION(rz) + }; + + inverse_kinematics(lseg); // this writes delta[ABC] from lseg[XYZ] + // should move the feedrate scaling to scara inverse_kinematics + + const float adiff = FABS(delta[A_AXIS] - scara_oldA), + bdiff = FABS(delta[B_AXIS] - scara_oldB); + scara_oldA = delta[A_AXIS]; + scara_oldB = delta[B_AXIS]; + float s_feedrate = max(adiff, bdiff) * scara_feed_factor; + + planner._buffer_line(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], le, s_feedrate, active_extruder); + + #else // CARTESIAN + + // Cartesian _buffer_line seems to take LOGICAL, not RAW coordinates + + const float lx = LOGICAL_X_POSITION(rx), + ly = LOGICAL_Y_POSITION(ry), + lz = LOGICAL_Z_POSITION(rz); + + planner._buffer_line(lx, ly, lz, le, fr, active_extruder); + + #endif + + } + + + /** + * Prepare a segmented linear move for DELTA/SCARA/CARTESIAN with UBL and FADE semantics. + * This calls planner._buffer_line multiple times for small incremental moves. + * Returns true if did NOT move, false if moved (requires current_position update). + */ + + bool _O2 unified_bed_leveling::prepare_segmented_line_to(const float ltarget[XYZE], const float &feedrate) { + + if (!position_is_reachable_xy(ltarget[X_AXIS], ltarget[Y_AXIS])) // fail if moving outside reachable boundary + return true; // did not move, so current_position still accurate + + const float tot_dx = ltarget[X_AXIS] - current_position[X_AXIS], + tot_dy = ltarget[Y_AXIS] - current_position[Y_AXIS], + tot_dz = ltarget[Z_AXIS] - current_position[Z_AXIS], + tot_de = ltarget[E_AXIS] - current_position[E_AXIS]; + + const float cartesian_xy_mm = HYPOT(tot_dx, tot_dy); // total horizontal xy distance + + #if IS_KINEMATIC + const float seconds = cartesian_xy_mm / feedrate; // seconds to move xy distance at requested rate + uint16_t segments = lroundf(delta_segments_per_second * seconds), // preferred number of segments for distance @ feedrate + seglimit = lroundf(cartesian_xy_mm * (1.0 / (DELTA_SEGMENT_MIN_LENGTH))); // number of segments at minimum segment length + NOMORE(segments, seglimit); // limit to minimum segment length (fewer segments) + #else + uint16_t segments = lroundf(cartesian_xy_mm * (1.0 / (DELTA_SEGMENT_MIN_LENGTH))); // cartesian fixed segment length + #endif + + NOLESS(segments, 1); // must have at least one segment + const float inv_segments = 1.0 / segments; // divide once, multiply thereafter + + #if IS_SCARA // scale the feed rate from mm/s to degrees/s + scara_feed_factor = cartesian_xy_mm * inv_segments * feedrate; + scara_oldA = stepper.get_axis_position_degrees(A_AXIS); + scara_oldB = stepper.get_axis_position_degrees(B_AXIS); + #endif + + const float seg_dx = tot_dx * inv_segments, + seg_dy = tot_dy * inv_segments, + seg_dz = tot_dz * inv_segments, + seg_de = tot_de * inv_segments; + + // Note that E segment distance could vary slightly as z mesh height + // changes for each segment, but small enough to ignore. + + float seg_rx = RAW_X_POSITION(current_position[X_AXIS]), + seg_ry = RAW_Y_POSITION(current_position[Y_AXIS]), + seg_rz = RAW_Z_POSITION(current_position[Z_AXIS]), + seg_le = current_position[E_AXIS]; + + const bool above_fade_height = ( + #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) + planner.z_fade_height != 0 && planner.z_fade_height < RAW_Z_POSITION(ltarget[Z_AXIS]) + #else + false + #endif + ); + + // Only compute leveling per segment if ubl active and target below z_fade_height. + + if (!state.active || above_fade_height) { // no mesh leveling + + const float z_offset = state.active ? state.z_offset : 0.0; + + do { + + if (--segments) { // not the last segment + seg_rx += seg_dx; + seg_ry += seg_dy; + seg_rz += seg_dz; + seg_le += seg_de; + } else { // last segment, use exact destination + seg_rx = RAW_X_POSITION(ltarget[X_AXIS]); + seg_ry = RAW_Y_POSITION(ltarget[Y_AXIS]); + seg_rz = RAW_Z_POSITION(ltarget[Z_AXIS]); + seg_le = ltarget[E_AXIS]; + } + + ubl_buffer_segment_raw( seg_rx, seg_ry, seg_rz + z_offset, seg_le, feedrate ); + + } while (segments); + + return false; // moved but did not set_current_to_destination(); + } + + // Otherwise perform per-segment leveling + + #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) + const float fade_scaling_factor = fade_scaling_factor_for_z(ltarget[Z_AXIS]); + #endif + + // increment to first segment destination + seg_rx += seg_dx; + seg_ry += seg_dy; + seg_rz += seg_dz; + seg_le += seg_de; + + for(;;) { // for each mesh cell encountered during the move + + // Compute mesh cell invariants that remain constant for all segments within cell. + // Note for cell index, if point is outside the mesh grid (in MESH_INSET perimeter) + // the bilinear interpolation from the adjacent cell within the mesh will still work. + // Inner loop will exit each time (because out of cell bounds) but will come back + // in top of loop and again re-find same adjacent cell and use it, just less efficient + // for mesh inset area. + + int8_t cell_xi = (seg_rx - (UBL_MESH_MIN_X)) * (1.0 / (MESH_X_DIST)), + cell_yi = (seg_ry - (UBL_MESH_MIN_Y)) * (1.0 / (MESH_X_DIST)); + + cell_xi = constrain(cell_xi, 0, (GRID_MAX_POINTS_X) - 1); + cell_yi = constrain(cell_yi, 0, (GRID_MAX_POINTS_Y) - 1); + + const float x0 = mesh_index_to_xpos(cell_xi), // 64 byte table lookup avoids mul+add + y0 = mesh_index_to_ypos(cell_yi); + + float z_x0y0 = z_values[cell_xi ][cell_yi ], // z at lower left corner + z_x1y0 = z_values[cell_xi+1][cell_yi ], // z at upper left corner + z_x0y1 = z_values[cell_xi ][cell_yi+1], // z at lower right corner + z_x1y1 = z_values[cell_xi+1][cell_yi+1]; // z at upper right corner + + if (isnan(z_x0y0)) z_x0y0 = 0; // ideally activating state.active (G29 A) + if (isnan(z_x1y0)) z_x1y0 = 0; // should refuse if any invalid mesh points + if (isnan(z_x0y1)) z_x0y1 = 0; // in order to avoid isnan tests per cell, + if (isnan(z_x1y1)) z_x1y1 = 0; // thus guessing zero for undefined points + + float cx = seg_rx - x0, // cell-relative x and y + cy = seg_ry - y0; + + const float z_xmy0 = (z_x1y0 - z_x0y0) * (1.0 / (MESH_X_DIST)), // z slope per x along y0 (lower left to lower right) + z_xmy1 = (z_x1y1 - z_x0y1) * (1.0 / (MESH_X_DIST)); // z slope per x along y1 (upper left to upper right) + + float z_cxy0 = z_x0y0 + z_xmy0 * cx; // z height along y0 at cx (changes for each cx in cell) + + const float z_cxy1 = z_x0y1 + z_xmy1 * cx, // z height along y1 at cx + z_cxyd = z_cxy1 - z_cxy0; // z height difference along cx from y0 to y1 + + float z_cxym = z_cxyd * (1.0 / (MESH_Y_DIST)); // z slope per y along cx from y0 to y1 (changes for each cx in cell) + + // float z_cxcy = z_cxy0 + z_cxym * cy; // interpolated mesh z height along cx at cy (do inside the segment loop) + + // As subsequent segments step through this cell, the z_cxy0 intercept will change + // and the z_cxym slope will change, both as a function of cx within the cell, and + // each change by a constant for fixed segment lengths. + + const float z_sxy0 = z_xmy0 * seg_dx, // per-segment adjustment to z_cxy0 + z_sxym = (z_xmy1 - z_xmy0) * (1.0 / (MESH_Y_DIST)) * seg_dx; // per-segment adjustment to z_cxym + + for(;;) { // for all segments within this mesh cell + + float z_cxcy = z_cxy0 + z_cxym * cy; // interpolated mesh z height along cx at cy + + #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) + z_cxcy *= fade_scaling_factor; // apply fade factor to interpolated mesh height + #endif + + z_cxcy += state.z_offset; // add fixed mesh offset from G29 Z + + if (--segments == 0) { // if this is last segment, use ltarget for exact + seg_rx = RAW_X_POSITION(ltarget[X_AXIS]); + seg_ry = RAW_Y_POSITION(ltarget[Y_AXIS]); + seg_rz = RAW_Z_POSITION(ltarget[Z_AXIS]); + seg_le = ltarget[E_AXIS]; + } + + ubl_buffer_segment_raw( seg_rx, seg_ry, seg_rz + z_cxcy, seg_le, feedrate ); + + if (segments == 0 ) // done with last segment + return false; // did not set_current_to_destination() + + seg_rx += seg_dx; + seg_ry += seg_dy; + seg_rz += seg_dz; + seg_le += seg_de; + + cx += seg_dx; + cy += seg_dy; + + if (!WITHIN(cx, 0, MESH_X_DIST) || !WITHIN(cy, 0, MESH_Y_DIST)) { // done within this cell, break to next + break; + } + + // Next segment still within same mesh cell, adjust the per-segment + // slope and intercept to compute next z height. + + z_cxy0 += z_sxy0; // adjust z_cxy0 by per-segment z_sxy0 + z_cxym += z_sxym; // adjust z_cxym by per-segment z_sxym + + } // segment loop + } // cell loop + } + + #endif // UBL_DELTA + +#endif // AUTO_BED_LEVELING_UBL + diff --git a/trunk/Arduino/Marlin_1.1.6/ultralcd.cpp b/trunk/Arduino/Marlin_1.1.6/ultralcd.cpp new file mode 100644 index 00000000..83ce9d2f --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/ultralcd.cpp @@ -0,0 +1,5022 @@ +/** + * 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 . + * + */ + +#include "MarlinConfig.h" + +#if ENABLED(ULTRA_LCD) + +#include "ultralcd.h" +#include "Marlin.h" +#include "language.h" +#include "cardreader.h" +#include "temperature.h" +#include "planner.h" +#include "stepper.h" +#include "configuration_store.h" +#include "utility.h" + +#if HAS_BUZZER && DISABLED(LCD_USE_I2C_BUZZER) + #include "buzzer.h" +#endif + +#if ENABLED(PRINTCOUNTER) + #include "printcounter.h" + #include "duration_t.h" +#endif + +#if ENABLED(BLTOUCH) + #include "endstops.h" +#endif + +#if ENABLED(AUTO_BED_LEVELING_UBL) + #include "ubl.h" + bool ubl_lcd_map_control = false; +#endif + +// Initialized by settings.load() +int16_t lcd_preheat_hotend_temp[2], lcd_preheat_bed_temp[2], lcd_preheat_fan_speed[2]; + +#if ENABLED(FILAMENT_LCD_DISPLAY) && ENABLED(SDSUPPORT) + millis_t previous_lcd_status_ms = 0; +#endif + +#if ENABLED(BABYSTEPPING) + long babysteps_done = 0; + #if ENABLED(BABYSTEP_ZPROBE_OFFSET) + static void lcd_babystep_zoffset(); + #else + static void lcd_babystep_z(); + #endif +#endif + +uint8_t lcd_status_message_level; +char lcd_status_message[3 * (LCD_WIDTH) + 1] = WELCOME_MSG; // worst case is kana with up to 3*LCD_WIDTH+1 + +#if ENABLED(STATUS_MESSAGE_SCROLLING) + uint8_t status_scroll_pos = 0; +#endif + +#if ENABLED(DOGLCD) + #include "ultralcd_impl_DOGM.h" + #include +#else + #include "ultralcd_impl_HD44780.h" +#endif + +#if ENABLED(ULTIPANEL) + #define DEFINE_LCD_IMPLEMENTATION_DRAWMENU_SETTING_EDIT_TYPE(_type, _name, _strFunc) \ + inline void lcd_implementation_drawmenu_setting_edit_ ## _name (const bool sel, const uint8_t row, const char* pstr, const char* pstr2, _type * const data, ...) { \ + UNUSED(pstr2); \ + DRAWMENU_SETTING_EDIT_GENERIC(_strFunc(*(data))); \ + } \ + inline void lcd_implementation_drawmenu_setting_edit_callback_ ## _name (const bool sel, const uint8_t row, const char* pstr, const char* pstr2, _type * const data, ...) { \ + UNUSED(pstr2); \ + DRAWMENU_SETTING_EDIT_GENERIC(_strFunc(*(data))); \ + } \ + inline void lcd_implementation_drawmenu_setting_edit_accessor_ ## _name (const bool sel, const uint8_t row, const char* pstr, const char* pstr2, _type (*pget)(), void (*pset)(_type), ...) { \ + UNUSED(pstr2); UNUSED(pset); \ + DRAWMENU_SETTING_EDIT_GENERIC(_strFunc(pget())); \ + } \ + typedef void _name##_void + DEFINE_LCD_IMPLEMENTATION_DRAWMENU_SETTING_EDIT_TYPE(int16_t, int3, itostr3); + DEFINE_LCD_IMPLEMENTATION_DRAWMENU_SETTING_EDIT_TYPE(uint8_t, int8, i8tostr3); + DEFINE_LCD_IMPLEMENTATION_DRAWMENU_SETTING_EDIT_TYPE(float, float3, ftostr3); + DEFINE_LCD_IMPLEMENTATION_DRAWMENU_SETTING_EDIT_TYPE(float, float32, ftostr32); + DEFINE_LCD_IMPLEMENTATION_DRAWMENU_SETTING_EDIT_TYPE(float, float43, ftostr43sign); + DEFINE_LCD_IMPLEMENTATION_DRAWMENU_SETTING_EDIT_TYPE(float, float5, ftostr5rj); + DEFINE_LCD_IMPLEMENTATION_DRAWMENU_SETTING_EDIT_TYPE(float, float51, ftostr51sign); + DEFINE_LCD_IMPLEMENTATION_DRAWMENU_SETTING_EDIT_TYPE(float, float52, ftostr52sign); + DEFINE_LCD_IMPLEMENTATION_DRAWMENU_SETTING_EDIT_TYPE(float, float62, ftostr62rj); + DEFINE_LCD_IMPLEMENTATION_DRAWMENU_SETTING_EDIT_TYPE(uint32_t, long5, ftostr5rj); + #define lcd_implementation_drawmenu_setting_edit_bool(sel, row, pstr, pstr2, data) DRAW_BOOL_SETTING(sel, row, pstr, data) + #define lcd_implementation_drawmenu_setting_edit_callback_bool(sel, row, pstr, pstr2, data, callback) DRAW_BOOL_SETTING(sel, row, pstr, data) + #define lcd_implementation_drawmenu_setting_edit_accessor_bool(sel, row, pstr, pstr2, pget, pset) DRAW_BOOL_SETTING(sel, row, pstr, data) +#endif // ULTIPANEL + +// The main status screen +void lcd_status_screen(); + +millis_t next_lcd_update_ms; + +uint8_t lcdDrawUpdate = LCDVIEW_CLEAR_CALL_REDRAW; // Set when the LCD needs to draw, decrements after every draw. Set to 2 in LCD routines so the LCD gets at least 1 full redraw (first redraw is partial) +uint16_t max_display_update_time = 0; + +#if ENABLED(DOGLCD) + bool drawing_screen = false; +#endif + +#if ENABLED(DAC_STEPPER_CURRENT) + #include "stepper_dac.h" //was dac_mcp4728.h MarlinMain uses stepper dac for the m-codes + uint8_t driverPercent[XYZE]; +#endif + +#if ENABLED(ULTIPANEL) + + #ifndef TALL_FONT_CORRECTION + #define TALL_FONT_CORRECTION 0 + #endif + + // Function pointer to menu functions. + typedef void (*screenFunc_t)(); + typedef void (*menuAction_t)(); + + #if HAS_POWER_SWITCH + extern bool powersupply_on; + #endif + + //////////////////////////////////////////// + ///////////////// Menu Tree //////////////// + //////////////////////////////////////////// + + void lcd_main_menu(); + void lcd_tune_menu(); + void lcd_prepare_menu(); + void lcd_move_menu(); + void lcd_control_menu(); + void lcd_control_temperature_menu(); + void lcd_control_temperature_preheat_material1_settings_menu(); + void lcd_control_temperature_preheat_material2_settings_menu(); + void lcd_control_motion_menu(); + void lcd_control_filament_menu(); + + #if ENABLED(LCD_INFO_MENU) + #if ENABLED(PRINTCOUNTER) + void lcd_info_stats_menu(); + #endif + void lcd_info_thermistors_menu(); + void lcd_info_board_menu(); + void lcd_info_menu(); + #endif // LCD_INFO_MENU + + #if ENABLED(ADVANCED_PAUSE_FEATURE) + void lcd_advanced_pause_toocold_menu(); + void lcd_advanced_pause_option_menu(); + void lcd_advanced_pause_init_message(); + void lcd_advanced_pause_unload_message(); + void lcd_advanced_pause_insert_message(); + void lcd_advanced_pause_load_message(); + void lcd_advanced_pause_heat_nozzle(); + void lcd_advanced_pause_extrude_message(); + void lcd_advanced_pause_resume_message(); + #endif + + #if ENABLED(DAC_STEPPER_CURRENT) + void dac_driver_commit(); + void dac_driver_getValues(); + void lcd_dac_menu(); + void lcd_dac_write_eeprom(); + #endif + + #if ENABLED(FWRETRACT) + void lcd_control_retract_menu(); + #endif + + #if ENABLED(DELTA_CALIBRATION_MENU) + void lcd_delta_calibrate_menu(); + #endif + + #if ENABLED(MESH_BED_LEVELING) && ENABLED(LCD_BED_LEVELING) + #include "mesh_bed_leveling.h" + extern void mesh_probing_done(); + #endif + + //////////////////////////////////////////// + //////////// Menu System Actions /////////// + //////////////////////////////////////////// + + #define menu_action_back(dummy) _menu_action_back() + void _menu_action_back(); + void menu_action_submenu(screenFunc_t data); + void menu_action_gcode(const char* pgcode); + void menu_action_function(menuAction_t data); + + #define DECLARE_MENU_EDIT_TYPE(_type, _name) \ + bool _menu_edit_ ## _name(); \ + void menu_edit_ ## _name(); \ + void menu_edit_callback_ ## _name(); \ + void _menu_action_setting_edit_ ## _name(const char * const pstr, _type* const ptr, const _type minValue, const _type maxValue); \ + void menu_action_setting_edit_ ## _name(const char * const pstr, _type * const ptr, const _type minValue, const _type maxValue); \ + void menu_action_setting_edit_callback_ ## _name(const char * const pstr, _type * const ptr, const _type minValue, const _type maxValue, const screenFunc_t callback, const bool live=false); \ + typedef void _name##_void + + DECLARE_MENU_EDIT_TYPE(int16_t, int3); + DECLARE_MENU_EDIT_TYPE(uint8_t, int8); + DECLARE_MENU_EDIT_TYPE(float, float3); + DECLARE_MENU_EDIT_TYPE(float, float32); + DECLARE_MENU_EDIT_TYPE(float, float43); + DECLARE_MENU_EDIT_TYPE(float, float5); + DECLARE_MENU_EDIT_TYPE(float, float51); + DECLARE_MENU_EDIT_TYPE(float, float52); + DECLARE_MENU_EDIT_TYPE(float, float62); + DECLARE_MENU_EDIT_TYPE(uint32_t, long5); + + void menu_action_setting_edit_bool(const char* pstr, bool* ptr); + void menu_action_setting_edit_callback_bool(const char* pstr, bool* ptr, screenFunc_t callbackFunc); + + #if ENABLED(SDSUPPORT) + void lcd_sdcard_menu(); + void menu_action_sdfile(const char* filename, char* longFilename); + void menu_action_sddirectory(const char* filename, char* longFilename); + #endif + + //////////////////////////////////////////// + //////////// Menu System Macros //////////// + //////////////////////////////////////////// + + #ifndef ENCODER_FEEDRATE_DEADZONE + #define ENCODER_FEEDRATE_DEADZONE 6 + #endif + + /** + * MENU_ITEM generates draw & handler code for a menu item, potentially calling: + * + * lcd_implementation_drawmenu_[type](sel, row, label, arg3...) + * menu_action_[type](arg3...) + * + * Examples: + * MENU_ITEM(back, MSG_WATCH, 0 [dummy parameter] ) + * or + * MENU_BACK(MSG_WATCH) + * lcd_implementation_drawmenu_back(sel, row, PSTR(MSG_WATCH)) + * menu_action_back() + * + * MENU_ITEM(function, MSG_PAUSE_PRINT, lcd_sdcard_pause) + * lcd_implementation_drawmenu_function(sel, row, PSTR(MSG_PAUSE_PRINT), lcd_sdcard_pause) + * menu_action_function(lcd_sdcard_pause) + * + * MENU_ITEM_EDIT(int3, MSG_SPEED, &feedrate_percentage, 10, 999) + * MENU_ITEM(setting_edit_int3, MSG_SPEED, PSTR(MSG_SPEED), &feedrate_percentage, 10, 999) + * lcd_implementation_drawmenu_setting_edit_int3(sel, row, PSTR(MSG_SPEED), PSTR(MSG_SPEED), &feedrate_percentage, 10, 999) + * menu_action_setting_edit_int3(PSTR(MSG_SPEED), &feedrate_percentage, 10, 999) + * + */ + #define _MENU_ITEM_PART_1(TYPE, ...) \ + if (_menuLineNr == _thisItemNr) { \ + if (lcd_clicked && encoderLine == _thisItemNr) { + + #define _MENU_ITEM_PART_2(TYPE, LABEL, ...) \ + menu_action_ ## TYPE(__VA_ARGS__); \ + if (screen_changed) return; \ + } \ + if (lcdDrawUpdate) \ + lcd_implementation_drawmenu_ ## TYPE(encoderLine == _thisItemNr, _lcdLineNr, PSTR(LABEL), ## __VA_ARGS__); \ + } \ + ++_thisItemNr + + #define MENU_ITEM(TYPE, LABEL, ...) do { \ + _skipStatic = false; \ + _MENU_ITEM_PART_1(TYPE, ## __VA_ARGS__); \ + _MENU_ITEM_PART_2(TYPE, LABEL, ## __VA_ARGS__); \ + }while(0) + + #define MENU_BACK(LABEL) MENU_ITEM(back, LABEL, 0) + + // Used to print static text with no visible cursor. + // Parameters: label [, bool center [, bool invert [, char *value] ] ] + #define STATIC_ITEM(LABEL, ...) \ + if (_menuLineNr == _thisItemNr) { \ + if (_skipStatic && encoderLine <= _thisItemNr) { \ + encoderPosition += ENCODER_STEPS_PER_MENU_ITEM; \ + ++encoderLine; \ + } \ + if (lcdDrawUpdate) \ + lcd_implementation_drawmenu_static(_lcdLineNr, PSTR(LABEL), ## __VA_ARGS__); \ + } \ + ++_thisItemNr + + #if ENABLED(ENCODER_RATE_MULTIPLIER) + + bool encoderRateMultiplierEnabled; + #define ENCODER_RATE_MULTIPLY(F) (encoderRateMultiplierEnabled = F) + + //#define ENCODER_RATE_MULTIPLIER_DEBUG // If defined, output the encoder steps per second value + + /** + * MENU_MULTIPLIER_ITEM generates drawing and handling code for a multiplier menu item + */ + #define MENU_MULTIPLIER_ITEM(type, label, ...) do { \ + _MENU_ITEM_PART_1(type, ## __VA_ARGS__); \ + encoderRateMultiplierEnabled = true; \ + lastEncoderMovementMillis = 0; \ + _MENU_ITEM_PART_2(type, label, ## __VA_ARGS__); \ + }while(0) + + #else // !ENCODER_RATE_MULTIPLIER + #define ENCODER_RATE_MULTIPLY(F) NOOP + #endif // !ENCODER_RATE_MULTIPLIER + + #define MENU_ITEM_DUMMY() do { _thisItemNr++; }while(0) + #define MENU_ITEM_EDIT(type, label, ...) MENU_ITEM(setting_edit_ ## type, label, PSTR(label), ## __VA_ARGS__) + #define MENU_ITEM_EDIT_CALLBACK(type, label, ...) MENU_ITEM(setting_edit_callback_ ## type, label, PSTR(label), ## __VA_ARGS__) + #if ENABLED(ENCODER_RATE_MULTIPLIER) + #define MENU_MULTIPLIER_ITEM_EDIT(type, label, ...) MENU_MULTIPLIER_ITEM(setting_edit_ ## type, label, PSTR(label), ## __VA_ARGS__) + #define MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(type, label, ...) MENU_MULTIPLIER_ITEM(setting_edit_callback_ ## type, label, PSTR(label), ## __VA_ARGS__) + #else // !ENCODER_RATE_MULTIPLIER + #define MENU_MULTIPLIER_ITEM_EDIT(type, label, ...) MENU_ITEM(setting_edit_ ## type, label, PSTR(label), ## __VA_ARGS__) + #define MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(type, label, ...) MENU_ITEM(setting_edit_callback_ ## type, label, PSTR(label), ## __VA_ARGS__) + #endif // !ENCODER_RATE_MULTIPLIER + + /** + * START_SCREEN_OR_MENU generates init code for a screen or menu + * + * encoderLine is the position based on the encoder + * 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 + * _countedItems is the total number of items in the menu (after one call) + */ + #define START_SCREEN_OR_MENU(LIMIT) \ + ENCODER_DIRECTION_MENUS(); \ + ENCODER_RATE_MULTIPLY(false); \ + if (encoderPosition > 0x8000) encoderPosition = 0; \ + static int8_t _countedItems = 0; \ + int8_t encoderLine = encoderPosition / (ENCODER_STEPS_PER_MENU_ITEM); \ + if (_countedItems > 0 && encoderLine >= _countedItems - (LIMIT)) { \ + encoderLine = max(0, _countedItems - (LIMIT)); \ + encoderPosition = encoderLine * (ENCODER_STEPS_PER_MENU_ITEM); \ + } + + #define SCREEN_OR_MENU_LOOP() \ + int8_t _menuLineNr = encoderTopLine, _thisItemNr; \ + for (int8_t _lcdLineNr = 0; _lcdLineNr < LCD_HEIGHT - (TALL_FONT_CORRECTION); _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() \ + START_SCREEN_OR_MENU(LCD_HEIGHT - (TALL_FONT_CORRECTION)); \ + encoderTopLine = encoderLine; \ + bool _skipStatic = false; \ + SCREEN_OR_MENU_LOOP() + + #define START_MENU() \ + START_SCREEN_OR_MENU(1); \ + screen_changed = false; \ + NOMORE(encoderTopLine, encoderLine); \ + if (encoderLine >= encoderTopLine + LCD_HEIGHT - (TALL_FONT_CORRECTION)) { \ + encoderTopLine = encoderLine - (LCD_HEIGHT - (TALL_FONT_CORRECTION) - 1); \ + } \ + bool _skipStatic = true; \ + SCREEN_OR_MENU_LOOP() + + #define END_SCREEN() \ + } \ + _countedItems = _thisItemNr + + #define END_MENU() \ + } \ + _countedItems = _thisItemNr; \ + UNUSED(_skipStatic) + + //////////////////////////////////////////// + ///////////// Global Variables ///////////// + //////////////////////////////////////////// + + /** + * REVERSE_MENU_DIRECTION + * + * To reverse the menu direction we need a general way to reverse + * the direction of the encoder everywhere. So encoderDirection is + * added to allow the encoder to go the other way. + * + * This behavior is limited to scrolling Menus and SD card listings, + * and is disabled in other contexts. + */ + #if ENABLED(REVERSE_MENU_DIRECTION) + int8_t encoderDirection = 1; + #define ENCODER_DIRECTION_NORMAL() (encoderDirection = 1) + #define ENCODER_DIRECTION_MENUS() (encoderDirection = -1) + #else + #define ENCODER_DIRECTION_NORMAL() ; + #define ENCODER_DIRECTION_MENUS() ; + #endif + + // Encoder Movement + volatile int8_t encoderDiff; // Updated in lcd_buttons_update, added to encoderPosition every LCD update + uint32_t encoderPosition; + millis_t lastEncoderMovementMillis = 0; + + // Button States + bool lcd_clicked, wait_for_unclick; + volatile uint8_t buttons; + millis_t next_button_update_ms; + #if ENABLED(REPRAPWORLD_KEYPAD) + volatile uint8_t buttons_reprapworld_keypad; + #endif + #if ENABLED(LCD_HAS_SLOW_BUTTONS) + volatile uint8_t slow_buttons; + #endif + + // Menu System Navigation + screenFunc_t currentScreen = lcd_status_screen; + int8_t encoderTopLine; + typedef struct { + screenFunc_t menu_function; + uint32_t encoder_position; + } menuPosition; + menuPosition screen_history[6]; + uint8_t screen_history_depth = 0; + bool screen_changed, defer_return_to_status; + + // Value Editing + const char *editLabel; + void *editValue; + int32_t minEditValue, maxEditValue; + screenFunc_t callbackFunc; + bool liveEdit; + + // Manual Moves + const float manual_feedrate_mm_m[] = MANUAL_FEEDRATE; + millis_t manual_move_start_time = 0; + int8_t manual_move_axis = (int8_t)NO_AXIS; + #if EXTRUDERS > 1 + int8_t manual_move_e_index = 0; + #else + #define manual_move_e_index 0 + #endif + + #if IS_KINEMATIC + bool processing_manual_move = false; + float manual_move_offset = 0.0; + #else + constexpr bool processing_manual_move = false; + #endif + + #if PIN_EXISTS(SD_DETECT) + uint8_t lcd_sd_status; + #endif + + #if ENABLED(PIDTEMP) + float raw_Ki, raw_Kd; // place-holders for Ki and Kd edits + #endif + + /** + * General function to go directly to a screen + */ + void lcd_goto_screen(screenFunc_t screen, const uint32_t encoder = 0) { + if (currentScreen != screen) { + + #if ENABLED(DOUBLECLICK_FOR_Z_BABYSTEPPING) && ENABLED(BABYSTEPPING) + static millis_t doubleclick_expire_ms = 0; + // Going to lcd_main_menu from status screen? Remember first click time. + // Going back to status screen within a very short time? Go to Z babystepping. + if (screen == lcd_main_menu) { + if (currentScreen == lcd_status_screen) + doubleclick_expire_ms = millis() + DOUBLECLICK_MAX_INTERVAL; + } + else if (screen == lcd_status_screen && currentScreen == lcd_main_menu && PENDING(millis(), doubleclick_expire_ms)) + screen = + #if ENABLED(BABYSTEP_ZPROBE_OFFSET) + lcd_babystep_zoffset + #else + lcd_babystep_z + #endif + ; + #endif + + currentScreen = screen; + encoderPosition = encoder; + if (screen == lcd_status_screen) { + defer_return_to_status = false; + #if ENABLED(AUTO_BED_LEVELING_UBL) + ubl_lcd_map_control = false; + #endif + screen_history_depth = 0; + } + lcd_implementation_clear(); + // Re-initialize custom characters that may be re-used + #if DISABLED(DOGLCD) && ENABLED(AUTO_BED_LEVELING_UBL) + if (!ubl_lcd_map_control) lcd_set_custom_characters( + #if ENABLED(LCD_PROGRESS_BAR) + screen == lcd_status_screen + #endif + ); + #elif ENABLED(LCD_PROGRESS_BAR) + lcd_set_custom_characters(screen == lcd_status_screen); + #endif + lcdDrawUpdate = LCDVIEW_CALL_REDRAW_NEXT; + screen_changed = true; + #if ENABLED(DOGLCD) + drawing_screen = false; + #endif + } + } + + /** + * Show "Moving..." till moves are done, then revert to previous display. + */ + static const char moving[] PROGMEM = MSG_MOVING; + static const char *sync_message = moving; + + // + // Display the synchronize screen until moves are + // finished, and don't return to the caller until + // done. ** This blocks the command queue! ** + // + void _lcd_synchronize() { + static bool no_reentry = false; + if (lcdDrawUpdate) lcd_implementation_drawmenu_static(LCD_HEIGHT >= 4 ? 1 : 0, sync_message); + if (no_reentry) return; + + // Make this the current handler till all moves are done + no_reentry = true; + screenFunc_t old_screen = currentScreen; + lcd_goto_screen(_lcd_synchronize); + stepper.synchronize(); + no_reentry = false; + lcd_goto_screen(old_screen); + } + + // Display the synchronize screen with a custom message + // ** This blocks the command queue! ** + void lcd_synchronize(const char * const msg=NULL) { + sync_message = msg ? msg : moving; + _lcd_synchronize(); + } + + void lcd_return_to_status() { lcd_goto_screen(lcd_status_screen); } + + void lcd_save_previous_screen() { + if (screen_history_depth < COUNT(screen_history)) { + screen_history[screen_history_depth].menu_function = currentScreen; + screen_history[screen_history_depth].encoder_position = encoderPosition; + ++screen_history_depth; + } + } + + void lcd_goto_previous_menu() { + if (screen_history_depth > 0) { + --screen_history_depth; + lcd_goto_screen( + screen_history[screen_history_depth].menu_function, + screen_history[screen_history_depth].encoder_position + ); + } + else + lcd_return_to_status(); + } + + void lcd_goto_previous_menu_no_defer() { + defer_return_to_status = false; + lcd_goto_previous_menu(); + } + +#endif // ULTIPANEL + +/** + * + * "Info Screen" + * + * This is very display-dependent, so the lcd implementation draws this. + */ + +void lcd_status_screen() { + + #if ENABLED(ULTIPANEL) + ENCODER_DIRECTION_NORMAL(); + ENCODER_RATE_MULTIPLY(false); + #endif + + #if ENABLED(LCD_PROGRESS_BAR) + millis_t ms = millis(); + #if DISABLED(PROGRESS_MSG_ONCE) + if (ELAPSED(ms, progress_bar_ms + PROGRESS_BAR_MSG_TIME + PROGRESS_BAR_BAR_TIME)) { + progress_bar_ms = ms; + } + #endif + #if PROGRESS_MSG_EXPIRE > 0 + // Handle message expire + if (expire_status_ms > 0) { + #if ENABLED(SDSUPPORT) + if (card.isFileOpen()) { + // Expire the message when printing is active + if (IS_SD_PRINTING) { + if (ELAPSED(ms, expire_status_ms)) { + lcd_status_message[0] = '\0'; + expire_status_ms = 0; + } + } + else { + expire_status_ms += LCD_UPDATE_INTERVAL; + } + } + else { + expire_status_ms = 0; + } + #else + expire_status_ms = 0; + #endif // SDSUPPORT + } + #endif + #endif // LCD_PROGRESS_BAR + + #if ENABLED(ULTIPANEL) + + if (lcd_clicked) { + #if ENABLED(FILAMENT_LCD_DISPLAY) && ENABLED(SDSUPPORT) + previous_lcd_status_ms = millis(); // get status message to show up for a while + #endif + lcd_implementation_init( // to maybe revive the LCD if static electricity killed it. + #if ENABLED(LCD_PROGRESS_BAR) + false + #endif + ); + lcd_goto_screen(lcd_main_menu); + return; + } + + #if ENABLED(ULTIPANEL_FEEDMULTIPLY) + const int16_t new_frm = feedrate_percentage + (int32_t)encoderPosition; + // Dead zone at 100% feedrate + if ((feedrate_percentage < 100 && new_frm > 100) || (feedrate_percentage > 100 && new_frm < 100)) { + feedrate_percentage = 100; + encoderPosition = 0; + } + else if (feedrate_percentage == 100) { + if ((int32_t)encoderPosition > ENCODER_FEEDRATE_DEADZONE) { + feedrate_percentage += (int32_t)encoderPosition - (ENCODER_FEEDRATE_DEADZONE); + encoderPosition = 0; + } + else if ((int32_t)encoderPosition < -(ENCODER_FEEDRATE_DEADZONE)) { + feedrate_percentage += (int32_t)encoderPosition + ENCODER_FEEDRATE_DEADZONE; + encoderPosition = 0; + } + } + else { + feedrate_percentage = new_frm; + encoderPosition = 0; + } + #endif // ULTIPANEL_FEEDMULTIPLY + + feedrate_percentage = constrain(feedrate_percentage, 10, 999); + + #endif // ULTIPANEL + + lcd_implementation_status_screen(); +} + +void lcd_reset_status() { lcd_setstatusPGM(PSTR(""), -1); } + +/** + * + * draw the kill screen + * + */ +void kill_screen(const char* lcd_msg) { + lcd_init(); + lcd_setalertstatusPGM(lcd_msg); + #if ENABLED(DOGLCD) + u8g.firstPage(); + do { + lcd_kill_screen(); + } while (u8g.nextPage()); + #else + lcd_kill_screen(); + #endif +} + +#if ENABLED(ULTIPANEL) + + /** + * + * Audio feedback for controller clicks + * + */ + void lcd_buzz(long duration, uint16_t freq) { + #if ENABLED(LCD_USE_I2C_BUZZER) + lcd.buzz(duration, freq); + #elif PIN_EXISTS(BEEPER) + buzzer.tone(duration, freq); + #else + UNUSED(duration); UNUSED(freq); + #endif + } + + void lcd_quick_feedback() { + lcdDrawUpdate = LCDVIEW_CLEAR_CALL_REDRAW; + buttons = 0; + next_button_update_ms = millis() + 500; + + // Buzz and wait. The delay is needed for buttons to settle! + lcd_buzz(LCD_FEEDBACK_FREQUENCY_DURATION_MS, LCD_FEEDBACK_FREQUENCY_HZ); + #if ENABLED(LCD_USE_I2C_BUZZER) + delay(10); + #elif PIN_EXISTS(BEEPER) + for (int8_t i = 5; i--;) { buzzer.tick(); delay(2); } + #endif + } + + void lcd_completion_feedback(const bool good/*=true*/) { + if (good) { + lcd_buzz(100, 659); + lcd_buzz(100, 698); + } + else lcd_buzz(20, 440); + } + + inline void line_to_current_z() { + planner.buffer_line_kinematic(current_position, MMM_TO_MMS(manual_feedrate_mm_m[Z_AXIS]), active_extruder); + } + + inline void line_to_z(const float &z) { + current_position[Z_AXIS] = z; + line_to_current_z(); + } + + #if ENABLED(SDSUPPORT) + + void lcd_sdcard_pause() { + card.pauseSDPrint(); + print_job_timer.pause(); + #if ENABLED(PARK_HEAD_ON_PAUSE) + enqueue_and_echo_commands_P(PSTR("M125")); + #endif + lcd_setstatusPGM(PSTR(MSG_PRINT_PAUSED), -1); + } + + void lcd_sdcard_resume() { + #if ENABLED(PARK_HEAD_ON_PAUSE) + enqueue_and_echo_commands_P(PSTR("M24")); + #else + card.startFileprint(); + print_job_timer.start(); + #endif + lcd_reset_status(); + } + + void lcd_sdcard_stop() { + card.stopSDPrint(); + clear_command_queue(); + quickstop_stepper(); + print_job_timer.stop(); + thermalManager.disable_all_heaters(); + #if FAN_COUNT > 0 + for (uint8_t i = 0; i < FAN_COUNT; i++) fanSpeeds[i] = 0; + #endif + wait_for_heatup = false; + lcd_setstatusPGM(PSTR(MSG_PRINT_ABORTED), -1); + lcd_return_to_status(); + } + + #endif // SDSUPPORT + + #if ENABLED(MENU_ITEM_CASE_LIGHT) + + extern uint8_t case_light_brightness; + extern bool case_light_on; + extern void update_case_light(); + + void case_light_menu() { + START_MENU(); + // + // ^ Main + // + MENU_BACK(MSG_MAIN); + MENU_ITEM_EDIT_CALLBACK(int8, MSG_CASE_LIGHT_BRIGHTNESS, &case_light_brightness, 0, 255, update_case_light, true); + MENU_ITEM_EDIT_CALLBACK(bool, MSG_CASE_LIGHT, (bool*)&case_light_on, update_case_light); + END_MENU(); + } + #endif // MENU_ITEM_CASE_LIGHT + + #if ENABLED(BLTOUCH) + + /** + * + * "BLTouch" submenu + * + */ + static void bltouch_menu() { + START_MENU(); + // + // ^ Main + // + MENU_BACK(MSG_MAIN); + MENU_ITEM(gcode, MSG_BLTOUCH_RESET, PSTR("M280 P" STRINGIFY(Z_ENDSTOP_SERVO_NR) " S" STRINGIFY(BLTOUCH_RESET))); + MENU_ITEM(gcode, MSG_BLTOUCH_SELFTEST, PSTR("M280 P" STRINGIFY(Z_ENDSTOP_SERVO_NR) " S" STRINGIFY(BLTOUCH_SELFTEST))); + MENU_ITEM(gcode, MSG_BLTOUCH_DEPLOY, PSTR("M280 P" STRINGIFY(Z_ENDSTOP_SERVO_NR) " S" STRINGIFY(BLTOUCH_DEPLOY))); + MENU_ITEM(gcode, MSG_BLTOUCH_STOW, PSTR("M280 P" STRINGIFY(Z_ENDSTOP_SERVO_NR) " S" STRINGIFY(BLTOUCH_STOW))); + END_MENU(); + } + + #endif // BLTOUCH + + #if ENABLED(LCD_PROGRESS_BAR_TEST) + + static void progress_bar_test() { + static int8_t bar_percent = 0; + if (lcd_clicked) { + lcd_goto_previous_menu(); + lcd_set_custom_characters(false); + return; + } + bar_percent += (int8_t)encoderPosition; + bar_percent = constrain(bar_percent, 0, 100); + encoderPosition = 0; + lcd_implementation_drawmenu_static(0, PSTR(MSG_PROGRESS_BAR_TEST), true, true); + lcd.setCursor((LCD_WIDTH) / 2 - 2, LCD_HEIGHT - 2); + lcd.print(itostr3(bar_percent)); lcd.write('%'); + lcd.setCursor(0, LCD_HEIGHT - 1); lcd_draw_progress_bar(bar_percent); + } + + void _progress_bar_test() { + lcd_goto_screen(progress_bar_test); + lcd_set_custom_characters(); + } + + #endif // LCD_PROGRESS_BAR_TEST + + #if HAS_DEBUG_MENU + + void lcd_debug_menu() { + START_MENU(); + + MENU_BACK(MSG_MAIN); // ^ Main + + #if ENABLED(LCD_PROGRESS_BAR_TEST) + MENU_ITEM(submenu, MSG_PROGRESS_BAR_TEST, _progress_bar_test); + #endif + + END_MENU(); + } + + #endif // HAS_DEBUG_MENU + + #if ENABLED(CUSTOM_USER_MENUS) + + #ifdef USER_SCRIPT_DONE + #define _DONE_SCRIPT "\n" USER_SCRIPT_DONE + #else + #define _DONE_SCRIPT "" + #endif + + void _lcd_user_gcode(const char * const cmd) { + enqueue_and_echo_commands_P(cmd); + #if ENABLED(USER_SCRIPT_AUDIBLE_FEEDBACK) + lcd_completion_feedback(); + #endif + #if ENABLED(USER_SCRIPT_RETURN) + lcd_return_to_status(); + #endif + } + + #if defined(USER_DESC_1) && defined(USER_GCODE_1) + void lcd_user_gcode_1() { _lcd_user_gcode(PSTR(USER_GCODE_1 _DONE_SCRIPT)); } + #endif + #if defined(USER_DESC_2) && defined(USER_GCODE_2) + void lcd_user_gcode_2() { _lcd_user_gcode(PSTR(USER_GCODE_2 _DONE_SCRIPT)); } + #endif + #if defined(USER_DESC_3) && defined(USER_GCODE_3) + void lcd_user_gcode_3() { _lcd_user_gcode(PSTR(USER_GCODE_3 _DONE_SCRIPT)); } + #endif + #if defined(USER_DESC_4) && defined(USER_GCODE_4) + void lcd_user_gcode_4() { _lcd_user_gcode(PSTR(USER_GCODE_4 _DONE_SCRIPT)); } + #endif + #if defined(USER_DESC_5) && defined(USER_GCODE_5) + void lcd_user_gcode_5() { _lcd_user_gcode(PSTR(USER_GCODE_5 _DONE_SCRIPT)); } + #endif + + void _lcd_user_menu() { + START_MENU(); + MENU_BACK(MSG_MAIN); + #if defined(USER_DESC_1) && defined(USER_GCODE_1) + MENU_ITEM(function, USER_DESC_1, lcd_user_gcode_1); + #endif + #if defined(USER_DESC_2) && defined(USER_GCODE_2) + MENU_ITEM(function, USER_DESC_2, lcd_user_gcode_2); + #endif + #if defined(USER_DESC_3) && defined(USER_GCODE_3) + MENU_ITEM(function, USER_DESC_3, lcd_user_gcode_3); + #endif + #if defined(USER_DESC_4) && defined(USER_GCODE_4) + MENU_ITEM(function, USER_DESC_4, lcd_user_gcode_4); + #endif + #if defined(USER_DESC_5) && defined(USER_GCODE_5) + MENU_ITEM(function, USER_DESC_5, lcd_user_gcode_5); + #endif + END_MENU(); + } + + #endif + + /** + * + * "Main" menu + * + */ + + void lcd_main_menu() { + START_MENU(); + MENU_BACK(MSG_WATCH); + + #if ENABLED(CUSTOM_USER_MENUS) + MENU_ITEM(submenu, MSG_USER_MENU, _lcd_user_menu); + #endif + + // + // Debug Menu when certain options are enabled + // + #if HAS_DEBUG_MENU + MENU_ITEM(submenu, MSG_DEBUG_MENU, lcd_debug_menu); + #endif + + // + // Set Case light on/off/brightness + // + #if ENABLED(MENU_ITEM_CASE_LIGHT) + if (USEABLE_HARDWARE_PWM(CASE_LIGHT_PIN)) { + MENU_ITEM(submenu, MSG_CASE_LIGHT, case_light_menu); + } + else + MENU_ITEM_EDIT_CALLBACK(bool, MSG_CASE_LIGHT, (bool*)&case_light_on, update_case_light); + #endif + + if (planner.movesplanned() || IS_SD_PRINTING) { + MENU_ITEM(submenu, MSG_TUNE, lcd_tune_menu); + } + else { + MENU_ITEM(submenu, MSG_PREPARE, lcd_prepare_menu); + } + MENU_ITEM(submenu, MSG_CONTROL, lcd_control_menu); + + #if ENABLED(SDSUPPORT) + if (card.cardOK) { + if (card.isFileOpen()) { + if (card.sdprinting) + MENU_ITEM(function, MSG_PAUSE_PRINT, lcd_sdcard_pause); + else + MENU_ITEM(function, MSG_RESUME_PRINT, lcd_sdcard_resume); + MENU_ITEM(function, MSG_STOP_PRINT, lcd_sdcard_stop); + } + else { + MENU_ITEM(submenu, MSG_CARD_MENU, lcd_sdcard_menu); + #if !PIN_EXISTS(SD_DETECT) + MENU_ITEM(gcode, MSG_CNG_SDCARD, PSTR("M21")); // SD-card changed by user + #endif + } + } + else { + MENU_ITEM(submenu, MSG_NO_CARD, lcd_sdcard_menu); + #if !PIN_EXISTS(SD_DETECT) + MENU_ITEM(gcode, MSG_INIT_SDCARD, PSTR("M21")); // Manually initialize the SD-card via user interface + #endif + } + #endif // SDSUPPORT + + #if ENABLED(LCD_INFO_MENU) + MENU_ITEM(submenu, MSG_INFO_MENU, lcd_info_menu); + #endif + + END_MENU(); + } + + /** + * + * "Tune" submenu items + * + */ + + #if HAS_M206_COMMAND + /** + * Set the home offset based on the current_position + */ + void lcd_set_home_offsets() { + // M428 Command + enqueue_and_echo_commands_P(PSTR("M428")); + lcd_return_to_status(); + } + #endif + + #if ENABLED(BABYSTEPPING) + + void _lcd_babystep(const AxisEnum axis, const char* msg) { + if (lcd_clicked) { return lcd_goto_previous_menu_no_defer(); } + ENCODER_DIRECTION_NORMAL(); + if (encoderPosition) { + const int16_t babystep_increment = (int32_t)encoderPosition * (BABYSTEP_MULTIPLICATOR); + encoderPosition = 0; + lcdDrawUpdate = LCDVIEW_REDRAW_NOW; + thermalManager.babystep_axis(axis, babystep_increment); + babysteps_done += babystep_increment; + } + if (lcdDrawUpdate) + lcd_implementation_drawedit(msg, ftostr43sign(planner.steps_to_mm[axis] * babysteps_done)); + } + + #if ENABLED(BABYSTEP_XY) + void _lcd_babystep_x() { _lcd_babystep(X_AXIS, PSTR(MSG_BABYSTEP_X)); } + void _lcd_babystep_y() { _lcd_babystep(Y_AXIS, PSTR(MSG_BABYSTEP_Y)); } + void lcd_babystep_x() { lcd_goto_screen(_lcd_babystep_x); babysteps_done = 0; defer_return_to_status = true; } + void lcd_babystep_y() { lcd_goto_screen(_lcd_babystep_y); babysteps_done = 0; defer_return_to_status = true; } + #endif + + #if ENABLED(BABYSTEP_ZPROBE_OFFSET) + + #if ENABLED(BABYSTEP_ZPROBE_GFX_OVERLAY) + void _lcd_babystep_zoffset_overlay(const float zprobe_zoffset) { + // Determine whether the user is raising or lowering the nozzle. + static int dir = 0; + static float old_zprobe_zoffset = 0; + if (zprobe_zoffset != old_zprobe_zoffset) { + dir = (zprobe_zoffset > old_zprobe_zoffset) ? 1 : -1; + old_zprobe_zoffset = zprobe_zoffset; + } + + #if ENABLED(BABYSTEP_ZPROBE_GFX_REVERSE) + const unsigned char* rot_up = ccw_bmp; + const unsigned char* rot_down = cw_bmp; + #else + const unsigned char* rot_up = cw_bmp; + const unsigned char* rot_down = ccw_bmp; + #endif + + #if ENABLED(USE_BIG_EDIT_FONT) + const int left = 0, + right = 45, + nozzle = 95; + #else + const int left = 5, + right = 90, + nozzle = 60; + #endif + + // Draw a representation of the nozzle + if (PAGE_CONTAINS(3, 16)) u8g.drawBitmapP(nozzle + 6, 4 - dir, 2, 12, nozzle_bmp); + if (PAGE_CONTAINS(20, 20)) u8g.drawBitmapP(nozzle + 0, 20, 3, 1, offset_bedline_bmp); + + // Draw cw/ccw indicator and up/down arrows. + if (PAGE_CONTAINS(47, 62)) { + u8g.drawBitmapP(left + 0, 47, 3, 16, rot_down); + u8g.drawBitmapP(right + 0, 47, 3, 16, rot_up); + u8g.drawBitmapP(right + 20, 48 - dir, 2, 13, up_arrow_bmp); + u8g.drawBitmapP(left + 20, 49 - dir, 2, 13, down_arrow_bmp); + } + } + #endif // BABYSTEP_ZPROBE_GFX_OVERLAY + + void lcd_babystep_zoffset() { + if (lcd_clicked) { return lcd_goto_previous_menu_no_defer(); } + defer_return_to_status = true; + ENCODER_DIRECTION_NORMAL(); + if (encoderPosition) { + const int16_t babystep_increment = (int32_t)encoderPosition * (BABYSTEP_MULTIPLICATOR); + encoderPosition = 0; + + const float new_zoffset = zprobe_zoffset + planner.steps_to_mm[Z_AXIS] * babystep_increment; + if (WITHIN(new_zoffset, Z_PROBE_OFFSET_RANGE_MIN, Z_PROBE_OFFSET_RANGE_MAX)) { + + if (planner.abl_enabled) + thermalManager.babystep_axis(Z_AXIS, babystep_increment); + + zprobe_zoffset = new_zoffset; + refresh_zprobe_zoffset(true); + lcdDrawUpdate = LCDVIEW_CALL_REDRAW_NEXT; + } + } + if (lcdDrawUpdate) { + lcd_implementation_drawedit(PSTR(MSG_ZPROBE_ZOFFSET), ftostr43sign(zprobe_zoffset)); + #if ENABLED(BABYSTEP_ZPROBE_GFX_OVERLAY) + _lcd_babystep_zoffset_overlay(zprobe_zoffset); + #endif + } + } + + #else // !BABYSTEP_ZPROBE_OFFSET + + void _lcd_babystep_z() { _lcd_babystep(Z_AXIS, PSTR(MSG_BABYSTEP_Z)); } + void lcd_babystep_z() { lcd_goto_screen(_lcd_babystep_z); babysteps_done = 0; defer_return_to_status = true; } + + #endif // !BABYSTEP_ZPROBE_OFFSET + + #endif // BABYSTEPPING + + #if ENABLED(AUTO_BED_LEVELING_UBL) + + 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; + + static void _lcd_mesh_fine_tune(const char* msg) { + defer_return_to_status = true; + if (ubl.encoder_diff) { + ubl_encoderPosition = (ubl.encoder_diff > 0) ? 1 : -1; + ubl.encoder_diff = 0; + + mesh_edit_accumulator += float(ubl_encoderPosition) * 0.005 / 2.0; + mesh_edit_value = mesh_edit_accumulator; + encoderPosition = 0; + lcdDrawUpdate = LCDVIEW_CALL_REDRAW_NEXT; + + const int32_t rounded = (int32_t)(mesh_edit_value * 1000.0); + mesh_edit_value = float(rounded - (rounded % 5L)) / 1000.0; + } + + if (lcdDrawUpdate) + lcd_implementation_drawedit(msg, ftostr43sign(mesh_edit_value)); + } + + void _lcd_mesh_edit_NOP() { + defer_return_to_status = true; + } + + float lcd_mesh_edit() { + lcd_goto_screen(_lcd_mesh_edit_NOP); + lcdDrawUpdate = LCDVIEW_CALL_REDRAW_NEXT; + _lcd_mesh_fine_tune(PSTR("Mesh Editor")); + return mesh_edit_value; + } + + void lcd_mesh_edit_setup(float initial) { + mesh_edit_value = mesh_edit_accumulator = initial; + lcd_goto_screen(_lcd_mesh_edit_NOP); + } + + void _lcd_z_offset_edit() { + _lcd_mesh_fine_tune(PSTR("Z-Offset: ")); + } + + float lcd_z_offset_edit() { + lcd_goto_screen(_lcd_z_offset_edit); + return mesh_edit_value; + } + + void lcd_z_offset_edit_setup(float initial) { + mesh_edit_value = mesh_edit_accumulator = initial; + lcd_goto_screen(_lcd_z_offset_edit); + } + + #endif // AUTO_BED_LEVELING_UBL + + + /** + * Watch temperature callbacks + */ + #if HAS_TEMP_HOTEND + #if WATCH_HOTENDS + #define _WATCH_FUNC(N) thermalManager.start_watching_heater(N) + #else + #define _WATCH_FUNC(N) NOOP + #endif + void watch_temp_callback_E0() { _WATCH_FUNC(0); } + #if HOTENDS > 1 + void watch_temp_callback_E1() { _WATCH_FUNC(1); } + #if HOTENDS > 2 + void watch_temp_callback_E2() { _WATCH_FUNC(2); } + #if HOTENDS > 3 + void watch_temp_callback_E3() { _WATCH_FUNC(3); } + #if HOTENDS > 4 + void watch_temp_callback_E4() { _WATCH_FUNC(4); } + #endif // HOTENDS > 4 + #endif // HOTENDS > 3 + #endif // HOTENDS > 2 + #endif // HOTENDS > 1 + #endif // HAS_TEMP_HOTEND + + void watch_temp_callback_bed() { + #if WATCH_THE_BED + thermalManager.start_watching_bed(); + #endif + } + + #if ENABLED(ADVANCED_PAUSE_FEATURE) + + void lcd_enqueue_filament_change() { + + #if ENABLED(PREVENT_COLD_EXTRUSION) + if (!DEBUGGING(DRYRUN) && !thermalManager.allow_cold_extrude && + thermalManager.degTargetHotend(active_extruder) < thermalManager.extrude_min_temp) { + lcd_save_previous_screen(); + lcd_goto_screen(lcd_advanced_pause_toocold_menu); + return; + } + #endif + + lcd_advanced_pause_show_message(ADVANCED_PAUSE_MESSAGE_INIT); + enqueue_and_echo_commands_P(PSTR("M600 B0")); + } + + #endif // ADVANCED_PAUSE_FEATURE + + /** + * + * "Tune" submenu + * + */ + void lcd_tune_menu() { + START_MENU(); + + // + // ^ Main + // + MENU_BACK(MSG_MAIN); + + // + // Speed: + // + MENU_ITEM_EDIT(int3, MSG_SPEED, &feedrate_percentage, 10, 999); + + // Manual bed leveling, Bed Z: + #if ENABLED(MESH_BED_LEVELING) && ENABLED(LCD_BED_LEVELING) + MENU_ITEM_EDIT(float43, MSG_BED_Z, &mbl.z_offset, -1, 1); + #endif + + // + // Nozzle: + // Nozzle [1-4]: + // + #if HOTENDS == 1 + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(int3, MSG_NOZZLE, &thermalManager.target_temperature[0], 0, HEATER_0_MAXTEMP - 15, watch_temp_callback_E0); + #else // HOTENDS > 1 + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(int3, MSG_NOZZLE MSG_N1, &thermalManager.target_temperature[0], 0, HEATER_0_MAXTEMP - 15, watch_temp_callback_E0); + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(int3, MSG_NOZZLE MSG_N2, &thermalManager.target_temperature[1], 0, HEATER_1_MAXTEMP - 15, watch_temp_callback_E1); + #if HOTENDS > 2 + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(int3, MSG_NOZZLE MSG_N3, &thermalManager.target_temperature[2], 0, HEATER_2_MAXTEMP - 15, watch_temp_callback_E2); + #if HOTENDS > 3 + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(int3, MSG_NOZZLE MSG_N4, &thermalManager.target_temperature[3], 0, HEATER_3_MAXTEMP - 15, watch_temp_callback_E3); + #if HOTENDS > 4 + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(int3, MSG_NOZZLE MSG_N5, &thermalManager.target_temperature[4], 0, HEATER_4_MAXTEMP - 15, watch_temp_callback_E4); + #endif // HOTENDS > 4 + #endif // HOTENDS > 3 + #endif // HOTENDS > 2 + #endif // HOTENDS > 1 + + // + // Bed: + // + #if HAS_TEMP_BED + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(int3, MSG_BED, &thermalManager.target_temperature_bed, 0, BED_MAXTEMP - 15, watch_temp_callback_bed); + #endif + + // + // Fan Speed: + // + #if FAN_COUNT > 0 + #if HAS_FAN0 + #if FAN_COUNT > 1 + #define MSG_1ST_FAN_SPEED MSG_FAN_SPEED " 1" + #else + #define MSG_1ST_FAN_SPEED MSG_FAN_SPEED + #endif + MENU_MULTIPLIER_ITEM_EDIT(int3, MSG_1ST_FAN_SPEED, &fanSpeeds[0], 0, 255); + #endif + #if HAS_FAN1 + MENU_MULTIPLIER_ITEM_EDIT(int3, MSG_FAN_SPEED " 2", &fanSpeeds[1], 0, 255); + #endif + #if HAS_FAN2 + MENU_MULTIPLIER_ITEM_EDIT(int3, MSG_FAN_SPEED " 3", &fanSpeeds[2], 0, 255); + #endif + #endif // FAN_COUNT > 0 + + // + // Flow: + // Flow [1-5]: + // + #if EXTRUDERS == 1 + MENU_ITEM_EDIT(int3, MSG_FLOW, &flow_percentage[0], 10, 999); + #else // EXTRUDERS > 1 + MENU_ITEM_EDIT(int3, MSG_FLOW, &flow_percentage[active_extruder], 10, 999); + MENU_ITEM_EDIT(int3, MSG_FLOW MSG_N1, &flow_percentage[0], 10, 999); + MENU_ITEM_EDIT(int3, MSG_FLOW MSG_N2, &flow_percentage[1], 10, 999); + #if EXTRUDERS > 2 + MENU_ITEM_EDIT(int3, MSG_FLOW MSG_N3, &flow_percentage[2], 10, 999); + #if EXTRUDERS > 3 + MENU_ITEM_EDIT(int3, MSG_FLOW MSG_N4, &flow_percentage[3], 10, 999); + #if EXTRUDERS > 4 + MENU_ITEM_EDIT(int3, MSG_FLOW MSG_N5, &flow_percentage[4], 10, 999); + #endif // EXTRUDERS > 4 + #endif // EXTRUDERS > 3 + #endif // EXTRUDERS > 2 + #endif // EXTRUDERS > 1 + + // + // Babystep X: + // Babystep Y: + // Babystep Z: + // + #if ENABLED(BABYSTEPPING) + #if ENABLED(BABYSTEP_XY) + MENU_ITEM(submenu, MSG_BABYSTEP_X, lcd_babystep_x); + MENU_ITEM(submenu, MSG_BABYSTEP_Y, lcd_babystep_y); + #endif + #if ENABLED(BABYSTEP_ZPROBE_OFFSET) + MENU_ITEM(submenu, MSG_ZPROBE_ZOFFSET, lcd_babystep_zoffset); + #else + MENU_ITEM(submenu, MSG_BABYSTEP_Z, lcd_babystep_z); + #endif + #endif + + // + // Change filament + // + #if ENABLED(ADVANCED_PAUSE_FEATURE) + if (!thermalManager.tooColdToExtrude(active_extruder)) + MENU_ITEM(function, MSG_FILAMENTCHANGE, lcd_enqueue_filament_change); + #endif + + END_MENU(); + } + + /** + * + * "Driver current control" submenu items + * + */ + #if ENABLED(DAC_STEPPER_CURRENT) + + void dac_driver_getValues() { LOOP_XYZE(i) driverPercent[i] = dac_current_get_percent((AxisEnum)i); } + + void dac_driver_commit() { dac_current_set_percents(driverPercent); } + + void dac_driver_eeprom_write() { dac_commit_eeprom(); } + + void lcd_dac_menu() { + dac_driver_getValues(); + START_MENU(); + MENU_BACK(MSG_CONTROL); + MENU_ITEM_EDIT_CALLBACK(int8, MSG_X " " MSG_DAC_PERCENT, &driverPercent[X_AXIS], 0, 100, dac_driver_commit); + MENU_ITEM_EDIT_CALLBACK(int8, MSG_Y " " MSG_DAC_PERCENT, &driverPercent[Y_AXIS], 0, 100, dac_driver_commit); + MENU_ITEM_EDIT_CALLBACK(int8, MSG_Z " " MSG_DAC_PERCENT, &driverPercent[Z_AXIS], 0, 100, dac_driver_commit); + MENU_ITEM_EDIT_CALLBACK(int8, MSG_E " " MSG_DAC_PERCENT, &driverPercent[E_AXIS], 0, 100, dac_driver_commit); + MENU_ITEM(function, MSG_DAC_EEPROM_WRITE, dac_driver_eeprom_write); + END_MENU(); + } + + #endif // DAC_STEPPER_CURRENT + + #if HAS_MOTOR_CURRENT_PWM + + void lcd_pwm_menu() { + START_MENU(); + MENU_BACK(MSG_CONTROL); + #if PIN_EXISTS(MOTOR_CURRENT_PWM_XY) + MENU_ITEM_EDIT_CALLBACK(long5, MSG_X MSG_Y, &stepper.motor_current_setting[0], 100, 2000, Stepper::refresh_motor_power); + #endif + #if PIN_EXISTS(MOTOR_CURRENT_PWM_Z) + MENU_ITEM_EDIT_CALLBACK(long5, MSG_Z, &stepper.motor_current_setting[1], 100, 2000, Stepper::refresh_motor_power); + #endif + #if PIN_EXISTS(MOTOR_CURRENT_PWM_E) + MENU_ITEM_EDIT_CALLBACK(long5, MSG_E, &stepper.motor_current_setting[2], 100, 2000, Stepper::refresh_motor_power); + #endif + END_MENU(); + } + + #endif // HAS_MOTOR_CURRENT_PWM + + constexpr int16_t heater_maxtemp[HOTENDS] = ARRAY_BY_HOTENDS(HEATER_0_MAXTEMP, HEATER_1_MAXTEMP, HEATER_2_MAXTEMP, HEATER_3_MAXTEMP, HEATER_4_MAXTEMP); + + /** + * + * "Prepare" submenu items + * + */ + void _lcd_preheat(const int16_t endnum, const int16_t temph, const int16_t tempb, const int16_t fan) { + if (temph > 0) thermalManager.setTargetHotend(min(heater_maxtemp[endnum], temph), endnum); + #if TEMP_SENSOR_BED != 0 + if (tempb >= 0) thermalManager.setTargetBed(tempb); + #else + UNUSED(tempb); + #endif + #if FAN_COUNT > 0 + #if FAN_COUNT > 1 + fanSpeeds[active_extruder < FAN_COUNT ? active_extruder : 0] = fan; + #else + fanSpeeds[0] = fan; + #endif + #else + UNUSED(fan); + #endif + lcd_return_to_status(); + } + + #if TEMP_SENSOR_0 != 0 + void lcd_preheat_m1_e0_only() { _lcd_preheat(0, lcd_preheat_hotend_temp[0], -1, lcd_preheat_fan_speed[0]); } + void lcd_preheat_m2_e0_only() { _lcd_preheat(0, lcd_preheat_hotend_temp[1], -1, lcd_preheat_fan_speed[1]); } + #if TEMP_SENSOR_BED != 0 + void lcd_preheat_m1_e0() { _lcd_preheat(0, lcd_preheat_hotend_temp[0], lcd_preheat_bed_temp[0], lcd_preheat_fan_speed[0]); } + void lcd_preheat_m2_e0() { _lcd_preheat(0, lcd_preheat_hotend_temp[1], lcd_preheat_bed_temp[1], lcd_preheat_fan_speed[1]); } + #endif + #endif + + #if HOTENDS > 1 + void lcd_preheat_m1_e1_only() { _lcd_preheat(1, lcd_preheat_hotend_temp[0], -1, lcd_preheat_fan_speed[0]); } + void lcd_preheat_m2_e1_only() { _lcd_preheat(1, lcd_preheat_hotend_temp[1], -1, lcd_preheat_fan_speed[1]); } + #if TEMP_SENSOR_BED != 0 + void lcd_preheat_m1_e1() { _lcd_preheat(1, lcd_preheat_hotend_temp[0], lcd_preheat_bed_temp[0], lcd_preheat_fan_speed[0]); } + void lcd_preheat_m2_e1() { _lcd_preheat(1, lcd_preheat_hotend_temp[1], lcd_preheat_bed_temp[1], lcd_preheat_fan_speed[1]); } + #endif + #if HOTENDS > 2 + void lcd_preheat_m1_e2_only() { _lcd_preheat(2, lcd_preheat_hotend_temp[0], -1, lcd_preheat_fan_speed[0]); } + void lcd_preheat_m2_e2_only() { _lcd_preheat(2, lcd_preheat_hotend_temp[1], -1, lcd_preheat_fan_speed[1]); } + #if TEMP_SENSOR_BED != 0 + void lcd_preheat_m1_e2() { _lcd_preheat(2, lcd_preheat_hotend_temp[0], lcd_preheat_bed_temp[0], lcd_preheat_fan_speed[0]); } + void lcd_preheat_m2_e2() { _lcd_preheat(2, lcd_preheat_hotend_temp[1], lcd_preheat_bed_temp[1], lcd_preheat_fan_speed[1]); } + #endif + #if HOTENDS > 3 + void lcd_preheat_m1_e3_only() { _lcd_preheat(3, lcd_preheat_hotend_temp[0], -1, lcd_preheat_fan_speed[0]); } + void lcd_preheat_m2_e3_only() { _lcd_preheat(3, lcd_preheat_hotend_temp[1], -1, lcd_preheat_fan_speed[1]); } + #if TEMP_SENSOR_BED != 0 + void lcd_preheat_m1_e3() { _lcd_preheat(3, lcd_preheat_hotend_temp[0], lcd_preheat_bed_temp[0], lcd_preheat_fan_speed[0]); } + void lcd_preheat_m2_e3() { _lcd_preheat(3, lcd_preheat_hotend_temp[1], lcd_preheat_bed_temp[1], lcd_preheat_fan_speed[1]); } + #endif + #if HOTENDS > 4 + void lcd_preheat_m1_e4_only() { _lcd_preheat(4, lcd_preheat_hotend_temp[0], -1, lcd_preheat_fan_speed[0]); } + void lcd_preheat_m2_e4_only() { _lcd_preheat(4, lcd_preheat_hotend_temp[1], -1, lcd_preheat_fan_speed[1]); } + #if TEMP_SENSOR_BED != 0 + void lcd_preheat_m1_e4() { _lcd_preheat(4, lcd_preheat_hotend_temp[0], lcd_preheat_bed_temp[0], lcd_preheat_fan_speed[0]); } + void lcd_preheat_m2_e4() { _lcd_preheat(4, lcd_preheat_hotend_temp[1], lcd_preheat_bed_temp[1], lcd_preheat_fan_speed[1]); } + #endif + #endif // HOTENDS > 4 + #endif // HOTENDS > 3 + #endif // HOTENDS > 2 + + void lcd_preheat_m1_all() { + #if HOTENDS > 1 + thermalManager.setTargetHotend(lcd_preheat_hotend_temp[0], 1); + #if HOTENDS > 2 + thermalManager.setTargetHotend(lcd_preheat_hotend_temp[0], 2); + #if HOTENDS > 3 + thermalManager.setTargetHotend(lcd_preheat_hotend_temp[0], 3); + #if HOTENDS > 4 + thermalManager.setTargetHotend(lcd_preheat_hotend_temp[0], 4); + #endif // HOTENDS > 4 + #endif // HOTENDS > 3 + #endif // HOTENDS > 2 + #endif // HOTENDS > 1 + #if TEMP_SENSOR_BED != 0 + lcd_preheat_m1_e0(); + #else + lcd_preheat_m1_e0_only(); + #endif + } + void lcd_preheat_m2_all() { + #if HOTENDS > 1 + thermalManager.setTargetHotend(lcd_preheat_hotend_temp[1], 1); + #if HOTENDS > 2 + thermalManager.setTargetHotend(lcd_preheat_hotend_temp[1], 2); + #if HOTENDS > 3 + thermalManager.setTargetHotend(lcd_preheat_hotend_temp[1], 3); + #if HOTENDS > 4 + thermalManager.setTargetHotend(lcd_preheat_hotend_temp[1], 4); + #endif // HOTENDS > 4 + #endif // HOTENDS > 3 + #endif // HOTENDS > 2 + #endif // HOTENDS > 1 + #if TEMP_SENSOR_BED != 0 + lcd_preheat_m2_e0(); + #else + lcd_preheat_m2_e0_only(); + #endif + } + + #endif // HOTENDS > 1 + + #if TEMP_SENSOR_BED != 0 + void lcd_preheat_m1_bedonly() { _lcd_preheat(0, 0, lcd_preheat_bed_temp[0], lcd_preheat_fan_speed[0]); } + void lcd_preheat_m2_bedonly() { _lcd_preheat(0, 0, lcd_preheat_bed_temp[1], lcd_preheat_fan_speed[1]); } + #endif + + #if TEMP_SENSOR_0 != 0 && (TEMP_SENSOR_1 != 0 || TEMP_SENSOR_2 != 0 || TEMP_SENSOR_3 != 0 || TEMP_SENSOR_4 != 0 || TEMP_SENSOR_BED != 0) + + void lcd_preheat_m1_menu() { + START_MENU(); + MENU_BACK(MSG_PREPARE); + #if HOTENDS == 1 + #if TEMP_SENSOR_BED != 0 + MENU_ITEM(function, MSG_PREHEAT_1, lcd_preheat_m1_e0); + MENU_ITEM(function, MSG_PREHEAT_1_END, lcd_preheat_m1_e0_only); + #else + MENU_ITEM(function, MSG_PREHEAT_1, lcd_preheat_m1_e0_only); + #endif + #else + #if TEMP_SENSOR_BED != 0 + MENU_ITEM(function, MSG_PREHEAT_1_N MSG_H1, lcd_preheat_m1_e0); + MENU_ITEM(function, MSG_PREHEAT_1_END " " MSG_E1, lcd_preheat_m1_e0_only); + MENU_ITEM(function, MSG_PREHEAT_1_N MSG_H2, lcd_preheat_m1_e1); + MENU_ITEM(function, MSG_PREHEAT_1_END " " MSG_E2, lcd_preheat_m1_e1_only); + #else + MENU_ITEM(function, MSG_PREHEAT_1_N MSG_H1, lcd_preheat_m1_e0_only); + MENU_ITEM(function, MSG_PREHEAT_1_N MSG_H2, lcd_preheat_m1_e1_only); + #endif + #if HOTENDS > 2 + #if TEMP_SENSOR_BED != 0 + MENU_ITEM(function, MSG_PREHEAT_1_N MSG_H3, lcd_preheat_m1_e2); + MENU_ITEM(function, MSG_PREHEAT_1_END " " MSG_E3, lcd_preheat_m1_e2_only); + #else + MENU_ITEM(function, MSG_PREHEAT_1_N MSG_H3, lcd_preheat_m1_e2_only); + #endif + #if HOTENDS > 3 + #if TEMP_SENSOR_BED != 0 + MENU_ITEM(function, MSG_PREHEAT_1_N MSG_H4, lcd_preheat_m1_e3); + MENU_ITEM(function, MSG_PREHEAT_1_END " " MSG_E4, lcd_preheat_m1_e3_only); + #else + MENU_ITEM(function, MSG_PREHEAT_1_N MSG_H4, lcd_preheat_m1_e3_only); + #endif + #if HOTENDS > 4 + #if TEMP_SENSOR_BED != 0 + MENU_ITEM(function, MSG_PREHEAT_1_N MSG_H5, lcd_preheat_m1_e4); + MENU_ITEM(function, MSG_PREHEAT_1_END " " MSG_E5, lcd_preheat_m1_e4_only); + #else + MENU_ITEM(function, MSG_PREHEAT_1_N MSG_H5, lcd_preheat_m1_e4_only); + #endif + #endif // HOTENDS > 4 + #endif // HOTENDS > 3 + #endif // HOTENDS > 2 + MENU_ITEM(function, MSG_PREHEAT_1_ALL, lcd_preheat_m1_all); + #endif // HOTENDS > 1 + #if TEMP_SENSOR_BED != 0 + MENU_ITEM(function, MSG_PREHEAT_1_BEDONLY, lcd_preheat_m1_bedonly); + #endif + END_MENU(); + } + + void lcd_preheat_m2_menu() { + START_MENU(); + MENU_BACK(MSG_PREPARE); + #if HOTENDS == 1 + #if TEMP_SENSOR_BED != 0 + MENU_ITEM(function, MSG_PREHEAT_2, lcd_preheat_m2_e0); + MENU_ITEM(function, MSG_PREHEAT_2_END, lcd_preheat_m2_e0_only); + #else + MENU_ITEM(function, MSG_PREHEAT_2, lcd_preheat_m2_e0_only); + #endif + #else + #if TEMP_SENSOR_BED != 0 + MENU_ITEM(function, MSG_PREHEAT_2_N MSG_H1, lcd_preheat_m2_e0); + MENU_ITEM(function, MSG_PREHEAT_2_END " " MSG_E1, lcd_preheat_m2_e0_only); + MENU_ITEM(function, MSG_PREHEAT_2_N MSG_H2, lcd_preheat_m2_e1); + MENU_ITEM(function, MSG_PREHEAT_2_END " " MSG_E2, lcd_preheat_m2_e1_only); + #else + MENU_ITEM(function, MSG_PREHEAT_2_N MSG_H1, lcd_preheat_m2_e0_only); + MENU_ITEM(function, MSG_PREHEAT_2_N MSG_H2, lcd_preheat_m2_e1_only); + #endif + #if HOTENDS > 2 + #if TEMP_SENSOR_BED != 0 + MENU_ITEM(function, MSG_PREHEAT_2_N MSG_H3, lcd_preheat_m2_e2); + MENU_ITEM(function, MSG_PREHEAT_2_END " " MSG_E3, lcd_preheat_m2_e2_only); + #else + MENU_ITEM(function, MSG_PREHEAT_2_N MSG_H3, lcd_preheat_m2_e2_only); + #endif + #if HOTENDS > 3 + #if TEMP_SENSOR_BED != 0 + MENU_ITEM(function, MSG_PREHEAT_2_N MSG_H4, lcd_preheat_m2_e3); + MENU_ITEM(function, MSG_PREHEAT_2_END " " MSG_E4, lcd_preheat_m2_e3_only); + #else + MENU_ITEM(function, MSG_PREHEAT_2_N MSG_H4, lcd_preheat_m2_e3_only); + #endif + #if HOTENDS > 4 + #if TEMP_SENSOR_BED != 0 + MENU_ITEM(function, MSG_PREHEAT_2_N MSG_H5, lcd_preheat_m2_e4); + MENU_ITEM(function, MSG_PREHEAT_2_END " " MSG_E5, lcd_preheat_m2_e4_only); + #else + MENU_ITEM(function, MSG_PREHEAT_2_N MSG_H5, lcd_preheat_m2_e4_only); + #endif + #endif // HOTENDS > 4 + #endif // HOTENDS > 3 + #endif // HOTENDS > 2 + MENU_ITEM(function, MSG_PREHEAT_2_ALL, lcd_preheat_m2_all); + #endif // HOTENDS > 1 + #if TEMP_SENSOR_BED != 0 + MENU_ITEM(function, MSG_PREHEAT_2_BEDONLY, lcd_preheat_m2_bedonly); + #endif + END_MENU(); + } + + #endif // TEMP_SENSOR_0 && (TEMP_SENSOR_1 || TEMP_SENSOR_2 || TEMP_SENSOR_3 || TEMP_SENSOR_4 || TEMP_SENSOR_BED) + + void lcd_cooldown() { + #if FAN_COUNT > 0 + for (uint8_t i = 0; i < FAN_COUNT; i++) fanSpeeds[i] = 0; + #endif + thermalManager.disable_all_heaters(); + lcd_return_to_status(); + } + + #if ENABLED(SDSUPPORT) && ENABLED(MENU_ADDAUTOSTART) + + void lcd_autostart_sd() { + card.autostart_index = 0; + card.setroot(); + card.checkautostart(true); + } + + #endif + + #if ENABLED(EEPROM_SETTINGS) + static void lcd_store_settings() { lcd_completion_feedback(settings.save()); } + static void lcd_load_settings() { lcd_completion_feedback(settings.load()); } + #endif + + #if HAS_BED_PROBE && DISABLED(BABYSTEP_ZPROBE_OFFSET) + static void lcd_refresh_zprobe_zoffset() { refresh_zprobe_zoffset(); } + #endif + + + #if ENABLED(LEVEL_BED_CORNERS) + + /** + * Level corners, starting in the front-left corner. + */ + static int8_t bed_corner; + void _lcd_goto_next_corner() { + line_to_z(LOGICAL_Z_POSITION(4.0)); + switch (bed_corner) { + case 0: + current_position[X_AXIS] = X_MIN_BED + 10; + current_position[Y_AXIS] = Y_MIN_BED + 10; + break; + case 1: + current_position[X_AXIS] = X_MAX_BED - 10; + break; + case 2: + current_position[Y_AXIS] = Y_MAX_BED - 10; + break; + case 3: + current_position[X_AXIS] = X_MIN_BED + 10; + break; + } + planner.buffer_line_kinematic(current_position, MMM_TO_MMS(manual_feedrate_mm_m[X_AXIS]), active_extruder); + line_to_z(LOGICAL_Z_POSITION(0.0)); + if (++bed_corner > 3) bed_corner = 0; + } + + void _lcd_corner_submenu() { + START_MENU(); + MENU_ITEM(function, MSG_NEXT_CORNER, _lcd_goto_next_corner); + MENU_ITEM(function, MSG_BACK, lcd_goto_previous_menu_no_defer); + END_MENU(); + } + + void _lcd_level_bed_corners() { + defer_return_to_status = true; + lcd_goto_screen(_lcd_corner_submenu); + bed_corner = 0; + _lcd_goto_next_corner(); + } + + #endif // LEVEL_BED_CORNERS + + #if ENABLED(LCD_BED_LEVELING) + + /** + * + * "Prepare" > "Level Bed" handlers + * + */ + + 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 + ); + + // + // Raise Z to the "manual probe height" + // Don't return until done. + // ** This blocks the command queue! ** + // + void _lcd_after_probing() { + #if MANUAL_PROBE_HEIGHT > 0 + line_to_z(LOGICAL_Z_POSITION(Z_MIN_POS) + MANUAL_PROBE_HEIGHT); + #endif + // Display "Done" screen and wait for moves to complete + #if MANUAL_PROBE_HEIGHT > 0 || ENABLED(MESH_BED_LEVELING) + lcd_synchronize(PSTR(MSG_LEVEL_BED_DONE)); + #endif + lcd_goto_previous_menu(); + lcd_completion_feedback(); + defer_return_to_status = false; + //LCD_MESSAGEPGM(MSG_LEVEL_BED_DONE); + } + + #if ENABLED(MESH_BED_LEVELING) + + // Utility to go to the next mesh point + inline void _manual_probe_goto_xy(float x, float y) { + #if MANUAL_PROBE_HEIGHT > 0 + const float prev_z = current_position[Z_AXIS]; + line_to_z(LOGICAL_Z_POSITION(Z_MIN_POS) + MANUAL_PROBE_HEIGHT); + #endif + current_position[X_AXIS] = LOGICAL_X_POSITION(x); + current_position[Y_AXIS] = LOGICAL_Y_POSITION(y); + planner.buffer_line_kinematic(current_position, MMM_TO_MMS(XY_PROBE_SPEED), active_extruder); + #if MANUAL_PROBE_HEIGHT > 0 + line_to_z(prev_z); + #endif + lcd_synchronize(); + } + + #elif ENABLED(PROBE_MANUALLY) + + bool lcd_wait_for_move; + + // + // Bed leveling is done. Wait for G29 to complete. + // A flag is used so that this can release control + // and allow the command queue to be processed. + // + void _lcd_level_bed_done() { + if (!lcd_wait_for_move) _lcd_after_probing(); + if (lcdDrawUpdate) lcd_implementation_drawedit(PSTR(MSG_LEVEL_BED_DONE)); + lcdDrawUpdate = LCDVIEW_CALL_REDRAW_NEXT; + } + + #endif + + void _lcd_level_goto_next_point(); + + /** + * Step 7: Get the Z coordinate, click goes to the next point or exits + */ + void _lcd_level_bed_get_z() { + ENCODER_DIRECTION_NORMAL(); + + if (lcd_clicked) { + + // + // Save the current Z position + // + + #if ENABLED(MESH_BED_LEVELING) + + // + // MBL records the position but doesn't move to the next one + // + + mbl.set_zigzag_z(manual_probe_index, current_position[Z_AXIS]); + + #endif + + // If done... + if (++manual_probe_index >= total_probe_points) { + + #if ENABLED(PROBE_MANUALLY) + + // + // The last G29 will record and enable but not move. + // + lcd_wait_for_move = true; + enqueue_and_echo_commands_P(PSTR("G29 V1")); + lcd_goto_screen(_lcd_level_bed_done); + + #elif ENABLED(MESH_BED_LEVELING) + + _lcd_after_probing(); + + mbl.set_has_mesh(true); + mesh_probing_done(); + + #endif + + } + else { + // MESH_BED_LEVELING: Z already stored, just move + // PROBE_MANUALLY: Send G29 to record Z, then move + _lcd_level_goto_next_point(); + } + + return; + } + + // + // Encoder knob or keypad buttons adjust the Z position + // + if (encoderPosition) { + refresh_cmd_timeout(); + const float z = current_position[Z_AXIS] + float((int32_t)encoderPosition) * (MBL_Z_STEP); + line_to_z(constrain(z, -(LCD_PROBE_Z_RANGE) * 0.5, (LCD_PROBE_Z_RANGE) * 0.5)); + lcdDrawUpdate = LCDVIEW_CALL_REDRAW_NEXT; + encoderPosition = 0; + } + + // + // Draw on first display, then only on Z change + // + if (lcdDrawUpdate) { + const float v = current_position[Z_AXIS]; + lcd_implementation_drawedit(PSTR(MSG_MOVE_Z), ftostr43sign(v + (v < 0 ? -0.0001 : 0.0001), '+')); + } + } + + /** + * Step 6: Display "Next point: 1 / 9" while waiting for move to finish + */ + + void _lcd_level_bed_moving() { + if (lcdDrawUpdate) { + char msg[10]; + sprintf_P(msg, PSTR("%i / %u"), (int)(manual_probe_index + 1), total_probe_points); + lcd_implementation_drawedit(PSTR(MSG_LEVEL_BED_NEXT_POINT), msg); + } + lcdDrawUpdate = LCDVIEW_CALL_NO_REDRAW; + #if ENABLED(PROBE_MANUALLY) + if (!lcd_wait_for_move) lcd_goto_screen(_lcd_level_bed_get_z); + #endif + } + + /** + * Step 5: Initiate a move to the next point + */ + void _lcd_level_goto_next_point() { + + // Set the menu to display ahead of blocking call + lcd_goto_screen(_lcd_level_bed_moving); + + #if ENABLED(MESH_BED_LEVELING) + + int8_t px, py; + mbl.zigzag(manual_probe_index, px, py); + + // Controls the loop until the move is done + _manual_probe_goto_xy( + LOGICAL_X_POSITION(mbl.index_to_xpos[px]), + LOGICAL_Y_POSITION(mbl.index_to_ypos[py]) + ); + + // After the blocking function returns, change menus + lcd_goto_screen(_lcd_level_bed_get_z); + + #elif ENABLED(PROBE_MANUALLY) + + // G29 Records Z, moves, and signals when it pauses + lcd_wait_for_move = true; + enqueue_and_echo_commands_P(PSTR("G29 V1")); + + #endif + } + + /** + * Step 4: Display "Click to Begin", wait for click + * Move to the first probe position + */ + void _lcd_level_bed_homing_done() { + if (lcdDrawUpdate) lcd_implementation_drawedit(PSTR(MSG_LEVEL_BED_WAITING)); + if (lcd_clicked) { + manual_probe_index = 0; + _lcd_level_goto_next_point(); + } + } + + /** + * Step 3: Display "Homing XYZ" - Wait for homing to finish + */ + void _lcd_level_bed_homing() { + if (lcdDrawUpdate) lcd_implementation_drawedit(PSTR(MSG_LEVEL_BED_HOMING), NULL); + lcdDrawUpdate = LCDVIEW_CALL_NO_REDRAW; + if (axis_homed[X_AXIS] && axis_homed[Y_AXIS] && axis_homed[Z_AXIS]) + lcd_goto_screen(_lcd_level_bed_homing_done); + } + + #if ENABLED(PROBE_MANUALLY) + extern bool g29_in_progress; + #endif + + /** + * Step 2: Continue Bed Leveling... + */ + void _lcd_level_bed_continue() { + defer_return_to_status = true; + axis_homed[X_AXIS] = axis_homed[Y_AXIS] = axis_homed[Z_AXIS] = false; + lcd_goto_screen(_lcd_level_bed_homing); + enqueue_and_echo_commands_P(PSTR("G28")); + } + + static bool _level_state; + void _lcd_toggle_bed_leveling() { set_bed_leveling_enabled(_level_state); } + + #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) + void _lcd_set_z_fade_height() { set_z_fade_height(planner.z_fade_height); } + #endif + + /** + * Step 1: Bed Level entry-point + * + * << Prepare + * Auto Home (if homing needed) + * Leveling On/Off (if data exists, and homed) + * Fade Height: --- (Req: ENABLE_LEVELING_FADE_HEIGHT) + * Mesh Z Offset: --- (Req: MESH_BED_LEVELING) + * Z Probe Offset: --- (Req: HAS_BED_PROBE, Opt: BABYSTEP_ZPROBE_OFFSET) + * Level Bed > + * Level Corners > (if homed) + * Load Settings (Req: EEPROM_SETTINGS) + * Save Settings (Req: EEPROM_SETTINGS) + */ + void lcd_bed_leveling() { + START_MENU(); + MENU_BACK(MSG_PREPARE); + + if (!(axis_known_position[X_AXIS] && axis_known_position[Y_AXIS] && axis_known_position[Z_AXIS])) + MENU_ITEM(gcode, MSG_AUTO_HOME, PSTR("G28")); + else if (leveling_is_valid()) { + _level_state = leveling_is_active(); + MENU_ITEM_EDIT_CALLBACK(bool, MSG_BED_LEVELING, &_level_state, _lcd_toggle_bed_leveling); + } + + #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) + set_z_fade_height(planner.z_fade_height); + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float62, MSG_Z_FADE_HEIGHT, &planner.z_fade_height, 0.0, 100.0, _lcd_set_z_fade_height); + #endif + + // + // MBL Z Offset + // + #if ENABLED(MESH_BED_LEVELING) + MENU_ITEM_EDIT(float43, MSG_BED_Z, &mbl.z_offset, -1, 1); + #endif + + #if ENABLED(BABYSTEP_ZPROBE_OFFSET) + MENU_ITEM(submenu, MSG_ZPROBE_ZOFFSET, lcd_babystep_zoffset); + #elif HAS_BED_PROBE + MENU_ITEM_EDIT_CALLBACK(float32, MSG_ZPROBE_ZOFFSET, &zprobe_zoffset, Z_PROBE_OFFSET_RANGE_MIN, Z_PROBE_OFFSET_RANGE_MAX, lcd_refresh_zprobe_zoffset); + #endif + + MENU_ITEM(submenu, MSG_LEVEL_BED, _lcd_level_bed_continue); + + #if ENABLED(LEVEL_BED_CORNERS) + // Move to the next corner for leveling + if (axis_homed[X_AXIS] && axis_homed[Y_AXIS] && axis_homed[Z_AXIS]) + MENU_ITEM(function, MSG_LEVEL_CORNERS, _lcd_level_bed_corners); + #endif + + #if ENABLED(EEPROM_SETTINGS) + MENU_ITEM(function, MSG_LOAD_EEPROM, lcd_load_settings); + MENU_ITEM(function, MSG_STORE_EEPROM, lcd_store_settings); + #endif + END_MENU(); + } + + #elif ENABLED(AUTO_BED_LEVELING_UBL) + + void _lcd_ubl_level_bed(); + + static int16_t ubl_storage_slot = 0, + custom_hotend_temp = 190, + side_points = 3, + ubl_fillin_amount = 5, + ubl_height_amount = 1, + n_edit_pts = 1, + x_plot = 0, + y_plot = 0; + + #if HAS_TEMP_BED + static int16_t custom_bed_temp = 50; + #endif + + /** + * UBL Build Custom Mesh Command + */ + void _lcd_ubl_build_custom_mesh() { + char UBL_LCD_GCODE[20]; + enqueue_and_echo_commands_P(PSTR("G28")); + #if HAS_TEMP_BED + sprintf_P(UBL_LCD_GCODE, PSTR("M190 S%i"), custom_bed_temp); + enqueue_and_echo_command(UBL_LCD_GCODE); + #endif + sprintf_P(UBL_LCD_GCODE, PSTR("M109 S%i"), custom_hotend_temp); + enqueue_and_echo_command(UBL_LCD_GCODE); + enqueue_and_echo_commands_P(PSTR("G29 P1")); + } + + /** + * UBL Custom Mesh submenu + * + * << Build Mesh + * Hotend Temp: --- + * Bed Temp: --- + * Build Custom Mesh + */ + void _lcd_ubl_custom_mesh() { + START_MENU(); + MENU_BACK(MSG_UBL_BUILD_MESH_MENU); + MENU_ITEM_EDIT(int3, MSG_UBL_CUSTOM_HOTEND_TEMP, &custom_hotend_temp, EXTRUDE_MINTEMP, (HEATER_0_MAXTEMP - 10)); + #if HAS_TEMP_BED + MENU_ITEM_EDIT(int3, MSG_UBL_CUSTOM_BED_TEMP, &custom_bed_temp, BED_MINTEMP, (BED_MAXTEMP - 5)); + #endif + MENU_ITEM(function, MSG_UBL_BUILD_CUSTOM_MESH, _lcd_ubl_build_custom_mesh); + END_MENU(); + } + + /** + * UBL Adjust Mesh Height Command + */ + void _lcd_ubl_adjust_height_cmd() { + char UBL_LCD_GCODE[16]; + 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)); + enqueue_and_echo_command(UBL_LCD_GCODE); + } + + /** + * UBL Adjust Mesh Height submenu + * + * << Edit Mesh + * Height Amount: --- + * Adjust Mesh Height + * << Info Screen + */ + void _lcd_ubl_height_adjust_menu() { + START_MENU(); + MENU_BACK(MSG_UBL_EDIT_MESH_MENU); + MENU_ITEM_EDIT_CALLBACK(int3, MSG_UBL_MESH_HEIGHT_AMOUNT, &ubl_height_amount, -9, 9, _lcd_ubl_adjust_height_cmd); + MENU_ITEM(function, MSG_WATCH, lcd_return_to_status); + END_MENU(); + } + + /** + * UBL Edit Mesh submenu + * + * << UBL Tools + * Fine Tune All + * Fine Tune Closest + * - Adjust Mesh Height >> + * << Info Screen + */ + void _lcd_ubl_edit_mesh() { + START_MENU(); + MENU_BACK(MSG_UBL_TOOLS); + MENU_ITEM(gcode, MSG_UBL_FINE_TUNE_ALL, PSTR("G29 P4 R999 T")); + MENU_ITEM(gcode, MSG_UBL_FINE_TUNE_CLOSEST, PSTR("G29 P4 T")); + MENU_ITEM(submenu, MSG_UBL_MESH_HEIGHT_ADJUST, _lcd_ubl_height_adjust_menu); + MENU_ITEM(function, MSG_WATCH, lcd_return_to_status); + END_MENU(); + } + + /** + * UBL Validate Custom Mesh Command + */ + void _lcd_ubl_validate_custom_mesh() { + char UBL_LCD_GCODE[24]; + const int temp = + #if HAS_TEMP_BED + custom_bed_temp + #else + 0 + #endif + ; + sprintf_P(UBL_LCD_GCODE, PSTR("G28\nG26 C B%i H%i P"), temp, custom_hotend_temp); + enqueue_and_echo_command(UBL_LCD_GCODE); + } + + /** + * UBL Validate Mesh submenu + * + * << UBL Tools + * PLA Mesh Validation + * ABS Mesh Validation + * Validate Custom Mesh + * << Info Screen + */ + void _lcd_ubl_validate_mesh() { + START_MENU(); + MENU_BACK(MSG_UBL_TOOLS); + #if HAS_TEMP_BED + MENU_ITEM(gcode, MSG_UBL_VALIDATE_PLA_MESH, PSTR("G28\nG26 C B" STRINGIFY(PREHEAT_1_TEMP_BED) " H" STRINGIFY(PREHEAT_1_TEMP_HOTEND) " P")); + MENU_ITEM(gcode, MSG_UBL_VALIDATE_ABS_MESH, PSTR("G28\nG26 C B" STRINGIFY(PREHEAT_2_TEMP_BED) " H" STRINGIFY(PREHEAT_2_TEMP_HOTEND) " P")); + #else + MENU_ITEM(gcode, MSG_UBL_VALIDATE_PLA_MESH, PSTR("G28\nG26 C B0 H" STRINGIFY(PREHEAT_1_TEMP_HOTEND) " P")); + MENU_ITEM(gcode, MSG_UBL_VALIDATE_ABS_MESH, PSTR("G28\nG26 C B0 H" STRINGIFY(PREHEAT_2_TEMP_HOTEND) " P")); + #endif + MENU_ITEM(function, MSG_UBL_VALIDATE_CUSTOM_MESH, _lcd_ubl_validate_custom_mesh); + MENU_ITEM(function, MSG_WATCH, lcd_return_to_status); + END_MENU(); + } + + /** + * UBL Grid Leveling Command + */ + void _lcd_ubl_grid_level_cmd() { + char UBL_LCD_GCODE[10]; + sprintf_P(UBL_LCD_GCODE, PSTR("G29 J%i"), side_points); + enqueue_and_echo_command(UBL_LCD_GCODE); + } + + /** + * UBL Grid Leveling submenu + * + * << UBL Tools + * Side points: --- + * Level Mesh + */ + void _lcd_ubl_grid_level() { + START_MENU(); + MENU_BACK(MSG_UBL_TOOLS); + MENU_ITEM_EDIT(int3, MSG_UBL_SIDE_POINTS, &side_points, 2, 6); + MENU_ITEM(function, MSG_UBL_MESH_LEVEL, _lcd_ubl_grid_level_cmd); + END_MENU(); + } + + /** + * UBL Mesh Leveling submenu + * + * << UBL Tools + * 3-Point Mesh Leveling + * - Grid Mesh Leveling >> + * << Info Screen + */ + void _lcd_ubl_mesh_leveling() { + START_MENU(); + MENU_BACK(MSG_UBL_TOOLS); + MENU_ITEM(gcode, MSG_UBL_3POINT_MESH_LEVELING, PSTR("G29 J0")); + MENU_ITEM(submenu, MSG_UBL_GRID_MESH_LEVELING, _lcd_ubl_grid_level); + MENU_ITEM(function, MSG_WATCH, lcd_return_to_status); + END_MENU(); + } + + /** + * UBL Fill-in Amount Mesh Command + */ + void _lcd_ubl_fillin_amount_cmd() { + char UBL_LCD_GCODE[16]; + sprintf_P(UBL_LCD_GCODE, PSTR("G29 P3 R C.%i"), ubl_fillin_amount); + enqueue_and_echo_command(UBL_LCD_GCODE); + } + + /** + * UBL Smart Fill-in Command + */ + void _lcd_ubl_smart_fillin_cmd() { + char UBL_LCD_GCODE[12]; + sprintf_P(UBL_LCD_GCODE, PSTR("G29 P3 T0")); + enqueue_and_echo_command(UBL_LCD_GCODE); + } + + /** + * UBL Fill-in Mesh submenu + * + * << Build Mesh + * Fill-in Amount: --- + * Fill-in Mesh + * Smart Fill-in + * Manual Fill-in + * << Info Screen + */ + void _lcd_ubl_fillin_menu() { + START_MENU(); + MENU_BACK(MSG_UBL_BUILD_MESH_MENU); + MENU_ITEM_EDIT_CALLBACK(int3, MSG_UBL_FILLIN_AMOUNT, &ubl_fillin_amount, 0, 9, _lcd_ubl_fillin_amount_cmd); + MENU_ITEM(function, MSG_UBL_SMART_FILLIN, _lcd_ubl_smart_fillin_cmd); + MENU_ITEM(gcode, MSG_UBL_MANUAL_FILLIN, PSTR("G29 P2 B T0")); + MENU_ITEM(function, MSG_WATCH, lcd_return_to_status); + END_MENU(); + } + + void _lcd_ubl_invalidate() { + ubl.invalidate(); + SERIAL_PROTOCOLLNPGM("Mesh invalidated."); + } + + /** + * UBL Build Mesh submenu + * + * << UBL Tools + * Build PLA Mesh + * Build ABS Mesh + * - Build Custom Mesh >> + * Build Cold Mesh + * - Fill-in Mesh >> + * Continue Bed Mesh + * Invalidate All + * Invalidate Closest + * << Info Screen + */ + void _lcd_ubl_build_mesh() { + START_MENU(); + MENU_BACK(MSG_UBL_TOOLS); + #if HAS_TEMP_BED + MENU_ITEM(gcode, MSG_UBL_BUILD_PLA_MESH, 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" + )); + MENU_ITEM(gcode, MSG_UBL_BUILD_ABS_MESH, 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 + MENU_ITEM(gcode, MSG_UBL_BUILD_PLA_MESH, PSTR( + "G28\n" + "M109 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND) "\n" + "G29 P1\n" + "M104 S0" + )); + MENU_ITEM(gcode, MSG_UBL_BUILD_ABS_MESH, PSTR( + "G28\n" + "M109 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND) "\n" + "G29 P1\n" + "M104 S0" + )); + #endif + MENU_ITEM(submenu, MSG_UBL_BUILD_CUSTOM_MESH, _lcd_ubl_custom_mesh); + MENU_ITEM(gcode, MSG_UBL_BUILD_COLD_MESH, PSTR("G28\nG29 P1")); + MENU_ITEM(submenu, MSG_UBL_FILLIN_MESH, _lcd_ubl_fillin_menu); + MENU_ITEM(gcode, MSG_UBL_CONTINUE_MESH, PSTR("G29 P1 C")); + MENU_ITEM(function, MSG_UBL_INVALIDATE_ALL, _lcd_ubl_invalidate); + MENU_ITEM(gcode, MSG_UBL_INVALIDATE_CLOSEST, PSTR("G29 I")); + MENU_ITEM(function, MSG_WATCH, lcd_return_to_status); + END_MENU(); + } + + /** + * UBL Load Mesh Command + */ + void _lcd_ubl_load_mesh_cmd() { + char UBL_LCD_GCODE[25]; + sprintf_P(UBL_LCD_GCODE, PSTR("G29 L%i"), ubl_storage_slot); + enqueue_and_echo_command(UBL_LCD_GCODE); + sprintf_P(UBL_LCD_GCODE, PSTR("M117 " MSG_MESH_LOADED "."), ubl_storage_slot); + enqueue_and_echo_command(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); + enqueue_and_echo_command(UBL_LCD_GCODE); + sprintf_P(UBL_LCD_GCODE, PSTR("M117 " MSG_MESH_SAVED "."), ubl_storage_slot); + enqueue_and_echo_command(UBL_LCD_GCODE); + } + + /** + * UBL Mesh Storage submenu + * + * << Unified Bed Leveling + * Memory Slot: --- + * Load Bed Mesh + * Save Bed Mesh + */ + void _lcd_ubl_storage_mesh() { + int16_t a = settings.calc_num_meshes(); + START_MENU(); + MENU_BACK(MSG_UBL_LEVEL_BED); + if (!WITHIN(ubl_storage_slot, 0, a - 1)) { + STATIC_ITEM(MSG_NO_STORAGE); + STATIC_ITEM(MSG_INIT_EEPROM); + } + else { + MENU_ITEM_EDIT(int3, MSG_UBL_STORAGE_SLOT, &ubl_storage_slot, 0, a - 1); + MENU_ITEM(function, MSG_UBL_LOAD_MESH, _lcd_ubl_load_mesh_cmd); + MENU_ITEM(function, MSG_UBL_SAVE_MESH, _lcd_ubl_save_mesh_cmd); + } + END_MENU(); + } + + /** + * UBL LCD "radar" map homing + */ + void _lcd_ubl_output_map_lcd(); + + void _lcd_ubl_map_homing() { + defer_return_to_status = true; + ubl_lcd_map_control = true; // Return to the map screen + if (lcdDrawUpdate) lcd_implementation_drawmenu_static(LCD_HEIGHT < 3 ? 0 : (LCD_HEIGHT > 4 ? 2 : 1), PSTR(MSG_LEVEL_BED_HOMING)); + lcdDrawUpdate = LCDVIEW_CALL_NO_REDRAW; + if (axis_homed[X_AXIS] && axis_homed[Y_AXIS] && axis_homed[Z_AXIS]) + lcd_goto_screen(_lcd_ubl_output_map_lcd); + } + + /** + * UBL LCD "radar" map point editing + */ + void _lcd_ubl_map_lcd_edit_cmd() { + char ubl_lcd_gcode [50], str[10], str2[10]; + + dtostrf(pgm_read_float(&ubl._mesh_index_to_xpos[x_plot]), 0, 2, str); + dtostrf(pgm_read_float(&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, n_edit_pts); + enqueue_and_echo_command(ubl_lcd_gcode); + } + + /** + * UBL LCD Map Movement + */ + void ubl_map_move_to_xy() { + current_position[X_AXIS] = LOGICAL_X_POSITION(pgm_read_float(&ubl._mesh_index_to_xpos[x_plot])); + current_position[Y_AXIS] = LOGICAL_Y_POSITION(pgm_read_float(&ubl._mesh_index_to_ypos[y_plot])); + planner.buffer_line_kinematic(current_position, MMM_TO_MMS(XY_PROBE_SPEED), active_extruder); + } + + /** + * UBL LCD "radar" map + */ + void set_current_from_steppers_for_axis(const AxisEnum axis); + void sync_plan_position(); + + void _lcd_ubl_output_map_lcd() { + static int16_t step_scaler = 0; + + if (!(axis_known_position[X_AXIS] && axis_known_position[Y_AXIS] && axis_known_position[Z_AXIS])) + return lcd_goto_screen(_lcd_ubl_map_homing); + + if (lcd_clicked) return _lcd_ubl_map_lcd_edit_cmd(); + ENCODER_DIRECTION_NORMAL(); + + if (encoderPosition) { + step_scaler += (int32_t)encoderPosition; + x_plot += step_scaler / (ENCODER_STEPS_PER_MENU_ITEM); + if (abs(step_scaler) >= ENCODER_STEPS_PER_MENU_ITEM) + step_scaler = 0; + refresh_cmd_timeout(); + + encoderPosition = 0; + lcdDrawUpdate = LCDVIEW_REDRAW_NOW; + } + + // 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; + + // Encoder to the left (--) + if (x_plot <= GRID_MAX_POINTS_X - (GRID_MAX_POINTS_X + 1)) { x_plot = GRID_MAX_POINTS_X - 1; y_plot--; } + if (y_plot <= GRID_MAX_POINTS_Y - (GRID_MAX_POINTS_Y + 1)) y_plot = GRID_MAX_POINTS_Y - 1; + + // Prevent underrun/overrun of plot numbers + x_plot = constrain(x_plot, GRID_MAX_POINTS_X - (GRID_MAX_POINTS_X + 1), GRID_MAX_POINTS_X + 1); + y_plot = constrain(y_plot, GRID_MAX_POINTS_Y - (GRID_MAX_POINTS_Y + 1), GRID_MAX_POINTS_Y + 1); + + // 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 + + if (lcdDrawUpdate) { + lcd_implementation_ubl_plot(x_plot, y_plot); + + ubl_map_move_to_xy(); // Move to current location + + if (planner.movesplanned() > 1) { // if the nozzle is moving, cancel the move. There is a new location + stepper.quick_stop(); + set_current_from_steppers_for_axis(ALL_AXES); + sync_plan_position(); + ubl_map_move_to_xy(); // Move to new location + refresh_cmd_timeout(); + } + } + } + + /** + * UBL Homing before LCD map + */ + void _lcd_ubl_output_map_lcd_cmd() { + if (!(axis_known_position[X_AXIS] && axis_known_position[Y_AXIS] && axis_known_position[Z_AXIS])) { + axis_homed[X_AXIS] = axis_homed[Y_AXIS] = axis_homed[Z_AXIS] = false; + enqueue_and_echo_commands_P(PSTR("G28")); + } + lcd_goto_screen(_lcd_ubl_map_homing); + } + + /** + * UBL Output map submenu + * + * << Unified Bed Leveling + * Output for Host + * Output for CSV + * Off Printer Backup + * Output Mesh Map + */ + void _lcd_ubl_output_map() { + START_MENU(); + MENU_BACK(MSG_UBL_LEVEL_BED); + MENU_ITEM(gcode, MSG_UBL_OUTPUT_MAP_HOST, PSTR("G29 T0")); + MENU_ITEM(gcode, MSG_UBL_OUTPUT_MAP_CSV, PSTR("G29 T1")); + MENU_ITEM(gcode, MSG_UBL_OUTPUT_MAP_BACKUP, PSTR("G29 S-1")); + MENU_ITEM(function, MSG_UBL_OUTPUT_MAP, _lcd_ubl_output_map_lcd_cmd); + END_MENU(); + } + + /** + * UBL Tools submenu + * + * << Unified Bed Leveling + * - Build Mesh >> + * - Validate Mesh >> + * - Edit Mesh >> + * - Mesh Leveling >> + */ + void _lcd_ubl_tools_menu() { + START_MENU(); + MENU_BACK(MSG_UBL_LEVEL_BED); + MENU_ITEM(submenu, MSG_UBL_BUILD_MESH_MENU, _lcd_ubl_build_mesh); + MENU_ITEM(gcode, MSG_UBL_MANUAL_MESH, PSTR("G29 I999\nG29 P2 B T0")); + MENU_ITEM(submenu, MSG_UBL_VALIDATE_MESH_MENU, _lcd_ubl_validate_mesh); + MENU_ITEM(submenu, MSG_UBL_EDIT_MESH_MENU, _lcd_ubl_edit_mesh); + MENU_ITEM(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(); + MENU_BACK(MSG_UBL_LEVEL_BED); + MENU_ITEM(gcode, "1 " MSG_UBL_BUILD_COLD_MESH, PSTR("G28\nG29 P1")); + MENU_ITEM(function, "2 " MSG_UBL_SMART_FILLIN, _lcd_ubl_smart_fillin_cmd); + MENU_ITEM(submenu, "3 " MSG_UBL_VALIDATE_MESH_MENU, _lcd_ubl_validate_mesh); + MENU_ITEM(gcode, "4 " MSG_UBL_FINE_TUNE_ALL, PSTR("G29 P4 R999 T")); + MENU_ITEM(submenu, "5 " MSG_UBL_VALIDATE_MESH_MENU, _lcd_ubl_validate_mesh); + MENU_ITEM(gcode, "6 " MSG_UBL_FINE_TUNE_ALL, PSTR("G29 P4 R999 T")); + MENU_ITEM(function, "7 " MSG_UBL_SAVE_MESH, _lcd_ubl_save_mesh_cmd); + END_MENU(); + } + + /** + * UBL System submenu + * + * << Prepare + * - Manually Build Mesh >> + * - Activate UBL >> + * - Deactivate UBL >> + * - Step-By-Step UBL >> + * - Mesh Storage >> + * - Output Map >> + * - UBL Tools >> + * - Output UBL Info >> + */ + + void _lcd_ubl_level_bed() { + START_MENU(); + MENU_BACK(MSG_PREPARE); + MENU_ITEM(gcode, MSG_UBL_ACTIVATE_MESH, PSTR("G29 A")); + MENU_ITEM(gcode, MSG_UBL_DEACTIVATE_MESH, PSTR("G29 D")); + MENU_ITEM(submenu, MSG_UBL_STEP_BY_STEP_MENU, _lcd_ubl_step_by_step); + MENU_ITEM(function, MSG_UBL_MESH_EDIT, _lcd_ubl_output_map_lcd_cmd); + MENU_ITEM(submenu, MSG_UBL_STORAGE_MESH_MENU, _lcd_ubl_storage_mesh); + MENU_ITEM(submenu, MSG_UBL_OUTPUT_MAP, _lcd_ubl_output_map); + MENU_ITEM(submenu, MSG_UBL_TOOLS, _lcd_ubl_tools_menu); + MENU_ITEM(gcode, MSG_UBL_INFO_UBL, PSTR("G29 W")); + END_MENU(); + } + + #endif // AUTO_BED_LEVELING_UBL + + /** + * + * "Prepare" submenu + * + */ + + void lcd_prepare_menu() { + START_MENU(); + + // + // ^ Main + // + MENU_BACK(MSG_MAIN); + + // + // Move Axis + // + #if ENABLED(DELTA) + if (axis_homed[Z_AXIS]) + #endif + MENU_ITEM(submenu, MSG_MOVE_AXIS, lcd_move_menu); + + // + // Auto Home + // + MENU_ITEM(gcode, MSG_AUTO_HOME, PSTR("G28")); + #if ENABLED(INDIVIDUAL_AXIS_HOMING_MENU) + MENU_ITEM(gcode, MSG_AUTO_HOME_X, PSTR("G28 X")); + MENU_ITEM(gcode, MSG_AUTO_HOME_Y, PSTR("G28 Y")); + MENU_ITEM(gcode, MSG_AUTO_HOME_Z, PSTR("G28 Z")); + #endif + + // + // Level Bed + // + #if ENABLED(AUTO_BED_LEVELING_UBL) + MENU_ITEM(submenu, MSG_UBL_LEVEL_BED, _lcd_ubl_level_bed); + #elif ENABLED(LCD_BED_LEVELING) + #if ENABLED(PROBE_MANUALLY) + if (!g29_in_progress) + #endif + MENU_ITEM(submenu, MSG_BED_LEVELING, lcd_bed_leveling); + #else + #if PLANNER_LEVELING + MENU_ITEM(gcode, MSG_BED_LEVELING, PSTR("G28\nG29")); + #endif + #if ENABLED(LEVEL_BED_CORNERS) + if (axis_homed[X_AXIS] && axis_homed[Y_AXIS] && axis_homed[Z_AXIS]) + MENU_ITEM(function, MSG_LEVEL_CORNERS, _lcd_level_bed_corners); + #endif + #endif + + #if HAS_M206_COMMAND + // + // Set Home Offsets + // + MENU_ITEM(function, MSG_SET_HOME_OFFSETS, lcd_set_home_offsets); + //MENU_ITEM(gcode, MSG_SET_ORIGIN, PSTR("G92 X0 Y0 Z0")); + #endif + + // + // Disable Steppers + // + MENU_ITEM(gcode, MSG_DISABLE_STEPPERS, PSTR("M84")); + + // + // Change filament + // + #if ENABLED(ADVANCED_PAUSE_FEATURE) + if (!thermalManager.tooColdToExtrude(active_extruder) && !IS_SD_FILE_OPEN) + MENU_ITEM(function, MSG_FILAMENTCHANGE, lcd_enqueue_filament_change); + #endif + + #if TEMP_SENSOR_0 != 0 + + // + // Cooldown + // + bool has_heat = false; + HOTEND_LOOP() if (thermalManager.target_temperature[HOTEND_INDEX]) { has_heat = true; break; } + #if HAS_TEMP_BED + if (thermalManager.target_temperature_bed) has_heat = true; + #endif + if (has_heat) MENU_ITEM(function, MSG_COOLDOWN, lcd_cooldown); + + // + // Preheat for Material 1 and 2 + // + #if TEMP_SENSOR_1 != 0 || TEMP_SENSOR_2 != 0 || TEMP_SENSOR_3 != 0 || TEMP_SENSOR_4 != 0 || TEMP_SENSOR_BED != 0 + MENU_ITEM(submenu, MSG_PREHEAT_1, lcd_preheat_m1_menu); + MENU_ITEM(submenu, MSG_PREHEAT_2, lcd_preheat_m2_menu); + #else + MENU_ITEM(function, MSG_PREHEAT_1, lcd_preheat_m1_e0_only); + MENU_ITEM(function, MSG_PREHEAT_2, lcd_preheat_m2_e0_only); + #endif + + #endif // TEMP_SENSOR_0 != 0 + + // + // BLTouch Self-Test and Reset + // + #if ENABLED(BLTOUCH) + MENU_ITEM(gcode, MSG_BLTOUCH_SELFTEST, PSTR("M280 P" STRINGIFY(Z_ENDSTOP_SERVO_NR) " S" STRINGIFY(BLTOUCH_SELFTEST))); + if (!endstops.z_probe_enabled && TEST_BLTOUCH()) + MENU_ITEM(gcode, MSG_BLTOUCH_RESET, PSTR("M280 P" STRINGIFY(Z_ENDSTOP_SERVO_NR) " S" STRINGIFY(BLTOUCH_RESET))); + #endif + + // + // Switch power on/off + // + #if HAS_POWER_SWITCH + if (powersupply_on) + MENU_ITEM(gcode, MSG_SWITCH_PS_OFF, PSTR("M81")); + else + MENU_ITEM(gcode, MSG_SWITCH_PS_ON, PSTR("M80")); + #endif + + // + // Autostart + // + #if ENABLED(SDSUPPORT) && ENABLED(MENU_ADDAUTOSTART) + MENU_ITEM(function, MSG_AUTOSTART, lcd_autostart_sd); + #endif + + // + // Delta Calibration + // + #if ENABLED(DELTA_CALIBRATION_MENU) + MENU_ITEM(submenu, MSG_DELTA_CALIBRATE, lcd_delta_calibrate_menu); + #endif + + END_MENU(); + } + + float move_menu_scale; + + #if ENABLED(DELTA_CALIBRATION_MENU) + + void lcd_move_z(); + void lcd_delta_calibrate_menu(); + + void _lcd_calibrate_homing() { + if (lcdDrawUpdate) lcd_implementation_drawmenu_static(LCD_HEIGHT >= 4 ? 1 : 0, PSTR(MSG_LEVEL_BED_HOMING)); + lcdDrawUpdate = LCDVIEW_CALL_REDRAW_NEXT; + if (axis_homed[X_AXIS] && axis_homed[Y_AXIS] && axis_homed[Z_AXIS]) + lcd_goto_previous_menu(); + } + + void _lcd_delta_calibrate_home() { + #if HAS_LEVELING + reset_bed_level(); // After calibration bed-level data is no longer valid + #endif + + enqueue_and_echo_commands_P(PSTR("G28")); + lcd_goto_screen(_lcd_calibrate_homing); + } + + void _man_probe_pt(const float &lx, const float &ly) { + #if HAS_LEVELING + reset_bed_level(); // After calibration bed-level data is no longer valid + #endif + + float z_dest = LOGICAL_Z_POSITION((Z_CLEARANCE_BETWEEN_PROBES) + (DELTA_PRINTABLE_RADIUS) / 5); + line_to_z(z_dest); + current_position[X_AXIS] = LOGICAL_X_POSITION(lx); + current_position[Y_AXIS] = LOGICAL_Y_POSITION(ly); + line_to_current_z(); + z_dest = LOGICAL_Z_POSITION(Z_CLEARANCE_BETWEEN_PROBES); + line_to_z(z_dest); + + lcd_synchronize(); + move_menu_scale = PROBE_MANUALLY_STEP; + lcd_goto_screen(lcd_move_z); + } + + float lcd_probe_pt(const float &lx, const float &ly) { + _man_probe_pt(lx, ly); + KEEPALIVE_STATE(PAUSED_FOR_USER); + defer_return_to_status = true; + wait_for_user = true; + while (wait_for_user) idle(); + KEEPALIVE_STATE(IN_HANDLER); + lcd_goto_previous_menu_no_defer(); + return current_position[Z_AXIS]; + } + + void _goto_tower_x() { _man_probe_pt(cos(RADIANS(210)) * delta_calibration_radius, sin(RADIANS(210)) * delta_calibration_radius); } + void _goto_tower_y() { _man_probe_pt(cos(RADIANS(330)) * delta_calibration_radius, sin(RADIANS(330)) * delta_calibration_radius); } + void _goto_tower_z() { _man_probe_pt(cos(RADIANS( 90)) * delta_calibration_radius, sin(RADIANS( 90)) * delta_calibration_radius); } + void _goto_center() { _man_probe_pt(0,0); } + + static float _delta_height = DELTA_HEIGHT; + void _lcd_set_delta_height() { + home_offset[Z_AXIS] = _delta_height - DELTA_HEIGHT; + update_software_endstops(Z_AXIS); + } + + void lcd_delta_settings() { + START_MENU(); + MENU_BACK(MSG_DELTA_CALIBRATE); + float Tz = 0.00; + MENU_ITEM_EDIT(float52, MSG_DELTA_DIAG_ROG, &delta_diagonal_rod, DELTA_DIAGONAL_ROD - 5.0, DELTA_DIAGONAL_ROD + 5.0); + _delta_height = DELTA_HEIGHT + home_offset[Z_AXIS]; + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float52, MSG_DELTA_HEIGHT, &_delta_height, _delta_height - 10.0, _delta_height + 10.0, _lcd_set_delta_height); + MENU_ITEM_EDIT(float43, "Ex", &endstop_adj[A_AXIS], -5.0, 5.0); + MENU_ITEM_EDIT(float43, "Ey", &endstop_adj[B_AXIS], -5.0, 5.0); + MENU_ITEM_EDIT(float43, "Ez", &endstop_adj[C_AXIS], -5.0, 5.0); + MENU_ITEM_EDIT(float52, MSG_DELTA_RADIUS, &delta_radius, DELTA_RADIUS - 5.0, DELTA_RADIUS + 5.0); + MENU_ITEM_EDIT(float43, "Tx", &delta_tower_angle_trim[A_AXIS], -5.0, 5.0); + MENU_ITEM_EDIT(float43, "Ty", &delta_tower_angle_trim[B_AXIS], -5.0, 5.0); + MENU_ITEM_EDIT(float43, "Tz", &delta_tower_angle_trim[C_AXIS], -5.0, 5.0); + END_MENU(); + } + + void lcd_delta_calibrate_menu() { + START_MENU(); + MENU_BACK(MSG_MAIN); + #if ENABLED(DELTA_AUTO_CALIBRATION) + MENU_ITEM(submenu, MSG_DELTA_SETTINGS, lcd_delta_settings); + MENU_ITEM(gcode, MSG_DELTA_AUTO_CALIBRATE, PSTR("G33")); + MENU_ITEM(gcode, MSG_DELTA_HEIGHT_CALIBRATE, PSTR("G33 P1")); + #if ENABLED(EEPROM_SETTINGS) + MENU_ITEM(function, MSG_STORE_EEPROM, lcd_store_settings); + MENU_ITEM(function, MSG_LOAD_EEPROM, lcd_load_settings); + #endif + #endif + MENU_ITEM(submenu, MSG_AUTO_HOME, _lcd_delta_calibrate_home); + if (axis_homed[Z_AXIS]) { + MENU_ITEM(submenu, MSG_DELTA_CALIBRATE_X, _goto_tower_x); + MENU_ITEM(submenu, MSG_DELTA_CALIBRATE_Y, _goto_tower_y); + MENU_ITEM(submenu, MSG_DELTA_CALIBRATE_Z, _goto_tower_z); + MENU_ITEM(submenu, MSG_DELTA_CALIBRATE_CENTER, _goto_center); + } + END_MENU(); + } + + #endif // DELTA_CALIBRATION_MENU + + #if IS_KINEMATIC + extern float feedrate_mm_s; + extern float destination[XYZE]; + void set_destination_to_current(); + void prepare_move_to_destination(); + #endif + + /** + * If the most recent manual move hasn't been fed to the planner yet, + * and the planner can accept one, send immediately + */ + inline void manage_manual_move() { + + if (processing_manual_move) return; + + if (manual_move_axis != (int8_t)NO_AXIS && ELAPSED(millis(), manual_move_start_time) && !planner.is_full()) { + + #if IS_KINEMATIC + + const float old_feedrate = feedrate_mm_s; + feedrate_mm_s = MMM_TO_MMS(manual_feedrate_mm_m[manual_move_axis]); + + #if EXTRUDERS > 1 + const int8_t old_extruder = active_extruder; + active_extruder = manual_move_e_index; + #endif + + // Set movement on a single axis + set_destination_to_current(); + destination[manual_move_axis] += manual_move_offset; + + // Reset for the next move + manual_move_offset = 0.0; + manual_move_axis = (int8_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; + prepare_move_to_destination(); // will call set_current_to_destination + processing_manual_move = false; + + feedrate_mm_s = old_feedrate; + #if EXTRUDERS > 1 + active_extruder = old_extruder; + #endif + + #else + + planner.buffer_line_kinematic(current_position, MMM_TO_MMS(manual_feedrate_mm_m[manual_move_axis]), manual_move_e_index); + manual_move_axis = (int8_t)NO_AXIS; + + #endif + } + } + + /** + * Set a flag that lcd_update() should start a move + * to "current_position" after a short delay. + */ + inline void manual_move_to_current(AxisEnum axis + #if E_MANUAL > 1 + , int8_t eindex=-1 + #endif + ) { + #if ENABLED(DUAL_X_CARRIAGE) || E_MANUAL > 1 + #if E_MANUAL > 1 + if (axis == E_AXIS) + #endif + manual_move_e_index = eindex >= 0 ? eindex : active_extruder; + #endif + manual_move_start_time = millis() + (move_menu_scale < 0.99 ? 0UL : 250UL); // delay for bigger moves + manual_move_axis = (int8_t)axis; + } + + /** + * + * "Prepare" > "Move Axis" submenu + * + */ + + void _lcd_move_xyz(const char* name, AxisEnum axis) { + if (lcd_clicked) { return lcd_goto_previous_menu(); } + ENCODER_DIRECTION_NORMAL(); + if (encoderPosition && !processing_manual_move) { + refresh_cmd_timeout(); + + // Start with no limits to movement + float min = current_position[axis] - 1000, + max = current_position[axis] + 1000; + + #if HAS_SOFTWARE_ENDSTOPS + // Limit to software endstops, if enabled + if (soft_endstops_enabled) { + #if ENABLED(MIN_SOFTWARE_ENDSTOPS) + min = soft_endstop_min[axis]; + #endif + #if ENABLED(MAX_SOFTWARE_ENDSTOPS) + max = soft_endstop_max[axis]; + #endif + } + #endif + + // 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 + min = -max; + } + #endif + + // Get the new position + const float diff = float((int32_t)encoderPosition) * move_menu_scale; + #if IS_KINEMATIC + manual_move_offset += diff; + // Limit only when trying to move towards the limit + if ((int32_t)encoderPosition < 0) NOLESS(manual_move_offset, min - current_position[axis]); + if ((int32_t)encoderPosition > 0) NOMORE(manual_move_offset, max - current_position[axis]); + #else + current_position[axis] += diff; + // Limit only when trying to move towards the limit + if ((int32_t)encoderPosition < 0) NOLESS(current_position[axis], min); + if ((int32_t)encoderPosition > 0) NOMORE(current_position[axis], max); + #endif + + encoderPosition = 0; + + manual_move_to_current(axis); + + lcdDrawUpdate = LCDVIEW_REDRAW_NOW; + } + if (lcdDrawUpdate) { + const float pos = current_position[axis] + #if IS_KINEMATIC + + manual_move_offset + #endif + ; + lcd_implementation_drawedit(name, move_menu_scale >= 0.1 ? ftostr41sign(pos) : ftostr43sign(pos)); + } + } + void lcd_move_x() { _lcd_move_xyz(PSTR(MSG_MOVE_X), X_AXIS); } + void lcd_move_y() { _lcd_move_xyz(PSTR(MSG_MOVE_Y), Y_AXIS); } + void lcd_move_z() { _lcd_move_xyz(PSTR(MSG_MOVE_Z), Z_AXIS); } + void _lcd_move_e( + #if E_MANUAL > 1 + int8_t eindex=-1 + #endif + ) { + if (lcd_clicked) { return lcd_goto_previous_menu(); } + ENCODER_DIRECTION_NORMAL(); + if (encoderPosition) { + if (!processing_manual_move) { + const float diff = float((int32_t)encoderPosition) * move_menu_scale; + #if IS_KINEMATIC + manual_move_offset += diff; + #else + current_position[E_AXIS] += diff; + #endif + manual_move_to_current(E_AXIS + #if E_MANUAL > 1 + , eindex + #endif + ); + lcdDrawUpdate = LCDVIEW_REDRAW_NOW; + } + encoderPosition = 0; + } + if (lcdDrawUpdate && !processing_manual_move) { + PGM_P pos_label; + #if E_MANUAL == 1 + pos_label = PSTR(MSG_MOVE_E); + #else + switch (eindex) { + default: pos_label = PSTR(MSG_MOVE_E MSG_MOVE_E1); break; + case 1: pos_label = PSTR(MSG_MOVE_E MSG_MOVE_E2); break; + #if E_MANUAL > 2 + case 2: pos_label = PSTR(MSG_MOVE_E MSG_MOVE_E3); break; + #if E_MANUAL > 3 + case 3: pos_label = PSTR(MSG_MOVE_E MSG_MOVE_E4); break; + #if E_MANUAL > 4 + case 4: pos_label = PSTR(MSG_MOVE_E MSG_MOVE_E5); break; + #endif // E_MANUAL > 4 + #endif // E_MANUAL > 3 + #endif // E_MANUAL > 2 + } + #endif // E_MANUAL > 1 + lcd_implementation_drawedit(pos_label, ftostr41sign(current_position[E_AXIS] + #if IS_KINEMATIC + + manual_move_offset + #endif + )); + } + } + + void lcd_move_e() { _lcd_move_e(); } + #if E_MANUAL > 1 + void lcd_move_e0() { _lcd_move_e(0); } + void lcd_move_e1() { _lcd_move_e(1); } + #if E_MANUAL > 2 + void lcd_move_e2() { _lcd_move_e(2); } + #if E_MANUAL > 3 + void lcd_move_e3() { _lcd_move_e(3); } + #if E_MANUAL > 4 + void lcd_move_e4() { _lcd_move_e(4); } + #endif // E_MANUAL > 4 + #endif // E_MANUAL > 3 + #endif // E_MANUAL > 2 + #endif // E_MANUAL > 1 + + /** + * + * "Prepare" > "Move Xmm" > "Move XYZ" submenu + * + */ + + screenFunc_t _manual_move_func_ptr; + + void _goto_manual_move(const float scale) { + defer_return_to_status = true; + move_menu_scale = scale; + lcd_goto_screen(_manual_move_func_ptr); + } + void lcd_move_menu_10mm() { _goto_manual_move(10.0); } + void lcd_move_menu_1mm() { _goto_manual_move( 1.0); } + void lcd_move_menu_01mm() { _goto_manual_move( 0.1); } + + void _lcd_move_distance_menu(const AxisEnum axis, const screenFunc_t func) { + _manual_move_func_ptr = func; + START_MENU(); + if (LCD_HEIGHT >= 4) { + switch(axis) { + case X_AXIS: + STATIC_ITEM(MSG_MOVE_X, true, true); break; + case Y_AXIS: + STATIC_ITEM(MSG_MOVE_Y, true, true); break; + case Z_AXIS: + STATIC_ITEM(MSG_MOVE_Z, true, true); break; + default: + STATIC_ITEM(MSG_MOVE_E, true, true); break; + } + } + MENU_BACK(MSG_MOVE_AXIS); + MENU_ITEM(submenu, MSG_MOVE_10MM, lcd_move_menu_10mm); + MENU_ITEM(submenu, MSG_MOVE_1MM, lcd_move_menu_1mm); + MENU_ITEM(submenu, MSG_MOVE_01MM, lcd_move_menu_01mm); + END_MENU(); + } + void lcd_move_get_x_amount() { _lcd_move_distance_menu(X_AXIS, lcd_move_x); } + void lcd_move_get_y_amount() { _lcd_move_distance_menu(Y_AXIS, lcd_move_y); } + void lcd_move_get_z_amount() { _lcd_move_distance_menu(Z_AXIS, lcd_move_z); } + void lcd_move_get_e_amount() { _lcd_move_distance_menu(E_AXIS, lcd_move_e); } + #if E_MANUAL > 1 + void lcd_move_get_e0_amount() { _lcd_move_distance_menu(E_AXIS, lcd_move_e0); } + void lcd_move_get_e1_amount() { _lcd_move_distance_menu(E_AXIS, lcd_move_e1); } + #if E_MANUAL > 2 + void lcd_move_get_e2_amount() { _lcd_move_distance_menu(E_AXIS, lcd_move_e2); } + #if E_MANUAL > 3 + void lcd_move_get_e3_amount() { _lcd_move_distance_menu(E_AXIS, lcd_move_e3); } + #if E_MANUAL > 4 + void lcd_move_get_e4_amount() { _lcd_move_distance_menu(E_AXIS, lcd_move_e4); } + #endif // E_MANUAL > 4 + #endif // E_MANUAL > 3 + #endif // E_MANUAL > 2 + #endif // E_MANUAL > 1 + + /** + * + * "Prepare" > "Move Axis" submenu + * + */ + + #if IS_KINEMATIC || ENABLED(NO_MOTION_BEFORE_HOMING) + #define _MOVE_XYZ_ALLOWED (axis_homed[X_AXIS] && axis_homed[Y_AXIS] && axis_homed[Z_AXIS]) + #else + #define _MOVE_XYZ_ALLOWED true + #endif + + #if ENABLED(DELTA) + #define _MOVE_XY_ALLOWED (current_position[Z_AXIS] <= delta_clip_start_height) + void lcd_lower_z_to_clip_height() { + line_to_z(delta_clip_start_height); + lcd_synchronize(); + } + #else + #define _MOVE_XY_ALLOWED true + #endif + + void lcd_move_menu() { + START_MENU(); + MENU_BACK(MSG_PREPARE); + + if (_MOVE_XYZ_ALLOWED) { + if (_MOVE_XY_ALLOWED) { + MENU_ITEM(submenu, MSG_MOVE_X, lcd_move_get_x_amount); + MENU_ITEM(submenu, MSG_MOVE_Y, lcd_move_get_y_amount); + } + #if ENABLED(DELTA) + else + MENU_ITEM(function, MSG_FREE_XY, lcd_lower_z_to_clip_height); + #endif + + MENU_ITEM(submenu, MSG_MOVE_Z, lcd_move_get_z_amount); + } + else + MENU_ITEM(gcode, MSG_AUTO_HOME, PSTR("G28")); + + #if ENABLED(SWITCHING_EXTRUDER) || ENABLED(DUAL_X_CARRIAGE) + if (active_extruder) + MENU_ITEM(gcode, MSG_SELECT " " MSG_E1, PSTR("T0")); + else + MENU_ITEM(gcode, MSG_SELECT " " MSG_E2, PSTR("T1")); + #endif + + MENU_ITEM(submenu, MSG_MOVE_E, lcd_move_get_e_amount); + #if E_MANUAL > 1 + MENU_ITEM(submenu, MSG_MOVE_E MSG_MOVE_E1, lcd_move_get_e0_amount); + MENU_ITEM(submenu, MSG_MOVE_E MSG_MOVE_E2, lcd_move_get_e1_amount); + #if E_MANUAL > 2 + MENU_ITEM(submenu, MSG_MOVE_E MSG_MOVE_E3, lcd_move_get_e2_amount); + #if E_MANUAL > 3 + MENU_ITEM(submenu, MSG_MOVE_E MSG_MOVE_E4, lcd_move_get_e3_amount); + #if E_MANUAL > 4 + MENU_ITEM(submenu, MSG_MOVE_E MSG_MOVE_E5, lcd_move_get_e4_amount); + #endif // E_MANUAL > 4 + #endif // E_MANUAL > 3 + #endif // E_MANUAL > 2 + #endif // E_MANUAL > 1 + + END_MENU(); + } + + /** + * + * "Control" submenu + * + */ + + #if HAS_LCD_CONTRAST + void lcd_callback_set_contrast() { set_lcd_contrast(lcd_contrast); } + #endif + + static void lcd_factory_settings() { + settings.reset(); + lcd_completion_feedback(); + } + + #if ENABLED(EEPROM_SETTINGS) + + static void lcd_init_eeprom() { + lcd_factory_settings(); + settings.save(); + lcd_goto_previous_menu(); + } + + static void lcd_init_eeprom_confirm() { + START_MENU(); + MENU_BACK(MSG_CONTROL); + MENU_ITEM(function, MSG_INIT_EEPROM, lcd_init_eeprom); + END_MENU(); + } + + #endif + + void lcd_control_menu() { + START_MENU(); + MENU_BACK(MSG_MAIN); + MENU_ITEM(submenu, MSG_TEMPERATURE, lcd_control_temperature_menu); + MENU_ITEM(submenu, MSG_MOTION, lcd_control_motion_menu); + MENU_ITEM(submenu, MSG_FILAMENT, lcd_control_filament_menu); + + #if HAS_LCD_CONTRAST + MENU_ITEM_EDIT_CALLBACK(int3, MSG_CONTRAST, (int*)&lcd_contrast, LCD_CONTRAST_MIN, LCD_CONTRAST_MAX, lcd_callback_set_contrast, true); + #endif + #if ENABLED(FWRETRACT) + MENU_ITEM(submenu, MSG_RETRACT, lcd_control_retract_menu); + #endif + #if ENABLED(DAC_STEPPER_CURRENT) + MENU_ITEM(submenu, MSG_DRIVE_STRENGTH, lcd_dac_menu); + #endif + #if HAS_MOTOR_CURRENT_PWM + MENU_ITEM(submenu, MSG_DRIVE_STRENGTH, lcd_pwm_menu); + #endif + + #if ENABLED(BLTOUCH) + MENU_ITEM(submenu, MSG_BLTOUCH, bltouch_menu); + #endif + + #if ENABLED(EEPROM_SETTINGS) + MENU_ITEM(function, MSG_STORE_EEPROM, lcd_store_settings); + MENU_ITEM(function, MSG_LOAD_EEPROM, lcd_load_settings); + #endif + MENU_ITEM(function, MSG_RESTORE_FAILSAFE, lcd_factory_settings); + #if ENABLED(EEPROM_SETTINGS) + MENU_ITEM(submenu, MSG_INIT_EEPROM, lcd_init_eeprom_confirm); + #endif + + END_MENU(); + } + + /** + * + * "Temperature" submenu + * + */ + + #if ENABLED(PID_AUTOTUNE_MENU) + + #if ENABLED(PIDTEMP) + int16_t autotune_temp[HOTENDS] = ARRAY_BY_HOTENDS1(150); + #endif + + #if ENABLED(PIDTEMPBED) + int16_t autotune_temp_bed = 70; + #endif + + void _lcd_autotune(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] + #endif + ); + enqueue_and_echo_command(cmd); + } + + #endif // PID_AUTOTUNE_MENU + + #if ENABLED(PIDTEMP) + + // 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 + 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 + PID_PARAM(Kd, e) = scalePID_d(raw_Kd); + thermalManager.updatePID(); + } + #define _DEFINE_PIDTEMP_BASE_FUNCS(N) \ + void copy_and_scalePID_i_E ## N() { copy_and_scalePID_i(N); } \ + void copy_and_scalePID_d_E ## N() { copy_and_scalePID_d(N); } + + #if ENABLED(PID_AUTOTUNE_MENU) + #define DEFINE_PIDTEMP_FUNCS(N) \ + _DEFINE_PIDTEMP_BASE_FUNCS(N); \ + void lcd_autotune_callback_E ## N() { _lcd_autotune(N); } typedef void _pid_##N##_void + #else + #define DEFINE_PIDTEMP_FUNCS(N) _DEFINE_PIDTEMP_BASE_FUNCS(N) typedef void _pid_##N##_void + #endif + + DEFINE_PIDTEMP_FUNCS(0); + #if ENABLED(PID_PARAMS_PER_HOTEND) + #if HOTENDS > 1 + DEFINE_PIDTEMP_FUNCS(1); + #if HOTENDS > 2 + DEFINE_PIDTEMP_FUNCS(2); + #if HOTENDS > 3 + DEFINE_PIDTEMP_FUNCS(3); + #if HOTENDS > 4 + DEFINE_PIDTEMP_FUNCS(4); + #endif // HOTENDS > 4 + #endif // HOTENDS > 3 + #endif // HOTENDS > 2 + #endif // HOTENDS > 1 + #endif // PID_PARAMS_PER_HOTEND + + #endif // PIDTEMP + + /** + * + * "Control" > "Temperature" submenu + * + */ + void lcd_control_temperature_menu() { + START_MENU(); + + // + // ^ Control + // + MENU_BACK(MSG_CONTROL); + + // + // Nozzle: + // Nozzle [1-5]: + // + #if HOTENDS == 1 + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(int3, MSG_NOZZLE, &thermalManager.target_temperature[0], 0, HEATER_0_MAXTEMP - 15, watch_temp_callback_E0); + #else // HOTENDS > 1 + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(int3, MSG_NOZZLE MSG_N1, &thermalManager.target_temperature[0], 0, HEATER_0_MAXTEMP - 15, watch_temp_callback_E0); + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(int3, MSG_NOZZLE MSG_N2, &thermalManager.target_temperature[1], 0, HEATER_1_MAXTEMP - 15, watch_temp_callback_E1); + #if HOTENDS > 2 + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(int3, MSG_NOZZLE MSG_N3, &thermalManager.target_temperature[2], 0, HEATER_2_MAXTEMP - 15, watch_temp_callback_E2); + #if HOTENDS > 3 + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(int3, MSG_NOZZLE MSG_N4, &thermalManager.target_temperature[3], 0, HEATER_3_MAXTEMP - 15, watch_temp_callback_E3); + #if HOTENDS > 4 + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(int3, MSG_NOZZLE MSG_N5, &thermalManager.target_temperature[4], 0, HEATER_4_MAXTEMP - 15, watch_temp_callback_E4); + #endif // HOTENDS > 4 + #endif // HOTENDS > 3 + #endif // HOTENDS > 2 + #endif // HOTENDS > 1 + + // + // Bed: + // + #if HAS_TEMP_BED + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(int3, MSG_BED, &thermalManager.target_temperature_bed, 0, BED_MAXTEMP - 15, watch_temp_callback_bed); + #endif + + // + // Fan Speed: + // + #if FAN_COUNT > 0 + #if HAS_FAN0 + #if FAN_COUNT > 1 + #define MSG_1ST_FAN_SPEED MSG_FAN_SPEED " 1" + #else + #define MSG_1ST_FAN_SPEED MSG_FAN_SPEED + #endif + MENU_MULTIPLIER_ITEM_EDIT(int3, MSG_1ST_FAN_SPEED, &fanSpeeds[0], 0, 255); + #endif + #if HAS_FAN1 + MENU_MULTIPLIER_ITEM_EDIT(int3, MSG_FAN_SPEED " 2", &fanSpeeds[1], 0, 255); + #endif + #if HAS_FAN2 + MENU_MULTIPLIER_ITEM_EDIT(int3, MSG_FAN_SPEED " 3", &fanSpeeds[2], 0, 255); + #endif + #endif // FAN_COUNT > 0 + + // + // Autotemp, Min, Max, Fact + // + #if ENABLED(AUTOTEMP) && (TEMP_SENSOR_0 != 0) + MENU_ITEM_EDIT(bool, MSG_AUTOTEMP, &planner.autotemp_enabled); + MENU_ITEM_EDIT(float3, MSG_MIN, &planner.autotemp_min, 0, HEATER_0_MAXTEMP - 15); + MENU_ITEM_EDIT(float3, MSG_MAX, &planner.autotemp_max, 0, HEATER_0_MAXTEMP - 15); + MENU_ITEM_EDIT(float32, MSG_FACTOR, &planner.autotemp_factor, 0.0, 1.0); + #endif + + // + // PID-P, PID-I, PID-D, PID-C, PID Autotune + // PID-P E1, PID-I E1, PID-D E1, PID-C E1, PID Autotune E1 + // PID-P E2, PID-I E2, PID-D E2, PID-C E2, PID Autotune E2 + // PID-P E3, PID-I E3, PID-D E3, PID-C E3, PID Autotune E3 + // PID-P E4, PID-I E4, PID-D E4, PID-C E4, PID Autotune E4 + // PID-P E5, PID-I E5, PID-D E5, PID-C E5, PID Autotune E5 + // + #if ENABLED(PIDTEMP) + + #define _PID_BASE_MENU_ITEMS(ELABEL, eindex) \ + raw_Ki = unscalePID_i(PID_PARAM(Ki, eindex)); \ + raw_Kd = unscalePID_d(PID_PARAM(Kd, eindex)); \ + MENU_ITEM_EDIT(float52, MSG_PID_P ELABEL, &PID_PARAM(Kp, eindex), 1, 9990); \ + MENU_ITEM_EDIT_CALLBACK(float52, MSG_PID_I ELABEL, &raw_Ki, 0.01, 9990, copy_and_scalePID_i_E ## eindex); \ + MENU_ITEM_EDIT_CALLBACK(float52, MSG_PID_D ELABEL, &raw_Kd, 1, 9990, copy_and_scalePID_d_E ## eindex) + + #if ENABLED(PID_EXTRUSION_SCALING) + #define _PID_MENU_ITEMS(ELABEL, eindex) \ + _PID_BASE_MENU_ITEMS(ELABEL, eindex); \ + MENU_ITEM_EDIT(float3, MSG_PID_C ELABEL, &PID_PARAM(Kc, eindex), 1, 9990) + #else + #define _PID_MENU_ITEMS(ELABEL, eindex) _PID_BASE_MENU_ITEMS(ELABEL, eindex) + #endif + + #if ENABLED(PID_AUTOTUNE_MENU) + #define PID_MENU_ITEMS(ELABEL, eindex) \ + _PID_MENU_ITEMS(ELABEL, eindex); \ + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(int3, MSG_PID_AUTOTUNE ELABEL, &autotune_temp[eindex], 150, heater_maxtemp[eindex] - 15, lcd_autotune_callback_E ## eindex) + #else + #define PID_MENU_ITEMS(ELABEL, eindex) _PID_MENU_ITEMS(ELABEL, eindex) + #endif + + #if ENABLED(PID_PARAMS_PER_HOTEND) && HOTENDS > 1 + PID_MENU_ITEMS(" " MSG_E1, 0); + PID_MENU_ITEMS(" " MSG_E2, 1); + #if HOTENDS > 2 + PID_MENU_ITEMS(" " MSG_E3, 2); + #if HOTENDS > 3 + PID_MENU_ITEMS(" " MSG_E4, 3); + #if HOTENDS > 4 + PID_MENU_ITEMS(" " MSG_E5, 4); + #endif // HOTENDS > 4 + #endif // HOTENDS > 3 + #endif // HOTENDS > 2 + #else // !PID_PARAMS_PER_HOTEND || HOTENDS == 1 + PID_MENU_ITEMS("", 0); + #endif // !PID_PARAMS_PER_HOTEND || HOTENDS == 1 + + #endif // PIDTEMP + + // + // Preheat Material 1 conf + // + MENU_ITEM(submenu, MSG_PREHEAT_1_SETTINGS, lcd_control_temperature_preheat_material1_settings_menu); + + // + // Preheat Material 2 conf + // + MENU_ITEM(submenu, MSG_PREHEAT_2_SETTINGS, lcd_control_temperature_preheat_material2_settings_menu); + END_MENU(); + } + + void _lcd_control_temperature_preheat_settings_menu(uint8_t material) { + #if HOTENDS > 4 + #define MINTEMP_ALL MIN5(HEATER_0_MINTEMP, HEATER_1_MINTEMP, HEATER_2_MINTEMP, HEATER_3_MINTEMP, HEATER_4_MINTEMP) + #define MAXTEMP_ALL MAX5(HEATER_0_MAXTEMP, HEATER_1_MAXTEMP, HEATER_2_MAXTEMP, HEATER_3_MAXTEMP, HEATER_4_MAXTEMP) + #elif HOTENDS > 3 + #define MINTEMP_ALL MIN4(HEATER_0_MINTEMP, HEATER_1_MINTEMP, HEATER_2_MINTEMP, HEATER_3_MINTEMP) + #define MAXTEMP_ALL MAX4(HEATER_0_MAXTEMP, HEATER_1_MAXTEMP, HEATER_2_MAXTEMP, HEATER_3_MAXTEMP) + #elif HOTENDS > 2 + #define MINTEMP_ALL MIN3(HEATER_0_MINTEMP, HEATER_1_MINTEMP, HEATER_2_MINTEMP) + #define MAXTEMP_ALL MAX3(HEATER_0_MAXTEMP, HEATER_1_MAXTEMP, HEATER_2_MAXTEMP) + #elif HOTENDS > 1 + #define MINTEMP_ALL min(HEATER_0_MINTEMP, HEATER_1_MINTEMP) + #define MAXTEMP_ALL max(HEATER_0_MAXTEMP, HEATER_1_MAXTEMP) + #else + #define MINTEMP_ALL HEATER_0_MINTEMP + #define MAXTEMP_ALL HEATER_0_MAXTEMP + #endif + START_MENU(); + MENU_BACK(MSG_TEMPERATURE); + MENU_ITEM_EDIT(int3, MSG_FAN_SPEED, &lcd_preheat_fan_speed[material], 0, 255); + #if TEMP_SENSOR_0 != 0 + MENU_ITEM_EDIT(int3, MSG_NOZZLE, &lcd_preheat_hotend_temp[material], MINTEMP_ALL, MAXTEMP_ALL - 15); + #endif + #if TEMP_SENSOR_BED != 0 + MENU_ITEM_EDIT(int3, MSG_BED, &lcd_preheat_bed_temp[material], BED_MINTEMP, BED_MAXTEMP - 15); + #endif + #if ENABLED(EEPROM_SETTINGS) + MENU_ITEM(function, MSG_STORE_EEPROM, lcd_store_settings); + #endif + END_MENU(); + } + + /** + * + * "Temperature" > "Preheat Material 1 conf" submenu + * + */ + void lcd_control_temperature_preheat_material1_settings_menu() { _lcd_control_temperature_preheat_settings_menu(0); } + + /** + * + * "Temperature" > "Preheat Material 2 conf" submenu + * + */ + void lcd_control_temperature_preheat_material2_settings_menu() { _lcd_control_temperature_preheat_settings_menu(1); } + + + /** + * + * "Control" > "Motion" submenu + * + */ + + void _reset_acceleration_rates() { planner.reset_acceleration_rates(); } + #if ENABLED(DISTINCT_E_FACTORS) + void _reset_e_acceleration_rate(const uint8_t e) { if (e == active_extruder) _reset_acceleration_rates(); } + void _reset_e0_acceleration_rate() { _reset_e_acceleration_rate(0); } + void _reset_e1_acceleration_rate() { _reset_e_acceleration_rate(1); } + #if E_STEPPERS > 2 + void _reset_e2_acceleration_rate() { _reset_e_acceleration_rate(2); } + #if E_STEPPERS > 3 + void _reset_e3_acceleration_rate() { _reset_e_acceleration_rate(3); } + #if E_STEPPERS > 4 + void _reset_e4_acceleration_rate() { _reset_e_acceleration_rate(4); } + #endif // E_STEPPERS > 4 + #endif // E_STEPPERS > 3 + #endif // E_STEPPERS > 2 + #endif + + void _planner_refresh_positioning() { planner.refresh_positioning(); } + #if ENABLED(DISTINCT_E_FACTORS) + void _planner_refresh_e_positioning(const uint8_t e) { + if (e == active_extruder) + _planner_refresh_positioning(); + else + planner.steps_to_mm[E_AXIS + e] = 1.0 / planner.axis_steps_per_mm[E_AXIS + e]; + } + void _planner_refresh_e0_positioning() { _planner_refresh_e_positioning(0); } + void _planner_refresh_e1_positioning() { _planner_refresh_e_positioning(1); } + #if E_STEPPERS > 2 + void _planner_refresh_e2_positioning() { _planner_refresh_e_positioning(2); } + #if E_STEPPERS > 3 + void _planner_refresh_e3_positioning() { _planner_refresh_e_positioning(3); } + #if E_STEPPERS > 4 + void _planner_refresh_e4_positioning() { _planner_refresh_e_positioning(4); } + #endif // E_STEPPERS > 4 + #endif // E_STEPPERS > 3 + #endif // E_STEPPERS > 2 + #endif + + // M203 / M205 Velocity options + void lcd_control_motion_velocity_menu() { + START_MENU(); + MENU_BACK(MSG_MOTION); + + // M203 Max Feedrate + MENU_ITEM_EDIT(float3, MSG_VMAX MSG_X, &planner.max_feedrate_mm_s[X_AXIS], 1, 999); + MENU_ITEM_EDIT(float3, MSG_VMAX MSG_Y, &planner.max_feedrate_mm_s[Y_AXIS], 1, 999); + MENU_ITEM_EDIT(float3, MSG_VMAX MSG_Z, &planner.max_feedrate_mm_s[Z_AXIS], 1, 999); + + #if ENABLED(DISTINCT_E_FACTORS) + MENU_ITEM_EDIT(float3, MSG_VMAX MSG_E, &planner.max_feedrate_mm_s[E_AXIS + active_extruder], 1, 999); + MENU_ITEM_EDIT(float3, MSG_VMAX MSG_E1, &planner.max_feedrate_mm_s[E_AXIS], 1, 999); + MENU_ITEM_EDIT(float3, MSG_VMAX MSG_E2, &planner.max_feedrate_mm_s[E_AXIS + 1], 1, 999); + #if E_STEPPERS > 2 + MENU_ITEM_EDIT(float3, MSG_VMAX MSG_E3, &planner.max_feedrate_mm_s[E_AXIS + 2], 1, 999); + #if E_STEPPERS > 3 + MENU_ITEM_EDIT(float3, MSG_VMAX MSG_E4, &planner.max_feedrate_mm_s[E_AXIS + 3], 1, 999); + #if E_STEPPERS > 4 + MENU_ITEM_EDIT(float3, MSG_VMAX MSG_E5, &planner.max_feedrate_mm_s[E_AXIS + 4], 1, 999); + #endif // E_STEPPERS > 4 + #endif // E_STEPPERS > 3 + #endif // E_STEPPERS > 2 + #else + MENU_ITEM_EDIT(float3, MSG_VMAX MSG_E, &planner.max_feedrate_mm_s[E_AXIS], 1, 999); + #endif + + // M205 S Min Feedrate + MENU_ITEM_EDIT(float3, MSG_VMIN, &planner.min_feedrate_mm_s, 0, 999); + + // M205 T Min Travel Feedrate + MENU_ITEM_EDIT(float3, MSG_VTRAV_MIN, &planner.min_travel_feedrate_mm_s, 0, 999); + + END_MENU(); + } + + // M201 / M204 Accelerations + void lcd_control_motion_acceleration_menu() { + START_MENU(); + MENU_BACK(MSG_MOTION); + + // M204 P Acceleration + MENU_ITEM_EDIT(float5, MSG_ACC, &planner.acceleration, 10, 99000); + + // M204 R Retract Acceleration + MENU_ITEM_EDIT(float5, MSG_A_RETRACT, &planner.retract_acceleration, 100, 99000); + + // M204 T Travel Acceleration + MENU_ITEM_EDIT(float5, MSG_A_TRAVEL, &planner.travel_acceleration, 100, 99000); + + // M201 settings + MENU_ITEM_EDIT_CALLBACK(long5, MSG_AMAX MSG_X, &planner.max_acceleration_mm_per_s2[X_AXIS], 100, 99000, _reset_acceleration_rates); + MENU_ITEM_EDIT_CALLBACK(long5, MSG_AMAX MSG_Y, &planner.max_acceleration_mm_per_s2[Y_AXIS], 100, 99000, _reset_acceleration_rates); + MENU_ITEM_EDIT_CALLBACK(long5, MSG_AMAX MSG_Z, &planner.max_acceleration_mm_per_s2[Z_AXIS], 10, 99000, _reset_acceleration_rates); + + #if ENABLED(DISTINCT_E_FACTORS) + MENU_ITEM_EDIT_CALLBACK(long5, MSG_AMAX MSG_E, &planner.max_acceleration_mm_per_s2[E_AXIS + active_extruder], 100, 99000, _reset_acceleration_rates); + MENU_ITEM_EDIT_CALLBACK(long5, MSG_AMAX MSG_E1, &planner.max_acceleration_mm_per_s2[E_AXIS], 100, 99000, _reset_e0_acceleration_rate); + MENU_ITEM_EDIT_CALLBACK(long5, MSG_AMAX MSG_E2, &planner.max_acceleration_mm_per_s2[E_AXIS + 1], 100, 99000, _reset_e1_acceleration_rate); + #if E_STEPPERS > 2 + MENU_ITEM_EDIT_CALLBACK(long5, MSG_AMAX MSG_E3, &planner.max_acceleration_mm_per_s2[E_AXIS + 2], 100, 99000, _reset_e2_acceleration_rate); + #if E_STEPPERS > 3 + MENU_ITEM_EDIT_CALLBACK(long5, MSG_AMAX MSG_E4, &planner.max_acceleration_mm_per_s2[E_AXIS + 3], 100, 99000, _reset_e3_acceleration_rate); + #if E_STEPPERS > 4 + MENU_ITEM_EDIT_CALLBACK(long5, MSG_AMAX MSG_E5, &planner.max_acceleration_mm_per_s2[E_AXIS + 4], 100, 99000, _reset_e4_acceleration_rate); + #endif // E_STEPPERS > 4 + #endif // E_STEPPERS > 3 + #endif // E_STEPPERS > 2 + #else + MENU_ITEM_EDIT_CALLBACK(long5, MSG_AMAX MSG_E, &planner.max_acceleration_mm_per_s2[E_AXIS], 100, 99000, _reset_acceleration_rates); + #endif + + END_MENU(); + } + + // M205 Jerk + void lcd_control_motion_jerk_menu() { + START_MENU(); + MENU_BACK(MSG_MOTION); + + MENU_ITEM_EDIT(float3, MSG_VX_JERK, &planner.max_jerk[X_AXIS], 1, 990); + MENU_ITEM_EDIT(float3, MSG_VY_JERK, &planner.max_jerk[Y_AXIS], 1, 990); + #if ENABLED(DELTA) + MENU_ITEM_EDIT(float3, MSG_VZ_JERK, &planner.max_jerk[Z_AXIS], 1, 990); + #else + MENU_ITEM_EDIT(float52, MSG_VZ_JERK, &planner.max_jerk[Z_AXIS], 0.1, 990); + #endif + MENU_ITEM_EDIT(float3, MSG_VE_JERK, &planner.max_jerk[E_AXIS], 1, 990); + + END_MENU(); + } + + // M92 Steps-per-mm + void lcd_control_motion_steps_per_mm_menu() { + START_MENU(); + MENU_BACK(MSG_MOTION); + + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float62, MSG_XSTEPS, &planner.axis_steps_per_mm[X_AXIS], 5, 9999, _planner_refresh_positioning); + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float62, MSG_YSTEPS, &planner.axis_steps_per_mm[Y_AXIS], 5, 9999, _planner_refresh_positioning); + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float62, MSG_ZSTEPS, &planner.axis_steps_per_mm[Z_AXIS], 5, 9999, _planner_refresh_positioning); + + #if ENABLED(DISTINCT_E_FACTORS) + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float62, MSG_ESTEPS, &planner.axis_steps_per_mm[E_AXIS + active_extruder], 5, 9999, _planner_refresh_positioning); + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float62, MSG_E1STEPS, &planner.axis_steps_per_mm[E_AXIS], 5, 9999, _planner_refresh_e0_positioning); + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float62, MSG_E2STEPS, &planner.axis_steps_per_mm[E_AXIS + 1], 5, 9999, _planner_refresh_e1_positioning); + #if E_STEPPERS > 2 + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float62, MSG_E3STEPS, &planner.axis_steps_per_mm[E_AXIS + 2], 5, 9999, _planner_refresh_e2_positioning); + #if E_STEPPERS > 3 + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float62, MSG_E4STEPS, &planner.axis_steps_per_mm[E_AXIS + 3], 5, 9999, _planner_refresh_e3_positioning); + #if E_STEPPERS > 4 + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float62, MSG_E5STEPS, &planner.axis_steps_per_mm[E_AXIS + 4], 5, 9999, _planner_refresh_e4_positioning); + #endif // E_STEPPERS > 4 + #endif // E_STEPPERS > 3 + #endif // E_STEPPERS > 2 + #else + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float62, MSG_ESTEPS, &planner.axis_steps_per_mm[E_AXIS], 5, 9999, _planner_refresh_positioning); + #endif + + END_MENU(); + } + + void lcd_control_motion_menu() { + START_MENU(); + MENU_BACK(MSG_CONTROL); + + #if ENABLED(BABYSTEP_ZPROBE_OFFSET) + MENU_ITEM(submenu, MSG_ZPROBE_ZOFFSET, lcd_babystep_zoffset); + #elif HAS_BED_PROBE + MENU_ITEM_EDIT_CALLBACK(float32, MSG_ZPROBE_ZOFFSET, &zprobe_zoffset, Z_PROBE_OFFSET_RANGE_MIN, Z_PROBE_OFFSET_RANGE_MAX, lcd_refresh_zprobe_zoffset); + #endif + + // M203 / M205 - Feedrate items + MENU_ITEM(submenu, MSG_VELOCITY, lcd_control_motion_velocity_menu); + + // M201 - Acceleration items + MENU_ITEM(submenu, MSG_ACCELERATION, lcd_control_motion_acceleration_menu); + + // M205 - Max Jerk + MENU_ITEM(submenu, MSG_JERK, lcd_control_motion_jerk_menu); + + // M92 - Steps Per mm + MENU_ITEM(submenu, MSG_STEPS_PER_MM, lcd_control_motion_steps_per_mm_menu); + + // M540 S - Abort on endstop hit when SD printing + #if ENABLED(ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED) + MENU_ITEM_EDIT(bool, MSG_ENDSTOP_ABORT, &stepper.abort_on_endstop_hit); + #endif + + END_MENU(); + } + + /** + * + * "Control" > "Filament" submenu + * + */ + void lcd_control_filament_menu() { + START_MENU(); + MENU_BACK(MSG_CONTROL); + + #if ENABLED(LIN_ADVANCE) + MENU_ITEM_EDIT(float3, MSG_ADVANCE_K, &planner.extruder_advance_k, 0, 999); + #endif + + MENU_ITEM_EDIT_CALLBACK(bool, MSG_VOLUMETRIC_ENABLED, &volumetric_enabled, calculate_volumetric_multipliers); + + if (volumetric_enabled) { + #if EXTRUDERS == 1 + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float43, MSG_FILAMENT_DIAM, &filament_size[0], 1.5, 3.25, calculate_volumetric_multipliers); + #else // EXTRUDERS > 1 + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float43, MSG_FILAMENT_DIAM MSG_DIAM_E1, &filament_size[0], 1.5, 3.25, calculate_volumetric_multipliers); + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float43, MSG_FILAMENT_DIAM MSG_DIAM_E2, &filament_size[1], 1.5, 3.25, calculate_volumetric_multipliers); + #if EXTRUDERS > 2 + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float43, MSG_FILAMENT_DIAM MSG_DIAM_E3, &filament_size[2], 1.5, 3.25, calculate_volumetric_multipliers); + #if EXTRUDERS > 3 + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float43, MSG_FILAMENT_DIAM MSG_DIAM_E4, &filament_size[3], 1.5, 3.25, calculate_volumetric_multipliers); + #if EXTRUDERS > 4 + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float43, MSG_FILAMENT_DIAM MSG_DIAM_E5, &filament_size[4], 1.5, 3.25, calculate_volumetric_multipliers); + #endif // EXTRUDERS > 4 + #endif // EXTRUDERS > 3 + #endif // EXTRUDERS > 2 + #endif // EXTRUDERS > 1 + } + + END_MENU(); + } + + /** + * + * "Control" > "Retract" submenu + * + */ + #if ENABLED(FWRETRACT) + + void lcd_control_retract_menu() { + START_MENU(); + MENU_BACK(MSG_CONTROL); + MENU_ITEM_EDIT(bool, MSG_AUTORETRACT, &autoretract_enabled); + MENU_ITEM_EDIT(float52, MSG_CONTROL_RETRACT, &retract_length, 0, 100); + #if EXTRUDERS > 1 + MENU_ITEM_EDIT(float52, MSG_CONTROL_RETRACT_SWAP, &swap_retract_length, 0, 100); + #endif + MENU_ITEM_EDIT(float3, MSG_CONTROL_RETRACTF, &retract_feedrate_mm_s, 1, 999); + MENU_ITEM_EDIT(float52, MSG_CONTROL_RETRACT_ZLIFT, &retract_zlift, 0, 999); + MENU_ITEM_EDIT(float52, MSG_CONTROL_RETRACT_RECOVER, &retract_recover_length, -100, 100); + #if EXTRUDERS > 1 + MENU_ITEM_EDIT(float52, MSG_CONTROL_RETRACT_RECOVER_SWAP, &swap_retract_recover_length, -100, 100); + #endif + MENU_ITEM_EDIT(float3, MSG_CONTROL_RETRACT_RECOVERF, &retract_recover_feedrate_mm_s, 1, 999); + END_MENU(); + } + + #endif // FWRETRACT + + #if ENABLED(SDSUPPORT) + + #if !PIN_EXISTS(SD_DETECT) + void lcd_sd_refresh() { + card.initsd(); + encoderTopLine = 0; + } + #endif + + void lcd_sd_updir() { + card.updir(); + encoderTopLine = 0; + screen_changed = true; + lcdDrawUpdate = LCDVIEW_CLEAR_CALL_REDRAW; + } + + /** + * + * "Print from SD" submenu + * + */ + void lcd_sdcard_menu() { + ENCODER_DIRECTION_MENUS(); + if (!lcdDrawUpdate && !lcd_clicked) return; // nothing to do (so don't thrash the SD card) + const uint16_t fileCnt = card.getnrfilenames(); + START_MENU(); + MENU_BACK(MSG_MAIN); + card.getWorkDirName(); + if (card.filename[0] == '/') { + #if !PIN_EXISTS(SD_DETECT) + MENU_ITEM(function, LCD_STR_REFRESH MSG_REFRESH, lcd_sd_refresh); + #endif + } + else { + MENU_ITEM(function, LCD_STR_FOLDER "..", lcd_sd_updir); + } + + 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; + + #if ENABLED(SDCARD_SORT_ALPHA) + card.getfilename_sorted(nr); + #else + card.getfilename(nr); + #endif + + if (card.filenameIsDir) + MENU_ITEM(sddirectory, MSG_CARD_MENU, card.filename, card.longFilename); + else + MENU_ITEM(sdfile, MSG_CARD_MENU, card.filename, card.longFilename); + } + else { + MENU_ITEM_DUMMY(); + } + } + END_MENU(); + } + + #endif // SDSUPPORT + + #if ENABLED(LCD_INFO_MENU) + + #if ENABLED(PRINTCOUNTER) + /** + * + * About Printer > Statistics submenu + * + */ + void lcd_info_stats_menu() { + if (lcd_clicked) { return lcd_goto_previous_menu(); } + + char buffer[21]; + printStatistics stats = print_job_timer.getStats(); + + START_SCREEN(); // 12345678901234567890 + STATIC_ITEM(MSG_INFO_PRINT_COUNT ": ", false, false, itostr3left(stats.totalPrints)); // Print Count: 999 + STATIC_ITEM(MSG_INFO_COMPLETED_PRINTS": ", false, false, itostr3left(stats.finishedPrints)); // Completed : 666 + + duration_t elapsed = stats.printTime; + elapsed.toString(buffer); + + STATIC_ITEM(MSG_INFO_PRINT_TIME ": ", false, false); // Total print Time: + STATIC_ITEM("", false, false, buffer); // 99y 364d 23h 59m 59s + + elapsed = stats.longestPrint; + elapsed.toString(buffer); + + STATIC_ITEM(MSG_INFO_PRINT_LONGEST ": ", false, false); // Longest job time: + STATIC_ITEM("", false, false, buffer); // 99y 364d 23h 59m 59s + + sprintf_P(buffer, PSTR("%ld.%im"), long(stats.filamentUsed / 1000), int16_t(stats.filamentUsed / 100) % 10); + STATIC_ITEM(MSG_INFO_PRINT_FILAMENT ": ", false, false); // Extruded total: + STATIC_ITEM("", false, false, buffer); // 125m + END_SCREEN(); + } + #endif // PRINTCOUNTER + + /** + * + * About Printer > Thermistors + * + */ + void lcd_info_thermistors_menu() { + if (lcd_clicked) { return lcd_goto_previous_menu(); } + START_SCREEN(); + #define THERMISTOR_ID TEMP_SENSOR_0 + #include "thermistornames.h" + STATIC_ITEM("T0: " THERMISTOR_NAME, false, true); + STATIC_ITEM(MSG_INFO_MIN_TEMP ": " STRINGIFY(HEATER_0_MINTEMP), false); + STATIC_ITEM(MSG_INFO_MAX_TEMP ": " STRINGIFY(HEATER_0_MAXTEMP), false); + + #if TEMP_SENSOR_1 != 0 + #undef THERMISTOR_ID + #define THERMISTOR_ID TEMP_SENSOR_1 + #include "thermistornames.h" + STATIC_ITEM("T1: " THERMISTOR_NAME, false, true); + STATIC_ITEM(MSG_INFO_MIN_TEMP ": " STRINGIFY(HEATER_1_MINTEMP), false); + STATIC_ITEM(MSG_INFO_MAX_TEMP ": " STRINGIFY(HEATER_1_MAXTEMP), false); + #endif + + #if TEMP_SENSOR_2 != 0 + #undef THERMISTOR_ID + #define THERMISTOR_ID TEMP_SENSOR_2 + #include "thermistornames.h" + STATIC_ITEM("T2: " THERMISTOR_NAME, false, true); + STATIC_ITEM(MSG_INFO_MIN_TEMP ": " STRINGIFY(HEATER_2_MINTEMP), false); + STATIC_ITEM(MSG_INFO_MAX_TEMP ": " STRINGIFY(HEATER_2_MAXTEMP), false); + #endif + + #if TEMP_SENSOR_3 != 0 + #undef THERMISTOR_ID + #define THERMISTOR_ID TEMP_SENSOR_3 + #include "thermistornames.h" + STATIC_ITEM("T3: " THERMISTOR_NAME, false, true); + STATIC_ITEM(MSG_INFO_MIN_TEMP ": " STRINGIFY(HEATER_3_MINTEMP), false); + STATIC_ITEM(MSG_INFO_MAX_TEMP ": " STRINGIFY(HEATER_3_MAXTEMP), false); + #endif + + #if TEMP_SENSOR_4 != 0 + #undef THERMISTOR_ID + #define THERMISTOR_ID TEMP_SENSOR_4 + #include "thermistornames.h" + STATIC_ITEM("T4: " THERMISTOR_NAME, false, true); + STATIC_ITEM(MSG_INFO_MIN_TEMP ": " STRINGIFY(HEATER_4_MINTEMP), false); + STATIC_ITEM(MSG_INFO_MAX_TEMP ": " STRINGIFY(HEATER_4_MAXTEMP), false); + #endif + + #if TEMP_SENSOR_BED != 0 + #undef THERMISTOR_ID + #define THERMISTOR_ID TEMP_SENSOR_BED + #include "thermistornames.h" + STATIC_ITEM("TBed:" THERMISTOR_NAME, false, true); + STATIC_ITEM(MSG_INFO_MIN_TEMP ": " STRINGIFY(BED_MINTEMP), false); + STATIC_ITEM(MSG_INFO_MAX_TEMP ": " STRINGIFY(BED_MAXTEMP), false); + #endif + END_SCREEN(); + } + + /** + * + * About Printer > Board Info + * + */ + void lcd_info_board_menu() { + if (lcd_clicked) { return lcd_goto_previous_menu(); } + START_SCREEN(); + STATIC_ITEM(BOARD_NAME, true, true); // MyPrinterController + STATIC_ITEM(MSG_INFO_BAUDRATE ": " STRINGIFY(BAUDRATE), true); // Baud: 250000 + STATIC_ITEM(MSG_INFO_PROTOCOL ": " PROTOCOL_VERSION, true); // Protocol: 1.0 + #if POWER_SUPPLY == 0 + STATIC_ITEM(MSG_INFO_PSU ": Generic", true); + #elif POWER_SUPPLY == 1 + STATIC_ITEM(MSG_INFO_PSU ": ATX", true); // Power Supply: ATX + #elif POWER_SUPPLY == 2 + STATIC_ITEM(MSG_INFO_PSU ": XBox", true); // Power Supply: XBox + #endif + END_SCREEN(); + } + + /** + * + * About Printer > Printer Info + * + */ + void lcd_info_printer_menu() { + if (lcd_clicked) { return lcd_goto_previous_menu(); } + START_SCREEN(); + STATIC_ITEM(MSG_MARLIN, true, true); // Marlin + STATIC_ITEM(SHORT_BUILD_VERSION, true); // x.x.x-Branch + STATIC_ITEM(STRING_DISTRIBUTION_DATE, true); // YYYY-MM-DD HH:MM + STATIC_ITEM(MACHINE_NAME, true); // My3DPrinter + STATIC_ITEM(WEBSITE_URL, true); // www.my3dprinter.com + STATIC_ITEM(MSG_INFO_EXTRUDERS ": " STRINGIFY(EXTRUDERS), true); // Extruders: 2 + #if ENABLED(AUTO_BED_LEVELING_3POINT) + STATIC_ITEM(MSG_3POINT_LEVELING, true); // 3-Point Leveling + #elif ENABLED(AUTO_BED_LEVELING_LINEAR) + STATIC_ITEM(MSG_LINEAR_LEVELING, true); // Linear Leveling + #elif ENABLED(AUTO_BED_LEVELING_BILINEAR) + STATIC_ITEM(MSG_BILINEAR_LEVELING, true); // Bi-linear Leveling + #elif ENABLED(AUTO_BED_LEVELING_UBL) + STATIC_ITEM(MSG_UBL_LEVELING, true); // Unified Bed Leveling + #elif ENABLED(MESH_BED_LEVELING) + STATIC_ITEM(MSG_MESH_LEVELING, true); // Mesh Leveling + #endif + END_SCREEN(); + } + + /** + * + * "About Printer" submenu + * + */ + void lcd_info_menu() { + START_MENU(); + MENU_BACK(MSG_MAIN); + MENU_ITEM(submenu, MSG_INFO_PRINTER_MENU, lcd_info_printer_menu); // Printer Info > + MENU_ITEM(submenu, MSG_INFO_BOARD_MENU, lcd_info_board_menu); // Board Info > + MENU_ITEM(submenu, MSG_INFO_THERMISTOR_MENU, lcd_info_thermistors_menu); // Thermistors > + #if ENABLED(PRINTCOUNTER) + MENU_ITEM(submenu, MSG_INFO_STATS_MENU, lcd_info_stats_menu); // Printer Statistics > + #endif + END_MENU(); + } + #endif // LCD_INFO_MENU + + /** + * + * Filament Change Feature Screens + * + */ + #if ENABLED(ADVANCED_PAUSE_FEATURE) + + // Portions from STATIC_ITEM... + #define HOTEND_STATUS_ITEM() do { \ + if (_menuLineNr == _thisItemNr) { \ + if (lcdDrawUpdate) { \ + lcd_implementation_drawmenu_static(_lcdLineNr, PSTR(MSG_FILAMENT_CHANGE_NOZZLE), false, true); \ + lcd_implementation_hotend_status(_lcdLineNr); \ + } \ + if (_skipStatic && encoderLine <= _thisItemNr) { \ + encoderPosition += ENCODER_STEPS_PER_MENU_ITEM; \ + ++encoderLine; \ + } \ + lcdDrawUpdate = LCDVIEW_CALL_REDRAW_NEXT; \ + } \ + ++_thisItemNr; \ + }while(0) + + void lcd_advanced_pause_toocold_menu() { + START_MENU(); + STATIC_ITEM(MSG_HEATING_FAILED_LCD, true, true); + STATIC_ITEM(MSG_FILAMENT_CHANGE_MINTEMP STRINGIFY(EXTRUDE_MINTEMP) ".", false, false); + MENU_BACK(MSG_BACK); + #if LCD_HEIGHT > 4 + STATIC_ITEM(" "); + #endif + HOTEND_STATUS_ITEM(); + END_MENU(); + } + + void lcd_advanced_pause_resume_print() { + advanced_pause_menu_response = ADVANCED_PAUSE_RESPONSE_RESUME_PRINT; + } + + void lcd_advanced_pause_extrude_more() { + advanced_pause_menu_response = ADVANCED_PAUSE_RESPONSE_EXTRUDE_MORE; + } + + void lcd_advanced_pause_option_menu() { + START_MENU(); + #if LCD_HEIGHT > 2 + STATIC_ITEM(MSG_FILAMENT_CHANGE_OPTION_HEADER, true, false); + #endif + MENU_ITEM(function, MSG_FILAMENT_CHANGE_OPTION_RESUME, lcd_advanced_pause_resume_print); + MENU_ITEM(function, MSG_FILAMENT_CHANGE_OPTION_EXTRUDE, lcd_advanced_pause_extrude_more); + END_MENU(); + } + + void lcd_advanced_pause_init_message() { + START_SCREEN(); + STATIC_ITEM(MSG_FILAMENT_CHANGE_HEADER, true, true); + STATIC_ITEM(MSG_FILAMENT_CHANGE_INIT_1); + #ifdef MSG_FILAMENT_CHANGE_INIT_2 + STATIC_ITEM(MSG_FILAMENT_CHANGE_INIT_2); + #define __FC_LINES_A 3 + #else + #define __FC_LINES_A 2 + #endif + #ifdef MSG_FILAMENT_CHANGE_INIT_3 + STATIC_ITEM(MSG_FILAMENT_CHANGE_INIT_3); + #define _FC_LINES_A (__FC_LINES_A + 1) + #else + #define _FC_LINES_A __FC_LINES_A + #endif + #if LCD_HEIGHT > _FC_LINES_A + 1 + STATIC_ITEM(" "); + #endif + HOTEND_STATUS_ITEM(); + END_SCREEN(); + } + + void lcd_advanced_pause_unload_message() { + START_SCREEN(); + STATIC_ITEM(MSG_FILAMENT_CHANGE_HEADER, true, true); + STATIC_ITEM(MSG_FILAMENT_CHANGE_UNLOAD_1); + #ifdef MSG_FILAMENT_CHANGE_UNLOAD_2 + STATIC_ITEM(MSG_FILAMENT_CHANGE_UNLOAD_2); + #define __FC_LINES_B 3 + #else + #define __FC_LINES_B 2 + #endif + #ifdef MSG_FILAMENT_CHANGE_UNLOAD_3 + STATIC_ITEM(MSG_FILAMENT_CHANGE_UNLOAD_3); + #define _FC_LINES_B (__FC_LINES_B + 1) + #else + #define _FC_LINES_B __FC_LINES_B + #endif + #if LCD_HEIGHT > _FC_LINES_B + 1 + STATIC_ITEM(" "); + #endif + HOTEND_STATUS_ITEM(); + END_SCREEN(); + } + + void lcd_advanced_pause_wait_for_nozzles_to_heat() { + START_SCREEN(); + STATIC_ITEM(MSG_FILAMENT_CHANGE_HEADER, true, true); + STATIC_ITEM(MSG_FILAMENT_CHANGE_HEATING_1); + #ifdef MSG_FILAMENT_CHANGE_HEATING_2 + STATIC_ITEM(MSG_FILAMENT_CHANGE_HEATING_2); + #define _FC_LINES_C 3 + #else + #define _FC_LINES_C 2 + #endif + #if LCD_HEIGHT > _FC_LINES_C + 1 + STATIC_ITEM(" "); + #endif + HOTEND_STATUS_ITEM(); + END_SCREEN(); + } + + void lcd_advanced_pause_heat_nozzle() { + START_SCREEN(); + STATIC_ITEM(MSG_FILAMENT_CHANGE_HEADER, true, true); + STATIC_ITEM(MSG_FILAMENT_CHANGE_HEAT_1); + #ifdef MSG_FILAMENT_CHANGE_INSERT_2 + STATIC_ITEM(MSG_FILAMENT_CHANGE_HEAT_2); + #define _FC_LINES_D 3 + #else + #define _FC_LINES_D 2 + #endif + #if LCD_HEIGHT > _FC_LINES_D + 1 + STATIC_ITEM(" "); + #endif + HOTEND_STATUS_ITEM(); + END_SCREEN(); + } + + void lcd_advanced_pause_insert_message() { + START_SCREEN(); + STATIC_ITEM(MSG_FILAMENT_CHANGE_HEADER, true, true); + STATIC_ITEM(MSG_FILAMENT_CHANGE_INSERT_1); + #ifdef MSG_FILAMENT_CHANGE_INSERT_2 + STATIC_ITEM(MSG_FILAMENT_CHANGE_INSERT_2); + #define __FC_LINES_E 3 + #else + #define __FC_LINES_E 2 + #endif + #ifdef MSG_FILAMENT_CHANGE_INSERT_3 + STATIC_ITEM(MSG_FILAMENT_CHANGE_INSERT_3); + #define _FC_LINES_E (__FC_LINES_E + 1) + #else + #define _FC_LINES_E __FC_LINES_E + #endif + #if LCD_HEIGHT > _FC_LINES_E + 1 + STATIC_ITEM(" "); + #endif + HOTEND_STATUS_ITEM(); + END_SCREEN(); + } + + void lcd_advanced_pause_load_message() { + START_SCREEN(); + STATIC_ITEM(MSG_FILAMENT_CHANGE_HEADER, true, true); + STATIC_ITEM(MSG_FILAMENT_CHANGE_LOAD_1); + #ifdef MSG_FILAMENT_CHANGE_LOAD_2 + STATIC_ITEM(MSG_FILAMENT_CHANGE_LOAD_2); + #define __FC_LINES_F 3 + #else + #define __FC_LINES_F 2 + #endif + #ifdef MSG_FILAMENT_CHANGE_LOAD_3 + STATIC_ITEM(MSG_FILAMENT_CHANGE_LOAD_3); + #define _FC_LINES_F (__FC_LINES_F + 1) + #else + #define _FC_LINES_F __FC_LINES_F + #endif + #if LCD_HEIGHT > _FC_LINES_F + 1 + STATIC_ITEM(" "); + #endif + HOTEND_STATUS_ITEM(); + END_SCREEN(); + } + + void lcd_advanced_pause_extrude_message() { + START_SCREEN(); + STATIC_ITEM(MSG_FILAMENT_CHANGE_HEADER, true, true); + STATIC_ITEM(MSG_FILAMENT_CHANGE_EXTRUDE_1); + #ifdef MSG_FILAMENT_CHANGE_EXTRUDE_2 + STATIC_ITEM(MSG_FILAMENT_CHANGE_EXTRUDE_2); + #define __FC_LINES_G 3 + #else + #define __FC_LINES_G 2 + #endif + #ifdef MSG_FILAMENT_CHANGE_EXTRUDE_3 + STATIC_ITEM(MSG_FILAMENT_CHANGE_EXTRUDE_3); + #define _FC_LINES_G (__FC_LINES_G + 1) + #else + #define _FC_LINES_G __FC_LINES_G + #endif + #if LCD_HEIGHT > _FC_LINES_G + 1 + STATIC_ITEM(" "); + #endif + HOTEND_STATUS_ITEM(); + END_SCREEN(); + } + + void lcd_advanced_pause_resume_message() { + START_SCREEN(); + STATIC_ITEM(MSG_FILAMENT_CHANGE_HEADER, true, true); + STATIC_ITEM(MSG_FILAMENT_CHANGE_RESUME_1); + #ifdef MSG_FILAMENT_CHANGE_RESUME_2 + STATIC_ITEM(MSG_FILAMENT_CHANGE_RESUME_2); + #endif + #ifdef MSG_FILAMENT_CHANGE_RESUME_3 + STATIC_ITEM(MSG_FILAMENT_CHANGE_RESUME_3); + #endif + END_SCREEN(); + } + + void lcd_advanced_pause_show_message(const AdvancedPauseMessage message) { + switch (message) { + case ADVANCED_PAUSE_MESSAGE_INIT: + defer_return_to_status = true; + lcd_goto_screen(lcd_advanced_pause_init_message); + break; + case ADVANCED_PAUSE_MESSAGE_UNLOAD: + defer_return_to_status = true; + lcd_goto_screen(lcd_advanced_pause_unload_message); + break; + case ADVANCED_PAUSE_MESSAGE_INSERT: + defer_return_to_status = true; + lcd_goto_screen(lcd_advanced_pause_insert_message); + break; + case ADVANCED_PAUSE_MESSAGE_LOAD: + defer_return_to_status = true; + lcd_goto_screen(lcd_advanced_pause_load_message); + break; + case ADVANCED_PAUSE_MESSAGE_EXTRUDE: + defer_return_to_status = true; + lcd_goto_screen(lcd_advanced_pause_extrude_message); + break; + case ADVANCED_PAUSE_MESSAGE_CLICK_TO_HEAT_NOZZLE: + defer_return_to_status = true; + lcd_goto_screen(lcd_advanced_pause_heat_nozzle); + break; + case ADVANCED_PAUSE_MESSAGE_WAIT_FOR_NOZZLES_TO_HEAT: + defer_return_to_status = true; + lcd_goto_screen(lcd_advanced_pause_wait_for_nozzles_to_heat); + break; + case ADVANCED_PAUSE_MESSAGE_OPTION: + defer_return_to_status = true; + advanced_pause_menu_response = ADVANCED_PAUSE_RESPONSE_WAIT_FOR; + lcd_goto_screen(lcd_advanced_pause_option_menu); + break; + case ADVANCED_PAUSE_MESSAGE_RESUME: + defer_return_to_status = true; + lcd_goto_screen(lcd_advanced_pause_resume_message); + break; + case ADVANCED_PAUSE_MESSAGE_STATUS: + lcd_return_to_status(); + break; + } + } + + #endif // ADVANCED_PAUSE_FEATURE + + /** + * + * Functions for editing single values + * + * The "DEFINE_MENU_EDIT_TYPE" macro generates the functions needed to edit a numerical value. + * + * For example, DEFINE_MENU_EDIT_TYPE(int16_t, int3, itostr3, 1) expands into these functions: + * + * bool _menu_edit_int3(); + * void menu_edit_int3(); // edit int16_t (interactively) + * void menu_edit_callback_int3(); // edit int16_t (interactively) with callback on completion + * void _menu_action_setting_edit_int3(const char * const pstr, int16_t * const ptr, const int16_t minValue, const int16_t maxValue); + * void menu_action_setting_edit_int3(const char * const pstr, int16_t * const ptr, const int16_t minValue, const int16_t maxValue); + * void menu_action_setting_edit_callback_int3(const char * const pstr, int16_t * const ptr, const int16_t minValue, const int16_t maxValue, const screenFunc_t callback, const bool live); // edit int16_t with callback + * + * You can then use one of the menu macros to present the edit interface: + * MENU_ITEM_EDIT(int3, MSG_SPEED, &feedrate_percentage, 10, 999) + * + * This expands into a more primitive menu item: + * MENU_ITEM(setting_edit_int3, MSG_SPEED, PSTR(MSG_SPEED), &feedrate_percentage, 10, 999) + * + * ...which calls: + * menu_action_setting_edit_int3(PSTR(MSG_SPEED), &feedrate_percentage, 10, 999) + */ + #define DEFINE_MENU_EDIT_TYPE(_type, _name, _strFunc, _scale) \ + bool _menu_edit_ ## _name() { \ + ENCODER_DIRECTION_NORMAL(); \ + if ((int32_t)encoderPosition < 0) encoderPosition = 0; \ + if ((int32_t)encoderPosition > maxEditValue) encoderPosition = maxEditValue; \ + if (lcdDrawUpdate) \ + lcd_implementation_drawedit(editLabel, _strFunc(((_type)((int32_t)encoderPosition + minEditValue)) * (1.0 / _scale))); \ + if (lcd_clicked || (liveEdit && lcdDrawUpdate)) { \ + _type value = ((_type)((int32_t)encoderPosition + minEditValue)) * (1.0 / _scale); \ + if (editValue != NULL) *((_type*)editValue) = value; \ + if (liveEdit) (*callbackFunc)(); \ + if (lcd_clicked) lcd_goto_previous_menu(); \ + } \ + return lcd_clicked; \ + } \ + void menu_edit_ ## _name() { _menu_edit_ ## _name(); } \ + void menu_edit_callback_ ## _name() { if (_menu_edit_ ## _name()) (*callbackFunc)(); } \ + void _menu_action_setting_edit_ ## _name(const char * const pstr, _type* const ptr, const _type minValue, const _type maxValue) { \ + lcd_save_previous_screen(); \ + \ + lcdDrawUpdate = LCDVIEW_CLEAR_CALL_REDRAW; \ + \ + editLabel = pstr; \ + editValue = ptr; \ + minEditValue = minValue * _scale; \ + maxEditValue = maxValue * _scale - minEditValue; \ + encoderPosition = (*ptr) * _scale - minEditValue; \ + } \ + void menu_action_setting_edit_ ## _name(const char * const pstr, _type * const ptr, const _type minValue, const _type maxValue) { \ + _menu_action_setting_edit_ ## _name(pstr, ptr, minValue, maxValue); \ + currentScreen = menu_edit_ ## _name; \ + } \ + void menu_action_setting_edit_callback_ ## _name(const char * const pstr, _type * const ptr, const _type minValue, const _type maxValue, const screenFunc_t callback, const bool live) { \ + _menu_action_setting_edit_ ## _name(pstr, ptr, minValue, maxValue); \ + currentScreen = menu_edit_callback_ ## _name; \ + callbackFunc = callback; \ + liveEdit = live; \ + } \ + typedef void _name + + DEFINE_MENU_EDIT_TYPE(int16_t, int3, itostr3, 1); + DEFINE_MENU_EDIT_TYPE(uint8_t, int8, i8tostr3, 1); + DEFINE_MENU_EDIT_TYPE(float, float3, ftostr3, 1.0); + DEFINE_MENU_EDIT_TYPE(float, float32, ftostr32, 100.0); + DEFINE_MENU_EDIT_TYPE(float, float43, ftostr43sign, 1000.0); + DEFINE_MENU_EDIT_TYPE(float, float5, ftostr5rj, 0.01); + DEFINE_MENU_EDIT_TYPE(float, float51, ftostr51sign, 10.0); + DEFINE_MENU_EDIT_TYPE(float, float52, ftostr52sign, 100.0); + DEFINE_MENU_EDIT_TYPE(float, float62, ftostr62rj, 100.0); + DEFINE_MENU_EDIT_TYPE(uint32_t, long5, ftostr5rj, 0.01); + + /** + * + * Handlers for Keypad input + * + */ + #if ENABLED(ADC_KEYPAD) + + inline bool handle_adc_keypad() { + static uint8_t adc_steps = 0; + if (buttons_reprapworld_keypad) { + if (adc_steps < 20) ++adc_steps; + lcd_quick_feedback(); + lcdDrawUpdate = LCDVIEW_REDRAW_NOW; + if (encoderDirection == -1) { // side effect which signals we are inside a menu + if (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_DOWN) encoderPosition -= ENCODER_STEPS_PER_MENU_ITEM; + else if (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_UP) encoderPosition += ENCODER_STEPS_PER_MENU_ITEM; + else if (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_LEFT) menu_action_back(); + else if (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_RIGHT) lcd_return_to_status(); + } + else { + const int8_t step = adc_steps > 19 ? 100 : adc_steps > 10 ? 10 : 1; + if (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_DOWN) encoderPosition += ENCODER_PULSES_PER_STEP * step; + else if (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_UP) encoderPosition -= ENCODER_PULSES_PER_STEP * step; + else if (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_RIGHT) encoderPosition = 0; + } + #if ENABLED(ADC_KEYPAD_DEBUG) + SERIAL_PROTOCOLLNPAIR("buttons_reprapworld_keypad = ", (uint32_t)buttons_reprapworld_keypad); + SERIAL_PROTOCOLLNPAIR("encoderPosition = ", (uint32_t)encoderPosition); + #endif + return true; + } + else if (!thermalManager.current_ADCKey_raw) + adc_steps = 0; // reset stepping acceleration + + return false; + } + + #elif ENABLED(REPRAPWORLD_KEYPAD) + + void _reprapworld_keypad_move(const AxisEnum axis, const int16_t dir) { + move_menu_scale = REPRAPWORLD_KEYPAD_MOVE_STEP; + encoderPosition = dir; + switch (axis) { + case X_AXIS: lcd_move_x(); break; + case Y_AXIS: lcd_move_y(); break; + case Z_AXIS: lcd_move_z(); + default: break; + } + } + void reprapworld_keypad_move_z_up() { _reprapworld_keypad_move(Z_AXIS, 1); } + void reprapworld_keypad_move_z_down() { _reprapworld_keypad_move(Z_AXIS, -1); } + void reprapworld_keypad_move_x_left() { _reprapworld_keypad_move(X_AXIS, -1); } + void reprapworld_keypad_move_x_right() { _reprapworld_keypad_move(X_AXIS, 1); } + void reprapworld_keypad_move_y_up() { _reprapworld_keypad_move(Y_AXIS, -1); } + void reprapworld_keypad_move_y_down() { _reprapworld_keypad_move(Y_AXIS, 1); } + void reprapworld_keypad_move_home() { enqueue_and_echo_commands_P(PSTR("G28")); } // move all axes home and wait + void reprapworld_keypad_move_menu() { lcd_goto_screen(lcd_move_menu); } + + inline void handle_reprapworld_keypad() { + + static uint8_t keypad_debounce = 0; + + if (!REPRAPWORLD_KEYPAD_PRESSED) { + if (keypad_debounce > 0) keypad_debounce--; + } + else if (!keypad_debounce) { + keypad_debounce = 2; + + if (REPRAPWORLD_KEYPAD_MOVE_MENU) reprapworld_keypad_move_menu(); + + #if DISABLED(DELTA) && Z_HOME_DIR == -1 + if (REPRAPWORLD_KEYPAD_MOVE_Z_UP) reprapworld_keypad_move_z_up(); + #endif + + if (axis_homed[X_AXIS] && axis_homed[Y_AXIS] && axis_homed[Z_AXIS]) { + #if ENABLED(DELTA) || Z_HOME_DIR != -1 + if (REPRAPWORLD_KEYPAD_MOVE_Z_UP) reprapworld_keypad_move_z_up(); + #endif + if (REPRAPWORLD_KEYPAD_MOVE_Z_DOWN) reprapworld_keypad_move_z_down(); + if (REPRAPWORLD_KEYPAD_MOVE_X_LEFT) reprapworld_keypad_move_x_left(); + if (REPRAPWORLD_KEYPAD_MOVE_X_RIGHT) reprapworld_keypad_move_x_right(); + if (REPRAPWORLD_KEYPAD_MOVE_Y_DOWN) reprapworld_keypad_move_y_down(); + if (REPRAPWORLD_KEYPAD_MOVE_Y_UP) reprapworld_keypad_move_y_up(); + } + else { + if (REPRAPWORLD_KEYPAD_MOVE_HOME) reprapworld_keypad_move_home(); + } + } + } + + #endif // REPRAPWORLD_KEYPAD + + /** + * + * Menu actions + * + */ + void _menu_action_back() { lcd_goto_previous_menu(); } + void menu_action_submenu(screenFunc_t func) { lcd_save_previous_screen(); lcd_goto_screen(func); } + void menu_action_gcode(const char* pgcode) { enqueue_and_echo_commands_P(pgcode); } + void menu_action_function(screenFunc_t func) { (*func)(); } + + #if ENABLED(SDSUPPORT) + + void menu_action_sdfile(const char* filename, char* longFilename) { + UNUSED(longFilename); + card.openAndPrintFile(filename); + lcd_return_to_status(); + } + + void menu_action_sddirectory(const char* filename, char* longFilename) { + UNUSED(longFilename); + card.chdir(filename); + encoderPosition = 0; + screen_changed = true; + lcdDrawUpdate = LCDVIEW_CLEAR_CALL_REDRAW; + } + + #endif // SDSUPPORT + + void menu_action_setting_edit_bool(const char* pstr, bool* ptr) { UNUSED(pstr); *ptr ^= true; lcdDrawUpdate = LCDVIEW_CLEAR_CALL_REDRAW; } + void menu_action_setting_edit_callback_bool(const char* pstr, bool* ptr, screenFunc_t callback) { + menu_action_setting_edit_bool(pstr, ptr); + (*callback)(); + } + +#endif // ULTIPANEL + +void lcd_init() { + + lcd_implementation_init( + #if ENABLED(LCD_PROGRESS_BAR) + true + #endif + ); + + #if ENABLED(NEWPANEL) + #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 ENABLED(REPRAPWORLD_KEYPAD) && DISABLED(ADC_KEYPAD) + SET_OUTPUT(SHIFT_CLK); + OUT_WRITE(SHIFT_LD, HIGH); + SET_INPUT_PULLUP(SHIFT_OUT); + #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 + + #else // !NEWPANEL + + #if ENABLED(SR_LCD_2W_NL) // Non latching 2 wire shift register + SET_OUTPUT(SR_DATA_PIN); + SET_OUTPUT(SR_CLK_PIN); + #elif defined(SHIFT_CLK) + SET_OUTPUT(SHIFT_CLK); + OUT_WRITE(SHIFT_LD, HIGH); + OUT_WRITE(SHIFT_EN, LOW); + SET_INPUT_PULLUP(SHIFT_OUT); + #endif // SR_LCD_2W_NL + + #endif // !NEWPANEL + + #if ENABLED(SDSUPPORT) && PIN_EXISTS(SD_DETECT) + SET_INPUT_PULLUP(SD_DETECT_PIN); + lcd_sd_status = 2; // UNKNOWN + #endif + + #if ENABLED(LCD_HAS_SLOW_BUTTONS) + slow_buttons = 0; + #endif + + lcd_buttons_update(); + + #if ENABLED(ULTIPANEL) + encoderDiff = 0; + #endif +} + +int16_t lcd_strlen(const char* s) { + int16_t i = 0, j = 0; + while (s[i]) { + if (PRINTABLE(s[i])) j++; + i++; + } + return j; +} + +int16_t lcd_strlen_P(const char* s) { + int16_t j = 0; + while (pgm_read_byte(s)) { + if (PRINTABLE(pgm_read_byte(s))) j++; + s++; + } + return j; +} + +bool lcd_blink() { + static uint8_t blink = 0; + static millis_t next_blink_ms = 0; + millis_t ms = millis(); + if (ELAPSED(ms, next_blink_ms)) { + blink ^= 0xFF; + next_blink_ms = ms + 1000 - LCD_UPDATE_INTERVAL / 2; + } + return blink != 0; +} + +/** + * Update the LCD, read encoder buttons, etc. + * - Read button states + * - Check the SD Card slot state + * - Act on RepRap World keypad input + * - Update the encoder position + * - Apply acceleration to the encoder position + * - Set lcdDrawUpdate = LCDVIEW_CALL_REDRAW_NOW on controller events + * - Reset the Info Screen timeout if there's any input + * - Update status indicators, if any + * + * Run the current LCD menu handler callback function: + * - Call the handler only if lcdDrawUpdate != LCDVIEW_NONE + * - Before calling the handler, LCDVIEW_CALL_NO_REDRAW => LCDVIEW_NONE + * - Call the menu handler. Menu handlers should do the following: + * - If a value changes, set lcdDrawUpdate to LCDVIEW_REDRAW_NOW and draw the value + * (Encoder events automatically set lcdDrawUpdate for you.) + * - if (lcdDrawUpdate) { redraw } + * - Before exiting the handler set lcdDrawUpdate to: + * - LCDVIEW_CLEAR_CALL_REDRAW to clear screen and set LCDVIEW_CALL_REDRAW_NEXT. + * - LCDVIEW_REDRAW_NOW to draw now (including remaining stripes). + * - LCDVIEW_CALL_REDRAW_NEXT to draw now and get LCDVIEW_REDRAW_NOW on the next loop. + * - LCDVIEW_CALL_NO_REDRAW to draw now and get LCDVIEW_NONE on the next loop. + * - NOTE: For graphical displays menu handlers may be called 2 or more times per loop, + * so don't change lcdDrawUpdate without considering this. + * + * After the menu handler callback runs (or not): + * - Clear the LCD if lcdDrawUpdate == LCDVIEW_CLEAR_CALL_REDRAW + * - Update lcdDrawUpdate for the next loop (i.e., move one state down, usually) + * + * No worries. This function is only called from the main thread. + */ +void lcd_update() { + + #if ENABLED(ULTIPANEL) + static millis_t return_to_status_ms = 0; + manage_manual_move(); + + lcd_buttons_update(); + + #if ENABLED(AUTO_BED_LEVELING_UBL) + const bool UBL_CONDITION = !ubl.has_control_of_lcd_panel; + #else + constexpr bool UBL_CONDITION = true; + #endif + + // If the action button is pressed... + if (UBL_CONDITION && LCD_CLICKED) { + 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; // Keep the click if not waiting for a user-click + wait_for_user = false; // Any click clears wait for user + lcd_quick_feedback(); // Always make a click sound + } + } + else wait_for_unclick = false; + #endif + + #if ENABLED(SDSUPPORT) && PIN_EXISTS(SD_DETECT) + + const bool sd_status = IS_SD_INSERTED; + if (sd_status != lcd_sd_status && lcd_detected()) { + + if (sd_status) { + card.initsd(); + if (lcd_sd_status != 2) LCD_MESSAGEPGM(MSG_SD_INSERTED); + } + else { + card.release(); + if (lcd_sd_status != 2) LCD_MESSAGEPGM(MSG_SD_REMOVED); + } + + lcd_sd_status = sd_status; + lcdDrawUpdate = LCDVIEW_CLEAR_CALL_REDRAW; + lcd_implementation_init( // to maybe revive the LCD if static electricity killed it. + #if ENABLED(LCD_PROGRESS_BAR) + currentScreen == lcd_status_screen + #endif + ); + } + + #endif // SDSUPPORT && SD_DETECT_PIN + + const millis_t ms = millis(); + if (ELAPSED(ms, next_lcd_update_ms) + #if ENABLED(DOGLCD) + || drawing_screen + #endif + ) { + + next_lcd_update_ms = ms + LCD_UPDATE_INTERVAL; + + #if ENABLED(LCD_HAS_STATUS_INDICATORS) + lcd_implementation_update_indicators(); + #endif + + #if ENABLED(ULTIPANEL) + + #if ENABLED(LCD_HAS_SLOW_BUTTONS) + slow_buttons = lcd_implementation_read_slow_buttons(); // buttons which take too long to read in interrupt context + #endif + + #if ENABLED(ADC_KEYPAD) + + if (handle_adc_keypad()) + return_to_status_ms = ms + LCD_TIMEOUT_TO_STATUS; + + #elif ENABLED(REPRAPWORLD_KEYPAD) + + handle_reprapworld_keypad(); + + #endif + + bool encoderPastThreshold = (abs(encoderDiff) >= ENCODER_PULSES_PER_STEP); + if (encoderPastThreshold || lcd_clicked) { + if (encoderPastThreshold) { + int32_t encoderMultiplier = 1; + + #if ENABLED(ENCODER_RATE_MULTIPLIER) + + if (encoderRateMultiplierEnabled) { + int32_t encoderMovementSteps = abs(encoderDiff) / ENCODER_PULSES_PER_STEP; + + if (lastEncoderMovementMillis) { + // Note that the rate is always calculated between two passes through the + // loop and that the abs of the encoderDiff value is tracked. + float encoderStepRate = float(encoderMovementSteps) / float(ms - lastEncoderMovementMillis) * 1000.0; + + if (encoderStepRate >= ENCODER_100X_STEPS_PER_SEC) encoderMultiplier = 100; + else if (encoderStepRate >= ENCODER_10X_STEPS_PER_SEC) encoderMultiplier = 10; + + #if ENABLED(ENCODER_RATE_MULTIPLIER_DEBUG) + SERIAL_ECHO_START(); + SERIAL_ECHOPAIR("Enc Step Rate: ", encoderStepRate); + SERIAL_ECHOPAIR(" Multiplier: ", encoderMultiplier); + SERIAL_ECHOPAIR(" ENCODER_10X_STEPS_PER_SEC: ", ENCODER_10X_STEPS_PER_SEC); + SERIAL_ECHOPAIR(" ENCODER_100X_STEPS_PER_SEC: ", ENCODER_100X_STEPS_PER_SEC); + SERIAL_EOL(); + #endif // ENCODER_RATE_MULTIPLIER_DEBUG + } + + lastEncoderMovementMillis = ms; + } // encoderRateMultiplierEnabled + #endif // ENCODER_RATE_MULTIPLIER + + encoderPosition += (encoderDiff * encoderMultiplier) / ENCODER_PULSES_PER_STEP; + encoderDiff = 0; + } + return_to_status_ms = ms + LCD_TIMEOUT_TO_STATUS; + lcdDrawUpdate = LCDVIEW_REDRAW_NOW; + } + #endif // ULTIPANEL + + // We arrive here every ~100ms when idling often enough. + // Instead of tracking the changes simply redraw the Info Screen ~1 time a second. + static int8_t lcd_status_update_delay = 1; // first update one loop delayed + if ( + #if ENABLED(ULTIPANEL) + currentScreen == lcd_status_screen && + #endif + !lcd_status_update_delay-- + ) { + lcd_status_update_delay = 9 + #if ENABLED(DOGLCD) + + 3 + #endif + ; + max_display_update_time--; + lcdDrawUpdate = LCDVIEW_REDRAW_NOW; + } + + // then we want to use 1/2 of the time only. + uint16_t bbr2 = planner.block_buffer_runtime() >> 1; + + #if ENABLED(DOGLCD) + if ((lcdDrawUpdate || drawing_screen) && (!bbr2 || (bbr2 > max_display_update_time))) + #else + if (lcdDrawUpdate && (!bbr2 || (bbr2 > max_display_update_time))) + #endif + { + #if ENABLED(DOGLCD) + if (!drawing_screen) + #endif + { + switch (lcdDrawUpdate) { + case LCDVIEW_CALL_NO_REDRAW: + lcdDrawUpdate = LCDVIEW_NONE; + break; + case LCDVIEW_CLEAR_CALL_REDRAW: // set by handlers, then altered after (rarely occurs here) + case LCDVIEW_CALL_REDRAW_NEXT: // set by handlers, then altered after (never occurs here?) + lcdDrawUpdate = LCDVIEW_REDRAW_NOW; + case LCDVIEW_REDRAW_NOW: // set above, or by a handler through LCDVIEW_CALL_REDRAW_NEXT + case LCDVIEW_NONE: + break; + } // switch + } + + #if ENABLED(ADC_KEYPAD) + buttons_reprapworld_keypad = 0; + #endif + + #if ENABLED(ULTIPANEL) + #define CURRENTSCREEN() (*currentScreen)(), lcd_clicked = false + #else + #define CURRENTSCREEN() lcd_status_screen() + #endif + + #if ENABLED(DOGLCD) // Changes due to different driver architecture of the DOGM display + if (!drawing_screen) { + u8g.firstPage(); + drawing_screen = 1; + } + lcd_setFont(FONT_MENU); + u8g.setColorIndex(1); + CURRENTSCREEN(); + if (drawing_screen && (drawing_screen = u8g.nextPage())) { + NOLESS(max_display_update_time, millis() - ms); + return; + } + #else + CURRENTSCREEN(); + #endif + NOLESS(max_display_update_time, millis() - ms); + } + + #if ENABLED(ULTIPANEL) + + // Return to Status Screen after a timeout + if (currentScreen == lcd_status_screen || defer_return_to_status) + return_to_status_ms = ms + LCD_TIMEOUT_TO_STATUS; + else if (ELAPSED(ms, return_to_status_ms)) + lcd_return_to_status(); + + #endif // ULTIPANEL + + #if ENABLED(DOGLCD) + if (!drawing_screen) + #endif + { + switch (lcdDrawUpdate) { + case LCDVIEW_CLEAR_CALL_REDRAW: + lcd_implementation_clear(); + case LCDVIEW_CALL_REDRAW_NEXT: + lcdDrawUpdate = LCDVIEW_REDRAW_NOW; + break; + case LCDVIEW_REDRAW_NOW: + lcdDrawUpdate = LCDVIEW_NONE; + break; + case LCDVIEW_NONE: + break; + } // switch + } + } // ELAPSED(ms, next_lcd_update_ms) +} + +void pad_message_string() { + uint8_t i = 0, j = 0; + char c; + while ((c = lcd_status_message[i]) && j < LCD_WIDTH) { + if (PRINTABLE(c)) j++; + i++; + } + if (true + #if ENABLED(STATUS_MESSAGE_SCROLLING) + && j < LCD_WIDTH + #endif + ) { + // pad with spaces to fill up the line + while (j++ < LCD_WIDTH) lcd_status_message[i++] = ' '; + // chop off at the edge + lcd_status_message[i] = '\0'; + } +} + +void lcd_finishstatus(const bool persist=false) { + + pad_message_string(); + + #if !(ENABLED(LCD_PROGRESS_BAR) && (PROGRESS_MSG_EXPIRE > 0)) + UNUSED(persist); + #endif + + #if ENABLED(LCD_PROGRESS_BAR) + progress_bar_ms = millis(); + #if PROGRESS_MSG_EXPIRE > 0 + expire_status_ms = persist ? 0 : progress_bar_ms + PROGRESS_MSG_EXPIRE; + #endif + #endif + lcdDrawUpdate = LCDVIEW_CLEAR_CALL_REDRAW; + + #if ENABLED(FILAMENT_LCD_DISPLAY) && ENABLED(SDSUPPORT) + previous_lcd_status_ms = millis(); //get status message to show up for a while + #endif + + #if ENABLED(STATUS_MESSAGE_SCROLLING) + status_scroll_pos = 0; + #endif +} + +#if ENABLED(LCD_PROGRESS_BAR) && PROGRESS_MSG_EXPIRE > 0 + void dontExpireStatus() { expire_status_ms = 0; } +#endif + +bool lcd_hasstatus() { return (lcd_status_message[0] != '\0'); } + +void lcd_setstatus(const char * const message, const bool persist) { + if (lcd_status_message_level > 0) return; + strncpy(lcd_status_message, message, 3 * (LCD_WIDTH)); + lcd_finishstatus(persist); +} + +void lcd_setstatusPGM(const char * const message, int8_t level) { + if (level < 0) level = lcd_status_message_level = 0; + if (level < lcd_status_message_level) return; + lcd_status_message_level = level; + strncpy_P(lcd_status_message, message, 3 * (LCD_WIDTH)); + lcd_finishstatus(level > 0); +} + +void lcd_status_printf_P(const uint8_t level, const char * const fmt, ...) { + if (level < lcd_status_message_level) return; + lcd_status_message_level = level; + va_list args; + va_start(args, fmt); + vsnprintf_P(lcd_status_message, 3 * (LCD_WIDTH), fmt, args); + va_end(args); + lcd_finishstatus(level > 0); +} + +void lcd_setalertstatusPGM(const char * const message) { + lcd_setstatusPGM(message, 1); + #if ENABLED(ULTIPANEL) + lcd_return_to_status(); + #endif +} + +void lcd_reset_alert_level() { lcd_status_message_level = 0; } + +#if HAS_LCD_CONTRAST + + void set_lcd_contrast(const uint16_t value) { + lcd_contrast = constrain(value, LCD_CONTRAST_MIN, LCD_CONTRAST_MAX); + u8g.setContrast(lcd_contrast); + } + +#endif + +#if ENABLED(ULTIPANEL) + + /** + * 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 + */ + #if defined(EN_A) && defined(EN_B) + #define encrot0 0 + #define encrot1 2 + #define encrot2 3 + #define encrot3 1 + #endif + + #define GET_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 + + + /** + * Read encoder buttons from the hardware registers + * Warning: This function is called from interrupt context! + */ + void lcd_buttons_update() { + static uint8_t lastEncoderBits; + millis_t now = millis(); + if (ELAPSED(now, next_button_update_ms)) { + + #if ENABLED(NEWPANEL) + 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 LCD_HAS_DIRECTIONAL_BUTTONS + + // Manage directional buttons + #if ENABLED(REVERSE_MENU_DIRECTION) + #define _ENCODER_UD_STEPS (ENCODER_STEPS_PER_MENU_ITEM * encoderDirection) + #else + #define _ENCODER_UD_STEPS ENCODER_STEPS_PER_MENU_ITEM + #endif + #if ENABLED(REVERSE_ENCODER_DIRECTION) + #define ENCODER_UD_STEPS _ENCODER_UD_STEPS + #define ENCODER_LR_PULSES ENCODER_PULSES_PER_STEP + #else + #define ENCODER_UD_STEPS -(_ENCODER_UD_STEPS) + #define ENCODER_LR_PULSES -(ENCODER_PULSES_PER_STEP) + #endif + + if (false) { + // for the else-ifs below + } + #if BUTTON_EXISTS(UP) + else if (BUTTON_PRESSED(UP)) { + encoderDiff = -(ENCODER_UD_STEPS); + next_button_update_ms = now + 300; + } + #endif + #if BUTTON_EXISTS(DWN) + else if (BUTTON_PRESSED(DWN)) { + encoderDiff = ENCODER_UD_STEPS; + next_button_update_ms = now + 300; + } + #endif + #if BUTTON_EXISTS(LFT) + else if (BUTTON_PRESSED(LFT)) { + encoderDiff = -(ENCODER_LR_PULSES); + next_button_update_ms = now + 300; + } + #endif + #if BUTTON_EXISTS(RT) + else if (BUTTON_PRESSED(RT)) { + encoderDiff = ENCODER_LR_PULSES; + next_button_update_ms = now + 300; + } + #endif + + #endif // LCD_HAS_DIRECTIONAL_BUTTONS + + buttons = newbutton; + #if ENABLED(LCD_HAS_SLOW_BUTTONS) + buttons |= slow_buttons; + #endif + + #if ENABLED(ADC_KEYPAD) + + uint8_t newbutton_reprapworld_keypad = 0; + buttons = 0; + if (buttons_reprapworld_keypad == 0) { + newbutton_reprapworld_keypad = get_ADC_keyValue(); + if (WITHIN(newbutton_reprapworld_keypad, 1, 8)) + buttons_reprapworld_keypad = _BV(newbutton_reprapworld_keypad - 1); + } + + #elif ENABLED(REPRAPWORLD_KEYPAD) + + GET_BUTTON_STATES(buttons_reprapworld_keypad); + + #endif + + #else + GET_BUTTON_STATES(buttons); + #endif // !NEWPANEL + + } // next_button_update_ms + + // Manage encoder rotation + #if ENABLED(REVERSE_MENU_DIRECTION) && ENABLED(REVERSE_ENCODER_DIRECTION) + #define ENCODER_DIFF_CW (encoderDiff -= encoderDirection) + #define ENCODER_DIFF_CCW (encoderDiff += encoderDirection) + #elif ENABLED(REVERSE_MENU_DIRECTION) + #define ENCODER_DIFF_CW (encoderDiff += encoderDirection) + #define ENCODER_DIFF_CCW (encoderDiff -= encoderDirection) + #elif ENABLED(REVERSE_ENCODER_DIRECTION) + #define ENCODER_DIFF_CW (encoderDiff--) + #define ENCODER_DIFF_CCW (encoderDiff++) + #else + #define ENCODER_DIFF_CW (encoderDiff++) + #define ENCODER_DIFF_CCW (encoderDiff--) + #endif + #define ENCODER_SPIN(_E1, _E2) switch (lastEncoderBits) { case _E1: ENCODER_DIFF_CW; break; case _E2: ENCODER_DIFF_CCW; } + + uint8_t enc = 0; + if (buttons & EN_A) enc |= B01; + if (buttons & EN_B) enc |= B10; + if (enc != lastEncoderBits) { + switch (enc) { + case encrot0: ENCODER_SPIN(encrot3, encrot1); break; + case encrot1: ENCODER_SPIN(encrot0, encrot2); break; + case encrot2: ENCODER_SPIN(encrot1, encrot3); break; + case encrot3: ENCODER_SPIN(encrot2, encrot0); break; + } + #if ENABLED(AUTO_BED_LEVELING_UBL) + if (ubl.has_control_of_lcd_panel) { + ubl.encoder_diff = encoderDiff; // Make the encoder's rotation available to G29's Mesh Editor + encoderDiff = 0; // We are going to lie to the LCD Panel and claim the encoder + // knob has not turned. + } + #endif + lastEncoderBits = enc; + } + } + + #if (ENABLED(LCD_I2C_TYPE_MCP23017) || ENABLED(LCD_I2C_TYPE_MCP23008)) && ENABLED(DETECT_DEVICE) + bool lcd_detected() { return lcd.LcdDetected() == 1; } + #else + bool lcd_detected() { return true; } + #endif + + #if ENABLED(AUTO_BED_LEVELING_UBL) + + void chirp_at_user() { + #if ENABLED(LCD_USE_I2C_BUZZER) + lcd.buzz(LCD_FEEDBACK_FREQUENCY_DURATION_MS, LCD_FEEDBACK_FREQUENCY_HZ); + #elif PIN_EXISTS(BEEPER) + buzzer.tone(LCD_FEEDBACK_FREQUENCY_DURATION_MS, LCD_FEEDBACK_FREQUENCY_HZ); + #endif + } + + bool ubl_lcd_clicked() { return LCD_CLICKED; } + + #endif + +#endif // ULTIPANEL + +#if ENABLED(ADC_KEYPAD) + + typedef struct { + uint16_t ADCKeyValueMin, ADCKeyValueMax; + uint8_t ADCKeyNo; + } _stADCKeypadTable_; + + static const _stADCKeypadTable_ stADCKeyTable[] PROGMEM = { + // VALUE_MIN, VALUE_MAX, KEY + { 4000, 4096, BLEN_REPRAPWORLD_KEYPAD_F1 + 1 }, // F1 + { 4000, 4096, BLEN_REPRAPWORLD_KEYPAD_F2 + 1 }, // F2 + { 4000, 4096, BLEN_REPRAPWORLD_KEYPAD_F3 + 1 }, // F3 + { 300, 500, BLEN_REPRAPWORLD_KEYPAD_LEFT + 1 }, // LEFT + { 1900, 2200, BLEN_REPRAPWORLD_KEYPAD_RIGHT + 1 }, // RIGHT + { 570, 870, BLEN_REPRAPWORLD_KEYPAD_UP + 1 }, // UP + { 2670, 2870, BLEN_REPRAPWORLD_KEYPAD_DOWN + 1 }, // DOWN + { 1150, 1450, BLEN_REPRAPWORLD_KEYPAD_MIDDLE + 1 }, // ENTER + }; + + uint8_t get_ADC_keyValue(void) { + if (thermalManager.ADCKey_count >= 16) { + const uint16_t currentkpADCValue = thermalManager.current_ADCKey_raw >> 2; + #if ENABLED(ADC_KEYPAD_DEBUG) + SERIAL_PROTOCOLLN(currentkpADCValue); + #endif + thermalManager.current_ADCKey_raw = 0; + thermalManager.ADCKey_count = 0; + if (currentkpADCValue < 4000) + for (uint8_t i = 0; i < ADC_KEY_NUM; i++) { + 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); + } + } + return 0; + } +#endif + +#endif // ULTRA_LCD diff --git a/trunk/Arduino/Marlin_1.1.6/ultralcd.h b/trunk/Arduino/Marlin_1.1.6/ultralcd.h new file mode 100644 index 00000000..0a50f173 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/ultralcd.h @@ -0,0 +1,204 @@ +/** + * 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 . + * + */ + +#ifndef ULTRALCD_H +#define ULTRALCD_H + +#include "Marlin.h" + +#if ENABLED(ULTRA_LCD) + + #define BUTTON_EXISTS(BN) (defined(BTN_## BN) && BTN_## BN >= 0) + #define BUTTON_PRESSED(BN) !READ(BTN_## BN) + + extern int16_t lcd_preheat_hotend_temp[2], lcd_preheat_bed_temp[2], lcd_preheat_fan_speed[2]; + + int16_t lcd_strlen(const char* s); + int16_t lcd_strlen_P(const char* s); + void lcd_update(); + void lcd_init(); + bool lcd_hasstatus(); + void lcd_setstatus(const char* message, const bool persist=false); + void lcd_setstatusPGM(const char* message, const int8_t level=0); + void lcd_setalertstatusPGM(const char* message); + void lcd_status_printf_P(const uint8_t level, const char * const fmt, ...); + void lcd_reset_alert_level(); + void lcd_kill_screen(); + void kill_screen(const char* lcd_msg); + bool lcd_detected(void); + + extern uint8_t lcdDrawUpdate; + inline void lcd_refresh() { lcdDrawUpdate = LCDVIEW_CLEAR_CALL_REDRAW; } + + #if HAS_BUZZER + void lcd_buzz(long duration, uint16_t freq); + #endif + + #if ENABLED(LCD_PROGRESS_BAR) && PROGRESS_MSG_EXPIRE > 0 + void dontExpireStatus(); + #endif + + #if ENABLED(ADC_KEYPAD) + uint8_t get_ADC_keyValue(); + #endif + + #if ENABLED(DOGLCD) + extern uint16_t lcd_contrast; + void set_lcd_contrast(const uint16_t value); + #endif + + #if ENABLED(SHOW_BOOTSCREEN) + void lcd_bootscreen(); + #endif + + #define LCD_UPDATE_INTERVAL 100 + + #if ENABLED(ULTIPANEL) + + #define BLEN_A 0 + #define BLEN_B 1 + // Encoder click is directly connected + #if BUTTON_EXISTS(ENC) + #define BLEN_C 2 + #endif + #define EN_A (_BV(BLEN_A)) + #define EN_B (_BV(BLEN_B)) + #define EN_C (_BV(BLEN_C)) + + extern volatile uint8_t buttons; // The last-checked buttons in a bit array. + void lcd_buttons_update(); + void lcd_quick_feedback(); // Audible feedback for a button click - could also be visual + void lcd_completion_feedback(const bool good=true); + + #if ENABLED(ADVANCED_PAUSE_FEATURE) + void lcd_advanced_pause_show_message(const AdvancedPauseMessage message); + #endif // ADVANCED_PAUSE_FEATURE + + #else + + inline void lcd_buttons_update() {} + + #endif + + #if ENABLED(FILAMENT_LCD_DISPLAY) && ENABLED(SDSUPPORT) + extern millis_t previous_lcd_status_ms; + #endif + + bool lcd_blink(); + + #if ENABLED(REPRAPWORLD_KEYPAD) // is also ULTIPANEL and NEWPANEL + + #define REPRAPWORLD_BTN_OFFSET 0 // bit offset into buttons for shift register values + + #define BLEN_REPRAPWORLD_KEYPAD_F3 0 + #define BLEN_REPRAPWORLD_KEYPAD_F2 1 + #define BLEN_REPRAPWORLD_KEYPAD_F1 2 + #define BLEN_REPRAPWORLD_KEYPAD_DOWN 3 + #define BLEN_REPRAPWORLD_KEYPAD_RIGHT 4 + #define BLEN_REPRAPWORLD_KEYPAD_MIDDLE 5 + #define BLEN_REPRAPWORLD_KEYPAD_UP 6 + #define BLEN_REPRAPWORLD_KEYPAD_LEFT 7 + + #define EN_REPRAPWORLD_KEYPAD_F3 (_BV(REPRAPWORLD_BTN_OFFSET + BLEN_REPRAPWORLD_KEYPAD_F3)) + #define EN_REPRAPWORLD_KEYPAD_F2 (_BV(REPRAPWORLD_BTN_OFFSET + BLEN_REPRAPWORLD_KEYPAD_F2)) + #define EN_REPRAPWORLD_KEYPAD_F1 (_BV(REPRAPWORLD_BTN_OFFSET + BLEN_REPRAPWORLD_KEYPAD_F1)) + #define EN_REPRAPWORLD_KEYPAD_DOWN (_BV(REPRAPWORLD_BTN_OFFSET + BLEN_REPRAPWORLD_KEYPAD_DOWN)) + #define EN_REPRAPWORLD_KEYPAD_RIGHT (_BV(REPRAPWORLD_BTN_OFFSET + BLEN_REPRAPWORLD_KEYPAD_RIGHT)) + #define EN_REPRAPWORLD_KEYPAD_MIDDLE (_BV(REPRAPWORLD_BTN_OFFSET + BLEN_REPRAPWORLD_KEYPAD_MIDDLE)) + #define EN_REPRAPWORLD_KEYPAD_UP (_BV(REPRAPWORLD_BTN_OFFSET + BLEN_REPRAPWORLD_KEYPAD_UP)) + #define EN_REPRAPWORLD_KEYPAD_LEFT (_BV(REPRAPWORLD_BTN_OFFSET + BLEN_REPRAPWORLD_KEYPAD_LEFT)) + + #define REPRAPWORLD_KEYPAD_MOVE_Z_DOWN (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_F3) + #define REPRAPWORLD_KEYPAD_MOVE_Z_UP (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_F2) + #define REPRAPWORLD_KEYPAD_MOVE_MENU (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_F1) + #define REPRAPWORLD_KEYPAD_MOVE_Y_DOWN (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_DOWN) + #define REPRAPWORLD_KEYPAD_MOVE_X_RIGHT (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_RIGHT) + #define REPRAPWORLD_KEYPAD_MOVE_HOME (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_MIDDLE) + #define REPRAPWORLD_KEYPAD_MOVE_Y_UP (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_UP) + #define REPRAPWORLD_KEYPAD_MOVE_X_LEFT (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_LEFT) + + #if ENABLED(ADC_KEYPAD) + #define REPRAPWORLD_KEYPAD_MOVE_HOME (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_F1) + #define KEYPAD_EN_C EN_REPRAPWORLD_KEYPAD_MIDDLE + #else + #define REPRAPWORLD_KEYPAD_MOVE_HOME (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_MIDDLE) + #define KEYPAD_EN_C EN_REPRAPWORLD_KEYPAD_F1 + #endif + #define REPRAPWORLD_KEYPAD_MOVE_MENU (buttons_reprapworld_keypad & KEYPAD_EN_C) + + #if BUTTON_EXISTS(ENC) + #define LCD_CLICKED ((buttons & EN_C) || REPRAPWORLD_KEYPAD_MOVE_MENU) + #else + #define LCD_CLICKED REPRAPWORLD_KEYPAD_MOVE_MENU + #endif + + #define REPRAPWORLD_KEYPAD_PRESSED (buttons_reprapworld_keypad & ( \ + EN_REPRAPWORLD_KEYPAD_F3 | \ + EN_REPRAPWORLD_KEYPAD_F2 | \ + EN_REPRAPWORLD_KEYPAD_F1 | \ + EN_REPRAPWORLD_KEYPAD_DOWN | \ + EN_REPRAPWORLD_KEYPAD_RIGHT | \ + EN_REPRAPWORLD_KEYPAD_MIDDLE | \ + EN_REPRAPWORLD_KEYPAD_UP | \ + EN_REPRAPWORLD_KEYPAD_LEFT) \ + ) + + #elif ENABLED(NEWPANEL) + #define LCD_CLICKED (buttons & EN_C) + #else + #define LCD_CLICKED false + #endif + +#else // no LCD + + inline void lcd_update() {} + inline void lcd_init() {} + inline bool lcd_hasstatus() { return false; } + inline void lcd_setstatus(const char* const message, const bool persist=false) { UNUSED(message); UNUSED(persist); } + inline void lcd_setstatusPGM(const char* const message, const int8_t level=0) { UNUSED(message); UNUSED(level); } + inline void lcd_setalertstatusPGM(const char* message) { UNUSED(message); } + inline void lcd_status_printf_P(const uint8_t level, const char * const fmt, ...) { UNUSED(level); UNUSED(fmt); } + inline void lcd_buttons_update() {} + inline void lcd_reset_alert_level() {} + inline bool lcd_detected() { return true; } + inline void lcd_refresh() {} + +#endif // ULTRA_LCD + +#define LCD_MESSAGEPGM(x) lcd_setstatusPGM(PSTR(x)) +#define LCD_ALERTMESSAGEPGM(x) lcd_setalertstatusPGM(PSTR(x)) + +void lcd_reset_status(); + +#if ENABLED(AUTO_BED_LEVELING_UBL) + extern bool ubl_lcd_map_control; + void lcd_mesh_edit_setup(float initial); + float lcd_mesh_edit(); + void lcd_z_offset_edit_setup(float); + float lcd_z_offset_edit(); +#endif + +#if ENABLED(DELTA_CALIBRATION_MENU) + float lcd_probe_pt(const float &lx, const float &ly); +#endif + +#endif // ULTRALCD_H diff --git a/trunk/Arduino/Marlin_1.1.6/ultralcd_impl_DOGM.h b/trunk/Arduino/Marlin_1.1.6/ultralcd_impl_DOGM.h new file mode 100644 index 00000000..6f75143a --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/ultralcd_impl_DOGM.h @@ -0,0 +1,1044 @@ +/** + * 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 . + * + */ + +/** + * ultralcd_impl_DOGM.h + * + * Graphics LCD implementation for 128x64 pixel LCDs by STB for ErikZalm/Marlin + * Demonstrator: http://www.reprap.org/wiki/STB_Electronics + * License: http://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 + */ + +#ifndef ULTRALCD_IMPL_DOGM_H +#define ULTRALCD_IMPL_DOGM_H + +#include "MarlinConfig.h" + +/** + * Implementation of the LCD display routines for a DOGM128 graphic display. + * These are common LCD 128x64 pixel graphic displays. + */ +#include "ultralcd.h" + +#if ENABLED(U8GLIB_ST7920) + #include "ultralcd_st7920_u8glib_rrd.h" +#endif + +#if ENABLED(U8GLIB_ST7565_64128N) + #include "ultralcd_st7565_u8glib_VIKI.h" +#endif + +#include "dogm_bitmaps.h" +#include "utility.h" +#include "duration_t.h" + +#include + +#if ENABLED(AUTO_BED_LEVELING_UBL) + #include "ubl.h" +#endif + +#if ENABLED(SHOW_BOOTSCREEN) && ENABLED(SHOW_CUSTOM_BOOTSCREEN) + #include "_Bootscreen.h" +#endif + +// Only Western languages support big / small fonts +#if DISABLED(DISPLAY_CHARSET_ISO10646_1) + #undef USE_BIG_EDIT_FONT + #undef USE_SMALL_INFOFONT +#endif + +#if ENABLED(USE_SMALL_INFOFONT) + #include "dogm_font_data_6x9_marlin.h" + #define FONT_STATUSMENU_NAME u8g_font_6x9 +#else + #define FONT_STATUSMENU_NAME FONT_MENU_NAME +#endif + +#include "dogm_font_data_Marlin_symbols.h" // The Marlin special symbols +#define FONT_SPECIAL_NAME Marlin_symbols + +#if DISABLED(SIMULATE_ROMFONT) + #if ENABLED(DISPLAY_CHARSET_ISO10646_1) + #include "dogm_font_data_ISO10646_1.h" + #define FONT_MENU_NAME ISO10646_1_5x7 + #elif ENABLED(DISPLAY_CHARSET_ISO10646_PL) + #include "dogm_font_data_ISO10646_1_PL.h" + #define FONT_MENU_NAME ISO10646_1_PL_5x7 + #elif ENABLED(DISPLAY_CHARSET_ISO10646_5) + #include "dogm_font_data_ISO10646_5_Cyrillic.h" + #define FONT_MENU_NAME ISO10646_5_Cyrillic_5x7 + #elif ENABLED(DISPLAY_CHARSET_ISO10646_KANA) + #include "dogm_font_data_ISO10646_Kana.h" + #define FONT_MENU_NAME ISO10646_Kana_5x7 + #elif ENABLED(DISPLAY_CHARSET_ISO10646_GREEK) + #include "dogm_font_data_ISO10646_Greek.h" + #define FONT_MENU_NAME ISO10646_Greek_5x7 + #elif ENABLED(DISPLAY_CHARSET_ISO10646_CN) + #include "dogm_font_data_ISO10646_CN.h" + #define FONT_MENU_NAME ISO10646_CN + #define TALL_FONT_CORRECTION 1 + #elif ENABLED(DISPLAY_CHARSET_ISO10646_TR) + #include "dogm_font_data_ISO10646_1_tr.h" + #define FONT_MENU_NAME ISO10646_TR + #elif ENABLED(DISPLAY_CHARSET_ISO10646_CZ) + #include "dogm_font_data_ISO10646_CZ.h" + #define FONT_MENU_NAME ISO10646_CZ + #elif ENABLED(DISPLAY_CHARSET_ISO10646_SK) + #include "dogm_font_data_ISO10646_SK.h" + #define FONT_MENU_NAME ISO10646_SK + #else // fall-back + #include "dogm_font_data_ISO10646_1.h" + #define FONT_MENU_NAME ISO10646_1_5x7 + #endif +#else // SIMULATE_ROMFONT + #if DISPLAY_CHARSET_HD44780 == JAPANESE + #include "dogm_font_data_HD44780_J.h" + #define FONT_MENU_NAME HD44780_J_5x7 + #elif DISPLAY_CHARSET_HD44780 == WESTERN + #include "dogm_font_data_HD44780_W.h" + #define FONT_MENU_NAME HD44780_W_5x7 + #elif DISPLAY_CHARSET_HD44780 == CYRILLIC + #include "dogm_font_data_HD44780_C.h" + #define FONT_MENU_NAME HD44780_C_5x7 + #else // fall-back + #include "dogm_font_data_ISO10646_1.h" + #define FONT_MENU_NAME ISO10646_1_5x7 + #endif +#endif // SIMULATE_ROMFONT + +//#define FONT_STATUSMENU_NAME FONT_MENU_NAME + +#define FONT_STATUSMENU 1 +#define FONT_SPECIAL 2 +#define FONT_MENU_EDIT 3 +#define FONT_MENU 4 + +// DOGM parameters (size in pixels) +#define DOG_CHAR_WIDTH 6 +#define DOG_CHAR_HEIGHT 12 +#if ENABLED(USE_BIG_EDIT_FONT) + #define FONT_MENU_EDIT_NAME u8g_font_9x18 + #define DOG_CHAR_WIDTH_EDIT 9 + #define DOG_CHAR_HEIGHT_EDIT 13 + #define LCD_WIDTH_EDIT 14 +#else + #define FONT_MENU_EDIT_NAME FONT_MENU_NAME + #define DOG_CHAR_WIDTH_EDIT 6 + #define DOG_CHAR_HEIGHT_EDIT 12 + #define LCD_WIDTH_EDIT 22 +#endif + +#ifndef TALL_FONT_CORRECTION + #define TALL_FONT_CORRECTION 0 +#endif + +#define START_COL 0 + +// LCD selection +#if ENABLED(REPRAPWORLD_GRAPHICAL_LCD) + U8GLIB_ST7920_128X64_4X u8g(LCD_PINS_RS); // 2 stripes + // U8GLIB_ST7920_128X64 u8g(LCD_PINS_RS); // 8 stripes +#elif ENABLED(U8GLIB_ST7920) + //U8GLIB_ST7920_128X64_4X u8g(LCD_PINS_D4, LCD_PINS_ENABLE, LCD_PINS_RS); // Original u8glib device. 2 stripes + // No 4 stripe device available from u8glib. + //U8GLIB_ST7920_128X64_1X u8g(LCD_PINS_D4, LCD_PINS_ENABLE, LCD_PINS_RS); // Original u8glib device. 8 stripes + U8GLIB_ST7920_128X64_RRD u8g(0); // Number of stripes can be adjusted in ultralcd_st7920_u8glib_rrd.h with PAGE_HEIGHT +#elif ENABLED(CARTESIO_UI) + // The CartesioUI display + #if DOGLCD_MOSI != -1 && DOGLCD_SCK != -1 + // using SW-SPI + //U8GLIB_DOGM128 u8g(DOGLCD_SCK, DOGLCD_MOSI, DOGLCD_CS, DOGLCD_A0); // 8 stripes + U8GLIB_DOGM128_2X u8g(DOGLCD_SCK, DOGLCD_MOSI, DOGLCD_CS, DOGLCD_A0); // 4 stripes + #else + //U8GLIB_DOGM128 u8g(DOGLCD_CS, DOGLCD_A0); // 8 stripes + U8GLIB_DOGM128_2X u8g(DOGLCD_CS, DOGLCD_A0); // 4 stripes + #endif +#elif ENABLED(U8GLIB_LM6059_AF) + // Based on the Adafruit ST7565 (http://www.adafruit.com/products/250) + //U8GLIB_LM6059 u8g(DOGLCD_CS, DOGLCD_A0); // 8 stripes + U8GLIB_LM6059_2X u8g(DOGLCD_CS, DOGLCD_A0); // 4 stripes +#elif ENABLED(U8GLIB_ST7565_64128N) + // The MaKrPanel, Mini Viki, and Viki 2.0, ST7565 controller as well + // U8GLIB_ST7565_64128n_2x_VIKI u8g(0); // using SW-SPI DOGLCD_MOSI != -1 && DOGLCD_SCK + U8GLIB_ST7565_64128n_2x_VIKI u8g(DOGLCD_SCK, DOGLCD_MOSI, DOGLCD_CS, DOGLCD_A0); // using SW-SPI + //U8GLIB_NHD_C12864_2X u8g(DOGLCD_CS, DOGLCD_A0); // 4 stripes HWSPI +#elif ENABLED(U8GLIB_SSD1306) + // Generic support for SSD1306 OLED I2C LCDs + //U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE | U8G_I2C_OPT_FAST); // 8 stripes + U8GLIB_SSD1306_128X64_2X u8g(U8G_I2C_OPT_NONE | U8G_I2C_OPT_FAST); // 4 stripes +#elif ENABLED(MKS_12864OLED) + // MKS 128x64 (SH1106) OLED I2C LCD + U8GLIB_SH1106_128X64 u8g(DOGLCD_SCK, DOGLCD_MOSI, DOGLCD_CS, DOGLCD_A0); // 8 stripes + //U8GLIB_SH1106_128X64_2X u8g(DOGLCD_SCK, DOGLCD_MOSI, DOGLCD_CS, DOGLCD_A0); // 4 stripes +#elif ENABLED(U8GLIB_SH1106) + // Generic support for SH1106 OLED I2C LCDs + //U8GLIB_SH1106_128X64 u8g(U8G_I2C_OPT_NONE | U8G_I2C_OPT_FAST); // 8 stripes + U8GLIB_SH1106_128X64_2X u8g(U8G_I2C_OPT_NONE | U8G_I2C_OPT_FAST); // 4 stripes +#elif ENABLED(MINIPANEL) + // The MINIPanel display + //U8GLIB_MINI12864 u8g(DOGLCD_CS, DOGLCD_A0); // 8 stripes + U8GLIB_MINI12864_2X u8g(DOGLCD_CS, DOGLCD_A0); // 4 stripes +#else + // for regular DOGM128 display with HW-SPI + //U8GLIB_DOGM128 u8g(DOGLCD_CS, DOGLCD_A0); // HW-SPI Com: CS, A0 // 8 stripes + U8GLIB_DOGM128_2X u8g(DOGLCD_CS, DOGLCD_A0); // HW-SPI Com: CS, A0 // 4 stripes +#endif + +#ifndef LCD_PIXEL_WIDTH + #define LCD_PIXEL_WIDTH 128 +#endif +#ifndef LCD_PIXEL_HEIGHT + #define LCD_PIXEL_HEIGHT 64 +#endif + +#include "utf_mapper.h" + +uint16_t lcd_contrast; // Initialized by settings.load() +static char currentfont = 0; + +// The current graphical page being rendered +u8g_page_t &page = ((u8g_pb_t *)((u8g.getU8g())->dev->dev_mem))->p; + +// For selective rendering within a Y range +#define PAGE_UNDER(yb) (u8g.getU8g()->current_page.y0 <= (yb)) +#define PAGE_CONTAINS(ya, yb) (PAGE_UNDER(yb) && u8g.getU8g()->current_page.y1 >= (ya)) + +static void lcd_setFont(const char font_nr) { + switch (font_nr) { + case FONT_STATUSMENU : {u8g.setFont(FONT_STATUSMENU_NAME); currentfont = FONT_STATUSMENU;}; break; + case FONT_MENU : {u8g.setFont(FONT_MENU_NAME); currentfont = FONT_MENU;}; break; + case FONT_SPECIAL : {u8g.setFont(FONT_SPECIAL_NAME); currentfont = FONT_SPECIAL;}; break; + case FONT_MENU_EDIT : {u8g.setFont(FONT_MENU_EDIT_NAME); currentfont = FONT_MENU_EDIT;}; break; + break; + } +} + +void lcd_print(const char c) { + if (WITHIN(c, 1, LCD_STR_SPECIAL_MAX)) { + u8g.setFont(FONT_SPECIAL_NAME); + u8g.print(c); + lcd_setFont(currentfont); + } + else charset_mapper(c); +} + +char lcd_print_and_count(const char c) { + if (WITHIN(c, 1, LCD_STR_SPECIAL_MAX)) { + u8g.setFont(FONT_SPECIAL_NAME); + u8g.print(c); + lcd_setFont(currentfont); + return 1; + } + else return charset_mapper(c); +} + +/** + * Core LCD printing functions + * On DOGM all strings go through a filter for utf + * But only use lcd_print_utf and lcd_printPGM_utf for translated text + */ +void lcd_print(const char *str) { while (*str) lcd_print(*str++); } +void lcd_printPGM(const char *str) { while (const char c = pgm_read_byte(str)) lcd_print(c), ++str; } + +void lcd_print_utf(const char *str, uint8_t n=LCD_WIDTH) { + char c; + while (n && (c = *str)) n -= charset_mapper(c), ++str; +} + +void lcd_printPGM_utf(const char *str, uint8_t n=LCD_WIDTH) { + char c; + while (n && (c = pgm_read_byte(str))) n -= charset_mapper(c), ++str; +} + +#if ENABLED(SHOW_BOOTSCREEN) + + #if ENABLED(SHOW_CUSTOM_BOOTSCREEN) + + void lcd_custom_bootscreen() { + u8g.firstPage(); + do { + u8g.drawBitmapP( + (128 - (CUSTOM_BOOTSCREEN_BMPWIDTH)) /2, + ( 64 - (CUSTOM_BOOTSCREEN_BMPHEIGHT)) /2, + CEILING(CUSTOM_BOOTSCREEN_BMPWIDTH, 8), CUSTOM_BOOTSCREEN_BMPHEIGHT, custom_start_bmp); + } while (u8g.nextPage()); + } + + #endif // SHOW_CUSTOM_BOOTSCREEN + + void lcd_bootscreen() { + + static bool show_bootscreen = true; + + if (show_bootscreen) { + show_bootscreen = false; + + #if ENABLED(START_BMPHIGH) + constexpr uint8_t offy = 0; + #else + constexpr uint8_t offy = DOG_CHAR_HEIGHT; + #endif + + const uint8_t offx = (u8g.getWidth() - (START_BMPWIDTH)) / 2, + txt1X = (u8g.getWidth() - (sizeof(STRING_SPLASH_LINE1) - 1) * (DOG_CHAR_WIDTH)) / 2; + + u8g.firstPage(); + do { + u8g.drawBitmapP(offx, offy, START_BMPBYTEWIDTH, START_BMPHEIGHT, start_bmp); + lcd_setFont(FONT_MENU); + #ifndef STRING_SPLASH_LINE2 + u8g.drawStr(txt1X, u8g.getHeight() - (DOG_CHAR_HEIGHT), STRING_SPLASH_LINE1); + #else + const uint8_t txt2X = (u8g.getWidth() - (sizeof(STRING_SPLASH_LINE2) - 1) * (DOG_CHAR_WIDTH)) / 2; + u8g.drawStr(txt1X, u8g.getHeight() - (DOG_CHAR_HEIGHT) * 3 / 2, STRING_SPLASH_LINE1); + u8g.drawStr(txt2X, u8g.getHeight() - (DOG_CHAR_HEIGHT) * 1 / 2, STRING_SPLASH_LINE2); + #endif + } while (u8g.nextPage()); + } + } + +#endif // SHOW_BOOTSCREEN + +// Initialize or re-initialize the LCD +static void lcd_implementation_init() { + + #if PIN_EXISTS(LCD_BACKLIGHT) // Enable LCD backlight + OUT_WRITE(LCD_BACKLIGHT_PIN, HIGH); + #endif + + #if PIN_EXISTS(LCD_RESET) + OUT_WRITE(LCD_RESET_PIN, LOW); // perform a clean hardware reset + _delay_ms(5); + OUT_WRITE(LCD_RESET_PIN, HIGH); + _delay_ms(5); // delay to allow the display to initalize + u8g.begin(); // re-initialize the display + #endif + + #if DISABLED(MINIPANEL) // setContrast not working for Mini Panel + u8g.setContrast(lcd_contrast); + #endif + + #if ENABLED(LCD_SCREEN_ROT_90) + u8g.setRot90(); // Rotate screen by 90° + #elif ENABLED(LCD_SCREEN_ROT_180) + u8g.setRot180(); // Rotate screen by 180° + #elif ENABLED(LCD_SCREEN_ROT_270) + u8g.setRot270(); // Rotate screen by 270° + #endif + + #if ENABLED(SHOW_BOOTSCREEN) + #if ENABLED(SHOW_CUSTOM_BOOTSCREEN) + lcd_custom_bootscreen(); + #else + lcd_bootscreen(); + #endif + #endif +} + +// The kill screen is displayed for unrecoverable conditions +void lcd_kill_screen() { + lcd_setFont(FONT_MENU); + u8g.setPrintPos(0, u8g.getHeight()/4*1); + lcd_print_utf(lcd_status_message); + u8g.setPrintPos(0, u8g.getHeight()/4*2); + lcd_printPGM(PSTR(MSG_HALTED)); + u8g.setPrintPos(0, u8g.getHeight()/4*3); + lcd_printPGM(PSTR(MSG_PLEASE_RESET)); +} + +void lcd_implementation_clear() { } // Automatically cleared by Picture Loop + +// +// Status Screen +// + +FORCE_INLINE void _draw_centered_temp(const int16_t temp, const uint8_t x, const uint8_t y) { + const uint8_t degsize = 6 * (temp >= 100 ? 3 : temp >= 10 ? 2 : 1); // number's pixel width + u8g.setPrintPos(x - (18 - degsize) / 2, y); // move left if shorter + lcd_print(itostr3(temp)); + lcd_printPGM(PSTR(LCD_STR_DEGREE " ")); +} + +FORCE_INLINE void _draw_heater_status(const uint8_t x, const int8_t heater, const bool blink) { + #if !HEATER_IDLE_HANDLER + UNUSED(blink); + #endif + + #if HAS_TEMP_BED + const bool isBed = heater < 0; + #else + constexpr bool isBed = false; + #endif + + if (PAGE_UNDER(7)) { + #if HEATER_IDLE_HANDLER + const bool is_idle = (!isBed ? thermalManager.is_heater_idle(heater) : + #if HAS_TEMP_BED + thermalManager.is_bed_idle() + #else + false + #endif + ); + + if (blink || !is_idle) + #endif + _draw_centered_temp((isBed ? thermalManager.degTargetBed() : thermalManager.degTargetHotend(heater)) + 0.5, x, 7); } + + if (PAGE_CONTAINS(21, 28)) + _draw_centered_temp((isBed ? thermalManager.degBed() : thermalManager.degHotend(heater)) + 0.5, x, 28); + + if (PAGE_CONTAINS(17, 20)) { + const uint8_t h = isBed ? 7 : 8, + y = isBed ? 18 : 17; + if (isBed ? thermalManager.isHeatingBed() : thermalManager.isHeatingHotend(heater)) { + u8g.setColorIndex(0); // white on black + u8g.drawBox(x + h, y, 2, 2); + u8g.setColorIndex(1); // black on white + } + else { + u8g.drawBox(x + h, y, 2, 2); + } + } +} + +FORCE_INLINE void _draw_axis_label(const AxisEnum axis, const char* const pstr, const bool blink) { + if (blink) + lcd_printPGM(pstr); + else { + if (!axis_homed[axis]) + u8g.print('?'); + else { + #if DISABLED(HOME_AFTER_DEACTIVATE) && DISABLED(DISABLE_REDUCED_ACCURACY_WARNING) + if (!axis_known_position[axis]) + u8g.print(' '); + else + #endif + lcd_printPGM(pstr); + } + } +} + +inline void lcd_implementation_status_message(const bool blink) { + #if ENABLED(STATUS_MESSAGE_SCROLLING) + static bool last_blink = false; + const uint8_t slen = lcd_strlen(lcd_status_message); + const char *stat = lcd_status_message + status_scroll_pos; + if (slen <= LCD_WIDTH) + lcd_print_utf(stat); // The string isn't scrolling + else { + if (status_scroll_pos <= slen - LCD_WIDTH) + lcd_print_utf(stat); // The string fills the screen + else { + uint8_t chars = LCD_WIDTH; + if (status_scroll_pos < slen) { // First string still visible + lcd_print_utf(stat); // The string leaves space + chars -= slen - status_scroll_pos; // Amount of space left + } + u8g.print('.'); // Always at 1+ spaces left, draw a dot + if (--chars) { + if (status_scroll_pos < slen + 1) // Draw a second dot if there's space + --chars, u8g.print('.'); + if (chars) lcd_print_utf(lcd_status_message, chars); // Print a second copy of the message + } + } + if (last_blink != blink) { + last_blink = blink; + // Skip any non-printing bytes + if (status_scroll_pos < slen) while (!PRINTABLE(lcd_status_message[status_scroll_pos])) status_scroll_pos++; + if (++status_scroll_pos >= slen + 2) status_scroll_pos = 0; + } + } + #else + lcd_print_utf(lcd_status_message); + #endif +} + +//#define DOGM_SD_PERCENT + +static void lcd_implementation_status_screen() { + + const bool blink = lcd_blink(); + + // Status Menu Font + lcd_setFont(FONT_STATUSMENU); + + // + // Fan Animation + // + + if (PAGE_UNDER(STATUS_SCREENHEIGHT + 1)) { + + u8g.drawBitmapP(9, 1, STATUS_SCREENBYTEWIDTH, STATUS_SCREENHEIGHT, + #if HAS_FAN0 + blink && fanSpeeds[0] ? status_screen0_bmp : status_screen1_bmp + #else + status_screen0_bmp + #endif + ); + + } + + // + // Temperature Graphics and Info + // + + if (PAGE_UNDER(28)) { + // Extruders + HOTEND_LOOP() _draw_heater_status(5 + e * 25, e, blink); + + // Heated bed + #if HOTENDS < 4 && HAS_TEMP_BED + _draw_heater_status(81, -1, blink); + #endif + + #if HAS_FAN0 + if (PAGE_CONTAINS(20, 27)) { + // Fan + const int16_t per = ((fanSpeeds[0] + 1) * 100) / 256; + if (per) { + u8g.setPrintPos(104, 27); + lcd_print(itostr3(per)); + u8g.print('%'); + } + } + #endif + } + + #if ENABLED(SDSUPPORT) + + // + // SD Card Symbol + // + + if (PAGE_CONTAINS(42 - (TALL_FONT_CORRECTION), 51 - (TALL_FONT_CORRECTION))) { + // Upper box + u8g.drawBox(42, 42 - (TALL_FONT_CORRECTION), 8, 7); // 42-48 (or 41-47) + // Right edge + u8g.drawBox(50, 44 - (TALL_FONT_CORRECTION), 2, 5); // 44-48 (or 43-47) + // Bottom hollow box + u8g.drawFrame(42, 49 - (TALL_FONT_CORRECTION), 10, 4); // 49-52 (or 48-51) + // Corner pixel + u8g.drawPixel(50, 43 - (TALL_FONT_CORRECTION)); // 43 (or 42) + } + + // + // Progress bar frame + // + + #define PROGRESS_BAR_X 54 + #define PROGRESS_BAR_WIDTH (LCD_PIXEL_WIDTH - PROGRESS_BAR_X) + + if (PAGE_CONTAINS(49, 52 - (TALL_FONT_CORRECTION))) // 49-52 (or 49-51) + u8g.drawFrame( + PROGRESS_BAR_X, 49, + PROGRESS_BAR_WIDTH, 4 - (TALL_FONT_CORRECTION) + ); + + if (IS_SD_PRINTING) { + + // + // Progress bar solid part + // + + if (PAGE_CONTAINS(50, 51 - (TALL_FONT_CORRECTION))) // 50-51 (or just 50) + u8g.drawBox( + PROGRESS_BAR_X + 1, 50, + (uint16_t)((PROGRESS_BAR_WIDTH - 2) * card.percentDone() * 0.01), 2 - (TALL_FONT_CORRECTION) + ); + + // + // SD Percent Complete + // + + #if ENABLED(DOGM_SD_PERCENT) + if (PAGE_CONTAINS(41, 48)) { + // Percent complete + u8g.setPrintPos(55, 48); + u8g.print(itostr3(card.percentDone())); + u8g.print('%'); + } + #endif + } + + // + // Elapsed Time + // + + #if DISABLED(DOGM_SD_PERCENT) + #define SD_DURATION_X (PROGRESS_BAR_X + (PROGRESS_BAR_WIDTH / 2) - len * (DOG_CHAR_WIDTH / 2)) + #else + #define SD_DURATION_X (LCD_PIXEL_WIDTH - len * DOG_CHAR_WIDTH) + #endif + + if (PAGE_CONTAINS(41, 48)) { + + char buffer[10]; + duration_t elapsed = print_job_timer.duration(); + bool has_days = (elapsed.value > 60*60*24L); + uint8_t len = elapsed.toDigital(buffer, has_days); + u8g.setPrintPos(SD_DURATION_X, 48); + lcd_print(buffer); + } + + #endif + + // + // XYZ Coordinates + // + + #if ENABLED(USE_SMALL_INFOFONT) + #define INFO_FONT_HEIGHT 7 + #else + #define INFO_FONT_HEIGHT 8 + #endif + + #define XYZ_BASELINE (30 + INFO_FONT_HEIGHT) + + #define X_LABEL_POS 3 + #define X_VALUE_POS 11 + #define XYZ_SPACING 40 + + #if ENABLED(XYZ_HOLLOW_FRAME) + #define XYZ_FRAME_TOP 29 + #define XYZ_FRAME_HEIGHT INFO_FONT_HEIGHT + 3 + #else + #define XYZ_FRAME_TOP 30 + #define XYZ_FRAME_HEIGHT INFO_FONT_HEIGHT + 1 + #endif + + // Before homing the axis letters are blinking 'X' <-> '?'. + // When axis is homed but axis_known_position is false the axis letters are blinking 'X' <-> ' '. + // When everything is ok you see a constant 'X'. + + static char xstring[5], ystring[5], zstring[7]; + #if ENABLED(FILAMENT_LCD_DISPLAY) && DISABLED(SDSUPPORT) + static char wstring[5], mstring[4]; + #endif + + // At the first page, regenerate the XYZ strings + if (page.page == 0) { + strcpy(xstring, ftostr4sign(current_position[X_AXIS])); + strcpy(ystring, ftostr4sign(current_position[Y_AXIS])); + strcpy(zstring, ftostr52sp(FIXFLOAT(current_position[Z_AXIS]))); + #if ENABLED(FILAMENT_LCD_DISPLAY) && DISABLED(SDSUPPORT) + strcpy(wstring, ftostr12ns(filament_width_meas)); + strcpy(mstring, itostr3(100.0 * volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM])); + #endif + } + + 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 + #endif + + if (PAGE_CONTAINS(XYZ_BASELINE - (INFO_FONT_HEIGHT - 1), XYZ_BASELINE)) { + + #if DISABLED(XYZ_HOLLOW_FRAME) + u8g.setColorIndex(0); // white on black + #endif + + u8g.setPrintPos(0 * XYZ_SPACING + X_LABEL_POS, XYZ_BASELINE); + _draw_axis_label(X_AXIS, PSTR(MSG_X), blink); + u8g.setPrintPos(0 * XYZ_SPACING + X_VALUE_POS, XYZ_BASELINE); + lcd_print(xstring); + + u8g.setPrintPos(1 * XYZ_SPACING + X_LABEL_POS, XYZ_BASELINE); + _draw_axis_label(Y_AXIS, PSTR(MSG_Y), blink); + u8g.setPrintPos(1 * XYZ_SPACING + X_VALUE_POS, XYZ_BASELINE); + lcd_print(ystring); + + u8g.setPrintPos(2 * XYZ_SPACING + X_LABEL_POS, XYZ_BASELINE); + _draw_axis_label(Z_AXIS, PSTR(MSG_Z), blink); + u8g.setPrintPos(2 * XYZ_SPACING + X_VALUE_POS, XYZ_BASELINE); + lcd_print(zstring); + + #if DISABLED(XYZ_HOLLOW_FRAME) + u8g.setColorIndex(1); // black on white + #endif + } + } + + // + // Feedrate + // + + if (PAGE_CONTAINS(51 - INFO_FONT_HEIGHT, 49)) { + lcd_setFont(FONT_MENU); + u8g.setPrintPos(3, 50); + lcd_print(LCD_STR_FEEDRATE[0]); + + lcd_setFont(FONT_STATUSMENU); + u8g.setPrintPos(12, 50); + lcd_print(itostr3(feedrate_percentage)); + u8g.print('%'); + + // + // Filament sensor display if SD is disabled + // + #if DISABLED(SDSUPPORT) && ENABLED(FILAMENT_LCD_DISPLAY) + u8g.setPrintPos(56, 50); + lcd_print(wstring); + u8g.setPrintPos(102, 50); + lcd_print(mstring); + u8g.print('%'); + lcd_setFont(FONT_MENU); + u8g.setPrintPos(47, 50); + lcd_print(LCD_STR_FILAM_DIA); + u8g.setPrintPos(93, 50); + lcd_print(LCD_STR_FILAM_MUL); + #endif + } + + // + // Status line + // + + #define STATUS_BASELINE (55 + INFO_FONT_HEIGHT) + + if (PAGE_CONTAINS(STATUS_BASELINE - (INFO_FONT_HEIGHT - 1), STATUS_BASELINE)) { + u8g.setPrintPos(0, STATUS_BASELINE); + + #if ENABLED(FILAMENT_LCD_DISPLAY) && ENABLED(SDSUPPORT) + if (PENDING(millis(), previous_lcd_status_ms + 5000UL)) { //Display both Status message line and Filament display on the last line + lcd_implementation_status_message(blink); + } + else { + lcd_printPGM(PSTR(LCD_STR_FILAM_DIA)); + u8g.print(':'); + lcd_print(ftostr12ns(filament_width_meas)); + lcd_printPGM(PSTR(" " LCD_STR_FILAM_MUL)); + u8g.print(':'); + lcd_print(itostr3(100.0 * volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM])); + u8g.print('%'); + } + #else + lcd_implementation_status_message(blink); + #endif + } +} + +#if ENABLED(ULTIPANEL) + + uint8_t row_y1, row_y2; + uint8_t constexpr row_height = DOG_CHAR_HEIGHT + 2 * (TALL_FONT_CORRECTION); + + #if ENABLED(ADVANCED_PAUSE_FEATURE) + + static void lcd_implementation_hotend_status(const uint8_t row) { + row_y1 = row * row_height + 1; + row_y2 = row_y1 + row_height - 1; + + if (!PAGE_CONTAINS(row_y1 + 1, row_y2 + 2)) return; + + u8g.setPrintPos(LCD_PIXEL_WIDTH - 11 * (DOG_CHAR_WIDTH), row_y2); + lcd_print('E'); + lcd_print((char)('1' + active_extruder)); + lcd_print(' '); + lcd_print(itostr3(thermalManager.degHotend(active_extruder))); + lcd_print('/'); + + if (lcd_blink() || !thermalManager.is_heater_idle(active_extruder)) + lcd_print(itostr3(thermalManager.degTargetHotend(active_extruder))); + } + + #endif // ADVANCED_PAUSE_FEATURE + + // Set the colors for a menu item based on whether it is selected + static void lcd_implementation_mark_as_selected(const uint8_t row, const bool isSelected) { + row_y1 = row * row_height + 1; + row_y2 = row_y1 + row_height - 1; + + if (!PAGE_CONTAINS(row_y1 + 1, row_y2 + 2)) return; + + if (isSelected) { + #if ENABLED(MENU_HOLLOW_FRAME) + 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.drawBox(0, row_y1 + 2, LCD_PIXEL_WIDTH, row_height - 1); + u8g.setColorIndex(0); // white on black + #endif + } + #if DISABLED(MENU_HOLLOW_FRAME) + else { + u8g.setColorIndex(1); // unmarked text is black on white + } + #endif + u8g.setPrintPos((START_COL) * (DOG_CHAR_WIDTH), row_y2); + } + + // Draw a static line of text in the same idiom as a menu item + static void lcd_implementation_drawmenu_static(const uint8_t row, const char* pstr, const bool center=true, const bool invert=false, const char* valstr=NULL) { + + lcd_implementation_mark_as_selected(row, invert); + + if (!PAGE_CONTAINS(row_y1, row_y2)) return; + + char c; + int8_t n = LCD_WIDTH - (START_COL); + + if (center && !valstr) { + int8_t pad = (LCD_WIDTH - lcd_strlen_P(pstr)) / 2; + while (--pad >= 0) { u8g.print(' '); n--; } + } + while (n > 0 && (c = pgm_read_byte(pstr))) { + n -= lcd_print_and_count(c); + pstr++; + } + if (valstr) while (n > 0 && (c = *valstr)) { + n -= lcd_print_and_count(c); + valstr++; + } + while (n-- > 0) u8g.print(' '); + } + + // Draw a generic menu item + static void lcd_implementation_drawmenu_generic(const bool isSelected, const uint8_t row, const char* pstr, const char pre_char, const char post_char) { + UNUSED(pre_char); + + lcd_implementation_mark_as_selected(row, isSelected); + + if (!PAGE_CONTAINS(row_y1, row_y2)) return; + + uint8_t n = LCD_WIDTH - (START_COL) - 2; + while (char c = pgm_read_byte(pstr)) { + n -= lcd_print_and_count(c); + pstr++; + } + while (n--) u8g.print(' '); + u8g.setPrintPos(LCD_PIXEL_WIDTH - (DOG_CHAR_WIDTH), row_y2); + lcd_print(post_char); + u8g.print(' '); + } + + // Macros for specific types of menu items + #define lcd_implementation_drawmenu_back(sel, row, pstr, dummy) lcd_implementation_drawmenu_generic(sel, row, pstr, LCD_STR_UPLEVEL[0], LCD_STR_UPLEVEL[0]) + #define lcd_implementation_drawmenu_submenu(sel, row, pstr, data) lcd_implementation_drawmenu_generic(sel, row, pstr, '>', LCD_STR_ARROW_RIGHT[0]) + #define lcd_implementation_drawmenu_gcode(sel, row, pstr, gcode) lcd_implementation_drawmenu_generic(sel, row, pstr, '>', ' ') + #define lcd_implementation_drawmenu_function(sel, row, pstr, data) lcd_implementation_drawmenu_generic(sel, row, pstr, '>', ' ') + + // Draw a menu item with an editable value + static void _drawmenu_setting_edit_generic(const bool isSelected, const uint8_t row, const char* pstr, const char* const data, const bool pgm) { + + lcd_implementation_mark_as_selected(row, isSelected); + + if (!PAGE_CONTAINS(row_y1, row_y2)) return; + + const uint8_t vallen = (pgm ? lcd_strlen_P(data) : (lcd_strlen((char*)data))); + uint8_t n = LCD_WIDTH - (START_COL) - 2 - vallen; + + while (char c = pgm_read_byte(pstr)) { + n -= lcd_print_and_count(c); + pstr++; + } + u8g.print(':'); + while (n--) u8g.print(' '); + u8g.setPrintPos(LCD_PIXEL_WIDTH - (DOG_CHAR_WIDTH) * vallen, row_y2); + if (pgm) lcd_printPGM(data); else lcd_print((char*)data); + } + + // Macros for edit items + #define lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, data) _drawmenu_setting_edit_generic(sel, row, pstr, data, false) + #define lcd_implementation_drawmenu_setting_edit_generic_P(sel, row, pstr, data) _drawmenu_setting_edit_generic(sel, row, pstr, data, true) + + #define DRAWMENU_SETTING_EDIT_GENERIC(_src) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, _src) + #define DRAW_BOOL_SETTING(sel, row, pstr, data) lcd_implementation_drawmenu_setting_edit_generic_P(sel, row, pstr, (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF)) + + void lcd_implementation_drawedit(const char* const pstr, const char* const value=NULL) { + const uint8_t labellen = lcd_strlen_P(pstr), + vallen = lcd_strlen(value); + + uint8_t rows = (labellen > LCD_WIDTH - 2 - vallen) ? 2 : 1; + + #if ENABLED(USE_BIG_EDIT_FONT) + uint8_t lcd_width, char_width; + if (labellen <= LCD_WIDTH_EDIT - 1) { + if (labellen + vallen + 2 >= LCD_WIDTH_EDIT) rows = 2; + lcd_width = LCD_WIDTH_EDIT + 1; + char_width = DOG_CHAR_WIDTH_EDIT; + lcd_setFont(FONT_MENU_EDIT); + } + else { + lcd_width = LCD_WIDTH - (START_COL); + char_width = DOG_CHAR_WIDTH; + lcd_setFont(FONT_MENU); + } + #else + constexpr uint8_t lcd_width = LCD_WIDTH - (START_COL), + char_width = DOG_CHAR_WIDTH; + #endif + + // Center either one or two rows + const uint8_t segmentHeight = u8g.getHeight() / (rows + 1); // 1 / (rows+1) = 1/2 or 1/3 + uint8_t baseline = segmentHeight + (DOG_CHAR_HEIGHT_EDIT + 1) / 2; + + bool onpage = PAGE_CONTAINS(baseline + 1 - (DOG_CHAR_HEIGHT_EDIT), baseline); + if (onpage) { + u8g.setPrintPos(0, baseline); + lcd_printPGM(pstr); + } + + if (value != NULL) { + u8g.print(':'); + if (rows == 2) { + baseline += segmentHeight; + onpage = PAGE_CONTAINS(baseline + 1 - (DOG_CHAR_HEIGHT_EDIT), baseline); + } + if (onpage) { + u8g.setPrintPos(((lcd_width - 1) - (vallen + 1)) * char_width, baseline); // Right-justified, leaving padded by spaces + u8g.print(' '); // overwrite char if value gets shorter + lcd_print(value); + } + } + } + + #if ENABLED(SDSUPPORT) + + static void _drawmenu_sd(const bool isSelected, const uint8_t row, const char* const pstr, const char* filename, char* const longFilename, const bool isDir) { + UNUSED(pstr); + + lcd_implementation_mark_as_selected(row, isSelected); + + if (!PAGE_CONTAINS(row_y1, row_y2)) return; + + uint8_t n = LCD_WIDTH - (START_COL) - 1; + if (longFilename[0]) { + filename = longFilename; + longFilename[n] = '\0'; // cutoff at screen edge + } + + if (isDir) lcd_print(LCD_STR_FOLDER[0]); + + while (char c = *filename) { + n -= lcd_print_and_count(c); + filename++; + } + while (n--) u8g.print(' '); + } + + #define lcd_implementation_drawmenu_sdfile(sel, row, pstr, filename, longFilename) _drawmenu_sd(sel, row, pstr, filename, longFilename, false) + #define lcd_implementation_drawmenu_sddirectory(sel, row, pstr, filename, longFilename) _drawmenu_sd(sel, row, pstr, filename, longFilename, true) + + #endif // SDSUPPORT + + #if ENABLED(AUTO_BED_LEVELING_UBL) + + /** + * UBL LCD "radar" map data + */ + #define MAP_UPPER_LEFT_CORNER_X 35 // These probably should be moved to the .h file But for now, + #define MAP_UPPER_LEFT_CORNER_Y 8 // it is easier to play with things having them here + #define MAP_MAX_PIXELS_X 53 + #define MAP_MAX_PIXELS_Y 49 + + void lcd_implementation_ubl_plot(const uint8_t x_plot, const uint8_t y_plot) { + // Scale the box pixels appropriately + uint8_t x_map_pixels = ((MAP_MAX_PIXELS_X - 4) / (GRID_MAX_POINTS_X)) * (GRID_MAX_POINTS_X), + y_map_pixels = ((MAP_MAX_PIXELS_Y - 4) / (GRID_MAX_POINTS_Y)) * (GRID_MAX_POINTS_Y), + + pixels_per_x_mesh_pnt = x_map_pixels / (GRID_MAX_POINTS_X), + pixels_per_y_mesh_pnt = y_map_pixels / (GRID_MAX_POINTS_Y), + + x_offset = MAP_UPPER_LEFT_CORNER_X + 1 + (MAP_MAX_PIXELS_X - x_map_pixels - 2) / 2, + y_offset = MAP_UPPER_LEFT_CORNER_Y + 1 + (MAP_MAX_PIXELS_Y - y_map_pixels - 2) / 2; + + // Clear the Mesh Map + + if (PAGE_CONTAINS(y_offset - 2, y_offset + y_map_pixels + 4)) { + u8g.setColorIndex(1); // First draw the bigger box in White so we have a border around the mesh map box + u8g.drawBox(x_offset - 2, y_offset - 2, x_map_pixels + 4, y_map_pixels + 4); + if (PAGE_CONTAINS(y_offset, y_offset + y_map_pixels)) { + u8g.setColorIndex(0); // Now actually clear the mesh map box + u8g.drawBox(x_offset, y_offset, x_map_pixels, y_map_pixels); + } + } + + // Display Mesh Point Locations + + u8g.setColorIndex(1); + const uint8_t sx = x_offset + pixels_per_x_mesh_pnt / 2; + uint8_t y = y_offset + pixels_per_y_mesh_pnt / 2; + for (uint8_t j = 0; j < GRID_MAX_POINTS_Y; j++, y += pixels_per_y_mesh_pnt) + if (PAGE_CONTAINS(y, y)) + for (uint8_t i = 0, x = sx; i < GRID_MAX_POINTS_X; i++, x += pixels_per_x_mesh_pnt) + u8g.drawBox(x, y, 1, 1); + + // Fill in the Specified Mesh Point + + uint8_t inverted_y = GRID_MAX_POINTS_Y - y_plot - 1; // The origin is typically in the lower right corner. We need to + // invert the Y to get it to plot in the right location. + + const uint8_t by = y_offset + inverted_y * pixels_per_y_mesh_pnt; + if (PAGE_CONTAINS(by, by + pixels_per_y_mesh_pnt)) + u8g.drawBox( + x_offset + x_plot * pixels_per_x_mesh_pnt, by, + pixels_per_x_mesh_pnt, pixels_per_y_mesh_pnt + ); + + // Put Relevant Text on Display + + // Show X and Y positions at top of screen + u8g.setColorIndex(1); + if (PAGE_UNDER(7)) { + u8g.setPrintPos(5, 7); + lcd_print("X:"); + lcd_print(ftostr32(LOGICAL_X_POSITION(pgm_read_float(&ubl._mesh_index_to_xpos[x_plot])))); + u8g.setPrintPos(74, 7); + lcd_print("Y:"); + lcd_print(ftostr32(LOGICAL_Y_POSITION(pgm_read_float(&ubl._mesh_index_to_ypos[y_plot])))); + } + + // Print plot position + if (PAGE_CONTAINS(64 - (INFO_FONT_HEIGHT - 1), 64)) { + u8g.setPrintPos(5, 64); + lcd_print('('); + u8g.print(x_plot); + lcd_print(','); + u8g.print(y_plot); + lcd_print(')'); + + // Show the location value + u8g.setPrintPos(74, 64); + lcd_print("Z:"); + if (!isnan(ubl.z_values[x_plot][y_plot])) + lcd_print(ftostr43sign(ubl.z_values[x_plot][y_plot])); + else + lcd_printPGM(PSTR(" -----")); + } + + } + + #endif // AUTO_BED_LEVELING_UBL + +#endif // ULTIPANEL + +#endif // __ULTRALCD_IMPL_DOGM_H diff --git a/trunk/Arduino/Marlin_1.1.6/ultralcd_impl_HD44780.h b/trunk/Arduino/Marlin_1.1.6/ultralcd_impl_HD44780.h new file mode 100644 index 00000000..74429b40 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/ultralcd_impl_HD44780.h @@ -0,0 +1,1514 @@ +/** + * 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 . + * + */ + +#ifndef ULTRALCD_IMPL_HD44780_H +#define ULTRALCD_IMPL_HD44780_H + +/** + * Implementation of the LCD display routines for a Hitachi HD44780 display. + * These are the most common LCD character displays. + */ + +#include "utility.h" +#include "duration_t.h" + +#if ENABLED(AUTO_BED_LEVELING_UBL) + #include "ubl.h" + + #if ENABLED(ULTIPANEL) + #define ULTRA_X_PIXELS_PER_CHAR 5 + #define ULTRA_Y_PIXELS_PER_CHAR 8 + #define ULTRA_COLUMNS_FOR_MESH_MAP 7 + #define ULTRA_ROWS_FOR_MESH_MAP 4 + + #define N_USER_CHARS 8 + + #define TOP_LEFT _BV(0) + #define TOP_RIGHT _BV(1) + #define LOWER_LEFT _BV(2) + #define LOWER_RIGHT _BV(3) + #endif +#endif + +extern volatile uint8_t buttons; //an extended version of the last checked buttons in a bit array. + +//////////////////////////////////// +// 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. + +#if ENABLED(ULTIPANEL) + + // + // Setup other button mappings of each panel + // + #if ENABLED(LCD_I2C_VIKI) + #define B_I2C_BTN_OFFSET 3 // (the first three bit positions reserved for EN_A, EN_B, EN_C) + + // button and encoder bit positions within 'buttons' + #define B_LE (BUTTON_LEFT< + #include + #include + #define LCD_CLASS LiquidCrystal_I2C + LCD_CLASS lcd(LCD_I2C_ADDRESS, LCD_I2C_PIN_EN, LCD_I2C_PIN_RW, LCD_I2C_PIN_RS, LCD_I2C_PIN_D4, LCD_I2C_PIN_D5, LCD_I2C_PIN_D6, LCD_I2C_PIN_D7); + +#elif ENABLED(LCD_I2C_TYPE_MCP23017) + //for the LED indicators (which maybe mapped to different things in lcd_implementation_update_indicators()) + #define LED_A 0x04 //100 + #define LED_B 0x02 //010 + #define LED_C 0x01 //001 + + #define LCD_HAS_STATUS_INDICATORS + + #include + #include + #define LCD_CLASS LiquidTWI2 + #if ENABLED(DETECT_DEVICE) + LCD_CLASS lcd(LCD_I2C_ADDRESS, 1); + #else + LCD_CLASS lcd(LCD_I2C_ADDRESS); + #endif + +#elif ENABLED(LCD_I2C_TYPE_MCP23008) + #include + #include + #define LCD_CLASS LiquidTWI2 + #if ENABLED(DETECT_DEVICE) + LCD_CLASS lcd(LCD_I2C_ADDRESS, 1); + #else + LCD_CLASS lcd(LCD_I2C_ADDRESS); + #endif + +#elif ENABLED(LCD_I2C_TYPE_PCA8574) + #include + #define LCD_CLASS LiquidCrystal_I2C + LCD_CLASS lcd(LCD_I2C_ADDRESS, LCD_WIDTH, LCD_HEIGHT); + +// 2 wire Non-latching LCD SR from: +// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/schematics#!shiftregister-connection +#elif ENABLED(SR_LCD_2W_NL) + extern "C" void __cxa_pure_virtual() { while (1); } + #include + #include + #define LCD_CLASS LiquidCrystal_SR + #if PIN_EXISTS(SR_STROBE) + LCD_CLASS lcd(SR_DATA_PIN, SR_CLK_PIN, SR_STROBE_PIN); + #else + LCD_CLASS lcd(SR_DATA_PIN, SR_CLK_PIN); + #endif +#elif ENABLED(LCM1602) + #include + #include + #include + #define LCD_CLASS LiquidCrystal_I2C + LCD_CLASS lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); +#else + // Standard directly connected LCD implementations + #include + #define LCD_CLASS LiquidCrystal + LCD_CLASS lcd(LCD_PINS_RS, LCD_PINS_ENABLE, LCD_PINS_D4, LCD_PINS_D5, LCD_PINS_D6, LCD_PINS_D7); //RS,Enable,D4,D5,D6,D7 +#endif + +#include "utf_mapper.h" + +#if ENABLED(LCD_PROGRESS_BAR) + static millis_t progress_bar_ms = 0; + #if PROGRESS_MSG_EXPIRE > 0 + static millis_t expire_status_ms = 0; + #endif + #define LCD_STR_PROGRESS "\x03\x04\x05" +#endif + +#if ENABLED(LCD_HAS_STATUS_INDICATORS) + static void lcd_implementation_update_indicators(); +#endif + +static void createChar_P(const char c, const byte * const ptr) { + byte temp[8]; + for (uint8_t i = 0; i < 8; i++) + temp[i] = pgm_read_byte(&ptr[i]); + lcd.createChar(c, temp); +} + +static void lcd_set_custom_characters( + #if ENABLED(LCD_PROGRESS_BAR) + const bool info_screen_charset = true + #endif +) { + const static PROGMEM byte bedTemp[8] = { + B00000, + B11111, + B10101, + B10001, + B10101, + B11111, + B00000, + B00000 + }; + + const static PROGMEM byte degree[8] = { + B01100, + B10010, + B10010, + B01100, + B00000, + B00000, + B00000, + B00000 + }; + + const static PROGMEM byte thermometer[8] = { + B00100, + B01010, + B01010, + B01010, + B01010, + B10001, + B10001, + B01110 + }; + + const static PROGMEM byte uplevel[8] = { + B00100, + B01110, + B11111, + B00100, + B11100, + B00000, + B00000, + B00000 + }; + + const static PROGMEM byte feedrate[8] = { + B11100, + B10000, + B11000, + B10111, + B00101, + B00110, + B00101, + B00000 + }; + + const static PROGMEM byte clock[8] = { + B00000, + B01110, + B10011, + B10101, + B10001, + B01110, + B00000, + B00000 + }; + + #if ENABLED(SDSUPPORT) + const static PROGMEM byte refresh[8] = { + B00000, + B00110, + B11001, + B11000, + B00011, + B10011, + B01100, + B00000, + }; + const static PROGMEM byte folder[8] = { + B00000, + B11100, + B11111, + B10001, + B10001, + B11111, + B00000, + B00000 + }; + + #if ENABLED(LCD_PROGRESS_BAR) + const static PROGMEM byte progress[3][8] = { { + B00000, + B10000, + B10000, + B10000, + B10000, + B10000, + B10000, + B00000 + }, { + B00000, + B10100, + B10100, + B10100, + B10100, + B10100, + B10100, + B00000 + }, { + B00000, + B10101, + B10101, + B10101, + B10101, + B10101, + B10101, + B00000 + } }; + #endif + #endif + + createChar_P(LCD_BEDTEMP_CHAR, bedTemp); + createChar_P(LCD_DEGREE_CHAR, degree); + createChar_P(LCD_STR_THERMOMETER[0], thermometer); + createChar_P(LCD_FEEDRATE_CHAR, feedrate); + createChar_P(LCD_CLOCK_CHAR, clock); + + #if ENABLED(SDSUPPORT) + #if ENABLED(LCD_PROGRESS_BAR) + static bool char_mode = false; + if (info_screen_charset != char_mode) { + char_mode = info_screen_charset; + if (info_screen_charset) { // Progress bar characters for info screen + for (int16_t i = 3; i--;) createChar_P(LCD_STR_PROGRESS[i], progress[i]); + } + else { // Custom characters for submenus + createChar_P(LCD_UPLEVEL_CHAR, uplevel); + createChar_P(LCD_STR_REFRESH[0], refresh); + createChar_P(LCD_STR_FOLDER[0], folder); + } + } + #else + createChar_P(LCD_UPLEVEL_CHAR, uplevel); + createChar_P(LCD_STR_REFRESH[0], refresh); + createChar_P(LCD_STR_FOLDER[0], folder); + #endif + + #else + createChar_P(LCD_UPLEVEL_CHAR, uplevel); + #endif +} + +static void lcd_implementation_init( + #if ENABLED(LCD_PROGRESS_BAR) + const bool info_screen_charset = true + #endif +) { + + #if ENABLED(LCD_I2C_TYPE_PCF8575) + lcd.begin(LCD_WIDTH, LCD_HEIGHT); + #ifdef LCD_I2C_PIN_BL + lcd.setBacklightPin(LCD_I2C_PIN_BL, POSITIVE); + lcd.setBacklight(HIGH); + #endif + + #elif ENABLED(LCD_I2C_TYPE_MCP23017) + lcd.setMCPType(LTI_TYPE_MCP23017); + lcd.begin(LCD_WIDTH, LCD_HEIGHT); + lcd_implementation_update_indicators(); + + #elif ENABLED(LCD_I2C_TYPE_MCP23008) + lcd.setMCPType(LTI_TYPE_MCP23008); + lcd.begin(LCD_WIDTH, LCD_HEIGHT); + + #elif ENABLED(LCD_I2C_TYPE_PCA8574) + lcd.init(); + lcd.backlight(); + + #else + lcd.begin(LCD_WIDTH, LCD_HEIGHT); + #endif + + lcd_set_custom_characters( + #if ENABLED(LCD_PROGRESS_BAR) + info_screen_charset + #endif + ); + + lcd.clear(); +} + +void lcd_implementation_clear() { lcd.clear(); } + +void lcd_print(const char c) { charset_mapper(c); } + +void lcd_print(const char *str) { while (*str) lcd.print(*str++); } +void lcd_printPGM(const char *str) { while (const char c = pgm_read_byte(str)) lcd.print(c), ++str; } + +void lcd_print_utf(const char *str, uint8_t n=LCD_WIDTH) { + char c; + while (n && (c = *str)) n -= charset_mapper(c), ++str; +} + +void lcd_printPGM_utf(const char *str, uint8_t n=LCD_WIDTH) { + char c; + while (n && (c = pgm_read_byte(str))) n -= charset_mapper(c), ++str; +} + +#if ENABLED(SHOW_BOOTSCREEN) + + void lcd_erase_line(const int16_t line) { + lcd.setCursor(0, line); + for (uint8_t i = LCD_WIDTH + 1; --i;) + lcd.write(' '); + } + + // Scroll the PSTR 'text' in a 'len' wide field for 'time' milliseconds at position col,line + void lcd_scroll(const int16_t col, const int16_t line, const char* const text, const int16_t len, const int16_t time) { + char tmp[LCD_WIDTH + 1] = {0}; + int16_t n = max(lcd_strlen_P(text) - len, 0); + for (int16_t i = 0; i <= n; i++) { + strncpy_P(tmp, text + i, min(len, LCD_WIDTH)); + lcd.setCursor(col, line); + lcd_print(tmp); + delay(time / max(n, 1)); + } + } + + static void logo_lines(const char* const extra) { + int16_t indent = (LCD_WIDTH - 8 - lcd_strlen_P(extra)) / 2; + lcd.setCursor(indent, 0); lcd.print('\x00'); lcd_printPGM(PSTR( "------" )); lcd.write('\x01'); + lcd.setCursor(indent, 1); lcd_printPGM(PSTR("|Marlin|")); lcd_printPGM(extra); + lcd.setCursor(indent, 2); lcd.write('\x02'); lcd_printPGM(PSTR( "------" )); lcd.write('\x03'); + } + + void lcd_bootscreen() { + const static PROGMEM byte corner[4][8] = { { + B00000, + B00000, + B00000, + B00000, + B00001, + B00010, + B00100, + B00100 + }, { + B00000, + B00000, + B00000, + B11100, + B11100, + B01100, + B00100, + B00100 + }, { + B00100, + B00010, + B00001, + B00000, + B00000, + B00000, + B00000, + B00000 + }, { + B00100, + B01000, + B10000, + B00000, + B00000, + B00000, + B00000, + B00000 + } }; + for (uint8_t i = 0; i < 4; i++) + createChar_P(i, corner[i]); + + lcd.clear(); + + #define LCD_EXTRA_SPACE (LCD_WIDTH-8) + + #define CENTER_OR_SCROLL(STRING,DELAY) \ + lcd_erase_line(3); \ + if (strlen(STRING) <= LCD_WIDTH) { \ + lcd.setCursor((LCD_WIDTH - lcd_strlen_P(PSTR(STRING))) / 2, 3); \ + lcd_printPGM(PSTR(STRING)); \ + safe_delay(DELAY); \ + } \ + else { \ + lcd_scroll(0, 3, PSTR(STRING), LCD_WIDTH, DELAY); \ + } + + #ifdef STRING_SPLASH_LINE1 + // + // Show the Marlin logo with splash line 1 + // + if (LCD_EXTRA_SPACE >= strlen(STRING_SPLASH_LINE1) + 1) { + // + // Show the Marlin logo, splash line1, and splash line 2 + // + logo_lines(PSTR(" " STRING_SPLASH_LINE1)); + #ifdef STRING_SPLASH_LINE2 + CENTER_OR_SCROLL(STRING_SPLASH_LINE2, 2000); + #else + safe_delay(2000); + #endif + } + else { + // + // Show the Marlin logo with splash line 1 + // After a delay show splash line 2, if it exists + // + #ifdef STRING_SPLASH_LINE2 + #define _SPLASH_WAIT_1 1500 + #else + #define _SPLASH_WAIT_1 2000 + #endif + logo_lines(PSTR("")); + CENTER_OR_SCROLL(STRING_SPLASH_LINE1, _SPLASH_WAIT_1); + #ifdef STRING_SPLASH_LINE2 + CENTER_OR_SCROLL(STRING_SPLASH_LINE2, 1500); + #endif + } + #elif defined(STRING_SPLASH_LINE2) + // + // Show splash line 2 only, alongside the logo if possible + // + if (LCD_EXTRA_SPACE >= strlen(STRING_SPLASH_LINE2) + 1) { + logo_lines(PSTR(" " STRING_SPLASH_LINE2)); + safe_delay(2000); + } + else { + logo_lines(PSTR("")); + CENTER_OR_SCROLL(STRING_SPLASH_LINE2, 2000); + } + #else + // + // Show only the Marlin logo + // + logo_lines(PSTR("")); + safe_delay(2000); + #endif + + lcd.clear(); + + safe_delay(100); + + lcd_set_custom_characters( + #if ENABLED(LCD_PROGRESS_BAR) + false + #endif + ); + } + +#endif // SHOW_BOOTSCREEN + +void lcd_kill_screen() { + lcd.setCursor(0, 0); + lcd_print_utf(lcd_status_message); + #if LCD_HEIGHT < 4 + lcd.setCursor(0, 2); + #else + lcd.setCursor(0, 2); + lcd_printPGM(PSTR(MSG_HALTED)); + lcd.setCursor(0, 3); + #endif + lcd_printPGM(PSTR(MSG_PLEASE_RESET)); +} + +FORCE_INLINE void _draw_axis_label(const AxisEnum axis, const char* const pstr, const bool blink) { + if (blink) + lcd_printPGM(pstr); + else { + if (!axis_homed[axis]) + lcd.write('?'); + else { + #if DISABLED(HOME_AFTER_DEACTIVATE) && DISABLED(DISABLE_REDUCED_ACCURACY_WARNING) + if (!axis_known_position[axis]) + lcd.write(' '); + else + #endif + lcd_printPGM(pstr); + } + } +} + +FORCE_INLINE void _draw_heater_status(const int8_t heater, const char prefix, const bool blink) { + const bool isBed = heater < 0; + + const float t1 = (isBed ? thermalManager.degBed() : thermalManager.degHotend(heater)), + t2 = (isBed ? thermalManager.degTargetBed() : thermalManager.degTargetHotend(heater)); + + if (prefix >= 0) lcd.print(prefix); + + lcd.print(itostr3(t1 + 0.5)); + lcd.write('/'); + + #if HEATER_IDLE_HANDLER + const bool is_idle = (!isBed ? thermalManager.is_heater_idle(heater) : + #if HAS_TEMP_BED + thermalManager.is_bed_idle() + #else + false + #endif + ); + + if (!blink && is_idle) { + lcd.write(' '); + if (t2 >= 10) lcd.write(' '); + if (t2 >= 100) lcd.write(' '); + } + else + #endif + lcd.print(itostr3left(t2 + 0.5)); + + if (prefix >= 0) { + lcd.print((char)LCD_DEGREE_CHAR); + lcd.write(' '); + if (t2 < 10) lcd.write(' '); + } +} + +#if ENABLED(LCD_PROGRESS_BAR) + + inline void lcd_draw_progress_bar(const uint8_t percent) { + const int16_t tix = (int16_t)(percent * (LCD_WIDTH) * 3) / 100, + cel = tix / 3, + rem = tix % 3; + uint8_t i = LCD_WIDTH; + char msg[LCD_WIDTH + 1], b = ' '; + msg[LCD_WIDTH] = '\0'; + while (i--) { + if (i == cel - 1) + b = LCD_STR_PROGRESS[2]; + else if (i == cel && rem != 0) + b = LCD_STR_PROGRESS[rem - 1]; + msg[i] = b; + } + lcd.print(msg); + } + +#endif // LCD_PROGRESS_BAR + +/** +Possible status screens: +16x2 |000/000 B000/000| + |0123456789012345| + +16x4 |000/000 B000/000| + |SD100% Z 000.00| + |F100% T--:--| + |0123456789012345| + +20x2 |T000/000D B000/000D | + |01234567890123456789| + +20x4 |T000/000D B000/000D | + |X 000 Y 000 Z 000.00| + |F100% SD100% T--:--| + |01234567890123456789| + +20x4 |T000/000D B000/000D | + |T000/000D Z 000.00| + |F100% SD100% T--:--| + |01234567890123456789| +*/ +static void lcd_implementation_status_screen() { + const bool blink = lcd_blink(); + + // + // Line 1 + // + + lcd.setCursor(0, 0); + + #if LCD_WIDTH < 20 + + // + // Hotend 0 Temperature + // + _draw_heater_status(0, -1, blink); + + // + // Hotend 1 or Bed Temperature + // + #if HOTENDS > 1 || TEMP_SENSOR_BED != 0 + + lcd.setCursor(8, 0); + #if HOTENDS > 1 + lcd.print((CHAR)LCD_STR_THERMOMETER[0]); + _draw_heater_status(1, -1, blink); + #else + lcd.print((CHAR)LCD_BEDTEMP_CHAR); + _draw_heater_status(-1, -1, blink); + #endif + + #endif // HOTENDS > 1 || TEMP_SENSOR_BED != 0 + + #else // LCD_WIDTH >= 20 + + // + // Hotend 0 Temperature + // + _draw_heater_status(0, LCD_STR_THERMOMETER[0], blink); + + // + // Hotend 1 or Bed Temperature + // + #if HOTENDS > 1 || TEMP_SENSOR_BED != 0 + lcd.setCursor(10, 0); + #if HOTENDS > 1 + _draw_heater_status(1, LCD_STR_THERMOMETER[0], blink); + #else + _draw_heater_status(-1, LCD_BEDTEMP_CHAR, blink); + #endif + + #endif // HOTENDS > 1 || TEMP_SENSOR_BED != 0 + + #endif // LCD_WIDTH >= 20 + + // + // Line 2 + // + + #if LCD_HEIGHT > 2 + + #if LCD_WIDTH < 20 + + #if ENABLED(SDSUPPORT) + lcd.setCursor(0, 2); + lcd_printPGM(PSTR("SD")); + if (IS_SD_PRINTING) + lcd.print(itostr3(card.percentDone())); + else + lcd_printPGM(PSTR("---")); + lcd.write('%'); + #endif // SDSUPPORT + + #else // LCD_WIDTH >= 20 + + lcd.setCursor(0, 1); + + #if HOTENDS > 1 && TEMP_SENSOR_BED != 0 + + // If we both have a 2nd extruder and a heated bed, + // show the heated bed temp on the left, + // since the first line is filled with extruder temps + _draw_heater_status(-1, LCD_BEDTEMP_CHAR, blink); + + #else + // Before homing the axis letters are blinking 'X' <-> '?'. + // When axis is homed but axis_known_position is false the axis letters are blinking 'X' <-> ' '. + // When everything is ok you see a constant 'X'. + + _draw_axis_label(X_AXIS, PSTR(MSG_X), blink); + lcd.print(ftostr4sign(current_position[X_AXIS])); + + lcd.write(' '); + + _draw_axis_label(Y_AXIS, PSTR(MSG_Y), blink); + lcd.print(ftostr4sign(current_position[Y_AXIS])); + + #endif // HOTENDS > 1 || TEMP_SENSOR_BED != 0 + + #endif // LCD_WIDTH >= 20 + + lcd.setCursor(LCD_WIDTH - 8, 1); + _draw_axis_label(Z_AXIS, PSTR(MSG_Z), blink); + lcd.print(ftostr52sp(FIXFLOAT(current_position[Z_AXIS]))); + + #if HAS_LEVELING + lcd.write(leveling_is_active() || blink ? '_' : ' '); + #endif + + #endif // LCD_HEIGHT > 2 + + // + // Line 3 + // + + #if LCD_HEIGHT > 3 + + lcd.setCursor(0, 2); + lcd.print((char)LCD_FEEDRATE_CHAR); + lcd.print(itostr3(feedrate_percentage)); + lcd.write('%'); + + #if LCD_WIDTH >= 20 && ENABLED(SDSUPPORT) + + lcd.setCursor(7, 2); + lcd_printPGM(PSTR("SD")); + if (IS_SD_PRINTING) + lcd.print(itostr3(card.percentDone())); + else + lcd_printPGM(PSTR("---")); + lcd.write('%'); + + #endif // LCD_WIDTH >= 20 && SDSUPPORT + + char buffer[10]; + duration_t elapsed = print_job_timer.duration(); + uint8_t len = elapsed.toDigital(buffer); + + lcd.setCursor(LCD_WIDTH - len - 1, 2); + lcd.print((char)LCD_CLOCK_CHAR); + lcd_print(buffer); + + #endif // LCD_HEIGHT > 3 + + // + // Last Line + // Status Message (which may be a Progress Bar or Filament display) + // + + lcd.setCursor(0, LCD_HEIGHT - 1); + + #if ENABLED(LCD_PROGRESS_BAR) + + // Draw the progress bar if the message has shown long enough + // or if there is no message set. + if (card.isFileOpen() && (ELAPSED(millis(), progress_bar_ms + PROGRESS_BAR_MSG_TIME) || !lcd_status_message[0])) { + const uint8_t percent = card.percentDone(); + if (percent) return lcd_draw_progress_bar(percent); + } + + #elif ENABLED(FILAMENT_LCD_DISPLAY) && ENABLED(SDSUPPORT) + + // Show Filament Diameter and Volumetric Multiplier % + // After allowing lcd_status_message to show for 5 seconds + if (ELAPSED(millis(), previous_lcd_status_ms + 5000UL)) { + lcd_printPGM(PSTR("Dia ")); + lcd.print(ftostr12ns(filament_width_meas)); + lcd_printPGM(PSTR(" V")); + lcd.print(itostr3(100.0 * volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM])); + lcd.write('%'); + return; + } + + #endif // FILAMENT_LCD_DISPLAY && SDSUPPORT + + #if ENABLED(STATUS_MESSAGE_SCROLLING) + static bool last_blink = false; + const uint8_t slen = lcd_strlen(lcd_status_message); + const char *stat = lcd_status_message + status_scroll_pos; + if (slen <= LCD_WIDTH) + lcd_print_utf(stat); // The string isn't scrolling + else { + if (status_scroll_pos <= slen - LCD_WIDTH) + lcd_print_utf(stat); // The string fills the screen + else { + uint8_t chars = LCD_WIDTH; + if (status_scroll_pos < slen) { // First string still visible + lcd_print_utf(stat); // The string leaves space + chars -= slen - status_scroll_pos; // Amount of space left + } + lcd.write('.'); // Always at 1+ spaces left, draw a dot + if (--chars) { + if (status_scroll_pos < slen + 1) // Draw a second dot if there's space + --chars, lcd.write('.'); + if (chars) lcd_print_utf(lcd_status_message, chars); // Print a second copy of the message + } + } + if (last_blink != blink) { + last_blink = blink; + // Skip any non-printing bytes + if (status_scroll_pos < slen) while (!PRINTABLE(lcd_status_message[status_scroll_pos])) status_scroll_pos++; + if (++status_scroll_pos >= slen + 2) status_scroll_pos = 0; + } + } + #else + lcd_print_utf(lcd_status_message); + #endif +} + +#if ENABLED(ULTIPANEL) + + #if ENABLED(ADVANCED_PAUSE_FEATURE) + + static void lcd_implementation_hotend_status(const uint8_t row) { + if (row < LCD_HEIGHT) { + lcd.setCursor(LCD_WIDTH - 9, row); + _draw_heater_status(active_extruder, LCD_STR_THERMOMETER[0], lcd_blink()); + } + } + + #endif // ADVANCED_PAUSE_FEATURE + + static void lcd_implementation_drawmenu_static(const uint8_t row, const char* pstr, const bool center=true, const bool invert=false, const char *valstr=NULL) { + UNUSED(invert); + char c; + int8_t n = LCD_WIDTH; + lcd.setCursor(0, row); + if (center && !valstr) { + int8_t pad = (LCD_WIDTH - lcd_strlen_P(pstr)) / 2; + while (--pad >= 0) { lcd.write(' '); n--; } + } + while (n > 0 && (c = pgm_read_byte(pstr))) { + n -= charset_mapper(c); + pstr++; + } + if (valstr) while (n > 0 && (c = *valstr)) { + n -= charset_mapper(c); + valstr++; + } + while (n-- > 0) lcd.write(' '); + } + + static void lcd_implementation_drawmenu_generic(const bool sel, const uint8_t row, const char* pstr, const char pre_char, const char post_char) { + char c; + uint8_t n = LCD_WIDTH - 2; + lcd.setCursor(0, row); + lcd.print(sel ? pre_char : ' '); + while ((c = pgm_read_byte(pstr)) && n > 0) { + n -= charset_mapper(c); + pstr++; + } + while (n--) lcd.write(' '); + lcd.print(post_char); + } + + static void lcd_implementation_drawmenu_setting_edit_generic(const bool sel, const uint8_t row, const char* pstr, const char pre_char, const char* const data) { + char c; + uint8_t n = LCD_WIDTH - 2 - lcd_strlen(data); + lcd.setCursor(0, row); + lcd.print(sel ? pre_char : ' '); + while ((c = pgm_read_byte(pstr)) && n > 0) { + n -= charset_mapper(c); + pstr++; + } + lcd.write(':'); + while (n--) lcd.write(' '); + lcd_print(data); + } + static void lcd_implementation_drawmenu_setting_edit_generic_P(const bool sel, const uint8_t row, const char* pstr, const char pre_char, const char* const data) { + char c; + uint8_t n = LCD_WIDTH - 2 - lcd_strlen_P(data); + lcd.setCursor(0, row); + lcd.print(sel ? pre_char : ' '); + while ((c = pgm_read_byte(pstr)) && n > 0) { + n -= charset_mapper(c); + pstr++; + } + lcd.write(':'); + while (n--) lcd.write(' '); + lcd_printPGM(data); + } + + #define DRAWMENU_SETTING_EDIT_GENERIC(_src) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, '>', _src) + #define DRAW_BOOL_SETTING(sel, row, pstr, data) lcd_implementation_drawmenu_setting_edit_generic_P(sel, row, pstr, '>', (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF)) + + void lcd_implementation_drawedit(const char* pstr, const char* const value=NULL) { + lcd.setCursor(1, 1); + lcd_printPGM(pstr); + if (value != NULL) { + lcd.write(':'); + const uint8_t valrow = (lcd_strlen_P(pstr) + 1 + lcd_strlen(value) + 1) > (LCD_WIDTH - 2) ? 2 : 1; // Value on the next row if it won't fit + lcd.setCursor((LCD_WIDTH - 1) - (lcd_strlen(value) + 1), valrow); // Right-justified, padded by spaces + lcd.write(' '); // overwrite char if value gets shorter + lcd_print(value); + } + } + + #if ENABLED(SDSUPPORT) + + static void lcd_implementation_drawmenu_sd(const bool sel, const uint8_t row, const char* const pstr, const char* filename, char* const longFilename, const uint8_t concat, const char post_char) { + UNUSED(pstr); + uint8_t n = LCD_WIDTH - concat; + lcd.setCursor(0, row); + lcd.print(sel ? '>' : ' '); + if (longFilename[0]) { + filename = longFilename; + longFilename[n] = '\0'; + } + while (char c = *filename) { + n -= charset_mapper(c); + filename++; + } + while (n--) lcd.write(' '); + lcd.print(post_char); + } + + static void lcd_implementation_drawmenu_sdfile(const bool sel, const uint8_t row, const char* pstr, const char* filename, char* const longFilename) { + lcd_implementation_drawmenu_sd(sel, row, pstr, filename, longFilename, 2, ' '); + } + + static void lcd_implementation_drawmenu_sddirectory(const bool sel, const uint8_t row, const char* pstr, const char* filename, char* const longFilename) { + lcd_implementation_drawmenu_sd(sel, row, pstr, filename, longFilename, 2, LCD_STR_FOLDER[0]); + } + + #endif // SDSUPPORT + + #define lcd_implementation_drawmenu_back(sel, row, pstr, dummy) lcd_implementation_drawmenu_generic(sel, row, pstr, LCD_UPLEVEL_CHAR, LCD_UPLEVEL_CHAR) + #define lcd_implementation_drawmenu_submenu(sel, row, pstr, data) lcd_implementation_drawmenu_generic(sel, row, pstr, '>', LCD_STR_ARROW_RIGHT[0]) + #define lcd_implementation_drawmenu_gcode(sel, row, pstr, gcode) lcd_implementation_drawmenu_generic(sel, row, pstr, '>', ' ') + #define lcd_implementation_drawmenu_function(sel, row, pstr, data) lcd_implementation_drawmenu_generic(sel, row, pstr, '>', ' ') + + #if ENABLED(LCD_HAS_SLOW_BUTTONS) + + extern millis_t next_button_update_ms; + + static uint8_t lcd_implementation_read_slow_buttons() { + #if ENABLED(LCD_I2C_TYPE_MCP23017) + // Reading these buttons this is likely to be too slow to call inside interrupt context + // so they are called during normal lcd_update + uint8_t slow_bits = lcd.readButtons() << B_I2C_BTN_OFFSET; + #if ENABLED(LCD_I2C_VIKI) + if ((slow_bits & (B_MI | B_RI)) && PENDING(millis(), next_button_update_ms)) // LCD clicked + slow_bits &= ~(B_MI | B_RI); // Disable LCD clicked buttons if screen is updated + #endif // LCD_I2C_VIKI + return slow_bits; + #endif // LCD_I2C_TYPE_MCP23017 + } + + #endif // LCD_HAS_SLOW_BUTTONS + + #if ENABLED(LCD_HAS_STATUS_INDICATORS) + + static void lcd_implementation_update_indicators() { + // Set the LEDS - referred to as backlights by the LiquidTWI2 library + static uint8_t ledsprev = 0; + uint8_t leds = 0; + + if (thermalManager.degTargetBed() > 0) leds |= LED_A; + + if (thermalManager.degTargetHotend(0) > 0) leds |= LED_B; + + #if FAN_COUNT > 0 + if (0 + #if HAS_FAN0 + || fanSpeeds[0] + #endif + #if HAS_FAN1 + || fanSpeeds[1] + #endif + #if HAS_FAN2 + || fanSpeeds[2] + #endif + ) leds |= LED_C; + #endif // FAN_COUNT > 0 + + #if HOTENDS > 1 + if (thermalManager.degTargetHotend(1) > 0) leds |= LED_C; + #endif + + if (leds != ledsprev) { + lcd.setBacklight(leds); + ledsprev = leds; + } + } + + #endif // LCD_HAS_STATUS_INDICATORS + + #if ENABLED(AUTO_BED_LEVELING_UBL) + + /** + Possible map screens: + + 16x2 |X000.00 Y000.00| + |(00,00) Z00.000| + + 20x2 | X:000.00 Y:000.00 | + | (00,00) Z:00.000 | + + 16x4 |+-------+(00,00)| + || |X000.00| + || |Y000.00| + |+-------+Z00.000| + + 20x4 | +-------+ (00,00) | + | | | X:000.00| + | | | Y:000.00| + | +-------+ Z:00.000| + */ + + typedef struct { + uint8_t custom_char_bits[ULTRA_Y_PIXELS_PER_CHAR]; + } custom_char; + + typedef struct { + uint8_t column, row; + uint8_t y_pixel_offset, x_pixel_offset; + uint8_t x_pixel_mask; + } coordinate; + + void add_edges_to_custom_char(custom_char * const custom, coordinate * const ul, coordinate * const lr, coordinate * const brc, const uint8_t cell_location); + FORCE_INLINE static void clear_custom_char(custom_char * const cc) { ZERO(cc->custom_char_bits); } + + /* + // This debug routine should be deleted by anybody that sees it. It doesn't belong here + // But I'm leaving it for now until we know the 20x4 Radar Map is working right. + // We may need it again if any funny lines show up on the mesh points. + void dump_custom_char(char *title, custom_char *c) { + SERIAL_PROTOCOLLN(title); + for (uint8_t j = 0; j < 8; j++) { + for (uint8_t i = 7; i >= 0; i--) + SERIAL_PROTOCOLCHAR(TEST(c->custom_char_bits[j], i) ? '1' : '0'); + SERIAL_EOL(); + } + SERIAL_EOL(); + } + //*/ + + coordinate pixel_location(int16_t x, int16_t y) { + coordinate ret_val; + int16_t xp, yp, r, c; + + x++; y++; // +1 because lines on the left and top + + c = x / (ULTRA_X_PIXELS_PER_CHAR); + r = y / (ULTRA_Y_PIXELS_PER_CHAR); + + ret_val.column = c; + ret_val.row = r; + + xp = x - c * (ULTRA_X_PIXELS_PER_CHAR); // get the pixel offsets into the character cell + xp = ULTRA_X_PIXELS_PER_CHAR - 1 - xp; // column within relevant character cell (0 on the right) + yp = y - r * (ULTRA_Y_PIXELS_PER_CHAR); + + ret_val.x_pixel_mask = _BV(xp); + ret_val.x_pixel_offset = xp; + ret_val.y_pixel_offset = yp; + return ret_val; + } + + coordinate pixel_location(uint8_t x, uint8_t y) { return pixel_location((int16_t)x, (int16_t)y); } + + void lcd_implementation_ubl_plot(uint8_t x, uint8_t inverted_y) { + + #if LCD_WIDTH >= 20 + #define _LCD_W_POS 12 + #define _PLOT_X 1 + #define _MAP_X 3 + #define _LABEL(C,X,Y) lcd.setCursor(X, Y); lcd.print(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) + #else + #define _LCD_W_POS 8 + #define _PLOT_X 0 + #define _MAP_X 1 + #define _LABEL(X,Y,C) lcd.setCursor(X, Y); lcd.write(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) + #endif + + #if LCD_HEIGHT <= 3 // 16x2 or 20x2 display + + /** + * Show X and Y positions + */ + _XLABEL(_PLOT_X, 0); + lcd.print(ftostr32(LOGICAL_X_POSITION(pgm_read_float(&ubl._mesh_index_to_xpos[x])))); + + _YLABEL(_LCD_W_POS, 0); + lcd.print(ftostr32(LOGICAL_Y_POSITION(pgm_read_float(&ubl._mesh_index_to_ypos[inverted_y])))); + + lcd.setCursor(_PLOT_X, 0); + + #else // 16x4 or 20x4 display + + coordinate upper_left, lower_right, bottom_right_corner; + custom_char new_char; + uint8_t i, j, k, l, m, n, n_rows, n_cols, y, + bottom_line, right_edge, + x_map_pixels, y_map_pixels, + pixels_per_x_mesh_pnt, pixels_per_y_mesh_pnt, + suppress_x_offset = 0, suppress_y_offset = 0; + + y = GRID_MAX_POINTS_Y - inverted_y - 1; + + upper_left.column = 0; + upper_left.row = 0; + lower_right.column = 0; + lower_right.row = 0; + + lcd_implementation_clear(); + + x_map_pixels = (ULTRA_X_PIXELS_PER_CHAR) * (ULTRA_COLUMNS_FOR_MESH_MAP) - 2; // minus 2 because we are drawing a box around the map + y_map_pixels = (ULTRA_Y_PIXELS_PER_CHAR) * (ULTRA_ROWS_FOR_MESH_MAP) - 2; + + pixels_per_x_mesh_pnt = x_map_pixels / (GRID_MAX_POINTS_X); + pixels_per_y_mesh_pnt = y_map_pixels / (GRID_MAX_POINTS_Y); + + if (pixels_per_x_mesh_pnt >= ULTRA_X_PIXELS_PER_CHAR) { // There are only 2 custom characters available, so the X + pixels_per_x_mesh_pnt = ULTRA_X_PIXELS_PER_CHAR; // size of the mesh point needs to fit within them independent + suppress_x_offset = 1; // of where the starting pixel is located. + } + + if (pixels_per_y_mesh_pnt >= ULTRA_Y_PIXELS_PER_CHAR) { // There are only 2 custom characters available, so the Y + pixels_per_y_mesh_pnt = ULTRA_Y_PIXELS_PER_CHAR; // size of the mesh point needs to fit within them independent + suppress_y_offset = 1; // of where the starting pixel is located. + } + + x_map_pixels = pixels_per_x_mesh_pnt * (GRID_MAX_POINTS_X); // now we have the right number of pixels to make both + y_map_pixels = pixels_per_y_mesh_pnt * (GRID_MAX_POINTS_Y); // directions fit nicely + + right_edge = pixels_per_x_mesh_pnt * (GRID_MAX_POINTS_X) + 1; // find location of right edge within the character cell + bottom_line= pixels_per_y_mesh_pnt * (GRID_MAX_POINTS_Y) + 1; // find location of bottome line within the character cell + + n_rows = bottom_line / (ULTRA_Y_PIXELS_PER_CHAR) + 1; + n_cols = right_edge / (ULTRA_X_PIXELS_PER_CHAR) + 1; + + for (i = 0; i < n_cols; i++) { + lcd.setCursor(i, 0); + lcd.print((char)0x00); // top line of the box + + lcd.setCursor(i, n_rows - 1); + lcd.write(0x01); // bottom line of the box + } + + for (j = 0; j < n_rows; j++) { + lcd.setCursor(0, j); + lcd.write(0x02); // Left edge of the box + lcd.setCursor(n_cols - 1, j); + lcd.write(0x03); // right edge of the box + } + + /** + * If the entire 4th row is not in use, do not put vertical bars all the way down to the bottom of the display + */ + + k = pixels_per_y_mesh_pnt * (GRID_MAX_POINTS_Y) + 2; + l = (ULTRA_Y_PIXELS_PER_CHAR) * n_rows; + if (l > k && l - k >= (ULTRA_Y_PIXELS_PER_CHAR) / 2) { + lcd.setCursor(0, n_rows - 1); // left edge of the box + lcd.write(' '); + lcd.setCursor(n_cols - 1, n_rows - 1); // right edge of the box + lcd.write(' '); + } + + clear_custom_char(&new_char); + new_char.custom_char_bits[0] = 0B11111U; // char #0 is used for the top line of the box + lcd.createChar(0, (uint8_t*)&new_char); + + clear_custom_char(&new_char); + k = (GRID_MAX_POINTS_Y) * pixels_per_y_mesh_pnt + 1; // row of pixels for the bottom box line + l = k % (ULTRA_Y_PIXELS_PER_CHAR); // row within relevant character cell + new_char.custom_char_bits[l] = 0B11111U; // char #1 is used for the bottom line of the box + lcd.createChar(1, (uint8_t*)&new_char); + + clear_custom_char(&new_char); + for (j = 0; j < ULTRA_Y_PIXELS_PER_CHAR; j++) + new_char.custom_char_bits[j] = 0B10000U; // char #2 is used for the left edge of the box + lcd.createChar(2, (uint8_t*)&new_char); + + clear_custom_char(&new_char); + m = (GRID_MAX_POINTS_X) * pixels_per_x_mesh_pnt + 1; // Column of pixels for the right box line + n = m % (ULTRA_X_PIXELS_PER_CHAR); // Column within relevant character cell + i = ULTRA_X_PIXELS_PER_CHAR - 1 - n; // Column within relevant character cell (0 on the right) + for (j = 0; j < ULTRA_Y_PIXELS_PER_CHAR; j++) + new_char.custom_char_bits[j] = (uint8_t)_BV(i); // Char #3 is used for the right edge of the box + lcd.createChar(3, (uint8_t*)&new_char); + + i = x * pixels_per_x_mesh_pnt - suppress_x_offset; + j = y * pixels_per_y_mesh_pnt - suppress_y_offset; + upper_left = pixel_location(i, j); + + k = (x + 1) * pixels_per_x_mesh_pnt - 1 - suppress_x_offset; + l = (y + 1) * pixels_per_y_mesh_pnt - 1 - suppress_y_offset; + lower_right = pixel_location(k, l); + + bottom_right_corner = pixel_location(x_map_pixels, y_map_pixels); + + /** + * First, handle the simple case where everything is within a single character cell. + * If part of the Mesh Plot is outside of this character cell, we will follow up + * and deal with that next. + */ + + //dump_custom_char("at entry:", &new_char); + + clear_custom_char(&new_char); + const uint8_t ypix = min(upper_left.y_pixel_offset + pixels_per_y_mesh_pnt, ULTRA_Y_PIXELS_PER_CHAR); + for (j = upper_left.y_pixel_offset; j < ypix; j++) { + i = upper_left.x_pixel_mask; + for (k = 0; k < pixels_per_x_mesh_pnt; k++) { + new_char.custom_char_bits[j] |= i; + i >>= 1; + } + } + //dump_custom_char("after loops:", &new_char); + + add_edges_to_custom_char(&new_char, &upper_left, &lower_right, &bottom_right_corner, TOP_LEFT); + //dump_custom_char("after add edges", &new_char); + lcd.createChar(4, (uint8_t*)&new_char); + + lcd.setCursor(upper_left.column, upper_left.row); + lcd.write(0x04); + //dump_custom_char("after lcd update:", &new_char); + + /** + * Next, check for two side by side character cells being used to display the Mesh Point + * If found... do the right hand character cell next. + */ + if (upper_left.column == lower_right.column - 1) { + l = upper_left.x_pixel_offset; + clear_custom_char(&new_char); + for (j = upper_left.y_pixel_offset; j < ypix; j++) { + i = _BV(ULTRA_X_PIXELS_PER_CHAR - 1); // Fill in the left side of the right character cell + for (k = 0; k < pixels_per_x_mesh_pnt - 1 - l; k++) { + new_char.custom_char_bits[j] |= i; + i >>= 1; + } + } + add_edges_to_custom_char(&new_char, &upper_left, &lower_right, &bottom_right_corner, TOP_RIGHT); + + lcd.createChar(5, (uint8_t *) &new_char); + + lcd.setCursor(lower_right.column, upper_left.row); + lcd.write(0x05); + } + + /** + * Next, check for two character cells stacked on top of each other being used to display the Mesh Point + */ + if (upper_left.row == lower_right.row - 1) { + l = ULTRA_Y_PIXELS_PER_CHAR - upper_left.y_pixel_offset; // Number of pixel rows in top character cell + k = pixels_per_y_mesh_pnt - l; // Number of pixel rows in bottom character cell + clear_custom_char(&new_char); + for (j = 0; j < k; j++) { + i = upper_left.x_pixel_mask; + for (m = 0; m < pixels_per_x_mesh_pnt; m++) { // Fill in the top side of the bottom character cell + new_char.custom_char_bits[j] |= i; + if (!(i >>= 1)) break; + } + } + add_edges_to_custom_char(&new_char, &upper_left, &lower_right, &bottom_right_corner, LOWER_LEFT); + lcd.createChar(6, (uint8_t *) &new_char); + + lcd.setCursor(upper_left.column, lower_right.row); + lcd.write(0x06); + } + + /** + * Next, check for four character cells being used to display the Mesh Point. If that is + * what is here, we work to fill in the character cell that is down one and to the right one + * from the upper_left character cell. + */ + + if (upper_left.column == lower_right.column - 1 && upper_left.row == lower_right.row - 1) { + l = ULTRA_Y_PIXELS_PER_CHAR - upper_left.y_pixel_offset; // Number of pixel rows in top character cell + k = pixels_per_y_mesh_pnt - l; // Number of pixel rows in bottom character cell + clear_custom_char(&new_char); + for (j = 0; j < k; j++) { + l = upper_left.x_pixel_offset; + i = _BV(ULTRA_X_PIXELS_PER_CHAR - 1); // Fill in the left side of the right character cell + for (m = 0; m < pixels_per_x_mesh_pnt - 1 - l; m++) { // Fill in the top side of the bottom character cell + new_char.custom_char_bits[j] |= i; + i >>= 1; + } + } + add_edges_to_custom_char(&new_char, &upper_left, &lower_right, &bottom_right_corner, LOWER_RIGHT); + lcd.createChar(7, (uint8_t*)&new_char); + + lcd.setCursor(lower_right.column, lower_right.row); + lcd.write(0x07); + } + + #endif + + /** + * Print plot position + */ + lcd.setCursor(_LCD_W_POS, 0); + lcd.write('('); + lcd.print(x); + lcd.write(','); + lcd.print(inverted_y); + lcd.write(')'); + + #if LCD_HEIGHT <= 3 // 16x2 or 20x2 display + + /** + * Print Z values + */ + _ZLABEL(_LCD_W_POS, 1); + if (!isnan(ubl.z_values[x][inverted_y])) + lcd.print(ftostr43sign(ubl.z_values[x][inverted_y])); + else + lcd_printPGM(PSTR(" -----")); + + #else // 16x4 or 20x4 display + + /** + * Show all values at right of screen + */ + _XLABEL(_LCD_W_POS, 1); + lcd.print(ftostr32(LOGICAL_X_POSITION(pgm_read_float(&ubl._mesh_index_to_xpos[x])))); + _YLABEL(_LCD_W_POS, 2); + lcd.print(ftostr32(LOGICAL_Y_POSITION(pgm_read_float(&ubl._mesh_index_to_ypos[inverted_y])))); + + /** + * Show the location value + */ + _ZLABEL(_LCD_W_POS, 3); + if (!isnan(ubl.z_values[x][inverted_y])) + lcd.print(ftostr43sign(ubl.z_values[x][inverted_y])); + else + lcd_printPGM(PSTR(" -----")); + + #endif // LCD_HEIGHT > 3 + } + + void add_edges_to_custom_char(custom_char * const custom, coordinate * const ul, coordinate * const lr, coordinate * const brc, uint8_t cell_location) { + uint8_t i, k; + int16_t n_rows = lr->row - ul->row + 1, + n_cols = lr->column - ul->column + 1; + + /** + * Check if Top line of box needs to be filled in + */ + if (ul->row == 0 && ((cell_location & TOP_LEFT) || (cell_location & TOP_RIGHT))) { // Only fill in the top line for the top character cells + + if (n_cols == 1) { + if (ul->column != brc->column) + custom->custom_char_bits[0] = 0xFF; // Single column in middle + else + for (i = brc->x_pixel_offset; i < ULTRA_X_PIXELS_PER_CHAR; i++) // Single column on right side + SBI(custom->custom_char_bits[0], i); + } + else if ((cell_location & TOP_LEFT) || lr->column != brc->column) // Multiple column in the middle or with right cell in middle + custom->custom_char_bits[0] = 0xFF; + else + for (i = brc->x_pixel_offset; i < ULTRA_X_PIXELS_PER_CHAR; i++) + SBI(custom->custom_char_bits[0], i); + } + + /** + * Check if left line of box needs to be filled in + */ + if ((cell_location & TOP_LEFT) || (cell_location & LOWER_LEFT)) { + if (ul->column == 0) { // Left column of characters on LCD Display + k = ul->row == brc->row ? brc->y_pixel_offset : ULTRA_Y_PIXELS_PER_CHAR; // If it isn't the last row... do the full character cell + for (i = 0; i < k; i++) + SBI(custom->custom_char_bits[i], ULTRA_X_PIXELS_PER_CHAR - 1); + } + } + + /** + * Check if bottom line of box needs to be filled in + */ + + // Single row of mesh plot cells + if (n_rows == 1 /* && (cell_location == TOP_LEFT || cell_location == TOP_RIGHT) */ && ul->row == brc->row) { + if (n_cols == 1) // Single row, single column case + k = ul->column == brc->column ? brc->x_pixel_mask : 0x01; + else if (cell_location & TOP_RIGHT) // Single row, multiple column case + k = lr->column == brc->column ? brc->x_pixel_mask : 0x01; + else // Single row, left of multiple columns + k = 0x01; + while (k < _BV(ULTRA_X_PIXELS_PER_CHAR)) { + custom->custom_char_bits[brc->y_pixel_offset] |= k; + k <<= 1; + } + } + + // Double row of characters on LCD Display + // And this is a bottom custom character + if (n_rows == 2 && (cell_location == LOWER_LEFT || cell_location == LOWER_RIGHT) && lr->row == brc->row) { + if (n_cols == 1) // Double row, single column case + k = ul->column == brc->column ? brc->x_pixel_mask : 0x01; + else if (cell_location & LOWER_RIGHT) // Double row, multiple column case + k = lr->column == brc->column ? brc->x_pixel_mask : 0x01; + else // Double row, left of multiple columns + k = 0x01; + while (k < _BV(ULTRA_X_PIXELS_PER_CHAR)) { + custom->custom_char_bits[brc->y_pixel_offset] |= k; + k <<= 1; + } + } + + /** + * Check if right line of box needs to be filled in + */ + // Nothing to do if the lower right part of the mesh pnt isn't in the same column as the box line + if (lr->column == brc->column) { + // This mesh point is in the same character cell as the right box line + if (ul->column == brc->column || (cell_location & TOP_RIGHT) || (cell_location & LOWER_RIGHT)) { + // If not the last row... do the full character cell + k = ul->row == brc->row ? brc->y_pixel_offset : ULTRA_Y_PIXELS_PER_CHAR; + for (i = 0; i < k; i++) custom->custom_char_bits[i] |= brc->x_pixel_mask; + } + } + } + + #endif // AUTO_BED_LEVELING_UBL + +#endif // ULTIPANEL + +#endif // ULTRALCD_IMPL_HD44780_H diff --git a/trunk/Arduino/Marlin_1.1.6/ultralcd_st7565_u8glib_VIKI.h b/trunk/Arduino/Marlin_1.1.6/ultralcd_st7565_u8glib_VIKI.h new file mode 100644 index 00000000..b7bb2e26 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/ultralcd_st7565_u8glib_VIKI.h @@ -0,0 +1,253 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2016, 2017 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#ifndef ULCDST7565_H +#define ULCDST7565_H + +#include + +#define ST7565_CLK_PIN DOGLCD_SCK +#define ST7565_DAT_PIN DOGLCD_MOSI +#define ST7565_CS_PIN DOGLCD_CS +#define ST7565_A0_PIN DOGLCD_A0 + +#define LCD_PIXEL_WIDTH 128 +#define LCD_PIXEL_HEIGHT 64 +#define PAGE_HEIGHT 8 + +//set optimization so ARDUINO optimizes this file +#pragma GCC optimize (3) + +// If you want you can define your own set of delays in Configuration.h +//#define ST7565_DELAY_1 DELAY_0_NOP +//#define ST7565_DELAY_2 DELAY_0_NOP +//#define ST7565_DELAY_3 DELAY_0_NOP + +/* +#define ST7565_DELAY_1 u8g_10MicroDelay() +#define ST7565_DELAY_2 u8g_10MicroDelay() +#define ST7565_DELAY_3 u8g_10MicroDelay() +*/ + +#if F_CPU >= 20000000 + #define CPU_ST7565_DELAY_1 DELAY_0_NOP + #define CPU_ST7565_DELAY_2 DELAY_0_NOP + #define CPU_ST7565_DELAY_3 DELAY_1_NOP +#elif (MOTHERBOARD == BOARD_3DRAG) || (MOTHERBOARD == BOARD_K8200) || (MOTHERBOARD == BOARD_K8400) + #define CPU_ST7565_DELAY_1 DELAY_0_NOP + #define CPU_ST7565_DELAY_2 DELAY_3_NOP + #define CPU_ST7565_DELAY_3 DELAY_0_NOP +#elif (MOTHERBOARD == BOARD_MINIRAMBO) + #define CPU_ST7565_DELAY_1 DELAY_0_NOP + #define CPU_ST7565_DELAY_2 DELAY_4_NOP + #define CPU_ST7565_DELAY_3 DELAY_0_NOP +#elif (MOTHERBOARD == BOARD_RAMBO) + #define CPU_ST7565_DELAY_1 DELAY_0_NOP + #define CPU_ST7565_DELAY_2 DELAY_0_NOP + #define CPU_ST7565_DELAY_3 DELAY_0_NOP +#elif F_CPU == 16000000 + #define CPU_ST7565_DELAY_1 DELAY_0_NOP + #define CPU_ST7565_DELAY_2 DELAY_0_NOP + #define CPU_ST7565_DELAY_3 DELAY_1_NOP +#else + #error "No valid condition for delays in 'ultralcd_st7565_u8glib_VIKI.h'" +#endif + +#ifndef ST7565_DELAY_1 + #define ST7565_DELAY_1 CPU_ST7565_DELAY_1 +#endif +#ifndef ST7565_DELAY_2 + #define ST7565_DELAY_2 CPU_ST7565_DELAY_2 +#endif +#ifndef ST7565_DELAY_3 + #define ST7565_DELAY_3 CPU_ST7565_DELAY_3 +#endif + +#if ENABLED(SHARED_SPI) // Re-ARM requires that the LCD and the SD card share a single SPI + + #define ST7565_WRITE_BYTE(a) { spiSend((uint8_t)a); U8G_DELAY(); } + #define ST7560_WriteSequence(count, pointer) { uint8_t *ptr = pointer; for (uint8_t i = 0; i < count; i++) {spiSend( *ptr++);} DELAY_10US; } + +#else + #define ST7565_SND_BIT \ + WRITE(ST7565_CLK_PIN, LOW); ST7565_DELAY_1; \ + WRITE(ST7565_DAT_PIN, val & 0x80); ST7565_DELAY_2; \ + WRITE(ST7565_CLK_PIN, HIGH); ST7565_DELAY_3; \ + WRITE(ST7565_CLK_PIN, LOW);\ + val <<= 1 + + static void ST7565_SWSPI_SND_8BIT(uint8_t val) { + ST7565_SND_BIT; // 1 + ST7565_SND_BIT; // 2 + ST7565_SND_BIT; // 3 + ST7565_SND_BIT; // 4 + ST7565_SND_BIT; // 5 + ST7565_SND_BIT; // 6 + ST7565_SND_BIT; // 7 + ST7565_SND_BIT; // 8 + } + + #define ST7565_WRITE_BYTE(a) { ST7565_SWSPI_SND_8BIT((uint8_t)a); U8G_DELAY(); } + #define ST7560_WriteSequence(count, pointer) { uint8_t *ptr = pointer; for (uint8_t i = 0; i < count; i++) {ST7565_SWSPI_SND_8BIT( *ptr++);} DELAY_10US; } +#endif + +#if defined(DOGM_SPI_DELAY_US) && DOGM_SPI_DELAY_US > 0 + #define U8G_DELAY() delayMicroseconds(DOGM_SPI_DELAY_US) +#else + #define U8G_DELAY() u8g_10MicroDelay() +#endif + +#define ST7565_CS() { WRITE(ST7565_CS_PIN,1); U8G_DELAY(); } +#define ST7565_NCS() { WRITE(ST7565_CS_PIN,0); } +#define ST7565_A0() { WRITE(ST7565_A0_PIN,1); U8G_DELAY(); } +#define ST7565_NA0() { WRITE(ST7565_A0_PIN,0); } + + +uint8_t u8g_dev_st7565_64128n_2x_VIKI_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg) { + switch (msg) { + case U8G_DEV_MSG_INIT: { + OUT_WRITE(ST7565_CS_PIN, LOW); + #if ENABLED(SHARED_SPI) + u8g_Delay(250); + spiBegin(); + #ifndef SPI_SPEED + #define SPI_SPEED SPI_FULL_SPEED // use same SPI speed as SD card + #endif + spiInit(SPI_SPEED); + #else + OUT_WRITE(ST7565_DAT_PIN, LOW); + OUT_WRITE(ST7565_CLK_PIN, LOW); + #endif + OUT_WRITE(ST7565_A0_PIN, LOW); + + ST7565_CS(); /* disable chip */ + ST7565_NA0(); /* instruction mode */ + ST7565_NCS(); /* enable chip */ + + ST7565_WRITE_BYTE(0x0A2); /* 0x0A2: LCD bias 1/9 (according to Displaytech 64128N datasheet) */ + ST7565_WRITE_BYTE(0x0A0); /* Normal ADC Select (according to Displaytech 64128N datasheet) */ + + ST7565_WRITE_BYTE(0x0C8); /* common output mode: set scan direction normal operation/SHL Select; 0x0C0 --> SHL = 0; normal; 0x0C8 --> SHL = 1 */ + ST7565_WRITE_BYTE(0x040); /* Display start line for Displaytech 64128N */ + + ST7565_WRITE_BYTE(0x028 | 0x04); /* power control: turn on voltage converter */ + //U8G_ESC_DLY(50); /* delay 50 ms - hangs after a reset if used */ + + ST7565_WRITE_BYTE(0x028 | 0x06); /* power control: turn on voltage regulator */ + //U8G_ESC_DLY(50); /* delay 50 ms - hangs after a reset if used */ + + ST7565_WRITE_BYTE(0x028 | 0x07); /* power control: turn on voltage follower */ + //U8G_ESC_DLY(50); /* delay 50 ms - hangs after a reset if used */ + + ST7565_WRITE_BYTE(0x010); /* Set V0 voltage resistor ratio. Setting for controlling brightness of Displaytech 64128N */ + + ST7565_WRITE_BYTE(0x0A6); /* display normal, bit val 0: LCD pixel off. */ + + ST7565_WRITE_BYTE(0x081); /* set contrast */ + ST7565_WRITE_BYTE(0x01E); /* Contrast value. Setting for controlling brightness of Displaytech 64128N */ + + ST7565_WRITE_BYTE(0x0AF); /* display on */ + + U8G_ESC_DLY(100); /* delay 100 ms */ + ST7565_WRITE_BYTE(0x0A5); /* display all points; ST7565 */ + U8G_ESC_DLY(100); /* delay 100 ms */ + U8G_ESC_DLY(100); /* delay 100 ms */ + ST7565_WRITE_BYTE(0x0A4); /* normal display */ + ST7565_CS(); /* disable chip */ + } /* end of sequence */ + break; + + case U8G_DEV_MSG_STOP: break; + + case U8G_DEV_MSG_PAGE_NEXT: { + u8g_pb_t *pb = (u8g_pb_t *)(dev->dev_mem); + ST7565_CS(); /* disable chip */ + ST7565_NA0(); /* instruction mode */ + ST7565_NCS(); /* enable chip */ + ST7565_WRITE_BYTE(0x010); /* set upper 4 bit of the col adr to 0x10 */ + ST7565_WRITE_BYTE(0x000); /* set lower 4 bit of the col adr to 0x00. Changed for DisplayTech 64128N */ + /* end of sequence */ + ST7565_WRITE_BYTE(0x0B0 | (2*pb->p.page));; /* select current page (ST7565R) */ + ST7565_A0(); /* data mode */ + ST7560_WriteSequence( (uint8_t) pb->width, (uint8_t *)pb->buf); + ST7565_CS(); /* disable chip */ + ST7565_NA0(); /* instruction mode */ + ST7565_NCS(); /* enable chip */ + ST7565_WRITE_BYTE(0x010); /* set upper 4 bit of the col adr to 0x10 */ + ST7565_WRITE_BYTE(0x000); /* set lower 4 bit of the col adr to 0x00. Changed for DisplayTech 64128N */ + /* end of sequence */ + ST7565_WRITE_BYTE(0x0B0 | (2*pb->p.page+1)); /* select current page (ST7565R) */ + ST7565_A0(); /* data mode */ + ST7560_WriteSequence( (uint8_t) pb->width, (uint8_t *)(pb->buf)+pb->width); + ST7565_CS(); /* disable chip */ + } + break; + + case U8G_DEV_MSG_CONTRAST: + ST7565_NCS(); + ST7565_NA0(); /* instruction mode */ + ST7565_WRITE_BYTE(0x081); + ST7565_WRITE_BYTE((*(uint8_t *)arg) >> 2); + ST7565_CS(); /* disable chip */ + return 1; + + case U8G_DEV_MSG_SLEEP_ON: + ST7565_NA0(); /* instruction mode */ + ST7565_NCS(); /* enable chip */ + ST7565_WRITE_BYTE(0x0AC); /* static indicator off */ + ST7565_WRITE_BYTE(0x000); /* indicator register set (not sure if this is required) */ + ST7565_WRITE_BYTE(0x0AE); /* display off */ + ST7565_WRITE_BYTE(0x0A5); /* all points on */ + ST7565_CS(); /* disable chip , bugfix 12 nov 2014 */ + /* end of sequence */ + return 1; + + case U8G_DEV_MSG_SLEEP_OFF: + ST7565_NA0(); /* instruction mode */ + ST7565_NCS(); /* enable chip */ + ST7565_WRITE_BYTE(0x0A4); /* all points off */ + ST7565_WRITE_BYTE(0x0AF); /* display on */ + U8G_ESC_DLY(50); /* delay 50 ms */ + ST7565_CS(); /* disable chip , bugfix 12 nov 2014 */ + /* end of sequence */ + return 1; + } + return u8g_dev_pb16v1_base_fn(u8g, dev, msg, arg); +} + +uint8_t u8g_dev_st7565_64128n_2x_VIKI_buf[LCD_PIXEL_WIDTH*2] U8G_NOCOMMON; +u8g_pb_t u8g_dev_st7565_64128n_2x_VIKI_pb = {{16, LCD_PIXEL_HEIGHT, 0, 0, 0}, LCD_PIXEL_WIDTH, u8g_dev_st7565_64128n_2x_VIKI_buf}; +u8g_dev_t u8g_dev_st7565_64128n_2x_VIKI_sw_spi = {u8g_dev_st7565_64128n_2x_VIKI_fn, &u8g_dev_st7565_64128n_2x_VIKI_pb, &u8g_com_null_fn}; + +class U8GLIB_ST7565_64128n_2x_VIKI : public U8GLIB { + public: + U8GLIB_ST7565_64128n_2x_VIKI(uint8_t dummy) + : U8GLIB(&u8g_dev_st7565_64128n_2x_VIKI_sw_spi) + { } + U8GLIB_ST7565_64128n_2x_VIKI(uint8_t sck, uint8_t mosi, uint8_t cs, uint8_t a0, uint8_t reset = U8G_PIN_NONE) + : U8GLIB(&u8g_dev_st7565_64128n_2x_VIKI_sw_spi) + { } +}; + +#pragma GCC reset_options + +#endif // ULCDST7565_H diff --git a/trunk/Arduino/Marlin_1.1.6/ultralcd_st7920_u8glib_rrd.h b/trunk/Arduino/Marlin_1.1.6/ultralcd_st7920_u8glib_rrd.h new file mode 100644 index 00000000..150b850d --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/ultralcd_st7920_u8glib_rrd.h @@ -0,0 +1,186 @@ +/** + * 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 . + * + */ + +#ifndef ULCDST7920_H +#define ULCDST7920_H + +#include + +#define ST7920_CLK_PIN LCD_PINS_D4 +#define ST7920_DAT_PIN LCD_PINS_ENABLE +#define ST7920_CS_PIN LCD_PINS_RS + +//#define PAGE_HEIGHT 8 //128 byte framebuffer +#define PAGE_HEIGHT 16 //256 byte framebuffer +//#define PAGE_HEIGHT 32 //512 byte framebuffer + +#define LCD_PIXEL_WIDTH 128 +#define LCD_PIXEL_HEIGHT 64 + +//set optimization so ARDUINO optimizes this file +#pragma GCC optimize (3) + +// If you want you can define your own set of delays in Configuration.h +//#define ST7920_DELAY_1 DELAY_0_NOP +//#define ST7920_DELAY_2 DELAY_0_NOP +//#define ST7920_DELAY_3 DELAY_0_NOP + +#if F_CPU >= 20000000 + #define CPU_ST7920_DELAY_1 DELAY_0_NOP + #define CPU_ST7920_DELAY_2 DELAY_0_NOP + #define CPU_ST7920_DELAY_3 DELAY_1_NOP +#elif (MOTHERBOARD == BOARD_3DRAG) || (MOTHERBOARD == BOARD_K8200) || (MOTHERBOARD == BOARD_K8400) + #define CPU_ST7920_DELAY_1 DELAY_0_NOP + #define CPU_ST7920_DELAY_2 DELAY_3_NOP + #define CPU_ST7920_DELAY_3 DELAY_0_NOP +#elif (MOTHERBOARD == BOARD_MINIRAMBO) + #define CPU_ST7920_DELAY_1 DELAY_0_NOP + #define CPU_ST7920_DELAY_2 DELAY_4_NOP + #define CPU_ST7920_DELAY_3 DELAY_0_NOP +#elif (MOTHERBOARD == BOARD_RAMBO) + #define CPU_ST7920_DELAY_1 DELAY_0_NOP + #define CPU_ST7920_DELAY_2 DELAY_0_NOP + #define CPU_ST7920_DELAY_3 DELAY_0_NOP +#elif F_CPU == 16000000 + #define CPU_ST7920_DELAY_1 DELAY_0_NOP + #define CPU_ST7920_DELAY_2 DELAY_0_NOP + #define CPU_ST7920_DELAY_3 DELAY_1_NOP +#else + #error "No valid condition for delays in 'ultralcd_st7920_u8glib_rrd.h'" +#endif + +#ifndef ST7920_DELAY_1 + #define ST7920_DELAY_1 CPU_ST7920_DELAY_1 +#endif +#ifndef ST7920_DELAY_2 + #define ST7920_DELAY_2 CPU_ST7920_DELAY_2 +#endif +#ifndef ST7920_DELAY_3 + #define ST7920_DELAY_3 CPU_ST7920_DELAY_3 +#endif + +#define ST7920_SND_BIT \ + WRITE(ST7920_CLK_PIN, LOW); ST7920_DELAY_1; \ + WRITE(ST7920_DAT_PIN, val & 0x80); ST7920_DELAY_2; \ + WRITE(ST7920_CLK_PIN, HIGH); ST7920_DELAY_3; \ + val <<= 1 + +static void ST7920_SWSPI_SND_8BIT(uint8_t val) { + ST7920_SND_BIT; // 1 + ST7920_SND_BIT; // 2 + ST7920_SND_BIT; // 3 + ST7920_SND_BIT; // 4 + ST7920_SND_BIT; // 5 + ST7920_SND_BIT; // 6 + ST7920_SND_BIT; // 7 + ST7920_SND_BIT; // 8 +} + +#if defined(DOGM_SPI_DELAY_US) && DOGM_SPI_DELAY_US > 0 + #define U8G_DELAY() delayMicroseconds(DOGM_SPI_DELAY_US) +#else + #define U8G_DELAY() u8g_10MicroDelay() +#endif + +#define ST7920_CS() { WRITE(ST7920_CS_PIN,1); U8G_DELAY(); } +#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_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(); } + +uint8_t u8g_dev_rrd_st7920_128x64_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg) { + uint8_t i, y; + switch (msg) { + case U8G_DEV_MSG_INIT: { + OUT_WRITE(ST7920_CS_PIN, LOW); + OUT_WRITE(ST7920_DAT_PIN, LOW); + OUT_WRITE(ST7920_CLK_PIN, HIGH); + + ST7920_CS(); + u8g_Delay(120); //initial delay for boot up + ST7920_SET_CMD(); + ST7920_WRITE_BYTE(0x08); //display off, cursor+blink off + ST7920_WRITE_BYTE(0x01); //clear CGRAM ram + u8g_Delay(15); //delay for CGRAM clear + ST7920_WRITE_BYTE(0x3E); //extended mode + GDRAM active + for (y = 0; y < (LCD_PIXEL_HEIGHT) / 2; y++) { //clear GDRAM + ST7920_WRITE_BYTE(0x80 | y); //set y + ST7920_WRITE_BYTE(0x80); //set x = 0 + ST7920_SET_DAT(); + for (i = 0; i < 2 * (LCD_PIXEL_WIDTH) / 8; i++) //2x width clears both segments + ST7920_WRITE_BYTE(0); + ST7920_SET_CMD(); + } + ST7920_WRITE_BYTE(0x0C); //display on, cursor+blink off + ST7920_NCS(); + } + break; + + case U8G_DEV_MSG_STOP: break; + + case U8G_DEV_MSG_PAGE_NEXT: { + uint8_t* ptr; + u8g_pb_t* pb = (u8g_pb_t*)(dev->dev_mem); + y = pb->p.page_y0; + ptr = (uint8_t*)pb->buf; + + ST7920_CS(); + for (i = 0; i < PAGE_HEIGHT; i ++) { + ST7920_SET_CMD(); + if (y < 32) { + ST7920_WRITE_BYTE(0x80 | y); //y + ST7920_WRITE_BYTE(0x80); //x=0 + } + else { + ST7920_WRITE_BYTE(0x80 | (y - 32)); //y + ST7920_WRITE_BYTE(0x80 | 8); //x=64 + } + ST7920_SET_DAT(); + ST7920_WRITE_BYTES(ptr, (LCD_PIXEL_WIDTH) / 8); //ptr is incremented inside of macro + y++; + } + ST7920_NCS(); + } + break; + } + #if PAGE_HEIGHT == 8 + return u8g_dev_pb8h1_base_fn(u8g, dev, msg, arg); + #elif PAGE_HEIGHT == 16 + return u8g_dev_pb16h1_base_fn(u8g, dev, msg, arg); + #else + return u8g_dev_pb32h1_base_fn(u8g, dev, msg, arg); + #endif +} + +uint8_t u8g_dev_st7920_128x64_rrd_buf[(LCD_PIXEL_WIDTH) * (PAGE_HEIGHT) / 8] U8G_NOCOMMON; +u8g_pb_t u8g_dev_st7920_128x64_rrd_pb = {{PAGE_HEIGHT, LCD_PIXEL_HEIGHT, 0, 0, 0}, LCD_PIXEL_WIDTH, u8g_dev_st7920_128x64_rrd_buf}; +u8g_dev_t u8g_dev_st7920_128x64_rrd_sw_spi = {u8g_dev_rrd_st7920_128x64_fn, &u8g_dev_st7920_128x64_rrd_pb, &u8g_com_null_fn}; + +class U8GLIB_ST7920_128X64_RRD : public U8GLIB { + public: + U8GLIB_ST7920_128X64_RRD(uint8_t dummy) : U8GLIB(&u8g_dev_st7920_128x64_rrd_sw_spi) { UNUSED(dummy); } +}; + +#pragma GCC reset_options + +#endif // ULCDST7920_H diff --git a/trunk/Arduino/Marlin_1.1.6/utf_mapper.h b/trunk/Arduino/Marlin_1.1.6/utf_mapper.h new file mode 100644 index 00000000..c49e6fc4 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/utf_mapper.h @@ -0,0 +1,671 @@ +/** + * 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 . + * + */ + +#ifndef UTF_MAPPER_H +#define UTF_MAPPER_H + +#include "language.h" + +#if ENABLED(DOGLCD) + #define HARDWARE_CHAR_OUT(C) u8g.print((char)(C)) +#else + #define HARDWARE_CHAR_OUT(C) lcd.write((char)(C)) +#endif + +#if DISABLED(SIMULATE_ROMFONT) && ENABLED(DOGLCD) + #if ENABLED(DISPLAY_CHARSET_ISO10646_1) \ + || ENABLED(DISPLAY_CHARSET_ISO10646_5) \ + || ENABLED(DISPLAY_CHARSET_ISO10646_KANA) \ + || ENABLED(DISPLAY_CHARSET_ISO10646_GREEK) \ + || ENABLED(DISPLAY_CHARSET_ISO10646_TR) + #define MAPPER_ONE_TO_ONE + #endif +#else // SIMULATE_ROMFONT || !DOGLCD + #if DISPLAY_CHARSET_HD44780 == JAPANESE + #if ENABLED(MAPPER_C2C3) + const PROGMEM uint8_t utf_recode[] = + { // 0 1 2 3 4 5 6 7 8 9 a b c d e f This is fair for symbols + 0x20,0x3F,0xEC,0xED,0x3F,0x5C,0x7C,0x3F,0x22,0x63,0x61,0x7F,0x3F,0x3F,0x52,0xB0, // c2a + //' ' ¢ £ ­ l " c a « R + 0xDF,0x3F,0x32,0x33,0x27,0xE4,0xF1,0xA5,0x2C,0x31,0xDF,0x7E,0x3F,0x3F,0x3F,0x3F, // c2b but relatively bad for letters. + // ° 2 3 ` N p . , 1 ° » + 0x3F,0x3F,0x3F,0x3F,0xE1,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F, // c38 + // ä + 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0xEF,0x78,0x3F,0x3F,0x3F,0x3F,0xF5,0x3F,0x3F,0xE2, // c39 missing characters display as '?' + // ö x ü ß + 0x3F,0x3F,0x3F,0x3F,0xE1,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F, // c3a + // ä + 0x3F,0xEE,0x3F,0x3F,0x3F,0x3F,0xEF,0xFD,0x3F,0x3F,0x3F,0x3F,0xF5,0x3F,0x3F,0x3F // c3b + // n ö ÷ ü + }; + #elif ENABLED(MAPPER_E382E383) + const PROGMEM uint8_t utf_recode[] = + { // 0 1 2 3 4 5 6 7 8 9 a b c d e f + 0x3D,0xB1,0xB1,0xA8,0xB2,0xA9,0xB3,0xAA,0xB4,0xAB,0xB5,0xB6,0xB6,0xB7,0xB7,0xB8, // e382a Please test and correct + // = ア ア ィ イ ゥ ウ ェ エ ォ オ ガ ガ キ キ ク + 0xB8,0xB9,0xB9,0xBA,0xBA,0xBB,0xBB,0xBC,0xBC,0xBD,0xBD,0xBE,0xBE,0xBF,0xBF,0xC0, // e382b + // ク ケ ケ コ コ サ サ シ シ ス ス セ セ ソ ソ タ + 0xC0,0xC1,0xC1,0xC2,0xC2,0xC2,0xC3,0xC3,0xC4,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA, // e3838 + // タ チ チ ッ ッ ッ テ テ ト ト ナ ニ ヌ ネ ノ ハ + 0xCA,0xCA,0xCB,0xCB,0xCB,0xCC,0xCC,0xCC,0xCD,0xCD,0xCD,0xCE,0xCE,0xCE,0xCF,0xD0, // e3839 + // ハ ハ ヒ ヒ ヒ フ フ フ ヘ ヘ ヘ ホ ホ ホ マ ミ + 0xD1,0xD2,0xD3,0xD4,0xD4,0xD5,0xD5,0xAE,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDC, // e383a + // ム メ モ ャ ャ ユ ユ ョ ヨ ラ リ ル レ ロ ワ ワ + 0xEC,0xA7,0xA6,0xDD,0xCC,0x3F,0x3F,0x3F,0x3F,0x3F,0xA6,0xA5,0xB0,0xA4,0xA4,0x3F // e383b + // ヰ ヱ ヲ ン フ ? ? ? ? ? ヲ ・ ー ヽ ヽ ? + }; + #elif ENABLED(MAPPER_D0D1) + #error "Cyrillic on a JAPANESE display makes no sense. There are no matching symbols." + #endif + + #elif DISPLAY_CHARSET_HD44780 == WESTERN + #if ENABLED(MAPPER_C2C3) + const PROGMEM uint8_t utf_recode[] = + { // 0 1 2 3 4 5 6 7 8 9 a b c d e f This is relative complete. + 0x20,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0x22,0xA9,0xAA,0xAB,0x3F,0x3F,0xAE,0x3F, // c2a ¡¢£¤¥¦§¨©ª«¬­®¯ + //' ' ¡ ¢ £ ¤ ¥ ¦ § " © ª « ? ? ® ? + 0xB0,0xB1,0xB2,0xB3,0x27,0xB5,0xB6,0xB7,0x2C,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, // c2b °±²³´µ¶·¸¹º»¼½¾¿ + // ° ± ³ ² ? µ ¶ · , ¹ º » ¼ ½ ¾ ¿ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, // c38 ÀÁÃÄÅÆÇÈÉÊËÌÍÎÏ + // À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï + 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, // c39 ÐÑÓÔÕÖרÙÚÛÜÝÞß + // Ð Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ü Ý Þ ß + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, // c3a àáãäåæçèéêëìíîï + // à á â ã ä å æ ç è é ê ë ì í î ï + 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF // c3b ðñóôõö÷øùúûüýþÿ + // ð ñ ò ó ô õ ö ÷ ø ù ú û ü ý þ ÿ + }; + #elif ENABLED(MAPPER_D0D1) + #define MAPPER_D0D1_MOD + const PROGMEM uint8_t utf_recode[] = + {//0 1 2 3 4 5 6 7 8 9 a b c d e f + 0x41,0x80,0x42,0x92,0x81,0x45,0x82,0x83,0x84,0x85,0x4B,0x86,0x4D,0x48,0x4F,0x87, // d0a + // A Б B Г Д E Ж З И Й K Л M H O П + 0x50,0x43,0x54,0x88,0xD8,0x58,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x62,0x8F,0xAC,0xAD, // d0b + // P C T У Ф X Ч ч Ш Щ Ъ Ы b Э Ю Я + 0x61,0x36,0x42,0x92,0x81,0x65,0x82,0xB3,0x84,0x85,0x6B,0x86,0x4D,0x48,0x6F,0x87, // d18 + // a 6 B Г Д e Ж ³ И Й k Л M H o П + 0x70,0x63,0x54,0x79,0xD8,0x78,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x62,0x8F,0xAC,0xAD // d19 + // p c T y Ф x Ч ч Ш Щ Ъ Ы b Э Ю Я + }; + #elif ENABLED(MAPPER_E382E383) + #error "Katakana on a WESTERN display makes no sense. There are no matching symbols." + #endif + + #elif DISPLAY_CHARSET_HD44780 == CYRILLIC + #if ENABLED(MAPPER_D0D1) + #define MAPPER_D0D1_MOD + // it is a Russian alphabet translation + // except 0401 --> 0xA2 = Ё, 0451 --> 0xB5 = ё + const PROGMEM uint8_t utf_recode[] = + { 0x41,0xA0,0x42,0xA1,0xE0,0x45,0xA3,0xA4, // unicode U+0400 to U+047f + // A Б->Ё B Г Д E Ж З // 0 Ѐ Ё Ђ Ѓ Є Ѕ І Ї + 0xA5,0xA6,0x4B,0xA7,0x4D,0x48,0x4F,0xA8, // Ј Љ Њ Ћ Ќ Ѝ Ў Џ + // И Й K Л M H O П // 1 А Б В Г Д Е Ж З + 0x50,0x43,0x54,0xA9,0xAA,0x58,0xE1,0xAB, // И Й К Л М Н О П + // P C T У Ф X Ч ч // 2 Р С Т У Ф Х Г Ч + 0xAC,0xE2,0xAD,0xAE,0x62,0xAF,0xB0,0xB1, // Ш Щ Ъ Ы Ь Э Ю Я + // Ш Щ Ъ Ы b Э Ю Я // 3 а б в г д е ж з + 0x61,0xB2,0xB3,0xB4,0xE3,0x65,0xB6,0xB7, // и й к л м н о п + // a б->ё в г д e ж з // 4 р с т у ф х ц ч + 0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0x6F,0xBE, // ш щ ъ ы ь э ю я + // и й к л м н o п // 5 ѐ ё ђ ѓ є ѕ і ї + 0x70,0x63,0xBF,0x79,0xE4,0x78,0xE5,0xC0, // ј љ њ ћ ќ ѝ ў џ + // p c т y ф x ц ч // 6 Ѡ ѡ Ѣ ѣ Ѥ ѥ Ѧ ѧ + 0xC1,0xE6,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7 // Ѫ ѩ Ѫ ѫ Ѭ ѭ Ѯ ѯ + // ш щ ъ ы ь э ю я // 7 Ѱ ѱ Ѳ ѳ Ѵ ѵ Ѷ ѷ + }; // ѻ ѹ Ѻ ѻ Ѽ ѽ Ѿ ѿ + #elif ENABLED(MAPPER_C2C3) + #error "Western languages on a CYRILLIC display makes no sense. There are no matching symbols." + #elif ENABLED(MAPPER_E382E383) + #error "Katakana on a CYRILLIC display makes no sense. There are no matching symbols." + #endif + #else + #error "Something went wrong in the setting of DISPLAY_CHARSET_HD44780" + #endif // DISPLAY_CHARSET_HD44780 +#endif // SIMULATE_ROMFONT + +#define PRINTABLE(C) (((C) & 0xC0u) != 0x80u) + +#if ENABLED(MAPPER_C2C3) + + char charset_mapper(const char c) { + static uint8_t utf_hi_char; // UTF-8 high part + static bool seen_c2 = false; + uint8_t d = c; + if (d >= 0x80u) { // UTF-8 handling + if (d >= 0xC0u && !seen_c2) { + utf_hi_char = d - 0xC2u; + seen_c2 = true; + return 0; + } + else if (seen_c2) { + d &= 0x3Fu; + #ifndef MAPPER_ONE_TO_ONE + HARDWARE_CHAR_OUT(pgm_read_byte_near(utf_recode + d + (utf_hi_char << 6) - 0x20)); + #else + HARDWARE_CHAR_OUT(0x80u + (utf_hi_char << 6) + d); + #endif + } + else { + HARDWARE_CHAR_OUT('?'); + } + } + else { + HARDWARE_CHAR_OUT(c); + } + seen_c2 = false; + return 1; + } + +#elif ENABLED(MAPPER_C2C3_TR) + + // the C2C3-mapper extended for the 6 altered symbols from C4 and C5 range. + + char charset_mapper(const char c) { + static uint8_t utf_hi_char; // UTF-8 high part + static bool seen_c2 = false, + seen_c4 = false, + seen_c5 = false; + uint8_t d = c; + if (d >= 0x80u) { // UTF-8 handling + if (d == 0xC4u) { seen_c4 = true; return 0; } + else if (d == 0xC5u) { seen_c5 = true; return 0; } + else if (d >= 0xC0u && !seen_c2) { + utf_hi_char = d - 0xC2u; + seen_c2 = true; + return 0; + } + else if (seen_c4) { + switch(d) { + case 0x9Eu: d = 0xD0u; break; + case 0x9Fu: d = 0xF0u; break; + case 0xB0u: d = 0xDDu; break; + case 0xB1u: d = 0xFDu; break; + default: d = '?'; + } + HARDWARE_CHAR_OUT(d); + } + else if (seen_c5) { + switch(d) { + case 0x9Eu: d = 0xDEu; break; + case 0x9Fu: d = 0xFEu; break; + default: d = '?'; + } + HARDWARE_CHAR_OUT(d); + } + else if (seen_c2) { + d &= 0x3Fu; + #ifndef MAPPER_ONE_TO_ONE + HARDWARE_CHAR_OUT(pgm_read_byte_near(utf_recode + d + (utf_hi_char << 6) - 0x20)); + #else + HARDWARE_CHAR_OUT(0x80u + (utf_hi_char << 6) + d); + #endif + } + else { + HARDWARE_CHAR_OUT('?'); + } + } + else { + HARDWARE_CHAR_OUT(c); + } + seen_c2 = seen_c4 = seen_c5 = false; + return 1; + } + +#elif ENABLED(MAPPER_CECF) + + char charset_mapper(const char c) { + static uint8_t utf_hi_char; // UTF-8 high part + static bool seen_ce = false; + uint8_t d = c; + if (d >= 0x80) { // UTF-8 handling + if (d >= 0xC0 && !seen_ce) { + utf_hi_char = d - 0xCE; + seen_ce = true; + return 0; + } + else if (seen_ce) { + d &= 0x3F; + #ifndef MAPPER_ONE_TO_ONE + HARDWARE_CHAR_OUT(pgm_read_byte_near(utf_recode + d + (utf_hi_char << 6) - 0x20)); + #else + HARDWARE_CHAR_OUT(0x80 + (utf_hi_char << 6) + d); + #endif + } + else { + HARDWARE_CHAR_OUT('?'); + } + } + else { + HARDWARE_CHAR_OUT(c); + } + seen_ce = false; + return 1; + } + +#elif ENABLED(MAPPER_CECF) + + char charset_mapper(const char c) { + static uint8_t utf_hi_char; // UTF-8 high part + static bool seen_ce = false; + uint8_t d = c; + if (d >= 0x80) { // UTF-8 handling + if (d >= 0xC0 && !seen_ce) { + utf_hi_char = d - 0xCE; + seen_ce = true; + return 0; + } + else if (seen_ce) { + d &= 0x3F; + #ifndef MAPPER_ONE_TO_ONE + HARDWARE_CHAR_OUT(pgm_read_byte_near(utf_recode + d + (utf_hi_char << 6) - 0x20)); + #else + HARDWARE_CHAR_OUT(0x80 + (utf_hi_char << 6) + d); + #endif + } + else { + HARDWARE_CHAR_OUT('?'); + } + } + else { + HARDWARE_CHAR_OUT(c); + } + seen_ce = false; + return 1; + } + +#elif ENABLED(MAPPER_D0D1_MOD) + + char charset_mapper(const char c) { + // it is a Russian alphabet translation + // except 0401 --> 0xA2 = Ё, 0451 --> 0xB5 = ё + static uint8_t utf_hi_char; // UTF-8 high part + static bool seen_d5 = false; + uint8_t d = c; + if (d >= 0x80) { // UTF-8 handling + if (d >= 0xD0 && !seen_d5) { + utf_hi_char = d - 0xD0; + seen_d5 = true; + return 0; + } + else if (seen_d5) { + d &= 0x3F; + if (!utf_hi_char && d == 1) { + HARDWARE_CHAR_OUT(0xA2); // Ё + } + else if (utf_hi_char == 1 && d == 0x11) { + HARDWARE_CHAR_OUT(0xB5); // ё + } + else { + HARDWARE_CHAR_OUT(pgm_read_byte_near(utf_recode + d + (utf_hi_char << 6) - 0x10)); + } + } + else { + HARDWARE_CHAR_OUT('?'); + } + } + else { + HARDWARE_CHAR_OUT(c); + } + seen_d5 = false; + return 1; + } + +#elif ENABLED(MAPPER_D0D1) + + char charset_mapper(const char c) { + static uint8_t utf_hi_char; // UTF-8 high part + static bool seen_d5 = false; + uint8_t d = c; + if (d >= 0x80u) { // UTF-8 handling + if (d >= 0xD0u && !seen_d5) { + utf_hi_char = d - 0xD0u; + seen_d5 = true; + return 0; + } + else if (seen_d5) { + d &= 0x3Fu; + #ifndef MAPPER_ONE_TO_ONE + HARDWARE_CHAR_OUT(pgm_read_byte_near(utf_recode + d + (utf_hi_char << 6) - 0x20)); + #else + HARDWARE_CHAR_OUT(0xA0u + (utf_hi_char << 6) + d); + #endif + } + else { + HARDWARE_CHAR_OUT('?'); + } + } + else { + HARDWARE_CHAR_OUT(c); + } + seen_d5 = false; + return 1; + } + +#elif ENABLED(MAPPER_E382E383) + + char charset_mapper(const char c) { + static uint8_t utf_hi_char; // UTF-8 high part + static bool seen_e3 = false, + seen_82_83 = false; + uint8_t d = c; + if (d >= 0x80) { // UTF-8 handling + if (d == 0xE3 && !seen_e3) { + seen_e3 = true; + return 0; // eat 0xE3 + } + else if (d >= 0x82 && seen_e3 && !seen_82_83) { + utf_hi_char = d - 0x82; + seen_82_83 = true; + return 0; + } + else if (seen_e3 && seen_82_83) { + d &= 0x3F; + #ifndef MAPPER_ONE_TO_ONE + HARDWARE_CHAR_OUT(pgm_read_byte_near(utf_recode + d + (utf_hi_char << 6) - 0x20)); + #else + HARDWARE_CHAR_OUT(0x80 + (utf_hi_char << 6) + d); + #endif + } + else + HARDWARE_CHAR_OUT('?'); + } + else + HARDWARE_CHAR_OUT(c); + + seen_e3 = false; + seen_82_83 = false; + return 1; + } + +#elif ENABLED(MAPPER_C3C4C5_PL) + + /** + * Ą C4 84 = 80 + * ą C4 85 = 81 + * Ć C4 86 = 82 + * ć C4 87 = 83 + * Ę C4 98 = 84 + * ę C4 99 = 85 + * Ł C5 81 = 86 + * ł C5 82 = 87 + * Ń C5 83 = 88 + * ń C5 84 = 89 + * Ó C3 93 = 8A + * ó C3 B3 = 8B + * Ś C5 9A = 8C + * ś C5 9B = 8D + * Ź C5 B9 = 8E + * ź C5 BA = 8F + * Ż C5 BB = 90 + * ż C5 BC = 91 + */ + + char charset_mapper(const char c) { + static bool seen_c3 = false, + seen_c4 = false, + seen_c5 = false; + uint8_t d = c; + if (d >= 0x80u) { // UTF-8 handling + if (d == 0xC4u) { seen_c4 = true; return 0; } + else if (d == 0xC5u) { seen_c5 = true; return 0; } + else if (d == 0xC3u) { seen_c3 = true; return 0; } + else if (seen_c4) { + switch(d) { + case 0x84u ... 0x87u: d -= 4; break; //Ą - ć + case 0x98u ... 0x99u: d -= 20; break; //Ę i ę + default: d = '?'; + } + HARDWARE_CHAR_OUT(d); + } + else if (seen_c5) { + switch(d) { + case 0x81u ... 0x84u: d += 5; break; //Ł - ń + case 0x9Au ... 0x9Bu: d -= 0x0Eu; break; //Ś i ś + case 0xB9u ... 0xBCu: d -= 0x2Bu; break; //Ź - ż + default: d = '?'; + } + HARDWARE_CHAR_OUT(d); + } + else if (seen_c3) { + switch(d) { + case 0x93u: d = 0x8Au; break; //Ó + case 0xB3u: d = 0x8Bu; break; //ó + d = '?'; + } + HARDWARE_CHAR_OUT(d); + } + + } + else + HARDWARE_CHAR_OUT(c); + + seen_c3 = seen_c4 = seen_c5 = false; + return 1; + } + +#elif ENABLED(MAPPER_C3C4C5_CZ) + + /** + * Á C3 81 = 80 + * É C3 89 = 81 + * Í C3 8D = 82 + * Ó C3 93 = 83 + * Ú C3 9A = 84 + * Ý C3 9D = 85 + * á C3 A1 = 86 + * é C3 A9 = 87 + * í C3 AD = 88 + * ó C3 B3 = 89 + * ú C3 BA = 8A + * ý C3 BD = 8B + * Č C4 8C = 8C + * č C4 8D = 8D + * Ď C4 8E = 8E + * ď C4 8F = 8F + * Ě C4 9A = 90 + * ě C4 9B = 91 + * Ň C5 87 = 92 + * ň C5 88 = 93 + * Ř C5 98 = 94 + * ř C5 99 = 95 + * Š C5 A0 = 96 + * š C5 A1 = 97 + * Ť C5 A4 = 98 + * ť C5 A5 = 99 + * Ů C5 AE = 9A + * ů C5 AF = 9B + * Ž C5 BD = 9C + * ž C5 BE = 9D + */ + + char charset_mapper(const char c) { + static bool seen_c3 = false, + seen_c4 = false, + seen_c5 = false; + uint8_t d = c; + if (d >= 0x80u) { // UTF-8 handling + if (d == 0xC4u) { seen_c4 = true; return 0; } + else if (d == 0xC5u) { seen_c5 = true; return 0; } + else if (d == 0xC3u) { seen_c3 = true; return 0; } + else if (seen_c4) { + switch(d) { + case 0x8Cu ... 0x8Fu: break; // ČčĎď Mapping 1:1 + case 0x9Au ... 0x9Bu: d -= 10; break; // Ěě + default: d = '?'; + } + HARDWARE_CHAR_OUT(d); + } + else if (seen_c5) { + switch(d) { + case 0x87u ... 0x88u: d += 0x0Bu; break; // Ňň + case 0x98u ... 0x99u: d -= 0x04u; break; // Řř + case 0xA0u ... 0xA1u: d -= 0x0Au; break; // Šš + case 0xA4u ... 0xA5u: d -= 0x0Cu; break; // Ťť + case 0xAEu ... 0xAFu: d -= 0x14u; break; // Ůů + case 0xBDu ... 0xBEu: d -= 0x21u; break; // Žž + default: d = '?'; + } + HARDWARE_CHAR_OUT(d); + } + else if (seen_c3) { + switch(d) { + case 0x81u: d = 0x80u; break; // Á + case 0x89u: d = 0x81u; break; // É + case 0x8Du: d = 0x82u; break; // Í + case 0x93u: d = 0x83u; break; // Ó + case 0x9Au: d = 0x84u; break; // Ú + case 0x9Du: d = 0x85u; break; // Ý + case 0xA1u: d = 0x86u; break; // á + case 0xA9u: d = 0x87u; break; // é + case 0xADu: d = 0x88u; break; // í + case 0xB3u: d = 0x89u; break; // ó + case 0xBAu: d = 0x8Au; break; // ú + case 0xBDu: d = 0x8Bu; break; // ý + default: d = '?'; + } + HARDWARE_CHAR_OUT(d); + } + + } + else + HARDWARE_CHAR_OUT(c); + + seen_c3 = seen_c4 = seen_c5 = false; + return 1; + } + +#elif ENABLED(MAPPER_C3C4C5_SK) + + /** + * Á C3 81 = 80 + * Ä C3 84 = 81 + * É C3 89 = 82 + * Í C3 8D = 83 + * Ó C3 93 = 84 + * Ô C3 94 = 85 + * Ú C3 9A = 86 + * Ý C3 9D = 87 + * á C3 A1 = 88 + * ä C3 A4 = 89 + * é C3 A9 = 8A + * í C3 AD = 8B + * ó C3 B3 = 8C + * ô C3 B4 = 8D + * ú C3 BA = 8E + * ý C3 BD = 8F + * Č C4 8C = 90 + * č C4 8D = 91 + * Ď C4 8E = 92 + * ď C4 8F = 93 + * Ĺ C4 B9 = 94 + * ĺ C4 BA = 95 + * Ľ C4 BD = 96 + * ľ C4 BE = 97 + * Ň C5 87 = 98 + * ň C5 88 = 99 + * Ŕ C5 94 = 9A + * ŕ C5 95 = 9B + * Š C5 A0 = 9C + * š C5 A1 = 9D + * Ť C5 A4 = 9E + * ť C5 A5 = 9F + * Ž C5 BD = A0 + * ž C5 BE = A1 + */ + + char charset_mapper(const char c) { + static bool seen_c3 = false, + seen_c4 = false, + seen_c5 = false; + uint8_t d = c; + if (d >= 0x80u) { // UTF-8 handling + if (d == 0xC4u) { seen_c4 = true; return 0; } + else if (d == 0xC5u) { seen_c5 = true; return 0; } + else if (d == 0xC3u) { seen_c3 = true; return 0; } + else if (seen_c4) { + switch(d) { + case 0x8Cu ... 0x8Fu: d += 0x04u; break; // ČčĎď + case 0xB9u ... 0xBAu: d -= 0x25u; break; // Ĺĺ + case 0xBDu ... 0xBEu: d -= 0x27u; break; // Ľľ + default: d = '?'; + } + HARDWARE_CHAR_OUT(d); + } + else if (seen_c5) { + switch(d) { + case 0x87u ... 0x88u: d += 0x11u; break; // Ňň + case 0x94u ... 0x95u: d += 0x06u; break; // Ŕŕ + case 0xA0u ... 0xA1u: d -= 0x04u; break; // Šš + case 0xA4u ... 0xA5u: d -= 0x06u; break; // Ťť + case 0xBDu ... 0xBEu: d -= 0x1Du; break; // Žž + default: d = '?'; + } + HARDWARE_CHAR_OUT(d); + } + else if (seen_c3) { + switch(d) { + case 0x81u: d = 0x80u; break; // Á + case 0x84u: d = 0x81u; break; // Ä + case 0x89u: d = 0x82u; break; // É + case 0x8Du: d = 0x83u; break; // Í + case 0x93u: d = 0x84u; break; // Ó + case 0x94u: d = 0x85u; break; // Ô + case 0x9Au: d = 0x86u; break; // Ú + case 0x9Du: d = 0x87u; break; // Ý + case 0xA1u: d = 0x88u; break; // á + case 0xA4u: d = 0x89u; break; // ä + case 0xA9u: d = 0x8Au; break; // é + case 0xADu: d = 0x8Bu; break; // í + case 0xB3u: d = 0x8Cu; break; // ó + case 0xB4u: d = 0x8Du; break; // ô + case 0xBAu: d = 0x8Eu; break; // ú + case 0xBDu: d = 0x8Fu; break; // ý + default: d = '?'; + } + HARDWARE_CHAR_OUT(d); + } + + } + else + HARDWARE_CHAR_OUT(c); + + seen_c3 = seen_c4 = seen_c5 = false; + return 1; + } + +#else + + #define MAPPER_NON + + #undef PRINTABLE + #define PRINTABLE(C) true + + char charset_mapper(const char c) { + HARDWARE_CHAR_OUT(c); + return 1; + } + +#endif // code mappers + +#endif // UTF_MAPPER_H diff --git a/trunk/Arduino/Marlin_1.1.6/utility.cpp b/trunk/Arduino/Marlin_1.1.6/utility.cpp new file mode 100644 index 00000000..0f591935 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/utility.cpp @@ -0,0 +1,257 @@ +/** + * 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 . + * + */ + +#include "Marlin.h" +#include "utility.h" +#include "temperature.h" + +void safe_delay(millis_t ms) { + while (ms > 50) { + ms -= 50; + delay(50); + thermalManager.manage_heater(); + } + delay(ms); + thermalManager.manage_heater(); // This keeps us safe if too many small safe_delay() calls are made +} + +#if ENABLED(EEPROM_SETTINGS) + + void crc16(uint16_t *crc, const void * const data, uint16_t cnt) { + uint8_t *ptr = (uint8_t *)data; + while (cnt--) { + *crc = (uint16_t)(*crc ^ (uint16_t)(((uint16_t)*ptr++) << 8)); + for (uint8_t x = 0; x < 8; x++) + *crc = (uint16_t)((*crc & 0x8000) ? ((uint16_t)(*crc << 1) ^ 0x1021) : (*crc << 1)); + } + } + +#endif // EEPROM_SETTINGS + +#if ENABLED(ULTRA_LCD) + + char conv[8] = { 0 }; + + #define DIGIT(n) ('0' + (n)) + #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, '-')) + + // Convert unsigned int to string 123 format + char* i8tostr3(const uint8_t xx) { + conv[4] = RJDIGIT(xx, 100); + conv[5] = RJDIGIT(xx, 10); + conv[6] = DIGIMOD(xx, 1); + return &conv[4]; + } + + // Convert signed int to rj string with 123 or -12 format + char* itostr3(const int x) { + int xx = x; + conv[4] = MINUSOR(xx, RJDIGIT(xx, 100)); + conv[5] = RJDIGIT(xx, 10); + conv[6] = DIGIMOD(xx, 1); + return &conv[4]; + } + + // Convert unsigned int to lj string with 123 format + char* itostr3left(const int xx) { + char *str = &conv[6]; + *str = DIGIMOD(xx, 1); + if (xx >= 10) { + *(--str) = DIGIMOD(xx, 10); + if (xx >= 100) + *(--str) = DIGIMOD(xx, 100); + } + return str; + } + + // Convert signed int to rj string with 1234, _123, -123, _-12, or __-1 format + char *itostr4sign(const int x) { + const bool neg = x < 0; + const int xx = neg ? -x : x; + if (x >= 1000) { + conv[3] = DIGIMOD(xx, 1000); + conv[4] = DIGIMOD(xx, 100); + conv[5] = DIGIMOD(xx, 10); + } + else { + if (xx >= 100) { + conv[3] = neg ? '-' : ' '; + conv[4] = DIGIMOD(xx, 100); + conv[5] = DIGIMOD(xx, 10); + } + else { + conv[3] = ' '; + conv[4] = ' '; + if (xx >= 10) { + conv[4] = neg ? '-' : ' '; + conv[5] = DIGIMOD(xx, 10); + } + else { + conv[5] = neg ? '-' : ' '; + } + } + } + conv[6] = DIGIMOD(xx, 1); + return &conv[3]; + } + + // Convert unsigned float to string with 1.23 format + char* ftostr12ns(const float &x) { + const long xx = (x < 0 ? -x : x) * 100; + conv[3] = DIGIMOD(xx, 100); + conv[4] = '.'; + conv[5] = DIGIMOD(xx, 10); + conv[6] = DIGIMOD(xx, 1); + return &conv[3]; + } + + // Convert signed float to fixed-length string with 023.45 / -23.45 format + char *ftostr32(const float &x) { + long xx = x * 100; + conv[1] = MINUSOR(xx, DIGIMOD(xx, 10000)); + conv[2] = DIGIMOD(xx, 1000); + conv[3] = DIGIMOD(xx, 100); + conv[4] = '.'; + conv[5] = DIGIMOD(xx, 10); + conv[6] = DIGIMOD(xx, 1); + return &conv[1]; + } + + #if ENABLED(LCD_DECIMAL_SMALL_XY) + + // Convert float to rj string with 1234, _123, -123, _-12, 12.3, _1.2, or -1.2 format + char *ftostr4sign(const float &fx) { + const int x = fx * 10; + if (!WITHIN(x, -99, 999)) return itostr4sign((int)fx); + const bool neg = x < 0; + const int xx = neg ? -x : x; + conv[3] = neg ? '-' : (xx >= 100 ? DIGIMOD(xx, 100) : ' '); + conv[4] = DIGIMOD(xx, 10); + conv[5] = '.'; + conv[6] = DIGIMOD(xx, 1); + return &conv[3]; + } + + #endif // LCD_DECIMAL_SMALL_XY + + // Convert float to fixed-length string with +123.4 / -123.4 format + char* ftostr41sign(const float &x) { + int xx = x * 10; + conv[1] = MINUSOR(xx, '+'); + conv[2] = DIGIMOD(xx, 1000); + conv[3] = DIGIMOD(xx, 100); + conv[4] = DIGIMOD(xx, 10); + conv[5] = '.'; + conv[6] = DIGIMOD(xx, 1); + return &conv[1]; + } + + // Convert signed float to string (6 digit) with -1.234 / _0.000 / +1.234 format + char* ftostr43sign(const float &x, char plus/*=' '*/) { + long xx = x * 1000; + conv[1] = xx ? MINUSOR(xx, plus) : ' '; + conv[2] = DIGIMOD(xx, 1000); + conv[3] = '.'; + conv[4] = DIGIMOD(xx, 100); + conv[5] = DIGIMOD(xx, 10); + conv[6] = DIGIMOD(xx, 1); + return &conv[1]; + } + + // Convert unsigned float to rj string with 12345 format + char* ftostr5rj(const float &x) { + const long xx = x < 0 ? -x : x; + conv[2] = RJDIGIT(xx, 10000); + conv[3] = RJDIGIT(xx, 1000); + conv[4] = RJDIGIT(xx, 100); + conv[5] = RJDIGIT(xx, 10); + conv[6] = DIGIMOD(xx, 1); + return &conv[2]; + } + + // Convert signed float to string with +1234.5 format + char* ftostr51sign(const float &x) { + long xx = x * 10; + conv[0] = MINUSOR(xx, '+'); + conv[1] = DIGIMOD(xx, 10000); + conv[2] = DIGIMOD(xx, 1000); + conv[3] = DIGIMOD(xx, 100); + conv[4] = DIGIMOD(xx, 10); + conv[5] = '.'; + conv[6] = DIGIMOD(xx, 1); + return conv; + } + + // Convert signed float to string with +123.45 format + char* ftostr52sign(const float &x) { + long xx = x * 100; + conv[0] = MINUSOR(xx, '+'); + conv[1] = DIGIMOD(xx, 10000); + conv[2] = DIGIMOD(xx, 1000); + conv[3] = DIGIMOD(xx, 100); + conv[4] = '.'; + conv[5] = DIGIMOD(xx, 10); + conv[6] = DIGIMOD(xx, 1); + return conv; + } + + // Convert unsigned float to string with 1234.56 format omitting trailing zeros + char* ftostr62rj(const float &x) { + const long xx = (x < 0 ? -x : x) * 100; + conv[0] = RJDIGIT(xx, 100000); + conv[1] = RJDIGIT(xx, 10000); + conv[2] = RJDIGIT(xx, 1000); + conv[3] = DIGIMOD(xx, 100); + conv[4] = '.'; + conv[5] = DIGIMOD(xx, 10); + conv[6] = DIGIMOD(xx, 1); + return conv; + } + + // Convert signed float to space-padded string with -_23.4_ format + char* ftostr52sp(const float &x) { + long xx = x * 100; + uint8_t dig; + conv[1] = MINUSOR(xx, RJDIGIT(xx, 10000)); + conv[2] = RJDIGIT(xx, 1000); + conv[3] = DIGIMOD(xx, 100); + + if ((dig = xx % 10)) { // second digit after decimal point? + conv[4] = '.'; + conv[5] = DIGIMOD(xx, 10); + conv[6] = DIGIT(dig); + } + else { + if ((dig = (xx / 10) % 10)) { // first digit after decimal point? + conv[4] = '.'; + conv[5] = DIGIT(dig); + } + else // nothing after decimal point + conv[4] = conv[5] = ' '; + conv[6] = ' '; + } + return &conv[1]; + } + +#endif // ULTRA_LCD diff --git a/trunk/Arduino/Marlin_1.1.6/utility.h b/trunk/Arduino/Marlin_1.1.6/utility.h new file mode 100644 index 00000000..426c5837 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/utility.h @@ -0,0 +1,86 @@ +/** + * 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 . + * + */ + +#ifndef __UTILITY_H__ +#define __UTILITY_H__ + +void safe_delay(millis_t ms); + +#if ENABLED(EEPROM_SETTINGS) + void crc16(uint16_t *crc, const void * const data, uint16_t cnt); +#endif + +#if ENABLED(ULTRA_LCD) + + // Convert uint8_t to string with 123 format + char* i8tostr3(const uint8_t x); + + // Convert signed int to rj string with 123 or -12 format + char* itostr3(const int x); + + // Convert unsigned int to lj string with 123 format + char* itostr3left(const int xx); + + // Convert signed int to rj string with _123, -123, _-12, or __-1 format + char *itostr4sign(const int x); + + // Convert unsigned float to string with 1.23 format + char* ftostr12ns(const float &x); + + // Convert signed float to fixed-length string with 023.45 / -23.45 format + char* ftostr32(const float &x); + + // Convert float to fixed-length string with +123.4 / -123.4 format + char* ftostr41sign(const float &x); + + // Convert signed float to string (6 digit) with -1.234 / _0.000 / +1.234 format + char* ftostr43sign(const float &x, char plus=' '); + + // Convert unsigned float to rj string with 12345 format + char* ftostr5rj(const float &x); + + // Convert signed float to string with +1234.5 format + char* ftostr51sign(const float &x); + + // Convert signed float to space-padded string with -_23.4_ format + char* ftostr52sp(const float &x); + + // Convert signed float to string with +123.45 format + char* ftostr52sign(const float &x); + + // Convert unsigned float to string with 1234.56 format omitting trailing zeros + char* ftostr62rj(const float &x); + + // Convert float to rj string with 123 or -12 format + FORCE_INLINE char *ftostr3(const float &x) { return itostr3((int)x); } + + #if ENABLED(LCD_DECIMAL_SMALL_XY) + // Convert float to rj string with 1234, _123, 12.3, _1.2, -123, _-12, or -1.2 format + char *ftostr4sign(const float &fx); + #else + // Convert float to rj string with 1234, _123, -123, __12, _-12, ___1, or __-1 format + FORCE_INLINE char *ftostr4sign(const float &x) { return itostr4sign((int)x); } + #endif + +#endif // ULTRA_LCD + +#endif // __UTILITY_H__ diff --git a/trunk/Arduino/Marlin_1.1.6/vector_3.cpp b/trunk/Arduino/Marlin_1.1.6/vector_3.cpp new file mode 100644 index 00000000..f9615bcf --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/vector_3.cpp @@ -0,0 +1,160 @@ +/** + * 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 . + * + */ + +/** + vector_3.cpp - Vector library for bed leveling + Copyright (c) 2012 Lars Brubaker. 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 +#include "Marlin.h" + +#if HAS_ABL +#include "vector_3.h" + +vector_3::vector_3() : x(0), y(0), z(0) { } + +vector_3::vector_3(float x_, float y_, float z_) : x(x_), y(y_), z(z_) { } + +vector_3 vector_3::cross(vector_3 left, vector_3 right) { + return vector_3(left.y * right.z - left.z * right.y, + left.z * right.x - left.x * right.z, + left.x * right.y - left.y * right.x); +} + +vector_3 vector_3::operator+(vector_3 v) { return vector_3((x + v.x), (y + v.y), (z + v.z)); } +vector_3 vector_3::operator-(vector_3 v) { return vector_3((x - v.x), (y - v.y), (z - v.z)); } + +vector_3 vector_3::get_normal() { + vector_3 normalized = vector_3(x, y, z); + normalized.normalize(); + return normalized; +} + +float vector_3::get_length() { return SQRT(sq(x) + sq(y) + sq(z)); } + +void vector_3::normalize() { + const float inv_length = 1.0 / get_length(); + x *= inv_length; + y *= inv_length; + z *= inv_length; +} + +void vector_3::apply_rotation(matrix_3x3 matrix) { + const float resultX = x * matrix.matrix[3 * 0 + 0] + y * matrix.matrix[3 * 1 + 0] + z * matrix.matrix[3 * 2 + 0], + resultY = x * matrix.matrix[3 * 0 + 1] + y * matrix.matrix[3 * 1 + 1] + z * matrix.matrix[3 * 2 + 1], + resultZ = x * matrix.matrix[3 * 0 + 2] + y * matrix.matrix[3 * 1 + 2] + z * matrix.matrix[3 * 2 + 2]; + x = resultX; + y = resultY; + z = resultZ; +} + +void vector_3::debug(const char * const title) { + serialprintPGM(title); + SERIAL_PROTOCOLPGM(" x: "); + SERIAL_PROTOCOL_F(x, 6); + SERIAL_PROTOCOLPGM(" y: "); + SERIAL_PROTOCOL_F(y, 6); + SERIAL_PROTOCOLPGM(" z: "); + SERIAL_PROTOCOL_F(z, 6); + SERIAL_EOL(); +} + +void apply_rotation_xyz(matrix_3x3 matrix, float &x, float &y, float &z) { + vector_3 vector = vector_3(x, y, z); + vector.apply_rotation(matrix); + x = vector.x; + y = vector.y; + z = vector.z; +} + +matrix_3x3 matrix_3x3::create_from_rows(vector_3 row_0, vector_3 row_1, vector_3 row_2) { + //row_0.debug(PSTR("row_0")); + //row_1.debug(PSTR("row_1")); + //row_2.debug(PSTR("row_2")); + matrix_3x3 new_matrix; + new_matrix.matrix[0] = row_0.x; new_matrix.matrix[1] = row_0.y; new_matrix.matrix[2] = row_0.z; + new_matrix.matrix[3] = row_1.x; new_matrix.matrix[4] = row_1.y; new_matrix.matrix[5] = row_1.z; + new_matrix.matrix[6] = row_2.x; new_matrix.matrix[7] = row_2.y; new_matrix.matrix[8] = row_2.z; + //new_matrix.debug(PSTR("new_matrix")); + return new_matrix; +} + +void matrix_3x3::set_to_identity() { + matrix[0] = 1; matrix[1] = 0; matrix[2] = 0; + matrix[3] = 0; matrix[4] = 1; matrix[5] = 0; + matrix[6] = 0; matrix[7] = 0; matrix[8] = 1; +} + +matrix_3x3 matrix_3x3::create_look_at(vector_3 target) { + vector_3 z_row = target.get_normal(); + vector_3 x_row = vector_3(1, 0, -target.x / target.z).get_normal(); + vector_3 y_row = vector_3::cross(z_row, x_row).get_normal(); + + // x_row.debug(PSTR("x_row")); + // y_row.debug(PSTR("y_row")); + // z_row.debug(PSTR("z_row")); + + // create the matrix already correctly transposed + matrix_3x3 rot = matrix_3x3::create_from_rows(x_row, y_row, z_row); + + // rot.debug(PSTR("rot")); + return rot; +} + +matrix_3x3 matrix_3x3::transpose(matrix_3x3 original) { + matrix_3x3 new_matrix; + new_matrix.matrix[0] = original.matrix[0]; new_matrix.matrix[1] = original.matrix[3]; new_matrix.matrix[2] = original.matrix[6]; + new_matrix.matrix[3] = original.matrix[1]; new_matrix.matrix[4] = original.matrix[4]; new_matrix.matrix[5] = original.matrix[7]; + new_matrix.matrix[6] = original.matrix[2]; new_matrix.matrix[7] = original.matrix[5]; new_matrix.matrix[8] = original.matrix[8]; + return new_matrix; +} + +void matrix_3x3::debug(const char * const title) { + serialprintPGM(title); + uint8_t count = 0; + for (uint8_t i = 0; i < 3; i++) { + for (uint8_t j = 0; j < 3; j++) { + if (matrix[count] >= 0.0) SERIAL_PROTOCOLCHAR('+'); + SERIAL_PROTOCOL_F(matrix[count], 6); + SERIAL_PROTOCOLCHAR(' '); + count++; + } + SERIAL_EOL(); + } +} + +#endif // HAS_ABL + diff --git a/trunk/Arduino/Marlin_1.1.6/vector_3.h b/trunk/Arduino/Marlin_1.1.6/vector_3.h new file mode 100644 index 00000000..19f6e3a3 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/vector_3.h @@ -0,0 +1,83 @@ +/** + * 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 . + * + */ + +/** + vector_3.cpp - Vector library for bed leveling + Copyright (c) 2012 Lars Brubaker. 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 VECTOR_3_H +#define VECTOR_3_H + +#if HAS_ABL + +class matrix_3x3; + +struct vector_3 { + float x, y, z; + + vector_3(); + vector_3(float x, float y, float z); + + static vector_3 cross(vector_3 a, vector_3 b); + + vector_3 operator+(vector_3 v); + vector_3 operator-(vector_3 v); + void normalize(); + float get_length(); + vector_3 get_normal(); + + void debug(const char * const title); + + void apply_rotation(matrix_3x3 matrix); +}; + +struct matrix_3x3 { + float matrix[9]; + + static matrix_3x3 create_from_rows(vector_3 row_0, vector_3 row_1, vector_3 row_2); + static matrix_3x3 create_look_at(vector_3 target); + static matrix_3x3 transpose(matrix_3x3 original); + + void set_to_identity(); + + void debug(const char * const title); +}; + + +void apply_rotation_xyz(matrix_3x3 rotationMatrix, float &x, float &y, float &z); + +#endif // HAS_ABL +#endif // VECTOR_3_H diff --git a/trunk/Arduino/Marlin_1.1.6/watchdog.cpp b/trunk/Arduino/Marlin_1.1.6/watchdog.cpp new file mode 100644 index 00000000..5e42b5fa --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/watchdog.cpp @@ -0,0 +1,56 @@ +/** + * 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 . + * + */ + +#include "Marlin.h" + +#if ENABLED(USE_WATCHDOG) + +#include "watchdog.h" + +// Initialize watchdog with a 4 sec interrupt time +void watchdog_init() { + #if ENABLED(WATCHDOG_RESET_MANUAL) + // We enable the watchdog timer, but only for the interrupt. + // Take care, as this requires the correct order of operation, with interrupts disabled. See the datasheet of any AVR chip for details. + wdt_reset(); + _WD_CONTROL_REG = _BV(_WD_CHANGE_BIT) | _BV(WDE); + _WD_CONTROL_REG = _BV(WDIE) | WDTO_4S; + #else + wdt_enable(WDTO_4S); + #endif +} + +//=========================================================================== +//=================================== ISR =================================== +//=========================================================================== + +// Watchdog timer interrupt, called if main program blocks >4sec and manual reset is enabled. +#if ENABLED(WATCHDOG_RESET_MANUAL) + ISR(WDT_vect) { + SERIAL_ERROR_START(); + SERIAL_ERRORLNPGM("Something is wrong, please turn off the printer."); + kill(PSTR("ERR:Please Reset")); //kill blocks //16 characters so it fits on a 16x2 display + while (1); //wait for user or serial reset + } +#endif // WATCHDOG_RESET_MANUAL + +#endif // USE_WATCHDOG diff --git a/trunk/Arduino/Marlin_1.1.6/watchdog.h b/trunk/Arduino/Marlin_1.1.6/watchdog.h new file mode 100644 index 00000000..2c04b589 --- /dev/null +++ b/trunk/Arduino/Marlin_1.1.6/watchdog.h @@ -0,0 +1,36 @@ +/** + * 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 . + * + */ + +#ifndef WATCHDOG_H +#define WATCHDOG_H + +#include "Marlin.h" +#include + +// Initialize watchdog with a 4 second interrupt time +void watchdog_init(); + +// Reset watchdog. MUST be called at least every 4 seconds after the +// first watchdog_init or AVR will go into emergency procedures. +inline void watchdog_reset() { wdt_reset(); } + +#endif diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/Conditionals.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/Conditionals.h new file mode 100644 index 00000000..ff6c6b18 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/Conditionals.h @@ -0,0 +1,27 @@ +/** + * 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 . + * + */ + +/** + * Conditionals.h + * OBSOLETE: Replaced by Conditionals_LCD.h and Conditionals_post.h + */ +#error "Old configurations? Please delete all #include lines from Configuration.h and Configuration_adv.h." diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/Conditionals_LCD.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/Conditionals_LCD.h new file mode 100644 index 00000000..29c67bf7 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/Conditionals_LCD.h @@ -0,0 +1,319 @@ +/** + * 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 . + * + */ + +/** + * Conditionals_LCD.h + * LCD Defines that depend on configuration but are not editable. + */ + +#ifndef CONDITIONALS_LCD_H // Get the LCD defines which are needed first +#define CONDITIONALS_LCD_H + + #define LCD_HAS_DIRECTIONAL_BUTTONS (BUTTON_EXISTS(UP) || BUTTON_EXISTS(DWN) || BUTTON_EXISTS(LFT) || BUTTON_EXISTS(RT)) + + #if ENABLED(CARTESIO_UI) + #define DOGLCD + #define ULTIPANEL + #define NEWPANEL + #define DEFAULT_LCD_CONTRAST 90 + #define LCD_CONTRAST_MIN 60 + #define LCD_CONTRAST_MAX 140 + #endif + + #if ENABLED(MAKRPANEL) || ENABLED(MINIPANEL) + #define DOGLCD + #define ULTIPANEL + #define NEWPANEL + #define DEFAULT_LCD_CONTRAST 17 + #endif + + #if ENABLED(miniVIKI) || ENABLED(VIKI2) || ENABLED(ELB_FULL_GRAPHIC_CONTROLLER) + #define ULTRA_LCD //general LCD support, also 16x2 + #define DOGLCD // Support for SPI LCD 128x64 (Controller ST7565R graphic Display Family) + #define ULTIMAKERCONTROLLER //as available from the Ultimaker online store. + + #if ENABLED(miniVIKI) + #define LCD_CONTRAST_MIN 75 + #define LCD_CONTRAST_MAX 115 + #define DEFAULT_LCD_CONTRAST 95 + #elif ENABLED(VIKI2) + #define DEFAULT_LCD_CONTRAST 40 + #elif ENABLED(ELB_FULL_GRAPHIC_CONTROLLER) + #define LCD_CONTRAST_MIN 90 + #define LCD_CONTRAST_MAX 130 + #define DEFAULT_LCD_CONTRAST 110 + #define U8GLIB_LM6059_AF + #define SD_DETECT_INVERTED + #endif + + #ifndef ENCODER_PULSES_PER_STEP + #define ENCODER_PULSES_PER_STEP 4 + #endif + #ifndef ENCODER_STEPS_PER_MENU_ITEM + #define ENCODER_STEPS_PER_MENU_ITEM 1 + #endif + #endif + + // Generic support for SSD1306 / SH1106 OLED based LCDs. + #if ENABLED(U8GLIB_SSD1306) || ENABLED(U8GLIB_SH1106) + #define ULTRA_LCD //general LCD support, also 16x2 + #define DOGLCD // Support for I2C LCD 128x64 (Controller SSD1306 / SH1106 graphic Display Family) + #endif + + #if ENABLED(PANEL_ONE) || ENABLED(U8GLIB_SH1106) + #define ULTIMAKERCONTROLLER + #endif + + #if ENABLED(BQ_LCD_SMART_CONTROLLER) + #define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER + + #ifndef ENCODER_PULSES_PER_STEP + #define ENCODER_PULSES_PER_STEP 4 + #endif + #ifndef ENCODER_STEPS_PER_MENU_ITEM + #define ENCODER_STEPS_PER_MENU_ITEM 1 + #endif + + #ifndef LONG_FILENAME_HOST_SUPPORT + #define LONG_FILENAME_HOST_SUPPORT + #endif + #endif + + #if ENABLED(REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER) + #define DOGLCD + #define U8GLIB_ST7920 + #define REPRAP_DISCOUNT_SMART_CONTROLLER + #endif + + #if ENABLED(ULTIMAKERCONTROLLER) \ + || ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER) \ + || ENABLED(G3D_PANEL) \ + || ENABLED(RIGIDBOT_PANEL) \ + || ENABLED(REPRAPWORLD_KEYPAD) + #define ULTIPANEL + #define NEWPANEL + #endif + + #if ENABLED(RA_CONTROL_PANEL) + #define LCD_I2C_TYPE_PCA8574 + #define LCD_I2C_ADDRESS 0x27 // I2C Address of the port expander + #define ULTIPANEL + #define NEWPANEL + #endif + + #if ENABLED(REPRAPWORLD_GRAPHICAL_LCD) + #define DOGLCD + #define U8GLIB_ST7920 + #define ULTIPANEL + #define NEWPANEL + #endif + + /** + * I2C PANELS + */ + + #if ENABLED(LCD_I2C_SAINSMART_YWROBOT) + // This uses the LiquidCrystal_I2C library ( https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home ) + // Make sure it is placed in the Arduino libraries directory. + #define LCD_I2C_TYPE_PCF8575 + #define LCD_I2C_ADDRESS 0x27 // I2C Address of the port expander + #define ULTIPANEL + #define NEWPANEL + #endif + + // PANELOLU2 LCD with status LEDs, separate encoder and click inputs + #if ENABLED(LCD_I2C_PANELOLU2) + #define LCD_I2C_TYPE_MCP23017 + #define LCD_I2C_ADDRESS 0x20 // I2C Address of the port expander + #define LCD_USE_I2C_BUZZER //comment out to disable buzzer on LCD + + #ifndef ENCODER_PULSES_PER_STEP + #define ENCODER_PULSES_PER_STEP 4 + #endif + #ifndef ENCODER_STEPS_PER_MENU_ITEM + #define ENCODER_STEPS_PER_MENU_ITEM 1 + #endif + + #define ULTIPANEL + #define NEWPANEL + #endif + + // Panucatt VIKI LCD with status LEDs, integrated click & L/R/U/P buttons, separate encoder inputs + #if ENABLED(LCD_I2C_VIKI) + // This uses the LiquidTWI2 library v1.2.3 or later ( https://github.com/lincomatic/LiquidTWI2 ) + // Make sure the LiquidTWI2 directory is placed in the Arduino or Sketchbook libraries subdirectory. + // Note: The pause/stop/resume LCD button pin should be connected to the Arduino + // BTN_ENC pin (or set BTN_ENC to -1 if not used) + #define LCD_I2C_TYPE_MCP23017 + #define LCD_I2C_ADDRESS 0x20 // I2C Address of the port expander + #define LCD_USE_I2C_BUZZER //comment out to disable buzzer on LCD (requires LiquidTWI2 v1.2.3 or later) + #define ULTIPANEL + #define NEWPANEL + + #define ENCODER_FEEDRATE_DEADZONE 4 + + #ifndef ENCODER_PULSES_PER_STEP + #define ENCODER_PULSES_PER_STEP 1 + #endif + #ifndef ENCODER_STEPS_PER_MENU_ITEM + #define ENCODER_STEPS_PER_MENU_ITEM 2 + #endif + #endif + + // Shift register panels + // --------------------- + // 2 wire Non-latching LCD SR from: + // https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/schematics#!shiftregister-connection + + #if ENABLED(SAV_3DLCD) + #define SR_LCD_2W_NL // Non latching 2 wire shift register + #define ULTIPANEL + #define NEWPANEL + #endif + + #if ENABLED(DOGLCD) // Change number of lines to match the DOG graphic display + #ifndef LCD_WIDTH + #define LCD_WIDTH 22 + #endif + #ifndef LCD_HEIGHT + #define LCD_HEIGHT 5 + #endif + #endif + + #if ENABLED(ULTIPANEL) + #define NEWPANEL //enable this if you have a click-encoder panel + #define ULTRA_LCD + #ifndef LCD_WIDTH + #define LCD_WIDTH 20 + #endif + #ifndef LCD_HEIGHT + #define LCD_HEIGHT 4 + #endif + #else //no panel but just LCD + #if ENABLED(ULTRA_LCD) + #ifndef LCD_WIDTH + #define LCD_WIDTH 16 + #endif + #ifndef LCD_HEIGHT + #define LCD_HEIGHT 2 + #endif + #endif + #endif + + #if ENABLED(DOGLCD) + /* Custom characters defined in font dogm_font_data_Marlin_symbols.h / Marlin_symbols.fon */ + // \x00 intentionally skipped to avoid problems in strings + #define LCD_STR_REFRESH "\x01" + #define LCD_STR_FOLDER "\x02" + #define LCD_STR_ARROW_RIGHT "\x03" + #define LCD_STR_UPLEVEL "\x04" + #define LCD_STR_CLOCK "\x05" + #define LCD_STR_FEEDRATE "\x06" + #define LCD_STR_BEDTEMP "\x07" + #define LCD_STR_THERMOMETER "\x08" + #define LCD_STR_DEGREE "\x09" + + #define LCD_STR_SPECIAL_MAX '\x09' + // Maximum here is 0x1f because 0x20 is ' ' (space) and the normal charsets begin. + // Better stay below 0x10 because DISPLAY_CHARSET_HD44780_WESTERN begins here. + #else + /* 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! + #define LCD_STR_DEGREE "\x01" + #define LCD_STR_THERMOMETER "\x02" + #define LCD_STR_UPLEVEL "\x03" + #define LCD_STR_REFRESH "\x04" + #define LCD_STR_FOLDER "\x05" + #define LCD_STR_FEEDRATE "\x06" + #define LCD_STR_CLOCK "\x07" + #define LCD_STR_ARROW_RIGHT ">" /* from the default character set */ + #endif + + /** + * Default LCD contrast for dogm-like LCD displays + */ + #if ENABLED(DOGLCD) + + #define HAS_LCD_CONTRAST ( \ + ENABLED(MAKRPANEL) \ + || ENABLED(CARTESIO_UI) \ + || ENABLED(VIKI2) \ + || ENABLED(miniVIKI) \ + || ENABLED(ELB_FULL_GRAPHIC_CONTROLLER) \ + ) + + #if HAS_LCD_CONTRAST + #ifndef LCD_CONTRAST_MIN + #define LCD_CONTRAST_MIN 0 + #endif + #ifndef LCD_CONTRAST_MAX + #define LCD_CONTRAST_MAX 63 + #endif + #ifndef DEFAULT_LCD_CONTRAST + #define DEFAULT_LCD_CONTRAST 32 + #endif + #endif + #endif + + #ifndef BOOTSCREEN_TIMEOUT + #define BOOTSCREEN_TIMEOUT 2500 + #endif + + /** + * Extruders have some combination of stepper motors and hotends + * so we separate these concepts into the defines: + * + * EXTRUDERS - Number of Selectable Tools + * HOTENDS - Number of hotends, whether connected or separate + * E_STEPPERS - Number of actual E stepper motors + * TOOL_E_INDEX - Index to use when getting/setting the tool state + * + */ + #if ENABLED(SINGLENOZZLE) // One hotend, multi-extruder + #define HOTENDS 1 + #define E_STEPPERS EXTRUDERS + #define E_MANUAL EXTRUDERS + #define TOOL_E_INDEX current_block->active_extruder + #undef TEMP_SENSOR_1_AS_REDUNDANT + #undef HOTEND_OFFSET_X + #undef HOTEND_OFFSET_Y + #elif ENABLED(SWITCHING_EXTRUDER) // One E stepper, unified E axis, two hotends + #define HOTENDS EXTRUDERS + #define E_STEPPERS 1 + #define E_MANUAL 1 + #define TOOL_E_INDEX 0 + #ifndef HOTEND_OFFSET_Z + #define HOTEND_OFFSET_Z { 0 } + #endif + #elif ENABLED(MIXING_EXTRUDER) // Multi-stepper, unified E axis, one hotend + #define HOTENDS 1 + #define E_STEPPERS MIXING_STEPPERS + #define E_MANUAL 1 + #define TOOL_E_INDEX 0 + #else // One stepper, E axis, and hotend per tool + #define HOTENDS EXTRUDERS + #define E_STEPPERS EXTRUDERS + #define E_MANUAL EXTRUDERS + #define TOOL_E_INDEX current_block->active_extruder + #endif + +#endif //CONDITIONALS_LCD_H diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/Conditionals_post.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/Conditionals_post.h new file mode 100644 index 00000000..aa6b28a5 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/Conditionals_post.h @@ -0,0 +1,663 @@ +/** + * 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 . + * + */ + +/** + * Conditionals_post.h + * Defines that depend on configuration but are not editable. + */ + +#ifndef CONDITIONALS_POST_H +#define CONDITIONALS_POST_H + + #if ENABLED(EMERGENCY_PARSER) + #define EMERGENCY_PARSER_CAPABILITIES " EMERGENCY_CODES:M108,M112,M410" + #else + #define EMERGENCY_PARSER_CAPABILITIES "" + #endif + + /** + * Set ENDSTOPPULLUPS for unused endstop switches + */ + #if ENABLED(ENDSTOPPULLUPS) + #if ENABLED(USE_XMAX_PLUG) + #define ENDSTOPPULLUP_XMAX + #endif + #if ENABLED(USE_YMAX_PLUG) + #define ENDSTOPPULLUP_YMAX + #endif + #if ENABLED(USE_ZMAX_PLUG) + #define ENDSTOPPULLUP_ZMAX + #endif + #if ENABLED(USE_XMIN_PLUG) + #define ENDSTOPPULLUP_XMIN + #endif + #if ENABLED(USE_YMIN_PLUG) + #define ENDSTOPPULLUP_YMIN + #endif + #if ENABLED(USE_ZMIN_PLUG) + #define ENDSTOPPULLUP_ZMIN + #endif + #if DISABLED(DISABLE_Z_MIN_PROBE_ENDSTOP) + #define ENDSTOPPULLUP_ZMIN_PROBE + #endif + #endif + + /** + * Axis lengths + */ + #define X_MAX_LENGTH (X_MAX_POS - (X_MIN_POS)) + #define Y_MAX_LENGTH (Y_MAX_POS - (Y_MIN_POS)) + #define Z_MAX_LENGTH (Z_MAX_POS - (Z_MIN_POS)) + + /** + * CoreXY and CoreXZ + */ + #if ENABLED(COREXY) + #define CORE_AXIS_1 A_AXIS // XY from A + B + #define CORE_AXIS_2 B_AXIS + #define NORMAL_AXIS Z_AXIS + #elif ENABLED(COREXZ) + #define CORE_AXIS_1 A_AXIS // XZ from A + C + #define CORE_AXIS_2 C_AXIS + #define NORMAL_AXIS Y_AXIS + #elif ENABLED(COREYZ) + #define CORE_AXIS_1 B_AXIS // YZ from B + C + #define CORE_AXIS_2 C_AXIS + #define NORMAL_AXIS X_AXIS + #endif + + /** + * SCARA + */ + #if ENABLED(SCARA) + #undef SLOWDOWN + #define QUICK_HOME //SCARA needs Quickhome + #endif + + /** + * Set the home position based on settings or manual overrides + */ + #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_MAX_LENGTH) * (X_HOME_DIR) * 0.5) + #endif + #else + #if ENABLED(DELTA) + #define X_HOME_POS ((X_MAX_LENGTH) * 0.5) + #else + #define X_HOME_POS (X_HOME_DIR < 0 ? X_MIN_POS : X_MAX_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_MAX_LENGTH) * (Y_HOME_DIR) * 0.5) + #endif + #else + #if ENABLED(DELTA) + #define Y_HOME_POS ((Y_MAX_LENGTH) * 0.5) + #else + #define Y_HOME_POS (Y_HOME_DIR < 0 ? Y_MIN_POS : Y_MAX_POS) + #endif + #endif + + #ifdef MANUAL_Z_HOME_POS + #define Z_HOME_POS MANUAL_Z_HOME_POS + #else + #define Z_HOME_POS (Z_HOME_DIR < 0 ? Z_MIN_POS : Z_MAX_POS) + #endif + + /** + * The BLTouch Probe emulates a servo probe + */ + #if ENABLED(BLTOUCH) + #undef Z_ENDSTOP_SERVO_NR + #undef Z_SERVO_ANGLES + #define Z_ENDSTOP_SERVO_NR 0 + #define Z_SERVO_ANGLES {10,90} // For BLTouch 10=deploy, 90=retract + #undef DEACTIVATE_SERVOS_AFTER_MOVE + #if ENABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN) + #undef Z_MIN_ENDSTOP_INVERTING + #define Z_MIN_ENDSTOP_INVERTING false + #endif + #endif + + /** + * Auto Bed Leveling and Z Probe Repeatability Test + */ + #define HAS_PROBING_PROCEDURE (ENABLED(AUTO_BED_LEVELING_FEATURE) || ENABLED(Z_MIN_PROBE_REPEATABILITY_TEST)) + + // Boundaries for probing based on set limits + #define MIN_PROBE_X (max(X_MIN_POS, X_MIN_POS + X_PROBE_OFFSET_FROM_EXTRUDER)) + #define MAX_PROBE_X (min(X_MAX_POS, X_MAX_POS + X_PROBE_OFFSET_FROM_EXTRUDER)) + #define MIN_PROBE_Y (max(Y_MIN_POS, Y_MIN_POS + Y_PROBE_OFFSET_FROM_EXTRUDER)) + #define MAX_PROBE_Y (min(Y_MAX_POS, Y_MAX_POS + Y_PROBE_OFFSET_FROM_EXTRUDER)) + + #define HAS_Z_SERVO_ENDSTOP (defined(Z_ENDSTOP_SERVO_NR) && Z_ENDSTOP_SERVO_NR >= 0) + + /** + * Z Sled Probe requires Z_SAFE_HOMING + */ + #if ENABLED(Z_PROBE_SLED) + #define Z_SAFE_HOMING + #endif + + /** + * DELTA should ignore Z_SAFE_HOMING + */ + #if ENABLED(DELTA) + #undef Z_SAFE_HOMING + #endif + + /** + * Safe Homing Options + */ + #if ENABLED(Z_SAFE_HOMING) + #ifndef Z_SAFE_HOMING_X_POINT + #define Z_SAFE_HOMING_X_POINT ((X_MIN_POS + X_MAX_POS) / 2) + #endif + #ifndef Z_SAFE_HOMING_Y_POINT + #define Z_SAFE_HOMING_Y_POINT ((Y_MIN_POS + Y_MAX_POS) / 2) + #endif + #endif + + /** + * Host keep alive + */ + #ifndef DEFAULT_KEEPALIVE_INTERVAL + #define DEFAULT_KEEPALIVE_INTERVAL 2 + #endif + + /** + * MAX_STEP_FREQUENCY differs for TOSHIBA + */ + #if ENABLED(CONFIG_STEPPERS_TOSHIBA) + #define MAX_STEP_FREQUENCY 10000 // Max step frequency for Toshiba Stepper Controllers + #else + #define MAX_STEP_FREQUENCY 40000 // Max step frequency for Ultimaker (5000 pps / half step) + #endif + + // MS1 MS2 Stepper Driver Microstepping mode table + #define MICROSTEP1 LOW,LOW + #define MICROSTEP2 HIGH,LOW + #define MICROSTEP4 LOW,HIGH + #define MICROSTEP8 HIGH,HIGH + #define MICROSTEP16 HIGH,HIGH + + /** + * Advance calculated values + */ + #if ENABLED(ADVANCE) + #define EXTRUSION_AREA (0.25 * (D_FILAMENT) * (D_FILAMENT) * M_PI) + #define STEPS_PER_CUBIC_MM_E (axis_steps_per_mm[E_AXIS] / (EXTRUSION_AREA)) + #endif + + #if ENABLED(ULTIPANEL) && DISABLED(ELB_FULL_GRAPHIC_CONTROLLER) + #undef SD_DETECT_INVERTED + #endif + + /** + * Set defaults for missing (newer) options + */ + #ifndef DISABLE_INACTIVE_X + #define DISABLE_INACTIVE_X DISABLE_X + #endif + #ifndef DISABLE_INACTIVE_Y + #define DISABLE_INACTIVE_Y DISABLE_Y + #endif + #ifndef DISABLE_INACTIVE_Z + #define DISABLE_INACTIVE_Z DISABLE_Z + #endif + #ifndef DISABLE_INACTIVE_E + #define DISABLE_INACTIVE_E DISABLE_E + #endif + + // Power Signal Control Definitions + // By default use ATX definition + #ifndef POWER_SUPPLY + #define POWER_SUPPLY 1 + #endif + #if (POWER_SUPPLY == 1) // 1 = ATX + #define PS_ON_AWAKE LOW + #define PS_ON_ASLEEP HIGH + #elif (POWER_SUPPLY == 2) // 2 = X-Box 360 203W + #define PS_ON_AWAKE HIGH + #define PS_ON_ASLEEP LOW + #endif + #define HAS_POWER_SWITCH (POWER_SUPPLY > 0 && PIN_EXISTS(PS_ON)) + + /** + * Temp Sensor defines + */ + #if TEMP_SENSOR_0 == -3 + #define HEATER_0_USES_MAX6675 + #define MAX6675_IS_MAX31855 + #elif TEMP_SENSOR_0 == -2 + #define HEATER_0_USES_MAX6675 + #elif TEMP_SENSOR_0 == -1 + #define HEATER_0_USES_AD595 + #elif TEMP_SENSOR_0 == 0 + #undef HEATER_0_MINTEMP + #undef HEATER_0_MAXTEMP + #elif TEMP_SENSOR_0 > 0 + #define THERMISTORHEATER_0 TEMP_SENSOR_0 + #define HEATER_0_USES_THERMISTOR + #endif + + #if TEMP_SENSOR_1 <= -2 + #error "MAX6675 / MAX31855 Thermocouples not supported for TEMP_SENSOR_1" + #elif TEMP_SENSOR_1 == -1 + #define HEATER_1_USES_AD595 + #elif TEMP_SENSOR_1 == 0 + #undef HEATER_1_MINTEMP + #undef HEATER_1_MAXTEMP + #elif TEMP_SENSOR_1 > 0 + #define THERMISTORHEATER_1 TEMP_SENSOR_1 + #define HEATER_1_USES_THERMISTOR + #endif + + #if TEMP_SENSOR_2 <= -2 + #error "MAX6675 / MAX31855 Thermocouples not supported for TEMP_SENSOR_2" + #elif TEMP_SENSOR_2 == -1 + #define HEATER_2_USES_AD595 + #elif TEMP_SENSOR_2 == 0 + #undef HEATER_2_MINTEMP + #undef HEATER_2_MAXTEMP + #elif TEMP_SENSOR_2 > 0 + #define THERMISTORHEATER_2 TEMP_SENSOR_2 + #define HEATER_2_USES_THERMISTOR + #endif + + #if TEMP_SENSOR_3 <= -2 + #error "MAX6675 / MAX31855 Thermocouples not supported for TEMP_SENSOR_3" + #elif TEMP_SENSOR_3 == -1 + #define HEATER_3_USES_AD595 + #elif TEMP_SENSOR_3 == 0 + #undef HEATER_3_MINTEMP + #undef HEATER_3_MAXTEMP + #elif TEMP_SENSOR_3 > 0 + #define THERMISTORHEATER_3 TEMP_SENSOR_3 + #define HEATER_3_USES_THERMISTOR + #endif + + #if TEMP_SENSOR_BED <= -2 + #error "MAX6675 / MAX31855 Thermocouples not supported for TEMP_SENSOR_BED" + #elif TEMP_SENSOR_BED == -1 + #define BED_USES_AD595 + #elif TEMP_SENSOR_BED == 0 + #undef BED_MINTEMP + #undef BED_MAXTEMP + #elif TEMP_SENSOR_BED > 0 + #define THERMISTORBED TEMP_SENSOR_BED + #define BED_USES_THERMISTOR + #endif + + /** + * Flags for PID handling + */ + #define HAS_PID_HEATING (ENABLED(PIDTEMP) || ENABLED(PIDTEMPBED)) + #define HAS_PID_FOR_BOTH (ENABLED(PIDTEMP) && ENABLED(PIDTEMPBED)) + + /** + * Default hotend offsets, if not defined + */ + #if HOTENDS > 1 + #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 + #if !defined(HOTEND_OFFSET_Z) && (ENABLED(DUAL_X_CARRIAGE) || ENABLED(SWITCHING_EXTRUDER)) + #define HOTEND_OFFSET_Z { 0 } + #endif + #endif + + /** + * ARRAY_BY_EXTRUDERS based on EXTRUDERS + */ + #define ARRAY_BY_EXTRUDERS(args...) ARRAY_N(EXTRUDERS, args) + #define ARRAY_BY_EXTRUDERS1(v1) ARRAY_BY_EXTRUDERS(v1, v1, v1, v1, v1, v1) + + /** + * ARRAY_BY_HOTENDS based on HOTENDS + */ + #define ARRAY_BY_HOTENDS(args...) ARRAY_N(HOTENDS, args) + #define ARRAY_BY_HOTENDS1(v1) ARRAY_BY_HOTENDS(v1, v1, v1, v1, v1, v1) + + /** + * Z_DUAL_ENDSTOPS endstop reassignment + */ + #if ENABLED(Z_DUAL_ENDSTOPS) + #define _XMIN_ 100 + #define _YMIN_ 200 + #define _ZMIN_ 300 + #define _XMAX_ 101 + #define _YMAX_ 201 + #define _ZMAX_ 301 + #if Z2_USE_ENDSTOP == _XMAX_ + #define Z2_MAX_ENDSTOP_INVERTING X_MAX_ENDSTOP_INVERTING + #define Z2_MAX_PIN X_MAX_PIN + #undef USE_XMAX_PLUG + #elif Z2_USE_ENDSTOP == _YMAX_ + #define Z2_MAX_ENDSTOP_INVERTING Y_MAX_ENDSTOP_INVERTING + #define Z2_MAX_PIN Y_MAX_PIN + #undef USE_YMAX_PLUG + #elif Z2_USE_ENDSTOP == _ZMAX_ + #define Z2_MAX_ENDSTOP_INVERTING Z_MAX_ENDSTOP_INVERTING + #define Z2_MAX_PIN Z_MAX_PIN + #undef USE_ZMAX_PLUG + #elif Z2_USE_ENDSTOP == _XMIN_ + #define Z2_MAX_ENDSTOP_INVERTING X_MIN_ENDSTOP_INVERTING + #define Z2_MAX_PIN X_MIN_PIN + #undef USE_XMIN_PLUG + #elif Z2_USE_ENDSTOP == _YMIN_ + #define Z2_MAX_ENDSTOP_INVERTING Y_MIN_ENDSTOP_INVERTING + #define Z2_MAX_PIN Y_MIN_PIN + #undef USE_YMIN_PLUG + #elif Z2_USE_ENDSTOP == _ZMIN_ + #define Z2_MAX_ENDSTOP_INVERTING Z_MIN_ENDSTOP_INVERTING + #define Z2_MAX_PIN Z_MIN_PIN + #undef USE_ZMIN_PLUG + #else + #define Z2_MAX_ENDSTOP_INVERTING false + #endif + #endif + + /** + * Shorthand for pin tests, used wherever needed + */ + #define HAS_TEMP_0 (PIN_EXISTS(TEMP_0) && TEMP_SENSOR_0 != 0 && TEMP_SENSOR_0 > -2) + #define HAS_TEMP_1 (PIN_EXISTS(TEMP_1) && TEMP_SENSOR_1 != 0 && TEMP_SENSOR_1 > -2) + #define HAS_TEMP_2 (PIN_EXISTS(TEMP_2) && TEMP_SENSOR_2 != 0 && TEMP_SENSOR_2 > -2) + #define HAS_TEMP_3 (PIN_EXISTS(TEMP_3) && TEMP_SENSOR_3 != 0 && TEMP_SENSOR_3 > -2) + #define HAS_TEMP_BED (PIN_EXISTS(TEMP_BED) && TEMP_SENSOR_BED != 0 && TEMP_SENSOR_BED > -2) + #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_BED (PIN_EXISTS(HEATER_BED)) + #define HAS_AUTO_FAN_0 (PIN_EXISTS(EXTRUDER_0_AUTO_FAN)) + #define HAS_AUTO_FAN_1 (PIN_EXISTS(EXTRUDER_1_AUTO_FAN)) + #define HAS_AUTO_FAN_2 (PIN_EXISTS(EXTRUDER_2_AUTO_FAN)) + #define HAS_AUTO_FAN_3 (PIN_EXISTS(EXTRUDER_3_AUTO_FAN)) + #define HAS_AUTO_FAN (HAS_AUTO_FAN_0 || HAS_AUTO_FAN_1 || HAS_AUTO_FAN_2 || HAS_AUTO_FAN_3) + #define HAS_FAN0 (PIN_EXISTS(FAN)) + #define HAS_FAN1 (PIN_EXISTS(FAN1) && CONTROLLERFAN_PIN != FAN1_PIN && EXTRUDER_0_AUTO_FAN_PIN != FAN1_PIN && EXTRUDER_1_AUTO_FAN_PIN != FAN1_PIN && EXTRUDER_2_AUTO_FAN_PIN != FAN1_PIN) + #define HAS_FAN2 (PIN_EXISTS(FAN2) && CONTROLLERFAN_PIN != FAN2_PIN && EXTRUDER_0_AUTO_FAN_PIN != FAN2_PIN && EXTRUDER_1_AUTO_FAN_PIN != FAN2_PIN && EXTRUDER_2_AUTO_FAN_PIN != FAN2_PIN) + #define HAS_CONTROLLERFAN (PIN_EXISTS(CONTROLLERFAN)) + #define HAS_SERVOS (defined(NUM_SERVOS) && NUM_SERVOS > 0) + #define HAS_SERVO_0 (PIN_EXISTS(SERVO0)) + #define HAS_SERVO_1 (PIN_EXISTS(SERVO1)) + #define HAS_SERVO_2 (PIN_EXISTS(SERVO2)) + #define HAS_SERVO_3 (PIN_EXISTS(SERVO3)) + #define HAS_FILAMENT_WIDTH_SENSOR (PIN_EXISTS(FILWIDTH)) + #define HAS_FIL_RUNOUT (PIN_EXISTS(FIL_RUNOUT)) + #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_X_MIN (PIN_EXISTS(X_MIN)) + #define HAS_X_MAX (PIN_EXISTS(X_MAX)) + #define HAS_Y_MIN (PIN_EXISTS(Y_MIN)) + #define HAS_Y_MAX (PIN_EXISTS(Y_MAX)) + #define HAS_Z_MIN (PIN_EXISTS(Z_MIN)) + #define HAS_Z_MAX (PIN_EXISTS(Z_MAX)) + #define HAS_Z2_MIN (PIN_EXISTS(Z2_MIN)) + #define HAS_Z2_MAX (PIN_EXISTS(Z2_MAX)) + #define HAS_Z_MIN_PROBE_PIN (PIN_EXISTS(Z_MIN_PROBE)) + #define HAS_SOLENOID_1 (PIN_EXISTS(SOL1)) + #define HAS_SOLENOID_2 (PIN_EXISTS(SOL2)) + #define HAS_SOLENOID_3 (PIN_EXISTS(SOL3)) + #define HAS_MICROSTEPS (PIN_EXISTS(X_MS1)) + #define HAS_MICROSTEPS_E0 (PIN_EXISTS(E0_MS1)) + #define HAS_MICROSTEPS_E1 (PIN_EXISTS(E1_MS1)) + #define HAS_MICROSTEPS_E2 (PIN_EXISTS(E2_MS1)) + #define HAS_STEPPER_RESET (PIN_EXISTS(STEPPER_RESET)) + #define HAS_X_ENABLE (PIN_EXISTS(X_ENABLE)) + #define HAS_X2_ENABLE (PIN_EXISTS(X2_ENABLE)) + #define HAS_Y_ENABLE (PIN_EXISTS(Y_ENABLE)) + #define HAS_Y2_ENABLE (PIN_EXISTS(Y2_ENABLE)) + #define HAS_Z_ENABLE (PIN_EXISTS(Z_ENABLE)) + #define HAS_Z2_ENABLE (PIN_EXISTS(Z2_ENABLE)) + #define HAS_E0_ENABLE (PIN_EXISTS(E0_ENABLE)) + #define HAS_E1_ENABLE (PIN_EXISTS(E1_ENABLE)) + #define HAS_E2_ENABLE (PIN_EXISTS(E2_ENABLE)) + #define HAS_E3_ENABLE (PIN_EXISTS(E3_ENABLE)) + #define HAS_E4_ENABLE (PIN_EXISTS(E4_ENABLE)) + #define HAS_X_DIR (PIN_EXISTS(X_DIR)) + #define HAS_X2_DIR (PIN_EXISTS(X2_DIR)) + #define HAS_Y_DIR (PIN_EXISTS(Y_DIR)) + #define HAS_Y2_DIR (PIN_EXISTS(Y2_DIR)) + #define HAS_Z_DIR (PIN_EXISTS(Z_DIR)) + #define HAS_Z2_DIR (PIN_EXISTS(Z2_DIR)) + #define HAS_E0_DIR (PIN_EXISTS(E0_DIR)) + #define HAS_E1_DIR (PIN_EXISTS(E1_DIR)) + #define HAS_E2_DIR (PIN_EXISTS(E2_DIR)) + #define HAS_E3_DIR (PIN_EXISTS(E3_DIR)) + #define HAS_E4_DIR (PIN_EXISTS(E4_DIR)) + #define HAS_X_STEP (PIN_EXISTS(X_STEP)) + #define HAS_X2_STEP (PIN_EXISTS(X2_STEP)) + #define HAS_Y_STEP (PIN_EXISTS(Y_STEP)) + #define HAS_Y2_STEP (PIN_EXISTS(Y2_STEP)) + #define HAS_Z_STEP (PIN_EXISTS(Z_STEP)) + #define HAS_Z2_STEP (PIN_EXISTS(Z2_STEP)) + #define HAS_E0_STEP (PIN_EXISTS(E0_STEP)) + #define HAS_E1_STEP (PIN_EXISTS(E1_STEP)) + #define HAS_E2_STEP (PIN_EXISTS(E2_STEP)) + #define HAS_E3_STEP (PIN_EXISTS(E3_STEP)) + #define HAS_E4_STEP (PIN_EXISTS(E4_STEP)) + #define HAS_DIGIPOTSS (PIN_EXISTS(DIGIPOTSS)) + #define HAS_BUZZER (PIN_EXISTS(BEEPER) || ENABLED(LCD_USE_I2C_BUZZER)) + + #define HAS_MOTOR_CURRENT_PWM (PIN_EXISTS(MOTOR_CURRENT_PWM_XY) || PIN_EXISTS(MOTOR_CURRENT_PWM_Z) || PIN_EXISTS(MOTOR_CURRENT_PWM_E)) + + #define HAS_TEMP_HOTEND (HAS_TEMP_0 || ENABLED(HEATER_0_USES_MAX6675)) + + #define HAS_THERMALLY_PROTECTED_BED (HAS_TEMP_BED && HAS_HEATER_BED && ENABLED(THERMAL_PROTECTION_BED)) + + /** + * This value is used by M109 when trying to calculate a ballpark safe margin + * to prevent wait-forever situation. + */ + #ifndef EXTRUDE_MINTEMP + #define EXTRUDE_MINTEMP 170 + #endif + + /** + * Helper Macros for heaters and extruder fan + */ + #define WRITE_HEATER_0P(v) WRITE(HEATER_0_PIN, v) + #if HOTENDS > 1 || ENABLED(HEATERS_PARALLEL) + #define WRITE_HEATER_1(v) WRITE(HEATER_1_PIN, v) + #if HOTENDS > 2 + #define WRITE_HEATER_2(v) WRITE(HEATER_2_PIN, v) + #if HOTENDS > 3 + #define WRITE_HEATER_3(v) WRITE(HEATER_3_PIN, v) + #endif + #endif + #endif + #if ENABLED(HEATERS_PARALLEL) + #define WRITE_HEATER_0(v) { WRITE_HEATER_0P(v); WRITE_HEATER_1(v); } + #else + #define WRITE_HEATER_0(v) WRITE_HEATER_0P(v) + #endif + #if HAS_HEATER_BED + #define WRITE_HEATER_BED(v) WRITE(HEATER_BED_PIN, v) + #endif + + /** + * Up to 3 PWM fans + */ + #if HAS_FAN2 + #define FAN_COUNT 3 + #elif HAS_FAN1 + #define FAN_COUNT 2 + #elif HAS_FAN0 + #define FAN_COUNT 1 + #else + #define FAN_COUNT 0 + #endif + + #if HAS_FAN0 + #define WRITE_FAN(v) WRITE(FAN_PIN, v) + #define WRITE_FAN0(v) WRITE_FAN(v) + #endif + #if HAS_FAN1 + #define WRITE_FAN1(v) WRITE(FAN1_PIN, v) + #endif + #if HAS_FAN2 + #define WRITE_FAN2(v) WRITE(FAN2_PIN, v) + #endif + #define WRITE_FAN_N(n, v) WRITE_FAN##n(v) + + /** + * Servos and probes + */ + + #if HAS_SERVOS + #ifndef Z_ENDSTOP_SERVO_NR + #define Z_ENDSTOP_SERVO_NR -1 + #endif + #endif + + #define PROBE_SELECTED (ENABLED(FIX_MOUNTED_PROBE) || ENABLED(Z_PROBE_ALLEN_KEY) || HAS_Z_SERVO_ENDSTOP || ENABLED(Z_PROBE_SLED)) + + #define PROBE_PIN_CONFIGURED (HAS_Z_MIN_PROBE_PIN || (HAS_Z_MIN && ENABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN))) + + #define HAS_BED_PROBE (PROBE_SELECTED && PROBE_PIN_CONFIGURED) + + #if ENABLED(Z_PROBE_ALLEN_KEY) + #define PROBE_IS_TRIGGERED_WHEN_STOWED_TEST + #endif + + /** + * Bed Probe dependencies + */ + #if HAS_BED_PROBE + #ifndef Z_PROBE_OFFSET_RANGE_MIN + #define Z_PROBE_OFFSET_RANGE_MIN -20 + #endif + #ifndef Z_PROBE_OFFSET_RANGE_MAX + #define Z_PROBE_OFFSET_RANGE_MAX 20 + #endif + #ifndef XY_PROBE_SPEED + #ifdef HOMING_FEEDRATE_XY + #define XY_PROBE_SPEED HOMING_FEEDRATE_XY + #else + #define XY_PROBE_SPEED 4000 + #endif + #endif + #if Z_PROBE_TRAVEL_HEIGHT > Z_PROBE_DEPLOY_HEIGHT + #define _Z_PROBE_DEPLOY_HEIGHT Z_PROBE_TRAVEL_HEIGHT + #else + #define _Z_PROBE_DEPLOY_HEIGHT Z_PROBE_DEPLOY_HEIGHT + #endif + #else + #undef X_PROBE_OFFSET_FROM_EXTRUDER + #undef Y_PROBE_OFFSET_FROM_EXTRUDER + #undef Z_PROBE_OFFSET_FROM_EXTRUDER + #define X_PROBE_OFFSET_FROM_EXTRUDER 0 + #define Y_PROBE_OFFSET_FROM_EXTRUDER 0 + #define Z_PROBE_OFFSET_FROM_EXTRUDER 0 + #endif + + /** + * Delta radius/rod trimmers + */ + #if ENABLED(DELTA) + #ifndef DELTA_RADIUS_TRIM_TOWER_1 + #define DELTA_RADIUS_TRIM_TOWER_1 0.0 + #endif + #ifndef DELTA_RADIUS_TRIM_TOWER_2 + #define DELTA_RADIUS_TRIM_TOWER_2 0.0 + #endif + #ifndef DELTA_RADIUS_TRIM_TOWER_3 + #define DELTA_RADIUS_TRIM_TOWER_3 0.0 + #endif + #ifndef DELTA_DIAGONAL_ROD_TRIM_TOWER_1 + #define DELTA_DIAGONAL_ROD_TRIM_TOWER_1 0.0 + #endif + #ifndef DELTA_DIAGONAL_ROD_TRIM_TOWER_2 + #define DELTA_DIAGONAL_ROD_TRIM_TOWER_2 0.0 + #endif + #ifndef DELTA_DIAGONAL_ROD_TRIM_TOWER_3 + #define DELTA_DIAGONAL_ROD_TRIM_TOWER_3 0.0 + #endif + #if ENABLED(AUTO_BED_LEVELING_GRID) + #define DELTA_BED_LEVELING_GRID + #endif + #endif + + /** + * When not using other bed leveling... + */ + #if ENABLED(AUTO_BED_LEVELING_FEATURE) && DISABLED(AUTO_BED_LEVELING_GRID) && DISABLED(DELTA_BED_LEVELING_GRID) + #define AUTO_BED_LEVELING_3POINT + #endif + + /** + * Buzzer/Speaker + */ + #if ENABLED(LCD_USE_I2C_BUZZER) + #ifndef LCD_FEEDBACK_FREQUENCY_HZ + #define LCD_FEEDBACK_FREQUENCY_HZ 1000 + #endif + #ifndef LCD_FEEDBACK_FREQUENCY_DURATION_MS + #define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 + #endif + #elif PIN_EXISTS(BEEPER) + #ifndef LCD_FEEDBACK_FREQUENCY_HZ + #define LCD_FEEDBACK_FREQUENCY_HZ 5000 + #endif + #ifndef LCD_FEEDBACK_FREQUENCY_DURATION_MS + #define LCD_FEEDBACK_FREQUENCY_DURATION_MS 2 + #endif + #else + #ifndef LCD_FEEDBACK_FREQUENCY_DURATION_MS + #define LCD_FEEDBACK_FREQUENCY_DURATION_MS 2 + #endif + #endif + + /** + * Z_HOMING_HEIGHT / Z_PROBE_TRAVEL_HEIGHT + */ + #ifndef Z_HOMING_HEIGHT + #ifndef Z_PROBE_TRAVEL_HEIGHT + #define Z_HOMING_HEIGHT 0 + #else + #define Z_HOMING_HEIGHT Z_PROBE_TRAVEL_HEIGHT + #endif + #endif + #ifndef Z_PROBE_TRAVEL_HEIGHT + #define Z_PROBE_TRAVEL_HEIGHT Z_HOMING_HEIGHT + #endif + +#endif // CONDITIONALS_POST_H diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/Configuration.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/Configuration.h new file mode 100644 index 00000000..e82736ae --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/Configuration.h @@ -0,0 +1,1327 @@ +/** + * 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 . + * + */ + +/** + * Configuration.h + * + * Basic settings such as: + * + * - Type of electronics + * - Type of temperature sensor + * - Printer geometry + * - Endstop configuration + * - LCD controller + * - Extra features + * + * Advanced settings can be found in Configuration_adv.h + * + */ +#ifndef CONFIGURATION_H +#define CONFIGURATION_H + +/** + * + * *********************************** + * ** ATTENTION TO ALL DEVELOPERS ** + * *********************************** + * + * You must increment this version number for every significant change such as, + * but not limited to: ADD, DELETE RENAME OR REPURPOSE any directive/option. + * + * Note: Update also Version.h ! + */ +#define CONFIGURATION_H_VERSION 010100 + +//=========================================================================== +//============================= Getting Started ============================= +//=========================================================================== + +/** + * Here are some standard links for getting your machine calibrated: + * + * http://reprap.org/wiki/Calibration + * http://youtu.be/wAL9d7FgInk + * http://calculator.josefprusa.cz + * http://reprap.org/wiki/Triffid_Hunter%27s_Calibration_Guide + * http://www.thingiverse.com/thing:5573 + * https://sites.google.com/site/repraplogphase/calibration-of-your-reprap + * http://www.thingiverse.com/thing:298812 + */ + +//=========================================================================== +//============================= DELTA Printer =============================== +//=========================================================================== +// For a Delta printer replace the configuration files with the files in the +// example_configurations/delta directory. +// + +//=========================================================================== +//============================= SCARA Printer =============================== +//=========================================================================== +// For a Scara printer replace the configuration files with the files in the +// example_configurations/SCARA directory. +// + +// @section info + +// User-specified version info of this build to display in [Pronterface, etc] terminal window during +// startup. Implementation of an idea by Prof Braino to inform user that any changes made to this +// build by the user have been successfully uploaded into firmware. +#define STRING_CONFIG_H_AUTHOR "JGE" // Who made the changes. +#define SHOW_BOOTSCREEN +#define STRING_SPLASH_LINE1 SHORT_BUILD_VERSION // will be shown during bootup in line 1 +#define STRING_SPLASH_LINE2 MSG_BOOT_LINE2 // will be shown during bootup in line 2 + +// +// *** VENDORS PLEASE READ ***************************************************** +// +// Marlin now allow you to have a vendor boot image to be displayed on machine +// start. When SHOW_CUSTOM_BOOTSCREEN is defined Marlin will first show your +// custom boot image and them the default Marlin boot image is shown. +// +// We suggest for you to take advantage of this new feature and keep the Marlin +// boot image unmodified. For an example have a look at the bq Hephestos 2 +// example configuration folder. +// +//#define SHOW_CUSTOM_BOOTSCREEN +// @section machine + +// SERIAL_PORT selects which serial port should be used for communication with the host. +// This allows the connection of wireless adapters (for instance) to non-default port pins. +// Serial port 0 is still used by the Arduino bootloader regardless of this setting. +// :[0,1,2,3,4,5,6,7] +#define SERIAL_PORT 0 + +// This determines the communication speed of the printer +// :[2400,9600,19200,38400,57600,115200,250000] +#define BAUDRATE 115200 + +// Enable the Bluetooth serial interface on AT90USB devices +//#define BLUETOOTH + +// The following define selects which electronics board you have. +// Please choose the name from boards.h that matches your setup +#ifndef MOTHERBOARD + #define MOTHERBOARD BOARD_K8600 +#endif + +// Optional custom name for your RepStrap or other custom machine +// Displayed in the LCD "Ready" message +#define CUSTOM_MACHINE_NAME "Vertex Nano" + +// Define this to set a unique identifier for this printer, (Used by some programs to differentiate between machines) +// You can use an online service to generate a random UUID. (eg http://www.uuidgenerator.net/version4) +#define MACHINE_UUID "00000000-0000-0000-0000-000000000000" + +// This defines the number of extruders +// :[1,2,3,4] +#define EXTRUDERS 1 + +// For Cyclops or any "multi-extruder" that shares a single nozzle. +//#define SINGLENOZZLE + +// A dual extruder that uses a single stepper motor +// Don't forget to set SSDE_SERVO_ANGLES and HOTEND_OFFSET_X/Y/Z +//#define SWITCHING_EXTRUDER +#if ENABLED(SWITCHING_EXTRUDER) + #define SWITCHING_EXTRUDER_SERVO_NR 0 + #define SWITCHING_EXTRUDER_SERVO_ANGLES { 0, 90 } // Angles for E0, E1 + //#define HOTEND_OFFSET_Z {0.0, 0.0} +#endif + +/** + * "Mixing Extruder" + * - Adds a new code, M165, to set the current mix factors. + * - Extends the stepping routines to move multiple steppers in proportion to the mix. + * - Optional support for Repetier Host M163, M164, and virtual extruder. + * - This implementation supports only a single extruder. + * - Enable DIRECT_MIXING_IN_G1 for Pia Taubert's reference implementation + */ +//#define MIXING_EXTRUDER +#if ENABLED(MIXING_EXTRUDER) + #define MIXING_STEPPERS 2 // Number of steppers in your mixing extruder + #define MIXING_VIRTUAL_TOOLS 16 // Use the Virtual Tool method with M163 and M164 + //#define DIRECT_MIXING_IN_G1 // Allow ABCDHI mix factors in G1 movement commands +#endif + +// Offset of the extruders (uncomment if using more than one and relying on firmware to position when changing). +// The offset has to be X=0, Y=0 for the extruder 0 hotend (default extruder). +// For the other hotends it is their distance from the extruder 0 hotend. +//#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis +//#define HOTEND_OFFSET_Y {0.0, 5.00} // (in mm) for each extruder, offset of the hotend on the Y axis + +//// The following define selects which power supply you have. Please choose the one that matches your setup +// 1 = ATX +// 2 = X-Box 360 203Watts (the blue wire connected to PS_ON and the red wire to VCC) +// :{1:'ATX',2:'X-Box 360'} +#define POWER_SUPPLY 1 + +// Define this to have the electronics keep the power supply off on startup. If you don't know what this is leave it. +//#define PS_DEFAULT_OFF + +// @section temperature + +//=========================================================================== +//============================= Thermal Settings ============================ +//=========================================================================== +// +//--NORMAL IS 4.7kohm PULLUP!-- 1kohm pullup can be used on hotend sensor, using correct resistor and table +// +//// Temperature sensor settings: +// -3 is thermocouple with MAX31855 (only for sensor 0) +// -2 is thermocouple with MAX6675 (only for sensor 0) +// -1 is thermocouple with AD595 +// 0 is not used +// 1 is 100k thermistor - best choice for EPCOS 100k (4.7k pullup) +// 2 is 200k thermistor - ATC Semitec 204GT-2 (4.7k pullup) +// 3 is Mendel-parts thermistor (4.7k pullup) +// 4 is 10k thermistor !! do not use it for a hotend. It gives bad resolution at high temp. !! +// 5 is 100K thermistor - ATC Semitec 104GT-2 (Used in ParCan & J-Head) (4.7k pullup) +// 6 is 100k EPCOS - Not as accurate as table 1 (created using a fluke thermocouple) (4.7k pullup) +// 7 is 100k Honeywell thermistor 135-104LAG-J01 (4.7k pullup) +// 71 is 100k Honeywell thermistor 135-104LAF-J01 (4.7k pullup) +// 8 is 100k 0603 SMD Vishay NTCS0603E3104FXT (4.7k pullup) +// 9 is 100k GE Sensing AL03006-58.2K-97-G1 (4.7k pullup) +// 10 is 100k RS thermistor 198-961 (4.7k pullup) +// 11 is 100k beta 3950 1% thermistor (4.7k pullup) +// 12 is 100k 0603 SMD Vishay NTCS0603E3104FXT (4.7k pullup) (calibrated for Makibox hot bed) +// 13 is 100k Hisens 3950 1% up to 300°C for hotend "Simple ONE " & "Hotend "All In ONE" +// 20 is the PT100 circuit found in the Ultimainboard V2.x +// 60 is 100k Maker's Tool Works Kapton Bed Thermistor beta=3950 +// 66 is 4.7M High Temperature thermistor from Dyze Design +// 70 is the 100K thermistor found in the bq Hephestos 2 +// +// 1k ohm pullup tables - This is not normal, you would have to have changed out your 4.7k for 1k +// (but gives greater accuracy and more stable PID) +// 51 is 100k thermistor - EPCOS (1k pullup) +// 52 is 200k thermistor - ATC Semitec 204GT-2 (1k pullup) +// 55 is 100k thermistor - ATC Semitec 104GT-2 (Used in ParCan & J-Head) (1k pullup) +// +// 1047 is Pt1000 with 4k7 pullup +// 1010 is Pt1000 with 1k pullup (non standard) +// 147 is Pt100 with 4k7 pullup +// 110 is Pt100 with 1k pullup (non standard) +// 998 and 999 are Dummy Tables. They will ALWAYS read 25°C or the temperature defined below. +// Use it for Testing or Development purposes. NEVER for production machine. +//#define DUMMY_THERMISTOR_998_VALUE 25 +//#define DUMMY_THERMISTOR_999_VALUE 100 +// :{ '0': "Not used",'1':"100k / 4.7k - EPCOS",'2':"200k / 4.7k - ATC Semitec 204GT-2",'3':"Mendel-parts / 4.7k",'4':"10k !! do not use for a hotend. Bad resolution at high temp. !!",'5':"100K / 4.7k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)",'6':"100k / 4.7k EPCOS - Not as accurate as Table 1",'7':"100k / 4.7k Honeywell 135-104LAG-J01",'8':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT",'9':"100k / 4.7k GE Sensing AL03006-58.2K-97-G1",'10':"100k / 4.7k RS 198-961",'11':"100k / 4.7k beta 3950 1%",'12':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT (calibrated for Makibox hot bed)",'13':"100k Hisens 3950 1% up to 300°C for hotend 'Simple ONE ' & hotend 'All In ONE'",'20':"PT100 (Ultimainboard V2.x)",'51':"100k / 1k - EPCOS",'52':"200k / 1k - ATC Semitec 204GT-2",'55':"100k / 1k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)",'60':"100k Maker's Tool Works Kapton Bed Thermistor beta=3950",'66':"Dyze Design 4.7M High Temperature thermistor",'70':"the 100K thermistor found in the bq Hephestos 2",'71':"100k / 4.7k Honeywell 135-104LAF-J01",'147':"Pt100 / 4.7k",'1047':"Pt1000 / 4.7k",'110':"Pt100 / 1k (non-standard)",'1010':"Pt1000 / 1k (non standard)",'-3':"Thermocouple + MAX31855 (only for sensor 0)",'-2':"Thermocouple + MAX6675 (only for sensor 0)",'-1':"Thermocouple + AD595",'998':"Dummy 1",'999':"Dummy 2" } +#define TEMP_SENSOR_0 1 +#define TEMP_SENSOR_1 0 +#define TEMP_SENSOR_2 0 +#define TEMP_SENSOR_3 0 +#define TEMP_SENSOR_BED 0 + +// This makes temp sensor 1 a redundant sensor for sensor 0. If the temperatures difference between these sensors is to high the print will be aborted. +//#define TEMP_SENSOR_1_AS_REDUNDANT +#define MAX_REDUNDANT_TEMP_SENSOR_DIFF 10 + +// Extruder temperature must be close to target for this long before M109 returns success +#define TEMP_RESIDENCY_TIME 10 // (seconds) +#define TEMP_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// Bed temperature must be close to target for this long before M190 returns success +#define TEMP_BED_RESIDENCY_TIME 10 // (seconds) +#define TEMP_BED_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one +#define TEMP_BED_WINDOW 1 // (degC) Window around target to start the residency timer x degC early. + +// The minimal temperature defines the temperature below which the heater will not be enabled It is used +// to check that the wiring to the thermistor is not broken. +// Otherwise this would lead to the heater being powered on all the time. +#define HEATER_0_MINTEMP 5 +#define HEATER_1_MINTEMP 5 +#define HEATER_2_MINTEMP 5 +#define HEATER_3_MINTEMP 5 +#define BED_MINTEMP 5 + +// When temperature exceeds max temp, your heater will be switched off. +// This feature exists to protect your hotend from overheating accidentally, but *NOT* from thermistor short/failure! +// You should use MINTEMP for thermistor short/failure protection. +#define HEATER_0_MAXTEMP 275 +#define HEATER_1_MAXTEMP 275 +#define HEATER_2_MAXTEMP 275 +#define HEATER_3_MAXTEMP 275 +#define BED_MAXTEMP 150 + +//=========================================================================== +//============================= PID Settings ================================ +//=========================================================================== +// PID Tuning Guide here: http://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 +#if ENABLED(PIDTEMP) + //#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result. + //#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 5 // 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. + #define PID_INTEGRAL_DRIVE_MAX PID_MAX //limit for the integral term + #define K1 0.95 //smoothing factor within the PID + + // If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it + // Ultimaker + #define DEFAULT_Kp 100 + #define DEFAULT_Ki 6 + #define DEFAULT_Kd 400 + + // MakerGear + //#define DEFAULT_Kp 7.0 + //#define DEFAULT_Ki 0.1 + //#define DEFAULT_Kd 12 + + // Mendel Parts V9 on 12V + //#define DEFAULT_Kp 18.25 + //#define DEFAULT_Ki 0.53 + //#define DEFAULT_Kd 156= + +#endif // PIDTEMP + +//=========================================================================== +//============================= PID > Bed Temperature Control =============== +//=========================================================================== +// Select PID or bang-bang with PIDTEMPBED. If bang-bang, BED_LIMIT_SWITCHING will enable hysteresis +// +// Uncomment this to enable PID on the bed. It uses the same frequency PWM as the extruder. +// If your PID_dT is the default, and correct for your hardware/configuration, that means 7.689Hz, +// which is fine for driving a square wave into a resistive load and does not significantly impact you FET heating. +// This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W heater. +// If your configuration is significantly different than this and you don't understand the issues involved, you probably +// shouldn't use bed PID until someone else verifies your hardware works. +// If this is enabled, find your own PID constants below. +//#define PIDTEMPBED + +//#define BED_LIMIT_SWITCHING + +// This sets the max power delivered to the bed, and replaces the HEATER_BED_DUTY_CYCLE_DIVIDER option. +// all forms of bed control obey this (PID, bang-bang, bang-bang with hysteresis) +// setting this to anything other than 255 enables a form of PWM to the bed just like HEATER_BED_DUTY_CYCLE_DIVIDER did, +// so you shouldn't use it unless you are OK with PWM on your bed. (see the comment on enabling PIDTEMPBED) +#define MAX_BED_POWER 255 // limits duty cycle to bed; 255=full current + +#if ENABLED(PIDTEMPBED) + + //#define PID_BED_DEBUG // Sends debug data to the serial port. + + #define PID_BED_INTEGRAL_DRIVE_MAX MAX_BED_POWER //limit for the integral term + + //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 + +// @section extruder + +//this prevents dangerous Extruder moves, i.e. if the temperature is under the limit +//can be software-disabled for whatever purposes by +#define PREVENT_DANGEROUS_EXTRUDE +//if PREVENT_DANGEROUS_EXTRUDE is on, you can still disable (uncomment) very long bits of extrusion separately. +//#define PREVENT_LENGTHY_EXTRUDE + +#define EXTRUDE_MINTEMP 170 +#define EXTRUDE_MAXLENGTH (X_MAX_LENGTH+Y_MAX_LENGTH) //prevent extrusion of very large distances. + +//=========================================================================== +//======================== Thermal Runaway Protection ======================= +//=========================================================================== + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * If you get "Thermal Runaway" or "Heating failed" errors the + * details can be tuned in Configuration_adv.h + */ + +#define THERMAL_PROTECTION_HOTENDS // Enable thermal protection for all extruders +#define THERMAL_PROTECTION_BED // Enable thermal protection for the heated bed + +//=========================================================================== +//============================= Mechanical Settings ========================= +//=========================================================================== + +// @section machine + +// Uncomment one of these options to enable CoreXY, CoreXZ, or CoreYZ kinematics +//#define COREXY +//#define COREXZ +//#define COREYZ + +// Enable this option for Toshiba steppers +//#define CONFIG_STEPPERS_TOSHIBA + +//=========================================================================== +//============================== Endstop Settings =========================== +//=========================================================================== + +// @section homing + +// Specify here all the endstop connectors that are connected to any endstop or probe. +// Almost all printers will be using one per axis. Probes will use one or more of the +// extra connectors. Leave undefined any used for non-endstop and non-probe purposes. +#define USE_XMIN_PLUG +//#define USE_YMIN_PLUG +//#define USE_ZMIN_PLUG +//#define USE_XMAX_PLUG +#define USE_YMAX_PLUG +#define USE_ZMAX_PLUG + +// coarse Endstop Settings +#define ENDSTOPPULLUPS // Comment this out (using // at the start of the line) to disable the endstop pullup resistors + +#if DISABLED(ENDSTOPPULLUPS) + // fine endstop settings: Individual pullups. will be ignored if ENDSTOPPULLUPS is defined + //#define ENDSTOPPULLUP_XMAX + //#define ENDSTOPPULLUP_YMAX + //#define ENDSTOPPULLUP_ZMAX + //#define ENDSTOPPULLUP_XMIN + //#define ENDSTOPPULLUP_YMIN + //#define ENDSTOPPULLUP_ZMIN + //#define ENDSTOPPULLUP_ZMIN_PROBE +#endif + +// Mechanical endstop with COM to ground and NC to Signal uses "false" here (most common setup). +#define X_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Y_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define X_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Y_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define Z_MIN_PROBE_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. + +//=========================================================================== +//============================= Z Probe Options ============================= +//=========================================================================== + +// +// Probe Type +// Probes are sensors/switches that are activated / deactivated before/after use. +// +// Allen Key Probes, Servo Probes, Z-Sled Probes, FIX_MOUNTED_PROBE, etc. +// You must activate one of these to use AUTO_BED_LEVELING_FEATURE below. +// +// Use M851 to set the Z probe vertical offset from the nozzle. Store with M500. +// + +// A Fix-Mounted Probe either doesn't deploy or needs manual deployment. +// For example an inductive probe, or a setup that uses the nozzle to probe. +// An inductive probe must be deactivated to go below +// its trigger-point if hardware endstops are active. +//#define FIX_MOUNTED_PROBE + +// The BLTouch probe emulates a servo probe. +//#define BLTOUCH + +// Z Servo Probe, such as an endstop switch on a rotating arm. +//#define Z_ENDSTOP_SERVO_NR 0 +//#define Z_SERVO_ANGLES {70,0} // Z Servo Deploy and Stow angles + +// Enable if you have a Z probe mounted on a sled like those designed by Charles Bell. +//#define Z_PROBE_SLED +//#define SLED_DOCKING_OFFSET 5 // The extra distance the X axis must travel to pickup the sled. 0 should be fine but you can push it further if you'd like. + +// Z Probe to nozzle (X,Y) offset, relative to (0, 0). +// X and Y offsets must be integers. +// +// In the following example the X and Y offsets are both positive: +// #define X_PROBE_OFFSET_FROM_EXTRUDER 10 +// #define Y_PROBE_OFFSET_FROM_EXTRUDER 10 +// +// +-- BACK ---+ +// | | +// L | (+) P | R <-- probe (20,20) +// E | | I +// F | (-) N (+) | G <-- nozzle (10,10) +// T | | H +// | (-) | T +// | | +// O-- FRONT --+ +// (0,0) +#define X_PROBE_OFFSET_FROM_EXTRUDER 10 // X offset: -left +right [of the nozzle] +#define Y_PROBE_OFFSET_FROM_EXTRUDER 10 // Y offset: -front +behind [the nozzle] +#define Z_PROBE_OFFSET_FROM_EXTRUDER 0 // Z offset: -below +above [the nozzle] + +// X and Y axis travel speed (mm/m) between probes +#define XY_PROBE_SPEED 8000 +// Speed for the first approach when double-probing (with PROBE_DOUBLE_TOUCH) +#define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z +// Speed for the "accurate" probe of each point +#define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2) +// Use double touch for probing +//#define PROBE_DOUBLE_TOUCH + +// +// Allen Key Probe is defined in the Delta example configurations. +// + +// Enable Z_MIN_PROBE_ENDSTOP to use _both_ a Z Probe and a Z-min-endstop on the same machine. +// With this option the Z_MIN_PROBE_PIN will only be used for probing, never for homing. +// +// *** PLEASE READ ALL INSTRUCTIONS BELOW FOR SAFETY! *** +// +// To continue using the Z-min-endstop for homing, be sure to disable Z_SAFE_HOMING. +// Example: To park the head outside the bed area when homing with G28. +// +// To use a separate Z probe, your board must define a Z_MIN_PROBE_PIN. +// +// For a servo-based Z probe, you must set up servo support below, including +// NUM_SERVOS, Z_ENDSTOP_SERVO_NR and Z_SERVO_ANGLES. +// +// - RAMPS 1.3/1.4 boards may be able to use the 5V, GND, and Aux4->D32 pin. +// - Use 5V for powered (usu. inductive) sensors. +// - Otherwise connect: +// - normally-closed switches to GND and D32. +// - normally-open switches to 5V and D32. +// +// Normally-closed switches are advised and are the default. +// +// The Z_MIN_PROBE_PIN sets the Arduino pin to use. (See your board's pins file.) +// Since the RAMPS Aux4->D32 pin maps directly to the Arduino D32 pin, D32 is the +// default pin for all RAMPS-based boards. Some other boards map differently. +// To set or change the pin for your board, edit the appropriate pins_XXXXX.h file. +// +// WARNING: +// Setting the wrong pin may have unexpected and potentially disastrous consequences. +// Use with caution and do your homework. +// +//#define Z_MIN_PROBE_ENDSTOP + +// Enable Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN to use the Z_MIN_PIN for your Z_MIN_PROBE. +// The Z_MIN_PIN will then be used for both Z-homing and probing. +#define Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + +// To use a probe you must enable one of the two options above! + +// This option disables the use of the Z_MIN_PROBE_PIN +// To enable the Z probe pin but disable its use, uncomment the line below. This only affects a +// Z probe switch if you have a separate Z min endstop also and have activated Z_MIN_PROBE_ENDSTOP above. +// If you're using the Z MIN endstop connector for your Z probe, this has no effect. +//#define DISABLE_Z_MIN_PROBE_ENDSTOP + +// Enable Z Probe Repeatability test to see how accurate your probe is +//#define Z_MIN_PROBE_REPEATABILITY_TEST + +// +// Probe Raise options provide clearance for the probe to deploy, stow, and travel. +// +#define Z_PROBE_DEPLOY_HEIGHT 15 // Raise to make room for the probe to deploy / stow +#define Z_PROBE_TRAVEL_HEIGHT 5 // Raise between probing points. + +// +// For M851 give a range for adjusting the Z probe offset +// +#define Z_PROBE_OFFSET_RANGE_MIN -20 +#define Z_PROBE_OFFSET_RANGE_MAX 20 + +// For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1 +// :{0:'Low',1:'High'} +#define X_ENABLE_ON 0 +#define Y_ENABLE_ON 0 +#define Z_ENABLE_ON 0 +#define E_ENABLE_ON 0 // For all extruders + +// Disables axis stepper immediately when it's not being used. +// WARNING: When motors turn off there is a chance of losing position accuracy! +#define DISABLE_X false +#define DISABLE_Y false +#define DISABLE_Z true +// Warn on display about possibly reduced accuracy +//#define DISABLE_REDUCED_ACCURACY_WARNING + +// @section extruder + +#define DISABLE_E false // For all extruders +#define DISABLE_INACTIVE_EXTRUDER true //disable only inactive extruders and keep active extruder enabled + +// @section machine + +// Invert the stepper direction. Change (or reverse the motor connector) if an axis goes the wrong way. +#define INVERT_X_DIR false +#define INVERT_Y_DIR false +#define INVERT_Z_DIR true + +// @section extruder + +// For direct drive extruder v9 set to true, for geared extruder set to false. +#define INVERT_E0_DIR false +#define INVERT_E1_DIR false +#define INVERT_E2_DIR false +#define INVERT_E3_DIR false + +// @section homing + +//#define Z_HOMING_HEIGHT 4 // (in mm) Minimal z height before homing (G28) for Z clearance above the bed, clamps, ... + // Be sure you have this distance over your Z_MAX_POS in case. + +// ENDSTOP SETTINGS: +// Sets direction of endstops when homing; 1=MAX, -1=MIN +// :[-1,1] +#define X_HOME_DIR -1 +#define Y_HOME_DIR 1 +#define Z_HOME_DIR 1 + +#define min_software_endstops false // If true, axis won't move to coordinates less than HOME_POS. +#define max_software_endstops true // If true, axis won't move to coordinates greater than the defined lengths below. + +// @section machine + +// Travel limits after homing (units are in mm) +#define X_MIN_POS 0 +#define Y_MIN_POS 0 +#define Z_MIN_POS 0 +#define X_MAX_POS 80 +#define Y_MAX_POS 80 +#define Z_MAX_POS 74 + +//=========================================================================== +//========================= Filament Runout Sensor ========================== +//=========================================================================== +//#define FILAMENT_RUNOUT_SENSOR // Uncomment for defining a filament runout sensor such as a mechanical or opto endstop to check the existence of filament + // In RAMPS uses servo pin 2. Can be changed in pins file. For other boards pin definition should be made. + // It is assumed that when logic high = filament available + // when logic low = filament ran out +#if ENABLED(FILAMENT_RUNOUT_SENSOR) + const bool FIL_RUNOUT_INVERTING = false; // set to true to invert the logic of the sensor. + #define ENDSTOPPULLUP_FIL_RUNOUT // Uncomment to use internal pullup for filament runout pins if the sensor is defined. + #define FILAMENT_RUNOUT_SCRIPT "M600" +#endif + +//=========================================================================== +//============================ Mesh Bed Leveling ============================ +//=========================================================================== + +//#define MESH_BED_LEVELING // Enable mesh bed leveling. + +#if ENABLED(MESH_BED_LEVELING) + #define MESH_INSET 10 // Mesh inset margin on print area + #define MESH_NUM_X_POINTS 3 // Don't use more than 7 points per axis, implementation limited. + #define MESH_NUM_Y_POINTS 3 + #define MESH_HOME_SEARCH_Z 4 // Z after Home, bed somewhere below but above 0.0. + + //#define MESH_G28_REST_ORIGIN // After homing all axes ('G28' or 'G28 XYZ') rest at origin [0,0,0] + + //#define MANUAL_BED_LEVELING // Add display menu option for bed leveling. + + #if ENABLED(MANUAL_BED_LEVELING) + #define MBL_Z_STEP 0.025 // Step size while manually probing Z axis. + #endif // MANUAL_BED_LEVELING + +#endif // MESH_BED_LEVELING + +//=========================================================================== +//============================ Bed Auto Leveling ============================ +//=========================================================================== + +// @section bedlevel + +//#define AUTO_BED_LEVELING_FEATURE // Delete the comment to enable (remove // at the start of the line) + +// Enable this feature to get detailed logging of G28, G29, M48, etc. +// Logging is off by default. Enable this logging feature with 'M111 S32'. +// NOTE: Requires a huge amount of PROGMEM. +//#define DEBUG_LEVELING_FEATURE + +#if ENABLED(AUTO_BED_LEVELING_FEATURE) + + // There are 2 different ways to specify probing locations: + // + // - "grid" mode + // Probe several points in a rectangular grid. + // You specify the rectangle and the density of sample points. + // This mode is preferred because there are more measurements. + // + // - "3-point" mode + // Probe 3 arbitrary points on the bed (that aren't collinear) + // You specify the XY coordinates of all 3 points. + + // Enable this to sample the bed in a grid (least squares solution). + // Note: this feature generates 10KB extra code size. + #define AUTO_BED_LEVELING_GRID + + #if ENABLED(AUTO_BED_LEVELING_GRID) + + #define LEFT_PROBE_BED_POSITION 15 + #define RIGHT_PROBE_BED_POSITION 170 + #define FRONT_PROBE_BED_POSITION 20 + #define BACK_PROBE_BED_POSITION 170 + + #define MIN_PROBE_EDGE 10 // The Z probe minimum square sides can be no smaller than this. + + // Set the number of grid points per dimension. + // You probably don't need more than 3 (squared=9). + #define AUTO_BED_LEVELING_GRID_POINTS 2 + + #else // !AUTO_BED_LEVELING_GRID + + // Arbitrary points to probe. + // A simple cross-product is used to estimate the plane of the bed. + #define ABL_PROBE_PT_1_X 15 + #define ABL_PROBE_PT_1_Y 180 + #define ABL_PROBE_PT_2_X 15 + #define ABL_PROBE_PT_2_Y 20 + #define ABL_PROBE_PT_3_X 170 + #define ABL_PROBE_PT_3_Y 20 + + #endif // !AUTO_BED_LEVELING_GRID + + //#define Z_PROBE_END_SCRIPT "G1 Z10 F12000\nG1 X15 Y330\nG1 Z0.5\nG1 Z10" // These commands will be executed in the end of G29 routine. + // Useful to retract a deployable Z probe. + + // If you've enabled AUTO_BED_LEVELING_FEATURE and are using the Z Probe for Z Homing, + // it is highly recommended you also enable Z_SAFE_HOMING below! + +#endif // AUTO_BED_LEVELING_FEATURE + + +// @section homing + +// The center of the bed is at (X=0, Y=0) +//#define BED_CENTER_AT_0_0 + +// Manually set the home position. Leave these undefined for automatic settings. +// For DELTA this is the top-center of the Cartesian print volume. +//#define MANUAL_X_HOME_POS 0 +//#define MANUAL_Y_HOME_POS 0 +//#define MANUAL_Z_HOME_POS 0 // Distance between the nozzle to printbed after homing + +// Use "Z Safe Homing" to avoid homing with a Z probe outside the bed area. +// +// With this feature enabled: +// +// - 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). +// - 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_MIN_POS + X_MAX_POS) / 2) // X point for Z homing when homing all axis (G28). + #define Z_SAFE_HOMING_Y_POINT ((Y_MIN_POS + Y_MAX_POS) / 2) // Y point for Z homing when homing all axis (G28). +#endif + +// Homing speeds (mm/m) +#define HOMING_FEEDRATE_XY (30*60) +#define HOMING_FEEDRATE_Z (8*60) + +// +// MOVEMENT SETTINGS +// @section motion +// + +// default settings + +#define DEFAULT_AXIS_STEPS_PER_UNIT {100,100,4675,75.75} // default steps per unit for Ultimaker +#define DEFAULT_MAX_FEEDRATE {150, 150, 2.5, 50} // (mm/sec) +#define DEFAULT_MAX_ACCELERATION {1500,1500,50,10000} // X, Y, Z, E maximum start speed for accelerated moves. E default values are good for Skeinforge 40+, for older versions raise them a lot. + +#define DEFAULT_ACCELERATION 1500 // X, Y, Z and E acceleration in mm/s^2 for printing moves +#define DEFAULT_RETRACT_ACCELERATION 1500 // E acceleration in mm/s^2 for retracts +#define DEFAULT_TRAVEL_ACCELERATION 1500 // X, Y, Z acceleration in mm/s^2 for travel (non printing) moves + +// The speed change that does not require acceleration (i.e. the software might assume it can be done instantaneously) +#define DEFAULT_XYJERK 5.0 // (mm/sec) +#define DEFAULT_ZJERK 0.4 // (mm/sec) +#define DEFAULT_EJERK 5.0 // (mm/sec) + + +//============================================================================= +//============================= Additional Features =========================== +//============================================================================= + +// @section extras + +// +// EEPROM +// +// The microcontroller can store settings in the EEPROM, e.g. max velocity... +// M500 - stores parameters in EEPROM +// M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily). +// M502 - reverts to the default "factory settings". You still need to store them in EEPROM afterwards if you want to. +//define this to enable EEPROM support +#define EEPROM_SETTINGS + +#if ENABLED(EEPROM_SETTINGS) + // To disable EEPROM Serial responses and decrease program space by ~1700 byte: comment this out: + #define EEPROM_CHITCHAT // Please keep turned on if you can. +#endif + +// +// Host Keepalive +// +// When enabled Marlin will send a busy status message to the host +// every couple of seconds when it can't accept commands. +// +#define HOST_KEEPALIVE_FEATURE // Disable this if your host doesn't like keepalive messages +#define DEFAULT_KEEPALIVE_INTERVAL 2 // Number of seconds between "busy" messages. Set with M113. + +// +// M100 Free Memory Watcher +// +//#define M100_FREE_MEMORY_WATCHER // uncomment to add the M100 Free Memory Watcher for debug purpose + +// +// G20/G21 Inch mode support +// +//#define INCH_MODE_SUPPORT + +// +// M149 Set temperature units support +// +//#define TEMPERATURE_UNITS_SUPPORT + +// @section temperature + +// Preheat Constants +#define PREHEAT_1_TEMP_HOTEND 190 +#define PREHEAT_1_TEMP_BED 0 +#define PREHEAT_1_FAN_SPEED 255 // Value from 0 to 255 + +#define PREHEAT_2_TEMP_HOTEND 235 +#define PREHEAT_2_TEMP_BED 0 +#define PREHEAT_2_FAN_SPEED 255 // Value from 0 to 255 + +// +// Nozzle Park -- EXPERIMENTAL +// +// When enabled allows the user to define a special XYZ position, inside the +// machine's topology, to park the nozzle when idle or when receiving the G27 +// command. +// +// The "P" paramenter controls what is the action applied to the Z axis: +// P0: (Default) If current Z-pos is lower than Z-park then the nozzle will +// be raised to reach Z-park height. +// +// P1: No matter the current Z-pos, the nozzle will be raised/lowered to +// reach Z-park height. +// +// P2: The nozzle height will be raised by Z-park amount but never going over +// the machine's limit of Z_MAX_POS. +// +//#define NOZZLE_PARK_FEATURE + +#if ENABLED(NOZZLE_PARK_FEATURE) + // Specify a park position as { X, Y, Z } + #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 } +#endif + +// +// Clean Nozzle Feature -- EXPERIMENTAL +// +// When enabled allows the user to send G12 to start the nozzle cleaning +// process, the G-Code accepts two parameters: +// "P" for pattern selection +// "S" for defining the number of strokes/repetitions +// +// Available list of patterns: +// P0: This is the default pattern, this process requires a sponge type +// material at a fixed bed location, the cleaning process is based on +// "strokes" i.e. back-and-forth movements between the starting and end +// points. +// +// P1: This starts a zig-zag pattern between (X0, Y0) and (X1, Y1), "T" +// defines the number of zig-zag triangles to be done. "S" defines the +// number of strokes aka one back-and-forth movement. As an example +// sending "G12 P1 S1 T3" will execute: +// +// -- +// | (X0, Y1) | /\ /\ /\ | (X1, Y1) +// | | / \ / \ / \ | +// A | | / \ / \ / \ | +// | | / \ / \ / \ | +// | (X0, Y0) | / \/ \/ \ | (X1, Y0) +// -- +--------------------------------+ +// |________|_________|_________| +// T1 T2 T3 +// +// Caveats: End point Z should use the same value as Start point Z. +// +// Attention: This is an EXPERIMENTAL feature, in the future the G-code arguments +// may change to add new functionality like different wipe patterns. +// +//#define NOZZLE_CLEAN_FEATURE + +#if ENABLED(NOZZLE_CLEAN_FEATURE) + // Number of pattern repetitions + #define NOZZLE_CLEAN_STROKES 12 + + // Specify positions as { X, Y, Z } + #define NOZZLE_CLEAN_START_POINT { 30, 30, (Z_MIN_POS + 1)} + #define NOZZLE_CLEAN_END_POINT {100, 60, (Z_MIN_POS + 1)} + + // Moves the nozzle to the initial position + #define NOZZLE_CLEAN_GOBACK +#endif + +// +// Print job timer +// +// Enable this option to automatically start and stop the +// print job timer when M104/M109/M190 commands are received. +// M104 (extruder without wait) - high temp = none, low temp = stop timer +// M109 (extruder with wait) - high temp = start timer, low temp = stop timer +// M190 (bed with wait) - high temp = start timer, low temp = none +// +// In all cases the timer can be started and stopped using +// the following commands: +// +// - M75 - Start the print job timer +// - M76 - Pause the print job timer +// - M77 - Stop the print job timer +#define PRINTJOB_TIMER_AUTOSTART + +// +// Print Counter +// +// When enabled Marlin will keep track of some print statistical data such as: +// - Total print jobs +// - Total successful print jobs +// - Total failed print jobs +// - Total time printing +// +// This information can be viewed by the M78 command. +#define PRINTCOUNTER + +//============================================================================= +//============================= LCD and SD support ============================ +//============================================================================= + +// @section lcd + +// +// LCD LANGUAGE +// +// Here you may choose the language used by Marlin on the LCD menus, the following +// list of languages are available: +// en, an, bg, ca, cn, cz, de, el, el-gr, es, eu, fi, fr, gl, hr, it, +// kana, kana_utf8, nl, pl, pt, pt_utf8, pt-br, pt-br_utf8, ru, test +// +// :{'en':'English','an':'Aragonese','bg':'Bulgarian','ca':'Catalan','cn':'Chinese','cz':'Czech','de':'German','el':'Greek','el-gr':'Greek (Greece)','es':'Spanish','eu':'Basque-Euskera','fi':'Finnish','fr':'French','gl':'Galician','hr':'Croatian','it':'Italian','kana':'Japanese','kana_utf8':'Japanese (UTF8)','nl':'Dutch','pl':'Polish','pt':'Portuguese','pt-br':'Portuguese (Brazilian)','pt-br_utf8':'Portuguese (Brazilian UTF8)','pt_utf8':'Portuguese (UTF8)','ru':'Russian','test':'TEST'} +// +#define LCD_LANGUAGE en + +// +// LCD Character Set +// +// Note: This option is NOT applicable to Graphical Displays. +// +// All character-based LCD's provide ASCII plus one of these +// language extensions: +// +// - JAPANESE ... the most common +// - WESTERN ... with more accented characters +// - CYRILLIC ... for the Russian language +// +// To determine the language extension installed on your controller: +// +// - Compile and upload with LCD_LANGUAGE set to 'test' +// - Click the controller to view the LCD menu +// - The LCD will display Japanese, Western, or Cyrillic text +// +// See https://github.com/MarlinFirmware/Marlin/wiki/LCD-Language +// +// :['JAPANESE','WESTERN','CYRILLIC'] +// +#define DISPLAY_CHARSET_HD44780 JAPANESE + +// +// LCD TYPE +// +// You may choose ULTRA_LCD if you have character based LCD with 16x2, 16x4, 20x2, +// 20x4 char/lines or DOGLCD for the full graphics display with 128x64 pixels +// (ST7565R family). (This option will be set automatically for certain displays.) +// +// IMPORTANT NOTE: The U8glib library is required for Full Graphic Display! +// https://github.com/olikraus/U8glib_Arduino +// +#define ULTRA_LCD // Character based +//#define DOGLCD // Full graphics display + +// +// SD CARD +// +// 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 + +// +// SD CARD: SPI SPEED +// +// Uncomment ONE of the following items to use a slower SPI transfer +// speed. This is usually required if you're getting volume init errors. +// +//#define SPI_SPEED SPI_HALF_SPEED +//#define SPI_SPEED SPI_QUARTER_SPEED +//#define SPI_SPEED SPI_EIGHTH_SPEED + +// +// SD CARD: ENABLE CRC +// +// Use CRC checks and retries on the SD communication. +// +//#define SD_CHECK_AND_RETRY + +// +// ENCODER SETTINGS +// +// This option overrides the default number of encoder pulses needed to +// produce one step. Should be increased for high-resolution encoders. +// +#define ENCODER_PULSES_PER_STEP 2 + +// +// Use this option to override the number of step signals required to +// move between next/prev menu items. +// +#define ENCODER_STEPS_PER_MENU_ITEM 1 + +/** + * Encoder Direction Options + * + * Test your encoder's behavior first with both options disabled. + * + * Reversed Value Edit and Menu Nav? Enable REVERSE_ENCODER_DIRECTION. + * Reversed Menu Navigation only? Enable REVERSE_MENU_DIRECTION. + * Reversed Value Editing only? Enable BOTH options. + */ + +// +// This option reverses the encoder direction everywhere +// +// Set this option if CLOCKWISE causes values to DECREASE +// +//#define REVERSE_ENCODER_DIRECTION + +// +// This option reverses the encoder direction for navigating LCD menus. +// +// If CLOCKWISE normally moves DOWN this makes it go UP. +// If CLOCKWISE normally moves UP this makes it go DOWN. +// +#define REVERSE_MENU_DIRECTION + +// +// Individual Axis Homing +// +// Add individual axis homing items (Home X, Home Y, and Home Z) to the LCD menu. +// +//#define INDIVIDUAL_AXIS_HOMING_MENU + +// +// SPEAKER/BUZZER +// +// If you have a speaker that can produce tones, enable it here. +// By default Marlin assumes you have a buzzer with a fixed frequency. +// +#define SPEAKER + +// +// The duration and frequency for the UI feedback sound. +// Set these to 0 to disable audio feedback in the LCD menus. +// +// Note: Test audio output with the G-Code: +// M300 S P +// +#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100 +#define LCD_FEEDBACK_FREQUENCY_HZ 1000 + +// +// CONTROLLER TYPE: Standard +// +// Marlin supports a wide variety of controllers. +// Enable one of the following options to specify your controller. +// + +// +// ULTIMAKER Controller. +// +#define ULTIMAKERCONTROLLER + +// +// ULTIPANEL as seen on Thingiverse. +// +//#define ULTIPANEL + +// +// Cartesio UI +// http://mauk.cc/webshop/cartesio-shop/electronics/user-interface +// +//#define CARTESIO_UI + +// +// PanelOne from T3P3 (via RAMPS 1.4 AUX2/AUX3) +// http://reprap.org/wiki/PanelOne +// +//#define PANEL_ONE + +// +// MaKr3d Makr-Panel with graphic controller and SD support. +// http://reprap.org/wiki/MaKr3d_MaKrPanel +// +//#define MAKRPANEL + +// +// ReprapWorld Graphical LCD +// https://reprapworld.com/?products_details&products_id/1218 +// +//#define REPRAPWORLD_GRAPHICAL_LCD + +// +// Activate one of these if you have a Panucatt Devices +// Viki 2.0 or mini Viki with Graphic LCD +// http://panucatt.com +// +//#define VIKI2 +//#define miniVIKI + +// +// Adafruit ST7565 Full Graphic Controller. +// https://github.com/eboston/Adafruit-ST7565-Full-Graphic-Controller/ +// +//#define ELB_FULL_GRAPHIC_CONTROLLER + +// +// RepRapDiscount Smart Controller. +// http://reprap.org/wiki/RepRapDiscount_Smart_Controller +// +// Note: Usually sold with a white PCB. +// +//#define REPRAP_DISCOUNT_SMART_CONTROLLER + +// +// GADGETS3D G3D LCD/SD Controller +// http://reprap.org/wiki/RAMPS_1.3/1.4_GADGETS3D_Shield_with_Panel +// +// Note: Usually sold with a blue PCB. +// +//#define G3D_PANEL + +// +// RepRapDiscount FULL GRAPHIC Smart Controller +// http://reprap.org/wiki/RepRapDiscount_Full_Graphic_Smart_Controller +// +//#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER + +// +// MakerLab Mini Panel with graphic +// controller and SD support - http://reprap.org/wiki/Mini_panel +// +//#define MINIPANEL + +// +// RepRapWorld REPRAPWORLD_KEYPAD v1.1 +// http://reprapworld.com/?products_details&products_id=202&cPath=1591_1626 +// +// REPRAPWORLD_KEYPAD_MOVE_STEP sets how much should the robot move when a key +// is pressed, a value of 10.0 means 10mm per click. +// +//#define REPRAPWORLD_KEYPAD +//#define REPRAPWORLD_KEYPAD_MOVE_STEP 10.0 + +// +// RigidBot Panel V1.0 +// http://www.inventapart.com/ +// +//#define RIGIDBOT_PANEL + +// +// BQ LCD Smart Controller shipped by +// default with the BQ Hephestos 2 and Witbox 2. +// +//#define BQ_LCD_SMART_CONTROLLER + +// +// CONTROLLER TYPE: I2C +// +// Note: These controllers require the installation of Arduino's LiquidCrystal_I2C +// library. For more info: https://github.com/kiyoshigawa/LiquidCrystal_I2C +// + +// +// Elefu RA Board Control Panel +// http://www.elefu.com/index.php?route=product/product&product_id=53 +// +//#define RA_CONTROL_PANEL + +// +// Sainsmart YW Robot (LCM1602) LCD Display +// +//#define LCD_I2C_SAINSMART_YWROBOT + +// +// Generic LCM1602 LCD adapter +// +//#define LCM1602 + +// +// PANELOLU2 LCD with status LEDs, +// separate encoder and click inputs. +// +// Note: This controller requires Arduino's LiquidTWI2 library v1.2.3 or later. +// For more info: https://github.com/lincomatic/LiquidTWI2 +// +// Note: The PANELOLU2 encoder click input can either be directly connected to +// a pin (if BTN_ENC defined to != -1) or read through I2C (when BTN_ENC == -1). +// +//#define LCD_I2C_PANELOLU2 + +// +// Panucatt VIKI LCD with status LEDs, +// integrated click & L/R/U/D buttons, separate encoder inputs. +// +//#define LCD_I2C_VIKI + +// +// SSD1306 OLED full graphics generic display +// +//#define U8GLIB_SSD1306 + +// +// SAV OLEd LCD module support using either SSD1306 or SH1106 based LCD modules +// +//#define SAV_3DGLCD +#if ENABLED(SAV_3DGLCD) + //#define U8GLIB_SSD1306 + #define U8GLIB_SH1106 +#endif + +// +// CONTROLLER TYPE: Shift register panels +// +// 2 wire Non-latching LCD SR from https://goo.gl/aJJ4sH +// LCD configuration: http://reprap.org/wiki/SAV_3D_LCD +// +//#define SAV_3DLCD + +//============================================================================= +//=============================== Extra Features ============================== +//============================================================================= + +// @section extras + +// Increase the FAN PWM frequency. Removes the PWM noise but increases heating in the FET/Arduino +//#define FAST_PWM_FAN + +// Use software PWM to drive the fan, as for the heaters. This uses a very low frequency +// which is not as annoying as with the hardware PWM. On the other hand, if this frequency +// is too low, you should also increment SOFT_PWM_SCALE. +//#define FAN_SOFT_PWM + +// Incrementing this by 1 will double the software PWM frequency, +// affecting heaters, and the fan if FAN_SOFT_PWM is enabled. +// However, control resolution will be halved for each increment; +// at zero value, there are 128 effective control positions. +#define SOFT_PWM_SCALE 0 + +// Temperature status LEDs that display the hotend and bed temperature. +// If all hotends and bed temperature and temperature setpoint are < 54C then the BLUE led is on. +// Otherwise the RED led is on. There is 1C hysteresis. +//#define TEMP_STAT_LEDS + +// M240 Triggers a camera by emulating a Canon RC-1 Remote +// Data from: http://www.doc-diy.net/photo/rc-1_hacked/ +//#define PHOTOGRAPH_PIN 23 + +// 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 + +//define BlinkM/CyzRgb Support +//#define BLINKM + +/*********************************************************************\ +* R/C SERVO support +* Sponsored by TrinityLabs, Reworked by codexmas +**********************************************************************/ + +// Number of servos +// +// If you select a configuration below, this will receive a default value and does not need to be set manually +// set it manually if you have more servos than extruders and wish to manually control some +// leaving it undefined or defining as 0 will disable the servo subsystem +// If unsure, leave commented / disabled +// +//#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command + +// Delay (in microseconds) before the next move will start, to give the servo time to reach its target angle. +// 300ms is a good value but you can try less delay. +// If the servo can't reach the requested position, increase it. +#define SERVO_DELAY 300 + +// Servo deactivation +// +// With this option servos are powered only during movement, then turned off to prevent jitter. +//#define DEACTIVATE_SERVOS_AFTER_MOVE + +/**********************************************************************\ + * Support for a filament diameter sensor + * Also allows adjustment of diameter at print time (vs at slicing) + * Single extruder only at this point (extruder 0) + * + * Motherboards + * 34 - RAMPS1.4 - uses Analog input 5 on the AUX2 connector + * 81 - Printrboard - Uses Analog input 2 on the Exp1 connector (version B,C,D,E) + * 301 - Rambo - uses Analog input 3 + * Note may require analog pins to be defined for different motherboards + **********************************************************************/ +// Uncomment below to enable +//#define FILAMENT_WIDTH_SENSOR + +#define DEFAULT_NOMINAL_FILAMENT_DIA 3.00 //Enter the diameter (in mm) of the filament generally used (3.0 mm or 1.75 mm) - this is then used in the slicer software. Used for sensor reading validation + +#if ENABLED(FILAMENT_WIDTH_SENSOR) + #define FILAMENT_SENSOR_EXTRUDER_NUM 0 //The number of the extruder that has the filament sensor (0,1,2) + #define MEASUREMENT_DELAY_CM 14 //measurement delay in cm. This is the distance from filament sensor to middle of barrel + + #define MEASURED_UPPER_LIMIT 3.30 //upper limit factor used for sensor reading validation in mm + #define MEASURED_LOWER_LIMIT 1.90 //lower limit factor for sensor reading validation in mm + #define MAX_MEASUREMENT_DELAY 20 //delay buffer size in bytes (1 byte = 1cm)- limits maximum measurement delay allowable (must be larger than MEASUREMENT_DELAY_CM and lower number saves RAM) + + #define DEFAULT_MEASURED_FILAMENT_DIA DEFAULT_NOMINAL_FILAMENT_DIA //set measured to nominal initially + + //When using an LCD, uncomment the line below to display the Filament sensor data on the last line instead of status. Status will appear for 5 sec. + //#define FILAMENT_LCD_DISPLAY +#endif + +#endif // CONFIGURATION_H diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/Configuration_adv.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/Configuration_adv.h new file mode 100644 index 00000000..0dcd7dd6 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/Configuration_adv.h @@ -0,0 +1,799 @@ +/** + * 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 . + * + */ + +/** + * Configuration_adv.h + * + * Advanced settings. + * Only change these if you know exactly what you're doing. + * Some of these settings can damage your printer if improperly set! + * + * Basic settings can be found in Configuration.h + * + */ +#ifndef CONFIGURATION_ADV_H +#define CONFIGURATION_ADV_H + +/** + * + * *********************************** + * ** ATTENTION TO ALL DEVELOPERS ** + * *********************************** + * + * You must increment this version number for every significant change such as, + * but not limited to: ADD, DELETE RENAME OR REPURPOSE any directive/option. + * + * Note: Update also Version.h ! + */ +#define CONFIGURATION_ADV_H_VERSION 010100 + +// @section temperature + +//=========================================================================== +//=============================Thermal Settings ============================ +//=========================================================================== + +#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 + #endif +#endif + +/** + * Thermal Protection protects your printer from damage and fire if a + * thermistor falls out or temperature sensors fail in any way. + * + * The issue: If a thermistor falls out or a temperature sensor fails, + * Marlin can no longer sense the actual temperature. Since a disconnected + * thermistor reads as a low temperature, the firmware will keep the heater on. + * + * The solution: Once the temperature reaches the target, start observing. + * If the temperature stays too far below the target (hysteresis) for too long (period), + * the firmware will halt the machine as a safety precaution. + * + * If you get false positives for "Thermal Runaway" increase THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD + */ +#if ENABLED(THERMAL_PROTECTION_HOTENDS) + #define THERMAL_PROTECTION_PERIOD 40 // Seconds + #define THERMAL_PROTECTION_HYSTERESIS 4 // Degrees Celsius + + /** + * Whenever an M104 or M109 increases the target temperature the firmware will wait for the + * WATCH_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get false positives for "Heating failed" increase WATCH_TEMP_PERIOD and/or decrease WATCH_TEMP_INCREASE + * WATCH_TEMP_INCREASE should not be below 2. + */ + #define WATCH_TEMP_PERIOD 60 // Seconds + #define WATCH_TEMP_INCREASE 2 // Degrees Celsius +#endif + +/** + * Thermal Protection parameters for the bed are just as above for hotends. + */ +#if ENABLED(THERMAL_PROTECTION_BED) + #define THERMAL_PROTECTION_BED_PERIOD 20 // Seconds + #define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius + + /** + * Whenever an M140 or M190 increases the target temperature the firmware will wait for the + * WATCH_BED_TEMP_PERIOD to expire, and if the temperature hasn't increased by WATCH_BED_TEMP_INCREASE + * degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190, + * but only if the current temperature is far enough below the target for a reliable test. + * + * If you get too many "Heating failed" errors, increase WATCH_BED_TEMP_PERIOD and/or decrease + * WATCH_BED_TEMP_INCREASE. (WATCH_BED_TEMP_INCREASE should not be below 2.) + */ + #define WATCH_BED_TEMP_PERIOD 60 // Seconds + #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius +#endif + +#if ENABLED(PIDTEMP) + // this adds an experimental additional term to the heating power, proportional to the extrusion speed. + // if Kc is chosen well, the additional required power due to increased melting should be compensated. + //#define PID_EXTRUSION_SCALING + #if ENABLED(PID_EXTRUSION_SCALING) + #define DEFAULT_Kc (100) //heating power=Kc*(e_speed) + #define LPQ_MAX_LEN 50 + #endif +#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 + */ +#define AUTOTEMP +#if ENABLED(AUTOTEMP) + #define AUTOTEMP_OLDWEIGHT 0.98 +#endif + +//Show Temperature ADC value +//The M105 command return, besides traditional information, the ADC value read from temperature sensors. +//#define SHOW_TEMP_ADC_VALUES + +/** + * High Temperature Thermistor Support + * + * Thermistors able to support high temperature tend to have a hard time getting + * good readings at room and lower temperatures. This means HEATER_X_RAW_LO_TEMP + * will probably be caught when the heating element first turns on during the + * preheating process, which will trigger a min_temp_error as a safety measure + * and force stop everything. + * To circumvent this limitation, we allow for a preheat time (during which, + * min_temp_error won't be triggered) and add a min_temp buffer to handle + * aberrant readings. + * + * If you want to enable this feature for your hotend thermistor(s) + * uncomment and set values > 0 in the constants below + */ + +// The number of consecutive low temperature errors that can occur +// before a min_temp_error is triggered. (Shouldn't be more than 10.) +//#define MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED 0 + +// The number of milliseconds a hotend will preheat before starting to check +// the temperature. This value should NOT be set to the time it takes the +// hot end to reach the target temperature, but the time it takes to reach +// the minimum temperature your thermistor can read. The lower the better/safer. +// This shouldn't need to be more than 30 seconds (30000) +//#define MILLISECONDS_PREHEAT_TIME 0 + +// @section extruder + +// extruder run-out prevention. +//if the machine is idle, and the temperature over MINTEMP, every couple of SECONDS some filament is extruded +#define EXTRUDER_RUNOUT_PREVENT +#define EXTRUDER_RUNOUT_MINTEMP 180 +#define EXTRUDER_RUNOUT_SECONDS 30 +#define EXTRUDER_RUNOUT_ESTEPS 14 // mm filament +#define EXTRUDER_RUNOUT_SPEED 1500 // extrusion speed +#define EXTRUDER_RUNOUT_EXTRUDE 100 + +// @section temperature + +//These defines help to calibrate the AD595 sensor in case you get wrong temperature measurements. +//The measured temperature is defined as "actualTemp = (measuredTemp * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET" +#define TEMP_SENSOR_AD595_OFFSET 0.0 +#define TEMP_SENSOR_AD595_GAIN 1.0 + +//This is for controlling a fan to cool down the stepper drivers +//it will turn on when any driver is enabled +//and turn off after the set amount of seconds from last driver being disabled again +#define CONTROLLERFAN_PIN -1 //Pin used for the fan to cool controller (-1 to disable) +#define CONTROLLERFAN_SECS 60 //How many seconds, after all motors were disabled, the fan should run +#define CONTROLLERFAN_SPEED 255 // == full speed + +// When first starting the main fan, run it at full speed for the +// given number of milliseconds. This gets the fan spinning reliably +// before setting a PWM value. (Does not work with software PWM for fan on Sanguinololu) +//#define FAN_KICKSTART_TIME 100 + +// This defines the minimal speed for the main fan, run in PWM mode +// to enable uncomment and set minimal PWM speed for reliable running (1-255) +// if fan speed is [1 - (FAN_MIN_PWM-1)] it is set to FAN_MIN_PWM +//#define FAN_MIN_PWM 50 + +// @section extruder + +// Extruder cooling fans +// Configure fan pin outputs to automatically turn on/off when the associated +// extruder temperature is above/below EXTRUDER_AUTO_FAN_TEMPERATURE. +// Multiple extruders can be assigned to the same pin in which case +// the fan will turn on when any selected extruder is above the threshold. +#define EXTRUDER_0_AUTO_FAN_PIN -1 +#define EXTRUDER_1_AUTO_FAN_PIN -1 +#define EXTRUDER_2_AUTO_FAN_PIN -1 +#define EXTRUDER_3_AUTO_FAN_PIN -1 +#define EXTRUDER_AUTO_FAN_TEMPERATURE 50 +#define EXTRUDER_AUTO_FAN_SPEED 255 // == full speed + +//=========================================================================== +//============================ Mechanical Settings ========================== +//=========================================================================== + +// @section homing + +// If you want endstops to stay on (by default) even when not homing +// enable this option. Override at any time with M120, M121. +//#define ENDSTOPS_ALWAYS_ON_DEFAULT + +// @section extras + +//#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. + +// Dual X Steppers +// Uncomment this option to drive two X axis motors. +// The next unused E driver will be assigned to the second X stepper. +//#define X_DUAL_STEPPER_DRIVERS +#if ENABLED(X_DUAL_STEPPER_DRIVERS) + // Set true if the two X motors need to rotate in opposite directions + #define INVERT_X2_VS_X_DIR true +#endif + + +// Dual Y Steppers +// Uncomment this option to drive two Y axis motors. +// The next unused E driver will be assigned to the second Y stepper. +//#define Y_DUAL_STEPPER_DRIVERS +#if ENABLED(Y_DUAL_STEPPER_DRIVERS) + // Set true if the two Y motors need to rotate in opposite directions + #define INVERT_Y2_VS_Y_DIR true +#endif + +// A single Z stepper driver is usually used to drive 2 stepper motors. +// Uncomment this option to use a separate stepper driver for each Z axis motor. +// The next unused E driver will be assigned to the second Z stepper. +//#define Z_DUAL_STEPPER_DRIVERS + +#if ENABLED(Z_DUAL_STEPPER_DRIVERS) + + // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper. + // That way the machine is capable to align the bed during home, since both Z steppers are homed. + // There is also an implementation of M666 (software endstops adjustment) to this feature. + // After Z homing, this adjustment is applied to just one of the steppers in order to align the bed. + // One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2. + // If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive. + // Play a little bit with small adjustments (0.5mm) and check the behaviour. + // The M119 (endstops report) will start reporting the Z2 Endstop as well. + + //#define Z_DUAL_ENDSTOPS + + #if ENABLED(Z_DUAL_ENDSTOPS) + #define Z2_USE_ENDSTOP _XMAX_ + #endif + +#endif // Z_DUAL_STEPPER_DRIVERS + +// Enable this for dual x-carriage printers. +// A dual x-carriage design has the advantage that the inactive extruder can be parked which +// prevents hot-end ooze contaminating the print. It also reduces the weight of each x-carriage +// allowing faster printing speeds. Connect your X2 stepper to the first unused E plug. +//#define DUAL_X_CARRIAGE +#if ENABLED(DUAL_X_CARRIAGE) + // Configuration for second X-carriage + // Note: the first x-carriage is defined as the x-carriage which homes to the minimum endstop; + // the second x-carriage always homes to the maximum endstop. + #define X2_MIN_POS 80 // set minimum to ensure second x-carriage doesn't hit the parked first X-carriage + #define X2_MAX_POS 353 // set maximum to the distance between toolheads when both heads are homed + #define X2_HOME_DIR 1 // the second X-carriage always homes to the maximum endstop position + #define X2_HOME_POS X2_MAX_POS // default home position is the maximum carriage position + // However: In this mode the HOTEND_OFFSET_X value for the second extruder provides a software + // override for X2_HOME_POS. This also allow recalibration of the distance between the two endstops + // without modifying the firmware (through the "M218 T1 X???" command). + // Remember: you should set the second extruder x-offset to 0 in your slicer. + + // There are a few selectable movement modes for dual x-carriages using M605 S + // Mode 0: Full control. The slicer has full control over both x-carriages and can achieve optimal travel results + // as long as it supports dual x-carriages. (M605 S0) + // Mode 1: Auto-park mode. The firmware will automatically park and unpark the x-carriages on tool changes so + // that additional slicer support is not required. (M605 S1) + // Mode 2: Duplication mode. The firmware will transparently make the second x-carriage and extruder copy all + // actions of the first x-carriage. This allows the printer to print 2 arbitrary items at + // once. (2nd extruder x offset and temp offset are set using: M605 S2 [Xnnn] [Rmmm]) + + // This is the default power-up mode which can be later using M605. + #define DEFAULT_DUAL_X_CARRIAGE_MODE 0 + + // Default settings in "Auto-park Mode" + #define TOOLCHANGE_PARK_ZLIFT 0.2 // the distance to raise Z axis when parking an extruder + #define TOOLCHANGE_UNPARK_ZLIFT 1 // the distance to raise Z axis when unparking an extruder + + // Default x offset in duplication mode (typically set to half print bed width) + #define DEFAULT_DUPLICATION_X_OFFSET 100 + +#endif //DUAL_X_CARRIAGE + +// @section homing + +//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: +#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 this is defined, if both x and y are to be homed, a diagonal move will be performed initially. + +// When G28 is called, this option will make Y home before X +//#define HOME_Y_BEFORE_X + +// @section machine + +#define AXIS_RELATIVE_MODES {false, false, false, false} + +// Allow duplication mode with a basic dual-nozzle extruder +//#define DUAL_NOZZLE_DUPLICATION_MODE + +// By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step. +#define INVERT_X_STEP_PIN false +#define INVERT_Y_STEP_PIN false +#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. +#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_E true + +#define DEFAULT_MINIMUMFEEDRATE 0.0 // minimum feedrate +#define DEFAULT_MINTRAVELFEEDRATE 0.0 + +// @section lcd + +#if ENABLED(ULTIPANEL) + #define MANUAL_FEEDRATE {50*60, 50*60, 4*60, 60} // Feedrates for manual moves along X, Y, Z, E from panel + #define ULTIPANEL_FEEDMULTIPLY // Comment to disable setting feedrate multiplier via encoder +#endif + +// @section extras + +// minimum time in microseconds that a movement needs to take if the buffer is emptied. +#define DEFAULT_MINSEGMENTTIME 20000 + +// If defined the movements slow down when the look ahead buffer is only half full +#define SLOWDOWN + +// Frequency limit +// See nophead's blog for more info +// Not working O +//#define XY_FREQUENCY_LIMIT 15 + +// 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 +// if unwanted behavior is observed on a user's machine when running at very slow speeds. +#define MINIMUM_PLANNER_SPEED 0.05// (mm/sec) + +// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU. +#define MICROSTEP_MODES {16,16,16,16,16} // [1,2,4,8,16] + +// Motor Current setting (Only functional when motor driver current ref pins are connected to a digital trimpot on supported boards) +#define DIGIPOT_MOTOR_CURRENT {135,135,135,135,135} // Values 0-255 (RAMBO 135 = ~0.75A, 185 = ~1A) + +// Motor Current controlled via PWM (Overridable on supported boards with PWM-driven motor driver current) +//#define PWM_MOTOR_CURRENT {1300, 1300, 1250} // Values in milliamps + +// uncomment to enable an I2C based DIGIPOT like on the Azteeg X3 Pro +//#define DIGIPOT_I2C +// Number of channels available for I2C digipot, For Azteeg X3 Pro we have 8 +#define DIGIPOT_I2C_NUM_CHANNELS 8 +// actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS +#define DIGIPOT_I2C_MOTOR_CURRENTS {1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0} + +//=========================================================================== +//=============================Additional Features=========================== +//=========================================================================== + +#define ENCODER_RATE_MULTIPLIER // If defined, certain menu edit operations automatically multiply the steps when the encoder is moved quickly +#define ENCODER_10X_STEPS_PER_SEC 75 // If the encoder steps per sec exceeds this value, multiply steps moved x10 to quickly advance the value +#define ENCODER_100X_STEPS_PER_SEC 160 // If the encoder steps per sec exceeds this value, multiply steps moved x100 to really quickly advance the value + +//#define CHDK 4 //Pin for triggering CHDK to take a picture see how to use it here http://captain-slow.dk/2014/03/09/3d-printing-timelapses/ +#define CHDK_DELAY 50 //How long in ms the pin should stay HIGH before going LOW again + +// @section lcd + +// Include a page of printer information in the LCD Main Menu +//#define LCD_INFO_MENU + +#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 + + #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? + #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. + + #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. + // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. + // using: + #define MENU_ADDAUTOSTART + + // Show a progress bar on HD44780 LCDs for SD printing + #define LCD_PROGRESS_BAR + + #if ENABLED(LCD_PROGRESS_BAR) + // Amount of time (ms) to show the bar + #define PROGRESS_BAR_BAR_TIME 2000 + // Amount of time (ms) to show the status message + #define PROGRESS_BAR_MSG_TIME 3000 + // Amount of time (ms) to retain the status message (0=forever) + #define PROGRESS_MSG_EXPIRE 0 + // Enable this to show messages for MSG_TIME then hide them + #define PROGRESS_MSG_ONCE + #endif + + // This allows hosts to request long names for files and folders with M33 + //#define LONG_FILENAME_HOST_SUPPORT + + // This option allows you to abort SD printing when any endstop is triggered. + // This feature must be enabled with "M540 S1" or from the LCD menu. + // To have any effect, endstops must be enabled during SD printing. + //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + +#endif // SDSUPPORT + +// for dogm lcd displays you can choose some additional fonts: +#if ENABLED(DOGLCD) + // save 3120 bytes of PROGMEM by commenting out #define USE_BIG_EDIT_FONT + // we don't have a big font for Cyrillic, Kana + //#define USE_BIG_EDIT_FONT + + // If you have spare 2300Byte of progmem and want to use a + // smaller font on the Info-screen uncomment the next line. + //#define USE_SMALL_INFOFONT +#endif // DOGLCD + +// @section safety + +// The hardware watchdog should reset the microcontroller disabling all outputs, +// in case the firmware gets stuck and doesn't do temperature regulation. +#define USE_WATCHDOG + +#if ENABLED(USE_WATCHDOG) + // If you have a watchdog reboot in an ArduinoMega2560 then the device will hang forever, as a watchdog reset will leave the watchdog on. + // The "WATCHDOG_RESET_MANUAL" goes around this by not using the hardware reset. + // However, THIS FEATURE IS UNSAFE!, as it will only work if interrupts are disabled. And the code could hang in an interrupt routine with interrupts disabled. + //#define WATCHDOG_RESET_MANUAL +#endif + +// @section lcd + +// Babystepping enables the user to control the axis in tiny amounts, independently from the normal printing process +// it can e.g. be used to change z-positions in the print startup phase in real-time +// does not respect endstops! +//#define BABYSTEPPING +#if ENABLED(BABYSTEPPING) + #define BABYSTEP_XY //not only z, but also XY in the menu. more clutter, more functions + //not implemented for deltabots! + #define BABYSTEP_INVERT_Z false //true for inverse movements in Z + #define BABYSTEP_MULTIPLICATOR 1 //faster movements +#endif + +// @section extruder + +// extruder advance constant (s2/mm3) +// +// advance (steps) = STEPS_PER_CUBIC_MM_E * EXTRUDER_ADVANCE_K * cubic mm per second ^ 2 +// +// Hooke's law says: force = k * distance +// Bernoulli's principle says: v ^ 2 / 2 + g . h + pressure / density = constant +// so: v ^ 2 is proportional to number of steps we advance the extruder +//#define ADVANCE + +#if ENABLED(ADVANCE) + #define EXTRUDER_ADVANCE_K .0 + #define D_FILAMENT 2.85 +#endif + +// Implementation of a linear pressure control +// Assumption: advance = k * (delta velocity) +// K=0 means advance disabled. A good value for a gregs wade extruder will be around K=75 +//#define LIN_ADVANCE + +#if ENABLED(LIN_ADVANCE) + #define LIN_ADVANCE_K 75 +#endif + +// @section leveling + +// Default mesh area is an area with an inset margin on the print area. +// Below are the macros that are used to define the borders for the mesh area, +// made available here for specialized needs, ie dual extruder setup. +#if ENABLED(MESH_BED_LEVELING) + #define MESH_MIN_X (X_MIN_POS + MESH_INSET) + #define MESH_MAX_X (X_MAX_POS - (MESH_INSET)) + #define MESH_MIN_Y (Y_MIN_POS + MESH_INSET) + #define MESH_MAX_Y (Y_MAX_POS - (MESH_INSET)) +#endif + +// @section extras + +// Arc interpretation settings: +#define ARC_SUPPORT // Disabling this saves ~2738 bytes +#define MM_PER_ARC_SEGMENT 1 +#define N_ARC_CORRECTION 25 + +// Support for G5 with XYZE destination and IJPQ offsets. Requires ~2666 bytes. +//#define BEZIER_CURVE_SUPPORT + +const unsigned int dropsegments = 5; //everything with less than this number of steps will be ignored as move and joined with the next movement + +// @section temperature + +// Control heater 0 and heater 1 in parallel. +//#define HEATERS_PARALLEL + +//=========================================================================== +//================================= Buffers ================================= +//=========================================================================== + +// @section hidden + +// 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, i.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 +#else + #define BLOCK_BUFFER_SIZE 16 // maximize block buffer +#endif + +// @section serial + +// The ASCII buffer for serial input +#define MAX_CMD_SIZE 96 +#define BUFSIZE 26 + +// Transfer Buffer Size +// To save 386 bytes of PROGMEM (and TX_BUFFER_SIZE+3 bytes of RAM) set to 0. +// To buffer a simple "ok" you need 4 bytes. +// For ADVANCED_OK (M105) you need 32 bytes. +// For debug-echo: 128 bytes for the optimal speed. +// Other output doesn't need to be that speedy. +// :[0,2,4,8,16,32,64,128,256] +#define TX_BUFFER_SIZE 0 + +// 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! +//#define EMERGENCY_PARSER + +// Bad Serial-connections can miss a received command by sending an 'ok' +// Therefore some clients abort after 30 seconds in a timeout. +// Some other clients start sending commands while receiving a 'wait'. +// This "wait" is only sent when the buffer is empty. 1 second is a good value here. +//#define NO_TIMEOUTS 1000 // Milliseconds + +// Some clients will have this feature soon. This could make the NO_TIMEOUTS unnecessary. +//#define ADVANCED_OK + +// @section fwretract + +// Firmware based and LCD controlled retract +// M207 and M208 can be used to define parameters for the retraction. +// The retraction can be called by the slicer using G10 and G11 +// until then, intended retractions can be detected by moves that only extrude and the direction. +// the moves are than replaced by the firmware controlled ones. + +//#define FWRETRACT //ONLY PARTIALLY TESTED +#if ENABLED(FWRETRACT) + #define MIN_RETRACT 0.1 //minimum extruded mm to accept a automatic gcode retraction attempt + #define RETRACT_LENGTH 3 //default retract length (positive mm) + #define RETRACT_LENGTH_SWAP 13 //default swap retract length (positive mm), for extruder change + #define RETRACT_FEEDRATE 45 //default feedrate for retracting (mm/s) + #define RETRACT_ZLIFT 0 //default retract Z-lift + #define RETRACT_RECOVER_LENGTH 0 //default additional recover length (mm, added to retract length when recovering) + #define RETRACT_RECOVER_LENGTH_SWAP 0 //default additional swap recover length (mm, added to retract length when recovering from extruder change) + #define RETRACT_RECOVER_FEEDRATE 8 //default feedrate for recovering from retraction (mm/s) +#endif + +// Add support for experimental filament exchange support M600; requires display +#if ENABLED(ULTIPANEL) + // #define FILAMENT_CHANGE_FEATURE // Enable filament exchange menu and M600 g-code (used for runout sensor too) + #if ENABLED(FILAMENT_CHANGE_FEATURE) + #define FILAMENT_CHANGE_X_POS 3 // X position of hotend + #define FILAMENT_CHANGE_Y_POS 3 // Y position of hotend + #define FILAMENT_CHANGE_Z_ADD 10 // Z addition of hotend (lift) + #define FILAMENT_CHANGE_XY_FEEDRATE 100 // X and Y axes feedrate in mm/s (also used for delta printers Z axis) + #define FILAMENT_CHANGE_Z_FEEDRATE 5 // Z axis feedrate in mm/s (not used for delta printers) + #define FILAMENT_CHANGE_RETRACT_LENGTH 2 // Initial retract in mm + // It is a short retract used immediately after print interrupt before move to filament exchange position + #define FILAMENT_CHANGE_RETRACT_FEEDRATE 60 // Initial retract feedrate in mm/s + #define FILAMENT_CHANGE_UNLOAD_LENGTH 100 // Unload filament length from hotend in mm + // Longer length for bowden printers to unload filament from whole bowden tube, + // shorter lenght for printers without bowden to unload filament from extruder only, + // 0 to disable unloading for manual unloading + #define FILAMENT_CHANGE_UNLOAD_FEEDRATE 10 // Unload filament feedrate in mm/s - filament unloading can be fast + #define FILAMENT_CHANGE_LOAD_LENGTH 0 // Load filament length over hotend in mm + // Longer length for bowden printers to fast load filament into whole bowden tube over the hotend, + // Short or zero length for printers without bowden where loading is not used + #define FILAMENT_CHANGE_LOAD_FEEDRATE 10 // Load filament feedrate in mm/s - filament loading into the bowden tube can be fast + #define FILAMENT_CHANGE_EXTRUDE_LENGTH 50 // Extrude filament length in mm after filament is load over the hotend, + // 0 to disable for manual extrusion + // Filament can be extruded repeatedly from the filament exchange menu to fill the hotend, + // or until outcoming filament color is not clear for filament color change + #define FILAMENT_CHANGE_EXTRUDE_FEEDRATE 3 // Extrude filament feedrate in mm/s - must be slower than load feedrate + #endif +#endif + +/******************************************************************************\ + * enable this section if you have TMC26X motor drivers. + * you need to import the TMC26XStepper library into the Arduino IDE for this + ******************************************************************************/ + +// @section tmc + +//#define HAVE_TMCDRIVER +#if ENABLED(HAVE_TMCDRIVER) + + //#define X_IS_TMC + #define X_MAX_CURRENT 1000 //in mA + #define X_SENSE_RESISTOR 91 //in mOhms + #define X_MICROSTEPS 16 //number of microsteps + + //#define X2_IS_TMC + #define X2_MAX_CURRENT 1000 //in mA + #define X2_SENSE_RESISTOR 91 //in mOhms + #define X2_MICROSTEPS 16 //number of microsteps + + //#define Y_IS_TMC + #define Y_MAX_CURRENT 1000 //in mA + #define Y_SENSE_RESISTOR 91 //in mOhms + #define Y_MICROSTEPS 16 //number of microsteps + + //#define Y2_IS_TMC + #define Y2_MAX_CURRENT 1000 //in mA + #define Y2_SENSE_RESISTOR 91 //in mOhms + #define Y2_MICROSTEPS 16 //number of microsteps + + //#define Z_IS_TMC + #define Z_MAX_CURRENT 1000 //in mA + #define Z_SENSE_RESISTOR 91 //in mOhms + #define Z_MICROSTEPS 16 //number of microsteps + + //#define Z2_IS_TMC + #define Z2_MAX_CURRENT 1000 //in mA + #define Z2_SENSE_RESISTOR 91 //in mOhms + #define Z2_MICROSTEPS 16 //number of microsteps + + //#define E0_IS_TMC + #define E0_MAX_CURRENT 1000 //in mA + #define E0_SENSE_RESISTOR 91 //in mOhms + #define E0_MICROSTEPS 16 //number of microsteps + + //#define E1_IS_TMC + #define E1_MAX_CURRENT 1000 //in mA + #define E1_SENSE_RESISTOR 91 //in mOhms + #define E1_MICROSTEPS 16 //number of microsteps + + //#define E2_IS_TMC + #define E2_MAX_CURRENT 1000 //in mA + #define E2_SENSE_RESISTOR 91 //in mOhms + #define E2_MICROSTEPS 16 //number of microsteps + + //#define E3_IS_TMC + #define E3_MAX_CURRENT 1000 //in mA + #define E3_SENSE_RESISTOR 91 //in mOhms + #define E3_MICROSTEPS 16 //number of microsteps + +#endif + +/******************************************************************************\ + * enable this section if you have L6470 motor drivers. + * you need to import the L6470 library into the Arduino IDE for this + ******************************************************************************/ + +// @section l6470 + +//#define HAVE_L6470DRIVER +#if ENABLED(HAVE_L6470DRIVER) + + //#define X_IS_L6470 + #define X_MICROSTEPS 16 //number of microsteps + #define X_K_VAL 50 // 0 - 255, Higher values, are higher power. Be careful not to go too high + #define X_OVERCURRENT 2000 //maxc current in mA. If the current goes over this value, the driver will switch off + #define X_STALLCURRENT 1500 //current in mA where the driver will detect a stall + + //#define X2_IS_L6470 + #define X2_MICROSTEPS 16 //number of microsteps + #define X2_K_VAL 50 // 0 - 255, Higher values, are higher power. Be careful not to go too high + #define X2_OVERCURRENT 2000 //maxc current in mA. If the current goes over this value, the driver will switch off + #define X2_STALLCURRENT 1500 //current in mA where the driver will detect a stall + + //#define Y_IS_L6470 + #define Y_MICROSTEPS 16 //number of microsteps + #define Y_K_VAL 50 // 0 - 255, Higher values, are higher power. Be careful not to go too high + #define Y_OVERCURRENT 2000 //maxc current in mA. If the current goes over this value, the driver will switch off + #define Y_STALLCURRENT 1500 //current in mA where the driver will detect a stall + + //#define Y2_IS_L6470 + #define Y2_MICROSTEPS 16 //number of microsteps + #define Y2_K_VAL 50 // 0 - 255, Higher values, are higher power. Be careful not to go too high + #define Y2_OVERCURRENT 2000 //maxc current in mA. If the current goes over this value, the driver will switch off + #define Y2_STALLCURRENT 1500 //current in mA where the driver will detect a stall + + //#define Z_IS_L6470 + #define Z_MICROSTEPS 16 //number of microsteps + #define Z_K_VAL 50 // 0 - 255, Higher values, are higher power. Be careful not to go too high + #define Z_OVERCURRENT 2000 //maxc current in mA. If the current goes over this value, the driver will switch off + #define Z_STALLCURRENT 1500 //current in mA where the driver will detect a stall + + //#define Z2_IS_L6470 + #define Z2_MICROSTEPS 16 //number of microsteps + #define Z2_K_VAL 50 // 0 - 255, Higher values, are higher power. Be careful not to go too high + #define Z2_OVERCURRENT 2000 //maxc current in mA. If the current goes over this value, the driver will switch off + #define Z2_STALLCURRENT 1500 //current in mA where the driver will detect a stall + + //#define E0_IS_L6470 + #define E0_MICROSTEPS 16 //number of microsteps + #define E0_K_VAL 50 // 0 - 255, Higher values, are higher power. Be careful not to go too high + #define E0_OVERCURRENT 2000 //maxc current in mA. If the current goes over this value, the driver will switch off + #define E0_STALLCURRENT 1500 //current in mA where the driver will detect a stall + + //#define E1_IS_L6470 + #define E1_MICROSTEPS 16 //number of microsteps + #define E1_K_VAL 50 // 0 - 255, Higher values, are higher power. Be careful not to go too high + #define E1_OVERCURRENT 2000 //maxc current in mA. If the current goes over this value, the driver will switch off + #define E1_STALLCURRENT 1500 //current in mA where the driver will detect a stall + + //#define E2_IS_L6470 + #define E2_MICROSTEPS 16 //number of microsteps + #define E2_K_VAL 50 // 0 - 255, Higher values, are higher power. Be careful not to go too high + #define E2_OVERCURRENT 2000 //maxc current in mA. If the current goes over this value, the driver will switch off + #define E2_STALLCURRENT 1500 //current in mA where the driver will detect a stall + + //#define E3_IS_L6470 + #define E3_MICROSTEPS 16 //number of microsteps + #define E3_K_VAL 50 // 0 - 255, Higher values, are higher power. Be careful not to go too high + #define E3_OVERCURRENT 2000 //maxc current in mA. If the current goes over this value, the driver will switch off + #define E3_STALLCURRENT 1500 //current in mA where the driver will detect a stall + +#endif + +/** + * TWI/I2C BUS + * + * This feature is an EXPERIMENTAL feature so it shall not be used on production + * machines. Enabling this will allow you to send and receive I2C data from slave + * devices on the bus. + * + * ; Example #1 + * ; This macro send the string "Marlin" to the slave device with address 0x63 (99) + * ; It uses multiple M155 commands with one B arg + * M155 A99 ; Target slave address + * M155 B77 ; M + * M155 B97 ; a + * M155 B114 ; r + * M155 B108 ; l + * M155 B105 ; i + * M155 B110 ; n + * M155 S1 ; Send the current buffer + * + * ; Example #2 + * ; Request 6 bytes from slave device with address 0x63 (99) + * M156 A99 B5 + * + * ; Example #3 + * ; Example serial output of a M156 request + * echo:i2c-reply: from:99 bytes:5 data:hello + */ + +// @section i2cbus + +//#define EXPERIMENTAL_I2CBUS + +#endif // CONFIGURATION_ADV_H diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/M100_Free_Mem_Chk.cpp b/trunk/Arduino/Marlin_K8600_1.1.0RC7/M100_Free_Mem_Chk.cpp new file mode 100644 index 00000000..82689465 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/M100_Free_Mem_Chk.cpp @@ -0,0 +1,248 @@ +/** + * 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 . + * + */ + +/** + * M100 Free Memory Watcher + * + * This code watches the free memory block between the bottom of the heap and the top of the stack. + * This memory block is initialized and watched via the M100 command. + * + * M100 I Initializes the free memory block and prints vitals statistics about the area + * M100 F Identifies how much of the free memory block remains free and unused. It also + * detects and reports any corruption within the free memory block that may have + * happened due to errant firmware. + * M100 D Does a hex display of the free memory block along with a flag for any errant + * data that does not match the expected value. + * M100 C x Corrupts x locations within the free memory block. This is useful to check the + * correctness of the M100 F and M100 D commands. + * + * Initial version by Roxy-3DPrintBoard + */ +#define M100_FREE_MEMORY_DUMPER // Comment out to remove Dump sub-command +#define M100_FREE_MEMORY_CORRUPTOR // Comment out to remove Corrupt sub-command + +#include "Marlin.h" + +#if ENABLED(M100_FREE_MEMORY_WATCHER) +extern char* __brkval; +extern size_t __heap_start, __heap_end, __flp; +extern char __bss_end; + +// +// Utility functions used by M100 to get its work done. +// + +char* top_of_stack(); +void prt_hex_nibble(unsigned int); +void prt_hex_byte(unsigned int); +void prt_hex_word(unsigned int); +int how_many_E5s_are_here(char*); + +void gcode_M100() { + static bool m100_not_initialized = true; + char* sp, *ptr; + int i, j, n; + // + // M100 D dumps the free memory block from __brkval to the stack pointer. + // malloc() eats memory from the start of the block and the stack grows + // up from the bottom of the block. Solid 0xE5's indicate nothing has + // used that memory yet. There should not be anything but 0xE5's within + // the block of 0xE5's. If there is, that would indicate memory corruption + // probably caused by bad pointers. Any unexpected values will be flagged in + // the right hand column to help spotting them. + // + #if ENABLED(M100_FREE_MEMORY_DUMPER) // Disable to remove Dump sub-command + if (code_seen('D')) { + ptr = __brkval ? __brkval : &__bss_end; + // + // We want to start and end the dump on a nice 16 byte boundry even though + // the values we are using are not 16 byte aligned. + // + SERIAL_ECHOPGM("\nbss_end : "); + prt_hex_word((unsigned int) ptr); + ptr = (char*)((unsigned long) ptr & 0xfff0); + sp = top_of_stack(); + SERIAL_ECHOPGM("\nStack Pointer : "); + prt_hex_word((unsigned int) sp); + SERIAL_EOL; + sp = (char*)((unsigned long) sp | 0x000f); + n = sp - ptr; + // + // This is the main loop of the Dump command. + // + while (ptr < sp) { + prt_hex_word((unsigned int) ptr); // Print the address + SERIAL_CHAR(':'); + for (i = 0; i < 16; i++) { // and 16 data bytes + prt_hex_byte(*(ptr + i)); + SERIAL_CHAR(' '); + } + SERIAL_CHAR('|'); // now show where non 0xE5's are + for (i = 0; i < 16; i++) { + if (*(ptr + i) == (char)0xe5) + SERIAL_CHAR(' '); + else + SERIAL_CHAR('?'); + } + SERIAL_EOL; + ptr += 16; + } + return; + } + #endif + // + // M100 F requests the code to return the number of free bytes in the memory pool along with + // other vital statistics that define the memory pool. + // + if (code_seen('F')) { + #if 0 + int max_addr = (int) __brkval ? __brkval : &__bss_end; + int max_cnt = 0; + #endif + int block_cnt = 0; + ptr = __brkval ? __brkval : &__bss_end; + sp = top_of_stack(); + n = sp - ptr; + // Scan through the range looking for the biggest block of 0xE5's we can find + for (i = 0; i < n; i++) { + if (*(ptr + i) == (char)0xe5) { + j = how_many_E5s_are_here(ptr + i); + if (j > 8) { + SERIAL_ECHOPAIR("Found ", j); + SERIAL_ECHOPGM(" bytes free at 0x"); + prt_hex_word((int) ptr + i); + SERIAL_EOL; + i += j; + block_cnt++; + } + #if 0 + if (j > max_cnt) { // We don't do anything with this information yet + max_cnt = j; // but we do know where the biggest free memory block is. + max_addr = (int) ptr + i; + } + #endif + } + } + if (block_cnt > 1) + SERIAL_ECHOLNPGM("\nMemory Corruption detected in free memory area."); + return; + } + // + // M100 C x Corrupts x locations in the free memory pool and reports the locations of the corruption. + // This is useful to check the correctness of the M100 D and the M100 F commands. + // + #if ENABLED(M100_FREE_MEMORY_CORRUPTOR) + if (code_seen('C')) { + int x = code_value_int(); // x gets the # of locations to corrupt within the memory pool + SERIAL_ECHOLNPGM("Corrupting free memory block.\n"); + ptr = __brkval ? __brkval : &__bss_end; + SERIAL_ECHOPAIR("\nbss_end : ", ptr); + ptr += 8; + sp = top_of_stack(); + SERIAL_ECHOPAIR("\nStack Pointer : ", sp); + SERIAL_ECHOLNPGM("\n"); + n = sp - ptr - 64; // -64 just to keep us from finding interrupt activity that + // has altered the stack. + j = n / (x + 1); + for (i = 1; i <= x; i++) { + *(ptr + (i * j)) = i; + SERIAL_ECHOPGM("\nCorrupting address: 0x"); + prt_hex_word((unsigned int)(ptr + (i * j))); + } + SERIAL_ECHOLNPGM("\n"); + return; + } + #endif + // + // M100 I Initializes the free memory pool so it can be watched and prints vital + // statistics that define the free memory pool. + // + if (m100_not_initialized || code_seen('I')) { // If no sub-command is specified, the first time + SERIAL_ECHOLNPGM("Initializing free memory block.\n"); // this happens, it will Initialize. + ptr = __brkval ? __brkval : &__bss_end; // Repeated M100 with no sub-command will not destroy the + SERIAL_ECHOPAIR("\nbss_end : ", ptr); // state of the initialized free memory pool. + ptr += 8; + sp = top_of_stack(); + SERIAL_ECHOPAIR("\nStack Pointer : ", sp); + SERIAL_ECHOLNPGM("\n"); + n = sp - ptr - 64; // -64 just to keep us from finding interrupt activity that + // has altered the stack. + SERIAL_ECHO(n); + SERIAL_ECHOLNPGM(" bytes of memory initialized.\n"); + for (i = 0; i < n; i++) + *(ptr + i) = (char)0xe5; + for (i = 0; i < n; i++) { + if (*(ptr + i) != (char)0xe5) { + SERIAL_ECHOPAIR("? address : ", ptr + i); + SERIAL_ECHOPAIR("=", *(ptr + i)); + SERIAL_ECHOLNPGM("\n"); + } + } + m100_not_initialized = false; + return; + } + return; +} + +// top_of_stack() returns the location of a variable on its stack frame. The value returned is above +// the stack once the function returns to the caller. + +char* top_of_stack() { + char x; + return &x + 1; // x is pulled on return; +} + +// +// 3 support routines to print hex numbers. We can print a nibble, byte and word +// + +void prt_hex_nibble(unsigned int n) { + if (n <= 9) + SERIAL_ECHO(n); + else + SERIAL_ECHO((char)('A' + n - 10)); +} + +void prt_hex_byte(unsigned int b) { + prt_hex_nibble((b & 0xf0) >> 4); + prt_hex_nibble(b & 0x0f); +} + +void prt_hex_word(unsigned int w) { + prt_hex_byte((w & 0xff00) >> 8); + prt_hex_byte(w & 0x0ff); +} + +// how_many_E5s_are_here() is a utility function to easily find out how many 0xE5's are +// at the specified location. Having this logic as a function simplifies the search code. +// +int how_many_E5s_are_here(char* p) { + int n; + for (n = 0; n < 32000; n++) { + if (*(p + n) != (char)0xe5) + return n - 1; + } + return -1; +} + +#endif + diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/Makefile b/trunk/Arduino/Marlin_K8600_1.1.0RC7/Makefile new file mode 100644 index 00000000..13280535 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/Makefile @@ -0,0 +1,521 @@ +# Sprinter Arduino Project Makefile +# +# Makefile Based on: +# Arduino 0011 Makefile +# Arduino adaptation by mellis, eighthave, oli.keller +# Marlin adaption by Daid +# +# This has been tested with Arduino 0022. +# +# This makefile allows you to build sketches from the command line +# without the Arduino environment (or Java). +# +# 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 +# might be /Applications/Arduino.app/Contents/Resources/Java). +# +# 2. Modify the line containing "UPLOAD_PORT" to refer to the filename +# representing the USB or serial connection to your Arduino board +# (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 +# 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 +# the speed lookup table with create_speed_lookuptable.py. +# +# 4. Type "make" and press enter to compile/verify your program. +# +# 5. Type "make upload", reset your Arduino board, and press enter to +# upload your program to the Arduino board. +# +# Note that all settings are set with ?=, this means you can override them +# from the commandline with "make HARDWARE_MOTHERBOARD=71" for example + +# This defined the board you are compiling for (see boards.h for the options) +HARDWARE_MOTHERBOARD ?= 11 + +# Arduino source install directory, and version number +# On most linuxes this will be /usr/share/arduino +ARDUINO_INSTALL_DIR ?= ${HOME}/Arduino +ARDUINO_VERSION ?= 106 + +# You can optionally set a path to the avr-gcc tools. Requires a trailing slash. (ex: /usr/local/avr-gcc/bin) +AVR_TOOLS_PATH ?= + +#Programmer configuration +UPLOAD_RATE ?= 57600 +AVRDUDE_PROGRAMMER ?= arduino +# 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 . +BUILD_DIR ?= applet + +# This defines whether Liquid_TWI2 support will be built +LIQUID_TWI2 ?= 0 + +# this defines if Wire is needed +WIRE ?= 0 + +############################################################################ +# Below here nothing should be changed... + +# Here the Arduino variant is selected by the board type +# HARDWARE_VARIANT = "arduino", "Sanguino", "Gen7", ... +# MCU = "atmega1280", "Mega2560", "atmega2560", "atmega644p", ... + +#Gen7 +ifeq ($(HARDWARE_MOTHERBOARD),10) +HARDWARE_VARIANT ?= Gen7 +MCU ?= atmega644 +F_CPU ?= 20000000 +else ifeq ($(HARDWARE_MOTHERBOARD),11) +HARDWARE_VARIANT ?= Gen7 +MCU ?= atmega644p +F_CPU ?= 20000000 +else ifeq ($(HARDWARE_MOTHERBOARD),12) +HARDWARE_VARIANT ?= Gen7 +MCU ?= atmega644p +F_CPU ?= 20000000 +else ifeq ($(HARDWARE_MOTHERBOARD),13) +HARDWARE_VARIANT ?= Gen7 +MCU ?= atmega1284p +F_CPU ?= 20000000 + +#RAMPS +else ifeq ($(HARDWARE_MOTHERBOARD),3) +HARDWARE_VARIANT ?= arduino +MCU ?= atmega2560 +else ifeq ($(HARDWARE_MOTHERBOARD),33) +HARDWARE_VARIANT ?= arduino +MCU ?= atmega2560 +else ifeq ($(HARDWARE_MOTHERBOARD),34) +HARDWARE_VARIANT ?= arduino +MCU ?= atmega2560 +else ifeq ($(HARDWARE_MOTHERBOARD),35) +HARDWARE_VARIANT ?= arduino +MCU ?= atmega2560 +else ifeq ($(HARDWARE_MOTHERBOARD),36) +HARDWARE_VARIANT ?= arduino +MCU ?= atmega2560 +else ifeq ($(HARDWARE_MOTHERBOARD),38) +HARDWARE_VARIANT ?= arduino +MCU ?= atmega2560 +else ifeq ($(HARDWARE_MOTHERBOARD),43) +HARDWARE_VARIANT ?= arduino +MCU ?= atmega2560 +else ifeq ($(HARDWARE_MOTHERBOARD),44) +HARDWARE_VARIANT ?= arduino +MCU ?= atmega2560 +else ifeq ($(HARDWARE_MOTHERBOARD),45) +HARDWARE_VARIANT ?= arduino +MCU ?= atmega2560 +else ifeq ($(HARDWARE_MOTHERBOARD),46) +HARDWARE_VARIANT ?= arduino +MCU ?= atmega2560 +else ifeq ($(HARDWARE_MOTHERBOARD),48) +HARDWARE_VARIANT ?= arduino +MCU ?= atmega2560 + +#Gen6 +else ifeq ($(HARDWARE_MOTHERBOARD),5) +HARDWARE_VARIANT ?= Gen6 +MCU ?= atmega644p +else ifeq ($(HARDWARE_MOTHERBOARD),51) +HARDWARE_VARIANT ?= Gen6 +MCU ?= atmega644p + +#Sanguinololu +else ifeq ($(HARDWARE_MOTHERBOARD),6) +HARDWARE_VARIANT ?= Sanguino +MCU ?= atmega644p +else ifeq ($(HARDWARE_MOTHERBOARD),62) +HARDWARE_VARIANT ?= Sanguino +MCU ?= atmega644p +else ifeq ($(HARDWARE_MOTHERBOARD),63) +HARDWARE_VARIANT ?= Sanguino +MCU ?= atmega644p +else ifeq ($(HARDWARE_MOTHERBOARD),65) +HARDWARE_VARIANT ?= Sanguino +MCU ?= atmega1284p +else ifeq ($(HARDWARE_MOTHERBOARD),66) +HARDWARE_VARIANT ?= Sanguino +MCU ?= atmega1284p +else ifeq ($(HARDWARE_MOTHERBOARD),69) +HARDWARE_VARIANT ?= Sanguino +MCU ?= atmega1284p + +#Ultimaker +else ifeq ($(HARDWARE_MOTHERBOARD),7) +HARDWARE_VARIANT ?= arduino +MCU ?= atmega2560 +else ifeq ($(HARDWARE_MOTHERBOARD),71) +HARDWARE_VARIANT ?= arduino +MCU ?= atmega1280 + +#Teensylu +else ifeq ($(HARDWARE_MOTHERBOARD),8) +HARDWARE_VARIANT ?= Teensy +MCU ?= at90usb1286 +else ifeq ($(HARDWARE_MOTHERBOARD),81) +HARDWARE_VARIANT ?= Teensy +MCU ?= at90usb1286 +else ifeq ($(HARDWARE_MOTHERBOARD),811) +HARDWARE_VARIANT ?= Teensy +MCU ?= at90usb1286 +else ifeq ($(HARDWARE_MOTHERBOARD),82) +HARDWARE_VARIANT ?= Teensy +MCU ?= at90usb646 +else ifeq ($(HARDWARE_MOTHERBOARD),83) +HARDWARE_VARIANT ?= Teensy +MCU ?= at90usb1286 +else ifeq ($(HARDWARE_MOTHERBOARD),84) +HARDWARE_VARIANT ?= Teensy +MCU ?= at90usb1286 + +#Gen3+ +else ifeq ($(HARDWARE_MOTHERBOARD),9) +HARDWARE_VARIANT ?= Sanguino +MCU ?= atmega644p + +#Gen3 Monolithic Electronics +else ifeq ($(HARDWARE_MOTHERBOARD),22) +HARDWARE_VARIANT ?= Sanguino +MCU ?= atmega644p + +#Megatronics +else ifeq ($(HARDWARE_MOTHERBOARD),70) +HARDWARE_VARIANT ?= arduino +MCU ?= atmega2560 + +#Alpha OMCA board +else ifeq ($(HARDWARE_MOTHERBOARD),90) +HARDWARE_VARIANT ?= SanguinoA +MCU ?= atmega644 + +#Final OMCA board +else ifeq ($(HARDWARE_MOTHERBOARD),91) +HARDWARE_VARIANT ?= Sanguino +MCU ?= atmega644p + +#Rambo +else ifeq ($(HARDWARE_MOTHERBOARD),301) +HARDWARE_VARIANT ?= arduino +MCU ?= atmega2560 + +# Azteeg +else ifeq ($(HARDWARE_MOTHERBOARD),67) +HARDWARE_VARIANT ?= arduino +MCU ?= atmega2560 +else ifeq ($(HARDWARE_MOTHERBOARD),68) +HARDWARE_VARIANT ?= arduino +MCU ?= atmega2560 + +endif + +# Be sure to regenerate speed_lookuptable.h with create_speed_lookuptable.py +# if you are setting this to something other than 16MHz +# Set to 16Mhz if not yet set. +F_CPU ?= 16000000 + +# Arduino contained the main source code for the Arduino +# Libraries, the "hardware variant" are for boards +# that derives from that, and their source are present in +# the main Marlin source directory +ifeq ($(HARDWARE_VARIANT), $(filter $(HARDWARE_VARIANT),arduino Sanguino)) +HARDWARE_DIR = $(ARDUINO_INSTALL_DIR)/hardware +else +ifeq ($(shell [ $(ARDUINO_VERSION) -ge 100 ] && echo true), true) +HARDWARE_DIR = ../ArduinoAddons/Arduino_1.x.x +else +HARDWARE_DIR = ../ArduinoAddons/Arduino_0.xx +endif +endif +HARDWARE_SRC = $(HARDWARE_DIR)/marlin/avr/cores/arduino + +TARGET = $(notdir $(CURDIR)) + +# VPATH tells make to look into these directory for source files, +# there is no need to specify explicit pathnames as long as the +# directory is added here + +VPATH = . +VPATH += $(BUILD_DIR) +VPATH += $(HARDWARE_SRC) +ifeq ($(HARDWARE_VARIANT), $(filter $(HARDWARE_VARIANT),arduino Teensy Sanguino)) +VPATH += $(HARDWARE_DIR)/marlin/avr/libraries/LiquidCrystal/src +VPATH += $(HARDWARE_DIR)/marlin/avr/libraries/SPI +ifeq ($(LIQUID_TWI2), 1) +VPATH += $(ARDUINO_INSTALL_DIR)/libraries/Wire +VPATH += $(ARDUINO_INSTALL_DIR)/libraries/Wire/utility +VPATH += $(ARDUINO_INSTALL_DIR)/libraries/LiquidTWI2 +endif +ifeq ($(WIRE), 1) +VPATH += $(ARDUINO_INSTALL_DIR)/libraries/Wire +VPATH += $(ARDUINO_INSTALL_DIR)/libraries/Wire/utility +endif +else +VPATH += $(HARDWARE_DIR)/libraries/LiquidCrystal +VPATH += $(HARDWARE_DIR)/libraries/SPI +ifeq ($(LIQUID_TWI2), 1) +VPATH += $(HARDWARE_DIR)/libraries/Wire +VPATH += $(HARDWARE_DIR)/libraries/Wire/utility +VPATH += $(HARDWARE_DIR)/libraries/LiquidTWI2 +endif +ifeq ($(WIRE), 1) +VPATH += $(HARDWARE_DIR)/libraries/Wire +VPATH += $(HARDWARE_DIR)/libraries/Wire/utility +endif +endif +ifeq ($(HARDWARE_VARIANT), arduino) +HARDWARE_SUB_VARIANT ?= mega +VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/variants/$(HARDWARE_SUB_VARIANT) +else +ifeq ($(HARDWARE_VARIANT), Sanguino) +VPATH += $(HARDWARE_DIR)/marlin/avr/variants/sanguino +else +HARDWARE_SUB_VARIANT ?= standard +VPATH += $(HARDWARE_DIR)/$(HARDWARE_VARIANT)/variants/$(HARDWARE_SUB_VARIANT) +endif +endif +SRC = wiring.c \ + wiring_analog.c wiring_digital.c \ + wiring_pulse.c \ + wiring_shift.c WInterrupts.c hooks.c +ifeq ($(HARDWARE_VARIANT), Teensy) +SRC = wiring.c +VPATH += $(ARDUINO_INSTALL_DIR)/hardware/teensy/cores/teensy +endif +CXXSRC = WMath.cpp WString.cpp Print.cpp Marlin_main.cpp \ + MarlinSerial.cpp Sd2Card.cpp SdBaseFile.cpp SdFatUtil.cpp \ + SdFile.cpp SdVolume.cpp planner.cpp stepper.cpp \ + temperature.cpp cardreader.cpp configuration_store.cpp \ + watchdog.cpp SPI.cpp servo.cpp Tone.cpp ultralcd.cpp digipot_mcp4451.cpp \ + dac_mcp4728.cpp vector_3.cpp qr_solve.cpp buzzer.cpp +ifeq ($(LIQUID_TWI2), 0) +CXXSRC += LiquidCrystal.cpp +else +SRC += twi.c +CXXSRC += Wire.cpp LiquidTWI2.cpp +endif + +ifeq ($(WIRE), 1) +SRC += twi.c +CXXSRC += Wire.cpp +endif + +#Check for Arduino 1.0.0 or higher and use the correct source files for that version +ifeq ($(shell [ $(ARDUINO_VERSION) -ge 100 ] && echo true), true) +CXXSRC += main.cpp +else +SRC += pins_arduino.c main.c +endif + +FORMAT = ihex + +# Name of this Makefile (used for "make depend"). +MAKEFILE = Makefile + +# Debugging format. +# Native formats for AVR-GCC's -g are stabs [default], or dwarf-2. +# AVR (extended) COFF requires stabs, plus an avr-objcopy run. +DEBUG = stabs + +OPT = s + +DEFINES ?= + +# Program settings +CC = $(AVR_TOOLS_PATH)avr-gcc +CXX = $(AVR_TOOLS_PATH)avr-g++ +OBJCOPY = $(AVR_TOOLS_PATH)avr-objcopy +OBJDUMP = $(AVR_TOOLS_PATH)avr-objdump +AR = $(AVR_TOOLS_PATH)avr-ar +SIZE = $(AVR_TOOLS_PATH)avr-size +NM = $(AVR_TOOLS_PATH)avr-nm +AVRDUDE = avrdude +REMOVE = rm -f +MV = mv -f + +# Place -D or -U options here +CDEFS = -DF_CPU=$(F_CPU) ${addprefix -D , $(DEFINES)} +CXXDEFS = $(CDEFS) + +ifeq ($(HARDWARE_VARIANT), Teensy) +CDEFS += -DUSB_SERIAL +SRC += usb.c pins_teensy.c +CXXSRC += usb_api.cpp +endif + +# Add all the source directories as include directories too +CINCS = ${addprefix -I ,${VPATH}} +CXXINCS = ${addprefix -I ,${VPATH}} + +# Compiler flag to set the C Standard level. +# c89 - "ANSI" C +# gnu89 - c89 plus GCC extensions +# c99 - ISO C99 standard (not yet fully implemented) +# gnu99 - c99 plus GCC extensions +#CSTANDARD = -std=gnu99 +CDEBUG = -g$(DEBUG) +CWARN = -Wall -Wstrict-prototypes +CTUNING = -funsigned-char -funsigned-bitfields -fpack-struct \ + -fshort-enums -w -ffunction-sections -fdata-sections \ + -DARDUINO=$(ARDUINO_VERSION) +ifneq ($(HARDWARE_MOTHERBOARD),) +CTUNING += -DMOTHERBOARD=${HARDWARE_MOTHERBOARD} +endif +#CEXTRA = -Wa,-adhlns=$(<:.c=.lst) +CEXTRA = -fno-use-cxa-atexit + +CFLAGS := $(CDEBUG) $(CDEFS) $(CINCS) -O$(OPT) $(CWARN) $(CEXTRA) $(CTUNING) +CXXFLAGS := $(CDEFS) $(CINCS) -O$(OPT) -Wall $(CEXTRA) $(CTUNING) +#ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs +LDFLAGS = -lm + + +# Programming support using avrdude. Settings and variables. +AVRDUDE_PORT = $(UPLOAD_PORT) +AVRDUDE_WRITE_FLASH = -Uflash:w:$(BUILD_DIR)/$(TARGET).hex:i +ifeq ($(shell uname -s), Linux) +AVRDUDE_CONF = /etc/avrdude/avrdude.conf +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) \ + -b$(UPLOAD_RATE) + +# Define all object files. +OBJ = ${patsubst %.c, $(BUILD_DIR)/%.o, ${SRC}} +OBJ += ${patsubst %.cpp, $(BUILD_DIR)/%.o, ${CXXSRC}} +OBJ += ${patsubst %.S, $(BUILD_DIR)/%.o, ${ASRC}} + +# Define all listing files. +LST = $(ASRC:.S=.lst) $(CXXSRC:.cpp=.lst) $(SRC:.c=.lst) + +# Combine all necessary flags and optional flags. +# Add target processor to flags. +ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) +ALL_CXXFLAGS = -mmcu=$(MCU) $(CXXFLAGS) +ALL_ASFLAGS = -mmcu=$(MCU) -x assembler-with-cpp $(ASFLAGS) + +# set V=1 (eg, "make V=1") to print the full commands etc. +ifneq ($V,1) + Pecho=@echo + P=@ +else + Pecho=@: + P= +endif + +# Default target. +all: sizeafter + +build: $(BUILD_DIR) elf hex + +# Creates the object directory +$(BUILD_DIR): + $P mkdir -p $(BUILD_DIR) + +elf: $(BUILD_DIR)/$(TARGET).elf +hex: $(BUILD_DIR)/$(TARGET).hex +eep: $(BUILD_DIR)/$(TARGET).eep +lss: $(BUILD_DIR)/$(TARGET).lss +sym: $(BUILD_DIR)/$(TARGET).sym + +# Program the device. +# Do not try to reset an Arduino if it's not one +upload: $(BUILD_DIR)/$(TARGET).hex +ifeq (${AVRDUDE_PROGRAMMER}, arduino) + stty hup < $(UPLOAD_PORT); true +endif + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) +ifeq (${AVRDUDE_PROGRAMMER}, arduino) + stty -hup < $(UPLOAD_PORT); true +endif + + # Display size of file. +HEXSIZE = $(SIZE) --target=$(FORMAT) $(BUILD_DIR)/$(TARGET).hex +ELFSIZE = $(SIZE) --mcu=$(MCU) -C $(BUILD_DIR)/$(TARGET).elf; \ + $(SIZE) $(BUILD_DIR)/$(TARGET).elf +sizebefore: + $P if [ -f $(BUILD_DIR)/$(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(HEXSIZE); echo; fi + +sizeafter: build + $P if [ -f $(BUILD_DIR)/$(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); echo; fi + + +# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB. +COFFCONVERT=$(OBJCOPY) --debugging \ + --change-section-address .data-0x800000 \ + --change-section-address .bss-0x800000 \ + --change-section-address .noinit-0x800000 \ + --change-section-address .eeprom-0x810000 + + +coff: $(BUILD_DIR)/$(TARGET).elf + $(COFFCONVERT) -O coff-avr $(BUILD_DIR)/$(TARGET).elf $(TARGET).cof + + +extcoff: $(TARGET).elf + $(COFFCONVERT) -O coff-ext-avr $(BUILD_DIR)/$(TARGET).elf $(TARGET).cof + + +.SUFFIXES: .elf .hex .eep .lss .sym +.PRECIOUS: .o + +.elf.hex: + $(Pecho) " COPY $@" + $P $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@ + +.elf.eep: + -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ + --change-section-lma .eeprom=0 -O $(FORMAT) $< $@ + +# Create extended listing file from ELF output file. +.elf.lss: + $(OBJDUMP) -h -S $< > $@ + +# Create a symbol table from ELF output file. +.elf.sym: + $(NM) -n $< > $@ + + # Link: create ELF output file from library. +$(BUILD_DIR)/$(TARGET).elf: $(OBJ) Configuration.h + $(Pecho) " CXX $@" + $P $(CC) $(ALL_CXXFLAGS) -Wl,--gc-sections -o $@ -L. $(OBJ) $(LDFLAGS) + +$(BUILD_DIR)/%.o: %.c Configuration.h Configuration_adv.h $(MAKEFILE) + $(Pecho) " CC $<" + $P $(CC) -MMD -c $(ALL_CFLAGS) $< -o $@ + +$(BUILD_DIR)/%.o: $(BUILD_DIR)/%.cpp Configuration.h Configuration_adv.h $(MAKEFILE) + $(Pecho) " CXX $<" + $P $(CXX) -MMD -c $(ALL_CXXFLAGS) $< -o $@ + +$(BUILD_DIR)/%.o: %.cpp Configuration.h Configuration_adv.h $(MAKEFILE) + $(Pecho) " CXX $<" + $P $(CXX) -MMD -c $(ALL_CXXFLAGS) $< -o $@ + + +# Target: clean project. +clean: + $(Pecho) " RM $(BUILD_DIR)/*" + $P $(REMOVE) $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).eep $(BUILD_DIR)/$(TARGET).cof $(BUILD_DIR)/$(TARGET).elf \ + $(BUILD_DIR)/$(TARGET).map $(BUILD_DIR)/$(TARGET).sym $(BUILD_DIR)/$(TARGET).lss $(BUILD_DIR)/$(TARGET).cpp \ + $(OBJ) $(LST) $(SRC:.c=.s) $(SRC:.c=.d) $(CXXSRC:.cpp=.s) $(CXXSRC:.cpp=.d) + $(Pecho) " RMDIR $(BUILD_DIR)/" + $P rm -rf $(BUILD_DIR) + + +.PHONY: all build elf hex eep lss sym program coff extcoff clean depend sizebefore sizeafter + +# Automaticaly include the dependency files created by gcc +-include ${wildcard $(BUILD_DIR)/*.d} diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/Marlin.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/Marlin.h new file mode 100644 index 00000000..35ec96d1 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/Marlin.h @@ -0,0 +1,401 @@ +/** + * 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 . + * + */ +#ifndef MARLIN_H +#define MARLIN_H + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "MarlinConfig.h" + +#include "enum.h" +#include "types.h" +#include "fastio.h" +#include "utility.h" + +#ifdef USBCON + #include "HardwareSerial.h" + #if ENABLED(BLUETOOTH) + #define MYSERIAL bluetoothSerial + #else + #define MYSERIAL Serial + #endif // BLUETOOTH +#else + #include "MarlinSerial.h" + #define MYSERIAL customizedSerial +#endif + +#include "WString.h" + +#if ENABLED(PRINTCOUNTER) + #include "printcounter.h" +#else + #include "stopwatch.h" +#endif + +#define SERIAL_CHAR(x) MYSERIAL.write(x) +#define SERIAL_EOL SERIAL_CHAR('\n') + +#define SERIAL_PROTOCOLCHAR(x) SERIAL_CHAR(x) +#define SERIAL_PROTOCOL(x) MYSERIAL.print(x) +#define SERIAL_PROTOCOL_F(x,y) MYSERIAL.print(x,y) +#define SERIAL_PROTOCOLPGM(x) serialprintPGM(PSTR(x)) +#define SERIAL_PROTOCOLLN(x) do{ MYSERIAL.print(x); SERIAL_EOL; }while(0) +#define SERIAL_PROTOCOLLNPGM(x) do{ serialprintPGM(PSTR(x "\n")); }while(0) + +#define SERIAL_PROTOCOLPAIR(name, value) SERIAL_ECHOPAIR(name, value) + +extern const char errormagic[] PROGMEM; +extern const char echomagic[] PROGMEM; + +#define SERIAL_ERROR_START serialprintPGM(errormagic) +#define SERIAL_ERROR(x) SERIAL_PROTOCOL(x) +#define SERIAL_ERRORPGM(x) SERIAL_PROTOCOLPGM(x) +#define SERIAL_ERRORLN(x) SERIAL_PROTOCOLLN(x) +#define SERIAL_ERRORLNPGM(x) SERIAL_PROTOCOLLNPGM(x) + +#define SERIAL_ECHO_START serialprintPGM(echomagic) +#define SERIAL_ECHO(x) SERIAL_PROTOCOL(x) +#define SERIAL_ECHOPGM(x) SERIAL_PROTOCOLPGM(x) +#define SERIAL_ECHOLN(x) SERIAL_PROTOCOLLN(x) +#define SERIAL_ECHOLNPGM(x) SERIAL_PROTOCOLLNPGM(x) + +#define SERIAL_ECHOPAIR(name,value) (serial_echopair_P(PSTR(name),(value))) + +void serial_echopair_P(const char* s_P, char v); +void serial_echopair_P(const char* s_P, int v); +void serial_echopair_P(const char* s_P, long v); +void serial_echopair_P(const char* s_P, float v); +void serial_echopair_P(const char* s_P, double v); +void serial_echopair_P(const char* s_P, unsigned long v); +FORCE_INLINE void serial_echopair_P(const char* s_P, uint8_t v) { serial_echopair_P(s_P, (int)v); } +FORCE_INLINE void serial_echopair_P(const char* s_P, uint16_t v) { serial_echopair_P(s_P, (int)v); } +FORCE_INLINE void serial_echopair_P(const char* s_P, bool v) { serial_echopair_P(s_P, (int)v); } +FORCE_INLINE void serial_echopair_P(const char* s_P, void *v) { serial_echopair_P(s_P, (unsigned long)v); } + +// Things to write to serial from Program memory. Saves 400 to 2k of RAM. +FORCE_INLINE void serialprintPGM(const char* str) { + char ch; + while ((ch = pgm_read_byte(str))) { + MYSERIAL.write(ch); + str++; + } +} + +void idle( + #if ENABLED(FILAMENT_CHANGE_FEATURE) + bool no_stepper_sleep = false // pass true to keep steppers from disabling on timeout + #endif +); + +void manage_inactivity(bool ignore_stepper_queue = false); + +#if ENABLED(DUAL_X_CARRIAGE) || ENABLED(DUAL_NOZZLE_DUPLICATION_MODE) + extern bool extruder_duplication_enabled; +#endif + +#if HAS_X2_ENABLE + #define enable_x() do{ X_ENABLE_WRITE( X_ENABLE_ON); X2_ENABLE_WRITE( X_ENABLE_ON); }while(0) + #define disable_x() do{ X_ENABLE_WRITE(!X_ENABLE_ON); X2_ENABLE_WRITE(!X_ENABLE_ON); axis_known_position[X_AXIS] = false; }while(0) +#elif HAS_X_ENABLE + #define enable_x() X_ENABLE_WRITE( X_ENABLE_ON) + #define disable_x() do{ X_ENABLE_WRITE(!X_ENABLE_ON); axis_known_position[X_AXIS] = false; }while(0) +#else + #define enable_x() NOOP + #define disable_x() NOOP +#endif + +#if HAS_Y2_ENABLE + #define enable_y() do{ Y_ENABLE_WRITE( Y_ENABLE_ON); Y2_ENABLE_WRITE(Y_ENABLE_ON); }while(0) + #define disable_y() do{ Y_ENABLE_WRITE(!Y_ENABLE_ON); Y2_ENABLE_WRITE(!Y_ENABLE_ON); axis_known_position[Y_AXIS] = false; }while(0) +#elif HAS_Y_ENABLE + #define enable_y() Y_ENABLE_WRITE( Y_ENABLE_ON) + #define disable_y() do{ Y_ENABLE_WRITE(!Y_ENABLE_ON); axis_known_position[Y_AXIS] = false; }while(0) +#else + #define enable_y() NOOP + #define disable_y() NOOP +#endif + +#if HAS_Z2_ENABLE + #define enable_z() do{ Z_ENABLE_WRITE( Z_ENABLE_ON); Z2_ENABLE_WRITE(Z_ENABLE_ON); }while(0) + #define disable_z() do{ Z_ENABLE_WRITE(!Z_ENABLE_ON); Z2_ENABLE_WRITE(!Z_ENABLE_ON); axis_known_position[Z_AXIS] = false; }while(0) +#elif HAS_Z_ENABLE + #define enable_z() Z_ENABLE_WRITE( Z_ENABLE_ON) + #define disable_z() do{ Z_ENABLE_WRITE(!Z_ENABLE_ON); axis_known_position[Z_AXIS] = false; }while(0) +#else + #define enable_z() NOOP + #define disable_z() NOOP +#endif + +#if ENABLED(MIXING_EXTRUDER) + + /** + * Mixing steppers synchronize their enable (and direction) together + */ + #if MIXING_STEPPERS > 3 + #define enable_e0() { E0_ENABLE_WRITE( E_ENABLE_ON); E1_ENABLE_WRITE( E_ENABLE_ON); E2_ENABLE_WRITE( E_ENABLE_ON); E3_ENABLE_WRITE( E_ENABLE_ON); } + #define disable_e0() { E0_ENABLE_WRITE(!E_ENABLE_ON); E1_ENABLE_WRITE(!E_ENABLE_ON); E2_ENABLE_WRITE(!E_ENABLE_ON); E3_ENABLE_WRITE(!E_ENABLE_ON); } + #elif MIXING_STEPPERS > 2 + #define enable_e0() { E0_ENABLE_WRITE( E_ENABLE_ON); E1_ENABLE_WRITE( E_ENABLE_ON); E2_ENABLE_WRITE( E_ENABLE_ON); } + #define disable_e0() { E0_ENABLE_WRITE(!E_ENABLE_ON); E1_ENABLE_WRITE(!E_ENABLE_ON); E2_ENABLE_WRITE(!E_ENABLE_ON); } + #else + #define enable_e0() { E0_ENABLE_WRITE( E_ENABLE_ON); E1_ENABLE_WRITE( E_ENABLE_ON); } + #define disable_e0() { E0_ENABLE_WRITE(!E_ENABLE_ON); E1_ENABLE_WRITE(!E_ENABLE_ON); } + #endif + #define enable_e1() NOOP + #define disable_e1() NOOP + #define enable_e2() NOOP + #define disable_e2() NOOP + #define enable_e3() NOOP + #define disable_e3() NOOP + +#else // !MIXING_EXTRUDER + + #if HAS_E0_ENABLE + #define enable_e0() E0_ENABLE_WRITE( E_ENABLE_ON) + #define disable_e0() E0_ENABLE_WRITE(!E_ENABLE_ON) + #else + #define enable_e0() NOOP + #define disable_e0() NOOP + #endif + + #if E_STEPPERS > 1 && HAS_E1_ENABLE + #define enable_e1() E1_ENABLE_WRITE( E_ENABLE_ON) + #define disable_e1() E1_ENABLE_WRITE(!E_ENABLE_ON) + #else + #define enable_e1() NOOP + #define disable_e1() NOOP + #endif + + #if E_STEPPERS > 2 && HAS_E2_ENABLE + #define enable_e2() E2_ENABLE_WRITE( E_ENABLE_ON) + #define disable_e2() E2_ENABLE_WRITE(!E_ENABLE_ON) + #else + #define enable_e2() NOOP + #define disable_e2() NOOP + #endif + + #if E_STEPPERS > 3 && HAS_E3_ENABLE + #define enable_e3() E3_ENABLE_WRITE( E_ENABLE_ON) + #define disable_e3() E3_ENABLE_WRITE(!E_ENABLE_ON) + #else + #define enable_e3() NOOP + #define disable_e3() NOOP + #endif + +#endif // !MIXING_EXTRUDER + +/** + * The axis order in all axis related arrays is X, Y, Z, E + */ +#define _AXIS(AXIS) AXIS ##_AXIS + +void enable_all_steppers(); +void disable_all_steppers(); + +void FlushSerialRequestResend(); +void ok_to_send(); + +void reset_bed_level(); +void kill(const char*); + +void quickstop_stepper(); + +#if ENABLED(FILAMENT_RUNOUT_SENSOR) + void handle_filament_runout(); +#endif + +extern uint8_t marlin_debug_flags; +#define DEBUGGING(F) (marlin_debug_flags & (DEBUG_## F)) + +extern bool Running; +inline bool IsRunning() { return Running; } +inline bool IsStopped() { return !Running; } + +bool enqueue_and_echo_command(const char* cmd, bool say_ok=false); //put a single ASCII command at the end of the current buffer or return false when it is full +void enqueue_and_echo_command_now(const char* cmd); // enqueue now, only return when the command has been enqueued +void enqueue_and_echo_commands_P(const char* cmd); //put one or many ASCII commands at the end of the current buffer, read from flash +void clear_command_queue(); + +void clamp_to_software_endstops(float target[3]); + +extern millis_t previous_cmd_ms; +inline void refresh_cmd_timeout() { previous_cmd_ms = millis(); } + +#if ENABLED(FAST_PWM_FAN) + void setPwmFrequency(uint8_t pin, int val); +#endif + +/** + * Feedrate scaling and conversion + */ +extern int feedrate_percentage; + +#define MMM_TO_MMS(MM_M) ((MM_M)/60.0) +#define MMS_TO_MMM(MM_S) ((MM_S)*60.0) +#define MMM_SCALED(MM_M) ((MM_M)*feedrate_percentage*0.01) +#define MMS_SCALED(MM_S) MMM_SCALED(MM_S) +#define MMM_TO_MMS_SCALED(MM_M) (MMS_SCALED(MMM_TO_MMS(MM_M))) + +extern bool axis_relative_modes[]; +extern bool volumetric_enabled; +extern int extruder_multiplier[EXTRUDERS]; // sets extrude multiply factor (in percent) for each extruder individually +extern float filament_size[EXTRUDERS]; // cross-sectional area of filament (in millimeters), typically around 1.75 or 2.85, 0 disables the volumetric calculations for the extruder. +extern float volumetric_multiplier[EXTRUDERS]; // reciprocal of cross-sectional area of filament (in square millimeters), stored this way to reduce computational burden in planner +extern bool axis_known_position[3]; // axis[n].is_known +extern bool axis_homed[3]; // axis[n].is_homed +extern volatile bool wait_for_heatup; + +extern float current_position[NUM_AXIS]; +extern float position_shift[3]; +extern float home_offset[3]; +extern float sw_endstop_min[3]; +extern float sw_endstop_max[3]; + +#define LOGICAL_POSITION(POS, AXIS) (POS + home_offset[AXIS] + position_shift[AXIS]) +#define RAW_POSITION(POS, AXIS) (POS - home_offset[AXIS] - position_shift[AXIS]) +#define LOGICAL_X_POSITION(POS) LOGICAL_POSITION(POS, X_AXIS) +#define LOGICAL_Y_POSITION(POS) LOGICAL_POSITION(POS, Y_AXIS) +#define LOGICAL_Z_POSITION(POS) LOGICAL_POSITION(POS, Z_AXIS) +#define RAW_X_POSITION(POS) RAW_POSITION(POS, X_AXIS) +#define RAW_Y_POSITION(POS) RAW_POSITION(POS, Y_AXIS) +#define RAW_Z_POSITION(POS) RAW_POSITION(POS, Z_AXIS) +#define RAW_CURRENT_POSITION(AXIS) RAW_POSITION(current_position[AXIS], AXIS) + +// GCode support for external objects +bool code_seen(char); +int code_value_int(); +float code_value_temp_abs(); +float code_value_temp_diff(); + +extern int vertexLedBrightness; +void set_led_brightness(); + +#if ENABLED(DELTA) + extern float delta[3]; + extern float endstop_adj[3]; // axis[n].endstop_adj + extern float delta_radius; + extern float delta_diagonal_rod; + extern float delta_segments_per_second; + extern float delta_diagonal_rod_trim_tower_1; + extern float delta_diagonal_rod_trim_tower_2; + extern float delta_diagonal_rod_trim_tower_3; + void inverse_kinematics(const float cartesian[3]); + void recalc_delta_settings(float radius, float diagonal_rod); + #if ENABLED(AUTO_BED_LEVELING_FEATURE) + extern int delta_grid_spacing[2]; + void adjust_delta(float cartesian[3]); + #endif +#elif ENABLED(SCARA) + extern float delta[3]; + extern float axis_scaling[3]; // Build size scaling + void inverse_kinematics(const float cartesian[3]); + void forward_kinematics_SCARA(float f_scara[3]); +#endif + +#if ENABLED(Z_DUAL_ENDSTOPS) + extern float z_endstop_adj; +#endif + +#if HAS_BED_PROBE + extern float zprobe_zoffset; +#endif + +#if ENABLED(HOST_KEEPALIVE_FEATURE) + extern uint8_t host_keepalive_interval; +#endif + +#if FAN_COUNT > 0 + extern int fanSpeeds[FAN_COUNT]; +#endif + +#if ENABLED(BARICUDA) + extern int baricuda_valve_pressure; + extern int baricuda_e_to_p_pressure; +#endif + +#if ENABLED(FILAMENT_WIDTH_SENSOR) + extern float filament_width_nominal; //holds the theoretical filament diameter i.e., 3.00 or 1.75 + extern bool filament_sensor; //indicates that filament sensor readings should control extrusion + extern float filament_width_meas; //holds the filament diameter as accurately measured + extern int8_t measurement_delay[]; //ring buffer to delay measurement + extern int filwidth_delay_index1, filwidth_delay_index2; //ring buffer index. used by planner, temperature, and main code + extern int meas_delay_cm; //delay distance +#endif + +#if ENABLED(FILAMENT_CHANGE_FEATURE) + extern FilamentChangeMenuResponse filament_change_menu_response; +#endif + +#if ENABLED(PID_EXTRUSION_SCALING) + extern int lpq_len; +#endif + +#if ENABLED(FWRETRACT) + extern bool autoretract_enabled; + extern bool retracted[EXTRUDERS]; // extruder[n].retracted + extern float retract_length, retract_length_swap, retract_feedrate_mm_s, retract_zlift; + extern float retract_recover_length, retract_recover_length_swap, retract_recover_feedrate_mm_s; +#endif + +// Print job timer +#if ENABLED(PRINTCOUNTER) + extern PrintCounter print_job_timer; +#else + extern Stopwatch print_job_timer; +#endif + +// Handling multiple extruders pins +extern uint8_t active_extruder; + +#if HAS_TEMP_HOTEND || HAS_TEMP_BED + void print_heaterstates(); +#endif + +#if ENABLED(MIXING_EXTRUDER) + extern float mixing_factor[MIXING_STEPPERS]; +#endif + +void calculate_volumetric_multipliers(); + +// Buzzer +#if HAS_BUZZER && PIN_EXISTS(BEEPER) + #include "buzzer.h" +#endif + +/** + * Blocking movement and shorthand functions + */ +inline void do_blocking_move_to(float x, float y, float z, float fr_mm_m=0.0); +inline void do_blocking_move_to_x(float x, float fr_mm_m=0.0); +inline void do_blocking_move_to_z(float z, float fr_mm_m=0.0); +inline void do_blocking_move_to_xy(float x, float y, float fr_mm_m=0.0); + +#endif //MARLIN_H diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/MarlinConfig.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/MarlinConfig.h new file mode 100644 index 00000000..64e0bac5 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/MarlinConfig.h @@ -0,0 +1,41 @@ +/** + * 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 . + * + */ + +#ifndef MARLIN_CONFIG_H +#define MARLIN_CONFIG_H + +#include "fastio.h" +#include "macros.h" +#include "boards.h" +#include "Version.h" +#include "Configuration.h" +#include "Conditionals_LCD.h" +#include "Configuration_adv.h" +#include "pins.h" +#ifndef USBCON + #define HardwareSerial_h // trick to disable the standard HWserial +#endif +#include "Arduino.h" +#include "Conditionals_post.h" +#include "SanityCheck.h" + +#endif // MARLIN_CONFIG_H diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/MarlinSerial.cpp b/trunk/Arduino/Marlin_K8600_1.1.0RC7/MarlinSerial.cpp new file mode 100644 index 00000000..9ef90026 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/MarlinSerial.cpp @@ -0,0 +1,539 @@ +/** + * 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 . + * + */ + +/** + 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) +*/ + +#include "MarlinSerial.h" + +#include "stepper.h" + +#include "Marlin.h" + +#ifndef USBCON +// this next line disables the entire HardwareSerial.cpp, +// this is so I can support Attiny series and any other chip without a UART +#if defined(UBRRH) || defined(UBRR0H) || defined(UBRR1H) || defined(UBRR2H) || defined(UBRR3H) + +#if UART_PRESENT(SERIAL_PORT) + ring_buffer_r rx_buffer = { { 0 }, 0, 0 }; + #if TX_BUFFER_SIZE > 0 + ring_buffer_t tx_buffer = { { 0 }, 0, 0 }; + static bool _written; + #endif +#endif + + +FORCE_INLINE void store_char(unsigned char c) { + CRITICAL_SECTION_START; + uint8_t h = rx_buffer.head; + uint8_t i = (uint8_t)(h + 1) & (RX_BUFFER_SIZE - 1); + + // 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 != rx_buffer.tail) { + rx_buffer.buffer[h] = c; + rx_buffer.head = i; + } + CRITICAL_SECTION_END; + + #if ENABLED(EMERGENCY_PARSER) + emergency_parser(c); + #endif +} + +#if TX_BUFFER_SIZE > 0 + FORCE_INLINE void _tx_udr_empty_irq(void) + { + // If interrupts are enabled, there must be more data in the output + // buffer. Send the next byte + uint8_t t = tx_buffer.tail; + uint8_t c = tx_buffer.buffer[t]; + tx_buffer.tail = (t + 1) & (TX_BUFFER_SIZE - 1); + + M_UDRx = 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 + SBI(M_UCSRxA, M_TXCx); + + if (tx_buffer.head == tx_buffer.tail) { + // Buffer empty, so disable interrupts + CBI(M_UCSRxB, M_UDRIEx); + } + } + + #if defined(M_USARTx_UDRE_vect) + ISR(M_USARTx_UDRE_vect) { + _tx_udr_empty_irq(); + } + #endif + +#endif + +#if defined(M_USARTx_RX_vect) + ISR(M_USARTx_RX_vect) { + unsigned char c = M_UDRx; + store_char(c); + } +#endif + +// Constructors //////////////////////////////////////////////////////////////// + +MarlinSerial::MarlinSerial() { } + +// Public Methods ////////////////////////////////////////////////////////////// + +void MarlinSerial::begin(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 + + if (useU2X) { + M_UCSRxA = _BV(M_U2Xx); + baud_setting = (F_CPU / 4 / baud - 1) / 2; + } + else { + M_UCSRxA = 0; + baud_setting = (F_CPU / 8 / baud - 1) / 2; + } + + // assign the baud_setting, a.k.a. ubbr (USART Baud Rate Register) + M_UBRRxH = baud_setting >> 8; + M_UBRRxL = baud_setting; + + SBI(M_UCSRxB, M_RXENx); + SBI(M_UCSRxB, M_TXENx); + SBI(M_UCSRxB, M_RXCIEx); + #if TX_BUFFER_SIZE > 0 + CBI(M_UCSRxB, M_UDRIEx); + _written = false; + #endif +} + +void MarlinSerial::end() { + CBI(M_UCSRxB, M_RXENx); + CBI(M_UCSRxB, M_TXENx); + CBI(M_UCSRxB, M_RXCIEx); + CBI(M_UCSRxB, M_UDRIEx); +} + +void MarlinSerial::checkRx(void) { + if (TEST(M_UCSRxA, M_RXCx)) { + uint8_t c = M_UDRx; + store_char(c); + } +} + +int MarlinSerial::peek(void) { + int v; + CRITICAL_SECTION_START; + uint8_t t = rx_buffer.tail; + if (rx_buffer.head == t) { + v = -1; + } + else { + v = rx_buffer.buffer[t]; + } + CRITICAL_SECTION_END; + return v; +} + +int MarlinSerial::read(void) { + int v; + CRITICAL_SECTION_START; + uint8_t t = rx_buffer.tail; + if (rx_buffer.head == t) { + v = -1; + } + else { + v = rx_buffer.buffer[t]; + rx_buffer.tail = (uint8_t)(t + 1) & (RX_BUFFER_SIZE - 1); + } + CRITICAL_SECTION_END; + return v; +} + +uint8_t MarlinSerial::available(void) { + CRITICAL_SECTION_START; + uint8_t h = rx_buffer.head; + uint8_t t = rx_buffer.tail; + CRITICAL_SECTION_END; + return (uint8_t)(RX_BUFFER_SIZE + h - t) & (RX_BUFFER_SIZE - 1); +} + +void MarlinSerial::flush(void) { + // RX + // don't reverse this or there may be problems if the RX interrupt + // occurs after reading the value of rx_buffer_head but before writing + // the value to rx_buffer_tail; the previous value of rx_buffer_head + // may be written to rx_buffer_tail, making it appear as if the buffer + // were full, not empty. + CRITICAL_SECTION_START; + rx_buffer.head = rx_buffer.tail; + CRITICAL_SECTION_END; +} + +#if TX_BUFFER_SIZE > 0 + uint8_t MarlinSerial::availableForWrite(void) { + CRITICAL_SECTION_START; + uint8_t h = tx_buffer.head; + uint8_t t = tx_buffer.tail; + CRITICAL_SECTION_END; + return (uint8_t)(TX_BUFFER_SIZE + h - t) & (TX_BUFFER_SIZE - 1); + } + + void MarlinSerial::write(uint8_t c) { + _written = true; + CRITICAL_SECTION_START; + bool emty = (tx_buffer.head == tx_buffer.tail); + CRITICAL_SECTION_END; + // If the buffer 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. + if (emty && TEST(M_UCSRxA, M_UDREx)) { + CRITICAL_SECTION_START; + M_UDRx = c; + SBI(M_UCSRxA, M_TXCx); + CRITICAL_SECTION_END; + return; + } + uint8_t i = (tx_buffer.head + 1) & (TX_BUFFER_SIZE - 1); + + // If the output buffer is full, there's nothing for it other than to + // wait for the interrupt handler to empty it a bit + while (i == tx_buffer.tail) { + if (!TEST(SREG, SREG_I)) { + // Interrupts are disabled, so we'll have to poll the data + // register empty flag ourselves. If it is set, pretend an + // interrupt has happened and call the handler to free up + // space for us. + if (TEST(M_UCSRxA, M_UDREx)) + _tx_udr_empty_irq(); + } else { + // nop, the interrupt handler will free up space for us + } + } + + tx_buffer.buffer[tx_buffer.head] = c; + { CRITICAL_SECTION_START; + tx_buffer.head = i; + SBI(M_UCSRxB, M_UDRIEx); + CRITICAL_SECTION_END; + } + return; + } + + void MarlinSerial::flushTX(void) { + // TX + // If we have never written a byte, no need to flush. This special + // case is needed since there is no way to force the TXC (transmit + // complete) bit to 1 during initialization + if (!_written) + return; + + while (TEST(M_UCSRxB, M_UDRIEx) || !TEST(M_UCSRxA, M_TXCx)) { + if (!TEST(SREG, SREG_I) && TEST(M_UCSRxB, M_UDRIEx)) + // Interrupts are globally disabled, but the DR empty + // interrupt should be enabled, so poll the DR empty flag to + // prevent deadlock + if (TEST(M_UCSRxA, M_UDREx)) + _tx_udr_empty_irq(); + } + // If we get here, nothing is queued anymore (DRIE is disabled) and + // the hardware finished tranmission (TXC is set). +} + +#else + void MarlinSerial::write(uint8_t c) { + while (!TEST(M_UCSRxA, M_UDREx)) + ; + M_UDRx = c; + } +#endif + +// end NEW + +/// imports from print.h + + +void MarlinSerial::print(char c, int base) { + print((long) c, base); +} + +void MarlinSerial::print(unsigned char b, int base) { + print((unsigned long) b, base); +} + +void MarlinSerial::print(int n, int base) { + print((long) n, base); +} + +void MarlinSerial::print(unsigned int n, int base) { + print((unsigned long) n, base); +} + +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); + } +} + +void MarlinSerial::print(unsigned long n, int base) { + if (base == 0) write(n); + else printNumber(n, base); +} + +void MarlinSerial::print(double n, int digits) { + printFloat(n, digits); +} + +void MarlinSerial::println(void) { + print('\r'); + print('\n'); +} + +void MarlinSerial::println(const String& s) { + print(s); + println(); +} + +void MarlinSerial::println(const char c[]) { + print(c); + println(); +} + +void MarlinSerial::println(char c, int base) { + print(c, base); + println(); +} + +void MarlinSerial::println(unsigned char b, int base) { + print(b, base); + println(); +} + +void MarlinSerial::println(int n, int base) { + print(n, base); + println(); +} + +void MarlinSerial::println(unsigned int n, int base) { + print(n, base); + println(); +} + +void MarlinSerial::println(long n, int base) { + print(n, base); + println(); +} + +void MarlinSerial::println(unsigned long n, int base) { + print(n, base); + println(); +} + +void MarlinSerial::println(double n, int digits) { + print(n, digits); + println(); +} + +// Private Methods ///////////////////////////////////////////////////////////// + +void MarlinSerial::printNumber(unsigned long n, uint8_t base) { + unsigned char buf[8 * sizeof(long)]; // Assumes 8-bit chars. + unsigned long i = 0; + + if (n == 0) { + print('0'); + return; + } + + while (n > 0) { + buf[i++] = n % base; + n /= base; + } + + for (; i > 0; i--) + print((char)(buf[i - 1] < 10 ? + '0' + buf[i - 1] : + 'A' + buf[i - 1] - 10)); +} + +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 /= 10.0; + + 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 > 0) print('.'); + + // Extract digits from the remainder one at a time + while (digits-- > 0) { + remainder *= 10.0; + int toPrint = int(remainder); + print(toPrint); + remainder -= toPrint; + } +} +// Preinstantiate Objects ////////////////////////////////////////////////////// + + +MarlinSerial customizedSerial; + +#endif // whole file +#endif // !USBCON + +// For AT90USB targets use the UART for BT interfacing +#if defined(USBCON) && ENABLED(BLUETOOTH) + HardwareSerial bluetoothSerial; +#endif + +#if ENABLED(EMERGENCY_PARSER) + + // Currently looking for: M108, M112, M410 + // If you alter the parser please don't forget to update the capabilities in Conditionals_post.h + + FORCE_INLINE void emergency_parser(unsigned char c) { + + static e_parser_state state = state_RESET; + + switch (state) { + case state_RESET: + switch (c) { + case ' ': break; + case 'N': state = state_N; break; + case 'M': state = state_M; break; + default: state = state_IGNORE; + } + break; + + case state_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 'M': state = state_M; break; + default: state = state_IGNORE; + } + break; + + case state_M: + switch (c) { + case ' ': break; + case '1': state = state_M1; break; + case '4': state = state_M4; break; + default: state = state_IGNORE; + } + break; + + case state_M1: + switch (c) { + case '0': state = state_M10; break; + case '1': state = state_M11; break; + default: state = state_IGNORE; + } + break; + + case state_M10: + state = (c == '8') ? state_M108 : state_IGNORE; + break; + + case state_M11: + state = (c == '2') ? state_M112 : state_IGNORE; + break; + + case state_M4: + state = (c == '1') ? state_M41 : state_IGNORE; + break; + + case state_M41: + state = (c == '0') ? state_M410 : state_IGNORE; + break; + + case state_IGNORE: + if (c == '\n') state = state_RESET; + break; + + default: + if (c == '\n') { + switch (state) { + case state_M108: + wait_for_heatup = false; + break; + case state_M112: + kill(PSTR(MSG_KILLED)); + break; + case state_M410: + quickstop_stepper(); + break; + default: + break; + } + state = state_RESET; + } + } + } +#endif diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/MarlinSerial.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/MarlinSerial.h new file mode 100644 index 00000000..e7617522 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/MarlinSerial.h @@ -0,0 +1,181 @@ +/** + * 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 . + * + */ + +/** + MarlinSerial.h - Hardware serial library for Wiring + Copyright (c) 2006 Nicholas Zambetti. All right reserved. + + Modified 28 September 2010 by Mark Sproul + Modified 14 February 2016 by Andreas Hardtung (added tx buffer) + +*/ + +#ifndef MarlinSerial_h +#define MarlinSerial_h + +#include "MarlinConfig.h" + +#ifndef SERIAL_PORT + #define SERIAL_PORT 0 +#endif + +// The presence of the UBRRH register is used to detect a UART. +#define UART_PRESENT(port) ((port == 0 && (defined(UBRRH) || defined(UBRR0H))) || \ + (port == 1 && defined(UBRR1H)) || (port == 2 && defined(UBRR2H)) || \ + (port == 3 && defined(UBRR3H))) + +// 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) +#if SERIAL_PORT == 0 && (!defined(UBRR0H) || !defined(UDR0)) // use un-numbered registers if necessary + #define SERIAL_REGNAME_INTERNAL(registerbase,number,suffix) registerbase##suffix +#else + #define SERIAL_REGNAME_INTERNAL(registerbase,number,suffix) registerbase##number##suffix +#endif + +// Registers used by MarlinSerial class (these are expanded +// depending on selected serial port +#define M_UCSRxA SERIAL_REGNAME(UCSR,SERIAL_PORT,A) // defines M_UCSRxA to be UCSRnA where n is the serial port number +#define M_UCSRxB SERIAL_REGNAME(UCSR,SERIAL_PORT,B) +#define M_RXENx SERIAL_REGNAME(RXEN,SERIAL_PORT,) +#define M_TXENx SERIAL_REGNAME(TXEN,SERIAL_PORT,) +#define M_TXCx SERIAL_REGNAME(TXC,SERIAL_PORT,) +#define M_RXCIEx SERIAL_REGNAME(RXCIE,SERIAL_PORT,) +#define M_UDREx SERIAL_REGNAME(UDRE,SERIAL_PORT,) +#define M_UDRIEx SERIAL_REGNAME(UDRIE,SERIAL_PORT,) +#define M_UDRx SERIAL_REGNAME(UDR,SERIAL_PORT,) +#define M_UBRRxH SERIAL_REGNAME(UBRR,SERIAL_PORT,H) +#define M_UBRRxL SERIAL_REGNAME(UBRR,SERIAL_PORT,L) +#define M_RXCx SERIAL_REGNAME(RXC,SERIAL_PORT,) +#define M_USARTx_RX_vect SERIAL_REGNAME(USART,SERIAL_PORT,_RX_vect) +#define M_U2Xx SERIAL_REGNAME(U2X,SERIAL_PORT,) +#define M_USARTx_UDRE_vect SERIAL_REGNAME(USART,SERIAL_PORT,_UDRE_vect) + + +#define DEC 10 +#define HEX 16 +#define OCT 8 +#define BIN 2 +#define BYTE 0 + + +#ifndef USBCON +// Define constants and variables for buffering incoming serial data. We're +// using a ring buffer (I think), in which rx_buffer_head is the index of the +// location to which to write the next incoming character and rx_buffer_tail +// is the index of the location from which to read. +// 256 is the max limit due to uint8_t head and tail. Use only powers of 2. (...,16,32,64,128,256) +#ifndef RX_BUFFER_SIZE + #define RX_BUFFER_SIZE 128 +#endif +#ifndef TX_BUFFER_SIZE + #define TX_BUFFER_SIZE 32 +#endif +#if !((RX_BUFFER_SIZE == 256) ||(RX_BUFFER_SIZE == 128) ||(RX_BUFFER_SIZE == 64) ||(RX_BUFFER_SIZE == 32) ||(RX_BUFFER_SIZE == 16) ||(RX_BUFFER_SIZE == 8) ||(RX_BUFFER_SIZE == 4) ||(RX_BUFFER_SIZE == 2)) + #error "RX_BUFFER_SIZE has to be a power of 2 and >= 2" +#endif +#if !((TX_BUFFER_SIZE == 256) ||(TX_BUFFER_SIZE == 128) ||(TX_BUFFER_SIZE == 64) ||(TX_BUFFER_SIZE == 32) ||(TX_BUFFER_SIZE == 16) ||(TX_BUFFER_SIZE == 8) ||(TX_BUFFER_SIZE == 4) ||(TX_BUFFER_SIZE == 2) ||(TX_BUFFER_SIZE == 0)) + #error TX_BUFFER_SIZE has to be a power of 2 or 0 +#endif + +struct ring_buffer_r { + unsigned char buffer[RX_BUFFER_SIZE]; + volatile uint8_t head; + volatile uint8_t tail; +}; + +#if TX_BUFFER_SIZE > 0 + struct ring_buffer_t { + unsigned char buffer[TX_BUFFER_SIZE]; + volatile uint8_t head; + volatile uint8_t tail; + }; +#endif + +#if UART_PRESENT(SERIAL_PORT) + extern ring_buffer_r rx_buffer; + #if TX_BUFFER_SIZE > 0 + extern ring_buffer_t tx_buffer; + #endif +#endif + +#if ENABLED(EMERGENCY_PARSER) + #include "language.h" + void emergency_parser(unsigned char c); +#endif + +class MarlinSerial { //: public Stream + + public: + MarlinSerial(); + void begin(long); + void end(); + int peek(void); + int read(void); + void flush(void); + uint8_t available(void); + void checkRx(void); + void write(uint8_t c); + #if TX_BUFFER_SIZE > 0 + uint8_t availableForWrite(void); + void flushTX(void); + #endif + + private: + void printNumber(unsigned long, uint8_t); + void printFloat(double, uint8_t); + + public: + FORCE_INLINE void write(const char* str) { while (*str) write(*str++); } + FORCE_INLINE void write(const uint8_t* buffer, size_t size) { while (size--) write(*buffer++); } + FORCE_INLINE void print(const String& s) { for (int i = 0; i < (int)s.length(); i++) write(s[i]); } + FORCE_INLINE void print(const char* str) { write(str); } + + void print(char, int = BYTE); + void print(unsigned char, int = BYTE); + void print(int, int = DEC); + void print(unsigned int, int = DEC); + void print(long, int = DEC); + void print(unsigned long, int = DEC); + void print(double, int = 2); + + void println(const String& s); + void println(const char[]); + void println(char, int = BYTE); + void println(unsigned char, int = BYTE); + void println(int, int = DEC); + void println(unsigned int, int = DEC); + void println(long, int = DEC); + void println(unsigned long, int = DEC); + void println(double, int = 2); + void println(void); +}; + +extern MarlinSerial customizedSerial; +#endif // !USBCON + +// Use the UART for Bluetooth in AT90USB configurations +#if defined(USBCON) && ENABLED(BLUETOOTH) + extern HardwareSerial bluetoothSerial; +#endif + +#endif diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/Marlin_K8600_1.1.0RC7.ino b/trunk/Arduino/Marlin_K8600_1.1.0RC7/Marlin_K8600_1.1.0RC7.ino new file mode 100644 index 00000000..9e8a60cd --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/Marlin_K8600_1.1.0RC7.ino @@ -0,0 +1,80 @@ +/** + * 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 . + * + */ + +/** + * About Marlin + * + * This firmware is a mashup between Sprinter and grbl. + * - https://github.com/kliment/Sprinter + * - https://github.com/simen/grbl/tree + * + * It has preliminary support for Matthew Roberts advance algorithm + * - http://reprap.org/pipermail/reprap-dev/2011-May/003323.html + */ + +/** + * Configuration Arduino IDE + * + * Arduino/Genuino Mega or Mega2560, ATmega2560(Mega 2560) + */ + + +/* All the implementation is done in *.cpp files to get better compatibility with avr-gcc without the Arduino IDE */ +/* Use this file to help the Arduino IDE find which Arduino libraries are needed and to keep documentation on GCode */ + +#include "MarlinConfig.h" + +#if ENABLED(ULTRA_LCD) + #if ENABLED(LCD_I2C_TYPE_PCF8575) + #include + #include + #elif ENABLED(LCD_I2C_TYPE_MCP23017) || ENABLED(LCD_I2C_TYPE_MCP23008) + #include + #include + #elif ENABLED(LCM1602) + #include + #include + #include + #elif ENABLED(DOGLCD) + #include // library for graphics LCD by Oli Kraus (https://github.com/olikraus/U8glib_Arduino) + #else + #include // library for character LCD + #endif +#endif + +#if HAS_DIGIPOTSS + #include +#endif + +#if ENABLED(DIGIPOT_I2C) + #include +#endif + +#if ENABLED(HAVE_TMCDRIVER) + #include + #include +#endif + +#if ENABLED(HAVE_L6470DRIVER) + #include + #include +#endif diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/Marlin_main.cpp b/trunk/Arduino/Marlin_K8600_1.1.0RC7/Marlin_main.cpp new file mode 100644 index 00000000..cbddbc96 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/Marlin_main.cpp @@ -0,0 +1,8784 @@ +/** + * 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 . + * + */ + +/** + * + * About Marlin + * + * This firmware is a mashup between Sprinter and grbl. + * - https://github.com/kliment/Sprinter + * - https://github.com/simen/grbl/tree + * + * It has preliminary support for Matthew Roberts advance algorithm + * - http://reprap.org/pipermail/reprap-dev/2011-May/003323.html + */ + +#include "Marlin.h" + +#if ENABLED(AUTO_BED_LEVELING_FEATURE) + #include "vector_3.h" + #if ENABLED(AUTO_BED_LEVELING_GRID) + #include "qr_solve.h" + #endif +#endif // AUTO_BED_LEVELING_FEATURE + +#if ENABLED(MESH_BED_LEVELING) + #include "mesh_bed_leveling.h" +#endif + +#if ENABLED(BEZIER_CURVE_SUPPORT) + #include "planner_bezier.h" +#endif + +#include "ultralcd.h" +#include "planner.h" +#include "stepper.h" +#include "endstops.h" +#include "temperature.h" +#include "cardreader.h" +#include "configuration_store.h" +#include "language.h" +#include "pins_arduino.h" +#include "math.h" +#include "nozzle.h" +#include "duration_t.h" +#include "types.h" + +#if ENABLED(USE_WATCHDOG) + #include "watchdog.h" +#endif + +#if ENABLED(BLINKM) + #include "blinkm.h" + #include "Wire.h" +#endif + +#if HAS_SERVOS + #include "servo.h" +#endif + +#if HAS_DIGIPOTSS + #include +#endif + +#if ENABLED(DAC_STEPPER_CURRENT) + #include "stepper_dac.h" +#endif + +#if ENABLED(EXPERIMENTAL_I2CBUS) + #include "twibus.h" +#endif + +/** + * Look here for descriptions of G-codes: + * - http://linuxcnc.org/handbook/gcode/g-code.html + * - http://objects.reprap.org/wiki/Mendel_User_Manual:_RepRapGCodes + * + * Help us document these G-codes online: + * - https://github.com/MarlinFirmware/Marlin/wiki/G-Code-in-Marlin + * - http://reprap.org/wiki/G-code + * + * ----------------- + * Implemented Codes + * ----------------- + * + * "G" Codes + * + * G0 -> G1 + * G1 - Coordinated Movement X Y Z E + * G2 - CW ARC + * G3 - CCW ARC + * G4 - Dwell S or P + * G5 - Cubic B-spline with XYZE destination and IJPQ offsets + * G10 - Retract filament according to settings of M207 + * G11 - Retract recover filament according to settings of M208 + * G12 - Clean tool + * G20 - Set input units to inches + * G21 - Set input units to millimeters + * G28 - Home one or more axes + * G29 - Detailed Z probe, probes the bed at 3 or more points. Will fail if you haven't homed yet. + * G30 - Single Z probe, probes bed at current XY location. + * G31 - Dock sled (Z_PROBE_SLED only) + * G32 - Undock sled (Z_PROBE_SLED only) + * G90 - Use Absolute Coordinates + * G91 - Use Relative Coordinates + * G92 - Set current position to coordinates given + * + * "M" Codes + * + * M0 - Unconditional stop - Wait for user to press a button on the LCD (Only if ULTRA_LCD is enabled) + * M1 - Same as M0 + * M17 - Enable/Power all stepper motors + * M18 - Disable all stepper motors; same as M84 + * M20 - List SD card + * M21 - Init SD card + * M22 - Release SD card + * M23 - Select SD file (M23 filename.g) + * M24 - Start/resume SD print + * M25 - Pause SD print + * M26 - Set SD position in bytes (M26 S12345) + * M27 - Report SD print status + * M28 - Start SD write (M28 filename.g) + * M29 - Stop SD write + * M30 - Delete file from SD (M30 filename.g) + * M31 - Output time since last M109 or SD card start to serial + * M32 - Select file and start SD print (Can be used _while_ printing from SD card files): + * syntax "M32 /path/filename#", or "M32 S !filename#" + * Call gcode file : "M32 P !filename#" and return to caller file after finishing (similar to #include). + * The '#' is necessary when calling from within sd files, as it stops buffer prereading + * M33 - Get the longname version of a path + * M42 - Change pin status via gcode Use M42 Px Sy to set pin x to value y, when omitting Px the onboard led will be used. + * M48 - Measure Z_Probe repeatability. M48 [P # of points] [X position] [Y position] [V_erboseness #] [E_ngage Probe] [L # of legs of travel] + * M75 - Start the print job timer + * M76 - Pause the print job timer + * M77 - Stop the print job timer + * M78 - Show statistical information about the print jobs + * M80 - Turn on Power Supply + * M81 - Turn off Power Supply + * M82 - Set E codes absolute (default) + * M83 - Set E codes relative while in Absolute Coordinates (G90) mode + * M84 - Disable steppers until next move, + * or use S to specify an inactivity timeout, after which the steppers will be disabled. S0 to disable the timeout. + * M85 - Set inactivity shutdown timer with parameter S. To disable set zero (default) + * M92 - Set planner.axis_steps_per_mm - same syntax as G92 + * M104 - Set extruder target temp + * M105 - Read current temp + * M106 - Fan on + * M107 - Fan off + * M108 - Stop the waiting for heaters in M109, M190, M303. Does not affect the target temperature. + * M109 - Sxxx Wait for extruder current temp to reach target temp. Waits only when heating + * Rxxx Wait for extruder current temp to reach target temp. Waits when heating and cooling + * IF AUTOTEMP is enabled, S B F. Exit autotemp by any M109 without F + * M110 - Set the current line number + * M111 - Set debug flags with S. See flag bits defined in enum.h. + * M112 - Emergency stop + * M113 - Get or set the timeout interval for Host Keepalive "busy" messages + * M114 - Output current position to serial port + * M115 - Capabilities string + * M117 - Display a message on the controller screen + * M119 - Output Endstop status to serial port + * M120 - Enable endstop detection + * M121 - Disable endstop detection + * M126 - Solenoid Air Valve Open (BariCUDA support by jmil) + * M127 - Solenoid Air Valve Closed (BariCUDA vent to atmospheric pressure by jmil) + * M128 - EtoP Open (BariCUDA EtoP = electricity to air pressure transducer by jmil) + * M129 - EtoP Closed (BariCUDA EtoP = electricity to air pressure transducer by jmil) + * M140 - Set bed target temp + * M145 - Set the heatup state H B F for S (0=PLA, 1=ABS) + * M149 - Set temperature units + * M150 - Set BlinkM Color Output R: Red<0-255> U(!): Green<0-255> B: Blue<0-255> over i2c, G for green does not work. + * M163 - Set a single proportion for a mixing extruder. Requires MIXING_EXTRUDER. + * M164 - Save the mix as a virtual extruder. Requires MIXING_EXTRUDER and MIXING_VIRTUAL_TOOLS. + * M165 - Set the proportions for a mixing extruder. Use parameters ABCDHI to set the mixing factors. Requires MIXING_EXTRUDER. + * 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 + * M200 - Set filament diameter, D, setting E axis units to cubic. (Use S0 to revert to linear units.) + * M201 - Set max acceleration in units/s^2 for print moves (M201 X1000 Y1000) + * M202 - Set max acceleration in units/s^2 for travel moves (M202 X1000 Y1000) Unused in Marlin!! + * M203 - Set maximum feedrate that your machine can sustain (M203 X200 Y200 Z300 E10000) in units/sec + * M204 - Set default acceleration: P for Printing moves, R for Retract only (no X, Y, Z) moves and T for Travel (non printing) moves (ex. M204 P800 T3000 R9000) in units/sec^2 + * M205 - Set advanced settings. Current units apply: + S T minimum speeds + B + X, Z, E + * M206 - Set additional homing offset + * M207 - Set Retract Length: S, Feedrate: F, and Z lift: Z + * M208 - Set Recover (unretract) Additional (!) Length: S and Feedrate: F + * M209 - Turn Automatic Retract Detection on/off: S (For slicers that don't support G10/11). + Every normal extrude-only move will be classified as retract depending on the direction. + * M218 - Set a tool offset: T X Y + * M220 - Set Feedrate Percentage: S ("FR" on your LCD) + * M221 - Set Flow Percentage: S + * M226 - Wait until the specified pin reaches the state required: P S + * M240 - Trigger a camera to take a photograph + * M250 - Set LCD contrast C (value 0..63) + * M280 - Set servo position absolute. P: servo index, S: angle or microseconds + * M300 - Play beep sound S P + * M301 - Set PID parameters P I and D + * M302 - Allow cold extrudes, or set the minimum extrude S. + * M303 - PID relay autotune S sets the target temperature. (default target temperature = 150C) + * M304 - Set bed PID parameters P I and D + * M380 - Activate solenoid on active extruder + * M381 - Disable all solenoids + * M400 - Finish all moves + * M401 - Lower Z probe if present + * M402 - Raise Z probe if present + * M404 - Display or set the Nominal Filament Width: [ N ] + * M405 - Enable Filament Sensor extrusion control. Optional delay between sensor and extruder: D + * M406 - Disable Filament Sensor extrusion control + * M407 - Display measured filament diameter in millimeters + * M410 - Quickstop. Abort all the planned moves + * M420 - Enable/Disable Mesh Leveling (with current values) S1=enable S0=disable + * M421 - Set a single Z coordinate in the Mesh Leveling grid. X Y Z + * M428 - Set the home_offset logically based on the current_position + * M500 - Store parameters in EEPROM + * M501 - Read parameters from EEPROM (if you need reset them after you changed them temporarily). + * M502 - Revert to the default "factory settings". You still need to store them in EEPROM afterwards if you want to. + * M503 - Print the current settings (from memory not from EEPROM). Use S0 to leave off headings. + * M540 - Use S[0|1] to enable or disable the stop SD card print on endstop hit (requires ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED) + * M600 - Pause for filament change X[pos] Y[pos] Z[relative lift] E[initial retract] L[later retract distance for removal] + * M665 - Set delta configurations: L R S + * M666 - Set delta endstop adjustment + * M605 - Set dual x-carriage movement mode: S [ X R ] + * M851 - Set Z probe's Z offset in current units. (Negative values apply to probes that extend below the nozzle.) + * M907 - Set digital trimpot motor current using axis codes. + * M908 - Control digital trimpot directly. + * M909 - DAC_STEPPER_CURRENT: Print digipot/DAC current value + * M910 - DAC_STEPPER_CURRENT: Commit digipot/DAC value to external EEPROM via I2C + * M350 - Set microstepping mode. + * M351 - Toggle MS1 MS2 pins directly. + * + * ************ SCARA Specific - This can change to suit future G-code regulations + * M360 - SCARA calibration: Move to cal-position ThetaA (0 deg calibration) + * M361 - SCARA calibration: Move to cal-position ThetaB (90 deg calibration - steps per degree) + * M362 - SCARA calibration: Move to cal-position PsiA (0 deg calibration) + * M363 - SCARA calibration: Move to cal-position PsiB (90 deg calibration - steps per degree) + * M364 - SCARA calibration: Move to cal-position PSIC (90 deg to Theta calibration position) + * M365 - SCARA calibration: Scaling factor, X, Y, Z axis + * ************* SCARA End *************** + * + * ************ Custom codes - This can change to suit future G-code regulations + * M100 - Watch Free Memory (For Debugging Only) + * M928 - Start SD logging (M928 filename.g) - ended by M29 + * M999 - Restart after being stopped by error + * + * "T" Codes + * + * T0-T3 - Select a tool by index (usually an extruder) [ F ] + * + */ + +#if ENABLED(M100_FREE_MEMORY_WATCHER) + void gcode_M100(); +#endif + +#if ENABLED(SDSUPPORT) + CardReader card; +#endif + +#if ENABLED(EXPERIMENTAL_I2CBUS) + TWIBus i2c; +#endif + +bool Running = true; + +uint8_t marlin_debug_flags = DEBUG_NONE; + +float current_position[NUM_AXIS] = { 0.0 }; +static float destination[NUM_AXIS] = { 0.0 }; +bool axis_known_position[3] = { false }; +bool axis_homed[3] = { false }; + +static long gcode_N, gcode_LastN, Stopped_gcode_LastN = 0; + +static char command_queue[BUFSIZE][MAX_CMD_SIZE]; +static char* current_command, *current_command_args; +static uint8_t cmd_queue_index_r = 0, + cmd_queue_index_w = 0, + commands_in_queue = 0; + +#if ENABLED(INCH_MODE_SUPPORT) + float linear_unit_factor = 1.0; + float volumetric_unit_factor = 1.0; +#endif +#if ENABLED(TEMPERATURE_UNITS_SUPPORT) + TempUnit input_temp_units = TEMPUNIT_C; +#endif + +/** + * Feed rates are often configured with mm/m + * but the planner and stepper like mm/s units. + */ +const float homing_feedrate_mm_m[] = { + #if ENABLED(DELTA) + HOMING_FEEDRATE_Z, HOMING_FEEDRATE_Z, + #else + HOMING_FEEDRATE_XY, HOMING_FEEDRATE_XY, + #endif + HOMING_FEEDRATE_Z, 0 +}; +static float feedrate_mm_m = 1500.0, saved_feedrate_mm_m; +int feedrate_percentage = 100, saved_feedrate_percentage; + +bool axis_relative_modes[] = AXIS_RELATIVE_MODES; +int extruder_multiplier[EXTRUDERS] = ARRAY_BY_EXTRUDERS1(100); +bool volumetric_enabled = false; +float filament_size[EXTRUDERS] = ARRAY_BY_EXTRUDERS1(DEFAULT_NOMINAL_FILAMENT_DIA); +float volumetric_multiplier[EXTRUDERS] = ARRAY_BY_EXTRUDERS1(1.0); + +// The distance that XYZ has been offset by G92. Reset by G28. +float position_shift[3] = { 0 }; + +// This offset is added to the configured home position. +// Set by M206, M428, or menu item. Saved to EEPROM. +float home_offset[3] = { 0 }; + +// Software Endstops. Default to configured limits. +float sw_endstop_min[3] = { X_MIN_POS, Y_MIN_POS, Z_MIN_POS }; +float sw_endstop_max[3] = { X_MAX_POS, Y_MAX_POS, Z_MAX_POS }; + +#if FAN_COUNT > 0 + int fanSpeeds[FAN_COUNT] = { 0 }; +#endif + +// The active extruder (tool). Set with T command. +uint8_t active_extruder = 0; + +// Relative Mode. Enable with G91, disable with G90. +static bool relative_mode = false; + +volatile bool wait_for_heatup = true; + +const char errormagic[] PROGMEM = "Error:"; +const char echomagic[] PROGMEM = "echo:"; +const char axis_codes[NUM_AXIS] = {'X', 'Y', 'Z', 'E'}; + +static int serial_count = 0; + +int vertexLedBrightness = 100; + +// GCode parameter pointer used by code_seen(), code_value_float(), etc. +static char* seen_pointer; + +// Next Immediate GCode Command pointer. NULL if none. +const char* queued_commands_P = NULL; + +const int sensitive_pins[] = SENSITIVE_PINS; ///< Sensitive pin list for M42 + +// Inactivity shutdown +millis_t previous_cmd_ms = 0; +static millis_t max_inactive_time = 0; +static millis_t stepper_inactive_time = (DEFAULT_STEPPER_DEACTIVE_TIME) * 1000UL; + +// Print Job Timer +#if ENABLED(PRINTCOUNTER) + PrintCounter print_job_timer = PrintCounter(); +#else + Stopwatch print_job_timer = Stopwatch(); +#endif + +// Buzzer - I2C on the LCD or a BEEPER_PIN +#if ENABLED(LCD_USE_I2C_BUZZER) + #define BUZZ(d,f) lcd_buzz(d, f) +#elif HAS_BUZZER + Buzzer buzzer; + #define BUZZ(d,f) buzzer.tone(d, f) +#else + #define BUZZ(d,f) NOOP +#endif + +static uint8_t target_extruder; + +#if HAS_BED_PROBE + float zprobe_zoffset = Z_PROBE_OFFSET_FROM_EXTRUDER; +#endif + +#define PLANNER_XY_FEEDRATE() (min(planner.max_feedrate_mm_s[X_AXIS], planner.max_feedrate_mm_s[Y_AXIS])) + +#if ENABLED(AUTO_BED_LEVELING_FEATURE) + int xy_probe_feedrate_mm_m = XY_PROBE_SPEED; + bool bed_leveling_in_progress = false; + #define XY_PROBE_FEEDRATE_MM_M xy_probe_feedrate_mm_m +#elif defined(XY_PROBE_SPEED) + #define XY_PROBE_FEEDRATE_MM_M XY_PROBE_SPEED +#else + #define XY_PROBE_FEEDRATE_MM_M MMS_TO_MMM(PLANNER_XY_FEEDRATE()) +#endif + +#if ENABLED(Z_DUAL_ENDSTOPS) && DISABLED(DELTA) + float z_endstop_adj = 0; +#endif + +// Extruder offsets +#if HOTENDS > 1 + float hotend_offset[][HOTENDS] = { + HOTEND_OFFSET_X, + HOTEND_OFFSET_Y + #ifdef HOTEND_OFFSET_Z + , HOTEND_OFFSET_Z + #endif + }; +#endif + +#if HAS_Z_SERVO_ENDSTOP + const int z_servo_angle[2] = Z_SERVO_ANGLES; +#endif + +#if ENABLED(BARICUDA) + int baricuda_valve_pressure = 0; + int baricuda_e_to_p_pressure = 0; +#endif + +#if ENABLED(FWRETRACT) + + bool autoretract_enabled = false; + bool retracted[EXTRUDERS] = { false }; + bool retracted_swap[EXTRUDERS] = { false }; + + float retract_length = RETRACT_LENGTH; + float retract_length_swap = RETRACT_LENGTH_SWAP; + float retract_feedrate_mm_s = RETRACT_FEEDRATE; + float retract_zlift = RETRACT_ZLIFT; + float retract_recover_length = RETRACT_RECOVER_LENGTH; + float retract_recover_length_swap = RETRACT_RECOVER_LENGTH_SWAP; + float retract_recover_feedrate_mm_s = RETRACT_RECOVER_FEEDRATE; + +#endif // FWRETRACT + +#if ENABLED(ULTIPANEL) && HAS_POWER_SWITCH + bool powersupply = + #if ENABLED(PS_DEFAULT_OFF) + false + #else + true + #endif + ; +#endif + +#if ENABLED(DELTA) + + #define TOWER_1 X_AXIS + #define TOWER_2 Y_AXIS + #define TOWER_3 Z_AXIS + + float delta[3]; + float cartesian_position[3] = { 0 }; + #define SIN_60 0.8660254037844386 + #define COS_60 0.5 + float endstop_adj[3] = { 0 }; + // these are the default values, can be overriden with M665 + float delta_radius = DELTA_RADIUS; + float delta_tower1_x = -SIN_60 * (delta_radius + DELTA_RADIUS_TRIM_TOWER_1); // front left tower + float delta_tower1_y = -COS_60 * (delta_radius + DELTA_RADIUS_TRIM_TOWER_1); + float delta_tower2_x = SIN_60 * (delta_radius + DELTA_RADIUS_TRIM_TOWER_2); // front right tower + float delta_tower2_y = -COS_60 * (delta_radius + DELTA_RADIUS_TRIM_TOWER_2); + float delta_tower3_x = 0; // back middle tower + float delta_tower3_y = (delta_radius + DELTA_RADIUS_TRIM_TOWER_3); + float delta_diagonal_rod = DELTA_DIAGONAL_ROD; + float delta_diagonal_rod_trim_tower_1 = DELTA_DIAGONAL_ROD_TRIM_TOWER_1; + float delta_diagonal_rod_trim_tower_2 = DELTA_DIAGONAL_ROD_TRIM_TOWER_2; + float delta_diagonal_rod_trim_tower_3 = DELTA_DIAGONAL_ROD_TRIM_TOWER_3; + float delta_diagonal_rod_2_tower_1 = sq(delta_diagonal_rod + delta_diagonal_rod_trim_tower_1); + float delta_diagonal_rod_2_tower_2 = sq(delta_diagonal_rod + delta_diagonal_rod_trim_tower_2); + float delta_diagonal_rod_2_tower_3 = sq(delta_diagonal_rod + delta_diagonal_rod_trim_tower_3); + float delta_segments_per_second = DELTA_SEGMENTS_PER_SECOND; + float delta_clip_start_height = Z_MAX_POS; + #if ENABLED(AUTO_BED_LEVELING_FEATURE) + int delta_grid_spacing[2] = { 0, 0 }; + float bed_level[AUTO_BED_LEVELING_GRID_POINTS][AUTO_BED_LEVELING_GRID_POINTS]; + #endif + float delta_safe_distance_from_top(); +#else + static bool home_all_axis = true; +#endif + +#if ENABLED(SCARA) + float delta_segments_per_second = SCARA_SEGMENTS_PER_SECOND; + float delta[3]; + float axis_scaling[3] = { 1, 1, 1 }; // Build size scaling, default to 1 +#endif + +#if ENABLED(FILAMENT_WIDTH_SENSOR) + //Variables for Filament Sensor input + float filament_width_nominal = DEFAULT_NOMINAL_FILAMENT_DIA; //Set nominal filament width, can be changed with M404 + bool filament_sensor = false; //M405 turns on filament_sensor control, M406 turns it off + float filament_width_meas = DEFAULT_MEASURED_FILAMENT_DIA; //Stores the measured filament diameter + int8_t measurement_delay[MAX_MEASUREMENT_DELAY + 1]; //ring buffer to delay measurement store extruder factor after subtracting 100 + int filwidth_delay_index1 = 0; //index into ring buffer + int filwidth_delay_index2 = -1; //index into ring buffer - set to -1 on startup to indicate ring buffer needs to be initialized + int meas_delay_cm = MEASUREMENT_DELAY_CM; //distance delay setting +#endif + +#if ENABLED(FILAMENT_RUNOUT_SENSOR) + static bool filament_ran_out = false; +#endif + +#if ENABLED(FILAMENT_CHANGE_FEATURE) + FilamentChangeMenuResponse filament_change_menu_response; +#endif + +#if ENABLED(MIXING_EXTRUDER) + float mixing_factor[MIXING_STEPPERS]; + #if MIXING_VIRTUAL_TOOLS > 1 + float mixing_virtual_tool_mix[MIXING_VIRTUAL_TOOLS][MIXING_STEPPERS]; + #endif +#endif + +static bool send_ok[BUFSIZE]; + +#if HAS_SERVOS + Servo servo[NUM_SERVOS]; + #define MOVE_SERVO(I, P) servo[I].move(P) + #if HAS_Z_SERVO_ENDSTOP + #define DEPLOY_Z_SERVO() MOVE_SERVO(Z_ENDSTOP_SERVO_NR, z_servo_angle[0]) + #define STOW_Z_SERVO() MOVE_SERVO(Z_ENDSTOP_SERVO_NR, z_servo_angle[1]) + #endif +#endif + +#ifdef CHDK + millis_t chdkHigh = 0; + boolean chdkActive = false; +#endif + +#if ENABLED(PID_EXTRUSION_SCALING) + int lpq_len = 20; +#endif + +#if ENABLED(HOST_KEEPALIVE_FEATURE) + static MarlinBusyState busy_state = NOT_BUSY; + static millis_t next_busy_signal_ms = 0; + uint8_t host_keepalive_interval = DEFAULT_KEEPALIVE_INTERVAL; + #define KEEPALIVE_STATE(n) do{ busy_state = n; }while(0) +#else + #define host_keepalive() ; + #define KEEPALIVE_STATE(n) ; +#endif // HOST_KEEPALIVE_FEATURE + +/** + * *************************************************************************** + * ******************************** FUNCTIONS ******************************** + * *************************************************************************** + */ + +void stop(); + +void get_available_commands(); +void process_next_command(); +void prepare_move_to_destination(); +void set_current_from_steppers_for_axis(AxisEnum axis); + +#if ENABLED(ARC_SUPPORT) + void plan_arc(float target[NUM_AXIS], float* offset, uint8_t clockwise); +#endif + +#if ENABLED(BEZIER_CURVE_SUPPORT) + void plan_cubic_move(const float offset[4]); +#endif + +void serial_echopair_P(const char* s_P, char v) { serialprintPGM(s_P); SERIAL_CHAR(v); } +void serial_echopair_P(const char* s_P, int v) { serialprintPGM(s_P); SERIAL_ECHO(v); } +void serial_echopair_P(const char* s_P, long v) { serialprintPGM(s_P); SERIAL_ECHO(v); } +void serial_echopair_P(const char* s_P, float v) { serialprintPGM(s_P); SERIAL_ECHO(v); } +void serial_echopair_P(const char* s_P, double v) { serialprintPGM(s_P); SERIAL_ECHO(v); } +void serial_echopair_P(const char* s_P, unsigned long v) { serialprintPGM(s_P); SERIAL_ECHO(v); } + +void tool_change(const uint8_t tmp_extruder, const float fr_mm_m=0.0, bool no_move=false); +static void report_current_position(); + +#if ENABLED(DEBUG_LEVELING_FEATURE) + void print_xyz(const char* prefix, const char* suffix, const float x, const float y, const float z) { + serialprintPGM(prefix); + SERIAL_ECHOPAIR("(", x); + SERIAL_ECHOPAIR(", ", y); + SERIAL_ECHOPAIR(", ", z); + SERIAL_ECHOPGM(")"); + + if (suffix) serialprintPGM(suffix); + else SERIAL_EOL; + } + + void print_xyz(const char* prefix, const char* suffix, const float xyz[]) { + print_xyz(prefix, suffix, xyz[X_AXIS], xyz[Y_AXIS], xyz[Z_AXIS]); + } + + #if ENABLED(AUTO_BED_LEVELING_FEATURE) + void print_xyz(const char* prefix, const char* suffix, const vector_3 &xyz) { + print_xyz(prefix, suffix, xyz.x, xyz.y, xyz.z); + } + #endif + + #define DEBUG_POS(SUFFIX,VAR) do { \ + print_xyz(PSTR(STRINGIFY(VAR) "="), PSTR(" : " SUFFIX "\n"), VAR); } while(0) +#endif + +/** + * sync_plan_position + * Set planner / stepper positions to the cartesian current_position. + * The stepper code translates these coordinates into step units. + * Allows translation between steps and millimeters for cartesian & core robots + */ +inline void sync_plan_position() { + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("sync_plan_position", current_position); + #endif + planner.set_position_mm(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); +} +inline void sync_plan_position_e() { planner.set_e_position_mm(current_position[E_AXIS]); } + +#if ENABLED(DELTA) || ENABLED(SCARA) + inline void sync_plan_position_delta() { + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("sync_plan_position_delta", current_position); + #endif + inverse_kinematics(current_position); + planner.set_position_mm(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], current_position[E_AXIS]); + } + #define SYNC_PLAN_POSITION_KINEMATIC() sync_plan_position_delta() +#else + #define SYNC_PLAN_POSITION_KINEMATIC() sync_plan_position() +#endif + +#if ENABLED(SDSUPPORT) + #include "SdFatUtil.h" + int freeMemory() { return SdFatUtil::FreeRam(); } +#else +extern "C" { + extern unsigned int __bss_end; + extern unsigned int __heap_start; + extern void* __brkval; + + int freeMemory() { + int free_memory; + if ((int)__brkval == 0) + free_memory = ((int)&free_memory) - ((int)&__bss_end); + else + free_memory = ((int)&free_memory) - ((int)__brkval); + return free_memory; + } +} +#endif //!SDSUPPORT + +#if ENABLED(DIGIPOT_I2C) + extern void digipot_i2c_set_current(int channel, float current); + extern void digipot_i2c_init(); +#endif + +/** + * Inject the next "immediate" command, when possible. + * Return true if any immediate commands remain to inject. + */ +static bool drain_queued_commands_P() { + if (queued_commands_P != NULL) { + size_t i = 0; + char c, cmd[30]; + strncpy_P(cmd, queued_commands_P, sizeof(cmd) - 1); + cmd[sizeof(cmd) - 1] = '\0'; + while ((c = cmd[i]) && c != '\n') i++; // find the end of this gcode command + cmd[i] = '\0'; + if (enqueue_and_echo_command(cmd)) { // success? + if (c) // newline char? + queued_commands_P += i + 1; // advance to the next command + else + queued_commands_P = NULL; // nul char? no more commands + } + } + return (queued_commands_P != NULL); // return whether any more remain +} + +/** + * Record one or many commands to run from program memory. + * Aborts the current queue, if any. + * Note: drain_queued_commands_P() must be called repeatedly to drain the commands afterwards + */ +void enqueue_and_echo_commands_P(const char* pgcode) { + queued_commands_P = pgcode; + drain_queued_commands_P(); // first command executed asap (when possible) +} + +void clear_command_queue() { + cmd_queue_index_r = cmd_queue_index_w; + commands_in_queue = 0; +} + +/** + * Once a new command is in the ring buffer, call this to commit it + */ +inline void _commit_command(bool say_ok) { + send_ok[cmd_queue_index_w] = say_ok; + cmd_queue_index_w = (cmd_queue_index_w + 1) % BUFSIZE; + commands_in_queue++; +} + +/** + * Copy a command directly into the main command buffer, from RAM. + * Returns true if successfully adds the command + */ +inline bool _enqueuecommand(const char* cmd, bool say_ok=false) { + if (*cmd == ';' || commands_in_queue >= BUFSIZE) return false; + strcpy(command_queue[cmd_queue_index_w], cmd); + _commit_command(say_ok); + return true; +} + +void enqueue_and_echo_command_now(const char* cmd) { + while (!enqueue_and_echo_command(cmd)) idle(); +} + +/** + * Enqueue with Serial Echo + */ +bool enqueue_and_echo_command(const char* cmd, bool say_ok/*=false*/) { + if (_enqueuecommand(cmd, say_ok)) { + SERIAL_ECHO_START; + SERIAL_ECHOPGM(MSG_Enqueueing); + SERIAL_ECHO(cmd); + SERIAL_ECHOLNPGM("\""); + return true; + } + return false; +} + +void setup_killpin() { + #if HAS_KILL + SET_INPUT(KILL_PIN); + WRITE(KILL_PIN, HIGH); + #endif +} + +#if ENABLED(FILAMENT_RUNOUT_SENSOR) + + void setup_filrunoutpin() { + pinMode(FIL_RUNOUT_PIN, INPUT); + #if ENABLED(ENDSTOPPULLUP_FIL_RUNOUT) + WRITE(FIL_RUNOUT_PIN, HIGH); + #endif + } + +#endif + +// Set home pin +void setup_homepin(void) { + #if HAS_HOME + SET_INPUT(HOME_PIN); + WRITE(HOME_PIN, HIGH); + #endif +} + + +void setup_photpin() { + #if HAS_PHOTOGRAPH + OUT_WRITE(PHOTOGRAPH_PIN, LOW); + #endif +} + +void setup_powerhold() { + #if HAS_SUICIDE + OUT_WRITE(SUICIDE_PIN, HIGH); + #endif + #if HAS_POWER_SWITCH + #if ENABLED(PS_DEFAULT_OFF) + OUT_WRITE(PS_ON_PIN, PS_ON_ASLEEP); + #else + OUT_WRITE(PS_ON_PIN, PS_ON_AWAKE); + #endif + #endif +} + +void suicide() { + #if HAS_SUICIDE + OUT_WRITE(SUICIDE_PIN, LOW); + #endif +} + +void servo_init() { + #if NUM_SERVOS >= 1 && HAS_SERVO_0 + servo[0].attach(SERVO0_PIN); + servo[0].detach(); // Just set up the pin. We don't have a position yet. Don't move to a random position. + #endif + #if NUM_SERVOS >= 2 && HAS_SERVO_1 + servo[1].attach(SERVO1_PIN); + servo[1].detach(); + #endif + #if NUM_SERVOS >= 3 && HAS_SERVO_2 + servo[2].attach(SERVO2_PIN); + servo[2].detach(); + #endif + #if NUM_SERVOS >= 4 && HAS_SERVO_3 + servo[3].attach(SERVO3_PIN); + servo[3].detach(); + #endif + + #if HAS_Z_SERVO_ENDSTOP + /** + * Set position of Z Servo Endstop + * + * The servo might be deployed and positioned too low to stow + * 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(); + #endif + + #if HAS_BED_PROBE + endstops.enable_z_probe(false); + #endif +} + +/** + * Stepper Reset (RigidBoard, et.al.) + */ +#if HAS_STEPPER_RESET + void disableStepperDrivers() { + pinMode(STEPPER_RESET_PIN, OUTPUT); + digitalWrite(STEPPER_RESET_PIN, LOW); // drive it down to hold in reset motor driver chips + } + void enableStepperDrivers() { pinMode(STEPPER_RESET_PIN, INPUT); } // set to input, which allows it to be pulled high by pullups +#endif + +// Set led brightness according to current variable +void set_led_brightness() +{ + //analogWrite(7, map(vertexLedBrightness, 0, 100, 0, 255)); +} + +/** + * Marlin entry-point: Set up before the program loop + * - Set up the kill pin, filament runout, power hold + * - Start the serial port + * - Print startup messages and diagnostics + * - Get EEPROM or default settings + * - Initialize managers for: + * • temperature + * • planner + * • watchdog + * • stepper + * • photo pin + * • servos + * • LCD controller + * • Digipot I2C + * • Z probe sled + * • status LEDs + */ +void setup() { + + set_led_brightness(); + + #ifdef DISABLE_JTAG + // Disable JTAG on AT90USB chips to free up pins for IO + MCUCR = 0x80; + MCUCR = 0x80; + #endif + + #if ENABLED(FILAMENT_RUNOUT_SENSOR) + setup_filrunoutpin(); + #endif + + setup_killpin(); + + setup_powerhold(); + + #if HAS_STEPPER_RESET + disableStepperDrivers(); + #endif + + MYSERIAL.begin(BAUDRATE); + SERIAL_PROTOCOLLNPGM("start"); + SERIAL_ECHO_START; + + // Check startup - does nothing if bootloader sets MCUSR to 0 + byte mcu = MCUSR; + if (mcu & 1) SERIAL_ECHOLNPGM(MSG_POWERUP); + if (mcu & 2) SERIAL_ECHOLNPGM(MSG_EXTERNAL_RESET); + if (mcu & 4) SERIAL_ECHOLNPGM(MSG_BROWNOUT_RESET); + if (mcu & 8) SERIAL_ECHOLNPGM(MSG_WATCHDOG_RESET); + if (mcu & 32) SERIAL_ECHOLNPGM(MSG_SOFTWARE_RESET); + MCUSR = 0; + + SERIAL_ECHOPGM(MSG_MARLIN); + SERIAL_ECHOLNPGM(" " SHORT_BUILD_VERSION); + + #ifdef STRING_DISTRIBUTION_DATE + #ifdef STRING_CONFIG_H_AUTHOR + SERIAL_ECHO_START; + SERIAL_ECHOPGM(MSG_CONFIGURATION_VER); + SERIAL_ECHOPGM(STRING_DISTRIBUTION_DATE); + SERIAL_ECHOPGM(MSG_AUTHOR); + SERIAL_ECHOLNPGM(STRING_CONFIG_H_AUTHOR); + SERIAL_ECHOPGM("Compiled: "); + SERIAL_ECHOLNPGM(__DATE__); + #endif // STRING_CONFIG_H_AUTHOR + #endif // STRING_DISTRIBUTION_DATE + + SERIAL_ECHO_START; + SERIAL_ECHOPGM(MSG_FREE_MEMORY); + SERIAL_ECHO(freeMemory()); + SERIAL_ECHOPGM(MSG_PLANNER_BUFFER_BYTES); + SERIAL_ECHOLN((int)sizeof(block_t)*BLOCK_BUFFER_SIZE); + + // Send "ok" after commands by default + for (int8_t i = 0; i < BUFSIZE; i++) send_ok[i] = true; + + // Load data from EEPROM if available (or use defaults) + // This also updates variables in the planner, elsewhere + Config_RetrieveSettings(); + + // Initialize current position based on home_offset + memcpy(current_position, home_offset, sizeof(home_offset)); + + // Vital to init stepper/planner equivalent for current_position + SYNC_PLAN_POSITION_KINEMATIC(); + + thermalManager.init(); // Initialize temperature loop + + #if ENABLED(USE_WATCHDOG) + watchdog_init(); + #endif + + stepper.init(); // Initialize stepper, this enables interrupts! + setup_photpin(); + servo_init(); + + #if HAS_CONTROLLERFAN + SET_OUTPUT(CONTROLLERFAN_PIN); //Set pin used for driver cooling fan + #endif + + #if HAS_STEPPER_RESET + enableStepperDrivers(); + #endif + + #if ENABLED(DIGIPOT_I2C) + digipot_i2c_init(); + #endif + + #if ENABLED(DAC_STEPPER_CURRENT) + dac_init(); + #endif + + #if ENABLED(Z_PROBE_SLED) && PIN_EXISTS(SLED) + pinMode(SLED_PIN, OUTPUT); + digitalWrite(SLED_PIN, LOW); // turn it off + #endif // Z_PROBE_SLED + + setup_homepin(); + + #ifdef STAT_LED_RED + pinMode(STAT_LED_RED, OUTPUT); + digitalWrite(STAT_LED_RED, LOW); // turn it off + #endif + + #ifdef STAT_LED_BLUE + pinMode(STAT_LED_BLUE, OUTPUT); + digitalWrite(STAT_LED_BLUE, LOW); // turn it off + #endif + + lcd_init(); + #if ENABLED(SHOW_BOOTSCREEN) + #if ENABLED(DOGLCD) + safe_delay(BOOTSCREEN_TIMEOUT); + #elif ENABLED(ULTRA_LCD) + bootscreen(); + lcd_init(); + #endif + #endif + + #if ENABLED(MIXING_EXTRUDER) && MIXING_VIRTUAL_TOOLS > 1 + // Initialize mixing to 100% color 1 + for (uint8_t i = 0; i < MIXING_STEPPERS; i++) + mixing_factor[i] = (i == 0) ? 1 : 0; + for (uint8_t t = 0; t < MIXING_VIRTUAL_TOOLS; t++) + for (uint8_t i = 0; i < MIXING_STEPPERS; i++) + mixing_virtual_tool_mix[t][i] = mixing_factor[i]; + #endif +} + +/** + * The main Marlin program loop + * + * - Save or log commands to SD + * - Process available commands (if not saving) + * - Call heater manager + * - Call inactivity manager + * - Call endstop manager + * - Call LCD update + */ +void loop() { + if (commands_in_queue < BUFSIZE) get_available_commands(); + + #if ENABLED(SDSUPPORT) + card.checkautostart(false); + #endif + + if (commands_in_queue) { + + #if ENABLED(SDSUPPORT) + + if (card.saving) { + char* command = command_queue[cmd_queue_index_r]; + if (strstr_P(command, PSTR("M29"))) { + // M29 closes the file + card.closefile(); + SERIAL_PROTOCOLLNPGM(MSG_FILE_SAVED); + ok_to_send(); + } + else { + // Write the string from the read buffer to SD + card.write_command(command); + if (card.logging) + process_next_command(); // The card is saving because it's logging + else + ok_to_send(); + } + } + else + process_next_command(); + + #else + + process_next_command(); + + #endif // SDSUPPORT + + // The queue may be reset by a command handler or by code invoked by idle() within a handler + if (commands_in_queue) { + --commands_in_queue; + cmd_queue_index_r = (cmd_queue_index_r + 1) % BUFSIZE; + } + } + endstops.report_state(); + idle(); +} + +void gcode_line_error(const char* err, bool doFlush = true) { + SERIAL_ERROR_START; + serialprintPGM(err); + SERIAL_ERRORLN(gcode_LastN); + //Serial.println(gcode_N); + if (doFlush) FlushSerialRequestResend(); + serial_count = 0; +} + +inline void get_serial_commands() { + static char serial_line_buffer[MAX_CMD_SIZE]; + static boolean serial_comment_mode = false; + + // If the command buffer is empty for too long, + // send "wait" to indicate Marlin is still waiting. + #if defined(NO_TIMEOUTS) && NO_TIMEOUTS > 0 + static millis_t last_command_time = 0; + millis_t ms = millis(); + if (commands_in_queue == 0 && !MYSERIAL.available() && ELAPSED(ms, last_command_time + NO_TIMEOUTS)) { + SERIAL_ECHOLNPGM(MSG_WAIT); + last_command_time = ms; + } + #endif + + /** + * Loop while serial characters are incoming and the queue is not full + */ + while (commands_in_queue < BUFSIZE && MYSERIAL.available() > 0) { + + char serial_char = MYSERIAL.read(); + + /** + * If the character ends the line + */ + if (serial_char == '\n' || serial_char == '\r') { + + serial_comment_mode = false; // end of line == end of comment + + if (!serial_count) continue; // skip empty lines + + serial_line_buffer[serial_count] = 0; // terminate string + serial_count = 0; //reset buffer + + char* command = serial_line_buffer; + + while (*command == ' ') command++; // skip any leading spaces + char* npos = (*command == 'N') ? command : NULL; // Require the N parameter to start the line + char* apos = strchr(command, '*'); + + if (npos) { + + boolean M110 = strstr_P(command, PSTR("M110")) != NULL; + + if (M110) { + char* n2pos = strchr(command + 4, 'N'); + if (n2pos) npos = n2pos; + } + + gcode_N = strtol(npos + 1, NULL, 10); + + if (gcode_N != gcode_LastN + 1 && !M110) { + gcode_line_error(PSTR(MSG_ERR_LINE_NO)); + return; + } + + if (apos) { + byte checksum = 0, count = 0; + while (command[count] != '*') checksum ^= command[count++]; + + if (strtol(apos + 1, NULL, 10) != checksum) { + gcode_line_error(PSTR(MSG_ERR_CHECKSUM_MISMATCH)); + return; + } + // if no errors, continue parsing + } + else { + gcode_line_error(PSTR(MSG_ERR_NO_CHECKSUM)); + return; + } + + gcode_LastN = gcode_N; + // if no errors, continue parsing + } + else if (apos) { // No '*' without 'N' + gcode_line_error(PSTR(MSG_ERR_NO_LINENUMBER_WITH_CHECKSUM), false); + return; + } + + // Movement commands alert when stopped + if (IsStopped()) { + char* gpos = strchr(command, 'G'); + if (gpos) { + int codenum = strtol(gpos + 1, NULL, 10); + switch (codenum) { + case 0: + case 1: + case 2: + case 3: + SERIAL_ERRORLNPGM(MSG_ERR_STOPPED); + LCD_MESSAGEPGM(MSG_STOPPED); + break; + } + } + } + + #if DISABLED(EMERGENCY_PARSER) + // If command was e-stop process now + if (strcmp(command, "M108") == 0) wait_for_heatup = false; + if (strcmp(command, "M112") == 0) kill(PSTR(MSG_KILLED)); + if (strcmp(command, "M410") == 0) { quickstop_stepper(); } + #endif + + #if defined(NO_TIMEOUTS) && NO_TIMEOUTS > 0 + last_command_time = ms; + #endif + + // Add the command to the queue + _enqueuecommand(serial_line_buffer, true); + } + else if (serial_count >= MAX_CMD_SIZE - 1) { + // Keep fetching, but ignore normal characters beyond the max length + // The command will be injected when EOL is reached + } + else if (serial_char == '\\') { // Handle escapes + if (MYSERIAL.available() > 0) { + // if we have one more character, copy it over + serial_char = MYSERIAL.read(); + if (!serial_comment_mode) serial_line_buffer[serial_count++] = serial_char; + } + // otherwise do nothing + } + else { // it's not a newline, carriage return or escape char + if (serial_char == ';') serial_comment_mode = true; + if (!serial_comment_mode) serial_line_buffer[serial_count++] = serial_char; + } + + } // queue has space, serial has data +} + +#if ENABLED(SDSUPPORT) + + inline void get_sdcard_commands() { + static bool stop_buffering = false, + sd_comment_mode = false; + + if (!card.sdprinting) return; + + /** + * '#' stops reading from SD to the buffer prematurely, so procedural + * macro calls are possible. If it occurs, stop_buffering is triggered + * and the buffer is run dry; this character _can_ occur in serial com + * due to checksums, however, no checksums are used in SD printing. + */ + + if (commands_in_queue == 0) stop_buffering = false; + + uint16_t sd_count = 0; + bool card_eof = card.eof(); + while (commands_in_queue < BUFSIZE && !card_eof && !stop_buffering) { + int16_t n = card.get(); + char sd_char = (char)n; + card_eof = card.eof(); + if (card_eof || n == -1 + || sd_char == '\n' || sd_char == '\r' + || ((sd_char == '#' || sd_char == ':') && !sd_comment_mode) + ) { + if (card_eof) { + SERIAL_PROTOCOLLNPGM(MSG_FILE_PRINTED); + card.printingHasFinished(); + card.checkautostart(true); + } + else if (n == -1) { + SERIAL_ERROR_START; + SERIAL_ECHOLNPGM(MSG_SD_ERR_READ); + } + if (sd_char == '#') stop_buffering = true; + + sd_comment_mode = false; //for new command + + if (!sd_count) continue; //skip empty lines + + command_queue[cmd_queue_index_w][sd_count] = '\0'; //terminate string + sd_count = 0; //clear buffer + + _commit_command(false); + } + else if (sd_count >= MAX_CMD_SIZE - 1) { + /** + * Keep fetching, but ignore normal characters beyond the max length + * The command will be injected when EOL is reached + */ + } + else { + if (sd_char == ';') sd_comment_mode = true; + if (!sd_comment_mode) command_queue[cmd_queue_index_w][sd_count++] = sd_char; + } + } + } + +#endif // SDSUPPORT + +/** + * Add to the circular command queue the next command from: + * - The command-injection queue (queued_commands_P) + * - The active serial input (usually USB) + * - The SD card file being actively printed + */ +void get_available_commands() { + + // if any immediate commands remain, don't get other commands yet + if (drain_queued_commands_P()) return; + + get_serial_commands(); + + #if ENABLED(SDSUPPORT) + get_sdcard_commands(); + #endif +} + +inline bool code_has_value() { + int i = 1; + char c = seen_pointer[i]; + while (c == ' ') c = seen_pointer[++i]; + if (c == '-' || c == '+') c = seen_pointer[++i]; + if (c == '.') c = seen_pointer[++i]; + return NUMERIC(c); +} + +inline float code_value_float() { + float ret; + char* e = strchr(seen_pointer, 'E'); + if (e) { + *e = 0; + ret = strtod(seen_pointer + 1, NULL); + *e = 'E'; + } + else + ret = strtod(seen_pointer + 1, NULL); + return ret; +} + +inline unsigned long code_value_ulong() { return strtoul(seen_pointer + 1, NULL, 10); } + +inline long code_value_long() { return strtol(seen_pointer + 1, NULL, 10); } + +inline int code_value_int() { return (int)strtol(seen_pointer + 1, NULL, 10); } + +inline uint16_t code_value_ushort() { return (uint16_t)strtoul(seen_pointer + 1, NULL, 10); } + +inline uint8_t code_value_byte() { return (uint8_t)(constrain(strtol(seen_pointer + 1, NULL, 10), 0, 255)); } + +inline bool code_value_bool() { return code_value_byte() > 0; } + +#if ENABLED(INCH_MODE_SUPPORT) + inline void set_input_linear_units(LinearUnit units) { + switch (units) { + case LINEARUNIT_INCH: + linear_unit_factor = 25.4; + break; + case LINEARUNIT_MM: + default: + linear_unit_factor = 1.0; + break; + } + volumetric_unit_factor = pow(linear_unit_factor, 3.0); + } + + inline float axis_unit_factor(int axis) { + return (axis == E_AXIS && volumetric_enabled ? volumetric_unit_factor : linear_unit_factor); + } + + inline float code_value_linear_units() { return code_value_float() * linear_unit_factor; } + inline float code_value_axis_units(int axis) { return code_value_float() * axis_unit_factor(axis); } + inline float code_value_per_axis_unit(int axis) { return code_value_float() / axis_unit_factor(axis); } + +#else + + inline float code_value_linear_units() { return code_value_float(); } + inline float code_value_axis_units(int axis) { UNUSED(axis); return code_value_float(); } + inline float code_value_per_axis_unit(int axis) { UNUSED(axis); return code_value_float(); } + +#endif + +#if ENABLED(TEMPERATURE_UNITS_SUPPORT) + inline void set_input_temp_units(TempUnit units) { input_temp_units = units; } + + float code_value_temp_abs() { + switch (input_temp_units) { + case TEMPUNIT_C: + return code_value_float(); + case TEMPUNIT_F: + return (code_value_float() - 32) * 0.5555555556; + case TEMPUNIT_K: + return code_value_float() - 272.15; + default: + return code_value_float(); + } + } + + float code_value_temp_diff() { + switch (input_temp_units) { + case TEMPUNIT_C: + case TEMPUNIT_K: + return code_value_float(); + case TEMPUNIT_F: + return code_value_float() * 0.5555555556; + default: + return code_value_float(); + } + } +#else + float code_value_temp_abs() { return code_value_float(); } + float code_value_temp_diff() { return code_value_float(); } +#endif + +FORCE_INLINE millis_t code_value_millis() { return code_value_ulong(); } +inline millis_t code_value_millis_from_seconds() { return code_value_float() * 1000; } + +bool code_seen(char code) { + seen_pointer = strchr(current_command_args, code); + return (seen_pointer != NULL); // Return TRUE if the code-letter was found +} + +/** + * Set target_extruder from the T parameter or the active_extruder + * + * Returns TRUE if the target is invalid + */ +bool get_target_extruder_from_command(int code) { + if (code_seen('T')) { + if (code_value_byte() >= EXTRUDERS) { + SERIAL_ECHO_START; + SERIAL_CHAR('M'); + SERIAL_ECHO(code); + SERIAL_ECHOPAIR(" " MSG_INVALID_EXTRUDER " ", code_value_byte()); + SERIAL_EOL; + return true; + } + target_extruder = code_value_byte(); + } + else + target_extruder = active_extruder; + + return false; +} + +#define DEFINE_PGM_READ_ANY(type, reader) \ + static inline type pgm_read_any(const type *p) \ + { return pgm_read_##reader##_near(p); } + +DEFINE_PGM_READ_ANY(float, float); +DEFINE_PGM_READ_ANY(signed char, byte); + +#define XYZ_CONSTS_FROM_CONFIG(type, array, CONFIG) \ + static const PROGMEM type array##_P[3] = \ + { X_##CONFIG, Y_##CONFIG, Z_##CONFIG }; \ + static inline type array(int axis) \ + { return pgm_read_any(&array##_P[axis]); } + +XYZ_CONSTS_FROM_CONFIG(float, base_min_pos, MIN_POS); +XYZ_CONSTS_FROM_CONFIG(float, base_max_pos, MAX_POS); +XYZ_CONSTS_FROM_CONFIG(float, base_home_pos, HOME_POS); +XYZ_CONSTS_FROM_CONFIG(float, max_length, MAX_LENGTH); +XYZ_CONSTS_FROM_CONFIG(float, home_bump_mm, HOME_BUMP_MM); +XYZ_CONSTS_FROM_CONFIG(signed char, home_dir, HOME_DIR); + +#if ENABLED(DUAL_X_CARRIAGE) || ENABLED(DUAL_NOZZLE_DUPLICATION_MODE) + bool extruder_duplication_enabled = false; // Used in Dual X mode 2 +#endif + +#if ENABLED(DUAL_X_CARRIAGE) + + #define DXC_FULL_CONTROL_MODE 0 + #define DXC_AUTO_PARK_MODE 1 + #define DXC_DUPLICATION_MODE 2 + + static int dual_x_carriage_mode = DEFAULT_DUAL_X_CARRIAGE_MODE; + + static float x_home_pos(int extruder) { + if (extruder == 0) + return LOGICAL_X_POSITION(base_home_pos(X_AXIS)); + else + /** + * In dual carriage mode the extruder offset provides an override of the + * second X-carriage offset when homed - otherwise X2_HOME_POS is used. + * This allow soft recalibration of the second extruder offset position + * without firmware reflash (through the M218 command). + */ + return (hotend_offset[X_AXIS][1] > 0) ? hotend_offset[X_AXIS][1] : X2_HOME_POS; + } + + static int x_home_dir(int extruder) { + return (extruder == 0) ? X_HOME_DIR : X2_HOME_DIR; + } + + static float inactive_extruder_x_pos = X2_MAX_POS; // used in mode 0 & 1 + static bool active_extruder_parked = false; // used in mode 1 & 2 + static float raised_parked_position[NUM_AXIS]; // used in mode 1 + static millis_t delayed_move_time = 0; // used in mode 1 + static float duplicate_extruder_x_offset = DEFAULT_DUPLICATION_X_OFFSET; // used in mode 2 + static float duplicate_extruder_temp_offset = 0; // used in mode 2 + +#endif //DUAL_X_CARRIAGE + +/** + * Software endstops can be used to monitor the open end of + * an axis that has a hardware endstop on the other end. Or + * they can prevent axes from moving past endstops and grinding. + * + * To keep doing their job as the coordinate system changes, + * the software endstop positions must be refreshed to remain + * at the same positions relative to the machine. + */ +static void update_software_endstops(AxisEnum axis) { + float offs = LOGICAL_POSITION(0, axis); + + #if ENABLED(DUAL_X_CARRIAGE) + if (axis == X_AXIS) { + float dual_max_x = max(hotend_offset[X_AXIS][1], X2_MAX_POS); + if (active_extruder != 0) { + sw_endstop_min[X_AXIS] = X2_MIN_POS + offs; + sw_endstop_max[X_AXIS] = dual_max_x + offs; + return; + } + else if (dual_x_carriage_mode == DXC_DUPLICATION_MODE) { + sw_endstop_min[X_AXIS] = base_min_pos(X_AXIS) + offs; + sw_endstop_max[X_AXIS] = min(base_max_pos(X_AXIS), dual_max_x - duplicate_extruder_x_offset) + offs; + return; + } + } + else + #endif + { + sw_endstop_min[axis] = base_min_pos(axis) + offs; + sw_endstop_max[axis] = base_max_pos(axis) + offs; + } + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOPAIR("For ", axis_codes[axis]); + SERIAL_ECHOPAIR(" axis:\n home_offset = ", home_offset[axis]); + SERIAL_ECHOPAIR("\n position_shift = ", position_shift[axis]); + SERIAL_ECHOPAIR("\n sw_endstop_min = ", sw_endstop_min[axis]); + SERIAL_ECHOPAIR("\n sw_endstop_max = ", sw_endstop_max[axis]); + SERIAL_EOL; + } + #endif + + #if ENABLED(DELTA) + if (axis == Z_AXIS) { + delta_clip_start_height = sw_endstop_max[axis] - delta_safe_distance_from_top(); + } + #endif + +} + +/** + * Change the home offset for an axis, update the current + * position and the software endstops to retain the same + * relative distance to the new home. + * + * Since this changes the current_position, code should + * call sync_plan_position soon after this. + */ +static void set_home_offset(AxisEnum axis, float v) { + current_position[axis] += v - home_offset[axis]; + home_offset[axis] = v; + update_software_endstops(axis); +} + +static void set_axis_is_at_home(AxisEnum axis) { + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOPAIR(">>> set_axis_is_at_home(", axis); + SERIAL_ECHOLNPGM(")"); + } + #endif + + position_shift[axis] = 0; + + #if ENABLED(DUAL_X_CARRIAGE) + if (axis == X_AXIS && (active_extruder != 0 || dual_x_carriage_mode == DXC_DUPLICATION_MODE)) { + if (active_extruder != 0) + current_position[X_AXIS] = x_home_pos(active_extruder); + else + current_position[X_AXIS] = LOGICAL_X_POSITION(base_home_pos(X_AXIS)); + update_software_endstops(X_AXIS); + return; + } + #endif + + #if ENABLED(SCARA) + + if (axis == X_AXIS || axis == Y_AXIS) { + + float homeposition[3]; + LOOP_XYZ(i) homeposition[i] = LOGICAL_POSITION(base_home_pos(i), i); + + // SERIAL_ECHOPGM("homeposition[x]= "); SERIAL_ECHO(homeposition[0]); + // SERIAL_ECHOPGM("homeposition[y]= "); SERIAL_ECHOLN(homeposition[1]); + + /** + * Works out real Homeposition angles using inverse kinematics, + * and calculates homing offset using forward kinematics + */ + inverse_kinematics(homeposition); + forward_kinematics_SCARA(delta); + + // SERIAL_ECHOPAIR("Delta X=", delta[X_AXIS]); + // SERIAL_ECHOPGM(" Delta Y="); SERIAL_ECHOLN(delta[Y_AXIS]); + + current_position[axis] = LOGICAL_POSITION(delta[axis], axis); + + /** + * SCARA home positions are based on configuration since the actual + * limits are determined by the inverse kinematic transform. + */ + sw_endstop_min[axis] = base_min_pos(axis); // + (delta[axis] - base_home_pos(axis)); + sw_endstop_max[axis] = base_max_pos(axis); // + (delta[axis] - base_home_pos(axis)); + } + else + #endif + { + current_position[axis] = LOGICAL_POSITION(base_home_pos(axis), axis); + update_software_endstops(axis); + + #if HAS_BED_PROBE && Z_HOME_DIR < 0 && DISABLED(Z_MIN_PROBE_ENDSTOP) + if (axis == Z_AXIS) { + current_position[Z_AXIS] -= zprobe_zoffset; + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOPAIR("> zprobe_zoffset = ", zprobe_zoffset); + SERIAL_EOL; + } + #endif + } + #endif + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOPAIR("> home_offset[", axis_codes[axis]); + SERIAL_ECHOPAIR("] = ", home_offset[axis]); + SERIAL_EOL; + DEBUG_POS("", current_position); + } + #endif + } + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOPAIR("<<< set_axis_is_at_home(", axis); + SERIAL_ECHOLNPGM(")"); + } + #endif +} + +/** + * Some planner shorthand inline functions + */ +inline float get_homing_bump_feedrate(AxisEnum axis) { + const int homing_bump_divisor[] = HOMING_BUMP_DIVISOR; + int hbd = homing_bump_divisor[axis]; + if (hbd < 1) { + hbd = 10; + SERIAL_ECHO_START; + SERIAL_ECHOLNPGM("Warning: Homing Bump Divisor < 1"); + } + return homing_feedrate_mm_m[axis] / hbd; +} +// +// line_to_current_position +// Move the planner to the current position from wherever it last moved +// (or from wherever it has been told it is located). +// +inline void line_to_current_position() { + planner.buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], MMM_TO_MMS(feedrate_mm_m), active_extruder); +} + +inline void line_to_z(float zPosition) { + planner.buffer_line(current_position[X_AXIS], current_position[Y_AXIS], zPosition, current_position[E_AXIS], MMM_TO_MMS(feedrate_mm_m), active_extruder); +} + +inline void line_to_axis_pos(AxisEnum axis, float where, float fr_mm_m = 0.0) { + float old_feedrate_mm_m = feedrate_mm_m; + current_position[axis] = where; + feedrate_mm_m = (fr_mm_m != 0.0) ? fr_mm_m : homing_feedrate_mm_m[axis]; + planner.buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], MMM_TO_MMS(feedrate_mm_m), active_extruder); + stepper.synchronize(); + feedrate_mm_m = old_feedrate_mm_m; +} + +// +// line_to_destination +// Move the planner, not necessarily synced with current_position +// +inline void line_to_destination(float fr_mm_m) { + planner.buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], MMM_TO_MMS(fr_mm_m), active_extruder); +} +inline void line_to_destination() { line_to_destination(feedrate_mm_m); } + +inline void set_current_to_destination() { memcpy(current_position, destination, sizeof(current_position)); } +inline void set_destination_to_current() { memcpy(destination, current_position, sizeof(destination)); } + +#if ENABLED(DELTA) + /** + * Calculate delta, start a line, and set current_position to destination + */ + void prepare_move_to_destination_raw() { + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("prepare_move_to_destination_raw", destination); + #endif + refresh_cmd_timeout(); + inverse_kinematics(destination); + planner.buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], destination[E_AXIS], MMM_TO_MMS_SCALED(feedrate_mm_m), active_extruder); + set_current_to_destination(); + } +#endif + +/** + * Plan a move to (X, Y, Z) and set the current_position + * The final current_position may not be the one that was requested + */ +void do_blocking_move_to(float x, float y, float z, float fr_mm_m /*=0.0*/) { + float old_feedrate_mm_m = feedrate_mm_m; + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) print_xyz(PSTR(">>> do_blocking_move_to"), NULL, x, y, z); + #endif + + #if ENABLED(DELTA) + + feedrate_mm_m = (fr_mm_m != 0.0) ? fr_mm_m : XY_PROBE_FEEDRATE_MM_M; + + set_destination_to_current(); // sync destination at the start + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("set_destination_to_current", destination); + #endif + + // when in the danger zone + if (current_position[Z_AXIS] > delta_clip_start_height) { + if (z > delta_clip_start_height) { // staying in the danger zone + destination[X_AXIS] = x; // move directly (uninterpolated) + destination[Y_AXIS] = y; + destination[Z_AXIS] = z; + prepare_move_to_destination_raw(); // set_current_to_destination + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("danger zone move", current_position); + #endif + return; + } + else { + destination[Z_AXIS] = delta_clip_start_height; + prepare_move_to_destination_raw(); // set_current_to_destination + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("zone border move", current_position); + #endif + } + } + + if (z > current_position[Z_AXIS]) { // raising? + destination[Z_AXIS] = z; + prepare_move_to_destination_raw(); // set_current_to_destination + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("z raise move", current_position); + #endif + } + + destination[X_AXIS] = x; + destination[Y_AXIS] = y; + prepare_move_to_destination(); // set_current_to_destination + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("xy move", current_position); + #endif + + if (z < current_position[Z_AXIS]) { // lowering? + destination[Z_AXIS] = z; + prepare_move_to_destination_raw(); // set_current_to_destination + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("z lower move", current_position); + #endif + } + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("<<< do_blocking_move_to"); + #endif + + #else + + // If Z needs to raise, do it before moving XY + if (current_position[Z_AXIS] < z) { + feedrate_mm_m = (fr_mm_m != 0.0) ? fr_mm_m : homing_feedrate_mm_m[Z_AXIS]; + current_position[Z_AXIS] = z; + line_to_current_position(); + } + + feedrate_mm_m = (fr_mm_m != 0.0) ? fr_mm_m : XY_PROBE_FEEDRATE_MM_M; + current_position[X_AXIS] = x; + current_position[Y_AXIS] = y; + line_to_current_position(); + + // If Z needs to lower, do it after moving XY + if (current_position[Z_AXIS] > z) { + feedrate_mm_m = (fr_mm_m != 0.0) ? fr_mm_m : homing_feedrate_mm_m[Z_AXIS]; + current_position[Z_AXIS] = z; + line_to_current_position(); + } + + #endif + + stepper.synchronize(); + + feedrate_mm_m = old_feedrate_mm_m; +} +void do_blocking_move_to_x(float x, float fr_mm_m/*=0.0*/) { + do_blocking_move_to(x, current_position[Y_AXIS], current_position[Z_AXIS], fr_mm_m); +} +void do_blocking_move_to_z(float z, float fr_mm_m/*=0.0*/) { + do_blocking_move_to(current_position[X_AXIS], current_position[Y_AXIS], z, fr_mm_m); +} +void do_blocking_move_to_xy(float x, float y, float fr_mm_m/*=0.0*/) { + do_blocking_move_to(x, y, current_position[Z_AXIS], fr_mm_m); +} + +// +// Prepare to do endstop or probe moves +// with custom feedrates. +// +// - Save current feedrates +// - Reset the rate multiplier +// - Reset the command timeout +// - Enable the endstops (for endstop moves) +// +static void setup_for_endstop_or_probe_move() { + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("setup_for_endstop_or_probe_move", current_position); + #endif + saved_feedrate_mm_m = feedrate_mm_m; + saved_feedrate_percentage = feedrate_percentage; + feedrate_percentage = 100; + refresh_cmd_timeout(); +} + +static void clean_up_after_endstop_or_probe_move() { + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("clean_up_after_endstop_or_probe_move", current_position); + #endif + feedrate_mm_m = saved_feedrate_mm_m; + feedrate_percentage = saved_feedrate_percentage; + refresh_cmd_timeout(); +} + +#if HAS_BED_PROBE + /** + * Raise Z to a minimum height to make room for a probe to move + */ + inline void do_probe_raise(float z_raise) { + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOPAIR("do_probe_raise(", z_raise); + SERIAL_ECHOLNPGM(")"); + } + #endif + float z_dest = LOGICAL_Z_POSITION(z_raise); + if (z_dest > current_position[Z_AXIS]) + do_blocking_move_to_z(z_dest); + } + +#endif //HAS_BED_PROBE + +#if ENABLED(Z_PROBE_ALLEN_KEY) || ENABLED(Z_PROBE_SLED) || ENABLED(Z_SAFE_HOMING) || HAS_PROBING_PROCEDURE || HOTENDS > 1 || ENABLED(NOZZLE_CLEAN_FEATURE) || ENABLED(NOZZLE_PARK_FEATURE) + static bool axis_unhomed_error(const bool x, const bool y, const bool z) { + const bool xx = x && !axis_homed[X_AXIS], + yy = y && !axis_homed[Y_AXIS], + zz = z && !axis_homed[Z_AXIS]; + if (xx || yy || zz) { + SERIAL_ECHO_START; + SERIAL_ECHOPGM(MSG_HOME " "); + if (xx) SERIAL_ECHOPGM(MSG_X); + if (yy) SERIAL_ECHOPGM(MSG_Y); + if (zz) SERIAL_ECHOPGM(MSG_Z); + SERIAL_ECHOLNPGM(" " MSG_FIRST); + + #if ENABLED(ULTRA_LCD) + char message[3 * (LCD_WIDTH) + 1] = ""; // worst case is kana.utf with up to 3*LCD_WIDTH+1 + strcat_P(message, PSTR(MSG_HOME " ")); + if (xx) strcat_P(message, PSTR(MSG_X)); + if (yy) strcat_P(message, PSTR(MSG_Y)); + if (zz) strcat_P(message, PSTR(MSG_Z)); + strcat_P(message, PSTR(" " MSG_FIRST)); + lcd_setstatus(message); + #endif + return true; + } + return false; + } +#endif + +#if ENABLED(Z_PROBE_SLED) + + #ifndef SLED_DOCKING_OFFSET + #define SLED_DOCKING_OFFSET 0 + #endif + + /** + * Method to dock/undock a sled designed by Charles Bell. + * + * stow[in] If false, move to MAX_X and engage the solenoid + * If true, move to MAX_X and release the solenoid + */ + static void dock_sled(bool stow) { + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOPAIR("dock_sled(", stow); + SERIAL_ECHOLNPGM(")"); + } + #endif + + // Dock sled a bit closer to ensure proper capturing + do_blocking_move_to_x(X_MAX_POS + SLED_DOCKING_OFFSET - ((stow) ? 1 : 0)); + + #if PIN_EXISTS(SLED) + digitalWrite(SLED_PIN, !stow); // switch solenoid + #endif + } + +#endif // Z_PROBE_SLED +#if ENABLED(Z_PROBE_ALLEN_KEY) + void run_deploy_moves_script() { + #if defined(Z_PROBE_ALLEN_KEY_DEPLOY_1_X) || defined(Z_PROBE_ALLEN_KEY_DEPLOY_1_Y) || defined(Z_PROBE_ALLEN_KEY_DEPLOY_1_Z) + #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_1_X + #define Z_PROBE_ALLEN_KEY_DEPLOY_1_X current_position[X_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_1_Y + #define Z_PROBE_ALLEN_KEY_DEPLOY_1_Y current_position[Y_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_1_Z + #define Z_PROBE_ALLEN_KEY_DEPLOY_1_Z current_position[Z_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_1_FEEDRATE + #define Z_PROBE_ALLEN_KEY_DEPLOY_1_FEEDRATE 0.0 + #endif + do_blocking_move_to(Z_PROBE_ALLEN_KEY_DEPLOY_1_X, Z_PROBE_ALLEN_KEY_DEPLOY_1_Y, Z_PROBE_ALLEN_KEY_DEPLOY_1_Z, Z_PROBE_ALLEN_KEY_DEPLOY_1_FEEDRATE); + #endif + #if defined(Z_PROBE_ALLEN_KEY_DEPLOY_2_X) || defined(Z_PROBE_ALLEN_KEY_DEPLOY_2_Y) || defined(Z_PROBE_ALLEN_KEY_DEPLOY_2_Z) + #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_2_X + #define Z_PROBE_ALLEN_KEY_DEPLOY_2_X current_position[X_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_2_Y + #define Z_PROBE_ALLEN_KEY_DEPLOY_2_Y current_position[Y_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_2_Z + #define Z_PROBE_ALLEN_KEY_DEPLOY_2_Z current_position[Z_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_2_FEEDRATE + #define Z_PROBE_ALLEN_KEY_DEPLOY_2_FEEDRATE 0.0 + #endif + do_blocking_move_to(Z_PROBE_ALLEN_KEY_DEPLOY_2_X, Z_PROBE_ALLEN_KEY_DEPLOY_2_Y, Z_PROBE_ALLEN_KEY_DEPLOY_2_Z, Z_PROBE_ALLEN_KEY_DEPLOY_2_FEEDRATE); + #endif + #if defined(Z_PROBE_ALLEN_KEY_DEPLOY_3_X) || defined(Z_PROBE_ALLEN_KEY_DEPLOY_3_Y) || defined(Z_PROBE_ALLEN_KEY_DEPLOY_3_Z) + #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_3_X + #define Z_PROBE_ALLEN_KEY_DEPLOY_3_X current_position[X_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_3_Y + #define Z_PROBE_ALLEN_KEY_DEPLOY_3_Y current_position[Y_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_3_Z + #define Z_PROBE_ALLEN_KEY_DEPLOY_3_Z current_position[Z_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_3_FEEDRATE + #define Z_PROBE_ALLEN_KEY_DEPLOY_3_FEEDRATE 0.0 + #endif + do_blocking_move_to(Z_PROBE_ALLEN_KEY_DEPLOY_3_X, Z_PROBE_ALLEN_KEY_DEPLOY_3_Y, Z_PROBE_ALLEN_KEY_DEPLOY_3_Z, Z_PROBE_ALLEN_KEY_DEPLOY_3_FEEDRATE); + #endif + #if defined(Z_PROBE_ALLEN_KEY_DEPLOY_4_X) || defined(Z_PROBE_ALLEN_KEY_DEPLOY_4_Y) || defined(Z_PROBE_ALLEN_KEY_DEPLOY_4_Z) + #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_4_X + #define Z_PROBE_ALLEN_KEY_DEPLOY_4_X current_position[X_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_4_Y + #define Z_PROBE_ALLEN_KEY_DEPLOY_4_Y current_position[Y_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_4_Z + #define Z_PROBE_ALLEN_KEY_DEPLOY_4_Z current_position[Z_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_4_FEEDRATE + #define Z_PROBE_ALLEN_KEY_DEPLOY_4_FEEDRATE 0.0 + #endif + do_blocking_move_to(Z_PROBE_ALLEN_KEY_DEPLOY_4_X, Z_PROBE_ALLEN_KEY_DEPLOY_4_Y, Z_PROBE_ALLEN_KEY_DEPLOY_4_Z, Z_PROBE_ALLEN_KEY_DEPLOY_4_FEEDRATE); + #endif + #if defined(Z_PROBE_ALLEN_KEY_DEPLOY_5_X) || defined(Z_PROBE_ALLEN_KEY_DEPLOY_5_Y) || defined(Z_PROBE_ALLEN_KEY_DEPLOY_5_Z) + #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_5_X + #define Z_PROBE_ALLEN_KEY_DEPLOY_5_X current_position[X_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_5_Y + #define Z_PROBE_ALLEN_KEY_DEPLOY_5_Y current_position[Y_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_5_Z + #define Z_PROBE_ALLEN_KEY_DEPLOY_5_Z current_position[Z_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_5_FEEDRATE + #define Z_PROBE_ALLEN_KEY_DEPLOY_5_FEEDRATE 0.0 + #endif + do_blocking_move_to(Z_PROBE_ALLEN_KEY_DEPLOY_5_X, Z_PROBE_ALLEN_KEY_DEPLOY_5_Y, Z_PROBE_ALLEN_KEY_DEPLOY_5_Z, Z_PROBE_ALLEN_KEY_DEPLOY_5_FEEDRATE); + #endif + } + void run_stow_moves_script() { + #if defined(Z_PROBE_ALLEN_KEY_STOW_1_X) || defined(Z_PROBE_ALLEN_KEY_STOW_1_Y) || defined(Z_PROBE_ALLEN_KEY_STOW_1_Z) + #ifndef Z_PROBE_ALLEN_KEY_STOW_1_X + #define Z_PROBE_ALLEN_KEY_STOW_1_X current_position[X_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_STOW_1_Y + #define Z_PROBE_ALLEN_KEY_STOW_1_Y current_position[Y_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_STOW_1_Z + #define Z_PROBE_ALLEN_KEY_STOW_1_Z current_position[Z_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_STOW_1_FEEDRATE + #define Z_PROBE_ALLEN_KEY_STOW_1_FEEDRATE 0.0 + #endif + do_blocking_move_to(Z_PROBE_ALLEN_KEY_STOW_1_X, Z_PROBE_ALLEN_KEY_STOW_1_Y, Z_PROBE_ALLEN_KEY_STOW_1_Z, Z_PROBE_ALLEN_KEY_STOW_1_FEEDRATE); + #endif + #if defined(Z_PROBE_ALLEN_KEY_STOW_2_X) || defined(Z_PROBE_ALLEN_KEY_STOW_2_Y) || defined(Z_PROBE_ALLEN_KEY_STOW_2_Z) + #ifndef Z_PROBE_ALLEN_KEY_STOW_2_X + #define Z_PROBE_ALLEN_KEY_STOW_2_X current_position[X_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_STOW_2_Y + #define Z_PROBE_ALLEN_KEY_STOW_2_Y current_position[Y_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_STOW_2_Z + #define Z_PROBE_ALLEN_KEY_STOW_2_Z current_position[Z_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_STOW_2_FEEDRATE + #define Z_PROBE_ALLEN_KEY_STOW_2_FEEDRATE 0.0 + #endif + do_blocking_move_to(Z_PROBE_ALLEN_KEY_STOW_2_X, Z_PROBE_ALLEN_KEY_STOW_2_Y, Z_PROBE_ALLEN_KEY_STOW_2_Z, Z_PROBE_ALLEN_KEY_STOW_2_FEEDRATE); + #endif + #if defined(Z_PROBE_ALLEN_KEY_STOW_3_X) || defined(Z_PROBE_ALLEN_KEY_STOW_3_Y) || defined(Z_PROBE_ALLEN_KEY_STOW_3_Z) + #ifndef Z_PROBE_ALLEN_KEY_STOW_3_X + #define Z_PROBE_ALLEN_KEY_STOW_3_X current_position[X_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_STOW_3_Y + #define Z_PROBE_ALLEN_KEY_STOW_3_Y current_position[Y_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_STOW_3_Z + #define Z_PROBE_ALLEN_KEY_STOW_3_Z current_position[Z_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_STOW_3_FEEDRATE + #define Z_PROBE_ALLEN_KEY_STOW_3_FEEDRATE 0.0 + #endif + do_blocking_move_to(Z_PROBE_ALLEN_KEY_STOW_3_X, Z_PROBE_ALLEN_KEY_STOW_3_Y, Z_PROBE_ALLEN_KEY_STOW_3_Z, Z_PROBE_ALLEN_KEY_STOW_3_FEEDRATE); + #endif + #if defined(Z_PROBE_ALLEN_KEY_STOW_4_X) || defined(Z_PROBE_ALLEN_KEY_STOW_4_Y) || defined(Z_PROBE_ALLEN_KEY_STOW_4_Z) + #ifndef Z_PROBE_ALLEN_KEY_STOW_4_X + #define Z_PROBE_ALLEN_KEY_STOW_4_X current_position[X_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_STOW_4_Y + #define Z_PROBE_ALLEN_KEY_STOW_4_Y current_position[Y_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_STOW_4_Z + #define Z_PROBE_ALLEN_KEY_STOW_4_Z current_position[Z_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_STOW_4_FEEDRATE + #define Z_PROBE_ALLEN_KEY_STOW_4_FEEDRATE 0.0 + #endif + do_blocking_move_to(Z_PROBE_ALLEN_KEY_STOW_4_X, Z_PROBE_ALLEN_KEY_STOW_4_Y, Z_PROBE_ALLEN_KEY_STOW_4_Z, Z_PROBE_ALLEN_KEY_STOW_4_FEEDRATE); + #endif + #if defined(Z_PROBE_ALLEN_KEY_STOW_5_X) || defined(Z_PROBE_ALLEN_KEY_STOW_5_Y) || defined(Z_PROBE_ALLEN_KEY_STOW_5_Z) + #ifndef Z_PROBE_ALLEN_KEY_STOW_5_X + #define Z_PROBE_ALLEN_KEY_STOW_5_X current_position[X_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_STOW_5_Y + #define Z_PROBE_ALLEN_KEY_STOW_5_Y current_position[Y_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_STOW_5_Z + #define Z_PROBE_ALLEN_KEY_STOW_5_Z current_position[Z_AXIS] + #endif + #ifndef Z_PROBE_ALLEN_KEY_STOW_5_FEEDRATE + #define Z_PROBE_ALLEN_KEY_STOW_5_FEEDRATE 0.0 + #endif + do_blocking_move_to(Z_PROBE_ALLEN_KEY_STOW_5_X, Z_PROBE_ALLEN_KEY_STOW_5_Y, Z_PROBE_ALLEN_KEY_STOW_5_Z, Z_PROBE_ALLEN_KEY_STOW_5_FEEDRATE); + #endif + } +#endif + +#if HAS_BED_PROBE + + // TRIGGERED_WHEN_STOWED_TEST can easily be extended to servo probes, ... if needed. + #if ENABLED(PROBE_IS_TRIGGERED_WHEN_STOWED_TEST) + #if ENABLED(Z_MIN_PROBE_ENDSTOP) + #define _TRIGGERED_WHEN_STOWED_TEST (READ(Z_MIN_PROBE_PIN) != Z_MIN_PROBE_ENDSTOP_INVERTING) + #else + #define _TRIGGERED_WHEN_STOWED_TEST (READ(Z_MIN_PIN) != Z_MIN_ENDSTOP_INVERTING) + #endif + #endif + + #define DEPLOY_PROBE() set_probe_deployed( true ) + #define STOW_PROBE() set_probe_deployed( false ) + + // returns false for ok and true for failure + static bool set_probe_deployed(bool deploy) { + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + DEBUG_POS("set_probe_deployed", current_position); + SERIAL_ECHOPAIR("deploy: ", deploy); + SERIAL_EOL; + } + #endif + + if (endstops.z_probe_enabled == deploy) return false; + + // Make room for probe + do_probe_raise(_Z_PROBE_DEPLOY_HEIGHT); + + #if ENABLED(Z_PROBE_SLED) + if (axis_unhomed_error(true, false, false)) { stop(); return true; } + #elif ENABLED(Z_PROBE_ALLEN_KEY) + if (axis_unhomed_error(true, true, true )) { stop(); return true; } + #endif + + float oldXpos = current_position[X_AXIS]; // save x position + float oldYpos = current_position[Y_AXIS]; // save y position + + #ifdef _TRIGGERED_WHEN_STOWED_TEST + // If endstop is already false, the Z probe is deployed + if (_TRIGGERED_WHEN_STOWED_TEST == deploy) { // closed after the probe specific actions. + // Would a goto be less ugly? + //while (!_TRIGGERED_WHEN_STOWED_TEST) { idle(); // would offer the opportunity + // for a triggered when stowed manual probe. + #endif + + #if ENABLED(Z_PROBE_SLED) + dock_sled(!deploy); + #elif HAS_Z_SERVO_ENDSTOP + servo[Z_ENDSTOP_SERVO_NR].move(z_servo_angle[((deploy) ? 0 : 1)]); + #elif ENABLED(Z_PROBE_ALLEN_KEY) + if (!deploy) run_stow_moves_script(); + else run_deploy_moves_script(); + #else + // Nothing to be done. Just enable_z_probe below... + #endif + + #ifdef _TRIGGERED_WHEN_STOWED_TEST + }; // opened before the probe specific actions + + if (_TRIGGERED_WHEN_STOWED_TEST == deploy) { + if (IsRunning()) { + SERIAL_ERROR_START; + SERIAL_ERRORLNPGM("Z-Probe failed"); + LCD_ALERTMESSAGEPGM("Err: ZPROBE"); + } + stop(); + return true; + } + #endif + + do_blocking_move_to(oldXpos, oldYpos, current_position[Z_AXIS]); // return to position before deploy + endstops.enable_z_probe( deploy ); + return false; + } + + // Do a single Z probe and return with current_position[Z_AXIS] + // at the height where the probe triggered. + static float run_z_probe() { + + // Prevent stepper_inactive_time from running out and EXTRUDER_RUNOUT_PREVENT from extruding + refresh_cmd_timeout(); + + #if ENABLED(AUTO_BED_LEVELING_FEATURE) + planner.bed_level_matrix.set_to_identity(); + #endif + + #if ENABLED(PROBE_DOUBLE_TOUCH) + do_blocking_move_to_z(-(Z_MAX_LENGTH + 10), Z_PROBE_SPEED_FAST); + endstops.hit_on_purpose(); + set_current_from_steppers_for_axis(Z_AXIS); + SYNC_PLAN_POSITION_KINEMATIC(); + + // move up the retract distance + do_blocking_move_to_z(current_position[Z_AXIS] + home_bump_mm(Z_AXIS), Z_PROBE_SPEED_FAST); + #else + // move fast, close to the bed + do_blocking_move_to_z(home_bump_mm(Z_AXIS), Z_PROBE_SPEED_FAST); + #endif + + // move down slowly to find bed + do_blocking_move_to_z(current_position[Z_AXIS] -2.0*home_bump_mm(Z_AXIS), Z_PROBE_SPEED_SLOW); + endstops.hit_on_purpose(); + set_current_from_steppers_for_axis(Z_AXIS); + SYNC_PLAN_POSITION_KINEMATIC(); + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("run_z_probe", current_position); + #endif + + return current_position[Z_AXIS]; + } + + // + // - Move to the given XY + // - Deploy the probe, if not already deployed + // - Probe the bed, get the Z position + // - Depending on the 'stow' flag + // - Stow the probe, or + // - Raise to the BETWEEN height + // - Return the probed Z position + // + static float probe_pt(float x, float y, bool stow = true, int verbose_level = 1) { + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOPAIR(">>> probe_pt(", x); + SERIAL_ECHOPAIR(", ", y); + SERIAL_ECHOPAIR(", ", stow ? "stow" : "no stow"); + SERIAL_ECHOLNPGM(")"); + DEBUG_POS("", current_position); + } + #endif + + float old_feedrate_mm_m = feedrate_mm_m; + + // Ensure a minimum height before moving the probe + do_probe_raise(Z_PROBE_TRAVEL_HEIGHT); + + // Move to the XY where we shall probe + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOPAIR("> do_blocking_move_to_xy(", x - (X_PROBE_OFFSET_FROM_EXTRUDER)); + SERIAL_ECHOPAIR(", ", y - (Y_PROBE_OFFSET_FROM_EXTRUDER)); + SERIAL_ECHOLNPGM(")"); + } + #endif + feedrate_mm_m = XY_PROBE_FEEDRATE_MM_M; + do_blocking_move_to_xy(x - (X_PROBE_OFFSET_FROM_EXTRUDER), y - (Y_PROBE_OFFSET_FROM_EXTRUDER)); + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) SERIAL_ECHOPGM("> "); + #endif + if (DEPLOY_PROBE()) return NAN; + + float measured_z = run_z_probe(); + + if (stow) { + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) SERIAL_ECHOPGM("> "); + #endif + if (STOW_PROBE()) return NAN; + } + else { + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("> do_probe_raise"); + #endif + do_probe_raise(Z_PROBE_TRAVEL_HEIGHT); + } + + if (verbose_level > 2) { + SERIAL_PROTOCOLPGM("Bed X: "); + SERIAL_PROTOCOL_F(x, 3); + SERIAL_PROTOCOLPGM(" Y: "); + SERIAL_PROTOCOL_F(y, 3); + SERIAL_PROTOCOLPGM(" Z: "); + SERIAL_PROTOCOL_F(measured_z, 3); + SERIAL_EOL; + } + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("<<< probe_pt"); + #endif + + feedrate_mm_m = old_feedrate_mm_m; + + return measured_z; + } + +#endif // HAS_BED_PROBE + +#if ENABLED(AUTO_BED_LEVELING_FEATURE) + + #if ENABLED(AUTO_BED_LEVELING_GRID) + + #if DISABLED(DELTA) + + static void set_bed_level_equation_lsq(double* plane_equation_coefficients) { + + //planner.bed_level_matrix.debug("bed level before"); + + #if ENABLED(DEBUG_LEVELING_FEATURE) + planner.bed_level_matrix.set_to_identity(); + if (DEBUGGING(LEVELING)) { + vector_3 uncorrected_position = planner.adjusted_position(); + DEBUG_POS(">>> set_bed_level_equation_lsq", uncorrected_position); + DEBUG_POS(">>> set_bed_level_equation_lsq", current_position); + } + #endif + + vector_3 planeNormal = vector_3(-plane_equation_coefficients[0], -plane_equation_coefficients[1], 1); + planner.bed_level_matrix = matrix_3x3::create_look_at(planeNormal); + + vector_3 corrected_position = planner.adjusted_position(); + current_position[X_AXIS] = corrected_position.x; + current_position[Y_AXIS] = corrected_position.y; + current_position[Z_AXIS] = corrected_position.z; + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("<<< set_bed_level_equation_lsq", corrected_position); + #endif + + SYNC_PLAN_POSITION_KINEMATIC(); + } + + #endif // !DELTA + + #else // !AUTO_BED_LEVELING_GRID + + static void set_bed_level_equation_3pts(float z_at_pt_1, float z_at_pt_2, float z_at_pt_3) { + + planner.bed_level_matrix.set_to_identity(); + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + vector_3 uncorrected_position = planner.adjusted_position(); + DEBUG_POS("set_bed_level_equation_3pts", uncorrected_position); + } + #endif + + vector_3 pt1 = vector_3(ABL_PROBE_PT_1_X, ABL_PROBE_PT_1_Y, z_at_pt_1); + vector_3 pt2 = vector_3(ABL_PROBE_PT_2_X, ABL_PROBE_PT_2_Y, z_at_pt_2); + vector_3 pt3 = vector_3(ABL_PROBE_PT_3_X, ABL_PROBE_PT_3_Y, z_at_pt_3); + vector_3 planeNormal = vector_3::cross(pt1 - pt2, pt3 - pt2).get_normal(); + + if (planeNormal.z < 0) { + planeNormal.x = -planeNormal.x; + planeNormal.y = -planeNormal.y; + planeNormal.z = -planeNormal.z; + } + + planner.bed_level_matrix = matrix_3x3::create_look_at(planeNormal); + vector_3 corrected_position = planner.adjusted_position(); + + current_position[X_AXIS] = corrected_position.x; + current_position[Y_AXIS] = corrected_position.y; + current_position[Z_AXIS] = corrected_position.z; + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("set_bed_level_equation_3pts", corrected_position); + #endif + + SYNC_PLAN_POSITION_KINEMATIC(); + } + + #endif // !AUTO_BED_LEVELING_GRID + + #if ENABLED(DELTA) + + /** + * All DELTA leveling in the Marlin uses NONLINEAR_BED_LEVELING + */ + static void extrapolate_one_point(int x, int y, int xdir, int ydir) { + if (bed_level[x][y] != 0.0) { + return; // Don't overwrite good values. + } + float a = 2 * bed_level[x + xdir][y] - bed_level[x + xdir * 2][y]; // Left to right. + float b = 2 * bed_level[x][y + ydir] - bed_level[x][y + ydir * 2]; // Front to back. + float c = 2 * bed_level[x + xdir][y + ydir] - bed_level[x + xdir * 2][y + ydir * 2]; // Diagonal. + float median = c; // Median is robust (ignores outliers). + if (a < b) { + if (b < c) median = b; + if (c < a) median = a; + } + else { // b <= a + if (c < b) median = b; + if (a < c) median = a; + } + bed_level[x][y] = median; + } + + /** + * Fill in the unprobed points (corners of circular print surface) + * using linear extrapolation, away from the center. + */ + static void extrapolate_unprobed_bed_level() { + int half = (AUTO_BED_LEVELING_GRID_POINTS - 1) / 2; + for (int y = 0; y <= half; y++) { + for (int x = 0; x <= half; x++) { + if (x + y < 3) continue; + extrapolate_one_point(half - x, half - y, x > 1 ? +1 : 0, y > 1 ? +1 : 0); + extrapolate_one_point(half + x, half - y, x > 1 ? -1 : 0, y > 1 ? +1 : 0); + extrapolate_one_point(half - x, half + y, x > 1 ? +1 : 0, y > 1 ? -1 : 0); + extrapolate_one_point(half + x, half + y, x > 1 ? -1 : 0, y > 1 ? -1 : 0); + } + } + } + + /** + * Print calibration results for plotting or manual frame adjustment. + */ + static void print_bed_level() { + for (int y = 0; y < AUTO_BED_LEVELING_GRID_POINTS; y++) { + for (int x = 0; x < AUTO_BED_LEVELING_GRID_POINTS; x++) { + SERIAL_PROTOCOL_F(bed_level[x][y], 2); + SERIAL_PROTOCOLCHAR(' '); + } + SERIAL_EOL; + } + } + + /** + * Reset calibration results to zero. + */ + void reset_bed_level() { + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("reset_bed_level"); + #endif + for (int y = 0; y < AUTO_BED_LEVELING_GRID_POINTS; y++) { + for (int x = 0; x < AUTO_BED_LEVELING_GRID_POINTS; x++) { + bed_level[x][y] = 0.0; + } + } + } + + #endif // DELTA + +#endif // AUTO_BED_LEVELING_FEATURE + +/** + * Home an individual axis + */ + +#define HOMEAXIS(LETTER) homeaxis(LETTER##_AXIS) + +static void homeaxis(AxisEnum axis) { + #define HOMEAXIS_DO(LETTER) \ + ((LETTER##_MIN_PIN > -1 && LETTER##_HOME_DIR==-1) || (LETTER##_MAX_PIN > -1 && LETTER##_HOME_DIR==1)) + + if (!(axis == X_AXIS ? HOMEAXIS_DO(X) : axis == Y_AXIS ? HOMEAXIS_DO(Y) : axis == Z_AXIS ? HOMEAXIS_DO(Z) : 0)) return; + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOPAIR(">>> homeaxis(", axis); + SERIAL_ECHOLNPGM(")"); + } + #endif + + int axis_home_dir = + #if ENABLED(DUAL_X_CARRIAGE) + (axis == X_AXIS) ? x_home_dir(active_extruder) : + #endif + home_dir(axis); + + // Homing Z towards the bed? Deploy the Z probe or endstop. + #if HAS_BED_PROBE && DISABLED(Z_MIN_PROBE_ENDSTOP) + if (axis == Z_AXIS && axis_home_dir < 0) { + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) SERIAL_ECHOPGM("> "); + #endif + if (DEPLOY_PROBE()) return; + } + #endif + + // Set the axis position as setup for the move + current_position[axis] = 0; + sync_plan_position(); + + // Set a flag for Z motor locking + #if ENABLED(Z_DUAL_ENDSTOPS) + if (axis == Z_AXIS) stepper.set_homing_flag(true); + #endif + + // Move towards the endstop until an endstop is triggered + line_to_axis_pos(axis, 1.5 * max_length(axis) * axis_home_dir); + + // Set the axis position as setup for the move + current_position[axis] = 0; + sync_plan_position(); + + // Move away from the endstop by the axis HOME_BUMP_MM + line_to_axis_pos(axis, -home_bump_mm(axis) * axis_home_dir); + + // Move slowly towards the endstop until triggered + line_to_axis_pos(axis, 2 * home_bump_mm(axis) * axis_home_dir, get_homing_bump_feedrate(axis)); + + // reset current_position to 0 to reflect hitting endpoint + current_position[axis] = 0; + sync_plan_position(); + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("> TRIGGER ENDSTOP", current_position); + #endif + + #if ENABLED(Z_DUAL_ENDSTOPS) + if (axis == Z_AXIS) { + float adj = fabs(z_endstop_adj); + bool lockZ1; + if (axis_home_dir > 0) { + adj = -adj; + lockZ1 = (z_endstop_adj > 0); + } + else + lockZ1 = (z_endstop_adj < 0); + + if (lockZ1) stepper.set_z_lock(true); else stepper.set_z2_lock(true); + + // Move to the adjusted endstop height + line_to_axis_pos(axis, adj); + + if (lockZ1) stepper.set_z_lock(false); else stepper.set_z2_lock(false); + stepper.set_homing_flag(false); + } // Z_AXIS + #endif + + #if ENABLED(DELTA) + // retrace by the amount specified in endstop_adj + if (endstop_adj[axis] * axis_home_dir < 0) { + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOPAIR("> endstop_adj = ", endstop_adj[axis]); + DEBUG_POS("", current_position); + } + #endif + line_to_axis_pos(axis, endstop_adj[axis]); + } + #endif + + // Set the axis position to its home position (plus home offsets) + set_axis_is_at_home(axis); + + SYNC_PLAN_POSITION_KINEMATIC(); + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("> AFTER set_axis_is_at_home", current_position); + #endif + + destination[axis] = current_position[axis]; + endstops.hit_on_purpose(); // clear endstop hit flags + axis_known_position[axis] = true; + axis_homed[axis] = true; + + // Put away the Z probe + #if HAS_BED_PROBE && DISABLED(Z_MIN_PROBE_ENDSTOP) + if (axis == Z_AXIS && axis_home_dir < 0) { + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) SERIAL_ECHOPGM("> "); + #endif + if (STOW_PROBE()) return; + } + #endif + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOPAIR("<<< homeaxis(", axis); + SERIAL_ECHOLNPGM(")"); + } + #endif +} + +#if ENABLED(FWRETRACT) + + void retract(bool retracting, bool swapping = false) { + + if (retracting == retracted[active_extruder]) return; + + float old_feedrate_mm_m = feedrate_mm_m; + + set_destination_to_current(); + + if (retracting) { + + feedrate_mm_m = MMS_TO_MMM(retract_feedrate_mm_s); + current_position[E_AXIS] += (swapping ? retract_length_swap : retract_length) / volumetric_multiplier[active_extruder]; + sync_plan_position_e(); + prepare_move_to_destination(); + + if (retract_zlift > 0.01) { + current_position[Z_AXIS] -= retract_zlift; + SYNC_PLAN_POSITION_KINEMATIC(); + prepare_move_to_destination(); + } + } + else { + + if (retract_zlift > 0.01) { + current_position[Z_AXIS] += retract_zlift; + SYNC_PLAN_POSITION_KINEMATIC(); + } + + feedrate_mm_m = MMS_TO_MMM(retract_recover_feedrate_mm_s); + float move_e = swapping ? retract_length_swap + retract_recover_length_swap : retract_length + retract_recover_length; + current_position[E_AXIS] -= move_e / volumetric_multiplier[active_extruder]; + sync_plan_position_e(); + prepare_move_to_destination(); + } + + feedrate_mm_m = old_feedrate_mm_m; + retracted[active_extruder] = retracting; + + } // retract() + +#endif // FWRETRACT + +#if ENABLED(MIXING_EXTRUDER) + + void normalize_mix() { + float mix_total = 0.0; + for (int i = 0; i < MIXING_STEPPERS; i++) { + float v = mixing_factor[i]; + if (v < 0) v = mixing_factor[i] = 0; + mix_total += v; + } + // Scale all values if they don't add up to ~1.0 + if (mix_total < 0.9999 || mix_total > 1.0001) { + SERIAL_PROTOCOLLNPGM("Warning: Mix factors must add up to 1.0. Scaling."); + float mix_scale = 1.0 / mix_total; + for (int i = 0; i < MIXING_STEPPERS; i++) + mixing_factor[i] *= mix_scale; + } + } + + #if ENABLED(DIRECT_MIXING_IN_G1) + // Get mixing parameters from the GCode + // Factors that are left out are set to 0 + // The total "must" be 1.0 (but it will be normalized) + void gcode_get_mix() { + const char* mixing_codes = "ABCDHI"; + for (int i = 0; i < MIXING_STEPPERS; i++) + mixing_factor[i] = code_seen(mixing_codes[i]) ? code_value_float() : 0; + + normalize_mix(); + } + #endif + +#endif + +/** + * *************************************************************************** + * ***************************** G-CODE HANDLING ***************************** + * *************************************************************************** + */ + +/** + * Set XYZE destination and feedrate from the current GCode command + * + * - Set destination from included axis codes + * - Set to current for missing axis codes + * - Set the feedrate, if included + */ +void gcode_get_destination() { + LOOP_XYZE(i) { + if (code_seen(axis_codes[i])) + destination[i] = code_value_axis_units(i) + (axis_relative_modes[i] || relative_mode ? current_position[i] : 0); + else + destination[i] = current_position[i]; + } + + if (code_seen('F') && code_value_linear_units() > 0.0) + feedrate_mm_m = code_value_linear_units(); + + #if ENABLED(PRINTCOUNTER) + if (!DEBUGGING(DRYRUN)) + print_job_timer.incFilamentUsed(destination[E_AXIS] - current_position[E_AXIS]); + #endif + + // Get ABCDHI mixing factors + #if ENABLED(MIXING_EXTRUDER) && ENABLED(DIRECT_MIXING_IN_G1) + gcode_get_mix(); + #endif +} + +void unknown_command_error() { + SERIAL_ECHO_START; + SERIAL_ECHOPGM(MSG_UNKNOWN_COMMAND); + SERIAL_ECHO(current_command); + SERIAL_ECHOLNPGM("\""); +} + +#if ENABLED(HOST_KEEPALIVE_FEATURE) + + /** + * Output a "busy" message at regular intervals + * while the machine is not accepting commands. + */ + void host_keepalive() { + millis_t ms = millis(); + if (host_keepalive_interval && busy_state != NOT_BUSY) { + if (PENDING(ms, next_busy_signal_ms)) return; + switch (busy_state) { + case IN_HANDLER: + case IN_PROCESS: + SERIAL_ECHO_START; + SERIAL_ECHOLNPGM(MSG_BUSY_PROCESSING); + break; + case PAUSED_FOR_USER: + SERIAL_ECHO_START; + SERIAL_ECHOLNPGM(MSG_BUSY_PAUSED_FOR_USER); + break; + case PAUSED_FOR_INPUT: + SERIAL_ECHO_START; + SERIAL_ECHOLNPGM(MSG_BUSY_PAUSED_FOR_INPUT); + break; + default: + break; + } + } + next_busy_signal_ms = ms + host_keepalive_interval * 1000UL; + } + +#endif //HOST_KEEPALIVE_FEATURE + +/** + * G0, G1: Coordinated movement of X Y Z E axes + */ +inline void gcode_G0_G1() { + if (IsRunning()) { + gcode_get_destination(); // For X Y Z E F + + #if ENABLED(FWRETRACT) + + if (autoretract_enabled && !(code_seen('X') || code_seen('Y') || code_seen('Z')) && code_seen('E')) { + float echange = destination[E_AXIS] - current_position[E_AXIS]; + // Is this move an attempt to retract or recover? + if ((echange < -MIN_RETRACT && !retracted[active_extruder]) || (echange > MIN_RETRACT && retracted[active_extruder])) { + current_position[E_AXIS] = destination[E_AXIS]; // hide the slicer-generated retract/recover from calculations + sync_plan_position_e(); // AND from the planner + retract(!retracted[active_extruder]); + return; + } + } + + #endif //FWRETRACT + + prepare_move_to_destination(); + } +} + +/** + * G2: Clockwise Arc + * G3: Counterclockwise Arc + */ +#if ENABLED(ARC_SUPPORT) + inline void gcode_G2_G3(bool clockwise) { + if (IsRunning()) { + + #if ENABLED(SF_ARC_FIX) + bool relative_mode_backup = relative_mode; + relative_mode = true; + #endif + + gcode_get_destination(); + + #if ENABLED(SF_ARC_FIX) + relative_mode = relative_mode_backup; + #endif + + // Center of arc as offset from current_position + float arc_offset[2] = { + code_seen('I') ? code_value_axis_units(X_AXIS) : 0, + code_seen('J') ? code_value_axis_units(Y_AXIS) : 0 + }; + + // Send an arc to the planner + plan_arc(destination, arc_offset, clockwise); + + refresh_cmd_timeout(); + } + } +#endif + +/** + * G4: Dwell S or P + */ +inline void gcode_G4() { + millis_t dwell_ms = 0; + + if (code_seen('P')) dwell_ms = code_value_millis(); // milliseconds to wait + if (code_seen('S')) dwell_ms = code_value_millis_from_seconds(); // seconds to wait + + stepper.synchronize(); + refresh_cmd_timeout(); + dwell_ms += previous_cmd_ms; // keep track of when we started waiting + + if (!lcd_hasstatus()) LCD_MESSAGEPGM(MSG_DWELL); + + while (PENDING(millis(), dwell_ms)) idle(); +} + +#if ENABLED(BEZIER_CURVE_SUPPORT) + + /** + * Parameters interpreted according to: + * http://linuxcnc.org/docs/2.6/html/gcode/gcode.html#sec:G5-Cubic-Spline + * However I, J omission is not supported at this point; all + * parameters can be omitted and default to zero. + */ + + /** + * G5: Cubic B-spline + */ + inline void gcode_G5() { + if (IsRunning()) { + + gcode_get_destination(); + + float offset[] = { + code_seen('I') ? code_value_axis_units(X_AXIS) : 0.0, + code_seen('J') ? code_value_axis_units(Y_AXIS) : 0.0, + code_seen('P') ? code_value_axis_units(X_AXIS) : 0.0, + code_seen('Q') ? code_value_axis_units(Y_AXIS) : 0.0 + }; + + plan_cubic_move(offset); + } + } + +#endif // BEZIER_CURVE_SUPPORT + +#if ENABLED(FWRETRACT) + + /** + * G10 - Retract filament according to settings of M207 + * G11 - Recover filament according to settings of M208 + */ + inline void gcode_G10_G11(bool doRetract=false) { + #if EXTRUDERS > 1 + if (doRetract) { + retracted_swap[active_extruder] = (code_seen('S') && code_value_bool()); // checks for swap retract argument + } + #endif + retract(doRetract + #if EXTRUDERS > 1 + , retracted_swap[active_extruder] + #endif + ); + } + +#endif //FWRETRACT + +#if ENABLED(NOZZLE_CLEAN_FEATURE) + /** + * G12: Clean the nozzle + */ + inline void gcode_G12() { + // Don't allow nozzle cleaning without homing first + if (axis_unhomed_error(true, true, true)) { return; } + + uint8_t const pattern = code_seen('P') ? code_value_ushort() : 0; + uint8_t const strokes = code_seen('S') ? code_value_ushort() : NOZZLE_CLEAN_STROKES; + uint8_t const objects = code_seen('T') ? code_value_ushort() : 3; + + Nozzle::clean(pattern, strokes, objects); + } +#endif + +#if ENABLED(INCH_MODE_SUPPORT) + /** + * G20: Set input mode to inches + */ + inline void gcode_G20() { + set_input_linear_units(LINEARUNIT_INCH); + } + + /** + * G21: Set input mode to millimeters + */ + inline void gcode_G21() { + set_input_linear_units(LINEARUNIT_MM); + } +#endif + +#if ENABLED(NOZZLE_PARK_FEATURE) + /** + * G27: Park the nozzle + */ + inline void gcode_G27() { + // Don't allow nozzle parking without homing first + if (axis_unhomed_error(true, true, true)) { return; } + uint8_t const z_action = code_seen('P') ? code_value_ushort() : 0; + Nozzle::park(z_action); + } +#endif // NOZZLE_PARK_FEATURE + +#if ENABLED(QUICK_HOME) + + static void quick_home_xy() { + + // Pretend the current position is 0,0 + current_position[X_AXIS] = current_position[Y_AXIS] = 0.0; + sync_plan_position(); + + int x_axis_home_dir = + #if ENABLED(DUAL_X_CARRIAGE) + x_home_dir(active_extruder) + #else + home_dir(X_AXIS) + #endif + ; + + float mlx = max_length(X_AXIS), + mly = max_length(Y_AXIS), + mlratio = mlx > mly ? mly / mlx : mlx / mly, + fr_mm_m = min(homing_feedrate_mm_m[X_AXIS], homing_feedrate_mm_m[Y_AXIS]) * sqrt(sq(mlratio) + 1.0); + + do_blocking_move_to_xy(1.5 * mlx * x_axis_home_dir, 1.5 * mly * home_dir(Y_AXIS), fr_mm_m); + endstops.hit_on_purpose(); // clear endstop hit flags + current_position[X_AXIS] = current_position[Y_AXIS] = 0.0; + + } + +#endif // QUICK_HOME + +/** + * G28: Home all axes according to settings + * + * Parameters + * + * None Home to all axes with no parameters. + * With QUICK_HOME enabled XY will home together, then Z. + * + * Cartesian parameters + * + * X Home to the X endstop + * Y Home to the Y endstop + * Z Home to the Z endstop + * + */ +inline void gcode_G28() { + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM(">>> gcode_G28"); + #endif + + // Wait for planner moves to finish! + stepper.synchronize(); + + // For auto bed leveling, clear the level matrix + #if ENABLED(AUTO_BED_LEVELING_FEATURE) + planner.bed_level_matrix.set_to_identity(); + #if ENABLED(DELTA) + reset_bed_level(); + #endif + #endif + + // Always home with tool 0 active + #if HOTENDS > 1 + uint8_t old_tool_index = active_extruder; + tool_change(0, 0, true); + #endif + + #if ENABLED(DUAL_X_CARRIAGE) || ENABLED(DUAL_NOZZLE_DUPLICATION_MODE) + extruder_duplication_enabled = false; + #endif + + /** + * For mesh bed leveling deactivate the mesh calculations, will be turned + * on again when homing all axis + */ + #if ENABLED(MESH_BED_LEVELING) + float pre_home_z = MESH_HOME_SEARCH_Z; + if (mbl.active()) { + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("MBL was active"); + #endif + // Save known Z position if already homed + if (axis_homed[X_AXIS] && axis_homed[Y_AXIS] && axis_homed[Z_AXIS]) { + pre_home_z = current_position[Z_AXIS]; + pre_home_z += mbl.get_z(RAW_CURRENT_POSITION(X_AXIS), RAW_CURRENT_POSITION(Y_AXIS)); + } + mbl.set_active(false); + current_position[Z_AXIS] = pre_home_z; + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("Set Z to pre_home_z", current_position); + #endif + } + #endif + + setup_for_endstop_or_probe_move(); + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("> endstops.enable(true)"); + #endif + endstops.enable(true); // Enable endstops for next homing move + + + #if ENABLED(DELTA) + /** + * A delta can only safely home all axes at the same time + */ + + // Pretend the current position is 0,0,0 + // This is like quick_home_xy() but for 3 towers. + current_position[X_AXIS] = current_position[Y_AXIS] = current_position[Z_AXIS] = 0.0; + sync_plan_position(); + + // Move all carriages up together until the first endstop is hit. + current_position[X_AXIS] = current_position[Y_AXIS] = current_position[Z_AXIS] = 3.0 * (Z_MAX_LENGTH); + feedrate_mm_m = 1.732 * homing_feedrate_mm_m[X_AXIS]; + line_to_current_position(); + stepper.synchronize(); + endstops.hit_on_purpose(); // clear endstop hit flags + current_position[X_AXIS] = current_position[Y_AXIS] = current_position[Z_AXIS] = 0.0; + + // take care of back off and rehome. Now one carriage is at the top. + HOMEAXIS(X); + HOMEAXIS(Y); + HOMEAXIS(Z); + + SYNC_PLAN_POSITION_KINEMATIC(); + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("(DELTA)", current_position); + #endif + + #else // NOT DELTA + + bool homeX = code_seen('X'), homeY = code_seen('Y'), homeZ = code_seen('Z'); + + home_all_axis = (!homeX && !homeY && !homeZ) || (homeX && homeY && homeZ); + + set_destination_to_current(); + + #if Z_HOME_DIR > 0 // If homing away from BED do Z first + + if (home_all_axis || homeZ) { + HOMEAXIS(Z); + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("> HOMEAXIS(Z)", current_position); + #endif + } + + #else + + if (home_all_axis || homeX || homeY) { + // Raise Z before homing any other axes and z is not already high enough (never lower z) + destination[Z_AXIS] = LOGICAL_Z_POSITION(Z_HOMING_HEIGHT); + if (destination[Z_AXIS] > current_position[Z_AXIS]) { + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOPAIR("Raise Z (before homing) to ", destination[Z_AXIS]); + SERIAL_EOL; + } + #endif + + do_blocking_move_to_z(destination[Z_AXIS]); + } + } + + #endif + + #if ENABLED(QUICK_HOME) + + if (home_all_axis || (homeX && homeY)) quick_home_xy(); + + #endif + + #if ENABLED(HOME_Y_BEFORE_X) + + // Home Y + if (home_all_axis || homeY) { + HOMEAXIS(Y); + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("> homeY", current_position); + #endif + } + + #endif + + // Home X + if (home_all_axis || homeX) { + #if ENABLED(DUAL_X_CARRIAGE) + int tmp_extruder = active_extruder; + active_extruder = !active_extruder; + HOMEAXIS(X); + inactive_extruder_x_pos = RAW_X_POSITION(current_position[X_AXIS]); + active_extruder = tmp_extruder; + HOMEAXIS(X); + // reset state used by the different modes + memcpy(raised_parked_position, current_position, sizeof(raised_parked_position)); + delayed_move_time = 0; + active_extruder_parked = true; + #else + HOMEAXIS(X); + #endif + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("> homeX", current_position); + #endif + } + + #if DISABLED(HOME_Y_BEFORE_X) + // Home Y + if (home_all_axis || homeY) { + HOMEAXIS(Y); + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("> homeY", current_position); + #endif + } + #endif + + // Home Z last if homing towards the bed + #if Z_HOME_DIR < 0 + + if (home_all_axis || homeZ) { + + #if ENABLED(Z_SAFE_HOMING) + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOLNPGM("> Z_SAFE_HOMING >>>"); + } + #endif + + if (home_all_axis) { + + /** + * At this point we already have Z at Z_HOMING_HEIGHT height + * No need to move Z any more as this height should already be safe + * enough to reach Z_SAFE_HOMING XY positions. + * Just make sure the planner is in sync. + */ + SYNC_PLAN_POSITION_KINEMATIC(); + + /** + * Move the Z probe (or just the nozzle) to the safe homing point + */ + destination[X_AXIS] = round(Z_SAFE_HOMING_X_POINT - (X_PROBE_OFFSET_FROM_EXTRUDER)); + destination[Y_AXIS] = round(Z_SAFE_HOMING_Y_POINT - (Y_PROBE_OFFSET_FROM_EXTRUDER)); + destination[Z_AXIS] = current_position[Z_AXIS]; // Z is already at the right height + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + DEBUG_POS("> Z_SAFE_HOMING > home_all_axis", current_position); + DEBUG_POS("> Z_SAFE_HOMING > home_all_axis", destination); + } + #endif + + // Move in the XY plane + do_blocking_move_to_xy(destination[X_AXIS], destination[Y_AXIS]); + } + + // Let's see if X and Y are homed + if (axis_unhomed_error(true, true, false)) return; + + /** + * Make sure the Z probe is within the physical limits + * NOTE: This doesn't necessarily ensure the Z probe is also + * within the bed! + */ + float cpx = RAW_CURRENT_POSITION(X_AXIS), cpy = RAW_CURRENT_POSITION(Y_AXIS); + if ( cpx >= X_MIN_POS - (X_PROBE_OFFSET_FROM_EXTRUDER) + && cpx <= X_MAX_POS - (X_PROBE_OFFSET_FROM_EXTRUDER) + && cpy >= Y_MIN_POS - (Y_PROBE_OFFSET_FROM_EXTRUDER) + && cpy <= Y_MAX_POS - (Y_PROBE_OFFSET_FROM_EXTRUDER)) { + + // Home the Z axis + HOMEAXIS(Z); + } + else { + LCD_MESSAGEPGM(MSG_ZPROBE_OUT); + SERIAL_ECHO_START; + SERIAL_ECHOLNPGM(MSG_ZPROBE_OUT); + } + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOLNPGM("<<< Z_SAFE_HOMING"); + } + #endif + + #else // !Z_SAFE_HOMING + + HOMEAXIS(Z); + + #endif // !Z_SAFE_HOMING + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("> (home_all_axis || homeZ) > final", current_position); + #endif + + } // home_all_axis || homeZ + + #endif // Z_HOME_DIR < 0 + + SYNC_PLAN_POSITION_KINEMATIC(); + + #endif // !DELTA (gcode_G28) + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("> endstops.not_homing()"); + #endif + endstops.not_homing(); + endstops.hit_on_purpose(); // clear endstop hit flags + + // Enable mesh leveling again + #if ENABLED(MESH_BED_LEVELING) + if (mbl.has_mesh()) { + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("MBL has mesh"); + #endif + if (home_all_axis || (axis_homed[X_AXIS] && axis_homed[Y_AXIS] && homeZ)) { + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("MBL Z homing"); + #endif + current_position[Z_AXIS] = MESH_HOME_SEARCH_Z + #if Z_HOME_DIR > 0 + + Z_MAX_POS + #endif + ; + SYNC_PLAN_POSITION_KINEMATIC(); + mbl.set_active(true); + #if ENABLED(MESH_G28_REST_ORIGIN) + current_position[Z_AXIS] = 0.0; + set_destination_to_current(); + feedrate_mm_m = homing_feedrate_mm_m[Z_AXIS]; + line_to_destination(); + stepper.synchronize(); + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("MBL Rest Origin", current_position); + #endif + #else + current_position[Z_AXIS] = MESH_HOME_SEARCH_Z - + mbl.get_z(RAW_CURRENT_POSITION(X_AXIS), RAW_CURRENT_POSITION(Y_AXIS)) + #if Z_HOME_DIR > 0 + + Z_MAX_POS + #endif + ; + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("MBL adjusted MESH_HOME_SEARCH_Z", current_position); + #endif + #endif + } + else if ((axis_homed[X_AXIS] && axis_homed[Y_AXIS] && axis_homed[Z_AXIS]) && (homeX || homeY)) { + current_position[Z_AXIS] = pre_home_z; + SYNC_PLAN_POSITION_KINEMATIC(); + mbl.set_active(true); + current_position[Z_AXIS] = pre_home_z - + mbl.get_z(RAW_CURRENT_POSITION(X_AXIS), RAW_CURRENT_POSITION(Y_AXIS)); + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("MBL Home X or Y", current_position); + #endif + } + } + #endif + + #if ENABLED(DELTA) + // move to a height where we can use the full xy-area + do_blocking_move_to_z(delta_clip_start_height); + #endif + + clean_up_after_endstop_or_probe_move(); + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("<<< gcode_G28"); + #endif + + // Restore the active tool after homing + #if HOTENDS > 1 + tool_change(old_tool_index, 0, true); + #endif + + report_current_position(); +} + +#if HAS_PROBING_PROCEDURE + + void out_of_range_error(const char* p_edge) { + SERIAL_PROTOCOLPGM("?Probe "); + serialprintPGM(p_edge); + SERIAL_PROTOCOLLNPGM(" position out of range."); + } + +#endif + +#if ENABLED(MESH_BED_LEVELING) + inline void _mbl_goto_xy(float x, float y) { + float old_feedrate_mm_m = feedrate_mm_m; + feedrate_mm_m = homing_feedrate_mm_m[X_AXIS]; + + current_position[Z_AXIS] = MESH_HOME_SEARCH_Z + #if Z_PROBE_TRAVEL_HEIGHT > Z_HOMING_HEIGHT + + Z_PROBE_TRAVEL_HEIGHT + #elif Z_HOMING_HEIGHT > 0 + + Z_HOMING_HEIGHT + #endif + ; + line_to_current_position(); + + current_position[X_AXIS] = LOGICAL_X_POSITION(x); + current_position[Y_AXIS] = LOGICAL_Y_POSITION(y); + line_to_current_position(); + + #if Z_PROBE_TRAVEL_HEIGHT > 0 || Z_HOMING_HEIGHT > 0 + current_position[Z_AXIS] = LOGICAL_Z_POSITION(MESH_HOME_SEARCH_Z); + line_to_current_position(); + #endif + + feedrate_mm_m = old_feedrate_mm_m; + stepper.synchronize(); + } + + /** + * G29: Mesh-based Z probe, probes a grid and produces a + * mesh to compensate for variable bed height + * + * Parameters With MESH_BED_LEVELING: + * + * S0 Produce a mesh report + * S1 Start probing mesh points + * S2 Probe the next mesh point + * S3 Xn Yn 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 + * + * The S0 report the points as below + * + * +----> X-axis 1-n + * | + * | + * v Y-axis 1-n + * + */ + inline void gcode_G29() { + + static int probe_point = -1; + MeshLevelingState state = code_seen('S') ? (MeshLevelingState)code_value_byte() : MeshReport; + if (state < 0 || state > 5) { + SERIAL_PROTOCOLLNPGM("S out of range (0-5)."); + return; + } + + int8_t px, py; + + switch (state) { + case MeshReport: + if (mbl.has_mesh()) { + SERIAL_PROTOCOLPAIR("State: ", mbl.active() ? "On" : "Off"); + SERIAL_PROTOCOLPAIR("\nNum X,Y: ", MESH_NUM_X_POINTS); + SERIAL_PROTOCOLCHAR(','); SERIAL_PROTOCOL(MESH_NUM_Y_POINTS); + SERIAL_PROTOCOLPAIR("\nZ search height: ", MESH_HOME_SEARCH_Z); + SERIAL_PROTOCOLPGM("\nZ offset: "); SERIAL_PROTOCOL_F(mbl.z_offset, 5); + SERIAL_PROTOCOLLNPGM("\nMeasured points:"); + for (py = 0; py < MESH_NUM_Y_POINTS; py++) { + for (px = 0; px < MESH_NUM_X_POINTS; px++) { + SERIAL_PROTOCOLPGM(" "); + SERIAL_PROTOCOL_F(mbl.z_values[py][px], 5); + } + SERIAL_EOL; + } + } + else + SERIAL_PROTOCOLLNPGM("Mesh bed leveling not active."); + break; + + case MeshStart: + mbl.reset(); + probe_point = 0; + enqueue_and_echo_commands_P(PSTR("G28\nG29 S2")); + break; + + case MeshNext: + if (probe_point < 0) { + SERIAL_PROTOCOLLNPGM("Start mesh probing with \"G29 S1\" first."); + return; + } + // For each G29 S2... + if (probe_point == 0) { + // For the initial G29 S2 make Z a positive value (e.g., 4.0) + current_position[Z_AXIS] = MESH_HOME_SEARCH_Z + #if Z_HOME_DIR > 0 + + Z_MAX_POS + #endif + ; + SYNC_PLAN_POSITION_KINEMATIC(); + } + else { + // For G29 S2 after adjusting Z. + mbl.set_zigzag_z(probe_point - 1, current_position[Z_AXIS]); + } + // If there's another point to sample, move there with optional lift. + if (probe_point < (MESH_NUM_X_POINTS) * (MESH_NUM_Y_POINTS)) { + mbl.zigzag(probe_point, px, py); + _mbl_goto_xy(mbl.get_probe_x(px), mbl.get_probe_y(py)); + probe_point++; + } + else { + // One last "return to the bed" (as originally coded) at completion + current_position[Z_AXIS] = MESH_HOME_SEARCH_Z + #if Z_PROBE_TRAVEL_HEIGHT > Z_HOMING_HEIGHT + + Z_PROBE_TRAVEL_HEIGHT + #elif Z_HOMING_HEIGHT > 0 + + Z_HOMING_HEIGHT + #endif + ; + line_to_current_position(); + stepper.synchronize(); + + // After recording the last point, activate the mbl and home + SERIAL_PROTOCOLLNPGM("Mesh probing done."); + probe_point = -1; + mbl.set_has_mesh(true); + enqueue_and_echo_commands_P(PSTR("G28")); + } + break; + + case MeshSet: + if (code_seen('X')) { + px = code_value_int() - 1; + if (px < 0 || px >= MESH_NUM_X_POINTS) { + SERIAL_PROTOCOLLNPGM("X out of range (1-" STRINGIFY(MESH_NUM_X_POINTS) ")."); + return; + } + } + else { + SERIAL_PROTOCOLLNPGM("X not entered."); + return; + } + if (code_seen('Y')) { + py = code_value_int() - 1; + if (py < 0 || py >= MESH_NUM_Y_POINTS) { + SERIAL_PROTOCOLLNPGM("Y out of range (1-" STRINGIFY(MESH_NUM_Y_POINTS) ")."); + return; + } + } + else { + SERIAL_PROTOCOLLNPGM("Y not entered."); + return; + } + if (code_seen('Z')) { + mbl.z_values[py][px] = code_value_axis_units(Z_AXIS); + } + else { + SERIAL_PROTOCOLLNPGM("Z not entered."); + return; + } + break; + + case MeshSetZOffset: + if (code_seen('Z')) { + mbl.z_offset = code_value_axis_units(Z_AXIS); + } + else { + SERIAL_PROTOCOLLNPGM("Z not entered."); + return; + } + break; + + case MeshReset: + if (mbl.active()) { + current_position[Z_AXIS] += + mbl.get_z(RAW_CURRENT_POSITION(X_AXIS), RAW_CURRENT_POSITION(Y_AXIS)) - MESH_HOME_SEARCH_Z; + mbl.reset(); + SYNC_PLAN_POSITION_KINEMATIC(); + } + else + mbl.reset(); + + } // switch(state) + + report_current_position(); + } + +#elif ENABLED(AUTO_BED_LEVELING_FEATURE) + + /** + * G29: Detailed Z probe, probes the bed at 3 or more points. + * Will fail if the printer has not been homed with G28. + * + * Enhanced G29 Auto Bed Leveling Probe Routine + * + * Parameters With AUTO_BED_LEVELING_GRID: + * + * P Set the size of the grid that will be probed (P x P points). + * Not supported by non-linear delta printer bed leveling. + * Example: "G29 P4" + * + * S Set the XY travel speed between probe points (in units/min) + * + * D Dry-Run mode. Just evaluate the bed Topology - Don't apply + * or clean the rotation Matrix. Useful to check the topology + * after a first run of G29. + * + * V Set the verbose level (0-4). Example: "G29 V3" + * + * T Generate a Bed Topology Report. Example: "G29 P5 T" for a detailed report. + * This is useful for manual bed leveling and finding flaws in the bed (to + * assist with part placement). + * Not supported by non-linear delta printer bed leveling. + * + * F Set the Front limit of the probing grid + * B Set the Back limit of the probing grid + * L Set the Left limit of the probing grid + * R Set the Right limit of the probing grid + * + * Global Parameters: + * + * E/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. + * Usage: "G29 E" or "G29 e" + * + */ + inline void gcode_G29() { + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOLNPGM(">>> gcode_G29"); + DEBUG_POS("", current_position); + } + #endif + + // Don't allow auto-leveling without homing first + if (axis_unhomed_error(true, true, true)) return; + + int verbose_level = code_seen('V') ? code_value_int() : 1; + if (verbose_level < 0 || verbose_level > 4) { + SERIAL_ECHOLNPGM("?(V)erbose Level is implausible (0-4)."); + return; + } + + bool dryrun = code_seen('D'); + bool stow_probe_after_each = code_seen('E'); + + #if ENABLED(AUTO_BED_LEVELING_GRID) + + #if DISABLED(DELTA) + bool do_topography_map = verbose_level > 2 || code_seen('T'); + #endif + + if (verbose_level > 0) { + SERIAL_PROTOCOLLNPGM("G29 Auto Bed Leveling"); + if (dryrun) SERIAL_PROTOCOLLNPGM("Running in DRY-RUN mode"); + } + + int auto_bed_leveling_grid_points = AUTO_BED_LEVELING_GRID_POINTS; + + #if DISABLED(DELTA) + if (code_seen('P')) auto_bed_leveling_grid_points = code_value_int(); + if (auto_bed_leveling_grid_points < 2) { + SERIAL_PROTOCOLLNPGM("?Number of probed (P)oints is implausible (2 minimum)."); + return; + } + #endif + + xy_probe_feedrate_mm_m = code_seen('S') ? (int)code_value_linear_units() : XY_PROBE_SPEED; + + int left_probe_bed_position = code_seen('L') ? (int)code_value_axis_units(X_AXIS) : LOGICAL_X_POSITION(LEFT_PROBE_BED_POSITION), + right_probe_bed_position = code_seen('R') ? (int)code_value_axis_units(X_AXIS) : LOGICAL_X_POSITION(RIGHT_PROBE_BED_POSITION), + front_probe_bed_position = code_seen('F') ? (int)code_value_axis_units(Y_AXIS) : LOGICAL_Y_POSITION(FRONT_PROBE_BED_POSITION), + back_probe_bed_position = code_seen('B') ? (int)code_value_axis_units(Y_AXIS) : LOGICAL_Y_POSITION(BACK_PROBE_BED_POSITION); + + bool left_out_l = left_probe_bed_position < LOGICAL_X_POSITION(MIN_PROBE_X), + left_out = left_out_l || left_probe_bed_position > right_probe_bed_position - (MIN_PROBE_EDGE), + right_out_r = right_probe_bed_position > LOGICAL_X_POSITION(MAX_PROBE_X), + right_out = right_out_r || right_probe_bed_position < left_probe_bed_position + MIN_PROBE_EDGE, + front_out_f = front_probe_bed_position < LOGICAL_Y_POSITION(MIN_PROBE_Y), + front_out = front_out_f || front_probe_bed_position > back_probe_bed_position - (MIN_PROBE_EDGE), + back_out_b = back_probe_bed_position > LOGICAL_Y_POSITION(MAX_PROBE_Y), + back_out = back_out_b || back_probe_bed_position < front_probe_bed_position + MIN_PROBE_EDGE; + + if (left_out || right_out || front_out || back_out) { + if (left_out) { + out_of_range_error(PSTR("(L)eft")); + left_probe_bed_position = left_out_l ? LOGICAL_X_POSITION(MIN_PROBE_X) : right_probe_bed_position - (MIN_PROBE_EDGE); + } + if (right_out) { + out_of_range_error(PSTR("(R)ight")); + right_probe_bed_position = right_out_r ? LOGICAL_Y_POSITION(MAX_PROBE_X) : left_probe_bed_position + MIN_PROBE_EDGE; + } + if (front_out) { + out_of_range_error(PSTR("(F)ront")); + front_probe_bed_position = front_out_f ? LOGICAL_Y_POSITION(MIN_PROBE_Y) : back_probe_bed_position - (MIN_PROBE_EDGE); + } + if (back_out) { + out_of_range_error(PSTR("(B)ack")); + back_probe_bed_position = back_out_b ? LOGICAL_Y_POSITION(MAX_PROBE_Y) : front_probe_bed_position + MIN_PROBE_EDGE; + } + return; + } + + #endif // AUTO_BED_LEVELING_GRID + + if (!dryrun) { + + #if ENABLED(DEBUG_LEVELING_FEATURE) && DISABLED(DELTA) + if (DEBUGGING(LEVELING)) { + vector_3 corrected_position = planner.adjusted_position(); + DEBUG_POS("BEFORE matrix.set_to_identity", corrected_position); + DEBUG_POS("BEFORE matrix.set_to_identity", current_position); + } + #endif + + // make sure the bed_level_rotation_matrix is identity or the planner will get it wrong + planner.bed_level_matrix.set_to_identity(); + + #if ENABLED(DELTA) + reset_bed_level(); + #else //!DELTA + + //vector_3 corrected_position = planner.adjusted_position(); + //corrected_position.debug("position before G29"); + vector_3 uncorrected_position = planner.adjusted_position(); + //uncorrected_position.debug("position during G29"); + current_position[X_AXIS] = uncorrected_position.x; + current_position[Y_AXIS] = uncorrected_position.y; + current_position[Z_AXIS] = uncorrected_position.z; + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("AFTER matrix.set_to_identity", uncorrected_position); + #endif + + SYNC_PLAN_POSITION_KINEMATIC(); + + #endif // !DELTA + } + + stepper.synchronize(); + + setup_for_endstop_or_probe_move(); + + // Deploy the probe. Probe will raise if needed. + if (DEPLOY_PROBE()) return; + + bed_leveling_in_progress = true; + + #if ENABLED(AUTO_BED_LEVELING_GRID) + + // probe at the points of a lattice grid + const int xGridSpacing = (right_probe_bed_position - left_probe_bed_position) / (auto_bed_leveling_grid_points - 1), + yGridSpacing = (back_probe_bed_position - front_probe_bed_position) / (auto_bed_leveling_grid_points - 1); + + #if ENABLED(DELTA) + delta_grid_spacing[0] = xGridSpacing; + delta_grid_spacing[1] = yGridSpacing; + float zoffset = zprobe_zoffset; + if (code_seen('Z')) zoffset += code_value_axis_units(Z_AXIS); + #else // !DELTA + /** + * solve the plane equation ax + by + d = z + * A is the matrix with rows [x y 1] for all the probed points + * B is the vector of the Z positions + * the normal vector to the plane is formed by the coefficients of the + * plane equation in the standard form, which is Vx*x+Vy*y+Vz*z+d = 0 + * so Vx = -a Vy = -b Vz = 1 (we want the vector facing towards positive Z + */ + + int abl2 = sq(auto_bed_leveling_grid_points); + + double eqnAMatrix[abl2 * 3], // "A" matrix of the linear system of equations + eqnBVector[abl2], // "B" vector of Z points + mean = 0.0; + int8_t indexIntoAB[auto_bed_leveling_grid_points][auto_bed_leveling_grid_points]; + #endif // !DELTA + + int probePointCounter = 0; + bool zig = (auto_bed_leveling_grid_points & 1) ? true : false; //always end at [RIGHT_PROBE_BED_POSITION, BACK_PROBE_BED_POSITION] + + for (int yCount = 0; yCount < auto_bed_leveling_grid_points; yCount++) { + double yProbe = front_probe_bed_position + yGridSpacing * yCount; + int xStart, xStop, xInc; + + if (zig) { + xStart = 0; + xStop = auto_bed_leveling_grid_points; + xInc = 1; + } + else { + xStart = auto_bed_leveling_grid_points - 1; + xStop = -1; + xInc = -1; + } + + zig = !zig; + + for (int xCount = xStart; xCount != xStop; xCount += xInc) { + double xProbe = left_probe_bed_position + xGridSpacing * xCount; + + #if ENABLED(DELTA) + // Avoid probing the corners (outside the round or hexagon print surface) on a delta printer. + float distance_from_center = HYPOT(xProbe, yProbe); + if (distance_from_center > DELTA_PROBEABLE_RADIUS) continue; + #endif //DELTA + + float measured_z = probe_pt(xProbe, yProbe, stow_probe_after_each, verbose_level); + + #if DISABLED(DELTA) + mean += measured_z; + + eqnBVector[probePointCounter] = measured_z; + eqnAMatrix[probePointCounter + 0 * abl2] = xProbe; + eqnAMatrix[probePointCounter + 1 * abl2] = yProbe; + eqnAMatrix[probePointCounter + 2 * abl2] = 1; + indexIntoAB[xCount][yCount] = probePointCounter; + #else + bed_level[xCount][yCount] = measured_z + zoffset; + #endif + + probePointCounter++; + + idle(); + + } //xProbe + } //yProbe + + #else // !AUTO_BED_LEVELING_GRID + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("> 3-point Leveling"); + #endif + + // Probe at 3 arbitrary points + float z_at_pt_1 = probe_pt( LOGICAL_X_POSITION(ABL_PROBE_PT_1_X), + LOGICAL_Y_POSITION(ABL_PROBE_PT_1_Y), + stow_probe_after_each, verbose_level), + z_at_pt_2 = probe_pt( LOGICAL_X_POSITION(ABL_PROBE_PT_2_X), + LOGICAL_Y_POSITION(ABL_PROBE_PT_2_Y), + stow_probe_after_each, verbose_level), + z_at_pt_3 = probe_pt( LOGICAL_X_POSITION(ABL_PROBE_PT_3_X), + LOGICAL_Y_POSITION(ABL_PROBE_PT_3_Y), + stow_probe_after_each, verbose_level); + + if (!dryrun) set_bed_level_equation_3pts(z_at_pt_1, z_at_pt_2, z_at_pt_3); + + #endif // !AUTO_BED_LEVELING_GRID + + // Raise to _Z_PROBE_DEPLOY_HEIGHT. Stow the probe. + if (STOW_PROBE()) return; + + // Restore state after probing + clean_up_after_endstop_or_probe_move(); + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("> probing complete", current_position); + #endif + + // Calculate leveling, print reports, correct the position + #if ENABLED(AUTO_BED_LEVELING_GRID) + #if ENABLED(DELTA) + + if (!dryrun) extrapolate_unprobed_bed_level(); + print_bed_level(); + + #else // !DELTA + + // solve lsq problem + double plane_equation_coefficients[3]; + qr_solve(plane_equation_coefficients, abl2, 3, eqnAMatrix, eqnBVector); + + mean /= abl2; + + if (verbose_level) { + SERIAL_PROTOCOLPGM("Eqn coefficients: a: "); + SERIAL_PROTOCOL_F(plane_equation_coefficients[0], 8); + SERIAL_PROTOCOLPGM(" b: "); + SERIAL_PROTOCOL_F(plane_equation_coefficients[1], 8); + SERIAL_PROTOCOLPGM(" d: "); + SERIAL_PROTOCOL_F(plane_equation_coefficients[2], 8); + SERIAL_EOL; + if (verbose_level > 2) { + SERIAL_PROTOCOLPGM("Mean of sampled points: "); + SERIAL_PROTOCOL_F(mean, 8); + SERIAL_EOL; + } + } + + if (!dryrun) set_bed_level_equation_lsq(plane_equation_coefficients); + + // Show the Topography map if enabled + if (do_topography_map) { + + SERIAL_PROTOCOLLNPGM("\nBed Height Topography:\n" + " +--- BACK --+\n" + " | |\n" + " L | (+) | R\n" + " E | | I\n" + " F | (-) N (+) | G\n" + " T | | H\n" + " | (-) | T\n" + " | |\n" + " O-- FRONT --+\n" + " (0,0)"); + + float min_diff = 999; + + for (int yy = auto_bed_leveling_grid_points - 1; yy >= 0; yy--) { + for (int xx = 0; xx < auto_bed_leveling_grid_points; xx++) { + int ind = indexIntoAB[xx][yy]; + float diff = eqnBVector[ind] - mean; + + float x_tmp = eqnAMatrix[ind + 0 * abl2], + y_tmp = eqnAMatrix[ind + 1 * abl2], + z_tmp = 0; + + apply_rotation_xyz(planner.bed_level_matrix, x_tmp, y_tmp, z_tmp); + + NOMORE(min_diff, eqnBVector[ind] - z_tmp); + + if (diff >= 0.0) + SERIAL_PROTOCOLPGM(" +"); // Include + for column alignment + else + SERIAL_PROTOCOLCHAR(' '); + SERIAL_PROTOCOL_F(diff, 5); + } // xx + SERIAL_EOL; + } // yy + SERIAL_EOL; + if (verbose_level > 3) { + SERIAL_PROTOCOLLNPGM("\nCorrected Bed Height vs. Bed Topology:"); + + for (int yy = auto_bed_leveling_grid_points - 1; yy >= 0; yy--) { + for (int xx = 0; xx < auto_bed_leveling_grid_points; xx++) { + int ind = indexIntoAB[xx][yy]; + float x_tmp = eqnAMatrix[ind + 0 * abl2], + y_tmp = eqnAMatrix[ind + 1 * abl2], + z_tmp = 0; + + apply_rotation_xyz(planner.bed_level_matrix, x_tmp, y_tmp, z_tmp); + + float diff = eqnBVector[ind] - z_tmp - min_diff; + if (diff >= 0.0) + SERIAL_PROTOCOLPGM(" +"); + // Include + for column alignment + else + SERIAL_PROTOCOLCHAR(' '); + SERIAL_PROTOCOL_F(diff, 5); + } // xx + SERIAL_EOL; + } // yy + SERIAL_EOL; + } + } //do_topography_map + #endif //!DELTA + #endif // AUTO_BED_LEVELING_GRID + + #if DISABLED(DELTA) + if (verbose_level > 0) + planner.bed_level_matrix.debug("\n\nBed Level Correction Matrix:"); + + if (!dryrun) { + /** + * Correct the Z height difference from Z probe position and nozzle tip position. + * The Z height on homing is measured by Z probe, but the Z probe is quite far + * from the nozzle. When the bed is uneven, this height must be corrected. + */ + float x_tmp = current_position[X_AXIS] + X_PROBE_OFFSET_FROM_EXTRUDER, + y_tmp = current_position[Y_AXIS] + Y_PROBE_OFFSET_FROM_EXTRUDER, + z_tmp = current_position[Z_AXIS], + stepper_z = stepper.get_axis_position_mm(Z_AXIS); //get the real Z (since planner.adjusted_position is now correcting the plane) + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOPAIR("> BEFORE apply_rotation_xyz > stepper_z = ", stepper_z); + SERIAL_ECHOPAIR(" ... z_tmp = ", z_tmp); + SERIAL_EOL; + } + #endif + + // Apply the correction sending the Z probe offset + apply_rotation_xyz(planner.bed_level_matrix, x_tmp, y_tmp, z_tmp); + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOPAIR("> AFTER apply_rotation_xyz > z_tmp = ", z_tmp); + SERIAL_EOL; + } + #endif + + // Adjust the current Z and send it to the planner. + current_position[Z_AXIS] += z_tmp - stepper_z; + SYNC_PLAN_POSITION_KINEMATIC(); + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("> corrected Z in G29", current_position); + #endif + } + #endif // !DELTA + + #ifdef Z_PROBE_END_SCRIPT + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOPGM("Z Probe End Script: "); + SERIAL_ECHOLNPGM(Z_PROBE_END_SCRIPT); + } + #endif + enqueue_and_echo_commands_P(PSTR(Z_PROBE_END_SCRIPT)); + stepper.synchronize(); + #endif + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("<<< gcode_G29"); + #endif + + bed_leveling_in_progress = false; + + report_current_position(); + + KEEPALIVE_STATE(IN_HANDLER); + } + +#endif //AUTO_BED_LEVELING_FEATURE + +#if HAS_BED_PROBE + + /** + * G30: Do a single Z probe at the current XY + */ + inline void gcode_G30() { + + setup_for_endstop_or_probe_move(); + + // TODO: clear the leveling matrix or the planner will be set incorrectly + float measured_z = probe_pt(current_position[X_AXIS] + X_PROBE_OFFSET_FROM_EXTRUDER, + current_position[Y_AXIS] + Y_PROBE_OFFSET_FROM_EXTRUDER, + true, 1); + + SERIAL_PROTOCOLPGM("Bed X: "); + SERIAL_PROTOCOL(current_position[X_AXIS] + X_PROBE_OFFSET_FROM_EXTRUDER + 0.0001); + SERIAL_PROTOCOLPGM(" Y: "); + SERIAL_PROTOCOL(current_position[Y_AXIS] + Y_PROBE_OFFSET_FROM_EXTRUDER + 0.0001); + SERIAL_PROTOCOLPGM(" Z: "); + SERIAL_PROTOCOL(measured_z + 0.0001); + SERIAL_EOL; + + clean_up_after_endstop_or_probe_move(); + + report_current_position(); + } + + #if ENABLED(Z_PROBE_SLED) + + /** + * G31: Deploy the Z probe + */ + inline void gcode_G31() { DEPLOY_PROBE(); } + + /** + * G32: Stow the Z probe + */ + inline void gcode_G32() { STOW_PROBE(); } + + #endif // Z_PROBE_SLED + +#endif // HAS_BED_PROBE + +/** + * G92: Set current position to given X Y Z E + */ +inline void gcode_G92() { + bool didE = code_seen('E'); + + if (!didE) stepper.synchronize(); + + bool didXYZ = false; + LOOP_XYZE(i) { + if (code_seen(axis_codes[i])) { + float p = current_position[i], + v = code_value_axis_units(i); + + current_position[i] = v; + + if (i != E_AXIS) { + position_shift[i] += v - p; // Offset the coordinate space + update_software_endstops((AxisEnum)i); + didXYZ = true; + } + } + } + if (didXYZ) + SYNC_PLAN_POSITION_KINEMATIC(); + else if (didE) + sync_plan_position_e(); +} + +#if ENABLED(ULTIPANEL) + + /** + * M0: Unconditional stop - Wait for user button press on LCD + * M1: Conditional stop - Wait for user button press on LCD + */ + inline void gcode_M0_M1() { + char* args = current_command_args; + + millis_t codenum = 0; + bool hasP = false, hasS = false; + if (code_seen('P')) { + codenum = code_value_millis(); // milliseconds to wait + hasP = codenum > 0; + } + if (code_seen('S')) { + codenum = code_value_millis_from_seconds(); // seconds to wait + hasS = codenum > 0; + } + + if (!hasP && !hasS && *args != '\0') + lcd_setstatus(args, true); + else { + LCD_MESSAGEPGM(MSG_USERWAIT); + #if ENABLED(LCD_PROGRESS_BAR) && PROGRESS_MSG_EXPIRE > 0 + dontExpireStatus(); + #endif + } + + lcd_ignore_click(); + stepper.synchronize(); + refresh_cmd_timeout(); + if (codenum > 0) { + codenum += previous_cmd_ms; // wait until this time for a click + KEEPALIVE_STATE(PAUSED_FOR_USER); + while (PENDING(millis(), codenum) && !lcd_clicked()) idle(); + KEEPALIVE_STATE(IN_HANDLER); + lcd_ignore_click(false); + } + else { + if (!lcd_detected()) return; + KEEPALIVE_STATE(PAUSED_FOR_USER); + while (!lcd_clicked()) idle(); + KEEPALIVE_STATE(IN_HANDLER); + } + if (IS_SD_PRINTING) + LCD_MESSAGEPGM(MSG_RESUMING); + else + LCD_MESSAGEPGM(WELCOME_MSG); + } + +#endif // ULTIPANEL + +/** + * M17: Enable power on all stepper motors + */ +inline void gcode_M17() { + LCD_MESSAGEPGM(MSG_NO_MOVE); + enable_all_steppers(); +} + +#if ENABLED(SDSUPPORT) + + /** + * M20: List SD card to serial output + */ + inline void gcode_M20() { + SERIAL_PROTOCOLLNPGM(MSG_BEGIN_FILE_LIST); + card.ls(); + SERIAL_PROTOCOLLNPGM(MSG_END_FILE_LIST); + } + + /** + * M21: Init SD Card + */ + inline void gcode_M21() { + card.initsd(); + } + + /** + * M22: Release SD Card + */ + inline void gcode_M22() { + card.release(); + } + + /** + * M23: Open a file + */ + inline void gcode_M23() { + card.openFile(current_command_args, true); + } + + /** + * M24: Start SD Print + */ + inline void gcode_M24() { + card.startFileprint(); + print_job_timer.start(); + } + + /** + * M25: Pause SD Print + */ + inline void gcode_M25() { + card.pauseSDPrint(); + } + + /** + * M26: Set SD Card file index + */ + inline void gcode_M26() { + if (card.cardOK && code_seen('S')) + card.setIndex(code_value_long()); + } + + /** + * M27: Get SD Card status + */ + inline void gcode_M27() { + card.getStatus(); + } + + /** + * M28: Start SD Write + */ + inline void gcode_M28() { + card.openFile(current_command_args, false); + } + + /** + * M29: Stop SD Write + * Processed in write to file routine above + */ + inline void gcode_M29() { + // card.saving = false; + } + + /** + * M30 : Delete SD Card file + */ + inline void gcode_M30() { + if (card.cardOK) { + card.closefile(); + card.removeFile(current_command_args); + } + } + +#endif //SDSUPPORT + +/** + * M31: Get the time since the start of SD Print (or last M109) + */ +inline void gcode_M31() { + char buffer[21]; + duration_t elapsed = print_job_timer.duration(); + elapsed.toString(buffer); + + lcd_setstatus(buffer); + + SERIAL_ECHO_START; + SERIAL_ECHOPGM("Print time: "); + SERIAL_ECHOLN(buffer); + + thermalManager.autotempShutdown(); +} + +#if ENABLED(SDSUPPORT) + + /** + * M32: Select file and start SD Print + */ + inline void gcode_M32() { + if (card.sdprinting) + stepper.synchronize(); + + char* namestartpos = strchr(current_command_args, '!'); // Find ! to indicate filename string start. + if (!namestartpos) + namestartpos = current_command_args; // Default name position, 4 letters after the M + else + namestartpos++; //to skip the '!' + + bool call_procedure = code_seen('P') && (seen_pointer < namestartpos); + + if (card.cardOK) { + card.openFile(namestartpos, true, call_procedure); + + if (code_seen('S') && seen_pointer < namestartpos) // "S" (must occur _before_ the filename!) + card.setIndex(code_value_long()); + + card.startFileprint(); + + // Procedure calls count as normal print time. + if (!call_procedure) print_job_timer.start(); + } + } + + #if ENABLED(LONG_FILENAME_HOST_SUPPORT) + + /** + * M33: Get the long full path of a file or folder + * + * Parameters: + * Case-insensitive DOS-style path to a file or folder + * + * Example: + * M33 miscel~1/armchair/armcha~1.gco + * + * Output: + * /Miscellaneous/Armchair/Armchair.gcode + */ + inline void gcode_M33() { + card.printLongPath(current_command_args); + } + + #endif + + /** + * M928: Start SD Write + */ + inline void gcode_M928() { + card.openLogFile(current_command_args); + } + +#endif // SDSUPPORT + +/** + * M42: Change pin status via GCode + * + * P Pin number (LED if omitted) + * S Pin status from 0 - 255 + */ +inline void gcode_M42() { + if (!code_seen('S')) return; + + int pin_status = code_value_int(); + if (pin_status < 0 || pin_status > 255) return; + + int pin_number = code_seen('P') ? code_value_int() : LED_PIN; + if (pin_number < 0) return; + + for (uint8_t i = 0; i < COUNT(sensitive_pins); i++) + if (pin_number == sensitive_pins[i]) return; + + pinMode(pin_number, OUTPUT); + digitalWrite(pin_number, pin_status); + analogWrite(pin_number, pin_status); + + #if FAN_COUNT > 0 + switch (pin_number) { + #if HAS_FAN0 + case FAN_PIN: fanSpeeds[0] = pin_status; break; + #endif + #if HAS_FAN1 + case FAN1_PIN: fanSpeeds[1] = pin_status; break; + #endif + #if HAS_FAN2 + case FAN2_PIN: fanSpeeds[2] = pin_status; break; + #endif + } + #endif +} + +#if ENABLED(Z_MIN_PROBE_REPEATABILITY_TEST) + + /** + * M48: Z probe repeatability measurement function. + * + * Usage: + * M48 + * P = Number of sampled points (4-50, default 10) + * X = Sample X position + * Y = Sample Y position + * V = Verbose level (0-4, default=1) + * E = Engage Z probe for each reading + * L = Number of legs of movement before probe + * S = Schizoid (Or Star if you prefer) + * + * This function assumes the bed has been homed. Specifically, that a G28 command + * as been issued prior to invoking the M48 Z probe repeatability measurement function. + * Any information generated by a prior G29 Bed leveling command will be lost and need to be + * regenerated. + */ + inline void gcode_M48() { + + if (axis_unhomed_error(true, true, true)) return; + + int8_t verbose_level = code_seen('V') ? code_value_byte() : 1; + if (verbose_level < 0 || verbose_level > 4) { + SERIAL_PROTOCOLLNPGM("?Verbose Level not plausible (0-4)."); + return; + } + + if (verbose_level > 0) + SERIAL_PROTOCOLLNPGM("M48 Z-Probe Repeatability test"); + + int8_t n_samples = code_seen('P') ? code_value_byte() : 10; + if (n_samples < 4 || n_samples > 50) { + SERIAL_PROTOCOLLNPGM("?Sample size not plausible (4-50)."); + return; + } + + float X_current = current_position[X_AXIS], + Y_current = current_position[Y_AXIS]; + + bool stow_probe_after_each = code_seen('E'); + + float X_probe_location = code_seen('X') ? code_value_axis_units(X_AXIS) : X_current + X_PROBE_OFFSET_FROM_EXTRUDER; + #if DISABLED(DELTA) + if (X_probe_location < LOGICAL_X_POSITION(MIN_PROBE_X) || X_probe_location > LOGICAL_X_POSITION(MAX_PROBE_X)) { + out_of_range_error(PSTR("X")); + return; + } + #endif + + float Y_probe_location = code_seen('Y') ? code_value_axis_units(Y_AXIS) : Y_current + Y_PROBE_OFFSET_FROM_EXTRUDER; + #if DISABLED(DELTA) + if (Y_probe_location < LOGICAL_Y_POSITION(MIN_PROBE_Y) || Y_probe_location > LOGICAL_Y_POSITION(MAX_PROBE_Y)) { + out_of_range_error(PSTR("Y")); + return; + } + #else + if (HYPOT(RAW_X_POSITION(X_probe_location), RAW_Y_POSITION(Y_probe_location)) > DELTA_PROBEABLE_RADIUS) { + SERIAL_PROTOCOLLNPGM("? (X,Y) location outside of probeable radius."); + return; + } + #endif + + bool seen_L = code_seen('L'); + uint8_t n_legs = seen_L ? code_value_byte() : 0; + if (n_legs > 15) { + SERIAL_PROTOCOLLNPGM("?Number of legs in movement not plausible (0-15)."); + return; + } + if (n_legs == 1) n_legs = 2; + + bool schizoid_flag = code_seen('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_PROTOCOLLNPGM("Positioning the probe..."); + + #if ENABLED(DELTA) + // we don't do bed level correction in M48 because we want the raw data when we probe + reset_bed_level(); + #elif ENABLED(AUTO_BED_LEVELING_FEATURE) + // we don't do bed level correction in M48 because we want the raw data when we probe + planner.bed_level_matrix.set_to_identity(); + #endif + + setup_for_endstop_or_probe_move(); + + // Move to the first point, deploy, and probe + probe_pt(X_probe_location, Y_probe_location, stow_probe_after_each, verbose_level); + + randomSeed(millis()); + + double mean = 0, sigma = 0, sample_set[n_samples]; + for (uint8_t n = 0; n < n_samples; n++) { + if (n_legs) { + int dir = (random(0, 10) > 5.0) ? -1 : 1; // clockwise or counter clockwise + float angle = random(0.0, 360.0), + radius = random( + #if ENABLED(DELTA) + DELTA_PROBEABLE_RADIUS / 8, DELTA_PROBEABLE_RADIUS / 3 + #else + 5, X_MAX_LENGTH / 8 + #endif + ); + + if (verbose_level > 3) { + SERIAL_ECHOPAIR("Starting radius: ", radius); + SERIAL_ECHOPAIR(" angle: ", angle); + SERIAL_ECHOPGM(" Direction: "); + if (dir > 0) SERIAL_ECHOPGM("Counter-"); + SERIAL_ECHOLNPGM("Clockwise"); + } + + for (uint8_t l = 0; l < n_legs - 1; l++) { + double 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. + 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); + + angle += delta_angle; + + while (angle > 360.0) // We probably do not need to keep the angle between 0 and 2*PI, but the + angle -= 360.0; // Arduino documentation says the trig functions should not be given values + while (angle < 0.0) // outside of this range. It looks like they behave correctly with + angle += 360.0; // numbers outside of the range, but just to be safe we clamp them. + + X_current = X_probe_location - (X_PROBE_OFFSET_FROM_EXTRUDER) + cos(RADIANS(angle)) * radius; + Y_current = Y_probe_location - (Y_PROBE_OFFSET_FROM_EXTRUDER) + sin(RADIANS(angle)) * radius; + + #if DISABLED(DELTA) + X_current = constrain(X_current, X_MIN_POS, X_MAX_POS); + Y_current = constrain(Y_current, 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 (HYPOT(X_current, Y_current) > DELTA_PROBEABLE_RADIUS) { + X_current /= 1.25; + Y_current /= 1.25; + if (verbose_level > 3) { + SERIAL_ECHOPAIR("Pulling point towards center:", X_current); + SERIAL_ECHOPAIR(", ", Y_current); + SERIAL_EOL; + } + } + #endif + if (verbose_level > 3) { + SERIAL_PROTOCOLPGM("Going to:"); + SERIAL_ECHOPAIR(" X", X_current); + SERIAL_ECHOPAIR(" Y", Y_current); + SERIAL_ECHOPAIR(" Z", current_position[Z_AXIS]); + SERIAL_EOL; + } + do_blocking_move_to_xy(X_current, Y_current); + } // n_legs loop + } // n_legs + + // Probe a single point + sample_set[n] = probe_pt(X_probe_location, Y_probe_location, stow_probe_after_each, verbose_level); + + /** + * Get the current mean for the data points we have so far + */ + double sum = 0.0; + for (uint8_t j = 0; j <= n; j++) sum += sample_set[j]; + mean = sum / (n + 1); + + /** + * 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_PROTOCOL(n + 1); + SERIAL_PROTOCOLPGM(" of "); + SERIAL_PROTOCOL((int)n_samples); + SERIAL_PROTOCOLPGM(" z: "); + SERIAL_PROTOCOL_F(current_position[Z_AXIS], 6); + if (verbose_level > 2) { + SERIAL_PROTOCOLPGM(" mean: "); + SERIAL_PROTOCOL_F(mean, 6); + SERIAL_PROTOCOLPGM(" sigma: "); + SERIAL_PROTOCOL_F(sigma, 6); + } + } + SERIAL_EOL; + } + + } // End of probe loop + + if (STOW_PROBE()) return; + + if (verbose_level > 0) { + SERIAL_PROTOCOLPGM("Mean: "); + SERIAL_PROTOCOL_F(mean, 6); + SERIAL_EOL; + } + + SERIAL_PROTOCOLPGM("Standard Deviation: "); + SERIAL_PROTOCOL_F(sigma, 6); + SERIAL_EOL; SERIAL_EOL; + + clean_up_after_endstop_or_probe_move(); + + report_current_position(); + } + +#endif // Z_MIN_PROBE_REPEATABILITY_TEST + +/** + * M75: Start print timer + */ +inline void gcode_M75() { print_job_timer.start(); } + +/** + * M76: Pause print timer + */ +inline void gcode_M76() { print_job_timer.pause(); } + +/** + * M77: Stop print timer + */ +inline void gcode_M77() { print_job_timer.stop(); } + +#if ENABLED(PRINTCOUNTER) + /** + * M78: Show print statistics + */ + inline void gcode_M78() { + // "M78 S78" will reset the statistics + if (code_seen('S') && code_value_int() == 78) + print_job_timer.initStats(); + else print_job_timer.showStats(); + } +#endif + +/** + * M104: Set hot end temperature + */ +inline void gcode_M104() { + if (get_target_extruder_from_command(104)) return; + if (DEBUGGING(DRYRUN)) return; + + #if ENABLED(SINGLENOZZLE) + if (target_extruder != active_extruder) return; + #endif + + if (code_seen('S')) { + thermalManager.setTargetHotend(code_value_temp_abs(), target_extruder); + #if ENABLED(DUAL_X_CARRIAGE) + if (dual_x_carriage_mode == DXC_DUPLICATION_MODE && target_extruder == 0) + thermalManager.setTargetHotend(code_value_temp_abs() == 0.0 ? 0.0 : code_value_temp_abs() + duplicate_extruder_temp_offset, 1); + #endif + + #if ENABLED(PRINTJOB_TIMER_AUTOSTART) + /** + * Stop the timer at the end of print, starting is managed by + * 'heat and wait' M109. + * We use half EXTRUDE_MINTEMP here to allow nozzles to be put into hot + * stand by mode, for instance in a dual extruder setup, without affecting + * the running print timer. + */ + if (code_value_temp_abs() <= (EXTRUDE_MINTEMP)/2) { + print_job_timer.stop(); + LCD_MESSAGEPGM(WELCOME_MSG); + } + #endif + + if (code_value_temp_abs() > thermalManager.degHotend(target_extruder)) LCD_MESSAGEPGM(MSG_HEATING); + } +} + +#if HAS_TEMP_HOTEND || HAS_TEMP_BED + + void print_heaterstates() { + #if HAS_TEMP_HOTEND + SERIAL_PROTOCOLPGM(" T:"); + SERIAL_PROTOCOL_F(thermalManager.degHotend(target_extruder), 1); + SERIAL_PROTOCOLPGM(" /"); + SERIAL_PROTOCOL_F(thermalManager.degTargetHotend(target_extruder), 1); + #if ENABLED(SHOW_TEMP_ADC_VALUES) + SERIAL_PROTOCOLPAIR(" (", thermalManager.current_temperature_raw[target_extruder] / OVERSAMPLENR); + SERIAL_CHAR(')'); + #endif + #endif + #if HAS_TEMP_BED + SERIAL_PROTOCOLPGM(" B:"); + SERIAL_PROTOCOL_F(thermalManager.degBed(), 1); + SERIAL_PROTOCOLPGM(" /"); + SERIAL_PROTOCOL_F(thermalManager.degTargetBed(), 1); + #if ENABLED(SHOW_TEMP_ADC_VALUES) + SERIAL_PROTOCOLPAIR(" (", thermalManager.current_temperature_bed_raw / OVERSAMPLENR); + SERIAL_CHAR(')'); + #endif + #endif + #if HOTENDS > 1 + HOTEND_LOOP() { + SERIAL_PROTOCOLPAIR(" T", e); + SERIAL_PROTOCOLCHAR(':'); + SERIAL_PROTOCOL_F(thermalManager.degHotend(e), 1); + SERIAL_PROTOCOLPGM(" /"); + SERIAL_PROTOCOL_F(thermalManager.degTargetHotend(e), 1); + #if ENABLED(SHOW_TEMP_ADC_VALUES) + SERIAL_PROTOCOLPAIR(" (", thermalManager.current_temperature_raw[e] / OVERSAMPLENR); + SERIAL_CHAR(')'); + #endif + } + #endif + SERIAL_PROTOCOLPGM(" @:"); + SERIAL_PROTOCOL(thermalManager.getHeaterPower(target_extruder)); + #if HAS_TEMP_BED + SERIAL_PROTOCOLPGM(" B@:"); + SERIAL_PROTOCOL(thermalManager.getHeaterPower(-1)); + #endif + #if HOTENDS > 1 + HOTEND_LOOP() { + SERIAL_PROTOCOLPAIR(" @", e); + SERIAL_PROTOCOLCHAR(':'); + SERIAL_PROTOCOL(thermalManager.getHeaterPower(e)); + } + #endif + } +#endif + +/** + * M105: Read hot end and bed temperature + */ +inline void gcode_M105() { + if (get_target_extruder_from_command(105)) return; + + #if HAS_TEMP_HOTEND || HAS_TEMP_BED + SERIAL_PROTOCOLPGM(MSG_OK); + print_heaterstates(); + #else // !HAS_TEMP_HOTEND && !HAS_TEMP_BED + SERIAL_ERROR_START; + SERIAL_ERRORLNPGM(MSG_ERR_NO_THERMISTORS); + #endif + + SERIAL_EOL; +} + +#if FAN_COUNT > 0 + + /** + * M106: Set Fan Speed + * + * S Speed between 0-255 + * P Fan index, if more than one fan + */ + inline void gcode_M106() { + uint16_t s = code_seen('S') ? code_value_ushort() : 255, + p = code_seen('P') ? code_value_ushort() : 0; + NOMORE(s, 255); + if (p < FAN_COUNT) fanSpeeds[p] = s; + } + + /** + * M107: Fan Off + */ + inline void gcode_M107() { + uint16_t p = code_seen('P') ? code_value_ushort() : 0; + if (p < FAN_COUNT) fanSpeeds[p] = 0; + } + +#endif // FAN_COUNT > 0 + +#if DISABLED(EMERGENCY_PARSER) + + /** + * M108: Stop the waiting for heaters in M109, M190, M303. Does not affect the target temperature. + */ + inline void gcode_M108() { wait_for_heatup = false; } + + + /** + * M112: Emergency Stop + */ + inline void gcode_M112() { kill(PSTR(MSG_KILLED)); } + + + /** + * M410: Quickstop - Abort all planned moves + * + * This will stop the carriages mid-move, so most likely they + * will be out of sync with the stepper position after this. + */ + inline void gcode_M410() { quickstop_stepper(); } + +#endif + + #ifndef MIN_COOLING_SLOPE_DEG + #define MIN_COOLING_SLOPE_DEG 1.50 + #endif + #ifndef MIN_COOLING_SLOPE_TIME + #define MIN_COOLING_SLOPE_TIME 60 + #endif + +/** + * M109: Sxxx Wait for extruder(s) to reach temperature. Waits only when heating. + * Rxxx Wait for extruder(s) to reach temperature. Waits when heating and cooling. + */ +inline void gcode_M109() { + + if (get_target_extruder_from_command(109)) return; + if (DEBUGGING(DRYRUN)) return; + + #if ENABLED(SINGLENOZZLE) + if (target_extruder != active_extruder) return; + #endif + + bool no_wait_for_cooling = code_seen('S'); + if (no_wait_for_cooling || code_seen('R')) { + thermalManager.setTargetHotend(code_value_temp_abs(), target_extruder); + #if ENABLED(DUAL_X_CARRIAGE) + if (dual_x_carriage_mode == DXC_DUPLICATION_MODE && target_extruder == 0) + thermalManager.setTargetHotend(code_value_temp_abs() == 0.0 ? 0.0 : code_value_temp_abs() + duplicate_extruder_temp_offset, 1); + #endif + + #if ENABLED(PRINTJOB_TIMER_AUTOSTART) + /** + * We use half EXTRUDE_MINTEMP here to allow nozzles to be put into hot + * stand by mode, for instance in a dual extruder setup, without affecting + * the running print timer. + */ + if (code_value_temp_abs() <= (EXTRUDE_MINTEMP)/2) { + print_job_timer.stop(); + LCD_MESSAGEPGM(WELCOME_MSG); + } + /** + * We do not check if the timer is already running because this check will + * be done for us inside the Stopwatch::start() method thus a running timer + * will not restart. + */ + else print_job_timer.start(); + #endif + + if (thermalManager.isHeatingHotend(target_extruder)) LCD_MESSAGEPGM(MSG_HEATING); + } + + #if ENABLED(AUTOTEMP) + planner.autotemp_M109(); + #endif + + #if TEMP_RESIDENCY_TIME > 0 + millis_t residency_start_ms = 0; + // Loop until the temperature has stabilized + #define TEMP_CONDITIONS (!residency_start_ms || PENDING(now, residency_start_ms + (TEMP_RESIDENCY_TIME) * 1000UL)) + #else + // Loop until the temperature is very close target + #define TEMP_CONDITIONS (wants_to_cool ? thermalManager.isCoolingHotend(target_extruder) : thermalManager.isHeatingHotend(target_extruder)) + #endif //TEMP_RESIDENCY_TIME > 0 + + float theTarget = -1.0, old_temp = 9999.0; + bool wants_to_cool = false; + wait_for_heatup = true; + millis_t now, next_temp_ms = 0, next_cool_check_ms = 0; + + KEEPALIVE_STATE(NOT_BUSY); + + do { + // Target temperature might be changed during the loop + if (theTarget != thermalManager.degTargetHotend(target_extruder)) { + wants_to_cool = thermalManager.isCoolingHotend(target_extruder); + theTarget = thermalManager.degTargetHotend(target_extruder); + + // Exit if S, continue if S, R, or R + if (no_wait_for_cooling && wants_to_cool) break; + } + + now = millis(); + if (ELAPSED(now, next_temp_ms)) { //Print temp & remaining time every 1s while waiting + next_temp_ms = now + 1000UL; + print_heaterstates(); + #if TEMP_RESIDENCY_TIME > 0 + SERIAL_PROTOCOLPGM(" W:"); + if (residency_start_ms) { + long rem = (((TEMP_RESIDENCY_TIME) * 1000UL) - (now - residency_start_ms)) / 1000UL; + SERIAL_PROTOCOLLN(rem); + } + else { + SERIAL_PROTOCOLLNPGM("?"); + } + #else + SERIAL_EOL; + #endif + } + + idle(); + refresh_cmd_timeout(); // to prevent stepper_inactive_time from running out + + float temp = thermalManager.degHotend(target_extruder); + + #if TEMP_RESIDENCY_TIME > 0 + + float temp_diff = fabs(theTarget - temp); + + 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; + } + else if (temp_diff > TEMP_HYSTERESIS) { + // Restart the timer whenever the temperature falls outside the hysteresis. + residency_start_ms = now; + } + + #endif //TEMP_RESIDENCY_TIME > 0 + + // Prevent a wait-forever situation if R is misused i.e. M109 R0 + if (wants_to_cool) { + // break after MIN_COOLING_SLOPE_TIME seconds + // if the temperature did not drop at least MIN_COOLING_SLOPE_DEG + if (!next_cool_check_ms || ELAPSED(now, next_cool_check_ms)) { + if (old_temp - temp < MIN_COOLING_SLOPE_DEG) break; + next_cool_check_ms = now + 1000UL * MIN_COOLING_SLOPE_TIME; + old_temp = temp; + } + } + + } while (wait_for_heatup && TEMP_CONDITIONS); + + LCD_MESSAGEPGM(MSG_HEATING_COMPLETE); + KEEPALIVE_STATE(IN_HANDLER); +} + +#if HAS_TEMP_BED + + #ifndef MIN_COOLING_SLOPE_DEG_BED + #define MIN_COOLING_SLOPE_DEG_BED 1.50 + #endif + #ifndef MIN_COOLING_SLOPE_TIME_BED + #define MIN_COOLING_SLOPE_TIME_BED 60 + #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 + */ + inline void gcode_M190() { + if (DEBUGGING(DRYRUN)) return; + + LCD_MESSAGEPGM(MSG_BED_HEATING); + bool no_wait_for_cooling = code_seen('S'); + if (no_wait_for_cooling || code_seen('R')) { + thermalManager.setTargetBed(code_value_temp_abs()); + #if ENABLED(PRINTJOB_TIMER_AUTOSTART) + if (code_value_temp_abs() > BED_MINTEMP) { + /** + * We start the timer when 'heating and waiting' command arrives, LCD + * functions never wait. Cooling down managed by extruders. + * + * We do not check if the timer is already running because this check will + * be done for us inside the Stopwatch::start() method thus a running timer + * will not restart. + */ + print_job_timer.start(); + } + #endif + } + + #if TEMP_BED_RESIDENCY_TIME > 0 + millis_t residency_start_ms = 0; + // Loop until the temperature has stabilized + #define TEMP_BED_CONDITIONS (!residency_start_ms || PENDING(now, residency_start_ms + (TEMP_BED_RESIDENCY_TIME) * 1000UL)) + #else + // Loop until the temperature is very close target + #define TEMP_BED_CONDITIONS (wants_to_cool ? thermalManager.isCoolingBed() : thermalManager.isHeatingBed()) + #endif //TEMP_BED_RESIDENCY_TIME > 0 + + float theTarget = -1.0, old_temp = 9999.0; + bool wants_to_cool = false; + wait_for_heatup = true; + millis_t now, next_temp_ms = 0, next_cool_check_ms = 0; + + KEEPALIVE_STATE(NOT_BUSY); + + target_extruder = active_extruder; // for print_heaterstates + + do { + // Target temperature might be changed during the loop + if (theTarget != thermalManager.degTargetBed()) { + wants_to_cool = thermalManager.isCoolingBed(); + theTarget = thermalManager.degTargetBed(); + + // Exit if S, continue if S, R, or R + if (no_wait_for_cooling && wants_to_cool) break; + } + + now = millis(); + if (ELAPSED(now, next_temp_ms)) { //Print Temp Reading every 1 second while heating up. + next_temp_ms = now + 1000UL; + print_heaterstates(); + #if TEMP_BED_RESIDENCY_TIME > 0 + SERIAL_PROTOCOLPGM(" W:"); + if (residency_start_ms) { + long rem = (((TEMP_BED_RESIDENCY_TIME) * 1000UL) - (now - residency_start_ms)) / 1000UL; + SERIAL_PROTOCOLLN(rem); + } + else { + SERIAL_PROTOCOLLNPGM("?"); + } + #else + SERIAL_EOL; + #endif + } + + idle(); + refresh_cmd_timeout(); // to prevent stepper_inactive_time from running out + + float temp = thermalManager.degBed(); + + #if TEMP_BED_RESIDENCY_TIME > 0 + + float temp_diff = fabs(theTarget - temp); + + 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; + } + else if (temp_diff > TEMP_BED_HYSTERESIS) { + // Restart the timer whenever the temperature falls outside the hysteresis. + residency_start_ms = now; + } + + #endif //TEMP_BED_RESIDENCY_TIME > 0 + + // Prevent a wait-forever situation if R is misused i.e. M190 R0 + if (wants_to_cool) { + // break after MIN_COOLING_SLOPE_TIME_BED seconds + // if the temperature did not drop at least MIN_COOLING_SLOPE_DEG_BED + if (!next_cool_check_ms || ELAPSED(now, next_cool_check_ms)) { + if (old_temp - temp < MIN_COOLING_SLOPE_DEG_BED) break; + next_cool_check_ms = now + 1000UL * MIN_COOLING_SLOPE_TIME_BED; + old_temp = temp; + } + } + + } while (wait_for_heatup && TEMP_BED_CONDITIONS); + + LCD_MESSAGEPGM(MSG_BED_DONE); + KEEPALIVE_STATE(IN_HANDLER); + } + +#endif // HAS_TEMP_BED + +/** + * M110: Set Current Line Number + */ +inline void gcode_M110() { + if (code_seen('N')) gcode_N = code_value_long(); +} + +/** + * M111: Set the debug level + */ +inline void gcode_M111() { + marlin_debug_flags = code_seen('S') ? code_value_byte() : (uint8_t) DEBUG_NONE; + + const static char str_debug_1[] PROGMEM = MSG_DEBUG_ECHO; + const static char str_debug_2[] PROGMEM = MSG_DEBUG_INFO; + const static char str_debug_4[] PROGMEM = MSG_DEBUG_ERRORS; + const static char str_debug_8[] PROGMEM = MSG_DEBUG_DRYRUN; + const static char str_debug_16[] PROGMEM = MSG_DEBUG_COMMUNICATION; + #if ENABLED(DEBUG_LEVELING_FEATURE) + const static char str_debug_32[] PROGMEM = MSG_DEBUG_LEVELING; + #endif + + const static char* 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_32 + #endif + }; + + SERIAL_ECHO_START; + SERIAL_ECHOPGM(MSG_DEBUG_PREFIX); + if (marlin_debug_flags) { + uint8_t comma = 0; + for (uint8_t i = 0; i < COUNT(debug_strings); i++) { + if (TEST(marlin_debug_flags, i)) { + if (comma++) SERIAL_CHAR(','); + serialprintPGM((char*)pgm_read_word(&(debug_strings[i]))); + } + } + } + else { + SERIAL_ECHOPGM(MSG_DEBUG_OFF); + } + SERIAL_EOL; +} + +#if ENABLED(HOST_KEEPALIVE_FEATURE) + + /** + * M113: Get or set Host Keepalive interval (0 to disable) + * + * S Optional. Set the keepalive interval. + */ + inline void gcode_M113() { + if (code_seen('S')) { + host_keepalive_interval = code_value_byte(); + NOMORE(host_keepalive_interval, 60); + } + else { + SERIAL_ECHO_START; + SERIAL_ECHOPAIR("M113 S", (unsigned long)host_keepalive_interval); + SERIAL_EOL; + } + } + +#endif + +#if ENABLED(BARICUDA) + + #if HAS_HEATER_1 + /** + * M126: Heater 1 valve open + */ + inline void gcode_M126() { baricuda_valve_pressure = code_seen('S') ? code_value_byte() : 255; } + /** + * M127: Heater 1 valve close + */ + inline void gcode_M127() { baricuda_valve_pressure = 0; } + #endif + + #if HAS_HEATER_2 + /** + * M128: Heater 2 valve open + */ + inline void gcode_M128() { baricuda_e_to_p_pressure = code_seen('S') ? code_value_byte() : 255; } + /** + * M129: Heater 2 valve close + */ + inline void gcode_M129() { baricuda_e_to_p_pressure = 0; } + #endif + +#endif //BARICUDA + +/** + * M140: Set bed temperature + */ +inline void gcode_M140() { + if (DEBUGGING(DRYRUN)) return; + if (code_seen('S')) thermalManager.setTargetBed(code_value_temp_abs()); +} + +#if ENABLED(ULTIPANEL) + + /** + * M145: Set the heatup state for a material in the LCD menu + * S (0=PLA, 1=ABS) + * H + * B + * F + */ + inline void gcode_M145() { + int8_t material = code_seen('S') ? (int8_t)code_value_int() : 0; + if (material < 0 || material > 1) { + SERIAL_ERROR_START; + SERIAL_ERRORLNPGM(MSG_ERR_MATERIAL_INDEX); + } + else { + int v; + switch (material) { + case 0: + if (code_seen('H')) { + v = code_value_int(); + preheatHotendTemp1 = constrain(v, EXTRUDE_MINTEMP, HEATER_0_MAXTEMP - 15); + } + if (code_seen('F')) { + v = code_value_int(); + preheatFanSpeed1 = constrain(v, 0, 255); + } + #if TEMP_SENSOR_BED != 0 + if (code_seen('B')) { + v = code_value_int(); + preheatBedTemp1 = constrain(v, BED_MINTEMP, BED_MAXTEMP - 15); + } + #endif + break; + case 1: + if (code_seen('H')) { + v = code_value_int(); + preheatHotendTemp2 = constrain(v, EXTRUDE_MINTEMP, HEATER_0_MAXTEMP - 15); + } + if (code_seen('F')) { + v = code_value_int(); + preheatFanSpeed2 = constrain(v, 0, 255); + } + #if TEMP_SENSOR_BED != 0 + if (code_seen('B')) { + v = code_value_int(); + preheatBedTemp2 = constrain(v, BED_MINTEMP, BED_MAXTEMP - 15); + } + #endif + break; + } + } + } + +#endif + +#if ENABLED(TEMPERATURE_UNITS_SUPPORT) + /** + * M149: Set temperature units + */ + inline void gcode_M149() { + if (code_seen('C')) { + set_input_temp_units(TEMPUNIT_C); + } else if (code_seen('K')) { + set_input_temp_units(TEMPUNIT_K); + } else if (code_seen('F')) { + set_input_temp_units(TEMPUNIT_F); + } + } +#endif + +#if HAS_POWER_SWITCH + + /** + * M80: Turn on Power Supply + */ + inline void gcode_M80() { + OUT_WRITE(PS_ON_PIN, PS_ON_AWAKE); //GND + + /** + * If you have a switch on suicide pin, this is useful + * if you want to start another print with suicide feature after + * a print without suicide... + */ + #if HAS_SUICIDE + OUT_WRITE(SUICIDE_PIN, HIGH); + #endif + + #if ENABLED(ULTIPANEL) + powersupply = true; + LCD_MESSAGEPGM(WELCOME_MSG); + lcd_update(); + #endif + } + +#endif // HAS_POWER_SWITCH + +/** + * M81: Turn off Power, including Power Supply, if there is one. + * + * This code should ALWAYS be available for EMERGENCY SHUTDOWN! + */ +inline void gcode_M81() { + thermalManager.disable_all_heaters(); + stepper.finish_and_disable(); + #if FAN_COUNT > 0 + #if FAN_COUNT > 1 + for (uint8_t i = 0; i < FAN_COUNT; i++) fanSpeeds[i] = 0; + #else + fanSpeeds[0] = 0; + #endif + #endif + delay(1000); // Wait 1 second before switching off + #if HAS_SUICIDE + stepper.synchronize(); + suicide(); + #elif HAS_POWER_SWITCH + OUT_WRITE(PS_ON_PIN, PS_ON_ASLEEP); + #endif + #if ENABLED(ULTIPANEL) + #if HAS_POWER_SWITCH + powersupply = false; + #endif + LCD_MESSAGEPGM(MACHINE_NAME " " MSG_OFF "."); + lcd_update(); + #endif +} + + +/** + * M82: Set E codes absolute (default) + */ +inline void gcode_M82() { axis_relative_modes[E_AXIS] = false; } + +/** + * M83: Set E codes relative while in Absolute Coordinates (G90) mode + */ +inline void gcode_M83() { axis_relative_modes[E_AXIS] = true; } + +/** + * M18, M84: Disable all stepper motors + */ +inline void gcode_M18_M84() { + if (code_seen('S')) { + stepper_inactive_time = code_value_millis_from_seconds(); + } + else { + bool all_axis = !((code_seen('X')) || (code_seen('Y')) || (code_seen('Z')) || (code_seen('E'))); + if (all_axis) { + stepper.finish_and_disable(); + } + else { + stepper.synchronize(); + if (code_seen('X')) disable_x(); + if (code_seen('Y')) disable_y(); + if (code_seen('Z')) disable_z(); + #if ((E0_ENABLE_PIN != X_ENABLE_PIN) && (E1_ENABLE_PIN != Y_ENABLE_PIN)) // Only enable on boards that have seperate ENABLE_PINS + if (code_seen('E')) { + disable_e0(); + disable_e1(); + disable_e2(); + disable_e3(); + } + #endif + } + } +} + +/** + * M85: Set inactivity shutdown timer with parameter S. To disable set zero (default) + */ +inline void gcode_M85() { + if (code_seen('S')) max_inactive_time = code_value_millis_from_seconds(); +} + +/** + * M92: Set axis steps-per-unit for one or more axes, X, Y, Z, and E. + * (Follows the same syntax as G92) + */ +inline void gcode_M92() { + LOOP_XYZE(i) { + if (code_seen(axis_codes[i])) { + if (i == E_AXIS) { + float value = code_value_per_axis_unit(i); + if (value < 20.0) { + float factor = planner.axis_steps_per_mm[i] / value; // increase e constants if M92 E14 is given for netfab. + planner.max_e_jerk *= factor; + planner.max_feedrate_mm_s[i] *= factor; + planner.max_acceleration_steps_per_s2[i] *= factor; + } + planner.axis_steps_per_mm[i] = value; + } + else { + planner.axis_steps_per_mm[i] = code_value_per_axis_unit(i); + } + } + } + planner.refresh_positioning(); +} + +/** + * Output the current position to serial + */ +static void report_current_position() { + SERIAL_PROTOCOLPGM("X:"); + SERIAL_PROTOCOL(current_position[X_AXIS]); + SERIAL_PROTOCOLPGM(" Y:"); + SERIAL_PROTOCOL(current_position[Y_AXIS]); + SERIAL_PROTOCOLPGM(" Z:"); + SERIAL_PROTOCOL(current_position[Z_AXIS]); + SERIAL_PROTOCOLPGM(" E:"); + SERIAL_PROTOCOL(current_position[E_AXIS]); + + stepper.report_positions(); + + #if ENABLED(SCARA) + SERIAL_PROTOCOLPGM("SCARA Theta:"); + SERIAL_PROTOCOL(delta[X_AXIS]); + SERIAL_PROTOCOLPGM(" Psi+Theta:"); + SERIAL_PROTOCOL(delta[Y_AXIS]); + SERIAL_EOL; + + SERIAL_PROTOCOLPGM("SCARA Cal - Theta:"); + SERIAL_PROTOCOL(delta[X_AXIS]); + SERIAL_PROTOCOLPGM(" Psi+Theta (90):"); + SERIAL_PROTOCOL(delta[Y_AXIS] - delta[X_AXIS] - 90); + SERIAL_EOL; + + SERIAL_PROTOCOLPGM("SCARA step Cal - Theta:"); + SERIAL_PROTOCOL(delta[X_AXIS] / 90 * planner.axis_steps_per_mm[X_AXIS]); + SERIAL_PROTOCOLPGM(" Psi+Theta:"); + SERIAL_PROTOCOL((delta[Y_AXIS] - delta[X_AXIS]) / 90 * planner.axis_steps_per_mm[Y_AXIS]); + SERIAL_EOL; SERIAL_EOL; + #endif +} + +/** + * M114: Output current position to serial port + */ +inline void gcode_M114() { report_current_position(); } + +/** + * M115: Capabilities string + */ +inline void gcode_M115() { + SERIAL_PROTOCOLPGM(MSG_M115_REPORT); +} + +/** + * M117: Set LCD Status Message + */ +inline void gcode_M117() { + lcd_setstatus(current_command_args); +} + +/** + * M119: Output endstop states to serial output + */ +inline void gcode_M119() { endstops.M119(); } + +/** + * M120: Enable endstops and set non-homing endstop state to "enabled" + */ +inline void gcode_M120() { endstops.enable_globally(true); } + +/** + * M121: Disable endstops and set non-homing endstop state to "disabled" + */ +inline void gcode_M121() { endstops.enable_globally(false); } + +#if ENABLED(BLINKM) + + /** + * M150: Set Status LED Color - Use R-U-B for R-G-B + */ + inline void gcode_M150() { + SendColors( + code_seen('R') ? code_value_byte() : 0, + code_seen('U') ? code_value_byte() : 0, + code_seen('B') ? code_value_byte() : 0 + ); + } + +#endif // BLINKM + +#if ENABLED(EXPERIMENTAL_I2CBUS) + + /** + * M155: Send data to a I2C slave device + * + * This is a PoC, the formating and arguments for the GCODE will + * change to be more compatible, the current proposal is: + * + * M155 A ; Sets the I2C slave address the data will be sent to + * + * M155 B + * M155 B + * M155 B + * + * M155 S1 ; Send the buffered data and reset the buffer + * M155 R1 ; Reset the buffer without sending data + * + */ + inline void gcode_M155() { + // Set the target address + if (code_seen('A')) + i2c.address(code_value_byte()); + + // Add a new byte to the buffer + else if (code_seen('B')) + i2c.addbyte(code_value_int()); + + // Flush the buffer to the bus + else if (code_seen('S')) i2c.send(); + + // Reset and rewind the buffer + else if (code_seen('R')) i2c.reset(); + } + + /** + * M156: Request X bytes from I2C slave device + * + * Usage: M156 A B + */ + inline void gcode_M156() { + uint8_t addr = code_seen('A') ? code_value_byte() : 0; + int bytes = code_seen('B') ? code_value_int() : 1; + + if (addr && bytes > 0 && bytes <= 32) { + i2c.address(addr); + i2c.reqbytes(bytes); + } + else { + SERIAL_ERROR_START; + SERIAL_ERRORLN("Bad i2c request"); + } + } + +#endif //EXPERIMENTAL_I2CBUS + +/** + * 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. + */ +inline void gcode_M200() { + + if (get_target_extruder_from_command(200)) return; + + if (code_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 + volumetric_enabled = (code_value_linear_units() != 0.0); + if (volumetric_enabled) { + filament_size[target_extruder] = code_value_linear_units(); + // make sure all extruders have some sane value for the filament size + for (uint8_t i = 0; i < COUNT(filament_size); i++) + if (! filament_size[i]) filament_size[i] = DEFAULT_NOMINAL_FILAMENT_DIA; + } + } + else { + //reserved for setting filament diameter via UFID or filament measuring device + return; + } + calculate_volumetric_multipliers(); +} + +/** + * M201: Set max acceleration in units/s^2 for print moves (M201 X1000 Y1000) + */ +inline void gcode_M201() { + LOOP_XYZE(i) { + if (code_seen(axis_codes[i])) { + planner.max_acceleration_mm_per_s2[i] = code_value_axis_units(i); + } + } + // steps per sq second need to be updated to agree with the units per sq second (as they are what is used in the planner) + planner.reset_acceleration_rates(); +} + +#if 0 // Not used for Sprinter/grbl gen6 + inline void gcode_M202() { + LOOP_XYZE(i) { + if (code_seen(axis_codes[i])) axis_travel_steps_per_sqr_second[i] = code_value_axis_units(i) * planner.axis_steps_per_mm[i]; + } + } +#endif + + +/** + * M203: Set maximum feedrate that your machine can sustain (M203 X200 Y200 Z300 E10000) in units/sec + */ +inline void gcode_M203() { + LOOP_XYZE(i) + if (code_seen(axis_codes[i])) + planner.max_feedrate_mm_s[i] = code_value_axis_units(i); +} + +/** + * M204: Set Accelerations in units/sec^2 (M204 P1200 R3000 T3000) + * + * P = Printing moves + * R = Retract only (no X, Y, Z) moves + * T = Travel (non printing) moves + * + * Also sets minimum segment time in ms (B20000) to prevent buffer under-runs and M20 minimum feedrate + */ +inline void gcode_M204() { + if (code_seen('S')) { // Kept for legacy compatibility. Should NOT BE USED for new developments. + planner.travel_acceleration = planner.acceleration = code_value_linear_units(); + SERIAL_ECHOPAIR("Setting Print and Travel Acceleration: ", planner.acceleration); + SERIAL_EOL; + } + if (code_seen('P')) { + planner.acceleration = code_value_linear_units(); + SERIAL_ECHOPAIR("Setting Print Acceleration: ", planner.acceleration); + SERIAL_EOL; + } + if (code_seen('R')) { + planner.retract_acceleration = code_value_linear_units(); + SERIAL_ECHOPAIR("Setting Retract Acceleration: ", planner.retract_acceleration); + SERIAL_EOL; + } + if (code_seen('T')) { + planner.travel_acceleration = code_value_linear_units(); + SERIAL_ECHOPAIR("Setting Travel Acceleration: ", planner.travel_acceleration); + SERIAL_EOL; + } +} + +/** + * M205: Set Advanced Settings + * + * S = Min Feed Rate (units/s) + * T = Min Travel Feed Rate (units/s) + * B = Min Segment Time (µs) + * X = Max XY Jerk (units/sec^2) + * Z = Max Z Jerk (units/sec^2) + * E = Max E Jerk (units/sec^2) + */ +inline void gcode_M205() { + if (code_seen('S')) planner.min_feedrate_mm_s = code_value_linear_units(); + if (code_seen('T')) planner.min_travel_feedrate_mm_s = code_value_linear_units(); + if (code_seen('B')) planner.min_segment_time = code_value_millis(); + if (code_seen('X')) planner.max_xy_jerk = code_value_linear_units(); + if (code_seen('Z')) planner.max_z_jerk = code_value_axis_units(Z_AXIS); + if (code_seen('E')) planner.max_e_jerk = code_value_axis_units(E_AXIS); +} + +/** + * M206: Set Additional Homing Offset (X Y Z). SCARA aliases T=X, P=Y + */ +inline void gcode_M206() { + LOOP_XYZ(i) + if (code_seen(axis_codes[i])) + set_home_offset((AxisEnum)i, code_value_axis_units(i)); + + #if ENABLED(SCARA) + if (code_seen('T')) set_home_offset(X_AXIS, code_value_axis_units(X_AXIS)); // Theta + if (code_seen('P')) set_home_offset(Y_AXIS, code_value_axis_units(Y_AXIS)); // Psi + #endif + + SYNC_PLAN_POSITION_KINEMATIC(); + report_current_position(); +} + +#if ENABLED(DELTA) + /** + * M665: Set delta configurations + * + * L = diagonal rod + * R = delta radius + * S = segments per second + * A = Alpha (Tower 1) diagonal rod trim + * B = Beta (Tower 2) diagonal rod trim + * C = Gamma (Tower 3) diagonal rod trim + */ + inline void gcode_M665() { + if (code_seen('L')) delta_diagonal_rod = code_value_linear_units(); + if (code_seen('R')) delta_radius = code_value_linear_units(); + if (code_seen('S')) delta_segments_per_second = code_value_float(); + if (code_seen('A')) delta_diagonal_rod_trim_tower_1 = code_value_linear_units(); + if (code_seen('B')) delta_diagonal_rod_trim_tower_2 = code_value_linear_units(); + if (code_seen('C')) delta_diagonal_rod_trim_tower_3 = code_value_linear_units(); + recalc_delta_settings(delta_radius, delta_diagonal_rod); + } + /** + * M666: Set delta endstop adjustment + */ + inline void gcode_M666() { + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOLNPGM(">>> gcode_M666"); + } + #endif + LOOP_XYZ(i) { + if (code_seen(axis_codes[i])) { + endstop_adj[i] = code_value_axis_units(i); + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOPGM("endstop_adj["); + SERIAL_ECHO(axis_codes[i]); + SERIAL_ECHOPAIR("] = ", endstop_adj[i]); + SERIAL_EOL; + } + #endif + } + } + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOLNPGM("<<< gcode_M666"); + } + #endif + } + +#elif ENABLED(Z_DUAL_ENDSTOPS) // !DELTA && ENABLED(Z_DUAL_ENDSTOPS) + + /** + * M666: For Z Dual Endstop setup, set z axis offset to the z2 axis. + */ + inline void gcode_M666() { + if (code_seen('Z')) z_endstop_adj = code_value_axis_units(Z_AXIS); + SERIAL_ECHOPAIR("Z Endstop Adjustment set to (mm):", z_endstop_adj); + SERIAL_EOL; + } + +#endif // !DELTA && Z_DUAL_ENDSTOPS + +#if ENABLED(FWRETRACT) + + /** + * M207: Set firmware retraction values + * + * S[+units] retract_length + * W[+units] retract_length_swap (multi-extruder) + * F[units/min] retract_feedrate_mm_s + * Z[units] retract_zlift + */ + inline void gcode_M207() { + if (code_seen('S')) retract_length = code_value_axis_units(E_AXIS); + if (code_seen('F')) retract_feedrate_mm_s = MMM_TO_MMS(code_value_axis_units(E_AXIS)); + if (code_seen('Z')) retract_zlift = code_value_axis_units(Z_AXIS); + #if EXTRUDERS > 1 + if (code_seen('W')) retract_length_swap = code_value_axis_units(E_AXIS); + #endif + } + + /** + * M208: Set firmware un-retraction values + * + * S[+units] retract_recover_length (in addition to M207 S*) + * W[+units] retract_recover_length_swap (multi-extruder) + * F[units/min] retract_recover_feedrate_mm_s + */ + inline void gcode_M208() { + if (code_seen('S')) retract_recover_length = code_value_axis_units(E_AXIS); + if (code_seen('F')) retract_recover_feedrate_mm_s = MMM_TO_MMS(code_value_axis_units(E_AXIS)); + #if EXTRUDERS > 1 + if (code_seen('W')) retract_recover_length_swap = code_value_axis_units(E_AXIS); + #endif + } + + /** + * M209: Enable automatic retract (M209 S1) + * detect if the slicer did not support G10/11: every normal extrude-only move will be classified as retract depending on the direction. + */ + inline void gcode_M209() { + if (code_seen('S')) { + int t = code_value_int(); + switch (t) { + case 0: + autoretract_enabled = false; + break; + case 1: + autoretract_enabled = true; + break; + default: + unknown_command_error(); + return; + } + for (int i = 0; i < EXTRUDERS; i++) retracted[i] = false; + } + } + +#endif // FWRETRACT + +#if HOTENDS > 1 + + /** + * M218 - set hotend offset (in linear units) + * + * T + * X + * Y + * Z - Available with DUAL_X_CARRIAGE and SWITCHING_EXTRUDER + */ + inline void gcode_M218() { + if (get_target_extruder_from_command(218)) return; + + if (code_seen('X')) hotend_offset[X_AXIS][target_extruder] = code_value_axis_units(X_AXIS); + if (code_seen('Y')) hotend_offset[Y_AXIS][target_extruder] = code_value_axis_units(Y_AXIS); + + #if ENABLED(DUAL_X_CARRIAGE) || ENABLED(SWITCHING_EXTRUDER) + if (code_seen('Z')) hotend_offset[Z_AXIS][target_extruder] = code_value_axis_units(Z_AXIS); + #endif + + SERIAL_ECHO_START; + SERIAL_ECHOPGM(MSG_HOTEND_OFFSET); + HOTEND_LOOP() { + SERIAL_CHAR(' '); + SERIAL_ECHO(hotend_offset[X_AXIS][e]); + SERIAL_CHAR(','); + SERIAL_ECHO(hotend_offset[Y_AXIS][e]); + #if ENABLED(DUAL_X_CARRIAGE) || ENABLED(SWITCHING_EXTRUDER) + SERIAL_CHAR(','); + SERIAL_ECHO(hotend_offset[Z_AXIS][e]); + #endif + } + SERIAL_EOL; + } + +#endif // HOTENDS > 1 + +/** + * M220: Set speed percentage factor, aka "Feed Rate" (M220 S95) + */ +inline void gcode_M220() { + if (code_seen('S')) feedrate_percentage = code_value_int(); +} + +/** + * M221: Set extrusion percentage (M221 T0 S95) + */ +inline void gcode_M221() { + if (get_target_extruder_from_command(221)) return; + if (code_seen('S')) + extruder_multiplier[target_extruder] = code_value_int(); +} + +/** + * M226: Wait until the specified pin reaches the state required (M226 P S) + */ +inline void gcode_M226() { + if (code_seen('P')) { + int pin_number = code_value_int(); + + int pin_state = code_seen('S') ? code_value_int() : -1; // required pin state - default is inverted + + if (pin_state >= -1 && pin_state <= 1) { + + for (uint8_t i = 0; i < COUNT(sensitive_pins); i++) { + if (sensitive_pins[i] == pin_number) { + pin_number = -1; + break; + } + } + + if (pin_number > -1) { + int target = LOW; + + stepper.synchronize(); + + pinMode(pin_number, INPUT); + + switch (pin_state) { + case 1: + target = HIGH; + break; + + case 0: + target = LOW; + break; + + case -1: + target = !digitalRead(pin_number); + break; + } + + while (digitalRead(pin_number) != target) idle(); + + } // pin_number > -1 + } // pin_state -1 0 1 + } // code_seen('P') +} + +#if HAS_SERVOS + + /** + * M280: Get or set servo position. P [S] + */ + inline void gcode_M280() { + if (!code_seen('P')) return; + int servo_index = code_value_int(); + if (servo_index >= 0 && servo_index < NUM_SERVOS) { + if (code_seen('S')) + MOVE_SERVO(servo_index, code_value_int()); + else { + SERIAL_ECHO_START; + SERIAL_ECHOPGM(" Servo "); + SERIAL_ECHO(servo_index); + SERIAL_ECHOPGM(": "); + SERIAL_ECHOLN(servo[servo_index].read()); + } + } + else { + SERIAL_ERROR_START; + SERIAL_ERROR("Servo "); + SERIAL_ERROR(servo_index); + SERIAL_ERRORLN(" out of range"); + } + } + +#endif // HAS_SERVOS + +#if HAS_BUZZER + + /** + * M300: Play beep sound S P + */ + inline void gcode_M300() { + uint16_t const frequency = code_seen('S') ? code_value_ushort() : 260; + uint16_t duration = code_seen('P') ? code_value_ushort() : 1000; + + // Limits the tone duration to 0-5 seconds. + NOMORE(duration, 5000); + + BUZZ(duration, frequency); + } + +#endif // HAS_BUZZER + +#if ENABLED(PIDTEMP) + + /** + * M301: Set PID parameters P I D (and optionally C, L) + * + * P[float] Kp term + * I[float] Ki term (unscaled) + * D[float] Kd term (unscaled) + * + * With PID_EXTRUSION_SCALING: + * + * C[float] Kc term + * L[float] LPQ length + */ + inline void gcode_M301() { + + // multi-extruder PID patch: M301 updates or prints a single extruder's PID values + // default behaviour (omitting E parameter) is to update for extruder 0 only + int e = code_seen('E') ? code_value_int() : 0; // extruder being updated + + if (e < HOTENDS) { // catch bad input value + if (code_seen('P')) PID_PARAM(Kp, e) = code_value_float(); + if (code_seen('I')) PID_PARAM(Ki, e) = scalePID_i(code_value_float()); + if (code_seen('D')) PID_PARAM(Kd, e) = scalePID_d(code_value_float()); + #if ENABLED(PID_EXTRUSION_SCALING) + if (code_seen('C')) PID_PARAM(Kc, e) = code_value_float(); + if (code_seen('L')) lpq_len = code_value_float(); + NOMORE(lpq_len, LPQ_MAX_LEN); + #endif + + thermalManager.updatePID(); + SERIAL_ECHO_START; + #if ENABLED(PID_PARAMS_PER_HOTEND) + SERIAL_ECHOPGM(" e:"); // specify extruder in serial output + SERIAL_ECHO(e); + #endif // PID_PARAMS_PER_HOTEND + SERIAL_ECHOPGM(" p:"); + SERIAL_ECHO(PID_PARAM(Kp, e)); + SERIAL_ECHOPGM(" i:"); + SERIAL_ECHO(unscalePID_i(PID_PARAM(Ki, e))); + SERIAL_ECHOPGM(" d:"); + SERIAL_ECHO(unscalePID_d(PID_PARAM(Kd, e))); + #if ENABLED(PID_EXTRUSION_SCALING) + SERIAL_ECHOPGM(" c:"); + //Kc does not have scaling applied above, or in resetting defaults + SERIAL_ECHO(PID_PARAM(Kc, e)); + #endif + SERIAL_EOL; + } + else { + SERIAL_ERROR_START; + SERIAL_ERRORLN(MSG_INVALID_EXTRUDER); + } + } + +#endif // PIDTEMP + +#if ENABLED(PIDTEMPBED) + + inline void gcode_M304() { + if (code_seen('P')) thermalManager.bedKp = code_value_float(); + if (code_seen('I')) thermalManager.bedKi = scalePID_i(code_value_float()); + if (code_seen('D')) thermalManager.bedKd = scalePID_d(code_value_float()); + + thermalManager.updatePID(); + + SERIAL_ECHO_START; + SERIAL_ECHOPGM(" p:"); + SERIAL_ECHO(thermalManager.bedKp); + SERIAL_ECHOPGM(" i:"); + SERIAL_ECHO(unscalePID_i(thermalManager.bedKi)); + SERIAL_ECHOPGM(" d:"); + SERIAL_ECHOLN(unscalePID_d(thermalManager.bedKd)); + } + +#endif // PIDTEMPBED + +#if defined(CHDK) || HAS_PHOTOGRAPH + + /** + * M240: Trigger a camera by emulating a Canon RC-1 + * See http://www.doc-diy.net/photo/rc-1_hacked/ + */ + inline void gcode_M240() { + #ifdef CHDK + + OUT_WRITE(CHDK, HIGH); + chdkHigh = millis(); + chdkActive = true; + + #elif HAS_PHOTOGRAPH + + const uint8_t NUM_PULSES = 16; + const float PULSE_LENGTH = 0.01524; + for (int i = 0; i < NUM_PULSES; i++) { + WRITE(PHOTOGRAPH_PIN, HIGH); + _delay_ms(PULSE_LENGTH); + WRITE(PHOTOGRAPH_PIN, LOW); + _delay_ms(PULSE_LENGTH); + } + delay(7.33); + for (int i = 0; i < NUM_PULSES; i++) { + WRITE(PHOTOGRAPH_PIN, HIGH); + _delay_ms(PULSE_LENGTH); + WRITE(PHOTOGRAPH_PIN, LOW); + _delay_ms(PULSE_LENGTH); + } + + #endif // !CHDK && HAS_PHOTOGRAPH + } + +#endif // CHDK || PHOTOGRAPH_PIN + +#if HAS_LCD_CONTRAST + + /** + * M250: Read and optionally set the LCD contrast + */ + inline void gcode_M250() { + if (code_seen('C')) set_lcd_contrast(code_value_int()); + SERIAL_PROTOCOLPGM("lcd contrast value: "); + SERIAL_PROTOCOL(lcd_contrast); + SERIAL_EOL; + } + +#endif // HAS_LCD_CONTRAST + +#if ENABLED(PREVENT_DANGEROUS_EXTRUDE) + + /** + * M302: Allow cold extrudes, or set the minimum extrude temperature + * + * S sets the minimum extrude temperature + * P enables (1) or disables (0) cold extrusion + * + * Examples: + * + * M302 ; report current cold extrusion state + * M302 P0 ; enable cold extrusion checking + * M302 P1 ; disables 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 + */ + inline void gcode_M302() { + bool seen_S = code_seen('S'); + if (seen_S) { + thermalManager.extrude_min_temp = code_value_temp_abs(); + thermalManager.allow_cold_extrude = (thermalManager.extrude_min_temp == 0); + } + + if (code_seen('P')) + thermalManager.allow_cold_extrude = (thermalManager.extrude_min_temp == 0) || code_value_bool(); + else if (!seen_S) { + // Report current state + SERIAL_ECHO_START; + SERIAL_ECHOPAIR("Cold extrudes are ", (thermalManager.allow_cold_extrude ? "en" : "dis")); + SERIAL_ECHOPAIR("abled (min temp ", int(thermalManager.extrude_min_temp + 0.5)); + SERIAL_ECHOLNPGM("C)"); + } + } + +#endif // PREVENT_DANGEROUS_EXTRUDE + +/** + * M303: PID relay autotune + * + * S sets the target temperature. (default 150C) + * E (-1 for the bed) (default 0) + * C + * U with a non-zero value will apply the result to current settings + */ +inline void gcode_M303() { + #if HAS_PID_HEATING + int e = code_seen('E') ? code_value_int() : 0; + int c = code_seen('C') ? code_value_int() : 5; + bool u = code_seen('U') && code_value_bool(); + + float temp = code_seen('S') ? code_value_temp_abs() : (e < 0 ? 70.0 : 150.0); + + if (e >= 0 && e < HOTENDS) + target_extruder = e; + + KEEPALIVE_STATE(NOT_BUSY); // don't send "busy: processing" messages during autotune output + + thermalManager.PID_autotune(temp, e, c, u); + + KEEPALIVE_STATE(IN_HANDLER); + #else + SERIAL_ERROR_START; + SERIAL_ERRORLNPGM(MSG_ERR_M303_DISABLED); + #endif +} + +#if ENABLED(SCARA) + bool SCARA_move_to_cal(uint8_t delta_x, uint8_t delta_y) { + //SoftEndsEnabled = false; // Ignore soft endstops during calibration + //SERIAL_ECHOLNPGM(" Soft endstops disabled"); + if (IsRunning()) { + //gcode_get_destination(); // For X Y Z E F + delta[X_AXIS] = delta_x; + delta[Y_AXIS] = delta_y; + forward_kinematics_SCARA(delta); + destination[X_AXIS] = delta[X_AXIS] / axis_scaling[X_AXIS]; + destination[Y_AXIS] = delta[Y_AXIS] / axis_scaling[Y_AXIS]; + prepare_move_to_destination(); + //ok_to_send(); + return true; + } + return false; + } + + /** + * M360: SCARA calibration: Move to cal-position ThetaA (0 deg calibration) + */ + inline bool gcode_M360() { + SERIAL_ECHOLNPGM(" Cal: Theta 0"); + return SCARA_move_to_cal(0, 120); + } + + /** + * M361: SCARA calibration: Move to cal-position ThetaB (90 deg calibration - steps per degree) + */ + inline bool gcode_M361() { + SERIAL_ECHOLNPGM(" Cal: Theta 90"); + return SCARA_move_to_cal(90, 130); + } + + /** + * M362: SCARA calibration: Move to cal-position PsiA (0 deg calibration) + */ + inline bool gcode_M362() { + SERIAL_ECHOLNPGM(" Cal: Psi 0"); + return SCARA_move_to_cal(60, 180); + } + + /** + * M363: SCARA calibration: Move to cal-position PsiB (90 deg calibration - steps per degree) + */ + inline bool gcode_M363() { + SERIAL_ECHOLNPGM(" Cal: Psi 90"); + return SCARA_move_to_cal(50, 90); + } + + /** + * M364: SCARA calibration: Move to cal-position PSIC (90 deg to Theta calibration position) + */ + inline bool gcode_M364() { + SERIAL_ECHOLNPGM(" Cal: Theta-Psi 90"); + return SCARA_move_to_cal(45, 135); + } + + /** + * M365: SCARA calibration: Scaling factor, X, Y, Z axis + */ + inline void gcode_M365() { + LOOP_XYZ(i) + if (code_seen(axis_codes[i])) + axis_scaling[i] = code_value_float(); + } + +#endif // SCARA + +#if ENABLED(EXT_SOLENOID) + + void enable_solenoid(uint8_t num) { + switch (num) { + case 0: + OUT_WRITE(SOL0_PIN, HIGH); + break; + #if HAS_SOLENOID_1 + case 1: + OUT_WRITE(SOL1_PIN, HIGH); + break; + #endif + #if HAS_SOLENOID_2 + case 2: + OUT_WRITE(SOL2_PIN, HIGH); + break; + #endif + #if HAS_SOLENOID_3 + case 3: + OUT_WRITE(SOL3_PIN, HIGH); + break; + #endif + default: + SERIAL_ECHO_START; + SERIAL_ECHOLNPGM(MSG_INVALID_SOLENOID); + break; + } + } + + void enable_solenoid_on_active_extruder() { enable_solenoid(active_extruder); } + + void disable_all_solenoids() { + OUT_WRITE(SOL0_PIN, LOW); + OUT_WRITE(SOL1_PIN, LOW); + OUT_WRITE(SOL2_PIN, LOW); + OUT_WRITE(SOL3_PIN, LOW); + } + + /** + * M380: Enable solenoid on the active extruder + */ + inline void gcode_M380() { enable_solenoid_on_active_extruder(); } + + /** + * M381: Disable all solenoids + */ + inline void gcode_M381() { disable_all_solenoids(); } + +#endif // EXT_SOLENOID + +/** + * M400: Finish all moves + */ +inline void gcode_M400() { stepper.synchronize(); } + +#if HAS_BED_PROBE + + /** + * M401: Engage Z Servo endstop if available + */ + inline void gcode_M401() { DEPLOY_PROBE(); } + + /** + * M402: Retract Z Servo endstop if enabled + */ + inline void gcode_M402() { STOW_PROBE(); } + +#endif // HAS_BED_PROBE + +#if ENABLED(FILAMENT_WIDTH_SENSOR) + + /** + * M404: Display or set (in current units) the nominal filament width (3mm, 1.75mm ) W<3.0> + */ + inline void gcode_M404() { + if (code_seen('W')) { + filament_width_nominal = code_value_linear_units(); + } + else { + SERIAL_PROTOCOLPGM("Filament dia (nominal mm):"); + SERIAL_PROTOCOLLN(filament_width_nominal); + } + } + + /** + * M405: Turn on filament sensor for control + */ + inline void gcode_M405() { + // This is technically a linear measurement, but since it's quantized to centimeters and is a different unit than + // everything else, it uses code_value_int() instead of code_value_linear_units(). + if (code_seen('D')) meas_delay_cm = code_value_int(); + NOMORE(meas_delay_cm, MAX_MEASUREMENT_DELAY); + + if (filwidth_delay_index2 == -1) { // Initialize the ring buffer if not done since startup + int temp_ratio = thermalManager.widthFil_to_size_ratio(); + + for (uint8_t i = 0; i < COUNT(measurement_delay); ++i) + measurement_delay[i] = temp_ratio - 100; // Subtract 100 to scale within a signed byte + + filwidth_delay_index1 = filwidth_delay_index2 = 0; + } + + filament_sensor = true; + + //SERIAL_PROTOCOLPGM("Filament dia (measured mm):"); + //SERIAL_PROTOCOL(filament_width_meas); + //SERIAL_PROTOCOLPGM("Extrusion ratio(%):"); + //SERIAL_PROTOCOL(extruder_multiplier[active_extruder]); + } + + /** + * M406: Turn off filament sensor for control + */ + inline void gcode_M406() { filament_sensor = false; } + + /** + * M407: Get measured filament diameter on serial output + */ + inline void gcode_M407() { + SERIAL_PROTOCOLPGM("Filament dia (measured mm):"); + SERIAL_PROTOCOLLN(filament_width_meas); + } + +#endif // FILAMENT_WIDTH_SENSOR + +void quickstop_stepper() { + stepper.quick_stop(); + #if DISABLED(SCARA) + stepper.synchronize(); + LOOP_XYZ(i) set_current_from_steppers_for_axis((AxisEnum)i); + SYNC_PLAN_POSITION_KINEMATIC(); + #endif +} + +#if ENABLED(MESH_BED_LEVELING) + + /** + * M420: Enable/Disable Mesh Bed Leveling + */ + inline void gcode_M420() { if (code_seen('S') && code_has_value()) mbl.set_has_mesh(code_value_bool()); } + + /** + * M421: Set a single Mesh Bed Leveling Z coordinate + * Use either 'M421 X Y Z' or 'M421 I J Z' + */ + inline void gcode_M421() { + int8_t px = 0, py = 0; + float z = 0; + bool hasX, hasY, hasZ, hasI, hasJ; + if ((hasX = code_seen('X'))) px = mbl.probe_index_x(code_value_axis_units(X_AXIS)); + if ((hasY = code_seen('Y'))) py = mbl.probe_index_y(code_value_axis_units(Y_AXIS)); + if ((hasI = code_seen('I'))) px = code_value_axis_units(X_AXIS); + if ((hasJ = code_seen('J'))) py = code_value_axis_units(Y_AXIS); + if ((hasZ = code_seen('Z'))) z = code_value_axis_units(Z_AXIS); + + if (hasX && hasY && hasZ) { + + if (px >= 0 && py >= 0) + mbl.set_z(px, py, z); + else { + SERIAL_ERROR_START; + SERIAL_ERRORLNPGM(MSG_ERR_MESH_XY); + } + } + else if (hasI && hasJ && hasZ) { + if (px >= 0 && px < MESH_NUM_X_POINTS && py >= 0 && py < MESH_NUM_Y_POINTS) + mbl.set_z(px, py, z); + else { + SERIAL_ERROR_START; + SERIAL_ERRORLNPGM(MSG_ERR_MESH_XY); + } + } + else { + SERIAL_ERROR_START; + SERIAL_ERRORLNPGM(MSG_ERR_M421_PARAMETERS); + } + } + +#endif + +/** + * M428: Set home_offset based on the distance between the + * current_position and the nearest "reference point." + * If an axis is past center its endstop position + * is the reference-point. Otherwise it uses 0. This allows + * the Z offset to be set near the bed when using a max endstop. + * + * M428 can't be used more than 2cm away from 0 or an endstop. + * + * Use M206 to set these values directly. + */ +inline void gcode_M428() { + bool err = false; + LOOP_XYZ(i) { + if (axis_homed[i]) { + float base = (current_position[i] > (sw_endstop_min[i] + sw_endstop_max[i]) * 0.5) ? base_home_pos(i) : 0, + diff = current_position[i] - LOGICAL_POSITION(base, i); + if (diff > -20 && diff < 20) { + set_home_offset((AxisEnum)i, home_offset[i] - diff); + } + else { + SERIAL_ERROR_START; + SERIAL_ERRORLNPGM(MSG_ERR_M428_TOO_FAR); + LCD_ALERTMESSAGEPGM("Err: Too far!"); + BUZZ(200, 40); + err = true; + break; + } + } + } + + if (!err) { + SYNC_PLAN_POSITION_KINEMATIC(); + report_current_position(); + LCD_MESSAGEPGM(MSG_HOME_OFFSETS_APPLIED); + BUZZ(200, 659); + BUZZ(200, 698); + } +} + +/** + * M500: Store settings in EEPROM + */ +inline void gcode_M500() { + Config_StoreSettings(); +} + +/** + * M501: Read settings from EEPROM + */ +inline void gcode_M501() { + Config_RetrieveSettings(); +} + +/** + * M502: Revert to default settings + */ +inline void gcode_M502() { + Config_ResetDefault(); +} + +/** + * M503: print settings currently in memory + */ +inline void gcode_M503() { + Config_PrintSettings(code_seen('S') && !code_value_bool()); +} + +#if ENABLED(ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED) + + /** + * M540: Set whether SD card print should abort on endstop hit (M540 S<0|1>) + */ + inline void gcode_M540() { + if (code_seen('S')) stepper.abort_on_endstop_hit = code_value_bool(); + } + +#endif // ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED + +#if HAS_BED_PROBE + + inline void gcode_M851() { + + SERIAL_ECHO_START; + SERIAL_ECHOPGM(MSG_ZPROBE_ZOFFSET); + SERIAL_CHAR(' '); + + if (code_seen('Z')) { + float value = code_value_axis_units(Z_AXIS); + if (Z_PROBE_OFFSET_RANGE_MIN <= value && value <= Z_PROBE_OFFSET_RANGE_MAX) { + zprobe_zoffset = value; + SERIAL_ECHO(zprobe_zoffset); + } + else { + SERIAL_ECHOPGM(MSG_Z_MIN); + SERIAL_ECHO(Z_PROBE_OFFSET_RANGE_MIN); + SERIAL_CHAR(' '); + SERIAL_ECHOPGM(MSG_Z_MAX); + SERIAL_ECHO(Z_PROBE_OFFSET_RANGE_MAX); + } + } + else { + SERIAL_ECHOPAIR(": ", zprobe_zoffset); + } + + SERIAL_EOL; + } + +#endif // HAS_BED_PROBE + +#if ENABLED(FILAMENT_CHANGE_FEATURE) + + /** + * M600: Pause for filament change + * + * E[distance] - Retract the filament this far (negative value) + * Z[distance] - Move the Z axis by this distance + * X[position] - Move to this X position, with Y + * Y[position] - Move to this Y position, with X + * L[distance] - Retract distance for removal (manual reload) + * + * Default values are used for omitted arguments. + * + */ + inline void gcode_M600() { + + if (thermalManager.tooColdToExtrude(active_extruder)) { + SERIAL_ERROR_START; + SERIAL_ERRORLNPGM(MSG_TOO_COLD_FOR_M600); + return; + } + + // Show initial message and wait for synchronize steppers + lcd_filament_change_show_message(FILAMENT_CHANGE_MESSAGE_INIT); + stepper.synchronize(); + + float lastpos[NUM_AXIS]; + + // Save current position of all axes + LOOP_XYZE(i) + lastpos[i] = destination[i] = current_position[i]; + + // Define runplan for move axes + #if ENABLED(DELTA) + #define RUNPLAN(RATE_MM_S) inverse_kinematics(destination); \ + planner.buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], destination[E_AXIS], RATE_MM_S, active_extruder); + #else + #define RUNPLAN(RATE_MM_S) line_to_destination(MMS_TO_MMM(RATE_MM_S)); + #endif + + KEEPALIVE_STATE(IN_HANDLER); + + // Initial retract before move to filament change position + if (code_seen('E')) destination[E_AXIS] += code_value_axis_units(E_AXIS); + #if defined(FILAMENT_CHANGE_RETRACT_LENGTH) && FILAMENT_CHANGE_RETRACT_LENGTH > 0 + else destination[E_AXIS] -= FILAMENT_CHANGE_RETRACT_LENGTH; + #endif + + RUNPLAN(FILAMENT_CHANGE_RETRACT_FEEDRATE); + + // Lift Z axis + float z_lift = code_seen('Z') ? code_value_axis_units(Z_AXIS) : + #if defined(FILAMENT_CHANGE_Z_ADD) && FILAMENT_CHANGE_Z_ADD > 0 + FILAMENT_CHANGE_Z_ADD + #else + 0 + #endif + ; + + if (z_lift > 0) { + destination[Z_AXIS] += z_lift; + NOMORE(destination[Z_AXIS], Z_MAX_POS); + RUNPLAN(FILAMENT_CHANGE_Z_FEEDRATE); + } + + // Move XY axes to filament exchange position + if (code_seen('X')) destination[X_AXIS] = code_value_axis_units(X_AXIS); + #ifdef FILAMENT_CHANGE_X_POS + else destination[X_AXIS] = FILAMENT_CHANGE_X_POS; + #endif + + if (code_seen('Y')) destination[Y_AXIS] = code_value_axis_units(Y_AXIS); + #ifdef FILAMENT_CHANGE_Y_POS + else destination[Y_AXIS] = FILAMENT_CHANGE_Y_POS; + #endif + + RUNPLAN(FILAMENT_CHANGE_XY_FEEDRATE); + + stepper.synchronize(); + lcd_filament_change_show_message(FILAMENT_CHANGE_MESSAGE_UNLOAD); + + // Unload filament + if (code_seen('L')) destination[E_AXIS] += code_value_axis_units(E_AXIS); + #if defined(FILAMENT_CHANGE_UNLOAD_LENGTH) && FILAMENT_CHANGE_UNLOAD_LENGTH > 0 + else destination[E_AXIS] -= FILAMENT_CHANGE_UNLOAD_LENGTH; + #endif + + RUNPLAN(FILAMENT_CHANGE_UNLOAD_FEEDRATE); + + // Synchronize steppers and then disable extruders steppers for manual filament changing + stepper.synchronize(); + disable_e0(); + disable_e1(); + disable_e2(); + disable_e3(); + delay(100); + + #if HAS_BUZZER + millis_t next_tick = 0; + #endif + + // Wait for filament insert by user and press button + lcd_filament_change_show_message(FILAMENT_CHANGE_MESSAGE_INSERT); + + while (!lcd_clicked()) { + #if HAS_BUZZER + millis_t ms = millis(); + if (ms >= next_tick) { + BUZZ(300, 2000); + next_tick = ms + 2500; // Beep every 2.5s while waiting + } + #endif + idle(true); + } + delay(100); + while (lcd_clicked()) idle(true); + delay(100); + + // Show load message + lcd_filament_change_show_message(FILAMENT_CHANGE_MESSAGE_LOAD); + + // Load filament + if (code_seen('L')) destination[E_AXIS] -= code_value_axis_units(E_AXIS); + #if defined(FILAMENT_CHANGE_LOAD_LENGTH) && FILAMENT_CHANGE_LOAD_LENGTH > 0 + else destination[E_AXIS] += FILAMENT_CHANGE_LOAD_LENGTH; + #endif + + RUNPLAN(FILAMENT_CHANGE_LOAD_FEEDRATE); + stepper.synchronize(); + + #if defined(FILAMENT_CHANGE_EXTRUDE_LENGTH) && FILAMENT_CHANGE_EXTRUDE_LENGTH > 0 + do { + // Extrude filament to get into hotend + lcd_filament_change_show_message(FILAMENT_CHANGE_MESSAGE_EXTRUDE); + destination[E_AXIS] += FILAMENT_CHANGE_EXTRUDE_LENGTH; + RUNPLAN(FILAMENT_CHANGE_EXTRUDE_FEEDRATE); + stepper.synchronize(); + // Ask user if more filament should be extruded + KEEPALIVE_STATE(PAUSED_FOR_USER); + lcd_filament_change_show_message(FILAMENT_CHANGE_MESSAGE_OPTION); + while (filament_change_menu_response == FILAMENT_CHANGE_RESPONSE_WAIT_FOR) idle(true); + KEEPALIVE_STATE(IN_HANDLER); + } while (filament_change_menu_response != FILAMENT_CHANGE_RESPONSE_RESUME_PRINT); + #endif + + lcd_filament_change_show_message(FILAMENT_CHANGE_MESSAGE_RESUME); + + KEEPALIVE_STATE(IN_HANDLER); + + // Set extruder to saved position + current_position[E_AXIS] = lastpos[E_AXIS]; + destination[E_AXIS] = lastpos[E_AXIS]; + planner.set_e_position_mm(current_position[E_AXIS]); + + #if ENABLED(DELTA) + // Move XYZ to starting position, then E + inverse_kinematics(lastpos); + planner.buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], destination[E_AXIS], FILAMENT_CHANGE_XY_FEEDRATE, active_extruder); + planner.buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], lastpos[E_AXIS], FILAMENT_CHANGE_XY_FEEDRATE, active_extruder); + #else + // Move XY to starting position, then Z, then E + destination[X_AXIS] = lastpos[X_AXIS]; + destination[Y_AXIS] = lastpos[Y_AXIS]; + RUNPLAN(FILAMENT_CHANGE_XY_FEEDRATE); + destination[Z_AXIS] = lastpos[Z_AXIS]; + RUNPLAN(FILAMENT_CHANGE_Z_FEEDRATE); + #endif + stepper.synchronize(); + + #if ENABLED(FILAMENT_RUNOUT_SENSOR) + filament_ran_out = false; + #endif + + // Show status screen + lcd_filament_change_show_message(FILAMENT_CHANGE_MESSAGE_STATUS); + } + +#endif // FILAMENT_CHANGE_FEATURE + +#if ENABLED(DUAL_X_CARRIAGE) + + /** + * M605: Set dual x-carriage movement mode + * + * M605 S0: Full control mode. The slicer has full control over x-carriage movement + * M605 S1: Auto-park mode. The inactive head will auto park/unpark without slicer involvement + * M605 S2 [Xnnn] [Rmmm]: Duplication mode. The second extruder will duplicate the first with nnn + * units x-offset and an optional differential hotend temperature of + * mmm degrees. E.g., with "M605 S2 X100 R2" the second extruder will duplicate + * the first with a spacing of 100mm in the x direction and 2 degrees hotter. + * + * Note: the X axis should be homed after changing dual x-carriage mode. + */ + inline void gcode_M605() { + stepper.synchronize(); + if (code_seen('S')) dual_x_carriage_mode = code_value_byte(); + switch (dual_x_carriage_mode) { + case DXC_DUPLICATION_MODE: + if (code_seen('X')) duplicate_extruder_x_offset = max(code_value_axis_units(X_AXIS), X2_MIN_POS - x_home_pos(0)); + if (code_seen('R')) duplicate_extruder_temp_offset = code_value_temp_diff(); + SERIAL_ECHO_START; + SERIAL_ECHOPGM(MSG_HOTEND_OFFSET); + SERIAL_CHAR(' '); + SERIAL_ECHO(hotend_offset[X_AXIS][0]); + SERIAL_CHAR(','); + SERIAL_ECHO(hotend_offset[Y_AXIS][0]); + SERIAL_CHAR(' '); + SERIAL_ECHO(duplicate_extruder_x_offset); + SERIAL_CHAR(','); + SERIAL_ECHOLN(hotend_offset[Y_AXIS][1]); + break; + case DXC_FULL_CONTROL_MODE: + case DXC_AUTO_PARK_MODE: + break; + default: + dual_x_carriage_mode = DEFAULT_DUAL_X_CARRIAGE_MODE; + break; + } + active_extruder_parked = false; + extruder_duplication_enabled = false; + delayed_move_time = 0; + } + +#elif ENABLED(DUAL_NOZZLE_DUPLICATION_MODE) + + inline void gcode_M605() { + stepper.synchronize(); + extruder_duplication_enabled = code_seen('S') && code_value_int() == 2; + SERIAL_ECHO_START; + SERIAL_ECHOPAIR(MSG_DUPLICATION_MODE, extruder_duplication_enabled ? MSG_ON : MSG_OFF); + SERIAL_EOL; + } + +#endif // M605 + +#if ENABLED(LIN_ADVANCE) + /** + * M905: Set advance factor + */ + inline void gcode_M905() { + stepper.synchronize(); + stepper.advance_M905(code_seen('K') ? code_value_float() : -1.0); + } +#endif + +/** + * M907: Set digital trimpot motor current using axis codes X, Y, Z, E, B, S + */ +inline void gcode_M907() { + #if HAS_DIGIPOTSS + LOOP_XYZE(i) + if (code_seen(axis_codes[i])) stepper.digipot_current(i, code_value_int()); + if (code_seen('B')) stepper.digipot_current(4, code_value_int()); + if (code_seen('S')) for (int i = 0; i <= 4; i++) stepper.digipot_current(i, code_value_int()); + #endif + #if PIN_EXISTS(MOTOR_CURRENT_PWM_XY) + if (code_seen('X')) stepper.digipot_current(0, code_value_int()); + #endif + #if PIN_EXISTS(MOTOR_CURRENT_PWM_Z) + if (code_seen('Z')) stepper.digipot_current(1, code_value_int()); + #endif + #if PIN_EXISTS(MOTOR_CURRENT_PWM_E) + if (code_seen('E')) stepper.digipot_current(2, code_value_int()); + #endif + #if ENABLED(DIGIPOT_I2C) + // this one uses actual amps in floating point + LOOP_XYZE(i) if (code_seen(axis_codes[i])) digipot_i2c_set_current(i, code_value_float()); + // for each additional extruder (named B,C,D,E..., channels 4,5,6,7...) + for (int i = NUM_AXIS; i < DIGIPOT_I2C_NUM_CHANNELS; i++) if (code_seen('B' + i - (NUM_AXIS))) digipot_i2c_set_current(i, code_value_float()); + #endif + #if ENABLED(DAC_STEPPER_CURRENT) + if (code_seen('S')) { + float dac_percent = code_value_float(); + for (uint8_t i = 0; i <= 4; i++) dac_current_percent(i, dac_percent); + } + LOOP_XYZE(i) if (code_seen(axis_codes[i])) dac_current_percent(i, code_value_float()); + #endif +} + +#if HAS_DIGIPOTSS || ENABLED(DAC_STEPPER_CURRENT) + + /** + * M908: Control digital trimpot directly (M908 P S) + */ + inline void gcode_M908() { + #if HAS_DIGIPOTSS + stepper.digitalPotWrite( + code_seen('P') ? code_value_int() : 0, + code_seen('S') ? code_value_int() : 0 + ); + #endif + #ifdef DAC_STEPPER_CURRENT + dac_current_raw( + code_seen('P') ? code_value_byte() : -1, + code_seen('S') ? code_value_ushort() : 0 + ); + #endif + } + + #if ENABLED(DAC_STEPPER_CURRENT) // As with Printrbot RevF + + inline void gcode_M909() { dac_print_values(); } + + inline void gcode_M910() { dac_commit_eeprom(); } + + #endif + +#endif // HAS_DIGIPOTSS || DAC_STEPPER_CURRENT + +#if HAS_MICROSTEPS + + // M350 Set microstepping mode. Warning: Steps per unit remains unchanged. S code sets stepping mode for all drivers. + inline void gcode_M350() { + if (code_seen('S')) for (int i = 0; i <= 4; i++) stepper.microstep_mode(i, code_value_byte()); + LOOP_XYZE(i) if (code_seen(axis_codes[i])) stepper.microstep_mode(i, code_value_byte()); + if (code_seen('B')) stepper.microstep_mode(4, code_value_byte()); + stepper.microstep_readings(); + } + + /** + * M351: Toggle MS1 MS2 pins directly with axis codes X Y Z E B + * S# determines MS1 or MS2, X# sets the pin high/low. + */ + inline void gcode_M351() { + if (code_seen('S')) switch (code_value_byte()) { + case 1: + LOOP_XYZE(i) if (code_seen(axis_codes[i])) stepper.microstep_ms(i, code_value_byte(), -1); + if (code_seen('B')) stepper.microstep_ms(4, code_value_byte(), -1); + break; + case 2: + LOOP_XYZE(i) if (code_seen(axis_codes[i])) stepper.microstep_ms(i, -1, code_value_byte()); + if (code_seen('B')) stepper.microstep_ms(4, -1, code_value_byte()); + break; + } + stepper.microstep_readings(); + } + +#endif // HAS_MICROSTEPS + +#if ENABLED(MIXING_EXTRUDER) + + /** + * M163: Set a single mix factor for a mixing extruder + * This is called "weight" by some systems. + * + * S[index] The channel index to set + * P[float] The mix value + * + */ + inline void gcode_M163() { + int mix_index = code_seen('S') ? code_value_int() : 0; + float mix_value = code_seen('P') ? code_value_float() : 0.0; + if (mix_index < MIXING_STEPPERS) mixing_factor[mix_index] = mix_value; + } + + #if MIXING_VIRTUAL_TOOLS > 1 + + /** + * M164: Store the current mix factors as a virtual tool. + * + * S[index] The virtual tool to store + * + */ + inline void gcode_M164() { + int tool_index = code_seen('S') ? code_value_int() : 0; + if (tool_index < MIXING_VIRTUAL_TOOLS) { + normalize_mix(); + for (uint8_t i = 0; i < MIXING_STEPPERS; i++) + mixing_virtual_tool_mix[tool_index][i] = mixing_factor[i]; + } + } + + #endif + + #if ENABLED(DIRECT_MIXING_IN_G1) + /** + * M165: Set multiple mix factors for a mixing extruder. + * Factors that are left out will be set to 0. + * All factors together must add up to 1.0. + * + * A[factor] Mix factor for extruder stepper 1 + * B[factor] Mix factor for extruder stepper 2 + * C[factor] Mix factor for extruder stepper 3 + * D[factor] Mix factor for extruder stepper 4 + * H[factor] Mix factor for extruder stepper 5 + * I[factor] Mix factor for extruder stepper 6 + * + */ + inline void gcode_M165() { gcode_get_mix(); } + #endif + +#endif // MIXING_EXTRUDER + +/** + * M999: Restart after being stopped + * + * Default behaviour is to flush the serial buffer and request + * a resend to the host starting on the last N line received. + * + * Sending "M999 S1" will resume printing without flushing the + * existing command buffer. + * + */ +inline void gcode_M999() { + Running = true; + lcd_reset_alert_level(); + + if (code_seen('S') && code_value_bool()) return; + + // gcode_LastN = Stopped_gcode_LastN; + FlushSerialRequestResend(); +} + +#if ENABLED(SWITCHING_EXTRUDER) + inline void move_extruder_servo(uint8_t e) { + const int angles[2] = SWITCHING_EXTRUDER_SERVO_ANGLES; + MOVE_SERVO(SWITCHING_EXTRUDER_SERVO_NR, angles[e]); + } +#endif + +inline void invalid_extruder_error(const uint8_t &e) { + SERIAL_ECHO_START; + SERIAL_CHAR('T'); + SERIAL_PROTOCOL_F(e, DEC); + SERIAL_ECHOLN(MSG_INVALID_EXTRUDER); +} + +void tool_change(const uint8_t tmp_extruder, const float fr_mm_m/*=0.0*/, bool no_move/*=false*/) { + #if ENABLED(MIXING_EXTRUDER) && MIXING_VIRTUAL_TOOLS > 1 + + if (tmp_extruder >= MIXING_VIRTUAL_TOOLS) { + invalid_extruder_error(tmp_extruder); + return; + } + + // T0-Tnnn: Switch virtual tool by changing the mix + for (uint8_t j = 0; j < MIXING_STEPPERS; j++) + mixing_factor[j] = mixing_virtual_tool_mix[tmp_extruder][j]; + + #else //!MIXING_EXTRUDER || MIXING_VIRTUAL_TOOLS <= 1 + + #if HOTENDS > 1 + + if (tmp_extruder >= EXTRUDERS) { + invalid_extruder_error(tmp_extruder); + return; + } + + float old_feedrate_mm_m = feedrate_mm_m; + + feedrate_mm_m = fr_mm_m > 0.0 ? (old_feedrate_mm_m = fr_mm_m) : XY_PROBE_FEEDRATE_MM_M; + + if (tmp_extruder != active_extruder) { + if (!no_move && axis_unhomed_error(true, true, true)) { + SERIAL_ECHOLNPGM("No move on toolchange"); + no_move = true; + } + + // Save current position to destination, for use later + set_destination_to_current(); + + #if ENABLED(DUAL_X_CARRIAGE) + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOPGM("Dual X Carriage Mode "); + switch (dual_x_carriage_mode) { + case DXC_DUPLICATION_MODE: SERIAL_ECHOLNPGM("DXC_DUPLICATION_MODE"); break; + case DXC_AUTO_PARK_MODE: SERIAL_ECHOLNPGM("DXC_AUTO_PARK_MODE"); break; + case DXC_FULL_CONTROL_MODE: SERIAL_ECHOLNPGM("DXC_FULL_CONTROL_MODE"); break; + } + } + #endif + + if (dual_x_carriage_mode == DXC_AUTO_PARK_MODE && IsRunning() && + (delayed_move_time || current_position[X_AXIS] != x_home_pos(active_extruder)) + ) { + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOPAIR("Raise to ", current_position[Z_AXIS] + TOOLCHANGE_PARK_ZLIFT); SERIAL_EOL; + SERIAL_ECHOPAIR("MoveX to ", x_home_pos(active_extruder)); SERIAL_EOL; + SERIAL_ECHOPAIR("Lower to ", current_position[Z_AXIS]); SERIAL_EOL; + } + #endif + // Park old head: 1) raise 2) move to park position 3) lower + for (uint8_t i = 0; i < 3; i++) + planner.buffer_line( + i == 0 ? current_position[X_AXIS] : x_home_pos(active_extruder), + current_position[Y_AXIS], + current_position[Z_AXIS] + (i == 2 ? 0 : TOOLCHANGE_PARK_ZLIFT), + current_position[E_AXIS], + planner.max_feedrate_mm_s[i == 1 ? X_AXIS : Z_AXIS], + active_extruder + ); + stepper.synchronize(); + } + + // apply Y & Z extruder offset (x offset is already used in determining home pos) + current_position[Y_AXIS] -= hotend_offset[Y_AXIS][active_extruder] - hotend_offset[Y_AXIS][tmp_extruder]; + current_position[Z_AXIS] -= hotend_offset[Z_AXIS][active_extruder] - hotend_offset[Z_AXIS][tmp_extruder]; + active_extruder = tmp_extruder; + + // This function resets the max/min values - the current position may be overwritten below. + set_axis_is_at_home(X_AXIS); + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("New Extruder", current_position); + #endif + + switch (dual_x_carriage_mode) { + case DXC_FULL_CONTROL_MODE: + current_position[X_AXIS] = LOGICAL_X_POSITION(inactive_extruder_x_pos); + inactive_extruder_x_pos = RAW_X_POSITION(destination[X_AXIS]); + break; + case DXC_DUPLICATION_MODE: + active_extruder_parked = (active_extruder == 0); // this triggers the second extruder to move into the duplication position + if (active_extruder_parked) + current_position[X_AXIS] = LOGICAL_X_POSITION(inactive_extruder_x_pos); + else + current_position[X_AXIS] = destination[X_AXIS] + duplicate_extruder_x_offset; + inactive_extruder_x_pos = RAW_X_POSITION(destination[X_AXIS]); + extruder_duplication_enabled = false; + break; + default: + // record raised toolhead position for use by unpark + memcpy(raised_parked_position, current_position, sizeof(raised_parked_position)); + raised_parked_position[Z_AXIS] += TOOLCHANGE_UNPARK_ZLIFT; + active_extruder_parked = true; + delayed_move_time = 0; + break; + } + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOPAIR("Active extruder parked: ", active_extruder_parked ? "yes" : "no"); + SERIAL_EOL; + DEBUG_POS("New extruder (parked)", current_position); + } + #endif + + // No extra case for AUTO_BED_LEVELING_FEATURE in DUAL_X_CARRIAGE. Does that mean they don't work together? + #else // !DUAL_X_CARRIAGE + + #if ENABLED(SWITCHING_EXTRUDER) + // <0 if the new nozzle is higher, >0 if lower. A bigger raise when lower. + float z_diff = hotend_offset[Z_AXIS][active_extruder] - hotend_offset[Z_AXIS][tmp_extruder], + z_raise = 0.3 + (z_diff > 0.0 ? z_diff : 0.0); + + // Always raise by some amount + planner.buffer_line( + current_position[X_AXIS], + current_position[Y_AXIS], + current_position[Z_AXIS] + z_raise, + current_position[E_AXIS], + planner.max_feedrate_mm_s[Z_AXIS], + active_extruder + ); + stepper.synchronize(); + + move_extruder_servo(active_extruder); + delay(500); + + // Move back down, if needed + if (z_raise != z_diff) { + planner.buffer_line( + current_position[X_AXIS], + current_position[Y_AXIS], + current_position[Z_AXIS] + z_diff, + current_position[E_AXIS], + planner.max_feedrate_mm_s[Z_AXIS], + active_extruder + ); + stepper.synchronize(); + } + #endif + + /** + * Set current_position to the position of the new nozzle. + * Offsets are based on linear distance, so we need to get + * the resulting position in coordinate space. + * + * - With grid or 3-point leveling, offset XYZ by a tilted vector + * - With mesh leveling, update Z for the new position + * - Otherwise, just use the raw linear distance + * + * Software endstops are altered here too. Consider a case where: + * E0 at X=0 ... E1 at X=10 + * When we switch to E1 now X=10, but E1 can't move left. + * To express this we apply the change in XY to the software endstops. + * E1 can move farther right than E0, so the right limit is extended. + * + * Note that we don't adjust the Z software endstops. Why not? + * Consider a case where Z=0 (here) and switching to E1 makes Z=1 + * because the bed is 1mm lower at the new position. As long as + * the first nozzle is out of the way, the carriage should be + * allowed to move 1mm lower. This technically "breaks" the + * Z software endstop. But this is technically correct (and + * there is no viable alternative). + */ + #if ENABLED(AUTO_BED_LEVELING_FEATURE) + // Offset extruder, make sure to apply the bed level rotation matrix + vector_3 tmp_offset_vec = vector_3(hotend_offset[X_AXIS][tmp_extruder], + hotend_offset[Y_AXIS][tmp_extruder], + 0), + act_offset_vec = vector_3(hotend_offset[X_AXIS][active_extruder], + hotend_offset[Y_AXIS][active_extruder], + 0), + offset_vec = tmp_offset_vec - act_offset_vec; + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + tmp_offset_vec.debug("tmp_offset_vec"); + act_offset_vec.debug("act_offset_vec"); + offset_vec.debug("offset_vec (BEFORE)"); + } + #endif + + offset_vec.apply_rotation(planner.bed_level_matrix.transpose(planner.bed_level_matrix)); + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) offset_vec.debug("offset_vec (AFTER)"); + #endif + + // Adjustments to the current position + float xydiff[2] = { offset_vec.x, offset_vec.y }; + current_position[Z_AXIS] += offset_vec.z; + + #else // !AUTO_BED_LEVELING_FEATURE + + float xydiff[2] = { + hotend_offset[X_AXIS][tmp_extruder] - hotend_offset[X_AXIS][active_extruder], + hotend_offset[Y_AXIS][tmp_extruder] - hotend_offset[Y_AXIS][active_extruder] + }; + + #if ENABLED(MESH_BED_LEVELING) + + if (mbl.active()) { + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) SERIAL_ECHOPAIR("Z before MBL: ", current_position[Z_AXIS]); + #endif + float xpos = RAW_CURRENT_POSITION(X_AXIS), + ypos = RAW_CURRENT_POSITION(Y_AXIS); + current_position[Z_AXIS] += mbl.get_z(xpos + xydiff[X_AXIS], ypos + xydiff[Y_AXIS]) - mbl.get_z(xpos, ypos); + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOPAIR(" after: ", current_position[Z_AXIS]); + SERIAL_EOL; + } + #endif + } + + #endif // MESH_BED_LEVELING + + #endif // !AUTO_BED_LEVELING_FEATURE + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOPAIR("Offset Tool XY by { ", xydiff[X_AXIS]); + SERIAL_ECHOPAIR(", ", xydiff[Y_AXIS]); + SERIAL_ECHOLNPGM(" }"); + } + #endif + + // The newly-selected extruder XY is actually at... + current_position[X_AXIS] += xydiff[X_AXIS]; + current_position[Y_AXIS] += xydiff[Y_AXIS]; + for (uint8_t i = X_AXIS; i <= Y_AXIS; i++) { + position_shift[i] += xydiff[i]; + update_software_endstops((AxisEnum)i); + } + + // Set the new active extruder + active_extruder = tmp_extruder; + + #endif // !DUAL_X_CARRIAGE + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("Sync After Toolchange", current_position); + #endif + + // Tell the planner the new "current position" + SYNC_PLAN_POSITION_KINEMATIC(); + + // Move to the "old position" (move the extruder into place) + if (!no_move && IsRunning()) { + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) DEBUG_POS("Move back", destination); + #endif + prepare_move_to_destination(); + } + + } // (tmp_extruder != active_extruder) + + stepper.synchronize(); + + #if ENABLED(EXT_SOLENOID) + disable_all_solenoids(); + enable_solenoid_on_active_extruder(); + #endif // EXT_SOLENOID + + feedrate_mm_m = old_feedrate_mm_m; + + #else // HOTENDS <= 1 + + // Set the new active extruder + active_extruder = tmp_extruder; + + UNUSED(fr_mm_m); + UNUSED(no_move); + + #endif // HOTENDS <= 1 + + SERIAL_ECHO_START; + SERIAL_ECHOPGM(MSG_ACTIVE_EXTRUDER); + SERIAL_PROTOCOLLN((int)active_extruder); + + #endif //!MIXING_EXTRUDER || MIXING_VIRTUAL_TOOLS <= 1 +} + +/** + * T0-T3: Switch tool, usually switching extruders + * + * F[units/min] Set the movement feedrate + * S1 Don't move the tool in XY after change + */ +inline void gcode_T(uint8_t tmp_extruder) { + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + SERIAL_ECHOPAIR(">>> gcode_T(", tmp_extruder); + SERIAL_ECHOLNPGM(")"); + DEBUG_POS("BEFORE", current_position); + } + #endif + + #if HOTENDS == 1 || (ENABLED(MIXING_EXTRUDER) && MIXING_VIRTUAL_TOOLS > 1) + + tool_change(tmp_extruder); + + #elif HOTENDS > 1 + + tool_change( + tmp_extruder, + code_seen('F') ? code_value_axis_units(X_AXIS) : 0.0, + (tmp_extruder == active_extruder) || (code_seen('S') && code_value_bool()) + ); + + #endif + + #if ENABLED(DEBUG_LEVELING_FEATURE) + if (DEBUGGING(LEVELING)) { + DEBUG_POS("AFTER", current_position); + SERIAL_ECHOLNPGM("<<< gcode_T"); + } + #endif +} + +/** + * Process a single command and dispatch it to its handler + * This is called from the main loop() + */ +void process_next_command() { + current_command = command_queue[cmd_queue_index_r]; + + if (DEBUGGING(ECHO)) { + SERIAL_ECHO_START; + SERIAL_ECHOLN(current_command); + } + + // Sanitize the current command: + // - Skip leading spaces + // - Bypass N[-0-9][0-9]*[ ]* + // - Overwrite * with nul to mark the end + while (*current_command == ' ') ++current_command; + if (*current_command == 'N' && NUMERIC_SIGNED(current_command[1])) { + current_command += 2; // skip N[-0-9] + while (NUMERIC(*current_command)) ++current_command; // skip [0-9]* + while (*current_command == ' ') ++current_command; // skip [ ]* + } + char* starpos = strchr(current_command, '*'); // * should always be the last parameter + if (starpos) while (*starpos == ' ' || *starpos == '*') *starpos-- = '\0'; // nullify '*' and ' ' + + char *cmd_ptr = current_command; + + // Get the command code, which must be G, M, or T + char command_code = *cmd_ptr++; + + // Skip spaces to get the numeric part + while (*cmd_ptr == ' ') cmd_ptr++; + + uint16_t codenum = 0; // define ahead of goto + + // Bail early if there's no code + bool code_is_good = NUMERIC(*cmd_ptr); + if (!code_is_good) goto ExitUnknownCommand; + + // Get and skip the code number + do { + codenum = (codenum * 10) + (*cmd_ptr - '0'); + cmd_ptr++; + } while (NUMERIC(*cmd_ptr)); + + // Skip all spaces to get to the first argument, or nul + while (*cmd_ptr == ' ') cmd_ptr++; + + // The command's arguments (if any) start here, for sure! + current_command_args = cmd_ptr; + + KEEPALIVE_STATE(IN_HANDLER); + + // Handle a known G, M, or T + switch (command_code) { + case 'G': switch (codenum) { + + // G0, G1 + case 0: + case 1: + gcode_G0_G1(); + break; + + // G2, G3 + #if ENABLED(ARC_SUPPORT) && DISABLED(SCARA) + case 2: // G2 - CW ARC + case 3: // G3 - CCW ARC + gcode_G2_G3(codenum == 2); + break; + #endif + + // G4 Dwell + case 4: + gcode_G4(); + break; + + #if ENABLED(BEZIER_CURVE_SUPPORT) + // G5 + case 5: // G5 - Cubic B_spline + gcode_G5(); + break; + #endif // BEZIER_CURVE_SUPPORT + + #if ENABLED(FWRETRACT) + case 10: // G10: retract + case 11: // G11: retract_recover + gcode_G10_G11(codenum == 10); + break; + #endif // FWRETRACT + + #if ENABLED(NOZZLE_CLEAN_FEATURE) + case 12: + gcode_G12(); // G12: Nozzle Clean + break; + #endif // NOZZLE_CLEAN_FEATURE + + #if ENABLED(INCH_MODE_SUPPORT) + case 20: //G20: Inch Mode + gcode_G20(); + break; + + case 21: //G21: MM Mode + gcode_G21(); + break; + #endif // INCH_MODE_SUPPORT + + #if ENABLED(NOZZLE_PARK_FEATURE) + case 27: // G27: Nozzle Park + gcode_G27(); + break; + #endif // NOZZLE_PARK_FEATURE + + case 28: // G28: Home all axes, one at a time + gcode_G28(); + break; + + #if ENABLED(AUTO_BED_LEVELING_FEATURE) || ENABLED(MESH_BED_LEVELING) + case 29: // G29 Detailed Z probe, probes the bed at 3 or more points. + gcode_G29(); + break; + #endif // AUTO_BED_LEVELING_FEATURE + + #if HAS_BED_PROBE + + case 30: // G30 Single Z probe + gcode_G30(); + break; + + #if ENABLED(Z_PROBE_SLED) + + case 31: // G31: dock the sled + gcode_G31(); + break; + + case 32: // G32: undock the sled + gcode_G32(); + break; + + #endif // Z_PROBE_SLED + #endif // HAS_BED_PROBE + + case 90: // G90 + relative_mode = false; + break; + case 91: // G91 + relative_mode = true; + break; + + case 92: // G92 + gcode_G92(); + break; + } + break; + + case 'M': switch (codenum) { + #if ENABLED(ULTIPANEL) + case 0: // M0 - Unconditional stop - Wait for user button press on LCD + case 1: // M1 - Conditional stop - Wait for user button press on LCD + gcode_M0_M1(); + break; + #endif // ULTIPANEL + + case 17: + gcode_M17(); + break; + + #if ENABLED(SDSUPPORT) + case 20: // M20 - list SD card + gcode_M20(); break; + case 21: // M21 - init SD card + gcode_M21(); break; + case 22: //M22 - release SD card + gcode_M22(); break; + case 23: //M23 - Select file + gcode_M23(); break; + case 24: //M24 - Start SD print + gcode_M24(); break; + case 25: //M25 - Pause SD print + gcode_M25(); break; + case 26: //M26 - Set SD index + gcode_M26(); break; + case 27: //M27 - Get SD status + gcode_M27(); break; + case 28: //M28 - Start SD write + gcode_M28(); break; + case 29: //M29 - Stop SD write + gcode_M29(); break; + case 30: //M30 Delete File + gcode_M30(); break; + case 32: //M32 - Select file and start SD print + gcode_M32(); break; + + #if ENABLED(LONG_FILENAME_HOST_SUPPORT) + case 33: //M33 - Get the long full path to a file or folder + gcode_M33(); break; + #endif // LONG_FILENAME_HOST_SUPPORT + + case 928: //M928 - Start SD write + gcode_M928(); break; + #endif //SDSUPPORT + + case 31: //M31 take time since the start of the SD print or an M109 command + gcode_M31(); + break; + + case 42: //M42 -Change pin status via gcode + gcode_M42(); + break; + + #if ENABLED(Z_MIN_PROBE_REPEATABILITY_TEST) + case 48: // M48 Z probe repeatability + gcode_M48(); + break; + #endif // Z_MIN_PROBE_REPEATABILITY_TEST + + case 75: // Start print timer + gcode_M75(); + break; + + case 76: // Pause print timer + gcode_M76(); + break; + + case 77: // Stop print timer + gcode_M77(); + break; + + #if ENABLED(PRINTCOUNTER) + case 78: // Show print statistics + gcode_M78(); + break; + #endif + + #if ENABLED(M100_FREE_MEMORY_WATCHER) + case 100: + gcode_M100(); + break; + #endif + + case 104: // M104 + gcode_M104(); + break; + + case 110: // M110: Set Current Line Number + gcode_M110(); + break; + + case 111: // M111: Set debug level + gcode_M111(); + break; + + #if DISABLED(EMERGENCY_PARSER) + + case 108: // M108: Cancel Waiting + gcode_M108(); + break; + + case 112: // M112: Emergency Stop + gcode_M112(); + break; + + case 410: // M410 quickstop - Abort all the planned moves. + gcode_M410(); + break; + + #endif + + #if ENABLED(HOST_KEEPALIVE_FEATURE) + case 113: // M113: Set Host Keepalive interval + gcode_M113(); + break; + #endif + + case 140: // M140: Set bed temp + gcode_M140(); + break; + + case 105: // M105: Read current temperature + gcode_M105(); + KEEPALIVE_STATE(NOT_BUSY); + return; // "ok" already printed + + case 109: // M109: Wait for temperature + gcode_M109(); + break; + + #if HAS_TEMP_BED + case 190: // M190: Wait for bed heater to reach target + gcode_M190(); + break; + #endif // HAS_TEMP_BED + + #if FAN_COUNT > 0 + case 106: // M106: Fan On + gcode_M106(); + break; + case 107: // M107: Fan Off + gcode_M107(); + break; + #endif // FAN_COUNT > 0 + + #if ENABLED(BARICUDA) + // PWM for HEATER_1_PIN + #if HAS_HEATER_1 + case 126: // M126: valve open + gcode_M126(); + break; + case 127: // M127: valve closed + gcode_M127(); + break; + #endif // HAS_HEATER_1 + + // PWM for HEATER_2_PIN + #if HAS_HEATER_2 + case 128: // M128: valve open + gcode_M128(); + break; + case 129: // M129: valve closed + gcode_M129(); + break; + #endif // HAS_HEATER_2 + #endif // BARICUDA + + #if HAS_POWER_SWITCH + + case 80: // M80: Turn on Power Supply + gcode_M80(); + break; + + #endif // HAS_POWER_SWITCH + + case 81: // M81: Turn off Power, including Power Supply, if possible + gcode_M81(); + break; + + case 82: + gcode_M82(); + break; + case 83: + gcode_M83(); + break; + case 18: // (for compatibility) + case 84: // M84 + gcode_M18_M84(); + break; + case 85: // M85 + gcode_M85(); + break; + case 92: // M92: Set the steps-per-unit for one or more axes + gcode_M92(); + break; + case 115: // M115: Report capabilities + gcode_M115(); + break; + case 117: // M117: Set LCD message text, if possible + gcode_M117(); + break; + case 114: // M114: Report current position + gcode_M114(); + break; + case 120: // M120: Enable endstops + gcode_M120(); + break; + case 121: // M121: Disable endstops + gcode_M121(); + break; + case 119: // M119: Report endstop states + gcode_M119(); + break; + + #if ENABLED(ULTIPANEL) + + case 145: // M145: Set material heatup parameters + gcode_M145(); + break; + + #endif + + #if ENABLED(TEMPERATURE_UNITS_SUPPORT) + case 149: + gcode_M149(); + break; + #endif + + #if ENABLED(BLINKM) + + case 150: // M150 + gcode_M150(); + break; + + #endif //BLINKM + + #if ENABLED(EXPERIMENTAL_I2CBUS) + + case 155: + gcode_M155(); + break; + + case 156: + gcode_M156(); + break; + + #endif //EXPERIMENTAL_I2CBUS + + #if ENABLED(MIXING_EXTRUDER) + case 163: // M163 S P set weight for a mixing extruder + gcode_M163(); + break; + #if MIXING_VIRTUAL_TOOLS > 1 + case 164: // M164 S save current mix as a virtual extruder + gcode_M164(); + break; + #endif + #if ENABLED(DIRECT_MIXING_IN_G1) + case 165: // M165 [ABCDHI] set multiple mix weights + gcode_M165(); + break; + #endif + #endif + + case 200: // M200 D Set filament diameter and set E axis units to cubic. (Use S0 to revert to linear units.) + gcode_M200(); + break; + case 201: // M201 + gcode_M201(); + break; + #if 0 // Not used for Sprinter/grbl gen6 + case 202: // M202 + gcode_M202(); + break; + #endif + case 203: // M203 max feedrate units/sec + gcode_M203(); + break; + case 204: // M204 acclereration S normal moves T filmanent only moves + gcode_M204(); + break; + case 205: //M205 advanced settings: minimum travel speed S=while printing T=travel only, B=minimum segment time X= maximum xy jerk, Z=maximum Z jerk + gcode_M205(); + break; + case 206: // M206 additional homing offset + gcode_M206(); + break; + + #if ENABLED(DELTA) + case 665: // M665 set delta configurations L R S + gcode_M665(); + break; + #endif + + #if ENABLED(DELTA) || ENABLED(Z_DUAL_ENDSTOPS) + case 666: // M666 set delta / dual endstop adjustment + gcode_M666(); + break; + #endif + + #if ENABLED(FWRETRACT) + case 207: // M207 - Set Retract Length: S, Feedrate: F, and Z lift: Z + gcode_M207(); + break; + case 208: // M208 - Set Recover (unretract) Additional (!) Length: S and Feedrate: F + gcode_M208(); + break; + case 209: // M209 - Turn Automatic Retract Detection on/off: S (For slicers that don't support G10/11). Every normal extrude-only move will be classified as retract depending on the direction. + gcode_M209(); + break; + #endif // FWRETRACT + + #if HOTENDS > 1 + case 218: // M218 - Set a tool offset: T X Y + gcode_M218(); + break; + #endif + + case 220: // M220 - Set Feedrate Percentage: S ("FR" on your LCD) + gcode_M220(); + break; + + case 221: // M221 - Set Flow Percentage: S + gcode_M221(); + break; + + case 226: // M226 P S- Wait until the specified pin reaches the state required + gcode_M226(); + break; + + #if HAS_SERVOS + case 280: // M280 - set servo position absolute. P: servo index, S: angle or microseconds + gcode_M280(); + break; + #endif // HAS_SERVOS + + #if HAS_BUZZER + case 300: // M300 - Play beep tone + gcode_M300(); + break; + #endif // HAS_BUZZER + + #if ENABLED(PIDTEMP) + case 301: // M301 + gcode_M301(); + break; + #endif // PIDTEMP + + #if ENABLED(PIDTEMPBED) + case 304: // M304 + gcode_M304(); + break; + #endif // PIDTEMPBED + + #if defined(CHDK) || HAS_PHOTOGRAPH + case 240: // M240 Triggers a camera by emulating a Canon RC-1 : http://www.doc-diy.net/photo/rc-1_hacked/ + gcode_M240(); + break; + #endif // CHDK || PHOTOGRAPH_PIN + + #if HAS_LCD_CONTRAST + case 250: // M250 Set LCD contrast value: C (value 0..63) + gcode_M250(); + break; + #endif // HAS_LCD_CONTRAST + + #if ENABLED(PREVENT_DANGEROUS_EXTRUDE) + case 302: // allow cold extrudes, or set the minimum extrude temperature + gcode_M302(); + break; + #endif // PREVENT_DANGEROUS_EXTRUDE + + case 303: // M303 PID autotune + gcode_M303(); + break; + + #if ENABLED(SCARA) + case 360: // M360 SCARA Theta pos1 + if (gcode_M360()) return; + break; + case 361: // M361 SCARA Theta pos2 + if (gcode_M361()) return; + break; + case 362: // M362 SCARA Psi pos1 + if (gcode_M362()) return; + break; + case 363: // M363 SCARA Psi pos2 + if (gcode_M363()) return; + break; + case 364: // M364 SCARA Psi pos3 (90 deg to Theta) + if (gcode_M364()) return; + break; + case 365: // M365 Set SCARA scaling for X Y Z + gcode_M365(); + break; + #endif // SCARA + + case 400: // M400 finish all moves + gcode_M400(); + break; + + #if HAS_BED_PROBE + case 401: + gcode_M401(); + break; + case 402: + gcode_M402(); + break; + #endif // HAS_BED_PROBE + + #if ENABLED(FILAMENT_WIDTH_SENSOR) + case 404: //M404 Enter the nominal filament width (3mm, 1.75mm ) N<3.0> or display nominal filament width + gcode_M404(); + break; + case 405: //M405 Turn on filament sensor for control + gcode_M405(); + break; + case 406: //M406 Turn off filament sensor for control + gcode_M406(); + break; + case 407: //M407 Display measured filament diameter + gcode_M407(); + break; + #endif // ENABLED(FILAMENT_WIDTH_SENSOR) + + #if ENABLED(MESH_BED_LEVELING) + case 420: // M420 Enable/Disable Mesh Bed Leveling + gcode_M420(); + break; + case 421: // M421 Set a Mesh Bed Leveling Z coordinate + gcode_M421(); + break; + #endif + + case 428: // M428 Apply current_position to home_offset + gcode_M428(); + break; + + case 500: // M500 Store settings in EEPROM + gcode_M500(); + break; + case 501: // M501 Read settings from EEPROM + gcode_M501(); + break; + case 502: // M502 Revert to default settings + gcode_M502(); + break; + case 503: // M503 print settings currently in memory + gcode_M503(); + break; + + #if ENABLED(ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED) + case 540: + gcode_M540(); + break; + #endif + + #if HAS_BED_PROBE + case 851: + gcode_M851(); + break; + #endif // HAS_BED_PROBE + + #if ENABLED(FILAMENT_CHANGE_FEATURE) + case 600: //Pause for filament change X[pos] Y[pos] Z[relative lift] E[initial retract] L[later retract distance for removal] + gcode_M600(); + break; + #endif // FILAMENT_CHANGE_FEATURE + + #if ENABLED(DUAL_X_CARRIAGE) + case 605: + gcode_M605(); + break; + #endif // DUAL_X_CARRIAGE + + #if ENABLED(LIN_ADVANCE) + case 905: // M905 Set advance factor. + gcode_M905(); + break; + #endif + + case 907: // M907 Set digital trimpot motor current using axis codes. + gcode_M907(); + break; + + #if HAS_DIGIPOTSS || ENABLED(DAC_STEPPER_CURRENT) + + case 908: // M908 Control digital trimpot directly. + gcode_M908(); + break; + + #if ENABLED(DAC_STEPPER_CURRENT) // As with Printrbot RevF + + case 909: // M909 Print digipot/DAC current value + gcode_M909(); + break; + + case 910: // M910 Commit digipot/DAC value to external EEPROM + gcode_M910(); + break; + + #endif + + #endif // HAS_DIGIPOTSS || DAC_STEPPER_CURRENT + + #if HAS_MICROSTEPS + + case 350: // M350 Set microstepping mode. Warning: Steps per unit remains unchanged. S code sets stepping mode for all drivers. + gcode_M350(); + break; + + case 351: // M351 Toggle MS1 MS2 pins directly, S# determines MS1 or MS2, X# sets the pin high/low. + gcode_M351(); + break; + + #endif // HAS_MICROSTEPS + + case 999: // M999: Restart after being Stopped + gcode_M999(); + break; + } + break; + + case 'T': + gcode_T(codenum); + break; + + default: code_is_good = false; + } + + KEEPALIVE_STATE(NOT_BUSY); + +ExitUnknownCommand: + + // Still unknown command? Throw an error + if (!code_is_good) unknown_command_error(); + + ok_to_send(); +} + +void FlushSerialRequestResend() { + //char command_queue[cmd_queue_index_r][100]="Resend:"; + MYSERIAL.flush(); + SERIAL_PROTOCOLPGM(MSG_RESEND); + SERIAL_PROTOCOLLN(gcode_LastN + 1); + ok_to_send(); +} + +void ok_to_send() { + refresh_cmd_timeout(); + if (!send_ok[cmd_queue_index_r]) return; + SERIAL_PROTOCOLPGM(MSG_OK); + #if ENABLED(ADVANCED_OK) + char* p = command_queue[cmd_queue_index_r]; + if (*p == 'N') { + SERIAL_PROTOCOL(' '); + SERIAL_ECHO(*p++); + while (NUMERIC_SIGNED(*p)) + SERIAL_ECHO(*p++); + } + SERIAL_PROTOCOLPGM(" P"); SERIAL_PROTOCOL(int(BLOCK_BUFFER_SIZE - planner.movesplanned() - 1)); + SERIAL_PROTOCOLPGM(" B"); SERIAL_PROTOCOL(BUFSIZE - commands_in_queue); + #endif + SERIAL_EOL; +} + +void clamp_to_software_endstops(float target[3]) { + if (min_software_endstops) { + NOLESS(target[X_AXIS], sw_endstop_min[X_AXIS]); + NOLESS(target[Y_AXIS], sw_endstop_min[Y_AXIS]); + NOLESS(target[Z_AXIS], sw_endstop_min[Z_AXIS]); + } + if (max_software_endstops) { + NOMORE(target[X_AXIS], sw_endstop_max[X_AXIS]); + NOMORE(target[Y_AXIS], sw_endstop_max[Y_AXIS]); + NOMORE(target[Z_AXIS], sw_endstop_max[Z_AXIS]); + } +} + +#if ENABLED(DELTA) + + void recalc_delta_settings(float radius, float diagonal_rod) { + delta_tower1_x = -SIN_60 * (radius + DELTA_RADIUS_TRIM_TOWER_1); // front left tower + delta_tower1_y = -COS_60 * (radius + DELTA_RADIUS_TRIM_TOWER_1); + delta_tower2_x = SIN_60 * (radius + DELTA_RADIUS_TRIM_TOWER_2); // front right tower + delta_tower2_y = -COS_60 * (radius + DELTA_RADIUS_TRIM_TOWER_2); + delta_tower3_x = 0.0; // back middle tower + delta_tower3_y = (radius + DELTA_RADIUS_TRIM_TOWER_3); + delta_diagonal_rod_2_tower_1 = sq(diagonal_rod + delta_diagonal_rod_trim_tower_1); + delta_diagonal_rod_2_tower_2 = sq(diagonal_rod + delta_diagonal_rod_trim_tower_2); + delta_diagonal_rod_2_tower_3 = sq(diagonal_rod + delta_diagonal_rod_trim_tower_3); + } + + void inverse_kinematics(const float in_cartesian[3]) { + + const float cartesian[3] = { + RAW_X_POSITION(in_cartesian[X_AXIS]), + RAW_Y_POSITION(in_cartesian[Y_AXIS]), + RAW_Z_POSITION(in_cartesian[Z_AXIS]) + }; + + delta[TOWER_1] = sqrt(delta_diagonal_rod_2_tower_1 + - sq(delta_tower1_x - cartesian[X_AXIS]) + - sq(delta_tower1_y - cartesian[Y_AXIS]) + ) + cartesian[Z_AXIS]; + delta[TOWER_2] = sqrt(delta_diagonal_rod_2_tower_2 + - sq(delta_tower2_x - cartesian[X_AXIS]) + - sq(delta_tower2_y - cartesian[Y_AXIS]) + ) + cartesian[Z_AXIS]; + delta[TOWER_3] = sqrt(delta_diagonal_rod_2_tower_3 + - sq(delta_tower3_x - cartesian[X_AXIS]) + - sq(delta_tower3_y - cartesian[Y_AXIS]) + ) + cartesian[Z_AXIS]; + /** + SERIAL_ECHOPGM("cartesian x="); SERIAL_ECHO(cartesian[X_AXIS]); + SERIAL_ECHOPGM(" y="); SERIAL_ECHO(cartesian[Y_AXIS]); + SERIAL_ECHOPGM(" z="); SERIAL_ECHOLN(cartesian[Z_AXIS]); + + SERIAL_ECHOPGM("delta a="); SERIAL_ECHO(delta[TOWER_1]); + SERIAL_ECHOPGM(" b="); SERIAL_ECHO(delta[TOWER_2]); + SERIAL_ECHOPGM(" c="); SERIAL_ECHOLN(delta[TOWER_3]); + */ + } + + float delta_safe_distance_from_top() { + float cartesian[3] = { + LOGICAL_X_POSITION(0), + LOGICAL_Y_POSITION(0), + LOGICAL_Z_POSITION(0) + }; + inverse_kinematics(cartesian); + float distance = delta[TOWER_3]; + cartesian[Y_AXIS] = LOGICAL_Y_POSITION(DELTA_PRINTABLE_RADIUS); + inverse_kinematics(cartesian); + return abs(distance - delta[TOWER_3]); + } + + void forward_kinematics_DELTA(float z1, float z2, float z3) { + //As discussed in Wikipedia "Trilateration" + //we are establishing a new coordinate + //system in the plane of the three carriage points. + //This system will have the origin at tower1 and + //tower2 is on the x axis. tower3 is in the X-Y + //plane with a Z component of zero. We will define unit + //vectors in this coordinate system in our original + //coordinate system. Then when we calculate the + //Xnew, Ynew and Znew values, we can translate back into + //the original system by moving along those unit vectors + //by the corresponding values. + // https://en.wikipedia.org/wiki/Trilateration + + // Variable names matched to Marlin, c-version + // and avoiding a vector library + // by Andreas Hardtung 2016-06-7 + // based on a Java function from + // "Delta Robot Kinematics by Steve Graves" V3 + + // Result is in cartesian_position[]. + + //Create a vector in old coordinates along x axis of new coordinate + float p12[3] = { delta_tower2_x - delta_tower1_x, delta_tower2_y - delta_tower1_y, z2 - z1 }; + + //Get the Magnitude of vector. + float d = sqrt( p12[0]*p12[0] + p12[1]*p12[1] + p12[2]*p12[2] ); + + //Create unit vector by dividing by magnitude. + float ex[3] = { p12[0]/d, p12[1]/d, p12[2]/d }; + + //Now find vector from the origin of the new system to the third point. + float p13[3] = { delta_tower3_x - delta_tower1_x, delta_tower3_y - delta_tower1_y, z3 - z1 }; + + //Now use dot product to find the component of this vector on the X axis. + float i = ex[0]*p13[0] + ex[1]*p13[1] + ex[2]*p13[2]; + + //Now create a vector along the x axis that represents the x component of p13. + float iex[3] = { ex[0]*i, ex[1]*i, ex[2]*i }; + + //Now subtract the X component away from the original vector leaving only the Y component. We use the + //variable that will be the unit vector after we scale it. + float ey[3] = { p13[0] - iex[0], p13[1] - iex[1], p13[2] - iex[2]}; + + //The magnitude of Y component + float j = sqrt(sq(ey[0]) + sq(ey[1]) + sq(ey[2])); + + //Now make vector a unit vector + ey[0] /= j; ey[1] /= j; ey[2] /= j; + + //The cross product of the unit x and y is the unit z + //float[] ez = vectorCrossProd(ex, ey); + float ez[3] = { ex[1]*ey[2] - ex[2]*ey[1], ex[2]*ey[0] - ex[0]*ey[2], ex[0]*ey[1] - ex[1]*ey[0] }; + + //Now we have the d, i and j values defined in Wikipedia. + //We can plug them into the equations defined in + //Wikipedia for Xnew, Ynew and Znew + float Xnew = (delta_diagonal_rod_2_tower_1 - delta_diagonal_rod_2_tower_2 + d*d)/(d*2); + float Ynew = ((delta_diagonal_rod_2_tower_1 - delta_diagonal_rod_2_tower_3 + i*i + j*j)/2 - i*Xnew) /j; + float Znew = sqrt(delta_diagonal_rod_2_tower_1 - Xnew*Xnew - Ynew*Ynew); + + //Now we can start from the origin in the old coords and + //add vectors in the old coords that represent the + //Xnew, Ynew and Znew to find the point in the old system + cartesian_position[X_AXIS] = delta_tower1_x + ex[0]*Xnew + ey[0]*Ynew - ez[0]*Znew; + cartesian_position[Y_AXIS] = delta_tower1_y + ex[1]*Xnew + ey[1]*Ynew - ez[1]*Znew; + cartesian_position[Z_AXIS] = z1 + ex[2]*Xnew + ey[2]*Ynew - ez[2]*Znew; + }; + + void forward_kinematics_DELTA(float point[3]) { + forward_kinematics_DELTA(point[X_AXIS], point[Y_AXIS], point[Z_AXIS]); + } + + void set_cartesian_from_steppers() { + forward_kinematics_DELTA(stepper.get_axis_position_mm(X_AXIS), + stepper.get_axis_position_mm(Y_AXIS), + stepper.get_axis_position_mm(Z_AXIS)); + } + + #if ENABLED(AUTO_BED_LEVELING_FEATURE) + + // Adjust print surface height by linear interpolation over the bed_level array. + void adjust_delta(float cartesian[3]) { + if (delta_grid_spacing[0] == 0 || delta_grid_spacing[1] == 0) return; // G29 not done! + + int half = (AUTO_BED_LEVELING_GRID_POINTS - 1) / 2; + float h1 = 0.001 - half, h2 = half - 0.001, + grid_x = max(h1, min(h2, RAW_X_POSITION(cartesian[X_AXIS]) / delta_grid_spacing[0])), + grid_y = max(h1, min(h2, RAW_Y_POSITION(cartesian[Y_AXIS]) / delta_grid_spacing[1])); + int floor_x = floor(grid_x), floor_y = floor(grid_y); + float ratio_x = grid_x - floor_x, ratio_y = grid_y - floor_y, + z1 = bed_level[floor_x + half][floor_y + half], + z2 = bed_level[floor_x + half][floor_y + half + 1], + z3 = bed_level[floor_x + half + 1][floor_y + half], + z4 = bed_level[floor_x + half + 1][floor_y + half + 1], + left = (1 - ratio_y) * z1 + ratio_y * z2, + right = (1 - ratio_y) * z3 + ratio_y * z4, + offset = (1 - ratio_x) * left + ratio_x * right; + + delta[X_AXIS] += offset; + delta[Y_AXIS] += offset; + delta[Z_AXIS] += offset; + + /** + SERIAL_ECHOPGM("grid_x="); SERIAL_ECHO(grid_x); + SERIAL_ECHOPGM(" grid_y="); SERIAL_ECHO(grid_y); + SERIAL_ECHOPGM(" floor_x="); SERIAL_ECHO(floor_x); + SERIAL_ECHOPGM(" floor_y="); SERIAL_ECHO(floor_y); + SERIAL_ECHOPGM(" ratio_x="); SERIAL_ECHO(ratio_x); + SERIAL_ECHOPGM(" ratio_y="); SERIAL_ECHO(ratio_y); + SERIAL_ECHOPGM(" z1="); SERIAL_ECHO(z1); + SERIAL_ECHOPGM(" z2="); SERIAL_ECHO(z2); + SERIAL_ECHOPGM(" z3="); SERIAL_ECHO(z3); + SERIAL_ECHOPGM(" z4="); SERIAL_ECHO(z4); + SERIAL_ECHOPGM(" left="); SERIAL_ECHO(left); + SERIAL_ECHOPGM(" right="); SERIAL_ECHO(right); + SERIAL_ECHOPGM(" offset="); SERIAL_ECHOLN(offset); + */ + } + #endif // AUTO_BED_LEVELING_FEATURE + +#endif // DELTA + +void set_current_from_steppers_for_axis(AxisEnum axis) { + #if ENABLED(DELTA) + set_cartesian_from_steppers(); + current_position[axis] = LOGICAL_POSITION(cartesian_position[axis], axis); + #elif ENABLED(AUTO_BED_LEVELING_FEATURE) + vector_3 pos = planner.adjusted_position(); + current_position[axis] = axis == X_AXIS ? pos.x : axis == Y_AXIS ? pos.y : pos.z; + #else + current_position[axis] = stepper.get_axis_position_mm(axis); // CORE handled transparently + #endif +} + +#if ENABLED(MESH_BED_LEVELING) + +// This function is used to split lines on mesh borders so each segment is only part of one mesh area +void mesh_line_to_destination(float fr_mm_m, uint8_t x_splits = 0xff, uint8_t y_splits = 0xff) { + int cx1 = mbl.cell_index_x(RAW_CURRENT_POSITION(X_AXIS)), + cy1 = mbl.cell_index_y(RAW_CURRENT_POSITION(Y_AXIS)), + cx2 = mbl.cell_index_x(RAW_X_POSITION(destination[X_AXIS])), + cy2 = mbl.cell_index_y(RAW_Y_POSITION(destination[Y_AXIS])); + NOMORE(cx1, MESH_NUM_X_POINTS - 2); + NOMORE(cy1, MESH_NUM_Y_POINTS - 2); + NOMORE(cx2, MESH_NUM_X_POINTS - 2); + NOMORE(cy2, MESH_NUM_Y_POINTS - 2); + + if (cx1 == cx2 && cy1 == cy2) { + // Start and end on same mesh square + line_to_destination(fr_mm_m); + set_current_to_destination(); + return; + } + + #define MBL_SEGMENT_END(A) (current_position[A ##_AXIS] + (destination[A ##_AXIS] - current_position[A ##_AXIS]) * normalized_dist) + + float normalized_dist, end[NUM_AXIS]; + + // Split at the left/front border of the right/top square + int8_t gcx = max(cx1, cx2), gcy = max(cy1, cy2); + if (cx2 != cx1 && TEST(x_splits, gcx)) { + memcpy(end, destination, sizeof(end)); + destination[X_AXIS] = LOGICAL_X_POSITION(mbl.get_probe_x(gcx)); + normalized_dist = (destination[X_AXIS] - current_position[X_AXIS]) / (end[X_AXIS] - current_position[X_AXIS]); + destination[Y_AXIS] = MBL_SEGMENT_END(Y); + CBI(x_splits, gcx); + } + else if (cy2 != cy1 && TEST(y_splits, gcy)) { + memcpy(end, destination, sizeof(end)); + destination[Y_AXIS] = LOGICAL_Y_POSITION(mbl.get_probe_y(gcy)); + normalized_dist = (destination[Y_AXIS] - current_position[Y_AXIS]) / (end[Y_AXIS] - current_position[Y_AXIS]); + destination[X_AXIS] = MBL_SEGMENT_END(X); + CBI(y_splits, gcy); + } + else { + // Already split on a border + line_to_destination(fr_mm_m); + set_current_to_destination(); + return; + } + + destination[Z_AXIS] = MBL_SEGMENT_END(Z); + destination[E_AXIS] = MBL_SEGMENT_END(E); + + // Do the split and look for more borders + mesh_line_to_destination(fr_mm_m, x_splits, y_splits); + + // Restore destination from stack + memcpy(destination, end, sizeof(end)); + mesh_line_to_destination(fr_mm_m, x_splits, y_splits); +} +#endif // MESH_BED_LEVELING + +#if ENABLED(DELTA) || ENABLED(SCARA) + + inline bool prepare_kinematic_move_to(float target[NUM_AXIS]) { + float difference[NUM_AXIS]; + LOOP_XYZE(i) difference[i] = target[i] - current_position[i]; + + float cartesian_mm = sqrt(sq(difference[X_AXIS]) + sq(difference[Y_AXIS]) + sq(difference[Z_AXIS])); + if (cartesian_mm < 0.000001) cartesian_mm = abs(difference[E_AXIS]); + if (cartesian_mm < 0.000001) return false; + float _feedrate_mm_s = MMM_TO_MMS_SCALED(feedrate_mm_m); + float seconds = cartesian_mm / _feedrate_mm_s; + int steps = max(1, int(delta_segments_per_second * seconds)); + float inv_steps = 1.0/steps; + + // SERIAL_ECHOPGM("mm="); SERIAL_ECHO(cartesian_mm); + // SERIAL_ECHOPGM(" seconds="); SERIAL_ECHO(seconds); + // SERIAL_ECHOPGM(" steps="); SERIAL_ECHOLN(steps); + + for (int s = 1; s <= steps; s++) { + + float fraction = float(s) * inv_steps; + + LOOP_XYZE(i) + target[i] = current_position[i] + difference[i] * fraction; + + inverse_kinematics(target); + + #if ENABLED(DELTA) && ENABLED(AUTO_BED_LEVELING_FEATURE) + if (!bed_leveling_in_progress) adjust_delta(target); + #endif + + //DEBUG_POS("prepare_kinematic_move_to", target); + //DEBUG_POS("prepare_kinematic_move_to", delta); + + planner.buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], target[E_AXIS], _feedrate_mm_s, active_extruder); + } + return true; + } + +#endif // DELTA || SCARA + +#if ENABLED(DUAL_X_CARRIAGE) + + inline bool prepare_move_to_destination_dualx() { + if (active_extruder_parked) { + if (dual_x_carriage_mode == DXC_DUPLICATION_MODE && active_extruder == 0) { + // move duplicate extruder into correct duplication position. + planner.set_position_mm( + LOGICAL_X_POSITION(inactive_extruder_x_pos), + current_position[Y_AXIS], + current_position[Z_AXIS], + current_position[E_AXIS] + ); + planner.buffer_line(current_position[X_AXIS] + duplicate_extruder_x_offset, + current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], planner.max_feedrate_mm_s[X_AXIS], 1); + SYNC_PLAN_POSITION_KINEMATIC(); + stepper.synchronize(); + extruder_duplication_enabled = true; + active_extruder_parked = false; + } + else if (dual_x_carriage_mode == DXC_AUTO_PARK_MODE) { // handle unparking of head + if (current_position[E_AXIS] == destination[E_AXIS]) { + // This is a travel move (with no extrusion) + // Skip it, but keep track of the current position + // (so it can be used as the start of the next non-travel move) + if (delayed_move_time != 0xFFFFFFFFUL) { + set_current_to_destination(); + NOLESS(raised_parked_position[Z_AXIS], destination[Z_AXIS]); + delayed_move_time = millis(); + return false; + } + } + delayed_move_time = 0; + // unpark extruder: 1) raise, 2) move into starting XY position, 3) lower + planner.buffer_line(raised_parked_position[X_AXIS], raised_parked_position[Y_AXIS], raised_parked_position[Z_AXIS], current_position[E_AXIS], planner.max_feedrate_mm_s[Z_AXIS], active_extruder); + planner.buffer_line(current_position[X_AXIS], current_position[Y_AXIS], raised_parked_position[Z_AXIS], current_position[E_AXIS], PLANNER_XY_FEEDRATE(), active_extruder); + planner.buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], planner.max_feedrate_mm_s[Z_AXIS], active_extruder); + active_extruder_parked = false; + } + } + return true; + } + +#endif // DUAL_X_CARRIAGE + +#if DISABLED(DELTA) && DISABLED(SCARA) + + inline bool prepare_move_to_destination_cartesian() { + // Do not use feedrate_percentage for E or Z only moves + if (current_position[X_AXIS] == destination[X_AXIS] && current_position[Y_AXIS] == destination[Y_AXIS]) { + line_to_destination(); + } + else { + #if ENABLED(MESH_BED_LEVELING) + if (mbl.active()) { + mesh_line_to_destination(MMM_SCALED(feedrate_mm_m)); + return false; + } + else + #endif + line_to_destination(MMM_SCALED(feedrate_mm_m)); + } + return true; + } + +#endif // !DELTA && !SCARA + +#if ENABLED(PREVENT_DANGEROUS_EXTRUDE) + + inline void prevent_dangerous_extrude(float& curr_e, float& dest_e) { + if (DEBUGGING(DRYRUN)) return; + float de = dest_e - curr_e; + if (de) { + if (thermalManager.tooColdToExtrude(active_extruder)) { + curr_e = dest_e; // Behave as if the move really took place, but ignore E part + SERIAL_ECHO_START; + SERIAL_ECHOLNPGM(MSG_ERR_COLD_EXTRUDE_STOP); + } + #if ENABLED(PREVENT_LENGTHY_EXTRUDE) + if (labs(de) > EXTRUDE_MAXLENGTH) { + curr_e = dest_e; // Behave as if the move really took place, but ignore E part + SERIAL_ECHO_START; + SERIAL_ECHOLNPGM(MSG_ERR_LONG_EXTRUDE_STOP); + } + #endif + } + } + +#endif // PREVENT_DANGEROUS_EXTRUDE + +/** + * Prepare a single move and get ready for the next one + * + * (This may call planner.buffer_line several times to put + * smaller moves into the planner for DELTA or SCARA.) + */ +void prepare_move_to_destination() { + clamp_to_software_endstops(destination); + refresh_cmd_timeout(); + + #if ENABLED(PREVENT_DANGEROUS_EXTRUDE) + prevent_dangerous_extrude(current_position[E_AXIS], destination[E_AXIS]); + #endif + + #if ENABLED(DELTA) || ENABLED(SCARA) + if (!prepare_kinematic_move_to(destination)) return; + #else + #if ENABLED(DUAL_X_CARRIAGE) + if (!prepare_move_to_destination_dualx()) return; + #endif + if (!prepare_move_to_destination_cartesian()) return; + #endif + + set_current_to_destination(); +} + +#if ENABLED(ARC_SUPPORT) + /** + * Plan an arc in 2 dimensions + * + * The arc is approximated by generating many small linear segments. + * The length of each segment is configured in MM_PER_ARC_SEGMENT (Default 1mm) + * Arcs should only be made relatively large (over 5mm), as larger arcs with + * larger segments will tend to be more efficient. Your slicer should have + * options for G2/G3 arc generation. In future these options may be GCode tunable. + */ + void plan_arc( + float target[NUM_AXIS], // Destination position + float* offset, // Center of rotation relative to current_position + uint8_t clockwise // Clockwise? + ) { + + float radius = HYPOT(offset[X_AXIS], offset[Y_AXIS]), + center_X = current_position[X_AXIS] + offset[X_AXIS], + center_Y = current_position[Y_AXIS] + offset[Y_AXIS], + linear_travel = target[Z_AXIS] - current_position[Z_AXIS], + extruder_travel = target[E_AXIS] - current_position[E_AXIS], + r_X = -offset[X_AXIS], // Radius vector from center to current location + r_Y = -offset[Y_AXIS], + rt_X = target[X_AXIS] - center_X, + rt_Y = target[Y_AXIS] - center_Y; + + // CCW angle of rotation between position and target from the circle center. Only one atan2() trig computation required. + float angular_travel = atan2(r_X * rt_Y - r_Y * rt_X, r_X * rt_X + r_Y * rt_Y); + if (angular_travel < 0) angular_travel += RADIANS(360); + if (clockwise) angular_travel -= RADIANS(360); + + // Make a circle if the angular rotation is 0 + if (angular_travel == 0 && current_position[X_AXIS] == target[X_AXIS] && current_position[Y_AXIS] == target[Y_AXIS]) + angular_travel += RADIANS(360); + + float mm_of_travel = HYPOT(angular_travel * radius, fabs(linear_travel)); + if (mm_of_travel < 0.001) return; + uint16_t segments = floor(mm_of_travel / (MM_PER_ARC_SEGMENT)); + if (segments == 0) segments = 1; + + float theta_per_segment = angular_travel / segments; + float linear_per_segment = linear_travel / segments; + float extruder_per_segment = extruder_travel / segments; + + /** + * Vector rotation by transformation matrix: r is the original vector, r_T is the rotated vector, + * and phi is the angle of rotation. Based on the solution approach by Jens Geisler. + * r_T = [cos(phi) -sin(phi); + * sin(phi) cos(phi] * r ; + * + * For arc generation, the center of the circle is the axis of rotation and the radius vector is + * defined from the circle center to the initial position. Each line segment is formed by successive + * vector rotations. This requires only two cos() and sin() computations to form the rotation + * matrix for the duration of the entire arc. Error may accumulate from numerical round-off, since + * all double numbers are single precision on the Arduino. (True double precision will not have + * round off issues for CNC applications.) Single precision error can accumulate to be greater than + * tool precision in some cases. Therefore, arc path correction is implemented. + * + * Small angle approximation may be used to reduce computation overhead further. This approximation + * holds for everything, but very small circles and large MM_PER_ARC_SEGMENT values. In other words, + * theta_per_segment would need to be greater than 0.1 rad and N_ARC_CORRECTION would need to be large + * to cause an appreciable drift error. N_ARC_CORRECTION~=25 is more than small enough to correct for + * numerical drift error. N_ARC_CORRECTION may be on the order a hundred(s) before error becomes an + * issue for CNC machines with the single precision Arduino calculations. + * + * This approximation also allows plan_arc to immediately insert a line segment into the planner + * without the initial overhead of computing cos() or sin(). By the time the arc needs to be applied + * a correction, the planner should have caught up to the lag caused by the initial plan_arc overhead. + * This is important when there are successive arc motions. + */ + // Vector rotation matrix values + float cos_T = 1 - 0.5 * sq(theta_per_segment); // Small angle approximation + float sin_T = theta_per_segment; + + float arc_target[NUM_AXIS]; + float sin_Ti, cos_Ti, r_new_Y; + uint16_t i; + int8_t count = 0; + + // Initialize the linear axis + arc_target[Z_AXIS] = current_position[Z_AXIS]; + + // Initialize the extruder axis + arc_target[E_AXIS] = current_position[E_AXIS]; + + float fr_mm_s = MMM_TO_MMS_SCALED(feedrate_mm_m); + + millis_t next_idle_ms = millis() + 200UL; + + for (i = 1; i < segments; i++) { // Iterate (segments-1) times + + thermalManager.manage_heater(); + millis_t now = millis(); + if (ELAPSED(now, next_idle_ms)) { + next_idle_ms = now + 200UL; + idle(); + } + + if (++count < N_ARC_CORRECTION) { + // Apply vector rotation matrix to previous r_X / 1 + r_new_Y = r_X * sin_T + r_Y * cos_T; + r_X = r_X * cos_T - r_Y * sin_T; + r_Y = r_new_Y; + } + else { + // Arc correction to radius vector. Computed only every N_ARC_CORRECTION increments. + // Compute exact location by applying transformation matrix from initial radius vector(=-offset). + // To reduce stuttering, the sin and cos could be computed at different times. + // For now, compute both at the same time. + cos_Ti = cos(i * theta_per_segment); + sin_Ti = sin(i * theta_per_segment); + r_X = -offset[X_AXIS] * cos_Ti + offset[Y_AXIS] * sin_Ti; + r_Y = -offset[X_AXIS] * sin_Ti - offset[Y_AXIS] * cos_Ti; + count = 0; + } + + // Update arc_target location + arc_target[X_AXIS] = center_X + r_X; + arc_target[Y_AXIS] = center_Y + r_Y; + arc_target[Z_AXIS] += linear_per_segment; + arc_target[E_AXIS] += extruder_per_segment; + + clamp_to_software_endstops(arc_target); + + #if ENABLED(DELTA) || ENABLED(SCARA) + inverse_kinematics(arc_target); + #if ENABLED(DELTA) && ENABLED(AUTO_BED_LEVELING_FEATURE) + adjust_delta(arc_target); + #endif + planner.buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], arc_target[E_AXIS], fr_mm_s, active_extruder); + #else + planner.buffer_line(arc_target[X_AXIS], arc_target[Y_AXIS], arc_target[Z_AXIS], arc_target[E_AXIS], fr_mm_s, active_extruder); + #endif + } + + // Ensure last segment arrives at target location. + #if ENABLED(DELTA) || ENABLED(SCARA) + inverse_kinematics(target); + #if ENABLED(DELTA) && ENABLED(AUTO_BED_LEVELING_FEATURE) + adjust_delta(target); + #endif + planner.buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], target[E_AXIS], fr_mm_s, active_extruder); + #else + planner.buffer_line(target[X_AXIS], target[Y_AXIS], target[Z_AXIS], target[E_AXIS], fr_mm_s, active_extruder); + #endif + + // As far as the parser is concerned, the position is now == target. In reality the + // motion control system might still be processing the action and the real tool position + // in any intermediate location. + set_current_to_destination(); + } +#endif + +#if ENABLED(BEZIER_CURVE_SUPPORT) + + void plan_cubic_move(const float offset[4]) { + cubic_b_spline(current_position, destination, offset, MMM_TO_MMS_SCALED(feedrate_mm_m), active_extruder); + + // As far as the parser is concerned, the position is now == target. In reality the + // motion control system might still be processing the action and the real tool position + // in any intermediate location. + set_current_to_destination(); + } + +#endif // BEZIER_CURVE_SUPPORT + +#if HAS_CONTROLLERFAN + + void controllerFan() { + static millis_t lastMotorOn = 0; // Last time a motor was turned on + static millis_t nextMotorCheck = 0; // Last time the state was checked + millis_t ms = millis(); + if (ELAPSED(ms, nextMotorCheck)) { + nextMotorCheck = ms + 2500UL; // Not a time critical function, so only check every 2.5s + if (X_ENABLE_READ == X_ENABLE_ON || Y_ENABLE_READ == Y_ENABLE_ON || Z_ENABLE_READ == Z_ENABLE_ON || thermalManager.soft_pwm_bed > 0 + || E0_ENABLE_READ == E_ENABLE_ON // If any of the drivers are enabled... + #if E_STEPPERS > 1 + || E1_ENABLE_READ == E_ENABLE_ON + #if HAS_X2_ENABLE + || X2_ENABLE_READ == X_ENABLE_ON + #endif + #if E_STEPPERS > 2 + || E2_ENABLE_READ == E_ENABLE_ON + #if E_STEPPERS > 3 + || E3_ENABLE_READ == E_ENABLE_ON + #endif + #endif + #endif + ) { + lastMotorOn = ms; //... set time to NOW so the fan will turn on + } + + // Fan off if no steppers have been enabled for CONTROLLERFAN_SECS seconds + uint8_t speed = (!lastMotorOn || ELAPSED(ms, lastMotorOn + (CONTROLLERFAN_SECS) * 1000UL)) ? 0 : CONTROLLERFAN_SPEED; + + // allows digital or PWM fan output to be used (see M42 handling) + digitalWrite(CONTROLLERFAN_PIN, speed); + analogWrite(CONTROLLERFAN_PIN, speed); + } + } + +#endif // HAS_CONTROLLERFAN + +#if ENABLED(SCARA) + + void forward_kinematics_SCARA(float f_scara[3]) { + // Perform forward kinematics, and place results in delta[3] + // The maths and first version has been done by QHARLEY . Integrated into masterbranch 06/2014 and slightly restructured by Joachim Cerny in June 2014 + + float x_sin, x_cos, y_sin, y_cos; + + //SERIAL_ECHOPGM("f_delta x="); SERIAL_ECHO(f_scara[X_AXIS]); + //SERIAL_ECHOPGM(" y="); SERIAL_ECHO(f_scara[Y_AXIS]); + + x_sin = sin(f_scara[X_AXIS] / SCARA_RAD2DEG) * Linkage_1; + x_cos = cos(f_scara[X_AXIS] / SCARA_RAD2DEG) * Linkage_1; + y_sin = sin(f_scara[Y_AXIS] / SCARA_RAD2DEG) * Linkage_2; + y_cos = cos(f_scara[Y_AXIS] / SCARA_RAD2DEG) * Linkage_2; + + //SERIAL_ECHOPGM(" x_sin="); SERIAL_ECHO(x_sin); + //SERIAL_ECHOPGM(" x_cos="); SERIAL_ECHO(x_cos); + //SERIAL_ECHOPGM(" y_sin="); SERIAL_ECHO(y_sin); + //SERIAL_ECHOPGM(" y_cos="); SERIAL_ECHOLN(y_cos); + + delta[X_AXIS] = x_cos + y_cos + SCARA_offset_x; //theta + delta[Y_AXIS] = x_sin + y_sin + SCARA_offset_y; //theta+phi + + //SERIAL_ECHOPGM(" delta[X_AXIS]="); SERIAL_ECHO(delta[X_AXIS]); + //SERIAL_ECHOPGM(" delta[Y_AXIS]="); SERIAL_ECHOLN(delta[Y_AXIS]); + } + + void inverse_kinematics(const float cartesian[3]) { + // Inverse kinematics. + // Perform SCARA IK and place results in delta[3]. + // The maths and first version were done by QHARLEY. + // Integrated, tweaked by Joachim Cerny in June 2014. + + float SCARA_pos[2]; + static float SCARA_C2, SCARA_S2, SCARA_K1, SCARA_K2, SCARA_theta, SCARA_psi; + + SCARA_pos[X_AXIS] = RAW_X_POSITION(cartesian[X_AXIS]) * axis_scaling[X_AXIS] - SCARA_offset_x; //Translate SCARA to standard X Y + SCARA_pos[Y_AXIS] = RAW_Y_POSITION(cartesian[Y_AXIS]) * axis_scaling[Y_AXIS] - SCARA_offset_y; // With scaling factor. + + #if (Linkage_1 == Linkage_2) + SCARA_C2 = ((sq(SCARA_pos[X_AXIS]) + sq(SCARA_pos[Y_AXIS])) / (2 * (float)L1_2)) - 1; + #else + SCARA_C2 = (sq(SCARA_pos[X_AXIS]) + sq(SCARA_pos[Y_AXIS]) - (float)L1_2 - (float)L2_2) / 45000; + #endif + + SCARA_S2 = sqrt(1 - sq(SCARA_C2)); + + SCARA_K1 = Linkage_1 + Linkage_2 * SCARA_C2; + SCARA_K2 = Linkage_2 * SCARA_S2; + + SCARA_theta = (atan2(SCARA_pos[X_AXIS], SCARA_pos[Y_AXIS]) - atan2(SCARA_K1, SCARA_K2)) * -1; + SCARA_psi = atan2(SCARA_S2, SCARA_C2); + + delta[X_AXIS] = SCARA_theta * SCARA_RAD2DEG; // Multiply by 180/Pi - theta is support arm angle + delta[Y_AXIS] = (SCARA_theta + SCARA_psi) * SCARA_RAD2DEG; // - equal to sub arm angle (inverted motor) + delta[Z_AXIS] = RAW_Z_POSITION(cartesian[Z_AXIS]); + + /** + SERIAL_ECHOPGM("cartesian x="); SERIAL_ECHO(cartesian[X_AXIS]); + SERIAL_ECHOPGM(" y="); SERIAL_ECHO(cartesian[Y_AXIS]); + SERIAL_ECHOPGM(" z="); SERIAL_ECHOLN(cartesian[Z_AXIS]); + + SERIAL_ECHOPGM("scara x="); SERIAL_ECHO(SCARA_pos[X_AXIS]); + SERIAL_ECHOPGM(" y="); SERIAL_ECHOLN(SCARA_pos[Y_AXIS]); + + SERIAL_ECHOPGM("delta x="); SERIAL_ECHO(delta[X_AXIS]); + SERIAL_ECHOPGM(" y="); SERIAL_ECHO(delta[Y_AXIS]); + SERIAL_ECHOPGM(" z="); SERIAL_ECHOLN(delta[Z_AXIS]); + + SERIAL_ECHOPGM("C2="); SERIAL_ECHO(SCARA_C2); + SERIAL_ECHOPGM(" S2="); SERIAL_ECHO(SCARA_S2); + SERIAL_ECHOPGM(" Theta="); SERIAL_ECHO(SCARA_theta); + SERIAL_ECHOPGM(" Psi="); SERIAL_ECHOLN(SCARA_psi); + SERIAL_EOL; + */ + } + +#endif // SCARA + +#if ENABLED(TEMP_STAT_LEDS) + + static bool red_led = false; + static millis_t next_status_led_update_ms = 0; + + void handle_status_leds(void) { + float max_temp = 0.0; + if (ELAPSED(millis(), next_status_led_update_ms)) { + next_status_led_update_ms += 500; // Update every 0.5s + HOTEND_LOOP() { + max_temp = max(max(max_temp, thermalManager.degHotend(e)), thermalManager.degTargetHotend(e)); + } + #if HAS_TEMP_BED + max_temp = max(max(max_temp, thermalManager.degTargetBed()), thermalManager.degBed()); + #endif + bool new_led = (max_temp > 55.0) ? true : (max_temp < 54.0) ? false : red_led; + if (new_led != red_led) { + red_led = new_led; + digitalWrite(STAT_LED_RED, new_led ? HIGH : LOW); + digitalWrite(STAT_LED_BLUE, new_led ? LOW : HIGH); + } + } + } + +#endif + +void enable_all_steppers() { + enable_x(); + enable_y(); + enable_z(); + enable_e0(); + enable_e1(); + enable_e2(); + enable_e3(); +} + +void disable_all_steppers() { + disable_x(); + disable_y(); + disable_z(); + disable_e0(); + disable_e1(); + disable_e2(); + disable_e3(); +} + +/** + * Standard idle routine keeps the machine alive + */ +void idle( + #if ENABLED(FILAMENT_CHANGE_FEATURE) + bool no_stepper_sleep/*=false*/ + #endif +) { + lcd_update(); + host_keepalive(); + manage_inactivity( + #if ENABLED(FILAMENT_CHANGE_FEATURE) + no_stepper_sleep + #endif + ); + + thermalManager.manage_heater(); + + #if ENABLED(PRINTCOUNTER) + print_job_timer.tick(); + #endif + + #if HAS_BUZZER && PIN_EXISTS(BEEPER) + buzzer.tick(); + #endif +} + +/** + * Manage several 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 + * - Check if pin CHDK needs to go LOW + * - Check for KILL button held down + * - Check for HOME button held down + * - Check if cooling fan needs to be switched on + * - Check if an idle but hot extruder needs filament extruded (EXTRUDER_RUNOUT_PREVENT) + */ +void manage_inactivity(bool ignore_stepper_queue/*=false*/) { + + #if ENABLED(FILAMENT_RUNOUT_SENSOR) + if ((IS_SD_PRINTING || print_job_timer.isRunning()) && !(READ(FIL_RUNOUT_PIN) ^ FIL_RUNOUT_INVERTING)) + handle_filament_runout(); + #endif + + if (commands_in_queue < BUFSIZE) get_available_commands(); + + millis_t ms = millis(); + + if (max_inactive_time && ELAPSED(ms, previous_cmd_ms + max_inactive_time)) kill(PSTR(MSG_KILLED)); + + if (stepper_inactive_time && ELAPSED(ms, previous_cmd_ms + stepper_inactive_time) + && !ignore_stepper_queue && !planner.blocks_queued()) { + #if ENABLED(DISABLE_INACTIVE_X) + disable_x(); + #endif + #if ENABLED(DISABLE_INACTIVE_Y) + disable_y(); + #endif + #if ENABLED(DISABLE_INACTIVE_Z) + disable_z(); + #endif + #if ENABLED(DISABLE_INACTIVE_E) + disable_e0(); + disable_e1(); + disable_e2(); + disable_e3(); + #endif + } + + #ifdef CHDK // Check if pin should be set to LOW after M240 set it to HIGH + if (chdkActive && PENDING(ms, chdkHigh + CHDK_DELAY)) { + chdkActive = false; + WRITE(CHDK, LOW); + } + #endif + + #if HAS_KILL + + // Check if the kill button was pressed and wait just in case it was an accidental + // key kill key press + // ------------------------------------------------------------------------------- + static int killCount = 0; // make the inactivity button a bit less responsive + const int KILL_DELAY = 750; + if (!READ(KILL_PIN)) + killCount++; + else if (killCount > 0) + killCount--; + + // Exceeded threshold and we can confirm that it was not accidental + // KILL the machine + // ---------------------------------------------------------------- + if (killCount >= KILL_DELAY) kill(PSTR(MSG_KILLED)); + #endif + + #if HAS_HOME + // Check to see if we have to home, use poor man's debouncer + // --------------------------------------------------------- + static int homeDebounceCount = 0; // poor man's debouncing count + const int HOME_DEBOUNCE_DELAY = 2500; + if (!READ(HOME_PIN)) { + if (!homeDebounceCount) { + enqueue_and_echo_commands_P(PSTR("G28")); + LCD_MESSAGEPGM(MSG_AUTO_HOME); + } + if (homeDebounceCount < HOME_DEBOUNCE_DELAY) + homeDebounceCount++; + else + homeDebounceCount = 0; + } + #endif + + #if HAS_CONTROLLERFAN + controllerFan(); // Check if fan should be turned on to cool stepper drivers down + #endif + + #if ENABLED(EXTRUDER_RUNOUT_PREVENT) + if (ELAPSED(ms, previous_cmd_ms + (EXTRUDER_RUNOUT_SECONDS) * 1000UL) + && thermalManager.degHotend(active_extruder) > EXTRUDER_RUNOUT_MINTEMP) { + #if ENABLED(SWITCHING_EXTRUDER) + bool oldstatus = E0_ENABLE_READ; + enable_e0(); + #else // !SWITCHING_EXTRUDER + bool oldstatus; + switch (active_extruder) { + case 0: + oldstatus = E0_ENABLE_READ; + enable_e0(); + break; + #if E_STEPPERS > 1 + case 1: + oldstatus = E1_ENABLE_READ; + enable_e1(); + break; + #if E_STEPPERS > 2 + case 2: + oldstatus = E2_ENABLE_READ; + enable_e2(); + break; + #if E_STEPPERS > 3 + case 3: + oldstatus = E3_ENABLE_READ; + enable_e3(); + break; + #endif + #endif + #endif + } + #endif // !SWITCHING_EXTRUDER + + float oldepos = current_position[E_AXIS], oldedes = destination[E_AXIS]; + planner.buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], + destination[E_AXIS] + (EXTRUDER_RUNOUT_EXTRUDE) * (EXTRUDER_RUNOUT_ESTEPS) / planner.axis_steps_per_mm[E_AXIS], + MMM_TO_MMS(EXTRUDER_RUNOUT_SPEED) * (EXTRUDER_RUNOUT_ESTEPS) / planner.axis_steps_per_mm[E_AXIS], active_extruder); + current_position[E_AXIS] = oldepos; + destination[E_AXIS] = oldedes; + planner.set_e_position_mm(oldepos); + previous_cmd_ms = ms; // refresh_cmd_timeout() + stepper.synchronize(); + #if ENABLED(SWITCHING_EXTRUDER) + E0_ENABLE_WRITE(oldstatus); + #else + switch (active_extruder) { + case 0: + E0_ENABLE_WRITE(oldstatus); + break; + #if E_STEPPERS > 1 + case 1: + E1_ENABLE_WRITE(oldstatus); + break; + #if E_STEPPERS > 2 + case 2: + E2_ENABLE_WRITE(oldstatus); + break; + #if E_STEPPERS > 3 + case 3: + E3_ENABLE_WRITE(oldstatus); + break; + #endif + #endif + #endif + } + #endif // !SWITCHING_EXTRUDER + } + #endif // EXTRUDER_RUNOUT_PREVENT + + #if ENABLED(DUAL_X_CARRIAGE) + // handle delayed move timeout + if (delayed_move_time && ELAPSED(ms, delayed_move_time + 1000UL) && IsRunning()) { + // travel moves have been received so enact them + delayed_move_time = 0xFFFFFFFFUL; // force moves to be done + set_destination_to_current(); + prepare_move_to_destination(); + } + #endif + + #if ENABLED(TEMP_STAT_LEDS) + handle_status_leds(); + #endif + + planner.check_axes_activity(); +} + +void kill(const char* lcd_msg) { + SERIAL_ERROR_START; + SERIAL_ERRORLNPGM(MSG_ERR_KILLED); + + #if ENABLED(ULTRA_LCD) + kill_screen(lcd_msg); + #else + UNUSED(lcd_msg); + #endif + + for (int i = 5; i--;) delay(100); // Wait a short time + + cli(); // Stop interrupts + thermalManager.disable_all_heaters(); + disable_all_steppers(); + + #if HAS_POWER_SWITCH + pinMode(PS_ON_PIN, INPUT); + #endif + + suicide(); + while (1) { + #if ENABLED(USE_WATCHDOG) + watchdog_reset(); + #endif + } // Wait for reset +} + +#if ENABLED(FILAMENT_RUNOUT_SENSOR) + + void handle_filament_runout() { + if (!filament_ran_out) { + filament_ran_out = true; + enqueue_and_echo_commands_P(PSTR(FILAMENT_RUNOUT_SCRIPT)); + stepper.synchronize(); + } + } + +#endif // FILAMENT_RUNOUT_SENSOR + +#if ENABLED(FAST_PWM_FAN) + + void setPwmFrequency(uint8_t pin, int val) { + val &= 0x07; + switch (digitalPinToTimer(pin)) { + #if defined(TCCR0A) + case TIMER0A: + case TIMER0B: + // TCCR0B &= ~(_BV(CS00) | _BV(CS01) | _BV(CS02)); + // TCCR0B |= val; + break; + #endif + #if defined(TCCR1A) + case TIMER1A: + case TIMER1B: + // TCCR1B &= ~(_BV(CS10) | _BV(CS11) | _BV(CS12)); + // TCCR1B |= val; + break; + #endif + #if defined(TCCR2) + case TIMER2: + case TIMER2: + TCCR2 &= ~(_BV(CS10) | _BV(CS11) | _BV(CS12)); + TCCR2 |= val; + break; + #endif + #if defined(TCCR2A) + case TIMER2A: + case TIMER2B: + TCCR2B &= ~(_BV(CS20) | _BV(CS21) | _BV(CS22)); + TCCR2B |= val; + break; + #endif + #if defined(TCCR3A) + case TIMER3A: + case TIMER3B: + case TIMER3C: + TCCR3B &= ~(_BV(CS30) | _BV(CS31) | _BV(CS32)); + TCCR3B |= val; + break; + #endif + #if defined(TCCR4A) + case TIMER4A: + case TIMER4B: + case TIMER4C: + TCCR4B &= ~(_BV(CS40) | _BV(CS41) | _BV(CS42)); + TCCR4B |= val; + break; + #endif + #if defined(TCCR5A) + case TIMER5A: + case TIMER5B: + case TIMER5C: + TCCR5B &= ~(_BV(CS50) | _BV(CS51) | _BV(CS52)); + TCCR5B |= val; + break; + #endif + } + } +#endif // FAST_PWM_FAN + +void stop() { + thermalManager.disable_all_heaters(); + if (IsRunning()) { + Running = false; + Stopped_gcode_LastN = gcode_LastN; // Save last g_code for restart + SERIAL_ERROR_START; + SERIAL_ERRORLNPGM(MSG_ERR_STOPPED); + LCD_MESSAGEPGM(MSG_STOPPED); + } +} + +float calculate_volumetric_multiplier(float diameter) { + if (!volumetric_enabled || diameter == 0) return 1.0; + float d2 = diameter * 0.5; + return 1.0 / (M_PI * d2 * d2); +} + +void calculate_volumetric_multipliers() { + for (uint8_t i = 0; i < COUNT(filament_size); i++) + volumetric_multiplier[i] = calculate_volumetric_multiplier(filament_size[i]); +} diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/SanityCheck.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/SanityCheck.h new file mode 100644 index 00000000..bec3d462 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/SanityCheck.h @@ -0,0 +1,736 @@ +/** + * 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 . + * + */ + +/** + * SanityCheck.h + * + * Test configuration values for errors at compile-time. + */ + +/** + * Due to the high number of issues related with old versions of Arduino IDE + * we now prevent Marlin from compiling with older toolkits. + */ +#if !defined(ARDUINO) || ARDUINO < 10600 + #error "Versions of Arduino IDE prior to 1.6.0 are no longer supported, please update your toolkit." +#endif + +/** + * We try our best to include sanity checks for all the changes configuration + * directives because people have a tendency to use outdated config files with + * the bleding edge source code, but sometimes this is not enough. This check + * will force a minimum config file revision, otherwise Marlin will not build. + */ +#if ! defined(CONFIGURATION_H_VERSION) || CONFIGURATION_H_VERSION < REQUIRED_CONFIGURATION_H_VERSION + #error "You are using an old Configuration.h file, update it before building Marlin." +#endif + +#if ! defined(CONFIGURATION_ADV_H_VERSION) || CONFIGURATION_ADV_H_VERSION < REQUIRED_CONFIGURATION_ADV_H_VERSION + #error "You are using an old Configuration_adv.h file, update it before building Marlin." +#endif + +/** + * Marlin release, version and default string + */ +#ifndef SHORT_BUILD_VERSION + #error "SHORT_BUILD_VERSION must be specified." +#elif !defined(DETAILED_BUILD_VERSION) + #error "BUILD_VERSION must be specified." +#elif !defined(STRING_DISTRIBUTION_DATE) + #error "STRING_DISTRIBUTION_DATE must be specified." +#elif !defined(PROTOCOL_VERSION) + #error "PROTOCOL_VERSION must be specified." +#elif !defined(MACHINE_NAME) + #error "MACHINE_NAME must be specified." +#elif !defined(SOURCE_CODE_URL) + #error "SOURCE_CODE_URL must be specified." +#elif !defined(DEFAULT_MACHINE_UUID) + #error "DEFAULT_MACHINE_UUID must be specified." +#elif !defined(WEBSITE_URL) + #error "WEBSITE_URL must be specified." +#endif + +/** + * Dual Stepper Drivers + */ +#if ENABLED(X_DUAL_STEPPER_DRIVERS) && ENABLED(DUAL_X_CARRIAGE) + #error "DUAL_X_CARRIAGE is not compatible with X_DUAL_STEPPER_DRIVERS." +#elif ENABLED(X_DUAL_STEPPER_DRIVERS) && (!HAS_X2_ENABLE || !HAS_X2_STEP || !HAS_X2_DIR) + #error "X_DUAL_STEPPER_DRIVERS requires X2 pins (and an extra E plug)." +#elif ENABLED(Y_DUAL_STEPPER_DRIVERS) && (!HAS_Y2_ENABLE || !HAS_Y2_STEP || !HAS_Y2_DIR) + #error "Y_DUAL_STEPPER_DRIVERS requires Y2 pins (and an extra E plug)." +#elif ENABLED(Z_DUAL_STEPPER_DRIVERS) && (!HAS_Z2_ENABLE || !HAS_Z2_STEP || !HAS_Z2_DIR) + #error "Z_DUAL_STEPPER_DRIVERS requires Z2 pins (and an extra E plug)." +#endif + +/** + * Progress Bar + */ +#if ENABLED(LCD_PROGRESS_BAR) + #if DISABLED(SDSUPPORT) + #error "LCD_PROGRESS_BAR requires SDSUPPORT." + #endif + #if ENABLED(DOGLCD) + #error "LCD_PROGRESS_BAR does not apply to graphical displays." + #endif + #if ENABLED(FILAMENT_LCD_DISPLAY) + #error "LCD_PROGRESS_BAR and FILAMENT_LCD_DISPLAY are not fully compatible. Comment out this line to use both." + #endif +#endif + +/** + * Babystepping + */ +#if ENABLED(BABYSTEPPING) + #if DISABLED(ULTRA_LCD) + #error "BABYSTEPPING requires an LCD controller." + #endif + #if ENABLED(SCARA) + #error "BABYSTEPPING is not implemented for SCARA yet." + #endif + #if ENABLED(DELTA) && ENABLED(BABYSTEP_XY) + #error "BABYSTEPPING only implemented for Z axis on deltabots." + #endif +#endif + +/** + * Filament Runout needs a pin and either SD Support or Auto print start detection + */ +#if ENABLED(FILAMENT_RUNOUT_SENSOR) + #if !HAS_FIL_RUNOUT + #error "FILAMENT_RUNOUT_SENSOR requires FIL_RUNOUT_PIN." + #elif DISABLED(SDSUPPORT) && DISABLED(PRINTJOB_TIMER_AUTOSTART) + #error "FILAMENT_RUNOUT_SENSOR requires SDSUPPORT or PRINTJOB_TIMER_AUTOSTART." + #endif +#endif + +/** + * Filament Change with Extruder Runout Prevention + */ +#if ENABLED(FILAMENT_CHANGE_FEATURE) && ENABLED(EXTRUDER_RUNOUT_PREVENT) + #error "EXTRUDER_RUNOUT_PREVENT is incompatible with FILAMENT_CHANGE_FEATURE." +#endif + +/** + * Individual axis homing is useless for DELTAS + */ +#if ENABLED(INDIVIDUAL_AXIS_HOMING_MENU) && ENABLED(DELTA) + #error "INDIVIDUAL_AXIS_HOMING_MENU is incompatible with DELTA kinematics." +#endif + +/** + * Options only for EXTRUDERS > 1 + */ +#if EXTRUDERS > 1 + + #if EXTRUDERS > 4 + #error "The maximum number of EXTRUDERS in Marlin is 4." + #endif + + #if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT) + #error "EXTRUDERS must be 1 with TEMP_SENSOR_1_AS_REDUNDANT." + #endif + + #if ENABLED(HEATERS_PARALLEL) + #error "EXTRUDERS must be 1 with HEATERS_PARALLEL." + #endif + +#elif ENABLED(SINGLENOZZLE) + #error "SINGLENOZZLE requires 2 or more EXTRUDERS." +#endif + +/** + * Only one type of extruder allowed + */ +#if (ENABLED(SWITCHING_EXTRUDER) && (ENABLED(SINGLENOZZLE) || ENABLED(MIXING_EXTRUDER))) \ + || (ENABLED(SINGLENOZZLE) && ENABLED(MIXING_EXTRUDER)) + #error "Please define only one type of extruder: SINGLENOZZLE, SWITCHING_EXTRUDER, or MIXING_EXTRUDER." +#endif + +/** + * Single Stepper Dual Extruder with switching servo + */ +#if ENABLED(SWITCHING_EXTRUDER) + #if ENABLED(DUAL_X_CARRIAGE) + #error "SWITCHING_EXTRUDER and DUAL_X_CARRIAGE are incompatible." + #elif EXTRUDERS != 2 + #error "SWITCHING_EXTRUDER requires exactly 2 EXTRUDERS." + #elif NUM_SERVOS < 1 + #error "SWITCHING_EXTRUDER requires NUM_SERVOS >= 1." + #endif +#endif + +/** + * Mixing Extruder requirements + */ +#if ENABLED(MIXING_EXTRUDER) + #if EXTRUDERS > 1 + #error "MIXING_EXTRUDER currently only supports one extruder." + #endif + #if MIXING_STEPPERS < 2 + #error "You must set MIXING_STEPPERS >= 2 for a mixing extruder." + #endif + #if ENABLED(FILAMENT_SENSOR) + #error "MIXING_EXTRUDER is incompatible with FILAMENT_SENSOR. Comment out this line to use it anyway." + #endif +#endif + +/** + * Limited number of servos + */ +#if defined(NUM_SERVOS) && NUM_SERVOS > 0 + #if NUM_SERVOS > 4 + #error "The maximum number of SERVOS in Marlin is 4." + #elif HAS_Z_SERVO_ENDSTOP && Z_ENDSTOP_SERVO_NR >= NUM_SERVOS + #error "Z_ENDSTOP_SERVO_NR must be smaller than NUM_SERVOS." + #endif +#endif + +/** + * Servo deactivation depends on servo endstops + */ +#if ENABLED(DEACTIVATE_SERVOS_AFTER_MOVE) && !HAS_Z_SERVO_ENDSTOP + #error "Z_ENDSTOP_SERVO_NR is required for DEACTIVATE_SERVOS_AFTER_MOVE." +#endif + +/** + * Required LCD language + */ +#if DISABLED(DOGLCD) && ENABLED(ULTRA_LCD) && !defined(DISPLAY_CHARSET_HD44780) + #error "You must set DISPLAY_CHARSET_HD44780 to JAPANESE, WESTERN or CYRILLIC for your LCD controller." +#endif + +/** + * Bed Heating Options - PID vs Limit Switching + */ +#if ENABLED(PIDTEMPBED) && ENABLED(BED_LIMIT_SWITCHING) + #error "To use BED_LIMIT_SWITCHING you must disable PIDTEMPBED." +#endif + +/** + * Mesh Bed Leveling + */ +#if ENABLED(MESH_BED_LEVELING) + #if ENABLED(DELTA) + #error "MESH_BED_LEVELING does not yet support DELTA printers." + #elif ENABLED(AUTO_BED_LEVELING_FEATURE) + #error "Select AUTO_BED_LEVELING_FEATURE or MESH_BED_LEVELING, not both." + #elif MESH_NUM_X_POINTS > 9 || MESH_NUM_Y_POINTS > 9 + #error "MESH_NUM_X_POINTS and MESH_NUM_Y_POINTS must be less than 10." + #endif +#elif ENABLED(MANUAL_BED_LEVELING) + #error "MESH_BED_LEVELING is required for MANUAL_BED_LEVELING." +#endif + +/** + * Probes + */ + +#if PROBE_SELECTED + + #if ENABLED(Z_PROBE_SLED) && ENABLED(DELTA) + #error "You cannot use Z_PROBE_SLED with DELTA." + #endif + + /** + * NUM_SERVOS is required for a Z servo probe + */ + #if HAS_Z_SERVO_ENDSTOP + #ifndef NUM_SERVOS + #error "You must set NUM_SERVOS for a Z servo probe (Z_ENDSTOP_SERVO_NR)." + #elif Z_ENDSTOP_SERVO_NR >= NUM_SERVOS + #error "Z_ENDSTOP_SERVO_NR must be less than NUM_SERVOS." + #endif + #endif + + /** + * A probe needs a pin + */ + #if !PROBE_PIN_CONFIGURED + #error "A probe needs a pin! Use Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN or Z_MIN_PROBE_PIN." + #endif + + /** + * Require a Z min pin + */ + #if HAS_Z_MIN + // Z_MIN_PIN and Z_MIN_PROBE_PIN can't co-exist when Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN + #if HAS_Z_MIN_PROBE_PIN && ENABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN) + #error "A probe cannot have more than one pin! Use Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN or Z_MIN_PROBE_PIN." + #endif + #elif !HAS_Z_MIN_PROBE_PIN || (DISABLED(Z_MIN_PROBE_ENDSTOP) || ENABLED(DISABLE_Z_MIN_PROBE_ENDSTOP)) + // A pin was set for the Z probe, but not enabled. + #error "A probe requires a Z_MIN or Z_PROBE pin. Z_MIN_PIN or Z_MIN_PROBE_PIN must point to a valid hardware pin." + #endif + + /** + * Make sure the plug is enabled if it's used + */ + #if ENABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN) && DISABLED(USE_ZMIN_PLUG) + #error "You must enable USE_ZMIN_PLUG if any probe or endstop is connected to the ZMIN plug." + #endif + + /** + * Only allow one probe option to be defined + */ + #if (ENABLED(FIX_MOUNTED_PROBE) && (ENABLED(Z_PROBE_ALLEN_KEY) || HAS_Z_SERVO_ENDSTOP || ENABLED(Z_PROBE_SLED))) \ + || (ENABLED(Z_PROBE_ALLEN_KEY) && (HAS_Z_SERVO_ENDSTOP || ENABLED(Z_PROBE_SLED))) \ + || (HAS_Z_SERVO_ENDSTOP && ENABLED(Z_PROBE_SLED)) + #error "Please define only one type of probe: Z Servo, Z_PROBE_ALLEN_KEY, Z_PROBE_SLED, or FIX_MOUNTED_PROBE." + #endif + + /** + * Don't allow nonsense probe-pin settings + */ + #if ENABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN) && ENABLED(Z_MIN_PROBE_ENDSTOP) + #error "You can't enable both Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN and Z_MIN_PROBE_ENDSTOP." + #elif ENABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN) && ENABLED(DISABLE_Z_MIN_PROBE_ENDSTOP) + #error "Don't enable DISABLE_Z_MIN_PROBE_ENDSTOP with Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN." + #elif ENABLED(DISABLE_Z_MIN_PROBE_ENDSTOP) && DISABLED(Z_MIN_PROBE_ENDSTOP) + #error "DISABLE_Z_MIN_PROBE_ENDSTOP requires Z_MIN_PROBE_ENDSTOP to be set." + #endif + + /** + * Require a Z probe pin if Z_MIN_PROBE_ENDSTOP is enabled. + */ + #if ENABLED(Z_MIN_PROBE_ENDSTOP) + #if !HAS_Z_MIN_PROBE_PIN + #error "Z_MIN_PROBE_ENDSTOP requires a Z_MIN_PROBE_PIN in your board's pins_XXXX.h file." + #endif + // Forcing Servo definitions can break some hall effect sensor setups. Leaving these here for further comment. + //#ifndef NUM_SERVOS + // #error "You must have NUM_SERVOS defined and there must be at least 1 configured to use Z_MIN_PROBE_ENDSTOP." + //#endif + //#if defined(NUM_SERVOS) && NUM_SERVOS < 1 + // #error "You must have at least 1 servo defined for NUM_SERVOS to use Z_MIN_PROBE_ENDSTOP." + //#endif + //#if Z_ENDSTOP_SERVO_NR < 0 + // #error "You must have Z_ENDSTOP_SERVO_NR set to at least 0 or above to use Z_MIN_PROBE_ENDSTOP." + //#endif + //#ifndef Z_SERVO_ANGLES + // #error "You must have Z_SERVO_ANGLES defined for Z Extend and Retract to use Z_MIN_PROBE_ENDSTOP." + //#endif + #endif + + /** + * Make sure Z raise values are set + */ + #if !defined(Z_PROBE_DEPLOY_HEIGHT) + #error "You must set Z_PROBE_DEPLOY_HEIGHT in your configuration." + #elif !defined(Z_PROBE_TRAVEL_HEIGHT) + #error "You must set Z_PROBE_TRAVEL_HEIGHT in your configuration." + #elif Z_PROBE_DEPLOY_HEIGHT < 0 + #error "Probes need Z_PROBE_DEPLOY_HEIGHT >= 0." + #elif Z_PROBE_TRAVEL_HEIGHT < 0 + #error "Probes need Z_PROBE_TRAVEL_HEIGHT >= 0." + #endif + +#else + + /** + * Require some kind of probe for bed leveling and probe testing + */ + #if ENABLED(AUTO_BED_LEVELING_FEATURE) + #error "AUTO_BED_LEVELING_FEATURE requires a probe! Define a Z Servo, Z_PROBE_ALLEN_KEY, Z_PROBE_SLED, or FIX_MOUNTED_PROBE." + #elif ENABLED(Z_MIN_PROBE_REPEATABILITY_TEST) + #error "Z_MIN_PROBE_REPEATABILITY_TEST requires a probe! Define a Z Servo, Z_PROBE_ALLEN_KEY, Z_PROBE_SLED, or FIX_MOUNTED_PROBE." + #endif + +#endif + +/** + * Make sure Z_SAFE_HOMING point is reachable + */ +#if ENABLED(Z_SAFE_HOMING) + #if Z_SAFE_HOMING_X_POINT < MIN_PROBE_X || Z_SAFE_HOMING_X_POINT > MAX_PROBE_X + #if HAS_BED_PROBE + #error "Z_SAFE_HOMING_X_POINT can't be reached by the Z probe." + #else + #error "Z_SAFE_HOMING_X_POINT can't be reached by the nozzle." + #endif + #elif Z_SAFE_HOMING_Y_POINT < MIN_PROBE_Y || Z_SAFE_HOMING_Y_POINT > MAX_PROBE_Y + #if HAS_BED_PROBE + #error "Z_SAFE_HOMING_Y_POINT can't be reached by the Z probe." + #else + #error "Z_SAFE_HOMING_Y_POINT can't be reached by the nozzle." + #endif + #endif +#endif // Z_SAFE_HOMING + +/** + * Auto Bed Leveling + */ +#if ENABLED(AUTO_BED_LEVELING_FEATURE) + + /** + * Delta has limited bed leveling options + */ + #if ENABLED(DELTA) && DISABLED(AUTO_BED_LEVELING_GRID) + #error "You must use AUTO_BED_LEVELING_GRID for DELTA bed leveling." + #endif + + /** + * Check if Probe_Offset * Grid Points is greater than Probing Range + */ + #if ENABLED(AUTO_BED_LEVELING_GRID) + #ifndef DELTA_PROBEABLE_RADIUS + // Be sure points are in the right order + #if LEFT_PROBE_BED_POSITION > RIGHT_PROBE_BED_POSITION + #error "LEFT_PROBE_BED_POSITION must be less than RIGHT_PROBE_BED_POSITION." + #elif FRONT_PROBE_BED_POSITION > BACK_PROBE_BED_POSITION + #error "FRONT_PROBE_BED_POSITION must be less than BACK_PROBE_BED_POSITION." + #endif + // Make sure probing points are reachable + #if LEFT_PROBE_BED_POSITION < MIN_PROBE_X + #error "The given LEFT_PROBE_BED_POSITION can't be reached by the Z probe." + #elif RIGHT_PROBE_BED_POSITION > MAX_PROBE_X + #error "The given RIGHT_PROBE_BED_POSITION can't be reached by the Z probe." + #elif FRONT_PROBE_BED_POSITION < MIN_PROBE_Y + #error "The given FRONT_PROBE_BED_POSITION can't be reached by the Z probe." + #elif BACK_PROBE_BED_POSITION > MAX_PROBE_Y + #error "The given BACK_PROBE_BED_POSITION can't be reached by the Z probe." + #endif + #endif + #else // !AUTO_BED_LEVELING_GRID + + // Check the triangulation points + #if ABL_PROBE_PT_1_X < MIN_PROBE_X || ABL_PROBE_PT_1_X > MAX_PROBE_X + #error "The given ABL_PROBE_PT_1_X can't be reached by the Z probe." + #elif ABL_PROBE_PT_2_X < MIN_PROBE_X || ABL_PROBE_PT_2_X > MAX_PROBE_X + #error "The given ABL_PROBE_PT_2_X can't be reached by the Z probe." + #elif ABL_PROBE_PT_3_X < MIN_PROBE_X || ABL_PROBE_PT_3_X > MAX_PROBE_X + #error "The given ABL_PROBE_PT_3_X can't be reached by the Z probe." + #elif ABL_PROBE_PT_1_Y < MIN_PROBE_Y || ABL_PROBE_PT_1_Y > MAX_PROBE_Y + #error "The given ABL_PROBE_PT_1_Y can't be reached by the Z probe." + #elif ABL_PROBE_PT_2_Y < MIN_PROBE_Y || ABL_PROBE_PT_2_Y > MAX_PROBE_Y + #error "The given ABL_PROBE_PT_2_Y can't be reached by the Z probe." + #elif ABL_PROBE_PT_3_Y < MIN_PROBE_Y || ABL_PROBE_PT_3_Y > MAX_PROBE_Y + #error "The given ABL_PROBE_PT_3_Y can't be reached by the Z probe." + #endif + + #endif // !AUTO_BED_LEVELING_GRID + +#endif // AUTO_BED_LEVELING_FEATURE + +/** + * Advance Extrusion + */ +#if ENABLED(ADVANCE) && ENABLED(LIN_ADVANCE) + #error "You can enable ADVANCE or LIN_ADVANCE, but not both." +#endif + +/** + * Filament Width Sensor + */ +#if ENABLED(FILAMENT_WIDTH_SENSOR) && !HAS_FILAMENT_WIDTH_SENSOR + #error "FILAMENT_WIDTH_SENSOR requires a FILWIDTH_PIN to be defined." +#endif + +/** + * ULTIPANEL encoder + */ +#if ENABLED(ULTIPANEL) && DISABLED(NEWPANEL) && DISABLED(SR_LCD_2W_NL) && !defined(SHIFT_CLK) + #error "ULTIPANEL requires some kind of encoder." +#endif + +#if ENCODER_PULSES_PER_STEP < 0 + #error "ENCODER_PULSES_PER_STEP should not be negative, use REVERSE_MENU_DIRECTION instead." +#endif + +/** + * SAV_3DGLCD display options + */ +#if ENABLED(U8GLIB_SSD1306) && ENABLED(U8GLIB_SH1106) + #error "Only enable one SAV_3DGLCD display type: U8GLIB_SSD1306 or U8GLIB_SH1106." +#endif + +/** + * Don't set more than one kinematic type + */ +#if (ENABLED(DELTA) && (ENABLED(SCARA) || ENABLED(COREXY) || ENABLED(COREXZ) || ENABLED(COREYZ))) \ + || (ENABLED(SCARA) && (ENABLED(COREXY) || ENABLED(COREXZ) || ENABLED(COREYZ))) \ + || (ENABLED(COREXY) && (ENABLED(COREXZ) || ENABLED(COREYZ))) \ + || (ENABLED(COREXZ) && ENABLED(COREYZ)) + #error "Please enable only one of DELTA, SCARA, COREXY, COREXZ, or COREYZ." +#endif + +/** + * Allen Key + * 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" +#endif + +/** + * Dual X Carriage requirements + */ +#if ENABLED(DUAL_X_CARRIAGE) + #if EXTRUDERS == 1 + #error "DUAL_X_CARRIAGE requires 2 (or more) extruders." + #elif ENABLED(COREXY) || ENABLED(COREXZ) + #error "DUAL_X_CARRIAGE cannot be used with COREXY or COREXZ." + #elif !HAS_X2_ENABLE || !HAS_X2_STEP || !HAS_X2_DIR + #error "DUAL_X_CARRIAGE requires X2 stepper pins to be defined." + #elif !HAS_X_MAX + #error "DUAL_X_CARRIAGE requires USE_XMAX_PLUG and an X Max Endstop." + #elif !defined(X2_HOME_POS) || !defined(X2_MIN_POS) || !defined(X2_MAX_POS) + #error "DUAL_X_CARRIAGE requires X2_HOME_POS, X2_MIN_POS, and X2_MAX_POS." + #elif X_HOME_DIR != -1 || X2_HOME_DIR != 1 + #error "DUAL_X_CARRIAGE requires X_HOME_DIR -1 and X2_HOME_DIR 1." + #endif +#endif // DUAL_X_CARRIAGE + +/** + * Make sure auto fan pins don't conflict with the fan pin + */ +#if HAS_AUTO_FAN + #if HAS_FAN0 + #if EXTRUDER_0_AUTO_FAN_PIN == FAN_PIN + #error "You cannot set EXTRUDER_0_AUTO_FAN_PIN equal to FAN_PIN." + #elif EXTRUDER_1_AUTO_FAN_PIN == FAN_PIN + #error "You cannot set EXTRUDER_1_AUTO_FAN_PIN equal to FAN_PIN." + #elif EXTRUDER_2_AUTO_FAN_PIN == FAN_PIN + #error "You cannot set EXTRUDER_2_AUTO_FAN_PIN equal to FAN_PIN." + #elif EXTRUDER_3_AUTO_FAN_PIN == FAN_PIN + #error "You cannot set EXTRUDER_3_AUTO_FAN_PIN equal to FAN_PIN." + #endif + #endif +#endif + +#if HAS_FAN0 && CONTROLLERFAN_PIN == FAN_PIN + #error "You cannot set CONTROLLERFAN_PIN equal to FAN_PIN." +#endif + +#if HAS_CONTROLLERFAN + #if EXTRUDER_0_AUTO_FAN_PIN == CONTROLLERFAN_PIN + #error "You cannot set EXTRUDER_0_AUTO_FAN_PIN equal to CONTROLLERFAN_PIN." + #elif EXTRUDER_1_AUTO_FAN_PIN == CONTROLLERFAN_PIN + #error "You cannot set EXTRUDER_1_AUTO_FAN_PIN equal to CONTROLLERFAN_PIN." + #elif EXTRUDER_2_AUTO_FAN_PIN == CONTROLLERFAN_PIN + #error "You cannot set EXTRUDER_2_AUTO_FAN_PIN equal to CONTROLLERFAN_PIN." + #elif EXTRUDER_3_AUTO_FAN_PIN == CONTROLLERFAN_PIN + #error "You cannot set EXTRUDER_3_AUTO_FAN_PIN equal to CONTROLLERFAN_PIN." + #endif +#endif + +/** + * Test Heater, Temp Sensor, and Extruder Pins; Sensor Type must also be set. + */ +#if !HAS_HEATER_0 + #error "HEATER_0_PIN not defined for this board." +#elif !PIN_EXISTS(TEMP_0) + #error "TEMP_0_PIN not defined for this board." +#elif !PIN_EXISTS(E0_STEP) || !PIN_EXISTS(E0_DIR) || !PIN_EXISTS(E0_ENABLE) + #error "E0_STEP_PIN, E0_DIR_PIN, or E0_ENABLE_PIN not defined for this board." +#elif TEMP_SENSOR_0 == 0 + #error "TEMP_SENSOR_0 is required." +#endif + +#if HOTENDS > 1 || ENABLED(HEATERS_PARALLEL) + #if !HAS_HEATER_1 + #error "HEATER_1_PIN not defined for this board." + #endif +#endif + +#if HOTENDS > 1 + #if TEMP_SENSOR_1 == 0 + #error "TEMP_SENSOR_1 is required with 2 or more HOTENDS." + #elif !PIN_EXISTS(TEMP_1) + #error "TEMP_1_PIN not defined for this board." + #endif + #if HOTENDS > 2 + #if TEMP_SENSOR_2 == 0 + #error "TEMP_SENSOR_2 is required with 3 or more HOTENDS." + #elif !HAS_HEATER_2 + #error "HEATER_2_PIN not defined for this board." + #elif !PIN_EXISTS(TEMP_2) + #error "TEMP_2_PIN not defined for this board." + #endif + #if HOTENDS > 3 + #if TEMP_SENSOR_3 == 0 + #error "TEMP_SENSOR_3 is required with 4 HOTENDS." + #elif !HAS_HEATER_3 + #error "HEATER_3_PIN not defined for this board." + #elif !PIN_EXISTS(TEMP_3) + #error "TEMP_3_PIN not defined for this board." + #endif + #elif TEMP_SENSOR_3 != 0 + #error "TEMP_SENSOR_3 shouldn't be set with only 3 extruders." + #endif + #elif TEMP_SENSOR_2 != 0 + #error "TEMP_SENSOR_2 shouldn't be set with only 2 extruders." + #elif TEMP_SENSOR_3 != 0 + #error "TEMP_SENSOR_3 shouldn't be set with only 2 extruders." + #endif +#elif TEMP_SENSOR_1 != 0 && DISABLED(TEMP_SENSOR_1_AS_REDUNDANT) + #error "TEMP_SENSOR_1 shouldn't be set with only 1 extruder." +#elif TEMP_SENSOR_2 != 0 + #error "TEMP_SENSOR_2 shouldn't be set with only 1 extruder." +#elif TEMP_SENSOR_3 != 0 + #error "TEMP_SENSOR_3 shouldn't be set with only 1 extruder." +#endif + +#if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT) && TEMP_SENSOR_1 == 0 + #error "TEMP_SENSOR_1 is required with TEMP_SENSOR_1_AS_REDUNDANT." +#endif + +/** + * Basic 2-nozzle duplication mode + */ +#if ENABLED(DUAL_NOZZLE_DUPLICATION_MODE) + #if HOTENDS != 2 + #error "DUAL_NOZZLE_DUPLICATION_MODE requires exactly 2 hotends." + #elif ENABLED(DUAL_X_CARRIAGE) + #error "DUAL_NOZZLE_DUPLICATION_MODE is incompatible with DUAL_X_CARRIAGE." + #elif ENABLED(SINGLENOZZLE) + #error "DUAL_NOZZLE_DUPLICATION_MODE is incompatible with SINGLENOZZLE." + #elif ENABLED(MIXING_EXTRUDER) + #error "DUAL_NOZZLE_DUPLICATION_MODE is incompatible with MIXING_EXTRUDER." + #elif ENABLED(SWITCHING_EXTRUDER) + #error "DUAL_NOZZLE_DUPLICATION_MODE is incompatible with SWITCHING_EXTRUDER." + #endif +#endif + +/** + * Test Extruder Pins + */ +#if EXTRUDERS > 3 + #if !PIN_EXISTS(E3_STEP) || !PIN_EXISTS(E3_DIR) || !PIN_EXISTS(E3_ENABLE) + #error "E3_STEP_PIN, E3_DIR_PIN, or E3_ENABLE_PIN not defined for this board." + #endif +#elif EXTRUDERS > 2 + #if !PIN_EXISTS(E2_STEP) || !PIN_EXISTS(E2_DIR) || !PIN_EXISTS(E2_ENABLE) + #error "E2_STEP_PIN, E2_DIR_PIN, or E2_ENABLE_PIN not defined for this board." + #endif +#elif EXTRUDERS > 1 + #if !PIN_EXISTS(E1_STEP) || !PIN_EXISTS(E1_DIR) || !PIN_EXISTS(E1_ENABLE) + #error "E1_STEP_PIN, E1_DIR_PIN, or E1_ENABLE_PIN not defined for this board." + #endif +#endif + +/** + * Endstops + */ +#if DISABLED(USE_XMIN_PLUG) && DISABLED(USE_XMAX_PLUG) && !(ENABLED(Z_DUAL_ENDSTOPS) && Z2_USE_ENDSTOP >= _XMAX_ && Z2_USE_ENDSTOP <= _XMIN_) + #error "You must enable USE_XMIN_PLUG or USE_XMAX_PLUG" +#elif DISABLED(USE_YMIN_PLUG) && DISABLED(USE_YMAX_PLUG) && !(ENABLED(Z_DUAL_ENDSTOPS) && Z2_USE_ENDSTOP >= _YMAX_ && Z2_USE_ENDSTOP <= _YMIN_) + #error "You must enable USE_YMIN_PLUG or USE_YMAX_PLUG" +#elif DISABLED(USE_ZMIN_PLUG) && DISABLED(USE_ZMAX_PLUG) && !(ENABLED(Z_DUAL_ENDSTOPS) && Z2_USE_ENDSTOP >= _ZMAX_ && Z2_USE_ENDSTOP <= _ZMIN_) + #error "You must enable USE_ZMIN_PLUG or USE_ZMAX_PLUG" +#elif ENABLED(Z_DUAL_ENDSTOPS) && !Z2_USE_ENDSTOP + #error "You must set Z2_USE_ENDSTOP with Z_DUAL_ENDSTOPS" +#endif + +/** + * emergency-command parser + */ +#if ENABLED(EMERGENCY_PARSER) && ENABLED(USBCON) + #error "EMERGENCY_PARSER does not work on boards with AT90USB processors (USBCON)." +#endif + + /** + * Warnings for old configurations + */ +#if WATCH_TEMP_PERIOD > 500 + #error "WATCH_TEMP_PERIOD now uses seconds instead of milliseconds." +#elif DISABLED(THERMAL_PROTECTION_HOTENDS) && (defined(WATCH_TEMP_PERIOD) || defined(THERMAL_PROTECTION_PERIOD)) + #error "Thermal Runaway Protection for hotends is now enabled with THERMAL_PROTECTION_HOTENDS." +#elif DISABLED(THERMAL_PROTECTION_BED) && defined(THERMAL_PROTECTION_BED_PERIOD) + #error "Thermal Runaway Protection for the bed is now enabled with THERMAL_PROTECTION_BED." +#elif ENABLED(COREXZ) && ENABLED(Z_LATE_ENABLE) + #error "Z_LATE_ENABLE can't be used with COREXZ." +#elif defined(X_HOME_RETRACT_MM) + #error "[XYZ]_HOME_RETRACT_MM settings have been renamed [XYZ]_HOME_BUMP_MM." +#elif defined(BEEPER) + #error "BEEPER is now BEEPER_PIN. Please update your pins definitions." +#elif defined(SDCARDDETECT) + #error "SDCARDDETECT is now SD_DETECT_PIN. Please update your pins definitions." +#elif defined(SDCARDDETECTINVERTED) + #error "SDCARDDETECTINVERTED is now SD_DETECT_INVERTED. Please update your configuration." +#elif defined(BTENABLED) + #error "BTENABLED is now BLUETOOTH. Please update your configuration." +#elif defined(CUSTOM_MENDEL_NAME) + #error "CUSTOM_MENDEL_NAME is now CUSTOM_MACHINE_NAME. Please update your configuration." +#elif defined(HAS_AUTOMATIC_VERSIONING) + #error "HAS_AUTOMATIC_VERSIONING is now USE_AUTOMATIC_VERSIONING. Please update your configuration." +#elif defined(ENABLE_AUTO_BED_LEVELING) + #error "ENABLE_AUTO_BED_LEVELING is now AUTO_BED_LEVELING_FEATURE. Please update your configuration." +#elif defined(SDSLOW) + #error "SDSLOW deprecated. Set SPI_SPEED to SPI_HALF_SPEED instead." +#elif defined(SDEXTRASLOW) + #error "SDEXTRASLOW deprecated. Set SPI_SPEED to SPI_QUARTER_SPEED instead." +#elif defined(FILAMENT_SENSOR) + #error "FILAMENT_SENSOR is deprecated. Use FILAMENT_WIDTH_SENSOR instead." +#elif defined(DISABLE_MAX_ENDSTOPS) || defined(DISABLE_MIN_ENDSTOPS) + #error "DISABLE_MAX_ENDSTOPS and DISABLE_MIN_ENDSTOPS deprecated. Use individual USE_*_PLUG options instead." +#elif ENABLED(Z_DUAL_ENDSTOPS) && !defined(Z2_USE_ENDSTOP) + #error "Z_DUAL_ENDSTOPS settings are simplified. Just set Z2_USE_ENDSTOP to the endstop you want to repurpose for Z2" +#elif defined(LANGUAGE_INCLUDE) + #error "LANGUAGE_INCLUDE has been replaced by LCD_LANGUAGE. Please update your configuration." +#elif defined(EXTRUDER_OFFSET_X) || defined(EXTRUDER_OFFSET_Y) + #error "EXTRUDER_OFFSET_[XY] is deprecated. Use HOTEND_OFFSET_[XY] instead." +#elif defined(PID_PARAMS_PER_EXTRUDER) + #error "PID_PARAMS_PER_EXTRUDER is deprecated. Use PID_PARAMS_PER_HOTEND instead." +#elif defined(EXTRUDER_WATTS) || defined(BED_WATTS) + #error "EXTRUDER_WATTS and BED_WATTS are deprecated. Remove them from your configuration." +#elif defined(SERVO_ENDSTOP_ANGLES) + #error "SERVO_ENDSTOP_ANGLES is deprecated. Use Z_SERVO_ANGLES instead." +#elif defined(X_ENDSTOP_SERVO_NR) || defined(Y_ENDSTOP_SERVO_NR) + #error "X_ENDSTOP_SERVO_NR and Y_ENDSTOP_SERVO_NR are deprecated and should be removed." +#elif defined(XY_TRAVEL_SPEED) + #error "XY_TRAVEL_SPEED is deprecated. Use XY_PROBE_SPEED instead." +#elif defined(PROBE_SERVO_DEACTIVATION_DELAY) + #error "PROBE_SERVO_DEACTIVATION_DELAY is deprecated. Use DEACTIVATE_SERVOS_AFTER_MOVE instead." +#elif defined(SERVO_DEACTIVATION_DELAY) + #error "SERVO_DEACTIVATION_DELAY is deprecated. Use SERVO_DELAY instead." +#elif ENABLED(FILAMENTCHANGEENABLE) + #error "FILAMENTCHANGEENABLE is now FILAMENT_CHANGE_FEATURE. Please update your configuration." +#elif defined(PLA_PREHEAT_HOTEND_TEMP) + #error "PLA_PREHEAT_HOTEND_TEMP is now PREHEAT_1_TEMP_HOTEND. Please update your configuration." +#elif defined(PLA_PREHEAT_HPB_TEMP) + #error "PLA_PREHEAT_HPB_TEMP is now PREHEAT_1_TEMP_BED. Please update your configuration." +#elif defined(PLA_PREHEAT_FAN_SPEED) + #error "PLA_PREHEAT_FAN_SPEED is now PREHEAT_1_FAN_SPEED. Please update your configuration." +#elif defined(ABS_PREHEAT_HOTEND_TEMP) + #error "ABS_PREHEAT_HOTEND_TEMP is now PREHEAT_2_TEMP_HOTEND. Please update your configuration." +#elif defined(ABS_PREHEAT_HPB_TEMP) + #error "ABS_PREHEAT_HPB_TEMP is now PREHEAT_2_TEMP_BED. Please update your configuration." +#elif defined(ABS_PREHEAT_FAN_SPEED) + #error "ABS_PREHEAT_FAN_SPEED is now PREHEAT_2_FAN_SPEED. Please update your configuration." +#elif defined(ENDSTOPS_ONLY_FOR_HOMING) + #error "ENDSTOPS_ONLY_FOR_HOMING is deprecated. Use (disable) ENDSTOPS_ALWAYS_ON_DEFAULT instead." +#elif defined(HOMING_FEEDRATE) + #error "HOMING_FEEDRATE is deprecated. Set individual rates with HOMING_FEEDRATE_(XY|Z|E) instead." +#elif defined(MANUAL_HOME_POSITIONS) + #error "MANUAL_HOME_POSITIONS is deprecated. Set MANUAL_[XYZ]_HOME_POS as-needed instead." +#elif defined(PID_ADD_EXTRUSION_RATE) + #error "PID_ADD_EXTRUSION_RATE is now PID_EXTRUSION_SCALING and is DISABLED by default. Are you sure you want to use this option? Please update your configuration." +#elif defined(Z_RAISE_BEFORE_HOMING) + #error "Z_RAISE_BEFORE_HOMING is now Z_HOMING_HEIGHT. Please update your configuration." +#elif defined(MIN_Z_HEIGHT_FOR_HOMING) + #error "MIN_Z_HEIGHT_FOR_HOMING is now Z_HOMING_HEIGHT. Please update your configuration." +#elif defined(Z_RAISE_BEFORE_PROBING) || defined(Z_RAISE_AFTER_PROBING) + #error "Z_RAISE_(BEFORE|AFTER)_PROBING are deprecated. Use Z_PROBE_DEPLOY_HEIGHT instead." +#elif defined(Z_RAISE_PROBE_DEPLOY_STOW) || defined(Z_RAISE_BETWEEN_PROBINGS) + #error "Z_RAISE_PROBE_DEPLOY_STOW and Z_RAISE_BETWEEN_PROBINGS are now Z_PROBE_DEPLOY_HEIGHT and Z_PROBE_TRAVEL_HEIGHT Please update your configuration." +#endif diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/Sd2Card.cpp b/trunk/Arduino/Marlin_K8600_1.1.0RC7/Sd2Card.cpp new file mode 100644 index 00000000..190e4ad1 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/Sd2Card.cpp @@ -0,0 +1,719 @@ +/** + * 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 . + * + */ + +/** + * Arduino Sd2Card Library + * Copyright (C) 2009 by William Greiman + * + * This file is part of the Arduino Sd2Card Library + */ +#include "Marlin.h" + +#if ENABLED(SDSUPPORT) +#include "Sd2Card.h" + +//------------------------------------------------------------------------------ +#if DISABLED(SOFTWARE_SPI) + // functions for hardware SPI + //------------------------------------------------------------------------------ + // make sure SPCR rate is in expected bits + #if (SPR0 != 0 || SPR1 != 1) + #error "unexpected SPCR bits" + #endif + /** + * Initialize hardware SPI + * Set SCK rate to F_CPU/pow(2, 1 + spiRate) for spiRate [0,6] + */ + static void spiInit(uint8_t spiRate) { + // See avr processor documentation + SPCR = _BV(SPE) | _BV(MSTR) | (spiRate >> 1); + SPSR = spiRate & 1 || spiRate == 6 ? 0 : _BV(SPI2X); + } + //------------------------------------------------------------------------------ + /** SPI receive a byte */ + static uint8_t spiRec() { + SPDR = 0XFF; + while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ } + return SPDR; + } + //------------------------------------------------------------------------------ + /** SPI read data - only one call so force inline */ + static inline __attribute__((always_inline)) + void spiRead(uint8_t* buf, uint16_t nbyte) { + 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; + } + //------------------------------------------------------------------------------ + /** SPI send a byte */ + static void spiSend(uint8_t b) { + SPDR = b; + while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ } + } + //------------------------------------------------------------------------------ + /** SPI send block - only one call so force inline */ + static inline __attribute__((always_inline)) + void spiSendBlock(uint8_t token, const uint8_t* buf) { + SPDR = token; + for (uint16_t i = 0; i < 512; i += 2) { + while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ } + SPDR = buf[i]; + while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ } + SPDR = buf[i + 1]; + } + while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ } + } + //------------------------------------------------------------------------------ +#else // SOFTWARE_SPI + //------------------------------------------------------------------------------ + /** nop to tune soft SPI timing */ + #define nop asm volatile ("nop\n\t") + //------------------------------------------------------------------------------ + /** Soft SPI receive byte */ + static uint8_t spiRec() { + uint8_t data = 0; + // no interrupts during byte receive - about 8 us + cli(); + // output pin high - like sending 0XFF + WRITE(SPI_MOSI_PIN, HIGH); + + for (uint8_t i = 0; i < 8; i++) { + WRITE(SPI_SCK_PIN, HIGH); + + // adjust so SCK is nice + nop; + nop; + + data <<= 1; + + if (READ(SPI_MISO_PIN)) data |= 1; + + WRITE(SPI_SCK_PIN, LOW); + } + // enable interrupts + sei(); + return data; + } + //------------------------------------------------------------------------------ + /** Soft SPI read data */ + static void spiRead(uint8_t* buf, uint16_t nbyte) { + for (uint16_t i = 0; i < nbyte; i++) + buf[i] = spiRec(); + } + //------------------------------------------------------------------------------ + /** Soft SPI send byte */ + static void spiSend(uint8_t data) { + // no interrupts during byte send - about 8 us + cli(); + for (uint8_t i = 0; i < 8; i++) { + WRITE(SPI_SCK_PIN, LOW); + + WRITE(SPI_MOSI_PIN, data & 0X80); + + data <<= 1; + + WRITE(SPI_SCK_PIN, HIGH); + } + // hold SCK high for a few ns + nop; + nop; + nop; + nop; + + WRITE(SPI_SCK_PIN, LOW); + // enable interrupts + sei(); + } + //------------------------------------------------------------------------------ + /** Soft SPI send block */ + void spiSendBlock(uint8_t token, const uint8_t* buf) { + spiSend(token); + for (uint16_t i = 0; i < 512; i++) + spiSend(buf[i]); + } +#endif // SOFTWARE_SPI +//------------------------------------------------------------------------------ +// send command and return error code. Return zero for OK +uint8_t Sd2Card::cardCommand(uint8_t cmd, uint32_t arg) { + // select card + chipSelectLow(); + + // wait up to 300 ms if busy + waitNotBusy(300); + + // send command + spiSend(cmd | 0x40); + + // send argument + for (int8_t s = 24; s >= 0; s -= 8) spiSend(arg >> s); + + // send CRC + uint8_t crc = 0XFF; + if (cmd == CMD0) crc = 0X95; // correct crc for CMD0 with arg 0 + if (cmd == CMD8) crc = 0X87; // correct crc for CMD8 with arg 0X1AA + spiSend(crc); + + // skip stuff byte for stop read + if (cmd == CMD12) spiRec(); + + // wait for response + for (uint8_t i = 0; ((status_ = spiRec()) & 0X80) && i != 0XFF; i++) { /* Intentionally left empty */ } + return status_; +} +//------------------------------------------------------------------------------ +/** + * Determine the size of an SD flash memory card. + * + * \return The number of 512 byte data blocks in the card + * or zero if an error occurs. + */ +uint32_t Sd2Card::cardSize() { + csd_t csd; + if (!readCSD(&csd)) return 0; + if (csd.v1.csd_ver == 0) { + uint8_t read_bl_len = csd.v1.read_bl_len; + uint16_t c_size = (csd.v1.c_size_high << 10) + | (csd.v1.c_size_mid << 2) | csd.v1.c_size_low; + uint8_t c_size_mult = (csd.v1.c_size_mult_high << 1) + | csd.v1.c_size_mult_low; + return (uint32_t)(c_size + 1) << (c_size_mult + read_bl_len - 7); + } + else if (csd.v2.csd_ver == 1) { + uint32_t c_size = ((uint32_t)csd.v2.c_size_high << 16) + | (csd.v2.c_size_mid << 8) | csd.v2.c_size_low; + return (c_size + 1) << 10; + } + else { + error(SD_CARD_ERROR_BAD_CSD); + return 0; + } +} +//------------------------------------------------------------------------------ +void Sd2Card::chipSelectHigh() { + digitalWrite(chipSelectPin_, HIGH); +} +//------------------------------------------------------------------------------ +void Sd2Card::chipSelectLow() { + #if DISABLED(SOFTWARE_SPI) + spiInit(spiRate_); + #endif // SOFTWARE_SPI + digitalWrite(chipSelectPin_, LOW); +} +//------------------------------------------------------------------------------ +/** Erase a range of blocks. + * + * \param[in] firstBlock The address of the first block in the range. + * \param[in] lastBlock The address of the last block in the range. + * + * \note This function requests the SD card to do a flash erase for a + * range of blocks. The data on the card after an erase operation is + * either 0 or 1, depends on the card vendor. The card must support + * single block erase. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool Sd2Card::erase(uint32_t firstBlock, uint32_t lastBlock) { + csd_t csd; + if (!readCSD(&csd)) goto fail; + // check for single block erase + if (!csd.v1.erase_blk_en) { + // erase size mask + uint8_t m = (csd.v1.sector_size_high << 1) | csd.v1.sector_size_low; + if ((firstBlock & m) != 0 || ((lastBlock + 1) & m) != 0) { + // error card can't erase specified area + error(SD_CARD_ERROR_ERASE_SINGLE_BLOCK); + goto fail; + } + } + if (type_ != SD_CARD_TYPE_SDHC) { + firstBlock <<= 9; + lastBlock <<= 9; + } + if (cardCommand(CMD32, firstBlock) + || cardCommand(CMD33, lastBlock) + || cardCommand(CMD38, 0)) { + error(SD_CARD_ERROR_ERASE); + goto fail; + } + if (!waitNotBusy(SD_ERASE_TIMEOUT)) { + error(SD_CARD_ERROR_ERASE_TIMEOUT); + goto fail; + } + chipSelectHigh(); + return true; +fail: + chipSelectHigh(); + return false; +} +//------------------------------------------------------------------------------ +/** Determine if card supports single block erase. + * + * \return The value one, true, is returned if single block erase is supported. + * The value zero, false, is returned if single block erase is not supported. + */ +bool Sd2Card::eraseSingleBlockEnable() { + csd_t csd; + return readCSD(&csd) ? csd.v1.erase_blk_en : false; +} +//------------------------------------------------------------------------------ +/** + * Initialize an SD flash memory card. + * + * \param[in] sckRateID SPI clock rate selector. See setSckRate(). + * \param[in] chipSelectPin SD chip select pin number. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. The reason for failure + * can be determined by calling errorCode() and errorData(). + */ +bool Sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin) { + errorCode_ = type_ = 0; + chipSelectPin_ = chipSelectPin; + // 16-bit init start time allows over a minute + uint16_t t0 = (uint16_t)millis(); + uint32_t arg; + + // set pin modes + pinMode(chipSelectPin_, OUTPUT); + chipSelectHigh(); + pinMode(SPI_MISO_PIN, INPUT); + pinMode(SPI_MOSI_PIN, OUTPUT); + pinMode(SPI_SCK_PIN, OUTPUT); + + #if DISABLED(SOFTWARE_SPI) + // SS must be in output mode even it is not chip select + pinMode(SS_PIN, OUTPUT); + // set SS high - may be chip select for another SPI device + #if SET_SPI_SS_HIGH + digitalWrite(SS_PIN, HIGH); + #endif // SET_SPI_SS_HIGH + // set SCK rate for initialization commands + spiRate_ = SPI_SD_INIT_RATE; + spiInit(spiRate_); + #endif // SOFTWARE_SPI + + // must supply min of 74 clock cycles with CS high. + for (uint8_t i = 0; i < 10; i++) spiSend(0XFF); + + // command to go idle in SPI mode + while ((status_ = cardCommand(CMD0, 0)) != R1_IDLE_STATE) { + if (((uint16_t)millis() - t0) > SD_INIT_TIMEOUT) { + error(SD_CARD_ERROR_CMD0); + goto fail; + } + } + // check SD version + if ((cardCommand(CMD8, 0x1AA) & R1_ILLEGAL_COMMAND)) { + type(SD_CARD_TYPE_SD1); + } + else { + // only need last byte of r7 response + for (uint8_t i = 0; i < 4; i++) status_ = spiRec(); + if (status_ != 0XAA) { + error(SD_CARD_ERROR_CMD8); + goto fail; + } + type(SD_CARD_TYPE_SD2); + } + // initialize card and send host supports SDHC if SD2 + arg = type() == SD_CARD_TYPE_SD2 ? 0X40000000 : 0; + + while ((status_ = cardAcmd(ACMD41, arg)) != R1_READY_STATE) { + // check for timeout + if (((uint16_t)millis() - t0) > SD_INIT_TIMEOUT) { + error(SD_CARD_ERROR_ACMD41); + goto fail; + } + } + // if SD2 read OCR register to check for SDHC card + if (type() == SD_CARD_TYPE_SD2) { + if (cardCommand(CMD58, 0)) { + error(SD_CARD_ERROR_CMD58); + goto fail; + } + 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(); + } + chipSelectHigh(); + + #if DISABLED(SOFTWARE_SPI) + return setSckRate(sckRateID); + #else // SOFTWARE_SPI + UNUSED(sckRateID); + return true; + #endif // SOFTWARE_SPI + +fail: + chipSelectHigh(); + return false; +} +//------------------------------------------------------------------------------ +/** + * Read a 512 byte block from an SD card. + * + * \param[in] blockNumber Logical block to be read. + * \param[out] dst Pointer to the location that will receive the data. + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool Sd2Card::readBlock(uint32_t blockNumber, uint8_t* dst) { + // use address if not SDHC card + if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9; + + #if ENABLED(SD_CHECK_AND_RETRY) + uint8_t retryCnt = 3; + do { + if (!cardCommand(CMD17, blockNumber)) { + if (readData(dst, 512)) return true; + } + else + error(SD_CARD_ERROR_CMD17); + + if (--retryCnt) break; + + chipSelectHigh(); + cardCommand(CMD12, 0); // Try sending a stop command, ignore the result. + errorCode_ = 0; + } while (true); + #else + if (cardCommand(CMD17, blockNumber)) + error(SD_CARD_ERROR_CMD17); + else + return readData(dst, 512); + #endif + + chipSelectHigh(); + return false; +} +//------------------------------------------------------------------------------ +/** Read one data block in a multiple block read sequence + * + * \param[in] dst Pointer to the location for the data to be read. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool Sd2Card::readData(uint8_t* dst) { + chipSelectLow(); + return readData(dst, 512); +} + +#if ENABLED(SD_CHECK_AND_RETRY) +static const uint16_t crctab[] PROGMEM = { + 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, + 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF, + 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6, + 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE, + 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485, + 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D, + 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4, + 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC, + 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823, + 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B, + 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12, + 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A, + 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41, + 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49, + 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70, + 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78, + 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F, + 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067, + 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E, + 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256, + 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D, + 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, + 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C, + 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634, + 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB, + 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3, + 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A, + 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92, + 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9, + 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1, + 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8, + 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0 +}; +static uint16_t CRC_CCITT(const uint8_t* data, size_t n) { + uint16_t crc = 0; + for (size_t i = 0; i < n; i++) { + crc = pgm_read_word(&crctab[(crc >> 8 ^ data[i]) & 0XFF]) ^ (crc << 8); + } + return crc; +} +#endif + +//------------------------------------------------------------------------------ +bool Sd2Card::readData(uint8_t* dst, uint16_t count) { + // wait for start block token + uint16_t t0 = millis(); + while ((status_ = spiRec()) == 0XFF) { + if (((uint16_t)millis() - t0) > SD_READ_TIMEOUT) { + error(SD_CARD_ERROR_READ_TIMEOUT); + goto fail; + } + } + if (status_ != DATA_START_BLOCK) { + error(SD_CARD_ERROR_READ); + goto fail; + } + // transfer data + spiRead(dst, count); + +#if ENABLED(SD_CHECK_AND_RETRY) + { + uint16_t calcCrc = CRC_CCITT(dst, count); + uint16_t recvCrc = spiRec() << 8; + recvCrc |= spiRec(); + if (calcCrc != recvCrc) { + error(SD_CARD_ERROR_CRC); + goto fail; + } + } +#else + // discard CRC + spiRec(); + spiRec(); +#endif + chipSelectHigh(); + // Send an additional dummy byte, required by Toshiba Flash Air SD Card + spiSend(0XFF); + return true; +fail: + chipSelectHigh(); + // Send an additional dummy byte, required by Toshiba Flash Air SD Card + spiSend(0XFF); + return false; +} +//------------------------------------------------------------------------------ +/** read CID or CSR register */ +bool Sd2Card::readRegister(uint8_t cmd, void* buf) { + uint8_t* dst = reinterpret_cast(buf); + if (cardCommand(cmd, 0)) { + error(SD_CARD_ERROR_READ_REG); + goto fail; + } + return readData(dst, 16); +fail: + chipSelectHigh(); + return false; +} +//------------------------------------------------------------------------------ +/** Start a read multiple blocks sequence. + * + * \param[in] blockNumber Address of first block in sequence. + * + * \note This function is used with readData() and readStop() for optimized + * multiple block reads. SPI chipSelect must be low for the entire sequence. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool Sd2Card::readStart(uint32_t blockNumber) { + if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9; + if (cardCommand(CMD18, blockNumber)) { + error(SD_CARD_ERROR_CMD18); + goto fail; + } + chipSelectHigh(); + return true; +fail: + chipSelectHigh(); + return false; +} +//------------------------------------------------------------------------------ +/** End a read multiple blocks sequence. + * +* \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool Sd2Card::readStop() { + chipSelectLow(); + if (cardCommand(CMD12, 0)) { + error(SD_CARD_ERROR_CMD12); + goto fail; + } + chipSelectHigh(); + return true; +fail: + chipSelectHigh(); + return false; +} +//------------------------------------------------------------------------------ +/** + * Set the SPI clock rate. + * + * \param[in] sckRateID A value in the range [0, 6]. + * + * The SPI clock will be set to F_CPU/pow(2, 1 + sckRateID). The maximum + * SPI rate is F_CPU/2 for \a sckRateID = 0 and the minimum rate is F_CPU/128 + * for \a scsRateID = 6. + * + * \return The value one, true, is returned for success and the value zero, + * false, is returned for an invalid value of \a sckRateID. + */ +bool Sd2Card::setSckRate(uint8_t sckRateID) { + if (sckRateID > 6) { + error(SD_CARD_ERROR_SCK_RATE); + return false; + } + spiRate_ = sckRateID; + return true; +} +//------------------------------------------------------------------------------ +// wait for card to go not busy +bool Sd2Card::waitNotBusy(uint16_t timeoutMillis) { + uint16_t t0 = millis(); + while (spiRec() != 0XFF) { + if (((uint16_t)millis() - t0) >= timeoutMillis) goto fail; + } + return true; +fail: + return false; +} +//------------------------------------------------------------------------------ +/** + * Writes a 512 byte block to an SD card. + * + * \param[in] blockNumber Logical block to be written. + * \param[in] src Pointer to the location of the data to be written. + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool Sd2Card::writeBlock(uint32_t blockNumber, const uint8_t* src) { + // use address if not SDHC card + if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9; + if (cardCommand(CMD24, blockNumber)) { + error(SD_CARD_ERROR_CMD24); + goto fail; + } + if (!writeData(DATA_START_BLOCK, src)) goto fail; + + // wait for flash programming to complete + if (!waitNotBusy(SD_WRITE_TIMEOUT)) { + error(SD_CARD_ERROR_WRITE_TIMEOUT); + goto fail; + } + // response is r2 so get and check two bytes for nonzero + if (cardCommand(CMD13, 0) || spiRec()) { + error(SD_CARD_ERROR_WRITE_PROGRAMMING); + goto fail; + } + chipSelectHigh(); + return true; +fail: + chipSelectHigh(); + return false; +} +//------------------------------------------------------------------------------ +/** Write one data block in a multiple block write sequence + * \param[in] src Pointer to the location of the data to be written. + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool Sd2Card::writeData(const uint8_t* src) { + chipSelectLow(); + // wait for previous write to finish + if (!waitNotBusy(SD_WRITE_TIMEOUT)) goto fail; + if (!writeData(WRITE_MULTIPLE_TOKEN, src)) goto fail; + chipSelectHigh(); + return true; +fail: + error(SD_CARD_ERROR_WRITE_MULTIPLE); + chipSelectHigh(); + return false; +} +//------------------------------------------------------------------------------ +// send one block of data for write block or write multiple blocks +bool Sd2Card::writeData(uint8_t token, const uint8_t* src) { + spiSendBlock(token, src); + + spiSend(0xff); // dummy crc + spiSend(0xff); // dummy crc + + status_ = spiRec(); + if ((status_ & DATA_RES_MASK) != DATA_RES_ACCEPTED) { + error(SD_CARD_ERROR_WRITE); + goto fail; + } + return true; +fail: + chipSelectHigh(); + return false; +} +//------------------------------------------------------------------------------ +/** Start a write multiple blocks sequence. + * + * \param[in] blockNumber Address of first block in sequence. + * \param[in] eraseCount The number of blocks to be pre-erased. + * + * \note This function is used with writeData() and writeStop() + * for optimized multiple block writes. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool Sd2Card::writeStart(uint32_t blockNumber, uint32_t eraseCount) { + // send pre-erase count + if (cardAcmd(ACMD23, eraseCount)) { + error(SD_CARD_ERROR_ACMD23); + goto fail; + } + // use address if not SDHC card + if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9; + if (cardCommand(CMD25, blockNumber)) { + error(SD_CARD_ERROR_CMD25); + goto fail; + } + chipSelectHigh(); + return true; +fail: + chipSelectHigh(); + return false; +} +//------------------------------------------------------------------------------ +/** End a write multiple blocks sequence. + * +* \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool Sd2Card::writeStop() { + chipSelectLow(); + if (!waitNotBusy(SD_WRITE_TIMEOUT)) goto fail; + spiSend(STOP_TRAN_TOKEN); + if (!waitNotBusy(SD_WRITE_TIMEOUT)) goto fail; + chipSelectHigh(); + return true; +fail: + error(SD_CARD_ERROR_STOP_TRAN); + chipSelectHigh(); + return false; +} + +#endif diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/Sd2Card.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/Sd2Card.h new file mode 100644 index 00000000..b1f442c4 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/Sd2Card.h @@ -0,0 +1,251 @@ +/** + * 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 . + * + */ + +/** + * Arduino Sd2Card Library + * Copyright (C) 2009 by William Greiman + * + * This file is part of the Arduino Sd2Card Library + */ + +#include "Marlin.h" +#if ENABLED(SDSUPPORT) + +#ifndef Sd2Card_h +#define Sd2Card_h +/** + * \file + * \brief Sd2Card class for V2 SD/SDHC cards + */ +#include "SdFatConfig.h" +#include "SdInfo.h" +//------------------------------------------------------------------------------ +// SPI speed is F_CPU/2^(1 + index), 0 <= index <= 6 +/** Set SCK to max rate of F_CPU/2. See Sd2Card::setSckRate(). */ +uint8_t const SPI_FULL_SPEED = 0; +/** Set SCK rate to F_CPU/4. See Sd2Card::setSckRate(). */ +uint8_t const SPI_HALF_SPEED = 1; +/** Set SCK rate to F_CPU/8. See Sd2Card::setSckRate(). */ +uint8_t const SPI_QUARTER_SPEED = 2; +/** Set SCK rate to F_CPU/16. See Sd2Card::setSckRate(). */ +uint8_t const SPI_EIGHTH_SPEED = 3; +/** Set SCK rate to F_CPU/32. See Sd2Card::setSckRate(). */ +uint8_t const SPI_SIXTEENTH_SPEED = 4; +//------------------------------------------------------------------------------ +/** init timeout ms */ +uint16_t const SD_INIT_TIMEOUT = 2000; +/** erase timeout ms */ +uint16_t const SD_ERASE_TIMEOUT = 10000; +/** read timeout ms */ +uint16_t const SD_READ_TIMEOUT = 300; +/** write time out ms */ +uint16_t const SD_WRITE_TIMEOUT = 600; +//------------------------------------------------------------------------------ +// SD card errors +/** timeout error for command CMD0 (initialize card in SPI mode) */ +uint8_t const SD_CARD_ERROR_CMD0 = 0X1; +/** CMD8 was not accepted - not a valid SD card*/ +uint8_t const SD_CARD_ERROR_CMD8 = 0X2; +/** card returned an error response for CMD12 (write stop) */ +uint8_t const SD_CARD_ERROR_CMD12 = 0X3; +/** card returned an error response for CMD17 (read block) */ +uint8_t const SD_CARD_ERROR_CMD17 = 0X4; +/** card returned an error response for CMD18 (read multiple block) */ +uint8_t const SD_CARD_ERROR_CMD18 = 0X5; +/** card returned an error response for CMD24 (write block) */ +uint8_t const SD_CARD_ERROR_CMD24 = 0X6; +/** WRITE_MULTIPLE_BLOCKS command failed */ +uint8_t const SD_CARD_ERROR_CMD25 = 0X7; +/** card returned an error response for CMD58 (read OCR) */ +uint8_t const SD_CARD_ERROR_CMD58 = 0X8; +/** SET_WR_BLK_ERASE_COUNT failed */ +uint8_t const SD_CARD_ERROR_ACMD23 = 0X9; +/** ACMD41 initialization process timeout */ +uint8_t const SD_CARD_ERROR_ACMD41 = 0XA; +/** card returned a bad CSR version field */ +uint8_t const SD_CARD_ERROR_BAD_CSD = 0XB; +/** erase block group command failed */ +uint8_t const SD_CARD_ERROR_ERASE = 0XC; +/** card not capable of single block erase */ +uint8_t const SD_CARD_ERROR_ERASE_SINGLE_BLOCK = 0XD; +/** Erase sequence timed out */ +uint8_t const SD_CARD_ERROR_ERASE_TIMEOUT = 0XE; +/** card returned an error token instead of read data */ +uint8_t const SD_CARD_ERROR_READ = 0XF; +/** read CID or CSD failed */ +uint8_t const SD_CARD_ERROR_READ_REG = 0X10; +/** timeout while waiting for start of read data */ +uint8_t const SD_CARD_ERROR_READ_TIMEOUT = 0X11; +/** card did not accept STOP_TRAN_TOKEN */ +uint8_t const SD_CARD_ERROR_STOP_TRAN = 0X12; +/** card returned an error token as a response to a write operation */ +uint8_t const SD_CARD_ERROR_WRITE = 0X13; +/** attempt to write protected block zero */ +uint8_t const SD_CARD_ERROR_WRITE_BLOCK_ZERO = 0X14; // REMOVE - not used +/** card did not go ready for a multiple block write */ +uint8_t const SD_CARD_ERROR_WRITE_MULTIPLE = 0X15; +/** card returned an error to a CMD13 status check after a write */ +uint8_t const SD_CARD_ERROR_WRITE_PROGRAMMING = 0X16; +/** timeout occurred during write programming */ +uint8_t const SD_CARD_ERROR_WRITE_TIMEOUT = 0X17; +/** incorrect rate selected */ +uint8_t const SD_CARD_ERROR_SCK_RATE = 0X18; +/** init() not called */ +uint8_t const SD_CARD_ERROR_INIT_NOT_CALLED = 0X19; +/** crc check error */ +uint8_t const SD_CARD_ERROR_CRC = 0X20; +//------------------------------------------------------------------------------ +// card types +/** Standard capacity V1 SD card */ +uint8_t const SD_CARD_TYPE_SD1 = 1; +/** Standard capacity V2 SD card */ +uint8_t const SD_CARD_TYPE_SD2 = 2; +/** High Capacity SD card */ +uint8_t const SD_CARD_TYPE_SDHC = 3; +/** + * define SOFTWARE_SPI to use bit-bang SPI + */ +//------------------------------------------------------------------------------ +#if MEGA_SOFT_SPI && (defined(__AVR_ATmega1280__)||defined(__AVR_ATmega2560__)) + #define SOFTWARE_SPI +#elif USE_SOFTWARE_SPI + #define SOFTWARE_SPI +#endif // MEGA_SOFT_SPI +//------------------------------------------------------------------------------ +// SPI pin definitions - do not edit here - change in SdFatConfig.h +// +#if DISABLED(SOFTWARE_SPI) + // hardware pin defs + /** The default chip select pin for the SD card is SS. */ + #define SD_CHIP_SELECT_PIN SS_PIN + // The following three pins must not be redefined for hardware SPI. + /** SPI Master Out Slave In pin */ + #define SPI_MOSI_PIN MOSI_PIN + /** SPI Master In Slave Out pin */ + #define SPI_MISO_PIN MISO_PIN + /** SPI Clock pin */ + #define SPI_SCK_PIN SCK_PIN + +#else // SOFTWARE_SPI + + /** SPI chip select pin */ + #define SD_CHIP_SELECT_PIN SOFT_SPI_CS_PIN + /** SPI Master Out Slave In pin */ + #define SPI_MOSI_PIN SOFT_SPI_MOSI_PIN + /** SPI Master In Slave Out pin */ + #define SPI_MISO_PIN SOFT_SPI_MISO_PIN + /** SPI Clock pin */ + #define SPI_SCK_PIN SOFT_SPI_SCK_PIN +#endif // SOFTWARE_SPI +//------------------------------------------------------------------------------ +/** + * \class Sd2Card + * \brief Raw access to SD and SDHC flash memory cards. + */ +class Sd2Card { + public: + /** Construct an instance of Sd2Card. */ + Sd2Card() : errorCode_(SD_CARD_ERROR_INIT_NOT_CALLED), type_(0) {} + uint32_t cardSize(); + bool erase(uint32_t firstBlock, uint32_t lastBlock); + bool eraseSingleBlockEnable(); + /** + * Set SD error code. + * \param[in] code value for error code. + */ + void error(uint8_t code) {errorCode_ = code;} + /** + * \return error code for last error. See Sd2Card.h for a list of error codes. + */ + int errorCode() const {return errorCode_;} + /** \return error data for last error. */ + int errorData() const {return status_;} + /** + * Initialize an SD flash memory card with default clock rate and chip + * select pin. See sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin). + * + * \return true for success or false for failure. + */ + bool init(uint8_t sckRateID = SPI_FULL_SPEED, + uint8_t chipSelectPin = SD_CHIP_SELECT_PIN); + bool readBlock(uint32_t block, uint8_t* dst); + /** + * Read a card's CID register. The CID contains card identification + * information such as Manufacturer ID, Product name, Product serial + * number and Manufacturing date. + * + * \param[out] cid pointer to area for returned data. + * + * \return true for success or false for failure. + */ + bool readCID(cid_t* cid) { + return readRegister(CMD10, cid); + } + /** + * Read a card's CSD register. The CSD contains Card-Specific Data that + * provides information regarding access to the card's contents. + * + * \param[out] csd pointer to area for returned data. + * + * \return true for success or false for failure. + */ + bool readCSD(csd_t* csd) { + return readRegister(CMD9, csd); + } + bool readData(uint8_t* dst); + bool readStart(uint32_t blockNumber); + bool readStop(); + bool setSckRate(uint8_t sckRateID); + /** Return the card type: SD V1, SD V2 or SDHC + * \return 0 - SD V1, 1 - SD V2, or 3 - SDHC. + */ + int type() const {return type_;} + bool writeBlock(uint32_t blockNumber, const uint8_t* src); + bool writeData(const uint8_t* src); + bool writeStart(uint32_t blockNumber, uint32_t eraseCount); + bool writeStop(); + private: + //---------------------------------------------------------------------------- + uint8_t chipSelectPin_; + uint8_t errorCode_; + uint8_t spiRate_; + uint8_t status_; + uint8_t type_; + // private functions + uint8_t cardAcmd(uint8_t cmd, uint32_t arg) { + cardCommand(CMD55, 0); + return cardCommand(cmd, arg); + } + uint8_t cardCommand(uint8_t cmd, uint32_t arg); + + bool readData(uint8_t* dst, uint16_t count); + bool readRegister(uint8_t cmd, void* buf); + void chipSelectHigh(); + void chipSelectLow(); + void type(uint8_t value) {type_ = value;} + bool waitNotBusy(uint16_t timeoutMillis); + bool writeData(uint8_t token, const uint8_t* src); +}; +#endif // Sd2Card_h + + +#endif diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/SdBaseFile.cpp b/trunk/Arduino/Marlin_K8600_1.1.0RC7/SdBaseFile.cpp new file mode 100644 index 00000000..95765f9c --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/SdBaseFile.cpp @@ -0,0 +1,1826 @@ +/** + * 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 . + * + */ + +/** + * Arduino SdFat Library + * Copyright (C) 2009 by William Greiman + * + * This file is part of the Arduino Sd2Card Library + */ + +#include "Marlin.h" +#if ENABLED(SDSUPPORT) + +#include "SdBaseFile.h" +//------------------------------------------------------------------------------ +// pointer to cwd directory +SdBaseFile* SdBaseFile::cwd_ = 0; +// callback function for date/time +void (*SdBaseFile::dateTime_)(uint16_t* date, uint16_t* time) = 0; +//------------------------------------------------------------------------------ +// add a cluster to a file +bool SdBaseFile::addCluster() { + if (!vol_->allocContiguous(1, &curCluster_)) goto fail; + + // if first cluster of file link to directory entry + if (firstCluster_ == 0) { + firstCluster_ = curCluster_; + flags_ |= F_FILE_DIR_DIRTY; + } + return true; + + fail: + return false; +} +//------------------------------------------------------------------------------ +// Add a cluster to a directory file and zero the cluster. +// return with first block of cluster in the cache +bool SdBaseFile::addDirCluster() { + uint32_t block; + // max folder size + if (fileSize_ / sizeof(dir_t) >= 0XFFFF) goto fail; + + if (!addCluster()) goto fail; + if (!vol_->cacheFlush()) goto fail; + + block = vol_->clusterStartBlock(curCluster_); + + // set cache to first block of cluster + vol_->cacheSetBlockNumber(block, true); + + // zero first block of cluster + memset(vol_->cacheBuffer_.data, 0, 512); + + // zero rest of cluster + for (uint8_t i = 1; i < vol_->blocksPerCluster_; i++) { + if (!vol_->writeBlock(block + i, vol_->cacheBuffer_.data)) goto fail; + } + // Increase directory file size by cluster size + fileSize_ += 512UL << vol_->clusterSizeShift_; + return true; +fail: + return false; +} +//------------------------------------------------------------------------------ +// cache a file's directory entry +// return pointer to cached entry or null for failure +dir_t* SdBaseFile::cacheDirEntry(uint8_t action) { + if (!vol_->cacheRawBlock(dirBlock_, action)) goto fail; + return vol_->cache()->dir + dirIndex_; +fail: + return 0; +} +//------------------------------------------------------------------------------ +/** Close a file and force cached data and directory information + * to be written to the storage device. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include no file is open or an I/O error. + */ +bool SdBaseFile::close() { + bool rtn = sync(); + type_ = FAT_FILE_TYPE_CLOSED; + return rtn; +} +//------------------------------------------------------------------------------ +/** Check for contiguous file and return its raw block range. + * + * \param[out] bgnBlock the first block address for the file. + * \param[out] endBlock the last block address for the file. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include file is not contiguous, file has zero length + * or an I/O error occurred. + */ +bool SdBaseFile::contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock) { + // error if no blocks + if (firstCluster_ == 0) goto fail; + + for (uint32_t c = firstCluster_; ; c++) { + uint32_t next; + if (!vol_->fatGet(c, &next)) goto fail; + + // check for contiguous + if (next != (c + 1)) { + // error if not end of chain + if (!vol_->isEOC(next)) goto fail; + *bgnBlock = vol_->clusterStartBlock(firstCluster_); + *endBlock = vol_->clusterStartBlock(c) + + vol_->blocksPerCluster_ - 1; + return true; + } + } + +fail: + return false; +} +//------------------------------------------------------------------------------ +/** Create and open a new contiguous file of a specified size. + * + * \note This function only supports short DOS 8.3 names. + * See open() for more information. + * + * \param[in] dirFile The directory where the file will be created. + * \param[in] path A path with a valid DOS 8.3 file name. + * \param[in] size The desired file size. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include \a path contains + * 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) { + uint32_t count; + // don't allow zero length file + if (size == 0) goto fail; + if (!open(dirFile, path, O_CREAT | O_EXCL | O_RDWR)) goto fail; + + // calculate number of clusters needed + count = ((size - 1) >> (vol_->clusterSizeShift_ + 9)) + 1; + + // allocate clusters + if (!vol_->allocContiguous(count, &firstCluster_)) { + remove(); + goto fail; + } + fileSize_ = size; + + // insure sync() will update dir entry + flags_ |= F_FILE_DIR_DIRTY; + + return sync(); +fail: + return false; +} +//------------------------------------------------------------------------------ +/** Return a file's directory entry. + * + * \param[out] dir Location for return of the file's directory entry. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool SdBaseFile::dirEntry(dir_t* dir) { + dir_t* p; + // make sure fields on SD are correct + if (!sync()) goto fail; + + // read entry + p = cacheDirEntry(SdVolume::CACHE_FOR_READ); + if (!p) goto fail; + + // copy to caller's struct + memcpy(dir, p, sizeof(dir_t)); + return true; +fail: + return false; +} +//------------------------------------------------------------------------------ +/** Format the name field of \a dir into the 13 byte array + * \a name in standard 8.3 short name format. + * + * \param[in] dir The directory structure containing the name. + * \param[out] name A 13 byte char array for the formatted name. + */ +void SdBaseFile::dirName(const dir_t& dir, char* name) { + uint8_t j = 0; + for (uint8_t i = 0; i < 11; i++) { + if (dir.name[i] == ' ')continue; + if (i == 8) name[j++] = '.'; + name[j++] = dir.name[i]; + } + name[j] = 0; +} +//------------------------------------------------------------------------------ +/** Test for the existence of a file in a directory + * + * \param[in] name Name of the file to be tested for. + * + * The calling instance must be an open directory file. + * + * dirFile.exists("TOFIND.TXT") searches for "TOFIND.TXT" in the directory + * dirFile. + * + * \return true if the file exists else false. + */ +bool SdBaseFile::exists(const char* name) { + SdBaseFile file; + return file.open(this, name, O_READ); +} +//------------------------------------------------------------------------------ +/** + * Get a string from a file. + * + * fgets() reads bytes from a file into the array pointed to by \a str, until + * \a num - 1 bytes are read, or a delimiter is read and transferred to \a str, + * or end-of-file is encountered. The string is then terminated + * with a null byte. + * + * fgets() deletes CR, '\\r', from the string. This insures only a '\\n' + * terminates the string for Windows text files which use CRLF for newline. + * + * \param[out] str Pointer to the array where the string is stored. + * \param[in] num Maximum number of characters to be read + * (including the final null byte). Usually the length + * of the array \a str is used. + * \param[in] delim Optional set of delimiters. The default is "\n". + * + * \return For success fgets() returns the length of the string in \a str. + * If no data is read, fgets() returns zero for EOF or -1 if an error occurred. + **/ +int16_t SdBaseFile::fgets(char* str, int16_t num, char* delim) { + char ch; + int16_t n = 0; + int16_t r = -1; + while ((n + 1) < num && (r = read(&ch, 1)) == 1) { + // delete CR + if (ch == '\r') continue; + str[n++] = ch; + if (!delim) { + if (ch == '\n') break; + } + else { + if (strchr(delim, ch)) break; + } + } + if (r < 0) { + // read error + return -1; + } + str[n] = '\0'; + return n; +} +//------------------------------------------------------------------------------ +/** Get a file's name + * + * \param[out] name An array of 13 characters for the file's name. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool SdBaseFile::getFilename(char* name) { + if (!isOpen()) return false; + + if (isRoot()) { + name[0] = '/'; + name[1] = '\0'; + return true; + } + // cache entry + dir_t* p = cacheDirEntry(SdVolume::CACHE_FOR_READ); + if (!p) return false; + + // format name + dirName(*p, name); + return true; +} +//------------------------------------------------------------------------------ +void SdBaseFile::getpos(filepos_t* pos) { + pos->position = curPosition_; + pos->cluster = curCluster_; +} + +//------------------------------------------------------------------------------ +/** List directory contents. + * + * \param[in] pr Print stream for list. + * + * \param[in] flags The inclusive OR of + * + * LS_DATE - %Print file modification date + * + * LS_SIZE - %Print file size. + * + * LS_R - Recursive list of subdirectories. + * + * \param[in] indent Amount of space before file name. Used for recursive + * list to indicate subdirectory level. + */ +void SdBaseFile::ls(uint8_t flags, uint8_t indent) { + rewind(); + int8_t status; + while ((status = lsPrintNext(flags, indent))) { + if (status > 1 && (flags & LS_R)) { + uint16_t index = curPosition() / 32 - 1; + SdBaseFile s; + if (s.open(this, index, O_READ)) s.ls(flags, indent + 2); + seekSet(32 * (index + 1)); + } + } +} +//------------------------------------------------------------------------------ +// saves 32 bytes on stack for ls recursion +// return 0 - EOF, 1 - normal file, or 2 - directory +int8_t SdBaseFile::lsPrintNext(uint8_t flags, uint8_t indent) { + dir_t dir; + uint8_t w = 0; + + while (1) { + if (read(&dir, sizeof(dir)) != sizeof(dir)) return 0; + if (dir.name[0] == DIR_NAME_FREE) return 0; + + // skip deleted entry and entries for . and .. + if (dir.name[0] != DIR_NAME_DELETED && dir.name[0] != '.' + && DIR_IS_FILE_OR_SUBDIR(&dir)) break; + } + // indent for dir level + for (uint8_t i = 0; i < indent; i++) MYSERIAL.write(' '); + + // print name + for (uint8_t i = 0; i < 11; i++) { + if (dir.name[i] == ' ')continue; + if (i == 8) { + MYSERIAL.write('.'); + w++; + } + MYSERIAL.write(dir.name[i]); + w++; + } + if (DIR_IS_SUBDIR(&dir)) { + MYSERIAL.write('/'); + w++; + } + if (flags & (LS_DATE | LS_SIZE)) { + while (w++ < 14) MYSERIAL.write(' '); + } + // print modify date/time if requested + if (flags & LS_DATE) { + MYSERIAL.write(' '); + printFatDate(dir.lastWriteDate); + MYSERIAL.write(' '); + printFatTime(dir.lastWriteTime); + } + // print size if requested + if (!DIR_IS_SUBDIR(&dir) && (flags & LS_SIZE)) { + MYSERIAL.write(' '); + MYSERIAL.print(dir.fileSize); + } + MYSERIAL.println(); + return DIR_IS_FILE(&dir) ? 1 : 2; +} +//------------------------------------------------------------------------------ +// format directory name field from a 8.3 name string +bool SdBaseFile::make83Name(const char* str, uint8_t* name, const char** ptr) { + uint8_t c; + uint8_t n = 7; // max index for part before dot + uint8_t i = 0; + // blank fill name and extension + while (i < 11) name[i++] = ' '; + i = 0; + while (*str != '\0' && *str != '/') { + c = *str++; + if (c == '.') { + if (n == 10) goto fail; // only one dot allowed + n = 10; // max index for full 8.3 name + i = 8; // place for extension + } + else { + // illegal FAT characters + PGM_P p = PSTR("|<>^+=?/[];,*\"\\"); + uint8_t b; + while ((b = pgm_read_byte(p++))) if (b == c) goto fail; + // check size and only allow ASCII printable characters + if (i > n || c < 0x21 || c == 0x7F) goto fail; + // only upper case allowed in 8.3 names - convert lower to upper + name[i++] = (c < 'a' || c > 'z') ? (c) : (c + ('A' - 'a')); + } + } + *ptr = str; + // must have a file name, extension is optional + return name[0] != ' '; +fail: + return false; +} +//------------------------------------------------------------------------------ +/** Make a new directory. + * + * \param[in] parent An open SdFat instance for the directory that will contain + * the new directory. + * + * \param[in] path A path with a valid 8.3 DOS name for the new directory. + * + * \param[in] pFlag Create missing parent directories if true. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include this file is already open, \a parent is not a + * directory, \a path is invalid or already exists in \a parent. + */ +bool SdBaseFile::mkdir(SdBaseFile* parent, const char* path, bool pFlag) { + uint8_t dname[11]; + SdBaseFile dir1, dir2; + SdBaseFile* sub = &dir1; + SdBaseFile* start = parent; + + if (!parent || isOpen()) goto fail; + + if (*path == '/') { + while (*path == '/') path++; + if (!parent->isRoot()) { + if (!dir2.openRoot(parent->vol_)) goto fail; + parent = &dir2; + } + } + while (1) { + if (!make83Name(path, dname, &path)) goto fail; + while (*path == '/') path++; + if (!*path) break; + if (!sub->open(parent, dname, O_READ)) { + if (!pFlag || !sub->mkdir(parent, dname)) { + goto fail; + } + } + if (parent != start) parent->close(); + parent = sub; + sub = parent != &dir1 ? &dir1 : &dir2; + } + return mkdir(parent, dname); +fail: + return false; +} +//------------------------------------------------------------------------------ +bool SdBaseFile::mkdir(SdBaseFile* parent, const uint8_t dname[11]) { + uint32_t block; + dir_t d; + dir_t* p; + + if (!parent->isDir()) goto fail; + + // create a normal file + if (!open(parent, dname, O_CREAT | O_EXCL | O_RDWR)) goto fail; + + // convert file to directory + flags_ = O_READ; + type_ = FAT_FILE_TYPE_SUBDIR; + + // allocate and zero first cluster + if (!addDirCluster())goto fail; + + // force entry to SD + if (!sync()) goto fail; + + // cache entry - should already be in cache due to sync() call + p = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); + if (!p) goto fail; + + // change directory entry attribute + p->attributes = DIR_ATT_DIRECTORY; + + // make entry for '.' + memcpy(&d, p, sizeof(d)); + d.name[0] = '.'; + for (uint8_t i = 1; i < 11; i++) d.name[i] = ' '; + + // cache block for '.' and '..' + block = vol_->clusterStartBlock(firstCluster_); + if (!vol_->cacheRawBlock(block, SdVolume::CACHE_FOR_WRITE)) goto fail; + + // copy '.' to block + memcpy(&vol_->cache()->dir[0], &d, sizeof(d)); + + // make entry for '..' + d.name[1] = '.'; + if (parent->isRoot()) { + d.firstClusterLow = 0; + d.firstClusterHigh = 0; + } + else { + d.firstClusterLow = parent->firstCluster_ & 0XFFFF; + d.firstClusterHigh = parent->firstCluster_ >> 16; + } + // copy '..' to block + memcpy(&vol_->cache()->dir[1], &d, sizeof(d)); + + // write first block + return vol_->cacheFlush(); +fail: + return false; +} +//------------------------------------------------------------------------------ +/** Open a file in the current working directory. + * + * \param[in] path A path with a valid 8.3 DOS name for a file to be opened. + * + * \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive + * OR of open flags. see SdBaseFile::open(SdBaseFile*, const char*, uint8_t). + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool SdBaseFile::open(const char* path, uint8_t oflag) { + return open(cwd_, path, oflag); +} +//------------------------------------------------------------------------------ +/** Open a file or directory by name. + * + * \param[in] dirFile An open SdFat instance for the directory containing the + * file to be opened. + * + * \param[in] path A path with a valid 8.3 DOS name for a file to be opened. + * + * \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive + * OR of flags from the following list + * + * O_READ - Open for reading. + * + * O_RDONLY - Same as O_READ. + * + * O_WRITE - Open for writing. + * + * O_WRONLY - Same as O_WRITE. + * + * O_RDWR - Open for reading and writing. + * + * O_APPEND - If set, the file offset shall be set to the end of the + * file prior to each write. + * + * O_AT_END - Set the initial position at the end of the file. + * + * O_CREAT - If the file exists, this flag has no effect except as noted + * under O_EXCL below. Otherwise, the file shall be created + * + * O_EXCL - If O_CREAT and O_EXCL are set, open() shall fail if the file exists. + * + * O_SYNC - Call sync() after each write. This flag should not be used with + * write(uint8_t), write_P(PGM_P), writeln_P(PGM_P), or the Arduino Print class. + * These functions do character at a time writes so sync() will be called + * after each byte. + * + * O_TRUNC - If the file exists and is a regular file, and the file is + * successfully opened and is not read only, its length shall be truncated to 0. + * + * WARNING: A given file must not be opened by more than one SdBaseFile object + * of file corruption may occur. + * + * \note Directory files must be opened read only. Write and truncation is + * not allowed for directory files. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include this file is already open, \a dirFile is not + * a directory, \a path is invalid, the file does not exist + * or can't be opened in the access mode specified by oflag. + */ +bool SdBaseFile::open(SdBaseFile* dirFile, const char* path, uint8_t oflag) { + uint8_t dname[11]; + SdBaseFile dir1, dir2; + SdBaseFile* parent = dirFile; + SdBaseFile* sub = &dir1; + + if (!dirFile) goto fail; + + // error if already open + if (isOpen()) goto fail; + + if (*path == '/') { + while (*path == '/') path++; + if (!dirFile->isRoot()) { + if (!dir2.openRoot(dirFile->vol_)) goto fail; + parent = &dir2; + } + } + while (1) { + if (!make83Name(path, dname, &path)) goto fail; + while (*path == '/') path++; + if (!*path) break; + if (!sub->open(parent, dname, O_READ)) goto fail; + if (parent != dirFile) parent->close(); + parent = sub; + sub = parent != &dir1 ? &dir1 : &dir2; + } + return open(parent, dname, oflag); +fail: + return false; +} +//------------------------------------------------------------------------------ +// open with filename in dname +bool SdBaseFile::open(SdBaseFile* dirFile, + const uint8_t dname[11], uint8_t oflag) { + bool emptyFound = false; + bool fileFound = false; + uint8_t index; + dir_t* p; + + vol_ = dirFile->vol_; + + dirFile->rewind(); + // search for file + + while (dirFile->curPosition_ < dirFile->fileSize_) { + index = 0XF & (dirFile->curPosition_ >> 5); + p = dirFile->readDirCache(); + if (!p) goto fail; + + if (p->name[0] == DIR_NAME_FREE || p->name[0] == DIR_NAME_DELETED) { + // remember first empty slot + if (!emptyFound) { + dirBlock_ = dirFile->vol_->cacheBlockNumber(); + dirIndex_ = index; + emptyFound = true; + } + // done if no entries follow + if (p->name[0] == DIR_NAME_FREE) break; + } + else if (!memcmp(dname, p->name, 11)) { + fileFound = true; + break; + } + } + if (fileFound) { + // don't open existing file if O_EXCL + if (oflag & O_EXCL) goto fail; + } + else { + // don't create unless O_CREAT and O_WRITE + if (!(oflag & O_CREAT) || !(oflag & O_WRITE)) goto fail; + if (emptyFound) { + index = dirIndex_; + p = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); + if (!p) goto fail; + } + else { + if (dirFile->type_ == FAT_FILE_TYPE_ROOT_FIXED) goto fail; + + // add and zero cluster for dirFile - first cluster is in cache for write + if (!dirFile->addDirCluster()) goto fail; + + // use first entry in cluster + p = dirFile->vol_->cache()->dir; + index = 0; + } + // initialize as empty file + memset(p, 0, sizeof(dir_t)); + memcpy(p->name, dname, 11); + + // set timestamps + if (dateTime_) { + // call user date/time function + dateTime_(&p->creationDate, &p->creationTime); + } + else { + // use default date/time + p->creationDate = FAT_DEFAULT_DATE; + p->creationTime = FAT_DEFAULT_TIME; + } + p->lastAccessDate = p->creationDate; + p->lastWriteDate = p->creationDate; + p->lastWriteTime = p->creationTime; + + // write entry to SD + if (!dirFile->vol_->cacheFlush()) goto fail; + } + // open entry in cache + return openCachedEntry(index, oflag); +fail: + return false; +} +//------------------------------------------------------------------------------ +/** Open a file by index. + * + * \param[in] dirFile An open SdFat instance for the directory. + * + * \param[in] index The \a index of the directory entry for the file to be + * opened. The value for \a index is (directory file position)/32. + * + * \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive + * OR of flags O_READ, O_WRITE, O_TRUNC, and O_SYNC. + * + * See open() by path for definition of flags. + * \return true for success or false for failure. + */ +bool SdBaseFile::open(SdBaseFile* dirFile, uint16_t index, uint8_t oflag) { + dir_t* p; + + vol_ = dirFile->vol_; + + // error if already open + if (isOpen() || !dirFile) goto fail; + + // don't open existing file if O_EXCL - user call error + if (oflag & O_EXCL) goto fail; + + // seek to location of entry + if (!dirFile->seekSet(32 * index)) goto fail; + + // read entry into cache + p = dirFile->readDirCache(); + if (!p) goto fail; + + // error if empty slot or '.' or '..' + if (p->name[0] == DIR_NAME_FREE || + p->name[0] == DIR_NAME_DELETED || p->name[0] == '.') { + goto fail; + } + // open cached entry + return openCachedEntry(index & 0XF, oflag); +fail: + return false; +} +//------------------------------------------------------------------------------ +// open a cached directory entry. Assumes vol_ is initialized +bool SdBaseFile::openCachedEntry(uint8_t dirIndex, uint8_t oflag) { + // location of entry in cache + dir_t* 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)) { + if (oflag & (O_WRITE | O_TRUNC)) goto fail; + } + // remember location of directory entry on SD + dirBlock_ = vol_->cacheBlockNumber(); + dirIndex_ = dirIndex; + + // copy first cluster number for directory fields + firstCluster_ = (uint32_t)p->firstClusterHigh << 16; + firstCluster_ |= p->firstClusterLow; + + // make sure it is a normal file or subdirectory + if (DIR_IS_FILE(p)) { + fileSize_ = p->fileSize; + type_ = FAT_FILE_TYPE_NORMAL; + } + else if (DIR_IS_SUBDIR(p)) { + if (!vol_->chainSize(firstCluster_, &fileSize_)) goto fail; + type_ = FAT_FILE_TYPE_SUBDIR; + } + else { + goto fail; + } + // save open flags for read/write + flags_ = oflag & F_OFLAG; + + // set to start of file + curCluster_ = 0; + curPosition_ = 0; + if ((oflag & O_TRUNC) && !truncate(0)) return false; + return oflag & O_AT_END ? seekEnd(0) : true; +fail: + type_ = FAT_FILE_TYPE_CLOSED; + return false; +} +//------------------------------------------------------------------------------ +/** Open the next file or subdirectory in a directory. + * + * \param[in] dirFile An open SdFat instance for the directory containing the + * file to be opened. + * + * \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive + * OR of flags O_READ, O_WRITE, O_TRUNC, and O_SYNC. + * + * See open() by path for definition of flags. + * \return true for success or false for failure. + */ +bool SdBaseFile::openNext(SdBaseFile* dirFile, uint8_t oflag) { + dir_t* p; + uint8_t index; + + if (!dirFile) goto fail; + + // error if already open + if (isOpen()) goto fail; + + vol_ = dirFile->vol_; + + while (1) { + index = 0XF & (dirFile->curPosition_ >> 5); + + // read entry into cache + p = dirFile->readDirCache(); + if (!p) goto fail; + + // done if last entry + if (p->name[0] == DIR_NAME_FREE) goto fail; + + // skip empty slot or '.' or '..' + if (p->name[0] == DIR_NAME_DELETED || p->name[0] == '.') { + continue; + } + // must be file or dir + if (DIR_IS_FILE_OR_SUBDIR(p)) { + return openCachedEntry(index, oflag); + } + } +fail: + return false; +} +//------------------------------------------------------------------------------ +/** Open a directory's parent directory. + * + * \param[in] dir Parent of this directory will be opened. Must not be root. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool SdBaseFile::openParent(SdBaseFile* dir) { + dir_t entry; + dir_t* p; + SdBaseFile file; + uint32_t c; + uint32_t cluster; + uint32_t lbn; + // error if already open or dir is root or dir is not a directory + if (isOpen() || !dir || dir->isRoot() || !dir->isDir()) goto fail; + vol_ = dir->vol_; + // position to '..' + if (!dir->seekSet(32)) goto fail; + // read '..' entry + if (dir->read(&entry, sizeof(entry)) != 32) goto fail; + // verify it is '..' + if (entry.name[0] != '.' || entry.name[1] != '.') goto fail; + // start cluster for '..' + cluster = entry.firstClusterLow; + cluster |= (uint32_t)entry.firstClusterHigh << 16; + if (cluster == 0) return openRoot(vol_); + // start block for '..' + lbn = vol_->clusterStartBlock(cluster); + // first block of parent dir + if (!vol_->cacheRawBlock(lbn, SdVolume::CACHE_FOR_READ)) { + goto fail; + } + p = &vol_->cacheBuffer_.dir[1]; + // verify name for '../..' + if (p->name[0] != '.' || p->name[1] != '.') goto fail; + // '..' is pointer to first cluster of parent. open '../..' to find parent + if (p->firstClusterHigh == 0 && p->firstClusterLow == 0) { + if (!file.openRoot(dir->volume())) goto fail; + } + else if (!file.openCachedEntry(1, O_READ)) { + goto fail; + } + // search for parent in '../..' + do { + if (file.readDir(&entry, NULL) != 32) goto fail; + c = entry.firstClusterLow; + c |= (uint32_t)entry.firstClusterHigh << 16; + } while (c != cluster); + // open parent + return open(&file, file.curPosition() / 32 - 1, O_READ); +fail: + return false; +} +//------------------------------------------------------------------------------ +/** Open a volume's root directory. + * + * \param[in] vol The FAT volume containing the root directory to be opened. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include the file is already open, the FAT volume has + * not been initialized or it a FAT12 volume. + */ +bool SdBaseFile::openRoot(SdVolume* vol) { + // error if file is already open + if (isOpen()) goto fail; + + if (vol->fatType() == 16 || (FAT12_SUPPORT && vol->fatType() == 12)) { + type_ = FAT_FILE_TYPE_ROOT_FIXED; + firstCluster_ = 0; + fileSize_ = 32 * vol->rootDirEntryCount(); + } + else if (vol->fatType() == 32) { + type_ = FAT_FILE_TYPE_ROOT32; + firstCluster_ = vol->rootDirStart(); + if (!vol->chainSize(firstCluster_, &fileSize_)) goto fail; + } + else { + // volume is not initialized, invalid, or FAT12 without support + return false; + } + vol_ = vol; + // read only + flags_ = O_READ; + + // set to start of file + curCluster_ = 0; + curPosition_ = 0; + + // root has no directory entry + dirBlock_ = 0; + dirIndex_ = 0; + return true; +fail: + return false; +} +//------------------------------------------------------------------------------ +/** Return the next available byte without consuming it. + * + * \return The byte if no error and not at eof else -1; + */ +int SdBaseFile::peek() { + filepos_t pos; + getpos(&pos); + int c = read(); + if (c >= 0) setpos(&pos); + return c; +} + +//------------------------------------------------------------------------------ +/** %Print the name field of a directory entry in 8.3 format. + * \param[in] pr Print stream for output. + * \param[in] dir The directory structure containing the name. + * \param[in] width Blank fill name if length is less than \a width. + * \param[in] printSlash Print '/' after directory names if true. + */ +void SdBaseFile::printDirName(const dir_t& dir, + uint8_t width, bool printSlash) { + uint8_t w = 0; + for (uint8_t i = 0; i < 11; i++) { + if (dir.name[i] == ' ')continue; + if (i == 8) { + MYSERIAL.write('.'); + w++; + } + MYSERIAL.write(dir.name[i]); + w++; + } + if (DIR_IS_SUBDIR(&dir) && printSlash) { + MYSERIAL.write('/'); + w++; + } + while (w < width) { + MYSERIAL.write(' '); + w++; + } +} +//------------------------------------------------------------------------------ +// print uint8_t with width 2 +static void print2u(uint8_t v) { + if (v < 10) MYSERIAL.write('0'); + MYSERIAL.print(v, DEC); +} +//------------------------------------------------------------------------------ +/** %Print a directory date field to Serial. + * + * Format is yyyy-mm-dd. + * + * \param[in] fatDate The date field from a directory entry. + */ + +//------------------------------------------------------------------------------ +/** %Print a directory date field. + * + * Format is yyyy-mm-dd. + * + * \param[in] pr Print stream for output. + * \param[in] fatDate The date field from a directory entry. + */ +void SdBaseFile::printFatDate(uint16_t fatDate) { + MYSERIAL.print(FAT_YEAR(fatDate)); + MYSERIAL.write('-'); + print2u(FAT_MONTH(fatDate)); + MYSERIAL.write('-'); + print2u(FAT_DAY(fatDate)); +} + +//------------------------------------------------------------------------------ +/** %Print a directory time field. + * + * Format is hh:mm:ss. + * + * \param[in] pr Print stream for output. + * \param[in] fatTime The time field from a directory entry. + */ +void SdBaseFile::printFatTime(uint16_t fatTime) { + print2u(FAT_HOUR(fatTime)); + MYSERIAL.write(':'); + print2u(FAT_MINUTE(fatTime)); + MYSERIAL.write(':'); + print2u(FAT_SECOND(fatTime)); +} +//------------------------------------------------------------------------------ +/** Print a file's name to Serial + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool SdBaseFile::printName() { + char name[FILENAME_LENGTH]; + if (!getFilename(name)) return false; + MYSERIAL.print(name); + return true; +} +//------------------------------------------------------------------------------ +/** Read the next byte from a file. + * + * \return For success read returns the next byte in the file as an int. + * If an error occurs or end of file is reached -1 is returned. + */ +int16_t SdBaseFile::read() { + uint8_t b; + return read(&b, 1) == 1 ? b : -1; +} +//------------------------------------------------------------------------------ +/** Read data from a file starting at the current position. + * + * \param[out] buf Pointer to the location that will receive the data. + * + * \param[in] nbyte Maximum number of bytes to read. + * + * \return For success read() returns the number of bytes read. + * A value less than \a nbyte, including zero, will be returned + * if end of file is reached. + * If an error occurs, read() returns -1. Possible errors include + * read() called before a file has been opened, corrupt file system + * or an I/O error occurred. + */ +int16_t SdBaseFile::read(void* buf, uint16_t nbyte) { + uint8_t* dst = reinterpret_cast(buf); + uint16_t offset; + uint16_t toRead; + uint32_t block; // raw device block number + + // error if not open or write only + if (!isOpen() || !(flags_ & O_READ)) goto fail; + + // max bytes left in file + NOMORE(nbyte, fileSize_ - curPosition_); + + // amount left to read + toRead = nbyte; + while (toRead > 0) { + offset = curPosition_ & 0X1FF; // offset in block + if (type_ == FAT_FILE_TYPE_ROOT_FIXED) { + block = vol_->rootDirStart() + (curPosition_ >> 9); + } + else { + uint8_t blockOfCluster = vol_->blockOfCluster(curPosition_); + if (offset == 0 && blockOfCluster == 0) { + // start of new cluster + if (curPosition_ == 0) { + // use first cluster in file + curCluster_ = firstCluster_; + } + else { + // get next cluster from FAT + if (!vol_->fatGet(curCluster_, &curCluster_)) goto fail; + } + } + block = vol_->clusterStartBlock(curCluster_) + blockOfCluster; + } + uint16_t n = toRead; + + // amount to be read from current block + NOMORE(n, 512 - offset); + + // no buffering needed if n == 512 + if (n == 512 && block != vol_->cacheBlockNumber()) { + if (!vol_->readBlock(block, dst)) goto fail; + } + else { + // read block to cache and copy data to caller + if (!vol_->cacheRawBlock(block, SdVolume::CACHE_FOR_READ)) goto fail; + uint8_t* src = vol_->cache()->data + offset; + memcpy(dst, src, n); + } + dst += n; + curPosition_ += n; + toRead -= n; + } + return nbyte; +fail: + return -1; +} + +/** + * Read the next entry in a directory. + * + * \param[out] dir The dir_t struct that will receive the data. + * + * \return For success readDir() returns the number of bytes read. + * A value of zero will be returned if end of file is reached. + * If an error occurs, readDir() returns -1. Possible errors include + * readDir() called before a directory has been opened, this is not + * a directory file or an I/O error occurred. + */ +int8_t SdBaseFile::readDir(dir_t* dir, char* longFilename) { + int16_t n; + // if not a directory file or miss-positioned return an error + if (!isDir() || (0X1F & curPosition_)) return -1; + + //If we have a longFilename buffer, mark it as invalid. If we find a long filename it will be filled automaticly. + if (longFilename != NULL) longFilename[0] = '\0'; + + while (1) { + + n = read(dir, sizeof(dir_t)); + if (n != sizeof(dir_t)) return n == 0 ? 0 : -1; + + // last entry if DIR_NAME_FREE + if (dir->name[0] == DIR_NAME_FREE) return 0; + + // skip empty entries and entry for . and .. + if (dir->name[0] == DIR_NAME_DELETED || dir->name[0] == '.') continue; + + // Fill the long filename if we have a long filename entry. + // Long filename entries are stored before the short filename. + if (longFilename != NULL && DIR_IS_LONG_NAME(dir)) { + vfat_t* VFAT = (vfat_t*)dir; + // Sanity-check the VFAT entry. The first cluster is always set to zero. And the sequence number should be higher than 0 + if (VFAT->firstClusterLow == 0 && (VFAT->sequenceNumber & 0x1F) > 0 && (VFAT->sequenceNumber & 0x1F) <= MAX_VFAT_ENTRIES) { + // TODO: Store the filename checksum to verify if a none-long filename aware system modified the file table. + n = ((VFAT->sequenceNumber & 0x1F) - 1) * (FILENAME_LENGTH); + for (uint8_t i = 0; i < FILENAME_LENGTH; i++) + 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'; + } + } + // Return if normal file or subdirectory + if (DIR_IS_FILE_OR_SUBDIR(dir)) return n; + } +} + +//------------------------------------------------------------------------------ +// Read next directory entry into the cache +// Assumes file is correctly positioned +dir_t* SdBaseFile::readDirCache() { + uint8_t i; + // error if not directory + if (!isDir()) goto fail; + + // index of entry in cache + i = (curPosition_ >> 5) & 0XF; + + // use read to locate and cache block + if (read() < 0) goto fail; + + // advance to next entry + curPosition_ += 31; + + // return pointer to entry + return vol_->cache()->dir + i; +fail: + return 0; +} +//------------------------------------------------------------------------------ +/** Remove a file. + * + * The directory entry and all data for the file are deleted. + * + * \note This function should not be used to delete the 8.3 version of a + * file that has a long name. For example if a file has the long name + * "New Text Document.txt" you should not delete the 8.3 name "NEWTEX~1.TXT". + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include the file read-only, is a directory, + * or an I/O error occurred. + */ +bool SdBaseFile::remove() { + dir_t* d; + // free any clusters - will fail if read-only or directory + if (!truncate(0)) goto fail; + + // cache directory entry + d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); + if (!d) goto fail; + + // mark entry deleted + d->name[0] = DIR_NAME_DELETED; + + // set this file closed + type_ = FAT_FILE_TYPE_CLOSED; + + // write entry to SD + return vol_->cacheFlush(); + return true; +fail: + return false; +} +//------------------------------------------------------------------------------ +/** Remove a file. + * + * The directory entry and all data for the file are deleted. + * + * \param[in] dirFile The directory that contains the file. + * \param[in] path Path for the file to be removed. + * + * \note This function should not be used to delete the 8.3 version of a + * file that has a long name. For example if a file has the long name + * "New Text Document.txt" you should not delete the 8.3 name "NEWTEX~1.TXT". + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include the file is a directory, is read only, + * \a dirFile is not a directory, \a path is not found + * or an I/O error occurred. + */ +bool SdBaseFile::remove(SdBaseFile* dirFile, const char* path) { + SdBaseFile file; + if (!file.open(dirFile, path, O_WRITE)) goto fail; + return file.remove(); +fail: + // can't set iostate - static function + return false; +} +//------------------------------------------------------------------------------ +/** Rename a file or subdirectory. + * + * \param[in] dirFile Directory for the new path. + * \param[in] newPath New path name for the file/directory. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include \a dirFile is not open or is not a directory + * file, newPath is invalid or already exists, or an I/O error occurs. + */ +bool SdBaseFile::rename(SdBaseFile* dirFile, const char* newPath) { + dir_t entry; + uint32_t dirCluster = 0; + SdBaseFile file; + dir_t* d; + + // must be an open file or subdirectory + if (!(isFile() || isSubDir())) goto fail; + + // can't move file + if (vol_ != dirFile->vol_) goto fail; + + // sync() and cache directory entry + sync(); + d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); + if (!d) goto fail; + + // save directory entry + memcpy(&entry, d, sizeof(entry)); + + // mark entry deleted + d->name[0] = DIR_NAME_DELETED; + + // make directory entry for new path + if (isFile()) { + if (!file.open(dirFile, newPath, O_CREAT | O_EXCL | O_WRITE)) { + goto restore; + } + } + else { + // don't create missing path prefix components + if (!file.mkdir(dirFile, newPath, false)) { + goto restore; + } + // save cluster containing new dot dot + dirCluster = file.firstCluster_; + } + // change to new directory entry + dirBlock_ = file.dirBlock_; + dirIndex_ = file.dirIndex_; + + // mark closed to avoid possible destructor close call + file.type_ = FAT_FILE_TYPE_CLOSED; + + // cache new directory entry + d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); + if (!d) goto fail; + + // copy all but name field to new directory entry + memcpy(&d->attributes, &entry.attributes, sizeof(entry) - sizeof(d->name)); + + // update dot dot if directory + if (dirCluster) { + // get new dot dot + uint32_t block = vol_->clusterStartBlock(dirCluster); + if (!vol_->cacheRawBlock(block, SdVolume::CACHE_FOR_READ)) goto fail; + memcpy(&entry, &vol_->cache()->dir[1], sizeof(entry)); + + // free unused cluster + if (!vol_->freeChain(dirCluster)) goto fail; + + // store new dot dot + block = vol_->clusterStartBlock(firstCluster_); + if (!vol_->cacheRawBlock(block, SdVolume::CACHE_FOR_WRITE)) goto fail; + memcpy(&vol_->cache()->dir[1], &entry, sizeof(entry)); + } + return vol_->cacheFlush(); + +restore: + d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); + if (!d) goto fail; + // restore entry + d->name[0] = entry.name[0]; + vol_->cacheFlush(); + +fail: + return false; +} +//------------------------------------------------------------------------------ +/** Remove a directory file. + * + * The directory file will be removed only if it is empty and is not the + * root directory. rmdir() follows DOS and Windows and ignores the + * read-only attribute for the directory. + * + * \note This function should not be used to delete the 8.3 version of a + * directory that has a long name. For example if a directory has the + * long name "New folder" you should not delete the 8.3 name "NEWFOL~1". + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include the file is not a directory, is the root + * directory, is not empty, or an I/O error occurred. + */ +bool SdBaseFile::rmdir() { + // must be open subdirectory + if (!isSubDir()) goto fail; + + rewind(); + + // make sure directory is empty + while (curPosition_ < fileSize_) { + dir_t* p = readDirCache(); + if (!p) goto fail; + // done if past last used entry + if (p->name[0] == DIR_NAME_FREE) break; + // skip empty slot, '.' or '..' + if (p->name[0] == DIR_NAME_DELETED || p->name[0] == '.') continue; + // error not empty + if (DIR_IS_FILE_OR_SUBDIR(p)) goto fail; + } + // convert empty directory to normal file for remove + type_ = FAT_FILE_TYPE_NORMAL; + flags_ |= O_WRITE; + return remove(); +fail: + return false; +} +//------------------------------------------------------------------------------ +/** Recursively delete a directory and all contained files. + * + * This is like the Unix/Linux 'rm -rf *' if called with the root directory + * hence the name. + * + * Warning - This will remove all contents of the directory including + * subdirectories. The directory will then be removed if it is not root. + * The read-only attribute for files will be ignored. + * + * \note This function should not be used to delete the 8.3 version of + * a directory that has a long name. See remove() and rmdir(). + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool SdBaseFile::rmRfStar() { + uint16_t index; + SdBaseFile f; + rewind(); + while (curPosition_ < fileSize_) { + // remember position + index = curPosition_ / 32; + + dir_t* p = readDirCache(); + if (!p) goto fail; + + // done if past last entry + if (p->name[0] == DIR_NAME_FREE) break; + + // skip empty slot or '.' or '..' + if (p->name[0] == DIR_NAME_DELETED || p->name[0] == '.') continue; + + // skip if part of long file name or volume label in root + if (!DIR_IS_FILE_OR_SUBDIR(p)) continue; + + if (!f.open(this, index, O_READ)) goto fail; + if (f.isSubDir()) { + // recursively delete + if (!f.rmRfStar()) goto fail; + } + else { + // ignore read-only + f.flags_ |= O_WRITE; + if (!f.remove()) goto fail; + } + // position to next entry if required + if (curPosition_ != (32 * (index + 1))) { + if (!seekSet(32 * (index + 1))) goto fail; + } + } + // don't try to delete root + if (!isRoot()) { + if (!rmdir()) goto fail; + } + return true; +fail: + return false; +} +//------------------------------------------------------------------------------ +/** Create a file object and open it in the current working directory. + * + * \param[in] path A path with a valid 8.3 DOS name for a file to be opened. + * + * \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive + * OR of open flags. see SdBaseFile::open(SdBaseFile*, const char*, uint8_t). + */ +SdBaseFile::SdBaseFile(const char* path, uint8_t oflag) { + type_ = FAT_FILE_TYPE_CLOSED; + writeError = false; + open(path, oflag); +} +//------------------------------------------------------------------------------ +/** Sets a file's position. + * + * \param[in] pos The new position in bytes from the beginning of the file. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool SdBaseFile::seekSet(uint32_t pos) { + uint32_t nCur; + uint32_t nNew; + // error if file not open or seek past end of file + if (!isOpen() || pos > fileSize_) goto fail; + + if (type_ == FAT_FILE_TYPE_ROOT_FIXED) { + curPosition_ = pos; + goto done; + } + if (pos == 0) { + // set position to start of file + curCluster_ = 0; + curPosition_ = 0; + goto done; + } + // calculate cluster index for cur and new position + nCur = (curPosition_ - 1) >> (vol_->clusterSizeShift_ + 9); + nNew = (pos - 1) >> (vol_->clusterSizeShift_ + 9); + + if (nNew < nCur || curPosition_ == 0) { + // must follow chain from first cluster + curCluster_ = firstCluster_; + } + else { + // advance from curPosition + nNew -= nCur; + } + while (nNew--) { + if (!vol_->fatGet(curCluster_, &curCluster_)) goto fail; + } + curPosition_ = pos; + +done: + return true; + +fail: + return false; +} +//------------------------------------------------------------------------------ +void SdBaseFile::setpos(filepos_t* pos) { + curPosition_ = pos->position; + curCluster_ = pos->cluster; +} +//------------------------------------------------------------------------------ +/** The sync() call causes all modified data and directory fields + * to be written to the storage device. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include a call to sync() before a file has been + * opened or an I/O error. + */ +bool SdBaseFile::sync() { + // only allow open files and directories + if (!isOpen()) goto fail; + + if (flags_ & F_FILE_DIR_DIRTY) { + dir_t* d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); + // check for deleted by another open file object + if (!d || d->name[0] == DIR_NAME_DELETED) goto fail; + + // do not set filesize for dir files + if (!isDir()) d->fileSize = fileSize_; + + // update first cluster fields + d->firstClusterLow = firstCluster_ & 0XFFFF; + d->firstClusterHigh = firstCluster_ >> 16; + + // set modify time if user supplied a callback date/time function + if (dateTime_) { + dateTime_(&d->lastWriteDate, &d->lastWriteTime); + d->lastAccessDate = d->lastWriteDate; + } + // clear directory dirty + flags_ &= ~F_FILE_DIR_DIRTY; + } + return vol_->cacheFlush(); + +fail: + writeError = true; + return false; +} +//------------------------------------------------------------------------------ +/** Copy a file's timestamps + * + * \param[in] file File to copy timestamps from. + * + * \note + * Modify and access timestamps may be overwritten if a date time callback + * function has been set by dateTimeCallback(). + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool SdBaseFile::timestamp(SdBaseFile* file) { + dir_t* d; + dir_t dir; + + // get timestamps + if (!file->dirEntry(&dir)) goto fail; + + // update directory fields + if (!sync()) goto fail; + + d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); + if (!d) goto fail; + + // copy timestamps + d->lastAccessDate = dir.lastAccessDate; + d->creationDate = dir.creationDate; + d->creationTime = dir.creationTime; + d->creationTimeTenths = dir.creationTimeTenths; + d->lastWriteDate = dir.lastWriteDate; + d->lastWriteTime = dir.lastWriteTime; + + // write back entry + return vol_->cacheFlush(); + +fail: + return false; +} +//------------------------------------------------------------------------------ +/** Set a file's timestamps in its directory entry. + * + * \param[in] flags Values for \a flags are constructed by a bitwise-inclusive + * OR of flags from the following list + * + * T_ACCESS - Set the file's last access date. + * + * T_CREATE - Set the file's creation date and time. + * + * T_WRITE - Set the file's last write/modification date and time. + * + * \param[in] year Valid range 1980 - 2107 inclusive. + * + * \param[in] month Valid range 1 - 12 inclusive. + * + * \param[in] day Valid range 1 - 31 inclusive. + * + * \param[in] hour Valid range 0 - 23 inclusive. + * + * \param[in] minute Valid range 0 - 59 inclusive. + * + * \param[in] second Valid range 0 - 59 inclusive + * + * \note It is possible to set an invalid date since there is no check for + * the number of days in a month. + * + * \note + * Modify and access timestamps may be overwritten if a date time callback + * function has been set by dateTimeCallback(). + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool SdBaseFile::timestamp(uint8_t flags, uint16_t year, uint8_t month, + uint8_t day, uint8_t hour, uint8_t minute, uint8_t second) { + uint16_t dirDate; + uint16_t dirTime; + dir_t* d; + + if (!isOpen() + || year < 1980 + || year > 2107 + || month < 1 + || month > 12 + || day < 1 + || day > 31 + || hour > 23 + || minute > 59 + || second > 59) { + goto fail; + } + // update directory entry + if (!sync()) goto fail; + + d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); + if (!d) goto fail; + + dirDate = FAT_DATE(year, month, day); + dirTime = FAT_TIME(hour, minute, second); + if (flags & T_ACCESS) { + d->lastAccessDate = dirDate; + } + if (flags & T_CREATE) { + d->creationDate = dirDate; + d->creationTime = dirTime; + // seems to be units of 1/100 second not 1/10 as Microsoft states + d->creationTimeTenths = second & 1 ? 100 : 0; + } + if (flags & T_WRITE) { + d->lastWriteDate = dirDate; + d->lastWriteTime = dirTime; + } + return vol_->cacheFlush(); +fail: + return false; +} +//------------------------------------------------------------------------------ +/** Truncate a file to a specified length. The current file position + * will be maintained if it is less than or equal to \a length otherwise + * it will be set to end of file. + * + * \param[in] length The desired length for the file. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include file is read only, file is a directory, + * \a length is greater than the current file size or an I/O error occurs. + */ +bool SdBaseFile::truncate(uint32_t length) { + uint32_t newPos; + // error if not a normal file or read-only + if (!isFile() || !(flags_ & O_WRITE)) goto fail; + + // error if length is greater than current size + if (length > fileSize_) goto fail; + + // fileSize and length are zero - nothing to do + if (fileSize_ == 0) return true; + + // remember position for seek after truncation + newPos = curPosition_ > length ? length : curPosition_; + + // position to last cluster in truncated file + if (!seekSet(length)) goto fail; + + if (length == 0) { + // free all clusters + if (!vol_->freeChain(firstCluster_)) goto fail; + firstCluster_ = 0; + } + else { + uint32_t toFree; + if (!vol_->fatGet(curCluster_, &toFree)) goto fail; + + if (!vol_->isEOC(toFree)) { + // free extra clusters + if (!vol_->freeChain(toFree)) goto fail; + + // current cluster is end of chain + if (!vol_->fatPutEOC(curCluster_)) goto fail; + } + } + fileSize_ = length; + + // need to update directory entry + flags_ |= F_FILE_DIR_DIRTY; + + if (!sync()) goto fail; + + // set file to correct position + return seekSet(newPos); + +fail: + return false; +} +//------------------------------------------------------------------------------ +/** Write data to an open file. + * + * \note Data is moved to the cache but may not be written to the + * storage device until sync() is called. + * + * \param[in] buf Pointer to the location of the data to be written. + * + * \param[in] nbyte Number of bytes to write. + * + * \return For success write() returns the number of bytes written, always + * \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) { + // convert void* to uint8_t* - must be before goto statements + const uint8_t* src = reinterpret_cast(buf); + + // number of bytes left to write - must be before goto statements + uint16_t nToWrite = nbyte; + + // error if not a normal file or is read-only + if (!isFile() || !(flags_ & O_WRITE)) goto fail; + + // seek to end of file if append flag + if ((flags_ & O_APPEND) && curPosition_ != fileSize_) { + if (!seekEnd()) goto fail; + } + + while (nToWrite > 0) { + uint8_t blockOfCluster = vol_->blockOfCluster(curPosition_); + uint16_t blockOffset = curPosition_ & 0X1FF; + if (blockOfCluster == 0 && blockOffset == 0) { + // start of new cluster + if (curCluster_ == 0) { + if (firstCluster_ == 0) { + // allocate first cluster of file + if (!addCluster()) goto fail; + } + else { + curCluster_ = firstCluster_; + } + } + else { + uint32_t next; + if (!vol_->fatGet(curCluster_, &next)) goto fail; + if (vol_->isEOC(next)) { + // add cluster if at end of chain + if (!addCluster()) goto fail; + } + else { + curCluster_ = next; + } + } + } + // max space in block + uint16_t n = 512 - blockOffset; + + // lesser of space and amount to write + NOMORE(n, nToWrite); + + // block for data write + uint32_t block = vol_->clusterStartBlock(curCluster_) + blockOfCluster; + if (n == 512) { + // full block - don't need to use cache + if (vol_->cacheBlockNumber() == block) { + // invalidate cache if block is in cache + vol_->cacheSetBlockNumber(0XFFFFFFFF, false); + } + if (!vol_->writeBlock(block, src)) goto fail; + } + else { + if (blockOffset == 0 && curPosition_ >= fileSize_) { + // start of new block don't need to read into cache + if (!vol_->cacheFlush()) goto fail; + // set cache dirty and SD address of block + vol_->cacheSetBlockNumber(block, true); + } + else { + // rewrite part of block + if (!vol_->cacheRawBlock(block, SdVolume::CACHE_FOR_WRITE)) goto fail; + } + uint8_t* dst = vol_->cache()->data + blockOffset; + memcpy(dst, src, n); + } + curPosition_ += n; + src += n; + nToWrite -= n; + } + if (curPosition_ > fileSize_) { + // update fileSize and insure sync will update dir entry + fileSize_ = curPosition_; + flags_ |= F_FILE_DIR_DIRTY; + } + else if (dateTime_ && nbyte) { + // insure sync will update modified date and time + flags_ |= F_FILE_DIR_DIRTY; + } + + if (flags_ & O_SYNC) { + if (!sync()) goto fail; + } + return nbyte; + +fail: + // return for write error + writeError = true; + return -1; +} +//------------------------------------------------------------------------------ +// suppress cpplint warnings with NOLINT comment +#if ALLOW_DEPRECATED_FUNCTIONS && !defined(DOXYGEN) + void (*SdBaseFile::oldDateTime_)(uint16_t& date, uint16_t& time) = 0; // NOLINT +#endif // ALLOW_DEPRECATED_FUNCTIONS + + +#endif diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/SdBaseFile.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/SdBaseFile.h new file mode 100644 index 00000000..2b912d2e --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/SdBaseFile.h @@ -0,0 +1,492 @@ +/** + * 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 . + * + */ + +/** + * Arduino SdFat Library + * Copyright (C) 2009 by William Greiman + * + * This file is part of the Arduino Sd2Card Library + */ +#include "Marlin.h" +#if ENABLED(SDSUPPORT) + +#ifndef SdBaseFile_h +#define SdBaseFile_h +/** + * \file + * \brief SdBaseFile class + */ +#include "Marlin.h" +#include "SdFatConfig.h" +#include "SdVolume.h" +//------------------------------------------------------------------------------ +/** + * \struct filepos_t + * \brief internal type for istream + * do not use in user apps + */ +struct filepos_t { + /** stream position */ + uint32_t position; + /** cluster for position */ + uint32_t cluster; + filepos_t() : position(0), cluster(0) {} +}; + +// use the gnu style oflag in open() +/** open() oflag for reading */ +uint8_t const O_READ = 0X01; +/** open() oflag - same as O_IN */ +uint8_t const O_RDONLY = O_READ; +/** open() oflag for write */ +uint8_t const O_WRITE = 0X02; +/** open() oflag - same as O_WRITE */ +uint8_t const O_WRONLY = O_WRITE; +/** open() oflag for reading and writing */ +uint8_t const O_RDWR = (O_READ | O_WRITE); +/** open() oflag mask for access modes */ +uint8_t const O_ACCMODE = (O_READ | O_WRITE); +/** The file offset shall be set to the end of the file prior to each write. */ +uint8_t const O_APPEND = 0X04; +/** synchronous writes - call sync() after each write */ +uint8_t const O_SYNC = 0X08; +/** truncate the file to zero length */ +uint8_t const O_TRUNC = 0X10; +/** set the initial position at the end of the file */ +uint8_t const O_AT_END = 0X20; +/** create the file if nonexistent */ +uint8_t const O_CREAT = 0X40; +/** If O_CREAT and O_EXCL are set, open() shall fail if the file exists */ +uint8_t const O_EXCL = 0X80; + +// SdBaseFile class static and const definitions +// flags for ls() +/** ls() flag to print modify date */ +uint8_t const LS_DATE = 1; +/** ls() flag to print file size */ +uint8_t const LS_SIZE = 2; +/** ls() flag for recursive list of subdirectories */ +uint8_t const LS_R = 4; + + +// flags for timestamp +/** set the file's last access date */ +uint8_t const T_ACCESS = 1; +/** set the file's creation date and time */ +uint8_t const T_CREATE = 2; +/** Set the file's write date and time */ +uint8_t const T_WRITE = 4; +// values for type_ +/** This file has not been opened. */ +uint8_t const FAT_FILE_TYPE_CLOSED = 0; +/** A normal file */ +uint8_t const FAT_FILE_TYPE_NORMAL = 1; +/** A FAT12 or FAT16 root directory */ +uint8_t const FAT_FILE_TYPE_ROOT_FIXED = 2; +/** A FAT32 root directory */ +uint8_t const FAT_FILE_TYPE_ROOT32 = 3; +/** A subdirectory file*/ +uint8_t const FAT_FILE_TYPE_SUBDIR = 4; +/** Test value for directory type */ +uint8_t const FAT_FILE_TYPE_MIN_DIR = FAT_FILE_TYPE_ROOT_FIXED; + +/** date field for FAT directory entry + * \param[in] year [1980,2107] + * \param[in] month [1,12] + * \param[in] day [1,31] + * + * \return Packed date for dir_t entry. + */ +static inline uint16_t FAT_DATE(uint16_t year, uint8_t month, uint8_t day) { + return (year - 1980) << 9 | month << 5 | day; +} +/** year part of FAT directory date field + * \param[in] fatDate Date in packed dir format. + * + * \return Extracted year [1980,2107] + */ +static inline uint16_t FAT_YEAR(uint16_t fatDate) { + return 1980 + (fatDate >> 9); +} +/** month part of FAT directory date field + * \param[in] fatDate Date in packed dir format. + * + * \return Extracted month [1,12] + */ +static inline uint8_t FAT_MONTH(uint16_t fatDate) { + return (fatDate >> 5) & 0XF; +} +/** day part of FAT directory date field + * \param[in] fatDate Date in packed dir format. + * + * \return Extracted day [1,31] + */ +static inline uint8_t FAT_DAY(uint16_t fatDate) { + return fatDate & 0X1F; +} +/** time field for FAT directory entry + * \param[in] hour [0,23] + * \param[in] minute [0,59] + * \param[in] second [0,59] + * + * \return Packed time for dir_t entry. + */ +static inline uint16_t FAT_TIME(uint8_t hour, uint8_t minute, uint8_t second) { + return hour << 11 | minute << 5 | second >> 1; +} +/** hour part of FAT directory time field + * \param[in] fatTime Time in packed dir format. + * + * \return Extracted hour [0,23] + */ +static inline uint8_t FAT_HOUR(uint16_t fatTime) { + return fatTime >> 11; +} +/** minute part of FAT directory time field + * \param[in] fatTime Time in packed dir format. + * + * \return Extracted minute [0,59] + */ +static inline uint8_t FAT_MINUTE(uint16_t fatTime) { + return (fatTime >> 5) & 0X3F; +} +/** second part of FAT directory time field + * Note second/2 is stored in packed time. + * + * \param[in] fatTime Time in packed dir format. + * + * \return Extracted second [0,58] + */ +static inline uint8_t FAT_SECOND(uint16_t fatTime) { + return 2 * (fatTime & 0X1F); +} +/** Default date for file timestamps is 1 Jan 2000 */ +uint16_t const FAT_DEFAULT_DATE = ((2000 - 1980) << 9) | (1 << 5) | 1; +/** Default time for file timestamp is 1 am */ +uint16_t const FAT_DEFAULT_TIME = (1 << 11); +//------------------------------------------------------------------------------ +/** + * \class SdBaseFile + * \brief Base class for SdFile with Print and C++ streams. + */ +class SdBaseFile { + public: + /** Create an instance. */ + SdBaseFile() : writeError(false), type_(FAT_FILE_TYPE_CLOSED) {} + SdBaseFile(const char* path, uint8_t oflag); + ~SdBaseFile() {if (isOpen()) close();} + /** + * writeError is set to true if an error occurs during a write(). + * Set writeError to false before calling print() and/or write() and check + * for true after calls to print() and/or write(). + */ + bool writeError; + //---------------------------------------------------------------------------- + // helpers for stream classes + /** get position for streams + * \param[out] pos struct to receive position + */ + void getpos(filepos_t* pos); + /** set position for streams + * \param[out] pos struct with value for new position + */ + void setpos(filepos_t* pos); + //---------------------------------------------------------------------------- + bool close(); + bool contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock); + bool createContiguous(SdBaseFile* dirFile, + const char* path, uint32_t size); + /** \return The current cluster number for a file or directory. */ + uint32_t curCluster() const {return curCluster_;} + /** \return The current position for a file or directory. */ + uint32_t curPosition() const {return curPosition_;} + /** \return Current working directory */ + static SdBaseFile* cwd() {return cwd_;} + /** Set the date/time callback function + * + * \param[in] dateTime The user's call back function. The callback + * function is of the form: + * + * \code + * void dateTime(uint16_t* date, uint16_t* time) { + * uint16_t year; + * uint8_t month, day, hour, minute, second; + * + * // User gets date and time from GPS or real-time clock here + * + * // return date using FAT_DATE macro to format fields + * *date = FAT_DATE(year, month, day); + * + * // return time using FAT_TIME macro to format fields + * *time = FAT_TIME(hour, minute, second); + * } + * \endcode + * + * Sets the function that is called when a file is created or when + * a file's directory entry is modified by sync(). All timestamps, + * access, creation, and modify, are set when a file is created. + * sync() maintains the last access date and last modify date/time. + * + * See the timestamp() function. + */ + static void dateTimeCallback( + void (*dateTime)(uint16_t* date, uint16_t* time)) { + dateTime_ = dateTime; + } + /** Cancel the date/time callback function. */ + static void dateTimeCallbackCancel() {dateTime_ = 0;} + bool dirEntry(dir_t* dir); + static void dirName(const dir_t& dir, char* name); + bool exists(const char* name); + int16_t fgets(char* str, int16_t num, char* delim = 0); + /** \return The total number of bytes in a file or directory. */ + uint32_t fileSize() const {return fileSize_;} + /** \return The first cluster number for a file or directory. */ + uint32_t firstCluster() const {return firstCluster_;} + bool getFilename(char* name); + /** \return True if this is a directory else false. */ + bool isDir() const {return type_ >= FAT_FILE_TYPE_MIN_DIR;} + /** \return True if this is a normal file else false. */ + bool isFile() const {return type_ == FAT_FILE_TYPE_NORMAL;} + /** \return True if this is an open file/directory else false. */ + bool isOpen() const {return type_ != FAT_FILE_TYPE_CLOSED;} + /** \return True if this is a subdirectory else false. */ + bool isSubDir() const {return type_ == FAT_FILE_TYPE_SUBDIR;} + /** \return True if this is the root directory. */ + bool isRoot() const { + return type_ == FAT_FILE_TYPE_ROOT_FIXED || type_ == FAT_FILE_TYPE_ROOT32; + } + void ls(uint8_t flags = 0, uint8_t indent = 0); + bool mkdir(SdBaseFile* dir, const char* path, bool pFlag = true); + // alias for backward compactability + bool makeDir(SdBaseFile* dir, const char* path) { + return mkdir(dir, path, false); + } + bool open(SdBaseFile* dirFile, uint16_t index, uint8_t oflag); + bool open(SdBaseFile* dirFile, const char* path, uint8_t oflag); + bool open(const char* path, uint8_t oflag = O_READ); + bool openNext(SdBaseFile* dirFile, uint8_t oflag); + bool openRoot(SdVolume* vol); + int peek(); + static void printFatDate(uint16_t fatDate); + static void printFatTime(uint16_t fatTime); + bool printName(); + int16_t read(); + int16_t read(void* buf, uint16_t nbyte); + int8_t readDir(dir_t* dir, char* longFilename); + static bool remove(SdBaseFile* dirFile, const char* path); + bool remove(); + /** Set the file's current position to zero. */ + void rewind() {seekSet(0);} + bool rename(SdBaseFile* dirFile, const char* newPath); + bool rmdir(); + // for backward compatibility + bool rmDir() {return rmdir();} + bool rmRfStar(); + /** Set the files position to current position + \a pos. See seekSet(). + * \param[in] offset The new position in bytes from the current position. + * \return true for success or false for failure. + */ + bool seekCur(int32_t offset) { + return seekSet(curPosition_ + offset); + } + /** Set the files position to end-of-file + \a offset. See seekSet(). + * \param[in] offset The new position in bytes from end-of-file. + * \return true for success or false for failure. + */ + bool seekEnd(int32_t offset = 0) {return seekSet(fileSize_ + offset);} + bool seekSet(uint32_t pos); + bool sync(); + bool timestamp(SdBaseFile* file); + bool timestamp(uint8_t flag, uint16_t year, uint8_t month, uint8_t day, + uint8_t hour, uint8_t minute, uint8_t second); + /** Type of file. You should use isFile() or isDir() instead of type() + * if possible. + * + * \return The file or directory type. + */ + uint8_t type() const {return type_;} + bool truncate(uint32_t size); + /** \return SdVolume that contains this file. */ + SdVolume* volume() const {return vol_;} + int16_t write(const void* buf, uint16_t nbyte); + //------------------------------------------------------------------------------ + private: + // allow SdFat to set cwd_ + friend class SdFat; + // global pointer to cwd dir + static SdBaseFile* cwd_; + // data time callback function + static void (*dateTime_)(uint16_t* date, uint16_t* time); + // bits defined in flags_ + // should be 0X0F + static uint8_t const F_OFLAG = (O_ACCMODE | O_APPEND | O_SYNC); + // sync of directory entry required + static uint8_t const F_FILE_DIR_DIRTY = 0X80; + + // private data + uint8_t flags_; // See above for definition of flags_ bits + uint8_t fstate_; // error and eof indicator + uint8_t type_; // type of file see above for values + uint32_t curCluster_; // cluster for current file position + uint32_t curPosition_; // current file position in bytes from beginning + uint32_t dirBlock_; // block for this files directory entry + uint8_t dirIndex_; // index of directory entry in dirBlock + uint32_t fileSize_; // file size in bytes + uint32_t firstCluster_; // first cluster of file + SdVolume* vol_; // volume where file is located + + /** experimental don't use */ + bool openParent(SdBaseFile* dir); + // private functions + bool addCluster(); + bool addDirCluster(); + dir_t* cacheDirEntry(uint8_t action); + int8_t lsPrintNext(uint8_t flags, uint8_t indent); + static bool make83Name(const char* str, uint8_t* name, const char** ptr); + bool mkdir(SdBaseFile* parent, const uint8_t dname[11]); + bool open(SdBaseFile* dirFile, const uint8_t dname[11], uint8_t oflag); + bool openCachedEntry(uint8_t cacheIndex, uint8_t oflags); + dir_t* readDirCache(); + //------------------------------------------------------------------------------ + // to be deleted + static void printDirName(const dir_t& dir, + uint8_t width, bool printSlash); + //------------------------------------------------------------------------------ + // Deprecated functions - suppress cpplint warnings with NOLINT comment +#if ALLOW_DEPRECATED_FUNCTIONS && !defined(DOXYGEN) + public: + /** \deprecated Use: + * bool contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock); + * \param[out] bgnBlock the first block address for the file. + * \param[out] endBlock the last block address for the file. + * \return true for success or false for failure. + */ + bool contiguousRange(uint32_t& bgnBlock, uint32_t& endBlock) { // NOLINT + return contiguousRange(&bgnBlock, &endBlock); + } + /** \deprecated Use: + * bool createContiguous(SdBaseFile* dirFile, + * const char* path, uint32_t size) + * \param[in] dirFile The directory where the file will be created. + * \param[in] path A path with a valid DOS 8.3 file name. + * \param[in] size The desired file size. + * \return true for success or false for failure. + */ + bool createContiguous(SdBaseFile& dirFile, // NOLINT + const char* path, uint32_t size) { + return createContiguous(&dirFile, path, size); + } + /** \deprecated Use: + * static void dateTimeCallback( + * void (*dateTime)(uint16_t* date, uint16_t* time)); + * \param[in] dateTime The user's call back function. + */ + static void dateTimeCallback( + void (*dateTime)(uint16_t& date, uint16_t& time)) { // NOLINT + oldDateTime_ = dateTime; + dateTime_ = dateTime ? oldToNew : 0; + } + /** \deprecated Use: bool dirEntry(dir_t* dir); + * \param[out] dir Location for return of the file's directory entry. + * \return true for success or false for failure. + */ + bool dirEntry(dir_t& dir) {return dirEntry(&dir);} // NOLINT + /** \deprecated Use: + * bool mkdir(SdBaseFile* dir, const char* path); + * \param[in] dir An open SdFat instance for the directory that will contain + * the new directory. + * \param[in] path A path with a valid 8.3 DOS name for the new directory. + * \return true for success or false for failure. + */ + bool mkdir(SdBaseFile& dir, const char* path) { // NOLINT + return mkdir(&dir, path); + } + /** \deprecated Use: + * bool open(SdBaseFile* dirFile, const char* path, uint8_t oflag); + * \param[in] dirFile An open SdFat instance for the directory containing the + * file to be opened. + * \param[in] path A path with a valid 8.3 DOS name for the file. + * \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive + * OR of flags O_READ, O_WRITE, O_TRUNC, and O_SYNC. + * \return true for success or false for failure. + */ + bool open(SdBaseFile& dirFile, // NOLINT + const char* path, uint8_t oflag) { + return open(&dirFile, path, oflag); + } + /** \deprecated Do not use in new apps + * \param[in] dirFile An open SdFat instance for the directory containing the + * file to be opened. + * \param[in] path A path with a valid 8.3 DOS name for a file to be opened. + * \return true for success or false for failure. + */ + bool open(SdBaseFile& dirFile, const char* path) { // NOLINT + return open(dirFile, path, O_RDWR); + } + /** \deprecated Use: + * bool open(SdBaseFile* dirFile, uint16_t index, uint8_t oflag); + * \param[in] dirFile An open SdFat instance for the directory. + * \param[in] index The \a index of the directory entry for the file to be + * opened. The value for \a index is (directory file position)/32. + * \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive + * OR of flags O_READ, O_WRITE, O_TRUNC, and O_SYNC. + * \return true for success or false for failure. + */ + bool open(SdBaseFile& dirFile, uint16_t index, uint8_t oflag) { // NOLINT + return open(&dirFile, index, oflag); + } + /** \deprecated Use: bool openRoot(SdVolume* vol); + * \param[in] vol The FAT volume containing the root directory to be opened. + * \return true for success or false for failure. + */ + bool openRoot(SdVolume& vol) {return openRoot(&vol);} // NOLINT + /** \deprecated Use: int8_t readDir(dir_t* dir); + * \param[out] dir The dir_t struct that will receive the data. + * \return bytes read for success zero for eof or -1 for failure. + */ + int8_t readDir(dir_t& dir, char* longFilename) {return readDir(&dir, longFilename);} // NOLINT + /** \deprecated Use: + * static uint8_t remove(SdBaseFile* dirFile, const char* path); + * \param[in] dirFile The directory that contains the file. + * \param[in] path The name of the file to be removed. + * \return true for success or false for failure. + */ + static bool remove(SdBaseFile& dirFile, const char* path) { // NOLINT + return remove(&dirFile, path); + } + //------------------------------------------------------------------------------ + // rest are private + private: + static void (*oldDateTime_)(uint16_t& date, uint16_t& time); // NOLINT + static void oldToNew(uint16_t* date, uint16_t* time) { + uint16_t d; + uint16_t t; + oldDateTime_(d, t); + *date = d; + *time = t; + } +#endif // ALLOW_DEPRECATED_FUNCTIONS +}; + +#endif // SdBaseFile_h +#endif diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/SdFatConfig.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/SdFatConfig.h new file mode 100644 index 00000000..d3406a02 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/SdFatConfig.h @@ -0,0 +1,134 @@ +/** + * 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 . + * + */ + +/** + * Arduino SdFat Library + * Copyright (C) 2009 by William Greiman + * + * This file is part of the Arduino Sd2Card Library + */ +/** + * \file + * \brief configuration definitions + */ +#include "Marlin.h" +#if ENABLED(SDSUPPORT) + +#ifndef SdFatConfig_h + #define SdFatConfig_h + #include + //------------------------------------------------------------------------------ + /** + * To use multiple SD cards set USE_MULTIPLE_CARDS nonzero. + * + * Using multiple cards costs 400 - 500 bytes of flash. + * + * Each card requires about 550 bytes of SRAM so use of a Mega is recommended. + */ + #define USE_MULTIPLE_CARDS 0 + //------------------------------------------------------------------------------ + /** + * Call flush for endl if ENDL_CALLS_FLUSH is nonzero + * + * The standard for iostreams is to call flush. This is very costly for + * SdFat. Each call to flush causes 2048 bytes of I/O to the SD. + * + * SdFat has a single 512 byte buffer for SD I/O so it must write the current + * data block to the SD, read the directory block from the SD, update the + * directory entry, write the directory block to the SD and read the data + * block back into the buffer. + * + * The SD flash memory controller is not designed for this many rewrites + * so performance may be reduced by more than a factor of 100. + * + * If ENDL_CALLS_FLUSH is zero, you must call flush and/or close to force + * all data to be written to the SD. + */ + #define ENDL_CALLS_FLUSH 0 + //------------------------------------------------------------------------------ + /** + * Allow use of deprecated functions if ALLOW_DEPRECATED_FUNCTIONS is nonzero + */ + #define ALLOW_DEPRECATED_FUNCTIONS 1 + //------------------------------------------------------------------------------ + /** + * Allow FAT12 volumes if FAT12_SUPPORT is nonzero. + * FAT12 has not been well tested. + */ + #define FAT12_SUPPORT 0 + //------------------------------------------------------------------------------ + /** + * SPI init rate for SD initialization commands. Must be 5 (F_CPU/64) + * or 6 (F_CPU/128). + */ + #define SPI_SD_INIT_RATE 5 + //------------------------------------------------------------------------------ + /** + * Set the SS pin high for hardware SPI. If SS is chip select for another SPI + * device this will disable that device during the SD init phase. + */ + #define SET_SPI_SS_HIGH 1 + //------------------------------------------------------------------------------ + /** + * Define MEGA_SOFT_SPI nonzero to use software SPI on Mega Arduinos. + * Pins used are SS 10, MOSI 11, MISO 12, and SCK 13. + * + * MEGA_SOFT_SPI allows an unmodified Adafruit GPS Shield to be used + * on Mega Arduinos. Software SPI works well with GPS Shield V1.1 + * but many SD cards will fail with GPS Shield V1.0. + */ + #define MEGA_SOFT_SPI 0 + //------------------------------------------------------------------------------ + /** + * Set USE_SOFTWARE_SPI nonzero to always use software SPI. + */ + #define USE_SOFTWARE_SPI 0 + // define software SPI pins so Mega can use unmodified 168/328 shields + /** Software SPI chip select pin for the SD */ + #define SOFT_SPI_CS_PIN 10 + /** Software SPI Master Out Slave In pin */ + #define SOFT_SPI_MOSI_PIN 11 + /** Software SPI Master In Slave Out pin */ + #define SOFT_SPI_MISO_PIN 12 + /** Software SPI Clock pin */ + #define SOFT_SPI_SCK_PIN 13 + //------------------------------------------------------------------------------ + /** + * The __cxa_pure_virtual function is an error handler that is invoked when + * a pure virtual function is called. + */ + #define USE_CXA_PURE_VIRTUAL 1 + + /** Number of UTF-16 characters per entry */ + #define FILENAME_LENGTH 13 + + /** + * Defines for long (vfat) filenames + */ + /** Number of VFAT entries used. Every entry has 13 UTF-16 characters */ + #define MAX_VFAT_ENTRIES (2) + /** Total size of the buffer used to store the long filenames */ + #define LONG_FILENAME_LENGTH (FILENAME_LENGTH*MAX_VFAT_ENTRIES+1) +#endif // SdFatConfig_h + + +#endif diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/SdFatStructs.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/SdFatStructs.h new file mode 100644 index 00000000..3e989dea --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/SdFatStructs.h @@ -0,0 +1,655 @@ +/** + * 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 . + * + */ + +/** + * Arduino SdFat Library + * Copyright (C) 2009 by William Greiman + * + * This file is part of the Arduino Sd2Card Library + */ +#include "Marlin.h" +#if ENABLED(SDSUPPORT) + +#ifndef SdFatStructs_h +#define SdFatStructs_h + +#define PACKED __attribute__((__packed__)) +/** + * \file + * \brief FAT file structures + */ +/** + * mostly from Microsoft document fatgen103.doc + * http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx + */ +//------------------------------------------------------------------------------ +/** Value for byte 510 of boot block or MBR */ +uint8_t const BOOTSIG0 = 0X55; +/** Value for byte 511 of boot block or MBR */ +uint8_t const BOOTSIG1 = 0XAA; +/** Value for bootSignature field int FAT/FAT32 boot sector */ +uint8_t const EXTENDED_BOOT_SIG = 0X29; +//------------------------------------------------------------------------------ +/** + * \struct partitionTable + * \brief MBR partition table entry + * + * A partition table entry for a MBR formatted storage device. + * The MBR partition table has four entries. + */ +struct partitionTable { + /** + * Boot Indicator . Indicates whether the volume is the active + * partition. Legal values include: 0X00. Do not use for booting. + * 0X80 Active partition. + */ + uint8_t boot; + /** + * Head part of Cylinder-head-sector address of the first block in + * the partition. Legal values are 0-255. Only used in old PC BIOS. + */ + uint8_t beginHead; + /** + * Sector part of Cylinder-head-sector address of the first block in + * the partition. Legal values are 1-63. Only used in old PC BIOS. + */ + unsigned beginSector : 6; + /** High bits cylinder for first block in partition. */ + unsigned beginCylinderHigh : 2; + /** + * Combine beginCylinderLow with beginCylinderHigh. Legal values + * are 0-1023. Only used in old PC BIOS. + */ + uint8_t beginCylinderLow; + /** + * Partition type. See defines that begin with PART_TYPE_ for + * some Microsoft partition types. + */ + uint8_t type; + /** + * head part of cylinder-head-sector address of the last sector in the + * partition. Legal values are 0-255. Only used in old PC BIOS. + */ + uint8_t endHead; + /** + * Sector part of cylinder-head-sector address of the last sector in + * the partition. Legal values are 1-63. Only used in old PC BIOS. + */ + unsigned endSector : 6; + /** High bits of end cylinder */ + unsigned endCylinderHigh : 2; + /** + * Combine endCylinderLow with endCylinderHigh. Legal values + * are 0-1023. Only used in old PC BIOS. + */ + uint8_t endCylinderLow; + /** Logical block address of the first block in the partition. */ + uint32_t firstSector; + /** Length of the partition, in blocks. */ + uint32_t totalSectors; +} PACKED; +/** Type name for partitionTable */ +typedef struct partitionTable part_t; +//------------------------------------------------------------------------------ +/** + * \struct masterBootRecord + * + * \brief Master Boot Record + * + * The first block of a storage device that is formatted with a MBR. + */ +struct masterBootRecord { + /** Code Area for master boot program. */ + uint8_t codeArea[440]; + /** Optional Windows NT disk signature. May contain boot code. */ + uint32_t diskSignature; + /** Usually zero but may be more boot code. */ + uint16_t usuallyZero; + /** Partition tables. */ + part_t part[4]; + /** First MBR signature byte. Must be 0X55 */ + uint8_t mbrSig0; + /** Second MBR signature byte. Must be 0XAA */ + uint8_t mbrSig1; +} PACKED; +/** Type name for masterBootRecord */ +typedef struct masterBootRecord mbr_t; +//------------------------------------------------------------------------------ +/** + * \struct fat_boot + * + * \brief Boot sector for a FAT12/FAT16 volume. + * + */ +struct fat_boot { + /** + * The first three bytes of the boot sector must be valid, + * executable x 86-based CPU instructions. This includes a + * jump instruction that skips the next nonexecutable bytes. + */ + uint8_t jump[3]; + /** + * This is typically a string of characters that identifies + * the operating system that formatted the volume. + */ + char oemId[8]; + /** + * The size of a hardware sector. Valid decimal values for this + * field are 512, 1024, 2048, and 4096. For most disks used in + * the United States, the value of this field is 512. + */ + uint16_t bytesPerSector; + /** + * Number of sectors per allocation unit. This value must be a + * power of 2 that is greater than 0. The legal values are + * 1, 2, 4, 8, 16, 32, 64, and 128. 128 should be avoided. + */ + uint8_t sectorsPerCluster; + /** + * The number of sectors preceding the start of the first FAT, + * including the boot sector. The value of this field is always 1. + */ + uint16_t reservedSectorCount; + /** + * The number of copies of the FAT on the volume. + * The value of this field is always 2. + */ + uint8_t fatCount; + /** + * For FAT12 and FAT16 volumes, this field contains the count of + * 32-byte directory entries in the root directory. For FAT32 volumes, + * this field must be set to 0. For FAT12 and FAT16 volumes, this + * value should always specify a count that when multiplied by 32 + * results in a multiple of bytesPerSector. FAT16 volumes should + * use the value 512. + */ + uint16_t rootDirEntryCount; + /** + * This field is the old 16-bit total count of sectors on the volume. + * This count includes the count of all sectors in all four regions + * of the volume. This field can be 0; if it is 0, then totalSectors32 + * must be nonzero. For FAT32 volumes, this field must be 0. For + * FAT12 and FAT16 volumes, this field contains the sector count, and + * totalSectors32 is 0 if the total sector count fits + * (is less than 0x10000). + */ + uint16_t totalSectors16; + /** + * This dates back to the old MS-DOS 1.x media determination and is + * no longer usually used for anything. 0xF8 is the standard value + * for fixed (nonremovable) media. For removable media, 0xF0 is + * frequently used. Legal values are 0xF0 or 0xF8-0xFF. + */ + uint8_t mediaType; + /** + * Count of sectors occupied by one FAT on FAT12/FAT16 volumes. + * On FAT32 volumes this field must be 0, and sectorsPerFat32 + * contains the FAT size count. + */ + uint16_t sectorsPerFat16; + /** Sectors per track for interrupt 0x13. Not used otherwise. */ + uint16_t sectorsPerTrack; + /** Number of heads for interrupt 0x13. Not used otherwise. */ + uint16_t headCount; + /** + * Count of hidden sectors preceding the partition that contains this + * FAT volume. This field is generally only relevant for media + * visible on interrupt 0x13. + */ + uint32_t hidddenSectors; + /** + * This field is the new 32-bit total count of sectors on the volume. + * This count includes the count of all sectors in all four regions + * of the volume. This field can be 0; if it is 0, then + * totalSectors16 must be nonzero. + */ + uint32_t totalSectors32; + /** + * Related to the BIOS physical drive number. Floppy drives are + * identified as 0x00 and physical hard disks are identified as + * 0x80, regardless of the number of physical disk drives. + * Typically, this value is set prior to issuing an INT 13h BIOS + * call to specify the device to access. The value is only + * relevant if the device is a boot device. + */ + uint8_t driveNumber; + /** used by Windows NT - should be zero for FAT */ + uint8_t reserved1; + /** 0X29 if next three fields are valid */ + uint8_t bootSignature; + /** + * A random serial number created when formatting a disk, + * which helps to distinguish between disks. + * Usually generated by combining date and time. + */ + uint32_t volumeSerialNumber; + /** + * A field once used to store the volume label. The volume label + * is now stored as a special file in the root directory. + */ + char volumeLabel[11]; + /** + * A field with a value of either FAT, FAT12 or FAT16, + * depending on the disk format. + */ + char fileSystemType[8]; + /** X86 boot code */ + uint8_t bootCode[448]; + /** must be 0X55 */ + uint8_t bootSectorSig0; + /** must be 0XAA */ + uint8_t bootSectorSig1; +} PACKED; +/** Type name for FAT Boot Sector */ +typedef struct fat_boot fat_boot_t; +//------------------------------------------------------------------------------ +/** + * \struct fat32_boot + * + * \brief Boot sector for a FAT32 volume. + * + */ +struct fat32_boot { + /** + * The first three bytes of the boot sector must be valid, + * executable x 86-based CPU instructions. This includes a + * jump instruction that skips the next nonexecutable bytes. + */ + uint8_t jump[3]; + /** + * This is typically a string of characters that identifies + * the operating system that formatted the volume. + */ + char oemId[8]; + /** + * The size of a hardware sector. Valid decimal values for this + * field are 512, 1024, 2048, and 4096. For most disks used in + * the United States, the value of this field is 512. + */ + uint16_t bytesPerSector; + /** + * Number of sectors per allocation unit. This value must be a + * power of 2 that is greater than 0. The legal values are + * 1, 2, 4, 8, 16, 32, 64, and 128. 128 should be avoided. + */ + uint8_t sectorsPerCluster; + /** + * The number of sectors preceding the start of the first FAT, + * including the boot sector. Must not be zero + */ + uint16_t reservedSectorCount; + /** + * The number of copies of the FAT on the volume. + * The value of this field is always 2. + */ + uint8_t fatCount; + /** + * FAT12/FAT16 only. For FAT32 volumes, this field must be set to 0. + */ + uint16_t rootDirEntryCount; + /** + * For FAT32 volumes, this field must be 0. + */ + uint16_t totalSectors16; + /** + * This dates back to the old MS-DOS 1.x media determination and is + * no longer usually used for anything. 0xF8 is the standard value + * for fixed (nonremovable) media. For removable media, 0xF0 is + * frequently used. Legal values are 0xF0 or 0xF8-0xFF. + */ + uint8_t mediaType; + /** + * On FAT32 volumes this field must be 0, and sectorsPerFat32 + * contains the FAT size count. + */ + uint16_t sectorsPerFat16; + /** Sectors per track for interrupt 0x13. Not used otherwise. */ + uint16_t sectorsPerTrack; + /** Number of heads for interrupt 0x13. Not used otherwise. */ + uint16_t headCount; + /** + * Count of hidden sectors preceding the partition that contains this + * FAT volume. This field is generally only relevant for media + * visible on interrupt 0x13. + */ + uint32_t hidddenSectors; + /** + * Contains the total number of sectors in the FAT32 volume. + */ + uint32_t totalSectors32; + /** + * Count of sectors occupied by one FAT on FAT32 volumes. + */ + uint32_t sectorsPerFat32; + /** + * This field is only defined for FAT32 media and does not exist on + * FAT12 and FAT16 media. + * Bits 0-3 -- Zero-based number of active FAT. + * Only valid if mirroring is disabled. + * Bits 4-6 -- Reserved. + * Bit 7 -- 0 means the FAT is mirrored at runtime into all FATs. + * -- 1 means only one FAT is active; it is the one referenced + * in bits 0-3. + * Bits 8-15 -- Reserved. + */ + uint16_t fat32Flags; + /** + * FAT32 version. High byte is major revision number. + * Low byte is minor revision number. Only 0.0 define. + */ + uint16_t fat32Version; + /** + * Cluster number of the first cluster of the root directory for FAT32. + * This usually 2 but not required to be 2. + */ + uint32_t fat32RootCluster; + /** + * Sector number of FSINFO structure in the reserved area of the + * FAT32 volume. Usually 1. + */ + uint16_t fat32FSInfo; + /** + * If nonzero, indicates the sector number in the reserved area + * of the volume of a copy of the boot record. Usually 6. + * No value other than 6 is recommended. + */ + uint16_t fat32BackBootBlock; + /** + * Reserved for future expansion. Code that formats FAT32 volumes + * should always set all of the bytes of this field to 0. + */ + uint8_t fat32Reserved[12]; + /** + * Related to the BIOS physical drive number. Floppy drives are + * identified as 0x00 and physical hard disks are identified as + * 0x80, regardless of the number of physical disk drives. + * Typically, this value is set prior to issuing an INT 13h BIOS + * call to specify the device to access. The value is only + * relevant if the device is a boot device. + */ + uint8_t driveNumber; + /** used by Windows NT - should be zero for FAT */ + uint8_t reserved1; + /** 0X29 if next three fields are valid */ + uint8_t bootSignature; + /** + * A random serial number created when formatting a disk, + * which helps to distinguish between disks. + * Usually generated by combining date and time. + */ + uint32_t volumeSerialNumber; + /** + * A field once used to store the volume label. The volume label + * is now stored as a special file in the root directory. + */ + char volumeLabel[11]; + /** + * A text field with a value of FAT32. + */ + char fileSystemType[8]; + /** X86 boot code */ + uint8_t bootCode[420]; + /** must be 0X55 */ + uint8_t bootSectorSig0; + /** must be 0XAA */ + uint8_t bootSectorSig1; +} PACKED; +/** Type name for FAT32 Boot Sector */ +typedef struct fat32_boot fat32_boot_t; +//------------------------------------------------------------------------------ +/** Lead signature for a FSINFO sector */ +uint32_t const FSINFO_LEAD_SIG = 0x41615252; +/** Struct signature for a FSINFO sector */ +uint32_t const FSINFO_STRUCT_SIG = 0x61417272; +/** + * \struct fat32_fsinfo + * + * \brief FSINFO sector for a FAT32 volume. + * + */ +struct fat32_fsinfo { + /** must be 0X52, 0X52, 0X61, 0X41 */ + uint32_t leadSignature; + /** must be zero */ + uint8_t reserved1[480]; + /** must be 0X72, 0X72, 0X41, 0X61 */ + uint32_t structSignature; + /** + * Contains the last known free cluster count on the volume. + * If the value is 0xFFFFFFFF, then the free count is unknown + * and must be computed. Any other value can be used, but is + * not necessarily correct. It should be range checked at least + * to make sure it is <= volume cluster count. + */ + uint32_t freeCount; + /** + * This is a hint for the FAT driver. It indicates the cluster + * number at which the driver should start looking for free clusters. + * If the value is 0xFFFFFFFF, then there is no hint and the driver + * should start looking at cluster 2. + */ + uint32_t nextFree; + /** must be zero */ + uint8_t reserved2[12]; + /** must be 0X00, 0X00, 0X55, 0XAA */ + uint8_t tailSignature[4]; +} PACKED; +/** Type name for FAT32 FSINFO Sector */ +typedef struct fat32_fsinfo fat32_fsinfo_t; +//------------------------------------------------------------------------------ +// End Of Chain values for FAT entries +/** FAT12 end of chain value used by Microsoft. */ +uint16_t const FAT12EOC = 0XFFF; +/** Minimum value for FAT12 EOC. Use to test for EOC. */ +uint16_t const FAT12EOC_MIN = 0XFF8; +/** FAT16 end of chain value used by Microsoft. */ +uint16_t const FAT16EOC = 0XFFFF; +/** Minimum value for FAT16 EOC. Use to test for EOC. */ +uint16_t const FAT16EOC_MIN = 0XFFF8; +/** FAT32 end of chain value used by Microsoft. */ +uint32_t const FAT32EOC = 0X0FFFFFFF; +/** Minimum value for FAT32 EOC. Use to test for EOC. */ +uint32_t const FAT32EOC_MIN = 0X0FFFFFF8; +/** Mask a for FAT32 entry. Entries are 28 bits. */ +uint32_t const FAT32MASK = 0X0FFFFFFF; +//------------------------------------------------------------------------------ +/** + * \struct directoryEntry + * \brief FAT short directory entry + * + * Short means short 8.3 name, not the entry size. + * + * Date Format. A FAT directory entry date stamp is a 16-bit field that is + * basically a date relative to the MS-DOS epoch of 01/01/1980. Here is the + * format (bit 0 is the LSB of the 16-bit word, bit 15 is the MSB of the + * 16-bit word): + * + * Bits 9-15: Count of years from 1980, valid value range 0-127 + * inclusive (1980-2107). + * + * Bits 5-8: Month of year, 1 = January, valid value range 1-12 inclusive. + * + * Bits 0-4: Day of month, valid value range 1-31 inclusive. + * + * Time Format. A FAT directory entry time stamp is a 16-bit field that has + * a granularity of 2 seconds. Here is the format (bit 0 is the LSB of the + * 16-bit word, bit 15 is the MSB of the 16-bit word). + * + * Bits 11-15: Hours, valid value range 0-23 inclusive. + * + * Bits 5-10: Minutes, valid value range 0-59 inclusive. + * + * Bits 0-4: 2-second count, valid value range 0-29 inclusive (0 - 58 seconds). + * + * The valid time range is from Midnight 00:00:00 to 23:59:58. + */ +struct directoryEntry { + /** Short 8.3 name. + * + * The first eight bytes contain the file name with blank fill. + * The last three bytes contain the file extension with blank fill. + */ + uint8_t name[11]; + /** Entry attributes. + * + * The upper two bits of the attribute byte are reserved and should + * always be set to 0 when a file is created and never modified or + * looked at after that. See defines that begin with DIR_ATT_. + */ + uint8_t attributes; + /** + * Reserved for use by Windows NT. Set value to 0 when a file is + * created and never modify or look at it after that. + */ + uint8_t reservedNT; + /** + * The granularity of the seconds part of creationTime is 2 seconds + * so this field is a count of tenths of a second and its valid + * value range is 0-199 inclusive. (WHG note - seems to be hundredths) + */ + uint8_t creationTimeTenths; + /** Time file was created. */ + uint16_t creationTime; + /** Date file was created. */ + uint16_t creationDate; + /** + * Last access date. Note that there is no last access time, only + * a date. This is the date of last read or write. In the case of + * a write, this should be set to the same date as lastWriteDate. + */ + uint16_t lastAccessDate; + /** + * High word of this entry's first cluster number (always 0 for a + * FAT12 or FAT16 volume). + */ + uint16_t firstClusterHigh; + /** Time of last write. File creation is considered a write. */ + uint16_t lastWriteTime; + /** Date of last write. File creation is considered a write. */ + uint16_t lastWriteDate; + /** Low word of this entry's first cluster number. */ + uint16_t firstClusterLow; + /** 32-bit unsigned holding this file's size in bytes. */ + uint32_t fileSize; +} PACKED; +/** + * \struct directoryVFATEntry + * \brief VFAT long filename directory entry + * + * directoryVFATEntries are found in the same list as normal directoryEntry. + * But have the attribute field set to DIR_ATT_LONG_NAME. + * + * Long filenames are saved in multiple directoryVFATEntries. + * Each entry containing 13 UTF-16 characters. + */ +struct directoryVFATEntry { + /** + * Sequence number. Consists of 2 parts: + * bit 6: indicates first long filename block for the next file + * bit 0-4: the position of this long filename block (first block is 1) + */ + uint8_t sequenceNumber; + /** First set of UTF-16 characters */ + uint16_t name1[5];//UTF-16 + /** attributes (at the same location as in directoryEntry), always 0x0F */ + uint8_t attributes; + /** Reserved for use by Windows NT. Always 0. */ + uint8_t reservedNT; + /** Checksum of the short 8.3 filename, can be used to checked if the file system as modified by a not-long-filename aware implementation. */ + uint8_t checksum; + /** Second set of UTF-16 characters */ + uint16_t name2[6];//UTF-16 + /** firstClusterLow is always zero for longFilenames */ + uint16_t firstClusterLow; + /** Third set of UTF-16 characters */ + uint16_t name3[2];//UTF-16 +} PACKED; +//------------------------------------------------------------------------------ +// Definitions for directory entries +// +/** Type name for directoryEntry */ +typedef struct directoryEntry dir_t; +/** Type name for directoryVFATEntry */ +typedef struct directoryVFATEntry vfat_t; +/** escape for name[0] = 0XE5 */ +uint8_t const DIR_NAME_0XE5 = 0X05; +/** name[0] value for entry that is free after being "deleted" */ +uint8_t const DIR_NAME_DELETED = 0XE5; +/** name[0] value for entry that is free and no allocated entries follow */ +uint8_t const DIR_NAME_FREE = 0X00; +/** file is read-only */ +uint8_t const DIR_ATT_READ_ONLY = 0X01; +/** File should hidden in directory listings */ +uint8_t const DIR_ATT_HIDDEN = 0X02; +/** Entry is for a system file */ +uint8_t const DIR_ATT_SYSTEM = 0X04; +/** Directory entry contains the volume label */ +uint8_t const DIR_ATT_VOLUME_ID = 0X08; +/** Entry is for a directory */ +uint8_t const DIR_ATT_DIRECTORY = 0X10; +/** Old DOS archive bit for backup support */ +uint8_t const DIR_ATT_ARCHIVE = 0X20; +/** Test value for long name entry. Test is + (d->attributes & DIR_ATT_LONG_NAME_MASK) == DIR_ATT_LONG_NAME. */ +uint8_t const DIR_ATT_LONG_NAME = 0X0F; +/** Test mask for long name entry */ +uint8_t const DIR_ATT_LONG_NAME_MASK = 0X3F; +/** defined attribute bits */ +uint8_t const DIR_ATT_DEFINED_BITS = 0X3F; +/** Directory entry is part of a long name + * \param[in] dir Pointer to a directory entry. + * + * \return true if the entry is for part of a long name else false. + */ +static inline uint8_t DIR_IS_LONG_NAME(const dir_t* dir) { + return (dir->attributes & DIR_ATT_LONG_NAME_MASK) == DIR_ATT_LONG_NAME; +} +/** Mask for file/subdirectory tests */ +uint8_t const DIR_ATT_FILE_TYPE_MASK = (DIR_ATT_VOLUME_ID | DIR_ATT_DIRECTORY); +/** Directory entry is for a file + * \param[in] dir Pointer to a directory entry. + * + * \return true if the entry is for a normal file else false. + */ +static inline uint8_t DIR_IS_FILE(const dir_t* dir) { + return (dir->attributes & DIR_ATT_FILE_TYPE_MASK) == 0; +} +/** Directory entry is for a subdirectory + * \param[in] dir Pointer to a directory entry. + * + * \return true if the entry is for a subdirectory else false. + */ +static inline uint8_t DIR_IS_SUBDIR(const dir_t* dir) { + return (dir->attributes & DIR_ATT_FILE_TYPE_MASK) == DIR_ATT_DIRECTORY; +} +/** Directory entry is for a file or subdirectory + * \param[in] dir Pointer to a directory entry. + * + * \return true if the entry is for a normal file or subdirectory else false. + */ +static inline uint8_t DIR_IS_FILE_OR_SUBDIR(const dir_t* dir) { + return (dir->attributes & DIR_ATT_VOLUME_ID) == 0; +} +#endif // SdFatStructs_h + + +#endif diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/SdFatUtil.cpp b/trunk/Arduino/Marlin_K8600_1.1.0RC7/SdFatUtil.cpp new file mode 100644 index 00000000..48d91df6 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/SdFatUtil.cpp @@ -0,0 +1,91 @@ +/** + * 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 . + * + */ + +/** + * Arduino SdFat Library + * Copyright (C) 2008 by William Greiman + * + * This file is part of the Arduino Sd2Card Library + */ +#include "Marlin.h" + +#if ENABLED(SDSUPPORT) +#include "SdFatUtil.h" + +//------------------------------------------------------------------------------ +/** Amount of free RAM + * \return The number of free bytes. + */ +#ifdef __arm__ +extern "C" char* sbrk(int incr); +int SdFatUtil::FreeRam() { + char top; + return &top - reinterpret_cast(sbrk(0)); +} +#else // __arm__ +extern char* __brkval; +extern char __bss_end; +/** Amount of free RAM + * \return The number of free bytes. + */ +int SdFatUtil::FreeRam() { + char top; + return __brkval ? &top - __brkval : &top - &__bss_end; +} +#endif // __arm + +//------------------------------------------------------------------------------ +/** %Print a string in flash memory. + * + * \param[in] pr Print object for output. + * \param[in] str Pointer to string stored in flash memory. + */ +void SdFatUtil::print_P(PGM_P str) { + for (uint8_t c; (c = pgm_read_byte(str)); str++) MYSERIAL.write(c); +} +//------------------------------------------------------------------------------ +/** %Print a string in flash memory followed by a CR/LF. + * + * \param[in] pr Print object for output. + * \param[in] str Pointer to string stored in flash memory. + */ +void SdFatUtil::println_P(PGM_P str) { + print_P(str); + MYSERIAL.println(); +} +//------------------------------------------------------------------------------ +/** %Print a string in flash memory to Serial. + * + * \param[in] str Pointer to string stored in flash memory. + */ +void SdFatUtil::SerialPrint_P(PGM_P str) { + print_P(str); +} +//------------------------------------------------------------------------------ +/** %Print a string in flash memory to Serial followed by a CR/LF. + * + * \param[in] str Pointer to string stored in flash memory. + */ +void SdFatUtil::SerialPrintln_P(PGM_P str) { + println_P(str); +} +#endif diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/SdFatUtil.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/SdFatUtil.h new file mode 100644 index 00000000..9db81ac5 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/SdFatUtil.h @@ -0,0 +1,57 @@ +/** + * 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 . + * + */ + +/** + * Arduino SdFat Library + * Copyright (C) 2008 by William Greiman + * + * This file is part of the Arduino Sd2Card Library + */ +#include "Marlin.h" +#if ENABLED(SDSUPPORT) + +#ifndef SdFatUtil_h +#define SdFatUtil_h +/** + * \file + * \brief Useful utility functions. + */ +#include "Marlin.h" +#include "MarlinSerial.h" +/** Store and print a string in flash memory.*/ +#define PgmPrint(x) SerialPrint_P(PSTR(x)) +/** Store and print a string in flash memory followed by a CR/LF.*/ +#define PgmPrintln(x) SerialPrintln_P(PSTR(x)) + +namespace SdFatUtil { + int FreeRam(); + void print_P(PGM_P str); + void println_P(PGM_P str); + void SerialPrint_P(PGM_P str); + void SerialPrintln_P(PGM_P str); +} + +using namespace SdFatUtil; // NOLINT +#endif //#define SdFatUtil_h + + +#endif diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/SdFile.cpp b/trunk/Arduino/Marlin_K8600_1.1.0RC7/SdFile.cpp new file mode 100644 index 00000000..fc66f417 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/SdFile.cpp @@ -0,0 +1,102 @@ +/** + * 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 . + * + */ + +/** + * Arduino SdFat Library + * Copyright (C) 2009 by William Greiman + * + * This file is part of the Arduino Sd2Card Library + */ +#include "Marlin.h" + +#if ENABLED(SDSUPPORT) +#include "SdFile.h" +/** Create a file object and open it in the current working directory. + * + * \param[in] path A path with a valid 8.3 DOS name for a file to be opened. + * + * \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive + * OR of open flags. see SdBaseFile::open(SdBaseFile*, const char*, uint8_t). + */ +SdFile::SdFile(const char* path, uint8_t oflag) : SdBaseFile(path, oflag) { +} +//------------------------------------------------------------------------------ +/** Write data to an open file. + * + * \note Data is moved to the cache but may not be written to the + * storage device until sync() is called. + * + * \param[in] buf Pointer to the location of the data to be written. + * + * \param[in] nbyte Number of bytes to write. + * + * \return For success write() returns the number of bytes written, always + * \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); +} +//------------------------------------------------------------------------------ +/** Write a byte to a file. Required by the Arduino Print class. + * \param[in] b the byte to be written. + * Use writeError to check for errors. + */ +#if ARDUINO >= 100 + size_t SdFile::write(uint8_t b) { + return SdBaseFile::write(&b, 1); + } +#else + void SdFile::write(uint8_t b) { + SdBaseFile::write(&b, 1); + } +#endif +//------------------------------------------------------------------------------ +/** Write a string to a file. Used by the Arduino Print class. + * \param[in] str Pointer to the string. + * Use writeError to check for errors. + */ +void SdFile::write(const char* str) { + SdBaseFile::write(str, strlen(str)); +} +//------------------------------------------------------------------------------ +/** Write a PROGMEM string to a file. + * \param[in] str Pointer to the PROGMEM string. + * Use writeError to check for errors. + */ +void SdFile::write_P(PGM_P str) { + for (uint8_t c; (c = pgm_read_byte(str)); str++) write(c); +} +//------------------------------------------------------------------------------ +/** Write a PROGMEM string followed by CR/LF to a file. + * \param[in] str Pointer to the PROGMEM string. + * Use writeError to check for errors. + */ +void SdFile::writeln_P(PGM_P str) { + write_P(str); + write_P(PSTR("\r\n")); +} + + +#endif diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/SdFile.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/SdFile.h new file mode 100644 index 00000000..53f38255 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/SdFile.h @@ -0,0 +1,63 @@ +/** + * 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 . + * + */ + +/** + * Arduino SdFat Library + * Copyright (C) 2009 by William Greiman + * + * This file is part of the Arduino Sd2Card Library + */ +/** + * \file + * \brief SdFile class + */ +#include "Marlin.h" + +#if ENABLED(SDSUPPORT) +#include "SdBaseFile.h" +#include +#ifndef SdFile_h +#define SdFile_h +//------------------------------------------------------------------------------ +/** + * \class SdFile + * \brief SdBaseFile with Print. + */ +class SdFile : public SdBaseFile, public Print { + public: + SdFile() {} + SdFile(const char* name, uint8_t oflag); + #if ARDUINO >= 100 + size_t write(uint8_t b); + #else + void write(uint8_t b); + #endif + + int16_t write(const void* buf, uint16_t nbyte); + void write(const char* str); + void write_P(PGM_P str); + void writeln_P(PGM_P str); +}; +#endif // SdFile_h + + +#endif diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/SdInfo.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/SdInfo.h new file mode 100644 index 00000000..f4b36b7a --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/SdInfo.h @@ -0,0 +1,289 @@ +/** + * 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 . + * + */ + +/** + * Arduino Sd2Card Library + * Copyright (C) 2009 by William Greiman + * + * This file is part of the Arduino Sd2Card Library + */ +#include "Marlin.h" +#if ENABLED(SDSUPPORT) + +#ifndef SdInfo_h +#define SdInfo_h +#include +// Based on the document: +// +// SD Specifications +// Part 1 +// Physical Layer +// Simplified Specification +// Version 3.01 +// May 18, 2010 +// +// http://www.sdcard.org/developers/tech/sdcard/pls/simplified_specs +//------------------------------------------------------------------------------ +// SD card commands +/** GO_IDLE_STATE - init card in spi mode if CS low */ +uint8_t const CMD0 = 0X00; +/** SEND_IF_COND - verify SD Memory Card interface operating condition.*/ +uint8_t const CMD8 = 0X08; +/** SEND_CSD - read the Card Specific Data (CSD register) */ +uint8_t const CMD9 = 0X09; +/** SEND_CID - read the card identification information (CID register) */ +uint8_t const CMD10 = 0X0A; +/** STOP_TRANSMISSION - end multiple block read sequence */ +uint8_t const CMD12 = 0X0C; +/** SEND_STATUS - read the card status register */ +uint8_t const CMD13 = 0X0D; +/** READ_SINGLE_BLOCK - read a single data block from the card */ +uint8_t const CMD17 = 0X11; +/** READ_MULTIPLE_BLOCK - read a multiple data blocks from the card */ +uint8_t const CMD18 = 0X12; +/** WRITE_BLOCK - write a single data block to the card */ +uint8_t const CMD24 = 0X18; +/** WRITE_MULTIPLE_BLOCK - write blocks of data until a STOP_TRANSMISSION */ +uint8_t const CMD25 = 0X19; +/** ERASE_WR_BLK_START - sets the address of the first block to be erased */ +uint8_t const CMD32 = 0X20; +/** ERASE_WR_BLK_END - sets the address of the last block of the continuous + range to be erased*/ +uint8_t const CMD33 = 0X21; +/** ERASE - erase all previously selected blocks */ +uint8_t const CMD38 = 0X26; +/** APP_CMD - escape for application specific command */ +uint8_t const CMD55 = 0X37; +/** READ_OCR - read the OCR register of a card */ +uint8_t const CMD58 = 0X3A; +/** SET_WR_BLK_ERASE_COUNT - Set the number of write blocks to be + pre-erased before writing */ +uint8_t const ACMD23 = 0X17; +/** SD_SEND_OP_COMD - Sends host capacity support information and + activates the card's initialization process */ +uint8_t const ACMD41 = 0X29; +//------------------------------------------------------------------------------ +/** status for card in the ready state */ +uint8_t const R1_READY_STATE = 0X00; +/** status for card in the idle state */ +uint8_t const R1_IDLE_STATE = 0X01; +/** status bit for illegal command */ +uint8_t const R1_ILLEGAL_COMMAND = 0X04; +/** start data token for read or write single block*/ +uint8_t const DATA_START_BLOCK = 0XFE; +/** stop token for write multiple blocks*/ +uint8_t const STOP_TRAN_TOKEN = 0XFD; +/** start data token for write multiple blocks*/ +uint8_t const WRITE_MULTIPLE_TOKEN = 0XFC; +/** mask for data response tokens after a write block operation */ +uint8_t const DATA_RES_MASK = 0X1F; +/** write data accepted token */ +uint8_t const DATA_RES_ACCEPTED = 0X05; +//------------------------------------------------------------------------------ +/** Card IDentification (CID) register */ +typedef struct CID { + // byte 0 + /** Manufacturer ID */ + unsigned char mid; + // byte 1-2 + /** OEM/Application ID */ + char oid[2]; + // byte 3-7 + /** Product name */ + char pnm[5]; + // byte 8 + /** Product revision least significant digit */ + unsigned char prv_m : 4; + /** Product revision most significant digit */ + unsigned char prv_n : 4; + // byte 9-12 + /** Product serial number */ + uint32_t psn; + // byte 13 + /** Manufacturing date year low digit */ + unsigned char mdt_year_high : 4; + /** not used */ + unsigned char reserved : 4; + // byte 14 + /** Manufacturing date month */ + unsigned char mdt_month : 4; + /** Manufacturing date year low digit */ + unsigned char mdt_year_low : 4; + // byte 15 + /** not used always 1 */ + unsigned char always1 : 1; + /** CRC7 checksum */ + unsigned char crc : 7; +} cid_t; +//------------------------------------------------------------------------------ +/** CSD for version 1.00 cards */ +typedef struct CSDV1 { + // byte 0 + unsigned char reserved1 : 6; + unsigned char csd_ver : 2; + // byte 1 + unsigned char taac; + // byte 2 + unsigned char nsac; + // byte 3 + unsigned char tran_speed; + // byte 4 + unsigned char ccc_high; + // byte 5 + unsigned char read_bl_len : 4; + unsigned char ccc_low : 4; + // byte 6 + unsigned char c_size_high : 2; + unsigned char reserved2 : 2; + unsigned char dsr_imp : 1; + unsigned char read_blk_misalign : 1; + unsigned char write_blk_misalign : 1; + unsigned char read_bl_partial : 1; + // byte 7 + unsigned char c_size_mid; + // byte 8 + unsigned char vdd_r_curr_max : 3; + unsigned char vdd_r_curr_min : 3; + unsigned char c_size_low : 2; + // byte 9 + unsigned char c_size_mult_high : 2; + unsigned char vdd_w_cur_max : 3; + unsigned char vdd_w_curr_min : 3; + // byte 10 + unsigned char sector_size_high : 6; + unsigned char erase_blk_en : 1; + unsigned char c_size_mult_low : 1; + // byte 11 + unsigned char wp_grp_size : 7; + unsigned char sector_size_low : 1; + // byte 12 + unsigned char write_bl_len_high : 2; + unsigned char r2w_factor : 3; + unsigned char reserved3 : 2; + unsigned char wp_grp_enable : 1; + // byte 13 + unsigned char reserved4 : 5; + unsigned char write_partial : 1; + unsigned char write_bl_len_low : 2; + // byte 14 + unsigned char reserved5: 2; + unsigned char file_format : 2; + unsigned char tmp_write_protect : 1; + unsigned char perm_write_protect : 1; + unsigned char copy : 1; + /** Indicates the file format on the card */ + unsigned char file_format_grp : 1; + // byte 15 + unsigned char always1 : 1; + unsigned char crc : 7; +} csd1_t; +//------------------------------------------------------------------------------ +/** CSD for version 2.00 cards */ +typedef struct CSDV2 { + // byte 0 + unsigned char reserved1 : 6; + unsigned char csd_ver : 2; + // byte 1 + /** fixed to 0X0E */ + unsigned char taac; + // byte 2 + /** fixed to 0 */ + unsigned char nsac; + // byte 3 + unsigned char tran_speed; + // byte 4 + unsigned char ccc_high; + // byte 5 + /** This field is fixed to 9h, which indicates READ_BL_LEN=512 Byte */ + unsigned char read_bl_len : 4; + unsigned char ccc_low : 4; + // byte 6 + /** not used */ + unsigned char reserved2 : 4; + unsigned char dsr_imp : 1; + /** fixed to 0 */ + unsigned char read_blk_misalign : 1; + /** fixed to 0 */ + unsigned char write_blk_misalign : 1; + /** fixed to 0 - no partial read */ + unsigned char read_bl_partial : 1; + // byte 7 + /** not used */ + unsigned char reserved3 : 2; + /** high part of card size */ + unsigned char c_size_high : 6; + // byte 8 + /** middle part of card size */ + unsigned char c_size_mid; + // byte 9 + /** low part of card size */ + unsigned char c_size_low; + // byte 10 + /** sector size is fixed at 64 KB */ + unsigned char sector_size_high : 6; + /** fixed to 1 - erase single is supported */ + unsigned char erase_blk_en : 1; + /** not used */ + unsigned char reserved4 : 1; + // byte 11 + unsigned char wp_grp_size : 7; + /** sector size is fixed at 64 KB */ + unsigned char sector_size_low : 1; + // byte 12 + /** write_bl_len fixed for 512 byte blocks */ + unsigned char write_bl_len_high : 2; + /** fixed value of 2 */ + unsigned char r2w_factor : 3; + /** not used */ + unsigned char reserved5 : 2; + /** fixed value of 0 - no write protect groups */ + unsigned char wp_grp_enable : 1; + // byte 13 + unsigned char reserved6 : 5; + /** always zero - no partial block read*/ + unsigned char write_partial : 1; + /** write_bl_len fixed for 512 byte blocks */ + unsigned char write_bl_len_low : 2; + // byte 14 + unsigned char reserved7: 2; + /** Do not use always 0 */ + unsigned char file_format : 2; + unsigned char tmp_write_protect : 1; + unsigned char perm_write_protect : 1; + unsigned char copy : 1; + /** Do not use always 0 */ + unsigned char file_format_grp : 1; + // byte 15 + /** not used always 1 */ + unsigned char always1 : 1; + /** checksum */ + unsigned char crc : 7; +} csd2_t; +//------------------------------------------------------------------------------ +/** union of old and new style CSD register */ +union csd_t { + csd1_t v1; + csd2_t v2; +}; +#endif // SdInfo_h + +#endif diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/SdVolume.cpp b/trunk/Arduino/Marlin_K8600_1.1.0RC7/SdVolume.cpp new file mode 100644 index 00000000..4166c066 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/SdVolume.cpp @@ -0,0 +1,420 @@ +/** + * 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 . + * + */ + +/** + * Arduino SdFat Library + * Copyright (C) 2009 by William Greiman + * + * This file is part of the Arduino Sd2Card Library + */ +#include "Marlin.h" +#if ENABLED(SDSUPPORT) + +#include "SdVolume.h" +//------------------------------------------------------------------------------ +#if !USE_MULTIPLE_CARDS + // raw block cache + uint32_t SdVolume::cacheBlockNumber_; // current block number + cache_t SdVolume::cacheBuffer_; // 512 byte cache for Sd2Card + Sd2Card* SdVolume::sdCard_; // pointer to SD card object + bool SdVolume::cacheDirty_; // cacheFlush() will write block if true + uint32_t SdVolume::cacheMirrorBlock_; // mirror block for second FAT +#endif // USE_MULTIPLE_CARDS +//------------------------------------------------------------------------------ +// find a contiguous group of clusters +bool SdVolume::allocContiguous(uint32_t count, uint32_t* curCluster) { + // start of group + uint32_t bgnCluster; + // end of group + uint32_t endCluster; + // last cluster of FAT + uint32_t fatEnd = clusterCount_ + 1; + + // flag to save place to start next search + bool setStart; + + // set search start cluster + if (*curCluster) { + // try to make file contiguous + bgnCluster = *curCluster + 1; + + // don't save new start location + setStart = false; + } + else { + // start at likely place for free cluster + bgnCluster = allocSearchStart_; + + // save next search start if one cluster + setStart = count == 1; + } + // end of group + endCluster = bgnCluster; + + // search the FAT for free clusters + for (uint32_t n = 0;; n++, endCluster++) { + // can't find space checked all clusters + if (n >= clusterCount_) goto fail; + + // past end - start from beginning of FAT + if (endCluster > fatEnd) { + bgnCluster = endCluster = 2; + } + uint32_t f; + if (!fatGet(endCluster, &f)) goto fail; + + if (f != 0) { + // cluster in use try next cluster as bgnCluster + bgnCluster = endCluster + 1; + } + else if ((endCluster - bgnCluster + 1) == count) { + // done - found space + break; + } + } + // mark end of chain + if (!fatPutEOC(endCluster)) goto fail; + + // link clusters + while (endCluster > bgnCluster) { + if (!fatPut(endCluster - 1, endCluster)) goto fail; + endCluster--; + } + if (*curCluster != 0) { + // connect chains + if (!fatPut(*curCluster, bgnCluster)) goto fail; + } + // return first cluster number to caller + *curCluster = bgnCluster; + + // remember possible next free cluster + if (setStart) allocSearchStart_ = bgnCluster + 1; + + return true; +fail: + return false; +} +//------------------------------------------------------------------------------ +bool SdVolume::cacheFlush() { + if (cacheDirty_) { + if (!sdCard_->writeBlock(cacheBlockNumber_, cacheBuffer_.data)) { + goto fail; + } + // mirror FAT tables + if (cacheMirrorBlock_) { + if (!sdCard_->writeBlock(cacheMirrorBlock_, cacheBuffer_.data)) { + goto fail; + } + cacheMirrorBlock_ = 0; + } + cacheDirty_ = 0; + } + return true; +fail: + return false; +} +//------------------------------------------------------------------------------ +bool SdVolume::cacheRawBlock(uint32_t blockNumber, bool dirty) { + if (cacheBlockNumber_ != blockNumber) { + if (!cacheFlush()) goto fail; + if (!sdCard_->readBlock(blockNumber, cacheBuffer_.data)) goto fail; + cacheBlockNumber_ = blockNumber; + } + if (dirty) cacheDirty_ = true; + return true; +fail: + return false; +} +//------------------------------------------------------------------------------ +// return the size in bytes of a cluster chain +bool SdVolume::chainSize(uint32_t cluster, uint32_t* size) { + uint32_t s = 0; + do { + if (!fatGet(cluster, &cluster)) goto fail; + s += 512UL << clusterSizeShift_; + } while (!isEOC(cluster)); + *size = s; + return true; +fail: + return false; +} +//------------------------------------------------------------------------------ +// Fetch a FAT entry +bool SdVolume::fatGet(uint32_t cluster, uint32_t* value) { + uint32_t lba; + if (cluster > (clusterCount_ + 1)) goto fail; + if (FAT12_SUPPORT && fatType_ == 12) { + uint16_t index = cluster; + index += index >> 1; + lba = fatStartBlock_ + (index >> 9); + if (!cacheRawBlock(lba, CACHE_FOR_READ)) goto fail; + index &= 0X1FF; + uint16_t tmp = cacheBuffer_.data[index]; + index++; + if (index == 512) { + if (!cacheRawBlock(lba + 1, CACHE_FOR_READ)) goto fail; + index = 0; + } + tmp |= cacheBuffer_.data[index] << 8; + *value = cluster & 1 ? tmp >> 4 : tmp & 0XFFF; + return true; + } + if (fatType_ == 16) { + lba = fatStartBlock_ + (cluster >> 8); + } + else if (fatType_ == 32) { + lba = fatStartBlock_ + (cluster >> 7); + } + else { + goto fail; + } + if (lba != cacheBlockNumber_) { + if (!cacheRawBlock(lba, CACHE_FOR_READ)) goto fail; + } + if (fatType_ == 16) { + *value = cacheBuffer_.fat16[cluster & 0XFF]; + } + else { + *value = cacheBuffer_.fat32[cluster & 0X7F] & FAT32MASK; + } + return true; +fail: + return false; +} +//------------------------------------------------------------------------------ +// Store a FAT entry +bool SdVolume::fatPut(uint32_t cluster, uint32_t value) { + uint32_t lba; + // error if reserved cluster + if (cluster < 2) goto fail; + + // error if not in FAT + if (cluster > (clusterCount_ + 1)) goto fail; + + if (FAT12_SUPPORT && fatType_ == 12) { + uint16_t index = cluster; + index += index >> 1; + lba = fatStartBlock_ + (index >> 9); + if (!cacheRawBlock(lba, CACHE_FOR_WRITE)) goto fail; + // mirror second FAT + if (fatCount_ > 1) cacheMirrorBlock_ = lba + blocksPerFat_; + index &= 0X1FF; + uint8_t tmp = value; + if (cluster & 1) { + tmp = (cacheBuffer_.data[index] & 0XF) | tmp << 4; + } + cacheBuffer_.data[index] = tmp; + index++; + if (index == 512) { + lba++; + index = 0; + if (!cacheRawBlock(lba, CACHE_FOR_WRITE)) goto fail; + // mirror second FAT + if (fatCount_ > 1) cacheMirrorBlock_ = lba + blocksPerFat_; + } + tmp = value >> 4; + if (!(cluster & 1)) { + tmp = ((cacheBuffer_.data[index] & 0XF0)) | tmp >> 4; + } + cacheBuffer_.data[index] = tmp; + return true; + } + if (fatType_ == 16) { + lba = fatStartBlock_ + (cluster >> 8); + } + else if (fatType_ == 32) { + lba = fatStartBlock_ + (cluster >> 7); + } + else { + goto fail; + } + if (!cacheRawBlock(lba, CACHE_FOR_WRITE)) goto fail; + // store entry + if (fatType_ == 16) { + cacheBuffer_.fat16[cluster & 0XFF] = value; + } + else { + cacheBuffer_.fat32[cluster & 0X7F] = value; + } + // mirror second FAT + if (fatCount_ > 1) cacheMirrorBlock_ = lba + blocksPerFat_; + return true; +fail: + return false; +} +//------------------------------------------------------------------------------ +// free a cluster chain +bool SdVolume::freeChain(uint32_t cluster) { + uint32_t next; + + // clear free cluster location + allocSearchStart_ = 2; + + do { + if (!fatGet(cluster, &next)) goto fail; + + // free cluster + if (!fatPut(cluster, 0)) goto fail; + + cluster = next; + } while (!isEOC(cluster)); + + return true; +fail: + return false; +} +//------------------------------------------------------------------------------ +/** Volume free space in clusters. + * + * \return Count of free clusters for success or -1 if an error occurs. + */ +int32_t SdVolume::freeClusterCount() { + uint32_t free = 0; + uint16_t n; + uint32_t todo = clusterCount_ + 2; + + if (fatType_ == 16) { + n = 256; + } + else if (fatType_ == 32) { + n = 128; + } + else { + // put FAT12 here + return -1; + } + + for (uint32_t lba = fatStartBlock_; todo; todo -= n, lba++) { + if (!cacheRawBlock(lba, CACHE_FOR_READ)) return -1; + NOMORE(n, todo); + if (fatType_ == 16) { + for (uint16_t i = 0; i < n; i++) { + if (cacheBuffer_.fat16[i] == 0) free++; + } + } + else { + for (uint16_t i = 0; i < n; i++) { + if (cacheBuffer_.fat32[i] == 0) free++; + } + } + } + return free; +} +//------------------------------------------------------------------------------ +/** Initialize a FAT volume. + * + * \param[in] dev The SD card where the volume is located. + * + * \param[in] part The partition to be used. Legal values for \a part are + * 1-4 to use the corresponding partition on a device formatted with + * a MBR, Master Boot Record, or zero if the device is formatted as + * a super floppy with the FAT boot sector in block zero. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. Reasons for + * failure include not finding a valid partition, not finding a valid + * FAT file system in the specified partition or an I/O error. + */ +bool SdVolume::init(Sd2Card* dev, uint8_t part) { + uint32_t totalBlocks; + uint32_t volumeStartBlock = 0; + fat32_boot_t* fbs; + + sdCard_ = dev; + fatType_ = 0; + allocSearchStart_ = 2; + cacheDirty_ = 0; // cacheFlush() will write block if true + cacheMirrorBlock_ = 0; + cacheBlockNumber_ = 0XFFFFFFFF; + + // if part == 0 assume super floppy with FAT boot sector in block zero + // if part > 0 assume mbr volume with partition table + if (part) { + if (part > 4)goto fail; + if (!cacheRawBlock(volumeStartBlock, CACHE_FOR_READ)) goto fail; + part_t* p = &cacheBuffer_.mbr.part[part - 1]; + if ((p->boot & 0X7F) != 0 || + p->totalSectors < 100 || + p->firstSector == 0) { + // not a valid partition + goto fail; + } + volumeStartBlock = p->firstSector; + } + if (!cacheRawBlock(volumeStartBlock, CACHE_FOR_READ)) goto fail; + fbs = &cacheBuffer_.fbs32; + if (fbs->bytesPerSector != 512 || + fbs->fatCount == 0 || + fbs->reservedSectorCount == 0 || + fbs->sectorsPerCluster == 0) { + // not valid FAT volume + goto fail; + } + fatCount_ = fbs->fatCount; + blocksPerCluster_ = fbs->sectorsPerCluster; + // determine shift that is same as multiply by blocksPerCluster_ + clusterSizeShift_ = 0; + while (blocksPerCluster_ != _BV(clusterSizeShift_)) { + // error if not power of 2 + if (clusterSizeShift_++ > 7) goto fail; + } + blocksPerFat_ = fbs->sectorsPerFat16 ? + fbs->sectorsPerFat16 : fbs->sectorsPerFat32; + + fatStartBlock_ = volumeStartBlock + fbs->reservedSectorCount; + + // count for FAT16 zero for FAT32 + rootDirEntryCount_ = fbs->rootDirEntryCount; + + // directory start for FAT16 dataStart for FAT32 + rootDirStart_ = fatStartBlock_ + fbs->fatCount * blocksPerFat_; + + // data start for FAT16 and FAT32 + dataStartBlock_ = rootDirStart_ + ((32 * fbs->rootDirEntryCount + 511) / 512); + + // total blocks for FAT16 or FAT32 + totalBlocks = fbs->totalSectors16 ? + fbs->totalSectors16 : fbs->totalSectors32; + + // total data blocks + clusterCount_ = totalBlocks - (dataStartBlock_ - volumeStartBlock); + + // divide by cluster size to get cluster count + clusterCount_ >>= clusterSizeShift_; + + // FAT type is determined by cluster count + if (clusterCount_ < 4085) { + fatType_ = 12; + if (!FAT12_SUPPORT) goto fail; + } + else if (clusterCount_ < 65525) { + fatType_ = 16; + } + else { + rootDirStart_ = fbs->fat32RootCluster; + fatType_ = 32; + } + return true; +fail: + return false; +} +#endif diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/SdVolume.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/SdVolume.h new file mode 100644 index 00000000..990248d6 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/SdVolume.h @@ -0,0 +1,227 @@ +/** + * 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 . + * + */ + +/** + * Arduino SdFat Library + * Copyright (C) 2009 by William Greiman + * + * This file is part of the Arduino Sd2Card Library + */ +#include "Marlin.h" +#if ENABLED(SDSUPPORT) +#ifndef SdVolume_h +#define SdVolume_h +/** + * \file + * \brief SdVolume class + */ +#include "SdFatConfig.h" +#include "Sd2Card.h" +#include "SdFatStructs.h" + +//============================================================================== +// SdVolume class +/** + * \brief Cache for an SD data block + */ +union cache_t { + /** Used to access cached file data blocks. */ + uint8_t data[512]; + /** Used to access cached FAT16 entries. */ + uint16_t fat16[256]; + /** Used to access cached FAT32 entries. */ + uint32_t fat32[128]; + /** Used to access cached directory entries. */ + dir_t dir[16]; + /** Used to access a cached Master Boot Record. */ + mbr_t mbr; + /** Used to access to a cached FAT boot sector. */ + fat_boot_t fbs; + /** Used to access to a cached FAT32 boot sector. */ + fat32_boot_t fbs32; + /** Used to access to a cached FAT32 FSINFO sector. */ + fat32_fsinfo_t fsinfo; +}; +//------------------------------------------------------------------------------ +/** + * \class SdVolume + * \brief Access FAT16 and FAT32 volumes on SD and SDHC cards. + */ +class SdVolume { + public: + /** Create an instance of SdVolume */ + SdVolume() : fatType_(0) {} + /** Clear the cache and returns a pointer to the cache. Used by the WaveRP + * recorder to do raw write to the SD card. Not for normal apps. + * \return A pointer to the cache buffer or zero if an error occurs. + */ + cache_t* cacheClear() { + if (!cacheFlush()) return 0; + cacheBlockNumber_ = 0XFFFFFFFF; + return &cacheBuffer_; + } + /** Initialize a FAT volume. Try partition one first then try super + * floppy format. + * + * \param[in] dev The Sd2Card where the volume is located. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. Reasons for + * failure include not finding a valid partition, not finding a valid + * FAT file system or an I/O error. + */ + bool init(Sd2Card* dev) { return init(dev, 1) ? true : init(dev, 0);} + bool init(Sd2Card* dev, uint8_t part); + + // inline functions that return volume info + /** \return The volume's cluster size in blocks. */ + uint8_t blocksPerCluster() const {return blocksPerCluster_;} + /** \return The number of blocks in one FAT. */ + uint32_t blocksPerFat() const {return blocksPerFat_;} + /** \return The total number of clusters in the volume. */ + uint32_t clusterCount() const {return clusterCount_;} + /** \return The shift count required to multiply by blocksPerCluster. */ + uint8_t clusterSizeShift() const {return clusterSizeShift_;} + /** \return The logical block number for the start of file data. */ + uint32_t dataStartBlock() const {return dataStartBlock_;} + /** \return The number of FAT structures on the volume. */ + uint8_t fatCount() const {return fatCount_;} + /** \return The logical block number for the start of the first FAT. */ + uint32_t fatStartBlock() const {return fatStartBlock_;} + /** \return The FAT type of the volume. Values are 12, 16 or 32. */ + uint8_t fatType() const {return fatType_;} + int32_t freeClusterCount(); + /** \return The number of entries in the root directory for FAT16 volumes. */ + uint32_t rootDirEntryCount() const {return rootDirEntryCount_;} + /** \return The logical block number for the start of the root directory + on FAT16 volumes or the first cluster number on FAT32 volumes. */ + uint32_t rootDirStart() const {return rootDirStart_;} + /** Sd2Card object for this volume + * \return pointer to Sd2Card object. + */ + Sd2Card* sdCard() {return sdCard_;} + /** Debug access to FAT table + * + * \param[in] n cluster number. + * \param[out] v value of entry + * \return true for success or false for failure + */ + bool dbgFat(uint32_t n, uint32_t* v) {return fatGet(n, v);} + //------------------------------------------------------------------------------ + private: + // Allow SdBaseFile access to SdVolume private data. + friend class SdBaseFile; + + // value for dirty argument in cacheRawBlock to indicate read from cache + static bool const CACHE_FOR_READ = false; + // value for dirty argument in cacheRawBlock to indicate write to cache + static bool const CACHE_FOR_WRITE = true; + +#if USE_MULTIPLE_CARDS + cache_t cacheBuffer_; // 512 byte cache for device blocks + uint32_t cacheBlockNumber_; // Logical number of block in the cache + Sd2Card* sdCard_; // Sd2Card object for cache + bool cacheDirty_; // cacheFlush() will write block if true + uint32_t cacheMirrorBlock_; // block number for mirror FAT +#else // USE_MULTIPLE_CARDS + static cache_t cacheBuffer_; // 512 byte cache for device blocks + static uint32_t cacheBlockNumber_; // Logical number of block in the cache + static Sd2Card* sdCard_; // Sd2Card object for cache + static bool cacheDirty_; // cacheFlush() will write block if true + static uint32_t cacheMirrorBlock_; // block number for mirror FAT +#endif // USE_MULTIPLE_CARDS + uint32_t allocSearchStart_; // start cluster for alloc search + uint8_t blocksPerCluster_; // cluster size in blocks + uint32_t blocksPerFat_; // FAT size in blocks + uint32_t clusterCount_; // clusters in one FAT + uint8_t clusterSizeShift_; // shift to convert cluster count to block count + uint32_t dataStartBlock_; // first data block number + uint8_t fatCount_; // number of FATs on volume + uint32_t fatStartBlock_; // start block for first FAT + uint8_t fatType_; // volume type (12, 16, OR 32) + uint16_t rootDirEntryCount_; // number of entries in FAT16 root dir + uint32_t rootDirStart_; // root start block for FAT16, cluster for FAT32 + //---------------------------------------------------------------------------- + bool allocContiguous(uint32_t count, uint32_t* curCluster); + uint8_t blockOfCluster(uint32_t position) const { + return (position >> 9) & (blocksPerCluster_ - 1); + } + uint32_t clusterStartBlock(uint32_t cluster) const { + return dataStartBlock_ + ((cluster - 2) << clusterSizeShift_); + } + uint32_t blockNumber(uint32_t cluster, uint32_t position) const { + return clusterStartBlock(cluster) + blockOfCluster(position); + } + cache_t* cache() {return &cacheBuffer_;} + uint32_t cacheBlockNumber() {return cacheBlockNumber_;} +#if USE_MULTIPLE_CARDS + bool cacheFlush(); + bool cacheRawBlock(uint32_t blockNumber, bool dirty); +#else // USE_MULTIPLE_CARDS + static bool cacheFlush(); + static bool cacheRawBlock(uint32_t blockNumber, bool dirty); +#endif // USE_MULTIPLE_CARDS + // used by SdBaseFile write to assign cache to SD location + void cacheSetBlockNumber(uint32_t blockNumber, bool dirty) { + cacheDirty_ = dirty; + cacheBlockNumber_ = blockNumber; + } + void cacheSetDirty() {cacheDirty_ |= CACHE_FOR_WRITE;} + bool chainSize(uint32_t beginCluster, uint32_t* size); + bool fatGet(uint32_t cluster, uint32_t* value); + bool fatPut(uint32_t cluster, uint32_t value); + bool fatPutEOC(uint32_t cluster) { + return fatPut(cluster, 0x0FFFFFFF); + } + bool freeChain(uint32_t cluster); + bool isEOC(uint32_t cluster) const { + if (FAT12_SUPPORT && fatType_ == 12) return cluster >= FAT12EOC_MIN; + if (fatType_ == 16) return cluster >= FAT16EOC_MIN; + return cluster >= FAT32EOC_MIN; + } + bool readBlock(uint32_t block, uint8_t* dst) { + return sdCard_->readBlock(block, dst); + } + bool writeBlock(uint32_t block, const uint8_t* dst) { + return sdCard_->writeBlock(block, dst); + } + //------------------------------------------------------------------------------ + // Deprecated functions - suppress cpplint warnings with NOLINT comment +#if ALLOW_DEPRECATED_FUNCTIONS && !defined(DOXYGEN) + public: + /** \deprecated Use: bool SdVolume::init(Sd2Card* dev); + * \param[in] dev The SD card where the volume is located. + * \return true for success or false for failure. + */ + bool init(Sd2Card& dev) {return init(&dev);} // NOLINT + /** \deprecated Use: bool SdVolume::init(Sd2Card* dev, uint8_t vol); + * \param[in] dev The SD card where the volume is located. + * \param[in] part The partition to be used. + * \return true for success or false for failure. + */ + bool init(Sd2Card& dev, uint8_t part) { // NOLINT + return init(&dev, part); + } +#endif // ALLOW_DEPRECATED_FUNCTIONS +}; +#endif // SdVolume +#endif diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/Version.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/Version.h new file mode 100644 index 00000000..6bd30e11 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/Version.h @@ -0,0 +1,92 @@ +/** + * 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 . + * + */ + +/** + * This file is the standard Marlin version identifier file, all fields can be + * overriden by the ones defined on _Version.h by using the Configuration.h + * directive USE_AUTOMATIC_VERSIONING. + */ + +#if ENABLED(USE_AUTOMATIC_VERSIONING) + + #include "_Version.h" + +#else + + /** + * Marlin release version identifier + */ + #define SHORT_BUILD_VERSION "1.1.0-RC7-PaoloIocco" + + /** + * 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)" + + /** + * 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 "2016-07-31 12:00" + + /** + * Required minimum Configuration.h and Configuration_adv.h file versions. + * + * You must increment this version number for every significant change such as, + * but not limited to: ADD, DELETE RENAME OR REPURPOSE any directive/option on + * the configuration files. + */ + #define REQUIRED_CONFIGURATION_H_VERSION 010100 + #define REQUIRED_CONFIGURATION_ADV_H_VERSION 010100 + + /** + * @todo: Missing documentation block + */ + #define PROTOCOL_VERSION "1.0" + + /** + * Defines a generic printer name to be output to the LCD after booting Marlin. + */ + #define MACHINE_NAME "3D Printer" + + /** + * The SOURCE_CODE_URL is the location where users will find the Marlin Source + * Code which is installed on the device. In most cases —unless the manufacturer + * has a distinct Github fork— the Source Code URL should just be the main + * Marlin repository. + */ + #define SOURCE_CODE_URL "https://github.com/MarlinFirmware/Marlin" + + /** + * Default generic printer UUID. + */ + #define DEFAULT_MACHINE_UUID "cede2a2f-41a2-4748-9b12-c55c62f367ff" + + /** + * 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" + +#endif // USE_AUTOMATIC_VERSIONING diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/blinkm.cpp b/trunk/Arduino/Marlin_K8600_1.1.0RC7/blinkm.cpp new file mode 100644 index 00000000..c495a5de --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/blinkm.cpp @@ -0,0 +1,46 @@ +/** + * 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 . + * + */ + +/** + * blinkm.cpp - Library for controlling a BlinkM over i2c + * Created by Tim Koster, August 21 2013. + */ + +#include "Marlin.h" + +#if ENABLED(BLINKM) + +#include "blinkm.h" + +void SendColors(byte red, byte grn, byte blu) { + Wire.begin(); + Wire.beginTransmission(0x09); + Wire.write('o'); //to disable ongoing script, only needs to be used once + Wire.write('n'); + Wire.write(red); + Wire.write(grn); + Wire.write(blu); + Wire.endTransmission(); +} + +#endif //BLINKM + diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/blinkm.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/blinkm.h new file mode 100644 index 00000000..ed2ad79b --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/blinkm.h @@ -0,0 +1,31 @@ +/** + * 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 . + * + */ + +/** + * blinkm.h - Library for controlling a BlinkM over i2c + * Created by Tim Koster, August 21 2013. + */ + +#include "Arduino.h" +#include "Wire.h" + +void SendColors(byte red, byte grn, byte blu); diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/boards.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/boards.h new file mode 100644 index 00000000..70953233 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/boards.h @@ -0,0 +1,102 @@ +/** + * 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 . + * + */ + +#ifndef BOARDS_H +#define BOARDS_H + +#define BOARD_UNKNOWN -1 + +#define BOARD_GEN7_CUSTOM 10 // Gen7 custom (Alfons3 Version) "https://github.com/Alfons3/Generation_7_Electronics" +#define BOARD_GEN7_12 11 // Gen7 v1.1, v1.2 +#define BOARD_GEN7_13 12 // Gen7 v1.3 +#define BOARD_GEN7_14 13 // Gen7 v1.4 +#define BOARD_CNCONTROLS_11 111 // Cartesio CN Controls V11 +#define BOARD_CNCONTROLS_12 112 // Cartesio CN Controls V12 +#define BOARD_CHEAPTRONIC 2 // Cheaptronic v1.0 +#define BOARD_SETHI 20 // Sethi 3D_1 +#define BOARD_RAMPS_OLD 3 // MEGA/RAMPS up to 1.2 +#define BOARD_RAMPS_13_EFB 33 // RAMPS 1.3 (Power outputs: Hotend, Fan, Bed) +#define BOARD_RAMPS_13_EEB 34 // RAMPS 1.3 (Power outputs: Hotend0, Hotend1, Bed) +#define BOARD_RAMPS_13_EFF 35 // RAMPS 1.3 (Power outputs: Hotend, Fan0, Fan1) +#define BOARD_RAMPS_13_EEF 36 // RAMPS 1.3 (Power outputs: Hotend0, Hotend1, Fan) +#define BOARD_RAMPS_13_SF 38 // RAMPS 1.3 (Power outputs: Spindle, Controller Fan) +#define BOARD_FELIX2 37 // Felix 2.0+ Electronics Board (RAMPS like) +#define BOARD_RIGIDBOARD 42 // Invent-A-Part RigidBoard +#define BOARD_RIGIDBOARD_V2 52 // Invent-A-Part RigidBoard V2 +#define BOARD_RAMPS_14_EFB 43 // RAMPS 1.4 (Power outputs: Hotend, Fan, Bed) +#define BOARD_RAMPS_14_EEB 44 // RAMPS 1.4 (Power outputs: Hotend0, Hotend1, Bed) +#define BOARD_RAMPS_14_EFF 45 // RAMPS 1.4 (Power outputs: Hotend, Fan0, Fan1) +#define BOARD_RAMPS_14_EEF 46 // RAMPS 1.4 (Power outputs: Hotend0, Hotend1, Fan) +#define BOARD_RAMPS_14_SF 48 // RAMPS 1.4 (Power outputs: Spindle, Controller Fan) +#define BOARD_GEN6 5 // Gen6 +#define BOARD_GEN6_DELUXE 51 // Gen6 deluxe +#define BOARD_SANGUINOLOLU_11 6 // Sanguinololu < 1.2 +#define BOARD_SANGUINOLOLU_12 62 // Sanguinololu 1.2 and above +#define BOARD_MELZI 63 // Melzi +#define BOARD_STB_11 64 // STB V1.1 +#define BOARD_AZTEEG_X1 65 // Azteeg X1 +#define BOARD_MELZI_MAKR3D 66 // Melzi with ATmega1284 (MaKr3d version) +#define BOARD_AZTEEG_X3 67 // Azteeg X3 +#define BOARD_AZTEEG_X3_PRO 68 // Azteeg X3 Pro +#define BOARD_ULTIMAKER 7 // Ultimaker +#define BOARD_ULTIMAKER_OLD 71 // Ultimaker (Older electronics. Pre 1.5.4. This is rare) +#define BOARD_ULTIMAIN_2 72 // Ultimainboard 2.x (Uses TEMP_SENSOR 20) +#define BOARD_K8600 75 // Velleman K8800 Controller +#define BOARD_K8800 76 // Velleman K8800 Controller +#define BOARD_3DRAG 77 // 3Drag Controller +#define BOARD_K8200 78 // Velleman K8200 Controller (derived from 3Drag Controller) +#define BOARD_K8400 79 // Velleman K8400 Controller (derived from 3Drag Controller) +#define BOARD_TEENSYLU 8 // Teensylu +#define BOARD_RUMBA 80 // Rumba +#define BOARD_PRINTRBOARD 81 // Printrboard (AT90USB1286) +#define BOARD_PRINTRBOARD_REVF 811 // Printrboard Revision F (AT90USB1286) +#define BOARD_BRAINWAVE 82 // Brainwave (AT90USB646) +#define BOARD_SAV_MKI 83 // SAV Mk-I (AT90USB1286) +#define BOARD_TEENSY2 84 // Teensy++2.0 (AT90USB1286) - CLI compile: DEFINES=AT90USBxx_TEENSYPP_ASSIGNMENTS HARDWARE_MOTHERBOARD=84 make +#define BOARD_BRAINWAVE_PRO 85 // Brainwave Pro (AT90USB1286) +#define BOARD_GEN3_PLUS 9 // Gen3+ +#define BOARD_GEN3_MONOLITHIC 22 // Gen3 Monolithic Electronics +#define BOARD_MEGATRONICS 70 // Megatronics +#define BOARD_MEGATRONICS_2 701 // Megatronics v2.0 +#define BOARD_MINITRONICS 702 // Minitronics v1.0/1.1 +#define BOARD_MEGATRONICS_3 703 // Megatronics v3.0 +#define BOARD_OMCA_A 90 // Alpha OMCA board +#define BOARD_OMCA 91 // Final OMCA board +#define BOARD_RAMBO 301 // Rambo +#define BOARD_MINIRAMBO 302 // Mini-Rambo +#define BOARD_AJ4P 303 // AJ4P +#define BOARD_MEGACONTROLLER 310 // Mega controller +#define BOARD_ELEFU_3 21 // Elefu Ra Board (v3) +#define BOARD_5DPRINT 88 // 5DPrint D8 Driver Board +#define BOARD_LEAPFROG 999 // Leapfrog +#define BOARD_MKS_BASE 40 // MKS BASE 1.0 +#define BOARD_MKS_13 47 // MKS v1.3 or 1.4 (maybe higher) +#define BOARD_SAINSMART_2IN1 49 // Sainsmart 2-in-1 board +#define BOARD_BAM_DICE 401 // 2PrintBeta BAM&DICE with STK drivers +#define BOARD_BAM_DICE_DUE 402 // 2PrintBeta BAM&DICE Due with STK drivers +#define BOARD_BQ_ZUM_MEGA_3D 503 // bq ZUM Mega 3D + +#define BOARD_99 99 // This is in pins.h but...? + +#define MB(board) (MOTHERBOARD==BOARD_##board) + +#endif //__BOARDS_H diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/buzzer.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/buzzer.h new file mode 100644 index 00000000..199d64e4 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/buzzer.h @@ -0,0 +1,145 @@ +/** + * 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 . + * + */ + +#ifndef __BUZZER_H__ +#define __BUZZER_H__ + +#include "types.h" +#include "fastio.h" +#include "circularqueue.h" +#include "temperature.h" + +#include "MarlinConfig.h" + +#define TONE_QUEUE_LENGTH 4 + +/** + * @brief Tone structure + * @details Simple abstraction of a tone based on a duration and a frequency. + */ +struct tone_t { + uint16_t duration; + uint16_t frequency; +}; + +/** + * @brief Buzzer class + */ +class Buzzer { + private: + struct state_t { + tone_t tone; + uint32_t endtime; + } state; + + protected: + CircularQueue buffer; + + /** + * @brief Inverts the sate of a digital PIN + * @details This will invert the current state of an digital IO pin. + */ + void invert() { + TOGGLE(BEEPER_PIN); + } + + /** + * @brief Turn off a digital PIN + * @details Alias of digitalWrite(PIN, LOW) using FastIO + */ + void off() { + WRITE(BEEPER_PIN, LOW); + } + + /** + * @brief Turn on a digital PIN + * @details Alias of digitalWrite(PIN, HIGH) using FastIO + */ + void on() { + WRITE(BEEPER_PIN, HIGH); + } + + /** + * @brief Resets the state of the class + * @details Brings the class state to a known one. + */ + void reset() { + this->off(); + this->state.endtime = 0; + } + + public: + /** + * @brief Class constructor + */ + Buzzer() { + SET_OUTPUT(BEEPER_PIN); + this->reset(); + } + + /** + * @brief Add a tone to the queue + * @details Adds a tone_t structure to the ring buffer, will block IO if the + * queue is full waiting for one slot to get available. + * + * @param duration Duration of the tone in milliseconds + * @param frequency Frequency of the tone in hertz + */ + void tone(uint16_t const &duration, uint16_t const &frequency = 0) { + while (buffer.isFull()) { + this->tick(); + thermalManager.manage_heater(); + } + this->buffer.enqueue((tone_t) { duration, frequency }); + } + + /** + * @brief Loop function + * @details This function should be called at loop, it will take care of + * playing the tones in the queue. + */ + virtual void tick() { + const millis_t now = millis(); + + if (!this->state.endtime) { + if (this->buffer.isEmpty()) return; + + this->state.tone = this->buffer.dequeue(); + this->state.endtime = now + this->state.tone.duration; + + if (this->state.tone.frequency > 0) { + #if ENABLED(SPEAKER) + CRITICAL_SECTION_START; + ::tone(BEEPER_PIN, this->state.tone.frequency, this->state.tone.duration); + CRITICAL_SECTION_END; + #else + this->on(); + #endif + } + } + else if (ELAPSED(now, this->state.endtime)) this->reset(); + } +}; + +extern Buzzer buzzer; + +#endif diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/cardreader.cpp b/trunk/Arduino/Marlin_K8600_1.1.0RC7/cardreader.cpp new file mode 100644 index 00000000..65b40933 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/cardreader.cpp @@ -0,0 +1,624 @@ +/** + * 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 . + * + */ + +#include "cardreader.h" + +#include "ultralcd.h" +#include "stepper.h" +#include "temperature.h" +#include "language.h" + +#include "Marlin.h" + +#if ENABLED(SDSUPPORT) + +CardReader::CardReader() { + filesize = 0; + sdpos = 0; + sdprinting = false; + cardOK = false; + saving = false; + logging = false; + workDirDepth = 0; + file_subcall_ctr = 0; + memset(workDirParents, 0, sizeof(workDirParents)); + + autostart_stilltocheck = true; //the SD start is delayed, because otherwise the serial cannot answer fast enough to make contact with the host software. + autostart_index = 0; + + //power to SD reader + #if SDPOWER > -1 + OUT_WRITE(SDPOWER, HIGH); + #endif //SDPOWER + + next_autostart_ms = millis() + 5000; +} + +char *createFilename(char *buffer, const dir_t &p) { //buffer > 12characters + char *pos = buffer; + for (uint8_t i = 0; i < 11; i++) { + if (p.name[i] == ' ') continue; + if (i == 8) *pos++ = '.'; + *pos++ = p.name[i]; + } + *pos++ = 0; + return buffer; +} + +/** + * Dive into a folder and recurse depth-first to perform a pre-set operation lsAction: + * LS_Count - Add +1 to nrFiles for every file within the parent + * LS_GetFilename - Get the filename of the file indexed by nrFiles + * LS_SerialPrint - Print the full path of each file to serial output + */ +void CardReader::lsDive(const char *prepend, SdFile parent, const char * const match/*=NULL*/) { + dir_t p; + uint8_t cnt = 0; + + // Read the next entry from a directory + while (parent.readDir(p, longFilename) > 0) { + + // If the entry is a directory and the action is LS_SerialPrint + if (DIR_IS_SUBDIR(&p) && lsAction != LS_Count && lsAction != LS_GetFilename) { + + // Get the short name for the item, which we know is a folder + char lfilename[FILENAME_LENGTH]; + createFilename(lfilename, p); + + // Allocate enough stack space for the full path to a folder, trailing slash, and nul + boolean prepend_is_empty = (prepend[0] == '\0'); + int len = (prepend_is_empty ? 1 : strlen(prepend)) + strlen(lfilename) + 1 + 1; + char path[len]; + + // Append the FOLDERNAME12/ to the passed string. + // It contains the full path to the "parent" argument. + // We now have the full path to the item in this folder. + strcpy(path, prepend_is_empty ? "/" : prepend); // root slash if prepend is empty + strcat(path, lfilename); // FILENAME_LENGTH-1 characters maximum + strcat(path, "/"); // 1 character + + // Serial.print(path); + + // Get a new directory object using the full path + // and dive recursively into it. + SdFile dir; + if (!dir.open(parent, lfilename, O_READ)) { + if (lsAction == LS_SerialPrint) { + SERIAL_ECHO_START; + SERIAL_ECHOPGM(MSG_SD_CANT_OPEN_SUBDIR); + SERIAL_ECHOLN(lfilename); + } + } + lsDive(path, dir); + // close() is done automatically by destructor of SdFile + } + else { + uint8_t pn0 = p.name[0]; + if (pn0 == DIR_NAME_FREE) break; + if (pn0 == DIR_NAME_DELETED || pn0 == '.') continue; + if (longFilename[0] == '.') continue; + + if (!DIR_IS_FILE_OR_SUBDIR(&p)) continue; + + filenameIsDir = DIR_IS_SUBDIR(&p); + + if (!filenameIsDir && (p.name[8] != 'G' || p.name[9] == '~')) continue; + + switch (lsAction) { + case LS_Count: + nrFiles++; + break; + case LS_SerialPrint: + createFilename(filename, p); + SERIAL_PROTOCOL(prepend); + SERIAL_PROTOCOLLN(filename); + break; + case LS_GetFilename: + createFilename(filename, p); + if (match != NULL) { + if (strcasecmp(match, filename) == 0) return; + } + else if (cnt == nrFiles) return; + cnt++; + break; + } + + } + } // while readDir +} + +void CardReader::ls() { + lsAction = LS_SerialPrint; + root.rewind(); + lsDive("", root); +} + +#if ENABLED(LONG_FILENAME_HOST_SUPPORT) + + /** + * Get a long pretty path based on a DOS 8.3 path + */ + void CardReader::printLongPath(char *path) { + lsAction = LS_GetFilename; + + int i, pathLen = strlen(path); + + // SERIAL_ECHOPGM("Full Path: "); SERIAL_ECHOLN(path); + + // Zero out slashes to make segments + for (i = 0; i < pathLen; i++) if (path[i] == '/') path[i] = '\0'; + + SdFile diveDir = root; // start from the root for segment 1 + for (i = 0; i < pathLen;) { + + if (path[i] == '\0') i++; // move past a single nul + + char *segment = &path[i]; // The segment after most slashes + + // If a segment is empty (extra-slash) then exit + if (!*segment) break; + + // Go to the next segment + while (path[++i]) { } + + // SERIAL_ECHOPGM("Looking for segment: "); SERIAL_ECHOLN(segment); + + // Find the item, setting the long filename + diveDir.rewind(); + lsDive("", diveDir, segment); + + // Print /LongNamePart to serial output + SERIAL_PROTOCOLCHAR('/'); + SERIAL_PROTOCOL(longFilename[0] ? longFilename : "???"); + + // If the filename was printed then that's it + if (!filenameIsDir) break; + + // SERIAL_ECHOPGM("Opening dir: "); SERIAL_ECHOLN(segment); + + // Open the sub-item as the new dive parent + SdFile dir; + if (!dir.open(diveDir, segment, O_READ)) { + SERIAL_EOL; + SERIAL_ECHO_START; + SERIAL_ECHOPGM(MSG_SD_CANT_OPEN_SUBDIR); + SERIAL_ECHO(segment); + break; + } + + diveDir.close(); + diveDir = dir; + + } // while i SD_PROCEDURE_DEPTH - 1) { + SERIAL_ERROR_START; + SERIAL_ERRORPGM("trying to call sub-gcode files with too many levels. MAX level is:"); + SERIAL_ERRORLN(SD_PROCEDURE_DEPTH); + kill(PSTR(MSG_KILLED)); + return; + } + + SERIAL_ECHO_START; + SERIAL_ECHOPGM("SUBROUTINE CALL target:\""); + SERIAL_ECHO(name); + SERIAL_ECHOPGM("\" parent:\""); + + //store current filename and position + getAbsFilename(proc_filenames[file_subcall_ctr]); + + SERIAL_ECHO(proc_filenames[file_subcall_ctr]); + SERIAL_ECHOPGM("\" pos"); + SERIAL_ECHOLN(sdpos); + filespos[file_subcall_ctr] = sdpos; + file_subcall_ctr++; + } + else { + SERIAL_ECHO_START; + SERIAL_ECHOPGM("Now doing file: "); + SERIAL_ECHOLN(name); + } + file.close(); + } + else { //opening fresh file + file_subcall_ctr = 0; //resetting procedure depth in case user cancels print while in procedure + SERIAL_ECHO_START; + SERIAL_ECHOPGM("Now fresh file: "); + SERIAL_ECHOLN(name); + } + sdprinting = false; + + SdFile myDir; + curDir = &root; + char *fname = name; + + char *dirname_start, *dirname_end; + if (name[0] == '/') { + dirname_start = &name[1]; + while (dirname_start != NULL) { + dirname_end = strchr(dirname_start, '/'); + //SERIAL_ECHOPGM("start:");SERIAL_ECHOLN((int)(dirname_start - name)); + //SERIAL_ECHOPGM("end :");SERIAL_ECHOLN((int)(dirname_end - name)); + if (dirname_end != NULL && dirname_end > dirname_start) { + char subdirname[FILENAME_LENGTH]; + strncpy(subdirname, dirname_start, dirname_end - dirname_start); + subdirname[dirname_end - dirname_start] = 0; + SERIAL_ECHOLN(subdirname); + if (!myDir.open(curDir, subdirname, O_READ)) { + SERIAL_PROTOCOLPGM(MSG_SD_OPEN_FILE_FAIL); + SERIAL_PROTOCOL(subdirname); + SERIAL_PROTOCOLCHAR('.'); + return; + } + else { + //SERIAL_ECHOLNPGM("dive ok"); + } + + curDir = &myDir; + dirname_start = dirname_end + 1; + } + else { // the remainder after all /fsa/fdsa/ is the filename + fname = dirname_start; + //SERIAL_ECHOLNPGM("remainder"); + //SERIAL_ECHOLN(fname); + break; + } + } + } + else { //relative path + curDir = &workDir; + } + + if (read) { + if (file.open(curDir, fname, O_READ)) { + filesize = file.fileSize(); + SERIAL_PROTOCOLPAIR(MSG_SD_FILE_OPENED, fname); + SERIAL_PROTOCOLPAIR(MSG_SD_SIZE, filesize); + SERIAL_EOL; + sdpos = 0; + + SERIAL_PROTOCOLLNPGM(MSG_SD_FILE_SELECTED); + getfilename(0, fname); + lcd_setstatus(longFilename[0] ? longFilename : fname); + } + else { + SERIAL_PROTOCOLPAIR(MSG_SD_OPEN_FILE_FAIL, fname); + SERIAL_PROTOCOLCHAR('.'); + SERIAL_EOL; + } + } + else { //write + if (!file.open(curDir, fname, O_CREAT | O_APPEND | O_WRITE | O_TRUNC)) { + SERIAL_PROTOCOLPAIR(MSG_SD_OPEN_FILE_FAIL, fname); + SERIAL_PROTOCOLCHAR('.'); + SERIAL_EOL; + } + else { + saving = true; + SERIAL_PROTOCOLPAIR(MSG_SD_WRITE_TO_FILE, name); + SERIAL_EOL; + lcd_setstatus(fname); + } + } +} + +void CardReader::removeFile(char* name) { + if (!cardOK) return; + + file.close(); + sdprinting = false; + + SdFile myDir; + curDir = &root; + char *fname = name; + + char *dirname_start, *dirname_end; + if (name[0] == '/') { + dirname_start = strchr(name, '/') + 1; + while (dirname_start != NULL) { + dirname_end = strchr(dirname_start, '/'); + //SERIAL_ECHOPGM("start:");SERIAL_ECHOLN((int)(dirname_start - name)); + //SERIAL_ECHOPGM("end :");SERIAL_ECHOLN((int)(dirname_end - name)); + if (dirname_end != NULL && dirname_end > dirname_start) { + char subdirname[FILENAME_LENGTH]; + strncpy(subdirname, dirname_start, dirname_end - dirname_start); + subdirname[dirname_end - dirname_start] = 0; + SERIAL_ECHOLN(subdirname); + if (!myDir.open(curDir, subdirname, O_READ)) { + SERIAL_PROTOCOLPAIR("open failed, File: ", subdirname); + SERIAL_PROTOCOLCHAR('.'); + return; + } + else { + //SERIAL_ECHOLNPGM("dive ok"); + } + + curDir = &myDir; + dirname_start = dirname_end + 1; + } + else { // the remainder after all /fsa/fdsa/ is the filename + fname = dirname_start; + //SERIAL_ECHOLNPGM("remainder"); + //SERIAL_ECHOLN(fname); + break; + } + } + } + else { // relative path + curDir = &workDir; + } + + if (file.remove(curDir, fname)) { + SERIAL_PROTOCOLPGM("File deleted:"); + SERIAL_PROTOCOLLN(fname); + sdpos = 0; + } + else { + SERIAL_PROTOCOLPGM("Deletion failed, File: "); + SERIAL_PROTOCOL(fname); + SERIAL_PROTOCOLCHAR('.'); + } +} + +void CardReader::getStatus() { + if (cardOK) { + SERIAL_PROTOCOLPGM(MSG_SD_PRINTING_BYTE); + SERIAL_PROTOCOL(sdpos); + SERIAL_PROTOCOLCHAR('/'); + SERIAL_PROTOCOLLN(filesize); + } + else { + SERIAL_PROTOCOLLNPGM(MSG_SD_NOT_PRINTING); + } +} + +void CardReader::write_command(char *buf) { + char* begin = buf; + char* npos = 0; + char* end = buf + strlen(buf) - 1; + + file.writeError = false; + if ((npos = strchr(buf, 'N')) != NULL) { + begin = strchr(npos, ' ') + 1; + end = strchr(npos, '*') - 1; + } + end[1] = '\r'; + end[2] = '\n'; + end[3] = '\0'; + file.write(begin); + if (file.writeError) { + SERIAL_ERROR_START; + SERIAL_ERRORLNPGM(MSG_SD_ERR_WRITE_TO_FILE); + } +} + +void CardReader::checkautostart(bool force) { + if (!force && (!autostart_stilltocheck || ELAPSED(millis(), next_autostart_ms))) + return; + + autostart_stilltocheck = false; + + if (!cardOK) { + initsd(); + if (!cardOK) return; // fail + } + + char autoname[10]; + sprintf_P(autoname, PSTR("auto%i.g"), autostart_index); + for (int8_t i = 0; i < (int8_t)strlen(autoname); i++) autoname[i] = tolower(autoname[i]); + + dir_t p; + + root.rewind(); + + bool found = false; + while (root.readDir(p, NULL) > 0) { + for (int8_t i = 0; i < (int8_t)strlen((char*)p.name); i++) p.name[i] = tolower(p.name[i]); + if (p.name[9] != '~' && strncmp((char*)p.name, autoname, 5) == 0) { + openAndPrintFile(autoname); + found = true; + } + } + if (!found) + autostart_index = -1; + else + autostart_index++; +} + +void CardReader::closefile(bool store_location) { + file.sync(); + file.close(); + saving = logging = false; + + if (store_location) { + //future: store printer state, filename and position for continuing a stopped print + // so one can unplug the printer and continue printing the next day. + } +} + +/** + * Get the name of a file in the current directory by index + */ +void CardReader::getfilename(uint16_t nr, const char * const match/*=NULL*/) { + curDir = &workDir; + lsAction = LS_GetFilename; + nrFiles = nr; + curDir->rewind(); + lsDive("", *curDir, match); +} + +uint16_t CardReader::getnrfilenames() { + curDir = &workDir; + lsAction = LS_Count; + nrFiles = 0; + curDir->rewind(); + lsDive("", *curDir); + //SERIAL_ECHOLN(nrFiles); + return nrFiles; +} + +void CardReader::chdir(const char * relpath) { + SdFile newfile; + SdFile *parent = &root; + + if (workDir.isOpen()) parent = &workDir; + + if (!newfile.open(*parent, relpath, O_READ)) { + SERIAL_ECHO_START; + SERIAL_ECHOPGM(MSG_SD_CANT_ENTER_SUBDIR); + SERIAL_ECHOLN(relpath); + } + else { + if (workDirDepth < MAX_DIR_DEPTH) + workDirParents[workDirDepth++] = *parent; + workDir = newfile; + } +} + +void CardReader::updir() { + if (workDirDepth > 0) + workDir = workDirParents[--workDirDepth]; +} + +void CardReader::printingHasFinished() { + stepper.synchronize(); + file.close(); + if (file_subcall_ctr > 0) { // Heading up to a parent file that called current as a procedure. + file_subcall_ctr--; + openFile(proc_filenames[file_subcall_ctr], true, true); + setIndex(filespos[file_subcall_ctr]); + startFileprint(); + } + else { + sdprinting = false; + if (SD_FINISHED_STEPPERRELEASE) + enqueue_and_echo_commands_P(PSTR(SD_FINISHED_RELEASECOMMAND)); + print_job_timer.stop(); + if (print_job_timer.duration() > 60) + enqueue_and_echo_commands_P(PSTR("M31")); + } +} + +#endif //SDSUPPORT diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/cardreader.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/cardreader.h new file mode 100644 index 00000000..8c22e581 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/cardreader.h @@ -0,0 +1,129 @@ +/** + * 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 . + * + */ + +#ifndef CARDREADER_H +#define CARDREADER_H + +#include "MarlinConfig.h" + +#if ENABLED(SDSUPPORT) + +#define MAX_DIR_DEPTH 10 // Maximum folder depth + +#include "SdFile.h" + +#include "types.h" +#include "enum.h" + +class CardReader { +public: + CardReader(); + + void initsd(); + void write_command(char *buf); + //files auto[0-9].g on the sd card are performed in a row + //this is to delay autostart and hence the initialisaiton of the sd card to some seconds after the normal init, so the device is available quick after a reset + + void checkautostart(bool x); + void openFile(char* name, bool read, bool push_current=false); + void openLogFile(char* name); + void removeFile(char* name); + void closefile(bool store_location=false); + void release(); + void openAndPrintFile(const char *name); + void startFileprint(); + void pauseSDPrint(); + void stopSDPrint(); + void getStatus(); + void printingHasFinished(); + + #if ENABLED(LONG_FILENAME_HOST_SUPPORT) + void printLongPath(char *path); + #endif + + void getfilename(uint16_t nr, const char* const match=NULL); + uint16_t getnrfilenames(); + + void getAbsFilename(char *t); + + void ls(); + void chdir(const char *relpath); + void updir(); + void setroot(); + + FORCE_INLINE bool isFileOpen() { return file.isOpen(); } + FORCE_INLINE bool eof() { return sdpos >= filesize; } + FORCE_INLINE int16_t get() { sdpos = file.curPosition(); return (int16_t)file.read(); } + FORCE_INLINE void setIndex(long index) { sdpos = index; file.seekSet(index); } + FORCE_INLINE uint8_t percentDone() { return (isFileOpen() && filesize) ? sdpos / ((filesize + 99) / 100) : 0; } + FORCE_INLINE char* getWorkDirName() { workDir.getFilename(filename); return filename; } + +public: + bool saving, logging, sdprinting, cardOK, filenameIsDir; + char filename[FILENAME_LENGTH], longFilename[LONG_FILENAME_LENGTH]; + int autostart_index; +private: + SdFile root, *curDir, workDir, workDirParents[MAX_DIR_DEPTH]; + uint8_t workDirDepth; + Sd2Card card; + SdVolume volume; + SdFile file; + + #define SD_PROCEDURE_DEPTH 1 + #define MAXPATHNAMELENGTH (FILENAME_LENGTH*MAX_DIR_DEPTH + MAX_DIR_DEPTH + 1) + uint8_t file_subcall_ctr; + uint32_t filespos[SD_PROCEDURE_DEPTH]; + char proc_filenames[SD_PROCEDURE_DEPTH][MAXPATHNAMELENGTH]; + uint32_t filesize; + uint32_t sdpos; + + millis_t next_autostart_ms; + bool autostart_stilltocheck; //the sd start is delayed, because otherwise the serial cannot answer fast enought to make contact with the hostsoftware. + + LsAction lsAction; //stored for recursion. + uint16_t nrFiles; //counter for the files in the current directory and recycled as position counter for getting the nrFiles'th name in the directory. + char* diveDirName; + void lsDive(const char *prepend, SdFile parent, const char * const match=NULL); +}; + +extern CardReader card; + +#define IS_SD_PRINTING (card.sdprinting) + +#if PIN_EXISTS(SD_DETECT) + #if ENABLED(SD_DETECT_INVERTED) + #define IS_SD_INSERTED (READ(SD_DETECT_PIN) != 0) + #else + #define IS_SD_INSERTED (READ(SD_DETECT_PIN) == 0) + #endif +#else + //No card detect line? Assume the card is inserted. + #define IS_SD_INSERTED true +#endif + +#else + +#define IS_SD_PRINTING (false) + +#endif //SDSUPPORT + +#endif //__CARDREADER_H diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/circularqueue.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/circularqueue.h new file mode 100644 index 00000000..9aafb99a --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/circularqueue.h @@ -0,0 +1,145 @@ +/** + * 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 . + * + */ + +#ifndef __CIRCULARQUEUE_H__ +#define __CIRCULARQUEUE_H__ + +#include + +/** + * @brief Circular Queue class + * @details Implementation of the classic ring buffer data structure + */ +template +class CircularQueue { + private: + + /** + * @brief Buffer structure + * @details This structure consolidates all the overhead required to handle + * a circular queue such as the pointers and the buffer vector. + */ + struct buffer_t { + uint8_t head; + uint8_t tail; + uint8_t count; + uint8_t size; + T queue[N]; + } buffer; + + public: + /** + * @brief Class constructor + * @details This class requires two template parameters, T defines the type + * of item this queue will handle and N defines the maximum number of + * items that can be stored on the queue. + */ + CircularQueue() { + this->buffer.size = N; + this->buffer.count = this->buffer.head = this->buffer.tail = 0; + } + + /** + * @brief Removes and returns a item from the queue + * @details Removes the oldest item on the queue, pointed to by the + * buffer_t head field. The item is returned to the caller. + * @return type T item + */ + T dequeue() { + if (this->isEmpty()) return T(); + + uint8_t index = this->buffer.head; + + --this->buffer.count; + if (++this->buffer.head == this->buffer.size) + this->buffer.head = 0; + + return this->buffer.queue[index]; + } + + /** + * @brief Adds an item to the queue + * @details Adds an item to the queue on the location pointed by the buffer_t + * tail variable. Returns false if no queue space is available. + * @param item Item to be added to the queue + * @return true if the operation was successful + */ + bool enqueue(T const &item) { + if (this->isFull()) return false; + + this->buffer.queue[this->buffer.tail] = item; + + ++this->buffer.count; + if (++this->buffer.tail == this->buffer.size) + this->buffer.tail = 0; + + return true; + } + + /** + * @brief Checks if the queue has no items + * @details Returns true if there are no items on the queue, false otherwise. + * @return true if queue is empty + */ + bool isEmpty() { + return this->buffer.count == 0; + } + + /** + * @brief Checks if the queue is full + * @details Returns true if the queue is full, false otherwise. + * @return true if queue is full + */ + bool isFull() { + return this->buffer.count == this->buffer.size; + } + + /** + * @brief Gets the queue size + * @details Returns the maximum number of items a queue can have. + * @return the queue size + */ + uint8_t size() { + return this->buffer.size; + } + + /** + * @brief Gets the next item from the queue without removing it + * @details Returns the next item in the queue without removing it + * or updating the pointers. + * @return first item in the queue + */ + T peek() { + return this->buffer.queue[this->buffer.head]; + } + + /** + * @brief Gets the number of items on the queue + * @details Returns the current number of items stored on the queue. + * @return number of items in the queue + */ + uint8_t count() { + return this->buffer.count; + } +}; + +#endif diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/configuration_store.cpp b/trunk/Arduino/Marlin_K8600_1.1.0RC7/configuration_store.cpp new file mode 100644 index 00000000..db10bba1 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/configuration_store.cpp @@ -0,0 +1,994 @@ +/** + * 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 . + * + */ + +/** + * configuration_store.cpp + * + * Configuration and EEPROM storage + * + * IMPORTANT: Whenever there are changes made to the variables stored in EEPROM + * in the functions below, also increment the version number. This makes sure that + * the default values are used whenever there is a change to the data, to prevent + * wrong data being written to the variables. + * + * 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. + * + */ + +#define EEPROM_VERSION "V24" + +// Change EEPROM version if these are changed: +#define EEPROM_OFFSET 100 +#define MAX_EXTRUDERS 4 + +/** + * V24 EEPROM Layout: + * + * 100 Version (char x4) + * 104 EEPROM Checksum (uint16_t) + * + * 106 M92 XYZE planner.axis_steps_per_mm (float x4) + * 122 M203 XYZE planner.max_feedrate_mm_s (float x4) + * 138 M201 XYZE planner.max_acceleration_mm_per_s2 (uint32_t x4) + * 154 M204 P planner.acceleration (float) + * 158 M204 R planner.retract_acceleration (float) + * 162 M204 T planner.travel_acceleration (float) + * 166 M205 S planner.min_feedrate_mm_s (float) + * 170 M205 T planner.min_travel_feedrate_mm_s (float) + * 174 M205 B planner.min_segment_time (ulong) + * 178 M205 X planner.max_xy_jerk (float) + * 182 M205 Z planner.max_z_jerk (float) + * 186 M205 E planner.max_e_jerk (float) + * 190 M206 XYZ home_offset (float x3) + * + * Mesh bed leveling: + * 202 M420 S status (uint8) + * 203 z_offset (float) + * 207 mesh_num_x (uint8 as set in firmware) + * 208 mesh_num_y (uint8 as set in firmware) + * 209 G29 S3 XYZ z_values[][] (float x9, by default, up to float x 81) + * + * AUTO BED LEVELING + * 245 M851 zprobe_zoffset (float) + * + * DELTA: + * 249 M666 XYZ endstop_adj (float x3) + * 261 M665 R delta_radius (float) + * 265 M665 L delta_diagonal_rod (float) + * 269 M665 S delta_segments_per_second (float) + * 273 M665 A delta_diagonal_rod_trim_tower_1 (float) + * 277 M665 B delta_diagonal_rod_trim_tower_2 (float) + * 281 M665 C delta_diagonal_rod_trim_tower_3 (float) + * + * Z_DUAL_ENDSTOPS: + * 285 M666 Z z_endstop_adj (float) + * + * ULTIPANEL: + * 289 M145 S0 H preheatHotendTemp1 (int) + * 291 M145 S0 B preheatBedTemp1 (int) + * 293 M145 S0 F preheatFanSpeed1 (int) + * 295 M145 S1 H preheatHotendTemp2 (int) + * 297 M145 S1 B preheatBedTemp2 (int) + * 299 M145 S1 F preheatFanSpeed2 (int) + * + * PIDTEMP: + * 301 M301 E0 PIDC Kp[0], Ki[0], Kd[0], Kc[0] (float x4) + * 317 M301 E1 PIDC Kp[1], Ki[1], Kd[1], Kc[1] (float x4) + * 333 M301 E2 PIDC Kp[2], Ki[2], Kd[2], Kc[2] (float x4) + * 349 M301 E3 PIDC Kp[3], Ki[3], Kd[3], Kc[3] (float x4) + * 365 M301 L lpq_len (int) + * + * PIDTEMPBED: + * 367 M304 PID thermalManager.bedKp, thermalManager.bedKi, thermalManager.bedKd (float x3) + * + * DOGLCD: + * 379 M250 C lcd_contrast (int) + * + * SCARA: + * 381 M365 XYZ axis_scaling (float x3) + * + * FWRETRACT: + * 393 M209 S autoretract_enabled (bool) + * 394 M207 S retract_length (float) + * 398 M207 W retract_length_swap (float) + * 402 M207 F retract_feedrate_mm_s (float) + * 406 M207 Z retract_zlift (float) + * 410 M208 S retract_recover_length (float) + * 414 M208 W retract_recover_length_swap (float) + * 418 M208 F retract_recover_feedrate_mm_s (float) + * + * Volumetric Extrusion: + * 422 M200 D volumetric_enabled (bool) + * 423 M200 T D filament_size (float x4) (T0..3) + * + * 439 This Slot is Available! + * + */ +#include "Marlin.h" +#include "language.h" +#include "endstops.h" +#include "planner.h" +#include "temperature.h" +#include "ultralcd.h" +#include "configuration_store.h" + +#if ENABLED(MESH_BED_LEVELING) + #include "mesh_bed_leveling.h" +#endif + +uint16_t eeprom_checksum; +const char version[4] = EEPROM_VERSION; + +void _EEPROM_writeData(int &pos, uint8_t* value, uint8_t size) { + uint8_t c; + while (size--) { + eeprom_write_byte((unsigned char*)pos, *value); + c = eeprom_read_byte((unsigned char*)pos); + if (c != *value) { + SERIAL_ECHO_START; + SERIAL_ECHOLNPGM(MSG_ERR_EEPROM_WRITE); + } + eeprom_checksum += c; + pos++; + value++; + }; +} +void _EEPROM_readData(int &pos, uint8_t* value, uint8_t size) { + do { + uint8_t c = eeprom_read_byte((unsigned char*)pos); + *value = c; + eeprom_checksum += c; + pos++; + value++; + } while (--size); +} + +/** + * Post-process after Retrieve or Reset + */ +void Config_Postprocess() { + // steps per s2 needs to be updated to agree with units per s2 + planner.reset_acceleration_rates(); + + // 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(delta_radius, delta_diagonal_rod); + #endif + + // Refresh steps_to_mm with the reciprocal of axis_steps_per_mm + // and init stepper.count[], planner.position[] with current_position + planner.refresh_positioning(); + + #if ENABLED(PIDTEMP) + thermalManager.updatePID(); + #endif + + calculate_volumetric_multipliers(); +} + +#if ENABLED(EEPROM_SETTINGS) + + #define DUMMY_PID_VALUE 3000.0f + #define EEPROM_START() int eeprom_index = EEPROM_OFFSET + #define EEPROM_SKIP(VAR) eeprom_index += sizeof(VAR) + #define EEPROM_WRITE(VAR) _EEPROM_writeData(eeprom_index, (uint8_t*)&VAR, sizeof(VAR)) + #define EEPROM_READ(VAR) _EEPROM_readData(eeprom_index, (uint8_t*)&VAR, sizeof(VAR)) + +/** + * M500 - Store Configuration + */ +void Config_StoreSettings() { + float dummy = 0.0f; + char ver[4] = "000"; + + EEPROM_START(); + + EEPROM_WRITE(ver); // invalidate data first + EEPROM_SKIP(eeprom_checksum); // Skip the checksum slot + + eeprom_checksum = 0; // clear before first "real data" + + EEPROM_WRITE(planner.axis_steps_per_mm); + EEPROM_WRITE(planner.max_feedrate_mm_s); + EEPROM_WRITE(planner.max_acceleration_mm_per_s2); + EEPROM_WRITE(planner.acceleration); + EEPROM_WRITE(planner.retract_acceleration); + EEPROM_WRITE(planner.travel_acceleration); + EEPROM_WRITE(planner.min_feedrate_mm_s); + EEPROM_WRITE(planner.min_travel_feedrate_mm_s); + EEPROM_WRITE(planner.min_segment_time); + EEPROM_WRITE(planner.max_xy_jerk); + EEPROM_WRITE(planner.max_z_jerk); + EEPROM_WRITE(planner.max_e_jerk); + EEPROM_WRITE(home_offset); + + #if ENABLED(MESH_BED_LEVELING) + // Compile time test that sizeof(mbl.z_values) is as expected + typedef char c_assert[(sizeof(mbl.z_values) == (MESH_NUM_X_POINTS) * (MESH_NUM_Y_POINTS) * sizeof(dummy)) ? 1 : -1]; + uint8_t mesh_num_x = MESH_NUM_X_POINTS, + mesh_num_y = MESH_NUM_Y_POINTS, + dummy_uint8 = mbl.status & _BV(MBL_STATUS_HAS_MESH_BIT); + EEPROM_WRITE(dummy_uint8); + EEPROM_WRITE(mbl.z_offset); + EEPROM_WRITE(mesh_num_x); + EEPROM_WRITE(mesh_num_y); + EEPROM_WRITE(mbl.z_values); + #else + // For disabled MBL write a default mesh + uint8_t mesh_num_x = 3, + mesh_num_y = 3, + dummy_uint8 = 0; + dummy = 0.0f; + EEPROM_WRITE(dummy_uint8); + EEPROM_WRITE(dummy); + EEPROM_WRITE(mesh_num_x); + EEPROM_WRITE(mesh_num_y); + for (uint8_t q = 0; q < mesh_num_x * mesh_num_y; q++) EEPROM_WRITE(dummy); + #endif // MESH_BED_LEVELING + + #if !HAS_BED_PROBE + float zprobe_zoffset = 0; + #endif + EEPROM_WRITE(zprobe_zoffset); + + // 9 floats for DELTA / Z_DUAL_ENDSTOPS + #if ENABLED(DELTA) + EEPROM_WRITE(endstop_adj); // 3 floats + EEPROM_WRITE(delta_radius); // 1 float + EEPROM_WRITE(delta_diagonal_rod); // 1 float + EEPROM_WRITE(delta_segments_per_second); // 1 float + EEPROM_WRITE(delta_diagonal_rod_trim_tower_1); // 1 float + EEPROM_WRITE(delta_diagonal_rod_trim_tower_2); // 1 float + EEPROM_WRITE(delta_diagonal_rod_trim_tower_3); // 1 float + #elif ENABLED(Z_DUAL_ENDSTOPS) + EEPROM_WRITE(z_endstop_adj); // 1 float + dummy = 0.0f; + for (uint8_t q = 8; q--;) EEPROM_WRITE(dummy); + #else + dummy = 0.0f; + for (uint8_t q = 9; q--;) EEPROM_WRITE(dummy); + #endif + + #if DISABLED(ULTIPANEL) + int preheatHotendTemp1 = PREHEAT_1_TEMP_HOTEND, preheatBedTemp1 = PREHEAT_1_TEMP_BED, preheatFanSpeed1 = PREHEAT_1_FAN_SPEED, + preheatHotendTemp2 = PREHEAT_2_TEMP_HOTEND, preheatBedTemp2 = PREHEAT_2_TEMP_BED, preheatFanSpeed2 = PREHEAT_2_FAN_SPEED; + #endif // !ULTIPANEL + + EEPROM_WRITE(preheatHotendTemp1); + EEPROM_WRITE(preheatBedTemp1); + EEPROM_WRITE(preheatFanSpeed1); + EEPROM_WRITE(preheatHotendTemp2); + EEPROM_WRITE(preheatBedTemp2); + EEPROM_WRITE(preheatFanSpeed2); + + for (uint8_t e = 0; e < MAX_EXTRUDERS; e++) { + + #if ENABLED(PIDTEMP) + if (e < HOTENDS) { + EEPROM_WRITE(PID_PARAM(Kp, e)); + EEPROM_WRITE(PID_PARAM(Ki, e)); + EEPROM_WRITE(PID_PARAM(Kd, e)); + #if ENABLED(PID_EXTRUSION_SCALING) + EEPROM_WRITE(PID_PARAM(Kc, e)); + #else + dummy = 1.0f; // 1.0 = default kc + EEPROM_WRITE(dummy); + #endif + } + else + #endif // !PIDTEMP + { + dummy = DUMMY_PID_VALUE; // When read, will not change the existing value + EEPROM_WRITE(dummy); // Kp + dummy = 0.0f; + for (uint8_t q = 3; q--;) EEPROM_WRITE(dummy); // Ki, Kd, Kc + } + + } // Hotends Loop + + #if DISABLED(PID_EXTRUSION_SCALING) + int lpq_len = 20; + #endif + EEPROM_WRITE(lpq_len); + + #if DISABLED(PIDTEMPBED) + dummy = DUMMY_PID_VALUE; + for (uint8_t q = 3; q--;) EEPROM_WRITE(dummy); + #else + EEPROM_WRITE(thermalManager.bedKp); + EEPROM_WRITE(thermalManager.bedKi); + EEPROM_WRITE(thermalManager.bedKd); + #endif + + #if !HAS_LCD_CONTRAST + const int lcd_contrast = 32; + #endif + EEPROM_WRITE(lcd_contrast); + + #if ENABLED(SCARA) + EEPROM_WRITE(axis_scaling); // 3 floats + #else + dummy = 1.0f; + EEPROM_WRITE(dummy); + #endif + + #if ENABLED(FWRETRACT) + EEPROM_WRITE(autoretract_enabled); + EEPROM_WRITE(retract_length); + #if EXTRUDERS > 1 + EEPROM_WRITE(retract_length_swap); + #else + dummy = 0.0f; + EEPROM_WRITE(dummy); + #endif + EEPROM_WRITE(retract_feedrate_mm_s); + EEPROM_WRITE(retract_zlift); + EEPROM_WRITE(retract_recover_length); + #if EXTRUDERS > 1 + EEPROM_WRITE(retract_recover_length_swap); + #else + dummy = 0.0f; + EEPROM_WRITE(dummy); + #endif + EEPROM_WRITE(retract_recover_feedrate_mm_s); + #endif // FWRETRACT + + EEPROM_WRITE(volumetric_enabled); + + // Save filament sizes + for (uint8_t q = 0; q < MAX_EXTRUDERS; q++) { + if (q < COUNT(filament_size)) dummy = filament_size[q]; + EEPROM_WRITE(dummy); + } + + uint16_t final_checksum = eeprom_checksum, + eeprom_size = eeprom_index; + + eeprom_index = EEPROM_OFFSET; + EEPROM_WRITE(version); + EEPROM_WRITE(final_checksum); + + // Report storage size + SERIAL_ECHO_START; + SERIAL_ECHOPAIR("Settings Stored (", eeprom_size); + SERIAL_ECHOLNPGM(" bytes)"); +} + +/** + * M501 - Retrieve Configuration + */ +void Config_RetrieveSettings() { + + EEPROM_START(); + + char stored_ver[4]; + EEPROM_READ(stored_ver); + + uint16_t stored_checksum; + EEPROM_READ(stored_checksum); + + // SERIAL_ECHOPAIR("Version: [", ver); + // SERIAL_ECHOPAIR("] Stored version: [", stored_ver); + // SERIAL_ECHOLNPGM("]"); + + if (strncmp(version, stored_ver, 3) != 0) { + Config_ResetDefault(); + } + else { + float dummy = 0; + + eeprom_checksum = 0; // clear before reading first "real data" + + // version number match + EEPROM_READ(planner.axis_steps_per_mm); + EEPROM_READ(planner.max_feedrate_mm_s); + EEPROM_READ(planner.max_acceleration_mm_per_s2); + + EEPROM_READ(planner.acceleration); + EEPROM_READ(planner.retract_acceleration); + EEPROM_READ(planner.travel_acceleration); + EEPROM_READ(planner.min_feedrate_mm_s); + EEPROM_READ(planner.min_travel_feedrate_mm_s); + EEPROM_READ(planner.min_segment_time); + EEPROM_READ(planner.max_xy_jerk); + EEPROM_READ(planner.max_z_jerk); + EEPROM_READ(planner.max_e_jerk); + EEPROM_READ(home_offset); + + uint8_t dummy_uint8 = 0, mesh_num_x = 0, mesh_num_y = 0; + EEPROM_READ(dummy_uint8); + EEPROM_READ(dummy); + EEPROM_READ(mesh_num_x); + EEPROM_READ(mesh_num_y); + #if ENABLED(MESH_BED_LEVELING) + mbl.status = dummy_uint8; + mbl.z_offset = dummy; + if (mesh_num_x == MESH_NUM_X_POINTS && mesh_num_y == MESH_NUM_Y_POINTS) { + // EEPROM data fits the current mesh + EEPROM_READ(mbl.z_values); + } + else { + // EEPROM data is stale + mbl.reset(); + for (uint8_t q = 0; q < mesh_num_x * mesh_num_y; q++) EEPROM_READ(dummy); + } + #else + // MBL is disabled - skip the stored data + for (uint8_t q = 0; q < mesh_num_x * mesh_num_y; q++) EEPROM_READ(dummy); + #endif // MESH_BED_LEVELING + + #if !HAS_BED_PROBE + float zprobe_zoffset = 0; + #endif + EEPROM_READ(zprobe_zoffset); + + #if ENABLED(DELTA) + EEPROM_READ(endstop_adj); // 3 floats + EEPROM_READ(delta_radius); // 1 float + EEPROM_READ(delta_diagonal_rod); // 1 float + EEPROM_READ(delta_segments_per_second); // 1 float + EEPROM_READ(delta_diagonal_rod_trim_tower_1); // 1 float + EEPROM_READ(delta_diagonal_rod_trim_tower_2); // 1 float + EEPROM_READ(delta_diagonal_rod_trim_tower_3); // 1 float + #elif ENABLED(Z_DUAL_ENDSTOPS) + EEPROM_READ(z_endstop_adj); + dummy = 0.0f; + for (uint8_t q=8; q--;) EEPROM_READ(dummy); + #else + dummy = 0.0f; + for (uint8_t q=9; q--;) EEPROM_READ(dummy); + #endif + + #if DISABLED(ULTIPANEL) + int preheatHotendTemp1, preheatBedTemp1, preheatFanSpeed1, + preheatHotendTemp2, preheatBedTemp2, preheatFanSpeed2; + #endif + + EEPROM_READ(preheatHotendTemp1); + EEPROM_READ(preheatBedTemp1); + EEPROM_READ(preheatFanSpeed1); + EEPROM_READ(preheatHotendTemp2); + EEPROM_READ(preheatBedTemp2); + EEPROM_READ(preheatFanSpeed2); + + #if ENABLED(PIDTEMP) + for (uint8_t e = 0; e < MAX_EXTRUDERS; e++) { + EEPROM_READ(dummy); // Kp + if (e < HOTENDS && dummy != DUMMY_PID_VALUE) { + // do not need to scale PID values as the values in EEPROM are already scaled + PID_PARAM(Kp, e) = dummy; + EEPROM_READ(PID_PARAM(Ki, e)); + EEPROM_READ(PID_PARAM(Kd, e)); + #if ENABLED(PID_EXTRUSION_SCALING) + EEPROM_READ(PID_PARAM(Kc, e)); + #else + EEPROM_READ(dummy); + #endif + } + else { + for (uint8_t q=3; q--;) EEPROM_READ(dummy); // Ki, Kd, Kc + } + } + #else // !PIDTEMP + // 4 x 4 = 16 slots for PID parameters + for (uint8_t q = MAX_EXTRUDERS * 4; q--;) EEPROM_READ(dummy); // Kp, Ki, Kd, Kc + #endif // !PIDTEMP + + #if DISABLED(PID_EXTRUSION_SCALING) + int lpq_len; + #endif + EEPROM_READ(lpq_len); + + #if ENABLED(PIDTEMPBED) + EEPROM_READ(dummy); // bedKp + if (dummy != DUMMY_PID_VALUE) { + thermalManager.bedKp = dummy; + EEPROM_READ(thermalManager.bedKi); + EEPROM_READ(thermalManager.bedKd); + } + #else + for (uint8_t q=3; q--;) EEPROM_READ(dummy); // bedKp, bedKi, bedKd + #endif + + #if !HAS_LCD_CONTRAST + int lcd_contrast; + #endif + EEPROM_READ(lcd_contrast); + + #if ENABLED(SCARA) + EEPROM_READ(axis_scaling); // 3 floats + #else + EEPROM_READ(dummy); + #endif + + #if ENABLED(FWRETRACT) + EEPROM_READ(autoretract_enabled); + EEPROM_READ(retract_length); + #if EXTRUDERS > 1 + EEPROM_READ(retract_length_swap); + #else + EEPROM_READ(dummy); + #endif + EEPROM_READ(retract_feedrate_mm_s); + EEPROM_READ(retract_zlift); + EEPROM_READ(retract_recover_length); + #if EXTRUDERS > 1 + EEPROM_READ(retract_recover_length_swap); + #else + EEPROM_READ(dummy); + #endif + EEPROM_READ(retract_recover_feedrate_mm_s); + #endif // FWRETRACT + + EEPROM_READ(volumetric_enabled); + + for (uint8_t q = 0; q < MAX_EXTRUDERS; q++) { + EEPROM_READ(dummy); + if (q < COUNT(filament_size)) filament_size[q] = dummy; + } + + if (eeprom_checksum == stored_checksum) { + Config_Postprocess(); + SERIAL_ECHO_START; + SERIAL_ECHO(version); + SERIAL_ECHOPAIR(" stored settings retrieved (", eeprom_index); + SERIAL_ECHOLNPGM(" bytes)"); + } + else { + SERIAL_ERROR_START; + SERIAL_ERRORLNPGM("EEPROM checksum mismatch"); + Config_ResetDefault(); + } + } + + #if ENABLED(EEPROM_CHITCHAT) + Config_PrintSettings(); + #endif +} + +#endif // EEPROM_SETTINGS + +/** + * M502 - Reset Configuration + */ +void Config_ResetDefault() { + float tmp1[] = DEFAULT_AXIS_STEPS_PER_UNIT; + float tmp2[] = DEFAULT_MAX_FEEDRATE; + long tmp3[] = DEFAULT_MAX_ACCELERATION; + LOOP_XYZE(i) { + planner.axis_steps_per_mm[i] = tmp1[i]; + planner.max_feedrate_mm_s[i] = tmp2[i]; + planner.max_acceleration_mm_per_s2[i] = tmp3[i]; + #if ENABLED(SCARA) + if (i < COUNT(axis_scaling)) + axis_scaling[i] = 1; + #endif + } + + planner.acceleration = DEFAULT_ACCELERATION; + planner.retract_acceleration = DEFAULT_RETRACT_ACCELERATION; + planner.travel_acceleration = DEFAULT_TRAVEL_ACCELERATION; + planner.min_feedrate_mm_s = DEFAULT_MINIMUMFEEDRATE; + planner.min_segment_time = DEFAULT_MINSEGMENTTIME; + planner.min_travel_feedrate_mm_s = DEFAULT_MINTRAVELFEEDRATE; + planner.max_xy_jerk = DEFAULT_XYJERK; + planner.max_z_jerk = DEFAULT_ZJERK; + planner.max_e_jerk = DEFAULT_EJERK; + home_offset[X_AXIS] = home_offset[Y_AXIS] = home_offset[Z_AXIS] = 0; + + #if ENABLED(MESH_BED_LEVELING) + mbl.reset(); + #endif + + #if HAS_BED_PROBE + zprobe_zoffset = Z_PROBE_OFFSET_FROM_EXTRUDER; + #endif + + #if ENABLED(DELTA) + endstop_adj[X_AXIS] = endstop_adj[Y_AXIS] = endstop_adj[Z_AXIS] = 0; + delta_radius = DELTA_RADIUS; + delta_diagonal_rod = DELTA_DIAGONAL_ROD; + delta_segments_per_second = DELTA_SEGMENTS_PER_SECOND; + delta_diagonal_rod_trim_tower_1 = DELTA_DIAGONAL_ROD_TRIM_TOWER_1; + delta_diagonal_rod_trim_tower_2 = DELTA_DIAGONAL_ROD_TRIM_TOWER_2; + delta_diagonal_rod_trim_tower_3 = DELTA_DIAGONAL_ROD_TRIM_TOWER_3; + #elif ENABLED(Z_DUAL_ENDSTOPS) + z_endstop_adj = 0; + #endif + + #if ENABLED(ULTIPANEL) + preheatHotendTemp1 = PREHEAT_1_TEMP_HOTEND; + preheatBedTemp1 = PREHEAT_1_TEMP_BED; + preheatFanSpeed1 = PREHEAT_1_FAN_SPEED; + preheatHotendTemp2 = PREHEAT_2_TEMP_HOTEND; + preheatBedTemp2 = PREHEAT_2_TEMP_BED; + preheatFanSpeed2 = PREHEAT_2_FAN_SPEED; + #endif + + #if HAS_LCD_CONTRAST + lcd_contrast = DEFAULT_LCD_CONTRAST; + #endif + + #if ENABLED(PIDTEMP) + #if ENABLED(PID_PARAMS_PER_HOTEND) && HOTENDS > 1 + HOTEND_LOOP() + #else + int e = 0; UNUSED(e); // only need to write once + #endif + { + PID_PARAM(Kp, e) = DEFAULT_Kp; + PID_PARAM(Ki, e) = scalePID_i(DEFAULT_Ki); + PID_PARAM(Kd, e) = scalePID_d(DEFAULT_Kd); + #if ENABLED(PID_EXTRUSION_SCALING) + PID_PARAM(Kc, e) = DEFAULT_Kc; + #endif + } + #if ENABLED(PID_EXTRUSION_SCALING) + lpq_len = 20; // default last-position-queue size + #endif + #endif // PIDTEMP + + #if ENABLED(PIDTEMPBED) + thermalManager.bedKp = DEFAULT_bedKp; + thermalManager.bedKi = scalePID_i(DEFAULT_bedKi); + thermalManager.bedKd = scalePID_d(DEFAULT_bedKd); + #endif + + #if ENABLED(FWRETRACT) + autoretract_enabled = false; + retract_length = RETRACT_LENGTH; + #if EXTRUDERS > 1 + retract_length_swap = RETRACT_LENGTH_SWAP; + #endif + retract_feedrate_mm_s = RETRACT_FEEDRATE; + retract_zlift = RETRACT_ZLIFT; + retract_recover_length = RETRACT_RECOVER_LENGTH; + #if EXTRUDERS > 1 + retract_recover_length_swap = RETRACT_RECOVER_LENGTH_SWAP; + #endif + retract_recover_feedrate_mm_s = RETRACT_RECOVER_FEEDRATE; + #endif + + volumetric_enabled = false; + for (uint8_t q = 0; q < COUNT(filament_size); q++) + filament_size[q] = DEFAULT_NOMINAL_FILAMENT_DIA; + + endstops.enable_globally( + #if ENABLED(ENDSTOPS_ALWAYS_ON_DEFAULT) + (true) + #else + (false) + #endif + ); + + Config_Postprocess(); + + SERIAL_ECHO_START; + SERIAL_ECHOLNPGM("Hardcoded Default Settings Loaded"); +} + +#if DISABLED(DISABLE_M503) + +#define CONFIG_ECHO_START do{ if (!forReplay) SERIAL_ECHO_START; }while(0) + +/** + * M503 - Print Configuration + */ +void Config_PrintSettings(bool forReplay) { + // Always have this function, even with EEPROM_SETTINGS disabled, the current values will be shown + + CONFIG_ECHO_START; + + if (!forReplay) { + SERIAL_ECHOLNPGM("Steps per unit:"); + CONFIG_ECHO_START; + } + SERIAL_ECHOPAIR(" M92 X", planner.axis_steps_per_mm[X_AXIS]); + SERIAL_ECHOPAIR(" Y", planner.axis_steps_per_mm[Y_AXIS]); + SERIAL_ECHOPAIR(" Z", planner.axis_steps_per_mm[Z_AXIS]); + SERIAL_ECHOPAIR(" E", planner.axis_steps_per_mm[E_AXIS]); + SERIAL_EOL; + + CONFIG_ECHO_START; + + #if ENABLED(SCARA) + if (!forReplay) { + SERIAL_ECHOLNPGM("Scaling factors:"); + CONFIG_ECHO_START; + } + SERIAL_ECHOPAIR(" M365 X", axis_scaling[X_AXIS]); + SERIAL_ECHOPAIR(" Y", axis_scaling[Y_AXIS]); + SERIAL_ECHOPAIR(" Z", axis_scaling[Z_AXIS]); + SERIAL_EOL; + CONFIG_ECHO_START; + #endif // SCARA + + if (!forReplay) { + SERIAL_ECHOLNPGM("Maximum feedrates (mm/s):"); + CONFIG_ECHO_START; + } + SERIAL_ECHOPAIR(" M203 X", planner.max_feedrate_mm_s[X_AXIS]); + SERIAL_ECHOPAIR(" Y", planner.max_feedrate_mm_s[Y_AXIS]); + SERIAL_ECHOPAIR(" Z", planner.max_feedrate_mm_s[Z_AXIS]); + SERIAL_ECHOPAIR(" E", planner.max_feedrate_mm_s[E_AXIS]); + SERIAL_EOL; + + CONFIG_ECHO_START; + if (!forReplay) { + SERIAL_ECHOLNPGM("Maximum Acceleration (mm/s2):"); + CONFIG_ECHO_START; + } + SERIAL_ECHOPAIR(" M201 X", planner.max_acceleration_mm_per_s2[X_AXIS]); + SERIAL_ECHOPAIR(" Y", planner.max_acceleration_mm_per_s2[Y_AXIS]); + SERIAL_ECHOPAIR(" Z", planner.max_acceleration_mm_per_s2[Z_AXIS]); + SERIAL_ECHOPAIR(" E", planner.max_acceleration_mm_per_s2[E_AXIS]); + SERIAL_EOL; + CONFIG_ECHO_START; + if (!forReplay) { + SERIAL_ECHOLNPGM("Accelerations: P=printing, R=retract and T=travel"); + CONFIG_ECHO_START; + } + SERIAL_ECHOPAIR(" M204 P", planner.acceleration); + SERIAL_ECHOPAIR(" R", planner.retract_acceleration); + SERIAL_ECHOPAIR(" T", planner.travel_acceleration); + SERIAL_EOL; + + CONFIG_ECHO_START; + if (!forReplay) { + SERIAL_ECHOLNPGM("Advanced variables: S=Min feedrate (mm/s), T=Min travel feedrate (mm/s), B=minimum segment time (ms), X=maximum XY jerk (mm/s), Z=maximum Z jerk (mm/s), E=maximum E jerk (mm/s)"); + CONFIG_ECHO_START; + } + SERIAL_ECHOPAIR(" M205 S", planner.min_feedrate_mm_s); + SERIAL_ECHOPAIR(" T", planner.min_travel_feedrate_mm_s); + SERIAL_ECHOPAIR(" B", planner.min_segment_time); + SERIAL_ECHOPAIR(" X", planner.max_xy_jerk); + SERIAL_ECHOPAIR(" Z", planner.max_z_jerk); + SERIAL_ECHOPAIR(" E", planner.max_e_jerk); + SERIAL_EOL; + + CONFIG_ECHO_START; + if (!forReplay) { + SERIAL_ECHOLNPGM("Home offset (mm)"); + CONFIG_ECHO_START; + } + SERIAL_ECHOPAIR(" M206 X", home_offset[X_AXIS]); + SERIAL_ECHOPAIR(" Y", home_offset[Y_AXIS]); + SERIAL_ECHOPAIR(" Z", home_offset[Z_AXIS]); + SERIAL_EOL; + + #if ENABLED(MESH_BED_LEVELING) + if (!forReplay) { + SERIAL_ECHOLNPGM("Mesh bed leveling:"); + CONFIG_ECHO_START; + } + SERIAL_ECHOPAIR(" M420 S", mbl.has_mesh() ? 1 : 0); + SERIAL_ECHOPAIR(" X", MESH_NUM_X_POINTS); + SERIAL_ECHOPAIR(" Y", MESH_NUM_Y_POINTS); + SERIAL_EOL; + for (uint8_t py = 1; py <= MESH_NUM_Y_POINTS; py++) { + for (uint8_t px = 1; px <= MESH_NUM_X_POINTS; px++) { + CONFIG_ECHO_START; + SERIAL_ECHOPAIR(" G29 S3 X", px); + SERIAL_ECHOPAIR(" Y", py); + SERIAL_ECHOPGM(" Z"); + SERIAL_PROTOCOL_F(mbl.z_values[py-1][px-1], 5); + SERIAL_EOL; + } + } + #endif + + #if ENABLED(DELTA) + CONFIG_ECHO_START; + if (!forReplay) { + SERIAL_ECHOLNPGM("Endstop adjustment (mm):"); + CONFIG_ECHO_START; + } + SERIAL_ECHOPAIR(" M666 X", endstop_adj[X_AXIS]); + SERIAL_ECHOPAIR(" Y", endstop_adj[Y_AXIS]); + SERIAL_ECHOPAIR(" Z", endstop_adj[Z_AXIS]); + SERIAL_EOL; + CONFIG_ECHO_START; + if (!forReplay) { + SERIAL_ECHOLNPGM("Delta settings: L=diagonal_rod, R=radius, S=segments_per_second, ABC=diagonal_rod_trim_tower_[123]"); + CONFIG_ECHO_START; + } + SERIAL_ECHOPAIR(" M665 L", delta_diagonal_rod); + SERIAL_ECHOPAIR(" R", delta_radius); + SERIAL_ECHOPAIR(" S", delta_segments_per_second); + SERIAL_ECHOPAIR(" A", delta_diagonal_rod_trim_tower_1); + SERIAL_ECHOPAIR(" B", delta_diagonal_rod_trim_tower_2); + SERIAL_ECHOPAIR(" C", delta_diagonal_rod_trim_tower_3); + SERIAL_EOL; + #elif ENABLED(Z_DUAL_ENDSTOPS) + CONFIG_ECHO_START; + if (!forReplay) { + SERIAL_ECHOLNPGM("Z2 Endstop adjustment (mm):"); + CONFIG_ECHO_START; + } + SERIAL_ECHOPAIR(" M666 Z", z_endstop_adj); + SERIAL_EOL; + #endif // DELTA + + #if ENABLED(ULTIPANEL) + CONFIG_ECHO_START; + if (!forReplay) { + SERIAL_ECHOLNPGM("Material heatup parameters:"); + CONFIG_ECHO_START; + } + SERIAL_ECHOPAIR(" M145 S0 H", preheatHotendTemp1); + SERIAL_ECHOPAIR(" B", preheatBedTemp1); + SERIAL_ECHOPAIR(" F", preheatFanSpeed1); + SERIAL_EOL; + CONFIG_ECHO_START; + SERIAL_ECHOPAIR(" M145 S1 H", preheatHotendTemp2); + SERIAL_ECHOPAIR(" B", preheatBedTemp2); + SERIAL_ECHOPAIR(" F", preheatFanSpeed2); + SERIAL_EOL; + #endif // ULTIPANEL + + #if HAS_PID_HEATING + + CONFIG_ECHO_START; + if (!forReplay) { + SERIAL_ECHOLNPGM("PID settings:"); + } + #if ENABLED(PIDTEMP) + #if HOTENDS > 1 + if (forReplay) { + HOTEND_LOOP() { + CONFIG_ECHO_START; + SERIAL_ECHOPAIR(" M301 E", e); + SERIAL_ECHOPAIR(" P", PID_PARAM(Kp, e)); + SERIAL_ECHOPAIR(" I", unscalePID_i(PID_PARAM(Ki, e))); + SERIAL_ECHOPAIR(" D", unscalePID_d(PID_PARAM(Kd, e))); + #if ENABLED(PID_EXTRUSION_SCALING) + SERIAL_ECHOPAIR(" C", PID_PARAM(Kc, e)); + if (e == 0) SERIAL_ECHOPAIR(" L", lpq_len); + #endif + SERIAL_EOL; + } + } + else + #endif // HOTENDS > 1 + // !forReplay || HOTENDS == 1 + { + CONFIG_ECHO_START; + SERIAL_ECHOPAIR(" M301 P", PID_PARAM(Kp, 0)); // for compatibility with hosts, only echo values for E0 + SERIAL_ECHOPAIR(" I", unscalePID_i(PID_PARAM(Ki, 0))); + SERIAL_ECHOPAIR(" D", unscalePID_d(PID_PARAM(Kd, 0))); + #if ENABLED(PID_EXTRUSION_SCALING) + SERIAL_ECHOPAIR(" C", PID_PARAM(Kc, 0)); + SERIAL_ECHOPAIR(" L", lpq_len); + #endif + SERIAL_EOL; + } + #endif // PIDTEMP + + #if ENABLED(PIDTEMPBED) + CONFIG_ECHO_START; + SERIAL_ECHOPAIR(" M304 P", thermalManager.bedKp); + SERIAL_ECHOPAIR(" I", unscalePID_i(thermalManager.bedKi)); + SERIAL_ECHOPAIR(" D", unscalePID_d(thermalManager.bedKd)); + SERIAL_EOL; + #endif + + #endif // PIDTEMP || PIDTEMPBED + + #if HAS_LCD_CONTRAST + CONFIG_ECHO_START; + if (!forReplay) { + SERIAL_ECHOLNPGM("LCD Contrast:"); + CONFIG_ECHO_START; + } + SERIAL_ECHOPAIR(" M250 C", lcd_contrast); + SERIAL_EOL; + #endif + + #if ENABLED(FWRETRACT) + + CONFIG_ECHO_START; + if (!forReplay) { + SERIAL_ECHOLNPGM("Retract: S=Length (mm) F:Speed (mm/m) Z: ZLift (mm)"); + CONFIG_ECHO_START; + } + SERIAL_ECHOPAIR(" M207 S", retract_length); + #if EXTRUDERS > 1 + SERIAL_ECHOPAIR(" W", retract_length_swap); + #endif + SERIAL_ECHOPAIR(" F", MMS_TO_MMM(retract_feedrate_mm_s)); + SERIAL_ECHOPAIR(" Z", retract_zlift); + SERIAL_EOL; + CONFIG_ECHO_START; + if (!forReplay) { + SERIAL_ECHOLNPGM("Recover: S=Extra length (mm) F:Speed (mm/m)"); + CONFIG_ECHO_START; + } + SERIAL_ECHOPAIR(" M208 S", retract_recover_length); + #if EXTRUDERS > 1 + SERIAL_ECHOPAIR(" W", retract_recover_length_swap); + #endif + SERIAL_ECHOPAIR(" F", MMS_TO_MMM(retract_recover_feedrate_mm_s)); + SERIAL_EOL; + CONFIG_ECHO_START; + if (!forReplay) { + SERIAL_ECHOLNPGM("Auto-Retract: S=0 to disable, 1 to interpret extrude-only moves as retracts or recoveries"); + CONFIG_ECHO_START; + } + SERIAL_ECHOPAIR(" M209 S", autoretract_enabled ? 1 : 0); + SERIAL_EOL; + + #endif // FWRETRACT + + /** + * Volumetric extrusion M200 + */ + if (!forReplay) { + CONFIG_ECHO_START; + SERIAL_ECHOPGM("Filament settings:"); + if (volumetric_enabled) + SERIAL_EOL; + else + SERIAL_ECHOLNPGM(" Disabled"); + } + + CONFIG_ECHO_START; + SERIAL_ECHOPAIR(" M200 D", filament_size[0]); + SERIAL_EOL; + #if EXTRUDERS > 1 + CONFIG_ECHO_START; + SERIAL_ECHOPAIR(" M200 T1 D", filament_size[1]); + SERIAL_EOL; + #if EXTRUDERS > 2 + CONFIG_ECHO_START; + SERIAL_ECHOPAIR(" M200 T2 D", filament_size[2]); + SERIAL_EOL; + #if EXTRUDERS > 3 + CONFIG_ECHO_START; + SERIAL_ECHOPAIR(" M200 T3 D", filament_size[3]); + SERIAL_EOL; + #endif + #endif + #endif + + if (!volumetric_enabled) { + CONFIG_ECHO_START; + SERIAL_ECHOLNPGM(" M200 D0"); + } + + /** + * Auto Bed Leveling + */ + #if HAS_BED_PROBE + if (!forReplay) { + CONFIG_ECHO_START; + SERIAL_ECHOLNPGM("Z-Probe Offset (mm):"); + } + CONFIG_ECHO_START; + SERIAL_ECHOPAIR(" M851 Z", zprobe_zoffset); + SERIAL_EOL; + #endif +} + +#endif // !DISABLE_M503 diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/configuration_store.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/configuration_store.h new file mode 100644 index 00000000..891f19fb --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/configuration_store.h @@ -0,0 +1,44 @@ +/** + * 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 . + * + */ + +#ifndef CONFIGURATION_STORE_H +#define CONFIGURATION_STORE_H + +#include "MarlinConfig.h" + +void Config_ResetDefault(); + +#if DISABLED(DISABLE_M503) + void Config_PrintSettings(bool forReplay=false); +#else + FORCE_INLINE void Config_PrintSettings(bool forReplay=false) {} +#endif + +#if ENABLED(EEPROM_SETTINGS) + void Config_StoreSettings(); + void Config_RetrieveSettings(); +#else + FORCE_INLINE void Config_StoreSettings() {} + FORCE_INLINE void Config_RetrieveSettings() { Config_ResetDefault(); Config_PrintSettings(); } +#endif + +#endif //CONFIGURATION_STORE_H diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/dac_mcp4728.cpp b/trunk/Arduino/Marlin_K8600_1.1.0RC7/dac_mcp4728.cpp new file mode 100644 index 00000000..01e38edf --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/dac_mcp4728.cpp @@ -0,0 +1,138 @@ +/** + * 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 . + * + */ + +/** + * 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 + * + * For discussion and feedback, please go to: + * http://arduino.cc/forum/index.php/topic,51842.0.html + */ + +#include "dac_mcp4728.h" + +#if ENABLED(DAC_STEPPER_CURRENT) + +uint16_t mcp4728_values[4]; + +/** + * Begin I2C, get current values (input register and eeprom) of mcp4728 + */ +void mcp4728_init() { + Wire.begin(); + Wire.requestFrom(int(DAC_DEV_ADDRESS), 24); + while(Wire.available()) { + int deviceID = Wire.read(); + int hiByte = Wire.read(); + int loByte = Wire.read(); + + int isEEPROM = (deviceID & 0B00001000) >> 3; + int channel = (deviceID & 0B00110000) >> 4; + if (isEEPROM != 1) { + mcp4728_values[channel] = word((hiByte & 0B00001111), loByte); + } + } +} + +/** + * Write input resister value to specified channel using fastwrite method. + * Channel : 0-3, Values : 0-4095 + */ +uint8_t mcp4728_analogWrite(uint8_t channel, uint16_t value) { + mcp4728_values[channel] = value; + return mcp4728_fastWrite(); +} +/** + * Write all input resistor values to EEPROM using SequencialWrite method. + * This will update both input register and EEPROM value + * This will also write current Vref, PowerDown, Gain settings to EEPROM + */ +uint8_t mcp4728_eepromWrite() { + Wire.beginTransmission(DAC_DEV_ADDRESS); + Wire.write(SEQWRITE); + for (uint8_t channel=0; channel <= 3; channel++) { + Wire.write(DAC_STEPPER_VREF << 7 | 0 << 5 | DAC_STEPPER_GAIN << 4 | highByte(mcp4728_values[channel])); + Wire.write(lowByte(mcp4728_values[channel])); + } + return Wire.endTransmission(); +} + +/** + * Write Voltage reference setting to all input regiters + */ +uint8_t mcp4728_setVref_all(uint8_t value) { + Wire.beginTransmission(DAC_DEV_ADDRESS); + Wire.write(VREFWRITE | value << 3 | value << 2 | value << 1 | value); + return Wire.endTransmission(); +} +/** + * Write Gain setting to all input regiters + */ +uint8_t mcp4728_setGain_all(uint8_t value) { + Wire.beginTransmission(DAC_DEV_ADDRESS); + Wire.write(GAINWRITE | value << 3 | value << 2 | value << 1 | value); + return Wire.endTransmission(); +} + +/** + * Return Input Regiter value + */ +uint16_t mcp4728_getValue(uint8_t channel) { return mcp4728_values[channel]; } + +/** + * Steph: Might be useful in the future + * Return Vout + * +uint16_t mcp4728_getVout(uint8_t channel) { + uint32_t vref = 2048; + uint32_t vOut = (vref * mcp4728_values[channel] * (_DAC_STEPPER_GAIN + 1)) / 4096; + if (vOut > defaultVDD) vOut = defaultVDD; + return vOut; +} +*/ + +/** + * FastWrite input register values - All DAC ouput update. refer to DATASHEET 5.6.1 + * DAC Input and PowerDown bits update. + * No EEPROM update + */ +uint8_t mcp4728_fastWrite() { + Wire.beginTransmission(DAC_DEV_ADDRESS); + for (uint8_t channel=0; channel <= 3; channel++) { + Wire.write(highByte(mcp4728_values[channel])); + Wire.write(lowByte(mcp4728_values[channel])); + } + return Wire.endTransmission(); +} + +/** + * Common function for simple general commands + */ +uint8_t mcp4728_simpleCommand(byte simpleCommand) { + Wire.beginTransmission(GENERALCALL); + Wire.write(simpleCommand); + return Wire.endTransmission(); +} + +#endif // DAC_STEPPER_CURRENT diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/dac_mcp4728.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/dac_mcp4728.h new file mode 100644 index 00000000..c096c856 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/dac_mcp4728.h @@ -0,0 +1,65 @@ +/** + * 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 . + * + */ + +/** + * Arduino library for MicroChip MCP4728 I2C D/A converter. + */ + +#ifndef mcp4728_h +#define mcp4728_h + +#include "MarlinConfig.h" + +#if ENABLED(DAC_STEPPER_CURRENT) +#include "Wire.h" + +#define defaultVDD 5000 +#define BASE_ADDR 0x60 +#define RESET 0B00000110 +#define WAKE 0B00001001 +#define UPDATE 0B00001000 +#define MULTIWRITE 0B01000000 +#define SINGLEWRITE 0B01011000 +#define SEQWRITE 0B01010000 +#define VREFWRITE 0B10000000 +#define GAINWRITE 0B11000000 +#define POWERDOWNWRITE 0B10100000 +#define GENERALCALL 0B00000000 +#define GAINWRITE 0B11000000 + +// This is taken from the original lib, makes it easy to edit if needed +// 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(uint8_t channel, uint16_t value); +uint8_t mcp4728_eepromWrite(); +uint8_t mcp4728_setVref_all(uint8_t value); +uint8_t mcp4728_setGain_all(uint8_t value); +uint16_t mcp4728_getValue(uint8_t channel); +uint8_t mcp4728_fastWrite(); +uint8_t mcp4728_simpleCommand(byte simpleCommand); + +#endif +#endif + diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/digipot_mcp4451.cpp b/trunk/Arduino/Marlin_K8600_1.1.0RC7/digipot_mcp4451.cpp new file mode 100644 index 00000000..c6a01915 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/digipot_mcp4451.cpp @@ -0,0 +1,79 @@ +/** + * 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 . + * + */ + +#include "MarlinConfig.h" + +#if ENABLED(DIGIPOT_I2C) + +#include "Stream.h" +#include "utility/twi.h" +#include "Wire.h" + +// 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 +#else + #define DIGIPOT_I2C_FACTOR 106.7 + #define DIGIPOT_I2C_MAX_CURRENT 2.5 +#endif + +static byte current_to_wiper(float current) { + return byte(ceil(float((DIGIPOT_I2C_FACTOR * current)))); +} + +static void i2c_send(byte addr, byte a, byte b) { + Wire.beginTransmission(addr); + Wire.write(a); + Wire.write(b); + Wire.endTransmission(); +} + +// This is for the MCP4451 I2C based digipot +void digipot_i2c_set_current(int channel, float current) { + current = min((float) max(current, 0.0f), DIGIPOT_I2C_MAX_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 + byte addr = 0x2C; // channel 0-3 + if (channel >= 4) { + addr = 0x2E; // channel 4-7 + channel -= 4; + } + + // Initial setup + i2c_send(addr, 0x40, 0xff); + i2c_send(addr, 0xA0, 0xff); + + // Set actual wiper value + byte addresses[4] = { 0x00, 0x10, 0x60, 0x70 }; + i2c_send(addr, addresses[channel], current_to_wiper(current)); +} + +void digipot_i2c_init() { + const float digipot_motor_current[] = DIGIPOT_I2C_MOTOR_CURRENTS; + Wire.begin(); + // setup initial currents as defined in Configuration_adv.h + for (int i = 0; i < COUNT(digipot_motor_current); i++) + digipot_i2c_set_current(i, digipot_motor_current[i]); +} + +#endif //DIGIPOT_I2C diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/dogm_bitmaps.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/dogm_bitmaps.h new file mode 100644 index 00000000..e020d243 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/dogm_bitmaps.h @@ -0,0 +1,422 @@ +/** + * 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 . + * + */ + +/** + * Standard Marlin Bitmap for splashscreen + * + * You may use one of the following tools to generate the C++ bitmap array from + * a black and white image: + * + * - http://www.marlinfw.org/tools/u8glib/converter.html + * - http://www.digole.com/tools/PicturetoC_Hex_converter.php + * + * Please note that using the high-res version takes 402Bytes of PROGMEM. + */ + +//#define START_BMPHIGH + +#if ENABLED(SHOW_BOOTSCREEN) + #if ENABLED(START_BMPHIGH) + #define START_BMPWIDTH 112 + #define START_BMPHEIGHT 38 + #define START_BMPBYTEWIDTH 14 + #define START_BMPBYTES 532 // START_BMPWIDTH * START_BMPHEIGHT / 8 + + const unsigned char start_bmp[START_BMPBYTES] PROGMEM = { + 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, + 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, + 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, + 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x3F, 0xFF, + 0xC0, 0x0F, 0xC0, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x18, 0x00, 0x1F, 0xFF, + 0xC0, 0x3F, 0xE1, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x3C, 0x00, 0x0F, 0xFF, + 0xC0, 0x7F, 0xF3, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x78, 0x3C, 0x00, 0x07, 0xFF, + 0xC0, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x78, 0x3C, 0x00, 0x03, 0xFF, + 0xC1, 0xF8, 0x7F, 0x87, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x01, 0xFF, + 0xC1, 0xF0, 0x3F, 0x03, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0xFF, + 0xC1, 0xE0, 0x1E, 0x01, 0xE0, 0x1F, 0x00, 0x03, 0xE0, 0x78, 0x3C, 0x03, 0xF0, 0x7F, + 0xC1, 0xE0, 0x1E, 0x01, 0xE0, 0x7F, 0xC0, 0x0F, 0xF8, 0x78, 0x3C, 0x07, 0xFC, 0x3F, + 0xC1, 0xE0, 0x1E, 0x01, 0xE1, 0xFF, 0xE0, 0x1F, 0xFC, 0x78, 0x3C, 0x0F, 0xFE, 0x1F, + 0xC1, 0xE0, 0x1E, 0x01, 0xE3, 0xFF, 0xF0, 0x3F, 0xFE, 0x78, 0x3C, 0x1F, 0xFE, 0x0F, + 0xC1, 0xE0, 0x1E, 0x01, 0xE3, 0xF3, 0xF8, 0x3F, 0x3E, 0x78, 0x3C, 0x3F, 0x3F, 0x07, + 0xC1, 0xE0, 0x1E, 0x01, 0xE7, 0xE0, 0xFC, 0x7C, 0x1F, 0x78, 0x3C, 0x3E, 0x1F, 0x07, + 0xC1, 0xE0, 0x1E, 0x01, 0xE7, 0xC0, 0x7C, 0x7C, 0x0F, 0x78, 0x3C, 0x3C, 0x0F, 0x03, + 0xC1, 0xE0, 0x1E, 0x01, 0xE7, 0x80, 0x7C, 0x78, 0x0F, 0x78, 0x3C, 0x3C, 0x0F, 0x03, + 0xC1, 0xE0, 0x1E, 0x01, 0xE7, 0x80, 0x3C, 0x78, 0x00, 0x78, 0x3C, 0x3C, 0x0F, 0x03, + 0xC1, 0xE0, 0x1E, 0x01, 0xE7, 0x80, 0x3C, 0x78, 0x00, 0x78, 0x3C, 0x3C, 0x0F, 0x03, + 0xC1, 0xE0, 0x1E, 0x01, 0xE7, 0x80, 0x3C, 0x78, 0x00, 0x78, 0x3C, 0x3C, 0x0F, 0x03, + 0xC1, 0xE0, 0x1E, 0x01, 0xE7, 0xC0, 0x3C, 0x78, 0x00, 0x78, 0x3C, 0x3C, 0x0F, 0x03, + 0xC1, 0xE0, 0x1E, 0x01, 0xE3, 0xE0, 0x3C, 0x78, 0x00, 0x7C, 0x3C, 0x3C, 0x0F, 0x03, + 0xC1, 0xE0, 0x1E, 0x01, 0xE3, 0xFF, 0x3F, 0xF8, 0x00, 0x7F, 0xBC, 0x3C, 0x0F, 0x03, + 0xC1, 0xE0, 0x1E, 0x01, 0xE1, 0xFF, 0x3F, 0xF8, 0x00, 0x3F, 0xBF, 0xFC, 0x0F, 0x03, + 0xC1, 0xE0, 0x1E, 0x01, 0xE0, 0xFF, 0x3F, 0xF8, 0x00, 0x1F, 0xBF, 0xFC, 0x0F, 0x03, + 0xC1, 0xE0, 0x1E, 0x01, 0xE0, 0x7F, 0x3F, 0xF8, 0x00, 0x0F, 0xBF, 0xFC, 0x0F, 0x03, + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, + 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, + 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, + 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, + 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, + 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80 }; + #else + #define START_BMPWIDTH 56 + #define START_BMPHEIGHT 19 + #define START_BMPBYTEWIDTH 7 + #define START_BMPBYTES 133 // START_BMPWIDTH * START_BMPHEIGHT / 8 + + const unsigned char start_bmp[START_BMPBYTES] PROGMEM = { + 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x60, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, + 0x83, 0xCF, 0x00, 0x00, 0x0C, 0x30, 0x3F, + 0x87, 0xFF, 0x80, 0x00, 0x0C, 0x30, 0x1F, + 0x86, 0x79, 0x80, 0x00, 0x0C, 0x00, 0x0F, + 0x8C, 0x30, 0xC7, 0x83, 0x8C, 0x30, 0xE7, + 0x8C, 0x30, 0xCF, 0xC7, 0xCC, 0x31, 0xF3, + 0x8C, 0x30, 0xDC, 0xEC, 0xEC, 0x33, 0xB9, + 0x8C, 0x30, 0xD8, 0x6C, 0x6C, 0x33, 0x19, + 0x8C, 0x30, 0xD0, 0x6C, 0x0C, 0x33, 0x19, + 0x8C, 0x30, 0xD8, 0x6C, 0x0C, 0x33, 0x19, + 0x8C, 0x30, 0xDC, 0x6C, 0x0E, 0x3B, 0x19, + 0x8C, 0x30, 0xCF, 0x7C, 0x07, 0x9F, 0x19, + 0x8C, 0x30, 0xC7, 0x7C, 0x03, 0x8F, 0x19, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, + 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8 }; + #endif +#endif + +// Here comes a compile-time operation to match the extruder symbols +// on the info screen to the set number of extruders in configuration.h +// +// When only one extruder is selected, the "1" on the symbol will not +// be displayed. + +#if HAS_TEMP_BED + #if HOTENDS == 1 + #define STATUS_SCREENWIDTH 115 //Width in pixels + #define STATUS_SCREENHEIGHT 19 //Height in pixels + #define STATUS_SCREENBYTEWIDTH 15 //Width in bytes + const unsigned char status_screen0_bmp[] PROGMEM = { //AVR-GCC, WinAVR + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x0C, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x0E, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4F, 0x0F, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x0F, 0xA0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5E, 0x07, 0xA0, + 0x7F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x04, 0x00, 0x40, 0x60, 0x20, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x82, 0x00, 0x40, 0xF0, 0x20, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x82, 0x00, 0x40, 0xF0, 0x20, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x04, 0x00, 0x40, 0x60, 0x20, + 0x7F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x08, 0x00, 0x5E, 0x07, 0xA0, + 0x7F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x10, 0x00, 0x5F, 0x0F, 0xA0, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x10, 0x00, 0x4F, 0x0F, 0x20, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x08, 0x00, 0x47, 0x0E, 0x20, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x04, 0x00, 0x63, 0x0C, 0x60, + 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, + 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x7F, 0xFF, 0xE0, + 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00 + }; + + #define STATUS_SCREENWIDTH 115 //Width in pixels + #define STATUS_SCREENHEIGHT 19 //Height in pixels + #define STATUS_SCREENBYTEWIDTH 15 //Width in bytes + const unsigned char status_screen1_bmp[] PROGMEM = { //AVR-GCC, WinAVR + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0xF8, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xF8, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xF0, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x60, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x01, 0xA0, + 0x7F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x04, 0x00, 0x5C, 0x63, 0xA0, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x82, 0x00, 0x5E, 0xF7, 0xA0, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x82, 0x00, 0x5E, 0xF7, 0xA0, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x04, 0x00, 0x5C, 0x63, 0xA0, + 0x7F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x08, 0x00, 0x58, 0x01, 0xA0, + 0x7F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x10, 0x00, 0x40, 0x60, 0x20, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x10, 0x00, 0x40, 0xF0, 0x20, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x08, 0x00, 0x41, 0xF8, 0x20, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x04, 0x00, 0x61, 0xF8, 0x60, + 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, + 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x7F, 0xFF, 0xE0, + 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00 + }; + #elif HOTENDS == 2 + #define STATUS_SCREENWIDTH 115 //Width in pixels + #define STATUS_SCREENHEIGHT 19 //Height in pixels + #define STATUS_SCREENBYTEWIDTH 15 //Width in bytes + const unsigned char status_screen0_bmp[] PROGMEM = { //AVR-GCC, WinAVR + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x0C, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x0E, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4F, 0x0F, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x0F, 0xA0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5E, 0x07, 0xA0, + 0x7F, 0x80, 0x00, 0x3F, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x41, 0x04, 0x00, 0x40, 0x60, 0x20, + 0xFB, 0xC0, 0x00, 0x79, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x20, 0x82, 0x00, 0x40, 0xF0, 0x20, + 0xF3, 0xC0, 0x00, 0x76, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x20, 0x82, 0x00, 0x40, 0xF0, 0x20, + 0xEB, 0xC0, 0x00, 0x7E, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x41, 0x04, 0x00, 0x40, 0x60, 0x20, + 0x7B, 0x80, 0x00, 0x3D, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x82, 0x08, 0x00, 0x5E, 0x07, 0xA0, + 0x7B, 0x80, 0x00, 0x3B, 0xC0, 0x00, 0x00, 0x00, 0x01, 0x04, 0x10, 0x00, 0x5F, 0x0F, 0xA0, + 0xFB, 0xC0, 0x00, 0x77, 0xE0, 0x00, 0x00, 0x00, 0x01, 0x04, 0x10, 0x00, 0x4F, 0x0F, 0x20, + 0xFB, 0xC0, 0x00, 0x70, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x82, 0x08, 0x00, 0x47, 0x0E, 0x20, + 0xFF, 0xC0, 0x00, 0x7F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x41, 0x04, 0x00, 0x63, 0x0C, 0x60, + 0x3F, 0x00, 0x00, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, + 0x1E, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x7F, 0xFF, 0xE0, + 0x0C, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00 + }; + + #define STATUS_SCREENWIDTH 115 //Width in pixels + #define STATUS_SCREENHEIGHT 19 //Height in pixels + #define STATUS_SCREENBYTEWIDTH 15 //Width in bytes + const unsigned char status_screen1_bmp[] PROGMEM = { //AVR-GCC, WinAVR + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0xF8, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xF8, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xF0, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x60, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x01, 0xA0, + 0x7F, 0x80, 0x00, 0x3F, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x41, 0x04, 0x00, 0x5C, 0x63, 0xA0, + 0xFB, 0xC0, 0x00, 0x79, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x20, 0x82, 0x00, 0x5E, 0xF7, 0xA0, + 0xF3, 0xC0, 0x00, 0x76, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x20, 0x82, 0x00, 0x5E, 0xF7, 0xA0, + 0xEB, 0xC0, 0x00, 0x7E, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x41, 0x04, 0x00, 0x5C, 0x63, 0xA0, + 0x7B, 0x80, 0x00, 0x3D, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x82, 0x08, 0x00, 0x58, 0x01, 0xA0, + 0x7B, 0x80, 0x00, 0x3B, 0xC0, 0x00, 0x00, 0x00, 0x01, 0x04, 0x10, 0x00, 0x40, 0x60, 0x20, + 0xFB, 0xC0, 0x00, 0x77, 0xE0, 0x00, 0x00, 0x00, 0x01, 0x04, 0x10, 0x00, 0x40, 0xF0, 0x20, + 0xFB, 0xC0, 0x00, 0x70, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x82, 0x08, 0x00, 0x41, 0xF8, 0x20, + 0xFF, 0xC0, 0x00, 0x7F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x41, 0x04, 0x00, 0x61, 0xF8, 0x60, + 0x3F, 0x00, 0x00, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, + 0x1E, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x7F, 0xFF, 0xE0, + 0x0C, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00 + }; + #else + #define STATUS_SCREENWIDTH 115 //Width in pixels + #define STATUS_SCREENHEIGHT 19 //Height in pixels + #define STATUS_SCREENBYTEWIDTH 15 //Width in bytes + const unsigned char status_screen0_bmp[] PROGMEM = { //AVR-GCC, WinAVR + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x0C, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x0E, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4F, 0x0F, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x0F, 0xA0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5E, 0x07, 0xA0, + 0x7F, 0x80, 0x00, 0x3F, 0xC0, 0x00, 0x3F, 0xC0, 0x00, 0x41, 0x04, 0x00, 0x40, 0x60, 0x20, + 0xFB, 0xC0, 0x00, 0x79, 0xE0, 0x00, 0x79, 0xE0, 0x00, 0x20, 0x82, 0x00, 0x40, 0xF0, 0x20, + 0xF3, 0xC0, 0x00, 0x76, 0xE0, 0x00, 0x76, 0xE0, 0x00, 0x20, 0x82, 0x00, 0x40, 0xF0, 0x20, + 0xEB, 0xC0, 0x00, 0x7E, 0xE0, 0x00, 0x7E, 0xE0, 0x00, 0x41, 0x04, 0x00, 0x40, 0x60, 0x20, + 0x7B, 0x80, 0x00, 0x3D, 0xC0, 0x00, 0x39, 0xC0, 0x00, 0x82, 0x08, 0x00, 0x5E, 0x07, 0xA0, + 0x7B, 0x80, 0x00, 0x3B, 0xC0, 0x00, 0x3E, 0xC0, 0x01, 0x04, 0x10, 0x00, 0x5F, 0x0F, 0xA0, + 0xFB, 0xC0, 0x00, 0x77, 0xE0, 0x00, 0x76, 0xE0, 0x01, 0x04, 0x10, 0x00, 0x4F, 0x0F, 0x20, + 0xFB, 0xC0, 0x00, 0x70, 0xE0, 0x00, 0x79, 0xE0, 0x00, 0x82, 0x08, 0x00, 0x47, 0x0E, 0x20, + 0xFF, 0xC0, 0x00, 0x7F, 0xE0, 0x00, 0x7F, 0xE0, 0x00, 0x41, 0x04, 0x00, 0x63, 0x0C, 0x60, + 0x3F, 0x00, 0x00, 0x1F, 0x80, 0x00, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, + 0x1E, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x0F, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x7F, 0xFF, 0xE0, + 0x0C, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00 + }; + + #define STATUS_SCREENWIDTH 115 //Width in pixels + #define STATUS_SCREENHEIGHT 19 //Height in pixels + #define STATUS_SCREENBYTEWIDTH 15 //Width in bytes + const unsigned char status_screen1_bmp[] PROGMEM = { //AVR-GCC, WinAVR + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0xF8, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xF8, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xF0, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x60, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x01, 0xA0, + 0x7F, 0x80, 0x00, 0x3F, 0xC0, 0x00, 0x3F, 0xC0, 0x00, 0x41, 0x04, 0x00, 0x5C, 0x63, 0xA0, + 0xFB, 0xC0, 0x00, 0x79, 0xE0, 0x00, 0x79, 0xE0, 0x00, 0x20, 0x82, 0x00, 0x5E, 0xF7, 0xA0, + 0xF3, 0xC0, 0x00, 0x76, 0xE0, 0x00, 0x76, 0xE0, 0x00, 0x20, 0x82, 0x00, 0x5E, 0xF7, 0xA0, + 0xEB, 0xC0, 0x00, 0x7E, 0xE0, 0x00, 0x7E, 0xE0, 0x00, 0x41, 0x04, 0x00, 0x5C, 0x63, 0xA0, + 0x7B, 0x80, 0x00, 0x3D, 0xC0, 0x00, 0x39, 0xC0, 0x00, 0x82, 0x08, 0x00, 0x58, 0x01, 0xA0, + 0x7B, 0x80, 0x00, 0x3B, 0xC0, 0x00, 0x3E, 0xC0, 0x01, 0x04, 0x10, 0x00, 0x40, 0x60, 0x20, + 0xFB, 0xC0, 0x00, 0x77, 0xE0, 0x00, 0x76, 0xE0, 0x01, 0x04, 0x10, 0x00, 0x40, 0xF0, 0x20, + 0xFB, 0xC0, 0x00, 0x70, 0xE0, 0x00, 0x79, 0xE0, 0x00, 0x82, 0x08, 0x00, 0x41, 0xF8, 0x20, + 0xFF, 0xC0, 0x00, 0x7F, 0xE0, 0x00, 0x7F, 0xE0, 0x00, 0x41, 0x04, 0x00, 0x61, 0xF8, 0x60, + 0x3F, 0x00, 0x00, 0x1F, 0x80, 0x00, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, + 0x1E, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x0F, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x7F, 0xFF, 0xE0, + 0x0C, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00 + }; + #endif // Extruders +#else + #if HOTENDS == 1 + #define STATUS_SCREENWIDTH 115 //Width in pixels + #define STATUS_SCREENHEIGHT 19 //Height in pixels + #define STATUS_SCREENBYTEWIDTH 15 //Width in bytes + const unsigned char status_screen0_bmp[] PROGMEM = { //AVR-GCC, WinAVR + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x0C, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x0E, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4F, 0x0F, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x0F, 0xA0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5E, 0x07, 0xA0, + 0x7F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x60, 0x20, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xF0, 0x20, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xF0, 0x20, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x60, 0x20, + 0x7F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5E, 0x07, 0xA0, + 0x7F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x0F, 0xA0, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4F, 0x0F, 0x20, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x0E, 0x20, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x0C, 0x60, + 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, + 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, + 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + #define STATUS_SCREENWIDTH 115 //Width in pixels + #define STATUS_SCREENHEIGHT 19 //Height in pixels + #define STATUS_SCREENBYTEWIDTH 15 //Width in bytes + const unsigned char status_screen1_bmp[] PROGMEM = { //AVR-GCC, WinAVR + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0xF8, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xF8, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xF0, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x60, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x01, 0xA0, + 0x7F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5C, 0x63, 0xA0, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5E, 0xF7, 0xA0, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5E, 0xF7, 0xA0, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5C, 0x63, 0xA0, + 0x7F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x01, 0xA0, + 0x7F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x60, 0x20, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xF0, 0x20, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xF8, 0x20, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0xF8, 0x60, + 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, + 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, + 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + #elif HOTENDS == 2 + #define STATUS_SCREENWIDTH 115 //Width in pixels + #define STATUS_SCREENHEIGHT 19 //Height in pixels + #define STATUS_SCREENBYTEWIDTH 15 //Width in bytes + const unsigned char status_screen0_bmp[] PROGMEM = { //AVR-GCC, WinAVR + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x0C, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x0E, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4F, 0x0F, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x0F, 0xA0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5E, 0x07, 0xA0, + 0x7F, 0x80, 0x00, 0x3F, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x60, 0x20, + 0xFB, 0xC0, 0x00, 0x79, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xF0, 0x20, + 0xF3, 0xC0, 0x00, 0x76, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xF0, 0x20, + 0xEB, 0xC0, 0x00, 0x7E, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x60, 0x20, + 0x7B, 0x80, 0x00, 0x3D, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5E, 0x07, 0xA0, + 0x7B, 0x80, 0x00, 0x3B, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x0F, 0xA0, + 0xFB, 0xC0, 0x00, 0x77, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4F, 0x0F, 0x20, + 0xFB, 0xC0, 0x00, 0x70, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x0E, 0x20, + 0xFF, 0xC0, 0x00, 0x7F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x0C, 0x60, + 0x3F, 0x00, 0x00, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, + 0x1E, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, + 0x0C, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + #define STATUS_SCREENWIDTH 115 //Width in pixels + #define STATUS_SCREENHEIGHT 19 //Height in pixels + #define STATUS_SCREENBYTEWIDTH 15 //Width in bytes + const unsigned char status_screen1_bmp[] PROGMEM = { //AVR-GCC, WinAVR + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0xF8, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xF8, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xF0, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x60, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x01, 0xA0, + 0x7F, 0x80, 0x00, 0x3F, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5C, 0x63, 0xA0, + 0xFB, 0xC0, 0x00, 0x79, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5E, 0xF7, 0xA0, + 0xF3, 0xC0, 0x00, 0x76, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5E, 0xF7, 0xA0, + 0xEB, 0xC0, 0x00, 0x7E, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5C, 0x63, 0xA0, + 0x7B, 0x80, 0x00, 0x3D, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x01, 0xA0, + 0x7B, 0x80, 0x00, 0x3B, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x60, 0x20, + 0xFB, 0xC0, 0x00, 0x77, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xF0, 0x20, + 0xFB, 0xC0, 0x00, 0x70, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xF8, 0x20, + 0xFF, 0xC0, 0x00, 0x7F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0xF8, 0x60, + 0x3F, 0x00, 0x00, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, + 0x1E, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, + 0x0C, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + #else + #define STATUS_SCREENWIDTH 115 //Width in pixels + #define STATUS_SCREENHEIGHT 19 //Height in pixels + #define STATUS_SCREENBYTEWIDTH 15 //Width in bytes + const unsigned char status_screen0_bmp[] PROGMEM = { //AVR-GCC, WinAVR + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x0C, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x0E, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4F, 0x0F, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x0F, 0xA0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5E, 0x07, 0xA0, + 0x7F, 0x80, 0x00, 0x3F, 0xC0, 0x00, 0x3F, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x40, 0x60, 0x20, + 0xFB, 0xC0, 0x00, 0x79, 0xE0, 0x00, 0x79, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x40, 0xF0, 0x20, + 0xF3, 0xC0, 0x00, 0x76, 0xE0, 0x00, 0x76, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x40, 0xF0, 0x20, + 0xEB, 0xC0, 0x00, 0x7E, 0xE0, 0x00, 0x7E, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x40, 0x60, 0x20, + 0x7B, 0x80, 0x00, 0x3D, 0xC0, 0x00, 0x39, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x5E, 0x07, 0xA0, + 0x7B, 0x80, 0x00, 0x3B, 0xC0, 0x00, 0x3E, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x0F, 0xA0, + 0xFB, 0xC0, 0x00, 0x77, 0xE0, 0x00, 0x76, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x4F, 0x0F, 0x20, + 0xFB, 0xC0, 0x00, 0x70, 0xE0, 0x00, 0x79, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x47, 0x0E, 0x20, + 0xFF, 0xC0, 0x00, 0x7F, 0xE0, 0x00, 0x7F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x63, 0x0C, 0x60, + 0x3F, 0x00, 0x00, 0x1F, 0x80, 0x00, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, + 0x1E, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, + 0x0C, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + #define STATUS_SCREENWIDTH 115 //Width in pixels + #define STATUS_SCREENHEIGHT 19 //Height in pixels + #define STATUS_SCREENBYTEWIDTH 15 //Width in bytes + const unsigned char status_screen1_bmp[] PROGMEM = { //AVR-GCC, WinAVR + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0xF8, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xF8, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xF0, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x60, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x01, 0xA0, + 0x7F, 0x80, 0x00, 0x3F, 0xC0, 0x00, 0x3F, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x5C, 0x63, 0xA0, + 0xFB, 0xC0, 0x00, 0x79, 0xE0, 0x00, 0x79, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x5E, 0xF7, 0xA0, + 0xF3, 0xC0, 0x00, 0x76, 0xE0, 0x00, 0x76, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x5E, 0xF7, 0xA0, + 0xEB, 0xC0, 0x00, 0x7E, 0xE0, 0x00, 0x7E, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x5C, 0x63, 0xA0, + 0x7B, 0x80, 0x00, 0x3D, 0xC0, 0x00, 0x39, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x58, 0x01, 0xA0, + 0x7B, 0x80, 0x00, 0x3B, 0xC0, 0x00, 0x3E, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x40, 0x60, 0x20, + 0xFB, 0xC0, 0x00, 0x77, 0xE0, 0x00, 0x76, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x40, 0xF0, 0x20, + 0xFB, 0xC0, 0x00, 0x70, 0xE0, 0x00, 0x79, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x41, 0xF8, 0x20, + 0xFF, 0xC0, 0x00, 0x7F, 0xE0, 0x00, 0x7F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x61, 0xF8, 0x60, + 0x3F, 0x00, 0x00, 0x1F, 0x80, 0x00, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xE0, + 0x1E, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, + 0x0C, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + #endif // Extruders +#endif // HAS_TEMP_BED diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/dogm_font_data_6x9_marlin.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/dogm_font_data_6x9_marlin.h new file mode 100644 index 00000000..f298a6ac --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/dogm_font_data_6x9_marlin.h @@ -0,0 +1,180 @@ +/** + * 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 . + * + */ + +/** + 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 + 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 + X Font ascent = 6 descent=-2 + 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 +}; diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/dogm_font_data_HD44780_C.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/dogm_font_data_HD44780_C.h new file mode 100644 index 00000000..21d4aaab --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/dogm_font_data_HD44780_C.h @@ -0,0 +1,194 @@ +/** + * 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 . + * + */ + +/** + Fontname: HD44780_C v1.2 + Copyright: A. Hardtung, public domain + Capital A Height: 7, '1' Height: 7 + Calculated Max Values w= 5 h= 8 x= 2 y= 7 dx= 6 dy= 0 ascent= 8 len= 8 + Font Bounding box w= 6 h= 9 x= 0 y=-2 + Calculated Min Values x= 0 y=-1 dx= 0 dy= 0 + Pure Font ascent = 7 descent=-1 + X Font ascent = 7 descent=-1 + Max Font ascent = 8 descent=-1 +*/ +#include +const u8g_fntpgm_uint8_t HD44780_C_5x7[2522] U8G_SECTION(".progmem.HD44780_C_5x7") = { + 0, 6, 9, 0, 254, 7, 1, 145, 3, 34, 32, 255, 255, 8, 255, 7, + 255, 0, 0, 0, 6, 0, 0, 1, 7, 7, 6, 2, 0, 128, 128, 128, + 128, 128, 0, 128, 3, 2, 2, 6, 1, 5, 160, 160, 5, 7, 7, 6, + 0, 0, 80, 80, 248, 80, 248, 80, 80, 5, 7, 7, 6, 0, 0, 32, + 120, 160, 112, 40, 240, 32, 5, 7, 7, 6, 0, 0, 192, 200, 16, 32, + 64, 152, 24, 5, 7, 7, 6, 0, 0, 96, 144, 160, 64, 168, 144, 104, + 2, 3, 3, 6, 1, 4, 192, 64, 128, 3, 7, 7, 6, 1, 0, 32, + 64, 128, 128, 128, 64, 32, 3, 7, 7, 6, 1, 0, 128, 64, 32, 32, + 32, 64, 128, 5, 5, 5, 6, 0, 1, 32, 168, 112, 168, 32, 5, 5, + 5, 6, 0, 1, 32, 32, 248, 32, 32, 2, 3, 3, 6, 2, 255, 192, + 64, 128, 5, 1, 1, 6, 0, 3, 248, 2, 2, 2, 6, 2, 0, 192, + 192, 5, 5, 5, 6, 0, 1, 8, 16, 32, 64, 128, 5, 7, 7, 6, + 0, 0, 112, 136, 152, 168, 200, 136, 112, 3, 7, 7, 6, 1, 0, 64, + 192, 64, 64, 64, 64, 224, 5, 7, 7, 6, 0, 0, 112, 136, 8, 112, + 128, 128, 248, 5, 7, 7, 6, 0, 0, 248, 16, 32, 16, 8, 8, 240, + 5, 7, 7, 6, 0, 0, 16, 48, 80, 144, 248, 16, 16, 5, 7, 7, + 6, 0, 0, 248, 128, 240, 8, 8, 136, 112, 5, 7, 7, 6, 0, 0, + 48, 64, 128, 240, 136, 136, 112, 5, 7, 7, 6, 0, 0, 248, 8, 16, + 32, 32, 32, 32, 5, 7, 7, 6, 0, 0, 112, 136, 136, 112, 136, 136, + 112, 5, 7, 7, 6, 0, 0, 112, 136, 136, 120, 8, 16, 96, 2, 5, + 5, 6, 2, 0, 192, 192, 0, 192, 192, 2, 6, 6, 6, 2, 255, 192, + 192, 0, 192, 64, 128, 4, 7, 7, 6, 0, 0, 16, 32, 64, 128, 64, + 32, 16, 5, 3, 3, 6, 0, 2, 248, 0, 248, 4, 7, 7, 6, 1, + 0, 128, 64, 32, 16, 32, 64, 128, 5, 7, 7, 6, 0, 0, 112, 136, + 8, 16, 32, 0, 32, 5, 6, 6, 6, 0, 0, 112, 136, 8, 104, 168, + 112, 5, 7, 7, 6, 0, 0, 112, 136, 136, 248, 136, 136, 136, 5, 7, + 7, 6, 0, 0, 240, 136, 136, 240, 136, 136, 240, 5, 7, 7, 6, 0, + 0, 112, 136, 128, 128, 128, 136, 112, 5, 7, 7, 6, 0, 0, 224, 144, + 136, 136, 136, 144, 224, 5, 7, 7, 6, 0, 0, 248, 128, 128, 240, 128, + 128, 248, 5, 7, 7, 6, 0, 0, 248, 128, 128, 240, 128, 128, 128, 5, + 7, 7, 6, 0, 0, 112, 136, 128, 184, 136, 136, 112, 5, 7, 7, 6, + 0, 0, 136, 136, 136, 248, 136, 136, 136, 1, 7, 7, 6, 2, 0, 128, + 128, 128, 128, 128, 128, 128, 5, 7, 7, 6, 0, 0, 56, 16, 16, 16, + 16, 144, 96, 5, 7, 7, 6, 0, 0, 136, 144, 160, 192, 160, 144, 136, + 5, 7, 7, 6, 0, 0, 128, 128, 128, 128, 128, 128, 248, 5, 7, 7, + 6, 0, 0, 136, 216, 168, 136, 136, 136, 136, 5, 7, 7, 6, 0, 0, + 136, 136, 200, 168, 152, 136, 136, 5, 7, 7, 6, 0, 0, 112, 136, 136, + 136, 136, 136, 112, 5, 7, 7, 6, 0, 0, 240, 136, 136, 240, 128, 128, + 128, 5, 7, 7, 6, 0, 0, 112, 136, 136, 136, 168, 144, 104, 5, 7, + 7, 6, 0, 0, 240, 136, 136, 240, 160, 144, 136, 5, 7, 7, 6, 0, + 0, 120, 128, 128, 112, 8, 8, 240, 5, 7, 7, 6, 0, 0, 248, 32, + 32, 32, 32, 32, 32, 5, 7, 7, 6, 0, 0, 136, 136, 136, 136, 136, + 136, 112, 5, 7, 7, 6, 0, 0, 136, 136, 136, 136, 136, 80, 32, 5, + 7, 7, 6, 0, 0, 136, 136, 136, 136, 136, 168, 80, 5, 7, 7, 6, + 0, 0, 136, 136, 80, 32, 80, 136, 136, 5, 7, 7, 6, 0, 0, 136, + 136, 136, 80, 32, 32, 32, 5, 7, 7, 6, 0, 0, 248, 8, 16, 32, + 64, 128, 248, 3, 7, 7, 6, 1, 0, 224, 128, 128, 128, 128, 128, 224, + 5, 7, 7, 6, 0, 0, 32, 112, 160, 160, 168, 112, 32, 3, 7, 7, + 6, 1, 0, 224, 32, 32, 32, 32, 32, 224, 5, 3, 3, 6, 0, 4, + 32, 80, 136, 5, 1, 1, 6, 0, 0, 248, 2, 2, 2, 6, 2, 5, + 128, 64, 5, 5, 5, 6, 0, 0, 112, 8, 120, 136, 120, 5, 7, 7, + 6, 0, 0, 128, 128, 176, 200, 136, 136, 240, 5, 5, 5, 6, 0, 0, + 112, 128, 128, 136, 112, 5, 7, 7, 6, 0, 0, 8, 8, 104, 152, 136, + 136, 120, 5, 5, 5, 6, 0, 0, 112, 136, 248, 128, 112, 5, 7, 7, + 6, 0, 0, 48, 72, 224, 64, 64, 64, 64, 5, 6, 6, 6, 0, 255, + 112, 136, 136, 120, 8, 112, 5, 7, 7, 6, 0, 0, 128, 128, 176, 200, + 136, 136, 136, 1, 7, 7, 6, 2, 0, 128, 0, 128, 128, 128, 128, 128, + 3, 8, 8, 6, 1, 255, 32, 0, 32, 32, 32, 32, 160, 64, 4, 7, + 7, 6, 0, 0, 128, 128, 144, 160, 192, 160, 144, 3, 7, 7, 6, 1, + 0, 192, 64, 64, 64, 64, 64, 224, 5, 5, 5, 6, 0, 0, 208, 168, + 168, 168, 168, 5, 5, 5, 6, 0, 0, 176, 200, 136, 136, 136, 5, 5, + 5, 6, 0, 0, 112, 136, 136, 136, 112, 5, 6, 6, 6, 0, 255, 240, + 136, 136, 240, 128, 128, 5, 6, 6, 6, 0, 255, 120, 136, 136, 120, 8, + 8, 5, 5, 5, 6, 0, 0, 176, 200, 128, 128, 128, 5, 5, 5, 6, + 0, 0, 112, 128, 112, 8, 240, 5, 7, 7, 6, 0, 0, 64, 64, 224, + 64, 64, 72, 48, 5, 5, 5, 6, 0, 0, 136, 136, 136, 152, 104, 5, + 5, 5, 6, 0, 0, 136, 136, 136, 80, 32, 5, 5, 5, 6, 0, 0, + 136, 136, 168, 168, 80, 5, 5, 5, 6, 0, 0, 136, 80, 32, 80, 136, + 5, 6, 6, 6, 0, 255, 136, 136, 136, 120, 8, 112, 5, 5, 5, 6, + 0, 0, 248, 16, 32, 64, 248, 5, 5, 5, 6, 0, 2, 184, 168, 168, + 168, 184, 5, 5, 5, 6, 0, 2, 184, 136, 184, 160, 184, 5, 5, 5, + 6, 0, 2, 184, 160, 184, 136, 184, 5, 6, 6, 6, 0, 1, 8, 40, + 72, 248, 64, 32, 5, 5, 5, 6, 0, 0, 56, 112, 224, 136, 240, 0, + 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, + 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, + 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, + 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, + 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, + 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, + 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, + 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 5, + 7, 7, 6, 0, 0, 248, 136, 128, 240, 136, 136, 240, 5, 7, 7, 6, + 0, 0, 248, 136, 128, 128, 128, 128, 128, 5, 7, 7, 6, 0, 0, 80, + 0, 248, 128, 240, 128, 248, 5, 7, 7, 6, 0, 0, 168, 168, 168, 112, + 168, 168, 168, 5, 7, 7, 6, 0, 0, 240, 8, 8, 112, 8, 8, 240, + 5, 7, 7, 6, 0, 0, 136, 136, 152, 168, 200, 136, 136, 5, 8, 8, + 6, 0, 0, 80, 32, 136, 152, 168, 168, 200, 136, 5, 7, 7, 6, 0, + 0, 120, 40, 40, 40, 40, 168, 72, 5, 7, 7, 6, 0, 0, 248, 136, + 136, 136, 136, 136, 136, 5, 7, 7, 6, 0, 0, 136, 136, 136, 80, 32, + 64, 128, 5, 7, 7, 6, 0, 0, 32, 112, 168, 168, 168, 112, 32, 5, + 7, 7, 6, 0, 0, 136, 136, 136, 120, 8, 8, 8, 5, 7, 7, 6, + 0, 0, 168, 168, 168, 168, 168, 168, 248, 5, 7, 7, 6, 0, 0, 192, + 64, 64, 112, 72, 72, 112, 5, 7, 7, 6, 0, 0, 136, 136, 136, 200, + 168, 168, 200, 5, 7, 7, 6, 0, 0, 112, 136, 8, 56, 8, 136, 112, + 5, 7, 7, 6, 0, 0, 144, 168, 168, 232, 168, 168, 144, 5, 7, 7, + 6, 0, 0, 120, 136, 136, 120, 40, 72, 136, 5, 7, 7, 6, 0, 0, + 24, 96, 128, 240, 136, 136, 112, 4, 5, 5, 6, 0, 0, 224, 144, 224, + 144, 224, 5, 5, 5, 6, 0, 0, 248, 136, 128, 128, 128, 5, 7, 7, + 6, 0, 0, 80, 0, 112, 136, 248, 128, 112, 5, 5, 5, 6, 0, 0, + 168, 168, 112, 168, 168, 5, 5, 5, 6, 0, 0, 240, 8, 48, 8, 240, + 5, 5, 5, 6, 0, 0, 136, 152, 168, 200, 136, 5, 7, 7, 6, 0, + 0, 80, 32, 136, 152, 168, 200, 136, 4, 5, 5, 6, 0, 0, 144, 160, + 192, 160, 144, 5, 5, 5, 6, 0, 0, 248, 40, 40, 168, 72, 5, 5, + 5, 6, 0, 0, 136, 216, 168, 136, 136, 5, 5, 5, 6, 0, 0, 136, + 136, 248, 136, 136, 5, 5, 5, 6, 0, 0, 248, 136, 136, 136, 136, 5, + 5, 5, 6, 0, 0, 248, 32, 32, 32, 32, 5, 5, 5, 6, 0, 0, + 136, 136, 120, 8, 8, 5, 5, 5, 6, 0, 0, 168, 168, 168, 168, 248, + 5, 5, 5, 6, 0, 0, 192, 64, 112, 72, 112, 5, 5, 5, 6, 0, + 0, 136, 136, 200, 168, 200, 4, 5, 5, 6, 0, 0, 128, 128, 224, 144, + 224, 5, 5, 5, 6, 0, 0, 112, 136, 56, 136, 112, 5, 5, 5, 6, + 0, 0, 144, 168, 232, 168, 144, 5, 5, 5, 6, 0, 0, 120, 136, 120, + 40, 72, 5, 5, 5, 6, 0, 1, 32, 72, 144, 72, 32, 5, 5, 5, + 6, 0, 1, 32, 144, 72, 144, 32, 5, 3, 3, 6, 0, 0, 72, 144, + 216, 5, 3, 3, 6, 0, 4, 216, 72, 144, 5, 7, 7, 6, 0, 0, + 144, 208, 176, 144, 56, 40, 56, 5, 7, 7, 6, 0, 0, 32, 0, 32, + 64, 128, 136, 112, 5, 7, 7, 6, 0, 0, 24, 32, 32, 112, 32, 32, + 192, 5, 7, 7, 6, 0, 0, 32, 80, 64, 240, 64, 64, 120, 1, 2, + 2, 6, 2, 0, 128, 128, 1, 4, 4, 6, 2, 0, 128, 128, 128, 128, + 3, 5, 5, 6, 1, 0, 160, 160, 160, 0, 224, 3, 5, 5, 6, 1, + 0, 160, 160, 160, 0, 160, 5, 7, 7, 6, 0, 0, 160, 0, 232, 16, + 32, 64, 128, 5, 5, 5, 6, 0, 1, 216, 112, 32, 112, 216, 5, 7, + 7, 6, 0, 0, 160, 64, 168, 16, 32, 64, 128, 3, 6, 6, 6, 1, + 1, 224, 64, 64, 64, 64, 224, 5, 6, 6, 6, 0, 1, 248, 80, 80, + 80, 80, 248, 5, 7, 7, 6, 0, 0, 32, 112, 168, 32, 32, 32, 32, + 5, 7, 7, 6, 0, 0, 32, 32, 32, 32, 168, 112, 32, 5, 7, 7, + 6, 0, 0, 128, 144, 176, 248, 176, 144, 128, 5, 7, 7, 6, 0, 0, + 8, 72, 104, 248, 104, 72, 8, 5, 7, 7, 6, 0, 0, 128, 136, 168, + 248, 168, 136, 128, 5, 7, 7, 6, 0, 0, 128, 224, 136, 16, 32, 64, + 128, 2, 2, 2, 6, 2, 2, 192, 192, 5, 8, 8, 6, 0, 255, 120, + 40, 40, 40, 72, 136, 248, 136, 5, 8, 8, 6, 0, 255, 136, 136, 136, + 136, 136, 136, 248, 8, 5, 8, 8, 6, 0, 255, 168, 168, 168, 168, 168, + 168, 248, 8, 5, 6, 6, 6, 0, 255, 120, 40, 72, 136, 248, 136, 5, + 7, 7, 6, 0, 255, 32, 32, 112, 168, 168, 112, 32, 5, 6, 6, 6, + 0, 255, 136, 136, 136, 136, 248, 8, 5, 6, 6, 6, 0, 255, 168, 168, + 168, 168, 248, 8, 2, 2, 2, 6, 2, 6, 64, 128, 3, 1, 1, 6, + 1, 7, 160, 5, 2, 2, 6, 0, 6, 72, 176, 5, 8, 8, 6, 0, + 0, 16, 32, 0, 112, 136, 248, 128, 112, 5, 6, 6, 6, 0, 255, 112, + 128, 136, 112, 32, 96, 3, 7, 7, 6, 1, 0, 160, 0, 160, 160, 160, + 32, 192, 5, 6, 6, 6, 0, 1, 32, 112, 112, 112, 248, 32, 5, 5, + 5, 6, 0, 1, 80, 0, 136, 0, 80, 5, 5, 5, 6, 0, 1, 112, + 136, 136, 136, 112, 5, 7, 7, 6, 0, 0, 136, 144, 168, 88, 184, 8, + 8, 5, 7, 7, 6, 0, 0, 136, 144, 184, 72, 184, 8, 56, 5, 7, + 7, 6, 0, 0, 136, 144, 184, 72, 152, 32, 56, 5, 8, 8, 6, 0, + 0, 192, 64, 192, 72, 216, 56, 8, 8, 5, 7, 7, 6, 0, 0, 136, + 248, 136, 248, 136, 248, 136, 4, 5, 5, 6, 0, 2, 192, 0, 48, 0, + 96, 5, 8, 8, 6, 0, 0, 64, 160, 224, 168, 8, 40, 120, 32, 5, + 8, 8, 6, 0, 0, 64, 112, 64, 120, 64, 112, 64, 224, 5, 8, 8, + 6, 0, 0, 32, 112, 32, 248, 32, 112, 32, 112, 5, 7, 7, 6, 0, + 0, 104, 0, 232, 0, 104, 16, 56, 5, 8, 8, 6, 0, 0, 16, 112, + 16, 240, 16, 112, 16, 56, 5, 7, 7, 6, 0, 1, 32, 112, 32, 248, + 32, 112, 32, 5, 8, 8, 6, 0, 0, 16, 144, 80, 48, 80, 144, 16, + 56, 5, 8, 8, 6, 0, 0, 48, 72, 32, 80, 80, 32, 144, 96, 5, + 7, 7, 6, 0, 0, 120, 168, 168, 120, 40, 40, 40, 5, 8, 8, 6, + 0, 0, 248, 248, 248, 248, 248, 248, 248, 248 +}; diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/dogm_font_data_HD44780_J.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/dogm_font_data_HD44780_J.h new file mode 100644 index 00000000..e4884c7c --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/dogm_font_data_HD44780_J.h @@ -0,0 +1,192 @@ +/** + * 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 . + * + */ + +/** + Fontname: HD44780_J + Copyright: A. Hardtung, public domain + Capital A Height: 7, '1' Height: 7 + Calculated Max Values w= 6 h=10 x= 2 y= 5 dx= 6 dy= 0 ascent= 8 len= 8 + 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 = 7 descent=-1 + X Font ascent = 7 descent=-1 + Max Font ascent = 8 descent=-2 +*/ +#include +const u8g_fntpgm_uint8_t HD44780_J_5x7[2492] U8G_SECTION(".progmem.HD44780_J_5x7") = { + 0, 6, 9, 0, 254, 7, 1, 145, 3, 34, 32, 255, 255, 8, 254, 7, + 255, 0, 0, 0, 6, 0, 0, 1, 7, 7, 6, 2, 0, 128, 128, 128, + 128, 128, 0, 128, 3, 2, 2, 6, 1, 5, 160, 160, 5, 7, 7, 6, + 0, 0, 80, 80, 248, 80, 248, 80, 80, 5, 7, 7, 6, 0, 0, 32, + 120, 160, 112, 40, 240, 32, 5, 7, 7, 6, 0, 0, 192, 200, 16, 32, + 64, 152, 24, 5, 7, 7, 6, 0, 0, 96, 144, 160, 64, 168, 144, 104, + 2, 3, 3, 6, 1, 4, 192, 64, 128, 3, 7, 7, 6, 1, 0, 32, + 64, 128, 128, 128, 64, 32, 3, 7, 7, 6, 1, 0, 128, 64, 32, 32, + 32, 64, 128, 5, 5, 5, 6, 0, 1, 32, 168, 112, 168, 32, 5, 5, + 5, 6, 0, 1, 32, 32, 248, 32, 32, 2, 3, 3, 6, 2, 255, 192, + 64, 128, 5, 1, 1, 6, 0, 3, 248, 2, 2, 2, 6, 2, 0, 192, + 192, 5, 5, 5, 6, 0, 1, 8, 16, 32, 64, 128, 5, 7, 7, 6, + 0, 0, 112, 136, 152, 168, 200, 136, 112, 3, 7, 7, 6, 1, 0, 64, + 192, 64, 64, 64, 64, 224, 5, 7, 7, 6, 0, 0, 112, 136, 8, 112, + 128, 128, 248, 5, 7, 7, 6, 0, 0, 248, 16, 32, 16, 8, 8, 240, + 5, 7, 7, 6, 0, 0, 16, 48, 80, 144, 248, 16, 16, 5, 7, 7, + 6, 0, 0, 248, 128, 240, 8, 8, 136, 112, 5, 7, 7, 6, 0, 0, + 48, 64, 128, 240, 136, 136, 112, 5, 7, 7, 6, 0, 0, 248, 8, 16, + 32, 32, 32, 32, 5, 7, 7, 6, 0, 0, 112, 136, 136, 112, 136, 136, + 112, 5, 7, 7, 6, 0, 0, 112, 136, 136, 120, 8, 16, 96, 2, 5, + 5, 6, 2, 0, 192, 192, 0, 192, 192, 2, 6, 6, 6, 2, 255, 192, + 192, 0, 192, 64, 128, 4, 7, 7, 6, 0, 0, 16, 32, 64, 128, 64, + 32, 16, 5, 3, 3, 6, 0, 2, 248, 0, 248, 4, 7, 7, 6, 1, + 0, 128, 64, 32, 16, 32, 64, 128, 5, 7, 7, 6, 0, 0, 112, 136, + 8, 16, 32, 0, 32, 5, 6, 6, 6, 0, 0, 112, 136, 8, 104, 168, + 112, 5, 7, 7, 6, 0, 0, 112, 136, 136, 248, 136, 136, 136, 5, 7, + 7, 6, 0, 0, 240, 136, 136, 240, 136, 136, 240, 5, 7, 7, 6, 0, + 0, 112, 136, 128, 128, 128, 136, 112, 5, 7, 7, 6, 0, 0, 224, 144, + 136, 136, 136, 144, 224, 5, 7, 7, 6, 0, 0, 248, 128, 128, 240, 128, + 128, 248, 5, 7, 7, 6, 0, 0, 248, 128, 128, 240, 128, 128, 128, 5, + 7, 7, 6, 0, 0, 112, 136, 128, 184, 136, 136, 112, 5, 7, 7, 6, + 0, 0, 136, 136, 136, 248, 136, 136, 136, 1, 7, 7, 6, 2, 0, 128, + 128, 128, 128, 128, 128, 128, 5, 7, 7, 6, 0, 0, 56, 16, 16, 16, + 16, 144, 96, 5, 7, 7, 6, 0, 0, 136, 144, 160, 192, 160, 144, 136, + 5, 7, 7, 6, 0, 0, 128, 128, 128, 128, 128, 128, 248, 5, 7, 7, + 6, 0, 0, 136, 216, 168, 136, 136, 136, 136, 5, 7, 7, 6, 0, 0, + 136, 136, 200, 168, 152, 136, 136, 5, 7, 7, 6, 0, 0, 112, 136, 136, + 136, 136, 136, 112, 5, 7, 7, 6, 0, 0, 240, 136, 136, 240, 128, 128, + 128, 5, 7, 7, 6, 0, 0, 112, 136, 136, 136, 168, 144, 104, 5, 7, + 7, 6, 0, 0, 240, 136, 136, 240, 160, 144, 136, 5, 7, 7, 6, 0, + 0, 120, 128, 128, 112, 8, 8, 240, 5, 7, 7, 6, 0, 0, 248, 32, + 32, 32, 32, 32, 32, 5, 7, 7, 6, 0, 0, 136, 136, 136, 136, 136, + 136, 112, 5, 7, 7, 6, 0, 0, 136, 136, 136, 136, 136, 80, 32, 5, + 7, 7, 6, 0, 0, 136, 136, 136, 136, 136, 168, 80, 5, 7, 7, 6, + 0, 0, 136, 136, 80, 32, 80, 136, 136, 5, 7, 7, 6, 0, 0, 136, + 136, 136, 80, 32, 32, 32, 5, 7, 7, 6, 0, 0, 248, 8, 16, 32, + 64, 128, 248, 3, 7, 7, 6, 1, 0, 224, 128, 128, 128, 128, 128, 224, + 5, 7, 7, 6, 0, 0, 136, 80, 248, 32, 248, 32, 32, 3, 7, 7, + 6, 1, 0, 224, 32, 32, 32, 32, 32, 224, 5, 3, 3, 6, 0, 4, + 32, 80, 136, 5, 1, 1, 6, 0, 0, 248, 2, 2, 2, 6, 2, 5, + 128, 64, 5, 5, 5, 6, 0, 0, 112, 8, 120, 136, 120, 5, 7, 7, + 6, 0, 0, 128, 128, 176, 200, 136, 136, 240, 5, 5, 5, 6, 0, 0, + 112, 128, 128, 136, 112, 5, 7, 7, 6, 0, 0, 8, 8, 104, 152, 136, + 136, 120, 5, 5, 5, 6, 0, 0, 112, 136, 248, 128, 112, 5, 7, 7, + 6, 0, 0, 48, 72, 224, 64, 64, 64, 64, 5, 6, 6, 6, 0, 255, + 112, 136, 136, 120, 8, 112, 5, 7, 7, 6, 0, 0, 128, 128, 176, 200, + 136, 136, 136, 1, 7, 7, 6, 2, 0, 128, 0, 128, 128, 128, 128, 128, + 3, 8, 8, 6, 1, 255, 32, 0, 32, 32, 32, 32, 160, 64, 4, 7, + 7, 6, 0, 0, 128, 128, 144, 160, 192, 160, 144, 3, 7, 7, 6, 1, + 0, 192, 64, 64, 64, 64, 64, 224, 5, 5, 5, 6, 0, 0, 208, 168, + 168, 168, 168, 5, 5, 5, 6, 0, 0, 176, 200, 136, 136, 136, 5, 5, + 5, 6, 0, 0, 112, 136, 136, 136, 112, 5, 6, 6, 6, 0, 255, 240, + 136, 136, 240, 128, 128, 5, 6, 6, 6, 0, 255, 120, 136, 136, 120, 8, + 8, 5, 5, 5, 6, 0, 0, 176, 200, 128, 128, 128, 5, 5, 5, 6, + 0, 0, 112, 128, 112, 8, 240, 5, 7, 7, 6, 0, 0, 64, 64, 224, + 64, 64, 72, 48, 5, 5, 5, 6, 0, 0, 136, 136, 136, 152, 104, 5, + 5, 5, 6, 0, 0, 136, 136, 136, 80, 32, 5, 5, 5, 6, 0, 0, + 136, 136, 168, 168, 80, 5, 5, 5, 6, 0, 0, 136, 80, 32, 80, 136, + 5, 6, 6, 6, 0, 255, 136, 136, 136, 120, 8, 112, 5, 5, 5, 6, + 0, 0, 248, 16, 32, 64, 248, 3, 7, 7, 6, 1, 0, 32, 64, 64, + 128, 64, 64, 32, 1, 7, 7, 6, 2, 0, 128, 128, 128, 128, 128, 128, + 128, 3, 7, 7, 6, 1, 0, 128, 64, 64, 32, 64, 64, 128, 5, 5, + 5, 6, 0, 1, 32, 16, 248, 16, 32, 5, 5, 5, 6, 0, 1, 32, + 64, 248, 64, 32, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, + 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, + 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, + 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, + 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, + 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, + 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, + 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, + 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, + 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, + 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, + 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, + 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 3, 3, 3, 6, 0, 0, + 224, 160, 224, 3, 4, 4, 6, 2, 3, 224, 128, 128, 128, 3, 4, 4, + 6, 0, 0, 32, 32, 32, 224, 3, 3, 3, 6, 0, 0, 128, 64, 32, + 2, 2, 2, 6, 1, 2, 192, 192, 5, 6, 6, 6, 0, 0, 248, 8, + 248, 8, 16, 32, 5, 5, 5, 6, 0, 0, 248, 8, 48, 32, 64, 4, + 5, 5, 6, 0, 0, 16, 32, 96, 160, 32, 5, 5, 5, 6, 0, 0, + 32, 248, 136, 8, 48, 5, 4, 4, 6, 0, 0, 248, 32, 32, 248, 5, + 5, 5, 6, 0, 0, 16, 248, 48, 80, 144, 5, 5, 5, 6, 0, 0, + 64, 248, 72, 80, 64, 5, 4, 4, 6, 0, 0, 112, 16, 16, 248, 4, + 5, 5, 6, 0, 0, 240, 16, 240, 16, 240, 5, 4, 4, 6, 0, 0, + 168, 168, 8, 48, 5, 1, 1, 6, 0, 3, 248, 5, 7, 7, 6, 0, + 0, 248, 8, 40, 48, 32, 32, 64, 5, 7, 7, 6, 0, 0, 8, 16, + 32, 96, 160, 32, 32, 5, 7, 7, 6, 0, 0, 32, 248, 136, 136, 8, + 16, 32, 5, 6, 6, 6, 0, 0, 248, 32, 32, 32, 32, 248, 5, 7, + 7, 6, 0, 0, 16, 248, 16, 48, 80, 144, 16, 5, 7, 7, 6, 0, + 0, 64, 248, 72, 72, 72, 72, 144, 5, 7, 7, 6, 0, 0, 32, 248, + 32, 248, 32, 32, 32, 5, 6, 6, 6, 0, 0, 120, 72, 136, 8, 16, + 96, 5, 7, 7, 6, 0, 0, 64, 120, 144, 16, 16, 16, 32, 5, 6, + 6, 6, 0, 0, 248, 8, 8, 8, 8, 248, 5, 7, 7, 6, 0, 0, + 80, 248, 80, 80, 16, 32, 64, 5, 6, 6, 6, 0, 0, 192, 8, 200, + 8, 16, 224, 5, 6, 6, 6, 0, 0, 248, 8, 16, 32, 80, 136, 5, + 7, 7, 6, 0, 0, 64, 248, 72, 80, 64, 64, 56, 5, 6, 6, 6, + 0, 0, 136, 136, 72, 8, 16, 96, 5, 6, 6, 6, 0, 0, 120, 72, + 168, 24, 16, 96, 5, 7, 7, 6, 0, 0, 16, 224, 32, 248, 32, 32, + 64, 5, 6, 6, 6, 0, 0, 168, 168, 168, 8, 16, 32, 5, 7, 7, + 6, 0, 0, 112, 0, 248, 32, 32, 32, 64, 3, 7, 7, 6, 1, 0, + 128, 128, 128, 192, 160, 128, 128, 5, 7, 7, 6, 0, 0, 32, 32, 248, + 32, 32, 64, 128, 5, 6, 6, 6, 0, 0, 112, 0, 0, 0, 0, 248, + 5, 6, 6, 6, 0, 0, 248, 8, 80, 32, 80, 128, 5, 7, 7, 6, + 0, 0, 32, 248, 16, 32, 112, 168, 32, 3, 7, 7, 6, 1, 0, 32, + 32, 32, 32, 32, 64, 128, 5, 6, 6, 6, 0, 0, 32, 16, 136, 136, + 136, 136, 5, 7, 7, 6, 0, 0, 128, 128, 248, 128, 128, 128, 120, 5, + 6, 6, 6, 0, 0, 248, 8, 8, 8, 16, 96, 5, 5, 5, 6, 0, + 1, 64, 160, 16, 8, 8, 5, 7, 7, 6, 0, 0, 32, 248, 32, 32, + 168, 168, 32, 5, 6, 6, 6, 0, 0, 248, 8, 8, 80, 32, 16, 4, + 6, 6, 6, 1, 0, 224, 0, 224, 0, 224, 16, 5, 6, 6, 6, 0, + 0, 32, 64, 128, 136, 248, 8, 5, 6, 6, 6, 0, 0, 8, 8, 80, + 32, 80, 128, 5, 6, 6, 6, 0, 0, 248, 64, 248, 64, 64, 56, 5, + 7, 7, 6, 0, 0, 64, 64, 248, 72, 80, 64, 64, 5, 7, 7, 6, + 0, 0, 112, 16, 16, 16, 16, 16, 248, 5, 6, 6, 6, 0, 0, 248, + 8, 248, 8, 8, 248, 5, 7, 7, 6, 0, 0, 112, 0, 248, 8, 8, + 16, 32, 4, 7, 7, 6, 0, 0, 144, 144, 144, 144, 16, 32, 64, 5, + 6, 6, 6, 0, 0, 32, 160, 160, 168, 168, 176, 5, 7, 7, 6, 0, + 0, 128, 128, 128, 136, 144, 160, 192, 5, 6, 6, 6, 0, 0, 248, 136, + 136, 136, 136, 248, 5, 6, 6, 6, 0, 0, 248, 136, 136, 8, 16, 32, + 5, 6, 6, 6, 0, 0, 192, 0, 8, 8, 16, 224, 4, 3, 3, 6, + 0, 4, 32, 144, 64, 3, 3, 3, 6, 0, 4, 224, 160, 224, 5, 5, + 5, 6, 0, 1, 72, 168, 144, 144, 104, 5, 7, 7, 6, 0, 0, 80, + 0, 112, 8, 120, 136, 120, 4, 8, 8, 6, 1, 255, 96, 144, 144, 224, + 144, 144, 224, 128, 5, 5, 5, 6, 0, 0, 112, 128, 96, 136, 112, 5, + 6, 6, 6, 0, 255, 136, 136, 152, 232, 136, 128, 5, 5, 5, 6, 0, + 0, 120, 160, 144, 136, 112, 5, 7, 7, 6, 0, 254, 48, 72, 136, 136, + 240, 128, 128, 5, 8, 8, 6, 0, 254, 120, 136, 136, 136, 120, 8, 8, + 112, 5, 5, 5, 6, 0, 1, 56, 32, 32, 160, 64, 4, 3, 3, 6, + 0, 3, 16, 208, 16, 4, 8, 8, 6, 0, 255, 16, 0, 48, 16, 16, + 16, 144, 96, 3, 3, 3, 6, 0, 4, 160, 64, 160, 5, 7, 7, 6, + 0, 0, 32, 112, 160, 160, 168, 112, 32, 5, 7, 7, 6, 0, 0, 64, + 64, 224, 64, 224, 64, 120, 5, 7, 7, 6, 0, 0, 112, 0, 176, 200, + 136, 136, 136, 5, 7, 7, 6, 0, 0, 80, 0, 112, 136, 136, 136, 112, + 5, 7, 7, 6, 0, 255, 176, 200, 136, 136, 240, 128, 128, 5, 7, 7, + 6, 0, 255, 104, 152, 136, 136, 120, 8, 8, 5, 6, 6, 6, 0, 0, + 112, 136, 248, 136, 136, 112, 5, 3, 3, 6, 0, 2, 88, 168, 208, 5, + 5, 5, 6, 0, 0, 112, 136, 136, 80, 216, 5, 7, 7, 6, 0, 0, + 80, 0, 136, 136, 136, 152, 104, 5, 7, 7, 6, 0, 0, 248, 128, 64, + 32, 64, 128, 248, 5, 5, 5, 6, 0, 0, 248, 80, 80, 80, 152, 5, + 7, 7, 6, 0, 0, 248, 0, 136, 80, 32, 80, 136, 5, 7, 7, 6, + 0, 255, 136, 136, 136, 136, 120, 8, 112, 5, 6, 6, 6, 0, 0, 8, + 240, 32, 248, 32, 32, 5, 5, 5, 6, 0, 0, 248, 64, 120, 72, 136, + 5, 5, 5, 6, 0, 0, 248, 168, 248, 136, 136, 5, 5, 5, 6, 0, + 1, 32, 0, 248, 0, 32, 0, 0, 0, 6, 0, 0, 6, 10, 10, 6, + 0, 254, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252 +}; diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/dogm_font_data_HD44780_W.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/dogm_font_data_HD44780_W.h new file mode 100644 index 00000000..86b4bf4b --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/dogm_font_data_HD44780_W.h @@ -0,0 +1,226 @@ +/** + * 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 . + * + */ + +/** + Fontname: HD44780_W + Copyright: A.Hardtung, public domain + Capital A Height: 7, '1' Height: 7 + Calculated Max Values w= 5 h= 9 x= 2 y= 5 dx= 6 dy= 0 ascent= 8 len= 9 + Font Bounding box w= 6 h= 9 x= 0 y=-2 + Calculated Min Values x= 0 y=-1 dx= 0 dy= 0 + Pure Font ascent = 7 descent=-1 + X Font ascent = 7 descent=-1 + Max Font ascent = 8 descent=-1 +*/ +#include +const u8g_fntpgm_uint8_t HD44780_W_5x7[3034] U8G_SECTION(".progmem.HD44780_W_5x7") = { + 0, 6, 9, 0, 254, 7, 2, 79, 3, 222, 16, 255, 255, 8, 255, 7, + 255, 4, 7, 7, 6, 0, 0, 16, 48, 112, 240, 112, 48, 16, 4, 7, + 7, 6, 1, 0, 128, 192, 224, 240, 224, 192, 128, 5, 3, 3, 6, 0, + 4, 216, 72, 144, 5, 3, 3, 6, 0, 4, 216, 144, 72, 5, 7, 7, + 6, 0, 0, 32, 112, 248, 0, 32, 112, 248, 5, 7, 7, 6, 0, 0, + 248, 112, 32, 0, 248, 112, 32, 5, 5, 5, 6, 0, 1, 112, 248, 248, + 248, 112, 5, 7, 7, 6, 0, 0, 8, 8, 40, 72, 248, 64, 32, 5, + 7, 7, 6, 0, 0, 32, 112, 168, 32, 32, 32, 32, 5, 7, 7, 6, + 0, 0, 32, 32, 32, 32, 168, 112, 32, 5, 5, 5, 6, 0, 1, 32, + 64, 248, 64, 32, 5, 5, 5, 6, 0, 1, 32, 16, 248, 16, 32, 5, + 7, 7, 6, 0, 0, 16, 32, 64, 32, 16, 0, 248, 5, 7, 7, 6, + 0, 0, 64, 32, 16, 32, 64, 0, 248, 5, 5, 5, 6, 0, 1, 32, + 32, 112, 112, 248, 5, 5, 5, 6, 0, 0, 248, 112, 112, 32, 32, 0, + 0, 0, 6, 0, 0, 1, 7, 7, 6, 2, 0, 128, 128, 128, 128, 128, + 0, 128, 3, 2, 2, 6, 1, 5, 160, 160, 5, 7, 7, 6, 0, 0, + 80, 80, 248, 80, 248, 80, 80, 5, 7, 7, 6, 0, 0, 32, 120, 160, + 112, 40, 240, 32, 5, 7, 7, 6, 0, 0, 192, 200, 16, 32, 64, 152, + 24, 5, 7, 7, 6, 0, 0, 96, 144, 160, 64, 168, 144, 104, 2, 3, + 3, 6, 1, 4, 192, 64, 128, 3, 7, 7, 6, 1, 0, 32, 64, 128, + 128, 128, 64, 32, 3, 7, 7, 6, 1, 0, 128, 64, 32, 32, 32, 64, + 128, 5, 5, 5, 6, 0, 1, 32, 168, 112, 168, 32, 5, 5, 5, 6, + 0, 1, 32, 32, 248, 32, 32, 2, 3, 3, 6, 2, 255, 192, 64, 128, + 5, 1, 1, 6, 0, 3, 248, 2, 2, 2, 6, 2, 0, 192, 192, 5, + 5, 5, 6, 0, 1, 8, 16, 32, 64, 128, 5, 7, 7, 6, 0, 0, + 112, 136, 152, 168, 200, 136, 112, 3, 7, 7, 6, 1, 0, 64, 192, 64, + 64, 64, 64, 224, 5, 7, 7, 6, 0, 0, 112, 136, 8, 112, 128, 128, + 248, 5, 7, 7, 6, 0, 0, 248, 16, 32, 16, 8, 8, 240, 5, 7, + 7, 6, 0, 0, 16, 48, 80, 144, 248, 16, 16, 5, 7, 7, 6, 0, + 0, 248, 128, 240, 8, 8, 136, 112, 5, 7, 7, 6, 0, 0, 48, 64, + 128, 240, 136, 136, 112, 5, 7, 7, 6, 0, 0, 248, 8, 16, 32, 32, + 32, 32, 5, 7, 7, 6, 0, 0, 112, 136, 136, 112, 136, 136, 112, 5, + 7, 7, 6, 0, 0, 112, 136, 136, 120, 8, 16, 96, 2, 5, 5, 6, + 2, 0, 192, 192, 0, 192, 192, 2, 6, 6, 6, 2, 255, 192, 192, 0, + 192, 64, 128, 4, 7, 7, 6, 0, 0, 16, 32, 64, 128, 64, 32, 16, + 5, 3, 3, 6, 0, 2, 248, 0, 248, 4, 7, 7, 6, 1, 0, 128, + 64, 32, 16, 32, 64, 128, 5, 7, 7, 6, 0, 0, 112, 136, 8, 16, + 32, 0, 32, 5, 6, 6, 6, 0, 0, 112, 136, 8, 104, 168, 112, 5, + 7, 7, 6, 0, 0, 112, 136, 136, 248, 136, 136, 136, 5, 7, 7, 6, + 0, 0, 240, 136, 136, 240, 136, 136, 240, 5, 7, 7, 6, 0, 0, 112, + 136, 128, 128, 128, 136, 112, 5, 7, 7, 6, 0, 0, 224, 144, 136, 136, + 136, 144, 224, 5, 7, 7, 6, 0, 0, 248, 128, 128, 240, 128, 128, 248, + 5, 7, 7, 6, 0, 0, 248, 128, 128, 240, 128, 128, 128, 5, 7, 7, + 6, 0, 0, 112, 136, 128, 184, 136, 136, 112, 5, 7, 7, 6, 0, 0, + 136, 136, 136, 248, 136, 136, 136, 1, 7, 7, 6, 2, 0, 128, 128, 128, + 128, 128, 128, 128, 5, 7, 7, 6, 0, 0, 56, 16, 16, 16, 16, 144, + 96, 5, 7, 7, 6, 0, 0, 136, 144, 160, 192, 160, 144, 136, 5, 7, + 7, 6, 0, 0, 128, 128, 128, 128, 128, 128, 248, 5, 7, 7, 6, 0, + 0, 136, 216, 168, 136, 136, 136, 136, 5, 7, 7, 6, 0, 0, 136, 136, + 200, 168, 152, 136, 136, 5, 7, 7, 6, 0, 0, 112, 136, 136, 136, 136, + 136, 112, 5, 7, 7, 6, 0, 0, 240, 136, 136, 240, 128, 128, 128, 5, + 7, 7, 6, 0, 0, 112, 136, 136, 136, 168, 144, 104, 5, 7, 7, 6, + 0, 0, 240, 136, 136, 240, 160, 144, 136, 5, 7, 7, 6, 0, 0, 120, + 128, 128, 112, 8, 8, 240, 5, 7, 7, 6, 0, 0, 248, 32, 32, 32, + 32, 32, 32, 5, 7, 7, 6, 0, 0, 136, 136, 136, 136, 136, 136, 112, + 5, 7, 7, 6, 0, 0, 136, 136, 136, 136, 136, 80, 32, 5, 7, 7, + 6, 0, 0, 136, 136, 136, 136, 136, 168, 80, 5, 7, 7, 6, 0, 0, + 136, 136, 80, 32, 80, 136, 136, 5, 7, 7, 6, 0, 0, 136, 136, 136, + 80, 32, 32, 32, 5, 7, 7, 6, 0, 0, 248, 8, 16, 32, 64, 128, + 248, 3, 7, 7, 6, 1, 0, 224, 128, 128, 128, 128, 128, 224, 5, 5, + 5, 6, 0, 1, 128, 64, 32, 16, 8, 3, 7, 7, 6, 1, 0, 224, + 32, 32, 32, 32, 32, 224, 5, 3, 3, 6, 0, 4, 32, 80, 136, 5, + 1, 1, 6, 0, 0, 248, 2, 2, 2, 6, 2, 5, 128, 64, 5, 5, + 5, 6, 0, 0, 112, 8, 120, 136, 120, 5, 7, 7, 6, 0, 0, 128, + 128, 176, 200, 136, 136, 240, 5, 5, 5, 6, 0, 0, 112, 128, 128, 136, + 112, 5, 7, 7, 6, 0, 0, 8, 8, 104, 152, 136, 136, 120, 5, 5, + 5, 6, 0, 0, 112, 136, 248, 128, 112, 5, 7, 7, 6, 0, 0, 48, + 72, 224, 64, 64, 64, 64, 5, 6, 6, 6, 0, 255, 112, 136, 136, 120, + 8, 112, 5, 7, 7, 6, 0, 0, 128, 128, 176, 200, 136, 136, 136, 1, + 7, 7, 6, 2, 0, 128, 0, 128, 128, 128, 128, 128, 3, 8, 8, 6, + 1, 255, 32, 0, 32, 32, 32, 32, 160, 64, 4, 7, 7, 6, 0, 0, + 128, 128, 144, 160, 192, 160, 144, 3, 7, 7, 6, 1, 0, 192, 64, 64, + 64, 64, 64, 224, 5, 5, 5, 6, 0, 0, 208, 168, 168, 168, 168, 5, + 5, 5, 6, 0, 0, 176, 200, 136, 136, 136, 5, 5, 5, 6, 0, 0, + 112, 136, 136, 136, 112, 5, 6, 6, 6, 0, 255, 240, 136, 136, 240, 128, + 128, 5, 6, 6, 6, 0, 255, 120, 136, 136, 120, 8, 8, 5, 5, 5, + 6, 0, 0, 176, 200, 128, 128, 128, 5, 5, 5, 6, 0, 0, 112, 128, + 112, 8, 240, 5, 7, 7, 6, 0, 0, 64, 64, 224, 64, 64, 72, 48, + 5, 5, 5, 6, 0, 0, 136, 136, 136, 152, 104, 5, 5, 5, 6, 0, + 0, 136, 136, 136, 80, 32, 5, 5, 5, 6, 0, 0, 136, 136, 168, 168, + 80, 5, 5, 5, 6, 0, 0, 136, 80, 32, 80, 136, 5, 6, 6, 6, + 0, 255, 136, 136, 136, 120, 8, 112, 5, 5, 5, 6, 0, 0, 248, 16, + 32, 64, 248, 3, 7, 7, 6, 1, 0, 32, 64, 64, 128, 64, 64, 32, + 1, 7, 7, 6, 2, 0, 128, 128, 128, 128, 128, 128, 128, 3, 7, 7, + 6, 1, 0, 128, 64, 64, 32, 64, 64, 128, 5, 6, 6, 6, 0, 1, + 8, 40, 72, 248, 64, 32, 5, 7, 7, 6, 0, 0, 32, 80, 136, 136, + 136, 136, 248, 5, 7, 7, 6, 0, 0, 248, 136, 128, 240, 136, 136, 240, + 5, 8, 8, 6, 0, 255, 120, 40, 40, 40, 72, 136, 248, 136, 5, 7, + 7, 6, 0, 0, 168, 168, 168, 112, 168, 168, 168, 5, 7, 7, 6, 0, + 0, 240, 8, 8, 112, 8, 8, 240, 5, 7, 7, 6, 0, 0, 136, 136, + 152, 168, 200, 136, 136, 5, 8, 8, 6, 0, 0, 80, 32, 136, 152, 168, + 168, 200, 136, 5, 7, 7, 6, 0, 0, 120, 40, 40, 40, 40, 168, 72, + 5, 7, 7, 6, 0, 0, 248, 136, 136, 136, 136, 136, 136, 5, 7, 7, + 6, 0, 0, 136, 136, 136, 80, 32, 64, 128, 5, 8, 8, 6, 0, 255, + 136, 136, 136, 136, 136, 136, 248, 8, 5, 7, 7, 6, 0, 0, 136, 136, + 136, 120, 8, 8, 8, 5, 7, 7, 6, 0, 0, 168, 168, 168, 168, 168, + 168, 248, 5, 8, 8, 6, 0, 255, 168, 168, 168, 168, 168, 168, 248, 8, + 5, 7, 7, 6, 0, 0, 192, 64, 64, 112, 72, 72, 112, 5, 7, 7, + 6, 0, 0, 136, 136, 136, 200, 168, 168, 200, 5, 7, 7, 6, 0, 0, + 112, 136, 40, 80, 8, 136, 112, 5, 5, 5, 6, 0, 0, 64, 160, 144, + 144, 104, 5, 7, 7, 6, 0, 0, 32, 48, 40, 40, 32, 224, 224, 5, + 7, 7, 6, 0, 0, 248, 136, 128, 128, 128, 128, 128, 5, 5, 5, 6, + 0, 0, 248, 80, 80, 80, 152, 5, 7, 7, 6, 0, 0, 248, 128, 64, + 32, 64, 128, 248, 5, 5, 5, 6, 0, 0, 120, 144, 144, 144, 96, 5, + 7, 7, 6, 0, 0, 48, 40, 56, 40, 200, 216, 24, 5, 6, 6, 6, + 0, 0, 8, 112, 160, 32, 32, 16, 5, 6, 6, 6, 0, 1, 32, 112, + 112, 112, 248, 32, 5, 7, 7, 6, 0, 0, 112, 136, 136, 248, 136, 136, + 112, 5, 5, 5, 6, 0, 0, 112, 136, 136, 80, 216, 5, 7, 7, 6, + 0, 0, 48, 72, 32, 80, 136, 136, 112, 5, 3, 3, 6, 0, 2, 88, + 168, 208, 5, 6, 6, 6, 0, 0, 80, 248, 248, 248, 112, 32, 5, 5, + 5, 6, 0, 0, 112, 128, 96, 136, 112, 5, 7, 7, 6, 0, 0, 112, + 136, 136, 136, 136, 136, 136, 5, 7, 7, 6, 0, 0, 216, 216, 216, 216, + 216, 216, 216, 1, 7, 7, 6, 2, 0, 128, 0, 128, 128, 128, 128, 128, + 5, 7, 7, 6, 0, 0, 32, 112, 160, 160, 168, 112, 32, 5, 7, 7, + 6, 0, 0, 48, 64, 64, 224, 64, 80, 168, 5, 5, 5, 6, 0, 0, + 136, 112, 80, 112, 136, 5, 7, 7, 6, 0, 0, 136, 80, 248, 32, 248, + 32, 32, 1, 7, 7, 6, 2, 0, 128, 128, 128, 0, 128, 128, 128, 5, + 8, 8, 6, 0, 0, 48, 72, 32, 80, 80, 32, 144, 96, 5, 7, 7, + 6, 0, 0, 24, 32, 32, 112, 32, 32, 192, 5, 7, 7, 6, 0, 0, + 248, 136, 184, 184, 184, 136, 248, 5, 7, 7, 6, 0, 0, 112, 8, 120, + 136, 120, 0, 248, 5, 5, 5, 6, 0, 1, 40, 80, 160, 80, 40, 5, + 7, 7, 6, 0, 0, 144, 168, 168, 232, 168, 168, 144, 5, 7, 7, 6, + 0, 0, 120, 136, 136, 120, 40, 72, 136, 5, 7, 7, 6, 0, 0, 248, + 136, 168, 136, 152, 168, 248, 2, 3, 3, 6, 2, 4, 64, 128, 192, 4, + 5, 5, 6, 0, 3, 96, 144, 144, 144, 96, 5, 7, 7, 6, 0, 0, + 32, 32, 248, 32, 32, 0, 248, 4, 5, 5, 6, 0, 3, 96, 144, 32, + 64, 240, 3, 5, 5, 6, 0, 3, 224, 32, 224, 32, 224, 5, 8, 8, + 6, 0, 0, 224, 144, 224, 128, 144, 184, 144, 24, 5, 8, 8, 6, 0, + 255, 136, 136, 136, 136, 152, 232, 128, 128, 5, 7, 7, 6, 0, 0, 120, + 152, 152, 120, 24, 24, 24, 2, 2, 2, 6, 2, 2, 192, 192, 5, 5, + 5, 6, 0, 0, 80, 136, 168, 168, 80, 3, 5, 5, 6, 0, 3, 64, + 192, 64, 64, 224, 5, 7, 7, 6, 0, 0, 112, 136, 136, 136, 112, 0, + 248, 5, 5, 5, 6, 0, 1, 160, 80, 40, 80, 160, 5, 7, 7, 6, + 0, 0, 136, 144, 168, 88, 184, 8, 8, 5, 7, 7, 6, 0, 0, 136, + 144, 184, 72, 152, 32, 56, 5, 8, 8, 6, 0, 0, 192, 64, 192, 72, + 216, 56, 8, 8, 5, 7, 7, 6, 0, 0, 32, 0, 32, 64, 128, 136, + 112, 5, 8, 8, 6, 0, 0, 64, 32, 32, 80, 136, 248, 136, 136, 5, + 8, 8, 6, 0, 0, 16, 32, 32, 80, 136, 248, 136, 136, 5, 8, 8, + 6, 0, 0, 32, 80, 0, 112, 136, 248, 136, 136, 5, 8, 8, 6, 0, + 0, 104, 144, 0, 112, 136, 248, 136, 136, 5, 8, 8, 6, 0, 0, 80, + 0, 32, 80, 136, 248, 136, 136, 5, 8, 8, 6, 0, 0, 32, 80, 32, + 112, 136, 248, 136, 136, 5, 7, 7, 6, 0, 0, 56, 96, 160, 184, 224, + 160, 184, 5, 8, 8, 6, 0, 255, 112, 136, 128, 128, 136, 112, 32, 96, + 5, 8, 8, 6, 0, 0, 64, 32, 0, 248, 128, 240, 128, 248, 5, 8, + 8, 6, 0, 0, 8, 16, 0, 248, 128, 240, 128, 248, 5, 8, 8, 6, + 0, 0, 32, 80, 0, 248, 128, 240, 128, 248, 5, 7, 7, 6, 0, 0, + 80, 0, 248, 128, 240, 128, 248, 3, 8, 8, 6, 1, 0, 128, 64, 0, + 224, 64, 64, 64, 224, 3, 8, 8, 6, 1, 0, 32, 64, 0, 224, 64, + 64, 64, 224, 3, 8, 8, 6, 1, 0, 64, 160, 0, 224, 64, 64, 64, + 224, 3, 7, 7, 6, 1, 0, 160, 0, 224, 64, 64, 64, 224, 5, 7, + 7, 6, 0, 0, 112, 72, 72, 232, 72, 72, 112, 5, 8, 8, 6, 0, + 0, 104, 144, 0, 136, 200, 168, 152, 136, 5, 8, 8, 6, 0, 0, 64, + 32, 112, 136, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, 16, 32, 112, + 136, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, 32, 80, 0, 112, 136, + 136, 136, 112, 5, 8, 8, 6, 0, 0, 104, 144, 0, 112, 136, 136, 136, + 112, 5, 8, 8, 6, 0, 0, 80, 0, 112, 136, 136, 136, 136, 112, 5, + 5, 5, 6, 0, 1, 136, 80, 32, 80, 136, 5, 7, 7, 6, 0, 0, + 112, 32, 112, 168, 112, 32, 112, 5, 8, 8, 6, 0, 0, 64, 32, 136, + 136, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, 16, 32, 136, 136, 136, + 136, 136, 112, 5, 8, 8, 6, 0, 0, 32, 80, 0, 136, 136, 136, 136, + 112, 5, 8, 8, 6, 0, 0, 80, 0, 136, 136, 136, 136, 136, 112, 5, + 8, 8, 6, 0, 0, 16, 32, 136, 80, 32, 32, 32, 32, 5, 8, 8, + 6, 0, 0, 192, 64, 112, 72, 72, 112, 64, 224, 5, 7, 7, 6, 0, + 0, 48, 72, 72, 112, 72, 72, 176, 5, 8, 8, 6, 0, 0, 64, 32, + 0, 112, 8, 120, 136, 120, 5, 8, 8, 6, 0, 0, 16, 32, 0, 112, + 8, 120, 136, 120, 5, 8, 8, 6, 0, 0, 32, 80, 0, 112, 8, 120, + 136, 120, 5, 8, 8, 6, 0, 0, 104, 144, 0, 112, 8, 120, 136, 120, + 5, 7, 7, 6, 0, 0, 80, 0, 112, 8, 120, 136, 120, 5, 8, 8, + 6, 0, 0, 32, 80, 32, 112, 8, 120, 136, 120, 5, 6, 6, 6, 0, + 0, 208, 40, 120, 160, 168, 80, 5, 6, 6, 6, 0, 255, 112, 128, 136, + 112, 32, 96, 5, 8, 8, 6, 0, 0, 64, 32, 0, 112, 136, 248, 128, + 112, 5, 8, 8, 6, 0, 0, 16, 32, 0, 112, 136, 248, 128, 112, 5, + 8, 8, 6, 0, 0, 32, 80, 0, 112, 136, 248, 128, 112, 5, 7, 7, + 6, 0, 0, 80, 0, 112, 136, 248, 128, 112, 3, 8, 8, 6, 1, 0, + 128, 64, 0, 64, 192, 64, 64, 224, 3, 8, 8, 6, 1, 0, 32, 64, + 0, 64, 192, 64, 64, 224, 3, 8, 8, 6, 1, 0, 64, 160, 0, 64, + 192, 64, 64, 224, 3, 7, 7, 6, 1, 0, 160, 0, 64, 192, 64, 64, + 224, 5, 7, 7, 6, 0, 0, 160, 64, 160, 16, 120, 136, 112, 5, 8, + 8, 6, 0, 0, 104, 144, 0, 176, 200, 136, 136, 136, 5, 8, 8, 6, + 0, 0, 64, 32, 0, 112, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, + 16, 32, 0, 112, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, 32, 80, + 0, 112, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, 104, 144, 0, 112, + 136, 136, 136, 112, 5, 7, 7, 6, 0, 0, 80, 0, 112, 136, 136, 136, + 112, 5, 5, 5, 6, 0, 1, 32, 0, 248, 0, 32, 5, 7, 7, 6, + 0, 0, 16, 32, 112, 168, 112, 32, 64, 5, 8, 8, 6, 0, 0, 64, + 32, 0, 136, 136, 136, 152, 104, 5, 8, 8, 6, 0, 0, 16, 32, 0, + 136, 136, 136, 152, 104, 5, 8, 8, 6, 0, 0, 32, 80, 0, 136, 136, + 136, 152, 104, 5, 7, 7, 6, 0, 0, 80, 0, 136, 136, 136, 152, 104, + 5, 9, 9, 6, 0, 255, 16, 32, 0, 136, 136, 136, 248, 8, 112, 4, + 7, 7, 6, 1, 0, 192, 64, 96, 80, 96, 64, 224, 5, 8, 8, 6, + 0, 255, 80, 0, 136, 136, 136, 248, 8, 112 +}; diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/dogm_font_data_ISO10646_1.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/dogm_font_data_ISO10646_1.h new file mode 100644 index 00000000..8ff40d05 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/dogm_font_data_ISO10646_1.h @@ -0,0 +1,198 @@ +/** + * 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 . + * + */ + +/** + Fontname: ISO10646-1 + Copyright: A.Hardtung, public domain + Capital A Height: 7, '1' Height: 7 + Calculated Max Values w= 5 h= 9 x= 2 y= 7 dx= 6 dy= 0 ascent= 8 len= 9 + Font Bounding box w= 6 h= 9 x= 0 y=-2 + Calculated Min Values x= 0 y=-1 dx= 0 dy= 0 + Pure Font ascent = 7 descent=-1 + X Font ascent = 7 descent=-1 + Max Font ascent = 8 descent=-1 +*/ +#include +const u8g_fntpgm_uint8_t ISO10646_1_5x7[2592] U8G_SECTION(".progmem.ISO10646_1_5x7") = { + 0, 6, 9, 0, 254, 7, 1, 146, 3, 33, 32, 255, 255, 8, 255, 7, + 255, 0, 0, 0, 6, 0, 0, 1, 7, 7, 6, 2, 0, 128, 128, 128, + 128, 128, 0, 128, 3, 2, 2, 6, 1, 5, 160, 160, 5, 7, 7, 6, + 0, 0, 80, 80, 248, 80, 248, 80, 80, 5, 7, 7, 6, 0, 0, 32, + 120, 160, 112, 40, 240, 32, 5, 7, 7, 6, 0, 0, 192, 200, 16, 32, + 64, 152, 24, 5, 7, 7, 6, 0, 0, 96, 144, 160, 64, 168, 144, 104, + 2, 3, 3, 6, 1, 4, 192, 64, 128, 3, 7, 7, 6, 1, 0, 32, + 64, 128, 128, 128, 64, 32, 3, 7, 7, 6, 1, 0, 128, 64, 32, 32, + 32, 64, 128, 5, 5, 5, 6, 0, 1, 32, 168, 112, 168, 32, 5, 5, + 5, 6, 0, 1, 32, 32, 248, 32, 32, 2, 3, 3, 6, 2, 255, 192, + 64, 128, 5, 1, 1, 6, 0, 3, 248, 2, 2, 2, 6, 2, 0, 192, + 192, 5, 5, 5, 6, 0, 1, 8, 16, 32, 64, 128, 5, 7, 7, 6, + 0, 0, 112, 136, 136, 136, 136, 136, 112, 3, 7, 7, 6, 1, 0, 64, + 192, 64, 64, 64, 64, 224, 5, 7, 7, 6, 0, 0, 112, 136, 8, 112, + 128, 128, 248, 5, 7, 7, 6, 0, 0, 248, 16, 32, 16, 8, 8, 240, + 5, 7, 7, 6, 0, 0, 16, 48, 80, 144, 248, 16, 16, 5, 7, 7, + 6, 0, 0, 248, 128, 240, 8, 8, 136, 112, 5, 7, 7, 6, 0, 0, + 112, 128, 128, 240, 136, 136, 112, 5, 7, 7, 6, 0, 0, 248, 8, 16, + 32, 32, 32, 32, 5, 7, 7, 6, 0, 0, 112, 136, 136, 112, 136, 136, + 112, 5, 7, 7, 6, 0, 0, 112, 136, 136, 120, 8, 8, 112, 2, 5, + 5, 6, 2, 0, 192, 192, 0, 192, 192, 2, 6, 6, 6, 2, 255, 192, + 192, 0, 192, 64, 128, 4, 7, 7, 6, 0, 0, 16, 32, 64, 128, 64, + 32, 16, 5, 3, 3, 6, 0, 2, 248, 0, 248, 4, 7, 7, 6, 1, + 0, 128, 64, 32, 16, 32, 64, 128, 5, 7, 7, 6, 0, 0, 112, 136, + 8, 16, 32, 0, 32, 5, 7, 7, 6, 0, 0, 112, 136, 8, 104, 168, + 168, 112, 5, 7, 7, 6, 0, 0, 112, 136, 136, 248, 136, 136, 136, 5, + 7, 7, 6, 0, 0, 240, 136, 136, 240, 136, 136, 240, 5, 7, 7, 6, + 0, 0, 112, 136, 128, 128, 128, 136, 112, 5, 7, 7, 6, 0, 0, 240, + 136, 136, 136, 136, 136, 240, 5, 7, 7, 6, 0, 0, 248, 128, 128, 240, + 128, 128, 248, 5, 7, 7, 6, 0, 0, 248, 128, 128, 240, 128, 128, 128, + 5, 7, 7, 6, 0, 0, 112, 136, 128, 184, 136, 136, 112, 5, 7, 7, + 6, 0, 0, 136, 136, 136, 248, 136, 136, 136, 1, 7, 7, 6, 2, 0, + 128, 128, 128, 128, 128, 128, 128, 5, 7, 7, 6, 0, 0, 56, 16, 16, + 16, 16, 144, 96, 5, 7, 7, 6, 0, 0, 136, 144, 160, 192, 160, 144, + 136, 5, 7, 7, 6, 0, 0, 128, 128, 128, 128, 128, 128, 248, 5, 7, + 7, 6, 0, 0, 136, 216, 168, 136, 136, 136, 136, 5, 7, 7, 6, 0, + 0, 136, 136, 200, 168, 152, 136, 136, 5, 7, 7, 6, 0, 0, 112, 136, + 136, 136, 136, 136, 112, 5, 7, 7, 6, 0, 0, 240, 136, 136, 240, 128, + 128, 128, 5, 7, 7, 6, 0, 0, 112, 136, 136, 136, 168, 144, 104, 5, + 7, 7, 6, 0, 0, 240, 136, 136, 240, 160, 144, 136, 5, 7, 7, 6, + 0, 0, 120, 128, 128, 112, 8, 8, 240, 5, 7, 7, 6, 0, 0, 248, + 32, 32, 32, 32, 32, 32, 5, 7, 7, 6, 0, 0, 136, 136, 136, 136, + 136, 136, 112, 5, 7, 7, 6, 0, 0, 136, 136, 136, 136, 136, 80, 32, + 5, 7, 7, 6, 0, 0, 136, 136, 136, 136, 136, 168, 80, 5, 7, 7, + 6, 0, 0, 136, 136, 80, 32, 80, 136, 136, 5, 7, 7, 6, 0, 0, + 136, 136, 136, 80, 32, 32, 32, 5, 7, 7, 6, 0, 0, 248, 8, 16, + 32, 64, 128, 248, 3, 7, 7, 6, 1, 0, 224, 128, 128, 128, 128, 128, + 224, 5, 5, 5, 6, 0, 1, 128, 64, 32, 16, 8, 3, 7, 7, 6, + 1, 0, 224, 32, 32, 32, 32, 32, 224, 5, 3, 3, 6, 0, 4, 32, + 80, 136, 5, 1, 1, 6, 0, 0, 248, 2, 2, 2, 6, 2, 5, 128, + 64, 5, 5, 5, 6, 0, 0, 112, 8, 120, 136, 120, 5, 7, 7, 6, + 0, 0, 128, 128, 176, 200, 136, 136, 240, 5, 5, 5, 6, 0, 0, 112, + 128, 128, 136, 112, 5, 7, 7, 6, 0, 0, 8, 8, 104, 152, 136, 136, + 120, 5, 5, 5, 6, 0, 0, 112, 136, 248, 128, 112, 5, 7, 7, 6, + 0, 0, 48, 72, 224, 64, 64, 64, 64, 5, 6, 6, 6, 0, 255, 112, + 136, 136, 120, 8, 112, 5, 7, 7, 6, 0, 0, 128, 128, 176, 200, 136, + 136, 136, 1, 7, 7, 6, 2, 0, 128, 0, 128, 128, 128, 128, 128, 3, + 8, 8, 6, 1, 255, 32, 0, 32, 32, 32, 32, 160, 64, 4, 7, 7, + 6, 0, 0, 128, 128, 144, 160, 192, 160, 144, 3, 7, 7, 6, 1, 0, + 192, 64, 64, 64, 64, 64, 224, 5, 5, 5, 6, 0, 0, 208, 168, 168, + 168, 168, 5, 5, 5, 6, 0, 0, 176, 200, 136, 136, 136, 5, 5, 5, + 6, 0, 0, 112, 136, 136, 136, 112, 5, 6, 6, 6, 0, 255, 240, 136, + 136, 240, 128, 128, 5, 6, 6, 6, 0, 255, 120, 136, 136, 120, 8, 8, + 5, 5, 5, 6, 0, 0, 176, 200, 128, 128, 128, 5, 5, 5, 6, 0, + 0, 112, 128, 112, 8, 240, 4, 7, 7, 6, 0, 0, 64, 64, 224, 64, + 64, 64, 48, 5, 5, 5, 6, 0, 0, 136, 136, 136, 152, 104, 5, 5, + 5, 6, 0, 0, 136, 136, 136, 80, 32, 5, 5, 5, 6, 0, 0, 136, + 136, 168, 168, 80, 5, 5, 5, 6, 0, 0, 136, 80, 32, 80, 136, 5, + 6, 6, 6, 0, 255, 136, 136, 136, 120, 8, 112, 5, 5, 5, 6, 0, + 0, 248, 16, 32, 64, 248, 3, 7, 7, 6, 1, 0, 32, 64, 64, 128, + 64, 64, 32, 1, 7, 7, 6, 2, 0, 128, 128, 128, 128, 128, 128, 128, + 3, 7, 7, 6, 1, 0, 128, 64, 64, 32, 64, 64, 128, 5, 2, 2, + 6, 0, 2, 104, 144, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, + 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, + 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, + 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, + 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, + 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, + 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, + 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, + 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, + 0, 1, 7, 7, 6, 2, 0, 128, 0, 128, 128, 128, 128, 128, 5, 7, + 7, 6, 0, 0, 32, 112, 168, 160, 168, 112, 32, 5, 7, 7, 6, 0, + 0, 48, 64, 64, 224, 64, 80, 168, 5, 5, 5, 6, 0, 0, 136, 112, + 80, 112, 136, 5, 7, 7, 6, 0, 0, 136, 80, 32, 248, 32, 248, 32, + 1, 7, 7, 6, 2, 0, 128, 128, 128, 0, 128, 128, 128, 5, 8, 8, + 6, 0, 0, 48, 72, 32, 80, 80, 32, 144, 96, 3, 1, 1, 6, 1, + 7, 160, 5, 7, 7, 6, 0, 0, 248, 136, 184, 184, 184, 136, 248, 5, + 7, 7, 6, 0, 1, 112, 8, 120, 136, 120, 0, 248, 5, 5, 5, 6, + 0, 1, 40, 80, 160, 80, 40, 5, 3, 3, 6, 0, 1, 248, 8, 8, + 2, 2, 2, 6, 2, 6, 64, 128, 5, 7, 7, 6, 0, 0, 248, 136, + 168, 136, 152, 168, 248, 5, 1, 1, 6, 0, 6, 248, 4, 4, 4, 6, + 0, 3, 96, 144, 144, 96, 5, 7, 7, 6, 0, 0, 32, 32, 248, 32, + 32, 0, 248, 4, 5, 5, 6, 0, 3, 96, 144, 32, 64, 240, 3, 5, + 5, 6, 0, 3, 224, 32, 224, 32, 224, 2, 2, 2, 6, 2, 6, 64, + 128, 5, 8, 8, 6, 0, 255, 136, 136, 136, 136, 152, 232, 128, 128, 5, + 7, 7, 6, 0, 0, 120, 152, 152, 120, 24, 24, 24, 2, 2, 2, 6, + 2, 2, 192, 192, 2, 2, 2, 6, 2, 255, 64, 128, 3, 5, 5, 6, + 0, 3, 64, 192, 64, 64, 224, 5, 7, 7, 6, 0, 1, 112, 136, 136, + 136, 112, 0, 248, 5, 5, 5, 6, 0, 1, 160, 80, 40, 80, 160, 5, + 7, 7, 6, 0, 0, 136, 144, 168, 88, 184, 8, 8, 5, 7, 7, 6, + 0, 0, 136, 144, 184, 72, 152, 32, 56, 5, 8, 8, 6, 0, 0, 192, + 64, 192, 72, 216, 56, 8, 8, 5, 7, 7, 6, 0, 0, 32, 0, 32, + 64, 128, 136, 112, 5, 8, 8, 6, 0, 0, 64, 32, 0, 112, 136, 248, + 136, 136, 5, 8, 8, 6, 0, 0, 16, 32, 0, 112, 136, 248, 136, 136, + 5, 8, 8, 6, 0, 0, 32, 80, 0, 112, 136, 248, 136, 136, 5, 8, + 8, 6, 0, 0, 104, 144, 0, 112, 136, 248, 136, 136, 5, 8, 8, 6, + 0, 0, 80, 0, 112, 136, 136, 248, 136, 136, 5, 8, 8, 6, 0, 0, + 32, 80, 32, 112, 136, 248, 136, 136, 5, 7, 7, 6, 0, 0, 56, 96, + 160, 184, 224, 160, 184, 5, 8, 8, 6, 0, 255, 112, 136, 128, 128, 136, + 112, 32, 96, 5, 8, 8, 6, 0, 0, 64, 32, 0, 248, 128, 240, 128, + 248, 5, 8, 8, 6, 0, 0, 8, 16, 0, 248, 128, 240, 128, 248, 5, + 8, 8, 6, 0, 0, 32, 80, 0, 248, 128, 240, 128, 248, 5, 7, 7, + 6, 0, 0, 80, 0, 248, 128, 240, 128, 248, 3, 8, 8, 6, 1, 0, + 128, 64, 0, 224, 64, 64, 64, 224, 3, 8, 8, 6, 1, 0, 32, 64, + 0, 224, 64, 64, 64, 224, 3, 8, 8, 6, 1, 0, 64, 160, 0, 224, + 64, 64, 64, 224, 3, 7, 7, 6, 1, 0, 160, 0, 224, 64, 64, 64, + 224, 5, 7, 7, 6, 0, 0, 112, 72, 72, 232, 72, 72, 112, 5, 8, + 8, 6, 0, 0, 104, 144, 0, 136, 200, 168, 152, 136, 5, 8, 8, 6, + 0, 0, 64, 32, 112, 136, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, + 16, 32, 112, 136, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, 32, 80, + 0, 112, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, 104, 144, 0, 112, + 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, 80, 0, 112, 136, 136, 136, + 136, 112, 5, 5, 5, 6, 0, 1, 136, 80, 32, 80, 136, 5, 8, 8, + 6, 0, 255, 16, 112, 168, 168, 168, 168, 112, 64, 5, 8, 8, 6, 0, + 0, 64, 32, 136, 136, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, 16, + 32, 136, 136, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, 32, 80, 0, + 136, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, 80, 0, 136, 136, 136, + 136, 136, 112, 5, 8, 8, 6, 0, 0, 16, 32, 136, 80, 32, 32, 32, + 32, 5, 9, 9, 6, 0, 255, 192, 64, 112, 72, 72, 112, 64, 64, 224, + 4, 8, 8, 6, 1, 255, 96, 144, 144, 160, 144, 144, 224, 128, 5, 8, + 8, 6, 0, 0, 64, 32, 0, 112, 8, 120, 136, 120, 5, 8, 8, 6, + 0, 0, 16, 32, 0, 112, 8, 120, 136, 120, 5, 8, 8, 6, 0, 0, + 32, 80, 0, 112, 8, 120, 136, 120, 5, 8, 8, 6, 0, 0, 104, 144, + 0, 112, 8, 120, 136, 120, 5, 7, 7, 6, 0, 0, 80, 0, 112, 8, + 120, 136, 120, 5, 8, 8, 6, 0, 0, 32, 80, 32, 112, 8, 120, 136, + 120, 5, 6, 6, 6, 0, 0, 208, 40, 120, 160, 168, 80, 5, 6, 6, + 6, 0, 255, 112, 128, 136, 112, 32, 96, 5, 8, 8, 6, 0, 0, 64, + 32, 0, 112, 136, 248, 128, 112, 5, 8, 8, 6, 0, 0, 16, 32, 0, + 112, 136, 248, 128, 112, 5, 8, 8, 6, 0, 0, 32, 80, 0, 112, 136, + 248, 128, 112, 5, 7, 7, 6, 0, 0, 80, 0, 112, 136, 248, 128, 112, + 3, 8, 8, 6, 1, 0, 128, 64, 0, 64, 192, 64, 64, 224, 3, 8, + 8, 6, 1, 0, 32, 64, 0, 64, 192, 64, 64, 224, 3, 8, 8, 6, + 1, 0, 64, 160, 0, 64, 192, 64, 64, 224, 3, 7, 7, 6, 1, 0, + 160, 0, 64, 192, 64, 64, 224, 5, 7, 7, 6, 0, 0, 160, 64, 160, + 16, 120, 136, 112, 5, 8, 8, 6, 0, 0, 104, 144, 0, 176, 200, 136, + 136, 136, 5, 8, 8, 6, 0, 0, 64, 32, 0, 112, 136, 136, 136, 112, + 5, 8, 8, 6, 0, 0, 16, 32, 0, 112, 136, 136, 136, 112, 5, 8, + 8, 6, 0, 0, 32, 80, 0, 112, 136, 136, 136, 112, 5, 8, 8, 6, + 0, 0, 104, 144, 0, 112, 136, 136, 136, 112, 5, 7, 7, 6, 0, 0, + 80, 0, 112, 136, 136, 136, 112, 5, 5, 5, 6, 0, 1, 32, 0, 248, + 0, 32, 5, 7, 7, 6, 0, 255, 16, 112, 168, 168, 168, 112, 64, 5, + 8, 8, 6, 0, 0, 64, 32, 0, 136, 136, 136, 152, 104, 5, 8, 8, + 6, 0, 0, 16, 32, 0, 136, 136, 136, 152, 104, 5, 8, 8, 6, 0, + 0, 32, 80, 0, 136, 136, 136, 152, 104, 5, 7, 7, 6, 0, 0, 80, + 0, 136, 136, 136, 152, 104, 5, 9, 9, 6, 0, 255, 16, 32, 0, 136, + 136, 136, 248, 8, 112, 4, 7, 7, 6, 1, 255, 192, 64, 96, 80, 96, + 64, 224, 5, 8, 8, 6, 0, 255, 80, 0, 136, 136, 136, 120, 8, 112 +}; diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/dogm_font_data_ISO10646_5_Cyrillic.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/dogm_font_data_ISO10646_5_Cyrillic.h new file mode 100644 index 00000000..75e779fd --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/dogm_font_data_ISO10646_5_Cyrillic.h @@ -0,0 +1,196 @@ +/** + * 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 . + * + */ + +/** + Fontname: ISO10646_5_Cyrillic + Copyright: A. Hardtung, public domain + Capital A Height: 7, '1' Height: 7 + Calculated Max Values w= 5 h= 9 x= 2 y= 5 dx= 6 dy= 0 ascent= 8 len= 9 + Font Bounding box w= 6 h= 9 x= 0 y=-2 + Calculated Min Values x= 0 y=-1 dx= 0 dy= 0 + Pure Font ascent = 7 descent=-1 + X Font ascent = 7 descent=-1 + Max Font ascent = 8 descent=-1 +*/ +#include +const u8g_fntpgm_uint8_t ISO10646_5_Cyrillic_5x7[2560] U8G_SECTION(".progmem.ISO10646_5_Cyrillic_5x7") = { + 0, 6, 9, 0, 254, 7, 1, 145, 3, 32, 32, 255, 255, 8, 255, 7, + 255, 0, 0, 0, 6, 0, 0, 1, 7, 7, 6, 2, 0, 128, 128, 128, + 128, 128, 0, 128, 3, 2, 2, 6, 1, 5, 160, 160, 5, 7, 7, 6, + 0, 0, 80, 80, 248, 80, 248, 80, 80, 5, 7, 7, 6, 0, 0, 32, + 120, 160, 112, 40, 240, 32, 5, 7, 7, 6, 0, 0, 192, 200, 16, 32, + 64, 152, 24, 5, 7, 7, 6, 0, 0, 96, 144, 160, 64, 168, 144, 104, + 2, 3, 3, 6, 1, 4, 192, 64, 128, 3, 7, 7, 6, 1, 0, 32, + 64, 128, 128, 128, 64, 32, 3, 7, 7, 6, 1, 0, 128, 64, 32, 32, + 32, 64, 128, 5, 5, 5, 6, 0, 1, 32, 168, 112, 168, 32, 5, 5, + 5, 6, 0, 1, 32, 32, 248, 32, 32, 2, 3, 3, 6, 2, 255, 192, + 64, 128, 5, 1, 1, 6, 0, 3, 248, 2, 2, 2, 6, 2, 0, 192, + 192, 5, 5, 5, 6, 0, 1, 8, 16, 32, 64, 128, 5, 7, 7, 6, + 0, 0, 112, 136, 152, 168, 200, 136, 112, 3, 7, 7, 6, 1, 0, 64, + 192, 64, 64, 64, 64, 224, 5, 7, 7, 6, 0, 0, 112, 136, 8, 112, + 128, 128, 248, 5, 7, 7, 6, 0, 0, 248, 16, 32, 16, 8, 8, 240, + 5, 7, 7, 6, 0, 0, 16, 48, 80, 144, 248, 16, 16, 5, 7, 7, + 6, 0, 0, 248, 128, 240, 8, 8, 136, 112, 5, 7, 7, 6, 0, 0, + 48, 64, 128, 240, 136, 136, 112, 5, 7, 7, 6, 0, 0, 248, 8, 16, + 32, 32, 32, 32, 5, 7, 7, 6, 0, 0, 112, 136, 136, 112, 136, 136, + 112, 5, 7, 7, 6, 0, 0, 112, 136, 136, 120, 8, 16, 96, 2, 5, + 5, 6, 2, 0, 192, 192, 0, 192, 192, 2, 6, 6, 6, 2, 255, 192, + 192, 0, 192, 64, 128, 4, 7, 7, 6, 0, 0, 16, 32, 64, 128, 64, + 32, 16, 5, 3, 3, 6, 0, 2, 248, 0, 248, 4, 7, 7, 6, 1, + 0, 128, 64, 32, 16, 32, 64, 128, 5, 7, 7, 6, 0, 0, 112, 136, + 8, 16, 32, 0, 32, 5, 6, 6, 6, 0, 0, 112, 136, 8, 104, 168, + 112, 5, 7, 7, 6, 0, 0, 112, 136, 136, 248, 136, 136, 136, 5, 7, + 7, 6, 0, 0, 240, 136, 136, 240, 136, 136, 240, 5, 7, 7, 6, 0, + 0, 112, 136, 128, 128, 128, 136, 112, 5, 7, 7, 6, 0, 0, 224, 144, + 136, 136, 136, 144, 224, 5, 7, 7, 6, 0, 0, 248, 128, 128, 240, 128, + 128, 248, 5, 7, 7, 6, 0, 0, 248, 128, 128, 240, 128, 128, 128, 5, + 7, 7, 6, 0, 0, 112, 136, 128, 184, 136, 136, 112, 5, 7, 7, 6, + 0, 0, 136, 136, 136, 248, 136, 136, 136, 1, 7, 7, 6, 2, 0, 128, + 128, 128, 128, 128, 128, 128, 5, 7, 7, 6, 0, 0, 56, 16, 16, 16, + 16, 144, 96, 5, 7, 7, 6, 0, 0, 136, 144, 160, 192, 160, 144, 136, + 5, 7, 7, 6, 0, 0, 128, 128, 128, 128, 128, 128, 248, 5, 7, 7, + 6, 0, 0, 136, 216, 168, 136, 136, 136, 136, 5, 7, 7, 6, 0, 0, + 136, 136, 200, 168, 152, 136, 136, 5, 7, 7, 6, 0, 0, 112, 136, 136, + 136, 136, 136, 112, 5, 7, 7, 6, 0, 0, 240, 136, 136, 240, 128, 128, + 128, 5, 7, 7, 6, 0, 0, 112, 136, 136, 136, 168, 144, 104, 5, 7, + 7, 6, 0, 0, 240, 136, 136, 240, 160, 144, 136, 5, 7, 7, 6, 0, + 0, 120, 128, 128, 112, 8, 8, 240, 5, 7, 7, 6, 0, 0, 248, 32, + 32, 32, 32, 32, 32, 5, 7, 7, 6, 0, 0, 136, 136, 136, 136, 136, + 136, 112, 5, 7, 7, 6, 0, 0, 136, 136, 136, 136, 136, 80, 32, 5, + 7, 7, 6, 0, 0, 136, 136, 136, 136, 136, 168, 80, 5, 7, 7, 6, + 0, 0, 136, 136, 80, 32, 80, 136, 136, 5, 7, 7, 6, 0, 0, 136, + 136, 136, 80, 32, 32, 32, 5, 7, 7, 6, 0, 0, 248, 8, 16, 32, + 64, 128, 248, 3, 7, 7, 6, 1, 0, 224, 128, 128, 128, 128, 128, 224, + 5, 5, 5, 6, 0, 1, 128, 64, 32, 16, 8, 3, 7, 7, 6, 1, + 0, 224, 32, 32, 32, 32, 32, 224, 5, 3, 3, 6, 0, 4, 32, 80, + 136, 5, 1, 1, 6, 0, 0, 248, 2, 2, 2, 6, 2, 5, 128, 64, + 5, 5, 5, 6, 0, 0, 112, 8, 120, 136, 120, 5, 7, 7, 6, 0, + 0, 128, 128, 176, 200, 136, 136, 240, 5, 5, 5, 6, 0, 0, 112, 128, + 128, 136, 112, 5, 7, 7, 6, 0, 0, 8, 8, 104, 152, 136, 136, 120, + 5, 5, 5, 6, 0, 0, 112, 136, 248, 128, 112, 5, 7, 7, 6, 0, + 0, 48, 72, 224, 64, 64, 64, 64, 5, 6, 6, 6, 0, 255, 112, 136, + 136, 120, 8, 112, 5, 7, 7, 6, 0, 0, 128, 128, 176, 200, 136, 136, + 136, 1, 7, 7, 6, 2, 0, 128, 0, 128, 128, 128, 128, 128, 3, 8, + 8, 6, 1, 255, 32, 0, 32, 32, 32, 32, 160, 64, 4, 7, 7, 6, + 0, 0, 128, 128, 144, 160, 192, 160, 144, 3, 7, 7, 6, 1, 0, 192, + 64, 64, 64, 64, 64, 224, 5, 5, 5, 6, 0, 0, 208, 168, 168, 168, + 168, 5, 5, 5, 6, 0, 0, 176, 200, 136, 136, 136, 5, 5, 5, 6, + 0, 0, 112, 136, 136, 136, 112, 5, 6, 6, 6, 0, 255, 240, 136, 136, + 240, 128, 128, 5, 6, 6, 6, 0, 255, 120, 136, 136, 120, 8, 8, 5, + 5, 5, 6, 0, 0, 176, 200, 128, 128, 128, 5, 5, 5, 6, 0, 0, + 112, 128, 112, 8, 240, 5, 7, 7, 6, 0, 0, 64, 64, 224, 64, 64, + 72, 48, 5, 5, 5, 6, 0, 0, 136, 136, 136, 152, 104, 5, 5, 5, + 6, 0, 0, 136, 136, 136, 80, 32, 5, 5, 5, 6, 0, 0, 136, 136, + 168, 168, 80, 5, 5, 5, 6, 0, 0, 136, 80, 32, 80, 136, 5, 6, + 6, 6, 0, 255, 136, 136, 136, 120, 8, 112, 5, 5, 5, 6, 0, 0, + 248, 16, 32, 64, 248, 3, 7, 7, 6, 1, 0, 32, 64, 64, 128, 64, + 64, 32, 1, 7, 7, 6, 2, 0, 128, 128, 128, 128, 128, 128, 128, 3, + 7, 7, 6, 1, 0, 128, 64, 64, 32, 64, 64, 128, 5, 2, 2, 6, + 0, 3, 104, 144, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, + 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, + 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, + 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, + 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, + 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, + 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, + 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, + 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, + 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, + 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, + 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, + 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 5, 8, 8, 6, 0, 0, + 64, 248, 128, 128, 240, 128, 128, 248, 5, 8, 8, 6, 0, 0, 80, 248, + 128, 128, 240, 128, 128, 248, 5, 7, 7, 6, 0, 0, 224, 64, 64, 112, + 72, 72, 112, 5, 8, 8, 6, 0, 0, 16, 32, 248, 136, 128, 128, 128, + 128, 5, 7, 7, 6, 0, 0, 48, 72, 128, 224, 128, 72, 48, 5, 7, + 7, 6, 0, 0, 112, 136, 128, 112, 8, 136, 112, 3, 7, 7, 6, 1, + 0, 224, 64, 64, 64, 64, 64, 224, 3, 8, 8, 6, 1, 0, 160, 0, + 224, 64, 64, 64, 64, 224, 5, 7, 7, 6, 0, 0, 56, 16, 16, 16, + 16, 144, 96, 5, 7, 7, 6, 0, 0, 160, 160, 160, 184, 168, 168, 184, + 5, 7, 7, 6, 0, 0, 160, 160, 160, 248, 168, 168, 184, 4, 7, 7, + 6, 0, 0, 224, 64, 112, 80, 80, 80, 80, 5, 8, 8, 6, 0, 0, + 16, 32, 136, 144, 160, 224, 144, 136, 5, 8, 8, 6, 0, 0, 64, 32, + 136, 152, 168, 200, 136, 136, 5, 9, 9, 6, 0, 255, 80, 32, 136, 136, + 136, 80, 32, 32, 32, 5, 8, 8, 6, 0, 255, 136, 136, 136, 136, 136, + 136, 248, 32, 5, 7, 7, 6, 0, 0, 112, 136, 136, 248, 136, 136, 136, + 5, 7, 7, 6, 0, 0, 248, 128, 128, 240, 136, 136, 240, 5, 7, 7, + 6, 0, 0, 240, 136, 136, 240, 136, 136, 240, 5, 7, 7, 6, 0, 0, + 248, 136, 128, 128, 128, 128, 128, 5, 8, 8, 6, 0, 255, 120, 40, 40, + 40, 72, 136, 248, 136, 5, 7, 7, 6, 0, 0, 248, 128, 128, 240, 128, + 128, 248, 5, 7, 7, 6, 0, 0, 168, 168, 168, 112, 168, 168, 168, 5, + 7, 7, 6, 0, 0, 240, 8, 8, 112, 8, 8, 240, 5, 7, 7, 6, + 0, 0, 136, 136, 152, 168, 200, 136, 136, 5, 8, 8, 6, 0, 0, 80, + 32, 136, 152, 168, 168, 200, 136, 5, 7, 7, 6, 0, 0, 136, 144, 160, + 192, 160, 144, 136, 5, 7, 7, 6, 0, 0, 120, 40, 40, 40, 40, 168, + 72, 5, 7, 7, 6, 0, 0, 136, 216, 168, 136, 136, 136, 136, 5, 7, + 7, 6, 0, 0, 136, 136, 136, 248, 136, 136, 136, 5, 7, 7, 6, 0, + 0, 112, 136, 136, 136, 136, 136, 112, 5, 7, 7, 6, 0, 0, 248, 136, + 136, 136, 136, 136, 136, 5, 7, 7, 6, 0, 0, 240, 136, 136, 240, 128, + 128, 128, 5, 7, 7, 6, 0, 0, 112, 136, 128, 128, 128, 136, 112, 5, + 7, 7, 6, 0, 0, 248, 32, 32, 32, 32, 32, 32, 5, 7, 7, 6, + 0, 0, 136, 136, 136, 80, 32, 64, 128, 5, 7, 7, 6, 0, 0, 32, + 112, 168, 168, 168, 112, 32, 5, 7, 7, 6, 0, 0, 136, 136, 80, 32, + 80, 136, 136, 5, 8, 8, 6, 0, 255, 136, 136, 136, 136, 136, 136, 248, + 8, 5, 7, 7, 6, 0, 0, 136, 136, 136, 152, 104, 8, 8, 5, 7, + 7, 6, 0, 0, 168, 168, 168, 168, 168, 168, 248, 5, 8, 8, 6, 0, + 255, 168, 168, 168, 168, 168, 168, 248, 8, 5, 7, 7, 6, 0, 0, 192, + 64, 64, 112, 72, 72, 112, 5, 7, 7, 6, 0, 0, 136, 136, 136, 200, + 168, 168, 200, 5, 7, 7, 6, 0, 0, 128, 128, 128, 240, 136, 136, 240, + 5, 7, 7, 6, 0, 0, 112, 136, 8, 56, 8, 136, 112, 5, 7, 7, + 6, 0, 0, 144, 168, 168, 232, 168, 168, 144, 5, 7, 7, 6, 0, 0, + 120, 136, 136, 120, 40, 72, 136, 5, 5, 5, 6, 0, 0, 112, 8, 120, + 136, 120, 5, 7, 7, 6, 0, 0, 24, 96, 128, 240, 136, 136, 112, 4, + 5, 5, 6, 0, 0, 224, 144, 224, 144, 224, 5, 5, 5, 6, 0, 0, + 248, 136, 128, 128, 128, 5, 6, 6, 6, 0, 255, 120, 40, 72, 136, 248, + 136, 5, 5, 5, 6, 0, 0, 112, 136, 248, 128, 112, 5, 5, 5, 6, + 0, 0, 168, 168, 112, 168, 168, 5, 5, 5, 6, 0, 0, 240, 8, 48, + 8, 240, 5, 5, 5, 6, 0, 0, 136, 152, 168, 200, 136, 5, 7, 7, + 6, 0, 0, 80, 32, 136, 152, 168, 200, 136, 4, 5, 5, 6, 0, 0, + 144, 160, 192, 160, 144, 5, 5, 5, 6, 0, 0, 248, 40, 40, 168, 72, + 5, 5, 5, 6, 0, 0, 136, 216, 168, 136, 136, 5, 5, 5, 6, 0, + 0, 136, 136, 248, 136, 136, 5, 5, 5, 6, 0, 0, 112, 136, 136, 136, + 112, 5, 5, 5, 6, 0, 0, 248, 136, 136, 136, 136, 5, 6, 6, 6, + 0, 255, 240, 136, 136, 240, 128, 128, 5, 5, 5, 6, 0, 0, 112, 128, + 128, 136, 112, 5, 5, 5, 6, 0, 0, 248, 32, 32, 32, 32, 5, 6, + 6, 6, 0, 255, 136, 136, 136, 120, 8, 112, 5, 6, 6, 6, 0, 0, + 32, 112, 168, 168, 112, 32, 5, 5, 5, 6, 0, 0, 136, 80, 32, 80, + 136, 5, 6, 6, 6, 0, 255, 136, 136, 136, 136, 248, 8, 5, 5, 5, + 6, 0, 0, 136, 136, 248, 8, 8, 5, 5, 5, 6, 0, 0, 168, 168, + 168, 168, 248, 5, 6, 6, 6, 0, 255, 168, 168, 168, 168, 248, 8, 5, + 5, 5, 6, 0, 0, 192, 64, 112, 72, 112, 5, 5, 5, 6, 0, 0, + 136, 136, 200, 168, 200, 3, 5, 5, 6, 1, 0, 128, 128, 192, 160, 192, + 5, 5, 5, 6, 0, 0, 112, 136, 56, 136, 112, 5, 5, 5, 6, 0, + 0, 144, 168, 232, 168, 144, 5, 5, 5, 6, 0, 0, 120, 136, 120, 40, + 72, 5, 8, 8, 6, 0, 0, 64, 32, 0, 112, 136, 248, 128, 112, 5, + 7, 7, 6, 0, 0, 80, 0, 112, 136, 248, 128, 112, 5, 9, 9, 6, + 0, 255, 64, 224, 64, 64, 120, 72, 72, 72, 16, 5, 8, 8, 6, 0, + 0, 16, 32, 0, 248, 136, 128, 128, 128, 5, 5, 5, 6, 0, 0, 112, + 136, 96, 136, 112, 5, 5, 5, 6, 0, 0, 112, 128, 112, 8, 240, 1, + 7, 7, 6, 2, 0, 128, 0, 128, 128, 128, 128, 128, 3, 7, 7, 6, + 1, 0, 160, 0, 64, 64, 64, 64, 64, 3, 8, 8, 6, 1, 255, 32, + 0, 32, 32, 32, 32, 160, 64, 5, 5, 5, 6, 0, 0, 160, 160, 184, + 168, 184, 5, 5, 5, 6, 0, 0, 160, 160, 248, 168, 184, 5, 6, 6, + 6, 0, 0, 64, 224, 64, 120, 72, 72, 4, 8, 8, 6, 0, 0, 16, + 32, 0, 144, 160, 192, 160, 144, 5, 8, 8, 6, 0, 0, 64, 32, 0, + 136, 152, 168, 200, 136, 5, 9, 9, 6, 0, 255, 80, 32, 0, 136, 136, + 136, 120, 8, 112, 5, 6, 6, 6, 0, 255, 136, 136, 136, 136, 248, 32 +}; diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/dogm_font_data_ISO10646_CN.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/dogm_font_data_ISO10646_CN.h new file mode 100644 index 00000000..11fdb224 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/dogm_font_data_ISO10646_CN.h @@ -0,0 +1,293 @@ +/** + * 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 . + * + */ + +/** + Fontname: ISO10646_CN + Copyright: A. Hardtung, public domain + Capital A Height: 7, '1' Height: 7 + Calculated Max Values w=11 h=11 x= 2 y=10 dx=12 dy= 0 ascent=10 len=22 + Font Bounding box w=12 h=11 x= 0 y=-2 + Calculated Min Values x= 0 y=-1 dx= 0 dy= 0 + Pure Font ascent = 7 descent=-1 + X Font ascent = 7 descent=-1 + Max Font ascent =10 descent=-1 +*/ +#include +const u8g_fntpgm_uint8_t ISO10646_CN[4105] U8G_SECTION(".progmem.ISO10646_CN") = { + 0, 12, 11, 0, 254, 7, 1, 146, 3, 33, 32, 255, 255, 10, 255, 7, + 255, 0, 0, 0, 6, 0, 10, 1, 7, 7, 6, 2, 0, 128, 128, 128, + 128, 128, 0, 128, 3, 2, 2, 6, 1, 5, 160, 160, 5, 7, 7, 6, + 0, 0, 80, 80, 248, 80, 248, 80, 80, 5, 7, 7, 6, 0, 0, 32, + 120, 160, 112, 40, 240, 32, 5, 7, 7, 6, 0, 0, 192, 200, 16, 32, + 64, 152, 24, 5, 7, 7, 6, 0, 0, 96, 144, 160, 64, 168, 144, 104, + 2, 3, 3, 6, 1, 4, 192, 64, 128, 3, 7, 7, 6, 1, 0, 32, + 64, 128, 128, 128, 64, 32, 3, 7, 7, 6, 1, 0, 128, 64, 32, 32, + 32, 64, 128, 5, 5, 5, 6, 0, 1, 32, 168, 112, 168, 32, 5, 5, + 5, 6, 0, 1, 32, 32, 248, 32, 32, 2, 3, 3, 6, 2, 255, 192, + 64, 128, 5, 1, 1, 6, 0, 3, 248, 2, 2, 2, 6, 2, 0, 192, + 192, 5, 5, 5, 6, 0, 1, 8, 16, 32, 64, 128, 5, 7, 7, 6, + 0, 0, 112, 136, 152, 168, 200, 136, 112, 3, 7, 7, 6, 1, 0, 64, + 192, 64, 64, 64, 64, 224, 5, 7, 7, 6, 0, 0, 112, 136, 8, 112, + 128, 128, 248, 5, 7, 7, 6, 0, 0, 248, 16, 32, 16, 8, 8, 240, + 5, 7, 7, 6, 0, 0, 16, 48, 80, 144, 248, 16, 16, 5, 7, 7, + 6, 0, 0, 248, 128, 240, 8, 8, 136, 112, 5, 7, 7, 6, 0, 0, + 112, 128, 128, 240, 136, 136, 112, 5, 7, 7, 6, 0, 0, 248, 8, 16, + 32, 32, 32, 32, 5, 7, 7, 6, 0, 0, 112, 136, 136, 112, 136, 136, + 112, 5, 7, 7, 6, 0, 0, 112, 136, 136, 120, 8, 8, 112, 2, 5, + 5, 6, 2, 0, 192, 192, 0, 192, 192, 2, 6, 6, 6, 2, 255, 192, + 192, 0, 192, 64, 128, 4, 7, 7, 6, 0, 0, 16, 32, 64, 128, 64, + 32, 16, 5, 3, 3, 6, 0, 2, 248, 0, 248, 4, 7, 7, 6, 0, + 0, 128, 64, 32, 16, 32, 64, 128, 5, 7, 7, 6, 0, 0, 112, 136, + 8, 16, 32, 0, 32, 5, 7, 7, 6, 0, 0, 112, 136, 8, 104, 168, + 168, 112, 5, 7, 7, 6, 0, 0, 112, 136, 136, 248, 136, 136, 136, 5, + 7, 7, 6, 0, 0, 240, 136, 136, 240, 136, 136, 240, 5, 7, 7, 6, + 0, 0, 112, 136, 128, 128, 128, 136, 112, 5, 7, 7, 6, 0, 0, 240, + 136, 136, 136, 136, 136, 240, 5, 7, 7, 6, 0, 0, 248, 128, 128, 240, + 128, 128, 248, 5, 7, 7, 6, 0, 0, 248, 128, 128, 240, 128, 128, 128, + 5, 7, 7, 6, 0, 0, 112, 136, 128, 184, 136, 136, 112, 5, 7, 7, + 6, 0, 0, 136, 136, 136, 248, 136, 136, 136, 1, 7, 7, 6, 2, 0, + 128, 128, 128, 128, 128, 128, 128, 5, 7, 7, 6, 0, 0, 56, 16, 16, + 16, 16, 144, 96, 5, 7, 7, 6, 0, 0, 136, 144, 160, 192, 160, 144, + 136, 5, 7, 7, 6, 0, 0, 128, 128, 128, 128, 128, 128, 248, 5, 7, + 7, 6, 0, 0, 136, 216, 168, 136, 136, 136, 136, 5, 7, 7, 6, 0, + 0, 136, 136, 200, 168, 152, 136, 136, 5, 7, 7, 6, 0, 0, 112, 136, + 136, 136, 136, 136, 112, 5, 7, 7, 6, 0, 0, 240, 136, 136, 240, 128, + 128, 128, 5, 7, 7, 6, 0, 0, 112, 136, 136, 136, 168, 144, 104, 5, + 7, 7, 6, 0, 0, 240, 136, 136, 240, 160, 144, 136, 5, 7, 7, 6, + 0, 0, 120, 128, 128, 112, 8, 8, 240, 5, 7, 7, 6, 0, 0, 248, + 32, 32, 32, 32, 32, 32, 5, 7, 7, 6, 0, 0, 136, 136, 136, 136, + 136, 136, 112, 5, 7, 7, 6, 0, 0, 136, 136, 136, 136, 136, 80, 32, + 5, 7, 7, 6, 0, 0, 136, 136, 136, 136, 136, 168, 80, 5, 7, 7, + 6, 0, 0, 136, 136, 80, 32, 80, 136, 136, 5, 7, 7, 6, 0, 0, + 136, 136, 136, 80, 32, 32, 32, 5, 7, 7, 6, 0, 0, 248, 8, 16, + 32, 64, 128, 248, 3, 7, 7, 6, 0, 0, 224, 128, 128, 128, 128, 128, + 224, 5, 5, 5, 6, 0, 1, 128, 64, 32, 16, 8, 3, 7, 7, 6, + 0, 0, 224, 32, 32, 32, 32, 32, 224, 5, 3, 3, 6, 0, 4, 32, + 80, 136, 5, 1, 1, 6, 0, 0, 248, 2, 2, 2, 6, 2, 5, 128, + 64, 5, 5, 5, 6, 0, 0, 112, 8, 120, 136, 120, 5, 7, 7, 6, + 0, 0, 128, 128, 176, 200, 136, 136, 240, 5, 5, 5, 6, 0, 0, 112, + 128, 128, 136, 112, 5, 7, 7, 6, 0, 0, 8, 8, 104, 152, 136, 136, + 120, 5, 5, 5, 6, 0, 0, 112, 136, 248, 128, 112, 5, 7, 7, 6, + 0, 0, 48, 72, 224, 64, 64, 64, 64, 5, 6, 6, 6, 0, 255, 112, + 136, 136, 120, 8, 112, 5, 7, 7, 6, 0, 0, 128, 128, 176, 200, 136, + 136, 136, 1, 7, 7, 6, 2, 0, 128, 0, 128, 128, 128, 128, 128, 3, + 8, 8, 6, 1, 255, 32, 0, 32, 32, 32, 32, 160, 64, 4, 7, 7, + 6, 1, 0, 128, 128, 144, 160, 192, 160, 144, 3, 7, 7, 6, 1, 0, + 192, 64, 64, 64, 64, 64, 224, 5, 5, 5, 6, 0, 0, 208, 168, 168, + 168, 168, 5, 5, 5, 6, 0, 0, 176, 200, 136, 136, 136, 5, 5, 5, + 6, 0, 0, 112, 136, 136, 136, 112, 5, 6, 6, 6, 0, 255, 240, 136, + 136, 240, 128, 128, 5, 6, 6, 6, 0, 255, 120, 136, 136, 120, 8, 8, + 5, 5, 5, 6, 0, 0, 176, 200, 128, 128, 128, 5, 5, 5, 6, 0, + 0, 112, 128, 112, 8, 240, 4, 7, 7, 6, 0, 0, 64, 64, 224, 64, + 64, 64, 48, 5, 5, 5, 6, 0, 0, 136, 136, 136, 152, 104, 5, 5, + 5, 6, 0, 0, 136, 136, 136, 80, 32, 5, 5, 5, 6, 0, 0, 136, + 136, 168, 168, 80, 5, 5, 5, 6, 0, 0, 136, 80, 32, 80, 136, 5, + 6, 6, 6, 0, 255, 136, 136, 136, 120, 8, 112, 5, 5, 5, 6, 0, + 0, 248, 16, 32, 64, 248, 3, 7, 7, 6, 1, 0, 32, 64, 64, 128, + 64, 64, 32, 1, 7, 7, 6, 2, 0, 128, 128, 128, 128, 128, 128, 128, + 3, 7, 7, 6, 1, 0, 128, 64, 64, 32, 64, 64, 128, 5, 2, 2, + 6, 0, 3, 104, 144, 0, 0, 0, 6, 0, 10, 0, 0, 0, 12, 0, + 10, 0, 0, 0, 12, 0, 10, 0, 0, 0, 12, 0, 10, 0, 0, 0, + 12, 0, 10, 0, 0, 0, 12, 0, 10, 0, 0, 0, 12, 0, 10, 0, + 0, 0, 12, 0, 10, 0, 0, 0, 12, 0, 10, 0, 0, 0, 12, 0, + 10, 0, 0, 0, 12, 0, 10, 0, 0, 0, 12, 0, 10, 0, 0, 0, + 12, 0, 10, 0, 0, 0, 12, 0, 10, 0, 0, 0, 12, 0, 10, 0, + 0, 0, 12, 0, 10, 0, 0, 0, 12, 0, 10, 0, 0, 0, 12, 0, + 10, 0, 0, 0, 12, 0, 10, 0, 0, 0, 12, 0, 10, 0, 0, 0, + 12, 0, 10, 0, 0, 0, 12, 0, 10, 0, 0, 0, 12, 0, 10, 0, + 0, 0, 12, 0, 10, 0, 0, 0, 12, 0, 10, 0, 0, 0, 12, 0, + 10, 0, 0, 0, 12, 0, 10, 0, 0, 0, 12, 0, 10, 0, 0, 0, + 12, 0, 10, 0, 0, 0, 12, 0, 10, 11, 11, 22, 12, 0, 255, 255, + 224, 2, 0, 2, 0, 4, 0, 13, 0, 20, 128, 36, 64, 196, 32, 4, + 0, 4, 0, 4, 0, 11, 11, 22, 12, 0, 255, 249, 0, 138, 0, 171, + 224, 172, 64, 170, 64, 170, 64, 170, 64, 170, 128, 33, 0, 82, 128, 140, + 96, 11, 11, 22, 12, 0, 255, 36, 0, 36, 0, 63, 128, 68, 0, 132, + 0, 4, 0, 255, 224, 10, 0, 17, 0, 32, 128, 192, 96, 11, 11, 22, + 12, 0, 255, 36, 0, 36, 0, 63, 192, 68, 0, 4, 0, 255, 224, 9, + 0, 9, 0, 17, 32, 33, 32, 64, 224, 11, 11, 22, 12, 0, 255, 32, + 0, 61, 224, 81, 32, 145, 32, 17, 32, 255, 32, 17, 32, 41, 32, 37, + 224, 69, 32, 128, 0, 11, 11, 22, 12, 0, 255, 32, 128, 127, 192, 8, + 64, 255, 224, 17, 0, 32, 128, 95, 64, 128, 32, 63, 128, 0, 0, 127, + 192, 11, 11, 22, 12, 0, 255, 34, 64, 71, 224, 148, 128, 228, 128, 47, + 224, 68, 128, 244, 128, 7, 224, 52, 128, 196, 128, 7, 224, 11, 11, 22, + 12, 0, 255, 4, 128, 143, 224, 73, 0, 25, 0, 47, 192, 9, 0, 9, + 0, 47, 192, 73, 0, 137, 0, 15, 224, 11, 11, 22, 12, 0, 255, 16, + 0, 63, 128, 81, 0, 14, 0, 49, 128, 192, 96, 63, 128, 36, 128, 63, + 128, 36, 128, 63, 128, 11, 11, 22, 12, 0, 255, 34, 128, 250, 64, 7, + 224, 250, 128, 138, 128, 138, 128, 250, 128, 34, 128, 178, 128, 170, 160, 100, + 224, 11, 11, 22, 12, 0, 255, 34, 32, 71, 64, 146, 128, 239, 224, 34, + 0, 71, 192, 236, 64, 7, 192, 52, 64, 199, 192, 4, 64, 11, 11, 22, + 12, 0, 255, 8, 0, 15, 192, 8, 0, 8, 0, 255, 224, 8, 0, 14, + 0, 9, 128, 8, 64, 8, 0, 8, 0, 10, 11, 22, 12, 0, 255, 255, + 128, 0, 128, 0, 128, 128, 128, 128, 128, 255, 128, 128, 0, 128, 0, 128, + 64, 128, 64, 127, 192, 11, 11, 22, 12, 0, 255, 71, 192, 65, 0, 239, + 224, 65, 0, 69, 0, 105, 96, 201, 32, 77, 96, 73, 32, 79, 224, 200, + 32, 11, 11, 22, 12, 0, 255, 8, 0, 4, 0, 4, 0, 10, 0, 10, + 0, 10, 0, 17, 0, 17, 0, 32, 128, 64, 64, 128, 32, 11, 11, 22, + 12, 0, 255, 34, 64, 34, 0, 247, 224, 34, 0, 35, 224, 53, 32, 229, + 32, 37, 64, 40, 128, 41, 64, 114, 32, 11, 10, 20, 12, 0, 0, 68, + 64, 68, 64, 68, 64, 127, 192, 4, 0, 4, 0, 132, 32, 132, 32, 132, + 32, 255, 224, 11, 11, 22, 12, 0, 255, 4, 0, 0, 0, 127, 192, 4, + 0, 4, 0, 4, 0, 127, 192, 4, 0, 4, 0, 4, 0, 255, 224, 11, + 11, 22, 12, 0, 255, 255, 224, 17, 0, 1, 192, 254, 0, 72, 128, 37, + 0, 4, 0, 255, 224, 21, 0, 36, 128, 196, 96, 11, 11, 22, 12, 0, + 255, 17, 0, 127, 192, 68, 64, 127, 192, 68, 64, 127, 192, 4, 0, 255, + 224, 4, 0, 4, 0, 4, 0, 9, 11, 22, 12, 0, 255, 16, 0, 255, + 128, 128, 128, 128, 128, 255, 128, 128, 128, 128, 128, 255, 128, 128, 128, 128, + 128, 255, 128, 11, 11, 22, 12, 0, 255, 113, 0, 1, 0, 3, 224, 249, + 32, 33, 32, 65, 32, 81, 32, 137, 32, 250, 32, 2, 32, 4, 192, 11, + 11, 22, 12, 0, 255, 127, 192, 17, 0, 17, 0, 17, 0, 17, 0, 255, + 224, 17, 0, 17, 0, 33, 0, 33, 0, 65, 0, 11, 11, 22, 12, 0, + 255, 33, 0, 34, 0, 244, 64, 87, 224, 80, 32, 87, 192, 148, 64, 84, + 64, 36, 64, 87, 192, 148, 64, 11, 11, 22, 12, 0, 255, 17, 0, 10, + 0, 127, 192, 4, 0, 4, 0, 255, 224, 4, 0, 10, 0, 17, 0, 32, + 128, 192, 96, 10, 11, 22, 12, 0, 255, 95, 192, 0, 64, 132, 64, 132, + 64, 191, 64, 132, 64, 140, 64, 148, 64, 164, 64, 140, 64, 129, 192, 11, + 11, 22, 12, 0, 255, 36, 0, 39, 192, 36, 0, 36, 0, 255, 224, 0, + 0, 20, 64, 36, 128, 71, 0, 12, 0, 112, 0, 11, 11, 22, 12, 0, + 255, 36, 128, 4, 128, 15, 192, 228, 128, 36, 128, 63, 224, 36, 128, 36, + 128, 40, 128, 80, 0, 143, 224, 11, 11, 22, 12, 0, 255, 8, 0, 8, + 0, 255, 128, 136, 128, 136, 128, 255, 128, 136, 128, 136, 128, 255, 160, 136, + 32, 7, 224, 11, 11, 22, 12, 0, 255, 39, 128, 36, 128, 244, 128, 36, + 128, 116, 128, 108, 128, 164, 128, 36, 128, 36, 160, 40, 160, 48, 96, 10, + 11, 22, 12, 0, 255, 255, 192, 128, 64, 128, 64, 158, 64, 146, 64, 146, + 64, 158, 64, 128, 64, 128, 64, 255, 192, 128, 64, 11, 11, 22, 12, 0, + 255, 127, 192, 68, 0, 95, 192, 80, 64, 95, 192, 80, 64, 95, 192, 66, + 0, 74, 128, 82, 64, 166, 32, 11, 11, 22, 12, 0, 255, 4, 0, 7, + 224, 4, 0, 127, 192, 64, 64, 64, 64, 64, 64, 127, 192, 0, 0, 82, + 64, 137, 32, 11, 11, 22, 12, 0, 255, 71, 128, 36, 128, 4, 128, 4, + 128, 232, 96, 32, 0, 47, 192, 36, 64, 34, 128, 49, 0, 38, 192, 11, + 11, 22, 12, 0, 255, 127, 192, 74, 64, 127, 192, 4, 0, 255, 224, 4, + 0, 63, 128, 32, 128, 36, 128, 36, 128, 255, 224, 11, 11, 22, 12, 0, + 255, 34, 0, 79, 224, 72, 32, 79, 224, 200, 0, 79, 224, 74, 160, 90, + 160, 111, 224, 74, 160, 72, 96, 11, 11, 22, 12, 0, 255, 243, 192, 36, + 64, 42, 128, 241, 0, 34, 128, 101, 224, 114, 32, 165, 64, 32, 128, 35, + 0, 44, 0, 11, 11, 22, 12, 0, 255, 4, 0, 255, 224, 128, 32, 0, + 0, 255, 224, 4, 0, 36, 0, 39, 192, 36, 0, 84, 0, 143, 224, 11, + 11, 22, 12, 0, 255, 115, 224, 16, 128, 81, 0, 35, 224, 250, 32, 42, + 160, 34, 160, 34, 160, 32, 128, 33, 64, 98, 32, 11, 11, 22, 12, 0, + 255, 34, 0, 247, 128, 34, 128, 54, 128, 226, 160, 37, 160, 36, 96, 104, + 32, 0, 0, 82, 64, 137, 32, 11, 11, 22, 12, 0, 255, 115, 192, 66, + 0, 66, 0, 123, 224, 74, 64, 74, 64, 122, 64, 74, 64, 66, 64, 68, + 64, 136, 64, 11, 11, 22, 12, 0, 255, 8, 0, 255, 224, 8, 0, 31, + 192, 48, 64, 95, 192, 144, 64, 31, 192, 16, 64, 16, 64, 16, 192, 11, + 11, 22, 12, 0, 255, 2, 0, 127, 224, 66, 0, 66, 0, 95, 192, 66, + 0, 71, 0, 74, 128, 82, 64, 98, 32, 130, 0, 11, 11, 22, 12, 0, + 255, 243, 192, 150, 64, 145, 128, 166, 96, 161, 0, 151, 192, 145, 0, 149, + 0, 231, 224, 129, 0, 129, 0, 11, 11, 22, 12, 0, 255, 15, 128, 136, + 128, 79, 128, 8, 128, 143, 128, 64, 0, 31, 192, 53, 64, 85, 64, 149, + 64, 63, 224, 11, 11, 22, 12, 0, 255, 39, 224, 32, 128, 248, 128, 32, + 128, 32, 128, 56, 128, 224, 128, 32, 128, 32, 128, 32, 128, 97, 128, 11, + 11, 22, 12, 0, 255, 31, 224, 145, 0, 87, 192, 20, 64, 23, 192, 148, + 64, 87, 192, 17, 0, 85, 64, 153, 32, 35, 0, 11, 11, 22, 12, 0, + 255, 32, 128, 39, 224, 242, 64, 33, 128, 34, 64, 52, 32, 226, 64, 34, + 64, 34, 64, 34, 64, 100, 64, 11, 11, 22, 12, 0, 255, 65, 0, 65, + 0, 79, 224, 233, 32, 73, 32, 73, 32, 111, 224, 201, 32, 73, 32, 73, + 32, 207, 224, 11, 11, 22, 12, 0, 255, 33, 0, 241, 0, 79, 224, 169, + 32, 249, 32, 47, 224, 57, 32, 233, 32, 41, 32, 47, 224, 40, 32, 11, + 11, 22, 12, 0, 255, 143, 224, 73, 32, 9, 32, 203, 160, 73, 32, 79, + 224, 72, 32, 75, 160, 74, 160, 107, 160, 80, 224, 11, 11, 22, 12, 0, + 255, 127, 192, 4, 0, 68, 64, 36, 64, 36, 128, 4, 0, 255, 224, 4, + 0, 4, 0, 4, 0, 4, 0, 11, 11, 22, 12, 0, 255, 130, 0, 66, + 0, 31, 224, 194, 0, 95, 192, 82, 64, 95, 192, 71, 0, 74, 128, 82, + 64, 191, 224, 11, 11, 22, 12, 0, 255, 4, 0, 127, 224, 72, 128, 127, + 224, 72, 128, 79, 128, 64, 0, 95, 192, 72, 64, 71, 128, 152, 96, 11, + 11, 22, 12, 0, 255, 1, 0, 239, 224, 161, 0, 164, 64, 175, 224, 164, + 64, 175, 224, 169, 32, 233, 32, 2, 128, 12, 96, 11, 11, 22, 12, 0, + 255, 20, 192, 246, 160, 188, 96, 167, 128, 168, 128, 191, 224, 169, 32, 239, + 224, 9, 32, 15, 224, 9, 32, 11, 11, 22, 12, 0, 255, 127, 128, 64, + 128, 66, 128, 98, 128, 84, 128, 72, 128, 72, 128, 84, 160, 98, 160, 64, + 96, 128, 32, 11, 11, 22, 12, 0, 255, 4, 0, 127, 224, 64, 32, 127, + 224, 64, 0, 125, 224, 84, 32, 76, 160, 84, 96, 100, 160, 141, 96, 11, + 11, 22, 12, 0, 255, 130, 0, 95, 224, 4, 0, 8, 64, 159, 224, 64, + 32, 10, 128, 10, 128, 74, 160, 146, 160, 34, 96, 11, 11, 22, 12, 0, + 255, 65, 0, 79, 224, 232, 32, 66, 128, 68, 64, 104, 32, 199, 192, 65, + 0, 65, 0, 65, 0, 207, 224, 11, 11, 22, 12, 0, 255, 80, 32, 125, + 32, 145, 32, 255, 32, 17, 32, 125, 32, 85, 32, 85, 32, 84, 32, 92, + 32, 16, 224, 11, 11, 22, 12, 0, 255, 63, 128, 32, 128, 63, 128, 32, + 128, 255, 224, 72, 0, 123, 192, 73, 64, 121, 64, 72, 128, 251, 96, 11, + 11, 22, 12, 0, 255, 4, 0, 4, 0, 4, 0, 36, 128, 36, 64, 68, + 64, 68, 32, 132, 32, 4, 0, 4, 0, 28, 0, 11, 11, 22, 12, 0, + 255, 4, 0, 4, 0, 4, 0, 255, 224, 4, 0, 10, 0, 10, 0, 17, + 0, 17, 0, 32, 128, 192, 96, 9, 10, 20, 10, 0, 0, 136, 128, 73, + 0, 8, 0, 255, 128, 0, 128, 0, 128, 127, 128, 0, 128, 0, 128, 255, + 128, 11, 11, 22, 12, 0, 255, 33, 0, 18, 0, 255, 224, 0, 0, 120, + 128, 74, 128, 122, 128, 74, 128, 122, 128, 72, 128, 89, 128, 11, 11, 22, + 12, 0, 255, 39, 192, 0, 0, 0, 0, 239, 224, 33, 0, 34, 0, 36, + 64, 47, 224, 32, 32, 80, 0, 143, 224, 11, 11, 22, 12, 0, 255, 32, + 128, 39, 0, 249, 0, 33, 192, 119, 0, 33, 0, 249, 224, 39, 0, 113, + 32, 169, 32, 32, 224, 11, 11, 22, 12, 0, 255, 16, 64, 16, 64, 253, + 224, 16, 64, 56, 192, 53, 64, 82, 64, 148, 64, 16, 64, 16, 64, 16, + 192, 11, 11, 22, 12, 0, 255, 0, 64, 248, 64, 11, 224, 8, 64, 136, + 64, 82, 64, 81, 64, 33, 64, 80, 64, 72, 64, 137, 192, 10, 11, 22, + 12, 0, 255, 132, 0, 132, 64, 132, 128, 245, 0, 134, 0, 132, 0, 132, + 0, 148, 0, 164, 64, 196, 64, 131, 192, 11, 11, 22, 12, 0, 255, 17, + 32, 125, 0, 17, 0, 255, 224, 41, 0, 253, 64, 73, 64, 124, 128, 8, + 160, 253, 96, 10, 32, 11, 11, 22, 12, 0, 255, 23, 192, 36, 64, 36, + 64, 103, 192, 161, 0, 47, 224, 33, 0, 35, 128, 37, 64, 41, 32, 33, + 0, 11, 11, 22, 12, 0, 255, 8, 0, 255, 224, 16, 0, 39, 192, 32, + 128, 97, 0, 175, 224, 33, 0, 33, 0, 33, 0, 35, 0, 11, 11, 22, + 12, 0, 255, 36, 0, 47, 224, 180, 0, 164, 128, 164, 160, 170, 192, 42, + 128, 40, 128, 41, 64, 50, 64, 36, 32, 11, 11, 22, 12, 0, 255, 127, + 224, 128, 0, 63, 192, 32, 64, 63, 192, 16, 0, 31, 192, 16, 64, 40, + 128, 71, 0, 56, 224, 11, 11, 22, 12, 0, 255, 127, 224, 64, 0, 64, + 0, 64, 0, 64, 0, 64, 0, 64, 0, 64, 0, 64, 0, 64, 0, 128, + 0, 11, 11, 22, 12, 0, 255, 255, 224, 4, 0, 127, 192, 68, 64, 127, + 192, 68, 64, 127, 192, 68, 0, 36, 0, 24, 0, 231, 224, 11, 11, 22, + 12, 0, 255, 17, 224, 253, 0, 69, 0, 41, 224, 253, 64, 17, 64, 125, + 64, 17, 64, 85, 64, 146, 64, 52, 64, 11, 11, 22, 12, 0, 255, 33, + 0, 95, 224, 64, 0, 207, 192, 64, 0, 79, 192, 64, 0, 79, 192, 72, + 64, 79, 192, 72, 64, 11, 11, 22, 12, 0, 255, 4, 0, 127, 192, 64, + 64, 127, 192, 64, 64, 127, 192, 64, 64, 127, 192, 4, 64, 82, 32, 191, + 160, 11, 11, 22, 12, 0, 255, 127, 192, 68, 64, 127, 192, 68, 64, 127, + 192, 4, 0, 27, 0, 224, 224, 17, 0, 17, 0, 97, 0, 11, 11, 22, + 12, 0, 255, 255, 224, 4, 0, 8, 0, 127, 224, 73, 32, 79, 32, 73, + 32, 79, 32, 73, 32, 73, 32, 127, 224, 11, 11, 22, 12, 0, 255, 253, + 224, 86, 64, 121, 64, 56, 128, 85, 64, 146, 32, 255, 224, 4, 0, 39, + 192, 36, 0, 255, 224, 11, 11, 22, 12, 0, 255, 251, 128, 82, 0, 123, + 224, 18, 64, 250, 64, 20, 64, 63, 128, 32, 128, 63, 128, 32, 128, 63, + 128, 11, 11, 22, 12, 0, 255, 31, 224, 32, 0, 39, 192, 100, 64, 167, + 192, 32, 0, 47, 224, 40, 32, 39, 192, 33, 0, 35, 0, 11, 11, 22, + 12, 0, 255, 243, 224, 130, 32, 130, 32, 250, 32, 130, 32, 130, 32, 138, + 32, 178, 32, 194, 224, 2, 0, 2, 0, 11, 11, 22, 12, 0, 255, 36, + 128, 70, 160, 149, 192, 228, 128, 39, 224, 68, 128, 245, 192, 6, 160, 52, + 128, 196, 128, 7, 224, 11, 11, 22, 12, 0, 255, 39, 192, 65, 0, 135, + 224, 224, 32, 34, 128, 69, 128, 242, 128, 15, 224, 48, 128, 193, 64, 2, + 32, 11, 11, 22, 12, 0, 255, 2, 0, 2, 0, 34, 0, 35, 192, 34, + 0, 34, 0, 34, 0, 34, 0, 34, 0, 34, 0, 255, 224, 9, 11, 22, + 12, 0, 255, 8, 0, 8, 0, 255, 128, 136, 128, 136, 128, 136, 128, 255, + 128, 136, 128, 136, 128, 136, 128, 255, 128, 11, 11, 22, 12, 0, 255, 33, + 0, 83, 160, 65, 0, 247, 224, 81, 0, 83, 192, 86, 64, 83, 192, 90, + 64, 83, 192, 66, 64, 11, 11, 22, 12, 0, 255, 127, 192, 4, 0, 4, + 0, 4, 0, 255, 224, 10, 0, 10, 0, 18, 0, 34, 32, 66, 32, 129, + 224, 11, 11, 22, 12, 0, 255, 17, 0, 33, 0, 47, 224, 97, 0, 163, + 128, 35, 128, 37, 64, 37, 64, 41, 32, 33, 0, 33, 0, 11, 11, 22, + 12, 0, 255, 247, 224, 148, 32, 244, 32, 151, 224, 148, 128, 244, 128, 151, + 224, 148, 128, 244, 160, 150, 96, 4, 32, 11, 11, 22, 12, 0, 255, 123, + 224, 148, 128, 4, 0, 127, 192, 4, 0, 255, 224, 1, 0, 255, 224, 33, + 0, 17, 0, 7, 0, 11, 11, 22, 12, 0, 255, 33, 0, 71, 192, 145, + 0, 47, 224, 96, 128, 175, 224, 32, 128, 36, 128, 34, 128, 32, 128, 35, + 128, 11, 11, 22, 12, 0, 255, 39, 192, 36, 64, 247, 192, 46, 224, 42, + 160, 62, 224, 225, 0, 47, 224, 35, 128, 37, 64, 105, 32, 11, 11, 22, + 12, 0, 255, 20, 0, 39, 224, 42, 0, 98, 0, 163, 192, 34, 0, 34, + 0, 35, 224, 34, 0, 34, 0, 34, 0 +}; diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/dogm_font_data_ISO10646_Greek.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/dogm_font_data_ISO10646_Greek.h new file mode 100644 index 00000000..0abb08d9 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/dogm_font_data_ISO10646_Greek.h @@ -0,0 +1,206 @@ +/** + * 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 . + * + */ + +/* + Fontname: ISO10646_4_Greek + Copyright: A. Hardtung, public domain + Capital A Height: 7, '1' Height: 7 + Calculated Max Values w= 5 h=10 x= 2 y= 6 dx= 6 dy= 0 ascent= 8 len=10 + 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 = 7 descent=-1 + X Font ascent = 7 descent=-1 + Max Font ascent = 8 descent=-2 +*/ +#include +const u8g_fntpgm_uint8_t ISO10646_Greek_5x7[2728] U8G_SECTION(".progmem.ISO10646_Greek_5x7") = { + 0,6,9,0,254,7,1,145,3,32,32,255,255,8,254,7, + 255,0,0,0,6,0,0,1,7,7,6,2,0,128,128,128, + 128,128,0,128,3,2,2,6,1,5,160,160,5,7,7,6, + 0,0,80,80,248,80,248,80,80,5,7,7,6,0,0,32, + 120,160,112,40,240,32,5,7,7,6,0,0,192,200,16,32, + 64,152,24,5,7,7,6,0,0,96,144,160,64,168,144,104, + 2,3,3,6,1,4,192,64,128,3,7,7,6,1,0,32, + 64,128,128,128,64,32,3,7,7,6,1,0,128,64,32,32, + 32,64,128,5,5,5,6,0,1,32,168,112,168,32,5,5, + 5,6,0,1,32,32,248,32,32,2,3,3,6,2,255,192, + 64,128,5,1,1,6,0,3,248,2,2,2,6,2,0,192, + 192,5,5,5,6,0,1,8,16,32,64,128,5,7,7,6, + 0,0,112,136,152,168,200,136,112,3,7,7,6,1,0,64, + 192,64,64,64,64,224,5,7,7,6,0,0,112,136,8,112, + 128,128,248,5,7,7,6,0,0,248,16,32,16,8,8,240, + 5,7,7,6,0,0,16,48,80,144,248,16,16,5,7,7, + 6,0,0,248,128,240,8,8,136,112,5,7,7,6,0,0, + 48,64,128,240,136,136,112,5,7,7,6,0,0,248,8,16, + 32,32,32,32,5,7,7,6,0,0,112,136,136,112,136,136, + 112,5,7,7,6,0,0,112,136,136,120,8,16,96,2,5, + 5,6,2,0,192,192,0,192,192,2,6,6,6,2,255,192, + 192,0,192,64,128,4,7,7,6,0,0,16,32,64,128,64, + 32,16,5,3,3,6,0,2,248,0,248,4,7,7,6,1, + 0,128,64,32,16,32,64,128,5,7,7,6,0,0,112,136, + 8,16,32,0,32,5,6,6,6,0,0,112,136,8,104,168, + 112,5,7,7,6,0,0,112,136,136,248,136,136,136,5,7, + 7,6,0,0,240,136,136,240,136,136,240,5,7,7,6,0, + 0,112,136,128,128,128,136,112,5,7,7,6,0,0,224,144, + 136,136,136,144,224,5,7,7,6,0,0,248,128,128,240,128, + 128,248,5,7,7,6,0,0,248,128,128,240,128,128,128,5, + 7,7,6,0,0,112,136,128,184,136,136,112,5,7,7,6, + 0,0,136,136,136,248,136,136,136,1,7,7,6,2,0,128, + 128,128,128,128,128,128,5,7,7,6,0,0,56,16,16,16, + 16,144,96,5,7,7,6,0,0,136,144,160,192,160,144,136, + 5,7,7,6,0,0,128,128,128,128,128,128,248,5,7,7, + 6,0,0,136,216,168,136,136,136,136,5,7,7,6,0,0, + 136,136,200,168,152,136,136,5,7,7,6,0,0,112,136,136, + 136,136,136,112,5,7,7,6,0,0,240,136,136,240,128,128, + 128,5,7,7,6,0,0,112,136,136,136,168,144,104,5,7, + 7,6,0,0,240,136,136,240,160,144,136,5,7,7,6,0, + 0,120,128,128,112,8,8,240,5,7,7,6,0,0,248,32, + 32,32,32,32,32,5,7,7,6,0,0,136,136,136,136,136, + 136,112,5,7,7,6,0,0,136,136,136,136,136,80,32,5, + 7,7,6,0,0,136,136,136,136,136,168,80,5,7,7,6, + 0,0,136,136,80,32,80,136,136,5,7,7,6,0,0,136, + 136,136,80,32,32,32,5,7,7,6,0,0,248,8,16,32, + 64,128,248,3,7,7,6,1,0,224,128,128,128,128,128,224, + 5,5,5,6,0,1,128,64,32,16,8,3,7,7,6,1, + 0,224,32,32,32,32,32,224,5,3,3,6,0,4,32,80, + 136,5,1,1,6,0,0,248,2,2,2,6,2,5,128,64, + 5,5,5,6,0,0,112,8,120,136,120,5,7,7,6,0, + 0,128,128,176,200,136,136,240,5,5,5,6,0,0,112,128, + 128,136,112,5,7,7,6,0,0,8,8,104,152,136,136,120, + 5,5,5,6,0,0,112,136,248,128,112,5,7,7,6,0, + 0,48,72,224,64,64,64,64,5,6,6,6,0,255,112,136, + 136,120,8,112,5,7,7,6,0,0,128,128,176,200,136,136, + 136,1,7,7,6,2,0,128,0,128,128,128,128,128,3,8, + 8,6,1,255,32,0,32,32,32,32,160,64,4,7,7,6, + 0,0,128,128,144,160,192,160,144,3,7,7,6,1,0,192, + 64,64,64,64,64,224,5,5,5,6,0,0,208,168,168,168, + 168,5,5,5,6,0,0,176,200,136,136,136,5,5,5,6, + 0,0,112,136,136,136,112,5,6,6,6,0,255,240,136,136, + 240,128,128,5,6,6,6,0,255,120,136,136,120,8,8,5, + 5,5,6,0,0,176,200,128,128,128,5,5,5,6,0,0, + 112,128,112,8,240,5,7,7,6,0,0,64,64,224,64,64, + 72,48,5,5,5,6,0,0,136,136,136,152,104,5,5,5, + 6,0,0,136,136,136,80,32,5,5,5,6,0,0,136,136, + 168,168,80,5,5,5,6,0,0,136,80,32,80,136,5,6, + 6,6,0,255,136,136,136,120,8,112,5,5,5,6,0,0, + 248,16,32,64,248,3,7,7,6,1,0,32,64,64,128,64, + 64,32,1,7,7,6,2,0,128,128,128,128,128,128,128,3, + 7,7,6,1,0,128,64,64,32,64,64,128,5,2,2,6, + 0,3,104,144,0,0,0,6,0,0,0,0,0,6,0,0, + 0,0,0,6,0,0,0,0,0,6,0,0,0,0,0,6, + 0,0,2,2,2,6,1,6,64,128,3,3,3,6,1,5, + 32,64,160,5,8,8,6,0,0,64,160,80,80,136,248,136, + 136,2,2,2,6,1,2,192,192,5,8,8,6,0,0,64, + 128,248,128,240,128,128,248,5,8,8,6,0,0,64,128,136, + 136,248,136,136,136,4,8,8,6,0,0,64,128,112,32,32, + 32,32,112,0,0,0,6,0,0,5,8,8,6,0,0,64, + 128,112,136,136,136,136,112,0,0,0,6,0,0,5,8,8, + 6,0,0,64,128,8,136,112,32,32,32,5,8,8,6,0, + 0,64,128,112,136,136,136,80,216,3,8,8,6,1,0,32, + 64,160,0,64,64,64,32,5,7,7,6,0,0,32,80,136, + 136,248,136,136,5,7,7,6,0,0,240,72,72,112,72,72, + 240,5,7,7,6,0,0,248,128,128,128,128,128,128,5,6, + 6,6,0,0,32,80,80,136,136,248,5,7,7,6,0,0, + 248,128,128,240,128,128,248,5,7,7,6,0,0,248,8,16, + 32,64,128,248,5,7,7,6,0,0,136,136,136,248,136,136, + 136,5,7,7,6,0,0,112,136,136,168,136,136,112,3,7, + 7,6,1,0,224,64,64,64,64,64,224,5,7,7,6,0, + 0,136,144,160,192,160,144,136,5,7,7,6,0,0,32,80, + 136,136,136,136,136,5,7,7,6,0,0,136,216,168,168,136, + 136,136,5,7,7,6,0,0,136,200,200,168,152,152,136,5, + 7,7,6,0,0,248,0,0,112,0,0,248,5,7,7,6, + 0,0,112,136,136,136,136,136,112,5,7,7,6,0,0,248, + 80,80,80,80,80,80,5,7,7,6,0,0,240,136,136,240, + 128,128,128,0,0,0,6,0,0,5,7,7,6,0,0,248, + 128,64,32,64,128,248,5,7,7,6,0,0,248,32,32,32, + 32,32,32,5,7,7,6,0,0,136,136,80,32,32,32,32, + 5,7,7,6,0,0,112,32,112,168,112,32,112,5,7,7, + 6,0,0,136,136,80,32,80,136,136,5,7,7,6,0,0, + 168,168,168,168,112,32,32,5,6,6,6,0,0,112,136,136, + 80,80,216,3,8,8,6,1,0,160,0,224,64,64,64,64, + 224,5,8,8,6,0,0,80,0,136,136,136,80,32,32,5, + 8,8,6,0,0,32,64,8,104,152,144,144,104,5,8,8, + 6,0,0,32,64,0,112,136,224,136,112,5,10,10,6,0, + 254,32,64,0,112,136,136,136,136,8,8,2,8,8,6,1, + 0,64,128,0,128,128,128,128,64,5,8,8,6,0,0,16, + 32,80,0,136,136,136,112,5,6,6,6,0,0,8,104,152, + 144,144,104,4,7,7,6,0,254,96,144,240,144,224,128,128, + 5,6,6,6,0,255,136,72,80,32,32,64,5,6,6,6, + 0,0,48,64,112,136,136,112,5,5,5,6,0,0,112,136, + 224,136,112,5,9,9,6,0,254,128,112,64,128,128,128,112, + 8,112,5,7,7,6,0,254,184,200,136,136,136,8,8,5, + 5,5,6,0,0,112,136,248,136,112,3,5,5,6,1,0, + 128,128,128,128,96,4,5,5,6,0,0,144,160,192,160,144, + 5,6,6,6,0,0,64,32,32,80,80,136,5,7,7,6, + 0,254,136,136,136,216,168,128,128,5,5,5,6,0,0,136, + 136,80,96,32,5,10,10,6,0,254,128,224,128,112,32,64, + 128,112,8,112,5,5,5,6,0,0,112,136,136,136,112,5, + 5,5,6,0,0,248,80,80,80,80,5,7,7,6,0,254, + 112,136,136,200,176,128,128,5,7,7,6,0,254,48,64,128, + 64,48,8,112,5,5,5,6,0,0,104,144,144,144,96,4, + 5,5,6,0,0,240,64,64,64,48,5,5,5,6,0,0, + 136,136,144,144,224,5,8,8,6,0,254,48,168,168,168,168, + 112,32,32,5,6,6,6,0,255,136,80,32,32,80,136,5, + 7,7,6,0,254,168,168,168,168,112,32,32,5,5,5,6, + 0,0,80,136,136,168,112,4,7,7,6,0,0,160,0,64, + 64,64,64,48,5,7,7,6,0,0,80,0,136,136,144,144, + 224,4,8,8,6,0,0,32,64,0,96,144,144,144,96,5, + 8,8,6,0,0,32,64,0,136,136,144,144,96,5,8,8, + 6,0,0,32,64,0,80,136,136,168,112,5,7,7,6,0, + 255,144,160,192,160,144,136,16,5,8,8,6,0,0,96,144, + 160,128,240,136,136,112,5,7,7,6,0,0,112,80,56,144, + 144,144,96,5,6,6,6,0,0,152,80,32,32,32,32,5, + 8,8,6,0,0,64,128,152,80,32,32,32,32,5,8,8, + 6,0,0,80,0,152,80,32,32,32,32,5,7,7,6,0, + 255,48,168,168,168,168,112,32,5,5,5,6,0,0,248,80, + 80,80,88,5,6,6,6,0,255,136,80,112,80,136,16,5, + 7,7,6,0,255,112,136,136,136,112,32,112,5,6,6,6, + 0,255,112,136,136,112,32,112,5,6,6,6,0,0,112,136, + 128,112,32,112,5,7,7,6,0,254,8,112,128,128,112,16, + 96,5,6,6,6,0,0,248,128,128,240,128,128,4,5,5, + 6,0,0,240,128,224,128,128,5,6,6,6,0,0,248,0, + 0,112,0,248,4,5,5,6,0,0,64,128,240,16,32,5, + 7,7,6,0,0,224,80,40,40,8,8,16,5,7,7,6, + 0,0,192,32,80,40,8,8,8,5,8,8,6,0,254,168, + 168,168,168,168,88,8,112,5,7,7,6,0,254,168,168,168, + 168,88,8,112,5,6,6,6,0,0,104,136,136,120,8,8, + 5,6,6,6,0,255,104,136,136,120,8,8,4,8,8,6, + 0,254,128,224,144,144,144,144,32,192,5,5,5,6,0,0, + 104,144,112,16,224,5,6,6,6,0,0,96,144,16,96,136, + 112,4,6,6,6,0,0,96,144,16,96,128,112,5,6,6, + 6,0,0,136,80,32,80,136,248,5,5,5,6,0,0,136, + 80,32,80,112,5,6,6,6,0,0,120,128,240,136,136,112, + 4,5,5,6,0,0,240,128,224,144,96,3,6,6,6,1, + 0,64,224,64,64,64,64,3,6,6,6,1,255,64,224,64, + 64,64,128,5,5,5,6,0,0,136,80,112,80,136,5,7, + 7,6,0,254,112,136,136,136,240,128,112,4,5,5,6,0, + 0,112,128,128,128,112,2,8,8,6,1,255,64,0,192,64, + 64,64,64,128,5,7,7,6,0,0,112,136,136,248,136,136, + 112,4,5,5,6,0,0,112,128,224,128,112,4,5,5,6, + 0,0,224,16,112,16,224,5,7,7,6,0,0,128,240,136, + 136,136,240,128,4,7,7,6,0,255,128,224,144,144,144,224, + 128,5,6,6,6,0,0,112,136,128,128,136,112,5,6,6, + 6,0,0,136,216,168,136,136,136,5,7,7,6,0,254,136, + 216,168,136,136,128,128,5,8,8,6,0,254,112,136,136,136, + 112,64,224,64,5,6,6,6,0,0,112,136,8,8,136,112, + 5,6,6,6,0,0,112,136,160,128,136,112,5,6,6,6, + 0,0,112,136,40,8,136,112}; diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/dogm_font_data_ISO10646_Kana.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/dogm_font_data_ISO10646_Kana.h new file mode 100644 index 00000000..69683740 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/dogm_font_data_ISO10646_Kana.h @@ -0,0 +1,192 @@ +/** + * 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 . + * + */ + +/** + Fontname: ISO10646_Kana + Copyright: A. Hardtung, public domain + Capital A Height: 7, '1' Height: 7 + Calculated Max Values w= 5 h= 8 x= 2 y= 5 dx= 6 dy= 0 ascent= 8 len= 8 + Font Bounding box w= 6 h= 9 x= 0 y=-2 + Calculated Min Values x= 0 y=-1 dx= 0 dy= 0 + Pure Font ascent = 7 descent=-1 + X Font ascent = 7 descent=-1 + Max Font ascent = 8 descent=-1 +*/ +#include +const u8g_fntpgm_uint8_t ISO10646_Kana_5x7[2482] U8G_SECTION(".progmem.ISO10646_Kana_5x7") = { + 0, 6, 9, 0, 254, 7, 1, 145, 3, 32, 32, 255, 255, 8, 255, 7, + 255, 0, 0, 0, 6, 0, 0, 1, 7, 7, 6, 2, 0, 128, 128, 128, + 128, 128, 0, 128, 3, 2, 2, 6, 1, 5, 160, 160, 5, 7, 7, 6, + 0, 0, 80, 80, 248, 80, 248, 80, 80, 5, 7, 7, 6, 0, 0, 32, + 120, 160, 112, 40, 240, 32, 5, 7, 7, 6, 0, 0, 192, 200, 16, 32, + 64, 152, 24, 5, 7, 7, 6, 0, 0, 96, 144, 160, 64, 168, 144, 104, + 2, 3, 3, 6, 1, 4, 192, 64, 128, 3, 7, 7, 6, 1, 0, 32, + 64, 128, 128, 128, 64, 32, 3, 7, 7, 6, 1, 0, 128, 64, 32, 32, + 32, 64, 128, 5, 5, 5, 6, 0, 1, 32, 168, 112, 168, 32, 5, 5, + 5, 6, 0, 1, 32, 32, 248, 32, 32, 2, 3, 3, 6, 2, 255, 192, + 64, 128, 5, 1, 1, 6, 0, 3, 248, 2, 2, 2, 6, 2, 0, 192, + 192, 5, 5, 5, 6, 0, 1, 8, 16, 32, 64, 128, 5, 7, 7, 6, + 0, 0, 112, 136, 152, 168, 200, 136, 112, 3, 7, 7, 6, 1, 0, 64, + 192, 64, 64, 64, 64, 224, 5, 7, 7, 6, 0, 0, 112, 136, 8, 112, + 128, 128, 248, 5, 7, 7, 6, 0, 0, 248, 16, 32, 16, 8, 8, 240, + 5, 7, 7, 6, 0, 0, 16, 48, 80, 144, 248, 16, 16, 5, 7, 7, + 6, 0, 0, 248, 128, 240, 8, 8, 136, 112, 5, 7, 7, 6, 0, 0, + 48, 64, 128, 240, 136, 136, 112, 5, 7, 7, 6, 0, 0, 248, 8, 16, + 32, 32, 32, 32, 5, 7, 7, 6, 0, 0, 112, 136, 136, 112, 136, 136, + 112, 5, 7, 7, 6, 0, 0, 112, 136, 136, 120, 8, 16, 96, 2, 5, + 5, 6, 2, 0, 192, 192, 0, 192, 192, 2, 6, 6, 6, 2, 255, 192, + 192, 0, 192, 64, 128, 4, 7, 7, 6, 0, 0, 16, 32, 64, 128, 64, + 32, 16, 5, 3, 3, 6, 0, 2, 248, 0, 248, 4, 7, 7, 6, 1, + 0, 128, 64, 32, 16, 32, 64, 128, 5, 7, 7, 6, 0, 0, 112, 136, + 8, 16, 32, 0, 32, 5, 6, 6, 6, 0, 0, 112, 136, 8, 104, 168, + 112, 5, 7, 7, 6, 0, 0, 112, 136, 136, 248, 136, 136, 136, 5, 7, + 7, 6, 0, 0, 240, 136, 136, 240, 136, 136, 240, 5, 7, 7, 6, 0, + 0, 112, 136, 128, 128, 128, 136, 112, 5, 7, 7, 6, 0, 0, 224, 144, + 136, 136, 136, 144, 224, 5, 7, 7, 6, 0, 0, 248, 128, 128, 240, 128, + 128, 248, 5, 7, 7, 6, 0, 0, 248, 128, 128, 240, 128, 128, 128, 5, + 7, 7, 6, 0, 0, 112, 136, 128, 184, 136, 136, 112, 5, 7, 7, 6, + 0, 0, 136, 136, 136, 248, 136, 136, 136, 1, 7, 7, 6, 2, 0, 128, + 128, 128, 128, 128, 128, 128, 5, 7, 7, 6, 0, 0, 56, 16, 16, 16, + 16, 144, 96, 5, 7, 7, 6, 0, 0, 136, 144, 160, 192, 160, 144, 136, + 5, 7, 7, 6, 0, 0, 128, 128, 128, 128, 128, 128, 248, 5, 7, 7, + 6, 0, 0, 136, 216, 168, 136, 136, 136, 136, 5, 7, 7, 6, 0, 0, + 136, 136, 200, 168, 152, 136, 136, 5, 7, 7, 6, 0, 0, 112, 136, 136, + 136, 136, 136, 112, 5, 7, 7, 6, 0, 0, 240, 136, 136, 240, 128, 128, + 128, 5, 7, 7, 6, 0, 0, 112, 136, 136, 136, 168, 144, 104, 5, 7, + 7, 6, 0, 0, 240, 136, 136, 240, 160, 144, 136, 5, 7, 7, 6, 0, + 0, 120, 128, 128, 112, 8, 8, 240, 5, 7, 7, 6, 0, 0, 248, 32, + 32, 32, 32, 32, 32, 5, 7, 7, 6, 0, 0, 136, 136, 136, 136, 136, + 136, 112, 5, 7, 7, 6, 0, 0, 136, 136, 136, 136, 136, 80, 32, 5, + 7, 7, 6, 0, 0, 136, 136, 136, 136, 136, 168, 80, 5, 7, 7, 6, + 0, 0, 136, 136, 80, 32, 80, 136, 136, 5, 7, 7, 6, 0, 0, 136, + 136, 136, 80, 32, 32, 32, 5, 7, 7, 6, 0, 0, 248, 8, 16, 32, + 64, 128, 248, 3, 7, 7, 6, 1, 0, 224, 128, 128, 128, 128, 128, 224, + 5, 5, 5, 6, 0, 1, 128, 64, 32, 16, 8, 3, 7, 7, 6, 1, + 0, 224, 32, 32, 32, 32, 32, 224, 5, 3, 3, 6, 0, 4, 32, 80, + 136, 5, 1, 1, 6, 0, 0, 248, 2, 2, 2, 6, 2, 5, 128, 64, + 5, 5, 5, 6, 0, 0, 112, 8, 120, 136, 120, 5, 7, 7, 6, 0, + 0, 128, 128, 176, 200, 136, 136, 240, 5, 5, 5, 6, 0, 0, 112, 128, + 128, 136, 112, 5, 7, 7, 6, 0, 0, 8, 8, 104, 152, 136, 136, 120, + 5, 5, 5, 6, 0, 0, 112, 136, 248, 128, 112, 5, 7, 7, 6, 0, + 0, 48, 72, 224, 64, 64, 64, 64, 5, 6, 6, 6, 0, 255, 112, 136, + 136, 120, 8, 112, 5, 7, 7, 6, 0, 0, 128, 128, 176, 200, 136, 136, + 136, 1, 7, 7, 6, 2, 0, 128, 0, 128, 128, 128, 128, 128, 3, 8, + 8, 6, 1, 255, 32, 0, 32, 32, 32, 32, 160, 64, 4, 7, 7, 6, + 0, 0, 128, 128, 144, 160, 192, 160, 144, 3, 7, 7, 6, 1, 0, 192, + 64, 64, 64, 64, 64, 224, 5, 5, 5, 6, 0, 0, 208, 168, 168, 168, + 168, 5, 5, 5, 6, 0, 0, 176, 200, 136, 136, 136, 5, 5, 5, 6, + 0, 0, 112, 136, 136, 136, 112, 5, 6, 6, 6, 0, 255, 240, 136, 136, + 240, 128, 128, 5, 6, 6, 6, 0, 255, 120, 136, 136, 120, 8, 8, 5, + 5, 5, 6, 0, 0, 176, 200, 128, 128, 128, 5, 5, 5, 6, 0, 0, + 112, 128, 112, 8, 240, 5, 7, 7, 6, 0, 0, 64, 64, 224, 64, 64, + 72, 48, 5, 5, 5, 6, 0, 0, 136, 136, 136, 152, 104, 5, 5, 5, + 6, 0, 0, 136, 136, 136, 80, 32, 5, 5, 5, 6, 0, 0, 136, 136, + 168, 168, 80, 5, 5, 5, 6, 0, 0, 136, 80, 32, 80, 136, 5, 6, + 6, 6, 0, 255, 136, 136, 136, 120, 8, 112, 5, 5, 5, 6, 0, 0, + 248, 16, 32, 64, 248, 3, 7, 7, 6, 1, 0, 32, 64, 64, 128, 64, + 64, 32, 1, 7, 7, 6, 2, 0, 128, 128, 128, 128, 128, 128, 128, 3, + 7, 7, 6, 1, 0, 128, 64, 64, 32, 64, 64, 128, 5, 2, 2, 6, + 0, 3, 104, 144, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, + 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, + 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, + 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, + 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, + 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, + 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, + 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, + 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, + 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, + 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, + 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, + 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 5, 3, 3, 6, 0, 1, + 248, 0, 248, 4, 4, 4, 6, 0, 0, 240, 16, 96, 64, 5, 6, 6, + 6, 0, 0, 248, 8, 40, 48, 32, 64, 3, 4, 4, 6, 1, 0, 32, + 64, 192, 64, 4, 6, 6, 6, 0, 0, 16, 32, 96, 160, 32, 32, 4, + 4, 4, 6, 0, 0, 32, 240, 144, 32, 5, 6, 6, 6, 0, 0, 32, + 248, 136, 8, 16, 32, 3, 4, 4, 6, 1, 0, 224, 64, 64, 224, 5, + 5, 5, 6, 0, 0, 248, 32, 32, 32, 248, 4, 4, 4, 6, 0, 0, + 32, 240, 96, 160, 5, 6, 6, 6, 0, 0, 16, 248, 48, 80, 144, 16, + 5, 6, 6, 6, 0, 0, 64, 248, 72, 72, 72, 144, 5, 8, 8, 6, + 0, 0, 40, 0, 64, 248, 72, 72, 72, 144, 5, 6, 6, 6, 0, 0, + 32, 248, 32, 248, 32, 32, 5, 8, 8, 6, 0, 0, 40, 0, 32, 248, + 32, 248, 32, 32, 4, 5, 5, 6, 0, 0, 112, 144, 16, 32, 192, 5, + 7, 7, 6, 0, 0, 40, 0, 112, 144, 16, 32, 192, 5, 6, 6, 6, + 0, 0, 64, 120, 144, 16, 16, 32, 5, 8, 8, 6, 0, 0, 40, 0, + 64, 120, 144, 16, 16, 32, 5, 5, 5, 6, 0, 0, 248, 8, 8, 8, + 248, 5, 7, 7, 6, 0, 0, 40, 0, 248, 8, 8, 8, 248, 5, 6, + 6, 6, 0, 0, 80, 248, 80, 16, 32, 64, 5, 8, 8, 6, 0, 0, + 40, 0, 80, 248, 80, 16, 32, 64, 5, 5, 5, 6, 0, 0, 192, 8, + 200, 16, 224, 5, 7, 7, 6, 0, 0, 40, 0, 192, 8, 200, 16, 224, + 5, 5, 5, 6, 0, 0, 248, 16, 32, 80, 136, 5, 7, 7, 6, 0, + 0, 40, 0, 248, 16, 32, 80, 136, 5, 6, 6, 6, 0, 0, 64, 248, + 72, 80, 64, 56, 5, 8, 8, 6, 0, 0, 40, 0, 64, 248, 72, 80, + 64, 56, 5, 5, 5, 6, 0, 0, 136, 136, 72, 16, 96, 5, 7, 7, + 6, 0, 0, 40, 0, 136, 136, 72, 16, 96, 5, 5, 5, 6, 0, 0, + 120, 72, 168, 16, 96, 5, 7, 7, 6, 0, 0, 40, 0, 120, 72, 168, + 16, 96, 5, 6, 6, 6, 0, 0, 16, 224, 32, 248, 32, 64, 5, 8, + 8, 6, 0, 0, 40, 0, 16, 224, 32, 248, 32, 64, 5, 4, 4, 6, + 0, 0, 168, 168, 8, 48, 5, 5, 5, 6, 0, 0, 168, 168, 8, 16, + 32, 5, 7, 7, 6, 0, 0, 40, 0, 168, 168, 8, 16, 32, 5, 6, + 6, 6, 0, 0, 112, 0, 248, 32, 32, 64, 5, 8, 8, 6, 0, 0, + 40, 0, 112, 0, 248, 32, 32, 64, 3, 6, 6, 6, 1, 0, 128, 128, + 192, 160, 128, 128, 4, 8, 8, 6, 1, 0, 80, 0, 128, 128, 192, 160, + 128, 128, 5, 6, 6, 6, 0, 0, 32, 248, 32, 32, 64, 128, 5, 5, + 5, 6, 0, 0, 112, 0, 0, 0, 248, 5, 5, 5, 6, 0, 0, 248, + 8, 80, 32, 208, 5, 6, 6, 6, 0, 0, 32, 248, 16, 32, 112, 168, + 3, 6, 6, 6, 1, 0, 32, 32, 32, 32, 64, 128, 5, 5, 5, 6, + 0, 0, 16, 136, 136, 136, 136, 5, 7, 7, 6, 0, 0, 40, 0, 16, + 136, 136, 136, 136, 5, 8, 8, 6, 0, 0, 24, 24, 0, 16, 136, 136, + 136, 136, 5, 6, 6, 6, 0, 0, 128, 128, 248, 128, 128, 120, 5, 7, + 7, 6, 0, 0, 40, 128, 128, 248, 128, 128, 120, 5, 7, 7, 6, 0, + 0, 24, 152, 128, 248, 128, 128, 120, 5, 5, 5, 6, 0, 0, 248, 8, + 8, 16, 96, 5, 7, 7, 6, 0, 0, 40, 0, 248, 8, 8, 16, 96, + 5, 8, 8, 6, 0, 0, 24, 24, 0, 248, 8, 8, 16, 96, 5, 4, + 4, 6, 0, 1, 64, 160, 16, 8, 5, 6, 6, 6, 0, 1, 40, 0, + 64, 160, 16, 8, 5, 6, 6, 6, 0, 1, 24, 24, 64, 160, 16, 8, + 5, 6, 6, 6, 0, 0, 32, 248, 32, 168, 168, 32, 5, 8, 8, 6, + 0, 0, 40, 0, 32, 248, 32, 168, 168, 32, 5, 8, 8, 6, 0, 0, + 24, 24, 32, 248, 32, 168, 168, 32, 5, 5, 5, 6, 0, 0, 248, 8, + 80, 32, 16, 4, 5, 5, 6, 1, 0, 224, 0, 224, 0, 240, 5, 5, + 5, 6, 0, 0, 32, 64, 136, 248, 8, 5, 5, 5, 6, 0, 0, 8, + 40, 16, 40, 192, 5, 5, 5, 6, 0, 0, 248, 64, 248, 64, 56, 5, + 4, 4, 6, 0, 0, 64, 248, 80, 64, 5, 6, 6, 6, 0, 0, 64, + 248, 72, 80, 64, 64, 4, 4, 4, 6, 0, 0, 96, 32, 32, 240, 5, + 5, 5, 6, 0, 0, 112, 16, 16, 16, 248, 4, 5, 5, 6, 0, 0, + 240, 16, 240, 16, 240, 5, 5, 5, 6, 0, 0, 248, 8, 248, 8, 248, + 5, 6, 6, 6, 0, 0, 112, 0, 248, 8, 16, 32, 4, 6, 6, 6, + 0, 0, 144, 144, 144, 144, 16, 32, 5, 5, 5, 6, 0, 0, 32, 160, + 168, 168, 176, 4, 5, 5, 6, 0, 0, 128, 128, 144, 160, 192, 5, 5, + 5, 6, 0, 0, 248, 136, 136, 136, 248, 4, 4, 4, 6, 0, 0, 240, + 144, 16, 32, 5, 5, 5, 6, 0, 0, 248, 136, 8, 16, 32, 5, 6, + 6, 6, 0, 0, 16, 248, 80, 80, 248, 16, 5, 5, 5, 6, 0, 0, + 248, 8, 48, 32, 248, 5, 5, 5, 6, 0, 0, 248, 8, 248, 8, 48, + 5, 5, 5, 6, 0, 0, 192, 8, 8, 16, 224, 5, 8, 8, 6, 0, + 0, 40, 0, 32, 248, 136, 8, 16, 32, 4, 4, 4, 6, 0, 0, 64, + 240, 80, 160, 4, 4, 4, 6, 0, 0, 64, 240, 32, 64, 5, 7, 7, + 6, 0, 0, 40, 0, 248, 136, 8, 16, 96, 5, 8, 8, 6, 0, 0, + 40, 0, 16, 248, 80, 80, 248, 16, 5, 7, 7, 6, 0, 0, 40, 0, + 248, 8, 48, 32, 248, 5, 7, 7, 6, 0, 0, 40, 0, 248, 8, 248, + 8, 48, 2, 2, 2, 6, 2, 2, 192, 192, 5, 1, 1, 6, 0, 2, + 248, 5, 4, 4, 6, 0, 1, 128, 96, 16, 8, 5, 5, 5, 6, 0, + 1, 40, 128, 96, 16, 8, 5, 6, 6, 6, 0, 0, 248, 8, 8, 8, + 8, 8 +}; diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/dogm_font_data_Marlin_symbols.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/dogm_font_data_Marlin_symbols.h new file mode 100644 index 00000000..ad9b983b --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/dogm_font_data_Marlin_symbols.h @@ -0,0 +1,45 @@ +/** + * 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 . + * + */ + +/** + Fontname: Marlin_symbols + Copyright: Created with Fony 1.4.7 + Capital A Height: 0, '1' Height: 0 + Calculated Max Values w= 5 h=10 x= 0 y= 3 dx= 6 dy= 0 ascent= 8 len=10 + 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 = 0 descent= 0 + X Font ascent = 0 descent= 0 + Max Font ascent = 8 descent=-2 +*/ +#include +const u8g_fntpgm_uint8_t Marlin_symbols[140] U8G_SECTION(".progmem.Marlin_symbols") = { + 0, 6, 9, 0, 254, 0, 0, 0, 0, 0, 1, 9, 0, 8, 254, 0, + 0, 5, 8, 8, 6, 0, 0, 64, 240, 200, 136, 136, 152, 120, 16, 5, + 8, 8, 6, 0, 0, 192, 248, 136, 136, 136, 136, 136, 248, 5, 5, 5, + 6, 0, 1, 32, 48, 248, 48, 32, 5, 8, 8, 6, 0, 0, 32, 112, + 248, 32, 32, 32, 32, 224, 5, 9, 9, 6, 0, 255, 32, 112, 168, 168, + 184, 136, 136, 112, 32, 5, 9, 9, 6, 0, 255, 224, 128, 192, 176, 168, + 40, 48, 40, 40, 5, 9, 9, 6, 0, 255, 248, 168, 136, 136, 136, 136, + 136, 168, 248, 5, 10, 10, 6, 0, 254, 32, 80, 80, 80, 80, 136, 168, + 168, 136, 112, 3, 3, 3, 6, 0, 3, 64, 160, 64 +}; diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/duration_t.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/duration_t.h new file mode 100644 index 00000000..25ea9bb9 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/duration_t.h @@ -0,0 +1,155 @@ +/** + * 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 . + * + */ + +#ifndef __DURATION_T__ +#define __DURATION_T__ + +struct duration_t { + /** + * @brief Duration is stored in seconds + */ + uint32_t value; + + /** + * @brief Constructor + */ + duration_t() + : duration_t(0) {}; + + /** + * @brief Constructor + * + * @param seconds The number of seconds + */ + duration_t(uint32_t const &seconds) { + this->value = seconds; + } + + /** + * @brief Equality comparison + * @details Overloads the equality comparison operator + * + * @param value The number of seconds to compare to + * @return True if both durations are equal + */ + bool operator==(const uint32_t &value) const { + return (this->value == value); + } + + /** + * @brief Inequality comparison + * @details Overloads the inequality comparison operator + * + * @param value The number of seconds to compare to + * @return False if both durations are equal + */ + bool operator!=(const uint32_t &value) const { + return ! this->operator==(value); + } + + /** + * @brief Formats the duration as years + * @return The number of years + */ + inline uint8_t year() const { + return this->day() / 365; + } + + /** + * @brief Formats the duration as days + * @return The number of days + */ + inline uint16_t day() const { + return this->hour() / 24; + } + + /** + * @brief Formats the duration as hours + * @return The number of hours + */ + inline uint32_t hour() const { + return this->minute() / 60; + } + + /** + * @brief Formats the duration as minutes + * @return The number of minutes + */ + inline uint32_t minute() const { + return this->second() / 60; + } + + /** + * @brief Formats the duration as seconds + * @return The number of seconds + */ + inline uint32_t second() const { + return this->value; + } + + /** + * @brief Formats the duration as a string + * @details String will be formated using a "full" representation of duration + * + * @param buffer The array pointed to must be able to accommodate 21 bytes + * + * Output examples: + * 123456789012345678901 (strlen) + * 135y 364d 23h 59m 59s + * 364d 23h 59m 59s + * 23h 59m 59s + * 59m 59s + * 59s + */ + void toString(char *buffer) const { + int y = this->year(), + d = this->day() % 365, + h = this->hour() % 24, + m = this->minute() % 60, + s = this->second() % 60; + + if (y) sprintf_P(buffer, PSTR("%iy %id %ih %im %is"), y, d, h, m, s); + else if (d) sprintf_P(buffer, PSTR("%id %ih %im %is"), d, h, m, s); + else if (h) sprintf_P(buffer, PSTR("%ih %im %is"), h, m, s); + else if (m) sprintf_P(buffer, PSTR("%im %is"), m, s); + else sprintf_P(buffer, PSTR("%is"), s); + } + + /** + * @brief Formats the duration as a string + * @details String will be formated using a "digital" representation of duration + * + * @param buffer The array pointed to must be able to accommodate 10 bytes + * + * Output examples: + * 1234567890 (strlen) + * 1193046:59 + */ + void toDigital(char *buffer) const { + int h = this->hour() % 24, + m = this->minute() % 60; + + sprintf_P(buffer, PSTR("%02i:%02i"), h, m); + } +}; + +#endif // __DURATION_T__ diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/endstops.cpp b/trunk/Arduino/Marlin_K8600_1.1.0RC7/endstops.cpp new file mode 100644 index 00000000..751296d4 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/endstops.cpp @@ -0,0 +1,378 @@ +/** + * 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 . + * + */ + +/** + * endstops.cpp - A singleton object to manage endstops + */ + +#include "Marlin.h" +#include "cardreader.h" +#include "endstops.h" +#include "temperature.h" +#include "stepper.h" +#include "ultralcd.h" + +// TEST_ENDSTOP: test the old and the current status of an endstop +#define TEST_ENDSTOP(ENDSTOP) (TEST(current_endstop_bits & old_endstop_bits, ENDSTOP)) + +Endstops endstops; + +// public: + +bool Endstops::enabled = true, + Endstops::enabled_globally = + #if ENABLED(ENDSTOPS_ALWAYS_ON_DEFAULT) + (true) + #else + (false) + #endif + ; +volatile char Endstops::endstop_hit_bits; // use X_MIN, Y_MIN, Z_MIN and Z_MIN_PROBE as BIT value + +#if ENABLED(Z_DUAL_ENDSTOPS) + uint16_t +#else + byte +#endif + Endstops::current_endstop_bits = 0, + Endstops::old_endstop_bits = 0; + +#if HAS_BED_PROBE + volatile bool Endstops::z_probe_enabled = false; +#endif + +/** + * Class and Instance Methods + */ + +void Endstops::init() { + + #if HAS_X_MIN + SET_INPUT(X_MIN_PIN); + #if ENABLED(ENDSTOPPULLUP_XMIN) + WRITE(X_MIN_PIN,HIGH); + #endif + #endif + + #if HAS_Y_MIN + SET_INPUT(Y_MIN_PIN); + #if ENABLED(ENDSTOPPULLUP_YMIN) + WRITE(Y_MIN_PIN,HIGH); + #endif + #endif + + #if HAS_Z_MIN + SET_INPUT(Z_MIN_PIN); + #if ENABLED(ENDSTOPPULLUP_ZMIN) + WRITE(Z_MIN_PIN,HIGH); + #endif + #endif + + #if HAS_Z2_MIN + SET_INPUT(Z2_MIN_PIN); + #if ENABLED(ENDSTOPPULLUP_ZMIN) + WRITE(Z2_MIN_PIN,HIGH); + #endif + #endif + + #if HAS_X_MAX + SET_INPUT(X_MAX_PIN); + #if ENABLED(ENDSTOPPULLUP_XMAX) + WRITE(X_MAX_PIN,HIGH); + #endif + #endif + + #if HAS_Y_MAX + SET_INPUT(Y_MAX_PIN); + #if ENABLED(ENDSTOPPULLUP_YMAX) + WRITE(Y_MAX_PIN,HIGH); + #endif + #endif + + #if HAS_Z_MAX + SET_INPUT(Z_MAX_PIN); + #if ENABLED(ENDSTOPPULLUP_ZMAX) + WRITE(Z_MAX_PIN,HIGH); + #endif + #endif + + #if HAS_Z2_MAX + SET_INPUT(Z2_MAX_PIN); + #if ENABLED(ENDSTOPPULLUP_ZMAX) + WRITE(Z2_MAX_PIN,HIGH); + #endif + #endif + + #if HAS_Z_MIN_PROBE_PIN && ENABLED(Z_MIN_PROBE_ENDSTOP) // Check for Z_MIN_PROBE_ENDSTOP so we don't pull a pin high unless it's to be used. + SET_INPUT(Z_MIN_PROBE_PIN); + #if ENABLED(ENDSTOPPULLUP_ZMIN_PROBE) + WRITE(Z_MIN_PROBE_PIN,HIGH); + #endif + #endif + +} // Endstops::init + +void Endstops::report_state() { + if (endstop_hit_bits) { + #if ENABLED(ULTRA_LCD) + char chrX = ' ', chrY = ' ', chrZ = ' ', chrP = ' '; + #define _SET_STOP_CHAR(A,C) (chr## A = C) + #else + #define _SET_STOP_CHAR(A,C) ; + #endif + + #define _ENDSTOP_HIT_ECHO(A,C) do{ \ + SERIAL_ECHOPAIR(" " STRINGIFY(A) ":", stepper.triggered_position_mm(A ##_AXIS)); \ + _SET_STOP_CHAR(A,C); }while(0) + + #define _ENDSTOP_HIT_TEST(A,C) \ + if (TEST(endstop_hit_bits, A ##_MIN) || TEST(endstop_hit_bits, A ##_MAX)) \ + _ENDSTOP_HIT_ECHO(A,C) + + SERIAL_ECHO_START; + SERIAL_ECHOPGM(MSG_ENDSTOPS_HIT); + _ENDSTOP_HIT_TEST(X, 'X'); + _ENDSTOP_HIT_TEST(Y, 'Y'); + _ENDSTOP_HIT_TEST(Z, 'Z'); + + #if ENABLED(Z_MIN_PROBE_ENDSTOP) + #define P_AXIS Z_AXIS + if (TEST(endstop_hit_bits, Z_MIN_PROBE)) _ENDSTOP_HIT_ECHO(P, 'P'); + #endif + SERIAL_EOL; + + #if ENABLED(ULTRA_LCD) + char msg[3 * strlen(MSG_LCD_ENDSTOPS) + 8 + 1]; // Room for a UTF 8 string + sprintf_P(msg, PSTR(MSG_LCD_ENDSTOPS " %c %c %c %c"), chrX, chrY, chrZ, chrP); + lcd_setstatus(msg); + #endif + + hit_on_purpose(); + + #if ENABLED(ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED) && ENABLED(SDSUPPORT) + if (stepper.abort_on_endstop_hit) { + card.sdprinting = false; + card.closefile(); + quickstop_stepper(); + thermalManager.disable_all_heaters(); // switch off all heaters. + } + #endif + } +} // Endstops::report_state + +void Endstops::M119() { + SERIAL_PROTOCOLLNPGM(MSG_M119_REPORT); + #if HAS_X_MIN + SERIAL_PROTOCOLPGM(MSG_X_MIN); + SERIAL_PROTOCOLLN(((READ(X_MIN_PIN)^X_MIN_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN)); + #endif + #if HAS_X_MAX + SERIAL_PROTOCOLPGM(MSG_X_MAX); + SERIAL_PROTOCOLLN(((READ(X_MAX_PIN)^X_MAX_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN)); + #endif + #if HAS_Y_MIN + SERIAL_PROTOCOLPGM(MSG_Y_MIN); + SERIAL_PROTOCOLLN(((READ(Y_MIN_PIN)^Y_MIN_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN)); + #endif + #if HAS_Y_MAX + SERIAL_PROTOCOLPGM(MSG_Y_MAX); + SERIAL_PROTOCOLLN(((READ(Y_MAX_PIN)^Y_MAX_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN)); + #endif + #if HAS_Z_MIN + SERIAL_PROTOCOLPGM(MSG_Z_MIN); + SERIAL_PROTOCOLLN(((READ(Z_MIN_PIN)^Z_MIN_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN)); + #endif + #if HAS_Z_MAX + SERIAL_PROTOCOLPGM(MSG_Z_MAX); + SERIAL_PROTOCOLLN(((READ(Z_MAX_PIN)^Z_MAX_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN)); + #endif + #if HAS_Z2_MAX + SERIAL_PROTOCOLPGM(MSG_Z2_MAX); + SERIAL_PROTOCOLLN(((READ(Z2_MAX_PIN)^Z2_MAX_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN)); + #endif + #if HAS_Z_MIN_PROBE_PIN + SERIAL_PROTOCOLPGM(MSG_Z_PROBE); + SERIAL_PROTOCOLLN(((READ(Z_MIN_PROBE_PIN)^Z_MIN_PROBE_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN)); + #endif +} // Endstops::M119 + +#if ENABLED(Z_DUAL_ENDSTOPS) + + // Pass the result of the endstop test + void Endstops::test_dual_z_endstops(EndstopEnum es1, EndstopEnum es2) { + byte z_test = TEST_ENDSTOP(es1) | (TEST_ENDSTOP(es2) << 1); // bit 0 for Z, bit 1 for Z2 + if (stepper.current_block->steps[Z_AXIS] > 0) { + stepper.endstop_triggered(Z_AXIS); + SBI(endstop_hit_bits, Z_MIN); + if (!stepper.performing_homing || (z_test == 0x3)) //if not performing home or if both endstops were trigged during homing... + stepper.kill_current_block(); + } + } + +#endif + +// Check endstops - Called from ISR! +void Endstops::update() { + + #define _ENDSTOP_PIN(AXIS, MINMAX) AXIS ##_## MINMAX ##_PIN + #define _ENDSTOP_INVERTING(AXIS, MINMAX) AXIS ##_## MINMAX ##_ENDSTOP_INVERTING + #define _ENDSTOP_HIT(AXIS) SBI(endstop_hit_bits, _ENDSTOP(AXIS, MIN)) + #define _ENDSTOP(AXIS, MINMAX) AXIS ##_## MINMAX + + // UPDATE_ENDSTOP_BIT: set the current endstop bits for an endstop to its status + #define UPDATE_ENDSTOP_BIT(AXIS, MINMAX) SET_BIT(current_endstop_bits, _ENDSTOP(AXIS, MINMAX), (READ(_ENDSTOP_PIN(AXIS, MINMAX)) != _ENDSTOP_INVERTING(AXIS, MINMAX))) + // COPY_BIT: copy the value of COPY_BIT to BIT in bits + #define COPY_BIT(bits, COPY_BIT, BIT) SET_BIT(bits, BIT, TEST(bits, COPY_BIT)) + + #define UPDATE_ENDSTOP(AXIS,MINMAX) do { \ + UPDATE_ENDSTOP_BIT(AXIS, MINMAX); \ + if (TEST_ENDSTOP(_ENDSTOP(AXIS, MINMAX)) && stepper.current_block->steps[_AXIS(AXIS)] > 0) { \ + _ENDSTOP_HIT(AXIS); \ + stepper.endstop_triggered(_AXIS(AXIS)); \ + } \ + } while(0) + + #if ENABLED(COREXY) || ENABLED(COREXZ) + // Head direction in -X axis for CoreXY and CoreXZ bots. + // If DeltaA == -DeltaB, the movement is only in Y or Z axis + if ((stepper.current_block->steps[CORE_AXIS_1] != stepper.current_block->steps[CORE_AXIS_2]) || (stepper.motor_direction(CORE_AXIS_1) == stepper.motor_direction(CORE_AXIS_2))) { + if (stepper.motor_direction(X_HEAD)) + #else + if (stepper.motor_direction(X_AXIS)) // stepping along -X axis (regular Cartesian bot) + #endif + { // -direction + #if ENABLED(DUAL_X_CARRIAGE) + // with 2 x-carriages, endstops are only checked in the homing direction for the active extruder + if ((stepper.current_block->active_extruder == 0 && X_HOME_DIR == -1) || (stepper.current_block->active_extruder != 0 && X2_HOME_DIR == -1)) + #endif + { + #if HAS_X_MIN + UPDATE_ENDSTOP(X, MIN); + #endif + } + } + else { // +direction + #if ENABLED(DUAL_X_CARRIAGE) + // with 2 x-carriages, endstops are only checked in the homing direction for the active extruder + if ((stepper.current_block->active_extruder == 0 && X_HOME_DIR == 1) || (stepper.current_block->active_extruder != 0 && X2_HOME_DIR == 1)) + #endif + { + #if HAS_X_MAX + UPDATE_ENDSTOP(X, MAX); + #endif + } + } + #if ENABLED(COREXY) || ENABLED(COREXZ) + } + #endif + + #if ENABLED(COREXY) || ENABLED(COREYZ) + // Head direction in -Y axis for CoreXY / CoreYZ bots. + // If DeltaA == DeltaB, the movement is only in X or Y axis + if ((stepper.current_block->steps[CORE_AXIS_1] != stepper.current_block->steps[CORE_AXIS_2]) || (stepper.motor_direction(CORE_AXIS_1) != stepper.motor_direction(CORE_AXIS_2))) { + if (stepper.motor_direction(Y_HEAD)) + #else + if (stepper.motor_direction(Y_AXIS)) // -direction + #endif + { // -direction + #if HAS_Y_MIN + UPDATE_ENDSTOP(Y, MIN); + #endif + } + else { // +direction + #if HAS_Y_MAX + UPDATE_ENDSTOP(Y, MAX); + #endif + } + #if ENABLED(COREXY) || ENABLED(COREYZ) + } + #endif + + #if ENABLED(COREXZ) || ENABLED(COREYZ) + // Head direction in -Z axis for CoreXZ or CoreYZ bots. + // If DeltaA == DeltaB, the movement is only in X or Y axis + if ((stepper.current_block->steps[CORE_AXIS_1] != stepper.current_block->steps[CORE_AXIS_2]) || (stepper.motor_direction(CORE_AXIS_1) != stepper.motor_direction(CORE_AXIS_2))) { + if (stepper.motor_direction(Z_HEAD)) + #else + if (stepper.motor_direction(Z_AXIS)) + #endif + { // z -direction + #if HAS_Z_MIN + + #if ENABLED(Z_DUAL_ENDSTOPS) + + UPDATE_ENDSTOP_BIT(Z, MIN); + #if HAS_Z2_MIN + UPDATE_ENDSTOP_BIT(Z2, MIN); + #else + COPY_BIT(current_endstop_bits, Z_MIN, Z2_MIN); + #endif + + test_dual_z_endstops(Z_MIN, Z2_MIN); + + #else // !Z_DUAL_ENDSTOPS + + #if HAS_BED_PROBE && ENABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN) + if (z_probe_enabled) UPDATE_ENDSTOP(Z, MIN); + #else + UPDATE_ENDSTOP(Z, MIN); + #endif + + #endif // !Z_DUAL_ENDSTOPS + + #endif // HAS_Z_MIN + + #if HAS_BED_PROBE && ENABLED(Z_MIN_PROBE_ENDSTOP) && DISABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN) + if (z_probe_enabled) { + UPDATE_ENDSTOP(Z, MIN_PROBE); + if (TEST_ENDSTOP(Z_MIN_PROBE)) SBI(endstop_hit_bits, Z_MIN_PROBE); + } + #endif + } + else { // z +direction + #if HAS_Z_MAX + + #if ENABLED(Z_DUAL_ENDSTOPS) + + UPDATE_ENDSTOP_BIT(Z, MAX); + #if HAS_Z2_MAX + UPDATE_ENDSTOP_BIT(Z2, MAX); + #else + COPY_BIT(current_endstop_bits, Z_MAX, Z2_MAX); + #endif + + test_dual_z_endstops(Z_MAX, Z2_MAX); + + #else // !Z_DUAL_ENDSTOPS + + UPDATE_ENDSTOP(Z, MAX); + + #endif // !Z_DUAL_ENDSTOPS + #endif // Z_MAX_PIN + } + #if ENABLED(COREXZ) + } + #endif + + old_endstop_bits = current_endstop_bits; + +} // Endstops::update() diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/endstops.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/endstops.h new file mode 100644 index 00000000..22c2468b --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/endstops.h @@ -0,0 +1,95 @@ +/** + * 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 . + * + */ + +/** + * endstops.h - manages endstops + */ + +#ifndef ENDSTOPS_H +#define ENDSTOPS_H + +#include "enum.h" + +class Endstops { + + public: + + static bool enabled, enabled_globally; + static volatile char endstop_hit_bits; // use X_MIN, Y_MIN, Z_MIN and Z_MIN_PROBE as BIT value + + #if ENABLED(Z_DUAL_ENDSTOPS) + static uint16_t + #else + static byte + #endif + current_endstop_bits, old_endstop_bits; + + Endstops() {}; + + /** + * Initialize the endstop pins + */ + void init(); + + /** + * Update the endstops bits from the pins + */ + static void update(); + + /** + * Print an error message reporting the position when the endstops were last hit. + */ + static void report_state(); //call from somewhere to create an serial error message with the locations the endstops where hit, in case they were triggered + + /** + * Report endstop positions in response to M119 + */ + static void M119(); + + // Enable / disable endstop checking globally + static void enable_globally(bool onoff=true) { enabled_globally = enabled = onoff; } + + // Enable / disable endstop checking + static void enable(bool onoff=true) { enabled = onoff; } + + // Disable / Enable endstops based on ENSTOPS_ONLY_FOR_HOMING and global enable + static void not_homing() { enabled = enabled_globally; } + + // Clear endstops (i.e., they were hit intentionally) to suppress the report + static void hit_on_purpose() { endstop_hit_bits = 0; } + + // Enable / disable endstop z-probe checking + #if HAS_BED_PROBE + static volatile bool z_probe_enabled; + static void enable_z_probe(bool onoff=true) { z_probe_enabled = onoff; } + #endif + + private: + + #if ENABLED(Z_DUAL_ENDSTOPS) + static void test_dual_z_endstops(EndstopEnum es1, EndstopEnum es2); + #endif +}; + +extern Endstops endstops; + +#endif // ENDSTOPS_H diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/enum.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/enum.h new file mode 100644 index 00000000..a51d208a --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/enum.h @@ -0,0 +1,193 @@ +/** + * 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 . + * + */ + +#ifndef __ENUM_H__ +#define __ENUM_H__ + +/** + * Axis indices as enumerated constants + * + * Special axis: + * - A_AXIS and B_AXIS are used by COREXY printers + * - X_HEAD and Y_HEAD is used for systems that don't have a 1:1 relationship + * between X_AXIS and X Head movement, like CoreXY bots + */ +enum AxisEnum { + NO_AXIS = -1, + X_AXIS = 0, + A_AXIS = 0, + Y_AXIS = 1, + B_AXIS = 1, + Z_AXIS = 2, + C_AXIS = 2, + E_AXIS = 3, + X_HEAD = 4, + Y_HEAD = 5, + Z_HEAD = 6 +}; + +#define LOOP_XYZ(VAR) for (uint8_t VAR=X_AXIS; VAR<=Z_AXIS; VAR++) +#define LOOP_XYZE(VAR) for (uint8_t VAR=X_AXIS; VAR<=E_AXIS; VAR++) + +typedef enum { + LINEARUNIT_MM, + LINEARUNIT_INCH +} LinearUnit; + +typedef enum { + TEMPUNIT_C, + TEMPUNIT_K, + TEMPUNIT_F +} TempUnit; + +/** + * Debug flags + * Not yet widely applied + */ +enum DebugFlags { + DEBUG_NONE = 0, + DEBUG_ECHO = _BV(0), ///< Echo commands in order as they are processed + DEBUG_INFO = _BV(1), ///< Print messages for code that has debug output + DEBUG_ERRORS = _BV(2), ///< Not implemented + DEBUG_DRYRUN = _BV(3), ///< Ignore temperature setting and E movement commands + DEBUG_COMMUNICATION = _BV(4), ///< Not implemented + DEBUG_LEVELING = _BV(5) ///< Print detailed output for homing and leveling +}; + +enum EndstopEnum { + X_MIN, + Y_MIN, + Z_MIN, + Z_MIN_PROBE, + X_MAX, + Y_MAX, + Z_MAX, + Z2_MIN, + Z2_MAX +}; + +/** + * Temperature + * Stages in the ISR loop + */ +enum TempState { + PrepareTemp_0, + MeasureTemp_0, + PrepareTemp_BED, + MeasureTemp_BED, + PrepareTemp_1, + MeasureTemp_1, + PrepareTemp_2, + MeasureTemp_2, + PrepareTemp_3, + MeasureTemp_3, + Prepare_FILWIDTH, + Measure_FILWIDTH, + StartupDelay // Startup, delay initial temp reading a tiny bit so the hardware can settle +}; + +#if ENABLED(EMERGENCY_PARSER) + enum e_parser_state { + state_RESET, + state_N, + state_M, + state_M1, + state_M10, + state_M108, + state_M11, + state_M112, + state_M4, + state_M41, + state_M410, + state_IGNORE // to '\n' + }; +#endif + +#if ENABLED(FILAMENT_CHANGE_FEATURE) + enum FilamentChangeMenuResponse { + FILAMENT_CHANGE_RESPONSE_WAIT_FOR, + FILAMENT_CHANGE_RESPONSE_EXTRUDE_MORE, + FILAMENT_CHANGE_RESPONSE_RESUME_PRINT + }; + + #if ENABLED(ULTIPANEL) + enum FilamentChangeMessage { + FILAMENT_CHANGE_MESSAGE_INIT, + FILAMENT_CHANGE_MESSAGE_UNLOAD, + FILAMENT_CHANGE_MESSAGE_INSERT, + FILAMENT_CHANGE_MESSAGE_LOAD, + FILAMENT_CHANGE_MESSAGE_EXTRUDE, + FILAMENT_CHANGE_MESSAGE_OPTION, + FILAMENT_CHANGE_MESSAGE_RESUME, + FILAMENT_CHANGE_MESSAGE_STATUS + }; + #endif +#endif + +/** + * States for managing Marlin and host communication + * Marlin sends messages if blocked or busy + */ +#if ENABLED(HOST_KEEPALIVE_FEATURE) + enum MarlinBusyState { + NOT_BUSY, // Not in a handler + IN_HANDLER, // Processing a GCode + IN_PROCESS, // Known to be blocking command input (as in G29) + PAUSED_FOR_USER, // Blocking pending any input + PAUSED_FOR_INPUT // Blocking pending text input (concept) + }; +#endif + +#if ENABLED(MESH_BED_LEVELING) + enum MeshLevelingState { + MeshReport, + MeshStart, + MeshNext, + MeshSet, + MeshSetZOffset, + MeshReset + }; + + enum MBLStatus { + MBL_STATUS_NONE = 0, + MBL_STATUS_HAS_MESH_BIT = 0, + MBL_STATUS_ACTIVE_BIT = 1 + }; +#endif + +/** + * SD Card + */ +enum LsAction { LS_SerialPrint, LS_Count, LS_GetFilename }; + +/** + * Ultra LCD + */ +enum LCDViewAction { + LCDVIEW_NONE, + LCDVIEW_REDRAW_NOW, + LCDVIEW_CALL_REDRAW_NEXT, + LCDVIEW_CLEAR_CALL_REDRAW, + LCDVIEW_CALL_NO_REDRAW +}; + +#endif // __ENUM_H__ diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/fastio.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/fastio.h new file mode 100644 index 00000000..3a608e00 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/fastio.h @@ -0,0 +1,4051 @@ +/** + * 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 . + * + */ + +/** + This code contributed by Triffid_Hunter and modified by Kliment + why double up on these macros? see http://gcc.gnu.org/onlinedocs/cpp/Stringification.html +*/ + +#ifndef _FASTIO_ARDUINO_H +#define _FASTIO_ARDUINO_H + +#include + +/** + utility functions +*/ + +#ifndef MASK + #define MASK(PIN) (1 << PIN) +#endif + +/** + magic I/O routines + now you can simply SET_OUTPUT(STEP); WRITE(STEP, 1); WRITE(STEP, 0); +*/ + +/// Read a pin +#define _READ(IO) ((bool)(DIO ## IO ## _RPORT & MASK(DIO ## IO ## _PIN))) +/// write to a pin +// On some boards pins > 0x100 are used. These are not converted to atomic actions. An critical section is needed. + +#define _WRITE_NC(IO, v) do { if (v) {DIO ## IO ## _WPORT |= MASK(DIO ## IO ## _PIN); } else {DIO ## IO ## _WPORT &= ~MASK(DIO ## IO ## _PIN); }; } while (0) + +#define _WRITE_C(IO, v) do { if (v) { \ + CRITICAL_SECTION_START; \ + {DIO ## IO ## _WPORT |= MASK(DIO ## IO ## _PIN); } \ + CRITICAL_SECTION_END; \ + } \ + else { \ + CRITICAL_SECTION_START; \ + {DIO ## IO ## _WPORT &= ~MASK(DIO ## IO ## _PIN); } \ + CRITICAL_SECTION_END; \ + } \ + } \ + while (0) + +#define _WRITE(IO, v) do { if (&(DIO ## IO ## _RPORT) >= (uint8_t *)0x100) {_WRITE_C(IO, v); } else {_WRITE_NC(IO, v); }; } while (0) + +/// toggle a pin +#define _TOGGLE(IO) do {DIO ## IO ## _RPORT = MASK(DIO ## IO ## _PIN); } while (0) + +/// set pin as input +#define _SET_INPUT(IO) do {DIO ## IO ## _DDR &= ~MASK(DIO ## IO ## _PIN); } while (0) +/// set pin as output +#define _SET_OUTPUT(IO) do {DIO ## IO ## _DDR |= MASK(DIO ## IO ## _PIN); } while (0) + +/// check if pin is an input +#define _GET_INPUT(IO) ((DIO ## IO ## _DDR & MASK(DIO ## IO ## _PIN)) == 0) +/// check if pin is an output +#define _GET_OUTPUT(IO) ((DIO ## IO ## _DDR & MASK(DIO ## IO ## _PIN)) != 0) + +/// check if pin is an timer +#define _GET_TIMER(IO) ((DIO ## IO ## _PWM) + +// why double up on these macros? see http://gcc.gnu.org/onlinedocs/cpp/Stringification.html + +/// Read a pin wrapper +#define READ(IO) _READ(IO) +/// Write to a pin wrapper +#define WRITE(IO, v) _WRITE(IO, v) + +/// toggle a pin wrapper +#define TOGGLE(IO) _TOGGLE(IO) + +/// set pin as input wrapper +#define SET_INPUT(IO) _SET_INPUT(IO) +/// set pin as output wrapper +#define SET_OUTPUT(IO) _SET_OUTPUT(IO) + +/// check if pin is an input wrapper +#define GET_INPUT(IO) _GET_INPUT(IO) +/// check if pin is an output wrapper +#define GET_OUTPUT(IO) _GET_OUTPUT(IO) + +/// check if pin is an timer wrapper +#define GET_TIMER(IO) _GET_TIMER(IO) + +// Shorthand +#define OUT_WRITE(IO, v) { SET_OUTPUT(IO); WRITE(IO, v); } + +/** + ports and functions + + added as necessary or if I feel like it- not a comprehensive list! +*/ + +#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328__) || defined(__AVR_ATmega328P__) + // UART + #define RXD DIO0 + #define TXD DIO1 + + // SPI + #define SCK DIO13 + #define MISO DIO12 + #define MOSI DIO11 + #define SS DIO10 + + // TWI (I2C) + #define SCL AIO5 + #define SDA AIO4 + + // timers and PWM + #define OC0A DIO6 + #define OC0B DIO5 + #define OC1A DIO9 + #define OC1B DIO10 + #define OC2A DIO11 + #define OC2B DIO3 + + #define DEBUG_LED AIO5 + + /** + pins + */ + + #define DIO0_PIN PIND0 + #define DIO0_RPORT PIND + #define DIO0_WPORT PORTD + #define DIO0_DDR DDRD + #define DIO0_PWM NULL + + #define DIO1_PIN PIND1 + #define DIO1_RPORT PIND + #define DIO1_WPORT PORTD + #define DIO1_DDR DDRD + #define DIO1_PWM NULL + + #define DIO2_PIN PIND2 + #define DIO2_RPORT PIND + #define DIO2_WPORT PORTD + #define DIO2_DDR DDRD + #define DIO2_PWM NULL + + #define DIO3_PIN PIND3 + #define DIO3_RPORT PIND + #define DIO3_WPORT PORTD + #define DIO3_DDR DDRD + #define DIO3_PWM &OCR2B + + #define DIO4_PIN PIND4 + #define DIO4_RPORT PIND + #define DIO4_WPORT PORTD + #define DIO4_DDR DDRD + #define DIO4_PWM NULL + + #define DIO5_PIN PIND5 + #define DIO5_RPORT PIND + #define DIO5_WPORT PORTD + #define DIO5_DDR DDRD + #define DIO5_PWM &OCR0B + + #define DIO6_PIN PIND6 + #define DIO6_RPORT PIND + #define DIO6_WPORT PORTD + #define DIO6_DDR DDRD + #define DIO6_PWM &OCR0A + + #define DIO7_PIN PIND7 + #define DIO7_RPORT PIND + #define DIO7_WPORT PORTD + #define DIO7_DDR DDRD + #define DIO7_PWM NULL + + #define DIO8_PIN PINB0 + #define DIO8_RPORT PINB + #define DIO8_WPORT PORTB + #define DIO8_DDR DDRB + #define DIO8_PWM NULL + + #define DIO9_PIN PINB1 + #define DIO9_RPORT PINB + #define DIO9_WPORT PORTB + #define DIO9_DDR DDRB + #define DIO9_PWM NULL + + #define DIO10_PIN PINB2 + #define DIO10_RPORT PINB + #define DIO10_WPORT PORTB + #define DIO10_DDR DDRB + #define DIO10_PWM NULL + + #define DIO11_PIN PINB3 + #define DIO11_RPORT PINB + #define DIO11_WPORT PORTB + #define DIO11_DDR DDRB + #define DIO11_PWM &OCR2A + + #define DIO12_PIN PINB4 + #define DIO12_RPORT PINB + #define DIO12_WPORT PORTB + #define DIO12_DDR DDRB + #define DIO12_PWM NULL + + #define DIO13_PIN PINB5 + #define DIO13_RPORT PINB + #define DIO13_WPORT PORTB + #define DIO13_DDR DDRB + #define DIO13_PWM NULL + + + #define DIO14_PIN PINC0 + #define DIO14_RPORT PINC + #define DIO14_WPORT PORTC + #define DIO14_DDR DDRC + #define DIO14_PWM NULL + + #define DIO15_PIN PINC1 + #define DIO15_RPORT PINC + #define DIO15_WPORT PORTC + #define DIO15_DDR DDRC + #define DIO15_PWM NULL + + #define DIO16_PIN PINC2 + #define DIO16_RPORT PINC + #define DIO16_WPORT PORTC + #define DIO16_DDR DDRC + #define DIO16_PWM NULL + + #define DIO17_PIN PINC3 + #define DIO17_RPORT PINC + #define DIO17_WPORT PORTC + #define DIO17_DDR DDRC + #define DIO17_PWM NULL + + #define DIO18_PIN PINC4 + #define DIO18_RPORT PINC + #define DIO18_WPORT PORTC + #define DIO18_DDR DDRC + #define DIO18_PWM NULL + + #define DIO19_PIN PINC5 + #define DIO19_RPORT PINC + #define DIO19_WPORT PORTC + #define DIO19_DDR DDRC + #define DIO19_PWM NULL + + #define DIO20_PIN PINC6 + #define DIO20_RPORT PINC + #define DIO20_WPORT PORTC + #define DIO20_DDR DDRC + #define DIO20_PWM NULL + + #define DIO21_PIN PINC7 + #define DIO21_RPORT PINC + #define DIO21_WPORT PORTC + #define DIO21_DDR DDRC + #define DIO21_PWM NULL + + + + #undef PB0 + #define PB0_PIN PINB0 + #define PB0_RPORT PINB + #define PB0_WPORT PORTB + #define PB0_DDR DDRB + #define PB0_PWM NULL + + #undef PB1 + #define PB1_PIN PINB1 + #define PB1_RPORT PINB + #define PB1_WPORT PORTB + #define PB1_DDR DDRB + #define PB1_PWM NULL + + #undef PB2 + #define PB2_PIN PINB2 + #define PB2_RPORT PINB + #define PB2_WPORT PORTB + #define PB2_DDR DDRB + #define PB2_PWM NULL + + #undef PB3 + #define PB3_PIN PINB3 + #define PB3_RPORT PINB + #define PB3_WPORT PORTB + #define PB3_DDR DDRB + #define PB3_PWM &OCR2A + + #undef PB4 + #define PB4_PIN PINB4 + #define PB4_RPORT PINB + #define PB4_WPORT PORTB + #define PB4_DDR DDRB + #define PB4_PWM NULL + + #undef PB5 + #define PB5_PIN PINB5 + #define PB5_RPORT PINB + #define PB5_WPORT PORTB + #define PB5_DDR DDRB + #define PB5_PWM NULL + + #undef PB6 + #define PB6_PIN PINB6 + #define PB6_RPORT PINB + #define PB6_WPORT PORTB + #define PB6_DDR DDRB + #define PB6_PWM NULL + + #undef PB7 + #define PB7_PIN PINB7 + #define PB7_RPORT PINB + #define PB7_WPORT PORTB + #define PB7_DDR DDRB + #define PB7_PWM NULL + + + #undef PC0 + #define PC0_PIN PINC0 + #define PC0_RPORT PINC + #define PC0_WPORT PORTC + #define PC0_DDR DDRC + #define PC0_PWM NULL + + #undef PC1 + #define PC1_PIN PINC1 + #define PC1_RPORT PINC + #define PC1_WPORT PORTC + #define PC1_DDR DDRC + #define PC1_PWM NULL + + #undef PC2 + #define PC2_PIN PINC2 + #define PC2_RPORT PINC + #define PC2_WPORT PORTC + #define PC2_DDR DDRC + #define PC2_PWM NULL + + #undef PC3 + #define PC3_PIN PINC3 + #define PC3_RPORT PINC + #define PC3_WPORT PORTC + #define PC3_DDR DDRC + #define PC3_PWM NULL + + #undef PC4 + #define PC4_PIN PINC4 + #define PC4_RPORT PINC + #define PC4_WPORT PORTC + #define PC4_DDR DDRC + #define PC4_PWM NULL + + #undef PC5 + #define PC5_PIN PINC5 + #define PC5_RPORT PINC + #define PC5_WPORT PORTC + #define PC5_DDR DDRC + #define PC5_PWM NULL + + #undef PC6 + #define PC6_PIN PINC6 + #define PC6_RPORT PINC + #define PC6_WPORT PORTC + #define PC6_DDR DDRC + #define PC6_PWM NULL + + #undef PC7 + #define PC7_PIN PINC7 + #define PC7_RPORT PINC + #define PC7_WPORT PORTC + #define PC7_DDR DDRC + #define PC7_PWM NULL + + + #undef PD0 + #define PD0_PIN PIND0 + #define PD0_RPORT PIND + #define PD0_WPORT PORTD + #define PD0_DDR DDRD + #define PD0_PWM NULL + + #undef PD1 + #define PD1_PIN PIND1 + #define PD1_RPORT PIND + #define PD1_WPORT PORTD + #define PD1_DDR DDRD + #define PD1_PWM NULL + + #undef PD2 + #define PD2_PIN PIND2 + #define PD2_RPORT PIND + #define PD2_WPORT PORTD + #define PD2_DDR DDRD + #define PD2_PWM NULL + + #undef PD3 + #define PD3_PIN PIND3 + #define PD3_RPORT PIND + #define PD3_WPORT PORTD + #define PD3_DDR DDRD + #define PD3_PWM &OCR2B + + #undef PD4 + #define PD4_PIN PIND4 + #define PD4_RPORT PIND + #define PD4_WPORT PORTD + #define PD4_DDR DDRD + #define PD4_PWM NULL + + #undef PD5 + #define PD5_PIN PIND5 + #define PD5_RPORT PIND + #define PD5_WPORT PORTD + #define PD5_DDR DDRD + #define PD5_PWM &OCR0B + + #undef PD6 + #define PD6_PIN PIND6 + #define PD6_RPORT PIND + #define PD6_WPORT PORTD + #define PD6_DDR DDRD + #define PD6_PWM &OCR0A + + #undef PD7 + #define PD7_PIN PIND7 + #define PD7_RPORT PIND + #define PD7_WPORT PORTD + #define PD7_DDR DDRD + #define PD7_PWM NULL +#endif /* _AVR_ATmega{168,328,328P}__ */ + +#if defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__) || defined(__AVR_ATmega1284P__) + // UART + #define RXD DIO8 + #define TXD DIO9 + #define RXD0 DIO8 + #define TXD0 DIO9 + + #define RXD1 DIO10 + #define TXD1 DIO11 + + // SPI + #define SCK DIO7 + #define MISO DIO6 + #define MOSI DIO5 + #define SS DIO4 + + // TWI (I2C) + #define SCL DIO16 + #define SDA DIO17 + + // timers and PWM + #define OC0A DIO3 + #define OC0B DIO4 + #define OC1A DIO13 + #define OC1B DIO12 + #define OC2A DIO15 + #define OC2B DIO14 + + #define DEBUG_LED DIO0 + /** + pins + */ + + #define DIO0_PIN PINB0 + #define DIO0_RPORT PINB + #define DIO0_WPORT PORTB + #define DIO0_DDR DDRB + #define DIO0_PWM NULL + + #define DIO1_PIN PINB1 + #define DIO1_RPORT PINB + #define DIO1_WPORT PORTB + #define DIO1_DDR DDRB + #define DIO1_PWM NULL + + #define DIO2_PIN PINB2 + #define DIO2_RPORT PINB + #define DIO2_WPORT PORTB + #define DIO2_DDR DDRB + #define DIO2_PWM NULL + + #define DIO3_PIN PINB3 + #define DIO3_RPORT PINB + #define DIO3_WPORT PORTB + #define DIO3_DDR DDRB + #define DIO3_PWM OCR0A + + #define DIO4_PIN PINB4 + #define DIO4_RPORT PINB + #define DIO4_WPORT PORTB + #define DIO4_DDR DDRB + #define DIO4_PWM OCR0B + + #define DIO5_PIN PINB5 + #define DIO5_RPORT PINB + #define DIO5_WPORT PORTB + #define DIO5_DDR DDRB + #define DIO5_PWM NULL + + #define DIO6_PIN PINB6 + #define DIO6_RPORT PINB + #define DIO6_WPORT PORTB + #define DIO6_DDR DDRB + #define DIO6_PWM NULL + + #define DIO7_PIN PINB7 + #define DIO7_RPORT PINB + #define DIO7_WPORT PORTB + #define DIO7_DDR DDRB + #define DIO7_PWM NULL + + #define DIO8_PIN PIND0 + #define DIO8_RPORT PIND + #define DIO8_WPORT PORTD + #define DIO8_DDR DDRD + #define DIO8_PWM NULL + + #define DIO9_PIN PIND1 + #define DIO9_RPORT PIND + #define DIO9_WPORT PORTD + #define DIO9_DDR DDRD + #define DIO9_PWM NULL + + #define DIO10_PIN PIND2 + #define DIO10_RPORT PIND + #define DIO10_WPORT PORTD + #define DIO10_DDR DDRD + #define DIO10_PWM NULL + + #define DIO11_PIN PIND3 + #define DIO11_RPORT PIND + #define DIO11_WPORT PORTD + #define DIO11_DDR DDRD + #define DIO11_PWM NULL + + #define DIO12_PIN PIND4 + #define DIO12_RPORT PIND + #define DIO12_WPORT PORTD + #define DIO12_DDR DDRD + #define DIO12_PWM OCR1B + + #define DIO13_PIN PIND5 + #define DIO13_RPORT PIND + #define DIO13_WPORT PORTD + #define DIO13_DDR DDRD + #define DIO13_PWM OCR1A + + #define DIO14_PIN PIND6 + #define DIO14_RPORT PIND + #define DIO14_WPORT PORTD + #define DIO14_DDR DDRD + #define DIO14_PWM OCR2B + + #define DIO15_PIN PIND7 + #define DIO15_RPORT PIND + #define DIO15_WPORT PORTD + #define DIO15_DDR DDRD + #define DIO15_PWM OCR2A + + #define DIO16_PIN PINC0 + #define DIO16_RPORT PINC + #define DIO16_WPORT PORTC + #define DIO16_DDR DDRC + #define DIO16_PWM NULL + + #define DIO17_PIN PINC1 + #define DIO17_RPORT PINC + #define DIO17_WPORT PORTC + #define DIO17_DDR DDRC + #define DIO17_PWM NULL + + #define DIO18_PIN PINC2 + #define DIO18_RPORT PINC + #define DIO18_WPORT PORTC + #define DIO18_DDR DDRC + #define DIO18_PWM NULL + + #define DIO19_PIN PINC3 + #define DIO19_RPORT PINC + #define DIO19_WPORT PORTC + #define DIO19_DDR DDRC + #define DIO19_PWM NULL + + #define DIO20_PIN PINC4 + #define DIO20_RPORT PINC + #define DIO20_WPORT PORTC + #define DIO20_DDR DDRC + #define DIO20_PWM NULL + + #define DIO21_PIN PINC5 + #define DIO21_RPORT PINC + #define DIO21_WPORT PORTC + #define DIO21_DDR DDRC + #define DIO21_PWM NULL + + #define DIO22_PIN PINC6 + #define DIO22_RPORT PINC + #define DIO22_WPORT PORTC + #define DIO22_DDR DDRC + #define DIO22_PWM NULL + + #define DIO23_PIN PINC7 + #define DIO23_RPORT PINC + #define DIO23_WPORT PORTC + #define DIO23_DDR DDRC + #define DIO23_PWM NULL + + #define DIO24_PIN PINA7 + #define DIO24_RPORT PINA + #define DIO24_WPORT PORTA + #define DIO24_DDR DDRA + #define DIO24_PWM NULL + + #define DIO25_PIN PINA6 + #define DIO25_RPORT PINA + #define DIO25_WPORT PORTA + #define DIO25_DDR DDRA + #define DIO25_PWM NULL + + #define DIO26_PIN PINA5 + #define DIO26_RPORT PINA + #define DIO26_WPORT PORTA + #define DIO26_DDR DDRA + #define DIO26_PWM NULL + + #define DIO27_PIN PINA4 + #define DIO27_RPORT PINA + #define DIO27_WPORT PORTA + #define DIO27_DDR DDRA + #define DIO27_PWM NULL + + #define DIO28_PIN PINA3 + #define DIO28_RPORT PINA + #define DIO28_WPORT PORTA + #define DIO28_DDR DDRA + #define DIO28_PWM NULL + + #define DIO29_PIN PINA2 + #define DIO29_RPORT PINA + #define DIO29_WPORT PORTA + #define DIO29_DDR DDRA + #define DIO29_PWM NULL + + #define DIO30_PIN PINA1 + #define DIO30_RPORT PINA + #define DIO30_WPORT PORTA + #define DIO30_DDR DDRA + #define DIO30_PWM NULL + + #define DIO31_PIN PINA0 + #define DIO31_RPORT PINA + #define DIO31_WPORT PORTA + #define DIO31_DDR DDRA + #define DIO31_PWM NULL + + #define AIO0_PIN PINA0 + #define AIO0_RPORT PINA + #define AIO0_WPORT PORTA + #define AIO0_DDR DDRA + #define AIO0_PWM NULL + + #define AIO1_PIN PINA1 + #define AIO1_RPORT PINA + #define AIO1_WPORT PORTA + #define AIO1_DDR DDRA + #define AIO1_PWM NULL + + #define AIO2_PIN PINA2 + #define AIO2_RPORT PINA + #define AIO2_WPORT PORTA + #define AIO2_DDR DDRA + #define AIO2_PWM NULL + + #define AIO3_PIN PINA3 + #define AIO3_RPORT PINA + #define AIO3_WPORT PORTA + #define AIO3_DDR DDRA + #define AIO3_PWM NULL + + #define AIO4_PIN PINA4 + #define AIO4_RPORT PINA + #define AIO4_WPORT PORTA + #define AIO4_DDR DDRA + #define AIO4_PWM NULL + + #define AIO5_PIN PINA5 + #define AIO5_RPORT PINA + #define AIO5_WPORT PORTA + #define AIO5_DDR DDRA + #define AIO5_PWM NULL + + #define AIO6_PIN PINA6 + #define AIO6_RPORT PINA + #define AIO6_WPORT PORTA + #define AIO6_DDR DDRA + #define AIO6_PWM NULL + + #define AIO7_PIN PINA7 + #define AIO7_RPORT PINA + #define AIO7_WPORT PORTA + #define AIO7_DDR DDRA + #define AIO7_PWM NULL + + + + #undef PA0 + #define PA0_PIN PINA0 + #define PA0_RPORT PINA + #define PA0_WPORT PORTA + #define PA0_DDR DDRA + #define PA0_PWM NULL + + #undef PA1 + #define PA1_PIN PINA1 + #define PA1_RPORT PINA + #define PA1_WPORT PORTA + #define PA1_DDR DDRA + #define PA1_PWM NULL + + #undef PA2 + #define PA2_PIN PINA2 + #define PA2_RPORT PINA + #define PA2_WPORT PORTA + #define PA2_DDR DDRA + #define PA2_PWM NULL + + #undef PA3 + #define PA3_PIN PINA3 + #define PA3_RPORT PINA + #define PA3_WPORT PORTA + #define PA3_DDR DDRA + #define PA3_PWM NULL + + #undef PA4 + #define PA4_PIN PINA4 + #define PA4_RPORT PINA + #define PA4_WPORT PORTA + #define PA4_DDR DDRA + #define PA4_PWM NULL + + #undef PA5 + #define PA5_PIN PINA5 + #define PA5_RPORT PINA + #define PA5_WPORT PORTA + #define PA5_DDR DDRA + #define PA5_PWM NULL + + #undef PA6 + #define PA6_PIN PINA6 + #define PA6_RPORT PINA + #define PA6_WPORT PORTA + #define PA6_DDR DDRA + #define PA6_PWM NULL + + #undef PA7 + #define PA7_PIN PINA7 + #define PA7_RPORT PINA + #define PA7_WPORT PORTA + #define PA7_DDR DDRA + #define PA7_PWM NULL + + + #undef PB0 + #define PB0_PIN PINB0 + #define PB0_RPORT PINB + #define PB0_WPORT PORTB + #define PB0_DDR DDRB + #define PB0_PWM NULL + + #undef PB1 + #define PB1_PIN PINB1 + #define PB1_RPORT PINB + #define PB1_WPORT PORTB + #define PB1_DDR DDRB + #define PB1_PWM NULL + + #undef PB2 + #define PB2_PIN PINB2 + #define PB2_RPORT PINB + #define PB2_WPORT PORTB + #define PB2_DDR DDRB + #define PB2_PWM NULL + + #undef PB3 + #define PB3_PIN PINB3 + #define PB3_RPORT PINB + #define PB3_WPORT PORTB + #define PB3_DDR DDRB + #define PB3_PWM OCR0A + + #undef PB4 + #define PB4_PIN PINB4 + #define PB4_RPORT PINB + #define PB4_WPORT PORTB + #define PB4_DDR DDRB + #define PB4_PWM OCR0B + + #undef PB5 + #define PB5_PIN PINB5 + #define PB5_RPORT PINB + #define PB5_WPORT PORTB + #define PB5_DDR DDRB + #define PB5_PWM NULL + + #undef PB6 + #define PB6_PIN PINB6 + #define PB6_RPORT PINB + #define PB6_WPORT PORTB + #define PB6_DDR DDRB + #define PB6_PWM NULL + + #undef PB7 + #define PB7_PIN PINB7 + #define PB7_RPORT PINB + #define PB7_WPORT PORTB + #define PB7_DDR DDRB + #define PB7_PWM NULL + + + #undef PC0 + #define PC0_PIN PINC0 + #define PC0_RPORT PINC + #define PC0_WPORT PORTC + #define PC0_DDR DDRC + #define PC0_PWM NULL + + #undef PC1 + #define PC1_PIN PINC1 + #define PC1_RPORT PINC + #define PC1_WPORT PORTC + #define PC1_DDR DDRC + #define PC1_PWM NULL + + #undef PC2 + #define PC2_PIN PINC2 + #define PC2_RPORT PINC + #define PC2_WPORT PORTC + #define PC2_DDR DDRC + #define PC2_PWM NULL + + #undef PC3 + #define PC3_PIN PINC3 + #define PC3_RPORT PINC + #define PC3_WPORT PORTC + #define PC3_DDR DDRC + #define PC3_PWM NULL + + #undef PC4 + #define PC4_PIN PINC4 + #define PC4_RPORT PINC + #define PC4_WPORT PORTC + #define PC4_DDR DDRC + #define PC4_PWM NULL + + #undef PC5 + #define PC5_PIN PINC5 + #define PC5_RPORT PINC + #define PC5_WPORT PORTC + #define PC5_DDR DDRC + #define PC5_PWM NULL + + #undef PC6 + #define PC6_PIN PINC6 + #define PC6_RPORT PINC + #define PC6_WPORT PORTC + #define PC6_DDR DDRC + #define PC6_PWM NULL + + #undef PC7 + #define PC7_PIN PINC7 + #define PC7_RPORT PINC + #define PC7_WPORT PORTC + #define PC7_DDR DDRC + #define PC7_PWM NULL + + + #undef PD0 + #define PD0_PIN PIND0 + #define PD0_RPORT PIND + #define PD0_WPORT PORTD + #define PD0_DDR DDRD + #define PD0_PWM NULL + + #undef PD1 + #define PD1_PIN PIND1 + #define PD1_RPORT PIND + #define PD1_WPORT PORTD + #define PD1_DDR DDRD + #define PD1_PWM NULL + + #undef PD2 + #define PD2_PIN PIND2 + #define PD2_RPORT PIND + #define PD2_WPORT PORTD + #define PD2_DDR DDRD + #define PD2_PWM NULL + + #undef PD3 + #define PD3_PIN PIND3 + #define PD3_RPORT PIND + #define PD3_WPORT PORTD + #define PD3_DDR DDRD + #define PD3_PWM NULL + + #undef PD4 + #define PD4_PIN PIND4 + #define PD4_RPORT PIND + #define PD4_WPORT PORTD + #define PD4_DDR DDRD + #define PD4_PWM NULL + + #undef PD5 + #define PD5_PIN PIND5 + #define PD5_RPORT PIND + #define PD5_WPORT PORTD + #define PD5_DDR DDRD + #define PD5_PWM NULL + + #undef PD6 + #define PD6_PIN PIND6 + #define PD6_RPORT PIND + #define PD6_WPORT PORTD + #define PD6_DDR DDRD + #define PD6_PWM OCR2B + + #undef PD7 + #define PD7_PIN PIND7 + #define PD7_RPORT PIND + #define PD7_WPORT PORTD + #define PD7_DDR DDRD + #define PD7_PWM OCR2A +#endif /* _AVR_ATmega{644,644P,644PA}__ */ + +#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) + // UART + #define RXD DIO0 + #define TXD DIO1 + + // SPI + #define SCK DIO52 + #define MISO DIO50 + #define MOSI DIO51 + #define SS DIO53 + + // TWI (I2C) + #define SCL DIO21 + #define SDA DIO20 + + // timers and PWM + #define OC0A DIO13 + #define OC0B DIO4 + #define OC1A DIO11 + #define OC1B DIO12 + #define OC2A DIO10 + #define OC2B DIO9 + #define OC3A DIO5 + #define OC3B DIO2 + #define OC3C DIO3 + #define OC4A DIO6 + #define OC4B DIO7 + #define OC4C DIO8 + #define OC5A DIO46 + #define OC5B DIO45 + #define OC5C DIO44 + + // change for your board + #define DEBUG_LED DIO21 + + /** + pins + */ + #define DIO0_PIN PINE0 + #define DIO0_RPORT PINE + #define DIO0_WPORT PORTE + #define DIO0_DDR DDRE + #define DIO0_PWM NULL + + #define DIO1_PIN PINE1 + #define DIO1_RPORT PINE + #define DIO1_WPORT PORTE + #define DIO1_DDR DDRE + #define DIO1_PWM NULL + + #define DIO2_PIN PINE4 + #define DIO2_RPORT PINE + #define DIO2_WPORT PORTE + #define DIO2_DDR DDRE + #define DIO2_PWM &OCR3BL + + #define DIO3_PIN PINE5 + #define DIO3_RPORT PINE + #define DIO3_WPORT PORTE + #define DIO3_DDR DDRE + #define DIO3_PWM &OCR3CL + + #define DIO4_PIN PING5 + #define DIO4_RPORT PING + #define DIO4_WPORT PORTG + #define DIO4_DDR DDRG + #define DIO4_PWM &OCR0B + + #define DIO5_PIN PINE3 + #define DIO5_RPORT PINE + #define DIO5_WPORT PORTE + #define DIO5_DDR DDRE + #define DIO5_PWM &OCR3AL + + #define DIO6_PIN PINH3 + #define DIO6_RPORT PINH + #define DIO6_WPORT PORTH + #define DIO6_DDR DDRH + #define DIO6_PWM &OCR4AL + + #define DIO7_PIN PINH4 + #define DIO7_RPORT PINH + #define DIO7_WPORT PORTH + #define DIO7_DDR DDRH + #define DIO7_PWM &OCR4BL + + #define DIO8_PIN PINH5 + #define DIO8_RPORT PINH + #define DIO8_WPORT PORTH + #define DIO8_DDR DDRH + #define DIO8_PWM &OCR4CL + + #define DIO9_PIN PINH6 + #define DIO9_RPORT PINH + #define DIO9_WPORT PORTH + #define DIO9_DDR DDRH + #define DIO9_PWM &OCR2B + + #define DIO10_PIN PINB4 + #define DIO10_RPORT PINB + #define DIO10_WPORT PORTB + #define DIO10_DDR DDRB + #define DIO10_PWM &OCR2A + + #define DIO11_PIN PINB5 + #define DIO11_RPORT PINB + #define DIO11_WPORT PORTB + #define DIO11_DDR DDRB + #define DIO11_PWM NULL + + #define DIO12_PIN PINB6 + #define DIO12_RPORT PINB + #define DIO12_WPORT PORTB + #define DIO12_DDR DDRB + #define DIO12_PWM NULL + + #define DIO13_PIN PINB7 + #define DIO13_RPORT PINB + #define DIO13_WPORT PORTB + #define DIO13_DDR DDRB + #define DIO13_PWM &OCR0A + + #define DIO14_PIN PINJ1 + #define DIO14_RPORT PINJ + #define DIO14_WPORT PORTJ + #define DIO14_DDR DDRJ + #define DIO14_PWM NULL + + #define DIO15_PIN PINJ0 + #define DIO15_RPORT PINJ + #define DIO15_WPORT PORTJ + #define DIO15_DDR DDRJ + #define DIO15_PWM NULL + + #define DIO16_PIN PINH1 + #define DIO16_RPORT PINH + #define DIO16_WPORT PORTH + #define DIO16_DDR DDRH + #define DIO16_PWM NULL + + #define DIO17_PIN PINH0 + #define DIO17_RPORT PINH + #define DIO17_WPORT PORTH + #define DIO17_DDR DDRH + #define DIO17_PWM NULL + + #define DIO18_PIN PIND3 + #define DIO18_RPORT PIND + #define DIO18_WPORT PORTD + #define DIO18_DDR DDRD + #define DIO18_PWM NULL + + #define DIO19_PIN PIND2 + #define DIO19_RPORT PIND + #define DIO19_WPORT PORTD + #define DIO19_DDR DDRD + #define DIO19_PWM NULL + + #define DIO20_PIN PIND1 + #define DIO20_RPORT PIND + #define DIO20_WPORT PORTD + #define DIO20_DDR DDRD + #define DIO20_PWM NULL + + #define DIO21_PIN PIND0 + #define DIO21_RPORT PIND + #define DIO21_WPORT PORTD + #define DIO21_DDR DDRD + #define DIO21_PWM NULL + + #define DIO22_PIN PINA0 + #define DIO22_RPORT PINA + #define DIO22_WPORT PORTA + #define DIO22_DDR DDRA + #define DIO22_PWM NULL + + #define DIO23_PIN PINA1 + #define DIO23_RPORT PINA + #define DIO23_WPORT PORTA + #define DIO23_DDR DDRA + #define DIO23_PWM NULL + + #define DIO24_PIN PINA2 + #define DIO24_RPORT PINA + #define DIO24_WPORT PORTA + #define DIO24_DDR DDRA + #define DIO24_PWM NULL + + #define DIO25_PIN PINA3 + #define DIO25_RPORT PINA + #define DIO25_WPORT PORTA + #define DIO25_DDR DDRA + #define DIO25_PWM NULL + + #define DIO26_PIN PINA4 + #define DIO26_RPORT PINA + #define DIO26_WPORT PORTA + #define DIO26_DDR DDRA + #define DIO26_PWM NULL + + #define DIO27_PIN PINA5 + #define DIO27_RPORT PINA + #define DIO27_WPORT PORTA + #define DIO27_DDR DDRA + #define DIO27_PWM NULL + + #define DIO28_PIN PINA6 + #define DIO28_RPORT PINA + #define DIO28_WPORT PORTA + #define DIO28_DDR DDRA + #define DIO28_PWM NULL + + #define DIO29_PIN PINA7 + #define DIO29_RPORT PINA + #define DIO29_WPORT PORTA + #define DIO29_DDR DDRA + #define DIO29_PWM NULL + + #define DIO30_PIN PINC7 + #define DIO30_RPORT PINC + #define DIO30_WPORT PORTC + #define DIO30_DDR DDRC + #define DIO30_PWM NULL + + #define DIO31_PIN PINC6 + #define DIO31_RPORT PINC + #define DIO31_WPORT PORTC + #define DIO31_DDR DDRC + #define DIO31_PWM NULL + + #define DIO32_PIN PINC5 + #define DIO32_RPORT PINC + #define DIO32_WPORT PORTC + #define DIO32_DDR DDRC + #define DIO32_PWM NULL + + #define DIO33_PIN PINC4 + #define DIO33_RPORT PINC + #define DIO33_WPORT PORTC + #define DIO33_DDR DDRC + #define DIO33_PWM NULL + + #define DIO34_PIN PINC3 + #define DIO34_RPORT PINC + #define DIO34_WPORT PORTC + #define DIO34_DDR DDRC + #define DIO34_PWM NULL + + #define DIO35_PIN PINC2 + #define DIO35_RPORT PINC + #define DIO35_WPORT PORTC + #define DIO35_DDR DDRC + #define DIO35_PWM NULL + + #define DIO36_PIN PINC1 + #define DIO36_RPORT PINC + #define DIO36_WPORT PORTC + #define DIO36_DDR DDRC + #define DIO36_PWM NULL + + #define DIO37_PIN PINC0 + #define DIO37_RPORT PINC + #define DIO37_WPORT PORTC + #define DIO37_DDR DDRC + #define DIO37_PWM NULL + + #define DIO38_PIN PIND7 + #define DIO38_RPORT PIND + #define DIO38_WPORT PORTD + #define DIO38_DDR DDRD + #define DIO38_PWM NULL + + #define DIO39_PIN PING2 + #define DIO39_RPORT PING + #define DIO39_WPORT PORTG + #define DIO39_DDR DDRG + #define DIO39_PWM NULL + + #define DIO40_PIN PING1 + #define DIO40_RPORT PING + #define DIO40_WPORT PORTG + #define DIO40_DDR DDRG + #define DIO40_PWM NULL + + #define DIO41_PIN PING0 + #define DIO41_RPORT PING + #define DIO41_WPORT PORTG + #define DIO41_DDR DDRG + #define DIO41_PWM NULL + + #define DIO42_PIN PINL7 + #define DIO42_RPORT PINL + #define DIO42_WPORT PORTL + #define DIO42_DDR DDRL + #define DIO42_PWM NULL + + #define DIO43_PIN PINL6 + #define DIO43_RPORT PINL + #define DIO43_WPORT PORTL + #define DIO43_DDR DDRL + #define DIO43_PWM NULL + + #define DIO44_PIN PINL5 + #define DIO44_RPORT PINL + #define DIO44_WPORT PORTL + #define DIO44_DDR DDRL + #define DIO44_PWM &OCR5CL + + #define DIO45_PIN PINL4 + #define DIO45_RPORT PINL + #define DIO45_WPORT PORTL + #define DIO45_DDR DDRL + #define DIO45_PWM &OCR5BL + + #define DIO46_PIN PINL3 + #define DIO46_RPORT PINL + #define DIO46_WPORT PORTL + #define DIO46_DDR DDRL + #define DIO46_PWM &OCR5AL + + #define DIO47_PIN PINL2 + #define DIO47_RPORT PINL + #define DIO47_WPORT PORTL + #define DIO47_DDR DDRL + #define DIO47_PWM NULL + + #define DIO48_PIN PINL1 + #define DIO48_RPORT PINL + #define DIO48_WPORT PORTL + #define DIO48_DDR DDRL + #define DIO48_PWM NULL + + #define DIO49_PIN PINL0 + #define DIO49_RPORT PINL + #define DIO49_WPORT PORTL + #define DIO49_DDR DDRL + #define DIO49_PWM NULL + + #define DIO50_PIN PINB3 + #define DIO50_RPORT PINB + #define DIO50_WPORT PORTB + #define DIO50_DDR DDRB + #define DIO50_PWM NULL + + #define DIO51_PIN PINB2 + #define DIO51_RPORT PINB + #define DIO51_WPORT PORTB + #define DIO51_DDR DDRB + #define DIO51_PWM NULL + + #define DIO52_PIN PINB1 + #define DIO52_RPORT PINB + #define DIO52_WPORT PORTB + #define DIO52_DDR DDRB + #define DIO52_PWM NULL + + #define DIO53_PIN PINB0 + #define DIO53_RPORT PINB + #define DIO53_WPORT PORTB + #define DIO53_DDR DDRB + #define DIO53_PWM NULL + + #define DIO54_PIN PINF0 + #define DIO54_RPORT PINF + #define DIO54_WPORT PORTF + #define DIO54_DDR DDRF + #define DIO54_PWM NULL + + #define DIO55_PIN PINF1 + #define DIO55_RPORT PINF + #define DIO55_WPORT PORTF + #define DIO55_DDR DDRF + #define DIO55_PWM NULL + + #define DIO56_PIN PINF2 + #define DIO56_RPORT PINF + #define DIO56_WPORT PORTF + #define DIO56_DDR DDRF + #define DIO56_PWM NULL + + #define DIO57_PIN PINF3 + #define DIO57_RPORT PINF + #define DIO57_WPORT PORTF + #define DIO57_DDR DDRF + #define DIO57_PWM NULL + + #define DIO58_PIN PINF4 + #define DIO58_RPORT PINF + #define DIO58_WPORT PORTF + #define DIO58_DDR DDRF + #define DIO58_PWM NULL + + #define DIO59_PIN PINF5 + #define DIO59_RPORT PINF + #define DIO59_WPORT PORTF + #define DIO59_DDR DDRF + #define DIO59_PWM NULL + + #define DIO60_PIN PINF6 + #define DIO60_RPORT PINF + #define DIO60_WPORT PORTF + #define DIO60_DDR DDRF + #define DIO60_PWM NULL + + #define DIO61_PIN PINF7 + #define DIO61_RPORT PINF + #define DIO61_WPORT PORTF + #define DIO61_DDR DDRF + #define DIO61_PWM NULL + + #define DIO62_PIN PINK0 + #define DIO62_RPORT PINK + #define DIO62_WPORT PORTK + #define DIO62_DDR DDRK + #define DIO62_PWM NULL + + #define DIO63_PIN PINK1 + #define DIO63_RPORT PINK + #define DIO63_WPORT PORTK + #define DIO63_DDR DDRK + #define DIO63_PWM NULL + + #define DIO64_PIN PINK2 + #define DIO64_RPORT PINK + #define DIO64_WPORT PORTK + #define DIO64_DDR DDRK + #define DIO64_PWM NULL + + #define DIO65_PIN PINK3 + #define DIO65_RPORT PINK + #define DIO65_WPORT PORTK + #define DIO65_DDR DDRK + #define DIO65_PWM NULL + + #define DIO66_PIN PINK4 + #define DIO66_RPORT PINK + #define DIO66_WPORT PORTK + #define DIO66_DDR DDRK + #define DIO66_PWM NULL + + #define DIO67_PIN PINK5 + #define DIO67_RPORT PINK + #define DIO67_WPORT PORTK + #define DIO67_DDR DDRK + #define DIO67_PWM NULL + + #define DIO68_PIN PINK6 + #define DIO68_RPORT PINK + #define DIO68_WPORT PORTK + #define DIO68_DDR DDRK + #define DIO68_PWM NULL + + #define DIO69_PIN PINK7 + #define DIO69_RPORT PINK + #define DIO69_WPORT PORTK + #define DIO69_DDR DDRK + #define DIO69_PWM NULL + + #define DIO70_PIN PING4 + #define DIO70_RPORT PING + #define DIO70_WPORT PORTG + #define DIO70_DDR DDRG + #define DIO70_PWM NULL + + #define DIO71_PIN PING3 + #define DIO71_RPORT PING + #define DIO71_WPORT PORTG + #define DIO71_DDR DDRG + #define DIO71_PWM NULL + + #define DIO72_PIN PINJ2 + #define DIO72_RPORT PINJ + #define DIO72_WPORT PORTJ + #define DIO72_DDR DDRJ + #define DIO72_PWM NULL + + #define DIO73_PIN PINJ3 + #define DIO73_RPORT PINJ + #define DIO73_WPORT PORTJ + #define DIO73_DDR DDRJ + #define DIO73_PWM NULL + + #define DIO74_PIN PINJ7 + #define DIO74_RPORT PINJ + #define DIO74_WPORT PORTJ + #define DIO74_DDR DDRJ + #define DIO74_PWM NULL + + #define DIO75_PIN PINJ4 + #define DIO75_RPORT PINJ + #define DIO75_WPORT PORTJ + #define DIO75_DDR DDRJ + #define DIO75_PWM NULL + + #define DIO76_PIN PINJ5 + #define DIO76_RPORT PINJ + #define DIO76_WPORT PORTJ + #define DIO76_DDR DDRJ + #define DIO76_PWM NULL + + #define DIO77_PIN PINJ6 + #define DIO77_RPORT PINJ + #define DIO77_WPORT PORTJ + #define DIO77_DDR DDRJ + #define DIO77_PWM NULL + + #define DIO78_PIN PINE2 + #define DIO78_RPORT PINE + #define DIO78_WPORT PORTE + #define DIO78_DDR DDRE + #define DIO78_PWM NULL + + #define DIO79_PIN PINE6 + #define DIO79_RPORT PINE + #define DIO79_WPORT PORTE + #define DIO79_DDR DDRE + #define DIO79_PWM NULL + + #define DIO80_PIN PINE7 + #define DIO80_RPORT PINE + #define DIO80_WPORT PORTE + #define DIO80_DDR DDRE + #define DIO80_PWM NULL + + #define DIO81_PIN PIND4 + #define DIO81_RPORT PIND + #define DIO81_WPORT PORTD + #define DIO81_DDR DDRD + #define DIO81_PWM NULL + + #define DIO82_PIN PIND5 + #define DIO82_RPORT PIND + #define DIO82_WPORT PORTD + #define DIO82_DDR DDRD + #define DIO82_PWM NULL + + #define DIO83_PIN PIND6 + #define DIO83_RPORT PIND + #define DIO83_WPORT PORTD + #define DIO83_DDR DDRD + #define DIO83_PWM NULL + + #define DIO84_PIN PINH2 + #define DIO84_RPORT PINH + #define DIO84_WPORT PORTH + #define DIO84_DDR DDRH + #define DIO84_PWM NULL + + #define DIO85_PIN PINH7 + #define DIO85_RPORT PINH + #define DIO85_WPORT PORTH + #define DIO85_DDR DDRH + #define DIO85_PWM NULL + + #undef PA0 + #define PA0_PIN PINA0 + #define PA0_RPORT PINA + #define PA0_WPORT PORTA + #define PA0_DDR DDRA + #define PA0_PWM NULL + #undef PA1 + #define PA1_PIN PINA1 + #define PA1_RPORT PINA + #define PA1_WPORT PORTA + #define PA1_DDR DDRA + #define PA1_PWM NULL + #undef PA2 + #define PA2_PIN PINA2 + #define PA2_RPORT PINA + #define PA2_WPORT PORTA + #define PA2_DDR DDRA + #define PA2_PWM NULL + #undef PA3 + #define PA3_PIN PINA3 + #define PA3_RPORT PINA + #define PA3_WPORT PORTA + #define PA3_DDR DDRA + #define PA3_PWM NULL + #undef PA4 + #define PA4_PIN PINA4 + #define PA4_RPORT PINA + #define PA4_WPORT PORTA + #define PA4_DDR DDRA + #define PA4_PWM NULL + #undef PA5 + #define PA5_PIN PINA5 + #define PA5_RPORT PINA + #define PA5_WPORT PORTA + #define PA5_DDR DDRA + #define PA5_PWM NULL + #undef PA6 + #define PA6_PIN PINA6 + #define PA6_RPORT PINA + #define PA6_WPORT PORTA + #define PA6_DDR DDRA + #define PA6_PWM NULL + #undef PA7 + #define PA7_PIN PINA7 + #define PA7_RPORT PINA + #define PA7_WPORT PORTA + #define PA7_DDR DDRA + #define PA7_PWM NULL + + #undef PB0 + #define PB0_PIN PINB0 + #define PB0_RPORT PINB + #define PB0_WPORT PORTB + #define PB0_DDR DDRB + #define PB0_PWM NULL + #undef PB1 + #define PB1_PIN PINB1 + #define PB1_RPORT PINB + #define PB1_WPORT PORTB + #define PB1_DDR DDRB + #define PB1_PWM NULL + #undef PB2 + #define PB2_PIN PINB2 + #define PB2_RPORT PINB + #define PB2_WPORT PORTB + #define PB2_DDR DDRB + #define PB2_PWM NULL + #undef PB3 + #define PB3_PIN PINB3 + #define PB3_RPORT PINB + #define PB3_WPORT PORTB + #define PB3_DDR DDRB + #define PB3_PWM NULL + #undef PB4 + #define PB4_PIN PINB4 + #define PB4_RPORT PINB + #define PB4_WPORT PORTB + #define PB4_DDR DDRB + #define PB4_PWM &OCR2A + #undef PB5 + #define PB5_PIN PINB5 + #define PB5_RPORT PINB + #define PB5_WPORT PORTB + #define PB5_DDR DDRB + #define PB5_PWM NULL + #undef PB6 + #define PB6_PIN PINB6 + #define PB6_RPORT PINB + #define PB6_WPORT PORTB + #define PB6_DDR DDRB + #define PB6_PWM NULL + #undef PB7 + #define PB7_PIN PINB7 + #define PB7_RPORT PINB + #define PB7_WPORT PORTB + #define PB7_DDR DDRB + #define PB7_PWM &OCR0A + + #undef PC0 + #define PC0_PIN PINC0 + #define PC0_RPORT PINC + #define PC0_WPORT PORTC + #define PC0_DDR DDRC + #define PC0_PWM NULL + #undef PC1 + #define PC1_PIN PINC1 + #define PC1_RPORT PINC + #define PC1_WPORT PORTC + #define PC1_DDR DDRC + #define PC1_PWM NULL + #undef PC2 + #define PC2_PIN PINC2 + #define PC2_RPORT PINC + #define PC2_WPORT PORTC + #define PC2_DDR DDRC + #define PC2_PWM NULL + #undef PC3 + #define PC3_PIN PINC3 + #define PC3_RPORT PINC + #define PC3_WPORT PORTC + #define PC3_DDR DDRC + #define PC3_PWM NULL + #undef PC4 + #define PC4_PIN PINC4 + #define PC4_RPORT PINC + #define PC4_WPORT PORTC + #define PC4_DDR DDRC + #define PC4_PWM NULL + #undef PC5 + #define PC5_PIN PINC5 + #define PC5_RPORT PINC + #define PC5_WPORT PORTC + #define PC5_DDR DDRC + #define PC5_PWM NULL + #undef PC6 + #define PC6_PIN PINC6 + #define PC6_RPORT PINC + #define PC6_WPORT PORTC + #define PC6_DDR DDRC + #define PC6_PWM NULL + #undef PC7 + #define PC7_PIN PINC7 + #define PC7_RPORT PINC + #define PC7_WPORT PORTC + #define PC7_DDR DDRC + #define PC7_PWM NULL + + #undef PD0 + #define PD0_PIN PIND0 + #define PD0_RPORT PIND + #define PD0_WPORT PORTD + #define PD0_DDR DDRD + #define PD0_PWM NULL + #undef PD1 + #define PD1_PIN PIND1 + #define PD1_RPORT PIND + #define PD1_WPORT PORTD + #define PD1_DDR DDRD + #define PD1_PWM NULL + #undef PD2 + #define PD2_PIN PIND2 + #define PD2_RPORT PIND + #define PD2_WPORT PORTD + #define PD2_DDR DDRD + #define PD2_PWM NULL + #undef PD3 + #define PD3_PIN PIND3 + #define PD3_RPORT PIND + #define PD3_WPORT PORTD + #define PD3_DDR DDRD + #define PD3_PWM NULL + #undef PD4 + #define PD4_PIN PIND4 + #define PD4_RPORT PIND + #define PD4_WPORT PORTD + #define PD4_DDR DDRD + #define PD4_PWM NULL + #undef PD5 + #define PD5_PIN PIND5 + #define PD5_RPORT PIND + #define PD5_WPORT PORTD + #define PD5_DDR DDRD + #define PD5_PWM NULL + #undef PD6 + #define PD6_PIN PIND6 + #define PD6_RPORT PIND + #define PD6_WPORT PORTD + #define PD6_DDR DDRD + #define PD6_PWM NULL + #undef PD7 + #define PD7_PIN PIND7 + #define PD7_RPORT PIND + #define PD7_WPORT PORTD + #define PD7_DDR DDRD + #define PD7_PWM NULL + + #undef PE0 + #define PE0_PIN PINE0 + #define PE0_RPORT PINE + #define PE0_WPORT PORTE + #define PE0_DDR DDRE + #define PE0_PWM NULL + #undef PE1 + #define PE1_PIN PINE1 + #define PE1_RPORT PINE + #define PE1_WPORT PORTE + #define PE1_DDR DDRE + #define PE1_PWM NULL + #undef PE2 + #define PE2_PIN PINE2 + #define PE2_RPORT PINE + #define PE2_WPORT PORTE + #define PE2_DDR DDRE + #define PE2_PWM NULL + #undef PE3 + #define PE3_PIN PINE3 + #define PE3_RPORT PINE + #define PE3_WPORT PORTE + #define PE3_DDR DDRE + #define PE3_PWM &OCR3AL + #undef PE4 + #define PE4_PIN PINE4 + #define PE4_RPORT PINE + #define PE4_WPORT PORTE + #define PE4_DDR DDRE + #define PE4_PWM &OCR3BL + #undef PE5 + #define PE5_PIN PINE5 + #define PE5_RPORT PINE + #define PE5_WPORT PORTE + #define PE5_DDR DDRE + #define PE5_PWM &OCR3CL + #undef PE6 + #define PE6_PIN PINE6 + #define PE6_RPORT PINE + #define PE6_WPORT PORTE + #define PE6_DDR DDRE + #define PE6_PWM NULL + #undef PE7 + #define PE7_PIN PINE7 + #define PE7_RPORT PINE + #define PE7_WPORT PORTE + #define PE7_DDR DDRE + #define PE7_PWM NULL + + #undef PF0 + #define PF0_PIN PINF0 + #define PF0_RPORT PINF + #define PF0_WPORT PORTF + #define PF0_DDR DDRF + #define PF0_PWM NULL + #undef PF1 + #define PF1_PIN PINF1 + #define PF1_RPORT PINF + #define PF1_WPORT PORTF + #define PF1_DDR DDRF + #define PF1_PWM NULL + #undef PF2 + #define PF2_PIN PINF2 + #define PF2_RPORT PINF + #define PF2_WPORT PORTF + #define PF2_DDR DDRF + #define PF2_PWM NULL + #undef PF3 + #define PF3_PIN PINF3 + #define PF3_RPORT PINF + #define PF3_WPORT PORTF + #define PF3_DDR DDRF + #define PF3_PWM NULL + #undef PF4 + #define PF4_PIN PINF4 + #define PF4_RPORT PINF + #define PF4_WPORT PORTF + #define PF4_DDR DDRF + #define PF4_PWM NULL + #undef PF5 + #define PF5_PIN PINF5 + #define PF5_RPORT PINF + #define PF5_WPORT PORTF + #define PF5_DDR DDRF + #define PF5_PWM NULL + #undef PF6 + #define PF6_PIN PINF6 + #define PF6_RPORT PINF + #define PF6_WPORT PORTF + #define PF6_DDR DDRF + #define PF6_PWM NULL + #undef PF7 + #define PF7_PIN PINF7 + #define PF7_RPORT PINF + #define PF7_WPORT PORTF + #define PF7_DDR DDRF + #define PF7_PWM NULL + + #undef PG0 + #define PG0_PIN PING0 + #define PG0_RPORT PING + #define PG0_WPORT PORTG + #define PG0_DDR DDRG + #define PG0_PWM NULL + #undef PG1 + #define PG1_PIN PING1 + #define PG1_RPORT PING + #define PG1_WPORT PORTG + #define PG1_DDR DDRG + #define PG1_PWM NULL + #undef PG2 + #define PG2_PIN PING2 + #define PG2_RPORT PING + #define PG2_WPORT PORTG + #define PG2_DDR DDRG + #define PG2_PWM NULL + #undef PG3 + #define PG3_PIN PING3 + #define PG3_RPORT PING + #define PG3_WPORT PORTG + #define PG3_DDR DDRG + #define PG3_PWM NULL + #undef PG4 + #define PG4_PIN PING4 + #define PG4_RPORT PING + #define PG4_WPORT PORTG + #define PG4_DDR DDRG + #define PG4_PWM NULL + #undef PG5 + #define PG5_PIN PING5 + #define PG5_RPORT PING + #define PG5_WPORT PORTG + #define PG5_DDR DDRG + #define PG5_PWM &OCR0B + #undef PG6 + #define PG6_PIN PING6 + #define PG6_RPORT PING + #define PG6_WPORT PORTG + #define PG6_DDR DDRG + #define PG6_PWM NULL + #undef PG7 + #define PG7_PIN PING7 + #define PG7_RPORT PING + #define PG7_WPORT PORTG + #define PG7_DDR DDRG + #define PG7_PWM NULL + + #undef PH0 + #define PH0_PIN PINH0 + #define PH0_RPORT PINH + #define PH0_WPORT PORTH + #define PH0_DDR DDRH + #define PH0_PWM NULL + #undef PH1 + #define PH1_PIN PINH1 + #define PH1_RPORT PINH + #define PH1_WPORT PORTH + #define PH1_DDR DDRH + #define PH1_PWM NULL + #undef PH2 + #define PH2_PIN PINH2 + #define PH2_RPORT PINH + #define PH2_WPORT PORTH + #define PH2_DDR DDRH + #define PH2_PWM NULL + #undef PH3 + #define PH3_PIN PINH3 + #define PH3_RPORT PINH + #define PH3_WPORT PORTH + #define PH3_DDR DDRH + #define PH3_PWM &OCR4AL + #undef PH4 + #define PH4_PIN PINH4 + #define PH4_RPORT PINH + #define PH4_WPORT PORTH + #define PH4_DDR DDRH + #define PH4_PWM &OCR4BL + #undef PH5 + #define PH5_PIN PINH5 + #define PH5_RPORT PINH + #define PH5_WPORT PORTH + #define PH5_DDR DDRH + #define PH5_PWM &OCR4CL + #undef PH6 + #define PH6_PIN PINH6 + #define PH6_RPORT PINH + #define PH6_WPORT PORTH + #define PH6_DDR DDRH + #define PH6_PWM &OCR2B + #undef PH7 + #define PH7_PIN PINH7 + #define PH7_RPORT PINH + #define PH7_WPORT PORTH + #define PH7_DDR DDRH + #define PH7_PWM NULL + + #undef PJ0 + #define PJ0_PIN PINJ0 + #define PJ0_RPORT PINJ + #define PJ0_WPORT PORTJ + #define PJ0_DDR DDRJ + #define PJ0_PWM NULL + #undef PJ1 + #define PJ1_PIN PINJ1 + #define PJ1_RPORT PINJ + #define PJ1_WPORT PORTJ + #define PJ1_DDR DDRJ + #define PJ1_PWM NULL + #undef PJ2 + #define PJ2_PIN PINJ2 + #define PJ2_RPORT PINJ + #define PJ2_WPORT PORTJ + #define PJ2_DDR DDRJ + #define PJ2_PWM NULL + #undef PJ3 + #define PJ3_PIN PINJ3 + #define PJ3_RPORT PINJ + #define PJ3_WPORT PORTJ + #define PJ3_DDR DDRJ + #define PJ3_PWM NULL + #undef PJ4 + #define PJ4_PIN PINJ4 + #define PJ4_RPORT PINJ + #define PJ4_WPORT PORTJ + #define PJ4_DDR DDRJ + #define PJ4_PWM NULL + #undef PJ5 + #define PJ5_PIN PINJ5 + #define PJ5_RPORT PINJ + #define PJ5_WPORT PORTJ + #define PJ5_DDR DDRJ + #define PJ5_PWM NULL + #undef PJ6 + #define PJ6_PIN PINJ6 + #define PJ6_RPORT PINJ + #define PJ6_WPORT PORTJ + #define PJ6_DDR DDRJ + #define PJ6_PWM NULL + #undef PJ7 + #define PJ7_PIN PINJ7 + #define PJ7_RPORT PINJ + #define PJ7_WPORT PORTJ + #define PJ7_DDR DDRJ + #define PJ7_PWM NULL + + #undef PK0 + #define PK0_PIN PINK0 + #define PK0_RPORT PINK + #define PK0_WPORT PORTK + #define PK0_DDR DDRK + #define PK0_PWM NULL + #undef PK1 + #define PK1_PIN PINK1 + #define PK1_RPORT PINK + #define PK1_WPORT PORTK + #define PK1_DDR DDRK + #define PK1_PWM NULL + #undef PK2 + #define PK2_PIN PINK2 + #define PK2_RPORT PINK + #define PK2_WPORT PORTK + #define PK2_DDR DDRK + #define PK2_PWM NULL + #undef PK3 + #define PK3_PIN PINK3 + #define PK3_RPORT PINK + #define PK3_WPORT PORTK + #define PK3_DDR DDRK + #define PK3_PWM NULL + #undef PK4 + #define PK4_PIN PINK4 + #define PK4_RPORT PINK + #define PK4_WPORT PORTK + #define PK4_DDR DDRK + #define PK4_PWM NULL + #undef PK5 + #define PK5_PIN PINK5 + #define PK5_RPORT PINK + #define PK5_WPORT PORTK + #define PK5_DDR DDRK + #define PK5_PWM NULL + #undef PK6 + #define PK6_PIN PINK6 + #define PK6_RPORT PINK + #define PK6_WPORT PORTK + #define PK6_DDR DDRK + #define PK6_PWM NULL + #undef PK7 + #define PK7_PIN PINK7 + #define PK7_RPORT PINK + #define PK7_WPORT PORTK + #define PK7_DDR DDRK + #define PK7_PWM NULL + + #undef PL0 + #define PL0_PIN PINL0 + #define PL0_RPORT PINL + #define PL0_WPORT PORTL + #define PL0_DDR DDRL + #define PL0_PWM NULL + #undef PL1 + #define PL1_PIN PINL1 + #define PL1_RPORT PINL + #define PL1_WPORT PORTL + #define PL1_DDR DDRL + #define PL1_PWM NULL + #undef PL2 + #define PL2_PIN PINL2 + #define PL2_RPORT PINL + #define PL2_WPORT PORTL + #define PL2_DDR DDRL + #define PL2_PWM NULL + #undef PL3 + #define PL3_PIN PINL3 + #define PL3_RPORT PINL + #define PL3_WPORT PORTL + #define PL3_DDR DDRL + #define PL3_PWM &OCR5AL + #undef PL4 + #define PL4_PIN PINL4 + #define PL4_RPORT PINL + #define PL4_WPORT PORTL + #define PL4_DDR DDRL + #define PL4_PWM &OCR5BL + #undef PL5 + #define PL5_PIN PINL5 + #define PL5_RPORT PINL + #define PL5_WPORT PORTL + #define PL5_DDR DDRL + #define PL5_PWM &OCR5CL + #undef PL6 + #define PL6_PIN PINL6 + #define PL6_RPORT PINL + #define PL6_WPORT PORTL + #define PL6_DDR DDRL + #define PL6_PWM NULL + #undef PL7 + #define PL7_PIN PINL7 + #define PL7_RPORT PINL + #define PL7_WPORT PORTL + #define PL7_DDR DDRL + #define PL7_PWM NULL + +#endif + +#if defined(__AVR_AT90USB1287__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) + + // change for your board + #define DEBUG_LED DIO31 /* led D5 red */ + + /** + pins + */ + + //#define AT90USBxx_TEENSYPP_ASSIGNMENTS // Use Teensy++ 2.0 assignments + #ifndef AT90USBxx_TEENSYPP_ASSIGNMENTS // Use traditional Marlin pin assignments + + // SPI + #define SCK DIO9 // 21 + #define MISO DIO11 // 23 + #define MOSI DIO10 // 22 + #define SS DIO8 // 20 + + #define DIO0_PIN PINA0 + #define DIO0_RPORT PINA + #define DIO0_WPORT PORTA + #define DIO0_PWM NULL + #define DIO0_DDR DDRA + + #define DIO1_PIN PINA1 + #define DIO1_RPORT PINA + #define DIO1_WPORT PORTA + #define DIO1_PWM NULL + #define DIO1_DDR DDRA + + #define DIO2_PIN PINA2 + #define DIO2_RPORT PINA + #define DIO2_WPORT PORTA + #define DIO2_PWM NULL + #define DIO2_DDR DDRA + + #define DIO3_PIN PINA3 + #define DIO3_RPORT PINA + #define DIO3_WPORT PORTA + #define DIO3_PWM NULL + #define DIO3_DDR DDRA + + #define DIO4_PIN PINA4 + #define DIO4_RPORT PINA + #define DIO4_WPORT PORTA + #define DIO4_PWM NULL + #define DIO4_DDR DDRA + + #define DIO5_PIN PINA5 + #define DIO5_RPORT PINA + #define DIO5_WPORT PORTA + #define DIO5_PWM NULL + #define DIO5_DDR DDRA + + #define DIO6_PIN PINA6 + #define DIO6_RPORT PINA + #define DIO6_WPORT PORTA + #define DIO6_PWM NULL + #define DIO6_DDR DDRA + + #define DIO7_PIN PINA7 + #define DIO7_RPORT PINA + #define DIO7_WPORT PORTA + #define DIO7_PWM NULL + #define DIO7_DDR DDRA + + #define DIO8_PIN PINB0 + #define DIO8_RPORT PINB + #define DIO8_WPORT PORTB + #define DIO8_PWM NULL + #define DIO8_DDR DDRB + + #define DIO9_PIN PINB1 + #define DIO9_RPORT PINB + #define DIO9_WPORT PORTB + #define DIO9_PWM NULL + #define DIO9_DDR DDRB + + #define DIO10_PIN PINB2 + #define DIO10_RPORT PINB + #define DIO10_WPORT PORTB + #define DIO10_PWM NULL + #define DIO10_DDR DDRB + + #define DIO11_PIN PINB3 + #define DIO11_RPORT PINB + #define DIO11_WPORT PORTB + #define DIO11_PWM NULL + #define DIO11_DDR DDRB + + #define DIO12_PIN PINB4 + #define DIO12_RPORT PINB + #define DIO12_WPORT PORTB + #define DIO12_PWM NULL + #define DIO12_DDR DDRB + + #define DIO13_PIN PINB5 + #define DIO13_RPORT PINB + #define DIO13_WPORT PORTB + #define DIO13_PWM NULL + #define DIO13_DDR DDRB + + #define DIO14_PIN PINB6 + #define DIO14_RPORT PINB + #define DIO14_WPORT PORTB + #define DIO14_PWM NULL + #define DIO14_DDR DDRB + + #define DIO15_PIN PINB7 + #define DIO15_RPORT PINB + #define DIO15_WPORT PORTB + #define DIO15_PWM NULL + #define DIO15_DDR DDRB + + #define DIO16_PIN PINC0 + #define DIO16_RPORT PINC + #define DIO16_WPORT PORTC + #define DIO16_PWM NULL + #define DIO16_DDR DDRC + + #define DIO17_PIN PINC1 + #define DIO17_RPORT PINC + #define DIO17_WPORT PORTC + #define DIO17_PWM NULL + #define DIO17_DDR DDRC + + #define DIO18_PIN PINC2 + #define DIO18_RPORT PINC + #define DIO18_WPORT PORTC + #define DIO18_PWM NULL + #define DIO18_DDR DDRC + + #define DIO19_PIN PINC3 + #define DIO19_RPORT PINC + #define DIO19_WPORT PORTC + #define DIO19_PWM NULL + #define DIO19_DDR DDRC + + #define DIO20_PIN PINC4 + #define DIO20_RPORT PINC + #define DIO20_WPORT PORTC + #define DIO20_PWM NULL + #define DIO20_DDR DDRC + + #define DIO21_PIN PINC5 + #define DIO21_RPORT PINC + #define DIO21_WPORT PORTC + #define DIO21_PWM NULL + #define DIO21_DDR DDRC + + #define DIO22_PIN PINC6 + #define DIO22_RPORT PINC + #define DIO22_WPORT PORTC + #define DIO22_PWM NULL + #define DIO22_DDR DDRC + + #define DIO23_PIN PINC7 + #define DIO23_RPORT PINC + #define DIO23_WPORT PORTC + #define DIO23_PWM NULL + #define DIO23_DDR DDRC + + #define DIO24_PIN PIND0 + #define DIO24_RPORT PIND + #define DIO24_WPORT PORTD + #define DIO24_PWM NULL + #define DIO24_DDR DDRD + + #define DIO25_PIN PIND1 + #define DIO25_RPORT PIND + #define DIO25_WPORT PORTD + #define DIO25_PWM NULL + #define DIO25_DDR DDRD + + #define DIO26_PIN PIND2 + #define DIO26_RPORT PIND + #define DIO26_WPORT PORTD + #define DIO26_PWM NULL + #define DIO26_DDR DDRD + + #define DIO27_PIN PIND3 + #define DIO27_RPORT PIND + #define DIO27_WPORT PORTD + #define DIO27_PWM NULL + #define DIO27_DDR DDRD + + #define DIO28_PIN PIND4 + #define DIO28_RPORT PIND + #define DIO28_WPORT PORTD + #define DIO28_PWM NULL + #define DIO28_DDR DDRD + + #define DIO29_PIN PIND5 + #define DIO29_RPORT PIND + #define DIO29_WPORT PORTD + #define DIO29_PWM NULL + #define DIO29_DDR DDRD + + #define DIO30_PIN PIND6 + #define DIO30_RPORT PIND + #define DIO30_WPORT PORTD + #define DIO30_PWM NULL + #define DIO30_DDR DDRD + + #define DIO31_PIN PIND7 + #define DIO31_RPORT PIND + #define DIO31_WPORT PORTD + #define DIO31_PWM NULL + #define DIO31_DDR DDRD + + + #define DIO32_PIN PINE0 + #define DIO32_RPORT PINE + #define DIO32_WPORT PORTE + #define DIO32_PWM NULL + #define DIO32_DDR DDRE + + #define DIO33_PIN PINE1 + #define DIO33_RPORT PINE + #define DIO33_WPORT PORTE + #define DIO33_PWM NULL + #define DIO33_DDR DDRE + + #define DIO34_PIN PINE2 + #define DIO34_RPORT PINE + #define DIO34_WPORT PORTE + #define DIO34_PWM NULL + #define DIO34_DDR DDRE + + #define DIO35_PIN PINE3 + #define DIO35_RPORT PINE + #define DIO35_WPORT PORTE + #define DIO35_PWM NULL + #define DIO35_DDR DDRE + + #define DIO36_PIN PINE4 + #define DIO36_RPORT PINE + #define DIO36_WPORT PORTE + #define DIO36_PWM NULL + #define DIO36_DDR DDRE + + #define DIO37_PIN PINE5 + #define DIO37_RPORT PINE + #define DIO37_WPORT PORTE + #define DIO37_PWM NULL + #define DIO37_DDR DDRE + + #define DIO38_PIN PINE6 + #define DIO38_RPORT PINE + #define DIO38_WPORT PORTE + #define DIO38_PWM NULL + #define DIO38_DDR DDRE + + #define DIO39_PIN PINE7 + #define DIO39_RPORT PINE + #define DIO39_WPORT PORTE + #define DIO39_PWM NULL + #define DIO39_DDR DDRE + + #define AIO0_PIN PINF0 + #define AIO0_RPORT PINF + #define AIO0_WPORT PORTF + #define AIO0_PWM NULL + #define AIO0_DDR DDRF + + #define AIO1_PIN PINF1 + #define AIO1_RPORT PINF + #define AIO1_WPORT PORTF + #define AIO1_PWM NULL + #define AIO1_DDR DDRF + + #define AIO2_PIN PINF2 + #define AIO2_RPORT PINF + #define AIO2_WPORT PORTF + #define AIO2_PWM NULL + #define AIO2_DDR DDRF + + #define AIO3_PIN PINF3 + #define AIO3_RPORT PINF + #define AIO3_WPORT PORTF + #define AIO3_PWM NULL + #define AIO3_DDR DDRF + + #define AIO4_PIN PINF4 + #define AIO4_RPORT PINF + #define AIO4_WPORT PORTF + #define AIO4_PWM NULL + #define AIO4_DDR DDRF + + #define AIO5_PIN PINF5 + #define AIO5_RPORT PINF + #define AIO5_WPORT PORTF + #define AIO5_PWM NULL + #define AIO5_DDR DDRF + + #define AIO6_PIN PINF6 + #define AIO6_RPORT PINF + #define AIO6_WPORT PORTF + #define AIO6_PWM NULL + #define AIO6_DDR DDRF + + #define AIO7_PIN PINF7 + #define AIO7_RPORT PINF + #define AIO7_WPORT PORTF + #define AIO7_PWM NULL + #define AIO7_DDR DDRF + + #define DIO40_PIN PINF0 + #define DIO40_RPORT PINF + #define DIO40_WPORT PORTF + #define DIO40_PWM NULL + #define DIO40_DDR DDRF + + #define DIO41_PIN PINF1 + #define DIO41_RPORT PINF + #define DIO41_WPORT PORTF + #define DIO41_PWM NULL + #define DIO41_DDR DDRF + + #define DIO42_PIN PINF2 + #define DIO42_RPORT PINF + #define DIO42_WPORT PORTF + #define DIO42_PWM NULL + #define DIO42_DDR DDRF + + #define DIO43_PIN PINF3 + #define DIO43_RPORT PINF + #define DIO43_WPORT PORTF + #define DIO43_PWM NULL + #define DIO43_DDR DDRF + + #define DIO44_PIN PINF4 + #define DIO44_RPORT PINF + #define DIO44_WPORT PORTF + #define DIO44_PWM NULL + #define DIO44_DDR DDRF + + #define DIO45_PIN PINF5 + #define DIO45_RPORT PINF + #define DIO45_WPORT PORTF + #define DIO45_PWM NULL + #define DIO45_DDR DDRF + + #define DIO46_PIN PINF6 + #define DIO46_RPORT PINF + #define DIO46_WPORT PORTF + #define DIO46_PWM NULL + #define DIO46_DDR DDRF + + #define DIO47_PIN PINF7 + #define DIO47_RPORT PINF + #define DIO47_WPORT PORTF + #define DIO47_PWM NULL + #define DIO47_DDR DDRF + + + + #undef PA0 + #define PA0_PIN PINA0 + #define PA0_RPORT PINA + #define PA0_WPORT PORTA + #define PA0_PWM NULL + #define PA0_DDR DDRA + #undef PA1 + #define PA1_PIN PINA1 + #define PA1_RPORT PINA + #define PA1_WPORT PORTA + #define PA1_PWM NULL + #define PA1_DDR DDRA + #undef PA2 + #define PA2_PIN PINA2 + #define PA2_RPORT PINA + #define PA2_WPORT PORTA + #define PA2_PWM NULL + #define PA2_DDR DDRA + #undef PA3 + #define PA3_PIN PINA3 + #define PA3_RPORT PINA + #define PA3_WPORT PORTA + #define PA3_PWM NULL + #define PA3_DDR DDRA + #undef PA4 + #define PA4_PIN PINA4 + #define PA4_RPORT PINA + #define PA4_WPORT PORTA + #define PA4_PWM NULL + #define PA4_DDR DDRA + #undef PA5 + #define PA5_PIN PINA5 + #define PA5_RPORT PINA + #define PA5_WPORT PORTA + #define PA5_PWM NULL + #define PA5_DDR DDRA + #undef PA6 + #define PA6_PIN PINA6 + #define PA6_RPORT PINA + #define PA6_WPORT PORTA + #define PA6_PWM NULL + #define PA6_DDR DDRA + #undef PA7 + #define PA7_PIN PINA7 + #define PA7_RPORT PINA + #define PA7_WPORT PORTA + #define PA7_PWM NULL + #define PA7_DDR DDRA + + #undef PB0 + #define PB0_PIN PINB0 + #define PB0_RPORT PINB + #define PB0_WPORT PORTB + #define PB0_PWM NULL + #define PB0_DDR DDRB + #undef PB1 + #define PB1_PIN PINB1 + #define PB1_RPORT PINB + #define PB1_WPORT PORTB + #define PB1_PWM NULL + #define PB1_DDR DDRB + #undef PB2 + #define PB2_PIN PINB2 + #define PB2_RPORT PINB + #define PB2_WPORT PORTB + #define PB2_PWM NULL + #define PB2_DDR DDRB + #undef PB3 + #define PB3_PIN PINB3 + #define PB3_RPORT PINB + #define PB3_WPORT PORTB + #define PB3_PWM NULL + #define PB3_DDR DDRB + #undef PB4 + #define PB4_PIN PINB4 + #define PB4_RPORT PINB + #define PB4_WPORT PORTB + #define PB4_PWM NULL + #define PB4_DDR DDRB + #undef PB5 + #define PB5_PIN PINB5 + #define PB5_RPORT PINB + #define PB5_WPORT PORTB + #define PB5_PWM NULL + #define PB5_DDR DDRB + #undef PB6 + #define PB6_PIN PINB6 + #define PB6_RPORT PINB + #define PB6_WPORT PORTB + #define PB6_PWM NULL + #define PB6_DDR DDRB + #undef PB7 + #define PB7_PIN PINB7 + #define PB7_RPORT PINB + #define PB7_WPORT PORTB + #define PB7_PWM NULL + #define PB7_DDR DDRB + + #undef PC0 + #define PC0_PIN PINC0 + #define PC0_RPORT PINC + #define PC0_WPORT PORTC + #define PC0_PWM NULL + #define PC0_DDR DDRC + #undef PC1 + #define PC1_PIN PINC1 + #define PC1_RPORT PINC + #define PC1_WPORT PORTC + #define PC1_PWM NULL + #define PC1_DDR DDRC + #undef PC2 + #define PC2_PIN PINC2 + #define PC2_RPORT PINC + #define PC2_WPORT PORTC + #define PC2_PWM NULL + #define PC2_DDR DDRC + #undef PC3 + #define PC3_PIN PINC3 + #define PC3_RPORT PINC + #define PC3_WPORT PORTC + #define PC3_PWM NULL + #define PC3_DDR DDRC + #undef PC4 + #define PC4_PIN PINC4 + #define PC4_RPORT PINC + #define PC4_WPORT PORTC + #define PC4_PWM NULL + #define PC4_DDR DDRC + #undef PC5 + #define PC5_PIN PINC5 + #define PC5_RPORT PINC + #define PC5_WPORT PORTC + #define PC5_PWM NULL + #define PC5_DDR DDRC + #undef PC6 + #define PC6_PIN PINC6 + #define PC6_RPORT PINC + #define PC6_WPORT PORTC + #define PC6_PWM NULL + #define PC6_DDR DDRC + #undef PC7 + #define PC7_PIN PINC7 + #define PC7_RPORT PINC + #define PC7_WPORT PORTC + #define PC7_PWM NULL + #define PC7_DDR DDRC + + #undef PD0 + #define PD0_PIN PIND0 + #define PD0_RPORT PIND + #define PD0_WPORT PORTD + #define PD0_PWM NULL + #define PD0_DDR DDRD + #undef PD1 + #define PD1_PIN PIND1 + #define PD1_RPORT PIND + #define PD1_WPORT PORTD + #define PD1_PWM NULL + #define PD1_DDR DDRD + #undef PD2 + #define PD2_PIN PIND2 + #define PD2_RPORT PIND + #define PD2_WPORT PORTD + #define PD2_PWM NULL + #define PD2_DDR DDRD + #undef PD3 + #define PD3_PIN PIND3 + #define PD3_RPORT PIND + #define PD3_WPORT PORTD + #define PD3_PWM NULL + #define PD3_DDR DDRD + #undef PD4 + #define PD4_PIN PIND4 + #define PD4_RPORT PIND + #define PD4_WPORT PORTD + #define PD4_PWM NULL + #define PD4_DDR DDRD + #undef PD5 + #define PD5_PIN PIND5 + #define PD5_RPORT PIND + #define PD5_WPORT PORTD + #define PD5_PWM NULL + #define PD5_DDR DDRD + #undef PD6 + #define PD6_PIN PIND6 + #define PD6_RPORT PIND + #define PD6_WPORT PORTD + #define PD6_PWM NULL + #define PD6_DDR DDRD + #undef PD7 + #define PD7_PIN PIND7 + #define PD7_RPORT PIND + #define PD7_WPORT PORTD + #define PD7_PWM NULL + #define PD7_DDR DDRD + + #undef PE0 + #define PE0_PIN PINE0 + #define PE0_RPORT PINE + #define PE0_WPORT PORTE + #define PE0_PWM NULL + #define PE0_DDR DDRE + #undef PE1 + #define PE1_PIN PINE1 + #define PE1_RPORT PINE + #define PE1_WPORT PORTE + #define PE1_PWM NULL + #define PE1_DDR DDRE + #undef PE2 + #define PE2_PIN PINE2 + #define PE2_RPORT PINE + #define PE2_WPORT PORTE + #define PE2_PWM NULL + #define PE2_DDR DDRE + #undef PE3 + #define PE3_PIN PINE3 + #define PE3_RPORT PINE + #define PE3_WPORT PORTE + #define PE3_PWM NULL + #define PE3_DDR DDRE + #undef PE4 + #define PE4_PIN PINE4 + #define PE4_RPORT PINE + #define PE4_WPORT PORTE + #define PE4_PWM NULL + #define PE4_DDR DDRE + #undef PE5 + #define PE5_PIN PINE5 + #define PE5_RPORT PINE + #define PE5_WPORT PORTE + #define PE5_PWM NULL + #define PE5_DDR DDRE + #undef PE6 + #define PE6_PIN PINE6 + #define PE6_RPORT PINE + #define PE6_WPORT PORTE + #define PE6_PWM NULL + #define PE6_DDR DDRE + #undef PE7 + #define PE7_PIN PINE7 + #define PE7_RPORT PINE + #define PE7_WPORT PORTE + #define PE7_PWM NULL + #define PE7_DDR DDRE + + #undef PF0 + #define PF0_PIN PINF0 + #define PF0_RPORT PINF + #define PF0_WPORT PORTF + #define PF0_PWM NULL + #define PF0_DDR DDRF + #undef PF1 + #define PF1_PIN PINF1 + #define PF1_RPORT PINF + #define PF1_WPORT PORTF + #define PF1_PWM NULL + #define PF1_DDR DDRF + #undef PF2 + #define PF2_PIN PINF2 + #define PF2_RPORT PINF + #define PF2_WPORT PORTF + #define PF2_PWM NULL + #define PF2_DDR DDRF + #undef PF3 + #define PF3_PIN PINF3 + #define PF3_RPORT PINF + #define PF3_WPORT PORTF + #define PF3_PWM NULL + #define PF3_DDR DDRF + #undef PF4 + #define PF4_PIN PINF4 + #define PF4_RPORT PINF + #define PF4_WPORT PORTF + #define PF4_PWM NULL + #define PF4_DDR DDRF + #undef PF5 + #define PF5_PIN PINF5 + #define PF5_RPORT PINF + #define PF5_WPORT PORTF + #define PF5_PWM NULL + #define PF5_DDR DDRF + #undef PF6 + #define PF6_PIN PINF6 + #define PF6_RPORT PINF + #define PF6_WPORT PORTF + #define PF6_PWM NULL + #define PF6_DDR DDRF + #undef PF7 + #define PF7_PIN PINF7 + #define PF7_RPORT PINF + #define PF7_WPORT PORTF + #define PF7_PWM NULL + #define PF7_DDR DDRF + + #else // AT90USBxx_TEENSYPP_ASSIGNMENTS -- Use Teensyduino Teensy++2.0 assignments. + + /** + + AT90USB 51 50 49 48 47 46 45 44 10 11 12 13 14 15 16 17 35 36 37 38 39 40 41 42 25 26 27 28 29 30 31 32 33 34 43 09 18 19 01 02 61 60 59 58 57 56 55 54 + Port A0 A1 A2 A3 A4 A5 A6 A7 B0 B1 B2 B3 B4 B5 B6 B7 C0 C1 C2 C3 C4 C5 C6 C7 D0 D1 D2 D3 D4 D5 D6 D7 E0 E1 E2 E3 E4 E5 E6 E7 F0 F1 F2 F3 F4 F5 F6 F7 + Marlin 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 + Teensy 28 29 30 31 32 33 34 35 20 21 22 23 24 25 26 27 10 11 12 13 14 15 16 17 00 01 02 03 04 05 06 07 08 09(46*47)36 37 18 19 38 39 40 41 42 43 44 45 + The pins 46 and 47 are not supported by Teensyduino, but are supported below. + */ + + // SPI + #define SCK DIO21 // 9 + #define MISO DIO23 // 11 + #define MOSI DIO22 // 10 + #define SS DIO20 // 8 + + #define DIO0_PIN PIND0 + #define DIO0_RPORT PIND + #define DIO0_WPORT PORTD + #define DIO0_PWM NULL + #define DIO0_DDR DDRD + + #define DIO1_PIN PIND1 + #define DIO1_RPORT PIND + #define DIO1_WPORT PORTD + #define DIO1_PWM NULL + #define DIO1_DDR DDRD + + #define DIO2_PIN PIND2 + #define DIO2_RPORT PIND + #define DIO2_WPORT PORTD + #define DIO2_PWM NULL + #define DIO2_DDR DDRD + + #define DIO3_PIN PIND3 + #define DIO3_RPORT PIND + #define DIO3_WPORT PORTD + #define DIO3_PWM NULL + #define DIO3_DDR DDRD + + #define DIO4_PIN PIND4 + #define DIO4_RPORT PIND + #define DIO4_WPORT PORTD + #define DIO4_PWM NULL + #define DIO4_DDR DDRD + + #define DIO5_PIN PIND5 + #define DIO5_RPORT PIND + #define DIO5_WPORT PORTD + #define DIO5_PWM NULL + #define DIO5_DDR DDRD + + #define DIO6_PIN PIND6 + #define DIO6_RPORT PIND + #define DIO6_WPORT PORTD + #define DIO6_PWM NULL + #define DIO6_DDR DDRD + + #define DIO7_PIN PIND7 + #define DIO7_RPORT PIND + #define DIO7_WPORT PORTD + #define DIO7_PWM NULL + #define DIO7_DDR DDRD + + #define DIO8_PIN PINE0 + #define DIO8_RPORT PINE + #define DIO8_WPORT PORTE + #define DIO8_PWM NULL + #define DIO8_DDR DDRE + + #define DIO9_PIN PINE1 + #define DIO9_RPORT PINE + #define DIO9_WPORT PORTE + #define DIO9_PWM NULL + #define DIO9_DDR DDRE + + #define DIO10_PIN PINC0 + #define DIO10_RPORT PINC + #define DIO10_WPORT PORTC + #define DIO10_PWM NULL + #define DIO10_DDR DDRC + + #define DIO11_PIN PINC1 + #define DIO11_RPORT PINC + #define DIO11_WPORT PORTC + #define DIO11_PWM NULL + #define DIO11_DDR DDRC + + #define DIO12_PIN PINC2 + #define DIO12_RPORT PINC + #define DIO12_WPORT PORTC + #define DIO12_PWM NULL + #define DIO12_DDR DDRC + + #define DIO13_PIN PINC3 + #define DIO13_RPORT PINC + #define DIO13_WPORT PORTC + #define DIO13_PWM NULL + #define DIO13_DDR DDRC + + #define DIO14_PIN PINC4 + #define DIO14_RPORT PINC + #define DIO14_WPORT PORTC + #define DIO14_PWM NULL + #define DIO14_DDR DDRC + + #define DIO15_PIN PINC5 + #define DIO15_RPORT PINC + #define DIO15_WPORT PORTC + #define DIO15_PWM NULL + #define DIO15_DDR DDRC + + #define DIO16_PIN PINC6 + #define DIO16_RPORT PINC + #define DIO16_WPORT PORTC + #define DIO16_PWM NULL + #define DIO16_DDR DDRC + + #define DIO17_PIN PINC7 + #define DIO17_RPORT PINC + #define DIO17_WPORT PORTC + #define DIO17_PWM NULL + #define DIO17_DDR DDRC + + #define DIO18_PIN PINE6 + #define DIO18_RPORT PINE + #define DIO18_WPORT PORTE + #define DIO18_PWM NULL + #define DIO18_DDR DDRE + + #define DIO19_PIN PINE7 + #define DIO19_RPORT PINE + #define DIO19_WPORT PORTE + #define DIO19_PWM NULL + #define DIO19_DDR DDRE + + #define DIO20_PIN PINB0 + #define DIO20_RPORT PINB + #define DIO20_WPORT PORTB + #define DIO20_PWM NULL + #define DIO20_DDR DDRB + + #define DIO21_PIN PINB1 + #define DIO21_RPORT PINB + #define DIO21_WPORT PORTB + #define DIO21_PWM NULL + #define DIO21_DDR DDRB + + #define DIO22_PIN PINB2 + #define DIO22_RPORT PINB + #define DIO22_WPORT PORTB + #define DIO22_PWM NULL + #define DIO22_DDR DDRB + + #define DIO23_PIN PINB3 + #define DIO23_RPORT PINB + #define DIO23_WPORT PORTB + #define DIO23_PWM NULL + #define DIO23_DDR DDRB + + #define DIO24_PIN PINB4 + #define DIO24_RPORT PINB + #define DIO24_WPORT PORTB + #define DIO24_PWM NULL + #define DIO24_DDR DDRB + + #define DIO25_PIN PINB5 + #define DIO25_RPORT PINB + #define DIO25_WPORT PORTB + #define DIO25_PWM NULL + #define DIO25_DDR DDRB + + #define DIO26_PIN PINB6 + #define DIO26_RPORT PINB + #define DIO26_WPORT PORTB + #define DIO26_PWM NULL + #define DIO26_DDR DDRB + + #define DIO27_PIN PINB7 + #define DIO27_RPORT PINB + #define DIO27_WPORT PORTB + #define DIO27_PWM NULL + #define DIO27_DDR DDRB + + #define DIO28_PIN PINA0 + #define DIO28_RPORT PINA + #define DIO28_WPORT PORTA + #define DIO28_PWM NULL + #define DIO28_DDR DDRA + + #define DIO29_PIN PINA1 + #define DIO29_RPORT PINA + #define DIO29_WPORT PORTA + #define DIO29_PWM NULL + #define DIO29_DDR DDRA + + #define DIO30_PIN PINA2 + #define DIO30_RPORT PINA + #define DIO30_WPORT PORTA + #define DIO30_PWM NULL + #define DIO30_DDR DDRA + + #define DIO31_PIN PINA3 + #define DIO31_RPORT PINA + #define DIO31_WPORT PORTA + #define DIO31_PWM NULL + #define DIO31_DDR DDRA + + #define DIO32_PIN PINA4 + #define DIO32_RPORT PINA + #define DIO32_WPORT PORTA + #define DIO32_PWM NULL + #define DIO32_DDR DDRA + + #define DIO33_PIN PINA5 + #define DIO33_RPORT PINA + #define DIO33_WPORT PORTA + #define DIO33_PWM NULL + #define DIO33_DDR DDRA + + #define DIO34_PIN PINA6 + #define DIO34_RPORT PINA + #define DIO34_WPORT PORTA + #define DIO34_PWM NULL + #define DIO34_DDR DDRA + + #define DIO35_PIN PINA7 + #define DIO35_RPORT PINA + #define DIO35_WPORT PORTA + #define DIO35_PWM NULL + #define DIO35_DDR DDRA + + #define DIO36_PIN PINE4 + #define DIO36_RPORT PINE + #define DIO36_WPORT PORTE + #define DIO36_PWM NULL + #define DIO36_DDR DDRE + + #define DIO37_PIN PINE5 + #define DIO37_RPORT PINE + #define DIO37_WPORT PORTE + #define DIO37_PWM NULL + #define DIO37_DDR DDRE + + #define DIO38_PIN PINF0 + #define DIO38_RPORT PINF + #define DIO38_WPORT PORTF + #define DIO38_PWM NULL + #define DIO38_DDR DDRF + + #define DIO39_PIN PINF1 + #define DIO39_RPORT PINF + #define DIO39_WPORT PORTF + #define DIO39_PWM NULL + #define DIO39_DDR DDRF + + #define DIO40_PIN PINF2 + #define DIO40_RPORT PINF + #define DIO40_WPORT PORTF + #define DIO40_PWM NULL + #define DIO40_DDR DDRF + + #define DIO41_PIN PINF3 + #define DIO41_RPORT PINF + #define DIO41_WPORT PORTF + #define DIO41_PWM NULL + #define DIO41_DDR DDRF + + #define DIO42_PIN PINF4 + #define DIO42_RPORT PINF + #define DIO42_WPORT PORTF + #define DIO42_PWM NULL + #define DIO42_DDR DDRF + + #define DIO43_PIN PINF5 + #define DIO43_RPORT PINF + #define DIO43_WPORT PORTF + #define DIO43_PWM NULL + #define DIO43_DDR DDRF + + #define DIO44_PIN PINF6 + #define DIO44_RPORT PINF + #define DIO44_WPORT PORTF + #define DIO44_PWM NULL + #define DIO44_DDR DDRF + + #define DIO45_PIN PINF7 + #define DIO45_RPORT PINF + #define DIO45_WPORT PORTF + #define DIO45_PWM NULL + #define DIO45_DDR DDRF + + #define AIO0_PIN PINF0 + #define AIO0_RPORT PINF + #define AIO0_WPORT PORTF + #define AIO0_PWM NULL + #define AIO0_DDR DDRF + + #define AIO1_PIN PINF1 + #define AIO1_RPORT PINF + #define AIO1_WPORT PORTF + #define AIO1_PWM NULL + #define AIO1_DDR DDRF + + #define AIO2_PIN PINF2 + #define AIO2_RPORT PINF + #define AIO2_WPORT PORTF + #define AIO2_PWM NULL + #define AIO2_DDR DDRF + + #define AIO3_PIN PINF3 + #define AIO3_RPORT PINF + #define AIO3_WPORT PORTF + #define AIO3_PWM NULL + #define AIO3_DDR DDRF + + #define AIO4_PIN PINF4 + #define AIO4_RPORT PINF + #define AIO4_WPORT PORTF + #define AIO4_PWM NULL + #define AIO4_DDR DDRF + + #define AIO5_PIN PINF5 + #define AIO5_RPORT PINF + #define AIO5_WPORT PORTF + #define AIO5_PWM NULL + #define AIO5_DDR DDRF + + #define AIO6_PIN PINF6 + #define AIO6_RPORT PINF + #define AIO6_WPORT PORTF + #define AIO6_PWM NULL + #define AIO6_DDR DDRF + + #define AIO7_PIN PINF7 + #define AIO7_RPORT PINF + #define AIO7_WPORT PORTF + #define AIO7_PWM NULL + #define AIO7_DDR DDRF + + //-- Begin not supported by Teensyduino + //-- don't use Arduino functions on these pins pinMode/digitalWrite/etc + #define DIO46_PIN PINE2 + #define DIO46_RPORT PINE + #define DIO46_WPORT PORTE + #define DIO46_PWM NULL + #define DIO46_DDR DDRE + + #define DIO47_PIN PINE3 + #define DIO47_RPORT PINE + #define DIO47_WPORT PORTE + #define DIO47_PWM NULL + #define DIO47_DDR DDRE + //-- end not supported by Teensyduino + + #undef PA0 + #define PA0_PIN PINA0 + #define PA0_RPORT PINA + #define PA0_WPORT PORTA + #define PA0_PWM NULL + #define PA0_DDR DDRA + #undef PA1 + #define PA1_PIN PINA1 + #define PA1_RPORT PINA + #define PA1_WPORT PORTA + #define PA1_PWM NULL + #define PA1_DDR DDRA + #undef PA2 + #define PA2_PIN PINA2 + #define PA2_RPORT PINA + #define PA2_WPORT PORTA + #define PA2_PWM NULL + #define PA2_DDR DDRA + #undef PA3 + #define PA3_PIN PINA3 + #define PA3_RPORT PINA + #define PA3_WPORT PORTA + #define PA3_PWM NULL + #define PA3_DDR DDRA + #undef PA4 + #define PA4_PIN PINA4 + #define PA4_RPORT PINA + #define PA4_WPORT PORTA + #define PA4_PWM NULL + #define PA4_DDR DDRA + #undef PA5 + #define PA5_PIN PINA5 + #define PA5_RPORT PINA + #define PA5_WPORT PORTA + #define PA5_PWM NULL + #define PA5_DDR DDRA + #undef PA6 + #define PA6_PIN PINA6 + #define PA6_RPORT PINA + #define PA6_WPORT PORTA + #define PA6_PWM NULL + #define PA6_DDR DDRA + #undef PA7 + #define PA7_PIN PINA7 + #define PA7_RPORT PINA + #define PA7_WPORT PORTA + #define PA7_PWM NULL + #define PA7_DDR DDRA + + #undef PB0 + #define PB0_PIN PINB0 + #define PB0_RPORT PINB + #define PB0_WPORT PORTB + #define PB0_PWM NULL + #define PB0_DDR DDRB + #undef PB1 + #define PB1_PIN PINB1 + #define PB1_RPORT PINB + #define PB1_WPORT PORTB + #define PB1_PWM NULL + #define PB1_DDR DDRB + #undef PB2 + #define PB2_PIN PINB2 + #define PB2_RPORT PINB + #define PB2_WPORT PORTB + #define PB2_PWM NULL + #define PB2_DDR DDRB + #undef PB3 + #define PB3_PIN PINB3 + #define PB3_RPORT PINB + #define PB3_WPORT PORTB + #define PB3_PWM NULL + #define PB3_DDR DDRB + #undef PB4 + #define PB4_PIN PINB4 + #define PB4_RPORT PINB + #define PB4_WPORT PORTB + #define PB4_PWM NULL + #define PB4_DDR DDRB + #undef PB5 + #define PB5_PIN PINB5 + #define PB5_RPORT PINB + #define PB5_WPORT PORTB + #define PB5_PWM NULL + #define PB5_DDR DDRB + #undef PB6 + #define PB6_PIN PINB6 + #define PB6_RPORT PINB + #define PB6_WPORT PORTB + #define PB6_PWM NULL + #define PB6_DDR DDRB + #undef PB7 + #define PB7_PIN PINB7 + #define PB7_RPORT PINB + #define PB7_WPORT PORTB + #define PB7_PWM NULL + #define PB7_DDR DDRB + + #undef PC0 + #define PC0_PIN PINC0 + #define PC0_RPORT PINC + #define PC0_WPORT PORTC + #define PC0_PWM NULL + #define PC0_DDR DDRC + #undef PC1 + #define PC1_PIN PINC1 + #define PC1_RPORT PINC + #define PC1_WPORT PORTC + #define PC1_PWM NULL + #define PC1_DDR DDRC + #undef PC2 + #define PC2_PIN PINC2 + #define PC2_RPORT PINC + #define PC2_WPORT PORTC + #define PC2_PWM NULL + #define PC2_DDR DDRC + #undef PC3 + #define PC3_PIN PINC3 + #define PC3_RPORT PINC + #define PC3_WPORT PORTC + #define PC3_PWM NULL + #define PC3_DDR DDRC + #undef PC4 + #define PC4_PIN PINC4 + #define PC4_RPORT PINC + #define PC4_WPORT PORTC + #define PC4_PWM NULL + #define PC4_DDR DDRC + #undef PC5 + #define PC5_PIN PINC5 + #define PC5_RPORT PINC + #define PC5_WPORT PORTC + #define PC5_PWM NULL + #define PC5_DDR DDRC + #undef PC6 + #define PC6_PIN PINC6 + #define PC6_RPORT PINC + #define PC6_WPORT PORTC + #define PC6_PWM NULL + #define PC6_DDR DDRC + #undef PC7 + #define PC7_PIN PINC7 + #define PC7_RPORT PINC + #define PC7_WPORT PORTC + #define PC7_PWM NULL + #define PC7_DDR DDRC + + #undef PD0 + #define PD0_PIN PIND0 + #define PD0_RPORT PIND + #define PD0_WPORT PORTD + #define PD0_PWM NULL + #define PD0_DDR DDRD + #undef PD1 + #define PD1_PIN PIND1 + #define PD1_RPORT PIND + #define PD1_WPORT PORTD + #define PD1_PWM NULL + #define PD1_DDR DDRD + #undef PD2 + #define PD2_PIN PIND2 + #define PD2_RPORT PIND + #define PD2_WPORT PORTD + #define PD2_PWM NULL + #define PD2_DDR DDRD + #undef PD3 + #define PD3_PIN PIND3 + #define PD3_RPORT PIND + #define PD3_WPORT PORTD + #define PD3_PWM NULL + #define PD3_DDR DDRD + #undef PD4 + #define PD4_PIN PIND4 + #define PD4_RPORT PIND + #define PD4_WPORT PORTD + #define PD4_PWM NULL + #define PD4_DDR DDRD + #undef PD5 + #define PD5_PIN PIND5 + #define PD5_RPORT PIND + #define PD5_WPORT PORTD + #define PD5_PWM NULL + #define PD5_DDR DDRD + #undef PD6 + #define PD6_PIN PIND6 + #define PD6_RPORT PIND + #define PD6_WPORT PORTD + #define PD6_PWM NULL + #define PD6_DDR DDRD + #undef PD7 + #define PD7_PIN PIND7 + #define PD7_RPORT PIND + #define PD7_WPORT PORTD + #define PD7_PWM NULL + #define PD7_DDR DDRD + + #undef PE0 + #define PE0_PIN PINE0 + #define PE0_RPORT PINE + #define PE0_WPORT PORTE + #define PE0_PWM NULL + #define PE0_DDR DDRE + #undef PE1 + #define PE1_PIN PINE1 + #define PE1_RPORT PINE + #define PE1_WPORT PORTE + #define PE1_PWM NULL + #define PE1_DDR DDRE + #undef PE2 + #define PE2_PIN PINE2 + #define PE2_RPORT PINE + #define PE2_WPORT PORTE + #define PE2_PWM NULL + #define PE2_DDR DDRE + #undef PE3 + #define PE3_PIN PINE3 + #define PE3_RPORT PINE + #define PE3_WPORT PORTE + #define PE3_PWM NULL + #define PE3_DDR DDRE + #undef PE4 + #define PE4_PIN PINE4 + #define PE4_RPORT PINE + #define PE4_WPORT PORTE + #define PE4_PWM NULL + #define PE4_DDR DDRE + #undef PE5 + #define PE5_PIN PINE5 + #define PE5_RPORT PINE + #define PE5_WPORT PORTE + #define PE5_PWM NULL + #define PE5_DDR DDRE + #undef PE6 + #define PE6_PIN PINE6 + #define PE6_RPORT PINE + #define PE6_WPORT PORTE + #define PE6_PWM NULL + #define PE6_DDR DDRE + #undef PE7 + #define PE7_PIN PINE7 + #define PE7_RPORT PINE + #define PE7_WPORT PORTE + #define PE7_PWM NULL + #define PE7_DDR DDRE + + #undef PF0 + #define PF0_PIN PINF0 + #define PF0_RPORT PINF + #define PF0_WPORT PORTF + #define PF0_PWM NULL + #define PF0_DDR DDRF + #undef PF1 + #define PF1_PIN PINF1 + #define PF1_RPORT PINF + #define PF1_WPORT PORTF + #define PF1_PWM NULL + #define PF1_DDR DDRF + #undef PF2 + #define PF2_PIN PINF2 + #define PF2_RPORT PINF + #define PF2_WPORT PORTF + #define PF2_PWM NULL + #define PF2_DDR DDRF + #undef PF3 + #define PF3_PIN PINF3 + #define PF3_RPORT PINF + #define PF3_WPORT PORTF + #define PF3_PWM NULL + #define PF3_DDR DDRF + #undef PF4 + #define PF4_PIN PINF4 + #define PF4_RPORT PINF + #define PF4_WPORT PORTF + #define PF4_PWM NULL + #define PF4_DDR DDRF + #undef PF5 + #define PF5_PIN PINF5 + #define PF5_RPORT PINF + #define PF5_WPORT PORTF + #define PF5_PWM NULL + #define PF5_DDR DDRF + #undef PF6 + #define PF6_PIN PINF6 + #define PF6_RPORT PINF + #define PF6_WPORT PORTF + #define PF6_PWM NULL + #define PF6_DDR DDRF + #undef PF7 + #define PF7_PIN PINF7 + #define PF7_RPORT PINF + #define PF7_WPORT PORTF + #define PF7_PWM NULL + #define PF7_DDR DDRF + + #endif // AT90USBxx_TEENSYPP_ASSIGNMENTS Teensyduino assignments +#endif // __AVR_AT90usbxxx__ + + +#if defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__) + // UART + #define RXD DIO0 + #define TXD DIO1 + + // SPI + #define SCK DIO10 + #define MISO DIO12 + #define MOSI DIO11 + #define SS DIO16 + + // TWI (I2C) + #define SCL DIO17 + #define SDA DIO18 + + // timers and PWM + #define OC0A DIO9 + #define OC0B DIO4 + #define OC1A DIO7 + #define OC1B DIO8 + #define OC2A DIO6 + #define OC3A DIO5 + #define OC3B DIO2 + #define OC3C DIO3 + + + // change for your board + #define DEBUG_LED DIO46 + + /** + pins + */ + #define DIO0_PIN PINE0 + #define DIO0_RPORT PINE + #define DIO0_WPORT PORTE + #define DIO0_DDR DDRE + #define DIO0_PWM NULL + + #define DIO1_PIN PINE1 + #define DIO1_RPORT PINE + #define DIO1_WPORT PORTE + #define DIO1_DDR DDRE + #define DIO1_PWM NULL + + #define DIO2_PIN PINE4 + #define DIO2_RPORT PINE + #define DIO2_WPORT PORTE + #define DIO2_DDR DDRE + #define DIO2_PWM &OCR3BL + + #define DIO3_PIN PINE5 + #define DIO3_RPORT PINE + #define DIO3_WPORT PORTE + #define DIO3_DDR DDRE + #define DIO3_PWM &OCR3CL + + #define DIO4_PIN PING5 + #define DIO4_RPORT PING + #define DIO4_WPORT PORTG + #define DIO4_DDR DDRG + #define DIO4_PWM &OCR0B + + #define DIO5_PIN PINE3 + #define DIO5_RPORT PINE + #define DIO5_WPORT PORTE + #define DIO5_DDR DDRE + #define DIO5_PWM &OCR3AL + + #define DIO6_PIN PINB4 + #define DIO6_RPORT PINB + #define DIO6_WPORT PORTB + #define DIO6_DDR DDRB + #define DIO6_PWM &OCR2AL + + #define DIO7_PIN PINB5 + #define DIO7_RPORT PINB + #define DIO7_WPORT PORTB + #define DIO7_DDR DDRB + #define DIO7_PWM &OCR1AL + + #define DIO8_PIN PINB6 + #define DIO8_RPORT PINB + #define DIO8_WPORT PORTB + #define DIO8_DDR DDRB + #define DIO8_PWM &OCR1BL + + #define DIO9_PIN PINB7 + #define DIO9_RPORT PINB + #define DIO9_WPORT PORTB + #define DIO9_DDR DDRB + #define DIO9_PWM &OCR0AL + + #define DIO10_PIN PINB1 + #define DIO10_RPORT PINB + #define DIO10_WPORT PORTB + #define DIO10_DDR DDRB + #define DIO10_PWM NULL + + #define DIO11_PIN PINB2 + #define DIO11_RPORT PINB + #define DIO11_WPORT PORTB + #define DIO11_DDR DDRB + #define DIO11_PWM NULL + + #define DIO12_PIN PINB3 + #define DIO12_RPORT PINB + #define DIO12_WPORT PORTB + #define DIO12_DDR DDRB + #define DIO12_PWM NULL + + #define DIO13_PIN PINE2 + #define DIO13_RPORT PINE + #define DIO13_WPORT PORTE + #define DIO13_DDR DDRE + #define DIO13_PWM NULL + + #define DIO14_PIN PINE6 + #define DIO14_RPORT PINE + #define DIO14_WPORT PORTE + #define DIO14_DDR DDRE + #define DIO14_PWM NULL + + #define DIO15_PIN PINE7 + #define DIO15_RPORT PINE + #define DIO15_WPORT PORTE + #define DIO15_DDR DDRE + #define DIO15_PWM NULL + + #define DIO16_PIN PINB0 + #define DIO16_RPORT PINB + #define DIO16_WPORT PORTB + #define DIO16_DDR DDRB + #define DIO16_PWM NULL + + #define DIO17_PIN PIND0 + #define DIO17_RPORT PIND + #define DIO17_WPORT PORTD + #define DIO17_DDR DDRD + #define DIO17_PWM NULL + + #define DIO18_PIN PIND1 + #define DIO18_RPORT PIND + #define DIO18_WPORT PORTD + #define DIO18_DDR DDRD + #define DIO18_PWM NULL + + #define DIO19_PIN PIND2 + #define DIO19_RPORT PIND + #define DIO19_WPORT PORTD + #define DIO19_DDR DDRD + #define DIO19_PWM NULL + + #define DIO20_PIN PIND3 + #define DIO20_RPORT PIND + #define DIO20_WPORT PORTD + #define DIO20_DDR DDRD + #define DIO20_PWM NULL + + #define DIO21_PIN PIND4 + #define DIO21_RPORT PIND + #define DIO21_WPORT PORTD + #define DIO21_DDR DDRD + #define DIO21_PWM NULL + + #define DIO22_PIN PIND5 + #define DIO22_RPORT PIND + #define DIO22_WPORT PORTD + #define DIO22_DDR DDRD + #define DIO22_PWM NULL + + #define DIO23_PIN PIND6 + #define DIO23_RPORT PIND + #define DIO23_WPORT PORTD + #define DIO23_DDR DDRD + #define DIO23_PWM NULL + + #define DIO24_PIN PIND7 + #define DIO24_RPORT PIND + #define DIO24_WPORT PORTD + #define DIO24_DDR DDRD + #define DIO24_PWM NULL + + #define DIO25_PIN PING0 + #define DIO25_RPORT PING + #define DIO25_WPORT PORTG + #define DIO25_DDR DDRG + #define DIO25_PWM NULL + + #define DIO26_PIN PING1 + #define DIO26_RPORT PING + #define DIO26_WPORT PORTG + #define DIO26_DDR DDRG + #define DIO26_PWM NULL + + #define DIO27_PIN PING2 + #define DIO27_RPORT PING + #define DIO27_WPORT PORTG + #define DIO27_DDR DDRG + #define DIO27_PWM NULL + + #define DIO28_PIN PING3 + #define DIO28_RPORT PING + #define DIO28_WPORT PORTG + #define DIO28_DDR DDRG + #define DIO28_PWM NULL + + #define DIO29_PIN PING4 + #define DIO29_RPORT PING + #define DIO29_WPORT PORTG + #define DIO29_DDR DDRG + #define DIO29_PWM NULL + + #define DIO30_PIN PINC0 + #define DIO30_RPORT PINC + #define DIO30_WPORT PORTC + #define DIO30_DDR DDRC + #define DIO30_PWM NULL + + #define DIO31_PIN PINC1 + #define DIO31_RPORT PINC + #define DIO31_WPORT PORTC + #define DIO31_DDR DDRC + #define DIO31_PWM NULL + + #define DIO32_PIN PINC2 + #define DIO32_RPORT PINC + #define DIO32_WPORT PORTC + #define DIO32_DDR DDRC + #define DIO32_PWM NULL + + #define DIO33_PIN PINC3 + #define DIO33_RPORT PINC + #define DIO33_WPORT PORTC + #define DIO33_DDR DDRC + #define DIO33_PWM NULL + + #define DIO34_PIN PINC4 + #define DIO34_RPORT PINC + #define DIO34_WPORT PORTC + #define DIO34_DDR DDRC + #define DIO34_PWM NULL + + #define DIO35_PIN PINC5 + #define DIO35_RPORT PINC + #define DIO35_WPORT PORTC + #define DIO35_DDR DDRC + #define DIO35_PWM NULL + + #define DIO36_PIN PINC6 + #define DIO36_RPORT PINC + #define DIO36_WPORT PORTC + #define DIO36_DDR DDRC + #define DIO36_PWM NULL + + #define DIO37_PIN PINC7 + #define DIO37_RPORT PINC + #define DIO37_WPORT PORTC + #define DIO37_DDR DDRC + #define DIO37_PWM NULL + + #define DIO38_PIN PINA0 + #define DIO38_RPORT PINA + #define DIO38_WPORT PORTA + #define DIO38_DDR DDRA + #define DIO38_PWM NULL + + #define DIO39_PIN PINA1 + #define DIO39_RPORT PINA + #define DIO39_WPORT PORTA + #define DIO39_DDR DDRA + #define DIO39_PWM NULL + + #define DIO40_PIN PINA2 + #define DIO40_RPORT PINA + #define DIO40_WPORT PORTA + #define DIO40_DDR DDRA + #define DIO40_PWM NULL + + #define DIO41_PIN PINA3 + #define DIO41_RPORT PINA + #define DIO41_WPORT PORTA + #define DIO41_DDR DDRA + #define DIO41_PWM NULL + + #define DIO42_PIN PINA4 + #define DIO42_RPORT PINA + #define DIO42_WPORT PORTA + #define DIO42_DDR DDRA + #define DIO42_PWM NULL + + #define DIO43_PIN PINA5 + #define DIO43_RPORT PINA + #define DIO43_WPORT PORTA + #define DIO43_DDR DDRA + #define DIO43_PWM NULL + + #define DIO44_PIN PINA6 + #define DIO44_RPORT PINA + #define DIO44_WPORT PORTA + #define DIO44_DDR DDRA + #define DIO44_PWM NULL + + #define DIO45_PIN PINA7 + #define DIO45_RPORT PINA + #define DIO45_WPORT PORTA + #define DIO45_DDR DDRA + #define DIO45_PWM NULL + + #define DIO46_PIN PINF0 + #define DIO46_RPORT PINF + #define DIO46_WPORT PORTF + #define DIO46_DDR DDRF + #define DIO46_PWM NULL + + #define DIO47_PIN PINF1 + #define DIO47_RPORT PINF + #define DIO47_WPORT PORTF + #define DIO47_DDR DDRF + #define DIO47_PWM NULL + + #define DIO48_PIN PINF2 + #define DIO48_RPORT PINF + #define DIO48_WPORT PORTF + #define DIO48_DDR DDRF + #define DIO48_PWM NULL + + #define DIO49_PIN PINF3 + #define DIO49_RPORT PINF + #define DIO49_WPORT PORTF + #define DIO49_DDR DDRF + #define DIO49_PWM NULL + + #define DIO50_PIN PINF4 + #define DIO50_RPORT PINF + #define DIO50_WPORT PORTF + #define DIO50_DDR DDRF + #define DIO50_PWM NULL + + #define DIO51_PIN PINF5 + #define DIO51_RPORT PINF + #define DIO51_WPORT PORTF + #define DIO51_DDR DDRF + #define DIO51_PWM NULL + + #define DIO52_PIN PINF6 + #define DIO52_RPORT PINF + #define DIO52_WPORT PORTF + #define DIO52_DDR DDRF + #define DIO52_PWM NULL + + #define DIO53_PIN PINF7 + #define DIO53_RPORT PINF + #define DIO53_WPORT PORTF + #define DIO53_DDR DDRF + #define DIO53_PWM NULL + + + + + #undef PA0 + #define PA0_PIN PINA0 + #define PA0_RPORT PINA + #define PA0_WPORT PORTA + #define PA0_DDR DDRA + #define PA0_PWM NULL + #undef PA1 + #define PA1_PIN PINA1 + #define PA1_RPORT PINA + #define PA1_WPORT PORTA + #define PA1_DDR DDRA + #define PA1_PWM NULL + #undef PA2 + #define PA2_PIN PINA2 + #define PA2_RPORT PINA + #define PA2_WPORT PORTA + #define PA2_DDR DDRA + #define PA2_PWM NULL + #undef PA3 + #define PA3_PIN PINA3 + #define PA3_RPORT PINA + #define PA3_WPORT PORTA + #define PA3_DDR DDRA + #define PA3_PWM NULL + #undef PA4 + #define PA4_PIN PINA4 + #define PA4_RPORT PINA + #define PA4_WPORT PORTA + #define PA4_DDR DDRA + #define PA4_PWM NULL + #undef PA5 + #define PA5_PIN PINA5 + #define PA5_RPORT PINA + #define PA5_WPORT PORTA + #define PA5_DDR DDRA + #define PA5_PWM NULL + #undef PA6 + #define PA6_PIN PINA6 + #define PA6_RPORT PINA + #define PA6_WPORT PORTA + #define PA6_DDR DDRA + #define PA6_PWM NULL + #undef PA7 + #define PA7_PIN PINA7 + #define PA7_RPORT PINA + #define PA7_WPORT PORTA + #define PA7_DDR DDRA + #define PA7_PWM NULL + + #undef PB0 + #define PB0_PIN PINB0 + #define PB0_RPORT PINB + #define PB0_WPORT PORTB + #define PB0_DDR DDRB + #define PB0_PWM NULL + #undef PB1 + #define PB1_PIN PINB1 + #define PB1_RPORT PINB + #define PB1_WPORT PORTB + #define PB1_DDR DDRB + #define PB1_PWM NULL + #undef PB2 + #define PB2_PIN PINB2 + #define PB2_RPORT PINB + #define PB2_WPORT PORTB + #define PB2_DDR DDRB + #define PB2_PWM NULL + #undef PB3 + #define PB3_PIN PINB3 + #define PB3_RPORT PINB + #define PB3_WPORT PORTB + #define PB3_DDR DDRB + #define PB3_PWM NULL + #undef PB4 + #define PB4_PIN PINB4 + #define PB4_RPORT PINB + #define PB4_WPORT PORTB + #define PB4_DDR DDRB + #define PB4_PWM &OCR2A + #undef PB5 + #define PB5_PIN PINB5 + #define PB5_RPORT PINB + #define PB5_WPORT PORTB + #define PB5_DDR DDRB + #define PB5_PWM NULL + #undef PB6 + #define PB6_PIN PINB6 + #define PB6_RPORT PINB + #define PB6_WPORT PORTB + #define PB6_DDR DDRB + #define PB6_PWM NULL + #undef PB7 + #define PB7_PIN PINB7 + #define PB7_RPORT PINB + #define PB7_WPORT PORTB + #define PB7_DDR DDRB + #define PB7_PWM &OCR0A + + #undef PC0 + #define PC0_PIN PINC0 + #define PC0_RPORT PINC + #define PC0_WPORT PORTC + #define PC0_DDR DDRC + #define PC0_PWM NULL + #undef PC1 + #define PC1_PIN PINC1 + #define PC1_RPORT PINC + #define PC1_WPORT PORTC + #define PC1_DDR DDRC + #define PC1_PWM NULL + #undef PC2 + #define PC2_PIN PINC2 + #define PC2_RPORT PINC + #define PC2_WPORT PORTC + #define PC2_DDR DDRC + #define PC2_PWM NULL + #undef PC3 + #define PC3_PIN PINC3 + #define PC3_RPORT PINC + #define PC3_WPORT PORTC + #define PC3_DDR DDRC + #define PC3_PWM NULL + #undef PC4 + #define PC4_PIN PINC4 + #define PC4_RPORT PINC + #define PC4_WPORT PORTC + #define PC4_DDR DDRC + #define PC4_PWM NULL + #undef PC5 + #define PC5_PIN PINC5 + #define PC5_RPORT PINC + #define PC5_WPORT PORTC + #define PC5_DDR DDRC + #define PC5_PWM NULL + #undef PC6 + #define PC6_PIN PINC6 + #define PC6_RPORT PINC + #define PC6_WPORT PORTC + #define PC6_DDR DDRC + #define PC6_PWM NULL + #undef PC7 + #define PC7_PIN PINC7 + #define PC7_RPORT PINC + #define PC7_WPORT PORTC + #define PC7_DDR DDRC + #define PC7_PWM NULL + + #undef PD0 + #define PD0_PIN PIND0 + #define PD0_RPORT PIND + #define PD0_WPORT PORTD + #define PD0_DDR DDRD + #define PD0_PWM NULL + #undef PD1 + #define PD1_PIN PIND1 + #define PD1_RPORT PIND + #define PD1_WPORT PORTD + #define PD1_DDR DDRD + #define PD1_PWM NULL + #undef PD2 + #define PD2_PIN PIND2 + #define PD2_RPORT PIND + #define PD2_WPORT PORTD + #define PD2_DDR DDRD + #define PD2_PWM NULL + #undef PD3 + #define PD3_PIN PIND3 + #define PD3_RPORT PIND + #define PD3_WPORT PORTD + #define PD3_DDR DDRD + #define PD3_PWM NULL + #undef PD4 + #define PD4_PIN PIND4 + #define PD4_RPORT PIND + #define PD4_WPORT PORTD + #define PD4_DDR DDRD + #define PD4_PWM NULL + #undef PD5 + #define PD5_PIN PIND5 + #define PD5_RPORT PIND + #define PD5_WPORT PORTD + #define PD5_DDR DDRD + #define PD5_PWM NULL + #undef PD6 + #define PD6_PIN PIND6 + #define PD6_RPORT PIND + #define PD6_WPORT PORTD + #define PD6_DDR DDRD + #define PD6_PWM NULL + #undef PD7 + #define PD7_PIN PIND7 + #define PD7_RPORT PIND + #define PD7_WPORT PORTD + #define PD7_DDR DDRD + #define PD7_PWM NULL + + #undef PE0 + #define PE0_PIN PINE0 + #define PE0_RPORT PINE + #define PE0_WPORT PORTE + #define PE0_DDR DDRE + #define PE0_PWM NULL + #undef PE1 + #define PE1_PIN PINE1 + #define PE1_RPORT PINE + #define PE1_WPORT PORTE + #define PE1_DDR DDRE + #define PE1_PWM NULL + #undef PE2 + #define PE2_PIN PINE2 + #define PE2_RPORT PINE + #define PE2_WPORT PORTE + #define PE2_DDR DDRE + #define PE2_PWM NULL + #undef PE3 + #define PE3_PIN PINE3 + #define PE3_RPORT PINE + #define PE3_WPORT PORTE + #define PE3_DDR DDRE + #define PE3_PWM &OCR3AL + #undef PE4 + #define PE4_PIN PINE4 + #define PE4_RPORT PINE + #define PE4_WPORT PORTE + #define PE4_DDR DDRE + #define PE4_PWM &OCR3BL + #undef PE5 + #define PE5_PIN PINE5 + #define PE5_RPORT PINE + #define PE5_WPORT PORTE + #define PE5_DDR DDRE + #define PE5_PWM &OCR3CL + #undef PE6 + #define PE6_PIN PINE6 + #define PE6_RPORT PINE + #define PE6_WPORT PORTE + #define PE6_DDR DDRE + #define PE6_PWM NULL + #undef PE7 + #define PE7_PIN PINE7 + #define PE7_RPORT PINE + #define PE7_WPORT PORTE + #define PE7_DDR DDRE + #define PE7_PWM NULL + + #undef PF0 + #define PF0_PIN PINF0 + #define PF0_RPORT PINF + #define PF0_WPORT PORTF + #define PF0_DDR DDRF + #define PF0_PWM NULL + #undef PF1 + #define PF1_PIN PINF1 + #define PF1_RPORT PINF + #define PF1_WPORT PORTF + #define PF1_DDR DDRF + #define PF1_PWM NULL + #undef PF2 + #define PF2_PIN PINF2 + #define PF2_RPORT PINF + #define PF2_WPORT PORTF + #define PF2_DDR DDRF + #define PF2_PWM NULL + #undef PF3 + #define PF3_PIN PINF3 + #define PF3_RPORT PINF + #define PF3_WPORT PORTF + #define PF3_DDR DDRF + #define PF3_PWM NULL + #undef PF4 + #define PF4_PIN PINF4 + #define PF4_RPORT PINF + #define PF4_WPORT PORTF + #define PF4_DDR DDRF + #define PF4_PWM NULL + #undef PF5 + #define PF5_PIN PINF5 + #define PF5_RPORT PINF + #define PF5_WPORT PORTF + #define PF5_DDR DDRF + #define PF5_PWM NULL + #undef PF6 + #define PF6_PIN PINF6 + #define PF6_RPORT PINF + #define PF6_WPORT PORTF + #define PF6_DDR DDRF + #define PF6_PWM NULL + #undef PF7 + #define PF7_PIN PINF7 + #define PF7_RPORT PINF + #define PF7_WPORT PORTF + #define PF7_DDR DDRF + #define PF7_PWM NULL + + #undef PG0 + #define PG0_PIN PING0 + #define PG0_RPORT PING + #define PG0_WPORT PORTG + #define PG0_DDR DDRG + #define PG0_PWM NULL + #undef PG1 + #define PG1_PIN PING1 + #define PG1_RPORT PING + #define PG1_WPORT PORTG + #define PG1_DDR DDRG + #define PG1_PWM NULL + #undef PG2 + #define PG2_PIN PING2 + #define PG2_RPORT PING + #define PG2_WPORT PORTG + #define PG2_DDR DDRG + #define PG2_PWM NULL + #undef PG3 + #define PG3_PIN PING3 + #define PG3_RPORT PING + #define PG3_WPORT PORTG + #define PG3_DDR DDRG + #define PG3_PWM NULL + #undef PG4 + #define PG4_PIN PING4 + #define PG4_RPORT PING + #define PG4_WPORT PORTG + #define PG4_DDR DDRG + #define PG4_PWM NULL + #undef PG5 + #define PG5_PIN PING5 + #define PG5_RPORT PING + #define PG5_WPORT PORTG + #define PG5_DDR DDRG + #define PG5_PWM &OCR0B + + +#endif + +#ifndef DIO0_PIN + #error "pins for this chip not defined in arduino.h! If you write an appropriate pin definition and have this firmware work on your chip, please submit a pull request" +#endif + +#endif /* _FASTIO_ARDUINO_H */ diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/language.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/language.h new file mode 100644 index 00000000..496fed5c --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/language.h @@ -0,0 +1,244 @@ +/** + * 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 . + * + */ + +#ifndef LANGUAGE_H +#define LANGUAGE_H + +#include "MarlinConfig.h" + +// Fallback if no language is set. DON'T CHANGE +#ifndef LCD_LANGUAGE + #define LCD_LANGUAGE en +#endif + +// For character-based LCD controllers (DISPLAY_CHARSET_HD44780) +#define JAPANESE 1 +#define WESTERN 2 +#define CYRILLIC 3 + +// NOTE: IF YOU CHANGE LANGUAGE FILES OR MERGE A FILE WITH CHANGES +// +// ==> ALWAYS TRY TO COMPILE MARLIN WITH/WITHOUT "ULTIPANEL" / "ULTRALCD" / "SDSUPPORT" #define IN "Configuration.h" +// ==> ALSO TRY ALL AVAILABLE LANGUAGE OPTIONS +// See also https://github.com/MarlinFirmware/Marlin/wiki/LCD-Language + +// Languages +// an Aragonese +// bg Bulgarian +// ca Catalan +// cn Chinese +// cz Czech +// de German +// el Greek +// el-gr Greek (Greece) +// en English +// es Spanish +// eu Basque-Euskera +// fi Finnish +// fr French +// gl Galician +// hr Croatian +// it Italian +// kana Japanese +// kana_utf8 Japanese (UTF8) +// nl Dutch +// pl Polish +// pt Portuguese +// pt-br Portuguese (Brazilian) +// pt-br_utf8 Portuguese (Brazilian UTF8) +// pt_utf8 Portuguese (UTF8) +// ru Russian + +#ifdef DEFAULT_SOURCE_CODE_URL + #undef SOURCE_CODE_URL + #define SOURCE_CODE_URL DEFAULT_SOURCE_CODE_URL +#endif + +#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 +#endif + +#ifndef MACHINE_UUID + #define MACHINE_UUID DEFAULT_MACHINE_UUID +#endif + +#ifdef DEFAULT_WEBSITE_URL + #undef WEBSITE_URL + #define WEBSITE_URL DEFAULT_WEBSITE_URL +#endif + +// Common LCD messages + + /* nothing here yet */ + +// Common serial messages +#define MSG_MARLIN "Marlin" + +// Serial Console Messages (do not translate those!) + +#define MSG_Enqueueing "enqueueing \"" +#define MSG_POWERUP "PowerUp" +#define MSG_EXTERNAL_RESET " External Reset" +#define MSG_BROWNOUT_RESET " Brown out Reset" +#define MSG_WATCHDOG_RESET " Watchdog Reset" +#define MSG_SOFTWARE_RESET " Software Reset" +#define MSG_AUTHOR " | Author: " +#define MSG_CONFIGURATION_VER " Last Updated: " +#define MSG_FREE_MEMORY " Free Memory: " +#define MSG_PLANNER_BUFFER_BYTES " PlannerBufferBytes: " +#define MSG_OK "ok" +#define MSG_WAIT "wait" +#define MSG_STATS "Stats: " +#define MSG_FILE_SAVED "Done saving file." +#define MSG_ERR_LINE_NO "Line Number is not Last Line Number+1, Last Line: " +#define MSG_ERR_CHECKSUM_MISMATCH "checksum mismatch, Last Line: " +#define MSG_ERR_NO_CHECKSUM "No Checksum with line number, Last Line: " +#define MSG_ERR_NO_LINENUMBER_WITH_CHECKSUM "No Line Number with checksum, Last Line: " +#define MSG_FILE_PRINTED "Done printing file" +#define MSG_BEGIN_FILE_LIST "Begin file list" +#define MSG_END_FILE_LIST "End file list" +#define MSG_INVALID_EXTRUDER "Invalid extruder" +#define MSG_INVALID_SOLENOID "Invalid solenoid" +#define MSG_ERR_NO_THERMISTORS "No thermistors - no temperature" +#define MSG_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 EMERGENCY_PARSER_CAPABILITIES "\n" +#define MSG_COUNT_X " Count X: " +#define MSG_COUNT_A " Count A: " +#define MSG_ERR_KILLED "Printer halted. kill() called!" +#define MSG_ERR_STOPPED "Printer stopped due to errors. Fix the error and use M999 to restart. (Temperature is reset. Set it after restarting)" +#define MSG_BUSY_PROCESSING "busy: processing" +#define MSG_BUSY_PAUSED_FOR_USER "busy: paused for user" +#define MSG_BUSY_PAUSED_FOR_INPUT "busy: paused for input" +#define MSG_RESEND "Resend: " +#define MSG_UNKNOWN_COMMAND "Unknown command: \"" +#define MSG_ACTIVE_EXTRUDER "Active Extruder: " +#define MSG_X_MIN "x_min: " +#define MSG_X_MAX "x_max: " +#define MSG_Y_MIN "y_min: " +#define MSG_Y_MAX "y_max: " +#define MSG_Z_MIN "z_min: " +#define MSG_Z_MAX "z_max: " +#define MSG_Z2_MAX "z2_max: " +#define MSG_Z_PROBE "z_probe: " +#define MSG_ERR_MATERIAL_INDEX "M145 S out of range (0-1)" +#define MSG_ERR_M421_PARAMETERS "M421 requires XYZ or IJZ parameters" +#define MSG_ERR_MESH_XY "Mesh XY or IJ cannot be resolved" +#define MSG_ERR_M428_TOO_FAR "Too far from reference point" +#define MSG_ERR_M303_DISABLED "PIDTEMP disabled" +#define MSG_M119_REPORT "Reporting endstop status" +#define MSG_ENDSTOP_HIT "TRIGGERED" +#define MSG_ENDSTOP_OPEN "open" +#define MSG_HOTEND_OFFSET "Hotend offsets:" +#define MSG_DUPLICATION_MODE "Duplication mode: " + +#define MSG_SD_CANT_OPEN_SUBDIR "Cannot open subdir " +#define MSG_SD_INIT_FAIL "SD init fail" +#define MSG_SD_VOL_INIT_FAIL "volume.init failed" +#define MSG_SD_OPENROOT_FAIL "openRoot failed" +#define MSG_SD_CARD_OK "SD card ok" +#define MSG_SD_WORKDIR_FAIL "workDir open failed" +#define MSG_SD_OPEN_FILE_FAIL "open failed, File: " +#define MSG_SD_FILE_OPENED "File opened: " +#define MSG_SD_SIZE " Size: " +#define MSG_SD_FILE_SELECTED "File selected" +#define MSG_SD_WRITE_TO_FILE "Writing to file: " +#define MSG_SD_PRINTING_BYTE "SD printing byte " +#define MSG_SD_NOT_PRINTING "Not SD printing" +#define MSG_SD_ERR_WRITE_TO_FILE "error writing to file" +#define MSG_SD_ERR_READ "SD read error" +#define MSG_SD_CANT_ENTER_SUBDIR "Cannot enter subdir: " + +#define MSG_STEPPER_TOO_HIGH "Steprate too high: " +#define MSG_ENDSTOPS_HIT "endstops hit: " +#define MSG_ERR_COLD_EXTRUDE_STOP " cold extrusion prevented" +#define MSG_ERR_LONG_EXTRUDE_STOP " too long extrusion prevented" +#define MSG_TOO_COLD_FOR_M600 "M600 Hotend too cold to change filament" +#define MSG_BABYSTEPPING_X "Babystepping X" +#define MSG_BABYSTEPPING_Y "Babystepping Y" +#define MSG_BABYSTEPPING_Z "Babystepping Z" +#define MSG_SERIAL_ERROR_MENU_STRUCTURE "Error in menu structure" + +#define MSG_ERR_EEPROM_WRITE "Error writing to EEPROM!" + +// temperature.cpp strings +#define MSG_PID_AUTOTUNE "PID Autotune" +#define MSG_PID_AUTOTUNE_START MSG_PID_AUTOTUNE " start" +#define MSG_PID_AUTOTUNE_FAILED MSG_PID_AUTOTUNE " failed!" +#define MSG_PID_BAD_EXTRUDER_NUM MSG_PID_AUTOTUNE_FAILED " Bad extruder number" +#define MSG_PID_TEMP_TOO_HIGH MSG_PID_AUTOTUNE_FAILED " Temperature too high" +#define MSG_PID_TIMEOUT MSG_PID_AUTOTUNE_FAILED " timeout" +#define MSG_BIAS " bias: " +#define MSG_D " d: " +#define MSG_T_MIN " min: " +#define MSG_T_MAX " max: " +#define MSG_KU " Ku: " +#define MSG_TU " Tu: " +#define MSG_CLASSIC_PID " Classic PID " +#define MSG_KP " Kp: " +#define MSG_KI " Ki: " +#define MSG_KD " Kd: " +#define MSG_B "B:" +#define MSG_T "T:" +#define MSG_AT " @:" +#define MSG_PID_AUTOTUNE_FINISHED MSG_PID_AUTOTUNE " finished! Put the last Kp, Ki and Kd constants from below into Configuration.h" +#define MSG_PID_DEBUG " PID_DEBUG " +#define MSG_PID_DEBUG_INPUT ": Input " +#define MSG_PID_DEBUG_OUTPUT " Output " +#define MSG_PID_DEBUG_PTERM " pTerm " +#define MSG_PID_DEBUG_ITERM " iTerm " +#define MSG_PID_DEBUG_DTERM " dTerm " +#define MSG_PID_DEBUG_CTERM " cTerm " +#define MSG_INVALID_EXTRUDER_NUM " - Invalid extruder number !" + +#define MSG_HEATER_BED "bed" +#define MSG_STOPPED_HEATER ", system stopped! Heater_ID: " +#define MSG_REDUNDANCY "Heater switched off. Temperature difference between temp sensors is too high !" +#define MSG_T_HEATING_FAILED "Heating failed" +#define MSG_T_THERMAL_RUNAWAY "Thermal Runaway" +#define MSG_T_MAXTEMP "MAXTEMP triggered" +#define MSG_T_MINTEMP "MINTEMP triggered" + +// Debug +#define MSG_DEBUG_PREFIX "DEBUG:" +#define MSG_DEBUG_OFF "off" +#define MSG_DEBUG_ECHO "ECHO" +#define MSG_DEBUG_INFO "INFO" +#define MSG_DEBUG_ERRORS "ERRORS" +#define MSG_DEBUG_DRYRUN "DRYRUN" +#define MSG_DEBUG_COMMUNICATION "COMMUNICATION" +#define MSG_DEBUG_LEVELING "LEVELING" + +// LCD Menu Messages + +#define LANGUAGE_INCL_(M) STRINGIFY_(language_##M.h) +#define LANGUAGE_INCL(M) LANGUAGE_INCL_(M) +#define INCLUDE_LANGUAGE LANGUAGE_INCL(LCD_LANGUAGE) + +#include INCLUDE_LANGUAGE +#include "language_en.h" + +#endif //__LANGUAGE_H diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_an.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_an.h new file mode 100644 index 00000000..bfabc0a5 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_an.h @@ -0,0 +1,157 @@ +/** + * 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 . + * + */ + +/** + * Aragonese + * + * LCD Menu Messages + * See also https://github.com/MarlinFirmware/Marlin/wiki/LCD-Language + * + */ +#ifndef LANGUAGE_AN_H +#define LANGUAGE_AN_H + +// Define SIMULATE_ROMFONT to see what is seen on the character based display defined in Configuration.h +//#define SIMULATE_ROMFONT +#define DISPLAY_CHARSET_ISO10646_1 + +#define WELCOME_MSG MACHINE_NAME " parada." +#define MSG_SD_INSERTED "Tarcheta colocada" +#define MSG_SD_REMOVED "Tarcheta retirada" +#define MSG_MAIN "Menu prencipal" +#define MSG_AUTOSTART " Autostart" +#define MSG_DISABLE_STEPPERS "Amortar motors" +#define MSG_AUTO_HOME "Levar a l'orichen" +#define MSG_LEVEL_BED_HOMING "Homing XYZ" +#define MSG_LEVEL_BED_WAITING "Click to Begin" +#define MSG_LEVEL_BED_DONE "Leveling Done!" +#define MSG_LEVEL_BED_CANCEL "Cancel" +#define MSG_SET_HOME_OFFSETS "Set home offsets" +#define MSG_HOME_OFFSETS_APPLIED "Offsets applied" +#define MSG_SET_ORIGIN "Establir zero" +#define MSG_PREHEAT_1 "Precalentar PLA" +#define MSG_PREHEAT_1_N "Precalentar PLA " +#define MSG_PREHEAT_1_ALL "Precalentar PLA a" +#define MSG_PREHEAT_1_BEDONLY "Prec. PLA Base" +#define MSG_PREHEAT_1_SETTINGS "Achustar tem. PLA" +#define MSG_PREHEAT_2 "Precalentar ABS" +#define MSG_PREHEAT_2_N "Precalentar ABS " +#define MSG_PREHEAT_2_ALL "Precalentar ABS a" +#define MSG_PREHEAT_2_BEDONLY "Prec. ABS Base" +#define MSG_PREHEAT_2_SETTINGS "Achustar tem. ABS" +#define MSG_COOLDOWN "Enfriar" +#define MSG_SWITCH_PS_ON "Enchegar Fuent" +#define MSG_SWITCH_PS_OFF "Desenchegar Fuent" +#define MSG_EXTRUDE "Extruir" +#define MSG_RETRACT "Retraer" +#define MSG_MOVE_AXIS "Mover Eixes" +#define MSG_MOVE_X "Move X" +#define MSG_MOVE_Y "Move Y" +#define MSG_MOVE_Z "Move Z" +#define MSG_MOVE_E "Extruder" +#define MSG_MOVE_01MM "Move 0.1mm" +#define MSG_MOVE_1MM "Move 1mm" +#define MSG_MOVE_10MM "Move 10mm" +#define MSG_SPEED "Velocidat" +#define MSG_NOZZLE "Nozzle" +#define MSG_BED "Base" +#define MSG_FAN_SPEED "Ixoriador" +#define MSG_FLOW "Fluxo" +#define MSG_CONTROL "Control" +#define MSG_MIN LCD_STR_THERMOMETER " Min" +#define MSG_MAX LCD_STR_THERMOMETER " Max" +#define MSG_FACTOR LCD_STR_THERMOMETER " Fact" +#define MSG_AUTOTEMP "Autotemp" +#define MSG_ON "On" +#define MSG_OFF "Off" +#define MSG_PID_P "PID-P" +#define MSG_PID_I "PID-I" +#define MSG_PID_D "PID-D" +#define MSG_PID_C "PID-C" +#define MSG_ACC "Acel" +#define MSG_VXY_JERK "Vxy-jerk" +#define MSG_VZ_JERK "Vz-jerk" +#define MSG_VE_JERK "Ves-jerk" +#define MSG_VMAX "Vmax" +#define MSG_X "X" +#define MSG_Y "Y" +#define MSG_Z "Z" +#define MSG_E "E" +#define MSG_VMIN "Vmin" +#define MSG_VTRAV_MIN "VTrav min" +#define MSG_AMAX "Amax" +#define MSG_A_RETRACT "A-retrac." +#define MSG_XSTEPS "X trangos/mm" +#define MSG_YSTEPS "Y trangos/mm" +#define MSG_ZSTEPS "Z trangos/mm" +#define MSG_ESTEPS "E trangos/mm" +#define MSG_TEMPERATURE "Temperatura" +#define MSG_MOTION "Movimiento" +#define MSG_VOLUMETRIC "Filament" +#define MSG_VOLUMETRIC_ENABLED "E in mm3" +#define MSG_FILAMENT_DIAM "Fil. Dia." +#define MSG_CONTRAST "Contrast" +#define MSG_STORE_EPROM "Alzar Memoria" +#define MSG_LOAD_EPROM "Cargar Memoria" +#define MSG_RESTORE_FAILSAFE "Rest. d'emerchen." +#define MSG_REFRESH "Tornar a cargar" +#define MSG_WATCH "Monitorizar" +#define MSG_PREPARE "Preparar" +#define MSG_TUNE "Achustar" +#define MSG_PAUSE_PRINT "Pausar impresion" +#define MSG_RESUME_PRINT "Contin. impresion" +#define MSG_STOP_PRINT "Detener Impresion" +#define MSG_CARD_MENU "Menu de SD" +#define MSG_NO_CARD "No i hai tarcheta" +#define MSG_DWELL "Reposo..." +#define MSG_USERWAIT "Asperan. ordines" +#define MSG_RESUMING "Contin. impresion" +#define MSG_PRINT_ABORTED "Print aborted" +#define MSG_NO_MOVE "Sin movimiento" +#define MSG_KILLED "ATURADA D'EMERCH." +#define MSG_STOPPED "ATURADA." +#define MSG_CONTROL_RETRACT "Retraer mm" +#define MSG_CONTROL_RETRACT_SWAP "Swap Retraer mm" +#define MSG_CONTROL_RETRACTF "Retraer F" +#define MSG_CONTROL_RETRACT_ZLIFT "Devantar mm" +#define MSG_CONTROL_RETRACT_RECOVER "DesRet +mm" +#define MSG_CONTROL_RETRACT_RECOVER_SWAP "Swap DesRet +mm" +#define MSG_CONTROL_RETRACT_RECOVERF "DesRet F" +#define MSG_AUTORETRACT "AutoRetr." +#define MSG_FILAMENTCHANGE "Cambear" +#define MSG_INIT_SDCARD "Encetan. tarcheta" +#define MSG_CNG_SDCARD "Cambiar tarcheta" +#define MSG_ZPROBE_OUT "Z probe out. bed" +#define MSG_HOME "Home" // Used as MSG_HOME " " MSG_X MSG_Y MSG_Z " " MSG_FIRST +#define MSG_FIRST "first" +#define MSG_ZPROBE_ZOFFSET "Z Offset" +#define MSG_BABYSTEP_X "Babystep X" +#define MSG_BABYSTEP_Y "Babystep Y" +#define MSG_BABYSTEP_Z "Babystep Z" +#define MSG_ENDSTOP_ABORT "Endstop abort" +#define MSG_DELTA_CALIBRATE "Delta Calibration" +#define MSG_DELTA_CALIBRATE_X "Calibrate X" +#define MSG_DELTA_CALIBRATE_Y "Calibrate Y" +#define MSG_DELTA_CALIBRATE_Z "Calibrate Z" +#define MSG_DELTA_CALIBRATE_CENTER "Calibrate Center" + +#endif // LANGUAGE_AN_H diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_bg.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_bg.h new file mode 100644 index 00000000..51606947 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_bg.h @@ -0,0 +1,159 @@ +/** + * 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 . + * + */ + +/** + * Bulgarian + * + * LCD Menu Messages + * See also https://github.com/MarlinFirmware/Marlin/wiki/LCD-Language + * + */ +#ifndef LANGUAGE_BG_H +#define LANGUAGE_BG_H + +#define MAPPER_D0D1 // For Cyrillic +// Define SIMULATE_ROMFONT to see what is seen on the character based display defined in Configuration.h +//#define SIMULATE_ROMFONT +#define DISPLAY_CHARSET_ISO10646_5 + +#define WELCOME_MSG MACHINE_NAME " Готов." +#define MSG_SD_INSERTED "Картата е поставена" +#define MSG_SD_REMOVED "Картата е извадена" +#define MSG_MAIN "Меню" +#define MSG_AUTOSTART "Автостарт" +#define MSG_DISABLE_STEPPERS "Изкл. двигатели" +#define MSG_AUTO_HOME "Паркиране" +#define MSG_LEVEL_BED_HOMING "Homing XYZ" +#define MSG_LEVEL_BED_WAITING "Click to Begin" +#define MSG_LEVEL_BED_DONE "Leveling Done!" +#define MSG_LEVEL_BED_CANCEL "Cancel" +#define MSG_SET_HOME_OFFSETS "Задай Начало" +#define MSG_HOME_OFFSETS_APPLIED "Offsets applied" +#define MSG_SET_ORIGIN "Изходна точка" +#define MSG_PREHEAT_1 "Подгряване PLA" +#define MSG_PREHEAT_1_N "Подгряване PLA" +#define MSG_PREHEAT_1_ALL "Подгр. PLA Всички" +#define MSG_PREHEAT_1_BEDONLY "Подгр. PLA Легло" +#define MSG_PREHEAT_1_SETTINGS "Настройки PLA" +#define MSG_PREHEAT_2 "Подгряване ABS" +#define MSG_PREHEAT_2_N "Подгряване ABS" +#define MSG_PREHEAT_2_ALL "Подгр. ABS Всички" +#define MSG_PREHEAT_2_BEDONLY "Подгр. ABS Легло" +#define MSG_PREHEAT_2_SETTINGS "Настройки ABS" +#define MSG_COOLDOWN "Охлаждане" +#define MSG_SWITCH_PS_ON "Вкл. захранване" +#define MSG_SWITCH_PS_OFF "Изкл. захранване" +#define MSG_EXTRUDE "Екструзия" +#define MSG_RETRACT "Откат" +#define MSG_MOVE_AXIS "Движение по ос" +#define MSG_LEVEL_BED "Нивелиране" +#define MSG_MOVE_X "Движение по X" +#define MSG_MOVE_Y "Движение по Y" +#define MSG_MOVE_Z "Движение по Z" +#define MSG_MOVE_E "Екструдер" +#define MSG_MOVE_01MM "Премести с 0.1mm" +#define MSG_MOVE_1MM "Премести с 1mm" +#define MSG_MOVE_10MM "Премести с 10mm" +#define MSG_SPEED "Скорост" +#define MSG_NOZZLE LCD_STR_THERMOMETER " Дюза" +#define MSG_BED LCD_STR_THERMOMETER " Легло" +#define MSG_FAN_SPEED "Вентилатор" +#define MSG_FLOW "Поток" +#define MSG_CONTROL "Управление" +#define MSG_MIN LCD_STR_THERMOMETER " Минимум" +#define MSG_MAX LCD_STR_THERMOMETER " Максимум" +#define MSG_FACTOR LCD_STR_THERMOMETER " Фактор" +#define MSG_AUTOTEMP "Авто-темп." +#define MSG_ON "Вкл. " +#define MSG_OFF "Изкл. " +#define MSG_PID_P "PID-P" +#define MSG_PID_I "PID-I" +#define MSG_PID_D "PID-D" +#define MSG_PID_C "PID-C" +#define MSG_ACC "Acc" +#define MSG_VXY_JERK "Vxy-jerk" +#define MSG_VZ_JERK "Vz-jerk" +#define MSG_VE_JERK "Ve-jerk" +#define MSG_VMAX "Vmax " +#define MSG_X "X" +#define MSG_Y "Y" +#define MSG_Z "Z" +#define MSG_E "E" +#define MSG_VMIN "Vmin" +#define MSG_VTRAV_MIN "VTrav min" +#define MSG_AMAX "Amax " +#define MSG_A_RETRACT "A-откат" +#define MSG_XSTEPS "X стъпки/mm" +#define MSG_YSTEPS "Y стъпки/mm" +#define MSG_ZSTEPS "Z стъпки/mm" +#define MSG_ESTEPS "E стъпки/mm" +#define MSG_TEMPERATURE "Температура" +#define MSG_MOTION "Движение" +#define MSG_VOLUMETRIC "Нишка" +#define MSG_VOLUMETRIC_ENABLED "E in mm3" +#define MSG_FILAMENT_DIAM "Диам. нишка" +#define MSG_CONTRAST "LCD контраст" +#define MSG_STORE_EPROM "Запази в EPROM" +#define MSG_LOAD_EPROM "Зареди от EPROM" +#define MSG_RESTORE_FAILSAFE "Фабрични настройки" +#define MSG_REFRESH LCD_STR_REFRESH "Обнови" +#define MSG_WATCH "Преглед" +#define MSG_PREPARE "Действия" +#define MSG_TUNE "Настройка" +#define MSG_PAUSE_PRINT "Пауза" +#define MSG_RESUME_PRINT "Възобнови печата" +#define MSG_STOP_PRINT "Спри печата" +#define MSG_CARD_MENU "Меню карта" +#define MSG_NO_CARD "Няма карта" +#define MSG_DWELL "Почивка..." +#define MSG_USERWAIT "Изчакване" +#define MSG_RESUMING "Продълж. печата" +#define MSG_PRINT_ABORTED "Печатът е прекъснат" +#define MSG_NO_MOVE "Няма движение" +#define MSG_KILLED "УБИТО." +#define MSG_STOPPED "СПРЯНО." +#define MSG_CONTROL_RETRACT "Откат mm" +#define MSG_CONTROL_RETRACT_SWAP "Смяна Откат mm" +#define MSG_CONTROL_RETRACTF "Откат V" +#define MSG_CONTROL_RETRACT_ZLIFT "Скок mm" +#define MSG_CONTROL_RETRACT_RECOVER "Възврат +mm" +#define MSG_CONTROL_RETRACT_RECOVER_SWAP "Смяна Възврат +mm" +#define MSG_CONTROL_RETRACT_RECOVERF "Възврат V" +#define MSG_AUTORETRACT "Автоoткат" +#define MSG_FILAMENTCHANGE "Смяна нишка" +#define MSG_INIT_SDCARD "Иниц. SD-Карта" +#define MSG_CNG_SDCARD "Смяна SD-Карта" +#define MSG_ZPROBE_OUT "Z-сондата е извадена" +#define MSG_HOME "Home" // Used as MSG_HOME " " MSG_X MSG_Y MSG_Z " " MSG_FIRST +#define MSG_FIRST "first" +#define MSG_ZPROBE_ZOFFSET "Z Отстояние" +#define MSG_BABYSTEP_X "Министъпка X" +#define MSG_BABYSTEP_Y "Министъпка Y" +#define MSG_BABYSTEP_Z "Министъпка Z" +#define MSG_ENDSTOP_ABORT "Стоп Кр.Изключватели" +#define MSG_DELTA_CALIBRATE "Делта Калибровка" +#define MSG_DELTA_CALIBRATE_X "Калибровка X" +#define MSG_DELTA_CALIBRATE_Y "Калибровка Y" +#define MSG_DELTA_CALIBRATE_Z "Калибровка Z" +#define MSG_DELTA_CALIBRATE_CENTER "Калибровка Център" + +#endif // LANGUAGE_BG_H diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_ca.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_ca.h new file mode 100644 index 00000000..b90f1c39 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_ca.h @@ -0,0 +1,158 @@ +/** + * 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 . + * + */ + +/** + * Catalan + * + * LCD Menu Messages + * See also https://github.com/MarlinFirmware/Marlin/wiki/LCD-Language + * + */ +#ifndef LANGUAGE_CA_H +#define LANGUAGE_CA_H + +#define MAPPER_C2C3 // because of "ó" +// Define SIMULATE_ROMFONT to see what is seen on the character based display defined in Configuration.h +//#define SIMULATE_ROMFONT +#define DISPLAY_CHARSET_ISO10646_1 + +#define WELCOME_MSG MACHINE_NAME " preparada." +#define MSG_SD_INSERTED "SD detectada." +#define MSG_SD_REMOVED "SD expulsada." +#define MSG_MAIN "Menu principal" +#define MSG_AUTOSTART "Inici automatic" +#define MSG_DISABLE_STEPPERS "Apagar motors" +#define MSG_AUTO_HOME "Home global" +#define MSG_LEVEL_BED_HOMING "Homing XYZ" +#define MSG_LEVEL_BED_WAITING "Click to Begin" +#define MSG_LEVEL_BED_DONE "Leveling Done!" +#define MSG_LEVEL_BED_CANCEL "Cancel" +#define MSG_SET_HOME_OFFSETS "Set home offsets" +#define MSG_HOME_OFFSETS_APPLIED "Offsets applied" +#define MSG_SET_ORIGIN "Establir origen" +#define MSG_PREHEAT_1 "Preescalfar PLA" +#define MSG_PREHEAT_1_N "Preescalfar PLA " +#define MSG_PREHEAT_1_ALL "Preesc. tot PLA" +#define MSG_PREHEAT_1_BEDONLY "Preesc. llit PLA" +#define MSG_PREHEAT_1_SETTINGS "Configuració PLA" +#define MSG_PREHEAT_2 "Preescalfar ABS" +#define MSG_PREHEAT_2_N "Preescalfar ABS " +#define MSG_PREHEAT_2_ALL "Preesc. tot ABS" +#define MSG_PREHEAT_2_BEDONLY "Preesc. llit ABS" +#define MSG_PREHEAT_2_SETTINGS "Configuració ABS" +#define MSG_COOLDOWN "Refredar" +#define MSG_SWITCH_PS_ON "Switch power on" +#define MSG_SWITCH_PS_OFF "Switch power off" +#define MSG_EXTRUDE "Extruir" +#define MSG_RETRACT "Refredar" +#define MSG_MOVE_AXIS "Moure eixos" +#define MSG_MOVE_X "Moure X" +#define MSG_MOVE_Y "Moure Y" +#define MSG_MOVE_Z "Moure Z" +#define MSG_MOVE_E "Extrusor" +#define MSG_MOVE_01MM "Moure 0.1mm" +#define MSG_MOVE_1MM "Moure 1mm" +#define MSG_MOVE_10MM "Moure 10mm" +#define MSG_SPEED "Velocitat" +#define MSG_NOZZLE "Nozzle" +#define MSG_BED "Llit" +#define MSG_FAN_SPEED "Vel. Ventilador" +#define MSG_FLOW "Fluxe" +#define MSG_CONTROL "Control" +#define MSG_MIN LCD_STR_THERMOMETER " Min" +#define MSG_MAX LCD_STR_THERMOMETER " Max" +#define MSG_FACTOR LCD_STR_THERMOMETER " Fact" +#define MSG_AUTOTEMP "Autotemp" +#define MSG_ON "On " +#define MSG_OFF "Off" +#define MSG_PID_P "PID-P" +#define MSG_PID_I "PID-I" +#define MSG_PID_D "PID-D" +#define MSG_PID_C "PID-C" +#define MSG_ACC "Accel" +#define MSG_VXY_JERK "Vxy-jerk" +#define MSG_VZ_JERK "Vz-jerk" +#define MSG_VE_JERK "Ve-jerk" +#define MSG_VMAX "Vmax " +#define MSG_X "X" +#define MSG_Y "Y" +#define MSG_Z "Z" +#define MSG_E "E" +#define MSG_VMIN "Vmin" +#define MSG_VTRAV_MIN "VTrav min" +#define MSG_AMAX "Amax " +#define MSG_A_RETRACT "A-retract" +#define MSG_XSTEPS "Xpassos/mm" +#define MSG_YSTEPS "Ypassos/mm" +#define MSG_ZSTEPS "Zpassos/mm" +#define MSG_ESTEPS "Epassos/mm" +#define MSG_TEMPERATURE "Temperatura" +#define MSG_MOTION "Moviment" +#define MSG_VOLUMETRIC "Filament" +#define MSG_VOLUMETRIC_ENABLED "E in mm3" +#define MSG_FILAMENT_DIAM "Fil. Dia." +#define MSG_CONTRAST "Contrast de LCD" +#define MSG_STORE_EPROM "Desar a memoria" +#define MSG_LOAD_EPROM "Carregar de mem." +#define MSG_RESTORE_FAILSAFE "Rest. emergencia" +#define MSG_REFRESH "Refrescar" +#define MSG_WATCH "Pantalla Info." +#define MSG_PREPARE "Preparar" +#define MSG_TUNE "Calibrar" +#define MSG_PAUSE_PRINT "Pausa imp." +#define MSG_RESUME_PRINT "Reprendre imp." +#define MSG_STOP_PRINT "Parar inp." +#define MSG_CARD_MENU "Imprimir de SD" +#define MSG_NO_CARD "-Sense targeta SD" +#define MSG_DWELL "Repos..." +#define MSG_USERWAIT "Esperant usuari.." +#define MSG_RESUMING "Reprenent imp." +#define MSG_PRINT_ABORTED "Print aborted" +#define MSG_NO_MOVE "Sense moviment." +#define MSG_KILLED "PARADA DE EMERG. " +#define MSG_STOPPED "ATURAT. " +#define MSG_CONTROL_RETRACT "Retreure mm" +#define MSG_CONTROL_RETRACT_SWAP "Swap Retreure mm" +#define MSG_CONTROL_RETRACTF "Retreure F" +#define MSG_CONTROL_RETRACT_ZLIFT "Aixecar mm" +#define MSG_CONTROL_RETRACT_RECOVER "DesRet +mm" +#define MSG_CONTROL_RETRACT_RECOVER_SWAP "Swap DesRet +mm" +#define MSG_CONTROL_RETRACT_RECOVERF "DesRet F" +#define MSG_AUTORETRACT "AutoRetr." +#define MSG_FILAMENTCHANGE "Canviar filament" +#define MSG_INIT_SDCARD "Iniciant SD" +#define MSG_CNG_SDCARD "Canviar SD" +#define MSG_ZPROBE_OUT "Z probe out. bed" +#define MSG_HOME "Home" // Used as MSG_HOME " " MSG_X MSG_Y MSG_Z " " MSG_FIRST +#define MSG_FIRST "first" +#define MSG_ZPROBE_ZOFFSET "Z Offset" +#define MSG_BABYSTEP_X "Babystep X" +#define MSG_BABYSTEP_Y "Babystep Y" +#define MSG_BABYSTEP_Z "Babystep Z" +#define MSG_ENDSTOP_ABORT "Endstop abort" +#define MSG_DELTA_CALIBRATE "Delta Calibration" +#define MSG_DELTA_CALIBRATE_X "Calibrate X" +#define MSG_DELTA_CALIBRATE_Y "Calibrate Y" +#define MSG_DELTA_CALIBRATE_Z "Calibrate Z" +#define MSG_DELTA_CALIBRATE_CENTER "Calibrate Center" + +#endif // LANGUAGE_CA_H diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_cn.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_cn.h new file mode 100644 index 00000000..86c639df --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_cn.h @@ -0,0 +1,162 @@ +/** + * 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 . + * + */ + +/** + * Chinese + * + * LCD Menu Messages + * See also https://github.com/MarlinFirmware/Marlin/wiki/LCD-Language + * + */ +#ifndef LANGUAGE_CN_H +#define LANGUAGE_CN_H +#define DISPLAY_CHARSET_ISO10646_CN + +#define WELCOME_MSG "\xa4\xa5\xa6\xa7" +#define MSG_SD_INSERTED "\xa8\xa9\xaa\xab" +#define MSG_SD_REMOVED "\xa8\xa9\xac\xad" +#define MSG_MAIN "\xae\xaf\xb0" +#define MSG_AUTOSTART "\xb1\xb2\xb3\xb4" +#define MSG_DISABLE_STEPPERS "\xb5\xb6\xb7\xb8\xb9\xba" +#define MSG_AUTO_HOME "\xbb\xbc\xbd" +#define MSG_LEVEL_BED_HOMING "Homing XYZ" +#define MSG_LEVEL_BED_WAITING "Click to Begin" +#define MSG_LEVEL_BED_DONE "Leveling Done!" +#define MSG_LEVEL_BED_CANCEL "Cancel" +#define MSG_SET_HOME_OFFSETS "\xbe\xbf\xbb\xbc\xbd\xc0\xc1" +#define MSG_HOME_OFFSETS_APPLIED "Offsets applied" +#define MSG_SET_ORIGIN "\xbe\xbf\xbc\xbd" +#define MSG_PREHEAT_1 "\xc3\xc4 PLA" +#define MSG_PREHEAT_1_N MSG_PREHEAT_1 " " +#define MSG_PREHEAT_1_ALL MSG_PREHEAT_1 " \xc5\xc6" +#define MSG_PREHEAT_1_BEDONLY MSG_PREHEAT_1 " \xc4\xc7" +#define MSG_PREHEAT_1_SETTINGS MSG_PREHEAT_1 " \xbe\xbf" +#define MSG_PREHEAT_2 "\xc3\xc4 ABS" +#define MSG_PREHEAT_2_N MSG_PREHEAT_2 " " +#define MSG_PREHEAT_2_ALL MSG_PREHEAT_2 " \xc5\xc6" +#define MSG_PREHEAT_2_BEDONLY MSG_PREHEAT_2 " \xbe\xc6" +#define MSG_PREHEAT_2_SETTINGS MSG_PREHEAT_2 " \xbe\xbf" +#define MSG_COOLDOWN "\xc8\xc9" +#define MSG_SWITCH_PS_ON "\xb9\xcb\xca\xb3" +#define MSG_SWITCH_PS_OFF "\xb9\xcb\xb5\xb6" +#define MSG_EXTRUDE "\xcc\xad" +#define MSG_RETRACT "\xbb\xcd" +#define MSG_MOVE_AXIS "\xc1\xb2\xce" +#define MSG_LEVEL_BED "\xcf\xe0\xc4\xc7" +#define MSG_MOVE_X "\xc1\xb2 X" +#define MSG_MOVE_Y "\xc1\xb2 Y" +#define MSG_MOVE_Z "\xc1\xb2 Z" +#define MSG_MOVE_E "\xcc\xad\xba" +#define MSG_MOVE_01MM "\xc1\xb2 0.1mm" +#define MSG_MOVE_1MM "\xc1\xb2 1mm" +#define MSG_MOVE_10MM "\xc1\xb2 10mm" +#define MSG_SPEED "\xd1\xd2" +#define MSG_NOZZLE "\xd3\xd4" +#define MSG_BED "\xc4\xc7" +#define MSG_FAN_SPEED "\xd5\xd6\xd1\xd2" +#define MSG_FLOW "\xcc\xad\xd1\xd2" +#define MSG_CONTROL "\xd8\xd9" +#define MSG_MIN LCD_STR_THERMOMETER " \xda\xdb" +#define MSG_MAX LCD_STR_THERMOMETER " \xda\xdc" +#define MSG_FACTOR LCD_STR_THERMOMETER " \xdd\xde" +#define MSG_AUTOTEMP "\xb1\xb2\xd8\xc9" +#define MSG_ON "\xb3 " // intentional space to shift wide symbol to the left +#define MSG_OFF "\xb5 " // intentional space to shift wide symbol to the left +#define MSG_PID_P "PID-P" +#define MSG_PID_I "PID-I" +#define MSG_PID_D "PID-D" +#define MSG_PID_C "PID-C" +#define MSG_ACC "Accel" +#define MSG_VXY_JERK "Vxy-jerk" +#define MSG_VZ_JERK "Vz-jerk" +#define MSG_VE_JERK "Ve-jerk" +#define MSG_VMAX "Vmax " +#define MSG_X "X" +#define MSG_Y "Y" +#define MSG_Z "Z" +#define MSG_E "E" +#define MSG_VMIN "Vmin" +#define MSG_VTRAV_MIN "VTrav min" +#define MSG_AMAX "Amax " +#define MSG_A_RETRACT "A-retract" +#define MSG_A_TRAVEL "A-travel" +#define MSG_XSTEPS "Xsteps/mm" +#define MSG_YSTEPS "Ysteps/mm" +#define MSG_ZSTEPS "Zsteps/mm" +#define MSG_ESTEPS "Esteps/mm" +#define MSG_TEMPERATURE "\xc9\xd2" +#define MSG_MOTION "\xdf\xb2" +#define MSG_VOLUMETRIC "Filament" +#define MSG_VOLUMETRIC_ENABLED "E in mm3" +#define MSG_FILAMENT_DIAM "Fil. Dia." +#define MSG_CONTRAST "LCD contrast" +#define MSG_STORE_EPROM "Store memory" +#define MSG_LOAD_EPROM "Load memory" +#define MSG_RESTORE_FAILSAFE "Restore failsafe" +#define MSG_REFRESH "Refresh" +#define MSG_WATCH "\xec\xed\xee\xef" +#define MSG_PREPARE "\xa4\xa5" +#define MSG_TUNE "\xcf\xf0" +#define MSG_PAUSE_PRINT "\xf1\xf2\xca\xf3" +#define MSG_RESUME_PRINT "\xf4\xf5\xca\xf3" +#define MSG_STOP_PRINT "\xf2\xf6\xca\xf3" +#define MSG_CARD_MENU "\xaf\xb0" +#define MSG_NO_CARD "\xf9\xa8" +#define MSG_DWELL "Sleep..." +#define MSG_USERWAIT "Wait for user..." +#define MSG_RESUMING "Resuming print" +#define MSG_PRINT_ABORTED "Print aborted" +#define MSG_NO_MOVE "No move." +#define MSG_KILLED "KILLED. " +#define MSG_STOPPED "STOPPED. " +#define MSG_CONTROL_RETRACT "Retract mm" +#define MSG_CONTROL_RETRACT_SWAP "Swap Re.mm" +#define MSG_CONTROL_RETRACTF "Retract V" +#define MSG_CONTROL_RETRACT_ZLIFT "Hop mm" +#define MSG_CONTROL_RETRACT_RECOVER "UnRet +mm" +#define MSG_CONTROL_RETRACT_RECOVER_SWAP "S UnRet+mm" +#define MSG_CONTROL_RETRACT_RECOVERF "UnRet V" +#define MSG_AUTORETRACT "AutoRetr." +#define MSG_FILAMENTCHANGE "Change filament" +#define MSG_INIT_SDCARD "Init. SD card" +#define MSG_CNG_SDCARD "Change SD card" +#define MSG_ZPROBE_OUT "Z probe out. bed" +#define MSG_HOME "Home" // Used as MSG_HOME " " MSG_X MSG_Y MSG_Z " " MSG_FIRST +#define MSG_FIRST "first" +#define MSG_ZPROBE_ZOFFSET "Z Offset" +#define MSG_BABYSTEP_X "Babystep X" +#define MSG_BABYSTEP_Y "Babystep Y" +#define MSG_BABYSTEP_Z "Babystep Z" +#define MSG_ENDSTOP_ABORT "Endstop abort" +#define MSG_HEATING_FAILED_LCD "Heating failed" +#define MSG_ERR_REDUNDANT_TEMP "Err: REDUNDANT TEMP" +#define MSG_THERMAL_RUNAWAY "THERMAL RUNAWAY" +#define MSG_ERR_MAXTEMP "Err: MAXTEMP" +#define MSG_ERR_MINTEMP "Err: MINTEMP" +#define MSG_ERR_MAXTEMP_BED "Err: MAXTEMP BED" +#define MSG_DELTA_CALIBRATE "Delta Calibration" +#define MSG_DELTA_CALIBRATE_X "Calibrate X" +#define MSG_DELTA_CALIBRATE_Y "Calibrate Y" +#define MSG_DELTA_CALIBRATE_Z "Calibrate Z" +#define MSG_DELTA_CALIBRATE_CENTER "Calibrate Center" + +#endif // LANGUAGE_CN_H diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_cz.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_cz.h new file mode 100644 index 00000000..742cd8c1 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_cz.h @@ -0,0 +1,262 @@ +/** + * 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 . + * + */ + +/** + * Czech + * + * LCD Menu Messages + * See also https://github.com/MarlinFirmware/Marlin/wiki/LCD-Language + * + * Translated by Petr Zahradnik, Computer Laboratory + * Blog and video blog Zahradnik se bavi + * http://www.zahradniksebavi.cz + * + */ +#ifndef LANGUAGE_CZ_H +#define LANGUAGE_CZ_H + +// Define SIMULATE_ROMFONT to see what is seen on the character based display defined in Configuration.h +//#define SIMULATE_ROMFONT +#define DISPLAY_CHARSET_ISO10646_1 + +#define WELCOME_MSG MACHINE_NAME " pripraven." +#define MSG_SD_INSERTED "Karta vlozena" +#define MSG_SD_REMOVED "Karta vyjmuta" +#define MSG_LCD_ENDSTOPS "Endstopy" // maximalne 8 znaku +#define MSG_MAIN "Hlavni nabidka" +#define MSG_AUTOSTART "Autostart" +#define MSG_DISABLE_STEPPERS "Uvolnit motory" +#define MSG_AUTO_HOME "Domovska pozice" +#define MSG_AUTO_HOME_X "Domu osa X" +#define MSG_AUTO_HOME_Y "Domu osa Y" +#define MSG_AUTO_HOME_Z "Domu osa Z" +#define MSG_LEVEL_BED_HOMING "Mereni podlozky" +#define MSG_LEVEL_BED_WAITING "Kliknutim spustte" +#define MSG_LEVEL_BED_NEXT_POINT "Dalsi bod" +#define MSG_LEVEL_BED_DONE "Mereni hotovo!" +#define MSG_LEVEL_BED_CANCEL "Storno" +#define MSG_SET_HOME_OFFSETS "Nastavit ofsety" +#define MSG_HOME_OFFSETS_APPLIED "Ofsety nastaveny" +#define MSG_SET_ORIGIN "Nastavit pocatek" +#define MSG_PREHEAT_1 "Zahrat PLA" +#define MSG_PREHEAT_1_N MSG_PREHEAT_1 " " +#define MSG_PREHEAT_1_ALL MSG_PREHEAT_1 " Vse" +#define MSG_PREHEAT_1_BEDONLY MSG_PREHEAT_1 " Podloz" +#define MSG_PREHEAT_1_SETTINGS MSG_PREHEAT_1 " Nast" +#define MSG_PREHEAT_2 "Zahrat ABS" +#define MSG_PREHEAT_2_N MSG_PREHEAT_2 " " +#define MSG_PREHEAT_2_ALL MSG_PREHEAT_2 " Vse" +#define MSG_PREHEAT_2_BEDONLY MSG_PREHEAT_2 " Podloz" +#define MSG_PREHEAT_2_SETTINGS MSG_PREHEAT_2 " Nast" +#define MSG_H1 "1" +#define MSG_H2 "2" +#define MSG_H3 "3" +#define MSG_H4 "4" +#define MSG_COOLDOWN "Zchladit" +#define MSG_SWITCH_PS_ON "Zapnout napajeni" +#define MSG_SWITCH_PS_OFF "Vypnout napajeni" +#define MSG_EXTRUDE "Vytlacit (extr.)" +#define MSG_RETRACT "Zatlacit (retr.)" +#define MSG_MOVE_AXIS "Posunout osy" +#define MSG_LEVEL_BED "Vyrovnat podlozku" +#define MSG_MOVE_X "Posunout X" +#define MSG_MOVE_Y "Posunout Y" +#define MSG_MOVE_Z "Posunout Z" +#define MSG_MOVE_E "Extruder" +#define MSG_MOVE_E1 "1" +#define MSG_MOVE_E2 "2" +#define MSG_MOVE_E3 "3" +#define MSG_MOVE_E4 "4" +#define MSG_MOVE_01MM "Posunout o 0,1mm" +#define MSG_MOVE_1MM "Posunout o 1mm" +#define MSG_MOVE_10MM "Posunout o 10mm" +#define MSG_SPEED "Rychlost" +#define MSG_BED_Z "Vyska podl." +#define MSG_NOZZLE "Tryska" +#define MSG_N1 " 1" +#define MSG_N2 " 2" +#define MSG_N3 " 3" +#define MSG_N4 " 4" +#define MSG_BED "Podlozka" +#define MSG_FAN_SPEED "Rychlost vent." +#define MSG_FLOW "Prutok" +#define MSG_CONTROL "Ovladani" +#define MSG_MIN " " LCD_STR_THERMOMETER " Min" +#define MSG_MAX " " LCD_STR_THERMOMETER " Max" +#define MSG_FACTOR " " LCD_STR_THERMOMETER " Fakt" +#define MSG_AUTOTEMP "Autoteplota" +#define MSG_ON "Zap" +#define MSG_OFF "Vyp" +#define MSG_PID_P "PID-P" +#define MSG_PID_I "PID-I" +#define MSG_PID_D "PID-D" +#define MSG_PID_C "PID-C" +#define MSG_SELECT "Vybrat" +#define MSG_E1 " E1" +#define MSG_E2 " E2" +#define MSG_E3 " E3" +#define MSG_E4 " E4" +#define MSG_ACC "Zrychl" +#define MSG_VXY_JERK "Vxy-jerk" +#define MSG_VZ_JERK "Vz-jerk" +#define MSG_VE_JERK "Ve-jerk" +#define MSG_VMAX "Vmax " +#define MSG_X "X" +#define MSG_Y "Y" +#define MSG_Z "Z" +#define MSG_E "E" +#define MSG_VMIN "Vmin" +#define MSG_VTRAV_MIN "VTrav min" +#define MSG_AMAX "Amax " +#define MSG_A_RETRACT "A-retrakt" +#define MSG_A_TRAVEL "A-prejezd" +#define MSG_XSTEPS "Xkroku/mm" +#define MSG_YSTEPS "Ykroku/mm" +#define MSG_ZSTEPS "Zkroku/mm" +#define MSG_ESTEPS "Ekroku/mm" +#define MSG_TEMPERATURE "Teplota" +#define MSG_MOTION "Pohyb" +#define MSG_VOLUMETRIC "Filament" +#define MSG_VOLUMETRIC_ENABLED "E na mm3" +#define MSG_FILAMENT_DIAM "Fil. Prum." +#define MSG_DIAM_E1 " 1" +#define MSG_DIAM_E2 " 2" +#define MSG_DIAM_E3 " 3" +#define MSG_DIAM_E4 " 4" +#define MSG_CONTRAST "Kontrast LCD" +#define MSG_STORE_EPROM "Ulozit nastaveni" +#define MSG_LOAD_EPROM "Nacist nastaveni" +#define MSG_RESTORE_FAILSAFE "Obnovit vychozi" +#define MSG_REFRESH "Obnovit" +#define MSG_WATCH "Info obrazovka" +#define MSG_PREPARE "Priprava tisku" +#define MSG_TUNE "Doladeni tisku" +#define MSG_PAUSE_PRINT "Pozastavit tisk" +#define MSG_RESUME_PRINT "Obnovit tisk" +#define MSG_STOP_PRINT "Zastavit tisk" +#define MSG_CARD_MENU "Tisknout z SD" +#define MSG_NO_CARD "Zadna SD karta" +#define MSG_DWELL "Uspano..." +#define MSG_USERWAIT "Cekani na uziv..." +#define MSG_RESUMING "Obnovovani tisku" +#define MSG_PRINT_ABORTED "Tisk zrusen" +#define MSG_NO_MOVE "Zadny pohyb." +#define MSG_KILLED "PRERUSENO. " +#define MSG_STOPPED "ZASTAVENO. " +#define MSG_CONTROL_RETRACT "Retrakt mm" +#define MSG_CONTROL_RETRACT_SWAP "Vymena Re.mm" +#define MSG_CONTROL_RETRACTF "Retraktovat V" +#define MSG_CONTROL_RETRACT_ZLIFT "Zvednuti Z mm" +#define MSG_CONTROL_RETRACT_RECOVER "UnRet +mm" +#define MSG_CONTROL_RETRACT_RECOVER_SWAP "S UnRet+mm" +#define MSG_CONTROL_RETRACT_RECOVERF "UnRet V" +#define MSG_AUTORETRACT "AutoRetr." +#define MSG_FILAMENTCHANGE "Vymenit filament" +#define MSG_INIT_SDCARD "Nacist SD kartu" +#define MSG_CNG_SDCARD "Vymenit SD kartu" +#define MSG_ZPROBE_OUT "Sonda Z mimo podl" +#define MSG_HOME "Domu" // Used as MSG_HOME " " MSG_X MSG_Y MSG_Z " " MSG_FIRST +#define MSG_FIRST "prvni" +#define MSG_ZPROBE_ZOFFSET "Z ofset" +#define MSG_BABYSTEP_X "Babystep X" +#define MSG_BABYSTEP_Y "Babystep Y" +#define MSG_BABYSTEP_Z "Babystep Z" +#define MSG_ENDSTOP_ABORT "Endstop abort" +#define MSG_HEATING_FAILED_LCD "Chyba zahrivani" +#define MSG_ERR_REDUNDANT_TEMP "REDUND. TEPLOTA" +#define MSG_THERMAL_RUNAWAY "TEPLOTNI SKOK" +#define MSG_ERR_MAXTEMP "VYSOKA TEPLOTA" +#define MSG_ERR_MINTEMP "NIZKA TEPLOTA" +#define MSG_ERR_MAXTEMP_BED "VYS. TEPL. PODL." +#define MSG_ERR_MINTEMP_BED "NIZ. TEPL. PODL." +#define MSG_HALTED "TISK. ZASTAVENA" +#define MSG_PLEASE_RESET "Provedte reset" +#define MSG_SHORT_DAY "d" +#define MSG_SHORT_HOUR "h" +#define MSG_SHORT_MINUTE "m" +#define MSG_HEATING "Zahrivani..." +#define MSG_HEATING_COMPLETE "Zahrati hotovo." +#define MSG_BED_HEATING "Zahrivani podl." +#define MSG_BED_DONE "Podlozka hotova." +#define MSG_DELTA_CALIBRATE "Delta Kalibrace" +#define MSG_DELTA_CALIBRATE_X "Kalibrovat X" +#define MSG_DELTA_CALIBRATE_Y "Kalibrovat Y" +#define MSG_DELTA_CALIBRATE_Z "Kalibrovat Z" +#define MSG_DELTA_CALIBRATE_CENTER "Kalibrovat Stred" +#define MSG_INFO_MENU "O tiskarne" +#define MSG_INFO_PRINTER_MENU "Info o tiskarne" +#define MSG_INFO_STATS_MENU "Statistika" +#define MSG_INFO_BOARD_MENU "Info o desce" +#define MSG_INFO_THERMISTOR_MENU "Termistory" +#define MSG_INFO_EXTRUDERS "Extrudery" +#define MSG_INFO_BAUDRATE "Rychlost" +#define MSG_INFO_PROTOCOL "Protokol" +#if LCD_WIDTH > 19 + #define MSG_INFO_PRINT_COUNT "Pocet tisku" + #define MSG_INFO_COMPLETED_PRINTS "Dokonceno" + #define MSG_INFO_PRINT_TIME "Celkovy cas" + #define MSG_INFO_PRINT_LONGEST "Nejdelsi tisk" + #define MSG_INFO_PRINT_FILAMENT "Celkem vytlaceno" +#else + #define MSG_INFO_PRINT_COUNT "Tisky" + #define MSG_INFO_COMPLETED_PRINTS "Hotovo" + #define MSG_INFO_PRINT_TIME "Cas" + #define MSG_INFO_PRINT_LONGEST "Nejdelsi" + #define MSG_INFO_PRINT_FILAMENT "Vytlaceno" +#endif +#define MSG_INFO_MIN_TEMP "Teplota min" +#define MSG_INFO_MAX_TEMP "Teplota max" +#define MSG_INFO_PSU "Nap. zdroj" + +#define MSG_FILAMENT_CHANGE_HEADER "VYMENA FILAMENTU" +#define MSG_FILAMENT_CHANGE_OPTION_HEADER "CO DAL?" +#define MSG_FILAMENT_CHANGE_OPTION_EXTRUDE "Jeste vytlacit" +#define MSG_FILAMENT_CHANGE_OPTION_RESUME "Obnovit tisk" +#if LCD_HEIGHT >= 4 + #define MSG_FILAMENT_CHANGE_INIT_1 "Cekejte prosim" + #define MSG_FILAMENT_CHANGE_INIT_2 "na zahajeni" + #define MSG_FILAMENT_CHANGE_INIT_3 "vymeny filamentu" + #define MSG_FILAMENT_CHANGE_UNLOAD_1 "Cekejte prosim" + #define MSG_FILAMENT_CHANGE_UNLOAD_2 "na vysunuti" + #define MSG_FILAMENT_CHANGE_UNLOAD_3 "filamentu" + #define MSG_FILAMENT_CHANGE_INSERT_1 "Vlozte filament" + #define MSG_FILAMENT_CHANGE_INSERT_2 "a stisknete" + #define MSG_FILAMENT_CHANGE_INSERT_3 "tlacitko..." + #define MSG_FILAMENT_CHANGE_LOAD_1 "Cekejte prosim" + #define MSG_FILAMENT_CHANGE_LOAD_2 "na zavedeni" + #define MSG_FILAMENT_CHANGE_LOAD_3 "filamentu" + #define MSG_FILAMENT_CHANGE_EXTRUDE_1 "Cekejte prosim" + #define MSG_FILAMENT_CHANGE_EXTRUDE_2 "na vytlaceni" + #define MSG_FILAMENT_CHANGE_EXTRUDE_3 "filamentu" + #define MSG_FILAMENT_CHANGE_RESUME_1 "Cekejte prosim" + #define MSG_FILAMENT_CHANGE_RESUME_2 "na pokracovani" + #define MSG_FILAMENT_CHANGE_RESUME_3 "tisku" +#else // LCD_HEIGHT < 4 + #define MSG_FILAMENT_CHANGE_INIT_1 "Cekejte..." + #define MSG_FILAMENT_CHANGE_UNLOAD_1 "Vysouvani..." + #define MSG_FILAMENT_CHANGE_INSERT_1 "Vlozte, kliknete" + #define MSG_FILAMENT_CHANGE_LOAD_1 "Zavadeni..." + #define MSG_FILAMENT_CHANGE_EXTRUDE_1 "Vytlacovani..." + #define MSG_FILAMENT_CHANGE_RESUME_1 "Pokracovani..." +#endif // LCD_HEIGHT < 4 + +#endif // LANGUAGE_CZ_H diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_da.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_da.h new file mode 100644 index 00000000..b107ca05 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_da.h @@ -0,0 +1,197 @@ +/** + * 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 . + * + */ + +/** + * Danish + * + * LCD Menu Messages + * See also https://github.com/MarlinFirmware/Marlin/wiki/LCD-Language + * + */ +#ifndef LANGUAGE_DA_H +#define LANGUAGE_DA_H + +#define MAPPER_C2C3 +// Define SIMULATE_ROMFONT to see what is seen on the character based display defined in Configuration.h +//#define SIMULATE_ROMFONT +#define DISPLAY_CHARSET_ISO10646_1 + +#define WELCOME_MSG MACHINE_NAME " er klar" +#define MSG_SD_INSERTED "Kort isat" +#define MSG_SD_REMOVED "Kort fjernet" +#define MSG_LCD_ENDSTOPS "Endstops" // Max length 8 characters +#define MSG_MAIN "Menu" +#define MSG_AUTOSTART "Autostart" +#define MSG_DISABLE_STEPPERS "Slå alle steppere fra" +#define MSG_AUTO_HOME "Auto Home" // G28 +#define MSG_AUTO_HOME_X "Home X" +#define MSG_AUTO_HOME_Y "Home Y" +#define MSG_AUTO_HOME_Z "Home Z" +#define MSG_LEVEL_BED_HOMING "Homing XYZ" +#define MSG_LEVEL_BED_WAITING "Tryk for at starte bed level" +#define MSG_LEVEL_BED_NEXT_POINT "Næste punkt" +#define MSG_LEVEL_BED_DONE "Bed level er færdig!" +#define MSG_LEVEL_BED_CANCEL "Annuller bed level" +#define MSG_SET_HOME_OFFSETS "Sæt forskyding af home" +#define MSG_HOME_OFFSETS_APPLIED "Forskydninger af home pos. er tilføjet" +#define MSG_SET_ORIGIN "Sæt origin" +#define MSG_PREHEAT_1 "Forvarm PLA" +#define MSG_PREHEAT_1_N "Forvarm PLA " +#define MSG_PREHEAT_1_ALL "Forvarm PLA Alle" +#define MSG_PREHEAT_1_BEDONLY "Forvarm PLA Bed" +#define MSG_PREHEAT_1_SETTINGS "Forvarm PLA conf" +#define MSG_PREHEAT_2 "Forvarm ABS" +#define MSG_PREHEAT_2_N "Forvarm ABS " +#define MSG_PREHEAT_2_ALL "Forvarm ABS Alle" +#define MSG_PREHEAT_2_BEDONLY "Forvarm ABS Bed" +#define MSG_PREHEAT_2_SETTINGS "Forvarm ABS conf" +#define MSG_H1 "1" +#define MSG_H2 "2" +#define MSG_H3 "3" +#define MSG_H4 "4" +#define MSG_COOLDOWN "Afkøl" +#define MSG_SWITCH_PS_ON "Slå strøm til" +#define MSG_SWITCH_PS_OFF "Slå strøm fra" +#define MSG_EXTRUDE "Extruder" +#define MSG_RETRACT "Retract" +#define MSG_MOVE_AXIS "Flyt akser" +#define MSG_LEVEL_BED "Juster bed" +#define MSG_MOVE_X "Flyt X" +#define MSG_MOVE_Y "Flyt Y" +#define MSG_MOVE_Z "Flyt Z" +#define MSG_MOVE_E "Extruder" +#define MSG_MOVE_E1 "1" +#define MSG_MOVE_E2 "2" +#define MSG_MOVE_E3 "3" +#define MSG_MOVE_E4 "4" +#define MSG_MOVE_01MM "Flyt 0.1mm" +#define MSG_MOVE_1MM "Flyt 1mm" +#define MSG_MOVE_10MM "Flyt 10mm" +#define MSG_SPEED "Hastighed" +#define MSG_BED_Z "Plade Z" +#define MSG_NOZZLE "Dyse" +#define MSG_N1 " 1" +#define MSG_N2 " 2" +#define MSG_N3 " 3" +#define MSG_N4 " 4" +#define MSG_BED "Plade" +#define MSG_FAN_SPEED "Blæser hastighed" +#define MSG_FLOW "Flow" +#define MSG_CONTROL "Kontrol" +#define MSG_MIN " \002 Min" +#define MSG_MAX " \002 Max" +#define MSG_FACTOR " \002 Fact" +#define MSG_AUTOTEMP "Autotemp" +#define MSG_ON "Til " +#define MSG_OFF "Fra" +#define MSG_PID_P "PID-P" +#define MSG_PID_I "PID-I" +#define MSG_PID_D "PID-D" +#define MSG_PID_C "PID-C" +#define MSG_E1 " E1" +#define MSG_E2 " E2" +#define MSG_E3 " E3" +#define MSG_E4 " E4" +#define MSG_ACC "Accel" +#define MSG_VXY_JERK "Vxy-jerk" +#define MSG_VZ_JERK "Vz-jerk" +#define MSG_VE_JERK "Ve-jerk" +#define MSG_VMAX "Vmax " +#define MSG_X "X" +#define MSG_Y "Y" +#define MSG_Z "Z" +#define MSG_E "E" +#define MSG_VMIN "Vmin" +#define MSG_VTRAV_MIN "VTrav min" +#define MSG_AMAX "Amax " +#define MSG_A_RETRACT "A-retract" +#define MSG_A_TRAVEL "A-rejse" +#define MSG_XSTEPS "Xsteps/mm" +#define MSG_YSTEPS "Ysteps/mm" +#define MSG_ZSTEPS "Zsteps/mm" +#define MSG_ESTEPS "Esteps/mm" +#define MSG_TEMPERATURE "Temperatur" +#define MSG_MOTION "Bevægelse" +#define MSG_VOLUMETRIC "Filament" +#define MSG_VOLUMETRIC_ENABLED "E in mm3" +#define MSG_FILAMENT_DIAM "Fil. Dia." +#define MSG_DIAM_E1 " 1" +#define MSG_DIAM_E2 " 2" +#define MSG_DIAM_E3 " 3" +#define MSG_DIAM_E4 " 4" +#define MSG_CONTRAST "LCD kontrast" +#define MSG_STORE_EPROM "Gem i EEPROM" +#define MSG_LOAD_EPROM "Hent fra EEPROM" +#define MSG_RESTORE_FAILSAFE "Gendan failsafe" +#define MSG_REFRESH "Genopfrisk" +#define MSG_WATCH "Info skærm" +#define MSG_PREPARE "Forbered" +#define MSG_TUNE "Tune" +#define MSG_PAUSE_PRINT "Pause printet" +#define MSG_RESUME_PRINT "Forsæt printet" +#define MSG_STOP_PRINT "Stop printet" +#define MSG_CARD_MENU "Print fra SD" +#define MSG_NO_CARD "Intet SD kort" +#define MSG_DWELL "Dvale..." +#define MSG_USERWAIT "Venter på bruger..." +#define MSG_RESUMING "Forsætter printet" +#define MSG_PRINT_ABORTED "Print annulleret" +#define MSG_NO_MOVE "Ingen bevægelse." +#define MSG_KILLED "DRÆBT. " +#define MSG_STOPPED "STOPPET. " +#define MSG_CONTROL_RETRACT "Tilbagetræk mm" +#define MSG_CONTROL_RETRACT_SWAP "Skift Re.mm" +#define MSG_CONTROL_RETRACTF "Tilbagetræk V" +#define MSG_CONTROL_RETRACT_ZLIFT "Hop mm" +#define MSG_CONTROL_RETRACT_RECOVER "UnRet +mm" +#define MSG_CONTROL_RETRACT_RECOVER_SWAP "S UnRet+mm" +#define MSG_CONTROL_RETRACT_RECOVERF "UnRet V" +#define MSG_AUTORETRACT "AutoRetr." +#define MSG_FILAMENTCHANGE "Skift filament" +#define MSG_INIT_SDCARD "Init. SD card" +#define MSG_CNG_SDCARD "Skift SD kort" +#define MSG_ZPROBE_OUT "Probe udenfor plade" +#define MSG_HOME "Home" // Used as MSG_HOME " " MSG_X MSG_Y MSG_Z " " MSG_FIRST +#define MSG_FIRST "first" +#define MSG_ZPROBE_ZOFFSET "Z Offset" +#define MSG_BABYSTEP_X "Babystep X" +#define MSG_BABYSTEP_Y "Babystep Y" +#define MSG_BABYSTEP_Z "Babystep Z" +#define MSG_ENDSTOP_ABORT "Endstop abort" +#define MSG_HEATING_FAILED_LCD "Opvarmning mislykkedes" +#define MSG_ERR_REDUNDANT_TEMP "Fejl: reserve temp" +#define MSG_THERMAL_RUNAWAY "Temp løber løbsk" +#define MSG_ERR_MAXTEMP "Fejl: Maks temp" +#define MSG_ERR_MINTEMP "Fejl: Min temp" +#define MSG_ERR_MAXTEMP_BED "Fejl: Maks Plsde temp" +#define MSG_ERR_MINTEMP_BED "Fejl: Min Plade temp" +#define MSG_HEATING "Opvarmer..." +#define MSG_HEATING_COMPLETE "Opvarmet" +#define MSG_BED_HEATING "Opvarmer plade" +#define MSG_BED_DONE "Plade opvarmet" +#define MSG_DELTA_CALIBRATE "Delta Kalibrering" +#define MSG_DELTA_CALIBRATE_X "Kalibrer X" +#define MSG_DELTA_CALIBRATE_Y "Kalibrer Y" +#define MSG_DELTA_CALIBRATE_Z "Kalibrer Z" +#define MSG_DELTA_CALIBRATE_CENTER "Kalibrerings Center" + +#endif // LANGUAGE_DA_H diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_de.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_de.h new file mode 100644 index 00000000..9744378f --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_de.h @@ -0,0 +1,227 @@ +/** + * 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 . + * + */ + +/** + * German + * + * LCD Menu Messages + * See also https://github.com/MarlinFirmware/Marlin/wiki/LCD-Language + * + */ +#ifndef LANGUAGE_DE_H +#define LANGUAGE_DE_H + +#define MAPPER_C2C3 +// Define SIMULATE_ROMFONT to see what is seen on the character based display defined in Configuration.h +//#define SIMULATE_ROMFONT +#define DISPLAY_CHARSET_ISO10646_1 + +#define WELCOME_MSG MACHINE_NAME " bereit" +#define MSG_SD_INSERTED "SD-Karte erkannt" +#define MSG_SD_REMOVED "SD-Karte entfernt" +#define MSG_MAIN "Hauptmenü" +#define MSG_AUTOSTART "Autostart" +#define MSG_DISABLE_STEPPERS "Motoren aus" // M84 +#define MSG_AUTO_HOME "Home" // G28 +#define MSG_LEVEL_BED_HOMING "Homing XYZ" +#define MSG_LEVEL_BED_WAITING "Klick für Start" +#define MSG_LEVEL_BED_DONE "Fertig" +#define MSG_LEVEL_BED_CANCEL "Abbruch" +#define MSG_SET_HOME_OFFSETS "Setze Homeoffsets" +#define MSG_HOME_OFFSETS_APPLIED "Offsets aktiv" +#define MSG_SET_ORIGIN "Setze Nullpunkt" //"G92 X0 Y0 Z0" commented out in ultralcd.cpp +#define MSG_PREHEAT_1 "Vorwärmen PLA" +#define MSG_PREHEAT_1_N "Vorwärmen PLA " +#define MSG_PREHEAT_1_ALL "Vorw. PLA Alle" +#define MSG_PREHEAT_1_BEDONLY "Vorw. PLA Bett" +#define MSG_PREHEAT_1_SETTINGS "Vorw. PLA Einst." +#define MSG_PREHEAT_2 "Vorwärmen ABS" +#define MSG_PREHEAT_2_N "Vorwärmen ABS " +#define MSG_PREHEAT_2_ALL "Vorw. ABS Alle" +#define MSG_PREHEAT_2_BEDONLY "Vorw. ABS Bett" +#define MSG_PREHEAT_2_SETTINGS "Vorw. ABS Einst." +#define MSG_COOLDOWN "Abkühlen" +#define MSG_SWITCH_PS_ON "Netzteil ein" +#define MSG_SWITCH_PS_OFF "Netzteil aus" +#define MSG_EXTRUDE "Extrudieren" +#define MSG_RETRACT "Retract" +#define MSG_MOVE_AXIS "Bewegen" +#define MSG_LEVEL_BED "Bett nivellieren" +#define MSG_MOVE_X "X" +#define MSG_MOVE_Y "Y" +#define MSG_MOVE_Z "Z" +#define MSG_MOVE_E "E" +#define MSG_MOVE_01MM " 0.1 mm" +#define MSG_MOVE_1MM " 1.0 mm" +#define MSG_MOVE_10MM "10.0 mm" +#define MSG_SPEED "Geschw." +#define MSG_BED_Z "Bett Z" +#define MSG_NOZZLE "Düse" +#define MSG_BED "Bett" +#define MSG_FAN_SPEED "Lüfter" +#define MSG_FLOW "Durchfluss" +#define MSG_CONTROL "Einstellungen" +#define MSG_MIN LCD_STR_THERMOMETER " min" +#define MSG_MAX LCD_STR_THERMOMETER " max" +#define MSG_FACTOR LCD_STR_THERMOMETER " Faktor" +#define MSG_AUTOTEMP "AutoTemp" +#define MSG_ON "Ein" +#define MSG_OFF "Aus" +#define MSG_PID_P "PID P" +#define MSG_PID_I "PID I" +#define MSG_PID_D "PID D" +#define MSG_PID_C "PID C" +#define MSG_ACC "A" +#define MSG_VXY_JERK "V XY Jerk" +#define MSG_VZ_JERK "V Z Jerk" +#define MSG_VE_JERK "V E Jerk" +#define MSG_VMAX "V max " // space by purpose +#define MSG_X "X" +#define MSG_Y "Y" +#define MSG_Z "Z" +#define MSG_E "E" +#define MSG_VMIN "V min" +#define MSG_VTRAV_MIN "V min Leerfahrt" +#define MSG_AMAX "A max " // space by purpose +#define MSG_A_RETRACT "A Retract" +#define MSG_A_TRAVEL "A Leerfahrt" +#define MSG_XSTEPS "X Steps/mm" +#define MSG_YSTEPS "Y Steps/mm" +#define MSG_ZSTEPS "Z Steps/mm" +#define MSG_ESTEPS "E Steps/mm" +#define MSG_TEMPERATURE "Temperatur" +#define MSG_MOTION "Bewegung" +#define MSG_VOLUMETRIC "Filament" +#define MSG_VOLUMETRIC_ENABLED "E in mm³" +#define MSG_FILAMENT_DIAM "D Fil." +#define MSG_CONTRAST "LCD Kontrast" +#define MSG_STORE_EPROM "EPROM speichern" +#define MSG_LOAD_EPROM "EPROM laden" +#define MSG_RESTORE_FAILSAFE "Standardkonfiguration" +#define MSG_REFRESH "Aktualisieren" +#define MSG_WATCH "Info" +#define MSG_PREPARE "Vorbereitung" +#define MSG_TUNE "Justierung" +#define MSG_PAUSE_PRINT "SD-Druck Pause" +#define MSG_RESUME_PRINT "SD-Druck Fortsetzung" +#define MSG_STOP_PRINT "SD-Druck Abbruch" +#define MSG_CARD_MENU "SD-Karte" +#define MSG_NO_CARD "Keine SD-Karte" +#define MSG_DWELL "Warten..." +#define MSG_USERWAIT "Warte auf Nutzer" +#define MSG_RESUMING "Druckfortsetzung" +#define MSG_PRINT_ABORTED "Druck abgebrochen" +#define MSG_NO_MOVE "Motoren eingeschaltet" +#define MSG_KILLED "KILLED" +#define MSG_STOPPED "ANGEHALTEN" +#define MSG_CONTROL_RETRACT "Retract mm" +#define MSG_CONTROL_RETRACT_SWAP "Wechs. Retract mm" +#define MSG_CONTROL_RETRACTF "Retract V" +#define MSG_CONTROL_RETRACT_ZLIFT "Z-Hop mm" +#define MSG_CONTROL_RETRACT_RECOVER "UnRet +mm" +#define MSG_CONTROL_RETRACT_RECOVER_SWAP "Wechs. UnRet +mm" +#define MSG_CONTROL_RETRACT_RECOVERF "UnRet V" +#define MSG_AUTORETRACT "AutoRetract" +#define MSG_FILAMENTCHANGE "Filament wechseln" +#define MSG_INIT_SDCARD "SD-Karte erkennen" // Manually initialize the SD-card via user interface +#define MSG_CNG_SDCARD "SD-Karte getauscht" // SD-card changed by user. For machines with no autocarddetect. Both send "M21" +#define MSG_ZPROBE_OUT "Sensor ausserhalb" +#define MSG_HOME "Vorher" // Used as MSG_HOME " " MSG_X MSG_Y MSG_Z " " MSG_FIRST +#define MSG_FIRST "homen" +#define MSG_ZPROBE_ZOFFSET "Z Offset" +#define MSG_BABYSTEP_X "Babystep X" +#define MSG_BABYSTEP_Y "Babystep Y" +#define MSG_BABYSTEP_Z "Babystep Z" +#define MSG_ENDSTOP_ABORT "Endstop-Abbr. ein" +#define MSG_HEATING_FAILED_LCD "HEIZEN FEHLGESCHLAGEN" +#define MSG_ERR_REDUNDANT_TEMP "REDUND. TEMPERATURABWEICHUNG" +#define MSG_THERMAL_RUNAWAY LCD_STR_THERMOMETER " NICHT ERREICHT" +#define MSG_ERR_MAXTEMP LCD_STR_THERMOMETER " ÜBERSCHRITTEN" +#define MSG_ERR_MINTEMP LCD_STR_THERMOMETER " UNTERSCHRITTEN" +#define MSG_ERR_MAXTEMP_BED "BETT " LCD_STR_THERMOMETER " ÜBERSCHRITTEN" +#define MSG_ERR_MINTEMP_BED "BETT " LCD_STR_THERMOMETER " UNTERSCHRITTEN" +#define MSG_HEATING "Aufheizen..." +#define MSG_HEATING_COMPLETE "Aufgeheizt" +#define MSG_BED_HEATING "Bett aufheizen" +#define MSG_BED_DONE "Bett aufgeheizt" +#define MSG_DELTA_CALIBRATE "Delta kalibrieren" +#define MSG_DELTA_CALIBRATE_X "Kalibriere X" +#define MSG_DELTA_CALIBRATE_Y "Kalibriere Y" +#define MSG_DELTA_CALIBRATE_Z "Kalibriere Z" +#define MSG_DELTA_CALIBRATE_CENTER "Kalibriere Mitte" + +#define MSG_INFO_MENU "Über den Drucker" +#define MSG_INFO_PRINTER_MENU "Drucker Info" +#define MSG_INFO_STATS_MENU "Drucker Stats" +#define MSG_INFO_BOARD_MENU "Board Info" +#define MSG_INFO_THERMISTOR_MENU "Thermistors" +#define MSG_INFO_EXTRUDERS "Extruders" +#define MSG_INFO_BAUDRATE "Baud" +#define MSG_INFO_PROTOCOL "Protokol" + +#if LCD_WIDTH > 19 + #define MSG_INFO_PRINT_COUNT "Gesamte Drucke " + #define MSG_INFO_COMPLETED_PRINTS "Beendete Drucke " + #define MSG_INFO_PRINT_TIME "Gesamte Druckzeit" +#else + #define MSG_INFO_PRINT_COUNT "Prints " + #define MSG_INFO_COMPLETED_PRINTS "Completed" + #define MSG_INFO_PRINT_TIME "Duration " +#endif +#define MSG_INFO_MIN_TEMP "Min Temp" +#define MSG_INFO_MAX_TEMP "Max Temp" +#define MSG_INFO_PSU "Stromversorgung" + +#define MSG_FILAMENT_CHANGE_HEADER "ÄNDERE FILAMENT" +#define MSG_FILAMENT_CHANGE_OPTION_HEADER "ÄNDERE OPTIONEN:" +#define MSG_FILAMENT_CHANGE_OPTION_EXTRUDE "Extrude mehr" +#define MSG_FILAMENT_CHANGE_OPTION_RESUME "Drucke weiter" + +#if LCD_HEIGHT >= 4 + #define MSG_FILAMENT_CHANGE_INIT_1 "Warte auf den" + #define MSG_FILAMENT_CHANGE_INIT_2 "Start zum " + #define MSG_FILAMENT_CHANGE_INIT_3 "Filament wechsel" + #define MSG_FILAMENT_CHANGE_UNLOAD_1 "Warte auf das" + #define MSG_FILAMENT_CHANGE_UNLOAD_2 "herrausnehmen" + #define MSG_FILAMENT_CHANGE_UNLOAD_3 "des Filaments" + #define MSG_FILAMENT_CHANGE_INSERT_1 "Fädel Filament" + #define MSG_FILAMENT_CHANGE_INSERT_2 "ein und drücke" + #define MSG_FILAMENT_CHANGE_INSERT_3 "den Knopf..." + #define MSG_FILAMENT_CHANGE_LOAD_1 "Warte auf das" + #define MSG_FILAMENT_CHANGE_LOAD_2 "laden des" + #define MSG_FILAMENT_CHANGE_LOAD_3 "Filaments" + #define MSG_FILAMENT_CHANGE_EXTRUDE_1 "Warte auf das" + #define MSG_FILAMENT_CHANGE_EXTRUDE_2 "Extruden des" + #define MSG_FILAMENT_CHANGE_EXTRUDE_3 "Filaments" + #define MSG_FILAMENT_CHANGE_RESUME_1 "Warte auf das" + #define MSG_FILAMENT_CHANGE_RESUME_2 "fortfahren des" + #define MSG_FILAMENT_CHANGE_RESUME_3 "Druckes" +#else // LCD_HEIGHT < 4 + #define MSG_FILAMENT_CHANGE_INIT_1 "Bitte warten..." + #define MSG_FILAMENT_CHANGE_UNLOAD_1 "Auswerfen..." + #define MSG_FILAMENT_CHANGE_INSERT_1 "Laden und Klick" + #define MSG_FILAMENT_CHANGE_LOAD_1 "Laden..." + #define MSG_FILAMENT_CHANGE_EXTRUDE_1 "Extruden..." + #define MSG_FILAMENT_CHANGE_RESUME_1 "Weitermachen..." +#endif // LCD_HEIGHT < 4 + +#endif // LANGUAGE_DE_H diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_el-gr.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_el-gr.h new file mode 100644 index 00000000..510e8aae --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_el-gr.h @@ -0,0 +1,198 @@ +/** + * 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 . + * + */ + +/** + * Greek (Greece) + * + * LCD Menu Messages + * See also https://github.com/MarlinFirmware/Marlin/wiki/LCD-Language + * + */ +#ifndef LANGUAGE_EL_GR_H +#define LANGUAGE_EL_GR_H + +// Define SIMULATE_ROMFONT to see what is seen on the character based display defined in Configuration.h +//#define SIMULATE_ROMFONT + +//#define MAPPER_CECF +//#define DISPLAY_CHARSET_ISO10646_GREEK + +#define WELCOME_MSG MACHINE_NAME " έτοιμο." +#define MSG_SD_INSERTED "Εισαγωγή κάρτας" +#define MSG_SD_REMOVED "Αφαίρεση κάρτας" +#define MSG_LCD_ENDSTOPS "Endstops" // Max length 8 characters +#define MSG_MAIN "Βασική Οθόνη" +#define MSG_AUTOSTART "Αυτόματη εκκίνηση" +#define MSG_DISABLE_STEPPERS "Απενεργοποίηση βηματιστή" +#define MSG_AUTO_HOME "Αυτομ. επαναφορά στο αρχικό σημείο" +#define MSG_AUTO_HOME_X "Αρχικό σημείο X" +#define MSG_AUTO_HOME_Y "Αρχικό σημείο Y" +#define MSG_AUTO_HOME_Z "Αρχικό σημείο Z" +#define MSG_LEVEL_BED_HOMING "Επαναφορά στο αρχικό σημείο ΧΥΖ" +#define MSG_LEVEL_BED_WAITING "Κάντε κλικ για να ξεκινήσετε" +#define MSG_LEVEL_BED_NEXT_POINT "Επόμενο σημείο" +#define MSG_LEVEL_BED_DONE "Ολοκλήρωση επιπεδοποίησης!" +#define MSG_LEVEL_BED_CANCEL "Ακύρωση" +#define MSG_SET_HOME_OFFSETS "Ορισμός βασικών μετατοπίσεων" +#define MSG_HOME_OFFSETS_APPLIED "Εφαρμόστηκαν οι μετατοπίσεις" +#define MSG_SET_ORIGIN "Ορισμός προέλευσης" +#define MSG_PREHEAT_1 "Προθέρμανση PLA" +#define MSG_PREHEAT_1_N MSG_PREHEAT_1 " " +#define MSG_PREHEAT_1_ALL MSG_PREHEAT_1 " όλα" +#define MSG_PREHEAT_1_BEDONLY MSG_PREHEAT_1 " κλίνη" +#define MSG_PREHEAT_1_SETTINGS MSG_PREHEAT_1 " επιβεβαίωση" +#define MSG_PREHEAT_2 "Προθέρμανση ABS" +#define MSG_PREHEAT_2_N MSG_PREHEAT_2 " " +#define MSG_PREHEAT_2_ALL MSG_PREHEAT_2 " όλα" +#define MSG_PREHEAT_2_BEDONLY MSG_PREHEAT_2 " Bed" +#define MSG_PREHEAT_2_SETTINGS MSG_PREHEAT_2 " επιβεβαίωση" +#define MSG_H1 "1" +#define MSG_H2 "2" +#define MSG_H3 "3" +#define MSG_H4 "4" +#define MSG_COOLDOWN "Μειωση θερμοκρασιας" +#define MSG_SWITCH_PS_ON "Ενεργοποίηση" +#define MSG_SWITCH_PS_OFF "Απενεργοποίηση" +#define MSG_EXTRUDE "Εξώθηση" +#define MSG_RETRACT "Ανάσυρση" +#define MSG_MOVE_AXIS "Μετακίνηση άξονα" +#define MSG_LEVEL_BED "Επιπεδοποίηση κλίνης" +#define MSG_MOVE_X "Μετακίνηση X" +#define MSG_MOVE_Y "Μετακίνηση Y" +#define MSG_MOVE_Z "Μετακίνηση Z" +#define MSG_MOVE_E "Εξωθητήρας" +#define MSG_MOVE_E1 "1" +#define MSG_MOVE_E2 "2" +#define MSG_MOVE_E3 "3" +#define MSG_MOVE_E4 "4" +#define MSG_MOVE_01MM "Μετακίνηση 0,1 μμ" +#define MSG_MOVE_1MM "Μετακίνηση 1 μμ" +#define MSG_MOVE_10MM "Μετακίνηση 10 μμ" +#define MSG_SPEED "Ταχύτητα" +#define MSG_BED_Z "Κλίνη Z" +#define MSG_NOZZLE "Ακροφύσιο" +#define MSG_N1 " 1" +#define MSG_N2 " 2" +#define MSG_N3 " 3" +#define MSG_N4 " 4" +#define MSG_BED "Κλίνη" +#define MSG_FAN_SPEED "Ταχύτητα ανεμιστήρα" +#define MSG_FLOW "Ροή" +#define MSG_CONTROL "Έλεγχος" +#define MSG_MIN " " LCD_STR_THERMOMETER " Min" +#define MSG_MAX " " LCD_STR_THERMOMETER " Max" +#define MSG_FACTOR " " LCD_STR_THERMOMETER " Fact" +#define MSG_AUTOTEMP "Αυτομ. ρύθμιση θερμοκρασίας" +#define MSG_ON "Ενεργοποιημένο" +#define MSG_OFF "Απενεργοποιημένο" +#define MSG_PID_P "PID-P" +#define MSG_PID_I "PID-I" +#define MSG_PID_D "PID-D" +#define MSG_PID_C "PID-C" +#define MSG_E1 " E1" +#define MSG_E2 " E2" +#define MSG_E3 " E3" +#define MSG_E4 " E4" +#define MSG_ACC "Επιτάχυνση" +#define MSG_VXY_JERK "Vαντίδραση xy" +#define MSG_VZ_JERK "Vαντίδραση z" +#define MSG_VE_JERK "Vαντίδραση e" +#define MSG_VMAX "Vμεγ " +#define MSG_X "X" +#define MSG_Y "Y" +#define MSG_Z "Z" +#define MSG_E "E" +#define MSG_VMIN "Vελαχ" +#define MSG_VTRAV_MIN "Vελάχ. μετατόπιση" +#define MSG_AMAX "Aμεγ " +#define MSG_A_RETRACT "Α-ανάσυρση" +#define MSG_A_TRAVEL "Α-μετατόπιση" +#define MSG_XSTEPS "Bήματα X ανά μμ" +#define MSG_YSTEPS "Bήματα Υ ανά μμ" +#define MSG_ZSTEPS "Bήματα Ζ ανά μμ" +#define MSG_ESTEPS "Bήματα Ε ανά μμ" +#define MSG_TEMPERATURE "Θερμοκρασία" +#define MSG_MOTION "Κίνηση" +#define MSG_VOLUMETRIC "Νήμα" +#define MSG_VOLUMETRIC_ENABLED "Ε σε μμ3" +#define MSG_FILAMENT_DIAM "Διάμετρος νήματος" +#define MSG_DIAM_E1 " 1" +#define MSG_DIAM_E2 " 2" +#define MSG_DIAM_E3 " 3" +#define MSG_DIAM_E4 " 4" +#define MSG_CONTRAST "Κοντράστ LCD" +#define MSG_STORE_EPROM "Αποθήκευση" +#define MSG_LOAD_EPROM "Φόρτωση" +#define MSG_RESTORE_FAILSAFE "Επαναφορά ασφαλούς αντιγράφου" +#define MSG_REFRESH "Ανανέωση" +#define MSG_WATCH "Οθόνη πληροφόρησης" +#define MSG_PREPARE "Προετοιμασία" +#define MSG_TUNE "Συντονισμός" +#define MSG_PAUSE_PRINT "Παύση εκτύπωσης" +#define MSG_RESUME_PRINT "Συνέχιση εκτύπωσης" +#define MSG_STOP_PRINT "Διακοπή εκτύπωσης" +#define MSG_CARD_MENU "Εκτύπωση από SD" +#define MSG_NO_CARD "Δεν βρέθηκε SD" +#define MSG_DWELL "Αναστολή λειτουργίας..." +#define MSG_USERWAIT "Αναμονή για χρήστη…" +#define MSG_RESUMING "Συνεχίζεται η εκτύπωση" +#define MSG_PRINT_ABORTED "Διακόπτεται η εκτύπωση" +#define MSG_NO_MOVE "Καμία κίνηση." +#define MSG_KILLED "ΤΕΡΜΑΤΙΣΜΟΣ. " +#define MSG_STOPPED "ΔΙΑΚΟΠΗ. " +#define MSG_CONTROL_RETRACT "Ανάσυρση μμ" +#define MSG_CONTROL_RETRACT_SWAP "Εναλλαγή ανάσυρσης μμ" +#define MSG_CONTROL_RETRACTF "Ανάσυρση V" +#define MSG_CONTROL_RETRACT_ZLIFT "Μεταπήδηση μμ" +#define MSG_CONTROL_RETRACT_RECOVER "UnRet +mm" +#define MSG_CONTROL_RETRACT_RECOVER_SWAP "S UnRet+mm" +#define MSG_CONTROL_RETRACT_RECOVERF "UnRet V" +#define MSG_AUTORETRACT "Αυτόματη ανάσυρση" +#define MSG_FILAMENTCHANGE "Αλλαγή νήματος" +#define MSG_INIT_SDCARD "Προετοιμασία κάρτας SD" +#define MSG_CNG_SDCARD "Αλλαγή κάρτας SD" +#define MSG_ZPROBE_OUT "Διερεύνηση Z εκτός κλίνης" +#define MSG_YX_UNHOMED "Επαναφορά Χ/Υ πριν από Ζ" +#define MSG_XYZ_UNHOMED "Επαναφορά ΧΥΖ πρώτα" +#define MSG_ZPROBE_ZOFFSET "Μετατόπιση Ζ" +#define MSG_BABYSTEP_X "Μικρό βήμα Χ" +#define MSG_BABYSTEP_Y "Μικρό βήμα Υ" +#define MSG_BABYSTEP_Z "Μικρό βήμα Ζ" +#define MSG_ENDSTOP_ABORT "Ματαίωση endstop " +#define MSG_HEATING_FAILED_LCD "Ανεπιτυχής θέρμανση" +#define MSG_ERR_REDUNDANT_TEMP "Λάθος: ΠΛΕΟΝΑΖΟΥΣΑ ΘΕΡΜΟΤΗΤΑ" +#define MSG_THERMAL_RUNAWAY "ΔΙΑΦΥΓΗ ΘΕΡΜΟΤΗΤΑΣ" +#define MSG_ERR_MAXTEMP "Λάθος: ΜΕΓΙΣΤΗ ΘΕΡΜΟΤΗΤΑ" +#define MSG_ERR_MINTEMP "Λάθος: ΕΛΑΧΙΣΤΗ ΘΕΡΜΟΤΗΤΑ" +#define MSG_ERR_MAXTEMP_BED "Λάθος: ΜΕΓΙΣΤΗ ΘΕΡΜΟΤΗΤΑ ΚΛΙΝΗΣ" +#define MSG_ERR_MINTEMP_BED "Λάθος: ΕΛΑΧΙΣΤΗ ΘΕΡΜΟΤΗΤΑ ΚΛΙΝΗΣ" +#define MSG_HEATING "Θερμαίνεται…" +#define MSG_HEATING_COMPLETE "Η θέρμανση ολοκληρώθηκε." +#define MSG_BED_HEATING "Θέρμανση κλίνης." +#define MSG_BED_DONE "Η κλίνη ολοκληρώθηκε." +#define MSG_DELTA_CALIBRATE "Βαθμονόμηση Delta" +#define MSG_DELTA_CALIBRATE_X "Βαθμονόμηση X" +#define MSG_DELTA_CALIBRATE_Y "Βαθμονόμηση Y" +#define MSG_DELTA_CALIBRATE_Z "Βαθμονόμηση Z" +#define MSG_DELTA_CALIBRATE_CENTER "Βαθμονόμηση κέντρου" + +#endif // LANGUAGE_EL_GR_H diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_el.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_el.h new file mode 100644 index 00000000..9d1c8555 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_el.h @@ -0,0 +1,254 @@ +/** + * 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 . + * + */ + +/** + * Greek + * + * LCD Menu Messages + * See also https://github.com/MarlinFirmware/Marlin/wiki/LCD-Language + * + */ +#ifndef LANGUAGE_EL_H +#define LANGUAGE_EL_H + +// Define SIMULATE_ROMFONT to see what is seen on the character based display defined in Configuration.h +//#define SIMULATE_ROMFONT + +#define MAPPER_CECF +#define DISPLAY_CHARSET_ISO10646_GREEK + +#define WELCOME_MSG MACHINE_NAME " έτοιμο." +#define MSG_SD_INSERTED "Εισαγωγή κάρτας" +#define MSG_SD_REMOVED "Αφαίρεση κάρτας" +#define MSG_LCD_ENDSTOPS "Endstops" // Max length 8 characters +#define MSG_MAIN "Βασική Οθόνη" +#define MSG_AUTOSTART "Αυτόματη εκκίνηση" +#define MSG_DISABLE_STEPPERS "Απενεργοποίηση Μοτέρ" +#define MSG_AUTO_HOME "Αυτομ. επαναφορά στο αρχικό σημείο" //SHORTEN +#define MSG_AUTO_HOME_X "Αρχικό σημείο X" +#define MSG_AUTO_HOME_Y "Αρχικό σημείο Y" +#define MSG_AUTO_HOME_Z "Αρχικό σημείο Z" +#define MSG_LEVEL_BED_HOMING "Επαναφορά Επ. Εκτύπωσης" //SHORTEN +#define MSG_LEVEL_BED_WAITING "Επιπεδοποίηση επ. Εκτύπωσης περιμενει" //SHORTEN +#define MSG_LEVEL_BED_NEXT_POINT "Επόμενο σημείο" +#define MSG_LEVEL_BED_DONE "Ολοκλήρωση επιπεδοποίησης!" //SHORTEN +#define MSG_LEVEL_BED_CANCEL "Ακύρωση" +#define MSG_SET_HOME_OFFSETS "Ορισμός βασικών μετατοπίσεων" //SHORTEN +#define MSG_HOME_OFFSETS_APPLIED "Εφαρμόστηκαν οι μετατοπίσεις" //SHORTEN +#define MSG_SET_ORIGIN "Ορισμός προέλευσης" +#define MSG_PREHEAT_1 "Προθέρμανση PLA" +#define MSG_PREHEAT_1_N MSG_PREHEAT_1 " " +#define MSG_PREHEAT_1_ALL MSG_PREHEAT_1 " όλα" +#define MSG_PREHEAT_1_BEDONLY MSG_PREHEAT_1 " bed" //SHORTEN +#define MSG_PREHEAT_1_SETTINGS MSG_PREHEAT_1 " επιβεβαίωση" //SHORTEN +#define MSG_PREHEAT_2 "Προθέρμανση ABS" +#define MSG_PREHEAT_2_N MSG_PREHEAT_2 " " +#define MSG_PREHEAT_2_ALL MSG_PREHEAT_2 " όλα" +#define MSG_PREHEAT_2_BEDONLY MSG_PREHEAT_2 " bed" //SHORTEN +#define MSG_PREHEAT_2_SETTINGS MSG_PREHEAT_2 " επιβεβαίωση" //SHORTEN +#define MSG_H1 "1" +#define MSG_H2 "2" +#define MSG_H3 "3" +#define MSG_H4 "4" +#define MSG_COOLDOWN "Μειωση θερμοκρασιας" +#define MSG_SWITCH_PS_ON "Ενεργοποίηση" +#define MSG_SWITCH_PS_OFF "Απενεργοποίηση" +#define MSG_EXTRUDE "Εξώθηση" +#define MSG_RETRACT "Ανάσυρση" +#define MSG_MOVE_AXIS "Μετακίνηση άξονα" +#define MSG_LEVEL_BED "Επιπεδοποίηση Επ. Εκτύπωσης" //SHORTEN +#define MSG_MOVE_X "Μετακίνηση X" +#define MSG_MOVE_Y "Μετακίνηση Y" +#define MSG_MOVE_Z "Μετακίνηση Z" +#define MSG_MOVE_E "Εξωθητήρας" +#define MSG_MOVE_E1 "1" +#define MSG_MOVE_E2 "2" +#define MSG_MOVE_E3 "3" +#define MSG_MOVE_E4 "4" +#define MSG_MOVE_01MM "Μετακίνηση 0,1μμ" +#define MSG_MOVE_1MM "Μετακίνηση 1μμ" +#define MSG_MOVE_10MM "Μετακίνηση 10μμ" +#define MSG_SPEED "Ταχύτητα" +#define MSG_BED_Z "Επ. Εκτύπωσης Z" +#define MSG_NOZZLE "Ακροφύσιο" +#define MSG_N1 " 1" +#define MSG_N2 " 2" +#define MSG_N3 " 3" +#define MSG_N4 " 4" +#define MSG_BED "Κλίνη" +#define MSG_FAN_SPEED "Ταχύτητα ανεμιστήρα" +#define MSG_FLOW "Ροή" +#define MSG_CONTROL "Έλεγχος" +#define MSG_MIN " " LCD_STR_THERMOMETER " Min" +#define MSG_MAX " " LCD_STR_THERMOMETER " Max" +#define MSG_FACTOR " " LCD_STR_THERMOMETER " Fact" +#define MSG_AUTOTEMP "Αυτομ ρύθμιση θερ/σίας" //SHORTEN +#define MSG_ON "Ενεργοποιημένο" +#define MSG_OFF "Απενεργοποιημένο" +#define MSG_PID_P "PID-P" +#define MSG_PID_I "PID-I" +#define MSG_PID_D "PID-D" +#define MSG_PID_C "PID-C" +#define MSG_E1 " E1" +#define MSG_E2 " E2" +#define MSG_E3 " E3" +#define MSG_E4 " E4" +#define MSG_ACC "Επιτάχυνση" +#define MSG_VXY_JERK "Vαντίδραση xy" +#define MSG_VZ_JERK "Vαντίδραση z" +#define MSG_VE_JERK "Vαντίδραση e" +#define MSG_VMAX "V Μέγιστο" +#define MSG_X "X" +#define MSG_Y "Y" +#define MSG_Z "Z" +#define MSG_E "E" +#define MSG_VMIN "V Ελάχιστο" +#define MSG_VTRAV_MIN "Vελάχ. μετατόπιση" +#define MSG_AMAX "Aμεγ " +#define MSG_A_RETRACT "Α-ανάσυρση" +#define MSG_A_TRAVEL "Α-μετατόπιση" +#define MSG_XSTEPS "Bήματα X ανά μμ" +#define MSG_YSTEPS "Bήματα Υ ανά μμ" +#define MSG_ZSTEPS "Bήματα Ζ ανά μμ" +#define MSG_ESTEPS "Bήματα Ε ανά μμ" +#define MSG_TEMPERATURE "Θερμοκρασία" +#define MSG_MOTION "Κίνηση" +#define MSG_VOLUMETRIC "Νήμα" +#define MSG_VOLUMETRIC_ENABLED "Ε σε μμ3" +#define MSG_FILAMENT_DIAM "Διάμετρος νήματος" +#define MSG_DIAM_E1 " 1" +#define MSG_DIAM_E2 " 2" +#define MSG_DIAM_E3 " 3" +#define MSG_DIAM_E4 " 4" +#define MSG_CONTRAST "Κοντράστ LCD" +#define MSG_STORE_EPROM "Αποθήκευση" +#define MSG_LOAD_EPROM "Φόρτωση" +#define MSG_RESTORE_FAILSAFE "Επαναφορά ασφαλούς αντιγράφου" //SHORTEN +#define MSG_REFRESH "Ανανέωση" +#define MSG_WATCH "Οθόνη πληροφόρησης" +#define MSG_PREPARE "Προετοιμασία" +#define MSG_TUNE "Συντονισμός" +#define MSG_PAUSE_PRINT "Παύση εκτύπωσης" +#define MSG_RESUME_PRINT "Συνέχιση εκτύπωσης" +#define MSG_STOP_PRINT "Διακοπή εκτύπωσης" +#define MSG_CARD_MENU "Εκτύπωση από SD" +#define MSG_NO_CARD "Δεν βρέθηκε SD" +#define MSG_DWELL "Αναστολή λειτουργίας" +#define MSG_USERWAIT "Αναμονή για χρήστη" +#define MSG_RESUMING "Συνεχίζεται η εκτύπωση" //SHORTEN +#define MSG_PRINT_ABORTED "Διακόπτεται η εκτύπωση" //SHORTEN +#define MSG_NO_MOVE "Καμία κίνηση." +#define MSG_KILLED "ΤΕΡΜΑΤΙΣΜΟΣ. " +#define MSG_STOPPED "ΔΙΑΚΟΠΗ. " +#define MSG_CONTROL_RETRACT "Ανάσυρση μμ" +#define MSG_CONTROL_RETRACT_SWAP "Εναλλαγή ανάσυρσης μμ" //SHORTEN +#define MSG_CONTROL_RETRACTF "Ανάσυρση V" +#define MSG_CONTROL_RETRACT_ZLIFT "Μεταπήδηση μμ" +#define MSG_CONTROL_RETRACT_RECOVER "UnRet +mm" +#define MSG_CONTROL_RETRACT_RECOVER_SWAP "S UnRet+mm" +#define MSG_CONTROL_RETRACT_RECOVERF "UnRet V" +#define MSG_AUTORETRACT "Αυτόματη ανάσυρση" +#define MSG_FILAMENTCHANGE "Αλλαγή νήματος" +#define MSG_INIT_SDCARD "Προετοιμασία κάρτας SD" //SHORTEN +#define MSG_CNG_SDCARD "Αλλαγή κάρτας SD" +#define MSG_ZPROBE_OUT "Διερεύνηση Z εκτός Επ.Εκτύπωσης" //SHORTEN +#define MSG_YX_UNHOMED "Επαναφορά Χ/Υ πριν από Ζ" //SHORTEN +#define MSG_XYZ_UNHOMED "Επαναφορά ΧΥΖ πρώτα" +#define MSG_ZPROBE_ZOFFSET "Μετατόπιση Ζ" +#define MSG_BABYSTEP_X "Μικρό βήμα Χ" +#define MSG_BABYSTEP_Y "Μικρό βήμα Υ" +#define MSG_BABYSTEP_Z "Μικρό βήμα Ζ" +#define MSG_ENDSTOP_ABORT "Ακύρωση endstop " +#define MSG_HEATING_FAILED_LCD "Ανεπιτυχής θέρμανση" +#define MSG_ERR_REDUNDANT_TEMP "ΠΛΕΟΝΑΖΟΥΣΑ ΘΕΡΜΟΤΗΤΑ" +#define MSG_THERMAL_RUNAWAY "ΔΙΑΦΥΓΗ ΘΕΡΜΟΚΡΑΣΙΑΣ" +#define MSG_ERR_MAXTEMP "ΠΕΡΙΤΗ ΘΕΡΜΟΚΡΑΣΙΑ" +#define MSG_ERR_MINTEMP "ΜΗ ΕΠΑΡΚΗΣ ΘΕΡΜΟΚΡΑΣΙΑΣ" //SHORTEN +#define MSG_ERR_MAXTEMP_BED "ΜΕΓΙΣΤΗ ΘΕΡΜΟΚΡΑΣΙΑΣ ΕΠ. ΕΚΤΥΠΩΣΗΣ" //SHORTEN +#define MSG_ERR_MINTEMP_BED "ΕΛΑΧΙΣΤΗ ΘΕΡΜΟΚΡΑΣΙΑΣ ΕΠ. ΕΚΤΥΠΩΣΗΣ" //SHORTEN +#define MSG_HALTED "H εκτύπωση διακόπηκε" +#define MSG_PLEASE_RESET "PLEASE RESET" //TRANSLATE +#define MSG_HEATING "Θερμαίνεται…" +#define MSG_HEATING_COMPLETE "Η θέρμανση ολοκληρώθηκε." //SHORTEN +#define MSG_BED_HEATING "Θέρμανση ΕΠ. Εκτύπωσης" //SHORTEN +#define MSG_BED_DONE "Η Επ. Εκτύπωσης ολοκληρώθηκε" //SHORTEN +#define MSG_DELTA_CALIBRATE "Βαθμονόμηση Delta" +#define MSG_DELTA_CALIBRATE_X "Βαθμονόμηση X" +#define MSG_DELTA_CALIBRATE_Y "Βαθμονόμηση Y" +#define MSG_DELTA_CALIBRATE_Z "Βαθμονόμηση Z" +#define MSG_DELTA_CALIBRATE_CENTER "Βαθμονόμηση κέντρου" + +#define MSG_INFO_MENU "About Printer" +#define MSG_INFO_PRINTER_MENU "Printer Info" +#define MSG_INFO_STATS_MENU "Printer Stats" +#define MSG_INFO_BOARD_MENU "Board Info" +#define MSG_INFO_THERMISTOR_MENU "Thermistors" +#define MSG_INFO_EXTRUDERS "Extruders" +#define MSG_INFO_BAUDRATE "Baud" +#define MSG_INFO_PROTOCOL "Protocol" + +#if LCD_WIDTH > 19 + #define MSG_INFO_PRINT_COUNT "Print Count" + #define MSG_INFO_COMPLETED_PRINTS "Completed " + #define MSG_INFO_PRINT_TIME "Total Time " +#else + #define MSG_INFO_PRINT_COUNT "Prints " + #define MSG_INFO_COMPLETED_PRINTS "Completed" + #define MSG_INFO_PRINT_TIME "Duration " +#endif +#define MSG_INFO_MIN_TEMP "Min Temp" +#define MSG_INFO_MAX_TEMP "Max Temp" +#define MSG_INFO_PSU "Power Supply" + +#define MSG_FILAMENT_CHANGE_HEADER "CHANGE FILAMENT" +#define MSG_FILAMENT_CHANGE_OPTION_EXTRUDE "Extrude more" +#define MSG_FILAMENT_CHANGE_OPTION_RESUME "Resume print" + +#if LCD_HEIGHT >= 4 + #define MSG_FILAMENT_CHANGE_INIT_1 "Wait for start" + #define MSG_FILAMENT_CHANGE_INIT_2 "of the filament" + #define MSG_FILAMENT_CHANGE_INIT_3 "change" + #define MSG_FILAMENT_CHANGE_UNLOAD_1 "Wait for" + #define MSG_FILAMENT_CHANGE_UNLOAD_2 "filament unload" + #define MSG_FILAMENT_CHANGE_UNLOAD_3 "" + #define MSG_FILAMENT_CHANGE_INSERT_1 "Insert filament" + #define MSG_FILAMENT_CHANGE_INSERT_2 "and press button" + #define MSG_FILAMENT_CHANGE_INSERT_3 "to continue..." + #define MSG_FILAMENT_CHANGE_LOAD_1 "Wait for" + #define MSG_FILAMENT_CHANGE_LOAD_2 "filament load" + #define MSG_FILAMENT_CHANGE_LOAD_3 "" + #define MSG_FILAMENT_CHANGE_EXTRUDE_1 "Wait for" + #define MSG_FILAMENT_CHANGE_EXTRUDE_2 "filament extrude" + #define MSG_FILAMENT_CHANGE_EXTRUDE_3 "" + #define MSG_FILAMENT_CHANGE_RESUME_1 "Wait for print" + #define MSG_FILAMENT_CHANGE_RESUME_2 "to resume" + #define MSG_FILAMENT_CHANGE_RESUME_3 "" +#else // LCD_HEIGHT < 4 + #define MSG_FILAMENT_CHANGE_INIT_1 "Please wait..." + #define MSG_FILAMENT_CHANGE_UNLOAD_1 "Ejecting..." + #define MSG_FILAMENT_CHANGE_INSERT_1 "Insert and Click" + #define MSG_FILAMENT_CHANGE_LOAD_1 "Loading..." + #define MSG_FILAMENT_CHANGE_EXTRUDE_1 "Extruding..." + #define MSG_FILAMENT_CHANGE_RESUME_1 "Resuming..." +#endif + +#endif // LANGUAGE_EL_H diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_en.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_en.h new file mode 100644 index 00000000..d640b159 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_en.h @@ -0,0 +1,738 @@ +/** + * 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 . + * + */ + +/** + * English + * + * LCD Menu Messages + * See also https://github.com/MarlinFirmware/Marlin/wiki/LCD-Language + * + */ +#ifndef LANGUAGE_EN_H +#define LANGUAGE_EN_H + +//#define SIMULATE_ROMFONT //Comment in to see what is seen on the character based displays +#if DISABLED(SIMULATE_ROMFONT) && DISABLED(DISPLAY_CHARSET_ISO10646_1) && DISABLED(DISPLAY_CHARSET_ISO10646_5) && DISABLED(DISPLAY_CHARSET_ISO10646_KANA) && DISABLED(DISPLAY_CHARSET_ISO10646_GREEK) && DISABLED(DISPLAY_CHARSET_ISO10646_CN) + #define DISPLAY_CHARSET_ISO10646_1 // use the better font on full graphic displays. +#endif + +// Splashscreen + +#ifndef MSG_SPLASH_NAME + #define MSG_SPLASH_NAME " VERTEX NANO" +#endif + +#ifndef MSG_SPLASH_FIRMWARE + #define MSG_SPLASH_FIRMWARE " V1.0-PaoloIocco" +#endif + +#ifndef MSG_SPLASH_WEBSITE1 + #define MSG_SPLASH_WEBSITE1 "vertex3dprinter.eu" +#endif + +#ifndef MSG_SPLASH_WEBSITE2 + #define MSG_SPLASH_WEBSITE2 " velleman.eu" +#endif + +#ifndef MSG_BOOT_LINE2 + #define MSG_BOOT_LINE2 "VERTEX NANO" +#endif + +// Splashscreen + +// Added Vertex Nano menu items + +#ifndef MSG_FIRMWARE + #define MSG_FIRMWARE "Firmware version" +#endif +#ifndef MSG_LED_MENU + #define MSG_LED_MENU "LED brightness" +#endif + + +#define MSG_LOAD_FILAMENT "(Un)load filament" +#define MSG_LOAD_ABS "Load ABS" +#define MSG_UNLOAD_ABS "Unload ABS" +#define MSG_LOAD_PLA "Load PLA" +#define MSG_UNLOAD_PLA "Unload PLA" +#define MSG_LOAD_TEXT0 " Insert filament" +#define MSG_LOAD_TEXT1 " until 1.5cm is" +#define MSG_LOAD_TEXT2 " visible in tube" +#define MSG_LOAD_TEXT3 "Then press button" + + +// Added Vertex Nano menu items + +#ifndef WELCOME_MSG + #define WELCOME_MSG MACHINE_NAME " ready." +#endif +#ifndef MSG_SD_INSERTED + #define MSG_SD_INSERTED "Card inserted" +#endif +#ifndef MSG_SD_REMOVED + #define MSG_SD_REMOVED "Card removed" +#endif +#ifndef MSG_LCD_ENDSTOPS + #define MSG_LCD_ENDSTOPS "Endstops" // Max length 8 characters +#endif +#ifndef MSG_MAIN + #define MSG_MAIN "Main" +#endif +#ifndef MSG_AUTOSTART + #define MSG_AUTOSTART "Autostart" +#endif +#ifndef MSG_DISABLE_STEPPERS + #define MSG_DISABLE_STEPPERS "Disable steppers" +#endif +#ifndef MSG_AUTO_HOME + #define MSG_AUTO_HOME "Auto home" +#endif +#ifndef MSG_AUTO_HOME_X + #define MSG_AUTO_HOME_X "Home X" +#endif +#ifndef MSG_AUTO_HOME_Y + #define MSG_AUTO_HOME_Y "Home Y" +#endif +#ifndef MSG_AUTO_HOME_Z + #define MSG_AUTO_HOME_Z "Home Z" +#endif +#ifndef MSG_LEVEL_BED_HOMING + #define MSG_LEVEL_BED_HOMING "Homing XYZ" +#endif +#ifndef MSG_LEVEL_BED_WAITING + #define MSG_LEVEL_BED_WAITING "Click to Begin" +#endif +#ifndef MSG_LEVEL_BED_NEXT_POINT + #define MSG_LEVEL_BED_NEXT_POINT "Next Point" +#endif +#ifndef MSG_LEVEL_BED_DONE + #define MSG_LEVEL_BED_DONE "Leveling Done!" +#endif +#ifndef MSG_LEVEL_BED_CANCEL + #define MSG_LEVEL_BED_CANCEL "Cancel" +#endif +#ifndef MSG_SET_HOME_OFFSETS + #define MSG_SET_HOME_OFFSETS "Set home offsets" +#endif +#ifndef MSG_HOME_OFFSETS_APPLIED + #define MSG_HOME_OFFSETS_APPLIED "Offsets applied" +#endif +#ifndef MSG_SET_ORIGIN + #define MSG_SET_ORIGIN "Set origin" +#endif +#ifndef MSG_PREHEAT_1 + #define MSG_PREHEAT "Preheat" +#endif +#ifndef MSG_PREHEAT_1 + #define MSG_PREHEAT_1 "Preheat PLA" +#endif +#ifndef MSG_PREHEAT_1_N + #define MSG_PREHEAT_1_N MSG_PREHEAT_1 " " +#endif +#ifndef MSG_PREHEAT_1_ALL + #define MSG_PREHEAT_1_ALL MSG_PREHEAT_1 " All" +#endif +#ifndef MSG_PREHEAT_1_BEDONLY + #define MSG_PREHEAT_1_BEDONLY MSG_PREHEAT_1 " Bed" +#endif +#ifndef MSG_PREHEAT_1_SETTINGS + #define MSG_PREHEAT_1_SETTINGS MSG_PREHEAT_1 " conf" +#endif +#ifndef MSG_PREHEAT_2 + #define MSG_PREHEAT_2 "Preheat ABS" +#endif +#ifndef MSG_PREHEAT_2_N + #define MSG_PREHEAT_2_N MSG_PREHEAT_2 " " +#endif +#ifndef MSG_PREHEAT_2_ALL + #define MSG_PREHEAT_2_ALL MSG_PREHEAT_2 " All" +#endif +#ifndef MSG_PREHEAT_2_BEDONLY + #define MSG_PREHEAT_2_BEDONLY MSG_PREHEAT_2 " Bed" +#endif +#ifndef MSG_PREHEAT_2_SETTINGS + #define MSG_PREHEAT_2_SETTINGS MSG_PREHEAT_2 " conf" +#endif +#ifndef MSG_H1 + #define MSG_H1 "1" +#endif +#ifndef MSG_H2 + #define MSG_H2 "2" +#endif +#ifndef MSG_H3 + #define MSG_H3 "3" +#endif +#ifndef MSG_H4 + #define MSG_H4 "4" +#endif +#ifndef MSG_COOLDOWN + #define MSG_COOLDOWN "Cooldown" +#endif +#ifndef MSG_SWITCH_PS_ON + #define MSG_SWITCH_PS_ON "Switch power on" +#endif +#ifndef MSG_SWITCH_PS_OFF + #define MSG_SWITCH_PS_OFF "Switch power off" +#endif +#ifndef MSG_EXTRUDE + #define MSG_EXTRUDE "Extrude" +#endif +#ifndef MSG_RETRACT + #define MSG_RETRACT "Retract" +#endif +#ifndef MSG_MOVE_AXIS + #define MSG_MOVE_AXIS "Move axis" +#endif +#ifndef MSG_LEVEL_BED + #define MSG_LEVEL_BED "Level bed" +#endif +#ifndef MSG_MOVE_X + #define MSG_MOVE_X "Move X" +#endif +#ifndef MSG_MOVE_Y + #define MSG_MOVE_Y "Move Y" +#endif +#ifndef MSG_MOVE_Z + #define MSG_MOVE_Z "Move Z" +#endif +#ifndef MSG_MOVE_E + #define MSG_MOVE_E "Extruder" +#endif +#ifndef MSG_MOVE_E1 + #define MSG_MOVE_E1 "1" +#endif +#ifndef MSG_MOVE_E2 + #define MSG_MOVE_E2 "2" +#endif +#ifndef MSG_MOVE_E3 + #define MSG_MOVE_E3 "3" +#endif +#ifndef MSG_MOVE_E4 + #define MSG_MOVE_E4 "4" +#endif +#ifndef MSG_MOVE_01MM + #define MSG_MOVE_01MM "Move 0.1mm" +#endif +#ifndef MSG_MOVE_1MM + #define MSG_MOVE_1MM "Move 1mm" +#endif +#ifndef MSG_MOVE_10MM + #define MSG_MOVE_10MM "Move 10mm" +#endif +#ifndef MSG_SPEED + #define MSG_SPEED "Speed" +#endif +#ifndef MSG_BED_Z + #define MSG_BED_Z "Bed Z" +#endif +#ifndef MSG_NOZZLE + #define MSG_NOZZLE "Nozzle" +#endif +#ifndef MSG_N1 + #define MSG_N1 " 1" +#endif +#ifndef MSG_N2 + #define MSG_N2 " 2" +#endif +#ifndef MSG_N3 + #define MSG_N3 " 3" +#endif +#ifndef MSG_N4 + #define MSG_N4 " 4" +#endif +#ifndef MSG_BED + #define MSG_BED "Bed" +#endif +#ifndef MSG_FAN_SPEED + #define MSG_FAN_SPEED "Fan speed" +#endif +#ifndef MSG_FLOW + #define MSG_FLOW "Flow" +#endif +#ifndef MSG_CONTROL + #define MSG_CONTROL "Settings" +#endif +#ifndef MSG_MIN + #define MSG_MIN " " LCD_STR_THERMOMETER " Min" +#endif +#ifndef MSG_MAX + #define MSG_MAX " " LCD_STR_THERMOMETER " Max" +#endif +#ifndef MSG_FACTOR + #define MSG_FACTOR " " LCD_STR_THERMOMETER " Fact" +#endif +#ifndef MSG_AUTOTEMP + #define MSG_AUTOTEMP "Autotemp" +#endif +#ifndef MSG_ON + #define MSG_ON "On " +#endif +#ifndef MSG_OFF + #define MSG_OFF "Off" +#endif +#ifndef MSG_PID_P + #define MSG_PID_P "PID-P" +#endif +#ifndef MSG_PID_I + #define MSG_PID_I "PID-I" +#endif +#ifndef MSG_PID_D + #define MSG_PID_D "PID-D" +#endif +#ifndef MSG_PID_C + #define MSG_PID_C "PID-C" +#endif +#ifndef MSG_SELECT + #define MSG_SELECT "Select" +#endif +#ifndef MSG_E1 + #define MSG_E1 " E1" +#endif +#ifndef MSG_E2 + #define MSG_E2 " E2" +#endif +#ifndef MSG_E3 + #define MSG_E3 " E3" +#endif +#ifndef MSG_E4 + #define MSG_E4 " E4" +#endif +#ifndef MSG_ACC + #define MSG_ACC "Accel" +#endif +#ifndef MSG_VXY_JERK + #define MSG_VXY_JERK "Vxy-jerk" +#endif +#ifndef MSG_VZ_JERK + #define MSG_VZ_JERK "Vz-jerk" +#endif +#ifndef MSG_VE_JERK + #define MSG_VE_JERK "Ve-jerk" +#endif +#ifndef MSG_VMAX + #define MSG_VMAX "Vmax " +#endif +#ifndef MSG_X + #define MSG_X "X" +#endif +#ifndef MSG_Y + #define MSG_Y "Y" +#endif +#ifndef MSG_Z + #define MSG_Z "Z" +#endif +#ifndef MSG_E + #define MSG_E "E" +#endif +#ifndef MSG_VMIN + #define MSG_VMIN "Vmin" +#endif +#ifndef MSG_VTRAV_MIN + #define MSG_VTRAV_MIN "VTrav min" +#endif +#ifndef MSG_AMAX + #define MSG_AMAX "Amax " +#endif +#ifndef MSG_A_RETRACT + #define MSG_A_RETRACT "A-retract" +#endif +#ifndef MSG_A_TRAVEL + #define MSG_A_TRAVEL "A-travel" +#endif +#ifndef MSG_XSTEPS + #define MSG_XSTEPS "Xsteps/mm" +#endif +#ifndef MSG_YSTEPS + #define MSG_YSTEPS "Ysteps/mm" +#endif +#ifndef MSG_ZSTEPS + #define MSG_ZSTEPS "Zsteps/mm" +#endif +#ifndef MSG_ESTEPS + #define MSG_ESTEPS "Esteps/mm" +#endif +#ifndef MSG_TEMPERATURE + #define MSG_TEMPERATURE "Temperature" +#endif +#ifndef MSG_MOTION + #define MSG_MOTION "Motion" +#endif +#ifndef MSG_VOLUMETRIC + #define MSG_VOLUMETRIC "Filament" +#endif +#ifndef MSG_VOLUMETRIC_ENABLED + #define MSG_VOLUMETRIC_ENABLED "E in mm3" +#endif +#ifndef MSG_FILAMENT_DIAM + #define MSG_FILAMENT_DIAM "Fil. Dia." +#endif +#ifndef MSG_DIAM_E1 + #define MSG_DIAM_E1 " 1" +#endif +#ifndef MSG_DIAM_E2 + #define MSG_DIAM_E2 " 2" +#endif +#ifndef MSG_DIAM_E3 + #define MSG_DIAM_E3 " 3" +#endif +#ifndef MSG_DIAM_E4 + #define MSG_DIAM_E4 " 4" +#endif +#ifndef MSG_CONTRAST + #define MSG_CONTRAST "LCD contrast" +#endif +#ifndef MSG_STORE_EPROM + #define MSG_STORE_EPROM "Store memory" +#endif +#ifndef MSG_LOAD_EPROM + #define MSG_LOAD_EPROM "Load memory" +#endif +#ifndef MSG_RESTORE_FAILSAFE + #define MSG_RESTORE_FAILSAFE "Restore failsafe" +#endif +#ifndef MSG_REFRESH + #define MSG_REFRESH "Refresh" +#endif +#ifndef MSG_WATCH + #define MSG_WATCH "Info screen" +#endif +#ifndef MSG_PREPARE + #define MSG_PREPARE "Control printer" +#endif +#ifndef MSG_TUNE + #define MSG_TUNE "Tune print job" +#endif +#ifndef MSG_PAUSE_PRINT + #define MSG_PAUSE_PRINT "Pause print" +#endif +#ifndef MSG_RESUME_PRINT + #define MSG_RESUME_PRINT "Resume print" +#endif +#ifndef MSG_STOP_PRINT + #define MSG_STOP_PRINT "Stop print" +#endif +#ifndef MSG_CARD_MENU + #define MSG_CARD_MENU "Print from SD" +#endif +#ifndef MSG_NO_CARD + #define MSG_NO_CARD "No SD card" +#endif +#ifndef MSG_DWELL + #define MSG_DWELL "Sleep..." +#endif +#ifndef MSG_USERWAIT + #define MSG_USERWAIT "Wait for user..." +#endif +#ifndef MSG_RESUMING + #define MSG_RESUMING "Resuming print" +#endif +#ifndef MSG_PRINT_ABORTED + #define MSG_PRINT_ABORTED "Print aborted" +#endif +#ifndef MSG_NO_MOVE + #define MSG_NO_MOVE "No move." +#endif +#ifndef MSG_KILLED + #define MSG_KILLED "KILLED. " +#endif +#ifndef MSG_STOPPED + #define MSG_STOPPED "STOPPED. " +#endif +#ifndef MSG_CONTROL_RETRACT + #define MSG_CONTROL_RETRACT "Retract mm" +#endif +#ifndef MSG_CONTROL_RETRACT_SWAP + #define MSG_CONTROL_RETRACT_SWAP "Swap Re.mm" +#endif +#ifndef MSG_CONTROL_RETRACTF + #define MSG_CONTROL_RETRACTF "Retract V" +#endif +#ifndef MSG_CONTROL_RETRACT_ZLIFT + #define MSG_CONTROL_RETRACT_ZLIFT "Hop mm" +#endif +#ifndef MSG_CONTROL_RETRACT_RECOVER + #define MSG_CONTROL_RETRACT_RECOVER "UnRet +mm" +#endif +#ifndef MSG_CONTROL_RETRACT_RECOVER_SWAP + #define MSG_CONTROL_RETRACT_RECOVER_SWAP "S UnRet+mm" +#endif +#ifndef MSG_CONTROL_RETRACT_RECOVERF + #define MSG_CONTROL_RETRACT_RECOVERF "UnRet V" +#endif +#ifndef MSG_AUTORETRACT + #define MSG_AUTORETRACT "AutoRetr." +#endif +#ifndef MSG_FILAMENTCHANGE + #define MSG_FILAMENTCHANGE "Change filament" +#endif +#ifndef MSG_INIT_SDCARD + #define MSG_INIT_SDCARD "Init. SD card" +#endif +#ifndef MSG_CNG_SDCARD + #define MSG_CNG_SDCARD "Change SD card" +#endif +#ifndef MSG_ZPROBE_OUT + #define MSG_ZPROBE_OUT "Z probe out. bed" +#endif +#ifndef MSG_HOME + #define MSG_HOME "Home" // Used as MSG_HOME " " MSG_X MSG_Y MSG_Z " " MSG_FIRST +#endif +#ifndef MSG_FIRST + #define MSG_FIRST "first" +#endif +#ifndef MSG_ZPROBE_ZOFFSET + #define MSG_ZPROBE_ZOFFSET "Z Offset" +#endif +#ifndef MSG_BABYSTEP_X + #define MSG_BABYSTEP_X "Babystep X" +#endif +#ifndef MSG_BABYSTEP_Y + #define MSG_BABYSTEP_Y "Babystep Y" +#endif +#ifndef MSG_BABYSTEP_Z + #define MSG_BABYSTEP_Z "Babystep Z" +#endif +#ifndef MSG_ENDSTOP_ABORT + #define MSG_ENDSTOP_ABORT "Endstop abort" +#endif +#ifndef MSG_HEATING_FAILED_LCD + #define MSG_HEATING_FAILED_LCD "Heating failed" +#endif +#ifndef MSG_ERR_REDUNDANT_TEMP + #define MSG_ERR_REDUNDANT_TEMP "Err: REDUNDANT TEMP" +#endif +#ifndef MSG_THERMAL_RUNAWAY + #define MSG_THERMAL_RUNAWAY "THERMAL RUNAWAY" +#endif +#ifndef MSG_ERR_MAXTEMP + #define MSG_ERR_MAXTEMP "Err: MAXTEMP" +#endif +#ifndef MSG_ERR_MINTEMP + #define MSG_ERR_MINTEMP "Err: MINTEMP" +#endif +#ifndef MSG_ERR_MAXTEMP_BED + #define MSG_ERR_MAXTEMP_BED "Err: MAXTEMP BED" +#endif +#ifndef MSG_ERR_MINTEMP_BED + #define MSG_ERR_MINTEMP_BED "Err: MINTEMP BED" +#endif +#ifndef MSG_HALTED + #define MSG_HALTED "PRINTER HALTED" +#endif +#ifndef MSG_PLEASE_RESET + #define MSG_PLEASE_RESET "Please reset" +#endif +#ifndef MSG_SHORT_DAY + #define MSG_SHORT_DAY "d" // One character only +#endif +#ifndef MSG_SHORT_HOUR + #define MSG_SHORT_HOUR "h" // One character only +#endif +#ifndef MSG_SHORT_MINUTE + #define MSG_SHORT_MINUTE "m" // One character only +#endif +#ifndef MSG_HEATING + #define MSG_HEATING "Heating..." +#endif +#ifndef MSG_HEATING_COMPLETE + #define MSG_HEATING_COMPLETE "Heating done." +#endif +#ifndef MSG_BED_HEATING + #define MSG_BED_HEATING "Bed Heating." +#endif +#ifndef MSG_BED_DONE + #define MSG_BED_DONE "Bed done." +#endif +#ifndef MSG_DELTA_CALIBRATE + #define MSG_DELTA_CALIBRATE "Delta Calibration" +#endif +#ifndef MSG_DELTA_CALIBRATE_X + #define MSG_DELTA_CALIBRATE_X "Calibrate X" +#endif +#ifndef MSG_DELTA_CALIBRATE_Y + #define MSG_DELTA_CALIBRATE_Y "Calibrate Y" +#endif +#ifndef MSG_DELTA_CALIBRATE_Z + #define MSG_DELTA_CALIBRATE_Z "Calibrate Z" +#endif +#ifndef MSG_DELTA_CALIBRATE_CENTER + #define MSG_DELTA_CALIBRATE_CENTER "Calibrate Center" +#endif + +#ifndef MSG_INFO_MENU + #define MSG_INFO_MENU "About Printer" +#endif +#ifndef MSG_INFO_PRINTER_MENU + #define MSG_INFO_PRINTER_MENU "Printer Info" +#endif +#ifndef MSG_INFO_STATS_MENU + #define MSG_INFO_STATS_MENU "Printer Stats" +#endif +#ifndef MSG_INFO_BOARD_MENU + #define MSG_INFO_BOARD_MENU "Board Info" +#endif +#ifndef MSG_INFO_THERMISTOR_MENU + #define MSG_INFO_THERMISTOR_MENU "Thermistors" +#endif +#ifndef MSG_INFO_EXTRUDERS + #define MSG_INFO_EXTRUDERS "Extruders" +#endif +#ifndef MSG_INFO_BAUDRATE + #define MSG_INFO_BAUDRATE "Baud" +#endif +#ifndef MSG_INFO_PROTOCOL + #define MSG_INFO_PROTOCOL "Protocol" +#endif + +#if LCD_WIDTH > 19 + #ifndef MSG_INFO_PRINT_COUNT + #define MSG_INFO_PRINT_COUNT "Print Count" + #endif + #ifndef MSG_INFO_COMPLETED_PRINTS + #define MSG_INFO_COMPLETED_PRINTS "Completed" + #endif + #ifndef MSG_INFO_PRINT_TIME + #define MSG_INFO_PRINT_TIME "Total print time" + #endif + #ifndef MSG_INFO_PRINT_LONGEST + #define MSG_INFO_PRINT_LONGEST "Longest job time" + #endif + #ifndef MSG_INFO_PRINT_FILAMENT + #define MSG_INFO_PRINT_FILAMENT "Extruded total" + #endif +#else + #ifndef MSG_INFO_PRINT_COUNT + #define MSG_INFO_PRINT_COUNT "Prints" + #endif + #ifndef MSG_INFO_COMPLETED_PRINTS + #define MSG_INFO_COMPLETED_PRINTS "Completed" + #endif + #ifndef MSG_INFO_PRINT_TIME + #define MSG_INFO_PRINT_TIME "Total" + #endif + #ifndef MSG_INFO_PRINT_LONGEST + #define MSG_INFO_PRINT_LONGEST "Longest" + #endif + #ifndef MSG_INFO_PRINT_FILAMENT + #define MSG_INFO_PRINT_FILAMENT "Extruded" + #endif +#endif + +#ifndef MSG_INFO_MIN_TEMP + #define MSG_INFO_MIN_TEMP "Min Temp" +#endif +#ifndef MSG_INFO_MAX_TEMP + #define MSG_INFO_MAX_TEMP "Max Temp" +#endif +#ifndef MSG_INFO_PSU + #define MSG_INFO_PSU "Power Supply" +#endif + +#ifndef MSG_FILAMENT_CHANGE_HEADER + #define MSG_FILAMENT_CHANGE_HEADER "CHANGE FILAMENT" +#endif +#ifndef MSG_FILAMENT_CHANGE_OPTION_HEADER + #define MSG_FILAMENT_CHANGE_OPTION_HEADER "CHANGE OPTIONS:" +#endif +#ifndef MSG_FILAMENT_CHANGE_OPTION_EXTRUDE + #define MSG_FILAMENT_CHANGE_OPTION_EXTRUDE "Extrude more" +#endif +#ifndef MSG_FILAMENT_CHANGE_OPTION_RESUME + #define MSG_FILAMENT_CHANGE_OPTION_RESUME "Resume print" +#endif +#if LCD_HEIGHT >= 4 + #ifndef MSG_FILAMENT_CHANGE_INIT_1 + #define MSG_FILAMENT_CHANGE_INIT_1 "Wait for start" + #endif + #ifndef MSG_FILAMENT_CHANGE_INIT_2 + #define MSG_FILAMENT_CHANGE_INIT_2 "of the filament" + #endif + #ifndef MSG_FILAMENT_CHANGE_INIT_3 + #define MSG_FILAMENT_CHANGE_INIT_3 "change" + #endif + #ifndef MSG_FILAMENT_CHANGE_UNLOAD_1 + #define MSG_FILAMENT_CHANGE_UNLOAD_1 "Wait for" + #endif + #ifndef MSG_FILAMENT_CHANGE_UNLOAD_2 + #define MSG_FILAMENT_CHANGE_UNLOAD_2 "filament unload" + #endif + #ifndef MSG_FILAMENT_CHANGE_UNLOAD_3 + #define MSG_FILAMENT_CHANGE_UNLOAD_3 "" + #endif + #ifndef MSG_FILAMENT_CHANGE_INSERT_1 + #define MSG_FILAMENT_CHANGE_INSERT_1 "Insert filament" + #endif + #ifndef MSG_FILAMENT_CHANGE_INSERT_2 + #define MSG_FILAMENT_CHANGE_INSERT_2 "and press button" + #endif + #ifndef MSG_FILAMENT_CHANGE_INSERT_3 + #define MSG_FILAMENT_CHANGE_INSERT_3 "to continue..." + #endif + #ifndef MSG_FILAMENT_CHANGE_LOAD_1 + #define MSG_FILAMENT_CHANGE_LOAD_1 "Wait for" + #endif + #ifndef MSG_FILAMENT_CHANGE_LOAD_2 + #define MSG_FILAMENT_CHANGE_LOAD_2 "filament load" + #endif + #ifndef MSG_FILAMENT_CHANGE_LOAD_3 + #define MSG_FILAMENT_CHANGE_LOAD_3 "" + #endif + #ifndef MSG_FILAMENT_CHANGE_EXTRUDE_1 + #define MSG_FILAMENT_CHANGE_EXTRUDE_1 "Wait for" + #endif + #ifndef MSG_FILAMENT_CHANGE_EXTRUDE_2 + #define MSG_FILAMENT_CHANGE_EXTRUDE_2 "filament extrude" + #endif + #ifndef MSG_FILAMENT_CHANGE_EXTRUDE_3 + #define MSG_FILAMENT_CHANGE_EXTRUDE_3 "" + #endif + #ifndef MSG_FILAMENT_CHANGE_RESUME_1 + #define MSG_FILAMENT_CHANGE_RESUME_1 "Wait for print" + #endif + #ifndef MSG_FILAMENT_CHANGE_RESUME_2 + #define MSG_FILAMENT_CHANGE_RESUME_2 "to resume" + #endif + #ifndef MSG_FILAMENT_CHANGE_RESUME_3 + #define MSG_FILAMENT_CHANGE_RESUME_3 "" + #endif +#else // LCD_HEIGHT < 4 + #ifndef MSG_FILAMENT_CHANGE_INIT_1 + #define MSG_FILAMENT_CHANGE_INIT_1 "Please wait..." + #endif + #ifndef MSG_FILAMENT_CHANGE_UNLOAD_1 + #define MSG_FILAMENT_CHANGE_UNLOAD_1 "Ejecting..." + #endif + #ifndef MSG_FILAMENT_CHANGE_INSERT_1 + #define MSG_FILAMENT_CHANGE_INSERT_1 "Insert and Click" + #endif + #ifndef MSG_FILAMENT_CHANGE_LOAD_1 + #define MSG_FILAMENT_CHANGE_LOAD_1 "Loading..." + #endif + #ifndef MSG_FILAMENT_CHANGE_EXTRUDE_1 + #define MSG_FILAMENT_CHANGE_EXTRUDE_1 "Extruding..." + #endif + #ifndef MSG_FILAMENT_CHANGE_RESUME_1 + #define MSG_FILAMENT_CHANGE_RESUME_1 "Resuming..." + #endif +#endif // LCD_HEIGHT < 4 + +#endif // LANGUAGE_EN_H diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_es.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_es.h new file mode 100644 index 00000000..2943fcf9 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_es.h @@ -0,0 +1,195 @@ +/** + * 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 . + * + */ + +/** + * Spanish + * + * LCD Menu Messages + * See also https://github.com/MarlinFirmware/Marlin/wiki/LCD-Language + * + */ +#ifndef LANGUAGE_ES_H +#define LANGUAGE_ES_H + +// Define SIMULATE_ROMFONT to see what is seen on the character based display defined in Configuration.h +//#define SIMULATE_ROMFONT +#define DISPLAY_CHARSET_ISO10646_1 + +#define WELCOME_MSG MACHINE_NAME " lista." +#define MSG_SD_INSERTED "Tarjeta colocada" +#define MSG_SD_REMOVED "Tarjeta retirada" +#define MSG_LCD_ENDSTOPS "Endstops" // Max length 8 characters +#define MSG_MAIN "Menu principal" +#define MSG_AUTOSTART "Inicio automatico" +#define MSG_DISABLE_STEPPERS "Apagar motores" +#define MSG_AUTO_HOME "Llevar al origen" +#define MSG_AUTO_HOME_X "Origen X" +#define MSG_AUTO_HOME_Y "Origen Y" +#define MSG_AUTO_HOME_Z "Origen Z" +#define MSG_LEVEL_BED_HOMING "Origen XYZ" +#define MSG_LEVEL_BED_WAITING "Presione para iniciar" +#define MSG_LEVEL_BED_DONE "Nivelacion lista!" +#define MSG_LEVEL_BED_CANCEL "Cancelar" +#define MSG_SET_HOME_OFFSETS "Ajustar desfases" +#define MSG_HOME_OFFSETS_APPLIED "Desfase aplicado" +#define MSG_SET_ORIGIN "Establecer origen" +#define MSG_PREHEAT_1 "Precalentar PLA" +#define MSG_PREHEAT_1_N MSG_PREHEAT_1 " " +#define MSG_PREHEAT_1_ALL MSG_PREHEAT_1 "Todo" +#define MSG_PREHEAT_1_BEDONLY MSG_PREHEAT_1"Plataforma" +#define MSG_PREHEAT_1_SETTINGS MSG_PREHEAT_1 "Config" +#define MSG_PREHEAT_2 "Precalentar ABS" +#define MSG_PREHEAT_2_N MSG_PREHEAT_2 " " +#define MSG_PREHEAT_2_ALL MSG_PREHEAT_2 "Todo" +#define MSG_PREHEAT_2_BEDONLY MSG_PREHEAT_2 "Plataforma" +#define MSG_PREHEAT_2_SETTINGS MSG_PREHEAT_2 "Config" +#define MSG_H1 "1" +#define MSG_H2 "2" +#define MSG_H3 "3" +#define MSG_H4 "4" +#define MSG_COOLDOWN "Enfriar" +#define MSG_SWITCH_PS_ON "Encender" +#define MSG_SWITCH_PS_OFF "Apagar" +#define MSG_EXTRUDE "Extruir" +#define MSG_RETRACT "Retraer" +#define MSG_MOVE_AXIS "Mover ejes" +#define MSG_LEVEL_BED "Nivelar plataforma" +#define MSG_MOVE_X "Mover X" +#define MSG_MOVE_Y "Mover Y" +#define MSG_MOVE_Z "Mover Z" +#define MSG_MOVE_E "Extrusor" +#define MSG_MOVE_E1 "1" +#define MSG_MOVE_E2 "2" +#define MSG_MOVE_E3 "3" +#define MSG_MOVE_E4 "4" +#define MSG_MOVE_01MM "Mover 0.1mm" +#define MSG_MOVE_1MM "Mover 1mm" +#define MSG_MOVE_10MM "Mover 10mm" +#define MSG_SPEED "Velocidad" +#define MSG_BED_Z "Plataforma Z" +#define MSG_NOZZLE "Boquilla" +#define MSG_N1 " 1" +#define MSG_N2 " 2" +#define MSG_N3 " 3" +#define MSG_N4 " 4" +#define MSG_BED "Plataforma" +#define MSG_FAN_SPEED "Ventilador" +#define MSG_FLOW "Flujo" +#define MSG_CONTROL "Control" +#define MSG_MIN LCD_STR_THERMOMETER " Min" +#define MSG_MAX LCD_STR_THERMOMETER " Max" +#define MSG_FACTOR LCD_STR_THERMOMETER " Fact" +#define MSG_AUTOTEMP "Temperatura Automatica" +#define MSG_ON "Encender" +#define MSG_OFF "Apagar" +#define MSG_PID_P "PID-P" +#define MSG_PID_I "PID-I" +#define MSG_PID_D "PID-D" +#define MSG_PID_C "PID-C" +#define MSG_E1 " E1" +#define MSG_E2 " E2" +#define MSG_E3 " E3" +#define MSG_E4 " E4" +#define MSG_ACC "Aceleracion" +#define MSG_VXY_JERK "Vxy-jerk" +#define MSG_VZ_JERK "Vz-jerk" +#define MSG_VE_JERK "Ve-jerk" +#define MSG_VMAX "Vmax" +#define MSG_X "X" +#define MSG_Y "Y" +#define MSG_Z "Z" +#define MSG_E "E" +#define MSG_VMIN "Vmin" +#define MSG_VTRAV_MIN "Vel. viaje min" +#define MSG_AMAX "Acel. max" +#define MSG_A_RETRACT "Acel. retrac." +#define MSG_A_TRAVEL "Acel. Viaje" +#define MSG_XSTEPS "X pasos/mm" +#define MSG_YSTEPS "Y pasos/mm" +#define MSG_ZSTEPS "Z pasos/mm" +#define MSG_ESTEPS "E pasos/mm" +#define MSG_TEMPERATURE "Temperatura" +#define MSG_MOTION "Movimiento" +#define MSG_VOLUMETRIC "Filamento" +#define MSG_VOLUMETRIC_ENABLED "E in mm3" +#define MSG_FILAMENT_DIAM "Fil. Dia." +#define MSG_DIAM_E1 " 1" +#define MSG_DIAM_E2 " 2" +#define MSG_DIAM_E3 " 3" +#define MSG_DIAM_E4 " 4" +#define MSG_CONTRAST "Contraste" +#define MSG_STORE_EPROM "Guardar memoria" +#define MSG_LOAD_EPROM "Cargar memoria" +#define MSG_RESTORE_FAILSAFE "Restaurar memoria." +#define MSG_REFRESH "Volver a cargar" +#define MSG_WATCH "Informacion" +#define MSG_PREPARE "Preparar" +#define MSG_TUNE "Ajustar" +#define MSG_PAUSE_PRINT "Pausar impresion" +#define MSG_RESUME_PRINT "Reanudar impresion" +#define MSG_STOP_PRINT "Detener impresion" +#define MSG_CARD_MENU "Menu de SD" +#define MSG_NO_CARD "No hay tarjeta SD" +#define MSG_DWELL "Reposo..." +#define MSG_USERWAIT "Esperando ordenes" +#define MSG_RESUMING "Resumiendo impre." +#define MSG_PRINT_ABORTED "Impresion cancelada" +#define MSG_NO_MOVE "Sin movimiento" +#define MSG_KILLED "Parada de emergencia." +#define MSG_STOPPED "Detenida" +#define MSG_CONTROL_RETRACT "Retraer mm" +#define MSG_CONTROL_RETRACT_SWAP "Interc. Retraer mm" +#define MSG_CONTROL_RETRACTF "Retraer V" +#define MSG_CONTROL_RETRACT_ZLIFT "Levantar mm" +#define MSG_CONTROL_RETRACT_RECOVER "DesRet +mm" +#define MSG_CONTROL_RETRACT_RECOVER_SWAP "Interc. DesRet +mm" +#define MSG_CONTROL_RETRACT_RECOVERF "DesRet V" +#define MSG_AUTORETRACT "Retraccion Auto." +#define MSG_FILAMENTCHANGE "Cambiar filamento" +#define MSG_INIT_SDCARD "Iniciando tarjeta" +#define MSG_CNG_SDCARD "Cambiar tarjeta" +#define MSG_ZPROBE_OUT "Sonda Z fuera" +#define MSG_HOME "Home" // Used as MSG_HOME " " MSG_X MSG_Y MSG_Z " " MSG_FIRST +#define MSG_FIRST "first" +#define MSG_ZPROBE_ZOFFSET "Desfase Z" +#define MSG_BABYSTEP_X "Micropaso X" +#define MSG_BABYSTEP_Y "Micropaso Y" +#define MSG_BABYSTEP_Z "Micropaso Z" +#define MSG_ENDSTOP_ABORT "Cancelado - Endstop" +#define MSG_HEATING_FAILED_LCD "Error: al calentar" +#define MSG_ERR_REDUNDANT_TEMP "Error: temperatura redundante" +#define MSG_THERMAL_RUNAWAY "Error de temperatura" +#define MSG_ERR_MAXTEMP "Error: Temp Maxima" +#define MSG_ERR_MINTEMP "Error: Temp Minima" +#define MSG_ERR_MAXTEMP_BED "Error: Temp Max Plataforma" +#define MSG_ERR_MINTEMP_BED "Error: Temp Min Plataforma" +#define MSG_HEATING "Calentando..." +#define MSG_HEATING_COMPLETE "Calentamiento Completo" +#define MSG_BED_HEATING "Calentando plataforma ..." +#define MSG_BED_DONE "Plataforma Caliente" +#define MSG_DELTA_CALIBRATE "Calibracion Delta" +#define MSG_DELTA_CALIBRATE_X "Calibrar X" +#define MSG_DELTA_CALIBRATE_Y "Calibrar Y" +#define MSG_DELTA_CALIBRATE_Z "Calibrar Z" +#define MSG_DELTA_CALIBRATE_CENTER "Calibrar Centro" + +#endif // LANGUAGE_ES_H diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_eu.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_eu.h new file mode 100644 index 00000000..909d6c85 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_eu.h @@ -0,0 +1,157 @@ +/** + * 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 . + * + */ + +/** + * Basque-Euskera + * + * LCD Menu Messages + * See also https://github.com/MarlinFirmware/Marlin/wiki/LCD-Language + * + */ +#ifndef LANGUAGE_EU_H +#define LANGUAGE_EU_H + +// Define SIMULATE_ROMFONT to see what is seen on the character based display defined in Configuration.h +//#define SIMULATE_ROMFONT +#define DISPLAY_CHARSET_ISO10646_1 + +#define WELCOME_MSG MACHINE_NAME " prest." +#define MSG_SD_INSERTED "Txartela sartuta" +#define MSG_SD_REMOVED "Txartela kenduta" +#define MSG_MAIN "Menu nagusia" +#define MSG_AUTOSTART "Auto hasiera" +#define MSG_DISABLE_STEPPERS "Itzali motoreak" +#define MSG_AUTO_HOME "Hasierara joan" +#define MSG_LEVEL_BED_HOMING "Homing XYZ" +#define MSG_LEVEL_BED_WAITING "Click to Begin" +#define MSG_LEVEL_BED_DONE "Leveling Done!" +#define MSG_LEVEL_BED_CANCEL "Cancel" +#define MSG_SET_HOME_OFFSETS "Set home offsets" +#define MSG_HOME_OFFSETS_APPLIED "Offsets applied" +#define MSG_SET_ORIGIN "Hasiera ipini" +#define MSG_PREHEAT_1 "Aurreberotu PLA" +#define MSG_PREHEAT_1_N "Aurreberotu PLA " +#define MSG_PREHEAT_1_ALL "Berotu PLA Guztia" +#define MSG_PREHEAT_1_BEDONLY "Berotu PLA Ohea" +#define MSG_PREHEAT_1_SETTINGS "Berotu PLA Konfig" +#define MSG_PREHEAT_2 "Aurreberotu ABS" +#define MSG_PREHEAT_2_N "Aurreberotu ABS " +#define MSG_PREHEAT_2_ALL "Berotu ABS Guztia" +#define MSG_PREHEAT_2_BEDONLY "Berotu ABS Ohea" +#define MSG_PREHEAT_2_SETTINGS "Berotu ABS Konfig" +#define MSG_COOLDOWN "Hoztu" +#define MSG_SWITCH_PS_ON "Energia piztu" +#define MSG_SWITCH_PS_OFF "Energia itzali" +#define MSG_EXTRUDE "Estruitu" +#define MSG_RETRACT "Atzera eragin" +#define MSG_MOVE_AXIS "Ardatzak mugitu" +#define MSG_MOVE_X "Mugitu X" +#define MSG_MOVE_Y "Mugitu Y" +#define MSG_MOVE_Z "Mugitu Z" +#define MSG_MOVE_E "Estrusorea" +#define MSG_MOVE_01MM "Mugitu 0.1mm" +#define MSG_MOVE_1MM "Mugitu 1mm" +#define MSG_MOVE_10MM "Mugitu 10mm" +#define MSG_SPEED "Abiadura" +#define MSG_NOZZLE "Pita" +#define MSG_BED "Ohea" +#define MSG_FAN_SPEED "Haizagailua" +#define MSG_FLOW "Fluxua" +#define MSG_CONTROL "Kontrola" +#define MSG_MIN LCD_STR_THERMOMETER " Min" +#define MSG_MAX LCD_STR_THERMOMETER " Max" +#define MSG_FACTOR LCD_STR_THERMOMETER " Faktorea" +#define MSG_AUTOTEMP "Auto tenperatura" +#define MSG_ON "On " +#define MSG_OFF "Off" +#define MSG_PID_P "PID-P" +#define MSG_PID_I "PID-I" +#define MSG_PID_D "PID-D" +#define MSG_PID_C "PID-C" +#define MSG_ACC "Azelerazioa" +#define MSG_VXY_JERK "Vxy-astindua" +#define MSG_VZ_JERK "Vz-astindua" +#define MSG_VE_JERK "Ve-astindua" +#define MSG_VMAX "Vmax " +#define MSG_X "X" +#define MSG_Y "Y" +#define MSG_Z "Z" +#define MSG_E "E" +#define MSG_VMIN "Vmin" +#define MSG_VTRAV_MIN "VTrav min" +#define MSG_AMAX "Amax " +#define MSG_A_RETRACT "A-retrakt" +#define MSG_XSTEPS "X pausoak/mm" +#define MSG_YSTEPS "Y pausoak/mm" +#define MSG_ZSTEPS "Z pausoak/mm" +#define MSG_ESTEPS "E pausoak/mm" +#define MSG_TEMPERATURE "Tenperatura" +#define MSG_MOTION "Mugimendua" +#define MSG_VOLUMETRIC "Filament" +#define MSG_VOLUMETRIC_ENABLED "E in mm3" +#define MSG_FILAMENT_DIAM "Fil. Dia." +#define MSG_CONTRAST "LCD kontrastea" +#define MSG_STORE_EPROM "Gorde memoria" +#define MSG_LOAD_EPROM "Kargatu memoria" +#define MSG_RESTORE_FAILSAFE "Larri. berriz." +#define MSG_REFRESH "Berriz kargatu" +#define MSG_WATCH "Pantaila info" +#define MSG_PREPARE "Prestatu" +#define MSG_TUNE "Doitu" +#define MSG_PAUSE_PRINT "Pausatu inprimak." +#define MSG_RESUME_PRINT "Jarraitu inprima." +#define MSG_STOP_PRINT "Gelditu inprima." +#define MSG_CARD_MENU "SD-tik inprimatu" +#define MSG_NO_CARD "Ez dago txartelik" +#define MSG_DWELL "Lo egin..." +#define MSG_USERWAIT "Aginduak zain..." +#define MSG_RESUMING "Jarraitzen inpri." +#define MSG_PRINT_ABORTED "Print aborted" +#define MSG_NO_MOVE "Mugimendu gabe" +#define MSG_KILLED "LARRIALDI GELDIA" +#define MSG_STOPPED "GELDITUTA. " +#define MSG_CONTROL_RETRACT "Atzera egin mm" +#define MSG_CONTROL_RETRACT_SWAP "Swap Atzera egin mm" +#define MSG_CONTROL_RETRACTF "Atzera egin V" +#define MSG_CONTROL_RETRACT_ZLIFT "Igo mm" +#define MSG_CONTROL_RETRACT_RECOVER "Atzera egin +mm" +#define MSG_CONTROL_RETRACT_RECOVER_SWAP "Swap Atzera egin +mm" +#define MSG_CONTROL_RETRACT_RECOVERF "Atzera egin V" +#define MSG_AUTORETRACT "Atzera egin" +#define MSG_FILAMENTCHANGE "Aldatu filament." +#define MSG_INIT_SDCARD "Hasieratu txartela" +#define MSG_CNG_SDCARD "Aldatu txartela" +#define MSG_ZPROBE_OUT "Z ohe hasiera" +#define MSG_HOME "Home" // Used as MSG_HOME " " MSG_X MSG_Y MSG_Z " " MSG_FIRST +#define MSG_FIRST "first" +#define MSG_ZPROBE_ZOFFSET "Z konpentsatu" +#define MSG_BABYSTEP_X "Babystep X" +#define MSG_BABYSTEP_Y "Babystep Y" +#define MSG_BABYSTEP_Z "Babystep Z" +#define MSG_ENDSTOP_ABORT "Endstop deuseztat" +#define MSG_DELTA_CALIBRATE "Delta Calibration" +#define MSG_DELTA_CALIBRATE_X "Calibrate X" +#define MSG_DELTA_CALIBRATE_Y "Calibrate Y" +#define MSG_DELTA_CALIBRATE_Z "Calibrate Z" +#define MSG_DELTA_CALIBRATE_CENTER "Calibrate Center" + +#endif // LANGUAGE_EU_H diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_fi.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_fi.h new file mode 100644 index 00000000..b73a207e --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_fi.h @@ -0,0 +1,158 @@ +/** + * 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 . + * + */ + +/** + * Finnish + * + * LCD Menu Messages + * See also https://github.com/MarlinFirmware/Marlin/wiki/LCD-Language + * + */ +#ifndef LANGUAGE_FI_H +#define LANGUAGE_FI_H + +#define MAPPER_C2C3 +// Define SIMULATE_ROMFONT to see what is seen on the character based display defined in Configuration.h +//#define SIMULATE_ROMFONT +#define DISPLAY_CHARSET_ISO10646_1 + +#define WELCOME_MSG MACHINE_NAME " valmis." +#define MSG_SD_INSERTED "Kortti asetettu" +#define MSG_SD_REMOVED "Kortti poistettu" +#define MSG_MAIN "Palaa" +#define MSG_AUTOSTART "Automaatti" +#define MSG_DISABLE_STEPPERS "Vapauta moottorit" +#define MSG_AUTO_HOME "Aja referenssiin" +#define MSG_LEVEL_BED_HOMING "Homing XYZ" +#define MSG_LEVEL_BED_WAITING "Click to Begin" +#define MSG_LEVEL_BED_DONE "Leveling Done!" +#define MSG_LEVEL_BED_CANCEL "Cancel" +#define MSG_SET_HOME_OFFSETS "Set home offsets" +#define MSG_HOME_OFFSETS_APPLIED "Offsets applied" +#define MSG_SET_ORIGIN "Aseta origo" +#define MSG_PREHEAT_1 "Esilämmitä PLA" +#define MSG_PREHEAT_1_N "Esilämmitä PLA " +#define MSG_PREHEAT_1_ALL "Esilä. PLA Kaikki" +#define MSG_PREHEAT_1_BEDONLY "Esilä. PLA Alusta" +#define MSG_PREHEAT_1_SETTINGS "Esilämm. PLA konf" +#define MSG_PREHEAT_2 "Esilämmitä ABS" +#define MSG_PREHEAT_2_N "Esilämmitä ABS " +#define MSG_PREHEAT_2_ALL "Esilä. ABS Kaikki" +#define MSG_PREHEAT_2_BEDONLY "Esilä. ABS Alusta" +#define MSG_PREHEAT_2_SETTINGS "Esilämm. ABS konf" +#define MSG_COOLDOWN "Jäähdytä" +#define MSG_SWITCH_PS_ON "Virta päälle" +#define MSG_SWITCH_PS_OFF "Virta pois" +#define MSG_EXTRUDE "Pursota" +#define MSG_RETRACT "Vedä takaisin" +#define MSG_MOVE_AXIS "Liikuta akseleita" +#define MSG_MOVE_X "Liikuta X" +#define MSG_MOVE_Y "Liikuta Y" +#define MSG_MOVE_Z "Liikuta Z" +#define MSG_MOVE_E "Extruder" +#define MSG_MOVE_01MM "Liikuta 0.1mm" +#define MSG_MOVE_1MM "Liikuta 1mm" +#define MSG_MOVE_10MM "Liikuta 10mm" +#define MSG_SPEED "Nopeus" +#define MSG_NOZZLE "Suutin" +#define MSG_BED "Alusta" +#define MSG_FAN_SPEED "Tuul. nopeus" +#define MSG_FLOW "Virtaus" +#define MSG_CONTROL "Kontrolli" +#define MSG_MIN LCD_STR_THERMOMETER " Min" +#define MSG_MAX LCD_STR_THERMOMETER " Max" +#define MSG_FACTOR LCD_STR_THERMOMETER " Kerr" +#define MSG_AUTOTEMP "Autotemp" +#define MSG_ON "On " +#define MSG_OFF "Off" +#define MSG_PID_P "PID-P" +#define MSG_PID_I "PID-I" +#define MSG_PID_D "PID-D" +#define MSG_PID_C "PID-C" +#define MSG_ACC "Kiihtyv" +#define MSG_VXY_JERK "Vxy-jerk" +#define MSG_VZ_JERK "Vz-jerk" +#define MSG_VE_JERK "Ve-jerk" +#define MSG_VMAX "Vmax " +#define MSG_X "X" +#define MSG_Y "Y" +#define MSG_Z "Z" +#define MSG_E "E" +#define MSG_VMIN "Vmin" +#define MSG_VTRAV_MIN "VLiike min" +#define MSG_AMAX "Amax " +#define MSG_A_RETRACT "A-peruuta" +#define MSG_XSTEPS "Xsteps/mm" +#define MSG_YSTEPS "Ysteps/mm" +#define MSG_ZSTEPS "Zsteps/mm" +#define MSG_ESTEPS "Esteps/mm" +#define MSG_TEMPERATURE "Lämpötila" +#define MSG_MOTION "Liike" +#define MSG_VOLUMETRIC "Filament" +#define MSG_VOLUMETRIC_ENABLED "E in mm³" +#define MSG_FILAMENT_DIAM "Fil. Dia." +#define MSG_CONTRAST "LCD kontrasti" +#define MSG_STORE_EPROM "Tallenna muistiin" +#define MSG_LOAD_EPROM "Lataa muistista" +#define MSG_RESTORE_FAILSAFE "Palauta oletus" +#define MSG_REFRESH "Päivitä" +#define MSG_WATCH "Seuraa" +#define MSG_PREPARE "Valmistele" +#define MSG_TUNE "Säädä" +#define MSG_PAUSE_PRINT "Keskeytä tulostus" +#define MSG_RESUME_PRINT "Jatka tulostusta" +#define MSG_STOP_PRINT "Pysäytä tulostus" +#define MSG_CARD_MENU "Korttivalikko" +#define MSG_NO_CARD "Ei korttia" +#define MSG_DWELL "Nukkumassa..." +#define MSG_USERWAIT "Odotet. valintaa" +#define MSG_RESUMING "Jatke. tulostusta" +#define MSG_PRINT_ABORTED "Print aborted" +#define MSG_NO_MOVE "Ei liiketta." +#define MSG_KILLED "KILLED. " +#define MSG_STOPPED "STOPPED. " +#define MSG_CONTROL_RETRACT "Vedä mm" +#define MSG_CONTROL_RETRACT_SWAP "Va. Vedä mm" +#define MSG_CONTROL_RETRACTF "Vedä V" +#define MSG_CONTROL_RETRACT_ZLIFT "Z mm" +#define MSG_CONTROL_RETRACT_RECOVER "UnRet +mm" +#define MSG_CONTROL_RETRACT_RECOVER_SWAP "Va. UnRet +mm" +#define MSG_CONTROL_RETRACT_RECOVERF "UnRet V" +#define MSG_AUTORETRACT "AutoVeto." +#define MSG_FILAMENTCHANGE "Change filament" +#define MSG_INIT_SDCARD "Init. SD-Card" +#define MSG_CNG_SDCARD "Change SD-Card" +#define MSG_ZPROBE_OUT "Z probe out. bed" +#define MSG_HOME "Home" // Used as MSG_HOME " " MSG_X MSG_Y MSG_Z " " MSG_FIRST +#define MSG_FIRST "first" +#define MSG_ZPROBE_ZOFFSET "Z Offset" +#define MSG_BABYSTEP_X "Babystep X" +#define MSG_BABYSTEP_Y "Babystep Y" +#define MSG_BABYSTEP_Z "Babystep Z" +#define MSG_ENDSTOP_ABORT "Endstop abort" +#define MSG_DELTA_CALIBRATE "Delta Kalibrointi" +#define MSG_DELTA_CALIBRATE_X "Kalibroi X" +#define MSG_DELTA_CALIBRATE_Y "Kalibroi Y" +#define MSG_DELTA_CALIBRATE_Z "Kalibroi Z" +#define MSG_DELTA_CALIBRATE_CENTER "Kalibroi Center" + +#endif // LANGUAGE_FI_H diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_fr.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_fr.h new file mode 100644 index 00000000..52adbcba --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_fr.h @@ -0,0 +1,171 @@ +/** + * 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 . + * + */ + +/** + * French + * + * LCD Menu Messages + * See also https://github.com/MarlinFirmware/Marlin/wiki/LCD-Language + * + */ +#ifndef LANGUAGE_FR_H +#define LANGUAGE_FR_H + +// Define SIMULATE_ROMFONT to see what is seen on the character based display defined in Configuration.h +//#define SIMULATE_ROMFONT +#define DISPLAY_CHARSET_ISO10646_1 + +#define WELCOME_MSG MACHINE_NAME " prete." +#define MSG_SD_INSERTED "Carte inseree" +#define MSG_SD_REMOVED "Carte retiree" +#define MSG_MAIN "Menu principal" +#define MSG_AUTOSTART "Demarrage auto" +#define MSG_DISABLE_STEPPERS "Arreter moteurs" +#define MSG_AUTO_HOME "Origine auto." +#define MSG_LEVEL_BED_HOMING "Origine XYZ" +#define MSG_LEVEL_BED_WAITING "Cliquer pour commencer" +#define MSG_LEVEL_BED_DONE "Mise a niveau OK!" +#define MSG_LEVEL_BED_CANCEL "Annuler" +#define MSG_SET_HOME_OFFSETS "Regler decal. origine" +#define MSG_HOME_OFFSETS_APPLIED "Decalages appliques" +#define MSG_SET_ORIGIN "Regler origine" +#define MSG_PREHEAT_1 "Prechauffage PLA" +#define MSG_PREHEAT_1_N "Prechauff. PLA " +#define MSG_PREHEAT_1_ALL "Prech. PLA Tout" +#define MSG_PREHEAT_1_BEDONLY "Prech. PLA Plateau" +#define MSG_PREHEAT_1_SETTINGS "Regl. prech. PLA" +#define MSG_PREHEAT_2 "Prechauffage ABS" +#define MSG_PREHEAT_2_N "Prechauff. ABS " +#define MSG_PREHEAT_2_ALL "Prech. ABS Tout" +#define MSG_PREHEAT_2_BEDONLY "Prech. ABS Plateau" +#define MSG_PREHEAT_2_SETTINGS "Regl. prech. ABS" +#define MSG_COOLDOWN "Refroidir" +#define MSG_SWITCH_PS_ON "Allumer alim." +#define MSG_SWITCH_PS_OFF "Eteindre alim." +#define MSG_EXTRUDE "Extrusion" +#define MSG_RETRACT "Retraction" +#define MSG_MOVE_AXIS "Deplacer un axe" +#define MSG_LEVEL_BED "Regl. Niv. Plateau" +#define MSG_MOVE_X "Depl. X" +#define MSG_MOVE_Y "Depl. Y" +#define MSG_MOVE_Z "Depl. Z" +#define MSG_MOVE_E "Extruder" +#define MSG_MOVE_01MM "Depl. 0.1mm" +#define MSG_MOVE_1MM "Depl. 1mm" +#define MSG_MOVE_10MM "Depl. 10mm" +#define MSG_SPEED " Vitesse" +#define MSG_BED_Z "Plateau Z" +#define MSG_NOZZLE "Buse" +#define MSG_BED "Plateau" +#define MSG_FAN_SPEED "Vite. ventilateur" +#define MSG_FLOW "Flux" +#define MSG_CONTROL "Controler" +#define MSG_MIN LCD_STR_THERMOMETER " Min" +#define MSG_MAX LCD_STR_THERMOMETER " Max" +#define MSG_FACTOR LCD_STR_THERMOMETER " Facteur" +#define MSG_AUTOTEMP "Temp. Auto." +#define MSG_ON "Marche " +#define MSG_OFF "Arret" +#define MSG_PID_P "PID-P" +#define MSG_PID_I "PID-I" +#define MSG_PID_D "PID-D" +#define MSG_PID_C "PID-C" +#define MSG_ACC "Accel" +#define MSG_VXY_JERK "Vxy-jerk" +#define MSG_VZ_JERK "Vz-jerk" +#define MSG_VE_JERK "Ve-jerk" +#define MSG_VMAX "Vmax" +#define MSG_X "X" +#define MSG_Y "Y" +#define MSG_Z "Z" +#define MSG_E "E" +#define MSG_VMIN "Vmin" +#define MSG_VTRAV_MIN "Vdepl min" +#define MSG_AMAX "Amax " +#define MSG_A_RETRACT "A-retract" +#define MSG_A_TRAVEL "A-Depl." +#define MSG_XSTEPS "Xpas/mm" +#define MSG_YSTEPS "Ypas/mm" +#define MSG_ZSTEPS "Zpas/mm" +#define MSG_ESTEPS "Epas/mm" +#define MSG_TEMPERATURE "Temperature" +#define MSG_MOTION "Mouvement" +#define MSG_VOLUMETRIC "Filament" +#define MSG_VOLUMETRIC_ENABLED "E en mm3" +#define MSG_FILAMENT_DIAM "Diam. Fil." +#define MSG_CONTRAST "Contraste LCD" +#define MSG_STORE_EPROM "Sauver config" +#define MSG_LOAD_EPROM "Lire config" +#define MSG_RESTORE_FAILSAFE "Restaurer defauts" +#define MSG_REFRESH "Actualiser" +#define MSG_WATCH "Surveiller" +#define MSG_PREPARE "Preparer" +#define MSG_TUNE "Regler" +#define MSG_PAUSE_PRINT "Interrompre impr." +#define MSG_RESUME_PRINT "Reprendre impr." +#define MSG_STOP_PRINT "Arreter impr." +#define MSG_CARD_MENU "Impr. depuis SD" +#define MSG_NO_CARD "Pas de carte" +#define MSG_DWELL "Repos..." +#define MSG_USERWAIT "Atten. de l'util." +#define MSG_RESUMING "Repri. de l'impr." +#define MSG_PRINT_ABORTED "Impr. Annulee" +#define MSG_NO_MOVE "Aucun mouvement." +#define MSG_KILLED "MORT." +#define MSG_STOPPED "STOPPE." +#define MSG_CONTROL_RETRACT "Retraction mm" +#define MSG_CONTROL_RETRACT_SWAP "Ech. Retr. mm" +#define MSG_CONTROL_RETRACTF "Retraction V" +#define MSG_CONTROL_RETRACT_ZLIFT "Hop mm" +#define MSG_CONTROL_RETRACT_RECOVER "UnRet +mm" +#define MSG_CONTROL_RETRACT_RECOVER_SWAP "Ech. UnRet +mm" +#define MSG_CONTROL_RETRACT_RECOVERF "UnRet V" +#define MSG_AUTORETRACT "Retract. Auto." +#define MSG_FILAMENTCHANGE "Changer filament" +#define MSG_INIT_SDCARD "Init. la carte SD" +#define MSG_CNG_SDCARD "Changer de carte" +#define MSG_ZPROBE_OUT "Z sonde exte. lit" +#define MSG_HOME "Home" // Used as MSG_HOME " " MSG_X MSG_Y MSG_Z " " MSG_FIRST +#define MSG_FIRST "first" +#define MSG_ZPROBE_ZOFFSET "Decalage Z" +#define MSG_BABYSTEP_X "Babystep X" +#define MSG_BABYSTEP_Y "Babystep Y" +#define MSG_BABYSTEP_Z "Babystep Z" +#define MSG_ENDSTOP_ABORT "Butee abandon" +#define MSG_HEATING_FAILED_LCD "Erreur de chauffe" +#define MSG_ERR_REDUNDANT_TEMP "Err: ERREUR TEMP. REDONDANTE" +#define MSG_THERMAL_RUNAWAY "EMBALLEMENT THERMIQUE" +#define MSG_ERR_MAXTEMP "Err: TEMP. MAX" +#define MSG_ERR_MINTEMP "Err: TEMP. MIN" +#define MSG_ERR_MAXTEMP_BED "Err: TEMP. MAX PLATEAU" +#define MSG_ERR_MINTEMP_BED "Err: TEMP. MIN PLATEAU" +#define MSG_HEATING "En chauffe..." +#define MSG_HEATING_COMPLETE "Chauffe terminee" +#define MSG_BED_HEATING "Plateau en chauffe..." +#define MSG_BED_DONE "Chauffe plateau terminee" +#define MSG_DELTA_CALIBRATE "Calibration Delta" +#define MSG_DELTA_CALIBRATE_X "Calibrer X" +#define MSG_DELTA_CALIBRATE_Y "Calibrer Y" +#define MSG_DELTA_CALIBRATE_Z "Calibrer Z" +#define MSG_DELTA_CALIBRATE_CENTER "Calibrer centre" + +#endif // LANGUAGE_FR_H diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_gl.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_gl.h new file mode 100644 index 00000000..c5fbbc9f --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_gl.h @@ -0,0 +1,259 @@ +/** + * 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 . + * + */ + +/** + * Galician language (ISO "gl") + * + * LCD Menu Messages + * See also https://github.com/MarlinFirmware/Marlin/wiki/LCD-Language + * + */ +#ifndef LANGUAGE_GL_H +#define LANGUAGE_GL_H + +#define MAPPER_C2C3 +// Define SIMULATE_ROMFONT to see what is seen on the character based display defined in Configuration.h +//#define SIMULATE_ROMFONT +#define DISPLAY_CHARSET_ISO10646_1 + +#define WELCOME_MSG MACHINE_NAME " lista." +#define MSG_SD_INSERTED "Tarxeta inserida" +#define MSG_SD_REMOVED "Tarxeta retirada" +#define MSG_LCD_ENDSTOPS "FinCarro" +#define MSG_MAIN "Menu principal" +#define MSG_AUTOSTART "Autoarranque" +#define MSG_DISABLE_STEPPERS "Apagar motores" +#define MSG_AUTO_HOME "Ir a orixe" +#define MSG_AUTO_HOME_X "Ir orixe X" +#define MSG_AUTO_HOME_Y "Ir orixe Y" +#define MSG_AUTO_HOME_Z "Ir orixe Z" +#define MSG_LEVEL_BED_HOMING "Ir orixes XYZ" +#define MSG_LEVEL_BED_WAITING "Prema pulsador" +#define MSG_LEVEL_BED_NEXT_POINT "Seguinte punto" +#define MSG_LEVEL_BED_DONE "Nivelado feito" +#define MSG_LEVEL_BED_CANCEL "Cancelar" +#define MSG_SET_HOME_OFFSETS "Offsets na orixe" +#define MSG_HOME_OFFSETS_APPLIED "Offsets fixados" +#define MSG_SET_ORIGIN "Fixar orixe" +#define MSG_PREHEAT_1 "Prequentar PLA" +#define MSG_PREHEAT_1_N "Prequentar PLA " +#define MSG_PREHEAT_1_ALL "Preque. PLA Todo" +#define MSG_PREHEAT_1_BEDONLY "Preque. PLA Cama" +#define MSG_PREHEAT_1_SETTINGS "Preque. PLA conf" +#define MSG_PREHEAT_2 "Prequentar ABS" +#define MSG_PREHEAT_2_N "Prequentar ABS " +#define MSG_PREHEAT_2_ALL "Preque. ABS Todo" +#define MSG_PREHEAT_2_BEDONLY "Preque. ABS Cama" +#define MSG_PREHEAT_2_SETTINGS "Preque. ABS conf" +#define MSG_H1 "1" +#define MSG_H2 "2" +#define MSG_H3 "3" +#define MSG_H4 "4" +#define MSG_COOLDOWN "Arrefriar" +#define MSG_SWITCH_PS_ON "Acender" +#define MSG_SWITCH_PS_OFF "Apagar" +#define MSG_EXTRUDE "Extrudir" +#define MSG_RETRACT "Retraer" +#define MSG_MOVE_AXIS "Mover eixe" +#define MSG_LEVEL_BED "Nivelar cama" +#define MSG_MOVE_X "Mover X" +#define MSG_MOVE_Y "Mover Y" +#define MSG_MOVE_Z "Mover Z" +#define MSG_MOVE_E "Extrusor" +#define MSG_MOVE_E1 "1" +#define MSG_MOVE_E2 "2" +#define MSG_MOVE_E3 "3" +#define MSG_MOVE_E4 "4" +#define MSG_MOVE_01MM "Mover 0.1mm" +#define MSG_MOVE_1MM "Mover 1mm" +#define MSG_MOVE_10MM "Mover 10mm" +#define MSG_SPEED "Velocidade" +#define MSG_BED_Z "Cama Z" +#define MSG_NOZZLE "Bico" +#define MSG_N1 " 1" +#define MSG_N2 " 2" +#define MSG_N3 " 3" +#define MSG_N4 " 4" +#define MSG_BED "Cama" +#define MSG_FAN_SPEED "Velocidade vent." +#define MSG_FLOW "Fluxo" +#define MSG_CONTROL "Control" +#define MSG_MIN " " LCD_STR_THERMOMETER " Min" +#define MSG_MAX " " LCD_STR_THERMOMETER " Max" +#define MSG_FACTOR " " LCD_STR_THERMOMETER " Fact" +#define MSG_AUTOTEMP "Autotemp" +#define MSG_ON "On " +#define MSG_OFF "Off" +#define MSG_PID_P "PID-P" +#define MSG_PID_I "PID-I" +#define MSG_PID_D "PID-D" +#define MSG_PID_C "PID-C" +#define MSG_SELECT "Escolla" +#define MSG_E1 " E1" +#define MSG_E2 " E2" +#define MSG_E3 " E3" +#define MSG_E4 " E4" +#define MSG_ACC "Acel" +#define MSG_VXY_JERK "Vxy-jerk" +#define MSG_VZ_JERK "Vz-jerk" +#define MSG_VE_JERK "Ve-jerk" +#define MSG_VMAX "Vmax " +#define MSG_X "X" +#define MSG_Y "Y" +#define MSG_Z "Z" +#define MSG_E "E" +#define MSG_VMIN "Vmin" +#define MSG_VTRAV_MIN "VTrav min" +#define MSG_AMAX "Amax " +#define MSG_A_RETRACT "A-retract" +#define MSG_A_TRAVEL "A-travel" +#define MSG_XSTEPS "Xpasos/mm" +#define MSG_YSTEPS "Ypasos/mm" +#define MSG_ZSTEPS "Zpasos/mm" +#define MSG_ESTEPS "Epasos/mm" +#define MSG_TEMPERATURE "Temperatura" +#define MSG_MOTION "Movemento" +#define MSG_VOLUMETRIC "Filamento" +#define MSG_VOLUMETRIC_ENABLED "E en mm3" +#define MSG_FILAMENT_DIAM "Diam. fil." +#define MSG_DIAM_E1 " 1" +#define MSG_DIAM_E2 " 2" +#define MSG_DIAM_E3 " 3" +#define MSG_DIAM_E4 " 4" +#define MSG_CONTRAST "Constraste LCD" +#define MSG_STORE_EPROM "Gardar en memo." +#define MSG_LOAD_EPROM "Cargar de memo." +#define MSG_RESTORE_FAILSAFE "Cargar de firm." +#define MSG_REFRESH "Volver a cargar" +#define MSG_WATCH "Monitorizacion" +#define MSG_PREPARE "Preparar" +#define MSG_TUNE "Axustar" +#define MSG_PAUSE_PRINT "Pausar impres." +#define MSG_RESUME_PRINT "Seguir impres." +#define MSG_STOP_PRINT "Deter impres." +#define MSG_CARD_MENU "Tarxeta SD" +#define MSG_NO_CARD "Sen tarxeta SD" +#define MSG_DWELL "En repouso..." +#define MSG_USERWAIT "A espera..." +#define MSG_RESUMING "Imprimindo..." +#define MSG_PRINT_ABORTED "Impre. cancelada" +#define MSG_NO_MOVE "Sen movemento." +#define MSG_KILLED "PROGRAMA MORTO" +#define MSG_STOPPED "PROGRAMA PARADO" +#define MSG_CONTROL_RETRACT "Retraccion mm" +#define MSG_CONTROL_RETRACT_SWAP "Cambio retra. mm" +#define MSG_CONTROL_RETRACTF "Retraccion V" +#define MSG_CONTROL_RETRACT_ZLIFT "Alzar Z mm" +#define MSG_CONTROL_RETRACT_RECOVER "Recup. retra. mm" +#define MSG_CONTROL_RETRACT_RECOVER_SWAP "Cambio recup. mm" +#define MSG_CONTROL_RETRACT_RECOVERF "Recuperacion V" +#define MSG_AUTORETRACT "Retraccion auto." +#define MSG_FILAMENTCHANGE "Cambiar filamen." +#define MSG_INIT_SDCARD "Iniciando SD" +#define MSG_CNG_SDCARD "Cambiar SD" +#define MSG_ZPROBE_OUT "Sonda-Z sen cama" +#define MSG_HOME "Home" // Used as MSG_HOME " " MSG_X MSG_Y MSG_Z " " MSG_FIRST +#define MSG_FIRST "first" +#define MSG_ZPROBE_ZOFFSET "Offset Z" +#define MSG_BABYSTEP_X "Micropaso X" +#define MSG_BABYSTEP_Y "Micropaso Y" +#define MSG_BABYSTEP_Z "Micropaso Z" +#define MSG_ENDSTOP_ABORT "Erro fin carro" +#define MSG_HEATING_FAILED_LCD "Fallo quentando" +#define MSG_ERR_REDUNDANT_TEMP "Erro temperatura" +#define MSG_THERMAL_RUNAWAY "Temp. excesiva" +#define MSG_ERR_MAXTEMP "Err: temp. max." +#define MSG_ERR_MINTEMP "Err: temp. min." +#define MSG_ERR_MAXTEMP_BED "Err: MAXTEMP BED" +#define MSG_ERR_MINTEMP_BED "Err: MINTEMP BED" +#define MSG_HALTED "SISTEMA MORTO" +#define MSG_PLEASE_RESET "Debe reiniciar!" +#define MSG_SHORT_DAY "d" // One character only +#define MSG_SHORT_HOUR "h" // One character only +#define MSG_SHORT_MINUTE "m" // One character only +#define MSG_HEATING "Quentando..." +#define MSG_HEATING_COMPLETE "Xa esta quente" +#define MSG_BED_HEATING "Quentando cama" +#define MSG_BED_DONE "Cama esta quente" +#define MSG_DELTA_CALIBRATE "Calibracion Delta" +#define MSG_DELTA_CALIBRATE_X "Calibrar X" +#define MSG_DELTA_CALIBRATE_Y "Calibrar Y" +#define MSG_DELTA_CALIBRATE_Z "Calibrar Z" +#define MSG_DELTA_CALIBRATE_CENTER "Calibrar Centro" +#define MSG_INFO_MENU "Acerca de..." +#define MSG_INFO_PRINTER_MENU "Informacion" +#define MSG_INFO_STATS_MENU "Estadisticas" +#define MSG_INFO_BOARD_MENU "Placa nai" +#define MSG_INFO_THERMISTOR_MENU "Termistores" +#define MSG_INFO_EXTRUDERS "Extrusores" +#define MSG_INFO_BAUDRATE "Baudios" +#define MSG_INFO_PROTOCOL "Protocolo" +#if LCD_WIDTH > 19 + #define MSG_INFO_PRINT_COUNT "Total traballos" + #define MSG_INFO_COMPLETED_PRINTS "Total completos" + #define MSG_INFO_PRINT_TIME "Tempo impresion" + #define MSG_INFO_PRINT_LONGEST "Traballo +longo" + #define MSG_INFO_PRINT_FILAMENT "Total extruido" +#else + #define MSG_INFO_PRINT_COUNT "Traballos" + #define MSG_INFO_COMPLETED_PRINTS "Completos" + #define MSG_INFO_PRINT_TIME "Tempo" + #define MSG_INFO_PRINT_LONGEST "O +longo" + #define MSG_INFO_PRINT_FILAMENT "Extruido" +#endif +#define MSG_INFO_MIN_TEMP "Min Temp" +#define MSG_INFO_MAX_TEMP "Max Temp" +#define MSG_INFO_PSU "Fonte alime." +#define MSG_FILAMENT_CHANGE_HEADER "TROCO FILAMENTO" +#define MSG_FILAMENT_CHANGE_OPTION_HEADER "OPCIONS TROCO:" +#define MSG_FILAMENT_CHANGE_OPTION_EXTRUDE "Extruir mais" +#define MSG_FILAMENT_CHANGE_OPTION_RESUME "Segue traballo" +#if LCD_HEIGHT >= 4 + #define MSG_FILAMENT_CHANGE_INIT_1 "Agarde para" + #define MSG_FILAMENT_CHANGE_INIT_2 "iniciar troco" + #define MSG_FILAMENT_CHANGE_INIT_3 "de filamento" + #define MSG_FILAMENT_CHANGE_UNLOAD_1 "Agarde pola" + #define MSG_FILAMENT_CHANGE_UNLOAD_2 "descarga do" + #define MSG_FILAMENT_CHANGE_UNLOAD_3 "filamento" + #define MSG_FILAMENT_CHANGE_INSERT_1 "Introduza o" + #define MSG_FILAMENT_CHANGE_INSERT_2 "filamento e" + #define MSG_FILAMENT_CHANGE_INSERT_3 "faga click" + #define MSG_FILAMENT_CHANGE_LOAD_1 "Agarde pola" + #define MSG_FILAMENT_CHANGE_LOAD_2 "carga do" + #define MSG_FILAMENT_CHANGE_LOAD_3 "filamento" + #define MSG_FILAMENT_CHANGE_EXTRUDE_1 "Agarde pola" + #define MSG_FILAMENT_CHANGE_EXTRUDE_2 "extrusion do" + #define MSG_FILAMENT_CHANGE_EXTRUDE_3 "filamento" + #define MSG_FILAMENT_CHANGE_RESUME_1 "Agarde para" + #define MSG_FILAMENT_CHANGE_RESUME_2 "seguir co" + #define MSG_FILAMENT_CHANGE_RESUME_3 "traballo" +#else // LCD_HEIGHT < 4 + #define MSG_FILAMENT_CHANGE_INIT_1 "Agarde..." + #define MSG_FILAMENT_CHANGE_UNLOAD_1 "Descargando..." + #define MSG_FILAMENT_CHANGE_INSERT_1 "Introduza e click" + #define MSG_FILAMENT_CHANGE_LOAD_1 "Cargando..." + #define MSG_FILAMENT_CHANGE_EXTRUDE_1 "Extruindo..." + #define MSG_FILAMENT_CHANGE_RESUME_1 "Seguindo..." +#endif // LCD_HEIGHT < 4 + +#endif // LANGUAGE_GL_H + diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_hr.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_hr.h new file mode 100644 index 00000000..60352150 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_hr.h @@ -0,0 +1,197 @@ +/** + * 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 . + * + */ + +/** + * Croatian (Hrvatski) + * + * LCD Menu Messages + * See also https://github.com/MarlinFirmware/Marlin/wiki/LCD-Language + * + */ +#ifndef LANGUAGE_HR_H +#define LANGUAGE_HR_H + + +// Define SIMULATE_ROMFONT to see what is seen on the character based display defined in Configuration.h +//#define SIMULATE_ROMFONT +#define DISPLAY_CHARSET_ISO10646_1 // use the better font on full graphic displays. + +#define WELCOME_MSG MACHINE_NAME " spreman." +#define MSG_SD_INSERTED "SD kartica umetnuta" +#define MSG_SD_REMOVED "SD kartica uklonjena" +#define MSG_LCD_ENDSTOPS "Endstops" // Max length 8 characters +#define MSG_MAIN "Main" +#define MSG_AUTOSTART "Automatsko pokretanje" +#define MSG_DISABLE_STEPPERS "Ugasi steppere" +#define MSG_AUTO_HOME "Automatski homing" +#define MSG_AUTO_HOME_X "Home-aj X" +#define MSG_AUTO_HOME_Y "Home-aj Y" +#define MSG_AUTO_HOME_Z "Home-aj Z" +#define MSG_LEVEL_BED_HOMING "Home-aj XYZ" +#define MSG_LEVEL_BED_WAITING "Click to Begin" +#define MSG_LEVEL_BED_NEXT_POINT "Sljedeća točka" +#define MSG_LEVEL_BED_DONE "Niveliranje gotovo!" +#define MSG_LEVEL_BED_CANCEL "Otkaži" +#define MSG_SET_HOME_OFFSETS "Postavi home offsete" +#define MSG_HOME_OFFSETS_APPLIED "Offsets postavljeni" +#define MSG_SET_ORIGIN "Postavi ishodište" +#define MSG_PREHEAT_1 "Predgrij PLA" +#define MSG_PREHEAT_1_N MSG_PREHEAT_1 " " +#define MSG_PREHEAT_1_ALL MSG_PREHEAT_1 " Sve" +#define MSG_PREHEAT_1_BEDONLY MSG_PREHEAT_1 " Bed" +#define MSG_PREHEAT_1_SETTINGS MSG_PREHEAT_1 " conf" +#define MSG_PREHEAT_2 "Predgrij ABS" +#define MSG_PREHEAT_2_N MSG_PREHEAT_2 " " +#define MSG_PREHEAT_2_ALL MSG_PREHEAT_2 " Sve" +#define MSG_PREHEAT_2_BEDONLY MSG_PREHEAT_2 " Bed" +#define MSG_PREHEAT_2_SETTINGS MSG_PREHEAT_2 " conf" +#define MSG_H1 "1" +#define MSG_H2 "2" +#define MSG_H3 "3" +#define MSG_H4 "4" +#define MSG_COOLDOWN "Hlađenje" +#define MSG_SWITCH_PS_ON "Uključi napajanje" +#define MSG_SWITCH_PS_OFF "Isključi napajanje" +#define MSG_EXTRUDE "Extrude" +#define MSG_RETRACT "Retract" +#define MSG_MOVE_AXIS "Miči os" +#define MSG_LEVEL_BED "Niveliraj bed" +#define MSG_MOVE_X "Miči X" +#define MSG_MOVE_Y "Miči Y" +#define MSG_MOVE_Z "Miči Z" +#define MSG_MOVE_E "Extruder" +#define MSG_MOVE_E1 "1" +#define MSG_MOVE_E2 "2" +#define MSG_MOVE_E3 "3" +#define MSG_MOVE_E4 "4" +#define MSG_MOVE_01MM "Miči 0.1mm" +#define MSG_MOVE_1MM "Miči 1mm" +#define MSG_MOVE_10MM "Miči 10mm" +#define MSG_SPEED "Brzina" +#define MSG_BED_Z "Bed Z" +#define MSG_NOZZLE "Nozzle" +#define MSG_N1 " 1" +#define MSG_N2 " 2" +#define MSG_N3 " 3" +#define MSG_N4 " 4" +#define MSG_BED "Bed" +#define MSG_FAN_SPEED "Brzina ventilatora" +#define MSG_FLOW "Flow" +#define MSG_CONTROL "Control" +#define MSG_MIN " " LCD_STR_THERMOMETER " Min" +#define MSG_MAX " " LCD_STR_THERMOMETER " Max" +#define MSG_FACTOR " " LCD_STR_THERMOMETER " Fact" +#define MSG_AUTOTEMP "Autotemp" +#define MSG_ON "On " +#define MSG_OFF "Off" +#define MSG_PID_P "PID-P" +#define MSG_PID_I "PID-I" +#define MSG_PID_D "PID-D" +#define MSG_PID_C "PID-C" +#define MSG_E1 " E1" +#define MSG_E2 " E2" +#define MSG_E3 " E3" +#define MSG_E4 " E4" +#define MSG_ACC "Accel" +#define MSG_VXY_JERK "Vxy-jerk" +#define MSG_VZ_JERK "Vz-jerk" +#define MSG_VE_JERK "Ve-jerk" +#define MSG_VMAX "Vmax " +#define MSG_X "X" +#define MSG_Y "Y" +#define MSG_Z "Z" +#define MSG_E "E" +#define MSG_VMIN "Vmin" +#define MSG_VTRAV_MIN "VTrav min" +#define MSG_AMAX "Amax " +#define MSG_A_RETRACT "A-retract" +#define MSG_A_TRAVEL "A-travel" +#define MSG_XSTEPS "Xsteps/mm" +#define MSG_YSTEPS "Ysteps/mm" +#define MSG_ZSTEPS "Zsteps/mm" +#define MSG_ESTEPS "Esteps/mm" +#define MSG_TEMPERATURE "Temperature" +#define MSG_MOTION "Motion" +#define MSG_VOLUMETRIC "Filament" +#define MSG_VOLUMETRIC_ENABLED "E in mm3" +#define MSG_FILAMENT_DIAM "Fil. Dia." +#define MSG_DIAM_E1 " 1" +#define MSG_DIAM_E2 " 2" +#define MSG_DIAM_E3 " 3" +#define MSG_DIAM_E4 " 4" +#define MSG_CONTRAST "Kontrast LCD-a" +#define MSG_STORE_EPROM "Pohrani u memoriju" +#define MSG_LOAD_EPROM "Učitaj memoriju" +#define MSG_RESTORE_FAILSAFE "Učitaj failsafe" +#define MSG_REFRESH "Osvježi" +#define MSG_WATCH "Info screen" +#define MSG_PREPARE "Pripremi" +#define MSG_TUNE "Tune" +#define MSG_PAUSE_PRINT "Pauziraj print" +#define MSG_RESUME_PRINT "Nastavi print" +#define MSG_STOP_PRINT "Zaustavi print" +#define MSG_CARD_MENU "Printaj s SD kartice" +#define MSG_NO_CARD "Nema SD kartice" +#define MSG_DWELL "Sleep..." +#define MSG_USERWAIT "Čekaj korisnika..." +#define MSG_RESUMING "Nastavljam print" +#define MSG_PRINT_ABORTED "Print otkazan" +#define MSG_NO_MOVE "No move." +#define MSG_KILLED "KILLED. " +#define MSG_STOPPED "ZAUSTAVLJEN. " +#define MSG_CONTROL_RETRACT "Retract mm" +#define MSG_CONTROL_RETRACT_SWAP "Swap Re.mm" +#define MSG_CONTROL_RETRACTF "Retract V" +#define MSG_CONTROL_RETRACT_ZLIFT "Hop mm" +#define MSG_CONTROL_RETRACT_RECOVER "UnRet +mm" +#define MSG_CONTROL_RETRACT_RECOVER_SWAP "S UnRet+mm" +#define MSG_CONTROL_RETRACT_RECOVERF "UnRet V" +#define MSG_AUTORETRACT "AutoRetr." +#define MSG_FILAMENTCHANGE "Promijeni filament" +#define MSG_INIT_SDCARD "Init. SD karticu" +#define MSG_CNG_SDCARD "Promijeni SD karticu" +#define MSG_ZPROBE_OUT "Z probe out. bed" +#define MSG_HOME "Home" // Used as MSG_HOME " " MSG_X MSG_Y MSG_Z " " MSG_FIRST +#define MSG_FIRST "first" +#define MSG_ZPROBE_ZOFFSET "Z Offset" +#define MSG_BABYSTEP_X "Babystep X" +#define MSG_BABYSTEP_Y "Babystep Y" +#define MSG_BABYSTEP_Z "Babystep Z" +#define MSG_ENDSTOP_ABORT "Endstop abort" +#define MSG_HEATING_FAILED_LCD "Heating failed" +#define MSG_ERR_REDUNDANT_TEMP "Err: REDUNDANT TEMP" +#define MSG_THERMAL_RUNAWAY "THERMAL RUNAWAY" +#define MSG_ERR_MAXTEMP "Err: MAXTEMP" +#define MSG_ERR_MINTEMP "Err: MINTEMP" +#define MSG_ERR_MAXTEMP_BED "Err: MAXTEMP BED" +#define MSG_ERR_MINTEMP_BED "Err: MINTEMP BED" +#define MSG_HEATING "Grijanje..." +#define MSG_HEATING_COMPLETE "Grijanje gotovo." +#define MSG_BED_HEATING "Grijanje Bed-a." +#define MSG_BED_DONE "Bed gotov." +#define MSG_DELTA_CALIBRATE "Delta Kalibracija" +#define MSG_DELTA_CALIBRATE_X "Kalibriraj X" +#define MSG_DELTA_CALIBRATE_Y "Kalibriraj Y" +#define MSG_DELTA_CALIBRATE_Z "Kalibriraj Z" +#define MSG_DELTA_CALIBRATE_CENTER "Kalibriraj Središte" + +#endif // LANGUAGE_HR_H diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_it.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_it.h new file mode 100644 index 00000000..047272bc --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_it.h @@ -0,0 +1,238 @@ +/** + * 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 . + * + */ + +/** + * Italian + * + * LCD Menu Messages + * See also https://github.com/MarlinFirmware/Marlin/wiki/LCD-Language + * + */ +#ifndef LANGUAGE_IT_H +#define LANGUAGE_IT_H + +// Define SIMULATE_ROMFONT to see what is seen on the character based display defined in Configuration.h +//#define SIMULATE_ROMFONT +#define DISPLAY_CHARSET_ISO10646_1 + +#define WELCOME_MSG MACHINE_NAME " pronto." +#define MSG_SD_INSERTED "SD Card inserita" +#define MSG_SD_REMOVED "SD Card rimossa" +#define MSG_LCD_ENDSTOPS "Endstop" +#define MSG_MAIN "Menu principale" +#define MSG_AUTOSTART "Autostart" +#define MSG_DISABLE_STEPPERS "Disabilita Motori" +#define MSG_AUTO_HOME "Auto Home" +#define MSG_AUTO_HOME_X "Home asse X" +#define MSG_AUTO_HOME_Y "Home asse Y" +#define MSG_AUTO_HOME_Z "Home asse Z" +#define MSG_LEVEL_BED_HOMING "Home assi XYZ" +#define MSG_LEVEL_BED_WAITING "Premi per Iniziare" +#define MSG_LEVEL_BED_NEXT_POINT "Punto successivo" +#define MSG_LEVEL_BED_DONE "Livel. terminato!" +#define MSG_LEVEL_BED_CANCEL "Annulla" +#define MSG_SET_HOME_OFFSETS "Imp. offset home" +#define MSG_HOME_OFFSETS_APPLIED "Offset applicato" +#define MSG_SET_ORIGIN "Imposta Origine" +#define MSG_PREHEAT_1 "Preriscalda PLA" +#define MSG_PREHEAT_1_N MSG_PREHEAT_1 " " +#define MSG_PREHEAT_1_ALL MSG_PREHEAT_1 " Tutto" +#define MSG_PREHEAT_1_BEDONLY MSG_PREHEAT_1 " Piatto" +#define MSG_PREHEAT_1_SETTINGS MSG_PREHEAT_1 " conf" +#define MSG_PREHEAT_2 "Preriscalda ABS" +#define MSG_PREHEAT_2_N MSG_PREHEAT_2 " " +#define MSG_PREHEAT_2_ALL MSG_PREHEAT_2 " Tutto" +#define MSG_PREHEAT_2_BEDONLY MSG_PREHEAT_2 " Piatto" +#define MSG_PREHEAT_2_SETTINGS MSG_PREHEAT_2 " conf" +#define MSG_COOLDOWN "Raffredda" +#define MSG_SWITCH_PS_ON "Accendi aliment." +#define MSG_SWITCH_PS_OFF "Spegni aliment." +#define MSG_EXTRUDE "Estrudi" +#define MSG_RETRACT "Ritrai" +#define MSG_MOVE_AXIS "Muovi Asse" +#define MSG_LEVEL_BED "Livella piano" +#define MSG_MOVE_X "Muovi X" +#define MSG_MOVE_Y "Muovi Y" +#define MSG_MOVE_Z "Muovi Z" +#define MSG_MOVE_E "Estrusore" +#define MSG_MOVE_01MM "Muovi di 0.1mm" +#define MSG_MOVE_1MM "Muovi di 1mm" +#define MSG_MOVE_10MM "Muovi di 10mm" +#define MSG_SPEED "Velocità" +#define MSG_BED_Z "piatto Z" +#define MSG_NOZZLE "Ugello" +#define MSG_BED "Piatto" +#define MSG_FAN_SPEED "Velocità ventola" +#define MSG_FLOW "Flusso" +#define MSG_CONTROL "Controllo" +#define MSG_MIN LCD_STR_THERMOMETER " Min" +#define MSG_MAX LCD_STR_THERMOMETER " Max" +#define MSG_FACTOR LCD_STR_THERMOMETER " Fact" +#define MSG_AUTOTEMP "Autotemp" +#define MSG_ON "On " +#define MSG_OFF "Off" +#define MSG_PID_P "PID-P" +#define MSG_PID_I "PID-I" +#define MSG_PID_D "PID-D" +#define MSG_PID_C "PID-C" +#define MSG_SELECT "Seleziona" +#define MSG_ACC "Accel" +#define MSG_VXY_JERK "Vxy-jerk" +#define MSG_VZ_JERK "Vz-jerk" +#define MSG_VE_JERK "Ve-jerk" +#define MSG_VMAX "Vmax " +#define MSG_X "X" +#define MSG_Y "Y" +#define MSG_Z "Z" +#define MSG_E "E" +#define MSG_VMIN "Vmin" +#define MSG_VTRAV_MIN "VTrav min" +#define MSG_AMAX "Amax " +#define MSG_A_RETRACT "A-retract" +#define MSG_A_TRAVEL "A-Spostamento" +#define MSG_XSTEPS "Xpassi/mm" +#define MSG_YSTEPS "Ypassi/mm" +#define MSG_ZSTEPS "Zpassi/mm" +#define MSG_ESTEPS "Epassi/mm" +#define MSG_TEMPERATURE "Temperatura" +#define MSG_MOTION "Movimento" +#define MSG_VOLUMETRIC "Filamento" +#define MSG_VOLUMETRIC_ENABLED "E in mm3" +#define MSG_FILAMENT_DIAM "Diam. filo" +#define MSG_CONTRAST "Contrasto LCD" +#define MSG_STORE_EPROM "Salva in memoria" +#define MSG_LOAD_EPROM "Carica da memoria" +#define MSG_RESTORE_FAILSAFE "Ripristina imp." +#define MSG_REFRESH "Aggiorna" +#define MSG_WATCH "Guarda" +#define MSG_PREPARE "Prepara" +#define MSG_TUNE "Regola" +#define MSG_PAUSE_PRINT "Pausa" +#define MSG_RESUME_PRINT "Riprendi stampa" +#define MSG_STOP_PRINT "Arresta stampa" +#define MSG_CARD_MENU "Stampa da SD" +#define MSG_NO_CARD "SD non presente" +#define MSG_DWELL "Sospensione..." +#define MSG_USERWAIT "Attendi Utente.." +#define MSG_RESUMING "Riprendi Stampa" +#define MSG_PRINT_ABORTED "Stampa annullata" +#define MSG_NO_MOVE "Nessun Movimento" +#define MSG_KILLED "UCCISO. " +#define MSG_STOPPED "ARRESTATO. " +#define MSG_CONTROL_RETRACT "Ritrai mm" +#define MSG_CONTROL_RETRACT_SWAP "Scamb. Ritrai mm" +#define MSG_CONTROL_RETRACTF "Ritrai V" +#define MSG_CONTROL_RETRACT_ZLIFT "Salta mm" +#define MSG_CONTROL_RETRACT_RECOVER "UnRet +mm" +#define MSG_CONTROL_RETRACT_RECOVER_SWAP "Scamb. UnRet+mm" +#define MSG_CONTROL_RETRACT_RECOVERF "UnRet V" +#define MSG_AUTORETRACT "AutoRitrai" +#define MSG_FILAMENTCHANGE "Cambia filamento" +#define MSG_INIT_SDCARD "Iniz. SD-Card" +#define MSG_CNG_SDCARD "Cambia SD-Card" +#define MSG_ZPROBE_OUT "Z probe out. bed" +#define MSG_HOME "Home" // Used as MSG_HOME " " MSG_X MSG_Y MSG_Z " " MSG_FIRST +#define MSG_FIRST "first" +#define MSG_ZPROBE_ZOFFSET "Z Offset" +#define MSG_BABYSTEP_X "Babystep X" +#define MSG_BABYSTEP_Y "Babystep Y" +#define MSG_BABYSTEP_Z "Babystep Z" +#define MSG_ENDSTOP_ABORT "Finecorsa abort" +#define MSG_HEATING_FAILED_LCD "Riscald. Fallito" +#define MSG_ERR_REDUNDANT_TEMP "Err: TEMP RIDONDANTI" +#define MSG_THERMAL_RUNAWAY "TEMP FUORI CONTROLLO" +#define MSG_ERR_MAXTEMP "Err: TEMP MASSIMA" +#define MSG_ERR_MINTEMP "Err: TEMP MINIMA" +#define MSG_ERR_MAXTEMP_BED "Err: TEMP MASSIMA PIATTO" +#define MSG_ERR_MINTEMP_BED "Err: TEMP MINIMA PIATTO" +#define MSG_HALTED "STAMPANTE FERMATA" +#define MSG_PLEASE_RESET "Riavviare prego" +#define MSG_SHORT_DAY "g" // One character only +#define MSG_SHORT_HOUR "h" // One character only +#define MSG_SHORT_MINUTE "m" // One character only +#define MSG_HEATING "Riscaldamento.." +#define MSG_HEATING_COMPLETE "Risc. completato" +#define MSG_BED_HEATING "Risc. Piatto.." +#define MSG_BED_DONE "Piatto Pronto" +#define MSG_DELTA_CALIBRATE "Calibraz. Delta" +#define MSG_DELTA_CALIBRATE_X "Calibra X" +#define MSG_DELTA_CALIBRATE_Y "Calibra Y" +#define MSG_DELTA_CALIBRATE_Z "Calibra Z" +#define MSG_DELTA_CALIBRATE_CENTER "Calibra Center" +#define MSG_INFO_MENU "Riguardo stampante" +#define MSG_INFO_PRINTER_MENU "Info. stampante" +#define MSG_INFO_STATS_MENU "Statistiche" +#define MSG_INFO_BOARD_MENU "Info. scheda" +#define MSG_INFO_THERMISTOR_MENU "Termistori" +#define MSG_INFO_EXTRUDERS "Estrusori" +#define MSG_INFO_BAUDRATE "Baud" +#define MSG_INFO_PROTOCOL "Protocollo" +#if LCD_WIDTH > 19 + #define MSG_INFO_PRINT_COUNT "Contat. stampa" + #define MSG_INFO_COMPLETED_PRINTS "Completati" + #define MSG_INFO_PRINT_TIME "Tempo totale" + #define MSG_INFO_PRINT_LONGEST "Lavoro piu lungo" + #define MSG_INFO_PRINT_FILAMENT "Totale estruso" +#else + #define MSG_INFO_PRINT_COUNT "Stampe" + #define MSG_INFO_COMPLETED_PRINTS "Completati" + #define MSG_INFO_PRINT_TIME "Durata" + #define MSG_INFO_PRINT_LONGEST "Piu lungo" + #define MSG_INFO_PRINT_FILAMENT "Estruso" +#endif +#define MSG_INFO_MIN_TEMP "Temp min" +#define MSG_INFO_MAX_TEMP "Temp max" +#define MSG_INFO_PSU "Alimentatore" + +#define MSG_FILAMENT_CHANGE_HEADER "CAMBIA FILAMENTO" +#define MSG_FILAMENT_CHANGE_OPTION_HEADER "CAMBIA OPZIONI:" +#define MSG_FILAMENT_CHANGE_OPTION_EXTRUDE "Estrusione" +#define MSG_FILAMENT_CHANGE_OPTION_RESUME "Riprendi stampa" +#if LCD_HEIGHT >= 4 + #define MSG_FILAMENT_CHANGE_INIT_1 "Attendere avvio" + #define MSG_FILAMENT_CHANGE_INIT_2 "del cambio" + #define MSG_FILAMENT_CHANGE_INIT_3 "di filamento" + #define MSG_FILAMENT_CHANGE_UNLOAD_1 "Attendere" + #define MSG_FILAMENT_CHANGE_UNLOAD_2 "l'espulsione" + #define MSG_FILAMENT_CHANGE_UNLOAD_3 "del filamento" + #define MSG_FILAMENT_CHANGE_INSERT_1 "Inserisci il" + #define MSG_FILAMENT_CHANGE_INSERT_2 "filamento e" + #define MSG_FILAMENT_CHANGE_INSERT_3 "premi per cont" + #define MSG_FILAMENT_CHANGE_LOAD_1 "Attendere" + #define MSG_FILAMENT_CHANGE_LOAD_2 "il caricamento" + #define MSG_FILAMENT_CHANGE_LOAD_3 "del filamento" + #define MSG_FILAMENT_CHANGE_EXTRUDE_1 "Attendere" + #define MSG_FILAMENT_CHANGE_EXTRUDE_2 "l'estrusione" + #define MSG_FILAMENT_CHANGE_EXTRUDE_3 "del filamento" + #define MSG_FILAMENT_CHANGE_RESUME_1 "Attendere" + #define MSG_FILAMENT_CHANGE_RESUME_2 "la ripresa" + #define MSG_FILAMENT_CHANGE_RESUME_3 "della stampa" +#else // LCD_HEIGHT < 4 + #define MSG_FILAMENT_CHANGE_INIT_1 "Attendere..." + #define MSG_FILAMENT_CHANGE_UNLOAD_1 "Espulsione..." + #define MSG_FILAMENT_CHANGE_INSERT_1 "Inserisci e premi" + #define MSG_FILAMENT_CHANGE_LOAD_1 "Caricamento..." + #define MSG_FILAMENT_CHANGE_EXTRUDE_1 "Estrusione..." + #define MSG_FILAMENT_CHANGE_RESUME_1 "Ripresa..." +#endif // LCD_HEIGHT < 4 + +#endif // LANGUAGE_IT_H diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_kana.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_kana.h new file mode 100644 index 00000000..67136e29 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_kana.h @@ -0,0 +1,292 @@ +/** + * 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 . + * + */ + +/** + * Japanese (Kana) + * + * LCD Menu Messages + * See also https://github.com/MarlinFirmware/Marlin/wiki/LCD-Language + * + */ + +#ifndef LANGUAGE_KANA_H +#define LANGUAGE_KANA_H + +// Define SIMULATE_ROMFONT to see what is seen on the character based display defined in Configuration.h +#define SIMULATE_ROMFONT +#define DISPLAY_CHARSET_ISO10646_KANA + +// 片仮名表示定義 +#define WELCOME_MSG MACHINE_NAME " ready." +#define MSG_SD_INSERTED "\xb6\xb0\xc4\xde\xb6\xde\xbf\xb3\xc6\xad\xb3\xbb\xda\xcf\xbc\xc0" // "カードガソウニュウサレマシタ" ("Card inserted") +#define MSG_SD_REMOVED "\xb6\xb0\xc4\xde\xb6\xde\xb1\xd8\xcf\xbe\xdd" // "カードガアリマセン" ("Card removed") +#define MSG_LCD_ENDSTOPS "Endstops" // Max length 8 characters +#define MSG_MAIN "\xd2\xb2\xdd" // "メイン" ("Main") +#define MSG_AUTOSTART "\xbc\xde\xc4\xde\xb3\xb6\xb2\xbc" // "ジドウカイシ" ("Autostart") +#define MSG_DISABLE_STEPPERS "\xd3\xb0\xc0\xb0\xc3\xde\xdd\xb9\xde\xdd\x20\xb5\xcc" // "モーターデンゲン オフ" ("Disable steppers") +#define MSG_AUTO_HOME "\xb9\xde\xdd\xc3\xdd\xcc\xaf\xb7" // "ゲンテンフッキ" ("Auto home") +#define MSG_AUTO_HOME_X "X\xbc\xde\xb8\x20\xb9\xde\xdd\xc3\xdd\xcc\xaf\xb7" // "Xジク ゲンテンフッキ" ("Home X") +#define MSG_AUTO_HOME_Y "Y\xbc\xde\xb8\x20\xb9\xde\xdd\xc3\xdd\xcc\xaf\xb7" // "Yジク ゲンテンフッキ" ("Home Y") +#define MSG_AUTO_HOME_Z "Z\xbc\xde\xb8\x20\xb9\xde\xdd\xc3\xdd\xcc\xaf\xb7" // "Zジク ゲンテンフッキ" ("Home Z") +#define MSG_LEVEL_BED_HOMING "\xb9\xde\xdd\xc3\xdd\xcc\xaf\xb7\xc1\xad\xb3" // "ゲンテンフッキチュウ" ("Homing XYZ") +#define MSG_LEVEL_BED_WAITING "\xda\xcd\xde\xd8\xdd\xb8\xde\xb6\xb2\xbc" // "レベリングカイシ" ("Click to Begin") +#define MSG_LEVEL_BED_NEXT_POINT "\xc2\xb7\xde\xc9\xbf\xb8\xc3\xb2\xc3\xdd\xcd" // "ツギノソクテイテンヘ" ("Next Point") +#define MSG_LEVEL_BED_DONE "\xda\xcd\xde\xd8\xdd\xb8\xde\xb6\xdd\xd8\xae\xb3" // "レベリングカンリョウ" ("Leveling Done!") +#define MSG_LEVEL_BED_CANCEL "\xc4\xd8\xd4\xd2" // "トリヤメ" ("Cancel") +#define MSG_SET_HOME_OFFSETS "\xb7\xbc\xde\xad\xdd\xb5\xcc\xbe\xaf\xc4\xbe\xaf\xc3\xb2" // "キジュンオフセットセッテイ" ("Set home offsets") +#define MSG_HOME_OFFSETS_APPLIED "\xb5\xcc\xbe\xaf\xc4\xb6\xde\xc3\xb7\xd6\xb3\xbb\xda\xcf\xbc\xc0" // "オフセットガテキヨウサレマシタ" ("Offsets applied") +#define MSG_SET_ORIGIN "\xb7\xbc\xde\xad\xdd\xbe\xaf\xc4" // "キジュンセット" ("Set origin") +#define MSG_PREHEAT_1 "PLA \xd6\xc8\xc2" // "PLA ヨネツ" ("Preheat PLA") +#define MSG_PREHEAT_1_N MSG_PREHEAT_1 " " +#define MSG_PREHEAT_1_ALL "PLA \xbd\xcd\xde\xc3\xd6\xc8\xc2" // "PLA スベテヨネツ" (" All") +#define MSG_PREHEAT_1_BEDONLY "PLA \xcd\xde\xaf\xc4\xde\xd6\xc8\xc2" // "PLA ベッドヨネツ" (" Bed") +#define MSG_PREHEAT_1_SETTINGS MSG_PREHEAT_1 "\xbe\xaf\xc3\xb2" // "セッテイ" (" conf") +#define MSG_PREHEAT_2 "ABS \xd6\xc8\xc2" // "ABS ヨネツ" ("Preheat ABS") +#define MSG_PREHEAT_2_N MSG_PREHEAT_2 " " +#define MSG_PREHEAT_2_ALL "ABS \xbd\xcd\xde\xc3\xd6\xc8\xc2" // "ABS スベテヨネツ" (" All") +#define MSG_PREHEAT_2_BEDONLY "ABS \xcd\xde\xaf\xc4\xde\xd6\xc8\xc2" // "ABS ベッドヨネツ" (" Bed") +#define MSG_PREHEAT_2_SETTINGS MSG_PREHEAT_2 "\xbe\xaf\xc3\xb2" // "セッテイ" (" conf") +#define MSG_COOLDOWN "\xb6\xc8\xc2\xc3\xb2\xbc" // "カネツテイシ" ("Cooldown") +#define MSG_SWITCH_PS_ON "\xc3\xde\xdd\xb9\xde\xdd\x20\xb5\xdd" // "デンゲン オン" ("Switch power on") +#define MSG_SWITCH_PS_OFF "\xc3\xde\xdd\xb9\xde\xdd\x20\xb5\xcc" // "デンゲン オフ" ("Switch power off") +#define MSG_EXTRUDE "\xb5\xbc\xc0\xde\xbc" // "オシダシ" ("Extrude") +#define MSG_RETRACT "\xcb\xb7\xba\xd0\xbe\xaf\xc3\xb2" // "ヒキコミセッテイ" ("Retract") +#define MSG_MOVE_AXIS "\xbc\xde\xb8\xb2\xc4\xde\xb3" // "ジクイドウ" ("Move axis") +#define MSG_LEVEL_BED "\xcd\xde\xaf\xc4\xde\xda\xcd\xde\xd8\xdd\xb8\xde" // "ベッドレベリング" ("Level bed") +#define MSG_MOVE_X "X\xbc\xde\xb8\x20\xb2\xc4\xde\xb3" // "Xジク イドウ" ("Move X") +#define MSG_MOVE_Y "Y\xbc\xde\xb8\x20\xb2\xc4\xde\xb3" // "Yジク イドウ" ("Move Y") +#define MSG_MOVE_Z "Z\xbc\xde\xb8\x20\xb2\xc4\xde\xb3" // "Zジク イドウ" ("Move Z") +#define MSG_MOVE_E "\xb4\xb8\xbd\xc4\xd9\xb0\xc0\xde\xb0" // "エクストルーダー" ("Extruder") +#define MSG_MOVE_01MM "0.1mm \xb2\xc4\xde\xb3" // "0.1mm イドウ" ("Move 0.1mm") +#define MSG_MOVE_1MM " 1mm \xb2\xc4\xde\xb3" // " 1mm イドウ" ("Move 1mm") +#define MSG_MOVE_10MM " 10mm \xb2\xc4\xde\xb3" // " 10mm イドウ" ("Move 10mm") +#define MSG_SPEED "\xbf\xb8\xc4\xde" // "ソクド" ("Speed") +#define MSG_BED_Z "Z\xb5\xcc\xbe\xaf\xc4" // "Zオフセット" ("Bed Z") +#define MSG_NOZZLE "\xc9\xbd\xde\xd9" // "ノズル" ("Nozzle") +#define MSG_BED "\xcd\xde\xaf\xc4\xde" // "ベッド" ("Bed") +#define MSG_FAN_SPEED "\xcc\xa7\xdd\xbf\xb8\xc4\xde" // "ファンソクド" ("Fan speed") +#define MSG_FLOW "\xc4\xbc\xad\xc2\xd8\xae\xb3" // "トシュツリョウ" ("Flow") +#define MSG_CONTROL "\xbe\xb2\xb7\xde\xae" // "セイギョ" ("Control") +#define MSG_MIN LCD_STR_THERMOMETER " \xbb\xb2\xc3\xb2" // " サイテイ" (" Min") +#define MSG_MAX LCD_STR_THERMOMETER " \xbb\xb2\xba\xb3" // " サイコウ" (" Max") +#define MSG_FACTOR LCD_STR_THERMOMETER " \xcc\xa7\xb8\xc0\xb0" // " ファクター" (" Fact") +#if LCD_WIDTH > 19 + #define MSG_AUTOTEMP "\xbc\xde\xc4\xde\xb3\xb5\xdd\xc4\xde\xbe\xb2\xb7\xde\xae" // "ジドウオンドセイギョ" ("Autotemp") +#else + #define MSG_AUTOTEMP "\xbc\xde\xc4\xde\xb3\xb5\xdd\xc4\xde" // "ジドウオンド" ("Autotemp") +#endif +#define MSG_ON "\xb5\xdd " // "オン " ("On ") +#define MSG_OFF "\xb5\xcc " // "オフ " ("Off") +#define MSG_PID_P "PID-P" +#define MSG_PID_I "PID-I" +#define MSG_PID_D "PID-D" +#define MSG_PID_C "PID-C" +#define MSG_SELECT "\xbe\xdd\xc0\xb8" // "センタク" ("Select") +#if LCD_WIDTH > 19 + #define MSG_ACC "\xb6\xbf\xb8\xc4\xde mm/s2" // "カソクド mm/s2" ("Accel") + #define MSG_VXY_JERK "XY\xbc\xde\xb8\x20\xd4\xb8\xc4\xde mm/s" // "XYジク ヤクド mm/s" ("Vxy-jerk") + #define MSG_VZ_JERK "Z\xbc\xde\xb8\x20\xd4\xb8\xc4\xde mm/s" // "Zジク ヤクド mm/s" ("Vz-jerk") + #define MSG_VE_JERK "\xb4\xb8\xbd\xc4\xd9\xb0\xc0\xde\xb0\x20\xd4\xb8\xc4\xde" // "エクストルーダー ヤクド" ("Ve-jerk") + #define MSG_VMAX "\xbb\xb2\xc0\xde\xb2\xb5\xb8\xd8\xbf\xb8\xc4\xde " // "サイダイオクリソクド " ("Vmax ") +#else + #define MSG_ACC "\xb6\xbf\xb8\xc4\xde" // "カソクド" ("Accel") + #define MSG_VXY_JERK "XY\xbc\xde\xb8\x20\xd4\xb8\xc4\xde" // "XYジク ヤクド" ("Vxy-jerk") + #define MSG_VZ_JERK "Z\xbc\xde\xb8\x20\xd4\xb8\xc4\xde" // "Zジク ヤクド" ("Vz-jerk") + #define MSG_VE_JERK "E\x20\xd4\xb8\xc4\xde" // "E ヤクド" ("Ve-jerk") + #define MSG_VMAX "max\xb5\xb8\xd8\xbf\xb8\xc4\xde " // "maxオクリソクド" ("Vmax ") +#endif +#define MSG_X "X" +#define MSG_Y "Y" +#define MSG_Z "Z" +#define MSG_E "E" +#if LCD_WIDTH > 19 + #define MSG_VMIN "\xbb\xb2\xbc\xae\xb3\xb5\xb8\xd8\xbf\xb8\xc4\xde" // "サイショウオクリソクド" ("Vmin") + #define MSG_VTRAV_MIN "\xbb\xb2\xbc\xae\xb3\xb2\xc4\xde\xb3\xbf\xb8\xc4\xde" // "サイショウイドウソクド" ("VTrav min") + #define MSG_AMAX "\xbb\xb2\xc0\xde\xb2\xb6\xbf\xb8\xc4\xde " // "サイダイカソクド " ("Amax ") +#else + #define MSG_VMIN "min\xb5\xb8\xd8\xbf\xb8\xc4\xde" // "minオクリソクド" ("Vmin") + #define MSG_VTRAV_MIN "min\xb2\xc4\xde\xb3\xbf\xb8\xc4\xde" // "minイドウソクド" ("VTrav min") + #define MSG_AMAX "max\xb6\xbf\xb8 " // "maxカソク " ("Amax ") +#endif +#define MSG_A_RETRACT "\xcb\xb7\xba\xd0\xb6\xbf\xb8\xc4\xde" // "ヒキコミカソクド" ("A-retract") +#define MSG_A_TRAVEL "\xb2\xc4\xde\xb3\xb6\xbf\xb8\xc4\xde" // "イドウカソクド" ("A-travel") +#define MSG_XSTEPS "Xsteps/mm" +#define MSG_YSTEPS "Ysteps/mm" +#define MSG_ZSTEPS "Zsteps/mm" +#define MSG_ESTEPS "Esteps/mm" +#define MSG_TEMPERATURE "\xb5\xdd\xc4\xde" // "オンド" ("Temperature") +#define MSG_MOTION "\xb3\xba\xde\xb7\xbe\xaf\xc3\xb2" // "ウゴキセッテイ" ("Motion") +#define MSG_VOLUMETRIC "\xcc\xa8\xd7\xd2\xdd\xc4" // "フィラメント" ("Filament") +#define MSG_VOLUMETRIC_ENABLED "E in mm3" +#if LCD_WIDTH > 19 + #define MSG_FILAMENT_DIAM "\xcc\xa8\xd7\xd2\xdd\xc4\xc1\xae\xaf\xb9\xb2" // "フィラメントチョッケイ" ("Fil. Dia.") +#else + #define MSG_FILAMENT_DIAM "\xcc\xa8\xd7\xd2\xdd\xc4\xb9\xb2" // "フィラメントケイ" ("Fil. Dia.") +#endif +#define MSG_CONTRAST "LCD\xba\xdd\xc4\xd7\xbd\xc4" // "LCDコントラスト" ("LCD contrast") +#define MSG_STORE_EPROM "\xd2\xd3\xd8\xcd\xb6\xb8\xc9\xb3" // "メモリヘカクノウ" ("Store memory") +#define MSG_LOAD_EPROM "\xd2\xd3\xd8\xb6\xd7\xd6\xd0\xba\xd0" // "メモリカラヨミコミ" ("Load memory") +#define MSG_RESTORE_FAILSAFE "\xbe\xaf\xc3\xb2\xd8\xbe\xaf\xc4" // "セッテイリセット" ("Restore failsafe") +#define MSG_REFRESH "\xd8\xcc\xda\xaf\xbc\xad" // "リフレッシュ" ("Refresh") +#define MSG_WATCH "\xbc\xde\xae\xb3\xce\xb3\xb6\xde\xd2\xdd" // "ジョウホウガメン" ("Info screen") +#define MSG_PREPARE "\xbc\xde\xad\xdd\xcb\xde\xbe\xaf\xc3\xb2" // "ジュンビセッテイ" ("Prepare") +#define MSG_TUNE "\xc1\xae\xb3\xbe\xb2" // "チョウセイ" ("Tune") +#define MSG_PAUSE_PRINT "\xb2\xc1\xbc\xde\xc3\xb2\xbc" // "イチジテイシ" ("Pause print") +#define MSG_RESUME_PRINT "\xcc\xdf\xd8\xdd\xc4\xbb\xb2\xb6\xb2" // "プリントサイカイ" ("Resume print") +#define MSG_STOP_PRINT "\xcc\xdf\xd8\xdd\xc4\xc3\xb2\xbc" // "プリントテイシ" ("Stop print") +#define MSG_CARD_MENU "SD\xb6\xb0\xc4\xde\xb6\xd7\xcc\xdf\xd8\xdd\xc4" // "SDカードカラプリント" ("Print from SD") +#define MSG_NO_CARD "SD\xb6\xb0\xc4\xde\xb6\xde\xb1\xd8\xcf\xbe\xdd" // "SDカードガアリマセン" ("No SD card") +#define MSG_DWELL "\xb7\xad\xb3\xbc" // "キュウシ" ("Sleep...") +#define MSG_USERWAIT "\xbc\xca\xde\xd7\xb8\xb5\xcf\xc1\xb8\xc0\xde\xbb\xb2" // "シバラクオマチクダサイ" ("Wait for user...") +#define MSG_RESUMING "\xcc\xdf\xd8\xdd\xc4\xbb\xb2\xb6\xb2" // "プリントサイカイ" ("Resuming print") +#define MSG_PRINT_ABORTED "\xcc\xdf\xd8\xdd\xc4\xb6\xde\xc1\xad\xb3\xbc\xbb\xda\xcf\xbc\xc0" // "プリントガチュウシサレマシタ" ("Print aborted") +#define MSG_NO_MOVE "\xb3\xba\xde\xb7\xcf\xbe\xdd" // "ウゴキマセン" ("No move.") +#define MSG_KILLED "\xcb\xbc\xde\xae\xb3\xc3\xb2\xbc" // "ヒジョウテイシ" ("KILLED. ") +#define MSG_STOPPED "\xc3\xb2\xbc\xbc\xcf\xbc\xc0" // "テイシシマシタ" ("STOPPED. ") +#if LCD_WIDTH > 19 + #define MSG_CONTROL_RETRACT "\xcb\xb7\xba\xd0\xd8\xae\xb3 mm" // "ヒキコミリョウ mm" ("Retract mm") + #define MSG_CONTROL_RETRACT_SWAP "\xcb\xb7\xba\xd0\xd8\xae\xb3S mm" // "ヒキコミリョウS mm" ("Swap Re.mm") + #define MSG_CONTROL_RETRACTF "\xcb\xb7\xba\xd0\xbf\xb8\xc4\xde mm/s" // "ヒキコミソクド mm/s" ("Retract V") + #define MSG_CONTROL_RETRACT_ZLIFT "\xc9\xbd\xde\xd9\xc0\xb2\xcb mm" // "ノズルタイヒ mm" ("Hop mm") + #define MSG_CONTROL_RETRACT_RECOVER "\xce\xbc\xae\xb3\xd8\xae\xb3 mm" // "ホショウリョウ mm" ("UnRet +mm") + #define MSG_CONTROL_RETRACT_RECOVER_SWAP "\xce\xbc\xae\xb3\xd8\xae\xb3S mm" // "ホショウリョウS mm" ("S UnRet+mm") + #define MSG_CONTROL_RETRACT_RECOVERF "\xce\xbc\xae\xb3\xbf\xb8\xc4\xde mm/s" // "ホショウソクド mm/s" ("UnRet V") +#else + #define MSG_CONTROL_RETRACT "\xcb\xb7\xba\xd0\xd8\xae\xb3" // "ヒキコミリョウ" ("Retract mm") + #define MSG_CONTROL_RETRACT_SWAP "\xcb\xb7\xba\xd0\xd8\xae\xb3S" // "ヒキコミリョウS" ("Swap Re.mm") + #define MSG_CONTROL_RETRACTF "\xcb\xb7\xba\xd0\xbf\xb8\xc4\xde" // "ヒキコミソクド" ("Retract V") + #define MSG_CONTROL_RETRACT_ZLIFT "\xc9\xbd\xde\xd9\xc0\xb2\xcb" // "ノズルタイヒ" ("Hop mm") + #define MSG_CONTROL_RETRACT_RECOVER "\xce\xbc\xae\xb3\xd8\xae\xb3" // "ホショウリョウ" ("UnRet +mm") + #define MSG_CONTROL_RETRACT_RECOVER_SWAP "\xce\xbc\xae\xb3\xd8\xae\xb3S" // "ホショウリョウS" ("S UnRet+mm") + #define MSG_CONTROL_RETRACT_RECOVERF "\xce\xbc\xae\xb3\xbf\xb8\xc4\xde" // "ホショウソクド" ("UnRet V") +#endif +#define MSG_AUTORETRACT "\xbc\xde\xc4\xde\xb3\xcb\xb7\xba\xd0" // "ジドウヒキコミ" ("AutoRetr.") +#define MSG_FILAMENTCHANGE "\xcc\xa8\xd7\xd2\xdd\xc4\xba\xb3\xb6\xdd" // "フィラメントコウカン" ("Change filament") +#define MSG_INIT_SDCARD "SD\xb6\xb0\xc4\xde\xbb\xb2\xd6\xd0\xba\xd0" // "SDカードサイヨミコミ" ("Init. SD card") +#define MSG_CNG_SDCARD "SD\xb6\xb0\xc4\xde\xba\xb3\xb6\xdd" // "SDカードコウカン" ("Change SD card") +#define MSG_ZPROBE_OUT "Z\xcc\xdf\xdb\xb0\xcc\xde\x20\xcd\xde\xaf\xc4\xde\xb6\xde\xb2" // "Zプローブ ベッドガイ" ("Z probe out. bed") +#define MSG_HOME "\xbb\xb7\xc6" // "サキニ" ("Home") // Used as MSG_HOME " " MSG_X MSG_Y MSG_Z " " MSG_FIRST +#if LCD_WIDTH > 19 + #define MSG_FIRST "\xa6\xcc\xaf\xb7\xbb\xbe\xc3\xb8\xc0\xde\xbb\xb2" // "ヲフッキサセテクダサイ" ("first") +#else + #define MSG_FIRST "\xa6\xcc\xaf\xb7\xbb\xbe\xd6" // "ヲフッキサセヨ" ("first") +#endif +#define MSG_ZPROBE_ZOFFSET "Z\xb5\xcc\xbe\xaf\xc4" // "Zオフセット" ("Z Offset") +#define MSG_BABYSTEP_X "X\xbc\xde\xb8\x20\xcb\xde\xc4\xde\xb3" // "Xジク ビドウ" ("Babystep X") +#define MSG_BABYSTEP_Y "Y\xbc\xde\xb8\x20\xcb\xde\xc4\xde\xb3" // "Yジク ビドウ" ("Babystep Y") +#define MSG_BABYSTEP_Z "Z\xbc\xde\xb8\x20\xcb\xde\xc4\xde\xb3" // "Zジク ビドウ" ("Babystep Z") +#if LCD_WIDTH > 19 + #define MSG_ENDSTOP_ABORT "\xb2\xc4\xde\xb3\xb9\xde\xdd\xb6\xb2\xb9\xdd\xc1\xb7\xc9\xb3" // "イドウゲンカイケンチキノウ" ("Endstop abort") +#else + #define MSG_ENDSTOP_ABORT "\xb2\xc4\xde\xb3\xb9\xde\xdd\xb6\xb2\xb9\xdd\xc1" // "イドウゲンカイケンチ" ("Endstop abort") +#endif +#define MSG_HEATING_FAILED_LCD "\xb6\xc8\xc2\xbc\xaf\xca\xdf\xb2" // "カネツシッパイ" ("Heating failed") +#if LCD_WIDTH > 19 + #define MSG_ERR_REDUNDANT_TEMP "\xb4\xd7\xb0:\xbc\xde\xae\xb3\xc1\xae\xb3\xbb\xb0\xd0\xbd\xc0\xb0\xb7\xc9\xb3" // "エラー:ジョウチョウサーミスターキノウ" ("Err: REDUNDANT TEMP") +#else + #define MSG_ERR_REDUNDANT_TEMP "\xb4\xd7\xb0:\xbc\xde\xae\xb3\xc1\xae\xb3\xbb\xb0\xd0\xbd\xc0" // "エラー:ジョウチョウサーミスタ" ("Err: REDUNDANT TEMP") +#endif +#define MSG_THERMAL_RUNAWAY "\xc8\xc2\xce\xde\xb3\xbf\xb3" // "ネツボウソウ" ("THERMAL RUNAWAY") +#define MSG_ERR_MAXTEMP "\xb4\xd7\xb0:\xbb\xb2\xba\xb3\xb5\xdd\xc1\xae\xb3\xb6" // "エラー:サイコウオンチョウカ" ("Err: MAXTEMP") +#define MSG_ERR_MINTEMP "\xb4\xd7\xb0:\xbb\xb2\xc3\xb2\xb5\xdd\xd0\xcf\xdd" // "エラー:サイテイオンミマン" ("Err: MINTEMP") +#if LCD_WIDTH > 19 + #define MSG_ERR_MAXTEMP_BED "\xb4\xd7\xb0:\xcd\xde\xaf\xc4\xde\x20\xbb\xb2\xba\xb3\xb5\xdd\xc1\xae\xb3\xb6" // "エラー:ベッド サイコウオンチョウカ" ("Err: MAXTEMP BED") + #define MSG_ERR_MINTEMP_BED "\xb4\xd7\xb0:\xcd\xde\xaf\xc4\xde\x20\xbb\xb2\xc3\xb2\xb5\xdd\xd0\xcf\xdd" // "エラー:ベッド サイテイオンミマン" ("Err: MINTEMP BED") +#else + #define MSG_ERR_MAXTEMP_BED "\xb4\xd7\xb0:\xcd\xde\xaf\xc4\xde\x20\xbb\xb2\xba\xb3\xb5\xdd" // "エラー:ベッド サイコウオン" ("Err: MAXTEMP BED") + #define MSG_ERR_MINTEMP_BED "\xb4\xd7\xb0:\xcd\xde\xaf\xc4\xde\x20\xbb\xb2\xc3\xb2\xb5\xdd" // "エラー:ベッド サイテイオン" ("Err: MINTEMP BED") +#endif +#define MSG_HALTED "\xcc\xdf\xd8\xdd\xc0\xb0\xca\xc3\xb2\xbc\xbc\xcf\xbc\xc0" // "プリンターハテイシシマシタ" ("PRINTER HALTED") +#define MSG_PLEASE_RESET "\xd8\xbe\xaf\xc4\xbc\xc3\xb8\xc0\xde\xbb\xb2" // "リセットシテクダサイ" ("Please reset") +#define MSG_SHORT_DAY "d" // One character only +#define MSG_SHORT_HOUR "h" // One character only +#define MSG_SHORT_MINUTE "m" // One character only +#define MSG_HEATING "\xb6\xc8\xc2\xc1\xad\xb3" // "カネツチュウ" ("Heating...") +#define MSG_HEATING_COMPLETE "\xb6\xc8\xc2\xb6\xdd\xd8\xae\xb3" // "カネツカンリョウ" ("Heating done.") +#define MSG_BED_HEATING "\xcd\xde\xaf\xc4\xde\x20\xb6\xc8\xc2\xc1\xad\xb3" // "ベッド カネツチュウ" ("Bed Heating.") +#define MSG_BED_DONE "\xcd\xde\xaf\xc4\xde\x20\xb6\xc8\xc2\xb6\xdd\xd8\xae\xb3" // "ベッド カネツカンリョウ" ("Bed done.") +#define MSG_DELTA_CALIBRATE "\xc3\xde\xd9\xc0\x20\xba\xb3\xbe\xb2" // "デルタ コウセイ" ("Delta Calibration") +#define MSG_DELTA_CALIBRATE_X "X\xbc\xde\xb8\x20\xba\xb3\xbe\xb2" // "Xジク コウセイ" ("Calibrate X") +#define MSG_DELTA_CALIBRATE_Y "Y\xbc\xde\xb8\x20\xba\xb3\xbe\xb2" // "Yジク コウセイ" ("Calibrate Y") +#define MSG_DELTA_CALIBRATE_Z "Z\xbc\xde\xb8\x20\xba\xb3\xbe\xb2" // "Zジク コウセイ" ("Calibrate Z") +#define MSG_DELTA_CALIBRATE_CENTER "\xc1\xad\xb3\xbc\xdd\x20\xba\xb3\xbe\xb2" // "チュウシン コウセイ" ("Calibrate Center") +#define MSG_INFO_MENU "\xba\xc9\xcc\xdf\xd8\xdd\xc0\xb0\xc6\xc2\xb2\xc3" // "コノプリンターニツイテ" ("About Printer") +#define MSG_INFO_PRINTER_MENU "\xcc\xdf\xd8\xdd\xc0\xb0\xbc\xde\xae\xb3\xce\xb3" // "プリンタージョウホウ" ("Printer Info") +#define MSG_INFO_STATS_MENU "\xcc\xdf\xd8\xdd\xc4\xbc\xde\xae\xb3\xb7\xae\xb3" // "プリントジョウキョウ" ("Printer Stats") +#define MSG_INFO_BOARD_MENU "\xbe\xb2\xb7\xde\xae\xb9\xb2\xbc\xde\xae\xb3\xce\xb3" // "セイギョケイジョウホウ" ("Board Info") +#define MSG_INFO_THERMISTOR_MENU "\xbb\xb0\xd0\xbd\xc0\xb0" // "サーミスター" ("Thermistors") +#define MSG_INFO_EXTRUDERS "\xb4\xb8\xbd\xc4\xd9\xb0\xc0\xde\xb0\xbd\xb3" // "エクストルーダースウ" ("Extruders") +#define MSG_INFO_BAUDRATE "\xce\xde\xb0\xda\xb0\xc4" // "ボーレート" ("Baud") +#define MSG_INFO_PROTOCOL "\xcc\xdf\xdb\xc4\xba\xd9" // "プロトコル" ("Protocol") +#define MSG_INFO_PRINT_COUNT "\xcc\xdf\xd8\xdd\xc4\xbd\xb3 " // "プリントスウ " ("Print Count") +#define MSG_INFO_COMPLETED_PRINTS "\xb6\xdd\xd8\xae\xb3\xbd\xb3" // "カンリョウスウ" ("Completed") +#define MSG_INFO_PRINT_TIME "\xcc\xdf\xd8\xdd\xc4\xbc\xde\xb6\xdd\xd9\xb2\xb9\xb2" // "プリントジカンルイケイ" ("Total print time") +#define MSG_INFO_PRINT_LONGEST "\xbb\xb2\xc1\xae\xb3\xcc\xdf\xd8\xdd\xc4\xbc\xde\xb6\xdd" // "サイチョウプリントジカン" ("Longest job time") +#if LCD_WIDTH > 19 + #define MSG_INFO_PRINT_FILAMENT "\xcc\xa8\xd7\xd2\xdd\xc4\xbc\xd6\xb3\xd8\xae\xb3\xd9\xb2\xb9\xb2" // "フィラメントシヨウリョウルイケイ" ("Extruded total") +#else + #define MSG_INFO_PRINT_FILAMENT "\xcc\xa8\xd7\xd2\xdd\xc4\xbf\xb3\xbc\xd6\xb3\xd8\xae\xb3" // "フィラメントソウシヨウリョウ" ("Extruded") +#endif +#define MSG_INFO_MIN_TEMP "\xbe\xaf\xc3\xb2\xbb\xb2\xc3\xb2\xb5\xdd" // "セッテイサイテイオン" ("Min Temp") +#define MSG_INFO_MAX_TEMP "\xbe\xaf\xc3\xb2\xbb\xb2\xba\xb3\xb5\xdd" // "セッテイサイコウオン" ("Max Temp") +#if LCD_WIDTH > 19 + #define MSG_INFO_PSU "\xc3\xde\xdd\xb9\xde\xdd\xbc\xad\xcd\xde\xc2" // "デンゲンシュベツ" ("Power Supply") +#else + #define MSG_INFO_PSU "\xc3\xde\xdd\xb9\xde\xdd" // "デンゲン" ("Power Supply") +#endif +#define MSG_FILAMENT_CHANGE_HEADER "\xcc\xa8\xd7\xd2\xdd\xc4\xba\xb3\xb6\xdd" // "フィラメントコウカン" ("CHANGE FILAMENT") +#define MSG_FILAMENT_CHANGE_OPTION_HEADER "\xc4\xde\xb3\xbb\xa6\xbe\xdd\xc0\xb8\xbc\xc3\xb8\xc0\xde\xbb\xb2" // "ドウサヲセンタクシテクダサイ" ("CHANGE OPTIONS:") +#define MSG_FILAMENT_CHANGE_OPTION_EXTRUDE "\xbb\xd7\xc6\xb5\xbc\xc0\xde\xbd" // "サラニオシダス" ("Extrude more") +#define MSG_FILAMENT_CHANGE_OPTION_RESUME "\xcc\xdf\xd8\xdd\xc4\xbb\xb2\xb6\xb2" // "プリントサイカイ" ("Resume print") +#if LCD_HEIGHT >= 4 + #define MSG_FILAMENT_CHANGE_INIT_1 "\xba\xb3\xb6\xdd\xa6\xb6\xb2\xbc\xbc\xcf\xbd" // "コウカンヲカイシシマス" ("Wait for start") + #define MSG_FILAMENT_CHANGE_INIT_2 "\xbc\xca\xde\xd7\xb8\xb5\xcf\xc1\xb8\xc0\xde\xbb\xb2" // "シバラクオマチクダサイ" ("of the filament") + #define MSG_FILAMENT_CHANGE_INIT_3 "" // "" ("change") + #define MSG_FILAMENT_CHANGE_UNLOAD_1 "\xcc\xa8\xd7\xd2\xdd\xc4\xc7\xb7\xc0\xde\xbc\xc1\xad\xb3" // "フィラメントヌキダシチュウ" ("Wait for") + #define MSG_FILAMENT_CHANGE_UNLOAD_2 "\xbc\xca\xde\xd7\xb8\xb5\xcf\xc1\xb8\xc0\xde\xbb\xb2" // "シバラクオマチクダサイ" ("filament unload") + #define MSG_FILAMENT_CHANGE_UNLOAD_3 "" + #define MSG_FILAMENT_CHANGE_INSERT_1 "\xcc\xa8\xd7\xd2\xdd\xc4\xa6\xbf\xb3\xc6\xad\xb3\xbc," // "フィラメントヲソウニュウシ," ("Insert filament") + #define MSG_FILAMENT_CHANGE_INSERT_2 "\xb8\xd8\xaf\xb8\xbd\xd9\xc4\xbf\xde\xaf\xba\xb3\xbc\xcf\xbd" // "クリックスルトゾッコウシマス" ("and press button") + #define MSG_FILAMENT_CHANGE_INSERT_3 "" // "" ("to continue...") + #define MSG_FILAMENT_CHANGE_LOAD_1 "\xcc\xa8\xd7\xd2\xdd\xc4\xbf\xb3\xc3\xdd\xc1\xad\xb3" // "フィラメントソウテンチュウ" ("Wait for") + #define MSG_FILAMENT_CHANGE_LOAD_2 "\xbc\xca\xde\xd7\xb8\xb5\xcf\xc1\xb8\xc0\xde\xbb\xb2" // "シバラクオマチクダサイ" ("filament load") + #define MSG_FILAMENT_CHANGE_LOAD_3 "" + #define MSG_FILAMENT_CHANGE_EXTRUDE_1 "\xcc\xa8\xd7\xd2\xdd\xc4\xb5\xbc\xc0\xde\xbc\xc1\xad\xb3" // "フィラメントオシダシチュウ" ("Wait for") + #define MSG_FILAMENT_CHANGE_EXTRUDE_2 "\xbc\xca\xde\xd7\xb8\xb5\xcf\xc1\xb8\xc0\xde\xbb\xb2" // "シバラクオマチクダサイ" ("filament extrude") + #define MSG_FILAMENT_CHANGE_EXTRUDE_3 "" + #define MSG_FILAMENT_CHANGE_RESUME_1 "\xcc\xdf\xd8\xdd\xc4\xa6\xbb\xb2\xb6\xb2\xbc\xcf\xbd" // "プリントヲサイカイシマス" ("Wait for print") + #define MSG_FILAMENT_CHANGE_RESUME_2 "\xbc\xca\xde\xd7\xb8\xb5\xcf\xc1\xb8\xc0\xde\xbb\xb2" // "シバラクオマチクダサイ" ("to resume") + #define MSG_FILAMENT_CHANGE_RESUME_3 "" +#else // LCD_HEIGHT < 4 + #define MSG_FILAMENT_CHANGE_INIT_1 "\xba\xb3\xb6\xdd\xa6\xb6\xb2\xbc\xbc\xcf\xbd" // "コウカンヲカイシシマス" ("Please wait...") + #define MSG_FILAMENT_CHANGE_UNLOAD_1 "\xcc\xa8\xd7\xd2\xdd\xc4\xc7\xb7\xc0\xde\xbc\xc1\xad\xb3" // "フィラメントヌキダシチュウ" ("Ejecting...") + #if LCD_WIDTH > 19 + #define MSG_FILAMENT_CHANGE_INSERT_1 "\xbf\xb3\xc6\xad\xb3\xbc\x2c\xb8\xd8\xaf\xb8\xbc\xc3\xb8\xc0\xde\xbb\xb2" // "ソウニュウシ,クリックシテクダサイ" ("Insert and Click") + #else + #define MSG_FILAMENT_CHANGE_INSERT_1 "\xbf\xb3\xc6\xad\xb3\xbc\x2c\xb8\xd8\xaf\xb8\xbe\xd6" // "ソウニュウシ,クリックセヨ" ("Insert and Click") + #endif + #define MSG_FILAMENT_CHANGE_LOAD_1 "\xcc\xa8\xd7\xd2\xdd\xc4\xbf\xb3\xc3\xdd\xc1\xad\xb3" // "フィラメントソウテンチュウ" ("Loading...") + #define MSG_FILAMENT_CHANGE_EXTRUDE_1 "\xcc\xa8\xd7\xd2\xdd\xc4\xb5\xbc\xc0\xde\xbc\xc1\xad\xb3" // "フィラメントオシダシチュウ" ("Extruding...") + #define MSG_FILAMENT_CHANGE_RESUME_1 "\xcc\xdf\xd8\xdd\xc4\xa6\xbb\xb2\xb6\xb2\xbc\xcf\xbd" // "プリントヲサイカイシマス" ("Resuming...") +#endif // LCD_HEIGHT < 4 + +#endif // LANGUAGE_KANA_H diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_kana_utf8.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_kana_utf8.h new file mode 100644 index 00000000..3e46f57d --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_kana_utf8.h @@ -0,0 +1,226 @@ +/** + * 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 . + * + */ + +/** + * Japanese (Kana UTF8 version) + * + * LCD Menu Messages + * See also https://github.com/MarlinFirmware/Marlin/wiki/LCD-Language + * + */ + +#ifndef LANGUAGE_KANA_UTF_H +#define LANGUAGE_KANA_UTF_H + +#define MAPPER_E382E383 +// Define SIMULATE_ROMFONT to see what is seen on the character based display defined in Configuration.h +//#define SIMULATE_ROMFONT +#define DISPLAY_CHARSET_ISO10646_KANA + +// This just to show the potential benefit of unicode. +// This translation can be improved by using the full charset of unicode codeblock U+30A0 to U+30FF. + +// 片仮名表示定義 +#define WELCOME_MSG MACHINE_NAME " ready." +#define MSG_SD_INSERTED "カードガソウニュウサレマシタ" // "Card inserted" +#define MSG_SD_REMOVED "カードガアリマセン" // "Card removed" +#define MSG_LCD_ENDSTOPS "エンドストップ" // "Endstops" // Max length 8 characters +#define MSG_MAIN "メイン" // "Main" +#define MSG_AUTOSTART "ジドウカイシ" // "Autostart" +#define MSG_DISABLE_STEPPERS "モーターデンゲン オフ" // "Disable steppers" +#define MSG_AUTO_HOME "ゲンテンフッキ" // "Auto home" +#define MSG_AUTO_HOME_X "Xジク ゲンテンフッキ" // "Home X" +#define MSG_AUTO_HOME_Y "Yジク ゲンテンフッキ" // "Home Y" +#define MSG_AUTO_HOME_Z "Zジク ゲンテンフッキ" // "Home Z" +#define MSG_LEVEL_BED_HOMING "ゲンテンフッキチュウ" // "Homing XYZ" +#define MSG_LEVEL_BED_WAITING "レベリングカイシ" // "Click to Begin" +#define MSG_LEVEL_BED_NEXT_POINT "ツギノソクテイテンヘ" // "Next Point" +#define MSG_LEVEL_BED_DONE "レベリングカンリョウ" // "Leveling Done!" +#define MSG_LEVEL_BED_CANCEL "トリヤメ" // "Cancel" +#define MSG_SET_HOME_OFFSETS "キジュンオフセットセッテイ" // "Set home offsets" +#define MSG_HOME_OFFSETS_APPLIED "オフセットガテキヨウサレマシタ" // "Offsets applied" +#define MSG_SET_ORIGIN "キジュンセット" // "Set origin" +#define MSG_PREHEAT_1 "PLA ヨネツ" // "Preheat PLA" +#define MSG_PREHEAT_1_N MSG_PREHEAT_1 " " +#define MSG_PREHEAT_1_ALL "PLA スベテヨネツ" // " All" +#define MSG_PREHEAT_1_BEDONLY "PLA ベッドヨネツ" // " Bed" +#define MSG_PREHEAT_1_SETTINGS MSG_PREHEAT_1 "セッテイ" // " conf" +#define MSG_PREHEAT_2 "ABS ヨネツ" // "Preheat ABS" +#define MSG_PREHEAT_2_N MSG_PREHEAT_2 " " +#define MSG_PREHEAT_2_ALL "ABS スベテヨネツ" // " All" +#define MSG_PREHEAT_2_BEDONLY "ABS ベッドヨネツ" // " Bed" +#define MSG_PREHEAT_2_SETTINGS MSG_PREHEAT_2 "セッテイ" // " conf" +#define MSG_COOLDOWN "カネツテイシ" // "Cooldown" +#define MSG_SWITCH_PS_ON "デンゲン オン" // "Switch power on" +#define MSG_SWITCH_PS_OFF "デンゲン オフ" // "Switch power off" +#define MSG_EXTRUDE "オシダシ" // "Extrude" +#define MSG_RETRACT "ヒキコミセッテイ" // "Retract" +#define MSG_MOVE_AXIS "ジクイドウ" // "Move axis" +#define MSG_LEVEL_BED "ベッドレベリング" // "Level bed" +#define MSG_MOVE_X "Xジク イドウ" // "Move X" +#define MSG_MOVE_Y "Yジク イドウ" // "Move Y" +#define MSG_MOVE_Z "Zジク イドウ" // "Move Z" +#define MSG_MOVE_E "エクストルーダー" // "Extruder" +#define MSG_MOVE_01MM "0.1mm イドウ" // "Move 0.1mm" +#define MSG_MOVE_1MM " 1mm イドウ" // "Move 1mm" +#define MSG_MOVE_10MM " 10mm イドウ" // "Move 10mm" +#define MSG_SPEED "ソクド" // "Speed" +#define MSG_BED_Z "Zオフセット" // "Bed Z" +#define MSG_NOZZLE "ノズル" // "Nozzle" +#define MSG_BED "ベッド" // "Bed" +#define MSG_FAN_SPEED "ファンソクド" // "Fan speed" +#define MSG_FLOW "トシュツリョウ" // "Flow" +#define MSG_CONTROL "セイギョ" // "Control" +#define MSG_MIN LCD_STR_THERMOMETER " サイテイ" // " Min" +#define MSG_MAX LCD_STR_THERMOMETER " サイコウ" // " Max" +#define MSG_FACTOR LCD_STR_THERMOMETER " ファクター" // " Fact" +#define MSG_AUTOTEMP "ジドウオンドセイギョ" // "Autotemp" +#define MSG_ON "オン " // "On " +#define MSG_OFF "オフ " // "Off" +#define MSG_PID_P "PID-P" +#define MSG_PID_I "PID-I" +#define MSG_PID_D "PID-D" +#define MSG_PID_C "PID-C" +#define MSG_SELECT "センタク" // "Select" +#define MSG_ACC "カソクド mm/s2" // "Accel" +#define MSG_VXY_JERK "XYジク ヤクド mm/s" // "Vxy-jerk" +#define MSG_VZ_JERK "Zジク ヤクド mm/s" // "Vz-jerk" +#define MSG_VE_JERK "エクストルーダー ヤクド" // "Ve-jerk" +#define MSG_VMAX "サイダイオクリソクド " // "Vmax " +#define MSG_X "X" +#define MSG_Y "Y" +#define MSG_Z "Z" +#define MSG_E "E" +#define MSG_VMIN "サイショウオクリソクド" // "Vmin" +#define MSG_VTRAV_MIN "サイショウイドウソクド" // "VTrav min" +#define MSG_AMAX "サイダイカソクド " // "Amax " +#define MSG_A_RETRACT "ヒキコミカソクド" // "A-retract" +#define MSG_A_TRAVEL "イドウカソクド" // "A-travel" +#define MSG_XSTEPS "Xsteps/mm" +#define MSG_YSTEPS "Ysteps/mm" +#define MSG_ZSTEPS "Zsteps/mm" +#define MSG_ESTEPS "Esteps/mm" +#define MSG_TEMPERATURE "オンド" // "Temperature" +#define MSG_MOTION "ウゴキセッテイ" // "Motion" +#define MSG_VOLUMETRIC "フィラメント" // "Filament" +#define MSG_VOLUMETRIC_ENABLED "E in mm3" +#define MSG_FILAMENT_DIAM "フィラメントチョッケイ" // "Fil. Dia." +#define MSG_CONTRAST "LCDコントラスト" // "LCD contrast" +#define MSG_STORE_EPROM "メモリヘカクノウ" // "Store memory" +#define MSG_LOAD_EPROM "メモリカラヨミコミ" // "Load memory" +#define MSG_RESTORE_FAILSAFE "セッテイリセット" // "Restore failsafe" +#define MSG_REFRESH "リフレッシュ" // "Refresh" +#define MSG_WATCH "ジョウホウガメン" // "Info screen" +#define MSG_PREPARE "ジュンビセッテイ" // "Prepare" +#define MSG_TUNE "チョウセイ" // "Tune" +#define MSG_PAUSE_PRINT "イチジテイシ" // "Pause print" +#define MSG_RESUME_PRINT "プリントサイカイ" // "Resume print" +#define MSG_STOP_PRINT "プリントテイシ" // "Stop print" +#define MSG_CARD_MENU "SDカードカラプリント" // "Print from SD" +#define MSG_NO_CARD "SDカードガアリマセン" // "No SD card" +#define MSG_DWELL "キュウシ" // "Sleep..." +#define MSG_USERWAIT "シバラクオマチクダサイ" // "Wait for user..." +#define MSG_RESUMING "プリントサイカイ" // "Resuming print" +#define MSG_PRINT_ABORTED "プリントガチュウシサレマシタ" // "Print aborted" +#define MSG_NO_MOVE "ウゴキマセン" // "No move." +#define MSG_KILLED "ヒジョウテイシ" // "KILLED. " +#define MSG_STOPPED "テイシシマシタ" // "STOPPED. " +#define MSG_CONTROL_RETRACT "ヒキコミリョウ mm" // "Retract mm" +#define MSG_CONTROL_RETRACT_SWAP "ヒキコミリョウS mm" // "Swap Re.mm" +#define MSG_CONTROL_RETRACTF "ヒキコミソクド mm/s" // "Retract V" +#define MSG_CONTROL_RETRACT_ZLIFT "ノズルタイヒ mm" // "Hop mm" +#define MSG_CONTROL_RETRACT_RECOVER "ホショウリョウ mm" // "UnRet +mm" +#define MSG_CONTROL_RETRACT_RECOVER_SWAP "ホショウリョウS mm" // "S UnRet+mm" +#define MSG_CONTROL_RETRACT_RECOVERF "ホショウソクド mm/s" // "UnRet V" +#define MSG_AUTORETRACT "ジドウヒキコミ" // "AutoRetr." +#define MSG_FILAMENTCHANGE "フィラメントコウカン" // "Change filament" +#define MSG_INIT_SDCARD "SDカードサイヨミコミ" // "Init. SD card" +#define MSG_CNG_SDCARD "SDカードコウカン" // "Change SD card" +#define MSG_ZPROBE_OUT "Zプローブ ベッドガイ" // "Z probe out. bed" +#define MSG_HOME "サキニ" // "Home" // Used as MSG_HOME " " MSG_X MSG_Y MSG_Z " " MSG_FIRST +#define MSG_FIRST "ヲフッキサセテクダサイ" // "first" +#define MSG_ZPROBE_ZOFFSET "Zオフセット" // "Z Offset" +#define MSG_BABYSTEP_X "Xジク ビドウ" // "Babystep X" +#define MSG_BABYSTEP_Y "Yジク ビドウ" // "Babystep Y" +#define MSG_BABYSTEP_Z "Zジク ビドウ" // "Babystep Z" +#define MSG_ENDSTOP_ABORT "イドウゲンカイケンチキノウ" // "Endstop abort" +#define MSG_HEATING_FAILED_LCD "カネツシッパイ" // "Heating failed" +#define MSG_ERR_REDUNDANT_TEMP "エラー:ジョウチョウサーミスターキノウ" // "Err: REDUNDANT TEMP" +#define MSG_THERMAL_RUNAWAY "ネツボウソウ" // "THERMAL RUNAWAY" +#define MSG_ERR_MAXTEMP "エラー:サイコウオンチョウカ" // "Err: MAXTEMP" +#define MSG_ERR_MINTEMP "エラー:サイテイオンミマン" // "Err: MINTEMP" +#define MSG_ERR_MAXTEMP_BED "エラー:ベッド サイコウオンチョウカ" // "Err: MAXTEMP BED" +#define MSG_ERR_MINTEMP_BED "エラー:ベッド サイテイオンミマン" // "Err: MINTEMP BED" +#define MSG_HALTED "プリンターハテイシシマシタ" // "PRINTER HALTED" +#define MSG_PLEASE_RESET "リセットシテクダサイ" // "Please reset" +#define MSG_SHORT_DAY "d" // One character only +#define MSG_SHORT_HOUR "h" // One character only +#define MSG_SHORT_MINUTE "m" // One character only +#define MSG_HEATING "カネツチュウ" // "Heating..." +#define MSG_HEATING_COMPLETE "カネツカンリョウ" // "Heating done." +#define MSG_BED_HEATING "ベッド カネツチュウ" // "Bed Heating." +#define MSG_BED_DONE "ベッド カネツカンリョウ" // "Bed done." +#define MSG_DELTA_CALIBRATE "デルタ コウセイ" // "Delta Calibration" +#define MSG_DELTA_CALIBRATE_X "Xジク コウセイ" // "Calibrate X" +#define MSG_DELTA_CALIBRATE_Y "Yジク コウセイ" // "Calibrate Y" +#define MSG_DELTA_CALIBRATE_Z "Zジク コウセイ" // "Calibrate Z" +#define MSG_DELTA_CALIBRATE_CENTER "チュウシン コウセイ" // "Calibrate Center" +#define MSG_INFO_MENU "コノプリンターニツイテ" // "About Printer" +#define MSG_INFO_PRINTER_MENU "プリンタージョウホウ" // "Printer Info" +#define MSG_INFO_STATS_MENU "プリントジョウキョウ" // "Printer Stats" +#define MSG_INFO_BOARD_MENU "セイギョケイジョウホウ" // "Board Info" +#define MSG_INFO_THERMISTOR_MENU "サーミスター" // "Thermistors" +#define MSG_INFO_EXTRUDERS "エクストルーダースウ" // "Extruders" +#define MSG_INFO_BAUDRATE "ボーレート" // "Baud" +#define MSG_INFO_PROTOCOL "プロトコル" // "Protocol" +#define MSG_INFO_PRINT_COUNT "プリントスウ " // "Print Count" +#define MSG_INFO_COMPLETED_PRINTS "カンリョウスウ" // "Completed" +#define MSG_INFO_PRINT_TIME "プリントジカンルイケイ" // "Total print time" +#define MSG_INFO_PRINT_LONGEST "サイチョウプリントジカン" // "Longest job time" +#define MSG_INFO_PRINT_FILAMENT "フィラメントシヨウリョウルイケイ" // "Extruded total" +#define MSG_INFO_MIN_TEMP "セッテイサイテイオン" // "Min Temp" +#define MSG_INFO_MAX_TEMP "セッテイサイコウオン" // "Max Temp" +#define MSG_INFO_PSU "デンゲンシュベツ" // "Power Supply" +#define MSG_FILAMENT_CHANGE_HEADER "フィラメントコウカン" // "CHANGE FILAMENT" +#define MSG_FILAMENT_CHANGE_OPTION_HEADER "ドウサヲセンタクシテクダサイ" // "CHANGE OPTIONS:" +#define MSG_FILAMENT_CHANGE_OPTION_EXTRUDE "サラニオシダス" // "Extrude more" +#define MSG_FILAMENT_CHANGE_OPTION_RESUME "プリントサイカイ" // "Resume print" +#define MSG_FILAMENT_CHANGE_INIT_1 "コウカンヲカイシシマス" // "Wait for start" +#define MSG_FILAMENT_CHANGE_INIT_2 "シバラクオマチクダサイ" // "of the filament" +#define MSG_FILAMENT_CHANGE_INIT_3 "" // "change" +#define MSG_FILAMENT_CHANGE_UNLOAD_1 "フィラメントヌキダシチュウ" // "Wait for" +#define MSG_FILAMENT_CHANGE_UNLOAD_2 "シバラクオマチクダサイ" // "filament unload" +#define MSG_FILAMENT_CHANGE_UNLOAD_3 "" +#define MSG_FILAMENT_CHANGE_INSERT_1 "フィラメントヲソウニュウシ," // "Insert filament" +#define MSG_FILAMENT_CHANGE_INSERT_2 "クリックスルトゾッコウシマス" // "and press button" +#define MSG_FILAMENT_CHANGE_INSERT_3 "" // "to continue..." +#define MSG_FILAMENT_CHANGE_LOAD_1 "フィラメントソウテンチュウ" // "Wait for" +#define MSG_FILAMENT_CHANGE_LOAD_2 "シバラクオマチクダサイ" // "filament load" +#define MSG_FILAMENT_CHANGE_LOAD_3 "" +#define MSG_FILAMENT_CHANGE_EXTRUDE_1 "フィラメントオシダシチュウ" // "Wait for" +#define MSG_FILAMENT_CHANGE_EXTRUDE_2 "シバラクオマチクダサイ" // "filament extrude" +#define MSG_FILAMENT_CHANGE_EXTRUDE_3 "" +#define MSG_FILAMENT_CHANGE_RESUME_1 "プリントヲサイカイシマス" // "Wait for print" +#define MSG_FILAMENT_CHANGE_RESUME_2 "シバラクオマチクダサイ" // "to resume" +#define MSG_FILAMENT_CHANGE_RESUME_3 "" + +#endif // LANGUAGE_KANA_UTF_H diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_nl.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_nl.h new file mode 100644 index 00000000..5f682bd9 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_nl.h @@ -0,0 +1,170 @@ +/** + * 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 . + * + */ + +/** + * Dutch + * + * LCD Menu Messages + * See also https://github.com/MarlinFirmware/Marlin/wiki/LCD-Language + * + */ +#ifndef LANGUAGE_NL_H +#define LANGUAGE_NL_H + +// Define SIMULATE_ROMFONT to see what is seen on the character based display defined in Configuration.h +//#define SIMULATE_ROMFONT +#define DISPLAY_CHARSET_ISO10646_1 + +#define WELCOME_MSG MACHINE_NAME " gereed." +#define MSG_SD_INSERTED "Kaart ingestoken" +#define MSG_SD_REMOVED "Kaart verwijderd" +#define MSG_MAIN "Hoofdmenu" +#define MSG_AUTOSTART "Autostart" +#define MSG_DISABLE_STEPPERS "Motoren uit" +#define MSG_AUTO_HOME "Auto home" +#define MSG_LEVEL_BED_HOMING "Homing XYZ" +#define MSG_LEVEL_BED_WAITING "Klik voor begin" +#define MSG_LEVEL_BED_DONE "Bed level kompl." +#define MSG_LEVEL_BED_CANCEL "Bed level afbr." +#define MSG_SET_HOME_OFFSETS "Zet home offsets" +#define MSG_HOME_OFFSETS_APPLIED "H offset toegep." +#define MSG_SET_ORIGIN "Nulpunt instellen" +#define MSG_PREHEAT_1 "PLA voorverwarmen" +#define MSG_PREHEAT_1_N "PLA voorverw. " +#define MSG_PREHEAT_1_ALL "PLA voorverw. aan" +#define MSG_PREHEAT_1_BEDONLY "PLA voorverw. Bed" +#define MSG_PREHEAT_1_SETTINGS "PLA verw. conf" +#define MSG_PREHEAT_2 "ABS voorverwarmen" +#define MSG_PREHEAT_2_N "ABS voorverw. " +#define MSG_PREHEAT_2_ALL "ABS voorverw. aan" +#define MSG_PREHEAT_2_BEDONLY "ABS voorverw. Bed" +#define MSG_PREHEAT_2_SETTINGS "ABS verw. conf" +#define MSG_COOLDOWN "Afkoelen" +#define MSG_SWITCH_PS_ON "Stroom aan" +#define MSG_SWITCH_PS_OFF "Stroom uit" +#define MSG_EXTRUDE "Extrude" +#define MSG_RETRACT "Retract" +#define MSG_MOVE_AXIS "As verplaatsen" +#define MSG_MOVE_X "Verplaats X" +#define MSG_MOVE_Y "Verplaats Y" +#define MSG_MOVE_Z "Verplaats Z" +#define MSG_MOVE_E "Extruder" +#define MSG_MOVE_01MM "Verplaats 0.1mm" +#define MSG_MOVE_1MM "Verplaats 1mm" +#define MSG_MOVE_10MM "Verplaats 10mm" +#define MSG_SPEED "Snelheid" +#define MSG_BED_Z "Bed Z" +#define MSG_NOZZLE "Nozzle" +#define MSG_BED "Bed" +#define MSG_FAN_SPEED "Fan snelheid" +#define MSG_FLOW "Flow" +#define MSG_CONTROL "Control" +#define MSG_MIN LCD_STR_THERMOMETER " Min" +#define MSG_MAX LCD_STR_THERMOMETER " Max" +#define MSG_FACTOR LCD_STR_THERMOMETER " Fact" +#define MSG_AUTOTEMP "Autotemp" +#define MSG_ON "Aan " +#define MSG_OFF "Uit" +#define MSG_PID_P "PID-P" +#define MSG_PID_I "PID-I" +#define MSG_PID_D "PID-D" +#define MSG_PID_C "PID-C" +#define MSG_ACC "Versn" +#define MSG_VXY_JERK "Vxy-jerk" +#define MSG_VZ_JERK "Vz-jerk" +#define MSG_VE_JERK "Ve-jerk" +#define MSG_VMAX "Vmax " +#define MSG_X "X" +#define MSG_Y "Y" +#define MSG_Z "Z" +#define MSG_E "E" +#define MSG_VMIN "Vmin" +#define MSG_VTRAV_MIN "VTrav min" +#define MSG_AMAX "Amax " +#define MSG_A_RETRACT "A-retract" +#define MSG_A_TRAVEL "A-travel" +#define MSG_XSTEPS "Xsteps/mm" +#define MSG_YSTEPS "Ysteps/mm" +#define MSG_ZSTEPS "Zsteps/mm" +#define MSG_ESTEPS "Esteps/mm" +#define MSG_TEMPERATURE "Temperatuur" +#define MSG_MOTION "Beweging" +#define MSG_VOLUMETRIC "Filament" +#define MSG_VOLUMETRIC_ENABLED "E in mm3" +#define MSG_FILAMENT_DIAM "Fil. Dia." +#define MSG_CONTRAST "LCD contrast" +#define MSG_STORE_EPROM "Geheugen opslaan" +#define MSG_LOAD_EPROM "Geheugen laden" +#define MSG_RESTORE_FAILSAFE "Noodstop reset" +#define MSG_REFRESH "Ververs" +#define MSG_WATCH "Info scherm" +#define MSG_PREPARE "Voorbereiden" +#define MSG_TUNE "Afstellen" +#define MSG_PAUSE_PRINT "Print pauzeren" +#define MSG_RESUME_PRINT "Print hervatten" +#define MSG_STOP_PRINT "Print stoppen" +#define MSG_CARD_MENU "Print van SD" +#define MSG_NO_CARD "Geen SD kaart" +#define MSG_DWELL "Slapen..." +#define MSG_USERWAIT "Wachten..." +#define MSG_RESUMING "Print hervatten" +#define MSG_PRINT_ABORTED "Print afgebroken" +#define MSG_NO_MOVE "Geen beweging." +#define MSG_KILLED "Afgebroken. " +#define MSG_STOPPED "Gestopt. " +#define MSG_CONTROL_RETRACT "Retract mm" +#define MSG_CONTROL_RETRACT_SWAP "Ruil Retract mm" +#define MSG_CONTROL_RETRACTF "Retract F" +#define MSG_CONTROL_RETRACT_ZLIFT "Hop mm" +#define MSG_CONTROL_RETRACT_RECOVER "UnRet +mm" +#define MSG_CONTROL_RETRACT_RECOVER_SWAP "Ruil UnRet +mm" +#define MSG_CONTROL_RETRACT_RECOVERF "UnRet F" +#define MSG_AUTORETRACT "AutoRetr." +#define MSG_FILAMENTCHANGE "Verv. Filament" +#define MSG_INIT_SDCARD "Init. SD kaart" +#define MSG_CNG_SDCARD "Verv. SD Kaart" +#define MSG_ZPROBE_OUT "Z probe uit. bed" +#define MSG_HOME "Home" // Used as MSG_HOME " " MSG_X MSG_Y MSG_Z " " MSG_FIRST +#define MSG_FIRST "first" +#define MSG_ZPROBE_ZOFFSET "Z Offset" +#define MSG_BABYSTEP_X "Babystap X" +#define MSG_BABYSTEP_Y "Babystap Y" +#define MSG_BABYSTEP_Z "Babystap Z" +#define MSG_ENDSTOP_ABORT "Endstop afbr." +#define MSG_HEATING_FAILED_LCD "voorverw. fout" +#define MSG_ERR_REDUNDANT_TEMP "Redun. temp fout" +#define MSG_THERMAL_RUNAWAY "Therm. wegloop" +#define MSG_ERR_MAXTEMP "Err: Max. temp" +#define MSG_ERR_MINTEMP "Err: Min. temp" +#define MSG_ERR_MAXTEMP_BED "Err: Max.tmp bed" +#define MSG_ERR_MINTEMP_BED "Err: Min.tmp bed" +#define MSG_HEATING "Voorwarmen..." +#define MSG_HEATING_COMPLETE "Voorverw. kompl." +#define MSG_BED_HEATING "Bed voorverw." +#define MSG_BED_DONE "Bed is voorverw." +#define MSG_DELTA_CALIBRATE "Delta Calibratie" +#define MSG_DELTA_CALIBRATE_X "Kalibreer X" +#define MSG_DELTA_CALIBRATE_Y "Kalibreer Y" +#define MSG_DELTA_CALIBRATE_Z "Kalibreer Z" +#define MSG_DELTA_CALIBRATE_CENTER "Kalibreer Midden" + +#endif // LANGUAGE_NL_H diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_pl.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_pl.h new file mode 100644 index 00000000..b1559c4a --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_pl.h @@ -0,0 +1,193 @@ +/** + * 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 . + * + */ + +/** + * Polish + * + * LCD Menu Messages + * See also https://github.com/MarlinFirmware/Marlin/wiki/LCD-Language + * + */ +#ifndef LANGUAGE_PL_H +#define LANGUAGE_PL_H + +// Define SIMULATE_ROMFONT to see what is seen on the character based display defined in Configuration.h +//#define SIMULATE_ROMFONT +#define DISPLAY_CHARSET_ISO10646_1 + +#define WELCOME_MSG MACHINE_NAME " gotowy." +#define MSG_SD_INSERTED "Karta wlozona" +#define MSG_SD_REMOVED "Karta usunieta" +#define MSG_LCD_ENDSTOPS "Krancow." // Max length 8 characters +#define MSG_MAIN "Menu glowne" +#define MSG_AUTOSTART "Autostart" +#define MSG_DISABLE_STEPPERS "Wylacz silniki" +#define MSG_AUTO_HOME "Auto. poz. zerowa" +#define MSG_LEVEL_BED_HOMING "Pozycja zerowa" +#define MSG_LEVEL_BED_WAITING "Kliknij by rozp." +#define MSG_LEVEL_BED_NEXT_POINT "Nastepny punkt" +#define MSG_LEVEL_BED_DONE "Wypoziomowano!" +#define MSG_LEVEL_BED_CANCEL "Anuluj" +#define MSG_SET_HOME_OFFSETS "Ust. poz. zer." +#define MSG_HOME_OFFSETS_APPLIED "Poz. zerowa ust." +#define MSG_SET_ORIGIN "Ustaw punkt zero" +#define MSG_PREHEAT_1 "Rozgrzej PLA" +#define MSG_PREHEAT_1_N "Rozgrzej PLA " +#define MSG_PREHEAT_1_ALL "Roz. PLA Wszystko" +#define MSG_PREHEAT_1_BEDONLY "Rozgrzej PLA Loze" +#define MSG_PREHEAT_1_SETTINGS "Ustaw. rozg. PLA" +#define MSG_PREHEAT_2 "Rozgrzej ABS" +#define MSG_PREHEAT_2_N "Rozgrzej ABS " +#define MSG_PREHEAT_2_ALL "Roz. ABS Wszystko" +#define MSG_PREHEAT_2_BEDONLY "Rozgrzej ABS Loze" +#define MSG_PREHEAT_2_SETTINGS "Ustaw. rozg. ABS" +#define MSG_H1 "1" +#define MSG_H2 "2" +#define MSG_H3 "3" +#define MSG_H4 "4" +#define MSG_COOLDOWN "Chlodzenie" +#define MSG_SWITCH_PS_ON "Wlacz zasilacz" +#define MSG_SWITCH_PS_OFF "Wylacz zasilacz" +#define MSG_EXTRUDE "Ekstruzja" +#define MSG_RETRACT "Wycofanie" +#define MSG_MOVE_AXIS "Ruch osi" +#define MSG_LEVEL_BED "Poziom. loza" +#define MSG_MOVE_X "Przesun w X" +#define MSG_MOVE_Y "Przesun w Y" +#define MSG_MOVE_Z "Przesun w Z" +#define MSG_MOVE_E "Ekstruzja (os E)" +#define MSG_MOVE_E1 "1" +#define MSG_MOVE_E2 "2" +#define MSG_MOVE_E3 "3" +#define MSG_MOVE_E4 "4" +#define MSG_MOVE_01MM "Przesuwaj co .1mm" +#define MSG_MOVE_1MM "Przesuwaj co 1mm" +#define MSG_MOVE_10MM "Przesuwaj co 10mm" +#define MSG_SPEED "Predkosc" +#define MSG_BED_Z "Loze Z" +#define MSG_NOZZLE "Dysza" +#define MSG_N1 " 1" +#define MSG_N2 " 2" +#define MSG_N3 " 3" +#define MSG_N4 " 4" +#define MSG_BED "Loze" +#define MSG_FAN_SPEED "Obroty wiatraka" +#define MSG_FLOW "Przeplyw" +#define MSG_CONTROL "Ustawienia" +#define MSG_MIN LCD_STR_THERMOMETER " Min" +#define MSG_MAX LCD_STR_THERMOMETER " Max" +#define MSG_FACTOR LCD_STR_THERMOMETER " Mnoznik" +#define MSG_AUTOTEMP "Auto. temperatura" +#define MSG_ON "Wl. " +#define MSG_OFF "Wyl." +#define MSG_PID_P "PID-P" +#define MSG_PID_I "PID-I" +#define MSG_PID_D "PID-D" +#define MSG_PID_C "PID-C" +#define MSG_E1 " E1" +#define MSG_E2 " E2" +#define MSG_E3 " E3" +#define MSG_E4 " E4" +#define MSG_ACC "Przyspieszenie" +#define MSG_VXY_JERK "Zryw Vxy" +#define MSG_VZ_JERK "Zryw Vz" +#define MSG_VE_JERK "Zryw Ve" +#define MSG_VMAX "Vmax " +#define MSG_X "X" +#define MSG_Y "Y" +#define MSG_Z "Z" +#define MSG_E "E" +#define MSG_VMIN "Vmin" +#define MSG_VTRAV_MIN "Vskok min" +#define MSG_AMAX "Amax" +#define MSG_A_RETRACT "A-wycofanie" +#define MSG_A_TRAVEL "A-przesun." +#define MSG_XSTEPS "krokiX/mm" +#define MSG_YSTEPS "krokiY/mm" +#define MSG_ZSTEPS "krokiZ/mm" +#define MSG_ESTEPS "krokiE/mm" +#define MSG_TEMPERATURE "Temperatura" +#define MSG_MOTION "Ruch" +#define MSG_VOLUMETRIC "Filament" +#define MSG_VOLUMETRIC_ENABLED "E w mm3" +#define MSG_FILAMENT_DIAM "Śr. fil." +#define MSG_DIAM_E1 " 1" +#define MSG_DIAM_E2 " 2" +#define MSG_DIAM_E3 " 3" +#define MSG_DIAM_E4 " 4" +#define MSG_CONTRAST "Kontrast LCD" +#define MSG_STORE_EPROM "Zapisz w pamieci" +#define MSG_LOAD_EPROM "Wczytaj z pamieci" +#define MSG_RESTORE_FAILSAFE "Ustaw. fabryczne" +#define MSG_REFRESH "Odswiez" +#define MSG_WATCH "Ekran glowny" +#define MSG_PREPARE "Przygotuj" +#define MSG_TUNE "Strojenie" +#define MSG_PAUSE_PRINT "Pauza" +#define MSG_RESUME_PRINT "Wznowienie" +#define MSG_STOP_PRINT "Stop" +#define MSG_CARD_MENU "Menu karty SD" +#define MSG_NO_CARD "Brak karty" +#define MSG_DWELL "Uspij..." +#define MSG_USERWAIT "Oczekiwanie..." +#define MSG_RESUMING "Wznawianie druku" +#define MSG_PRINT_ABORTED "Druk przerwany" +#define MSG_NO_MOVE "Brak ruchu" +#define MSG_KILLED "Ubity. " +#define MSG_STOPPED "Zatrzymany. " +#define MSG_CONTROL_RETRACT "Wycofaj mm" +#define MSG_CONTROL_RETRACT_SWAP "Z Wycof. mm" +#define MSG_CONTROL_RETRACTF "Wycofaj V" +#define MSG_CONTROL_RETRACT_ZLIFT "Skok Z mm" +#define MSG_CONTROL_RETRACT_RECOVER "Cof. wycof. +mm" +#define MSG_CONTROL_RETRACT_RECOVER_SWAP "Z Cof. wyc. +mm" +#define MSG_CONTROL_RETRACT_RECOVERF "Cof. wycof. V" +#define MSG_AUTORETRACT "Auto. wycofanie" +#define MSG_FILAMENTCHANGE "Zmien filament" +#define MSG_INIT_SDCARD "Inicjal. karty SD" +#define MSG_CNG_SDCARD "Zmiana karty SD" +#define MSG_ZPROBE_OUT "Sonda Z za lozem" +#define MSG_HOME "Home" // Used as MSG_HOME " " MSG_X MSG_Y MSG_Z " " MSG_FIRST +#define MSG_FIRST "first" +#define MSG_ZPROBE_ZOFFSET "Offset Z" +#define MSG_BABYSTEP_X "Babystep X" +#define MSG_BABYSTEP_Y "Babystep Y" +#define MSG_BABYSTEP_Z "Babystep Z" +#define MSG_ENDSTOP_ABORT "Blad krancowki" +#define MSG_HEATING_FAILED_LCD "Rozgrz. nieudane" +#define MSG_ERR_REDUNDANT_TEMP "Błąd temperatury" +#define MSG_THERMAL_RUNAWAY "Zanik temp." +#define MSG_ERR_MAXTEMP "Err: max. temp." +#define MSG_ERR_MINTEMP "Err: min. temp." +#define MSG_ERR_MAXTEMP_BED "Err: max. temp. loza" +#define MSG_ERR_MINTEMP_BED "Err: min. temp. loza" +#define MSG_HEATING "Rozgrzewanie..." +#define MSG_HEATING_COMPLETE "Rozgrzano" +#define MSG_BED_HEATING "Rozgrzewanie loza..." +#define MSG_BED_DONE "Rozgrzano loze" +#define MSG_DELTA_CALIBRATE "Kalibrowanie Delty" +#define MSG_DELTA_CALIBRATE_X "Kalibruj X" +#define MSG_DELTA_CALIBRATE_Y "Kalibruj Y" +#define MSG_DELTA_CALIBRATE_Z "Kalibruj Z" +#define MSG_DELTA_CALIBRATE_CENTER "Kalibruj środek" + +#endif // LANGUAGE_PL_H diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_pt-br.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_pt-br.h new file mode 100644 index 00000000..3db6e15c --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_pt-br.h @@ -0,0 +1,170 @@ +/** + * 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 . + * + */ + +/** + * Portuguese (Brazil) + * + * LCD Menu Messages + * See also https://github.com/MarlinFirmware/Marlin/wiki/LCD-Language + * + */ +#ifndef LANGUAGE_PT_BR_H +#define LANGUAGE_PT_BR_H + +// Define SIMULATE_ROMFONT to see what is seen on the character based display defined in Configuration.h +//#define SIMULATE_ROMFONT +#define DISPLAY_CHARSET_ISO10646_1 + +#define WELCOME_MSG MACHINE_NAME " pronto." +#define MSG_SD_INSERTED "Cartao inserido" +#define MSG_SD_REMOVED "Cartao removido" +#define MSG_MAIN "Menu principal" +#define MSG_AUTOSTART "Autostart" +#define MSG_DISABLE_STEPPERS "Desabi. motores" +#define MSG_AUTO_HOME "Ir para origen" +#define MSG_LEVEL_BED_HOMING "Homing XYZ" +#define MSG_LEVEL_BED_WAITING "Click to Begin" +#define MSG_LEVEL_BED_DONE "Leveling Done!" +#define MSG_LEVEL_BED_CANCEL "Cancel" +#define MSG_SET_HOME_OFFSETS "Ajustar Jogo" +#define MSG_HOME_OFFSETS_APPLIED "Offsets applied" +#define MSG_SET_ORIGIN "Ajustar orig." +#define MSG_PREHEAT_1 "Pre-aquecer PLA" +#define MSG_PREHEAT_1_N "Pre-aquecer PLA" +#define MSG_PREHEAT_1_ALL "Pre-aq.Todo PLA" +#define MSG_PREHEAT_1_BEDONLY "Pre-aq. PLA " LCD_STR_THERMOMETER "Base" +#define MSG_PREHEAT_1_SETTINGS "Ajustar PLA" +#define MSG_PREHEAT_2 "Pre-aquecer ABS" +#define MSG_PREHEAT_2_N "Pre-aquecer ABS" +#define MSG_PREHEAT_2_ALL "Pre-aq.Todo ABS" +#define MSG_PREHEAT_2_BEDONLY "Pre-aq. ABS " LCD_STR_THERMOMETER "Base" +#define MSG_PREHEAT_2_SETTINGS "Ajustar ABS" +#define MSG_COOLDOWN "Esfriar" +#define MSG_SWITCH_PS_ON "Ligar" +#define MSG_SWITCH_PS_OFF "Desligar" +#define MSG_EXTRUDE "Extrudar" +#define MSG_RETRACT "Retrair" +#define MSG_MOVE_AXIS "Mover eixo" +#define MSG_MOVE_X "Mover X" +#define MSG_MOVE_Y "Mover Y" +#define MSG_MOVE_Z "Mover Z" +#define MSG_MOVE_E "Mover Extrusor" +#define MSG_MOVE_01MM "Mover 0.1mm" +#define MSG_MOVE_1MM "Mover 1mm" +#define MSG_MOVE_10MM "Mover 10mm" +#define MSG_SPEED "Velocidade" +#define MSG_BED_Z "Base Z" +#define MSG_NOZZLE LCD_STR_THERMOMETER " Bocal" +#define MSG_BED LCD_STR_THERMOMETER " Base" +#define MSG_FAN_SPEED "Vel. Ventoinha" +#define MSG_FLOW "Fluxo" +#define MSG_CONTROL "Controle" +#define MSG_MIN LCD_STR_THERMOMETER " Min" +#define MSG_MAX LCD_STR_THERMOMETER " Max" +#define MSG_FACTOR LCD_STR_THERMOMETER " Fact" +#define MSG_AUTOTEMP "Temp. Automatica" +#define MSG_ON "Ligado " +#define MSG_OFF "Desligado" +#define MSG_PID_P "PID-P" +#define MSG_PID_I "PID-I" +#define MSG_PID_D "PID-D" +#define MSG_PID_C "PID-C" +#define MSG_ACC "Acc" +#define MSG_VXY_JERK "jogo VXY" +#define MSG_VZ_JERK "jogo VZ" +#define MSG_VE_JERK "jogo VE" +#define MSG_VMAX " Vmax " +#define MSG_X "X" +#define MSG_Y "Y" +#define MSG_Z "Z" +#define MSG_E "E" +#define MSG_VMIN "Vmin" +#define MSG_VTRAV_MIN "VTrav min" +#define MSG_AMAX "Amax " +#define MSG_A_RETRACT "Retrair A" +#define MSG_A_TRAVEL "A-movimento" +#define MSG_XSTEPS "Passo X/mm" +#define MSG_YSTEPS "Passo Y/mm" +#define MSG_ZSTEPS "Passo Z/mm" +#define MSG_ESTEPS "E/mm" +#define MSG_TEMPERATURE "Temperatura" +#define MSG_MOTION "Movimento" +#define MSG_VOLUMETRIC "Filamento" +#define MSG_VOLUMETRIC_ENABLED "Extr. em mm3" +#define MSG_FILAMENT_DIAM "Diametro Fil." +#define MSG_CONTRAST "Contraste" +#define MSG_STORE_EPROM "Salvar" +#define MSG_LOAD_EPROM "Ler" +#define MSG_RESTORE_FAILSAFE "Rest. de emerg." +#define MSG_REFRESH LCD_STR_REFRESH " Restaurar" +#define MSG_WATCH "Monitorar" +#define MSG_PREPARE "Preparar" +#define MSG_TUNE "Afinar" +#define MSG_PAUSE_PRINT "Pausar impressao" +#define MSG_RESUME_PRINT "Resumir impressao" +#define MSG_STOP_PRINT "Parar impressao" +#define MSG_CARD_MENU "Imprimir do SD" +#define MSG_NO_CARD "Sem cartao SD" +#define MSG_DWELL "Repouso..." +#define MSG_USERWAIT "Esperando ordem" +#define MSG_RESUMING "Resumindo Impres." +#define MSG_PRINT_ABORTED "Impres. Abortada." +#define MSG_NO_MOVE "Sem movimento" +#define MSG_KILLED "PARADA DE EMERG." +#define MSG_STOPPED "PARADA. " +#define MSG_CONTROL_RETRACT "Retrair mm" +#define MSG_CONTROL_RETRACT_SWAP "Retrair Troca mm" +#define MSG_CONTROL_RETRACTF "Retrair V" +#define MSG_CONTROL_RETRACT_ZLIFT "Levantar mm" +#define MSG_CONTROL_RETRACT_RECOVER "Des Retrair +mm" +#define MSG_CONTROL_RETRACT_RECOVER_SWAP "Des RetTroca +mm" +#define MSG_CONTROL_RETRACT_RECOVERF "Des Retrair V" +#define MSG_AUTORETRACT "Retracao Autom." +#define MSG_FILAMENTCHANGE "Trocar Filamento" +#define MSG_INIT_SDCARD "Iniciar SD" +#define MSG_CNG_SDCARD "Trocar SD" +#define MSG_ZPROBE_OUT "Son. fora da mesa" +#define MSG_HOME "Home" // Used as MSG_HOME " " MSG_X MSG_Y MSG_Z " " MSG_FIRST +#define MSG_FIRST "first" +#define MSG_ZPROBE_ZOFFSET "Deslocamento no Z" +#define MSG_BABYSTEP_X "Passinho X" +#define MSG_BABYSTEP_Y "Passinho Y" +#define MSG_BABYSTEP_Z "Passinho Z" +#define MSG_ENDSTOP_ABORT "Fim de Curso" +#define MSG_HEATING_FAILED_LCD "Aquecimento falhou" +#define MSG_ERR_REDUNDANT_TEMP "Err: REDUNDANT TEMP" +#define MSG_THERMAL_RUNAWAY "THERMAL RUNAWAY" +#define MSG_ERR_MAXTEMP "Err: T Maxima" +#define MSG_ERR_MINTEMP "Err: T Minima" +#define MSG_ERR_MAXTEMP_BED "Err: T Base Maxima" +#define MSG_ERR_MINTEMP_BED "Err: T Base Minima" +#define MSG_HEATING "Aquecendo..." +#define MSG_HEATING_COMPLETE "Aquecida." +#define MSG_BED_HEATING "Aquecendo base.." +#define MSG_BED_DONE "Base aquecida." +#define MSG_DELTA_CALIBRATE "Calibrar Delta" +#define MSG_DELTA_CALIBRATE_X "Calibrar X" +#define MSG_DELTA_CALIBRATE_Y "Calibrar Y" +#define MSG_DELTA_CALIBRATE_Z "Calibrar Z" +#define MSG_DELTA_CALIBRATE_CENTER "Calibrar Centro" + +#endif // LANGUAGE_PT_BR_H diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_pt-br_utf8.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_pt-br_utf8.h new file mode 100644 index 00000000..a556c243 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_pt-br_utf8.h @@ -0,0 +1,170 @@ +/** + * 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 . + * + */ + +/** + * Portuguese (Brazil) + * + * LCD Menu Messages + * See also https://github.com/MarlinFirmware/Marlin/wiki/LCD-Language + * + */ +#ifndef LANGUAGE_PT_BR_UTF_H +#define LANGUAGE_PT_BR_UTF_H + +// Define SIMULATE_ROMFONT to see what is seen on the character based display defined in Configuration.h +//#define SIMULATE_ROMFONT +#define DISPLAY_CHARSET_ISO10646_1 + +#define WELCOME_MSG MACHINE_NAME " pronto." +#define MSG_SD_INSERTED "Cartão inserido" +#define MSG_SD_REMOVED "Cartão removido" +#define MSG_MAIN "Menu principal" +#define MSG_AUTOSTART "Autostart" +#define MSG_DISABLE_STEPPERS "Desabi. motores" +#define MSG_AUTO_HOME "Ir para origen" +#define MSG_LEVEL_BED_HOMING "Indo para origem" +#define MSG_LEVEL_BED_WAITING "Click to Begin" +#define MSG_LEVEL_BED_DONE "Leveling Done!" +#define MSG_LEVEL_BED_CANCEL "Cancel" +#define MSG_SET_HOME_OFFSETS "Ajustar Jogo" +#define MSG_HOME_OFFSETS_APPLIED "Offsets applied" +#define MSG_SET_ORIGIN "Ajustar orig." +#define MSG_PREHEAT_1 "Pre-aquecer PLA" +#define MSG_PREHEAT_1_N "Pre-aquecer PLA" +#define MSG_PREHEAT_1_ALL "Pre-aq.Todo PLA" +#define MSG_PREHEAT_1_BEDONLY "Pre-aq. PLA " LCD_STR_THERMOMETER "Base" +#define MSG_PREHEAT_1_SETTINGS "Ajustar PLA" +#define MSG_PREHEAT_2 "Pre-aquecer ABS" +#define MSG_PREHEAT_2_N "Pre-aquecer ABS" +#define MSG_PREHEAT_2_ALL "Pre-aq.Todo ABS" +#define MSG_PREHEAT_2_BEDONLY "Pre-aq. ABS " LCD_STR_THERMOMETER "Base" +#define MSG_PREHEAT_2_SETTINGS "Ajustar ABS" +#define MSG_COOLDOWN "Esfriar" +#define MSG_SWITCH_PS_ON "Ligar" +#define MSG_SWITCH_PS_OFF "Desligar" +#define MSG_EXTRUDE "Extrudar" +#define MSG_RETRACT "Retrair" +#define MSG_MOVE_AXIS "Mover eixo" +#define MSG_MOVE_X "Mover X" +#define MSG_MOVE_Y "Mover Y" +#define MSG_MOVE_Z "Mover Z" +#define MSG_MOVE_E "Mover Extrusor" +#define MSG_MOVE_01MM "Mover 0.1mm" +#define MSG_MOVE_1MM "Mover 1mm" +#define MSG_MOVE_10MM "Mover 10mm" +#define MSG_SPEED "Velocidade" +#define MSG_BED_Z "Base Z" +#define MSG_NOZZLE LCD_STR_THERMOMETER " Bocal" +#define MSG_BED LCD_STR_THERMOMETER " Base" +#define MSG_FAN_SPEED "Vel. Ventoinha" +#define MSG_FLOW "Fluxo" +#define MSG_CONTROL "Controle" +#define MSG_MIN LCD_STR_THERMOMETER " Min" +#define MSG_MAX LCD_STR_THERMOMETER " Max" +#define MSG_FACTOR LCD_STR_THERMOMETER " Fact" +#define MSG_AUTOTEMP "Temp. Automática" +#define MSG_ON "Ligado " +#define MSG_OFF "Desligado" +#define MSG_PID_P "PID-P" +#define MSG_PID_I "PID-I" +#define MSG_PID_D "PID-D" +#define MSG_PID_C "PID-C" +#define MSG_ACC "Acc" +#define MSG_VXY_JERK "jogo VXY" +#define MSG_VZ_JERK "jogo VZ" +#define MSG_VE_JERK "jogo VE" +#define MSG_VMAX " Vmax " +#define MSG_X "X" +#define MSG_Y "Y" +#define MSG_Z "Z" +#define MSG_E "E" +#define MSG_VMIN "Vmin" +#define MSG_VTRAV_MIN "VTrav min" +#define MSG_AMAX "Amax " +#define MSG_A_RETRACT "Retrair A" +#define MSG_A_TRAVEL "A-movimento" +#define MSG_XSTEPS "Passo X/mm" +#define MSG_YSTEPS "Passo Y/mm" +#define MSG_ZSTEPS "Passo Z/mm" +#define MSG_ESTEPS "E/mm" +#define MSG_TEMPERATURE "Temperatura" +#define MSG_MOTION "Movimento" +#define MSG_VOLUMETRIC "Filamento" +#define MSG_VOLUMETRIC_ENABLED "Extr. em mm3" +#define MSG_FILAMENT_DIAM "Diametro Fil." +#define MSG_CONTRAST "Contraste" +#define MSG_STORE_EPROM "Salvar" +#define MSG_LOAD_EPROM "Ler" +#define MSG_RESTORE_FAILSAFE "Rest. de emerg." +#define MSG_REFRESH LCD_STR_REFRESH " Restaurar" +#define MSG_WATCH "Monitorar" +#define MSG_PREPARE "Preparar" +#define MSG_TUNE "Afinar" +#define MSG_PAUSE_PRINT "Pausar impressão" +#define MSG_RESUME_PRINT "Resumir impressão" +#define MSG_STOP_PRINT "Parar impressão" +#define MSG_CARD_MENU "Imprimir do SD" +#define MSG_NO_CARD "Sem cartão SD" +#define MSG_DWELL "Repouso..." +#define MSG_USERWAIT "Esperando ordem" +#define MSG_RESUMING "Resumindo Impres." +#define MSG_PRINT_ABORTED "Impres. Abortada." +#define MSG_NO_MOVE "Sem movimento" +#define MSG_KILLED "PARADA DE EMERG." +#define MSG_STOPPED "PARADA. " +#define MSG_CONTROL_RETRACT "Retrair mm" +#define MSG_CONTROL_RETRACT_SWAP "Retrair Troca mm" +#define MSG_CONTROL_RETRACTF "Retrair V" +#define MSG_CONTROL_RETRACT_ZLIFT "Levantar mm" +#define MSG_CONTROL_RETRACT_RECOVER "Des Retrair +mm" +#define MSG_CONTROL_RETRACT_RECOVER_SWAP "Des RetTroca +mm" +#define MSG_CONTROL_RETRACT_RECOVERF "Des Retrair V" +#define MSG_AUTORETRACT "Retração Autom." +#define MSG_FILAMENTCHANGE "Trocar Filamento" +#define MSG_INIT_SDCARD "Iniciar SD" +#define MSG_CNG_SDCARD "Trocar SD" +#define MSG_ZPROBE_OUT "Son. fora da mesa" +#define MSG_HOME "Home" // Used as MSG_HOME " " MSG_X MSG_Y MSG_Z " " MSG_FIRST +#define MSG_FIRST "first" +#define MSG_ZPROBE_ZOFFSET "Deslocamento no Z" +#define MSG_BABYSTEP_X "Passinho X" +#define MSG_BABYSTEP_Y "Passinho Y" +#define MSG_BABYSTEP_Z "Passinho Z" +#define MSG_ENDSTOP_ABORT "Fim de Curso" +#define MSG_HEATING_FAILED_LCD "Aquecimento falhou" +#define MSG_ERR_REDUNDANT_TEMP "Err: REDUNDANT TEMP" +#define MSG_THERMAL_RUNAWAY "THERMAL RUNAWAY" +#define MSG_ERR_MAXTEMP "Err: T Máxima" +#define MSG_ERR_MINTEMP "Err: T Mínima" +#define MSG_ERR_MAXTEMP_BED "Err: T Base Máxima" +#define MSG_ERR_MINTEMP_BED "Err: T Base Mínima" +#define MSG_HEATING "Aquecendo..." +#define MSG_HEATING_COMPLETE "Aquecida." +#define MSG_BED_HEATING "Aquecendo base.." +#define MSG_BED_DONE "Base aquecida." +#define MSG_DELTA_CALIBRATE "Calibrar Delta" +#define MSG_DELTA_CALIBRATE_X "Calibrar X" +#define MSG_DELTA_CALIBRATE_Y "Calibrar Y" +#define MSG_DELTA_CALIBRATE_Z "Calibrar Z" +#define MSG_DELTA_CALIBRATE_CENTER "Calibrar Centro" + +#endif // LANGUAGE_PT_BR_UTF_H diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_pt.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_pt.h new file mode 100644 index 00000000..a0df879f --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_pt.h @@ -0,0 +1,180 @@ +/** + * 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 . + * + */ + +/** + * Portuguese + * + * LCD Menu Messages + * See also https://github.com/MarlinFirmware/Marlin/wiki/LCD-Language + * + */ +#ifndef LANGUAGE_PT_H +#define LANGUAGE_PT_H + +// Define SIMULATE_ROMFONT to see what is seen on the character based display defined in Configuration.h +//#define SIMULATE_ROMFONT +#define DISPLAY_CHARSET_ISO10646_1 + +#define WELCOME_MSG MACHINE_NAME " pronto." +#define MSG_SD_INSERTED "Cartao inserido" +#define MSG_SD_REMOVED "Cartao removido" +#define MSG_MAIN "Menu principal" +#define MSG_AUTOSTART "Autostart" +#define MSG_DISABLE_STEPPERS "Desactivar motores" +#define MSG_AUTO_HOME "Ir para origem" +#define MSG_AUTO_HOME_X "Ir para origem X" +#define MSG_AUTO_HOME_Y "Ir para origem Y" +#define MSG_AUTO_HOME_Z "Ir para origem Z" +#define MSG_LEVEL_BED_HOMING "Indo para origem" +#define MSG_LEVEL_BED_WAITING "Click para iniciar" +#define MSG_LEVEL_BED_NEXT_POINT "Proximo ponto" +#define MSG_LEVEL_BED_DONE "Pronto !" +#define MSG_LEVEL_BED_CANCEL "Cancelar" +#define MSG_SET_HOME_OFFSETS "Definir desvio" +#define MSG_HOME_OFFSETS_APPLIED "Offsets applied" +#define MSG_SET_ORIGIN "Definir origem" +#define MSG_PREHEAT_1 "Pre-aquecer PLA" +#define MSG_PREHEAT_1_N "Pre-aquecer PLA" +#define MSG_PREHEAT_1_ALL "Pre-aq. PLA Tudo" +#define MSG_PREHEAT_1_BEDONLY "Pre-aq. PLA " LCD_STR_THERMOMETER "Base" +#define MSG_PREHEAT_1_SETTINGS "Definicoes PLA" +#define MSG_PREHEAT_2 "Pre-aquecer ABS" +#define MSG_PREHEAT_2_N "Pre-aquecer ABS " +#define MSG_PREHEAT_2_ALL "Pre-aq. ABS Tudo" +#define MSG_PREHEAT_2_BEDONLY "Pre-aq. ABS " LCD_STR_THERMOMETER "Base" +#define MSG_PREHEAT_2_SETTINGS "Definicoes ABS" +#define MSG_COOLDOWN "Arrefecer" +#define MSG_SWITCH_PS_ON "Ligar" +#define MSG_SWITCH_PS_OFF "Desligar" +#define MSG_EXTRUDE "Extrudir" +#define MSG_RETRACT "Retrair" +#define MSG_MOVE_AXIS "Mover eixo" +#define MSG_MOVE_X "Mover X" +#define MSG_MOVE_Y "Mover Y" +#define MSG_MOVE_Z "Mover Z" +#define MSG_MOVE_E "Mover Extrusor" +#define MSG_MOVE_01MM "Mover 0.1mm" +#define MSG_MOVE_1MM "Mover 1mm" +#define MSG_MOVE_10MM "Mover 10mm" +#define MSG_SPEED "Velocidade" +#define MSG_BED_Z "Base Z" +#define MSG_NOZZLE LCD_STR_THERMOMETER " Bico" +#define MSG_BED LCD_STR_THERMOMETER " Base" +#define MSG_FAN_SPEED "Vel. ventoinha" +#define MSG_FLOW "Fluxo" +#define MSG_CONTROL "Controlo" +#define MSG_MIN LCD_STR_THERMOMETER " Min" +#define MSG_MAX LCD_STR_THERMOMETER " Max" +#define MSG_FACTOR LCD_STR_THERMOMETER " Fact" +#define MSG_AUTOTEMP "Temp. Automatica" +#define MSG_ON "On " +#define MSG_OFF "Off" +#define MSG_PID_P "PID-P" +#define MSG_PID_I "PID-I" +#define MSG_PID_D "PID-D" +#define MSG_PID_C "PID-C" +#define MSG_E1 "E1" +#define MSG_E2 "E2" +#define MSG_E3 "E3" +#define MSG_E4 "E4" +#define MSG_ACC "Acc" +#define MSG_VXY_JERK "Vxy-jerk" +#define MSG_VZ_JERK "Vz-jerk" +#define MSG_VE_JERK "Ve-jerk" +#define MSG_VMAX " Vmax " +#define MSG_X "X" +#define MSG_Y "Y" +#define MSG_Z "Z" +#define MSG_E "E" +#define MSG_VMIN "Vmin" +#define MSG_VTRAV_MIN "VTrav min" +#define MSG_AMAX "Amax " +#define MSG_A_RETRACT "A-retraccao" +#define MSG_A_TRAVEL "A-movimento" +#define MSG_XSTEPS "X passo/mm" +#define MSG_YSTEPS "Y passo/mm" +#define MSG_ZSTEPS "Z passo/mm" +#define MSG_ESTEPS "E passo/mm" +#define MSG_TEMPERATURE "Temperatura" +#define MSG_MOTION "Movimento" +#define MSG_VOLUMETRIC "Filamento" +#define MSG_VOLUMETRIC_ENABLED "E em mm3" +#define MSG_FILAMENT_DIAM "Fil. Diam." +#define MSG_CONTRAST "Contraste" +#define MSG_STORE_EPROM "Guardar na memoria" +#define MSG_LOAD_EPROM "Carregar da memoria" +#define MSG_RESTORE_FAILSAFE "Rest. de emergen." +#define MSG_REFRESH LCD_STR_REFRESH " Recarregar" +#define MSG_WATCH "Monitorizar" +#define MSG_PREPARE "Preparar" +#define MSG_TUNE "Afinar" +#define MSG_PAUSE_PRINT "Pausar impressao" +#define MSG_RESUME_PRINT "Retomar impressao" +#define MSG_STOP_PRINT "Parar impressao" +#define MSG_CARD_MENU "Imprimir do SD" +#define MSG_NO_CARD "Sem cartao SD" +#define MSG_DWELL "Em espera..." +#define MSG_USERWAIT "A espera de ordem" +#define MSG_RESUMING "Retomando impressao" +#define MSG_PRINT_ABORTED "Impressao cancelada" +#define MSG_NO_MOVE "Sem movimento" +#define MSG_KILLED "EMERGENCIA. " +#define MSG_STOPPED "PARADO. " +#define MSG_CONTROL_RETRACT " Retrair mm" +#define MSG_CONTROL_RETRACT_SWAP "Troca Retrair mm" +#define MSG_CONTROL_RETRACTF " Retrair V" +#define MSG_CONTROL_RETRACT_ZLIFT " Levantar mm" +#define MSG_CONTROL_RETRACT_RECOVER " DesRet +mm" +#define MSG_CONTROL_RETRACT_RECOVER_SWAP "Troca DesRet +mm" +#define MSG_CONTROL_RETRACT_RECOVERF " DesRet V" +#define MSG_AUTORETRACT " AutoRetr." +#define MSG_FILAMENTCHANGE "Trocar filamento" +#define MSG_INIT_SDCARD "Inici. cartao SD" +#define MSG_CNG_SDCARD "Trocar cartao SD" +#define MSG_ZPROBE_OUT "Sensor fora/base" +#define MSG_HOME "Home" // Used as MSG_HOME " " MSG_X MSG_Y MSG_Z " " MSG_FIRST +#define MSG_FIRST "first" +#define MSG_ZPROBE_ZOFFSET "Desvio Z" +#define MSG_BABYSTEP_X "Babystep X" +#define MSG_BABYSTEP_Y "Babystep Y" +#define MSG_BABYSTEP_Z "Babystep Z" +#define MSG_ENDSTOP_ABORT "Fim de curso" +#define MSG_HEATING_FAILED_LCD "Aquecimento falhou" +#define MSG_ERR_REDUNDANT_TEMP "Err: REDUNDANT TEMP" +#define MSG_THERMAL_RUNAWAY "THERMAL RUNAWAY" +#define MSG_ERR_MAXTEMP "Err: T Maxima" +#define MSG_ERR_MINTEMP "Err: T Minima" +#define MSG_ERR_MAXTEMP_BED "Err: T Base Maxima" +#define MSG_ERR_MINTEMP_BED "Err: T Base Minima" +#define MSG_HEATING "Aquecendo..." +#define MSG_HEATING_COMPLETE "Aquecida." +#define MSG_BED_HEATING "Aquecendo base.." +#define MSG_BED_DONE "Base aquecida." +#define MSG_DELTA_CALIBRATE "Calibracao Delta" +#define MSG_DELTA_CALIBRATE_X "Calibrar X" +#define MSG_DELTA_CALIBRATE_Y "Calibrar Y" +#define MSG_DELTA_CALIBRATE_Z "Calibrar Z" +#define MSG_DELTA_CALIBRATE_CENTER "Calibrar Centro" + +#define MSG_LCD_ENDSTOPS "Fim de curso" + +#endif // LANGUAGE_PT_H diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_pt_utf8.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_pt_utf8.h new file mode 100644 index 00000000..24ce828b --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_pt_utf8.h @@ -0,0 +1,180 @@ +/** + * 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 . + * + */ + +/** + * Portuguese + * + * LCD Menu Messages + * See also https://github.com/MarlinFirmware/Marlin/wiki/LCD-Language + * + */ +#ifndef LANGUAGE_PT_UTF_H +#define LANGUAGE_PT_UTF_H + +// Define SIMULATE_ROMFONT to see what is seen on the character based display defined in Configuration.h +//#define SIMULATE_ROMFONT +#define DISPLAY_CHARSET_ISO10646_1 + +#define WELCOME_MSG MACHINE_NAME " pronto." +#define MSG_SD_INSERTED "Cartão inserido" +#define MSG_SD_REMOVED "Cartão removido" +#define MSG_MAIN "Menu principal" +#define MSG_AUTOSTART "Autostart" +#define MSG_DISABLE_STEPPERS "Desactivar motores" +#define MSG_AUTO_HOME "Ir para origem" +#define MSG_AUTO_HOME_X "Ir para origem X" +#define MSG_AUTO_HOME_Y "Ir para origem Y" +#define MSG_AUTO_HOME_Z "Ir para origem Z" +#define MSG_LEVEL_BED_HOMING "Indo para origem" +#define MSG_LEVEL_BED_WAITING "Click para iniciar" +#define MSG_LEVEL_BED_NEXT_POINT "Próximo ponto" +#define MSG_LEVEL_BED_DONE "Pronto !" +#define MSG_LEVEL_BED_CANCEL "Cancelar" +#define MSG_SET_HOME_OFFSETS "Definir desvio" +#define MSG_HOME_OFFSETS_APPLIED "Offsets aplicados" +#define MSG_SET_ORIGIN "Definir origem" +#define MSG_PREHEAT_1 "Pre-aquecer PLA" +#define MSG_PREHEAT_1_N "Pre-aquecer PLA" +#define MSG_PREHEAT_1_ALL "Pre-aq. PLA Tudo" +#define MSG_PREHEAT_1_BEDONLY "Pre-aq. PLA " LCD_STR_THERMOMETER "Base" +#define MSG_PREHEAT_1_SETTINGS "Definições PLA" +#define MSG_PREHEAT_2 "Pre-aquecer ABS" +#define MSG_PREHEAT_2_N "Pre-aquecer ABS " +#define MSG_PREHEAT_2_ALL "Pre-aq. ABS Tudo" +#define MSG_PREHEAT_2_BEDONLY "Pre-aq. ABS " LCD_STR_THERMOMETER "Base" +#define MSG_PREHEAT_2_SETTINGS "Definições ABS" +#define MSG_COOLDOWN "Arrefecer" +#define MSG_SWITCH_PS_ON "Ligar" +#define MSG_SWITCH_PS_OFF "Desligar" +#define MSG_EXTRUDE "Extrudir" +#define MSG_RETRACT "Retrair" +#define MSG_MOVE_AXIS "Mover eixo" +#define MSG_MOVE_X "Mover X" +#define MSG_MOVE_Y "Mover Y" +#define MSG_MOVE_Z "Mover Z" +#define MSG_MOVE_E "Mover Extrusor" +#define MSG_MOVE_01MM "Mover 0.1mm" +#define MSG_MOVE_1MM "Mover 1mm" +#define MSG_MOVE_10MM "Mover 10mm" +#define MSG_SPEED "Velocidade" +#define MSG_BED_Z "Base Z" +#define MSG_NOZZLE LCD_STR_THERMOMETER " Bico" +#define MSG_BED LCD_STR_THERMOMETER " Base" +#define MSG_FAN_SPEED "Vel. ventoinha" +#define MSG_FLOW "Fluxo" +#define MSG_CONTROL "Controlo" +#define MSG_MIN LCD_STR_THERMOMETER " Min" +#define MSG_MAX LCD_STR_THERMOMETER " Max" +#define MSG_FACTOR LCD_STR_THERMOMETER " Fact" +#define MSG_AUTOTEMP "Temp. Automática" +#define MSG_ON "On " +#define MSG_OFF "Off" +#define MSG_PID_P "PID-P" +#define MSG_PID_I "PID-I" +#define MSG_PID_D "PID-D" +#define MSG_PID_C "PID-C" +#define MSG_E1 "E1" +#define MSG_E2 "E2" +#define MSG_E3 "E3" +#define MSG_E4 "E4" +#define MSG_ACC "Acc" +#define MSG_VXY_JERK "Vxy-jerk" +#define MSG_VZ_JERK "Vz-jerk" +#define MSG_VE_JERK "Ve-jerk" +#define MSG_VMAX " Vmax " +#define MSG_X "X" +#define MSG_Y "Y" +#define MSG_Z "Z" +#define MSG_E "E" +#define MSG_VMIN "Vmin" +#define MSG_VTRAV_MIN "VTrav min" +#define MSG_AMAX "Amax " +#define MSG_A_RETRACT "A-retracção" +#define MSG_A_TRAVEL "A-movimento" +#define MSG_XSTEPS "X passo/mm" +#define MSG_YSTEPS "Y passo/mm" +#define MSG_ZSTEPS "Z passo/mm" +#define MSG_ESTEPS "E passo/mm" +#define MSG_TEMPERATURE "Temperatura" +#define MSG_MOTION "Movimento" +#define MSG_VOLUMETRIC "Filamento" +#define MSG_VOLUMETRIC_ENABLED "E em mm3" +#define MSG_FILAMENT_DIAM "Fil. Diam." +#define MSG_CONTRAST "Contraste" +#define MSG_STORE_EPROM "Guardar na memoria" +#define MSG_LOAD_EPROM "Carregar da memoria" +#define MSG_RESTORE_FAILSAFE "Rest. de emergen." +#define MSG_REFRESH LCD_STR_REFRESH " Recarregar" +#define MSG_WATCH "Monitorizar" +#define MSG_PREPARE "Preparar" +#define MSG_TUNE "Afinar" +#define MSG_PAUSE_PRINT "Pausar impressão" +#define MSG_RESUME_PRINT "Retomar impressão" +#define MSG_STOP_PRINT "Parar impressão" +#define MSG_CARD_MENU "Imprimir do SD" +#define MSG_NO_CARD "Sem cartão SD" +#define MSG_DWELL "Em espera..." +#define MSG_USERWAIT "Á espera de ordem" +#define MSG_RESUMING "Retomando impressão" +#define MSG_PRINT_ABORTED "Impressão cancelada" +#define MSG_NO_MOVE "Sem movimento" +#define MSG_KILLED "EMERGÊNCIA. " +#define MSG_STOPPED "PARADO. " +#define MSG_CONTROL_RETRACT " Retrair mm" +#define MSG_CONTROL_RETRACT_SWAP "Troca Retrair mm" +#define MSG_CONTROL_RETRACTF " Retrair V" +#define MSG_CONTROL_RETRACT_ZLIFT " Levantar mm" +#define MSG_CONTROL_RETRACT_RECOVER " DesRet +mm" +#define MSG_CONTROL_RETRACT_RECOVER_SWAP "Troca DesRet +mm" +#define MSG_CONTROL_RETRACT_RECOVERF " DesRet V" +#define MSG_AUTORETRACT " AutoRetr." +#define MSG_FILAMENTCHANGE "Trocar filamento" +#define MSG_INIT_SDCARD "Inici. cartão SD" +#define MSG_CNG_SDCARD "Trocar cartão SD" +#define MSG_ZPROBE_OUT "Sensor fora/base" +#define MSG_HOME "Home" // Used as MSG_HOME " " MSG_X MSG_Y MSG_Z " " MSG_FIRST +#define MSG_FIRST "first" +#define MSG_ZPROBE_ZOFFSET "Desvio Z" +#define MSG_BABYSTEP_X "Babystep X" +#define MSG_BABYSTEP_Y "Babystep Y" +#define MSG_BABYSTEP_Z "Babystep Z" +#define MSG_ENDSTOP_ABORT "Fim de curso" +#define MSG_HEATING_FAILED_LCD "Aquecimento falhou" +#define MSG_ERR_REDUNDANT_TEMP "Err: REDUNDANT TEMP" +#define MSG_THERMAL_RUNAWAY "THERMAL RUNAWAY" +#define MSG_ERR_MAXTEMP "Err: T Máxima" +#define MSG_ERR_MINTEMP "Err: T Mínima" +#define MSG_ERR_MAXTEMP_BED "Err: T Base Máxima" +#define MSG_ERR_MINTEMP_BED "Err: T Base Mínima" +#define MSG_HEATING "Aquecendo..." +#define MSG_HEATING_COMPLETE "Aquecida." +#define MSG_BED_HEATING "Aquecendo base.." +#define MSG_BED_DONE "Base aquecida." +#define MSG_DELTA_CALIBRATE "Calibração Delta" +#define MSG_DELTA_CALIBRATE_X "Calibrar X" +#define MSG_DELTA_CALIBRATE_Y "Calibrar Y" +#define MSG_DELTA_CALIBRATE_Z "Calibrar Z" +#define MSG_DELTA_CALIBRATE_CENTER "Calibrar Centro" + +#define MSG_LCD_ENDSTOPS "Fim de curso" + +#endif // LANGUAGE_PT_UTF_H diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_ru.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_ru.h new file mode 100644 index 00000000..aa381c88 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_ru.h @@ -0,0 +1,169 @@ +/** + * 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 . + * + */ + +/** + * Russian + * + * LCD Menu Messages + * See also https://github.com/MarlinFirmware/Marlin/wiki/LCD-Language + * + */ +#ifndef LANGUAGE_RU_H +#define LANGUAGE_RU_H + +#define MAPPER_D0D1 // For Cyrillic +// Define SIMULATE_ROMFONT to see what is seen on the character based display defined in Configuration.h +//#define SIMULATE_ROMFONT +#define DISPLAY_CHARSET_ISO10646_5 + +#define WELCOME_MSG MACHINE_NAME " Готов." +#define MSG_SD_INSERTED "Карта вставлена" +#define MSG_SD_REMOVED "Карта извлечена" +#define MSG_MAIN "Меню" +#define MSG_AUTOSTART "Автостарт" +#define MSG_DISABLE_STEPPERS "Выкл. двигатели" +#define MSG_AUTO_HOME "Парковка" +#define MSG_LEVEL_BED_HOMING "Homing XYZ" +#define MSG_LEVEL_BED_WAITING "Click to Begin" +#define MSG_LEVEL_BED_DONE "Leveling Done!" +#define MSG_LEVEL_BED_CANCEL "Cancel" +#define MSG_SET_HOME_OFFSETS "Запомнить парковку" +#define MSG_HOME_OFFSETS_APPLIED "Offsets applied" +#define MSG_SET_ORIGIN "Запомнить ноль" +#define MSG_PREHEAT_1 "Преднагрев PLA" +#define MSG_PREHEAT_1_N "Греть PLA Сопло " +#define MSG_PREHEAT_1_ALL "Греть PLA Все" +#define MSG_PREHEAT_1_BEDONLY "Греть PLA Стол" +#define MSG_PREHEAT_1_SETTINGS "Настройки PLA" +#define MSG_PREHEAT_2 "Преднагрев ABS" +#define MSG_PREHEAT_2_N "Греть ABS Сопло " +#define MSG_PREHEAT_2_ALL "Греть ABS Все" +#define MSG_PREHEAT_2_BEDONLY "Греть ABS Стол" +#define MSG_PREHEAT_2_SETTINGS "Настройки ABS" +#define MSG_COOLDOWN "Охлаждение" +#define MSG_SWITCH_PS_ON "Включить Питание" +#define MSG_SWITCH_PS_OFF "Отключить Питание" +#define MSG_EXTRUDE "Экструзия" +#define MSG_RETRACT "Втягивание" +#define MSG_MOVE_AXIS "Движение по осям" +#define MSG_MOVE_X "Движение по X" +#define MSG_MOVE_Y "Движение по Y" +#define MSG_MOVE_Z "Движение по Z" +#define MSG_MOVE_E "Экструдер" +#define MSG_MOVE_01MM "Движение XYZ 0.1mm" +#define MSG_MOVE_1MM "Движение XYZ 1mm" +#define MSG_MOVE_10MM "Движение XY 10mm" +#define MSG_LEVEL_BED "Калибровать стол" +#define MSG_SPEED "Скорость" +#define MSG_NOZZLE LCD_STR_THERMOMETER " Сопло" +#define MSG_BED LCD_STR_THERMOMETER " Стол" +#define MSG_FAN_SPEED "Кулер" +#define MSG_FLOW "Поток" +#define MSG_CONTROL "Настройки" +#define MSG_MIN LCD_STR_THERMOMETER " Минимум" +#define MSG_MAX LCD_STR_THERMOMETER " Максимум" +#define MSG_FACTOR LCD_STR_THERMOMETER " Фактор" +#define MSG_AUTOTEMP "Автотемпература" +#define MSG_ON "Вкл. " +#define MSG_OFF "Откл. " +#define MSG_PID_P "PID-P" +#define MSG_PID_I "PID-I" +#define MSG_PID_D "PID-D" +#define MSG_PID_C "PID-C" +#define MSG_ACC "Acc" +#define MSG_VXY_JERK "Vxy-jerk" +#define MSG_VZ_JERK "Vz-jerk" +#define MSG_VE_JERK "Ve-jerk" +#define MSG_VMAX "Vmax " +#define MSG_X "X" +#define MSG_Y "Y" +#define MSG_Z "Z" +#define MSG_E "E" +#define MSG_VMIN "Vmin" +#define MSG_VTRAV_MIN "VTrav min" +#define MSG_AMAX "Amax" +#define MSG_A_RETRACT "A-втягивание" +#define MSG_XSTEPS "X шаг/мм" +#define MSG_YSTEPS "Y шаг/мм" +#define MSG_ZSTEPS "Z шаг/мм" +#define MSG_ESTEPS "E шаг/мм" +#define MSG_TEMPERATURE "Температура" +#define MSG_MOTION "Механика" +#define MSG_VOLUMETRIC "Пруток" +#define MSG_VOLUMETRIC_ENABLED "E в mm3" +#define MSG_FILAMENT_DIAM "Диаметр прутка" +#define MSG_CONTRAST "Контраст LCD" +#define MSG_STORE_EPROM "Сохранить в EEPROM" +#define MSG_LOAD_EPROM "Считать из EEPROM" +#define MSG_RESTORE_FAILSAFE "Сброс EEPROM" +#define MSG_REFRESH "Обновить" +#define MSG_WATCH "Обзор" +#define MSG_PREPARE "Действия" +#define MSG_TUNE "Настройки" +#define MSG_PAUSE_PRINT "Пауза печати" +#define MSG_RESUME_PRINT "Продолжить печать" +#define MSG_STOP_PRINT "Остановить печать" +#define MSG_CARD_MENU "Обзор карты" +#define MSG_NO_CARD "Нет карты" +#define MSG_DWELL "Сон..." +#define MSG_USERWAIT "Ожиданиие" +#define MSG_RESUMING "Возобновление..." +#define MSG_PRINT_ABORTED "Отмена печати" +#define MSG_NO_MOVE "Нет движения." +#define MSG_KILLED "УБИТО." +#define MSG_STOPPED "ОСТАНОВЛЕНО." +#define MSG_CONTROL_RETRACT "Втягивание mm" +#define MSG_CONTROL_RETRACT_SWAP "Втяг. смены mm" +#define MSG_CONTROL_RETRACTF "Втягивание V" +#define MSG_CONTROL_RETRACT_ZLIFT "Втяг. прыжка mm" +#define MSG_CONTROL_RETRACT_RECOVER "Возврат +mm" +#define MSG_CONTROL_RETRACT_RECOVER_SWAP "Возврат смены +mm" +#define MSG_CONTROL_RETRACT_RECOVERF "Возврат V" +#define MSG_AUTORETRACT "Авто Втягивание" +#define MSG_FILAMENTCHANGE "Смена прутка" +#define MSG_INIT_SDCARD "Иниц. карту" +#define MSG_CNG_SDCARD "Сменить карту" +#define MSG_ZPROBE_OUT "Z датчик вне стола" +#define MSG_YX_UNHOMED "Паркуй X/Y перед Z" +#define MSG_ZPROBE_ZOFFSET "Смещение Z" +#define MSG_BABYSTEP_X "Babystep X" +#define MSG_BABYSTEP_Y "Babystep Y" +#define MSG_BABYSTEP_Z "Babystep Z" +#define MSG_ENDSTOP_ABORT "Сработал концевик" +#define MSG_HEATING_FAILED_LCD "Разогрев не удался" +#define MSG_ERR_REDUNDANT_TEMP "Ошибка:Слишком горячо" +#define MSG_THERMAL_RUNAWAY "THERMAL RUNAWAY" +#define MSG_ERR_MAXTEMP "Ошибка: Т макс." +#define MSG_ERR_MINTEMP "Ошибка: Т мин." +#define MSG_ERR_MAXTEMP_BED "Ошибка:Т макс.стол" +#define MSG_ERR_MINTEMP_BED "Ошибка:Т мин.стол" +#define MSG_HEATING "Нагреваю сопло..." +#define MSG_HEATING_COMPLETE "Нагрев выполнен" +#define MSG_BED_HEATING "Нагреваю стол" +#define MSG_BED_DONE "Стол разогрет" +#define MSG_DELTA_CALIBRATE "Калибровка Delta" +#define MSG_DELTA_CALIBRATE_X "Калибровать X" +#define MSG_DELTA_CALIBRATE_Y "Калибровать Y" +#define MSG_DELTA_CALIBRATE_Z "Калибровать Z" +#define MSG_DELTA_CALIBRATE_CENTER "Калибровать Center" + +#endif // LANGUAGE_RU_H diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_test.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_test.h new file mode 100644 index 00000000..99fa712a --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/language_test.h @@ -0,0 +1,237 @@ +/** + * 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 . + * + */ + +/** + * TEST + * + * LCD Menu Messages + * See also https://github.com/MarlinFirmware/Marlin/wiki/LCD-Language + * + */ +#ifndef LANGUAGE_TEST_H +#define LANGUAGE_TEST_H + +// Select ONE of the following Mappers. +// They decide what to do with a symbol in the area of [0x80:0xFF]. They take a symbol of this language file and make them point +// into an array with 128 cells, where they'll find the place of the symbol of the font in use. +// +// a.)For ASCII coded Language_xx.h files like (en) there are no occurrences of symbols above 0x7F so no mapper is needed. +// If such a symbol appears it is mapped directly into the font. This is the case for the language files we used until now, with all the STR_XX or +// "\xxx" symbols. All Symbols are only one byte long. +// b.) For Unicoded Language_xx.h files (currently ru, de and kana_utf8 ) the non ASCII [0x00-0x7F] symbols are represented by more than one byte. +// In the case of two bytes the first is pointing to a 'codepage' and the second to a place in the codepage. These codepages contain 64 symbols. +// So two of them can be mapped. For most of the European languages the necessary symbols are contained in the pages C2 and C3. Cyrillic uses D0 +// and D1. +// c.) For katakana (one of the Japanese symbol sets) Unicode uses 3 bytes. Here the second byte also points to a codepage and byte 3 to the symbol. +// I hope the pages E282 and E283 are sufficient to write katakana. +// Kanji (an other Japanese symbol set) uses far more than two codepages. So currently I don't see a chance to map the Unicodes. Its not +// impossible to have a close to direct mapping but will need giant conversion tables and fonts (we don't want to have in a embedded system). + +//#define MAPPER_C2C3 // For most European languages when language file is in utf8 +//#define MAPPER_D0D1 // For Cyrillic +//#define MAPPER_E382E383 // For Katakana +//#define MAPPER_NON // For direct ascii codes. Fall back mapper - if no other is defined. + +// Define SIMULATE_ROMFONT to see what is seen on the character based display defined in Configuration.h +//#define SIMULATE_ROMFONT + +// Select the better font for full graphic displays. +//#define DISPLAY_CHARSET_ISO10646_1 +//#define DISPLAY_CHARSET_ISO10646_5 +//#define DISPLAY_CHARSET_ISO10646_GREEK +//#define DISPLAY_CHARSET_ISO10646_KANA + + + +// next 5 lines select variants in this file only +#define DISPLAYTEST +//#define WEST +//#define CYRIL +//#define KANA + + +// TESTSTRINGS + +#define STRG_ASCII_2 " !\"#$%&'()*+,-./" +#define STRG_ASCII_3 "0123456789:;<=>?" +#define STRG_ASCII_4 "@ABCDEFGHIJKLMNO" +#define STRG_ASCII_5 "PQRSTUVWXYZ[\]^_" +#define STRG_ASCII_6 "`abcdefghijklmno" +#define STRG_ASCII_7 "pqrstuvwxyz{|}~" + +#define STRG_C2_8 "" +#define STRG_C2_9 "" +#define STRG_C2_a " ¡¢£¤¥¦§¨©ª«¬­®¯" +#define STRG_C2_b "°±²³´µ¶·¸¹º»¼½¾¿" +#define STRG_C3_8 "ÈÁÂÃÄÅÆÇÈÉÊËÌÍÎÏ" +#define STRG_C3_9 "ÐÑÒÓÔÕÖרÙÚÛÜÝÞß" +#define STRG_C3_a "àáâãäåæçèéêëìíîï" +#define STRG_C3_b "ðñòóôõö÷øùúûüýþÿ" + +#define STRG_D0_8 "ЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏ" +#define STRG_D0_9 "АБВГДЕЖЗИЙКЛМНОП" +#define STRG_D0_a "РСТУФХЦЧШЩЪЫЬЭЮЯ" +#define STRG_D0_b "абвгдежзийклмноп" +#define STRG_D1_8 "рстуфхцчшщъыьэюя" +#define STRG_D1_9 "ѐёђѓєѕіїјљњћќѝўџ" +#define STRG_D1_a "ѠѡѢѣѤѥѦѧѨѩѪѫѬѭѮѯ" +#define STRG_D1_b "ѰѱѲѳѴѵѶѷѸѹѺѻѼѽѾѿ" + +#define STRG_E382_8 "よめもゃやゅゆょよらりるれろゎわ" +#define STRG_E382_9 "ゐゑをんゔゕゖ゗゘゙゚゛ ゜ゝゞゟ" +#define STRG_E382_a "゠ァアィイゥウェエォオカガキギク" +#define STRG_E382_b "グケゲコゴサザシジスズセゼソゾタ" +#define STRG_E383_8 "トチヂッツヅテデトドナニヌネノハ" +#define STRG_E383_9 "バパヒビピフブプヘベペホボポマミ" +#define STRG_E383_a "ムメモャヤュユョヨラリルレロヮワ" +#define STRG_E383_b "ヰヱヲンヴヵヶヷヸヹヺ・ーヽヾヿ" + +#define STRG_OKTAL_0 "\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017" +#define STRG_OKTAL_1 "\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" +#define STRG_OKTAL_2 "\040\041\042\043\044\045\046\047\050\051\052\053\054\055\056\057" +#define STRG_OKTAL_3 "\060\061\062\063\064\065\066\067\070\071\072\073\074\075\076\077" +#define STRG_OKTAL_4 "\100\101\102\103\104\105\106\107\110\111\112\113\114\115\116\117" +#define STRG_OKTAL_5 "\120\121\122\123\124\125\126\127\130\131\132\133\134\135\136\137" +#define STRG_OKTAL_6 "\140\141\142\143\144\145\146\147\150\151\152\153\154\155\156\157" +#define STRG_OKTAL_7 "\160\161\162\163\164\165\166\167\170\171\172\173\174\175\176\177" +#define STRG_OKTAL_8 "\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217" +#define STRG_OKTAL_9 "\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237" +#define STRG_OKTAL_a "\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257" +#define STRG_OKTAL_b "\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277" +#define STRG_OKTAL_c "\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317" +#define STRG_OKTAL_d "\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337" +#define STRG_OKTAL_e "\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357" +#define STRG_OKTAL_f "\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377" + +#if ENABLED(DISPLAYTEST) + #define WELCOME_MSG "Language TEST" + + #define MSG_WATCH "Display test" + #define MSG_PREPARE STRG_OKTAL_b + #define MSG_CONTROL STRG_OKTAL_c +#endif + +#if ENABLED(WEST) + #define WELCOME_MSG "Language TEST" + + #define MSG_WATCH "\001\002\003\004\005\006\007\010\011" + #define MSG_PREPARE "UTF8" + #define MSG_CONTROL "ASCII" + + //#define MSG_MAIN ".." + #define MSG_DISABLE_STEPPERS STRG_C2_8 + #define MSG_AUTO_HOME STRG_C2_9 + #define MSG_SET_HOME_OFFSETS STRG_C2_a + #define MSG_PREHEAT_1 STRG_C2_b + #define MSG_PREHEAT_2 STRG_C3_8 + #define MSG_COOLDOWN STRG_C3_9 + #define MSG_SWITCH_PS_OFF STRG_C3_a + #define MSG_MOVE_AXIS STRG_C3_b + + #define MSG_MAIN STRG_OKTAL_2 + #define MSG_TEMPERATURE STRG_OKTAL_3 + #define MSG_MOTION STRG_OKTAL_4 + #define MSG_VOLUMETRIC STRG_OKTAL_5 + #define MSG_CONTRAST STRG_OKTAL_6 + #define MSG_RESTORE_FAILSAFE STRG_OKTAL_7 + + #define MSG_NOZZLE STRG_OKTAL_8 + #define MSG_FAN_SPEED STRG_OKTAL_9 + #define MSG_AUTOTEMP STRG_OKTAL_a + #define MSG_MIN STRG_OKTAL_b + #define MSG_MAX STRG_OKTAL_c + #define MSG_FACTOR STRG_OKTAL_d + #define MSG_PID_P STRG_OKTAL_e + #define MSG_PID_I STRG_OKTAL_f + +#endif + +#if ENABLED(CYRIL) + #define WELCOME_MSG "Language TEST" + + #define MSG_WATCH "\001\002\003\004\005\006\007\010\011" + #define MSG_PREPARE "UTF8" + #define MSG_CONTROL "ASCII" + + //#define MSG_MAIN ".." + #define MSG_DISABLE_STEPPERS STRG_D0_8 + #define MSG_AUTO_HOME STRG_D0_9 + #define MSG_SET_HOME_OFFSETS STRG_D0_a + #define MSG_PREHEAT_1 STRG_D0_b + #define MSG_PREHEAT_2 STRG_D1_8 + #define MSG_COOLDOWN STRG_D1_9 + #define MSG_SWITCH_PS_OFF STRG_D1_a + #define MSG_MOVE_AXIS STRG_D1_b + + #define MSG_MAIN STRG_OKTAL_2 + #define MSG_TEMPERATURE STRG_OKTAL_3 + #define MSG_MOTION STRG_OKTAL_4 + #define MSG_VOLUMETRIC STRG_OKTAL_5 + #define MSG_CONTRAST STRG_OKTAL_6 + #define MSG_RESTORE_FAILSAFE STRG_OKTAL_7 + + #define MSG_NOZZLE STRG_OKTAL_8 + #define MSG_FAN_SPEED STRG_OKTAL_9 + #define MSG_AUTOTEMP STRG_OKTAL_a + #define MSG_MIN STRG_OKTAL_b + #define MSG_MAX STRG_OKTAL_c + #define MSG_FACTOR STRG_OKTAL_d + #define MSG_PID_P STRG_OKTAL_e + #define MSG_PID_I STRG_OKTAL_f + +#endif + +#if ENABLED(KANA) + #define WELCOME_MSG "Language TEST" + + #define MSG_WATCH "\001\002\003\004\005\006\007\010\011" + #define MSG_PREPARE "UTF8" + #define MSG_CONTROL "ASCII" + + //#define MSG_MAIN ".." + #define MSG_DISABLE_STEPPERS STRG_E382_8 + #define MSG_AUTO_HOME STRG_E382_9 + #define MSG_SET_HOME_OFFSETS STRG_E382_a + #define MSG_PREHEAT_1 STRG_E382_b + #define MSG_PREHEAT_2 STRG_E383_8 + #define MSG_COOLDOWN STRG_E383_9 + #define MSG_SWITCH_PS_OFF STRG_E383_a + #define MSG_MOVE_AXIS STRG_E383_b + + #define MSG_MAIN STRG_OKTAL_2 + #define MSG_TEMPERATURE STRG_OKTAL_3 + #define MSG_MOTION STRG_OKTAL_4 + #define MSG_VOLUMETRIC STRG_OKTAL_5 + #define MSG_CONTRAST STRG_OKTAL_6 + #define MSG_RESTORE_FAILSAFE STRG_OKTAL_7 + + #define MSG_NOZZLE STRG_OKTAL_8 + #define MSG_FAN_SPEED STRG_OKTAL_9 + #define MSG_AUTOTEMP STRG_OKTAL_a + #define MSG_MIN STRG_OKTAL_b + #define MSG_MAX STRG_OKTAL_c + #define MSG_FACTOR STRG_OKTAL_d + #define MSG_PID_P STRG_OKTAL_e + #define MSG_PID_I STRG_OKTAL_f +#endif + +#endif // LANGUAGE_TEST_H diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/macros.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/macros.h new file mode 100644 index 00000000..5eec73e3 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/macros.h @@ -0,0 +1,121 @@ +/** + * 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 . + * + */ + +#ifndef MACROS_H +#define MACROS_H + +#define NUM_AXIS 4 + +#define FORCE_INLINE __attribute__((always_inline)) inline + +// Bracket code that shouldn't be interrupted +#ifndef CRITICAL_SECTION_START + #define CRITICAL_SECTION_START unsigned char _sreg = SREG; cli(); + #define CRITICAL_SECTION_END SREG = _sreg; +#endif + +// Remove compiler warning on an unused variable +#define UNUSED(x) (void) (x) + +// Macros to make a string from a macro +#define STRINGIFY_(M) #M +#define STRINGIFY(M) STRINGIFY_(M) + +// Macros for bit masks +#define TEST(n,b) (((n)&_BV(b))!=0) +#define SBI(n,b) (n |= _BV(b)) +#define CBI(n,b) (n &= ~_BV(b)) +#define SET_BIT(n,b,value) (n) ^= ((-value)^(n)) & (_BV(b)) + +// Macros for maths shortcuts +#ifndef M_PI + #define M_PI 3.14159265358979323846 +#endif +#define RADIANS(d) ((d)*M_PI/180.0) +#define DEGREES(r) ((r)*180.0/M_PI) +#define HYPOT(x,y) sqrt(sq(x)+sq(y)) + +// Macros to contrain values +#define NOLESS(v,n) do{ if (v < n) v = n; }while(0) +#define NOMORE(v,n) do{ if (v > n) v = n; }while(0) + +// Macros to support option testing +#define _CAT(a, ...) a ## __VA_ARGS__ +#define SWITCH_ENABLED_false 0 +#define SWITCH_ENABLED_true 1 +#define SWITCH_ENABLED_0 0 +#define SWITCH_ENABLED_1 1 +#define SWITCH_ENABLED_ 1 +#define ENABLED(b) _CAT(SWITCH_ENABLED_, b) +#define DISABLED(b) (!_CAT(SWITCH_ENABLED_, b)) + +#define NUMERIC(a) ((a) >= '0' && '9' >= (a)) +#define NUMERIC_SIGNED(a) (NUMERIC(a) || (a) == '-') +#define COUNT(a) (sizeof(a)/sizeof(*a)) + +// Macros for initializing arrays +#define ARRAY_6(v1, v2, v3, v4, v5, v6, args...) { v1, v2, v3, v4, v5, v6 } +#define ARRAY_5(v1, v2, v3, v4, v5, args...) { v1, v2, v3, v4, v5 } +#define ARRAY_4(v1, v2, v3, v4, args...) { v1, v2, v3, v4 } +#define ARRAY_3(v1, v2, v3, args...) { v1, v2, v3 } +#define ARRAY_2(v1, v2, args...) { v1, v2 } +#define ARRAY_1(v1, args...) { v1 } + +#define _ARRAY_N(N, args...) ARRAY_ ##N(args) +#define ARRAY_N(N, args...) _ARRAY_N(N, args) + +// 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 INCREMENT_(n) INC_ ##n +#define INCREMENT(n) INCREMENT_(n) + +// Macros for subtracting +#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 DECREMENT_(n) DEC_ ##n +#define DECREMENT(n) DECREMENT_(n) + +#define PIN_EXISTS(PN) (defined(PN ##_PIN) && PN ##_PIN >= 0) + +#define PENDING(NOW,SOON) ((long)(NOW-(SOON))<0) +#define ELAPSED(NOW,SOON) (!PENDING(NOW,SOON)) + +#define NOOP do{} while(0) + +#define CEILING(x,y) (((x) + (y) - 1) / (y)) + +#endif //__MACROS_H diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/mesh_bed_leveling.cpp b/trunk/Arduino/Marlin_K8600_1.1.0RC7/mesh_bed_leveling.cpp new file mode 100644 index 00000000..babad8aa --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/mesh_bed_leveling.cpp @@ -0,0 +1,37 @@ +/** + * 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 . + * + */ + +#include "mesh_bed_leveling.h" + +#if ENABLED(MESH_BED_LEVELING) + + mesh_bed_leveling mbl; + + mesh_bed_leveling::mesh_bed_leveling() { reset(); } + + void mesh_bed_leveling::reset() { + status = MBL_STATUS_NONE; + z_offset = 0; + memset(z_values, 0, sizeof(z_values)); + } + +#endif // MESH_BED_LEVELING diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/mesh_bed_leveling.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/mesh_bed_leveling.h new file mode 100644 index 00000000..eb668e1c --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/mesh_bed_leveling.h @@ -0,0 +1,105 @@ +/** + * 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 . + * + */ + +#include "Marlin.h" + +#if ENABLED(MESH_BED_LEVELING) + #define MESH_X_DIST ((MESH_MAX_X - (MESH_MIN_X))/(MESH_NUM_X_POINTS - 1)) + #define MESH_Y_DIST ((MESH_MAX_Y - (MESH_MIN_Y))/(MESH_NUM_Y_POINTS - 1)) + + class mesh_bed_leveling { + public: + uint8_t status; // Has Mesh and Is Active bits + float z_offset; + float z_values[MESH_NUM_Y_POINTS][MESH_NUM_X_POINTS]; + + mesh_bed_leveling(); + + void reset(); + + static FORCE_INLINE float get_probe_x(int8_t i) { return MESH_MIN_X + (MESH_X_DIST) * i; } + static FORCE_INLINE float get_probe_y(int8_t i) { return MESH_MIN_Y + (MESH_Y_DIST) * i; } + void set_z(const int8_t px, const int8_t py, const float z) { z_values[py][px] = z; } + + bool active() { return TEST(status, MBL_STATUS_ACTIVE_BIT); } + void set_active(bool onOff) { if (onOff) SBI(status, MBL_STATUS_ACTIVE_BIT); else CBI(status, MBL_STATUS_ACTIVE_BIT); } + bool has_mesh() { return TEST(status, MBL_STATUS_HAS_MESH_BIT); } + void set_has_mesh(bool onOff) { if (onOff) SBI(status, MBL_STATUS_HAS_MESH_BIT); else CBI(status, MBL_STATUS_HAS_MESH_BIT); } + + inline void zigzag(int8_t index, int8_t &px, int8_t &py) { + px = index % (MESH_NUM_X_POINTS); + py = index / (MESH_NUM_X_POINTS); + if (py & 1) px = (MESH_NUM_X_POINTS - 1) - px; // Zig zag + } + + void set_zigzag_z(int8_t index, float z) { + int8_t px, py; + zigzag(index, px, py); + set_z(px, py, z); + } + + int8_t cell_index_x(float x) { + int8_t cx = int(x - (MESH_MIN_X)) / (MESH_X_DIST); + return constrain(cx, 0, (MESH_NUM_X_POINTS) - 2); + } + + int8_t cell_index_y(float y) { + int8_t cy = int(y - (MESH_MIN_Y)) / (MESH_Y_DIST); + return constrain(cy, 0, (MESH_NUM_Y_POINTS) - 2); + } + + int8_t probe_index_x(float x) { + int8_t px = int(x - (MESH_MIN_X) + (MESH_X_DIST) / 2) / (MESH_X_DIST); + return (px >= 0 && px < (MESH_NUM_X_POINTS)) ? px : -1; + } + + int8_t probe_index_y(float y) { + int8_t py = int(y - (MESH_MIN_Y) + (MESH_Y_DIST) / 2) / (MESH_Y_DIST); + return (py >= 0 && py < (MESH_NUM_Y_POINTS)) ? py : -1; + } + + float calc_z0(float a0, float a1, float z1, float a2, float z2) { + float delta_z = (z2 - z1) / (a2 - a1); + float delta_a = a0 - a1; + return z1 + delta_a * delta_z; + } + + float get_z(float x0, float y0) { + int8_t cx = cell_index_x(x0), + cy = cell_index_y(y0); + if (cx < 0 || cy < 0) return z_offset; + float z1 = calc_z0(x0, + get_probe_x(cx), z_values[cy][cx], + get_probe_x(cx + 1), z_values[cy][cx + 1]); + float z2 = calc_z0(x0, + get_probe_x(cx), z_values[cy + 1][cx], + get_probe_x(cx + 1), z_values[cy + 1][cx + 1]); + float z0 = calc_z0(y0, + get_probe_y(cy), z1, + get_probe_y(cy + 1), z2); + return z0 + z_offset; + } + }; + + extern mesh_bed_leveling mbl; + +#endif // MESH_BED_LEVELING diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/nozzle.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/nozzle.h new file mode 100644 index 00000000..cce22db4 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/nozzle.h @@ -0,0 +1,195 @@ +/* + * 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 . + * + */ + +#ifndef __NOZZLE_H__ +#define __NOZZLE_H__ + +#include "Marlin.h" +#include "point_t.h" + +/** + * @brief Nozzle class + * + * @todo: Do not ignore the end.z value and allow XYZ movements + */ +class Nozzle { + private: + /** + * @brief Stroke clean pattern + * @details Wipes the nozzle back and forth in a linear movement + * + * @param start point_t defining the starting point + * @param end point_t defining the ending point + * @param strokes number of strokes to execute + */ + static void stroke( + __attribute__((unused)) point_t const &start, + __attribute__((unused)) point_t const &end, + __attribute__((unused)) uint8_t const &strokes + ) __attribute__((optimize ("Os"))) { + #if ENABLED(NOZZLE_CLEAN_FEATURE) + + #if ENABLED(NOZZLE_CLEAN_GOBACK) + // Store the current coords + point_t const initial = { + current_position[X_AXIS], + current_position[Y_AXIS], + current_position[Z_AXIS], + current_position[E_AXIS] + }; + #endif // NOZZLE_CLEAN_GOBACK + + // Move to the starting point + do_blocking_move_to_xy(start.x, start.y); + do_blocking_move_to_z(start.z); + + // Start the stroke pattern + for (uint8_t i = 0; i < (strokes >>1); i++) { + do_blocking_move_to_xy(end.x, end.y); + do_blocking_move_to_xy(start.x, start.y); + } + + #if ENABLED(NOZZLE_CLEAN_GOBACK) + // Move the nozzle to the initial point + do_blocking_move_to_z(initial.z); + do_blocking_move_to_xy(initial.x, initial.y); + #endif // NOZZLE_CLEAN_GOBACK + + #endif // NOZZLE_CLEAN_FEATURE + } + + /** + * @brief Zig-zag clean pattern + * @details Apply a zig-zag cleanning pattern + * + * @param start point_t defining the starting point + * @param end point_t defining the ending point + * @param strokes number of strokes to execute + * @param objects number of objects to create + */ + static void zigzag( + __attribute__((unused)) point_t const &start, + __attribute__((unused)) point_t const &end, + __attribute__((unused)) uint8_t const &strokes, + __attribute__((unused)) uint8_t const &objects + ) __attribute__((optimize ("Os"))) { + #if ENABLED(NOZZLE_CLEAN_FEATURE) + float A = fabs(end.y - start.y); // [twice the] Amplitude + float P = fabs(end.x - start.x) / (objects << 1); // Period + + // Don't allow impossible triangles + if (A <= 0.0f || P <= 0.0f ) return; + + #if ENABLED(NOZZLE_CLEAN_GOBACK) + // Store the current coords + point_t const initial = { + current_position[X_AXIS], + current_position[Y_AXIS], + current_position[Z_AXIS], + current_position[E_AXIS] + }; + #endif // NOZZLE_CLEAN_GOBACK + + for (uint8_t j = 0; j < strokes; j++) { + for (uint8_t i = 0; i < (objects << 1); i++) { + float const x = start.x + i * P; + float const y = start.y + (A/P) * (P - fabs(fmod((i*P), (2*P)) - P)); + + do_blocking_move_to_xy(x, y); + if (i == 0) do_blocking_move_to_z(start.z); + } + + for (int i = (objects << 1); i > -1; i--) { + float const x = start.x + i * P; + float const y = start.y + (A/P) * (P - fabs(fmod((i*P), (2*P)) - P)); + + do_blocking_move_to_xy(x, y); + } + } + + #if ENABLED(NOZZLE_CLEAN_GOBACK) + // Move the nozzle to the initial point + do_blocking_move_to_z(initial.z); + do_blocking_move_to_xy(initial.x, initial.y); + #endif // NOZZLE_CLEAN_GOBACK + + #endif // NOZZLE_CLEAN_FEATURE + } + + public: + /** + * @brief Clean the nozzle + * @details Starts the selected clean procedure pattern + * + * @param pattern one of the available patterns + * @param argument depends on the cleaning pattern + */ + static void clean( + __attribute__((unused)) uint8_t const &pattern, + __attribute__((unused)) uint8_t const &strokes, + __attribute__((unused)) uint8_t const &objects = 0 + ) __attribute__((optimize ("Os"))) { + #if ENABLED(NOZZLE_CLEAN_FEATURE) + switch (pattern) { + case 1: + Nozzle::zigzag( + NOZZLE_CLEAN_START_POINT, + NOZZLE_CLEAN_END_POINT, strokes, objects); + break; + + default: + Nozzle::stroke( + NOZZLE_CLEAN_START_POINT, + NOZZLE_CLEAN_END_POINT, strokes); + } + #endif // NOZZLE_CLEAN_FEATURE + } + + static void park( + __attribute__((unused)) uint8_t const &z_action + ) __attribute__((optimize ("Os"))) { + #if ENABLED(NOZZLE_PARK_FEATURE) + float const z = current_position[Z_AXIS]; + point_t const park = NOZZLE_PARK_POINT; + + switch(z_action) { + case 1: // force Z-park height + do_blocking_move_to_z(park.z); + break; + + case 2: // Raise by Z-park height + do_blocking_move_to_z( + (z + park.z > Z_MAX_POS) ? Z_MAX_POS : z + park.z); + break; + + default: // Raise to Z-park height if lower + if (current_position[Z_AXIS] < park.z) + do_blocking_move_to_z(park.z); + } + + do_blocking_move_to_xy(park.x, park.y); + + #endif // NOZZLE_PARK_FEATURE + } +}; + +#endif diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins.h new file mode 100644 index 00000000..628a292a --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins.h @@ -0,0 +1,476 @@ +/** + * 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 . + * + */ + +#ifndef PINS_H +#define PINS_H + +#if MB(GEN7_CUSTOM) + #include "pins_GEN7_CUSTOM.h" +#elif MB(GEN7_12) + #include "pins_GEN7_12.h" +#elif MB(GEN7_13) + #include "pins_GEN7_13.h" +#elif MB(GEN7_14) + #include "pins_GEN7_14.h" +#elif MB(CNCONTROLS_11) + #include "pins_CNCONTROLS_11.h" +#elif MB(CNCONTROLS_12) + #include "pins_CNCONTROLS_12.h" +#elif MB(CHEAPTRONIC) + #include "pins_CHEAPTRONIC.h" +#elif MB(SETHI) + #include "pins_SETHI.h" +#elif MB(RAMPS_OLD) + #include "pins_RAMPS_OLD.h" +#elif MB(RAMPS_13_EFB) + #define IS_RAMPS_EFB + #include "pins_RAMPS_13.h" +#elif MB(RAMPS_13_EEB) + #define IS_RAMPS_EEB + #include "pins_RAMPS_13.h" +#elif MB(RAMPS_13_EFF) + #define IS_RAMPS_EFF + #include "pins_RAMPS_13.h" +#elif MB(RAMPS_13_EEF) + #define IS_RAMPS_EEF + #include "pins_RAMPS_13.h" +#elif MB(RAMPS_13_SF) + #define IS_RAMPS_SF + #include "pins_RAMPS_13.h" +#elif MB(RAMPS_14_EFB) + #define IS_RAMPS_EFB + #include "pins_RAMPS.h" +#elif MB(RAMPS_14_EEB) + #define IS_RAMPS_EEB + #include "pins_RAMPS.h" +#elif MB(RAMPS_14_EFF) + #define IS_RAMPS_EFF + #include "pins_RAMPS.h" +#elif MB(RAMPS_14_EEF) + #define IS_RAMPS_EEF + #include "pins_RAMPS.h" +#elif MB(RAMPS_14_SF) + #define IS_RAMPS_SF + #include "pins_RAMPS.h" +#elif MB(GEN6) + #include "pins_GEN6.h" +#elif MB(GEN6_DELUXE) + #include "pins_GEN6_DELUXE.h" +#elif MB(SANGUINOLOLU_11) + #include "pins_SANGUINOLOLU_11.h" +#elif MB(SANGUINOLOLU_12) + #include "pins_SANGUINOLOLU_12.h" +#elif MB(MELZI) + #include "pins_MELZI.h" +#elif MB(STB_11) + #include "pins_STB_11.h" +#elif MB(AZTEEG_X1) + #include "pins_AZTEEG_X1.h" +#elif MB(MELZI_MAKR3D) + #include "pins_MELZI_MAKR3D.h" +#elif MB(AZTEEG_X3) + #include "pins_AZTEEG_X3.h" +#elif MB(AZTEEG_X3_PRO) + #include "pins_AZTEEG_X3_PRO.h" +#elif MB(ULTIMAKER) + #include "pins_ULTIMAKER.h" +#elif MB(ULTIMAKER_OLD) + #include "pins_ULTIMAKER_OLD.h" +#elif MB(ULTIMAIN_2) + #include "pins_ULTIMAIN_2.h" +#elif MB(K8600) + #include "pins_K8600.h" +#elif MB(K8800) + #include "pins_K8800.h" +#elif MB(3DRAG) + #include "pins_3DRAG.h" +#elif MB(K8200) + #include "pins_K8200.h" +#elif MB(K8400) + #include "pins_K8400.h" +#elif MB(TEENSYLU) + #include "pins_TEENSYLU.h" +#elif MB(RUMBA) + #include "pins_RUMBA.h" +#elif MB(PRINTRBOARD) + #include "pins_PRINTRBOARD.h" +#elif MB(PRINTRBOARD_REVF) + #include "pins_PRINTRBOARD_REVF.h" +#elif MB(BRAINWAVE) + #include "pins_BRAINWAVE.h" +#elif MB(BRAINWAVE_PRO) + #include "pins_BRAINWAVE_PRO.h" +#elif MB(SAV_MKI) + #include "pins_SAV_MKI.h" +#elif MB(TEENSY2) + #include "pins_TEENSY2.h" +#elif MB(GEN3_PLUS) + #include "pins_GEN3_PLUS.h" +#elif MB(GEN3_MONOLITHIC) + #include "pins_GEN3_MONOLITHIC.h" +#elif MB(MEGATRONICS) + #include "pins_MEGATRONICS.h" +#elif MB(MINITRONICS) + #include "pins_MINITRONICS.h" +#elif MB(MEGATRONICS_2) + #include "pins_MEGATRONICS_2.h" +#elif MB(MEGATRONICS_3) + #include "pins_MEGATRONICS_3.h" +#elif MB(OMCA_A) + #include "pins_OMCA_A.h" +#elif MB(OMCA) + #include "pins_OMCA.h" +#elif MB(RAMBO) + #include "pins_RAMBO.h" +#elif MB(MINIRAMBO) + #include "pins_MINIRAMBO.h" +#elif MB(ELEFU_3) + #include "pins_ELEFU_3.h" +#elif MB(5DPRINT) + #include "pins_5DPRINT.h" +#elif MB(LEAPFROG) + #include "pins_LEAPFROG.h" +#elif MB(BAM_DICE) + #include "pins_RAMPS.h" +#elif MB(BAM_DICE_DUE) + #include "pins_BAM_DICE_DUE.h" +#elif MB(FELIX2) + #include "pins_FELIX2.h" +#elif MB(MKS_BASE) + #include "pins_MKS_BASE.h" +#elif MB(RIGIDBOARD) + #include "pins_RIGIDBOARD.h" +#elif MB(RIGIDBOARD_V2) + #include "pins_RIGIDBOARD_V2.h" +#elif MB(MEGACONTROLLER) + #include "pins_MEGACONTROLLER.h" +#elif MB(BQ_ZUM_MEGA_3D) + #include "pins_BQ_ZUM_MEGA_3D.h" +#elif MB(99) + #include "pins_99.h" +#elif MB(AJ4P) + #include "pins_AJ4P.h" +#elif MB(MKS_13) + #include "pins_MKS_13.h" +#elif MB(SAINSMART_2IN1) + #include "pins_SAINSMART_2IN1.h" +#else + #error "Unknown MOTHERBOARD value set in Configuration.h" +#endif + +// Define certain undefined pins +#ifndef X_MS1_PIN + #define X_MS1_PIN -1 +#endif +#ifndef X_MS2_PIN + #define X_MS2_PIN -1 +#endif +#ifndef Y_MS1_PIN + #define Y_MS1_PIN -1 +#endif +#ifndef Y_MS2_PIN + #define Y_MS2_PIN -1 +#endif +#ifndef Z_MS1_PIN + #define Z_MS1_PIN -1 +#endif +#ifndef Z_MS2_PIN + #define Z_MS2_PIN -1 +#endif +#ifndef E0_MS1_PIN + #define E0_MS1_PIN -1 +#endif +#ifndef E0_MS2_PIN + #define E0_MS2_PIN -1 +#endif +#ifndef E1_MS1_PIN + #define E1_MS1_PIN -1 +#endif +#ifndef E1_MS2_PIN + #define E1_MS2_PIN -1 +#endif + +#ifndef FAN_PIN + #define FAN_PIN -1 +#endif +#ifndef FAN1_PIN + #define FAN1_PIN -1 +#endif +#ifndef FAN2_PIN + #define FAN2_PIN -1 +#endif + +#ifndef HEATER_0_PIN + #define HEATER_0_PIN -1 +#endif +#ifndef HEATER_1_PIN + #define HEATER_1_PIN -1 +#endif +#ifndef HEATER_2_PIN + #define HEATER_2_PIN -1 +#endif +#ifndef HEATER_3_PIN + #define HEATER_3_PIN -1 +#endif +#ifndef HEATER_BED_PIN + #define HEATER_BED_PIN -1 +#endif + +#ifndef TEMP_0_PIN + #define TEMP_0_PIN -1 +#endif +#ifndef TEMP_1_PIN + #define TEMP_1_PIN -1 +#endif +#ifndef TEMP_2_PIN + #define TEMP_2_PIN -1 +#endif +#ifndef TEMP_3_PIN + #define TEMP_3_PIN -1 +#endif +#ifndef TEMP_BED_PIN + #define TEMP_BED_PIN -1 +#endif + +#ifndef SD_DETECT_PIN + #define SD_DETECT_PIN -1 +#endif +#ifndef SDPOWER + #define SDPOWER -1 +#endif +#ifndef SDSS + #define SDSS -1 +#endif +#ifndef LED_PIN + #define LED_PIN -1 +#endif +#ifndef PS_ON_PIN + #define PS_ON_PIN -1 +#endif +#ifndef KILL_PIN + #define KILL_PIN -1 +#endif +#ifndef SUICIDE_PIN + #define SUICIDE_PIN -1 +#endif + +// Marlin needs to account for pins that equal -1 +#define marlinAnalogInputToDigitalPin(p) ((p) == -1 ? -1 : (p) + 0xA0) + +// List of pins which to ignore when asked to change by gcode, 0 and 1 are RX and TX, do not mess with those! +#define _E0_PINS E0_STEP_PIN, E0_DIR_PIN, E0_ENABLE_PIN, E0_MS1_PIN, E0_MS2_PIN, +#define _E1_PINS +#define _E2_PINS +#define _E3_PINS + +#if EXTRUDERS > 1 + #undef _E1_PINS + #define _E1_PINS E1_STEP_PIN, E1_DIR_PIN, E1_ENABLE_PIN, E1_MS1_PIN, E1_MS2_PIN, + #if EXTRUDERS > 2 + #undef _E2_PINS + #define _E2_PINS E2_STEP_PIN, E2_DIR_PIN, E2_ENABLE_PIN, + #if EXTRUDERS > 3 + #undef _E3_PINS + #define _E3_PINS E3_STEP_PIN, E3_DIR_PIN, E3_ENABLE_PIN, + #endif + #endif +#endif + +#define _H0_PINS HEATER_0_PIN, EXTRUDER_0_AUTO_FAN_PIN, marlinAnalogInputToDigitalPin(TEMP_0_PIN), +#define _H1_PINS +#define _H2_PINS +#define _H3_PINS + +#if HOTENDS > 1 + #undef _H1_PINS + #define _H1_PINS HEATER_1_PIN, EXTRUDER_1_AUTO_FAN_PIN, marlinAnalogInputToDigitalPin(TEMP_1_PIN), + #if HOTENDS > 2 + #undef _H2_PINS + #define _H2_PINS HEATER_2_PIN, EXTRUDER_2_AUTO_FAN_PIN, marlinAnalogInputToDigitalPin(TEMP_2_PIN), + #if HOTENDS > 3 + #undef _H3_PINS + #define _H3_PINS HEATER_3_PIN, EXTRUDER_3_AUTO_FAN_PIN, marlinAnalogInputToDigitalPin(TEMP_3_PIN), + #endif + #endif +#elif ENABLED(MIXING_EXTRUDER) + #undef _E1_PINS + #define _E1_PINS E1_STEP_PIN, E1_DIR_PIN, E1_ENABLE_PIN, + #if MIXING_STEPPERS > 2 + #undef _E2_PINS + #define _E2_PINS E2_STEP_PIN, E2_DIR_PIN, E2_ENABLE_PIN, + #if MIXING_STEPPERS > 3 + #undef _E3_PINS + #define _E3_PINS E3_STEP_PIN, E3_DIR_PIN, E3_ENABLE_PIN, + #endif + #endif +#endif + +#define BED_PINS HEATER_BED_PIN, marlinAnalogInputToDigitalPin(TEMP_BED_PIN), + +// +// Assign endstop pins for boards with only 3 connectors +// +#ifdef X_STOP_PIN + #if X_HOME_DIR < 0 + #define X_MIN_PIN X_STOP_PIN + #define X_MAX_PIN -1 + #else + #define X_MIN_PIN -1 + #define X_MAX_PIN X_STOP_PIN + #endif +#endif + +#ifdef Y_STOP_PIN + #if Y_HOME_DIR < 0 + #define Y_MIN_PIN Y_STOP_PIN + #define Y_MAX_PIN -1 + #else + #define Y_MIN_PIN -1 + #define Y_MAX_PIN Y_STOP_PIN + #endif +#endif + +#ifdef Z_STOP_PIN + #if Z_HOME_DIR < 0 + #define Z_MIN_PIN Z_STOP_PIN + #define Z_MAX_PIN -1 + #else + #define Z_MIN_PIN -1 + #define Z_MAX_PIN Z_STOP_PIN + #endif +#endif + +// +// Disable unused endstop / probe pins +// +#if ENABLED(DISABLE_Z_MIN_PROBE_ENDSTOP) || DISABLED(Z_MIN_PROBE_ENDSTOP) // Allow code to compile regardless of Z_MIN_PROBE_ENDSTOP setting. + #undef Z_MIN_PROBE_PIN + #define Z_MIN_PROBE_PIN -1 +#endif + +#if DISABLED(USE_XMAX_PLUG) + #undef X_MAX_PIN + #define X_MAX_PIN -1 +#endif + +#if DISABLED(USE_YMAX_PLUG) + #undef Y_MAX_PIN + #define Y_MAX_PIN -1 +#endif + +#if DISABLED(USE_ZMAX_PLUG) + #undef Z_MAX_PIN + #define Z_MAX_PIN -1 +#endif + +#if DISABLED(USE_XMIN_PLUG) + #undef X_MIN_PIN + #define X_MIN_PIN -1 +#endif + +#if DISABLED(USE_YMIN_PLUG) + #undef Y_MIN_PIN + #define Y_MIN_PIN -1 +#endif + +#if DISABLED(USE_ZMIN_PLUG) + #undef Z_MIN_PIN + #define Z_MIN_PIN -1 +#endif + +// +// Dual X-carriage, Dual Y, Dual Z support +// + +#define _X2_PINS +#define _Y2_PINS +#define _Z2_PINS + +#define __EPIN(p,q) E##p##_##q##_PIN +#define _EPIN(p,q) __EPIN(p,q) + +// The X2 axis, if any, should be the next open extruder port +#if ENABLED(DUAL_X_CARRIAGE) || ENABLED(X_DUAL_STEPPER_DRIVERS) + #ifndef X2_STEP_PIN + #define X2_STEP_PIN _EPIN(E_STEPPERS, STEP) + #define X2_DIR_PIN _EPIN(E_STEPPERS, DIR) + #define X2_ENABLE_PIN _EPIN(E_STEPPERS, ENABLE) + #endif + #undef _X2_PINS + #define _X2_PINS X2_STEP_PIN, X2_DIR_PIN, X2_ENABLE_PIN, + #define Y2_E_INDEX INCREMENT(E_STEPPERS) +#else + #define Y2_E_INDEX E_STEPPERS +#endif + +// The Y2 axis, if any, should be the next open extruder port +#if ENABLED(Y_DUAL_STEPPER_DRIVERS) + #ifndef Y2_STEP_PIN + #define Y2_STEP_PIN _EPIN(Y2_E_INDEX, STEP) + #define Y2_DIR_PIN _EPIN(Y2_E_INDEX, DIR) + #define Y2_ENABLE_PIN _EPIN(Y2_E_INDEX, ENABLE) + #endif + #undef _Y2_PINS + #define _Y2_PINS Y2_STEP_PIN, Y2_DIR_PIN, Y2_ENABLE_PIN, + #define Z2_E_INDEX INCREMENT(Y2_E_INDEX) +#else + #define Z2_E_INDEX Y2_E_INDEX +#endif + +// The Z2 axis, if any, should be the next open extruder port +#if ENABLED(Z_DUAL_STEPPER_DRIVERS) + #ifndef Z2_STEP_PIN + #define Z2_STEP_PIN _EPIN(Z2_E_INDEX, STEP) + #define Z2_DIR_PIN _EPIN(Z2_E_INDEX, DIR) + #define Z2_ENABLE_PIN _EPIN(Z2_E_INDEX, ENABLE) + #endif + #undef _Z2_PINS + #define _Z2_PINS Z2_STEP_PIN, Z2_DIR_PIN, Z2_ENABLE_PIN, +#endif + +#define SENSITIVE_PINS { 0, 1, \ + X_STEP_PIN, X_DIR_PIN, X_ENABLE_PIN, X_MIN_PIN, X_MAX_PIN, \ + Y_STEP_PIN, Y_DIR_PIN, Y_ENABLE_PIN, Y_MIN_PIN, Y_MAX_PIN, \ + Z_STEP_PIN, Z_DIR_PIN, Z_ENABLE_PIN, Z_MIN_PIN, Z_MAX_PIN, Z_MIN_PROBE_PIN, \ + PS_ON_PIN, HEATER_BED_PIN, FAN_PIN, FAN1_PIN, FAN2_PIN, CONTROLLERFAN_PIN, \ + _E0_PINS _E1_PINS _E2_PINS _E3_PINS BED_PINS \ + _H0_PINS _H1_PINS _H2_PINS _H3_PINS \ + _X2_PINS _Y2_PINS _Z2_PINS \ + X_MS1_PIN, X_MS2_PIN, Y_MS1_PIN, Y_MS2_PIN, Z_MS1_PIN, Z_MS2_PIN \ + } + +#define HAS_DIGIPOTSS (PIN_EXISTS(DIGIPOTSS)) + +#ifndef SCK_PIN + #define SCK_PIN SCK +#endif +#ifndef MISO_PIN + #define MISO_PIN MISO +#endif +#ifndef MOSI_PIN + #define MOSI_PIN MOSI +#endif +#ifndef SS_PIN + #define SS_PIN SS +#endif + +#endif //__PINS_H diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_3DRAG.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_3DRAG.h new file mode 100644 index 00000000..a3a61690 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_3DRAG.h @@ -0,0 +1,95 @@ +/** + * 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 . + * + */ + +/** + * 3DRAG (and K8200 / K8400) Arduino Mega with RAMPS v1.4 pin assignments + */ + +#ifndef BOARD_NAME + #define BOARD_NAME "3Drag" +#endif + +#ifndef DEFAULT_MACHINE_NAME + #define DEFAULT_MACHINE_NAME "3Drag" +#endif + +#ifndef DEFAULT_SOURCE_CODE_URL + #define DEFAULT_SOURCE_CODE_URL "http://3dprint.elettronicain.it/" +#endif + +#include "pins_RAMPS.h" + +#undef Z_ENABLE_PIN +#define Z_ENABLE_PIN 63 + +#undef X_MAX_PIN +#undef Y_MAX_PIN +#undef Z_MAX_PIN +#define X_MAX_PIN 2 +#define Y_MAX_PIN 15 +#define Z_MAX_PIN -1 + +#undef SDSS +#define SDSS 25//53 + +#undef FAN_PIN +#define FAN_PIN 8 + +#undef HEATER_1_PIN +#undef HEATER_2_PIN +#undef HEATER_BED_PIN +#define HEATER_0_PIN 10 +#define HEATER_1_PIN 12 +#define HEATER_2_PIN 6 + +#define HEATER_BED_PIN 9 // BED + +#if ENABLED(ULTRA_LCD) && ENABLED(NEWPANEL) + #undef BEEPER_PIN + #define BEEPER_PIN -1 + + #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 16 + #define BTN_EN2 17 + #define BTN_ENC 23 + +#else + + #define BEEPER_PIN 33 + +#endif // ULTRA_LCD && NEWPANEL diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_5DPRINT.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_5DPRINT.h new file mode 100644 index 00000000..dae7e203 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_5DPRINT.h @@ -0,0 +1,79 @@ +/** + * 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 . + * + */ + +/** + * 5DPrint D8 Driver board pin assignments + * + * https://bitbucket.org/makible/5dprint-d8-controller-board + */ + +#ifndef __AVR_AT90USB1286__ + #error "Oops! Make sure you have 'Teensy++ 2.0' selected from the 'Tools -> Boards' menu." +#endif + +#define DEFAULT_MACHINE_NAME "Makibox" +#define BOARD_NAME "5DPrint D8" + +#define LARGE_FLASH true + +#define X_STEP_PIN 0 +#define X_DIR_PIN 1 +#define X_ENABLE_PIN 23 +#define X_STOP_PIN 37 + +#define Y_STEP_PIN 2 +#define Y_DIR_PIN 3 +#define Y_ENABLE_PIN 19 +#define Y_STOP_PIN 36 + +#define Z_STEP_PIN 4 +#define Z_DIR_PIN 5 +#define Z_ENABLE_PIN 18 +#define Z_STOP_PIN 39 + +#define E0_STEP_PIN 6 +#define E0_DIR_PIN 7 +#define E0_ENABLE_PIN 17 + +#define HEATER_0_PIN 21 // Extruder +#define HEATER_BED_PIN 20 // Bed +// You may need to change FAN_PIN to 16 because Marlin isn't using fastio.h +// for the fan and Teensyduino uses a different pin mapping. +#define FAN_PIN 16 // Fan + +#define TEMP_0_PIN 1 // Extruder / Analog pin numbering +#define TEMP_BED_PIN 0 // Bed / Analog pin numbering + +// The SDSS pin uses a different pin mapping from file fastio.h +#define SDSS 20 + +// Microstepping pins +// Note that the pin mapping is not from fastio.h +// See Sd2PinMap.h for the pin configurations ??? +#define X_MS1_PIN 25 +#define X_MS2_PIN 26 +#define Y_MS1_PIN 9 +#define Y_MS2_PIN 8 +#define Z_MS1_PIN 7 +#define Z_MS2_PIN 6 +#define E0_MS1_PIN 5 +#define E0_MS2_PIN 4 diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_99.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_99.h new file mode 100644 index 00000000..6b7d1e89 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_99.h @@ -0,0 +1,53 @@ +/** + * 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 . + * + */ + +/** + * Board 99 pin assignments + */ +#define BOARD_NAME "99 Unknown" + +#define X_STEP_PIN 2 +#define X_DIR_PIN 3 +#define X_ENABLE_PIN -1 +#define X_STOP_PIN 16 + +#define Y_STEP_PIN 5 +#define Y_DIR_PIN 6 +#define Y_ENABLE_PIN -1 +#define Y_STOP_PIN 67 + +#define Z_STEP_PIN 62 +#define Z_DIR_PIN 63 +#define Z_ENABLE_PIN -1 +#define Z_STOP_PIN 59 + +#define E0_STEP_PIN 65 +#define E0_DIR_PIN 66 +#define E0_ENABLE_PIN -1 + +#define SDSS 53 +#define PS_ON_PIN 9 + +#define HEATER_0_PIN 13 +#define TEMP_0_PIN 6 // MUST USE ANALOG INPUT NUMBERING NOT DIGITAL OUTPUT NUMBERING!!!!!!!!! +#define HEATER_BED_PIN 4 +#define TEMP_BED_PIN 10 diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_A4JP.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_A4JP.h new file mode 100644 index 00000000..990abc30 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_A4JP.h @@ -0,0 +1,141 @@ +/** + * 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 . + * + */ + +/************************************************ + * Rambo pin assignments MODIFIED FOR A4JP + ************************************************/ + +#ifndef __AVR_ATmega2560__ + #error "Oops! Make sure you have 'Arduino Mega 2560' selected from the 'Tools -> Boards' menu." +#endif + +#define BOARD_NAME "AJ4P" + +// Servo support +#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 + +#if ENABLED(Z_PROBE_SLED) + #define SLED_PIN -1 +#endif + +//Fan_2 2 + +/***************** +#if ENABLED(ULTRA_LCD) + + #define KILL_PIN -1 //was 80 Glen maybe a mistake + +#endif // ULTRA_LCD */ + +#if ENABLED(VIKI2) || ENABLED(miniVIKI) + #define BEEPER_PIN 44 + // Pins for DOGM SPI LCD Support + #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 + + #if ENABLED(TEMP_STAT_LEDS) + #define STAT_LED_RED 22 + #define STAT_LED_BLUE 32 + #endif +#endif // VIKI2/miniVIKI + +#define FILWIDTH_PIN 3 // ANALOG NUMBERING + +/************************************************ + * Rambo pin assignments old + ************************************************/ + +#define LARGE_FLASH true +#define X_STEP_PIN 37 +#define X_DIR_PIN 48 +#define X_MIN_PIN 12 +#define X_MAX_PIN 24 +#define X_ENABLE_PIN 29 +#define X_MS1_PIN 40 +#define X_MS2_PIN 41 +#define Y_STEP_PIN 36 +#define Y_DIR_PIN 49 +#define Y_MIN_PIN 11 +#define Y_MAX_PIN 23 +#define Y_ENABLE_PIN 28 +#define Y_MS1_PIN 69 +#define Y_MS2_PIN 39 +#define Z_STEP_PIN 35 +#define Z_DIR_PIN 47 +#define Z_MIN_PIN 10 +#define Z_MAX_PIN 30 +#define Z_ENABLE_PIN 27 +#define Z_MS1_PIN 68 +#define Z_MS2_PIN 67 + +#define HEATER_BED_PIN 3 +#define TEMP_BED_PIN 7 //2014/02/04 0:T0 / 1:T1 / 2:T2 / 7:T3 +#define HEATER_0_PIN 9 +#define TEMP_0_PIN 0 +#define HEATER_1_PIN 7 + +#define E0_STEP_PIN 34 +#define E0_DIR_PIN 43 +#define E0_ENABLE_PIN 26 +#define E0_MS1_PIN 65 +#define E0_MS2_PIN 66 +#define E1_STEP_PIN 33 +#define E1_DIR_PIN 42 +#define E1_ENABLE_PIN 25 +#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 SDSS 53 +#define LED_PIN 13 +#define FAN_PIN 8 +#define PS_ON_PIN 4 +#define FAN_0_PIN 6 //Glen +#define FAN_1_PIN 2 //Glen + +// 2015/12/23 + +#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 HOME_PIN BTN_HOME diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_AZTEEG_X1.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_AZTEEG_X1.h new file mode 100644 index 00000000..8f87a7ea --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_AZTEEG_X1.h @@ -0,0 +1,30 @@ +/** + * 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 . + * + */ + +/** + * Azteeg X1 pin assignments + */ + +#define BOARD_NAME "Azteeg X1" + +#define SANGUINOLOLU_V_1_2 +#include "pins_SANGUINOLOLU_11.h" diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_AZTEEG_X3.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_AZTEEG_X3.h new file mode 100644 index 00000000..b33818ee --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_AZTEEG_X3.h @@ -0,0 +1,56 @@ +/** + * 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 . + * + */ + +/** + * AZTEEG_X3 Arduino Mega with RAMPS v1.4 pin assignments + */ + +#if HOTENDS > 2 + #error "Azteeg X3 supports up to 2 hotends. Comment this line to keep going." +#endif + +#define BOARD_NAME "Azteeg X3" + +#include "pins_RAMPS_13.h" + +#if ENABLED(VIKI2) || ENABLED(miniVIKI) + + #undef DOGLCD_A0 + #undef DOGLCD_CS + #undef BTN_ENC + #define DOGLCD_A0 31 + #define DOGLCD_CS 32 + #define BTN_ENC 12 + + #if ENABLED(TEMP_STAT_LEDS) + #undef STAT_LED_RED + #undef STAT_LED_BLUE + #define STAT_LED_RED 64 + #define STAT_LED_BLUE 63 + #endif + +#elif ENABLED(TEMP_STAT_LEDS) + + #define STAT_LED_RED 6 + #define STAT_LED_BLUE 11 + +#endif diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_AZTEEG_X3_PRO.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_AZTEEG_X3_PRO.h new file mode 100644 index 00000000..f4114c56 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_AZTEEG_X3_PRO.h @@ -0,0 +1,112 @@ +/** + * 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 . + * + */ + +/** + * AZTEEG_X3_PRO (Arduino Mega) pin assignments + */ + +#define BOARD_NAME "Azteeg X3 Pro" + +#include "pins_RAMPS.h" + +#undef FAN_PIN +#define FAN_PIN 6 //Part Cooling System + +#undef BEEPER_PIN +#define BEEPER_PIN 33 +#define CONTROLLERFAN_PIN 4 //Pin used for the fan to cool motherboard (-1 to disable) +//Fans/Water Pump to cool the hotend cool side. +#define EXTRUDER_0_AUTO_FAN_PIN 5 +#define EXTRUDER_1_AUTO_FAN_PIN 5 +#define EXTRUDER_2_AUTO_FAN_PIN 5 +#define EXTRUDER_3_AUTO_FAN_PIN 5 +// +//This section is to swap the MIN and MAX pins because the X3 Pro comes with only +//MIN endstops soldered onto the board. Delta code wants the homing endstops to be +//the MAX so I swapped them here. +// +#if ENABLED(DELTA) + #undef X_MIN_PIN + #undef X_MAX_PIN + #undef Y_MIN_PIN + #undef Y_MAX_PIN + #undef Z_MIN_PIN + #undef Z_MAX_PIN + + #define X_MIN_PIN 2 + #define X_MAX_PIN 3 + #define Y_MIN_PIN 15 + #define Y_MAX_PIN 14 + #define Z_MIN_PIN 19 + #define Z_MAX_PIN 18 +#endif + +#ifndef Z_MIN_PROBE_PIN + #define Z_MIN_PROBE_PIN 19 +#endif + +#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 E4_STEP_PIN 43 +#define E4_DIR_PIN 37 +#define E4_ENABLE_PIN 42 + +#undef HEATER_1_PIN +#undef HEATER_2_PIN +#undef HEATER_3_PIN +#define HEATER_1_PIN 9 +#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 + +#undef TEMP_2_PIN +#undef TEMP_3_PIN +#define TEMP_2_PIN 12 // ANALOG NUMBERING +#define TEMP_3_PIN 11 // ANALOG NUMBERING +#define TEMP_4_PIN 10 // ANALOG NUMBERING +#define TC1 4 // ANALOG NUMBERING Thermo couple on Azteeg X3Pro +#define TC2 5 // ANALOG NUMBERING Thermo couple on Azteeg X3Pro + +// +// These Servo pins are for when they are defined. Tested for usage with bed leveling +// on a Delta with 1 servo. Running through the Z servo endstop in code. +// Physical wire attachment was done on EXT1 on the GND, 5V, and D47 pins. +// +#undef SERVO0_PIN +#define SERVO0_PIN 47 + +#if ENABLED(VIKI2) || ENABLED(miniVIKI) + #undef SD_DETECT_PIN + #define SD_DETECT_PIN 49 // For easy adapter board +#elif ENABLED(TEMP_STAT_LEDS) + #define STAT_LED_RED 32 + #define STAT_LED_BLUE 35 +#endif diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_BAM_DICE_DUE.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_BAM_DICE_DUE.h new file mode 100644 index 00000000..0c5914f2 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_BAM_DICE_DUE.h @@ -0,0 +1,38 @@ +/** + * 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 . + * + */ + +/** + * BAM&DICE Due (Arduino Mega) pin assignments + */ + +#if HOTENDS > 2 + #error "2PrintBeta Due supports up to 2 hotends. Comment this line to keep going." +#endif + +#define BOARD_NAME "2PrintBeta Due" + +#include "pins_RAMPS.h" + +#undef TEMP_0_PIN +#undef TEMP_1_PIN +#define TEMP_0_PIN 9 // ANALOG NUMBERING +#define TEMP_1_PIN 11 // ANALOG NUMBERING diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_BQ_ZUM_MEGA_3D.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_BQ_ZUM_MEGA_3D.h new file mode 100644 index 00000000..c5509d4e --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_BQ_ZUM_MEGA_3D.h @@ -0,0 +1,69 @@ +/** + * 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 . + * + */ + +/** + * bq ZUM Mega 3D board definition + */ + +#ifndef __AVR_ATmega2560__ + #error "Oops! Make sure you have 'Arduino Mega 2560' selected from the 'Tools -> Boards' menu." +#endif + +#define BOARD_NAME "ZUM Mega 3D" + +#include "pins_RAMPS_13.h" + +#undef X_MAX_PIN +#define X_MAX_PIN 79 // 2 + +#undef Z_ENABLE_PIN +#define Z_ENABLE_PIN 77 // 62 + +#undef FAN_PIN +#define FAN_PIN 12 // 4 + +#undef HEATER_0_PIN +#define HEATER_0_PIN 9 // 10 + +#undef HEATER_1_PIN +#define HEATER_1_PIN 10 // 9 + +#undef TEMP_1_PIN +#define TEMP_1_PIN 14 // 15 + +#undef TEMP_BED_PIN +#define TEMP_BED_PIN 15 // 14 + +#define DIGIPOTSS_PIN 22 +#define DIGIPOT_CHANNELS { 4, 5, 3, 0, 1 } + +#define FAN1_PIN 7 + +#undef PS_ON_PIN // 12 +#define PS_ON_PIN 81 // External Power Supply + +#if ENABLED(AUTO_BED_LEVELING_FEATURE) + #undef Z_MIN_PIN + #undef Z_MAX_PIN + #define Z_MIN_PIN 19 // IND_S_5V + #define Z_MAX_PIN 18 // Z-MIN Label +#endif diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_BRAINWAVE.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_BRAINWAVE.h new file mode 100644 index 00000000..9dfeb3ab --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_BRAINWAVE.h @@ -0,0 +1,66 @@ +/** + * 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 . + * + */ + +/** + * Brainwave 1.0 pin assignments (AT90USB646) + * + * Requires hardware bundle for Arduino: + * https://github.com/unrepentantgeek/brainwave-arduino + */ + +#ifndef __AVR_AT90USB646__ + #error "Oops! Make sure you have 'Brainwave' selected from the 'Tools -> Boards' menu." +#endif + +#define BOARD_NAME "Brainwave" + +#define X_STEP_PIN 27 +#define X_DIR_PIN 29 +#define X_ENABLE_PIN 28 +#define X_STOP_PIN 7 +#define X_ATT_PIN 26 + +#define Y_STEP_PIN 31 +#define Y_DIR_PIN 33 +#define Y_ENABLE_PIN 32 +#define Y_STOP_PIN 6 +#define Y_ATT_PIN 30 + +#define Z_STEP_PIN 17 +#define Z_DIR_PIN 19 +#define Z_ENABLE_PIN 18 +#define Z_STOP_PIN 5 +#define Z_ATT_PIN 16 + +#define E0_STEP_PIN 21 +#define E0_DIR_PIN 23 +#define E0_ENABLE_PIN 22 +#define E0_ATT_PIN 20 + +#define HEATER_0_PIN 4 // Extruder +#define HEATER_BED_PIN 38 // Bed +#define FAN_PIN 3 // Fan + +#define TEMP_0_PIN 7 // Extruder / Analog pin numbering +#define TEMP_BED_PIN 6 // Bed / Analog pin numbering + +#define LED_PIN 39 diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_BRAINWAVE_PRO.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_BRAINWAVE_PRO.h new file mode 100644 index 00000000..cba0d469 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_BRAINWAVE_PRO.h @@ -0,0 +1,77 @@ +/** + * 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 . + * + */ + +/** + * Brainwave Pro pin assignments (AT90USB1286) + * + * Requires hardware bundle for Arduino: + * https://github.com/unrepentantgeek/brainwave-arduino + */ + +#ifndef __AVR_AT90USB1286__ + #error "Oops! Make sure you have 'Brainwave Pro' selected from the 'Tools -> Boards' menu." +#endif + +#include "fastio.h" + +#ifndef AT90USBxx_TEENSYPP_ASSIGNMENTS // use Teensyduino Teensy++2.0 pin assignments instead of Marlin alphabetical. + #error "Uncomment #define AT90USBxx_TEENSYPP_ASSIGNMENTS in fastio.h for this config" +#endif + +#define BOARD_NAME "Brainwave Pro" + +#define LARGE_FLASH true + +#define X_STOP_PIN 47 +#define Y_STOP_PIN 18 +#define Z_MAX_PIN 36 +#ifndef Z_MIN_PROBE_PIN + #define Z_MIN_PROBE_PIN 17 +#endif + +#define X_STEP_PIN 33 +#define X_DIR_PIN 32 +#define X_ENABLE_PIN 11 + +#define Y_STEP_PIN 31 +#define Y_DIR_PIN 30 +#define Y_ENABLE_PIN 8 + +#define Z_STEP_PIN 29 +#define Z_DIR_PIN 28 +#define Z_ENABLE_PIN 37 + +#define E0_STEP_PIN 35 +#define E0_DIR_PIN 34 +#define E0_ENABLE_PIN 13 + +#define HEATER_0_PIN 15 +#define HEATER_BED_PIN 14 // Bed +#define FAN_PIN 16 // Fan, PWM + +#define TEMP_0_PIN 2 // Extruder / Analog pin numbering +#define TEMP_1_PIN 1 // Spare / Analog pin numbering +#define TEMP_BED_PIN 0 // Bed / Analog pin numbering + +#define SDSS 20 +#define LED_PIN 19 +#define SD_DETECT_PIN 12 diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_CHEAPTRONIC.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_CHEAPTRONIC.h new file mode 100644 index 00000000..2fbb4e83 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_CHEAPTRONIC.h @@ -0,0 +1,87 @@ +/** + * 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 . + * + */ + +/** + * Cheaptronic v1.0 pin assignments + */ + +#ifndef __AVR_ATmega2560__ + #error "Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu." +#endif + +#define BOARD_NAME "Cheaptronic v1.0" +#define LARGE_FLASH true + +// X motor stepper +#define X_STEP_PIN 14 +#define X_DIR_PIN 15 +#define X_ENABLE_PIN 24 + +// Y motor stepper +#define Y_STEP_PIN 35 +#define Y_DIR_PIN 36 +#define Y_ENABLE_PIN 31 + +// Z motor stepper +#define Z_STEP_PIN 40 +#define Z_DIR_PIN 41 +#define Z_ENABLE_PIN 37 + +// XYZ endstops +#define X_STOP_PIN 3 +#define Y_STOP_PIN 2 +#define Z_STOP_PIN 5 + +// Extruder 0 stepper +#define E0_STEP_PIN 26 +#define E0_DIR_PIN 28 +#define E0_ENABLE_PIN 25 + +// Extruder 1 stepper +#define E1_STEP_PIN 33 +#define E1_DIR_PIN 34 +#define E1_ENABLE_PIN 30 + + +#define HEATER_0_PIN 19 // EXTRUDER 1 +#define HEATER_1_PIN 23 // EXTRUDER 2 +#define HEATER_BED_PIN 22 + +// Temperature sensors +#define TEMP_0_PIN 15 +#define TEMP_1_PIN 14 +#define TEMP_BED_PIN 13 + +// Cheaptronic v1.0 doesn't support LCD +#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 + +// Cheaptronic v1.0 doesn't support keypad +#define BTN_EN1 -1 +#define BTN_EN2 -1 +#define BTN_ENC -1 + +// Cheaptronic v1.0 doesn't use this diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_CNCONTROLS_11.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_CNCONTROLS_11.h new file mode 100644 index 00000000..1de35a2c --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_CNCONTROLS_11.h @@ -0,0 +1,101 @@ +/** + * CartesioV11 pin assignments + */ + +#if !defined(__AVR_ATmega1280__) && !defined(__AVR_ATmega2560__) + #error Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu. +#endif + +#define BOARD_NAME "CN Controls V11" + +//#define LARGE_FLASH true + +#define X_ENABLE_PIN 35 +#define X_STEP_PIN 34 +#define X_DIR_PIN 36 +#define X_MIN_PIN 43 +#define X_MAX_PIN -1 + +#define Y_ENABLE_PIN 38 +#define Y_STEP_PIN 37 +#define Y_DIR_PIN 39 +#define Y_MIN_PIN 45 +#define Y_MAX_PIN -1 + +#define Z_ENABLE_PIN 41 +#define Z_STEP_PIN 40 +#define Z_DIR_PIN 48 +#define Z_MIN_PIN 42 +#define Z_MAX_PIN -1 + +#define E0_ENABLE_PIN 3 +#define E0_STEP_PIN 29 +#define E0_DIR_PIN 28 +#define HEATER_0_PIN 5 +#define TEMP_0_PIN 0 // ANALOG INPUT !! + +#define E1_ENABLE_PIN 60 +#define E1_STEP_PIN 61 +#define E1_DIR_PIN 62 +#define HEATER_1_PIN 58 +#define TEMP_1_PIN 3 // 3 for tool2 -> 2 for chambertemp + +#define E2_ENABLE_PIN 16 +#define E2_STEP_PIN 15 +#define E2_DIR_PIN 14 +#define HEATER_2_PIN 64 +#define TEMP_2_PIN 2 // 9 for tool3 -> 2 for chambertemp + +#define E3_ENABLE_PIN 47 +#define E3_STEP_PIN 44 +#define E3_DIR_PIN 49 +#define HEATER_3_PIN 46 +#define TEMP_3_PIN 11 // 11 for tool4 -> 2 for chambertemp + +#define HEATER_BED_PIN 2 +#define TEMP_BED_PIN 1 // ANALOG INPUT !! + +// 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 TEMP_CHAMBER_PIN 2 // ANALOG INPUT !! +//#define FIL_RUNOUT_PIN -1 +//#define PWM_1_PIN 11 +//#define PWM_2_PIN 10 +//#define SPARE_IO 12 +//#define FAN_PIN 7 // common PWM pin for all tools + +// User interface +#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 + +// The encoder and click button +#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 UI1 31 +//#define UI2 22 + +// Other +#define SDSS 53 +#define SD_DETECT_PIN 13 +#define STAT_LED_BLUE -1 +#define STAT_LED_RED 31 diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_CNCONTROLS_12.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_CNCONTROLS_12.h new file mode 100644 index 00000000..cb338346 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_CNCONTROLS_12.h @@ -0,0 +1,105 @@ +/** + * CartesioV12 pin assignments + */ + +#if !defined(__AVR_ATmega1280__) && !defined(__AVR_ATmega2560__) + #error Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu. +#endif + +#define BOARD_NAME "CN Controls V12" + +//#define LARGE_FLASH true + +#define X_ENABLE_PIN 26 +#define X_STEP_PIN 25 +#define X_DIR_PIN 27 +#define X_MIN_PIN 19 +#define X_MAX_PIN -1 + +#define Y_ENABLE_PIN 29 +#define Y_STEP_PIN 28 +#define Y_DIR_PIN 30 +#define Y_MIN_PIN 22 +#define Y_MAX_PIN -1 + +#define Z_ENABLE_PIN 32 +#define Z_STEP_PIN 31 +#define Z_DIR_PIN 33 +#define Z_MIN_PIN 23 +#define Z_MAX_PIN -1 + +#define E0_ENABLE_PIN 58 +#define E0_STEP_PIN 57 +#define E0_DIR_PIN 55 +#define HEATER_0_PIN 11 +#define TEMP_0_PIN 0 // ANALOG INPUT !! + +#define E1_ENABLE_PIN 60 +#define E1_STEP_PIN 61 +#define E1_DIR_PIN 62 +#define HEATER_1_PIN 9 +#define TEMP_1_PIN 9 // 9 for tool2 -> 13 for chambertemp + +#define E2_ENABLE_PIN 44 +#define E2_STEP_PIN 46 +#define E2_DIR_PIN 66 +#define HEATER_2_PIN 6 +#define TEMP_2_PIN 13 // 10 for tool3 -> 13 for chambertemp + +#define E3_ENABLE_PIN 47 +#define E3_STEP_PIN 45 +#define E3_DIR_PIN 69 +#define HEATER_3_PIN 3 +#define TEMP_3_PIN 11 // 11 for tool4 -> 13 for chambertemp + +#define HEATER_BED_PIN 24 +#define TEMP_BED_PIN 14 // ANALOG INPUT !! + +// 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 + +// Common I/O + +//#define TEMP_CHAMBER_PIN 13 // ANALOG INPUT !! +#define FIL_RUNOUT_PIN 18 +//#define PWM_1_PIN 12 +//#define PWM_2_PIN 13 +//#define SPARE_IO 17 +#define FAN_PIN 5 // 5 is PWMtool3 -> 7 is common PWM pin for all tools + +// User interface +#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 LCD_SCREEN_ROT_180 + +// The encoder and click button +#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 UI1 43 +//#define UI2 37 + +// Other +#define SDSS 53 +#define SD_DETECT_PIN 15 +#define STAT_LED_BLUE -1 +#define STAT_LED_RED 10 // TOOL_0_PWM_PIN diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_ELEFU_3.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_ELEFU_3.h new file mode 100644 index 00000000..2b8e64d8 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_ELEFU_3.h @@ -0,0 +1,125 @@ +/** + * 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 . + * + */ + +/** + * Elefu RA Board Pin Assignments + */ + +#ifndef __AVR_ATmega2560__ + #error "Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu." +#endif + +#define BOARD_NAME "Elefu Ra v3" + +#define X_STEP_PIN 49 +#define X_DIR_PIN 13 +#define X_ENABLE_PIN 48 +#define X_MIN_PIN 35 +#define X_MAX_PIN 34 + +#define Y_STEP_PIN 11 +#define Y_DIR_PIN 9 +#define Y_ENABLE_PIN 12 +#define Y_MIN_PIN 33 +#define Y_MAX_PIN 32 + +#define Z_STEP_PIN 7 +#define Z_DIR_PIN 6 +#define Z_ENABLE_PIN 8 +#define Z_MIN_PIN 31 +#define Z_MAX_PIN 30 + +#define E2_STEP_PIN 43 +#define E2_DIR_PIN 47 +#define E2_ENABLE_PIN 42 + +#define E1_STEP_PIN 18 +#define E1_DIR_PIN 19 +#define E1_ENABLE_PIN 38 + +#define E0_STEP_PIN 40 +#define E0_DIR_PIN 41 +#define E0_ENABLE_PIN 37 + +#define FAN_PIN 16 //5V PWM + +#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 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 TEMP_0_PIN 3 //ANALOG NUMBERING +#define TEMP_1_PIN 2 //ANALOG NUMBERING +#define TEMP_2_PIN 1 //ANALOG NUMBERING +#define TEMP_BED_PIN 0 //ANALOG NUMBERING + +#define BEEPER_PIN 36 + +// M240 Triggers a camera by emulating a Canon RC-1 Remote +// Data from: http://www.doc-diy.net/photo/rc-1_hacked/ +#define PHOTOGRAPH_PIN 29 + +#if ENABLED(RA_CONTROL_PANEL) + + #define SDSS 53 + #define SD_DETECT_PIN 28 + + #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 + + //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 //bit 3 on port A + #define TLC_CLOCK_PORT &PORTA //bit 3 on port A + + #define TLC_BLANK_BIT 1 //bit 1 on port A + #define TLC_BLANK_PORT &PORTA //bit 1 on port A + + #define TLC_DATA_BIT 2 //bit 2 on port A + #define TLC_DATA_PORT &PORTA //bit 2 on port A + + #define TLC_XLAT_BIT 0 //bit 0 on port A + #define TLC_XLAT_PORT &PORTA //bit 0 on port A + + //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 + + //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. + //NOTE: the array should be 8 long for every TLC you have. These defaults assume (2) TLCs. + #define TRANS_ARRAY {0, 1, 2, 3, 4, 5, 6, 7, 15, 14, 13, 12, 11, 10, 9, 8} //forwards + //#define TRANS_ARRAY {7, 6, 5, 4, 3, 2, 1, 0, 8, 9, 10, 11, 12, 13, 14, 15} //backwards +#endif // RA_DISCO diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_FELIX2.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_FELIX2.h new file mode 100644 index 00000000..31906b51 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_FELIX2.h @@ -0,0 +1,47 @@ +/** + * 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 . + * + */ + +/** + * FELIXprinters v2.0/3.0 (RAMPS v1.4) pin assignments + */ + +#if HOTENDS > 2 + #error "Felix 2.0+ supports up to 2 hotends. Comment this line to keep going." +#endif + +#define BOARD_NAME "Felix 2.0+" + +// Power outputs EFBF or EFBE +#define MOSFET_D_PIN 7 + +#include "pins_RAMPS.h" + +#undef SDPOWER +#define SDPOWER 1 + +#define PS_ON_PIN 12 + +#if ENABLED(ULTRA_LCD) && ENABLED(NEWPANEL) + + #define SD_DETECT_PIN 6 + +#endif // NEWPANEL && ULTRA_LCD diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_GEN3_MONOLITHIC.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_GEN3_MONOLITHIC.h new file mode 100644 index 00000000..85d5b3fa --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_GEN3_MONOLITHIC.h @@ -0,0 +1,69 @@ +/** + * 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 . + * + */ + +/** + * Gen3 Monolithic Electronics pin assignments + */ + +#ifndef __AVR_ATmega644P__ + #error "Oops! Make sure you have 'Sanguino' selected from the 'Tools -> Boards' menu." +#endif + +#define BOARD_NAME "Gen3 Monolithic" +#define DEBUG_PIN 0 + +// x axis +#define X_STEP_PIN 15 +#define X_DIR_PIN 18 +#define X_MIN_PIN 20 +// Alex Checar #define X_STOP_PIN 20 +#define X_ENABLE_PIN 24 // actually uses Y_enable_pin +#define X_MAX_PIN -1 + +// y axis +#define Y_STEP_PIN 23 +#define Y_DIR_PIN 22 +#define Y_MIN_PIN 25 +// Alex Checar #define Y_STOP_PIN 25 +#define Y_ENABLE_PIN 24 // shared with X_enable_pin +#define Y_MAX_PIN -1 + +// z axis +#define Z_STEP_PIN 27 +#define Z_DIR_PIN 28 +#define Z_MIN_PIN 30 +// Alex Checar #define Z_STOP_PIN 30 +#define Z_ENABLE_PIN 29 +#define Z_MAX_PIN -1 + +// extruder pins +#define E0_STEP_PIN 12 +#define E0_DIR_PIN 17 +#define E0_ENABLE_PIN 3 + +#define HEATER_0_PIN 16 +#define TEMP_0_PIN 0 + +// pin for controlling the PSU. +#define PS_ON_PIN 14 // Alex, Do this work on the card? + +// Alex extras from Gen3+ diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_GEN3_PLUS.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_GEN3_PLUS.h new file mode 100644 index 00000000..7889a010 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_GEN3_PLUS.h @@ -0,0 +1,60 @@ +/** + * 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 . + * + */ + +/** + * Gen3+ pin assignments + */ + +#if !defined(__AVR_ATmega644P__) && !defined(__AVR_ATmega1284P__) + #error "Oops! Make sure you have 'Sanguino' selected from the 'Tools -> Boards' menu." +#endif + +#define BOARD_NAME "Gen3+" + +#define X_STEP_PIN 15 +#define X_DIR_PIN 18 +#define X_STOP_PIN 20 + +#define Y_STEP_PIN 23 +#define Y_DIR_PIN 22 +#define Y_STOP_PIN 25 + +#define Z_STEP_PIN 27 +#define Z_DIR_PIN 28 +#define Z_STOP_PIN 30 + +#define E0_STEP_PIN 17 +#define E0_DIR_PIN 21 + +#define PS_ON_PIN 14 + +#define HEATER_0_PIN 12 // (extruder) + +#define HEATER_BED_PIN 16 // (bed) +#define X_ENABLE_PIN 19 +#define Y_ENABLE_PIN 24 +#define Z_ENABLE_PIN 29 +#define E0_ENABLE_PIN 13 + +#define TEMP_0_PIN 0 // MUST USE ANALOG INPUT NUMBERING NOT DIGITAL OUTPUT NUMBERING!!!!!!!!! (pin 33 extruder) +#define TEMP_BED_PIN 5 // MUST USE ANALOG INPUT NUMBERING NOT DIGITAL OUTPUT NUMBERING!!!!!!!!! (pin 34 bed) +#define SDSS 4 diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_GEN6.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_GEN6.h new file mode 100644 index 00000000..ae3d33a9 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_GEN6.h @@ -0,0 +1,75 @@ +/** + * 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 . + * + */ + +/** + * Gen6 pin assignments + */ + +#ifndef __AVR_ATmega644P__ + #ifndef __AVR_ATmega1284P__ + #error "Oops! Make sure you have 'Sanguino' selected from the 'Tools -> Boards' menu." + #endif +#endif + +#ifndef BOARD_NAME + #define BOARD_NAME "Gen6" +#endif + +//x axis pins +#define X_STEP_PIN 15 +#define X_DIR_PIN 18 +#define X_ENABLE_PIN 19 +#define X_STOP_PIN 20 + +//y axis pins +#define Y_STEP_PIN 23 +#define Y_DIR_PIN 22 +#define Y_ENABLE_PIN 24 +#define Y_STOP_PIN 25 + +//z axis pins +#define Z_STEP_PIN 27 +#define Z_DIR_PIN 28 +#define Z_ENABLE_PIN 29 +#define Z_STOP_PIN 30 + +//extruder pins +#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 TEMP_0_PIN 5 //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 //changed @ rkoeppl 20110410 +#endif + +#define SDSS 17 +//our pin for debugging. + +#define DEBUG_PIN 0 + +//our RS485 pins +#define TX_ENABLE_PIN 12 +#define RX_ENABLE_PIN 13 diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_GEN6_DELUXE.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_GEN6_DELUXE.h new file mode 100644 index 00000000..b1a1037e --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_GEN6_DELUXE.h @@ -0,0 +1,29 @@ +/** + * 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 . + * + */ + +/** + * Gen6 Deluxe pin assignments + */ + +#define BOARD_NAME "Gen6 Deluxe" + +#include "pins_GEN6.h" diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_GEN7_12.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_GEN7_12.h new file mode 100644 index 00000000..1e59ae6f --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_GEN7_12.h @@ -0,0 +1,87 @@ +/** + * 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 . + * + */ + +/** + * Gen7 v1.1, v1.2, v1.3 pin assignments + */ + +#if !defined(__AVR_ATmega644P__) && !defined(__AVR_ATmega644__) && !defined(__AVR_ATmega1284P__) + #error "Oops! Make sure you have 'Gen7' selected from the 'Tools -> Boards' menu." +#endif + +#ifndef BOARD_NAME + #define BOARD_NAME "Gen7 v1.1 / 1.2" +#endif + +#ifndef GEN7_VERSION + #define GEN7_VERSION 12 // v1.x +#endif + +//x axis pins +#define X_STEP_PIN 19 +#define X_DIR_PIN 18 +#define X_ENABLE_PIN 24 +#define X_STOP_PIN 7 + +//y axis pins +#define Y_STEP_PIN 23 +#define Y_DIR_PIN 22 +#define Y_ENABLE_PIN 24 +#define Y_STOP_PIN 5 + +//z axis pins +#define Z_STEP_PIN 26 +#define Z_DIR_PIN 25 +#define Z_ENABLE_PIN 24 +#define Z_MIN_PIN 1 +#define Z_MAX_PIN 0 + +//extruder pins +#define E0_STEP_PIN 28 +#define E0_DIR_PIN 27 +#define E0_ENABLE_PIN 24 + +#define TEMP_0_PIN 1 +#define TEMP_BED_PIN 2 + +#define HEATER_0_PIN 4 +#define HEATER_BED_PIN 3 + + +// Gen7 v1.3 removed the fan pin +#if GEN7_VERSION < 13 + #define FAN_PIN 31 +#endif + +#define PS_ON_PIN 15 + +//All these generations of Gen7 supply thermistor power +//via PS_ON, so ignore bad thermistor readings +#define BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE + +//our pin for debugging. +#define DEBUG_PIN 0 + +//our RS485 pins +#define TX_ENABLE_PIN 12 +#define RX_ENABLE_PIN 13 + diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_GEN7_13.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_GEN7_13.h new file mode 100644 index 00000000..2365ae8b --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_GEN7_13.h @@ -0,0 +1,30 @@ +/** + * 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 . + * + */ + +/** + * Gen7 v1.3 pin assignments + */ + +#define BOARD_NAME "Gen7 v1.3" + +#define GEN7_VERSION 13 // v1.3 +#include "pins_GEN7_12.h" diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_GEN7_14.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_GEN7_14.h new file mode 100644 index 00000000..87ccb601 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_GEN7_14.h @@ -0,0 +1,71 @@ +/** + * 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 . + * + */ + +/** + * Gen7 v1.4 pin assignments + */ + +#if !defined(__AVR_ATmega644P__) && !defined(__AVR_ATmega644__) && !defined(__AVR_ATmega1284P__) + #error "Oops! Make sure you have 'Gen7' selected from the 'Tools -> Boards' menu." +#endif + +#define BOARD_NAME "Gen7 v1.4" + +#define GEN7_VERSION 14 // v1.4 + +//x axis pins +#define X_STEP_PIN 29 +#define X_DIR_PIN 28 +#define X_ENABLE_PIN 25 +#define X_STOP_PIN 0 + +//y axis pins +#define Y_STEP_PIN 27 +#define Y_DIR_PIN 26 +#define Y_ENABLE_PIN 25 +#define Y_STOP_PIN 1 + +//z axis pins +#define Z_STEP_PIN 23 +#define Z_DIR_PIN 22 +#define Z_ENABLE_PIN 25 +#define Z_STOP_PIN 2 + +//extruder pins +#define E0_STEP_PIN 19 +#define E0_DIR_PIN 18 +#define E0_ENABLE_PIN 25 + +#define TEMP_0_PIN 1 +#define TEMP_BED_PIN 0 + +#define HEATER_0_PIN 4 +#define HEATER_BED_PIN 3 + +#define PS_ON_PIN 15 + +//our pin for debugging. +#define DEBUG_PIN 0 + +//our RS485 pins +#define TX_ENABLE_PIN 12 +#define RX_ENABLE_PIN 13 diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_GEN7_CUSTOM.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_GEN7_CUSTOM.h new file mode 100644 index 00000000..06aaebd6 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_GEN7_CUSTOM.h @@ -0,0 +1,90 @@ +/** + * 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 . + * + */ + +/** + * Gen7 Alfons3 board pin assignments + * + * These Pins are assigned for the modified GEN7 Board from Alfons3. + * Please review the pins and adjust them for your needs. + */ + +#if !defined(__AVR_ATmega644P__) && !defined(__AVR_ATmega644__) && !defined(__AVR_ATmega1284P__) + #error "Oops! Make sure you have 'Gen7' selected from the 'Tools -> Boards' menu." +#endif + +#define BOARD_NAME "Gen7 Custom" + +//x axis pins +#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_STOP_PIN 0 + +//y axis pins +#define Y_STEP_PIN 23 +#define Y_DIR_PIN 22 +#define Y_ENABLE_PIN 24 +#define Y_STOP_PIN 1 + +//z axis pins +#define Z_STEP_PIN 26 +#define Z_DIR_PIN 25 +#define Z_ENABLE_PIN 24 +#define Z_STOP_PIN 2 + +//extruder pins +#define E0_STEP_PIN 28 +#define E0_DIR_PIN 27 +#define E0_ENABLE_PIN 24 + +#define TEMP_0_PIN 2 +#define TEMP_BED_PIN 1 // MUST USE ANALOG INPUT NUMBERING NOT DIGITAL OUTPUT NUMBERING!!!!!!!!! (pin 34 bed) + +#define HEATER_0_PIN 4 +#define HEATER_BED_PIN 3 // (bed) + +#define SDSS 31 // SCL pin of I2C header || CS Pin for SD Card support + +#define PS_ON_PIN 19 +//our pin for debugging. + +#define DEBUG_PIN -1 + +//our RS485 pins +//#define TX_ENABLE_PIN 12 +//#define RX_ENABLE_PIN 13 + +#define BEEPER_PIN -1 + +//Pins for 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 + +//buttons are directly attached +#define BTN_EN1 11 +#define BTN_EN2 10 +#define BTN_ENC 12 + diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_K8200.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_K8200.h new file mode 100644 index 00000000..cc3e7311 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_K8200.h @@ -0,0 +1,32 @@ +/** + * 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 . + * + */ + +/** + * K8200 Arduino Mega with RAMPS v1.3 pin assignments + * Identical to 3DRAG + */ + +#define BOARD_NAME "Velleman K8200" +#define DEFAULT_MACHINE_NAME "K8200" +#define DEFAULT_SOURCE_CODE_URL "https://github.com/CONSULitAS/Marlin-K8200" + +#include "pins_3DRAG.h" diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_K8400.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_K8400.h new file mode 100644 index 00000000..a15e9e49 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_K8400.h @@ -0,0 +1,52 @@ +/** + * 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 . + * + */ + +/** + * Velleman K8400 (Vertex) + * 3DRAG clone + * + * K8400 has some minor differences over a normal 3Drag: + * - No X/Y max endstops + * - Second extruder step pin has moved + * - No power supply control + * - Second heater has moved pin + */ + +#define BOARD_NAME "K8400" +#define DEFAULT_MACHINE_NAME "Vertex" +#define DEFAULT_SOURCE_CODE_URL "https://github.com/birkett/Vertex-K8400-Firmware" + +#include "pins_3DRAG.h" + +#undef X_MAX_PIN +#define X_MAX_PIN -1 +#undef Y_MAX_PIN +#define Y_MAX_PIN -1 + +#undef E1_STEP_PIN +#define E1_STEP_PIN 32 + +#undef PS_ON_PIN +#undef KILL_PIN + +#undef HEATER_1_PIN +#define HEATER_1_PIN 11 diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_K8600.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_K8600.h new file mode 100644 index 00000000..45d875a6 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_K8600.h @@ -0,0 +1,111 @@ +/** + * 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 v1.4 pin assignments + */ + +#include "pins_RAMPS_14.h" + +#define DEFAULT_MACHINE_NAME "Vertex Nano" +#define DEFAULT_SOURCE_CODE_URL "http://www.vertex3dprinter.eu/" + +#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 + +#undef X_MIN_PIN +#undef Y_MAX_PIN +#undef Z_MAX_PIN +#undef Z_MIN_PIN +#define X_MIN_PIN 3 +#define Y_MAX_PIN 14 +#define Z_MAX_PIN 18 +#define Z_MIN_PIN -1 + +#undef SDSS +#define SDSS 25//53 + +#undef FAN_PIN +#define FAN_PIN 7//8 + +#undef HEATER_0_PIN +#define HEATER_0_PIN 10 + +#undef HEATER_1_PIN +#undef HEATER_2_PIN +#undef HEATER_BED_PIN +#define HEATER_0_PIN 10 +#define HEATER_1_PIN -1 +#define HEATER_2_PIN -1 +#define HEATER_BED_PIN -1 // BED + +#if ENABLED(ULTRA_LCD) && ENABLED(NEWPANEL) + #undef BEEPER_PIN + #define BEEPER_PIN -1 + + #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 //the click + +#else + + #define BEEPER_PIN 33 + +#endif // ULTRA_LCD && NEWPANEL diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_LEAPFROG.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_LEAPFROG.h new file mode 100644 index 00000000..acfba037 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_LEAPFROG.h @@ -0,0 +1,73 @@ +/** + * 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 . + * + */ + +/** + * Leapfrog Driver board pin assignments + */ + +#if !defined(__AVR_ATmega1280__) && !defined(__AVR_ATmega2560__) + #error "Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu." +#endif + +#define BOARD_NAME "Leapfrog" + +#define X_STEP_PIN 28 +#define X_DIR_PIN 63 +#define X_ENABLE_PIN 29 +#define X_MIN_PIN 47 +#define X_MAX_PIN 2 //Max endstops default to disabled "-1", set to commented value to enable. + +#define Y_STEP_PIN 14 // A6 +#define Y_DIR_PIN 15 // A0 +#define Y_ENABLE_PIN 39 +#define Y_MIN_PIN 48 +#define Y_MAX_PIN 15 + +#define Z_STEP_PIN 31 // A2 +#define Z_DIR_PIN 32 // A6 +#define Z_ENABLE_PIN 30 // A1 +#define Z_MIN_PIN 49 +#define Z_MAX_PIN -1 + +#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 SDSS 11 +#define LED_PIN 13 +#define FAN_PIN 7 +#define SOL1_PIN 16 +#define SOL2_PIN 17 + +#define HEATER_0_PIN 9 +#define HEATER_1_PIN 8 // 12 +#define HEATER_2_PIN 11 //-1 // 13 +#define TEMP_0_PIN 13 //D27 // MUST USE ANALOG INPUT NUMBERING NOT DIGITAL OUTPUT NUMBERING!!!!!!!!! +#define TEMP_1_PIN 15 // 1 +#define HEATER_BED_PIN 10 // 14/15 +#define TEMP_BED_PIN 14 // 1,2 or I2C +/* 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/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_MEGACONTROLLER.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_MEGACONTROLLER.h new file mode 100644 index 00000000..7ea4ee34 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_MEGACONTROLLER.h @@ -0,0 +1,123 @@ +/** + * 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 . + * + */ + +/** + * Mega controller pin assignments + */ + +#ifndef __AVR_ATmega2560__ + #error "Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu." +#endif + +#if E_STEPPERS > 2 || HOTENDS > 2 + #error "Mega Controller supports up to 2 hotends / E-steppers. Comment this line to keep going." +#endif + +#define BOARD_NAME "Mega Controller" + +#define SERVO0_PIN 30 +#define SERVO1_PIN 31 +#define SERVO2_PIN 32 +#define SERVO3_PIN 33 + +#define X_STEP_PIN 62//A8 +#define X_DIR_PIN 63//A9 +#define X_ENABLE_PIN 61//A7 +#define X_MIN_PIN 43 +#define X_MAX_PIN 42 //Max endstops default to disabled "-1", set to commented value to enable. + +#define Y_STEP_PIN 65 // A11 +#define Y_DIR_PIN 66 // A12 +#define Y_ENABLE_PIN 64//A10 +#define Y_MIN_PIN 38 +#define Y_MAX_PIN 41 + +#define Z_STEP_PIN 68 // A14 +#define Z_DIR_PIN 69 // A15 +#define Z_ENABLE_PIN 67 // A13 +#define Z_MIN_PIN 40 +#define Z_MAX_PIN 37 + +#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 SDSS 53 +#define LED_PIN 13 + +#define FAN_PIN 39 +#define FAN1_PIN 35 +#define FAN2_PIN 36 +#define FAN_SOFT_PWM +#define CONTROLLERFAN_PIN FAN2_PIN + +#define HEATER_0_PIN 29 // EXTRUDER 1 +#define HEATER_1_PIN 34 // EXTRUDER 2 + +#if TEMP_SENSOR_0 == -1 + #define TEMP_0_PIN 4 // ANALOG NUMBERING +#else + #define TEMP_0_PIN 0 // ANALOG NUMBERING +#endif + +#if TEMP_SENSOR_1 == -1 + #define TEMP_1_PIN 5 // ANALOG NUMBERING +#else + #define TEMP_1_PIN 2 // ANALOG NUMBERING +#endif + +#define TEMP_2_PIN 3 // ANALOG NUMBERING + +#define HEATER_BED_PIN 28 // BED + +#if TEMP_SENSOR_BED == -1 + #define TEMP_BED_PIN 6 // ANALOG NUMBERING +#else + #define TEMP_BED_PIN 1 // ANALOG NUMBERING +#endif + +#if ENABLED(MINIPANEL) + #define BEEPER_PIN 46 + // Pins for DOGM SPI LCD Support + #define DOGLCD_A0 47 + #define DOGLCD_CS 45 + #define LCD_PIN_BL 44 // backlight LED on PA3 + + #define KILL_PIN 12 + // GLCD features + //#define LCD_CONTRAST 190 + // 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 SD_DETECT_PIN 49 +#endif // MINIPANEL + diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_MEGATRONICS.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_MEGATRONICS.h new file mode 100644 index 00000000..1b95f525 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_MEGATRONICS.h @@ -0,0 +1,97 @@ +/** + * 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 . + * + */ + +/** + * MegaTronics pin assignments + */ + +#ifndef __AVR_ATmega2560__ + #error "Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu." +#endif + +#define BOARD_NAME "Megatronics" +#define LARGE_FLASH true + +#define X_STEP_PIN 26 +#define X_DIR_PIN 28 +#define X_ENABLE_PIN 24 +#define X_MIN_PIN 41 +#define X_MAX_PIN 37 + +#define Y_STEP_PIN 60 // A6 +#define Y_DIR_PIN 61 // A7 +#define Y_ENABLE_PIN 22 +#define Y_MIN_PIN 14 +#define Y_MAX_PIN 15 + +#define Z_STEP_PIN 54 // A0 +#define Z_DIR_PIN 55 // A1 +#define Z_ENABLE_PIN 56 // A2 +#define Z_MIN_PIN 18 +#define Z_MAX_PIN 19 + +#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 SDSS 53 +#define LED_PIN 13 + +#define FAN_PIN 7 // IO pin. Buffer needed +#define PS_ON_PIN 12 + +#define HEATER_0_PIN 9 +#define HEATER_1_PIN 8 +#define HEATER_BED_PIN 10 // BED + +#if TEMP_SENSOR_0 == -1 + #define TEMP_0_PIN 8 // ANALOG NUMBERING +#else + #define TEMP_0_PIN 13 // ANALOG NUMBERING +#endif +#define TEMP_1_PIN 15 // ANALOG NUMBERING +#define TEMP_BED_PIN 14 // ANALOG NUMBERING + +// AUX-4 +#define BEEPER_PIN 33 + +#if ENABLED(ULTRA_LCD) && ENABLED(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 + + // Buttons directly attached using AUX-2 + #define BTN_EN1 59 + #define BTN_EN2 64 + #define BTN_ENC 43 + + #define SD_DETECT_PIN -1 // RAMPS doesn't use this + +#endif // ULTRA_LCD && NEWPANEL diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_MEGATRONICS_2.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_MEGATRONICS_2.h new file mode 100644 index 00000000..991ab4a9 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_MEGATRONICS_2.h @@ -0,0 +1,104 @@ +/** + * 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 . + * + */ + +/** + * MegaTronics v2.0 pin assignments + */ + +#ifndef __AVR_ATmega2560__ + #error "Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu." +#endif + +#define BOARD_NAME "Megatronics v2.0" +#define LARGE_FLASH true + +#define X_STEP_PIN 26 +#define X_DIR_PIN 27 +#define X_ENABLE_PIN 25 +#define X_MIN_PIN 37 +#define X_MAX_PIN 40 + +#define Y_STEP_PIN 4 // A6 +#define Y_DIR_PIN 54 // A0 +#define Y_ENABLE_PIN 5 +#define Y_MIN_PIN 41 +#define Y_MAX_PIN 38 + +#define Z_STEP_PIN 56 // A2 +#define Z_DIR_PIN 60 // A6 +#define Z_ENABLE_PIN 55 // A1 +#define Z_MIN_PIN 18 +#define Z_MAX_PIN 19 + +#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 E2_STEP_PIN 23 +#define E2_DIR_PIN 24 +#define E2_ENABLE_PIN 22 + +#define SDSS 53 +#define LED_PIN 13 + +#define FAN_PIN 7 +#define FAN2_PIN 6 +#define PS_ON_PIN 12 + +#define HEATER_0_PIN 9 // EXTRUDER 1 +#if TEMP_SENSOR_0 == -1 + #define TEMP_0_PIN 4 // ANALOG NUMBERING +#else + #define TEMP_0_PIN 13 // ANALOG NUMBERING +#endif + +#define HEATER_1_PIN 8 // EXTRUDER 2 +#if TEMP_SENSOR_1 == -1 + #define TEMP_1_PIN 8 // ANALOG NUMBERING +#else + #define TEMP_1_PIN 15 // ANALOG NUMBERING +#endif + +#define HEATER_BED_PIN 10 // BED +#if TEMP_SENSOR_BED == -1 + #define TEMP_BED_PIN 8 // ANALOG NUMBERING +#else + #define TEMP_BED_PIN 14 // ANALOG NUMBERING +#endif + +#define BEEPER_PIN 64 + +#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 + +// Buttons are directly attached using keypad +#define BTN_EN1 61 +#define BTN_EN2 59 +#define BTN_ENC 43 diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_MEGATRONICS_3.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_MEGATRONICS_3.h new file mode 100644 index 00000000..a983ee2a --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_MEGATRONICS_3.h @@ -0,0 +1,147 @@ +/** + * 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 . + * + */ + +/** + * MegaTronics v3.0 pin assignments + */ + +#ifndef __AVR_ATmega2560__ + #error "Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu." +#endif + +#define MEGATRONICS_31 + +#if ENABLED(MEGATRONICS_31) + #define BOARD_NAME "Megatronics v3.1" +#else + #define BOARD_NAME "Megatronics v3.0" +#endif + +#define LARGE_FLASH true + +#if ENABLED(Z_PROBE_SLED) + #define SLED_PIN -1 +#endif + +// Servo support +#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 X_STEP_PIN 58 +#define X_DIR_PIN 57 +#define X_ENABLE_PIN 59 +#define X_MIN_PIN 37 +#define X_MAX_PIN 40 + +#define Y_STEP_PIN 5 +#define Y_DIR_PIN 17 +#define Y_ENABLE_PIN 4 +#define Y_MIN_PIN 41 +#define Y_MAX_PIN 38 + +#define Z_STEP_PIN 16 +#define Z_DIR_PIN 11 +#define Z_ENABLE_PIN 3 +#define Z_MIN_PIN 18 +#define Z_MAX_PIN 19 + +#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 E2_STEP_PIN 22 +#define E2_DIR_PIN 60 +#define E2_ENABLE_PIN 23 + +#define SDSS 53 +#define LED_PIN 13 + +#define PS_ON_PIN 12 + +#define HEATER_0_PIN 2 +#define HEATER_1_PIN 9 +#define HEATER_2_PIN 8 +#define HEATER_BED_PIN 10 +#define FAN_PIN 6 +#define FAN2_PIN 7 + +#if TEMP_SENSOR_0 == -1 + #define TEMP_0_PIN 11 // ANALOG NUMBERING +#else + #define TEMP_0_PIN 15 // ANALOG NUMBERING +#endif +#if TEMP_SENSOR_1 == -1 + #define TEMP_1_PIN 10 // ANALOG NUMBERING +#else + #define TEMP_1_PIN 13 // ANALOG NUMBERING +#endif +#if TEMP_SENSOR_2 == -1 + #define TEMP_2_PIN 9 // ANALOG NUMBERING +#else + #define TEMP_2_PIN 12 // ANALOG NUMBERING +#endif +#if TEMP_SENSOR_BED == -1 + #define TEMP_BED_PIN 8 // ANALOG NUMBERING +#else + #define TEMP_BED_PIN 14 // ANALOG NUMBERING +#endif + +/** + * Controllers and LCDs + */ +#define BEEPER_PIN 61 + +#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 +#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 SHIFT_CLK 43 + #define SHIFT_LD 35 + #define SHIFT_OUT 34 + #define SHIFT_EN 44 + + #if ENABLED(MEGATRONICS_31) + #define SD_DETECT_PIN 56 + #else + #define SD_DETECT_PIN -1 + #endif + +#endif diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_MELZI.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_MELZI.h new file mode 100644 index 00000000..677f0cf3 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_MELZI.h @@ -0,0 +1,34 @@ +/** + * 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 . + * + */ + +/** + * Melzi pin assignments + */ + +#define BOARD_NAME "Melzi" + +#if defined(__AVR_ATmega1284P__) + #define LARGE_FLASH true +#endif + +#define SANGUINOLOLU_V_1_2 +#include "pins_SANGUINOLOLU_11.h" diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_MELZI_MAKR3D.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_MELZI_MAKR3D.h new file mode 100644 index 00000000..877f8cbd --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_MELZI_MAKR3D.h @@ -0,0 +1,34 @@ +/** + * 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 . + * + */ + +/** + * Melzi with ATmega1284 (MaKr3d version) pin assignments + */ + +#define BOARD_NAME "Melzi ATmega1284" + +#if defined(__AVR_ATmega1284P__) + #define LARGE_FLASH true +#endif + +#define SANGUINOLOLU_V_1_2 +#include "pins_SANGUINOLOLU_11.h" diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_MINIRAMBO.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_MINIRAMBO.h new file mode 100644 index 00000000..089ea599 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_MINIRAMBO.h @@ -0,0 +1,116 @@ +/** + * 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 . + * + */ + +/** + * Mini-Rambo pin assignments + */ + +#ifndef __AVR_ATmega2560__ + #error "Oops! Make sure you have 'Arduino Mega 2560 or Rambo' selected from the 'Tools -> Boards' menu." +#endif + +#define BOARD_NAME "Mini Rambo" +#define LARGE_FLASH true + +#define X_STEP_PIN 37 +#define X_DIR_PIN 48 +#define X_MIN_PIN 12 +#define X_MAX_PIN 30 +#define X_ENABLE_PIN 29 +#define X_MS1_PIN 40 +#define X_MS2_PIN 41 + +#define Y_STEP_PIN 36 +#define Y_DIR_PIN 49 +#define Y_MIN_PIN 11 +#define Y_MAX_PIN 24 +#define Y_ENABLE_PIN 28 +#define Y_MS1_PIN 69 +#define Y_MS2_PIN 39 + +#define Z_STEP_PIN 35 +#define Z_DIR_PIN 47 +#define Z_MIN_PIN 10 +#define Z_MAX_PIN 23 +#define Z_ENABLE_PIN 27 +#define Z_MS1_PIN 68 +#define Z_MS2_PIN 67 + +#define HEATER_BED_PIN 4 +#define TEMP_BED_PIN 2 + +#define HEATER_0_PIN 3 +#define TEMP_0_PIN 0 + +#define HEATER_1_PIN 7 +#define TEMP_1_PIN 1 + +#if ENABLED(BARICUDA) + #define HEATER_2_PIN 6 +#endif + +#define E0_STEP_PIN 34 +#define E0_DIR_PIN 43 +#define E0_ENABLE_PIN 26 +#define E0_MS1_PIN 65 +#define E0_MS2_PIN 66 + +#define E1_STEP_PIN -1 +#define E1_DIR_PIN -1 +#define E1_ENABLE_PIN -1 + +#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 +#define MOTOR_CURRENT_PWM_RANGE 2000 +#define DEFAULT_PWM_MOTOR_CURRENT {1300, 1300, 1250} +#define SDSS 53 +#define LED_PIN 13 +#define FAN_PIN 8 +#define FAN_1_PIN 6 + +#if ENABLED(ULTRA_LCD) + + #define KILL_PIN 32 + + #if ENABLED(NEWPANEL) + + // Beeper on AUX-4 + #define BEEPER_PIN 84 + + #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 + + //buttons are directly attached using AUX-2 + #define BTN_EN1 14 + #define BTN_EN2 72 + #define BTN_ENC 9 // the click + + #define SD_DETECT_PIN 15 + + #endif //NEWPANEL +#endif //ULTRA_LCD diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_MINITRONICS.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_MINITRONICS.h new file mode 100644 index 00000000..34faa9ad --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_MINITRONICS.h @@ -0,0 +1,109 @@ +/** + * 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 . + * + */ + +/** + * Minitronics v1.0/1.1 pin assignments + */ + +#ifndef __AVR_ATmega1281__ + #error "Oops! Make sure you have 'Minitronics' selected from the 'Tools -> Boards' menu." +#endif + +#define BOARD_NAME "Minitronics v1.0 / v1.1" +#define LARGE_FLASH true + +#define X_STEP_PIN 48 +#define X_DIR_PIN 47 +#define X_ENABLE_PIN 49 +#define X_MIN_PIN 5 +#define X_MAX_PIN 2 + +#define Y_STEP_PIN 39 // A6 +#define Y_DIR_PIN 40 // A0 +#define Y_ENABLE_PIN 38 +#define Y_MIN_PIN 2 +#define Y_MAX_PIN 15 + +#define Z_STEP_PIN 42 // A2 +#define Z_DIR_PIN 43 // A6 +#define Z_ENABLE_PIN 41 // A1 +#define Z_MIN_PIN 6 +#define Z_MAX_PIN -1 + +#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 E2_STEP_PIN -1 +#define E2_DIR_PIN -1 +#define E2_ENABLE_PIN -1 + +#define SDSS 16 +#define LED_PIN 46 + +#define FAN_PIN 9 + +#define TEMP_0_PIN 7 // ANALOG NUMBERING +#define TEMP_1_PIN 6 // ANALOG NUMBERING +#define TEMP_BED_PIN 6 // ANALOG NUMBERING + +#define HEATER_0_PIN 7 // EXTRUDER 1 +#define HEATER_1_PIN 8 // EXTRUDER 2 +#define HEATER_BED_PIN 3 // BED + +/** + * Controllers and LCDs + */ +#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 BTN_EN1 18 + #define BTN_EN2 17 + #define BTN_ENC 25 + + #define SD_DETECT_PIN 30 + +#else + + #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 + + // Buttons are directly attached using keypad + #define BTN_EN1 -1 + #define BTN_EN2 -1 + #define BTN_ENC -1 + + #define SD_DETECT_PIN -1 // Minitronics doesn't use this +#endif diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_MKS_13.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_MKS_13.h new file mode 100644 index 00000000..3b5b242a --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_MKS_13.h @@ -0,0 +1,128 @@ +/** + * 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 . + * + */ + +/** + * Arduino Mega with RAMPS v1.4 adjusted pin assignments + * + * MKS v1.3 (Extruder, Fan, Bed) + * MKS v1.3 (Extruder, Extruder, Fan, Bed) + * MKS v1.4 (Extruder, Fan, Bed) + * MKS v1.4 (Extruder, Extruder, Fan, Bed) + */ + +#if HOTENDS > 2 + #error "MKS 1.3/1.4 supports up to 2 hotends. Comment this line to keep going." +#endif + +#define BOARD_NAME "MKS > v1.3" + +// Power outputs EFBF or EFBE +#define MOSFET_D_PIN 7 + +#include "pins_RAMPS.h" + +#if ENABLED(VIKI2) || ENABLED(miniVIKI) + /** + * VIKI2 Has two groups of wires with... + * + * +Vin + Input supply, requires 120ma for LCD and mSD card + * GND Ground Pin + * MOSI Data input for LCD and SD + * MISO Data output for SD + * SCK Clock for LCD and SD + * AO Reg. Sel for LCD + * LCS Chip Select for LCD + * SDCS Chip Select for SD + * SDCD Card Detect pin for SD + * ENCA Encoder output A + * ENCB Encoder output B + * ENCBTN Encoder button switch + * + * BTN Panel mounted button switch + * BUZZER Piezo buzzer + * BLUE-LED Blue LED ring pin (3 to 5v, mosfet buffered) + * RED-LED Red LED ring pin (3 to 5v, mosfet buffered) + * + * This configuration uses the following arrangement: + * + * EXP1 D37 = EN2 D35 = EN1 EXP2 D50 = MISO D52 = SCK + * D17 = BLUE D16 = RED D31 = ENC D53 = SDCS + * D23 = KILL D25 = BUZZ D33 = --- D51 = MOSI + * D27 = A0 D29 = LCS D49 = SDCD RST = --- + * GND = GND 5V = 5V GND = --- D41 = --- + */ + + #undef BTN_EN1 + #undef BTN_EN2 + #undef BTN_ENC + #undef DOGLCD_A0 + #undef DOGLCD_CS + #undef SD_DETECT_PIN + #undef BEEPER_PIN + #undef KILL_PIN + + // + // VIKI2 12-wire lead + // + + // orange/white SDCD + #define SD_DETECT_PIN 49 + + // white ENCA + #define BTN_EN1 35 + + // green ENCB + #define BTN_EN2 37 + + // purple ENCBTN + #define BTN_ENC 31 + + // brown A0 + #define DOGLCD_A0 27 + + // green/white LCS + #define DOGLCD_CS 29 + + // 50 gray MISO + // 51 yellow MOSI + // 52 orange SCK + + // blue SDCS + //#define SDSS 53 + + // + // VIKI2 4-wire lead + // + + // blue BTN + #define KILL_PIN 23 + + // green BUZZER + #define BEEPER_PIN 25 + + // yellow RED-LED + #define STAT_LED_RED 16 + + // white BLUE-LED + #define STAT_LED_BLUE 17 + +#endif diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_MKS_BASE.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_MKS_BASE.h new file mode 100644 index 00000000..8c722201 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_MKS_BASE.h @@ -0,0 +1,36 @@ +/** + * 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 . + * + */ + +/** + * MKS BASE 1.0 – Arduino Mega2560 with RAMPS v1.4 pin assignments + */ + +#if HOTENDS > 2 + #error "MKS BASE 1.0 supports up to 2 hotends. Comment this line to keep going." +#endif + +#define BOARD_NAME "MKS BASE 1.0" + +// Power outputs EFBF or EFBE +#define MOSFET_D_PIN 7 + +#include "pins_RAMPS.h" \ No newline at end of file diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_OMCA.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_OMCA.h new file mode 100644 index 00000000..9ec6309d --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_OMCA.h @@ -0,0 +1,107 @@ +/** + * 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 . + * + */ + +/** + * Open Motion controller with enable based extruders (Final!) + * + * ATMega644 + * + * +---\/---+ + * (D 0) PB0 1| |40 PA0 (AI 0 / D31) + * (D 1) PB1 2| |39 PA1 (AI 1 / D30) + * INT2 (D 2) PB2 3| |38 PA2 (AI 2 / D29) + * PWM (D 3) PB3 4| |37 PA3 (AI 3 / D28) + * PWM (D 4) PB4 5| |36 PA4 (AI 4 / D27) + * MOSI (D 5) PB5 6| |35 PA5 (AI 5 / D26) + * MISO (D 6) PB6 7| |34 PA6 (AI 6 / D25) + * SCK (D 7) PB7 8| |33 PA7 (AI 7 / D24) + * RST 9| |32 AREF + * VCC 10| |31 GND + * GND 11| |30 AVCC + * XTAL2 12| |29 PC7 (D 23) + * XTAL1 13| |28 PC6 (D 22) + * RX0 (D 8) PD0 14| |27 PC5 (D 21) TDI + * TX0 (D 9) PD1 15| |26 PC4 (D 20) TDO + * INT0 RX1 (D 10) PD2 16| |25 PC3 (D 19) TMS + * INT1 TX1 (D 11) PD3 17| |24 PC2 (D 18) TCK + * PWM (D 12) PD4 18| |23 PC1 (D 17) SDA + * PWM (D 13) PD5 19| |22 PC0 (D 16) SCL + * PWM (D 14) PD6 20| |21 PD7 (D 15) PWM + * +--------+ + * + * REF http://sanguino.cc/hardware + */ + +#if !defined(__AVR_ATmega644P__) && !defined(__AVR_ATmega644__) + #error "Oops! Make sure you have 'Sanguino' selected from the 'Tools -> Boards' menu. (Final OMCA board)" +#endif + +#define BOARD_NAME "Final OMCA" + +#define X_STEP_PIN 26 +#define X_DIR_PIN 25 +#define X_ENABLE_PIN 10 +#define X_STOP_PIN 0 + +#define Y_STEP_PIN 28 +#define Y_DIR_PIN 27 +#define Y_ENABLE_PIN 10 +#define Y_STOP_PIN 1 + +#define Z_STEP_PIN 23 +#define Z_DIR_PIN 22 +#define Z_ENABLE_PIN 10 +#define Z_STOP_PIN 2 + +#define E0_STEP_PIN 24 +#define E0_DIR_PIN 21 +#define E0_ENABLE_PIN 10 + +// future proofing +#define __FS 20 +#define __FD 19 +#define __GS 18 +#define __GD 13 + +#define UNUSED_PWM 14 // PWM on LEFT connector + +#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 SDSS 11 +#define FAN_PIN 14 // PWM on MIDDLE connector + +#define HEATER_0_PIN 3 // DONE PWM on RIGHT connector +#define HEATER_BED_PIN 4 + +#define TEMP_0_PIN 0 // ANALOG INPUT NUMBERING +#define TEMP_1_PIN 1 // ANALOG +#define TEMP_BED_PIN 2 // 1,2 or I2C + +#define I2C_SCL 16 +#define I2C_SDA 17 + diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_OMCA_A.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_OMCA_A.h new file mode 100644 index 00000000..39d232ae --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_OMCA_A.h @@ -0,0 +1,92 @@ +/** + * 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 . + * + */ + +/** + * Open Motion controller with enable based extruders (Alpha!) + * + * ATMega644 + * + * +---\/---+ + * (D 0) PB0 1| |40 PA0 (AI 0 / D31) + * (D 1) PB1 2| |39 PA1 (AI 1 / D30) + * INT2 (D 2) PB2 3| |38 PA2 (AI 2 / D29) + * PWM (D 3) PB3 4| |37 PA3 (AI 3 / D28) + * PWM (D 4) PB4 5| |36 PA4 (AI 4 / D27) + * MOSI (D 5) PB5 6| |35 PA5 (AI 5 / D26) + * MISO (D 6) PB6 7| |34 PA6 (AI 6 / D25) + * SCK (D 7) PB7 8| |33 PA7 (AI 7 / D24) + * RST 9| |32 AREF + * VCC 10| |31 GND + * GND 11| |30 AVCC + * XTAL2 12| |29 PC7 (D 23) + * XTAL1 13| |28 PC6 (D 22) + * RX0 (D 8) PD0 14| |27 PC5 (D 21) TDI + * TX0 (D 9) PD1 15| |26 PC4 (D 20) TDO + * INT0 RX1 (D 10) PD2 16| |25 PC3 (D 19) TMS + * INT1 TX1 (D 11) PD3 17| |24 PC2 (D 18) TCK + * PWM (D 12) PD4 18| |23 PC1 (D 17) SDA + * PWM (D 13) PD5 19| |22 PC0 (D 16) SCL + * PWM (D 14) PD6 20| |21 PD7 (D 15) PWM + * +--------+ + * + */ + +#ifndef __AVR_ATmega644__ + #error "Oops! Make sure you have 'SanguinoA' selected from the 'Tools -> Boards' menu." +#endif + +#define BOARD_NAME "Alpha OMCA" + +#define X_STEP_PIN 21 +#define X_DIR_PIN 20 +#define X_ENABLE_PIN 24 +#define X_STOP_PIN 0 + +#define Y_STEP_PIN 23 +#define Y_DIR_PIN 22 +#define Y_ENABLE_PIN 24 +#define Y_STOP_PIN 1 + +#define Z_STEP_PIN 26 +#define Z_DIR_PIN 25 +#define Z_ENABLE_PIN 24 +#define Z_STOP_PIN 2 + +#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 E2_STEP_PIN -1 // 17 +#define E2_DIR_PIN -1 // 16 +#define E2_ENABLE_PIN 24 + +#define SDSS 11 +#define FAN_PIN 3 + +#define HEATER_0_PIN 4 +#define TEMP_0_PIN 0 //D27 // MUST USE ANALOG INPUT NUMBERING NOT DIGITAL OUTPUT NUMBERING!!!!!!!!! + +/* 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/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_PRINTRBOARD.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_PRINTRBOARD.h new file mode 100644 index 00000000..fb1874b6 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_PRINTRBOARD.h @@ -0,0 +1,136 @@ +/** + * 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 . + * + */ + +/** + * Printrboard 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 + */ + +#ifndef __AVR_AT90USB1286__ + #error "Oops! Make sure you have 'Teensy++ 2.0' selected from the 'Tools -> Boards' menu." +#endif + +#if ENABLED(AT90USBxx_TEENSYPP_ASSIGNMENTS) // use Teensyduino Teensy++2.0 pin assignments instead of Marlin traditional. + #error "These Printrboard assignments depend on traditional Marlin assignments, not AT90USBxx_TEENSYPP_ASSIGNMENTS in fastio.h" +#endif + +#define BOARD_NAME "Printrboard" +#define LARGE_FLASH true + +// Disable JTAG pins so they can be used for the Extrudrboard +#define DISABLE_JTAG true + +#define X_STEP_PIN 0 +#define X_DIR_PIN 1 +#define X_ENABLE_PIN 39 + +#define Y_STEP_PIN 2 +#define Y_DIR_PIN 3 +#define Y_ENABLE_PIN 38 + +#define Z_STEP_PIN 4 +#define Z_DIR_PIN 5 +#define Z_ENABLE_PIN 23 + +#define E0_STEP_PIN 6 +#define E0_DIR_PIN 7 +#define E0_ENABLE_PIN 19 + +#define HEATER_0_PIN 21 // Extruder +#define HEATER_1_PIN 46 +#define HEATER_2_PIN 47 +#define HEATER_BED_PIN 20 + +// If soft or fast PWM is off then use Teensyduino pin numbering, Marlin +// fastio pin numbering otherwise +#if ENABLED(FAN_SOFT_PWM) || ENABLED(FAST_PWM_FAN) + #define FAN_PIN 22 +#else + #define FAN_PIN 16 +#endif + +#define X_STOP_PIN 35 +#if ENABLED(SDSUPPORT) + #define Y_STOP_PIN 37 // Move Ystop to Estop socket +#else + #define Y_STOP_PIN 8 // Ystop in Ystop socket +#endif +#define Z_STOP_PIN 36 +#define TEMP_0_PIN 1 // Extruder / Analog pin numbering +#define TEMP_BED_PIN 0 // Bed / Analog pin numbering + +#define FILWIDTH_PIN 2 // ANALOG NUMBERING + +////LCD Pin Setup//// + +#define SDSS 26 + +#if ENABLED(ULTRA_LCD) && ENABLED(NEWPANEL) + //we have no buzzer installed + #define BEEPER_PIN -1 + + //LCD Pins + #if ENABLED(LCD_I2C_PANELOLU2) + #define BTN_EN1 27 //RX1 - fastio.h pin mapping 27 + #define BTN_EN2 26 //TX1 - fastio.h pin mapping 26 + #define BTN_ENC 43 //A3 - fastio.h pin mapping 43 + #define SDSS 40 //use SD card on Panelolu2 (Teensyduino pin mapping) + #else + #define BTN_EN1 16 + #define BTN_EN2 17 + #define BTN_ENC 18//the click + #endif // LCD_I2C_PANELOLU2 + + //not connected to a pin + #define SD_DETECT_PIN -1 + + #define LCD_PINS_RS 9 + #define LCD_PINS_ENABLE 8 + #define LCD_PINS_D4 7 + #define LCD_PINS_D5 6 + #define LCD_PINS_D6 5 + #define LCD_PINS_D7 4 + +#endif // ULTRA_LCD && NEWPANEL + +#if ENABLED(VIKI2) || ENABLED(miniVIKI) + //FastIO + #define BEEPER_PIN 32 + // Pins for DOGM SPI LCD Support + #define DOGLCD_A0 42 //Non-FastIO + #define DOGLCD_CS 43 //Non-FastIO + #define LCD_SCREEN_ROT_180 + + //The encoder and click button (FastIO Pins) + #define BTN_EN1 26 + #define BTN_EN2 27 + #define BTN_ENC 47 + + #define SDSS 45 + #define SD_DETECT_PIN -1 // FastIO (Manual says 72 I'm not certain cause I can't test) + #if ENABLED(TEMP_STAT_LEDS) + #define STAT_LED_RED 12 //Non-FastIO + #define STAT_LED_BLUE 10 //Non-FastIO + #endif +#endif diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_PRINTRBOARD_REVF.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_PRINTRBOARD_REVF.h new file mode 100644 index 00000000..61b23fb4 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_PRINTRBOARD_REVF.h @@ -0,0 +1,137 @@ +/** + * 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 . + * + */ + +/** + * Printrboard 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 + */ + +#ifndef __AVR_AT90USB1286__ + #error "Oops! Make sure you have 'Teensy++ 2.0' selected from the 'Tools -> Boards' menu." +#endif + +#if ENABLED(AT90USBxx_TEENSYPP_ASSIGNMENTS) // use Teensyduino Teensy++2.0 pin assignments instead of Marlin traditional. + #error "These Printrboard assignments depend on traditional Marlin assignments, not AT90USBxx_TEENSYPP_ASSIGNMENTS in fastio.h" +#endif + +#define BOARD_NAME "Printrboard Rev F" +#define LARGE_FLASH true + +#define X_STEP_PIN 0 +#define X_DIR_PIN 1 +#define X_ENABLE_PIN 39 + +#define Y_STEP_PIN 2 +#define Y_DIR_PIN 3 +#define Y_ENABLE_PIN 38 + +#define Z_STEP_PIN 4 +#define Z_DIR_PIN 5 +#define Z_ENABLE_PIN 23 + +#define E0_STEP_PIN 6 +#define E0_DIR_PIN 7 +#define E0_ENABLE_PIN 19 + +#define HEATER_0_PIN 21 // Extruder +#define HEATER_1_PIN 46 +#define HEATER_2_PIN 47 +#define HEATER_BED_PIN 20 + +// If soft or fast PWM is off then use Teensyduino pin numbering, Marlin +// fastio pin numbering otherwise +#if ENABLED(FAN_SOFT_PWM) || ENABLED(FAST_PWM_FAN) + #define FAN_PIN 22 +#else + #define FAN_PIN 16 +#endif + +#define X_STOP_PIN 35 +#define Y_STOP_PIN 12 +#define Z_STOP_PIN 36 + +#define TEMP_0_PIN 1 // Extruder / Analog pin numbering +#define TEMP_BED_PIN 0 // Bed / Analog pin numbering + +#define FILWIDTH_PIN 2 // ANALOG NUMBERING + +////LCD Pin Setup//// + +#define SDSS 20 // Teensylu pin mapping + +// uncomment to enable an I2C based DAC like on the Printrboard REVF +#define DAC_STEPPER_CURRENT +// Number of channels available for DAC, For Printrboar REVF there are 4 +#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 + +#if ENABLED(ULTRA_LCD) + #define BEEPER_PIN -1 + + #define LCD_PINS_RS 9 + #define LCD_PINS_ENABLE 8 + #define LCD_PINS_D4 7 + #define LCD_PINS_D5 6 + #define LCD_PINS_D6 5 + #define LCD_PINS_D7 4 + + #define BTN_EN1 16 + #define BTN_EN2 17 + #define BTN_ENC 18//the click + + #define SD_DETECT_PIN -1 + + //encoder rotation values + #define encrot0 0 + #define encrot1 2 + #define encrot2 3 + #define encrot3 1 +#endif + +#if ENABLED(VIKI2) || ENABLED(miniVIKI) + #define BEEPER_PIN 32 //FastIO + // Pins for DOGM SPI LCD Support + #define DOGLCD_A0 42 //Non-FastIO + #define DOGLCD_CS 43 //Non-FastIO + #define LCD_SCREEN_ROT_180 + + //The encoder and click button (FastIO Pins) + #define BTN_EN1 26 + #define BTN_EN2 27 + #define BTN_ENC 47 + + #define SDSS 45 + #define SD_DETECT_PIN -1 // FastIO (Manual says 72 I'm not certain cause I can't test) + + #if ENABLED(TEMP_STAT_LEDS) + #define STAT_LED_RED 12 //Non-FastIO + #define STAT_LED_BLUE 10 //Non-FastIO + #endif +#endif diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_RAMBO.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_RAMBO.h new file mode 100644 index 00000000..278774ca --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_RAMBO.h @@ -0,0 +1,181 @@ +/** + * 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 . + * + */ + +/** + * Rambo pin assignments + */ + +#ifndef __AVR_ATmega2560__ + #error "Oops! Make sure you have 'Arduino Mega 2560' selected from the 'Tools -> Boards' menu." +#endif + +#define BOARD_NAME "Rambo" + +#define LARGE_FLASH true + +// Servo support +#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 + +#if ENABLED(Z_PROBE_SLED) + #define SLED_PIN -1 +#endif + +#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 +#ifndef Z_MIN_PROBE_PIN + #define Z_MIN_PROBE_PIN 10 +#endif + +#define X_STEP_PIN 37 +#define X_DIR_PIN 48 +#define X_ENABLE_PIN 29 +#define X_MS1_PIN 40 +#define X_MS2_PIN 41 + +#define Y_STEP_PIN 36 +#define Y_DIR_PIN 49 +#define Y_ENABLE_PIN 28 +#define Y_MS1_PIN 69 +#define Y_MS2_PIN 39 + +#define Z_STEP_PIN 35 +#define Z_DIR_PIN 47 +#define Z_ENABLE_PIN 27 +#define Z_MS1_PIN 68 +#define Z_MS2_PIN 67 + +#define HEATER_BED_PIN 3 +#define TEMP_BED_PIN 2 + +#define HEATER_0_PIN 9 +#define TEMP_0_PIN 0 + +#define HEATER_1_PIN 7 +#define TEMP_1_PIN 1 + +#if ENABLED(BARICUDA) + #define HEATER_2_PIN 6 +#endif + +#define E0_STEP_PIN 34 +#define E0_DIR_PIN 43 +#define E0_ENABLE_PIN 26 +#define E0_MS1_PIN 65 +#define E0_MS2_PIN 66 + +#define E1_STEP_PIN 33 +#define E1_DIR_PIN 42 +#define E1_ENABLE_PIN 25 +#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 SDSS 53 +#define LED_PIN 13 +#define FAN_PIN 8 + +#define FILWIDTH_PIN 3 // ANALOG NUMBERING + +/********************************************************** + Fan Pins + Fan_0 8 + Fan_1 6 + Fan_2 2 +***********************************************************/ +#define PS_ON_PIN 4 + +#if ENABLED(ULTRA_LCD) + + #define KILL_PIN 80 + + #if ENABLED(NEWPANEL) + + #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 ENABLED(VIKI2) || ENABLED(miniVIKI) + #define BEEPER_PIN 44 + + #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 SD_DETECT_PIN -1 // Pin 72 if using easy adapter board + + #if ENABLED(TEMP_STAT_LEDS) + #define STAT_LED_RED 22 + #define STAT_LED_BLUE 32 + #endif + + #else + + #define BEEPER_PIN 79 // AUX-4 + + // AUX-2 + #define BTN_EN1 76 + #define BTN_EN2 77 + #define BTN_ENC 78 + + #define SD_DETECT_PIN 81 + + #endif // VIKI2/miniVIKI + + #else //!NEWPANEL - old style panel with shift register + + // No Beeper added + #define BEEPER_PIN 33 + + //buttons are 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 + + #endif // !NEWPANEL + +#endif // ULTRA_LCD + diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_RAMPS.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_RAMPS.h new file mode 100644 index 00000000..5f2e0d11 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_RAMPS.h @@ -0,0 +1,344 @@ +/** + * 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 . + * + */ + +/** + * Arduino Mega with RAMPS v1.4 (or v1.3) pin assignments + * + * Applies to the following boards: + * + * RAMPS_14_EFB (Hotend, Fan, Bed) + * RAMPS_14_EEB (Hotend0, Hotend1, Bed) + * RAMPS_14_EFF (Hotend, Fan0, Fan1) + * RAMPS_14_EEF (Hotend0, Hotend1, Fan) + * RAMPS_14_SF (Spindle, Controller Fan) + * + * RAMPS_13_EFB (Hotend, Fan, Bed) + * RAMPS_13_EEB (Hotend0, Hotend1, Bed) + * RAMPS_13_EFF (Hotend, Fan0, Fan1) + * RAMPS_13_EEF (Hotend0, Hotend1, Fan) + * RAMPS_13_SF (Spindle, Controller Fan) + * + * Other pins_MYBOARD.h files may override these defaults + * + * Differences between + * RAMPS_13 | RAMPS_14 + * 7 | 11 + */ + +#if !defined(__AVR_ATmega1280__) && !defined(__AVR_ATmega2560__) + #error "Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu." +#endif + +#ifndef BOARD_NAME + #define BOARD_NAME "RAMPS 1.4" +#endif + +#define LARGE_FLASH true + +#ifdef IS_RAMPS_13 + #define SERVO0_PIN 7 // RAMPS_13 // Will conflict with BTN_EN2 on LCD_I2C_VIKI +#else + #define SERVO0_PIN 11 +#endif +#define SERVO1_PIN 6 +#define SERVO2_PIN 5 +#define SERVO3_PIN 4 + +#define X_MIN_PIN 3 +#ifndef X_MAX_PIN + #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 +#ifndef Z_MIN_PROBE_PIN + #define Z_MIN_PROBE_PIN 32 +#endif + +#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 Z_STEP_PIN 46 +#define Z_DIR_PIN 48 +#define Z_ENABLE_PIN 62 + +#define E0_STEP_PIN 26 +#define E0_DIR_PIN 28 +#define E0_ENABLE_PIN 24 + +#define E1_STEP_PIN 36 +#define E1_DIR_PIN 34 +#define E1_ENABLE_PIN 30 + +#define SDSS 53 +#define LED_PIN 13 + +// Use the RAMPS 1.4 Analog input 5 on the AUX2 connector +#define FILWIDTH_PIN 5 // ANALOG NUMBERING + +// define digital pin 4 for the filament runout sensor. Use the RAMPS 1.4 digital input 4 on the servos connector +#define FIL_RUNOUT_PIN 4 + +#define PS_ON_PIN 12 +#define TEMP_0_PIN 13 // ANALOG NUMBERING +#define TEMP_1_PIN 15 // ANALOG NUMBERING +#define TEMP_BED_PIN 14 // ANALOG NUMBERING + +#if ENABLED(Z_PROBE_SLED) + #define SLED_PIN -1 +#endif + +// Augmentation for auto-assigning RAMPS plugs +#if DISABLED(IS_RAMPS_EEB) && DISABLED(IS_RAMPS_EEF) && DISABLED(IS_RAMPS_EFB) && DISABLED(IS_RAMPS_EFF) && DISABLED(IS_RAMPS_SF) && !PIN_EXISTS(MOSFET_D) + #if HOTENDS > 1 + #if TEMP_SENSOR_BED + #define IS_RAMPS_EEB + #else + #define IS_RAMPS_EEF + #endif + #elif TEMP_SENSOR_BED + #define IS_RAMPS_EFB + #else + #define IS_RAMPS_EFF + #endif +#endif + +/** + * Hi Voltage PWM Pin Assignments + */ + +#ifndef MOSFET_D_PIN + #define MOSFET_D_PIN -1 +#endif +#ifndef RAMPS_D8_PIN + #define RAMPS_D8_PIN 8 +#endif +#ifndef RAMPS_D9_PIN + #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 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 + #define CONTROLLERFAN_PIN -1 +#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 + #else + #define HEATER_1_PIN MOSFET_D_PIN + #endif +#endif + +#ifndef FAN_PIN + #define FAN_PIN 4 // IO pin. Buffer needed +#endif + +/** + * LCD Controller Pin Assignments + */ + +#if ENABLED(ULTRA_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 ENABLED(NEWPANEL) && ENABLED(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 + #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_D7 29 + #if DISABLED(NEWPANEL) + #define BEEPER_PIN 33 + // Buttons are 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_PIN_BL 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 // reverse if the encoder turns the wrong way. + #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 // reverse if the encoder turns the wrong way. + #define BTN_EN2 7 // http://files.panucatt.com/datasheets/viki_wiring_diagram.pdf + // tells about 40/42. + // 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 ENABLED(VIKI2) || ENABLED(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 + + #if ENABLED(TEMP_STAT_LEDS) + #define STAT_LED_RED 32 + #define STAT_LED_BLUE 35 + #endif + #elif ENABLED(ELB_FULL_GRAPHIC_CONTROLLER) + #define BTN_EN1 35 // reverse if the encoder turns the wrong way. + #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_PIN_BL 33 + #elif ENABLED(MINIPANEL) + #define BEEPER_PIN 42 + // Pins for DOGM SPI LCD Support + #define DOGLCD_A0 44 + #define DOGLCD_CS 66 + #define LCD_PIN_BL 65 // backlight LED on A11/D65 + #define SDSS 53 + + #define KILL_PIN 64 + // GLCD features + //#define LCD_CONTRAST 190 + // 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 are directly attached using AUX-2 + #if ENABLED(REPRAPWORLD_KEYPAD) + #define BTN_EN1 64 // encoder + #define BTN_EN2 59 // encoder + #define BTN_ENC 63 // enter button + #define SHIFT_OUT 40 // shift register + #define SHIFT_CLK 44 // shift register + #define SHIFT_LD 42 // shift register + #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 // the click + #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 // ULTRA_LCD + +// SPI for Max6675 or Max31855 Thermocouple +#if DISABLED(SDSUPPORT) + #define MAX6675_SS 66 // Do not use pin 53 if there is even the remote possibility of using Display/SD card +#else + #define MAX6675_SS 66 // Do not 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 diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_RAMPS_13.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_RAMPS_13.h new file mode 100644 index 00000000..effce907 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_RAMPS_13.h @@ -0,0 +1,41 @@ +/** + * 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 . + * + */ + +/** + * Arduino Mega with RAMPS v1.3 pin assignments + * + * Applies to the following boards: + * + * RAMPS_13_EFB (Extruder, Fan, Bed) + * RAMPS_13_EEB (Extruder, Extruder, Bed) + * RAMPS_13_EFF (Extruder, Fan, Fan) + * RAMPS_13_EEF (Extruder, Extruder, Fan) + * RAMPS_13_SF (Spindle, Controller Fan) + * + */ + +#ifndef BOARD_NAME + #define BOARD_NAME "RAMPS 1.3" +#endif + +#define IS_RAMPS_13 +#include "pins_RAMPS.h" diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_RAMPS_14.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_RAMPS_14.h new file mode 100644 index 00000000..dc1f219d --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_RAMPS_14.h @@ -0,0 +1,296 @@ +/** + * 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 . + * + */ + +/** + * Arduino Mega with RAMPS v1.4 (or v1.3) pin assignments + * + * Applies to the following boards: + * + * RAMPS_14_EFB (Extruder, Fan, Bed) + * RAMPS_14_EEB (Extruder, Extruder, Bed) + * RAMPS_14_EFF (Extruder, Fan, Fan) + * RAMPS_14_EEF (Extruder, Extruder, Fan) + * RAMPS_14_SF (Spindle, Controller Fan) + * + * RAMPS_13_EFB (Extruder, Fan, Bed) + * RAMPS_13_EEB (Extruder, Extruder, Bed) + * RAMPS_13_EFF (Extruder, Fan, Fan) + * RAMPS_13_EEF (Extruder, Extruder, Fan) + * RAMPS_13_SF (Spindle, Controller Fan) + * + * Other pins_MYBOARD.h files may override these defaults + * + * Differences between + * RAMPS_13 | RAMPS_14 + * 7 | 11 + */ + +#if !defined(__AVR_ATmega1280__) && !defined(__AVR_ATmega2560__) + #error Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu. +#endif + +#define LARGE_FLASH true + +#ifdef IS_RAMPS_13 + #define SERVO0_PIN 7 // RAMPS_13 // Will conflict with BTN_EN2 on LCD_I2C_VIKI +#else + #define SERVO0_PIN 11 +#endif +#define SERVO1_PIN 6 +#define SERVO2_PIN 5 +#define SERVO3_PIN 4 + +#define X_STEP_PIN 54 +#define X_DIR_PIN 55 +#define X_ENABLE_PIN 38 +#define X_MIN_PIN 3 +#ifndef X_MAX_PIN + #define X_MAX_PIN 2 +#endif + +#define Y_STEP_PIN 60 +#define Y_DIR_PIN 61 +#define Y_ENABLE_PIN 56 +#define Y_MIN_PIN 14 +#define Y_MAX_PIN 15 + +#define Z_STEP_PIN 46 +#define Z_DIR_PIN 48 +#define Z_ENABLE_PIN 62 +#define Z_MIN_PIN 18 +#define Z_MAX_PIN 19 + +#define E0_STEP_PIN 26 +#define E0_DIR_PIN 28 +#define E0_ENABLE_PIN 24 + +#define E1_STEP_PIN 36 +#define E1_DIR_PIN 34 +#define E1_ENABLE_PIN 30 + +#define SDPOWER -1 +#define SDSS 53 +#define LED_PIN 13 + +// Use the RAMPS 1.4 Analog input 5 on the AUX2 connector +#define FILWIDTH_PIN 5 // ANALOG NUMBERING + +#if ENABLED(Z_MIN_PROBE_ENDSTOP) + // Define a pin to use as the signal pin on Arduino for the Z_PROBE endstop. + #define Z_MIN_PROBE_PIN 32 +#endif + +#if ENABLED(FILAMENT_RUNOUT_SENSOR) + // define digital pin 4 for the filament runout sensor. Use the RAMPS 1.4 digital input 4 on the servos connector + #define FILRUNOUT_PIN 4 +#endif + +#if MB(RAMPS_14_EFF) || MB(RAMPS_13_EFF) || ENABLED(IS_RAMPS_EFB) + #define FAN_PIN 9 // (Sprinter config) + #if MB(RAMPS_14_EFF) || MB(RAMPS_13_EFF) + #define CONTROLLERFAN_PIN -1 // Pin used for the fan to cool controller + #endif +#elif MB(RAMPS_14_EEF) || MB(RAMPS_14_SF) || MB(RAMPS_13_EEF) || MB(RAMPS_13_SF) + #define FAN_PIN 8 +#else + #define FAN_PIN 4 // IO pin. Buffer needed +#endif + +#define PS_ON_PIN 12 + +#if ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER) || ENABLED(G3D_PANEL) + #define KILL_PIN 41 +#endif + +#if MB(RAMPS_14_EFF) || MB(RAMPS_13_EFF) + #define HEATER_0_PIN 8 +#else + #define HEATER_0_PIN 10 // EXTRUDER 1 +#endif + +#if MB(RAMPS_14_SF) || MB(RAMPS_13_SF) || ENABLED(IS_RAMPS_EFB) + #define HEATER_1_PIN -1 +#else + #define HEATER_1_PIN 9 // EXTRUDER 2 (FAN On Sprinter) +#endif + +#define HEATER_2_PIN -1 + +#define TEMP_0_PIN 13 // ANALOG NUMBERING +#define TEMP_1_PIN 15 // ANALOG NUMBERING +#define TEMP_2_PIN -1 // ANALOG NUMBERING + +#if MB(RAMPS_14_EFF) || MB(RAMPS_14_EEF) || MB(RAMPS_14_SF) || MB(RAMPS_13_EFF) || MB(RAMPS_13_EEF) || MB(RAMPS_13_SF) + #define HEATER_BED_PIN -1 // NO BED +#else + #define HEATER_BED_PIN 8 // BED +#endif + +#define TEMP_BED_PIN 14 // ANALOG NUMBERING + +#if ENABLED(Z_PROBE_SLED) + #define SLED_PIN -1 +#endif + +#if ENABLED(ULTRA_LCD) + + #if ENABLED(NEWPANEL) + #if ENABLED(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 + #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_D7 29 + #endif + + #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 + #elif ENABLED(LCD_I2C_PANELOLU2) + #define BTN_EN1 47 // reverse if the encoder turns the wrong way. + #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 // reverse if the encoder turns the wrong way. + #define BTN_EN2 7 // http://files.panucatt.com/datasheets/viki_wiring_diagram.pdf + // tells about 40/42. + // 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 ENABLED(ELB_FULL_GRAPHIC_CONTROLLER) + #define BTN_EN1 35 // reverse if the encoder turns the wrong way. + #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_PIN_BL 33 + #elif ENABLED(MINIPANEL) + #define BEEPER_PIN 42 + // Pins for DOGM SPI LCD Support + #define DOGLCD_A0 44 + #define DOGLCD_CS 66 + #define LCD_PIN_BL 65 // backlight LED on A11/D65 + #define SDSS 53 + + #define KILL_PIN 64 + // GLCD features + //#define LCD_CONTRAST 190 + // 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 //the click switch + //not connected to a pin + #define SD_DETECT_PIN 49 + + #else + + #define BEEPER_PIN 33 // Beeper on AUX-4 + + // buttons are directly attached using AUX-2 + #if ENABLED(REPRAPWORLD_KEYPAD) + #define BTN_EN1 64 // encoder + #define BTN_EN2 59 // encoder + #define BTN_ENC 63 // enter button + #define SHIFT_OUT 40 // shift register + #define SHIFT_CLK 44 // shift register + #define SHIFT_LD 42 // shift register + #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 // the click + #endif + + #if ENABLED(G3D_PANEL) + #define SD_DETECT_PIN 49 + #else + // #define SD_DETECT_PIN -1 // Ramps doesn't use this + #endif + + #endif + #else // !NEWPANEL (Old-style panel with shift register) + + #define BEEPER_PIN 33 // No Beeper added + + // Buttons are 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 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 // !NEWPANEL + +#endif // ULTRA_LCD + +// SPI for Max6675 or Max31855 Thermocouple +#if DISABLED(SDSUPPORT) + #define MAX6675_SS 66 // Do not use pin 53 if there is even the remote possibility of using Display/SD card +#else + #define MAX6675_SS 66 // Do not 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 + +#if DISABLED(SDSUPPORT) + // these pins are defined in the SD library if building with SD support + #define SCK_PIN 52 + #define MISO_PIN 50 + #define MOSI_PIN 51 +#endif + +#ifndef KILL_PIN + // #define KILL_PIN -1 +#endif diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_RAMPS_OLD.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_RAMPS_OLD.h new file mode 100644 index 00000000..213bd3f1 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_RAMPS_OLD.h @@ -0,0 +1,80 @@ +/** + * 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 . + * + */ + +/** + * Arduino Mega with RAMPS v1.0, v1.1, v1.2 pin assignments + */ + +#if !defined(__AVR_ATmega1280__) && !defined(__AVR_ATmega2560__) + #error "Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu." +#endif + +#define BOARD_NAME "MEGA/RAMPS <1.2" + +// Uncomment the following line for RAMPS v1.0 +//#define RAMPS_V_1_0 + +#define X_STEP_PIN 26 +#define X_DIR_PIN 28 +#define X_ENABLE_PIN 24 +#define X_MIN_PIN 3 +#define X_MAX_PIN 2 + +#define Y_STEP_PIN 38 +#define Y_DIR_PIN 40 +#define Y_ENABLE_PIN 36 +#define Y_MIN_PIN 16 +#define Y_MAX_PIN 17 + +#define Z_STEP_PIN 44 +#define Z_DIR_PIN 46 +#define Z_ENABLE_PIN 42 +#define Z_MIN_PIN 18 +#define Z_MAX_PIN 19 + +#define E0_STEP_PIN 32 +#define E0_DIR_PIN 34 +#define E0_ENABLE_PIN 30 + +#define SDPOWER 48 +#define SDSS 53 +#define LED_PIN 13 + +#if ENABLED(RAMPS_V_1_0) // RAMPS_V_1_0 + #define HEATER_0_PIN 12 // RAMPS 1.0 + #define HEATER_BED_PIN -1 // RAMPS 1.0 + #define FAN_PIN 11 // RAMPS 1.0 +#else // RAMPS_V_1_1 or RAMPS_V_1_2 + #define HEATER_0_PIN 10 // RAMPS 1.1 + #define HEATER_BED_PIN 8 // RAMPS 1.1 + #define FAN_PIN 9 // RAMPS 1.1 +#endif + +#define TEMP_0_PIN 2 // MUST USE ANALOG INPUT NUMBERING NOT DIGITAL OUTPUT NUMBERING!!!!!!!!! +#define TEMP_BED_PIN 1 // MUST USE ANALOG INPUT NUMBERING NOT DIGITAL OUTPUT NUMBERING!!!!!!!!! + +// SPI for Max6675 or Max31855 Thermocouple +#if DISABLED(SDSUPPORT) + #define MAX6675_SS 66// Do not use pin 53 if there is even the remote possibility of using Display/SD card +#else + #define MAX6675_SS 66// Do not 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 diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_RIGIDBOARD.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_RIGIDBOARD.h new file mode 100644 index 00000000..a60e492a --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_RIGIDBOARD.h @@ -0,0 +1,117 @@ +/** + * 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 . + * + */ + +/** + * RIGIDBOARD Arduino Mega with RAMPS v1.4 pin assignments + */ + +#define BOARD_NAME "RigidBoard" + +#define RAMPS_D10_PIN 9 // EXTRUDER 1 +#define MOSFET_D_PIN 12 // EXTRUDER 2 or FAN +#ifndef Z_MIN_PROBE_PIN + #define Z_MIN_PROBE_PIN 19 // Z-MAX pin J14 End Stops +#endif + +#include "pins_RAMPS.h" + +#undef TEMP_0_PIN +#undef TEMP_1_PIN +#define TEMP_0_PIN 14 // ANALOG NUMBERING +#define TEMP_1_PIN 13 // ANALOG NUMBERING + +// LCD Panel options for the RigidBoard + +#if ENABLED(RIGIDBOT_PANEL) + + #undef BEEPER_PIN + #define BEEPER_PIN -1 + + // Direction buttons + #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 + + // 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 + +#elif ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER) + + #undef BEEPER_PIN + #define BEEPER_PIN -1 + + #undef SD_DETECT_PIN + #define SD_DETECT_PIN 22 + + #undef KILL_PIN + #define KILL_PIN 32 + +#endif + +// SPI for Max6675 or Max31855 Thermocouple +#undef MAX6675_SS +#if ENABLED(SDSUPPORT) + #define MAX6675_SS 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 +#else + #define MAX6675_SS 53 // Don't use pin 53 if there is even the remote possibility of using Display/SD card +#endif + +// RigidBot swaps E0 / E1 plugs vs RAMPS 1.3 + +#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 + +#undef FAN_PIN +#define FAN_PIN 8 // Same as RAMPS_13_EEF + +#undef PS_ON_PIN +#define PS_ON_PIN -1 + +#undef HEATER_BED_PIN +#define HEATER_BED_PIN 10 + +#undef TEMP_BED_PIN +#define TEMP_BED_PIN 15 // ANALOG NUMBERING + +#define STEPPER_RESET_PIN 41 // Stepper drivers have a reset on RigidBot diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_RIGIDBOARD_V2.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_RIGIDBOARD_V2.h new file mode 100644 index 00000000..7aad12e9 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_RIGIDBOARD_V2.h @@ -0,0 +1,43 @@ +/** + * 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 . + * + */ + +/** + * RIGIDBOARD V2 Arduino Mega with RAMPS v1.4 pin assignments + */ + +#include "pins_RIGIDBOARD.h" + +#undef BOARD_NAME +#define BOARD_NAME "RigidBoard V2" + +// I2C based DAC like on the Printrboard REVF +#define DAC_STEPPER_CURRENT +// Channels available for DAC, For Rigidboard there are 4 +#define DAC_STEPPER_ORDER {0,1,2,3} + +#define DAC_STEPPER_SENSE 0.11 +#define DAC_STEPPER_ADDRESS 0 +#define DAC_STEPPER_MAX 5000 +#define DAC_STEPPER_VREF 1 //internal Vref, gain 1x = 2.048V +#define DAC_STEPPER_GAIN 0 +#define DAC_DISABLE_PIN 42 // set low to enable DAC +#define DAC_OR_ADDRESS 0x01 diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_RUMBA.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_RUMBA.h new file mode 100644 index 00000000..ec5e0236 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_RUMBA.h @@ -0,0 +1,126 @@ +/** + * 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 . + * + */ + +/** + * RUMBA pin assignments + */ + +#ifndef __AVR_ATmega2560__ + #error "Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu." +#endif + +#if E_STEPPERS > 3 || HOTENDS > 3 + #error "RUMBA supports up to 3 hotends / E-steppers. Comment this line to keep going." +#endif + +#define DEFAULT_MACHINE_NAME "Rumba" +#define BOARD_NAME "Rumba" + +#define X_STEP_PIN 17 +#define X_DIR_PIN 16 +#define X_ENABLE_PIN 48 +#define X_MIN_PIN 37 +#define X_MAX_PIN 36 + +#define Y_STEP_PIN 54 +#define Y_DIR_PIN 47 +#define Y_ENABLE_PIN 55 +#define Y_MIN_PIN 35 +#define Y_MAX_PIN 34 + +#define Z_STEP_PIN 57 +#define Z_DIR_PIN 56 +#define Z_ENABLE_PIN 62 +#define Z_MIN_PIN 33 +#define Z_MAX_PIN 32 + +#ifndef Z_MIN_PROBE_PIN + #define Z_MIN_PROBE_PIN 33 +#endif + +#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 E2_STEP_PIN 29 +#define E2_DIR_PIN 28 +#define E2_ENABLE_PIN 39 + +#define LED_PIN 13 + +#define FAN_PIN 7 +#define FAN1_PIN 8 + +#define PS_ON_PIN 45 +#define KILL_PIN 46 + +#define HEATER_0_PIN 2 // EXTRUDER 1 +#define HEATER_1_PIN 3 // EXTRUDER 2 +#define HEATER_2_PIN 6 // EXTRUDER 3 + +#if TEMP_SENSOR_0 == -1 + #define TEMP_0_PIN 6 // ANALOG NUMBERING - connector *K1* on RUMBA thermocouple ADD ON is used +#else + #define TEMP_0_PIN 15 // ANALOG NUMBERING - default connector for thermistor *T0* on rumba board is used +#endif + +#if TEMP_SENSOR_1 == -1 + #define TEMP_1_PIN 5 // ANALOG NUMBERING - connector *K2* on RUMBA thermocouple ADD ON is used +#else + #define TEMP_1_PIN 14 // ANALOG NUMBERING - default connector for thermistor *T1* on rumba board is used +#endif + +#if TEMP_SENSOR_2 == -1 + #define TEMP_2_PIN 7 // ANALOG NUMBERING - connector *K3* on RUMBA thermocouple ADD ON is used <-- this can not be used when TEMP_SENSOR_BED is defined as thermocouple +#else + #define TEMP_2_PIN 13 // ANALOG NUMBERING - default connector for thermistor *T2* on rumba board is used +#endif + +//optional for extruder 4 or chamber: #define TEMP_X_PIN 12 // ANALOG NUMBERING - default connector for thermistor *T3* on rumba board is used +//optional FAN1 can be used as 4th heater output: #define HEATER_3_PIN 8 // EXTRUDER 4 + +#define HEATER_BED_PIN 9 // BED +#if TEMP_SENSOR_BED == -1 + #define TEMP_BED_PIN 7 // ANALOG NUMBERING - connector *K3* on RUMBA thermocouple ADD ON is used <-- this can not be used when TEMP_SENSOR_2 is defined as thermocouple +#else + #define TEMP_BED_PIN 11 // ANALOG NUMBERING - default connector for thermistor *THB* on rumba board is used +#endif + +#define SDSS 53 +#define SD_DETECT_PIN 49 +#define BEEPER_PIN 44 +#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 BTN_EN1 11 +#define BTN_EN2 12 +#define BTN_ENC 43 + +#define SERVO0_PIN 5 + diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_SAINSMART_2IN1.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_SAINSMART_2IN1.h new file mode 100644 index 00000000..8d272ada --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_SAINSMART_2IN1.h @@ -0,0 +1,38 @@ +/** + * 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 . + * + */ + +/** + * Sainsmart 2-in-1 pin assignments + */ + +#if HOTENDS > 2 + #error "Sainsmart 2-in-1 supports up to 2 hotends. Comment this line to keep going." +#endif + +#define BOARD_NAME "Sainsmart" + +#define RAMPS_D10_PIN 9 // E +#define RAMPS_D9_PIN 7 // F PART FAN in front of board next to Extruder heat + // RAMPS_D8_PIN 8 // B +#define MOSFET_D_PIN 10 // F / E + +#include "pins_RAMPS.h" diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_SANGUINOLOLU_11.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_SANGUINOLOLU_11.h new file mode 100644 index 00000000..a6220c59 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_SANGUINOLOLU_11.h @@ -0,0 +1,191 @@ +/** + * 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 . + * + */ + +/** + * Sanguinololu board pin assignments + */ + +#if !defined(__AVR_ATmega644P__) && !defined(__AVR_ATmega1284P__) + #error "Oops! Make sure you have 'Sanguino' selected from the 'Tools -> Boards' menu." +#endif + +#ifndef BOARD_NAME + #define BOARD_NAME "Sanguinololu <1.2" +#endif + +#define IS_MELZI (MB(MELZI) || MB(MELZI_MAKR3D)) + +#define X_STEP_PIN 15 +#define X_DIR_PIN 21 +#define X_STOP_PIN 18 + +#define Y_STEP_PIN 22 +#define Y_DIR_PIN 23 +#define Y_STOP_PIN 19 + +#define Z_STEP_PIN 3 +#define Z_DIR_PIN 2 +#define Z_STOP_PIN 20 + +#define E0_STEP_PIN 1 +#define E0_DIR_PIN 0 + +#if MB(AZTEEG_X1) || MB(STB_11) || IS_MELZI + #define FAN_PIN 4 // Works for Panelolu2 too +#endif + +#if IS_MELZI + #define LED_PIN 27 // On some broken versions of the Sanguino libraries the pin definitions are wrong, so LED_PIN needs to be 28. But you should upgrade your Sanguino libraries! See #368. +#elif MB(STB_11) + #define LCD_PIN_BL 17 // LCD backlight LED +#endif + +#if ENABLED(Z_PROBE_SLED) + #define SLED_PIN -1 +#endif + +#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 + + #if ENABLED(LCD_I2C_PANELOLU2) + #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 + +#endif + +#define TEMP_0_PIN 7 // MUST USE ANALOG INPUT NUMBERING NOT DIGITAL OUTPUT NUMBERING!!!!!!!!! (pin 33 extruder) +#define TEMP_BED_PIN 6 // MUST USE ANALOG INPUT NUMBERING NOT DIGITAL OUTPUT NUMBERING!!!!!!!!! (pin 34 bed) +#define SDSS 31 + +/** + * On some broken versions of the Sanguino libraries the pin definitions are wrong, + * which then needs SDSS as pin 24. But you should upgrade your Sanguino libraries! See #368. + */ +//#define SDSS 24 + +#if ENABLED(ULTRA_LCD) && ENABLED(NEWPANEL) + + // No buzzer installed + #define BEEPER_PIN -1 + + // LCD Pins + #if ENABLED(DOGLCD) + + #if ENABLED(U8GLIB_ST7920) //SPI GLCD 12864 ST7920 ( like [www.digole.com] ) For Melzi V2.0 + + #if IS_MELZI // Melzi board + #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 + #endif + + #else // DOGM SPI LCD Support + + #define DOGLCD_A0 30 + #define DOGLCD_CS 29 + #define LCD_CONTRAST 1 + + #endif + + // Uncomment screen orientation + #define LCD_SCREEN_ROT_0 + //#define LCD_SCREEN_ROT_90 + //#define LCD_SCREEN_ROT_180 + //#define LCD_SCREEN_ROT_270 + + #else // !DOGLCD - Standard Hitachi LCD controller + + #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 // !DOGLCD + + //The encoder and click button + #define BTN_EN1 11 + #define BTN_EN2 10 + #if ENABLED(LCD_I2C_PANELOLU2) + #if IS_MELZI + #define BTN_ENC 29 + #define LCD_SDSS 30 // Panelolu2 SD card reader rather than the Melzi + #else + #define BTN_ENC 30 + #endif + #else + #define BTN_ENC 16 + #define LCD_SDSS 28 // Smart Controller SD card reader rather than the Melzi + #endif //Panelolu2 + + #define SD_DETECT_PIN -1 + +#elif ENABLED(MAKRPANEL) + + #define BEEPER_PIN 29 + + // Pins for DOGM SPI LCD Support + #define DOGLCD_A0 30 + #define DOGLCD_CS 17 + #define LCD_PIN_BL 28 // backlight LED on PA3 + // GLCD features + #define LCD_CONTRAST 1 + // Uncomment screen orientation + #define LCD_SCREEN_ROT_0 + //#define LCD_SCREEN_ROT_90 + //#define LCD_SCREEN_ROT_180 + //#define LCD_SCREEN_ROT_270 + //The encoder and click button + #define BTN_EN1 11 + #define BTN_EN2 10 + #define BTN_ENC 16 + + #define SD_DETECT_PIN -1 + +#endif // MAKRPANEL diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_SANGUINOLOLU_12.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_SANGUINOLOLU_12.h new file mode 100644 index 00000000..f214d6f0 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_SANGUINOLOLU_12.h @@ -0,0 +1,42 @@ +/** + * 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 . + * + */ + +/** + * Sanguinololu V1.2 pin assignments + * + * Applies to the following boards: + * + * AZTEEG_X1 + * MELZI + * MELZI_MAKR3D + * SANGUINOLOLU_12 + * STB_11 + */ + +#define BOARD_NAME "Sanguinololu 1.2" + +#if defined(__AVR_ATmega1284P__) + #define LARGE_FLASH true +#endif + +#define SANGUINOLOLU_V_1_2 +#include "pins_SANGUINOLOLU_11.h" diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_SAV_MKI.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_SAV_MKI.h new file mode 100644 index 00000000..530f63ad --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_SAV_MKI.h @@ -0,0 +1,119 @@ +/** + * 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 . + * + */ + +/** + * SAV MkI pin assignments (AT90USB1286) + * Requires the Teensyduino software with Teensy++ 2.0 selected in Arduino IDE! + * http://www.pjrc.com/teensy/teensyduino.html + * RepRap Clone Wars project board. + */ + +#ifndef __AVR_AT90USB1286__ + #error "Oops! Make sure you have 'Teensy++ 2.0' selected from the 'Tools -> Boards' menu." +#endif + +#define DEFAULT_MACHINE_NAME "SAV MkI" +#define DEFAULT_SOURCE_CODE_URL "https://github.com/fmalpartida/Marlin/tree/SAV-MkI-config" +#define BOARD_NAME "SAV MkI" + +#define LARGE_FLASH true + +#define X_STEP_PIN 0 +#define X_DIR_PIN 1 +#define X_ENABLE_PIN 39 + +#define Y_STEP_PIN 2 +#define Y_DIR_PIN 3 +#define Y_ENABLE_PIN 38 + +#define Z_STEP_PIN 4 +#define Z_DIR_PIN 5 +#define Z_ENABLE_PIN 23 + +#define E0_STEP_PIN 6 +#define E0_DIR_PIN 7 +#define E0_ENABLE_PIN 19 + +#define HEATER_0_PIN 21 // Extruder +#define HEATER_BED_PIN 20 // Bed +#define FAN_PIN 16 // Fan -- from Teensyduino environment. + // For the fan and Teensyduino uses a different pin mapping. +#define X_STOP_PIN 13 +#define Y_STOP_PIN 14 +//#define Z_STOP_PIN 15 +#define Z_STOP_PIN 36 // For inductive sensor. + +#define TEMP_0_PIN 7 // Extruder / Analog pin numbering +#define TEMP_BED_PIN 6 // Bed / Analog pin numbering + +#define SDSS 20 // PB0 - 8 in marlin env. + +// Extension header pin mapping +// ---------------------------- +// SCL (I2C)-D0 A0 (An), IO +// SDA (I2C)-D1 A1 (An), IO +// RX1-D2 A2 (An), IO +// TX1-D3 A3 (An), IO +// PWM-D24 A4 (An), IO +// 5V GND +// 12V GND +#define EXT_AUX_SCL_D0 0 // 0 (teensy), 24 (marlin) +#define EXT_AUX_SDA_D1 1 // 1 (teensy), 25 (marlin) +#define EXT_AUX_RX1_D2 26 // 2 (teensy), 26 (marlin) +#define EXT_AUX_TX1_D3 27 // 3 (teensy), 27 (marlin) +#define EXT_AUX_PWM_D24 12 // 24 (teensy), 12 (marlin) +#define EXT_AUX_A0 0 // Analog +#define EXT_AUX_A0_IO 40 // Digital IO, 38 (teensy), 40 (marlin) +#define EXT_AUX_A1 1 // Analog +#define EXT_AUX_A1_IO 41 // Digital IO, 39 (teensy), 41 (marlin) +#define EXT_AUX_A2 2 // Analog +#define EXT_AUX_A2_IO 42 // Digital IO, 40 (teensy), 42 (marlin) +#define EXT_AUX_A3 3 // Analog +#define EXT_AUX_A3_IO 43 // Digital IO, 41 (teensy), 43 (marlin) +#define EXT_AUX_A4 4 // Analog +#define EXT_AUX_A4_IO 44 // Digital IO, 42 (teensy), 44 (marlin) + + +#define BEEPER_PIN -1 +#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 + +#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 +#endif // SAV_3DLCD + +#if ENABLED(SAV_3DLCD) || ENABLED(SAV_3DGLCD) + #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 +#endif // SAV_3DLCD || SAV_3DGLCD + +#define SERVO0_PIN 41 // In teensy's pin definition for pinMode (in servo.cpp) diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_SETHI.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_SETHI.h new file mode 100644 index 00000000..ff154acf --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_SETHI.h @@ -0,0 +1,86 @@ +/** + * 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 . + * + */ + +/** + * Sethi 3D_1 pin assignments - www.sethi3d.com.br + */ + +#if !defined(__AVR_ATmega644P__) && !defined(__AVR_ATmega644__) && !defined(__AVR_ATmega1284P__) + #error "Oops! Make sure you have 'Sethi 3D' selected from the 'Tools -> Boards' menu." +#endif + +#define BOARD_NAME "Sethi 3D_1" + +#ifndef GEN7_VERSION + #define GEN7_VERSION 12 // v1.x +#endif + +//x axis pins +#define X_STEP_PIN 19 +#define X_DIR_PIN 18 +#define X_ENABLE_PIN 24 +#define X_STOP_PIN 2 + +//y axis pins +#define Y_STEP_PIN 23 +#define Y_DIR_PIN 22 +#define Y_ENABLE_PIN 24 +#define Y_STOP_PIN 0 + +//z axis pins +#define Z_STEP_PIN 26 +#define Z_DIR_PIN 25 +#define Z_ENABLE_PIN 24 +#define Z_MIN_PIN 1 +#define Z_MAX_PIN 0 + +//extruder pins +#define E0_STEP_PIN 28 +#define E0_DIR_PIN 27 +#define E0_ENABLE_PIN 24 + +#define TEMP_0_PIN 1 +#define TEMP_BED_PIN 2 + +#define HEATER_0_PIN 4 +#define HEATER_BED_PIN 3 + + +#if (GEN7_VERSION >= 13) + // Gen7 v1.3 removed the fan pin + #define FAN_PIN -1 +#else + #define FAN_PIN 31 +#endif + +#define PS_ON_PIN 15 + +//All these generations of Gen7 supply thermistor power +//via PS_ON, so ignore bad thermistor readings +#define BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE + +//our pin for debugging. +#define DEBUG_PIN 0 + +//our RS485 pins +#define TX_ENABLE_PIN 12 +#define RX_ENABLE_PIN 13 diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_STB_11.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_STB_11.h new file mode 100644 index 00000000..318dc39c --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_STB_11.h @@ -0,0 +1,34 @@ +/** + * 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 . + * + */ + +/** + * STB V1.1 pin assignments + */ + +#define BOARD_NAME "STB V1.1" + +#if defined(__AVR_ATmega1284P__) + #define LARGE_FLASH true +#endif + +#define SANGUINOLOLU_V_1_2 +#include "pins_SANGUINOLOLU_11.h" diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_TEENSY2.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_TEENSY2.h new file mode 100644 index 00000000..f4f7d4c0 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_TEENSY2.h @@ -0,0 +1,122 @@ +/** + * 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 . + * + */ + +/** + * 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 + * + * CLI build: DEFINES=AT90USBxx_TEENSYPP_ASSIGNMENTS HARDWARE_MOTHERBOARD=84 make + * + * DaveX plan for Teensylu/printrboard-type pinouts for a TeensyBreadboard: + * (ref teensylu & sprinter) + * + * USB + * GND GND |-----#####-----| +5V ATX +5SB + * ATX PS_ON PWM 27 |b7 ##### b6| 26 PWM* Stepper Enable + * PWM 0 |d0 b5| 25 PWM* + * PWM 1 |d1 b4| 24 PWM + * X_MIN 2 |d2 b3| 23 MISO_PIN + * Y_MIN 3 |d3 b2| 22 MOSI_PIN + * Z_MIN 4 |d4 * * b1| 21 SCK_PIN + * 5 |d5 e e b0| 20 SDSS + * LED 6 |d6 5 4 e7| 19 + * 7 |d7 e6| 18 + * LCD RS 8 |e0 | GND + * LCD EN 9 |e1 a4 a0 R| AREF + * LCD D4 10 |c0 a5 a1 f0| 38 A0 ENC_1 + * LCD D5 11 |c1 a6 a2 f1| 39 A1 ENC_2 + * LCD D6 12 |c2 a7 a3 f2| 40 A2 ENC_CLK + * LCD D6 13 |c3 f3| 41 A3 + * Bed Heat PWM 14 |c4 V G R f4| 42 A4 + * Extruder Heat PWM 15 |c5 c n S f5| 43 A5 + * Fan PWM 16 |c6 c d T f6| 44 A6 Bed TC + * 17 |c7 * * * f7| 45 A7 Extruder TC * 4.7k * +5 + * ----------------- + * + * Interior E4: 36, INT4 + * Interior E5: 37, INT5 + * Interior PA0-7: 28-35 -- Printrboard and Teensylu use these pins for step & direction: + * T++ PA Signal Marlin + * + * Z STEP 32 a4 a0 28 X STEP + * Z DIR 33 a5 a1 29 X DIR + * E STEP 34 a6 a2 30 Y STEP + * E DIR 35 a7 a3 31 Y DIR + */ + +#ifndef __AVR_AT90USB1286__ + #error "Oops! Make sure you have 'Teensy++ 2.0' selected from the 'Tools -> Boards' menu." +#endif + +#ifndef AT90USBxx_TEENSYPP_ASSIGNMENTS // use Teensyduino Teensy++2.0 pin assignments instead of Marlin alphabetical. + #error "Uncomment #define AT90USBxx_TEENSYPP_ASSIGNMENTS in fastio.h for this config" + // (or build from command line) +#endif + +#define BOARD_NAME "Teensy++2.0" + +#define LARGE_FLASH true + +#define X_STEP_PIN 28 // 0 Marlin +#define X_DIR_PIN 29 // 1 Marlin +#define X_ENABLE_PIN 26 + +#define Y_STEP_PIN 30 // 2 Marlin +#define Y_DIR_PIN 31 // 3 +#define Y_ENABLE_PIN 26 // Shared w/x + +#define Z_STEP_PIN 32 // 4 +#define Z_DIR_PIN 33 // 5 +#define Z_ENABLE_PIN 26 // Shared w/x + +#define E0_STEP_PIN 34 // 6 +#define E0_DIR_PIN 35 // 7 +#define E0_ENABLE_PIN 26 // Shared w/x + +#define HEATER_0_PIN 15 // 21 // Extruder +#define HEATER_BED_PIN 14 // 20 // Bed +#define FAN_PIN 16 // 22 // Fan + +#define X_STOP_PIN 2 +#define Y_STOP_PIN 3 +#define Z_STOP_PIN 4 + +#define TEMP_0_PIN 7 // Extruder / Analog pin numbering +#define TEMP_BED_PIN 6 // Bed / Analog pin numbering + +#define SDSS 20 // 8 +#define LED_PIN 6 +#define PS_ON_PIN 27 + +#if ENABLED(ULTIPANEL) + #define LCD_PINS_RS 8 + #define LCD_PINS_ENABLE 9 + #define LCD_PINS_D4 10 + #define LCD_PINS_D5 11 + #define LCD_PINS_D6 12 + #define LCD_PINS_D7 13 + #define BTN_EN1 38 + #define BTN_EN2 39 + #define BTN_ENC 40 +#endif diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_TEENSYLU.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_TEENSYLU.h new file mode 100644 index 00000000..77583776 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_TEENSYLU.h @@ -0,0 +1,93 @@ +/** + * 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 . + * + */ + +/** + * Teensylu 0.7 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 + */ + +#ifndef __AVR_AT90USB1286__ + #error "Oops! Make sure you have 'Teensy++ 2.0' selected from the 'Tools -> Boards' menu." +#endif + +#if ENABLED(AT90USBxx_TEENSYPP_ASSIGNMENTS) // use Teensyduino Teensy++2.0 pin assignments instead of Marlin traditional. + #error "These Teensylu assignments depend on traditional Marlin assignments, not AT90USBxx_TEENSYPP_ASSIGNMENTS in fastio.h" +#endif + +#define BOARD_NAME "Teensylu" + +#define LARGE_FLASH true + +#define X_STEP_PIN 0 +#define X_DIR_PIN 1 +#define X_ENABLE_PIN 39 + +#define Y_STEP_PIN 2 +#define Y_DIR_PIN 3 +#define Y_ENABLE_PIN 38 + +#define Z_STEP_PIN 4 +#define Z_DIR_PIN 5 +#define Z_ENABLE_PIN 23 + +#define E0_STEP_PIN 6 +#define E0_DIR_PIN 7 +#define E0_ENABLE_PIN 19 + +#define HEATER_0_PIN 21 // Extruder +#define HEATER_1_PIN 46 +#define HEATER_2_PIN 47 +#define HEATER_BED_PIN 20 + +// If soft or fast PWM is off then use Teensyduino pin numbering, Marlin +// fastio pin numbering otherwise +#if ENABLED(FAN_SOFT_PWM) || ENABLED(FAST_PWM_FAN) + #define FAN_PIN 22 +#else + #define FAN_PIN 16 +#endif + +#define X_STOP_PIN 13 +#define Y_STOP_PIN 14 +#define Z_STOP_PIN 15 +#define TEMP_0_PIN 7 // Extruder / Analog pin numbering +#define TEMP_BED_PIN 6 // Bed / Analog pin numbering + +#define SDSS 8 + +#if ENABLED(ULTRA_LCD) && ENABLED(NEWPANEL) + + #define BEEPER_PIN -1 + + #if ENABLED(LCD_I2C_PANELOLU2) + #define BTN_EN1 27 //RX1 - fastio.h pin mapping 27 + #define BTN_EN2 26 //TX1 - fastio.h pin mapping 26 + #define BTN_ENC 43 //A3 - fastio.h pin mapping 43 + #define SDSS 40 //use SD card on Panelolu2 (Teensyduino pin mapping) + #endif // LCD_I2C_PANELOLU2 + + #define SD_DETECT_PIN -1 + +#endif // ULTRA_LCD && NEWPANEL + diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_ULTIMAIN_2.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_ULTIMAIN_2.h new file mode 100644 index 00000000..c2de0a42 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_ULTIMAIN_2.h @@ -0,0 +1,94 @@ +/** + * 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 . + * + */ + +/** + * Ultiboard v2.0 pin assignments + */ + +#ifndef __AVR_ATmega2560__ + #error "Oops! Make sure you have 'Arduino Mega 2560' selected from the 'Tools -> Boards' menu." +#endif + +#define DEFAULT_MACHINE_NAME "Ultimaker" +#define DEFAULT_SOURCE_CODE_URL "https://github.com/Ultimaker/Marlin" +#define BOARD_NAME "Ultimaker 2.x" + +#define X_STEP_PIN 25 +#define X_DIR_PIN 23 +#define X_STOP_PIN 22 +#define X_ENABLE_PIN 27 + +#define Y_STEP_PIN 32 +#define Y_DIR_PIN 33 +#define Y_STOP_PIN 26 +#define Y_ENABLE_PIN 31 + +#define Z_STEP_PIN 35 +#define Z_DIR_PIN 36 +#define Z_STOP_PIN 29 +#define Z_ENABLE_PIN 34 + +#define HEATER_BED_PIN 4 +#define TEMP_BED_PIN 10 + +#define HEATER_0_PIN 2 +#define TEMP_0_PIN 8 + +#define HEATER_1_PIN 3 +#define TEMP_1_PIN 9 + +#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 SDSS 53 +#define LED_PIN 8 +#define FAN_PIN 7 +#define SAFETY_TRIGGERED_PIN 28 //PIN to detect the safety circuit has triggered +#define MAIN_VOLTAGE_MEASURE_PIN 14 //Analogue PIN to measure the main voltage, with a 100k - 4k7 resitor divider. + +#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 +#define MOTOR_CURRENT_PWM_RANGE 2000 +#define DEFAULT_PWM_MOTOR_CURRENT {1300, 1300, 1250} + +#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 + +//buttons are directly attached +#define BTN_EN1 40 +#define BTN_EN2 41 +#define BTN_ENC 19 + +#define SD_DETECT_PIN 39 diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_ULTIMAKER.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_ULTIMAKER.h new file mode 100644 index 00000000..d770f3a6 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_ULTIMAKER.h @@ -0,0 +1,119 @@ +/** + * 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 . + * + */ + +/** + * Ultimaker pin assignments + */ + +#if !defined(__AVR_ATmega1280__) && !defined(__AVR_ATmega2560__) + #error "Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu." +#endif + +#define DEFAULT_MACHINE_NAME "Ultimaker" +#define DEFAULT_SOURCE_CODE_URL "https://github.com/Ultimaker/Marlin" +#define BOARD_NAME "Ultimaker" + +#define LARGE_FLASH true + +#define SERVO0_PIN 13 // untested + +#define X_STEP_PIN 25 +#define X_DIR_PIN 23 +#define X_MIN_PIN 22 +#define X_MAX_PIN 24 +#define X_ENABLE_PIN 27 + +#define Y_STEP_PIN 31 +#define Y_DIR_PIN 33 +#define Y_MIN_PIN 26 +#define Y_MAX_PIN 28 +#define Y_ENABLE_PIN 29 + +#define Z_STEP_PIN 37 +#define Z_DIR_PIN 39 +#define Z_MIN_PIN 30 +#define Z_MAX_PIN 32 +#define Z_ENABLE_PIN 35 + +#define HEATER_BED_PIN 4 +#define TEMP_BED_PIN 10 + +#define HEATER_0_PIN 2 +#define TEMP_0_PIN 8 + +#define HEATER_1_PIN 3 +#define TEMP_1_PIN 9 + +#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 SDSS 53 +#define LED_PIN 13 +#define FAN_PIN 7 +#define PS_ON_PIN 12 +#define SUICIDE_PIN 54 //PIN that has to be turned on right after start, to keep power flowing. + +#if ENABLED(ULTRA_LCD) + + #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 + + //buttons are directly attached + #define BTN_EN1 40 + #define BTN_EN2 42 + #define BTN_ENC 19 + + #define SD_DETECT_PIN 38 + + #else //!NEWPANEL - Old style panel with shift register + + //buttons are 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 SD_DETECT_PIN -1 + + #endif // !NEWPANEL + +#endif // ULTRA_LCD diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_ULTIMAKER_OLD.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_ULTIMAKER_OLD.h new file mode 100644 index 00000000..33bc26c9 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/pins_ULTIMAKER_OLD.h @@ -0,0 +1,74 @@ +/** + * 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 . + * + */ + +/** + * Ultimaker pin assignments (Old electronics) + */ + +#if !defined(__AVR_ATmega1280__) && !defined(__AVR_ATmega2560__) + #error "Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu." +#endif + +#define DEFAULT_MACHINE_NAME "Ultimaker" +#define DEFAULT_SOURCE_CODE_URL "https://github.com/Ultimaker/Marlin" +#define BOARD_NAME "Ultimaker <1.5.4" + +#define LARGE_FLASH true + +#define X_STEP_PIN 25 +#define X_DIR_PIN 23 +#define X_MIN_PIN 15 +#define X_MAX_PIN 14 +#define X_ENABLE_PIN 27 + +#define Y_STEP_PIN 31 +#define Y_DIR_PIN 33 +#define Y_MIN_PIN 17 +#define Y_MAX_PIN 16 +#define Y_ENABLE_PIN 29 + +#define Z_STEP_PIN 37 +#define Z_DIR_PIN 39 +#define Z_MIN_PIN 19 +#define Z_MAX_PIN 18 +#define Z_ENABLE_PIN 35 + +#define TEMP_0_PIN 8 +#define TEMP_1_PIN 1 + +#define HEATER_0_PIN 2 +#define HEATER_1_PIN 1 + +#define E0_STEP_PIN 43 +#define E0_DIR_PIN 45 +#define E0_ENABLE_PIN 41 + +#define E1_STEP_PIN -1 +#define E1_DIR_PIN -1 +#define E1_ENABLE_PIN -1 + +#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 diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/planner.cpp b/trunk/Arduino/Marlin_K8600_1.1.0RC7/planner.cpp new file mode 100644 index 00000000..4e4d4a18 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/planner.cpp @@ -0,0 +1,1205 @@ +/** + * 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 . + * + */ + +/** + * planner.cpp + * + * Buffer movement commands and manage the acceleration profile plan + * + * Derived from Grbl + * Copyright (c) 2009-2011 Simen Svale Skogsrud + * + * The ring buffer implementation gleaned from the wiring_serial library by David A. Mellis. + * + * + * Reasoning behind the mathematics in this module (in the key of 'Mathematica'): + * + * s == speed, a == acceleration, t == time, d == distance + * + * Basic definitions: + * Speed[s_, a_, t_] := s + (a*t) + * Travel[s_, a_, t_] := Integrate[Speed[s, a, t], t] + * + * Distance to reach a specific speed with a constant acceleration: + * Solve[{Speed[s, a, t] == m, Travel[s, a, t] == d}, d, t] + * d -> (m^2 - s^2)/(2 a) --> estimate_acceleration_distance() + * + * Speed after a given distance of travel with constant acceleration: + * Solve[{Speed[s, a, t] == m, Travel[s, a, t] == d}, m, t] + * m -> Sqrt[2 a d + s^2] + * + * DestinationSpeed[s_, a_, d_] := Sqrt[2 a d + s^2] + * + * When to start braking (di) to reach a specified destination speed (s2) after accelerating + * from initial speed s1 without ever stopping at a plateau: + * Solve[{DestinationSpeed[s1, a, di] == DestinationSpeed[s2, a, d - di]}, di] + * di -> (2 a d - s1^2 + s2^2)/(4 a) --> intersection_distance() + * + * IntersectionDistance[s1_, s2_, a_, d_] := (2 a d - s1^2 + s2^2)/(4 a) + * + */ + +#include "planner.h" +#include "stepper.h" +#include "temperature.h" +#include "ultralcd.h" +#include "language.h" + +#include "Marlin.h" + +#if ENABLED(MESH_BED_LEVELING) + #include "mesh_bed_leveling.h" +#endif + +Planner planner; + + // public: + +/** + * A ring buffer of moves described in steps + */ +block_t Planner::block_buffer[BLOCK_BUFFER_SIZE]; +volatile uint8_t Planner::block_buffer_head = 0; // Index of the next block to be pushed +volatile uint8_t Planner::block_buffer_tail = 0; + +float Planner::max_feedrate_mm_s[NUM_AXIS], // Max speeds in mm per second + Planner::axis_steps_per_mm[NUM_AXIS], + Planner::steps_to_mm[NUM_AXIS]; + +unsigned long Planner::max_acceleration_steps_per_s2[NUM_AXIS], + Planner::max_acceleration_mm_per_s2[NUM_AXIS]; // Use M201 to override by software + +millis_t Planner::min_segment_time; +float Planner::min_feedrate_mm_s, + Planner::acceleration, // Normal acceleration mm/s^2 DEFAULT ACCELERATION for all printing moves. M204 SXXXX + Planner::retract_acceleration, // Retract acceleration mm/s^2 filament pull-back and push-forward while standing still in the other axes M204 TXXXX + Planner::travel_acceleration, // Travel acceleration mm/s^2 DEFAULT ACCELERATION for all NON printing moves. M204 MXXXX + Planner::max_xy_jerk, // The largest speed change requiring no acceleration + Planner::max_z_jerk, + Planner::max_e_jerk, + Planner::min_travel_feedrate_mm_s; + +#if ENABLED(AUTO_BED_LEVELING_FEATURE) + matrix_3x3 Planner::bed_level_matrix; // Transform to compensate for bed level +#endif + +#if ENABLED(AUTOTEMP) + float Planner::autotemp_max = 250, + Planner::autotemp_min = 210, + Planner::autotemp_factor = 0.1; + bool Planner::autotemp_enabled = false; +#endif + +// private: + +long Planner::position[NUM_AXIS] = { 0 }; + +float Planner::previous_speed[NUM_AXIS], + Planner::previous_nominal_speed; + +#if ENABLED(DISABLE_INACTIVE_EXTRUDER) + uint8_t Planner::g_uc_extruder_last_move[EXTRUDERS] = { 0 }; +#endif // DISABLE_INACTIVE_EXTRUDER + +#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 + long Planner::axis_segment_time[2][3] = { {MAX_FREQ_TIME + 1, 0, 0}, {MAX_FREQ_TIME + 1, 0, 0} }; +#endif + +/** + * Class and Instance Methods + */ + +Planner::Planner() { init(); } + +void Planner::init() { + block_buffer_head = block_buffer_tail = 0; + memset(position, 0, sizeof(position)); // clear position + LOOP_XYZE(i) previous_speed[i] = 0.0; + previous_nominal_speed = 0.0; + #if ENABLED(AUTO_BED_LEVELING_FEATURE) + bed_level_matrix.set_to_identity(); + #endif +} + +/** + * Calculate trapezoid parameters, multiplying the entry- and exit-speeds + * by the provided factors. + */ +void Planner::calculate_trapezoid_for_block(block_t* block, float entry_factor, float exit_factor) { + unsigned long initial_rate = ceil(block->nominal_rate * entry_factor), + final_rate = ceil(block->nominal_rate * exit_factor); // (steps per second) + + // Limit minimal step rate (Otherwise the timer will overflow.) + NOLESS(initial_rate, 120); + NOLESS(final_rate, 120); + + long accel = block->acceleration_steps_per_s2; + int32_t accelerate_steps = ceil(estimate_acceleration_distance(initial_rate, block->nominal_rate, accel)); + int32_t decelerate_steps = floor(estimate_acceleration_distance(block->nominal_rate, final_rate, -accel)); + + // Calculate the size of Plateau of Nominal Rate. + int32_t plateau_steps = block->step_event_count - accelerate_steps - decelerate_steps; + + // Is the Plateau of Nominal Rate smaller than nothing? That means no cruising, and we will + // have to use intersection_distance() to calculate when to abort accel and start braking + // in order to reach the final_rate exactly at the end of this block. + if (plateau_steps < 0) { + accelerate_steps = ceil(intersection_distance(initial_rate, final_rate, accel, block->step_event_count)); + accelerate_steps = max(accelerate_steps, 0); // Check limits due to numerical round-off + accelerate_steps = min((uint32_t)accelerate_steps, block->step_event_count);//(We can cast here to unsigned, because the above line ensures that we are above zero) + plateau_steps = 0; + } + + #if ENABLED(ADVANCE) + volatile long initial_advance = block->advance * sq(entry_factor); + volatile long final_advance = block->advance * sq(exit_factor); + #endif // ADVANCE + + // block->accelerate_until = accelerate_steps; + // block->decelerate_after = accelerate_steps+plateau_steps; + CRITICAL_SECTION_START; // Fill variables used by the stepper in a critical section + if (!block->busy) { // Don't update variables if block is busy. + block->accelerate_until = accelerate_steps; + block->decelerate_after = accelerate_steps + plateau_steps; + block->initial_rate = initial_rate; + block->final_rate = final_rate; + #if ENABLED(ADVANCE) + block->initial_advance = initial_advance; + block->final_advance = final_advance; + #endif + } + CRITICAL_SECTION_END; +} + +// "Junction jerk" in this context is the immediate change in speed at the junction of two blocks. +// This method will calculate the junction jerk as the euclidean distance between the nominal +// velocities of the respective blocks. +//inline float junction_jerk(block_t *before, block_t *after) { +// return sqrt( +// pow((before->speed_x-after->speed_x), 2)+pow((before->speed_y-after->speed_y), 2)); +//} + + +// The kernel called by recalculate() when scanning the plan from last to first entry. +void Planner::reverse_pass_kernel(block_t* previous, block_t* current, block_t* next) { + if (!current) return; + UNUSED(previous); + + if (next) { + // If entry speed is already at the maximum entry speed, no need to recheck. Block is cruising. + // If not, block in state of acceleration or deceleration. Reset entry speed to maximum and + // check for maximum allowable speed reductions to ensure maximum possible planned speed. + float max_entry_speed = current->max_entry_speed; + if (current->entry_speed != max_entry_speed) { + + // If nominal length true, max junction speed is guaranteed to be reached. Only compute + // for max allowable speed if block is decelerating and nominal length is false. + if (!current->nominal_length_flag && max_entry_speed > next->entry_speed) { + current->entry_speed = min(max_entry_speed, + max_allowable_speed(-current->acceleration, next->entry_speed, current->millimeters)); + } + else { + current->entry_speed = max_entry_speed; + } + current->recalculate_flag = true; + + } + } // Skip last block. Already initialized and set for recalculation. +} + +/** + * recalculate() needs to go over the current plan twice. + * Once in reverse and once forward. This implements the reverse pass. + */ +void Planner::reverse_pass() { + + if (movesplanned() > 3) { + + block_t* block[3] = { NULL, NULL, NULL }; + + // Make a local copy of block_buffer_tail, because the interrupt can alter it + CRITICAL_SECTION_START; + uint8_t tail = block_buffer_tail; + CRITICAL_SECTION_END + + uint8_t b = BLOCK_MOD(block_buffer_head - 3); + while (b != tail) { + b = prev_block_index(b); + block[2] = block[1]; + block[1] = block[0]; + block[0] = &block_buffer[b]; + reverse_pass_kernel(block[0], block[1], block[2]); + } + } +} + +// The kernel called by recalculate() when scanning the plan from first to last entry. +void Planner::forward_pass_kernel(block_t* previous, block_t* current, block_t* next) { + if (!previous) return; + UNUSED(next); + + // If the previous block is an acceleration block, but it is not long enough to complete the + // full speed change within the block, we need to adjust the entry speed accordingly. Entry + // speeds have already been reset, maximized, and reverse planned by reverse planner. + // If nominal length is true, max junction speed is guaranteed to be reached. No need to recheck. + if (!previous->nominal_length_flag) { + if (previous->entry_speed < current->entry_speed) { + double entry_speed = min(current->entry_speed, + max_allowable_speed(-previous->acceleration, previous->entry_speed, previous->millimeters)); + // Check for junction speed change + if (current->entry_speed != entry_speed) { + current->entry_speed = entry_speed; + current->recalculate_flag = true; + } + } + } +} + +/** + * recalculate() needs to go over the current plan twice. + * Once in reverse and once forward. This implements the forward pass. + */ +void Planner::forward_pass() { + block_t* block[3] = { NULL, NULL, NULL }; + + for (uint8_t b = block_buffer_tail; b != block_buffer_head; b = next_block_index(b)) { + block[0] = block[1]; + block[1] = block[2]; + block[2] = &block_buffer[b]; + forward_pass_kernel(block[0], block[1], block[2]); + } + forward_pass_kernel(block[1], block[2], NULL); +} + +/** + * Recalculate the trapezoid speed profiles for all blocks in the plan + * according to the entry_factor for each junction. Must be called by + * recalculate() after updating the blocks. + */ +void Planner::recalculate_trapezoids() { + int8_t block_index = block_buffer_tail; + block_t* current; + block_t* next = NULL; + + while (block_index != block_buffer_head) { + current = next; + next = &block_buffer[block_index]; + if (current) { + // Recalculate if current block entry or exit junction speed has changed. + if (current->recalculate_flag || next->recalculate_flag) { + // NOTE: Entry and exit factors always > 0 by all previous logic operations. + float nom = current->nominal_speed; + calculate_trapezoid_for_block(current, current->entry_speed / nom, next->entry_speed / nom); + current->recalculate_flag = false; // Reset current only to ensure next trapezoid is computed + } + } + block_index = next_block_index(block_index); + } + // Last/newest block in buffer. Exit speed is set with MINIMUM_PLANNER_SPEED. Always recalculated. + if (next) { + float nom = next->nominal_speed; + calculate_trapezoid_for_block(next, next->entry_speed / nom, (MINIMUM_PLANNER_SPEED) / nom); + next->recalculate_flag = false; + } +} + +/* + * Recalculate the motion plan according to the following algorithm: + * + * 1. Go over every block in reverse order... + * + * Calculate a junction speed reduction (block_t.entry_factor) so: + * + * a. The junction jerk is within the set limit, and + * + * b. No speed reduction within one block requires faster + * deceleration than the one, true constant acceleration. + * + * 2. Go over every block in chronological order... + * + * Dial down junction speed reduction values if: + * a. The speed increase within one block would require faster + * acceleration than the one, true constant acceleration. + * + * After that, all blocks will have an entry_factor allowing all speed changes to + * be performed using only the one, true constant acceleration, and where no junction + * jerk is jerkier than the set limit, Jerky. Finally it will: + * + * 3. Recalculate "trapezoids" for all blocks. + */ +void Planner::recalculate() { + reverse_pass(); + forward_pass(); + recalculate_trapezoids(); +} + + +#if ENABLED(AUTOTEMP) + + void Planner::getHighESpeed() { + static float oldt = 0; + + if (!autotemp_enabled) return; + if (thermalManager.degTargetHotend(0) + 2 < autotemp_min) return; // probably temperature set to zero. + + float high = 0.0; + for (uint8_t b = block_buffer_tail; b != block_buffer_head; b = next_block_index(b)) { + block_t* block = &block_buffer[b]; + if (block->steps[X_AXIS] || block->steps[Y_AXIS] || block->steps[Z_AXIS]) { + float se = (float)block->steps[E_AXIS] / block->step_event_count * block->nominal_speed; // mm/sec; + NOLESS(high, se); + } + } + + float t = autotemp_min + high * autotemp_factor; + t = constrain(t, autotemp_min, autotemp_max); + if (oldt > t) { + t *= (1 - (AUTOTEMP_OLDWEIGHT)); + t += (AUTOTEMP_OLDWEIGHT) * oldt; + } + oldt = t; + thermalManager.setTargetHotend(t, 0); + } + +#endif //AUTOTEMP + +/** + * Maintain fans, paste extruder pressure, + */ +void Planner::check_axes_activity() { + unsigned char axis_active[NUM_AXIS] = { 0 }, + tail_fan_speed[FAN_COUNT]; + + #if FAN_COUNT > 0 + for (uint8_t i = 0; i < FAN_COUNT; i++) tail_fan_speed[i] = fanSpeeds[i]; + #endif + + #if ENABLED(BARICUDA) + #if HAS_HEATER_1 + unsigned char tail_valve_pressure = baricuda_valve_pressure; + #endif + #if HAS_HEATER_2 + unsigned char tail_e_to_p_pressure = baricuda_e_to_p_pressure; + #endif + #endif + + if (blocks_queued()) { + + #if FAN_COUNT > 0 + for (uint8_t i = 0; i < FAN_COUNT; i++) tail_fan_speed[i] = block_buffer[block_buffer_tail].fan_speed[i]; + #endif + + block_t* block; + + #if ENABLED(BARICUDA) + block = &block_buffer[block_buffer_tail]; + #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 + #endif + + for (uint8_t b = block_buffer_tail; b != block_buffer_head; b = next_block_index(b)) { + block = &block_buffer[b]; + LOOP_XYZE(i) if (block->steps[i]) axis_active[i]++; + } + } + #if ENABLED(DISABLE_X) + if (!axis_active[X_AXIS]) disable_x(); + #endif + #if ENABLED(DISABLE_Y) + if (!axis_active[Y_AXIS]) disable_y(); + #endif + #if ENABLED(DISABLE_Z) + if (!axis_active[Z_AXIS]) disable_z(); + #endif + #if ENABLED(DISABLE_E) + if (!axis_active[E_AXIS]) { + disable_e0(); + disable_e1(); + disable_e2(); + disable_e3(); + } + #endif + + #if FAN_COUNT > 0 + + #if defined(FAN_MIN_PWM) + #define CALC_FAN_SPEED(f) (tail_fan_speed[f] ? ( FAN_MIN_PWM + (tail_fan_speed[f] * (255 - FAN_MIN_PWM)) / 255 ) : 0) + #else + #define CALC_FAN_SPEED(f) tail_fan_speed[f] + #endif + + #ifdef FAN_KICKSTART_TIME + + static millis_t fan_kick_end[FAN_COUNT] = { 0 }; + + #define KICKSTART_FAN(f) \ + if (tail_fan_speed[f]) { \ + millis_t ms = millis(); \ + if (fan_kick_end[f] == 0) { \ + fan_kick_end[f] = ms + FAN_KICKSTART_TIME; \ + tail_fan_speed[f] = 255; \ + } else { \ + if (PENDING(ms, fan_kick_end[f])) { \ + tail_fan_speed[f] = 255; \ + } \ + } \ + } else { \ + fan_kick_end[f] = 0; \ + } + + #if HAS_FAN0 + KICKSTART_FAN(0); + #endif + #if HAS_FAN1 + KICKSTART_FAN(1); + #endif + #if HAS_FAN2 + KICKSTART_FAN(2); + #endif + + #endif //FAN_KICKSTART_TIME + + #if ENABLED(FAN_SOFT_PWM) + #if HAS_FAN0 + thermalManager.fanSpeedSoftPwm[0] = CALC_FAN_SPEED(0); + #endif + #if HAS_FAN1 + thermalManager.fanSpeedSoftPwm[1] = CALC_FAN_SPEED(1); + #endif + #if HAS_FAN2 + thermalManager.fanSpeedSoftPwm[2] = CALC_FAN_SPEED(2); + #endif + #else + #if HAS_FAN0 + analogWrite(FAN_PIN, CALC_FAN_SPEED(0)); + #endif + #if HAS_FAN1 + analogWrite(FAN1_PIN, CALC_FAN_SPEED(1)); + #endif + #if HAS_FAN2 + analogWrite(FAN2_PIN, CALC_FAN_SPEED(2)); + #endif + #endif + + #endif // FAN_COUNT > 0 + + #if ENABLED(AUTOTEMP) + getHighESpeed(); + #endif + + #if ENABLED(BARICUDA) + #if HAS_HEATER_1 + analogWrite(HEATER_1_PIN, tail_valve_pressure); + #endif + #if HAS_HEATER_2 + analogWrite(HEATER_2_PIN, tail_e_to_p_pressure); + #endif + #endif +} + +/** + * Planner::buffer_line + * + * Add a new linear movement to the buffer. + * + * x,y,z,e - target position in mm + * fr_mm_s - (target) speed of the move + * extruder - target extruder + */ + +#if ENABLED(AUTO_BED_LEVELING_FEATURE) || ENABLED(MESH_BED_LEVELING) + void Planner::buffer_line(float x, float y, float z, const float& e, float fr_mm_s, const uint8_t extruder) +#else + void Planner::buffer_line(const float& x, const float& y, const float& z, const float& e, float fr_mm_s, const uint8_t extruder) +#endif // AUTO_BED_LEVELING_FEATURE +{ + // Calculate the buffer head after we push this byte + int next_buffer_head = next_block_index(block_buffer_head); + + // If the buffer is full: good! That means we are well ahead of the robot. + // Rest here until there is room in the buffer. + while (block_buffer_tail == next_buffer_head) idle(); + + #if ENABLED(MESH_BED_LEVELING) + if (mbl.active()) + z += mbl.get_z(x - home_offset[X_AXIS], y - home_offset[Y_AXIS]); + #elif ENABLED(AUTO_BED_LEVELING_FEATURE) + apply_rotation_xyz(bed_level_matrix, x, y, z); + #endif + + // The target position of the tool in absolute steps + // Calculate target position in absolute steps + //this should be done after the wait, because otherwise a M92 code within the gcode disrupts this calculation somehow + long target[NUM_AXIS] = { + lround(x * axis_steps_per_mm[X_AXIS]), + lround(y * axis_steps_per_mm[Y_AXIS]), + lround(z * axis_steps_per_mm[Z_AXIS]), + lround(e * axis_steps_per_mm[E_AXIS]) + }; + + long dx = target[X_AXIS] - position[X_AXIS], + dy = target[Y_AXIS] - position[Y_AXIS], + dz = target[Z_AXIS] - position[Z_AXIS]; + + // DRYRUN ignores all temperature constraints and assures that the extruder is instantly satisfied + if (DEBUGGING(DRYRUN)) + position[E_AXIS] = target[E_AXIS]; + + long de = target[E_AXIS] - position[E_AXIS]; + + #if ENABLED(PREVENT_DANGEROUS_EXTRUDE) + if (de) { + if (thermalManager.tooColdToExtrude(extruder)) { + position[E_AXIS] = target[E_AXIS]; // Behave as if the move really took place, but ignore E part + de = 0; // no difference + SERIAL_ECHO_START; + SERIAL_ECHOLNPGM(MSG_ERR_COLD_EXTRUDE_STOP); + } + #if ENABLED(PREVENT_LENGTHY_EXTRUDE) + if (labs(de) > axis_steps_per_mm[E_AXIS] * (EXTRUDE_MAXLENGTH)) { + position[E_AXIS] = target[E_AXIS]; // Behave as if the move really took place, but ignore E part + de = 0; // no difference + SERIAL_ECHO_START; + SERIAL_ECHOLNPGM(MSG_ERR_LONG_EXTRUDE_STOP); + } + #endif + } + #endif + + // Prepare to set up new block + block_t* block = &block_buffer[block_buffer_head]; + + // Mark block as not busy (Not executed by the stepper interrupt) + block->busy = false; + + // Number of steps for each axis + #if ENABLED(COREXY) + // corexy planning + // these equations follow the form of the dA and dB equations on http://www.corexy.com/theory.html + block->steps[A_AXIS] = labs(dx + dy); + block->steps[B_AXIS] = labs(dx - dy); + block->steps[Z_AXIS] = labs(dz); + #elif ENABLED(COREXZ) + // corexz planning + block->steps[A_AXIS] = labs(dx + dz); + block->steps[Y_AXIS] = labs(dy); + block->steps[C_AXIS] = labs(dx - dz); + #elif ENABLED(COREYZ) + // coreyz planning + block->steps[X_AXIS] = labs(dx); + block->steps[B_AXIS] = labs(dy + dz); + block->steps[C_AXIS] = labs(dy - dz); + #else + // default non-h-bot planning + block->steps[X_AXIS] = labs(dx); + block->steps[Y_AXIS] = labs(dy); + block->steps[Z_AXIS] = labs(dz); + #endif + + block->steps[E_AXIS] = labs(de); + block->steps[E_AXIS] *= volumetric_multiplier[extruder]; + block->steps[E_AXIS] *= extruder_multiplier[extruder]; + block->steps[E_AXIS] /= 100; + block->step_event_count = max(block->steps[X_AXIS], max(block->steps[Y_AXIS], max(block->steps[Z_AXIS], block->steps[E_AXIS]))); + + // Bail if this is a zero-length block + if (block->step_event_count <= dropsegments) return; + + // For a mixing extruder, get a magnified step_event_count for each + #if ENABLED(MIXING_EXTRUDER) + for (uint8_t i = 0; i < MIXING_STEPPERS; i++) + block->mix_event_count[i] = (mixing_factor[i] < 0.0001) ? 0 : block->step_event_count / mixing_factor[i]; + #endif + + #if FAN_COUNT > 0 + for (uint8_t i = 0; i < FAN_COUNT; i++) block->fan_speed[i] = fanSpeeds[i]; + #endif + + #if ENABLED(BARICUDA) + block->valve_pressure = baricuda_valve_pressure; + block->e_to_p_pressure = baricuda_e_to_p_pressure; + #endif + + // Compute direction bits for this block + uint8_t db = 0; + #if ENABLED(COREXY) + if (dx < 0) SBI(db, X_HEAD); // Save the real Extruder (head) direction in X Axis + if (dy < 0) SBI(db, Y_HEAD); // ...and Y + if (dz < 0) SBI(db, Z_AXIS); + if (dx + dy < 0) SBI(db, A_AXIS); // Motor A direction + if (dx - dy < 0) SBI(db, B_AXIS); // Motor B direction + #elif ENABLED(COREXZ) + if (dx < 0) SBI(db, X_HEAD); // Save the real Extruder (head) direction in X Axis + if (dy < 0) SBI(db, Y_AXIS); + if (dz < 0) SBI(db, Z_HEAD); // ...and Z + if (dx + dz < 0) SBI(db, A_AXIS); // Motor A direction + if (dx - dz < 0) SBI(db, C_AXIS); // Motor C direction + #elif ENABLED(COREYZ) + if (dx < 0) SBI(db, X_AXIS); + if (dy < 0) SBI(db, Y_HEAD); // Save the real Extruder (head) direction in Y Axis + if (dz < 0) SBI(db, Z_HEAD); // ...and Z + if (dy + dz < 0) SBI(db, B_AXIS); // Motor B direction + if (dy - dz < 0) SBI(db, C_AXIS); // Motor C direction + #else + if (dx < 0) SBI(db, X_AXIS); + if (dy < 0) SBI(db, Y_AXIS); + if (dz < 0) SBI(db, Z_AXIS); + #endif + if (de < 0) SBI(db, E_AXIS); + block->direction_bits = db; + + block->active_extruder = extruder; + + //enable active axes + #if ENABLED(COREXY) + if (block->steps[A_AXIS] || block->steps[B_AXIS]) { + enable_x(); + enable_y(); + } + #if DISABLED(Z_LATE_ENABLE) + if (block->steps[Z_AXIS]) enable_z(); + #endif + #elif ENABLED(COREXZ) + if (block->steps[A_AXIS] || block->steps[C_AXIS]) { + enable_x(); + enable_z(); + } + if (block->steps[Y_AXIS]) enable_y(); + #else + if (block->steps[X_AXIS]) enable_x(); + if (block->steps[Y_AXIS]) enable_y(); + #if DISABLED(Z_LATE_ENABLE) + if (block->steps[Z_AXIS]) enable_z(); + #endif + #endif + + // Enable extruder(s) + if (block->steps[E_AXIS]) { + + #if ENABLED(DISABLE_INACTIVE_EXTRUDER) // Enable only the selected extruder + + for (int i = 0; i < EXTRUDERS; i++) + if (g_uc_extruder_last_move[i] > 0) g_uc_extruder_last_move[i]--; + + switch(extruder) { + case 0: + enable_e0(); + #if ENABLED(DUAL_X_CARRIAGE) + if (extruder_duplication_enabled) { + enable_e1(); + g_uc_extruder_last_move[1] = (BLOCK_BUFFER_SIZE) * 2; + } + #endif + g_uc_extruder_last_move[0] = (BLOCK_BUFFER_SIZE) * 2; + #if EXTRUDERS > 1 + if (g_uc_extruder_last_move[1] == 0) disable_e1(); + #if EXTRUDERS > 2 + if (g_uc_extruder_last_move[2] == 0) disable_e2(); + #if EXTRUDERS > 3 + if (g_uc_extruder_last_move[3] == 0) disable_e3(); + #endif + #endif + #endif + break; + #if EXTRUDERS > 1 + case 1: + enable_e1(); + g_uc_extruder_last_move[1] = (BLOCK_BUFFER_SIZE) * 2; + if (g_uc_extruder_last_move[0] == 0) disable_e0(); + #if EXTRUDERS > 2 + if (g_uc_extruder_last_move[2] == 0) disable_e2(); + #if EXTRUDERS > 3 + if (g_uc_extruder_last_move[3] == 0) disable_e3(); + #endif + #endif + break; + #if EXTRUDERS > 2 + case 2: + enable_e2(); + g_uc_extruder_last_move[2] = (BLOCK_BUFFER_SIZE) * 2; + if (g_uc_extruder_last_move[0] == 0) disable_e0(); + if (g_uc_extruder_last_move[1] == 0) disable_e1(); + #if EXTRUDERS > 3 + if (g_uc_extruder_last_move[3] == 0) disable_e3(); + #endif + break; + #if EXTRUDERS > 3 + case 3: + enable_e3(); + g_uc_extruder_last_move[3] = (BLOCK_BUFFER_SIZE) * 2; + if (g_uc_extruder_last_move[0] == 0) disable_e0(); + if (g_uc_extruder_last_move[1] == 0) disable_e1(); + if (g_uc_extruder_last_move[2] == 0) disable_e2(); + break; + #endif // EXTRUDERS > 3 + #endif // EXTRUDERS > 2 + #endif // EXTRUDERS > 1 + } + #else + enable_e0(); + enable_e1(); + enable_e2(); + enable_e3(); + #endif + } + + if (block->steps[E_AXIS]) + NOLESS(fr_mm_s, min_feedrate_mm_s); + else + NOLESS(fr_mm_s, min_travel_feedrate_mm_s); + + /** + * This part of the code calculates the total length of the movement. + * For cartesian bots, the X_AXIS is the real X movement and same for Y_AXIS. + * But for corexy bots, that is not true. The "X_AXIS" and "Y_AXIS" motors (that should be named to A_AXIS + * and B_AXIS) cannot be used for X and Y length, because A=X+Y and B=X-Y. + * 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. + */ + #if ENABLED(COREXY) || ENABLED(COREXZ) || ENABLED(COREYZ) + float delta_mm[7]; + #if ENABLED(COREXY) + delta_mm[X_HEAD] = dx * steps_to_mm[A_AXIS]; + delta_mm[Y_HEAD] = dy * steps_to_mm[B_AXIS]; + delta_mm[Z_AXIS] = dz * steps_to_mm[Z_AXIS]; + delta_mm[A_AXIS] = (dx + dy) * steps_to_mm[A_AXIS]; + delta_mm[B_AXIS] = (dx - dy) * steps_to_mm[B_AXIS]; + #elif ENABLED(COREXZ) + delta_mm[X_HEAD] = dx * steps_to_mm[A_AXIS]; + delta_mm[Y_AXIS] = dy * steps_to_mm[Y_AXIS]; + delta_mm[Z_HEAD] = dz * steps_to_mm[C_AXIS]; + delta_mm[A_AXIS] = (dx + dz) * steps_to_mm[A_AXIS]; + delta_mm[C_AXIS] = (dx - dz) * steps_to_mm[C_AXIS]; + #elif ENABLED(COREYZ) + delta_mm[X_AXIS] = dx * steps_to_mm[X_AXIS]; + delta_mm[Y_HEAD] = dy * steps_to_mm[B_AXIS]; + delta_mm[Z_HEAD] = dz * steps_to_mm[C_AXIS]; + delta_mm[B_AXIS] = (dy + dz) * steps_to_mm[B_AXIS]; + delta_mm[C_AXIS] = (dy - dz) * steps_to_mm[C_AXIS]; + #endif + #else + float delta_mm[4]; + delta_mm[X_AXIS] = dx * steps_to_mm[X_AXIS]; + delta_mm[Y_AXIS] = dy * steps_to_mm[Y_AXIS]; + delta_mm[Z_AXIS] = dz * steps_to_mm[Z_AXIS]; + #endif + delta_mm[E_AXIS] = 0.01 * (de * steps_to_mm[E_AXIS]) * volumetric_multiplier[extruder] * extruder_multiplier[extruder]; + + if (block->steps[X_AXIS] <= dropsegments && block->steps[Y_AXIS] <= dropsegments && block->steps[Z_AXIS] <= dropsegments) { + block->millimeters = fabs(delta_mm[E_AXIS]); + } + else { + block->millimeters = sqrt( + #if ENABLED(COREXY) + sq(delta_mm[X_HEAD]) + sq(delta_mm[Y_HEAD]) + sq(delta_mm[Z_AXIS]) + #elif ENABLED(COREXZ) + sq(delta_mm[X_HEAD]) + sq(delta_mm[Y_AXIS]) + sq(delta_mm[Z_HEAD]) + #elif ENABLED(COREYZ) + sq(delta_mm[X_AXIS]) + sq(delta_mm[Y_HEAD]) + sq(delta_mm[Z_HEAD]) + #else + sq(delta_mm[X_AXIS]) + sq(delta_mm[Y_AXIS]) + sq(delta_mm[Z_AXIS]) + #endif + ); + } + float inverse_millimeters = 1.0 / block->millimeters; // Inverse millimeters to remove multiple divides + + // Calculate moves/second for this move. No divide by zero due to previous checks. + float inverse_mm_s = fr_mm_s * inverse_millimeters; + + int moves_queued = movesplanned(); + + // Slow down when the buffer starts to empty, rather than wait at the corner for a buffer refill + #if ENABLED(OLD_SLOWDOWN) || ENABLED(SLOWDOWN) + bool mq = moves_queued > 1 && moves_queued < (BLOCK_BUFFER_SIZE) / 2; + #if ENABLED(OLD_SLOWDOWN) + if (mq) fr_mm_s *= 2.0 * moves_queued / (BLOCK_BUFFER_SIZE); + #endif + #if ENABLED(SLOWDOWN) + // segment time im micro seconds + unsigned long segment_time = lround(1000000.0/inverse_mm_s); + if (mq) { + if (segment_time < min_segment_time) { + // buffer is draining, add extra time. The amount of time added increases if the buffer is still emptied more. + inverse_mm_s = 1000000.0 / (segment_time + lround(2 * (min_segment_time - segment_time) / moves_queued)); + #ifdef XY_FREQUENCY_LIMIT + segment_time = lround(1000000.0 / inverse_mm_s); + #endif + } + } + #endif + #endif + + block->nominal_speed = block->millimeters * inverse_mm_s; // (mm/sec) Always > 0 + block->nominal_rate = ceil(block->step_event_count * inverse_mm_s); // (step/sec) Always > 0 + + #if ENABLED(FILAMENT_WIDTH_SENSOR) + static float filwidth_e_count = 0, filwidth_delay_dist = 0; + + //FMM update ring buffer used for delay with filament measurements + if (extruder == FILAMENT_SENSOR_EXTRUDER_NUM && filwidth_delay_index2 >= 0) { //only for extruder with filament sensor and if ring buffer is initialized + + const int MMD_CM = MAX_MEASUREMENT_DELAY + 1, MMD_MM = MMD_CM * 10; + + // increment counters with next move in e axis + filwidth_e_count += delta_mm[E_AXIS]; + filwidth_delay_dist += delta_mm[E_AXIS]; + + // Only get new measurements on forward E movement + if (filwidth_e_count > 0.0001) { + + // Loop the delay distance counter (modulus by the mm length) + while (filwidth_delay_dist >= MMD_MM) filwidth_delay_dist -= MMD_MM; + + // Convert into an index into the measurement array + filwidth_delay_index1 = (int)(filwidth_delay_dist * 0.1 + 0.0001); + + // If the index has changed (must have gone forward)... + if (filwidth_delay_index1 != filwidth_delay_index2) { + filwidth_e_count = 0; // Reset the E movement counter + int8_t meas_sample = thermalManager.widthFil_to_size_ratio() - 100; // Subtract 100 to reduce magnitude - to store in a signed char + do { + filwidth_delay_index2 = (filwidth_delay_index2 + 1) % MMD_CM; // The next unused slot + measurement_delay[filwidth_delay_index2] = meas_sample; // Store the measurement + } while (filwidth_delay_index1 != filwidth_delay_index2); // More slots to fill? + } + } + } + #endif + + // Calculate and limit speed in mm/sec for each axis + float current_speed[NUM_AXIS]; + float speed_factor = 1.0; //factor <=1 do decrease speed + LOOP_XYZE(i) { + current_speed[i] = delta_mm[i] * inverse_mm_s; + float cs = fabs(current_speed[i]), mf = max_feedrate_mm_s[i]; + if (cs > mf) speed_factor = min(speed_factor, mf / cs); + } + + // Max segement time in us. + #ifdef XY_FREQUENCY_LIMIT + + // Check and limit the xy direction change frequency + unsigned char direction_change = block->direction_bits ^ old_direction_bits; + old_direction_bits = block->direction_bits; + segment_time = lround((float)segment_time / speed_factor); + + long xs0 = axis_segment_time[X_AXIS][0], + xs1 = axis_segment_time[X_AXIS][1], + xs2 = axis_segment_time[X_AXIS][2], + ys0 = axis_segment_time[Y_AXIS][0], + ys1 = axis_segment_time[Y_AXIS][1], + ys2 = axis_segment_time[Y_AXIS][2]; + + if (TEST(direction_change, X_AXIS)) { + xs2 = axis_segment_time[X_AXIS][2] = xs1; + xs1 = axis_segment_time[X_AXIS][1] = xs0; + xs0 = 0; + } + xs0 = axis_segment_time[X_AXIS][0] = xs0 + segment_time; + + if (TEST(direction_change, Y_AXIS)) { + ys2 = axis_segment_time[Y_AXIS][2] = axis_segment_time[Y_AXIS][1]; + ys1 = axis_segment_time[Y_AXIS][1] = axis_segment_time[Y_AXIS][0]; + ys0 = 0; + } + ys0 = axis_segment_time[Y_AXIS][0] = ys0 + segment_time; + + long max_x_segment_time = max(xs0, max(xs1, xs2)), + max_y_segment_time = max(ys0, max(ys1, ys2)), + min_xy_segment_time = min(max_x_segment_time, max_y_segment_time); + if (min_xy_segment_time < MAX_FREQ_TIME) { + float low_sf = speed_factor * min_xy_segment_time / (MAX_FREQ_TIME); + speed_factor = min(speed_factor, low_sf); + } + #endif // XY_FREQUENCY_LIMIT + + // Correct the speed + if (speed_factor < 1.0) { + LOOP_XYZE(i) current_speed[i] *= speed_factor; + block->nominal_speed *= speed_factor; + block->nominal_rate *= speed_factor; + } + + // Compute and limit the acceleration rate for the trapezoid generator. + float steps_per_mm = block->step_event_count / block->millimeters; + if (!block->steps[X_AXIS] && !block->steps[Y_AXIS] && !block->steps[Z_AXIS]) { + block->acceleration_steps_per_s2 = ceil(retract_acceleration * steps_per_mm); // convert to: acceleration steps/sec^2 + } + else { + // Limit acceleration per axis + block->acceleration_steps_per_s2 = ceil((block->steps[E_AXIS] ? acceleration : travel_acceleration) * steps_per_mm); + if (max_acceleration_steps_per_s2[X_AXIS] < (block->acceleration_steps_per_s2 * block->steps[X_AXIS]) / block->step_event_count) + block->acceleration_steps_per_s2 = (max_acceleration_steps_per_s2[X_AXIS] * block->step_event_count) / block->steps[X_AXIS]; + if (max_acceleration_steps_per_s2[Y_AXIS] < (block->acceleration_steps_per_s2 * block->steps[Y_AXIS]) / block->step_event_count) + block->acceleration_steps_per_s2 = (max_acceleration_steps_per_s2[Y_AXIS] * block->step_event_count) / block->steps[Y_AXIS]; + if (max_acceleration_steps_per_s2[Z_AXIS] < (block->acceleration_steps_per_s2 * block->steps[Z_AXIS]) / block->step_event_count) + block->acceleration_steps_per_s2 = (max_acceleration_steps_per_s2[Z_AXIS] * block->step_event_count) / block->steps[Z_AXIS]; + if (max_acceleration_steps_per_s2[E_AXIS] < (block->acceleration_steps_per_s2 * block->steps[E_AXIS]) / block->step_event_count) + block->acceleration_steps_per_s2 = (max_acceleration_steps_per_s2[E_AXIS] * block->step_event_count) / block->steps[E_AXIS]; + } + block->acceleration = block->acceleration_steps_per_s2 / steps_per_mm; + block->acceleration_rate = (long)(block->acceleration_steps_per_s2 * 16777216.0 / ((F_CPU) * 0.125)); + + #if 0 // Use old jerk for now + + float junction_deviation = 0.1; + + // Compute path unit vector + double unit_vec[3]; + + unit_vec[X_AXIS] = delta_mm[X_AXIS] * inverse_millimeters; + unit_vec[Y_AXIS] = delta_mm[Y_AXIS] * inverse_millimeters; + unit_vec[Z_AXIS] = delta_mm[Z_AXIS] * inverse_millimeters; + + // 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 + // deviation is defined as the distance from the junction to the closest edge of the circle, + // collinear with the circle center. The circular segment joining the two paths represents the + // path of centripetal acceleration. Solve for max velocity based on max acceleration about the + // radius of the circle, defined indirectly by junction deviation. This may be also viewed as + // path width or max_jerk in the previous grbl version. This approach does not actually deviate + // from path, but used as a robust way to compute cornering speeds, as it takes into account the + // nonlinearities of both the junction angle and junction velocity. + double vmax_junction = MINIMUM_PLANNER_SPEED; // Set default max junction speed + + // Skip first block or when previous_nominal_speed is used as a flag for homing and offset cycles. + if ((block_buffer_head != block_buffer_tail) && (previous_nominal_speed > 0.0)) { + // Compute cosine of angle between previous and current path. (prev_unit_vec is negative) + // NOTE: Max junction velocity is computed without sin() or acos() by trig half angle identity. + double cos_theta = - previous_unit_vec[X_AXIS] * unit_vec[X_AXIS] + - previous_unit_vec[Y_AXIS] * unit_vec[Y_AXIS] + - previous_unit_vec[Z_AXIS] * unit_vec[Z_AXIS] ; + // Skip and use default max junction speed for 0 degree acute junction. + if (cos_theta < 0.95) { + vmax_junction = min(previous_nominal_speed, block->nominal_speed); + // Skip and avoid divide by zero for straight junctions at 180 degrees. Limit to min() of nominal speeds. + if (cos_theta > -0.95) { + // Compute maximum junction velocity based on maximum acceleration and junction deviation + double sin_theta_d2 = sqrt(0.5 * (1.0 - cos_theta)); // Trig half angle identity. Always positive. + vmax_junction = min(vmax_junction, + sqrt(block->acceleration * junction_deviation * sin_theta_d2 / (1.0 - sin_theta_d2))); + } + } + } + #endif + + // Start with a safe speed + float vmax_junction = max_xy_jerk * 0.5, + vmax_junction_factor = 1.0, + mz2 = max_z_jerk * 0.5, + me2 = max_e_jerk * 0.5, + csz = current_speed[Z_AXIS], + cse = current_speed[E_AXIS]; + if (fabs(csz) > mz2) vmax_junction = min(vmax_junction, mz2); + if (fabs(cse) > me2) vmax_junction = min(vmax_junction, me2); + vmax_junction = min(vmax_junction, block->nominal_speed); + float safe_speed = vmax_junction; + + if ((moves_queued > 1) && (previous_nominal_speed > 0.0001)) { + float dsx = current_speed[X_AXIS] - previous_speed[X_AXIS], + dsy = current_speed[Y_AXIS] - previous_speed[Y_AXIS], + dsz = fabs(csz - previous_speed[Z_AXIS]), + dse = fabs(cse - previous_speed[E_AXIS]), + jerk = HYPOT(dsx, dsy); + + // if ((fabs(previous_speed[X_AXIS]) > 0.0001) || (fabs(previous_speed[Y_AXIS]) > 0.0001)) { + vmax_junction = block->nominal_speed; + // } + if (jerk > max_xy_jerk) vmax_junction_factor = max_xy_jerk / jerk; + if (dsz > max_z_jerk) vmax_junction_factor = min(vmax_junction_factor, max_z_jerk / dsz); + if (dse > max_e_jerk) vmax_junction_factor = min(vmax_junction_factor, max_e_jerk / dse); + + vmax_junction = min(previous_nominal_speed, vmax_junction * vmax_junction_factor); // Limit speed to max previous speed + } + block->max_entry_speed = vmax_junction; + + // Initialize block entry speed. Compute based on deceleration to user-defined MINIMUM_PLANNER_SPEED. + double v_allowable = max_allowable_speed(-block->acceleration, MINIMUM_PLANNER_SPEED, block->millimeters); + block->entry_speed = min(vmax_junction, v_allowable); + + // Initialize planner efficiency flags + // Set flag if block will always reach maximum junction speed regardless of entry/exit speeds. + // If a block can de/ac-celerate from nominal speed to zero within the length of the block, then + // the current block and next block junction speeds are guaranteed to always be at their maximum + // junction speeds in deceleration and acceleration, respectively. This is due to how the current + // block nominal speed limits both the current and next maximum junction speeds. Hence, in both + // the reverse and forward planners, the corresponding block junction speed will always be at the + // the maximum junction speed and may always be ignored for any speed reduction checks. + block->nominal_length_flag = (block->nominal_speed <= v_allowable); + block->recalculate_flag = true; // Always calculate trapezoid for new block + + // Update previous path unit_vector and nominal speed + LOOP_XYZE(i) previous_speed[i] = current_speed[i]; + previous_nominal_speed = block->nominal_speed; + + #if ENABLED(LIN_ADVANCE) + + // block->steps[E_AXIS] == block->step_event_count: A problem occurs when there's a very tiny move before a retract. + // In this case, the retract and the move will be executed together. + // This leads to an enormous number of advance steps due to a huge e_acceleration. + // The math is correct, but you don't want a retract move done with advance! + // So this situation is filtered out here. + if (!block->steps[E_AXIS] || (!block->steps[X_AXIS] && !block->steps[Y_AXIS] && !block->steps[Z_AXIS]) || stepper.get_advance_k() == 0 || (uint32_t) block->steps[E_AXIS] == block->step_event_count) { + block->use_advance_lead = false; + } + else { + block->use_advance_lead = true; + block->e_speed_multiplier8 = (block->steps[E_AXIS] << 8) / block->step_event_count; + } + + #elif ENABLED(ADVANCE) + + // Calculate advance rate + if (!block->steps[E_AXIS] || (!block->steps[X_AXIS] && !block->steps[Y_AXIS] && !block->steps[Z_AXIS])) { + block->advance_rate = 0; + block->advance = 0; + } + else { + long acc_dist = estimate_acceleration_distance(0, block->nominal_rate, block->acceleration_steps_per_s2); + float advance = ((STEPS_PER_CUBIC_MM_E) * (EXTRUDER_ADVANCE_K)) * HYPOT(cse, EXTRUSION_AREA) * 256; + block->advance = advance; + block->advance_rate = acc_dist ? advance / (float)acc_dist : 0; + } + /** + SERIAL_ECHO_START; + SERIAL_ECHOPGM("advance :"); + SERIAL_ECHO(block->advance/256.0); + SERIAL_ECHOPGM("advance rate :"); + SERIAL_ECHOLN(block->advance_rate/256.0); + */ + + #endif // ADVANCE or LIN_ADVANCE + + calculate_trapezoid_for_block(block, block->entry_speed / block->nominal_speed, safe_speed / block->nominal_speed); + + // Move buffer head + block_buffer_head = next_buffer_head; + + // Update position + LOOP_XYZE(i) position[i] = target[i]; + + recalculate(); + + stepper.wake_up(); + +} // buffer_line() + +#if ENABLED(AUTO_BED_LEVELING_FEATURE) && DISABLED(DELTA) + + /** + * Get the XYZ position of the steppers as a vector_3. + * + * On CORE machines XYZ is derived from ABC. + */ + vector_3 Planner::adjusted_position() { + vector_3 pos = vector_3(stepper.get_axis_position_mm(X_AXIS), stepper.get_axis_position_mm(Y_AXIS), stepper.get_axis_position_mm(Z_AXIS)); + + //pos.debug("in Planner::adjusted_position"); + //bed_level_matrix.debug("in Planner::adjusted_position"); + + matrix_3x3 inverse = matrix_3x3::transpose(bed_level_matrix); + //inverse.debug("in Planner::inverse"); + + pos.apply_rotation(inverse); + //pos.debug("after rotation"); + + return pos; + } + +#endif // AUTO_BED_LEVELING_FEATURE && !DELTA + +/** + * Directly set the planner XYZ position (hence the stepper positions). + * + * On CORE machines stepper ABC will be translated from the given XYZ. + */ +#if ENABLED(AUTO_BED_LEVELING_FEATURE) || ENABLED(MESH_BED_LEVELING) + void Planner::set_position_mm(float x, float y, float z, const float& e) +#else + void Planner::set_position_mm(const float& x, const float& y, const float& z, const float& e) +#endif // AUTO_BED_LEVELING_FEATURE || MESH_BED_LEVELING + { + #if ENABLED(MESH_BED_LEVELING) + + if (mbl.active()) + z += mbl.get_z(RAW_X_POSITION(x), RAW_Y_POSITION(y)); + + #elif ENABLED(AUTO_BED_LEVELING_FEATURE) + + apply_rotation_xyz(bed_level_matrix, x, y, z); + + #endif + + long nx = position[X_AXIS] = lround(x * axis_steps_per_mm[X_AXIS]), + ny = position[Y_AXIS] = lround(y * axis_steps_per_mm[Y_AXIS]), + nz = position[Z_AXIS] = lround(z * axis_steps_per_mm[Z_AXIS]), + ne = position[E_AXIS] = lround(e * axis_steps_per_mm[E_AXIS]); + stepper.set_position(nx, ny, nz, ne); + previous_nominal_speed = 0.0; // Resets planner junction speeds. Assumes start from rest. + + LOOP_XYZE(i) previous_speed[i] = 0.0; + } + +/** + * Directly set the planner E position (hence the stepper E position). + */ +void Planner::set_e_position_mm(const float& e) { + position[E_AXIS] = lround(e * axis_steps_per_mm[E_AXIS]); + stepper.set_e_position(position[E_AXIS]); + previous_speed[E_AXIS] = 0.0; +} + +// Recalculate the steps/s^2 acceleration rates, based on the mm/s^2 +void Planner::reset_acceleration_rates() { + LOOP_XYZE(i) + max_acceleration_steps_per_s2[i] = max_acceleration_mm_per_s2[i] * axis_steps_per_mm[i]; +} + +// Recalculate position, steps_to_mm if axis_steps_per_mm changes! +void Planner::refresh_positioning() { + LOOP_XYZE(i) steps_to_mm[i] = 1.0 / axis_steps_per_mm[i]; + #if ENABLED(DELTA) || ENABLED(SCARA) + inverse_kinematics(current_position); + set_position_mm(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], current_position[E_AXIS]); + #else + set_position_mm(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + #endif + reset_acceleration_rates(); +} + +#if ENABLED(AUTOTEMP) + + void Planner::autotemp_M109() { + autotemp_enabled = code_seen('F'); + if (autotemp_enabled) autotemp_factor = code_value_temp_diff(); + if (code_seen('S')) autotemp_min = code_value_temp_abs(); + if (code_seen('B')) autotemp_max = code_value_temp_abs(); + } + +#endif diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/planner.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/planner.h new file mode 100644 index 00000000..74055366 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/planner.h @@ -0,0 +1,335 @@ +/** + * 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 . + * + */ + +/** + * planner.h + * + * Buffer movement commands and manage the acceleration profile plan + * + * Derived from Grbl + * Copyright (c) 2009-2011 Simen Svale Skogsrud + */ + +#ifndef PLANNER_H +#define PLANNER_H + +#include "types.h" +#include "MarlinConfig.h" + +#if ENABLED(AUTO_BED_LEVELING_FEATURE) + #include "vector_3.h" +#endif + +class Planner; +extern Planner planner; + +/** + * struct block_t + * + * A single entry in the planner buffer. + * Tracks linear movement over multiple axes. + * + * The "nominal" values are as-specified by gcode, and + * may never actually be reached due to acceleration limits. + */ +typedef struct { + + unsigned char active_extruder; // The extruder to move (if E move) + + // Fields used by the bresenham algorithm for tracing the line + long steps[NUM_AXIS]; // Step count along each axis + unsigned long step_event_count; // The number of step events required to complete this block + + #if ENABLED(MIXING_EXTRUDER) + unsigned long mix_event_count[MIXING_STEPPERS]; // Scaled step_event_count for the mixing steppers + #endif + + long accelerate_until, // The index of the step event on which to stop acceleration + decelerate_after, // The index of the step event on which to start decelerating + acceleration_rate; // The acceleration rate used for acceleration calculation + + unsigned char direction_bits; // The direction bit set for this block (refers to *_DIRECTION_BIT in config.h) + + // Advance extrusion + #if ENABLED(LIN_ADVANCE) + bool use_advance_lead; + int e_speed_multiplier8; // Factorised by 2^8 to avoid float + #elif ENABLED(ADVANCE) + long advance_rate; + volatile long initial_advance; + volatile long final_advance; + float advance; + #endif + + // Fields used by the motion planner to manage acceleration + float nominal_speed, // The nominal speed for this block in mm/sec + entry_speed, // Entry speed at previous-current junction in mm/sec + max_entry_speed, // Maximum allowable junction entry speed in mm/sec + millimeters, // The total travel of this block in mm + acceleration; // acceleration mm/sec^2 + unsigned char recalculate_flag, // Planner flag to recalculate trapezoids on entry junction + nominal_length_flag; // Planner flag for nominal speed always reached + + // Settings for the trapezoid generator + unsigned long nominal_rate, // The nominal step rate for this block in step_events/sec + initial_rate, // The jerk-adjusted step rate at start of block + final_rate, // The minimal rate at exit + acceleration_steps_per_s2; // acceleration steps/sec^2 + + #if FAN_COUNT > 0 + unsigned long fan_speed[FAN_COUNT]; + #endif + + #if ENABLED(BARICUDA) + unsigned long valve_pressure, e_to_p_pressure; + #endif + + volatile char busy; + +} block_t; + +#define BLOCK_MOD(n) ((n)&(BLOCK_BUFFER_SIZE-1)) + +class Planner { + + public: + + /** + * A ring buffer of moves described in steps + */ + static block_t block_buffer[BLOCK_BUFFER_SIZE]; + static volatile uint8_t block_buffer_head; // Index of the next block to be pushed + static volatile uint8_t block_buffer_tail; + + static float max_feedrate_mm_s[NUM_AXIS]; // Max speeds in mm per second + static float axis_steps_per_mm[NUM_AXIS]; + static float steps_to_mm[NUM_AXIS]; + static unsigned long max_acceleration_steps_per_s2[NUM_AXIS]; + static unsigned long max_acceleration_mm_per_s2[NUM_AXIS]; // Use M201 to override by software + + static millis_t min_segment_time; + static float min_feedrate_mm_s; + static float acceleration; // Normal acceleration mm/s^2 DEFAULT ACCELERATION for all printing moves. M204 SXXXX + static float retract_acceleration; // Retract acceleration mm/s^2 filament pull-back and push-forward while standing still in the other axes M204 TXXXX + static float travel_acceleration; // Travel acceleration mm/s^2 DEFAULT ACCELERATION for all NON printing moves. M204 MXXXX + static float max_xy_jerk; // The largest speed change requiring no acceleration + static float max_z_jerk; + static float max_e_jerk; + static float min_travel_feedrate_mm_s; + + #if ENABLED(AUTO_BED_LEVELING_FEATURE) + static matrix_3x3 bed_level_matrix; // Transform to compensate for bed level + #endif + + private: + + /** + * The current position of the tool in absolute steps + * Recalculated if any axis_steps_per_mm are changed by gcode + */ + static long position[NUM_AXIS]; + + /** + * Speed of previous path line segment + */ + static float previous_speed[NUM_AXIS]; + + /** + * Nominal speed of previous path line segment + */ + static float previous_nominal_speed; + + #if ENABLED(DISABLE_INACTIVE_EXTRUDER) + /** + * 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 long(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 long axis_segment_time[2][3]; + #endif + + public: + + /** + * Instance Methods + */ + + Planner(); + + void init(); + + /** + * Static (class) Methods + */ + + static void reset_acceleration_rates(); + static void refresh_positioning(); + + // Manage fans, paste pressure, etc. + static void check_axes_activity(); + + /** + * Number of moves currently in the planner + */ + static uint8_t movesplanned() { return BLOCK_MOD(block_buffer_head - block_buffer_tail + BLOCK_BUFFER_SIZE); } + + static bool is_full() { return (block_buffer_tail == BLOCK_MOD(block_buffer_head + 1)); } + + #if ENABLED(AUTO_BED_LEVELING_FEATURE) || ENABLED(MESH_BED_LEVELING) + + #if ENABLED(AUTO_BED_LEVELING_FEATURE) + /** + * The corrected position, applying the bed level matrix + */ + static vector_3 adjusted_position(); + #endif + + /** + * Add a new linear movement to the buffer. + * + * x,y,z,e - target position in mm + * fr_mm_s - (target) speed of the move (mm/s) + * extruder - target extruder + */ + static void buffer_line(float x, float y, float z, const float& e, float fr_mm_s, const uint8_t extruder); + + /** + * Set the planner.position and individual stepper positions. + * Used by G92, G28, G29, and other procedures. + * + * Multiplies by axis_steps_per_mm[] and does necessary conversion + * for COREXY / COREXZ / COREYZ to set the corresponding stepper positions. + * + * Clears previous speed values. + */ + static void set_position_mm(float x, float y, float z, const float& e); + + #else + + static void buffer_line(const float& x, const float& y, const float& z, const float& e, float fr_mm_s, const uint8_t extruder); + static void set_position_mm(const float& x, const float& y, const float& z, const float& e); + + #endif // AUTO_BED_LEVELING_FEATURE || MESH_BED_LEVELING + + /** + * Set the E position (mm) of the planner (and the E stepper) + */ + static void set_e_position_mm(const float& e); + + /** + * Does the buffer have any blocks queued? + */ + static bool blocks_queued() { return (block_buffer_head != block_buffer_tail); } + + /** + * "Discards" the block and "releases" the memory. + * Called when the current block is no longer needed. + */ + static void discard_current_block() { + if (blocks_queued()) + block_buffer_tail = BLOCK_MOD(block_buffer_tail + 1); + } + + /** + * The current block. NULL if the buffer is empty. + * This also marks the block as busy. + */ + static block_t* get_current_block() { + if (blocks_queued()) { + block_t* block = &block_buffer[block_buffer_tail]; + block->busy = true; + return block; + } + else + return NULL; + } + + #if ENABLED(AUTOTEMP) + static float autotemp_max; + static float autotemp_min; + static float autotemp_factor; + static bool autotemp_enabled; + static void getHighESpeed(); + static void autotemp_M109(); + #endif + + private: + + /** + * Get the index of the next / previous block in the ring buffer + */ + static int8_t next_block_index(int8_t block_index) { return BLOCK_MOD(block_index + 1); } + static int8_t prev_block_index(int8_t block_index) { return BLOCK_MOD(block_index - 1); } + + /** + * Calculate the distance (not time) it takes to accelerate + * from initial_rate to target_rate using the given acceleration: + */ + static float estimate_acceleration_distance(float initial_rate, float target_rate, float accel) { + if (accel == 0) return 0; // accel was 0, set acceleration distance to 0 + return (sq(target_rate) - sq(initial_rate)) / (accel * 2); + } + + /** + * Return the point at which you must start braking (at the rate of -'acceleration') if + * you start at 'initial_rate', accelerate (until reaching the point), and want to end at + * 'final_rate' after traveling 'distance'. + * + * This is used to compute the intersection point between acceleration and deceleration + * in cases where the "trapezoid" has no plateau (i.e., never reaches maximum speed) + */ + static float intersection_distance(float initial_rate, float final_rate, float accel, float distance) { + if (accel == 0) return 0; // accel was 0, set intersection distance to 0 + return (accel * 2 * distance - sq(initial_rate) + sq(final_rate)) / (accel * 4); + } + + /** + * Calculate the maximum allowable speed at this point, in order + * to reach 'target_velocity' using 'acceleration' within a given + * 'distance'. + */ + static float max_allowable_speed(float accel, float target_velocity, float distance) { + return sqrt(sq(target_velocity) - 2 * accel * distance); + } + + static void calculate_trapezoid_for_block(block_t* block, float entry_factor, float exit_factor); + + static void reverse_pass_kernel(block_t* previous, block_t* current, block_t* next); + static void forward_pass_kernel(block_t* previous, block_t* current, block_t* next); + + static void reverse_pass(); + static void forward_pass(); + + static void recalculate_trapezoids(); + + static void recalculate(); + +}; + +#endif // PLANNER_H diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/planner_bezier.cpp b/trunk/Arduino/Marlin_K8600_1.1.0RC7/planner_bezier.cpp new file mode 100644 index 00000000..6ca7afd1 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/planner_bezier.cpp @@ -0,0 +1,203 @@ +/** + * 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 . + * + */ + +/** + * planner_bezier.cpp + * + * Compute and buffer movement commands for bezier curves + * + */ + +#include "Marlin.h" + +#if ENABLED(BEZIER_CURVE_SUPPORT) + +#include "planner.h" +#include "language.h" +#include "temperature.h" + +// See the meaning in the documentation of cubic_b_spline(). +#define MIN_STEP 0.002 +#define MAX_STEP 0.1 +#define SIGMA 0.1 + +/* Compute the linear interpolation between to real numbers. +*/ +inline static float interp(float a, float b, float t) { return (1.0 - t) * a + t * b; } + +/** + * Compute a Bézier curve using the De Casteljau's algorithm (see + * https://en.wikipedia.org/wiki/De_Casteljau%27s_algorithm), which is + * easy to code and has good numerical stability (very important, + * since Arudino works with limited precision real numbers). + */ +inline static float eval_bezier(float a, float b, float c, float d, float t) { + float iab = interp(a, b, t); + float ibc = interp(b, c, t); + float icd = interp(c, d, t); + float iabc = interp(iab, ibc, t); + float ibcd = interp(ibc, icd, t); + float iabcd = interp(iabc, ibcd, t); + return iabcd; +} + +/** + * We approximate Euclidean distance with the sum of the coordinates + * offset (so-called "norm 1"), which is quicker to compute. + */ +inline static float dist1(float x1, float y1, float x2, float y2) { return fabs(x1 - x2) + fabs(y1 - y2); } + +/** + * The algorithm for computing the step is loosely based on the one in Kig + * (See https://sources.debian.net/src/kig/4:15.08.3-1/misc/kigpainter.cpp/#L759) + * However, we do not use the stack. + * + * The algorithm goes as it follows: the parameters t runs from 0.0 to + * 1.0 describing the curve, which is evaluated by eval_bezier(). At + * each iteration we have to choose a step, i.e., the increment of the + * t variable. By default the step of the previous iteration is taken, + * and then it is enlarged or reduced depending on how straight the + * curve locally is. The step is always clamped between MIN_STEP/2 and + * 2*MAX_STEP. MAX_STEP is taken at the first iteration. + * + * For some t, the step value is considered acceptable if the curve in + * the interval [t, t+step] is sufficiently straight, i.e., + * sufficiently close to linear interpolation. In practice the + * following test is performed: the distance between eval_bezier(..., + * t+step/2) is evaluated and compared with 0.5*(eval_bezier(..., + * t)+eval_bezier(..., t+step)). If it is smaller than SIGMA, then the + * step value is considered acceptable, otherwise it is not. The code + * seeks to find the larger step value which is considered acceptable. + * + * At every iteration the recorded step value is considered and then + * iteratively halved until it becomes acceptable. If it was already + * acceptable in the beginning (i.e., no halving were done), then + * maybe it was necessary to enlarge it; then it is iteratively + * doubled while it remains acceptable. The last acceptable value + * found is taken, provided that it is between MIN_STEP and MAX_STEP + * and does not bring t over 1.0. + * + * Caveat: this algorithm is not perfect, since it can happen that a + * step is considered acceptable even when the curve is not linear at + * all in the interval [t, t+step] (but its mid point coincides "by + * chance" with the midpoint according to the parametrization). This + * kind of glitches can be eliminated with proper first derivative + * estimates; however, given the improbability of such configurations, + * the mitigation offered by MIN_STEP and the small computational + * power available on Arduino, I think it is not wise to implement it. + */ +void cubic_b_spline(const float position[NUM_AXIS], const float target[NUM_AXIS], const float offset[4], float fr_mm_s, uint8_t extruder) { + // Absolute first and second control points are recovered. + float first0 = position[X_AXIS] + offset[0]; + float first1 = position[Y_AXIS] + offset[1]; + float second0 = target[X_AXIS] + offset[2]; + float second1 = target[Y_AXIS] + offset[3]; + float t = 0.0; + + float bez_target[4]; + bez_target[X_AXIS] = position[X_AXIS]; + bez_target[Y_AXIS] = position[Y_AXIS]; + float step = MAX_STEP; + + millis_t next_idle_ms = millis() + 200UL; + + while (t < 1.0) { + + thermalManager.manage_heater(); + millis_t now = millis(); + if (ELAPSED(now, next_idle_ms)) { + next_idle_ms = now + 200UL; + idle(); + } + + // First try to reduce the step in order to make it sufficiently + // close to a linear interpolation. + bool did_reduce = false; + float new_t = t + step; + NOMORE(new_t, 1.0); + float new_pos0 = eval_bezier(position[X_AXIS], first0, second0, target[X_AXIS], new_t); + float new_pos1 = eval_bezier(position[Y_AXIS], first1, second1, target[Y_AXIS], new_t); + for (;;) { + if (new_t - t < (MIN_STEP)) break; + float candidate_t = 0.5 * (t + new_t); + float candidate_pos0 = eval_bezier(position[X_AXIS], first0, second0, target[X_AXIS], candidate_t); + float candidate_pos1 = eval_bezier(position[Y_AXIS], first1, second1, target[Y_AXIS], candidate_t); + float interp_pos0 = 0.5 * (bez_target[X_AXIS] + new_pos0); + float interp_pos1 = 0.5 * (bez_target[Y_AXIS] + new_pos1); + if (dist1(candidate_pos0, candidate_pos1, interp_pos0, interp_pos1) <= (SIGMA)) break; + new_t = candidate_t; + new_pos0 = candidate_pos0; + new_pos1 = candidate_pos1; + did_reduce = true; + } + + // If we did not reduce the step, maybe we should enlarge it. + if (!did_reduce) for (;;) { + if (new_t - t > MAX_STEP) break; + float candidate_t = t + 2.0 * (new_t - t); + if (candidate_t >= 1.0) break; + float candidate_pos0 = eval_bezier(position[X_AXIS], first0, second0, target[X_AXIS], candidate_t); + float candidate_pos1 = eval_bezier(position[Y_AXIS], first1, second1, target[Y_AXIS], candidate_t); + float interp_pos0 = 0.5 * (bez_target[X_AXIS] + candidate_pos0); + float interp_pos1 = 0.5 * (bez_target[Y_AXIS] + candidate_pos1); + if (dist1(new_pos0, new_pos1, interp_pos0, interp_pos1) > (SIGMA)) break; + new_t = candidate_t; + new_pos0 = candidate_pos0; + new_pos1 = candidate_pos1; + } + + // Check some postcondition; they are disabled in the actual + // Marlin build, but if you test the same code on a computer you + // may want to check they are respect. + /* + assert(new_t <= 1.0); + if (new_t < 1.0) { + assert(new_t - t >= (MIN_STEP) / 2.0); + assert(new_t - t <= (MAX_STEP) * 2.0); + } + */ + + step = new_t - t; + t = new_t; + + // Compute and send new position + bez_target[X_AXIS] = new_pos0; + bez_target[Y_AXIS] = new_pos1; + // FIXME. The following two are wrong, since the parameter t is + // not linear in the distance. + bez_target[Z_AXIS] = interp(position[Z_AXIS], target[Z_AXIS], t); + bez_target[E_AXIS] = interp(position[E_AXIS], target[E_AXIS], t); + clamp_to_software_endstops(bez_target); + + #if ENABLED(DELTA) || ENABLED(SCARA) + inverse_kinematics(bez_target); + #if ENABLED(DELTA) && ENABLED(AUTO_BED_LEVELING_FEATURE) + adjust_delta(bez_target); + #endif + planner.buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], bez_target[E_AXIS], fr_mm_s, extruder); + #else + planner.buffer_line(bez_target[X_AXIS], bez_target[Y_AXIS], bez_target[Z_AXIS], bez_target[E_AXIS], fr_mm_s, extruder); + #endif + } +} + +#endif // BEZIER_CURVE_SUPPORT diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/planner_bezier.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/planner_bezier.h new file mode 100644 index 00000000..d17e7c80 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/planner_bezier.h @@ -0,0 +1,43 @@ +/** + * 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 . + * + */ + +/** + * planner_bezier.h + * + * Compute and buffer movement commands for bezier curves + * + */ + +#ifndef PLANNER_BEZIER_H +#define PLANNER_BEZIER_H + +#include "Marlin.h" + +void cubic_b_spline( + const float position[NUM_AXIS], // current position + const float target[NUM_AXIS], // target position + const float offset[4], // a pair of offsets + float fr_mm_s, + uint8_t extruder + ); + +#endif // PLANNER_BEZIER_H diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/point_t.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/point_t.h new file mode 100644 index 00000000..360abce6 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/point_t.h @@ -0,0 +1,77 @@ +/** + * 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 . + * + */ + +#ifndef __POINT_T__ +#define __POINT_T__ + +/** + * @brief Cartesian Point + * @details Represents a three dimensional point on Cartesian coordinate system, + * using an additional fourth dimension for the extrusion length. + * + * @param x The x-coordinate of the point. + * @param y The y-coordinate of the point. + * @param z The z-coordinate of the point. + * @param e The e-coordinate of the point. + */ +struct point_t { + float x; + float y; + float z; + float e; + + /** + * @brief Two dimensional point constructor + * + * @param x The x-coordinate of the point. + * @param y The y-coordinate of the point. + */ + point_t(float const x, float const y) + : point_t(x, y, NAN, NAN) {} + + /** + * @brief Three dimensional point constructor + * + * @param x The x-coordinate of the point. + * @param y The y-coordinate of the point. + * @param z The z-coordinate of the point. + */ + point_t(float const x, float const y, float const z) + : point_t(x, y, z, NAN) {} + + /** + * @brief Tree dimensional point constructor with extrusion length + * + * @param x The x-coordinate of the point. + * @param y The y-coordinate of the point. + * @param z The z-coordinate of the point. + * @param e The e-coordinate of the point. + */ + point_t(float const x, float const y, float const z, float const e) { + this->x = x; + this->y = y; + this->z = z; + this->e = e; + } +}; + +#endif // __POINT_T__ diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/printcounter.cpp b/trunk/Arduino/Marlin_K8600_1.1.0RC7/printcounter.cpp new file mode 100644 index 00000000..b6cef6e7 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/printcounter.cpp @@ -0,0 +1,233 @@ +/* + * 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 . + * + */ + +#include "Marlin.h" +#include "printcounter.h" +#include "duration_t.h" + +PrintCounter::PrintCounter(): super() { + this->loadStats(); +} + +millis_t PrintCounter::deltaDuration() { + #if ENABLED(DEBUG_PRINTCOUNTER) + PrintCounter::debug(PSTR("deltaDuration")); + #endif + + millis_t tmp = this->lastDuration; + this->lastDuration = this->duration(); + return this->lastDuration - tmp; +} + +bool PrintCounter::isLoaded() { + return this->loaded; +} + +void PrintCounter::incFilamentUsed(double const &amount) { + #if ENABLED(DEBUG_PRINTCOUNTER) + PrintCounter::debug(PSTR("incFilamentUsed")); + #endif + + // Refuses to update data if object is not loaded + if (!this->isLoaded()) return; + + this->data.filamentUsed += amount; // mm +} + + +void PrintCounter::initStats() { + #if ENABLED(DEBUG_PRINTCOUNTER) + PrintCounter::debug(PSTR("initStats")); + #endif + + this->loaded = true; + this->data = { 0, 0, 0, 0, 0.0 }; + + this->saveStats(); + eeprom_write_byte((uint8_t *) this->address, 0x16); +} + +void PrintCounter::loadStats() { + #if ENABLED(DEBUG_PRINTCOUNTER) + PrintCounter::debug(PSTR("loadStats")); + #endif + + // Checks if the EEPROM block is initialized + if (eeprom_read_byte((uint8_t *) this->address) != 0x16) this->initStats(); + else eeprom_read_block(&this->data, + (void *)(this->address + sizeof(uint8_t)), sizeof(printStatistics)); + + this->loaded = true; +} + +void PrintCounter::saveStats() { + #if ENABLED(DEBUG_PRINTCOUNTER) + PrintCounter::debug(PSTR("saveStats")); + #endif + + // Refuses to save data if object is not loaded + if (!this->isLoaded()) return; + + // Saves the struct to EEPROM + eeprom_update_block(&this->data, + (void *)(this->address + sizeof(uint8_t)), sizeof(printStatistics)); +} + +void PrintCounter::showStats() { + char buffer[21]; + duration_t elapsed; + + SERIAL_PROTOCOLPGM(MSG_STATS); + + SERIAL_ECHOPGM("Prints: "); + SERIAL_ECHO(this->data.totalPrints); + + SERIAL_ECHOPGM(", Finished: "); + SERIAL_ECHO(this->data.finishedPrints); + + SERIAL_ECHOPGM(", Failed: "); // Note: Removes 1 from failures with an active counter + SERIAL_ECHO(this->data.totalPrints - this->data.finishedPrints + - ((this->isRunning() || this->isPaused()) ? 1 : 0)); + + SERIAL_EOL; + SERIAL_PROTOCOLPGM(MSG_STATS); + + elapsed = this->data.printTime; + elapsed.toString(buffer); + + SERIAL_ECHOPGM("Total time: "); + SERIAL_ECHO(buffer); + + #if ENABLED(DEBUG_PRINTCOUNTER) + SERIAL_ECHOPGM(" ("); + SERIAL_ECHO(this->data.printTime); + SERIAL_ECHOPGM(")"); + #endif + + elapsed = this->data.longestPrint; + elapsed.toString(buffer); + + SERIAL_ECHOPGM(", Longest job: "); + SERIAL_ECHO(buffer); + + #if ENABLED(DEBUG_PRINTCOUNTER) + SERIAL_ECHOPGM(" ("); + SERIAL_ECHO(this->data.longestPrint); + SERIAL_ECHOPGM(")"); + #endif + + SERIAL_EOL; + SERIAL_PROTOCOLPGM(MSG_STATS); + + SERIAL_ECHOPGM("Filament used: "); + SERIAL_ECHO(this->data.filamentUsed / 1000); + SERIAL_ECHOPGM("m"); + + SERIAL_EOL; +} + +void PrintCounter::tick() { + if (!this->isRunning()) return; + + static uint32_t update_last = millis(), + eeprom_last = millis(); + + millis_t now = millis(); + + // Trying to get the amount of calculations down to the bare min + const static uint16_t i = this->updateInterval * 1000; + + if (now - update_last >= i) { + #if ENABLED(DEBUG_PRINTCOUNTER) + PrintCounter::debug(PSTR("tick")); + #endif + + this->data.printTime += this->deltaDuration(); + update_last = now; + } + + // Trying to get the amount of calculations down to the bare min + const static millis_t j = this->saveInterval * 1000; + if (now - eeprom_last >= j) { + eeprom_last = now; + this->saveStats(); + } +} + +// @Override +bool PrintCounter::start() { + #if ENABLED(DEBUG_PRINTCOUNTER) + PrintCounter::debug(PSTR("start")); + #endif + + bool paused = this->isPaused(); + + if (super::start()) { + if (!paused) { + this->data.totalPrints++; + this->lastDuration = 0; + } + return true; + } + else return false; +} + +// @Override +bool PrintCounter::stop() { + #if ENABLED(DEBUG_PRINTCOUNTER) + PrintCounter::debug(PSTR("stop")); + #endif + + if (super::stop()) { + this->data.finishedPrints++; + this->data.printTime += this->deltaDuration(); + + if (this->duration() > this->data.longestPrint) + this->data.longestPrint = this->duration(); + + this->saveStats(); + return true; + } + else return false; +} + +// @Override +void PrintCounter::reset() { + #if ENABLED(DEBUG_PRINTCOUNTER) + PrintCounter::debug(PSTR("stop")); + #endif + + super::reset(); + this->lastDuration = 0; +} + +#if ENABLED(DEBUG_PRINTCOUNTER) + + void PrintCounter::debug(const char func[]) { + if (DEBUGGING(INFO)) { + SERIAL_ECHOPGM("PrintCounter::"); + serialprintPGM(func); + SERIAL_ECHOLNPGM("()"); + } + } + +#endif diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/printcounter.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/printcounter.h new file mode 100644 index 00000000..0e9d06f4 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/printcounter.h @@ -0,0 +1,175 @@ +/* + * 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 . + * + */ + +#ifndef PRINTCOUNTER_H +#define PRINTCOUNTER_H + +#include "macros.h" +#include "language.h" +#include "stopwatch.h" +#include + + +// Print debug messages with M111 S2 +//#define DEBUG_PRINTCOUNTER + +struct printStatistics { // 13 bytes + //const uint8_t magic; // Magic header, it will always be 0x16 + uint16_t totalPrints; // Number of prints + uint16_t finishedPrints; // Number of complete prints + uint32_t printTime; // Accumulated printing time + uint32_t longestPrint; // Longest successfull print job + double filamentUsed; // Accumulated filament consumed in mm +}; + +class PrintCounter: public Stopwatch { + private: + typedef Stopwatch super; + + printStatistics data; + + /** + * @brief EEPROM address + * @details Defines the start offset address where the data is stored. + */ + const uint16_t address = 0x32; + + /** + * @brief Interval in seconds between counter updates + * @details This const value defines what will be the time between each + * accumulator update. This is different from the EEPROM save interval. + * + * @note The max value for this option is 60(s), otherwise integer + * overflow will happen. + */ + const uint16_t updateInterval = 10; + + /** + * @brief Interval in seconds between EEPROM saves + * @details This const value defines what will be the time between each + * EEPROM save cycle, the development team recommends to set this value + * no lower than 3600 secs (1 hour). + */ + const uint16_t saveInterval = 3600; + + /** + * @brief Timestamp of the last call to deltaDuration() + * @details Stores the timestamp of the last deltaDuration(), this is + * required due to the updateInterval cycle. + */ + millis_t lastDuration; + + /** + * @brief Stats were loaded from EERPROM + * @details If set to true it indicates if the statistical data was already + * loaded from the EEPROM. + */ + bool loaded = false; + + protected: + /** + * @brief dT since the last call + * @details Returns the elapsed time in seconds since the last call, this is + * used internally for print statistics accounting is not intended to be a + * user callable function. + */ + millis_t deltaDuration(); + + public: + /** + * @brief Class constructor + */ + PrintCounter(); + + /** + * @brief Checks if Print Statistics has been loaded + * @details Returns true if the statistical data has been loaded. + * @return bool + */ + bool isLoaded(); + + /** + * @brief Increments the total filament used + * @details The total filament used counter will be incremented by "amount". + * + * @param amount The amount of filament used in mm + */ + void incFilamentUsed(double const &amount); + + /** + * @brief Resets the Print Statistics + * @details Resets the statistics to zero and saves them to EEPROM creating + * also the magic header. + */ + void initStats(); + + /** + * @brief Loads the Print Statistics + * @details Loads the statistics from EEPROM + */ + void loadStats(); + + /** + * @brief Saves the Print Statistics + * @details Saves the statistics to EEPROM + */ + void saveStats(); + + /** + * @brief Serial output the Print Statistics + * @details This function may change in the future, for now it directly + * prints the statistical data to serial. + */ + void showStats(); + + /** + * @brief Return the currently loaded statistics + * @details Return the raw data, in the same structure used internally + */ + printStatistics getStats() { return this->data; } + + /** + * @brief Loop function + * @details This function should be called at loop, it will take care of + * periodically save the statistical data to EEPROM and do time keeping. + */ + void tick(); + + /** + * The following functions are being overridden + */ + bool start(); + bool stop(); + void reset(); + + #if ENABLED(DEBUG_PRINTCOUNTER) + + /** + * @brief Prints a debug message + * @details Prints a simple debug message "PrintCounter::function" + */ + static void debug(const char func[]); + + #endif +}; + +#endif // PRINTCOUNTER_H diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/qr_solve.cpp b/trunk/Arduino/Marlin_K8600_1.1.0RC7/qr_solve.cpp new file mode 100644 index 00000000..ddafb005 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/qr_solve.cpp @@ -0,0 +1,1591 @@ +/** + * 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 . + * + */ + +#include "qr_solve.h" + +#if ENABLED(AUTO_BED_LEVELING_GRID) + +#include +#include + +//# include "r8lib.h" + +int i4_min(int i1, int i2) + +/******************************************************************************/ +/** + Purpose: + + I4_MIN returns the smaller of two I4's. + + Licensing: + + This code is distributed under the GNU LGPL license. + + Modified: + + 29 August 2006 + + Author: + + John Burkardt + + Parameters: + + Input, int I1, I2, two integers to be compared. + + Output, int I4_MIN, the smaller of I1 and I2. +*/ +{ + return (i1 < i2) ? i1 : i2; +} + +double r8_epsilon(void) + +/******************************************************************************/ +/** + Purpose: + + R8_EPSILON returns the R8 round off unit. + + Discussion: + + R8_EPSILON is a number R which is a power of 2 with the property that, + to the precision of the computer's arithmetic, + 1 < 1 + R + but + 1 = ( 1 + R / 2 ) + + Licensing: + + This code is distributed under the GNU LGPL license. + + Modified: + + 01 September 2012 + + Author: + + John Burkardt + + Parameters: + + Output, double R8_EPSILON, the R8 round-off unit. +*/ +{ + const double value = 2.220446049250313E-016; + return value; +} + +double r8_max(double x, double y) + +/******************************************************************************/ +/** + Purpose: + + R8_MAX returns the maximum of two R8's. + + Licensing: + + This code is distributed under the GNU LGPL license. + + Modified: + + 07 May 2006 + + Author: + + John Burkardt + + Parameters: + + Input, double X, Y, the quantities to compare. + + Output, double R8_MAX, the maximum of X and Y. +*/ +{ + return (y < x) ? x : y; +} + +double r8_abs(double x) + +/******************************************************************************/ +/** + Purpose: + + R8_ABS returns the absolute value of an R8. + + Licensing: + + This code is distributed under the GNU LGPL license. + + Modified: + + 07 May 2006 + + Author: + + John Burkardt + + Parameters: + + Input, double X, the quantity whose absolute value is desired. + + Output, double R8_ABS, the absolute value of X. +*/ +{ + return (x < 0.0) ? -x : x; +} + +double r8_sign(double x) + +/******************************************************************************/ +/** + Purpose: + + R8_SIGN returns the sign of an R8. + + Licensing: + + This code is distributed under the GNU LGPL license. + + Modified: + + 08 May 2006 + + Author: + + John Burkardt + + Parameters: + + Input, double X, the number whose sign is desired. + + Output, double R8_SIGN, the sign of X. +*/ +{ + return (x < 0.0) ? -1.0 : 1.0; +} + +double r8mat_amax(int m, int n, double a[]) + +/******************************************************************************/ +/** + Purpose: + + R8MAT_AMAX returns the maximum absolute value entry of an R8MAT. + + Discussion: + + An R8MAT is a doubly dimensioned array of R8 values, stored as a vector + in column-major order. + + Licensing: + + This code is distributed under the GNU LGPL license. + + Modified: + + 07 September 2012 + + Author: + + John Burkardt + + Parameters: + + Input, int M, the number of rows in A. + + Input, int N, the number of columns in A. + + Input, double A[M*N], the M by N matrix. + + Output, double R8MAT_AMAX, the maximum absolute value entry of A. +*/ +{ + double value = r8_abs(a[0 + 0 * m]); + for (int j = 0; j < n; j++) { + for (int i = 0; i < m; i++) { + NOLESS(value, r8_abs(a[i + j * m])); + } + } + return value; +} + +void r8mat_copy(double a2[], int m, int n, double a1[]) + +/******************************************************************************/ +/** + Purpose: + + R8MAT_COPY_NEW copies one R8MAT to a "new" R8MAT. + + Discussion: + + An R8MAT is a doubly dimensioned array of R8 values, stored as a vector + in column-major order. + + Licensing: + + This code is distributed under the GNU LGPL license. + + Modified: + + 26 July 2008 + + Author: + + John Burkardt + + Parameters: + + Input, int M, N, the number of rows and columns. + + Input, double A1[M*N], the matrix to be copied. + + Output, double R8MAT_COPY_NEW[M*N], the copy of A1. +*/ +{ + for (int j = 0; j < n; j++) { + for (int i = 0; i < m; i++) + a2[i + j * m] = a1[i + j * m]; + } +} + +/******************************************************************************/ + +void daxpy(int n, double da, double dx[], int incx, double dy[], int incy) + +/******************************************************************************/ +/** + Purpose: + + DAXPY computes constant times a vector plus a vector. + + Discussion: + + This routine uses unrolled loops for increments equal to one. + + Licensing: + + This code is distributed under the GNU LGPL license. + + Modified: + + 30 March 2007 + + Author: + + C version by John Burkardt + + Reference: + + Jack Dongarra, Cleve Moler, Jim Bunch, Pete Stewart, + LINPACK User's Guide, + SIAM, 1979. + + Charles Lawson, Richard Hanson, David Kincaid, Fred Krogh, + Basic Linear Algebra Subprograms for Fortran Usage, + Algorithm 539, + ACM Transactions on Mathematical Software, + Volume 5, Number 3, September 1979, pages 308-323. + + Parameters: + + Input, int N, the number of elements in DX and DY. + + Input, double DA, the multiplier of DX. + + Input, double DX[*], the first vector. + + Input, int INCX, the increment between successive entries of DX. + + Input/output, double DY[*], the second vector. + On output, DY[*] has been replaced by DY[*] + DA * DX[*]. + + Input, int INCY, the increment between successive entries of DY. +*/ +{ + if (n <= 0 || da == 0.0) return; + + int i, ix, iy, m; + /** + Code for unequal increments or equal increments + not equal to 1. + */ + if (incx != 1 || incy != 1) { + if (0 <= incx) + ix = 0; + else + ix = (- n + 1) * incx; + if (0 <= incy) + iy = 0; + else + iy = (- n + 1) * incy; + for (i = 0; i < n; i++) { + dy[iy] = dy[iy] + da * dx[ix]; + ix = ix + incx; + iy = iy + incy; + } + } + /** + Code for both increments equal to 1. + */ + else { + m = n % 4; + for (i = 0; i < m; i++) + dy[i] = dy[i] + da * dx[i]; + for (i = m; i < n; i = i + 4) { + dy[i ] = dy[i ] + da * dx[i ]; + dy[i + 1] = dy[i + 1] + da * dx[i + 1]; + dy[i + 2] = dy[i + 2] + da * dx[i + 2]; + dy[i + 3] = dy[i + 3] + da * dx[i + 3]; + } + } +} +/******************************************************************************/ + +double ddot(int n, double dx[], int incx, double dy[], int incy) + +/******************************************************************************/ +/** + Purpose: + + DDOT forms the dot product of two vectors. + + Discussion: + + This routine uses unrolled loops for increments equal to one. + + Licensing: + + This code is distributed under the GNU LGPL license. + + Modified: + + 30 March 2007 + + Author: + + C version by John Burkardt + + Reference: + + Jack Dongarra, Cleve Moler, Jim Bunch, Pete Stewart, + LINPACK User's Guide, + SIAM, 1979. + + Charles Lawson, Richard Hanson, David Kincaid, Fred Krogh, + Basic Linear Algebra Subprograms for Fortran Usage, + Algorithm 539, + ACM Transactions on Mathematical Software, + Volume 5, Number 3, September 1979, pages 308-323. + + Parameters: + + Input, int N, the number of entries in the vectors. + + Input, double DX[*], the first vector. + + Input, int INCX, the increment between successive entries in DX. + + Input, double DY[*], the second vector. + + Input, int INCY, the increment between successive entries in DY. + + Output, double DDOT, the sum of the product of the corresponding + entries of DX and DY. +*/ +{ + + if (n <= 0) return 0.0; + + int i, m; + double dtemp = 0.0; + + /** + Code for unequal increments or equal increments + not equal to 1. + */ + if (incx != 1 || incy != 1) { + int ix = (incx >= 0) ? 0 : (-n + 1) * incx, + iy = (incy >= 0) ? 0 : (-n + 1) * incy; + for (i = 0; i < n; i++) { + dtemp += dx[ix] * dy[iy]; + ix = ix + incx; + iy = iy + incy; + } + } + /** + Code for both increments equal to 1. + */ + else { + m = n % 5; + for (i = 0; i < m; i++) + dtemp += dx[i] * dy[i]; + for (i = m; i < n; i = i + 5) { + dtemp += dx[i] * dy[i] + + dx[i + 1] * dy[i + 1] + + dx[i + 2] * dy[i + 2] + + dx[i + 3] * dy[i + 3] + + dx[i + 4] * dy[i + 4]; + } + } + return dtemp; +} +/******************************************************************************/ + +double dnrm2(int n, double x[], int incx) + +/******************************************************************************/ +/** + Purpose: + + DNRM2 returns the euclidean norm of a vector. + + Discussion: + + DNRM2 ( X ) = sqrt ( X' * X ) + + Licensing: + + This code is distributed under the GNU LGPL license. + + Modified: + + 30 March 2007 + + Author: + + C version by John Burkardt + + Reference: + + Jack Dongarra, Cleve Moler, Jim Bunch, Pete Stewart, + LINPACK User's Guide, + SIAM, 1979. + + Charles Lawson, Richard Hanson, David Kincaid, Fred Krogh, + Basic Linear Algebra Subprograms for Fortran Usage, + Algorithm 539, + ACM Transactions on Mathematical Software, + Volume 5, Number 3, September 1979, pages 308-323. + + Parameters: + + Input, int N, the number of entries in the vector. + + Input, double X[*], the vector whose norm is to be computed. + + Input, int INCX, the increment between successive entries of X. + + Output, double DNRM2, the Euclidean norm of X. +*/ +{ + double norm; + if (n < 1 || incx < 1) + norm = 0.0; + else if (n == 1) + norm = r8_abs(x[0]); + else { + double scale = 0.0, ssq = 1.0; + int ix = 0; + for (int i = 0; i < n; i++) { + if (x[ix] != 0.0) { + double absxi = r8_abs(x[ix]); + if (scale < absxi) { + ssq = 1.0 + ssq * (scale / absxi) * (scale / absxi); + scale = absxi; + } + else + ssq = ssq + (absxi / scale) * (absxi / scale); + } + ix += incx; + } + norm = scale * sqrt(ssq); + } + return norm; +} +/******************************************************************************/ + +void dqrank(double a[], int lda, int m, int n, double tol, int* kr, + int jpvt[], double qraux[]) + +/******************************************************************************/ +/** + Purpose: + + DQRANK computes the QR factorization of a rectangular matrix. + + Discussion: + + This routine is used in conjunction with DQRLSS to solve + overdetermined, underdetermined and singular linear systems + in a least squares sense. + + DQRANK uses the LINPACK subroutine DQRDC to compute the QR + factorization, with column pivoting, of an M by N matrix A. + The numerical rank is determined using the tolerance TOL. + + Note that on output, ABS ( A(1,1) ) / ABS ( A(KR,KR) ) is an estimate + of the condition number of the matrix of independent columns, + and of R. This estimate will be <= 1/TOL. + + Licensing: + + This code is distributed under the GNU LGPL license. + + Modified: + + 21 April 2012 + + Author: + + C version by John Burkardt. + + Reference: + + Jack Dongarra, Cleve Moler, Jim Bunch, Pete Stewart, + LINPACK User's Guide, + SIAM, 1979, + ISBN13: 978-0-898711-72-1, + LC: QA214.L56. + + Parameters: + + Input/output, double A[LDA*N]. On input, the matrix whose + decomposition is to be computed. On output, the information from DQRDC. + The triangular matrix R of the QR factorization is contained in the + upper triangle and information needed to recover the orthogonal + matrix Q is stored below the diagonal in A and in the vector QRAUX. + + Input, int LDA, the leading dimension of A, which must + be at least M. + + Input, int M, the number of rows of A. + + Input, int N, the number of columns of A. + + Input, double TOL, a relative tolerance used to determine the + numerical rank. The problem should be scaled so that all the elements + of A have roughly the same absolute accuracy, EPS. Then a reasonable + value for TOL is roughly EPS divided by the magnitude of the largest + element. + + Output, int *KR, the numerical rank. + + Output, int JPVT[N], the pivot information from DQRDC. + Columns JPVT(1), ..., JPVT(KR) of the original matrix are linearly + independent to within the tolerance TOL and the remaining columns + are linearly dependent. + + Output, double QRAUX[N], will contain extra information defining + the QR factorization. +*/ +{ + double work[n]; + + for (int i = 0; i < n; i++) + jpvt[i] = 0; + + int job = 1; + + dqrdc(a, lda, m, n, qraux, jpvt, work, job); + + *kr = 0; + int k = i4_min(m, n); + for (int j = 0; j < k; j++) { + if (r8_abs(a[j + j * lda]) <= tol * r8_abs(a[0 + 0 * lda])) + return; + *kr = j + 1; + } +} +/******************************************************************************/ + +void dqrdc(double a[], int lda, int n, int p, double qraux[], int jpvt[], + double work[], int job) + +/******************************************************************************/ +/** + Purpose: + + DQRDC computes the QR factorization of a real rectangular matrix. + + Discussion: + + DQRDC uses Householder transformations. + + Column pivoting based on the 2-norms of the reduced columns may be + performed at the user's option. + + Licensing: + + This code is distributed under the GNU LGPL license. + + Modified: + + 07 June 2005 + + Author: + + C version by John Burkardt. + + Reference: + + Jack Dongarra, Cleve Moler, Jim Bunch and Pete Stewart, + LINPACK User's Guide, + SIAM, (Society for Industrial and Applied Mathematics), + 3600 University City Science Center, + Philadelphia, PA, 19104-2688. + ISBN 0-89871-172-X + + Parameters: + + Input/output, double A(LDA,P). On input, the N by P matrix + whose decomposition is to be computed. On output, A contains in + its upper triangle the upper triangular matrix R of the QR + factorization. Below its diagonal A contains information from + which the orthogonal part of the decomposition can be recovered. + Note that if pivoting has been requested, the decomposition is not that + of the original matrix A but that of A with its columns permuted + as described by JPVT. + + Input, int LDA, the leading dimension of the array A. LDA must + be at least N. + + Input, int N, the number of rows of the matrix A. + + Input, int P, the number of columns of the matrix A. + + Output, double QRAUX[P], contains further information required + to recover the orthogonal part of the decomposition. + + Input/output, integer JPVT[P]. On input, JPVT contains integers that + control the selection of the pivot columns. The K-th column A(*,K) of A + is placed in one of three classes according to the value of JPVT(K). + > 0, then A(K) is an initial column. + = 0, then A(K) is a free column. + < 0, then A(K) is a final column. + Before the decomposition is computed, initial columns are moved to + the beginning of the array A and final columns to the end. Both + initial and final columns are frozen in place during the computation + and only free columns are moved. At the K-th stage of the + reduction, if A(*,K) is occupied by a free column it is interchanged + with the free column of largest reduced norm. JPVT is not referenced + if JOB == 0. On output, JPVT(K) contains the index of the column of the + original matrix that has been interchanged into the K-th column, if + pivoting was requested. + + Workspace, double WORK[P]. WORK is not referenced if JOB == 0. + + Input, int JOB, initiates column pivoting. + 0, no pivoting is done. + nonzero, pivoting is done. +*/ +{ + int jp; + int j; + int lup; + int maxj; + double maxnrm, nrmxl, t, tt; + + int pl = 1, pu = 0; + /** + If pivoting is requested, rearrange the columns. + */ + if (job != 0) { + for (j = 1; j <= p; j++) { + int swapj = (0 < jpvt[j - 1]); + jpvt[j - 1] = (jpvt[j - 1] < 0) ? -j : j; + if (swapj) { + if (j != pl) + dswap(n, a + 0 + (pl - 1)*lda, 1, a + 0 + (j - 1), 1); + jpvt[j - 1] = jpvt[pl - 1]; + jpvt[pl - 1] = j; + pl++; + } + } + pu = p; + for (j = p; 1 <= j; j--) { + if (jpvt[j - 1] < 0) { + jpvt[j - 1] = -jpvt[j - 1]; + if (j != pu) { + dswap(n, a + 0 + (pu - 1)*lda, 1, a + 0 + (j - 1)*lda, 1); + jp = jpvt[pu - 1]; + jpvt[pu - 1] = jpvt[j - 1]; + jpvt[j - 1] = jp; + } + pu = pu - 1; + } + } + } + /** + Compute the norms of the free columns. + */ + for (j = pl; j <= pu; j++) + qraux[j - 1] = dnrm2(n, a + 0 + (j - 1) * lda, 1); + for (j = pl; j <= pu; j++) + work[j - 1] = qraux[j - 1]; + /** + Perform the Householder reduction of A. + */ + lup = i4_min(n, p); + for (int l = 1; l <= lup; l++) { + /** + Bring the column of largest norm into the pivot position. + */ + if (pl <= l && l < pu) { + maxnrm = 0.0; + maxj = l; + for (j = l; j <= pu; j++) { + if (maxnrm < qraux[j - 1]) { + maxnrm = qraux[j - 1]; + maxj = j; + } + } + if (maxj != l) { + dswap(n, a + 0 + (l - 1)*lda, 1, a + 0 + (maxj - 1)*lda, 1); + qraux[maxj - 1] = qraux[l - 1]; + work[maxj - 1] = work[l - 1]; + jp = jpvt[maxj - 1]; + jpvt[maxj - 1] = jpvt[l - 1]; + jpvt[l - 1] = jp; + } + } + /** + Compute the Householder transformation for column L. + */ + qraux[l - 1] = 0.0; + if (l != n) { + nrmxl = dnrm2(n - l + 1, a + l - 1 + (l - 1) * lda, 1); + if (nrmxl != 0.0) { + if (a[l - 1 + (l - 1)*lda] != 0.0) + nrmxl = nrmxl * r8_sign(a[l - 1 + (l - 1) * lda]); + dscal(n - l + 1, 1.0 / nrmxl, a + l - 1 + (l - 1)*lda, 1); + a[l - 1 + (l - 1)*lda] = 1.0 + a[l - 1 + (l - 1) * lda]; + /** + Apply the transformation to the remaining columns, updating the norms. + */ + for (j = l + 1; j <= p; j++) { + t = -ddot(n - l + 1, a + l - 1 + (l - 1) * lda, 1, a + l - 1 + (j - 1) * lda, 1) + / a[l - 1 + (l - 1) * lda]; + daxpy(n - l + 1, t, a + l - 1 + (l - 1)*lda, 1, a + l - 1 + (j - 1)*lda, 1); + if (pl <= j && j <= pu) { + if (qraux[j - 1] != 0.0) { + tt = 1.0 - pow(r8_abs(a[l - 1 + (j - 1) * lda]) / qraux[j - 1], 2); + tt = r8_max(tt, 0.0); + t = tt; + tt = 1.0 + 0.05 * tt * pow(qraux[j - 1] / work[j - 1], 2); + if (tt != 1.0) + qraux[j - 1] = qraux[j - 1] * sqrt(t); + else { + qraux[j - 1] = dnrm2(n - l, a + l + (j - 1) * lda, 1); + work[j - 1] = qraux[j - 1]; + } + } + } + } + /** + Save the transformation. + */ + qraux[l - 1] = a[l - 1 + (l - 1) * lda]; + a[l - 1 + (l - 1)*lda] = -nrmxl; + } + } + } +} +/******************************************************************************/ + +int dqrls(double a[], int lda, int m, int n, double tol, int* kr, double b[], + double x[], double rsd[], int jpvt[], double qraux[], int itask) + +/******************************************************************************/ +/** + Purpose: + + DQRLS factors and solves a linear system in the least squares sense. + + Discussion: + + The linear system may be overdetermined, underdetermined or singular. + The solution is obtained using a QR factorization of the + coefficient matrix. + + DQRLS can be efficiently used to solve several least squares + problems with the same matrix A. The first system is solved + with ITASK = 1. The subsequent systems are solved with + ITASK = 2, to avoid the recomputation of the matrix factors. + The parameters KR, JPVT, and QRAUX must not be modified + between calls to DQRLS. + + DQRLS is used to solve in a least squares sense + overdetermined, underdetermined and singular linear systems. + The system is A*X approximates B where A is M by N. + B is a given M-vector, and X is the N-vector to be computed. + A solution X is found which minimimzes the sum of squares (2-norm) + of the residual, A*X - B. + + The numerical rank of A is determined using the tolerance TOL. + + DQRLS uses the LINPACK subroutine DQRDC to compute the QR + factorization, with column pivoting, of an M by N matrix A. + + Licensing: + + This code is distributed under the GNU LGPL license. + + Modified: + + 10 September 2012 + + Author: + + C version by John Burkardt. + + Reference: + + David Kahaner, Cleve Moler, Steven Nash, + Numerical Methods and Software, + Prentice Hall, 1989, + ISBN: 0-13-627258-4, + LC: TA345.K34. + + Parameters: + + Input/output, double A[LDA*N], an M by N matrix. + On input, the matrix whose decomposition is to be computed. + In a least squares data fitting problem, A(I,J) is the + value of the J-th basis (model) function at the I-th data point. + On output, A contains the output from DQRDC. The triangular matrix R + of the QR factorization is contained in the upper triangle and + information needed to recover the orthogonal matrix Q is stored + below the diagonal in A and in the vector QRAUX. + + Input, int LDA, the leading dimension of A. + + Input, int M, the number of rows of A. + + Input, int N, the number of columns of A. + + Input, double TOL, a relative tolerance used to determine the + numerical rank. The problem should be scaled so that all the elements + of A have roughly the same absolute accuracy EPS. Then a reasonable + value for TOL is roughly EPS divided by the magnitude of the largest + element. + + Output, int *KR, the numerical rank. + + Input, double B[M], the right hand side of the linear system. + + Output, double X[N], a least squares solution to the linear + system. + + Output, double RSD[M], the residual, B - A*X. RSD may + overwrite B. + + Workspace, int JPVT[N], required if ITASK = 1. + Columns JPVT(1), ..., JPVT(KR) of the original matrix are linearly + independent to within the tolerance TOL and the remaining columns + are linearly dependent. ABS ( A(1,1) ) / ABS ( A(KR,KR) ) is an estimate + of the condition number of the matrix of independent columns, + and of R. This estimate will be <= 1/TOL. + + Workspace, double QRAUX[N], required if ITASK = 1. + + Input, int ITASK. + 1, DQRLS factors the matrix A and solves the least squares problem. + 2, DQRLS assumes that the matrix A was factored with an earlier + call to DQRLS, and only solves the least squares problem. + + Output, int DQRLS, error code. + 0: no error + -1: LDA < M (fatal error) + -2: N < 1 (fatal error) + -3: ITASK < 1 (fatal error) +*/ +{ + int ind; + if (lda < m) { + /*fprintf ( stderr, "\n" ); + fprintf ( stderr, "DQRLS - Fatal error!\n" ); + fprintf ( stderr, " LDA < M.\n" );*/ + ind = -1; + return ind; + } + + if (n <= 0) { + /*fprintf ( stderr, "\n" ); + fprintf ( stderr, "DQRLS - Fatal error!\n" ); + fprintf ( stderr, " N <= 0.\n" );*/ + ind = -2; + return ind; + } + + if (itask < 1) { + /*fprintf ( stderr, "\n" ); + fprintf ( stderr, "DQRLS - Fatal error!\n" ); + fprintf ( stderr, " ITASK < 1.\n" );*/ + ind = -3; + return ind; + } + + ind = 0; + /** + Factor the matrix. + */ + if (itask == 1) + dqrank(a, lda, m, n, tol, kr, jpvt, qraux); + /** + Solve the least-squares problem. + */ + dqrlss(a, lda, m, n, *kr, b, x, rsd, jpvt, qraux); + return ind; +} +/******************************************************************************/ + +void dqrlss(double a[], int lda, int m, int n, int kr, double b[], double x[], + double rsd[], int jpvt[], double qraux[]) + +/******************************************************************************/ +/** + Purpose: + + DQRLSS solves a linear system in a least squares sense. + + Discussion: + + DQRLSS must be preceded by a call to DQRANK. + + The system is to be solved is + A * X = B + where + A is an M by N matrix with rank KR, as determined by DQRANK, + B is a given M-vector, + X is the N-vector to be computed. + + A solution X, with at most KR nonzero components, is found which + minimizes the 2-norm of the residual (A*X-B). + + Once the matrix A has been formed, DQRANK should be + called once to decompose it. Then, for each right hand + side B, DQRLSS should be called once to obtain the + solution and residual. + + Licensing: + + This code is distributed under the GNU LGPL license. + + Modified: + + 10 September 2012 + + Author: + + C version by John Burkardt + + Parameters: + + Input, double A[LDA*N], the QR factorization information + from DQRANK. The triangular matrix R of the QR factorization is + contained in the upper triangle and information needed to recover + the orthogonal matrix Q is stored below the diagonal in A and in + the vector QRAUX. + + Input, int LDA, the leading dimension of A, which must + be at least M. + + Input, int M, the number of rows of A. + + Input, int N, the number of columns of A. + + Input, int KR, the rank of the matrix, as estimated by DQRANK. + + Input, double B[M], the right hand side of the linear system. + + Output, double X[N], a least squares solution to the + linear system. + + Output, double RSD[M], the residual, B - A*X. RSD may + overwrite B. + + Input, int JPVT[N], the pivot information from DQRANK. + Columns JPVT[0], ..., JPVT[KR-1] of the original matrix are linearly + independent to within the tolerance TOL and the remaining columns + are linearly dependent. + + Input, double QRAUX[N], auxiliary information from DQRANK + defining the QR factorization. +*/ +{ + int i; + int info; + int j; + int job; + int k; + double t; + + if (kr != 0) { + job = 110; + info = dqrsl(a, lda, m, kr, qraux, b, rsd, rsd, x, rsd, rsd, job); UNUSED(info); + } + + for (i = 0; i < n; i++) + jpvt[i] = - jpvt[i]; + + for (i = kr; i < n; i++) + x[i] = 0.0; + + for (j = 1; j <= n; j++) { + if (jpvt[j - 1] <= 0) { + k = - jpvt[j - 1]; + jpvt[j - 1] = k; + + while (k != j) { + t = x[j - 1]; + x[j - 1] = x[k - 1]; + x[k - 1] = t; + jpvt[k - 1] = -jpvt[k - 1]; + k = jpvt[k - 1]; + } + } + } +} +/******************************************************************************/ + +int dqrsl(double a[], int lda, int n, int k, double qraux[], double y[], + double qy[], double qty[], double b[], double rsd[], double ab[], int job) + +/******************************************************************************/ +/** + Purpose: + + DQRSL computes transformations, projections, and least squares solutions. + + Discussion: + + DQRSL requires the output of DQRDC. + + For K <= min(N,P), let AK be the matrix + + AK = ( A(JPVT[0]), A(JPVT(2)), ..., A(JPVT(K)) ) + + formed from columns JPVT[0], ..., JPVT(K) of the original + N by P matrix A that was input to DQRDC. If no pivoting was + done, AK consists of the first K columns of A in their + original order. DQRDC produces a factored orthogonal matrix Q + and an upper triangular matrix R such that + + AK = Q * (R) + (0) + + This information is contained in coded form in the arrays + A and QRAUX. + + The parameters QY, QTY, B, RSD, and AB are not referenced + if their computation is not requested and in this case + can be replaced by dummy variables in the calling program. + To save storage, the user may in some cases use the same + array for different parameters in the calling sequence. A + frequently occurring example is when one wishes to compute + any of B, RSD, or AB and does not need Y or QTY. In this + case one may identify Y, QTY, and one of B, RSD, or AB, while + providing separate arrays for anything else that is to be + computed. + + Thus the calling sequence + + dqrsl ( a, lda, n, k, qraux, y, dum, y, b, y, dum, 110, info ) + + will result in the computation of B and RSD, with RSD + overwriting Y. More generally, each item in the following + list contains groups of permissible identifications for + a single calling sequence. + + 1. (Y,QTY,B) (RSD) (AB) (QY) + + 2. (Y,QTY,RSD) (B) (AB) (QY) + + 3. (Y,QTY,AB) (B) (RSD) (QY) + + 4. (Y,QY) (QTY,B) (RSD) (AB) + + 5. (Y,QY) (QTY,RSD) (B) (AB) + + 6. (Y,QY) (QTY,AB) (B) (RSD) + + In any group the value returned in the array allocated to + the group corresponds to the last member of the group. + + Licensing: + + This code is distributed under the GNU LGPL license. + + Modified: + + 07 June 2005 + + Author: + + C version by John Burkardt. + + Reference: + + Jack Dongarra, Cleve Moler, Jim Bunch and Pete Stewart, + LINPACK User's Guide, + SIAM, (Society for Industrial and Applied Mathematics), + 3600 University City Science Center, + Philadelphia, PA, 19104-2688. + ISBN 0-89871-172-X + + Parameters: + + Input, double A[LDA*P], contains the output of DQRDC. + + Input, int LDA, the leading dimension of the array A. + + Input, int N, the number of rows of the matrix AK. It must + have the same value as N in DQRDC. + + Input, int K, the number of columns of the matrix AK. K + must not be greater than min(N,P), where P is the same as in the + calling sequence to DQRDC. + + Input, double QRAUX[P], the auxiliary output from DQRDC. + + Input, double Y[N], a vector to be manipulated by DQRSL. + + Output, double QY[N], contains Q * Y, if requested. + + Output, double QTY[N], contains Q' * Y, if requested. + + Output, double B[K], the solution of the least squares problem + minimize norm2 ( Y - AK * B), + if its computation has been requested. Note that if pivoting was + requested in DQRDC, the J-th component of B will be associated with + column JPVT(J) of the original matrix A that was input into DQRDC. + + Output, double RSD[N], the least squares residual Y - AK * B, + if its computation has been requested. RSD is also the orthogonal + projection of Y onto the orthogonal complement of the column space + of AK. + + Output, double AB[N], the least squares approximation Ak * B, + if its computation has been requested. AB is also the orthogonal + projection of Y onto the column space of A. + + Input, integer JOB, specifies what is to be computed. JOB has + the decimal expansion ABCDE, with the following meaning: + + if A != 0, compute QY. + if B != 0, compute QTY. + if C != 0, compute QTY and B. + if D != 0, compute QTY and RSD. + if E != 0, compute QTY and AB. + + Note that a request to compute B, RSD, or AB automatically triggers + the computation of QTY, for which an array must be provided in the + calling sequence. + + Output, int DQRSL, is zero unless the computation of B has + been requested and R is exactly singular. In this case, INFO is the + index of the first zero diagonal element of R, and B is left unaltered. +*/ +{ + int cab; + int cb; + int cqty; + int cqy; + int cr; + int i; + int info; + int j; + int jj; + int ju; + double t; + double temp; + /** + Set INFO flag. + */ + info = 0; + + /** + Determine what is to be computed. + */ + cqy = ( job / 10000 != 0); + cqty = ((job % 10000) != 0); + cb = ((job % 1000) / 100 != 0); + cr = ((job % 100) / 10 != 0); + cab = ((job % 10) != 0); + ju = i4_min(k, n - 1); + + /** + Special action when N = 1. + */ + if (ju == 0) { + if (cqy) + qy[0] = y[0]; + if (cqty) + qty[0] = y[0]; + if (cab) + ab[0] = y[0]; + if (cb) { + if (a[0 + 0 * lda] == 0.0) + info = 1; + else + b[0] = y[0] / a[0 + 0 * lda]; + } + if (cr) + rsd[0] = 0.0; + return info; + } + /** + Set up to compute QY or QTY. + */ + if (cqy) { + for (i = 1; i <= n; i++) + qy[i - 1] = y[i - 1]; + } + if (cqty) { + for (i = 1; i <= n; i++) + qty[i - 1] = y[i - 1]; + } + /** + Compute QY. + */ + if (cqy) { + for (jj = 1; jj <= ju; jj++) { + j = ju - jj + 1; + if (qraux[j - 1] != 0.0) { + temp = a[j - 1 + (j - 1) * lda]; + a[j - 1 + (j - 1)*lda] = qraux[j - 1]; + t = -ddot(n - j + 1, a + j - 1 + (j - 1) * lda, 1, qy + j - 1, 1) / a[j - 1 + (j - 1) * lda]; + daxpy(n - j + 1, t, a + j - 1 + (j - 1)*lda, 1, qy + j - 1, 1); + a[j - 1 + (j - 1)*lda] = temp; + } + } + } + /** + Compute Q'*Y. + */ + if (cqty) { + for (j = 1; j <= ju; j++) { + if (qraux[j - 1] != 0.0) { + temp = a[j - 1 + (j - 1) * lda]; + a[j - 1 + (j - 1)*lda] = qraux[j - 1]; + t = -ddot(n - j + 1, a + j - 1 + (j - 1) * lda, 1, qty + j - 1, 1) / a[j - 1 + (j - 1) * lda]; + daxpy(n - j + 1, t, a + j - 1 + (j - 1)*lda, 1, qty + j - 1, 1); + a[j - 1 + (j - 1)*lda] = temp; + } + } + } + /** + Set up to compute B, RSD, or AB. + */ + if (cb) { + for (i = 1; i <= k; i++) + b[i - 1] = qty[i - 1]; + } + if (cab) { + for (i = 1; i <= k; i++) + ab[i - 1] = qty[i - 1]; + } + if (cr && k < n) { + for (i = k + 1; i <= n; i++) + rsd[i - 1] = qty[i - 1]; + } + if (cab && k + 1 <= n) { + for (i = k + 1; i <= n; i++) + ab[i - 1] = 0.0; + } + if (cr) { + for (i = 1; i <= k; i++) + rsd[i - 1] = 0.0; + } + /** + Compute B. + */ + if (cb) { + for (jj = 1; jj <= k; jj++) { + j = k - jj + 1; + if (a[j - 1 + (j - 1)*lda] == 0.0) { + info = j; + break; + } + b[j - 1] = b[j - 1] / a[j - 1 + (j - 1) * lda]; + if (j != 1) { + t = -b[j - 1]; + daxpy(j - 1, t, a + 0 + (j - 1)*lda, 1, b, 1); + } + } + } + /** + Compute RSD or AB as required. + */ + if (cr || cab) { + for (jj = 1; jj <= ju; jj++) { + j = ju - jj + 1; + if (qraux[j - 1] != 0.0) { + temp = a[j - 1 + (j - 1) * lda]; + a[j - 1 + (j - 1)*lda] = qraux[j - 1]; + if (cr) { + t = -ddot(n - j + 1, a + j - 1 + (j - 1) * lda, 1, rsd + j - 1, 1) + / a[j - 1 + (j - 1) * lda]; + daxpy(n - j + 1, t, a + j - 1 + (j - 1)*lda, 1, rsd + j - 1, 1); + } + if (cab) { + t = -ddot(n - j + 1, a + j - 1 + (j - 1) * lda, 1, ab + j - 1, 1) + / a[j - 1 + (j - 1) * lda]; + daxpy(n - j + 1, t, a + j - 1 + (j - 1)*lda, 1, ab + j - 1, 1); + } + a[j - 1 + (j - 1)*lda] = temp; + } + } + } + return info; +} +/******************************************************************************/ + +/******************************************************************************/ + +void dscal(int n, double sa, double x[], int incx) + +/******************************************************************************/ +/** + Purpose: + + DSCAL scales a vector by a constant. + + Licensing: + + This code is distributed under the GNU LGPL license. + + Modified: + + 30 March 2007 + + Author: + + C version by John Burkardt + + Reference: + + Jack Dongarra, Cleve Moler, Jim Bunch, Pete Stewart, + LINPACK User's Guide, + SIAM, 1979. + + Charles Lawson, Richard Hanson, David Kincaid, Fred Krogh, + Basic Linear Algebra Subprograms for Fortran Usage, + Algorithm 539, + ACM Transactions on Mathematical Software, + Volume 5, Number 3, September 1979, pages 308-323. + + Parameters: + + Input, int N, the number of entries in the vector. + + Input, double SA, the multiplier. + + Input/output, double X[*], the vector to be scaled. + + Input, int INCX, the increment between successive entries of X. +*/ +{ + int i; + int ix; + int m; + + if (n <= 0) return; + + if (incx == 1) { + m = n % 5; + for (i = 0; i < m; i++) + x[i] = sa * x[i]; + for (i = m; i < n; i = i + 5) { + x[i] = sa * x[i]; + x[i + 1] = sa * x[i + 1]; + x[i + 2] = sa * x[i + 2]; + x[i + 3] = sa * x[i + 3]; + x[i + 4] = sa * x[i + 4]; + } + } + else { + if (0 <= incx) + ix = 0; + else + ix = (- n + 1) * incx; + for (i = 0; i < n; i++) { + x[ix] = sa * x[ix]; + ix = ix + incx; + } + } +} +/******************************************************************************/ + + +void dswap(int n, double x[], int incx, double y[], int incy) + +/******************************************************************************/ +/** + Purpose: + + DSWAP interchanges two vectors. + + Licensing: + + This code is distributed under the GNU LGPL license. + + Modified: + + 30 March 2007 + + Author: + + C version by John Burkardt + + Reference: + + Jack Dongarra, Cleve Moler, Jim Bunch, Pete Stewart, + LINPACK User's Guide, + SIAM, 1979. + + Charles Lawson, Richard Hanson, David Kincaid, Fred Krogh, + Basic Linear Algebra Subprograms for Fortran Usage, + Algorithm 539, + ACM Transactions on Mathematical Software, + Volume 5, Number 3, September 1979, pages 308-323. + + Parameters: + + Input, int N, the number of entries in the vectors. + + Input/output, double X[*], one of the vectors to swap. + + Input, int INCX, the increment between successive entries of X. + + Input/output, double Y[*], one of the vectors to swap. + + Input, int INCY, the increment between successive elements of Y. +*/ +{ + if (n <= 0) return; + + int i, ix, iy, m; + double temp; + + if (incx == 1 && incy == 1) { + m = n % 3; + for (i = 0; i < m; i++) { + temp = x[i]; + x[i] = y[i]; + y[i] = temp; + } + for (i = m; i < n; i = i + 3) { + temp = x[i]; + x[i] = y[i]; + y[i] = temp; + temp = x[i + 1]; + x[i + 1] = y[i + 1]; + y[i + 1] = temp; + temp = x[i + 2]; + x[i + 2] = y[i + 2]; + y[i + 2] = temp; + } + } + else { + ix = (incx >= 0) ? 0 : (-n + 1) * incx; + iy = (incy >= 0) ? 0 : (-n + 1) * incy; + for (i = 0; i < n; i++) { + temp = x[ix]; + x[ix] = y[iy]; + y[iy] = temp; + ix = ix + incx; + iy = iy + incy; + } + } +} +/******************************************************************************/ + +/******************************************************************************/ + +void qr_solve(double x[], int m, int n, double a[], double b[]) + +/******************************************************************************/ +/** + Purpose: + + QR_SOLVE solves a linear system in the least squares sense. + + Discussion: + + If the matrix A has full column rank, then the solution X should be the + unique vector that minimizes the Euclidean norm of the residual. + + If the matrix A does not have full column rank, then the solution is + not unique; the vector X will minimize the residual norm, but so will + various other vectors. + + Licensing: + + This code is distributed under the GNU LGPL license. + + Modified: + + 11 September 2012 + + Author: + + John Burkardt + + Reference: + + David Kahaner, Cleve Moler, Steven Nash, + Numerical Methods and Software, + Prentice Hall, 1989, + ISBN: 0-13-627258-4, + LC: TA345.K34. + + Parameters: + + Input, int M, the number of rows of A. + + Input, int N, the number of columns of A. + + Input, double A[M*N], the matrix. + + Input, double B[M], the right hand side. + + Output, double QR_SOLVE[N], the least squares solution. +*/ +{ + double a_qr[n * m], qraux[n], r[m], tol; + int ind, itask, jpvt[n], kr, lda; + + r8mat_copy(a_qr, m, n, a); + lda = m; + tol = r8_epsilon() / r8mat_amax(m, n, a_qr); + itask = 1; + + ind = dqrls(a_qr, lda, m, n, tol, &kr, b, x, r, jpvt, qraux, itask); UNUSED(ind); +} +/******************************************************************************/ + +#endif diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/qr_solve.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/qr_solve.h new file mode 100644 index 00000000..3ea30e9e --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/qr_solve.h @@ -0,0 +1,44 @@ +/** + * 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 . + * + */ + +#include "MarlinConfig.h" + +#if ENABLED(AUTO_BED_LEVELING_GRID) + +void daxpy(int n, double da, double dx[], int incx, double dy[], int incy); +double ddot(int n, double dx[], int incx, double dy[], int incy); +double dnrm2(int n, double x[], int incx); +void dqrank(double a[], int lda, int m, int n, double tol, int* kr, + int jpvt[], double qraux[]); +void dqrdc(double a[], int lda, int n, int p, double qraux[], int jpvt[], + double work[], int job); +int dqrls(double a[], int lda, int m, int n, double tol, int* kr, double b[], + double x[], double rsd[], int jpvt[], double qraux[], int itask); +void dqrlss(double a[], int lda, int m, int n, int kr, double b[], double x[], + double rsd[], int jpvt[], double qraux[]); +int dqrsl(double a[], int lda, int n, int k, double qraux[], double y[], + double qy[], double qty[], double b[], double rsd[], double ab[], int job); +void dscal(int n, double sa, double x[], int incx); +void dswap(int n, double x[], int incx, double y[], int incy); +void qr_solve(double x[], int m, int n, double a[], double b[]); + +#endif diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/servo.cpp b/trunk/Arduino/Marlin_K8600_1.1.0RC7/servo.cpp new file mode 100644 index 00000000..b5f9ed86 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/servo.cpp @@ -0,0 +1,320 @@ +/** + * 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 . + * + */ + +/** + * servo.cpp - Interrupt driven Servo library for Arduino using 16 bit timers- Version 2 + * Copyright (c) 2009 Michael Margolis. All right reserved. + */ + +/** + * 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 + * + * Note that analogWrite of PWM on pins associated with the timer are disabled when the first servo is attached. + * Timers are seized as needed in groups of 12 servos - 24 servos use two timers, 48 servos will use four. + * + * The methods are: + * + * Servo - Class for manipulating servo motors connected to Arduino pins. + * + * attach(pin) - Attach a servo motor to an i/o pin. + * attach(pin, min, max) - Attach to a pin, setting min and max values in microseconds + * Default min is 544, max is 2400 + * + * write() - Set the servo angle in degrees. (Invalid angles —over MIN_PULSE_WIDTH— are treated as µs.) + * writeMicroseconds() - Set the servo pulse width in microseconds. + * move(pin, angle) - Sequence of attach(pin), write(angle), delay(SERVO_DELAY). + * With DEACTIVATE_SERVOS_AFTER_MOVE it detaches after SERVO_DELAY. + * read() - Get the last-written servo pulse width as an angle between 0 and 180. + * 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 "MarlinConfig.h" + +#if HAS_SERVOS + +#include +#include + +#include "servo.h" + +#define usToTicks(_us) (( clockCyclesPerMicrosecond()* _us) / 8) // converts microseconds to tick (assumes prescale of 8) // 12 Aug 2009 +#define ticksToUs(_ticks) (( (unsigned)_ticks * 8)/ clockCyclesPerMicrosecond() ) // converts from ticks back to microseconds + +#define TRIM_DURATION 2 // compensation ticks to trim adjust for digitalWrite delays // 12 August 2009 + +//#define NBR_TIMERS ((MAX_SERVOS) / (SERVOS_PER_TIMER)) + +static ServoInfo_t servo_info[MAX_SERVOS]; // static array of servo info structures +static volatile int8_t Channel[_Nbr_16timers ]; // counter for the servo being pulsed for each timer (or -1 if refresh interval) + +uint8_t ServoCount = 0; // the total number of attached servos + + +// convenience macros +#define SERVO_INDEX_TO_TIMER(_servo_nbr) ((timer16_Sequence_t)(_servo_nbr / (SERVOS_PER_TIMER))) // returns the timer controlling this servo +#define SERVO_INDEX_TO_CHANNEL(_servo_nbr) (_servo_nbr % (SERVOS_PER_TIMER)) // returns the index of the servo on this timer +#define SERVO_INDEX(_timer,_channel) ((_timer*(SERVOS_PER_TIMER)) + _channel) // macro to access servo index by timer and channel +#define SERVO(_timer,_channel) (servo_info[SERVO_INDEX(_timer,_channel)]) // macro to access servo class by timer and channel + +#define SERVO_MIN() (MIN_PULSE_WIDTH - this->min * 4) // minimum value in uS for this servo +#define SERVO_MAX() (MAX_PULSE_WIDTH - this->max * 4) // maximum value in uS for this servo + +/************ static functions common to all instances ***********************/ + +static inline void handle_interrupts(timer16_Sequence_t timer, volatile uint16_t* TCNTn, volatile uint16_t* OCRnA) { + if (Channel[timer] < 0) + *TCNTn = 0; // channel set to -1 indicated that refresh interval completed so reset the timer + else { + if (SERVO_INDEX(timer, Channel[timer]) < ServoCount && SERVO(timer, Channel[timer]).Pin.isActive) + digitalWrite(SERVO(timer, Channel[timer]).Pin.nbr, LOW); // pulse this channel low if activated + } + + Channel[timer]++; // increment to the next channel + if (SERVO_INDEX(timer, Channel[timer]) < ServoCount && Channel[timer] < SERVOS_PER_TIMER) { + *OCRnA = *TCNTn + SERVO(timer, Channel[timer]).ticks; + if (SERVO(timer, Channel[timer]).Pin.isActive) // check if activated + digitalWrite(SERVO(timer, Channel[timer]).Pin.nbr, HIGH); // its an active channel so pulse it high + } + else { + // finished all channels so wait for the refresh period to expire before starting over + if (((unsigned)*TCNTn) + 4 < usToTicks(REFRESH_INTERVAL)) // allow a few ticks to ensure the next OCR1A not missed + *OCRnA = (unsigned int)usToTicks(REFRESH_INTERVAL); + else + *OCRnA = *TCNTn + 4; // at least REFRESH_INTERVAL has elapsed + Channel[timer] = -1; // this will get incremented at the end of the refresh period to start again at the first channel + } +} + +#ifndef WIRING // Wiring pre-defines signal handlers so don't define any if compiling for the Wiring platform + + // Interrupt handlers for Arduino + #if ENABLED(_useTimer1) + SIGNAL (TIMER1_COMPA_vect) { handle_interrupts(_timer1, &TCNT1, &OCR1A); } + #endif + + #if ENABLED(_useTimer3) + SIGNAL (TIMER3_COMPA_vect) { handle_interrupts(_timer3, &TCNT3, &OCR3A); } + #endif + + #if ENABLED(_useTimer4) + SIGNAL (TIMER4_COMPA_vect) { handle_interrupts(_timer4, &TCNT4, &OCR4A); } + #endif + + #if ENABLED(_useTimer5) + SIGNAL (TIMER5_COMPA_vect) { handle_interrupts(_timer5, &TCNT5, &OCR5A); } + #endif + +#else //!WIRING + + // Interrupt handlers for Wiring + #if ENABLED(_useTimer1) + void Timer1Service() { handle_interrupts(_timer1, &TCNT1, &OCR1A); } + #endif + #if ENABLED(_useTimer3) + void Timer3Service() { handle_interrupts(_timer3, &TCNT3, &OCR3A); } + #endif + +#endif //!WIRING + + +static void initISR(timer16_Sequence_t timer) { + #if ENABLED(_useTimer1) + if (timer == _timer1) { + TCCR1A = 0; // normal counting mode + TCCR1B = _BV(CS11); // set prescaler of 8 + TCNT1 = 0; // clear the timer count + #if defined(__AVR_ATmega8__)|| defined(__AVR_ATmega128__) + SBI(TIFR, OCF1A); // clear any pending interrupts; + SBI(TIMSK, OCIE1A); // enable the output compare interrupt + #else + // here if not ATmega8 or ATmega128 + SBI(TIFR1, OCF1A); // clear any pending interrupts; + SBI(TIMSK1, OCIE1A); // enable the output compare interrupt + #endif + #ifdef WIRING + timerAttach(TIMER1OUTCOMPAREA_INT, Timer1Service); + #endif + } + #endif + + #if ENABLED(_useTimer3) + if (timer == _timer3) { + TCCR3A = 0; // normal counting mode + TCCR3B = _BV(CS31); // set prescaler of 8 + TCNT3 = 0; // clear the timer count + #ifdef __AVR_ATmega128__ + SBI(TIFR, OCF3A); // clear any pending interrupts; + SBI(ETIMSK, OCIE3A); // enable the output compare interrupt + #else + TIFR3 = _BV(OCF3A); // clear any pending interrupts; + TIMSK3 = _BV(OCIE3A) ; // enable the output compare interrupt + #endif + #ifdef WIRING + timerAttach(TIMER3OUTCOMPAREA_INT, Timer3Service); // for Wiring platform only + #endif + } + #endif + + #if ENABLED(_useTimer4) + if (timer == _timer4) { + TCCR4A = 0; // normal counting mode + TCCR4B = _BV(CS41); // set prescaler of 8 + TCNT4 = 0; // clear the timer count + TIFR4 = _BV(OCF4A); // clear any pending interrupts; + TIMSK4 = _BV(OCIE4A) ; // enable the output compare interrupt + } + #endif + + #if ENABLED(_useTimer5) + if (timer == _timer5) { + TCCR5A = 0; // normal counting mode + TCCR5B = _BV(CS51); // set prescaler of 8 + TCNT5 = 0; // clear the timer count + TIFR5 = _BV(OCF5A); // clear any pending interrupts; + TIMSK5 = _BV(OCIE5A) ; // enable the output compare interrupt + } + #endif +} + +static void finISR(timer16_Sequence_t timer) { + // Disable use of the given timer + #ifdef WIRING + if (timer == _timer1) { + CBI( + #if defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__) + TIMSK1 + #else + TIMSK + #endif + , OCIE1A); // disable timer 1 output compare interrupt + timerDetach(TIMER1OUTCOMPAREA_INT); + } + else if (timer == _timer3) { + CBI( + #if defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__) + TIMSK3 + #else + ETIMSK + #endif + , OCIE3A); // disable the timer3 output compare A interrupt + timerDetach(TIMER3OUTCOMPAREA_INT); + } + #else //!WIRING + // For arduino - in future: call here to a currently undefined function to reset the timer + UNUSED(timer); + #endif +} + +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++) { + if (SERVO(timer, channel).Pin.isActive) + return true; + } + return false; +} + + +/****************** end of static functions ******************************/ + +Servo::Servo() { + if (ServoCount < MAX_SERVOS) { + this->servoIndex = ServoCount++; // assign a servo index to this instance + servo_info[this->servoIndex].ticks = usToTicks(DEFAULT_PULSE_WIDTH); // store default values - 12 Aug 2009 + } + else + this->servoIndex = INVALID_SERVO; // too many servos +} + +int8_t Servo::attach(int pin) { + return this->attach(pin, MIN_PULSE_WIDTH, MAX_PULSE_WIDTH); +} + +int8_t Servo::attach(int pin, int min, int max) { + + if (this->servoIndex >= MAX_SERVOS) return -1; + + if (pin > 0) servo_info[this->servoIndex].Pin.nbr = pin; + pinMode(servo_info[this->servoIndex].Pin.nbr, OUTPUT); // set servo pin to output + + // todo min/max check: abs(min - MIN_PULSE_WIDTH) /4 < 128 + this->min = (MIN_PULSE_WIDTH - min) / 4; //resolution of min/max is 4 uS + this->max = (MAX_PULSE_WIDTH - max) / 4; + + // initialize the timer if it has not already been initialized + timer16_Sequence_t timer = SERVO_INDEX_TO_TIMER(servoIndex); + if (!isTimerActive(timer)) initISR(timer); + servo_info[this->servoIndex].Pin.isActive = true; // this must be set after the check for isTimerActive + + return this->servoIndex; +} + +void Servo::detach() { + servo_info[this->servoIndex].Pin.isActive = false; + timer16_Sequence_t timer = SERVO_INDEX_TO_TIMER(servoIndex); + if (!isTimerActive(timer)) finISR(timer); +} + +void Servo::write(int value) { + if (value < MIN_PULSE_WIDTH) { // treat values less than 544 as angles in degrees (valid values in microseconds are handled as microseconds) + value = map(constrain(value, 0, 180), 0, 180, SERVO_MIN(), SERVO_MAX()); + } + this->writeMicroseconds(value); +} + +void Servo::writeMicroseconds(int value) { + // calculate and store the values for the given channel + byte channel = this->servoIndex; + if (channel < MAX_SERVOS) { // ensure channel is valid + // ensure pulse width is valid + value = constrain(value, SERVO_MIN(), SERVO_MAX()) - (TRIM_DURATION); + value = usToTicks(value); // convert to ticks after compensating for interrupt overhead - 12 Aug 2009 + + CRITICAL_SECTION_START; + servo_info[channel].ticks = value; + CRITICAL_SECTION_END; + } +} + +// return the value as degrees +int Servo::read() { return map(this->readMicroseconds() + 1, SERVO_MIN(), SERVO_MAX(), 0, 180); } + +int Servo::readMicroseconds() { + return (this->servoIndex == INVALID_SERVO) ? 0 : ticksToUs(servo_info[this->servoIndex].ticks) + TRIM_DURATION; +} + +bool Servo::attached() { return servo_info[this->servoIndex].Pin.isActive; } + +void Servo::move(int value) { + if (this->attach(0) >= 0) { + this->write(value); + delay(SERVO_DELAY); + #if ENABLED(DEACTIVATE_SERVOS_AFTER_MOVE) + this->detach(); + #endif + } +} + +#endif diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/servo.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/servo.h new file mode 100644 index 00000000..07532bc3 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/servo.h @@ -0,0 +1,161 @@ +/** + * 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 . + * + */ + +/** + servo.h - Interrupt driven Servo library for Arduino using 16 bit timers- Version 2 + Copyright (c) 2009 Michael Margolis. 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 +*/ + +/** + + 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 + + Note that analogWrite of PWM on pins associated with the timer are disabled when the first servo is attached. + Timers are seized as needed in groups of 12 servos - 24 servos use two timers, 48 servos will use four. + The sequence used to seize timers is defined in timers.h + + The methods are: + + Servo - Class for manipulating servo motors connected to Arduino pins. + + attach(pin ) - Attaches a servo motor to an i/o pin. + attach(pin, min, max ) - Attaches to a pin setting min and max values in microseconds + default min is 544, max is 2400 + + write() - Sets the servo angle in degrees. (invalid angle that is valid as pulse in microseconds is treated as microseconds) + writeMicroseconds() - Sets the servo pulse width in microseconds + read() - Gets the last written servo pulse width as an angle between 0 and 180. + readMicroseconds() - Gets the last written servo pulse width in microseconds. (was read_us() in first release) + attached() - Returns true if there is a servo attached. + detach() - Stops an attached servos from pulsing its i/o pin. + move(angle) - Sequence of attach(0), write(angle), + With DEACTIVATE_SERVOS_AFTER_MOVE wait SERVO_DELAY and detach. + */ + +#ifndef servo_h +#define servo_h + +#include + +/** + * Defines for 16 bit timers used with Servo library + * + * If _useTimerX is defined then TimerX is a 16 bit timer on the current board + * timer16_Sequence_t enumerates the sequence that the timers should be allocated + * _Nbr_16timers indicates how many 16 bit timers are available. + * + */ + +// 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. + #endif +#elif defined(__AVR_ATmega32U4__) + #define _useTimer3 +#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) + #define _useTimer3 +#elif defined(__AVR_ATmega128__) || defined(__AVR_ATmega1281__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega2561__) + #define _useTimer3 +#else + // everything else +#endif + +typedef enum { + #if ENABLED(_useTimer1) + _timer1, + #endif + #if ENABLED(_useTimer3) + _timer3, + #endif + #if ENABLED(_useTimer4) + _timer4, + #endif + #if ENABLED(_useTimer5) + _timer5, + #endif + _Nbr_16timers +} timer16_Sequence_t; + + +#define Servo_VERSION 2 // software version of this library + +#define MIN_PULSE_WIDTH 544 // the shortest pulse sent to a servo +#define MAX_PULSE_WIDTH 2400 // the longest pulse sent to a servo +#define DEFAULT_PULSE_WIDTH 1500 // default pulse width when servo is attached +#define REFRESH_INTERVAL 20000 // minimum time to refresh servos in microseconds + +#define SERVOS_PER_TIMER 12 // the maximum number of servos controlled by one timer +#define MAX_SERVOS (_Nbr_16timers * SERVOS_PER_TIMER) + +#define INVALID_SERVO 255 // flag indicating an invalid servo index + +typedef struct { + uint8_t nbr : 6 ; // a pin number from 0 to 63 + uint8_t isActive : 1 ; // true if this channel is enabled, pin not pulsed if false +} ServoPin_t; + +typedef struct { + ServoPin_t Pin; + unsigned int ticks; +} ServoInfo_t; + +class Servo { + public: + Servo(); + int8_t attach(int pin); // attach the given pin to the next free channel, set pinMode, return channel number (-1 on fail) + int8_t attach(int pin, int min, int max); // as above but also sets min and max values for writes. + void detach(); + void write(int value); // if value is < 200 it is treated as an angle, otherwise as pulse width in microseconds + void writeMicroseconds(int value); // write pulse width in microseconds + void move(int value); // attach the servo, then move to value + // if value is < 200 it is treated as an angle, otherwise as pulse width in microseconds + // if DEACTIVATE_SERVOS_AFTER_MOVE wait SERVO_DELAY, then detach + int read(); // returns current pulse width as an angle between 0 and 180 degrees + int readMicroseconds(); // returns current pulse width in microseconds for this servo (was read_us() in first release) + bool attached(); // return true if this servo is attached, otherwise false + + private: + uint8_t servoIndex; // index into the channel data for this servo + int8_t min; // minimum is this value times 4 added to MIN_PULSE_WIDTH + int8_t max; // maximum is this value times 4 added to MAX_PULSE_WIDTH +}; + +#endif diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/speed_lookuptable.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/speed_lookuptable.h new file mode 100644 index 00000000..08cc4839 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/speed_lookuptable.h @@ -0,0 +1,174 @@ +/** + * 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 . + * + */ + +#ifndef SPEED_LOOKUPTABLE_H +#define SPEED_LOOKUPTABLE_H + +#include "Marlin.h" + +#if F_CPU == 16000000 + +const uint16_t speed_lookuptable_fast[256][2] PROGMEM = {\ + { 62500, 55556}, { 6944, 3268}, { 3676, 1176}, { 2500, 607}, { 1893, 369}, { 1524, 249}, { 1275, 179}, { 1096, 135}, + { 961, 105}, { 856, 85}, { 771, 69}, { 702, 58}, { 644, 49}, { 595, 42}, { 553, 37}, { 516, 32}, + { 484, 28}, { 456, 25}, { 431, 23}, { 408, 20}, { 388, 19}, { 369, 16}, { 353, 16}, { 337, 14}, + { 323, 13}, { 310, 11}, { 299, 11}, { 288, 11}, { 277, 9}, { 268, 9}, { 259, 8}, { 251, 8}, + { 243, 8}, { 235, 7}, { 228, 6}, { 222, 6}, { 216, 6}, { 210, 6}, { 204, 5}, { 199, 5}, + { 194, 5}, { 189, 4}, { 185, 4}, { 181, 4}, { 177, 4}, { 173, 4}, { 169, 4}, { 165, 3}, + { 162, 3}, { 159, 4}, { 155, 3}, { 152, 3}, { 149, 2}, { 147, 3}, { 144, 3}, { 141, 2}, + { 139, 3}, { 136, 2}, { 134, 2}, { 132, 3}, { 129, 2}, { 127, 2}, { 125, 2}, { 123, 2}, + { 121, 2}, { 119, 1}, { 118, 2}, { 116, 2}, { 114, 1}, { 113, 2}, { 111, 2}, { 109, 1}, + { 108, 2}, { 106, 1}, { 105, 2}, { 103, 1}, { 102, 1}, { 101, 1}, { 100, 2}, { 98, 1}, + { 97, 1}, { 96, 1}, { 95, 2}, { 93, 1}, { 92, 1}, { 91, 1}, { 90, 1}, { 89, 1}, + { 88, 1}, { 87, 1}, { 86, 1}, { 85, 1}, { 84, 1}, { 83, 0}, { 83, 1}, { 82, 1}, + { 81, 1}, { 80, 1}, { 79, 1}, { 78, 0}, { 78, 1}, { 77, 1}, { 76, 1}, { 75, 0}, + { 75, 1}, { 74, 1}, { 73, 1}, { 72, 0}, { 72, 1}, { 71, 1}, { 70, 0}, { 70, 1}, + { 69, 0}, { 69, 1}, { 68, 1}, { 67, 0}, { 67, 1}, { 66, 0}, { 66, 1}, { 65, 0}, + { 65, 1}, { 64, 1}, { 63, 0}, { 63, 1}, { 62, 0}, { 62, 1}, { 61, 0}, { 61, 1}, + { 60, 0}, { 60, 0}, { 60, 1}, { 59, 0}, { 59, 1}, { 58, 0}, { 58, 1}, { 57, 0}, + { 57, 1}, { 56, 0}, { 56, 0}, { 56, 1}, { 55, 0}, { 55, 1}, { 54, 0}, { 54, 0}, + { 54, 1}, { 53, 0}, { 53, 0}, { 53, 1}, { 52, 0}, { 52, 0}, { 52, 1}, { 51, 0}, + { 51, 0}, { 51, 1}, { 50, 0}, { 50, 0}, { 50, 1}, { 49, 0}, { 49, 0}, { 49, 1}, + { 48, 0}, { 48, 0}, { 48, 1}, { 47, 0}, { 47, 0}, { 47, 0}, { 47, 1}, { 46, 0}, + { 46, 0}, { 46, 1}, { 45, 0}, { 45, 0}, { 45, 0}, { 45, 1}, { 44, 0}, { 44, 0}, + { 44, 0}, { 44, 1}, { 43, 0}, { 43, 0}, { 43, 0}, { 43, 1}, { 42, 0}, { 42, 0}, + { 42, 0}, { 42, 1}, { 41, 0}, { 41, 0}, { 41, 0}, { 41, 0}, { 41, 1}, { 40, 0}, + { 40, 0}, { 40, 0}, { 40, 0}, { 40, 1}, { 39, 0}, { 39, 0}, { 39, 0}, { 39, 0}, + { 39, 1}, { 38, 0}, { 38, 0}, { 38, 0}, { 38, 0}, { 38, 1}, { 37, 0}, { 37, 0}, + { 37, 0}, { 37, 0}, { 37, 0}, { 37, 1}, { 36, 0}, { 36, 0}, { 36, 0}, { 36, 0}, + { 36, 1}, { 35, 0}, { 35, 0}, { 35, 0}, { 35, 0}, { 35, 0}, { 35, 0}, { 35, 1}, + { 34, 0}, { 34, 0}, { 34, 0}, { 34, 0}, { 34, 0}, { 34, 1}, { 33, 0}, { 33, 0}, + { 33, 0}, { 33, 0}, { 33, 0}, { 33, 0}, { 33, 1}, { 32, 0}, { 32, 0}, { 32, 0}, + { 32, 0}, { 32, 0}, { 32, 0}, { 32, 0}, { 32, 1}, { 31, 0}, { 31, 0}, { 31, 0}, + { 31, 0}, { 31, 0}, { 31, 0}, { 31, 1}, { 30, 0}, { 30, 0}, { 30, 0}, { 30, 0} +}; + +const uint16_t speed_lookuptable_slow[256][2] PROGMEM = {\ + { 62500, 12500}, { 50000, 8334}, { 41666, 5952}, { 35714, 4464}, { 31250, 3473}, { 27777, 2777}, { 25000, 2273}, { 22727, 1894}, + { 20833, 1603}, { 19230, 1373}, { 17857, 1191}, { 16666, 1041}, { 15625, 920}, { 14705, 817}, { 13888, 731}, { 13157, 657}, + { 12500, 596}, { 11904, 541}, { 11363, 494}, { 10869, 453}, { 10416, 416}, { 10000, 385}, { 9615, 356}, { 9259, 331}, + { 8928, 308}, { 8620, 287}, { 8333, 269}, { 8064, 252}, { 7812, 237}, { 7575, 223}, { 7352, 210}, { 7142, 198}, + { 6944, 188}, { 6756, 178}, { 6578, 168}, { 6410, 160}, { 6250, 153}, { 6097, 145}, { 5952, 139}, { 5813, 132}, + { 5681, 126}, { 5555, 121}, { 5434, 115}, { 5319, 111}, { 5208, 106}, { 5102, 102}, { 5000, 99}, { 4901, 94}, + { 4807, 91}, { 4716, 87}, { 4629, 84}, { 4545, 81}, { 4464, 79}, { 4385, 75}, { 4310, 73}, { 4237, 71}, + { 4166, 68}, { 4098, 66}, { 4032, 64}, { 3968, 62}, { 3906, 60}, { 3846, 59}, { 3787, 56}, { 3731, 55}, + { 3676, 53}, { 3623, 52}, { 3571, 50}, { 3521, 49}, { 3472, 48}, { 3424, 46}, { 3378, 45}, { 3333, 44}, + { 3289, 43}, { 3246, 41}, { 3205, 41}, { 3164, 39}, { 3125, 39}, { 3086, 38}, { 3048, 36}, { 3012, 36}, + { 2976, 35}, { 2941, 35}, { 2906, 33}, { 2873, 33}, { 2840, 32}, { 2808, 31}, { 2777, 30}, { 2747, 30}, + { 2717, 29}, { 2688, 29}, { 2659, 28}, { 2631, 27}, { 2604, 27}, { 2577, 26}, { 2551, 26}, { 2525, 25}, + { 2500, 25}, { 2475, 25}, { 2450, 23}, { 2427, 24}, { 2403, 23}, { 2380, 22}, { 2358, 22}, { 2336, 22}, + { 2314, 21}, { 2293, 21}, { 2272, 20}, { 2252, 20}, { 2232, 20}, { 2212, 20}, { 2192, 19}, { 2173, 18}, + { 2155, 19}, { 2136, 18}, { 2118, 18}, { 2100, 17}, { 2083, 17}, { 2066, 17}, { 2049, 17}, { 2032, 16}, + { 2016, 16}, { 2000, 16}, { 1984, 16}, { 1968, 15}, { 1953, 16}, { 1937, 14}, { 1923, 15}, { 1908, 15}, + { 1893, 14}, { 1879, 14}, { 1865, 14}, { 1851, 13}, { 1838, 14}, { 1824, 13}, { 1811, 13}, { 1798, 13}, + { 1785, 12}, { 1773, 13}, { 1760, 12}, { 1748, 12}, { 1736, 12}, { 1724, 12}, { 1712, 12}, { 1700, 11}, + { 1689, 12}, { 1677, 11}, { 1666, 11}, { 1655, 11}, { 1644, 11}, { 1633, 10}, { 1623, 11}, { 1612, 10}, + { 1602, 10}, { 1592, 10}, { 1582, 10}, { 1572, 10}, { 1562, 10}, { 1552, 9}, { 1543, 10}, { 1533, 9}, + { 1524, 9}, { 1515, 9}, { 1506, 9}, { 1497, 9}, { 1488, 9}, { 1479, 9}, { 1470, 9}, { 1461, 8}, + { 1453, 8}, { 1445, 9}, { 1436, 8}, { 1428, 8}, { 1420, 8}, { 1412, 8}, { 1404, 8}, { 1396, 8}, + { 1388, 7}, { 1381, 8}, { 1373, 7}, { 1366, 8}, { 1358, 7}, { 1351, 7}, { 1344, 8}, { 1336, 7}, + { 1329, 7}, { 1322, 7}, { 1315, 7}, { 1308, 6}, { 1302, 7}, { 1295, 7}, { 1288, 6}, { 1282, 7}, + { 1275, 6}, { 1269, 7}, { 1262, 6}, { 1256, 6}, { 1250, 7}, { 1243, 6}, { 1237, 6}, { 1231, 6}, + { 1225, 6}, { 1219, 6}, { 1213, 6}, { 1207, 6}, { 1201, 5}, { 1196, 6}, { 1190, 6}, { 1184, 5}, + { 1179, 6}, { 1173, 5}, { 1168, 6}, { 1162, 5}, { 1157, 5}, { 1152, 6}, { 1146, 5}, { 1141, 5}, + { 1136, 5}, { 1131, 5}, { 1126, 5}, { 1121, 5}, { 1116, 5}, { 1111, 5}, { 1106, 5}, { 1101, 5}, + { 1096, 5}, { 1091, 5}, { 1086, 4}, { 1082, 5}, { 1077, 5}, { 1072, 4}, { 1068, 5}, { 1063, 4}, + { 1059, 5}, { 1054, 4}, { 1050, 4}, { 1046, 5}, { 1041, 4}, { 1037, 4}, { 1033, 5}, { 1028, 4}, + { 1024, 4}, { 1020, 4}, { 1016, 4}, { 1012, 4}, { 1008, 4}, { 1004, 4}, { 1000, 4}, { 996, 4}, + { 992, 4}, { 988, 4}, { 984, 4}, { 980, 4}, { 976, 4}, { 972, 4}, { 968, 3}, { 965, 3} +}; + +#elif F_CPU == 20000000 + +const uint16_t speed_lookuptable_fast[256][2] PROGMEM = { + {62500, 54055}, {8445, 3917}, {4528, 1434}, {3094, 745}, {2349, 456}, {1893, 307}, {1586, 222}, {1364, 167}, + {1197, 131}, {1066, 105}, {961, 86}, {875, 72}, {803, 61}, {742, 53}, {689, 45}, {644, 40}, + {604, 35}, {569, 32}, {537, 28}, {509, 25}, {484, 23}, {461, 21}, {440, 19}, {421, 17}, + {404, 16}, {388, 15}, {373, 14}, {359, 13}, {346, 12}, {334, 11}, {323, 10}, {313, 10}, + {303, 9}, {294, 9}, {285, 8}, {277, 7}, {270, 8}, {262, 7}, {255, 6}, {249, 6}, + {243, 6}, {237, 6}, {231, 5}, {226, 5}, {221, 5}, {216, 5}, {211, 4}, {207, 5}, + {202, 4}, {198, 4}, {194, 4}, {190, 3}, {187, 4}, {183, 3}, {180, 3}, {177, 4}, + {173, 3}, {170, 3}, {167, 2}, {165, 3}, {162, 3}, {159, 2}, {157, 3}, {154, 2}, + {152, 3}, {149, 2}, {147, 2}, {145, 2}, {143, 2}, {141, 2}, {139, 2}, {137, 2}, + {135, 2}, {133, 2}, {131, 2}, {129, 1}, {128, 2}, {126, 2}, {124, 1}, {123, 2}, + {121, 1}, {120, 2}, {118, 1}, {117, 1}, {116, 2}, {114, 1}, {113, 1}, {112, 2}, + {110, 1}, {109, 1}, {108, 1}, {107, 2}, {105, 1}, {104, 1}, {103, 1}, {102, 1}, + {101, 1}, {100, 1}, {99, 1}, {98, 1}, {97, 1}, {96, 1}, {95, 1}, {94, 1}, + {93, 1}, {92, 1}, {91, 0}, {91, 1}, {90, 1}, {89, 1}, {88, 1}, {87, 0}, + {87, 1}, {86, 1}, {85, 1}, {84, 0}, {84, 1}, {83, 1}, {82, 1}, {81, 0}, + {81, 1}, {80, 1}, {79, 0}, {79, 1}, {78, 0}, {78, 1}, {77, 1}, {76, 0}, + {76, 1}, {75, 0}, {75, 1}, {74, 1}, {73, 0}, {73, 1}, {72, 0}, {72, 1}, + {71, 0}, {71, 1}, {70, 0}, {70, 1}, {69, 0}, {69, 1}, {68, 0}, {68, 1}, + {67, 0}, {67, 1}, {66, 0}, {66, 1}, {65, 0}, {65, 0}, {65, 1}, {64, 0}, + {64, 1}, {63, 0}, {63, 1}, {62, 0}, {62, 0}, {62, 1}, {61, 0}, {61, 1}, + {60, 0}, {60, 0}, {60, 1}, {59, 0}, {59, 0}, {59, 1}, {58, 0}, {58, 0}, + {58, 1}, {57, 0}, {57, 0}, {57, 1}, {56, 0}, {56, 0}, {56, 1}, {55, 0}, + {55, 0}, {55, 1}, {54, 0}, {54, 0}, {54, 1}, {53, 0}, {53, 0}, {53, 0}, + {53, 1}, {52, 0}, {52, 0}, {52, 1}, {51, 0}, {51, 0}, {51, 0}, {51, 1}, + {50, 0}, {50, 0}, {50, 0}, {50, 1}, {49, 0}, {49, 0}, {49, 0}, {49, 1}, + {48, 0}, {48, 0}, {48, 0}, {48, 1}, {47, 0}, {47, 0}, {47, 0}, {47, 1}, + {46, 0}, {46, 0}, {46, 0}, {46, 0}, {46, 1}, {45, 0}, {45, 0}, {45, 0}, + {45, 1}, {44, 0}, {44, 0}, {44, 0}, {44, 0}, {44, 1}, {43, 0}, {43, 0}, + {43, 0}, {43, 0}, {43, 1}, {42, 0}, {42, 0}, {42, 0}, {42, 0}, {42, 0}, + {42, 1}, {41, 0}, {41, 0}, {41, 0}, {41, 0}, {41, 0}, {41, 1}, {40, 0}, + {40, 0}, {40, 0}, {40, 0}, {40, 1}, {39, 0}, {39, 0}, {39, 0}, {39, 0}, + {39, 0}, {39, 0}, {39, 1}, {38, 0}, {38, 0}, {38, 0}, {38, 0}, {38, 0}, +}; + +const uint16_t speed_lookuptable_slow[256][2] PROGMEM = { + {62500, 10417}, {52083, 7441}, {44642, 5580}, {39062, 4340}, {34722, 3472}, {31250, 2841}, {28409, 2368}, {26041, 2003}, + {24038, 1717}, {22321, 1488}, {20833, 1302}, {19531, 1149}, {18382, 1021}, {17361, 914}, {16447, 822}, {15625, 745}, + {14880, 676}, {14204, 618}, {13586, 566}, {13020, 520}, {12500, 481}, {12019, 445}, {11574, 414}, {11160, 385}, + {10775, 359}, {10416, 336}, {10080, 315}, {9765, 296}, {9469, 278}, {9191, 263}, {8928, 248}, {8680, 235}, + {8445, 222}, {8223, 211}, {8012, 200}, {7812, 191}, {7621, 181}, {7440, 173}, {7267, 165}, {7102, 158}, + {6944, 151}, {6793, 145}, {6648, 138}, {6510, 133}, {6377, 127}, {6250, 123}, {6127, 118}, {6009, 113}, + {5896, 109}, {5787, 106}, {5681, 101}, {5580, 98}, {5482, 95}, {5387, 91}, {5296, 88}, {5208, 86}, + {5122, 82}, {5040, 80}, {4960, 78}, {4882, 75}, {4807, 73}, {4734, 70}, {4664, 69}, {4595, 67}, + {4528, 64}, {4464, 63}, {4401, 61}, {4340, 60}, {4280, 58}, {4222, 56}, {4166, 55}, {4111, 53}, + {4058, 52}, {4006, 51}, {3955, 49}, {3906, 48}, {3858, 48}, {3810, 45}, {3765, 45}, {3720, 44}, + {3676, 43}, {3633, 42}, {3591, 40}, {3551, 40}, {3511, 39}, {3472, 38}, {3434, 38}, {3396, 36}, + {3360, 36}, {3324, 35}, {3289, 34}, {3255, 34}, {3221, 33}, {3188, 32}, {3156, 31}, {3125, 31}, + {3094, 31}, {3063, 30}, {3033, 29}, {3004, 28}, {2976, 28}, {2948, 28}, {2920, 27}, {2893, 27}, + {2866, 26}, {2840, 25}, {2815, 25}, {2790, 25}, {2765, 24}, {2741, 24}, {2717, 24}, {2693, 23}, + {2670, 22}, {2648, 22}, {2626, 22}, {2604, 22}, {2582, 21}, {2561, 21}, {2540, 20}, {2520, 20}, + {2500, 20}, {2480, 20}, {2460, 19}, {2441, 19}, {2422, 19}, {2403, 18}, {2385, 18}, {2367, 18}, + {2349, 17}, {2332, 18}, {2314, 17}, {2297, 16}, {2281, 17}, {2264, 16}, {2248, 16}, {2232, 16}, + {2216, 16}, {2200, 15}, {2185, 15}, {2170, 15}, {2155, 15}, {2140, 15}, {2125, 14}, {2111, 14}, + {2097, 14}, {2083, 14}, {2069, 14}, {2055, 13}, {2042, 13}, {2029, 13}, {2016, 13}, {2003, 13}, + {1990, 13}, {1977, 12}, {1965, 12}, {1953, 13}, {1940, 11}, {1929, 12}, {1917, 12}, {1905, 12}, + {1893, 11}, {1882, 11}, {1871, 11}, {1860, 11}, {1849, 11}, {1838, 11}, {1827, 11}, {1816, 10}, + {1806, 11}, {1795, 10}, {1785, 10}, {1775, 10}, {1765, 10}, {1755, 10}, {1745, 9}, {1736, 10}, + {1726, 9}, {1717, 10}, {1707, 9}, {1698, 9}, {1689, 9}, {1680, 9}, {1671, 9}, {1662, 9}, + {1653, 9}, {1644, 8}, {1636, 9}, {1627, 8}, {1619, 9}, {1610, 8}, {1602, 8}, {1594, 8}, + {1586, 8}, {1578, 8}, {1570, 8}, {1562, 8}, {1554, 7}, {1547, 8}, {1539, 8}, {1531, 7}, + {1524, 8}, {1516, 7}, {1509, 7}, {1502, 7}, {1495, 7}, {1488, 7}, {1481, 7}, {1474, 7}, + {1467, 7}, {1460, 7}, {1453, 7}, {1446, 6}, {1440, 7}, {1433, 7}, {1426, 6}, {1420, 6}, + {1414, 7}, {1407, 6}, {1401, 6}, {1395, 7}, {1388, 6}, {1382, 6}, {1376, 6}, {1370, 6}, + {1364, 6}, {1358, 6}, {1352, 6}, {1346, 5}, {1341, 6}, {1335, 6}, {1329, 5}, {1324, 6}, + {1318, 5}, {1313, 6}, {1307, 5}, {1302, 6}, {1296, 5}, {1291, 5}, {1286, 6}, {1280, 5}, + {1275, 5}, {1270, 5}, {1265, 5}, {1260, 5}, {1255, 5}, {1250, 5}, {1245, 5}, {1240, 5}, + {1235, 5}, {1230, 5}, {1225, 5}, {1220, 5}, {1215, 4}, {1211, 5}, {1206, 5}, {1201, 5}, +}; + +#endif + +#endif diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/stepper.cpp b/trunk/Arduino/Marlin_K8600_1.1.0RC7/stepper.cpp new file mode 100644 index 00000000..88e8cd56 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/stepper.cpp @@ -0,0 +1,1250 @@ +/** + * 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 . + * + */ + +/** + * stepper.cpp - A singleton object to execute motion plans using stepper motors + * Marlin Firmware + * + * Derived from Grbl + * Copyright (c) 2009-2011 Simen Svale Skogsrud + * + * Grbl is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Grbl is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * 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 . + */ + +/* The timer calculations of this module informed by the 'RepRap cartesian firmware' by Zack Smith + and Philipp Tiefenbacher. */ + +#include "Marlin.h" +#include "stepper.h" +#include "endstops.h" +#include "planner.h" +#include "temperature.h" +#include "ultralcd.h" +#include "language.h" +#include "cardreader.h" +#include "speed_lookuptable.h" + +#if HAS_DIGIPOTSS + #include +#endif + +Stepper stepper; // Singleton + +// public: + +block_t* Stepper::current_block = NULL; // A pointer to the block currently being traced + +#if ENABLED(ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED) + bool Stepper::abort_on_endstop_hit = false; +#endif + +#if ENABLED(Z_DUAL_ENDSTOPS) + bool Stepper::performing_homing = false; +#endif + +// private: + +unsigned char Stepper::last_direction_bits = 0; // The next stepping-bits to be output +unsigned int Stepper::cleaning_buffer_counter = 0; + +#if ENABLED(Z_DUAL_ENDSTOPS) + bool Stepper::locked_z_motor = false; + bool Stepper::locked_z2_motor = false; +#endif + +long Stepper::counter_X = 0, + Stepper::counter_Y = 0, + Stepper::counter_Z = 0, + Stepper::counter_E = 0; + +volatile unsigned long Stepper::step_events_completed = 0; // The number of step events executed in the current block + +#if ENABLED(ADVANCE) || ENABLED(LIN_ADVANCE) + + unsigned char Stepper::old_OCR0A; + volatile unsigned char Stepper::eISR_Rate = 200; // Keep the ISR at a low rate until needed + + #if ENABLED(LIN_ADVANCE) + volatile int Stepper::e_steps[E_STEPPERS]; + int Stepper::extruder_advance_k = LIN_ADVANCE_K, + Stepper::final_estep_rate, + Stepper::current_estep_rate[E_STEPPERS], + Stepper::current_adv_steps[E_STEPPERS]; + #else + long Stepper::e_steps[E_STEPPERS], + Stepper::final_advance = 0, + Stepper::old_advance = 0, + Stepper::advance_rate, + Stepper::advance; + #endif +#endif + +long Stepper::acceleration_time, Stepper::deceleration_time; + +volatile long Stepper::count_position[NUM_AXIS] = { 0 }; +volatile signed char Stepper::count_direction[NUM_AXIS] = { 1, 1, 1, 1 }; + +#if ENABLED(MIXING_EXTRUDER) + long Stepper::counter_M[MIXING_STEPPERS]; +#endif + +unsigned short Stepper::acc_step_rate; // needed for deceleration start point +uint8_t Stepper::step_loops, Stepper::step_loops_nominal; +unsigned short Stepper::OCR1A_nominal; + +volatile long Stepper::endstops_trigsteps[3]; + +#if ENABLED(X_DUAL_STEPPER_DRIVERS) + #define X_APPLY_DIR(v,Q) do{ X_DIR_WRITE(v); X2_DIR_WRITE((v) != INVERT_X2_VS_X_DIR); }while(0) + #define X_APPLY_STEP(v,Q) do{ X_STEP_WRITE(v); X2_STEP_WRITE(v); }while(0) +#elif ENABLED(DUAL_X_CARRIAGE) + #define X_APPLY_DIR(v,ALWAYS) \ + if (extruder_duplication_enabled || ALWAYS) { \ + X_DIR_WRITE(v); \ + X2_DIR_WRITE(v); \ + } \ + else { \ + if (current_block->active_extruder) X2_DIR_WRITE(v); else X_DIR_WRITE(v); \ + } + #define X_APPLY_STEP(v,ALWAYS) \ + if (extruder_duplication_enabled || ALWAYS) { \ + X_STEP_WRITE(v); \ + X2_STEP_WRITE(v); \ + } \ + else { \ + if (current_block->active_extruder != 0) X2_STEP_WRITE(v); else X_STEP_WRITE(v); \ + } +#else + #define X_APPLY_DIR(v,Q) X_DIR_WRITE(v) + #define X_APPLY_STEP(v,Q) X_STEP_WRITE(v) +#endif + +#if ENABLED(Y_DUAL_STEPPER_DRIVERS) + #define Y_APPLY_DIR(v,Q) do{ Y_DIR_WRITE(v); Y2_DIR_WRITE((v) != INVERT_Y2_VS_Y_DIR); }while(0) + #define Y_APPLY_STEP(v,Q) do{ Y_STEP_WRITE(v); Y2_STEP_WRITE(v); }while(0) +#else + #define Y_APPLY_DIR(v,Q) Y_DIR_WRITE(v) + #define Y_APPLY_STEP(v,Q) Y_STEP_WRITE(v) +#endif + +#if ENABLED(Z_DUAL_STEPPER_DRIVERS) + #define Z_APPLY_DIR(v,Q) do{ Z_DIR_WRITE(v); Z2_DIR_WRITE(v); }while(0) + #if ENABLED(Z_DUAL_ENDSTOPS) + #define Z_APPLY_STEP(v,Q) \ + if (performing_homing) { \ + if (Z_HOME_DIR > 0) {\ + if (!(TEST(endstops.old_endstop_bits, Z_MAX) && (count_direction[Z_AXIS] > 0)) && !locked_z_motor) Z_STEP_WRITE(v); \ + if (!(TEST(endstops.old_endstop_bits, Z2_MAX) && (count_direction[Z_AXIS] > 0)) && !locked_z2_motor) Z2_STEP_WRITE(v); \ + } \ + else { \ + if (!(TEST(endstops.old_endstop_bits, Z_MIN) && (count_direction[Z_AXIS] < 0)) && !locked_z_motor) Z_STEP_WRITE(v); \ + if (!(TEST(endstops.old_endstop_bits, Z2_MIN) && (count_direction[Z_AXIS] < 0)) && !locked_z2_motor) Z2_STEP_WRITE(v); \ + } \ + } \ + else { \ + Z_STEP_WRITE(v); \ + Z2_STEP_WRITE(v); \ + } + #else + #define Z_APPLY_STEP(v,Q) do{ Z_STEP_WRITE(v); Z2_STEP_WRITE(v); }while(0) + #endif +#else + #define Z_APPLY_DIR(v,Q) Z_DIR_WRITE(v) + #define Z_APPLY_STEP(v,Q) Z_STEP_WRITE(v) +#endif + +#if DISABLED(MIXING_EXTRUDER) + #define E_APPLY_STEP(v,Q) E_STEP_WRITE(v) +#endif + +// intRes = longIn1 * longIn2 >> 24 +// uses: +// r26 to store 0 +// r27 to store bits 16-23 of the 48bit result. The top bit is used to round the two byte result. +// note that the lower two bytes and the upper byte of the 48bit result are not calculated. +// this can cause the result to be out by one as the lower bytes may cause carries into the upper ones. +// B0 A0 are bits 24-39 and are the returned value +// C1 B1 A1 is longIn1 +// D2 C2 B2 A2 is longIn2 +// +#define MultiU24X32toH16(intRes, longIn1, longIn2) \ + asm volatile ( \ + "clr r26 \n\t" \ + "mul %A1, %B2 \n\t" \ + "mov r27, r1 \n\t" \ + "mul %B1, %C2 \n\t" \ + "movw %A0, r0 \n\t" \ + "mul %C1, %C2 \n\t" \ + "add %B0, r0 \n\t" \ + "mul %C1, %B2 \n\t" \ + "add %A0, r0 \n\t" \ + "adc %B0, r1 \n\t" \ + "mul %A1, %C2 \n\t" \ + "add r27, r0 \n\t" \ + "adc %A0, r1 \n\t" \ + "adc %B0, r26 \n\t" \ + "mul %B1, %B2 \n\t" \ + "add r27, r0 \n\t" \ + "adc %A0, r1 \n\t" \ + "adc %B0, r26 \n\t" \ + "mul %C1, %A2 \n\t" \ + "add r27, r0 \n\t" \ + "adc %A0, r1 \n\t" \ + "adc %B0, r26 \n\t" \ + "mul %B1, %A2 \n\t" \ + "add r27, r1 \n\t" \ + "adc %A0, r26 \n\t" \ + "adc %B0, r26 \n\t" \ + "lsr r27 \n\t" \ + "adc %A0, r26 \n\t" \ + "adc %B0, r26 \n\t" \ + "mul %D2, %A1 \n\t" \ + "add %A0, r0 \n\t" \ + "adc %B0, r1 \n\t" \ + "mul %D2, %B1 \n\t" \ + "add %B0, r0 \n\t" \ + "clr r1 \n\t" \ + : \ + "=&r" (intRes) \ + : \ + "d" (longIn1), \ + "d" (longIn2) \ + : \ + "r26" , "r27" \ + ) + +// Some useful constants + +#define ENABLE_STEPPER_DRIVER_INTERRUPT() SBI(TIMSK1, OCIE1A) +#define DISABLE_STEPPER_DRIVER_INTERRUPT() CBI(TIMSK1, OCIE1A) + +/** + * __________________________ + * /| |\ _________________ ^ + * / | | \ /| |\ | + * / | | \ / | | \ s + * / | | | | | \ p + * / | | | | | \ e + * +-----+------------------------+---+--+---------------+----+ e + * | BLOCK 1 | BLOCK 2 | d + * + * time -----> + * + * The trapezoid is the shape the speed curve over time. It starts at block->initial_rate, accelerates + * first block->accelerate_until step_events_completed, then keeps going at constant speed until + * step_events_completed reaches block->decelerate_after after which it decelerates until the trapezoid generator is reset. + * The slope of acceleration is calculated using v = u + at where t is the accumulated timer values of the steps so far. + */ +void Stepper::wake_up() { + // TCNT1 = 0; + ENABLE_STEPPER_DRIVER_INTERRUPT(); +} + +/** + * Set the stepper direction of each axis + * + * COREXY: X_AXIS=A_AXIS and Y_AXIS=B_AXIS + * COREXZ: X_AXIS=A_AXIS and Z_AXIS=C_AXIS + * COREYZ: Y_AXIS=B_AXIS and Z_AXIS=C_AXIS + */ +void Stepper::set_directions() { + + #define SET_STEP_DIR(AXIS) \ + if (motor_direction(AXIS ##_AXIS)) { \ + AXIS ##_APPLY_DIR(INVERT_## AXIS ##_DIR, false); \ + count_direction[AXIS ##_AXIS] = -1; \ + } \ + else { \ + AXIS ##_APPLY_DIR(!INVERT_## AXIS ##_DIR, false); \ + count_direction[AXIS ##_AXIS] = 1; \ + } + + SET_STEP_DIR(X); // A + SET_STEP_DIR(Y); // B + SET_STEP_DIR(Z); // C + + #if DISABLED(ADVANCE) + if (motor_direction(E_AXIS)) { + REV_E_DIR(); + count_direction[E_AXIS] = -1; + } + else { + NORM_E_DIR(); + count_direction[E_AXIS] = 1; + } + #endif //!ADVANCE +} + +// "The Stepper Driver Interrupt" - This timer interrupt is the workhorse. +// It pops blocks from the block_buffer and executes them by pulsing the stepper pins appropriately. +ISR(TIMER1_COMPA_vect) { Stepper::isr(); } + +void Stepper::isr() { + if (cleaning_buffer_counter) { + current_block = NULL; + planner.discard_current_block(); + #ifdef SD_FINISHED_RELEASECOMMAND + if ((cleaning_buffer_counter == 1) && (SD_FINISHED_STEPPERRELEASE)) enqueue_and_echo_commands_P(PSTR(SD_FINISHED_RELEASECOMMAND)); + #endif + cleaning_buffer_counter--; + OCR1A = 200; + return; + } + + // If there is no current block, attempt to pop one from the buffer + if (!current_block) { + // Anything in the buffer? + current_block = planner.get_current_block(); + if (current_block) { + current_block->busy = true; + trapezoid_generator_reset(); + + // Initialize Bresenham counters to 1/2 the ceiling + counter_X = counter_Y = counter_Z = counter_E = -(current_block->step_event_count >> 1); + + #if ENABLED(MIXING_EXTRUDER) + MIXING_STEPPERS_LOOP(i) + counter_M[i] = -(current_block->mix_event_count[i] >> 1); + #endif + + step_events_completed = 0; + + #if ENABLED(Z_LATE_ENABLE) + if (current_block->steps[Z_AXIS] > 0) { + enable_z(); + OCR1A = 2000; //1ms wait + return; + } + #endif + + // #if ENABLED(ADVANCE) + // e_steps[TOOL_E_INDEX] = 0; + // #endif + } + else { + OCR1A = 2000; // 1kHz. + } + } + + if (current_block) { + + // Update endstops state, if enabled + if (endstops.enabled + #if HAS_BED_PROBE + || endstops.z_probe_enabled + #endif + ) endstops.update(); + + // Take multiple steps per interrupt (For high speed moves) + for (int8_t i = 0; i < step_loops; i++) { + #ifndef USBCON + customizedSerial.checkRx(); // Check for serial chars. + #endif + + #if ENABLED(LIN_ADVANCE) + + counter_E += current_block->steps[E_AXIS]; + if (counter_E > 0) { + counter_E -= current_block->step_event_count; + #if DISABLED(MIXING_EXTRUDER) + // Don't step E here for mixing extruder + count_position[E_AXIS] += count_direction[E_AXIS]; + e_steps[TOOL_E_INDEX] += motor_direction(E_AXIS) ? -1 : 1; + #endif + } + + #if ENABLED(MIXING_EXTRUDER) + // Step mixing steppers proportionally + long dir = motor_direction(E_AXIS) ? -1 : 1; + MIXING_STEPPERS_LOOP(j) { + counter_m[j] += current_block->steps[E_AXIS]; + if (counter_m[j] > 0) { + counter_m[j] -= current_block->mix_event_count[j]; + e_steps[j] += dir; + } + } + #endif + + if (current_block->use_advance_lead) { + int delta_adv_steps = (((long)extruder_advance_k * current_estep_rate[TOOL_E_INDEX]) >> 9) - current_adv_steps[TOOL_E_INDEX]; + #if ENABLED(MIXING_EXTRUDER) + // Mixing extruders apply advance lead proportionally + MIXING_STEPPERS_LOOP(j) { + int steps = delta_adv_steps * current_block->step_event_count / current_block->mix_event_count[j]; + e_steps[j] += steps; + current_adv_steps[j] += steps; + } + #else + // For most extruders, advance the single E stepper + e_steps[TOOL_E_INDEX] += delta_adv_steps; + current_adv_steps[TOOL_E_INDEX] += delta_adv_steps; + #endif + } + + #elif ENABLED(ADVANCE) + + // Always count the unified E axis + counter_E += current_block->steps[E_AXIS]; + if (counter_E > 0) { + counter_E -= current_block->step_event_count; + #if DISABLED(MIXING_EXTRUDER) + // Don't step E here for mixing extruder + e_steps[TOOL_E_INDEX] += motor_direction(E_AXIS) ? -1 : 1; + #endif + } + + #if ENABLED(MIXING_EXTRUDER) + + // Step mixing steppers proportionally + long dir = motor_direction(E_AXIS) ? -1 : 1; + MIXING_STEPPERS_LOOP(j) { + counter_m[j] += current_block->steps[E_AXIS]; + if (counter_m[j] > 0) { + counter_m[j] -= current_block->mix_event_count[j]; + e_steps[j] += dir; + } + } + + #endif // MIXING_EXTRUDER + + #endif // ADVANCE or LIN_ADVANCE + + #define _COUNTER(AXIS) counter_## AXIS + #define _APPLY_STEP(AXIS) AXIS ##_APPLY_STEP + #define _INVERT_STEP_PIN(AXIS) INVERT_## AXIS ##_STEP_PIN + + #define STEP_ADD(AXIS) \ + _COUNTER(AXIS) += current_block->steps[_AXIS(AXIS)]; \ + if (_COUNTER(AXIS) > 0) { _APPLY_STEP(AXIS)(!_INVERT_STEP_PIN(AXIS),0); } + + STEP_ADD(X); + STEP_ADD(Y); + STEP_ADD(Z); + + #if DISABLED(ADVANCE) && DISABLED(LIN_ADVANCE) + #if ENABLED(MIXING_EXTRUDER) + // Keep updating the single E axis + counter_E += current_block->steps[E_AXIS]; + // Tick the counters used for this mix + MIXING_STEPPERS_LOOP(j) { + // Step mixing steppers (proportionally) + counter_M[j] += current_block->steps[E_AXIS]; + // Step when the counter goes over zero + if (counter_M[j] > 0) En_STEP_WRITE(j, !INVERT_E_STEP_PIN); + } + #else // !MIXING_EXTRUDER + STEP_ADD(E); + #endif + #endif // !ADVANCE && !LIN_ADVANCE + + #define STEP_IF_COUNTER(AXIS) \ + if (_COUNTER(AXIS) > 0) { \ + _COUNTER(AXIS) -= current_block->step_event_count; \ + count_position[_AXIS(AXIS)] += count_direction[_AXIS(AXIS)]; \ + _APPLY_STEP(AXIS)(_INVERT_STEP_PIN(AXIS),0); \ + } + + STEP_IF_COUNTER(X); + STEP_IF_COUNTER(Y); + STEP_IF_COUNTER(Z); + + #if DISABLED(ADVANCE) && DISABLED(LIN_ADVANCE) + #if ENABLED(MIXING_EXTRUDER) + // Always step the single E axis + if (counter_E > 0) { + counter_E -= current_block->step_event_count; + count_position[E_AXIS] += count_direction[E_AXIS]; + } + MIXING_STEPPERS_LOOP(j) { + if (counter_M[j] > 0) { + counter_M[j] -= current_block->mix_event_count[j]; + En_STEP_WRITE(j, INVERT_E_STEP_PIN); + } + } + #else // !MIXING_EXTRUDER + STEP_IF_COUNTER(E); + #endif + #endif // !ADVANCE && !LIN_ADVANCE + + step_events_completed++; + if (step_events_completed >= current_block->step_event_count) break; + } + + #if ENABLED(ADVANCE) || ENABLED(LIN_ADVANCE) + // If we have esteps to execute, fire the next ISR "now" + if (e_steps[TOOL_E_INDEX]) OCR0A = TCNT0 + 2; + #endif + + // Calculate new timer value + unsigned short timer, step_rate; + if (step_events_completed <= (unsigned long)current_block->accelerate_until) { + + MultiU24X32toH16(acc_step_rate, acceleration_time, current_block->acceleration_rate); + acc_step_rate += current_block->initial_rate; + + // upper limit + NOMORE(acc_step_rate, current_block->nominal_rate); + + // step_rate to timer interval + timer = calc_timer(acc_step_rate); + OCR1A = timer; + acceleration_time += timer; + + #if ENABLED(LIN_ADVANCE) + + if (current_block->use_advance_lead) + current_estep_rate[TOOL_E_INDEX] = ((unsigned long)acc_step_rate * current_block->e_speed_multiplier8) >> 8; + + if (current_block->use_advance_lead) { + #if ENABLED(MIXING_EXTRUDER) + MIXING_STEPPERS_LOOP(j) + current_estep_rate[j] = ((unsigned long)acc_step_rate * current_block->e_speed_multiplier8 * current_block->step_event_count / current_block->mix_event_count[j]) >> 8; + #else + current_estep_rate[TOOL_E_INDEX] = ((unsigned long)acc_step_rate * current_block->e_speed_multiplier8) >> 8; + #endif + } + + #elif ENABLED(ADVANCE) + + advance += advance_rate * step_loops; + //NOLESS(advance, current_block->advance); + + long advance_whole = advance >> 8, + advance_factor = advance_whole - old_advance; + + // Do E steps + advance steps + #if ENABLED(MIXING_EXTRUDER) + // ...for mixing steppers proportionally + MIXING_STEPPERS_LOOP(j) + e_steps[j] += advance_factor * current_block->step_event_count / current_block->mix_event_count[j]; + #else + // ...for the active extruder + e_steps[TOOL_E_INDEX] += advance_factor; + #endif + + old_advance = advance_whole; + + #endif // ADVANCE or LIN_ADVANCE + + #if ENABLED(ADVANCE) || ENABLED(LIN_ADVANCE) + eISR_Rate = (timer >> 2) * step_loops / abs(e_steps[TOOL_E_INDEX]); + #endif + } + else if (step_events_completed > (unsigned long)current_block->decelerate_after) { + MultiU24X32toH16(step_rate, deceleration_time, current_block->acceleration_rate); + + if (step_rate <= acc_step_rate) { // Still decelerating? + step_rate = acc_step_rate - step_rate; + NOLESS(step_rate, current_block->final_rate); + } + else + step_rate = current_block->final_rate; + + // step_rate to timer interval + timer = calc_timer(step_rate); + OCR1A = timer; + deceleration_time += timer; + + #if ENABLED(LIN_ADVANCE) + + if (current_block->use_advance_lead) { + #if ENABLED(MIXING_EXTRUDER) + MIXING_STEPPERS_LOOP(j) + current_estep_rate[j] = ((unsigned long)step_rate * current_block->e_speed_multiplier8 * current_block->step_event_count / current_block->mix_event_count[j]) >> 8; + #else + current_estep_rate[TOOL_E_INDEX] = ((unsigned long)step_rate * current_block->e_speed_multiplier8) >> 8; + #endif + } + + #elif ENABLED(ADVANCE) + + advance -= advance_rate * step_loops; + NOLESS(advance, final_advance); + + // Do E steps + advance steps + long advance_whole = advance >> 8, + advance_factor = advance_whole - old_advance; + + #if ENABLED(MIXING_EXTRUDER) + MIXING_STEPPERS_LOOP(j) + e_steps[j] += advance_factor * current_block->step_event_count / current_block->mix_event_count[j]; + #else + e_steps[TOOL_E_INDEX] += advance_factor; + #endif + + old_advance = advance_whole; + + #endif // ADVANCE or LIN_ADVANCE + + #if ENABLED(ADVANCE) || ENABLED(LIN_ADVANCE) + eISR_Rate = (timer >> 2) * step_loops / abs(e_steps[TOOL_E_INDEX]); + #endif + } + else { + + #if ENABLED(LIN_ADVANCE) + + if (current_block->use_advance_lead) + current_estep_rate[TOOL_E_INDEX] = final_estep_rate; + + eISR_Rate = (OCR1A_nominal >> 2) * step_loops_nominal / abs(e_steps[TOOL_E_INDEX]); + + #endif + + OCR1A = OCR1A_nominal; + // ensure we're running at the correct step rate, even if we just came off an acceleration + step_loops = step_loops_nominal; + } + + OCR1A = (OCR1A < (TCNT1 + 16)) ? (TCNT1 + 16) : OCR1A; + + // If current block is finished, reset pointer + if (step_events_completed >= current_block->step_event_count) { + current_block = NULL; + planner.discard_current_block(); + } + } +} + +#if ENABLED(ADVANCE) || ENABLED(LIN_ADVANCE) + + // Timer interrupt for E. e_steps is set in the main routine; + // Timer 0 is shared with millies + ISR(TIMER0_COMPA_vect) { Stepper::advance_isr(); } + + void Stepper::advance_isr() { + + old_OCR0A += eISR_Rate; + OCR0A = old_OCR0A; + + #define STEP_E_ONCE(INDEX) \ + if (e_steps[INDEX] != 0) { \ + E## INDEX ##_STEP_WRITE(INVERT_E_STEP_PIN); \ + if (e_steps[INDEX] < 0) { \ + E## INDEX ##_DIR_WRITE(INVERT_E## INDEX ##_DIR); \ + e_steps[INDEX]++; \ + } \ + else { \ + E## INDEX ##_DIR_WRITE(!INVERT_E## INDEX ##_DIR); \ + e_steps[INDEX]--; \ + } \ + E## INDEX ##_STEP_WRITE(!INVERT_E_STEP_PIN); \ + } + + // Step all E steppers that have steps + for (uint8_t i = 0; i < step_loops; i++) { + STEP_E_ONCE(0); + #if E_STEPPERS > 1 + STEP_E_ONCE(1); + #if E_STEPPERS > 2 + STEP_E_ONCE(2); + #if E_STEPPERS > 3 + STEP_E_ONCE(3); + #endif + #endif + #endif + } + + } + +#endif // ADVANCE or LIN_ADVANCE + +void Stepper::init() { + + digipot_init(); //Initialize Digipot Motor Current + microstep_init(); //Initialize Microstepping Pins + + // initialise TMC Steppers + #if ENABLED(HAVE_TMCDRIVER) + tmc_init(); + #endif + // initialise L6470 Steppers + #if ENABLED(HAVE_L6470DRIVER) + L6470_init(); + #endif + + // Initialize Dir Pins + #if HAS_X_DIR + X_DIR_INIT; + #endif + #if HAS_X2_DIR + X2_DIR_INIT; + #endif + #if HAS_Y_DIR + Y_DIR_INIT; + #if ENABLED(Y_DUAL_STEPPER_DRIVERS) && HAS_Y2_DIR + Y2_DIR_INIT; + #endif + #endif + #if HAS_Z_DIR + Z_DIR_INIT; + #if ENABLED(Z_DUAL_STEPPER_DRIVERS) && HAS_Z2_DIR + Z2_DIR_INIT; + #endif + #endif + #if HAS_E0_DIR + E0_DIR_INIT; + #endif + #if HAS_E1_DIR + E1_DIR_INIT; + #endif + #if HAS_E2_DIR + E2_DIR_INIT; + #endif + #if HAS_E3_DIR + E3_DIR_INIT; + #endif + + //Initialize Enable Pins - steppers default to disabled. + + #if HAS_X_ENABLE + X_ENABLE_INIT; + if (!X_ENABLE_ON) X_ENABLE_WRITE(HIGH); + #if ENABLED(DUAL_X_CARRIAGE) && HAS_X2_ENABLE + X2_ENABLE_INIT; + if (!X_ENABLE_ON) X2_ENABLE_WRITE(HIGH); + #endif + #endif + + #if HAS_Y_ENABLE + Y_ENABLE_INIT; + if (!Y_ENABLE_ON) Y_ENABLE_WRITE(HIGH); + #if ENABLED(Y_DUAL_STEPPER_DRIVERS) && HAS_Y2_ENABLE + Y2_ENABLE_INIT; + if (!Y_ENABLE_ON) Y2_ENABLE_WRITE(HIGH); + #endif + #endif + + #if HAS_Z_ENABLE + Z_ENABLE_INIT; + if (!Z_ENABLE_ON) Z_ENABLE_WRITE(HIGH); + #if ENABLED(Z_DUAL_STEPPER_DRIVERS) && HAS_Z2_ENABLE + Z2_ENABLE_INIT; + if (!Z_ENABLE_ON) Z2_ENABLE_WRITE(HIGH); + #endif + #endif + + #if HAS_E0_ENABLE + E0_ENABLE_INIT; + if (!E_ENABLE_ON) E0_ENABLE_WRITE(HIGH); + #endif + #if HAS_E1_ENABLE + E1_ENABLE_INIT; + if (!E_ENABLE_ON) E1_ENABLE_WRITE(HIGH); + #endif + #if HAS_E2_ENABLE + E2_ENABLE_INIT; + if (!E_ENABLE_ON) E2_ENABLE_WRITE(HIGH); + #endif + #if HAS_E3_ENABLE + E3_ENABLE_INIT; + if (!E_ENABLE_ON) E3_ENABLE_WRITE(HIGH); + #endif + + // + // Init endstops and pullups here + // + endstops.init(); + + #define _STEP_INIT(AXIS) AXIS ##_STEP_INIT + #define _WRITE_STEP(AXIS, HIGHLOW) AXIS ##_STEP_WRITE(HIGHLOW) + #define _DISABLE(axis) disable_## axis() + + #define AXIS_INIT(axis, AXIS, PIN) \ + _STEP_INIT(AXIS); \ + _WRITE_STEP(AXIS, _INVERT_STEP_PIN(PIN)); \ + _DISABLE(axis) + + #define E_AXIS_INIT(NUM) AXIS_INIT(e## NUM, E## NUM, E) + + // Initialize Step Pins + #if HAS_X_STEP + #if ENABLED(X_DUAL_STEPPER_DRIVERS) || ENABLED(DUAL_X_CARRIAGE) + X2_STEP_INIT; + X2_STEP_WRITE(INVERT_X_STEP_PIN); + #endif + AXIS_INIT(x, X, X); + #endif + + #if HAS_Y_STEP + #if ENABLED(Y_DUAL_STEPPER_DRIVERS) + Y2_STEP_INIT; + Y2_STEP_WRITE(INVERT_Y_STEP_PIN); + #endif + AXIS_INIT(y, Y, Y); + #endif + + #if HAS_Z_STEP + #if ENABLED(Z_DUAL_STEPPER_DRIVERS) + Z2_STEP_INIT; + Z2_STEP_WRITE(INVERT_Z_STEP_PIN); + #endif + AXIS_INIT(z, Z, Z); + #endif + + #if HAS_E0_STEP + E_AXIS_INIT(0); + #endif + #if HAS_E1_STEP + E_AXIS_INIT(1); + #endif + #if HAS_E2_STEP + E_AXIS_INIT(2); + #endif + #if HAS_E3_STEP + E_AXIS_INIT(3); + #endif + + // waveform generation = 0100 = CTC + CBI(TCCR1B, WGM13); + SBI(TCCR1B, WGM12); + CBI(TCCR1A, WGM11); + CBI(TCCR1A, WGM10); + + // output mode = 00 (disconnected) + TCCR1A &= ~(3 << COM1A0); + TCCR1A &= ~(3 << COM1B0); + // Set the timer pre-scaler + // Generally we use a divider of 8, resulting in a 2MHz timer + // frequency on a 16MHz MCU. If you are going to change this, be + // sure to regenerate speed_lookuptable.h with + // create_speed_lookuptable.py + TCCR1B = (TCCR1B & ~(0x07 << CS10)) | (2 << CS10); + + OCR1A = 0x4000; + TCNT1 = 0; + ENABLE_STEPPER_DRIVER_INTERRUPT(); + + #if ENABLED(ADVANCE) || ENABLED(LIN_ADVANCE) + + for (int i = 0; i < E_STEPPERS; i++) { + e_steps[i] = 0; + #if ENABLED(LIN_ADVANCE) + current_adv_steps[i] = 0; + #endif + } + + #if defined(TCCR0A) && defined(WGM01) + CBI(TCCR0A, WGM01); + CBI(TCCR0A, WGM00); + #endif + SBI(TIMSK0, OCIE0A); + + #endif // ADVANCE or LIN_ADVANCE + + endstops.enable(true); // Start with endstops active. After homing they can be disabled + sei(); + + set_directions(); // Init directions to last_direction_bits = 0 +} + + +/** + * Block until all buffered steps are executed + */ +void Stepper::synchronize() { while (planner.blocks_queued()) idle(); } + +/** + * Set the stepper positions directly in steps + * + * The input is based on the typical per-axis XYZ steps. + * For CORE machines XYZ needs to be translated to ABC. + * + * This allows get_axis_position_mm to correctly + * derive the current XYZ position later on. + */ +void Stepper::set_position(const long& x, const long& y, const long& z, const long& e) { + CRITICAL_SECTION_START; + + #if ENABLED(COREXY) + // corexy positioning + // these equations follow the form of the dA and dB equations on http://www.corexy.com/theory.html + count_position[A_AXIS] = x + y; + count_position[B_AXIS] = x - y; + count_position[Z_AXIS] = z; + #elif ENABLED(COREXZ) + // corexz planning + count_position[A_AXIS] = x + z; + count_position[Y_AXIS] = y; + count_position[C_AXIS] = x - z; + #elif ENABLED(COREYZ) + // coreyz planning + count_position[X_AXIS] = x; + count_position[B_AXIS] = y + z; + count_position[C_AXIS] = y - z; + #else + // default non-h-bot planning + count_position[X_AXIS] = x; + count_position[Y_AXIS] = y; + count_position[Z_AXIS] = z; + #endif + + count_position[E_AXIS] = e; + CRITICAL_SECTION_END; +} + +void Stepper::set_e_position(const long& e) { + CRITICAL_SECTION_START; + count_position[E_AXIS] = e; + CRITICAL_SECTION_END; +} + +/** + * Get a stepper's position in steps. + */ +long Stepper::position(AxisEnum axis) { + CRITICAL_SECTION_START; + long count_pos = count_position[axis]; + CRITICAL_SECTION_END; + return count_pos; +} + +/** + * Get an axis position according to stepper position(s) + * For CORE machines apply translation from ABC to XYZ. + */ +float Stepper::get_axis_position_mm(AxisEnum axis) { + float axis_steps; + #if ENABLED(COREXY) || ENABLED(COREXZ) || ENABLED(COREYZ) + // Requesting one of the "core" axes? + if (axis == CORE_AXIS_1 || axis == CORE_AXIS_2) { + CRITICAL_SECTION_START; + long pos1 = count_position[CORE_AXIS_1], + pos2 = count_position[CORE_AXIS_2]; + CRITICAL_SECTION_END; + // ((a1+a2)+(a1-a2))/2 -> (a1+a2+a1-a2)/2 -> (a1+a1)/2 -> a1 + // ((a1+a2)-(a1-a2))/2 -> (a1+a2-a1+a2)/2 -> (a2+a2)/2 -> a2 + axis_steps = (pos1 + ((axis == CORE_AXIS_1) ? pos2 : -pos2)) * 0.5f; + } + else + axis_steps = position(axis); + #else + axis_steps = position(axis); + #endif + return axis_steps * planner.steps_to_mm[axis]; +} + +void Stepper::finish_and_disable() { + synchronize(); + disable_all_steppers(); +} + +void Stepper::quick_stop() { + cleaning_buffer_counter = 5000; + DISABLE_STEPPER_DRIVER_INTERRUPT(); + while (planner.blocks_queued()) planner.discard_current_block(); + current_block = NULL; + ENABLE_STEPPER_DRIVER_INTERRUPT(); +} + +void Stepper::endstop_triggered(AxisEnum axis) { + + #if ENABLED(COREXY) || ENABLED(COREXZ) || ENABLED(COREYZ) + + float axis_pos = count_position[axis]; + if (axis == CORE_AXIS_1) + axis_pos = (axis_pos + count_position[CORE_AXIS_2]) * 0.5; + else if (axis == CORE_AXIS_2) + axis_pos = (count_position[CORE_AXIS_1] - axis_pos) * 0.5; + endstops_trigsteps[axis] = axis_pos; + + #else // !COREXY && !COREXZ && !COREYZ + + endstops_trigsteps[axis] = count_position[axis]; + + #endif // !COREXY && !COREXZ && !COREYZ + + kill_current_block(); +} + +void Stepper::report_positions() { + CRITICAL_SECTION_START; + long xpos = count_position[X_AXIS], + ypos = count_position[Y_AXIS], + zpos = count_position[Z_AXIS]; + CRITICAL_SECTION_END; + + #if ENABLED(COREXY) || ENABLED(COREXZ) + SERIAL_PROTOCOLPGM(MSG_COUNT_A); + #else + SERIAL_PROTOCOLPGM(MSG_COUNT_X); + #endif + SERIAL_PROTOCOL(xpos); + + #if ENABLED(COREXY) || ENABLED(COREYZ) + SERIAL_PROTOCOLPGM(" B:"); + #else + SERIAL_PROTOCOLPGM(" Y:"); + #endif + SERIAL_PROTOCOL(ypos); + + #if ENABLED(COREXZ) || ENABLED(COREYZ) + SERIAL_PROTOCOLPGM(" C:"); + #else + SERIAL_PROTOCOLPGM(" Z:"); + #endif + SERIAL_PROTOCOL(zpos); + + SERIAL_EOL; +} + +#if ENABLED(BABYSTEPPING) + + // MUST ONLY BE CALLED BY AN ISR, + // No other ISR should ever interrupt this! + void Stepper::babystep(const uint8_t axis, const bool direction) { + + #define _ENABLE(axis) enable_## axis() + #define _READ_DIR(AXIS) AXIS ##_DIR_READ + #define _INVERT_DIR(AXIS) INVERT_## AXIS ##_DIR + #define _APPLY_DIR(AXIS, INVERT) AXIS ##_APPLY_DIR(INVERT, true) + + #define BABYSTEP_AXIS(axis, AXIS, INVERT) { \ + _ENABLE(axis); \ + uint8_t old_pin = _READ_DIR(AXIS); \ + _APPLY_DIR(AXIS, _INVERT_DIR(AXIS)^direction^INVERT); \ + _APPLY_STEP(AXIS)(!_INVERT_STEP_PIN(AXIS), true); \ + delayMicroseconds(2); \ + _APPLY_STEP(AXIS)(_INVERT_STEP_PIN(AXIS), true); \ + _APPLY_DIR(AXIS, old_pin); \ + } + + switch (axis) { + + case X_AXIS: + BABYSTEP_AXIS(x, X, false); + break; + + case Y_AXIS: + BABYSTEP_AXIS(y, Y, false); + break; + + case Z_AXIS: { + + #if DISABLED(DELTA) + + BABYSTEP_AXIS(z, Z, BABYSTEP_INVERT_Z); + + #else // DELTA + + bool z_direction = direction ^ BABYSTEP_INVERT_Z; + + enable_x(); + enable_y(); + enable_z(); + uint8_t old_x_dir_pin = X_DIR_READ, + old_y_dir_pin = Y_DIR_READ, + old_z_dir_pin = Z_DIR_READ; + //setup new step + X_DIR_WRITE(INVERT_X_DIR ^ z_direction); + Y_DIR_WRITE(INVERT_Y_DIR ^ z_direction); + Z_DIR_WRITE(INVERT_Z_DIR ^ z_direction); + //perform step + X_STEP_WRITE(!INVERT_X_STEP_PIN); + Y_STEP_WRITE(!INVERT_Y_STEP_PIN); + Z_STEP_WRITE(!INVERT_Z_STEP_PIN); + delayMicroseconds(2); + X_STEP_WRITE(INVERT_X_STEP_PIN); + Y_STEP_WRITE(INVERT_Y_STEP_PIN); + Z_STEP_WRITE(INVERT_Z_STEP_PIN); + //get old pin state back. + X_DIR_WRITE(old_x_dir_pin); + Y_DIR_WRITE(old_y_dir_pin); + Z_DIR_WRITE(old_z_dir_pin); + + #endif + + } break; + + default: break; + } + } + +#endif //BABYSTEPPING + +/** + * Software-controlled Stepper Motor Current + */ + +#if HAS_DIGIPOTSS + + // From Arduino DigitalPotControl example + void Stepper::digitalPotWrite(int address, int value) { + digitalWrite(DIGIPOTSS_PIN, LOW); // take the SS pin low to select the chip + SPI.transfer(address); // send in the address and value via SPI: + SPI.transfer(value); + digitalWrite(DIGIPOTSS_PIN, HIGH); // take the SS pin high to de-select the chip: + //delay(10); + } + +#endif //HAS_DIGIPOTSS + +void Stepper::digipot_init() { + #if HAS_DIGIPOTSS + const uint8_t digipot_motor_current[] = DIGIPOT_MOTOR_CURRENT; + + SPI.begin(); + pinMode(DIGIPOTSS_PIN, OUTPUT); + 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]); + } + #endif + #if HAS_MOTOR_CURRENT_PWM + #if PIN_EXISTS(MOTOR_CURRENT_PWM_XY) + pinMode(MOTOR_CURRENT_PWM_XY_PIN, OUTPUT); + digipot_current(0, motor_current_setting[0]); + #endif + #if PIN_EXISTS(MOTOR_CURRENT_PWM_Z) + pinMode(MOTOR_CURRENT_PWM_Z_PIN, OUTPUT); + digipot_current(1, motor_current_setting[1]); + #endif + #if PIN_EXISTS(MOTOR_CURRENT_PWM_E) + pinMode(MOTOR_CURRENT_PWM_E_PIN, OUTPUT); + digipot_current(2, motor_current_setting[2]); + #endif + //Set timer5 to 31khz so the PWM of the motor power is as constant as possible. (removes a buzzing noise) + TCCR5B = (TCCR5B & ~(_BV(CS50) | _BV(CS51) | _BV(CS52))) | _BV(CS50); + #endif +} + +void Stepper::digipot_current(uint8_t driver, int current) { + #if HAS_DIGIPOTSS + const uint8_t digipot_ch[] = DIGIPOT_CHANNELS; + digitalPotWrite(digipot_ch[driver], current); + #elif HAS_MOTOR_CURRENT_PWM + #define _WRITE_CURRENT_PWM(P) analogWrite(P, 255L * current / (MOTOR_CURRENT_PWM_RANGE)) + switch (driver) { + #if PIN_EXISTS(MOTOR_CURRENT_PWM_XY) + case 0: _WRITE_CURRENT_PWM(MOTOR_CURRENT_PWM_XY_PIN); break; + #endif + #if PIN_EXISTS(MOTOR_CURRENT_PWM_Z) + case 1: _WRITE_CURRENT_PWM(MOTOR_CURRENT_PWM_Z_PIN); break; + #endif + #if PIN_EXISTS(MOTOR_CURRENT_PWM_E) + case 2: _WRITE_CURRENT_PWM(MOTOR_CURRENT_PWM_E_PIN); break; + #endif + } + #else + UNUSED(driver); + UNUSED(current); + #endif +} + +void Stepper::microstep_init() { + #if HAS_MICROSTEPS_E1 + pinMode(E1_MS1_PIN, OUTPUT); + pinMode(E1_MS2_PIN, OUTPUT); + #endif + + #if HAS_MICROSTEPS + pinMode(X_MS1_PIN, OUTPUT); + pinMode(X_MS2_PIN, OUTPUT); + pinMode(Y_MS1_PIN, OUTPUT); + pinMode(Y_MS2_PIN, OUTPUT); + pinMode(Z_MS1_PIN, OUTPUT); + pinMode(Z_MS2_PIN, OUTPUT); + pinMode(E0_MS1_PIN, OUTPUT); + pinMode(E0_MS2_PIN, OUTPUT); + const uint8_t microstep_modes[] = MICROSTEP_MODES; + for (uint16_t i = 0; i < COUNT(microstep_modes); i++) + microstep_mode(i, microstep_modes[i]); + #endif +} + +/** + * Software-controlled Microstepping + */ + +void Stepper::microstep_ms(uint8_t driver, int8_t ms1, int8_t ms2) { + if (ms1 >= 0) switch (driver) { + case 0: digitalWrite(X_MS1_PIN, ms1); break; + case 1: digitalWrite(Y_MS1_PIN, ms1); break; + case 2: digitalWrite(Z_MS1_PIN, ms1); break; + case 3: digitalWrite(E0_MS1_PIN, ms1); break; + #if HAS_MICROSTEPS_E1 + case 4: digitalWrite(E1_MS1_PIN, ms1); break; + #endif + } + if (ms2 >= 0) switch (driver) { + case 0: digitalWrite(X_MS2_PIN, ms2); break; + case 1: digitalWrite(Y_MS2_PIN, ms2); break; + case 2: digitalWrite(Z_MS2_PIN, ms2); break; + case 3: digitalWrite(E0_MS2_PIN, ms2); break; + #if PIN_EXISTS(E1_MS2) + case 4: digitalWrite(E1_MS2_PIN, ms2); break; + #endif + } +} + +void Stepper::microstep_mode(uint8_t driver, uint8_t stepping_mode) { + switch (stepping_mode) { + case 1: microstep_ms(driver, MICROSTEP1); break; + case 2: microstep_ms(driver, MICROSTEP2); break; + case 4: microstep_ms(driver, MICROSTEP4); break; + case 8: microstep_ms(driver, MICROSTEP8); break; + case 16: microstep_ms(driver, MICROSTEP16); break; + } +} + +void Stepper::microstep_readings() { + SERIAL_PROTOCOLLNPGM("MS1,MS2 Pins"); + SERIAL_PROTOCOLPGM("X: "); + SERIAL_PROTOCOL(digitalRead(X_MS1_PIN)); + SERIAL_PROTOCOLLN(digitalRead(X_MS2_PIN)); + SERIAL_PROTOCOLPGM("Y: "); + SERIAL_PROTOCOL(digitalRead(Y_MS1_PIN)); + SERIAL_PROTOCOLLN(digitalRead(Y_MS2_PIN)); + SERIAL_PROTOCOLPGM("Z: "); + SERIAL_PROTOCOL(digitalRead(Z_MS1_PIN)); + SERIAL_PROTOCOLLN(digitalRead(Z_MS2_PIN)); + SERIAL_PROTOCOLPGM("E0: "); + SERIAL_PROTOCOL(digitalRead(E0_MS1_PIN)); + SERIAL_PROTOCOLLN(digitalRead(E0_MS2_PIN)); + #if HAS_MICROSTEPS_E1 + SERIAL_PROTOCOLPGM("E1: "); + SERIAL_PROTOCOL(digitalRead(E1_MS1_PIN)); + SERIAL_PROTOCOLLN(digitalRead(E1_MS2_PIN)); + #endif +} + +#if ENABLED(LIN_ADVANCE) + + void Stepper::advance_M905(const float &k) { + if (k >= 0) extruder_advance_k = k; + SERIAL_ECHO_START; + SERIAL_ECHOPAIR("Advance factor: ", extruder_advance_k); + SERIAL_EOL; + } + +#endif // LIN_ADVANCE diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/stepper.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/stepper.h new file mode 100644 index 00000000..1dd1531e --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/stepper.h @@ -0,0 +1,380 @@ +/** + * 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 . + * + */ + +/** + * stepper.h - stepper motor driver: executes motion plans of planner.c using the stepper motors + * Derived from Grbl + * + * Copyright (c) 2009-2011 Simen Svale Skogsrud + * + * Grbl is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Grbl is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * 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 . + */ + +#ifndef STEPPER_H +#define STEPPER_H + +#include "planner.h" +#include "speed_lookuptable.h" +#include "stepper_indirection.h" +#include "language.h" +#include "types.h" + +class Stepper; +extern Stepper stepper; + +// intRes = intIn1 * intIn2 >> 16 +// uses: +// r26 to store 0 +// r27 to store the byte 1 of the 24 bit result +#define MultiU16X8toH16(intRes, charIn1, intIn2) \ + asm volatile ( \ + "clr r26 \n\t" \ + "mul %A1, %B2 \n\t" \ + "movw %A0, r0 \n\t" \ + "mul %A1, %A2 \n\t" \ + "add %A0, r1 \n\t" \ + "adc %B0, r26 \n\t" \ + "lsr r0 \n\t" \ + "adc %A0, r26 \n\t" \ + "adc %B0, r26 \n\t" \ + "clr r1 \n\t" \ + : \ + "=&r" (intRes) \ + : \ + "d" (charIn1), \ + "d" (intIn2) \ + : \ + "r26" \ + ) + +class Stepper { + + public: + + static block_t* current_block; // A pointer to the block currently being traced + + #if ENABLED(ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED) + static bool abort_on_endstop_hit; + #endif + + #if ENABLED(Z_DUAL_ENDSTOPS) + static bool performing_homing; + #endif + + private: + + static unsigned char last_direction_bits; // The next stepping-bits to be output + static unsigned int cleaning_buffer_counter; + + #if ENABLED(Z_DUAL_ENDSTOPS) + static bool locked_z_motor, locked_z2_motor; + #endif + + // Counter variables for the Bresenham line tracer + static long counter_X, counter_Y, counter_Z, counter_E; + static volatile unsigned long step_events_completed; // The number of step events executed in the current block + + #if ENABLED(ADVANCE) || ENABLED(LIN_ADVANCE) + static unsigned char old_OCR0A; + static volatile unsigned char eISR_Rate; + #if ENABLED(LIN_ADVANCE) + static volatile int e_steps[E_STEPPERS]; + static int extruder_advance_k; + static int final_estep_rate; + static int current_estep_rate[E_STEPPERS]; // Actual extruder speed [steps/s] + static int current_adv_steps[E_STEPPERS]; // The amount of current added esteps due to advance. + // i.e., the current amount of pressure applied + // to the spring (=filament). + #else + static long e_steps[E_STEPPERS]; + static long advance_rate, advance, final_advance; + static long old_advance; + #endif + #endif // ADVANCE or LIN_ADVANCE + + static long acceleration_time, deceleration_time; + //unsigned long accelerate_until, decelerate_after, acceleration_rate, initial_rate, final_rate, nominal_rate; + static unsigned short acc_step_rate; // needed for deceleration start point + static uint8_t step_loops, step_loops_nominal; + static unsigned short OCR1A_nominal; + + static volatile long endstops_trigsteps[3]; + static volatile long endstops_stepsTotal, endstops_stepsDone; + + #if HAS_MOTOR_CURRENT_PWM + #ifndef PWM_MOTOR_CURRENT + #define PWM_MOTOR_CURRENT DEFAULT_PWM_MOTOR_CURRENT + #endif + static constexpr int motor_current_setting[3] = PWM_MOTOR_CURRENT; + #endif + + // + // Positions of stepper motors, in step units + // + static volatile long count_position[NUM_AXIS]; + + // + // Current direction of stepper motors (+1 or -1) + // + static volatile signed char count_direction[NUM_AXIS]; + + // + // Mixing extruder mix counters + // + #if ENABLED(MIXING_EXTRUDER) + static long counter_M[MIXING_STEPPERS]; + #define MIXING_STEPPERS_LOOP(VAR) \ + for (uint8_t VAR = 0; VAR < MIXING_STEPPERS; VAR++) \ + if (current_block->mix_event_count[VAR]) + #endif + + public: + + // + // Constructor / initializer + // + Stepper() { }; + + // + // Initialize stepper hardware + // + static void init(); + + // + // Interrupt Service Routines + // + + static void isr(); + + #if ENABLED(ADVANCE) || ENABLED(LIN_ADVANCE) + static void advance_isr(); + #endif + + // + // Block until all buffered steps are executed + // + static void synchronize(); + + // + // Set the current position in steps + // + static void set_position(const long& x, const long& y, const long& z, const long& e); + static void set_e_position(const long& e); + + // + // Set direction bits for all steppers + // + static void set_directions(); + + // + // Get the position of a stepper, in steps + // + static long position(AxisEnum axis); + + // + // Report the positions of the steppers, in steps + // + static void report_positions(); + + // + // Get the position (mm) of an axis based on stepper position(s) + // + static float get_axis_position_mm(AxisEnum axis); + + // + // The stepper subsystem goes to sleep when it runs out of things to execute. Call this + // to notify the subsystem that it is time to go to work. + // + static void wake_up(); + + // + // Wait for moves to finish and disable all steppers + // + static void finish_and_disable(); + + // + // Quickly stop all steppers and clear the blocks queue + // + static void quick_stop(); + + // + // The direction of a single motor + // + static FORCE_INLINE bool motor_direction(AxisEnum axis) { return TEST(last_direction_bits, axis); } + + #if HAS_DIGIPOTSS + static void digitalPotWrite(int address, int value); + #endif + static void microstep_ms(uint8_t driver, int8_t ms1, int8_t ms2); + static void digipot_current(uint8_t driver, int current); + static void microstep_mode(uint8_t driver, uint8_t stepping); + static void microstep_readings(); + + #if ENABLED(Z_DUAL_ENDSTOPS) + static FORCE_INLINE void set_homing_flag(bool state) { performing_homing = state; } + static FORCE_INLINE void set_z_lock(bool state) { locked_z_motor = state; } + static FORCE_INLINE void set_z2_lock(bool state) { locked_z2_motor = state; } + #endif + + #if ENABLED(BABYSTEPPING) + static void babystep(const uint8_t axis, const bool direction); // perform a short step with a single stepper motor, outside of any convention + #endif + + static inline void kill_current_block() { + step_events_completed = current_block->step_event_count; + } + + // + // Handle a triggered endstop + // + static void endstop_triggered(AxisEnum axis); + + // + // Triggered position of an axis in mm (not core-savvy) + // + static FORCE_INLINE float triggered_position_mm(AxisEnum axis) { + return endstops_trigsteps[axis] * planner.steps_to_mm[axis]; + } + + #if ENABLED(LIN_ADVANCE) + void advance_M905(const float &k); + FORCE_INLINE int get_advance_k() { return extruder_advance_k; } + #endif + + private: + + static FORCE_INLINE unsigned short calc_timer(unsigned short step_rate) { + unsigned short timer; + + NOMORE(step_rate, MAX_STEP_FREQUENCY); + + if (step_rate > 20000) { // If steprate > 20kHz >> step 4 times + step_rate >>= 2; + step_loops = 4; + } + else if (step_rate > 10000) { // If steprate > 10kHz >> step 2 times + step_rate >>= 1; + step_loops = 2; + } + else { + step_loops = 1; + } + + NOLESS(step_rate, F_CPU / 500000); + step_rate -= F_CPU / 500000; // Correct for minimal speed + if (step_rate >= (8 * 256)) { // higher step rate + unsigned short table_address = (unsigned short)&speed_lookuptable_fast[(unsigned char)(step_rate >> 8)][0]; + unsigned char tmp_step_rate = (step_rate & 0x00ff); + unsigned short gain = (unsigned short)pgm_read_word_near(table_address + 2); + MultiU16X8toH16(timer, tmp_step_rate, gain); + timer = (unsigned short)pgm_read_word_near(table_address) - timer; + } + else { // lower step rates + unsigned short table_address = (unsigned short)&speed_lookuptable_slow[0][0]; + table_address += ((step_rate) >> 1) & 0xfffc; + timer = (unsigned short)pgm_read_word_near(table_address); + timer -= (((unsigned short)pgm_read_word_near(table_address + 2) * (unsigned char)(step_rate & 0x0007)) >> 3); + } + if (timer < 100) { // (20kHz - this should never happen) + timer = 100; + MYSERIAL.print(MSG_STEPPER_TOO_HIGH); + MYSERIAL.println(step_rate); + } + return timer; + } + + // Initializes the trapezoid generator from the current block. Called whenever a new + // block begins. + static FORCE_INLINE void trapezoid_generator_reset() { + + static int8_t last_extruder = -1; + + if (current_block->direction_bits != last_direction_bits || current_block->active_extruder != last_extruder) { + last_direction_bits = current_block->direction_bits; + last_extruder = current_block->active_extruder; + set_directions(); + } + + #if ENABLED(ADVANCE) + + advance = current_block->initial_advance; + final_advance = current_block->final_advance; + + // Do E steps + advance steps + #if ENABLED(MIXING_EXTRUDER) + long advance_factor = (advance >> 8) - old_advance; + // ...for mixing steppers proportionally + MIXING_STEPPERS_LOOP(j) + e_steps[j] += advance_factor * current_block->step_event_count / current_block->mix_event_count[j]; + #else + // ...for the active extruder + e_steps[TOOL_E_INDEX] += ((advance >> 8) - old_advance); + #endif + + old_advance = advance >> 8; + + #endif + + deceleration_time = 0; + // step_rate to timer interval + OCR1A_nominal = calc_timer(current_block->nominal_rate); + // make a note of the number of step loops required at nominal speed + step_loops_nominal = step_loops; + acc_step_rate = current_block->initial_rate; + acceleration_time = calc_timer(acc_step_rate); + OCR1A = acceleration_time; + + #if ENABLED(LIN_ADVANCE) + if (current_block->use_advance_lead) { + current_estep_rate[current_block->active_extruder] = ((unsigned long)acc_step_rate * current_block->e_speed_multiplier8) >> 8; + final_estep_rate = (current_block->nominal_rate * current_block->e_speed_multiplier8) >> 8; + } + #endif + + // SERIAL_ECHO_START; + // SERIAL_ECHOPGM("advance :"); + // SERIAL_ECHO(current_block->advance/256.0); + // SERIAL_ECHOPGM("advance rate :"); + // SERIAL_ECHO(current_block->advance_rate/256.0); + // SERIAL_ECHOPGM("initial advance :"); + // SERIAL_ECHO(current_block->initial_advance/256.0); + // SERIAL_ECHOPGM("final advance :"); + // SERIAL_ECHOLN(current_block->final_advance/256.0); + } + + static void digipot_init(); + static void microstep_init(); + +}; + +#endif // STEPPER_H \ No newline at end of file diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/stepper_dac.cpp b/trunk/Arduino/Marlin_K8600_1.1.0RC7/stepper_dac.cpp new file mode 100644 index 00000000..6c71b89f --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/stepper_dac.cpp @@ -0,0 +1,114 @@ +/** + * 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 . + * + */ + +/** + stepper_dac.cpp - To set stepper current via DAC + + Part of Marlin + + Copyright (c) 2016 MarlinFirmware + + Marlin is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Marlin is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Marlin. If not, see . +*/ + +#include "Marlin.h" + +#if ENABLED(DAC_STEPPER_CURRENT) + + #include "stepper_dac.h" + + bool dac_present = false; + const uint8_t dac_order[NUM_AXIS] = DAC_STEPPER_ORDER; + + int dac_init() { + #if PIN_EXISTS(DAC_DISABLE) + pinMode(DAC_DISABLE_PIN, OUTPUT); + digitalWrite(DAC_DISABLE_PIN, LOW); // set pin low to enable DAC + #endif + + mcp4728_init(); + + if (mcp4728_simpleCommand(RESET)) return -1; + + dac_present = true; + + mcp4728_setVref_all(DAC_STEPPER_VREF); + mcp4728_setGain_all(DAC_STEPPER_GAIN); + + return 0; + } + + void dac_current_percent(uint8_t channel, float val) { + if (!dac_present) return; + + NOMORE(val, 100); + + mcp4728_analogWrite(dac_order[channel], val * DAC_STEPPER_MAX / 100); + mcp4728_simpleCommand(UPDATE); + } + + void dac_current_raw(uint8_t channel, uint16_t val) { + if (!dac_present) return; + + NOMORE(val, DAC_STEPPER_MAX); + + mcp4728_analogWrite(dac_order[channel], val); + mcp4728_simpleCommand(UPDATE); + } + + static float dac_perc(int8_t n) { return 100.0 * mcp4728_getValue(dac_order[n]) / DAC_STEPPER_MAX; } + static float dac_amps(int8_t n) { return ((2.048 * mcp4728_getValue(dac_order[n])) / 4096.0) / (8.0 * DAC_STEPPER_SENSE); } + + void dac_print_values() { + if (!dac_present) return; + + SERIAL_ECHO_START; + SERIAL_ECHOLNPGM("Stepper current values in % (Amps):"); + SERIAL_ECHO_START; + SERIAL_ECHOPAIR(" X:", dac_perc(0)); + SERIAL_ECHOPAIR(" (", dac_amps(0)); + SERIAL_ECHOPAIR(") Y:", dac_perc(1)); + SERIAL_ECHOPAIR(" (", dac_amps(1)); + SERIAL_ECHOPAIR(") Z:", dac_perc(2)); + SERIAL_ECHOPAIR(" (", dac_amps(2)); + SERIAL_ECHOPAIR(") E:", dac_perc(3)); + SERIAL_ECHOPAIR(" (", dac_amps(3)); + SERIAL_ECHOLNPGM(")"); + } + + void dac_commit_eeprom() { + if (!dac_present) return; + mcp4728_eepromWrite(); + } + +#endif // DAC_STEPPER_CURRENT diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/stepper_dac.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/stepper_dac.h new file mode 100644 index 00000000..d80a8467 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/stepper_dac.h @@ -0,0 +1,55 @@ +/** + * 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 . + * + */ + +/** + stepper_dac.h - To set stepper current via DAC + + Part of Marlin + + Copyright (c) 2016 MarlinFirmware + + Marlin is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Marlin is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Marlin. If not, see . +*/ + +#ifndef STEPPER_DAC_H +#define STEPPER_DAC_H + +#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(); + +#endif // STEPPER_DAC_H diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/stepper_indirection.cpp b/trunk/Arduino/Marlin_K8600_1.1.0RC7/stepper_indirection.cpp new file mode 100644 index 00000000..101249e3 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/stepper_indirection.cpp @@ -0,0 +1,245 @@ +/** + * 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 . + * + */ + +/** + stepper_indirection.c - stepper motor driver indirection + to allow some stepper functions to be done via SPI/I2c instead of direct pin manipulation + Part of Marlin + + Copyright (c) 2015 Dominik Wenger + + Marlin is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Marlin is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Marlin. If not, see . +*/ + +#include "stepper_indirection.h" + +#include "MarlinConfig.h" + +#if ENABLED(HAVE_TMCDRIVER) + #include + #include +#endif + +// Stepper objects of TMC steppers used +#if ENABLED(X_IS_TMC) + TMC26XStepper stepperX(200, X_ENABLE_PIN, X_STEP_PIN, X_DIR_PIN, X_MAX_CURRENT, X_SENSE_RESISTOR); +#endif +#if ENABLED(X2_IS_TMC) + TMC26XStepper stepperX2(200, X2_ENABLE_PIN, X2_STEP_PIN, X2_DIR_PIN, X2_MAX_CURRENT, X2_SENSE_RESISTOR); +#endif +#if ENABLED(Y_IS_TMC) + TMC26XStepper stepperY(200, Y_ENABLE_PIN, Y_STEP_PIN, Y_DIR_PIN, Y_MAX_CURRENT, Y_SENSE_RESISTOR); +#endif +#if ENABLED(Y2_IS_TMC) + TMC26XStepper stepperY2(200, Y2_ENABLE_PIN, Y2_STEP_PIN, Y2_DIR_PIN, Y2_MAX_CURRENT, Y2_SENSE_RESISTOR); +#endif +#if ENABLED(Z_IS_TMC) + TMC26XStepper stepperZ(200, Z_ENABLE_PIN, Z_STEP_PIN, Z_DIR_PIN, Z_MAX_CURRENT, Z_SENSE_RESISTOR); +#endif +#if ENABLED(Z2_IS_TMC) + TMC26XStepper stepperZ2(200, Z2_ENABLE_PIN, Z2_STEP_PIN, Z2_DIR_PIN, Z2_MAX_CURRENT, Z2_SENSE_RESISTOR); +#endif +#if ENABLED(E0_IS_TMC) + TMC26XStepper stepperE0(200, E0_ENABLE_PIN, E0_STEP_PIN, E0_DIR_PIN, E0_MAX_CURRENT, E0_SENSE_RESISTOR); +#endif +#if ENABLED(E1_IS_TMC) + TMC26XStepper stepperE1(200, E1_ENABLE_PIN, E1_STEP_PIN, E1_DIR_PIN, E1_MAX_CURRENT, E1_SENSE_RESISTOR); +#endif +#if ENABLED(E2_IS_TMC) + TMC26XStepper stepperE2(200, E2_ENABLE_PIN, E2_STEP_PIN, E2_DIR_PIN, E2_MAX_CURRENT, E2_SENSE_RESISTOR); +#endif +#if ENABLED(E3_IS_TMC) + TMC26XStepper stepperE3(200, E3_ENABLE_PIN, E3_STEP_PIN, E3_DIR_PIN, E3_MAX_CURRENT, E3_SENSE_RESISTOR); +#endif + +#if ENABLED(HAVE_TMCDRIVER) +void tmc_init() { + #if ENABLED(X_IS_TMC) + stepperX.setMicrosteps(X_MICROSTEPS); + stepperX.start(); + #endif + #if ENABLED(X2_IS_TMC) + stepperX2.setMicrosteps(X2_MICROSTEPS); + stepperX2.start(); + #endif + #if ENABLED(Y_IS_TMC) + stepperY.setMicrosteps(Y_MICROSTEPS); + stepperY.start(); + #endif + #if ENABLED(Y2_IS_TMC) + stepperY2.setMicrosteps(Y2_MICROSTEPS); + stepperY2.start(); + #endif + #if ENABLED(Z_IS_TMC) + stepperZ.setMicrosteps(Z_MICROSTEPS); + stepperZ.start(); + #endif + #if ENABLED(Z2_IS_TMC) + stepperZ2.setMicrosteps(Z2_MICROSTEPS); + stepperZ2.start(); + #endif + #if ENABLED(E0_IS_TMC) + stepperE0.setMicrosteps(E0_MICROSTEPS); + stepperE0.start(); + #endif + #if ENABLED(E1_IS_TMC) + stepperE1.setMicrosteps(E1_MICROSTEPS); + stepperE1.start(); + #endif + #if ENABLED(E2_IS_TMC) + stepperE2.setMicrosteps(E2_MICROSTEPS); + stepperE2.start(); + #endif + #if ENABLED(E3_IS_TMC) + stepperE3.setMicrosteps(E3_MICROSTEPS); + stepperE3.start(); + #endif +} +#endif + +// L6470 Driver objects and inits + +#if ENABLED(HAVE_L6470DRIVER) + #include + #include +#endif + +// L6470 Stepper objects +#if ENABLED(X_IS_L6470) + L6470 stepperX(X_ENABLE_PIN); +#endif +#if ENABLED(X2_IS_L6470) + L6470 stepperX2(X2_ENABLE_PIN); +#endif +#if ENABLED(Y_IS_L6470) + L6470 stepperY(Y_ENABLE_PIN); +#endif +#if ENABLED(Y2_IS_L6470) + L6470 stepperY2(Y2_ENABLE_PIN); +#endif +#if ENABLED(Z_IS_L6470) + L6470 stepperZ(Z_ENABLE_PIN); +#endif +#if ENABLED(Z2_IS_L6470) + L6470 stepperZ2(Z2_ENABLE_PIN); +#endif +#if ENABLED(E0_IS_L6470) + L6470 stepperE0(E0_ENABLE_PIN); +#endif +#if ENABLED(E1_IS_L6470) + L6470 stepperE1(E1_ENABLE_PIN); +#endif +#if ENABLED(E2_IS_L6470) + L6470 stepperE2(E2_ENABLE_PIN); +#endif +#if ENABLED(E3_IS_L6470) + L6470 stepperE3(E3_ENABLE_PIN); +#endif + + +// init routine +#if ENABLED(HAVE_L6470DRIVER) +void L6470_init() { + #if ENABLED(X_IS_L6470) + stepperX.init(X_K_VAL); + stepperX.softFree(); + stepperX.setMicroSteps(X_MICROSTEPS); + stepperX.setOverCurrent(X_OVERCURRENT); //set overcurrent protection + stepperX.setStallCurrent(X_STALLCURRENT); + #endif + #if ENABLED(X2_IS_L6470) + stepperX2.init(X2_K_VAL); + stepperX2.softFree(); + stepperX2.setMicroSteps(X2_MICROSTEPS); + stepperX2.setOverCurrent(X2_OVERCURRENT); //set overcurrent protection + stepperX2.setStallCurrent(X2_STALLCURRENT); + #endif + #if ENABLED(Y_IS_L6470) + stepperY.init(Y_K_VAL); + stepperY.softFree(); + stepperY.setMicroSteps(Y_MICROSTEPS); + stepperY.setOverCurrent(Y_OVERCURRENT); //set overcurrent protection + stepperY.setStallCurrent(Y_STALLCURRENT); + #endif + #if ENABLED(Y2_IS_L6470) + stepperY2.init(Y2_K_VAL); + stepperY2.softFree(); + stepperY2.setMicroSteps(Y2_MICROSTEPS); + stepperY2.setOverCurrent(Y2_OVERCURRENT); //set overcurrent protection + stepperY2.setStallCurrent(Y2_STALLCURRENT); + #endif + #if ENABLED(Z_IS_L6470) + stepperZ.init(Z_K_VAL); + stepperZ.softFree(); + stepperZ.setMicroSteps(Z_MICROSTEPS); + stepperZ.setOverCurrent(Z_OVERCURRENT); //set overcurrent protection + stepperZ.setStallCurrent(Z_STALLCURRENT); + #endif + #if ENABLED(Z2_IS_L6470) + stepperZ2.init(Z2_K_VAL); + stepperZ2.softFree(); + stepperZ2.setMicroSteps(Z2_MICROSTEPS); + stepperZ2.setOverCurrent(Z2_OVERCURRENT); //set overcurrent protection + stepperZ2.setStallCurrent(Z2_STALLCURRENT); + #endif + #if ENABLED(E0_IS_L6470) + stepperE0.init(E0_K_VAL); + stepperE0.softFree(); + stepperE0.setMicroSteps(E0_MICROSTEPS); + stepperE0.setOverCurrent(E0_OVERCURRENT); //set overcurrent protection + stepperE0.setStallCurrent(E0_STALLCURRENT); + #endif + #if ENABLED(E1_IS_L6470) + stepperE1.init(E1_K_VAL); + stepperE1.softFree(); + stepperE1.setMicroSteps(E1_MICROSTEPS); + stepperE1.setOverCurrent(E1_OVERCURRENT); //set overcurrent protection + stepperE1.setStallCurrent(E1_STALLCURRENT); + #endif + #if ENABLED(E2_IS_L6470) + stepperE2.init(E2_K_VAL); + stepperE2.softFree(); + stepperE2.setMicroSteps(E2_MICROSTEPS); + stepperE2.setOverCurrent(E2_OVERCURRENT); //set overcurrent protection + stepperE2.setStallCurrent(E2_STALLCURRENT); + #endif + #if ENABLED(E3_IS_L6470) + stepperE3.init(E3_K_VAL); + stepperE3.softFree(); + stepperE3.setMicroSteps(E3_MICROSTEPS); + stepperE3.setOverCurrent(E3_OVERCURRENT); //set overcurrent protection + stepperE3.setStallCurrent(E3_STALLCURRENT); + #endif +} +#endif + diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/stepper_indirection.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/stepper_indirection.h new file mode 100644 index 00000000..6fd19dd4 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/stepper_indirection.h @@ -0,0 +1,395 @@ +/** + * 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 . + * + */ + +/** + stepper_indirection.h - stepper motor driver indirection macros + to allow some stepper functions to be done via SPI/I2c instead of direct pin manipulation + Part of Marlin + + Copyright (c) 2015 Dominik Wenger + + Marlin is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Marlin is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Marlin. If not, see . +*/ + +#ifndef STEPPER_INDIRECTION_H +#define STEPPER_INDIRECTION_H + +#include "MarlinConfig.h" + +// TMC26X drivers have STEP/DIR on normal pins, but ENABLE via SPI +#if ENABLED(HAVE_TMCDRIVER) + #include + #include + void tmc_init(); +#endif + +// L6470 has STEP on normal pins, but DIR/ENABLE via SPI +#if ENABLED(HAVE_L6470DRIVER) + #include + #include + void L6470_init(); +#endif + +// X Stepper +#if ENABLED(HAVE_L6470DRIVER) && ENABLED(X_IS_L6470) + extern L6470 stepperX; + #define X_ENABLE_INIT NOOP + #define X_ENABLE_WRITE(STATE) do{if(STATE) stepperX.Step_Clock(stepperX.getStatus() & STATUS_HIZ); else stepperX.softFree();}while(0) + #define X_ENABLE_READ (stepperX.getStatus() & STATUS_HIZ) + #define X_DIR_INIT NOOP + #define X_DIR_WRITE(STATE) stepperX.Step_Clock(STATE) + #define X_DIR_READ (stepperX.getStatus() & STATUS_DIR) +#else + #if ENABLED(HAVE_TMCDRIVER) && ENABLED(X_IS_TMC) + extern TMC26XStepper stepperX; + #define X_ENABLE_INIT NOOP + #define X_ENABLE_WRITE(STATE) stepperX.setEnabled(STATE) + #define X_ENABLE_READ stepperX.isEnabled() + #else + #define X_ENABLE_INIT SET_OUTPUT(X_ENABLE_PIN) + #define X_ENABLE_WRITE(STATE) WRITE(X_ENABLE_PIN,STATE) + #define X_ENABLE_READ READ(X_ENABLE_PIN) + #endif + #define X_DIR_INIT SET_OUTPUT(X_DIR_PIN) + #define X_DIR_WRITE(STATE) WRITE(X_DIR_PIN,STATE) + #define X_DIR_READ READ(X_DIR_PIN) +#endif +#define X_STEP_INIT SET_OUTPUT(X_STEP_PIN) +#define X_STEP_WRITE(STATE) WRITE(X_STEP_PIN,STATE) +#define X_STEP_READ READ(X_STEP_PIN) + +// Y Stepper +#if ENABLED(HAVE_L6470DRIVER) && ENABLED(Y_IS_L6470) + extern L6470 stepperY; + #define Y_ENABLE_INIT NOOP + #define Y_ENABLE_WRITE(STATE) do{if(STATE) stepperY.Step_Clock(stepperY.getStatus() & STATUS_HIZ); else stepperY.softFree();}while(0) + #define Y_ENABLE_READ (stepperY.getStatus() & STATUS_HIZ) + #define Y_DIR_INIT NOOP + #define Y_DIR_WRITE(STATE) stepperY.Step_Clock(STATE) + #define Y_DIR_READ (stepperY.getStatus() & STATUS_DIR) +#else + #if ENABLED(HAVE_TMCDRIVER) && ENABLED(Y_IS_TMC) + extern TMC26XStepper stepperY; + #define Y_ENABLE_INIT NOOP + #define Y_ENABLE_WRITE(STATE) stepperY.setEnabled(STATE) + #define Y_ENABLE_READ stepperY.isEnabled() + #else + #define Y_ENABLE_INIT SET_OUTPUT(Y_ENABLE_PIN) + #define Y_ENABLE_WRITE(STATE) WRITE(Y_ENABLE_PIN,STATE) + #define Y_ENABLE_READ READ(Y_ENABLE_PIN) + #endif + #define Y_DIR_INIT SET_OUTPUT(Y_DIR_PIN) + #define Y_DIR_WRITE(STATE) WRITE(Y_DIR_PIN,STATE) + #define Y_DIR_READ READ(Y_DIR_PIN) +#endif +#define Y_STEP_INIT SET_OUTPUT(Y_STEP_PIN) +#define Y_STEP_WRITE(STATE) WRITE(Y_STEP_PIN,STATE) +#define Y_STEP_READ READ(Y_STEP_PIN) + +// Z Stepper +#if ENABLED(HAVE_L6470DRIVER) && ENABLED(Z_IS_L6470) + extern L6470 stepperZ; + #define Z_ENABLE_INIT NOOP + #define Z_ENABLE_WRITE(STATE) do{if(STATE) stepperZ.Step_Clock(stepperZ.getStatus() & STATUS_HIZ); else stepperZ.softFree();}while(0) + #define Z_ENABLE_READ (stepperZ.getStatus() & STATUS_HIZ) + #define Z_DIR_INIT NOOP + #define Z_DIR_WRITE(STATE) stepperZ.Step_Clock(STATE) + #define Z_DIR_READ (stepperZ.getStatus() & STATUS_DIR) +#else + #if ENABLED(HAVE_TMCDRIVER) && ENABLED(Z_IS_TMC) + extern TMC26XStepper stepperZ; + #define Z_ENABLE_INIT NOOP + #define Z_ENABLE_WRITE(STATE) stepperZ.setEnabled(STATE) + #define Z_ENABLE_READ stepperZ.isEnabled() + #else + #define Z_ENABLE_INIT SET_OUTPUT(Z_ENABLE_PIN) + #define Z_ENABLE_WRITE(STATE) WRITE(Z_ENABLE_PIN,STATE) + #define Z_ENABLE_READ READ(Z_ENABLE_PIN) + #endif + #define Z_DIR_INIT SET_OUTPUT(Z_DIR_PIN) + #define Z_DIR_WRITE(STATE) WRITE(Z_DIR_PIN,STATE) + #define Z_DIR_READ READ(Z_DIR_PIN) +#endif +#define Z_STEP_INIT SET_OUTPUT(Z_STEP_PIN) +#define Z_STEP_WRITE(STATE) WRITE(Z_STEP_PIN,STATE) +#define Z_STEP_READ READ(Z_STEP_PIN) + +// X2 Stepper +#if HAS_X2_ENABLE + #if ENABLED(HAVE_L6470DRIVER) && ENABLED(X2_IS_L6470) + extern L6470 stepperX2; + #define X2_ENABLE_INIT NOOP + #define X2_ENABLE_WRITE(STATE) do{if(STATE) stepperX2.Step_Clock(stepperX2.getStatus() & STATUS_HIZ); else stepperX2.softFree();}while(0) + #define X2_ENABLE_READ (stepperX2.getStatus() & STATUS_HIZ) + #define X2_DIR_INIT NOOP + #define X2_DIR_WRITE(STATE) stepperX2.Step_Clock(STATE) + #define X2_DIR_READ (stepperX2.getStatus() & STATUS_DIR) + #else + #if ENABLED(HAVE_TMCDRIVER) && ENABLED(X2_IS_TMC) + extern TMC26XStepper stepperX2; + #define X2_ENABLE_INIT NOOP + #define X2_ENABLE_WRITE(STATE) stepperX2.setEnabled(STATE) + #define X2_ENABLE_READ stepperX2.isEnabled() + #else + #define X2_ENABLE_INIT SET_OUTPUT(X2_ENABLE_PIN) + #define X2_ENABLE_WRITE(STATE) WRITE(X2_ENABLE_PIN,STATE) + #define X2_ENABLE_READ READ(X2_ENABLE_PIN) + #endif + #define X2_DIR_INIT SET_OUTPUT(X2_DIR_PIN) + #define X2_DIR_WRITE(STATE) WRITE(X2_DIR_PIN,STATE) + #define X2_DIR_READ READ(X2_DIR_PIN) + #endif + #define X2_STEP_INIT SET_OUTPUT(X2_STEP_PIN) + #define X2_STEP_WRITE(STATE) WRITE(X2_STEP_PIN,STATE) + #define X2_STEP_READ READ(X2_STEP_PIN) +#endif + +// Y2 Stepper +#if HAS_Y2_ENABLE + #if ENABLED(HAVE_L6470DRIVER) && ENABLED(Y2_IS_L6470) + extern L6470 stepperY2; + #define Y2_ENABLE_INIT NOOP + #define Y2_ENABLE_WRITE(STATE) do{if(STATE) stepperY2.Step_Clock(stepperY2.getStatus() & STATUS_HIZ); else stepperY2.softFree();}while(0) + #define Y2_ENABLE_READ (stepperY2.getStatus() & STATUS_HIZ) + #define Y2_DIR_INIT NOOP + #define Y2_DIR_WRITE(STATE) stepperY2.Step_Clock(STATE) + #define Y2_DIR_READ (stepperY2.getStatus() & STATUS_DIR) + #else + #if ENABLED(HAVE_TMCDRIVER) && ENABLED(Y2_IS_TMC) + extern TMC26XStepper stepperY2; + #define Y2_ENABLE_INIT NOOP + #define Y2_ENABLE_WRITE(STATE) stepperY2.setEnabled(STATE) + #define Y2_ENABLE_READ stepperY2.isEnabled() + #else + #define Y2_ENABLE_INIT SET_OUTPUT(Y2_ENABLE_PIN) + #define Y2_ENABLE_WRITE(STATE) WRITE(Y2_ENABLE_PIN,STATE) + #define Y2_ENABLE_READ READ(Y2_ENABLE_PIN) + #endif + #define Y2_DIR_INIT SET_OUTPUT(Y2_DIR_PIN) + #define Y2_DIR_WRITE(STATE) WRITE(Y2_DIR_PIN,STATE) + #define Y2_DIR_READ READ(Y2_DIR_PIN) + #endif + #define Y2_STEP_INIT SET_OUTPUT(Y2_STEP_PIN) + #define Y2_STEP_WRITE(STATE) WRITE(Y2_STEP_PIN,STATE) + #define Y2_STEP_READ READ(Y2_STEP_PIN) +#endif + +// Z2 Stepper +#if HAS_Z2_ENABLE + #if ENABLED(HAVE_L6470DRIVER) && ENABLED(Z2_IS_L6470) + extern L6470 stepperZ2; + #define Z2_ENABLE_INIT NOOP + #define Z2_ENABLE_WRITE(STATE) do{if(STATE) stepperZ2.Step_Clock(stepperZ2.getStatus() & STATUS_HIZ); else stepperZ2.softFree();}while(0) + #define Z2_ENABLE_READ (stepperZ2.getStatus() & STATUS_HIZ) + #define Z2_DIR_INIT NOOP + #define Z2_DIR_WRITE(STATE) stepperZ2.Step_Clock(STATE) + #define Z2_DIR_READ (stepperZ2.getStatus() & STATUS_DIR) + #else + #if ENABLED(HAVE_TMCDRIVER) && ENABLED(Z2_IS_TMC) + extern TMC26XStepper stepperZ2; + #define Z2_ENABLE_INIT NOOP + #define Z2_ENABLE_WRITE(STATE) stepperZ2.setEnabled(STATE) + #define Z2_ENABLE_READ stepperZ2.isEnabled() + #else + #define Z2_ENABLE_INIT SET_OUTPUT(Z2_ENABLE_PIN) + #define Z2_ENABLE_WRITE(STATE) WRITE(Z2_ENABLE_PIN,STATE) + #define Z2_ENABLE_READ READ(Z2_ENABLE_PIN) + #endif + #define Z2_DIR_INIT SET_OUTPUT(Z2_DIR_PIN) + #define Z2_DIR_WRITE(STATE) WRITE(Z2_DIR_PIN,STATE) + #define Z2_DIR_READ READ(Z2_DIR_PIN) + #endif + #define Z2_STEP_INIT SET_OUTPUT(Z2_STEP_PIN) + #define Z2_STEP_WRITE(STATE) WRITE(Z2_STEP_PIN,STATE) + #define Z2_STEP_READ READ(Z2_STEP_PIN) +#endif + +// E0 Stepper +#if ENABLED(HAVE_L6470DRIVER) && ENABLED(E0_IS_L6470) + extern L6470 stepperE0; + #define E0_ENABLE_INIT NOOP + #define E0_ENABLE_WRITE(STATE) do{if(STATE) stepperE0.Step_Clock(stepperE0.getStatus() & STATUS_HIZ); else stepperE0.softFree();}while(0) + #define E0_ENABLE_READ (stepperE0.getStatus() & STATUS_HIZ) + #define E0_DIR_INIT NOOP + #define E0_DIR_WRITE(STATE) stepperE0.Step_Clock(STATE) + #define E0_DIR_READ (stepperE0.getStatus() & STATUS_DIR) +#else + #if ENABLED(HAVE_TMCDRIVER) && ENABLED(E0_IS_TMC) + extern TMC26XStepper stepperE0; + #define E0_ENABLE_INIT NOOP + #define E0_ENABLE_WRITE(STATE) stepperE0.setEnabled(STATE) + #define E0_ENABLE_READ stepperE0.isEnabled() + #else + #define E0_ENABLE_INIT SET_OUTPUT(E0_ENABLE_PIN) + #define E0_ENABLE_WRITE(STATE) WRITE(E0_ENABLE_PIN,STATE) + #define E0_ENABLE_READ READ(E0_ENABLE_PIN) + #endif + #define E0_DIR_INIT SET_OUTPUT(E0_DIR_PIN) + #define E0_DIR_WRITE(STATE) WRITE(E0_DIR_PIN,STATE) + #define E0_DIR_READ READ(E0_DIR_PIN) +#endif +#define E0_STEP_INIT SET_OUTPUT(E0_STEP_PIN) +#define E0_STEP_WRITE(STATE) WRITE(E0_STEP_PIN,STATE) +#define E0_STEP_READ READ(E0_STEP_PIN) + +// E1 Stepper +#if ENABLED(HAVE_L6470DRIVER) && ENABLED(E1_IS_L6470) + extern L6470 stepperE1; + #define E1_ENABLE_INIT NOOP + #define E1_ENABLE_WRITE(STATE) do{if(STATE) stepperE1.Step_Clock(stepperE1.getStatus() & STATUS_HIZ); else stepperE1.softFree();}while(0) + #define E1_ENABLE_READ (stepperE1.getStatus() & STATUS_HIZ) + #define E1_DIR_INIT NOOP + #define E1_DIR_WRITE(STATE) stepperE1.Step_Clock(STATE) + #define E1_DIR_READ (stepperE1.getStatus() & STATUS_DIR) +#else + #if ENABLED(HAVE_TMCDRIVER) && ENABLED(E1_IS_TMC) + extern TMC26XStepper stepperE1; + #define E1_ENABLE_INIT NOOP + #define E1_ENABLE_WRITE(STATE) stepperE1.setEnabled(STATE) + #define E1_ENABLE_READ stepperE1.isEnabled() + #else + #define E1_ENABLE_INIT SET_OUTPUT(E1_ENABLE_PIN) + #define E1_ENABLE_WRITE(STATE) WRITE(E1_ENABLE_PIN,STATE) + #define E1_ENABLE_READ READ(E1_ENABLE_PIN) + #endif + #define E1_DIR_INIT SET_OUTPUT(E1_DIR_PIN) + #define E1_DIR_WRITE(STATE) WRITE(E1_DIR_PIN,STATE) + #define E1_DIR_READ READ(E1_DIR_PIN) +#endif +#define E1_STEP_INIT SET_OUTPUT(E1_STEP_PIN) +#define E1_STEP_WRITE(STATE) WRITE(E1_STEP_PIN,STATE) +#define E1_STEP_READ READ(E1_STEP_PIN) + +// E2 Stepper +#if ENABLED(HAVE_L6470DRIVER) && ENABLED(E2_IS_L6470) + extern L6470 stepperE2; + #define E2_ENABLE_INIT NOOP + #define E2_ENABLE_WRITE(STATE) do{if(STATE) stepperE2.Step_Clock(stepperE2.getStatus() & STATUS_HIZ); else stepperE2.softFree();}while(0) + #define E2_ENABLE_READ (stepperE2.getStatus() & STATUS_HIZ) + #define E2_DIR_INIT NOOP + #define E2_DIR_WRITE(STATE) stepperE2.Step_Clock(STATE) + #define E2_DIR_READ (stepperE2.getStatus() & STATUS_DIR) +#else + #if ENABLED(HAVE_TMCDRIVER) && ENABLED(E2_IS_TMC) + extern TMC26XStepper stepperE2; + #define E2_ENABLE_INIT NOOP + #define E2_ENABLE_WRITE(STATE) stepperE2.setEnabled(STATE) + #define E2_ENABLE_READ stepperE2.isEnabled() + #else + #define E2_ENABLE_INIT SET_OUTPUT(E2_ENABLE_PIN) + #define E2_ENABLE_WRITE(STATE) WRITE(E2_ENABLE_PIN,STATE) + #define E2_ENABLE_READ READ(E2_ENABLE_PIN) + #endif + #define E2_DIR_INIT SET_OUTPUT(E2_DIR_PIN) + #define E2_DIR_WRITE(STATE) WRITE(E2_DIR_PIN,STATE) + #define E2_DIR_READ READ(E2_DIR_PIN) +#endif +#define E2_STEP_INIT SET_OUTPUT(E2_STEP_PIN) +#define E2_STEP_WRITE(STATE) WRITE(E2_STEP_PIN,STATE) +#define E2_STEP_READ READ(E2_STEP_PIN) + +// E3 Stepper +#if ENABLED(HAVE_L6470DRIVER) && ENABLED(E3_IS_L6470) + extern L6470 stepperE3; + #define E3_ENABLE_INIT NOOP + #define E3_ENABLE_WRITE(STATE) do{if(STATE) stepperE3.Step_Clock(stepperE3.getStatus() & STATUS_HIZ); else stepperE3.softFree();}while(0) + #define E3_ENABLE_READ (stepperE3.getStatus() & STATUS_HIZ) + #define E3_DIR_INIT NOOP + #define E3_DIR_WRITE(STATE) stepperE3.Step_Clock(STATE) + #define E3_DIR_READ (stepperE3.getStatus() & STATUS_DIR) +#else + #if ENABLED(HAVE_TMCDRIVER) && ENABLED(E3_IS_TMC) + extern TMC26XStepper stepperE3; + #define E3_ENABLE_INIT NOOP + #define E3_ENABLE_WRITE(STATE) stepperE3.setEnabled(STATE) + #define E3_ENABLE_READ stepperE3.isEnabled() + #else + #define E3_ENABLE_INIT SET_OUTPUT(E3_ENABLE_PIN) + #define E3_ENABLE_WRITE(STATE) WRITE(E3_ENABLE_PIN,STATE) + #define E3_ENABLE_READ READ(E3_ENABLE_PIN) + #endif + #define E3_DIR_INIT SET_OUTPUT(E3_DIR_PIN) + #define E3_DIR_WRITE(STATE) WRITE(E3_DIR_PIN,STATE) + #define E3_DIR_READ READ(E3_DIR_PIN) +#endif +#define E3_STEP_INIT SET_OUTPUT(E3_STEP_PIN) +#define E3_STEP_WRITE(STATE) WRITE(E3_STEP_PIN,STATE) +#define E3_STEP_READ READ(E3_STEP_PIN) + +/** + * Extruder indirection for the single E axis + */ +#if ENABLED(SWITCHING_EXTRUDER) + #define E_STEP_WRITE(v) E0_STEP_WRITE(v) + #define NORM_E_DIR() E0_DIR_WRITE(current_block->active_extruder ? INVERT_E0_DIR : !INVERT_E0_DIR) + #define REV_E_DIR() E0_DIR_WRITE(current_block->active_extruder ? !INVERT_E0_DIR : INVERT_E0_DIR) +#elif EXTRUDERS > 3 + #define E_STEP_WRITE(v) { switch (current_block->active_extruder) { case 0: E0_STEP_WRITE(v); break; case 1: E1_STEP_WRITE(v); break; case 2: E2_STEP_WRITE(v); break; case 3: E3_STEP_WRITE(v); } } + #define NORM_E_DIR() { switch (current_block->active_extruder) { case 0: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 1: E1_DIR_WRITE(!INVERT_E1_DIR); break; case 2: E2_DIR_WRITE(!INVERT_E2_DIR); break; case 3: E3_DIR_WRITE(!INVERT_E3_DIR); } } + #define REV_E_DIR() { switch (current_block->active_extruder) { case 0: E0_DIR_WRITE(INVERT_E0_DIR); break; case 1: E1_DIR_WRITE(INVERT_E1_DIR); break; case 2: E2_DIR_WRITE(INVERT_E2_DIR); break; case 3: E3_DIR_WRITE(INVERT_E3_DIR); } } +#elif EXTRUDERS > 2 + #define E_STEP_WRITE(v) { switch (current_block->active_extruder) { case 0: E0_STEP_WRITE(v); break; case 1: E1_STEP_WRITE(v); break; case 2: E2_STEP_WRITE(v); } } + #define NORM_E_DIR() { switch (current_block->active_extruder) { case 0: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 1: E1_DIR_WRITE(!INVERT_E1_DIR); break; case 2: E2_DIR_WRITE(!INVERT_E2_DIR); } } + #define REV_E_DIR() { switch (current_block->active_extruder) { case 0: E0_DIR_WRITE(INVERT_E0_DIR); break; case 1: E1_DIR_WRITE(INVERT_E1_DIR); break; case 2: E2_DIR_WRITE(INVERT_E2_DIR); } } +#elif EXTRUDERS > 1 + #if ENABLED(DUAL_X_CARRIAGE) || ENABLED(DUAL_NOZZLE_DUPLICATION_MODE) + #define E_STEP_WRITE(v) { if (extruder_duplication_enabled) { E0_STEP_WRITE(v); E1_STEP_WRITE(v); } else if (current_block->active_extruder == 0) { E0_STEP_WRITE(v); } else { E1_STEP_WRITE(v); } } + #define NORM_E_DIR() { if (extruder_duplication_enabled) { E0_DIR_WRITE(!INVERT_E0_DIR); E1_DIR_WRITE(!INVERT_E1_DIR); } else if (current_block->active_extruder == 0) { E0_DIR_WRITE(!INVERT_E0_DIR); } else { E1_DIR_WRITE(!INVERT_E1_DIR); } } + #define REV_E_DIR() { if (extruder_duplication_enabled) { E0_DIR_WRITE(INVERT_E0_DIR); E1_DIR_WRITE(INVERT_E1_DIR); } else if (current_block->active_extruder == 0) { E0_DIR_WRITE(INVERT_E0_DIR); } else { E1_DIR_WRITE(INVERT_E1_DIR); } } + #else + #define E_STEP_WRITE(v) { if (current_block->active_extruder == 0) { E0_STEP_WRITE(v); } else { E1_STEP_WRITE(v); } } + #define NORM_E_DIR() { if (current_block->active_extruder == 0) { E0_DIR_WRITE(!INVERT_E0_DIR); } else { E1_DIR_WRITE(!INVERT_E1_DIR); } } + #define REV_E_DIR() { if (current_block->active_extruder == 0) { E0_DIR_WRITE(INVERT_E0_DIR); } else { E1_DIR_WRITE(INVERT_E1_DIR); } } + #endif +#elif ENABLED(MIXING_EXTRUDER) + #define E_STEP_WRITE(v) NOOP /* not used for mixing extruders! */ + #if MIXING_STEPPERS > 3 + #define En_STEP_WRITE(n,v) { switch (n) { case 0: E0_STEP_WRITE(v); break; case 1: E1_STEP_WRITE(v); break; case 2: E2_STEP_WRITE(v); break; case 3: E3_STEP_WRITE(v); } } + #define NORM_E_DIR() { E0_DIR_WRITE(!INVERT_E0_DIR); E1_DIR_WRITE(!INVERT_E1_DIR); E2_DIR_WRITE(!INVERT_E2_DIR); E3_DIR_WRITE(!INVERT_E3_DIR); } + #define REV_E_DIR() { E0_DIR_WRITE( INVERT_E0_DIR); E1_DIR_WRITE( INVERT_E1_DIR); E2_DIR_WRITE( INVERT_E2_DIR); E3_DIR_WRITE( INVERT_E3_DIR); } + #elif MIXING_STEPPERS > 2 + #define En_STEP_WRITE(n,v) { switch (n) { case 0: E0_STEP_WRITE(v); break; case 1: E1_STEP_WRITE(v); break; case 2: E2_STEP_WRITE(v); } } + #define NORM_E_DIR() { E0_DIR_WRITE(!INVERT_E0_DIR); E1_DIR_WRITE(!INVERT_E1_DIR); E2_DIR_WRITE(!INVERT_E2_DIR); } + #define REV_E_DIR() { E0_DIR_WRITE( INVERT_E0_DIR); E1_DIR_WRITE( INVERT_E1_DIR); E2_DIR_WRITE( INVERT_E2_DIR); } + #else + #define En_STEP_WRITE(n,v) { switch (n) { case 0: E0_STEP_WRITE(v); break; case 1: E1_STEP_WRITE(v); } } + #define NORM_E_DIR() { E0_DIR_WRITE(!INVERT_E0_DIR); E1_DIR_WRITE(!INVERT_E1_DIR); } + #define REV_E_DIR() { E0_DIR_WRITE( INVERT_E0_DIR); E1_DIR_WRITE( INVERT_E1_DIR); } + #endif +#else + #define E_STEP_WRITE(v) E0_STEP_WRITE(v) + #define NORM_E_DIR() E0_DIR_WRITE(!INVERT_E0_DIR) + #define REV_E_DIR() E0_DIR_WRITE(INVERT_E0_DIR) +#endif + +#endif // STEPPER_INDIRECTION_H diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/stopwatch.cpp b/trunk/Arduino/Marlin_K8600_1.1.0RC7/stopwatch.cpp new file mode 100644 index 00000000..ef701a11 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/stopwatch.cpp @@ -0,0 +1,106 @@ +/* + * 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 . + * + */ + +#include "Marlin.h" +#include "stopwatch.h" + +Stopwatch::Stopwatch() { + this->reset(); +} + +bool Stopwatch::stop() { + #if ENABLED(DEBUG_STOPWATCH) + Stopwatch::debug(PSTR("stop")); + #endif + + if (this->isRunning() || this->isPaused()) { + this->state = STOPPED; + this->stopTimestamp = millis(); + return true; + } + else return false; +} + +bool Stopwatch::pause() { + #if ENABLED(DEBUG_STOPWATCH) + Stopwatch::debug(PSTR("pause")); + #endif + + if (this->isRunning()) { + this->state = PAUSED; + this->stopTimestamp = millis(); + return true; + } + else return false; +} + +bool Stopwatch::start() { + #if ENABLED(DEBUG_STOPWATCH) + Stopwatch::debug(PSTR("start")); + #endif + + if (!this->isRunning()) { + if (this->isPaused()) this->accumulator = this->duration(); + else this->reset(); + + this->state = RUNNING; + this->startTimestamp = millis(); + return true; + } + else return false; +} + +void Stopwatch::reset() { + #if ENABLED(DEBUG_STOPWATCH) + Stopwatch::debug(PSTR("reset")); + #endif + + this->state = STOPPED; + this->startTimestamp = 0; + this->stopTimestamp = 0; + this->accumulator = 0; +} + +bool Stopwatch::isRunning() { + return (this->state == RUNNING) ? true : false; +} + +bool Stopwatch::isPaused() { + return (this->state == PAUSED) ? true : false; +} + +millis_t Stopwatch::duration() { + return (((this->isRunning()) ? millis() : this->stopTimestamp) + - this->startTimestamp) / 1000UL + this->accumulator; +} + +#if ENABLED(DEBUG_STOPWATCH) + + void Stopwatch::debug(const char func[]) { + if (DEBUGGING(INFO)) { + SERIAL_ECHOPGM("Stopwatch::"); + serialprintPGM(func); + SERIAL_ECHOLNPGM("()"); + } + } + +#endif diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/stopwatch.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/stopwatch.h new file mode 100644 index 00000000..70948288 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/stopwatch.h @@ -0,0 +1,117 @@ +/* + * 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 . + * + */ + +#ifndef STOPWATCH_H +#define STOPWATCH_H + +#include "macros.h" + +// Print debug messages with M111 S2 (Uses 156 bytes of PROGMEM) +//#define DEBUG_STOPWATCH + +/** + * @brief Stopwatch class + * @details This class acts as a timer proving stopwatch functionality including + * the ability to pause the running time counter. + */ +class Stopwatch { + private: + enum State { + STOPPED, + RUNNING, + PAUSED + }; + + Stopwatch::State state; + millis_t accumulator; + millis_t startTimestamp; + millis_t stopTimestamp; + + public: + /** + * @brief Class constructor + */ + Stopwatch(); + + /** + * @brief Stops the stopwatch + * @details Stops the running timer, it will silently ignore the request if + * no timer is currently running. + * @return true is method was successful + */ + bool stop(); + + /** + * @brief Pause the stopwatch + * @details Pauses the running timer, it will silently ignore the request if + * no timer is currently running. + * @return true is method was successful + */ + bool pause(); + + /** + * @brief Starts the stopwatch + * @details Starts the timer, it will silently ignore the request if the + * timer is already running. + * @return true is method was successful + */ + bool start(); + + /** + * @brief Resets the stopwatch + * @details Resets all settings to their default values. + */ + void reset(); + + /** + * @brief Checks if the timer is running + * @details Returns true if the timer is currently running, false otherwise. + * @return true if stopwatch is running + */ + bool isRunning(); + + /** + * @brief Checks if the timer is paused + * @details Returns true if the timer is currently paused, false otherwise. + * @return true if stopwatch is paused + */ + bool isPaused(); + + /** + * @brief Gets the running time + * @details Returns the total number of seconds the timer has been running. + * @return the delta since starting the stopwatch + */ + millis_t duration(); + + #if ENABLED(DEBUG_STOPWATCH) + + /** + * @brief Prints a debug message + * @details Prints a simple debug message "Stopwatch::function" + */ + static void debug(const char func[]); + + #endif +}; + +#endif //STOPWATCH_H diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/temperature.cpp b/trunk/Arduino/Marlin_K8600_1.1.0RC7/temperature.cpp new file mode 100644 index 00000000..552ef8b2 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/temperature.cpp @@ -0,0 +1,1837 @@ +/** + * 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 . + * + */ + +/** + * temperature.cpp - temperature control + */ + +#include "Marlin.h" +#include "ultralcd.h" +#include "temperature.h" +#include "thermistortables.h" +#include "language.h" +#if ENABLED(BABYSTEPPING) + #include "stepper.h" +#endif + +#if ENABLED(USE_WATCHDOG) + #include "watchdog.h" +#endif + +#ifdef K1 // Defined in Configuration.h in the PID settings + #define K2 (1.0-K1) +#endif + +#if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT) + static void* heater_ttbl_map[2] = {(void*)HEATER_0_TEMPTABLE, (void*)HEATER_1_TEMPTABLE }; + static 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); + static 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); +#endif + +Temperature thermalManager; + +// public: + +float Temperature::current_temperature[HOTENDS] = { 0.0 }, + Temperature::current_temperature_bed = 0.0; +int Temperature::current_temperature_raw[HOTENDS] = { 0 }, + Temperature::target_temperature[HOTENDS] = { 0 }, + Temperature::current_temperature_bed_raw = 0, + Temperature::target_temperature_bed = 0; + +#if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT) + float Temperature::redundant_temperature = 0.0; +#endif + +unsigned char Temperature::soft_pwm_bed; + +#if ENABLED(FAN_SOFT_PWM) + unsigned char Temperature::fanSpeedSoftPwm[FAN_COUNT]; +#endif + +#if ENABLED(PIDTEMP) + #if ENABLED(PID_PARAMS_PER_HOTEND) && HOTENDS > 1 + float Temperature::Kp[HOTENDS] = ARRAY_BY_HOTENDS1(DEFAULT_Kp), + Temperature::Ki[HOTENDS] = ARRAY_BY_HOTENDS1((DEFAULT_Ki) * (PID_dT)), + Temperature::Kd[HOTENDS] = ARRAY_BY_HOTENDS1((DEFAULT_Kd) / (PID_dT)); + #if ENABLED(PID_EXTRUSION_SCALING) + float Temperature::Kc[HOTENDS] = ARRAY_BY_HOTENDS1(DEFAULT_Kc); + #endif + #else + float Temperature::Kp = DEFAULT_Kp, + Temperature::Ki = (DEFAULT_Ki) * (PID_dT), + Temperature::Kd = (DEFAULT_Kd) / (PID_dT); + #if ENABLED(PID_EXTRUSION_SCALING) + float Temperature::Kc = DEFAULT_Kc; + #endif + #endif +#endif + +#if ENABLED(PIDTEMPBED) + float Temperature::bedKp = DEFAULT_bedKp, + Temperature::bedKi = ((DEFAULT_bedKi) * PID_dT), + Temperature::bedKd = ((DEFAULT_bedKd) / PID_dT); +#endif + +#if ENABLED(BABYSTEPPING) + volatile int Temperature::babystepsTodo[3] = { 0 }; +#endif + +#if ENABLED(THERMAL_PROTECTION_HOTENDS) && WATCH_TEMP_PERIOD > 0 + int Temperature::watch_target_temp[HOTENDS] = { 0 }; + millis_t Temperature::watch_heater_next_ms[HOTENDS] = { 0 }; +#endif + +#if ENABLED(THERMAL_PROTECTION_BED) && WATCH_BED_TEMP_PERIOD > 0 + int Temperature::watch_target_bed_temp = 0; + millis_t Temperature::watch_bed_next_ms = 0; +#endif + +#if ENABLED(PREVENT_DANGEROUS_EXTRUDE) + bool Temperature::allow_cold_extrude = false; + float Temperature::extrude_min_temp = EXTRUDE_MINTEMP; +#endif + +// private: + +#if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT) + int Temperature::redundant_temperature_raw = 0; + float Temperature::redundant_temperature = 0.0; +#endif + +volatile bool Temperature::temp_meas_ready = false; + +#if ENABLED(PIDTEMP) + float Temperature::temp_iState[HOTENDS] = { 0 }, + Temperature::temp_dState[HOTENDS] = { 0 }, + Temperature::pTerm[HOTENDS], + Temperature::iTerm[HOTENDS], + Temperature::dTerm[HOTENDS]; + + #if ENABLED(PID_EXTRUSION_SCALING) + float Temperature::cTerm[HOTENDS]; + long Temperature::last_e_position; + long Temperature::lpq[LPQ_MAX_LEN]; + int Temperature::lpq_ptr = 0; + #endif + + float Temperature::pid_error[HOTENDS], + Temperature::temp_iState_min[HOTENDS], + Temperature::temp_iState_max[HOTENDS]; + bool Temperature::pid_reset[HOTENDS]; +#endif + +#if ENABLED(PIDTEMPBED) + float Temperature::temp_iState_bed = { 0 }, + Temperature::temp_dState_bed = { 0 }, + Temperature::pTerm_bed, + Temperature::iTerm_bed, + Temperature::dTerm_bed, + Temperature::pid_error_bed, + Temperature::temp_iState_min_bed, + Temperature::temp_iState_max_bed; +#else + millis_t Temperature::next_bed_check_ms; +#endif + +unsigned long Temperature::raw_temp_value[4] = { 0 }; +unsigned long Temperature::raw_temp_bed_value = 0; + +// Init min and max temp with extreme values to prevent false errors during startup +int Temperature::minttemp_raw[HOTENDS] = ARRAY_BY_HOTENDS(HEATER_0_RAW_LO_TEMP , HEATER_1_RAW_LO_TEMP , HEATER_2_RAW_LO_TEMP, HEATER_3_RAW_LO_TEMP), + Temperature::maxttemp_raw[HOTENDS] = ARRAY_BY_HOTENDS(HEATER_0_RAW_HI_TEMP , HEATER_1_RAW_HI_TEMP , HEATER_2_RAW_HI_TEMP, HEATER_3_RAW_HI_TEMP), + Temperature::minttemp[HOTENDS] = { 0 }, + Temperature::maxttemp[HOTENDS] = ARRAY_BY_HOTENDS1(16383); + +#ifdef MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED + int Temperature::consecutive_low_temperature_error[HOTENDS] = { 0 }; +#endif + +#ifdef MILLISECONDS_PREHEAT_TIME + unsigned long Temperature::preheat_end_time[HOTENDS] = { 0 }; +#endif + +#ifdef BED_MINTEMP + int Temperature::bed_minttemp_raw = HEATER_BED_RAW_LO_TEMP; +#endif + +#ifdef BED_MAXTEMP + int Temperature::bed_maxttemp_raw = HEATER_BED_RAW_HI_TEMP; +#endif + +#if ENABLED(FILAMENT_WIDTH_SENSOR) + int Temperature::meas_shift_index; // Index of a delayed sample in buffer +#endif + +#if HAS_AUTO_FAN + millis_t Temperature::next_auto_fan_check_ms; +#endif + +unsigned char Temperature::soft_pwm[HOTENDS]; + +#if ENABLED(FAN_SOFT_PWM) + unsigned char Temperature::soft_pwm_fan[FAN_COUNT]; +#endif + +#if ENABLED(FILAMENT_WIDTH_SENSOR) + int Temperature::current_raw_filwidth = 0; //Holds measured filament diameter - one extruder only +#endif + +#if HAS_PID_HEATING + + void Temperature::PID_autotune(float temp, int hotend, int ncycles, bool set_result/*=false*/) { + float input = 0.0; + int cycles = 0; + bool heating = true; + + millis_t temp_ms = millis(), t1 = temp_ms, t2 = temp_ms; + long t_high = 0, t_low = 0; + + long bias, d; + float Ku, Tu; + float workKp = 0, workKi = 0, workKd = 0; + float max = 0, min = 10000; + + #if HAS_AUTO_FAN + next_auto_fan_check_ms = temp_ms + 2500UL; + #endif + + if (hotend >= + #if ENABLED(PIDTEMP) + HOTENDS + #else + 0 + #endif + || hotend < + #if ENABLED(PIDTEMPBED) + -1 + #else + 0 + #endif + ) { + SERIAL_ECHOLN(MSG_PID_BAD_EXTRUDER_NUM); + return; + } + + SERIAL_ECHOLN(MSG_PID_AUTOTUNE_START); + + disable_all_heaters(); // switch off all heaters. + + #if HAS_PID_FOR_BOTH + if (hotend < 0) + soft_pwm_bed = bias = d = (MAX_BED_POWER) / 2; + else + soft_pwm[hotend] = bias = d = (PID_MAX) / 2; + #elif ENABLED(PIDTEMP) + soft_pwm[hotend] = bias = d = (PID_MAX) / 2; + #else + soft_pwm_bed = bias = d = (MAX_BED_POWER) / 2; + #endif + + wait_for_heatup = true; + + // PID Tuning loop + while (wait_for_heatup) { + + millis_t ms = millis(); + + if (temp_meas_ready) { // temp sample ready + updateTemperaturesFromRawValues(); + + input = + #if HAS_PID_FOR_BOTH + hotend < 0 ? current_temperature_bed : current_temperature[hotend] + #elif ENABLED(PIDTEMP) + current_temperature[hotend] + #else + current_temperature_bed + #endif + ; + + max = max(max, input); + min = min(min, input); + + #if HAS_AUTO_FAN + if (ELAPSED(ms, next_auto_fan_check_ms)) { + checkExtruderAutoFans(); + next_auto_fan_check_ms = ms + 2500UL; + } + #endif + + if (heating && input > temp) { + if (ELAPSED(ms, t2 + 5000UL)) { + heating = false; + #if HAS_PID_FOR_BOTH + if (hotend < 0) + soft_pwm_bed = (bias - d) >> 1; + else + soft_pwm[hotend] = (bias - d) >> 1; + #elif ENABLED(PIDTEMP) + soft_pwm[hotend] = (bias - d) >> 1; + #elif ENABLED(PIDTEMPBED) + soft_pwm_bed = (bias - d) >> 1; + #endif + t1 = ms; + t_high = t1 - t2; + max = temp; + } + } + + if (!heating && input < temp) { + if (ELAPSED(ms, t1 + 5000UL)) { + heating = true; + t2 = ms; + t_low = t2 - t1; + if (cycles > 0) { + long max_pow = + #if HAS_PID_FOR_BOTH + hotend < 0 ? MAX_BED_POWER : PID_MAX + #elif ENABLED(PIDTEMP) + PID_MAX + #else + MAX_BED_POWER + #endif + ; + bias += (d * (t_high - t_low)) / (t_low + t_high); + bias = constrain(bias, 20, max_pow - 20); + d = (bias > max_pow / 2) ? max_pow - 1 - bias : bias; + + SERIAL_PROTOCOLPAIR(MSG_BIAS, bias); + SERIAL_PROTOCOLPAIR(MSG_D, d); + SERIAL_PROTOCOLPAIR(MSG_T_MIN, min); + SERIAL_PROTOCOLPAIR(MSG_T_MAX, max); + if (cycles > 2) { + Ku = (4.0 * d) / (3.14159265 * (max - min) * 0.5); + Tu = ((float)(t_low + t_high) * 0.001); + SERIAL_PROTOCOLPAIR(MSG_KU, Ku); + SERIAL_PROTOCOLPAIR(MSG_TU, Tu); + workKp = 0.6 * Ku; + workKi = 2 * workKp / Tu; + workKd = workKp * Tu * 0.125; + SERIAL_PROTOCOLLNPGM(MSG_CLASSIC_PID); + SERIAL_PROTOCOLPAIR(MSG_KP, workKp); + SERIAL_PROTOCOLPAIR(MSG_KI, workKi); + SERIAL_PROTOCOLPAIR(MSG_KD, workKd); + /** + workKp = 0.33*Ku; + workKi = workKp/Tu; + workKd = workKp*Tu/3; + SERIAL_PROTOCOLLNPGM(" Some overshoot"); + SERIAL_PROTOCOLPAIR(" Kp: ", workKp); + SERIAL_PROTOCOLPAIR(" Ki: ", workKi); + SERIAL_PROTOCOLPAIR(" Kd: ", workKd); + workKp = 0.2*Ku; + workKi = 2*workKp/Tu; + workKd = workKp*Tu/3; + SERIAL_PROTOCOLLNPGM(" No overshoot"); + SERIAL_PROTOCOLPAIR(" Kp: ", workKp); + SERIAL_PROTOCOLPAIR(" Ki: ", workKi); + SERIAL_PROTOCOLPAIR(" Kd: ", workKd); + */ + } + } + #if HAS_PID_FOR_BOTH + if (hotend < 0) + soft_pwm_bed = (bias + d) >> 1; + else + soft_pwm[hotend] = (bias + d) >> 1; + #elif ENABLED(PIDTEMP) + soft_pwm[hotend] = (bias + d) >> 1; + #else + soft_pwm_bed = (bias + d) >> 1; + #endif + cycles++; + min = temp; + } + } + } + #define MAX_OVERSHOOT_PID_AUTOTUNE 20 + if (input > temp + MAX_OVERSHOOT_PID_AUTOTUNE) { + SERIAL_PROTOCOLLNPGM(MSG_PID_TEMP_TOO_HIGH); + return; + } + // Every 2 seconds... + if (ELAPSED(ms, temp_ms + 2000UL)) { + #if HAS_TEMP_HOTEND || HAS_TEMP_BED + print_heaterstates(); + SERIAL_EOL; + #endif + + temp_ms = ms; + } // every 2 seconds + // Over 2 minutes? + if (((ms - t1) + (ms - t2)) > (10L * 60L * 1000L * 2L)) { + SERIAL_PROTOCOLLNPGM(MSG_PID_TIMEOUT); + return; + } + if (cycles > ncycles) { + SERIAL_PROTOCOLLNPGM(MSG_PID_AUTOTUNE_FINISHED); + + #if HAS_PID_FOR_BOTH + const char* estring = hotend < 0 ? "bed" : ""; + SERIAL_PROTOCOLPAIR("#define DEFAULT_", estring); SERIAL_PROTOCOLPAIR("Kp ", workKp); + SERIAL_PROTOCOLPAIR("#define DEFAULT_", estring); SERIAL_PROTOCOLPAIR("Ki ", workKi); + SERIAL_PROTOCOLPAIR("#define DEFAULT_", estring); SERIAL_PROTOCOLPAIR("Kd ", workKd); + #elif ENABLED(PIDTEMP) + SERIAL_PROTOCOLPAIR("#define DEFAULT_Kp ", workKp); + SERIAL_PROTOCOLPAIR("#define DEFAULT_Ki ", workKi); + SERIAL_PROTOCOLPAIR("#define DEFAULT_Kd ", workKd); + #else + SERIAL_PROTOCOLPAIR("#define DEFAULT_bedKp ", workKp); + SERIAL_PROTOCOLPAIR("#define DEFAULT_bedKi ", workKi); + SERIAL_PROTOCOLPAIR("#define DEFAULT_bedKd ", workKd); + #endif + + #define _SET_BED_PID() \ + bedKp = workKp; \ + bedKi = scalePID_i(workKi); \ + bedKd = scalePID_d(workKd); \ + updatePID() + + #define _SET_EXTRUDER_PID() \ + PID_PARAM(Kp, hotend) = workKp; \ + PID_PARAM(Ki, hotend) = scalePID_i(workKi); \ + PID_PARAM(Kd, hotend) = scalePID_d(workKd); \ + updatePID() + + // Use the result? (As with "M303 U1") + if (set_result) { + #if HAS_PID_FOR_BOTH + if (hotend < 0) { + _SET_BED_PID(); + } + else { + _SET_EXTRUDER_PID(); + } + #elif ENABLED(PIDTEMP) + _SET_EXTRUDER_PID(); + #else + _SET_BED_PID(); + #endif + } + return; + } + lcd_update(); + } + if (!wait_for_heatup) disable_all_heaters(); + } + +#endif // HAS_PID_HEATING + +/** + * Class and Instance Methods + */ + +Temperature::Temperature() { } + +void Temperature::updatePID() { + #if ENABLED(PIDTEMP) + #if ENABLED(PID_EXTRUSION_SCALING) + last_e_position = 0; + #endif + HOTEND_LOOP() { + temp_iState_max[e] = (PID_INTEGRAL_DRIVE_MAX) / PID_PARAM(Ki, e); + } + #endif + #if ENABLED(PIDTEMPBED) + temp_iState_max_bed = (PID_BED_INTEGRAL_DRIVE_MAX) / bedKi; + #endif +} + +int Temperature::getHeaterPower(int heater) { + return heater < 0 ? soft_pwm_bed : soft_pwm[heater]; +} + +#if HAS_AUTO_FAN + + void Temperature::checkExtruderAutoFans() { + const int8_t fanPin[] = { EXTRUDER_0_AUTO_FAN_PIN, EXTRUDER_1_AUTO_FAN_PIN, EXTRUDER_2_AUTO_FAN_PIN, EXTRUDER_3_AUTO_FAN_PIN }; + const int fanBit[] = { 0, + EXTRUDER_1_AUTO_FAN_PIN == EXTRUDER_0_AUTO_FAN_PIN ? 0 : 1, + EXTRUDER_2_AUTO_FAN_PIN == EXTRUDER_0_AUTO_FAN_PIN ? 0 : + EXTRUDER_2_AUTO_FAN_PIN == EXTRUDER_1_AUTO_FAN_PIN ? 1 : 2, + EXTRUDER_3_AUTO_FAN_PIN == EXTRUDER_0_AUTO_FAN_PIN ? 0 : + EXTRUDER_3_AUTO_FAN_PIN == EXTRUDER_1_AUTO_FAN_PIN ? 1 : + EXTRUDER_3_AUTO_FAN_PIN == EXTRUDER_2_AUTO_FAN_PIN ? 2 : 3 + }; + uint8_t fanState = 0; + HOTEND_LOOP() { + if (current_temperature[e] > EXTRUDER_AUTO_FAN_TEMPERATURE) + SBI(fanState, fanBit[e]); + } + uint8_t fanDone = 0; + for (int8_t f = 0; f <= 3; f++) { + int8_t pin = fanPin[f]; + if (pin >= 0 && !TEST(fanDone, fanBit[f])) { + unsigned char newFanSpeed = TEST(fanState, fanBit[f]) ? EXTRUDER_AUTO_FAN_SPEED : 0; + // this idiom allows both digital and PWM fan outputs (see M42 handling). + digitalWrite(pin, newFanSpeed); + analogWrite(pin, newFanSpeed); + SBI(fanDone, fanBit[f]); + } + } + } + +#endif // HAS_AUTO_FAN + +// +// Temperature Error Handlers +// +void Temperature::_temp_error(int e, const char* serial_msg, const char* lcd_msg) { + static bool killed = false; + if (IsRunning()) { + SERIAL_ERROR_START; + serialprintPGM(serial_msg); + SERIAL_ERRORPGM(MSG_STOPPED_HEATER); + if (e >= 0) SERIAL_ERRORLN((int)e); else SERIAL_ERRORLNPGM(MSG_HEATER_BED); + } + #if DISABLED(BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE) + if (!killed) { + Running = false; + killed = true; + kill(lcd_msg); + } + else + disable_all_heaters(); // paranoia + #endif +} + +void Temperature::max_temp_error(uint8_t e) { + #if HOTENDS == 1 + UNUSED(e); + #endif + _temp_error(HOTEND_INDEX, PSTR(MSG_T_MAXTEMP), PSTR(MSG_ERR_MAXTEMP)); +} +void Temperature::min_temp_error(uint8_t e) { + #if HOTENDS == 1 + UNUSED(e); + #endif + _temp_error(HOTEND_INDEX, PSTR(MSG_T_MINTEMP), PSTR(MSG_ERR_MINTEMP)); +} + +float Temperature::get_pid_output(int e) { + #if HOTENDS == 1 + UNUSED(e); + #define _HOTEND_TEST true + #else + #define _HOTEND_TEST e == active_extruder + #endif + float pid_output; + #if ENABLED(PIDTEMP) + #if DISABLED(PID_OPENLOOP) + pid_error[HOTEND_INDEX] = target_temperature[HOTEND_INDEX] - current_temperature[HOTEND_INDEX]; + dTerm[HOTEND_INDEX] = K2 * PID_PARAM(Kd, HOTEND_INDEX) * (current_temperature[HOTEND_INDEX] - temp_dState[HOTEND_INDEX]) + K1 * dTerm[HOTEND_INDEX]; + temp_dState[HOTEND_INDEX] = current_temperature[HOTEND_INDEX]; + if (pid_error[HOTEND_INDEX] > PID_FUNCTIONAL_RANGE) { + pid_output = BANG_MAX; + pid_reset[HOTEND_INDEX] = true; + } + else if (pid_error[HOTEND_INDEX] < -(PID_FUNCTIONAL_RANGE) || target_temperature[HOTEND_INDEX] == 0) { + pid_output = 0; + pid_reset[HOTEND_INDEX] = true; + } + else { + if (pid_reset[HOTEND_INDEX]) { + temp_iState[HOTEND_INDEX] = 0.0; + pid_reset[HOTEND_INDEX] = false; + } + pTerm[HOTEND_INDEX] = PID_PARAM(Kp, HOTEND_INDEX) * pid_error[HOTEND_INDEX]; + temp_iState[HOTEND_INDEX] += pid_error[HOTEND_INDEX]; + temp_iState[HOTEND_INDEX] = constrain(temp_iState[HOTEND_INDEX], temp_iState_min[HOTEND_INDEX], temp_iState_max[HOTEND_INDEX]); + iTerm[HOTEND_INDEX] = PID_PARAM(Ki, HOTEND_INDEX) * temp_iState[HOTEND_INDEX]; + + pid_output = pTerm[HOTEND_INDEX] + iTerm[HOTEND_INDEX] - dTerm[HOTEND_INDEX]; + + #if ENABLED(PID_EXTRUSION_SCALING) + cTerm[HOTEND_INDEX] = 0; + if (_HOTEND_TEST) { + long e_position = stepper.position(E_AXIS); + if (e_position > last_e_position) { + lpq[lpq_ptr] = e_position - last_e_position; + last_e_position = e_position; + } + else { + lpq[lpq_ptr] = 0; + } + if (++lpq_ptr >= lpq_len) lpq_ptr = 0; + cTerm[HOTEND_INDEX] = (lpq[lpq_ptr] * planner.steps_to_mm[E_AXIS]) * PID_PARAM(Kc, HOTEND_INDEX); + pid_output += cTerm[HOTEND_INDEX]; + } + #endif // PID_EXTRUSION_SCALING + + if (pid_output > PID_MAX) { + if (pid_error[HOTEND_INDEX] > 0) temp_iState[HOTEND_INDEX] -= pid_error[HOTEND_INDEX]; // conditional un-integration + pid_output = PID_MAX; + } + else if (pid_output < 0) { + if (pid_error[HOTEND_INDEX] < 0) temp_iState[HOTEND_INDEX] -= pid_error[HOTEND_INDEX]; // conditional un-integration + pid_output = 0; + } + } + #else + pid_output = constrain(target_temperature[HOTEND_INDEX], 0, PID_MAX); + #endif //PID_OPENLOOP + + #if ENABLED(PID_DEBUG) + SERIAL_ECHO_START; + SERIAL_ECHOPAIR(MSG_PID_DEBUG, HOTEND_INDEX); + SERIAL_ECHOPAIR(MSG_PID_DEBUG_INPUT, current_temperature[HOTEND_INDEX]); + SERIAL_ECHOPAIR(MSG_PID_DEBUG_OUTPUT, pid_output); + SERIAL_ECHOPAIR(MSG_PID_DEBUG_PTERM, pTerm[HOTEND_INDEX]); + SERIAL_ECHOPAIR(MSG_PID_DEBUG_ITERM, iTerm[HOTEND_INDEX]); + SERIAL_ECHOPAIR(MSG_PID_DEBUG_DTERM, dTerm[HOTEND_INDEX]); + #if ENABLED(PID_EXTRUSION_SCALING) + SERIAL_ECHOPAIR(MSG_PID_DEBUG_CTERM, cTerm[HOTEND_INDEX]); + #endif + SERIAL_EOL; + #endif //PID_DEBUG + + #else /* PID off */ + pid_output = (current_temperature[HOTEND_INDEX] < target_temperature[HOTEND_INDEX]) ? PID_MAX : 0; + #endif + + return pid_output; +} + +#if ENABLED(PIDTEMPBED) + float Temperature::get_pid_output_bed() { + float pid_output; + #if DISABLED(PID_OPENLOOP) + pid_error_bed = target_temperature_bed - current_temperature_bed; + pTerm_bed = bedKp * pid_error_bed; + temp_iState_bed += pid_error_bed; + temp_iState_bed = constrain(temp_iState_bed, temp_iState_min_bed, temp_iState_max_bed); + iTerm_bed = bedKi * temp_iState_bed; + + dTerm_bed = K2 * bedKd * (current_temperature_bed - temp_dState_bed) + K1 * dTerm_bed; + temp_dState_bed = current_temperature_bed; + + pid_output = pTerm_bed + iTerm_bed - dTerm_bed; + if (pid_output > MAX_BED_POWER) { + if (pid_error_bed > 0) temp_iState_bed -= pid_error_bed; // conditional un-integration + pid_output = MAX_BED_POWER; + } + else if (pid_output < 0) { + if (pid_error_bed < 0) temp_iState_bed -= pid_error_bed; // conditional un-integration + pid_output = 0; + } + #else + pid_output = constrain(target_temperature_bed, 0, MAX_BED_POWER); + #endif // PID_OPENLOOP + + #if ENABLED(PID_BED_DEBUG) + SERIAL_ECHO_START; + SERIAL_ECHOPGM(" PID_BED_DEBUG "); + SERIAL_ECHOPGM(": Input "); + SERIAL_ECHO(current_temperature_bed); + SERIAL_ECHOPGM(" Output "); + SERIAL_ECHO(pid_output); + SERIAL_ECHOPGM(" pTerm "); + SERIAL_ECHO(pTerm_bed); + SERIAL_ECHOPGM(" iTerm "); + SERIAL_ECHO(iTerm_bed); + SERIAL_ECHOPGM(" dTerm "); + SERIAL_ECHOLN(dTerm_bed); + #endif //PID_BED_DEBUG + + return pid_output; + } +#endif //PIDTEMPBED + +/** + * Manage heating activities for extruder hot-ends and a heated bed + * - Acquire updated temperature readings + * - Also resets the watchdog timer + * - Invoke thermal runaway protection + * - Manage extruder auto-fan + * - Apply filament width to the extrusion rate (may move) + * - Update the heated bed PID output value + */ +void Temperature::manage_heater() { + + if (!temp_meas_ready) return; + + updateTemperaturesFromRawValues(); // also resets the watchdog + + #if ENABLED(HEATER_0_USES_MAX6675) + float ct = current_temperature[0]; + if (ct > min(HEATER_0_MAXTEMP, 1023)) max_temp_error(0); + if (ct < max(HEATER_0_MINTEMP, 0.01)) min_temp_error(0); + #endif + + #if (ENABLED(THERMAL_PROTECTION_HOTENDS) && WATCH_TEMP_PERIOD > 0) || (ENABLED(THERMAL_PROTECTION_BED) && WATCH_BED_TEMP_PERIOD > 0) || DISABLED(PIDTEMPBED) || HAS_AUTO_FAN + millis_t ms = millis(); + #endif + + // Loop through all hotends + HOTEND_LOOP() { + + #if ENABLED(THERMAL_PROTECTION_HOTENDS) + thermal_runaway_protection(&thermal_runaway_state_machine[e], &thermal_runaway_timer[e], current_temperature[e], target_temperature[e], e, THERMAL_PROTECTION_PERIOD, THERMAL_PROTECTION_HYSTERESIS); + #endif + + float pid_output = get_pid_output(e); + + // Check if temperature is within the correct range + soft_pwm[e] = (current_temperature[e] > minttemp[e] || is_preheating(e)) && current_temperature[e] < maxttemp[e] ? (int)pid_output >> 1 : 0; + + // Check if the temperature is failing to increase + #if ENABLED(THERMAL_PROTECTION_HOTENDS) && WATCH_TEMP_PERIOD > 0 + + // Is it time to check this extruder's heater? + if (watch_heater_next_ms[e] && ELAPSED(ms, watch_heater_next_ms[e])) { + // Has it failed to increase enough? + if (degHotend(e) < watch_target_temp[e]) { + // Stop! + _temp_error(e, PSTR(MSG_T_HEATING_FAILED), PSTR(MSG_HEATING_FAILED_LCD)); + } + else { + // Start again if the target is still far off + start_watching_heater(e); + } + } + + #endif // THERMAL_PROTECTION_HOTENDS + + // Check if the temperature is failing to increase + #if ENABLED(THERMAL_PROTECTION_BED) && WATCH_BED_TEMP_PERIOD > 0 + + // Is it time to check the bed? + if (watch_bed_next_ms && ELAPSED(ms, watch_bed_next_ms)) { + // Has it failed to increase enough? + if (degBed() < watch_target_bed_temp) { + // Stop! + _temp_error(-1, PSTR(MSG_T_HEATING_FAILED), PSTR(MSG_HEATING_FAILED_LCD)); + } + else { + // Start again if the target is still far off + start_watching_bed(); + } + } + + #endif // THERMAL_PROTECTION_HOTENDS + + #if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT) + if (fabs(current_temperature[0] - redundant_temperature) > MAX_REDUNDANT_TEMP_SENSOR_DIFF) { + _temp_error(0, PSTR(MSG_REDUNDANCY), PSTR(MSG_ERR_REDUNDANT_TEMP)); + } + #endif + + } // Hotends Loop + + #if HAS_AUTO_FAN + if (ELAPSED(ms, next_auto_fan_check_ms)) { // only need to check fan state very infrequently + checkExtruderAutoFans(); + next_auto_fan_check_ms = ms + 2500UL; + } + #endif + + // Control the extruder rate based on the width sensor + #if ENABLED(FILAMENT_WIDTH_SENSOR) + if (filament_sensor) { + meas_shift_index = filwidth_delay_index1 - meas_delay_cm; + if (meas_shift_index < 0) meas_shift_index += MAX_MEASUREMENT_DELAY + 1; //loop around buffer if needed + + // Get the delayed info and add 100 to reconstitute to a percent of + // the nominal filament diameter then square it to get an area + meas_shift_index = constrain(meas_shift_index, 0, MAX_MEASUREMENT_DELAY); + float vm = pow((measurement_delay[meas_shift_index] + 100.0) * 0.01, 2); + NOLESS(vm, 0.01); + volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM] = vm; + } + #endif //FILAMENT_WIDTH_SENSOR + + #if DISABLED(PIDTEMPBED) + if (PENDING(ms, next_bed_check_ms)) return; + next_bed_check_ms = ms + BED_CHECK_INTERVAL; + #endif + + #if TEMP_SENSOR_BED != 0 + + #if HAS_THERMALLY_PROTECTED_BED + thermal_runaway_protection(&thermal_runaway_bed_state_machine, &thermal_runaway_bed_timer, current_temperature_bed, target_temperature_bed, -1, THERMAL_PROTECTION_BED_PERIOD, THERMAL_PROTECTION_BED_HYSTERESIS); + #endif + + #if ENABLED(PIDTEMPBED) + float pid_output = get_pid_output_bed(); + + soft_pwm_bed = current_temperature_bed > BED_MINTEMP && current_temperature_bed < BED_MAXTEMP ? (int)pid_output >> 1 : 0; + + #elif ENABLED(BED_LIMIT_SWITCHING) + // Check if temperature is within the correct band + if (current_temperature_bed > BED_MINTEMP && current_temperature_bed < BED_MAXTEMP) { + if (current_temperature_bed >= target_temperature_bed + BED_HYSTERESIS) + soft_pwm_bed = 0; + else if (current_temperature_bed <= target_temperature_bed - (BED_HYSTERESIS)) + soft_pwm_bed = MAX_BED_POWER >> 1; + } + else { + soft_pwm_bed = 0; + WRITE_HEATER_BED(LOW); + } + #else // !PIDTEMPBED && !BED_LIMIT_SWITCHING + // Check if temperature is within the correct range + if (current_temperature_bed > BED_MINTEMP && current_temperature_bed < BED_MAXTEMP) { + soft_pwm_bed = current_temperature_bed < target_temperature_bed ? MAX_BED_POWER >> 1 : 0; + } + else { + soft_pwm_bed = 0; + WRITE_HEATER_BED(LOW); + } + #endif + #endif //TEMP_SENSOR_BED != 0 +} + +#define PGM_RD_W(x) (short)pgm_read_word(&x) + +// Derived from RepRap FiveD extruder::getTemperature() +// For hot end temperature measurement. +float Temperature::analog2temp(int raw, uint8_t e) { + #if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT) + if (e > HOTENDS) + #else + if (e >= HOTENDS) + #endif + { + SERIAL_ERROR_START; + SERIAL_ERROR((int)e); + SERIAL_ERRORLNPGM(MSG_INVALID_EXTRUDER_NUM); + kill(PSTR(MSG_KILLED)); + return 0.0; + } + + #if ENABLED(HEATER_0_USES_MAX6675) + if (e == 0) return 0.25 * raw; + #endif + + if (heater_ttbl_map[e] != NULL) { + float celsius = 0; + uint8_t i; + short(*tt)[][2] = (short(*)[][2])(heater_ttbl_map[e]); + + for (i = 1; i < heater_ttbllen_map[e]; i++) { + if (PGM_RD_W((*tt)[i][0]) > raw) { + celsius = PGM_RD_W((*tt)[i - 1][1]) + + (raw - PGM_RD_W((*tt)[i - 1][0])) * + (float)(PGM_RD_W((*tt)[i][1]) - PGM_RD_W((*tt)[i - 1][1])) / + (float)(PGM_RD_W((*tt)[i][0]) - PGM_RD_W((*tt)[i - 1][0])); + break; + } + } + + // Overflow: Set to last value in the table + if (i == heater_ttbllen_map[e]) celsius = PGM_RD_W((*tt)[i - 1][1]); + + return celsius; + } + return ((raw * ((5.0 * 100.0) / 1024.0) / OVERSAMPLENR) * (TEMP_SENSOR_AD595_GAIN)) + TEMP_SENSOR_AD595_OFFSET; +} + +// Derived from RepRap FiveD extruder::getTemperature() +// For bed temperature measurement. +float Temperature::analog2tempBed(int raw) { + #if ENABLED(BED_USES_THERMISTOR) + float celsius = 0; + byte i; + + for (i = 1; i < BEDTEMPTABLE_LEN; i++) { + if (PGM_RD_W(BEDTEMPTABLE[i][0]) > raw) { + celsius = PGM_RD_W(BEDTEMPTABLE[i - 1][1]) + + (raw - PGM_RD_W(BEDTEMPTABLE[i - 1][0])) * + (float)(PGM_RD_W(BEDTEMPTABLE[i][1]) - PGM_RD_W(BEDTEMPTABLE[i - 1][1])) / + (float)(PGM_RD_W(BEDTEMPTABLE[i][0]) - PGM_RD_W(BEDTEMPTABLE[i - 1][0])); + break; + } + } + + // Overflow: Set to last value in the table + if (i == BEDTEMPTABLE_LEN) celsius = PGM_RD_W(BEDTEMPTABLE[i - 1][1]); + + return celsius; + + #elif defined(BED_USES_AD595) + + return ((raw * ((5.0 * 100.0) / 1024.0) / OVERSAMPLENR) * (TEMP_SENSOR_AD595_GAIN)) + TEMP_SENSOR_AD595_OFFSET; + + #else + + UNUSED(raw); + return 0; + + #endif +} + +/** + * Get the raw values into the actual temperatures. + * The raw values are created in interrupt context, + * and this function is called from normal context + * as it would block the stepper routine. + */ +void Temperature::updateTemperaturesFromRawValues() { + #if ENABLED(HEATER_0_USES_MAX6675) + current_temperature_raw[0] = read_max6675(); + #endif + HOTEND_LOOP() { + current_temperature[e] = Temperature::analog2temp(current_temperature_raw[e], e); + } + current_temperature_bed = Temperature::analog2tempBed(current_temperature_bed_raw); + #if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT) + redundant_temperature = Temperature::analog2temp(redundant_temperature_raw, 1); + #endif + #if ENABLED(FILAMENT_WIDTH_SENSOR) + filament_width_meas = analog2widthFil(); + #endif + + #if ENABLED(USE_WATCHDOG) + // Reset the watchdog after we know we have a temperature measurement. + watchdog_reset(); + #endif + + CRITICAL_SECTION_START; + temp_meas_ready = false; + CRITICAL_SECTION_END; +} + + +#if ENABLED(FILAMENT_WIDTH_SENSOR) + + // Convert raw Filament Width to millimeters + float Temperature::analog2widthFil() { + return current_raw_filwidth / 16383.0 * 5.0; + //return current_raw_filwidth; + } + + // Convert raw Filament Width to a ratio + int Temperature::widthFil_to_size_ratio() { + float temp = filament_width_meas; + if (temp < MEASURED_LOWER_LIMIT) temp = filament_width_nominal; //assume sensor cut out + else NOMORE(temp, MEASURED_UPPER_LIMIT); + return filament_width_nominal / temp * 100; + } + +#endif + + +/** + * Initialize the temperature manager + * The manager is implemented by periodic calls to manage_heater() + */ +void Temperature::init() { + + #if MB(RUMBA) && ((TEMP_SENSOR_0==-1)||(TEMP_SENSOR_1==-1)||(TEMP_SENSOR_2==-1)||(TEMP_SENSOR_BED==-1)) + //disable RUMBA JTAG in case the thermocouple extension is plugged on top of JTAG connector + MCUCR = _BV(JTD); + MCUCR = _BV(JTD); + #endif + + // Finish init of mult hotend arrays + HOTEND_LOOP() { + // populate with the first value + maxttemp[e] = maxttemp[0]; + #if ENABLED(PIDTEMP) + temp_iState_min[e] = 0.0; + temp_iState_max[e] = (PID_INTEGRAL_DRIVE_MAX) / PID_PARAM(Ki, e); + #if ENABLED(PID_EXTRUSION_SCALING) + last_e_position = 0; + #endif + #endif //PIDTEMP + #if ENABLED(PIDTEMPBED) + temp_iState_min_bed = 0.0; + temp_iState_max_bed = (PID_BED_INTEGRAL_DRIVE_MAX) / bedKi; + #endif //PIDTEMPBED + } + + #if ENABLED(PIDTEMP) && ENABLED(PID_EXTRUSION_SCALING) + last_e_position = 0; + #endif + + #if HAS_HEATER_0 + SET_OUTPUT(HEATER_0_PIN); + #endif + #if HAS_HEATER_1 + SET_OUTPUT(HEATER_1_PIN); + #endif + #if HAS_HEATER_2 + SET_OUTPUT(HEATER_2_PIN); + #endif + #if HAS_HEATER_3 + SET_OUTPUT(HEATER_3_PIN); + #endif + #if HAS_HEATER_BED + SET_OUTPUT(HEATER_BED_PIN); + #endif + + #if ENABLED(FAST_PWM_FAN) || ENABLED(FAN_SOFT_PWM) + + #if HAS_FAN0 + SET_OUTPUT(FAN_PIN); + #if ENABLED(FAST_PWM_FAN) + setPwmFrequency(FAN_PIN, 1); // No prescaling. Pwm frequency = F_CPU/256/8 + #endif + #if ENABLED(FAN_SOFT_PWM) + soft_pwm_fan[0] = fanSpeedSoftPwm[0] / 2; + #endif + #endif + + #if HAS_FAN1 + SET_OUTPUT(FAN1_PIN); + #if ENABLED(FAST_PWM_FAN) + setPwmFrequency(FAN1_PIN, 1); // No prescaling. Pwm frequency = F_CPU/256/8 + #endif + #if ENABLED(FAN_SOFT_PWM) + soft_pwm_fan[1] = fanSpeedSoftPwm[1] / 2; + #endif + #endif + + #if HAS_FAN2 + SET_OUTPUT(FAN2_PIN); + #if ENABLED(FAST_PWM_FAN) + setPwmFrequency(FAN2_PIN, 1); // No prescaling. Pwm frequency = F_CPU/256/8 + #endif + #if ENABLED(FAN_SOFT_PWM) + soft_pwm_fan[2] = fanSpeedSoftPwm[2] / 2; + #endif + #endif + + #endif // FAST_PWM_FAN || FAN_SOFT_PWM + + #if ENABLED(HEATER_0_USES_MAX6675) + + #if DISABLED(SDSUPPORT) + OUT_WRITE(SCK_PIN, LOW); + OUT_WRITE(MOSI_PIN, HIGH); + OUT_WRITE(MISO_PIN, HIGH); + #else + OUT_WRITE(SS_PIN, HIGH); + #endif + + OUT_WRITE(MAX6675_SS, HIGH); + + #endif //HEATER_0_USES_MAX6675 + + #ifdef DIDR2 + #define ANALOG_SELECT(pin) do{ if (pin < 8) SBI(DIDR0, pin); else SBI(DIDR2, pin - 8); }while(0) + #else + #define ANALOG_SELECT(pin) do{ SBI(DIDR0, pin); }while(0) + #endif + + // Set analog inputs + ADCSRA = _BV(ADEN) | _BV(ADSC) | _BV(ADIF) | 0x07; + DIDR0 = 0; + #ifdef DIDR2 + DIDR2 = 0; + #endif + #if HAS_TEMP_0 + ANALOG_SELECT(TEMP_0_PIN); + #endif + #if HAS_TEMP_1 + ANALOG_SELECT(TEMP_1_PIN); + #endif + #if HAS_TEMP_2 + ANALOG_SELECT(TEMP_2_PIN); + #endif + #if HAS_TEMP_3 + ANALOG_SELECT(TEMP_3_PIN); + #endif + #if HAS_TEMP_BED + ANALOG_SELECT(TEMP_BED_PIN); + #endif + #if ENABLED(FILAMENT_WIDTH_SENSOR) + ANALOG_SELECT(FILWIDTH_PIN); + #endif + + #if HAS_AUTO_FAN_0 + pinMode(EXTRUDER_0_AUTO_FAN_PIN, OUTPUT); + #endif + #if HAS_AUTO_FAN_1 && (EXTRUDER_1_AUTO_FAN_PIN != EXTRUDER_0_AUTO_FAN_PIN) + pinMode(EXTRUDER_1_AUTO_FAN_PIN, OUTPUT); + #endif + #if HAS_AUTO_FAN_2 && (EXTRUDER_2_AUTO_FAN_PIN != EXTRUDER_0_AUTO_FAN_PIN) && (EXTRUDER_2_AUTO_FAN_PIN != EXTRUDER_1_AUTO_FAN_PIN) + pinMode(EXTRUDER_2_AUTO_FAN_PIN, OUTPUT); + #endif + #if HAS_AUTO_FAN_3 && (EXTRUDER_3_AUTO_FAN_PIN != EXTRUDER_0_AUTO_FAN_PIN) && (EXTRUDER_3_AUTO_FAN_PIN != EXTRUDER_1_AUTO_FAN_PIN) && (EXTRUDER_3_AUTO_FAN_PIN != EXTRUDER_2_AUTO_FAN_PIN) + pinMode(EXTRUDER_3_AUTO_FAN_PIN, OUTPUT); + #endif + + // Use timer0 for temperature measurement + // Interleave temperature interrupt with millies interrupt + OCR0B = 128; + SBI(TIMSK0, OCIE0B); + + // Wait for temperature measurement to settle + delay(250); + + #define TEMP_MIN_ROUTINE(NR) \ + minttemp[NR] = HEATER_ ## NR ## _MINTEMP; \ + while(analog2temp(minttemp_raw[NR], NR) < HEATER_ ## NR ## _MINTEMP) { \ + if (HEATER_ ## NR ## _RAW_LO_TEMP < HEATER_ ## NR ## _RAW_HI_TEMP) \ + minttemp_raw[NR] += OVERSAMPLENR; \ + else \ + minttemp_raw[NR] -= OVERSAMPLENR; \ + } + #define TEMP_MAX_ROUTINE(NR) \ + maxttemp[NR] = HEATER_ ## NR ## _MAXTEMP; \ + while(analog2temp(maxttemp_raw[NR], NR) > HEATER_ ## NR ## _MAXTEMP) { \ + if (HEATER_ ## NR ## _RAW_LO_TEMP < HEATER_ ## NR ## _RAW_HI_TEMP) \ + maxttemp_raw[NR] -= OVERSAMPLENR; \ + else \ + maxttemp_raw[NR] += OVERSAMPLENR; \ + } + + #ifdef HEATER_0_MINTEMP + TEMP_MIN_ROUTINE(0); + #endif + #ifdef HEATER_0_MAXTEMP + TEMP_MAX_ROUTINE(0); + #endif + #if HOTENDS > 1 + #ifdef HEATER_1_MINTEMP + TEMP_MIN_ROUTINE(1); + #endif + #ifdef HEATER_1_MAXTEMP + TEMP_MAX_ROUTINE(1); + #endif + #if HOTENDS > 2 + #ifdef HEATER_2_MINTEMP + TEMP_MIN_ROUTINE(2); + #endif + #ifdef HEATER_2_MAXTEMP + TEMP_MAX_ROUTINE(2); + #endif + #if HOTENDS > 3 + #ifdef HEATER_3_MINTEMP + TEMP_MIN_ROUTINE(3); + #endif + #ifdef HEATER_3_MAXTEMP + TEMP_MAX_ROUTINE(3); + #endif + #endif // HOTENDS > 3 + #endif // HOTENDS > 2 + #endif // HOTENDS > 1 + + #ifdef BED_MINTEMP + while(analog2tempBed(bed_minttemp_raw) < BED_MINTEMP) { + #if HEATER_BED_RAW_LO_TEMP < HEATER_BED_RAW_HI_TEMP + bed_minttemp_raw += OVERSAMPLENR; + #else + bed_minttemp_raw -= OVERSAMPLENR; + #endif + } + #endif //BED_MINTEMP + #ifdef BED_MAXTEMP + while (analog2tempBed(bed_maxttemp_raw) > BED_MAXTEMP) { + #if HEATER_BED_RAW_LO_TEMP < HEATER_BED_RAW_HI_TEMP + bed_maxttemp_raw -= OVERSAMPLENR; + #else + bed_maxttemp_raw += OVERSAMPLENR; + #endif + } + #endif //BED_MAXTEMP +} + +#if ENABLED(THERMAL_PROTECTION_HOTENDS) && WATCH_TEMP_PERIOD > 0 + /** + * Start Heating Sanity Check for hotends that are below + * their target temperature by a configurable margin. + * This is called when the temperature is set. (M104, M109) + */ + void Temperature::start_watching_heater(uint8_t e) { + #if HOTENDS == 1 + UNUSED(e); + #endif + if (degHotend(HOTEND_INDEX) < degTargetHotend(HOTEND_INDEX) - (WATCH_TEMP_INCREASE + TEMP_HYSTERESIS + 1)) { + watch_target_temp[HOTEND_INDEX] = degHotend(HOTEND_INDEX) + WATCH_TEMP_INCREASE; + watch_heater_next_ms[HOTEND_INDEX] = millis() + (WATCH_TEMP_PERIOD) * 1000UL; + } + else + watch_heater_next_ms[HOTEND_INDEX] = 0; + } +#endif + +#if ENABLED(THERMAL_PROTECTION_BED) && WATCH_BED_TEMP_PERIOD > 0 + /** + * Start Heating Sanity Check for hotends that are below + * their target temperature by a configurable margin. + * This is called when the temperature is set. (M140, M190) + */ + void Temperature::start_watching_bed() { + if (degBed() < degTargetBed() - (WATCH_BED_TEMP_INCREASE + TEMP_BED_HYSTERESIS + 1)) { + watch_target_bed_temp = degBed() + WATCH_BED_TEMP_INCREASE; + watch_bed_next_ms = millis() + (WATCH_BED_TEMP_PERIOD) * 1000UL; + } + else + watch_bed_next_ms = 0; + } +#endif + +#if ENABLED(THERMAL_PROTECTION_HOTENDS) || HAS_THERMALLY_PROTECTED_BED + + #if ENABLED(THERMAL_PROTECTION_HOTENDS) + Temperature::TRState Temperature::thermal_runaway_state_machine[HOTENDS] = { TRInactive }; + millis_t Temperature::thermal_runaway_timer[HOTENDS] = { 0 }; + #endif + + #if HAS_THERMALLY_PROTECTED_BED + Temperature::TRState Temperature::thermal_runaway_bed_state_machine = TRInactive; + millis_t Temperature::thermal_runaway_bed_timer; + #endif + + void Temperature::thermal_runaway_protection(Temperature::TRState* state, millis_t* timer, float temperature, float target_temperature, int heater_id, int period_seconds, int hysteresis_degc) { + + static float tr_target_temperature[HOTENDS + 1] = { 0.0 }; + + /** + SERIAL_ECHO_START; + SERIAL_ECHOPGM("Thermal Thermal Runaway Running. Heater ID: "); + if (heater_id < 0) SERIAL_ECHOPGM("bed"); else SERIAL_ECHO(heater_id); + SERIAL_ECHOPAIR(" ; State:", *state); + SERIAL_ECHOPAIR(" ; Timer:", *timer); + SERIAL_ECHOPAIR(" ; Temperature:", temperature); + SERIAL_ECHOPAIR(" ; Target Temp:", target_temperature); + SERIAL_EOL; + */ + + int heater_index = heater_id >= 0 ? heater_id : HOTENDS; + + // If the target temperature changes, restart + if (tr_target_temperature[heater_index] != target_temperature) { + tr_target_temperature[heater_index] = target_temperature; + *state = target_temperature > 0 ? TRFirstHeating : TRInactive; + } + + 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 (temperature < tr_target_temperature[heater_index]) break; + *state = TRStable; + // While the temperature is stable watch for a bad temperature + case TRStable: + if (temperature < tr_target_temperature[heater_index] - hysteresis_degc && ELAPSED(millis(), *timer)) + *state = TRRunaway; + else { + *timer = millis() + period_seconds * 1000UL; + break; + } + case TRRunaway: + _temp_error(heater_id, PSTR(MSG_T_THERMAL_RUNAWAY), PSTR(MSG_THERMAL_RUNAWAY)); + } + } + +#endif // THERMAL_PROTECTION_HOTENDS || THERMAL_PROTECTION_BED + +void Temperature::disable_all_heaters() { + HOTEND_LOOP() setTargetHotend(0, e); + setTargetBed(0); + + // If all heaters go down then for sure our print job has stopped + print_job_timer.stop(); + + #define DISABLE_HEATER(NR) { \ + setTargetHotend(0, NR); \ + soft_pwm[NR] = 0; \ + WRITE_HEATER_ ## NR (LOW); \ + } + + #if HAS_TEMP_HOTEND + setTargetHotend(0, 0); + soft_pwm[0] = 0; + WRITE_HEATER_0P(LOW); // Should HEATERS_PARALLEL apply here? Then change to DISABLE_HEATER(0) + #endif + + #if HOTENDS > 1 && HAS_TEMP_1 + DISABLE_HEATER(1); + #endif + + #if HOTENDS > 2 && HAS_TEMP_2 + DISABLE_HEATER(2); + #endif + + #if HOTENDS > 3 && HAS_TEMP_3 + DISABLE_HEATER(3); + #endif + + #if HAS_TEMP_BED + target_temperature_bed = 0; + soft_pwm_bed = 0; + #if HAS_HEATER_BED + WRITE_HEATER_BED(LOW); + #endif + #endif +} + +#if ENABLED(HEATER_0_USES_MAX6675) + + #define MAX6675_HEAT_INTERVAL 250u + + #if ENABLED(MAX6675_IS_MAX31855) + uint32_t max6675_temp = 2000; + #define MAX6675_ERROR_MASK 7 + #define MAX6675_DISCARD_BITS 18 + #define MAX6675_SPEED_BITS (_BV(SPR1)) // clock ÷ 64 + #else + uint16_t max6675_temp = 2000; + #define MAX6675_ERROR_MASK 4 + #define MAX6675_DISCARD_BITS 3 + #define MAX6675_SPEED_BITS (_BV(SPR0)) // clock ÷ 16 + #endif + + int Temperature::read_max6675() { + + static millis_t next_max6675_ms = 0; + + millis_t ms = millis(); + + if (PENDING(ms, next_max6675_ms)) return (int)max6675_temp; + + next_max6675_ms = ms + MAX6675_HEAT_INTERVAL; + + CBI( + #ifdef PRR + PRR + #elif defined(PRR0) + PRR0 + #endif + , PRSPI); + SPCR = _BV(MSTR) | _BV(SPE) | MAX6675_SPEED_BITS; + + WRITE(MAX6675_SS, 0); // enable TT_MAX6675 + + // ensure 100ns delay - a bit extra is fine + asm("nop");//50ns on 20Mhz, 62.5ns on 16Mhz + asm("nop");//50ns on 20Mhz, 62.5ns on 16Mhz + + // Read a big-endian temperature value + max6675_temp = 0; + for (uint8_t i = sizeof(max6675_temp); i--;) { + SPDR = 0; + for (;!TEST(SPSR, SPIF);); + max6675_temp |= SPDR; + if (i > 0) max6675_temp <<= 8; // shift left if not the last byte + } + + WRITE(MAX6675_SS, 1); // disable TT_MAX6675 + + if (max6675_temp & MAX6675_ERROR_MASK) + max6675_temp = 4000; // thermocouple open + else + max6675_temp >>= MAX6675_DISCARD_BITS; + + return (int)max6675_temp; + } + +#endif //HEATER_0_USES_MAX6675 + +/** + * Get raw temperatures + */ +void Temperature::set_current_temp_raw() { + #if HAS_TEMP_0 && DISABLED(HEATER_0_USES_MAX6675) + current_temperature_raw[0] = raw_temp_value[0]; + #endif + #if HAS_TEMP_1 + #if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT) + redundant_temperature_raw = raw_temp_value[1]; + #else + current_temperature_raw[1] = raw_temp_value[1]; + #endif + #if HAS_TEMP_2 + current_temperature_raw[2] = raw_temp_value[2]; + #if HAS_TEMP_3 + current_temperature_raw[3] = raw_temp_value[3]; + #endif + #endif + #endif + current_temperature_bed_raw = raw_temp_bed_value; + temp_meas_ready = true; +} + +/** + * Timer 0 is shared with millies + * - Manage PWM to all the heaters and fan + * - Update the raw temperature values + * - Check new temperature values for MIN/MAX errors + * - Step the babysteps value for each axis towards 0 + */ +ISR(TIMER0_COMPB_vect) { Temperature::isr(); } + +void Temperature::isr() { + + static unsigned char temp_count = 0; + static TempState temp_state = StartupDelay; + static unsigned char pwm_count = _BV(SOFT_PWM_SCALE); + + // Static members for each heater + #if ENABLED(SLOW_PWM_HEATERS) + static unsigned char slow_pwm_count = 0; + #define ISR_STATICS(n) \ + static unsigned char soft_pwm_ ## n; \ + static unsigned char state_heater_ ## n = 0; \ + static unsigned char state_timer_heater_ ## n = 0 + #else + #define ISR_STATICS(n) static unsigned char soft_pwm_ ## n + #endif + + // Statics per heater + ISR_STATICS(0); + #if (HOTENDS > 1) || ENABLED(HEATERS_PARALLEL) + ISR_STATICS(1); + #if HOTENDS > 2 + ISR_STATICS(2); + #if HOTENDS > 3 + ISR_STATICS(3); + #endif + #endif + #endif + #if HAS_HEATER_BED + ISR_STATICS(BED); + #endif + + #if ENABLED(FILAMENT_WIDTH_SENSOR) + static unsigned long raw_filwidth_value = 0; + #endif + + #if DISABLED(SLOW_PWM_HEATERS) + /** + * standard PWM modulation + */ + if (pwm_count == 0) { + soft_pwm_0 = soft_pwm[0]; + if (soft_pwm_0 > 0) { + WRITE_HEATER_0(1); + } + else WRITE_HEATER_0P(0); // If HEATERS_PARALLEL should apply, change to WRITE_HEATER_0 + + #if HOTENDS > 1 + soft_pwm_1 = soft_pwm[1]; + WRITE_HEATER_1(soft_pwm_1 > 0 ? 1 : 0); + #if HOTENDS > 2 + soft_pwm_2 = soft_pwm[2]; + WRITE_HEATER_2(soft_pwm_2 > 0 ? 1 : 0); + #if HOTENDS > 3 + soft_pwm_3 = soft_pwm[3]; + WRITE_HEATER_3(soft_pwm_3 > 0 ? 1 : 0); + #endif + #endif + #endif + + #if HAS_HEATER_BED + soft_pwm_BED = soft_pwm_bed; + WRITE_HEATER_BED(soft_pwm_BED > 0 ? 1 : 0); + #endif + + #if ENABLED(FAN_SOFT_PWM) + #if HAS_FAN0 + soft_pwm_fan[0] = fanSpeedSoftPwm[0] / 2; + WRITE_FAN(soft_pwm_fan[0] > 0 ? 1 : 0); + #endif + #if HAS_FAN1 + soft_pwm_fan[1] = fanSpeedSoftPwm[1] / 2; + WRITE_FAN1(soft_pwm_fan[1] > 0 ? 1 : 0); + #endif + #if HAS_FAN2 + soft_pwm_fan[2] = fanSpeedSoftPwm[2] / 2; + WRITE_FAN2(soft_pwm_fan[2] > 0 ? 1 : 0); + #endif + #endif + } + + if (soft_pwm_0 < pwm_count) WRITE_HEATER_0(0); + #if HOTENDS > 1 + if (soft_pwm_1 < pwm_count) WRITE_HEATER_1(0); + #if HOTENDS > 2 + if (soft_pwm_2 < pwm_count) WRITE_HEATER_2(0); + #if HOTENDS > 3 + if (soft_pwm_3 < pwm_count) WRITE_HEATER_3(0); + #endif + #endif + #endif + + #if HAS_HEATER_BED + if (soft_pwm_BED < pwm_count) WRITE_HEATER_BED(0); + #endif + + #if ENABLED(FAN_SOFT_PWM) + #if HAS_FAN0 + if (soft_pwm_fan[0] < pwm_count) WRITE_FAN(0); + #endif + #if HAS_FAN1 + if (soft_pwm_fan[1] < pwm_count) WRITE_FAN1(0); + #endif + #if HAS_FAN2 + if (soft_pwm_fan[2] < pwm_count) WRITE_FAN2(0); + #endif + #endif + + pwm_count += _BV(SOFT_PWM_SCALE); + pwm_count &= 0x7f; + + #else // SLOW_PWM_HEATERS + + /** + * SLOW PWM HEATERS + * + * for heaters drived by relay + */ + #ifndef MIN_STATE_TIME + #define MIN_STATE_TIME 16 // MIN_STATE_TIME * 65.5 = time in milliseconds + #endif + + // Macros for Slow PWM timer logic - HEATERS_PARALLEL applies + #define _SLOW_PWM_ROUTINE(NR, src) \ + soft_pwm_ ## NR = src; \ + if (soft_pwm_ ## NR > 0) { \ + if (state_timer_heater_ ## NR == 0) { \ + if (state_heater_ ## NR == 0) state_timer_heater_ ## NR = MIN_STATE_TIME; \ + state_heater_ ## NR = 1; \ + WRITE_HEATER_ ## NR(1); \ + } \ + } \ + else { \ + if (state_timer_heater_ ## NR == 0) { \ + if (state_heater_ ## NR == 1) state_timer_heater_ ## NR = MIN_STATE_TIME; \ + state_heater_ ## NR = 0; \ + WRITE_HEATER_ ## NR(0); \ + } \ + } + #define SLOW_PWM_ROUTINE(n) _SLOW_PWM_ROUTINE(n, soft_pwm[n]) + + #define PWM_OFF_ROUTINE(NR) \ + if (soft_pwm_ ## NR < slow_pwm_count) { \ + if (state_timer_heater_ ## NR == 0) { \ + if (state_heater_ ## NR == 1) state_timer_heater_ ## NR = MIN_STATE_TIME; \ + state_heater_ ## NR = 0; \ + WRITE_HEATER_ ## NR (0); \ + } \ + } + + if (slow_pwm_count == 0) { + + SLOW_PWM_ROUTINE(0); // EXTRUDER 0 + #if HOTENDS > 1 + SLOW_PWM_ROUTINE(1); // EXTRUDER 1 + #if HOTENDS > 2 + SLOW_PWM_ROUTINE(2); // EXTRUDER 2 + #if HOTENDS > 3 + SLOW_PWM_ROUTINE(3); // EXTRUDER 3 + #endif + #endif + #endif + #if HAS_HEATER_BED + _SLOW_PWM_ROUTINE(BED, soft_pwm_bed); // BED + #endif + + } // slow_pwm_count == 0 + + PWM_OFF_ROUTINE(0); // EXTRUDER 0 + #if HOTENDS > 1 + PWM_OFF_ROUTINE(1); // EXTRUDER 1 + #if HOTENDS > 2 + PWM_OFF_ROUTINE(2); // EXTRUDER 2 + #if HOTENDS > 3 + PWM_OFF_ROUTINE(3); // EXTRUDER 3 + #endif + #endif + #endif + #if HAS_HEATER_BED + PWM_OFF_ROUTINE(BED); // BED + #endif + + #if ENABLED(FAN_SOFT_PWM) + if (pwm_count == 0) { + #if HAS_FAN0 + soft_pwm_fan[0] = fanSpeedSoftPwm[0] / 2; + WRITE_FAN(soft_pwm_fan[0] > 0 ? 1 : 0); + #endif + #if HAS_FAN1 + soft_pwm_fan[1] = fanSpeedSoftPwm[1] / 2; + WRITE_FAN1(soft_pwm_fan[1] > 0 ? 1 : 0); + #endif + #if HAS_FAN2 + soft_pwm_fan[2] = fanSpeedSoftPwm[2] / 2; + WRITE_FAN2(soft_pwm_fan[2] > 0 ? 1 : 0); + #endif + } + #if HAS_FAN0 + if (soft_pwm_fan[0] < pwm_count) WRITE_FAN(0); + #endif + #if HAS_FAN1 + if (soft_pwm_fan[1] < pwm_count) WRITE_FAN1(0); + #endif + #if HAS_FAN2 + if (soft_pwm_fan[2] < pwm_count) WRITE_FAN2(0); + #endif + #endif //FAN_SOFT_PWM + + pwm_count += _BV(SOFT_PWM_SCALE); + pwm_count &= 0x7f; + + // increment slow_pwm_count only every 64 pwm_count circa 65.5ms + if ((pwm_count % 64) == 0) { + slow_pwm_count++; + slow_pwm_count &= 0x7f; + + // EXTRUDER 0 + if (state_timer_heater_0 > 0) state_timer_heater_0--; + #if HOTENDS > 1 // EXTRUDER 1 + if (state_timer_heater_1 > 0) state_timer_heater_1--; + #if HOTENDS > 2 // EXTRUDER 2 + if (state_timer_heater_2 > 0) state_timer_heater_2--; + #if HOTENDS > 3 // EXTRUDER 3 + if (state_timer_heater_3 > 0) state_timer_heater_3--; + #endif + #endif + #endif + #if HAS_HEATER_BED + if (state_timer_heater_BED > 0) state_timer_heater_BED--; + #endif + } // (pwm_count % 64) == 0 + + #endif // SLOW_PWM_HEATERS + + #define SET_ADMUX_ADCSRA(pin) ADMUX = _BV(REFS0) | (pin & 0x07); SBI(ADCSRA, ADSC) + #ifdef MUX5 + #define START_ADC(pin) if (pin > 7) ADCSRB = _BV(MUX5); else ADCSRB = 0; SET_ADMUX_ADCSRA(pin) + #else + #define START_ADC(pin) ADCSRB = 0; SET_ADMUX_ADCSRA(pin) + #endif + + // Prepare or measure a sensor, each one every 12th frame + switch (temp_state) { + case PrepareTemp_0: + #if HAS_TEMP_0 + START_ADC(TEMP_0_PIN); + #endif + lcd_buttons_update(); + temp_state = MeasureTemp_0; + break; + case MeasureTemp_0: + #if HAS_TEMP_0 + raw_temp_value[0] += ADC; + #endif + temp_state = PrepareTemp_BED; + break; + + case PrepareTemp_BED: + #if HAS_TEMP_BED + START_ADC(TEMP_BED_PIN); + #endif + lcd_buttons_update(); + temp_state = MeasureTemp_BED; + break; + case MeasureTemp_BED: + #if HAS_TEMP_BED + raw_temp_bed_value += ADC; + #endif + temp_state = PrepareTemp_1; + break; + + case PrepareTemp_1: + #if HAS_TEMP_1 + START_ADC(TEMP_1_PIN); + #endif + lcd_buttons_update(); + temp_state = MeasureTemp_1; + break; + case MeasureTemp_1: + #if HAS_TEMP_1 + raw_temp_value[1] += ADC; + #endif + temp_state = PrepareTemp_2; + break; + + case PrepareTemp_2: + #if HAS_TEMP_2 + START_ADC(TEMP_2_PIN); + #endif + lcd_buttons_update(); + temp_state = MeasureTemp_2; + break; + case MeasureTemp_2: + #if HAS_TEMP_2 + raw_temp_value[2] += ADC; + #endif + temp_state = PrepareTemp_3; + break; + + case PrepareTemp_3: + #if HAS_TEMP_3 + START_ADC(TEMP_3_PIN); + #endif + lcd_buttons_update(); + temp_state = MeasureTemp_3; + break; + case MeasureTemp_3: + #if HAS_TEMP_3 + raw_temp_value[3] += ADC; + #endif + temp_state = Prepare_FILWIDTH; + break; + + case Prepare_FILWIDTH: + #if ENABLED(FILAMENT_WIDTH_SENSOR) + START_ADC(FILWIDTH_PIN); + #endif + lcd_buttons_update(); + temp_state = Measure_FILWIDTH; + break; + case Measure_FILWIDTH: + #if ENABLED(FILAMENT_WIDTH_SENSOR) + // raw_filwidth_value += ADC; //remove to use an IIR filter approach + if (ADC > 102) { //check that ADC is reading a voltage > 0.5 volts, otherwise don't take in the data. + raw_filwidth_value -= (raw_filwidth_value >> 7); //multiply raw_filwidth_value by 127/128 + raw_filwidth_value += ((unsigned long)ADC << 7); //add new ADC reading + } + #endif + temp_state = PrepareTemp_0; + temp_count++; + break; + + case StartupDelay: + temp_state = PrepareTemp_0; + break; + + // default: + // SERIAL_ERROR_START; + // SERIAL_ERRORLNPGM("Temp measurement error!"); + // break; + } // switch(temp_state) + + if (temp_count >= OVERSAMPLENR) { // 10 * 16 * 1/(16000000/64/256) = 164ms. + // Update the raw values if they've been read. Else we could be updating them during reading. + if (!temp_meas_ready) set_current_temp_raw(); + + // Filament Sensor - can be read any time since IIR filtering is used + #if ENABLED(FILAMENT_WIDTH_SENSOR) + current_raw_filwidth = raw_filwidth_value >> 10; // Divide to get to 0-16384 range since we used 1/128 IIR filter approach + #endif + + temp_count = 0; + for (int i = 0; i < 4; i++) raw_temp_value[i] = 0; + raw_temp_bed_value = 0; + + #if HAS_TEMP_0 && DISABLED(HEATER_0_USES_MAX6675) + #if HEATER_0_RAW_LO_TEMP > HEATER_0_RAW_HI_TEMP + #define GE0 <= + #else + #define GE0 >= + #endif + if (current_temperature_raw[0] GE0 maxttemp_raw[0]) max_temp_error(0); + if (minttemp_raw[0] GE0 current_temperature_raw[0] && !is_preheating(0) && target_temperature[0] > 0.0f) { + #ifdef MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED + if (++consecutive_low_temperature_error[0] >= MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED) + #endif + min_temp_error(0); + } + #ifdef MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED + else + consecutive_low_temperature_error[0] = 0; + #endif + #endif + + #if HAS_TEMP_1 && HOTENDS > 1 + #if HEATER_1_RAW_LO_TEMP > HEATER_1_RAW_HI_TEMP + #define GE1 <= + #else + #define GE1 >= + #endif + if (current_temperature_raw[1] GE1 maxttemp_raw[1]) max_temp_error(1); + if (minttemp_raw[1] GE1 current_temperature_raw[1] && !is_preheating(1) && target_temperature[1] > 0.0f) { + #ifdef MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED + if (++consecutive_low_temperature_error[1] >= MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED) + #endif + min_temp_error(1); + } + #ifdef MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED + else + consecutive_low_temperature_error[1] = 0; + #endif + #endif // TEMP_SENSOR_1 + + #if HAS_TEMP_2 && HOTENDS > 2 + #if HEATER_2_RAW_LO_TEMP > HEATER_2_RAW_HI_TEMP + #define GE2 <= + #else + #define GE2 >= + #endif + if (current_temperature_raw[2] GE2 maxttemp_raw[2]) max_temp_error(2); + if (minttemp_raw[2] GE2 current_temperature_raw[2] && !is_preheating(2) && target_temperature[2] > 0.0f) { + #ifdef MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED + if (++consecutive_low_temperature_error[2] >= MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED) + #endif + min_temp_error(2); + } + #ifdef MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED + else + consecutive_low_temperature_error[2] = 0; + #endif + #endif // TEMP_SENSOR_2 + + #if HAS_TEMP_3 && HOTENDS > 3 + #if HEATER_3_RAW_LO_TEMP > HEATER_3_RAW_HI_TEMP + #define GE3 <= + #else + #define GE3 >= + #endif + if (current_temperature_raw[3] GE3 maxttemp_raw[3]) max_temp_error(3); + if (minttemp_raw[3] GE3 current_temperature_raw[3] && !is_preheating(3) && target_temperature[3] > 0.0f) { + #ifdef MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED + if (++consecutive_low_temperature_error[3] >= MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED) + #endif + min_temp_error(3); + } + #ifdef MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED + else + consecutive_low_temperature_error[3] = 0; + #endif + #endif // TEMP_SENSOR_3 + + #if HAS_TEMP_BED + #if HEATER_BED_RAW_LO_TEMP > HEATER_BED_RAW_HI_TEMP + #define GEBED <= + #else + #define GEBED >= + #endif + if (current_temperature_bed_raw GEBED bed_maxttemp_raw) _temp_error(-1, PSTR(MSG_T_MAXTEMP), PSTR(MSG_ERR_MAXTEMP_BED)); + if (bed_minttemp_raw GEBED current_temperature_bed_raw) _temp_error(-1, PSTR(MSG_T_MINTEMP), PSTR(MSG_ERR_MINTEMP_BED)); + #endif + + } // temp_count >= OVERSAMPLENR + + #if ENABLED(BABYSTEPPING) + for (uint8_t axis = X_AXIS; axis <= Z_AXIS; axis++) { + int curTodo = babystepsTodo[axis]; //get rid of volatile for performance + + if (curTodo > 0) { + stepper.babystep(axis,/*fwd*/true); + babystepsTodo[axis]--; //fewer to do next time + } + else if (curTodo < 0) { + stepper.babystep(axis,/*fwd*/false); + babystepsTodo[axis]++; //fewer to do next time + } + } + #endif //BABYSTEPPING +} diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/temperature.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/temperature.h new file mode 100644 index 00000000..ffb47a59 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/temperature.h @@ -0,0 +1,465 @@ +/** + * 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 . + * + */ + +/** + * temperature.h - temperature controller + */ + +#ifndef TEMPERATURE_H +#define TEMPERATURE_H + +#include "planner.h" +#include "thermistortables.h" + +#include "MarlinConfig.h" + +#if ENABLED(PID_EXTRUSION_SCALING) + #include "stepper.h" +#endif + +#ifndef SOFT_PWM_SCALE + #define SOFT_PWM_SCALE 0 +#endif + +#if HOTENDS == 1 + #define HOTEND_LOOP() const int8_t e = 0; + #define HOTEND_INDEX 0 + #define EXTRUDER_IDX 0 +#else + #define HOTEND_LOOP() for (int8_t e = 0; e < HOTENDS; e++) + #define HOTEND_INDEX e + #define EXTRUDER_IDX active_extruder +#endif + +class Temperature { + + public: + + static float current_temperature[HOTENDS], + current_temperature_bed; + static int current_temperature_raw[HOTENDS], + target_temperature[HOTENDS], + current_temperature_bed_raw, + target_temperature_bed; + + #if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT) + static float redundant_temperature; + #endif + + static unsigned char soft_pwm_bed; + + #if ENABLED(FAN_SOFT_PWM) + static unsigned char fanSpeedSoftPwm[FAN_COUNT]; + #endif + + #if ENABLED(PIDTEMP) || ENABLED(PIDTEMPBED) + #define PID_dT ((OVERSAMPLENR * 12.0)/(F_CPU / 64.0 / 256.0)) + #endif + + #if ENABLED(PIDTEMP) + + #if ENABLED(PID_PARAMS_PER_HOTEND) && HOTENDS > 1 + + static float Kp[HOTENDS], Ki[HOTENDS], Kd[HOTENDS]; + #if ENABLED(PID_EXTRUSION_SCALING) + static float Kc[HOTENDS]; + #endif + #define PID_PARAM(param, h) Temperature::param[h] + + #else + + static float Kp, Ki, Kd; + #if ENABLED(PID_EXTRUSION_SCALING) + static float Kc; + #endif + #define PID_PARAM(param, h) Temperature::param + + #endif // PID_PARAMS_PER_HOTEND + + // Apply the scale factors to the PID values + #define scalePID_i(i) ( (i) * PID_dT ) + #define unscalePID_i(i) ( (i) / PID_dT ) + #define scalePID_d(d) ( (d) / PID_dT ) + #define unscalePID_d(d) ( (d) * PID_dT ) + + #endif + + #if ENABLED(PIDTEMPBED) + static float bedKp, bedKi, bedKd; + #endif + + #if ENABLED(BABYSTEPPING) + static volatile int babystepsTodo[3]; + #endif + + #if ENABLED(THERMAL_PROTECTION_HOTENDS) && WATCH_TEMP_PERIOD > 0 + static int watch_target_temp[HOTENDS]; + static millis_t watch_heater_next_ms[HOTENDS]; + #endif + + #if ENABLED(THERMAL_PROTECTION_BED) && WATCH_BED_TEMP_PERIOD > 0 + static int watch_target_bed_temp; + static millis_t watch_bed_next_ms; + #endif + + #if ENABLED(PREVENT_DANGEROUS_EXTRUDE) + static bool allow_cold_extrude; + static float extrude_min_temp; + static bool tooColdToExtrude(uint8_t e) { + #if HOTENDS == 1 + UNUSED(e); + #endif + return allow_cold_extrude ? false : degHotend(HOTEND_INDEX) < extrude_min_temp; + } + #else + static bool tooColdToExtrude(uint8_t e) { UNUSED(e); return false; } + #endif + + private: + + #if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT) + static int redundant_temperature_raw; + static float redundant_temperature; + #endif + + static volatile bool temp_meas_ready; + + #if ENABLED(PIDTEMP) + static float temp_iState[HOTENDS], + temp_dState[HOTENDS], + pTerm[HOTENDS], + iTerm[HOTENDS], + dTerm[HOTENDS]; + + #if ENABLED(PID_EXTRUSION_SCALING) + static float cTerm[HOTENDS]; + static long last_e_position; + static long lpq[LPQ_MAX_LEN]; + static int lpq_ptr; + #endif + + static float pid_error[HOTENDS], + temp_iState_min[HOTENDS], + temp_iState_max[HOTENDS]; + static bool pid_reset[HOTENDS]; + #endif + + #if ENABLED(PIDTEMPBED) + static float temp_iState_bed, + temp_dState_bed, + pTerm_bed, + iTerm_bed, + dTerm_bed, + pid_error_bed, + temp_iState_min_bed, + temp_iState_max_bed; + #else + static millis_t next_bed_check_ms; + #endif + + static unsigned long raw_temp_value[4], + raw_temp_bed_value; + + // Init min and max temp with extreme values to prevent false errors during startup + static int minttemp_raw[HOTENDS], + maxttemp_raw[HOTENDS], + minttemp[HOTENDS], + maxttemp[HOTENDS]; + + #ifdef MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED + static int consecutive_low_temperature_error[HOTENDS]; + #endif + + #ifdef MILLISECONDS_PREHEAT_TIME + static unsigned long preheat_end_time[HOTENDS]; + #endif + + #ifdef BED_MINTEMP + static int bed_minttemp_raw; + #endif + + #ifdef BED_MAXTEMP + static int bed_maxttemp_raw; + #endif + + #if ENABLED(FILAMENT_WIDTH_SENSOR) + static int meas_shift_index; // Index of a delayed sample in buffer + #endif + + #if HAS_AUTO_FAN + static millis_t next_auto_fan_check_ms; + #endif + + static unsigned char soft_pwm[HOTENDS]; + + #if ENABLED(FAN_SOFT_PWM) + static unsigned char soft_pwm_fan[FAN_COUNT]; + #endif + + #if ENABLED(FILAMENT_WIDTH_SENSOR) + static int current_raw_filwidth; //Holds measured filament diameter - one extruder only + #endif + + public: + + /** + * Instance Methods + */ + + Temperature(); + + void init(); + + /** + * Static (class) methods + */ + static float analog2temp(int raw, uint8_t e); + static float analog2tempBed(int raw); + + /** + * Called from the Temperature ISR + */ + static void isr(); + + /** + * Call periodically to manage heaters + */ + static void manage_heater(); + + /** + * Preheating hotends + */ + #ifdef MILLISECONDS_PREHEAT_TIME + static bool is_preheating(uint8_t e) { + #if HOTENDS == 1 + UNUSED(e); + #endif + return preheat_end_time[HOTEND_INDEX] && PENDING(millis(), preheat_end_time[HOTEND_INDEX]); + } + static void start_preheat_time(uint8_t e) { + #if HOTENDS == 1 + UNUSED(e); + #endif + preheat_end_time[HOTEND_INDEX] = millis() + MILLISECONDS_PREHEAT_TIME; + } + static void reset_preheat_time(uint8_t e) { + #if HOTENDS == 1 + UNUSED(e); + #endif + preheat_end_time[HOTEND_INDEX] = 0; + } + #else + #define is_preheating(n) (false) + #endif + + #if ENABLED(FILAMENT_WIDTH_SENSOR) + static float analog2widthFil(); // Convert raw Filament Width to millimeters + static int widthFil_to_size_ratio(); // Convert raw Filament Width to an extrusion ratio + #endif + + + //high level conversion routines, for use outside of temperature.cpp + //inline so that there is no performance decrease. + //deg=degreeCelsius + + static float degHotend(uint8_t e) { + #if HOTENDS == 1 + UNUSED(e); + #endif + return current_temperature[HOTEND_INDEX]; + } + static float degBed() { return current_temperature_bed; } + + #if ENABLED(SHOW_TEMP_ADC_VALUES) + static float rawHotendTemp(uint8_t e) { + #if HOTENDS == 1 + UNUSED(e); + #endif + return current_temperature_raw[HOTEND_INDEX]; + } + static float rawBedTemp() { return current_temperature_bed_raw; } + #endif + + static float degTargetHotend(uint8_t e) { + #if HOTENDS == 1 + UNUSED(e); + #endif + return target_temperature[HOTEND_INDEX]; + } + static float degTargetBed() { return target_temperature_bed; } + + #if ENABLED(THERMAL_PROTECTION_HOTENDS) && WATCH_TEMP_PERIOD > 0 + static void start_watching_heater(uint8_t e = 0); + #endif + + #if ENABLED(THERMAL_PROTECTION_BED) && WATCH_BED_TEMP_PERIOD > 0 + static void start_watching_bed(); + #endif + + static void setTargetHotend(const float& celsius, uint8_t e) { + #if HOTENDS == 1 + UNUSED(e); + #endif + #ifdef MILLISECONDS_PREHEAT_TIME + if (celsius == 0.0f) + reset_preheat_time(HOTEND_INDEX); + else if (target_temperature[HOTEND_INDEX] == 0.0f) + start_preheat_time(HOTEND_INDEX); + #endif + target_temperature[HOTEND_INDEX] = celsius; + #if ENABLED(THERMAL_PROTECTION_HOTENDS) && WATCH_TEMP_PERIOD > 0 + start_watching_heater(HOTEND_INDEX); + #endif + } + + static void setTargetBed(const float& celsius) { + target_temperature_bed = celsius; + #if ENABLED(THERMAL_PROTECTION_BED) && WATCH_BED_TEMP_PERIOD > 0 + start_watching_bed(); + #endif + } + + static bool isHeatingHotend(uint8_t e) { + #if HOTENDS == 1 + UNUSED(e); + #endif + return target_temperature[HOTEND_INDEX] > current_temperature[HOTEND_INDEX]; + } + static bool isHeatingBed() { return target_temperature_bed > current_temperature_bed; } + + static bool isCoolingHotend(uint8_t e) { + #if HOTENDS == 1 + UNUSED(e); + #endif + return target_temperature[HOTEND_INDEX] < current_temperature[HOTEND_INDEX]; + } + static bool isCoolingBed() { return target_temperature_bed < current_temperature_bed; } + + /** + * The software PWM power for a heater + */ + static int getHeaterPower(int heater); + + /** + * Switch off all heaters, set all target temperatures to 0 + */ + static void disable_all_heaters(); + + /** + * Perform auto-tuning for hotend or bed in response to M303 + */ + #if HAS_PID_HEATING + static void PID_autotune(float temp, int hotend, int ncycles, bool set_result=false); + #endif + + /** + * Update the temp manager when PID values change + */ + static void updatePID(); + + static void autotempShutdown() { + #if ENABLED(AUTOTEMP) + if (planner.autotemp_enabled) { + planner.autotemp_enabled = false; + if (degTargetHotend(EXTRUDER_IDX) > planner.autotemp_min) + setTargetHotend(0, EXTRUDER_IDX); + } + #endif + } + + #if ENABLED(BABYSTEPPING) + + static void babystep_axis(AxisEnum axis, int distance) { + #if ENABLED(COREXY) || ENABLED(COREXZ) || ENABLED(COREYZ) + #if ENABLED(BABYSTEP_XY) + switch (axis) { + case CORE_AXIS_1: // X on CoreXY and CoreXZ, Y on CoreYZ + babystepsTodo[CORE_AXIS_1] += distance * 2; + babystepsTodo[CORE_AXIS_2] += distance * 2; + break; + case CORE_AXIS_2: // Y on CoreXY, Z on CoreXZ and CoreYZ + babystepsTodo[CORE_AXIS_1] += distance * 2; + babystepsTodo[CORE_AXIS_2] -= distance * 2; + break; + case NORMAL_AXIS: // Z on CoreXY, Y on CoreXZ, X on CoreYZ + babystepsTodo[NORMAL_AXIS] += distance; + break; + } + #elif ENABLED(COREXZ) || ENABLED(COREYZ) + // Only Z stepping needs to be handled here + babystepsTodo[CORE_AXIS_1] += distance * 2; + babystepsTodo[CORE_AXIS_2] -= distance * 2; + #else + babystepsTodo[Z_AXIS] += distance; + #endif + #else + babystepsTodo[axis] += distance; + #endif + } + + #endif // BABYSTEPPING + + private: + + static void set_current_temp_raw(); + + static void updateTemperaturesFromRawValues(); + + #if ENABLED(HEATER_0_USES_MAX6675) + static int read_max6675(); + #endif + + static void checkExtruderAutoFans(); + + static float get_pid_output(int e); + + #if ENABLED(PIDTEMPBED) + static float get_pid_output_bed(); + #endif + + static void _temp_error(int e, const char* serial_msg, const char* lcd_msg); + static void min_temp_error(uint8_t e); + static void max_temp_error(uint8_t e); + + #if ENABLED(THERMAL_PROTECTION_HOTENDS) || HAS_THERMALLY_PROTECTED_BED + + typedef enum TRState { TRInactive, TRFirstHeating, TRStable, TRRunaway } TRstate; + + static void thermal_runaway_protection(TRState* state, millis_t* timer, float temperature, float target_temperature, int heater_id, int period_seconds, int hysteresis_degc); + + #if ENABLED(THERMAL_PROTECTION_HOTENDS) + static TRState thermal_runaway_state_machine[HOTENDS]; + static millis_t thermal_runaway_timer[HOTENDS]; + #endif + + #if HAS_THERMALLY_PROTECTED_BED + static TRState thermal_runaway_bed_state_machine; + static millis_t thermal_runaway_bed_timer; + #endif + + #endif // THERMAL_PROTECTION + +}; + +extern Temperature thermalManager; + +#endif // TEMPERATURE_H diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/thermistornames.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/thermistornames.h new file mode 100644 index 00000000..64829ce7 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/thermistornames.h @@ -0,0 +1,95 @@ +/** + * 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 . + * + */ + +#undef THERMISTOR_NAME + +// Thermcouples +#if THERMISTOR_ID == -3 + #define THERMISTOR_NAME "MAX31855" +#elif THERMISTOR_ID == -2 + #define THERMISTOR_NAME "MAX6675" +#elif THERMISTOR_ID == -1 + #define THERMISTOR_NAME "AD595" + +// Standard thermistors +#elif THERMISTOR_ID == 1 + #define THERMISTOR_NAME "EPCOS 100K" +#elif THERMISTOR_ID == 2 + #define THERMISTOR_NAME "ATC 204GT-2" +#elif THERMISTOR_ID == 3 + #define THERMISTOR_NAME "Mendel-parts" +#elif THERMISTOR_ID == 4 + #define THERMISTOR_NAME "Generic 10K" +#elif THERMISTOR_ID == 5 + #define THERMISTOR_NAME "ATC 104GT-2" +#elif THERMISTOR_ID == 6 + #define THERMISTOR_NAME "EPCOS (alt)" +#elif THERMISTOR_ID == 7 + #define THERMISTOR_NAME "HW 104LAG" +#elif THERMISTOR_ID == 71 + #define THERMISTOR_NAME "HW 104LAF" +#elif THERMISTOR_ID == 8 + #define THERMISTOR_NAME "E3104FXT" +#elif THERMISTOR_ID == 9 + #define THERMISTOR_NAME "GE AL03006" +#elif THERMISTOR_ID == 10 + #define THERMISTOR_NAME "RS 198-961" +#elif THERMISTOR_ID == 11 + #define THERMISTOR_NAME "1% beta 3950" +#elif THERMISTOR_ID == 12 + #define THERMISTOR_NAME "E3104FXT (alt)" +#elif THERMISTOR_ID == 13 + #define THERMISTOR_NAME "Hisens 3950" +#elif THERMISTOR_ID == 20 + #define THERMISTOR_NAME "PT100 UltiMB" +#elif THERMISTOR_ID == 60 + #define THERMISTOR_NAME "Makers Tool" +#elif THERMISTOR_ID == 70 + #define THERMISTOR_NAME "Hephestos 2" + +// Modified thermistors +#elif THERMISTOR_ID == 51 + #define THERMISTOR_NAME "EPCOS 1K" +#elif THERMISTOR_ID == 52 + #define THERMISTOR_NAME "ATC204GT-2 1K" +#elif THERMISTOR_ID == 55 + #define THERMISTOR_NAME "ATC104GT-2 1K" +#elif THERMISTOR_ID == 1047 + #define THERMISTOR_NAME "PT1000 4K7" +#elif THERMISTOR_ID == 1010 + #define THERMISTOR_NAME "PT1000 1K" +#elif THERMISTOR_ID == 147 + #define THERMISTOR_NAME "PT100 4K7" +#elif THERMISTOR_ID == 110 + #define THERMISTOR_NAME "PT100 1K" + +// High Temperature thermistors +#elif THERMISTOR_ID == 66 + #define THERMISTOR_NAME "Dyze 4.7M" + +// Dummies for dev testing +#elif THERMISTOR_ID == 998 + #define THERMISTOR_NAME "Dummy 1" +#elif THERMISTOR_ID == 999 + #define THERMISTOR_NAME "Dummy 2" + +#endif // THERMISTOR_ID diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/thermistortables.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/thermistortables.h new file mode 100644 index 00000000..7980b720 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/thermistortables.h @@ -0,0 +1,1323 @@ +/** + * 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 . + * + */ + +#ifndef THERMISTORTABLES_H_ +#define THERMISTORTABLES_H_ + +#include "Marlin.h" +#include "macros.h" + +#define OVERSAMPLENR 16 + +#define ANY_THERMISTOR_IS(n) (THERMISTORHEATER_0 == n || THERMISTORHEATER_1 == n || THERMISTORHEATER_2 == n || THERMISTORHEATER_3 == n || THERMISTORBED == n) + +#if ANY_THERMISTOR_IS(1) // 100k bed thermistor +const short temptable_1[][2] PROGMEM = { + { 23 * OVERSAMPLENR, 300 }, + { 25 * OVERSAMPLENR, 295 }, + { 27 * OVERSAMPLENR, 290 }, + { 28 * OVERSAMPLENR, 285 }, + { 31 * OVERSAMPLENR, 280 }, + { 33 * OVERSAMPLENR, 275 }, + { 35 * OVERSAMPLENR, 270 }, + { 38 * OVERSAMPLENR, 265 }, + { 41 * OVERSAMPLENR, 260 }, + { 44 * OVERSAMPLENR, 255 }, + { 48 * OVERSAMPLENR, 250 }, + { 52 * OVERSAMPLENR, 245 }, + { 56 * OVERSAMPLENR, 240 }, + { 61 * OVERSAMPLENR, 235 }, + { 66 * OVERSAMPLENR, 230 }, + { 71 * OVERSAMPLENR, 225 }, + { 78 * OVERSAMPLENR, 220 }, + { 84 * OVERSAMPLENR, 215 }, + { 92 * OVERSAMPLENR, 210 }, + { 100 * OVERSAMPLENR, 205 }, + { 109 * OVERSAMPLENR, 200 }, + { 120 * OVERSAMPLENR, 195 }, + { 131 * OVERSAMPLENR, 190 }, + { 143 * OVERSAMPLENR, 185 }, + { 156 * OVERSAMPLENR, 180 }, + { 171 * OVERSAMPLENR, 175 }, + { 187 * OVERSAMPLENR, 170 }, + { 205 * OVERSAMPLENR, 165 }, + { 224 * OVERSAMPLENR, 160 }, + { 245 * OVERSAMPLENR, 155 }, + { 268 * OVERSAMPLENR, 150 }, + { 293 * OVERSAMPLENR, 145 }, + { 320 * OVERSAMPLENR, 140 }, + { 348 * OVERSAMPLENR, 135 }, + { 379 * OVERSAMPLENR, 130 }, + { 411 * OVERSAMPLENR, 125 }, + { 445 * OVERSAMPLENR, 120 }, + { 480 * OVERSAMPLENR, 115 }, + { 516 * OVERSAMPLENR, 110 }, + { 553 * OVERSAMPLENR, 105 }, + { 591 * OVERSAMPLENR, 100 }, + { 628 * OVERSAMPLENR, 95 }, + { 665 * OVERSAMPLENR, 90 }, + { 702 * OVERSAMPLENR, 85 }, + { 737 * OVERSAMPLENR, 80 }, + { 770 * OVERSAMPLENR, 75 }, + { 801 * OVERSAMPLENR, 70 }, + { 830 * OVERSAMPLENR, 65 }, + { 857 * OVERSAMPLENR, 60 }, + { 881 * OVERSAMPLENR, 55 }, + { 903 * OVERSAMPLENR, 50 }, + { 922 * OVERSAMPLENR, 45 }, + { 939 * OVERSAMPLENR, 40 }, + { 954 * OVERSAMPLENR, 35 }, + { 966 * OVERSAMPLENR, 30 }, + { 977 * OVERSAMPLENR, 25 }, + { 985 * OVERSAMPLENR, 20 }, + { 993 * OVERSAMPLENR, 15 }, + { 999 * OVERSAMPLENR, 10 }, + { 1004 * OVERSAMPLENR, 5 }, + { 1008 * OVERSAMPLENR, 0 } // safety +}; +#endif + +#if ANY_THERMISTOR_IS(2) // 200k bed thermistor +// 200k ATC Semitec 204GT-2 +// Verified by linagee. Source: http://shop.arcol.hu/static/datasheets/thermistors.pdf +// Calculated using 4.7kohm pullup, voltage divider math, and manufacturer provided temp/resistance +const short temptable_2[][2] PROGMEM = { + { 1 * OVERSAMPLENR, 848 }, + { 30 * OVERSAMPLENR, 300 }, // top rating 300C + { 34 * OVERSAMPLENR, 290 }, + { 39 * OVERSAMPLENR, 280 }, + { 46 * OVERSAMPLENR, 270 }, + { 53 * OVERSAMPLENR, 260 }, + { 63 * OVERSAMPLENR, 250 }, + { 74 * OVERSAMPLENR, 240 }, + { 87 * OVERSAMPLENR, 230 }, + { 104 * OVERSAMPLENR, 220 }, + { 124 * OVERSAMPLENR, 210 }, + { 148 * OVERSAMPLENR, 200 }, + { 176 * OVERSAMPLENR, 190 }, + { 211 * OVERSAMPLENR, 180 }, + { 252 * OVERSAMPLENR, 170 }, + { 301 * OVERSAMPLENR, 160 }, + { 357 * OVERSAMPLENR, 150 }, + { 420 * OVERSAMPLENR, 140 }, + { 489 * OVERSAMPLENR, 130 }, + { 562 * OVERSAMPLENR, 120 }, + { 636 * OVERSAMPLENR, 110 }, + { 708 * OVERSAMPLENR, 100 }, + { 775 * OVERSAMPLENR, 90 }, + { 835 * OVERSAMPLENR, 80 }, + { 884 * OVERSAMPLENR, 70 }, + { 924 * OVERSAMPLENR, 60 }, + { 955 * OVERSAMPLENR, 50 }, + { 977 * OVERSAMPLENR, 40 }, + { 993 * OVERSAMPLENR, 30 }, + { 1004 * OVERSAMPLENR, 20 }, + { 1012 * OVERSAMPLENR, 10 }, + { 1016 * OVERSAMPLENR, 0 } +}; +#endif + +#if ANY_THERMISTOR_IS(3) // mendel-parts +const short temptable_3[][2] PROGMEM = { + { 1 * OVERSAMPLENR, 864 }, + { 21 * OVERSAMPLENR, 300 }, + { 25 * OVERSAMPLENR, 290 }, + { 29 * OVERSAMPLENR, 280 }, + { 33 * OVERSAMPLENR, 270 }, + { 39 * OVERSAMPLENR, 260 }, + { 46 * OVERSAMPLENR, 250 }, + { 54 * OVERSAMPLENR, 240 }, + { 64 * OVERSAMPLENR, 230 }, + { 75 * OVERSAMPLENR, 220 }, + { 90 * OVERSAMPLENR, 210 }, + { 107 * OVERSAMPLENR, 200 }, + { 128 * OVERSAMPLENR, 190 }, + { 154 * OVERSAMPLENR, 180 }, + { 184 * OVERSAMPLENR, 170 }, + { 221 * OVERSAMPLENR, 160 }, + { 265 * OVERSAMPLENR, 150 }, + { 316 * OVERSAMPLENR, 140 }, + { 375 * OVERSAMPLENR, 130 }, + { 441 * OVERSAMPLENR, 120 }, + { 513 * OVERSAMPLENR, 110 }, + { 588 * OVERSAMPLENR, 100 }, + { 734 * OVERSAMPLENR, 80 }, + { 856 * OVERSAMPLENR, 60 }, + { 938 * OVERSAMPLENR, 40 }, + { 986 * OVERSAMPLENR, 20 }, + { 1008 * OVERSAMPLENR, 0 }, + { 1018 * OVERSAMPLENR, -20 } +}; +#endif + +#if ANY_THERMISTOR_IS(4) // 10k thermistor +const short temptable_4[][2] PROGMEM = { + { 1 * OVERSAMPLENR, 430 }, + { 54 * OVERSAMPLENR, 137 }, + { 107 * OVERSAMPLENR, 107 }, + { 160 * OVERSAMPLENR, 91 }, + { 213 * OVERSAMPLENR, 80 }, + { 266 * OVERSAMPLENR, 71 }, + { 319 * OVERSAMPLENR, 64 }, + { 372 * OVERSAMPLENR, 57 }, + { 425 * OVERSAMPLENR, 51 }, + { 478 * OVERSAMPLENR, 46 }, + { 531 * OVERSAMPLENR, 41 }, + { 584 * OVERSAMPLENR, 35 }, + { 637 * OVERSAMPLENR, 30 }, + { 690 * OVERSAMPLENR, 25 }, + { 743 * OVERSAMPLENR, 20 }, + { 796 * OVERSAMPLENR, 14 }, + { 849 * OVERSAMPLENR, 7 }, + { 902 * OVERSAMPLENR, 0 }, + { 955 * OVERSAMPLENR, -11 }, + { 1008 * OVERSAMPLENR, -35 } +}; +#endif + +#if ANY_THERMISTOR_IS(5) // 100k ParCan thermistor (104GT-2) +// ATC Semitec 104GT-2 (Used in ParCan) +// Verified by linagee. Source: http://shop.arcol.hu/static/datasheets/thermistors.pdf +// Calculated using 4.7kohm pullup, voltage divider math, and manufacturer provided temp/resistance +const short temptable_5[][2] PROGMEM = { + { 1 * OVERSAMPLENR, 713 }, + { 17 * OVERSAMPLENR, 300 }, // top rating 300C + { 20 * OVERSAMPLENR, 290 }, + { 23 * OVERSAMPLENR, 280 }, + { 27 * OVERSAMPLENR, 270 }, + { 31 * OVERSAMPLENR, 260 }, + { 37 * OVERSAMPLENR, 250 }, + { 43 * OVERSAMPLENR, 240 }, + { 51 * OVERSAMPLENR, 230 }, + { 61 * OVERSAMPLENR, 220 }, + { 73 * OVERSAMPLENR, 210 }, + { 87 * OVERSAMPLENR, 200 }, + { 106 * OVERSAMPLENR, 190 }, + { 128 * OVERSAMPLENR, 180 }, + { 155 * OVERSAMPLENR, 170 }, + { 189 * OVERSAMPLENR, 160 }, + { 230 * OVERSAMPLENR, 150 }, + { 278 * OVERSAMPLENR, 140 }, + { 336 * OVERSAMPLENR, 130 }, + { 402 * OVERSAMPLENR, 120 }, + { 476 * OVERSAMPLENR, 110 }, + { 554 * OVERSAMPLENR, 100 }, + { 635 * OVERSAMPLENR, 90 }, + { 713 * OVERSAMPLENR, 80 }, + { 784 * OVERSAMPLENR, 70 }, + { 846 * OVERSAMPLENR, 60 }, + { 897 * OVERSAMPLENR, 50 }, + { 937 * OVERSAMPLENR, 40 }, + { 966 * OVERSAMPLENR, 30 }, + { 986 * OVERSAMPLENR, 20 }, + { 1000 * OVERSAMPLENR, 10 }, + { 1010 * OVERSAMPLENR, 0 } +}; +#endif + +#if ANY_THERMISTOR_IS(6) // 100k Epcos thermistor +const short temptable_6[][2] PROGMEM = { + { 1 * OVERSAMPLENR, 350 }, + { 28 * OVERSAMPLENR, 250 }, // top rating 250C + { 31 * OVERSAMPLENR, 245 }, + { 35 * OVERSAMPLENR, 240 }, + { 39 * OVERSAMPLENR, 235 }, + { 42 * OVERSAMPLENR, 230 }, + { 44 * OVERSAMPLENR, 225 }, + { 49 * OVERSAMPLENR, 220 }, + { 53 * OVERSAMPLENR, 215 }, + { 62 * OVERSAMPLENR, 210 }, + { 71 * OVERSAMPLENR, 205 }, // fitted graphically + { 78 * OVERSAMPLENR, 200 }, // fitted graphically + { 94 * OVERSAMPLENR, 190 }, + { 102 * OVERSAMPLENR, 185 }, + { 116 * OVERSAMPLENR, 170 }, + { 143 * OVERSAMPLENR, 160 }, + { 183 * OVERSAMPLENR, 150 }, + { 223 * OVERSAMPLENR, 140 }, + { 270 * OVERSAMPLENR, 130 }, + { 318 * OVERSAMPLENR, 120 }, + { 383 * OVERSAMPLENR, 110 }, + { 413 * OVERSAMPLENR, 105 }, + { 439 * OVERSAMPLENR, 100 }, + { 484 * OVERSAMPLENR, 95 }, + { 513 * OVERSAMPLENR, 90 }, + { 607 * OVERSAMPLENR, 80 }, + { 664 * OVERSAMPLENR, 70 }, + { 781 * OVERSAMPLENR, 60 }, + { 810 * OVERSAMPLENR, 55 }, + { 849 * OVERSAMPLENR, 50 }, + { 914 * OVERSAMPLENR, 45 }, + { 914 * OVERSAMPLENR, 40 }, + { 935 * OVERSAMPLENR, 35 }, + { 954 * OVERSAMPLENR, 30 }, + { 970 * OVERSAMPLENR, 25 }, + { 978 * OVERSAMPLENR, 22 }, + { 1008 * OVERSAMPLENR, 3 }, + { 1023 * OVERSAMPLENR, 0 } // to allow internal 0 degrees C +}; +#endif + +#if ANY_THERMISTOR_IS(7) // 100k Honeywell 135-104LAG-J01 +const short temptable_7[][2] PROGMEM = { + { 1 * OVERSAMPLENR, 941 }, + { 19 * OVERSAMPLENR, 362 }, + { 37 * OVERSAMPLENR, 299 }, // top rating 300C + { 55 * OVERSAMPLENR, 266 }, + { 73 * OVERSAMPLENR, 245 }, + { 91 * OVERSAMPLENR, 229 }, + { 109 * OVERSAMPLENR, 216 }, + { 127 * OVERSAMPLENR, 206 }, + { 145 * OVERSAMPLENR, 197 }, + { 163 * OVERSAMPLENR, 190 }, + { 181 * OVERSAMPLENR, 183 }, + { 199 * OVERSAMPLENR, 177 }, + { 217 * OVERSAMPLENR, 171 }, + { 235 * OVERSAMPLENR, 166 }, + { 253 * OVERSAMPLENR, 162 }, + { 271 * OVERSAMPLENR, 157 }, + { 289 * OVERSAMPLENR, 153 }, + { 307 * OVERSAMPLENR, 149 }, + { 325 * OVERSAMPLENR, 146 }, + { 343 * OVERSAMPLENR, 142 }, + { 361 * OVERSAMPLENR, 139 }, + { 379 * OVERSAMPLENR, 135 }, + { 397 * OVERSAMPLENR, 132 }, + { 415 * OVERSAMPLENR, 129 }, + { 433 * OVERSAMPLENR, 126 }, + { 451 * OVERSAMPLENR, 123 }, + { 469 * OVERSAMPLENR, 121 }, + { 487 * OVERSAMPLENR, 118 }, + { 505 * OVERSAMPLENR, 115 }, + { 523 * OVERSAMPLENR, 112 }, + { 541 * OVERSAMPLENR, 110 }, + { 559 * OVERSAMPLENR, 107 }, + { 577 * OVERSAMPLENR, 105 }, + { 595 * OVERSAMPLENR, 102 }, + { 613 * OVERSAMPLENR, 99 }, + { 631 * OVERSAMPLENR, 97 }, + { 649 * OVERSAMPLENR, 94 }, + { 667 * OVERSAMPLENR, 92 }, + { 685 * OVERSAMPLENR, 89 }, + { 703 * OVERSAMPLENR, 86 }, + { 721 * OVERSAMPLENR, 84 }, + { 739 * OVERSAMPLENR, 81 }, + { 757 * OVERSAMPLENR, 78 }, + { 775 * OVERSAMPLENR, 75 }, + { 793 * OVERSAMPLENR, 72 }, + { 811 * OVERSAMPLENR, 69 }, + { 829 * OVERSAMPLENR, 66 }, + { 847 * OVERSAMPLENR, 62 }, + { 865 * OVERSAMPLENR, 59 }, + { 883 * OVERSAMPLENR, 55 }, + { 901 * OVERSAMPLENR, 51 }, + { 919 * OVERSAMPLENR, 46 }, + { 937 * OVERSAMPLENR, 41 }, + { 955 * OVERSAMPLENR, 35 }, + { 973 * OVERSAMPLENR, 27 }, + { 991 * OVERSAMPLENR, 17 }, + { 1009 * OVERSAMPLENR, 1 }, + { 1023 * OVERSAMPLENR, 0 } // to allow internal 0 degrees C +}; +#endif + +#if ANY_THERMISTOR_IS(71) // 100k Honeywell 135-104LAF-J01 +// R0 = 100000 Ohm +// T0 = 25 °C +// Beta = 3974 +// R1 = 0 Ohm +// R2 = 4700 Ohm +const short temptable_71[][2] PROGMEM = { + { 35 * OVERSAMPLENR, 300 }, + { 51 * OVERSAMPLENR, 270 }, + { 54 * OVERSAMPLENR, 265 }, + { 58 * OVERSAMPLENR, 260 }, + { 59 * OVERSAMPLENR, 258 }, + { 61 * OVERSAMPLENR, 256 }, + { 63 * OVERSAMPLENR, 254 }, + { 64 * OVERSAMPLENR, 252 }, + { 66 * OVERSAMPLENR, 250 }, + { 67 * OVERSAMPLENR, 249 }, + { 68 * OVERSAMPLENR, 248 }, + { 69 * OVERSAMPLENR, 247 }, + { 70 * OVERSAMPLENR, 246 }, + { 71 * OVERSAMPLENR, 245 }, + { 72 * OVERSAMPLENR, 244 }, + { 73 * OVERSAMPLENR, 243 }, + { 74 * OVERSAMPLENR, 242 }, + { 75 * OVERSAMPLENR, 241 }, + { 76 * OVERSAMPLENR, 240 }, + { 77 * OVERSAMPLENR, 239 }, + { 78 * OVERSAMPLENR, 238 }, + { 79 * OVERSAMPLENR, 237 }, + { 80 * OVERSAMPLENR, 236 }, + { 81 * OVERSAMPLENR, 235 }, + { 82 * OVERSAMPLENR, 234 }, + { 84 * OVERSAMPLENR, 233 }, + { 85 * OVERSAMPLENR, 232 }, + { 86 * OVERSAMPLENR, 231 }, + { 87 * OVERSAMPLENR, 230 }, + { 89 * OVERSAMPLENR, 229 }, + { 90 * OVERSAMPLENR, 228 }, + { 91 * OVERSAMPLENR, 227 }, + { 92 * OVERSAMPLENR, 226 }, + { 94 * OVERSAMPLENR, 225 }, + { 95 * OVERSAMPLENR, 224 }, + { 97 * OVERSAMPLENR, 223 }, + { 98 * OVERSAMPLENR, 222 }, + { 99 * OVERSAMPLENR, 221 }, + { 101 * OVERSAMPLENR, 220 }, + { 102 * OVERSAMPLENR, 219 }, + { 104 * OVERSAMPLENR, 218 }, + { 106 * OVERSAMPLENR, 217 }, + { 107 * OVERSAMPLENR, 216 }, + { 109 * OVERSAMPLENR, 215 }, + { 110 * OVERSAMPLENR, 214 }, + { 112 * OVERSAMPLENR, 213 }, + { 114 * OVERSAMPLENR, 212 }, + { 115 * OVERSAMPLENR, 211 }, + { 117 * OVERSAMPLENR, 210 }, + { 119 * OVERSAMPLENR, 209 }, + { 121 * OVERSAMPLENR, 208 }, + { 123 * OVERSAMPLENR, 207 }, + { 125 * OVERSAMPLENR, 206 }, + { 126 * OVERSAMPLENR, 205 }, + { 128 * OVERSAMPLENR, 204 }, + { 130 * OVERSAMPLENR, 203 }, + { 132 * OVERSAMPLENR, 202 }, + { 134 * OVERSAMPLENR, 201 }, + { 136 * OVERSAMPLENR, 200 }, + { 139 * OVERSAMPLENR, 199 }, + { 141 * OVERSAMPLENR, 198 }, + { 143 * OVERSAMPLENR, 197 }, + { 145 * OVERSAMPLENR, 196 }, + { 147 * OVERSAMPLENR, 195 }, + { 150 * OVERSAMPLENR, 194 }, + { 152 * OVERSAMPLENR, 193 }, + { 154 * OVERSAMPLENR, 192 }, + { 157 * OVERSAMPLENR, 191 }, + { 159 * OVERSAMPLENR, 190 }, + { 162 * OVERSAMPLENR, 189 }, + { 164 * OVERSAMPLENR, 188 }, + { 167 * OVERSAMPLENR, 187 }, + { 170 * OVERSAMPLENR, 186 }, + { 172 * OVERSAMPLENR, 185 }, + { 175 * OVERSAMPLENR, 184 }, + { 178 * OVERSAMPLENR, 183 }, + { 181 * OVERSAMPLENR, 182 }, + { 184 * OVERSAMPLENR, 181 }, + { 187 * OVERSAMPLENR, 180 }, + { 190 * OVERSAMPLENR, 179 }, + { 193 * OVERSAMPLENR, 178 }, + { 196 * OVERSAMPLENR, 177 }, + { 199 * OVERSAMPLENR, 176 }, + { 202 * OVERSAMPLENR, 175 }, + { 205 * OVERSAMPLENR, 174 }, + { 208 * OVERSAMPLENR, 173 }, + { 212 * OVERSAMPLENR, 172 }, + { 215 * OVERSAMPLENR, 171 }, + { 219 * OVERSAMPLENR, 170 }, + { 237 * OVERSAMPLENR, 165 }, + { 256 * OVERSAMPLENR, 160 }, + { 300 * OVERSAMPLENR, 150 }, + { 351 * OVERSAMPLENR, 140 }, + { 470 * OVERSAMPLENR, 120 }, + { 504 * OVERSAMPLENR, 115 }, + { 538 * OVERSAMPLENR, 110 }, + { 552 * OVERSAMPLENR, 108 }, + { 566 * OVERSAMPLENR, 106 }, + { 580 * OVERSAMPLENR, 104 }, + { 594 * OVERSAMPLENR, 102 }, + { 608 * OVERSAMPLENR, 100 }, + { 622 * OVERSAMPLENR, 98 }, + { 636 * OVERSAMPLENR, 96 }, + { 650 * OVERSAMPLENR, 94 }, + { 664 * OVERSAMPLENR, 92 }, + { 678 * OVERSAMPLENR, 90 }, + { 712 * OVERSAMPLENR, 85 }, + { 745 * OVERSAMPLENR, 80 }, + { 758 * OVERSAMPLENR, 78 }, + { 770 * OVERSAMPLENR, 76 }, + { 783 * OVERSAMPLENR, 74 }, + { 795 * OVERSAMPLENR, 72 }, + { 806 * OVERSAMPLENR, 70 }, + { 818 * OVERSAMPLENR, 68 }, + { 829 * OVERSAMPLENR, 66 }, + { 840 * OVERSAMPLENR, 64 }, + { 850 * OVERSAMPLENR, 62 }, + { 860 * OVERSAMPLENR, 60 }, + { 870 * OVERSAMPLENR, 58 }, + { 879 * OVERSAMPLENR, 56 }, + { 888 * OVERSAMPLENR, 54 }, + { 897 * OVERSAMPLENR, 52 }, + { 905 * OVERSAMPLENR, 50 }, + { 924 * OVERSAMPLENR, 45 }, + { 940 * OVERSAMPLENR, 40 }, + { 955 * OVERSAMPLENR, 35 }, + { 967 * OVERSAMPLENR, 30 }, + { 970 * OVERSAMPLENR, 29 }, + { 972 * OVERSAMPLENR, 28 }, + { 974 * OVERSAMPLENR, 27 }, + { 976 * OVERSAMPLENR, 26 }, + { 978 * OVERSAMPLENR, 25 }, + { 980 * OVERSAMPLENR, 24 }, + { 982 * OVERSAMPLENR, 23 }, + { 984 * OVERSAMPLENR, 22 }, + { 985 * OVERSAMPLENR, 21 }, + { 987 * OVERSAMPLENR, 20 }, + { 995 * OVERSAMPLENR, 15 }, + { 1001 * OVERSAMPLENR, 10 }, + { 1006 * OVERSAMPLENR, 5 }, + { 1010 * OVERSAMPLENR, 0 } +}; +#endif + +#if ANY_THERMISTOR_IS(8) +// 100k 0603 SMD Vishay NTCS0603E3104FXT (4.7k pullup) +const short temptable_8[][2] PROGMEM = { + { 1 * OVERSAMPLENR, 704 }, + { 54 * OVERSAMPLENR, 216 }, + { 107 * OVERSAMPLENR, 175 }, + { 160 * OVERSAMPLENR, 152 }, + { 213 * OVERSAMPLENR, 137 }, + { 266 * OVERSAMPLENR, 125 }, + { 319 * OVERSAMPLENR, 115 }, + { 372 * OVERSAMPLENR, 106 }, + { 425 * OVERSAMPLENR, 99 }, + { 478 * OVERSAMPLENR, 91 }, + { 531 * OVERSAMPLENR, 85 }, + { 584 * OVERSAMPLENR, 78 }, + { 637 * OVERSAMPLENR, 71 }, + { 690 * OVERSAMPLENR, 65 }, + { 743 * OVERSAMPLENR, 58 }, + { 796 * OVERSAMPLENR, 50 }, + { 849 * OVERSAMPLENR, 42 }, + { 902 * OVERSAMPLENR, 31 }, + { 955 * OVERSAMPLENR, 17 }, + { 1008 * OVERSAMPLENR, 0 } +}; +#endif + +#if ANY_THERMISTOR_IS(9) +// 100k GE Sensing AL03006-58.2K-97-G1 (4.7k pullup) +const short temptable_9[][2] PROGMEM = { + { 1 * OVERSAMPLENR, 936 }, + { 36 * OVERSAMPLENR, 300 }, + { 71 * OVERSAMPLENR, 246 }, + { 106 * OVERSAMPLENR, 218 }, + { 141 * OVERSAMPLENR, 199 }, + { 176 * OVERSAMPLENR, 185 }, + { 211 * OVERSAMPLENR, 173 }, + { 246 * OVERSAMPLENR, 163 }, + { 281 * OVERSAMPLENR, 155 }, + { 316 * OVERSAMPLENR, 147 }, + { 351 * OVERSAMPLENR, 140 }, + { 386 * OVERSAMPLENR, 134 }, + { 421 * OVERSAMPLENR, 128 }, + { 456 * OVERSAMPLENR, 122 }, + { 491 * OVERSAMPLENR, 117 }, + { 526 * OVERSAMPLENR, 112 }, + { 561 * OVERSAMPLENR, 107 }, + { 596 * OVERSAMPLENR, 102 }, + { 631 * OVERSAMPLENR, 97 }, + { 666 * OVERSAMPLENR, 92 }, + { 701 * OVERSAMPLENR, 87 }, + { 736 * OVERSAMPLENR, 81 }, + { 771 * OVERSAMPLENR, 76 }, + { 806 * OVERSAMPLENR, 70 }, + { 841 * OVERSAMPLENR, 63 }, + { 876 * OVERSAMPLENR, 56 }, + { 911 * OVERSAMPLENR, 48 }, + { 946 * OVERSAMPLENR, 38 }, + { 981 * OVERSAMPLENR, 23 }, + { 1005 * OVERSAMPLENR, 5 }, + { 1016 * OVERSAMPLENR, 0 } +}; +#endif + +#if ANY_THERMISTOR_IS(10) +// 100k RS thermistor 198-961 (4.7k pullup) +const short temptable_10[][2] PROGMEM = { + { 1 * OVERSAMPLENR, 929 }, + { 36 * OVERSAMPLENR, 299 }, + { 71 * OVERSAMPLENR, 246 }, + { 106 * OVERSAMPLENR, 217 }, + { 141 * OVERSAMPLENR, 198 }, + { 176 * OVERSAMPLENR, 184 }, + { 211 * OVERSAMPLENR, 173 }, + { 246 * OVERSAMPLENR, 163 }, + { 281 * OVERSAMPLENR, 154 }, + { 316 * OVERSAMPLENR, 147 }, + { 351 * OVERSAMPLENR, 140 }, + { 386 * OVERSAMPLENR, 134 }, + { 421 * OVERSAMPLENR, 128 }, + { 456 * OVERSAMPLENR, 122 }, + { 491 * OVERSAMPLENR, 117 }, + { 526 * OVERSAMPLENR, 112 }, + { 561 * OVERSAMPLENR, 107 }, + { 596 * OVERSAMPLENR, 102 }, + { 631 * OVERSAMPLENR, 97 }, + { 666 * OVERSAMPLENR, 91 }, + { 701 * OVERSAMPLENR, 86 }, + { 736 * OVERSAMPLENR, 81 }, + { 771 * OVERSAMPLENR, 76 }, + { 806 * OVERSAMPLENR, 70 }, + { 841 * OVERSAMPLENR, 63 }, + { 876 * OVERSAMPLENR, 56 }, + { 911 * OVERSAMPLENR, 48 }, + { 946 * OVERSAMPLENR, 38 }, + { 981 * OVERSAMPLENR, 23 }, + { 1005 * OVERSAMPLENR, 5 }, + { 1016 * OVERSAMPLENR, 0 } +}; +#endif + +#if ANY_THERMISTOR_IS(11) +// QU-BD silicone bed QWG-104F-3950 thermistor +const short temptable_11[][2] PROGMEM = { + { 1 * OVERSAMPLENR, 938 }, + { 31 * OVERSAMPLENR, 314 }, + { 41 * OVERSAMPLENR, 290 }, + { 51 * OVERSAMPLENR, 272 }, + { 61 * OVERSAMPLENR, 258 }, + { 71 * OVERSAMPLENR, 247 }, + { 81 * OVERSAMPLENR, 237 }, + { 91 * OVERSAMPLENR, 229 }, + { 101 * OVERSAMPLENR, 221 }, + { 111 * OVERSAMPLENR, 215 }, + { 121 * OVERSAMPLENR, 209 }, + { 131 * OVERSAMPLENR, 204 }, + { 141 * OVERSAMPLENR, 199 }, + { 151 * OVERSAMPLENR, 195 }, + { 161 * OVERSAMPLENR, 190 }, + { 171 * OVERSAMPLENR, 187 }, + { 181 * OVERSAMPLENR, 183 }, + { 191 * OVERSAMPLENR, 179 }, + { 201 * OVERSAMPLENR, 176 }, + { 221 * OVERSAMPLENR, 170 }, + { 241 * OVERSAMPLENR, 165 }, + { 261 * OVERSAMPLENR, 160 }, + { 281 * OVERSAMPLENR, 155 }, + { 301 * OVERSAMPLENR, 150 }, + { 331 * OVERSAMPLENR, 144 }, + { 361 * OVERSAMPLENR, 139 }, + { 391 * OVERSAMPLENR, 133 }, + { 421 * OVERSAMPLENR, 128 }, + { 451 * OVERSAMPLENR, 123 }, + { 491 * OVERSAMPLENR, 117 }, + { 531 * OVERSAMPLENR, 111 }, + { 571 * OVERSAMPLENR, 105 }, + { 611 * OVERSAMPLENR, 100 }, + { 641 * OVERSAMPLENR, 95 }, + { 681 * OVERSAMPLENR, 90 }, + { 711 * OVERSAMPLENR, 85 }, + { 751 * OVERSAMPLENR, 79 }, + { 791 * OVERSAMPLENR, 72 }, + { 811 * OVERSAMPLENR, 69 }, + { 831 * OVERSAMPLENR, 65 }, + { 871 * OVERSAMPLENR, 57 }, + { 881 * OVERSAMPLENR, 55 }, + { 901 * OVERSAMPLENR, 51 }, + { 921 * OVERSAMPLENR, 45 }, + { 941 * OVERSAMPLENR, 39 }, + { 971 * OVERSAMPLENR, 28 }, + { 981 * OVERSAMPLENR, 23 }, + { 991 * OVERSAMPLENR, 17 }, + { 1001 * OVERSAMPLENR, 9 }, + { 1021 * OVERSAMPLENR, -27 } +}; +#endif + +#if ANY_THERMISTOR_IS(13) +// Hisens thermistor B25/50 =3950 +/-1% +const short temptable_13[][2] PROGMEM = { + { 20.04 * OVERSAMPLENR, 300 }, + { 23.19 * OVERSAMPLENR, 290 }, + { 26.71 * OVERSAMPLENR, 280 }, + { 31.23 * OVERSAMPLENR, 270 }, + { 36.52 * OVERSAMPLENR, 260 }, + { 42.75 * OVERSAMPLENR, 250 }, + { 50.68 * OVERSAMPLENR, 240 }, + { 60.22 * OVERSAMPLENR, 230 }, + { 72.03 * OVERSAMPLENR, 220 }, + { 86.84 * OVERSAMPLENR, 210 }, + { 102.79 * OVERSAMPLENR, 200 }, + { 124.46 * OVERSAMPLENR, 190 }, + { 151.02 * OVERSAMPLENR, 180 }, + { 182.86 * OVERSAMPLENR, 170 }, + { 220.72 * OVERSAMPLENR, 160 }, + { 316.96 * OVERSAMPLENR, 140 }, + { 447.17 * OVERSAMPLENR, 120 }, + { 590.61 * OVERSAMPLENR, 100 }, + { 737.31 * OVERSAMPLENR, 80 }, + { 857.77 * OVERSAMPLENR, 60 }, + { 939.52 * OVERSAMPLENR, 40 }, + { 986.03 * OVERSAMPLENR, 20 }, + { 1008.7 * OVERSAMPLENR, 0 } + +}; +#endif + +#if ANY_THERMISTOR_IS(20) // PT100 with INA826 amp on Ultimaker v2.0 electronics +// The PT100 in the Ultimaker v2.0 electronics has a high sample value for a high temperature. +// This does not match the normal thermistor behaviour so we need to set the following defines +#if (THERMISTORHEATER_0 == 20) + #define HEATER_0_RAW_HI_TEMP 16383 + #define HEATER_0_RAW_LO_TEMP 0 +#endif +#if (THERMISTORHEATER_1 == 20) + #define HEATER_1_RAW_HI_TEMP 16383 + #define HEATER_1_RAW_LO_TEMP 0 +#endif +#if (THERMISTORHEATER_2 == 20) + #define HEATER_2_RAW_HI_TEMP 16383 + #define HEATER_2_RAW_LO_TEMP 0 +#endif +#if (THERMISTORHEATER_3 == 20) + #define HEATER_3_RAW_HI_TEMP 16383 + #define HEATER_3_RAW_LO_TEMP 0 +#endif +#if (THERMISTORBED == 20) + #define HEATER_BED_RAW_HI_TEMP 16383 + #define HEATER_BED_RAW_LO_TEMP 0 +#endif +const short temptable_20[][2] PROGMEM = { + { 0 * OVERSAMPLENR, 0 }, + { 227 * OVERSAMPLENR, 1 }, + { 236 * OVERSAMPLENR, 10 }, + { 245 * OVERSAMPLENR, 20 }, + { 253 * OVERSAMPLENR, 30 }, + { 262 * OVERSAMPLENR, 40 }, + { 270 * OVERSAMPLENR, 50 }, + { 279 * OVERSAMPLENR, 60 }, + { 287 * OVERSAMPLENR, 70 }, + { 295 * OVERSAMPLENR, 80 }, + { 304 * OVERSAMPLENR, 90 }, + { 312 * OVERSAMPLENR, 100 }, + { 320 * OVERSAMPLENR, 110 }, + { 329 * OVERSAMPLENR, 120 }, + { 337 * OVERSAMPLENR, 130 }, + { 345 * OVERSAMPLENR, 140 }, + { 353 * OVERSAMPLENR, 150 }, + { 361 * OVERSAMPLENR, 160 }, + { 369 * OVERSAMPLENR, 170 }, + { 377 * OVERSAMPLENR, 180 }, + { 385 * OVERSAMPLENR, 190 }, + { 393 * OVERSAMPLENR, 200 }, + { 401 * OVERSAMPLENR, 210 }, + { 409 * OVERSAMPLENR, 220 }, + { 417 * OVERSAMPLENR, 230 }, + { 424 * OVERSAMPLENR, 240 }, + { 432 * OVERSAMPLENR, 250 }, + { 440 * OVERSAMPLENR, 260 }, + { 447 * OVERSAMPLENR, 270 }, + { 455 * OVERSAMPLENR, 280 }, + { 463 * OVERSAMPLENR, 290 }, + { 470 * OVERSAMPLENR, 300 }, + { 478 * OVERSAMPLENR, 310 }, + { 485 * OVERSAMPLENR, 320 }, + { 493 * OVERSAMPLENR, 330 }, + { 500 * OVERSAMPLENR, 340 }, + { 507 * OVERSAMPLENR, 350 }, + { 515 * OVERSAMPLENR, 360 }, + { 522 * OVERSAMPLENR, 370 }, + { 529 * OVERSAMPLENR, 380 }, + { 537 * OVERSAMPLENR, 390 }, + { 544 * OVERSAMPLENR, 400 }, + { 614 * OVERSAMPLENR, 500 }, + { 681 * OVERSAMPLENR, 600 }, + { 744 * OVERSAMPLENR, 700 }, + { 805 * OVERSAMPLENR, 800 }, + { 862 * OVERSAMPLENR, 900 }, + { 917 * OVERSAMPLENR, 1000 }, + { 968 * OVERSAMPLENR, 1100 } +}; +#endif + +#if ANY_THERMISTOR_IS(51) +// 100k EPCOS (WITH 1kohm RESISTOR FOR PULLUP, R9 ON SANGUINOLOLU! NOT FOR 4.7kohm PULLUP! THIS IS NOT NORMAL!) +// 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 = { + { 1 * OVERSAMPLENR, 350 }, + { 190 * OVERSAMPLENR, 250 }, // top rating 250C + { 203 * OVERSAMPLENR, 245 }, + { 217 * OVERSAMPLENR, 240 }, + { 232 * OVERSAMPLENR, 235 }, + { 248 * OVERSAMPLENR, 230 }, + { 265 * OVERSAMPLENR, 225 }, + { 283 * OVERSAMPLENR, 220 }, + { 302 * OVERSAMPLENR, 215 }, + { 322 * OVERSAMPLENR, 210 }, + { 344 * OVERSAMPLENR, 205 }, + { 366 * OVERSAMPLENR, 200 }, + { 390 * OVERSAMPLENR, 195 }, + { 415 * OVERSAMPLENR, 190 }, + { 440 * OVERSAMPLENR, 185 }, + { 467 * OVERSAMPLENR, 180 }, + { 494 * OVERSAMPLENR, 175 }, + { 522 * OVERSAMPLENR, 170 }, + { 551 * OVERSAMPLENR, 165 }, + { 580 * OVERSAMPLENR, 160 }, + { 609 * OVERSAMPLENR, 155 }, + { 638 * OVERSAMPLENR, 150 }, + { 666 * OVERSAMPLENR, 145 }, + { 695 * OVERSAMPLENR, 140 }, + { 722 * OVERSAMPLENR, 135 }, + { 749 * OVERSAMPLENR, 130 }, + { 775 * OVERSAMPLENR, 125 }, + { 800 * OVERSAMPLENR, 120 }, + { 823 * OVERSAMPLENR, 115 }, + { 845 * OVERSAMPLENR, 110 }, + { 865 * OVERSAMPLENR, 105 }, + { 884 * OVERSAMPLENR, 100 }, + { 901 * OVERSAMPLENR, 95 }, + { 917 * OVERSAMPLENR, 90 }, + { 932 * OVERSAMPLENR, 85 }, + { 944 * OVERSAMPLENR, 80 }, + { 956 * OVERSAMPLENR, 75 }, + { 966 * OVERSAMPLENR, 70 }, + { 975 * OVERSAMPLENR, 65 }, + { 982 * OVERSAMPLENR, 60 }, + { 989 * OVERSAMPLENR, 55 }, + { 995 * OVERSAMPLENR, 50 }, + { 1000 * OVERSAMPLENR, 45 }, + { 1004 * OVERSAMPLENR, 40 }, + { 1007 * OVERSAMPLENR, 35 }, + { 1010 * OVERSAMPLENR, 30 }, + { 1013 * OVERSAMPLENR, 25 }, + { 1015 * OVERSAMPLENR, 20 }, + { 1017 * OVERSAMPLENR, 15 }, + { 1018 * OVERSAMPLENR, 10 }, + { 1019 * OVERSAMPLENR, 5 }, + { 1020 * OVERSAMPLENR, 0 }, + { 1021 * OVERSAMPLENR, -5 } +}; +#endif + +#if ANY_THERMISTOR_IS(52) +// 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 +// 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 = { + { 1 * OVERSAMPLENR, 500 }, + { 125 * OVERSAMPLENR, 300 }, // top rating 300C + { 142 * OVERSAMPLENR, 290 }, + { 162 * OVERSAMPLENR, 280 }, + { 185 * OVERSAMPLENR, 270 }, + { 211 * OVERSAMPLENR, 260 }, + { 240 * OVERSAMPLENR, 250 }, + { 274 * OVERSAMPLENR, 240 }, + { 312 * OVERSAMPLENR, 230 }, + { 355 * OVERSAMPLENR, 220 }, + { 401 * OVERSAMPLENR, 210 }, + { 452 * OVERSAMPLENR, 200 }, + { 506 * OVERSAMPLENR, 190 }, + { 563 * OVERSAMPLENR, 180 }, + { 620 * OVERSAMPLENR, 170 }, + { 677 * OVERSAMPLENR, 160 }, + { 732 * OVERSAMPLENR, 150 }, + { 783 * OVERSAMPLENR, 140 }, + { 830 * OVERSAMPLENR, 130 }, + { 871 * OVERSAMPLENR, 120 }, + { 906 * OVERSAMPLENR, 110 }, + { 935 * OVERSAMPLENR, 100 }, + { 958 * OVERSAMPLENR, 90 }, + { 976 * OVERSAMPLENR, 80 }, + { 990 * OVERSAMPLENR, 70 }, + { 1000 * OVERSAMPLENR, 60 }, + { 1008 * OVERSAMPLENR, 50 }, + { 1013 * OVERSAMPLENR, 40 }, + { 1017 * OVERSAMPLENR, 30 }, + { 1019 * OVERSAMPLENR, 20 }, + { 1021 * OVERSAMPLENR, 10 }, + { 1022 * OVERSAMPLENR, 0 } +}; +#endif + +#if ANY_THERMISTOR_IS(55) +// 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 +// 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 = { + { 1 * OVERSAMPLENR, 500 }, + { 76 * OVERSAMPLENR, 300 }, + { 87 * OVERSAMPLENR, 290 }, + { 100 * OVERSAMPLENR, 280 }, + { 114 * OVERSAMPLENR, 270 }, + { 131 * OVERSAMPLENR, 260 }, + { 152 * OVERSAMPLENR, 250 }, + { 175 * OVERSAMPLENR, 240 }, + { 202 * OVERSAMPLENR, 230 }, + { 234 * OVERSAMPLENR, 220 }, + { 271 * OVERSAMPLENR, 210 }, + { 312 * OVERSAMPLENR, 200 }, + { 359 * OVERSAMPLENR, 190 }, + { 411 * OVERSAMPLENR, 180 }, + { 467 * OVERSAMPLENR, 170 }, + { 527 * OVERSAMPLENR, 160 }, + { 590 * OVERSAMPLENR, 150 }, + { 652 * OVERSAMPLENR, 140 }, + { 713 * OVERSAMPLENR, 130 }, + { 770 * OVERSAMPLENR, 120 }, + { 822 * OVERSAMPLENR, 110 }, + { 867 * OVERSAMPLENR, 100 }, + { 905 * OVERSAMPLENR, 90 }, + { 936 * OVERSAMPLENR, 80 }, + { 961 * OVERSAMPLENR, 70 }, + { 979 * OVERSAMPLENR, 60 }, + { 993 * OVERSAMPLENR, 50 }, + { 1003 * OVERSAMPLENR, 40 }, + { 1010 * OVERSAMPLENR, 30 }, + { 1015 * OVERSAMPLENR, 20 }, + { 1018 * OVERSAMPLENR, 10 }, + { 1020 * OVERSAMPLENR, 0 } +}; +#endif + +#if ANY_THERMISTOR_IS(60) // Maker's Tool Works Kapton Bed Thermistor +// ./createTemperatureLookup.py --r0=100000 --t0=25 --r1=0 --r2=4700 --beta=3950 +// r0: 100000 +// t0: 25 +// r1: 0 (parallel with rTherm) +// r2: 4700 (series with rTherm) +// beta: 3950 +// min adc: 1 at 0.0048828125 V +// max adc: 1023 at 4.9951171875 V +const short temptable_60[][2] PROGMEM = { + { 51 * OVERSAMPLENR, 272 }, + { 61 * OVERSAMPLENR, 258 }, + { 71 * OVERSAMPLENR, 247 }, + { 81 * OVERSAMPLENR, 237 }, + { 91 * OVERSAMPLENR, 229 }, + { 101 * OVERSAMPLENR, 221 }, + { 131 * OVERSAMPLENR, 204 }, + { 161 * OVERSAMPLENR, 190 }, + { 191 * OVERSAMPLENR, 179 }, + { 231 * OVERSAMPLENR, 167 }, + { 271 * OVERSAMPLENR, 157 }, + { 311 * OVERSAMPLENR, 148 }, + { 351 * OVERSAMPLENR, 140 }, + { 381 * OVERSAMPLENR, 135 }, + { 411 * OVERSAMPLENR, 130 }, + { 441 * OVERSAMPLENR, 125 }, + { 451 * OVERSAMPLENR, 123 }, + { 461 * OVERSAMPLENR, 122 }, + { 471 * OVERSAMPLENR, 120 }, + { 481 * OVERSAMPLENR, 119 }, + { 491 * OVERSAMPLENR, 117 }, + { 501 * OVERSAMPLENR, 116 }, + { 511 * OVERSAMPLENR, 114 }, + { 521 * OVERSAMPLENR, 113 }, + { 531 * OVERSAMPLENR, 111 }, + { 541 * OVERSAMPLENR, 110 }, + { 551 * OVERSAMPLENR, 108 }, + { 561 * OVERSAMPLENR, 107 }, + { 571 * OVERSAMPLENR, 105 }, + { 581 * OVERSAMPLENR, 104 }, + { 591 * OVERSAMPLENR, 102 }, + { 601 * OVERSAMPLENR, 101 }, + { 611 * OVERSAMPLENR, 100 }, + { 621 * OVERSAMPLENR, 98 }, + { 631 * OVERSAMPLENR, 97 }, + { 641 * OVERSAMPLENR, 95 }, + { 651 * OVERSAMPLENR, 94 }, + { 661 * OVERSAMPLENR, 92 }, + { 671 * OVERSAMPLENR, 91 }, + { 681 * OVERSAMPLENR, 90 }, + { 691 * OVERSAMPLENR, 88 }, + { 701 * OVERSAMPLENR, 87 }, + { 711 * OVERSAMPLENR, 85 }, + { 721 * OVERSAMPLENR, 84 }, + { 731 * OVERSAMPLENR, 82 }, + { 741 * OVERSAMPLENR, 81 }, + { 751 * OVERSAMPLENR, 79 }, + { 761 * OVERSAMPLENR, 77 }, + { 771 * OVERSAMPLENR, 76 }, + { 781 * OVERSAMPLENR, 74 }, + { 791 * OVERSAMPLENR, 72 }, + { 801 * OVERSAMPLENR, 71 }, + { 811 * OVERSAMPLENR, 69 }, + { 821 * OVERSAMPLENR, 67 }, + { 831 * OVERSAMPLENR, 65 }, + { 841 * OVERSAMPLENR, 63 }, + { 851 * OVERSAMPLENR, 62 }, + { 861 * OVERSAMPLENR, 60 }, + { 871 * OVERSAMPLENR, 57 }, + { 881 * OVERSAMPLENR, 55 }, + { 891 * OVERSAMPLENR, 53 }, + { 901 * OVERSAMPLENR, 51 }, + { 911 * OVERSAMPLENR, 48 }, + { 921 * OVERSAMPLENR, 45 }, + { 931 * OVERSAMPLENR, 42 }, + { 941 * OVERSAMPLENR, 39 }, + { 951 * OVERSAMPLENR, 36 }, + { 961 * OVERSAMPLENR, 32 }, + { 981 * OVERSAMPLENR, 23 }, + { 991 * OVERSAMPLENR, 17 }, + { 1001 * OVERSAMPLENR, 9 }, + { 1008 * OVERSAMPLENR, 0 } +}; +#endif + +#if ANY_THERMISTOR_IS(66) +// DyzeDesign 500°C Thermistor +const short temptable_66[][2] PROGMEM = { + { 17.5 * OVERSAMPLENR, 850 }, + { 17.9 * OVERSAMPLENR, 500 }, + { 21.7 * OVERSAMPLENR, 480 }, + { 26.6 * OVERSAMPLENR, 460 }, + { 33.1 * OVERSAMPLENR, 440 }, + { 41.0 * OVERSAMPLENR, 420 }, + { 52.3 * OVERSAMPLENR, 400 }, + { 67.7 * OVERSAMPLENR, 380 }, + { 86.5 * OVERSAMPLENR, 360 }, + { 112.0 * OVERSAMPLENR, 340 }, + { 147.2 * OVERSAMPLENR, 320 }, + { 194.0 * OVERSAMPLENR, 300 }, + { 254.3 * OVERSAMPLENR, 280 }, + { 330.2 * OVERSAMPLENR, 260 }, + { 427.9 * OVERSAMPLENR, 240 }, + { 533.4 * OVERSAMPLENR, 220 }, + { 646.5 * OVERSAMPLENR, 200 }, + { 754.4 * OVERSAMPLENR, 180 }, + { 844.3 * OVERSAMPLENR, 160 }, + { 911.7 * OVERSAMPLENR, 140 }, + { 958.6 * OVERSAMPLENR, 120 }, + { 988.8 * OVERSAMPLENR, 100 }, + { 1006.6 * OVERSAMPLENR, 80 }, + { 1015.8 * OVERSAMPLENR, 60 }, + { 1021.3 * OVERSAMPLENR, 30 }, + { 1023 * OVERSAMPLENR - 1, 25}, + { 1023 * OVERSAMPLENR, 20} +}; +#endif + +#if ANY_THERMISTOR_IS(12) +// 100k 0603 SMD Vishay NTCS0603E3104FXT (4.7k pullup) (calibrated for Makibox hot bed) +const short temptable_12[][2] PROGMEM = { + { 35 * OVERSAMPLENR, 180 }, // top rating 180C + { 211 * OVERSAMPLENR, 140 }, + { 233 * OVERSAMPLENR, 135 }, + { 261 * OVERSAMPLENR, 130 }, + { 290 * OVERSAMPLENR, 125 }, + { 328 * OVERSAMPLENR, 120 }, + { 362 * OVERSAMPLENR, 115 }, + { 406 * OVERSAMPLENR, 110 }, + { 446 * OVERSAMPLENR, 105 }, + { 496 * OVERSAMPLENR, 100 }, + { 539 * OVERSAMPLENR, 95 }, + { 585 * OVERSAMPLENR, 90 }, + { 629 * OVERSAMPLENR, 85 }, + { 675 * OVERSAMPLENR, 80 }, + { 718 * OVERSAMPLENR, 75 }, + { 758 * OVERSAMPLENR, 70 }, + { 793 * OVERSAMPLENR, 65 }, + { 822 * OVERSAMPLENR, 60 }, + { 841 * OVERSAMPLENR, 55 }, + { 875 * OVERSAMPLENR, 50 }, + { 899 * OVERSAMPLENR, 45 }, + { 926 * OVERSAMPLENR, 40 }, + { 946 * OVERSAMPLENR, 35 }, + { 962 * OVERSAMPLENR, 30 }, + { 977 * OVERSAMPLENR, 25 }, + { 987 * OVERSAMPLENR, 20 }, + { 995 * OVERSAMPLENR, 15 }, + { 1001 * OVERSAMPLENR, 10 }, + { 1010 * OVERSAMPLENR, 0 }, + { 1023 * OVERSAMPLENR, -40 } +}; +#endif + +#if ANY_THERMISTOR_IS(70) // bqh2 stock thermistor +const short temptable_70[][2] PROGMEM = { + { 22 * OVERSAMPLENR, 300 }, + { 24 * OVERSAMPLENR, 295 }, + { 25 * OVERSAMPLENR, 290 }, + { 27 * OVERSAMPLENR, 285 }, + { 29 * OVERSAMPLENR, 280 }, + { 32 * OVERSAMPLENR, 275 }, + { 34 * OVERSAMPLENR, 270 }, + { 37 * OVERSAMPLENR, 265 }, + { 40 * OVERSAMPLENR, 260 }, + { 43 * OVERSAMPLENR, 255 }, + { 46 * OVERSAMPLENR, 250 }, + { 50 * OVERSAMPLENR, 245 }, + { 54 * OVERSAMPLENR, 240 }, + { 59 * OVERSAMPLENR, 235 }, + { 64 * OVERSAMPLENR, 230 }, + { 70 * OVERSAMPLENR, 225 }, + { 76 * OVERSAMPLENR, 220 }, + { 83 * OVERSAMPLENR, 215 }, + { 90 * OVERSAMPLENR, 210 }, + { 99 * OVERSAMPLENR, 205 }, + { 108 * OVERSAMPLENR, 200 }, + { 118 * OVERSAMPLENR, 195 }, + { 129 * OVERSAMPLENR, 190 }, + { 141 * OVERSAMPLENR, 185 }, + { 154 * OVERSAMPLENR, 180 }, + { 169 * OVERSAMPLENR, 175 }, + { 185 * OVERSAMPLENR, 170 }, + { 203 * OVERSAMPLENR, 165 }, + { 222 * OVERSAMPLENR, 160 }, + { 243 * OVERSAMPLENR, 155 }, + { 266 * OVERSAMPLENR, 150 }, + { 290 * OVERSAMPLENR, 145 }, + { 317 * OVERSAMPLENR, 140 }, + { 346 * OVERSAMPLENR, 135 }, + { 376 * OVERSAMPLENR, 130 }, + { 408 * OVERSAMPLENR, 125 }, + { 442 * OVERSAMPLENR, 120 }, + { 477 * OVERSAMPLENR, 115 }, + { 513 * OVERSAMPLENR, 110 }, + { 551 * OVERSAMPLENR, 105 }, + { 588 * OVERSAMPLENR, 100 }, + { 626 * OVERSAMPLENR, 95 }, + { 663 * OVERSAMPLENR, 90 }, + { 699 * OVERSAMPLENR, 85 }, + { 735 * OVERSAMPLENR, 80 }, + { 768 * OVERSAMPLENR, 75 }, + { 800 * OVERSAMPLENR, 70 }, + { 829 * OVERSAMPLENR, 65 }, + { 856 * OVERSAMPLENR, 60 }, + { 881 * OVERSAMPLENR, 55 }, + { 903 * OVERSAMPLENR, 50 }, + { 922 * OVERSAMPLENR, 45 }, + { 939 * OVERSAMPLENR, 40 }, + { 954 * OVERSAMPLENR, 35 }, + { 966 * OVERSAMPLENR, 30 }, + { 977 * OVERSAMPLENR, 25 }, + { 986 * OVERSAMPLENR, 20 }, + { 994 * OVERSAMPLENR, 15 }, + { 1000 * OVERSAMPLENR, 10 }, + { 1005 * OVERSAMPLENR, 5 }, + { 1009 * OVERSAMPLENR, 0 } // safety +}; +#endif + +// Pt1000 and Pt100 handling +// +// Rt=R0*(1+a*T+b*T*T) [for T>0] +// a=3.9083E-3, b=-5.775E-7 + +#define PtA 3.9083E-3 +#define PtB -5.775E-7 +#define PtRt(T,R0) ((R0)*(1.0+(PtA)*(T)+(PtB)*(T)*(T))) +#define PtAdVal(T,R0,Rup) (short)(1024/(Rup/PtRt(T,R0)+1)) +#define PtLine(T,R0,Rup) { PtAdVal(T,R0,Rup)*OVERSAMPLENR, T }, + +#if ANY_THERMISTOR_IS(110) // Pt100 with 1k0 pullup +const short temptable_110[][2] PROGMEM = { + // only few values are needed as the curve is very flat + PtLine( 0, 100, 1000) + PtLine( 50, 100, 1000) + PtLine(100, 100, 1000) + PtLine(150, 100, 1000) + PtLine(200, 100, 1000) + PtLine(250, 100, 1000) + PtLine(300, 100, 1000) +}; +#endif +#if ANY_THERMISTOR_IS(147) // Pt100 with 4k7 pullup +const short temptable_147[][2] PROGMEM = { + // only few values are needed as the curve is very flat + PtLine( 0, 100, 4700) + PtLine( 50, 100, 4700) + PtLine(100, 100, 4700) + PtLine(150, 100, 4700) + PtLine(200, 100, 4700) + PtLine(250, 100, 4700) + PtLine(300, 100, 4700) +}; +#endif +#if ANY_THERMISTOR_IS(1010) // Pt1000 with 1k0 pullup +const short temptable_1010[][2] PROGMEM = { + PtLine( 0, 1000, 1000) + PtLine( 25, 1000, 1000) + PtLine( 50, 1000, 1000) + PtLine( 75, 1000, 1000) + PtLine(100, 1000, 1000) + PtLine(125, 1000, 1000) + PtLine(150, 1000, 1000) + PtLine(175, 1000, 1000) + PtLine(200, 1000, 1000) + PtLine(225, 1000, 1000) + PtLine(250, 1000, 1000) + PtLine(275, 1000, 1000) + PtLine(300, 1000, 1000) +}; +#endif +#if ANY_THERMISTOR_IS(1047) // Pt1000 with 4k7 pullup +const short temptable_1047[][2] PROGMEM = { + // only few values are needed as the curve is very flat + PtLine( 0, 1000, 4700) + PtLine( 50, 1000, 4700) + PtLine(100, 1000, 4700) + PtLine(150, 1000, 4700) + PtLine(200, 1000, 4700) + PtLine(250, 1000, 4700) + PtLine(300, 1000, 4700) +}; +#endif + +#if ANY_THERMISTOR_IS(999) // User-defined table + // Dummy Thermistor table.. It will ALWAYS read a fixed value. + #ifndef DUMMY_THERMISTOR_999_VALUE + #define DUMMY_THERMISTOR_999_VALUE 25 + #endif + const short temptable_999[][2] PROGMEM = { + { 1 * OVERSAMPLENR, DUMMY_THERMISTOR_999_VALUE }, + { 1023 * OVERSAMPLENR, DUMMY_THERMISTOR_999_VALUE } +}; +#endif + +#if ANY_THERMISTOR_IS(998) // User-defined table + // Dummy Thermistor table.. It will ALWAYS read a fixed value. + #ifndef DUMMY_THERMISTOR_998_VALUE + #define DUMMY_THERMISTOR_998_VALUE 25 + #endif + const short temptable_998[][2] PROGMEM = { + { 1 * OVERSAMPLENR, DUMMY_THERMISTOR_998_VALUE }, + { 1023 * OVERSAMPLENR, DUMMY_THERMISTOR_998_VALUE } +}; +#endif + + +#define _TT_NAME(_N) temptable_ ## _N +#define TT_NAME(_N) _TT_NAME(_N) + +#ifdef THERMISTORHEATER_0 + #define HEATER_0_TEMPTABLE TT_NAME(THERMISTORHEATER_0) + #define HEATER_0_TEMPTABLE_LEN COUNT(HEATER_0_TEMPTABLE) +#else + #ifdef HEATER_0_USES_THERMISTOR + #error "No heater 0 thermistor table specified" + #else // HEATER_0_USES_THERMISTOR + #define HEATER_0_TEMPTABLE NULL + #define HEATER_0_TEMPTABLE_LEN 0 + #endif // HEATER_0_USES_THERMISTOR +#endif + +// Set the high and low raw values for the heater, this indicates which raw value is a high or low temperature +#ifndef HEATER_0_RAW_HI_TEMP + #ifdef HEATER_0_USES_THERMISTOR // In case of a thermistor the highest temperature results in the lowest ADC value + #define HEATER_0_RAW_HI_TEMP 0 + #define HEATER_0_RAW_LO_TEMP 16383 + #else // In case of an thermocouple the highest temperature results in the highest ADC value + #define HEATER_0_RAW_HI_TEMP 16383 + #define HEATER_0_RAW_LO_TEMP 0 + #endif +#endif + +#ifdef THERMISTORHEATER_1 + #define HEATER_1_TEMPTABLE TT_NAME(THERMISTORHEATER_1) + #define HEATER_1_TEMPTABLE_LEN COUNT(HEATER_1_TEMPTABLE) +#else + #ifdef HEATER_1_USES_THERMISTOR + #error "No heater 1 thermistor table specified" + #else // HEATER_1_USES_THERMISTOR + #define HEATER_1_TEMPTABLE NULL + #define HEATER_1_TEMPTABLE_LEN 0 + #endif // HEATER_1_USES_THERMISTOR +#endif + +// Set the high and low raw values for the heater, this indicates which raw value is a high or low temperature +#ifndef HEATER_1_RAW_HI_TEMP + #ifdef HEATER_1_USES_THERMISTOR // In case of a thermistor the highest temperature results in the lowest ADC value + #define HEATER_1_RAW_HI_TEMP 0 + #define HEATER_1_RAW_LO_TEMP 16383 + #else // In case of an thermocouple the highest temperature results in the highest ADC value + #define HEATER_1_RAW_HI_TEMP 16383 + #define HEATER_1_RAW_LO_TEMP 0 + #endif +#endif + +#ifdef THERMISTORHEATER_2 + #define HEATER_2_TEMPTABLE TT_NAME(THERMISTORHEATER_2) + #define HEATER_2_TEMPTABLE_LEN COUNT(HEATER_2_TEMPTABLE) +#else + #ifdef HEATER_2_USES_THERMISTOR + #error "No heater 2 thermistor table specified" + #else // HEATER_2_USES_THERMISTOR + #define HEATER_2_TEMPTABLE NULL + #define HEATER_2_TEMPTABLE_LEN 0 + #endif // HEATER_2_USES_THERMISTOR +#endif + +// Set the high and low raw values for the heater, this indicates which raw value is a high or low temperature +#ifndef HEATER_2_RAW_HI_TEMP + #ifdef HEATER_2_USES_THERMISTOR // In case of a thermistor the highest temperature results in the lowest ADC value + #define HEATER_2_RAW_HI_TEMP 0 + #define HEATER_2_RAW_LO_TEMP 16383 + #else // In case of an thermocouple the highest temperature results in the highest ADC value + #define HEATER_2_RAW_HI_TEMP 16383 + #define HEATER_2_RAW_LO_TEMP 0 + #endif +#endif + +#ifdef THERMISTORHEATER_3 + #define HEATER_3_TEMPTABLE TT_NAME(THERMISTORHEATER_3) + #define HEATER_3_TEMPTABLE_LEN COUNT(HEATER_3_TEMPTABLE) +#else + #ifdef HEATER_3_USES_THERMISTOR + #error "No heater 3 thermistor table specified" + #else // HEATER_3_USES_THERMISTOR + #define HEATER_3_TEMPTABLE NULL + #define HEATER_3_TEMPTABLE_LEN 0 + #endif // HEATER_3_USES_THERMISTOR +#endif + +// Set the high and low raw values for the heater, this indicates which raw value is a high or low temperature +#ifndef HEATER_3_RAW_HI_TEMP + #ifdef HEATER_3_USES_THERMISTOR // In case of a thermistor the highest temperature results in the lowest ADC value + #define HEATER_3_RAW_HI_TEMP 0 + #define HEATER_3_RAW_LO_TEMP 16383 + #else // In case of an thermocouple the highest temperature results in the highest ADC value + #define HEATER_3_RAW_HI_TEMP 16383 + #define HEATER_3_RAW_LO_TEMP 0 + #endif +#endif + +#ifdef THERMISTORBED + #define BEDTEMPTABLE TT_NAME(THERMISTORBED) + #define BEDTEMPTABLE_LEN COUNT(BEDTEMPTABLE) +#else + #ifdef BED_USES_THERMISTOR + #error "No bed thermistor table specified" + #endif // BED_USES_THERMISTOR +#endif + +// Set the high and low raw values for the heater, this indicates which raw value is a high or low temperature +#ifndef HEATER_BED_RAW_HI_TEMP + #ifdef BED_USES_THERMISTOR // In case of a thermistor the highest temperature results in the lowest ADC value + #define HEATER_BED_RAW_HI_TEMP 0 + #define HEATER_BED_RAW_LO_TEMP 16383 + #else // In case of an thermocouple the highest temperature results in the highest ADC value + #define HEATER_BED_RAW_HI_TEMP 16383 + #define HEATER_BED_RAW_LO_TEMP 0 + #endif +#endif + +#endif // THERMISTORTABLES_H_ diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/twibus.cpp b/trunk/Arduino/Marlin_K8600_1.1.0RC7/twibus.cpp new file mode 100644 index 00000000..c1d6008d --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/twibus.cpp @@ -0,0 +1,118 @@ +/* + * 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 . + * + */ + +#include "Marlin.h" + +#if ENABLED(EXPERIMENTAL_I2CBUS) + +#include "twibus.h" + +#include + +TWIBus::TWIBus() { + Wire.begin(); // We use no address so we will join the BUS as the master + this->reset(); +} + +void TWIBus::reset() { + this->addr = 0; + this->buffer_s = 0; + this->buffer[0] = 0x00; +} + +void TWIBus::address(uint8_t addr) { + this->addr = addr; + + #if ENABLED(DEBUG_TWIBUS) + debug(PSTR("sendto"), this->addr); + #endif +} + +void TWIBus::addbyte(char c) { + if (buffer_s >= sizeof(this->buffer)) return; + this->buffer[this->buffer_s++] = c; + + #if ENABLED(DEBUG_TWIBUS) + debug(PSTR("addbyte"), this->buffer[this->buffer_s - 1]); + #endif +} + +void TWIBus::send() { + if (!this->addr) return; + + #if ENABLED(DEBUG_TWIBUS) + debug(PSTR("send()")); + #endif + + Wire.beginTransmission(this->addr); + Wire.write(this->buffer, this->buffer_s); + Wire.endTransmission(); + + // Reset the buffer after sending the data + this->reset(); +} + +void TWIBus::reqbytes(uint8_t bytes) { + if (!this->addr) return; + + #if ENABLED(DEBUG_TWIBUS) + debug(PSTR("reqbytes"), bytes); + #endif + + millis_t t = millis() + this->timeout; + Wire.requestFrom(this->addr, bytes); + + // requestFrom() is a blocking function + while (Wire.available() < bytes) { + if (ELAPSED(millis(), t)) break; + else continue; + } + + SERIAL_ECHO_START; + SERIAL_ECHOPAIR("i2c-reply: from:", this->addr); + SERIAL_ECHOPAIR(" bytes:", Wire.available()); + SERIAL_ECHOPGM (" data:"); + + // Protect against buffer overflows if the number of received bytes + // is less than the number of requested bytes + uint8_t wba = Wire.available(); + for (int i = 0; i < wba; i++) SERIAL_CHAR(Wire.read()); + SERIAL_EOL; + + // Reset the buffer after sending the data + this->reset(); +} + +#if ENABLED(DEBUG_TWIBUS) + + void TWIBus::debug(const char func[], int32_t val/*=-1*/) { + if (DEBUGGING(INFO)) { + SERIAL_ECHOPGM("TWIBus::"); + serialprintPGM(func); + if (val >= 0) SERIAL_ECHOPAIR(": ", val); + SERIAL_EOL; + } + } + +#endif + +#endif //EXPERIMENTAL_I2CBUS diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/twibus.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/twibus.h new file mode 100644 index 00000000..d0d0e0ff --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/twibus.h @@ -0,0 +1,137 @@ +/* + * 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 . + * + */ + +#ifndef TWIBUS_H +#define TWIBUS_H + +#include "macros.h" + +// Print debug messages with M111 S2 (Uses 236 bytes of PROGMEM) +//#define DEBUG_TWIBUS + +/** + * TWIBUS class + * + * This class implements a wrapper around the two wire (I2C) bus, it allows + * Marlin to send and request data from any slave device on the bus. This is + * an experimental feature and it's inner workings as well as public facing + * interface are prune to change in the future. + * + * The two main consumers of this class are M155 and M156, where M155 allows + * Marlin to send a I2C packet to a device (please be aware that no repeated + * starts are possible), this can be done in caching method by calling multiple + * times M155 B or a one liner M155, have a look at + * the gcode_M155() function for more information. M156 allows Marlin to + * request data from a device, the received data is then relayed into the serial + * line for host interpretation. + * + */ +class TWIBus { + private: + /** + * @brief Timeout value in milliseconds + * @details For blocking operations this constant value will set the max + * amount of time Marlin will keep waiting for a reply. Useful is something + * goes wrong on the bus and the SDA/SCL lines are held up by another device. + */ + const int timeout = 5; + + /** + * @brief Target device address + * @description This stores, until the buffer is flushed, the target device + * address, take not we do follow Arduino 7bit addressing. + */ + uint8_t addr = 0; + + /** + * @brief Number of bytes on buffer + * @description This var holds the total number of bytes on our buffer + * waiting to be flushed to the bus. + */ + uint8_t buffer_s = 0; + + /** + * @brief Internal buffer + * @details This is a fixed buffer, TWI command cannot be longer than this + */ + char buffer[30]; + + + public: + /** + * @brief Class constructor + * @details Initialized the TWI bus and clears the buffer + */ + TWIBus(); + + /** + * @brief Reset the buffer + * @details Brings the internal buffer to a known-empty state + */ + void reset(); + + /** + * @brief Send the buffer data to the bus + * @details Flushed the buffer into the bus targeting the cached slave device + * address. + */ + void send(); + + /** + * @brief Add one byte to the buffer + * @details Adds the byte to the buffer in a sequential way, if buffer is full + * the request is silently ignored. + * + * @param c a data byte + */ + void addbyte(char c); + + /** + * @brief Sets the target slave address + * @details The target slave address is stored so it can be later used when + * the complete packet needs to be sent over the bus. + * + * @param addr 7-bit integer address + */ + void address(uint8_t addr); + + /** + * @brief Request data from slave device + * @details Requests data from a slave device, when the data is received it will + * be relayed to the serial line using a parser-friendly formatting. + * + * @param bytes the number of bytes to request + */ + void reqbytes(uint8_t bytes); + + #if ENABLED(DEBUG_TWIBUS) + + /** + * @brief Prints a debug message + * @details Prints a simple debug message "TWIBus::function: value" + */ + static void debug(const char func[], int32_t val = -1); + + #endif +}; + +#endif //TWIBUS_H diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/types.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/types.h new file mode 100644 index 00000000..8ab7beeb --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/types.h @@ -0,0 +1,28 @@ +/** + * 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 . + * + */ + +#ifndef __TYPES_H__ +#define __TYPES_H__ + +typedef unsigned long millis_t; + +#endif diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/ultralcd.cpp b/trunk/Arduino/Marlin_K8600_1.1.0RC7/ultralcd.cpp new file mode 100644 index 00000000..e724d640 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/ultralcd.cpp @@ -0,0 +1,3305 @@ +/** + * 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 . + * + */ + +#include "ultralcd.h" +#if ENABLED(ULTRA_LCD) +#include "Marlin.h" +#include "language.h" +#include "cardreader.h" +#include "temperature.h" +#include "stepper.h" +#include "configuration_store.h" + +#if ENABLED(PRINTCOUNTER) + #include "printcounter.h" + #include "duration_t.h" +#endif + +int preheatHotendTemp1, preheatBedTemp1, preheatFanSpeed1, + preheatHotendTemp2, preheatBedTemp2, preheatFanSpeed2; + +#if ENABLED(FILAMENT_LCD_DISPLAY) + millis_t previous_lcd_status_ms = 0; +#endif + +uint8_t lcd_status_message_level; +char lcd_status_message[3 * (LCD_WIDTH) + 1] = WELCOME_MSG; // worst case is kana with up to 3*LCD_WIDTH+1 + +#if ENABLED(DOGLCD) + #include "ultralcd_impl_DOGM.h" +#else + #include "ultralcd_impl_HD44780.h" +#endif + +// The main status screen +static void lcd_status_screen(); + +millis_t next_lcd_update_ms; + +uint8_t lcdDrawUpdate = LCDVIEW_CLEAR_CALL_REDRAW; // Set when the LCD needs to draw, decrements after every draw. Set to 2 in LCD routines so the LCD gets at least 1 full redraw (first redraw is partial) + +#if ENABLED(ULTIPANEL) + + // place-holders for Ki and Kd edits + float raw_Ki, raw_Kd; + + /** + * REVERSE_MENU_DIRECTION + * + * To reverse the menu direction we need a general way to reverse + * the direction of the encoder everywhere. So encoderDirection is + * added to allow the encoder to go the other way. + * + * This behavior is limited to scrolling Menus and SD card listings, + * and is disabled in other contexts. + */ + #if ENABLED(REVERSE_MENU_DIRECTION) + int8_t encoderDirection = 1; + #define ENCODER_DIRECTION_NORMAL() (encoderDirection = 1) + #define ENCODER_DIRECTION_MENUS() (encoderDirection = -1) + #else + #define ENCODER_DIRECTION_NORMAL() ; + #define ENCODER_DIRECTION_MENUS() ; + #endif + + int8_t encoderDiff; // updated from interrupt context and added to encoderPosition every LCD update + + millis_t manual_move_start_time = 0; + int8_t manual_move_axis = (int8_t)NO_AXIS; + #if EXTRUDERS > 1 + int8_t manual_move_e_index = 0; + #else + #define manual_move_e_index 0 + #endif + + bool encoderRateMultiplierEnabled; + int32_t lastEncoderMovementMillis; + + #if HAS_POWER_SWITCH + extern bool powersupply; + #endif + const float manual_feedrate_mm_m[] = MANUAL_FEEDRATE; + static void lcd_main_menu(); + static void lcd_tune_menu(); + static void lcd_prepare_menu(); + static void lcd_move_menu(); + static void lcd_control_menu(); + static void lcd_control_temperature_menu(); + static void lcd_control_temperature_preheat_pla_settings_menu(); + static void lcd_control_temperature_preheat_abs_settings_menu(); + static void lcd_control_motion_menu(); + static void lcd_control_volumetric_menu(); + + //VERTEX NANO MENUS + static void lcd_led_menu(); + static void lcd_load_menu(); + static void preheat_menu(); + static void lcd_firmware_menu(); + + #if ENABLED(LCD_INFO_MENU) + #if ENABLED(PRINTCOUNTER) + static void lcd_info_stats_menu(); + #endif + static void lcd_info_thermistors_menu(); + static void lcd_info_board_menu(); + static void lcd_info_menu(); + #endif // LCD_INFO_MENU + + #if ENABLED(FILAMENT_CHANGE_FEATURE) + static void lcd_filament_change_option_menu(); + static void lcd_filament_change_init_message(); + static void lcd_filament_change_unload_message(); + static void lcd_filament_change_insert_message(); + static void lcd_filament_change_load_message(); + static void lcd_filament_change_extrude_message(); + static void lcd_filament_change_resume_message(); + #endif + + #if HAS_LCD_CONTRAST + static void lcd_set_contrast(); + #endif + + #if ENABLED(FWRETRACT) + static void lcd_control_retract_menu(); + #endif + + #if ENABLED(DELTA_CALIBRATION_MENU) + static void lcd_delta_calibrate_menu(); + #endif + + #if ENABLED(MANUAL_BED_LEVELING) + #include "mesh_bed_leveling.h" + #endif + + // Function pointer to menu functions. + typedef void (*screenFunc_t)(); + + // Different types of actions that can be used in menu items. + static void menu_action_back(); + static void menu_action_submenu(screenFunc_t data); + static void menu_action_gcode(const char* pgcode); + static void menu_action_function(screenFunc_t data); + static void menu_action_setting_edit_bool(const char* pstr, bool* ptr); + static void menu_action_setting_edit_int3(const char* pstr, int* ptr, int minValue, int maxValue); + static void menu_action_setting_edit_float3(const char* pstr, float* ptr, float minValue, float maxValue); + static void menu_action_setting_edit_float32(const char* pstr, float* ptr, float minValue, float maxValue); + static void menu_action_setting_edit_float43(const char* pstr, float* ptr, float minValue, float maxValue); + static void menu_action_setting_edit_float5(const char* pstr, float* ptr, float minValue, float maxValue); + static void menu_action_setting_edit_float51(const char* pstr, float* ptr, float minValue, float maxValue); + static void menu_action_setting_edit_float52(const char* pstr, float* ptr, float minValue, float maxValue); + static void menu_action_setting_edit_long5(const char* pstr, unsigned long* ptr, unsigned long minValue, unsigned long maxValue); + static void menu_action_setting_edit_callback_bool(const char* pstr, bool* ptr, screenFunc_t callbackFunc); + static void menu_action_setting_edit_callback_int3(const char* pstr, int* ptr, int minValue, int maxValue, screenFunc_t callbackFunc); + static void menu_action_setting_edit_callback_float3(const char* pstr, float* ptr, float minValue, float maxValue, screenFunc_t callbackFunc); + static void menu_action_setting_edit_callback_float32(const char* pstr, float* ptr, float minValue, float maxValue, screenFunc_t callbackFunc); + static void menu_action_setting_edit_callback_float43(const char* pstr, float* ptr, float minValue, float maxValue, screenFunc_t callbackFunc); + static void menu_action_setting_edit_callback_float5(const char* pstr, float* ptr, float minValue, float maxValue, screenFunc_t callbackFunc); + static void menu_action_setting_edit_callback_float51(const char* pstr, float* ptr, float minValue, float maxValue, screenFunc_t callbackFunc); + static void menu_action_setting_edit_callback_float52(const char* pstr, float* ptr, float minValue, float maxValue, screenFunc_t callbackFunc); + static void menu_action_setting_edit_callback_long5(const char* pstr, unsigned long* ptr, unsigned long minValue, unsigned long maxValue, screenFunc_t callbackFunc); + + #if ENABLED(SDSUPPORT) + static void lcd_sdcard_menu(); + static void menu_action_sdfile(const char* filename, char* longFilename); + static void menu_action_sddirectory(const char* filename, char* longFilename); + #endif + + /* Helper macros for menus */ + + #ifndef ENCODER_FEEDRATE_DEADZONE + #define ENCODER_FEEDRATE_DEADZONE 10 + #endif + #ifndef ENCODER_STEPS_PER_MENU_ITEM + #define ENCODER_STEPS_PER_MENU_ITEM 5 + #endif + #ifndef ENCODER_PULSES_PER_STEP + #define ENCODER_PULSES_PER_STEP 1 + #endif + + /** + * START_SCREEN_OR_MENU generates init code for a screen or menu + * + * encoderLine is the position based on the encoder + * 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 + * _countedItems is the total number of items in the menu (after one call) + */ + #define START_SCREEN_OR_MENU(LIMIT) \ + ENCODER_DIRECTION_MENUS(); \ + encoderRateMultiplierEnabled = false; \ + if (encoderPosition > 0x8000) encoderPosition = 0; \ + static int8_t _countedItems = 0; \ + int8_t encoderLine = encoderPosition / ENCODER_STEPS_PER_MENU_ITEM; \ + if (_countedItems > 0 && encoderLine >= _countedItems - LIMIT) { \ + encoderLine = _countedItems - LIMIT; \ + encoderPosition = encoderLine * (ENCODER_STEPS_PER_MENU_ITEM); \ + } + + #define SCREEN_OR_MENU_LOOP() \ + int8_t _menuLineNr = encoderTopLine, _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. + * 'wasClicked' indicates the controller was clicked. + */ + #define START_SCREEN() \ + START_SCREEN_OR_MENU(LCD_HEIGHT); \ + encoderTopLine = encoderLine; \ + bool _skipStatic = false; \ + SCREEN_OR_MENU_LOOP() + + #define START_MENU() \ + START_SCREEN_OR_MENU(1); \ + NOMORE(encoderTopLine, encoderLine); \ + if (encoderLine >= encoderTopLine + LCD_HEIGHT) { \ + encoderTopLine = encoderLine - (LCD_HEIGHT - 1); \ + } \ + bool wasClicked = LCD_CLICKED; \ + bool _skipStatic = true; \ + SCREEN_OR_MENU_LOOP() + + /** + * MENU_ITEM generates draw & handler code for a menu item, potentially calling: + * + * lcd_implementation_drawmenu_[type](sel, row, label, arg3...) + * menu_action_[type](arg3...) + * + * Examples: + * MENU_ITEM(back, MSG_WATCH) + * lcd_implementation_drawmenu_back(sel, row, PSTR(MSG_WATCH)) + * menu_action_back() + * + * MENU_ITEM(function, MSG_PAUSE_PRINT, lcd_sdcard_pause) + * lcd_implementation_drawmenu_function(sel, row, PSTR(MSG_PAUSE_PRINT), lcd_sdcard_pause) + * menu_action_function(lcd_sdcard_pause) + * + * MENU_ITEM_EDIT(int3, MSG_SPEED, &feedrate_percentage, 10, 999) + * MENU_ITEM(setting_edit_int3, MSG_SPEED, PSTR(MSG_SPEED), &feedrate_percentage, 10, 999) + * lcd_implementation_drawmenu_setting_edit_int3(sel, row, PSTR(MSG_SPEED), PSTR(MSG_SPEED), &feedrate_percentage, 10, 999) + * menu_action_setting_edit_int3(PSTR(MSG_SPEED), &feedrate_percentage, 10, 999) + * + */ + #define _MENU_ITEM_PART_1(TYPE, LABEL, ARGS...) \ + if (_menuLineNr == _thisItemNr) { \ + if (lcdDrawUpdate) \ + lcd_implementation_drawmenu_ ## TYPE(encoderLine == _thisItemNr, _lcdLineNr, PSTR(LABEL), ## ARGS); \ + if (wasClicked && encoderLine == _thisItemNr) { \ + lcd_quick_feedback() + + #define _MENU_ITEM_PART_2(TYPE, ARGS...) \ + menu_action_ ## TYPE(ARGS); \ + return; \ + } \ + } \ + ++_thisItemNr + + #define MENU_ITEM(TYPE, LABEL, ARGS...) do { \ + _skipStatic = false; \ + _MENU_ITEM_PART_1(TYPE, LABEL, ## ARGS); \ + _MENU_ITEM_PART_2(TYPE, ## ARGS); \ + } while(0) + + // Used to print static text with no visible cursor. + #define STATIC_ITEM(LABEL, ARGS...) \ + if (_menuLineNr == _thisItemNr) { \ + if (_skipStatic && encoderLine <= _thisItemNr) { \ + encoderPosition += ENCODER_STEPS_PER_MENU_ITEM; \ + lcdDrawUpdate = LCDVIEW_CALL_REDRAW_NEXT; \ + } \ + if (lcdDrawUpdate) \ + lcd_implementation_drawmenu_static(_lcdLineNr, PSTR(LABEL), ## ARGS); \ + } \ + ++_thisItemNr + + #define END_SCREEN() \ + } \ + _countedItems = _thisItemNr + + #define END_MENU() \ + } \ + _countedItems = _thisItemNr; \ + UNUSED(_skipStatic) + + #if ENABLED(ENCODER_RATE_MULTIPLIER) + + //#define ENCODER_RATE_MULTIPLIER_DEBUG // If defined, output the encoder steps per second value + + /** + * MENU_MULTIPLIER_ITEM generates drawing and handling code for a multiplier menu item + */ + #define MENU_MULTIPLIER_ITEM(type, label, args...) do { \ + _MENU_ITEM_PART_1(type, label, ## args); \ + encoderRateMultiplierEnabled = true; \ + lastEncoderMovementMillis = 0; \ + _MENU_ITEM_PART_2(type, ## args); \ + } while(0) + + #endif //ENCODER_RATE_MULTIPLIER + + #define MENU_ITEM_DUMMY() do { _thisItemNr++; } while(0) + #define MENU_ITEM_EDIT(type, label, args...) MENU_ITEM(setting_edit_ ## type, label, PSTR(label), ## args) + #define MENU_ITEM_EDIT_CALLBACK(type, label, args...) MENU_ITEM(setting_edit_callback_ ## type, label, PSTR(label), ## args) + #if ENABLED(ENCODER_RATE_MULTIPLIER) + #define MENU_MULTIPLIER_ITEM_EDIT(type, label, args...) MENU_MULTIPLIER_ITEM(setting_edit_ ## type, label, PSTR(label), ## args) + #define MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(type, label, args...) MENU_MULTIPLIER_ITEM(setting_edit_callback_ ## type, label, PSTR(label), ## args) + #else //!ENCODER_RATE_MULTIPLIER + #define MENU_MULTIPLIER_ITEM_EDIT(type, label, args...) MENU_ITEM(setting_edit_ ## type, label, PSTR(label), ## args) + #define MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(type, label, args...) MENU_ITEM(setting_edit_callback_ ## type, label, PSTR(label), ## args) + #endif //!ENCODER_RATE_MULTIPLIER + + /** Used variables to keep track of the menu */ + volatile uint8_t buttons; //the last checked buttons in a bit array. + #if ENABLED(REPRAPWORLD_KEYPAD) + volatile uint8_t buttons_reprapworld_keypad; // to store the keypad shift register values + #endif + + #if ENABLED(LCD_HAS_SLOW_BUTTONS) + volatile uint8_t slow_buttons; // Bits of the pressed buttons. + #endif + int8_t encoderTopLine; /* scroll offset in the current menu */ + millis_t next_button_update_ms; + uint8_t lastEncoderBits; + uint32_t encoderPosition; + #if PIN_EXISTS(SD_DETECT) + uint8_t lcd_sd_status; + #endif + + typedef struct { + screenFunc_t menu_function; + uint32_t encoder_position; + } menuPosition; + + screenFunc_t currentScreen = lcd_status_screen; // pointer to the currently active menu handler + + menuPosition screen_history[10]; + uint8_t screen_history_depth = 0; + + bool ignore_click = false; + bool wait_for_unclick; + bool defer_return_to_status = false; + + // Variables used when editing values. + const char* editLabel; + void* editValue; + int32_t minEditValue, maxEditValue; + screenFunc_t callbackFunc; // call this after editing + + /** + * General function to go directly to a menu + * Remembers the previous position + */ + static void lcd_goto_screen(screenFunc_t screen, const bool feedback = false, const uint32_t encoder = 0) { + if (currentScreen != screen) { + currentScreen = screen; + lcdDrawUpdate = LCDVIEW_CLEAR_CALL_REDRAW; + encoderPosition = encoder; + if (feedback) lcd_quick_feedback(); + if (screen == lcd_status_screen) { + defer_return_to_status = false; + screen_history_depth = 0; + } + #if ENABLED(LCD_PROGRESS_BAR) + // For LCD_PROGRESS_BAR re-initialize custom characters + lcd_set_custom_characters(screen == lcd_status_screen); + #endif + } + } + + static void lcd_return_to_status() { lcd_goto_screen(lcd_status_screen); } + + inline void lcd_save_previous_menu() { + if (screen_history_depth < COUNT(screen_history)) { + screen_history[screen_history_depth].menu_function = currentScreen; + screen_history[screen_history_depth].encoder_position = encoderPosition; + ++screen_history_depth; + } + } + + static void lcd_goto_previous_menu(bool feedback=false) { + if (screen_history_depth > 0) { + --screen_history_depth; + lcd_goto_screen( + screen_history[screen_history_depth].menu_function, + feedback, + screen_history[screen_history_depth].encoder_position + ); + } + else + lcd_return_to_status(); + } + + void lcd_ignore_click(bool b) { + ignore_click = b; + wait_for_unclick = false; + } + +#endif // ULTIPANEL + +/** + * + * "Info Screen" + * + * This is very display-dependent, so the lcd implementation draws this. + */ + +static void lcd_status_screen() { + + #if ENABLED(ULTIPANEL) + ENCODER_DIRECTION_NORMAL(); + encoderRateMultiplierEnabled = false; + #endif + + #if ENABLED(LCD_PROGRESS_BAR) + millis_t ms = millis(); + #if DISABLED(PROGRESS_MSG_ONCE) + if (ELAPSED(ms, progress_bar_ms + PROGRESS_BAR_MSG_TIME + PROGRESS_BAR_BAR_TIME)) { + progress_bar_ms = ms; + } + #endif + #if PROGRESS_MSG_EXPIRE > 0 + // Handle message expire + if (expire_status_ms > 0) { + #if ENABLED(SDSUPPORT) + if (card.isFileOpen()) { + // Expire the message when printing is active + if (IS_SD_PRINTING) { + if (ELAPSED(ms, expire_status_ms)) { + lcd_status_message[0] = '\0'; + expire_status_ms = 0; + } + } + else { + expire_status_ms += LCD_UPDATE_INTERVAL; + } + } + else { + expire_status_ms = 0; + } + #else + expire_status_ms = 0; + #endif //SDSUPPORT + } + #endif + #endif //LCD_PROGRESS_BAR + + lcd_implementation_status_screen(); + + #if ENABLED(ULTIPANEL) + + bool current_click = LCD_CLICKED; + + if (ignore_click) { + if (wait_for_unclick) { + if (!current_click) + ignore_click = wait_for_unclick = false; + else + current_click = false; + } + else if (current_click) { + lcd_quick_feedback(); + wait_for_unclick = true; + current_click = false; + } + } + + if (current_click) { + lcd_goto_screen(lcd_main_menu, true); + lcd_implementation_init( // to maybe revive the LCD if static electricity killed it. + #if ENABLED(LCD_PROGRESS_BAR) && ENABLED(ULTIPANEL) + currentScreen == lcd_status_screen + #endif + ); + #if ENABLED(FILAMENT_LCD_DISPLAY) + previous_lcd_status_ms = millis(); // get status message to show up for a while + #endif + } + + #if ENABLED(ULTIPANEL_FEEDMULTIPLY) + int new_frm = feedrate_percentage + (int32_t)encoderPosition; + // Dead zone at 100% feedrate + if ((feedrate_percentage < 100 && new_frm > 100) || (feedrate_percentage > 100 && new_frm < 100)) { + feedrate_percentage = 100; + encoderPosition = 0; + } + else if (feedrate_percentage == 100) { + if ((int32_t)encoderPosition > ENCODER_FEEDRATE_DEADZONE) { + feedrate_percentage += (int32_t)encoderPosition - (ENCODER_FEEDRATE_DEADZONE); + encoderPosition = 0; + } + else if ((int32_t)encoderPosition < -(ENCODER_FEEDRATE_DEADZONE)) { + feedrate_percentage += (int32_t)encoderPosition + ENCODER_FEEDRATE_DEADZONE; + encoderPosition = 0; + } + } + else { + feedrate_percentage = new_frm; + encoderPosition = 0; + } + #endif // ULTIPANEL_FEEDMULTIPLY + + feedrate_percentage = constrain(feedrate_percentage, 10, 999); + + #endif //ULTIPANEL +} + +/** + * + * draw the kill screen + * + */ +void kill_screen(const char* lcd_msg) { + lcd_init(); + lcd_setalertstatuspgm(lcd_msg); + #if ENABLED(DOGLCD) + u8g.firstPage(); + do { + lcd_kill_screen(); + } while (u8g.nextPage()); + #else + lcd_kill_screen(); + #endif +} + +#if ENABLED(ULTIPANEL) + + inline void line_to_current(AxisEnum axis) { + #if ENABLED(DELTA) + inverse_kinematics(current_position); + planner.buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], current_position[E_AXIS], MMM_TO_MMS(manual_feedrate_mm_m[axis]), active_extruder); + #else // !DELTA + planner.buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], MMM_TO_MMS(manual_feedrate_mm_m[axis]), active_extruder); + #endif // !DELTA + } + + #if ENABLED(SDSUPPORT) + + static void lcd_sdcard_pause() { + card.pauseSDPrint(); + print_job_timer.pause(); + } + + static void lcd_sdcard_resume() { + card.startFileprint(); + print_job_timer.start(); + } + + static void lcd_sdcard_stop() { + card.stopSDPrint(); + clear_command_queue(); + quickstop_stepper(); + print_job_timer.stop(); + //thermalManager.autotempShutdown(); + thermalManager.disable_all_heaters(); // Test to disable the heating instead of using autotemp + wait_for_heatup = false; + lcd_setstatus(MSG_PRINT_ABORTED, true); + } + + #endif //SDSUPPORT + + /** + * + * "Main" menu + * + */ + + static void lcd_main_menu() { + + START_MENU(); + MENU_ITEM(back, MSG_WATCH); + if (planner.movesplanned() || IS_SD_PRINTING) { + MENU_ITEM(submenu, MSG_TUNE, lcd_tune_menu); + } + else { + MENU_ITEM(submenu, MSG_PREPARE, lcd_prepare_menu); + #if ENABLED(DELTA_CALIBRATION_MENU) + MENU_ITEM(submenu, MSG_DELTA_CALIBRATE, lcd_delta_calibrate_menu); + #endif + } + MENU_ITEM(submenu, MSG_CONTROL, lcd_control_menu); + + #if ENABLED(SDSUPPORT) + if (card.cardOK) { + if (card.isFileOpen()) { + if (card.sdprinting) + MENU_ITEM(function, MSG_PAUSE_PRINT, lcd_sdcard_pause); + else + MENU_ITEM(function, MSG_RESUME_PRINT, lcd_sdcard_resume); + MENU_ITEM(function, MSG_STOP_PRINT, lcd_sdcard_stop); + } + else { + MENU_ITEM(submenu, MSG_CARD_MENU, lcd_sdcard_menu); + #if !PIN_EXISTS(SD_DETECT) + MENU_ITEM(gcode, MSG_CNG_SDCARD, PSTR("M21")); // SD-card changed by user + #endif + } + } + else { + MENU_ITEM(submenu, MSG_NO_CARD, lcd_sdcard_menu); + #if !PIN_EXISTS(SD_DETECT) + MENU_ITEM(gcode, MSG_INIT_SDCARD, PSTR("M21")); // Manually initialize the SD-card via user interface + #endif + } + #endif //SDSUPPORT + + #if ENABLED(LCD_INFO_MENU) + MENU_ITEM(submenu, MSG_INFO_MENU, lcd_info_menu); + #endif + MENU_ITEM(submenu, MSG_FIRMWARE, lcd_firmware_menu); + END_MENU(); + } + + void lcd_firmware_menu() + { + START_MENU(); + MENU_ITEM(function, MSG_SPLASH_NAME, lcd_return_to_status); + MENU_ITEM(function, MSG_SPLASH_FIRMWARE, lcd_return_to_status); + MENU_ITEM(function, MSG_SPLASH_WEBSITE1, lcd_return_to_status); + MENU_ITEM(function, MSG_SPLASH_WEBSITE2, lcd_return_to_status); + END_MENU(); + } + + void preheat_menu() + { + START_MENU(); + MENU_ITEM(back, MSG_PREHEAT); + MENU_ITEM(function, MSG_PREHEAT_1, lcd_preheat_pla0); + MENU_ITEM(function, MSG_PREHEAT_2, lcd_preheat_abs0); + END_MENU(); + } + + void lcd_load_menu() + { + START_MENU(); + MENU_ITEM(back, MSG_LOAD_FILAMENT); + MENU_ITEM(submenu, MSG_LOAD_ABS, lcd_load_menu_ABS); + MENU_ITEM(submenu, MSG_LOAD_PLA, lcd_load_menu_PLA); + MENU_ITEM(submenu, MSG_UNLOAD_ABS, lcd_unload_menu_ABS); + MENU_ITEM(submenu, MSG_UNLOAD_PLA, lcd_unload_menu_PLA); + END_MENU(); + } + + void lcd_load_menu_ABS() + { + START_MENU(); + MENU_ITEM(function, MSG_LOAD_TEXT0, lcd_load_menu_ABS_go); + MENU_ITEM(function, MSG_LOAD_TEXT1, lcd_load_menu_ABS_go); + MENU_ITEM(function, MSG_LOAD_TEXT2, lcd_load_menu_ABS_go); + MENU_ITEM(function, MSG_LOAD_TEXT3, lcd_load_menu_ABS_go); + END_MENU(); + } + + void lcd_load_menu_PLA() + { + START_MENU(); + MENU_ITEM(function, MSG_LOAD_TEXT0, lcd_load_menu_PLA_go); + MENU_ITEM(function, MSG_LOAD_TEXT1, lcd_load_menu_PLA_go); + MENU_ITEM(function, MSG_LOAD_TEXT2, lcd_load_menu_PLA_go); + MENU_ITEM(function, MSG_LOAD_TEXT3, lcd_load_menu_PLA_go); + END_MENU(); + } + + void lcd_load_menu_ABS_go() + { + enqueue_and_echo_commands_P(PSTR("M104 T0 S235")); + enqueue_and_echo_commands_P(PSTR("G28")); + enqueue_and_echo_commands_P(PSTR("M109 T0 S235")); + enqueue_and_echo_commands_P(PSTR("G92 E0")); + enqueue_and_echo_commands_P(PSTR("M83")); + enqueue_and_echo_commands_P(PSTR("G1 E430 F1000")); + enqueue_and_echo_commands_P(PSTR("G1 E70 F100")); + enqueue_and_echo_commands_P(PSTR("M117 Loading filament ")); + enqueue_and_echo_commands_P(PSTR("M84")); + enqueue_and_echo_commands_P(PSTR("M82")); + enqueue_and_echo_commands_P(PSTR("M104 T0 S0")); + enqueue_and_echo_commands_P(PSTR("M117 Vertex Nano ready ")); + lcd_return_to_status(); + } + + void lcd_load_menu_PLA_go() + { + enqueue_and_echo_commands_P(PSTR("M104 T0 S190")); + enqueue_and_echo_commands_P(PSTR("G28")); + enqueue_and_echo_commands_P(PSTR("M109 T0 S190")); + enqueue_and_echo_commands_P(PSTR("G92 E0")); + enqueue_and_echo_commands_P(PSTR("M83")); + enqueue_and_echo_commands_P(PSTR("G1 E430 F1000")); + enqueue_and_echo_commands_P(PSTR("G1 E70 F100")); + enqueue_and_echo_commands_P(PSTR("M117 Loading filament ")); + enqueue_and_echo_commands_P(PSTR("M84")); + enqueue_and_echo_commands_P(PSTR("M82")); + enqueue_and_echo_commands_P(PSTR("M104 T0 S0")); + enqueue_and_echo_commands_P(PSTR("M117 Vertex Nano ready ")); + lcd_return_to_status(); + } + + void lcd_unload_menu_ABS() + { + enqueue_and_echo_commands_P(PSTR("M104 T0 S235")); + enqueue_and_echo_commands_P(PSTR("G28")); + enqueue_and_echo_commands_P(PSTR("M109 T0 S235")); + enqueue_and_echo_commands_P(PSTR("G92 E0")); + enqueue_and_echo_commands_P(PSTR("M83")); + enqueue_and_echo_commands_P(PSTR("G1 E10 F50")); + enqueue_and_echo_commands_P(PSTR("G1 E-30 F100")); + enqueue_and_echo_commands_P(PSTR("G1 E-550 F1000")); + enqueue_and_echo_commands_P(PSTR("M117 Unloading filament ")); + enqueue_and_echo_commands_P(PSTR("M84")); + enqueue_and_echo_commands_P(PSTR("M82")); + enqueue_and_echo_commands_P(PSTR("M104 T0 S0")); + enqueue_and_echo_commands_P(PSTR("M117 Vertex Nano ready ")); + lcd_return_to_status(); + } + + void lcd_unload_menu_PLA() + { + enqueue_and_echo_commands_P(PSTR("M104 T0 S190")); + enqueue_and_echo_commands_P(PSTR("G28")); + enqueue_and_echo_commands_P(PSTR("M109 T0 S190")); + enqueue_and_echo_commands_P(PSTR("G92 E0")); + enqueue_and_echo_commands_P(PSTR("M83")); + enqueue_and_echo_commands_P(PSTR("G1 E10 F50")); + enqueue_and_echo_commands_P(PSTR("G1 E-30 F100")); + enqueue_and_echo_commands_P(PSTR("G1 E-550 F1000")); + enqueue_and_echo_commands_P(PSTR("M117 Unloading filament ")); + enqueue_and_echo_commands_P(PSTR("M84")); + enqueue_and_echo_commands_P(PSTR("M82")); + enqueue_and_echo_commands_P(PSTR("M104 T0 S0")); + enqueue_and_echo_commands_P(PSTR("M117 Vertex Nano ready ")); + lcd_return_to_status(); + } + + /** + * + * "Tune" submenu items + * + */ + + /** + * Set the home offset based on the current_position + */ + void lcd_set_home_offsets() { + // M428 Command + enqueue_and_echo_commands_P(PSTR("M428")); + enqueue_and_echo_commands_P(PSTR("M500")); + lcd_return_to_status(); + } + + #if ENABLED(BABYSTEPPING) + + long babysteps_done = 0; + + static void _lcd_babystep(const AxisEnum axis, const char* msg) { + if (LCD_CLICKED) { lcd_goto_previous_menu(true); return; } + ENCODER_DIRECTION_NORMAL(); + if (encoderPosition) { + int babystep_increment = (int32_t)encoderPosition * BABYSTEP_MULTIPLICATOR; + encoderPosition = 0; + lcdDrawUpdate = LCDVIEW_REDRAW_NOW; + thermalManager.babystep_axis(axis, babystep_increment); + babysteps_done += babystep_increment; + } + if (lcdDrawUpdate) + lcd_implementation_drawedit(msg, ftostr43sign( + ((1000 * babysteps_done) * planner.steps_to_mm[axis]) * 0.001f + )); + } + + #if ENABLED(BABYSTEP_XY) + static void _lcd_babystep_x() { _lcd_babystep(X_AXIS, PSTR(MSG_BABYSTEPPING_X)); } + static void _lcd_babystep_y() { _lcd_babystep(Y_AXIS, PSTR(MSG_BABYSTEPPING_Y)); } + static void lcd_babystep_x() { babysteps_done = 0; lcd_goto_screen(_lcd_babystep_x); } + static void lcd_babystep_y() { babysteps_done = 0; lcd_goto_screen(_lcd_babystep_y); } + #endif + static void _lcd_babystep_z() { _lcd_babystep(Z_AXIS, PSTR(MSG_BABYSTEPPING_Z)); } + static void lcd_babystep_z() { babysteps_done = 0; lcd_goto_screen(_lcd_babystep_z); } + + #endif //BABYSTEPPING + + /** + * Watch temperature callbacks + */ + #if ENABLED(THERMAL_PROTECTION_HOTENDS) && WATCH_TEMP_PERIOD > 0 + #if TEMP_SENSOR_0 != 0 + void watch_temp_callback_E0() { thermalManager.start_watching_heater(0); } + #endif + #if HOTENDS > 1 && TEMP_SENSOR_1 != 0 + void watch_temp_callback_E1() { thermalManager.start_watching_heater(1); } + #endif // HOTENDS > 1 + #if HOTENDS > 2 && TEMP_SENSOR_2 != 0 + void watch_temp_callback_E2() { thermalManager.start_watching_heater(2); } + #endif // HOTENDS > 2 + #if HOTENDS > 3 && TEMP_SENSOR_3 != 0 + void watch_temp_callback_E3() { thermalManager.start_watching_heater(3); } + #endif // HOTENDS > 3 + #else + #if TEMP_SENSOR_0 != 0 + void watch_temp_callback_E0() {} + #endif + #if HOTENDS > 1 && TEMP_SENSOR_1 != 0 + void watch_temp_callback_E1() {} + #endif // HOTENDS > 1 + #if HOTENDS > 2 && TEMP_SENSOR_2 != 0 + void watch_temp_callback_E2() {} + #endif // HOTENDS > 2 + #if HOTENDS > 3 && TEMP_SENSOR_3 != 0 + void watch_temp_callback_E3() {} + #endif // HOTENDS > 3 + #endif + + #if ENABLED(THERMAL_PROTECTION_BED) && WATCH_BED_TEMP_PERIOD > 0 + #if TEMP_SENSOR_BED != 0 + void watch_temp_callback_bed() { thermalManager.start_watching_bed(); } + #endif + #else + #if TEMP_SENSOR_BED != 0 + void watch_temp_callback_bed() {} + #endif + #endif + + /** + * + * "Tune" submenu + * + */ + static void lcd_tune_menu() { + START_MENU(); + + // + // ^ Main + // + MENU_ITEM(back, MSG_MAIN); + + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(int3, MSG_LED_MENU, &vertexLedBrightness, 0, 100, set_led_brightness); + + + // + // Speed: + // + MENU_ITEM_EDIT(int3, MSG_SPEED, &feedrate_percentage, 10, 999); + + // Manual bed leveling, Bed Z: + #if ENABLED(MANUAL_BED_LEVELING) + MENU_ITEM_EDIT(float43, MSG_BED_Z, &mbl.z_offset, -1, 1); + #endif + + // + // Nozzle: + // Nozzle [1-4]: + // + #if HOTENDS == 1 + #if TEMP_SENSOR_0 != 0 + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(int3, MSG_NOZZLE, &thermalManager.target_temperature[0], 0, HEATER_0_MAXTEMP - 15, watch_temp_callback_E0); + #endif + #else //HOTENDS > 1 + #if TEMP_SENSOR_0 != 0 + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(int3, MSG_NOZZLE MSG_N1, &thermalManager.target_temperature[0], 0, HEATER_0_MAXTEMP - 15, watch_temp_callback_E0); + #endif + #if TEMP_SENSOR_1 != 0 + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(int3, MSG_NOZZLE MSG_N2, &thermalManager.target_temperature[1], 0, HEATER_1_MAXTEMP - 15, watch_temp_callback_E1); + #endif + #if HOTENDS > 2 + #if TEMP_SENSOR_2 != 0 + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(int3, MSG_NOZZLE MSG_N3, &thermalManager.target_temperature[2], 0, HEATER_2_MAXTEMP - 15, watch_temp_callback_E2); + #endif + #if HOTENDS > 3 + #if TEMP_SENSOR_3 != 0 + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(int3, MSG_NOZZLE MSG_N4, &thermalManager.target_temperature[3], 0, HEATER_3_MAXTEMP - 15, watch_temp_callback_E3); + #endif + #endif // HOTENDS > 3 + #endif // HOTENDS > 2 + #endif // HOTENDS > 1 + + // + // Bed: + // + #if TEMP_SENSOR_BED != 0 + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(int3, MSG_BED, &thermalManager.target_temperature_bed, 0, BED_MAXTEMP - 15, watch_temp_callback_bed); + #endif + + // + // Fan Speed: + // + #if FAN_COUNT > 0 + #if HAS_FAN0 + #if FAN_COUNT > 1 + #define MSG_1ST_FAN_SPEED MSG_FAN_SPEED " 1" + #else + #define MSG_1ST_FAN_SPEED MSG_FAN_SPEED + #endif + MENU_MULTIPLIER_ITEM_EDIT(int3, MSG_1ST_FAN_SPEED, &fanSpeeds[0], 0, 255); + #endif + #if HAS_FAN1 + MENU_MULTIPLIER_ITEM_EDIT(int3, MSG_FAN_SPEED " 2", &fanSpeeds[1], 0, 255); + #endif + #if HAS_FAN2 + MENU_MULTIPLIER_ITEM_EDIT(int3, MSG_FAN_SPEED " 3", &fanSpeeds[2], 0, 255); + #endif + #endif // FAN_COUNT > 0 + + // + // Flow: + // Flow 1: + // Flow 2: + // Flow 3: + // Flow 4: + // + #if EXTRUDERS == 1 + MENU_ITEM_EDIT(int3, MSG_FLOW, &extruder_multiplier[0], 10, 999); + #else // EXTRUDERS > 1 + MENU_ITEM_EDIT(int3, MSG_FLOW, &extruder_multiplier[active_extruder], 10, 999); + MENU_ITEM_EDIT(int3, MSG_FLOW MSG_N1, &extruder_multiplier[0], 10, 999); + MENU_ITEM_EDIT(int3, MSG_FLOW MSG_N2, &extruder_multiplier[1], 10, 999); + #if EXTRUDERS > 2 + MENU_ITEM_EDIT(int3, MSG_FLOW MSG_N3, &extruder_multiplier[2], 10, 999); + #if EXTRUDERS > 3 + MENU_ITEM_EDIT(int3, MSG_FLOW MSG_N4, &extruder_multiplier[3], 10, 999); + #endif //EXTRUDERS > 3 + #endif //EXTRUDERS > 2 + #endif //EXTRUDERS > 1 + + // + // Babystep X: + // Babystep Y: + // Babystep Z: + // + #if ENABLED(BABYSTEPPING) + #if ENABLED(BABYSTEP_XY) + MENU_ITEM(submenu, MSG_BABYSTEP_X, lcd_babystep_x); + MENU_ITEM(submenu, MSG_BABYSTEP_Y, lcd_babystep_y); + #endif //BABYSTEP_XY + MENU_ITEM(submenu, MSG_BABYSTEP_Z, lcd_babystep_z); + #endif + + // + // Change filament + // + #if ENABLED(FILAMENT_CHANGE_FEATURE) + MENU_ITEM(gcode, MSG_FILAMENTCHANGE, PSTR("M600")); + #endif + + END_MENU(); + } + + /** + * + * "Prepare" submenu items + * + */ + void _lcd_preheat(int endnum, const float temph, const float tempb, const int fan) { + if (temph > 0) thermalManager.setTargetHotend(temph, endnum); + #if TEMP_SENSOR_BED != 0 + thermalManager.setTargetBed(tempb); + #else + UNUSED(tempb); + #endif + #if FAN_COUNT > 0 + #if FAN_COUNT > 1 + fanSpeeds[active_extruder < FAN_COUNT ? active_extruder : 0] = fan; + #else + fanSpeeds[0] = fan; + #endif + #else + UNUSED(fan); + #endif + lcd_return_to_status(); + } + + #if TEMP_SENSOR_0 != 0 + void lcd_preheat_pla0() { _lcd_preheat(0, preheatHotendTemp1, preheatBedTemp1, preheatFanSpeed1); } + void lcd_preheat_abs0() { _lcd_preheat(0, preheatHotendTemp2, preheatBedTemp2, preheatFanSpeed2); } + #endif + + #if HOTENDS > 1 + void lcd_preheat_pla1() { _lcd_preheat(1, preheatHotendTemp1, preheatBedTemp1, preheatFanSpeed1); } + void lcd_preheat_abs1() { _lcd_preheat(1, preheatHotendTemp2, preheatBedTemp2, preheatFanSpeed2); } + #if HOTENDS > 2 + void lcd_preheat_pla2() { _lcd_preheat(2, preheatHotendTemp1, preheatBedTemp1, preheatFanSpeed1); } + void lcd_preheat_abs2() { _lcd_preheat(2, preheatHotendTemp2, preheatBedTemp2, preheatFanSpeed2); } + #if HOTENDS > 3 + void lcd_preheat_pla3() { _lcd_preheat(3, preheatHotendTemp1, preheatBedTemp1, preheatFanSpeed1); } + void lcd_preheat_abs3() { _lcd_preheat(3, preheatHotendTemp2, preheatBedTemp2, preheatFanSpeed2); } + #endif + #endif + + void lcd_preheat_pla0123() { + #if HOTENDS > 1 + thermalManager.setTargetHotend(preheatHotendTemp1, 1); + #if HOTENDS > 2 + thermalManager.setTargetHotend(preheatHotendTemp1, 2); + #if HOTENDS > 3 + thermalManager.setTargetHotend(preheatHotendTemp1, 3); + #endif + #endif + #endif + lcd_preheat_pla0(); + } + void lcd_preheat_abs0123() { + #if HOTENDS > 1 + thermalManager.setTargetHotend(preheatHotendTemp2, 1); + #if HOTENDS > 2 + thermalManager.setTargetHotend(preheatHotendTemp2, 2); + #if HOTENDS > 3 + thermalManager.setTargetHotend(preheatHotendTemp2, 3); + #endif + #endif + #endif + lcd_preheat_abs0(); + } + + #endif // HOTENDS > 1 + + #if TEMP_SENSOR_BED != 0 + void lcd_preheat_pla_bedonly() { _lcd_preheat(0, 0, preheatBedTemp1, preheatFanSpeed1); } + void lcd_preheat_abs_bedonly() { _lcd_preheat(0, 0, preheatBedTemp2, preheatFanSpeed2); } + #endif + + #if TEMP_SENSOR_0 != 0 && (TEMP_SENSOR_1 != 0 || TEMP_SENSOR_2 != 0 || TEMP_SENSOR_3 != 0 || TEMP_SENSOR_BED != 0) + + static void lcd_preheat_pla_menu() { + START_MENU(); + MENU_ITEM(back, MSG_PREPARE); + #if HOTENDS == 1 + MENU_ITEM(function, MSG_PREHEAT_1, lcd_preheat_pla0); + #else + MENU_ITEM(function, MSG_PREHEAT_1_N MSG_H1, lcd_preheat_pla0); + MENU_ITEM(function, MSG_PREHEAT_1_N MSG_H2, lcd_preheat_pla1); + #if HOTENDS > 2 + MENU_ITEM(function, MSG_PREHEAT_1_N MSG_H3, lcd_preheat_pla2); + #if HOTENDS > 3 + MENU_ITEM(function, MSG_PREHEAT_1_N MSG_H4, lcd_preheat_pla3); + #endif + #endif + MENU_ITEM(function, MSG_PREHEAT_1_ALL, lcd_preheat_pla0123); + #endif + #if TEMP_SENSOR_BED != 0 + MENU_ITEM(function, MSG_PREHEAT_1_BEDONLY, lcd_preheat_pla_bedonly); + #endif + END_MENU(); + } + + static void lcd_preheat_abs_menu() { + START_MENU(); + MENU_ITEM(back, MSG_PREPARE); + #if HOTENDS == 1 + + MENU_ITEM(function, MSG_PREHEAT_2, lcd_preheat_abs0); + #else + MENU_ITEM(function, MSG_PREHEAT_2_N MSG_H1, lcd_preheat_abs0); + MENU_ITEM(function, MSG_PREHEAT_2_N MSG_H2, lcd_preheat_abs1); + #if HOTENDS > 2 + MENU_ITEM(function, MSG_PREHEAT_2_N MSG_H3, lcd_preheat_abs2); + #if HOTENDS > 3 + MENU_ITEM(function, MSG_PREHEAT_2_N MSG_H4, lcd_preheat_abs3); + #endif + #endif + MENU_ITEM(function, MSG_PREHEAT_2_ALL, lcd_preheat_abs0123); + #endif + #if TEMP_SENSOR_BED != 0 + MENU_ITEM(function, MSG_PREHEAT_2_BEDONLY, lcd_preheat_abs_bedonly); + #endif + END_MENU(); + } + + #endif // TEMP_SENSOR_0 && (TEMP_SENSOR_1 || TEMP_SENSOR_2 || TEMP_SENSOR_3 || TEMP_SENSOR_BED) + + void lcd_cooldown() { + #if FAN_COUNT > 0 + for (uint8_t i = 0; i < FAN_COUNT; i++) fanSpeeds[i] = 0; + #endif + thermalManager.disable_all_heaters(); + lcd_return_to_status(); + } + + #if ENABLED(SDSUPPORT) && ENABLED(MENU_ADDAUTOSTART) + + static void lcd_autostart_sd() { + card.autostart_index = 0; + card.setroot(); + card.checkautostart(true); + } + + #endif + + #if ENABLED(MANUAL_BED_LEVELING) + + /** + * + * "Prepare" > "Bed Leveling" handlers + * + */ + + static uint8_t _lcd_level_bed_position; + + // Utility to go to the next mesh point + // A raise is added between points if Z_HOMING_HEIGHT is in use + // Note: During Manual Bed Leveling the homed Z position is MESH_HOME_SEARCH_Z + // Z position will be restored with the final action, a G28 + inline void _mbl_goto_xy(float x, float y) { + current_position[Z_AXIS] = MESH_HOME_SEARCH_Z + Z_HOMING_HEIGHT; + line_to_current(Z_AXIS); + current_position[X_AXIS] = x + home_offset[X_AXIS]; + current_position[Y_AXIS] = y + home_offset[Y_AXIS]; + line_to_current(manual_feedrate_mm_m[X_AXIS] <= manual_feedrate_mm_m[Y_AXIS] ? X_AXIS : Y_AXIS); + #if Z_HOMING_HEIGHT > 0 + current_position[Z_AXIS] = MESH_HOME_SEARCH_Z; // How do condition and action match? + line_to_current(Z_AXIS); + #endif + stepper.synchronize(); + } + + static void _lcd_level_goto_next_point(); + + static void _lcd_level_bed_done() { + if (lcdDrawUpdate) lcd_implementation_drawedit(PSTR(MSG_LEVEL_BED_DONE)); + lcdDrawUpdate = + #if ENABLED(DOGLCD) + LCDVIEW_CALL_REDRAW_NEXT + #else + LCDVIEW_CALL_NO_REDRAW + #endif + ; + } + + /** + * Step 7: Get the Z coordinate, then goto next point or exit + */ + static void _lcd_level_bed_get_z() { + ENCODER_DIRECTION_NORMAL(); + + // Encoder wheel adjusts the Z position + if (encoderPosition) { + refresh_cmd_timeout(); + current_position[Z_AXIS] += float((int32_t)encoderPosition) * (MBL_Z_STEP); + NOLESS(current_position[Z_AXIS], 0); + NOMORE(current_position[Z_AXIS], MESH_HOME_SEARCH_Z * 2); + line_to_current(Z_AXIS); + lcdDrawUpdate = + #if ENABLED(DOGLCD) + LCDVIEW_CALL_REDRAW_NEXT + #else + LCDVIEW_REDRAW_NOW + #endif + ; + encoderPosition = 0; + } + + static bool debounce_click = false; + if (LCD_CLICKED) { + if (!debounce_click) { + debounce_click = true; // ignore multiple "clicks" in a row + mbl.set_zigzag_z(_lcd_level_bed_position++, current_position[Z_AXIS]); + if (_lcd_level_bed_position == (MESH_NUM_X_POINTS) * (MESH_NUM_Y_POINTS)) { + lcd_goto_screen(_lcd_level_bed_done, true); + + current_position[Z_AXIS] = MESH_HOME_SEARCH_Z + Z_HOMING_HEIGHT; + line_to_current(Z_AXIS); + stepper.synchronize(); + + mbl.set_has_mesh(true); + enqueue_and_echo_commands_P(PSTR("G28")); + lcd_return_to_status(); + //LCD_MESSAGEPGM(MSG_LEVEL_BED_DONE); + #if HAS_BUZZER + lcd_buzz(200, 659); + lcd_buzz(200, 698); + #endif + } + else { + lcd_goto_screen(_lcd_level_goto_next_point, true); + } + } + } + else { + debounce_click = false; + } + + // Update on first display, then only on updates to Z position + // Show message above on clicks instead + if (lcdDrawUpdate) { + float v = current_position[Z_AXIS] - MESH_HOME_SEARCH_Z; + lcd_implementation_drawedit(PSTR(MSG_MOVE_Z), ftostr43sign(v + (v < 0 ? -0.0001 : 0.0001), '+')); + } + + } + + /** + * Step 6: Display "Next point: 1 / 9" while waiting for move to finish + */ + static void _lcd_level_bed_moving() { + if (lcdDrawUpdate) { + char msg[10]; + sprintf_P(msg, PSTR("%i / %u"), (int)(_lcd_level_bed_position + 1), (MESH_NUM_X_POINTS) * (MESH_NUM_Y_POINTS)); + lcd_implementation_drawedit(PSTR(MSG_LEVEL_BED_NEXT_POINT), msg); + } + + lcdDrawUpdate = + #if ENABLED(DOGLCD) + LCDVIEW_CALL_REDRAW_NEXT + #else + LCDVIEW_CALL_NO_REDRAW + #endif + ; + } + + /** + * Step 5: Initiate a move to the next point + */ + static void _lcd_level_goto_next_point() { + // Set the menu to display ahead of blocking call + lcd_goto_screen(_lcd_level_bed_moving); + + // _mbl_goto_xy runs the menu loop until the move is done + int8_t px, py; + mbl.zigzag(_lcd_level_bed_position, px, py); + _mbl_goto_xy(mbl.get_probe_x(px), mbl.get_probe_y(py)); + + // After the blocking function returns, change menus + lcd_goto_screen(_lcd_level_bed_get_z); + } + + /** + * Step 4: Display "Click to Begin", wait for click + * Move to the first probe position + */ + static void _lcd_level_bed_homing_done() { + if (lcdDrawUpdate) lcd_implementation_drawedit(PSTR(MSG_LEVEL_BED_WAITING)); + if (LCD_CLICKED) { + _lcd_level_bed_position = 0; + current_position[Z_AXIS] = MESH_HOME_SEARCH_Z + #if Z_HOME_DIR > 0 + + Z_MAX_POS + #endif + ; + planner.set_position_mm(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + lcd_goto_screen(_lcd_level_goto_next_point, true); + } + } + + /** + * Step 3: Display "Homing XYZ" - Wait for homing to finish + */ + static void _lcd_level_bed_homing() { + if (lcdDrawUpdate) lcd_implementation_drawedit(PSTR(MSG_LEVEL_BED_HOMING), NULL); + lcdDrawUpdate = + #if ENABLED(DOGLCD) + LCDVIEW_CALL_REDRAW_NEXT + #else + LCDVIEW_CALL_NO_REDRAW + #endif + ; + if (axis_homed[X_AXIS] && axis_homed[Y_AXIS] && axis_homed[Z_AXIS]) + lcd_goto_screen(_lcd_level_bed_homing_done); + } + + /** + * Step 2: Continue Bed Leveling... + */ + static void _lcd_level_bed_continue() { + defer_return_to_status = true; + axis_homed[X_AXIS] = axis_homed[Y_AXIS] = axis_homed[Z_AXIS] = false; + mbl.reset(); + enqueue_and_echo_commands_P(PSTR("G28")); + lcd_goto_screen(_lcd_level_bed_homing); + } + + /** + * Step 1: MBL entry-point: "Cancel" or "Level Bed" + */ + static void lcd_level_bed() { + START_MENU(); + MENU_ITEM(back, MSG_LEVEL_BED_CANCEL); + MENU_ITEM(submenu, MSG_LEVEL_BED, _lcd_level_bed_continue); + END_MENU(); + } + + #endif // MANUAL_BED_LEVELING + + /** + * + * "Prepare" submenu + * + */ + + static void lcd_prepare_menu() { + START_MENU(); + + // + // ^ Main + // + MENU_ITEM(back, MSG_MAIN); + + // Auto Home + MENU_ITEM(gcode, MSG_AUTO_HOME, PSTR("G28")); + // load filament + MENU_ITEM(submenu, MSG_LOAD_FILAMENT, lcd_load_menu); + // INDIVIDUAL_AXIS_HOMING_MENU + #if ENABLED(INDIVIDUAL_AXIS_HOMING_MENU) + MENU_ITEM(gcode, MSG_AUTO_HOME_X, PSTR("G28 X")); + MENU_ITEM(gcode, MSG_AUTO_HOME_Y, PSTR("G28 Y")); + MENU_ITEM(gcode, MSG_AUTO_HOME_Z, PSTR("G28 Z")); + #endif + + + + // + // Level Bed + // + #if ENABLED(AUTO_BED_LEVELING_FEATURE) + MENU_ITEM(gcode, MSG_LEVEL_BED, + axis_homed[X_AXIS] && axis_homed[Y_AXIS] ? PSTR("G29") : PSTR("G28\nG29") + ); + #elif ENABLED(MANUAL_BED_LEVELING) + MENU_ITEM(submenu, MSG_LEVEL_BED, lcd_level_bed); + #endif + + + + // + // Disable Steppers + // + //MENU_ITEM(gcode, MSG_DISABLE_STEPPERS, PSTR("M84")); + + // + // Preheat + // + MENU_ITEM(submenu, MSG_PREHEAT, preheat_menu); + + //#if TEMP_SENSOR_0 != 0 + // #if TEMP_SENSOR_1 != 0 || TEMP_SENSOR_2 != 0 || TEMP_SENSOR_3 != 0 || TEMP_SENSOR_BED != 0 + // MENU_ITEM(submenu, MSG_PREHEAT_1, lcd_preheat_pla_menu); + // MENU_ITEM(submenu, MSG_PREHEAT_2, lcd_preheat_abs_menu); + // #else + // MENU_ITEM(function, MSG_PREHEAT_1, lcd_preheat_pla0); + // MENU_ITEM(function, MSG_PREHEAT_2, lcd_preheat_abs0); + // #endif + //#endif + // + // Move Axis + // + MENU_ITEM(submenu, MSG_MOVE_AXIS, lcd_move_menu); + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(int3, MSG_LED_MENU, &vertexLedBrightness, 0, 100, set_led_brightness); + // + // Set Home Offsets + // + MENU_ITEM(function, MSG_SET_HOME_OFFSETS, lcd_set_home_offsets); + //MENU_ITEM(gcode, MSG_SET_ORIGIN, PSTR("G92 X0 Y0 Z0")); + + + // + // Cooldown + // + //MENU_ITEM(function, MSG_COOLDOWN, lcd_cooldown); + + // + // Switch power on/off + // + //#if HAS_POWER_SWITCH + // if (powersupply) + // MENU_ITEM(gcode, MSG_SWITCH_PS_OFF, PSTR("M81")); + // else + // MENU_ITEM(gcode, MSG_SWITCH_PS_ON, PSTR("M80")); + //#endif + + // + // Autostart + // + //#if ENABLED(SDSUPPORT) && ENABLED(MENU_ADDAUTOSTART) + // MENU_ITEM(function, MSG_AUTOSTART, lcd_autostart_sd); + //#endif + + END_MENU(); + } + + #if ENABLED(DELTA_CALIBRATION_MENU) + + static void lcd_delta_calibrate_menu() { + START_MENU(); + MENU_ITEM(back, MSG_MAIN); + MENU_ITEM(gcode, MSG_AUTO_HOME, PSTR("G28")); + MENU_ITEM(gcode, MSG_DELTA_CALIBRATE_X, PSTR("G0 F8000 X-77.94 Y-45 Z0")); + MENU_ITEM(gcode, MSG_DELTA_CALIBRATE_Y, PSTR("G0 F8000 X77.94 Y-45 Z0")); + MENU_ITEM(gcode, MSG_DELTA_CALIBRATE_Z, PSTR("G0 F8000 X0 Y90 Z0")); + MENU_ITEM(gcode, MSG_DELTA_CALIBRATE_CENTER, PSTR("G0 F8000 X0 Y0 Z0")); + END_MENU(); + } + + #endif // DELTA_CALIBRATION_MENU + + float move_menu_scale; + + /** + * If the most recent manual move hasn't been fed to the planner yet, + * and the planner can accept one, send immediately + */ + inline void manage_manual_move() { + if (manual_move_axis != (int8_t)NO_AXIS && ELAPSED(millis(), manual_move_start_time) && !planner.is_full()) { + #if ENABLED(DELTA) + inverse_kinematics(current_position); + planner.buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], current_position[E_AXIS], MMM_TO_MMS(manual_feedrate_mm_m[manual_move_axis]), manual_move_e_index); + #else + planner.buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], MMM_TO_MMS(manual_feedrate_mm_m[manual_move_axis]), manual_move_e_index); + #endif + manual_move_axis = (int8_t)NO_AXIS; + } + } + + /** + * Set a flag that lcd_update() should start a move + * to "current_position" after a short delay. + */ + inline void manual_move_to_current(AxisEnum axis + #if E_MANUAL > 1 + , int8_t eindex=-1 + #endif + ) { + #if E_MANUAL > 1 + if (axis == E_AXIS) manual_move_e_index = eindex >= 0 ? eindex : active_extruder; + #endif + manual_move_start_time = millis() + (move_menu_scale < 0.99 ? 0UL : 250UL); // delay for bigger moves + manual_move_axis = (int8_t)axis; + } + + /** + * + * "Prepare" > "Move Axis" submenu + * + */ + + static void _lcd_move_xyz(const char* name, AxisEnum axis, float min, float max) { + if (LCD_CLICKED) { lcd_goto_previous_menu(true); return; } + ENCODER_DIRECTION_NORMAL(); + if (encoderPosition) { + refresh_cmd_timeout(); + current_position[axis] += float((int32_t)encoderPosition) * move_menu_scale; + if (min_software_endstops) NOLESS(current_position[axis], min); + if (max_software_endstops) NOMORE(current_position[axis], max); + encoderPosition = 0; + manual_move_to_current(axis); + lcdDrawUpdate = LCDVIEW_REDRAW_NOW; + } + if (lcdDrawUpdate) lcd_implementation_drawedit(name, ftostr41sign(current_position[axis])); + } + #if ENABLED(DELTA) + static float delta_clip_radius_2 = (DELTA_PRINTABLE_RADIUS) * (DELTA_PRINTABLE_RADIUS); + static int delta_clip( float a ) { return sqrt(delta_clip_radius_2 - sq(a)); } + static void lcd_move_x() { int clip = delta_clip(current_position[Y_AXIS]); _lcd_move_xyz(PSTR(MSG_MOVE_X), X_AXIS, max(sw_endstop_min[X_AXIS], -clip), min(sw_endstop_max[X_AXIS], clip)); } + static void lcd_move_y() { int clip = delta_clip(current_position[X_AXIS]); _lcd_move_xyz(PSTR(MSG_MOVE_Y), Y_AXIS, max(sw_endstop_min[Y_AXIS], -clip), min(sw_endstop_max[Y_AXIS], clip)); } + #else + static void lcd_move_x() { _lcd_move_xyz(PSTR(MSG_MOVE_X), X_AXIS, sw_endstop_min[X_AXIS], sw_endstop_max[X_AXIS]); } + static void lcd_move_y() { _lcd_move_xyz(PSTR(MSG_MOVE_Y), Y_AXIS, sw_endstop_min[Y_AXIS], sw_endstop_max[Y_AXIS]); } + #endif + static void lcd_move_z() { _lcd_move_xyz(PSTR(MSG_MOVE_Z), Z_AXIS, sw_endstop_min[Z_AXIS], sw_endstop_max[Z_AXIS]); } + static void _lcd_move_e( + #if E_MANUAL > 1 + int8_t eindex=-1 + #endif + ) { + if (LCD_CLICKED) { lcd_goto_previous_menu(true); return; } + ENCODER_DIRECTION_NORMAL(); + if (encoderPosition) { + current_position[E_AXIS] += float((int32_t)encoderPosition) * move_menu_scale; + encoderPosition = 0; + manual_move_to_current(E_AXIS + #if E_MANUAL > 1 + , eindex + #endif + ); + lcdDrawUpdate = LCDVIEW_REDRAW_NOW; + } + if (lcdDrawUpdate) { + PGM_P pos_label; + #if E_MANUAL == 1 + pos_label = PSTR(MSG_MOVE_E); + #else + switch (eindex) { + default: pos_label = PSTR(MSG_MOVE_E MSG_MOVE_E1); break; + case 1: pos_label = PSTR(MSG_MOVE_E MSG_MOVE_E2); break; + #if E_MANUAL > 2 + case 2: pos_label = PSTR(MSG_MOVE_E MSG_MOVE_E3); break; + #if E_MANUAL > 3 + case 3: pos_label = PSTR(MSG_MOVE_E MSG_MOVE_E4); break; + #endif + #endif + } + #endif + lcd_implementation_drawedit(pos_label, ftostr41sign(current_position[E_AXIS])); + } + } + + static void lcd_move_e() { _lcd_move_e(); } + #if E_MANUAL > 1 + static void lcd_move_e0() { _lcd_move_e(0); } + static void lcd_move_e1() { _lcd_move_e(1); } + #if E_MANUAL > 2 + static void lcd_move_e2() { _lcd_move_e(2); } + #if E_MANUAL > 3 + static void lcd_move_e3() { _lcd_move_e(3); } + #endif + #endif + #endif + + /** + * + * "Prepare" > "Move Xmm" > "Move XYZ" submenu + * + */ + + #if ENABLED(DELTA) || ENABLED(SCARA) + #define _MOVE_XYZ_ALLOWED (axis_homed[X_AXIS] && axis_homed[Y_AXIS] && axis_homed[Z_AXIS]) + #else + #define _MOVE_XYZ_ALLOWED true + #endif + + static void _lcd_move_menu_axis() { + START_MENU(); + MENU_ITEM(back, MSG_MOVE_AXIS); + + if (_MOVE_XYZ_ALLOWED) { + MENU_ITEM(submenu, MSG_MOVE_X, lcd_move_x); + MENU_ITEM(submenu, MSG_MOVE_Y, lcd_move_y); + } + + if (move_menu_scale < 10.0) { + if (_MOVE_XYZ_ALLOWED) MENU_ITEM(submenu, MSG_MOVE_Z, lcd_move_z); + + #if ENABLED(SWITCHING_EXTRUDER) + if (active_extruder) + MENU_ITEM(gcode, MSG_SELECT MSG_E1, PSTR("T0")); + else + MENU_ITEM(gcode, MSG_SELECT MSG_E2, PSTR("T1")); + #endif + + MENU_ITEM(submenu, MSG_MOVE_E, lcd_move_e); + #if E_MANUAL > 1 + MENU_ITEM(submenu, MSG_MOVE_E MSG_MOVE_E1, lcd_move_e0); + MENU_ITEM(submenu, MSG_MOVE_E MSG_MOVE_E2, lcd_move_e1); + #if E_MANUAL > 2 + MENU_ITEM(submenu, MSG_MOVE_E MSG_MOVE_E3, lcd_move_e2); + #if E_MANUAL > 3 + MENU_ITEM(submenu, MSG_MOVE_E MSG_MOVE_E4, lcd_move_e3); + #endif + #endif + #endif + } + END_MENU(); + } + + static void lcd_move_menu_10mm() { + move_menu_scale = 10.0; + _lcd_move_menu_axis(); + } + static void lcd_move_menu_1mm() { + move_menu_scale = 1.0; + _lcd_move_menu_axis(); + } + static void lcd_move_menu_01mm() { + move_menu_scale = 0.1; + _lcd_move_menu_axis(); + } + + /** + * + * "Prepare" > "Move Axis" submenu + * + */ + + static void lcd_move_menu() { + START_MENU(); + MENU_ITEM(back, MSG_PREPARE); + + if (_MOVE_XYZ_ALLOWED) + MENU_ITEM(submenu, MSG_MOVE_10MM, lcd_move_menu_10mm); + + MENU_ITEM(submenu, MSG_MOVE_1MM, lcd_move_menu_1mm); + MENU_ITEM(submenu, MSG_MOVE_01MM, lcd_move_menu_01mm); + //TODO:X,Y,Z,E + END_MENU(); + } + + /** + * + * "Control" submenu + * + */ + + static void lcd_control_menu() { + START_MENU(); + MENU_ITEM(back, MSG_MAIN); + MENU_ITEM(submenu, MSG_TEMPERATURE, lcd_control_temperature_menu); + MENU_ITEM(submenu, MSG_MOTION, lcd_control_motion_menu); + MENU_ITEM(submenu, MSG_VOLUMETRIC, lcd_control_volumetric_menu); + + #if HAS_LCD_CONTRAST + //MENU_ITEM_EDIT(int3, MSG_CONTRAST, &lcd_contrast, 0, 63); + MENU_ITEM(submenu, MSG_CONTRAST, lcd_set_contrast); + #endif + #if ENABLED(FWRETRACT) + MENU_ITEM(submenu, MSG_RETRACT, lcd_control_retract_menu); + #endif + #if ENABLED(EEPROM_SETTINGS) + MENU_ITEM(function, MSG_STORE_EPROM, Config_StoreSettings); + MENU_ITEM(function, MSG_LOAD_EPROM, Config_RetrieveSettings); + #endif + MENU_ITEM(function, MSG_RESTORE_FAILSAFE, Config_ResetDefault); + END_MENU(); + } + + /** + * + * "Temperature" submenu + * + */ + + #if ENABLED(PID_AUTOTUNE_MENU) + + #if ENABLED(PIDTEMP) + int autotune_temp[HOTENDS] = ARRAY_BY_HOTENDS1(150); + const int heater_maxtemp[HOTENDS] = ARRAY_BY_HOTENDS(HEATER_0_MAXTEMP, HEATER_1_MAXTEMP, HEATER_2_MAXTEMP, HEATER_3_MAXTEMP); + #endif + + #if ENABLED(PIDTEMPBED) + int autotune_temp_bed = 70; + #endif + + static void _lcd_autotune(int 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] + #endif + ); + enqueue_and_echo_command(cmd); + } + + #endif //PID_AUTOTUNE_MENU + + #if ENABLED(PIDTEMP) + + // 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(int e) { + #if DISABLED(PID_PARAMS_PER_HOTEND) || HOTENDS == 1 + UNUSED(e); + #endif + PID_PARAM(Ki, e) = scalePID_i(raw_Ki); + thermalManager.updatePID(); + } + void copy_and_scalePID_d(int e) { + #if DISABLED(PID_PARAMS_PER_HOTEND) || HOTENDS == 1 + UNUSED(e); + #endif + PID_PARAM(Kd, e) = scalePID_d(raw_Kd); + thermalManager.updatePID(); + } + #define _PIDTEMP_BASE_FUNCTIONS(eindex) \ + void copy_and_scalePID_i_E ## eindex() { copy_and_scalePID_i(eindex); } \ + void copy_and_scalePID_d_E ## eindex() { copy_and_scalePID_d(eindex); } + + #if ENABLED(PID_AUTOTUNE_MENU) + #define _PIDTEMP_FUNCTIONS(eindex) \ + _PIDTEMP_BASE_FUNCTIONS(eindex); \ + void lcd_autotune_callback_E ## eindex() { _lcd_autotune(eindex); } + #else + #define _PIDTEMP_FUNCTIONS(eindex) _PIDTEMP_BASE_FUNCTIONS(eindex) + #endif + + _PIDTEMP_FUNCTIONS(0); + #if ENABLED(PID_PARAMS_PER_HOTEND) + #if HOTENDS > 1 + _PIDTEMP_FUNCTIONS(1); + #if HOTENDS > 2 + _PIDTEMP_FUNCTIONS(2); + #if HOTENDS > 3 + _PIDTEMP_FUNCTIONS(3); + #endif //HOTENDS > 3 + #endif //HOTENDS > 2 + #endif //HOTENDS > 1 + #endif //PID_PARAMS_PER_HOTEND + + #endif //PIDTEMP + + /** + * + * "Control" > "Temperature" submenu + * + */ + static void lcd_control_temperature_menu() { + START_MENU(); + + // + // ^ Control + // + MENU_ITEM(back, MSG_CONTROL); + + // + // Nozzle: + // Nozzle [1-4]: + // + #if HOTENDS == 1 + #if TEMP_SENSOR_0 != 0 + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(int3, MSG_NOZZLE, &thermalManager.target_temperature[0], 0, HEATER_0_MAXTEMP - 15, watch_temp_callback_E0); + #endif + #else //HOTENDS > 1 + #if TEMP_SENSOR_0 != 0 + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(int3, MSG_NOZZLE MSG_N1, &thermalManager.target_temperature[0], 0, HEATER_0_MAXTEMP - 15, watch_temp_callback_E0); + #endif + #if TEMP_SENSOR_1 != 0 + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(int3, MSG_NOZZLE MSG_N2, &thermalManager.target_temperature[1], 0, HEATER_1_MAXTEMP - 15, watch_temp_callback_E1); + #endif + #if HOTENDS > 2 + #if TEMP_SENSOR_2 != 0 + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(int3, MSG_NOZZLE MSG_N3, &thermalManager.target_temperature[2], 0, HEATER_2_MAXTEMP - 15, watch_temp_callback_E2); + #endif + #if HOTENDS > 3 + #if TEMP_SENSOR_3 != 0 + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(int3, MSG_NOZZLE MSG_N4, &thermalManager.target_temperature[3], 0, HEATER_3_MAXTEMP - 15, watch_temp_callback_E3); + #endif + #endif // HOTENDS > 3 + #endif // HOTENDS > 2 + #endif // HOTENDS > 1 + + // + // Bed: + // + #if TEMP_SENSOR_BED != 0 + MENU_MULTIPLIER_ITEM_EDIT(int3, MSG_BED, &thermalManager.target_temperature_bed, 0, BED_MAXTEMP - 15); + #endif + + // + // Fan Speed: + // + //#if FAN_COUNT > 0 + // #if HAS_FAN0 + // #if FAN_COUNT > 1 + // #define MSG_1ST_FAN_SPEED MSG_FAN_SPEED " 1" + // #else + // #define MSG_1ST_FAN_SPEED MSG_FAN_SPEED + // #endif + // MENU_MULTIPLIER_ITEM_EDIT(int3, MSG_1ST_FAN_SPEED, &fanSpeeds[0], 0, 255); + // #endif + // #if HAS_FAN1 + // MENU_MULTIPLIER_ITEM_EDIT(int3, MSG_FAN_SPEED " 2", &fanSpeeds[1], 0, 255); + // #endif + // #if HAS_FAN2 + // MENU_MULTIPLIER_ITEM_EDIT(int3, MSG_FAN_SPEED " 3", &fanSpeeds[2], 0, 255); + // #endif + //#endif // FAN_COUNT > 0 + + // + // Autotemp, Min, Max, Fact + // + #if ENABLED(AUTOTEMP) && (TEMP_SENSOR_0 != 0) + MENU_ITEM_EDIT(bool, MSG_AUTOTEMP, &planner.autotemp_enabled); + MENU_ITEM_EDIT(float3, MSG_MIN, &planner.autotemp_min, 0, HEATER_0_MAXTEMP - 15); + MENU_ITEM_EDIT(float3, MSG_MAX, &planner.autotemp_max, 0, HEATER_0_MAXTEMP - 15); + MENU_ITEM_EDIT(float32, MSG_FACTOR, &planner.autotemp_factor, 0.0, 1.0); + #endif + + // + // PID-P, PID-I, PID-D, PID-C, PID Autotune + // PID-P E1, PID-I E1, PID-D E1, PID-C E1, PID Autotune E1 + // PID-P E2, PID-I E2, PID-D E2, PID-C E2, PID Autotune E2 + // PID-P E3, PID-I E3, PID-D E3, PID-C E3, PID Autotune E3 + // PID-P E4, PID-I E4, PID-D E4, PID-C E4, PID Autotune E4 + // + #if ENABLED(PIDTEMP) + + #define _PID_BASE_MENU_ITEMS(ELABEL, eindex) \ + raw_Ki = unscalePID_i(PID_PARAM(Ki, eindex)); \ + raw_Kd = unscalePID_d(PID_PARAM(Kd, eindex)); \ + MENU_ITEM_EDIT(float52, MSG_PID_P ELABEL, &PID_PARAM(Kp, eindex), 1, 9990); \ + MENU_ITEM_EDIT_CALLBACK(float52, MSG_PID_I ELABEL, &raw_Ki, 0.01, 9990, copy_and_scalePID_i_E ## eindex); \ + MENU_ITEM_EDIT_CALLBACK(float52, MSG_PID_D ELABEL, &raw_Kd, 1, 9990, copy_and_scalePID_d_E ## eindex) + + #if ENABLED(PID_EXTRUSION_SCALING) + #define _PID_MENU_ITEMS(ELABEL, eindex) \ + _PID_BASE_MENU_ITEMS(ELABEL, eindex); \ + MENU_ITEM_EDIT(float3, MSG_PID_C ELABEL, &PID_PARAM(Kc, eindex), 1, 9990) + #else + #define _PID_MENU_ITEMS(ELABEL, eindex) _PID_BASE_MENU_ITEMS(ELABEL, eindex) + #endif + + #if ENABLED(PID_AUTOTUNE_MENU) + #define PID_MENU_ITEMS(ELABEL, eindex) \ + _PID_MENU_ITEMS(ELABEL, eindex); \ + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(int3, MSG_PID_AUTOTUNE ELABEL, &autotune_temp[eindex], 150, heater_maxtemp[eindex] - 15, lcd_autotune_callback_E ## eindex) + #else + #define PID_MENU_ITEMS(ELABEL, eindex) _PID_MENU_ITEMS(ELABEL, eindex) + #endif + + #if ENABLED(PID_PARAMS_PER_HOTEND) && HOTENDS > 1 + PID_MENU_ITEMS(MSG_E1, 0); + PID_MENU_ITEMS(MSG_E2, 1); + #if HOTENDS > 2 + PID_MENU_ITEMS(MSG_E3, 2); + #if HOTENDS > 3 + PID_MENU_ITEMS(MSG_E4, 3); + #endif //HOTENDS > 3 + #endif //HOTENDS > 2 + #else //!PID_PARAMS_PER_HOTEND || HOTENDS == 1 + PID_MENU_ITEMS("", 0); + #endif //!PID_PARAMS_PER_HOTEND || HOTENDS == 1 + + #endif //PIDTEMP + + // + // Preheat PLA conf + // + MENU_ITEM(submenu, MSG_PREHEAT_1_SETTINGS, lcd_control_temperature_preheat_pla_settings_menu); + + // + // Preheat ABS conf + // + MENU_ITEM(submenu, MSG_PREHEAT_2_SETTINGS, lcd_control_temperature_preheat_abs_settings_menu); + END_MENU(); + } + + /** + * + * "Temperature" > "Preheat PLA conf" submenu + * + */ + static void lcd_control_temperature_preheat_pla_settings_menu() { + START_MENU(); + MENU_ITEM(back, MSG_TEMPERATURE); + MENU_ITEM_EDIT(int3, MSG_FAN_SPEED, &preheatFanSpeed1, 0, 255); + #if TEMP_SENSOR_0 != 0 + MENU_ITEM_EDIT(int3, MSG_NOZZLE, &preheatHotendTemp1, HEATER_0_MINTEMP, HEATER_0_MAXTEMP - 15); + #endif + #if TEMP_SENSOR_BED != 0 + MENU_ITEM_EDIT(int3, MSG_BED, &preheatBedTemp1, BED_MINTEMP, BED_MAXTEMP - 15); + #endif + #if ENABLED(EEPROM_SETTINGS) + MENU_ITEM(function, MSG_STORE_EPROM, Config_StoreSettings); + #endif + END_MENU(); + } + + /** + * + * "Temperature" > "Preheat ABS conf" submenu + * + */ + static void lcd_control_temperature_preheat_abs_settings_menu() { + START_MENU(); + MENU_ITEM(back, MSG_TEMPERATURE); + MENU_ITEM_EDIT(int3, MSG_FAN_SPEED, &preheatFanSpeed2, 0, 255); + #if TEMP_SENSOR_0 != 0 + MENU_ITEM_EDIT(int3, MSG_NOZZLE, &preheatHotendTemp2, HEATER_0_MINTEMP, HEATER_0_MAXTEMP - 15); + #endif + #if TEMP_SENSOR_BED != 0 + MENU_ITEM_EDIT(int3, MSG_BED, &preheatBedTemp2, BED_MINTEMP, BED_MAXTEMP - 15); + #endif + #if ENABLED(EEPROM_SETTINGS) + MENU_ITEM(function, MSG_STORE_EPROM, Config_StoreSettings); + #endif + END_MENU(); + } + + static void _reset_acceleration_rates() { planner.reset_acceleration_rates(); } + static void _planner_refresh_positioning() { planner.refresh_positioning(); } + + /** + * + * "Control" > "Motion" submenu + * + */ + static void lcd_control_motion_menu() { + START_MENU(); + MENU_ITEM(back, MSG_CONTROL); + #if HAS_BED_PROBE + MENU_ITEM_EDIT(float32, MSG_ZPROBE_ZOFFSET, &zprobe_zoffset, Z_PROBE_OFFSET_RANGE_MIN, Z_PROBE_OFFSET_RANGE_MAX); + #endif + // Manual bed leveling, Bed Z: + #if ENABLED(MANUAL_BED_LEVELING) + MENU_ITEM_EDIT(float43, MSG_BED_Z, &mbl.z_offset, -1, 1); + #endif + MENU_ITEM_EDIT(float5, MSG_ACC, &planner.acceleration, 10, 99000); + MENU_ITEM_EDIT(float3, MSG_VXY_JERK, &planner.max_xy_jerk, 1, 990); + #if ENABLED(DELTA) + MENU_ITEM_EDIT(float3, MSG_VZ_JERK, &planner.max_z_jerk, 1, 990); + #else + MENU_ITEM_EDIT(float52, MSG_VZ_JERK, &planner.max_z_jerk, 0.1, 990); + #endif + MENU_ITEM_EDIT(float3, MSG_VE_JERK, &planner.max_e_jerk, 1, 990); + MENU_ITEM_EDIT(float3, MSG_VMAX MSG_X, &planner.max_feedrate_mm_s[X_AXIS], 1, 999); + MENU_ITEM_EDIT(float3, MSG_VMAX MSG_Y, &planner.max_feedrate_mm_s[Y_AXIS], 1, 999); + MENU_ITEM_EDIT(float3, MSG_VMAX MSG_Z, &planner.max_feedrate_mm_s[Z_AXIS], 1, 999); + MENU_ITEM_EDIT(float3, MSG_VMAX MSG_E, &planner.max_feedrate_mm_s[E_AXIS], 1, 999); + MENU_ITEM_EDIT(float3, MSG_VMIN, &planner.min_feedrate_mm_s, 0, 999); + MENU_ITEM_EDIT(float3, MSG_VTRAV_MIN, &planner.min_travel_feedrate_mm_s, 0, 999); + MENU_ITEM_EDIT_CALLBACK(long5, MSG_AMAX MSG_X, &planner.max_acceleration_mm_per_s2[X_AXIS], 100, 99000, _reset_acceleration_rates); + MENU_ITEM_EDIT_CALLBACK(long5, MSG_AMAX MSG_Y, &planner.max_acceleration_mm_per_s2[Y_AXIS], 100, 99000, _reset_acceleration_rates); + MENU_ITEM_EDIT_CALLBACK(long5, MSG_AMAX MSG_Z, &planner.max_acceleration_mm_per_s2[Z_AXIS], 10, 99000, _reset_acceleration_rates); + MENU_ITEM_EDIT_CALLBACK(long5, MSG_AMAX MSG_E, &planner.max_acceleration_mm_per_s2[E_AXIS], 100, 99000, _reset_acceleration_rates); + MENU_ITEM_EDIT(float5, MSG_A_RETRACT, &planner.retract_acceleration, 100, 99000); + MENU_ITEM_EDIT(float5, MSG_A_TRAVEL, &planner.travel_acceleration, 100, 99000); + MENU_ITEM_EDIT_CALLBACK(float52, MSG_XSTEPS, &planner.axis_steps_per_mm[X_AXIS], 5, 9999, _planner_refresh_positioning); + MENU_ITEM_EDIT_CALLBACK(float52, MSG_YSTEPS, &planner.axis_steps_per_mm[Y_AXIS], 5, 9999, _planner_refresh_positioning); + #if ENABLED(DELTA) + MENU_ITEM_EDIT_CALLBACK(float52, MSG_ZSTEPS, &planner.axis_steps_per_mm[Z_AXIS], 5, 9999, _planner_refresh_positioning); + #else + MENU_ITEM_EDIT_CALLBACK(float51, MSG_ZSTEPS, &planner.axis_steps_per_mm[Z_AXIS], 5, 9999, _planner_refresh_positioning); + #endif + MENU_ITEM_EDIT_CALLBACK(float51, MSG_ESTEPS, &planner.axis_steps_per_mm[E_AXIS], 5, 9999, _planner_refresh_positioning); + #if ENABLED(ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED) + MENU_ITEM_EDIT(bool, MSG_ENDSTOP_ABORT, &stepper.abort_on_endstop_hit); + #endif + #if ENABLED(SCARA) + MENU_ITEM_EDIT(float74, MSG_XSCALE, &axis_scaling[X_AXIS], 0.5, 2); + MENU_ITEM_EDIT(float74, MSG_YSCALE, &axis_scaling[Y_AXIS], 0.5, 2); + #endif + END_MENU(); + } + + /** + * + * "Control" > "Filament" submenu + * + */ + static void lcd_control_volumetric_menu() { + START_MENU(); + MENU_ITEM(back, MSG_CONTROL); + + MENU_ITEM_EDIT_CALLBACK(bool, MSG_VOLUMETRIC_ENABLED, &volumetric_enabled, calculate_volumetric_multipliers); + + if (volumetric_enabled) { + #if EXTRUDERS == 1 + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float43, MSG_FILAMENT_DIAM, &filament_size[0], 1.5, 3.25, calculate_volumetric_multipliers); + #else //EXTRUDERS > 1 + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float43, MSG_FILAMENT_DIAM MSG_DIAM_E1, &filament_size[0], 1.5, 3.25, calculate_volumetric_multipliers); + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float43, MSG_FILAMENT_DIAM MSG_DIAM_E2, &filament_size[1], 1.5, 3.25, calculate_volumetric_multipliers); + #if EXTRUDERS > 2 + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float43, MSG_FILAMENT_DIAM MSG_DIAM_E3, &filament_size[2], 1.5, 3.25, calculate_volumetric_multipliers); + #if EXTRUDERS > 3 + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float43, MSG_FILAMENT_DIAM MSG_DIAM_E4, &filament_size[3], 1.5, 3.25, calculate_volumetric_multipliers); + #endif //EXTRUDERS > 3 + #endif //EXTRUDERS > 2 + #endif //EXTRUDERS > 1 + } + + END_MENU(); + } + + /** + * + * "Control" > "Contrast" submenu + * + */ + #if HAS_LCD_CONTRAST + static void lcd_set_contrast() { + if (LCD_CLICKED) { lcd_goto_previous_menu(true); return; } + ENCODER_DIRECTION_NORMAL(); + if (encoderPosition) { + set_lcd_contrast(lcd_contrast + encoderPosition); + encoderPosition = 0; + lcdDrawUpdate = LCDVIEW_REDRAW_NOW; + } + if (lcdDrawUpdate) { + lcd_implementation_drawedit(PSTR(MSG_CONTRAST), + #if LCD_CONTRAST_MAX >= 100 + itostr3(lcd_contrast) + #else + itostr2(lcd_contrast) + #endif + ); + } + } + #endif // HAS_LCD_CONTRAST + + /** + * + * "Control" > "Retract" submenu + * + */ + #if ENABLED(FWRETRACT) + static void lcd_control_retract_menu() { + START_MENU(); + MENU_ITEM(back, MSG_CONTROL); + MENU_ITEM_EDIT(bool, MSG_AUTORETRACT, &autoretract_enabled); + MENU_ITEM_EDIT(float52, MSG_CONTROL_RETRACT, &retract_length, 0, 100); + #if EXTRUDERS > 1 + MENU_ITEM_EDIT(float52, MSG_CONTROL_RETRACT_SWAP, &retract_length_swap, 0, 100); + #endif + MENU_ITEM_EDIT(float3, MSG_CONTROL_RETRACTF, &retract_feedrate_mm_s, 1, 999); + MENU_ITEM_EDIT(float52, MSG_CONTROL_RETRACT_ZLIFT, &retract_zlift, 0, 999); + MENU_ITEM_EDIT(float52, MSG_CONTROL_RETRACT_RECOVER, &retract_recover_length, 0, 100); + #if EXTRUDERS > 1 + MENU_ITEM_EDIT(float52, MSG_CONTROL_RETRACT_RECOVER_SWAP, &retract_recover_length_swap, 0, 100); + #endif + MENU_ITEM_EDIT(float3, MSG_CONTROL_RETRACT_RECOVERF, &retract_recover_feedrate_mm_s, 1, 999); + END_MENU(); + } + #endif // FWRETRACT + + #if ENABLED(SDSUPPORT) + + #if !PIN_EXISTS(SD_DETECT) + static void lcd_sd_refresh() { + card.initsd(); + encoderTopLine = 0; + } + #endif + + static void lcd_sd_updir() { + card.updir(); + encoderTopLine = 0; + } + + /** + * + * "Print from SD" submenu + * + */ + void lcd_sdcard_menu() { + ENCODER_DIRECTION_MENUS(); + if (lcdDrawUpdate == 0 && LCD_CLICKED == 0) return; // nothing to do (so don't thrash the SD card) + uint16_t fileCnt = card.getnrfilenames(); + START_MENU(); + MENU_ITEM(back, MSG_MAIN); + card.getWorkDirName(); + if (card.filename[0] == '/') { + #if !PIN_EXISTS(SD_DETECT) + MENU_ITEM(function, LCD_STR_REFRESH MSG_REFRESH, lcd_sd_refresh); + #endif + } + else { + MENU_ITEM(function, LCD_STR_FOLDER "..", lcd_sd_updir); + } + + for (uint16_t i = 0; i < fileCnt; i++) { + if (_menuLineNr == _thisItemNr) { + card.getfilename( + #if ENABLED(SDCARD_RATHERRECENTFIRST) + fileCnt-1 - + #endif + i + ); + + if (card.filenameIsDir) + MENU_ITEM(sddirectory, MSG_CARD_MENU, card.filename, card.longFilename); + else + MENU_ITEM(sdfile, MSG_CARD_MENU, card.filename, card.longFilename); + } + else { + MENU_ITEM_DUMMY(); + } + } + END_MENU(); + } + + #endif //SDSUPPORT + + #if ENABLED(LCD_INFO_MENU) + + #if ENABLED(PRINTCOUNTER) + /** + * + * About Printer > Statistics submenu + * + */ + static void lcd_info_stats_menu() { + if (LCD_CLICKED) { lcd_goto_previous_menu(true); return; } + + char buffer[21]; + printStatistics stats = print_job_timer.getStats(); + + START_SCREEN(); // 12345678901234567890 + STATIC_ITEM(MSG_INFO_PRINT_COUNT ": ", false, false, itostr3left(stats.totalPrints)); // Print Count: 999 + STATIC_ITEM(MSG_INFO_COMPLETED_PRINTS" : ", false, false, itostr3left(stats.finishedPrints)); // Completed : 666 + + duration_t elapsed = stats.printTime; + elapsed.toString(buffer); + + STATIC_ITEM(MSG_INFO_PRINT_TIME ": ", false, false); // Total print Time: + STATIC_ITEM("", false, false, buffer); // 99y 364d 23h 59m 59s + + elapsed = stats.longestPrint; + elapsed.toString(buffer); + + STATIC_ITEM(MSG_INFO_PRINT_LONGEST ": ", false, false); // Longest job time: + STATIC_ITEM("", false, false, buffer); // 99y 364d 23h 59m 59s + + sprintf_P(buffer, PSTR("%im"), stats.filamentUsed / 1000); + STATIC_ITEM(MSG_INFO_PRINT_FILAMENT ": ", false, false); // Extruded total: + STATIC_ITEM("", false, false, buffer); // 125m + END_SCREEN(); + } + #endif // PRINTCOUNTER + + /** + * + * About Printer > Thermistors + * + */ + static void lcd_info_thermistors_menu() { + if (LCD_CLICKED) { lcd_goto_previous_menu(true); return; } + START_SCREEN(); + #define THERMISTOR_ID TEMP_SENSOR_0 + #include "thermistornames.h" + STATIC_ITEM("T0: " THERMISTOR_NAME, false, true); + STATIC_ITEM(MSG_INFO_MIN_TEMP ": " STRINGIFY(HEATER_0_MINTEMP), false); + STATIC_ITEM(MSG_INFO_MAX_TEMP ": " STRINGIFY(HEATER_0_MAXTEMP), false); + + #if TEMP_SENSOR_1 != 0 + #undef THERMISTOR_ID + #define THERMISTOR_ID TEMP_SENSOR_1 + #include "thermistornames.h" + STATIC_ITEM("T1: " THERMISTOR_NAME, false, true); + STATIC_ITEM(MSG_INFO_MIN_TEMP ": " STRINGIFY(HEATER_1_MINTEMP), false); + STATIC_ITEM(MSG_INFO_MAX_TEMP ": " STRINGIFY(HEATER_1_MAXTEMP), false); + #endif + + #if TEMP_SENSOR_2 != 0 + #undef THERMISTOR_ID + #define THERMISTOR_ID TEMP_SENSOR_2 + #include "thermistornames.h" + STATIC_ITEM("T2: " THERMISTOR_NAME, false, true); + STATIC_ITEM(MSG_INFO_MIN_TEMP ": " STRINGIFY(HEATER_2_MINTEMP), false); + STATIC_ITEM(MSG_INFO_MAX_TEMP ": " STRINGIFY(HEATER_2_MAXTEMP), false); + #endif + + #if TEMP_SENSOR_3 != 0 + #undef THERMISTOR_ID + #define THERMISTOR_ID TEMP_SENSOR_3 + #include "thermistornames.h" + STATIC_ITEM("T3: " THERMISTOR_NAME, false, true); + STATIC_ITEM(MSG_INFO_MIN_TEMP ": " STRINGIFY(HEATER_3_MINTEMP), false); + STATIC_ITEM(MSG_INFO_MAX_TEMP ": " STRINGIFY(HEATER_3_MAXTEMP), false); + #endif + + #if TEMP_SENSOR_BED != 0 + #undef THERMISTOR_ID + #define THERMISTOR_ID TEMP_SENSOR_BED + #include "thermistornames.h" + STATIC_ITEM("TBed:" THERMISTOR_NAME, false, true); + STATIC_ITEM(MSG_INFO_MIN_TEMP ": " STRINGIFY(BED_MINTEMP), false); + STATIC_ITEM(MSG_INFO_MAX_TEMP ": " STRINGIFY(BED_MAXTEMP), false); + #endif + END_SCREEN(); + } + + /** + * + * About Printer > Board Info + * + */ + static void lcd_info_board_menu() { + if (LCD_CLICKED) { lcd_goto_previous_menu(true); return; } + START_SCREEN(); + STATIC_ITEM(BOARD_NAME, true, true); // MyPrinterController + STATIC_ITEM(MSG_INFO_BAUDRATE ": " STRINGIFY(BAUDRATE)); // Baud: 250000 + STATIC_ITEM(MSG_INFO_PROTOCOL ": " PROTOCOL_VERSION); // Protocol: 1.0 + #ifdef POWER_SUPPLY + #if (POWER_SUPPLY == 1) + STATIC_ITEM(MSG_INFO_PSU ": ATX"); // Power Supply: ATX + #elif (POWER_SUPPLY == 2) + STATIC_ITEM(MSG_INFO_PSU ": XBox"); // Power Supply: XBox + #endif + #endif // POWER_SUPPLY + END_SCREEN(); + } + + /** + * + * About Printer > Printer Info + * + */ + static void lcd_info_printer_menu() { + if (LCD_CLICKED) { lcd_goto_previous_menu(true); return; } + START_SCREEN(); + STATIC_ITEM(MSG_MARLIN, true, true); // Marlin + STATIC_ITEM(SHORT_BUILD_VERSION); // x.x.x-Branch + STATIC_ITEM(STRING_DISTRIBUTION_DATE); // YYYY-MM-DD HH:MM + STATIC_ITEM(MACHINE_NAME); // My3DPrinter + STATIC_ITEM(WEBSITE_URL); // www.my3dprinter.com + STATIC_ITEM(MSG_INFO_EXTRUDERS ": " STRINGIFY(EXTRUDERS)); // Extruders: 2 + END_SCREEN(); + } + + /** + * + * "About Printer" submenu + * + */ + static void lcd_info_menu() { + START_MENU(); + MENU_ITEM(back, MSG_MAIN); + MENU_ITEM(submenu, MSG_INFO_PRINTER_MENU, lcd_info_printer_menu); // Printer Info > + MENU_ITEM(submenu, MSG_INFO_BOARD_MENU, lcd_info_board_menu); // Board Info > + MENU_ITEM(submenu, MSG_INFO_THERMISTOR_MENU, lcd_info_thermistors_menu); // Thermistors > + #if ENABLED(PRINTCOUNTER) + MENU_ITEM(submenu, MSG_INFO_STATS_MENU, lcd_info_stats_menu); // Printer Statistics > + #endif + END_MENU(); + } + #endif // LCD_INFO_MENU + + #if ENABLED(FILAMENT_CHANGE_FEATURE) + + static void lcd_filament_change_resume_print() { + filament_change_menu_response = FILAMENT_CHANGE_RESPONSE_RESUME_PRINT; + lcdDrawUpdate = 2; + lcd_goto_screen(lcd_status_screen); + } + + static void lcd_filament_change_extrude_more() { + filament_change_menu_response = FILAMENT_CHANGE_RESPONSE_EXTRUDE_MORE; + } + + static void lcd_filament_change_option_menu() { + START_MENU(); + #if LCD_HEIGHT > 2 + STATIC_ITEM(MSG_FILAMENT_CHANGE_OPTION_HEADER, true, false); + #endif + MENU_ITEM(function, MSG_FILAMENT_CHANGE_OPTION_RESUME, lcd_filament_change_resume_print); + MENU_ITEM(function, MSG_FILAMENT_CHANGE_OPTION_EXTRUDE, lcd_filament_change_extrude_more); + END_MENU(); + } + + static void lcd_filament_change_init_message() { + START_SCREEN(); + STATIC_ITEM(MSG_FILAMENT_CHANGE_HEADER, true, true); + STATIC_ITEM(MSG_FILAMENT_CHANGE_INIT_1); + #ifdef MSG_FILAMENT_CHANGE_INIT_2 + STATIC_ITEM(MSG_FILAMENT_CHANGE_INIT_2); + #endif + #ifdef MSG_FILAMENT_CHANGE_INIT_3 + STATIC_ITEM(MSG_FILAMENT_CHANGE_INIT_3); + #endif + END_SCREEN(); + } + + static void lcd_filament_change_unload_message() { + START_SCREEN(); + STATIC_ITEM(MSG_FILAMENT_CHANGE_HEADER, true, true); + STATIC_ITEM(MSG_FILAMENT_CHANGE_UNLOAD_1); + #ifdef MSG_FILAMENT_CHANGE_UNLOAD_2 + STATIC_ITEM(MSG_FILAMENT_CHANGE_UNLOAD_2); + #endif + #ifdef MSG_FILAMENT_CHANGE_UNLOAD_3 + STATIC_ITEM(MSG_FILAMENT_CHANGE_UNLOAD_3); + #endif + END_SCREEN(); + } + + static void lcd_filament_change_insert_message() { + START_SCREEN(); + STATIC_ITEM(MSG_FILAMENT_CHANGE_HEADER, true, true); + STATIC_ITEM(MSG_FILAMENT_CHANGE_INSERT_1); + #ifdef MSG_FILAMENT_CHANGE_INSERT_2 + STATIC_ITEM(MSG_FILAMENT_CHANGE_INSERT_2); + #endif + #ifdef MSG_FILAMENT_CHANGE_INSERT_3 + STATIC_ITEM(MSG_FILAMENT_CHANGE_INSERT_3); + #endif + END_SCREEN(); + } + + static void lcd_filament_change_load_message() { + START_SCREEN(); + STATIC_ITEM(MSG_FILAMENT_CHANGE_HEADER, true, true); + STATIC_ITEM(MSG_FILAMENT_CHANGE_LOAD_1); + #ifdef MSG_FILAMENT_CHANGE_LOAD_2 + STATIC_ITEM(MSG_FILAMENT_CHANGE_LOAD_2); + #endif + #ifdef MSG_FILAMENT_CHANGE_LOAD_3 + STATIC_ITEM(MSG_FILAMENT_CHANGE_LOAD_3); + #endif + END_SCREEN(); + } + + static void lcd_filament_change_extrude_message() { + START_SCREEN(); + STATIC_ITEM(MSG_FILAMENT_CHANGE_HEADER, true, true); + STATIC_ITEM(MSG_FILAMENT_CHANGE_EXTRUDE_1); + #ifdef MSG_FILAMENT_CHANGE_EXTRUDE_2 + STATIC_ITEM(MSG_FILAMENT_CHANGE_EXTRUDE_2); + #endif + #ifdef MSG_FILAMENT_CHANGE_EXTRUDE_3 + STATIC_ITEM(MSG_FILAMENT_CHANGE_EXTRUDE_3); + #endif + END_SCREEN(); + } + + static void lcd_filament_change_resume_message() { + START_SCREEN(); + STATIC_ITEM(MSG_FILAMENT_CHANGE_HEADER, true, true); + STATIC_ITEM(MSG_FILAMENT_CHANGE_RESUME_1); + #ifdef MSG_FILAMENT_CHANGE_RESUME_2 + STATIC_ITEM(MSG_FILAMENT_CHANGE_RESUME_2); + #endif + #ifdef MSG_FILAMENT_CHANGE_RESUME_3 + STATIC_ITEM(MSG_FILAMENT_CHANGE_RESUME_3); + #endif + END_SCREEN(); + } + + void lcd_filament_change_show_message(FilamentChangeMessage message) { + switch (message) { + case FILAMENT_CHANGE_MESSAGE_INIT: + defer_return_to_status = true; + lcd_goto_screen(lcd_filament_change_init_message); + break; + case FILAMENT_CHANGE_MESSAGE_UNLOAD: + lcd_goto_screen(lcd_filament_change_unload_message); + break; + case FILAMENT_CHANGE_MESSAGE_INSERT: + lcd_goto_screen(lcd_filament_change_insert_message); + break; + case FILAMENT_CHANGE_MESSAGE_LOAD: + lcd_goto_screen(lcd_filament_change_load_message); + break; + case FILAMENT_CHANGE_MESSAGE_EXTRUDE: + lcd_goto_screen(lcd_filament_change_extrude_message); + break; + case FILAMENT_CHANGE_MESSAGE_OPTION: + filament_change_menu_response = FILAMENT_CHANGE_RESPONSE_WAIT_FOR; + lcd_goto_screen(lcd_filament_change_option_menu); + break; + case FILAMENT_CHANGE_MESSAGE_RESUME: + lcd_goto_screen(lcd_filament_change_resume_message); + break; + case FILAMENT_CHANGE_MESSAGE_STATUS: + lcd_return_to_status(); + break; + } + } + + #endif // FILAMENT_CHANGE_FEATURE + + /** + * + * Functions for editing single values + * + * The "menu_edit_type" macro generates the functions needed to edit a numerical value. + * + * For example, menu_edit_type(int, int3, itostr3, 1) expands into these functions: + * + * bool _menu_edit_int3(); + * void menu_edit_int3(); // edit int (interactively) + * void menu_edit_callback_int3(); // edit int (interactively) with callback on completion + * static void _menu_action_setting_edit_int3(const char* pstr, int* ptr, int minValue, int maxValue); + * static void menu_action_setting_edit_int3(const char* pstr, int* ptr, int minValue, int maxValue); + * static void menu_action_setting_edit_callback_int3(const char* pstr, int* ptr, int minValue, int maxValue, screenFunc_t callback); // edit int with callback + * + * You can then use one of the menu macros to present the edit interface: + * MENU_ITEM_EDIT(int3, MSG_SPEED, &feedrate_percentage, 10, 999) + * + * This expands into a more primitive menu item: + * MENU_ITEM(setting_edit_int3, MSG_SPEED, PSTR(MSG_SPEED), &feedrate_percentage, 10, 999) + * + * + * Also: MENU_MULTIPLIER_ITEM_EDIT, MENU_ITEM_EDIT_CALLBACK, and MENU_MULTIPLIER_ITEM_EDIT_CALLBACK + * + * menu_action_setting_edit_int3(PSTR(MSG_SPEED), &feedrate_percentage, 10, 999) + */ + #define menu_edit_type(_type, _name, _strFunc, scale) \ + bool _menu_edit_ ## _name () { \ + ENCODER_DIRECTION_NORMAL(); \ + bool isClicked = LCD_CLICKED; \ + if ((int32_t)encoderPosition < 0) encoderPosition = 0; \ + if ((int32_t)encoderPosition > maxEditValue) encoderPosition = maxEditValue; \ + if (lcdDrawUpdate) \ + lcd_implementation_drawedit(editLabel, _strFunc(((_type)((int32_t)encoderPosition + minEditValue)) / scale)); \ + if (isClicked) { \ + *((_type*)editValue) = ((_type)((int32_t)encoderPosition + minEditValue)) / scale; \ + lcd_goto_previous_menu(true); \ + } \ + return isClicked; \ + } \ + void menu_edit_ ## _name () { _menu_edit_ ## _name(); } \ + void menu_edit_callback_ ## _name () { if (_menu_edit_ ## _name ()) (*callbackFunc)(); } \ + static void _menu_action_setting_edit_ ## _name (const char* pstr, _type* ptr, _type minValue, _type maxValue) { \ + lcd_save_previous_menu(); \ + \ + lcdDrawUpdate = LCDVIEW_CLEAR_CALL_REDRAW; \ + \ + editLabel = pstr; \ + editValue = ptr; \ + minEditValue = minValue * scale; \ + maxEditValue = maxValue * scale - minEditValue; \ + encoderPosition = (*ptr) * scale - minEditValue; \ + } \ + static void menu_action_setting_edit_ ## _name (const char* pstr, _type* ptr, _type minValue, _type maxValue) { \ + _menu_action_setting_edit_ ## _name(pstr, ptr, minValue, maxValue); \ + currentScreen = menu_edit_ ## _name; \ + }\ + static void menu_action_setting_edit_callback_ ## _name (const char* pstr, _type* ptr, _type minValue, _type maxValue, screenFunc_t callback) { \ + _menu_action_setting_edit_ ## _name(pstr, ptr, minValue, maxValue); \ + currentScreen = menu_edit_callback_ ## _name; \ + callbackFunc = callback; \ + } + + menu_edit_type(int, int3, itostr3, 1); + menu_edit_type(float, float3, ftostr3, 1); + menu_edit_type(float, float32, ftostr32, 100); + menu_edit_type(float, float43, ftostr43sign, 1000); + menu_edit_type(float, float5, ftostr5rj, 0.01); + menu_edit_type(float, float51, ftostr51sign, 10); + menu_edit_type(float, float52, ftostr52sign, 100); + menu_edit_type(unsigned long, long5, ftostr5rj, 0.01); + + /** + * + * Handlers for RepRap World Keypad input + * + */ + #if ENABLED(REPRAPWORLD_KEYPAD) + static void _reprapworld_keypad_move(AxisEnum axis, int dir) { + move_menu_scale = REPRAPWORLD_KEYPAD_MOVE_STEP; + encoderPosition = dir; + switch (axis) { + case X_AXIS: lcd_move_x(); break; + case Y_AXIS: lcd_move_y(); break; + case Z_AXIS: lcd_move_z(); + } + } + static void reprapworld_keypad_move_z_up() { _reprapworld_keypad_move(Z_AXIS, 1); } + static void reprapworld_keypad_move_z_down() { _reprapworld_keypad_move(Z_AXIS, -1); } + static void reprapworld_keypad_move_x_left() { _reprapworld_keypad_move(X_AXIS, -1); } + static void reprapworld_keypad_move_x_right() { _reprapworld_keypad_move(X_AXIS, 1); } + static void reprapworld_keypad_move_y_up() { _reprapworld_keypad_move(Y_AXIS, -1); } + static void reprapworld_keypad_move_y_down() { _reprapworld_keypad_move(Y_AXIS, 1); } + static void reprapworld_keypad_move_home() { enqueue_and_echo_commands_P(PSTR("G28")); } // move all axes home and wait + static void reprapworld_keypad_move_menu() { lcd_goto_screen(lcd_move_menu); } + #endif // REPRAPWORLD_KEYPAD + + /** + * + * Audio feedback for controller clicks + * + */ + void lcd_buzz(long duration, uint16_t freq) { + #if ENABLED(LCD_USE_I2C_BUZZER) + lcd.buzz(duration, freq); + #elif PIN_EXISTS(BEEPER) + buzzer.tone(duration, freq); + #endif + } + + void lcd_quick_feedback() { + lcdDrawUpdate = LCDVIEW_CLEAR_CALL_REDRAW; + next_button_update_ms = millis() + 500; + + // Buzz and wait. The delay is needed for buttons to settle! + lcd_buzz(LCD_FEEDBACK_FREQUENCY_DURATION_MS, LCD_FEEDBACK_FREQUENCY_HZ); + #if ENABLED(LCD_USE_I2C_BUZZER) + delay(10); + #elif PIN_EXISTS(BEEPER) + for (int8_t i = 5; i--;) { buzzer.tick(); delay(2); } + #endif + } + + /** + * + * Menu actions + * + */ + static void menu_action_back() { lcd_goto_previous_menu(); } + static void menu_action_submenu(screenFunc_t func) { lcd_save_previous_menu(); lcd_goto_screen(func); } + static void menu_action_gcode(const char* pgcode) { enqueue_and_echo_commands_P(pgcode); } + static void menu_action_function(screenFunc_t func) { (*func)(); } + + #if ENABLED(SDSUPPORT) + + static void menu_action_sdfile(const char* filename, char* longFilename) { + UNUSED(longFilename); + card.openAndPrintFile(filename); + lcd_return_to_status(); + } + + static void menu_action_sddirectory(const char* filename, char* longFilename) { + UNUSED(longFilename); + card.chdir(filename); + encoderPosition = 0; + } + + #endif //SDSUPPORT + + static void menu_action_setting_edit_bool(const char* pstr, bool* ptr) {UNUSED(pstr); *ptr = !(*ptr); } + static void menu_action_setting_edit_callback_bool(const char* pstr, bool* ptr, screenFunc_t callback) { + menu_action_setting_edit_bool(pstr, ptr); + (*callback)(); + } + +#endif //ULTIPANEL + +/** LCD API **/ +void lcd_init() { + + lcd_implementation_init(); + + #if ENABLED(NEWPANEL) + #if BUTTON_EXISTS(EN1) + SET_INPUT(BTN_EN1); + WRITE(BTN_EN1, HIGH); + #endif + + #if BUTTON_EXISTS(EN2) + SET_INPUT(BTN_EN2); + WRITE(BTN_EN2, HIGH); + #endif + + #if BUTTON_EXISTS(ENC) + SET_INPUT(BTN_ENC); + WRITE(BTN_ENC, HIGH); + #endif + + #if ENABLED(REPRAPWORLD_KEYPAD) + pinMode(SHIFT_CLK, OUTPUT); + pinMode(SHIFT_LD, OUTPUT); + pinMode(SHIFT_OUT, INPUT); + WRITE(SHIFT_OUT, HIGH); + WRITE(SHIFT_LD, HIGH); + #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 + + #else // !NEWPANEL + + #if ENABLED(SR_LCD_2W_NL) // Non latching 2 wire shift register + pinMode(SR_DATA_PIN, OUTPUT); + pinMode(SR_CLK_PIN, OUTPUT); + #elif defined(SHIFT_CLK) + pinMode(SHIFT_CLK, OUTPUT); + pinMode(SHIFT_LD, OUTPUT); + pinMode(SHIFT_EN, OUTPUT); + pinMode(SHIFT_OUT, INPUT); + WRITE(SHIFT_OUT, HIGH); + WRITE(SHIFT_LD, HIGH); + WRITE(SHIFT_EN, LOW); + #endif // SR_LCD_2W_NL + + #endif // !NEWPANEL + + #if ENABLED(SDSUPPORT) && PIN_EXISTS(SD_DETECT) + SET_INPUT(SD_DETECT_PIN); + WRITE(SD_DETECT_PIN, HIGH); + lcd_sd_status = 2; // UNKNOWN + #endif + + #if ENABLED(LCD_HAS_SLOW_BUTTONS) + slow_buttons = 0; + #endif + + lcd_buttons_update(); + + #if ENABLED(ULTIPANEL) + encoderDiff = 0; + #endif +} + +int lcd_strlen(const char* s) { + int i = 0, j = 0; + while (s[i]) { + #if ENABLED(MAPPER_NON) + j++; + #else + if ((s[i] & 0xC0u) != 0x80u) j++; + #endif + i++; + } + return j; +} + +int lcd_strlen_P(const char* s) { + int j = 0; + while (pgm_read_byte(s)) { + #if ENABLED(MAPPER_NON) + j++; + #else + if ((pgm_read_byte(s) & 0xC0u) != 0x80u) j++; + #endif + s++; + } + return j; +} + +bool lcd_blink() { + static uint8_t blink = 0; + static millis_t next_blink_ms = 0; + millis_t ms = millis(); + if (ELAPSED(ms, next_blink_ms)) { + blink ^= 0xFF; + next_blink_ms = ms + 1000 - LCD_UPDATE_INTERVAL / 2; + } + return blink != 0; +} + +/** + * Update the LCD, read encoder buttons, etc. + * - Read button states + * - Check the SD Card slot state + * - Act on RepRap World keypad input + * - Update the encoder position + * - Apply acceleration to the encoder position + * - Set lcdDrawUpdate = LCDVIEW_CALL_REDRAW_NOW on controller events + * - Reset the Info Screen timeout if there's any input + * - Update status indicators, if any + * + * Run the current LCD menu handler callback function: + * - Call the handler only if lcdDrawUpdate != LCDVIEW_NONE + * - Before calling the handler, LCDVIEW_CALL_NO_REDRAW => LCDVIEW_NONE + * - Call the menu handler. Menu handlers should do the following: + * - If a value changes, set lcdDrawUpdate to LCDVIEW_REDRAW_NOW and draw the value + * (Encoder events automatically set lcdDrawUpdate for you.) + * - if (lcdDrawUpdate) { redraw } + * - Before exiting the handler set lcdDrawUpdate to: + * - LCDVIEW_CLEAR_CALL_REDRAW to clear screen and set LCDVIEW_CALL_REDRAW_NEXT. + * - LCDVIEW_REDRAW_NOW or LCDVIEW_NONE to keep drawingm but only in this loop. + * - LCDVIEW_REDRAW_NEXT to keep drawing and draw on the next loop also. + * - LCDVIEW_CALL_NO_REDRAW to keep drawing (or start drawing) with no redraw on the next loop. + * - NOTE: For graphical displays menu handlers may be called 2 or more times per loop, + * so don't change lcdDrawUpdate without considering this. + * + * After the menu handler callback runs (or not): + * - Clear the LCD if lcdDrawUpdate == LCDVIEW_CLEAR_CALL_REDRAW + * - Update lcdDrawUpdate for the next loop (i.e., move one state down, usually) + * + * No worries. This function is only called from the main thread. + */ +void lcd_update() { + + #if ENABLED(ULTIPANEL) + static millis_t return_to_status_ms = 0; + manage_manual_move(); + #endif + + lcd_buttons_update(); + + #if ENABLED(SDSUPPORT) && PIN_EXISTS(SD_DETECT) + + bool sd_status = IS_SD_INSERTED; + if (sd_status != lcd_sd_status && lcd_detected()) { + lcdDrawUpdate = LCDVIEW_CLEAR_CALL_REDRAW; + lcd_implementation_init( // to maybe revive the LCD if static electricity killed it. + #if ENABLED(LCD_PROGRESS_BAR) && ENABLED(ULTIPANEL) + currentScreen == lcd_status_screen + #endif + ); + + if (sd_status) { + card.initsd(); + if (lcd_sd_status != 2) LCD_MESSAGEPGM(MSG_SD_INSERTED); + } + else { + card.release(); + if (lcd_sd_status != 2) LCD_MESSAGEPGM(MSG_SD_REMOVED); + } + + lcd_sd_status = sd_status; + } + + #endif //SDSUPPORT && SD_DETECT_PIN + + millis_t ms = millis(); + if (ELAPSED(ms, next_lcd_update_ms)) { + + next_lcd_update_ms = ms + LCD_UPDATE_INTERVAL; + + #if ENABLED(LCD_HAS_STATUS_INDICATORS) + lcd_implementation_update_indicators(); + #endif + + #if ENABLED(LCD_HAS_SLOW_BUTTONS) + slow_buttons = lcd_implementation_read_slow_buttons(); // buttons which take too long to read in interrupt context + #endif + + #if ENABLED(ULTIPANEL) + + #if ENABLED(REPRAPWORLD_KEYPAD) + + static uint8_t keypad_debounce = 0; + + if (!REPRAPWORLD_KEYPAD_PRESSED) { + if (keypad_debounce > 0) keypad_debounce--; + } + else if (!keypad_debounce) { + keypad_debounce = 2; + + if (REPRAPWORLD_KEYPAD_MOVE_MENU) reprapworld_keypad_move_menu(); + + #if DISABLED(DELTA) && Z_HOME_DIR == -1 + if (REPRAPWORLD_KEYPAD_MOVE_Z_UP) reprapworld_keypad_move_z_up(); + #endif + + if (axis_homed[X_AXIS] && axis_homed[Y_AXIS] && axis_homed[Z_AXIS]) { + #if ENABLED(DELTA) || Z_HOME_DIR != -1 + if (REPRAPWORLD_KEYPAD_MOVE_Z_UP) reprapworld_keypad_move_z_up(); + #endif + if (REPRAPWORLD_KEYPAD_MOVE_Z_DOWN) reprapworld_keypad_move_z_down(); + if (REPRAPWORLD_KEYPAD_MOVE_X_LEFT) reprapworld_keypad_move_x_left(); + if (REPRAPWORLD_KEYPAD_MOVE_X_RIGHT) reprapworld_keypad_move_x_right(); + if (REPRAPWORLD_KEYPAD_MOVE_Y_DOWN) reprapworld_keypad_move_y_down(); + if (REPRAPWORLD_KEYPAD_MOVE_Y_UP) reprapworld_keypad_move_y_up(); + } + else { + if (REPRAPWORLD_KEYPAD_MOVE_HOME) reprapworld_keypad_move_home(); + } + } + #endif // REPRAPWORLD_KEYPAD + + bool encoderPastThreshold = (abs(encoderDiff) >= ENCODER_PULSES_PER_STEP); + if (encoderPastThreshold || LCD_CLICKED) { + if (encoderPastThreshold) { + int32_t encoderMultiplier = 1; + + #if ENABLED(ENCODER_RATE_MULTIPLIER) + + if (encoderRateMultiplierEnabled) { + int32_t encoderMovementSteps = abs(encoderDiff) / ENCODER_PULSES_PER_STEP; + + if (lastEncoderMovementMillis != 0) { + // Note that the rate is always calculated between to passes through the + // loop and that the abs of the encoderDiff value is tracked. + float encoderStepRate = (float)(encoderMovementSteps) / ((float)(ms - lastEncoderMovementMillis)) * 1000.0; + + if (encoderStepRate >= ENCODER_100X_STEPS_PER_SEC) encoderMultiplier = 100; + else if (encoderStepRate >= ENCODER_10X_STEPS_PER_SEC) encoderMultiplier = 10; + + #if ENABLED(ENCODER_RATE_MULTIPLIER_DEBUG) + SERIAL_ECHO_START; + SERIAL_ECHOPAIR("Enc Step Rate: ", encoderStepRate); + SERIAL_ECHOPAIR(" Multiplier: ", encoderMultiplier); + SERIAL_ECHOPAIR(" ENCODER_10X_STEPS_PER_SEC: ", ENCODER_10X_STEPS_PER_SEC); + SERIAL_ECHOPAIR(" ENCODER_100X_STEPS_PER_SEC: ", ENCODER_100X_STEPS_PER_SEC); + SERIAL_EOL; + #endif //ENCODER_RATE_MULTIPLIER_DEBUG + } + + lastEncoderMovementMillis = ms; + } // encoderRateMultiplierEnabled + #endif //ENCODER_RATE_MULTIPLIER + + encoderPosition += (encoderDiff * encoderMultiplier) / ENCODER_PULSES_PER_STEP; + encoderDiff = 0; + } + return_to_status_ms = ms + LCD_TIMEOUT_TO_STATUS; + lcdDrawUpdate = LCDVIEW_REDRAW_NOW; + } + #endif // ULTIPANEL + + // We arrive here every ~100ms when idling often enough. + // Instead of tracking the changes simply redraw the Info Screen ~1 time a second. + static int8_t lcd_status_update_delay = 1; // first update one loop delayed + if ( + #if ENABLED(ULTIPANEL) + currentScreen == lcd_status_screen && + #endif + !lcd_status_update_delay--) { + lcd_status_update_delay = 9; + lcdDrawUpdate = LCDVIEW_REDRAW_NOW; + } + + if (lcdDrawUpdate) { + + switch (lcdDrawUpdate) { + case LCDVIEW_CALL_NO_REDRAW: + lcdDrawUpdate = LCDVIEW_NONE; + break; + case LCDVIEW_CLEAR_CALL_REDRAW: // set by handlers, then altered after (rarely occurs here) + case LCDVIEW_CALL_REDRAW_NEXT: // set by handlers, then altered after (never occurs here?) + lcdDrawUpdate = LCDVIEW_REDRAW_NOW; + case LCDVIEW_REDRAW_NOW: // set above, or by a handler through LCDVIEW_CALL_REDRAW_NEXT + case LCDVIEW_NONE: + break; + } + + #if ENABLED(DOGLCD) // Changes due to different driver architecture of the DOGM display + static int8_t dot_color = 0; + dot_color = 1 - dot_color; + u8g.firstPage(); + do { + lcd_setFont(FONT_MENU); + u8g.setPrintPos(125, 0); + u8g.setColorIndex(dot_color); // Set color for the alive dot + u8g.drawPixel(127, 63); // draw alive dot + u8g.setColorIndex(1); // black on white + (*currentScreen)(); + } while (u8g.nextPage()); + #elif ENABLED(ULTIPANEL) + (*currentScreen)(); + #else + lcd_status_screen(); + #endif + } + + #if ENABLED(ULTIPANEL) + + // Return to Status Screen after a timeout + if (currentScreen == lcd_status_screen || defer_return_to_status) + return_to_status_ms = ms + LCD_TIMEOUT_TO_STATUS; + else if (ELAPSED(ms, return_to_status_ms)) + lcd_return_to_status(); + + #endif // ULTIPANEL + + switch (lcdDrawUpdate) { + case LCDVIEW_CLEAR_CALL_REDRAW: + lcd_implementation_clear(); + case LCDVIEW_CALL_REDRAW_NEXT: + lcdDrawUpdate = LCDVIEW_REDRAW_NOW; + break; + case LCDVIEW_REDRAW_NOW: + lcdDrawUpdate = LCDVIEW_NONE; + break; + case LCDVIEW_NONE: + break; + } + + } +} + +void set_utf_strlen(char* s, uint8_t n) { + uint8_t i = 0, j = 0; + while (s[i] && (j < n)) { + #if ENABLED(MAPPER_NON) + j++; + #else + if ((s[i] & 0xC0u) != 0x80u) j++; + #endif + i++; + } + while (j++ < n) s[i++] = ' '; + s[i] = '\0'; +} + +void lcd_finishstatus(bool persist=false) { + set_utf_strlen(lcd_status_message, LCD_WIDTH); + #if !(ENABLED(LCD_PROGRESS_BAR) && (PROGRESS_MSG_EXPIRE > 0)) + UNUSED(persist); + #endif + + #if ENABLED(LCD_PROGRESS_BAR) + progress_bar_ms = millis(); + #if PROGRESS_MSG_EXPIRE > 0 + expire_status_ms = persist ? 0 : progress_bar_ms + PROGRESS_MSG_EXPIRE; + #endif + #endif + lcdDrawUpdate = LCDVIEW_CLEAR_CALL_REDRAW; + + #if ENABLED(FILAMENT_LCD_DISPLAY) + previous_lcd_status_ms = millis(); //get status message to show up for a while + #endif +} + +#if ENABLED(LCD_PROGRESS_BAR) && PROGRESS_MSG_EXPIRE > 0 + void dontExpireStatus() { expire_status_ms = 0; } +#endif + +bool lcd_hasstatus() { return (lcd_status_message[0] != '\0'); } + +void lcd_setstatus(const char* message, bool persist) { + if (lcd_status_message_level > 0) return; + strncpy(lcd_status_message, message, 3 * (LCD_WIDTH)); + lcd_finishstatus(persist); +} + +void lcd_setstatuspgm(const char* message, uint8_t level) { + if (level < lcd_status_message_level) return; + lcd_status_message_level = level; + strncpy_P(lcd_status_message, message, 3 * (LCD_WIDTH)); + lcd_finishstatus(level > 0); +} + +void lcd_setalertstatuspgm(const char* message) { + lcd_setstatuspgm(message, 1); + #if ENABLED(ULTIPANEL) + lcd_return_to_status(); + #endif +} + +void lcd_reset_alert_level() { lcd_status_message_level = 0; } + +#if HAS_LCD_CONTRAST + void set_lcd_contrast(int value) { + lcd_contrast = constrain(value, LCD_CONTRAST_MIN, LCD_CONTRAST_MAX); + u8g.setContrast(lcd_contrast); + } +#endif + +#if ENABLED(ULTIPANEL) + + /** + * 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 + */ + #if defined(EN_A) && defined(EN_B) + #define encrot0 0 + #define encrot1 2 + #define encrot2 3 + #define encrot3 1 + #endif + + #define GET_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 + + + /** + * Read encoder buttons from the hardware registers + * Warning: This function is called from interrupt context! + */ + void lcd_buttons_update() { + #if ENABLED(NEWPANEL) + 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 LCD_HAS_DIRECTIONAL_BUTTONS || BUTTON_EXISTS(ENC) + millis_t now = millis(); + #endif + + #if LCD_HAS_DIRECTIONAL_BUTTONS + if (ELAPSED(now, next_button_update_ms)) { + if (false) { + // for the else-ifs below + } + #if BUTTON_EXISTS(UP) + else if (BUTTON_PRESSED(UP)) { + encoderDiff = -(ENCODER_STEPS_PER_MENU_ITEM); + next_button_update_ms = now + 300; + } + #endif + #if BUTTON_EXISTS(DWN) + else if (BUTTON_PRESSED(DWN)) { + encoderDiff = ENCODER_STEPS_PER_MENU_ITEM; + next_button_update_ms = now + 300; + } + #endif + #if BUTTON_EXISTS(LFT) + else if (BUTTON_PRESSED(LFT)) { + encoderDiff = -(ENCODER_PULSES_PER_STEP); + next_button_update_ms = now + 300; + } + #endif + #if BUTTON_EXISTS(RT) + else if (BUTTON_PRESSED(RT)) { + encoderDiff = ENCODER_PULSES_PER_STEP; + next_button_update_ms = now + 300; + } + #endif + } + #endif + + #if BUTTON_EXISTS(ENC) + if (ELAPSED(now, next_button_update_ms) && BUTTON_PRESSED(ENC)) newbutton |= EN_C; + #endif + + buttons = newbutton; + #if ENABLED(LCD_HAS_SLOW_BUTTONS) + buttons |= slow_buttons; + #endif + #if ENABLED(REPRAPWORLD_KEYPAD) + GET_BUTTON_STATES(buttons_reprapworld_keypad); + #endif + #else + GET_BUTTON_STATES(buttons); + #endif //!NEWPANEL + + // Manage encoder rotation + #if ENABLED(REVERSE_MENU_DIRECTION) && ENABLED(REVERSE_ENCODER_DIRECTION) + #define ENCODER_DIFF_CW (encoderDiff -= encoderDirection) + #define ENCODER_DIFF_CCW (encoderDiff += encoderDirection) + #elif ENABLED(REVERSE_MENU_DIRECTION) + #define ENCODER_DIFF_CW (encoderDiff += encoderDirection) + #define ENCODER_DIFF_CCW (encoderDiff -= encoderDirection) + #elif ENABLED(REVERSE_ENCODER_DIRECTION) + #define ENCODER_DIFF_CW (encoderDiff--) + #define ENCODER_DIFF_CCW (encoderDiff++) + #else + #define ENCODER_DIFF_CW (encoderDiff++) + #define ENCODER_DIFF_CCW (encoderDiff--) + #endif + #define ENCODER_SPIN(_E1, _E2) switch (lastEncoderBits) { case _E1: ENCODER_DIFF_CW; break; case _E2: ENCODER_DIFF_CCW; } + + uint8_t enc = 0; + if (buttons & EN_A) enc |= B01; + if (buttons & EN_B) enc |= B10; + if (enc != lastEncoderBits) { + switch (enc) { + case encrot0: ENCODER_SPIN(encrot3, encrot1); break; + case encrot1: ENCODER_SPIN(encrot0, encrot2); break; + case encrot2: ENCODER_SPIN(encrot1, encrot3); break; + case encrot3: ENCODER_SPIN(encrot2, encrot0); break; + } + } + lastEncoderBits = enc; + } + + bool lcd_detected(void) { + #if (ENABLED(LCD_I2C_TYPE_MCP23017) || ENABLED(LCD_I2C_TYPE_MCP23008)) && ENABLED(DETECT_DEVICE) + return lcd.LcdDetected() == 1; + #else + return true; + #endif + } + + bool lcd_clicked() { return LCD_CLICKED; } + +#endif // ULTIPANEL + +/*********************************/ +/** Number to string conversion **/ +/*********************************/ + +#define DIGIT(n) ('0' + (n)) +#define DIGIMOD(n) DIGIT((n) % 10) + +char conv[8]; + +// Convert float to rj string with 123 or -12 format +char *ftostr3(const float& x) { return itostr3((int)x); } + +// Convert float to rj string with _123, -123, _-12, or __-1 format +char *ftostr4sign(const float& x) { return itostr4sign((int)x); } + +// Convert unsigned int to string with 12 format +char* itostr2(const uint8_t& x) { + int xx = x; + conv[0] = DIGIMOD(xx / 10); + conv[1] = DIGIMOD(xx); + conv[2] = '\0'; + return conv; +} + +// Convert float to string with +123.4 / -123.4 format +char* ftostr41sign(const float& x) { + int xx = int(abs(x * 10)) % 10000; + conv[0] = x >= 0 ? '+' : '-'; + conv[1] = DIGIMOD(xx / 1000); + conv[2] = DIGIMOD(xx / 100); + conv[3] = DIGIMOD(xx / 10); + conv[4] = '.'; + conv[5] = DIGIMOD(xx); + conv[6] = '\0'; + return conv; +} + +// Convert signed float to string with 023.45 / -23.45 format +char *ftostr32(const float& x) { + long xx = abs(x * 100); + conv[0] = x >= 0 ? DIGIMOD(xx / 10000) : '-'; + conv[1] = DIGIMOD(xx / 1000); + conv[2] = DIGIMOD(xx / 100); + conv[3] = '.'; + conv[4] = DIGIMOD(xx / 10); + conv[5] = DIGIMOD(xx); + conv[6] = '\0'; + return conv; +} + +// Convert signed float to string (6 digit) with -1.234 / _0.000 / +1.234 format +char* ftostr43sign(const float& x, char plus/*=' '*/) { + long xx = x * 1000; + if (xx == 0) + conv[0] = ' '; + else if (xx > 0) + conv[0] = plus; + else { + xx = -xx; + conv[0] = '-'; + } + conv[1] = DIGIMOD(xx / 1000); + conv[2] = '.'; + conv[3] = DIGIMOD(xx / 100); + conv[4] = DIGIMOD(xx / 10); + conv[5] = DIGIMOD(xx); + conv[6] = '\0'; + return conv; +} + +// Convert unsigned float to string with 1.23 format +char* ftostr12ns(const float& x) { + long xx = x * 100; + xx = abs(xx); + conv[0] = DIGIMOD(xx / 100); + conv[1] = '.'; + conv[2] = DIGIMOD(xx / 10); + conv[3] = DIGIMOD(xx); + conv[4] = '\0'; + return conv; +} + +// Convert signed int to lj string with +012 / -012 format +char* itostr3sign(const int& x) { + int xx; + if (x >= 0) { + conv[0] = '+'; + xx = x; + } + else { + conv[0] = '-'; + xx = -x; + } + conv[1] = DIGIMOD(xx / 100); + conv[2] = DIGIMOD(xx / 10); + conv[3] = DIGIMOD(xx); + conv[4] = '.'; + conv[5] = '0'; + conv[6] = '\0'; + return conv; +} + +// Convert signed int to rj string with 123 or -12 format +char* itostr3(const int& x) { + int xx = x; + if (xx < 0) { + conv[0] = '-'; + xx = -xx; + } + else + conv[0] = xx >= 100 ? DIGIMOD(xx / 100) : ' '; + + conv[1] = xx >= 10 ? DIGIMOD(xx / 10) : ' '; + conv[2] = DIGIMOD(xx); + conv[3] = '\0'; + return conv; +} + +// Convert unsigned int to lj string with 123 format +char* itostr3left(const int& xx) { + if (xx >= 100) { + conv[0] = DIGIMOD(xx / 100); + conv[1] = DIGIMOD(xx / 10); + conv[2] = DIGIMOD(xx); + conv[3] = '\0'; + } + else if (xx >= 10) { + conv[0] = DIGIMOD(xx / 10); + conv[1] = DIGIMOD(xx); + conv[2] = '\0'; + } + else { + conv[0] = DIGIMOD(xx); + conv[1] = '\0'; + } + return conv; +} + +// Convert signed int to rj string with _123, -123, _-12, or __-1 format +char *itostr4sign(const int& x) { + int xx = abs(x); + int sign = 0; + if (xx >= 100) { + conv[1] = DIGIMOD(xx / 100); + conv[2] = DIGIMOD(xx / 10); + } + else if (xx >= 10) { + conv[0] = ' '; + sign = 1; + conv[2] = DIGIMOD(xx / 10); + } + else { + conv[0] = ' '; + conv[1] = ' '; + sign = 2; + } + conv[sign] = x < 0 ? '-' : ' '; + conv[3] = DIGIMOD(xx); + conv[4] = '\0'; + return conv; +} + +// Convert unsigned float to rj string with 12345 format +char* ftostr5rj(const float& x) { + long xx = abs(x); + conv[0] = xx >= 10000 ? DIGIMOD(xx / 10000) : ' '; + conv[1] = xx >= 1000 ? DIGIMOD(xx / 1000) : ' '; + conv[2] = xx >= 100 ? DIGIMOD(xx / 100) : ' '; + conv[3] = xx >= 10 ? DIGIMOD(xx / 10) : ' '; + conv[4] = DIGIMOD(xx); + conv[5] = '\0'; + return conv; +} + +// Convert signed float to string with +1234.5 format +char* ftostr51sign(const float& x) { + long xx = abs(x * 10); + conv[0] = (x >= 0) ? '+' : '-'; + conv[1] = DIGIMOD(xx / 10000); + conv[2] = DIGIMOD(xx / 1000); + conv[3] = DIGIMOD(xx / 100); + conv[4] = DIGIMOD(xx / 10); + conv[5] = '.'; + conv[6] = DIGIMOD(xx); + conv[7] = '\0'; + return conv; +} + +// Convert signed float to string with +123.45 format +char* ftostr52sign(const float& x) { + long xx = abs(x * 100); + conv[0] = (x >= 0) ? '+' : '-'; + conv[1] = DIGIMOD(xx / 10000); + conv[2] = DIGIMOD(xx / 1000); + conv[3] = DIGIMOD(xx / 100); + conv[4] = '.'; + conv[5] = DIGIMOD(xx / 10); + conv[6] = DIGIMOD(xx); + conv[7] = '\0'; + return conv; +} + +// Convert signed float to space-padded string with -_23.4_ format +char* ftostr52sp(const float& x) { + long xx = x * 100; + uint8_t dig; + if (xx < 0) { // negative val = -_0 + xx = -xx; + conv[0] = '-'; + dig = (xx / 1000) % 10; + conv[1] = dig ? DIGIT(dig) : ' '; + } + else { // positive val = __0 + dig = (xx / 10000) % 10; + if (dig) { + conv[0] = DIGIT(dig); + conv[1] = DIGIMOD(xx / 1000); + } + else { + conv[0] = ' '; + dig = (xx / 1000) % 10; + conv[1] = dig ? DIGIT(dig) : ' '; + } + } + + conv[2] = DIGIMOD(xx / 100); // lsd always + + dig = xx % 10; + if (dig) { // 2 decimal places + conv[5] = DIGIT(dig); + conv[4] = DIGIMOD(xx / 10); + conv[3] = '.'; + } + else { // 1 or 0 decimal place + dig = (xx / 10) % 10; + if (dig) { + conv[4] = DIGIT(dig); + conv[3] = '.'; + } + else { + conv[3] = conv[4] = ' '; + } + conv[5] = ' '; + } + conv[6] = '\0'; + return conv; +} + +#endif // ULTRA_LCD diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/ultralcd.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/ultralcd.h new file mode 100644 index 00000000..b9e0e54c --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/ultralcd.h @@ -0,0 +1,195 @@ +/** + * 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 . + * + */ + +#ifndef ULTRALCD_H +#define ULTRALCD_H + +#include "Marlin.h" + +#if ENABLED(ULTRA_LCD) + + #define BUTTON_EXISTS(BN) (defined(BTN_## BN) && BTN_## BN >= 0) + #define BUTTON_PRESSED(BN) !READ(BTN_## BN) + + int lcd_strlen(const char* s); + int lcd_strlen_P(const char* s); + void lcd_update(); + void lcd_init(); + bool lcd_hasstatus(); + void lcd_setstatus(const char* message, const bool persist=false); + void lcd_setstatuspgm(const char* message, const uint8_t level=0); + void lcd_setalertstatuspgm(const char* message); + void lcd_reset_alert_level(); + bool lcd_detected(void); + void lcd_kill_screen(); + void kill_screen(const char* lcd_msg); + void lcd_preheat_pla0(); + void lcd_preheat_abs0(); + void lcd_load_menu_ABS(); + void lcd_load_menu_ABS_go(); + void lcd_load_menu_PLA(); + void lcd_load_menu_PLA_go(); + void lcd_unload_menu_ABS(); + void lcd_unload_menu_PLA(); + + #if HAS_BUZZER + void lcd_buzz(long duration, uint16_t freq); + #endif + + #if ENABLED(LCD_PROGRESS_BAR) && PROGRESS_MSG_EXPIRE > 0 + void dontExpireStatus(); + #endif + + #if ENABLED(DOGLCD) + extern int lcd_contrast; + void set_lcd_contrast(int value); + #elif ENABLED(SHOW_BOOTSCREEN) + void bootscreen(); + #endif + + #define LCD_MESSAGEPGM(x) lcd_setstatuspgm(PSTR(x)) + #define LCD_ALERTMESSAGEPGM(x) lcd_setalertstatuspgm(PSTR(x)) + + #define LCD_UPDATE_INTERVAL 100 + #define LCD_TIMEOUT_TO_STATUS 15000 + + #if ENABLED(ULTIPANEL) + extern volatile uint8_t buttons; //the last checked buttons in a bit array. + void lcd_buttons_update(); + void lcd_quick_feedback(); // Audible feedback for a button click - could also be visual + bool lcd_clicked(); + void lcd_ignore_click(bool b=true); + + #if ENABLED(FILAMENT_CHANGE_FEATURE) + void lcd_filament_change_show_message(FilamentChangeMessage message); + #endif // FILAMENT_CHANGE_FEATURE + + #else + FORCE_INLINE void lcd_buttons_update() {} + #endif + + extern int preheatHotendTemp1; + extern int preheatBedTemp1; + extern int preheatFanSpeed1; + extern int preheatHotendTemp2; + extern int preheatBedTemp2; + extern int preheatFanSpeed2; + + #if ENABLED(FILAMENT_LCD_DISPLAY) + extern millis_t previous_lcd_status_ms; + #endif + + bool lcd_blink(); + + #if ENABLED(ULTIPANEL) + #define BLEN_A 0 + #define BLEN_B 1 + // Encoder click is directly connected + #if BUTTON_EXISTS(ENC) + #define BLEN_C 2 + #define EN_C (_BV(BLEN_C)) + #endif + #define EN_A (_BV(BLEN_A)) + #define EN_B (_BV(BLEN_B)) + #define EN_C (_BV(BLEN_C)) + #endif + + #if ENABLED(REPRAPWORLD_KEYPAD) // is also ULTIPANEL and NEWPANEL + + #define REPRAPWORLD_BTN_OFFSET 0 // bit offset into buttons for shift register values + + #define BLEN_REPRAPWORLD_KEYPAD_F3 0 + #define BLEN_REPRAPWORLD_KEYPAD_F2 1 + #define BLEN_REPRAPWORLD_KEYPAD_F1 2 + #define BLEN_REPRAPWORLD_KEYPAD_DOWN 3 + #define BLEN_REPRAPWORLD_KEYPAD_RIGHT 4 + #define BLEN_REPRAPWORLD_KEYPAD_MIDDLE 5 + #define BLEN_REPRAPWORLD_KEYPAD_UP 6 + #define BLEN_REPRAPWORLD_KEYPAD_LEFT 7 + + #define EN_REPRAPWORLD_KEYPAD_F3 (_BV(REPRAPWORLD_BTN_OFFSET + BLEN_REPRAPWORLD_KEYPAD_F3)) + #define EN_REPRAPWORLD_KEYPAD_F2 (_BV(REPRAPWORLD_BTN_OFFSET + BLEN_REPRAPWORLD_KEYPAD_F2)) + #define EN_REPRAPWORLD_KEYPAD_F1 (_BV(REPRAPWORLD_BTN_OFFSET + BLEN_REPRAPWORLD_KEYPAD_F1)) + #define EN_REPRAPWORLD_KEYPAD_DOWN (_BV(REPRAPWORLD_BTN_OFFSET + BLEN_REPRAPWORLD_KEYPAD_DOWN)) + #define EN_REPRAPWORLD_KEYPAD_RIGHT (_BV(REPRAPWORLD_BTN_OFFSET + BLEN_REPRAPWORLD_KEYPAD_RIGHT)) + #define EN_REPRAPWORLD_KEYPAD_MIDDLE (_BV(REPRAPWORLD_BTN_OFFSET + BLEN_REPRAPWORLD_KEYPAD_MIDDLE)) + #define EN_REPRAPWORLD_KEYPAD_UP (_BV(REPRAPWORLD_BTN_OFFSET + BLEN_REPRAPWORLD_KEYPAD_UP)) + #define EN_REPRAPWORLD_KEYPAD_LEFT (_BV(REPRAPWORLD_BTN_OFFSET + BLEN_REPRAPWORLD_KEYPAD_LEFT)) + + #define REPRAPWORLD_KEYPAD_MOVE_Z_DOWN (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_F3) + #define REPRAPWORLD_KEYPAD_MOVE_Z_UP (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_F2) + #define REPRAPWORLD_KEYPAD_MOVE_MENU (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_F1) + #define REPRAPWORLD_KEYPAD_MOVE_Y_DOWN (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_DOWN) + #define REPRAPWORLD_KEYPAD_MOVE_X_RIGHT (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_RIGHT) + #define REPRAPWORLD_KEYPAD_MOVE_HOME (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_MIDDLE) + #define REPRAPWORLD_KEYPAD_MOVE_Y_UP (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_UP) + #define REPRAPWORLD_KEYPAD_MOVE_X_LEFT (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_LEFT) + + #define REPRAPWORLD_KEYPAD_PRESSED (buttons_reprapworld_keypad & ( \ + EN_REPRAPWORLD_KEYPAD_F3 | \ + EN_REPRAPWORLD_KEYPAD_F2 | \ + EN_REPRAPWORLD_KEYPAD_F1 | \ + EN_REPRAPWORLD_KEYPAD_DOWN | \ + EN_REPRAPWORLD_KEYPAD_RIGHT | \ + EN_REPRAPWORLD_KEYPAD_MIDDLE | \ + EN_REPRAPWORLD_KEYPAD_UP | \ + EN_REPRAPWORLD_KEYPAD_LEFT) \ + ) + + #define LCD_CLICKED ((buttons & EN_C) || (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_F1)) + #elif ENABLED(NEWPANEL) + #define LCD_CLICKED (buttons & EN_C) + #endif + +#else //no LCD + FORCE_INLINE void lcd_update() {} + FORCE_INLINE void lcd_init() {} + FORCE_INLINE bool lcd_hasstatus() { return false; } + FORCE_INLINE void lcd_setstatus(const char* message, const bool persist=false) {UNUSED(message); UNUSED(persist);} + FORCE_INLINE void lcd_setstatuspgm(const char* message, const uint8_t level=0) {UNUSED(message); UNUSED(level);} + FORCE_INLINE void lcd_buttons_update() {} + FORCE_INLINE void lcd_reset_alert_level() {} + FORCE_INLINE bool lcd_detected(void) { return true; } + + #define LCD_MESSAGEPGM(x) NOOP + #define LCD_ALERTMESSAGEPGM(x) NOOP + +#endif //ULTRA_LCD + +char* itostr2(const uint8_t& x); +char* itostr3sign(const int& x); +char* itostr3(const int& x); +char* itostr3left(const int& x); +char* itostr4sign(const int& x); + +char* ftostr3(const float& x); +char* ftostr4sign(const float& x); +char* ftostr41sign(const float& x); +char* ftostr32(const float& x); +char* ftostr43sign(const float& x, char plus=' '); +char* ftostr12ns(const float& x); +char* ftostr5rj(const float& x); +char* ftostr51sign(const float& x); +char* ftostr52sign(const float& x); +char* ftostr52sp(const float& x); // remove zero-padding from ftostr32 + +#endif //ULTRALCD_H diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/ultralcd_impl_DOGM.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/ultralcd_impl_DOGM.h new file mode 100644 index 00000000..f8ffd4db --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/ultralcd_impl_DOGM.h @@ -0,0 +1,634 @@ +/** + * 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 . + * + */ + +/** + * ultralcd_impl_DOGM.h + * + * Graphics LCD implementation for 128x64 pixel LCDs by STB for ErikZalm/Marlin + * Demonstrator: http://www.reprap.org/wiki/STB_Electronics + * License: http://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 + */ + +#ifndef ULTRALCD_IMPL_DOGM_H +#define ULTRALCD_IMPL_DOGM_H + +#include "MarlinConfig.h" + +/** + * Implementation of the LCD display routines for a DOGM128 graphic display. + * These are common LCD 128x64 pixel graphic displays. + */ +#include "ultralcd.h" +#include "ultralcd_st7920_u8glib_rrd.h" +#include "dogm_bitmaps.h" +#include "duration_t.h" + +#include + +#if ENABLED(SHOW_BOOTSCREEN) && ENABLED(SHOW_CUSTOM_BOOTSCREEN) + #include "_Bootscreen.h" +#endif + +#if DISABLED(MAPPER_C2C3) && DISABLED(MAPPER_NON) && ENABLED(USE_BIG_EDIT_FONT) + #undef USE_BIG_EDIT_FONT +#endif + +#if ENABLED(USE_SMALL_INFOFONT) + #include "dogm_font_data_6x9_marlin.h" + #define FONT_STATUSMENU_NAME u8g_font_6x9 +#else + #define FONT_STATUSMENU_NAME FONT_MENU_NAME +#endif + +#include "dogm_font_data_Marlin_symbols.h" // The Marlin special symbols +#define FONT_SPECIAL_NAME Marlin_symbols + +#if DISABLED(SIMULATE_ROMFONT) + #if ENABLED(DISPLAY_CHARSET_ISO10646_1) + #include "dogm_font_data_ISO10646_1.h" + #define FONT_MENU_NAME ISO10646_1_5x7 + #elif ENABLED(DISPLAY_CHARSET_ISO10646_5) + #include "dogm_font_data_ISO10646_5_Cyrillic.h" + #define FONT_MENU_NAME ISO10646_5_Cyrillic_5x7 + #elif ENABLED(DISPLAY_CHARSET_ISO10646_KANA) + #include "dogm_font_data_ISO10646_Kana.h" + #define FONT_MENU_NAME ISO10646_Kana_5x7 + #elif ENABLED(DISPLAY_CHARSET_ISO10646_GREEK) + #include "dogm_font_data_ISO10646_Greek.h" + #define FONT_MENU_NAME ISO10646_Greek_5x7 + #elif ENABLED(DISPLAY_CHARSET_ISO10646_CN) + #include "dogm_font_data_ISO10646_CN.h" + #define FONT_MENU_NAME ISO10646_CN + #define TALL_FONT_CORRECTION 1 + #else // fall-back + #include "dogm_font_data_ISO10646_1.h" + #define FONT_MENU_NAME ISO10646_1_5x7 + #endif +#else // SIMULATE_ROMFONT + #if DISPLAY_CHARSET_HD44780 == JAPANESE + #include "dogm_font_data_HD44780_J.h" + #define FONT_MENU_NAME HD44780_J_5x7 + #elif DISPLAY_CHARSET_HD44780 == WESTERN + #include "dogm_font_data_HD44780_W.h" + #define FONT_MENU_NAME HD44780_W_5x7 + #elif DISPLAY_CHARSET_HD44780 == CYRILLIC + #include "dogm_font_data_HD44780_C.h" + #define FONT_MENU_NAME HD44780_C_5x7 + #else // fall-back + #include "dogm_font_data_ISO10646_1.h" + #define FONT_MENU_NAME ISO10646_1_5x7 + #endif +#endif // SIMULATE_ROMFONT + +//#define FONT_STATUSMENU_NAME FONT_MENU_NAME + +#define FONT_STATUSMENU 1 +#define FONT_SPECIAL 2 +#define FONT_MENU_EDIT 3 +#define FONT_MENU 4 + +// DOGM parameters (size in pixels) +#define DOG_CHAR_WIDTH 6 +#define DOG_CHAR_HEIGHT 12 +#if ENABLED(USE_BIG_EDIT_FONT) + #define FONT_MENU_EDIT_NAME u8g_font_9x18 + #define DOG_CHAR_WIDTH_EDIT 9 + #define DOG_CHAR_HEIGHT_EDIT 18 + #define LCD_WIDTH_EDIT 14 +#else + #define FONT_MENU_EDIT_NAME FONT_MENU_NAME + #define DOG_CHAR_WIDTH_EDIT 6 + #define DOG_CHAR_HEIGHT_EDIT 12 + #define LCD_WIDTH_EDIT 22 +#endif + +#ifndef TALL_FONT_CORRECTION + #define TALL_FONT_CORRECTION 0 +#endif + +#define START_COL 0 + +// LCD selection +#if ENABLED(REPRAPWORLD_GRAPHICAL_LCD) + U8GLIB_ST7920_128X64_4X u8g(LCD_PINS_RS); +#elif ENABLED(U8GLIB_ST7920) + //U8GLIB_ST7920_128X64_RRD u8g(0,0,0); + U8GLIB_ST7920_128X64_RRD u8g(0); +#elif ENABLED(CARTESIO_UI) + // The CartesioUI display + #if DOGLCD_MOSI != -1 && DOGLCD_SCK != -1 + // using SW-SPI + U8GLIB_DOGM128 u8g(DOGLCD_SCK, DOGLCD_MOSI, DOGLCD_CS, DOGLCD_A0); + #else + U8GLIB_DOGM128 u8g(DOGLCD_CS, DOGLCD_A0); + #endif +#elif ENABLED(U8GLIB_LM6059_AF) + // Based on the Adafruit ST7565 (http://www.adafruit.com/products/250) + U8GLIB_LM6059 u8g(DOGLCD_CS, DOGLCD_A0); +#elif ENABLED(MAKRPANEL) || ENABLED(VIKI2) || ENABLED(miniVIKI) + // The MaKrPanel, Mini Viki, and Viki 2.0, ST7565 controller as well + U8GLIB_NHD_C12864 u8g(DOGLCD_CS, DOGLCD_A0); +#elif ENABLED(U8GLIB_SSD1306) + // Generic support for SSD1306 OLED I2C LCDs + U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE | U8G_I2C_OPT_FAST); +#elif ENABLED(U8GLIB_SH1106) + // Generic support for SH1106 OLED I2C LCDs + U8GLIB_SH1106_128X64 u8g(U8G_I2C_OPT_NONE | U8G_I2C_OPT_FAST); +#elif ENABLED(MINIPANEL) + // The MINIPanel display + U8GLIB_MINI12864 u8g(DOGLCD_CS, DOGLCD_A0); +#else + // for regular DOGM128 display with HW-SPI + U8GLIB_DOGM128 u8g(DOGLCD_CS, DOGLCD_A0); // HW-SPI Com: CS, A0 +#endif + +#ifndef LCD_PIXEL_WIDTH + #define LCD_PIXEL_WIDTH 128 +#endif +#ifndef LCD_PIXEL_HEIGHT + #define LCD_PIXEL_HEIGHT 64 +#endif + +#include "utf_mapper.h" + +int lcd_contrast; +static char currentfont = 0; + +static void lcd_setFont(char font_nr) { + switch(font_nr) { + case FONT_STATUSMENU : {u8g.setFont(FONT_STATUSMENU_NAME); currentfont = FONT_STATUSMENU;}; break; + case FONT_MENU : {u8g.setFont(FONT_MENU_NAME); currentfont = FONT_MENU;}; break; + case FONT_SPECIAL : {u8g.setFont(FONT_SPECIAL_NAME); currentfont = FONT_SPECIAL;}; break; + case FONT_MENU_EDIT : {u8g.setFont(FONT_MENU_EDIT_NAME); currentfont = FONT_MENU_EDIT;}; break; + break; + } +} + +char lcd_print(char c) { + if ((c > 0) && (c <= LCD_STR_SPECIAL_MAX)) { + u8g.setFont(FONT_SPECIAL_NAME); + u8g.print(c); + lcd_setFont(currentfont); + return 1; + } else { + return charset_mapper(c); + } +} + +char lcd_print(const char* str) { + char c; + int i = 0; + char n = 0; + while ((c = str[i++])) { + n += lcd_print(c); + } + return n; +} + +/* Arduino < 1.0.0 is missing a function to print PROGMEM strings, so we need to implement our own */ +char lcd_printPGM(const char* str) { + char c; + char n = 0; + while ((c = pgm_read_byte(str++))) { + n += lcd_print(c); + } + return n; +} + +/* Warning: This function is called from interrupt context */ +static void lcd_implementation_init() { + + #if defined(LCD_PIN_BL) && LCD_PIN_BL > -1 // Enable LCD backlight + pinMode(LCD_PIN_BL, OUTPUT); + digitalWrite(LCD_PIN_BL, HIGH); + #endif + + #if defined(LCD_PIN_RESET) && LCD_PIN_RESET > -1 + pinMode(LCD_PIN_RESET, OUTPUT); + digitalWrite(LCD_PIN_RESET, HIGH); + #endif + + #if DISABLED(MINIPANEL) // setContrast not working for Mini Panel + u8g.setContrast(lcd_contrast); + #endif + + #if ENABLED(LCD_SCREEN_ROT_90) + u8g.setRot90(); // Rotate screen by 90° + #elif ENABLED(LCD_SCREEN_ROT_180) + u8g.setRot180(); // Rotate screen by 180° + #elif ENABLED(LCD_SCREEN_ROT_270) + u8g.setRot270(); // Rotate screen by 270° + #endif + + #if ENABLED(SHOW_BOOTSCREEN) + static bool show_bootscreen = true; + + #if ENABLED(SHOW_CUSTOM_BOOTSCREEN) + if (show_bootscreen) { + u8g.firstPage(); + do { + u8g.drawBitmapP( + (128 - (CUSTOM_BOOTSCREEN_BMPWIDTH)) /2, + ( 64 - (CUSTOM_BOOTSCREEN_BMPHEIGHT)) /2, + CEILING(CUSTOM_BOOTSCREEN_BMPWIDTH, 8), CUSTOM_BOOTSCREEN_BMPHEIGHT, custom_start_bmp); + } while (u8g.nextPage()); + safe_delay(CUSTOM_BOOTSCREEN_TIMEOUT); + } + #endif // SHOW_CUSTOM_BOOTSCREEN + + int offx = (u8g.getWidth() - (START_BMPWIDTH)) / 2; + + #if ENABLED(START_BMPHIGH) + int offy = 0; + #else + int offy = DOG_CHAR_HEIGHT; + #endif + + int txt1X = (u8g.getWidth() - (sizeof(STRING_SPLASH_LINE1) - 1) * (DOG_CHAR_WIDTH)) / 2; + + if (show_bootscreen) { + u8g.firstPage(); + do { + u8g.drawBitmapP(offx, offy, START_BMPBYTEWIDTH, START_BMPHEIGHT, start_bmp); + lcd_setFont(FONT_MENU); + #ifndef STRING_SPLASH_LINE2 + u8g.drawStr(txt1X, u8g.getHeight() - (DOG_CHAR_HEIGHT), STRING_SPLASH_LINE1); + #else + int txt2X = (u8g.getWidth() - (sizeof(STRING_SPLASH_LINE2) - 1) * (DOG_CHAR_WIDTH)) / 2; + u8g.drawStr(txt1X, u8g.getHeight() - (DOG_CHAR_HEIGHT) * 3 / 2, STRING_SPLASH_LINE1); + u8g.drawStr(txt2X, u8g.getHeight() - (DOG_CHAR_HEIGHT) * 1 / 2, STRING_SPLASH_LINE2); + #endif + } while (u8g.nextPage()); + } + + show_bootscreen = false; + + #endif // SHOW_BOOTSCREEN +} + +void lcd_kill_screen() { + lcd_setFont(FONT_MENU); + u8g.setPrintPos(0, u8g.getHeight()/4*1); + lcd_print(lcd_status_message); + u8g.setPrintPos(0, u8g.getHeight()/4*2); + lcd_printPGM(PSTR(MSG_HALTED)); + u8g.setPrintPos(0, u8g.getHeight()/4*3); + lcd_printPGM(PSTR(MSG_PLEASE_RESET)); +} + +static void lcd_implementation_clear() { } // Automatically cleared by Picture Loop + +FORCE_INLINE void _draw_centered_temp(int temp, int x, int y) { + int degsize = 6 * (temp >= 100 ? 3 : temp >= 10 ? 2 : 1); // number's pixel width + u8g.setPrintPos(x - (18 - degsize) / 2, y); // move left if shorter + lcd_print(itostr3(temp)); + lcd_printPGM(PSTR(LCD_STR_DEGREE " ")); +} + +FORCE_INLINE void _draw_heater_status(int x, int heater) { + #if HAS_TEMP_BED + bool isBed = heater < 0; + #else + const bool isBed = false; + #endif + + _draw_centered_temp((isBed ? thermalManager.degTargetBed() : thermalManager.degTargetHotend(heater)) + 0.5, x, 7); + + _draw_centered_temp((isBed ? thermalManager.degBed() : thermalManager.degHotend(heater)) + 0.5, x, 28); + + int h = isBed ? 7 : 8, + y = isBed ? 18 : 17; + if (isBed ? thermalManager.isHeatingBed() : thermalManager.isHeatingHotend(heater)) { + u8g.setColorIndex(0); // white on black + u8g.drawBox(x + h, y, 2, 2); + u8g.setColorIndex(1); // black on white + } + else { + u8g.drawBox(x + h, y, 2, 2); + } +} + +FORCE_INLINE void _draw_axis_label(AxisEnum axis, const char *pstr, bool blink) { + if (blink) + lcd_printPGM(pstr); + else { + if (!axis_homed[axis]) + lcd_printPGM(PSTR("?")); + else { + #if DISABLED(DISABLE_REDUCED_ACCURACY_WARNING) + if (!axis_known_position[axis]) + lcd_printPGM(PSTR(" ")); + else + #endif + lcd_printPGM(pstr); + } + } +} + +static void lcd_implementation_status_screen() { + u8g.setColorIndex(1); // black on white + + bool blink = lcd_blink(); + + // Symbols menu graphics, animated fan + u8g.drawBitmapP(9, 1, STATUS_SCREENBYTEWIDTH, STATUS_SCREENHEIGHT, + #if HAS_FAN0 + blink && fanSpeeds[0] ? status_screen0_bmp : status_screen1_bmp + #else + status_screen0_bmp + #endif + ); + + // Status Menu Font for SD info, Heater status, Fan, XYZ + lcd_setFont(FONT_STATUSMENU); + + #if ENABLED(SDSUPPORT) + // SD Card Symbol + u8g.drawBox(42, 42 - (TALL_FONT_CORRECTION), 8, 7); + u8g.drawBox(50, 44 - (TALL_FONT_CORRECTION), 2, 5); + u8g.drawFrame(42, 49 - (TALL_FONT_CORRECTION), 10, 4); + u8g.drawPixel(50, 43 - (TALL_FONT_CORRECTION)); + + // Progress bar frame + u8g.drawFrame(54, 49, 73, 4 - (TALL_FONT_CORRECTION)); + + // SD Card Progress bar and clock + if (IS_SD_PRINTING) { + // Progress bar solid part + u8g.drawBox(55, 50, (unsigned int)(71 * card.percentDone() * 0.01), 2 - (TALL_FONT_CORRECTION)); + } + + u8g.setPrintPos(80,48); + + char buffer[10]; + duration_t elapsed = print_job_timer.duration(); + elapsed.toDigital(buffer); + lcd_print(buffer); + + #endif + + // Extruders + HOTEND_LOOP() _draw_heater_status(5 + e * 25, e); + + // Heated bed + #if HOTENDS < 4 && HAS_TEMP_BED + _draw_heater_status(81, -1); + #endif + + // Fan + u8g.setPrintPos(104, 27); + #if HAS_FAN0 + int per = ((fanSpeeds[0] + 1) * 100) / 256; + if (per) { + lcd_print(itostr3(per)); + lcd_print('%'); + } + #endif + + // X, Y, Z-Coordinates + // Before homing the axis letters are blinking 'X' <-> '?'. + // When axis is homed but axis_known_position is false the axis letters are blinking 'X' <-> ' '. + // When everything is ok you see a constant 'X'. + #define XYZ_BASELINE 38 + + #if ENABLED(USE_SMALL_INFOFONT) + u8g.drawBox(0, 30, LCD_PIXEL_WIDTH, 10); + #else + u8g.drawBox(0, 30, LCD_PIXEL_WIDTH, 9); + #endif + u8g.setColorIndex(0); // white on black + + u8g.setPrintPos(2, XYZ_BASELINE); + _draw_axis_label(X_AXIS, PSTR(MSG_X), blink); + u8g.setPrintPos(10, XYZ_BASELINE); + lcd_print(ftostr4sign(current_position[X_AXIS])); + + u8g.setPrintPos(43, XYZ_BASELINE); + _draw_axis_label(Y_AXIS, PSTR(MSG_Y), blink); + u8g.setPrintPos(51, XYZ_BASELINE); + lcd_print(ftostr4sign(current_position[Y_AXIS])); + + u8g.setPrintPos(83, XYZ_BASELINE); + _draw_axis_label(Z_AXIS, PSTR(MSG_Z), blink); + u8g.setPrintPos(91, XYZ_BASELINE); + lcd_print(ftostr52sp(current_position[Z_AXIS] + 0.00001)); + + u8g.setColorIndex(1); // black on white + + // Feedrate + lcd_setFont(FONT_MENU); + u8g.setPrintPos(3, 49); + lcd_print(LCD_STR_FEEDRATE[0]); + + lcd_setFont(FONT_STATUSMENU); + u8g.setPrintPos(12, 49); + lcd_print(itostr3(feedrate_percentage)); + lcd_print('%'); + + // Status line + #if ENABLED(USE_SMALL_INFOFONT) + u8g.setPrintPos(0, 62); + #else + u8g.setPrintPos(0, 63); + #endif + #if DISABLED(FILAMENT_LCD_DISPLAY) + lcd_print(lcd_status_message); + #else + if (PENDING(millis(), previous_lcd_status_ms + 5000UL)) { //Display both Status message line and Filament display on the last line + lcd_print(lcd_status_message); + } + else { + lcd_printPGM(PSTR("dia:")); + lcd_print(ftostr12ns(filament_width_meas)); + lcd_printPGM(PSTR(" factor:")); + lcd_print(itostr3(100.0 * volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM])); + lcd_print('%'); + } + #endif +} + +static void lcd_implementation_mark_as_selected(uint8_t row, bool isSelected) { + if (isSelected) { + u8g.setColorIndex(1); // black on white + u8g.drawBox(0, row * (DOG_CHAR_HEIGHT) + 3 - (TALL_FONT_CORRECTION), LCD_PIXEL_WIDTH, DOG_CHAR_HEIGHT); + u8g.setColorIndex(0); // following text must be white on black + } + else { + u8g.setColorIndex(1); // unmarked text is black on white + } + u8g.setPrintPos((START_COL) * (DOG_CHAR_WIDTH), (row + 1) * (DOG_CHAR_HEIGHT)); +} + +#if ENABLED(LCD_INFO_MENU) || ENABLED(FILAMENT_CHANGE_FEATURE) + + static void lcd_implementation_drawmenu_static(uint8_t row, const char* pstr, bool center=true, bool invert=false, const char* valstr=NULL) { + + lcd_implementation_mark_as_selected(row, invert); + + char c; + int8_t n = LCD_WIDTH - (START_COL); + + if (center && !valstr) { + int8_t pad = (LCD_WIDTH - lcd_strlen_P(pstr)) / 2; + while (--pad >= 0) { lcd_print(' '); n--; } + } + while (n > 0 && (c = pgm_read_byte(pstr))) { + n -= lcd_print(c); + pstr++; + } + if (valstr) while (n > 0 && (c = *valstr)) { + n -= lcd_print(c); + valstr++; + } + while (n-- > 0) lcd_print(' '); + } + +#endif // LCD_INFO_MENU || FILAMENT_CHANGE_FEATURE + +static void lcd_implementation_drawmenu_generic(bool isSelected, uint8_t row, const char* pstr, char pre_char, char post_char) { + UNUSED(pre_char); + + char c; + uint8_t n = LCD_WIDTH - (START_COL) - 2; + + lcd_implementation_mark_as_selected(row, isSelected); + + while (c = pgm_read_byte(pstr)) { + n -= lcd_print(c); + pstr++; + } + while (n--) lcd_print(' '); + u8g.setPrintPos(LCD_PIXEL_WIDTH - (DOG_CHAR_WIDTH), (row + 1) * (DOG_CHAR_HEIGHT)); + lcd_print(post_char); + lcd_print(' '); +} + +static void _drawmenu_setting_edit_generic(bool isSelected, uint8_t row, const char* pstr, const char* data, bool pgm) { + char c; + uint8_t vallen = (pgm ? lcd_strlen_P(data) : (lcd_strlen((char*)data))); + uint8_t n = LCD_WIDTH - (START_COL) - 2 - vallen; + + lcd_implementation_mark_as_selected(row, isSelected); + + while (c = pgm_read_byte(pstr)) { + n -= lcd_print(c); + pstr++; + } + lcd_print(':'); + while (n--) lcd_print(' '); + u8g.setPrintPos(LCD_PIXEL_WIDTH - (DOG_CHAR_WIDTH) * vallen, (row + 1) * (DOG_CHAR_HEIGHT)); + if (pgm) lcd_printPGM(data); else lcd_print((char*)data); +} + +#define lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, data) _drawmenu_setting_edit_generic(sel, row, pstr, data, false) +#define lcd_implementation_drawmenu_setting_edit_generic_P(sel, row, pstr, data) _drawmenu_setting_edit_generic(sel, row, pstr, data, true) + +#define lcd_implementation_drawmenu_setting_edit_int3(sel, row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, itostr3(*(data))) +#define lcd_implementation_drawmenu_setting_edit_float3(sel, row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ftostr3(*(data))) +#define lcd_implementation_drawmenu_setting_edit_float32(sel, row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ftostr32(*(data))) +#define lcd_implementation_drawmenu_setting_edit_float43(sel, row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ftostr43sign(*(data))) +#define lcd_implementation_drawmenu_setting_edit_float5(sel, row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ftostr5rj(*(data))) +#define lcd_implementation_drawmenu_setting_edit_float52(sel, row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ftostr52sign(*(data))) +#define lcd_implementation_drawmenu_setting_edit_float51(sel, row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ftostr51sign(*(data))) +#define lcd_implementation_drawmenu_setting_edit_long5(sel, row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ftostr5rj(*(data))) +#define lcd_implementation_drawmenu_setting_edit_bool(sel, row, pstr, pstr2, data) lcd_implementation_drawmenu_setting_edit_generic_P(sel, row, pstr, (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF)) + +//Add version for callback functions +#define lcd_implementation_drawmenu_setting_edit_callback_int3(sel, row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, itostr3(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_float3(sel, row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ftostr3(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_float32(sel, row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ftostr32(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_float43(sel, row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ftostr43sign(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_float5(sel, row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ftostr5rj(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_float52(sel, row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ftostr52sign(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_float51(sel, row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ftostr51sign(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_long5(sel, row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ftostr5rj(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_bool(sel, row, pstr, pstr2, data, callback) lcd_implementation_drawmenu_setting_edit_generic_P(sel, row, pstr, (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF)) + +void lcd_implementation_drawedit(const char* pstr, const char* value=NULL) { + uint8_t rows = 1; + uint8_t lcd_width = LCD_WIDTH - (START_COL), char_width = DOG_CHAR_WIDTH; + uint8_t vallen = lcd_strlen(value); + + #if ENABLED(USE_BIG_EDIT_FONT) + if (lcd_strlen_P(pstr) <= LCD_WIDTH_EDIT - 1) { + lcd_setFont(FONT_MENU_EDIT); + lcd_width = LCD_WIDTH_EDIT + 1; + char_width = DOG_CHAR_WIDTH_EDIT; + if (lcd_strlen_P(pstr) >= LCD_WIDTH_EDIT - vallen) rows = 2; + } + else { + lcd_setFont(FONT_MENU); + } + #endif + + if (lcd_strlen_P(pstr) > LCD_WIDTH - 2 - vallen) rows = 2; + + const float kHalfChar = (DOG_CHAR_HEIGHT_EDIT) / 2; + float rowHeight = u8g.getHeight() / (rows + 1); // 1/(rows+1) = 1/2 or 1/3 + + u8g.setPrintPos(0, rowHeight + kHalfChar); + lcd_printPGM(pstr); + if (value != NULL) { + lcd_print(':'); + u8g.setPrintPos((lcd_width - 1 - vallen) * char_width, rows * rowHeight + kHalfChar); + lcd_print(value); + } +} + +#if ENABLED(SDSUPPORT) + + static void _drawmenu_sd(bool isSelected, uint8_t row, const char* pstr, const char* filename, char* const longFilename, bool isDir) { + UNUSED(pstr); + char c; + uint8_t n = LCD_WIDTH - (START_COL) - 1; + + if (longFilename[0]) { + filename = longFilename; + longFilename[n] = '\0'; + } + + lcd_implementation_mark_as_selected(row, isSelected); + + if (isDir) lcd_print(LCD_STR_FOLDER[0]); + while ((c = *filename)) { + n -= lcd_print(c); + filename++; + } + while (n--) lcd_print(' '); + } + + #define lcd_implementation_drawmenu_sdfile(sel, row, pstr, filename, longFilename) _drawmenu_sd(sel, row, pstr, filename, longFilename, false) + #define lcd_implementation_drawmenu_sddirectory(sel, row, pstr, filename, longFilename) _drawmenu_sd(sel, row, pstr, filename, longFilename, true) + +#endif //SDSUPPORT + +#define lcd_implementation_drawmenu_back(sel, row, pstr) lcd_implementation_drawmenu_generic(sel, row, pstr, LCD_STR_UPLEVEL[0], LCD_STR_UPLEVEL[0]) +#define lcd_implementation_drawmenu_submenu(sel, row, pstr, data) lcd_implementation_drawmenu_generic(sel, row, pstr, '>', LCD_STR_ARROW_RIGHT[0]) +#define lcd_implementation_drawmenu_gcode(sel, row, pstr, gcode) lcd_implementation_drawmenu_generic(sel, row, pstr, '>', ' ') +#define lcd_implementation_drawmenu_function(sel, row, pstr, data) lcd_implementation_drawmenu_generic(sel, row, pstr, '>', ' ') + +#endif //__ULTRALCD_IMPL_DOGM_H diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/ultralcd_impl_HD44780.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/ultralcd_impl_HD44780.h new file mode 100644 index 00000000..efbc67fe --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/ultralcd_impl_HD44780.h @@ -0,0 +1,1115 @@ +/** + * 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 . + * + */ + +#ifndef ULTRALCD_IMPL_HD44780_H +#define ULTRALCD_IMPL_HD44780_H + +/** +* Implementation of the LCD display routines for a Hitachi HD44780 display. These are common LCD character displays. +**/ + +#include "duration_t.h" + +extern volatile uint8_t buttons; //an extended version of the last checked buttons in a bit array. + +//////////////////////////////////// +// 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. + +#if ENABLED(ULTIPANEL) + + // + // Setup other button mappings of each panel + // + #if ENABLED(LCD_I2C_VIKI) + #define B_I2C_BTN_OFFSET 3 // (the first three bit positions reserved for EN_A, EN_B, EN_C) + + // button and encoder bit positions within 'buttons' + #define B_LE (BUTTON_LEFT< + #include + #include + #define LCD_CLASS LiquidCrystal_I2C + LCD_CLASS lcd(LCD_I2C_ADDRESS, LCD_I2C_PIN_EN, LCD_I2C_PIN_RW, LCD_I2C_PIN_RS, LCD_I2C_PIN_D4, LCD_I2C_PIN_D5, LCD_I2C_PIN_D6, LCD_I2C_PIN_D7); + +#elif ENABLED(LCD_I2C_TYPE_MCP23017) + //for the LED indicators (which maybe mapped to different things in lcd_implementation_update_indicators()) + #define LED_A 0x04 //100 + #define LED_B 0x02 //010 + #define LED_C 0x01 //001 + + #define LCD_HAS_STATUS_INDICATORS + + #include + #include + #define LCD_CLASS LiquidTWI2 + #if ENABLED(DETECT_DEVICE) + LCD_CLASS lcd(LCD_I2C_ADDRESS, 1); + #else + LCD_CLASS lcd(LCD_I2C_ADDRESS); + #endif + +#elif ENABLED(LCD_I2C_TYPE_MCP23008) + #include + #include + #define LCD_CLASS LiquidTWI2 + #if ENABLED(DETECT_DEVICE) + LCD_CLASS lcd(LCD_I2C_ADDRESS, 1); + #else + LCD_CLASS lcd(LCD_I2C_ADDRESS); + #endif + +#elif ENABLED(LCD_I2C_TYPE_PCA8574) + #include + #define LCD_CLASS LiquidCrystal_I2C + LCD_CLASS lcd(LCD_I2C_ADDRESS, LCD_WIDTH, LCD_HEIGHT); + +// 2 wire Non-latching LCD SR from: +// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/schematics#!shiftregister-connection +#elif ENABLED(SR_LCD_2W_NL) + extern "C" void __cxa_pure_virtual() { while (1); } + #include + #include + #define LCD_CLASS LiquidCrystal_SR + LCD_CLASS lcd(SR_DATA_PIN, SR_CLK_PIN); +#elif ENABLED(LCM1602) + #include + #include + #include + #define LCD_CLASS LiquidCrystal_I2C + LCD_CLASS lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); +#else + // Standard directly connected LCD implementations + #include + #define LCD_CLASS LiquidCrystal + LCD_CLASS lcd(LCD_PINS_RS, LCD_PINS_ENABLE, LCD_PINS_D4, LCD_PINS_D5, LCD_PINS_D6, LCD_PINS_D7); //RS,Enable,D4,D5,D6,D7 +#endif + +#include "utf_mapper.h" + +#if ENABLED(LCD_PROGRESS_BAR) + static millis_t progress_bar_ms = 0; + #if PROGRESS_MSG_EXPIRE > 0 + static millis_t expire_status_ms = 0; + #endif + #define LCD_STR_PROGRESS "\x03\x04\x05" +#endif + +#if ENABLED(LCD_HAS_STATUS_INDICATORS) + static void lcd_implementation_update_indicators(); +#endif + +static void lcd_set_custom_characters( + #if ENABLED(LCD_PROGRESS_BAR) + bool progress_bar_set = true + #endif +) { + byte bedTemp[8] = { + B00000, + B11111, + B10101, + B10001, + B10101, + B11111, + B00000, + B00000 + }; //thanks Sonny Mounicou + byte degree[8] = { + B01100, + B10010, + B10010, + B01100, + B00000, + B00000, + B00000, + B00000 + }; + byte thermometer[8] = { + B00100, + B01010, + B01010, + B01010, + B01010, + B10001, + B10001, + B01110 + }; + byte uplevel[8] = { + B00100, + B01110, + B11111, + B00100, + B11100, + B00000, + B00000, + B00000 + }; //thanks joris + byte refresh[8] = { + B00000, + B00110, + B11001, + B11000, + B00011, + B10011, + B01100, + B00000, + }; //thanks joris + byte folder[8] = { + B00000, + B11100, + B11111, + B10001, + B10001, + B11111, + B00000, + B00000 + }; //thanks joris + byte feedrate[8] = { + B11100, + B10000, + B11000, + B10111, + B00101, + B00110, + B00101, + B00000 + }; //thanks Sonny Mounicou + byte clock[8] = { + B00000, + B01110, + B10011, + B10101, + B10001, + B01110, + B00000, + B00000 + }; //thanks Sonny Mounicou + + #if ENABLED(LCD_PROGRESS_BAR) + static bool char_mode = false; + byte progress[3][8] = { { + B00000, + B10000, + B10000, + B10000, + B10000, + B10000, + B10000, + B00000 + }, { + B00000, + B10100, + B10100, + B10100, + B10100, + B10100, + B10100, + B00000 + }, { + B00000, + B10101, + B10101, + B10101, + B10101, + B10101, + B10101, + B00000 + } }; + if (progress_bar_set != char_mode) { + char_mode = progress_bar_set; + lcd.createChar(LCD_STR_BEDTEMP[0], bedTemp); + lcd.createChar(LCD_STR_DEGREE[0], degree); + lcd.createChar(LCD_STR_THERMOMETER[0], thermometer); + lcd.createChar(LCD_STR_FEEDRATE[0], feedrate); + lcd.createChar(LCD_STR_CLOCK[0], clock); + if (progress_bar_set) { + // Progress bar characters for info screen + for (int i = 3; i--;) lcd.createChar(LCD_STR_PROGRESS[i], progress[i]); + } + else { + // Custom characters for submenus + lcd.createChar(LCD_STR_UPLEVEL[0], uplevel); + lcd.createChar(LCD_STR_REFRESH[0], refresh); + lcd.createChar(LCD_STR_FOLDER[0], folder); + } + } + #else + lcd.createChar(LCD_STR_BEDTEMP[0], bedTemp); + lcd.createChar(LCD_STR_DEGREE[0], degree); + lcd.createChar(LCD_STR_THERMOMETER[0], thermometer); + lcd.createChar(LCD_STR_UPLEVEL[0], uplevel); + lcd.createChar(LCD_STR_REFRESH[0], refresh); + lcd.createChar(LCD_STR_FOLDER[0], folder); + lcd.createChar(LCD_STR_FEEDRATE[0], feedrate); + lcd.createChar(LCD_STR_CLOCK[0], clock); + #endif +} + +static void lcd_implementation_init( + #if ENABLED(LCD_PROGRESS_BAR) + bool progress_bar_set = true + #endif +) { + + #if ENABLED(LCD_I2C_TYPE_PCF8575) + lcd.begin(LCD_WIDTH, LCD_HEIGHT); + #ifdef LCD_I2C_PIN_BL + lcd.setBacklightPin(LCD_I2C_PIN_BL, POSITIVE); + lcd.setBacklight(HIGH); + #endif + + #elif ENABLED(LCD_I2C_TYPE_MCP23017) + lcd.setMCPType(LTI_TYPE_MCP23017); + lcd.begin(LCD_WIDTH, LCD_HEIGHT); + lcd_implementation_update_indicators(); + + #elif ENABLED(LCD_I2C_TYPE_MCP23008) + lcd.setMCPType(LTI_TYPE_MCP23008); + lcd.begin(LCD_WIDTH, LCD_HEIGHT); + + #elif ENABLED(LCD_I2C_TYPE_PCA8574) + lcd.init(); + lcd.backlight(); + + #else + lcd.begin(LCD_WIDTH, LCD_HEIGHT); + #endif + + lcd_set_custom_characters( + #if ENABLED(LCD_PROGRESS_BAR) + progress_bar_set + #endif + ); + + lcd.clear(); +} + +static void lcd_implementation_clear() { lcd.clear(); } + +/* Arduino < 1.0.0 is missing a function to print PROGMEM strings, so we need to implement our own */ +char lcd_printPGM(const char* str) { + char c, n = 0; + while ((c = pgm_read_byte(str++))) n += charset_mapper(c); + return n; +} + +char lcd_print(const char* str) { + char c, n = 0; + unsigned char i = 0; + while ((c = str[i++])) n += charset_mapper(c); + return n; +} + +unsigned lcd_print(char c) { return charset_mapper(c); } + + /*char *logosplash[] = { + "\xff\x20\xff\x20\x20\xff\xff\xff\x20\x20\xff\xff\xff\x20\x20\xff\xff\xff\x20\x20\xff\xff\xff\x20\x20\xff\x20\xff\x20\x20\x20\x20\xff\x20\xff\x20\x20\xff\xff\xff\x20\x20\xff\x20\xff\x20\x20\xff\xff\xff\x20\x20", + "\xff\x20\xff\x20\x20\xff\x03\x03\x20\x20\xff\x20\xff\x20\x20\x20\xff\x20\x20\x20\xff\x03\x03\x20\x20\x20\xff\x20\x20\x20\x20\x20\xff\x01\xff\x20\x20\xff\x20\xff\x20\x20\xff\x01\xff\x20\x20\xff\x20\xff\x20\x20", + "\xff\x20\xff\x20\x20\xff\x04\x04\x20\x20\xff\xff\x20\x20\x20\x20\xff\x20\x20\x20\xff\x04\x04\x20\x20\x20\xff\x20\x20\x20\x20\x20\xff\x02\xff\x20\x20\xff\xff\xff\x20\x20\xff\x02\xff\x20\x20\xff\x20\xff\x20\x20", + "\x20\xff\x20\x20\x20\xff\xff\xff\x20\x20\xff\x20\xff\x20\x20\x20\xff\x20\x20\x20\xff\xff\xff\x20\x20\xff\x20\xff\x20\x20\x20\x20\xff\x20\xff\x20\x20\xff\x20\xff\x20\x20\xff\x20\xff\x20\x20\xff\xff\xff\x20\x20" + }; // original Logo Splash */ + char *logosplash[] = { + "\xff\x20\xff\x20\x20\x20\xff\x20\xff\x20\x20\xff\xff\xff\x20\x20\xff\x20\xff\x20\x20\xff\xff\xff\x20\x20 *** Improved by ***", + "\xff\x20\xff\x20\x03\x20\xff\x01\xff\x20\x20\xff\x20\xff\x20\x20\xff\x01\xff\x20\x20\xff\x20\xff\x20\x20 ** 2018 - Paolo Iocco **", + "\xff\x20\xff\x20\x04\x20\xff\x02\xff\x20\x20\xff\xff\xff\x20\x20\xff\x02\xff\x20\x20\xff\x20\xff\x20\x20 ** and his bright **", + "\x20\xff\x20\x20\x20\x20\xff\x20\xff\x20\x20\xff\x20\xff\x20\x20\xff\x20\xff\x20\x20\xff\xff\xff\x20\x20 *** Family ***" + }; // Modified Logo Splash + +#if ENABLED(SHOW_BOOTSCREEN) + + void lcd_erase_line(int line) { + lcd.setCursor(0, line); + for (int i = 0; i < LCD_WIDTH; i++) + lcd_print(' '); + } + + // Scroll the PSTR 'text' in a 'len' wide field for 'time' milliseconds at position col,line + void lcd_scroll(int col, int line, const char* text, int len, int time) { + char tmp[LCD_WIDTH + 1] = {0}; + int n = max(lcd_strlen_P(text) - len, 0); + for (int i = 0; i <= n; i++) { + strncpy_P(tmp, text + i, min(len, LCD_WIDTH)); + lcd.setCursor(col, line); + lcd_print(tmp); + delay(time / max(n, 1)); + } + } + + static void logo_lines(const char *extra) { + int indent = (LCD_WIDTH - 8 - lcd_strlen_P(extra)) / 2; + lcd.setCursor(indent, 0); lcd.print('\x00'); lcd_printPGM(PSTR( "------" )); lcd.print('\x01'); + lcd.setCursor(indent, 1); lcd_printPGM(PSTR("|Marlin|")); lcd_printPGM(extra); + lcd.setCursor(indent, 2); lcd.print('\x02'); lcd_printPGM(PSTR( "------" )); lcd.print('\x03'); + } + + void bootscreen() { + byte top_left[8] = { + B00000, + B00000, + B00000, + B00000, + B00001, + B00010, + B00100, + B00100 + }; + byte top_right[8] = { + B00000, + B00000, + B00000, + B11100, + B11100, + B01100, + B00100, + B00100 + }; + byte botom_left[8] = { + B00100, + B00010, + B00001, + B00000, + B00000, + B00000, + B00000, + B00000 + }; + byte botom_right[8] = { + B00100, + B01000, + B10000, + B00000, + B00000, + B00000, + B00000, + B00000 + }; + byte half_left[8] = { + B11100, + B11100, + B11100, + B11100, + B11100, + B11100, + B11100, + B11100 + }; + + byte half_right[8] = { + B00111, + B00111, + B00111, + B00111, + B00111, + B00111, + B00111, + B00111 + }; + + byte half_top[8] = { + B11111, + B11111, + B11111, + B11111, + B00000, + B00000, + B00000, + B00000 + }; + + byte half_bottom[8] = { + B00000, + B00000, + B00000, + B00000, + B11111, + B11111, + B11111, + B11111 + }; + lcd.createChar(0, top_left); + lcd.createChar(1, top_right); + lcd.createChar(2, botom_left); + lcd.createChar(3, botom_right); + + lcd.clear(); + + #define LCD_EXTRA_SPACE (LCD_WIDTH-8) + + #define CENTER_OR_SCROLL(STRING,DELAY) \ + lcd_erase_line(3); \ + if (strlen(STRING) <= LCD_WIDTH) { \ + lcd.setCursor((LCD_WIDTH - lcd_strlen_P(PSTR(STRING))) / 2, 3); \ + lcd_printPGM(PSTR(STRING)); \ + safe_delay(DELAY); \ + } \ + else { \ + lcd_scroll(0, 3, PSTR(STRING), LCD_WIDTH, DELAY); \ + } + + #ifdef STRING_SPLASH_LINE1 + // + // Show the Marlin logo with splash line 1 + // + if (LCD_EXTRA_SPACE >= strlen(STRING_SPLASH_LINE1) + 1) { + // + // Show the Marlin logo, splash line1, and splash line 2 + // + logo_lines(PSTR(" " STRING_SPLASH_LINE1)); + #ifdef STRING_SPLASH_LINE2 + CENTER_OR_SCROLL(STRING_SPLASH_LINE2, 2000); + #else + safe_delay(2000); + #endif + } + else { + // + // Show the Marlin logo with splash line 1 + // After a delay show splash line 2, if it exists + // + #ifdef STRING_SPLASH_LINE2 + #define _SPLASH_WAIT_1 1500 + #else + #define _SPLASH_WAIT_1 2000 + #endif + logo_lines(PSTR("")); + CENTER_OR_SCROLL(STRING_SPLASH_LINE1, _SPLASH_WAIT_1); + #ifdef STRING_SPLASH_LINE2 + CENTER_OR_SCROLL(STRING_SPLASH_LINE2, 1500); + #endif + } + #elif defined(STRING_SPLASH_LINE2) + // + // Show splash line 2 only, alongside the logo if possible + // + if (LCD_EXTRA_SPACE >= strlen(STRING_SPLASH_LINE2) + 1) { + logo_lines(PSTR(" " STRING_SPLASH_LINE2)); + safe_delay(2000); + } + else { + logo_lines(PSTR("")); + CENTER_OR_SCROLL(STRING_SPLASH_LINE2, 2000); + } + #else + // + // Show only the Marlin logo + // + logo_lines(PSTR("")); + safe_delay(2000); + #endif + lcd_set_custom_characters( + #if ENABLED(LCD_PROGRESS_BAR) + false + #endif + ); + +//VertexNano Bootscreen// + + lcd.clear(); + + pinMode(BTN_ENC,INPUT); + pinMode(BTN_EN1,INPUT); + pinMode(BTN_EN2,INPUT); + WRITE(BTN_EN1,HIGH); + WRITE(BTN_EN2,HIGH); + WRITE(BTN_ENC,HIGH); + + int width = 20; // screen width + int stp = 2; + int lngth = 52; + + lcd.createChar(1, half_left); + lcd.createChar(2, half_right); + lcd.createChar(3, half_bottom); + lcd.createChar(4, half_top); + + for (int m=width-1; m>=0; m-=stp) { + for (int i=0; i<4; i++) { + String line = logosplash[i]; + lcd.setCursor(m, i); + lcd.print(line.substring(0, width - m)); + } + + lcd.display(); + for (int n=0; n<255; n++) { + safe_delay(1); + thermalManager.manage_heater(); + if((READ(BTN_ENC)==0) || (READ(BTN_EN1)==0) || (READ(BTN_EN2)==0)) + { + goto bailout; + } + } + lcd.noDisplay(); + } + + for (int m=1; m 1 || TEMP_SENSOR_BED != 0 + + lcd.setCursor(8, 0); + #if HOTENDS > 1 + lcd.print(LCD_STR_THERMOMETER[0]); + LCD_TEMP_ONLY(thermalManager.degHotend(1), thermalManager.degTargetHotend(1)); + #else + lcd.print(LCD_STR_BEDTEMP[0]); + LCD_TEMP_ONLY(thermalManager.degBed(), thermalManager.degTargetBed()); + #endif + + #endif // HOTENDS > 1 || TEMP_SENSOR_BED != 0 + + #else // LCD_WIDTH >= 20 + + // + // Hotend 0 Temperature + // + LCD_TEMP(thermalManager.degHotend(0), thermalManager.degTargetHotend(0), LCD_STR_THERMOMETER[0]); + + // + // Hotend 1 or Bed Temperature + // + #if HOTENDS > 1 || TEMP_SENSOR_BED != 0 + lcd.setCursor(10, 0); + #if HOTENDS > 1 + LCD_TEMP(thermalManager.degHotend(1), thermalManager.degTargetHotend(1), LCD_STR_THERMOMETER[0]); + #else + LCD_TEMP(thermalManager.degBed(), thermalManager.degTargetBed(), LCD_STR_BEDTEMP[0]); + #endif + + #endif // HOTENDS > 1 || TEMP_SENSOR_BED != 0 + + #endif // LCD_WIDTH >= 20 + + // + // Line 2 + // + + #if LCD_HEIGHT > 2 + + bool blink = lcd_blink(); + + #if LCD_WIDTH < 20 + + #if ENABLED(SDSUPPORT) + lcd.setCursor(0, 2); + lcd_printPGM(PSTR("SD")); + if (IS_SD_PRINTING) + lcd.print(itostr3(card.percentDone())); + else + lcd_printPGM(PSTR("---")); + lcd.print('%'); + #endif // SDSUPPORT + + #else // LCD_WIDTH >= 20 + + lcd.setCursor(0, 1); + + #if HOTENDS > 1 && TEMP_SENSOR_BED != 0 + + // If we both have a 2nd extruder and a heated bed, + // show the heated bed temp on the left, + // since the first line is filled with extruder temps + LCD_TEMP(thermalManager.degBed(), thermalManager.degTargetBed(), LCD_STR_BEDTEMP[0]); + + #else + // Before homing the axis letters are blinking 'X' <-> '?'. + // When axis is homed but axis_known_position is false the axis letters are blinking 'X' <-> ' '. + // When everything is ok you see a constant 'X'. + + _draw_axis_label(X_AXIS, PSTR(MSG_X), blink); + lcd.print(ftostr4sign(current_position[X_AXIS])); + + lcd_printPGM(PSTR(" ")); + + _draw_axis_label(Y_AXIS, PSTR(MSG_Y), blink); + lcd.print(ftostr4sign(current_position[Y_AXIS])); + + #endif // HOTENDS > 1 || TEMP_SENSOR_BED != 0 + + #endif // LCD_WIDTH >= 20 + + lcd.setCursor(LCD_WIDTH - 8, 1); + _draw_axis_label(Z_AXIS, PSTR(MSG_Z), blink); + lcd.print(ftostr52sp(current_position[Z_AXIS] + 0.00001)); + + #endif // LCD_HEIGHT > 2 + + // + // Line 3 + // + + #if LCD_HEIGHT > 3 + + lcd.setCursor(0, 2); + lcd.print(LCD_STR_FEEDRATE[0]); + lcd.print(itostr3(feedrate_percentage)); + lcd.print('%'); + + #if LCD_WIDTH > 19 && ENABLED(SDSUPPORT) + + lcd.setCursor(7, 2); + lcd_printPGM(PSTR("SD")); + if (IS_SD_PRINTING) + lcd.print(itostr3(card.percentDone())); + else + lcd_printPGM(PSTR("---")); + lcd.print('%'); + + #endif // LCD_WIDTH > 19 && SDSUPPORT + + lcd.setCursor(LCD_WIDTH - 6, 2); + lcd.print(LCD_STR_CLOCK[0]); + + char buffer[10]; + duration_t elapsed = print_job_timer.duration(); + elapsed.toDigital(buffer); + lcd_print(buffer); + + #endif // LCD_HEIGHT > 3 + + // + // Last Line + // Status Message (which may be a Progress Bar or Filament display) + // + + lcd.setCursor(0, LCD_HEIGHT - 1); + + #if ENABLED(LCD_PROGRESS_BAR) + + if (card.isFileOpen()) { + // Draw the progress bar if the message has shown long enough + // or if there is no message set. + if (ELAPSED(millis(), progress_bar_ms + PROGRESS_BAR_MSG_TIME) || !lcd_status_message[0]) { + int tix = (int)(card.percentDone() * (LCD_WIDTH) * 3) / 100, + cel = tix / 3, rem = tix % 3, i = LCD_WIDTH; + char msg[LCD_WIDTH + 1], b = ' '; + msg[i] = '\0'; + while (i--) { + if (i == cel - 1) + b = LCD_STR_PROGRESS[2]; + else if (i == cel && rem != 0) + b = LCD_STR_PROGRESS[rem - 1]; + msg[i] = b; + } + lcd.print(msg); + return; + } + } //card.isFileOpen + + #elif ENABLED(FILAMENT_LCD_DISPLAY) + + // Show Filament Diameter and Volumetric Multiplier % + // After allowing lcd_status_message to show for 5 seconds + if (ELAPSED(millis(), previous_lcd_status_ms + 5000UL)) { + lcd_printPGM(PSTR("Dia ")); + lcd.print(ftostr12ns(filament_width_meas)); + lcd_printPGM(PSTR(" V")); + lcd.print(itostr3(100.0 * volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM])); + lcd.print('%'); + return; + } + + #endif // FILAMENT_LCD_DISPLAY + + lcd_print(lcd_status_message); +} + +#if ENABLED(LCD_INFO_MENU) || ENABLED(FILAMENT_CHANGE_FEATURE) + + static void lcd_implementation_drawmenu_static(uint8_t row, const char* pstr, bool center=true, bool invert=false, const char *valstr=NULL) { + UNUSED(invert); + char c; + int8_t n = LCD_WIDTH; + lcd.setCursor(0, row); + if (center && !valstr) { + int8_t pad = (LCD_WIDTH - lcd_strlen_P(pstr)) / 2; + while (--pad >= 0) { lcd.print(' '); n--; } + } + while (n > 0 && (c = pgm_read_byte(pstr))) { + n -= lcd_print(c); + pstr++; + } + if (valstr) while (n > 0 && (c = *valstr)) { + n -= lcd_print(c); + valstr++; + } + while (n-- > 0) lcd.print(' '); + } + +#endif // LCD_INFO_MENU || FILAMENT_CHANGE_FEATURE + +static void lcd_implementation_drawmenu_generic(bool sel, uint8_t row, const char* pstr, char pre_char, char post_char) { + char c; + uint8_t n = LCD_WIDTH - 2; + lcd.setCursor(0, row); + lcd.print(sel ? pre_char : ' '); + while ((c = pgm_read_byte(pstr)) && n > 0) { + n -= lcd_print(c); + pstr++; + } + while (n--) lcd.print(' '); + lcd.print(post_char); +} + +static void lcd_implementation_drawmenu_setting_edit_generic(bool sel, uint8_t row, const char* pstr, char pre_char, char* data) { + char c; + uint8_t n = LCD_WIDTH - 2 - lcd_strlen(data); + lcd.setCursor(0, row); + lcd.print(sel ? pre_char : ' '); + while ((c = pgm_read_byte(pstr)) && n > 0) { + n -= lcd_print(c); + pstr++; + } + lcd.print(':'); + while (n--) lcd.print(' '); + lcd_print(data); +} +static void lcd_implementation_drawmenu_setting_edit_generic_P(bool sel, uint8_t row, const char* pstr, char pre_char, const char* data) { + char c; + uint8_t n = LCD_WIDTH - 2 - lcd_strlen_P(data); + lcd.setCursor(0, row); + lcd.print(sel ? pre_char : ' '); + while ((c = pgm_read_byte(pstr)) && n > 0) { + n -= lcd_print(c); + pstr++; + } + lcd.print(':'); + while (n--) lcd.print(' '); + lcd_printPGM(data); +} + +#define lcd_implementation_drawmenu_setting_edit_int3(sel, row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, '>', itostr3(*(data))) +#define lcd_implementation_drawmenu_setting_edit_float3(sel, row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, '>', ftostr3(*(data))) +#define lcd_implementation_drawmenu_setting_edit_float32(sel, row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, '>', ftostr32(*(data))) +#define lcd_implementation_drawmenu_setting_edit_float43(sel, row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, '>', ftostr43sign(*(data))) +#define lcd_implementation_drawmenu_setting_edit_float5(sel, row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, '>', ftostr5rj(*(data))) +#define lcd_implementation_drawmenu_setting_edit_float52(sel, row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, '>', ftostr52sign(*(data))) +#define lcd_implementation_drawmenu_setting_edit_float51(sel, row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, '>', ftostr51sign(*(data))) +#define lcd_implementation_drawmenu_setting_edit_long5(sel, row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, '>', ftostr5rj(*(data))) +#define lcd_implementation_drawmenu_setting_edit_bool(sel, row, pstr, pstr2, data) lcd_implementation_drawmenu_setting_edit_generic_P(sel, row, pstr, '>', (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF)) + +//Add version for callback functions +#define lcd_implementation_drawmenu_setting_edit_callback_int3(sel, row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, '>', itostr3(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_float3(sel, row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, '>', ftostr3(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_float32(sel, row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, '>', ftostr32(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_float43(sel, row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, '>', ftostr43sign(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_float5(sel, row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, '>', ftostr5rj(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_float52(sel, row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, '>', ftostr52sign(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_float51(sel, row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, '>', ftostr51sign(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_long5(sel, row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, '>', ftostr5rj(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_bool(sel, row, pstr, pstr2, data, callback) lcd_implementation_drawmenu_setting_edit_generic_P(sel, row, pstr, '>', (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF)) + +void lcd_implementation_drawedit(const char* pstr, const char* value=NULL) { + lcd.setCursor(1, 1); + lcd_printPGM(pstr); + if (value != NULL) { + lcd.print(':'); + lcd.setCursor(LCD_WIDTH - lcd_strlen(value), 1); + lcd_print(value); + } +} + +#if ENABLED(SDSUPPORT) + + static void lcd_implementation_drawmenu_sd(bool sel, uint8_t row, const char* pstr, const char* filename, char* longFilename, uint8_t concat, char post_char) { + UNUSED(pstr); + char c; + uint8_t n = LCD_WIDTH - concat; + lcd.setCursor(0, row); + lcd.print(sel ? '>' : ' '); + if (longFilename[0]) { + filename = longFilename; + longFilename[n] = '\0'; + } + while ((c = *filename) && n > 0) { + n -= lcd_print(c); + filename++; + } + while (n--) lcd.print(' '); + lcd.print(post_char); + } + + static void lcd_implementation_drawmenu_sdfile(bool sel, uint8_t row, const char* pstr, const char* filename, char* longFilename) { + lcd_implementation_drawmenu_sd(sel, row, pstr, filename, longFilename, 2, ' '); + } + + static void lcd_implementation_drawmenu_sddirectory(bool sel, uint8_t row, const char* pstr, const char* filename, char* longFilename) { + lcd_implementation_drawmenu_sd(sel, row, pstr, filename, longFilename, 2, LCD_STR_FOLDER[0]); + } + +#endif //SDSUPPORT + +#define lcd_implementation_drawmenu_back(sel, row, pstr) lcd_implementation_drawmenu_generic(sel, row, pstr, LCD_STR_UPLEVEL[0], LCD_STR_UPLEVEL[0]) +#define lcd_implementation_drawmenu_submenu(sel, row, pstr, data) lcd_implementation_drawmenu_generic(sel, row, pstr, '>', LCD_STR_ARROW_RIGHT[0]) +#define lcd_implementation_drawmenu_gcode(sel, row, pstr, gcode) lcd_implementation_drawmenu_generic(sel, row, pstr, '>', ' ') +#define lcd_implementation_drawmenu_function(sel, row, pstr, data) lcd_implementation_drawmenu_generic(sel, row, pstr, '>', ' ') + +#if ENABLED(LCD_HAS_STATUS_INDICATORS) + + static void lcd_implementation_update_indicators() { + // Set the LEDS - referred to as backlights by the LiquidTWI2 library + static uint8_t ledsprev = 0; + uint8_t leds = 0; + + if (thermalManager.degTargetBed() > 0) leds |= LED_A; + + if (thermalManager.degTargetHotend(0) > 0) leds |= LED_B; + + #if FAN_COUNT > 0 + if (0 + #if HAS_FAN0 + || fanSpeeds[0] + #endif + #if HAS_FAN1 + || fanSpeeds[1] + #endif + #if HAS_FAN2 + || fanSpeeds[2] + #endif + ) leds |= LED_C; + #endif // FAN_COUNT > 0 + + #if HOTENDS > 1 + if (thermalManager.degTargetHotend(1) > 0) leds |= LED_C; + #endif + + if (leds != ledsprev) { + lcd.setBacklight(leds); + ledsprev = leds; + } + + } + +#endif // LCD_HAS_STATUS_INDICATORS + +#if ENABLED(LCD_HAS_SLOW_BUTTONS) + + extern millis_t next_button_update_ms; + + static uint8_t lcd_implementation_read_slow_buttons() { + #if ENABLED(LCD_I2C_TYPE_MCP23017) + // Reading these buttons this is likely to be too slow to call inside interrupt context + // so they are called during normal lcd_update + uint8_t slow_bits = lcd.readButtons() << B_I2C_BTN_OFFSET; + #if ENABLED(LCD_I2C_VIKI) + if ((slow_bits & (B_MI | B_RI)) && PENDING(millis(), next_button_update_ms)) // LCD clicked + slow_bits &= ~(B_MI | B_RI); // Disable LCD clicked buttons if screen is updated + #endif // LCD_I2C_VIKI + return slow_bits; + #endif // LCD_I2C_TYPE_MCP23017 + } + +#endif // LCD_HAS_SLOW_BUTTONS + +#endif // ULTRALCD_IMPL_HD44780_H diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/ultralcd_st7920_u8glib_rrd.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/ultralcd_st7920_u8glib_rrd.h new file mode 100644 index 00000000..7226f55c --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/ultralcd_st7920_u8glib_rrd.h @@ -0,0 +1,191 @@ +/** + * 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 . + * + */ + +#ifndef ULCDST7920_H +#define ULCDST7920_H + +#include "Marlin.h" + +#if ENABLED(U8GLIB_ST7920) + +#define ST7920_CLK_PIN LCD_PINS_D4 +#define ST7920_DAT_PIN LCD_PINS_ENABLE +#define ST7920_CS_PIN LCD_PINS_RS + +//#define PAGE_HEIGHT 8 //128 byte framebuffer +//#define PAGE_HEIGHT 16 //256 byte framebuffer +#define PAGE_HEIGHT 32 //512 byte framebuffer + +#define LCD_PIXEL_WIDTH 128 +#define LCD_PIXEL_HEIGHT 64 + +#include + +//set optimization so ARDUINO optimizes this file +#pragma GCC optimize (3) + +#define DELAY_0_NOP NOOP +#define DELAY_1_NOP __asm__("nop\n\t") +#define DELAY_2_NOP __asm__("nop\n\t" "nop\n\t") +#define DELAY_3_NOP __asm__("nop\n\t" "nop\n\t" "nop\n\t") +#define DELAY_4_NOP __asm__("nop\n\t" "nop\n\t" "nop\n\t" "nop\n\t") + + +// If you want you can define your own set of delays in Configuration.h +//#define ST7920_DELAY_1 DELAY_0_NOP +//#define ST7920_DELAY_2 DELAY_0_NOP +//#define ST7920_DELAY_3 DELAY_0_NOP + +#if F_CPU >= 20000000 + #define CPU_ST7920_DELAY_1 DELAY_0_NOP + #define CPU_ST7920_DELAY_2 DELAY_0_NOP + #define CPU_ST7920_DELAY_3 DELAY_1_NOP +#elif (MOTHERBOARD == BOARD_3DRAG) || (MOTHERBOARD == BOARD_K8200) || (MOTHERBOARD == BOARD_K8400) + #define CPU_ST7920_DELAY_1 DELAY_0_NOP + #define CPU_ST7920_DELAY_2 DELAY_3_NOP + #define CPU_ST7920_DELAY_3 DELAY_0_NOP +#elif (MOTHERBOARD == BOARD_MINIRAMBO) + #define CPU_ST7920_DELAY_1 DELAY_0_NOP + #define CPU_ST7920_DELAY_2 DELAY_4_NOP + #define CPU_ST7920_DELAY_3 DELAY_0_NOP +#elif (MOTHERBOARD == BOARD_RAMBO) + #define CPU_ST7920_DELAY_1 DELAY_0_NOP + #define CPU_ST7920_DELAY_2 DELAY_0_NOP + #define CPU_ST7920_DELAY_3 DELAY_0_NOP +#elif F_CPU == 16000000 + #define CPU_ST7920_DELAY_1 DELAY_0_NOP + #define CPU_ST7920_DELAY_2 DELAY_0_NOP + #define CPU_ST7920_DELAY_3 DELAY_1_NOP +#else + #error "No valid condition for delays in 'ultralcd_st7920_u8glib_rrd.h'" +#endif + +#ifndef ST7920_DELAY_1 + #define ST7920_DELAY_1 CPU_ST7920_DELAY_1 +#endif +#ifndef ST7920_DELAY_2 + #define ST7920_DELAY_2 CPU_ST7920_DELAY_2 +#endif +#ifndef ST7920_DELAY_3 + #define ST7920_DELAY_3 CPU_ST7920_DELAY_3 +#endif + +#define ST7920_SND_BIT \ + WRITE(ST7920_CLK_PIN, LOW); ST7920_DELAY_1; \ + WRITE(ST7920_DAT_PIN, val & 0x80); ST7920_DELAY_2; \ + WRITE(ST7920_CLK_PIN, HIGH); ST7920_DELAY_3; \ + val <<= 1 + +static void ST7920_SWSPI_SND_8BIT(uint8_t val) { + ST7920_SND_BIT; // 1 + ST7920_SND_BIT; // 2 + ST7920_SND_BIT; // 3 + ST7920_SND_BIT; // 4 + ST7920_SND_BIT; // 5 + ST7920_SND_BIT; // 6 + ST7920_SND_BIT; // 7 + ST7920_SND_BIT; // 8 +} + +#define ST7920_CS() {WRITE(ST7920_CS_PIN,1);u8g_10MicroDelay();} +#define ST7920_NCS() {WRITE(ST7920_CS_PIN,0);} +#define ST7920_SET_CMD() {ST7920_SWSPI_SND_8BIT(0xf8);u8g_10MicroDelay();} +#define ST7920_SET_DAT() {ST7920_SWSPI_SND_8BIT(0xfa);u8g_10MicroDelay();} +#define ST7920_WRITE_BYTE(a) {ST7920_SWSPI_SND_8BIT((uint8_t)((a)&0xf0u));ST7920_SWSPI_SND_8BIT((uint8_t)((a)<<4u));u8g_10MicroDelay();} +#define ST7920_WRITE_BYTES(p,l) {uint8_t i;for(i=0;idev_mem); + y = pb->p.page_y0; + ptr = (uint8_t*)pb->buf; + + ST7920_CS(); + for (i = 0; i < PAGE_HEIGHT; i ++) { + ST7920_SET_CMD(); + if (y < 32) { + ST7920_WRITE_BYTE(0x80 | y); //y + ST7920_WRITE_BYTE(0x80); //x=0 + } + else { + ST7920_WRITE_BYTE(0x80 | (y - 32)); //y + ST7920_WRITE_BYTE(0x80 | 8); //x=64 + } + ST7920_SET_DAT(); + ST7920_WRITE_BYTES(ptr, (LCD_PIXEL_WIDTH) / 8); //ptr is incremented inside of macro + y++; + } + ST7920_NCS(); + } + break; + } +#if PAGE_HEIGHT == 8 + return u8g_dev_pb8h1_base_fn(u8g, dev, msg, arg); +#elif PAGE_HEIGHT == 16 + return u8g_dev_pb16h1_base_fn(u8g, dev, msg, arg); +#else + return u8g_dev_pb32h1_base_fn(u8g, dev, msg, arg); +#endif +} + +uint8_t u8g_dev_st7920_128x64_rrd_buf[(LCD_PIXEL_WIDTH) * (PAGE_HEIGHT) / 8] U8G_NOCOMMON; +u8g_pb_t u8g_dev_st7920_128x64_rrd_pb = {{PAGE_HEIGHT, LCD_PIXEL_HEIGHT, 0, 0, 0}, LCD_PIXEL_WIDTH, u8g_dev_st7920_128x64_rrd_buf}; +u8g_dev_t u8g_dev_st7920_128x64_rrd_sw_spi = {u8g_dev_rrd_st7920_128x64_fn, &u8g_dev_st7920_128x64_rrd_pb, &u8g_com_null_fn}; + +class U8GLIB_ST7920_128X64_RRD : public U8GLIB { + public: + U8GLIB_ST7920_128X64_RRD(uint8_t dummy) : U8GLIB(&u8g_dev_st7920_128x64_rrd_sw_spi) { UNUSED(dummy); } +}; + +#pragma GCC reset_options + +#endif //U8GLIB_ST7920 +#endif //ULCDST7920_H diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/utf_mapper.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/utf_mapper.h new file mode 100644 index 00000000..bba85e18 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/utf_mapper.h @@ -0,0 +1,358 @@ +/** + * 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 . + * + */ + +#ifndef UTF_MAPPER_H +#define UTF_MAPPER_H + +#include "language.h" + +#if ENABLED(DOGLCD) + #define HARDWARE_CHAR_OUT u8g.print +#else + #define HARDWARE_CHAR_OUT lcd.write +#endif + +#if DISABLED(SIMULATE_ROMFONT) && ENABLED(DOGLCD) + #if ENABLED(DISPLAY_CHARSET_ISO10646_1) + #define MAPPER_ONE_TO_ONE + #elif ENABLED(DISPLAY_CHARSET_ISO10646_5) + #define MAPPER_ONE_TO_ONE + #elif ENABLED(DISPLAY_CHARSET_ISO10646_KANA) + #define MAPPER_ONE_TO_ONE + #elif ENABLED(DISPLAY_CHARSET_ISO10646_GREEK) + #define MAPPER_ONE_TO_ONE + #endif +#else // SIMULATE_ROMFONT + #if DISPLAY_CHARSET_HD44780 == JAPANESE + #if ENABLED(MAPPER_C2C3) + const PROGMEM uint8_t utf_recode[] = + { // 0 1 2 3 4 5 6 7 8 9 a b c d e f This is fair for symbols + 0x20,0x3f,0xec,0xed,0x3f,0x5c,0x7c,0x3f,0x22,0x63,0x61,0x7f,0x3f,0x3f,0x52,0xb0, // c2a + // ' ' ¢ £ ­ l " c a « R + 0xdf,0x3f,0x32,0x33,0x27,0xe4,0xf1,0xa5,0x2c,0x31,0xdf,0x7e,0x3f,0x3f,0x3f,0x3f, // c2b but relatively bad for letters. + // ° 2 3 ` N p . , 1 ° » + 0x3f,0x3f,0x3f,0x3f,0xe1,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f, // c38 + // ä + 0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0xef,0x78,0x3f,0x3f,0x3f,0x3f,0xf5,0x3f,0x3f,0xe2, // c39 missing characters display as '?' + // ö x ü ß + 0x3f,0x3f,0x3f,0x3f,0xe1,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f, // c3a + // ä + 0x3f,0xee,0x3f,0x3f,0x3f,0x3f,0xef,0xfd,0x3f,0x3f,0x3f,0x3f,0xf5,0x3f,0x3f,0x3f // c3b + // n ö ÷ ü + }; + #elif ENABLED(MAPPER_E382E383) + const PROGMEM uint8_t utf_recode[] = + { // 0 1 2 3 4 5 6 7 8 9 a b c d e f + 0x3d,0xb1,0xb1,0xa8,0xb2,0xa9,0xb3,0xaa,0xb4,0xab,0xb5,0xb6,0xb6,0xb7,0xb7,0xb8, // e382a Please test and correct + // = ア ア ィ イ ゥ ウ ェ エ ォ オ ガ ガ キ キ ク + 0xb8,0xb9,0xb9,0xba,0xba,0xbb,0xbb,0xbc,0xbc,0xbd,0xbd,0xbe,0xbe,0xbf,0xbf,0xc0, // e382b + // ク ケ ケ コ コ サ サ シ シ ス ス セ セ ソ ソ タ + 0xc0,0xc1,0xc1,0xc2,0xc2,0xc2,0xc3,0xc3,0xc4,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca, // e3838 + // タ チ チ ッ ッ ッ テ テ ト ト ナ ニ ヌ ネ ノ ハ + 0xca,0xca,0xcb,0xcb,0xcb,0xcc,0xcc,0xcc,0xcd,0xcd,0xcd,0xce,0xce,0xce,0xcf,0xd0, // e3839 + // ハ ハ ヒ ヒ ヒ フ フ フ ヘ ヘ ヘ ホ ホ ホ マ ミ + 0xd1,0xd2,0xd3,0xd4,0xd4,0xd5,0xd5,0xae,0xd6,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,0xdc, // e383a + // ム メ モ ャ ャ ユ ユ ョ ヨ ラ リ ル レ ロ ワ ワ + 0xec,0xa7,0xa6,0xdd,0xcc,0x3f,0x3f,0x3f,0x3f,0x3f,0xa6,0xa5,0xb0,0xa4,0xa4,0x3f // e383b + // ヰ ヱ ヲ ン フ ? ? ? ? ? ヲ ・ ー ヽ ヽ ? + }; + #elif ENABLED(MAPPER_D0D1) + #error "Cyrillic on a JAPANESE display makes no sense. There are no matching symbols." + #endif + + #elif DISPLAY_CHARSET_HD44780 == WESTERN + #if ENABLED(MAPPER_C2C3) + const PROGMEM uint8_t utf_recode[] = + { // 0 1 2 3 4 5 6 7 8 9 a b c d e f This is relative complete. + 0x20,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0x22,0xa9,0xaa,0xab,0x3f,0x3f,0xae,0x3f, // c2a ¡¢£¤¥¦§¨©ª«¬­®¯ + // ' ' ¡ ¢ £ ¤ ¥ ¦ § " © ª « ? ? ® ? + 0xb0,0xb1,0xb2,0xb3,0x27,0xb5,0xb6,0xb7,0x2c,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf, // c2b °±²³´µ¶·¸¹º»¼½¾¿ + // ° ± ³ ² ? µ ¶ · , ¹ º » ¼ ½ ¾ ¿ + 0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf, // c38 ÀÁÃÄÅÆÇÈÉÊËÌÍÎÏ + // À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï + 0xd0,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,0xdd,0xde,0xdf, // c39 ÐÑÓÔÕÖרÙÚÛÜÝÞß + // Ð Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ü Ý Þ ß + 0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xeb,0xec,0xed,0xee,0xef, // c3a àáãäåæçèéêëìíîï + // à á â ã ä å æ ç è é ê ë ì í î ï + 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff // c3b ðñóôõö÷øùúûüýþÿ + // ð ñ ò ó ô õ ö ÷ ø ù ú û ü ý þ ÿ + }; + #elif ENABLED(MAPPER_D0D1) + #define MAPPER_D0D1_MOD + const PROGMEM uint8_t utf_recode[] = + {//0 1 2 3 4 5 6 7 8 9 a b c d e f + 0x41,0x80,0x42,0x92,0x81,0x45,0x82,0x83,0x84,0x85,0x4b,0x86,0x4d,0x48,0x4f,0x87, // d0a + // A Б B Г Д E Ж З И Й K Л M H O П + 0x50,0x43,0x54,0x88,0xd8,0x58,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x62,0x8f,0xac,0xad, // d0b + // P C T У Ф X Ч ч Ш Щ Ъ Ы b Э Ю Я + 0x61,0x36,0x42,0x92,0x81,0x65,0x82,0xb3,0x84,0x85,0x6b,0x86,0x4d,0x48,0x6f,0x87, // d18 + // a 6 B Г Д e Ж ³ И Й k Л M H o П + 0x70,0x63,0x54,0x79,0xd8,0x78,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x62,0x8f,0xac,0xad // d19 + // p c T y Ф x Ч ч Ш Щ Ъ Ы b Э Ю Я + }; + #elif ENABLED(MAPPER_E382E383) + #error "Katakana on a WESTERN display makes no sense. There are no matching symbols." + #endif + + #elif DISPLAY_CHARSET_HD44780 == CYRILLIC + #if ENABLED(MAPPER_D0D1) + #define MAPPER_D0D1_MOD + // it is a Russian alphabet translation + // except 0401 --> 0xa2 = Ё, 0451 --> 0xb5 = ё + const PROGMEM uint8_t utf_recode[] = + { 0x41,0xa0,0x42,0xa1,0xe0,0x45,0xa3,0xa4, // unicode U+0400 to U+047f + // A Б->Ё B Г Д E Ж З // 0 Ѐ Ё Ђ Ѓ Є Ѕ І Ї + 0xa5,0xa6,0x4b,0xa7,0x4d,0x48,0x4f,0xa8, // Ј Љ Њ Ћ Ќ Ѝ Ў Џ + // И Й K Л M H O П // 1 А Б В Г Д Е Ж З + 0x50,0x43,0x54,0xa9,0xaa,0x58,0xe1,0xab, // И Й К Л М Н О П + // P C T У Ф X Ч ч // 2 Р С Т У Ф Х Г Ч + 0xac,0xe2,0xad,0xae,0x62,0xaf,0xb0,0xb1, // Ш Щ Ъ Ы Ь Э Ю Я + // Ш Щ Ъ Ы b Э Ю Я // 3 а б в г д е ж з + 0x61,0xb2,0xb3,0xb4,0xe3,0x65,0xb6,0xb7, // и й к л м н о п + // a б->ё в г д e ж з // 4 р с т у ф х ц ч + 0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0x6f,0xbe, // ш щ ъ ы ь э ю я + // и й к л м н o п // 5 ѐ ё ђ ѓ є ѕ і ї + 0x70,0x63,0xbf,0x79,0xe4,0x78,0xe5,0xc0, // ј љ њ ћ ќ ѝ ў џ + // p c т y ф x ц ч // 6 Ѡ ѡ Ѣ ѣ Ѥ ѥ Ѧ ѧ + 0xc1,0xe6,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7 // Ѫ ѩ Ѫ ѫ Ѭ ѭ Ѯ ѯ + // ш щ ъ ы ь э ю я // 7 Ѱ ѱ Ѳ ѳ Ѵ ѵ Ѷ ѷ + }; // ѻ ѹ Ѻ ѻ Ѽ ѽ Ѿ ѿ + #elif ENABLED(MAPPER_C2C3) + #error "Western languages on a CYRILLIC display makes no sense. There are no matching symbols." + #elif ENABLED(MAPPER_E382E383) + #error "Katakana on a CYRILLIC display makes no sense. There are no matching symbols." + #endif + #else + #error "Something went wrong in the setting of DISPLAY_CHARSET_HD44780" + #endif // DISPLAY_CHARSET_HD44780 +#endif // SIMULATE_ROMFONT + +#if ENABLED(MAPPER_C2C3) + + char charset_mapper(char c) { + static uint8_t utf_hi_char; // UTF-8 high part + static bool seen_c2 = false; + uint8_t d = c; + if ( d >= 0x80u ) { // UTF-8 handling + if ( (d >= 0xc0u) && (!seen_c2) ) { + utf_hi_char = d - 0xc2u; + seen_c2 = true; + return 0; + } + else if (seen_c2) { + d &= 0x3fu; + #ifndef MAPPER_ONE_TO_ONE + HARDWARE_CHAR_OUT((char)pgm_read_byte_near(utf_recode + d + (utf_hi_char << 6) - 0x20)); + #else + HARDWARE_CHAR_OUT((char)(0x80u + (utf_hi_char << 6) + d)) ; + #endif + } + else { + HARDWARE_CHAR_OUT('?'); + } + } + else { + HARDWARE_CHAR_OUT((char) c ); + } + seen_c2 = false; + return 1; + } + +#elif ENABLED(MAPPER_CECF) + + char charset_mapper(char c) { + static uint8_t utf_hi_char; // UTF-8 high part + static bool seen_ce = false; + uint8_t d = c; + if ( d >= 0x80 ) { // UTF-8 handling + if ( (d >= 0xc0) && (!seen_ce) ) { + utf_hi_char = d - 0xce; + seen_ce = true; + return 0; + } + else if (seen_ce) { + d &= 0x3f; + #ifndef MAPPER_ONE_TO_ONE + HARDWARE_CHAR_OUT((char)pgm_read_byte_near(utf_recode + d + (utf_hi_char << 6) - 0x20)); + #else + HARDWARE_CHAR_OUT((char)(0x80 + (utf_hi_char << 6) + d)) ; + #endif + } + else { + HARDWARE_CHAR_OUT('?'); + } + } + else { + HARDWARE_CHAR_OUT((char) c ); + } + seen_ce = false; + return 1; + } + +#elif ENABLED(MAPPER_CECF) + + char charset_mapper(char c) { + static uint8_t utf_hi_char; // UTF-8 high part + static bool seen_ce = false; + uint8_t d = c; + if ( d >= 0x80 ) { // UTF-8 handling + if ( (d >= 0xc0) && (!seen_ce) ) { + utf_hi_char = d - 0xce; + seen_ce = true; + return 0; + } + else if (seen_ce) { + d &= 0x3f; + #ifndef MAPPER_ONE_TO_ONE + HARDWARE_CHAR_OUT((char)pgm_read_byte_near(utf_recode + d + (utf_hi_char << 6) - 0x20)); + #else + HARDWARE_CHAR_OUT((char)(0x80 + (utf_hi_char << 6) + d)) ; + #endif + } + else { + HARDWARE_CHAR_OUT('?'); + } + } + else { + HARDWARE_CHAR_OUT((char) c ); + } + seen_ce = false; + return 1; + } + +#elif ENABLED(MAPPER_D0D1_MOD) + + char charset_mapper(char c) { + // it is a Russian alphabet translation + // except 0401 --> 0xa2 = Ё, 0451 --> 0xb5 = ё + static uint8_t utf_hi_char; // UTF-8 high part + static bool seen_d5 = false; + uint8_t d = c; + if (d >= 0x80) { // UTF-8 handling + if (d >= 0xd0 && !seen_d5) { + utf_hi_char = d - 0xd0; + seen_d5 = true; + return 0; + } + else if (seen_d5) { + d &= 0x3f; + if (!utf_hi_char && d == 1) { + HARDWARE_CHAR_OUT((char) 0xa2); // Ё + } + else if (utf_hi_char == 1 && d == 0x11) { + HARDWARE_CHAR_OUT((char)0xb5); // ё + } + else { + HARDWARE_CHAR_OUT((char)pgm_read_byte_near(utf_recode + d + (utf_hi_char << 6) - 0x10)); + } + } + else { + HARDWARE_CHAR_OUT('?'); + } + } + else { + HARDWARE_CHAR_OUT((char) c ); + } + seen_d5 = false; + return 1; + } + +#elif ENABLED(MAPPER_D0D1) + + char charset_mapper(char c) { + static uint8_t utf_hi_char; // UTF-8 high part + static bool seen_d5 = false; + uint8_t d = c; + if (d >= 0x80u) { // UTF-8 handling + if (d >= 0xd0u && !seen_d5) { + utf_hi_char = d - 0xd0u; + seen_d5 = true; + return 0; + } + else if (seen_d5) { + d &= 0x3fu; + #ifndef MAPPER_ONE_TO_ONE + HARDWARE_CHAR_OUT((char)pgm_read_byte_near(utf_recode + d + (utf_hi_char << 6) - 0x20)); + #else + HARDWARE_CHAR_OUT((char)(0xa0u + (utf_hi_char << 6) + d)) ; + #endif + } + else { + HARDWARE_CHAR_OUT('?'); + } + } + else { + HARDWARE_CHAR_OUT((char) c ); + } + seen_d5 = false; + return 1; + } + +#elif ENABLED(MAPPER_E382E383) + + char charset_mapper(char c) { + static uint8_t utf_hi_char; // UTF-8 high part + static bool seen_e3 = false; + static bool seen_82_83 = false; + uint8_t d = c; + if (d >= 0x80) { // UTF-8 handling + if (d == 0xe3 && !seen_e3) { + seen_e3 = true; + return 0; // eat 0xe3 + } + else if (d >= 0x82 && seen_e3 && !seen_82_83) { + utf_hi_char = d - 0x82; + seen_82_83 = true; + return 0; + } + else if (seen_e3 && seen_82_83) { + d &= 0x3f; + #ifndef MAPPER_ONE_TO_ONE + HARDWARE_CHAR_OUT((char)pgm_read_byte_near(utf_recode + d + (utf_hi_char << 6) - 0x20)); + #else + HARDWARE_CHAR_OUT((char)(0x80 + (utf_hi_char << 6) + d)) ; + #endif + } + else { + HARDWARE_CHAR_OUT((char) '?' ); + } + } + else { + HARDWARE_CHAR_OUT((char) c ); + } + seen_e3 = false; + seen_82_83 = false; + return 1; + } + +#else + + #define MAPPER_NON + + char charset_mapper(char c) { + HARDWARE_CHAR_OUT( c ); + return 1; + } + + #endif // code mappers + +#endif // UTF_MAPPER_H diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/utility.cpp b/trunk/Arduino/Marlin_K8600_1.1.0RC7/utility.cpp new file mode 100644 index 00000000..0285219c --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/utility.cpp @@ -0,0 +1,34 @@ +/** + * 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 . + * + */ + +#include "Marlin.h" +#include "utility.h" +#include "temperature.h" + +void safe_delay(millis_t ms) { + while (ms > 50) { + ms -= 50; + delay(50); + thermalManager.manage_heater(); + } + delay(ms); +} diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/utility.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/utility.h new file mode 100644 index 00000000..8ca70dbf --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/utility.h @@ -0,0 +1,28 @@ +/** + * 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 . + * + */ + +#ifndef __UTILITY_H__ +#define __UTILITY_H__ + +void safe_delay(millis_t ms); + +#endif diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/vector_3.cpp b/trunk/Arduino/Marlin_K8600_1.1.0RC7/vector_3.cpp new file mode 100644 index 00000000..1cca0d9d --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/vector_3.cpp @@ -0,0 +1,160 @@ +/** + * 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 . + * + */ + +/** + vector_3.cpp - Vector library for bed leveling + Copyright (c) 2012 Lars Brubaker. 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 +#include "Marlin.h" + +#if ENABLED(AUTO_BED_LEVELING_FEATURE) +#include "vector_3.h" + +vector_3::vector_3() : x(0), y(0), z(0) { } + +vector_3::vector_3(float x_, float y_, float z_) : x(x_), y(y_), z(z_) { } + +vector_3 vector_3::cross(vector_3 left, vector_3 right) { + return vector_3(left.y * right.z - left.z * right.y, + left.z * right.x - left.x * right.z, + left.x * right.y - left.y * right.x); +} + +vector_3 vector_3::operator+(vector_3 v) { return vector_3((x + v.x), (y + v.y), (z + v.z)); } +vector_3 vector_3::operator-(vector_3 v) { return vector_3((x - v.x), (y - v.y), (z - v.z)); } + +vector_3 vector_3::get_normal() { + vector_3 normalized = vector_3(x, y, z); + normalized.normalize(); + return normalized; +} + +float vector_3::get_length() { return sqrt((x * x) + (y * y) + (z * z)); } + +void vector_3::normalize() { + float length = get_length(); + x /= length; + y /= length; + z /= length; +} + +void vector_3::apply_rotation(matrix_3x3 matrix) { + float resultX = x * matrix.matrix[3 * 0 + 0] + y * matrix.matrix[3 * 1 + 0] + z * matrix.matrix[3 * 2 + 0]; + float resultY = x * matrix.matrix[3 * 0 + 1] + y * matrix.matrix[3 * 1 + 1] + z * matrix.matrix[3 * 2 + 1]; + float resultZ = x * matrix.matrix[3 * 0 + 2] + y * matrix.matrix[3 * 1 + 2] + z * matrix.matrix[3 * 2 + 2]; + x = resultX; + y = resultY; + z = resultZ; +} + +void vector_3::debug(const char title[]) { + SERIAL_PROTOCOL(title); + SERIAL_PROTOCOLPGM(" x: "); + SERIAL_PROTOCOL_F(x, 6); + SERIAL_PROTOCOLPGM(" y: "); + SERIAL_PROTOCOL_F(y, 6); + SERIAL_PROTOCOLPGM(" z: "); + SERIAL_PROTOCOL_F(z, 6); + SERIAL_EOL; +} + +void apply_rotation_xyz(matrix_3x3 matrix, float& x, float& y, float& z) { + vector_3 vector = vector_3(x, y, z); + vector.apply_rotation(matrix); + x = vector.x; + y = vector.y; + z = vector.z; +} + +matrix_3x3 matrix_3x3::create_from_rows(vector_3 row_0, vector_3 row_1, vector_3 row_2) { + //row_0.debug("row_0"); + //row_1.debug("row_1"); + //row_2.debug("row_2"); + matrix_3x3 new_matrix; + new_matrix.matrix[0] = row_0.x; new_matrix.matrix[1] = row_0.y; new_matrix.matrix[2] = row_0.z; + new_matrix.matrix[3] = row_1.x; new_matrix.matrix[4] = row_1.y; new_matrix.matrix[5] = row_1.z; + new_matrix.matrix[6] = row_2.x; new_matrix.matrix[7] = row_2.y; new_matrix.matrix[8] = row_2.z; + //new_matrix.debug("new_matrix"); + return new_matrix; +} + +void matrix_3x3::set_to_identity() { + matrix[0] = 1; matrix[1] = 0; matrix[2] = 0; + matrix[3] = 0; matrix[4] = 1; matrix[5] = 0; + matrix[6] = 0; matrix[7] = 0; matrix[8] = 1; +} + +matrix_3x3 matrix_3x3::create_look_at(vector_3 target) { + vector_3 z_row = target.get_normal(); + vector_3 x_row = vector_3(1, 0, -target.x / target.z).get_normal(); + vector_3 y_row = vector_3::cross(z_row, x_row).get_normal(); + + // x_row.debug("x_row"); + // y_row.debug("y_row"); + // z_row.debug("z_row"); + + // create the matrix already correctly transposed + matrix_3x3 rot = matrix_3x3::create_from_rows(x_row, y_row, z_row); + + // rot.debug("rot"); + return rot; +} + +matrix_3x3 matrix_3x3::transpose(matrix_3x3 original) { + matrix_3x3 new_matrix; + new_matrix.matrix[0] = original.matrix[0]; new_matrix.matrix[1] = original.matrix[3]; new_matrix.matrix[2] = original.matrix[6]; + new_matrix.matrix[3] = original.matrix[1]; new_matrix.matrix[4] = original.matrix[4]; new_matrix.matrix[5] = original.matrix[7]; + new_matrix.matrix[6] = original.matrix[2]; new_matrix.matrix[7] = original.matrix[5]; new_matrix.matrix[8] = original.matrix[8]; + return new_matrix; +} + +void matrix_3x3::debug(const char title[]) { + SERIAL_PROTOCOLLN(title); + int count = 0; + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + if (matrix[count] >= 0.0) SERIAL_PROTOCOLCHAR('+'); + SERIAL_PROTOCOL_F(matrix[count], 6); + SERIAL_PROTOCOLCHAR(' '); + count++; + } + SERIAL_EOL; + } +} + +#endif // AUTO_BED_LEVELING_FEATURE + diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/vector_3.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/vector_3.h new file mode 100644 index 00000000..e76188b0 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/vector_3.h @@ -0,0 +1,82 @@ +/** + * 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 . + * + */ + +/** + vector_3.cpp - Vector library for bed leveling + Copyright (c) 2012 Lars Brubaker. 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 VECTOR_3_H +#define VECTOR_3_H + +#if ENABLED(AUTO_BED_LEVELING_FEATURE) +class matrix_3x3; + +struct vector_3 { + float x, y, z; + + vector_3(); + vector_3(float x, float y, float z); + + static vector_3 cross(vector_3 a, vector_3 b); + + vector_3 operator+(vector_3 v); + vector_3 operator-(vector_3 v); + void normalize(); + float get_length(); + vector_3 get_normal(); + + void debug(const char title[]); + + void apply_rotation(matrix_3x3 matrix); +}; + +struct matrix_3x3 { + float matrix[9]; + + static matrix_3x3 create_from_rows(vector_3 row_0, vector_3 row_1, vector_3 row_2); + static matrix_3x3 create_look_at(vector_3 target); + static matrix_3x3 transpose(matrix_3x3 original); + + void set_to_identity(); + + void debug(const char title[]); +}; + + +void apply_rotation_xyz(matrix_3x3 rotationMatrix, float& x, float& y, float& z); +#endif // AUTO_BED_LEVELING_FEATURE + +#endif // VECTOR_3_H diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/watchdog.cpp b/trunk/Arduino/Marlin_K8600_1.1.0RC7/watchdog.cpp new file mode 100644 index 00000000..4397ab60 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/watchdog.cpp @@ -0,0 +1,56 @@ +/** + * 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 . + * + */ + +#include "Marlin.h" + +#if ENABLED(USE_WATCHDOG) + +#include "watchdog.h" + +// Initialize watchdog with a 4 sec interrupt time +void watchdog_init() { + #if ENABLED(WATCHDOG_RESET_MANUAL) + // We enable the watchdog timer, but only for the interrupt. + // Take care, as this requires the correct order of operation, with interrupts disabled. See the datasheet of any AVR chip for details. + wdt_reset(); + _WD_CONTROL_REG = _BV(_WD_CHANGE_BIT) | _BV(WDE); + _WD_CONTROL_REG = _BV(WDIE) | WDTO_4S; + #else + wdt_enable(WDTO_4S); + #endif +} + +//=========================================================================== +//=================================== ISR =================================== +//=========================================================================== + +// Watchdog timer interrupt, called if main program blocks >1sec and manual reset is enabled. +#if ENABLED(WATCHDOG_RESET_MANUAL) + ISR(WDT_vect) { + SERIAL_ERROR_START; + SERIAL_ERRORLNPGM("Something is wrong, please turn off the printer."); + kill(PSTR("ERR:Please Reset")); //kill blocks //16 characters so it fits on a 16x2 display + while (1); //wait for user or serial reset + } +#endif //WATCHDOG_RESET_MANUAL + +#endif //USE_WATCHDOG diff --git a/trunk/Arduino/Marlin_K8600_1.1.0RC7/watchdog.h b/trunk/Arduino/Marlin_K8600_1.1.0RC7/watchdog.h new file mode 100644 index 00000000..2c04b589 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_1.1.0RC7/watchdog.h @@ -0,0 +1,36 @@ +/** + * 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 . + * + */ + +#ifndef WATCHDOG_H +#define WATCHDOG_H + +#include "Marlin.h" +#include + +// Initialize watchdog with a 4 second interrupt time +void watchdog_init(); + +// Reset watchdog. MUST be called at least every 4 seconds after the +// first watchdog_init or AVR will go into emergency procedures. +inline void watchdog_reset() { wdt_reset(); } + +#endif diff --git a/trunk/Arduino/Marlin_K8600_Original/eeprom.bin b/trunk/Arduino/Marlin_K8600_Original/eeprom.bin new file mode 100644 index 0000000000000000000000000000000000000000..f39e6884eadad11eb235261c4f52d5841f40a05e GIT binary patch literal 4096 zcmezWpHv{WhhY(eVJ9;~s}lpm3g)Hm1Pur?GGREP#=vj_r~!y2Cb=>+Ob4>XoFQ1j zfq}up=?*Ic0|*;2Ffa(H1Br&+E^rLwf`Eb_h+N=s_RJYO5Dnsi!1*(0?7<9XW-vu1 zVjs|){|v9eB*^Jo|4p;k3i#&&belaxgS9J)H3aw~Kutg$P^Huh?Compiled on = CPU Type = __AVR_ARCH__= AVR LibC Ver= GCC Version = CPU ID = Low fuse = High fuse = Ext fuse = Lock fuse = Mar 7 20131.6.84.3.5V# ADDR op code instruction addr Interruptno vectorrjmp jmp What port:Port not supportedMust be a letter Writting EEReading EEEE err cnt=PORT0=Zero addr?=CPU stats@=EEPROM testB=Blink LEDE=Dump EEPROMF=Dump FLASHH=HelpL=List I/O PortsQ=QuitR=Dump RAMV=show interrupt VectorsY=Port blink*$޿Ϳ   00`  $ ` 0@W1/_?O(9&1/_?O#aπdπdπd#Yπd1#y(//p/]3_πd/p/]3_πd6c0qdp.`]O`πd+012dp.jp.`]O`πdjp.πd/`πd/?O_oϒߒߓϓͷ޷b޿Ϳ8.b.\mw$ "..AQ('' '--- - πd␓πd πdu$$:Q: ;a wwx.p- πd-Rpp5 p   πjf rb޿Ϳϑߑߐϐo_O?//?O_oϒߒߓϓͷ޷S@޿Ϳ `a``x'/`ဓဓ$$D.,$$$!.  1.,';@PAaq􅱀XO__O^OYHQ@^OQ@ ]OS@`]OR@$$]OR@^OR@\OS@$$ \OS@ ^O(9Q@!01 ^OQ@"/_?OOO_O!08HX\OS@_O'' 0@P ]OHYR@O__O]OYHR@!2 cJ0Q_S Y–πd/_?O)11y_O0 0 +    ``ϐ6u2πd⠓πd4 44 Y4X33ş34 Ž4 p4 Ř5 +“584 5 –5 E™5 găb  +   b``````ap4`````   `W䑎/ `W䑎/ `W䑎/ `W/ ϋb`o- 1` πd_OQA૿!0`$$w.#1` πd_OQA૿!"0`ap4xΉb'//16/16πdąb@P`p POOOPA@@&Τσb@P`p   POOO ̀b```````````͇b{{{{{{{{{{{͈bw$s$$ ďb@ +P ` p   +   POOO +   i͊b``f$w$C]OR@]OR@]OR@]OR@bp4Ⱃπdπdπd]O +R@'//- ]OR@ .πd πdπd']O(R@.$$$aq(.3$D$U$aq7]O8R@aqG]OHR@.. +//n --,$   πd]OR@ 00πd]OR@ @@πd]OR@ PPπd1`p|ppPL@@/?@P""##]OʀۀR@  `'//- - 00πdN@χ"" +##  ]OR@.$/-,$]OR@pppp'' + 0@P""""A J  ("9"J"["5" 3DU: Wh `'' '//- - ␓πd㠓πd'' '--- - ]OR@ M.,--n ̓b`uπd/T164 44 N4044 04 Y4 k4 484 4 +4 4  1< 1< 1< 1< 1< 1< 1<k1<Q1<71< +  1< ɀπɈɌɈ$$00(000a00 HC+1 Bɑk?b']O(R@7ɲ/b'2ɂ/++b'+.0 9b']OS@]OS@ _O]OS@b' + & 0 w$1 10 0P0 0 m0 YS1 w11 O1 1P1 11 @1 l11 [1 33Y􏁈#0/u59W +59W'0 䌃千厃䏃切則劇㋇+09A9A9Dw$s#,0(&W$05􌁈09W WWύl.W#0슃\OS@X/D'3'"'''(+9+J+[+(+9+J+[+///'(+9+J+[+"3DU^O(9J[R@Y:\O8S@\OS@.$\OHYS@**1 \OS@PL@@0\O +S@[W\O*;S@PO/O?O\O*;S@^OHYj{R@1,\O(S@\OS@\OS@++ `[0W$N__OoOO.. ^O*;R@ [WρဓW5^OR@|., m]P@`pDUfw^O +R@N _`q^OHYj{R@\OS@\OS@.$\OS@**m_O1!^O +R@ n_O^OR@"P0@6^O(9J[R@v!'////_?OOO_O.?@Qa^O(9J[R@-_?O슃"0ဓπd]OR@πdC/0πd/ πdπde]OR@n%i'd'11di'!P0@!1i`πdXw ]OR@_]OR@ '/ 716ဓW'' ϐ  .& +w. paOO.   fwi`pQ Zϒ'&/  ATmega2560Arduino explorer stk500V2 by MLSBootloader>Huh?Compiled on = CPU Type = __AVR_ARCH__= AVR LibC Ver= GCC Version = CPU ID = Low fuse = High fuse = Ext fuse = Lock fuse = Mar 7 20131.6.84.3.5V# ADDR op code instruction addr Interruptno vectorrjmp jmp What port:Port not supportedMust be a letter Writting EEReading EEEE err cnt=PORT0=Zero addr?=CPU stats@=EEPROM testB=Blink LEDE=Dump EEPROMF=Dump FLASHH=HelpL=List I/O PortsQ=QuitR=Dump RAMV=show interrupt VectorsY=Port blink*$޿Ϳ   00`  $ ` 0@W1/_?O(9&1/_?O#aπdπdπd#Yπd1#y(//p/]3_πd/p/]3_πd6c0qdp.`]O`πd+012dp.jp.`]O`πdjp.πd/`πd/?O_oϒߒߓϓͷ޷b޿Ϳ8.b.\mw$ "..AQ('' '--- - πd␓πd πdu$$:Q: ;a wwx.p- πd-Rpp5 p   πjf rb޿Ϳϑߑߐϐo_O?//?O_oϒߒߓϓͷ޷S@޿Ϳ `a``x'/`ဓဓ$$D.,$$$!.  1.,';@PAaq􅱀XO__O^OYHQ@^OQ@ ]OS@`]OR@$$]OR@^OR@\OS@$$ \OS@ ^O(9Q@!01 ^OQ@"/_?OOO_O!08HX\OS@_O'' 0@P ]OHYR@O__O]OYHR@!2 cJ0Q_S Y–πd/_?O)11y_O0 0 +    ``ϐ6u2πd⠓πd4 44 Y4X33ş34 Ž4 p4 Ř5 +“584 5 –5 E™5 găb  +   b``````ap4`````   `W䑎/ `W䑎/ `W䑎/ `W/ ϋb`o- 1` πd_OQA૿!0`$$w.#1` πd_OQA૿!"0`ap4xΉb'//16/16πdąb@P`p POOOPA@@&Τσb@P`p   POOO ̀b```````````͇b{{{{{{{{{{{͈bw$s$$ ďb@ +P ` p   +   POOO +   i͊b``f$w$C]OR@]OR@]OR@]OR@bp4Ⱃπdπdπd]O +R@'//- ]OR@ .πd πdπd']O(R@.$$$aq(.3$D$U$aq7]O8R@aqG]OHR@.. +//n --,$   πd]OR@ 00πd]OR@ @@πd]OR@ PPπd1`p|ppPL@@/?@P""##]OʀۀR@  `'//- - 00πdN@χ"" +##  ]OR@.$/-,$]OR@pppp'' + 0@P""""A J  ("9"J"["5" 3DU: Wh `'' '//- - ␓πd㠓πd'' '--- - ]OR@ M.,--n ̓b`uπd/T164 44 N4044 04 Y4 k4 484 4 +4 4  1< 1< 1< 1< 1< 1< 1<k1<Q1<71< +  1< ɀπɈɌɈ$$00(000a00 HC+1 Bɑk?b']O(R@7ɲ/b'2ɂ/++b'+.0 9b']OS@]OS@ _O]OS@b' + & 0 w$1 10 0P0 0 m0 YS1 w11 O1 1P1 11 @1 l11 [1 33Y􏁈#0/u59W +59W'0 䌃千厃䏃切則劇㋇+09A9A9Dw$s#,0(&W$05􌁈09W WWύl.W#0슃\OS@X/D'3'"'''(+9+J+[+(+9+J+[+///'(+9+J+[+"3DU^O(9J[R@Y:\O8S@\OS@.$\OHYS@**1 \OS@PL@@0\O +S@[W\O*;S@PO/O?O\O*;S@^OHYj{R@1,\O(S@\OS@\OS@++ `[0W$N__OoOO.. ^O*;R@ [WρဓW5^OR@|., m]P@`pDUfw^O +R@N _`q^OHYj{R@\OS@\OS@.$\OS@**m_O1!^O +R@ n_O^OR@"P0@6^O(9J[R@v!'////_?OOO_O.?@Qa^O(9J[R@-_?O슃"0ဓπd]OR@πdC/0πd/ πdπde]OR@n%i'd'11di'!P0@!1i`πdXw ]OR@_]OR@ '/ 716ဓW'' ϐ  .& +w. paOO.   fwi`pQ Zϒ'&/  \ No newline at end of file diff --git a/trunk/Arduino/Marlin_K8600_Original/flash.hex b/trunk/Arduino/Marlin_K8600_Original/flash.hex new file mode 100644 index 00000000..0fd299fb --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_Original/flash.hex @@ -0,0 +1 @@ +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xd,0x94,0x89,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0x41,0x54,0x6d,0x65,0x67,0x61,0x32,0x35,0x36,0x30,0x0,0x41,0x72,0x64,0x75,0x69,0x6e,0x6f,0x20,0x65,0x78,0x70,0x6c,0x6f,0x72,0x65,0x72,0x20,0x73,0x74,0x6b,0x35,0x30,0x30,0x56,0x32,0x20,0x62,0x79,0x20,0x4d,0x4c,0x53,0x0,0x42,0x6f,0x6f,0x74,0x6c,0x6f,0x61,0x64,0x65,0x72,0x3e,0x0,0x48,0x75,0x68,0x3f,0x0,0x43,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x64,0x20,0x6f,0x6e,0x20,0x3d,0x20,0x0,0x43,0x50,0x55,0x20,0x54,0x79,0x70,0x65,0x20,0x20,0x20,0x20,0x3d,0x20,0x0,0x5f,0x5f,0x41,0x56,0x52,0x5f,0x41,0x52,0x43,0x48,0x5f,0x5f,0x3d,0x20,0x0,0x41,0x56,0x52,0x20,0x4c,0x69,0x62,0x43,0x20,0x56,0x65,0x72,0x3d,0x20,0x0,0x47,0x43,0x43,0x20,0x56,0x65,0x72,0x73,0x69,0x6f,0x6e,0x20,0x3d,0x20,0x0,0x43,0x50,0x55,0x20,0x49,0x44,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x0,0x4c,0x6f,0x77,0x20,0x66,0x75,0x73,0x65,0x20,0x20,0x20,0x20,0x3d,0x20,0x0,0x48,0x69,0x67,0x68,0x20,0x66,0x75,0x73,0x65,0x20,0x20,0x20,0x3d,0x20,0x0,0x45,0x78,0x74,0x20,0x66,0x75,0x73,0x65,0x20,0x20,0x20,0x20,0x3d,0x20,0x0,0x4c,0x6f,0x63,0x6b,0x20,0x66,0x75,0x73,0x65,0x20,0x20,0x20,0x3d,0x20,0x0,0x4d,0x61,0x72,0x20,0x20,0x37,0x20,0x32,0x30,0x31,0x33,0x0,0x31,0x2e,0x36,0x2e,0x38,0x0,0x34,0x2e,0x33,0x2e,0x35,0x0,0x56,0x23,0x20,0x20,0x20,0x41,0x44,0x44,0x52,0x20,0x20,0x20,0x6f,0x70,0x20,0x63,0x6f,0x64,0x65,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x73,0x74,0x72,0x75,0x63,0x74,0x69,0x6f,0x6e,0x20,0x61,0x64,0x64,0x72,0x20,0x20,0x20,0x49,0x6e,0x74,0x65,0x72,0x72,0x75,0x70,0x74,0x0,0x6e,0x6f,0x20,0x76,0x65,0x63,0x74,0x6f,0x72,0x0,0x72,0x6a,0x6d,0x70,0x20,0x20,0x0,0x6a,0x6d,0x70,0x20,0x0,0x57,0x68,0x61,0x74,0x20,0x70,0x6f,0x72,0x74,0x3a,0x0,0x50,0x6f,0x72,0x74,0x20,0x6e,0x6f,0x74,0x20,0x73,0x75,0x70,0x70,0x6f,0x72,0x74,0x65,0x64,0x0,0x4d,0x75,0x73,0x74,0x20,0x62,0x65,0x20,0x61,0x20,0x6c,0x65,0x74,0x74,0x65,0x72,0x0,0x20,0x0,0x57,0x72,0x69,0x74,0x74,0x69,0x6e,0x67,0x20,0x45,0x45,0x0,0x52,0x65,0x61,0x64,0x69,0x6e,0x67,0x20,0x45,0x45,0x0,0x45,0x45,0x20,0x65,0x72,0x72,0x20,0x63,0x6e,0x74,0x3d,0x0,0x50,0x4f,0x52,0x54,0x0,0x30,0x3d,0x5a,0x65,0x72,0x6f,0x20,0x61,0x64,0x64,0x72,0x0,0x3f,0x3d,0x43,0x50,0x55,0x20,0x73,0x74,0x61,0x74,0x73,0x0,0x40,0x3d,0x45,0x45,0x50,0x52,0x4f,0x4d,0x20,0x74,0x65,0x73,0x74,0x0,0x42,0x3d,0x42,0x6c,0x69,0x6e,0x6b,0x20,0x4c,0x45,0x44,0x0,0x45,0x3d,0x44,0x75,0x6d,0x70,0x20,0x45,0x45,0x50,0x52,0x4f,0x4d,0x0,0x46,0x3d,0x44,0x75,0x6d,0x70,0x20,0x46,0x4c,0x41,0x53,0x48,0x0,0x48,0x3d,0x48,0x65,0x6c,0x70,0x0,0x4c,0x3d,0x4c,0x69,0x73,0x74,0x20,0x49,0x2f,0x4f,0x20,0x50,0x6f,0x72,0x74,0x73,0x0,0x51,0x3d,0x51,0x75,0x69,0x74,0x0,0x52,0x3d,0x44,0x75,0x6d,0x70,0x20,0x52,0x41,0x4d,0x0,0x56,0x3d,0x73,0x68,0x6f,0x77,0x20,0x69,0x6e,0x74,0x65,0x72,0x72,0x75,0x70,0x74,0x20,0x56,0x65,0x63,0x74,0x6f,0x72,0x73,0x0,0x59,0x3d,0x50,0x6f,0x72,0x74,0x20,0x62,0x6c,0x69,0x6e,0x6b,0x0,0x2a,0x0,0x11,0x24,0x1f,0xbe,0xcf,0xef,0xd1,0xe2,0xde,0xbf,0xcd,0xbf,0x1,0xe0,0xc,0xbf,0x12,0xe0,0xa0,0xe0,0xb2,0xe0,0xee,0xe1,0xfd,0xef,0x3,0xe0,0xb,0xbf,0x2,0xc0,0x7,0x90,0xd,0x92,0xa0,0x30,0xb1,0x7,0xd9,0xf7,0x12,0xe0,0xa0,0xe0,0xb2,0xe0,0x1,0xc0,0x1d,0x92,0xae,0x30,0xb1,0x7,0xe1,0xf7,0xf,0x94,0x60,0xf3,0xd,0x94,0x8d,0xfe,0x1,0xe2,0xe,0xbf,0xf,0xef,0xd,0xbf,0x11,0x24,0x1f,0xbe,0xd,0x94,0x60,0xf3,0xd,0x94,0x0,0xf0,0x20,0xe0,0x30,0xe0,0x40,0xed,0x57,0xe0,0x5,0xc0,0xfa,0x1,0x31,0x97,0xf1,0xf7,0x2f,0x5f,0x3f,0x4f,0x28,0x17,0x39,0x7,0xc0,0xf3,0x8,0x95,0x9c,0x1,0x26,0xf,0x31,0x1d,0xc9,0x1,0xa0,0xe0,0xb0,0xe0,0x2f,0x5f,0x3f,0x4f,0xab,0xbf,0xfc,0x1,0x87,0x91,0x88,0x23,0x61,0xf0,0x80,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0xea,0xcf,0x8,0x95,0x8d,0xe0,0x80,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0x8a,0xe0,0x80,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0x8,0x95,0xf,0x94,0xc2,0xf1,0xf,0x94,0xdc,0xf1,0x8,0x95,0xfc,0x1,0x90,0x81,0x99,0x23,0x59,0xf0,0x90,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0x31,0x96,0x99,0x23,0x79,0xf7,0x8,0x95,0x28,0x2f,0x98,0x2f,0x92,0x95,0x9f,0x70,0x89,0x2f,0x80,0x5d,0x8a,0x33,0x8,0xf0,0x89,0x5f,0x80,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0x82,0x2f,0x8f,0x70,0x98,0x2f,0x90,0x5d,0x9a,0x33,0x8,0xf0,0x99,0x5f,0x90,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0x8,0x95,0x9c,0x1,0xfb,0x1,0x85,0x36,0x91,0x5,0x1c,0xf4,0x63,0x30,0x71,0x5,0x94,0xf0,0xc9,0x1,0x64,0xe6,0x70,0xe0,0xf,0x94,0x2e,0xfe,0x60,0x5d,0x7f,0x4f,0x60,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0x2b,0x30,0x31,0x5,0x14,0xf4,0x32,0x97,0xb4,0xf0,0xc9,0x1,0x64,0xe6,0x70,0xe0,0xf,0x94,0x2e,0xfe,0x6a,0xe0,0x70,0xe0,0xf,0x94,0x2e,0xfe,0x60,0x5d,0x7f,0x4f,0x60,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0xc9,0x1,0x6a,0xe0,0x70,0xe0,0xf,0x94,0x2e,0xfe,0xc0,0x96,0x80,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0x8,0x95,0x1f,0x93,0x18,0x2f,0x8e,0xe6,0x92,0xee,0x60,0xe0,0xf,0x94,0xc2,0xf1,0x10,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0xf,0x94,0xdc,0xf1,0x1f,0x91,0x8,0x95,0x2f,0x92,0x3f,0x92,0x4f,0x92,0x5f,0x92,0x6f,0x92,0x7f,0x92,0x8f,0x92,0x9f,0x92,0xaf,0x92,0xbf,0x92,0xcf,0x92,0xdf,0x92,0xef,0x92,0xff,0x92,0xf,0x93,0x1f,0x93,0xdf,0x93,0xcf,0x93,0xcd,0xb7,0xde,0xb7,0x62,0x97,0xf,0xb6,0xf8,0x94,0xde,0xbf,0xf,0xbe,0xcd,0xbf,0x38,0x2e,0x62,0x2e,0xca,0x1,0xdb,0x1,0x5c,0x1,0x6d,0x1,0x77,0x24,0x20,0xe2,0x22,0x2e,0x2e,0x1,0x8,0x94,0x41,0x1c,0x51,0x1c,0x8b,0xc0,0x81,0xe0,0xa8,0x16,0x80,0xe0,0xb8,0x6,0x81,0xe0,0xc8,0x6,0x80,0xe0,0xd8,0x6,0x28,0xf0,0xc6,0x1,0xaa,0x27,0xbb,0x27,0xf,0x94,0xd,0xf2,0xbb,0x27,0xad,0x2d,0x9c,0x2d,0x8b,0x2d,0xf,0x94,0xd,0xf2,0x8a,0x2d,0xf,0x94,0xd,0xf2,0x20,0x92,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0x9d,0xe2,0x90,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0x20,0x92,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0x19,0x82,0x86,0x1,0x75,0x1,0x88,0x24,0x99,0x24,0xa1,0xe0,0x3a,0x16,0x51,0xf0,0x3a,0x16,0x20,0xf0,0xb2,0xe0,0x3b,0x16,0x61,0xf4,0x9,0xc0,0xb,0xbf,0xf7,0x1,0x77,0x90,0x7,0xc0,0xc7,0x1,0xf,0x94,0x77,0xfe,0x78,0x2e,0x2,0xc0,0xf7,0x1,0x70,0x80,0x87,0x2d,0xf,0x94,0xd,0xf2,0x20,0x92,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0x87,0x2d,0x80,0x52,0xf4,0x1,0xef,0x70,0xf0,0x70,0x8f,0x35,0x20,0xf4,0xe4,0xd,0xf5,0x1d,0x70,0x82,0x4,0xc0,0xe4,0xd,0xf5,0x1d,0x8e,0xe2,0x80,0x83,0x8,0x94,0xe1,0x1c,0xf1,0x1c,0x1,0x1d,0x11,0x1d,0x8,0x94,0x81,0x1c,0x91,0x1c,0x90,0xe1,0x89,0x16,0x91,0x4,0x9,0xf0,0xc2,0xcf,0x80,0xe1,0x90,0xe0,0xa0,0xe0,0xb0,0xe0,0xa8,0xe,0xb9,0x1e,0xca,0x1e,0xdb,0x1e,0x19,0x8a,0xc2,0x1,0xf,0x94,0xfa,0xf1,0xf,0x94,0xdc,0xf1,0x6a,0x94,0x66,0x20,0x9,0xf0,0x72,0xcf,0x62,0x96,0xf,0xb6,0xf8,0x94,0xde,0xbf,0xf,0xbe,0xcd,0xbf,0xcf,0x91,0xdf,0x91,0x1f,0x91,0xf,0x91,0xff,0x90,0xef,0x90,0xdf,0x90,0xcf,0x90,0xbf,0x90,0xaf,0x90,0x9f,0x90,0x8f,0x90,0x7f,0x90,0x6f,0x90,0x5f,0x90,0x4f,0x90,0x3f,0x90,0x2f,0x90,0x8,0x95,0x2f,0x92,0x3f,0x92,0x4f,0x92,0x5f,0x92,0x6f,0x92,0x7f,0x92,0x8f,0x92,0x9f,0x92,0xaf,0x92,0xbf,0x92,0xcf,0x92,0xdf,0x92,0xef,0x92,0xff,0x92,0xf,0x93,0x1f,0x93,0xdf,0x93,0xcf,0x93,0xcd,0xb7,0xde,0xb7,0xcd,0x53,0xd1,0x40,0xf,0xb6,0xf8,0x94,0xde,0xbf,0xf,0xbe,0xcd,0xbf,0x1,0xe2,0xe,0xbf,0xf,0xef,0xd,0xbf,0x94,0xb7,0xf8,0x94,0xa8,0x95,0x14,0xbe,0x80,0x91,0x60,0x0,0x88,0x61,0x80,0x93,0x60,0x0,0x10,0x92,0x60,0x0,0x78,0x94,0x93,0xff,0x5,0xc0,0xe0,0x91,0x0,0x2,0xf0,0x91,0x1,0x2,0x19,0x95,0x27,0x9a,0x2f,0x9a,0x80,0x91,0xc0,0x0,0x82,0x60,0x80,0x93,0xc0,0x0,0x80,0xe1,0x80,0x93,0xc4,0x0,0x88,0xe1,0x80,0x93,0xc1,0x0,0x0,0x0,0xee,0x24,0xff,0x24,0x87,0x1,0x44,0xe0,0xa4,0x2e,0xb1,0x2c,0xcc,0x24,0xdd,0x24,0x24,0xc0,0xc5,0x1,0x1,0x97,0xf1,0xf7,0x8,0x94,0xe1,0x1c,0xf1,0x1c,0x1,0x1d,0x11,0x1d,0x21,0xe2,0xe2,0x16,0x2e,0xe4,0xf2,0x6,0x20,0xe0,0x2,0x7,0x20,0xe0,0x12,0x7,0x18,0xf0,0x31,0xe0,0xc3,0x2e,0xd1,0x2c,0xc8,0x1,0xb7,0x1,0x27,0xec,0x3b,0xe1,0x40,0xe0,0x50,0xe0,0xf,0x94,0x41,0xfe,0x61,0x15,0x71,0x5,0x81,0x5,0x91,0x5,0x19,0xf4,0x85,0xb1,0x80,0x58,0x85,0xb9,0x80,0x91,0xc0,0x0,0x87,0xfd,0x3,0xc0,0xc1,0x14,0xd1,0x4,0xa9,0xf2,0xa6,0x1,0x4f,0x5f,0x5f,0x4f,0xc2,0x5e,0xde,0x4f,0x59,0x83,0x48,0x83,0xce,0x51,0xd1,0x40,0xc2,0x5e,0xde,0x4f,0x88,0x81,0x99,0x81,0xce,0x51,0xd1,0x40,0x1,0x97,0x11,0xf0,0xd,0x94,0x10,0xfe,0xc0,0x5d,0xde,0x4f,0x19,0x82,0x18,0x82,0xc0,0x53,0xd1,0x40,0x60,0xe0,0xc1,0x5d,0xde,0x4f,0x18,0x82,0xcf,0x52,0xd1,0x40,0x88,0x24,0x99,0x24,0xc3,0x5d,0xde,0x4f,0x19,0x82,0x18,0x82,0xcd,0x52,0xd1,0x40,0xc0,0x5e,0xde,0x4f,0x18,0x82,0x19,0x82,0x1a,0x82,0x1b,0x82,0xc0,0x52,0xd1,0x40,0xce,0x5c,0xde,0x4f,0x18,0x82,0x19,0x82,0x1a,0x82,0x1b,0x82,0xc2,0x53,0xd1,0x40,0xee,0x24,0xff,0x24,0x87,0x1,0xb,0xbf,0xf7,0x1,0x7,0x91,0x16,0x91,0xc4,0x5c,0xde,0x4f,0x19,0x83,0x8,0x83,0xcc,0x53,0xd1,0x40,0xd,0x94,0xb,0xfe,0xc2,0x5e,0xde,0x4f,0x28,0x81,0x39,0x81,0xce,0x51,0xd1,0x40,0x21,0x30,0x31,0x5,0x9,0xf5,0x20,0x91,0xc6,0x0,0xc2,0x5e,0xde,0x4f,0x19,0x82,0x18,0x82,0xce,0x51,0xd1,0x40,0x22,0xc0,0x2f,0x5f,0x3f,0x4f,0x4f,0x4f,0x5f,0x4f,0x21,0x30,0x82,0xe1,0x38,0x7,0x8a,0xe7,0x48,0x7,0x80,0xe0,0x58,0x7,0x80,0xf0,0xc4,0x5c,0xde,0x4f,0xe8,0x81,0xf9,0x81,0xcc,0x53,0xd1,0x40,0xef,0x5f,0xff,0x4f,0x19,0xf0,0xee,0x27,0xff,0x27,0x9,0x94,0x20,0xe0,0x30,0xe0,0x40,0xe0,0x50,0xe0,0x80,0x91,0xc0,0x0,0x87,0xff,0xe0,0xcf,0x20,0x91,0xc6,0x0,0xc3,0x5d,0xde,0x4f,0x48,0x81,0x59,0x81,0xcd,0x52,0xd1,0x40,0x4f,0x5f,0x5f,0x4f,0xc3,0x5d,0xde,0x4f,0x59,0x83,0x48,0x83,0xcd,0x52,0xd1,0x40,0x21,0x32,0x9,0xf0,0x63,0xc6,0x4a,0x30,0x51,0x5,0x8,0xf0,0x5f,0xc6,0x8,0x94,0x81,0x1c,0x91,0x1c,0x53,0xe0,0x85,0x16,0x91,0x4,0x9,0xf0,0x59,0xc6,0x0,0xe0,0x10,0xe0,0x18,0xc0,0x81,0xe2,0x80,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0x2f,0x5f,0x3f,0x4f,0x29,0x31,0x31,0x5,0x79,0xf7,0xf,0x94,0xdc,0xf1,0xf,0x5f,0x1f,0x4f,0x5,0x30,0x11,0x5,0x19,0xf0,0x20,0xe0,0x30,0xe0,0xe5,0xcf,0x10,0x92,0xa,0x2,0x10,0x92,0xb,0x2,0x10,0x92,0xc,0x2,0x10,0x92,0xd,0x2,0x10,0x92,0x6,0x2,0x10,0x92,0x7,0x2,0x10,0x92,0x8,0x2,0x10,0x92,0x9,0x2,0x10,0x92,0x2,0x2,0x10,0x92,0x3,0x2,0x10,0x92,0x4,0x2,0x10,0x92,0x5,0x2,0x8f,0xee,0x90,0xee,0x60,0xe0,0xf,0x94,0xf5,0xf1,0x80,0xe1,0x91,0xee,0x60,0xe0,0xf,0x94,0xc2,0xf1,0x80,0x91,0xc0,0x0,0x87,0xff,0xfc,0xcf,0x90,0x91,0xc6,0x0,0x90,0x36,0x8,0xf0,0x9f,0x75,0x90,0x32,0xb8,0xf0,0x90,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0xa0,0xe2,0xa0,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0x98,0x34,0x9,0xf4,0xd7,0xc1,0x99,0x34,0xb8,0xf4,0x92,0x34,0x9,0xf4,0x59,0xc1,0x93,0x34,0x58,0xf4,0x90,0x33,0x19,0xf1,0x90,0x33,0x8,0xf4,0xe3,0xc5,0x9f,0x33,0xa1,0xf1,0x90,0x34,0x9,0xf0,0xde,0xc5,0xbd,0xc0,0x95,0x34,0x9,0xf4,0x70,0xc1,0x96,0x34,0x9,0xf0,0xd7,0xc5,0x98,0xc1,0x92,0x35,0x9,0xf4,0x2b,0xc2,0x93,0x35,0x38,0xf4,0x9c,0x34,0x9,0xf4,0xf5,0xc1,0x91,0x35,0x9,0xf0,0xcb,0xc5,0x18,0xc2,0x96,0x35,0x9,0xf4,0x45,0xc2,0x99,0x35,0x9,0xf0,0xc4,0xc5,0x67,0xc4,0x83,0xe7,0x92,0xee,0x62,0xe0,0xf,0x94,0xf5,0xf1,0x10,0x92,0x6,0x2,0x10,0x92,0x7,0x2,0x10,0x92,0x8,0x2,0x10,0x92,0x9,0x2,0x10,0x92,0xa,0x2,0x10,0x92,0xb,0x2,0x10,0x92,0xc,0x2,0x10,0x92,0xd,0x2,0x13,0xc1,0x8f,0xe7,0x92,0xee,0x62,0xe0,0xf,0x94,0xf5,0xf1,0x8f,0xee,0x90,0xee,0x60,0xe0,0xf,0x94,0xf5,0xf1,0x81,0xe2,0x91,0xee,0x60,0xe0,0xf,0x94,0xc2,0xf1,0x87,0xeb,0x91,0xee,0x60,0xe0,0xf,0x94,0xf5,0xf1,0x80,0xe3,0x91,0xee,0x60,0xe0,0xf,0x94,0xc2,0xf1,0x84,0xee,0x90,0xee,0x60,0xe0,0xf,0x94,0xf5,0xf1,0x8f,0xe3,0x91,0xee,0x60,0xe0,0xf,0x94,0xc2,0xf1,0x86,0xe0,0x90,0xe0,0x61,0xe0,0x70,0xe0,0xf,0x94,0x34,0xf2,0xf,0x94,0xdc,0xf1,0x8d,0xe5,0x91,0xee,0x60,0xe0,0xf,0x94,0xc2,0xf1,0x89,0xec,0x91,0xee,0x60,0xe0,0xf,0x94,0xf5,0xf1,0x8e,0xe4,0x91,0xee,0x60,0xe0,0xf,0x94,0xc2,0xf1,0x83,0xec,0x91,0xee,0x60,0xe0,0xf,0x94,0xf5,0xf1,0x8c,0xe6,0x91,0xee,0x60,0xe0,0xf,0x94,0xc2,0xf1,0x8e,0xe1,0xf,0x94,0xd,0xf2,0x88,0xe9,0xf,0x94,0xd,0xf2,0x81,0xe0,0xf,0x94,0xd,0xf2,0xf,0x94,0xdc,0xf1,0x8b,0xe7,0x91,0xee,0x60,0xe0,0xf,0x94,0xc2,0xf1,0x19,0xe0,0xe0,0xe0,0xf0,0xe0,0x10,0x93,0x57,0x0,0xe4,0x91,0x8e,0x2f,0xf,0x94,0xd,0xf2,0xf,0x94,0xdc,0xf1,0x8a,0xe8,0x91,0xee,0x60,0xe0,0xf,0x94,0xc2,0xf1,0xe3,0xe0,0xf0,0xe0,0x10,0x93,0x57,0x0,0xe4,0x91,0x8e,0x2f,0xf,0x94,0xd,0xf2,0xf,0x94,0xdc,0xf1,0x89,0xe9,0x91,0xee,0x60,0xe0,0xf,0x94,0xc2,0xf1,0xe2,0xe0,0xf0,0xe0,0x10,0x93,0x57,0x0,0xe4,0x91,0x8e,0x2f,0xf,0x94,0xd,0xf2,0xf,0x94,0xdc,0xf1,0x88,0xea,0x91,0xee,0x60,0xe0,0xf,0x94,0xc2,0xf1,0xe1,0xe0,0xf0,0xe0,0x10,0x93,0x57,0x0,0x14,0x91,0x81,0x2f,0xf,0x94,0xd,0xf2,0xf,0x94,0xdc,0xf1,0x7,0xcf,0x8b,0xe8,0x92,0xee,0x62,0xe0,0xf,0x94,0xf5,0xf1,0x8b,0xe4,0x92,0xee,0x60,0xe0,0xf,0x94,0xf5,0xf1,0xf,0x94,0xdc,0xf1,0x0,0xe0,0x10,0xe0,0x19,0xc0,0xc8,0x1,0x6f,0x2d,0xf,0x94,0x7f,0xfe,0xff,0x20,0x31,0xf4,0x89,0xe4,0x92,0xee,0x60,0xe0,0xf,0x94,0xc2,0xf1,0xb,0xc0,0xf0,0x92,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0xf,0x5f,0x1f,0x4f,0xc8,0x1,0x81,0x51,0x9f,0x41,0xa0,0xe0,0xb0,0xe0,0xab,0xbf,0xfc,0x1,0xf7,0x90,0xba,0xe2,0xfb,0x16,0x21,0xf0,0xe2,0xe0,0x0,0x30,0x1e,0x7,0xc1,0xf6,0xf,0x94,0xdc,0xf1,0xf,0x94,0xdc,0xf1,0x87,0xe5,0x92,0xee,0x60,0xe0,0xf,0x94,0xf5,0xf1,0xf,0x94,0xdc,0xf1,0xcc,0x24,0xdd,0x24,0x0,0xe0,0x10,0xe0,0x1e,0xc0,0xc8,0x1,0xf,0x94,0x77,0xfe,0xf8,0x2e,0x88,0x23,0x31,0xf4,0x89,0xe4,0x92,0xee,0x60,0xe0,0xf,0x94,0xc2,0xf1,0xb,0xc0,0x80,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0xfe,0x14,0x19,0xf0,0x8,0x94,0xc1,0x1c,0xd1,0x1c,0xf,0x5f,0x1f,0x4f,0xc8,0x1,0x81,0x51,0x9f,0x41,0xa0,0xe0,0xb0,0xe0,0xab,0xbf,0xfc,0x1,0xe7,0x90,0xfa,0xe2,0xef,0x16,0x21,0xf0,0x22,0xe0,0x0,0x30,0x12,0x7,0x99,0xf6,0xf,0x94,0xdc,0xf1,0xf,0x94,0xdc,0xf1,0x82,0xe6,0x92,0xee,0x60,0xe0,0xf,0x94,0xc2,0xf1,0xc6,0x1,0x61,0xe0,0x70,0xe0,0xf,0x94,0x34,0xf2,0xf,0x94,0xdc,0xf1,0xf,0x94,0xdc,0xf1,0x10,0x92,0x2,0x2,0x10,0x92,0x3,0x2,0x10,0x92,0x4,0x2,0x10,0x92,0x5,0x2,0x78,0xce,0x89,0xe9,0x92,0xee,0x62,0xe0,0xf,0x94,0xf5,0xf1,0x27,0x9a,0x2f,0x9a,0x16,0xc0,0x2f,0x98,0x80,0xe0,0x90,0xe0,0xe0,0xed,0xf7,0xe0,0x31,0x97,0xf1,0xf7,0x1,0x96,0x84,0x36,0x91,0x5,0xc1,0xf7,0x2f,0x9a,0x80,0xe0,0x90,0xe0,0xe0,0xed,0xf7,0xe0,0x31,0x97,0xf1,0xf7,0x1,0x96,0x84,0x36,0x91,0x5,0xc1,0xf7,0x80,0x91,0xc0,0x0,0x87,0xff,0xe6,0xcf,0x80,0x91,0xc0,0x0,0x87,0xff,0xfc,0xcf,0x64,0xc4,0x85,0xea,0x92,0xee,0x62,0xe0,0xf,0x94,0xf5,0xf1,0x40,0x91,0x2,0x2,0x50,0x91,0x3,0x2,0x60,0x91,0x4,0x2,0x70,0x91,0x5,0x2,0x81,0xe0,0x20,0xe1,0xf,0x94,0x91,0xf2,0x80,0x91,0x2,0x2,0x90,0x91,0x3,0x2,0xa0,0x91,0x4,0x2,0xb0,0x91,0x5,0x2,0x80,0x50,0x9f,0x4f,0xaf,0x4f,0xbf,0x4f,0x80,0x93,0x2,0x2,0x90,0x93,0x3,0x2,0xa0,0x93,0x4,0x2,0xb0,0x93,0x5,0x2,0x80,0x50,0x90,0x41,0xa0,0x40,0xb0,0x40,0x8,0xf4,0x26,0xce,0xa4,0xcf,0x83,0xeb,0x92,0xee,0x62,0xe0,0xf,0x94,0xf5,0xf1,0x40,0x91,0x6,0x2,0x50,0x91,0x7,0x2,0x60,0x91,0x8,0x2,0x70,0x91,0x9,0x2,0x80,0xe0,0x20,0xe1,0xf,0x94,0x91,0xf2,0x80,0x91,0x6,0x2,0x90,0x91,0x7,0x2,0xa0,0x91,0x8,0x2,0xb0,0x91,0x9,0x2,0x80,0x50,0x9f,0x4f,0xaf,0x4f,0xbf,0x4f,0x80,0x93,0x6,0x2,0x90,0x93,0x7,0x2,0xa0,0x93,0x8,0x2,0xb0,0x93,0x9,0x2,0xff,0xcd,0x80,0xec,0x92,0xee,0x62,0xe0,0xf,0x94,0xf5,0xf1,0x83,0xe7,0x92,0xee,0x60,0xe0,0xf,0x94,0xf5,0xf1,0x8f,0xe7,0x92,0xee,0x60,0xe0,0xf,0x94,0xf5,0xf1,0x8b,0xe8,0x92,0xee,0x60,0xe0,0xf,0x94,0xf5,0xf1,0x89,0xe9,0x92,0xee,0x60,0xe0,0xf,0x94,0xf5,0xf1,0x85,0xea,0x92,0xee,0x60,0xe0,0xf,0x94,0xf5,0xf1,0x83,0xeb,0x92,0xee,0x60,0xe0,0xf,0x94,0xf5,0xf1,0x80,0xec,0x92,0xee,0x60,0xe0,0xf,0x94,0xf5,0xf1,0x87,0xec,0x92,0xee,0x60,0xe0,0xf,0x94,0xf5,0xf1,0x88,0xed,0x92,0xee,0x60,0xe0,0xf,0x94,0xf5,0xf1,0x8f,0xed,0x92,0xee,0x60,0xe0,0xf,0x94,0xf5,0xf1,0x8a,0xee,0x92,0xee,0x60,0xe0,0xf,0x94,0xf5,0xf1,0x83,0xe0,0x93,0xee,0xbd,0xcd,0x87,0xec,0x92,0xee,0x62,0xe0,0xf,0x94,0xf5,0xf1,0x81,0xe4,0xf,0x94,0x7b,0xf2,0x82,0xe4,0xf,0x94,0x7b,0xf2,0x83,0xe4,0xf,0x94,0x7b,0xf2,0x84,0xe4,0xf,0x94,0x7b,0xf2,0x85,0xe4,0xf,0x94,0x7b,0xf2,0x86,0xe4,0xf,0x94,0x7b,0xf2,0x87,0xe4,0xf,0x94,0x7b,0xf2,0x88,0xe4,0xf,0x94,0x7b,0xf2,0x8a,0xe4,0xf,0x94,0x7b,0xf2,0x8b,0xe4,0xf,0x94,0x7b,0xf2,0x8c,0xe4,0xf,0x94,0x7b,0xf2,0x99,0xcd,0x88,0xed,0x92,0xee,0x62,0xe0,0xf,0x94,0xf5,0xf1,0x77,0x24,0x73,0x94,0x88,0x24,0x99,0x24,0x9,0xc4,0x8f,0xed,0x92,0xee,0x62,0xe0,0xf,0x94,0xf5,0xf1,0x40,0x91,0xa,0x2,0x50,0x91,0xb,0x2,0x60,0x91,0xc,0x2,0x70,0x91,0xd,0x2,0x82,0xe0,0x20,0xe1,0xf,0x94,0x91,0xf2,0x80,0x91,0xa,0x2,0x90,0x91,0xb,0x2,0xa0,0x91,0xc,0x2,0xb0,0x91,0xd,0x2,0x80,0x50,0x9f,0x4f,0xaf,0x4f,0xbf,0x4f,0x80,0x93,0xa,0x2,0x90,0x93,0xb,0x2,0xa0,0x93,0xc,0x2,0xb0,0x93,0xd,0x2,0x69,0xcd,0x8a,0xee,0x92,0xee,0x62,0xe0,0xf,0x94,0xf5,0xf1,0x84,0xee,0x90,0xee,0x60,0xe0,0xf,0x94,0xf5,0xf1,0x8f,0xec,0x91,0xee,0x60,0xe0,0xf,0x94,0xf5,0xf1,0x66,0x24,0x77,0x24,0x43,0x1,0xcc,0x5d,0xde,0x4f,0x19,0x82,0x18,0x82,0xc4,0x52,0xd1,0x40,0xd4,0x1,0xc3,0x1,0xb6,0x95,0xa7,0x95,0x97,0x95,0x87,0x95,0xca,0x5d,0xde,0x4f,0x88,0x83,0x99,0x83,0xaa,0x83,0xbb,0x83,0xc6,0x52,0xd1,0x40,0xcc,0x5d,0xde,0x4f,0xa8,0x81,0xb9,0x81,0xc4,0x52,0xd1,0x40,0x11,0x96,0xcc,0x5d,0xde,0x4f,0xb9,0x83,0xa8,0x83,0xc4,0x52,0xd1,0x40,0xcd,0x1,0x62,0xe0,0x70,0xe0,0xf,0x94,0x34,0xf2,0xb0,0xe2,0xb0,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0xed,0xe2,0xe0,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0xf0,0xe2,0xf0,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0xca,0x5d,0xde,0x4f,0xe8,0x80,0xf9,0x80,0xa,0x81,0x1b,0x81,0xc6,0x52,0xd1,0x40,0xbb,0x27,0xa1,0x2f,0x90,0x2f,0x8f,0x2d,0xf,0x94,0xd,0xf2,0xca,0x5d,0xde,0x4f,0x88,0x81,0xc6,0x52,0xd1,0x40,0xf,0x94,0xd,0xf2,0xb0,0xe2,0xfb,0x2e,0xf0,0x92,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0xd,0xe3,0x0,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0x10,0xe2,0x10,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0x8b,0xbe,0xf3,0x1,0x27,0x91,0xc6,0x5d,0xde,0x4f,0x28,0x83,0xca,0x52,0xd1,0x40,0xa2,0x2e,0xbb,0x24,0xcc,0x24,0xdd,0x24,0x8,0x94,0x61,0x1c,0x71,0x1c,0x81,0x1c,0x91,0x1c,0x8b,0xbe,0xf3,0x1,0x87,0x91,0x28,0x2e,0x33,0x24,0x44,0x24,0x55,0x24,0x8,0x94,0x61,0x1c,0x71,0x1c,0x81,0x1c,0x91,0x1c,0x8b,0xbe,0xf3,0x1,0x37,0x91,0xc5,0x5d,0xde,0x4f,0x38,0x83,0xcb,0x52,0xd1,0x40,0x8,0x94,0x61,0x1c,0x71,0x1c,0x81,0x1c,0x91,0x1c,0x8b,0xbe,0xf3,0x1,0x47,0x91,0xc4,0x5d,0xde,0x4f,0x48,0x83,0xcc,0x52,0xd1,0x40,0xad,0xef,0xea,0x2e,0xaf,0xef,0xfa,0x2e,0xaf,0xef,0xa,0x2f,0xaf,0xef,0x1a,0x2f,0x6e,0xc,0x7f,0x1c,0x80,0x1e,0x91,0x1e,0x14,0x2d,0x3,0x2d,0xf2,0x2c,0xee,0x24,0xea,0xc,0xfb,0x1c,0xc,0x1d,0x1d,0x1d,0xf,0x94,0xd,0xf2,0x20,0xe2,0x20,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0xc6,0x5d,0xde,0x4f,0x88,0x81,0xca,0x52,0xd1,0x40,0xf,0x94,0xd,0xf2,0x30,0xe2,0x30,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0xc4,0x5d,0xde,0x4f,0x88,0x81,0xcc,0x52,0xd1,0x40,0xf,0x94,0xd,0xf2,0x40,0xe2,0x40,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0xc5,0x5d,0xde,0x4f,0x88,0x81,0xcb,0x52,0xd1,0x40,0xf,0x94,0xd,0xf2,0x50,0xe2,0x50,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0x8f,0xef,0xe8,0x16,0x8f,0xef,0xf8,0x6,0x80,0xe0,0x8,0x7,0x80,0xe0,0x18,0x7,0x31,0xf4,0x84,0xe0,0x92,0xee,0x60,0xe0,0xf,0x94,0xc2,0xf1,0xdf,0xc0,0xd8,0x1,0xc7,0x1,0x80,0x70,0x90,0x7c,0xa0,0x70,0xb0,0x70,0x80,0x50,0x90,0x4c,0xa0,0x40,0xb0,0x40,0xd1,0xf5,0x2f,0xef,0x3f,0xe3,0x40,0xe0,0x50,0xe0,0xe2,0x22,0xf3,0x22,0x4,0x23,0x15,0x23,0xca,0x5d,0xde,0x4f,0xa8,0x80,0xb9,0x80,0xca,0x80,0xdb,0x80,0xc6,0x52,0xd1,0x40,0xae,0xc,0xbf,0x1c,0xc0,0x1e,0xd1,0x1e,0xaa,0xc,0xbb,0x1c,0xcc,0x1c,0xdd,0x1c,0x8e,0xe0,0x92,0xee,0x60,0xe0,0xf,0x94,0xc2,0xf1,0xbb,0x27,0xa1,0x2f,0x90,0x2f,0x8f,0x2d,0xf,0x94,0xd,0xf2,0x8e,0x2d,0xf,0x94,0xd,0xf2,0x30,0xe2,0x30,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0x4e,0xe3,0x40,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x87,0xc0,0x8e,0xe0,0x9e,0xef,0xa0,0xe0,0xb0,0xe0,0xe8,0x22,0xf9,0x22,0xa,0x23,0x1b,0x23,0x9c,0xe0,0xe9,0x16,0x94,0xe9,0xf9,0x6,0x90,0xe0,0x9,0x7,0x90,0xe0,0x19,0x7,0x9,0xf0,0x88,0xc0,0xc4,0x5d,0xde,0x4f,0xa8,0x81,0xcc,0x52,0xd1,0x40,0xea,0x2e,0xff,0x24,0x0,0xe0,0x10,0xe0,0x10,0x2f,0xf,0x2d,0xfe,0x2c,0xee,0x24,0xc5,0x5d,0xde,0x4f,0xb8,0x81,0xcb,0x52,0xd1,0x40,0xeb,0xe,0xf1,0x1c,0x1,0x1d,0x11,0x1d,0xd6,0x1,0xc5,0x1,0x81,0x70,0x90,0x70,0xa0,0x70,0xb0,0x70,0xdc,0x1,0x99,0x27,0x88,0x27,0xe8,0xe,0xf9,0x1e,0xa,0x1f,0x1b,0x1f,0x20,0xef,0x30,0xe0,0x40,0xe0,0x50,0xe0,0xa2,0x22,0xb3,0x22,0xc4,0x22,0xd5,0x22,0x41,0xe1,0xaa,0xc,0xbb,0x1c,0xcc,0x1c,0xdd,0x1c,0x4a,0x95,0xd1,0xf7,0xea,0xc,0xfb,0x1c,0xc,0x1d,0x1d,0x1d,0x81,0xe0,0x90,0xe0,0xa0,0xe0,0xb0,0xe0,0x28,0x22,0x39,0x22,0x4a,0x22,0x5b,0x22,0x35,0xe1,0x22,0xc,0x33,0x1c,0x44,0x1c,0x55,0x1c,0x3a,0x95,0xd1,0xf7,0xe2,0xc,0xf3,0x1c,0x4,0x1d,0x15,0x1d,0x57,0x1,0x68,0x1,0xaa,0xc,0xbb,0x1c,0xcc,0x1c,0xdd,0x1c,0x85,0xe1,0x92,0xee,0x60,0xe0,0xf,0x94,0xc2,0xf1,0xc8,0x1,0xaa,0x27,0xbb,0x27,0xf,0x94,0xd,0xf2,0xbb,0x27,0xa1,0x2f,0x90,0x2f,0x8f,0x2d,0xf,0x94,0xd,0xf2,0x8e,0x2d,0xf,0x94,0xd,0xf2,0x90,0xe2,0x90,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0xae,0xe3,0xa0,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0xc6,0x1,0xaa,0x27,0xbb,0x27,0xf,0x94,0xd,0xf2,0xbb,0x27,0xad,0x2d,0x9c,0x2d,0x8b,0x2d,0xf,0x94,0xd,0xf2,0x8a,0x2d,0xf,0x94,0xd,0xf2,0xf,0x94,0xdc,0xf1,0xcc,0x5d,0xde,0x4f,0xe8,0x81,0xf9,0x81,0xc4,0x52,0xd1,0x40,0xf9,0x97,0x9,0xf4,0x4d,0xcb,0xf4,0xe0,0xef,0x2e,0xf1,0x2c,0x1,0x2d,0x11,0x2d,0x6e,0xc,0x7f,0x1c,0x80,0x1e,0x91,0x1e,0xf2,0xcd,0x83,0xe0,0x93,0xee,0x62,0xe0,0xf,0x94,0xf5,0xf1,0x8a,0xe1,0x92,0xee,0x60,0xe0,0xf,0x94,0xc2,0xf1,0x80,0x91,0xc0,0x0,0x87,0xff,0xfc,0xcf,0x10,0x91,0xc6,0x0,0x1f,0x75,0x10,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0xf,0x94,0xdc,0xf1,0x81,0x2f,0x81,0x54,0x8a,0x31,0x8,0xf0,0x36,0xc1,0x16,0x34,0x9,0xf4,0x95,0xc0,0x17,0x34,0x90,0xf4,0x13,0x34,0x9,0xf4,0x4e,0xc0,0x14,0x34,0x30,0xf4,0x11,0x34,0xf1,0xf0,0x12,0x34,0x9,0xf0,0x1d,0xc1,0x30,0xc0,0x14,0x34,0x9,0xf4,0x59,0xc0,0x15,0x34,0x9,0xf0,0x16,0xc1,0x6b,0xc0,0x1a,0x34,0x9,0xf4,0xc4,0xc0,0x1b,0x34,0x38,0xf4,0x17,0x34,0x9,0xf4,0x8f,0xc0,0x18,0x34,0x9,0xf0,0xa,0xc1,0xa1,0xc0,0x1b,0x34,0x9,0xf4,0xd2,0xc0,0x1c,0x34,0x9,0xf0,0x3,0xc1,0xe8,0xc0,0x8f,0xef,0x81,0xb9,0xd,0xc0,0x82,0xb1,0x80,0x95,0x82,0xb9,0x80,0xe0,0x90,0xe0,0xe0,0xed,0xf7,0xe0,0x31,0x97,0xf1,0xf7,0x1,0x96,0x88,0x3c,0x91,0x5,0xc1,0xf7,0x80,0x91,0xc0,0x0,0x87,0xff,0xef,0xcf,0x12,0xb8,0xef,0xc0,0x8f,0xef,0x84,0xb9,0xd,0xc0,0x85,0xb1,0x80,0x95,0x85,0xb9,0x80,0xe0,0x90,0xe0,0xe0,0xed,0xf7,0xe0,0x31,0x97,0xf1,0xf7,0x1,0x96,0x88,0x3c,0x91,0x5,0xc1,0xf7,0x80,0x91,0xc0,0x0,0x87,0xff,0xef,0xcf,0x15,0xb8,0xd9,0xc0,0x8f,0xef,0x87,0xb9,0xd,0xc0,0x88,0xb1,0x80,0x95,0x88,0xb9,0x80,0xe0,0x90,0xe0,0xe0,0xed,0xf7,0xe0,0x31,0x97,0xf1,0xf7,0x1,0x96,0x88,0x3c,0x91,0x5,0xc1,0xf7,0x80,0x91,0xc0,0x0,0x87,0xff,0xef,0xcf,0x18,0xb8,0xc3,0xc0,0x8f,0xef,0x8a,0xb9,0xd,0xc0,0x8b,0xb1,0x80,0x95,0x8b,0xb9,0x80,0xe0,0x90,0xe0,0xe0,0xed,0xf7,0xe0,0x31,0x97,0xf1,0xf7,0x1,0x96,0x88,0x3c,0x91,0x5,0xc1,0xf7,0x80,0x91,0xc0,0x0,0x87,0xff,0xef,0xcf,0x1b,0xb8,0xad,0xc0,0x8f,0xef,0x8d,0xb9,0xd,0xc0,0x8e,0xb1,0x80,0x95,0x8e,0xb9,0x80,0xe0,0x90,0xe0,0xe0,0xed,0xf7,0xe0,0x31,0x97,0xf1,0xf7,0x1,0x96,0x88,0x3c,0x91,0x5,0xc1,0xf7,0x80,0x91,0xc0,0x0,0x87,0xff,0xef,0xcf,0x1e,0xb8,0x97,0xc0,0x8f,0xef,0x80,0xbb,0xd,0xc0,0x81,0xb3,0x80,0x95,0x81,0xbb,0x80,0xe0,0x90,0xe0,0xe0,0xed,0xf7,0xe0,0x31,0x97,0xf1,0xf7,0x1,0x96,0x88,0x3c,0x91,0x5,0xc1,0xf7,0x80,0x91,0xc0,0x0,0x87,0xff,0xef,0xcf,0x11,0xba,0x81,0xc0,0x8f,0xef,0x83,0xbb,0xd,0xc0,0x84,0xb3,0x80,0x95,0x84,0xbb,0x80,0xe0,0x90,0xe0,0xe0,0xed,0xf7,0xe0,0x31,0x97,0xf1,0xf7,0x1,0x96,0x88,0x3c,0x91,0x5,0xc1,0xf7,0x80,0x91,0xc0,0x0,0x87,0xff,0xef,0xcf,0x14,0xba,0x6b,0xc0,0x8f,0xef,0x80,0x93,0x1,0x1,0xf,0xc0,0x80,0x91,0x2,0x1,0x80,0x95,0x80,0x93,0x2,0x1,0x80,0xe0,0x90,0xe0,0xe0,0xed,0xf7,0xe0,0x31,0x97,0xf1,0xf7,0x1,0x96,0x88,0x3c,0x91,0x5,0xc1,0xf7,0x80,0x91,0xc0,0x0,0x87,0xff,0xed,0xcf,0x10,0x92,0x2,0x1,0x51,0xc0,0x8f,0xef,0x80,0x93,0x4,0x1,0xf,0xc0,0x80,0x91,0x5,0x1,0x80,0x95,0x80,0x93,0x5,0x1,0x80,0xe0,0x90,0xe0,0xe0,0xed,0xf7,0xe0,0x31,0x97,0xf1,0xf7,0x1,0x96,0x88,0x3c,0x91,0x5,0xc1,0xf7,0x80,0x91,0xc0,0x0,0x87,0xff,0xed,0xcf,0x10,0x92,0x5,0x1,0x37,0xc0,0x8f,0xef,0x80,0x93,0x7,0x1,0xf,0xc0,0x80,0x91,0x8,0x1,0x80,0x95,0x80,0x93,0x8,0x1,0x80,0xe0,0x90,0xe0,0xe0,0xed,0xf7,0xe0,0x31,0x97,0xf1,0xf7,0x1,0x96,0x88,0x3c,0x91,0x5,0xc1,0xf7,0x80,0x91,0xc0,0x0,0x87,0xff,0xed,0xcf,0x10,0x92,0x8,0x1,0x1d,0xc0,0x8f,0xef,0x80,0x93,0xa,0x1,0xf,0xc0,0x80,0x91,0xb,0x1,0x80,0x95,0x80,0x93,0xb,0x1,0x80,0xe0,0x90,0xe0,0xe0,0xed,0xf7,0xe0,0x31,0x97,0xf1,0xf7,0x1,0x96,0x88,0x3c,0x91,0x5,0xc1,0xf7,0x80,0x91,0xc0,0x0,0x87,0xff,0xed,0xcf,0x10,0x92,0xb,0x1,0x3,0xc0,0x85,0xe2,0x92,0xee,0xee,0xc9,0x80,0x91,0xc0,0x0,0x87,0xff,0xfc,0xcf,0x80,0x91,0xc6,0x0,0xea,0xc9,0x88,0xe3,0x92,0xee,0xe4,0xc9,0x8c,0xe1,0x91,0xee,0xe1,0xc9,0x88,0x24,0x99,0x24,0x93,0x30,0x11,0xf1,0x94,0x30,0x28,0xf4,0x91,0x30,0x89,0xf0,0x92,0x30,0xb8,0xf4,0x8,0xc0,0x95,0x30,0x61,0xf1,0x95,0x30,0xf0,0xf0,0x96,0x30,0x9,0xf0,0x48,0xc0,0x43,0xc0,0x2b,0x31,0x9,0xf0,0x42,0xc9,0x91,0xe0,0x6b,0xe1,0x3f,0xc9,0x62,0x27,0xc1,0x5d,0xde,0x4f,0x28,0x83,0xcf,0x52,0xd1,0x40,0x92,0xe0,0x37,0xc9,0xb2,0x2f,0xa0,0xe0,0x62,0x27,0x93,0xe0,0x32,0xc9,0x82,0x2f,0x90,0xe0,0xa8,0x2b,0xb9,0x2b,0x62,0x27,0x94,0xe0,0x2b,0xc9,0x2e,0x30,0x9,0xf0,0x39,0xc3,0x62,0x27,0x95,0xe0,0xc0,0x5d,0xde,0x4f,0x19,0x82,0x18,0x82,0xc0,0x53,0xd1,0x40,0x1f,0xc9,0xe1,0xe0,0xf0,0xe0,0xec,0xf,0xfd,0x1f,0xc0,0x5d,0xde,0x4f,0x8,0x81,0x19,0x81,0xc0,0x53,0xd1,0x40,0xe0,0xf,0xf1,0x1f,0x20,0x83,0xf,0x5f,0x1f,0x4f,0xc0,0x5d,0xde,0x4f,0x19,0x83,0x8,0x83,0xc0,0x53,0xd1,0x40,0x62,0x27,0xa,0x17,0x1b,0x7,0x9,0xf0,0x5,0xc9,0xd8,0x1,0x96,0xe0,0x2,0xc9,0x26,0x17,0x9,0xf0,0x10,0xc3,0x3,0xc0,0x97,0x30,0x9,0xf0,0xfb,0xc8,0x77,0x24,0x99,0x81,0x93,0x31,0x9,0xf4,0x12,0xc1,0x94,0x31,0xc8,0xf4,0x96,0x30,0x9,0xf4,0xd8,0xc0,0x97,0x30,0x50,0xf4,0x92,0x30,0x9,0xf4,0x6,0xc1,0x93,0x30,0x9,0xf4,0x6d,0xc0,0x91,0x30,0x9,0xf0,0x59,0xc2,0x53,0xc0,0x91,0x31,0x9,0xf4,0x77,0xc0,0x92,0x31,0x8,0xf0,0xbb,0xc0,0x90,0x31,0x9,0xf0,0x4f,0xc2,0xf5,0xc0,0x98,0x31,0x9,0xf4,0x87,0xc0,0x99,0x31,0x50,0xf4,0x95,0x31,0x9,0xf4,0xef,0xc0,0x95,0x31,0x8,0xf4,0xc6,0xc1,0x96,0x31,0x9,0xf0,0x40,0xc2,0xc2,0xc1,0x9a,0x31,0x9,0xf4,0x6c,0xc0,0x9a,0x31,0x8,0xf4,0x91,0xc0,0x9b,0x31,0x9,0xf4,0x5b,0xc0,0x9d,0x31,0x9,0xf0,0x33,0xc2,0x9d,0x81,0x90,0x33,0x59,0xf4,0x8f,0x81,0x88,0x23,0x11,0xf4,0x9e,0xe1,0x1c,0xc0,0x81,0x30,0x11,0xf0,0x91,0xe0,0x18,0xc0,0x98,0xe9,0x16,0xc0,0x89,0x2f,0x80,0x75,0x91,0xf0,0x90,0x35,0x39,0xf4,0xe0,0xe0,0xf0,0xe0,0x89,0xe0,0x80,0x93,0x57,0x0,0x94,0x91,0xa,0xc0,0x98,0x35,0x39,0xf4,0xe3,0xe0,0xf0,0xe0,0x89,0xe0,0x80,0x93,0x57,0x0,0x94,0x91,0x1,0xc0,0x90,0xe0,0x1a,0x82,0x1b,0x82,0x8d,0x81,0x8c,0x83,0x1d,0x82,0x9e,0x83,0x1f,0x82,0x27,0xe0,0x30,0xe0,0x9,0xc2,0x1a,0x82,0x88,0xe0,0x8b,0x83,0x81,0xe4,0x8c,0x83,0x86,0xe5,0x8d,0x83,0x82,0xe5,0x8e,0x83,0x89,0xe4,0x8f,0x83,0x83,0xe5,0x88,0x87,0x80,0xe5,0x89,0x87,0x8f,0xe5,0x8a,0x87,0x82,0xe3,0x8b,0x87,0x2b,0xe0,0x30,0xe0,0xf3,0xc1,0x8a,0x81,0x81,0x39,0x41,0xf0,0x82,0x39,0x41,0xf0,0x80,0x39,0x11,0xf4,0x8f,0xe0,0x5,0xc0,0x80,0xe0,0x3,0xc0,0x82,0xe0,0x1,0xc0,0x8a,0xe0,0x1a,0x82,0x8b,0x83,0x44,0xc0,0x77,0x24,0x73,0x94,0x82,0xc0,0x8d,0x81,0x88,0x23,0x11,0xf4,0x8e,0xe1,0x2c,0xc0,0x81,0x30,0x11,0xf0,0x81,0xe0,0x28,0xc0,0x88,0xe9,0x26,0xc0,0x1a,0x82,0xe1,0xe0,0xf0,0xe0,0x89,0xe0,0x80,0x93,0x57,0x0,0x84,0x91,0x8b,0x83,0x1c,0x82,0x24,0xe0,0x30,0xe0,0xc8,0xc1,0x8b,0x81,0x80,0x35,0x89,0xf4,0x8c,0x81,0x88,0x30,0x39,0xf4,0xe2,0xe0,0xf0,0xe0,0x89,0xe0,0x80,0x93,0x57,0x0,0x84,0x91,0xd,0xc0,0xe0,0xe0,0xf0,0xe0,0x89,0xe0,0x80,0x93,0x57,0x0,0x84,0x91,0x6,0xc0,0xe3,0xe0,0xf0,0xe0,0x89,0xe0,0x80,0x93,0x57,0x0,0x84,0x91,0x1a,0x82,0xdf,0xcf,0x8d,0x81,0x83,0x6c,0x99,0xe0,0xe1,0xe0,0xf0,0xe0,0x8,0x2e,0x90,0x93,0x57,0x0,0xe8,0x95,0x7,0xb6,0x0,0xfc,0xfd,0xcf,0x1a,0x82,0x1b,0x82,0x23,0xe0,0x30,0xe0,0x9b,0xc1,0x80,0xec,0x8a,0x83,0xce,0x5c,0xde,0x4f,0x18,0x82,0x19,0x82,0x1a,0x82,0x1b,0x82,0xc2,0x53,0xd1,0x40,0x8e,0xc1,0x8a,0x81,0x90,0xe0,0xa0,0xe0,0xb0,0xe0,0x58,0x2f,0x44,0x27,0x33,0x27,0x22,0x27,0x8b,0x81,0x90,0xe0,0xa0,0xe0,0xb0,0xe0,0xdc,0x1,0x99,0x27,0x88,0x27,0x28,0x2b,0x39,0x2b,0x4a,0x2b,0x5b,0x2b,0x8d,0x81,0x90,0xe0,0xa0,0xe0,0xb0,0xe0,0x28,0x2b,0x39,0x2b,0x4a,0x2b,0x5b,0x2b,0x8c,0x81,0x90,0xe0,0xa0,0xe0,0xb0,0xe0,0xba,0x2f,0xa9,0x2f,0x98,0x2f,0x88,0x27,0x28,0x2b,0x39,0x2b,0x4a,0x2b,0x5b,0x2b,0x22,0xf,0x33,0x1f,0x44,0x1f,0x55,0x1f,0xc0,0x5e,0xde,0x4f,0x28,0x83,0x39,0x83,0x4a,0x83,0x5b,0x83,0xc0,0x52,0xd1,0x40,0x1a,0x82,0x59,0xc1,0x3a,0x81,0xc9,0x5c,0xde,0x4f,0x38,0x83,0xc7,0x53,0xd1,0x40,0xca,0x5c,0xde,0x4f,0x18,0x82,0xc6,0x53,0xd1,0x40,0x8b,0x81,0xc8,0x2e,0xdd,0x24,0xca,0x5c,0xde,0x4f,0x48,0x81,0x59,0x81,0xc6,0x53,0xd1,0x40,0xc4,0x2a,0xd5,0x2a,0x93,0x31,0x9,0xf0,0x82,0xc0,0xce,0x5c,0xde,0x4f,0x88,0x81,0x99,0x81,0xaa,0x81,0xbb,0x81,0xc2,0x53,0xd1,0x40,0x80,0x50,0x90,0x4c,0xa3,0x40,0xb0,0x40,0x30,0xf5,0x83,0xe0,0xce,0x5c,0xde,0x4f,0xe8,0x80,0xf9,0x80,0xa,0x81,0x1b,0x81,0xc2,0x53,0xd1,0x40,0xf7,0x1,0x0,0x93,0x5b,0x0,0x80,0x93,0x57,0x0,0xe8,0x95,0x7,0xb6,0x0,0xfc,0xfd,0xcf,0xce,0x5c,0xde,0x4f,0x8,0x81,0x19,0x81,0x2a,0x81,0x3b,0x81,0xc2,0x53,0xd1,0x40,0x0,0x50,0x1f,0x4f,0x2f,0x4f,0x3f,0x4f,0xce,0x5c,0xde,0x4f,0x8,0x83,0x19,0x83,0x2a,0x83,0x3b,0x83,0xc2,0x53,0xd1,0x40,0xc0,0x5e,0xde,0x4f,0x48,0x81,0x59,0x81,0x6a,0x81,0x7b,0x81,0xc0,0x52,0xd1,0x40,0xde,0x1,0x1b,0x96,0x31,0xe0,0x8c,0x91,0x11,0x96,0x2c,0x91,0x11,0x97,0x12,0x96,0xc7,0x5c,0xde,0x4f,0x28,0x83,0xc9,0x53,0xd1,0x40,0xc8,0x5c,0xde,0x4f,0x18,0x82,0xc8,0x53,0xd1,0x40,0x90,0xe0,0xc8,0x5c,0xde,0x4f,0xe8,0x81,0xf9,0x81,0xc8,0x53,0xd1,0x40,0x8e,0x2b,0x9f,0x2b,0xc,0x1,0xfa,0x1,0x60,0x93,0x5b,0x0,0x30,0x93,0x57,0x0,0xe8,0x95,0x11,0x24,0x4e,0x5f,0x5f,0x4f,0x6f,0x4f,0x7f,0x4f,0xe,0xef,0xe0,0x2e,0xf,0xef,0xf0,0x2e,0xce,0xc,0xdf,0x1c,0xc1,0x14,0xd1,0x4,0x99,0xf6,0x85,0xe0,0xc0,0x5e,0xde,0x4f,0x8,0x81,0x19,0x81,0x2a,0x81,0x3b,0x81,0xc0,0x52,0xd1,0x40,0xf8,0x1,0x20,0x93,0x5b,0x0,0x80,0x93,0x57,0x0,0xe8,0x95,0x7,0xb6,0x0,0xfc,0xfd,0xcf,0x81,0xe1,0x80,0x93,0x57,0x0,0xe8,0x95,0x35,0xc0,0xc0,0x5e,0xde,0x4f,0x88,0x81,0x99,0x81,0xaa,0x81,0xbb,0x81,0xc0,0x52,0xd1,0x40,0xb6,0x95,0xa7,0x95,0x97,0x95,0x87,0x95,0x7c,0x1,0x86,0x1,0xab,0xe0,0xaa,0x2e,0xb1,0x2c,0xac,0xe,0xbd,0x1e,0xb,0xc0,0xd5,0x1,0x6d,0x91,0x5d,0x1,0xc7,0x1,0xf,0x94,0x7f,0xfe,0x8,0x94,0xe1,0x1c,0xf1,0x1c,0x1,0x50,0x10,0x40,0x1,0x15,0x11,0x5,0x91,0xf7,0xa6,0x1,0x60,0xe0,0x70,0xe0,0x44,0xf,0x55,0x1f,0x66,0x1f,0x77,0x1f,0xc0,0x5e,0xde,0x4f,0xe8,0x80,0xf9,0x80,0xa,0x81,0x1b,0x81,0xc0,0x52,0xd1,0x40,0x4e,0xd,0x5f,0x1d,0x60,0x1f,0x71,0x1f,0x1a,0x82,0xc0,0x5e,0xde,0x4f,0x48,0x83,0x59,0x83,0x6a,0x83,0x7b,0x83,0xc0,0x52,0xd1,0x40,0x7f,0xc0,0xfa,0x80,0xc5,0x5c,0xde,0x4f,0xf8,0x82,0xcb,0x53,0xd1,0x40,0xc6,0x5c,0xde,0x4f,0x18,0x82,0xca,0x53,0xd1,0x40,0x8b,0x81,0xc8,0x2e,0xdd,0x24,0xc6,0x5c,0xde,0x4f,0x8,0x81,0x19,0x81,0xca,0x53,0xd1,0x40,0xc0,0x2a,0xd1,0x2a,0x1a,0x82,0x89,0x81,0xbe,0x1,0x6d,0x5f,0x7f,0x4f,0x84,0x31,0x21,0xf5,0x96,0x1,0xc0,0x5e,0xde,0x4f,0xe8,0x80,0xf9,0x80,0xa,0x81,0x1b,0x81,0xc0,0x52,0xd1,0x40,0xb,0xbf,0xf7,0x1,0x87,0x91,0x96,0x91,0xdb,0x1,0x8c,0x93,0x11,0x96,0x9c,0x93,0x6e,0x5f,0x7f,0x4f,0xd8,0x1,0xc7,0x1,0x2,0x96,0xa1,0x1d,0xb1,0x1d,0xc0,0x5e,0xde,0x4f,0x88,0x83,0x99,0x83,0xaa,0x83,0xbb,0x83,0xc0,0x52,0xd1,0x40,0x22,0x50,0x30,0x40,0xf1,0xf6,0x36,0xc0,0xc0,0x5e,0xde,0x4f,0x28,0x81,0x39,0x81,0x4a,0x81,0x5b,0x81,0xc0,0x52,0xd1,0x40,0x8,0x94,0xc1,0x8,0xd1,0x8,0x76,0x1,0x0,0xe0,0x10,0xe0,0x8,0x94,0xc1,0x1c,0xd1,0x1c,0x8,0x94,0xe1,0x1c,0xf1,0x1c,0x1,0x1d,0x11,0x1d,0xe2,0xe,0xf3,0x1e,0x4,0x1f,0x15,0x1f,0x21,0xbd,0xbb,0x27,0xa5,0x2f,0x94,0x2f,0x83,0x2f,0x82,0xbd,0x2f,0x5f,0x3f,0x4f,0x4f,0x4f,0x5f,0x4f,0xf8,0x9a,0x80,0xb5,0xdb,0x1,0x8d,0x93,0xbd,0x1,0x2e,0x15,0x3f,0x5,0x40,0x7,0x51,0x7,0x61,0xf7,0xc0,0x5e,0xde,0x4f,0x28,0x83,0x39,0x83,0x4a,0x83,0x5b,0x83,0xc0,0x52,0xd1,0x40,0x96,0x1,0x2d,0x5f,0x3f,0x4f,0xfb,0x1,0x10,0x82,0x4,0xc0,0x80,0xec,0x8a,0x83,0x22,0xe0,0x30,0xe0,0x8b,0xe1,0x80,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0xc1,0x5d,0xde,0x4f,0xf8,0x81,0xcf,0x52,0xd1,0x40,0xf0,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0x43,0x2f,0x30,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0x92,0x2f,0x20,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0x8e,0xe0,0x80,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0x65,0xe1,0xc1,0x5d,0xde,0x4f,0xe8,0x80,0xcf,0x52,0xd1,0x40,0x6e,0x25,0x69,0x27,0x64,0x27,0xfe,0x1,0x31,0x96,0x10,0xc0,0x90,0x81,0x90,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x31,0x96,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0x69,0x27,0x21,0x50,0x30,0x40,0x21,0x15,0x31,0x5,0x69,0xf7,0x60,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0x85,0xb1,0x80,0x58,0x85,0xb9,0x77,0x20,0x81,0xf4,0xc1,0x5d,0xde,0x4f,0x8,0x81,0xcf,0x52,0xd1,0x40,0xf,0x5f,0xc1,0x5d,0xde,0x4f,0x8,0x83,0xcf,0x52,0xd1,0x40,0x90,0xe0,0xa0,0xe0,0xb0,0xe0,0xd,0x94,0x1a,0xf4,0x27,0x98,0x2f,0x98,0x80,0xe0,0x90,0xe0,0x20,0xed,0x37,0xe0,0xf9,0x1,0x31,0x97,0xf1,0xf7,0x1,0x96,0x84,0x36,0x91,0x5,0xc9,0xf7,0x0,0x0,0x80,0x91,0xc0,0x0,0x8d,0x7f,0x80,0x93,0xc0,0x0,0x81,0xe1,0x80,0x93,0x57,0x0,0xe8,0x95,0xee,0x27,0xff,0x27,0x9,0x94,0xff,0xcf,0x90,0xe0,0xd,0x94,0x1a,0xf4,0x97,0xfb,0x9,0x2e,0x7,0x26,0xa,0xd0,0x77,0xfd,0x4,0xd0,0x2e,0xd0,0x6,0xd0,0x0,0x20,0x1a,0xf4,0x70,0x95,0x61,0x95,0x7f,0x4f,0x8,0x95,0xf6,0xf7,0x90,0x95,0x81,0x95,0x9f,0x4f,0x8,0x95,0xa1,0xe2,0x1a,0x2e,0xaa,0x1b,0xbb,0x1b,0xfd,0x1,0xd,0xc0,0xaa,0x1f,0xbb,0x1f,0xee,0x1f,0xff,0x1f,0xa2,0x17,0xb3,0x7,0xe4,0x7,0xf5,0x7,0x20,0xf0,0xa2,0x1b,0xb3,0xb,0xe4,0xb,0xf5,0xb,0x66,0x1f,0x77,0x1f,0x88,0x1f,0x99,0x1f,0x1a,0x94,0x69,0xf7,0x60,0x95,0x70,0x95,0x80,0x95,0x90,0x95,0x9b,0x1,0xac,0x1,0xbd,0x1,0xcf,0x1,0x8,0x95,0xaa,0x1b,0xbb,0x1b,0x51,0xe1,0x7,0xc0,0xaa,0x1f,0xbb,0x1f,0xa6,0x17,0xb7,0x7,0x10,0xf0,0xa6,0x1b,0xb7,0xb,0x88,0x1f,0x99,0x1f,0x5a,0x95,0xa9,0xf7,0x80,0x95,0x90,0x95,0xbc,0x1,0xcd,0x1,0x8,0x95,0xf9,0x99,0xfe,0xcf,0x92,0xbd,0x81,0xbd,0xf8,0x9a,0x99,0x27,0x80,0xb5,0x8,0x95,0x26,0x2f,0xf9,0x99,0xfe,0xcf,0x1f,0xba,0x92,0xbd,0x81,0xbd,0x20,0xbd,0xf,0xb6,0xf8,0x94,0xfa,0x9a,0xf9,0x9a,0xf,0xbe,0x1,0x96,0x8,0x95,0xf8,0x94,0xff,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,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xd,0x94,0x89,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0xd,0x94,0xb2,0xf1,0x41,0x54,0x6d,0x65,0x67,0x61,0x32,0x35,0x36,0x30,0x0,0x41,0x72,0x64,0x75,0x69,0x6e,0x6f,0x20,0x65,0x78,0x70,0x6c,0x6f,0x72,0x65,0x72,0x20,0x73,0x74,0x6b,0x35,0x30,0x30,0x56,0x32,0x20,0x62,0x79,0x20,0x4d,0x4c,0x53,0x0,0x42,0x6f,0x6f,0x74,0x6c,0x6f,0x61,0x64,0x65,0x72,0x3e,0x0,0x48,0x75,0x68,0x3f,0x0,0x43,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x64,0x20,0x6f,0x6e,0x20,0x3d,0x20,0x0,0x43,0x50,0x55,0x20,0x54,0x79,0x70,0x65,0x20,0x20,0x20,0x20,0x3d,0x20,0x0,0x5f,0x5f,0x41,0x56,0x52,0x5f,0x41,0x52,0x43,0x48,0x5f,0x5f,0x3d,0x20,0x0,0x41,0x56,0x52,0x20,0x4c,0x69,0x62,0x43,0x20,0x56,0x65,0x72,0x3d,0x20,0x0,0x47,0x43,0x43,0x20,0x56,0x65,0x72,0x73,0x69,0x6f,0x6e,0x20,0x3d,0x20,0x0,0x43,0x50,0x55,0x20,0x49,0x44,0x20,0x20,0x20,0x20,0x20,0x20,0x3d,0x20,0x0,0x4c,0x6f,0x77,0x20,0x66,0x75,0x73,0x65,0x20,0x20,0x20,0x20,0x3d,0x20,0x0,0x48,0x69,0x67,0x68,0x20,0x66,0x75,0x73,0x65,0x20,0x20,0x20,0x3d,0x20,0x0,0x45,0x78,0x74,0x20,0x66,0x75,0x73,0x65,0x20,0x20,0x20,0x20,0x3d,0x20,0x0,0x4c,0x6f,0x63,0x6b,0x20,0x66,0x75,0x73,0x65,0x20,0x20,0x20,0x3d,0x20,0x0,0x4d,0x61,0x72,0x20,0x20,0x37,0x20,0x32,0x30,0x31,0x33,0x0,0x31,0x2e,0x36,0x2e,0x38,0x0,0x34,0x2e,0x33,0x2e,0x35,0x0,0x56,0x23,0x20,0x20,0x20,0x41,0x44,0x44,0x52,0x20,0x20,0x20,0x6f,0x70,0x20,0x63,0x6f,0x64,0x65,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x73,0x74,0x72,0x75,0x63,0x74,0x69,0x6f,0x6e,0x20,0x61,0x64,0x64,0x72,0x20,0x20,0x20,0x49,0x6e,0x74,0x65,0x72,0x72,0x75,0x70,0x74,0x0,0x6e,0x6f,0x20,0x76,0x65,0x63,0x74,0x6f,0x72,0x0,0x72,0x6a,0x6d,0x70,0x20,0x20,0x0,0x6a,0x6d,0x70,0x20,0x0,0x57,0x68,0x61,0x74,0x20,0x70,0x6f,0x72,0x74,0x3a,0x0,0x50,0x6f,0x72,0x74,0x20,0x6e,0x6f,0x74,0x20,0x73,0x75,0x70,0x70,0x6f,0x72,0x74,0x65,0x64,0x0,0x4d,0x75,0x73,0x74,0x20,0x62,0x65,0x20,0x61,0x20,0x6c,0x65,0x74,0x74,0x65,0x72,0x0,0x20,0x0,0x57,0x72,0x69,0x74,0x74,0x69,0x6e,0x67,0x20,0x45,0x45,0x0,0x52,0x65,0x61,0x64,0x69,0x6e,0x67,0x20,0x45,0x45,0x0,0x45,0x45,0x20,0x65,0x72,0x72,0x20,0x63,0x6e,0x74,0x3d,0x0,0x50,0x4f,0x52,0x54,0x0,0x30,0x3d,0x5a,0x65,0x72,0x6f,0x20,0x61,0x64,0x64,0x72,0x0,0x3f,0x3d,0x43,0x50,0x55,0x20,0x73,0x74,0x61,0x74,0x73,0x0,0x40,0x3d,0x45,0x45,0x50,0x52,0x4f,0x4d,0x20,0x74,0x65,0x73,0x74,0x0,0x42,0x3d,0x42,0x6c,0x69,0x6e,0x6b,0x20,0x4c,0x45,0x44,0x0,0x45,0x3d,0x44,0x75,0x6d,0x70,0x20,0x45,0x45,0x50,0x52,0x4f,0x4d,0x0,0x46,0x3d,0x44,0x75,0x6d,0x70,0x20,0x46,0x4c,0x41,0x53,0x48,0x0,0x48,0x3d,0x48,0x65,0x6c,0x70,0x0,0x4c,0x3d,0x4c,0x69,0x73,0x74,0x20,0x49,0x2f,0x4f,0x20,0x50,0x6f,0x72,0x74,0x73,0x0,0x51,0x3d,0x51,0x75,0x69,0x74,0x0,0x52,0x3d,0x44,0x75,0x6d,0x70,0x20,0x52,0x41,0x4d,0x0,0x56,0x3d,0x73,0x68,0x6f,0x77,0x20,0x69,0x6e,0x74,0x65,0x72,0x72,0x75,0x70,0x74,0x20,0x56,0x65,0x63,0x74,0x6f,0x72,0x73,0x0,0x59,0x3d,0x50,0x6f,0x72,0x74,0x20,0x62,0x6c,0x69,0x6e,0x6b,0x0,0x2a,0x0,0x11,0x24,0x1f,0xbe,0xcf,0xef,0xd1,0xe2,0xde,0xbf,0xcd,0xbf,0x1,0xe0,0xc,0xbf,0x12,0xe0,0xa0,0xe0,0xb2,0xe0,0xee,0xe1,0xfd,0xef,0x3,0xe0,0xb,0xbf,0x2,0xc0,0x7,0x90,0xd,0x92,0xa0,0x30,0xb1,0x7,0xd9,0xf7,0x12,0xe0,0xa0,0xe0,0xb2,0xe0,0x1,0xc0,0x1d,0x92,0xae,0x30,0xb1,0x7,0xe1,0xf7,0xf,0x94,0x60,0xf3,0xd,0x94,0x8d,0xfe,0x1,0xe2,0xe,0xbf,0xf,0xef,0xd,0xbf,0x11,0x24,0x1f,0xbe,0xd,0x94,0x60,0xf3,0xd,0x94,0x0,0xf0,0x20,0xe0,0x30,0xe0,0x40,0xed,0x57,0xe0,0x5,0xc0,0xfa,0x1,0x31,0x97,0xf1,0xf7,0x2f,0x5f,0x3f,0x4f,0x28,0x17,0x39,0x7,0xc0,0xf3,0x8,0x95,0x9c,0x1,0x26,0xf,0x31,0x1d,0xc9,0x1,0xa0,0xe0,0xb0,0xe0,0x2f,0x5f,0x3f,0x4f,0xab,0xbf,0xfc,0x1,0x87,0x91,0x88,0x23,0x61,0xf0,0x80,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0xea,0xcf,0x8,0x95,0x8d,0xe0,0x80,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0x8a,0xe0,0x80,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0x8,0x95,0xf,0x94,0xc2,0xf1,0xf,0x94,0xdc,0xf1,0x8,0x95,0xfc,0x1,0x90,0x81,0x99,0x23,0x59,0xf0,0x90,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0x31,0x96,0x99,0x23,0x79,0xf7,0x8,0x95,0x28,0x2f,0x98,0x2f,0x92,0x95,0x9f,0x70,0x89,0x2f,0x80,0x5d,0x8a,0x33,0x8,0xf0,0x89,0x5f,0x80,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0x82,0x2f,0x8f,0x70,0x98,0x2f,0x90,0x5d,0x9a,0x33,0x8,0xf0,0x99,0x5f,0x90,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0x8,0x95,0x9c,0x1,0xfb,0x1,0x85,0x36,0x91,0x5,0x1c,0xf4,0x63,0x30,0x71,0x5,0x94,0xf0,0xc9,0x1,0x64,0xe6,0x70,0xe0,0xf,0x94,0x2e,0xfe,0x60,0x5d,0x7f,0x4f,0x60,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0x2b,0x30,0x31,0x5,0x14,0xf4,0x32,0x97,0xb4,0xf0,0xc9,0x1,0x64,0xe6,0x70,0xe0,0xf,0x94,0x2e,0xfe,0x6a,0xe0,0x70,0xe0,0xf,0x94,0x2e,0xfe,0x60,0x5d,0x7f,0x4f,0x60,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0xc9,0x1,0x6a,0xe0,0x70,0xe0,0xf,0x94,0x2e,0xfe,0xc0,0x96,0x80,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0x8,0x95,0x1f,0x93,0x18,0x2f,0x8e,0xe6,0x92,0xee,0x60,0xe0,0xf,0x94,0xc2,0xf1,0x10,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0xf,0x94,0xdc,0xf1,0x1f,0x91,0x8,0x95,0x2f,0x92,0x3f,0x92,0x4f,0x92,0x5f,0x92,0x6f,0x92,0x7f,0x92,0x8f,0x92,0x9f,0x92,0xaf,0x92,0xbf,0x92,0xcf,0x92,0xdf,0x92,0xef,0x92,0xff,0x92,0xf,0x93,0x1f,0x93,0xdf,0x93,0xcf,0x93,0xcd,0xb7,0xde,0xb7,0x62,0x97,0xf,0xb6,0xf8,0x94,0xde,0xbf,0xf,0xbe,0xcd,0xbf,0x38,0x2e,0x62,0x2e,0xca,0x1,0xdb,0x1,0x5c,0x1,0x6d,0x1,0x77,0x24,0x20,0xe2,0x22,0x2e,0x2e,0x1,0x8,0x94,0x41,0x1c,0x51,0x1c,0x8b,0xc0,0x81,0xe0,0xa8,0x16,0x80,0xe0,0xb8,0x6,0x81,0xe0,0xc8,0x6,0x80,0xe0,0xd8,0x6,0x28,0xf0,0xc6,0x1,0xaa,0x27,0xbb,0x27,0xf,0x94,0xd,0xf2,0xbb,0x27,0xad,0x2d,0x9c,0x2d,0x8b,0x2d,0xf,0x94,0xd,0xf2,0x8a,0x2d,0xf,0x94,0xd,0xf2,0x20,0x92,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0x9d,0xe2,0x90,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0x20,0x92,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0x19,0x82,0x86,0x1,0x75,0x1,0x88,0x24,0x99,0x24,0xa1,0xe0,0x3a,0x16,0x51,0xf0,0x3a,0x16,0x20,0xf0,0xb2,0xe0,0x3b,0x16,0x61,0xf4,0x9,0xc0,0xb,0xbf,0xf7,0x1,0x77,0x90,0x7,0xc0,0xc7,0x1,0xf,0x94,0x77,0xfe,0x78,0x2e,0x2,0xc0,0xf7,0x1,0x70,0x80,0x87,0x2d,0xf,0x94,0xd,0xf2,0x20,0x92,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0x87,0x2d,0x80,0x52,0xf4,0x1,0xef,0x70,0xf0,0x70,0x8f,0x35,0x20,0xf4,0xe4,0xd,0xf5,0x1d,0x70,0x82,0x4,0xc0,0xe4,0xd,0xf5,0x1d,0x8e,0xe2,0x80,0x83,0x8,0x94,0xe1,0x1c,0xf1,0x1c,0x1,0x1d,0x11,0x1d,0x8,0x94,0x81,0x1c,0x91,0x1c,0x90,0xe1,0x89,0x16,0x91,0x4,0x9,0xf0,0xc2,0xcf,0x80,0xe1,0x90,0xe0,0xa0,0xe0,0xb0,0xe0,0xa8,0xe,0xb9,0x1e,0xca,0x1e,0xdb,0x1e,0x19,0x8a,0xc2,0x1,0xf,0x94,0xfa,0xf1,0xf,0x94,0xdc,0xf1,0x6a,0x94,0x66,0x20,0x9,0xf0,0x72,0xcf,0x62,0x96,0xf,0xb6,0xf8,0x94,0xde,0xbf,0xf,0xbe,0xcd,0xbf,0xcf,0x91,0xdf,0x91,0x1f,0x91,0xf,0x91,0xff,0x90,0xef,0x90,0xdf,0x90,0xcf,0x90,0xbf,0x90,0xaf,0x90,0x9f,0x90,0x8f,0x90,0x7f,0x90,0x6f,0x90,0x5f,0x90,0x4f,0x90,0x3f,0x90,0x2f,0x90,0x8,0x95,0x2f,0x92,0x3f,0x92,0x4f,0x92,0x5f,0x92,0x6f,0x92,0x7f,0x92,0x8f,0x92,0x9f,0x92,0xaf,0x92,0xbf,0x92,0xcf,0x92,0xdf,0x92,0xef,0x92,0xff,0x92,0xf,0x93,0x1f,0x93,0xdf,0x93,0xcf,0x93,0xcd,0xb7,0xde,0xb7,0xcd,0x53,0xd1,0x40,0xf,0xb6,0xf8,0x94,0xde,0xbf,0xf,0xbe,0xcd,0xbf,0x1,0xe2,0xe,0xbf,0xf,0xef,0xd,0xbf,0x94,0xb7,0xf8,0x94,0xa8,0x95,0x14,0xbe,0x80,0x91,0x60,0x0,0x88,0x61,0x80,0x93,0x60,0x0,0x10,0x92,0x60,0x0,0x78,0x94,0x93,0xff,0x5,0xc0,0xe0,0x91,0x0,0x2,0xf0,0x91,0x1,0x2,0x19,0x95,0x27,0x9a,0x2f,0x9a,0x80,0x91,0xc0,0x0,0x82,0x60,0x80,0x93,0xc0,0x0,0x80,0xe1,0x80,0x93,0xc4,0x0,0x88,0xe1,0x80,0x93,0xc1,0x0,0x0,0x0,0xee,0x24,0xff,0x24,0x87,0x1,0x44,0xe0,0xa4,0x2e,0xb1,0x2c,0xcc,0x24,0xdd,0x24,0x24,0xc0,0xc5,0x1,0x1,0x97,0xf1,0xf7,0x8,0x94,0xe1,0x1c,0xf1,0x1c,0x1,0x1d,0x11,0x1d,0x21,0xe2,0xe2,0x16,0x2e,0xe4,0xf2,0x6,0x20,0xe0,0x2,0x7,0x20,0xe0,0x12,0x7,0x18,0xf0,0x31,0xe0,0xc3,0x2e,0xd1,0x2c,0xc8,0x1,0xb7,0x1,0x27,0xec,0x3b,0xe1,0x40,0xe0,0x50,0xe0,0xf,0x94,0x41,0xfe,0x61,0x15,0x71,0x5,0x81,0x5,0x91,0x5,0x19,0xf4,0x85,0xb1,0x80,0x58,0x85,0xb9,0x80,0x91,0xc0,0x0,0x87,0xfd,0x3,0xc0,0xc1,0x14,0xd1,0x4,0xa9,0xf2,0xa6,0x1,0x4f,0x5f,0x5f,0x4f,0xc2,0x5e,0xde,0x4f,0x59,0x83,0x48,0x83,0xce,0x51,0xd1,0x40,0xc2,0x5e,0xde,0x4f,0x88,0x81,0x99,0x81,0xce,0x51,0xd1,0x40,0x1,0x97,0x11,0xf0,0xd,0x94,0x10,0xfe,0xc0,0x5d,0xde,0x4f,0x19,0x82,0x18,0x82,0xc0,0x53,0xd1,0x40,0x60,0xe0,0xc1,0x5d,0xde,0x4f,0x18,0x82,0xcf,0x52,0xd1,0x40,0x88,0x24,0x99,0x24,0xc3,0x5d,0xde,0x4f,0x19,0x82,0x18,0x82,0xcd,0x52,0xd1,0x40,0xc0,0x5e,0xde,0x4f,0x18,0x82,0x19,0x82,0x1a,0x82,0x1b,0x82,0xc0,0x52,0xd1,0x40,0xce,0x5c,0xde,0x4f,0x18,0x82,0x19,0x82,0x1a,0x82,0x1b,0x82,0xc2,0x53,0xd1,0x40,0xee,0x24,0xff,0x24,0x87,0x1,0xb,0xbf,0xf7,0x1,0x7,0x91,0x16,0x91,0xc4,0x5c,0xde,0x4f,0x19,0x83,0x8,0x83,0xcc,0x53,0xd1,0x40,0xd,0x94,0xb,0xfe,0xc2,0x5e,0xde,0x4f,0x28,0x81,0x39,0x81,0xce,0x51,0xd1,0x40,0x21,0x30,0x31,0x5,0x9,0xf5,0x20,0x91,0xc6,0x0,0xc2,0x5e,0xde,0x4f,0x19,0x82,0x18,0x82,0xce,0x51,0xd1,0x40,0x22,0xc0,0x2f,0x5f,0x3f,0x4f,0x4f,0x4f,0x5f,0x4f,0x21,0x30,0x82,0xe1,0x38,0x7,0x8a,0xe7,0x48,0x7,0x80,0xe0,0x58,0x7,0x80,0xf0,0xc4,0x5c,0xde,0x4f,0xe8,0x81,0xf9,0x81,0xcc,0x53,0xd1,0x40,0xef,0x5f,0xff,0x4f,0x19,0xf0,0xee,0x27,0xff,0x27,0x9,0x94,0x20,0xe0,0x30,0xe0,0x40,0xe0,0x50,0xe0,0x80,0x91,0xc0,0x0,0x87,0xff,0xe0,0xcf,0x20,0x91,0xc6,0x0,0xc3,0x5d,0xde,0x4f,0x48,0x81,0x59,0x81,0xcd,0x52,0xd1,0x40,0x4f,0x5f,0x5f,0x4f,0xc3,0x5d,0xde,0x4f,0x59,0x83,0x48,0x83,0xcd,0x52,0xd1,0x40,0x21,0x32,0x9,0xf0,0x63,0xc6,0x4a,0x30,0x51,0x5,0x8,0xf0,0x5f,0xc6,0x8,0x94,0x81,0x1c,0x91,0x1c,0x53,0xe0,0x85,0x16,0x91,0x4,0x9,0xf0,0x59,0xc6,0x0,0xe0,0x10,0xe0,0x18,0xc0,0x81,0xe2,0x80,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0x2f,0x5f,0x3f,0x4f,0x29,0x31,0x31,0x5,0x79,0xf7,0xf,0x94,0xdc,0xf1,0xf,0x5f,0x1f,0x4f,0x5,0x30,0x11,0x5,0x19,0xf0,0x20,0xe0,0x30,0xe0,0xe5,0xcf,0x10,0x92,0xa,0x2,0x10,0x92,0xb,0x2,0x10,0x92,0xc,0x2,0x10,0x92,0xd,0x2,0x10,0x92,0x6,0x2,0x10,0x92,0x7,0x2,0x10,0x92,0x8,0x2,0x10,0x92,0x9,0x2,0x10,0x92,0x2,0x2,0x10,0x92,0x3,0x2,0x10,0x92,0x4,0x2,0x10,0x92,0x5,0x2,0x8f,0xee,0x90,0xee,0x60,0xe0,0xf,0x94,0xf5,0xf1,0x80,0xe1,0x91,0xee,0x60,0xe0,0xf,0x94,0xc2,0xf1,0x80,0x91,0xc0,0x0,0x87,0xff,0xfc,0xcf,0x90,0x91,0xc6,0x0,0x90,0x36,0x8,0xf0,0x9f,0x75,0x90,0x32,0xb8,0xf0,0x90,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0xa0,0xe2,0xa0,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0x98,0x34,0x9,0xf4,0xd7,0xc1,0x99,0x34,0xb8,0xf4,0x92,0x34,0x9,0xf4,0x59,0xc1,0x93,0x34,0x58,0xf4,0x90,0x33,0x19,0xf1,0x90,0x33,0x8,0xf4,0xe3,0xc5,0x9f,0x33,0xa1,0xf1,0x90,0x34,0x9,0xf0,0xde,0xc5,0xbd,0xc0,0x95,0x34,0x9,0xf4,0x70,0xc1,0x96,0x34,0x9,0xf0,0xd7,0xc5,0x98,0xc1,0x92,0x35,0x9,0xf4,0x2b,0xc2,0x93,0x35,0x38,0xf4,0x9c,0x34,0x9,0xf4,0xf5,0xc1,0x91,0x35,0x9,0xf0,0xcb,0xc5,0x18,0xc2,0x96,0x35,0x9,0xf4,0x45,0xc2,0x99,0x35,0x9,0xf0,0xc4,0xc5,0x67,0xc4,0x83,0xe7,0x92,0xee,0x62,0xe0,0xf,0x94,0xf5,0xf1,0x10,0x92,0x6,0x2,0x10,0x92,0x7,0x2,0x10,0x92,0x8,0x2,0x10,0x92,0x9,0x2,0x10,0x92,0xa,0x2,0x10,0x92,0xb,0x2,0x10,0x92,0xc,0x2,0x10,0x92,0xd,0x2,0x13,0xc1,0x8f,0xe7,0x92,0xee,0x62,0xe0,0xf,0x94,0xf5,0xf1,0x8f,0xee,0x90,0xee,0x60,0xe0,0xf,0x94,0xf5,0xf1,0x81,0xe2,0x91,0xee,0x60,0xe0,0xf,0x94,0xc2,0xf1,0x87,0xeb,0x91,0xee,0x60,0xe0,0xf,0x94,0xf5,0xf1,0x80,0xe3,0x91,0xee,0x60,0xe0,0xf,0x94,0xc2,0xf1,0x84,0xee,0x90,0xee,0x60,0xe0,0xf,0x94,0xf5,0xf1,0x8f,0xe3,0x91,0xee,0x60,0xe0,0xf,0x94,0xc2,0xf1,0x86,0xe0,0x90,0xe0,0x61,0xe0,0x70,0xe0,0xf,0x94,0x34,0xf2,0xf,0x94,0xdc,0xf1,0x8d,0xe5,0x91,0xee,0x60,0xe0,0xf,0x94,0xc2,0xf1,0x89,0xec,0x91,0xee,0x60,0xe0,0xf,0x94,0xf5,0xf1,0x8e,0xe4,0x91,0xee,0x60,0xe0,0xf,0x94,0xc2,0xf1,0x83,0xec,0x91,0xee,0x60,0xe0,0xf,0x94,0xf5,0xf1,0x8c,0xe6,0x91,0xee,0x60,0xe0,0xf,0x94,0xc2,0xf1,0x8e,0xe1,0xf,0x94,0xd,0xf2,0x88,0xe9,0xf,0x94,0xd,0xf2,0x81,0xe0,0xf,0x94,0xd,0xf2,0xf,0x94,0xdc,0xf1,0x8b,0xe7,0x91,0xee,0x60,0xe0,0xf,0x94,0xc2,0xf1,0x19,0xe0,0xe0,0xe0,0xf0,0xe0,0x10,0x93,0x57,0x0,0xe4,0x91,0x8e,0x2f,0xf,0x94,0xd,0xf2,0xf,0x94,0xdc,0xf1,0x8a,0xe8,0x91,0xee,0x60,0xe0,0xf,0x94,0xc2,0xf1,0xe3,0xe0,0xf0,0xe0,0x10,0x93,0x57,0x0,0xe4,0x91,0x8e,0x2f,0xf,0x94,0xd,0xf2,0xf,0x94,0xdc,0xf1,0x89,0xe9,0x91,0xee,0x60,0xe0,0xf,0x94,0xc2,0xf1,0xe2,0xe0,0xf0,0xe0,0x10,0x93,0x57,0x0,0xe4,0x91,0x8e,0x2f,0xf,0x94,0xd,0xf2,0xf,0x94,0xdc,0xf1,0x88,0xea,0x91,0xee,0x60,0xe0,0xf,0x94,0xc2,0xf1,0xe1,0xe0,0xf0,0xe0,0x10,0x93,0x57,0x0,0x14,0x91,0x81,0x2f,0xf,0x94,0xd,0xf2,0xf,0x94,0xdc,0xf1,0x7,0xcf,0x8b,0xe8,0x92,0xee,0x62,0xe0,0xf,0x94,0xf5,0xf1,0x8b,0xe4,0x92,0xee,0x60,0xe0,0xf,0x94,0xf5,0xf1,0xf,0x94,0xdc,0xf1,0x0,0xe0,0x10,0xe0,0x19,0xc0,0xc8,0x1,0x6f,0x2d,0xf,0x94,0x7f,0xfe,0xff,0x20,0x31,0xf4,0x89,0xe4,0x92,0xee,0x60,0xe0,0xf,0x94,0xc2,0xf1,0xb,0xc0,0xf0,0x92,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0xf,0x5f,0x1f,0x4f,0xc8,0x1,0x81,0x51,0x9f,0x41,0xa0,0xe0,0xb0,0xe0,0xab,0xbf,0xfc,0x1,0xf7,0x90,0xba,0xe2,0xfb,0x16,0x21,0xf0,0xe2,0xe0,0x0,0x30,0x1e,0x7,0xc1,0xf6,0xf,0x94,0xdc,0xf1,0xf,0x94,0xdc,0xf1,0x87,0xe5,0x92,0xee,0x60,0xe0,0xf,0x94,0xf5,0xf1,0xf,0x94,0xdc,0xf1,0xcc,0x24,0xdd,0x24,0x0,0xe0,0x10,0xe0,0x1e,0xc0,0xc8,0x1,0xf,0x94,0x77,0xfe,0xf8,0x2e,0x88,0x23,0x31,0xf4,0x89,0xe4,0x92,0xee,0x60,0xe0,0xf,0x94,0xc2,0xf1,0xb,0xc0,0x80,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0xfe,0x14,0x19,0xf0,0x8,0x94,0xc1,0x1c,0xd1,0x1c,0xf,0x5f,0x1f,0x4f,0xc8,0x1,0x81,0x51,0x9f,0x41,0xa0,0xe0,0xb0,0xe0,0xab,0xbf,0xfc,0x1,0xe7,0x90,0xfa,0xe2,0xef,0x16,0x21,0xf0,0x22,0xe0,0x0,0x30,0x12,0x7,0x99,0xf6,0xf,0x94,0xdc,0xf1,0xf,0x94,0xdc,0xf1,0x82,0xe6,0x92,0xee,0x60,0xe0,0xf,0x94,0xc2,0xf1,0xc6,0x1,0x61,0xe0,0x70,0xe0,0xf,0x94,0x34,0xf2,0xf,0x94,0xdc,0xf1,0xf,0x94,0xdc,0xf1,0x10,0x92,0x2,0x2,0x10,0x92,0x3,0x2,0x10,0x92,0x4,0x2,0x10,0x92,0x5,0x2,0x78,0xce,0x89,0xe9,0x92,0xee,0x62,0xe0,0xf,0x94,0xf5,0xf1,0x27,0x9a,0x2f,0x9a,0x16,0xc0,0x2f,0x98,0x80,0xe0,0x90,0xe0,0xe0,0xed,0xf7,0xe0,0x31,0x97,0xf1,0xf7,0x1,0x96,0x84,0x36,0x91,0x5,0xc1,0xf7,0x2f,0x9a,0x80,0xe0,0x90,0xe0,0xe0,0xed,0xf7,0xe0,0x31,0x97,0xf1,0xf7,0x1,0x96,0x84,0x36,0x91,0x5,0xc1,0xf7,0x80,0x91,0xc0,0x0,0x87,0xff,0xe6,0xcf,0x80,0x91,0xc0,0x0,0x87,0xff,0xfc,0xcf,0x64,0xc4,0x85,0xea,0x92,0xee,0x62,0xe0,0xf,0x94,0xf5,0xf1,0x40,0x91,0x2,0x2,0x50,0x91,0x3,0x2,0x60,0x91,0x4,0x2,0x70,0x91,0x5,0x2,0x81,0xe0,0x20,0xe1,0xf,0x94,0x91,0xf2,0x80,0x91,0x2,0x2,0x90,0x91,0x3,0x2,0xa0,0x91,0x4,0x2,0xb0,0x91,0x5,0x2,0x80,0x50,0x9f,0x4f,0xaf,0x4f,0xbf,0x4f,0x80,0x93,0x2,0x2,0x90,0x93,0x3,0x2,0xa0,0x93,0x4,0x2,0xb0,0x93,0x5,0x2,0x80,0x50,0x90,0x41,0xa0,0x40,0xb0,0x40,0x8,0xf4,0x26,0xce,0xa4,0xcf,0x83,0xeb,0x92,0xee,0x62,0xe0,0xf,0x94,0xf5,0xf1,0x40,0x91,0x6,0x2,0x50,0x91,0x7,0x2,0x60,0x91,0x8,0x2,0x70,0x91,0x9,0x2,0x80,0xe0,0x20,0xe1,0xf,0x94,0x91,0xf2,0x80,0x91,0x6,0x2,0x90,0x91,0x7,0x2,0xa0,0x91,0x8,0x2,0xb0,0x91,0x9,0x2,0x80,0x50,0x9f,0x4f,0xaf,0x4f,0xbf,0x4f,0x80,0x93,0x6,0x2,0x90,0x93,0x7,0x2,0xa0,0x93,0x8,0x2,0xb0,0x93,0x9,0x2,0xff,0xcd,0x80,0xec,0x92,0xee,0x62,0xe0,0xf,0x94,0xf5,0xf1,0x83,0xe7,0x92,0xee,0x60,0xe0,0xf,0x94,0xf5,0xf1,0x8f,0xe7,0x92,0xee,0x60,0xe0,0xf,0x94,0xf5,0xf1,0x8b,0xe8,0x92,0xee,0x60,0xe0,0xf,0x94,0xf5,0xf1,0x89,0xe9,0x92,0xee,0x60,0xe0,0xf,0x94,0xf5,0xf1,0x85,0xea,0x92,0xee,0x60,0xe0,0xf,0x94,0xf5,0xf1,0x83,0xeb,0x92,0xee,0x60,0xe0,0xf,0x94,0xf5,0xf1,0x80,0xec,0x92,0xee,0x60,0xe0,0xf,0x94,0xf5,0xf1,0x87,0xec,0x92,0xee,0x60,0xe0,0xf,0x94,0xf5,0xf1,0x88,0xed,0x92,0xee,0x60,0xe0,0xf,0x94,0xf5,0xf1,0x8f,0xed,0x92,0xee,0x60,0xe0,0xf,0x94,0xf5,0xf1,0x8a,0xee,0x92,0xee,0x60,0xe0,0xf,0x94,0xf5,0xf1,0x83,0xe0,0x93,0xee,0xbd,0xcd,0x87,0xec,0x92,0xee,0x62,0xe0,0xf,0x94,0xf5,0xf1,0x81,0xe4,0xf,0x94,0x7b,0xf2,0x82,0xe4,0xf,0x94,0x7b,0xf2,0x83,0xe4,0xf,0x94,0x7b,0xf2,0x84,0xe4,0xf,0x94,0x7b,0xf2,0x85,0xe4,0xf,0x94,0x7b,0xf2,0x86,0xe4,0xf,0x94,0x7b,0xf2,0x87,0xe4,0xf,0x94,0x7b,0xf2,0x88,0xe4,0xf,0x94,0x7b,0xf2,0x8a,0xe4,0xf,0x94,0x7b,0xf2,0x8b,0xe4,0xf,0x94,0x7b,0xf2,0x8c,0xe4,0xf,0x94,0x7b,0xf2,0x99,0xcd,0x88,0xed,0x92,0xee,0x62,0xe0,0xf,0x94,0xf5,0xf1,0x77,0x24,0x73,0x94,0x88,0x24,0x99,0x24,0x9,0xc4,0x8f,0xed,0x92,0xee,0x62,0xe0,0xf,0x94,0xf5,0xf1,0x40,0x91,0xa,0x2,0x50,0x91,0xb,0x2,0x60,0x91,0xc,0x2,0x70,0x91,0xd,0x2,0x82,0xe0,0x20,0xe1,0xf,0x94,0x91,0xf2,0x80,0x91,0xa,0x2,0x90,0x91,0xb,0x2,0xa0,0x91,0xc,0x2,0xb0,0x91,0xd,0x2,0x80,0x50,0x9f,0x4f,0xaf,0x4f,0xbf,0x4f,0x80,0x93,0xa,0x2,0x90,0x93,0xb,0x2,0xa0,0x93,0xc,0x2,0xb0,0x93,0xd,0x2,0x69,0xcd,0x8a,0xee,0x92,0xee,0x62,0xe0,0xf,0x94,0xf5,0xf1,0x84,0xee,0x90,0xee,0x60,0xe0,0xf,0x94,0xf5,0xf1,0x8f,0xec,0x91,0xee,0x60,0xe0,0xf,0x94,0xf5,0xf1,0x66,0x24,0x77,0x24,0x43,0x1,0xcc,0x5d,0xde,0x4f,0x19,0x82,0x18,0x82,0xc4,0x52,0xd1,0x40,0xd4,0x1,0xc3,0x1,0xb6,0x95,0xa7,0x95,0x97,0x95,0x87,0x95,0xca,0x5d,0xde,0x4f,0x88,0x83,0x99,0x83,0xaa,0x83,0xbb,0x83,0xc6,0x52,0xd1,0x40,0xcc,0x5d,0xde,0x4f,0xa8,0x81,0xb9,0x81,0xc4,0x52,0xd1,0x40,0x11,0x96,0xcc,0x5d,0xde,0x4f,0xb9,0x83,0xa8,0x83,0xc4,0x52,0xd1,0x40,0xcd,0x1,0x62,0xe0,0x70,0xe0,0xf,0x94,0x34,0xf2,0xb0,0xe2,0xb0,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0xed,0xe2,0xe0,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0xf0,0xe2,0xf0,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0xca,0x5d,0xde,0x4f,0xe8,0x80,0xf9,0x80,0xa,0x81,0x1b,0x81,0xc6,0x52,0xd1,0x40,0xbb,0x27,0xa1,0x2f,0x90,0x2f,0x8f,0x2d,0xf,0x94,0xd,0xf2,0xca,0x5d,0xde,0x4f,0x88,0x81,0xc6,0x52,0xd1,0x40,0xf,0x94,0xd,0xf2,0xb0,0xe2,0xfb,0x2e,0xf0,0x92,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0xd,0xe3,0x0,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0x10,0xe2,0x10,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0x8b,0xbe,0xf3,0x1,0x27,0x91,0xc6,0x5d,0xde,0x4f,0x28,0x83,0xca,0x52,0xd1,0x40,0xa2,0x2e,0xbb,0x24,0xcc,0x24,0xdd,0x24,0x8,0x94,0x61,0x1c,0x71,0x1c,0x81,0x1c,0x91,0x1c,0x8b,0xbe,0xf3,0x1,0x87,0x91,0x28,0x2e,0x33,0x24,0x44,0x24,0x55,0x24,0x8,0x94,0x61,0x1c,0x71,0x1c,0x81,0x1c,0x91,0x1c,0x8b,0xbe,0xf3,0x1,0x37,0x91,0xc5,0x5d,0xde,0x4f,0x38,0x83,0xcb,0x52,0xd1,0x40,0x8,0x94,0x61,0x1c,0x71,0x1c,0x81,0x1c,0x91,0x1c,0x8b,0xbe,0xf3,0x1,0x47,0x91,0xc4,0x5d,0xde,0x4f,0x48,0x83,0xcc,0x52,0xd1,0x40,0xad,0xef,0xea,0x2e,0xaf,0xef,0xfa,0x2e,0xaf,0xef,0xa,0x2f,0xaf,0xef,0x1a,0x2f,0x6e,0xc,0x7f,0x1c,0x80,0x1e,0x91,0x1e,0x14,0x2d,0x3,0x2d,0xf2,0x2c,0xee,0x24,0xea,0xc,0xfb,0x1c,0xc,0x1d,0x1d,0x1d,0xf,0x94,0xd,0xf2,0x20,0xe2,0x20,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0xc6,0x5d,0xde,0x4f,0x88,0x81,0xca,0x52,0xd1,0x40,0xf,0x94,0xd,0xf2,0x30,0xe2,0x30,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0xc4,0x5d,0xde,0x4f,0x88,0x81,0xcc,0x52,0xd1,0x40,0xf,0x94,0xd,0xf2,0x40,0xe2,0x40,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0xc5,0x5d,0xde,0x4f,0x88,0x81,0xcb,0x52,0xd1,0x40,0xf,0x94,0xd,0xf2,0x50,0xe2,0x50,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0x8f,0xef,0xe8,0x16,0x8f,0xef,0xf8,0x6,0x80,0xe0,0x8,0x7,0x80,0xe0,0x18,0x7,0x31,0xf4,0x84,0xe0,0x92,0xee,0x60,0xe0,0xf,0x94,0xc2,0xf1,0xdf,0xc0,0xd8,0x1,0xc7,0x1,0x80,0x70,0x90,0x7c,0xa0,0x70,0xb0,0x70,0x80,0x50,0x90,0x4c,0xa0,0x40,0xb0,0x40,0xd1,0xf5,0x2f,0xef,0x3f,0xe3,0x40,0xe0,0x50,0xe0,0xe2,0x22,0xf3,0x22,0x4,0x23,0x15,0x23,0xca,0x5d,0xde,0x4f,0xa8,0x80,0xb9,0x80,0xca,0x80,0xdb,0x80,0xc6,0x52,0xd1,0x40,0xae,0xc,0xbf,0x1c,0xc0,0x1e,0xd1,0x1e,0xaa,0xc,0xbb,0x1c,0xcc,0x1c,0xdd,0x1c,0x8e,0xe0,0x92,0xee,0x60,0xe0,0xf,0x94,0xc2,0xf1,0xbb,0x27,0xa1,0x2f,0x90,0x2f,0x8f,0x2d,0xf,0x94,0xd,0xf2,0x8e,0x2d,0xf,0x94,0xd,0xf2,0x30,0xe2,0x30,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0x4e,0xe3,0x40,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x87,0xc0,0x8e,0xe0,0x9e,0xef,0xa0,0xe0,0xb0,0xe0,0xe8,0x22,0xf9,0x22,0xa,0x23,0x1b,0x23,0x9c,0xe0,0xe9,0x16,0x94,0xe9,0xf9,0x6,0x90,0xe0,0x9,0x7,0x90,0xe0,0x19,0x7,0x9,0xf0,0x88,0xc0,0xc4,0x5d,0xde,0x4f,0xa8,0x81,0xcc,0x52,0xd1,0x40,0xea,0x2e,0xff,0x24,0x0,0xe0,0x10,0xe0,0x10,0x2f,0xf,0x2d,0xfe,0x2c,0xee,0x24,0xc5,0x5d,0xde,0x4f,0xb8,0x81,0xcb,0x52,0xd1,0x40,0xeb,0xe,0xf1,0x1c,0x1,0x1d,0x11,0x1d,0xd6,0x1,0xc5,0x1,0x81,0x70,0x90,0x70,0xa0,0x70,0xb0,0x70,0xdc,0x1,0x99,0x27,0x88,0x27,0xe8,0xe,0xf9,0x1e,0xa,0x1f,0x1b,0x1f,0x20,0xef,0x30,0xe0,0x40,0xe0,0x50,0xe0,0xa2,0x22,0xb3,0x22,0xc4,0x22,0xd5,0x22,0x41,0xe1,0xaa,0xc,0xbb,0x1c,0xcc,0x1c,0xdd,0x1c,0x4a,0x95,0xd1,0xf7,0xea,0xc,0xfb,0x1c,0xc,0x1d,0x1d,0x1d,0x81,0xe0,0x90,0xe0,0xa0,0xe0,0xb0,0xe0,0x28,0x22,0x39,0x22,0x4a,0x22,0x5b,0x22,0x35,0xe1,0x22,0xc,0x33,0x1c,0x44,0x1c,0x55,0x1c,0x3a,0x95,0xd1,0xf7,0xe2,0xc,0xf3,0x1c,0x4,0x1d,0x15,0x1d,0x57,0x1,0x68,0x1,0xaa,0xc,0xbb,0x1c,0xcc,0x1c,0xdd,0x1c,0x85,0xe1,0x92,0xee,0x60,0xe0,0xf,0x94,0xc2,0xf1,0xc8,0x1,0xaa,0x27,0xbb,0x27,0xf,0x94,0xd,0xf2,0xbb,0x27,0xa1,0x2f,0x90,0x2f,0x8f,0x2d,0xf,0x94,0xd,0xf2,0x8e,0x2d,0xf,0x94,0xd,0xf2,0x90,0xe2,0x90,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0xae,0xe3,0xa0,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0xc6,0x1,0xaa,0x27,0xbb,0x27,0xf,0x94,0xd,0xf2,0xbb,0x27,0xad,0x2d,0x9c,0x2d,0x8b,0x2d,0xf,0x94,0xd,0xf2,0x8a,0x2d,0xf,0x94,0xd,0xf2,0xf,0x94,0xdc,0xf1,0xcc,0x5d,0xde,0x4f,0xe8,0x81,0xf9,0x81,0xc4,0x52,0xd1,0x40,0xf9,0x97,0x9,0xf4,0x4d,0xcb,0xf4,0xe0,0xef,0x2e,0xf1,0x2c,0x1,0x2d,0x11,0x2d,0x6e,0xc,0x7f,0x1c,0x80,0x1e,0x91,0x1e,0xf2,0xcd,0x83,0xe0,0x93,0xee,0x62,0xe0,0xf,0x94,0xf5,0xf1,0x8a,0xe1,0x92,0xee,0x60,0xe0,0xf,0x94,0xc2,0xf1,0x80,0x91,0xc0,0x0,0x87,0xff,0xfc,0xcf,0x10,0x91,0xc6,0x0,0x1f,0x75,0x10,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0xf,0x94,0xdc,0xf1,0x81,0x2f,0x81,0x54,0x8a,0x31,0x8,0xf0,0x36,0xc1,0x16,0x34,0x9,0xf4,0x95,0xc0,0x17,0x34,0x90,0xf4,0x13,0x34,0x9,0xf4,0x4e,0xc0,0x14,0x34,0x30,0xf4,0x11,0x34,0xf1,0xf0,0x12,0x34,0x9,0xf0,0x1d,0xc1,0x30,0xc0,0x14,0x34,0x9,0xf4,0x59,0xc0,0x15,0x34,0x9,0xf0,0x16,0xc1,0x6b,0xc0,0x1a,0x34,0x9,0xf4,0xc4,0xc0,0x1b,0x34,0x38,0xf4,0x17,0x34,0x9,0xf4,0x8f,0xc0,0x18,0x34,0x9,0xf0,0xa,0xc1,0xa1,0xc0,0x1b,0x34,0x9,0xf4,0xd2,0xc0,0x1c,0x34,0x9,0xf0,0x3,0xc1,0xe8,0xc0,0x8f,0xef,0x81,0xb9,0xd,0xc0,0x82,0xb1,0x80,0x95,0x82,0xb9,0x80,0xe0,0x90,0xe0,0xe0,0xed,0xf7,0xe0,0x31,0x97,0xf1,0xf7,0x1,0x96,0x88,0x3c,0x91,0x5,0xc1,0xf7,0x80,0x91,0xc0,0x0,0x87,0xff,0xef,0xcf,0x12,0xb8,0xef,0xc0,0x8f,0xef,0x84,0xb9,0xd,0xc0,0x85,0xb1,0x80,0x95,0x85,0xb9,0x80,0xe0,0x90,0xe0,0xe0,0xed,0xf7,0xe0,0x31,0x97,0xf1,0xf7,0x1,0x96,0x88,0x3c,0x91,0x5,0xc1,0xf7,0x80,0x91,0xc0,0x0,0x87,0xff,0xef,0xcf,0x15,0xb8,0xd9,0xc0,0x8f,0xef,0x87,0xb9,0xd,0xc0,0x88,0xb1,0x80,0x95,0x88,0xb9,0x80,0xe0,0x90,0xe0,0xe0,0xed,0xf7,0xe0,0x31,0x97,0xf1,0xf7,0x1,0x96,0x88,0x3c,0x91,0x5,0xc1,0xf7,0x80,0x91,0xc0,0x0,0x87,0xff,0xef,0xcf,0x18,0xb8,0xc3,0xc0,0x8f,0xef,0x8a,0xb9,0xd,0xc0,0x8b,0xb1,0x80,0x95,0x8b,0xb9,0x80,0xe0,0x90,0xe0,0xe0,0xed,0xf7,0xe0,0x31,0x97,0xf1,0xf7,0x1,0x96,0x88,0x3c,0x91,0x5,0xc1,0xf7,0x80,0x91,0xc0,0x0,0x87,0xff,0xef,0xcf,0x1b,0xb8,0xad,0xc0,0x8f,0xef,0x8d,0xb9,0xd,0xc0,0x8e,0xb1,0x80,0x95,0x8e,0xb9,0x80,0xe0,0x90,0xe0,0xe0,0xed,0xf7,0xe0,0x31,0x97,0xf1,0xf7,0x1,0x96,0x88,0x3c,0x91,0x5,0xc1,0xf7,0x80,0x91,0xc0,0x0,0x87,0xff,0xef,0xcf,0x1e,0xb8,0x97,0xc0,0x8f,0xef,0x80,0xbb,0xd,0xc0,0x81,0xb3,0x80,0x95,0x81,0xbb,0x80,0xe0,0x90,0xe0,0xe0,0xed,0xf7,0xe0,0x31,0x97,0xf1,0xf7,0x1,0x96,0x88,0x3c,0x91,0x5,0xc1,0xf7,0x80,0x91,0xc0,0x0,0x87,0xff,0xef,0xcf,0x11,0xba,0x81,0xc0,0x8f,0xef,0x83,0xbb,0xd,0xc0,0x84,0xb3,0x80,0x95,0x84,0xbb,0x80,0xe0,0x90,0xe0,0xe0,0xed,0xf7,0xe0,0x31,0x97,0xf1,0xf7,0x1,0x96,0x88,0x3c,0x91,0x5,0xc1,0xf7,0x80,0x91,0xc0,0x0,0x87,0xff,0xef,0xcf,0x14,0xba,0x6b,0xc0,0x8f,0xef,0x80,0x93,0x1,0x1,0xf,0xc0,0x80,0x91,0x2,0x1,0x80,0x95,0x80,0x93,0x2,0x1,0x80,0xe0,0x90,0xe0,0xe0,0xed,0xf7,0xe0,0x31,0x97,0xf1,0xf7,0x1,0x96,0x88,0x3c,0x91,0x5,0xc1,0xf7,0x80,0x91,0xc0,0x0,0x87,0xff,0xed,0xcf,0x10,0x92,0x2,0x1,0x51,0xc0,0x8f,0xef,0x80,0x93,0x4,0x1,0xf,0xc0,0x80,0x91,0x5,0x1,0x80,0x95,0x80,0x93,0x5,0x1,0x80,0xe0,0x90,0xe0,0xe0,0xed,0xf7,0xe0,0x31,0x97,0xf1,0xf7,0x1,0x96,0x88,0x3c,0x91,0x5,0xc1,0xf7,0x80,0x91,0xc0,0x0,0x87,0xff,0xed,0xcf,0x10,0x92,0x5,0x1,0x37,0xc0,0x8f,0xef,0x80,0x93,0x7,0x1,0xf,0xc0,0x80,0x91,0x8,0x1,0x80,0x95,0x80,0x93,0x8,0x1,0x80,0xe0,0x90,0xe0,0xe0,0xed,0xf7,0xe0,0x31,0x97,0xf1,0xf7,0x1,0x96,0x88,0x3c,0x91,0x5,0xc1,0xf7,0x80,0x91,0xc0,0x0,0x87,0xff,0xed,0xcf,0x10,0x92,0x8,0x1,0x1d,0xc0,0x8f,0xef,0x80,0x93,0xa,0x1,0xf,0xc0,0x80,0x91,0xb,0x1,0x80,0x95,0x80,0x93,0xb,0x1,0x80,0xe0,0x90,0xe0,0xe0,0xed,0xf7,0xe0,0x31,0x97,0xf1,0xf7,0x1,0x96,0x88,0x3c,0x91,0x5,0xc1,0xf7,0x80,0x91,0xc0,0x0,0x87,0xff,0xed,0xcf,0x10,0x92,0xb,0x1,0x3,0xc0,0x85,0xe2,0x92,0xee,0xee,0xc9,0x80,0x91,0xc0,0x0,0x87,0xff,0xfc,0xcf,0x80,0x91,0xc6,0x0,0xea,0xc9,0x88,0xe3,0x92,0xee,0xe4,0xc9,0x8c,0xe1,0x91,0xee,0xe1,0xc9,0x88,0x24,0x99,0x24,0x93,0x30,0x11,0xf1,0x94,0x30,0x28,0xf4,0x91,0x30,0x89,0xf0,0x92,0x30,0xb8,0xf4,0x8,0xc0,0x95,0x30,0x61,0xf1,0x95,0x30,0xf0,0xf0,0x96,0x30,0x9,0xf0,0x48,0xc0,0x43,0xc0,0x2b,0x31,0x9,0xf0,0x42,0xc9,0x91,0xe0,0x6b,0xe1,0x3f,0xc9,0x62,0x27,0xc1,0x5d,0xde,0x4f,0x28,0x83,0xcf,0x52,0xd1,0x40,0x92,0xe0,0x37,0xc9,0xb2,0x2f,0xa0,0xe0,0x62,0x27,0x93,0xe0,0x32,0xc9,0x82,0x2f,0x90,0xe0,0xa8,0x2b,0xb9,0x2b,0x62,0x27,0x94,0xe0,0x2b,0xc9,0x2e,0x30,0x9,0xf0,0x39,0xc3,0x62,0x27,0x95,0xe0,0xc0,0x5d,0xde,0x4f,0x19,0x82,0x18,0x82,0xc0,0x53,0xd1,0x40,0x1f,0xc9,0xe1,0xe0,0xf0,0xe0,0xec,0xf,0xfd,0x1f,0xc0,0x5d,0xde,0x4f,0x8,0x81,0x19,0x81,0xc0,0x53,0xd1,0x40,0xe0,0xf,0xf1,0x1f,0x20,0x83,0xf,0x5f,0x1f,0x4f,0xc0,0x5d,0xde,0x4f,0x19,0x83,0x8,0x83,0xc0,0x53,0xd1,0x40,0x62,0x27,0xa,0x17,0x1b,0x7,0x9,0xf0,0x5,0xc9,0xd8,0x1,0x96,0xe0,0x2,0xc9,0x26,0x17,0x9,0xf0,0x10,0xc3,0x3,0xc0,0x97,0x30,0x9,0xf0,0xfb,0xc8,0x77,0x24,0x99,0x81,0x93,0x31,0x9,0xf4,0x12,0xc1,0x94,0x31,0xc8,0xf4,0x96,0x30,0x9,0xf4,0xd8,0xc0,0x97,0x30,0x50,0xf4,0x92,0x30,0x9,0xf4,0x6,0xc1,0x93,0x30,0x9,0xf4,0x6d,0xc0,0x91,0x30,0x9,0xf0,0x59,0xc2,0x53,0xc0,0x91,0x31,0x9,0xf4,0x77,0xc0,0x92,0x31,0x8,0xf0,0xbb,0xc0,0x90,0x31,0x9,0xf0,0x4f,0xc2,0xf5,0xc0,0x98,0x31,0x9,0xf4,0x87,0xc0,0x99,0x31,0x50,0xf4,0x95,0x31,0x9,0xf4,0xef,0xc0,0x95,0x31,0x8,0xf4,0xc6,0xc1,0x96,0x31,0x9,0xf0,0x40,0xc2,0xc2,0xc1,0x9a,0x31,0x9,0xf4,0x6c,0xc0,0x9a,0x31,0x8,0xf4,0x91,0xc0,0x9b,0x31,0x9,0xf4,0x5b,0xc0,0x9d,0x31,0x9,0xf0,0x33,0xc2,0x9d,0x81,0x90,0x33,0x59,0xf4,0x8f,0x81,0x88,0x23,0x11,0xf4,0x9e,0xe1,0x1c,0xc0,0x81,0x30,0x11,0xf0,0x91,0xe0,0x18,0xc0,0x98,0xe9,0x16,0xc0,0x89,0x2f,0x80,0x75,0x91,0xf0,0x90,0x35,0x39,0xf4,0xe0,0xe0,0xf0,0xe0,0x89,0xe0,0x80,0x93,0x57,0x0,0x94,0x91,0xa,0xc0,0x98,0x35,0x39,0xf4,0xe3,0xe0,0xf0,0xe0,0x89,0xe0,0x80,0x93,0x57,0x0,0x94,0x91,0x1,0xc0,0x90,0xe0,0x1a,0x82,0x1b,0x82,0x8d,0x81,0x8c,0x83,0x1d,0x82,0x9e,0x83,0x1f,0x82,0x27,0xe0,0x30,0xe0,0x9,0xc2,0x1a,0x82,0x88,0xe0,0x8b,0x83,0x81,0xe4,0x8c,0x83,0x86,0xe5,0x8d,0x83,0x82,0xe5,0x8e,0x83,0x89,0xe4,0x8f,0x83,0x83,0xe5,0x88,0x87,0x80,0xe5,0x89,0x87,0x8f,0xe5,0x8a,0x87,0x82,0xe3,0x8b,0x87,0x2b,0xe0,0x30,0xe0,0xf3,0xc1,0x8a,0x81,0x81,0x39,0x41,0xf0,0x82,0x39,0x41,0xf0,0x80,0x39,0x11,0xf4,0x8f,0xe0,0x5,0xc0,0x80,0xe0,0x3,0xc0,0x82,0xe0,0x1,0xc0,0x8a,0xe0,0x1a,0x82,0x8b,0x83,0x44,0xc0,0x77,0x24,0x73,0x94,0x82,0xc0,0x8d,0x81,0x88,0x23,0x11,0xf4,0x8e,0xe1,0x2c,0xc0,0x81,0x30,0x11,0xf0,0x81,0xe0,0x28,0xc0,0x88,0xe9,0x26,0xc0,0x1a,0x82,0xe1,0xe0,0xf0,0xe0,0x89,0xe0,0x80,0x93,0x57,0x0,0x84,0x91,0x8b,0x83,0x1c,0x82,0x24,0xe0,0x30,0xe0,0xc8,0xc1,0x8b,0x81,0x80,0x35,0x89,0xf4,0x8c,0x81,0x88,0x30,0x39,0xf4,0xe2,0xe0,0xf0,0xe0,0x89,0xe0,0x80,0x93,0x57,0x0,0x84,0x91,0xd,0xc0,0xe0,0xe0,0xf0,0xe0,0x89,0xe0,0x80,0x93,0x57,0x0,0x84,0x91,0x6,0xc0,0xe3,0xe0,0xf0,0xe0,0x89,0xe0,0x80,0x93,0x57,0x0,0x84,0x91,0x1a,0x82,0xdf,0xcf,0x8d,0x81,0x83,0x6c,0x99,0xe0,0xe1,0xe0,0xf0,0xe0,0x8,0x2e,0x90,0x93,0x57,0x0,0xe8,0x95,0x7,0xb6,0x0,0xfc,0xfd,0xcf,0x1a,0x82,0x1b,0x82,0x23,0xe0,0x30,0xe0,0x9b,0xc1,0x80,0xec,0x8a,0x83,0xce,0x5c,0xde,0x4f,0x18,0x82,0x19,0x82,0x1a,0x82,0x1b,0x82,0xc2,0x53,0xd1,0x40,0x8e,0xc1,0x8a,0x81,0x90,0xe0,0xa0,0xe0,0xb0,0xe0,0x58,0x2f,0x44,0x27,0x33,0x27,0x22,0x27,0x8b,0x81,0x90,0xe0,0xa0,0xe0,0xb0,0xe0,0xdc,0x1,0x99,0x27,0x88,0x27,0x28,0x2b,0x39,0x2b,0x4a,0x2b,0x5b,0x2b,0x8d,0x81,0x90,0xe0,0xa0,0xe0,0xb0,0xe0,0x28,0x2b,0x39,0x2b,0x4a,0x2b,0x5b,0x2b,0x8c,0x81,0x90,0xe0,0xa0,0xe0,0xb0,0xe0,0xba,0x2f,0xa9,0x2f,0x98,0x2f,0x88,0x27,0x28,0x2b,0x39,0x2b,0x4a,0x2b,0x5b,0x2b,0x22,0xf,0x33,0x1f,0x44,0x1f,0x55,0x1f,0xc0,0x5e,0xde,0x4f,0x28,0x83,0x39,0x83,0x4a,0x83,0x5b,0x83,0xc0,0x52,0xd1,0x40,0x1a,0x82,0x59,0xc1,0x3a,0x81,0xc9,0x5c,0xde,0x4f,0x38,0x83,0xc7,0x53,0xd1,0x40,0xca,0x5c,0xde,0x4f,0x18,0x82,0xc6,0x53,0xd1,0x40,0x8b,0x81,0xc8,0x2e,0xdd,0x24,0xca,0x5c,0xde,0x4f,0x48,0x81,0x59,0x81,0xc6,0x53,0xd1,0x40,0xc4,0x2a,0xd5,0x2a,0x93,0x31,0x9,0xf0,0x82,0xc0,0xce,0x5c,0xde,0x4f,0x88,0x81,0x99,0x81,0xaa,0x81,0xbb,0x81,0xc2,0x53,0xd1,0x40,0x80,0x50,0x90,0x4c,0xa3,0x40,0xb0,0x40,0x30,0xf5,0x83,0xe0,0xce,0x5c,0xde,0x4f,0xe8,0x80,0xf9,0x80,0xa,0x81,0x1b,0x81,0xc2,0x53,0xd1,0x40,0xf7,0x1,0x0,0x93,0x5b,0x0,0x80,0x93,0x57,0x0,0xe8,0x95,0x7,0xb6,0x0,0xfc,0xfd,0xcf,0xce,0x5c,0xde,0x4f,0x8,0x81,0x19,0x81,0x2a,0x81,0x3b,0x81,0xc2,0x53,0xd1,0x40,0x0,0x50,0x1f,0x4f,0x2f,0x4f,0x3f,0x4f,0xce,0x5c,0xde,0x4f,0x8,0x83,0x19,0x83,0x2a,0x83,0x3b,0x83,0xc2,0x53,0xd1,0x40,0xc0,0x5e,0xde,0x4f,0x48,0x81,0x59,0x81,0x6a,0x81,0x7b,0x81,0xc0,0x52,0xd1,0x40,0xde,0x1,0x1b,0x96,0x31,0xe0,0x8c,0x91,0x11,0x96,0x2c,0x91,0x11,0x97,0x12,0x96,0xc7,0x5c,0xde,0x4f,0x28,0x83,0xc9,0x53,0xd1,0x40,0xc8,0x5c,0xde,0x4f,0x18,0x82,0xc8,0x53,0xd1,0x40,0x90,0xe0,0xc8,0x5c,0xde,0x4f,0xe8,0x81,0xf9,0x81,0xc8,0x53,0xd1,0x40,0x8e,0x2b,0x9f,0x2b,0xc,0x1,0xfa,0x1,0x60,0x93,0x5b,0x0,0x30,0x93,0x57,0x0,0xe8,0x95,0x11,0x24,0x4e,0x5f,0x5f,0x4f,0x6f,0x4f,0x7f,0x4f,0xe,0xef,0xe0,0x2e,0xf,0xef,0xf0,0x2e,0xce,0xc,0xdf,0x1c,0xc1,0x14,0xd1,0x4,0x99,0xf6,0x85,0xe0,0xc0,0x5e,0xde,0x4f,0x8,0x81,0x19,0x81,0x2a,0x81,0x3b,0x81,0xc0,0x52,0xd1,0x40,0xf8,0x1,0x20,0x93,0x5b,0x0,0x80,0x93,0x57,0x0,0xe8,0x95,0x7,0xb6,0x0,0xfc,0xfd,0xcf,0x81,0xe1,0x80,0x93,0x57,0x0,0xe8,0x95,0x35,0xc0,0xc0,0x5e,0xde,0x4f,0x88,0x81,0x99,0x81,0xaa,0x81,0xbb,0x81,0xc0,0x52,0xd1,0x40,0xb6,0x95,0xa7,0x95,0x97,0x95,0x87,0x95,0x7c,0x1,0x86,0x1,0xab,0xe0,0xaa,0x2e,0xb1,0x2c,0xac,0xe,0xbd,0x1e,0xb,0xc0,0xd5,0x1,0x6d,0x91,0x5d,0x1,0xc7,0x1,0xf,0x94,0x7f,0xfe,0x8,0x94,0xe1,0x1c,0xf1,0x1c,0x1,0x50,0x10,0x40,0x1,0x15,0x11,0x5,0x91,0xf7,0xa6,0x1,0x60,0xe0,0x70,0xe0,0x44,0xf,0x55,0x1f,0x66,0x1f,0x77,0x1f,0xc0,0x5e,0xde,0x4f,0xe8,0x80,0xf9,0x80,0xa,0x81,0x1b,0x81,0xc0,0x52,0xd1,0x40,0x4e,0xd,0x5f,0x1d,0x60,0x1f,0x71,0x1f,0x1a,0x82,0xc0,0x5e,0xde,0x4f,0x48,0x83,0x59,0x83,0x6a,0x83,0x7b,0x83,0xc0,0x52,0xd1,0x40,0x7f,0xc0,0xfa,0x80,0xc5,0x5c,0xde,0x4f,0xf8,0x82,0xcb,0x53,0xd1,0x40,0xc6,0x5c,0xde,0x4f,0x18,0x82,0xca,0x53,0xd1,0x40,0x8b,0x81,0xc8,0x2e,0xdd,0x24,0xc6,0x5c,0xde,0x4f,0x8,0x81,0x19,0x81,0xca,0x53,0xd1,0x40,0xc0,0x2a,0xd1,0x2a,0x1a,0x82,0x89,0x81,0xbe,0x1,0x6d,0x5f,0x7f,0x4f,0x84,0x31,0x21,0xf5,0x96,0x1,0xc0,0x5e,0xde,0x4f,0xe8,0x80,0xf9,0x80,0xa,0x81,0x1b,0x81,0xc0,0x52,0xd1,0x40,0xb,0xbf,0xf7,0x1,0x87,0x91,0x96,0x91,0xdb,0x1,0x8c,0x93,0x11,0x96,0x9c,0x93,0x6e,0x5f,0x7f,0x4f,0xd8,0x1,0xc7,0x1,0x2,0x96,0xa1,0x1d,0xb1,0x1d,0xc0,0x5e,0xde,0x4f,0x88,0x83,0x99,0x83,0xaa,0x83,0xbb,0x83,0xc0,0x52,0xd1,0x40,0x22,0x50,0x30,0x40,0xf1,0xf6,0x36,0xc0,0xc0,0x5e,0xde,0x4f,0x28,0x81,0x39,0x81,0x4a,0x81,0x5b,0x81,0xc0,0x52,0xd1,0x40,0x8,0x94,0xc1,0x8,0xd1,0x8,0x76,0x1,0x0,0xe0,0x10,0xe0,0x8,0x94,0xc1,0x1c,0xd1,0x1c,0x8,0x94,0xe1,0x1c,0xf1,0x1c,0x1,0x1d,0x11,0x1d,0xe2,0xe,0xf3,0x1e,0x4,0x1f,0x15,0x1f,0x21,0xbd,0xbb,0x27,0xa5,0x2f,0x94,0x2f,0x83,0x2f,0x82,0xbd,0x2f,0x5f,0x3f,0x4f,0x4f,0x4f,0x5f,0x4f,0xf8,0x9a,0x80,0xb5,0xdb,0x1,0x8d,0x93,0xbd,0x1,0x2e,0x15,0x3f,0x5,0x40,0x7,0x51,0x7,0x61,0xf7,0xc0,0x5e,0xde,0x4f,0x28,0x83,0x39,0x83,0x4a,0x83,0x5b,0x83,0xc0,0x52,0xd1,0x40,0x96,0x1,0x2d,0x5f,0x3f,0x4f,0xfb,0x1,0x10,0x82,0x4,0xc0,0x80,0xec,0x8a,0x83,0x22,0xe0,0x30,0xe0,0x8b,0xe1,0x80,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0xc1,0x5d,0xde,0x4f,0xf8,0x81,0xcf,0x52,0xd1,0x40,0xf0,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0x43,0x2f,0x30,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0x92,0x2f,0x20,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0x8e,0xe0,0x80,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0x65,0xe1,0xc1,0x5d,0xde,0x4f,0xe8,0x80,0xcf,0x52,0xd1,0x40,0x6e,0x25,0x69,0x27,0x64,0x27,0xfe,0x1,0x31,0x96,0x10,0xc0,0x90,0x81,0x90,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x31,0x96,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0x69,0x27,0x21,0x50,0x30,0x40,0x21,0x15,0x31,0x5,0x69,0xf7,0x60,0x93,0xc6,0x0,0x80,0x91,0xc0,0x0,0x86,0xff,0xfc,0xcf,0x80,0x91,0xc0,0x0,0x80,0x64,0x80,0x93,0xc0,0x0,0x85,0xb1,0x80,0x58,0x85,0xb9,0x77,0x20,0x81,0xf4,0xc1,0x5d,0xde,0x4f,0x8,0x81,0xcf,0x52,0xd1,0x40,0xf,0x5f,0xc1,0x5d,0xde,0x4f,0x8,0x83,0xcf,0x52,0xd1,0x40,0x90,0xe0,0xa0,0xe0,0xb0,0xe0,0xd,0x94,0x1a,0xf4,0x27,0x98,0x2f,0x98,0x80,0xe0,0x90,0xe0,0x20,0xed,0x37,0xe0,0xf9,0x1,0x31,0x97,0xf1,0xf7,0x1,0x96,0x84,0x36,0x91,0x5,0xc9,0xf7,0x0,0x0,0x80,0x91,0xc0,0x0,0x8d,0x7f,0x80,0x93,0xc0,0x0,0x81,0xe1,0x80,0x93,0x57,0x0,0xe8,0x95,0xee,0x27,0xff,0x27,0x9,0x94,0xff,0xcf,0x90,0xe0,0xd,0x94,0x1a,0xf4,0x97,0xfb,0x9,0x2e,0x7,0x26,0xa,0xd0,0x77,0xfd,0x4,0xd0,0x2e,0xd0,0x6,0xd0,0x0,0x20,0x1a,0xf4,0x70,0x95,0x61,0x95,0x7f,0x4f,0x8,0x95,0xf6,0xf7,0x90,0x95,0x81,0x95,0x9f,0x4f,0x8,0x95,0xa1,0xe2,0x1a,0x2e,0xaa,0x1b,0xbb,0x1b,0xfd,0x1,0xd,0xc0,0xaa,0x1f,0xbb,0x1f,0xee,0x1f,0xff,0x1f,0xa2,0x17,0xb3,0x7,0xe4,0x7,0xf5,0x7,0x20,0xf0,0xa2,0x1b,0xb3,0xb,0xe4,0xb,0xf5,0xb,0x66,0x1f,0x77,0x1f,0x88,0x1f,0x99,0x1f,0x1a,0x94,0x69,0xf7,0x60,0x95,0x70,0x95,0x80,0x95,0x90,0x95,0x9b,0x1,0xac,0x1,0xbd,0x1,0xcf,0x1,0x8,0x95,0xaa,0x1b,0xbb,0x1b,0x51,0xe1,0x7,0xc0,0xaa,0x1f,0xbb,0x1f,0xa6,0x17,0xb7,0x7,0x10,0xf0,0xa6,0x1b,0xb7,0xb,0x88,0x1f,0x99,0x1f,0x5a,0x95,0xa9,0xf7,0x80,0x95,0x90,0x95,0xbc,0x1,0xcd,0x1,0x8,0x95,0xf9,0x99,0xfe,0xcf,0x92,0xbd,0x81,0xbd,0xf8,0x9a,0x99,0x27,0x80,0xb5,0x8,0x95,0x26,0x2f,0xf9,0x99,0xfe,0xcf,0x1f,0xba,0x92,0xbd,0x81,0xbd,0x20,0xbd,0xf,0xb6,0xf8,0x94,0xfa,0x9a,0xf9,0x9a,0xf,0xbe,0x1,0x96,0x8,0x95,0xf8,0x94,0xff,0xcf diff --git a/trunk/Arduino/Marlin_K8600_Original/hfuse.bin b/trunk/Arduino/Marlin_K8600_Original/hfuse.bin new file mode 100644 index 00000000..07e2dac4 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_Original/hfuse.bin @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/trunk/Arduino/Marlin_K8600_Original/hfuse.hex b/trunk/Arduino/Marlin_K8600_Original/hfuse.hex new file mode 100644 index 00000000..3ad9dfb1 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_Original/hfuse.hex @@ -0,0 +1 @@ +0xd8 diff --git a/trunk/Arduino/Marlin_K8600_Original/lfuse.bin b/trunk/Arduino/Marlin_K8600_Original/lfuse.bin new file mode 100644 index 00000000..ce542efa --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_Original/lfuse.bin @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/trunk/Arduino/Marlin_K8600_Original/lfuse.hex b/trunk/Arduino/Marlin_K8600_Original/lfuse.hex new file mode 100644 index 00000000..7a35b297 --- /dev/null +++ b/trunk/Arduino/Marlin_K8600_Original/lfuse.hex @@ -0,0 +1 @@ +0xff diff --git a/trunk/Arduino/Micronucleus_Bootloader/micronucleus-1.11-ledpb1.hex b/trunk/Arduino/Micronucleus_Bootloader/micronucleus-1.11-ledpb1.hex new file mode 100644 index 00000000..3397f3e0 --- /dev/null +++ b/trunk/Arduino/Micronucleus_Bootloader/micronucleus-1.11-ledpb1.hex @@ -0,0 +1,119 @@ +:0800000077CC76CCACCC74CCBB +:1018C00017C016C04CC014C00902120001010080EC +:1018D0003209040000000000000012011001FF00A6 +:1018E0000008D01653070B0100000001040309048F +:1018F00011241FBECFE5D2E0CDBFDEBF00EB0F93BA +:1019000007E00F9310E0A0E6B0E0E2EEFFE102C0D6 +:1019100005900D92A636B107D9F720E0A6E6B0E013 +:1019200001C01D92A639B207E1F7E2C1A82FB92F75 +:1019300080E090E041E050EA609530E009C02D91F0 +:1019400082279795879510F084279527305EC8F3F6 +:101950006F5FA8F30895EADF8D939D930895CF9369 +:10196000CFB7CF93C0915F02C03B21F4C0915E021C +:10197000C73021F0CF91CFBFCF91A1CFCC27C39556 +:10198000B39BE9F7B39B0BC0B39B09C0B39B07C0E4 +:10199000B39B05C0B39B03C0B39B01C0D3C00F92E0 +:1019A000DF93C0917900DD27C058DF4F012EB39B34 +:1019B00003C0DF910F90E6CF2F930F931F934F93A8 +:1019C0002FEF4F6F06B303FB20F95F933F9350E077 +:1019D0003BE065C016B30126502953FDC89556B3A8 +:1019E000012703FB25F92F7306B3B1F05027102709 +:1019F00013FB26F906B22230F0F000C016B301271F +:101A000003FB27F90126502906B22430E8F54F7769 +:101A1000206816B30000F6CF50274F7D206206B233 +:101A2000102F000000C006B300265029102713FB1A +:101A300026F906B2E2CF4F7B06B3206400C0DACFAE +:101A400001265029187106B269F14E7F2160012FDD +:101A500016B328C0002650294D7F06B22260102FF1 +:101A600029C0012650294B7F06B22460012F2DC0CA +:101A700016B301265029477F2860000006B22EC009 +:101A80004F7E06B3206130C0422706B3499300263B +:101A90005029102706B24FEF13FB20F9297F16B308 +:101AA00079F2187159F10126502906B2012703FB7A +:101AB00021F9237F06B371F2002650293150D0F06E +:101AC00006B2102713FB22F9277E16B351F2012626 +:101AD0005029012703FB06B223F92F7C49F20000AD +:101AE00006B3102713FB24F90026502906B22F79DC +:101AF00039F270CF10E21ABF002717C03B50319562 +:101B0000C31BD04010E21ABF0881033CF9F00B342C +:101B1000E9F0209177001981110F1213EDCF0936EA +:101B200051F10D3211F0013E39F700937E003F91E3 +:101B30005F914F911F910F912F91DF910F90CAB735 +:101B4000C5FD1DCFCF91CFBFCF91189520917E00BD +:101B5000222369F310917C00112321F5343022F106 +:101B600030937C0020937800109179003BE0311B8A +:101B70003093790019C000917C0001309CF40AE593 +:101B80003091600034FD11C000936000CCE6D0E0DD +:101B900010C0052710E000C021C0052710E0C8953F +:101BA00008BB14C03AE501C032ED032EC0E0D0E01E +:101BB00032E017B31861C39A08B317BB58E120E8A5 +:101BC0004FEF20FF052708BB279517951C3F28F7E7 +:101BD00000004552B0F720FF0527279508BB179551 +:101BE0001C3FB8F629913A9561F7077E10917D0068 +:101BF000110F08BBC250D04011F01093770010E2D3 +:101C00001ABF086017B3177E402F477E54E05A95DD +:101C1000F1F708BB17BB48BB8ACFF8942FEFB0E8A9 +:101C2000A0E44AE0B1BF000081EE9CE0B399FECF92 +:101C3000B39BFECF0197B399FDCF97FF03C0BA1BAB +:101C4000819501C0BA0FA69529F4281710F031B775 +:101C5000282FA1E0415031F731BF0000789408955A +:101C6000F894F201329785E080935700E8957894D4 +:101C70000895F201309729F49093680080936700EB +:101C800007C0E430F10539F490936A00809369004D +:101C90008FE59CEC1FC02CEB421628E1520639F46C +:101CA00080916700909168008E559C4F13C02EEB79 +:101CB000421628E1520639F48091690090916A0039 +:101CC0008D559C4F07C02AEB421628E1520611F4AD +:101CD00081B790E02FB7F89431E00C0130935700B2 +:101CE000E89511242F0182E0480E511C2FBF089562 +:101CF00014BE88E181BD87E081BDBB9A88E893E18D +:101D0000ECE9F1E03197F1F70197D1F7BB98AC9A84 +:101D10008BB780628BBF7894C198712C8CE991E06D +:101D20000197F1F7A895312C60917C00162F135084 +:101D300017FDB2C080917900CCE0D0E0C81BD1097A +:101D4000C058DF4F6150CE01F1DD8E3F9F4409F056 +:101D5000A1C0809178008D3209F085C0183009F05B +:101D600099C083EC80936C008AE5809360001092A8 +:101D700066009881292F207689812223D1F0712C49 +:101D8000811108C082E690E090937B0080937A00F6 +:101D900024E05FC0813051F481E180935700E895E1 +:101DA0004C805D8097FD50C02FEF4FC0382E20E053 +:101DB00050C09A8110927500811106C01092760071 +:101DC00085E790E022E03BC0853019F490937D00D8 +:101DD0002CC0863009F58B81813019F48AED98E1A9 +:101DE00004C0823041F488EC98E190937B008093AA +:101DF0007A0022E10DC0833051F4911108C08CEEBD +:101E000098E190937B0080937A0024E001C020E069 +:101E100080E4809366001DC0883059F0893019F441 +:101E200090937F0002C08A3039F085E790E020E08F +:101E300006C08FE790E002C085E790E021E0909334 +:101E40007B0080937A0005C02E8180E88093660035 +:101E500007C08F81811104C08E81821708F4282F5A +:101E60002093610017C08091660087FF13C080EC4B +:101E7000481688E1580620F0842D8F7339F00AC087 +:101E800089919991F6DE125091F7F6CF95E0392EAF +:101E90001092610010927C008091600084FF42C02B +:101EA000809161008F3F09F43DC0182F893008F000 +:101EB00018E0811B8093610080916C0098E889276D +:101EC00080936C00112311F1E0917A00F0917B0076 +:101ED0008091660086FF0BC0ADE6B0E084918D93E3 +:101EE00031968DE690E0810F8A13F8CF0BC0EF0199 +:101EF000ADE6B0E089918D93FE018DE690E0810F13 +:101F00008A13F8CFF0937B00E0937A00612F8DE67F +:101F100090E021DD1C5F1C3019F08FEF8093610091 +:101F20001093600084E196B3987131F48150D9F731 +:101F300010927D0010927700C1E08111C0E0809185 +:101F40006B008C1729F0C11101C067DEC0936B00D4 +:101F5000C30101963C018035934C11F484E0382E86 +:101F6000872D8D7011F0B99801C0B99A232D3320B7 +:101F7000E9F08AE390E20197F1F72230A9F4F894AE +:101F8000E0ECF8E1E054F10983E080935700E89534 +:101F90003097C1F7412C512CC8E08FEF9FEF69DEDD +:101FA000C150D9F75DDE02C02530E1F384E038127C +:101FB000B5CEEDEBF8E1E491EF3F09F4AFCEB9987F +:101FC000F894BB9A1BBE15BA10925F02EAEBF8E1D7 +:101FD000E4918E2F81508E3F10F4E1BF00006ECC53 +:021FE000FFCF31 +:061FE2005AFF18BA400886 +:04000003000018C021 +:00000001FF diff --git a/trunk/Arduino/Micronucleus_Bootloader/micronucleus-1.11.hex b/trunk/Arduino/Micronucleus_Bootloader/micronucleus-1.11.hex new file mode 100644 index 00000000..dd31260f --- /dev/null +++ b/trunk/Arduino/Micronucleus_Bootloader/micronucleus-1.11.hex @@ -0,0 +1,118 @@ +:0800000077CC76CCACCC74CCBB +:1018C00017C016C04CC014C00902120001010080EC +:1018D0003209040000000000000012011001FF00A6 +:1018E0000008D01653070B0100000001040309048F +:1018F00011241FBECFE5D2E0CDBFDEBF00EB0F93BA +:1019000007E00F9310E0A0E6B0E0E2EDFFE102C0D7 +:1019100005900D92A636B107D9F720E0A6E6B0E013 +:1019200001C01D92A639B207E1F7E2C1A82FB92F75 +:1019300080E090E041E050EA609530E009C02D91F0 +:1019400082279795879510F084279527305EC8F3F6 +:101950006F5FA8F30895EADF8D939D930895CF9369 +:10196000CFB7CF93C0915F02C03B21F4C0915E021C +:10197000C73021F0CF91CFBFCF91A1CFCC27C39556 +:10198000B39BE9F7B39B0BC0B39B09C0B39B07C0E4 +:10199000B39B05C0B39B03C0B39B01C0D3C00F92E0 +:1019A000DF93C0917900DD27C058DF4F012EB39B34 +:1019B00003C0DF910F90E6CF2F930F931F934F93A8 +:1019C0002FEF4F6F06B303FB20F95F933F9350E077 +:1019D0003BE065C016B30126502953FDC89556B3A8 +:1019E000012703FB25F92F7306B3B1F05027102709 +:1019F00013FB26F906B22230F0F000C016B301271F +:101A000003FB27F90126502906B22430E8F54F7769 +:101A1000206816B30000F6CF50274F7D206206B233 +:101A2000102F000000C006B300265029102713FB1A +:101A300026F906B2E2CF4F7B06B3206400C0DACFAE +:101A400001265029187106B269F14E7F2160012FDD +:101A500016B328C0002650294D7F06B22260102FF1 +:101A600029C0012650294B7F06B22460012F2DC0CA +:101A700016B301265029477F2860000006B22EC009 +:101A80004F7E06B3206130C0422706B3499300263B +:101A90005029102706B24FEF13FB20F9297F16B308 +:101AA00079F2187159F10126502906B2012703FB7A +:101AB00021F9237F06B371F2002650293150D0F06E +:101AC00006B2102713FB22F9277E16B351F2012626 +:101AD0005029012703FB06B223F92F7C49F20000AD +:101AE00006B3102713FB24F90026502906B22F79DC +:101AF00039F270CF10E21ABF002717C03B50319562 +:101B0000C31BD04010E21ABF0881033CF9F00B342C +:101B1000E9F0209177001981110F1213EDCF0936EA +:101B200051F10D3211F0013E39F700937E003F91E3 +:101B30005F914F911F910F912F91DF910F90CAB735 +:101B4000C5FD1DCFCF91CFBFCF91189520917E00BD +:101B5000222369F310917C00112321F5343022F106 +:101B600030937C0020937800109179003BE0311B8A +:101B70003093790019C000917C0001309CF40AE593 +:101B80003091600034FD11C000936000CCE6D0E0DD +:101B900010C0052710E000C021C0052710E0C8953F +:101BA00008BB14C03AE501C032ED032EC0E0D0E01E +:101BB00032E017B31861C39A08B317BB58E120E8A5 +:101BC0004FEF20FF052708BB279517951C3F28F7E7 +:101BD00000004552B0F720FF0527279508BB179551 +:101BE0001C3FB8F629913A9561F7077E10917D0068 +:101BF000110F08BBC250D04011F01093770010E2D3 +:101C00001ABF086017B3177E402F477E54E05A95DD +:101C1000F1F708BB17BB48BB8ACFF8942FEFB0E8A9 +:101C2000A0E44AE0B1BF000081EE9CE0B399FECF92 +:101C3000B39BFECF0197B399FDCF97FF03C0BA1BAB +:101C4000819501C0BA0FA69529F4281710F031B775 +:101C5000282FA1E0415031F731BF0000789408955A +:101C6000F894F201329785E080935700E8957894D4 +:101C70000895F201309729F49093680080936700EB +:101C800007C0E430F10539F490936A00809369004D +:101C90008FE59CEC1FC02CEB421628E1520639F46C +:101CA00080916700909168008E559C4F13C02EEB79 +:101CB000421628E1520639F48091690090916A0039 +:101CC0008D559C4F07C02AEB421628E1520611F4AD +:101CD00081B790E02FB7F89431E00C0130935700B2 +:101CE000E89511242F0182E0480E511C2FBF089562 +:101CF00014BE88E181BD87E081BDBB9A88E893E18D +:101D0000ECE9F1E03197F1F70197D1F7BB98AC9A84 +:101D10008BB780628BBF7894712C8CE991E001972E +:101D2000F1F7A895312C60917C00162F135017FD08 +:101D3000B2C080917900CCE0D0E0C81BD109C05876 +:101D4000DF4F6150CE01F2DD8E3F9F4409F0A1C00C +:101D5000809178008D3209F085C0183009F099C063 +:101D600083EC80936C008AE580936000109266009B +:101D70009881292F207689812223D1F0712C81111D +:101D800008C082E690E090937B0080937A0024E084 +:101D90005FC0813051F481E180935700E8954C8019 +:101DA0005D8097FD50C02FEF4FC0382E20E050C00F +:101DB0009A8110927500811106C01092760085E715 +:101DC00090E022E03BC0853019F490937D002CC058 +:101DD000863009F58B81813019F48AED98E104C0D1 +:101DE000823041F488EC98E190937B0080937A00F4 +:101DF00022E10DC0833051F4911108C08CEE98E1BE +:101E000090937B0080937A0024E001C020E080E47E +:101E1000809366001DC0883059F0893019F4909382 +:101E20007F0002C08A3039F085E790E020E006C0EC +:101E30008FE790E002C085E790E021E090937B007F +:101E400080937A0005C02E8180E88093660007C0E9 +:101E50008F81811104C08E81821708F4282F20936E +:101E6000610017C08091660087FF13C080EC4816A0 +:101E700088E1580620F0842D8F7339F00AC08991CB +:101E80009991F7DE125091F7F6CF95E0392E109226 +:101E9000610010927C008091600084FF42C08091BC +:101EA00061008F3F09F43DC0182F893008F018E019 +:101EB000811B8093610080916C0098E88927809352 +:101EC0006C00112311F1E0917A00F0917B00809178 +:101ED000660086FF0BC0ADE6B0E084918D9331962D +:101EE0008DE690E0810F8A13F8CF0BC0EF01ADE6CD +:101EF000B0E089918D93FE018DE690E0810F8A1309 +:101F0000F8CFF0937B00E0937A00612F8DE690E0AC +:101F100022DD1C5F1C3019F08FEF8093610010935D +:101F2000600084E196B3987131F48150D9F7109232 +:101F30007D0010927700C1E08111C0E080916B00BC +:101F40008C1729F0C11101C068DEC0936B00C3017A +:101F500001963C018035934C11F484E0382E232DFA +:101F60003320E9F08AE390E20197F1F72230A9F4F7 +:101F7000F894E0ECF8E1E054F10983E08093570035 +:101F8000E8953097C1F7412C512CC8E08FEF9FEFB7 +:101F900070DEC150D9F764DE02C02530E1F384E081 +:101FA0003812BBCEEDEBF8E1E491EF3F09F4B5CE8A +:101FB000F894BB9A1BBE15BA10925F02EAEBF8E1E7 +:101FC000E4918E2F81508E3F10F4E1BF000076CC5B +:021FD000FFCF41 +:061FD2005AFF18BA400896 +:04000003000018C021 +:00000001FF diff --git a/trunk/Arduino/Repetier_0.92.9/BedLeveling.cpp b/trunk/Arduino/Repetier_0.92.9/BedLeveling.cpp new file mode 100644 index 00000000..737e2318 --- /dev/null +++ b/trunk/Arduino/Repetier_0.92.9/BedLeveling.cpp @@ -0,0 +1,708 @@ + +/* +More and more printers now have automatic bed leveling using an ever increasing variety of methods. +This makes the leveling routine one of the most complex parts of the firmware and there is not one +way to level but hundreds of combinations. + +First you should decide on the correction method. Once we know how our bed is tilted we want to +remove that. This correction is defined by BED_CORRECTION_METHOD and allows the following values: +BED_CORRECTION_METHOD 0 +Use a rotation matrix. This will make z axis go up/down while moving in x/y direction to compensate +the tilt. For multiple extruders make sure the height match the tilt of the bed or one will scratch. + +BED_CORRECTION_METHOD 1 +Motorized correction. This method needs a bed that is fixed on 3 points from which 2 have a motor +to change the height. The positions are defined by +BED_MOTOR_1_X, BED_MOTOR_1_Y, BED_MOTOR_2_X, BED_MOTOR_2_Y, BED_MOTOR_3_X, BED_MOTOR_3_Y +Motor 2 and 3 are the one driven by motor driver 0 and 1. These can be extra motors like Felix Pro 1 +uses them or a system with 3 z axis where motors can be controlled individually like the Sparkcube +does. + +Next we have to distinguish several methods of z probing sensors. Each have their own advantages and +disadvantages. First the z probe has a position when activated and that position is defined by +#define Z_PROBE_X_OFFSET 0 +#define Z_PROBE_Y_OFFSET 0 +This is needed since we need to know where we measure the height when the z probe triggers. When +probing is activated you will see a move to make probe go over current extruder position. The +position can be changed in eeprom later on. + +Some probes need to be activated/deactivated so we can use them. This is defined in the scripts +#define Z_PROBE_START_SCRIPT "" +#define Z_PROBE_FINISHED_SCRIPT "" + +Now when we probe we want to know the distance of the extruder to the bed. This is defined by +#define Z_PROBE_HEIGHT 4 +The 4 means that when we trigger the distance of the nozzle tip is 4mm. If your switch tends +to return different points you might repeat a measured point and use the average height: +#define Z_PROBE_SWITCHING_DISTANCE 1 +#define Z_PROBE_REPETITIONS 5 +Switching distance is the z raise needed to turn back a signal reliably to off. Inductive sensors +need only a bit while mechanical switches may require a bit more. + +Next thing to consider is the force for switching. Some beds use a cantilever design and pushing on +the outside easily bends the bed. If your sensor needs some force to trigger you add the error of +bending. For this reason you might add a bending correction. Currently you define +#define BENDING_CORRECTION_A 0 +#define BENDING_CORRECTION_B 0 +#define BENDING_CORRECTION_C 0 +which are the deflections at the 3 z probe points. For all other possible measurements these values +get interpolated. You can modify the values later on in eeprom. For force less sensors set them to 0. + +Next thing is endstop handling. Without bed leveling you normally home to minimum position for x,y and z. +With bed leveling this is not that easy any more. Since we do bed leveling we already assume the bed is +not leveled for x/y moves. So without correction we would hit the bed for different x/y positions at +different heights. As a result we have no real minimum position. That makes a z min endstop quite useless. +There is an exception to this. If your nozzle triggers z min or if a inductive sensor would trigger at a given +position we could use that signal. With nozzle triggers you need to be careful as a drop of filament +would change the height. The other problem is that while homing the auto leveling is not used. So +the only position would be if the z min sensor is directly over the 0,0 coordinate which is the rotation point +if we have matrix based correction. For motor based correction this will work everywhere correctly. + +So the only useful position for a z endstop is z max position. Apart from not having the bed tilt problem it +also allows homing with a full bed so you can continue an aborted print with some gcode tweaking. With z max +homing we adjust the error by simply changing the max. z height. One thing you need to remember is setting +#define ENDSTOP_Z_BACK_ON_HOME 4 +so we release the z max endstop. This is very important if we move xy at z max. Auto leveling might want to +increase z and the endstop might prevent it causing wrong position and a head crash if we later go down. +The value should be larger then the maximum expected tilt. + +Now it is time to define how we measure the bed rotation. Here again we have several methods to choose. +All methods need at least 3 points to define the bed rotation correctly. The quality we get comes +from the selection of the right points and method. + +BED_LEVELING_METHOD 0 +This method measures at the 3 probe points and creates a plane through these points. If you have +a really planar bed this gives the optimum result. The 3 points must not be in one line and have +a long distance to increase numerical stability. + +BED_LEVELING_METHOD 1 +This measures a grid. Probe point 1 is the origin and points 2 and 3 span a grid. We measure +BED_LEVELING_GRID_SIZE points in each direction and compute a regression plane through all +points. This gives a good overall plane if you have small bumps measuring inaccuracies. + +BED_LEVELING_METHOD 2 +Bending correcting 4 point measurement. This is for cantilevered beds that have the rotation axis +not at the side but inside the bed. Here we can assume no bending on the axis and a symmetric +bending to both sides of the axis. So probe points 2 and 3 build the symmetric axis and +point 1 is mirrored to 1m across the axis. Using the symmetry we then remove the bending +from 1 and use that as plane. + +By now the leveling process is finished. All errors that remain are measuring errors and bumps on +the bed it self. For deltas you can enable distortion correction to follow the bumps. + +There are 2 ways to consider a changing bed coating, which are defined by Z_PROBE_Z_OFFSET_MODE. +Z_PROBE_Z_OFFSET_MODE = 0 means we measure the surface of the bed below any coating. This is e.g. +the case with inductive sensors where we put BuildTak on top. In that case we can set Z_PROBE_Z_OFFSET +to the thickness of BuildTak to compensate. If we later change the coating, we only change Z_PROBE_Z_OFFSET +to new coating thickness. + +Z_PROBE_Z_OFFSET_MODE = 1 means we measure the surface of the coating, e.g. because we have a mechanical switch. +In that case we add Z_PROBE_Z_OFFSET for the measured height to compensate for correct distance to bed surface. + +In homing to max we reduce z length by Z_PROBE_Z_OFFSET to get a correct height. +In homing to z min we assume z endstop is bed level so we move up Z_PROBE_Z_OFFSET after endstop is hit. This +requires the extruder to bend the coating thickness without harm! +*/ + +#include "Repetier.h" + +#ifndef BED_LEVELING_METHOD +#define BED_LEVELING_METHOD 0 +#endif + +#ifndef BED_CORRECTION_METHOD +#define BED_CORRECTION_METHOD 0 +#endif + +#ifndef BED_LEVELING_GRID_SIZE +#define BED_LEVELING_GRID_SIZE 5 +#endif + +#ifndef BED_LEVELING_REPETITIONS +#define BED_LEVELING_REPETITIONS 1 +#endif + + +class PlaneBuilder { + float sum_xx,sum_xy,sum_yy,sum_x,sum_y,sum_xz,sum_yz,sum_z,n; + public: + PlaneBuilder() { + reset(); + } + void reset() { + sum_xx = sum_xy = sum_yy = sum_x = sum_y = sum_xz = sum_yz = sum_z = n = 0; + } + void addPoint(float x,float y,float z) { + n++; + sum_xx += x * x; + sum_xy += x * y; + sum_yy += y * y; + sum_x += x; + sum_y += y; + sum_xz += x * z; + sum_yz += y * z; + sum_z += z; + } + void createPlane(Plane &plane,bool silent=false) { + float det = (sum_x * (sum_xy * sum_y - sum_x * sum_yy) + sum_xx * (n * sum_yy - sum_y * sum_y) + sum_xy * (sum_x * sum_y - n * sum_xy)); + plane.a = ((sum_xy * sum_y - sum_x * sum_yy) * sum_z + (sum_x * sum_y - n * sum_xy) * sum_yz + sum_xz * (n * sum_yy - sum_y * sum_y)) / det; + plane.b = ((sum_x * sum_xy - sum_xx * sum_y) * sum_z + (n * sum_xx - sum_x * sum_x) * sum_yz + sum_xz * (sum_x * sum_y - n * sum_xy)) / det; + plane.c = ((sum_xx * sum_yy - sum_xy * sum_xy) * sum_z + (sum_x * sum_xy - sum_xx * sum_y) * sum_yz + sum_xz * (sum_xy * sum_y - sum_x * sum_yy)) / det; + if(!silent) { + Com::printF(PSTR("plane: a = "),plane.a,4); + Com::printF(PSTR(" b = "),plane.b,4); + Com::printFLN(PSTR(" c = "),plane.c,4); + } + } +}; + +#if FEATURE_AUTOLEVEL && FEATURE_Z_PROBE + +bool measureAutolevelPlane(Plane &plane) { + PlaneBuilder builder; + builder.reset(); +#if BED_LEVELING_METHOD == 0 // 3 point + float h; + Printer::moveTo(EEPROM::zProbeX1(),EEPROM::zProbeY1(),IGNORE_COORDINATE,IGNORE_COORDINATE,EEPROM::zProbeXYSpeed()); + h = Printer::runZProbe(false,false); + if(h == ILLEGAL_Z_PROBE) + return false; + builder.addPoint(EEPROM::zProbeX1(),EEPROM::zProbeY1(),h); + Printer::moveTo(EEPROM::zProbeX2(),EEPROM::zProbeY2(),IGNORE_COORDINATE,IGNORE_COORDINATE,EEPROM::zProbeXYSpeed()); + h = Printer::runZProbe(false,false); + if(h == ILLEGAL_Z_PROBE) + return false; + builder.addPoint(EEPROM::zProbeX2(),EEPROM::zProbeY2(),h); + Printer::moveTo(EEPROM::zProbeX3(),EEPROM::zProbeY3(),IGNORE_COORDINATE,IGNORE_COORDINATE,EEPROM::zProbeXYSpeed()); + h = Printer::runZProbe(false,false); + if(h == ILLEGAL_Z_PROBE) + return false; + builder.addPoint(EEPROM::zProbeX3(),EEPROM::zProbeY3(),h); +#elif BED_LEVELING_METHOD == 1 // linear regression + float delta = 1.0 / (BED_LEVELING_GRID_SIZE - 1); + float ox = EEPROM::zProbeX1(); + float oy = EEPROM::zProbeY1(); + float ax = delta * (EEPROM::zProbeX2() - EEPROM::zProbeX1()); + float ay = delta * (EEPROM::zProbeY2() - EEPROM::zProbeY1()); + float bx = delta * (EEPROM::zProbeX3() - EEPROM::zProbeX1()); + float by = delta * (EEPROM::zProbeY3() - EEPROM::zProbeY1()); + for(int ix = 0; ix < BED_LEVELING_GRID_SIZE; ix++) { + for(int iy = 0; iy < BED_LEVELING_GRID_SIZE; iy++) { + float px = ox + static_cast(ix) * ax + static_cast(iy) * bx; + float py = oy + static_cast(ix) * ay + static_cast(iy) * by; + Printer::moveTo(px,py,IGNORE_COORDINATE,IGNORE_COORDINATE,EEPROM::zProbeXYSpeed()); + float h = Printer::runZProbe(false,false); + if(h == ILLEGAL_Z_PROBE) + return false; + builder.addPoint(px,py,h); + } + } + +#elif BED_LEVELING_METHOD == 2 // 4 point symmetric + float h1,h2,h3,h4; + float apx = EEPROM::zProbeX1() - EEPROM::zProbeX2(); + float apy = EEPROM::zProbeY1() - EEPROM::zProbeY2(); + float abx = EEPROM::zProbeX3() - EEPROM::zProbeX2(); + float aby = EEPROM::zProbeY3() - EEPROM::zProbeY2(); + float ab2 = abx * abx + aby * aby; + float abap = apx * abx + apy * aby; + float t = abap / ab2; + float xx = EEPROM::zProbeX2() + t * abx; + float xy = EEPROM::zProbeY2() + t * aby; + float x1Mirror = EEPROM::zProbeX1() + 2.0 * (xx - EEPROM::zProbeX1()); + float y1Mirror = EEPROM::zProbeY1() + 2.0 * (xy - EEPROM::zProbeY1()); + Printer::moveTo(EEPROM::zProbeX1(),EEPROM::zProbeY1(),IGNORE_COORDINATE,IGNORE_COORDINATE,EEPROM::zProbeXYSpeed()); + h1 = Printer::runZProbe(false,false); + if(h1 == ILLEGAL_Z_PROBE) + return false; + Printer::moveTo(EEPROM::zProbeX2(),EEPROM::zProbeY2(),IGNORE_COORDINATE,IGNORE_COORDINATE,EEPROM::zProbeXYSpeed()); + h2 = Printer::runZProbe(false,false); + if(h2 == ILLEGAL_Z_PROBE) + return false; + Printer::moveTo(EEPROM::zProbeX3(),EEPROM::zProbeY3(),IGNORE_COORDINATE,IGNORE_COORDINATE,EEPROM::zProbeXYSpeed()); + h3 = Printer::runZProbe(false,false); + if(h3 == ILLEGAL_Z_PROBE) + return false; + Printer::moveTo(x1Mirror,y1Mirror,IGNORE_COORDINATE,IGNORE_COORDINATE,EEPROM::zProbeXYSpeed()); + h4 = Printer::runZProbe(false,false); + if(h4 == ILLEGAL_Z_PROBE) + return false; + t = h2 + (h3 - h2) * t; // theoretical height for crossing point for symmetric axis + h1 = t - (h4 - h1) * 0.5; // remove bending part + builder.addPoint(EEPROM::zProbeX1(), EEPROM::zProbeY1(), h1); + builder.addPoint(EEPROM::zProbeX2(), EEPROM::zProbeY2(), h2); + builder.addPoint(EEPROM::zProbeX3(), EEPROM::zProbeY3(), h3); +#else +#error Unknown bed leveling method +#endif + builder.createPlane(plane,false); + return true; +} + +void correctAutolevel(GCode *code,Plane &plane) { +#if BED_CORRECTION_METHOD == 0 // rotation matrix + //Printer::buildTransformationMatrix(plane.z(EEPROM::zProbeX1(),EEPROM::zProbeY1()),plane.z(EEPROM::zProbeX2(),EEPROM::zProbeY2()),plane.z(EEPROM::zProbeX3(),EEPROM::zProbeY3())); + Printer::buildTransformationMatrix(plane); +#elif BED_CORRECTION_METHOD == 1 // motorized correction +#if !defined(NUM_MOTOR_DRIVERS) || NUM_MOTOR_DRIVERS < 2 +#error You need to define 2 motors for motorized bed correction +#endif + Commands::waitUntilEndOfAllMoves(); // move steppers might be leveling steppers as well ! + float h1 = plane.z(BED_MOTOR_1_X,BED_MOTOR_1_Y); + float h2 = plane.z(BED_MOTOR_2_X,BED_MOTOR_2_Y); + float h3 = plane.z(BED_MOTOR_3_X,BED_MOTOR_3_Y); + // h1 is reference heights, h2 => motor 0, h3 => motor 1 + h2 -= h1; + h3 -= h1; +#if defined(LIMIT_MOTORIZED_CORRECTION) + if(h2 < -LIMIT_MOTORIZED_CORRECTION) h2 = -LIMIT_MOTORIZED_CORRECTION; + if(h2 > LIMIT_MOTORIZED_CORRECTION) h2 = LIMIT_MOTORIZED_CORRECTION; + if(h3 < -LIMIT_MOTORIZED_CORRECTION) h3 = -LIMIT_MOTORIZED_CORRECTION; + if(h3 > LIMIT_MOTORIZED_CORRECTION) h3 = LIMIT_MOTORIZED_CORRECTION; +#endif + MotorDriverInterface *motor2 = getMotorDriver(0); + MotorDriverInterface *motor3 = getMotorDriver(1); + motor2->setCurrentAs(0); + motor3->setCurrentAs(0); + motor2->gotoPosition(h2); + motor3->gotoPosition(h3); + motor2->disable(); + motor3->disable(); // now bed is even + Printer::currentPositionSteps[Z_AXIS] = h1 * Printer::axisStepsPerMM[Z_AXIS]; +#else +#error Unknown bed correction method set +#endif +} + +/* +Implementation of the G32 command +G32 S<0..2> - Autolevel print bed. S = 1 measure zLength, S = 2 Measure and store new zLength +S = 0 : Do not update length - use this if you have not homed before or you mess up zlength! +S = 1 : Measure zLength so homing works +S = 2 : Like s = 1 plus store results in EEPROM for next connection. +*/ +bool runBedLeveling(GCode *com) { + float h1,h2,h3,hc,oldFeedrate = Printer::feedrate; + int s = com->hasS() ? com->S : -1; +#if DISTORTION_CORRECTION + bool distEnabled = Printer::distortion.isEnabled(); + Printer::distortion.disable(false); // if level has changed, distortion is also invalid +#endif + Printer::setAutolevelActive(false); // iterate + Printer::resetTransformationMatrix(true); // in case we switch from matrix to motorized! +#if DRIVE_SYSTEM == DELTA + // It is not possible to go to the edges at the top, also users try + // it often and wonder why the coordinate system is then wrong. + // For that reason we ensure a correct behavior by code. + Printer::homeAxis(true, true, true); + Printer::moveTo(IGNORE_COORDINATE, IGNORE_COORDINATE, EEPROM::zProbeBedDistance() + EEPROM::zProbeHeight(), IGNORE_COORDINATE, Printer::homingFeedrate[Z_AXIS]); +#endif + Printer::startProbing(true); + //GCode::executeFString(Com::tZProbeStartScript); + Printer::coordinateOffset[X_AXIS] = Printer::coordinateOffset[Y_AXIS] = Printer::coordinateOffset[Z_AXIS] = 0; + Plane plane; +#if BED_CORRECTION_METHOD == 1 + for(int r = 0; r < BED_LEVELING_REPETITIONS; r++) { +#if DRIVE_SYSTEM == DELTA + if(r > 0) { + Printer::finishProbing(); + Printer::homeAxis(true, true, true); + Printer::moveTo(IGNORE_COORDINATE, IGNORE_COORDINATE, EEPROM::zProbeBedDistance() + EEPROM::zProbeHeight(), IGNORE_COORDINATE, Printer::homingFeedrate[Z_AXIS]); + Printer::startProbing(true); + } +#endif +#endif + if(!measureAutolevelPlane(plane)) { + Com::printErrorFLN(PSTR("Probing had returned errors - autoleveling canceled.")); + return false; + } + correctAutolevel(com,plane); + + // Leveling is finished now update own positions and store leveling data if needed + float currentZ = plane.z((float)Printer::currentPositionSteps[X_AXIS] * Printer::invAxisStepsPerMM[X_AXIS],(float)Printer::currentPositionSteps[Y_AXIS] * Printer::invAxisStepsPerMM[Y_AXIS]); + Com::printF(PSTR("CurrentZ:"),currentZ); + Com::printFLN(PSTR(" atZ:"),Printer::currentPosition[Z_AXIS]); + // With max z endstop we adjust zlength so after next homing we have also a calibrated printer + Printer::zMin = 0; +#if MAX_HARDWARE_ENDSTOP_Z + float xRot,yRot,zRot; + Printer::transformFromPrinter(Printer::currentPosition[X_AXIS],Printer::currentPosition[Y_AXIS],Printer::currentPosition[Z_AXIS],xRot,yRot,zRot); + Com::printFLN(PSTR("Z after rotation:"),zRot); + // With max z endstop we adjust zlength so after next homing we have also a calibrated printer + if(s != 0) { + Printer::zLength += currentZ - zRot; + Com::printFLN(Com::tZProbePrinterHeight, Printer::zLength); + } +#endif + Printer::currentPositionSteps[Z_AXIS] = currentZ * Printer::axisStepsPerMM[Z_AXIS]; + Printer::updateCurrentPosition(true); +#if BED_CORRECTION_METHOD == 1 + if(fabs(plane.a) < 0.00025 && fabsf(plane.b) < 0.00025 ) + break; // we reached achievable precision so we can stop + } +#endif + Printer::updateDerivedParameter(); + Printer::finishProbing(); +#if BED_CORRECTION_METHOD != 1 + Printer::setAutolevelActive(true); // only for software correction or we can spare the comp. time +#endif + if(s >= 2) { + EEPROM::storeDataIntoEEPROM(); + } + Printer::updateCurrentPosition(true); + Commands::printCurrentPosition(PSTR("G32 ")); +#if DISTORTION_CORRECTION + if(distEnabled) + Printer::distortion.enable(false); // if level has changed, distortion is also invalid +#endif +#if DRIVE_SYSTEM == DELTA + Printer::homeAxis(true, true, true); // shifting z makes positioning invalid, need to recalibrate +#endif + Printer::feedrate = oldFeedrate; + return true; +} + +#endif + +void Printer::setAutolevelActive(bool on) { +#if FEATURE_AUTOLEVEL + if(on == isAutolevelActive()) return; + flag0 = (on ? flag0 | PRINTER_FLAG0_AUTOLEVEL_ACTIVE : flag0 & ~PRINTER_FLAG0_AUTOLEVEL_ACTIVE); + if(on) + Com::printInfoFLN(Com::tAutolevelEnabled); + else + Com::printInfoFLN(Com::tAutolevelDisabled); + updateCurrentPosition(false); +#endif // FEATURE_AUTOLEVEL +} +#if MAX_HARDWARE_ENDSTOP_Z +float Printer::runZMaxProbe() { +#if NONLINEAR_SYSTEM + long startZ = realDeltaPositionSteps[Z_AXIS] = currentNonlinearPositionSteps[Z_AXIS]; // update real +#endif + Commands::waitUntilEndOfAllMoves(); + long probeDepth = 2*(Printer::zMaxSteps-Printer::zMinSteps); + stepsRemainingAtZHit = -1; + setZProbingActive(true); + PrintLine::moveRelativeDistanceInSteps(0,0,probeDepth,0,EEPROM::zProbeSpeed(),true,true); + if(stepsRemainingAtZHit < 0) { + Com::printErrorFLN(PSTR("z-max homing failed")); + return ILLEGAL_Z_PROBE; + } + setZProbingActive(false); + currentPositionSteps[Z_AXIS] -= stepsRemainingAtZHit; +#if NONLINEAR_SYSTEM + probeDepth -= (realDeltaPositionSteps[Z_AXIS] - startZ); +#else + probeDepth -= stepsRemainingAtZHit; +#endif + float distance = (float)probeDepth * invAxisStepsPerMM[Z_AXIS]; + Com::printF(Com::tZProbeMax,distance); + Com::printF(Com::tSpaceXColon,realXPosition()); + Com::printFLN(Com::tSpaceYColon,realYPosition()); + PrintLine::moveRelativeDistanceInSteps(0,0,-probeDepth,0,EEPROM::zProbeSpeed(),true,true); + return distance; +} +#endif + +#if FEATURE_Z_PROBE +void Printer::startProbing(bool runScript) { + float oldOffX = Printer::offsetX; + float oldOffY = Printer::offsetY; + float oldOffZ = Printer::offsetZ; + if(runScript) + GCode::executeFString(Com::tZProbeStartScript); + float maxStartHeight = EEPROM::zProbeBedDistance() + (EEPROM::zProbeHeight() > 0 ? EEPROM::zProbeHeight() : 0) + 0.1; + if(currentPosition[Z_AXIS] > maxStartHeight) { + moveTo(IGNORE_COORDINATE, IGNORE_COORDINATE, maxStartHeight, IGNORE_COORDINATE, homingFeedrate[Z_AXIS]); + } + Printer::offsetX = -EEPROM::zProbeXOffset(); + Printer::offsetY = -EEPROM::zProbeYOffset(); + Printer::offsetZ = 0; // we correct this with probe height + PrintLine::moveRelativeDistanceInSteps((Printer::offsetX - oldOffX) * Printer::axisStepsPerMM[X_AXIS], + (Printer::offsetY - oldOffY) * Printer::axisStepsPerMM[Y_AXIS], + 0, 0, EEPROM::zProbeXYSpeed(), true, ALWAYS_CHECK_ENDSTOPS); +} + +void Printer::finishProbing() { + float oldOffX = Printer::offsetX; + float oldOffY = Printer::offsetY; + float oldOffZ = Printer::offsetZ; + GCode::executeFString(Com::tZProbeEndScript); + if(Extruder::current) { + Printer::offsetX = -Extruder::current->xOffset * Printer::invAxisStepsPerMM[X_AXIS]; + Printer::offsetY = -Extruder::current->yOffset * Printer::invAxisStepsPerMM[Y_AXIS]; + Printer::offsetZ = -Extruder::current->zOffset * Printer::invAxisStepsPerMM[Z_AXIS]; + } + PrintLine::moveRelativeDistanceInSteps((Printer::offsetX - oldOffX) * Printer::axisStepsPerMM[X_AXIS], + (Printer::offsetY - oldOffY) * Printer::axisStepsPerMM[Y_AXIS], + (Printer::offsetZ - oldOffZ) * Printer::axisStepsPerMM[Z_AXIS], 0, EEPROM::zProbeXYSpeed(), true, ALWAYS_CHECK_ENDSTOPS); +} + +/* +This is the most important function for bed leveling. It does +1. Run probe start script if first = true and runStartScript = true +2. Position zProbe at current position if first = true. If we are more then maxStartHeight away from bed we also go down to that distance. +3. Measure the the steps until probe hits the bed. +4. Undo positioning to z probe and run finish script if last = true. + +Now we compute the nozzle height as follows: +a) Compute average height from repeated measurements +b) Add zProbeHeight to correct difference between triggering point and nozzle height above bed +c) If Z_PROBE_Z_OFFSET_MODE == 1 we add zProbeZOffset() that is coating thickness if we measure below coating with indictive sensor. +d) Add distortion correction. +e) Add bending correction + +Then we return the measured and corrected z distance. +*/ +float Printer::runZProbe(bool first,bool last,uint8_t repeat,bool runStartScript) { + float oldOffX = Printer::offsetX; + float oldOffY = Printer::offsetY; + float oldOffZ = Printer::offsetZ; + if(first) + startProbing(runStartScript); + Commands::waitUntilEndOfAllMoves(); + int32_t sum = 0, probeDepth; + int32_t shortMove = static_cast((float)Z_PROBE_SWITCHING_DISTANCE * axisStepsPerMM[Z_AXIS]); // distance to go up for repeated moves + int32_t lastCorrection = currentPositionSteps[Z_AXIS]; // starting position +#if NONLINEAR_SYSTEM + realDeltaPositionSteps[Z_AXIS] = currentNonlinearPositionSteps[Z_AXIS]; // update real +#endif + //int32_t updateZ = 0; + waitForZProbeStart(); + Endstops::update(); + Endstops::update(); + if(Endstops::zProbe()) { + Com::printErrorFLN(PSTR("z-probe triggered before starting probing.")); + return ILLEGAL_Z_PROBE; + } + for(int8_t r = 0; r < repeat; r++) { + probeDepth = 2 * (Printer::zMaxSteps - Printer::zMinSteps); // probe should always hit within this distance + stepsRemainingAtZHit = -1; // Marker that we did not hit z probe + //int32_t offx = axisStepsPerMM[X_AXIS] * EEPROM::zProbeXOffset(); + //int32_t offy = axisStepsPerMM[Y_AXIS] * EEPROM::zProbeYOffset(); + //PrintLine::moveRelativeDistanceInSteps(-offx,-offy,0,0,EEPROM::zProbeXYSpeed(),true,true); + setZProbingActive(true); + PrintLine::moveRelativeDistanceInSteps(0, 0, -probeDepth, 0, EEPROM::zProbeSpeed(), true, true); + if(stepsRemainingAtZHit < 0) { + Com::printErrorFLN(Com::tZProbeFailed); + return ILLEGAL_Z_PROBE; + } + setZProbingActive(false); +#if NONLINEAR_SYSTEM + stepsRemainingAtZHit = realDeltaPositionSteps[C_TOWER] - currentNonlinearPositionSteps[C_TOWER]; // nonlinear moves may split z so stepsRemainingAtZHit is only what is left from last segment not total move. This corrects the problem. +#endif +#if DRIVE_SYSTEM == DELTA + currentNonlinearPositionSteps[A_TOWER] += stepsRemainingAtZHit; // Update difference + currentNonlinearPositionSteps[B_TOWER] += stepsRemainingAtZHit; + currentNonlinearPositionSteps[C_TOWER] += stepsRemainingAtZHit; +#endif + currentPositionSteps[Z_AXIS] += stepsRemainingAtZHit; // now current position is correct + sum += lastCorrection - currentPositionSteps[Z_AXIS]; + if(r + 1 < repeat) { + // go only shortest possible move up for repetitions + PrintLine::moveRelativeDistanceInSteps(0, 0, shortMove, 0, EEPROM::zProbeSpeed(), true, true); + if(Endstops::zProbe()) { + Com::printErrorFLN(PSTR("z-probe did not untrigger on repetitive measurement - maybe you need to increase distance!")); + return ILLEGAL_Z_PROBE; + } + } + } + float distance = static_cast(sum) * invAxisStepsPerMM[Z_AXIS] / static_cast(repeat) + EEPROM::zProbeHeight(); +#if Z_PROBE_Z_OFFSET_MODE == 1 + distance += EEPROM::zProbeZOffset(); // We measured including coating, so we need to add coating thickness! +#endif +#if DISTORTION_CORRECTION + float zCorr = 0; + if(Printer::distortion.isEnabled()) { + zCorr = distortion.correct(currentPositionSteps[X_AXIS] + EEPROM::zProbeXOffset() * axisStepsPerMM[X_AXIS],currentPositionSteps[Y_AXIS] + + EEPROM::zProbeYOffset() * axisStepsPerMM[Y_AXIS],0) * invAxisStepsPerMM[Z_AXIS]; + distance += zCorr; + } +#endif + distance += bendingCorrectionAt(currentPosition[X_AXIS], currentPosition[Y_AXIS]); + Com::printF(Com::tZProbe, distance); + Com::printF(Com::tSpaceXColon, realXPosition()); +#if DISTORTION_CORRECTION + if(Printer::distortion.isEnabled()) { + Com::printF(Com::tSpaceYColon, realYPosition()); + Com::printFLN(PSTR(" zCorr:"), zCorr); + } else { + Com::printFLN(Com::tSpaceYColon, realYPosition()); + } +#else + Com::printFLN(Com::tSpaceYColon, realYPosition()); +#endif + // Go back to start position + PrintLine::moveRelativeDistanceInSteps(0, 0, lastCorrection - currentPositionSteps[Z_AXIS], 0, EEPROM::zProbeSpeed(), true, true); + if(Endstops::zProbe()) { + Com::printErrorFLN(PSTR("z-probe did not untrigger after going back to start position.")); + return ILLEGAL_Z_PROBE; + } + //PrintLine::moveRelativeDistanceInSteps(offx,offy,0,0,EEPROM::zProbeXYSpeed(),true,true); + if(last) + finishProbing(); + return distance; +} + +float Printer::bendingCorrectionAt(float x, float y) { + PlaneBuilder builder; + builder.addPoint(EEPROM::zProbeX1(),EEPROM::zProbeY1(),EEPROM::bendingCorrectionA()); + builder.addPoint(EEPROM::zProbeX2(),EEPROM::zProbeY2(),EEPROM::bendingCorrectionB()); + builder.addPoint(EEPROM::zProbeX3(),EEPROM::zProbeY3(),EEPROM::bendingCorrectionC()); + Plane plane; + builder.createPlane(plane,true); + return plane.z(x,y); +} + +void Printer::waitForZProbeStart() { +#if Z_PROBE_WAIT_BEFORE_TEST + Endstops::update(); + Endstops::update(); // double test to get right signal. Needed for crosstalk protection. + if(Endstops::zProbe()) return; +#if UI_DISPLAY_TYPE != NO_DISPLAY + uid.setStatusP(Com::tHitZProbe); + uid.refreshPage(); +#endif +#ifdef DEBUG_PRINT + debugWaitLoop = 3; +#endif + while(!Endstops::zProbe()) { + defaultLoopActions(); + Endstops::update(); + Endstops::update(); // double test to get right signal. Needed for crosstalk protection. + } +#ifdef DEBUG_PRINT + debugWaitLoop = 4; +#endif + HAL::delayMilliseconds(30); + while(Endstops::zProbe()) { + defaultLoopActions(); + Endstops::update(); + Endstops::update(); // double test to get right signal. Needed for crosstalk protection. + } + HAL::delayMilliseconds(30); + UI_CLEAR_STATUS; +#endif +} +#endif + +void Printer::transformToPrinter(float x,float y,float z,float &transX,float &transY,float &transZ) { +#if FEATURE_AXISCOMP + // Axis compensation: + x = x + y * EEPROM::axisCompTanXY() + z * EEPROM::axisCompTanXZ(); + y = y + z * EEPROM::axisCompTanYZ(); +#endif +#if BED_CORRECTION_METHOD != 1 && FEATURE_AUTOLEVEL + if(isAutolevelActive()) { + transX = x * autolevelTransformation[0] + y * autolevelTransformation[3] + z * autolevelTransformation[6]; + transY = x * autolevelTransformation[1] + y * autolevelTransformation[4] + z * autolevelTransformation[7]; + transZ = x * autolevelTransformation[2] + y * autolevelTransformation[5] + z * autolevelTransformation[8]; + } else { + transX = x; + transY = y; + transZ = z; + } +#else + transX = x; + transY = y; + transZ = z; +#endif +} + +void Printer::transformFromPrinter(float x,float y,float z,float &transX,float &transY,float &transZ) { +#if BED_CORRECTION_METHOD != 1 && FEATURE_AUTOLEVEL + if(isAutolevelActive()) { + transX = x * autolevelTransformation[0] + y * autolevelTransformation[1] + z * autolevelTransformation[2]; + transY = x * autolevelTransformation[3] + y * autolevelTransformation[4] + z * autolevelTransformation[5]; + transZ = x * autolevelTransformation[6] + y * autolevelTransformation[7] + z * autolevelTransformation[8]; + } else { + transX = x; + transY = y; + transZ = z; + } +#else + transX = x; + transY = y; + transZ = z; +#endif +#if FEATURE_AXISCOMP + // Axis compensation: + transY = transY - transZ * EEPROM::axisCompTanYZ(); + transX = transX - transY * EEPROM::axisCompTanXY() - transZ * EEPROM::axisCompTanXZ(); +#endif +} +#if FEATURE_AUTOLEVEL +void Printer::resetTransformationMatrix(bool silent) { + autolevelTransformation[0] = autolevelTransformation[4] = autolevelTransformation[8] = 1; + autolevelTransformation[1] = autolevelTransformation[2] = autolevelTransformation[3] = + autolevelTransformation[5] = autolevelTransformation[6] = autolevelTransformation[7] = 0; + if(!silent) + Com::printInfoFLN(Com::tAutolevelReset); +} + +void Printer::buildTransformationMatrix(Plane &plane) { + float z0 = plane.z(0,0); + float az = z0-plane.z(1,0); // ax = 1, ay = 0 + float bz = z0-plane.z(0,1); // bx = 0, by = 1 + // First z direction + autolevelTransformation[6] = -az; + autolevelTransformation[7] = -bz; + autolevelTransformation[8] = 1; + float len = sqrt(az * az + bz * bz + 1); + autolevelTransformation[6] /= len; + autolevelTransformation[7] /= len; + autolevelTransformation[8] /= len; + autolevelTransformation[0] = 1; + autolevelTransformation[1] = 0; + autolevelTransformation[2] = -autolevelTransformation[6]/autolevelTransformation[8]; + len = sqrt(autolevelTransformation[0] * autolevelTransformation[0] + autolevelTransformation[1] * autolevelTransformation[1] + autolevelTransformation[2] * autolevelTransformation[2]); + autolevelTransformation[0] /= len; + autolevelTransformation[1] /= len; + autolevelTransformation[2] /= len; + // cross(z,x) y,z) + autolevelTransformation[3] = autolevelTransformation[7] * autolevelTransformation[2] - autolevelTransformation[8] * autolevelTransformation[1]; + autolevelTransformation[4] = autolevelTransformation[8] * autolevelTransformation[0] - autolevelTransformation[6] * autolevelTransformation[2]; + autolevelTransformation[5] = autolevelTransformation[6] * autolevelTransformation[1] - autolevelTransformation[7] * autolevelTransformation[0]; + len = sqrt(autolevelTransformation[3] * autolevelTransformation[3] + autolevelTransformation[4] * autolevelTransformation[4] + autolevelTransformation[5] * autolevelTransformation[5]); + autolevelTransformation[3] /= len; + autolevelTransformation[4] /= len; + autolevelTransformation[5] /= len; + + Com::printArrayFLN(Com::tTransformationMatrix,autolevelTransformation, 9, 6); +} +/* +void Printer::buildTransformationMatrix(float h1,float h2,float h3) { + float ax = EEPROM::zProbeX2() - EEPROM::zProbeX1(); + float ay = EEPROM::zProbeY2() - EEPROM::zProbeY1(); + float az = h1 - h2; + float bx = EEPROM::zProbeX3() - EEPROM::zProbeX1(); + float by = EEPROM::zProbeY3() - EEPROM::zProbeY1(); + float bz = h1 - h3; + // First z direction + autolevelTransformation[6] = ay * bz - az * by; + autolevelTransformation[7] = az * bx - ax * bz; + autolevelTransformation[8] = ax * by - ay * bx; + float len = sqrt(autolevelTransformation[6] * autolevelTransformation[6] + autolevelTransformation[7] * autolevelTransformation[7] + autolevelTransformation[8] * autolevelTransformation[8]); + if(autolevelTransformation[8] < 0) len = -len; + autolevelTransformation[6] /= len; + autolevelTransformation[7] /= len; + autolevelTransformation[8] /= len; + autolevelTransformation[3] = 0; + autolevelTransformation[4] = autolevelTransformation[8]; + autolevelTransformation[5] = -autolevelTransformation[7]; + // cross(y,z) + autolevelTransformation[0] = autolevelTransformation[4] * autolevelTransformation[8] - autolevelTransformation[5] * autolevelTransformation[7]; + autolevelTransformation[1] = autolevelTransformation[5] * autolevelTransformation[6];// - autolevelTransformation[3] * autolevelTransformation[8]; + autolevelTransformation[2] = autolevelTransformation[3] * autolevelTransformation[7] - autolevelTransformation[4] * autolevelTransformation[6]; + len = sqrt(autolevelTransformation[0] * autolevelTransformation[0] + autolevelTransformation[1] * autolevelTransformation[1] + autolevelTransformation[2] * autolevelTransformation[2]); + autolevelTransformation[0] /= len; + autolevelTransformation[1] /= len; + autolevelTransformation[2] /= len; + len = sqrt(autolevelTransformation[4] * autolevelTransformation[4] + autolevelTransformation[5] * autolevelTransformation[5]); + autolevelTransformation[4] /= len; + autolevelTransformation[5] /= len; + Com::printArrayFLN(Com::tTransformationMatrix,autolevelTransformation, 9, 6); +} +*/ +#endif diff --git a/trunk/Arduino/Repetier_0.92.9/Commands.cpp b/trunk/Arduino/Repetier_0.92.9/Commands.cpp new file mode 100644 index 00000000..7f702628 --- /dev/null +++ b/trunk/Arduino/Repetier_0.92.9/Commands.cpp @@ -0,0 +1,2463 @@ +/* +This file is part of Repetier-Firmware. + +Repetier-Firmware is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Repetier-Firmware is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Repetier-Firmware. If not, see . + +This firmware is a nearly complete rewrite of the sprinter firmware +by kliment (https://github.com/kliment/Sprinter) +which based on Tonokip RepRap firmware rewrite based off of Hydra-mmm firmware. +*/ + +#include "Repetier.h" + +const int8_t sensitive_pins[] PROGMEM = SENSITIVE_PINS; // Sensitive pin list for M42 +int Commands::lowestRAMValue = MAX_RAM; +int Commands::lowestRAMValueSend = MAX_RAM; + +void Commands::commandLoop() { + while(true) { +#ifdef DEBUG_PRINT + debugWaitLoop = 1; +#endif + if(!Printer::isBlockingReceive()) { + GCode::readFromSerial(); + GCode *code = GCode::peekCurrentCommand(); + //UI_SLOW; // do longer timed user interface action + UI_MEDIUM; // do check encoder + if(code) { +#if SDSUPPORT + if(sd.savetosd) { + if(!(code->hasM() && code->M == 29)) // still writing to file + sd.writeCommand(code); + else + sd.finishWrite(); +#if ECHO_ON_EXECUTE + code->echoCommand(); +#endif + } else +#endif + Commands::executeGCode(code); + code->popCurrentCommand(); + } + } else { + UI_MEDIUM; + } + Printer::defaultLoopActions(); + } +} + +void Commands::checkForPeriodicalActions(bool allowNewMoves) { + Printer::handleInterruptEvent(); + EVENT_PERIODICAL; + if(!executePeriodical) return; + executePeriodical = 0; + EVENT_TIMER_100MS; + Extruder::manageTemperatures(); + if(--counter250ms == 0) { + if(manageMonitor) + writeMonitor(); + counter250ms = 5; + EVENT_TIMER_500MS; + } + // If called from queueDelta etc. it is an error to start a new move since it + // would invalidate old computation resulting in unpredicted behavior. + // lcd controller can start new moves, so we disallow it if called from within + // a move command. + UI_SLOW(allowNewMoves); +} + +/** \brief Waits until movement cache is empty. + +Some commands expect no movement, before they can execute. This function +waits, until the steppers are stopped. In the meanwhile it buffers incoming +commands and manages temperatures. +*/ +void Commands::waitUntilEndOfAllMoves() { +#ifdef DEBUG_PRINT + debugWaitLoop = 8; +#endif + while(PrintLine::hasLines()) { + GCode::readFromSerial(); + checkForPeriodicalActions(false); + UI_MEDIUM; + } +} + +void Commands::waitUntilEndOfAllBuffers() { + GCode *code = NULL; +#ifdef DEBUG_PRINT + debugWaitLoop = 9; +#endif + while(PrintLine::hasLines() || (code != NULL)) { + GCode::readFromSerial(); + code = GCode::peekCurrentCommand(); + UI_MEDIUM; // do check encoder + if(code) { +#if SDSUPPORT + if(sd.savetosd) { + if(!(code->hasM() && code->M == 29)) // still writing to file + sd.writeCommand(code); + else + sd.finishWrite(); +#if ECHO_ON_EXECUTE + code->echoCommand(); +#endif + } else +#endif + Commands::executeGCode(code); + code->popCurrentCommand(); + } + Commands::checkForPeriodicalActions(false); // only called from memory + UI_MEDIUM; + } +} + +void Commands::printCurrentPosition(FSTRINGPARAM(s)) { + float x, y, z; + Printer::realPosition(x, y, z); + if (isnan(x) || isinf(x) || isnan(y) || isinf(y) || isnan(z) || isinf(z)) { + Com::printErrorFLN(s); // flag where the error condition came from + } + x += Printer::coordinateOffset[X_AXIS]; + y += Printer::coordinateOffset[Y_AXIS]; + z += Printer::coordinateOffset[Z_AXIS]; + Com::printF(Com::tXColon, x * (Printer::unitIsInches ? 0.03937 : 1), 2); + Com::printF(Com::tSpaceYColon, y * (Printer::unitIsInches ? 0.03937 : 1), 2); + Com::printF(Com::tSpaceZColon, z * (Printer::unitIsInches ? 0.03937 : 1), 3); + Com::printFLN(Com::tSpaceEColon, Printer::currentPositionSteps[E_AXIS] * Printer::invAxisStepsPerMM[E_AXIS] * (Printer::unitIsInches ? 0.03937 : 1), 4); + //Com::printF(PSTR("OffX:"),Printer::offsetX); // to debug offset handling + //Com::printFLN(PSTR(" OffY:"),Printer::offsetY); +} + +void Commands::printTemperatures(bool showRaw) { +#if NUM_EXTRUDER > 0 + float temp = Extruder::current->tempControl.currentTemperatureC; +#if HEATED_BED_SENSOR_TYPE == 0 + Com::printF(Com::tTColon,temp); + Com::printF(Com::tSpaceSlash,Extruder::current->tempControl.targetTemperatureC,0); +#else + Com::printF(Com::tTColon,temp); + Com::printF(Com::tSpaceSlash,Extruder::current->tempControl.targetTemperatureC,0); +#if HAVE_HEATED_BED + Com::printF(Com::tSpaceBColon,Extruder::getHeatedBedTemperature()); + Com::printF(Com::tSpaceSlash,heatedBedController.targetTemperatureC,0); + if(showRaw) { + Com::printF(Com::tSpaceRaw,(int)NUM_EXTRUDER); + Com::printF(Com::tColon,(1023 << (2 - ANALOG_REDUCE_BITS)) - heatedBedController.currentTemperature); + } + Com::printF(Com::tSpaceBAtColon,(pwm_pos[heatedBedController.pwmIndex])); // Show output of auto tune when tuning! +#endif +#endif +#if TEMP_PID + Com::printF(Com::tSpaceAtColon,(autotuneIndex == 255 ? pwm_pos[Extruder::current->id] : pwm_pos[autotuneIndex])); // Show output of auto tune when tuning! +#endif +#if NUM_EXTRUDER > 1 && MIXING_EXTRUDER == 0 + for(uint8_t i = 0; i < NUM_EXTRUDER; i++) { + Com::printF(Com::tSpaceT,(int)i); + Com::printF(Com::tColon,extruder[i].tempControl.currentTemperatureC); + Com::printF(Com::tSpaceSlash,extruder[i].tempControl.targetTemperatureC,0); +#if TEMP_PID + Com::printF(Com::tSpaceAt,(int)i); + Com::printF(Com::tColon,(pwm_pos[extruder[i].tempControl.pwmIndex])); // Show output of autotune when tuning! +#endif + if(showRaw) { + Com::printF(Com::tSpaceRaw,(int)i); + Com::printF(Com::tColon,(1023 << (2 - ANALOG_REDUCE_BITS)) - extruder[i].tempControl.currentTemperature); + } + } +#elif NUM_EXTRUDER == 1 + if(showRaw) { + Com::printF(Com::tSpaceRaw,(int)0); + Com::printF(Com::tColon,(1023 << (2 - ANALOG_REDUCE_BITS)) - extruder[0].tempControl.currentTemperature); + } +#endif + Com::println(); +#endif +} +void Commands::changeFeedrateMultiply(int factor) { + if(factor < 25) factor = 25; + if(factor > 500) factor = 500; + Printer::feedrate *= (float)factor / (float)Printer::feedrateMultiply; + Printer::feedrateMultiply = factor; + Com::printFLN(Com::tSpeedMultiply, factor); +} + +void Commands::changeFlowrateMultiply(int factor) { + if(factor < 25) factor = 25; + if(factor > 200) factor = 200; + Printer::extrudeMultiply = factor; + if(Extruder::current->diameter <= 0) + Printer::extrusionFactor = 0.01f * static_cast(factor); + else + Printer::extrusionFactor = 0.01f * static_cast(factor) * 4.0f / (Extruder::current->diameter * Extruder::current->diameter * 3.141592654f); + Com::printFLN(Com::tFlowMultiply, factor); +} + +#if FEATURE_FAN_CONTROL +uint8_t fanKickstart; +#endif +#if FEATURE_FAN2_CONTROL +uint8_t fan2Kickstart; +#endif + +void Commands::setFanSpeed(int speed, bool immediately) { +#if FAN_PIN >- 1 && FEATURE_FAN_CONTROL + if(Printer::fanSpeed == speed) + return; + speed = constrain(speed,0,255); + Printer::setMenuMode(MENU_MODE_FAN_RUNNING,speed != 0); + Printer::fanSpeed = speed; + if(PrintLine::linesCount == 0 || immediately) { + if(Printer::mode == PRINTER_MODE_FFF) { + for(fast8_t i = 0; i < PRINTLINE_CACHE_SIZE; i++) + PrintLine::lines[i].secondSpeed = speed; // fill all printline buffers with new fan speed value + } + Printer::setFanSpeedDirectly(speed); + } + Com::printFLN(Com::tFanspeed,speed); // send only new values to break update loops! +#endif +} +void Commands::setFan2Speed(int speed) { +#if FAN2_PIN >- 1 && FEATURE_FAN2_CONTROL + speed = constrain(speed,0,255); + Printer::setFan2SpeedDirectly(speed); + Com::printFLN(Com::tFan2speed,speed); // send only new values to break update loops! +#endif +} + +void Commands::reportPrinterUsage() { +#if EEPROM_MODE != 0 + float dist = Printer::filamentPrinted * 0.001 + HAL::eprGetFloat(EPR_PRINTING_DISTANCE); + Com::printF(Com::tPrintedFilament, dist, 2); + Com::printF(Com::tSpacem); + bool alloff = true; +#if NUM_EXTRUDER > 0 + for(uint8_t i = 0; i < NUM_EXTRUDER; i++) + if(tempController[i]->targetTemperatureC > 15) alloff = false; +#endif + int32_t seconds = (alloff ? 0 : (HAL::timeInMilliseconds() - Printer::msecondsPrinting) / 1000) + HAL::eprGetInt32(EPR_PRINTING_TIME); + int32_t tmp = seconds / 86400; + seconds -= tmp * 86400; + Com::printF(Com::tPrintingTime,tmp); + tmp = seconds / 3600; + Com::printF(Com::tSpaceDaysSpace,tmp); + seconds -= tmp * 3600; + tmp = seconds / 60; + Com::printF(Com::tSpaceHoursSpace,tmp); + Com::printFLN(Com::tSpaceMin); +#endif +} +#if STEPPER_CURRENT_CONTROL == CURRENT_CONTROL_DIGIPOT +// Digipot methods for controling current and microstepping + +#if defined(DIGIPOTSS_PIN) && DIGIPOTSS_PIN > -1 +int digitalPotWrite(int address, uint16_t value) { // From Arduino DigitalPotControl example + if(value > 255) + value = 255; + WRITE(DIGIPOTSS_PIN,LOW); // take the SS pin low to select the chip + HAL::spiSend(address); // send in the address and value via SPI: + HAL::spiSend(value); + WRITE(DIGIPOTSS_PIN,HIGH); // take the SS pin high to de-select the chip: + //delay(10); +} + +void setMotorCurrent(uint8_t driver, uint16_t current) { + if(driver > 4) return; + const uint8_t digipot_ch[] = DIGIPOT_CHANNELS; + digitalPotWrite(digipot_ch[driver], current); +} + +void setMotorCurrentPercent( uint8_t channel, float level) { + uint16_t raw_level = ( level * 255 / 100 ); + setMotorCurrent(channel,raw_level); +} +#endif + +void motorCurrentControlInit() { //Initialize Digipot Motor Current +#if DIGIPOTSS_PIN && DIGIPOTSS_PIN > -1 + HAL::spiInit(0); //SPI.begin(); + SET_OUTPUT(DIGIPOTSS_PIN); +#ifdef MOTOR_CURRENT_PERCENT + const float digipot_motor_current[] = MOTOR_CURRENT_PERCENT; + for(int i = 0; i <= 4; i++) + //digitalPotWrite(digipot_ch[i], digipot_motor_current[i]); + setMotorCurrentPercent(i,digipot_motor_current[i]); +#else + const uint8_t digipot_motor_current[] = MOTOR_CURRENT; + for(int i = 0; i <= 4; i++) + //digitalPotWrite(digipot_ch[i], digipot_motor_current[i]); + setMotorCurrent(i,digipot_motor_current[i]); +#endif +#endif +} +#endif + +#if STEPPER_CURRENT_CONTROL == CURRENT_CONTROL_LTC2600 + +void setMotorCurrent( uint8_t channel, unsigned short level ) { + if(channel >= LTC2600_NUM_CHANNELS) return; + const uint8_t ltc_channels[] = LTC2600_CHANNELS; + if(channel > LTC2600_NUM_CHANNELS) return; + uint8_t address = ltc_channels[channel]; + fast8_t i; + + + // NOTE: Do not increase the current endlessly. In case the engine reaches its current saturation, the engine and the driver can heat up and loss power. + // When the saturation is reached, more current causes more heating and more power loss. + // In case of engines with lower quality, the saturation current may be reached before the nominal current. + + // configure the pins + WRITE( LTC2600_CS_PIN, HIGH ); + SET_OUTPUT( LTC2600_CS_PIN ); + WRITE( LTC2600_SCK_PIN, LOW ); + SET_OUTPUT( LTC2600_SCK_PIN ); + WRITE( LTC2600_SDI_PIN, LOW ); + SET_OUTPUT( LTC2600_SDI_PIN ); + + // enable the command interface of the LTC2600 + WRITE( LTC2600_CS_PIN, LOW ); + + // transfer command and address + for( i = 7; i >= 0; i-- ) { + WRITE( LTC2600_SDI_PIN, address & (0x01 << i)); + WRITE( LTC2600_SCK_PIN, 1 ); + WRITE( LTC2600_SCK_PIN, 0 ); + } + + // transfer the data word + for( i = 15; i >= 0; i-- ) { + WRITE( LTC2600_SDI_PIN, level & (0x01 << i)); + WRITE( LTC2600_SCK_PIN, 1 ); + WRITE( LTC2600_SCK_PIN, 0 ); + } + + // disable the ommand interface of the LTC2600 - + // this carries out the specified command + WRITE( LTC2600_CS_PIN, HIGH ); + +} // setLTC2600 +void setMotorCurrentPercent( uint8_t channel, float level) { + if(level > 100.0f) level = 100.0f; + uint16_t raw_level = static_cast( (long)level * 65535L / 100L ); + setMotorCurrent(channel,raw_level); +} + +void motorCurrentControlInit() { //Initialize LTC2600 Motor Current + uint8_t i; +#ifdef MOTOR_CURRENT_PERCENT + const float digipot_motor_current[] = MOTOR_CURRENT_PERCENT; + for(int i = 0; i < LTC2600_NUM_CHANNELS; i++) + //digitalPotWrite(digipot_ch[i], digipot_motor_current[i]); + setMotorCurrentPercent(i,digipot_motor_current[i]); +#else + const unsigned int ltc_current[] = MOTOR_CURRENT; + for(i = 0; i < LTC2600_NUM_CHANNELS; i++) { + setMotorCurrent(i, ltc_current[i] ); + } +#endif +} +#endif + +#if STEPPER_CURRENT_CONTROL == CURRENT_CONTROL_ALLIGATOR +void setMotorCurrent(uint8_t channel, unsigned short value) { + if(channel >= 7) // max channel (X,Y,Z,E0,E1,E2,E3) + return; + if(value > 255) + value=255; + + uint8_t externalDac_buf[2] = {0x10, 0x00}; + + if(channel > 3) + externalDac_buf[0] |= ( 7 - channel << 6); + else + externalDac_buf[0] |= ( 3 - channel << 6); + + externalDac_buf[0] |= (value >> 4); + externalDac_buf[1] |= (value << 4); + + // All SPI chip-select HIGH + WRITE(DAC0_SYNC, HIGH); + WRITE(DAC1_SYNC, HIGH); + WRITE(SPI_EEPROM1_CS, HIGH); + WRITE(SPI_EEPROM2_CS, HIGH); + WRITE(SPI_FLASH_CS, HIGH); + WRITE(SDSS, HIGH); + + if(channel > 3) { // DAC Piggy E1,E2,E3 + WRITE(DAC1_SYNC,LOW); + HAL::delayMicroseconds(2); + WRITE(DAC1_SYNC,HIGH); + HAL::delayMicroseconds(2); + WRITE(DAC1_SYNC,LOW); + } else { // DAC onboard X,Y,Z,E0 + WRITE(DAC0_SYNC,LOW); + HAL::delayMicroseconds(2); + WRITE(DAC0_SYNC,HIGH); + HAL::delayMicroseconds(2); + WRITE(DAC0_SYNC,LOW); + } + + HAL::delayMicroseconds(2); + HAL::spiSend(SPI_CHAN_DAC, externalDac_buf, 2); +} + +void setMotorCurrentPercent( uint8_t channel, float level) { + uint16_t raw_level = ( level * 255 / 100 ); + setMotorCurrent(channel,raw_level); +} + +void motorCurrentControlInit() { //Initialize Motor Current + uint8_t externalDac_buf[2] = {0x20, 0x00};//all off + + // All SPI chip-select HIGH + WRITE(DAC0_SYNC, HIGH); + WRITE(DAC1_SYNC, HIGH); + WRITE(SPI_EEPROM1_CS, HIGH); + WRITE(SPI_EEPROM2_CS, HIGH); + WRITE(SPI_FLASH_CS, HIGH); + WRITE(SDSS, HIGH); + + // init onboard DAC + WRITE(DAC0_SYNC, LOW); + HAL::delayMicroseconds(2); + WRITE(DAC0_SYNC, HIGH); + HAL::delayMicroseconds(2); + WRITE(DAC0_SYNC, LOW); + + HAL::spiSend(SPI_CHAN_DAC,externalDac_buf, 2); + WRITE(DAC0_SYNC, HIGH); + +#if NUM_EXTRUDER > 1 + // init Piggy DAC + WRITE(DAC1_SYNC, LOW); + HAL::delayMicroseconds(2); + WRITE(DAC1_SYNC, HIGH); + HAL::delayMicroseconds(2); + WRITE(DAC1_SYNC, LOW); + + HAL::spiSend(SPI_CHAN_DAC,externalDac_buf, 2); + WRITE(DAC1_SYNC, HIGH); +#endif + +#ifdef MOTOR_CURRENT_PERCENT + const float digipot_motor_current[] = MOTOR_CURRENT_PERCENT; + for(int i = 0; i < NUM_EXTRUDER+3; i++) + setMotorCurrentPercent(i,digipot_motor_current[i]); +#else + const uint8_t digipot_motor_current[] = MOTOR_CURRENT; + for(uint8_t i = 0; i < NUM_EXTRUDER+3; i++) + setMotorCurrent(i,digipot_motor_current[i]); +#endif +} +#endif + + +#if STEPPER_CURRENT_CONTROL == CURRENT_CONTROL_MCP4728 +uint8_t _intVref[] = {MCP4728_VREF, MCP4728_VREF, MCP4728_VREF, MCP4728_VREF}; +uint8_t _gain[] = {MCP4728_GAIN, MCP4728_GAIN, MCP4728_GAIN, MCP4728_GAIN}; +uint8_t _powerDown[] = {0,0,0,0}; +int16_t dac_motor_current[] = {0,0,0,0}; + +uint8_t _intVrefEp[] = {MCP4728_VREF, MCP4728_VREF, MCP4728_VREF, MCP4728_VREF}; +uint8_t _gainEp[] = {MCP4728_GAIN, MCP4728_GAIN, MCP4728_GAIN, MCP4728_GAIN}; +uint8_t _powerDownEp[] = {0,0,0,0}; +int16_t _valuesEp[] = {0,0,0,0}; + +uint8_t dac_stepper_channel[] = MCP4728_STEPPER_ORDER; + +int dacSimpleCommand(uint8_t simple_command) { + HAL::i2cStartWait(MCP4728_GENERALCALL_ADDRESS + I2C_WRITE); + HAL::i2cWrite(simple_command); + HAL::i2cStop(); +} + +void dacReadStatus() { + HAL::delayMilliseconds(500); + HAL::i2cStartWait(MCP4728_I2C_ADDRESS | I2C_READ); + + for (int i = 0; i < 8; i++) { // 2 sets of 4 Channels (1 EEPROM, 1 Runtime) + uint8_t deviceID = HAL::i2cReadAck(); + uint8_t hiByte = HAL::i2cReadAck(); + uint8_t loByte = ((i < 7) ? HAL::i2cReadAck() : HAL::i2cReadNak()); + + uint8_t isEEPROM = (deviceID & 0B00001000) >> 3; + uint8_t channel = (deviceID & 0B00110000) >> 4; + if (isEEPROM == 1) { + _intVrefEp[channel] = (hiByte & 0B10000000) >> 7; + _gainEp[channel] = (hiByte & 0B00010000) >> 4; + _powerDownEp[channel] = (hiByte & 0B01100000) >> 5; + _valuesEp[channel] = word((hiByte & 0B00001111), loByte); + } else { + _intVref[channel] = (hiByte & 0B10000000) >> 7; + _gain[channel] = (hiByte & 0B00010000) >> 4; + _powerDown[channel] = (hiByte & 0B01100000) >> 5; + dac_motor_current[channel] = word((hiByte & 0B00001111), loByte); + } + } + + HAL::i2cStop(); +} + +void dacAnalogUpdate(bool saveEEPROM = false) { + uint8_t dac_write_cmd = MCP4728_CMD_SEQ_WRITE; + + HAL::i2cStartWait(MCP4728_I2C_ADDRESS + I2C_WRITE); + if (saveEEPROM) HAL::i2cWrite(dac_write_cmd); + + for (int i = 0; i < MCP4728_NUM_CHANNELS; i++) { + uint16_t level = dac_motor_current[i]; + + uint8_t highbyte = ( _intVref[i] << 7 | _gain[i] << 4 | (uint8_t)((level) >> 8) ); + uint8_t lowbyte = ( (uint8_t) ((level) & 0xff) ); + dac_write_cmd = MCP4728_CMD_MULTI_WRITE | (i << 1); + + if (!saveEEPROM) HAL::i2cWrite(dac_write_cmd); + HAL::i2cWrite(highbyte); + HAL::i2cWrite(lowbyte); + } + + HAL::i2cStop(); + + // Instruct the MCP4728 to reflect our updated value(s) on its DAC Outputs + dacSimpleCommand((uint8_t)MCP4728_CMD_GC_UPDATE); // MCP4728 General Command Software Update (Update all DAC Outputs to reflect settings) + + // if (saveEEPROM) dacReadStatus(); // Not necessary, just a read-back sanity check. +} + +void dacCommitEeprom() { + dacAnalogUpdate(true); + dacReadStatus(); // Refresh EEPROM Values with values actually stored in EEPROM. . +} + +void dacPrintSet(int dacChannelSettings[], const char* dacChannelPrefixes[]) { + for (int i = 0; i < MCP4728_NUM_CHANNELS; i++) { + uint8_t dac_channel = dac_stepper_channel[i]; // DAC Channel is a mapped lookup. + Com::printF(dacChannelPrefixes[i], ((float)dacChannelSettings[dac_channel] * 100 / MCP4728_VOUT_MAX)); + Com::printF(Com::tSpaceRaw); + Com::printFLN(Com::tColon,dacChannelSettings[dac_channel]); + } +} + +void dacPrintValues() { + const char* dacChannelPrefixes[] = {Com::tSpaceXColon, Com::tSpaceYColon, Com::tSpaceZColon, Com::tSpaceEColon}; + + Com::printFLN(Com::tMCPEpromSettings); + dacPrintSet(_valuesEp, dacChannelPrefixes); // Once for the EEPROM set + + Com::printFLN(Com::tMCPCurrentSettings); + dacPrintSet(dac_motor_current, dacChannelPrefixes); // And another for the RUNTIME set +} + +void setMotorCurrent( uint8_t xyz_channel, uint16_t level ) { + if (xyz_channel >= MCP4728_NUM_CHANNELS) return; + uint8_t stepper_channel = dac_stepper_channel[xyz_channel]; + dac_motor_current[stepper_channel] = level < MCP4728_VOUT_MAX ? level : MCP4728_VOUT_MAX; + dacAnalogUpdate(); +} + +void setMotorCurrentPercent( uint8_t channel, float level) { + uint16_t raw_level = ( level * MCP4728_VOUT_MAX / 100 ); + setMotorCurrent(channel,raw_level); +} + +void motorCurrentControlInit() { //Initialize MCP4728 Motor Current + HAL::i2cInit(400000); // Initialize the i2c bus. + dacSimpleCommand((uint8_t)MCP4728_CMD_GC_RESET); // MCP4728 General Command Reset + dacReadStatus(); // Load Values from EEPROM. + + for(int i = 0; i < MCP4728_NUM_CHANNELS; i++) { + setMotorCurrent(dac_stepper_channel[i], _valuesEp[i] ); // This is not strictly necessary, but serves as a good sanity check to ensure we're all on the same page. + } +} +#endif + +#if defined(X_MS1_PIN) && X_MS1_PIN > -1 +void microstepMS(uint8_t driver, int8_t ms1, int8_t ms2) { + if(ms1 > -1) switch(driver) { + case 0: +#if X_MS1_PIN > -1 + WRITE( X_MS1_PIN,ms1); +#endif + break; + case 1: +#if Y_MS1_PIN > -1 + WRITE( Y_MS1_PIN,ms1); +#endif + break; + case 2: +#if Z_MS1_PIN > -1 + WRITE( Z_MS1_PIN,ms1); +#endif + break; + case 3: +#if E0_MS1_PIN > -1 + WRITE(E0_MS1_PIN,ms1); +#endif + break; + case 4: +#if E1_MS1_PIN > -1 + WRITE(E1_MS1_PIN,ms1); +#endif + break; + } + if(ms2 > -1) switch(driver) { + case 0: +#if X_MS2_PIN > -1 + WRITE( X_MS2_PIN,ms2); +#endif + break; + case 1: +#if Y_MS2_PIN > -1 + WRITE( Y_MS2_PIN,ms2); +#endif + break; + case 2: +#if Z_MS2_PIN > -1 + WRITE( Z_MS2_PIN,ms2); +#endif + break; + case 3: +#if E0_MS2_PIN > -1 + WRITE(E0_MS2_PIN,ms2); +#endif + break; + case 4: +#if E1_MS2_PIN > -1 + WRITE(E1_MS2_PIN,ms2); +#endif + break; + } +} + +void microstepMode(uint8_t driver, uint8_t stepping_mode) { + switch(stepping_mode) { + case 1: + microstepMS(driver,MICROSTEP1); + break; + case 2: + microstepMS(driver,MICROSTEP2); + break; + case 4: + microstepMS(driver,MICROSTEP4); + break; + case 8: + microstepMS(driver,MICROSTEP8); + break; + case 16: + microstepMS(driver,MICROSTEP16); + break; + case 32: + microstepMS(driver,MICROSTEP32); + break; + } +} + +void microstepReadings() { + Com::printFLN(Com::tMS1MS2Pins); +#if X_MS1_PIN > -1 && X_MS2_PIN > -1 + Com::printF(Com::tXColon,READ(X_MS1_PIN)); + Com::printFLN(Com::tComma,READ(X_MS2_PIN)); +#elif X_MS1_PIN > -1 + Com::printFLN(Com::tXColon,READ(X_MS1_PIN)); +#endif +#if Y_MS1_PIN > -1 && Y_MS2_PIN > -1 + Com::printF(Com::tYColon,READ(Y_MS1_PIN)); + Com::printFLN(Com::tComma,READ(Y_MS2_PIN)); +#elif Y_MS1_PIN > -1 + Com::printFLN(Com::tYColon,READ(Y_MS1_PIN)); +#endif +#if Z_MS1_PIN > -1 && Z_MS2_PIN > -1 + Com::printF(Com::tZColon,READ(Z_MS1_PIN)); + Com::printFLN(Com::tComma,READ(Z_MS2_PIN)); +#elif Z_MS1_PIN > -1 + Com::printFLN(Com::tZColon,READ(Z_MS1_PIN)); +#endif +#if E0_MS1_PIN > -1 && E0_MS2_PIN > -1 + Com::printF(Com::tE0Colon,READ(E0_MS1_PIN)); + Com::printFLN(Com::tComma,READ(E0_MS2_PIN)); +#elif E0_MS1_PIN > -1 + Com::printFLN(Com::tE0Colon,READ(E0_MS1_PIN)); +#endif +#if E1_MS1_PIN > -1 && E1_MS2_PIN > -1 + Com::printF(Com::tE1Colon,READ(E1_MS1_PIN)); + Com::printFLN(Com::tComma,READ(E1_MS2_PIN)); +#elif E1_MS1_PIN > -1 + Com::printFLN(Com::tE1Colon,READ(E1_MS1_PIN)); +#endif +} +#endif + +void microstepInit() { +#if defined(X_MS1_PIN) && X_MS1_PIN > -1 + const uint8_t microstep_modes[] = MICROSTEP_MODES; +#if X_MS1_PIN > -1 + SET_OUTPUT(X_MS1_PIN); +#endif +#if Y_MS1_PIN > -1 + SET_OUTPUT(Y_MS1_PIN); +#endif +#if Z_MS1_PIN > -1 + SET_OUTPUT(Z_MS1_PIN); +#endif +#if E0_MS1_PIN > -1 + SET_OUTPUT(E0_MS1_PIN); +#endif +#if E1_MS1_PIN > -1 + SET_OUTPUT(E1_MS1_PIN); +#endif +#if X_MS2_PIN > -1 + SET_OUTPUT(X_MS2_PIN); +#endif +#if Y_MS2_PIN > -1 + SET_OUTPUT(Y_MS2_PIN); +#endif +#if Z_MS2_PIN > -1 + SET_OUTPUT(Z_MS2_PIN); +#endif +#if E0_MS2_PIN > -1 + SET_OUTPUT(E0_MS2_PIN); +#endif +#if E1_MS2_PIN > -1 + SET_OUTPUT(E1_MS2_PIN); +#endif + for(int i = 0; i <= 4; i++) microstepMode(i, microstep_modes[i]); +#endif +} + +/** +\brief Execute the Arc command stored in com. +*/ +#if ARC_SUPPORT +void Commands::processArc(GCode *com) { + float position[Z_AXIS_ARRAY]; + Printer::realPosition(position[X_AXIS],position[Y_AXIS],position[Z_AXIS]); + if(!Printer::setDestinationStepsFromGCode(com)) return; // For X Y Z E F + float offset[2] = {Printer::convertToMM(com->hasI() ? com->I : 0),Printer::convertToMM(com->hasJ() ? com->J : 0)}; + float target[E_AXIS_ARRAY] = {Printer::realXPosition(),Printer::realYPosition(),Printer::realZPosition(),Printer::destinationSteps[E_AXIS]*Printer::invAxisStepsPerMM[E_AXIS]}; + float r; + if (com->hasR()) { + /* + We need to calculate the center of the circle that has the designated radius and passes + through both the current position and the target position. This method calculates the following + set of equations where [x,y] is the vector from current to target position, d == magnitude of + that vector, h == hypotenuse of the triangle formed by the radius of the circle, the distance to + the center of the travel vector. A vector perpendicular to the travel vector [-y,x] is scaled to the + length of h [-y/d*h, x/d*h] and added to the center of the travel vector [x/2,y/2] to form the new point + [i,j] at [x/2-y/d*h, y/2+x/d*h] which will be the center of our arc. + + d^2 == x^2 + y^2 + h^2 == r^2 - (d/2)^2 + i == x/2 - y/d*h + j == y/2 + x/d*h + + O <- [i,j] + - | + r - | + - | + - | h + - | + [0,0] -> C -----------------+--------------- T <- [x,y] + | <------ d/2 ---->| + + C - Current position + T - Target position + O - center of circle that pass through both C and T + d - distance from C to T + r - designated radius + h - distance from center of CT to O + + Expanding the equations: + + d -> sqrt(x^2 + y^2) + h -> sqrt(4 * r^2 - x^2 - y^2)/2 + i -> (x - (y * sqrt(4 * r^2 - x^2 - y^2)) / sqrt(x^2 + y^2)) / 2 + j -> (y + (x * sqrt(4 * r^2 - x^2 - y^2)) / sqrt(x^2 + y^2)) / 2 + + Which can be written: + + i -> (x - (y * sqrt(4 * r^2 - x^2 - y^2))/sqrt(x^2 + y^2))/2 + j -> (y + (x * sqrt(4 * r^2 - x^2 - y^2))/sqrt(x^2 + y^2))/2 + + Which we for size and speed reasons optimize to: + + h_x2_div_d = sqrt(4 * r^2 - x^2 - y^2)/sqrt(x^2 + y^2) + i = (x - (y * h_x2_div_d))/2 + j = (y + (x * h_x2_div_d))/2 + + */ + r = Printer::convertToMM(com->R); + // Calculate the change in position along each selected axis + double x = target[X_AXIS]-position[X_AXIS]; + double y = target[Y_AXIS]-position[Y_AXIS]; + + double h_x2_div_d = -sqrt(4 * r*r - x*x - y*y)/hypot(x,y); // == -(h * 2 / d) + // If r is smaller than d, the arc is now traversing the complex plane beyond the reach of any + // real CNC, and thus - for practical reasons - we will terminate promptly: + if(isnan(h_x2_div_d)) { + Com::printErrorFLN(Com::tInvalidArc); + return; + } + // Invert the sign of h_x2_div_d if the circle is counter clockwise (see sketch below) + if (com->G == 3) { + h_x2_div_d = -h_x2_div_d; + } + + /* The counter clockwise circle lies to the left of the target direction. When offset is positive, + the left hand circle will be generated - when it is negative the right hand circle is generated. + + + T <-- Target position + + ^ + Clockwise circles with this center | Clockwise circles with this center will have + will have > 180 deg of angular travel | < 180 deg of angular travel, which is a good thing! + \ | / + center of arc when h_x2_div_d is positive -> x <----- | -----> x <- center of arc when h_x2_div_d is negative + | + | + + C <-- Current position */ + + + // Negative R is g-code-alese for "I want a circle with more than 180 degrees of travel" (go figure!), + // even though it is advised against ever generating such circles in a single line of g-code. By + // inverting the sign of h_x2_div_d the center of the circles is placed on the opposite side of the line of + // travel and thus we get the unadvisably long arcs as prescribed. + if (r < 0) { + h_x2_div_d = -h_x2_div_d; + r = -r; // Finished with r. Set to positive for mc_arc + } + // Complete the operation by calculating the actual center of the arc + offset[0] = 0.5 * (x - (y * h_x2_div_d)); + offset[1] = 0.5 * (y + (x * h_x2_div_d)); + + } else { // Offset mode specific computations + r = hypot(offset[0], offset[1]); // Compute arc radius for arc + } + // Set clockwise/counter-clockwise sign for arc computations + uint8_t isclockwise = com->G == 2; + // Trace the arc + PrintLine::arc(position, target, offset, r, isclockwise); +} +#endif +extern bool runBedLeveling(GCode *com); +/** +\brief Execute the G command stored in com. +*/ +void Commands::processGCode(GCode *com) { + uint32_t codenum; //throw away variable + switch(com->G) { + case 0: // G0 -> G1 + case 1: // G1 +#if defined(SUPPORT_LASER) && SUPPORT_LASER + { + // disable laser for G0 moves + bool laserOn = LaserDriver::laserOn; + if(com->G == 0 && Printer::mode == PRINTER_MODE_LASER) { + LaserDriver::laserOn = false; + } +#endif // defined + if(com->hasS()) Printer::setNoDestinationCheck(com->S != 0); + if(Printer::setDestinationStepsFromGCode(com)) // For X Y Z E F +#if NONLINEAR_SYSTEM + if (!PrintLine::queueNonlinearMove(ALWAYS_CHECK_ENDSTOPS, true, true)) { + Com::printWarningFLN(PSTR("executeGCode / queueDeltaMove returns error")); + } +#else + PrintLine::queueCartesianMove(ALWAYS_CHECK_ENDSTOPS, true); +#endif +#if UI_HAS_KEYS + // ui can only execute motion commands if we are not waiting inside a move for an + // old move to finish. For normal response times, we always leave one free after + // sending a line. Drawback: 1 buffer line less for limited time. Since input cache + // gets filled while waiting, the lost is neglectible. + PrintLine::waitForXFreeLines(1, true); +#endif // UI_HAS_KEYS +#ifdef DEBUG_QUEUE_MOVE + { + + InterruptProtectedBlock noInts; + int lc = (int)PrintLine::linesCount; + int lp = (int)PrintLine::linesPos; + int wp = (int)PrintLine::linesWritePos; + int n = (wp - lp); + if(n < 0) n += PRINTLINE_CACHE_SIZE; + noInts.unprotect(); + if(n != lc) + Com::printFLN(PSTR("Buffer corrupted")); + } +#endif +#if defined(SUPPORT_LASER) && SUPPORT_LASER + LaserDriver::laserOn = laserOn; + } +#endif // defined + break; +#if ARC_SUPPORT + case 2: // CW Arc + case 3: // CCW Arc MOTION_MODE_CW_ARC: case MOTION_MODE_CCW_ARC: +#if defined(SUPPORT_LASER) && SUPPORT_LASER + { + // disable laser for G0 moves + bool laserOn = LaserDriver::laserOn; + if(com->G == 0 && Printer::mode == PRINTER_MODE_LASER) { + LaserDriver::laserOn = false; + } +#endif // defined + processArc(com); +#if defined(SUPPORT_LASER) && SUPPORT_LASER + LaserDriver::laserOn = laserOn; + } +#endif // defined + break; +#endif + case 4: // G4 dwell + Commands::waitUntilEndOfAllMoves(); + codenum = 0; + if(com->hasP()) codenum = com->P; // milliseconds to wait + if(com->hasS()) codenum = com->S * 1000; // seconds to wait + codenum += HAL::timeInMilliseconds(); // keep track of when we started waiting + while((uint32_t)(codenum-HAL::timeInMilliseconds()) < 2000000000 ) { + GCode::readFromSerial(); + Commands::checkForPeriodicalActions(true); + } + break; +#if FEATURE_RETRACTION && NUM_EXTRUDER > 0 + case 10: // G10 S<1 = long retract, 0 = short retract = default> retracts filament accoridng to stored setting +#if NUM_EXTRUDER > 1 + Extruder::current->retract(true, com->hasS() && com->S > 0); +#else + Extruder::current->retract(true, false); +#endif + break; + case 11: // G11 S<1 = long retract, 0 = short retract = default> = Undo retraction according to stored setting +#if NUM_EXTRUDER > 1 + Extruder::current->retract(false, com->hasS() && com->S > 0); +#else + Extruder::current->retract(false, false); +#endif + break; +#endif // FEATURE_RETRACTION + case 20: // G20 Units to inches + Printer::unitIsInches = 1; + break; + case 21: // G21 Units to mm + Printer::unitIsInches = 0; + break; + case 28: { //G28 Home all Axis one at a time +#if defined(SUPPORT_LASER) && SUPPORT_LASER + bool oldLaser = LaserDriver::laserOn; + LaserDriver::laserOn = false; +#endif + uint8_t homeAllAxis = (com->hasNoXYZ() && !com->hasE()); + if(com->hasE()) + Printer::currentPositionSteps[E_AXIS] = 0; + if(homeAllAxis || !com->hasNoXYZ()) + Printer::homeAxis(homeAllAxis || com->hasX(),homeAllAxis || com->hasY(),homeAllAxis || com->hasZ()); +#if defined(SUPPORT_LASER) && SUPPORT_LASER + LaserDriver::laserOn = oldLaser; +#endif + Printer::updateCurrentPosition(); + } + break; +#if FEATURE_Z_PROBE + case 29: { // G29 3 points, build average or distortion compensation +#if defined(Z_PROBE_MIN_TEMPERATURE) && Z_PROBE_MIN_TEMPERATURE && Z_PROBE_REQUIRES_HEATING + float actTemp[NUM_EXTRUDER]; + for(int i = 0; i < NUM_EXTRUDER; i++) + actTemp[i] = extruder[i].tempControl.targetTemperatureC; + Printer::moveToReal(IGNORE_COORDINATE,IGNORE_COORDINATE,RMath::max(EEPROM::zProbeHeight(),static_cast(ZHOME_HEAT_HEIGHT)),IGNORE_COORDINATE,Printer::homingFeedrate[Z_AXIS]); + Commands::waitUntilEndOfAllMoves(); +#if ZHOME_HEAT_ALL + for(int i = 0; i < NUM_EXTRUDER; i++) { + Extruder::setTemperatureForExtruder(RMath::max(actTemp[i],static_cast(ZPROBE_MIN_TEMPERATURE)),i,false,false); + } + for(int i = 0; i < NUM_EXTRUDER; i++) { + if(extruder[i].tempControl.currentTemperatureC < ZPROBE_MIN_TEMPERATURE) + Extruder::setTemperatureForExtruder(RMath::max(actTemp[i],static_cast(ZPROBE_MIN_TEMPERATURE)),i,false,true); + } +#else + if(extruder[Extruder::current->id].tempControl.currentTemperatureC < ZPROBE_MIN_TEMPERATURE) + Extruder::setTemperatureForExtruder(RMath::max(actTemp[Extruder::current->id],static_cast(ZPROBE_MIN_TEMPERATURE)),Extruder::current->id,false,true); +#endif +#endif + bool ok = true; + Printer::startProbing(true); + bool oldAutolevel = Printer::isAutolevelActive(); + Printer::setAutolevelActive(false); + float sum = 0, last,oldFeedrate = Printer::feedrate; + Printer::moveTo(EEPROM::zProbeX1(), EEPROM::zProbeY1(), IGNORE_COORDINATE, IGNORE_COORDINATE, EEPROM::zProbeXYSpeed()); + sum = Printer::runZProbe(true,false,Z_PROBE_REPETITIONS,false); + if(sum == ILLEGAL_Z_PROBE) ok = false; + if(ok) { + Printer::moveTo(EEPROM::zProbeX2(), EEPROM::zProbeY2(), IGNORE_COORDINATE, IGNORE_COORDINATE, EEPROM::zProbeXYSpeed()); + last = Printer::runZProbe(false,false); + if(last == ILLEGAL_Z_PROBE) ok = false; + sum+= last; + } + if(ok) { + Printer::moveTo(EEPROM::zProbeX3(), EEPROM::zProbeY3(), IGNORE_COORDINATE, IGNORE_COORDINATE, EEPROM::zProbeXYSpeed()); + last = Printer::runZProbe(false,true); + if(last == ILLEGAL_Z_PROBE) ok = false; + sum += last; + } + if(ok) { + sum *= 0.33333333333333; + Com::printFLN(Com::tZProbeAverage, sum); + if(com->hasS() && com->S) { +#if MAX_HARDWARE_ENDSTOP_Z +#if DRIVE_SYSTEM == DELTA + Printer::updateCurrentPosition(); + Printer::zLength += sum - Printer::currentPosition[Z_AXIS]; + Printer::updateDerivedParameter(); + Printer::homeAxis(true,true,true); +#else + Printer::currentPositionSteps[Z_AXIS] = sum * Printer::axisStepsPerMM[Z_AXIS]; + float zup = Printer::runZMaxProbe(); + if(zup == ILLEGAL_Z_PROBE) { + ok = false; + } else + Printer::zLength = zup + sum - ENDSTOP_Z_BACK_ON_HOME; +#endif // DELTA + Com::printInfoFLN(Com::tZProbeZReset); + Com::printFLN(Com::tZProbePrinterHeight,Printer::zLength); +#else + Printer::currentPositionSteps[Z_AXIS] = sum * Printer::axisStepsPerMM[Z_AXIS]; + Com::printFLN(PSTR("Adjusted z origin")); +#endif // max z endstop + } + Printer::feedrate = oldFeedrate; + Printer::setAutolevelActive(oldAutolevel); + if(ok && com->hasS() && com->S == 2) + EEPROM::storeDataIntoEEPROM(); + } + Printer::updateCurrentPosition(true); + printCurrentPosition(PSTR("G29 ")); + Printer::finishProbing(); + Printer::feedrate = oldFeedrate; + if(!ok) { + GCode::fatalError(PSTR("G29 leveling failed!")); + break; + } +#if defined(Z_PROBE_MIN_TEMPERATURE) && Z_PROBE_MIN_TEMPERATURE && Z_PROBE_REQUIRES_HEATING +#if ZHOME_HEAT_ALL + for(int i = 0; i < NUM_EXTRUDER; i++) { + Extruder::setTemperatureForExtruder(RMath::max(actTemp[i],static_cast(ZPROBE_MIN_TEMPERATURE)),i,false,false); + } + for(int i = 0; i < NUM_EXTRUDER; i++) { + if(extruder[i].tempControl.currentTemperatureC < ZPROBE_MIN_TEMPERATURE) + Extruder::setTemperatureForExtruder(RMath::max(actTemp[i],static_cast(ZPROBE_MIN_TEMPERATURE)),i,false,true); + } +#else + if(extruder[Extruder::current->id].tempControl.currentTemperatureC < ZPROBE_MIN_TEMPERATURE) + Extruder::setTemperatureForExtruder(RMath::max(actTemp[Extruder::current->id],static_cast(ZPROBE_MIN_TEMPERATURE)),Extruder::current->id,false,true); +#endif +#endif + } + break; + case 30: + { // G30 single probe set Z0 + uint8_t p = (com->hasP() ? (uint8_t)com->P : 3); + if(Printer::runZProbe(p & 1,p & 2) == ILLEGAL_Z_PROBE) { + GCode::fatalError(PSTR("G29 leveling failed!")); + break; + } + Printer::updateCurrentPosition(p & 1); + } + break; + case 31: // G31 display hall sensor output + Endstops::update(); + Endstops::update(); + Com::printF(Com::tZProbeState); + Com::printF(Endstops::zProbe() ? Com::tHSpace : Com::tLSpace); + Com::println(); + break; +#if FEATURE_AUTOLEVEL + case 32: // G32 Auto-Bed leveling + { +#if defined(Z_PROBE_MIN_TEMPERATURE) && Z_PROBE_MIN_TEMPERATURE && Z_PROBE_REQUIRES_HEATING + float actTemp[NUM_EXTRUDER]; + for(int i = 0; i < NUM_EXTRUDER; i++) + actTemp[i] = extruder[i].tempControl.targetTemperatureC; + Printer::moveToReal(IGNORE_COORDINATE,IGNORE_COORDINATE,RMath::max(EEPROM::zProbeHeight(),static_cast(ZHOME_HEAT_HEIGHT)),IGNORE_COORDINATE,Printer::homingFeedrate[Z_AXIS]); + Commands::waitUntilEndOfAllMoves(); +#if ZHOME_HEAT_ALL + for(int i = 0; i < NUM_EXTRUDER; i++) { + Extruder::setTemperatureForExtruder(RMath::max(actTemp[i],static_cast(ZPROBE_MIN_TEMPERATURE)),i,false,false); + } + for(int i = 0; i < NUM_EXTRUDER; i++) { + if(extruder[i].tempControl.currentTemperatureC < ZPROBE_MIN_TEMPERATURE) + Extruder::setTemperatureForExtruder(RMath::max(actTemp[i],static_cast(ZPROBE_MIN_TEMPERATURE)),i,false,true); + } +#else + if(extruder[Extruder::current->id].tempControl.currentTemperatureC < ZPROBE_MIN_TEMPERATURE) + Extruder::setTemperatureForExtruder(RMath::max(actTemp[Extruder::current->id],static_cast(ZPROBE_MIN_TEMPERATURE)),Extruder::current->id,false,true); +#endif +#endif + if(!runBedLeveling(com)) { + GCode::fatalError(PSTR("G32 leveling failed!")); + break; + } +#if defined(Z_PROBE_MIN_TEMPERATURE) && Z_PROBE_MIN_TEMPERATURE && Z_PROBE_REQUIRES_HEATING +#if ZHOME_HEAT_ALL + for(int i = 0; i < NUM_EXTRUDER; i++) { + Extruder::setTemperatureForExtruder(RMath::max(actTemp[i],static_cast(ZPROBE_MIN_TEMPERATURE)),i,false,false); + } + for(int i = 0; i < NUM_EXTRUDER; i++) { + if(extruder[i].tempControl.currentTemperatureC < ZPROBE_MIN_TEMPERATURE) + Extruder::setTemperatureForExtruder(RMath::max(actTemp[i],static_cast(ZPROBE_MIN_TEMPERATURE)),i,false,true); + } +#else + if(extruder[Extruder::current->id].tempControl.currentTemperatureC < ZPROBE_MIN_TEMPERATURE) + Extruder::setTemperatureForExtruder(RMath::max(actTemp[Extruder::current->id],static_cast(ZPROBE_MIN_TEMPERATURE)),Extruder::current->id,false,true); +#endif +#endif + } + break; +#endif +#if DISTORTION_CORRECTION + case 33: { + if(com->hasL()) { // G33 L0 - List distortion matrix + Printer::distortion.showMatrix(); + } else if(com->hasR()) { // G33 R0 - Reset distortion matrix + Printer::distortion.resetCorrection(); + } else if(com->hasX() || com->hasY() || com->hasZ()) { // G33 X Y Z - Set correction for nearest point + if(com->hasX() && com->hasY() && com->hasZ()) { + Printer::distortion.set(com->X, com->Y, com->Z); + } else { + Com::printErrorFLN(PSTR("You need to define X, Y and Z to set a point!")); + } + } else { // G33 +#if defined(Z_PROBE_MIN_TEMPERATURE) && Z_PROBE_MIN_TEMPERATURE && Z_PROBE_REQUIRES_HEATING + float actTemp[NUM_EXTRUDER]; + for(int i = 0; i < NUM_EXTRUDER; i++) + actTemp[i] = extruder[i].tempControl.targetTemperatureC; + Printer::moveToReal(IGNORE_COORDINATE,IGNORE_COORDINATE,RMath::max(EEPROM::zProbeHeight(),static_cast(ZHOME_HEAT_HEIGHT)),IGNORE_COORDINATE,Printer::homingFeedrate[Z_AXIS]); + Commands::waitUntilEndOfAllMoves(); +#if ZHOME_HEAT_ALL + for(int i = 0; i < NUM_EXTRUDER; i++) { + Extruder::setTemperatureForExtruder(RMath::max(actTemp[i],static_cast(ZPROBE_MIN_TEMPERATURE)),i,false,false); + } + for(int i = 0; i < NUM_EXTRUDER; i++) { + if(extruder[i].tempControl.currentTemperatureC < ZPROBE_MIN_TEMPERATURE) + Extruder::setTemperatureForExtruder(RMath::max(actTemp[i],static_cast(ZPROBE_MIN_TEMPERATURE)),i,false,true); + } +#else + if(extruder[Extruder::current->id].tempControl.currentTemperatureC < ZPROBE_MIN_TEMPERATURE) + Extruder::setTemperatureForExtruder(RMath::max(actTemp[Extruder::current->id],static_cast(ZPROBE_MIN_TEMPERATURE)),Extruder::current->id,false,true); +#endif +#endif + float oldFeedrate = Printer::feedrate; + if(!Printer::measureDistortion()) { + GCode::fatalError(PSTR("G33 failed!")); + break; + } + Printer::feedrate = oldFeedrate; +#if defined(Z_PROBE_MIN_TEMPERATURE) && Z_PROBE_MIN_TEMPERATURE && Z_PROBE_REQUIRES_HEATING +#if ZHOME_HEAT_ALL + for(int i = 0; i < NUM_EXTRUDER; i++) + Extruder::setTemperatureForExtruder(actTemp[i],i,false,false); + for(int i = 0; i < NUM_EXTRUDER; i++) + Extruder::setTemperatureForExtruder(actTemp[i],i,false, actTemp[i] > MAX_ROOM_TEMPERATURE); +#else + Extruder::setTemperatureForExtruder(actTemp[Extruder::current->id], Extruder::current->id, false, actTemp[Extruder::current->id] > MAX_ROOM_TEMPERATURE); +#endif +#endif + } + } + break; +#endif +#endif + case 90: // G90 + Printer::relativeCoordinateMode = false; + if(com->internalCommand) + Com::printInfoFLN(PSTR("Absolute positioning")); + break; + case 91: // G91 + Printer::relativeCoordinateMode = true; + if(com->internalCommand) + Com::printInfoFLN(PSTR("Relative positioning")); + break; + case 92: { // G92 + float xOff = Printer::coordinateOffset[X_AXIS]; + float yOff = Printer::coordinateOffset[Y_AXIS]; + float zOff = Printer::coordinateOffset[Z_AXIS]; + if(com->hasX()) xOff = Printer::convertToMM(com->X) - Printer::currentPosition[X_AXIS]; + if(com->hasY()) yOff = Printer::convertToMM(com->Y) - Printer::currentPosition[Y_AXIS]; + if(com->hasZ()) zOff = Printer::convertToMM(com->Z) - Printer::currentPosition[Z_AXIS]; + Printer::setOrigin(xOff, yOff, zOff); + if(com->hasE()) { + Printer::currentPositionSteps[E_AXIS] = Printer::convertToMM(com->E) * Printer::axisStepsPerMM[E_AXIS]; + } + } + break; +#if DRIVE_SYSTEM == DELTA + case 100: { // G100 Calibrate floor or rod radius + // Using manual control, adjust hot end to contact floor. + // G100 No action. Avoid accidental floor reset. + // G100 [X] [Y] [Z] set floor for argument passed in. Number ignored and may be absent. + // G100 R with X Y or Z flag error, sets only floor or radius, not both. + // G100 R[n] Add n to radius. Adjust to be above floor if necessary + // G100 R[0] set radius based on current z measurement. Moves to (0,0,0) + float currentZmm = Printer::currentPosition[Z_AXIS]; + if (currentZmm/Printer::zLength > 0.1) { + Com::printErrorFLN(PSTR("Calibration code is limited to bottom 10% of Z height")); + break; + } + if (com->hasR()) { + if (com->hasX() || com->hasY() || com->hasZ()) + Com::printErrorFLN(PSTR("Cannot set radius and floor at same time.")); + else if (com->R != 0) { + //add r to radius + if (abs(com->R) <= 10) EEPROM::incrementRodRadius(com->R); + else Com::printErrorFLN(PSTR("Calibration movement is limited to 10mm.")); + } else { + // auto set radius. Head must be at 0,0 and touching + // Z offset will be corrected for. + if (Printer::currentPosition[X_AXIS] == 0 + && Printer::currentPosition[Y_AXIS] == 0) { + if(Printer::isLargeMachine()) { + // calculate radius assuming we are at surface + // If Z is greater than 0 it will get calculated out for correct radius + // Use either A or B tower as they acnhor x cartesian axis and always have + // Radius distance to center in simplest set up. + float h = Printer::deltaDiagonalStepsSquaredB.f; + unsigned long bSteps = Printer::currentNonlinearPositionSteps[B_TOWER]; + // The correct Rod Radius would put us here at z==0 and B height is + // square root (rod length squared minus rod radius squared) + // Reverse that to get calculated Rod Radius given B height + h -= RMath::sqr((float)bSteps); + h = sqrt(h); + EEPROM::setRodRadius(h*Printer::invAxisStepsPerMM[Z_AXIS]); + } else { + // calculate radius assuming we are at surface + // If Z is greater than 0 it will get calculated out for correct radius + // Use either A or B tower as they acnhor x cartesian axis and always have + // Radius distance to center in simplest set up. + unsigned long h = Printer::deltaDiagonalStepsSquaredB.l; + unsigned long bSteps = Printer::currentNonlinearPositionSteps[B_TOWER]; + // The correct Rod Radius would put us here at z==0 and B height is + // square root (rod length squared minus rod radius squared) + // Reverse that to get calculated Rod Radius given B height + h -= RMath::sqr(bSteps); + h = SQRT(h); + EEPROM::setRodRadius(h*Printer::invAxisStepsPerMM[Z_AXIS]); + } + } else + Com::printErrorFLN(PSTR("First move to touch at x,y=0,0 to auto-set radius.")); + } + } else { + bool tooBig = false; + if (com->hasX()) { + if (abs(com->X) <= 10) + EEPROM::setTowerXFloor(com->X + currentZmm + Printer::xMin); + else tooBig = true; + } + if (com->hasY()) { + if (abs(com->Y) <= 10) + EEPROM::setTowerYFloor(com->Y + currentZmm + Printer::yMin); + else tooBig = true; + } + if (com->hasZ()) { + if (abs(com->Z) <= 10) + EEPROM::setTowerZFloor(com->Z + currentZmm + Printer::zMin); + else tooBig = true; + } + if (tooBig) + Com::printErrorFLN(PSTR("Calibration movement is limited to 10mm.")); + } + // after adjusting zero, physical position is out of sync with memory position + // this could cause jerky movement or push head into print surface. + // moving gets back into safe zero'ed position with respect to newle set floor or Radius. + Printer::moveTo(IGNORE_COORDINATE,IGNORE_COORDINATE,12.0,IGNORE_COORDINATE,IGNORE_COORDINATE); + break; + } + case 131: { // G131 Remove offset + float cx,cy,cz; + Printer::realPosition(cx,cy,cz); + float oldfeedrate = Printer::feedrate; + Printer::offsetX = 0; + Printer::offsetY = 0; + Printer::moveToReal(cx,cy,cz,IGNORE_COORDINATE,Printer::homingFeedrate[X_AXIS]); + Printer::feedrate = oldfeedrate; + Printer::updateCurrentPosition(); + } + break; + case 132: { // G132 Calibrate endstop offsets + // This has the probably unintended side effect of turning off leveling. + Printer::setAutolevelActive(false); // don't let transformations change result! + Printer::coordinateOffset[X_AXIS] = 0; + Printer::coordinateOffset[Y_AXIS] = 0; + Printer::coordinateOffset[Z_AXIS] = 0; + // I think this is coded incorrectly, as it depends on the biginning position of the + // of the hot end, and so should first move to x,y,z= 0,0,0, but as that may not + // be possible if the printer is not in the homes/zeroed state, the printer + // cannot safely move to 0 z coordinate without crashong into the print surface. + // so other than commenting, I'm not meddling. + // but you will always get different counts from different positions. + Printer::deltaMoveToTopEndstops(Printer::homingFeedrate[Z_AXIS]); + int32_t m = RMath::max(Printer::stepsRemainingAtXHit,RMath::max(Printer::stepsRemainingAtYHit,Printer::stepsRemainingAtZHit)); + int32_t offx = m - Printer::stepsRemainingAtXHit; + int32_t offy = m - Printer::stepsRemainingAtYHit; + int32_t offz = m - Printer::stepsRemainingAtZHit; + Com::printFLN(Com::tTower1, offx); + Com::printFLN(Com::tTower2, offy); + Com::printFLN(Com::tTower3, offz); +#if EEPROM_MODE != 0 + if(com->hasS() && com->S > 0) { + EEPROM::setDeltaTowerXOffsetSteps(offx); + EEPROM::setDeltaTowerYOffsetSteps(offy); + EEPROM::setDeltaTowerZOffsetSteps(offz); + } +#endif + PrintLine::moveRelativeDistanceInSteps(0, 0, -5*Printer::axisStepsPerMM[Z_AXIS], 0, Printer::homingFeedrate[Z_AXIS], true, true); + Printer::homeAxis(true,true,true); + } + break; + case 133: { // G133 Measure steps to top + bool oldAuto = Printer::isAutolevelActive(); + Printer::setAutolevelActive(false); // don't let transformations change result! + Printer::currentPositionSteps[X_AXIS] = 0; + Printer::currentPositionSteps[Y_AXIS] = 0; + Printer::currentPositionSteps[Z_AXIS] = 0; + Printer::coordinateOffset[X_AXIS] = 0; + Printer::coordinateOffset[Y_AXIS] = 0; + Printer::coordinateOffset[Z_AXIS] = 0; + Printer::currentNonlinearPositionSteps[A_TOWER] = 0; + Printer::currentNonlinearPositionSteps[B_TOWER] = 0; + Printer::currentNonlinearPositionSteps[C_TOWER] = 0; + // similar to comment above, this will get a different answer from any different starting point + // so it is unclear how this is helpful. It must start at a well defined point. + Printer::deltaMoveToTopEndstops(Printer::homingFeedrate[Z_AXIS]); + int32_t offx = HOME_DISTANCE_STEPS - Printer::stepsRemainingAtXHit; + int32_t offy = HOME_DISTANCE_STEPS - Printer::stepsRemainingAtYHit; + int32_t offz = HOME_DISTANCE_STEPS - Printer::stepsRemainingAtZHit; + Com::printFLN(Com::tTower1,offx); + Com::printFLN(Com::tTower2,offy); + Com::printFLN(Com::tTower3,offz); + Printer::setAutolevelActive(oldAuto); + PrintLine::moveRelativeDistanceInSteps(0, 0, Printer::axisStepsPerMM[Z_AXIS] * -ENDSTOP_Z_BACK_MOVE, 0, Printer::homingFeedrate[Z_AXIS] / ENDSTOP_X_RETEST_REDUCTION_FACTOR, true, false); + Printer::homeAxis(true,true,true); + } + break; + case 135: // G135 + Com::printF(PSTR("CompDelta:"),Printer::currentNonlinearPositionSteps[A_TOWER]); + Com::printF(Com::tComma,Printer::currentNonlinearPositionSteps[B_TOWER]); + Com::printFLN(Com::tComma,Printer::currentNonlinearPositionSteps[C_TOWER]); +#ifdef DEBUG_REAL_POSITION + Com::printF(PSTR("RealDelta:"),Printer::realDeltaPositionSteps[A_TOWER]); + Com::printF(Com::tComma,Printer::realDeltaPositionSteps[B_TOWER]); + Com::printFLN(Com::tComma,Printer::realDeltaPositionSteps[C_TOWER]); +#endif + Printer::updateCurrentPosition(); + Com::printF(PSTR("PosFromSteps:")); + printCurrentPosition(PSTR("G134 ")); + break; + +#endif // DRIVE_SYSTEM +#if FEATURE_Z_PROBE && NUM_EXTRUDER > 1 + case 134: + { // - G134 Px Sx Zx - Calibrate nozzle height difference (need z probe in nozzle!) Px = reference extruder, Sx = only measure extrude x against reference, Zx = add to measured z distance for Sx for correction. + float z = com->hasZ() ? com->Z : 0; + int p = com->hasP() ? com->P : 0; + int s = com->hasS() ? com->S : -1; + int startExtruder = Extruder::current->id; + extruder[p].zOffset = 0; + float mins[NUM_EXTRUDER],maxs[NUM_EXTRUDER],avg[NUM_EXTRUDER]; + for(int i = 0; i < NUM_EXTRUDER; i++) { // silence unnecessary compiler warning + avg[i] = 0; + } + bool bigError = false; + +#if defined(Z_PROBE_MIN_TEMPERATURE) && Z_PROBE_MIN_TEMPERATURE + float actTemp[NUM_EXTRUDER]; + for(int i = 0; i < NUM_EXTRUDER; i++) + actTemp[i] = extruder[i].tempControl.targetTemperatureC; + Printer::moveToReal(IGNORE_COORDINATE,IGNORE_COORDINATE,ZHOME_HEAT_HEIGHT,IGNORE_COORDINATE,Printer::homingFeedrate[Z_AXIS]); + Commands::waitUntilEndOfAllMoves(); +#if ZHOME_HEAT_ALL + for(int i = 0; i < NUM_EXTRUDER; i++) { + Extruder::setTemperatureForExtruder(RMath::max(actTemp[i],static_cast(ZPROBE_MIN_TEMPERATURE)),i,false,false); + } + for(int i = 0; i < NUM_EXTRUDER; i++) { + if(extruder[i].tempControl.currentTemperatureC < ZPROBE_MIN_TEMPERATURE) + Extruder::setTemperatureForExtruder(RMath::max(actTemp[i],static_cast(ZPROBE_MIN_TEMPERATURE)),i,false,true); + } +#else + if(extruder[Extruder::current->id].tempControl.currentTemperatureC < ZPROBE_MIN_TEMPERATURE) + Extruder::setTemperatureForExtruder(RMath::max(actTemp[Extruder::current->id],static_cast(ZPROBE_MIN_TEMPERATURE)),Extruder::current->id,false,true); +#endif +#endif + +#ifndef G134_REPETITIONS +#define G134_REPETITIONS 3 +#endif +#ifndef G134_PRECISION +#define G134_PRECISION 0.05 +#endif + Printer::startProbing(true); + for(int r = 0; r < G134_REPETITIONS && !bigError; r++) { + Extruder::selectExtruderById(p); + float refHeight = Printer::runZProbe(false,false); + if(refHeight == ILLEGAL_Z_PROBE) { + bigError = true; + break; + } + for(int i = 0; i < NUM_EXTRUDER && !bigError; i++) { + if(i == p) continue; + if(s >= 0 && i != s) continue; + extruder[i].zOffset = 0; + Extruder::selectExtruderById(i); + float height = Printer::runZProbe(false,false); + if(height == ILLEGAL_Z_PROBE) { + bigError = true; + break; + } + float off = (height - refHeight + z); + if(r == 0) { + avg[i] = mins[i] = maxs[i] = off; + } else { + avg[i] += off; + if(off < mins[i]) mins[i] = off; + if(off > maxs[i]) maxs[i] = off; + if(maxs[i] - mins[i] > G134_PRECISION) { + Com::printErrorFLN(PSTR("Deviation between measurements were too big, please repeat.")); + bigError = true; + break; + } + } + } + } + if(!bigError) { + for(int i = 0; i < NUM_EXTRUDER; i++) { + if(s >= 0 && i != s) continue; + extruder[i].zOffset = avg[i] * Printer::axisStepsPerMM[Z_AXIS] / G134_REPETITIONS; + } +#if EEPROM_MODE != 0 + EEPROM::storeDataIntoEEPROM(0); +#endif + } + Extruder::selectExtruderById(startExtruder); + Printer::finishProbing(); +#if defined(Z_PROBE_MIN_TEMPERATURE) && Z_PROBE_MIN_TEMPERATURE +#if ZHOME_HEAT_ALL + for(int i = 0; i < NUM_EXTRUDER; i++) + Extruder::setTemperatureForExtruder(actTemp[i],i,false,false); + for(int i = 0; i < NUM_EXTRUDER; i++) + Extruder::setTemperatureForExtruder(actTemp[i],i,false, actTemp[i] > MAX_ROOM_TEMPERATURE); +#else + Extruder::setTemperatureForExtruder(actTemp[Extruder::current->id], Extruder::current->id, false, actTemp[Extruder::current->id] > MAX_ROOM_TEMPERATURE); +#endif +#endif + } + break; +#endif +#if defined(NUM_MOTOR_DRIVERS) && NUM_MOTOR_DRIVERS > 0 + case 201: + commandG201(*com); + break; + case 202: + commandG202(*com); + break; + case 203: + commandG203(*com); + break; + case 204: + commandG204(*com); + break; +#endif // defined + default: + if(!EVENT_UNHANDLED_G_CODE(com) && Printer::debugErrors()) { + Com::printF(Com::tUnknownCommand); + com->printCommand(); + } + } + previousMillisCmd = HAL::timeInMilliseconds(); +} +/** +\brief Execute the G command stored in com. +*/ +void Commands::processMCode(GCode *com) { + switch( com->M ) { + case 3: // Spindle/laser on +#if defined(SUPPORT_LASER) && SUPPORT_LASER + if(Printer::mode == PRINTER_MODE_LASER) { + if(com->hasS()) + LaserDriver::intensity = constrain(com->S,0,255); + LaserDriver::laserOn = true; + Com::printFLN(PSTR("LaserOn:"),(int)LaserDriver::intensity); + } +#endif // defined +#if defined(SUPPORT_CNC) && SUPPORT_CNC + if(Printer::mode == PRINTER_MODE_CNC) { + waitUntilEndOfAllMoves(); + CNCDriver::spindleOnCW(com->hasS() ? com->S : 0); + } +#endif // defined + break; + case 4: // Spindle CCW +#if defined(SUPPORT_CNC) && SUPPORT_CNC + if(Printer::mode == PRINTER_MODE_CNC) { + waitUntilEndOfAllMoves(); + CNCDriver::spindleOnCCW(com->hasS() ? com->S : 0); + } +#endif // defined + break; + case 5: // Spindle/laser off +#if defined(SUPPORT_LASER) && SUPPORT_LASER + if(Printer::mode == PRINTER_MODE_LASER) { + LaserDriver::laserOn = false; + } +#endif // defined +#if defined(SUPPORT_CNC) && SUPPORT_CNC + if(Printer::mode == PRINTER_MODE_CNC) { + waitUntilEndOfAllMoves(); + CNCDriver::spindleOff(); + } +#endif // defined + break; +#if SDSUPPORT + case 20: // M20 - list SD card +#if JSON_OUTPUT + if (com->hasString() && com->text[1] == '2') { // " S2 P/folder" + if (com->text[3] == 'P') { + sd.lsJSON(com->text + 4); + } + } else sd.ls(); +#else + sd.ls(); +#endif + break; + case 21: // M21 - init SD card + sd.mount(); + break; + case 22: //M22 - release SD card + sd.unmount(); + break; + case 23: //M23 - Select file + if(com->hasString()) { + sd.fat.chdir(); + sd.selectFile(com->text); + } + break; + case 24: //M24 - Start SD print + sd.startPrint(); + break; + case 25: //M25 - Pause SD print + sd.pausePrint(); + break; + case 26: //M26 - Set SD index + if(com->hasS()) + sd.setIndex(com->S); + break; + case 27: //M27 - Get SD status + sd.printStatus(); + break; + case 28: //M28 - Start SD write + if(com->hasString()) + sd.startWrite(com->text); + break; + case 29: //M29 - Stop SD write + //processed in write to file routine above + //savetosd = false; + break; + case 30: // M30 filename - Delete file + if(com->hasString()) { + sd.fat.chdir(); + sd.deleteFile(com->text); + } + break; + case 32: // M32 directoryname + if(com->hasString()) { + sd.fat.chdir(); + sd.makeDirectory(com->text); + } + break; +#endif +#if JSON_OUTPUT && SDSUPPORT + case 36: // M36 JSON File Info + if (com->hasString()) { + sd.JSONFileInfo(com->text); + } + break; +#endif + case 42: //M42 -Change pin status via gcode + if (com->hasP()) { + int pin_number = com->P; + for(uint8_t i = 0; i < (uint8_t)sizeof(sensitive_pins); i++) { + if (pgm_read_byte(&sensitive_pins[i]) == pin_number) { + pin_number = -1; + break; + } + } + if (pin_number > -1) { + if(com->hasS()) { + if(com->S >= 0 && com->S <= 255) { + pinMode(pin_number, OUTPUT); + digitalWrite(pin_number, com->S); + analogWrite(pin_number, com->S); + Com::printF(Com::tSetOutputSpace, pin_number); + Com::printFLN(Com::tSpaceToSpace,(int)com->S); + } else + Com::printErrorFLN(PSTR("Illegal S value for M42")); + } else { + pinMode(pin_number, INPUT_PULLUP); + Com::printF(Com::tSpaceToSpace, pin_number); + Com::printFLN(Com::tSpaceIsSpace, digitalRead(pin_number)); + } + } else { + Com::printErrorFLN(PSTR("Pin can not be set by M42, is in sensitive pins! ")); + } + } + break; + case 80: // M80 - ATX Power On +#if PS_ON_PIN>-1 + Commands::waitUntilEndOfAllMoves(); + previousMillisCmd = HAL::timeInMilliseconds(); + SET_OUTPUT(PS_ON_PIN); //GND + Printer::setPowerOn(true); + WRITE(PS_ON_PIN, (POWER_INVERTING ? HIGH : LOW)); +#endif + break; + case 81: // M81 - ATX Power Off +#if PS_ON_PIN>-1 + Commands::waitUntilEndOfAllMoves(); + SET_OUTPUT(PS_ON_PIN); //GND + Printer::setPowerOn(false); + WRITE(PS_ON_PIN,(POWER_INVERTING ? LOW : HIGH)); +#endif + break; + case 82: // M82 + Printer::relativeExtruderCoordinateMode = false; + break; + case 83: // M83 + Printer::relativeExtruderCoordinateMode = true; + break; + case 84: // M84 + if(com->hasS()) { + stepperInactiveTime = com->S * 1000; + } else { + Commands::waitUntilEndOfAllMoves(); + Printer::kill(true); + } + break; + case 85: // M85 + if(com->hasS()) + maxInactiveTime = (int32_t)com->S * 1000; + else + maxInactiveTime = 0; + break; + case 92: // M92 + if(com->hasX()) Printer::axisStepsPerMM[X_AXIS] = com->X; + if(com->hasY()) Printer::axisStepsPerMM[Y_AXIS] = com->Y; + if(com->hasZ()) Printer::axisStepsPerMM[Z_AXIS] = com->Z; + Printer::updateDerivedParameter(); + if(com->hasE()) { + Extruder::current->stepsPerMM = com->E; + Extruder::selectExtruderById(Extruder::current->id); + } + break; + case 99: { // M99 S
    S : Set stepper current for digipot (RAMBO board) +- M999 - Continue from fatal error. M999 S1 will create a fatal error for testing. +*/ + +#include "Repetier.h" +#include + +#if UI_DISPLAY_TYPE == DISPLAY_ARDUINO_LIB +//#include // Uncomment this if you are using liquid crystal library +#endif + +void setup() +{ + Printer::setup(); +} + +void loop() +{ + Commands::commandLoop(); +} + + + + + + + + diff --git a/trunk/Arduino/Repetier_0.92.9/SDCard.cpp b/trunk/Arduino/Repetier_0.92.9/SDCard.cpp new file mode 100644 index 00000000..b70336a0 --- /dev/null +++ b/trunk/Arduino/Repetier_0.92.9/SDCard.cpp @@ -0,0 +1,651 @@ +/* + This file is part of Repetier-Firmware. + + Repetier-Firmware is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Repetier-Firmware is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Repetier-Firmware. If not, see . + + This firmware is a nearly complete rewrite of the sprinter firmware + by kliment (https://github.com/kliment/Sprinter) + which based on Tonokip RepRap firmware rewrite based off of Hydra-mmm firmware. +*/ + +#include "Repetier.h" + +#if SDSUPPORT + +char tempLongFilename[LONG_FILENAME_LENGTH + 1]; +char fullName[LONG_FILENAME_LENGTH * SD_MAX_FOLDER_DEPTH + SD_MAX_FOLDER_DEPTH + 1]; + +SDCard sd; + +SDCard::SDCard() +{ + sdmode = 0; + sdactive = false; + savetosd = false; + Printer::setAutomount(false); +} + +void SDCard::automount() +{ +#if SDCARDDETECT > -1 + if(READ(SDCARDDETECT) != SDCARDDETECTINVERTED) + { + if(sdactive || sdmode == 100) // Card removed + { + Com::printFLN(PSTR("SD card removed")); +#if UI_DISPLAY_TYPE != NO_DISPLAY + uid.executeAction(UI_ACTION_TOP_MENU, true); +#endif + unmount(); + UI_STATUS_UPD_F(Com::translatedF(UI_TEXT_SD_REMOVED_ID)); + } + } + else + { + if(!sdactive && sdmode != 100) + { + UI_STATUS_UPD_F(Com::translatedF(UI_TEXT_SD_INSERTED_ID)); + mount(); + if(sdmode != 100) // send message only if we have success + Com::printFLN(PSTR("SD card inserted")); // Not translatable or host will not understand signal +#if UI_DISPLAY_TYPE != NO_DISPLAY + if(sdactive && !uid.isWizardActive()) { // Wizards have priority + Printer::setAutomount(true); + uid.executeAction(UI_ACTION_SD_PRINT + UI_ACTION_TOPMENU, true); + } +#endif + } + } +#endif +} + +void SDCard::initsd() +{ + sdactive = false; +#if SDSS > -1 +#if SDCARDDETECT > -1 + if(READ(SDCARDDETECT) != SDCARDDETECTINVERTED) + return; +#endif + HAL::pingWatchdog(); + HAL::delayMilliseconds(50); // wait for stabilization of contacts, bootup ... + fat.begin(SDSS, SPI_FULL_SPEED); // dummy init of SD_CARD + HAL::delayMilliseconds(50); // wait for init end + HAL::pingWatchdog(); + /*if(dir[0].isOpen()) + dir[0].close();*/ + if(!fat.begin(SDSS, SPI_FULL_SPEED)) + { + Com::printFLN(Com::tSDInitFail); + sdmode = 100; // prevent automount loop! + return; + } + sdactive = true; + Printer::setMenuMode(MENU_MODE_SD_MOUNTED, true); + HAL::pingWatchdog(); + + fat.chdir(); + if(selectFile("init.g", true)) + { + startPrint(); + } +#endif +} + +void SDCard::mount() +{ + sdmode = 0; + initsd(); +} + +void SDCard::unmount() +{ + sdmode = 0; + sdactive = false; + savetosd = false; + Printer::setAutomount(false); + Printer::setMenuMode(MENU_MODE_SD_MOUNTED + MENU_MODE_SD_PAUSED + MENU_MODE_SD_PRINTING, false); +#if UI_DISPLAY_TYPE != NO_DISPLAY && SDSUPPORT + uid.cwd[0] = '/'; + uid.cwd[1] = 0; + uid.folderLevel = 0; +#endif +} + +void SDCard::startPrint() +{ + if(!sdactive) return; + sdmode = 1; + Printer::setMenuMode(MENU_MODE_SD_PRINTING, true); + Printer::setMenuMode(MENU_MODE_SD_PAUSED, false); +} +void SDCard::pausePrint(bool intern) +{ + if(!sd.sdactive) return; + sdmode = 2; // finish running line + Printer::setMenuMode(MENU_MODE_SD_PAUSED, true); + if(intern) { + Commands::waitUntilEndOfAllBuffers(); + sdmode = 0; + Printer::MemoryPosition(); + Printer::moveToReal(IGNORE_COORDINATE, IGNORE_COORDINATE, IGNORE_COORDINATE, + Printer::memoryE - RETRACT_ON_PAUSE, + Printer::maxFeedrate[E_AXIS] / 2); +#if DRIVE_SYSTEM == DELTA + Printer::moveToReal(0, 0.9 * EEPROM::deltaMaxRadius(), IGNORE_COORDINATE, IGNORE_COORDINATE, Printer::maxFeedrate[X_AXIS]); +#else + Printer::moveToReal(Printer::xMin, Printer::yMin + Printer::yLength, IGNORE_COORDINATE, IGNORE_COORDINATE, Printer::maxFeedrate[X_AXIS]); +#endif + Printer::lastCmdPos[X_AXIS] = Printer::currentPosition[X_AXIS]; + Printer::lastCmdPos[Y_AXIS] = Printer::currentPosition[Y_AXIS]; + Printer::lastCmdPos[Z_AXIS] = Printer::currentPosition[Z_AXIS]; + GCode::executeFString(PSTR(PAUSE_START_COMMANDS)); + } +} + +void SDCard::continuePrint(bool intern) +{ + if(!sd.sdactive) return; + if(intern) { + GCode::executeFString(PSTR(PAUSE_END_COMMANDS)); + Printer::GoToMemoryPosition(true, true, false, false, Printer::maxFeedrate[X_AXIS]); + Printer::GoToMemoryPosition(false, false, true, false, Printer::maxFeedrate[Z_AXIS] / 2.0f); + Printer::GoToMemoryPosition(false, false, false, true, Printer::maxFeedrate[E_AXIS] / 2.0f); + } + Printer::setMenuMode(MENU_MODE_SD_PAUSED, false); + sdmode = 1; +} + +void SDCard::stopPrint() +{ + if(!sd.sdactive) return; + if(sdmode) + Com::printFLN(PSTR("SD print stopped by user.")); + sdmode = 0; + Printer::setMenuMode(MENU_MODE_SD_PRINTING,false); + Printer::setMenuMode(MENU_MODE_SD_PAUSED,false); + GCode::executeFString(PSTR(SD_RUN_ON_STOP)); + if(SD_STOP_HEATER_AND_MOTORS_ON_STOP) { + Commands::waitUntilEndOfAllMoves(); + Printer::kill(false); + } +} + +void SDCard::writeCommand(GCode *code) +{ + unsigned int sum1 = 0, sum2 = 0; // for fletcher-16 checksum + uint8_t buf[100]; + uint8_t p = 2; + file.writeError = false; + uint16_t params = 128 | (code->params & ~1); + memcopy2(buf,¶ms); + //*(int*)buf = params; + if(code->isV2()) // Read G,M as 16 bit value + { + memcopy2(&buf[p],&code->params2); + //*(int*)&buf[p] = code->params2; + p += 2; + if(code->hasString()) + buf[p++] = strlen(code->text); + if(code->hasM()) + { + memcopy2(&buf[p],&code->M); + //*(int*)&buf[p] = code->M; + p += 2; + } + if(code->hasG()) + { + memcopy2(&buf[p],&code->G); + //*(int*)&buf[p]= code->G; + p += 2; + } + } + else + { + if(code->hasM()) + { + buf[p++] = (uint8_t)code->M; + } + if(code->hasG()) + { + buf[p++] = (uint8_t)code->G; + } + } + if(code->hasX()) + { + memcopy4(&buf[p],&code->X); + //*(float*)&buf[p] = code->X; + p += 4; + } + if(code->hasY()) + { + memcopy4(&buf[p],&code->Y); + //*(float*)&buf[p] = code->Y; + p += 4; + } + if(code->hasZ()) + { + memcopy4(&buf[p],&code->Z); + //*(float*)&buf[p] = code->Z; + p += 4; + } + if(code->hasE()) + { + memcopy4(&buf[p],&code->E); + //*(float*)&buf[p] = code->E; + p += 4; + } + if(code->hasF()) + { + memcopy4(&buf[p],&code->F); + //*(float*)&buf[p] = code->F; + p += 4; + } + if(code->hasT()) + { + buf[p++] = code->T; + } + if(code->hasS()) + { + memcopy4(&buf[p],&code->S); + //*(int32_t*)&buf[p] = code->S; + p += 4; + } + if(code->hasP()) + { + memcopy4(&buf[p],&code->P); + //*(int32_t*)&buf[p] = code->P; + p += 4; + } + if(code->hasI()) + { + memcopy4(&buf[p],&code->I); + //*(float*)&buf[p] = code->I; + p += 4; + } + if(code->hasJ()) + { + memcopy4(&buf[p],&code->J); + //*(float*)&buf[p] = code->J; + p += 4; + } + if(code->hasR()) + { + memcopy4(&buf[p],&code->R); + //*(float*)&buf[p] = code->R; + p += 4; + } + if(code->hasD()) + { + memcopy4(&buf[p],&code->D); + //*(float*)&buf[p] = code->D; + p += 4; + } + if(code->hasC()) + { + memcopy4(&buf[p],&code->C); + //*(float*)&buf[p] = code->C; + p += 4; + } + if(code->hasH()) + { + memcopy4(&buf[p],&code->H); + //*(float*)&buf[p] = code->H; + p += 4; + } + if(code->hasA()) + { + memcopy4(&buf[p],&code->A); + //*(float*)&buf[p] = code->A; + p += 4; + } + if(code->hasB()) + { + memcopy4(&buf[p],&code->B); + //*(float*)&buf[p] = code->B; + p += 4; + } + if(code->hasK()) + { + memcopy4(&buf[p],&code->K); + //*(float*)&buf[p] = code->K; + p += 4; + } + if(code->hasL()) + { + memcopy4(&buf[p],&code->L); + //*(float*)&buf[p] = code->L; + p += 4; + } + if(code->hasO()) + { + memcopy4(&buf[p],&code->O); + //*(float*)&buf[p] = code->O; + p += 4; + } + if(code->hasString()) // read 16 uint8_t into string + { + char *sp = code->text; + if(code->isV2()) + { + uint8_t i = strlen(code->text); + for(; i; i--) buf[p++] = *sp++; + } + else + { + for(uint8_t i = 0; i < 16; ++i) buf[p++] = *sp++; + } + } + uint8_t *ptr = buf; + uint8_t len = p; + while (len) + { + uint8_t tlen = len > 21 ? 21 : len; + len -= tlen; + do + { + sum1 += *ptr++; + if(sum1 >= 255) sum1 -= 255; + sum2 += sum1; + if(sum2 >= 255) sum2 -= 255; + } + while (--tlen); + } + buf[p++] = sum1; + buf[p++] = sum2; + // Debug + /*Com::printF(PSTR("Buf: ")); + for(int i=0;iinit(targetFile); + } + if (!targetFile.isOpen()) { + Com::printF(Com::tJSONErrorStart); + Com::printF(Com::tNotSDPrinting); + Com::printFLN(Com::tJSONErrorEnd); + return; + } + + // {"err":0,"size":457574,"height":4.00,"layerHeight":0.25,"filament":[6556.3],"generatedBy":"Slic3r 1.1.7 on 2014-11-09 at 17:11:32"} + Com::printF(Com::tJSONFileInfoStart); + Com::print(info->fileSize); + Com::printF(Com::tJSONFileInfoHeight); + Com::print(info->objectHeight); + Com::printF(Com::tJSONFileInfoLayerHeight); + Com::print(info->layerHeight); + Com::printF(Com::tJSONFileInfoFilament); + Com::print(info->filamentNeeded); + Com::printF(Com::tJSONFileInfoGeneratedBy); + Com::print(info->generatedBy); + Com::print('"'); + if (strlen(filename) == 0) { + Com::printF(Com::tJSONFileInfoName); + file.printName(); + Com::print('"'); + } + Com::print('}'); + Com::println(); +}; + +#endif + +bool SDCard::selectFile(const char *filename, bool silent) +{ + SdBaseFile parent; + const char *oldP = filename; + + if(!sdactive) return false; + sdmode = 0; + + file.close(); + + parent = *fat.vwd(); + if (file.open(&parent, filename, O_READ)) + { + if ((oldP = strrchr(filename, '/')) != NULL) + oldP++; + else + oldP = filename; + + if(!silent) + { + Com::printF(Com::tFileOpened, oldP); + Com::printFLN(Com::tSpaceSizeColon,file.fileSize()); + } +#if JSON_OUTPUT + fileInfo.init(file); +#endif + sdpos = 0; + filesize = file.fileSize(); + Com::printFLN(Com::tFileSelected); + return true; + } + else + { + if(!silent) + Com::printFLN(Com::tFileOpenFailed); + return false; + } +} + +void SDCard::printStatus() +{ + if(sdactive) + { + Com::printF(Com::tSDPrintingByte, sdpos); + Com::printFLN(Com::tSlash, filesize); + } + else + { + Com::printFLN(Com::tNotSDPrinting); + } +} + +void SDCard::startWrite(char *filename) +{ + if(!sdactive) return; + file.close(); + sdmode = 0; + fat.chdir(); + if(!file.open(filename, O_CREAT | O_APPEND | O_WRITE | O_TRUNC)) + { + Com::printFLN(Com::tOpenFailedFile,filename); + } + else + { + UI_STATUS_F(Com::translatedF(UI_TEXT_UPLOADING_ID)); + savetosd = true; + Com::printFLN(Com::tWritingToFile,filename); + } +} + +void SDCard::finishWrite() +{ + if(!savetosd) return; // already closed or never opened + file.sync(); + file.close(); + savetosd = false; + Com::printFLN(Com::tDoneSavingFile); + UI_CLEAR_STATUS; +} + +void SDCard::deleteFile(char *filename) +{ + if(!sdactive) return; + sdmode = 0; + file.close(); + if(fat.remove(filename)) + { + Com::printFLN(Com::tFileDeleted); + } + else + { + if(fat.rmdir(filename)) + Com::printFLN(Com::tFileDeleted); + else + Com::printFLN(Com::tDeletionFailed); + } +} + +void SDCard::makeDirectory(char *filename) +{ + if(!sdactive) return; + sdmode = 0; + file.close(); + if(fat.mkdir(filename)) + { + Com::printFLN(Com::tDirectoryCreated); + } + else + { + Com::printFLN(Com::tCreationFailed); + } +} + +#ifdef GLENN_DEBUG +void SDCard::writeToFile() +{ + size_t nbyte; + char szName[10]; + + strcpy(szName, "Testing\r\n"); + nbyte = file.write(szName, strlen(szName)); + Com::print("L="); + Com::print((long)nbyte); + Com::println(); +} + +#endif + +#endif + diff --git a/trunk/Arduino/Repetier_0.92.9/SdFat.cpp b/trunk/Arduino/Repetier_0.92.9/SdFat.cpp new file mode 100644 index 00000000..0c914de3 --- /dev/null +++ b/trunk/Arduino/Repetier_0.92.9/SdFat.cpp @@ -0,0 +1,4494 @@ +/* Arduino SdFat Library + * Copyright (C) 2012 by William Greiman + * + * This file is part of the Arduino SdFat Library + * + * This Library is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Arduino SdFat Library. If not, see + * . + */ + #include "Repetier.h" +#if SDSUPPORT +#if defined(ARDUINO) && ARDUINO >= 100 +#include "Arduino.h" +#else +#include "WProgram.h" +#define COMPAT_PRE1 +#endif +//#include + +extern int8_t RFstricmp(const char* s1, const char* s2); +extern int8_t RFstrnicmp(const char* s1, const char* s2, size_t n); + +//#define GLENN_DEBUG + +//------------------------------------------------------------------------------ +static void pstrPrintln(FSTRINGPARAM(str)) { + Com::printFLN(str); +} +//------------------------------------------------------------------------------ +/** + * Initialize an SdFat object. + * + * Initializes the SD card, SD volume, and root directory. + * + * \param[in] chipSelectPin SD chip select pin. See Sd2Card::init(). + * \param[in] sckRateID value for SPI SCK rate. See Sd2Card::init(). + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool SdFat::begin(uint8_t chipSelectPin, uint8_t sckRateID) { + return card_.init(sckRateID, chipSelectPin) && vol_.init(&card_) && chdir(1); +} +//------------------------------------------------------------------------------ + +/** Change a volume's working directory to root + * + * Changes the volume's working directory to the SD's root directory. + * Optionally set the current working directory to the volume's + * working directory. + * + * \param[in] set_cwd Set the current working directory to this volume's + * working directory if true. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool SdFat::chdir(bool set_cwd) { + if (set_cwd) SdBaseFile::cwd_ = &vwd_; + if (vwd_.isOpen()) vwd_.close(); + return vwd_.openRoot(&vol_); +} +//------------------------------------------------------------------------------ +/** Change a volume's working directory + * + * Changes the volume working directory to the \a path subdirectory. + * Optionally set the current working directory to the volume's + * working directory. + * + * Example: If the volume's working directory is "/DIR", chdir("SUB") + * will change the volume's working directory from "/DIR" to "/DIR/SUB". + * + * If path is "/", the volume's working directory will be changed to the + * root directory + * + * \param[in] path The name of the subdirectory. + * + * \param[in] set_cwd Set the current working directory to this volume's + * working directory if true. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool SdFat::chdir(const char *path, bool set_cwd) { + SdBaseFile dir; + if (path[0] == '/' && path[1] == '\0') return chdir(set_cwd); + + if (!dir.open(&vwd_, path, O_READ)) goto fail; + if (!dir.isDir()) goto fail; + vwd_ = dir; + if (set_cwd) SdBaseFile::cwd_ = &vwd_; + return true; + + fail: + return false; +} +//------------------------------------------------------------------------------ +/** Set the current working directory to a volume's working directory. + * + * This is useful with multiple SD cards. + * + * The current working directory is changed to this volume's working directory. + * + * This is like the Windows/DOS \: command. + */ +void SdFat::chvol() { + SdBaseFile::cwd_ = &vwd_; +} +//------------------------------------------------------------------------------ +/** %Print any SD error code and halt. */ +void SdFat::errorHalt() { + errorPrint(); + while (1); +} +//------------------------------------------------------------------------------ +/** %Print msg, any SD error code, and halt. + * + * \param[in] msg Message to print. + */ +void SdFat::errorHalt(char const* msg) { + errorPrint(msg); + while (1); +} +//------------------------------------------------------------------------------ +/** %Print msg, any SD error code, and halt. + * + * \param[in] msg Message in program space (flash memory) to print. + */ +void SdFat::errorHalt_P(FSTRINGPARAM(msg)) { + errorPrint_P(msg); + while (1); +} +//------------------------------------------------------------------------------ +/** %Print any SD error code. */ +void SdFat::errorPrint() { + if (!card_.errorCode()) return; + Com::printFLN(Com::tSDErrorCode,card_.errorCode()); +} +//------------------------------------------------------------------------------ +/** %Print msg, any SD error code. + * + * \param[in] msg Message to print. + */ +void SdFat::errorPrint(char const* msg) { + Com::printFLN(Com::tError,msg); + errorPrint(); +} +//------------------------------------------------------------------------------ +/** %Print msg, any SD error code. + * + * \param[in] msg Message in program space (flash memory) to print. + */ +void SdFat::errorPrint_P(FSTRINGPARAM(msg)) { + Com::printF(Com::tError); + Com::printFLN(msg); + errorPrint(); +} +//------------------------------------------------------------------------------ +/** + * Test for the existence of a file. + * + * \param[in] name Name of the file to be tested for. + * + * \return true if the file exists else false. + */ +bool SdFat::exists(const char* name) { + return vwd_.exists(name); +} +//------------------------------------------------------------------------------ +/** %Print error details and halt after SdFat::init() fails. */ +void SdFat::initErrorHalt() { + initErrorPrint(); + while (1); +} +//------------------------------------------------------------------------------ +/**Print message, error details, and halt after SdFat::init() fails. + * + * \param[in] msg Message to print. + */ +void SdFat::initErrorHalt(char const *msg) { + Com::print(msg); + Com::println(); + initErrorHalt(); +} +//------------------------------------------------------------------------------ +/**Print message, error details, and halt after SdFat::init() fails. + * + * \param[in] msg Message in program space (flash memory) to print. + */ +void SdFat::initErrorHalt_P(FSTRINGPARAM(msg)) { + pstrPrintln(msg); + initErrorHalt(); +} +//------------------------------------------------------------------------------ +/** Print error details after SdFat::init() fails. */ +void SdFat::initErrorPrint() { + if (card_.errorCode()) { + pstrPrintln(PSTR("Can't access SD card. Do not reformat.")); + if (card_.errorCode() == SD_CARD_ERROR_CMD0) { + pstrPrintln(PSTR("No card, wrong chip select pin, or SPI problem?")); + } + errorPrint(); + } else if (vol_.fatType() == 0) { + pstrPrintln(PSTR("Invalid format, reformat SD.")); + } else if (!vwd_.isOpen()) { + pstrPrintln(PSTR("Can't open root directory.")); + } else { + pstrPrintln(PSTR("No error found.")); + } +} +//------------------------------------------------------------------------------ +/**Print message and error details and halt after SdFat::init() fails. + * + * \param[in] msg Message to print. + */ +void SdFat::initErrorPrint(char const *msg) { + Com::print(msg); + Com::println(); + initErrorPrint(); +} +//------------------------------------------------------------------------------ +/**Print message and error details after SdFat::init() fails. + * + * \param[in] msg Message in program space (flash memory) to print. + */ +void SdFat::initErrorPrint_P(FSTRINGPARAM(msg)) { + pstrPrintln(msg); + initErrorHalt(); +} +//------------------------------------------------------------------------------ +/** Make a subdirectory in the volume working directory. + * + * \param[in] path A path with a valid 8.3 DOS name for the subdirectory. + * + * \param[in] pFlag Create missing parent directories if true. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool SdFat::mkdir(const char* path, bool pFlag) { + SdBaseFile sub; + return sub.mkdir(&vwd_, path, pFlag); +} +//------------------------------------------------------------------------------ +/** Remove a file from the volume working directory. +* +* \param[in] path A path with a valid 8.3 DOS name for the file. +* +* \return The value one, true, is returned for success and +* the value zero, false, is returned for failure. +*/ +bool SdFat::remove(const char* path) { + return SdBaseFile::remove(&vwd_, path); +} +//------------------------------------------------------------------------------ +/** Rename a file or subdirectory. + * + * \param[in] oldPath Path name to the file or subdirectory to be renamed. + * + * \param[in] newPath New path name of the file or subdirectory. + * + * The \a newPath object must not exist before the rename call. + * + * The file to be renamed must not be open. The directory entry may be + * moved and file system corruption could occur if the file is accessed by + * a file object that was opened before the rename() call. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool SdFat::rename(const char *oldPath, const char *newPath) { + SdBaseFile file; + if (!file.open(oldPath, O_READ)) return false; + return file.rename(&vwd_, newPath); +} +//------------------------------------------------------------------------------ +/** Remove a subdirectory from the volume's working directory. + * + * \param[in] path A path with a valid 8.3 DOS name for the subdirectory. + * + * The subdirectory file will be removed only if it is empty. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool SdFat::rmdir(const char* path) { + SdBaseFile sub; + if (!sub.open(path, O_READ)) return false; + return sub.rmdir(); +} +//------------------------------------------------------------------------------ +/** Truncate a file to a specified length. The current file position + * will be maintained if it is less than or equal to \a length otherwise + * it will be set to end of file. + * + * \param[in] path A path with a valid 8.3 DOS name for the file. + * \param[in] length The desired length for the file. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include file is read only, file is a directory, + * \a length is greater than the current file size or an I/O error occurs. + */ +bool SdFat::truncate(const char* path, uint32_t length) { + SdBaseFile file; + if (!file.open(path, O_WRITE)) return false; + return file.truncate(length); +} + +// macro for debug +#define DBG_FAIL_MACRO // Serial.println(__LINE__) +//------------------------------------------------------------------------------ +// pointer to cwd directory +SdBaseFile* SdBaseFile::cwd_ = 0; +// callback function for date/time +void (*SdBaseFile::dateTime_)(uint16_t* date, uint16_t* time) = 0; +//------------------------------------------------------------------------------ +// add a cluster to a file +bool SdBaseFile::addCluster() { + if (!vol_->allocContiguous(1, &curCluster_)) { + DBG_FAIL_MACRO; + goto fail; + } + // if first cluster of file link to directory entry + if (firstCluster_ == 0) { + firstCluster_ = curCluster_; + flags_ |= F_FILE_DIR_DIRTY; + } + return true; + + fail: + return false; +} +//------------------------------------------------------------------------------ +// Add a cluster to a directory file and zero the cluster. +// return with first block of cluster in the cache +cache_t* SdBaseFile::addDirCluster() { + uint32_t block; + cache_t* pc; + // max folder size + if (fileSize_/sizeof(dir_t) >= 0XFFFF) { + DBG_FAIL_MACRO; + goto fail; + } + if (!addCluster()) { + DBG_FAIL_MACRO; + goto fail; + } + block = vol_->clusterStartBlock(curCluster_); + pc = vol_->cacheFetch(block, SdVolume::CACHE_RESERVE_FOR_WRITE); + if (!pc) { + DBG_FAIL_MACRO; + goto fail; + } + memset(pc, 0, 512); + // zero rest of clusters + for (uint8_t i = 1; i < vol_->blocksPerCluster_; i++) { + if (!vol_->writeBlock(block + i, pc->data)) { + DBG_FAIL_MACRO; + goto fail; + } + } + // Increase directory file size by cluster size + fileSize_ += 512UL*vol_->blocksPerCluster_; + return pc; + + fail: + return 0; +} +//------------------------------------------------------------------------------ +// cache a file's directory entry +// return pointer to cached entry or null for failure +dir_t* SdBaseFile::cacheDirEntry(uint8_t action) { + cache_t* pc; + pc = vol_->cacheFetch(dirBlock_, action); + if (!pc) { + DBG_FAIL_MACRO; + goto fail; + } + return pc->dir + dirIndex_; + fail: + return 0; +} +//------------------------------------------------------------------------------ +/** Close a file and force cached data and directory information + * to be written to the storage device. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include no file is open or an I/O error. + */ +bool SdBaseFile::close() { + bool rtn = sync(); + type_ = FAT_FILE_TYPE_CLOSED; + return rtn; +} +//------------------------------------------------------------------------------ +/** Check for contiguous file and return its raw block range. + * + * \param[out] bgnBlock the first block address for the file. + * \param[out] endBlock the last block address for the file. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include file is not contiguous, file has zero length + * or an I/O error occurred. + */ +bool SdBaseFile::contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock) { + // error if no blocks + if (firstCluster_ == 0) { + DBG_FAIL_MACRO; + goto fail; + } + for (uint32_t c = firstCluster_; ; c++) { + uint32_t next; + if (!vol_->fatGet(c, &next)) { + DBG_FAIL_MACRO; + goto fail; + } + // check for contiguous + if (next != (c + 1)) { + // error if not end of chain + if (!vol_->isEOC(next)) { + DBG_FAIL_MACRO; + goto fail; + } + *bgnBlock = vol_->clusterStartBlock(firstCluster_); + *endBlock = vol_->clusterStartBlock(c) + + vol_->blocksPerCluster_ - 1; + return true; + } + } + + fail: + return false; +} +//------------------------------------------------------------------------------ +/** Create and open a new contiguous file of a specified size. + * + * \note This function only supports short DOS 8.3 names. + * See open() for more information. + * + * \param[in] dirFile The directory where the file will be created. + * \param[in] path A path with a valid DOS 8.3 file name. + * \param[in] size The desired file size. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include \a path contains + * 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) { + uint32_t count; + // don't allow zero length file + if (size == 0) { + DBG_FAIL_MACRO; + goto fail; + } + if (!open(dirFile, path, O_CREAT | O_EXCL | O_RDWR)) { + DBG_FAIL_MACRO; + goto fail; + } + // calculate number of clusters needed + count = ((size - 1) >> (vol_->clusterSizeShift_ + 9)) + 1; + + // allocate clusters + if (!vol_->allocContiguous(count, &firstCluster_)) { + remove(); + DBG_FAIL_MACRO; + goto fail; + } + fileSize_ = size; + + // insure sync() will update dir entry + flags_ |= F_FILE_DIR_DIRTY; + + return sync(); + + fail: + return false; +} +//------------------------------------------------------------------------------ +/** Return a file's directory entry. + * + * \param[out] dir Location for return of the file's directory entry. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool SdBaseFile::dirEntry(dir_t* dir) { + dir_t* p; + // make sure fields on SD are correct + if (!sync()) { + DBG_FAIL_MACRO; + goto fail; + } + // read entry + p = cacheDirEntry(SdVolume::CACHE_FOR_READ); + if (!p) { + DBG_FAIL_MACRO; + goto fail; + } + // copy to caller's struct + memcpy(dir, p, sizeof(dir_t)); + return true; + + fail: + return false; +} +//------------------------------------------------------------------------------ +/** Format the name field of \a dir into the 13 byte array + * \a name in standard 8.3 short name format. + * + * \param[in] dir The directory structure containing the name. + * \param[out] name A 13 byte char array for the formatted name. + */ +void SdBaseFile::dirName(const dir_t& dir, char* name) { + uint8_t j = 0; + for (uint8_t i = 0; i < 11; i++) { + if (dir.name[i] == ' ') continue; + if (i == 8) name[j++] = '.'; + name[j++] = dir.name[i]; + } + name[j] = 0; +} +//------------------------------------------------------------------------------ +/** Test for the existence of a file in a directory + * + * \param[in] name Name of the file to be tested for. + * + * The calling instance must be an open directory file. + * + * dirFile.exists("TOFIND.TXT") searches for "TOFIND.TXT" in the directory + * dirFile. + * + * \return true if the file exists else false. + */ +bool SdBaseFile::exists(const char* name) { + SdBaseFile file; + return file.open(this, name, O_READ); +} +//------------------------------------------------------------------------------ +/** + * Get a string from a file. + * + * fgets() reads bytes from a file into the array pointed to by \a str, until + * \a num - 1 bytes are read, or a delimiter is read and transferred to \a str, + * or end-of-file is encountered. The string is then terminated + * with a null byte. + * + * fgets() deletes CR, '\\r', from the string. This insures only a '\\n' + * terminates the string for Windows text files which use CRLF for newline. + * + * \param[out] str Pointer to the array where the string is stored. + * \param[in] num Maximum number of characters to be read + * (including the final null byte). Usually the length + * of the array \a str is used. + * \param[in] delim Optional set of delimiters. The default is "\n". + * + * \return For success fgets() returns the length of the string in \a str. + * If no data is read, fgets() returns zero for EOF or -1 if an error occurred. + **/ +int16_t SdBaseFile::fgets(char* str, int16_t num, char* delim) { + char ch; + int16_t n = 0; + int16_t r = -1; + while ((n + 1) < num && (r = read(&ch, 1)) == 1) { + // delete CR + if (ch == '\r') continue; + str[n++] = ch; + if (!delim) { + if (ch == '\n') break; + } else { + if (strchr(delim, ch)) break; + } + } + if (r < 0) { + // read error + return -1; + } + str[n] = '\0'; + return n; +} +//------------------------------------------------------------------------------ +/** Get a file's name + * + * \param[out] name An array of 13 characters for the file's name. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool SdBaseFile::getFilename(char* name) { + dir_t* p; + if (!isOpen()) { + DBG_FAIL_MACRO; + goto fail; + } + if (isRoot()) { + name[0] = '/'; + name[1] = '\0'; + return true; + } + // cache entry + p = cacheDirEntry(SdVolume::CACHE_FOR_READ); + if (!p) { + DBG_FAIL_MACRO; + goto fail; + } + // format name + dirName(*p, name); + return true; + + fail: + return false; +} +//------------------------------------------------------------------------------ +void SdBaseFile::getpos(FatPos_t* pos) { + pos->position = curPosition_; + pos->cluster = curCluster_; +} +//------------------------------------------------------------------------------ +/** List directory contents to stdOut. + * + * \param[in] flags The inclusive OR of + * + * LS_DATE - %Print file modification date + * + * LS_SIZE - %Print file size. + * + * LS_R - Recursive list of subdirectories. + */ +void SdBaseFile::ls(uint8_t flags) { + ls(flags, 0); +} + +uint8_t SdBaseFile::lsRecursive(SdBaseFile *parent, uint8_t level, char *findFilename, SdBaseFile *pParentFound, bool isJson) +{ + dir_t *p = NULL; + //uint8_t cnt=0; + //char *oldpathend = pathend; + bool firstFile = true; + + parent->rewind(); + + while ((p = parent->getLongFilename(p, tempLongFilename, 0, NULL))) + { + HAL::pingWatchdog(); + if (! (DIR_IS_FILE(p) || DIR_IS_SUBDIR(p))) continue; + if (strcmp(tempLongFilename, "..") == 0) continue; + if (tempLongFilename[0] == '.') continue; // MAC CRAP + if (DIR_IS_SUBDIR(p)) { + if (level >= SD_MAX_FOLDER_DEPTH) continue; // can't go deeper + if (level < SD_MAX_FOLDER_DEPTH && findFilename == NULL) { + if (level && !isJson) { + Com::print(fullName); + Com::printF(Com::tSlash); + } +#if JSON_OUTPUT + if (isJson) { + if (!firstFile) Com::print(','); + Com::print('"');Com::print('*'); + SDCard::printEscapeChars(tempLongFilename); + Com::print('"'); + firstFile = false; + } else { + Com::print(tempLongFilename); + Com::printFLN(Com::tSlash); // End with / to mark it as directory entry, so we can see empty directories. + } +#else + Com::print(tempLongFilename); + Com::printFLN(Com::tSlash); // End with / to mark it as directory entry, so we can see empty directories. +#endif + } + SdBaseFile next; + char *tmp; + + if(level) strcat(fullName, "/"); + + strcat(fullName, tempLongFilename); + uint16_t index = (parent->curPosition()-31) >> 5; + + if(!isJson && next.open(parent, index, O_READ)) + { + if (next.lsRecursive(&next,level+1, findFilename, pParentFound,false)) + return true; + } + parent->seekSet(32 * (index + 1)); + if ((tmp = strrchr(fullName, '/'))!= NULL) + *tmp = 0; + else + *fullName = 0; + } + else + { + if (findFilename != NULL) + { + int8_t cFullname; + + cFullname = strlen(fullName); + if (RFstrnicmp(fullName, findFilename, cFullname) == 0) + { + if (cFullname > 0) + cFullname++; + if (RFstricmp(tempLongFilename, findFilename+cFullname) == 0) + { + if (pParentFound != NULL) + *pParentFound = *parent; + return true; + } + } + } + else + { + if(level && !isJson) + { + Com::print(fullName); + Com::printF(Com::tSlash); + } +#if JSON_OUTPUT + if (isJson) { + if (!firstFile) Com::printF(Com::tComma); + Com::print('"'); + SDCard::printEscapeChars(tempLongFilename); + Com::print('"'); + firstFile = false; + } else +#endif + { + Com::print(tempLongFilename); +#if SD_EXTENDED_DIR + Com::printF(Com::tSpace, (long) p->fileSize); +#endif + Com::println(); + } + } + } + } + return false; +} + +//------------------------------------------------------------------------------ +/** List directory contents. + * + * \param[in] pr Print stream for list. + * + * \param[in] flags The inclusive OR of + * + * LS_DATE - %Print file modification date + * + * LS_SIZE - %Print file size. + * + * LS_R - Recursive list of subdirectories. + * + * \param[in] indent Amount of space before file name. Used for recursive + * list to indicate subdirectory level. + */ +void SdBaseFile::ls(uint8_t flags, uint8_t indent) { + SdBaseFile parent; + rewind(); + *fullName = 0; + pathend = fullName; + parent = *this; + lsRecursive(&parent, 0, NULL, NULL, false); +} + +#if JSON_OUTPUT +void SdBaseFile::lsJSON() { + SdBaseFile parent; + rewind(); + *fullName = 0; + parent = *this; + lsRecursive(&parent, 0, NULL, NULL, true); +} +#endif + +//------------------------------------------------------------------------------ +// saves 32 bytes on stack for ls recursion +// return 0 - EOF, 1 - normal file, or 2 - directory +int8_t SdBaseFile::lsPrintNext(uint8_t flags, uint8_t indent) { + dir_t dir; + //uint8_t w = 0; + while (1) { + if (read(&dir, sizeof(dir)) != sizeof(dir)) return 0; + if (dir.name[0] == DIR_NAME_FREE) return 0; + + // skip deleted entry and entries for . and .. + if (dir.name[0] != DIR_NAME_DELETED && dir.name[0] != '.' + && DIR_IS_FILE_OR_SUBDIR(&dir)) break; + } + // indent for dir level + for (uint8_t i = 0; i < indent; i++) Com::print(' '); + + printDirName(dir, flags & (LS_DATE | LS_SIZE) ? 14 : 0, true); + + // print modify date/time if requested + if (flags & LS_DATE) { + Com::print(' '); + printFatDate(dir.lastWriteDate); + Com::print(' '); + printFatTime(dir.lastWriteTime); + } + // print size if requested + if (!DIR_IS_SUBDIR(&dir) && (flags & LS_SIZE)) { + Com::print(' '); + Com::print(dir.fileSize); + } + Com::println(); + return DIR_IS_FILE(&dir) ? 1 : 2; +} +//------------------------------------------------------------------------------ +// format directory name field from a 8.3 name string +FSTRINGVALUE(illegalFileChars,"|<>^+=?/[];,*\"\\") +bool SdBaseFile::make83Name(const char* str, uint8_t* name, const char** ptr) { + uint8_t c; + uint8_t n = 7; // max index for part before dot + uint8_t i = 0; + // blank fill name and extension + while (i < 11) name[i++] = ' '; + i = 0; + while (*str != '\0' && *str != '/') { + c = *str++; + if (c == '.') { + if (n == 10) { + DBG_FAIL_MACRO; + goto fail; // only one dot allowed + } + n = 10; // max index for full 8.3 name + i = 8; // place for extension + } else { + // illegal FAT characters +#define FLASH_ILLEGAL_CHARS +#ifdef FLASH_ILLEGAL_CHARS + // store chars in flash + FSTRINGPARAM(p); + p = illegalFileChars; + uint8_t b; + while ((b = HAL::readFlashByte(p++))) { + if (b == c) { + DBG_FAIL_MACRO; + goto fail; + } + } +#else // FLASH_ILLEGAL_CHARS + // store chars in RAM + if (strchr("|<>^+=?/[];,*\"\\", c)) { + DBG_FAIL_MACRO; + goto fail; + } +#endif // FLASH_ILLEGAL_CHARS + + // check size and only allow ASCII printable characters + if (i > n || c < 0X20 || c > 0X7E) { + c = '_'; + } + // only upper case allowed in 8.3 names - convert lower to upper + name[i++] = c < 'a' || c > 'z' ? c : c + ('A' - 'a'); + } + } + *ptr = str; + // must have a file name, extension is optional + return name[0] != ' '; + + fail: + return false; +} +//------------------------------------------------------------------------------ +/** Make a new directory. + * + * \param[in] parent An open SdFat instance for the directory that will contain + * the new directory. + * + * \param[in] path A path with a valid 8.3 DOS name for the new directory. + * + * \param[in] pFlag Create missing parent directories if true. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include this file is already open, \a parent is not a + * directory, \a path is invalid or already exists in \a parent. + */ +bool SdBaseFile::mkdir(SdBaseFile* parent, const char* path, bool pFlag) { + + uint8_t dname[LONG_FILENAME_LENGTH+1]; + SdBaseFile newParent; + + if (openParentReturnFile(parent, path, dname, &newParent, pFlag)) + { + return mkdir(&newParent, dname); + } + return false; +} +//------------------------------------------------------------------------------ +bool SdBaseFile::mkdir(SdBaseFile* parent, const uint8_t *dname) { + dir_t d; + + if (!parent->isDir()) { + DBG_FAIL_MACRO; + return false; + } + + // create a normal file + if (!open(parent, dname, O_CREAT | O_EXCL | O_RDWR, true)) { + DBG_FAIL_MACRO; + return false; + } + + // make entry for '.' + memset(&d, 0, sizeof(d)); + d.creationDate = FAT_DEFAULT_DATE; + d.creationTime = FAT_DEFAULT_TIME; + d.lastAccessDate = d.creationDate; + d.lastWriteDate = d.creationDate; + d.lastWriteTime = d.creationTime; + + d.name[0] = '.'; + d.attributes = DIR_ATT_DIRECTORY; + for (uint8_t i = 1; i < 11; i++) d.name[i] = ' '; + + if (write(&d, sizeof(dir_t)) < 0) + return false; + sync(); + + // make entry for '..' + d.name[1] = '.'; + if (parent->isRoot()) { + d.firstClusterLow = 0; + d.firstClusterHigh = 0; + } else { + d.firstClusterLow = parent->firstCluster_ & 0XFFFF; + d.firstClusterHigh = parent->firstCluster_ >> 16; + } + if (write(&d, sizeof(dir_t)) < 0) + return false; + sync(); + memset(&d, 0, sizeof(dir_t)); + if (write(&d, sizeof(dir_t)) < 0) + return false; + sync(); +// fileSize_ = 0; + type_ = FAT_FILE_TYPE_SUBDIR; + flags_ |= F_FILE_DIR_DIRTY; + return true; +} +//------------------------------------------------------------------------------ + /** Open a file in the current working directory. + * + * \param[in] path A path with a valid 8.3 DOS name for a file to be opened. + * + * \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive + * OR of open flags. see SdBaseFile::open(SdBaseFile*, const char*, uint8_t). + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ + bool SdBaseFile::open(const char* path, uint8_t oflag) { + return open(cwd_, path, oflag); + } + +//------------------------------------------------------------------------------ +/** Open a file or directory by name. + * + * \param[in] dirFile An open SdFat instance for the directory containing the + * file to be opened. + * + * \param[in] path A path with a valid 8.3 DOS name for a file to be opened. + * + * \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive + * OR of flags from the following list + * + * O_READ - Open for reading. + * + * O_RDONLY - Same as O_READ. + * + * O_WRITE - Open for writing. + * + * O_WRONLY - Same as O_WRITE. + * + * O_RDWR - Open for reading and writing. + * + * O_APPEND - If set, the file offset shall be set to the end of the + * file prior to each write. + * + * O_AT_END - Set the initial position at the end of the file. + * + * O_CREAT - If the file exists, this flag has no effect except as noted + * under O_EXCL below. Otherwise, the file shall be created + * + * O_EXCL - If O_CREAT and O_EXCL are set, open() shall fail if the file exists. + * + * O_SYNC - Call sync() after each write. This flag should not be used with + * write(uint8_t), write_P(PGM_P), writelnmkdir_P(PGM_P), or the Arduino Print class. + * These functions do character at a time writes so sync() will be called + * after each byte. + * + * O_TRUNC - If the file exists and is a regular file, and the file is + * successfully opened and is not read only, its length shall be truncated to 0. + * + * WARNING: A given file must not be opened by more than one SdBaseFile object + * of file corruption may occur. + * + * \note Directory files must be opened read only. Write and truncation is + * not allowed for directory files. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include this file is already open, \a dirFile is not + * a directory, \a path is invalid, the file does not exist + * or can't be opened in the access mode specified by oflag. + */ + + bool SdBaseFile::openParentReturnFile(SdBaseFile* dirFile, const char* path, uint8_t *dname, + SdBaseFile *newParent, boolean bMakeDirs) { + SdBaseFile dir1, dir2; + SdBaseFile *parent = dirFile; + //dir_t *pEntry; + SdBaseFile *sub = &dir1; + char *p; + //boolean bFound; + +#ifdef GLENN_DEBUG + Commands::checkFreeMemory(); + Commands::writeLowestFreeRAM(); +#endif + + *dname = 0; + + if (!dirFile) { + DBG_FAIL_MACRO; + goto fail; + } + // error if already open + if (isOpen()) { + DBG_FAIL_MACRO; + goto fail; + } + if (*path == '/') { + while (*path == '/') path++; + if (!dirFile->isRoot()) + { + if (!dir2.openRoot(dirFile->vol_)) + { + DBG_FAIL_MACRO; + goto fail; + } + parent = &dir2; + } + } + // Traverse the Long Directory Name Path until we get to the LEAF (long file name) + while ((p = strchr(path, '/')) != NULL) + { + int8_t cb = p-path; + + memcpy(dname, path, cb); + *(dname+cb) = 0; + + if (*(p+1) == 0) + goto success; +#ifdef GLENN_DEBUG + Commands::checkFreeMemory(); + Commands::writeLowestFreeRAM(); +#endif + //bFound = false; + if (!sub->open(parent, dname, O_READ, false)) + { + if (!bMakeDirs) + return false; + if (!sub->mkdir(parent, dname)) + { + return false; + } + } + if (parent != dirFile) parent->close(); + parent = sub; + sub = parent != &dir1 ? &dir1 : &dir2; + path = p+1; + } + strcpy((char *)dname, path); + + success: + *newParent = *parent; +#ifdef GLENN_DEBUG + Commands::checkFreeMemory(); + Commands::writeLowestFreeRAM(); +#endif + return true; + + fail: + return false; +} + +bool SdBaseFile::open(SdBaseFile* dirFile, const char* path, uint8_t oflag) +{ + uint8_t dname[LONG_FILENAME_LENGTH+1]; + SdBaseFile parent; + + if (openParentReturnFile(dirFile, path, dname, &parent, false)) + { + if (*dname == 0) + return true; + return open(&parent, dname, oflag, false); + } + + return false; +} + + +uint8_t SdBaseFile::lfn_checksum(const unsigned char *pFCBName) +{ + int i; + unsigned char sum = 0; + + for (i = 11; i; i--) + sum = ((sum & 1) << 7) + (sum >> 1) + *pFCBName++; + + return sum; +} +//------------------------------------------------------------------------------ +// open with filename in dname +bool SdBaseFile::open(SdBaseFile* dirFile,const uint8_t *dname, uint8_t oflag, bool bDir) { + bool emptyFound = false; + uint8_t index = 0; + dir_t tempDir, *p = NULL; + const char *tempPtr; + char newName[SHORT_FILENAME_LENGTH+2]; + boolean bShortName = false; + int8_t cVFATNeeded = -1, cVFATFoundCur; + uint32_t wIndexPos = 0; + uint8_t cbFilename; + char *Filename = (char *)dname; + +#ifdef GLENN_DEBUG + Com::print("Open File:"); + Com::print((char*)dname); + Com::println(); +#endif + vol_ = dirFile->vol_; + dirFile->rewind(); + // search for file + + if (oflag & O_CREAT) + { + int8_t cb = strlen((char *)dname); + bShortName = cb < 9; + cVFATNeeded = (cb / 13) + (cb % 13 == 0 ? 0 : 1); + } + + while ((p = dirFile->getLongFilename(p, tempLongFilename, cVFATNeeded, &wIndexPos))) + { + HAL::pingWatchdog(); + index = (0XF & ((dirFile->curPosition_-31) >> 5)); + if (RFstricmp(tempLongFilename, (char *)dname) == 0) + { +#ifdef GLENN_DEBUG + Com::print("FFound"); + Com::println(); +#endif + if (oflag & O_EXCL) + { + DBG_FAIL_MACRO; + goto fail; + } + return openCachedEntry(index, oflag); + } + } + + // don't create unless O_CREAT and O_WRITE + if (!(oflag & O_CREAT) || !(oflag & O_WRITE)) { + goto fail; + } + + dirFile->findSpace(&tempDir, cVFATNeeded, &cVFATFoundCur, &wIndexPos); + if (wIndexPos != 0) + { + emptyFound = true; +#ifdef GLENN_DEBUG + Com::print("Empty FAT:"); + Com::print((long)wIndexPos); + Com::println(); +#endif + index = wIndexPos >> 5; + } + else + { + // only 512 entries allowed in FAT16 Root Fixed dir + if (dirFile->type() == FAT_FILE_TYPE_ROOT_FIXED && (dirFile->curPosition_ >> 5) >= 512) + goto fail; + cVFATFoundCur = cVFATNeeded + 1; + if (dirFile->curPosition_ > 0) + wIndexPos = dirFile->curPosition_-32; + } + p = &tempDir; + +#ifdef GLENN_DEBUG + Com::print("CurPos:"); + Com::print((long)wIndexPos); + Com::println(); +#endif + dirFile->flags_ |= O_WRITE; + dirFile->seekSet(wIndexPos); + + // Create LONG FILE NAMES and LONG DIRECTORIES HERE + // FILL IN MULTIPLE dir_t enteries.. + // DO a test and and make all files created have a long file name of "XXXXXXX " +#ifdef GLENN_DEBUG + Com::print("At Index:"); + Com::print((long)index); + Com::print("-"); + Com::print((long)bShortName); + Com::println(); + + Com::print("Create:"); + Com::print((char *)dname); + Com::println(); +#endif + if (!bShortName) + { + char *pExt, szExt[5]; + + // Generate 8.3 from longfile name + if ((pExt = strchr((char *)dname, '.')) != NULL) + { + strncpy(szExt, pExt, 4); + szExt[4] = 0; + if (pExt > (char*)dname+6) + pExt = (char*)dname+6; + } + else + { + szExt[0] = 0; + pExt = (char*)dname+6; + } + uint8_t cb = pExt-(char *)dname; + memcpy(newName, dname, cb); + newName[cb] = 0; + strcat(newName, "~1"); + strcat(newName, szExt); + } + else + { + strcpy(newName, (char *)dname); + } + + uint8_t checksum; + + make83Name(newName, (uint8_t *)p->name, &tempPtr); + checksum = lfn_checksum(p->name); +#ifdef GLENN_DEBUG + Com::print("Name:"); + Com::print((char *)p->name); + Com::println(); +#endif + cbFilename = strlen(Filename); + + // Write Long File Name VFAT entries to file + for(uint8_t iBlk=cVFATNeeded;iBlk>0;iBlk--) + { + vfat_t *VFAT = (vfat_t *)p; + uint8_t n; + + n = (iBlk-1) * 13; + memset(p, 0, sizeof(dir_t)); + p->attributes = DIR_ATT_LONG_NAME; + VFAT->sequenceNumber = iBlk | (iBlk == cVFATNeeded ? 0x40 : 0); + + uint16_t *pName = VFAT->name1; + + for(int8_t i=0;i<13;i++) + { + if (n+i > cbFilename) + *pName++ = 0xffff; + else + *pName++ = (uint16_t)Filename[n+i]; + if (i == 4) + pName = VFAT->name2; + else if (i == 10) + pName = VFAT->name3; + } + VFAT->checksum = checksum; + if (dirFile->write(p, sizeof(dir_t)) < 0) + goto fail; + dirFile->sync(); + } + // END WRITING LONG FILE NAME BLK + + // Start 8.3 file init + // initialize as empty file + memset(p, 0, sizeof(dir_t)); + + make83Name(newName, (uint8_t *)p->name, &tempPtr); + + p->attributes = bDir ? DIR_ATT_DIRECTORY : DIR_ATT_ARCHIVE; + + p->creationDate = FAT_DEFAULT_DATE; + p->creationTime = FAT_DEFAULT_TIME; + p->lastAccessDate = p->creationDate; + p->lastWriteDate = p->creationDate; + p->lastWriteTime = p->creationTime; + + if (dirFile->write(p, sizeof(dir_t)) < 0) + goto fail; + dirFile->sync(); + + memset(p, 0, sizeof(dir_t)); + + if (emptyFound) + p->name[0] = DIR_NAME_DELETED; + + for(int8_t i=0;i< cVFATFoundCur - cVFATNeeded;i++) + { + if (dirFile->write(p, sizeof(dir_t)) < 0) + goto fail; + dirFile->sync(); + } + return open(dirFile, (wIndexPos >> 5) + (cVFATNeeded), oflag & ~O_EXCL); + + fail: + return false; +} +//------------------------------------------------------------------------------ +/** Open a file by index. + * + * \param[in] dirFile An open SdFat instance for the directory. + * + * \param[in] index The \a index of the directory entry for the file to be + * opened. The value for \a index is (directory file position)/32. + * + * \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive + * OR of flags O_READ, O_WRITE, O_TRUNC, and O_SYNC. + * + * See open() by path for definition of flags. + * \return true for success or false for failure. + */ +bool SdBaseFile::open(SdBaseFile* dirFile, uint16_t index, uint8_t oflag) { + dir_t* p; + + vol_ = dirFile->vol_; + + // error if already open + if (isOpen() || !dirFile) { + DBG_FAIL_MACRO; + goto fail; + } + + // don't open existing file if O_EXCL - user call error + if (oflag & O_EXCL) { + DBG_FAIL_MACRO; + goto fail; + } + // seek to location of entry + if (!dirFile->seekSet(32 * index)) { + DBG_FAIL_MACRO; + goto fail; + } + // read entry into cache + p = dirFile->readDirCache(); + if (!p) { + DBG_FAIL_MACRO; + goto fail; + } + // error if empty slot or '.' or '..' + if (p->name[0] == DIR_NAME_FREE || + p->name[0] == DIR_NAME_DELETED || p->name[0] == '.') { + DBG_FAIL_MACRO; + goto fail; + } + // open cached entry + return openCachedEntry(index & 0XF, oflag); + + fail: + return false; +} +//------------------------------------------------------------------------------ +// open a cached directory entry. Assumes vol_ is initialized +bool SdBaseFile::openCachedEntry(uint8_t dirIndex, uint8_t oflag) { + // location of entry in cache + dir_t* p = &vol_->cacheAddress()->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)) { +// if (oflag & (O_WRITE | O_TRUNC)) { +// DBG_FAIL_MACRO; +// goto fail; +// } + } + // remember location of directory entry on SD + dirBlock_ = vol_->cacheBlockNumber(); + dirIndex_ = dirIndex; + + // copy first cluster number for directory fields + firstCluster_ = (uint32_t)p->firstClusterHigh << 16; + firstCluster_ |= p->firstClusterLow; + +#ifdef GLENN_DEBUG + Com::print("CATR:"); + Com::print(firstCluster_); + Com::print("-"); + Com::print(p->name[0]); + Com::println(); +#endif + + // make sure it is a normal file or subdirectory + if (DIR_IS_FILE(p)) { + fileSize_ = p->fileSize; + type_ = FAT_FILE_TYPE_NORMAL; + } else if (DIR_IS_SUBDIR(p)) { + if (!setDirSize()) { + fileSize_= 0; + } + type_ = FAT_FILE_TYPE_SUBDIR; + } else { + DBG_FAIL_MACRO; + goto fail; + } + // save open flags for read/write + flags_ = oflag & F_OFLAG; + + // set to start of file + curCluster_ = 0; + curPosition_ = 0; + if ((oflag & O_TRUNC) && !truncate(0)) { + DBG_FAIL_MACRO; + goto fail; + } + return oflag & O_AT_END ? seekEnd(0) : true; + + fail: + type_ = FAT_FILE_TYPE_CLOSED; + return false; +} +//------------------------------------------------------------------------------ +/** Open the next file or subdirectory in a directory. + * + * \param[in] dirFile An open SdFat instance for the directory containing the + * file to be opened. + * + * \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive + * OR of flags O_READ, O_WRITE, O_TRUNC, and O_SYNC. + * + * See open() by path for definition of flags. + * \return true for success or false for failure. + */ +bool SdBaseFile::openNext(SdBaseFile* dirFile, uint8_t oflag) { + dir_t* p; + uint8_t index; + + if (!dirFile) { + DBG_FAIL_MACRO; + goto fail; + } + // error if already open + if (isOpen()) { + DBG_FAIL_MACRO; + goto fail; + } + vol_ = dirFile->vol_; + + while (1) { + index = 0XF & (dirFile->curPosition_ >> 5); + + // read entry into cache + p = dirFile->readDirCache(); + if (!p) { + DBG_FAIL_MACRO; + goto fail; + } + // done if last entry + if (p->name[0] == DIR_NAME_FREE) { + DBG_FAIL_MACRO; + goto fail; + } + // skip empty slot or '.' or '..' + if (p->name[0] == DIR_NAME_DELETED || p->name[0] == '.') { + continue; + } + // must be file or dir + if (DIR_IS_FILE_OR_SUBDIR(p)) { + return openCachedEntry(index, oflag); + } + } + + fail: + return false; +} +//------------------------------------------------------------------------------ +/** Open a directory's parent directory. + * + * \param[in] dir Parent of this directory will be opened. Must not be root. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool SdBaseFile::openParent(SdBaseFile* dir) { + dir_t entry; + dir_t* p; + SdBaseFile file; + uint32_t c; + uint32_t cluster; + uint32_t lbn; + cache_t* pc; + // error if already open or dir is root or dir is not a directory + if (isOpen() || !dir || dir->isRoot() || !dir->isDir()) { + DBG_FAIL_MACRO; + goto fail; + } + vol_ = dir->vol_; + // position to '..' + if (!dir->seekSet(32)) { + DBG_FAIL_MACRO; + goto fail; + } + // read '..' entry + if (dir->read(&entry, sizeof(entry)) != 32) { + DBG_FAIL_MACRO; + goto fail; + } + // verify it is '..' + if (entry.name[0] != '.' || entry.name[1] != '.') { + DBG_FAIL_MACRO; + goto fail; + } + // start cluster for '..' + cluster = entry.firstClusterLow; + cluster |= (uint32_t)entry.firstClusterHigh << 16; + if (cluster == 0) return openRoot(vol_); + // start block for '..' + lbn = vol_->clusterStartBlock(cluster); + // first block of parent dir + pc = vol_->cacheFetch(lbn, SdVolume::CACHE_FOR_READ); + if (!pc) { + DBG_FAIL_MACRO; + goto fail; + } + p = &pc->dir[1]; + // verify name for '../..' + if (p->name[0] != '.' || p->name[1] != '.') { + DBG_FAIL_MACRO; + goto fail; + } + // '..' is pointer to first cluster of parent. open '../..' to find parent + if (p->firstClusterHigh == 0 && p->firstClusterLow == 0) { + if (!file.openRoot(dir->volume())) { + DBG_FAIL_MACRO; + goto fail; + } + } else { + if (!file.openCachedEntry(1, O_READ)) { + DBG_FAIL_MACRO; + goto fail; + } + } + // search for parent in '../..' + do { + if (file.readDir(&entry, NULL) != 32) { + DBG_FAIL_MACRO; + goto fail; + } + c = entry.firstClusterLow; + c |= (uint32_t)entry.firstClusterHigh << 16; + } while (c != cluster); + // open parent + return open(&file, file.curPosition()/32 - 1, O_READ); + + fail: + return false; +} +//------------------------------------------------------------------------------ +/** Open a volume's root directory. + * + * \param[in] vol The FAT volume containing the root directory to be opened. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include the file is already open, the FAT volume has + * not been initialized or it a FAT12 volume. + */ +bool SdBaseFile::openRoot(SdVolume* vol) { + // error if file is already open + if (isOpen()) { +#if defined(DEBUG_SD_ERROR) + Com::printErrorFLN(PSTR("Root already open")); +#endif + DBG_FAIL_MACRO; + goto fail; + } + vol_ = vol; + if (vol->fatType() == 16 || (FAT12_SUPPORT && vol->fatType() == 12)) { + type_ = FAT_FILE_TYPE_ROOT_FIXED; + firstCluster_ = 0; + fileSize_ = 32 * vol->rootDirEntryCount(); + } else if (vol->fatType() == 32) { + type_ = FAT_FILE_TYPE_ROOT32; + firstCluster_ = vol->rootDirStart(); + if (!setDirSize()) { + DBG_FAIL_MACRO; + goto fail; + } + } else { + // volume is not initialized, invalid, or FAT12 without support +#if defined(DEBUG_SD_ERROR) + Com::printErrorF(PSTR("volume is not initialized, invalid, or FAT12 without support, type:")); + Com::print((int)vol->fatType());Com::println(); +#endif + DBG_FAIL_MACRO; + goto fail; + } + // read only + flags_ = O_READ; + + // set to start of file + curCluster_ = 0; + curPosition_ = 0; + + // root has no directory entry + dirBlock_ = 0; + dirIndex_ = 0; + return true; + + fail: +#if defined(DEBUG_SD_ERROR) + Com::printErrorFLN(PSTR("SD open root dir failed")); +#endif + return false; +} +//------------------------------------------------------------------------------ +/** Return the next available byte without consuming it. + * + * \return The byte if no error and not at eof else -1; + */ +int SdBaseFile::peek() { + FatPos_t pos; + getpos(&pos); + int c = read(); + if (c >= 0) setpos(&pos); + return c; +} +//------------------------------------------------------------------------------ +/** %Print the name field of a directory entry in 8.3 format. + * \param[in] pr Print stream for output. + * \param[in] dir The directory structure containing the name. + * \param[in] width Blank fill name if length is less than \a width. + * \param[in] printSlash Print '/' after directory names if true. + */ +void SdBaseFile::printDirName(const dir_t& dir, + uint8_t width, bool printSlash) { + uint8_t w = 0; + for (uint8_t i = 0; i < 11; i++) { + if (dir.name[i] == ' ')continue; + if (i == 8) { + Com::print('.'); + w++; + } + Com::print(dir.name[i]); + w++; + } + if (DIR_IS_SUBDIR(&dir) && printSlash) { + Com::print('/'); + w++; + } + while (w < width) { + Com::print(' '); + w++; + } +} +//------------------------------------------------------------------------------ +// print uint8_t with width 2 +static void print2u(uint8_t v) { + if (v < 10) Com::print('0'); + Com::print(v); +} +//------------------------------------------------------------------------------ +/** Print a file's creation date and time + * + * \param[in] pr Print stream for output. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool SdBaseFile::printCreateDateTime() { + dir_t dir; + if (!dirEntry(&dir)) { + DBG_FAIL_MACRO; + goto fail; + } + printFatDate(dir.creationDate); + Com::print(' '); + printFatTime(dir.creationTime); + return true; + + fail: + return false; +} + +//------------------------------------------------------------------------------ +/** %Print a directory date field. + * + * Format is yyyy-mm-dd. + * + * \param[in] pr Print stream for output. + * \param[in] fatDate The date field from a directory entry. + */ +void SdBaseFile::printFatDate(uint16_t fatDate) { + Com::print((int)FAT_YEAR(fatDate)); + Com::print('-'); + print2u(FAT_MONTH(fatDate)); + Com::print('-'); + print2u(FAT_DAY(fatDate)); +} + +//------------------------------------------------------------------------------ +/** %Print a directory time field. + * + * Format is hh:mm:ss. + * + * \param[in] pr Print stream for output. + * \param[in] fatTime The time field from a directory entry. + */ +void SdBaseFile::printFatTime( uint16_t fatTime) { + print2u(FAT_HOUR(fatTime)); + Com::print(':'); + print2u(FAT_MINUTE(fatTime)); + Com::print(':'); + print2u(FAT_SECOND(fatTime)); +} +//------------------------------------------------------------------------------ +/** Print a file's modify date and time + * + * \param[in] pr Print stream for output. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool SdBaseFile::printModifyDateTime() { + dir_t dir; + if (!dirEntry(&dir)) { + DBG_FAIL_MACRO; + goto fail; + } + printFatDate(dir.lastWriteDate); + Com::print(' '); + printFatTime(dir.lastWriteTime); + return true; + + fail: + return false; +} +/** Template for SdBaseFile::printField() */ + +template + +static int printFieldT(SdBaseFile* file, char sign, Type value, char term) { + char buf[3*sizeof(Type) + 3]; + char* str = &buf[sizeof(buf)]; + + if (term) { + *--str = term; + if (term == '\n') { + *--str = '\r'; + } + } + do { + Type m = value; + value /= 10; + *--str = '0' + m - 10*value; + } while (value); + if (sign) { + *--str = sign; + } + return file->write(str, &buf[sizeof(buf)] - str); +} +//------------------------------------------------------------------------------ +/** Print a number followed by a field terminator. + * \param[in] value The number to be printed. + * \param[in] term The field terminator. Use '\\n' for CR LF. + * \return The number of bytes written or -1 if an error occurs. + */ +int SdBaseFile::printField(uint16_t value, char term) { + return printFieldT(this, 0, value, term); +} +//------------------------------------------------------------------------------ +/** Print a number followed by a field terminator. + * \param[in] value The number to be printed. + * \param[in] term The field terminator. Use '\\n' for CR LF. + * \return The number of bytes written or -1 if an error occurs. + */ +int SdBaseFile::printField(int16_t value, char term) { + char sign = 0; + if (value < 0) { + sign = '-'; + value = -value; + } + return printFieldT(this, sign, (uint16_t)value, term); +} +//------------------------------------------------------------------------------ +/** Print a number followed by a field terminator. + * \param[in] value The number to be printed. + * \param[in] term The field terminator. Use '\\n' for CR LF. + * \return The number of bytes written or -1 if an error occurs. + */ +int SdBaseFile::printField(uint32_t value, char term) { + return printFieldT(this, 0, value, term); +} +//------------------------------------------------------------------------------ +/** Print a number followed by a field terminator. + * \param[in] value The number to be printed. + * \param[in] term The field terminator. Use '\\n' for CR LF. + * \return The number of bytes written or -1 if an error occurs. + */ +int SdBaseFile::printField(int32_t value, char term) { + char sign = 0; + if (value < 0) { + sign = '-'; + value = -value; + } + return printFieldT(this, sign, (uint32_t)value, term); +} + +//----------------------------------------------------------------------------- +//------------------------------------------------------------------------------ +/** Print a file's name + * + * \param[in] pr Print stream for output. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool SdBaseFile::printName() { + char name[13]; + if (!getFilename(name)) { + DBG_FAIL_MACRO; + goto fail; + } + Com::print(name); + return true; + fail: + return false; +} +//------------------------------------------------------------------------------ +/** Read the next byte from a file. + * + * \return For success read returns the next byte in the file as an int. + * If an error occurs or end of file is reached -1 is returned. + */ +int16_t SdBaseFile::read() { + uint8_t b; + return read(&b, 1) == 1 ? b : -1; +} +//------------------------------------------------------------------------------ +/** Read data from a file starting at the current position. + * + * \param[out] buf Pointer to the location that will receive the data. + * + * \param[in] nbyte Maximum number of bytes to read. + * + * \return For success read() returns the number of bytes read. + * A value less than \a nbyte, including zero, will be returned + * if end of file is reached. + * If an error occurs, read() returns -1. Possible errors include + * read() called before a file has been opened, corrupt file system + * or an I/O error occurred. + */ +int SdBaseFile::read(void* buf, size_t nbyte) { + uint8_t blockOfCluster; + uint8_t* dst = reinterpret_cast(buf); + uint16_t offset; + size_t toRead; + uint32_t block; // raw device block number + cache_t* pc; + + // error if not open or write only + if (!isOpen() || !(flags_ & O_READ)) { + DBG_FAIL_MACRO; + goto fail; + } + // max bytes left in file + if (nbyte >= (fileSize_ - curPosition_)) { + nbyte = fileSize_ - curPosition_; + } + // amount left to read + toRead = nbyte; + while (toRead > 0) { + size_t n; + offset = curPosition_ & 0X1FF; // offset in block + blockOfCluster = vol_->blockOfCluster(curPosition_); + if (type_ == FAT_FILE_TYPE_ROOT_FIXED) { + block = vol_->rootDirStart() + (curPosition_ >> 9); +#ifdef GLENN_DEBUG + Com::print("RBL:"); + Com::print(block); + Com::println(); +#endif + } else { + if (offset == 0 && blockOfCluster == 0) { + // start of new cluster + if (curPosition_ == 0) { + // use first cluster in file + curCluster_ = firstCluster_; + } else { + // get next cluster from FAT + if (!vol_->fatGet(curCluster_, &curCluster_)) { + DBG_FAIL_MACRO; + goto fail; + } + } + } + block = vol_->clusterStartBlock(curCluster_) + blockOfCluster; + } + if (offset != 0 || toRead < 512 || block == vol_->cacheBlockNumber()) { + // amount to be read from current block + n = 512 - offset; + if (n > toRead) n = toRead; + // read block to cache and copy data to caller + pc = vol_->cacheFetch(block, SdVolume::CACHE_FOR_READ); + if (!pc) { + DBG_FAIL_MACRO; + goto fail; + } + uint8_t* src = pc->data + offset; + memcpy(dst, src, n); + } else if (!USE_MULTI_BLOCK_SD_IO || toRead < 1024) { + // read single block + n = 512; + if (!vol_->readBlock(block, dst)) { + DBG_FAIL_MACRO; + goto fail; + } + } else { + uint8_t nb = toRead >> 9; + if (type_ != FAT_FILE_TYPE_ROOT_FIXED) { + uint8_t mb = vol_->blocksPerCluster() - blockOfCluster; + if (mb < nb) nb = mb; + } + n = 512*nb; + if (vol_->cacheBlockNumber() <= block + && block < (vol_->cacheBlockNumber() + nb)) { + // flush cache if a block is in the cache + if (!vol_->cacheSync()) { + DBG_FAIL_MACRO; + goto fail; + } + } + if (!vol_->sdCard()->readStart(block)) { + DBG_FAIL_MACRO; + goto fail; + } + for (uint8_t b = 0; b < nb; b++) { + if (!vol_->sdCard()->readData(dst + b*512)) { + DBG_FAIL_MACRO; + goto fail; + } + } + if (!vol_->sdCard()->readStop()) { + DBG_FAIL_MACRO; + goto fail; + } + } + dst += n; + curPosition_ += n; + toRead -= n; + } + return nbyte; + + fail: + return -1; +} + + +//------------------------------------------------------------------------------ +/** Read the next directory entry from a directory file with the long filename + * + * \param[out] dir The dir_t struct that will receive the data. + * \param[out] longFiename The long filename associated with the 8.3 name + * + * \return For success getLongFilename() returns a pointer to dir_t + * A value of zero will be returned if end of file is reached. + */ + + +dir_t *SdBaseFile::getLongFilename(dir_t *dir, char *longFilename, int8_t cVFATNeeded, uint32_t *pwIndexPos) +{ + int16_t n; + uint8_t bLastPart = true; + uint8_t checksum; + + if (longFilename != NULL) + *longFilename = 0; + + while (1) + { + HAL::pingWatchdog(); +#ifdef GLENN_DEBUG + Commands::checkFreeMemory(); + Commands::writeLowestFreeRAM(); +#endif + if (!(dir = readDirCache())) + { + return NULL; + } + + if (dir->name[0] == DIR_NAME_FREE) + return NULL; + + if (dir->name[0] == DIR_NAME_0XE5 || dir->name[0] == DIR_NAME_DELETED) + { + bLastPart = true; + if (longFilename != NULL) + *longFilename = 0; + continue; + } + + if (DIR_IS_LONG_NAME(dir)) + { + if (longFilename != NULL) + { + vfat_t *VFAT = (vfat_t*)dir; + int8_t nSeq = VFAT->sequenceNumber & 0x1F; + + // Sanity check the VFAT entry. The first cluster is always set to zero. And the sequence number should be higher then 0 + if (VFAT->firstClusterLow == 0 && nSeq > 0 && nSeq <= MAX_VFAT_ENTRIES) + { + n = (nSeq - 1) * 13; + + longFilename[n+0] = (char)VFAT->name1[0]; + + longFilename[n+1] = (char)VFAT->name1[1]; + longFilename[n+2] = (char)VFAT->name1[2]; + longFilename[n+3] = (char)VFAT->name1[3]; + longFilename[n+4] = (char)VFAT->name1[4]; + longFilename[n+5] = (char)VFAT->name2[0]; + longFilename[n+6] = (char)VFAT->name2[1]; + longFilename[n+7] = (char)VFAT->name2[2]; + longFilename[n+8] = (char)VFAT->name2[3]; + longFilename[n+9] = (char)VFAT->name2[4]; + longFilename[n+10] = (char)VFAT->name2[5]; + longFilename[n+11] = (char)VFAT->name3[0]; + longFilename[n+12] = (char)VFAT->name3[1]; + + if (bLastPart) + { + checksum = VFAT->checksum; + longFilename[n+13] = 0; + } + bLastPart = false; + } + } + } + else + { + if ((dir->attributes & DIR_ATT_HIDDEN || dir->attributes & DIR_ATT_SYSTEM) || (dir->name[0] == '.' && dir->name[1] != '.')) + { + bLastPart = true; + if (longFilename != NULL) + *longFilename = 0; + continue; + } + if (DIR_IS_FILE(dir) || DIR_IS_SUBDIR(dir)) + { + if (longFilename && (bLastPart || checksum != lfn_checksum(dir->name))) + { + sd.createFilename(longFilename, *dir); + } + return dir; + } + } + } +#ifdef GLENN_DEBUG + Commands::checkFreeMemory(); + Commands::writeLowestFreeRAM(); +#endif + return dir; +} + +bool SdBaseFile::findSpace(dir_t *dir, int8_t cVFATNeeded, int8_t *pcVFATFound, uint32_t *pwIndexPos) +{ + //int16_t n; // unused + int8_t cVFATFound = 0; + // if not a directory file or miss-positioned return an error + if (!isDir()) return -1; + + rewind(); + + while (1) { + HAL::pingWatchdog(); + dir = readDirCache(); + if (!dir) return false; + // last entry if DIR_NAME_FREE + if (dir->name[0] == DIR_NAME_FREE) return 0; + // skip empty entries and entry for . and .. +#ifdef GLENN_DEBUG + Com::print("Attr:"); + Com::print((long)dir->attributes); + Com::print(" "); + Com::print((long)dir->name[0]); + Com::println(); +#endif + + if (dir->name[0] == DIR_NAME_0XE5 || dir->name[0] == DIR_NAME_DELETED) + { + if (DIR_IS_LONG_NAME(dir)) + { + //vfat_t *VFAT = (vfat_t*)dir; // unused + cVFATFound++; + } + else + { +#ifdef GLENN_DEBUG + Com::print("Need: "); + Com::print(cVFATNeeded); + Com::print(" Got: "); + Com::print(cVFATFound); + Com::print(" "); + Com::println(); +#endif + if (pwIndexPos != NULL && cVFATNeeded > 0 && cVFATFound >= cVFATNeeded && *pwIndexPos == 0) + { + *pwIndexPos = curPosition_-sizeof(dir_t)-(cVFATFound * sizeof(dir_t)); + *pcVFATFound = cVFATFound; + return true; + } + cVFATFound++; + } + } + else + { + cVFATFound = 0; + } + } +} + +//------------------------------------------------------------------------------ +/** Read the next directory entry from a directory file. + * + * \param[out] dir The dir_t struct that will receive the data. + * + * \return For success readDir() returns the number of bytes read. + * A value of zero will be returned if end of file is reached. + * If an error occurs, readDir() returns -1. Possible errors include + * readDir() called before a directory has been opened, this is not + * a directory file or an I/O error occurred. + */ + +int8_t SdBaseFile::readDir(dir_t* dir, char* longFilename) { + int16_t n; + // if not a directory file or miss-positioned return an error + if (!isDir() || (0X1F & curPosition_)) return -1; + + while (1) { + n = read(dir, sizeof(dir_t)); + if (n != sizeof(dir_t)) return n == 0 ? 0 : -1; + // last entry if DIR_NAME_FREE + if (dir->name[0] == DIR_NAME_FREE) return 0; + // skip empty entries and entry for . and .. + if (dir->name[0] == DIR_NAME_DELETED || dir->name[0] == '.') continue; + // return if normal file or subdirectory + if (DIR_IS_FILE_OR_SUBDIR(dir)) return n; + } +} +//------------------------------------------------------------------------------ +// Read next directory entry into the cache +// Assumes file is correctly positioned +dir_t* SdBaseFile::readDirCache() { + uint8_t i; + // error if not directory + if (!isDir()) { + DBG_FAIL_MACRO; + goto fail; + } + // index of entry in cache + i = (curPosition_ >> 5) & 0XF; + // use read to locate and cache block + if (read() < 0) { + DBG_FAIL_MACRO; + goto fail; + } + // advance to next entry + curPosition_ += 31; + + // return pointer to entry + return vol_->cacheAddress()->dir + i; + + fail: + return 0; +} +//------------------------------------------------------------------------------ +/** Remove a file. + * + * The directory entry and all data for the file are deleted. + * + * \note This function should not be used to delete the 8.3 version of a + * file that has a long name. For example if a file has the long name + * "New Text Document.txt" you should not delete the 8.3 name "NEWTEX~1.TXT". + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include the file read-only, is a directory, + * or an I/O error occurred. + */ +bool SdBaseFile::remove() { + dir_t* d; + // free any clusters - will fail if read-only or directory + if (!truncate(0)) { + DBG_FAIL_MACRO; + goto fail; + } + // cache directory entry + d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); + if (!d) { + DBG_FAIL_MACRO; + goto fail; + } + // mark entry deleted + d->name[0] = DIR_NAME_DELETED; + + // set this file closed + type_ = FAT_FILE_TYPE_CLOSED; + + // write entry to SD + return vol_->cacheSync(); + return true; + + fail: + return false; +} +//------------------------------------------------------------------------------ +/** Remove a file. + * + * The directory entry and all data for the file are deleted. + * + * \param[in] dirFile The directory that contains the file. + * \param[in] path Path for the file to be removed. + * + * \note This function should not be used to delete the 8.3 version of a + * file that has a long name. For example if a file has the long name + * "New Text Document.txt" you should not delete the 8.3 name "NEWTEX~1.TXT". + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include the file is a directory, is read only, + * \a dirFile is not a directory, \a path is not found + * or an I/O error occurred. + */ +bool SdBaseFile::remove(SdBaseFile* dirFile, const char* path) { + SdBaseFile file; + if (!file.open(dirFile, path, O_WRITE)) { + DBG_FAIL_MACRO; + goto fail; + } + return file.remove(); + + fail: + return false; +} +//------------------------------------------------------------------------------ +/** Rename a file or subdirectory. + * + * \param[in] dirFile Directory for the new path. + * \param[in] newPath New path name for the file/directory. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include \a dirFile is not open or is not a directory + * file, newPath is invalid or already exists, or an I/O error occurs. + */ +bool SdBaseFile::rename(SdBaseFile* dirFile, const char* newPath) { + dir_t entry; + uint32_t dirCluster = 0; + SdBaseFile file; + cache_t* pc; + dir_t* d; + + // must be an open file or subdirectory + if (!(isFile() || isSubDir())) { + DBG_FAIL_MACRO; + goto fail; + } + // can't move file + if (vol_ != dirFile->vol_) { + DBG_FAIL_MACRO; + goto fail; + } + // sync() and cache directory entry + sync(); + d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); + if (!d) { + DBG_FAIL_MACRO; + goto fail; + } + // save directory entry + memcpy(&entry, d, sizeof(entry)); + + // mark entry deleted + d->name[0] = DIR_NAME_DELETED; + + // make directory entry for new path + if (isFile()) { + if (!file.open(dirFile, newPath, O_CREAT | O_EXCL | O_WRITE)) { + goto restore; + } + } else { + // don't create missing path prefix components + if (!file.mkdir(dirFile, newPath, false)) { + goto restore; + } + // save cluster containing new dot dot + dirCluster = file.firstCluster_; + } + // change to new directory entry + dirBlock_ = file.dirBlock_; + dirIndex_ = file.dirIndex_; + + // mark closed to avoid possible destructor close call + file.type_ = FAT_FILE_TYPE_CLOSED; + + // cache new directory entry + d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); + if (!d) { + DBG_FAIL_MACRO; + goto fail; + } + // copy all but name field to new directory entry + memcpy(&d->attributes, &entry.attributes, sizeof(entry) - sizeof(d->name)); + + // update dot dot if directory + if (dirCluster) { + // get new dot dot + uint32_t block = vol_->clusterStartBlock(dirCluster); + pc = vol_->cacheFetch(block, SdVolume::CACHE_FOR_READ); + if (!pc) { + DBG_FAIL_MACRO; + goto fail; + } + memcpy(&entry, &pc->dir[1], sizeof(entry)); + + // free unused cluster + if (!vol_->freeChain(dirCluster)) { + DBG_FAIL_MACRO; + goto fail; + } + // store new dot dot + block = vol_->clusterStartBlock(firstCluster_); + pc = vol_->cacheFetch(block, SdVolume::CACHE_FOR_WRITE); + if (!pc) { + DBG_FAIL_MACRO; + goto fail; + } + memcpy(&pc->dir[1], &entry, sizeof(entry)); + } + return vol_->cacheSync(); + + restore: + d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); + if (!d) { + DBG_FAIL_MACRO; + goto fail; + } + // restore entry + d->name[0] = entry.name[0]; + vol_->cacheSync(); + + fail: + return false; +} +//------------------------------------------------------------------------------ +/** Remove a directory file. + * + * The directory file will be removed only if it is empty and is not the + * root directory. rmdir() follows DOS and Windows and ignores the + * read-only attribute for the directory. + * + * \note This function should not be used to delete the 8.3 version of a + * directory that has a long name. For example if a directory has the + * long name "New folder" you should not delete the 8.3 name "NEWFOL~1". + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include the file is not a directory, is the root + * directory, is not empty, or an I/O error occurred. + */ +bool SdBaseFile::rmdir() { + // must be open subdirectory + if (!isSubDir()) { + DBG_FAIL_MACRO; + goto fail; + } + rewind(); + + // make sure directory is empty + while (curPosition_ < fileSize_) { + dir_t* p = readDirCache(); + if (!p) { + DBG_FAIL_MACRO; + goto fail; + } + // done if past last used entry + if (p->name[0] == DIR_NAME_FREE) break; + // skip empty slot, '.' or '..' + if (p->name[0] == DIR_NAME_DELETED || p->name[0] == '.') continue; + // error not empty + if (DIR_IS_FILE_OR_SUBDIR(p)) { + DBG_FAIL_MACRO; + goto fail; + } + } + // convert empty directory to normal file for remove + type_ = FAT_FILE_TYPE_NORMAL; + flags_ |= O_WRITE; + return remove(); + + fail: + return false; +} +//------------------------------------------------------------------------------ +/** Recursively delete a directory and all contained files. + * + * This is like the Unix/Linux 'rm -rf *' if called with the root directory + * hence the name. + * + * Warning - This will remove all contents of the directory including + * subdirectories. The directory will then be removed if it is not root. + * The read-only attribute for files will be ignored. + * + * \note This function should not be used to delete the 8.3 version of + * a directory that has a long name. See remove() and rmdir(). + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool SdBaseFile::rmRfStar() { + uint16_t index; + SdBaseFile f; + rewind(); + while (curPosition_ < fileSize_) { + // remember position + index = curPosition_/32; + + dir_t* p = readDirCache(); + if (!p) { + DBG_FAIL_MACRO; + goto fail; + } + // done if past last entry + if (p->name[0] == DIR_NAME_FREE) break; + + // skip empty slot or '.' or '..' + if (p->name[0] == DIR_NAME_DELETED || p->name[0] == '.') continue; + + // skip if part of long file name or volume label in root + if (!DIR_IS_FILE_OR_SUBDIR(p)) continue; + + if (!f.open(this, index, O_READ)) { + DBG_FAIL_MACRO; + goto fail; + } + if (f.isSubDir()) { + // recursively delete + if (!f.rmRfStar()) { + DBG_FAIL_MACRO; + goto fail; + } + } else { + // ignore read-only + f.flags_ |= O_WRITE; + if (!f.remove()) { + DBG_FAIL_MACRO; + goto fail; + } + } + // position to next entry if required + if (curPosition_ != (32UL*(index + 1))) { + if (!seekSet(32UL*(index + 1))) { + DBG_FAIL_MACRO; + goto fail; + } + } + } + // don't try to delete root + if (!isRoot()) { + if (!rmdir()) { + DBG_FAIL_MACRO; + goto fail; + } + } + return true; + + fail: + return false; +} +//------------------------------------------------------------------------------ +/** Create a file object and open it in the current working directory. + * + * \param[in] path A path with a valid 8.3 DOS name for a file to be opened. + * + * \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive + * OR of open flags. see SdBaseFile::open(SdBaseFile*, const char*, uint8_t). + */ +SdBaseFile::SdBaseFile(const char* path, uint8_t oflag) { + type_ = FAT_FILE_TYPE_CLOSED; + writeError = false; + open(path, oflag); +} +//------------------------------------------------------------------------------ +/** Sets a file's position. + * + * \param[in] pos The new position in bytes from the beginning of the file. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool SdBaseFile::seekSet(uint32_t pos) { + uint32_t nCur; + uint32_t nNew; + // error if file not open or seek past end of file + if (!isOpen() || pos > fileSize_) { + DBG_FAIL_MACRO; + goto fail; + } + if (type_ == FAT_FILE_TYPE_ROOT_FIXED) { + curPosition_ = pos; + curCluster_ = 0; + goto done; + } + if (pos == 0) { + // set position to start of file + curCluster_ = 0; + curPosition_ = 0; + goto done; + } + // calculate cluster index for cur and new position + nCur = (curPosition_ - 1) >> (vol_->clusterSizeShift_ + 9); + nNew = (pos - 1) >> (vol_->clusterSizeShift_ + 9); + + if (nNew < nCur || curPosition_ == 0) { + // must follow chain from first cluster + curCluster_ = firstCluster_; + } else { + // advance from curPosition + nNew -= nCur; + } + while (nNew--) { + if (!vol_->fatGet(curCluster_, &curCluster_)) { + DBG_FAIL_MACRO; + goto fail; + } + } + curPosition_ = pos; + + done: + return true; + + fail: + return false; +} +// set fileSize_ for a directory +bool SdBaseFile::setDirSize() { + uint16_t s = 0; + uint32_t cluster = firstCluster_; + do { + if (!vol_->fatGet(cluster, &cluster)) { + DBG_FAIL_MACRO; + goto fail; + } + s += vol_->blocksPerCluster(); + // max size if a directory file is 4096 blocks + if (s >= 4096) { + DBG_FAIL_MACRO; + goto fail; + } + } while (!vol_->isEOC(cluster)); + fileSize_ = 512L*s; + return true; + + fail: + return false; +} + +//----------------------------------------------------------------------------- +//------------------------------------------------------------------------------ +void SdBaseFile::setpos(FatPos_t* pos) { + curPosition_ = pos->position; + curCluster_ = pos->cluster; +} +//------------------------------------------------------------------------------ +/** The sync() call causes all modified data and directory fields + * to be written to the storage device. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include a call to sync() before a file has been + * opened or an I/O error. + */ +bool SdBaseFile::sync() { + // only allow open files and directories + if (!isOpen()) { + DBG_FAIL_MACRO; + goto fail; + } + if (flags_ & F_FILE_DIR_DIRTY) { + dir_t* d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); + // check for deleted by another open file object + if (!d || d->name[0] == DIR_NAME_DELETED) { + DBG_FAIL_MACRO; + goto fail; + } + // do not set filesize for dir files + if (!isDir()) d->fileSize = fileSize_; + + // update first cluster fields + d->firstClusterLow = firstCluster_ & 0XFFFF; + d->firstClusterHigh = firstCluster_ >> 16; + + // set modify time if user supplied a callback date/time function + if (dateTime_) { + dateTime_(&d->lastWriteDate, &d->lastWriteTime); + d->lastAccessDate = d->lastWriteDate; + } + // clear directory dirty + flags_ &= ~F_FILE_DIR_DIRTY; + } + return vol_->cacheSync(); + + fail: + writeError = true; + return false; +} +//------------------------------------------------------------------------------ +/** Copy a file's timestamps + * + * \param[in] file File to copy timestamps from. + * + * \note + * Modify and access timestamps may be overwritten if a date time callback + * function has been set by dateTimeCallback(). + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool SdBaseFile::timestamp(SdBaseFile* file) { + dir_t* d; + dir_t dir; + + // get timestamps + if (!file->dirEntry(&dir)) { + DBG_FAIL_MACRO; + goto fail; + } + // update directory fields + if (!sync()) { + DBG_FAIL_MACRO; + goto fail; + } + d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); + if (!d) { + DBG_FAIL_MACRO; + goto fail; + } + // copy timestamps + d->lastAccessDate = dir.lastAccessDate; + d->creationDate = dir.creationDate; + d->creationTime = dir.creationTime; + d->creationTimeTenths = dir.creationTimeTenths; + d->lastWriteDate = dir.lastWriteDate; + d->lastWriteTime = dir.lastWriteTime; + + // write back entry + return vol_->cacheSync(); + + fail: + return false; +} +//------------------------------------------------------------------------------ +/** Set a file's timestamps in its directory entry. + * + * \param[in] flags Values for \a flags are constructed by a bitwise-inclusive + * OR of flags from the following list + * + * T_ACCESS - Set the file's last access date. + * + * T_CREATE - Set the file's creation date and time. + * + * T_WRITE - Set the file's last write/modification date and time. + * + * \param[in] year Valid range 1980 - 2107 inclusive. + * + * \param[in] month Valid range 1 - 12 inclusive. + * + * \param[in] day Valid range 1 - 31 inclusive. + * + * \param[in] hour Valid range 0 - 23 inclusive. + * + * \param[in] minute Valid range 0 - 59 inclusive. + * + * \param[in] second Valid range 0 - 59 inclusive + * + * \note It is possible to set an invalid date since there is no check for + * the number of days in a month. + * + * \note + * Modify and access timestamps may be overwritten if a date time callback + * function has been set by dateTimeCallback(). + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool SdBaseFile::timestamp(uint8_t flags, uint16_t year, uint8_t month, + uint8_t day, uint8_t hour, uint8_t minute, uint8_t second) { + uint16_t dirDate; + uint16_t dirTime; + dir_t* d; + + if (!isOpen() + || year < 1980 + || year > 2107 + || month < 1 + || month > 12 + || day < 1 + || day > 31 + || hour > 23 + || minute > 59 + || second > 59) { + DBG_FAIL_MACRO; + goto fail; + } + // update directory entry + if (!sync()) { + DBG_FAIL_MACRO; + goto fail; + } + d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); + if (!d) { + DBG_FAIL_MACRO; + goto fail; + } + dirDate = FAT_DATE(year, month, day); + dirTime = FAT_TIME(hour, minute, second); + if (flags & T_ACCESS) { + d->lastAccessDate = dirDate; + } + if (flags & T_CREATE) { + d->creationDate = dirDate; + d->creationTime = dirTime; + // seems to be units of 1/100 second not 1/10 as Microsoft states + d->creationTimeTenths = second & 1 ? 100 : 0; + } + if (flags & T_WRITE) { + d->lastWriteDate = dirDate; + d->lastWriteTime = dirTime; + } + return vol_->cacheSync(); + + fail: + return false; +} +//------------------------------------------------------------------------------ +/** Truncate a file to a specified length. The current file position + * will be maintained if it is less than or equal to \a length otherwise + * it will be set to end of file. + * + * \param[in] length The desired length for the file. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + * Reasons for failure include file is read only, file is a directory, + * \a length is greater than the current file size or an I/O error occurs. + */ +bool SdBaseFile::truncate(uint32_t length) { + uint32_t newPos; + // error if not a normal file or read-only + if (!isFile() || !(flags_ & O_WRITE)) { + DBG_FAIL_MACRO; + goto fail; + } + // error if length is greater than current size + if (length > fileSize_) { + DBG_FAIL_MACRO; + goto fail; + } + // fileSize and length are zero - nothing to do + if (fileSize_ == 0) return true; + + // remember position for seek after truncation + newPos = curPosition_ > length ? length : curPosition_; + + // position to last cluster in truncated file + if (!seekSet(length)) { + DBG_FAIL_MACRO; + goto fail; + } + if (length == 0) { + // free all clusters + if (!vol_->freeChain(firstCluster_)) { + DBG_FAIL_MACRO; + goto fail; + } + firstCluster_ = 0; + } else { + uint32_t toFree; + if (!vol_->fatGet(curCluster_, &toFree)) { + DBG_FAIL_MACRO; + goto fail; + } + if (!vol_->isEOC(toFree)) { + // free extra clusters + if (!vol_->freeChain(toFree)) { + DBG_FAIL_MACRO; + goto fail; + } + // current cluster is end of chain + if (!vol_->fatPutEOC(curCluster_)) { + DBG_FAIL_MACRO; + goto fail; + } + } + } + fileSize_ = length; + + // need to update directory entry + flags_ |= F_FILE_DIR_DIRTY; + + if (!sync()) { + DBG_FAIL_MACRO; + goto fail; + } + // set file to correct position + return seekSet(newPos); + + fail: + return false; +} +//------------------------------------------------------------------------------ +/** Write data to an open file. + * + * \note Data is moved to the cache but may not be written to the + * storage device until sync() is called. + * + * \param[in] buf Pointer to the location of the data to be written. + * + * \param[in] nbyte Number of bytes to write. + * + * \return For success write() returns the number of bytes written, always + * \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. + * + */ +int SdBaseFile::write(const void* buf, size_t nbyte) { + // convert void* to uint8_t* - must be before goto statements + const uint8_t* src = reinterpret_cast(buf); + cache_t* pc; + uint8_t cacheOption; + // number of bytes left to write - must be before goto statements + size_t nToWrite = nbyte; + size_t n; + +#ifdef GLENN_DEBUG + Com::print("Cur Pos:"); + Com::print(curPosition_); + Com::println(); +#endif + + // error if not a normal file or is read-only + if (/*!isFile() || */!(flags_ & O_WRITE)) { + DBG_FAIL_MACRO; + goto fail; + } + + // seek to end of file if append flag + if ((flags_ & O_APPEND) && curPosition_ != fileSize_) { + if (!seekEnd()) { + DBG_FAIL_MACRO; + goto fail; + } + } + + while (nToWrite) { + uint8_t blockOfCluster = vol_->blockOfCluster(curPosition_); + uint16_t blockOffset = curPosition_ & 0X1FF; + +#ifdef GLENN_DEBUG + Com::print("BC"); + Com::print((long)blockOfCluster); + Com::print("-"); + Com::print((long)blockOffset); + Com::print("-"); + Com::print((long)curCluster_); + Com::print("-"); + Com::print((long)firstCluster_); + Com::print("-"); + Com::print((long)vol_->blocksPerCluster_); + Com::println(); +#endif + + if (blockOfCluster == 0 && blockOffset == 0) { + // start of new cluster + if (curCluster_ != 0) { + uint32_t next; + if (!vol_->fatGet(curCluster_, &next)) { + DBG_FAIL_MACRO; + goto fail; + } + if (vol_->isEOC(next)) { + // add cluster if at end of chain + if (!addCluster()) { + DBG_FAIL_MACRO; + goto fail; + } + } else { + curCluster_ = next; + } + } else { + if (firstCluster_ == 0) { + // allocate first cluster of file + if (!addCluster()) { + DBG_FAIL_MACRO; + goto fail; + } + } else { + curCluster_ = firstCluster_; + } + } + } + // block for data write + uint32_t block = type_ == FAT_FILE_TYPE_ROOT_FIXED ? vol_->rootDirStart() + (curPosition_ >> 9) : vol_->clusterStartBlock(curCluster_) + blockOfCluster; + + if (blockOffset != 0 || nToWrite < 512) { + // partial block - must use cache + // max space in block + n = 512 - blockOffset; + // lesser of space and amount to write + if (n > nToWrite) n = nToWrite; + + if (blockOffset == 0 && curPosition_ >= fileSize_) { + // start of new block don't need to read into cache + cacheOption = SdVolume::CACHE_RESERVE_FOR_WRITE; + } else { + // rewrite part of block + cacheOption = SdVolume::CACHE_FOR_WRITE; + } +#ifdef GLENN_DEBUG + Com::print("BL:"); + Com::print(block); + Com::println(); +#endif + pc = vol_->cacheFetch(block, cacheOption); + if (!pc) { + DBG_FAIL_MACRO; + goto fail; + } + uint8_t* dst = pc->data + blockOffset; + memcpy(dst, src, n); + if (512 == (n + blockOffset)) { + if (!vol_->cacheWriteData()) { + DBG_FAIL_MACRO; + goto fail; + } + } + } else if (!USE_MULTI_BLOCK_SD_IO || nToWrite < 1024) { + // use single block write command + n = 512; + if (vol_->cacheBlockNumber() == block) { + vol_->cacheInvalidate(); + } + if (!vol_->writeBlock(block, src)) { + DBG_FAIL_MACRO; + goto fail; + } + } else { + // use multiple block write command + uint8_t maxBlocks = vol_->blocksPerCluster() - blockOfCluster; + uint8_t nBlock = nToWrite >> 9; + if (nBlock > maxBlocks) nBlock = maxBlocks; + + n = 512*nBlock; + if (!vol_->sdCard()->writeStart(block, nBlock)) { + DBG_FAIL_MACRO; + goto fail; + } + for (uint8_t b = 0; b < nBlock; b++) { + // invalidate cache if block is in cache + if ((block + b) == vol_->cacheBlockNumber()) { + vol_->cacheInvalidate(); + } + if (!vol_->sdCard()->writeData(src + 512*b)) { + DBG_FAIL_MACRO; + goto fail; + } + } + if (!vol_->sdCard()->writeStop()) { + DBG_FAIL_MACRO; + goto fail; + } + } + curPosition_ += n; + src += n; + nToWrite -= n; + } +#ifdef GLENN_DEBUG + Com::print("Cur Pos:"); + Com::print(curPosition_); + Com::println(); +#endif + + if (curPosition_ > fileSize_) { + // update fileSize and insure sync will update dir entry + fileSize_ = curPosition_; + flags_ |= F_FILE_DIR_DIRTY; + } else if (dateTime_ && nbyte) { + // insure sync will update modified date and time + flags_ |= F_FILE_DIR_DIRTY; + } + + if (flags_ & O_SYNC) { + if (!sync()) { + DBG_FAIL_MACRO; + goto fail; + } + } + return nbyte; + + fail: + // return for write error + writeError = true; + return -1; +} +//------------------------------------------------------------------------------ +// suppress cpplint warnings with NOLINT comment +#if ALLOW_DEPRECATED_FUNCTIONS && !defined(DOXYGEN) +void (*SdBaseFile::oldDateTime_)(uint16_t& date, uint16_t& time) = 0; // NOLINT +#endif // ALLOW_DEPRECATED_FUNCTIONS + +// ============== Sd2Card.cpp ============= + +//============================================================================== +// debug trace macro +#define SD_TRACE(m, b) +// #define SD_TRACE(m, b) Serial.print(m);Serial.println(b); +// SPI functions +#ifndef SOFTWARE_SPI +// functions for hardware SPI +//------------------------------------------------------------------------------ +// make sure SPCR rate is in expected bits +#if (SPR0 != 0 || SPR1 != 1) +#error unexpected SPCR bits +#endif +//------------------------------------------------------------------------------ +/** + * initialize SPI pins + */ +static void spiBegin() { + // Already spi init for EEPROM in Alligator boards +#if !defined(EEPROM_AVAILABLE) || !defined(EEPROM_SPI_ALLIGATOR) || EEPROM_AVAILABLE != EEPROM_SPI_ALLIGATOR + HAL::spiBegin(); +#endif +} +//------------------------------------------------------------------------------ +/** + * Initialize hardware SPI + * Set SCK rate to F_CPU/pow(2, 1 + spiRate) for spiRate [0,6] + */ +static void spiInit(uint8_t spiRate) { + HAL::spiInit(spiRate); +} +//------------------------------------------------------------------------------ +/** SPI receive a byte */ +static uint8_t spiRec() { + return HAL::spiReceive(); +} +//------------------------------------------------------------------------------ +/** SPI read data - only one call so force inline */ +static inline __attribute__((always_inline)) + uint8_t spiRec(uint8_t* buf, uint16_t nbyte) { +HAL::spiReadBlock(buf,nbyte); +return 0; +} +//------------------------------------------------------------------------------ +/** SPI send a byte */ +static void spiSend(uint8_t b) { + HAL::spiSend(b); +} +//------------------------------------------------------------------------------ +/** SPI send block - only one call so force inline */ +static inline __attribute__((always_inline)) + void spiSendBlock(uint8_t token, const uint8_t* buf) { + HAL::spiSendBlock(token,buf); +} +static void spiSend(const uint8_t* buf , size_t n) { + HAL::spiSend(buf,n); +} + +//------------------------------------------------------------------------------ +#else // SOFTWARE_SPI +#include +static +SoftSPI softSpiBus; +//------------------------------------------------------------------------------ +/** + * initialize SPI pins + */ +static void spiBegin() { + softSpiBus.begin(); +} +//------------------------------------------------------------------------------ +/** Soft SPI receive byte */ +static uint8_t spiRec() { + return softSpiBus.receive(); +} +//------------------------------------------------------------------------------ +/** Soft SPI read data */ +static uint8_t spiRec(uint8_t* buf, size_t nbyte) { + for (size_t i = 0; i < nbyte; i++) { + buf[i] = spiRec(); + } + return 0; +} +//------------------------------------------------------------------------------ +/** Soft SPI send byte */ +static void spiSend(uint8_t data) { + softSpiBus.send(data); +} +//------------------------------------------------------------------------------ +/** Soft SPI send block */ +static void spiSendBlock(uint8_t token, const uint8_t* buf) { + spiSend(token); + for (uint16_t i = 0; i < 512; i++) { + spiSend(buf[i]); + } +} + +#endif // SOFTWARE_SPI +//============================================================================== +#if USE_SD_CRC +// CRC functions +//------------------------------------------------------------------------------ +static uint8_t CRC7(const uint8_t* data, uint8_t n) { + uint8_t crc = 0; + for (uint8_t i = 0; i < n; i++) { + uint8_t d = data[i]; + for (uint8_t j = 0; j < 8; j++) { + crc <<= 1; + if ((d & 0x80) ^ (crc & 0x80)) crc ^= 0x09; + d <<= 1; + } + } + return (crc << 1) | 1; +} +//------------------------------------------------------------------------------ +#if USE_SD_CRC == 1 +// slower CRC-CCITT +// uses the x^16,x^12,x^5,x^1 polynomial. +static uint16_t CRC_CCITT(const uint8_t *data, size_t n) { + uint16_t crc = 0; + for (size_t i = 0; i < n; i++) { + crc = (uint8_t)(crc >> 8) | (crc << 8); + crc ^= data[i]; + crc ^= (uint8_t)(crc & 0xff) >> 4; + crc ^= crc << 12; + crc ^= (crc & 0xff) << 5; + } + return crc; +} +#elif USE_SD_CRC > 1 // CRC_CCITT +//------------------------------------------------------------------------------ +// faster CRC-CCITT +// uses the x^16,x^12,x^5,x^1 polynomial. +static const uint16_t crctab[] PROGMEM = { + 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, + 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF, + 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6, + 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE, + 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485, + 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D, + 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4, + 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC, + 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823, + 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B, + 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12, + 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A, + 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41, + 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49, + 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70, + 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78, + 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F, + 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067, + 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E, + 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256, + 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D, + 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, + 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C, + 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634, + 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB, + 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3, + 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A, + 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92, + 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9, + 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1, + 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8, + 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0 +}; +static uint16_t CRC_CCITT(const uint8_t* data, size_t n) { + uint16_t crc = 0; + for (size_t i = 0; i < n; i++) { + crc = pgm_read_word(&crctab[(crc >> 8 ^ data[i]) & 0XFF]) ^ (crc << 8); + } + return crc; +} +#endif // CRC_CCITT +#endif // USE_SD_CRC +//============================================================================== +// Sd2Card member functions +//------------------------------------------------------------------------------ +// send command and return error code. Return zero for OK +uint8_t Sd2Card::cardCommand(uint8_t cmd, uint32_t arg) { + // select card + chipSelectLow(); + + // wait up to 300 ms if busy + waitNotBusy(300); + + uint8_t *pa = reinterpret_cast(&arg); + +#if USE_SD_CRC + // form message + uint8_t d[6] = {static_cast(cmd | static_cast(0X40)), pa[3], pa[2], pa[1], pa[0]}; + + // add crc + d[5] = CRC7(d, 5); + + // send message + for (uint8_t k = 0; k < 6; k++) spiSend(d[k]); +#else // USE_SD_CRC + // send command + spiSend(cmd | 0x40); + + // send argument + for (int8_t i = 3; i >= 0; i--) spiSend(pa[i]); + + // send CRC - correct for CMD0 with arg zero or CMD8 with arg 0X1AA + spiSend(cmd == CMD0 ? 0X95 : 0X87); +#endif // USE_SD_CRC + // additional delay for CMD0 + if (cmd == CMD0) delay(100); + // skip stuff byte for stop read + if (cmd == CMD12) spiRec(); + + // wait for response + for (uint8_t i = 0; ((status_ = spiRec()) & 0X80) && i != 0XFF; i++); + return status_; +} +//------------------------------------------------------------------------------ +/** + * Determine the size of an SD flash memory card. + * + * \return The number of 512 byte data blocks in the card + * or zero if an error occurs. + */ +uint32_t Sd2Card::cardSize() { + csd_t csd; + if (!readCSD(&csd)) return 0; + if (csd.v1.csd_ver == 0) { + uint8_t read_bl_len = csd.v1.read_bl_len; + uint16_t c_size = (csd.v1.c_size_high << 10) + | (csd.v1.c_size_mid << 2) | csd.v1.c_size_low; + uint8_t c_size_mult = (csd.v1.c_size_mult_high << 1) + | csd.v1.c_size_mult_low; + return (uint32_t)(c_size + 1) << (c_size_mult + read_bl_len - 7); + } else if (csd.v2.csd_ver == 1) { + uint32_t c_size = 0X10000L * csd.v2.c_size_high + 0X100L + * (uint32_t)csd.v2.c_size_mid + csd.v2.c_size_low; + return (c_size + 1) << 10; + } else { + error(SD_CARD_ERROR_BAD_CSD); + return 0; + } +} +//------------------------------------------------------------------------------ +void Sd2Card::chipSelectHigh() { + HAL::digitalWrite(chipSelectPin_, HIGH); + // insure MISO goes high impedance + HAL::spiSend(0XFF); +} +//------------------------------------------------------------------------------ +void Sd2Card::chipSelectLow() { +#ifndef SOFTWARE_SPI + spiInit(spiRate_); +#endif // SOFTWARE_SPI + HAL::digitalWrite(chipSelectPin_, LOW); +} +//------------------------------------------------------------------------------ +/** Erase a range of blocks. + * + * \param[in] firstBlock The address of the first block in the range. + * \param[in] lastBlock The address of the last block in the range. + * + * \note This function requests the SD card to do a flash erase for a + * range of blocks. The data on the card after an erase operation is + * either 0 or 1, depends on the card vendor. The card must support + * single block erase. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool Sd2Card::erase(uint32_t firstBlock, uint32_t lastBlock) { + csd_t csd; + if (!readCSD(&csd)) goto fail; + // check for single block erase + if (!csd.v1.erase_blk_en) { + // erase size mask + uint8_t m = (csd.v1.sector_size_high << 1) | csd.v1.sector_size_low; + if ((firstBlock & m) != 0 || ((lastBlock + 1) & m) != 0) { + // error card can't erase specified area + error(SD_CARD_ERROR_ERASE_SINGLE_BLOCK); + goto fail; + } + } + if (type_ != SD_CARD_TYPE_SDHC) { + firstBlock <<= 9; + lastBlock <<= 9; + } + if (cardCommand(CMD32, firstBlock) + || cardCommand(CMD33, lastBlock) + || cardCommand(CMD38, 0)) { + error(SD_CARD_ERROR_ERASE); + goto fail; + } + if (!waitNotBusy(SD_ERASE_TIMEOUT)) { + error(SD_CARD_ERROR_ERASE_TIMEOUT); + goto fail; + } + chipSelectHigh(); + return true; + + fail: + chipSelectHigh(); + return false; +} +//------------------------------------------------------------------------------ +/** Determine if card supports single block erase. + * + * \return The value one, true, is returned if single block erase is supported. + * The value zero, false, is returned if single block erase is not supported. + */ +bool Sd2Card::eraseSingleBlockEnable() { + csd_t csd; + return readCSD(&csd) ? csd.v1.erase_blk_en : false; +} +//------------------------------------------------------------------------------ +/** + * Initialize an SD flash memory card. + * + * \param[in] sckRateID SPI clock rate selector. See setSckRate(). + * \param[in] chipSelectPin SD chip select pin number. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. The reason for failure + * can be determined by calling errorCode() and errorData(). + */ +bool Sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin) { + errorCode_ = type_ = 0; + chipSelectPin_ = chipSelectPin; + // 16-bit init start time allows over a minute + uint16_t t0 = (uint16_t)HAL::timeInMilliseconds(); + uint32_t arg; + + HAL::pinMode(chipSelectPin_, OUTPUT); + HAL::digitalWrite(chipSelectPin_, HIGH); + spiBegin(); + +#ifndef SOFTWARE_SPI + // set SCK rate for initialization commands + spiRate_ = SPI_SD_INIT_RATE; + spiInit(spiRate_); +#endif // SOFTWARE_SPI + + // must supply min of 74 clock cycles with CS high. + for (uint8_t i = 0; i < 20; i++) spiSend(0XFF); + + // command to go idle in SPI mode + while (cardCommand(CMD0, 0) != R1_IDLE_STATE) { + if (((uint16_t)HAL::timeInMilliseconds() - t0) > SD_INIT_TIMEOUT) { + error(SD_CARD_ERROR_CMD0); + goto fail; + } + } + // check SD version + while (1) { + if (cardCommand(CMD8, 0x1AA) == (R1_ILLEGAL_COMMAND | R1_IDLE_STATE)) { + type(SD_CARD_TYPE_SD1); + break; + } + for (uint8_t i = 0; i < 4; i++) status_ = spiRec(); + if (status_ == 0XAA) { + type(SD_CARD_TYPE_SD2); + break; + } + if (((uint16_t)HAL::timeInMilliseconds() - t0) > SD_INIT_TIMEOUT) { + error(SD_CARD_ERROR_CMD8); + goto fail; + } + } + // initialize card and send host supports SDHC if SD2 + arg = type() == SD_CARD_TYPE_SD2 ? 0X40000000 : 0; + + while (cardAcmd(ACMD41, arg) != R1_READY_STATE) { + // check for timeout + if (((uint16_t)HAL::timeInMilliseconds() - t0) > SD_INIT_TIMEOUT) { + error(SD_CARD_ERROR_ACMD41); + goto fail; + } + } + // if SD2 read OCR register to check for SDHC card + if (type() == SD_CARD_TYPE_SD2) { + if (cardCommand(CMD58, 0)) { + error(SD_CARD_ERROR_CMD58); + goto fail; + } + 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(); + } +#if USE_SD_CRC + if (cardCommand(CMD59, 1) > 1) { + error(SD_CARD_ERROR_CMD59); + goto fail; + } +#endif // USE_SD_CRC + chipSelectHigh(); + +#ifndef SOFTWARE_SPI + return setSckRate(sckRateID); +#else // SOFTWARE_SPI + return true; +#endif // SOFTWARE_SPI + + fail: + chipSelectHigh(); +#if defined(DEBUG_SD_ERROR) + Com::printErrorFLN(PSTR("SD card initalization failed")); +#endif + return false; +} +//------------------------------------------------------------------------------ +/** + * Read a 512 byte block from an SD card. + * + * \param[in] blockNumber Logical block to be read. + * \param[out] dst Pointer to the location that will receive the data. + + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool Sd2Card::readBlock(uint32_t blockNumber, uint8_t* dst) { + SD_TRACE("RB", blockNumber); + // use address if not SDHC card + if (type()!= SD_CARD_TYPE_SDHC) blockNumber <<= 9; + if (cardCommand(CMD17, blockNumber)) { + error(SD_CARD_ERROR_CMD17); + goto fail; + } + return readData(dst, 512); + + fail: + chipSelectHigh(); + return false; +} +//------------------------------------------------------------------------------ +/** Read one data block in a multiple block read sequence + * + * \param[in] dst Pointer to the location for the data to be read. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool Sd2Card::readData(uint8_t *dst) { + chipSelectLow(); + return readData(dst, 512); +} +//------------------------------------------------------------------------------ +bool Sd2Card::readData(uint8_t* dst, size_t count) { + uint16_t crc; + // wait for start block token + uint16_t t0 = HAL::timeInMilliseconds(); + while ((status_ = spiRec()) == 0XFF) { + if (((uint16_t)HAL::timeInMilliseconds() - t0) > SD_READ_TIMEOUT) { + error(SD_CARD_ERROR_READ_TIMEOUT); + goto fail; + } + } + if (status_ != DATA_START_BLOCK) { + error(SD_CARD_ERROR_READ); + goto fail; + } + // transfer data + if ((status_ = spiRec(dst, count))) { + error(SD_CARD_ERROR_SPI_DMA); + goto fail; + } + // get crc + crc = (spiRec() << 8) | spiRec(); +#if USE_SD_CRC + if (crc != CRC_CCITT(dst, count)) { + error(SD_CARD_ERROR_READ_CRC); + goto fail; + } +#endif // USE_SD_CRC + + chipSelectHigh(); + return true; + + fail: + chipSelectHigh(); + return false; +} +//------------------------------------------------------------------------------ +/** read CID or CSR register */ +bool Sd2Card::readRegister(uint8_t cmd, void* buf) { + uint8_t* dst = reinterpret_cast(buf); + if (cardCommand(cmd, 0)) { + error(SD_CARD_ERROR_READ_REG); + goto fail; + } + return readData(dst, 16); + + fail: + chipSelectHigh(); + return false; +} +//------------------------------------------------------------------------------ +/** Start a read multiple blocks sequence. + * + * \param[in] blockNumber Address of first block in sequence. + * + * \note This function is used with readData() and readStop() for optimized + * multiple block reads. SPI chipSelect must be low for the entire sequence. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool Sd2Card::readStart(uint32_t blockNumber) { + SD_TRACE("RS", blockNumber); + if (type()!= SD_CARD_TYPE_SDHC) blockNumber <<= 9; + if (cardCommand(CMD18, blockNumber)) { + error(SD_CARD_ERROR_CMD18); + goto fail; + } + chipSelectHigh(); + return true; + + fail: + chipSelectHigh(); + return false; +} +//------------------------------------------------------------------------------ +/** End a read multiple blocks sequence. + * +* \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool Sd2Card::readStop() { + chipSelectLow(); + if (cardCommand(CMD12, 0)) { + error(SD_CARD_ERROR_CMD12); + goto fail; + } + chipSelectHigh(); + return true; + + fail: + chipSelectHigh(); + return false; +} +//------------------------------------------------------------------------------ +/** + * Set the SPI clock rate. + * + * \param[in] sckRateID A value in the range [0, 14]. + * + * The SPI clock divisor will be set to approximately + * + * (2 + (sckRateID & 1)) << ( sckRateID/2) + * + * The maximum SPI rate is F_CPU/2 for \a sckRateID = 0 and the rate is + * F_CPU/128 for \a scsRateID = 12. + * + * \return The value one, true, is returned for success and the value zero, + * false, is returned for an invalid value of \a sckRateID. + */ +bool Sd2Card::setSckRate(uint8_t sckRateID) { + if (sckRateID > MAX_SCK_RATE_ID) { + error(SD_CARD_ERROR_SCK_RATE); + return false; + } + spiRate_ = sckRateID; + return true; +} + +//------------------------------------------------------------------------------ +// wait for card to go not busy +bool Sd2Card::waitNotBusy(uint16_t timeoutMillis) { + uint16_t t0 = HAL::timeInMilliseconds(); + while (spiRec() != 0XFF) { + if (((uint16_t)HAL::timeInMilliseconds() - t0) >= timeoutMillis) goto fail; + } + return true; + + fail: + return false; +} +//------------------------------------------------------------------------------ +/** + * Writes a 512 byte block to an SD card. + * + * \param[in] blockNumber Logical block to be written. + * \param[in] src Pointer to the location of the data to be written. + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool Sd2Card::writeBlock(uint32_t blockNumber, const uint8_t* src) { + SD_TRACE("WB", blockNumber); + // use address if not SDHC card + if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9; + if (cardCommand(CMD24, blockNumber)) { + error(SD_CARD_ERROR_CMD24); + goto fail; + } + if (!writeData(DATA_START_BLOCK, src)) goto fail; + + // wait for flash programming to complete + if (!waitNotBusy(SD_WRITE_TIMEOUT)) { + error(SD_CARD_ERROR_WRITE_TIMEOUT); + goto fail; + } + // response is r2 so get and check two bytes for nonzero + if (cardCommand(CMD13, 0) || spiRec()) { + error(SD_CARD_ERROR_WRITE_PROGRAMMING); + goto fail; + } + chipSelectHigh(); + return true; + + fail: + chipSelectHigh(); + return false; +} +//------------------------------------------------------------------------------ +/** Write one data block in a multiple block write sequence + * \param[in] src Pointer to the location of the data to be written. + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool Sd2Card::writeData(const uint8_t* src) { + chipSelectLow(); + // wait for previous write to finish + if (!waitNotBusy(SD_WRITE_TIMEOUT)) goto fail; + if (!writeData(WRITE_MULTIPLE_TOKEN, src)) goto fail; + chipSelectHigh(); + return true; + + fail: + error(SD_CARD_ERROR_WRITE_MULTIPLE); + chipSelectHigh(); + return false; +} +//------------------------------------------------------------------------------ +// send one block of data for write block or write multiple blocks +bool Sd2Card::writeData(uint8_t token, const uint8_t* src) { +#if USE_SD_CRC + uint16_t crc = CRC_CCITT(src, 512); +#else // USE_SD_CRC + uint16_t crc = 0XFFFF; +#endif // USE_SD_CRC + + spiSend(token); + spiSend(src, 512); + spiSend(crc >> 8); + spiSend(crc & 0XFF); + + status_ = spiRec(); + if ((status_ & DATA_RES_MASK) != DATA_RES_ACCEPTED) { + error(SD_CARD_ERROR_WRITE); + goto fail; + } + return true; + + fail: + chipSelectHigh(); + return false; +} +//------------------------------------------------------------------------------ +/** Start a write multiple blocks sequence. + * + * \param[in] blockNumber Address of first block in sequence. + * \param[in] eraseCount The number of blocks to be pre-erased. + * + * \note This function is used with writeData() and writeStop() + * for optimized multiple block writes. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool Sd2Card::writeStart(uint32_t blockNumber, uint32_t eraseCount) { + SD_TRACE("WS", blockNumber); + // send pre-erase count + if (cardAcmd(ACMD23, eraseCount)) { + error(SD_CARD_ERROR_ACMD23); + goto fail; + } + // use address if not SDHC card + if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9; + if (cardCommand(CMD25, blockNumber)) { + error(SD_CARD_ERROR_CMD25); + goto fail; + } + chipSelectHigh(); + return true; + + fail: + chipSelectHigh(); + return false; +} +//------------------------------------------------------------------------------ +/** End a write multiple blocks sequence. + * +* \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ +bool Sd2Card::writeStop() { + chipSelectLow(); + if (!waitNotBusy(SD_WRITE_TIMEOUT)) goto fail; + spiSend(STOP_TRAN_TOKEN); + if (!waitNotBusy(SD_WRITE_TIMEOUT)) goto fail; + chipSelectHigh(); + return true; + + fail: + error(SD_CARD_ERROR_STOP_TRAN); + chipSelectHigh(); + return false; +} + +// =================== SdVolume =================== + +//------------------------------------------------------------------------------ +#if !USE_MULTIPLE_CARDS +// raw block cache + +cache_t SdVolume::cacheBuffer_; // 512 byte cache for Sd2Card +uint32_t SdVolume::cacheBlockNumber_; // current block number +uint8_t SdVolume::cacheStatus_; // status of cache block +uint32_t SdVolume::cacheFatOffset_; // offset for mirrored FAT +#if USE_SEPARATE_FAT_CACHE +cache_t SdVolume::cacheFatBuffer_; // 512 byte cache for FAT +uint32_t SdVolume::cacheFatBlockNumber_; // current Fat block number +uint8_t SdVolume::cacheFatStatus_; // status of cache Fatblock +#endif // USE_SEPARATE_FAT_CACHE +Sd2Card* SdVolume::sdCard_; // pointer to SD card object +#endif // USE_MULTIPLE_CARDS +//------------------------------------------------------------------------------ +// find a contiguous group of clusters +bool SdVolume::allocContiguous(uint32_t count, uint32_t* curCluster) { + // start of group + uint32_t bgnCluster; + // end of group + uint32_t endCluster; + // last cluster of FAT + uint32_t fatEnd = clusterCount_ + 1; + + // flag to save place to start next search + bool setStart; + + // set search start cluster + if (*curCluster) { + // try to make file contiguous + bgnCluster = *curCluster + 1; + + // don't save new start location + setStart = false; + } else { + // start at likely place for free cluster + bgnCluster = allocSearchStart_; + + // save next search start if one cluster + setStart = count == 1; + } + // end of group + endCluster = bgnCluster; + + // search the FAT for free clusters + for (uint32_t n = 0;; n++, endCluster++) { + // can't find space checked all clusters + if (n >= clusterCount_) { + DBG_FAIL_MACRO; + goto fail; + } + + // past end - start from beginning of FAT + if (endCluster > fatEnd) { + bgnCluster = endCluster = 2; + } + uint32_t f; + if (!fatGet(endCluster, &f)) { + DBG_FAIL_MACRO; + goto fail; + } + + if (f != 0) { + // cluster in use try next cluster as bgnCluster + bgnCluster = endCluster + 1; + } else if ((endCluster - bgnCluster + 1) == count) { + // done - found space + break; + } + } + // mark end of chain + if (!fatPutEOC(endCluster)) { + DBG_FAIL_MACRO; + goto fail; + } + + // link clusters + while (endCluster > bgnCluster) { + if (!fatPut(endCluster - 1, endCluster)) { + DBG_FAIL_MACRO; + goto fail; + } + endCluster--; + } + if (*curCluster != 0) { + // connect chains + if (!fatPut(*curCluster, bgnCluster)) { + DBG_FAIL_MACRO; + goto fail; + } + } + // return first cluster number to caller + *curCluster = bgnCluster; + // remember possible next free cluster + if (setStart) allocSearchStart_ = bgnCluster + 1; + return true; + + fail: + return false; +} +//============================================================================== + +// cache functions + +#if USE_SEPARATE_FAT_CACHE + +//------------------------------------------------------------------------------ +cache_t* SdVolume::cacheFetch(uint32_t blockNumber, uint8_t options) { + return cacheFetchData(blockNumber, options); +} +//------------------------------------------------------------------------------ +cache_t* SdVolume::cacheFetchData(uint32_t blockNumber, uint8_t options) { + if (cacheBlockNumber_ != blockNumber) { + if (!cacheWriteData()) { + DBG_FAIL_MACRO; + goto fail; + } + if (!(options & CACHE_OPTION_NO_READ)) { +#ifdef GLENN_DEBUG + Com::print("Rd blk:"); + Com::print(blockNumber); + Com::println(); +#endif + if (!sdCard_->readBlock(blockNumber, cacheBuffer_.data)) { + DBG_FAIL_MACRO; + goto fail; + } + } + cacheStatus_ = 0; + cacheBlockNumber_ = blockNumber; + } + cacheStatus_ |= options & CACHE_STATUS_MASK; + return &cacheBuffer_; + + fail: + return 0; +} +//------------------------------------------------------------------------------ +cache_t* SdVolume::cacheFetchFat(uint32_t blockNumber, uint8_t options) { + if (cacheFatBlockNumber_ != blockNumber) { + if (!cacheWriteFat()) { + DBG_FAIL_MACRO; + goto fail; + } + if (!(options & CACHE_OPTION_NO_READ)) { + if (!sdCard_->readBlock(blockNumber, cacheFatBuffer_.data)) { + DBG_FAIL_MACRO; + goto fail; + } + } + cacheFatStatus_ = 0; + cacheFatBlockNumber_ = blockNumber; + } + cacheFatStatus_ |= options & CACHE_STATUS_MASK; + return &cacheFatBuffer_; + + fail: + return 0; +} +//------------------------------------------------------------------------------ +bool SdVolume::cacheSync() { + return cacheWriteData() && cacheWriteFat(); +} +//------------------------------------------------------------------------------ +bool SdVolume::cacheWriteData() { + if (cacheStatus_ & CACHE_STATUS_DIRTY) { + if (!sdCard_->writeBlock(cacheBlockNumber_, cacheBuffer_.data)) { + DBG_FAIL_MACRO; + goto fail; + } + cacheStatus_ &= ~CACHE_STATUS_DIRTY; + } + return true; + + fail: + return false; +} +//------------------------------------------------------------------------------ +bool SdVolume::cacheWriteFat() { + if (cacheFatStatus_ & CACHE_STATUS_DIRTY) { + if (!sdCard_->writeBlock(cacheFatBlockNumber_, cacheFatBuffer_.data)) { + DBG_FAIL_MACRO; + goto fail; + } + // mirror second FAT + if (cacheFatOffset_) { + uint32_t lbn = cacheFatBlockNumber_ + cacheFatOffset_; + if (!sdCard_->writeBlock(lbn, cacheFatBuffer_.data)) { + DBG_FAIL_MACRO; + goto fail; + } + } + cacheFatStatus_ &= ~CACHE_STATUS_DIRTY; + } + return true; + + fail: + return false; +} +#else // USE_SEPARATE_FAT_CACHE +//------------------------------------------------------------------------------ +cache_t* SdVolume::cacheFetch(uint32_t blockNumber, uint8_t options) { + if (cacheBlockNumber_ != blockNumber) { + if (!cacheSync()) { + DBG_FAIL_MACRO; + goto fail; + } + if (!(options & CACHE_OPTION_NO_READ)) { + if (!sdCard_->readBlock(blockNumber, cacheBuffer_.data)) { + DBG_FAIL_MACRO; + goto fail; + } + } + cacheStatus_ = 0; + cacheBlockNumber_ = blockNumber; + } + cacheStatus_ |= options & CACHE_STATUS_MASK; + return &cacheBuffer_; + + fail: + return 0; +} +//------------------------------------------------------------------------------ +cache_t* SdVolume::cacheFetchFat(uint32_t blockNumber, uint8_t options) { + return cacheFetch(blockNumber, options | CACHE_STATUS_FAT_BLOCK); +} +//------------------------------------------------------------------------------ +bool SdVolume::cacheSync() { + if (cacheStatus_ & CACHE_STATUS_DIRTY) { +#ifdef GLENN_DEBUG + Com::print("Wr blk:"); + Com::print(cacheBlockNumber_); + Com::println(); +#endif + if (!sdCard_->writeBlock(cacheBlockNumber_, cacheBuffer_.data)) { + DBG_FAIL_MACRO; + goto fail; + } + // mirror second FAT + if ((cacheStatus_ & CACHE_STATUS_FAT_BLOCK) && cacheFatOffset_) { + uint32_t lbn = cacheBlockNumber_ + cacheFatOffset_; + if (!sdCard_->writeBlock(lbn, cacheBuffer_.data)) { + DBG_FAIL_MACRO; + goto fail; + } + } + cacheStatus_ &= ~CACHE_STATUS_DIRTY; + } + return true; + + fail: + return false; +} +//------------------------------------------------------------------------------ +bool SdVolume::cacheWriteData() { + return cacheSync(); +} +#endif // USE_SEPARATE_FAT_CACHE +//------------------------------------------------------------------------------ +void SdVolume::cacheInvalidate() { + cacheBlockNumber_ = 0XFFFFFFFF; + cacheStatus_ = 0; +} +//============================================================================== +//------------------------------------------------------------------------------ +uint32_t SdVolume::clusterStartBlock(uint32_t cluster) const { + return dataStartBlock_ + ((cluster - 2)*blocksPerCluster_); +} +//------------------------------------------------------------------------------ +// Fetch a FAT entry +bool SdVolume::fatGet(uint32_t cluster, uint32_t* value) { + uint32_t lba; + cache_t* pc; + + // error if reserved cluster of beyond FAT + + if (cluster < 2 || cluster > (clusterCount_ + 1)) { + + DBG_FAIL_MACRO; + + goto fail; + + } + + if (FAT12_SUPPORT && fatType_ == 12) { + + uint16_t index = cluster; + + index += index >> 1; + + lba = fatStartBlock_ + (index >> 9); + pc = cacheFetchFat(lba, CACHE_FOR_READ); + if (!pc) { + DBG_FAIL_MACRO; + goto fail; + } + index &= 0X1FF; + uint16_t tmp = pc->data[index]; + index++; + if (index == 512) { + pc = cacheFetchFat(lba + 1, CACHE_FOR_READ); + if (!pc) { + DBG_FAIL_MACRO; + goto fail; + } + index = 0; + } + tmp |= pc->data[index] << 8; + *value = cluster & 1 ? tmp >> 4 : tmp & 0XFFF; + return true; + } + if (fatType_ == 16) { + lba = fatStartBlock_ + (cluster >> 8); + } else if (fatType_ == 32) { + lba = fatStartBlock_ + (cluster >> 7); + } else { + DBG_FAIL_MACRO; + goto fail; + } + pc = cacheFetchFat(lba, CACHE_FOR_READ); + if (!pc) { + DBG_FAIL_MACRO; + goto fail; + } + if (fatType_ == 16) { + *value = pc->fat16[cluster & 0XFF]; + } else { + *value = pc->fat32[cluster & 0X7F] & FAT32MASK; + } + return true; + + fail: + return false; +} +//------------------------------------------------------------------------------ +// Store a FAT entry +bool SdVolume::fatPut(uint32_t cluster, uint32_t value) { + uint32_t lba; + cache_t* pc; + // error if reserved cluster of beyond FAT + if (cluster < 2 || cluster > (clusterCount_ + 1)) { + DBG_FAIL_MACRO; + goto fail; + } + if (FAT12_SUPPORT && fatType_ == 12) { + uint16_t index = cluster; + index += index >> 1; + lba = fatStartBlock_ + (index >> 9); + pc = cacheFetchFat(lba, CACHE_FOR_WRITE); + if (!pc) { + DBG_FAIL_MACRO; + goto fail; + } + index &= 0X1FF; + uint8_t tmp = value; + if (cluster & 1) { + tmp = (pc->data[index] & 0XF) | tmp << 4; + } + pc->data[index] = tmp; + + index++; + if (index == 512) { + lba++; + index = 0; + pc = cacheFetchFat(lba, CACHE_FOR_WRITE); + if (!pc) { + DBG_FAIL_MACRO; + goto fail; + } + } + tmp = value >> 4; + if (!(cluster & 1)) { + tmp = ((pc->data[index] & 0XF0)) | tmp >> 4; + } + pc->data[index] = tmp; + return true; + } + if (fatType_ == 16) { + lba = fatStartBlock_ + (cluster >> 8); + } else if (fatType_ == 32) { + lba = fatStartBlock_ + (cluster >> 7); + } else { + DBG_FAIL_MACRO; + goto fail; + } + pc = cacheFetchFat(lba, CACHE_FOR_WRITE); + if (!pc) { + DBG_FAIL_MACRO; + goto fail; + } + // store entry + if (fatType_ == 16) { + pc->fat16[cluster & 0XFF] = value; + } else { + pc->fat32[cluster & 0X7F] = value; + } + return true; + + fail: + return false; +} +//------------------------------------------------------------------------------ +// free a cluster chain +bool SdVolume::freeChain(uint32_t cluster) { + uint32_t next; + + // clear free cluster location + allocSearchStart_ = 2; + + do { + if (!fatGet(cluster, &next)) { + DBG_FAIL_MACRO; + goto fail; + } + // free cluster + if (!fatPut(cluster, 0)) { + DBG_FAIL_MACRO; + goto fail; + } + + cluster = next; + } while (!isEOC(cluster)); + + return true; + + fail: + return false; +} +//------------------------------------------------------------------------------ +/** Volume free space in clusters. + * + * \return Count of free clusters for success or -1 if an error occurs. + */ +int32_t SdVolume::freeClusterCount() { + uint32_t free = 0; + uint32_t lba; + uint32_t todo = clusterCount_ + 2; + uint16_t n; + + if (FAT12_SUPPORT && fatType_ == 12) { + for (unsigned i = 2; i < todo; i++) { + uint32_t c; + if (!fatGet(i, &c)) { + DBG_FAIL_MACRO; + goto fail; + } + if (c == 0) free++; + } + } else if (fatType_ == 16 || fatType_ == 32) { + lba = fatStartBlock_; + while (todo) { + cache_t* pc = cacheFetchFat(lba++, CACHE_FOR_READ); + if (!pc) { + DBG_FAIL_MACRO; + goto fail; + } + n = fatType_ == 16 ? 256 : 128; + if (todo < n) n = todo; + if (fatType_ == 16) { + for (uint16_t i = 0; i < n; i++) { + if (pc->fat16[i] == 0) free++; + } + } else { + for (uint16_t i = 0; i < n; i++) { + if (pc->fat32[i] == 0) free++; + } + } + todo -= n; + } + } else { + // invalid FAT type + DBG_FAIL_MACRO; + goto fail; + } + return free; + + fail: + return -1; +} +//------------------------------------------------------------------------------ +/** Initialize a FAT volume. + * + * \param[in] dev The SD card where the volume is located. + * + * \param[in] part The partition to be used. Legal values for \a part are + * 1-4 to use the corresponding partition on a device formatted with + * a MBR, Master Boot Record, or zero if the device is formatted as + * a super floppy with the FAT boot sector in block zero. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. Reasons for + * failure include not finding a valid partition, not finding a valid + * FAT file system in the specified partition or an I/O error. + */ +bool SdVolume::init(Sd2Card* dev, uint8_t part) { + uint32_t totalBlocks; + uint32_t volumeStartBlock = 0; + fat32_boot_t* fbs; + cache_t* pc; + sdCard_ = dev; + fatType_ = 0; + allocSearchStart_ = 2; + cacheStatus_ = 0; // cacheSync() will write block if true + cacheBlockNumber_ = 0XFFFFFFFF; + cacheFatOffset_ = 0; +#if defined(USE_SERARATEFAT_CACHE) && USE_SERARATEFAT_CACHE + cacheFatStatus_ = 0; // cacheSync() will write block if true + cacheFatBlockNumber_ = 0XFFFFFFFF; +#endif // USE_SERARATEFAT_CACHE + // if part == 0 assume super floppy with FAT boot sector in block zero + // if part > 0 assume mbr volume with partition table + if (part) { + if (part > 4) { +#if defined(DEBUG_SD_ERROR) + Com::printErrorFLN(PSTR("volume init: illegal part")); +#endif + DBG_FAIL_MACRO; + goto fail; + } + pc = cacheFetch(volumeStartBlock, CACHE_FOR_READ); + if (!pc) { +#if defined(DEBUG_SD_ERROR) + Com::printErrorFLN(PSTR("volume init: cache fetch failed")); +#endif + DBG_FAIL_MACRO; + goto fail; + } + part_t* p = &pc->mbr.part[part-1]; + if ((p->boot & 0X7F) !=0 || + p->totalSectors < 100 || + p->firstSector == 0) { + // not a valid partition +#if defined(DEBUG_SD_ERROR) + Com::printErrorFLN(PSTR("volume init: invalid partition")); +#endif + DBG_FAIL_MACRO; + goto fail; + } + volumeStartBlock = p->firstSector; + } + pc = cacheFetch(volumeStartBlock, CACHE_FOR_READ); + if (!pc) { +#if defined(DEBUG_SD_ERROR) +Com::printErrorFLN(PSTR("volume init: cache fetch failed")); +#endif + DBG_FAIL_MACRO; + goto fail; + } + fbs = &(pc->fbs32); + if (fbs->bytesPerSector != 512 || + fbs->fatCount == 0 || + fbs->reservedSectorCount == 0 || + fbs->sectorsPerCluster == 0) { + // not valid FAT volume +#if defined(DEBUG_SD_ERROR) + Com::printErrorFLN(PSTR("volume init: not a valid FAT volume")); + Com::printFLN(PSTR("BytesPerSector:"),fbs->bytesPerSector); + Com::printFLN(PSTR("fatCount:"),fbs->fatCount); + Com::printFLN(PSTR("reservedSectorCount:"),fbs->reservedSectorCount); + Com::printFLN(PSTR("sectorsPerCluster:"),fbs->sectorsPerCluster); +#endif + DBG_FAIL_MACRO; + goto fail; + } + fatCount_ = fbs->fatCount; + blocksPerCluster_ = fbs->sectorsPerCluster; + // determine shift that is same as multiply by blocksPerCluster_ + clusterSizeShift_ = 0; + while (blocksPerCluster_ != (1 << clusterSizeShift_)) { + // error if not power of 2 + if (clusterSizeShift_++ > 7) { + DBG_FAIL_MACRO; + goto fail; + } + } + blocksPerFat_ = fbs->sectorsPerFat16 ? + fbs->sectorsPerFat16 : fbs->sectorsPerFat32; + + if (fatCount_ > 0) cacheFatOffset_ = blocksPerFat_; + fatStartBlock_ = volumeStartBlock + fbs->reservedSectorCount; + + // count for FAT16 zero for FAT32 + rootDirEntryCount_ = fbs->rootDirEntryCount; + + // directory start for FAT16 dataStart for FAT32 + rootDirStart_ = fatStartBlock_ + fbs->fatCount * blocksPerFat_; + + // data start for FAT16 and FAT32 + dataStartBlock_ = rootDirStart_ + ((32 * fbs->rootDirEntryCount + 511)/512); + + // total blocks for FAT16 or FAT32 + totalBlocks = fbs->totalSectors16 ? + fbs->totalSectors16 : fbs->totalSectors32; + // total data blocks + clusterCount_ = totalBlocks - (dataStartBlock_ - volumeStartBlock); + + // divide by cluster size to get cluster count + clusterCount_ >>= clusterSizeShift_; + + // FAT type is determined by cluster count + if (clusterCount_ < 4085) { + fatType_ = 12; + if (!FAT12_SUPPORT) { +#if defined(DEBUG_SD_ERROR) + Com::printErrorFLN(PSTR("volume init: No FAT 12 support")); +#endif + DBG_FAIL_MACRO; + goto fail; + } + } else if (clusterCount_ < 65525) { + fatType_ = 16; + } else { + rootDirStart_ = fbs->fat32RootCluster; + fatType_ = 32; + } + return true; + + fail: +#if defined(DEBUG_SD_ERROR) + Com::printErrorFLN(PSTR("SD volume open failed")); +#endif + return false; +} +// =============== SdFile.cpp ==================== + +/** Create a file object and open it in the current working directory. + * + * \param[in] path A path with a valid 8.3 DOS name for a file to be opened. + * + * \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive + * OR of open flags. see SdBaseFile::open(SdBaseFile*, const char*, uint8_t). + */ +SdFile::SdFile(const char* path, uint8_t oflag) : SdBaseFile(path, oflag) { +} +//------------------------------------------------------------------------------ +/** Write data to an open file. + * + * \note Data is moved to the cache but may not be written to the + * storage device until sync() is called. + * + * \param[in] buf Pointer to the location of the data to be written. + * + * \param[in] nbyte Number of bytes to write. + * + * \return For success write() returns the number of bytes written, always + * \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. + * + */ +int SdFile::write(const void* buf, size_t nbyte) { + return SdBaseFile::write(buf, nbyte); +} +//------------------------------------------------------------------------------ +/** Write a byte to a file. Required by the Arduino Print class. + * \param[in] b the byte to be written. + * Use getWriteError to check for errors. + * \return 1 for success and 0 for failure. + */ +#ifdef COMPAT_PRE1 + void SdFile::write(uint8_t b) { + SdBaseFile::write(&b, 1); + } +#else +size_t SdFile::write(uint8_t b) { + return SdBaseFile::write(&b, 1) == 1 ? 1 : 0; +} +#endif + +//------------------------------------------------------------------------------ +/** Write a string to a file. Used by the Arduino Print class. + * \param[in] str Pointer to the string. + * Use getWriteError to check for errors. + * \return count of characters written for success or -1 for failure. + */ +int SdFile::write(const char* str) { + return SdBaseFile::write(str, strlen(str)); +} +//------------------------------------------------------------------------------ +/** Write a PROGMEM string to a file. + * \param[in] str Pointer to the PROGMEM string. + * Use getWriteError to check for errors. + */ +void SdFile::write_P(FSTRINGPARAM(str)) { + for (uint8_t c; (c = HAL::readFlashByte(str)); str++) write(c); +} +//------------------------------------------------------------------------------ +/** Write a PROGMEM string followed by CR/LF to a file. + * \param[in] str Pointer to the PROGMEM string. + * Use getWriteError to check for errors. + */ +void SdFile::writeln_P(FSTRINGPARAM(str)) { + write_P(str); + write_P(Com::tNewline); +} + +// ================ SdFatUtil.cpp =================== + +//------------------------------------------------------------------------------ +/** Amount of free RAM + * \return The number of free bytes. + */ +int SdFatUtil::FreeRam() { + extern int __bss_end; + extern int* __brkval; + int free_memory; + if (reinterpret_cast(__brkval) == 0) { + // if no heap use from end of bss section + free_memory = reinterpret_cast(&free_memory) + - reinterpret_cast(&__bss_end); + } else { + // use from top of stack to heap + free_memory = reinterpret_cast(&free_memory) + - reinterpret_cast(__brkval); + } + return free_memory; +} +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/** %Print a string in flash memory to Serial. + * + * \param[in] str Pointer to string stored in flash memory. + */ +void SdFatUtil::SerialPrint_P(FSTRINGPARAM(str)) { + Com::printF(str); +} +//------------------------------------------------------------------------------ +/** %Print a string in flash memory to Serial followed by a CR/LF. + * + * \param[in] str Pointer to string stored in flash memory. + */ +void SdFatUtil::SerialPrintln_P(FSTRINGPARAM(str)) { + Com::printFLN(str); +} + +// ============== + +#endif // SDSUPPORT + diff --git a/trunk/Arduino/Repetier_0.92.9/SdFat.h b/trunk/Arduino/Repetier_0.92.9/SdFat.h new file mode 100644 index 00000000..6c6cb60d --- /dev/null +++ b/trunk/Arduino/Repetier_0.92.9/SdFat.h @@ -0,0 +1,2326 @@ +/* Arduino SdFat Library + * Copyright (C) 2012 by William Greiman + * + * This file is part of the Arduino SdFat Library + * + * This Library is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Arduino SdFat Library. If not, see + * . + */ +/* Arduino SdFat Library + * Copyright (C) 2012 by William Greiman + * + * This file is part of the Arduino SdFat Library + * + * This Library is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Arduino SdFat Library. If not, see + * . + */ + +/** +\mainpage Arduino %SdFat Library +
    Copyright © 2012 by William Greiman +
    + +\section Intro Introduction +The Arduino %SdFat Library is a minimal implementation of FAT16 and FAT32 +file systems on SD flash memory cards. Standard SD and high capacity SDHC +cards are supported. + +Experimental support for FAT12 can be enabled by setting FAT12_SUPPORT +nonzero in SdFatConfig.h. + +The %SdFat library only supports short 8.3 names. + +The main classes in %SdFat are SdFat, SdFile, \ref fstream, \ref ifstream, +and \ref ofstream. + +The SdFat class maintains a volume working directories, a current working +directory, and simplifies initialization of other classes. + +The SdFile class provides binary file access functions such as open(), read(), +remove(), write(), close() and sync(). This class supports access to the root +directory and subdirectories. + +The \ref fstream class implements C++ iostreams for both reading and writing +text files. + +The \ref ifstream class implements the C++ iostreams for reading text files. + +The \ref ofstream class implements the C++ iostreams for writing text files. + +The classes \ref ibufstream and \ref obufstream format and parse character + strings in memory buffers. + +the classes ArduinoInStream and ArduinoOutStream provide iostream functions +for Serial, LiquidCrystal, and other devices. + +The SdVolume class supports FAT16 and FAT32 partitions. Most applications +will not need to call SdVolume member function. + +The Sd2Card class supports access to standard SD cards and SDHC cards. Most +applications will not need to call Sd2Card functions. The Sd2Card class can +be used for raw access to the SD card. + +A number of example are provided in the %SdFat/examples folder. These were +developed to test %SdFat and illustrate its use. + +%SdFat was developed for high speed data recording. %SdFat was used to +implement an audio record/play class, WaveRP, for the Adafruit Wave Shield. +This application uses special Sd2Card calls to write to contiguous files in +raw mode. These functions reduce write latency so that audio can be +recorded with the small amount of RAM in the Arduino. + +\section SDcard SD\SDHC Cards + +Arduinos access SD cards using the cards SPI protocol. PCs, Macs, and +most consumer devices use the 4-bit parallel SD protocol. A card that +functions well on A PC or Mac may not work well on the Arduino. + +Most cards have good SPI read performance but cards vary widely in SPI +write performance. Write performance is limited by how efficiently the +card manages internal erase/remapping operations. The Arduino cannot +optimize writes to reduce erase operations because of its limit RAM. + +SanDisk cards generally have good write performance. They seem to have +more internal RAM buffering than other cards and therefore can limit +the number of flash erase operations that the Arduino forces due to its +limited RAM. + +\section Hardware Hardware Configuration + +%SdFat was developed using an +
    Adafruit Industries + Wave Shield. + +The hardware interface to the SD card should not use a resistor based level +shifter. %SdFat sets the SPI bus frequency to 8 MHz which results in signal +rise times that are too slow for the edge detectors in many newer SD card +controllers when resistor voltage dividers are used. + +The 5 to 3.3 V level shifter for 5 V Arduinos should be IC based like the +74HC4050N based circuit shown in the file SdLevel.png. The Adafruit Wave Shield +uses a 74AHC125N. Gravitech sells SD and MicroSD Card Adapters based on the +74LCX245. + +If you are using a resistor based level shifter and are having problems try +setting the SPI bus frequency to 4 MHz. This can be done by using +card.init(SPI_HALF_SPEED) to initialize the SD card. + +\section comment Bugs and Comments + +If you wish to report bugs or have comments, send email to fat16lib@sbcglobal.net. + +\section SdFatClass SdFat Usage + +%SdFat uses a slightly restricted form of short names. +Only printable ASCII characters are supported. No characters with code point +values greater than 127 are allowed. Space is not allowed even though space +was allowed in the API of early versions of DOS. + +Short names are limited to 8 characters followed by an optional period (.) +and extension of up to 3 characters. The characters may be any combination +of letters and digits. The following special characters are also allowed: + +$ % ' - _ @ ~ ` ! ( ) { } ^ # & + +Short names are always converted to upper case and their original case +value is lost. + +\note + The Arduino Print class uses character +at a time writes so it was necessary to use a \link SdFile::sync() sync() \endlink +function to control when data is written to the SD card. + +\par +An application which writes to a file using print(), println() or +\link SdFile::write write() \endlink must call \link SdFile::sync() sync() \endlink +at the appropriate time to force data and directory information to be written +to the SD Card. Data and directory information are also written to the SD card +when \link SdFile::close() close() \endlink is called. + +\par +Applications must use care calling \link SdFile::sync() sync() \endlink +since 2048 bytes of I/O is required to update file and +directory information. This includes writing the current data block, reading +the block that contains the directory entry for update, writing the directory +block back and reading back the current data block. + +It is possible to open a file with two or more instances of SdFile. A file may +be corrupted if data is written to the file by more than one instance of SdFile. + +\section HowTo How to format SD Cards as FAT Volumes + +You should use a freshly formatted SD card for best performance. FAT +file systems become slower if many files have been created and deleted. +This is because the directory entry for a deleted file is marked as deleted, +but is not deleted. When a new file is created, these entries must be scanned +before creating the file, a flaw in the FAT design. Also files can become +fragmented which causes reads and writes to be slower. + +A formatter sketch, SdFormatter.pde, is included in the +%SdFat/examples/SdFormatter directory. This sketch attempts to +emulate SD Association's SDFormatter. + +The best way to restore an SD card's format on a PC is to use SDFormatter +which can be downloaded from: + +http://www.sdcard.org/consumers/formatter/ + +SDFormatter aligns flash erase boundaries with file +system structures which reduces write latency and file system overhead. + +SDFormatter does not have an option for FAT type so it may format +small cards as FAT12. + +After the MBR is restored by SDFormatter you may need to reformat small +cards that have been formatted FAT12 to force the volume type to be FAT16. + +If you reformat the SD card with an OS utility, choose a cluster size that +will result in: + +4084 < CountOfClusters && CountOfClusters < 65525 + +The volume will then be FAT16. + +If you are formatting an SD card on OS X or Linux, be sure to use the first +partition. Format this partition with a cluster count in above range for FAT16. +SDHC cards should be formatted FAT32 with a cluster size of 32 KB. + +Microsoft operating systems support removable media formatted with a +Master Boot Record, MBR, or formatted as a super floppy with a FAT Boot Sector +in block zero. + +Microsoft operating systems expect MBR formatted removable media +to have only one partition. The first partition should be used. + +Microsoft operating systems do not support partitioning SD flash cards. +If you erase an SD card with a program like KillDisk, Most versions of +Windows will format the card as a super floppy. + +\section References References + +Adafruit Industries: + +http://www.adafruit.com/ + +http://www.ladyada.net/make/waveshield/ + +The Arduino site: + +http://www.arduino.cc/ + +For more information about FAT file systems see: + +http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx + +For information about using SD cards as SPI devices see: + +http://www.sdcard.org/developers/tech/sdcard/pls/Simplified_Physical_Layer_Spec.pdf + +The ATmega328 datasheet: + +http://www.atmel.com/dyn/resources/prod_documents/doc8161.pdf + + + */ +#ifndef SdFat_h +#define SdFat_h +/** + * \file + * \brief SdFat class + */ +//------------------------------------------------------------------------------ +/** SdFat version YYYYMMDD */ +#define SD_FAT_VERSION 20130629 +//------------------------------------------------------------------------------ +/** error if old IDE */ +#if !defined(ARDUINO) || ARDUINO < 100 +#error Arduino IDE must be 1.0 or greater +#endif // ARDUINO < 100 +//------------------------------------------------------------------------------ +#include +// Based on the document: +// +// SD Specifications +// Part 1 +// Physical Layer +// Simplified Specification +// Version 3.01 +// May 18, 2010 +// +// http://www.sdcard.org/developers/tech/sdcard/pls/simplified_specs +//------------------------------------------------------------------------------ +// SD card commands +/** GO_IDLE_STATE - init card in spi mode if CS low */ +uint8_t const CMD0 = 0X00; +/** SEND_IF_COND - verify SD Memory Card interface operating condition.*/ +uint8_t const CMD8 = 0X08; +/** SEND_CSD - read the Card Specific Data (CSD register) */ +uint8_t const CMD9 = 0X09; +/** SEND_CID - read the card identification information (CID register) */ +uint8_t const CMD10 = 0X0A; +/** STOP_TRANSMISSION - end multiple block read sequence */ +uint8_t const CMD12 = 0X0C; +/** SEND_STATUS - read the card status register */ +uint8_t const CMD13 = 0X0D; +/** READ_SINGLE_BLOCK - read a single data block from the card */ +uint8_t const CMD17 = 0X11; +/** READ_MULTIPLE_BLOCK - read a multiple data blocks from the card */ +uint8_t const CMD18 = 0X12; +/** WRITE_BLOCK - write a single data block to the card */ +uint8_t const CMD24 = 0X18; +/** WRITE_MULTIPLE_BLOCK - write blocks of data until a STOP_TRANSMISSION */ +uint8_t const CMD25 = 0X19; +/** ERASE_WR_BLK_START - sets the address of the first block to be erased */ +uint8_t const CMD32 = 0X20; +/** ERASE_WR_BLK_END - sets the address of the last block of the continuous + range to be erased*/ +uint8_t const CMD33 = 0X21; +/** ERASE - erase all previously selected blocks */ +uint8_t const CMD38 = 0X26; +/** APP_CMD - escape for application specific command */ +uint8_t const CMD55 = 0X37; +/** READ_OCR - read the OCR register of a card */ +uint8_t const CMD58 = 0X3A; +/** CRC_ON_OFF - enable or disable CRC checking */ +uint8_t const CMD59 = 0X3B; +/** SET_WR_BLK_ERASE_COUNT - Set the number of write blocks to be + pre-erased before writing */ +uint8_t const ACMD23 = 0X17; +/** SD_SEND_OP_COMD - Sends host capacity support information and + activates the card's initialization process */ +uint8_t const ACMD41 = 0X29; +//------------------------------------------------------------------------------ +/** status for card in the ready state */ +uint8_t const R1_READY_STATE = 0X00; +/** status for card in the idle state */ +uint8_t const R1_IDLE_STATE = 0X01; +/** status bit for illegal command */ +uint8_t const R1_ILLEGAL_COMMAND = 0X04; +/** start data token for read or write single block*/ +uint8_t const DATA_START_BLOCK = 0XFE; +/** stop token for write multiple blocks*/ +uint8_t const STOP_TRAN_TOKEN = 0XFD; +/** start data token for write multiple blocks*/ +uint8_t const WRITE_MULTIPLE_TOKEN = 0XFC; +/** mask for data response tokens after a write block operation */ +uint8_t const DATA_RES_MASK = 0X1F; +/** write data accepted token */ +uint8_t const DATA_RES_ACCEPTED = 0X05; +//------------------------------------------------------------------------------ +/** Card IDentification (CID) register */ +typedef struct CID { + // byte 0 + /** Manufacturer ID */ + unsigned char mid; + // byte 1-2 + /** OEM/Application ID */ + char oid[2]; + // byte 3-7 + /** Product name */ + char pnm[5]; + // byte 8 + /** Product revision least significant digit */ + unsigned char prv_m : 4; + /** Product revision most significant digit */ + unsigned char prv_n : 4; + // byte 9-12 + /** Product serial number */ + uint32_t psn; + // byte 13 + /** Manufacturing date year low digit */ + unsigned char mdt_year_high : 4; + /** not used */ + unsigned char reserved : 4; + // byte 14 + /** Manufacturing date month */ + unsigned char mdt_month : 4; + /** Manufacturing date year low digit */ + unsigned char mdt_year_low :4; + // byte 15 + /** not used always 1 */ + unsigned char always1 : 1; + /** CRC7 checksum */ + unsigned char crc : 7; +}__attribute__((packed)) cid_t; +//------------------------------------------------------------------------------ +/** CSD for version 1.00 cards */ +typedef struct CSDV1 { + // byte 0 + unsigned char reserved1 : 6; + unsigned char csd_ver : 2; + // byte 1 + unsigned char taac; + // byte 2 + unsigned char nsac; + // byte 3 + unsigned char tran_speed; + // byte 4 + unsigned char ccc_high; + // byte 5 + unsigned char read_bl_len : 4; + unsigned char ccc_low : 4; + // byte 6 + unsigned char c_size_high : 2; + unsigned char reserved2 : 2; + unsigned char dsr_imp : 1; + unsigned char read_blk_misalign :1; + unsigned char write_blk_misalign : 1; + unsigned char read_bl_partial : 1; + // byte 7 + unsigned char c_size_mid; + // byte 8 + unsigned char vdd_r_curr_max : 3; + unsigned char vdd_r_curr_min : 3; + unsigned char c_size_low :2; + // byte 9 + unsigned char c_size_mult_high : 2; + unsigned char vdd_w_cur_max : 3; + unsigned char vdd_w_curr_min : 3; + // byte 10 + unsigned char sector_size_high : 6; + unsigned char erase_blk_en : 1; + unsigned char c_size_mult_low : 1; + // byte 11 + unsigned char wp_grp_size : 7; + unsigned char sector_size_low : 1; + // byte 12 + unsigned char write_bl_len_high : 2; + unsigned char r2w_factor : 3; + unsigned char reserved3 : 2; + unsigned char wp_grp_enable : 1; + // byte 13 + unsigned char reserved4 : 5; + unsigned char write_partial : 1; + unsigned char write_bl_len_low : 2; + // byte 14 + unsigned char reserved5: 2; + unsigned char file_format : 2; + unsigned char tmp_write_protect : 1; + unsigned char perm_write_protect : 1; + unsigned char copy : 1; + /** Indicates the file format on the card */ + unsigned char file_format_grp : 1; + // byte 15 + unsigned char always1 : 1; + unsigned char crc : 7; +}__attribute__((packed)) csd1_t; +//------------------------------------------------------------------------------ +/** CSD for version 2.00 cards */ +typedef struct CSDV2 { + // byte 0 + unsigned char reserved1 : 6; + unsigned char csd_ver : 2; + // byte 1 + /** fixed to 0X0E */ + unsigned char taac; + // byte 2 + /** fixed to 0 */ + unsigned char nsac; + // byte 3 + unsigned char tran_speed; + // byte 4 + unsigned char ccc_high; + // byte 5 + /** This field is fixed to 9h, which indicates READ_BL_LEN=512 Byte */ + unsigned char read_bl_len : 4; + unsigned char ccc_low : 4; + // byte 6 + /** not used */ + unsigned char reserved2 : 4; + unsigned char dsr_imp : 1; + /** fixed to 0 */ + unsigned char read_blk_misalign :1; + /** fixed to 0 */ + unsigned char write_blk_misalign : 1; + /** fixed to 0 - no partial read */ + unsigned char read_bl_partial : 1; + // byte 7 + /** high part of card size */ + unsigned char c_size_high : 6; + /** not used */ + unsigned char reserved3 : 2; + // byte 8 + /** middle part of card size */ + unsigned char c_size_mid; + // byte 9 + /** low part of card size */ + unsigned char c_size_low; + // byte 10 + /** sector size is fixed at 64 KB */ + unsigned char sector_size_high : 6; + /** fixed to 1 - erase single is supported */ + unsigned char erase_blk_en : 1; + /** not used */ + unsigned char reserved4 : 1; + // byte 11 + unsigned char wp_grp_size : 7; + /** sector size is fixed at 64 KB */ + unsigned char sector_size_low : 1; + // byte 12 + /** write_bl_len fixed for 512 byte blocks */ + unsigned char write_bl_len_high : 2; + /** fixed value of 2 */ + unsigned char r2w_factor : 3; + /** not used */ + unsigned char reserved5 : 2; + /** fixed value of 0 - no write protect groups */ + unsigned char wp_grp_enable : 1; + // byte 13 + unsigned char reserved6 : 5; + /** always zero - no partial block read*/ + unsigned char write_partial : 1; + /** write_bl_len fixed for 512 byte blocks */ + unsigned char write_bl_len_low : 2; + // byte 14 + unsigned char reserved7: 2; + /** Do not use always 0 */ + unsigned char file_format : 2; + unsigned char tmp_write_protect : 1; + unsigned char perm_write_protect : 1; + unsigned char copy : 1; + /** Do not use always 0 */ + unsigned char file_format_grp : 1; + // byte 15 + /** not used always 1 */ + unsigned char always1 : 1; + /** checksum */ + unsigned char crc : 7; +}__attribute__((packed)) csd2_t; +//------------------------------------------------------------------------------ +/** union of old and new style CSD register */ +union csd_t { + csd1_t v1; + csd2_t v2; +}; + +//------------------------------------------------------------------------------ +/** + * To enable SD card CRC checking set USE_SD_CRC nonzero. + * + * Set USE_SD_CRC to 1 to use a smaller slower CRC-CCITT function. + * + * Set USE_SD_CRC to 2 to used a larger faster table driven CRC-CCITT function. + */ +#define USE_SD_CRC 2 +//------------------------------------------------------------------------------ +/** + * To use multiple SD cards set USE_MULTIPLE_CARDS nonzero. + * + * Using multiple cards costs 400 - 500 bytes of flash. + * + * Each card requires about 550 bytes of SRAM so use of a Mega is recommended. + */ +#define USE_MULTIPLE_CARDS 0 +//------------------------------------------------------------------------------ +/** + * Set DESTRUCTOR_CLOSES_FILE nonzero to close a file in its destructor. + * + * Causes use of lots of heap in ARM. + */ +#define DESTRUCTOR_CLOSES_FILE 0 +//------------------------------------------------------------------------------ + +/** + * Set USE_SEPARATE_FAT_CACHE nonzero to use a second 512 byte cache + * for FAT table entries. Improves performance for large writes that + * are not a multiple of 512 bytes. + */ +#ifdef __arm__ +#define USE_SEPARATE_FAT_CACHE 1 +#else // __arm__ +#define USE_SEPARATE_FAT_CACHE 0 +#endif // __arm__ +//------------------------------------------------------------------------------ +/** + * Don't use mult-block read/write on small AVR boards + */ +#if defined(RAMEND) && (RAMEND < 3000 || (NONLINEAR_SYSTEM && RAMEND<8000)) +#define USE_MULTI_BLOCK_SD_IO 0 +#else +#define USE_MULTI_BLOCK_SD_IO 1 +#endif +//------------------------------------------------------------------------------ +/** + * Force use of Arduino Standard SPI library if USE_ARDUINO_SPI_LIBRARY + * is nonzero. + */ +#define USE_ARDUINO_SPI_LIBRARY 0 + +//------------------------------------------------------------------------------ + +/** + * Use native SPI on Teensy 3.0 if USE_NATIVE_MK20DX128-SPI is nonzero. + */ +#if defined(__arm__) && defined(CORE_TEENSY) +#define USE_NATIVE_MK20DX128_SPI 1 +#else +#define USE_NATIVE_MK20DX128_SPI 0 +#endif +//------------------------------------------------------------------------------ +/** + * Use fast SAM3X SPI library if USE_NATIVE_SAM3X_SPI is nonzero. + */ +#if defined(__arm__) && !defined(CORE_TEENSY) +#define USE_NATIVE_SAM3X_SPI 1 +#else +#define USE_NATIVE_SAM3X_SPI 0 +#endif +//------------------------------------------------------------------------------ +/** + * Set nonzero to use Serial (the HardwareSerial class) for error messages + * and output from print functions like ls(). + * + * If USE_SERIAL_FOR_STD_OUT is zero, a small non-interrupt driven class + * is used to output messages to serial port zero. This allows an alternate + * Serial library like SerialPort to be used with SdFat. + * + * You can redirect stdOut with SdFat::setStdOut(Print* stream) and + * get the current stream with SdFat::stdOut(). + */ +#define USE_SERIAL_FOR_STD_OUT 0 +//------------------------------------------------------------------------------ +/** + * Call flush for endl if ENDL_CALLS_FLUSH is nonzero + * + * The standard for iostreams is to call flush. This is very costly for + * SdFat. Each call to flush causes 2048 bytes of I/O to the SD. + * + * SdFat has a single 512 byte buffer for SD I/O so it must write the current + * data block to the SD, read the directory block from the SD, update the + * directory entry, write the directory block to the SD and read the data + * block back into the buffer. + * + * The SD flash memory controller is not designed for this many rewrites + * so performance may be reduced by more than a factor of 100. + * + * If ENDL_CALLS_FLUSH is zero, you must call flush and/or close to force + * all data to be written to the SD. + */ +#define ENDL_CALLS_FLUSH 0 +//------------------------------------------------------------------------------ +/** + * Allow use of deprecated functions if ALLOW_DEPRECATED_FUNCTIONS is nonzero + */ +#define ALLOW_DEPRECATED_FUNCTIONS 0 +//------------------------------------------------------------------------------ +/** + * Allow FAT12 volumes if FAT12_SUPPORT is nonzero. + * FAT12 has not been well tested. + */ +#define FAT12_SUPPORT 0 +//------------------------------------------------------------------------------ +/** + * SPI init rate for SD initialization commands. Must be 10 (F_CPU/64) + * or greater + */ +#define SPI_SD_INIT_RATE 11 +//------------------------------------------------------------------------------ +/** + * Set the SS pin high for hardware SPI. If SS is chip select for another SPI + * device this will disable that device during the SD init phase. + */ +#define SET_SPI_SS_HIGH 1 +//------------------------------------------------------------------------------ +/** + * Define MEGA_SOFT_SPI nonzero to use software SPI on Mega Arduinos. + * Default pins used are SS 10, MOSI 11, MISO 12, and SCK 13. + * Edit Software Spi pins to change pin numbers. + * + * MEGA_SOFT_SPI allows an unmodified Adafruit GPS Shield to be used + * on Mega Arduinos. Software SPI works well with GPS Shield V1.1 + * but many SD cards will fail with GPS Shield V1.0. + */ +#define MEGA_SOFT_SPI 0 +//------------------------------------------------------------------------------ +/** + * Define LEONARDO_SOFT_SPI nonzero to use software SPI on Leonardo Arduinos. + * Derfault pins used are SS 10, MOSI 11, MISO 12, and SCK 13. + * Edit Software Spi pins to change pin numbers. + * + * LEONARDO_SOFT_SPI allows an unmodified Adafruit GPS Shield to be used + * on Leonardo Arduinos. Software SPI works well with GPS Shield V1.1 + * but many SD cards will fail with GPS Shield V1.0. + */ +#define LEONARDO_SOFT_SPI 0 +//------------------------------------------------------------------------------ +/** + * Set USE_SOFTWARE_SPI nonzero to always use software SPI. + */ +#define USE_SOFTWARE_SPI 0 +// define software SPI pins so Mega can use unmodified 168/328 shields +/** Default Software SPI chip select pin */ +uint8_t const SOFT_SPI_CS_PIN = 10; +/** Software SPI Master Out Slave In pin */ +uint8_t const SOFT_SPI_MOSI_PIN = 11; +/** Software SPI Master In Slave Out pin */ +uint8_t const SOFT_SPI_MISO_PIN = 12; +/** Software SPI Clock pin */ +uint8_t const SOFT_SPI_SCK_PIN = 13; +//------------------------------------------------------------------------------ +// SPI speed is F_CPU/2^(1 + index), 0 <= index <= 6 +/** Set SCK to max rate of F_CPU/2. See Sd2Card::setSckRate(). */ +uint8_t const SPI_FULL_SPEED = 0; +/** Set SCK rate to F_CPU/3 for Due */ +uint8_t const SPI_DIV3_SPEED = 1; +/** Set SCK rate to F_CPU/4. See Sd2Card::setSckRate(). */ +uint8_t const SPI_HALF_SPEED = 2; +/** Set SCK rate to F_CPU/6 for Due */ +uint8_t const SPI_DIV6_SPEED = 3; +/** Set SCK rate to F_CPU/8. See Sd2Card::setSckRate(). */ +uint8_t const SPI_QUARTER_SPEED = 4; +/** Set SCK rate to F_CPU/16. See Sd2Card::setSckRate(). */ +uint8_t const SPI_EIGHTH_SPEED = 6; +/** Set SCK rate to F_CPU/32. See Sd2Card::setSckRate(). */ +uint8_t const SPI_SIXTEENTH_SPEED = 8; +/** MAX rate test - see spiInit for a given chip for details */ +const uint8_t MAX_SCK_RATE_ID = 14; +//------------------------------------------------------------------------------ +/** init timeout ms */ +uint16_t const SD_INIT_TIMEOUT = 2000; +/** erase timeout ms */ +uint16_t const SD_ERASE_TIMEOUT = 10000; +/** read timeout ms */ +uint16_t const SD_READ_TIMEOUT = 300; +/** write time out ms */ +uint16_t const SD_WRITE_TIMEOUT = 600; +//------------------------------------------------------------------------------ +// SD card errors +/** timeout error for command CMD0 (initialize card in SPI mode) */ +uint8_t const SD_CARD_ERROR_CMD0 = 0X1; +/** CMD8 was not accepted - not a valid SD card*/ +uint8_t const SD_CARD_ERROR_CMD8 = 0X2; +/** card returned an error response for CMD12 (write stop) */ +uint8_t const SD_CARD_ERROR_CMD12 = 0X3; +/** card returned an error response for CMD17 (read block) */ +uint8_t const SD_CARD_ERROR_CMD17 = 0X4; +/** card returned an error response for CMD18 (read multiple block) */ +uint8_t const SD_CARD_ERROR_CMD18 = 0X5; +/** card returned an error response for CMD24 (write block) */ +uint8_t const SD_CARD_ERROR_CMD24 = 0X6; +/** WRITE_MULTIPLE_BLOCKS command failed */ +uint8_t const SD_CARD_ERROR_CMD25 = 0X7; +/** card returned an error response for CMD58 (read OCR) */ +uint8_t const SD_CARD_ERROR_CMD58 = 0X8; +/** SET_WR_BLK_ERASE_COUNT failed */ +uint8_t const SD_CARD_ERROR_ACMD23 = 0X9; +/** ACMD41 initialization process timeout */ +uint8_t const SD_CARD_ERROR_ACMD41 = 0XA; +/** card returned a bad CSR version field */ +uint8_t const SD_CARD_ERROR_BAD_CSD = 0XB; +/** erase block group command failed */ +uint8_t const SD_CARD_ERROR_ERASE = 0XC; +/** card not capable of single block erase */ +uint8_t const SD_CARD_ERROR_ERASE_SINGLE_BLOCK = 0XD; +/** Erase sequence timed out */ +uint8_t const SD_CARD_ERROR_ERASE_TIMEOUT = 0XE; +/** card returned an error token instead of read data */ +uint8_t const SD_CARD_ERROR_READ = 0XF; +/** read CID or CSD failed */ +uint8_t const SD_CARD_ERROR_READ_REG = 0X10; +/** timeout while waiting for start of read data */ +uint8_t const SD_CARD_ERROR_READ_TIMEOUT = 0X11; +/** card did not accept STOP_TRAN_TOKEN */ +uint8_t const SD_CARD_ERROR_STOP_TRAN = 0X12; +/** card returned an error token as a response to a write operation */ +uint8_t const SD_CARD_ERROR_WRITE = 0X13; +/** attempt to write protected block zero */ +uint8_t const SD_CARD_ERROR_WRITE_BLOCK_ZERO = 0X14; // REMOVE - not used +/** card did not go ready for a multiple block write */ +uint8_t const SD_CARD_ERROR_WRITE_MULTIPLE = 0X15; +/** card returned an error to a CMD13 status check after a write */ +uint8_t const SD_CARD_ERROR_WRITE_PROGRAMMING = 0X16; +/** timeout occurred during write programming */ +uint8_t const SD_CARD_ERROR_WRITE_TIMEOUT = 0X17; +/** incorrect rate selected */ +uint8_t const SD_CARD_ERROR_SCK_RATE = 0X18; +/** init() not called */ +uint8_t const SD_CARD_ERROR_INIT_NOT_CALLED = 0X19; +/** card returned an error for CMD59 (CRC_ON_OFF) */ +uint8_t const SD_CARD_ERROR_CMD59 = 0X1A; +/** invalid read CRC */ +uint8_t const SD_CARD_ERROR_READ_CRC = 0X1B; +/** SPI DMA error */ +uint8_t const SD_CARD_ERROR_SPI_DMA = 0X1C; +//------------------------------------------------------------------------------ +// card types +/** Standard capacity V1 SD card */ +uint8_t const SD_CARD_TYPE_SD1 = 1; +/** Standard capacity V2 SD card */ +uint8_t const SD_CARD_TYPE_SD2 = 2; +/** High Capacity SD card */ +uint8_t const SD_CARD_TYPE_SDHC = 3; +/** + * define SOFTWARE_SPI to use bit-bang SPI + */ +//------------------------------------------------------------------------------ +#if LEONARDO_SOFT_SPI && defined(__AVR_ATmega32U4__) && !defined(CORE_TEENSY) +#define SOFTWARE_SPI +#elif MEGA_SOFT_SPI&&(defined(__AVR_ATmega1280__)||defined(__AVR_ATmega2560__)) +#define SOFTWARE_SPI +#elif USE_SOFTWARE_SPI +#define SOFTWARE_SPI +#endif // LEONARDO_SOFT_SPI +//------------------------------------------------------------------------------ +// define default chip select pin +// +#ifndef SOFTWARE_SPI +// hardware pin defs +/** The default chip select pin for the SD card is SS. */ +uint8_t const SD_CHIP_SELECT_PIN = SDSS; +#else // SOFTWARE_SPI +/** SPI chip select pin */ +uint8_t const SD_CHIP_SELECT_PIN = SOFT_SPI_CS_PIN; +#endif // SOFTWARE_SPI +//------------------------------------------------------------------------------ +/** + * \class Sd2Card + * \brief Raw access to SD and SDHC flash memory cards. + */ +class Sd2Card { + public: + /** Construct an instance of Sd2Card. */ + Sd2Card() : errorCode_(SD_CARD_ERROR_INIT_NOT_CALLED), type_(0) {} + uint32_t cardSize(); + bool erase(uint32_t firstBlock, uint32_t lastBlock); + bool eraseSingleBlockEnable(); + /** + * Set SD error code. + * \param[in] code value for error code. + */ + void error(uint8_t code) {errorCode_ = code;} + /** + * \return error code for last error. See Sd2Card.h for a list of error codes. + */ + int errorCode() const {return errorCode_;} + /** \return error data for last error. */ + int errorData() const {return status_;} + /** + * Initialize an SD flash memory card with default clock rate and chip + * select pin. See sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin). + * + * \return true for success or false for failure. + */ + bool init(uint8_t sckRateID = SPI_FULL_SPEED, + uint8_t chipSelectPin = SD_CHIP_SELECT_PIN); + bool readBlock(uint32_t block, uint8_t* dst); + /** + * Read a card's CID register. The CID contains card identification + * information such as Manufacturer ID, Product name, Product serial + * number and Manufacturing date. + * + * \param[out] cid pointer to area for returned data. + * + * \return true for success or false for failure. + */ + bool readCID(cid_t* cid) { + return readRegister(CMD10, cid); + } + /** + * Read a card's CSD register. The CSD contains Card-Specific Data that + * provides information regarding access to the card's contents. + * + * \param[out] csd pointer to area for returned data. + * + * \return true for success or false for failure. + */ + bool readCSD(csd_t* csd) { + return readRegister(CMD9, csd); + } + bool readData(uint8_t *dst); + bool readStart(uint32_t blockNumber); + bool readStop(); + bool setSckRate(uint8_t sckRateID); + /** Return the card type: SD V1, SD V2 or SDHC + * \return 0 - SD V1, 1 - SD V2, or 3 - SDHC. + */ + int type() const {return type_;} + bool writeBlock(uint32_t blockNumber, const uint8_t* src); + bool writeData(const uint8_t* src); + bool writeStart(uint32_t blockNumber, uint32_t eraseCount); + bool writeStop(); + + private: + //---------------------------------------------------------------------------- + uint8_t chipSelectPin_; + uint8_t errorCode_; + uint8_t spiRate_; + uint8_t status_; + uint8_t type_; + // private functions + uint8_t cardAcmd(uint8_t cmd, uint32_t arg) { + cardCommand(CMD55, 0); + return cardCommand(cmd, arg); + } + uint8_t cardCommand(uint8_t cmd, uint32_t arg); + bool readData(uint8_t* dst, size_t count); + bool readRegister(uint8_t cmd, void* buf); + void chipSelectHigh(); + void chipSelectLow(); + void type(uint8_t value) {type_ = value;} + bool waitNotBusy(uint16_t timeoutMillis); + bool writeData(uint8_t token, const uint8_t* src); +}; + +/** + * \file + * \brief FAT file structures + */ +/* + * mostly from Microsoft document fatgen103.doc + * http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx + */ +//------------------------------------------------------------------------------ +/** Value for byte 510 of boot block or MBR */ +uint8_t const BOOTSIG0 = 0X55; +/** Value for byte 511 of boot block or MBR */ +uint8_t const BOOTSIG1 = 0XAA; +/** Value for bootSignature field int FAT/FAT32 boot sector */ +uint8_t const EXTENDED_BOOT_SIG = 0X29; +//------------------------------------------------------------------------------ +/** + * \struct partitionTable + * \brief MBR partition table entry + * + * A partition table entry for a MBR formatted storage device. + * The MBR partition table has four entries. + */ +struct partitionTable { + /** + * Boot Indicator . Indicates whether the volume is the active + * partition. Legal values include: 0X00. Do not use for booting. + * 0X80 Active partition. + */ + uint8_t boot; + /** + * Head part of Cylinder-head-sector address of the first block in + * the partition. Legal values are 0-255. Only used in old PC BIOS. + */ + uint8_t beginHead; + /** + * Sector part of Cylinder-head-sector address of the first block in + * the partition. Legal values are 1-63. Only used in old PC BIOS. + */ + unsigned beginSector : 6; + /** High bits cylinder for first block in partition. */ + unsigned beginCylinderHigh : 2; + /** + * Combine beginCylinderLow with beginCylinderHigh. Legal values + * are 0-1023. Only used in old PC BIOS. + */ + uint8_t beginCylinderLow; + /** + * Partition type. See defines that begin with PART_TYPE_ for + * some Microsoft partition types. + */ + uint8_t type; + /** + * head part of cylinder-head-sector address of the last sector in the + * partition. Legal values are 0-255. Only used in old PC BIOS. + */ + uint8_t endHead; + /** + * Sector part of cylinder-head-sector address of the last sector in + * the partition. Legal values are 1-63. Only used in old PC BIOS. + */ + unsigned endSector : 6; + /** High bits of end cylinder */ + unsigned endCylinderHigh : 2; + /** + * Combine endCylinderLow with endCylinderHigh. Legal values + * are 0-1023. Only used in old PC BIOS. + */ + uint8_t endCylinderLow; + /** Logical block address of the first block in the partition. */ + uint32_t firstSector; + /** Length of the partition, in blocks. */ + uint32_t totalSectors; +} PACK; +/** Type name for partitionTable */ +typedef struct partitionTable part_t; +//------------------------------------------------------------------------------ +/** + * \struct masterBootRecord + * + * \brief Master Boot Record + * + * The first block of a storage device that is formatted with a MBR. + */ +struct masterBootRecord { + /** Code Area for master boot program. */ + uint8_t codeArea[440]; + /** Optional Windows NT disk signature. May contain boot code. */ + uint32_t diskSignature; + /** Usually zero but may be more boot code. */ + uint16_t usuallyZero; + /** Partition tables. */ + part_t part[4]; + /** First MBR signature byte. Must be 0X55 */ + uint8_t mbrSig0; + /** Second MBR signature byte. Must be 0XAA */ + uint8_t mbrSig1; +} PACK; +/** Type name for masterBootRecord */ +typedef struct masterBootRecord mbr_t; +//------------------------------------------------------------------------------ +/** + * \struct fat_boot + * + * \brief Boot sector for a FAT12/FAT16 volume. + * + */ +struct fat_boot { + /** + * The first three bytes of the boot sector must be valid, + * executable x 86-based CPU instructions. This includes a + * jump instruction that skips the next nonexecutable bytes. + */ + uint8_t jump[3]; + /** + * This is typically a string of characters that identifies + * the operating system that formatted the volume. + */ + char oemId[8]; + /** + * The size of a hardware sector. Valid decimal values for this + * field are 512, 1024, 2048, and 4096. For most disks used in + * the United States, the value of this field is 512. + */ + uint16_t bytesPerSector; + /** + * Number of sectors per allocation unit. This value must be a + * power of 2 that is greater than 0. The legal values are + * 1, 2, 4, 8, 16, 32, 64, and 128. 128 should be avoided. + */ + uint8_t sectorsPerCluster; + /** + * The number of sectors preceding the start of the first FAT, + * including the boot sector. The value of this field is always 1. + */ + uint16_t reservedSectorCount; + /** + * The number of copies of the FAT on the volume. + * The value of this field is always 2. + */ + uint8_t fatCount; + /** + * For FAT12 and FAT16 volumes, this field contains the count of + * 32-byte directory entries in the root directory. For FAT32 volumes, + * this field must be set to 0. For FAT12 and FAT16 volumes, this + * value should always specify a count that when multiplied by 32 + * results in a multiple of bytesPerSector. FAT16 volumes should + * use the value 512. + */ + uint16_t rootDirEntryCount; + /** + * This field is the old 16-bit total count of sectors on the volume. + * This count includes the count of all sectors in all four regions + * of the volume. This field can be 0; if it is 0, then totalSectors32 + * must be nonzero. For FAT32 volumes, this field must be 0. For + * FAT12 and FAT16 volumes, this field contains the sector count, and + * totalSectors32 is 0 if the total sector count fits + * (is less than 0x10000). + */ + uint16_t totalSectors16; + /** + * This dates back to the old MS-DOS 1.x media determination and is + * no longer usually used for anything. 0xF8 is the standard value + * for fixed (nonremovable) media. For removable media, 0xF0 is + * frequently used. Legal values are 0xF0 or 0xF8-0xFF. + */ + uint8_t mediaType; + /** + * Count of sectors occupied by one FAT on FAT12/FAT16 volumes. + * On FAT32 volumes this field must be 0, and sectorsPerFat32 + * contains the FAT size count. + */ + uint16_t sectorsPerFat16; + /** Sectors per track for interrupt 0x13. Not used otherwise. */ + uint16_t sectorsPerTrack; + /** Number of heads for interrupt 0x13. Not used otherwise. */ + uint16_t headCount; + /** + * Count of hidden sectors preceding the partition that contains this + * FAT volume. This field is generally only relevant for media + * visible on interrupt 0x13. + */ + uint32_t hidddenSectors; + /** + * This field is the new 32-bit total count of sectors on the volume. + * This count includes the count of all sectors in all four regions + * of the volume. This field can be 0; if it is 0, then + * totalSectors16 must be nonzero. + */ + uint32_t totalSectors32; + /** + * Related to the BIOS physical drive number. Floppy drives are + * identified as 0x00 and physical hard disks are identified as + * 0x80, regardless of the number of physical disk drives. + * Typically, this value is set prior to issuing an INT 13h BIOS + * call to specify the device to access. The value is only + * relevant if the device is a boot device. + */ + uint8_t driveNumber; + /** used by Windows NT - should be zero for FAT */ + uint8_t reserved1; + /** 0X29 if next three fields are valid */ + uint8_t bootSignature; + /** + * A random serial number created when formatting a disk, + * which helps to distinguish between disks. + * Usually generated by combining date and time. + */ + uint32_t volumeSerialNumber; + /** + * A field once used to store the volume label. The volume label + * is now stored as a special file in the root directory. + */ + char volumeLabel[11]; + /** + * A field with a value of either FAT, FAT12 or FAT16, + * depending on the disk format. + */ + char fileSystemType[8]; + /** X86 boot code */ + uint8_t bootCode[448]; + /** must be 0X55 */ + uint8_t bootSectorSig0; + /** must be 0XAA */ + uint8_t bootSectorSig1; +} PACK; +/** Type name for FAT Boot Sector */ +typedef struct fat_boot fat_boot_t; +//------------------------------------------------------------------------------ +/** + * \struct fat32_boot + * + * \brief Boot sector for a FAT32 volume. + * + */ +struct fat32_boot { + /** + * The first three bytes of the boot sector must be valid, + * executable x 86-based CPU instructions. This includes a + * jump instruction that skips the next nonexecutable bytes. + */ + uint8_t jump[3]; + /** + * This is typically a string of characters that identifies + * the operating system that formatted the volume. + */ + char oemId[8]; + /** + * The size of a hardware sector. Valid decimal values for this + * field are 512, 1024, 2048, and 4096. For most disks used in + * the United States, the value of this field is 512. + */ + uint16_t bytesPerSector; + /** + * Number of sectors per allocation unit. This value must be a + * power of 2 that is greater than 0. The legal values are + * 1, 2, 4, 8, 16, 32, 64, and 128. 128 should be avoided. + */ + uint8_t sectorsPerCluster; + /** + * The number of sectors preceding the start of the first FAT, + * including the boot sector. Must not be zero + */ + uint16_t reservedSectorCount; + /** + * The number of copies of the FAT on the volume. + * The value of this field is always 2. + */ + uint8_t fatCount; + /** + * FAT12/FAT16 only. For FAT32 volumes, this field must be set to 0. + */ + uint16_t rootDirEntryCount; + /** + * For FAT32 volumes, this field must be 0. + */ + uint16_t totalSectors16; + /** + * This dates back to the old MS-DOS 1.x media determination and is + * no longer usually used for anything. 0xF8 is the standard value + * for fixed (nonremovable) media. For removable media, 0xF0 is + * frequently used. Legal values are 0xF0 or 0xF8-0xFF. + */ + uint8_t mediaType; + /** + * On FAT32 volumes this field must be 0, and sectorsPerFat32 + * contains the FAT size count. + */ + uint16_t sectorsPerFat16; + /** Sectors per track for interrupt 0x13. Not used otherwise. */ + uint16_t sectorsPerTrack; + /** Number of heads for interrupt 0x13. Not used otherwise. */ + uint16_t headCount; + /** + * Count of hidden sectors preceding the partition that contains this + * FAT volume. This field is generally only relevant for media + * visible on interrupt 0x13. + */ + uint32_t hidddenSectors; + /** + * Contains the total number of sectors in the FAT32 volume. + */ + uint32_t totalSectors32; + /** + * Count of sectors occupied by one FAT on FAT32 volumes. + */ + uint32_t sectorsPerFat32; + /** + * This field is only defined for FAT32 media and does not exist on + * FAT12 and FAT16 media. + * Bits 0-3 -- Zero-based number of active FAT. + * Only valid if mirroring is disabled. + * Bits 4-6 -- Reserved. + * Bit 7 -- 0 means the FAT is mirrored at runtime into all FATs. + * -- 1 means only one FAT is active; it is the one referenced + * in bits 0-3. + * Bits 8-15 -- Reserved. + */ + uint16_t fat32Flags; + /** + * FAT32 version. High byte is major revision number. + * Low byte is minor revision number. Only 0.0 define. + */ + uint16_t fat32Version; + /** + * Cluster number of the first cluster of the root directory for FAT32. + * This usually 2 but not required to be 2. + */ + uint32_t fat32RootCluster; + /** + * Sector number of FSINFO structure in the reserved area of the + * FAT32 volume. Usually 1. + */ + uint16_t fat32FSInfo; + /** + * If nonzero, indicates the sector number in the reserved area + * of the volume of a copy of the boot record. Usually 6. + * No value other than 6 is recommended. + */ + uint16_t fat32BackBootBlock; + /** + * Reserved for future expansion. Code that formats FAT32 volumes + * should always set all of the bytes of this field to 0. + */ + uint8_t fat32Reserved[12]; + /** + * Related to the BIOS physical drive number. Floppy drives are + * identified as 0x00 and physical hard disks are identified as + * 0x80, regardless of the number of physical disk drives. + * Typically, this value is set prior to issuing an INT 13h BIOS + * call to specify the device to access. The value is only + * relevant if the device is a boot device. + */ + uint8_t driveNumber; + /** used by Windows NT - should be zero for FAT */ + uint8_t reserved1; + /** 0X29 if next three fields are valid */ + uint8_t bootSignature; + /** + * A random serial number created when formatting a disk, + * which helps to distinguish between disks. + * Usually generated by combining date and time. + */ + uint32_t volumeSerialNumber; + /** + * A field once used to store the volume label. The volume label + * is now stored as a special file in the root directory. + */ + char volumeLabel[11]; + /** + * A text field with a value of FAT32. + */ + char fileSystemType[8]; + /** X86 boot code */ + uint8_t bootCode[420]; + /** must be 0X55 */ + uint8_t bootSectorSig0; + /** must be 0XAA */ + uint8_t bootSectorSig1; +} PACK; +/** Type name for FAT32 Boot Sector */ +typedef struct fat32_boot fat32_boot_t; +//------------------------------------------------------------------------------ +/** Lead signature for a FSINFO sector */ +uint32_t const FSINFO_LEAD_SIG = 0x41615252; +/** Struct signature for a FSINFO sector */ +uint32_t const FSINFO_STRUCT_SIG = 0x61417272; +/** + * \struct fat32_fsinfo + * + * \brief FSINFO sector for a FAT32 volume. + * + */ +struct fat32_fsinfo { + /** must be 0X52, 0X52, 0X61, 0X41 */ + uint32_t leadSignature; + /** must be zero */ + uint8_t reserved1[480]; + /** must be 0X72, 0X72, 0X41, 0X61 */ + uint32_t structSignature; + /** + * Contains the last known free cluster count on the volume. + * If the value is 0xFFFFFFFF, then the free count is unknown + * and must be computed. Any other value can be used, but is + * not necessarily correct. It should be range checked at least + * to make sure it is <= volume cluster count. + */ + uint32_t freeCount; + /** + * This is a hint for the FAT driver. It indicates the cluster + * number at which the driver should start looking for free clusters. + * If the value is 0xFFFFFFFF, then there is no hint and the driver + * should start looking at cluster 2. + */ + uint32_t nextFree; + /** must be zero */ + uint8_t reserved2[12]; + /** must be 0X00, 0X00, 0X55, 0XAA */ + uint8_t tailSignature[4]; +} PACK; +/** Type name for FAT32 FSINFO Sector */ +typedef struct fat32_fsinfo fat32_fsinfo_t; +//------------------------------------------------------------------------------ +// End Of Chain values for FAT entries +/** FAT12 end of chain value used by Microsoft. */ +uint16_t const FAT12EOC = 0XFFF; +/** Minimum value for FAT12 EOC. Use to test for EOC. */ +uint16_t const FAT12EOC_MIN = 0XFF8; +/** FAT16 end of chain value used by Microsoft. */ +uint16_t const FAT16EOC = 0XFFFF; +/** Minimum value for FAT16 EOC. Use to test for EOC. */ +uint16_t const FAT16EOC_MIN = 0XFFF8; +/** FAT32 end of chain value used by Microsoft. */ +uint32_t const FAT32EOC = 0X0FFFFFFF; +/** Minimum value for FAT32 EOC. Use to test for EOC. */ +uint32_t const FAT32EOC_MIN = 0X0FFFFFF8; +/** Mask a for FAT32 entry. Entries are 28 bits. */ +uint32_t const FAT32MASK = 0X0FFFFFFF; + +// Reuse directory entries from deleted files +#define SD_CARD_REUSE_FAT_ENTRIES true +//------------------------------------------------------------------------------ +/** + * \struct directoryEntry + * \brief FAT short directory entry + * + * Short means short 8.3 name, not the entry size. + * + * Date Format. A FAT directory entry date stamp is a 16-bit field that is + * basically a date relative to the MS-DOS epoch of 01/01/1980. Here is the + * format (bit 0 is the LSB of the 16-bit word, bit 15 is the MSB of the + * 16-bit word): + * + * Bits 9-15: Count of years from 1980, valid value range 0-127 + * inclusive (1980-2107). + * + * Bits 5-8: Month of year, 1 = January, valid value range 1-12 inclusive. + * + * Bits 0-4: Day of month, valid value range 1-31 inclusive. + * + * Time Format. A FAT directory entry time stamp is a 16-bit field that has + * a granularity of 2 seconds. Here is the format (bit 0 is the LSB of the + * 16-bit word, bit 15 is the MSB of the 16-bit word). + * + * Bits 11-15: Hours, valid value range 0-23 inclusive. + * + * Bits 5-10: Minutes, valid value range 0-59 inclusive. + * + * Bits 0-4: 2-second count, valid value range 0-29 inclusive (0 - 58 seconds). + * + * The valid time range is from Midnight 00:00:00 to 23:59:58. + */ +struct directoryEntry { + /** Short 8.3 name. + * + * The first eight bytes contain the file name with blank fill. + * The last three bytes contain the file extension with blank fill. + */ + uint8_t name[11]; + /** Entry attributes. + * + * The upper two bits of the attribute byte are reserved and should + * always be set to 0 when a file is created and never modified or + * looked at after that. See defines that begin with DIR_ATT_. + */ + uint8_t attributes; + /** + * Reserved for use by Windows NT. Set value to 0 when a file is + * created and never modify or look at it after that. + */ + uint8_t reservedNT; + /** + * The granularity of the seconds part of creationTime is 2 seconds + * so this field is a count of tenths of a second and its valid + * value range is 0-199 inclusive. (WHG note - seems to be hundredths) + */ + uint8_t creationTimeTenths; + /** Time file was created. */ + uint16_t creationTime; + /** Date file was created. */ + uint16_t creationDate; + /** + * Last access date. Note that there is no last access time, only + * a date. This is the date of last read or write. In the case of + * a write, this should be set to the same date as lastWriteDate. + */ + uint16_t lastAccessDate; + /** + * High word of this entry's first cluster number (always 0 for a + * FAT12 or FAT16 volume). + */ + uint16_t firstClusterHigh; + /** Time of last write. File creation is considered a write. */ + uint16_t lastWriteTime; + /** Date of last write. File creation is considered a write. */ + uint16_t lastWriteDate; + /** Low word of this entry's first cluster number. */ + uint16_t firstClusterLow; + /** 32-bit unsigned holding this file's size in bytes. */ + uint32_t fileSize; +} PACK; + +// LONG FILENAME FAT ENTRY +struct directoryVFATEntry { + /** + * Sequence number. Consists of 2 parts: + * bit 6: indicates first long filename block for the next file + * bit 0-4: the position of this long filename block (first block is 1) + */ + uint8_t sequenceNumber; + /** First set of UTF-16 characters */ + uint16_t name1[5];//UTF-16 + /** attributes (at the same location as in directoryEntry), always 0x0F */ + uint8_t attributes; + /** Reserved for use by Windows NT. Always 0. */ + uint8_t reservedNT; + /** Checksum of the short 8.3 filename, can be used to checked if the file system as modified by a not-long-filename aware implementation. */ + uint8_t checksum; + /** Second set of UTF-16 characters */ + uint16_t name2[6];//UTF-16 + /** firstClusterLow is always zero for longFilenames */ + uint16_t firstClusterLow; + /** Third set of UTF-16 characters */ + uint16_t name3[2];//UTF-16 +} PACK; +typedef struct directoryVFATEntry vfat_t; + + +//------------------------------------------------------------------------------ +// Definitions for directory entries +// +/** Type name for directoryEntry */ +typedef struct directoryEntry dir_t; +/** escape for name[0] = 0XE5 */ +uint8_t const DIR_NAME_0XE5 = 0X05; +/** name[0] value for entry that is free after being "deleted" */ +uint8_t const DIR_NAME_DELETED = 0XE5; +/** name[0] value for entry that is free and no allocated entries follow */ +uint8_t const DIR_NAME_FREE = 0X00; +/** file is read-only */ +uint8_t const DIR_ATT_READ_ONLY = 0X01; +/** File should hidden in directory listings */ +uint8_t const DIR_ATT_HIDDEN = 0X02; +/** Entry is for a system file */ +uint8_t const DIR_ATT_SYSTEM = 0X04; +/** Directory entry contains the volume label */ +uint8_t const DIR_ATT_VOLUME_ID = 0X08; +/** Entry is for a directory */ +uint8_t const DIR_ATT_DIRECTORY = 0X10; +/** Old DOS archive bit for backup support */ +uint8_t const DIR_ATT_ARCHIVE = 0X20; +/** Test value for long name entry. Test is + (d->attributes & DIR_ATT_LONG_NAME_MASK) == DIR_ATT_LONG_NAME. */ +uint8_t const DIR_ATT_LONG_NAME = 0X0F; +/** Test mask for long name entry */ +uint8_t const DIR_ATT_LONG_NAME_MASK = 0X3F; +/** defined attribute bits */ +uint8_t const DIR_ATT_DEFINED_BITS = 0X3F; +/** Directory entry is part of a long name + * \param[in] dir Pointer to a directory entry. + * + * \return true if the entry is for part of a long name else false. + */ +static inline uint8_t DIR_IS_LONG_NAME(const dir_t* dir) { + return (dir->attributes & DIR_ATT_LONG_NAME_MASK) == DIR_ATT_LONG_NAME; +} +/** Mask for file/subdirectory tests */ +uint8_t const DIR_ATT_FILE_TYPE_MASK = (DIR_ATT_VOLUME_ID | DIR_ATT_DIRECTORY); +/** Directory entry is for a file + * \param[in] dir Pointer to a directory entry. + * + * \return true if the entry is for a normal file else false. + */ +static inline uint8_t DIR_IS_FILE(const dir_t* dir) { + return (dir->attributes & DIR_ATT_FILE_TYPE_MASK) == 0; +} +/** Directory entry is for a subdirectory + * \param[in] dir Pointer to a directory entry. + * + * \return true if the entry is for a subdirectory else false. + */ +static inline uint8_t DIR_IS_SUBDIR(const dir_t* dir) { + return (dir->attributes & DIR_ATT_FILE_TYPE_MASK) == DIR_ATT_DIRECTORY; +} +/** Directory entry is for a file or subdirectory + * \param[in] dir Pointer to a directory entry. + * + * \return true if the entry is for a normal file or subdirectory else false. + */ +static inline uint8_t DIR_IS_FILE_OR_SUBDIR(const dir_t* dir) { + return (dir->attributes & DIR_ATT_VOLUME_ID) == 0; +} + +//============================================================================== +// SdVolume class +/** + * \brief Cache for an SD data block + */ +union cache_t { + /** Used to access cached file data blocks. */ + uint8_t data[512]; + /** Used to access cached FAT16 entries. */ + uint16_t fat16[256]; + /** Used to access cached FAT32 entries. */ + uint32_t fat32[128]; + /** Used to access cached directory entries. */ + dir_t dir[16]; + /** Used to access a cached Master Boot Record. */ + mbr_t mbr; + /** Used to access to a cached FAT boot sector. */ + fat_boot_t fbs; + /** Used to access to a cached FAT32 boot sector. */ + fat32_boot_t fbs32; + /** Used to access to a cached FAT32 FSINFO sector. */ + fat32_fsinfo_t fsinfo; +} PACK; +//------------------------------------------------------------------------------ +/** + * \class SdVolume + * \brief Access FAT16 and FAT32 volumes on SD and SDHC cards. + */ +class SdVolume { + public: + /** Create an instance of SdVolume */ + SdVolume() : fatType_(0) {} + /** Clear the cache and returns a pointer to the cache. Used by the WaveRP + * recorder to do raw write to the SD card. Not for normal apps. + * \return A pointer to the cache buffer or zero if an error occurs. + */ + cache_t* cacheClear() { + if (!cacheSync()) return 0; + cacheBlockNumber_ = 0XFFFFFFFF; + return &cacheBuffer_; + } + /** Initialize a FAT volume. Try partition one first then try super + * floppy format. + * + * \param[in] dev The Sd2Card where the volume is located. + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. Reasons for + * failure include not finding a valid partition, not finding a valid + * FAT file system or an I/O error. + */ + bool init(Sd2Card* dev) { return init(dev, 1) ? true : init(dev, 0);} + bool init(Sd2Card* dev, uint8_t part); + + // inline functions that return volume info + /** \return The volume's cluster size in blocks. */ + uint8_t blocksPerCluster() const {return blocksPerCluster_;} + /** \return The number of blocks in one FAT. */ + uint32_t blocksPerFat() const {return blocksPerFat_;} + /** \return The total number of clusters in the volume. */ + uint32_t clusterCount() const {return clusterCount_;} + /** \return The shift count required to multiply by blocksPerCluster. */ + uint8_t clusterSizeShift() const {return clusterSizeShift_;} + /** \return The logical block number for the start of file data. */ + uint32_t dataStartBlock() const {return dataStartBlock_;} + /** \return The number of FAT structures on the volume. */ + uint8_t fatCount() const {return fatCount_;} + /** \return The logical block number for the start of the first FAT. */ + uint32_t fatStartBlock() const {return fatStartBlock_;} + /** \return The FAT type of the volume. Values are 12, 16 or 32. */ + uint8_t fatType() const {return fatType_;} + int32_t freeClusterCount(); + /** \return The number of entries in the root directory for FAT16 volumes. */ + uint32_t rootDirEntryCount() const {return rootDirEntryCount_;} + /** \return The logical block number for the start of the root directory + on FAT16 volumes or the first cluster number on FAT32 volumes. */ + uint32_t rootDirStart() const {return rootDirStart_;} + /** Sd2Card object for this volume + * \return pointer to Sd2Card object. + */ + Sd2Card* sdCard() {return sdCard_;} + /** Debug access to FAT table + * + * \param[in] n cluster number. + * \param[out] v value of entry + * \return true for success or false for failure + */ + bool dbgFat(uint32_t n, uint32_t* v) {return fatGet(n, v);} +//------------------------------------------------------------------------------ + private: + // Allow SdBaseFile access to SdVolume private data. + friend class SdBaseFile; +//------------------------------------------------------------------------------ + uint32_t allocSearchStart_; // start cluster for alloc search + uint8_t blocksPerCluster_; // cluster size in blocks + uint32_t blocksPerFat_; // FAT size in blocks + uint32_t clusterCount_; // clusters in one FAT + uint8_t clusterSizeShift_; // shift to convert cluster count to block count + uint32_t dataStartBlock_; // first data block number + uint8_t fatCount_; // number of FATs on volume + uint32_t fatStartBlock_; // start block for first FAT + uint8_t fatType_; // volume type (12, 16, OR 32) + uint16_t rootDirEntryCount_; // number of entries in FAT16 root dir + uint32_t rootDirStart_; // root start block for FAT16, cluster for FAT32 +//------------------------------------------------------------------------------ +// block caches +// use of static functions save a bit of flash - maybe not worth complexity +// + static const uint8_t CACHE_STATUS_DIRTY = 1; + static const uint8_t CACHE_STATUS_FAT_BLOCK = 2; + static const uint8_t CACHE_STATUS_MASK + = CACHE_STATUS_DIRTY | CACHE_STATUS_FAT_BLOCK; + static const uint8_t CACHE_OPTION_NO_READ = 4; + // value for option argument in cacheFetch to indicate read from cache + static uint8_t const CACHE_FOR_READ = 0; + // value for option argument in cacheFetch to indicate write to cache + static uint8_t const CACHE_FOR_WRITE = CACHE_STATUS_DIRTY; + // reserve cache block with no read + static uint8_t const CACHE_RESERVE_FOR_WRITE + = CACHE_STATUS_DIRTY | CACHE_OPTION_NO_READ; +#if USE_MULTIPLE_CARDS + cache_t cacheBuffer_; // 512 byte cache for device blocks + uint32_t cacheBlockNumber_; // Logical number of block in the cache + uint32_t cacheFatOffset_; // offset for mirrored FAT + Sd2Card* sdCard_; // Sd2Card object for cache + uint8_t cacheStatus_; // status of cache block +#if USE_SEPARATE_FAT_CACHE + cache_t cacheFatBuffer_; // 512 byte cache for FAT + uint32_t cacheFatBlockNumber_; // current Fat block number + uint8_t cacheFatStatus_; // status of cache Fatblock +#endif // USE_SEPARATE_FAT_CACHE +#else // USE_MULTIPLE_CARDS + static cache_t cacheBuffer_; // 512 byte cache for device blocks + static uint32_t cacheBlockNumber_; // Logical number of block in the cache + static uint32_t cacheFatOffset_; // offset for mirrored FAT + static uint8_t cacheStatus_; // status of cache block +#if USE_SEPARATE_FAT_CACHE + static cache_t cacheFatBuffer_; // 512 byte cache for FAT + static uint32_t cacheFatBlockNumber_; // current Fat block number + static uint8_t cacheFatStatus_; // status of cache Fatblock +#endif // USE_SEPARATE_FAT_CACHE + static Sd2Card* sdCard_; // Sd2Card object for cache +#endif // USE_MULTIPLE_CARDS + + cache_t *cacheAddress() {return &cacheBuffer_;} + uint32_t cacheBlockNumber() {return cacheBlockNumber_;} +#if USE_MULTIPLE_CARDS + cache_t* cacheFetch(uint32_t blockNumber, uint8_t options); + cache_t* cacheFetchData(uint32_t blockNumber, uint8_t options); + cache_t* cacheFetchFat(uint32_t blockNumber, uint8_t options); + void cacheInvalidate(); + bool cacheSync(); + bool cacheWriteData(); + bool cacheWriteFat(); +#else // USE_MULTIPLE_CARDS + static cache_t* cacheFetch(uint32_t blockNumber, uint8_t options); + static cache_t* cacheFetchData(uint32_t blockNumber, uint8_t options); + static cache_t* cacheFetchFat(uint32_t blockNumber, uint8_t options); + static void cacheInvalidate(); + static bool cacheSync(); + static bool cacheWriteData(); + static bool cacheWriteFat(); +#endif // USE_MULTIPLE_CARDS +//------------------------------------------------------------------------------ + bool allocContiguous(uint32_t count, uint32_t* curCluster); + uint8_t blockOfCluster(uint32_t position) const { + return (position >> 9) & (blocksPerCluster_ - 1);} + uint32_t clusterStartBlock(uint32_t cluster) const; + bool fatGet(uint32_t cluster, uint32_t* value); + bool fatPut(uint32_t cluster, uint32_t value); + bool fatPutEOC(uint32_t cluster) { + return fatPut(cluster, 0x0FFFFFFF); + } + bool freeChain(uint32_t cluster); + bool isEOC(uint32_t cluster) const { + if (FAT12_SUPPORT && fatType_ == 12) return cluster >= FAT12EOC_MIN; + if (fatType_ == 16) return cluster >= FAT16EOC_MIN; + return cluster >= FAT32EOC_MIN; + } + bool readBlock(uint32_t block, uint8_t* dst) { + return sdCard_->readBlock(block, dst);} + bool writeBlock(uint32_t block, const uint8_t* dst) { + return sdCard_->writeBlock(block, dst); + } +//------------------------------------------------------------------------------ + // Deprecated functions - suppress cpplint warnings with NOLINT comment +#if ALLOW_DEPRECATED_FUNCTIONS && !defined(DOXYGEN) + + public: + /** \deprecated Use: bool SdVolume::init(Sd2Card* dev); + * \param[in] dev The SD card where the volume is located. + * \return true for success or false for failure. + */ + bool init(Sd2Card& dev) {return init(&dev);} // NOLINT + /** \deprecated Use: bool SdVolume::init(Sd2Card* dev, uint8_t vol); + * \param[in] dev The SD card where the volume is located. + * \param[in] part The partition to be used. + * \return true for success or false for failure. + */ + bool init(Sd2Card& dev, uint8_t part) { // NOLINT + return init(&dev, part); + } +#endif // ALLOW_DEPRECATED_FUNCTIONS +}; + +//------------------------------------------------------------------------------ +/** + * \struct FatPos_t + * \brief internal type for istream + * do not use in user apps + */ +struct FatPos_t { + /** stream position */ + uint32_t position; + /** cluster for position */ + uint32_t cluster; + FatPos_t() : position(0), cluster(0) {} +}; + +// use the gnu style oflag in open() +/** open() oflag for reading */ +uint8_t const O_READ = 0X01; +/** open() oflag - same as O_IN */ +uint8_t const O_RDONLY = O_READ; +/** open() oflag for write */ +uint8_t const O_WRITE = 0X02; +/** open() oflag - same as O_WRITE */ +uint8_t const O_WRONLY = O_WRITE; +/** open() oflag for reading and writing */ +uint8_t const O_RDWR = (O_READ | O_WRITE); +/** open() oflag mask for access modes */ +uint8_t const O_ACCMODE = (O_READ | O_WRITE); +/** The file offset shall be set to the end of the file prior to each write. */ +uint8_t const O_APPEND = 0X04; +/** synchronous writes - call sync() after each write */ +uint8_t const O_SYNC = 0X08; +/** truncate the file to zero length */ +uint8_t const O_TRUNC = 0X10; +/** set the initial position at the end of the file */ +uint8_t const O_AT_END = 0X20; +/** create the file if nonexistent */ +uint8_t const O_CREAT = 0X40; +/** If O_CREAT and O_EXCL are set, open() shall fail if the file exists */ +uint8_t const O_EXCL = 0X80; + +// SdBaseFile class static and const definitions +// flags for ls() +/** ls() flag to print modify date */ +uint8_t const LS_DATE = 1; +/** ls() flag to print file size */ +uint8_t const LS_SIZE = 2; +/** ls() flag for recursive list of subdirectories */ +uint8_t const LS_R = 4; + + +// flags for timestamp +/** set the file's last access date */ +uint8_t const T_ACCESS = 1; +/** set the file's creation date and time */ +uint8_t const T_CREATE = 2; +/** Set the file's write date and time */ +uint8_t const T_WRITE = 4; +// values for type_ +/** This file has not been opened. */ +uint8_t const FAT_FILE_TYPE_CLOSED = 0; +/** A normal file */ +uint8_t const FAT_FILE_TYPE_NORMAL = 1; +/** A FAT12 or FAT16 root directory */ +uint8_t const FAT_FILE_TYPE_ROOT_FIXED = 2; +/** A FAT32 root directory */ +uint8_t const FAT_FILE_TYPE_ROOT32 = 3; +/** A subdirectory file*/ +uint8_t const FAT_FILE_TYPE_SUBDIR = 4; +/** Test value for directory type */ +uint8_t const FAT_FILE_TYPE_MIN_DIR = FAT_FILE_TYPE_ROOT_FIXED; + +/** date field for FAT directory entry + * \param[in] year [1980,2107] + * \param[in] month [1,12] + * \param[in] day [1,31] + * + * \return Packed date for dir_t entry. + */ +static inline uint16_t FAT_DATE(uint16_t year, uint8_t month, uint8_t day) { + return (year - 1980) << 9 | month << 5 | day; +} +/** year part of FAT directory date field + * \param[in] fatDate Date in packed dir format. + * + * \return Extracted year [1980,2107] + */ +static inline uint16_t FAT_YEAR(uint16_t fatDate) { + return 1980 + (fatDate >> 9); +} +/** month part of FAT directory date field + * \param[in] fatDate Date in packed dir format. + * + * \return Extracted month [1,12] + */ +static inline uint8_t FAT_MONTH(uint16_t fatDate) { + return (fatDate >> 5) & 0XF; +} +/** day part of FAT directory date field + * \param[in] fatDate Date in packed dir format. + * + * \return Extracted day [1,31] + */ +static inline uint8_t FAT_DAY(uint16_t fatDate) { + return fatDate & 0X1F; +} +/** time field for FAT directory entry + * \param[in] hour [0,23] + * \param[in] minute [0,59] + * \param[in] second [0,59] + * + * \return Packed time for dir_t entry. + */ +static inline uint16_t FAT_TIME(uint8_t hour, uint8_t minute, uint8_t second) { + return hour << 11 | minute << 5 | second >> 1; +} +/** hour part of FAT directory time field + * \param[in] fatTime Time in packed dir format. + * + * \return Extracted hour [0,23] + */ +static inline uint8_t FAT_HOUR(uint16_t fatTime) { + return fatTime >> 11; +} +/** minute part of FAT directory time field + * \param[in] fatTime Time in packed dir format. + * + * \return Extracted minute [0,59] + */ +static inline uint8_t FAT_MINUTE(uint16_t fatTime) { + return(fatTime >> 5) & 0X3F; +} +/** second part of FAT directory time field + * Note second/2 is stored in packed time. + * + * \param[in] fatTime Time in packed dir format. + * + * \return Extracted second [0,58] + */ +static inline uint8_t FAT_SECOND(uint16_t fatTime) { + return 2*(fatTime & 0X1F); +} +/** Default date for file timestamps is 1 Jan 2000 */ +uint16_t const FAT_DEFAULT_DATE = ((2000 - 1980) << 9) | (1 << 5) | 1; +/** Default time for file timestamp is 1 am */ +uint16_t const FAT_DEFAULT_TIME = (1 << 11); +//------------------------------------------------------------------------------ +/** + * \class SdBaseFile + * \brief Base class for SdFile with Print and C++ streams. + */ +class SdBaseFile { + public: + /** Create an instance. */ + SdBaseFile() : writeError(false), type_(FAT_FILE_TYPE_CLOSED) {} + SdBaseFile(const char* path, uint8_t oflag); + #if DESTRUCTOR_CLOSES_FILE + ~SdBaseFile() {if(isOpen()) close();} + #endif + /** + * writeError is set to true if an error occurs during a write(). + * Set writeError to false before calling print() and/or write() and check + * for true after calls to print() and/or write(). + */ + bool writeError; + /** \return value of writeError */ + bool getWriteError() {return writeError;} + /** Set writeError to zero */ + void clearWriteError() {writeError = 0;} + //---------------------------------------------------------------------------- + // helpers for stream classes + /** get position for streams + * \param[out] pos struct to receive position + */ + void getpos(FatPos_t* pos); + /** set position for streams + * \param[out] pos struct with value for new position + */ + void setpos(FatPos_t* pos); + //---------------------------------------------------------------------------- + /** \return number of bytes available from yhe current position to EOF */ + uint32_t available() {return fileSize() - curPosition();} + bool close(); + bool contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock); + bool createContiguous(SdBaseFile* dirFile, + const char* path, uint32_t size); + /** \return The current cluster number for a file or directory. */ + uint32_t curCluster() const {return curCluster_;} + /** \return The current position for a file or directory. */ + uint32_t curPosition() const {return curPosition_;} + /** \return Current working directory */ + static SdBaseFile* cwd() {return cwd_;} + /** Set the date/time callback function + * + * \param[in] dateTime The user's call back function. The callback + * function is of the form: + * + * \code + * void dateTime(uint16_t* date, uint16_t* time) { + * uint16_t year; + * uint8_t month, day, hour, minute, second; + * + * // User gets date and time from GPS or real-time clock here + * + * // return date using FAT_DATE macro to format fields + * *date = FAT_DATE(year, month, day); + * + * // return time using FAT_TIME macro to format fields + * *time = FAT_TIME(hour, minute, second); + * } + * \endcode + * + * Sets the function that is called when a file is created or when + * a file's directory entry is modified by sync(). All timestamps, + * access, creation, and modify, are set when a file is created. + * sync() maintains the last access date and last modify date/time. + * + * See the timestamp() function. + */ + static void dateTimeCallback( + void (*dateTime)(uint16_t* date, uint16_t* time)) { + dateTime_ = dateTime; + } + /** Cancel the date/time callback function. */ + static void dateTimeCallbackCancel() {dateTime_ = 0;} + bool dirEntry(dir_t* dir); + static void dirName(const dir_t& dir, char* name); + bool exists(const char* name); + int16_t fgets(char* str, int16_t num, char* delim = 0); + /** \return The total number of bytes in a file or directory. */ + uint32_t fileSize() const {return fileSize_;} + /** \return The first cluster number for a file or directory. */ + uint32_t firstCluster() const {return firstCluster_;} + bool getFilename(char* name); + uint8_t lfn_checksum(const unsigned char *pFCBName); + bool openParentReturnFile(SdBaseFile* dirFile, const char* path, uint8_t *dname, SdBaseFile *newParent, boolean bMakeDirs); + + + /** \return True if this is a directory else false. */ + bool isDir() const {return type_ >= FAT_FILE_TYPE_MIN_DIR;} + /** \return True if this is a normal file else false. */ + bool isFile() const {return type_ == FAT_FILE_TYPE_NORMAL;} + /** \return True if this is an open file/directory else false. */ + bool isOpen() const {return type_ != FAT_FILE_TYPE_CLOSED;} + /** \return True if this is a subdirectory else false. */ + bool isSubDir() const {return type_ == FAT_FILE_TYPE_SUBDIR;} + /** \return True if this is the root directory. */ + bool isRoot() const { + return type_ == FAT_FILE_TYPE_ROOT_FIXED || type_ == FAT_FILE_TYPE_ROOT32; + } + void ls(uint8_t flags = 0, uint8_t indent = 0); + void ls(uint8_t flags = 0); + bool mkdir(SdBaseFile* dir, const char* path, bool pFlag = true); + // alias for backward compactability + bool makeDir(SdBaseFile* dir, const char* path) { + return mkdir(dir, path, false); + } + bool open(SdBaseFile* dirFile, uint16_t index, uint8_t oflag); + bool open(SdBaseFile* dirFile, const char* path, uint8_t oflag); + bool open(const char* path, uint8_t oflag = O_READ); + bool openNext(SdBaseFile* dirFile, uint8_t oflag); + bool openRoot(SdVolume* vol); + int8_t readDir(dir_t& dir, char *longfilename) {return readDir(&dir, longfilename);} + int peek(); + bool printCreateDateTime(); + static void printFatDate(uint16_t fatDate); + static void printFatTime(uint16_t fatTime); + bool printModifyDateTime(); + int printField(int16_t value, char term); + int printField(uint16_t value, char term); + int printField(int32_t value, char term); + int printField(uint32_t value, char term); + bool printName(); + int16_t read(); + int read(void* buf, size_t nbyte); + int8_t readDir(dir_t* dir, char *longfilename); + + static bool remove(SdBaseFile* dirFile, const char* path); + bool remove(); + /** Set the file's current position to zero. */ + void rewind() {seekSet(0);} + bool rename(SdBaseFile* dirFile, const char* newPath); + bool rmdir(); + // for backward compatibility + bool rmDir() {return rmdir();} + bool rmRfStar(); + /** Set the files position to current position + \a pos. See seekSet(). + * \param[in] offset The new position in bytes from the current position. + * \return true for success or false for failure. + */ + bool seekCur(int32_t offset) { + return seekSet(curPosition_ + offset); + } + /** Set the files position to end-of-file + \a offset. See seekSet(). + * \param[in] offset The new position in bytes from end-of-file. + * \return true for success or false for failure. + */ + bool seekEnd(int32_t offset = 0) {return seekSet(fileSize_ + offset);} + bool seekSet(uint32_t pos); + bool sync(); + bool timestamp(SdBaseFile* file); + bool timestamp(uint8_t flag, uint16_t year, uint8_t month, uint8_t day, + uint8_t hour, uint8_t minute, uint8_t second); + /** Type of file. You should use isFile() or isDir() instead of type() + * if possible. + * + * \return The file or directory type. + */ + uint8_t type() const {return type_;} + bool truncate(uint32_t size); + /** \return SdVolume that contains this file. */ + SdVolume* volume() const {return vol_;} + int write(const void* buf, size_t nbyte); +//------------------------------------------------------------------------------ + public: + // allow SdFat to set cwd_ + friend class SdFat; + // global pointer to cwd dir + static SdBaseFile* cwd_; + // data time callback function + static void (*dateTime_)(uint16_t* date, uint16_t* time); + // bits defined in flags_ + // should be 0X0F + static uint8_t const F_OFLAG = (O_ACCMODE | O_APPEND | O_SYNC); + // sync of directory entry required + static uint8_t const F_FILE_DIR_DIRTY = 0X80; + + // private data + uint8_t flags_; // See above for definition of flags_ bits + uint8_t fstate_; // error and eof indicator + uint8_t type_; // type of file see above for values + uint8_t dirIndex_; // index of directory entry in dirBlock + SdVolume* vol_; // volume where file is located + uint32_t curCluster_; // cluster for current file position + uint32_t curPosition_; // current file position in bytes from beginning + uint32_t dirBlock_; // block for this files directory entry + uint32_t fileSize_; // file size in bytes + uint32_t firstCluster_; // first cluster of file + char *pathend; + + + + /** experimental don't use */ + bool openParent(SdBaseFile* dir); + // private functions + bool addCluster(); + cache_t* addDirCluster(); + dir_t* cacheDirEntry(uint8_t action); + int8_t lsPrintNext(uint8_t flags, uint8_t indent); + static bool make83Name(const char* str, uint8_t* name, const char** ptr); + bool mkdir(SdBaseFile* parent, const uint8_t *dname); + bool open(SdBaseFile* dirFile, const uint8_t *dname, uint8_t oflag, bool bDir); + bool openCachedEntry(uint8_t cacheIndex, uint8_t oflags); + dir_t* readDirCache(); + dir_t* readDirCacheSpecial(); + dir_t *getLongFilename(dir_t *dir, char *longFilename, int8_t cVFATNeeded, uint32_t *pwIndexPos); + bool findSpace(dir_t *dir, int8_t cVFATNeeded, int8_t *pcVFATFound, uint32_t *pwIndexPos); + uint8_t lsRecursive(SdBaseFile *parent, uint8_t level, char *findFilename, SdBaseFile *pParentFound, bool isJson); + + bool setDirSize(); +//------------------------------------------------------------------------------ +// to be deleted + static void printDirName(const dir_t& dir, + uint8_t width, bool printSlash); +//------------------------------------------------------------------------------ +// Deprecated functions - suppress cpplint warnings with NOLINT comment +#if ALLOW_DEPRECATED_FUNCTIONS && !defined(DOXYGEN) + + public: + /** \deprecated Use: + * bool contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock); + * \param[out] bgnBlock the first block address for the file. + * \param[out] endBlock the last block address for the file. + * \return true for success or false for failure. + */ + bool contiguousRange(uint32_t& bgnBlock, uint32_t& endBlock) { // NOLINT + return contiguousRange(&bgnBlock, &endBlock); + } + /** \deprecated Use: + * bool createContiguous(SdBaseFile* dirFile, + * const char* path, uint32_t size) + * \param[in] dirFile The directory where the file will be created. + * \param[in] path A path with a valid DOS 8.3 file name. + * \param[in] size The desired file size. + * \return true for success or false for failure. + */ + bool createContiguous(SdBaseFile& dirFile, // NOLINT + const char* path, uint32_t size) { + return createContiguous(&dirFile, path, size); + } + /** \deprecated Use: + * static void dateTimeCallback( + * void (*dateTime)(uint16_t* date, uint16_t* time)); + * \param[in] dateTime The user's call back function. + */ + static void dateTimeCallback( + void (*dateTime)(uint16_t& date, uint16_t& time)) { // NOLINT + oldDateTime_ = dateTime; + dateTime_ = dateTime ? oldToNew : 0; + } + /** \deprecated Use: bool dirEntry(dir_t* dir); + * \param[out] dir Location for return of the file's directory entry. + * \return true for success or false for failure. + */ + bool dirEntry(dir_t& dir) {return dirEntry(&dir);} // NOLINT + /** \deprecated Use: + * bool mkdir(SdBaseFile* dir, const char* path); + * \param[in] dir An open SdFat instance for the directory that will contain + * the new directory. + * \param[in] path A path with a valid 8.3 DOS name for the new directory. + * \return true for success or false for failure. + */ + bool mkdir(SdBaseFile& dir, const char* path) { // NOLINT + return mkdir(&dir, path); + } + /** \deprecated Use: + * bool open(SdBaseFile* dirFile, const char* path, uint8_t oflag); + * \param[in] dirFile An open SdFat instance for the directory containing the + * file to be opened. + * \param[in] path A path with a valid 8.3 DOS name for the file. + * \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive + * OR of flags O_READ, O_WRITE, O_TRUNC, and O_SYNC. + * \return true for success or false for failure. + */ + bool open(SdBaseFile& dirFile, // NOLINT + const char* path, uint8_t oflag) { + return open(&dirFile, path, oflag); + } + /** \deprecated Do not use in new apps + * \param[in] dirFile An open SdFat instance for the directory containing the + * file to be opened. + * \param[in] path A path with a valid 8.3 DOS name for a file to be opened. + * \return true for success or false for failure. + */ + bool open(SdBaseFile& dirFile, const char* path) { // NOLINT + return open(dirFile, path, O_RDWR); + } + /** \deprecated Use: + * bool open(SdBaseFile* dirFile, uint16_t index, uint8_t oflag); + * \param[in] dirFile An open SdFat instance for the directory. + * \param[in] index The \a index of the directory entry for the file to be + * opened. The value for \a index is (directory file position)/32. + * \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive + * OR of flags O_READ, O_WRITE, O_TRUNC, and O_SYNC. + * \return true for success or false for failure. + */ + bool open(SdBaseFile& dirFile, uint16_t index, uint8_t oflag) { // NOLINT + return open(&dirFile, index, oflag); + } + /** \deprecated Use: bool openRoot(SdVolume* vol); + * \param[in] vol The FAT volume containing the root directory to be opened. + * \return true for success or false for failure. + */ + bool openRoot(SdVolume& vol) {return openRoot(&vol);} // NOLINT + /** \deprecated Use: int8_t readDir(dir_t* dir); + * \param[out] dir The dir_t struct that will receive the data. + * \return bytes read for success zero for eof or -1 for failure. + */ + int8_t readDir(dir_t& dir) {return readDir(&dir);} // NOLINT + /** \deprecated Use: + * static uint8_t remove(SdBaseFile* dirFile, const char* path); + * \param[in] dirFile The directory that contains the file. + * \param[in] path The name of the file to be removed. + * \return true for success or false for failure. + */ + static bool remove(SdBaseFile& dirFile, const char* path) { // NOLINT + return remove(&dirFile, path); + } +//------------------------------------------------------------------------------ +// rest are private + private: + static void (*oldDateTime_)(uint16_t& date, uint16_t& time); // NOLINT + static void oldToNew(uint16_t* date, uint16_t* time) { + uint16_t d; + uint16_t t; + oldDateTime_(d, t); + *date = d; + *time = t; + } +#elif !defined(DOXYGEN) // ALLOW_DEPRECATED_FUNCTIONS + public: + bool contiguousRange(uint32_t& bgnBlock, uint32_t& endBlock) // NOLINT + __attribute__((error("use contiguousRange(&bgnBlock, &endBlock)"))); + bool createContiguous(SdBaseFile& dirFile, // NOLINT + const char* path, uint32_t size) + __attribute__((error("use createContiguous(&bgnBlock, &endBlock)"))); + static void dateTimeCallback( // NOLINT + void (*dateTime)(uint16_t& date, uint16_t& time)) // NOLINT + __attribute__((error("use void dateTimeCallback(" + "void (*dateTime)(uint16_t* date, uint16_t* time))"))); + bool dirEntry(dir_t& dir) // NOLINT + __attribute__((error("use dirEntry(&dir)"))); + bool mkdir(SdBaseFile& dir, const char* path) // NOLINT + __attribute__((error("use mkdir(&dir, path)"))); + bool open(SdBaseFile& dirFile, // NOLINT + const char* path, uint8_t oflag) + __attribute__((error("use open(&dirFile, path, oflag)"))); + bool open(SdBaseFile& dirFile, const char* path) // NOLINT + __attribute__((error("use open(&dirFile, path, O_RDWR)"))); + bool open(SdBaseFile& dirFile, uint16_t index, uint8_t oflag) // NOLINT + __attribute__((error("use open(&dirFile, index, oflag)"))); + bool openRoot(SdVolume& vol) // NOLINT + __attribute__((error("use openRoot(&vol)"))); + int8_t readDir(dir_t& dir) // NOLINT + __attribute__((error("use readDir(&dir)"))); + static bool remove(SdBaseFile& dirFile, const char* path) // NOLINT + __attribute__((error("use remove(&dirFile, path)"))); +#endif // ALLOW_DEPRECATED_FUNCTIONS +#if JSON_OUTPUT + void lsJSON(); +#endif +}; +//------------------------------------------------------------------------------ +/** + * \class SdFile + * \brief SdBaseFile with Print. + */ +class SdFile : public SdBaseFile { + public: + SdFile() {} + SdFile(const char* name, uint8_t oflag); +#if DESTRUCTOR_CLOSES_FILE + ~SdFile() {} +#endif // DESTRUCTOR_CLOSES_FILE + /** \return value of writeError */ + bool getWriteError() {return SdBaseFile::getWriteError();} + /** Set writeError to zero */ + void clearWriteError() {SdBaseFile::clearWriteError();} +#ifdef COMPAT_PRE1 + void write(uint8_t b); +#else + size_t write(uint8_t b); +#endif + int write(const char* str); + int write(const void* buf, size_t nbyte); + void write_P(FSTRINGPARAM(str)); + void writeln_P(FSTRINGPARAM(str)); +}; +/** Store and print a string in flash memory.*/ +#define PgmPrint(x) SerialPrint_P(PSTR(x)) +/** Store and print a string in flash memory followed by a CR/LF.*/ +#define PgmPrintln(x) SerialPrintln_P(PSTR(x)) + +namespace SdFatUtil { + int FreeRam(); + void SerialPrint_P(FSTRINGPARAM(str)); + void SerialPrintln_P(FSTRINGPARAM(str)); +} + +using namespace SdFatUtil; // NOLINT + +//#include +//#include +//------------------------------------------------------------------------------ +/** + * \class SdFat + * \brief Integration class for the %SdFat library. + */ +class SdFat { + public: + SdFat() {} +#if ALLOW_DEPRECATED_FUNCTIONS && !defined(DOXYGEN) + /** + * Initialize an SdFat object. + * + * Initializes the SD card, SD volume, and root directory. + * + * \param[in] sckRateID value for SPI SCK rate. See Sd2Card::init(). + * \param[in] chipSelectPin SD chip select pin. See Sd2Card::init(). + * + * \return The value one, true, is returned for success and + * the value zero, false, is returned for failure. + */ + + bool init(uint8_t sckRateID = SPI_FULL_SPEED, + uint8_t chipSelectPin = SD_CHIP_SELECT_PIN) { + return begin(chipSelectPin, sckRateID); + } +#elif !defined(DOXYGEN) // ALLOW_DEPRECATED_FUNCTIONS + bool init() __attribute__((error("use sd.begin()"))); + bool init(uint8_t sckRateID) + __attribute__((error("use sd.begin(chipSelect, sckRate)"))); + bool init(uint8_t sckRateID, uint8_t chipSelectPin) + __attribute__((error("use sd.begin(chipSelect, sckRate)"))); +#endif // ALLOW_DEPRECATED_FUNCTIONS + /** \return a pointer to the Sd2Card object. */ + Sd2Card* card() {return &card_;} + bool chdir(bool set_cwd = false); + bool chdir(const char* path, bool set_cwd = false); + void chvol(); + void errorHalt(); + void errorHalt_P(FSTRINGPARAM(msg)); + void errorHalt(char const *msg); + void errorPrint(); + void errorPrint_P(FSTRINGPARAM(msg)); + void errorPrint(char const *msg); + bool exists(const char* name); + bool begin(uint8_t chipSelectPin = SD_CHIP_SELECT_PIN, + uint8_t sckRateID = SPI_FULL_SPEED); + void initErrorHalt(); + void initErrorHalt(char const *msg); + void initErrorHalt_P(FSTRINGPARAM(msg)); + void initErrorPrint(); + void initErrorPrint(char const *msg); + void initErrorPrint_P(FSTRINGPARAM(msg)); + void ls(uint8_t flags = 0); + bool mkdir(const char* path, bool pFlag = true); + bool remove(const char* path); + bool rename(const char *oldPath, const char *newPath); + bool rmdir(const char* path); + bool truncate(const char* path, uint32_t length); + /** \return a pointer to the SdVolume object. */ + SdVolume* vol() {return &vol_;} + /** \return a pointer to the volume working directory. */ + SdBaseFile* vwd() {return &vwd_;} + //---------------------------------------------------------------------------- + // static functions for stdOut + + private: + Sd2Card card_; + SdVolume vol_; + SdBaseFile vwd_; +}; +#endif // SdFat_h diff --git a/trunk/Arduino/Repetier_0.92.9/fastio.h b/trunk/Arduino/Repetier_0.92.9/fastio.h new file mode 100644 index 00000000..ad602e03 --- /dev/null +++ b/trunk/Arduino/Repetier_0.92.9/fastio.h @@ -0,0 +1,3737 @@ +/* + This code contibuted by Triffid_Hunter and modified by Kliment + why double up on these macros? see http://gcc.gnu.org/onlinedocs/cpp/Stringification.html + 2012/3/10 AT90USB128x modified by lincomatic to match Teensyduino +*/ +#ifndef _ARDUINO_H +#define _ARDUINO_H + +#include + +/* + utility functions +*/ + +#ifndef MASK +/// MASKING- returns \f$2^PIN\f$ + #define MASK(PIN) (1 << PIN) +#endif + +/* + magic I/O routines + + now you can simply SET_OUTPUT(STEP); WRITE(STEP, 1); WRITE(STEP, 0); +*/ + +/// Read a pin +#define _READ(IO) ((bool)(DIO ## IO ## _RPORT & MASK(DIO ## IO ## _PIN))) +/// write to a pin +#define _WRITE(IO, v) do { if (v) {DIO ## IO ## _WPORT |= MASK(DIO ## IO ## _PIN); } else {DIO ## IO ## _WPORT &= ~MASK(DIO ## IO ## _PIN); }; } while (0) +/// toggle a pin +#define _TOGGLE(IO) do {DIO ## IO ## _RPORT = MASK(DIO ## IO ## _PIN); } while (0) + +/// set pin as input +#define _SET_INPUT(IO) do {DIO ## IO ## _DDR &= ~MASK(DIO ## IO ## _PIN); } while (0) +/// set pin as output +#define _SET_OUTPUT(IO) do {DIO ## IO ## _DDR |= MASK(DIO ## IO ## _PIN); } while (0) + +/// check if pin is an input +#define _GET_INPUT(IO) ((DIO ## IO ## _DDR & MASK(DIO ## IO ## _PIN)) == 0) +/// check if pin is an output +#define _GET_OUTPUT(IO) ((DIO ## IO ## _DDR & MASK(DIO ## IO ## _PIN)) != 0) + +// why double up on these macros? see http://gcc.gnu.org/onlinedocs/cpp/Stringification.html + +/// Read a pin wrapper +#define READ(IO) _READ(IO) +/// Write to a pin wrapper +#define WRITE(IO, v) _WRITE(IO, v) +#define PULLUP(IO,v) _WRITE(IO, v) +/// toggle a pin wrapper +#define TOGGLE(IO) _TOGGLE(IO) + +/// set pin as input wrapper +#define SET_INPUT(IO) _SET_INPUT(IO) +/// set pin as output wrapper +#define SET_OUTPUT(IO) _SET_OUTPUT(IO) + +/// check if pin is an input wrapper +#define GET_INPUT(IO) _GET_INPUT(IO) +/// check if pin is an output wrapper +#define GET_OUTPUT(IO) _GET_OUTPUT(IO) + +/* + ports and functions + + added as necessary or if I feel like it- not a comprehensive list! +*/ + +#if defined (__AVR_ATmega168__) || defined (__AVR_ATmega328__) || defined (__AVR_ATmega328P__) +// UART +#define RXD DIO0 +#define TXD DIO1 + +// SPI +#define SCK 13 +#define MISO DIO12 +#define MOSI DIO11 +#define SS 10 + +// TWI (I2C) +#define SCL AIO5 +#define SDA AIO4 + +// timers and PWM +#define OC0A DIO6 +#define OC0B DIO5 +#define OC1A DIO9 +#define OC1B DIO10 +#define OC2A DIO11 +#define OC2B DIO3 + +#define DEBUG_LED AIO5 + +/* +pins +*/ + +#define DIO0_PIN PIND0 +#define DIO0_RPORT PIND +#define DIO0_WPORT PORTD +#define DIO0_DDR DDRD +#define DIO0_PWM NULL + +#define DIO1_PIN PIND1 +#define DIO1_RPORT PIND +#define DIO1_WPORT PORTD +#define DIO1_DDR DDRD +#define DIO1_PWM NULL + +#define DIO2_PIN PIND2 +#define DIO2_RPORT PIND +#define DIO2_WPORT PORTD +#define DIO2_DDR DDRD +#define DIO2_PWM NULL + +#define DIO3_PIN PIND3 +#define DIO3_RPORT PIND +#define DIO3_WPORT PORTD +#define DIO3_DDR DDRD +#define DIO3_PWM &OCR2B + +#define DIO4_PIN PIND4 +#define DIO4_RPORT PIND +#define DIO4_WPORT PORTD +#define DIO4_DDR DDRD +#define DIO4_PWM NULL + +#define DIO5_PIN PIND5 +#define DIO5_RPORT PIND +#define DIO5_WPORT PORTD +#define DIO5_DDR DDRD +#define DIO5_PWM &OCR0B + +#define DIO6_PIN PIND6 +#define DIO6_RPORT PIND +#define DIO6_WPORT PORTD +#define DIO6_DDR DDRD +#define DIO6_PWM &OCR0A + +#define DIO7_PIN PIND7 +#define DIO7_RPORT PIND +#define DIO7_WPORT PORTD +#define DIO7_DDR DDRD +#define DIO7_PWM NULL + +#define DIO8_PIN PINB0 +#define DIO8_RPORT PINB +#define DIO8_WPORT PORTB +#define DIO8_DDR DDRB +#define DIO8_PWM NULL + +#define DIO9_PIN PINB1 +#define DIO9_RPORT PINB +#define DIO9_WPORT PORTB +#define DIO9_DDR DDRB +#define DIO9_PWM NULL + +#define DIO10_PIN PINB2 +#define DIO10_RPORT PINB +#define DIO10_WPORT PORTB +#define DIO10_DDR DDRB +#define DIO10_PWM NULL + +#define DIO11_PIN PINB3 +#define DIO11_RPORT PINB +#define DIO11_WPORT PORTB +#define DIO11_DDR DDRB +#define DIO11_PWM &OCR2A + +#define DIO12_PIN PINB4 +#define DIO12_RPORT PINB +#define DIO12_WPORT PORTB +#define DIO12_DDR DDRB +#define DIO12_PWM NULL + +#define DIO13_PIN PINB5 +#define DIO13_RPORT PINB +#define DIO13_WPORT PORTB +#define DIO13_DDR DDRB +#define DIO13_PWM NULL + + +#define DIO14_PIN PINC0 +#define DIO14_RPORT PINC +#define DIO14_WPORT PORTC +#define DIO14_DDR DDRC +#define DIO14_PWM NULL + +#define DIO15_PIN PINC1 +#define DIO15_RPORT PINC +#define DIO15_WPORT PORTC +#define DIO15_DDR DDRC +#define DIO15_PWM NULL + +#define DIO16_PIN PINC2 +#define DIO16_RPORT PINC +#define DIO16_WPORT PORTC +#define DIO16_DDR DDRC +#define DIO16_PWM NULL + +#define DIO17_PIN PINC3 +#define DIO17_RPORT PINC +#define DIO17_WPORT PORTC +#define DIO17_DDR DDRC +#define DIO17_PWM NULL + +#define DIO18_PIN PINC4 +#define DIO18_RPORT PINC +#define DIO18_WPORT PORTC +#define DIO18_DDR DDRC +#define DIO18_PWM NULL + +#define DIO19_PIN PINC5 +#define DIO19_RPORT PINC +#define DIO19_WPORT PORTC +#define DIO19_DDR DDRC +#define DIO19_PWM NULL + +#define DIO20_PIN PINC6 +#define DIO20_RPORT PINC +#define DIO20_WPORT PORTC +#define DIO20_DDR DDRC +#define DIO20_PWM NULL + +#define DIO21_PIN PINC7 +#define DIO21_RPORT PINC +#define DIO21_WPORT PORTC +#define DIO21_DDR DDRC +#define DIO21_PWM NULL + + + +#undef PB0 +#define PB0_PIN PINB0 +#define PB0_RPORT PINB +#define PB0_WPORT PORTB +#define PB0_DDR DDRB +#define PB0_PWM NULL + +#undef PB1 +#define PB1_PIN PINB1 +#define PB1_RPORT PINB +#define PB1_WPORT PORTB +#define PB1_DDR DDRB +#define PB1_PWM NULL + +#undef PB2 +#define PB2_PIN PINB2 +#define PB2_RPORT PINB +#define PB2_WPORT PORTB +#define PB2_DDR DDRB +#define PB2_PWM NULL + +#undef PB3 +#define PB3_PIN PINB3 +#define PB3_RPORT PINB +#define PB3_WPORT PORTB +#define PB3_DDR DDRB +#define PB3_PWM &OCR2A + +#undef PB4 +#define PB4_PIN PINB4 +#define PB4_RPORT PINB +#define PB4_WPORT PORTB +#define PB4_DDR DDRB +#define PB4_PWM NULL + +#undef PB5 +#define PB5_PIN PINB5 +#define PB5_RPORT PINB +#define PB5_WPORT PORTB +#define PB5_DDR DDRB +#define PB5_PWM NULL + +#undef PB6 +#define PB6_PIN PINB6 +#define PB6_RPORT PINB +#define PB6_WPORT PORTB +#define PB6_DDR DDRB +#define PB6_PWM NULL + +#undef PB7 +#define PB7_PIN PINB7 +#define PB7_RPORT PINB +#define PB7_WPORT PORTB +#define PB7_DDR DDRB +#define PB7_PWM NULL + + +#undef PC0 +#define PC0_PIN PINC0 +#define PC0_RPORT PINC +#define PC0_WPORT PORTC +#define PC0_DDR DDRC +#define PC0_PWM NULL + +#undef PC1 +#define PC1_PIN PINC1 +#define PC1_RPORT PINC +#define PC1_WPORT PORTC +#define PC1_DDR DDRC +#define PC1_PWM NULL + +#undef PC2 +#define PC2_PIN PINC2 +#define PC2_RPORT PINC +#define PC2_WPORT PORTC +#define PC2_DDR DDRC +#define PC2_PWM NULL + +#undef PC3 +#define PC3_PIN PINC3 +#define PC3_RPORT PINC +#define PC3_WPORT PORTC +#define PC3_DDR DDRC +#define PC3_PWM NULL + +#undef PC4 +#define PC4_PIN PINC4 +#define PC4_RPORT PINC +#define PC4_WPORT PORTC +#define PC4_DDR DDRC +#define PC4_PWM NULL + +#undef PC5 +#define PC5_PIN PINC5 +#define PC5_RPORT PINC +#define PC5_WPORT PORTC +#define PC5_DDR DDRC +#define PC5_PWM NULL + +#undef PC6 +#define PC6_PIN PINC6 +#define PC6_RPORT PINC +#define PC6_WPORT PORTC +#define PC6_DDR DDRC +#define PC6_PWM NULL + +#undef PC7 +#define PC7_PIN PINC7 +#define PC7_RPORT PINC +#define PC7_WPORT PORTC +#define PC7_DDR DDRC +#define PC7_PWM NULL + + +#undef PD0 +#define PD0_PIN PIND0 +#define PD0_RPORT PIND +#define PD0_WPORT PORTD +#define PD0_DDR DDRD +#define PD0_PWM NULL + +#undef PD1 +#define PD1_PIN PIND1 +#define PD1_RPORT PIND +#define PD1_WPORT PORTD +#define PD1_DDR DDRD +#define PD1_PWM NULL + +#undef PD2 +#define PD2_PIN PIND2 +#define PD2_RPORT PIND +#define PD2_WPORT PORTD +#define PD2_DDR DDRD +#define PD2_PWM NULL + +#undef PD3 +#define PD3_PIN PIND3 +#define PD3_RPORT PIND +#define PD3_WPORT PORTD +#define PD3_DDR DDRD +#define PD3_PWM &OCR2B + +#undef PD4 +#define PD4_PIN PIND4 +#define PD4_RPORT PIND +#define PD4_WPORT PORTD +#define PD4_DDR DDRD +#define PD4_PWM NULL + +#undef PD5 +#define PD5_PIN PIND5 +#define PD5_RPORT PIND +#define PD5_WPORT PORTD +#define PD5_DDR DDRD +#define PD5_PWM &OCR0B + +#undef PD6 +#define PD6_PIN PIND6 +#define PD6_RPORT PIND +#define PD6_WPORT PORTD +#define PD6_DDR DDRD +#define PD6_PWM &OCR0A + +#undef PD7 +#define PD7_PIN PIND7 +#define PD7_RPORT PIND +#define PD7_WPORT PORTD +#define PD7_DDR DDRD +#define PD7_PWM NULL +#endif /* _AVR_ATmega{168,328,328P}__ */ + +#if defined (__AVR_ATmega644__) || defined (__AVR_ATmega644P__) || defined (__AVR_ATmega644PA__) || defined (__AVR_ATmega1284P__) +// UART +#define RXD DIO8 +#define TXD DIO9 +#define RXD0 DIO8 +#define TXD0 DIO9 + +#define RXD1 DIO10 +#define TXD1 DIO11 + +// SPI +#define SCK 7 +#define MISO DIO6 +#define MOSI DIO5 +#define SS 4 + +// TWI (I2C) +#define SCL DIO16 +#define SDA DIO17 + +// timers and PWM +#define OC0A DIO3 +#define OC0B DIO4 +#define OC1A DIO13 +#define OC1B DIO12 +#define OC2A DIO15 +#define OC2B DIO14 + +#define DEBUG_LED DIO0 +/* +pins +*/ + +#define DIO0_PIN PINB0 +#define DIO0_RPORT PINB +#define DIO0_WPORT PORTB +#define DIO0_DDR DDRB +#define DIO0_PWM NULL + +#define DIO1_PIN PINB1 +#define DIO1_RPORT PINB +#define DIO1_WPORT PORTB +#define DIO1_DDR DDRB +#define DIO1_PWM NULL + +#define DIO2_PIN PINB2 +#define DIO2_RPORT PINB +#define DIO2_WPORT PORTB +#define DIO2_DDR DDRB +#define DIO2_PWM NULL + +#define DIO3_PIN PINB3 +#define DIO3_RPORT PINB +#define DIO3_WPORT PORTB +#define DIO3_DDR DDRB +#define DIO3_PWM &OCR0A + +#define DIO4_PIN PINB4 +#define DIO4_RPORT PINB +#define DIO4_WPORT PORTB +#define DIO4_DDR DDRB +#define DIO4_PWM &OCR0B + +#define DIO5_PIN PINB5 +#define DIO5_RPORT PINB +#define DIO5_WPORT PORTB +#define DIO5_DDR DDRB +#define DIO5_PWM NULL + +#define DIO6_PIN PINB6 +#define DIO6_RPORT PINB +#define DIO6_WPORT PORTB +#define DIO6_DDR DDRB +#define DIO6_PWM NULL + +#define DIO7_PIN PINB7 +#define DIO7_RPORT PINB +#define DIO7_WPORT PORTB +#define DIO7_DDR DDRB +#define DIO7_PWM NULL + +#define DIO8_PIN PIND0 +#define DIO8_RPORT PIND +#define DIO8_WPORT PORTD +#define DIO8_DDR DDRD +#define DIO8_PWM NULL + +#define DIO9_PIN PIND1 +#define DIO9_RPORT PIND +#define DIO9_WPORT PORTD +#define DIO9_DDR DDRD +#define DIO9_PWM NULL + +#define DIO10_PIN PIND2 +#define DIO10_RPORT PIND +#define DIO10_WPORT PORTD +#define DIO10_DDR DDRD +#define DIO10_PWM NULL + +#define DIO11_PIN PIND3 +#define DIO11_RPORT PIND +#define DIO11_WPORT PORTD +#define DIO11_DDR DDRD +#define DIO11_PWM NULL + +#define DIO12_PIN PIND4 +#define DIO12_RPORT PIND +#define DIO12_WPORT PORTD +#define DIO12_DDR DDRD +#define DIO12_PWM NULL + +#define DIO13_PIN PIND5 +#define DIO13_RPORT PIND +#define DIO13_WPORT PORTD +#define DIO13_DDR DDRD +#define DIO13_PWM NULL + +#define DIO14_PIN PIND6 +#define DIO14_RPORT PIND +#define DIO14_WPORT PORTD +#define DIO14_DDR DDRD +#define DIO14_PWM &OCR2B + +#define DIO15_PIN PIND7 +#define DIO15_RPORT PIND +#define DIO15_WPORT PORTD +#define DIO15_DDR DDRD +#define DIO15_PWM &OCR2A + +#define DIO16_PIN PINC0 +#define DIO16_RPORT PINC +#define DIO16_WPORT PORTC +#define DIO16_DDR DDRC +#define DIO16_PWM NULL + +#define DIO17_PIN PINC1 +#define DIO17_RPORT PINC +#define DIO17_WPORT PORTC +#define DIO17_DDR DDRC +#define DIO17_PWM NULL + +#define DIO18_PIN PINC2 +#define DIO18_RPORT PINC +#define DIO18_WPORT PORTC +#define DIO18_DDR DDRC +#define DIO18_PWM NULL + +#define DIO19_PIN PINC3 +#define DIO19_RPORT PINC +#define DIO19_WPORT PORTC +#define DIO19_DDR DDRC +#define DIO19_PWM NULL + +#define DIO20_PIN PINC4 +#define DIO20_RPORT PINC +#define DIO20_WPORT PORTC +#define DIO20_DDR DDRC +#define DIO20_PWM NULL + +#define DIO21_PIN PINC5 +#define DIO21_RPORT PINC +#define DIO21_WPORT PORTC +#define DIO21_DDR DDRC +#define DIO21_PWM NULL + +#define DIO22_PIN PINC6 +#define DIO22_RPORT PINC +#define DIO22_WPORT PORTC +#define DIO22_DDR DDRC +#define DIO22_PWM NULL + +#define DIO23_PIN PINC7 +#define DIO23_RPORT PINC +#define DIO23_WPORT PORTC +#define DIO23_DDR DDRC +#define DIO23_PWM NULL + +#define DIO24_PIN PINA7 +#define DIO24_RPORT PINA +#define DIO24_WPORT PORTA +#define DIO24_DDR DDRA +#define DIO24_PWM NULL + +#define DIO25_PIN PINA6 +#define DIO25_RPORT PINA +#define DIO25_WPORT PORTA +#define DIO25_DDR DDRA +#define DIO25_PWM NULL + +#define DIO26_PIN PINA5 +#define DIO26_RPORT PINA +#define DIO26_WPORT PORTA +#define DIO26_DDR DDRA +#define DIO26_PWM NULL + +#define DIO27_PIN PINA4 +#define DIO27_RPORT PINA +#define DIO27_WPORT PORTA +#define DIO27_DDR DDRA +#define DIO27_PWM NULL + +#define DIO28_PIN PINA3 +#define DIO28_RPORT PINA +#define DIO28_WPORT PORTA +#define DIO28_DDR DDRA +#define DIO28_PWM NULL + +#define DIO29_PIN PINA2 +#define DIO29_RPORT PINA +#define DIO29_WPORT PORTA +#define DIO29_DDR DDRA +#define DIO29_PWM NULL + +#define DIO30_PIN PINA1 +#define DIO30_RPORT PINA +#define DIO30_WPORT PORTA +#define DIO30_DDR DDRA +#define DIO30_PWM NULL + +#define DIO31_PIN PINA0 +#define DIO31_RPORT PINA +#define DIO31_WPORT PORTA +#define DIO31_DDR DDRA +#define DIO31_PWM NULL + +#define AIO0_PIN PINA0 +#define AIO0_RPORT PINA +#define AIO0_WPORT PORTA +#define AIO0_DDR DDRA +#define AIO0_PWM NULL + +#define AIO1_PIN PINA1 +#define AIO1_RPORT PINA +#define AIO1_WPORT PORTA +#define AIO1_DDR DDRA +#define AIO1_PWM NULL + +#define AIO2_PIN PINA2 +#define AIO2_RPORT PINA +#define AIO2_WPORT PORTA +#define AIO2_DDR DDRA +#define AIO2_PWM NULL + +#define AIO3_PIN PINA3 +#define AIO3_RPORT PINA +#define AIO3_WPORT PORTA +#define AIO3_DDR DDRA +#define AIO3_PWM NULL + +#define AIO4_PIN PINA4 +#define AIO4_RPORT PINA +#define AIO4_WPORT PORTA +#define AIO4_DDR DDRA +#define AIO4_PWM NULL + +#define AIO5_PIN PINA5 +#define AIO5_RPORT PINA +#define AIO5_WPORT PORTA +#define AIO5_DDR DDRA +#define AIO5_PWM NULL + +#define AIO6_PIN PINA6 +#define AIO6_RPORT PINA +#define AIO6_WPORT PORTA +#define AIO6_DDR DDRA +#define AIO6_PWM NULL + +#define AIO7_PIN PINA7 +#define AIO7_RPORT PINA +#define AIO7_WPORT PORTA +#define AIO7_DDR DDRA +#define AIO7_PWM NULL + + + +#undef PA0 +#define PA0_PIN PINA0 +#define PA0_RPORT PINA +#define PA0_WPORT PORTA +#define PA0_DDR DDRA +#define PA0_PWM NULL + +#undef PA1 +#define PA1_PIN PINA1 +#define PA1_RPORT PINA +#define PA1_WPORT PORTA +#define PA1_DDR DDRA +#define PA1_PWM NULL + +#undef PA2 +#define PA2_PIN PINA2 +#define PA2_RPORT PINA +#define PA2_WPORT PORTA +#define PA2_DDR DDRA +#define PA2_PWM NULL + +#undef PA3 +#define PA3_PIN PINA3 +#define PA3_RPORT PINA +#define PA3_WPORT PORTA +#define PA3_DDR DDRA +#define PA3_PWM NULL + +#undef PA4 +#define PA4_PIN PINA4 +#define PA4_RPORT PINA +#define PA4_WPORT PORTA +#define PA4_DDR DDRA +#define PA4_PWM NULL + +#undef PA5 +#define PA5_PIN PINA5 +#define PA5_RPORT PINA +#define PA5_WPORT PORTA +#define PA5_DDR DDRA +#define PA5_PWM NULL + +#undef PA6 +#define PA6_PIN PINA6 +#define PA6_RPORT PINA +#define PA6_WPORT PORTA +#define PA6_DDR DDRA +#define PA6_PWM NULL + +#undef PA7 +#define PA7_PIN PINA7 +#define PA7_RPORT PINA +#define PA7_WPORT PORTA +#define PA7_DDR DDRA +#define PA7_PWM NULL + + +#undef PB0 +#define PB0_PIN PINB0 +#define PB0_RPORT PINB +#define PB0_WPORT PORTB +#define PB0_DDR DDRB +#define PB0_PWM NULL + +#undef PB1 +#define PB1_PIN PINB1 +#define PB1_RPORT PINB +#define PB1_WPORT PORTB +#define PB1_DDR DDRB +#define PB1_PWM NULL + +#undef PB2 +#define PB2_PIN PINB2 +#define PB2_RPORT PINB +#define PB2_WPORT PORTB +#define PB2_DDR DDRB +#define PB2_PWM NULL + +#undef PB3 +#define PB3_PIN PINB3 +#define PB3_RPORT PINB +#define PB3_WPORT PORTB +#define PB3_DDR DDRB +#define PB3_PWM &OCR0A + +#undef PB4 +#define PB4_PIN PINB4 +#define PB4_RPORT PINB +#define PB4_WPORT PORTB +#define PB4_DDR DDRB +#define PB4_PWM &OCR0B + +#undef PB5 +#define PB5_PIN PINB5 +#define PB5_RPORT PINB +#define PB5_WPORT PORTB +#define PB5_DDR DDRB +#define PB5_PWM NULL + +#undef PB6 +#define PB6_PIN PINB6 +#define PB6_RPORT PINB +#define PB6_WPORT PORTB +#define PB6_DDR DDRB +#define PB6_PWM NULL + +#undef PB7 +#define PB7_PIN PINB7 +#define PB7_RPORT PINB +#define PB7_WPORT PORTB +#define PB7_DDR DDRB +#define PB7_PWM NULL + + +#undef PC0 +#define PC0_PIN PINC0 +#define PC0_RPORT PINC +#define PC0_WPORT PORTC +#define PC0_DDR DDRC +#define PC0_PWM NULL + +#undef PC1 +#define PC1_PIN PINC1 +#define PC1_RPORT PINC +#define PC1_WPORT PORTC +#define PC1_DDR DDRC +#define PC1_PWM NULL + +#undef PC2 +#define PC2_PIN PINC2 +#define PC2_RPORT PINC +#define PC2_WPORT PORTC +#define PC2_DDR DDRC +#define PC2_PWM NULL + +#undef PC3 +#define PC3_PIN PINC3 +#define PC3_RPORT PINC +#define PC3_WPORT PORTC +#define PC3_DDR DDRC +#define PC3_PWM NULL + +#undef PC4 +#define PC4_PIN PINC4 +#define PC4_RPORT PINC +#define PC4_WPORT PORTC +#define PC4_DDR DDRC +#define PC4_PWM NULL + +#undef PC5 +#define PC5_PIN PINC5 +#define PC5_RPORT PINC +#define PC5_WPORT PORTC +#define PC5_DDR DDRC +#define PC5_PWM NULL + +#undef PC6 +#define PC6_PIN PINC6 +#define PC6_RPORT PINC +#define PC6_WPORT PORTC +#define PC6_DDR DDRC +#define PC6_PWM NULL + +#undef PC7 +#define PC7_PIN PINC7 +#define PC7_RPORT PINC +#define PC7_WPORT PORTC +#define PC7_DDR DDRC +#define PC7_PWM NULL + + +#undef PD0 +#define PD0_PIN PIND0 +#define PD0_RPORT PIND +#define PD0_WPORT PORTD +#define PD0_DDR DDRD +#define PD0_PWM NULL + +#undef PD1 +#define PD1_PIN PIND1 +#define PD1_RPORT PIND +#define PD1_WPORT PORTD +#define PD1_DDR DDRD +#define PD1_PWM NULL + +#undef PD2 +#define PD2_PIN PIND2 +#define PD2_RPORT PIND +#define PD2_WPORT PORTD +#define PD2_DDR DDRD +#define PD2_PWM NULL + +#undef PD3 +#define PD3_PIN PIND3 +#define PD3_RPORT PIND +#define PD3_WPORT PORTD +#define PD3_DDR DDRD +#define PD3_PWM NULL + +#undef PD4 +#define PD4_PIN PIND4 +#define PD4_RPORT PIND +#define PD4_WPORT PORTD +#define PD4_DDR DDRD +#define PD4_PWM NULL + +#undef PD5 +#define PD5_PIN PIND5 +#define PD5_RPORT PIND +#define PD5_WPORT PORTD +#define PD5_DDR DDRD +#define PD5_PWM NULL + +#undef PD6 +#define PD6_PIN PIND6 +#define PD6_RPORT PIND +#define PD6_WPORT PORTD +#define PD6_DDR DDRD +#define PD6_PWM &OCR2B + +#undef PD7 +#define PD7_PIN PIND7 +#define PD7_RPORT PIND +#define PD7_WPORT PORTD +#define PD7_DDR DDRD +#define PD7_PWM &OCR2A +#endif /* _AVR_ATmega{644,644P,644PA}__ */ + +#if defined (__AVR_ATmega1280__) || defined (__AVR_ATmega2560__) +// UART +#define RXD DIO0 +#define TXD DIO1 + +// SPI +#define SCK 52 +#define MISO DIO50 +#define MOSI DIO51 +#define SS 53 + +// TWI (I2C) +#define SCL DIO21 +#define SDA DIO20 + +// timers and PWM +#define OC0A DIO13 +#define OC0B DIO4 +#define OC1A DIO11 +#define OC1B DIO12 +#define OC2A DIO10 +#define OC2B DIO9 +#define OC3A DIO5 +#define OC3B DIO2 +#define OC3C DIO3 +#define OC4A DIO6 +#define OC4B DIO7 +#define OC4C DIO8 +#define OC5A DIO46 +#define OC5B DIO45 +#define OC5C DIO44 + +// change for your board +#if MOTHERBOARD == 12 +#define DEBUG_LED DIO22 +#else +#define DEBUG_LED DIO21 +#endif +/* +pins +*/ +#define DIO0_PIN PINE0 +#define DIO0_RPORT PINE +#define DIO0_WPORT PORTE +#define DIO0_DDR DDRE +#define DIO0_PWM NULL + +#define DIO1_PIN PINE1 +#define DIO1_RPORT PINE +#define DIO1_WPORT PORTE +#define DIO1_DDR DDRE +#define DIO1_PWM NULL + +#define DIO2_PIN PINE4 +#define DIO2_RPORT PINE +#define DIO2_WPORT PORTE +#define DIO2_DDR DDRE +#define DIO2_PWM &OCR3BL + +#define DIO3_PIN PINE5 +#define DIO3_RPORT PINE +#define DIO3_WPORT PORTE +#define DIO3_DDR DDRE +#define DIO3_PWM &OCR3CL + +#define DIO4_PIN PING5 +#define DIO4_RPORT PING +#define DIO4_WPORT PORTG +#define DIO4_DDR DDRG +#define DIO4_PWM &OCR0B + +#define DIO5_PIN PINE3 +#define DIO5_RPORT PINE +#define DIO5_WPORT PORTE +#define DIO5_DDR DDRE +#define DIO5_PWM &OCR3AL + +#define DIO6_PIN PINH3 +#define DIO6_RPORT PINH +#define DIO6_WPORT PORTH +#define DIO6_DDR DDRH +#define DIO6_PWM &OCR4AL + +#define DIO7_PIN PINH4 +#define DIO7_RPORT PINH +#define DIO7_WPORT PORTH +#define DIO7_DDR DDRH +#define DIO7_PWM &OCR4BL + +#define DIO8_PIN PINH5 +#define DIO8_RPORT PINH +#define DIO8_WPORT PORTH +#define DIO8_DDR DDRH +#define DIO8_PWM &OCR4CL + +#define DIO9_PIN PINH6 +#define DIO9_RPORT PINH +#define DIO9_WPORT PORTH +#define DIO9_DDR DDRH +#define DIO9_PWM &OCR2B + +#define DIO10_PIN PINB4 +#define DIO10_RPORT PINB +#define DIO10_WPORT PORTB +#define DIO10_DDR DDRB +#define DIO10_PWM &OCR2A + +#define DIO11_PIN PINB5 +#define DIO11_RPORT PINB +#define DIO11_WPORT PORTB +#define DIO11_DDR DDRB +#define DIO11_PWM NULL + +#define DIO12_PIN PINB6 +#define DIO12_RPORT PINB +#define DIO12_WPORT PORTB +#define DIO12_DDR DDRB +#define DIO12_PWM NULL + +#define DIO13_PIN PINB7 +#define DIO13_RPORT PINB +#define DIO13_WPORT PORTB +#define DIO13_DDR DDRB +#define DIO13_PWM &OCR0A + +#define DIO14_PIN PINJ1 +#define DIO14_RPORT PINJ +#define DIO14_WPORT PORTJ +#define DIO14_DDR DDRJ +#define DIO14_PWM NULL + +#define DIO15_PIN PINJ0 +#define DIO15_RPORT PINJ +#define DIO15_WPORT PORTJ +#define DIO15_DDR DDRJ +#define DIO15_PWM NULL + +#define DIO16_PIN PINH1 +#define DIO16_RPORT PINH +#define DIO16_WPORT PORTH +#define DIO16_DDR DDRH +#define DIO16_PWM NULL + +#define DIO17_PIN PINH0 +#define DIO17_RPORT PINH +#define DIO17_WPORT PORTH +#define DIO17_DDR DDRH +#define DIO17_PWM NULL + +#define DIO18_PIN PIND3 +#define DIO18_RPORT PIND +#define DIO18_WPORT PORTD +#define DIO18_DDR DDRD +#define DIO18_PWM NULL + +#define DIO19_PIN PIND2 +#define DIO19_RPORT PIND +#define DIO19_WPORT PORTD +#define DIO19_DDR DDRD +#define DIO19_PWM NULL + +#define DIO20_PIN PIND1 +#define DIO20_RPORT PIND +#define DIO20_WPORT PORTD +#define DIO20_DDR DDRD +#define DIO20_PWM NULL + +#define DIO21_PIN PIND0 +#define DIO21_RPORT PIND +#define DIO21_WPORT PORTD +#define DIO21_DDR DDRD +#define DIO21_PWM NULL + +#define DIO22_PIN PINA0 +#define DIO22_RPORT PINA +#define DIO22_WPORT PORTA +#define DIO22_DDR DDRA +#define DIO22_PWM NULL + +#define DIO23_PIN PINA1 +#define DIO23_RPORT PINA +#define DIO23_WPORT PORTA +#define DIO23_DDR DDRA +#define DIO23_PWM NULL + +#define DIO24_PIN PINA2 +#define DIO24_RPORT PINA +#define DIO24_WPORT PORTA +#define DIO24_DDR DDRA +#define DIO24_PWM NULL + +#define DIO25_PIN PINA3 +#define DIO25_RPORT PINA +#define DIO25_WPORT PORTA +#define DIO25_DDR DDRA +#define DIO25_PWM NULL + +#define DIO26_PIN PINA4 +#define DIO26_RPORT PINA +#define DIO26_WPORT PORTA +#define DIO26_DDR DDRA +#define DIO26_PWM NULL + +#define DIO27_PIN PINA5 +#define DIO27_RPORT PINA +#define DIO27_WPORT PORTA +#define DIO27_DDR DDRA +#define DIO27_PWM NULL + +#define DIO28_PIN PINA6 +#define DIO28_RPORT PINA +#define DIO28_WPORT PORTA +#define DIO28_DDR DDRA +#define DIO28_PWM NULL + +#define DIO29_PIN PINA7 +#define DIO29_RPORT PINA +#define DIO29_WPORT PORTA +#define DIO29_DDR DDRA +#define DIO29_PWM NULL + +#define DIO30_PIN PINC7 +#define DIO30_RPORT PINC +#define DIO30_WPORT PORTC +#define DIO30_DDR DDRC +#define DIO30_PWM NULL + +#define DIO31_PIN PINC6 +#define DIO31_RPORT PINC +#define DIO31_WPORT PORTC +#define DIO31_DDR DDRC +#define DIO31_PWM NULL + +#define DIO32_PIN PINC5 +#define DIO32_RPORT PINC +#define DIO32_WPORT PORTC +#define DIO32_DDR DDRC +#define DIO32_PWM NULL + +#define DIO33_PIN PINC4 +#define DIO33_RPORT PINC +#define DIO33_WPORT PORTC +#define DIO33_DDR DDRC +#define DIO33_PWM NULL + +#define DIO34_PIN PINC3 +#define DIO34_RPORT PINC +#define DIO34_WPORT PORTC +#define DIO34_DDR DDRC +#define DIO34_PWM NULL + +#define DIO35_PIN PINC2 +#define DIO35_RPORT PINC +#define DIO35_WPORT PORTC +#define DIO35_DDR DDRC +#define DIO35_PWM NULL + +#define DIO36_PIN PINC1 +#define DIO36_RPORT PINC +#define DIO36_WPORT PORTC +#define DIO36_DDR DDRC +#define DIO36_PWM NULL + +#define DIO37_PIN PINC0 +#define DIO37_RPORT PINC +#define DIO37_WPORT PORTC +#define DIO37_DDR DDRC +#define DIO37_PWM NULL + +#define DIO38_PIN PIND7 +#define DIO38_RPORT PIND +#define DIO38_WPORT PORTD +#define DIO38_DDR DDRD +#define DIO38_PWM NULL + +#define DIO39_PIN PING2 +#define DIO39_RPORT PING +#define DIO39_WPORT PORTG +#define DIO39_DDR DDRG +#define DIO39_PWM NULL + +#define DIO40_PIN PING1 +#define DIO40_RPORT PING +#define DIO40_WPORT PORTG +#define DIO40_DDR DDRG +#define DIO40_PWM NULL + +#define DIO41_PIN PING0 +#define DIO41_RPORT PING +#define DIO41_WPORT PORTG +#define DIO41_DDR DDRG +#define DIO41_PWM NULL + +#define DIO42_PIN PINL7 +#define DIO42_RPORT PINL +#define DIO42_WPORT PORTL +#define DIO42_DDR DDRL +#define DIO42_PWM NULL + +#define DIO43_PIN PINL6 +#define DIO43_RPORT PINL +#define DIO43_WPORT PORTL +#define DIO43_DDR DDRL +#define DIO43_PWM NULL + +#define DIO44_PIN PINL5 +#define DIO44_RPORT PINL +#define DIO44_WPORT PORTL +#define DIO44_DDR DDRL +#define DIO44_PWM &OCR5CL + +#define DIO45_PIN PINL4 +#define DIO45_RPORT PINL +#define DIO45_WPORT PORTL +#define DIO45_DDR DDRL +#define DIO45_PWM &OCR5BL + +#define DIO46_PIN PINL3 +#define DIO46_RPORT PINL +#define DIO46_WPORT PORTL +#define DIO46_DDR DDRL +#define DIO46_PWM &OCR5AL + +#define DIO47_PIN PINL2 +#define DIO47_RPORT PINL +#define DIO47_WPORT PORTL +#define DIO47_DDR DDRL +#define DIO47_PWM NULL + +#define DIO48_PIN PINL1 +#define DIO48_RPORT PINL +#define DIO48_WPORT PORTL +#define DIO48_DDR DDRL +#define DIO48_PWM NULL + +#define DIO49_PIN PINL0 +#define DIO49_RPORT PINL +#define DIO49_WPORT PORTL +#define DIO49_DDR DDRL +#define DIO49_PWM NULL + +#define DIO50_PIN PINB3 +#define DIO50_RPORT PINB +#define DIO50_WPORT PORTB +#define DIO50_DDR DDRB +#define DIO50_PWM NULL + +#define DIO51_PIN PINB2 +#define DIO51_RPORT PINB +#define DIO51_WPORT PORTB +#define DIO51_DDR DDRB +#define DIO51_PWM NULL + +#define DIO52_PIN PINB1 +#define DIO52_RPORT PINB +#define DIO52_WPORT PORTB +#define DIO52_DDR DDRB +#define DIO52_PWM NULL + +#define DIO53_PIN PINB0 +#define DIO53_RPORT PINB +#define DIO53_WPORT PORTB +#define DIO53_DDR DDRB +#define DIO53_PWM NULL + +#define DIO54_PIN PINF0 +#define DIO54_RPORT PINF +#define DIO54_WPORT PORTF +#define DIO54_DDR DDRF +#define DIO54_PWM NULL + +#define DIO55_PIN PINF1 +#define DIO55_RPORT PINF +#define DIO55_WPORT PORTF +#define DIO55_DDR DDRF +#define DIO55_PWM NULL + +#define DIO56_PIN PINF2 +#define DIO56_RPORT PINF +#define DIO56_WPORT PORTF +#define DIO56_DDR DDRF +#define DIO56_PWM NULL + +#define DIO57_PIN PINF3 +#define DIO57_RPORT PINF +#define DIO57_WPORT PORTF +#define DIO57_DDR DDRF +#define DIO57_PWM NULL + +#define DIO58_PIN PINF4 +#define DIO58_RPORT PINF +#define DIO58_WPORT PORTF +#define DIO58_DDR DDRF +#define DIO58_PWM NULL + +#define DIO59_PIN PINF5 +#define DIO59_RPORT PINF +#define DIO59_WPORT PORTF +#define DIO59_DDR DDRF +#define DIO59_PWM NULL + +#define DIO60_PIN PINF6 +#define DIO60_RPORT PINF +#define DIO60_WPORT PORTF +#define DIO60_DDR DDRF +#define DIO60_PWM NULL + +#define DIO61_PIN PINF7 +#define DIO61_RPORT PINF +#define DIO61_WPORT PORTF +#define DIO61_DDR DDRF +#define DIO61_PWM NULL + +#define DIO62_PIN PINK0 +#define DIO62_RPORT PINK +#define DIO62_WPORT PORTK +#define DIO62_DDR DDRK +#define DIO62_PWM NULL + +#define DIO63_PIN PINK1 +#define DIO63_RPORT PINK +#define DIO63_WPORT PORTK +#define DIO63_DDR DDRK +#define DIO63_PWM NULL + +#define DIO64_PIN PINK2 +#define DIO64_RPORT PINK +#define DIO64_WPORT PORTK +#define DIO64_DDR DDRK +#define DIO64_PWM NULL + +#define DIO65_PIN PINK3 +#define DIO65_RPORT PINK +#define DIO65_WPORT PORTK +#define DIO65_DDR DDRK +#define DIO65_PWM NULL + +#define DIO66_PIN PINK4 +#define DIO66_RPORT PINK +#define DIO66_WPORT PORTK +#define DIO66_DDR DDRK +#define DIO66_PWM NULL + +#define DIO67_PIN PINK5 +#define DIO67_RPORT PINK +#define DIO67_WPORT PORTK +#define DIO67_DDR DDRK +#define DIO67_PWM NULL + +#define DIO68_PIN PINK6 +#define DIO68_RPORT PINK +#define DIO68_WPORT PORTK +#define DIO68_DDR DDRK +#define DIO68_PWM NULL + +#define DIO69_PIN PINK7 +#define DIO69_RPORT PINK +#define DIO69_WPORT PORTK +#define DIO69_DDR DDRK +#define DIO69_PWM NULL + +#if MOTHERBOARD == 12 +#define DIO80_PIN PINJ2 +#define DIO80_RPORT PINJ +#define DIO80_WPORT PORTJ +#define DIO80_DDR DDRJ +#define DIO80_PWM NULL + +#define DIO81_PIN PINJ4 +#define DIO81_RPORT PINJ +#define DIO81_WPORT PORTJ +#define DIO81_DDR DDRJ +#define DIO81_PWM NULL + +#define DIO82_PIN PINJ5 +#define DIO82_RPORT PINJ +#define DIO82_WPORT PORTJ +#define DIO82_DDR DDRJ +#define DIO82_PWM NULL + +#define DIO83_PIN PINJ6 +#define DIO83_RPORT PINJ +#define DIO83_WPORT PORTJ +#define DIO83_DDR DDRJ +#define DIO83_PWM NULL + +#define DIO84_PIN PINJ7 +#define DIO84_RPORT PINJ +#define DIO84_WPORT PORTJ +#define DIO84_DDR DDRJ +#define DIO84_PWM NULL + +#define DIO85_PIN PINH7 +#define DIO85_RPORT PINH +#define DIO85_WPORT PORTH +#define DIO85_DDR DDRH +#define DIO85_PWM NULL + +#define DIO86_PIN PINH2 +#define DIO86_RPORT PINH +#define DIO86_WPORT PORTH +#define DIO86_DDR DDRH +#define DIO86_PWM NULL + +#define DIO90_PIN PINE7 +#define DIO90_RPORT PINE +#define DIO90_WPORT PORTE +#define DIO90_DDR DDRE +#define DIO90_PWM NULL + +#define DIO91_PIN PINE2 +#define DIO91_RPORT PINE +#define DIO91_WPORT PORTE +#define DIO91_DDR DDRE +#define DIO91_PWM NULL + +#define DIO92_PIN PIND4 +#define DIO92_RPORT PIND +#define DIO92_WPORT PORTD +#define DIO92_DDR DDRD +#define DIO92_PWM NULL + +#define DIO93_PIN PIND5 +#define DIO93_RPORT PIND +#define DIO93_WPORT PORTD +#define DIO93_DDR DDRD +#define DIO93_PWM NULL + +#define DIO94_PIN PIND6 +#define DIO94_RPORT PIND +#define DIO94_WPORT PORTD +#define DIO94_DDR DDRD +#define DIO94_PWM NULL +#else // MOTHERBOARD == 12 + +//added below DIO definitions for RAMBo support for LCD's etc... + +#define DIO70_PIN PING4 +#define DIO70_RPORT PING +#define DIO70_WPORT PORTG +#define DIO70_DDR DDRG +#define DIO70_PWM NULL +#define DIO71_PIN PING3 +#define DIO71_RPORT PING +#define DIO71_WPORT PORTG +#define DIO71_DDR DDRG +#define DIO71_PWM NULL +#define DIO72_PIN PINJ2 +#define DIO72_RPORT PINJ +#define DIO72_WPORT PORTJ +#define DIO72_DDR DDRJ +#define DIO72_PWM NULL +#define DIO73_PIN PINJ3 +#define DIO73_RPORT PINJ +#define DIO73_WPORT PORTJ +#define DIO73_DDR DDRJ +#define DIO73_PWM NULL +#define DIO74_PIN PINJ7 +#define DIO74_RPORT PINJ +#define DIO74_WPORT PORTJ +#define DIO74_DDR DDRJ +#define DIO74_PWM NULL +#define DIO75_PIN PINJ4 +#define DIO75_RPORT PINJ +#define DIO75_WPORT PORTJ +#define DIO75_DDR DDRJ +#define DIO75_PWM NULL + + +#define DIO76_PIN PINJ5 +#define DIO76_RPORT PINJ +#define DIO76_WPORT PORTJ +#define DIO76_DDR DDRJ +#define DIO76_PWM NULL +#define DIO77_PIN PINJ6 +#define DIO77_RPORT PINJ +#define DIO77_WPORT PORTJ +#define DIO77_DDR DDRJ +#define DIO77_PWM NULL +#define DIO78_PIN PINE2 +#define DIO78_RPORT PINE +#define DIO78_WPORT PORTE +#define DIO78_DDR DDRE +#define DIO78_PWM NULL +#define DIO79_PIN PINE6 +#define DIO79_RPORT PINE +#define DIO79_WPORT PORTE +#define DIO79_DDR DDRE +#define DIO79_PWM NULL +#define DIO80_PIN PINE7 +#define DIO80_RPORT PINE +#define DIO80_WPORT PORTE +#define DIO80_DDR DDRE +#define DIO80_PWM NULL +#define DIO81_PIN PIND4 +#define DIO81_RPORT PIND +#define DIO81_WPORT PORTD +#define DIO81_DDR DDRD +#define DIO81_PWM NULL + +#endif + +#undef PA0 +#define PA0_PIN PINA0 +#define PA0_RPORT PINA +#define PA0_WPORT PORTA +#define PA0_DDR DDRA +#define PA0_PWM NULL +#undef PA1 +#define PA1_PIN PINA1 +#define PA1_RPORT PINA +#define PA1_WPORT PORTA +#define PA1_DDR DDRA +#define PA1_PWM NULL +#undef PA2 +#define PA2_PIN PINA2 +#define PA2_RPORT PINA +#define PA2_WPORT PORTA +#define PA2_DDR DDRA +#define PA2_PWM NULL +#undef PA3 +#define PA3_PIN PINA3 +#define PA3_RPORT PINA +#define PA3_WPORT PORTA +#define PA3_DDR DDRA +#define PA3_PWM NULL +#undef PA4 +#define PA4_PIN PINA4 +#define PA4_RPORT PINA +#define PA4_WPORT PORTA +#define PA4_DDR DDRA +#define PA4_PWM NULL +#undef PA5 +#define PA5_PIN PINA5 +#define PA5_RPORT PINA +#define PA5_WPORT PORTA +#define PA5_DDR DDRA +#define PA5_PWM NULL +#undef PA6 +#define PA6_PIN PINA6 +#define PA6_RPORT PINA +#define PA6_WPORT PORTA +#define PA6_DDR DDRA +#define PA6_PWM NULL +#undef PA7 +#define PA7_PIN PINA7 +#define PA7_RPORT PINA +#define PA7_WPORT PORTA +#define PA7_DDR DDRA +#define PA7_PWM NULL + +#undef PB0 +#define PB0_PIN PINB0 +#define PB0_RPORT PINB +#define PB0_WPORT PORTB +#define PB0_DDR DDRB +#define PB0_PWM NULL +#undef PB1 +#define PB1_PIN PINB1 +#define PB1_RPORT PINB +#define PB1_WPORT PORTB +#define PB1_DDR DDRB +#define PB1_PWM NULL +#undef PB2 +#define PB2_PIN PINB2 +#define PB2_RPORT PINB +#define PB2_WPORT PORTB +#define PB2_DDR DDRB +#define PB2_PWM NULL +#undef PB3 +#define PB3_PIN PINB3 +#define PB3_RPORT PINB +#define PB3_WPORT PORTB +#define PB3_DDR DDRB +#define PB3_PWM NULL +#undef PB4 +#define PB4_PIN PINB4 +#define PB4_RPORT PINB +#define PB4_WPORT PORTB +#define PB4_DDR DDRB +#define PB4_PWM &OCR2A +#undef PB5 +#define PB5_PIN PINB5 +#define PB5_RPORT PINB +#define PB5_WPORT PORTB +#define PB5_DDR DDRB +#define PB5_PWM NULL +#undef PB6 +#define PB6_PIN PINB6 +#define PB6_RPORT PINB +#define PB6_WPORT PORTB +#define PB6_DDR DDRB +#define PB6_PWM NULL +#undef PB7 +#define PB7_PIN PINB7 +#define PB7_RPORT PINB +#define PB7_WPORT PORTB +#define PB7_DDR DDRB +#define PB7_PWM &OCR0A + +#undef PC0 +#define PC0_PIN PINC0 +#define PC0_RPORT PINC +#define PC0_WPORT PORTC +#define PC0_DDR DDRC +#define PC0_PWM NULL +#undef PC1 +#define PC1_PIN PINC1 +#define PC1_RPORT PINC +#define PC1_WPORT PORTC +#define PC1_DDR DDRC +#define PC1_PWM NULL +#undef PC2 +#define PC2_PIN PINC2 +#define PC2_RPORT PINC +#define PC2_WPORT PORTC +#define PC2_DDR DDRC +#define PC2_PWM NULL +#undef PC3 +#define PC3_PIN PINC3 +#define PC3_RPORT PINC +#define PC3_WPORT PORTC +#define PC3_DDR DDRC +#define PC3_PWM NULL +#undef PC4 +#define PC4_PIN PINC4 +#define PC4_RPORT PINC +#define PC4_WPORT PORTC +#define PC4_DDR DDRC +#define PC4_PWM NULL +#undef PC5 +#define PC5_PIN PINC5 +#define PC5_RPORT PINC +#define PC5_WPORT PORTC +#define PC5_DDR DDRC +#define PC5_PWM NULL +#undef PC6 +#define PC6_PIN PINC6 +#define PC6_RPORT PINC +#define PC6_WPORT PORTC +#define PC6_DDR DDRC +#define PC6_PWM NULL +#undef PC7 +#define PC7_PIN PINC7 +#define PC7_RPORT PINC +#define PC7_WPORT PORTC +#define PC7_DDR DDRC +#define PC7_PWM NULL + +#undef PD0 +#define PD0_PIN PIND0 +#define PD0_RPORT PIND +#define PD0_WPORT PORTD +#define PD0_DDR DDRD +#define PD0_PWM NULL +#undef PD1 +#define PD1_PIN PIND1 +#define PD1_RPORT PIND +#define PD1_WPORT PORTD +#define PD1_DDR DDRD +#define PD1_PWM NULL +#undef PD2 +#define PD2_PIN PIND2 +#define PD2_RPORT PIND +#define PD2_WPORT PORTD +#define PD2_DDR DDRD +#define PD2_PWM NULL +#undef PD3 +#define PD3_PIN PIND3 +#define PD3_RPORT PIND +#define PD3_WPORT PORTD +#define PD3_DDR DDRD +#define PD3_PWM NULL +#undef PD4 +#define PD4_PIN PIND4 +#define PD4_RPORT PIND +#define PD4_WPORT PORTD +#define PD4_DDR DDRD +#define PD4_PWM NULL +#undef PD5 +#define PD5_PIN PIND5 +#define PD5_RPORT PIND +#define PD5_WPORT PORTD +#define PD5_DDR DDRD +#define PD5_PWM NULL +#undef PD6 +#define PD6_PIN PIND6 +#define PD6_RPORT PIND +#define PD6_WPORT PORTD +#define PD6_DDR DDRD +#define PD6_PWM NULL +#undef PD7 +#define PD7_PIN PIND7 +#define PD7_RPORT PIND +#define PD7_WPORT PORTD +#define PD7_DDR DDRD +#define PD7_PWM NULL + +#undef PE0 +#define PE0_PIN PINE0 +#define PE0_RPORT PINE +#define PE0_WPORT PORTE +#define PE0_DDR DDRE +#define PE0_PWM NULL +#undef PE1 +#define PE1_PIN PINE1 +#define PE1_RPORT PINE +#define PE1_WPORT PORTE +#define PE1_DDR DDRE +#define PE1_PWM NULL +#undef PE2 +#define PE2_PIN PINE2 +#define PE2_RPORT PINE +#define PE2_WPORT PORTE +#define PE2_DDR DDRE +#define PE2_PWM NULL +#undef PE3 +#define PE3_PIN PINE3 +#define PE3_RPORT PINE +#define PE3_WPORT PORTE +#define PE3_DDR DDRE +#define PE3_PWM &OCR3AL +#undef PE4 +#define PE4_PIN PINE4 +#define PE4_RPORT PINE +#define PE4_WPORT PORTE +#define PE4_DDR DDRE +#define PE4_PWM &OCR3BL +#undef PE5 +#define PE5_PIN PINE5 +#define PE5_RPORT PINE +#define PE5_WPORT PORTE +#define PE5_DDR DDRE +#define PE5_PWM &OCR3CL +#undef PE6 +#define PE6_PIN PINE6 +#define PE6_RPORT PINE +#define PE6_WPORT PORTE +#define PE6_DDR DDRE +#define PE6_PWM NULL +#undef PE7 +#define PE7_PIN PINE7 +#define PE7_RPORT PINE +#define PE7_WPORT PORTE +#define PE7_DDR DDRE +#define PE7_PWM NULL + +#undef PF0 +#define PF0_PIN PINF0 +#define PF0_RPORT PINF +#define PF0_WPORT PORTF +#define PF0_DDR DDRF +#define PF0_PWM NULL +#undef PF1 +#define PF1_PIN PINF1 +#define PF1_RPORT PINF +#define PF1_WPORT PORTF +#define PF1_DDR DDRF +#define PF1_PWM NULL +#undef PF2 +#define PF2_PIN PINF2 +#define PF2_RPORT PINF +#define PF2_WPORT PORTF +#define PF2_DDR DDRF +#define PF2_PWM NULL +#undef PF3 +#define PF3_PIN PINF3 +#define PF3_RPORT PINF +#define PF3_WPORT PORTF +#define PF3_DDR DDRF +#define PF3_PWM NULL +#undef PF4 +#define PF4_PIN PINF4 +#define PF4_RPORT PINF +#define PF4_WPORT PORTF +#define PF4_DDR DDRF +#define PF4_PWM NULL +#undef PF5 +#define PF5_PIN PINF5 +#define PF5_RPORT PINF +#define PF5_WPORT PORTF +#define PF5_DDR DDRF +#define PF5_PWM NULL +#undef PF6 +#define PF6_PIN PINF6 +#define PF6_RPORT PINF +#define PF6_WPORT PORTF +#define PF6_DDR DDRF +#define PF6_PWM NULL +#undef PF7 +#define PF7_PIN PINF7 +#define PF7_RPORT PINF +#define PF7_WPORT PORTF +#define PF7_DDR DDRF +#define PF7_PWM NULL + +#undef PG0 +#define PG0_PIN PING0 +#define PG0_RPORT PING +#define PG0_WPORT PORTG +#define PG0_DDR DDRG +#define PG0_PWM NULL +#undef PG1 +#define PG1_PIN PING1 +#define PG1_RPORT PING +#define PG1_WPORT PORTG +#define PG1_DDR DDRG +#define PG1_PWM NULL +#undef PG2 +#define PG2_PIN PING2 +#define PG2_RPORT PING +#define PG2_WPORT PORTG +#define PG2_DDR DDRG +#define PG2_PWM NULL +#undef PG3 +#define PG3_PIN PING3 +#define PG3_RPORT PING +#define PG3_WPORT PORTG +#define PG3_DDR DDRG +#define PG3_PWM NULL +#undef PG4 +#define PG4_PIN PING4 +#define PG4_RPORT PING +#define PG4_WPORT PORTG +#define PG4_DDR DDRG +#define PG4_PWM NULL +#undef PG5 +#define PG5_PIN PING5 +#define PG5_RPORT PING +#define PG5_WPORT PORTG +#define PG5_DDR DDRG +#define PG5_PWM &OCR0B +#undef PG6 +#define PG6_PIN PING6 +#define PG6_RPORT PING +#define PG6_WPORT PORTG +#define PG6_DDR DDRG +#define PG6_PWM NULL +#undef PG7 +#define PG7_PIN PING7 +#define PG7_RPORT PING +#define PG7_WPORT PORTG +#define PG7_DDR DDRG +#define PG7_PWM NULL + +#undef PH0 +#define PH0_PIN PINH0 +#define PH0_RPORT PINH +#define PH0_WPORT PORTH +#define PH0_DDR DDRH +#define PH0_PWM NULL +#undef PH1 +#define PH1_PIN PINH1 +#define PH1_RPORT PINH +#define PH1_WPORT PORTH +#define PH1_DDR DDRH +#define PH1_PWM NULL +#undef PH2 +#define PH2_PIN PINH2 +#define PH2_RPORT PINH +#define PH2_WPORT PORTH +#define PH2_DDR DDRH +#define PH2_PWM NULL +#undef PH3 +#define PH3_PIN PINH3 +#define PH3_RPORT PINH +#define PH3_WPORT PORTH +#define PH3_DDR DDRH +#define PH3_PWM &OCR4AL +#undef PH4 +#define PH4_PIN PINH4 +#define PH4_RPORT PINH +#define PH4_WPORT PORTH +#define PH4_DDR DDRH +#define PH4_PWM &OCR4BL +#undef PH5 +#define PH5_PIN PINH5 +#define PH5_RPORT PINH +#define PH5_WPORT PORTH +#define PH5_DDR DDRH +#define PH5_PWM &OCR4CL +#undef PH6 +#define PH6_PIN PINH6 +#define PH6_RPORT PINH +#define PH6_WPORT PORTH +#define PH6_DDR DDRH +#define PH6_PWM &OCR2B +#undef PH7 +#define PH7_PIN PINH7 +#define PH7_RPORT PINH +#define PH7_WPORT PORTH +#define PH7_DDR DDRH +#define PH7_PWM NULL + +#undef PJ0 +#define PJ0_PIN PINJ0 +#define PJ0_RPORT PINJ +#define PJ0_WPORT PORTJ +#define PJ0_DDR DDRJ +#define PJ0_PWM NULL +#undef PJ1 +#define PJ1_PIN PINJ1 +#define PJ1_RPORT PINJ +#define PJ1_WPORT PORTJ +#define PJ1_DDR DDRJ +#define PJ1_PWM NULL +#undef PJ2 +#define PJ2_PIN PINJ2 +#define PJ2_RPORT PINJ +#define PJ2_WPORT PORTJ +#define PJ2_DDR DDRJ +#define PJ2_PWM NULL +#undef PJ3 +#define PJ3_PIN PINJ3 +#define PJ3_RPORT PINJ +#define PJ3_WPORT PORTJ +#define PJ3_DDR DDRJ +#define PJ3_PWM NULL +#undef PJ4 +#define PJ4_PIN PINJ4 +#define PJ4_RPORT PINJ +#define PJ4_WPORT PORTJ +#define PJ4_DDR DDRJ +#define PJ4_PWM NULL +#undef PJ5 +#define PJ5_PIN PINJ5 +#define PJ5_RPORT PINJ +#define PJ5_WPORT PORTJ +#define PJ5_DDR DDRJ +#define PJ5_PWM NULL +#undef PJ6 +#define PJ6_PIN PINJ6 +#define PJ6_RPORT PINJ +#define PJ6_WPORT PORTJ +#define PJ6_DDR DDRJ +#define PJ6_PWM NULL +#undef PJ7 +#define PJ7_PIN PINJ7 +#define PJ7_RPORT PINJ +#define PJ7_WPORT PORTJ +#define PJ7_DDR DDRJ +#define PJ7_PWM NULL + +#undef PK0 +#define PK0_PIN PINK0 +#define PK0_RPORT PINK +#define PK0_WPORT PORTK +#define PK0_DDR DDRK +#define PK0_PWM NULL +#undef PK1 +#define PK1_PIN PINK1 +#define PK1_RPORT PINK +#define PK1_WPORT PORTK +#define PK1_DDR DDRK +#define PK1_PWM NULL +#undef PK2 +#define PK2_PIN PINK2 +#define PK2_RPORT PINK +#define PK2_WPORT PORTK +#define PK2_DDR DDRK +#define PK2_PWM NULL +#undef PK3 +#define PK3_PIN PINK3 +#define PK3_RPORT PINK +#define PK3_WPORT PORTK +#define PK3_DDR DDRK +#define PK3_PWM NULL +#undef PK4 +#define PK4_PIN PINK4 +#define PK4_RPORT PINK +#define PK4_WPORT PORTK +#define PK4_DDR DDRK +#define PK4_PWM NULL +#undef PK5 +#define PK5_PIN PINK5 +#define PK5_RPORT PINK +#define PK5_WPORT PORTK +#define PK5_DDR DDRK +#define PK5_PWM NULL +#undef PK6 +#define PK6_PIN PINK6 +#define PK6_RPORT PINK +#define PK6_WPORT PORTK +#define PK6_DDR DDRK +#define PK6_PWM NULL +#undef PK7 +#define PK7_PIN PINK7 +#define PK7_RPORT PINK +#define PK7_WPORT PORTK +#define PK7_DDR DDRK +#define PK7_PWM NULL + +#undef PL0 +#define PL0_PIN PINL0 +#define PL0_RPORT PINL +#define PL0_WPORT PORTL +#define PL0_DDR DDRL +#define PL0_PWM NULL +#undef PL1 +#define PL1_PIN PINL1 +#define PL1_RPORT PINL +#define PL1_WPORT PORTL +#define PL1_DDR DDRL +#define PL1_PWM NULL +#undef PL2 +#define PL2_PIN PINL2 +#define PL2_RPORT PINL +#define PL2_WPORT PORTL +#define PL2_DDR DDRL +#define PL2_PWM NULL +#undef PL3 +#define PL3_PIN PINL3 +#define PL3_RPORT PINL +#define PL3_WPORT PORTL +#define PL3_DDR DDRL +#define PL3_PWM &OCR5AL +#undef PL4 +#define PL4_PIN PINL4 +#define PL4_RPORT PINL +#define PL4_WPORT PORTL +#define PL4_DDR DDRL +#define PL4_PWM &OCR5BL +#undef PL5 +#define PL5_PIN PINL5 +#define PL5_RPORT PINL +#define PL5_WPORT PORTL +#define PL5_DDR DDRL +#define PL5_PWM &OCR5CL +#undef PL6 +#define PL6_PIN PINL6 +#define PL6_RPORT PINL +#define PL6_WPORT PORTL +#define PL6_DDR DDRL +#define PL6_PWM NULL +#undef PL7 +#define PL7_PIN PINL7 +#define PL7_RPORT PINL +#define PL7_WPORT PORTL +#define PL7_DDR DDRL +#define PL7_PWM NULL + +#endif + +#if defined (__AVR_AT90USB1287__) || defined (__AVR_AT90USB1286__) +// SPI +#define SCK 9 +#define MISO DIO11 +#define MOSI DIO10 +#define SS 8 + +#if MOTHERBOARD != 8 && MOTHERBOARD != 9 && MOTHERBOARD != 88 +// change for your board +#define DEBUG_LED DIO31 /* led D5 red */ + +/* +pins +*/ +#define DIO0_PIN PINA0 +#define DIO0_RPORT PINA +#define DIO0_WPORT PORTA +#define DIO0_PWM NULL +#define DIO0_DDR DDRA + +#define DIO1_PIN PINA1 +#define DIO1_RPORT PINA +#define DIO1_WPORT PORTA +#define DIO1_PWM NULL +#define DIO1_DDR DDRA + +#define DIO2_PIN PINA2 +#define DIO2_RPORT PINA +#define DIO2_WPORT PORTA +#define DIO2_PWM NULL +#define DIO2_DDR DDRA + +#define DIO3_PIN PINA3 +#define DIO3_RPORT PINA +#define DIO3_WPORT PORTA +#define DIO3_PWM NULL +#define DIO3_DDR DDRA + +#define DIO4_PIN PINA4 +#define DIO4_RPORT PINA +#define DIO4_WPORT PORTA +#define DIO4_PWM NULL +#define DIO4_DDR DDRA + +#define DIO5_PIN PINA5 +#define DIO5_RPORT PINA +#define DIO5_WPORT PORTA +#define DIO5_PWM NULL +#define DIO5_DDR DDRA + +#define DIO6_PIN PINA6 +#define DIO6_RPORT PINA +#define DIO6_WPORT PORTA +#define DIO6_PWM NULL +#define DIO6_DDR DDRA + +#define DIO7_PIN PINA7 +#define DIO7_RPORT PINA +#define DIO7_WPORT PORTA +#define DIO7_PWM NULL +#define DIO7_DDR DDRA + +#define DIO8_PIN PINB0 +#define DIO8_RPORT PINB +#define DIO8_WPORT PORTB +#define DIO8_PWM NULL +#define DIO8_DDR DDRB + +#define DIO9_PIN PINB1 +#define DIO9_RPORT PINB +#define DIO9_WPORT PORTB +#define DIO9_PWM NULL +#define DIO9_DDR DDRB + +#define DIO10_PIN PINB2 +#define DIO10_RPORT PINB +#define DIO10_WPORT PORTB +#define DIO10_PWM NULL +#define DIO10_DDR DDRB + +#define DIO11_PIN PINB3 +#define DIO11_RPORT PINB +#define DIO11_WPORT PORTB +#define DIO11_PWM NULL +#define DIO11_DDR DDRB + +#define DIO12_PIN PINB4 +#define DIO12_RPORT PINB +#define DIO12_WPORT PORTB +#define DIO12_PWM NULL +#define DIO12_DDR DDRB + +#define DIO13_PIN PINB5 +#define DIO13_RPORT PINB +#define DIO13_WPORT PORTB +#define DIO13_PWM NULL +#define DIO13_DDR DDRB + +#define DIO14_PIN PINB6 +#define DIO14_RPORT PINB +#define DIO14_WPORT PORTB +#define DIO14_PWM NULL +#define DIO14_DDR DDRB + +#define DIO15_PIN PINB7 +#define DIO15_RPORT PINB +#define DIO15_WPORT PORTB +#define DIO15_PWM NULL +#define DIO15_DDR DDRB + +#define DIO16_PIN PINC0 +#define DIO16_RPORT PINC +#define DIO16_WPORT PORTC +#define DIO16_PWM NULL +#define DIO16_DDR DDRC + +#define DIO17_PIN PINC1 +#define DIO17_RPORT PINC +#define DIO17_WPORT PORTC +#define DIO17_PWM NULL +#define DIO17_DDR DDRC + +#define DIO18_PIN PINC2 +#define DIO18_RPORT PINC +#define DIO18_WPORT PORTC +#define DIO18_PWM NULL +#define DIO18_DDR DDRC + +#define DIO19_PIN PINC3 +#define DIO19_RPORT PINC +#define DIO19_WPORT PORTC +#define DIO19_PWM NULL +#define DIO19_DDR DDRC + +#define DIO20_PIN PINC4 +#define DIO20_RPORT PINC +#define DIO20_WPORT PORTC +#define DIO20_PWM NULL +#define DIO20_DDR DDRC + +#define DIO21_PIN PINC5 +#define DIO21_RPORT PINC +#define DIO21_WPORT PORTC +#define DIO21_PWM NULL +#define DIO21_DDR DDRC + +#define DIO22_PIN PINC6 +#define DIO22_RPORT PINC +#define DIO22_WPORT PORTC +#define DIO22_PWM NULL +#define DIO22_DDR DDRC + +#define DIO23_PIN PINC7 +#define DIO23_RPORT PINC +#define DIO23_WPORT PORTC +#define DIO23_PWM NULL +#define DIO23_DDR DDRC + +#define DIO24_PIN PIND0 +#define DIO24_RPORT PIND +#define DIO24_WPORT PORTD +#define DIO24_PWM NULL +#define DIO24_DDR DDRD + +#define DIO25_PIN PIND1 +#define DIO25_RPORT PIND +#define DIO25_WPORT PORTD +#define DIO25_PWM NULL +#define DIO25_DDR DDRD + +#define DIO26_PIN PIND2 +#define DIO26_RPORT PIND +#define DIO26_WPORT PORTD +#define DIO26_PWM NULL +#define DIO26_DDR DDRD + +#define DIO27_PIN PIND3 +#define DIO27_RPORT PIND +#define DIO27_WPORT PORTD +#define DIO27_PWM NULL +#define DIO27_DDR DDRD + +#define DIO28_PIN PIND4 +#define DIO28_RPORT PIND +#define DIO28_WPORT PORTD +#define DIO28_PWM NULL +#define DIO28_DDR DDRD + +#define DIO29_PIN PIND5 +#define DIO29_RPORT PIND +#define DIO29_WPORT PORTD +#define DIO29_PWM NULL +#define DIO29_DDR DDRD + +#define DIO30_PIN PIND6 +#define DIO30_RPORT PIND +#define DIO30_WPORT PORTD +#define DIO30_PWM NULL +#define DIO30_DDR DDRD + +#define DIO31_PIN PIND7 +#define DIO31_RPORT PIND +#define DIO31_WPORT PORTD +#define DIO31_PWM NULL +#define DIO31_DDR DDRD + + +#define DIO32_PIN PINE0 +#define DIO32_RPORT PINE +#define DIO32_WPORT PORTE +#define DIO32_PWM NULL +#define DIO32_DDR DDRE + +#define DIO33_PIN PINE1 +#define DIO33_RPORT PINE +#define DIO33_WPORT PORTE +#define DIO33_PWM NULL +#define DIO33_DDR DDRE + +#define DIO34_PIN PINE2 +#define DIO34_RPORT PINE +#define DIO34_WPORT PORTE +#define DIO34_PWM NULL +#define DIO34_DDR DDRE + +#define DIO35_PIN PINE3 +#define DIO35_RPORT PINE +#define DIO35_WPORT PORTE +#define DIO35_PWM NULL +#define DIO35_DDR DDRE + +#define DIO36_PIN PINE4 +#define DIO36_RPORT PINE +#define DIO36_WPORT PORTE +#define DIO36_PWM NULL +#define DIO36_DDR DDRE + +#define DIO37_PIN PINE5 +#define DIO37_RPORT PINE +#define DIO37_WPORT PORTE +#define DIO37_PWM NULL +#define DIO37_DDR DDRE + +#define DIO38_PIN PINE6 +#define DIO38_RPORT PINE +#define DIO38_WPORT PORTE +#define DIO38_PWM NULL +#define DIO38_DDR DDRE + +#define DIO39_PIN PINE7 +#define DIO39_RPORT PINE +#define DIO39_WPORT PORTE +#define DIO39_PWM NULL +#define DIO39_DDR DDRE + +#define AIO0_PIN PINF0 +#define AIO0_RPORT PINF +#define AIO0_WPORT PORTF +#define AIO0_PWM NULL +#define AIO0_DDR DDRF + +#define AIO1_PIN PINF1 +#define AIO1_RPORT PINF +#define AIO1_WPORT PORTF +#define AIO1_PWM NULL +#define AIO1_DDR DDRF + +#define AIO2_PIN PINF2 +#define AIO2_RPORT PINF +#define AIO2_WPORT PORTF +#define AIO2_PWM NULL +#define AIO2_DDR DDRF + +#define AIO3_PIN PINF3 +#define AIO3_RPORT PINF +#define AIO3_WPORT PORTF +#define AIO3_PWM NULL +#define AIO3_DDR DDRF + +#define AIO4_PIN PINF4 +#define AIO4_RPORT PINF +#define AIO4_WPORT PORTF +#define AIO4_PWM NULL +#define AIO4_DDR DDRF + +#define AIO5_PIN PINF5 +#define AIO5_RPORT PINF +#define AIO5_WPORT PORTF +#define AIO5_PWM NULL +#define AIO5_DDR DDRF + +#define AIO6_PIN PINF6 +#define AIO6_RPORT PINF +#define AIO6_WPORT PORTF +#define AIO6_PWM NULL +#define AIO6_DDR DDRF + +#define AIO7_PIN PINF7 +#define AIO7_RPORT PINF +#define AIO7_WPORT PORTF +#define AIO7_PWM NULL +#define AIO7_DDR DDRF + +#define DIO40_PIN PINF0 +#define DIO40_RPORT PINF +#define DIO40_WPORT PORTF +#define DIO40_PWM NULL +#define DIO40_DDR DDRF + +#define DIO41_PIN PINF1 +#define DIO41_RPORT PINF +#define DIO41_WPORT PORTF +#define DIO41_PWM NULL +#define DIO41_DDR DDRF + +#define DIO42_PIN PINF2 +#define DIO42_RPORT PINF +#define DIO42_WPORT PORTF +#define DIO42_PWM NULL +#define DIO42_DDR DDRF + +#define DIO43_PIN PINF3 +#define DIO43_RPORT PINF +#define DIO43_WPORT PORTF +#define DIO43_PWM NULL +#define DIO43_DDR DDRF + +#define DIO44_PIN PINF4 +#define DIO44_RPORT PINF +#define DIO44_WPORT PORTF +#define DIO44_PWM NULL +#define DIO44_DDR DDRF + +#define DIO45_PIN PINF5 +#define DIO45_RPORT PINF +#define DIO45_WPORT PORTF +#define DIO45_PWM NULL +#define DIO45_DDR DDRF + +#define DIO46_PIN PINF6 +#define DIO46_RPORT PINF +#define DIO46_WPORT PORTF +#define DIO46_PWM NULL +#define DIO46_DDR DDRF + +#define DIO47_PIN PINF7 +#define DIO47_RPORT PINF +#define DIO47_WPORT PORTF +#define DIO47_PWM NULL +#define DIO47_DDR DDRF + +#else +/* +pins +*/ +#define DIO0_PIN PIND0 +#define DIO0_RPORT PIND +#define DIO0_WPORT PORTD +#define DIO0_PWM NULL +#define DIO0_DDR DDRD + +#define DIO1_PIN PIND1 +#define DIO1_RPORT PIND +#define DIO1_WPORT PORTD +#define DIO1_PWM NULL +#define DIO1_DDR DDRD + +#define DIO2_PIN PIND2 +#define DIO2_RPORT PIND +#define DIO2_WPORT PORTD +#define DIO2_PWM NULL +#define DIO2_DDR DDRD + +#define DIO3_PIN PIND3 +#define DIO3_RPORT PIND +#define DIO3_WPORT PORTD +#define DIO3_PWM NULL +#define DIO3_DDR DDRD + +#define DIO4_PIN PIND4 +#define DIO4_RPORT PIND +#define DIO4_WPORT PORTD +#define DIO4_PWM NULL +#define DIO4_DDR DDRD + +#define DIO5_PIN PIND5 +#define DIO5_RPORT PIND +#define DIO5_WPORT PORTD +#define DIO5_PWM NULL +#define DIO5_DDR DDRD + +#define DIO6_PIN PIND6 +#define DIO6_RPORT PIND +#define DIO6_WPORT PORTD +#define DIO6_PWM NULL +#define DIO6_DDR DDRD + +#define DIO7_PIN PIND7 +#define DIO7_RPORT PIND +#define DIO7_WPORT PORTD +#define DIO7_PWM NULL +#define DIO7_DDR DDRD + +#define DIO8_PIN PINE0 +#define DIO8_RPORT PINE +#define DIO8_WPORT PORTE +#define DIO8_PWM NULL +#define DIO8_DDR DDRE + +#define DIO9_PIN PINE1 +#define DIO9_RPORT PINE +#define DIO9_WPORT PORTE +#define DIO9_PWM NULL +#define DIO9_DDR DDRE + +#define DIO10_PIN PINC0 +#define DIO10_RPORT PINC +#define DIO10_WPORT PORTC +#define DIO10_PWM NULL +#define DIO10_DDR DDRC + +#define DIO11_PIN PINC1 +#define DIO11_RPORT PINC +#define DIO11_WPORT PORTC +#define DIO11_PWM NULL +#define DIO11_DDR DDRC + +#define DIO12_PIN PINC2 +#define DIO12_RPORT PINC +#define DIO12_WPORT PORTC +#define DIO12_PWM NULL +#define DIO12_DDR DDRC + +#define DIO13_PIN PINC3 +#define DIO13_RPORT PINC +#define DIO13_WPORT PORTC +#define DIO13_PWM NULL +#define DIO13_DDR DDRC + +#define DIO14_PIN PINC4 +#define DIO14_RPORT PINC +#define DIO14_WPORT PORTC +#define DIO14_PWM NULL +#define DIO14_DDR DDRC + +#define DIO15_PIN PINC5 +#define DIO15_RPORT PINC +#define DIO15_WPORT PORTC +#define DIO15_PWM NULL +#define DIO15_DDR DDRC + +#define DIO16_PIN PINC6 +#define DIO16_RPORT PINC +#define DIO16_WPORT PORTC +#define DIO16_PWM NULL +#define DIO16_DDR DDRC + +#define DIO17_PIN PINC7 +#define DIO17_RPORT PINC +#define DIO17_WPORT PORTC +#define DIO17_PWM NULL +#define DIO17_DDR DDRC + +#define DIO18_PIN PINE6 +#define DIO18_RPORT PINE +#define DIO18_WPORT PORTE +#define DIO18_PWM NULL +#define DIO18_DDR DDRE + +#define DIO19_PIN PINE7 +#define DIO19_RPORT PINE +#define DIO19_WPORT PORTE +#define DIO19_PWM NULL +#define DIO19_DDR DDRE + +#define DIO20_PIN PINB0 +#define DIO20_RPORT PINB +#define DIO20_WPORT PORTB +#define DIO20_PWM NULL +#define DIO20_DDR DDRB + +#define DIO21_PIN PINB1 +#define DIO21_RPORT PINB +#define DIO21_WPORT PORTB +#define DIO21_PWM NULL +#define DIO21_DDR DDRB + +#define DIO22_PIN PINB2 +#define DIO22_RPORT PINB +#define DIO22_WPORT PORTB +#define DIO22_PWM NULL +#define DIO22_DDR DDRB + +#define DIO23_PIN PINB3 +#define DIO23_RPORT PINB +#define DIO23_WPORT PORTB +#define DIO23_PWM NULL +#define DIO23_DDR DDRB + +#define DIO24_PIN PINB4 +#define DIO24_RPORT PINB +#define DIO24_WPORT PORTB +#define DIO24_PWM NULL +#define DIO24_DDR DDRB + +#define DIO25_PIN PINB5 +#define DIO25_RPORT PINB +#define DIO25_WPORT PORTB +#define DIO25_PWM NULL +#define DIO25_DDR DDRB + +#define DIO26_PIN PINB6 +#define DIO26_RPORT PINB +#define DIO26_WPORT PORTB +#define DIO26_PWM NULL +#define DIO26_DDR DDRB + +#define DIO27_PIN PINB7 +#define DIO27_RPORT PINB +#define DIO27_WPORT PORTB +#define DIO27_PWM NULL +#define DIO27_DDR DDRB + +#define DIO28_PIN PINA0 +#define DIO28_RPORT PINA +#define DIO28_WPORT PORTA +#define DIO28_PWM NULL +#define DIO28_DDR DDRA + +#define DIO29_PIN PINA1 +#define DIO29_RPORT PINA +#define DIO29_WPORT PORTA +#define DIO29_PWM NULL +#define DIO29_DDR DDRA + +#define DIO30_PIN PINA2 +#define DIO30_RPORT PINA +#define DIO30_WPORT PORTA +#define DIO30_PWM NULL +#define DIO30_DDR DDRA + +#define DIO31_PIN PINA3 +#define DIO31_RPORT PINA +#define DIO31_WPORT PORTA +#define DIO31_PWM NULL +#define DIO31_DDR DDRA + + +#define DIO32_PIN PINA4 +#define DIO32_RPORT PINA +#define DIO32_WPORT PORTA +#define DIO32_PWM NULL +#define DIO32_DDR DDRA + +#define DIO33_PIN PINA5 +#define DIO33_RPORT PINA +#define DIO33_WPORT PORTA +#define DIO33_PWM NULL +#define DIO33_DDR DDRA + +#define DIO34_PIN PINA6 +#define DIO34_RPORT PINA +#define DIO34_WPORT PORTA +#define DIO34_PWM NULL +#define DIO34_DDR DDRA + +#define DIO35_PIN PINA7 +#define DIO35_RPORT PINA +#define DIO35_WPORT PORTA +#define DIO35_PWM NULL +#define DIO35_DDR DDRA + +#define DIO36_PIN PINE4 +#define DIO36_RPORT PINE +#define DIO36_WPORT PORTE +#define DIO36_PWM NULL +#define DIO36_DDR DDRE + +#define DIO37_PIN PINE5 +#define DIO37_RPORT PINE +#define DIO37_WPORT PORTE +#define DIO37_PWM NULL +#define DIO37_DDR DDRE + +#define DIO38_PIN PINF0 +#define DIO38_RPORT PINF +#define DIO38_WPORT PORTF +#define DIO38_PWM NULL +#define DIO38_DDR DDRF + +#define DIO39_PIN PINF1 +#define DIO39_RPORT PINF +#define DIO39_WPORT PORTF +#define DIO39_PWM NULL +#define DIO39_DDR DDRF + +#define DIO40_PIN PINF2 +#define DIO40_RPORT PINF +#define DIO40_WPORT PORTF +#define DIO40_PWM NULL +#define DIO40_DDR DDRF + +#define DIO41_PIN PINF3 +#define DIO41_RPORT PINF +#define DIO41_WPORT PORTF +#define DIO41_PWM NULL +#define DIO41_DDR DDRF + +#define DIO42_PIN PINF4 +#define DIO42_RPORT PINF +#define DIO42_WPORT PORTF +#define DIO42_PWM NULL +#define DIO42_DDR DDRF + +#define DIO43_PIN PINF5 +#define DIO43_RPORT PINF +#define DIO43_WPORT PORTF +#define DIO43_PWM NULL +#define DIO43_DDR DDRF + +#define DIO44_PIN PINF6 +#define DIO44_RPORT PINF +#define DIO44_WPORT PORTF +#define DIO44_PWM NULL +#define DIO44_DDR DDRF + +#define DIO45_PIN PINF7 +#define DIO45_RPORT PINF +#define DIO45_WPORT PORTF +#define DIO45_PWM NULL +#define DIO45_DDR DDRF + +#define AIO0_PIN PINF0 +#define AIO0_RPORT PINF +#define AIO0_WPORT PORTF +#define AIO0_PWM NULL +#define AIO0_DDR DDRF + +#define AIO1_PIN PINF1 +#define AIO1_RPORT PINF +#define AIO1_WPORT PORTF +#define AIO1_PWM NULL +#define AIO1_DDR DDRF + +#define AIO2_PIN PINF2 +#define AIO2_RPORT PINF +#define AIO2_WPORT PORTF +#define AIO2_PWM NULL +#define AIO2_DDR DDRF + +#define AIO3_PIN PINF3 +#define AIO3_RPORT PINF +#define AIO3_WPORT PORTF +#define AIO3_PWM NULL +#define AIO3_DDR DDRF + +#define AIO4_PIN PINF4 +#define AIO4_RPORT PINF +#define AIO4_WPORT PORTF +#define AIO4_PWM NULL +#define AIO4_DDR DDRF + +#define AIO5_PIN PINF5 +#define AIO5_RPORT PINF +#define AIO5_WPORT PORTF +#define AIO5_PWM NULL +#define AIO5_DDR DDRF + +#define AIO6_PIN PINF6 +#define AIO6_RPORT PINF +#define AIO6_WPORT PORTF +#define AIO6_PWM NULL +#define AIO6_DDR DDRF + +#define AIO7_PIN PINF7 +#define AIO7_RPORT PINF +#define AIO7_WPORT PORTF +#define AIO7_PWM NULL +#define AIO7_DDR DDRF + +//-- Begin not supported by Teensyduino +//-- don't use Arduino functions on these pins pinMode/digitalWrite/etc +#define DIO46_PIN PINE2 +#define DIO46_RPORT PINE +#define DIO46_WPORT PORTE +#define DIO46_PWM NULL +#define DIO46_DDR DDRE + +#define DIO47_PIN PINE3 +#define DIO47_RPORT PINE +#define DIO47_WPORT PORTE +#define DIO47_PWM NULL +#define DIO47_DDR DDRE +//-- end not supported by Teensyduino + +#endif + + +#undef PA0 +#define PA0_PIN PINA0 +#define PA0_RPORT PINA +#define PA0_WPORT PORTA +#define PA0_PWM NULL +#define PA0_DDR DDRA +#undef PA1 +#define PA1_PIN PINA1 +#define PA1_RPORT PINA +#define PA1_WPORT PORTA +#define PA1_PWM NULL +#define PA1_DDR DDRA +#undef PA2 +#define PA2_PIN PINA2 +#define PA2_RPORT PINA +#define PA2_WPORT PORTA +#define PA2_PWM NULL +#define PA2_DDR DDRA +#undef PA3 +#define PA3_PIN PINA3 +#define PA3_RPORT PINA +#define PA3_WPORT PORTA +#define PA3_PWM NULL +#define PA3_DDR DDRA +#undef PA4 +#define PA4_PIN PINA4 +#define PA4_RPORT PINA +#define PA4_WPORT PORTA +#define PA4_PWM NULL +#define PA4_DDR DDRA +#undef PA5 +#define PA5_PIN PINA5 +#define PA5_RPORT PINA +#define PA5_WPORT PORTA +#define PA5_PWM NULL +#define PA5_DDR DDRA +#undef PA6 +#define PA6_PIN PINA6 +#define PA6_RPORT PINA +#define PA6_WPORT PORTA +#define PA6_PWM NULL +#define PA6_DDR DDRA +#undef PA7 +#define PA7_PIN PINA7 +#define PA7_RPORT PINA +#define PA7_WPORT PORTA +#define PA7_PWM NULL +#define PA7_DDR DDRA + +#undef PB0 +#define PB0_PIN PINB0 +#define PB0_RPORT PINB +#define PB0_WPORT PORTB +#define PB0_PWM NULL +#define PB0_DDR DDRB +#undef PB1 +#define PB1_PIN PINB1 +#define PB1_RPORT PINB +#define PB1_WPORT PORTB +#define PB1_PWM NULL +#define PB1_DDR DDRB +#undef PB2 +#define PB2_PIN PINB2 +#define PB2_RPORT PINB +#define PB2_WPORT PORTB +#define PB2_PWM NULL +#define PB2_DDR DDRB +#undef PB3 +#define PB3_PIN PINB3 +#define PB3_RPORT PINB +#define PB3_WPORT PORTB +#define PB3_PWM NULL +#define PB3_DDR DDRB +#undef PB4 +#define PB4_PIN PINB4 +#define PB4_RPORT PINB +#define PB4_WPORT PORTB +#define PB4_PWM NULL +#define PB4_DDR DDRB +#undef PB5 +#define PB5_PIN PINB5 +#define PB5_RPORT PINB +#define PB5_WPORT PORTB +#define PB5_PWM NULL +#define PB5_DDR DDRB +#undef PB6 +#define PB6_PIN PINB6 +#define PB6_RPORT PINB +#define PB6_WPORT PORTB +#define PB6_PWM NULL +#define PB6_DDR DDRB +#undef PB7 +#define PB7_PIN PINB7 +#define PB7_RPORT PINB +#define PB7_WPORT PORTB +#define PB7_PWM NULL +#define PB7_DDR DDRB + +#undef PC0 +#define PC0_PIN PINC0 +#define PC0_RPORT PINC +#define PC0_WPORT PORTC +#define PC0_PWM NULL +#define PC0_DDR DDRC +#undef PC1 +#define PC1_PIN PINC1 +#define PC1_RPORT PINC +#define PC1_WPORT PORTC +#define PC1_PWM NULL +#define PC1_DDR DDRC +#undef PC2 +#define PC2_PIN PINC2 +#define PC2_RPORT PINC +#define PC2_WPORT PORTC +#define PC2_PWM NULL +#define PC2_DDR DDRC +#undef PC3 +#define PC3_PIN PINC3 +#define PC3_RPORT PINC +#define PC3_WPORT PORTC +#define PC3_PWM NULL +#define PC3_DDR DDRC +#undef PC4 +#define PC4_PIN PINC4 +#define PC4_RPORT PINC +#define PC4_WPORT PORTC +#define PC4_PWM NULL +#define PC4_DDR DDRC +#undef PC5 +#define PC5_PIN PINC5 +#define PC5_RPORT PINC +#define PC5_WPORT PORTC +#define PC5_PWM NULL +#define PC5_DDR DDRC +#undef PC6 +#define PC6_PIN PINC6 +#define PC6_RPORT PINC +#define PC6_WPORT PORTC +#define PC6_PWM NULL +#define PC6_DDR DDRC +#undef PC7 +#define PC7_PIN PINC7 +#define PC7_RPORT PINC +#define PC7_WPORT PORTC +#define PC7_PWM NULL +#define PC7_DDR DDRC + +#undef PD0 +#define PD0_PIN PIND0 +#define PD0_RPORT PIND +#define PD0_WPORT PORTD +#define PD0_PWM NULL +#define PD0_DDR DDRD +#undef PD1 +#define PD1_PIN PIND1 +#define PD1_RPORT PIND +#define PD1_WPORT PORTD +#define PD1_PWM NULL +#define PD1_DDR DDRD +#undef PD2 +#define PD2_PIN PIND2 +#define PD2_RPORT PIND +#define PD2_WPORT PORTD +#define PD2_PWM NULL +#define PD2_DDR DDRD +#undef PD3 +#define PD3_PIN PIND3 +#define PD3_RPORT PIND +#define PD3_WPORT PORTD +#define PD3_PWM NULL +#define PD3_DDR DDRD +#undef PD4 +#define PD4_PIN PIND4 +#define PD4_RPORT PIND +#define PD4_WPORT PORTD +#define PD4_PWM NULL +#define PD4_DDR DDRD +#undef PD5 +#define PD5_PIN PIND5 +#define PD5_RPORT PIND +#define PD5_WPORT PORTD +#define PD5_PWM NULL +#define PD5_DDR DDRD +#undef PD6 +#define PD6_PIN PIND6 +#define PD6_RPORT PIND +#define PD6_WPORT PORTD +#define PD6_PWM NULL +#define PD6_DDR DDRD +#undef PD7 +#define PD7_PIN PIND7 +#define PD7_RPORT PIND +#define PD7_WPORT PORTD +#define PD7_PWM NULL +#define PD7_DDR DDRD + +#undef PE0 +#define PE0_PIN PINE0 +#define PE0_RPORT PINE +#define PE0_WPORT PORTE +#define PE0_PWM NULL +#define PE0_DDR DDRE +#undef PE1 +#define PE1_PIN PINE1 +#define PE1_RPORT PINE +#define PE1_WPORT PORTE +#define PE1_PWM NULL +#define PE1_DDR DDRE +#undef PE2 +#define PE2_PIN PINE2 +#define PE2_RPORT PINE +#define PE2_WPORT PORTE +#define PE2_PWM NULL +#define PE2_DDR DDRE +#undef PE3 +#define PE3_PIN PINE3 +#define PE3_RPORT PINE +#define PE3_WPORT PORTE +#define PE3_PWM NULL +#define PE3_DDR DDRE +#undef PE4 +#define PE4_PIN PINE4 +#define PE4_RPORT PINE +#define PE4_WPORT PORTE +#define PE4_PWM NULL +#define PE4_DDR DDRE +#undef PE5 +#define PE5_PIN PINE5 +#define PE5_RPORT PINE +#define PE5_WPORT PORTE +#define PE5_PWM NULL +#define PE5_DDR DDRE +#undef PE6 +#define PE6_PIN PINE6 +#define PE6_RPORT PINE +#define PE6_WPORT PORTE +#define PE6_PWM NULL +#define PE6_DDR DDRE +#undef PE7 +#define PE7_PIN PINE7 +#define PE7_RPORT PINE +#define PE7_WPORT PORTE +#define PE7_PWM NULL +#define PE7_DDR DDRE + +#undef PF0 +#define PF0_PIN PINF0 +#define PF0_RPORT PINF +#define PF0_WPORT PORTF +#define PF0_PWM NULL +#define PF0_DDR DDRF +#undef PF1 +#define PF1_PIN PINF1 +#define PF1_RPORT PINF +#define PF1_WPORT PORTF +#define PF1_PWM NULL +#define PF1_DDR DDRF +#undef PF2 +#define PF2_PIN PINF2 +#define PF2_RPORT PINF +#define PF2_WPORT PORTF +#define PF2_PWM NULL +#define PF2_DDR DDRF +#undef PF3 +#define PF3_PIN PINF3 +#define PF3_RPORT PINF +#define PF3_WPORT PORTF +#define PF3_PWM NULL +#define PF3_DDR DDRF +#undef PF4 +#define PF4_PIN PINF4 +#define PF4_RPORT PINF +#define PF4_WPORT PORTF +#define PF4_PWM NULL +#define PF4_DDR DDRF +#undef PF5 +#define PF5_PIN PINF5 +#define PF5_RPORT PINF +#define PF5_WPORT PORTF +#define PF5_PWM NULL +#define PF5_DDR DDRF +#undef PF6 +#define PF6_PIN PINF6 +#define PF6_RPORT PINF +#define PF6_WPORT PORTF +#define PF6_PWM NULL +#define PF6_DDR DDRF +#undef PF7 +#define PF7_PIN PINF7 +#define PF7_RPORT PINF +#define PF7_WPORT PORTF +#define PF7_PWM NULL +#define PF7_DDR DDRF +#endif + +#if defined (__AVR_ATmega1281__) || defined (__AVR_ATmega2561__) +// UART +#define RXD DIO0 +#define TXD DIO1 + +// SPI +#define SCK 10 +#define MISO DIO12 +#define MOSI DIO11 +#define SS 16 + +// TWI (I2C) +#define SCL DIO17 +#define SDA DIO18 + +// timers and PWM +#define OC0A DIO9 +#define OC0B DIO4 +#define OC1A DIO7 +#define OC1B DIO8 +#define OC2A DIO6 +#define OC3A DIO5 +#define OC3B DIO2 +#define OC3C DIO3 + + +// change for your board +#define DEBUG_LED DIO46 + +/* +pins +*/ +#define DIO0_PIN PINE0 +#define DIO0_RPORT PINE +#define DIO0_WPORT PORTE +#define DIO0_DDR DDRE +#define DIO0_PWM NULL + +#define DIO1_PIN PINE1 +#define DIO1_RPORT PINE +#define DIO1_WPORT PORTE +#define DIO1_DDR DDRE +#define DIO1_PWM NULL + +#define DIO2_PIN PINE4 +#define DIO2_RPORT PINE +#define DIO2_WPORT PORTE +#define DIO2_DDR DDRE +#define DIO2_PWM &OCR3BL + +#define DIO3_PIN PINE5 +#define DIO3_RPORT PINE +#define DIO3_WPORT PORTE +#define DIO3_DDR DDRE +#define DIO3_PWM &OCR3CL + +#define DIO4_PIN PING5 +#define DIO4_RPORT PING +#define DIO4_WPORT PORTG +#define DIO4_DDR DDRG +#define DIO4_PWM &OCR0B + +#define DIO5_PIN PINE3 +#define DIO5_RPORT PINE +#define DIO5_WPORT PORTE +#define DIO5_DDR DDRE +#define DIO5_PWM &OCR3AL + +#define DIO6_PIN PINB4 +#define DIO6_RPORT PINB +#define DIO6_WPORT PORTB +#define DIO6_DDR DDRB +#define DIO6_PWM &OCR2AL + +#define DIO7_PIN PINB5 +#define DIO7_RPORT PINB +#define DIO7_WPORT PORTB +#define DIO7_DDR DDRB +#define DIO7_PWM &OCR1AL + +#define DIO8_PIN PINB6 +#define DIO8_RPORT PINB +#define DIO8_WPORT PORTB +#define DIO8_DDR DDRB +#define DIO8_PWM &OCR1BL + +#define DIO9_PIN PINB7 +#define DIO9_RPORT PINB +#define DIO9_WPORT PORTB +#define DIO9_DDR DDRB +#define DIO9_PWM &OCR0AL + +#define DIO10_PIN PINB1 +#define DIO10_RPORT PINB +#define DIO10_WPORT PORTB +#define DIO10_DDR DDRB +#define DIO10_PWM NULL + +#define DIO11_PIN PINB2 +#define DIO11_RPORT PINB +#define DIO11_WPORT PORTB +#define DIO11_DDR DDRB +#define DIO11_PWM NULL + +#define DIO12_PIN PINB3 +#define DIO12_RPORT PINB +#define DIO12_WPORT PORTB +#define DIO12_DDR DDRB +#define DIO12_PWM NULL + +#define DIO13_PIN PINE2 +#define DIO13_RPORT PINE +#define DIO13_WPORT PORTE +#define DIO13_DDR DDRE +#define DIO13_PWM NULL + +#define DIO14_PIN PINE6 +#define DIO14_RPORT PINE +#define DIO14_WPORT PORTE +#define DIO14_DDR DDRE +#define DIO14_PWM NULL + +#define DIO15_PIN PINE7 +#define DIO15_RPORT PINE +#define DIO15_WPORT PORTE +#define DIO15_DDR DDRE +#define DIO15_PWM NULL + +#define DIO16_PIN PINB0 +#define DIO16_RPORT PINB +#define DIO16_WPORT PORTB +#define DIO16_DDR DDRB +#define DIO16_PWM NULL + +#define DIO17_PIN PIND0 +#define DIO17_RPORT PIND +#define DIO17_WPORT PORTD +#define DIO17_DDR DDRD +#define DIO17_PWM NULL + +#define DIO18_PIN PIND1 +#define DIO18_RPORT PIND +#define DIO18_WPORT PORTD +#define DIO18_DDR DDRD +#define DIO18_PWM NULL + +#define DIO19_PIN PIND2 +#define DIO19_RPORT PIND +#define DIO19_WPORT PORTD +#define DIO19_DDR DDRD +#define DIO19_PWM NULL + +#define DIO20_PIN PIND3 +#define DIO20_RPORT PIND +#define DIO20_WPORT PORTD +#define DIO20_DDR DDRD +#define DIO20_PWM NULL + +#define DIO21_PIN PIND4 +#define DIO21_RPORT PIND +#define DIO21_WPORT PORTD +#define DIO21_DDR DDRD +#define DIO21_PWM NULL + +#define DIO22_PIN PIND5 +#define DIO22_RPORT PIND +#define DIO22_WPORT PORTD +#define DIO22_DDR DDRD +#define DIO22_PWM NULL + +#define DIO23_PIN PIND6 +#define DIO23_RPORT PIND +#define DIO23_WPORT PORTD +#define DIO23_DDR DDRD +#define DIO23_PWM NULL + +#define DIO24_PIN PIND7 +#define DIO24_RPORT PIND +#define DIO24_WPORT PORTD +#define DIO24_DDR DDRD +#define DIO24_PWM NULL + +#define DIO25_PIN PING0 +#define DIO25_RPORT PING +#define DIO25_WPORT PORTG +#define DIO25_DDR DDRG +#define DIO25_PWM NULL + +#define DIO26_PIN PING1 +#define DIO26_RPORT PING +#define DIO26_WPORT PORTG +#define DIO26_DDR DDRG +#define DIO26_PWM NULL + +#define DIO27_PIN PING2 +#define DIO27_RPORT PING +#define DIO27_WPORT PORTG +#define DIO27_DDR DDRG +#define DIO27_PWM NULL + +#define DIO28_PIN PING3 +#define DIO28_RPORT PING +#define DIO28_WPORT PORTG +#define DIO28_DDR DDRG +#define DIO28_PWM NULL + +#define DIO29_PIN PING4 +#define DIO29_RPORT PING +#define DIO29_WPORT PORTG +#define DIO29_DDR DDRG +#define DIO29_PWM NULL + +#define DIO30_PIN PINC0 +#define DIO30_RPORT PINC +#define DIO30_WPORT PORTC +#define DIO30_DDR DDRC +#define DIO30_PWM NULL + +#define DIO31_PIN PINC1 +#define DIO31_RPORT PINC +#define DIO31_WPORT PORTC +#define DIO31_DDR DDRC +#define DIO31_PWM NULL + +#define DIO32_PIN PINC2 +#define DIO32_RPORT PINC +#define DIO32_WPORT PORTC +#define DIO32_DDR DDRC +#define DIO32_PWM NULL + +#define DIO33_PIN PINC3 +#define DIO33_RPORT PINC +#define DIO33_WPORT PORTC +#define DIO33_DDR DDRC +#define DIO33_PWM NULL + +#define DIO34_PIN PINC4 +#define DIO34_RPORT PINC +#define DIO34_WPORT PORTC +#define DIO34_DDR DDRC +#define DIO34_PWM NULL + +#define DIO35_PIN PINC5 +#define DIO35_RPORT PINC +#define DIO35_WPORT PORTC +#define DIO35_DDR DDRC +#define DIO35_PWM NULL + +#define DIO36_PIN PINC6 +#define DIO36_RPORT PINC +#define DIO36_WPORT PORTC +#define DIO36_DDR DDRC +#define DIO36_PWM NULL + +#define DIO37_PIN PINC7 +#define DIO37_RPORT PINC +#define DIO37_WPORT PORTC +#define DIO37_DDR DDRC +#define DIO37_PWM NULL + +#define DIO38_PIN PINA0 +#define DIO38_RPORT PINA +#define DIO38_WPORT PORTA +#define DIO38_DDR DDRA +#define DIO38_PWM NULL + +#define DIO39_PIN PINA1 +#define DIO39_RPORT PINA +#define DIO39_WPORT PORTA +#define DIO39_DDR DDRA +#define DIO39_PWM NULL + +#define DIO40_PIN PINA2 +#define DIO40_RPORT PINA +#define DIO40_WPORT PORTA +#define DIO40_DDR DDRA +#define DIO40_PWM NULL + +#define DIO41_PIN PINA3 +#define DIO41_RPORT PINA +#define DIO41_WPORT PORTA +#define DIO41_DDR DDRA +#define DIO41_PWM NULL + +#define DIO42_PIN PINA4 +#define DIO42_RPORT PINA +#define DIO42_WPORT PORTA +#define DIO42_DDR DDRA +#define DIO42_PWM NULL + +#define DIO43_PIN PINA5 +#define DIO43_RPORT PINA +#define DIO43_WPORT PORTA +#define DIO43_DDR DDRA +#define DIO43_PWM NULL + +#define DIO44_PIN PINA6 +#define DIO44_RPORT PINA +#define DIO44_WPORT PORTA +#define DIO44_DDR DDRA +#define DIO44_PWM NULL + +#define DIO45_PIN PINA7 +#define DIO45_RPORT PINA +#define DIO45_WPORT PORTA +#define DIO45_DDR DDRA +#define DIO45_PWM NULL + +#define DIO46_PIN PINF0 +#define DIO46_RPORT PINF +#define DIO46_WPORT PORTF +#define DIO46_DDR DDRF +#define DIO46_PWM NULL + +#define DIO47_PIN PINF1 +#define DIO47_RPORT PINF +#define DIO47_WPORT PORTF +#define DIO47_DDR DDRF +#define DIO47_PWM NULL + +#define DIO48_PIN PINF2 +#define DIO48_RPORT PINF +#define DIO48_WPORT PORTF +#define DIO48_DDR DDRF +#define DIO48_PWM NULL + +#define DIO49_PIN PINF3 +#define DIO49_RPORT PINF +#define DIO49_WPORT PORTF +#define DIO49_DDR DDRF +#define DIO49_PWM NULL + +#define DIO50_PIN PINF4 +#define DIO50_RPORT PINF +#define DIO50_WPORT PORTF +#define DIO50_DDR DDRF +#define DIO50_PWM NULL + +#define DIO51_PIN PINF5 +#define DIO51_RPORT PINF +#define DIO51_WPORT PORTF +#define DIO51_DDR DDRF +#define DIO51_PWM NULL + +#define DIO52_PIN PINF6 +#define DIO52_RPORT PINF +#define DIO52_WPORT PORTF +#define DIO52_DDR DDRF +#define DIO52_PWM NULL + +#define DIO53_PIN PINF7 +#define DIO53_RPORT PINF +#define DIO53_WPORT PORTF +#define DIO53_DDR DDRF +#define DIO53_PWM NULL + +#undef PA0 +#define PA0_PIN PINA0 +#define PA0_RPORT PINA +#define PA0_WPORT PORTA +#define PA0_DDR DDRA +#define PA0_PWM NULL +#undef PA1 +#define PA1_PIN PINA1 +#define PA1_RPORT PINA +#define PA1_WPORT PORTA +#define PA1_DDR DDRA +#define PA1_PWM NULL +#undef PA2 +#define PA2_PIN PINA2 +#define PA2_RPORT PINA +#define PA2_WPORT PORTA +#define PA2_DDR DDRA +#define PA2_PWM NULL +#undef PA3 +#define PA3_PIN PINA3 +#define PA3_RPORT PINA +#define PA3_WPORT PORTA +#define PA3_DDR DDRA +#define PA3_PWM NULL +#undef PA4 +#define PA4_PIN PINA4 +#define PA4_RPORT PINA +#define PA4_WPORT PORTA +#define PA4_DDR DDRA +#define PA4_PWM NULL +#undef PA5 +#define PA5_PIN PINA5 +#define PA5_RPORT PINA +#define PA5_WPORT PORTA +#define PA5_DDR DDRA +#define PA5_PWM NULL +#undef PA6 +#define PA6_PIN PINA6 +#define PA6_RPORT PINA +#define PA6_WPORT PORTA +#define PA6_DDR DDRA +#define PA6_PWM NULL +#undef PA7 +#define PA7_PIN PINA7 +#define PA7_RPORT PINA +#define PA7_WPORT PORTA +#define PA7_DDR DDRA +#define PA7_PWM NULL + +#undef PB0 +#define PB0_PIN PINB0 +#define PB0_RPORT PINB +#define PB0_WPORT PORTB +#define PB0_DDR DDRB +#define PB0_PWM NULL +#undef PB1 +#define PB1_PIN PINB1 +#define PB1_RPORT PINB +#define PB1_WPORT PORTB +#define PB1_DDR DDRB +#define PB1_PWM NULL +#undef PB2 +#define PB2_PIN PINB2 +#define PB2_RPORT PINB +#define PB2_WPORT PORTB +#define PB2_DDR DDRB +#define PB2_PWM NULL +#undef PB3 +#define PB3_PIN PINB3 +#define PB3_RPORT PINB +#define PB3_WPORT PORTB +#define PB3_DDR DDRB +#define PB3_PWM NULL +#undef PB4 +#define PB4_PIN PINB4 +#define PB4_RPORT PINB +#define PB4_WPORT PORTB +#define PB4_DDR DDRB +#define PB4_PWM &OCR2A +#undef PB5 +#define PB5_PIN PINB5 +#define PB5_RPORT PINB +#define PB5_WPORT PORTB +#define PB5_DDR DDRB +#define PB5_PWM NULL +#undef PB6 +#define PB6_PIN PINB6 +#define PB6_RPORT PINB +#define PB6_WPORT PORTB +#define PB6_DDR DDRB +#define PB6_PWM NULL +#undef PB7 +#define PB7_PIN PINB7 +#define PB7_RPORT PINB +#define PB7_WPORT PORTB +#define PB7_DDR DDRB +#define PB7_PWM &OCR0A + +#undef PC0 +#define PC0_PIN PINC0 +#define PC0_RPORT PINC +#define PC0_WPORT PORTC +#define PC0_DDR DDRC +#define PC0_PWM NULL +#undef PC1 +#define PC1_PIN PINC1 +#define PC1_RPORT PINC +#define PC1_WPORT PORTC +#define PC1_DDR DDRC +#define PC1_PWM NULL +#undef PC2 +#define PC2_PIN PINC2 +#define PC2_RPORT PINC +#define PC2_WPORT PORTC +#define PC2_DDR DDRC +#define PC2_PWM NULL +#undef PC3 +#define PC3_PIN PINC3 +#define PC3_RPORT PINC +#define PC3_WPORT PORTC +#define PC3_DDR DDRC +#define PC3_PWM NULL +#undef PC4 +#define PC4_PIN PINC4 +#define PC4_RPORT PINC +#define PC4_WPORT PORTC +#define PC4_DDR DDRC +#define PC4_PWM NULL +#undef PC5 +#define PC5_PIN PINC5 +#define PC5_RPORT PINC +#define PC5_WPORT PORTC +#define PC5_DDR DDRC +#define PC5_PWM NULL +#undef PC6 +#define PC6_PIN PINC6 +#define PC6_RPORT PINC +#define PC6_WPORT PORTC +#define PC6_DDR DDRC +#define PC6_PWM NULL +#undef PC7 +#define PC7_PIN PINC7 +#define PC7_RPORT PINC +#define PC7_WPORT PORTC +#define PC7_DDR DDRC +#define PC7_PWM NULL + +#undef PD0 +#define PD0_PIN PIND0 +#define PD0_RPORT PIND +#define PD0_WPORT PORTD +#define PD0_DDR DDRD +#define PD0_PWM NULL +#undef PD1 +#define PD1_PIN PIND1 +#define PD1_RPORT PIND +#define PD1_WPORT PORTD +#define PD1_DDR DDRD +#define PD1_PWM NULL +#undef PD2 +#define PD2_PIN PIND2 +#define PD2_RPORT PIND +#define PD2_WPORT PORTD +#define PD2_DDR DDRD +#define PD2_PWM NULL +#undef PD3 +#define PD3_PIN PIND3 +#define PD3_RPORT PIND +#define PD3_WPORT PORTD +#define PD3_DDR DDRD +#define PD3_PWM NULL +#undef PD4 +#define PD4_PIN PIND4 +#define PD4_RPORT PIND +#define PD4_WPORT PORTD +#define PD4_DDR DDRD +#define PD4_PWM NULL +#undef PD5 +#define PD5_PIN PIND5 +#define PD5_RPORT PIND +#define PD5_WPORT PORTD +#define PD5_DDR DDRD +#define PD5_PWM NULL +#undef PD6 +#define PD6_PIN PIND6 +#define PD6_RPORT PIND +#define PD6_WPORT PORTD +#define PD6_DDR DDRD +#define PD6_PWM NULL +#undef PD7 +#define PD7_PIN PIND7 +#define PD7_RPORT PIND +#define PD7_WPORT PORTD +#define PD7_DDR DDRD +#define PD7_PWM NULL + +#undef PE0 +#define PE0_PIN PINE0 +#define PE0_RPORT PINE +#define PE0_WPORT PORTE +#define PE0_DDR DDRE +#define PE0_PWM NULL +#undef PE1 +#define PE1_PIN PINE1 +#define PE1_RPORT PINE +#define PE1_WPORT PORTE +#define PE1_DDR DDRE +#define PE1_PWM NULL +#undef PE2 +#define PE2_PIN PINE2 +#define PE2_RPORT PINE +#define PE2_WPORT PORTE +#define PE2_DDR DDRE +#define PE2_PWM NULL +#undef PE3 +#define PE3_PIN PINE3 +#define PE3_RPORT PINE +#define PE3_WPORT PORTE +#define PE3_DDR DDRE +#define PE3_PWM &OCR3AL +#undef PE4 +#define PE4_PIN PINE4 +#define PE4_RPORT PINE +#define PE4_WPORT PORTE +#define PE4_DDR DDRE +#define PE4_PWM &OCR3BL +#undef PE5 +#define PE5_PIN PINE5 +#define PE5_RPORT PINE +#define PE5_WPORT PORTE +#define PE5_DDR DDRE +#define PE5_PWM &OCR3CL +#undef PE6 +#define PE6_PIN PINE6 +#define PE6_RPORT PINE +#define PE6_WPORT PORTE +#define PE6_DDR DDRE +#define PE6_PWM NULL +#undef PE7 +#define PE7_PIN PINE7 +#define PE7_RPORT PINE +#define PE7_WPORT PORTE +#define PE7_DDR DDRE +#define PE7_PWM NULL + +#undef PF0 +#define PF0_PIN PINF0 +#define PF0_RPORT PINF +#define PF0_WPORT PORTF +#define PF0_DDR DDRF +#define PF0_PWM NULL +#undef PF1 +#define PF1_PIN PINF1 +#define PF1_RPORT PINF +#define PF1_WPORT PORTF +#define PF1_DDR DDRF +#define PF1_PWM NULL +#undef PF2 +#define PF2_PIN PINF2 +#define PF2_RPORT PINF +#define PF2_WPORT PORTF +#define PF2_DDR DDRF +#define PF2_PWM NULL +#undef PF3 +#define PF3_PIN PINF3 +#define PF3_RPORT PINF +#define PF3_WPORT PORTF +#define PF3_DDR DDRF +#define PF3_PWM NULL +#undef PF4 +#define PF4_PIN PINF4 +#define PF4_RPORT PINF +#define PF4_WPORT PORTF +#define PF4_DDR DDRF +#define PF4_PWM NULL +#undef PF5 +#define PF5_PIN PINF5 +#define PF5_RPORT PINF +#define PF5_WPORT PORTF +#define PF5_DDR DDRF +#define PF5_PWM NULL +#undef PF6 +#define PF6_PIN PINF6 +#define PF6_RPORT PINF +#define PF6_WPORT PORTF +#define PF6_DDR DDRF +#define PF6_PWM NULL +#undef PF7 +#define PF7_PIN PINF7 +#define PF7_RPORT PINF +#define PF7_WPORT PORTF +#define PF7_DDR DDRF +#define PF7_PWM NULL + +#undef PG0 +#define PG0_PIN PING0 +#define PG0_RPORT PING +#define PG0_WPORT PORTG +#define PG0_DDR DDRG +#define PG0_PWM NULL +#undef PG1 +#define PG1_PIN PING1 +#define PG1_RPORT PING +#define PG1_WPORT PORTG +#define PG1_DDR DDRG +#define PG1_PWM NULL +#undef PG2 +#define PG2_PIN PING2 +#define PG2_RPORT PING +#define PG2_WPORT PORTG +#define PG2_DDR DDRG +#define PG2_PWM NULL +#undef PG3 +#define PG3_PIN PING3 +#define PG3_RPORT PING +#define PG3_WPORT PORTG +#define PG3_DDR DDRG +#define PG3_PWM NULL +#undef PG4 +#define PG4_PIN PING4 +#define PG4_RPORT PING +#define PG4_WPORT PORTG +#define PG4_DDR DDRG +#define PG4_PWM NULL +#undef PG5 +#define PG5_PIN PING5 +#define PG5_RPORT PING +#define PG5_WPORT PORTG +#define PG5_DDR DDRG +#define PG5_PWM &OCR0B + +#endif + +#ifndef DIO0_PIN +#error pins for this chip not defined in arduino.h! If you write an appropriate pin definition and have this firmware work on your chip, please submit a pull request +#endif + +#endif /* _ARDUINO_H */ + diff --git a/trunk/Arduino/Repetier_0.92.9/gcode.cpp b/trunk/Arduino/Repetier_0.92.9/gcode.cpp new file mode 100644 index 00000000..f68764c4 --- /dev/null +++ b/trunk/Arduino/Repetier_0.92.9/gcode.cpp @@ -0,0 +1,1243 @@ +/* + This file is part of Repetier-Firmware. + + Repetier-Firmware is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Repetier-Firmware is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Repetier-Firmware. If not, see . + + This firmware is a nearly complete rewrite of the sprinter firmware + by kliment (https://github.com/kliment/Sprinter) + which based on Tonokip RepRap firmware rewrite based off of Hydra-mmm firmware. + + Functions in this file are used to communicate using ascii or repetier protocol. +*/ + +#include "Repetier.h" + +#ifndef FEATURE_CHECKSUM_FORCED +#define FEATURE_CHECKSUM_FORCED false +#endif + +GCode GCode::commandsBuffered[GCODE_BUFFER_SIZE]; ///< Buffer for received commands. +uint8_t GCode::bufferReadIndex = 0; ///< Read position in gcode_buffer. +uint8_t GCode::bufferWriteIndex = 0; ///< Write position in gcode_buffer. +uint8_t GCode::commandReceiving[MAX_CMD_SIZE]; ///< Current received command. +uint8_t GCode::commandsReceivingWritePosition = 0; ///< Writing position in gcode_transbuffer. +uint8_t GCode::sendAsBinary; ///< Flags the command as binary input. +uint8_t GCode::wasLastCommandReceivedAsBinary = 0; ///< Was the last successful command in binary mode? +uint8_t GCode::commentDetected = false; ///< Flags true if we are reading the comment part of a command. +uint8_t GCode::binaryCommandSize; ///< Expected size of the incoming binary command. +bool GCode::waitUntilAllCommandsAreParsed = false; ///< Don't read until all commands are parsed. Needed if gcode_buffer is misused as storage for strings. +uint32_t GCode::lastLineNumber = 0; ///< Last line number received. +uint32_t GCode::actLineNumber; ///< Line number of current command. +int8_t GCode::waitingForResend = -1; ///< Waiting for line to be resend. -1 = no wait. +volatile uint8_t GCode::bufferLength = 0; ///< Number of commands stored in gcode_buffer +millis_t GCode::timeOfLastDataPacket = 0; ///< Time, when we got the last data packet. Used to detect missing uint8_ts. +uint8_t GCode::formatErrors = 0; +PGM_P GCode::fatalErrorMsg = NULL; ///< message unset = no fatal error + +/** \page Repetier-protocol + +\section Introduction + +The repetier-protocol was developed, to overcome some shortcommings in the standard +RepRap communication method, while remaining backward compatible. To use the improved +features of this protocal, you need a host which speaks it. On Windows the recommended +host software is Repetier-Host. It is developed in parallel to this firmware and supports +all implemented features. + +\subsection Improvements + +- With higher speeds, the serial connection is more likely to produce communication failures. + The standard method is to transfer a checksum at the end of the line. This checksum is the + XORd value of all characters send. The value is limited to a range between 0 and 127. It can + not detect two identical missing characters or a wrong order. Therefore the new protocol + uses Fletchers checksum, which overcomes these shortcommings. +- The new protocol send data in binary format. This reduces the data size to less then 50% and + it speeds up decoding the command. No slow conversion from string to floats are needed. + +*/ + +/** \brief Computes size of binary data from bitfield. + +In the repetier-protocol in binary mode, the first 2 uint8_ts define the +data. From this bitfield, this function computes the size of the command +including the 2 uint8_ts of the bitfield and the 2 uint8_ts for the checksum. + +Gcode Letter to Bit and Datatype: + +- N : Bit 0 : 16-Bit Integer +- M : Bit 1 : 8-Bit unsigned uint8_t +- G : Bit 2 : 8-Bit unsigned uint8_t +- X : Bit 3 : 32-Bit Float +- Y : Bit 4 : 32-Bit Float +- Z : Bit 5 : 32-Bit Float +- E : Bit 6 : 32-Bit Float +- : Bit 7 : always set to distinguish binary from ASCII line. +- F : Bit 8 : 32-Bit Float +- T : Bit 9 : 8 Bit Integer +- S : Bit 10 : 32 Bit Value +- P : Bit 11 : 32 Bit Integer +- V2 : Bit 12 : Version 2 command for additional commands/sizes +- Ext : Bit 13 : There are 2 more uint8_ts following with Bits, only for future versions +- Int :Bit 14 : Marks it as internal command, +- Text : Bit 15 : 16 Byte ASCII String terminated with 0 +Second word if V2: +- I : Bit 0 : 32-Bit float +- J : Bit 1 : 32-Bit float +- R : Bit 2 : 32-Bit float +- D : Bit 3 : 32-Bit float +- C : Bit 4 : 32-Bit float +- H : Bit 5 : 32-Bit float +- A : Bit 6 : 32-Bit float +- B : Bit 7 : 32-Bit float +- K : Bit 8 : 32-Bit float +- L : Bit 9 : 32-Bit float +- O : Bit 0 : 32-Bit float +*/ +uint8_t GCode::computeBinarySize(char *ptr) // unsigned int bitfield) { +{ + uint8_t s = 4; // include checksum and bitfield + uint16_t bitfield = *(uint16_t*)ptr; + if(bitfield & 1) s += 2; + if(bitfield & 8) s += 4; + if(bitfield & 16) s += 4; + if(bitfield & 32) s += 4; + if(bitfield & 64) s += 4; + if(bitfield & 256) s += 4; + if(bitfield & 512) s += 1; + if(bitfield & 1024) s += 4; + if(bitfield & 2048) s += 4; + if(bitfield & 4096) // Version 2 or later + { + s += 2; // for bitfield 2 + uint16_t bitfield2 = *(uint16_t*)(ptr + 2); + if(bitfield & 2) s += 2; + if(bitfield & 4) s += 2; + if(bitfield2 & 1) s += 4; + if(bitfield2 & 2) s += 4; + if(bitfield2 & 4) s += 4; + if(bitfield2 & 8) s += 4; + if(bitfield2 & 16) s += 4; + if(bitfield2 & 32) s += 4; + if(bitfield2 & 64) s += 4; + if(bitfield2 & 128) s += 4; + if(bitfield2 & 256) s += 4; + if(bitfield2 & 512) s += 4; + if(bitfield2 & 1024) s += 4; + if(bitfield2 & 2048) s += 4; + if(bitfield2 & 4096) s += 4; + if(bitfield2 & 8192) s += 4; + if(bitfield2 & 16384) s += 4; + if(bitfield2 & 32768) s += 4; + if(bitfield & 32768) s += RMath::min(80,(uint8_t)ptr[4] + 1); + } + else + { + if(bitfield & 2) s += 1; + if(bitfield & 4) s += 1; + if(bitfield & 32768) s += 16; + } + return s; +} + +void GCode::requestResend() +{ + HAL::serialFlush(); + commandsReceivingWritePosition = 0; + if(sendAsBinary) + waitingForResend = 30; + else + waitingForResend = 14; + Com::println(); + Com::printFLN(Com::tResend,lastLineNumber + 1); + Com::printFLN(Com::tOk); +} + +/** + Check if result is plausible. If it is, an ok is send and the command is stored in queue. + If not, a resend and ok is send. +*/ +void GCode::checkAndPushCommand() +{ + if(hasM()) + { + if(M == 110) // Reset line number + { + lastLineNumber = actLineNumber; + Com::printFLN(Com::tOk); + waitingForResend = -1; + return; + } + if(M == 112) // Emergency kill - freeze printer + { + Commands::emergencyStop(); + } +#ifdef DEBUG_COM_ERRORS + if(M == 666) // force an communication error + { + lastLineNumber++; + return; + } else if(M == 668) { + lastLineNumber = 0; // simulate a reset so lines are out of resend buffer + } +#endif // DEBUG_COM_ERRORS + } + if(hasN()) + { + if((((lastLineNumber + 1) & 0xffff) != (actLineNumber & 0xffff))) + { + if(static_cast(lastLineNumber - actLineNumber) < 40) + { + // we have seen that line already. So we assume it is a repeated resend and we ignore it + commandsReceivingWritePosition = 0; + Com::printFLN(Com::tSkip,actLineNumber); + Com::printFLN(Com::tOk); + } + else if(waitingForResend < 0) // after a resend, we have to skip the garbage in buffers, no message for this + { + if(Printer::debugErrors()) + { + Com::printF(Com::tExpectedLine, lastLineNumber + 1); + Com::printFLN(Com::tGot, actLineNumber); + } + requestResend(); // Line missing, force resend + } + else + { + --waitingForResend; + commandsReceivingWritePosition = 0; + Com::printFLN(Com::tSkip, actLineNumber); + Com::printFLN(Com::tOk); + } + return; + } + lastLineNumber = actLineNumber; + } else if(lastLineNumber && !(hasM() && M == 117)) { // once line number always line number! + if(Printer::debugErrors()) + { + Com::printErrorFLN(PSTR("Missing linenumber")); + } + requestResend(); + return; + } + if(GCode::hasFatalError() && !(hasM() && M==999)) { + GCode::reportFatalError(); + } else { + pushCommand(); + } +#ifdef DEBUG_COM_ERRORS + if(hasM() && M == 667) + return; // omit ok +#endif +#if ACK_WITH_LINENUMBER + Com::printFLN(Com::tOkSpace, actLineNumber); +#else + Com::printFLN(Com::tOk); +#endif + wasLastCommandReceivedAsBinary = sendAsBinary; + waitingForResend = -1; // everything is ok. +} + +void GCode::pushCommand() +{ +#if !ECHO_ON_EXECUTE + commandsBuffered[bufferWriteIndex].echoCommand(); +#endif + if(++bufferWriteIndex >= GCODE_BUFFER_SIZE) bufferWriteIndex = 0; + bufferLength++; +} + +/** + Get the next buffered command. Returns 0 if no more commands are buffered. For each + returned command, the gcode_command_finished() function must be called. +*/ +GCode *GCode::peekCurrentCommand() +{ + if(bufferLength == 0) return NULL; // No more data + return &commandsBuffered[bufferReadIndex]; +} + +/** \brief Removes the last returned command from cache. */ +void GCode::popCurrentCommand() +{ + if(!bufferLength) return; // Should not happen, but safety first +#if ECHO_ON_EXECUTE + echoCommand(); +#endif + if(++bufferReadIndex == GCODE_BUFFER_SIZE) bufferReadIndex = 0; + bufferLength--; +} + +void GCode::echoCommand() +{ + if(Printer::debugEcho()) + { + Com::printF(Com::tEcho); + printCommand(); + } +} + +void GCode::debugCommandBuffer() +{ + Com::printF(PSTR("CommandBuffer")); + for(int i = 0; i < commandsReceivingWritePosition; i++) + Com::printF(Com::tColon,(int)commandReceiving[i]); + Com::println(); + Com::printFLN(PSTR("Binary:"), (int)sendAsBinary); + if(!sendAsBinary) + { + Com::print((char*)commandReceiving); + Com::println(); + } +} + +/** \brief Execute commands in progmem stored string. Multiple commands are seperated by \n */ +void GCode::executeFString(FSTRINGPARAM(cmd)) +{ + char buf[80]; + uint8_t buflen; + char c; + GCode code; + do + { + // Wait for a free place in command buffer + // Scan next command from string + uint8_t comment = 0; + buflen = 0; + do + { + c = HAL::readFlashByte(cmd++); + if(c == 0 || c == '\n') break; + if(c == ';') comment = 1; + if(comment) continue; + buf[buflen++] = c; + } + while(buflen < 79); + if(buflen == 0) // empty line ignore + continue; + buf[buflen] = 0; + // Send command into command buffer + if(code.parseAscii((char *)buf,false) && (code.params & 518)) // Success + { +#ifdef DEBUG_PRINT + debugWaitLoop = 7; +#endif + + Commands::executeGCode(&code); + Printer::defaultLoopActions(); + } + } + while(c); +} + +/** \brief Read from serial console or sdcard. + +This function is the main function to read the commands from serial console or from sdcard. +It must be called frequently to empty the incoming buffer. +*/ +void GCode::readFromSerial() +{ + if(bufferLength >= GCODE_BUFFER_SIZE) return; // all buffers full + if(waitUntilAllCommandsAreParsed && bufferLength) return; + waitUntilAllCommandsAreParsed = false; + millis_t time = HAL::timeInMilliseconds(); + if(!HAL::serialByteAvailable()) + { + if((waitingForResend >= 0 || commandsReceivingWritePosition > 0) && time - timeOfLastDataPacket > 200) + { + // Com::printF(PSTR("WFR:"),waitingForResend);Com::printF(PSTR(" CRWP:"),commandsReceivingWritePosition);commandReceiving[commandsReceivingWritePosition] = 0;Com::printFLN(PSTR(" GOT:"),(char*)commandReceiving); + requestResend(); // Something is wrong, a started line was not continued in the last second + timeOfLastDataPacket = time; + } +#ifdef WAITING_IDENTIFIER + else if(bufferLength == 0 && time - timeOfLastDataPacket > 1000) // Don't do it if buffer is not empty. It may be a slow executing command. + { + Com::printFLN(Com::tWait); // Unblock communication in case the last ok was not received correct. + timeOfLastDataPacket = time; + } +#endif + } + while(HAL::serialByteAvailable() && commandsReceivingWritePosition < MAX_CMD_SIZE) // consume data until no data or buffer full + { + timeOfLastDataPacket = time; //HAL::timeInMilliseconds(); + commandReceiving[commandsReceivingWritePosition++] = HAL::serialReadByte(); + // first lets detect, if we got an old type ascii command + if(commandsReceivingWritePosition == 1) + { + if(waitingForResend >= 0 && wasLastCommandReceivedAsBinary) + { + if(!commandReceiving[0]) + waitingForResend--; // Skip 30 zeros to get in sync + else + waitingForResend = 30; + commandsReceivingWritePosition = 0; + continue; + } + if(!commandReceiving[0]) // Ignore zeros + { + commandsReceivingWritePosition = 0; + continue; + } + sendAsBinary = (commandReceiving[0] & 128) != 0; + } + if(sendAsBinary) + { + if(commandsReceivingWritePosition < 2 ) continue; + if(commandsReceivingWritePosition == 5 || commandsReceivingWritePosition == 4) + binaryCommandSize = computeBinarySize((char*)commandReceiving); + if(commandsReceivingWritePosition == binaryCommandSize) + { + GCode *act = &commandsBuffered[bufferWriteIndex]; + if(act->parseBinary(commandReceiving, true)) // Success + act->checkAndPushCommand(); + else + requestResend(); + commandsReceivingWritePosition = 0; + return; + } + } + else // Ascii command + { + char ch = commandReceiving[commandsReceivingWritePosition - 1]; + if(ch == 0 || ch == '\n' || ch == '\r' || (!commentDetected && ch == ':')) // complete line read + { + commandReceiving[commandsReceivingWritePosition - 1] = 0; + //Com::printF(PSTR("Parse ascii:"));Com::print((char*)commandReceiving);Com::println(); + commentDetected = false; + if(commandsReceivingWritePosition == 1) // empty line ignore + { + commandsReceivingWritePosition = 0; + continue; + } + GCode *act = &commandsBuffered[bufferWriteIndex]; + if(act->parseAscii((char *)commandReceiving, true)) // Success + act->checkAndPushCommand(); + else + requestResend(); + commandsReceivingWritePosition = 0; + return; + } + else + { + if(ch == ';') commentDetected = true; // ignore new data until line end + if(commentDetected) commandsReceivingWritePosition--; + } + } + if(commandsReceivingWritePosition == MAX_CMD_SIZE) + { + requestResend(); + return; + } + } +#if SDSUPPORT + if(sd.sdmode == 0 || sd.sdmode >= 100 || commandsReceivingWritePosition != 0) // not reading or incoming serial command + return; + while( sd.filesize > sd.sdpos && commandsReceivingWritePosition < MAX_CMD_SIZE) // consume data until no data or buffer full + { + timeOfLastDataPacket = HAL::timeInMilliseconds(); + int n = sd.file.read(); + if(n == -1) + { + Com::printFLN(Com::tSDReadError); + UI_ERROR("SD Read Error"); + + // Second try in case of recoverable errors + sd.file.seekSet(sd.sdpos); + n = sd.file.read(); + if(n == -1) + { + Com::printErrorFLN(PSTR("SD error did not recover!")); + sd.sdmode = 0; + break; + } + UI_ERROR("SD error fixed"); + } + sd.sdpos++; // = file.curPosition(); + commandReceiving[commandsReceivingWritePosition++] = (uint8_t)n; + + // first lets detect, if we got an old type ascii command + if(commandsReceivingWritePosition == 1) + { + sendAsBinary = (commandReceiving[0] & 128) != 0; + } + if(sendAsBinary) + { + if(commandsReceivingWritePosition < 2 ) continue; + if(commandsReceivingWritePosition == 4 || commandsReceivingWritePosition == 5) + binaryCommandSize = computeBinarySize((char*)commandReceiving); + if(commandsReceivingWritePosition == binaryCommandSize) + { + GCode *act = &commandsBuffered[bufferWriteIndex]; + if(act->parseBinary(commandReceiving, false)) // Success, silently ignore illegal commands + pushCommand(); + commandsReceivingWritePosition = 0; + if(sd.sdmode == 2) + sd.sdmode = 0; + return; + } + } + else + { + char ch = commandReceiving[commandsReceivingWritePosition-1]; + bool returnChar = ch == '\n' || ch == '\r'; + if(returnChar || sd.filesize == sd.sdpos || (!commentDetected && ch == ':') || commandsReceivingWritePosition >= (MAX_CMD_SIZE - 1) ) // complete line read + { + if(returnChar || ch == ':') + commandReceiving[commandsReceivingWritePosition - 1] = 0; + else + commandReceiving[commandsReceivingWritePosition] = 0; + commentDetected = false; + if(commandsReceivingWritePosition == 1) // empty line ignore + { + commandsReceivingWritePosition = 0; + continue; + } + GCode *act = &commandsBuffered[bufferWriteIndex]; + if(act->parseAscii((char *)commandReceiving, false)) // Success + pushCommand(); + commandsReceivingWritePosition = 0; + if(sd.sdmode == 2) + sd.sdmode = 0; + return; + } + else + { + if(ch == ';') commentDetected = true; // ignore new data until line end + if(commentDetected) commandsReceivingWritePosition--; + } + } + } + sd.sdmode = 0; + Com::printFLN(Com::tDonePrinting); + commandsReceivingWritePosition = 0; + commentDetected = false; + Printer::setMenuMode(MENU_MODE_SD_PRINTING, false); +#endif +} + +/** + Converts a binary uint8_tfield containing one GCode line into a GCode structure. + Returns true if checksum was correct. +*/ +bool GCode::parseBinary(uint8_t *buffer,bool fromSerial) +{ + internalCommand = !fromSerial; + unsigned int sum1 = 0, sum2 = 0; // for fletcher-16 checksum + // first do fletcher-16 checksum tests see + // http://en.wikipedia.org/wiki/Fletcher's_checksum + uint8_t *p = buffer; + uint8_t len = binaryCommandSize - 2; + while (len) + { + uint8_t tlen = len > 21 ? 21 : len; + len -= tlen; + do + { + sum1 += *p++; + if(sum1 >= 255) sum1 -= 255; + sum2 += sum1; + if(sum2 >= 255) sum2 -= 255; + } + while (--tlen); + } + sum1 -= *p++; + sum2 -= *p; + if(sum1 | sum2) + { + if(Printer::debugErrors()) + { + Com::printErrorFLN(Com::tWrongChecksum); + } + return false; + } + p = buffer; + params = *(uint16_t *)p; + p += 2; + uint8_t textlen = 16; + if(isV2()) + { + params2 = *(uint16_t *)p; + p += 2; + if(hasString()) + textlen = *p++; + } + else params2 = 0; + if(params & 1) + { + actLineNumber = N = *(uint16_t *)p; + p += 2; + } + if(isV2()) // Read G,M as 16 bit value + { + if(hasM()) + { + M = *(uint16_t *)p; + p += 2; + } + if(hasG()) + { + G = *(uint16_t *)p; + p += 2; + } + } + else + { + if(hasM()) + { + M = *p++; + } + if(hasG()) + { + G = *p++; + } + } + //if(code->params & 8) {memcpy(&code->X,p,4);p+=4;} + if(hasX()) + { + X = *(float *)p; + p += 4; + } + if(hasY()) + { + Y = *(float *)p; + p += 4; + } + if(hasZ()) + { + Z = *(float *)p; + p += 4; + } + if(hasE()) + { + E = *(float *)p; + p += 4; + } + if(hasF()) + { + F = *(float *)p; + p += 4; + } + if(hasT()) + { + T = *p++; + } + if(hasS()) + { + S = *(int32_t*)p; + p += 4; + } + if(hasP()) + { + P = *(int32_t*)p; + p += 4; + } + if(hasI()) + { + I = *(float *)p; + p += 4; + } + if(hasJ()) + { + J = *(float *)p; + p += 4; + } + if(hasR()) + { + R = *(float *)p; + p += 4; + } + if(hasD()) + { + D = *(float *)p; + p += 4; + } + if(hasC()) + { + C = *(float *)p; + p += 4; + } + if(hasH()) + { + H = *(float *)p; + p += 4; + } + if(hasA()) + { + A = *(float *)p; + p += 4; + } + if(hasB()) + { + B = *(float *)p; + p += 4; + } + if(hasK()) + { + K = *(float *)p; + p += 4; + } + if(hasL()) + { + L = *(float *)p; + p += 4; + } + if(hasO()) + { + O = *(float *)p; + p += 4; + } + if(hasString()) // set text pointer to string + { + text = (char*)p; + text[textlen] = 0; // Terminate string overwriting checksum + waitUntilAllCommandsAreParsed = true; // Don't destroy string until executed + } + formatErrors = 0; + return true; +} + +/** + Converts a ascii GCode line into a GCode structure. +*/ +bool GCode::parseAscii(char *line,bool fromSerial) +{ + char *pos = line; + params = 0; + params2 = 0; + internalCommand = !fromSerial; + char c; + while ( (c = *(pos++)) ) + { + if(c == '(' || c == '%') break; // alternative comment or program block + switch(c) + { + case 'N': + case 'n': + { + actLineNumber = parseLongValue(pos); + params |=1; + N = actLineNumber; + break; + } + case 'G': + case 'g': + { + G = parseLongValue(pos) & 0xffff; + params |= 4; + if(G > 255) params |= 4096; + break; + } + case 'M': + case 'm': + { + M = parseLongValue(pos) & 0xffff; + params |= 2; + if(M > 255) params |= 4096; + // handle non standard text arguments that some M codes have + if (M == 20 || M == 23 || M == 28 || M == 29 || M == 30 || M == 32 || M == 36 || M == 117) + { + // after M command we got a filename or text + char digit; + while( (digit = *pos) ) + { + if (digit < '0' || digit > '9') break; + pos++; + } + while( (digit = *pos) ) + { + if (digit != ' ') break; + pos++; + // skip leading whitespaces (may be no white space) + } + text = pos; + while (*pos) + { + if((M != 117 && M != 20 && *pos==' ') || *pos=='*') break; + pos++; // find a space as file name end + } + *pos = 0; // truncate filename by erasing space with nul, also skips checksum + waitUntilAllCommandsAreParsed = true; // don't risk string be deleted + params |= 32768; + } + break; + } + case 'X': + case 'x': + { + X = parseFloatValue(pos); + params |= 8; + break; + } + case 'Y': + case 'y': + { + Y = parseFloatValue(pos); + params |= 16; + break; + } + case 'Z': + case 'z': + { + Z = parseFloatValue(pos); + params |= 32; + break; + } + case 'E': + case 'e': + { + E = parseFloatValue(pos); + params |= 64; + break; + } + case 'F': + case 'f': + { + F = parseFloatValue(pos); + params |= 256; + break; + } + case 'T': + case 't': + { + T = parseLongValue(pos) & 0xff; + params |= 512; + break; + } + case 'S': + case 's': + { + S = parseLongValue(pos); + params |= 1024; + break; + } + case 'P': + case 'p': + { + P = parseLongValue(pos); + params |= 2048; + break; + } + case 'I': + case 'i': + { + I = parseFloatValue(pos); + params2 |= 1; + params |= 4096; // Needs V2 for saving + break; + } + case 'J': + case 'j': + { + J = parseFloatValue(pos); + params2 |= 2; + params |= 4096; // Needs V2 for saving + break; + } + case 'R': + case 'r': + { + R = parseFloatValue(pos); + params2 |= 4; + params |= 4096; // Needs V2 for saving + break; + } + case 'D': + case 'd': + { + D = parseFloatValue(pos); + params2 |= 8; + params |= 4096; // Needs V2 for saving + break; + } + case 'C': + case 'c': + { + D = parseFloatValue(pos); + params2 |= 16; + params |= 4096; // Needs V2 for saving + break; + } + case 'H': + case 'h': + { + D = parseFloatValue(pos); + params2 |= 32; + params |= 4096; // Needs V2 for saving + break; + } + case 'A': + case 'a': + { + D = parseFloatValue(pos); + params2 |= 64; + params |= 4096; // Needs V2 for saving + break; + } + case 'B': + case 'b': + { + D = parseFloatValue(pos); + params2 |= 128; + params |= 4096; // Needs V2 for saving + break; + } + case 'K': + case 'k': + { + D = parseFloatValue(pos); + params2 |= 256; + params |= 4096; // Needs V2 for saving + break; + } + case 'L': + case 'l': + { + D = parseFloatValue(pos); + params2 |= 512; + params |= 4096; // Needs V2 for saving + break; + } + case 'O': + case 'o': + { + D = parseFloatValue(pos); + params2 |= 1024; + params |= 4096; // Needs V2 for saving + break; + } + case '*' : //checksum + { + uint8_t checksum_given = parseLongValue(pos); + uint8_t checksum = 0; + while(line != (pos - 1)) checksum ^= *line++; +#if FEATURE_CHECKSUM_FORCED + Printer::flag0 |= PRINTER_FLAG0_FORCE_CHECKSUM; +#endif + if(checksum != checksum_given) + { + if(Printer::debugErrors()) + { + Com::printErrorFLN(Com::tWrongChecksum); + } + return false; // mismatch + } + break; + } + default: + break; + }// end switch + }// end while + + if(hasFormatError() || (params & 518) == 0) // Must contain G, M or T command and parameter need to have variables! + { + formatErrors++; + if(Printer::debugErrors()) + Com::printErrorFLN(Com::tFormatError); + if(formatErrors < 3) return false; + } + else formatErrors = 0; + return true; +} + +/** \brief Print command on serial console */ +void GCode::printCommand() +{ + if(hasN()) { + Com::print('N'); + Com::print((int32_t)N); + Com::print(' '); + } + if(hasM()) + { + Com::print('M'); + Com::print((int)M); + Com::print(' '); + } + if(hasG()) + { + Com::print('G'); + Com::print((int)G); + Com::print(' '); + } + if(hasT()) + { + Com::print('T'); + Com::print((int)T); + Com::print(' '); + } + if(hasX()) + { + Com::printF(Com::tX,X); + } + if(hasY()) + { + Com::printF(Com::tY,Y); + } + if(hasZ()) + { + Com::printF(Com::tZ,Z); + } + if(hasE()) + { + Com::printF(Com::tE,E,4); + } + if(hasF()) + { + Com::printF(Com::tF,F); + } + if(hasS()) + { + Com::printF(Com::tS,S); + } + if(hasP()) + { + Com::printF(Com::tP,P); + } + if(hasI()) + { + Com::printF(Com::tI,I); + } + if(hasJ()) + { + Com::printF(Com::tJ,J); + } + if(hasR()) + { + Com::printF(Com::tR,R); + } + if(hasString()) + { + Com::print(text); + } + Com::println(); +} + +void GCode::fatalError(FSTRINGPARAM(message)) { + fatalErrorMsg = message; +#if SDSUPPORT + if(sd.sdmode != 0) { // stop sd print to prevent damage + sd.stopPrint(); + } +#endif + if(Printer::currentPosition[Z_AXIS] < Printer::zMin + Printer::zLength - 15) + PrintLine::moveRelativeDistanceInStepsReal(0,0,10*Printer::axisStepsPerMM[Z_AXIS],0,Printer::homingFeedrate[Z_AXIS],true,true); + EVENT_FATAL_ERROR_OCCURED + Commands::waitUntilEndOfAllMoves(); + Printer::kill(true); + reportFatalError(); +} + +void GCode::reportFatalError() { + Com::printF(Com::tFatal); + Com::printF(fatalErrorMsg); + Com::printFLN(PSTR(" Printer stopped and heaters disabled due to this error. Fix error and restart with M999.")); + UI_ERROR_P(fatalErrorMsg) +} + +void GCode::resetFatalError() { + TemperatureController::resetAllErrorStates(); + fatalErrorMsg = NULL; + UI_ERROR(""); + EVENT_CONTINUE_FROM_FATAL_ERROR + Com::printFLN(PSTR("info:Continue from fatal state")); +} + +#if JSON_OUTPUT + +// --------------------------------------------------------------- // +// Code that gets gcode information is adapted from RepRapFirmware // +// Originally licensed under GPL // +// Authors: reprappro, dc42, dcnewman, others // +// Source: https://github.com/dcnewman/RepRapFirmware // +// Copy date: 15 Nov 2015 // +// --------------------------------------------------------------- // + +void GCodeFileInfo::init(SdBaseFile &file) { + this->fileSize = file.fileSize(); + this->filamentNeeded = 0.0; + this->objectHeight = 0.0; + this->layerHeight = 0.0; + if (!file.isOpen()) return; + bool genByFound = false, layerHeightFound = false, filamentNeedFound = false; + #if CPU_ARCH==ARCH_AVR + #define GCI_BUF_SIZE 120 + #else + #define GCI_BUF_SIZE 1024 + #endif + // READ 4KB FROM THE BEGINNING + char buf[GCI_BUF_SIZE]; + for (int i = 0; i < 4096; i += GCI_BUF_SIZE-50) { + if(!file.seekSet(i)) break; + file.read(buf, GCI_BUF_SIZE); + if (!genByFound && findGeneratedBy(buf, this->generatedBy)) genByFound = true; + if (!layerHeightFound && findLayerHeight(buf, this->layerHeight)) layerHeightFound = true; + if (!filamentNeedFound && findFilamentNeed(buf, this->filamentNeeded)) filamentNeedFound = true; + if(genByFound && layerHeightFound && filamentNeedFound) goto get_objectHeight; + } + + // READ 4KB FROM END + for (int i = 0; i < 4096; i += GCI_BUF_SIZE-50) { + if(!file.seekEnd(-4096 + i)) break; + file.read(buf, GCI_BUF_SIZE); + if (!genByFound && findGeneratedBy(buf, this->generatedBy)) genByFound = true; + if (!layerHeightFound && findLayerHeight(buf, this->layerHeight)) layerHeightFound = true; + if (!filamentNeedFound && findFilamentNeed(buf, this->filamentNeeded)) filamentNeedFound = true; + if(genByFound && layerHeightFound && filamentNeedFound) goto get_objectHeight; + } + + get_objectHeight: + // MOVE FROM END UP IN 1KB BLOCKS UP TO 30KB + for (int i = GCI_BUF_SIZE; i < 30000; i += GCI_BUF_SIZE-50) { + if(!file.seekEnd(-i)) break; + file.read(buf, GCI_BUF_SIZE); + if (findTotalHeight(buf, this->objectHeight)) break; + } + file.seekSet(0); +} + +bool GCodeFileInfo::findGeneratedBy(char *buf, char *genBy) { + // Slic3r & S3D + const char* generatedByString = PSTR("generated by "); + char* pos = strstr_P(buf, generatedByString); + if (pos) { + pos += strlen_P(generatedByString); + size_t i = 0; + while (i < GENBY_SIZE - 1 && *pos >= ' ') { + char c = *pos++; + if (c == '"' || c == '\\') { + // Need to escape the quote-mark for JSON + if (i > GENBY_SIZE - 3) break; + genBy[i++] = '\\'; + } + genBy[i++] = c; + } + genBy[i] = 0; + return true; + } + + // CURA + const char* slicedAtString = PSTR(";Sliced at: "); + pos = strstr_P(buf, slicedAtString); + if (pos) { + strcpy_P(genBy, PSTR("Cura")); + return true; + } + + // UNKNOWN + strcpy_P(genBy, PSTR("Unknown")); + return false; +} + +bool GCodeFileInfo::findLayerHeight(char *buf, float &layerHeight) { + // SLIC3R + layerHeight = 0; + const char* layerHeightSlic3r = PSTR("; layer_height "); + char *pos = strstr_P(buf, layerHeightSlic3r); + if (pos) { + pos += strlen_P(layerHeightSlic3r); + while (*pos == ' ' || *pos == 't' || *pos == '=' || *pos == ':') { + ++pos; + } + layerHeight = strtod(pos, NULL); + return true; + } + + // CURA + const char* layerHeightCura = PSTR("Layer height: "); + pos = strstr_P(buf, layerHeightCura); + if (pos) { + pos += strlen_P(layerHeightCura); + while (*pos == ' ' || *pos == 't' || *pos == '=' || *pos == ':') { + ++pos; + } + layerHeight = strtod(pos, NULL); + return true; + } + + return false; +} + +bool GCodeFileInfo::findFilamentNeed(char *buf, float &filament) { + const char* filamentUsedStr = PSTR("filament used"); + const char* pos = strstr_P(buf, filamentUsedStr); + filament = 0; + if (pos != NULL) { + pos += strlen_P(filamentUsedStr); + while (*pos == ' ' || *pos == 't' || *pos == '=' || *pos == ':') { + ++pos; // this allows for " = " from default slic3r comment and ": " from default Cura comment + } + if (isDigit(*pos)) { + char *q; + filament += strtod(pos, &q); + if (*q == 'm' && *(q + 1) != 'm') { + filament *= 1000.0; // Cura outputs filament used in metres not mm + } + } + return true; + } + return false; +} + +bool GCodeFileInfo::findTotalHeight(char *buf, float &height) { + int len = 1024; + bool inComment, inRelativeMode = false; + unsigned int zPos; + for (int i = len - 5; i > 0; i--) { + if (inRelativeMode) { + inRelativeMode = !(buf[i] == 'G' && buf[i + 1] == '9' && buf[i + 2] == '1' && buf[i + 3] <= ' '); + } else if (buf[i] == 'G') { + // Ignore G0/G1 codes if absolute mode was switched back using G90 (typical for Cura files) + if (buf[i + 1] == '9' && buf[i + 2] == '0' && buf[i + 3] <= ' ') { + inRelativeMode = true; + } else if ((buf[i + 1] == '0' || buf[i + 1] == '1') && buf[i + 2] == ' ') { + // Look for last "G0/G1 ... Z#HEIGHT#" command as generated by common slicers + // Looks like we found a controlled move, however it could be in a comment, especially when using slic3r 1.1.1 + inComment = false; + size_t j = i; + while (j != 0) { + --j; + char c = buf[j]; + if (c == '\n' || c == '\r') break; + if (c == ';') { + // It is in a comment, so give up on this one + inComment = true; + break; + } + } + if (inComment) continue; + + // Find 'Z' position and grab that value + zPos = 0; + for (int j = i + 3; j < len - 2; j++) { + char c = buf[j]; + if (c < ' ') { + // Skip all whitespaces... + while (j < len - 2 && c <= ' ') { + c = buf[++j]; + } + // ...to make sure ";End" doesn't follow G0 .. Z#HEIGHT# + if (zPos != 0) { + //debugPrintf("Found at offset %u text: %.100s\n", zPos, &buf[zPos + 1]); + height = strtod(&buf[zPos + 1], NULL); + return true; + } + break; + } else if (c == ';') break; + else if (c == 'Z') zPos = j; + } + } + } + } + return false; +} +#endif // JSON_OUTPUT diff --git a/trunk/Arduino/Repetier_0.92.9/gcode.h b/trunk/Arduino/Repetier_0.92.9/gcode.h new file mode 100644 index 00000000..22118053 --- /dev/null +++ b/trunk/Arduino/Repetier_0.92.9/gcode.h @@ -0,0 +1,255 @@ +/* + This file is part of Repetier-Firmware. + + Repetier-Firmware is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Repetier-Firmware is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Repetier-Firmware. If not, see . + +*/ +#ifndef _GCODE_H +#define _GCODE_H + +#define MAX_CMD_SIZE 96 +#define ARRAY_SIZE(_x) (sizeof(_x)/sizeof(_x[0])) +class SDCard; +class GCode // 52 uint8_ts per command needed +{ + uint16_t params; + uint16_t params2; +public: + uint16_t N; // Line number + uint16_t M; + uint16_t G; + float X; + float Y; + float Z; + float E; + float F; + int32_t S; + int32_t P; + float I; + float J; + float R; + float D; + float C; + float H; + float A; + float B; + float K; + float L; + float O; + + char *text; //text[17]; + //moved the byte to the end and aligned ints on short boundary + // Old habit from PC, which require alignments for data types such as int and long to be on 2 or 4 byte boundary + // Otherwise, the compiler adds padding, wasted space. + uint8_t T; // This may not matter on any of these controllers, but it can't hurt + // True if origin did not come from serial console. That way we can send status messages to + // a host only if he would normally not know about the mode switch. + bool internalCommand; + inline bool hasM() + { + return ((params & 2)!=0); + } + inline bool hasN() + { + return ((params & 1)!=0); + } + inline bool hasG() + { + return ((params & 4)!=0); + } + inline bool hasX() + { + return ((params & 8)!=0); + } + inline bool hasY() + { + return ((params & 16)!=0); + } + inline bool hasZ() + { + return ((params & 32)!=0); + } + inline bool hasNoXYZ() + { + return ((params & 56)==0); + } + inline bool hasE() + { + return ((params & 64)!=0); + } + inline bool hasF() + { + return ((params & 256)!=0); + } + inline bool hasT() + { + return ((params & 512)!=0); + } + inline bool hasS() + { + return ((params & 1024)!=0); + } + inline bool hasP() + { + return ((params & 2048)!=0); + } + inline bool isV2() + { + return ((params & 4096)!=0); + } + inline bool hasString() + { + return ((params & 32768)!=0); + } + inline bool hasI() + { + return ((params2 & 1)!=0); + } + inline bool hasJ() + { + return ((params2 & 2)!=0); + } + inline bool hasR() + { + return ((params2 & 4)!=0); + } + inline bool hasD() + { + return ((params2 & 8)!=0); + } + inline bool hasC() + { + return ((params2 & 16)!=0); + } + inline bool hasH() + { + return ((params2 & 32)!=0); + } + inline bool hasA() + { + return ((params2 & 64)!=0); + } + inline bool hasB() + { + return ((params2 & 128)!=0); + } + inline bool hasK() + { + return ((params2 & 256)!=0); + } + inline bool hasL() + { + return ((params2 & 512)!=0); + } + inline bool hasO() + { + return ((params2 & 1024)!=0); + } + inline long getS(long def) + { + return (hasS() ? S : def); + } + inline long getP(long def) + { + return (hasP() ? P : def); + } + inline void setFormatError() { + params2 |= 32768; + } + inline bool hasFormatError() { + return ((params2 & 32768)!=0); + } + void printCommand(); + bool parseBinary(uint8_t *buffer,bool fromSerial); + bool parseAscii(char *line,bool fromSerial); + void popCurrentCommand(); + void echoCommand(); + /** Get next command in command buffer. After the command is processed, call gcode_command_finished() */ + static GCode *peekCurrentCommand(); + /** Frees the cache used by the last command fetched. */ + static void readFromSerial(); + static void pushCommand(); + static void executeFString(FSTRINGPARAM(cmd)); + static uint8_t computeBinarySize(char *ptr); + static void fatalError(FSTRINGPARAM(message)); + static void reportFatalError(); + static void resetFatalError(); + inline static bool hasFatalError() { + return fatalErrorMsg != NULL; + } + friend class SDCard; + friend class UIDisplay; +private: + void debugCommandBuffer(); + void checkAndPushCommand(); + static void requestResend(); + inline float parseFloatValue(char *s) + { + char *endPtr; + while(*s == 32) s++; // skip spaces + float f = (strtod(s, &endPtr)); + if(s == endPtr) f=0.0; // treat empty string "x " as "x0" + return f; + } + inline long parseLongValue(char *s) + { + char *endPtr; + while(*s == 32) s++; // skip spaces + long l = (strtol(s, &endPtr, 10)); + if(s == endPtr) l=0; // treat empty string argument "p " as "p0" + return l; + } + + static FSTRINGPARAM(fatalErrorMsg); + static GCode commandsBuffered[GCODE_BUFFER_SIZE]; ///< Buffer for received commands. + static uint8_t bufferReadIndex; ///< Read position in gcode_buffer. + static uint8_t bufferWriteIndex; ///< Write position in gcode_buffer. + static uint8_t commandReceiving[MAX_CMD_SIZE]; ///< Current received command. + static uint8_t commandsReceivingWritePosition; ///< Writing position in gcode_transbuffer. + static uint8_t sendAsBinary; ///< Flags the command as binary input. + static uint8_t wasLastCommandReceivedAsBinary; ///< Was the last successful command in binary mode? + static uint8_t commentDetected; ///< Flags true if we are reading the comment part of a command. + static uint8_t binaryCommandSize; ///< Expected size of the incoming binary command. + static bool waitUntilAllCommandsAreParsed; ///< Don't read until all commands are parsed. Needed if gcode_buffer is misused as storage for strings. + static uint32_t lastLineNumber; ///< Last line number received. + static uint32_t actLineNumber; ///< Line number of current command. + static int8_t waitingForResend; ///< Waiting for line to be resend. -1 = no wait. + static volatile uint8_t bufferLength; ///< Number of commands stored in gcode_buffer + static millis_t timeOfLastDataPacket; ///< Time, when we got the last data packet. Used to detect missing uint8_ts. + static uint8_t formatErrors; ///< Number of sequential format errors +}; + +#if JSON_OUTPUT +#include "SdFat.h" +// Struct to hold Gcode file information 32 bytes +#define GENBY_SIZE 16 +class GCodeFileInfo { +public: + void init(SdBaseFile &file); + + unsigned long fileSize; + float objectHeight; + float layerHeight; + float filamentNeeded; + char generatedBy[GENBY_SIZE]; + + bool findGeneratedBy(char *buf, char *genBy); + bool findLayerHeight(char *buf, float &layerHeight); + bool findFilamentNeed(char *buf, float &filament); + bool findTotalHeight(char *buf, float &objectHeight); +}; +#endif + +#endif + diff --git a/trunk/Arduino/Repetier_0.92.9/logo.h b/trunk/Arduino/Repetier_0.92.9/logo.h new file mode 100644 index 00000000..979aafc7 --- /dev/null +++ b/trunk/Arduino/Repetier_0.92.9/logo.h @@ -0,0 +1,46 @@ +//------------------------------------------------------------------------------ +// File generated by LCD Assistant +// http://en.radzio.dxp.pl/bitmap_converter/ +//------------------------------------------------------------------------------ + +#ifndef CUSTOM_LOGO +#define LOGO_WIDTH 60 +#define LOGO_HEIGHT 64 + +const unsigned char logo[] PROGMEM = { //AVR-GCC, WinAVR +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x01, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0xFF, 0xFE, 0x00, +0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0xC3, 0xE1, 0xF0, 0x7F, 0x0F, 0xC0, +0x00, 0x07, 0x1F, 0x87, 0xC1, 0xFC, 0x3F, 0xC0, 0x00, 0x38, 0xFF, 0xFF, 0xFF, 0xF0, 0xFE, 0x40, +0x01, 0xC3, 0xFF, 0xFF, 0xFF, 0xC1, 0xFC, 0x40, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x07, 0xF0, 0x40, +0x3F, 0xFF, 0xFF, 0x80, 0x00, 0x1F, 0xE0, 0x40, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x40, +0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x40, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x40, +0x30, 0x00, 0x00, 0x01, 0xFF, 0xFC, 0x04, 0x40, 0x30, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x0C, 0x40, +0x30, 0x00, 0x00, 0x00, 0x00, 0x38, 0x1C, 0x40, 0x30, 0x00, 0x00, 0x00, 0x00, 0x38, 0x3E, 0x40, +0x30, 0x00, 0x00, 0x00, 0x00, 0x38, 0x7E, 0x40, 0x30, 0xFF, 0xFF, 0x80, 0x00, 0x38, 0xFE, 0x40, +0x30, 0xFF, 0xFF, 0xF8, 0x00, 0x38, 0xFE, 0x40, 0x30, 0xFF, 0xFF, 0xFE, 0x00, 0x38, 0xE6, 0x40, +0x30, 0xFF, 0xFF, 0xFF, 0x00, 0x38, 0xE6, 0x40, 0x30, 0xFF, 0xFF, 0xFF, 0x80, 0x38, 0xC6, 0x40, +0x30, 0xFF, 0xFF, 0xFF, 0x80, 0x38, 0xC6, 0x40, 0x30, 0xFF, 0xBF, 0xFF, 0x80, 0x38, 0xC4, 0x40, +0x30, 0xFF, 0x80, 0xFF, 0xC0, 0x38, 0xC4, 0x40, 0x30, 0xFF, 0x80, 0xFF, 0xC0, 0x38, 0xC4, 0x40, +0x30, 0xFF, 0x80, 0x7F, 0xC0, 0x38, 0xCC, 0x40, 0x30, 0xFF, 0x80, 0x7F, 0xC0, 0x38, 0xFC, 0x40, +0x30, 0xFF, 0x80, 0x7F, 0xC0, 0x38, 0xF8, 0x40, 0x30, 0xFF, 0x80, 0xFF, 0xC0, 0x38, 0xF8, 0x40, +0x30, 0xFF, 0xFF, 0xFF, 0xC0, 0x38, 0xF0, 0x40, 0x30, 0xFF, 0xFF, 0xFF, 0x80, 0x38, 0xE0, 0x40, +0x30, 0xFF, 0xFF, 0xFF, 0x80, 0x38, 0xE0, 0x40, 0x30, 0xFF, 0xFF, 0xFF, 0x00, 0x38, 0xC0, 0x40, +0x30, 0xFF, 0xFF, 0xFE, 0x00, 0x38, 0xC0, 0x40, 0x30, 0xFF, 0xFF, 0xF0, 0x00, 0x38, 0xC0, 0x40, +0x30, 0xFF, 0x9F, 0xF0, 0x00, 0x38, 0xC0, 0x40, 0x30, 0xFF, 0x8F, 0xFC, 0x00, 0x38, 0xC0, 0x40, +0x30, 0xFF, 0x87, 0xFC, 0x00, 0x38, 0xC0, 0x40, 0x30, 0xFF, 0x87, 0xFE, 0x00, 0x38, 0xC0, 0x40, +0x30, 0xFF, 0x83, 0xFF, 0x00, 0x38, 0xC0, 0x80, 0x30, 0xFF, 0x83, 0xFF, 0x00, 0x38, 0xC0, 0x80, +0x30, 0xFF, 0x81, 0xFF, 0x80, 0x38, 0xC1, 0x00, 0x30, 0xFF, 0x81, 0xFF, 0x80, 0x38, 0xC2, 0x00, +0x30, 0xFF, 0x80, 0xFF, 0xC0, 0x38, 0x82, 0x00, 0x30, 0xFF, 0x80, 0xFF, 0xC0, 0x38, 0x84, 0x00, +0x30, 0xFF, 0x80, 0x7F, 0xE0, 0x38, 0x08, 0x00, 0x30, 0x7F, 0x80, 0x7F, 0xE0, 0x38, 0x08, 0x00, +0x30, 0x0F, 0x80, 0x3F, 0xE0, 0x38, 0x10, 0x00, 0x30, 0x00, 0x00, 0x3F, 0xF0, 0x38, 0x10, 0x00, +0x38, 0x00, 0x00, 0x03, 0xF0, 0x38, 0x20, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x38, 0x40, 0x00, +0x3C, 0x00, 0x00, 0x00, 0x00, 0x38, 0x40, 0x00, 0x3F, 0xF8, 0x00, 0x00, 0x00, 0x39, 0x80, 0x00, +0x3F, 0xFF, 0xF8, 0x00, 0x00, 0x3D, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF8, 0x00, 0x7F, 0x00, 0x00, +0x00, 0x07, 0xFF, 0xFF, 0xF8, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFC, 0x00, 0x00, +0x00, 0x00, 0x00, 0x03, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xF8, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; +#else +LOGO_BITMAP +#endif diff --git a/trunk/Arduino/Repetier_0.92.9/makefile b/trunk/Arduino/Repetier_0.92.9/makefile new file mode 100644 index 00000000..57f254a4 --- /dev/null +++ b/trunk/Arduino/Repetier_0.92.9/makefile @@ -0,0 +1,140 @@ +# Arduino Make file. Refer to https://github.com/sudar/Arduino-Makefile +# + +BOARD_TAG = mighty_opt +BOARDS_TXT = $(ARDUINO_SKETCHBOOK)/hardware/custom/avr/boards.txt +BOOTLOADER_PARENT = $(ARDUINO_SKETCHBOOK)/hardware/custom/avr/bootloaders +#ARDUINO_CORE_PATH = $(ARDUINO_SKETCHBOOK)/hardware/custom/avr/cores/standard +#ARDUINO_PLATFORM_LIB_PATH = $(ARDUINO_SKETCHBOOK)/hardware/custom/avr/libraries +ARDUINO_VAR_PATH = $(ARDUINO_SKETCHBOOK)/hardware/custom/avr/variants + +BOOTLOADER_PATH = optiboot +BOOTLOADER_FILE = optiboot_atmega1284p.hex +ISP_PROG = usbasp +#AVRDUDE_OPTS = -v +include ../paths.mk +include ../Arduino.mk + +# --- leonardo (or pro micro w/leo bootloader) +#BOARD_TAG = leonardo +#MONITOR_PORT = /dev/ttyACM0 +#include /usr/share/arduino/Arduino.mk + +# --- mega2560 ide 1.0 +#BOARD_TAG = mega2560 +#ARDUINO_PORT = /dev/ttyACM0 +#include /usr/share/arduino/Arduino.mk + +# --- mega2560 ide 1.6 +#BOARD_TAG = mega +#BOARD_SUB = atmega2560 +#MONITOR_PORT = /dev/ttyACM0 +#ARDUINO_DIR = /where/you/installed/arduino-1.6.5 +#include /usr/share/arduino/Arduino.mk + +# --- nano ide 1.0 +#BOARD_TAG = nano328 +#MONITOR_PORT = /dev/ttyUSB0 +#include /usr/share/arduino/Arduino.mk + +# --- nano ide 1.6 +#BOARD_TAG = nano +#BOARD_SUB = atmega328 +#ARDUINO_DIR = /where/you/installed/arduino-1.6.5 +#include /usr/share/arduino/Arduino.mk + +# --- pro mini +#BOARD_TAG = pro5v328 +#MONITOR_PORT = /dev/ttyUSB0 +#include /usr/share/arduino/Arduino.mk + +# --- sparkfun pro micro +#BOARD_TAG = promicro16 +#ALTERNATE_CORE = promicro +#BOARDS_TXT = $(HOME)/arduino/hardware/promicro/boards.txt +#BOOTLOADER_PARENT = $(HOME)/arduino/hardware/promicro/bootloaders +#BOOTLOADER_PATH = caterina +#BOOTLOADER_FILE = Caterina-promicro16.hex +#ISP_PROG = usbasp +#AVRDUDE_OPTS = -v +#include /usr/share/arduino/Arduino.mk + +# --- chipkit +#BOARD_TAG = mega_pic32 +#MPIDE_DIR = /where/you/installed/mpide-0023-linux64-20130817-test +#include /usr/share/arduino/chipKIT.mk + +# --- pinoccio +#BOARD_TAG = pinoccio256 +#ALTERNATE_CORE = pinoccio +#BOOTLOADER_PARENT = $(HOME)/arduino/hardware/pinoccio/bootloaders +#BOOTLOADER_PATH = STK500RFR2/release_0.51 +#BOOTLOADER_FILE = boot_pinoccio.hex +#CFLAGS_STD = -std=gnu99 +#CXXFLAGS_STD = -std=gnu++11 +#include /usr/share/arduino/Arduino.mk + +# --- fio +#BOARD_TAG = fio +#include /usr/share/arduino/Arduino.mk + +# --- atmega-ng ide 1.6 +#BOARD_TAG = atmegang +#BOARD_SUB = atmega168 +#MONITOR_PORT = /dev/ttyACM0 +#ARDUINO_DIR = /where/you/installed/arduino-1.6.5 +#include /usr/share/arduino/Arduino.mk + +# --- arduino-tiny ide 1.0 +#ISP_PROG = usbasp +#BOARD_TAG = attiny85at8 +#ALTERNATE_CORE = tiny +#ARDUINO_VAR_PATH = $(HOME)/arduino/hardware/tiny/cores/tiny +#ARDUINO_CORE_PATH = $(HOME)/arduino/hardware/tiny/cores/tiny +#AVRDUDE_OPTS = -v +#include /usr/share/arduino/Arduino.mk + +# --- arduino-tiny ide 1.6 +#ISP_PROG = usbasp +#BOARD_TAG = attiny85at8 +#ALTERNATE_CORE = tiny +#ARDUINO_DIR = /where/you/installed/arduino-1.6.5 +#include /usr/share/arduino/Arduino.mk + +# --- damellis attiny ide 1.0 +#ISP_PROG = usbasp +#BOARD_TAG = attiny85 +#ALTERNATE_CORE = attiny-master +#AVRDUDE_OPTS = -v +#include /usr/share/arduino/Arduino.mk + +# --- damellis attiny ide 1.6 +#ISP_PROG = usbasp +#BOARD_TAG = attiny +#BOARD_SUB = attiny85 +#ALTERNATE_CORE = attiny +#F_CPU = 16000000L +#ARDUINO_DIR = /where/you/installed/arduino-1.6.5 +#include /usr/share/arduino/Arduino.mk + +# --- teensy3 +#BOARD_TAG = teensy31 +#ARDUINO_DIR = /where/you/installed/the/patched/teensy/arduino-1.0.6 +#include /usr/share/arduino/Teensy.mk + +# --- mighty 1284p +#BOARD_TAG = mighty_opt +#BOARDS_TXT = $(HOME)/arduino/hardware/mighty-1284p/boards.txt +#BOOTLOADER_PARENT = $(HOME)/arduino/hardware/mighty-1284p/bootloaders +#BOOTLOADER_PATH = optiboot +#BOOTLOADER_FILE = optiboot_atmega1284p.hex +#ISP_PROG = usbasp +#AVRDUDE_OPTS = -v +#include /usr/share/arduino/Arduino.mk + +# --- atmega328p on breadboard +#BOARD_TAG = atmega328bb +#ISP_PROG = usbasp +#AVRDUDE_OPTS = -v +#BOARDS_TXT = $(HOME)/arduino/hardware/breadboard/boards.txt +#include /usr/share/arduino/Arduino.mk diff --git a/trunk/Arduino/Repetier_0.92.9/motion.cpp b/trunk/Arduino/Repetier_0.92.9/motion.cpp new file mode 100644 index 00000000..2f868500 --- /dev/null +++ b/trunk/Arduino/Repetier_0.92.9/motion.cpp @@ -0,0 +1,2914 @@ +/* + This file is part of Repetier-Firmware. + + Repetier-Firmware is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Repetier-Firmware is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Repetier-Firmware. If not, see . + + This firmware is a nearly complete rewrite of the sprinter firmware + by kliment (https://github.com/kliment/Sprinter) + which based on Tonokip RepRap firmware rewrite based off of Hydra-mmm firmware. + + Functions in this file are used to communicate using ascii or repetier protocol. +*/ + +#include "Repetier.h" + +// ================ Sanity checks ================ +#ifndef STEP_DOUBLER_FREQUENCY +#error Please add new parameter STEP_DOUBLER_FREQUENCY to your configuration. +#else +#if STEP_DOUBLER_FREQUENCY < 10000 || STEP_DOUBLER_FREQUENCY > 20000 +#if CPU_ARCH==ARCH_AVR +#error STEP_DOUBLER_FREQUENCY should be in range 10000-16000. +#endif +#endif +#endif +#ifdef EXTRUDER_SPEED +#error EXTRUDER_SPEED is not used any more. Values are now taken from extruder definition. +#endif +#ifdef ENDSTOPPULLUPS +#error ENDSTOPPULLUPS is now replaced by individual pullup configuration! +#endif +#ifdef EXT0_PID_PGAIN +#error The PID system has changed. Please use the new float number options! +#endif +// #################################################################################### +// # No configuration below this line - just some error checking # +// #################################################################################### +#ifdef SUPPORT_MAX6675 +#if !defined SCK_PIN || !defined MOSI_PIN || !defined MISO_PIN +#error For MAX6675 support, you need to define SCK_PIN, MISO_PIN and MOSI_PIN in pins.h +#endif +#endif +#if X_STEP_PIN < 0 || Y_STEP_PIN < 0 || Z_STEP_PIN < 0 +#error One of the following pins is not assigned: X_STEP_PIN,Y_STEP_PIN,Z_STEP_PIN +#endif +#if EXT0_STEP_PIN < 0 && NUM_EXTRUDER > 0 +#error EXT0_STEP_PIN not set to a pin number. +#endif +#if EXT0_DIR_PIN < 0 && NUM_EXTRUDER > 0 +#error EXT0_DIR_PIN not set to a pin number. +#endif +#if PRINTLINE_CACHE_SIZE < 4 +#error PRINTLINE_CACHE_SIZE must be at least 5 +#endif + +//Inactivity shutdown variables +millis_t previousMillisCmd = 0; +millis_t maxInactiveTime = MAX_INACTIVE_TIME * 1000L; +millis_t stepperInactiveTime = STEPPER_INACTIVE_TIME * 1000L; +long baudrate = BAUDRATE; ///< Communication speed rate. +#if USE_ADVANCE +#if ENABLE_QUADRATIC_ADVANCE +int maxadv = 0; +#endif +int maxadv2 = 0; +float maxadvspeed = 0; +#endif +uint8_t pwm_pos[NUM_PWM]; // 0-NUM_EXTRUDER = Heater 0-NUM_EXTRUDER of extruder, NUM_EXTRUDER = Heated bed, NUM_EXTRUDER+1 Board fan, NUM_EXTRUDER+2 = Fan +volatile int waitRelax = 0; // Delay filament relax at the end of print, could be a simple timeout + +PrintLine PrintLine::lines[PRINTLINE_CACHE_SIZE]; ///< Cache for print moves. +PrintLine *PrintLine::cur = NULL; ///< Current printing line +#if CPU_ARCH == ARCH_ARM +volatile bool PrintLine::nlFlag = false; +#endif +ufast8_t PrintLine::linesWritePos = 0; ///< Position where we write the next cached line move. +volatile ufast8_t PrintLine::linesCount = 0; ///< Number of lines cached 0 = nothing to do. +ufast8_t PrintLine::linesPos = 0; ///< Position for executing line movement. + +/** +Move printer the given number of steps. Puts the move into the queue. Used by e.g. homing commands. +*/ +void PrintLine::moveRelativeDistanceInSteps(int32_t x, int32_t y, int32_t z, int32_t e, float feedrate, bool waitEnd, bool checkEndstop,bool pathOptimize) +{ +#if NUM_EXTRUDER > 0 + if(Printer::debugDryrun() || (MIN_EXTRUDER_TEMP > 30 && Extruder::current->tempControl.currentTemperatureC < MIN_EXTRUDER_TEMP && !Printer::isColdExtrusionAllowed())) + e = 0; // should not be allowed for current temperature +#endif + float savedFeedrate = Printer::feedrate; + Printer::destinationSteps[X_AXIS] = Printer::currentPositionSteps[X_AXIS] + x; + Printer::destinationSteps[Y_AXIS] = Printer::currentPositionSteps[Y_AXIS] + y; + Printer::destinationSteps[Z_AXIS] = Printer::currentPositionSteps[Z_AXIS] + z; + Printer::destinationSteps[E_AXIS] = Printer::currentPositionSteps[E_AXIS] + e; + Printer::feedrate = feedrate; +#if NONLINEAR_SYSTEM + if (!queueNonlinearMove(checkEndstop, pathOptimize, false)) + { + Com::printWarningFLN(PSTR("moveRelativeDistanceInSteps / queueDeltaMove returns error")); + } +#else + queueCartesianMove(checkEndstop, pathOptimize); +#endif + Printer::feedrate = savedFeedrate; + Printer::updateCurrentPosition(false); + if(waitEnd) + Commands::waitUntilEndOfAllMoves(); + previousMillisCmd = HAL::timeInMilliseconds(); +} + +void PrintLine::moveRelativeDistanceInStepsReal(int32_t x, int32_t y, int32_t z, int32_t e, float feedrate, bool waitEnd,bool pathOptimize) +{ + Printer::lastCmdPos[X_AXIS] += x * Printer::invAxisStepsPerMM[X_AXIS]; + Printer::lastCmdPos[Y_AXIS] += y * Printer::invAxisStepsPerMM[Y_AXIS]; + Printer::lastCmdPos[Z_AXIS] += z * Printer::invAxisStepsPerMM[Z_AXIS]; + if(!Printer::isPositionAllowed( Printer::lastCmdPos[X_AXIS], Printer::lastCmdPos[Y_AXIS], Printer::lastCmdPos[Z_AXIS])) + { + return; // ignore move + } +#if NUM_EXTRUDER > 0 + if(Printer::debugDryrun() || (MIN_EXTRUDER_TEMP > 30 && Extruder::current->tempControl.currentTemperatureC < MIN_EXTRUDER_TEMP && !Printer::isColdExtrusionAllowed())) + e = 0; // should not be allowed for current temperature +#endif + Printer::moveToReal(Printer::lastCmdPos[X_AXIS], Printer::lastCmdPos[Y_AXIS], Printer::lastCmdPos[Z_AXIS], + (Printer::currentPositionSteps[E_AXIS] + e) * Printer::invAxisStepsPerMM[E_AXIS],feedrate,pathOptimize); + Printer::updateCurrentPosition(); + if(waitEnd) + Commands::waitUntilEndOfAllMoves(); + previousMillisCmd = HAL::timeInMilliseconds(); +} + +#if !NONLINEAR_SYSTEM +#if DISTORTION_CORRECTION + /* Special version which adds distortion correction to z. Gets called from queueCartesianMove if needed. */ + void PrintLine::queueCartesianSegmentTo(uint8_t check_endstops, uint8_t pathOptimize) { + + // Correct the bumps + Printer::zCorrectionStepsIncluded = Printer::distortion.correct(Printer::destinationSteps[X_AXIS],Printer::destinationSteps[Y_AXIS],Printer::destinationSteps[Z_AXIS]); + Printer::destinationSteps[Z_AXIS] += Printer::zCorrectionStepsIncluded; +#if DEBUG_DISTORTION + Com::printF(PSTR("zCorr:"),Printer::zCorrectionStepsIncluded*Printer::invAxisStepsPerMM[Z_AXIS],3); + Com::printF(PSTR(" atX:"),Printer::destinationSteps[0]*Printer::invAxisStepsPerMM[X_AXIS]); + Com::printFLN(PSTR(" atY:"),Printer::destinationSteps[1]*Printer::invAxisStepsPerMM[Y_AXIS]); +#endif + PrintLine::waitForXFreeLines(1); + uint8_t newPath = PrintLine::insertWaitMovesIfNeeded(pathOptimize, 0); + PrintLine *p = PrintLine::getNextWriteLine(); + + float axisDistanceMM[E_AXIS_ARRAY]; // Axis movement in mm + p->flags = (check_endstops ? FLAG_CHECK_ENDSTOPS : 0); + #if MIXING_EXTRUDER + if(Printer::isAllEMotors()) { + p->flags |= FLAG_ALL_E_MOTORS; + } + #endif + p->joinFlags = 0; + if(!pathOptimize) p->setEndSpeedFixed(true); + p->dir = 0; + //Find direction + Printer::zCorrectionStepsIncluded = 0; + for(uint8_t axis = 0; axis < 4; axis++) + { + p->delta[axis] = Printer::destinationSteps[axis] - Printer::currentPositionSteps[axis]; + p->secondSpeed = Printer::fanSpeed; + if(axis == E_AXIS) + { + if(Printer::mode == PRINTER_MODE_FFF) + { + Printer::extrudeMultiplyError += (static_cast(p->delta[E_AXIS]) * Printer::extrusionFactor); + p->delta[E_AXIS] = static_cast(Printer::extrudeMultiplyError); + Printer::extrudeMultiplyError -= p->delta[E_AXIS]; + Printer::filamentPrinted += p->delta[E_AXIS] * Printer::invAxisStepsPerMM[axis]; + } + #if defined(SUPPORT_LASER) && SUPPORT_LASER + else if(Printer::mode == PRINTER_MODE_LASER) + { + p->secondSpeed = ((p->delta[X_AXIS] != 0 || p->delta[Y_AXIS] != 0) && (LaserDriver::laserOn || p->delta[E_AXIS] != 0) ? LaserDriver::intensity : 0); + p->delta[E_AXIS] = 0; + } + #endif + } + if(p->delta[axis] >= 0) + p->setPositiveDirectionForAxis(axis); + else + p->delta[axis] = -p->delta[axis]; + axisDistanceMM[axis] = p->delta[axis] * Printer::invAxisStepsPerMM[axis]; + if(p->delta[axis]) p->setMoveOfAxis(axis); + Printer::currentPositionSteps[axis] = Printer::destinationSteps[axis]; + } + if(p->isNoMove()) + { + if(newPath) // need to delete dummy elements, otherwise commands can get locked. + PrintLine::resetPathPlanner(); + return; // No steps included + } + float xydist2; + #if ENABLE_BACKLASH_COMPENSATION + if((p->isXYZMove()) && ((p->dir & XYZ_DIRPOS)^(Printer::backlashDir & XYZ_DIRPOS)) & (Printer::backlashDir >> 3)) // We need to compensate backlash, add a move + { + PrintLine::waitForXFreeLines(2); + uint8_t wpos2 = PrintLine::linesWritePos + 1; + if(wpos2 >= PRINTLINE_CACHE_SIZE) wpos2 = 0; + PrintLine *p2 = &PrintLine::lines[wpos2]; + memcpy(p2,p,sizeof(PrintLine)); // Move current data to p2 + uint8_t changed = (p->dir & XYZ_DIRPOS)^(Printer::backlashDir & XYZ_DIRPOS); + float back_diff[4]; // Axis movement in mm + back_diff[E_AXIS] = 0; + back_diff[X_AXIS] = (changed & 1 ? (p->isXPositiveMove() ? Printer::backlashX : -Printer::backlashX) : 0); + back_diff[Y_AXIS] = (changed & 2 ? (p->isYPositiveMove() ? Printer::backlashY : -Printer::backlashY) : 0); + back_diff[Z_AXIS] = (changed & 4 ? (p->isZPositiveMove() ? Printer::backlashZ : -Printer::backlashZ) : 0); + p->dir &= XYZ_DIRPOS; // x,y and z are already correct + for(uint8_t i = 0; i < 4; i++) + { + float f = back_diff[i]*Printer::axisStepsPerMM[i]; + p->delta[i] = abs((long)f); + if(p->delta[i]) p->dir |= XSTEP << i; + } + //Define variables that are needed for the Bresenham algorithm. Please note that Z is not currently included in the Bresenham algorithm. + if(p->delta[Y_AXIS] > p->delta[X_AXIS] && p->delta[Y_AXIS] > p->delta[Z_AXIS]) p->primaryAxis = Y_AXIS; + else if (p->delta[X_AXIS] > p->delta[Z_AXIS] ) p->primaryAxis = X_AXIS; + else p->primaryAxis = Z_AXIS; + p->stepsRemaining = p->delta[p->primaryAxis]; + //Feedrate calc based on XYZ travel distance + xydist2 = back_diff[X_AXIS] * back_diff[X_AXIS] + back_diff[Y_AXIS] * back_diff[Y_AXIS]; + if(p->isZMove()) + p->distance = sqrt(xydist2 + back_diff[Z_AXIS] * back_diff[Z_AXIS]); + else + p->distance = sqrt(xydist2); + // 56 seems to be xstep|ystep|e_posdir which just seems odd + Printer::backlashDir = (Printer::backlashDir & 56) | (p2->dir & XYZ_DIRPOS); + p->calculateMove(back_diff,pathOptimize,p->primaryAxis); + p = p2; // use saved instance for the real move + } + #endif + + //Define variables that are needed for the Bresenham algorithm. Please note that Z is not currently included in the Bresenham algorithm. + if(p->delta[Y_AXIS] > p->delta[X_AXIS] && p->delta[Y_AXIS] > p->delta[Z_AXIS] && p->delta[Y_AXIS] > p->delta[E_AXIS]) p->primaryAxis = Y_AXIS; + else if (p->delta[X_AXIS] > p->delta[Z_AXIS] && p->delta[X_AXIS] > p->delta[E_AXIS]) p->primaryAxis = X_AXIS; + else if (p->delta[Z_AXIS] > p->delta[E_AXIS]) p->primaryAxis = Z_AXIS; + else p->primaryAxis = E_AXIS; + p->stepsRemaining = p->delta[p->primaryAxis]; + if(p->isXYZMove()) + { + xydist2 = axisDistanceMM[X_AXIS] * axisDistanceMM[X_AXIS] + axisDistanceMM[Y_AXIS] * axisDistanceMM[Y_AXIS]; + if(p->isZMove()) + p->distance = RMath::max((float)sqrt(xydist2 + axisDistanceMM[Z_AXIS] * axisDistanceMM[Z_AXIS]),fabs(axisDistanceMM[E_AXIS])); + else + p->distance = RMath::max((float)sqrt(xydist2),fabs(axisDistanceMM[E_AXIS])); + } + else + p->distance = fabs(axisDistanceMM[E_AXIS]); + p->calculateMove(axisDistanceMM,pathOptimize,p->primaryAxis); + + } +#endif +/** + Put a move to the current destination coordinates into the movement cache. + If the cache is full, the method will wait, until a place gets free. During + wait communication and temperature control is enabled. + @param check_endstops Read endstop during move. +*/ +void PrintLine::queueCartesianMove(uint8_t check_endstops, uint8_t pathOptimize) +{ + Printer::constrainDestinationCoords(); + Printer::unsetAllSteppersDisabled(); +#if DISTORTION_CORRECTION + if(Printer::distortion.isEnabled() && Printer::destinationSteps[Z_AXIS] < Printer::distortion.zMaxSteps() && Printer::isZProbingActive() == false && !Printer::isHoming()) { + // we are inside correction height so we split all moves in lines of max. 10 mm and add them + // including a z correction + int32_t deltas[E_AXIS_ARRAY],start[E_AXIS_ARRAY]; + for(fast8_t i = 0;i < E_AXIS_ARRAY;i++) { + deltas[i] = Printer::destinationSteps[i] - Printer::currentPositionSteps[i]; + start[i] = Printer::currentPositionSteps[i]; + } + float dx = Printer::invAxisStepsPerMM[X_AXIS] * deltas[X_AXIS]; + float dy = Printer::invAxisStepsPerMM[Y_AXIS] * deltas[Y_AXIS]; + float len = dx * dx + dy * dy; + if(len < 100) { // no splitting required + queueCartesianSegmentTo(check_endstops, pathOptimize); + return; + } + // we need to split longer lines to follow bed curvature + len = sqrt(len); + int segments = (static_cast(len) + 9) / 10; +#if DEBUG_DISTORTION + Com::printF(PSTR("Split line len:"),len);Com::printFLN(PSTR(" segments:"),segments); +#endif + for(int i = 1; i <= segments; i++) { + for(fast8_t j = 0; j < E_AXIS_ARRAY; j++) { + Printer::destinationSteps[j] = start[j] + (i * deltas[j]) / segments; + } + queueCartesianSegmentTo(check_endstops, pathOptimize); + } + return; + } +#endif + waitForXFreeLines(1); + uint8_t newPath = insertWaitMovesIfNeeded(pathOptimize, 0); + PrintLine *p = getNextWriteLine(); + + float axisDistanceMM[E_AXIS_ARRAY]; // Axis movement in mm + p->flags = (check_endstops ? FLAG_CHECK_ENDSTOPS : 0); +#if MIXING_EXTRUDER + if(Printer::isAllEMotors()) { + p->flags |= FLAG_ALL_E_MOTORS; + } +#endif + p->joinFlags = 0; + if(!pathOptimize) p->setEndSpeedFixed(true); + p->dir = 0; + //Find direction + Printer::zCorrectionStepsIncluded = 0; + for(uint8_t axis = 0; axis < 4; axis++) + { + p->delta[axis] = Printer::destinationSteps[axis] - Printer::currentPositionSteps[axis]; + p->secondSpeed = Printer::fanSpeed; + if(axis == E_AXIS) + { + if(Printer::mode == PRINTER_MODE_FFF) + { + Printer::extrudeMultiplyError += (static_cast(p->delta[E_AXIS]) * Printer::extrusionFactor); + p->delta[E_AXIS] = static_cast(Printer::extrudeMultiplyError); + Printer::extrudeMultiplyError -= p->delta[E_AXIS]; + Printer::filamentPrinted += p->delta[E_AXIS] * Printer::invAxisStepsPerMM[axis]; + } +#if defined(SUPPORT_LASER) && SUPPORT_LASER + else if(Printer::mode == PRINTER_MODE_LASER) + { + p->secondSpeed = ((p->delta[X_AXIS] != 0 || p->delta[Y_AXIS] != 0) && (LaserDriver::laserOn || p->delta[E_AXIS] != 0) ? LaserDriver::intensity : 0); + p->delta[E_AXIS] = 0; + } +#endif + } + if(p->delta[axis] >= 0) + p->setPositiveDirectionForAxis(axis); + else + p->delta[axis] = -p->delta[axis]; + axisDistanceMM[axis] = p->delta[axis] * Printer::invAxisStepsPerMM[axis]; + if(p->delta[axis]) p->setMoveOfAxis(axis); + Printer::currentPositionSteps[axis] = Printer::destinationSteps[axis]; + } + if(p->isNoMove()) + { + if(newPath) // need to delete dummy elements, otherwise commands can get locked. + resetPathPlanner(); + return; // No steps included + } + float xydist2; +#if ENABLE_BACKLASH_COMPENSATION + if((p->isXYZMove()) && ((p->dir & XYZ_DIRPOS)^(Printer::backlashDir & XYZ_DIRPOS)) & (Printer::backlashDir >> 3)) // We need to compensate backlash, add a move + { + waitForXFreeLines(2); + uint8_t wpos2 = linesWritePos + 1; + if(wpos2 >= PRINTLINE_CACHE_SIZE) wpos2 = 0; + PrintLine *p2 = &lines[wpos2]; + memcpy(p2,p,sizeof(PrintLine)); // Move current data to p2 + uint8_t changed = (p->dir & XYZ_DIRPOS)^(Printer::backlashDir & XYZ_DIRPOS); + float back_diff[4]; // Axis movement in mm + back_diff[E_AXIS] = 0; + back_diff[X_AXIS] = (changed & 1 ? (p->isXPositiveMove() ? Printer::backlashX : -Printer::backlashX) : 0); + back_diff[Y_AXIS] = (changed & 2 ? (p->isYPositiveMove() ? Printer::backlashY : -Printer::backlashY) : 0); + back_diff[Z_AXIS] = (changed & 4 ? (p->isZPositiveMove() ? Printer::backlashZ : -Printer::backlashZ) : 0); + p->dir &= XYZ_DIRPOS; // x,y and z are already correct + for(uint8_t i = 0; i < 4; i++) + { + float f = back_diff[i]*Printer::axisStepsPerMM[i]; + p->delta[i] = abs((long)f); + if(p->delta[i]) p->dir |= XSTEP << i; + } + //Define variables that are needed for the Bresenham algorithm. Please note that Z is not currently included in the Bresenham algorithm. + if(p->delta[Y_AXIS] > p->delta[X_AXIS] && p->delta[Y_AXIS] > p->delta[Z_AXIS]) p->primaryAxis = Y_AXIS; + else if (p->delta[X_AXIS] > p->delta[Z_AXIS] ) p->primaryAxis = X_AXIS; + else p->primaryAxis = Z_AXIS; + p->stepsRemaining = p->delta[p->primaryAxis]; + //Feedrate calc based on XYZ travel distance + xydist2 = back_diff[X_AXIS] * back_diff[X_AXIS] + back_diff[Y_AXIS] * back_diff[Y_AXIS]; + if(p->isZMove()) + p->distance = sqrt(xydist2 + back_diff[Z_AXIS] * back_diff[Z_AXIS]); + else + p->distance = sqrt(xydist2); + // 56 seems to be xstep|ystep|e_posdir which just seems odd + Printer::backlashDir = (Printer::backlashDir & 56) | (p2->dir & XYZ_DIRPOS); + p->calculateMove(back_diff,pathOptimize,p->primaryAxis); + p = p2; // use saved instance for the real move + } +#endif + + //Define variables that are needed for the Bresenham algorithm. Please note that Z is not currently included in the Bresenham algorithm. + if(p->delta[Y_AXIS] > p->delta[X_AXIS] && p->delta[Y_AXIS] > p->delta[Z_AXIS] && p->delta[Y_AXIS] > p->delta[E_AXIS]) p->primaryAxis = Y_AXIS; + else if (p->delta[X_AXIS] > p->delta[Z_AXIS] && p->delta[X_AXIS] > p->delta[E_AXIS]) p->primaryAxis = X_AXIS; + else if (p->delta[Z_AXIS] > p->delta[E_AXIS]) p->primaryAxis = Z_AXIS; + else p->primaryAxis = E_AXIS; + p->stepsRemaining = p->delta[p->primaryAxis]; + if(p->isXYZMove()) + { + xydist2 = axisDistanceMM[X_AXIS] * axisDistanceMM[X_AXIS] + axisDistanceMM[Y_AXIS] * axisDistanceMM[Y_AXIS]; + if(p->isZMove()) + p->distance = RMath::max((float)sqrt(xydist2 + axisDistanceMM[Z_AXIS] * axisDistanceMM[Z_AXIS]),fabs(axisDistanceMM[E_AXIS])); + else + p->distance = RMath::max((float)sqrt(xydist2),fabs(axisDistanceMM[E_AXIS])); + } + else + p->distance = fabs(axisDistanceMM[E_AXIS]); + p->calculateMove(axisDistanceMM,pathOptimize,p->primaryAxis); +} +#endif + +void PrintLine::calculateMove(float axisDistanceMM[], uint8_t pathOptimize,fast8_t drivingAxis) +{ +#if NONLINEAR_SYSTEM + long axisInterval[VIRTUAL_AXIS_ARRAY]; // shortest interval possible for that axis +#else + long axisInterval[E_AXIS_ARRAY]; +#endif + float timeForMove = (float)(F_CPU)*distance / (isXOrYMove() ? RMath::max(Printer::minimumSpeed, Printer::feedrate) : Printer::feedrate); // time is in ticks + //bool critical = Printer::isZProbingActive(); + if(linesCount < MOVE_CACHE_LOW && timeForMove < LOW_TICKS_PER_MOVE) // Limit speed to keep cache full. + { + //Com::printF(PSTR("L:"),(int)linesCount); + //Com::printF(PSTR(" Old "),timeForMove); + timeForMove += (3 * (LOW_TICKS_PER_MOVE - timeForMove)) / (linesCount + 1); // Increase time if queue gets empty. Add more time if queue gets smaller. + //Com::printFLN(PSTR("Slow "),timeForMove); + //critical = true; + } + timeInTicks = timeForMove; + UI_MEDIUM; // do check encoder + // Compute the slowest allowed interval (ticks/step), so maximum feedrate is not violated + int32_t limitInterval0; + int32_t limitInterval = limitInterval0 = timeForMove / stepsRemaining; // until not violated by other constraints it is your target speed + float toTicks = static_cast(F_CPU) / stepsRemaining; + if(isXMove()) + { + axisInterval[X_AXIS] = axisDistanceMM[X_AXIS] * toTicks / (Printer::maxFeedrate[X_AXIS]); // mm*ticks/s/(mm/s*steps) = ticks/step +#if !NONLINEAR_SYSTEM || defined(FAST_COREXYZ) + limitInterval = RMath::max(axisInterval[X_AXIS], limitInterval); +#endif + } + else axisInterval[X_AXIS] = 0; + if(isYMove()) + { + axisInterval[Y_AXIS] = axisDistanceMM[Y_AXIS] * toTicks / Printer::maxFeedrate[Y_AXIS]; +#if !NONLINEAR_SYSTEM || defined(FAST_COREXYZ) + limitInterval = RMath::max(axisInterval[Y_AXIS], limitInterval); +#endif + } + else axisInterval[Y_AXIS] = 0; + if(isZMove()) // normally no move in z direction + { + axisInterval[Z_AXIS] = axisDistanceMM[Z_AXIS] * toTicks / Printer::maxFeedrate[Z_AXIS]; // must prevent overflow! +#if !NONLINEAR_SYSTEM || defined(FAST_COREXYZ) + limitInterval = RMath::max(axisInterval[Z_AXIS], limitInterval); +#endif + } + else axisInterval[Z_AXIS] = 0; + if(isEMove()) + { + axisInterval[E_AXIS] = axisDistanceMM[E_AXIS] * toTicks / Printer::maxFeedrate[E_AXIS]; + limitInterval = RMath::max(axisInterval[E_AXIS], limitInterval); + } + else axisInterval[E_AXIS] = 0; +#if DRIVE_SYSTEM == DELTA + if(axisDistanceMM[VIRTUAL_AXIS] >= 0) {// only for deltas all speeds in all directions have same limit + axisInterval[VIRTUAL_AXIS] = axisDistanceMM[VIRTUAL_AXIS] * toTicks / (Printer::maxFeedrate[Z_AXIS]); + limitInterval = RMath::max(axisInterval[VIRTUAL_AXIS], limitInterval); + } +#endif + fullInterval = limitInterval = limitInterval > LIMIT_INTERVAL ? limitInterval : LIMIT_INTERVAL; // This is our target speed + if(limitInterval != limitInterval0) { + // new time at full speed = limitInterval*p->stepsRemaining [ticks] + timeForMove = (float)limitInterval * (float)stepsRemaining; // for large z-distance this overflows with long computation + } + float inverseTimeS = (float)F_CPU / timeForMove; + if(isXMove()) + { + axisInterval[X_AXIS] = timeForMove / delta[X_AXIS]; + speedX = axisDistanceMM[X_AXIS] * inverseTimeS; + if(isXNegativeMove()) speedX = -speedX; + } + else speedX = 0; + if(isYMove()) + { + axisInterval[Y_AXIS] = timeForMove / delta[Y_AXIS]; + speedY = axisDistanceMM[Y_AXIS] * inverseTimeS; + if(isYNegativeMove()) speedY = -speedY; + } + else speedY = 0; + if(isZMove()) + { + axisInterval[Z_AXIS] = timeForMove / delta[Z_AXIS]; + speedZ = axisDistanceMM[Z_AXIS] * inverseTimeS; + if(isZNegativeMove()) speedZ = -speedZ; + } + else speedZ = 0; + if(isEMove()) + { + axisInterval[E_AXIS] = timeForMove / delta[E_AXIS]; + speedE = axisDistanceMM[E_AXIS] * inverseTimeS; + if(isENegativeMove()) speedE = -speedE; + } +#if NONLINEAR_SYSTEM + axisInterval[VIRTUAL_AXIS] = limitInterval; //timeForMove/stepsRemaining; +#endif + fullSpeed = distance * inverseTimeS; + //long interval = axis_interval[primary_axis]; // time for every step in ticks with full speed + //If acceleration is enabled, do some Bresenham calculations depending on which axis will lead it. +#if RAMP_ACCELERATION + // slowest time to accelerate from v0 to limitInterval determines used acceleration + // t = (v_end-v_start)/a + float slowestAxisPlateauTimeRepro = 1e15; // 1/time to reduce division Unit: 1/s + uint32_t *accel = (isEPositiveMove() ? Printer::maxPrintAccelerationStepsPerSquareSecond : Printer::maxTravelAccelerationStepsPerSquareSecond); +#if defined(INTERPOLATE_ACCELERATION_WITH_Z) && INTERPOLATE_ACCELERATION_WITH_Z != 0 + uint32_t newAccel[4]; + float accelFac = (100.0 + (EEPROM::accelarationFactorTop() - 100.0) * Printer::currentPosition[Z_AXIS] / Printer::zLength)*0.01; +#if INTERPOLATE_ACCELERATION_WITH_Z == 1 || INTERPOLATE_ACCELERATION_WITH_Z == 3 + newAccel[X_AXIS] = static_cast(accel[X_AXIS] * accelFac); + newAccel[Y_AXIS] = static_cast(accel[Y_AXIS] * accelFac); +#else + newAccel[X_AXIS] = accel[X_AXIS]; + newAccel[Y_AXIS] = accel[Y_AXIS]; +#endif +#if INTERPOLATE_ACCELERATION_WITH_Z == 2 || INTERPOLATE_ACCELERATION_WITH_Z == 3 + newAccel[Z_AXIS] = static_cast(accel[Z_AXIS] * accelFac); +#else + newAccel[Z_AXIS] = accel[Z_AXIS]; +#endif + newAccel[E_AXIS] = accel[E_AXIS]; + accel = newAccel; +#endif // INTERPOLATE_ACCELERATION_WITH_Z + for(fast8_t i = 0; i < E_AXIS_ARRAY ; i++) + { + if(isMoveOfAxis(i)) + // v = a * t => t = v/a = F_CPU/(c*a) => 1/t = c*a/F_CPU + slowestAxisPlateauTimeRepro = RMath::min(slowestAxisPlateauTimeRepro, (float)axisInterval[i] * (float)accel[i]); // steps/s^2 * step/tick Ticks/s^2 + } + + // Errors for delta move are initialized in timer (except extruder) +#if !NONLINEAR_SYSTEM + error[X_AXIS] = error[Y_AXIS] = error[Z_AXIS] = error[E_AXIS] = delta[primaryAxis] >> 1; +#endif +#if NONLINEAR_SYSTEM + error[E_AXIS] = stepsRemaining >> 1; +#endif + invFullSpeed = 1.0 / fullSpeed; + accelerationPrim = slowestAxisPlateauTimeRepro / axisInterval[primaryAxis]; // a = v/t = F_CPU/(c*t): Steps/s^2 + //Now we can calculate the new primary axis acceleration, so that the slowest axis max acceleration is not violated + fAcceleration = 262144.0 * (float)accelerationPrim / F_CPU; // will overflow without float! + accelerationDistance2 = 2.0 * distance * slowestAxisPlateauTimeRepro * fullSpeed/((float)F_CPU); // mm^2/s^2 + startSpeed = endSpeed = minSpeed = safeSpeed(drivingAxis); + // Can accelerate to full speed within the line + if (startSpeed * startSpeed + accelerationDistance2 >= fullSpeed * fullSpeed) + setNominalMove(); + + vMax = F_CPU / fullInterval; // maximum steps per second, we can reach + // if(p->vMax>46000) // gets overflow in N computation + // p->vMax = 46000; + //p->plateauN = (p->vMax*p->vMax/p->accelerationPrim)>>1; +#if USE_ADVANCE + if(!isXYZMove() || !isEMove()) + { +#if ENABLE_QUADRATIC_ADVANCE + advanceRate = 0; // No head move or E move only or sucking filament back + advanceFull = 0; +#endif + advanceL = 0; + } + else + { + float advlin = fabs(speedE) * Extruder::current->advanceL * 0.001 * Printer::axisStepsPerMM[E_AXIS]; + advanceL = (uint16_t)((65536L * advlin)/vMax); //advanceLscaled = (65536*vE*k2)/vMax +#if ENABLE_QUADRATIC_ADVANCE + advanceFull = 65536*Extruder::current->advanceK * speedE * speedE; // Steps*65536 at full speed + long steps = (HAL::U16SquaredToU32(vMax)) / (accelerationPrim << 1); // v^2/(2*a) = steps needed to accelerate from 0-vMax + advanceRate = advanceFull / steps; + if((advanceFull >> 16) > maxadv) + { + maxadv = (advanceFull >> 16); + maxadvspeed = fabs(speedE); + } +#endif + if(advlin > maxadv2) + { + maxadv2 = advlin; + maxadvspeed = fabs(speedE); + } + } +#endif + UI_MEDIUM; // do check encoder + updateTrapezoids(); + // how much steps on primary axis do we need to reach target feedrate + //p->plateauSteps = (long) (((float)p->acceleration *0.5f / slowest_axis_plateau_time_repro + p->vMin) *1.01f/slowest_axis_plateau_time_repro); +#else +#if USE_ADVANCE +#if ENABLE_QUADRATIC_ADVANCE + advanceRate = 0; // No advance for constant speeds + advanceFull = 0; +#endif +#endif +#endif + +#ifdef DEBUG_STEPCOUNT +// Set in delta move calculation +#if !NONLINEAR_SYSTEM + totalStepsRemaining = delta[X_AXIS] + delta[Y_AXIS] + delta[Z_AXIS]; +#endif +#endif +#ifdef DEBUG_QUEUE_MOVE + if(Printer::debugEcho()) + { + logLine(); + Com::printFLN(Com::tDBGLimitInterval, limitInterval); + Com::printFLN(Com::tDBGMoveDistance, distance); + Com::printFLN(Com::tDBGCommandedFeedrate, Printer::feedrate); + Com::printFLN(Com::tDBGConstFullSpeedMoveTime, timeForMove); + } +#endif + // Make result permanent + if (pathOptimize) waitRelax = 70; + pushLine(); + DEBUG_MEMORY; +} + +/** +This is the path planner. + +It goes from the last entry and tries to increase the end speed of previous moves in a fashion that the maximum jerk +is never exceeded. If a segment with reached maximum speed is met, the planner stops. Everything left from this +is already optimal from previous updates. +The first 2 entries in the queue are not checked. The first is the one that is already in print and the following will likely to become active. + +The method is called before lines_count is increased! +*/ +void PrintLine::updateTrapezoids() +{ + ufast8_t first = linesWritePos; + PrintLine *firstLine; + PrintLine *act = &lines[linesWritePos]; + InterruptProtectedBlock noInts; + + // First we find out how far back we could go with optimization. + + ufast8_t maxfirst = linesPos; // first non fixed segment we might change + if(maxfirst != linesWritePos) + nextPlannerIndex(maxfirst); // don't touch the line printing + // Now ignore enough segments to gain enough time for path planning + millis_t timeleft = 0; + // Skip as many stored moves as needed to gain enough time for computation +#if PRINTLINE_CACHE_SIZE < 10 +#define minTime 4500L * PRINTLINE_CACHE_SIZE +#else +#define minTime 45000L +#endif + while(timeleft < minTime && maxfirst != linesWritePos) + { + timeleft += lines[maxfirst].timeInTicks; + nextPlannerIndex(maxfirst); + } + // Search last fixed element + while(first != maxfirst && !lines[first].isEndSpeedFixed()) + previousPlannerIndex(first); + if(first != linesWritePos && lines[first].isEndSpeedFixed()) + nextPlannerIndex(first); + // now first points to last segment before the end speed is fixed + // so start speed is also fixed. + + if(first == linesWritePos) // Nothing to plan, only new element present + { + act->block(); // Prevent stepper interrupt from using this + noInts.unprotect(); + act->setStartSpeedFixed(true); + act->updateStepsParameter(); + act->unblock(); + return; + } + // now we have at least one additional move for optimization + // that is not a wait move + // First is now the new element or the first element with non fixed end speed. + // anyhow, the start speed of first is fixed + firstLine = &lines[first]; + firstLine->block(); // don't let printer touch this or following segments during update + noInts.unprotect(); + ufast8_t previousIndex = linesWritePos; + previousPlannerIndex(previousIndex); + PrintLine *previous = &lines[previousIndex]; // segment before the one we are inserting +#if DRIVE_SYSTEM != DELTA + // filters z-move<->not z-move +/* if((previous->primaryAxis == Z_AXIS && act->primaryAxis != Z_AXIS) || (previous->primaryAxis != Z_AXIS && act->primaryAxis == Z_AXIS)) + { + previous->setEndSpeedFixed(true); + act->setStartSpeedFixed(true); + act->updateStepsParameter(); + firstLine->unblock(); + return; + }*/ +#endif // DRIVE_SYSTEM + + if(previous->isEOnlyMove() != act->isEOnlyMove()) + { + previous->maxJunctionSpeed = act->startSpeed; + previous->setEndSpeedFixed(true); + act->setStartSpeedFixed(true); + act->updateStepsParameter(); + firstLine->unblock(); + return; + } + else + { + computeMaxJunctionSpeed(previous, act); // Set maximum junction speed if we have a real move before + } + // Increase speed if possible neglecting current speed + backwardPlanner(linesWritePos,first); + // Reduce speed to reachable speeds + forwardPlanner(first); + +#ifdef DEBUG_PLANNER + Com::printF(PSTR("Planner: "),(int)linesCount); + previousPlannerIndex(first); + Com::printF(PSTR(" F "),lines[first].startSpeed,1); + Com::printF(PSTR(" - "),lines[first].endSpeed,1); + Com::printF(PSTR("("),lines[first].maxJunctionSpeed,1); + Com::printF(PSTR(","),(int)lines[first].joinFlags); + nextPlannerIndex(first); +#endif + // Update precomputed data + do + { + lines[first].updateStepsParameter(); +#ifdef DEBUG_PLANNER + Com::printF(PSTR(" / "),lines[first].startSpeed,1); + Com::printF(PSTR(" - "),lines[first].endSpeed,1); + Com::printF(PSTR("("),lines[first].maxJunctionSpeed,1); + Com::printF(PSTR(","),(int)lines[first].joinFlags); +#ifdef DEBUG_QUEUE_MOVE + Com::println(); +#endif +#endif + //noInts.protect(); + lines[first].unblock(); // start with first block to release next used segment as early as possible + nextPlannerIndex(first); + lines[first].block(); + //noInts.unprotect(); + } + while(first != linesWritePos); + act->updateStepsParameter(); + act->unblock(); +#ifdef DEBUG_PLANNER + Com::printF(PSTR(" / "),lines[first].startSpeed,1); + Com::printF(PSTR(" - "),lines[first].endSpeed,1); + Com::printF(PSTR("("),lines[first].maxJunctionSpeed,1); + Com::printFLN(PSTR(","),(int)lines[first].joinFlags); +#endif +} + +/* Computes the maximum junction speed of the newly added segment under +optimal conditions. There is no guarantee that the previous move will be able to reach the +speed at all, but if it could exceed it will never exceed this theoretical limit. + +if you define ALTERNATIVE_JERK the new jerk computations are used. These +use the cosine of the angle and the maximum speed +Jerk = (1-cos(alpha))*min(v1,v2) +This sets jerk to 0 on zero angle change. + + Old New +0°: 0 0 +30°: 51,8 13.4 +45°: 76.53 29.3 +90°: 141 100 +180°: 200 200 + + +Speed from 100 to 200 + Old New(min) New(max) +0°: 100 0 0 +30°: 123,9 13.4 26.8 +45°: 147.3 29.3 58.6 +90°: 223 100 200 +180°: 300 200 400 + +*/ +inline void PrintLine::computeMaxJunctionSpeed(PrintLine *previous, PrintLine *current) +{ +#if NONLINEAR_SYSTEM + /* if (previous->moveID == current->moveID) // Avoid computing junction speed for split nonlinear lines + { + if(previous->fullSpeed > current->fullSpeed) + previous->maxJunctionSpeed = current->fullSpeed; + else + previous->maxJunctionSpeed = previous->fullSpeed; + return; + }*/ +#endif +#if USE_ADVANCE + if(Printer::isAdvanceActivated()) + { + // if we start/stop extrusion we need to do so with lowest possible end speed + // or advance would leave a drolling extruder and can not adjust fast enough. + if(previous->isEMove() != current->isEMove()) + { + previous->setEndSpeedFixed(true); + current->setStartSpeedFixed(true); + previous->endSpeed = current->startSpeed = previous->maxJunctionSpeed = RMath::min(previous->endSpeed, current->startSpeed); + previous->invalidateParameter(); + current->invalidateParameter(); + return; + } + } +#endif // USE_ADVANCE + // if we are here we have to identical move types + // either pure extrusion -> pure extrusion or + // move -> move (with or without extrusion) + // First we compute the normalized jerk for speed 1 + float factor = 1.0; + float lengthFactor = 1.0; +#ifdef REDUCE_ON_SMALL_SEGMENTS + if(previous->distance < MAX_JERK_DISTANCE) + lengthFactor = static_cast(MAX_JERK_DISTANCE*MAX_JERK_DISTANCE) / (previous->distance * previous->distance); +#endif + float maxJoinSpeed = RMath::min(current->fullSpeed,previous->fullSpeed); +#if (DRIVE_SYSTEM == DELTA) // No point computing Z Jerk separately for delta moves +#ifdef ALTERNATIVE_JERK + float jerk = maxJoinSpeed * lengthFactor * (1.0 - (current->speedX * previous->speedX + current->speedY * previous->speedY + current->speedZ * previous->speedZ) / (current->fullSpeed * previous->fullSpeed)); +#else + float dx = current->speedX - previous->speedX; + float dy = current->speedY - previous->speedY; + float dz = current->speedZ - previous->speedZ; + float jerk = sqrt(dx * dx + dy * dy + dz * dz) * lengthFactor; +#endif // ALTERNATIVE_JERK +#else // DELTA +#ifdef ALTERNATIVE_JERK + float jerk = maxJoinSpeed * lengthFactor * (1.0 - (current->speedX * previous->speedX + current->speedY * previous->speedY + current->speedZ * previous->speedZ) / (current->fullSpeed * previous->fullSpeed)); +#else + float dx = current->speedX - previous->speedX; + float dy = current->speedY - previous->speedY; + float jerk = sqrt(dx * dx + dy * dy) * lengthFactor; +#endif // ALTERNATIVE_JERK +#endif // DELTA + if(jerk > Printer::maxJerk) { + factor = Printer::maxJerk / jerk; // always < 1.0! + if(factor * maxJoinSpeed * 2.0 < Printer::maxJerk) + factor = Printer::maxJerk / (2.0 * maxJoinSpeed); + } +#if DRIVE_SYSTEM != DELTA + if((previous->dir | current->dir) & ZSTEP) + { + float dz = fabs(current->speedZ - previous->speedZ); + if(dz > Printer::maxZJerk) + factor = RMath::min(factor, Printer::maxZJerk / dz); + } +#endif + float eJerk = fabs(current->speedE - previous->speedE); + if(eJerk > Extruder::current->maxStartFeedrate) + factor = RMath::min(factor, Extruder::current->maxStartFeedrate / eJerk); + + previous->maxJunctionSpeed = maxJoinSpeed * factor; // set speed limit +#ifdef DEBUG_QUEUE_MOVE + if(Printer::debugEcho()) + { + Com::printF(PSTR("ID:"), (int)previous); + Com::printFLN(PSTR(" MJ:"), previous->maxJunctionSpeed); + } +#endif // DEBUG_QUEUE_MOVE +} + +/** Update parameter used by updateTrapezoids + +Computes the acceleration/deceleration steps and advanced parameter associated. +*/ +void PrintLine::updateStepsParameter() +{ + if(areParameterUpToDate() || isWarmUp()) return; + float startFactor = startSpeed * invFullSpeed; + float endFactor = endSpeed * invFullSpeed; + vStart = vMax * startFactor; //starting speed + vEnd = vMax * endFactor; +#if CPU_ARCH == ARCH_AVR + uint32_t vmax2 = HAL::U16SquaredToU32(vMax); + accelSteps = ((vmax2 - HAL::U16SquaredToU32(vStart)) / (accelerationPrim << 1)) + 1; // Always add 1 for missing precision + decelSteps = ((vmax2 - HAL::U16SquaredToU32(vEnd)) /(accelerationPrim << 1)) + 1; +#else + uint64_t vmax2 = static_cast(vMax) * static_cast(vMax); + accelSteps = ((vmax2 - static_cast(vStart) * static_cast(vStart)) / (accelerationPrim << 1)) + 1; // Always add 1 for missing precision + decelSteps = ((vmax2 - static_cast(vEnd) * static_cast(vEnd)) / (accelerationPrim << 1)) + 1; +#endif + +#if USE_ADVANCE +#if ENABLE_QUADRATIC_ADVANCE + advanceStart = (float)advanceFull * startFactor * startFactor; + advanceEnd = (float)advanceFull * endFactor * endFactor; +#endif +#endif + if(accelSteps + decelSteps >= stepsRemaining) // can't reach limit speed + { + uint16_t red = (accelSteps + decelSteps + 2 - stepsRemaining) >> 1; + accelSteps = accelSteps - RMath::min(accelSteps, red); + decelSteps = decelSteps - RMath::min(decelSteps, red); + } + setParameterUpToDate(); +#ifdef DEBUG_QUEUE_MOVE + if(Printer::debugEcho()) + { + Com::printFLN(Com::tDBGId,(int)this); + Com::printF(Com::tDBGVStartEnd,(long)vStart); + Com::printFLN(Com::tSlash,(long)vEnd); + Com::printF(Com::tDBAccelSteps,(long)accelSteps); + Com::printF(Com::tSlash,(long)decelSteps); + Com::printFLN(Com::tSlash,(long)stepsRemaining); + Com::printF(Com::tDBGStartEndSpeed,startSpeed,1); + Com::printFLN(Com::tSlash,endSpeed,1); + Com::printFLN(Com::tDBGFlags,(uint32_t)flags); + Com::printFLN(Com::tDBGJoinFlags,(uint32_t)joinFlags); + } +#endif +} + +/** +Compute the maximum speed from the last entered move. +The backwards planner traverses the moves from last to first looking at deceleration. The RHS of the accelerate/decelerate ramp. + +start = last line inserted +last = last element until we check +*/ +inline void PrintLine::backwardPlanner(ufast8_t start,ufast8_t last) +{ + PrintLine *act = &lines[start], *previous; + float lastJunctionSpeed = act->endSpeed; // Start always with safe speed + + //PREVIOUS_PLANNER_INDEX(last); // Last element is already fixed in start speed + while(start != last) + { + previousPlannerIndex(start); + previous = &lines[start]; + previous->block(); + // Avoid speed calculation once cruising in split delta move +#if NONLINEAR_SYSTEM + /*if (previous->moveID == act->moveID && lastJunctionSpeed == previous->maxJunctionSpeed) + { + act->startSpeed = RMath::max(act->minSpeed, previous->endSpeed = lastJunctionSpeed); + previous->invalidateParameter(); + act->invalidateParameter(); + }*/ +#endif + + /* if(prev->isEndSpeedFixed()) // Nothing to update from here on, happens when path optimize disabled + { + act->setStartSpeedFixed(true); + return; + }*/ + + // Avoid speed calculations if we know we can accelerate within the line + lastJunctionSpeed = (act->isNominalMove() ? act->fullSpeed : sqrt(lastJunctionSpeed * lastJunctionSpeed + act->accelerationDistance2)); // acceleration is acceleration*distance*2! What can be reached if we try? + // If that speed is more that the maximum junction speed allowed then ... + if(lastJunctionSpeed >= previous->maxJunctionSpeed) // Limit is reached + { + // If the previous line's end speed has not been updated to maximum speed then do it now + if(previous->endSpeed != previous->maxJunctionSpeed) + { + previous->invalidateParameter(); // Needs recomputation + previous->endSpeed = RMath::max(previous->minSpeed, previous->maxJunctionSpeed); // possibly unneeded??? + } + // If actual line start speed has not been updated to maximum speed then do it now + if(act->startSpeed != previous->maxJunctionSpeed) + { + act->startSpeed = RMath::max(act->minSpeed, previous->maxJunctionSpeed); // possibly unneeded??? + act->invalidateParameter(); + } + lastJunctionSpeed = previous->endSpeed; + } + else + { + // Block previous end and act start as calculated speed and recalculate plateau speeds (which could move the speed higher again) + act->startSpeed = RMath::max(act->minSpeed, lastJunctionSpeed); + lastJunctionSpeed = previous->endSpeed = RMath::max(lastJunctionSpeed, previous->minSpeed); + previous->invalidateParameter(); + act->invalidateParameter(); + } + act = previous; + } // while loop +} + +void PrintLine::forwardPlanner(ufast8_t first) +{ + PrintLine *act; + PrintLine *next = &lines[first]; + float vmaxRight; + float leftSpeed = next->startSpeed; + while(first != linesWritePos) // All except last segment, which has fixed end speed + { + act = next; + nextPlannerIndex(first); + next = &lines[first]; + /* if(act->isEndSpeedFixed()) + { + leftSpeed = act->endSpeed; + continue; // Nothing to do here + }*/ + // Avoid speed calculate once cruising in split delta move +#if NONLINEAR_SYSTEM +/* if (act->moveID == next->moveID && act->endSpeed == act->maxJunctionSpeed) + { + act->startSpeed = leftSpeed; + leftSpeed = act->endSpeed; + act->setEndSpeedFixed(true); + next->setStartSpeedFixed(true); + continue; + }*/ +#endif + // Avoid speed calculates if we know we can accelerate within the line. + vmaxRight = (act->isNominalMove() ? act->fullSpeed : sqrt(leftSpeed * leftSpeed + act->accelerationDistance2)); + if(vmaxRight > act->endSpeed) // Could be higher next run? + { + if(leftSpeed < act->minSpeed) + { + leftSpeed = act->minSpeed; + act->endSpeed = sqrt(leftSpeed * leftSpeed + act->accelerationDistance2); + } + act->startSpeed = leftSpeed; + next->startSpeed = leftSpeed = RMath::max(RMath::min(act->endSpeed, act->maxJunctionSpeed), next->minSpeed); + if(act->endSpeed == act->maxJunctionSpeed) // Full speed reached, don't compute again! + { + act->setEndSpeedFixed(true); + next->setStartSpeedFixed(true); + } + act->invalidateParameter(); + } + else // We can accelerate full speed without reaching limit, which is as fast as possible. Fix it! + { + act->fixStartAndEndSpeed(); + act->invalidateParameter(); + if(act->minSpeed > leftSpeed) + { + leftSpeed = act->minSpeed; + vmaxRight = sqrt(leftSpeed * leftSpeed + act->accelerationDistance2); + } + act->startSpeed = leftSpeed; + act->endSpeed = RMath::max(act->minSpeed,vmaxRight); + next->startSpeed = leftSpeed = RMath::max(RMath::min(act->endSpeed, act->maxJunctionSpeed), next->minSpeed); + next->setStartSpeedFixed(true); + } + } // While + next->startSpeed = RMath::max(next->minSpeed, leftSpeed); // This is the new segment, which is updated anyway, no extra flag needed. +} + + +inline float PrintLine::safeSpeed(fast8_t drivingAxis) +{ + float safe(Printer::maxJerk * 0.5); +#if DRIVE_SYSTEM != DELTA + if(isZMove()) + { + float mz = Printer::maxZJerk * 0.5; + if(isXOrYMove()) + { + if(fabs(speedZ) > mz) + safe = RMath::min(safe,mz * fullSpeed / fabs(speedZ)); + } + else + { + safe = mz; + } + } +#endif + if(isEMove()) + { + if(isXYZMove()) + safe = RMath::min(safe, 0.5 * Extruder::current->maxStartFeedrate * fullSpeed / fabs(speedE)); + else + safe = 0.5 * Extruder::current->maxStartFeedrate; // This is a retraction move + } + // Check for minimum speeds needed for numerical robustness + if(drivingAxis == X_AXIS || drivingAxis == Y_AXIS) // enforce minimum speed for numerical stability of explicit speed integration + safe = RMath::max(Printer::minimumSpeed, safe); + else if(drivingAxis == Z_AXIS) + { + safe = RMath::max(Printer::minimumZSpeed, safe); + } + return RMath::min(safe, fullSpeed); +} + + +/** Check if move is new. If it is insert some dummy moves to allow the path optimizer to work since it does +not act on the first two moves in the queue. The stepper timer will spot these moves and leave some time for +processing. +*/ +uint8_t PrintLine::insertWaitMovesIfNeeded(uint8_t pathOptimize, uint8_t waitExtraLines) +{ + if(linesCount == 0 && waitRelax == 0 && pathOptimize) // First line after some time - warm up needed + { + //return 0; +#if NONLINEAR_SYSTEM + uint8_t w = 3; +#else + uint8_t w = 4; +#endif + while(w--) + { + PrintLine *p = getNextWriteLine(); + p->flags = FLAG_WARMUP; + p->joinFlags = FLAG_JOIN_STEPPARAMS_COMPUTED | FLAG_JOIN_END_FIXED | FLAG_JOIN_START_FIXED; + p->dir = 0; + p->setWaitForXLinesFilled(w + waitExtraLines); +#if NONLINEAR_SYSTEM + p->setWaitTicks(300000); + p->moveID = lastMoveID++; +#else + p->setWaitTicks(100000); +#endif // NONLINEAR_SYSTEM + pushLine(); + } + //Com::printFLN(PSTR("InsertWait")); + return 1; + } + return 0; +} + +void PrintLine::logLine() +{ +#ifdef DEBUG_QUEUE_MOVE + Com::printFLN(Com::tDBGId,(int)this); + Com::printArrayFLN(Com::tDBGDelta,delta); + Com::printFLN(Com::tDBGDir,(uint32_t)dir); + Com::printFLN(Com::tDBGFlags,(uint32_t)flags); + Com::printFLN(Com::tDBGFullSpeed,fullSpeed); + Com::printFLN(Com::tDBGVMax,(int32_t)vMax); + Com::printFLN(Com::tDBGAcceleration,accelerationDistance2); + Com::printFLN(Com::tDBGAccelerationPrim,(int32_t)accelerationPrim); + Com::printFLN(Com::tDBGRemainingSteps,stepsRemaining); +#if USE_ADVANCE +#if ENABLE_QUADRATIC_ADVANCE + Com::printFLN(Com::tDBGAdvanceFull,advanceFull >> 16); + Com::printFLN(Com::tDBGAdvanceRate,advanceRate); +#endif +#endif +#endif // DEBUG_QUEUE_MOVE +} + +void PrintLine::waitForXFreeLines(uint8_t b, bool allowMoves) +{ + while(getLinesCount() + b > PRINTLINE_CACHE_SIZE) // wait for a free entry in movement cache + { + GCode::readFromSerial(); + Commands::checkForPeriodicalActions(allowMoves); + } +} + +#ifdef FAST_COREXYZ +uint8_t transformCartesianStepsToDeltaSteps(int32_t cartesianPosSteps[], int32_t corePosSteps[]) +{ + #if DRIVE_SYSTEM == XY_GANTRY + //1 = z axis + xy H-gantry (x_motor = x+y, y_motor = x-y) + corePosSteps[A_TOWER] = cartesianPosSteps[X_AXIS] + cartesianPosSteps[Y_AXIS]; + corePosSteps[B_TOWER] = cartesianPosSteps[X_AXIS] - cartesianPosSteps[Y_AXIS]; + corePosSteps[C_TOWER] = cartesianPosSteps[Z_AXIS]; + #elif DRIVE_SYSTEM == YX_GANTRY + // 2 = z axis + xy H-gantry (x_motor = x+y, y_motor = y-x) + corePosSteps[A_TOWER] = cartesianPosSteps[X_AXIS] + cartesianPosSteps[Y_AXIS]; + corePosSteps[B_TOWER] = cartesianPosSteps[Y_AXIS] - cartesianPosSteps[X_AXIS]; + corePosSteps[C_TOWER] = cartesianPosSteps[Z_AXIS]; + #elif DRIVE_SYSTEM == XZ_GANTRY + // 8 = y axis + xz H-gantry (x_motor = x+z, z_motor = x-z) + corePosSteps[A_TOWER] = cartesianPosSteps[X_AXIS] + cartesianPosSteps[Z_AXIS]; + corePosSteps[C_TOWER] = cartesianPosSteps[X_AXIS] - cartesianPosSteps[Z_AXIS]; + corePosSteps[B_TOWER] = cartesianPosSteps[Y_AXIS]; + #elif DRIVE_SYSTEM == ZX_GANTRY + //9 = y axis + xz H-gantry (x_motor = x+z, z_motor = z-x) + corePosSteps[A_TOWER] = cartesianPosSteps[X_AXIS] + cartesianPosSteps[Z_AXIS]; + corePosSteps[C_TOWER] = cartesianPosSteps[Z_AXIS] - cartesianPosSteps[X_AXIS]; + corePosSteps[B_TOWER] = cartesianPosSteps[Y_AXIS]; + #elif DRIVE_SYSTEM == GANTRY_FAKE + corePosSteps[A_TOWER] = cartesianPosSteps[X_AXIS]; + corePosSteps[B_TOWER] = cartesianPosSteps[Y_AXIS]; + corePosSteps[C_TOWER] = cartesianPosSteps[Z_AXIS]; + #endif + return 1; +} +#endif + +#if DRIVE_SYSTEM == DELTA +// pick one for verbose the other silent +#define RETURN_0(s) { Com::printErrorFLN(PSTR(s)); return 0; } +/*#define RETURN_0(s) { Com::print(s " "); SHOWS(temp); SHOWS(opt);\ + SHOWS(cartesianPosSteps[Z_AXIS]);\ + SHOWS(towerAMinSteps); ;\ + SHOWS(deltaPosSteps[A_TOWER]); \ + SHOWS(Printer::deltaAPosYSteps);\ + SHOWS(cartesianPosSteps[Y_AXIS]); \ + SHOW(Printer::deltaDiagonalStepsSquaredA.l); return 0; } + */ +/** + Calculate the delta tower position from a Cartesian position + @param cartesianPosSteps Array containing Cartesian coordinates. + @param deltaPosSteps Result array with tower coordinates. + @returns 1 if Cartesian coordinates have a valid delta tower position 0 if not. +*/ +uint8_t transformCartesianStepsToDeltaSteps(int32_t cartesianPosSteps[], int32_t deltaPosSteps[]) +{ + int32_t zSteps = cartesianPosSteps[Z_AXIS]; +#if DISTORTION_CORRECTION + static int cnt = 0; + static int32_t lastZSteps = 9999999; + static int32_t lastZCorrection = 0; + cnt++; + if(cnt >= DISTORTION_UPDATE_FREQUENCY || lastZSteps != zSteps) + { + cnt = 0; + lastZSteps = zSteps; + lastZCorrection = Printer::distortion.correct(cartesianPosSteps[X_AXIS], cartesianPosSteps[Y_AXIS], cartesianPosSteps[Z_AXIS]); + } + zSteps += lastZCorrection; +#endif + if(Printer::isLargeMachine()) + { +#ifdef SUPPORT_64_BIT_MATH + // 64 bit is better for precision, so we use that if available. + // A TOWER height + uint64_t temp = RMath::absLong(Printer::deltaAPosYSteps - cartesianPosSteps[Y_AXIS]); + uint64_t opt = Printer::deltaDiagonalStepsSquaredA.L; + + temp *= temp; + if (opt < temp) + RETURN_0("Apos y square "); + opt -= temp; + + temp = RMath::absLong(Printer::deltaAPosXSteps - cartesianPosSteps[X_AXIS]); + temp *= temp; + if (opt < temp) + RETURN_0("Apos x square "); + + deltaPosSteps[A_TOWER] = HAL::integer64Sqrt(opt - temp) + zSteps; + if (deltaPosSteps[A_TOWER] < Printer::deltaFloorSafetyMarginSteps && !Printer::isZProbingActive()) + RETURN_0("A hit floor"); + + // B TOWER height + temp = RMath::absLong(Printer::deltaBPosYSteps - cartesianPosSteps[Y_AXIS]); + opt = Printer::deltaDiagonalStepsSquaredB.L; + temp *= temp; + if (opt < temp) + RETURN_0("Bpos y square "); + opt -= temp; + + temp = RMath::absLong(Printer::deltaBPosXSteps - cartesianPosSteps[X_AXIS]); + temp *= temp; + if (opt < temp) + RETURN_0("Bpos x square "); + + deltaPosSteps[B_TOWER] = HAL::integer64Sqrt(opt - temp) + zSteps ; + if (deltaPosSteps[B_TOWER] < Printer::deltaFloorSafetyMarginSteps && !Printer::isZProbingActive()) + RETURN_0("B hit floor"); + + // C TOWER height + temp = RMath::absLong(Printer::deltaCPosYSteps - cartesianPosSteps[Y_AXIS]); + opt = Printer::deltaDiagonalStepsSquaredC.L ; + + temp = temp * temp; + if ( opt < temp ) + RETURN_0("Cpos y square "); + opt -= temp; + + temp = RMath::absLong(Printer::deltaCPosXSteps - cartesianPosSteps[X_AXIS]); + temp = temp * temp; + if ( opt < temp ) + RETURN_0("Cpos x square "); + + deltaPosSteps[C_TOWER] = HAL::integer64Sqrt(opt - temp) + zSteps; + if (deltaPosSteps[C_TOWER] < Printer::deltaFloorSafetyMarginSteps && !Printer::isZProbingActive()) + RETURN_0("C hit floor"); +#else + float temp = Printer::deltaAPosYSteps - cartesianPosSteps[Y_AXIS]; + float opt = Printer::deltaDiagonalStepsSquaredA.f - temp * temp; + float temp2 = Printer::deltaAPosXSteps - cartesianPosSteps[X_AXIS]; + if ((temp = opt - temp2 * temp2) >= 0) + deltaPosSteps[A_TOWER] = floor(0.5 + sqrt(temp) + + zSteps); + else + return 0; + if (deltaPosSteps[A_TOWER] < Printer::deltaFloorSafetyMarginSteps && !Printer::isZProbingActive()) return 0; + + temp = Printer::deltaBPosYSteps - cartesianPosSteps[Y_AXIS]; + opt = Printer::deltaDiagonalStepsSquaredB.f - temp * temp; + temp2 = Printer::deltaBPosXSteps - cartesianPosSteps[X_AXIS]; + if ((temp = opt - temp2 * temp2) >= 0) + deltaPosSteps[B_TOWER] = floor(0.5 + sqrt(temp) + + zSteps); + else + return 0; + if (deltaPosSteps[B_TOWER] < Printer::deltaFloorSafetyMarginSteps && !Printer::isZProbingActive()) return 0; + + temp = Printer::deltaCPosYSteps - cartesianPosSteps[Y_AXIS]; + opt = Printer::deltaDiagonalStepsSquaredC.f - temp * temp; + temp2 = Printer::deltaCPosXSteps - cartesianPosSteps[X_AXIS]; + if ((temp = opt - temp2*temp2) >= 0) + deltaPosSteps[C_TOWER] = floor(0.5 + sqrt(temp) + + zSteps); + else + return 0; + if (deltaPosSteps[C_TOWER] < Printer::deltaFloorSafetyMarginSteps && !Printer::isZProbingActive()) return 0; + + return 1; +#endif + } + else + { + // As we are right on the edge of many printers arm lengths, this is rewrittent to use unsigned long + // This allows 52% longer arms to be used without performance penalty + // the code is a bit longer, because we cannot use negative to test for invalid conditions + // Also, previous code did not check for overflow of squared result + // Overflow is also detected as a fault condition + + const uint32_t LIMIT = 65534; // Largest squarable int without overflow; + + // A TOWER height + uint32_t temp = RMath::absLong(Printer::deltaAPosYSteps - cartesianPosSteps[Y_AXIS]); + uint32_t opt = Printer::deltaDiagonalStepsSquaredA.l; + + if (temp > LIMIT) + RETURN_0("Apos y steps "); + temp *= temp; + if (opt < temp) + RETURN_0("Apos y square "); + opt -= temp; + + temp = RMath::absLong(Printer::deltaAPosXSteps - cartesianPosSteps[X_AXIS]); + if (temp > LIMIT) + RETURN_0("Apos x steps "); + temp *= temp; + if (opt < temp) + RETURN_0("Apos x square "); + + deltaPosSteps[A_TOWER] = SQRT(opt-temp) + zSteps; + if (deltaPosSteps[A_TOWER] < Printer::deltaFloorSafetyMarginSteps && !Printer::isZProbingActive()) + RETURN_0("A hit floor"); + + // B TOWER height + temp = RMath::absLong(Printer::deltaBPosYSteps - cartesianPosSteps[Y_AXIS]); + opt = Printer::deltaDiagonalStepsSquaredB.l; + + if (temp > LIMIT) + RETURN_0("Bpos y steps "); + temp *= temp; + if (opt < temp) + RETURN_0("Bpos y square "); + opt -= temp; + + temp = RMath::absLong(Printer::deltaBPosXSteps - cartesianPosSteps[X_AXIS]); + if (temp > LIMIT ) + RETURN_0("Bpos x steps "); + temp *= temp; + if (opt < temp) + RETURN_0("Bpos x square "); + + deltaPosSteps[B_TOWER] = SQRT(opt-temp) + zSteps ; + if (deltaPosSteps[B_TOWER] < Printer::deltaFloorSafetyMarginSteps && !Printer::isZProbingActive()) + RETURN_0("B hit floor"); + + // C TOWER height + temp = RMath::absLong(Printer::deltaCPosYSteps - cartesianPosSteps[Y_AXIS]); + opt = Printer::deltaDiagonalStepsSquaredC.l ; + + if (temp > LIMIT) + RETURN_0("Cpos y steps "); + temp = temp * temp; + if ( opt < temp ) + RETURN_0("Cpos y square "); + opt -= temp; + + temp = RMath::absLong(Printer::deltaCPosXSteps - cartesianPosSteps[X_AXIS]); + if (temp > LIMIT) + RETURN_0("Cpos x steps "); + temp = temp * temp; + if ( opt < temp ) + RETURN_0("Cpos x square "); + + deltaPosSteps[C_TOWER] = SQRT(opt - temp) + zSteps; + if (deltaPosSteps[C_TOWER] < Printer::deltaFloorSafetyMarginSteps && !Printer::isZProbingActive()) + RETURN_0("C hit floor"); + /* + long temp = Printer::deltaAPosYSteps - cartesianPosSteps[Y_AXIS]; + long opt = Printer::deltaDiagonalStepsSquaredA.l - temp * temp; + long temp2 = Printer::deltaAPosXSteps - cartesianPosSteps[X_AXIS]; + if ((temp = opt - temp2 * temp2) >= 0) + #ifdef FAST_INTEGER_SQRT + deltaPosSteps[A_TOWER] = HAL::integerSqrt(temp) + cartesianPosSteps[Z_AXIS]; + #else + deltaPosSteps[A_TOWER] = sqrt(temp) + cartesianPosSteps[Z_AXIS]; + #endif + else + return 0; + + temp = Printer::deltaBPosYSteps - cartesianPosSteps[Y_AXIS]; + opt = Printer::deltaDiagonalStepsSquaredB.l - temp * temp; + temp2 = Printer::deltaBPosXSteps - cartesianPosSteps[X_AXIS]; + if ((temp = opt - temp2*temp2) >= 0) + #ifdef FAST_INTEGER_SQRT + deltaPosSteps[B_TOWER] = HAL::integerSqrt(temp) + cartesianPosSteps[Z_AXIS]; + #else + deltaPosSteps[B_TOWER] = sqrt(temp) + cartesianPosSteps[Z_AXIS]; + #endif + else + return 0; + + temp = Printer::deltaCPosYSteps - cartesianPosSteps[Y_AXIS]; + opt = Printer::deltaDiagonalStepsSquaredC.l - temp * temp; + temp2 = Printer::deltaCPosXSteps - cartesianPosSteps[X_AXIS]; + if ((temp = opt - temp2*temp2) >= 0) + #ifdef FAST_INTEGER_SQRT + deltaPosSteps[C_TOWER] = HAL::integerSqrt(temp) + cartesianPosSteps[Z_AXIS]; + #else + deltaPosSteps[C_TOWER] = sqrt(temp) + cartesianPosSteps[Z_AXIS]; + #endif + else + return 0;*/ + } + return 1; +} +#endif + +#if DRIVE_SYSTEM==TUGA + +/** + Calculate the delta tower position from a Cartesian position + @param cartesianPosSteps Array containing Cartesian coordinates. + @param deltaPosSteps Result array with tower coordinates. + @returns 1 if Cartesian coordinates have a valid delta tower position 0 if not. + + X Y + * * + \ / + \ / + \ / + \/ + / + / + / + / + * Extruder + + +*/ +uint8_t transformCartesianStepsToDeltaSteps(int32_t cartesianPosSteps[], int32_t tugaPosSteps[]) +{ + tugaPosSteps[0] = cartesianPosSteps[0]; + tugaPosSteps[2] = cartesianPosSteps[2]; + int32_t y2 = Printer::deltaBPosXSteps-cartesianPosSteps[1]; + if(Printer::isLargeMachine()) + { + float y2f = (float)y2 * (float)y2; + float temp = Printer::deltaDiagonalStepsSquaredF - y2f; + if(temp < 0) return 0; + tugaPosSteps[1] = tugaPosSteps[0] + sqrt(temp); + } + else + { + y2 = y2*y2; + int32_t temp = Printer::deltaDiagonalStepsSquared - y2; + if(temp < 0) return 0; + tugaPosSteps[1] = tugaPosSteps[0] + HAL::integerSqrt(temp); + } + return 1; +} +#endif + + +#if NONLINEAR_SYSTEM + +bool NonlinearSegment::checkEndstops(PrintLine *cur, bool checkall) +{ + fast8_t r = 0; + if(Printer::isZProbingActive()) + { + Endstops::update(); +#if FEATURE_Z_PROBE + if(isZNegativeMove() && Endstops::zProbe()) + { +#if DRIVE_SYSTEM == DELTA + cur->setXMoveFinished(); + cur->setYMoveFinished(); +#endif + cur->setZMoveFinished(); + //dir = 0; + Printer::stepsRemainingAtZHit = cur->stepsRemaining; + cur->stepsRemaining = 0; + return true; + } +#endif +#if DRIVE_SYSTEM == DELTA + if(isZPositiveMove() && isXPositiveMove() && isYPositiveMove() && Endstops::anyXYZMax()) +#else + if(isZPositiveMove() && Endstops::zMax()) +#endif + { +#if DRIVE_SYSTEM == DELTA + cur->setXMoveFinished(); + cur->setYMoveFinished(); +#endif + cur->setZMoveFinished(); + //dir = 0; + Printer::stepsRemainingAtZHit = cur->stepsRemaining; + return true; + } + } else if(checkall) { + Endstops::update(); // do not test twice + if(!Endstops::anyXYZ()) // very quick check for the normal case + return false; + } + if(checkall) + { +#if GANTRY + // Test axis endstops based on global direction + if(cur->isXPositiveMove() && Endstops::xMax()) + { + setXMoveFinished(); + cur->setXMoveFinished(); + r = 1; + } + if(cur->isYPositiveMove() && Endstops::yMax()) + { + setYMoveFinished(); + cur->setYMoveFinished(); + r = 1; + } + if(cur->isXNegativeMove() && Endstops::xMin()) + { + setXMoveFinished(); + cur->setXMoveFinished(); + r = 1; + } + if(cur->isYNegativeMove() && Endstops::yMin()) + { + setYMoveFinished(); + cur->setYMoveFinished(); + r = 1; + } + if(cur->isZPositiveMove() && Endstops::zMax()) + { + setZMoveFinished(); + cur->setZMoveFinished(); + r = 1; + } + if(cur->isZNegativeMove() && Endstops::zMin()) + { + setZMoveFinished(); + cur->setZMoveFinished(); + r = 1; + } +#else + // endstops are per motor and do not depend on global axis movement + if(isXPositiveMove() && Endstops::xMax()) + { +#if DRIVE_SYSTEM == DELTA + if(Printer::stepsRemainingAtXHit < 0) + Printer::stepsRemainingAtXHit = cur->stepsRemaining; +#endif + setXMoveFinished(); + cur->setXMoveFinished(); + r++; + } + if(isYPositiveMove() && Endstops::yMax()) + { +#if DRIVE_SYSTEM == DELTA + if(Printer::stepsRemainingAtYHit < 0) + Printer::stepsRemainingAtYHit = cur->stepsRemaining; +#endif + setYMoveFinished(); + cur->setYMoveFinished(); + r++; + } +#if DRIVE_SYSTEM != DELTA + if(isXNegativeMove() && Endstops::xMin()) + { + setXMoveFinished(); + cur->setXMoveFinished(); + r++; + } + if(isYNegativeMove() && Endstops::yMin()) + { + setYMoveFinished(); + cur->setYMoveFinished(); + r++; + } +#endif + if(isZPositiveMove() && Endstops::zMax()) + { +#if MAX_HARDWARE_ENDSTOP_Z + if(Printer::stepsRemainingAtZHit) + Printer::stepsRemainingAtZHit = cur->stepsRemaining; +#endif + setZMoveFinished(); + cur->setZMoveFinished(); + r++; + } + if(isZNegativeMove() && Endstops::zMin()) + { + setZMoveFinished(); + cur->setZMoveFinished(); + r++; + } +#if DRIVE_SYSTEM == DELTA + if(Printer::isHoming()) + return r == 3; +#endif +#endif // Not gantry + } + return r != 0; +} + +void PrintLine::calculateDirectionAndDelta(int32_t difference[], ufast8_t *dir, int32_t delta[]) +{ + *dir = 0; + //Find direction + if(difference[X_AXIS] != 0) { + if(difference[X_AXIS] < 0) { + delta[X_AXIS] = -difference[X_AXIS]; + *dir |= XSTEP; + } else { + delta[X_AXIS] = difference[X_AXIS]; + *dir |= X_DIRPOS + XSTEP; + } + } else { + delta[X_AXIS] = 0; + } + + if(difference[Y_AXIS] != 0) { + if(difference[Y_AXIS] < 0) { + delta[Y_AXIS] = -difference[Y_AXIS]; + *dir |= YSTEP; + } else { + delta[Y_AXIS] = difference[Y_AXIS]; + *dir |= Y_DIRPOS + YSTEP; + } + } else { + delta[Y_AXIS] = 0; + } + if(difference[Z_AXIS] != 0) { + if(difference[Z_AXIS] < 0) { + delta[Z_AXIS] = -difference[Z_AXIS]; + *dir |= ZSTEP; + } else { + delta[Z_AXIS] = difference[Z_AXIS]; + *dir |= Z_DIRPOS + ZSTEP; + } + } else { + delta[Z_AXIS] = 0; + } + if(difference[E_AXIS] != 0) { + if(difference[E_AXIS] < 0) { + delta[E_AXIS] = -difference[E_AXIS]; + *dir |= ESTEP; + } else { + delta[E_AXIS] = difference[E_AXIS]; + *dir |= E_DIRPOS + ESTEP; + } + } else { + delta[E_AXIS] = 0; + } +} +/** + Calculate and cache the delta robot positions of the Cartesian move in a line. + @return The largest delta axis move in a single segment + @param p The line to examine. +*/ +inline uint16_t PrintLine::calculateNonlinearSubSegments(uint8_t softEndstop) +{ + fast8_t i; + int32_t delta,diff; + int32_t destinationSteps[Z_AXIS_ARRAY], destinationDeltaSteps[TOWER_ARRAY]; + // Save current position +#if (CPU_ARCH == ARCH_AVR) && !EXACT_DELTA_MOVES + for(uint8_t i = 0; i < Z_AXIS_ARRAY; i++) + destinationSteps[i] = Printer::currentPositionSteps[i]; +#else + float dx[Z_AXIS_ARRAY]; + for(int i = 0; i < Z_AXIS_ARRAY; i++) + dx[i] = static_cast(Printer::destinationSteps[i] - Printer::currentPositionSteps[i]) / static_cast(numNonlinearSegments); +#endif +// out.println_byte_P(PSTR("Calculate delta segments:"), p->numDeltaSegments); +#ifdef DEBUG_STEPCOUNT + totalStepsRemaining = 0; +#endif + + uint16_t maxAxisSteps = 0; + for (int s = numNonlinearSegments; s > 0; s--) + { + NonlinearSegment *d = &segments[s - 1]; + +#if (CPU_ARCH == ARCH_AVR) && !EXACT_DELTA_MOVES + for(i = 0; i < Z_AXIS_ARRAY; i++) + { + // End of segment in Cartesian steps + + // This method generates small waves which get larger with increasing number of delta segments. smaller? + diff = Printer::destinationSteps[i] - destinationSteps[i]; + if(s == 1) + destinationSteps[i] += diff; + else if(s == 2) + destinationSteps[i] += (diff >> 1); + else if(s == 4) + destinationSteps[i] += (diff >> 2); + else if(diff < 0) + destinationSteps[i] -= HAL::Div4U2U(-diff, s); + else + destinationSteps[i] += HAL::Div4U2U(diff, s); + } +#else + float segment = static_cast(numNonlinearSegments - s + 1); + for(i = 0; i < Z_AXIS_ARRAY; i++) // End of segment in Cartesian steps + // Perfect approximation, but slower, so we limit it to faster processors like arm + destinationSteps[i] = static_cast(floor(0.5 + dx[i] * segment)) + Printer::currentPositionSteps[i]; +#endif + // Verify that delta calculation has a solution + if (transformCartesianStepsToDeltaSteps(destinationSteps, destinationDeltaSteps)) + { + d->dir = 0; +#if DRIVE_SYSTEM == DELTA + if (softEndstop) + { + destinationDeltaSteps[A_TOWER] = RMath::min(destinationDeltaSteps[A_TOWER], Printer::maxDeltaPositionSteps); + destinationDeltaSteps[B_TOWER] = RMath::min(destinationDeltaSteps[B_TOWER], Printer::maxDeltaPositionSteps); + destinationDeltaSteps[C_TOWER] = RMath::min(destinationDeltaSteps[C_TOWER], Printer::maxDeltaPositionSteps); + } +#endif + for(i = 0; i < TOWER_ARRAY; i++) + { + delta = destinationDeltaSteps[i] - Printer::currentNonlinearPositionSteps[i]; + if (delta > 0) + { + d->setPositiveMoveOfAxis(i); +#ifdef DEBUG_DELTA_OVERFLOW + if (delta > 65535) + Com::printFLN(Com::tDBGDeltaOverflow, delta); +#endif + d->deltaSteps[i] = static_cast(delta); + } + else + { + d->setMoveOfAxis(i); +#ifdef DEBUG_DELTA_OVERFLOW + if (-delta > 65535) + Com::printFLN(Com::tDBGDeltaOverflow, delta); +#endif + d->deltaSteps[i] = static_cast(-delta); + } +#ifdef DEBUG_STEPCOUNT + totalStepsRemaining += d->deltaSteps[i]; +#endif + if(d->deltaSteps[i] > maxAxisSteps) + maxAxisSteps = d->deltaSteps[i]; + Printer::currentNonlinearPositionSteps[i] = destinationDeltaSteps[i]; + } + } + else + { + // Illegal position - ignore move + Com::printWarningF(Com::tInvalidDeltaCoordinate); + Com::printF(PSTR(" x:"), destinationSteps[X_AXIS]); + Com::printF(PSTR(" y:"), destinationSteps[Y_AXIS]); + Com::printFLN(PSTR(" z:"), destinationSteps[Z_AXIS]); + d->dir = 0; + d->deltaSteps[A_TOWER] = d->deltaSteps[B_TOWER] = d->deltaSteps[C_TOWER] = 0; + return 65535; // flag error + } + } +#ifdef DEBUG_STEPCOUNT +// out.println_long_P(PSTR("initial StepsRemaining:"), p->totalStepsRemaining); +#endif + return maxAxisSteps; +} + +uint8_t PrintLine::calculateDistance(float axisDistanceMM[], uint8_t dir, float *distance) +{ + // Calculate distance depending on direction + if(dir & XYZ_STEP) + { + if(dir & XSTEP) + *distance = axisDistanceMM[X_AXIS] * axisDistanceMM[X_AXIS]; + else + *distance = 0; + if(dir & YSTEP) + *distance += axisDistanceMM[Y_AXIS] * axisDistanceMM[Y_AXIS]; + if(dir & ZSTEP) + *distance += axisDistanceMM[Z_AXIS] * axisDistanceMM[Z_AXIS]; + *distance = RMath::max((float)sqrt(*distance), axisDistanceMM[E_AXIS]); + return 1; + } + else + { + if(dir & ESTEP) + { + *distance = axisDistanceMM[E_AXIS]; + return 1; + } + *distance = 0; + return 0; + } +} + +#if SOFTWARE_LEVELING +void PrintLine::calculatePlane(int32_t factors[], int32_t p1[], int32_t p2[], int32_t p3[]) +{ + factors[0] = p1[1] * (p2[2] - p3[2]) + p2[1] * (p3[2] - p1[2]) + p3[1] * (p1[2] - p2[2]); + factors[1] = p1[2] * (p2[0] - p3[0]) + p2[2] * (p3[0] - p1[0]) + p3[2] * (p1[0] - p2[0]); + factors[2] = p1[0] * (p2[1] - p3[1]) + p2[0] * (p3[1] - p1[1]) + p3[0] * (p1[1] - p2[1]); + factors[3] = p1[0] * ((p2[1] * p3[2]) - (p3[1] * p2[2])) + p2[0] * ((p3[1] * p1[2]) - (p1[1] * p3[2])) + p3[0] * ((p1[1] * p2[2]) - (p2[1] * p1[2])); +} + +float PrintLine::calcZOffset(int32_t factors[], int32_t pointX, int32_t pointY) +{ + return (factors[3] - factors[X_AXIS] * pointX - factors[Y_AXIS] * pointY) / (float) factors[2]; +} +#endif + +inline void PrintLine::queueEMove(int32_t extrudeDiff,uint8_t check_endstops,uint8_t pathOptimize) +{ + Printer::unsetAllSteppersDisabled(); + waitForXFreeLines(1); + uint8_t newPath = insertWaitMovesIfNeeded(pathOptimize, 1); + PrintLine *p = getNextWriteLine(); + float axisDistanceMM[VIRTUAL_AXIS_ARRAY]; // Axis movement in mm + if(check_endstops) p->flags = FLAG_CHECK_ENDSTOPS; + else p->flags = 0; +#if MIXING_EXTRUDER + if(Printer::isAllEMotors()) { + p->flags |= FLAG_ALL_E_MOTORS; + } +#endif + p->joinFlags = 0; + if(!pathOptimize) p->setEndSpeedFixed(true); + //Find direction + for(uint8_t i = 0; i < Z_AXIS_ARRAY; i++) + { + p->delta[i] = 0; + axisDistanceMM[i] = 0; + } + if (extrudeDiff >= 0) + { + p->delta[E_AXIS] = extrudeDiff; + p->dir = E_STEP_DIRPOS; + } + else + { + p->delta[E_AXIS] = -extrudeDiff; + p->dir = ESTEP; + } + Printer::currentPositionSteps[E_AXIS] = Printer::destinationSteps[E_AXIS]; + + p->numNonlinearSegments = 0; + //Define variables that are needed for the Bresenham algorithm. Please note that Z is not currently included in the Bresenham algorithm. + p->primaryAxis = E_AXIS; + p->stepsRemaining = p->delta[E_AXIS]; + axisDistanceMM[E_AXIS] = p->distance = p->delta[E_AXIS] * Printer::invAxisStepsPerMM[E_AXIS]; + axisDistanceMM[VIRTUAL_AXIS] = -p->distance; + p->moveID = lastMoveID++; + p->calculateMove(axisDistanceMM,pathOptimize,E_AXIS); +} + +/** + Split a line up into a series of lines with at most DELTASEGMENTS_PER_PRINTLINE delta segments. + @param check_endstops Check endstops during the move. + @param pathOptimize Run the path optimizer. + @param delta_step_rate delta step rate in segments per second for the move. +*/ +uint8_t PrintLine::queueNonlinearMove(uint8_t check_endstops,uint8_t pathOptimize, uint8_t softEndstop) +{ + //if (softEndstop && Printer::destinationSteps[Z_AXIS] < 0) Printer::destinationSteps[Z_AXIS] = 0; // now constrained at entry level including cylinder test + EVENT_CONTRAIN_DESTINATION_COORDINATES + int32_t difference[E_AXIS_ARRAY]; + float axisDistanceMM[VIRTUAL_AXIS_ARRAY]; // Real cartesian axis movement in mm. Virtual axis in 4; + uint8_t secondSpeed = Printer::fanSpeed; + for(fast8_t axis = 0; axis < E_AXIS_ARRAY; axis++) + { + difference[axis] = Printer::destinationSteps[axis] - Printer::currentPositionSteps[axis]; + if(axis == E_AXIS) + { + if(Printer::mode == PRINTER_MODE_FFF) + { + Printer::extrudeMultiplyError += (static_cast(difference[E_AXIS]) * Printer::extrusionFactor); + difference[E_AXIS] = static_cast(Printer::extrudeMultiplyError); + Printer::extrudeMultiplyError -= difference[E_AXIS]; + axisDistanceMM[E_AXIS] = difference[E_AXIS] * Printer::invAxisStepsPerMM[E_AXIS]; + Printer::filamentPrinted += axisDistanceMM[E_AXIS]; + axisDistanceMM[E_AXIS] = fabs(axisDistanceMM[E_AXIS]); + } +#if defined(SUPPORT_LASER) && SUPPORT_LASER + else if(Printer::mode == PRINTER_MODE_LASER) + { + secondSpeed = ((axisDistanceMM[X_AXIS] != 0 || axisDistanceMM[Y_AXIS] != 0) && (LaserDriver::laserOn || axisDistanceMM[E_AXIS] != 0) ? LaserDriver::intensity : 0); + axisDistanceMM[E_AXIS] = 0; + } +#endif + } + else + axisDistanceMM[axis] = fabs(difference[axis] * Printer::invAxisStepsPerMM[axis]); + } + + float cartesianDistance; + ufast8_t cartesianDir; + int32_t cartesianDeltaSteps[E_AXIS_ARRAY]; + calculateDirectionAndDelta(difference, &cartesianDir, cartesianDeltaSteps); + if (!calculateDistance(axisDistanceMM, cartesianDir, &cartesianDistance)) + { + // Appears the intent is to do nothing if no distance is detected. + // This apparently is not an error condition, just early exit. + return true; + } + + if (!(cartesianDir & XYZ_STEP)) + { + queueEMove(difference[E_AXIS], check_endstops,pathOptimize); + return true; + } + + int16_t segmentCount; +#if DRIVE_SYSTEM == DELTA + float feedrate = RMath::min(Printer::feedrate, Printer::maxFeedrate[Z_AXIS]); +#else + float feedrate = Printer::feedrate; // each motor has own max. feedrate here resulting in total feedrate +#endif + if (cartesianDir & XY_STEP) + { + // Compute number of seconds for move and hence number of segments needed + //float seconds = 100 * cartesianDistance / (Printer::feedrate * Printer::feedrateMultiply); multiply in feedrate included + float seconds = cartesianDistance / feedrate; +#ifdef DEBUG_SPLIT + Com::printFLN(Com::tDBGDeltaSeconds, seconds); +#endif + float sps = static_cast((cartesianDir & ESTEP) == ESTEP ? Printer::printMovesPerSecond : Printer::travelMovesPerSecond); + segmentCount = RMath::max(1, static_cast(sps * seconds)); +#ifdef DEBUG_SEGMENT_LENGTH + float segDist = cartesianDistance/(float)segmentCount; + if(segDist > Printer::maxRealSegmentLength) + { + Printer::maxRealSegmentLength = segDist; + Com::printFLN(PSTR("SegmentsPerSecond:"),sps); + Com::printFLN(PSTR("New max. segment length:"),segDist); + } +#endif + //Com::printFLN(PSTR("Segments:"),segmentCount); + } + else + { + // Optimize pure Z axis move. Since a pure Z axis move is linear all we have to watch out for is unsigned integer overruns in + // the queued moves; +#ifdef DEBUG_SPLIT + Com::printFLN(Com::tDBGDeltaZDelta, cartesianDeltaSteps[Z_AXIS]); +#endif + segmentCount = (cartesianDeltaSteps[Z_AXIS] + (uint32_t)43680) / (uint32_t)43679; // can not go to 65535 for rounding issues causing overflow later in some cases! + } + // Now compute the number of lines needed + int numLines = (segmentCount + DELTASEGMENTS_PER_PRINTLINE - 1) / DELTASEGMENTS_PER_PRINTLINE; + // There could be some error here but it doesn't matter since the number of segments will just be reduced slightly + int segmentsPerLine = segmentCount / numLines; + + int32_t startPosition[E_AXIS_ARRAY], fractionalSteps[E_AXIS_ARRAY]; + if(numLines > 1) + { + for (fast8_t i = 0; i < Z_AXIS_ARRAY; i++) + startPosition[i] = Printer::currentPositionSteps[i]; + startPosition[E_AXIS] = 0; + cartesianDistance /= static_cast(numLines); + } + +#ifdef DEBUG_SPLIT + Com::printFLN(Com::tDBGDeltaSegments, segmentCount); + Com::printFLN(Com::tDBGDeltaNumLines, numLines); + Com::printFLN(Com::tDBGDeltaSegmentsPerLine, segmentsPerLine); +#endif + Printer::unsetAllSteppersDisabled(); // Motor is enabled now + waitForXFreeLines(1); + + // Insert dummy moves if necessary + // Need to leave at least one slot open for the first split move + insertWaitMovesIfNeeded(pathOptimize, RMath::min(PRINTLINE_CACHE_SIZE - 4, numLines)); + uint32_t oldEDestination = Printer::destinationSteps[E_AXIS]; // flow and volumetric extrusion changed virtual target + Printer::currentPositionSteps[E_AXIS] = 0; + + for (int lineNumber = 1; lineNumber <= numLines; lineNumber++) + { + waitForXFreeLines(1); + PrintLine *p = getNextWriteLine(); + // Downside a comparison per loop. Upside one less distance calculation and simpler code. + if (numLines == 1) + { + // p->numDeltaSegments = segmentCount; // not neede, gets overwritten further down + p->dir = cartesianDir; + for (fast8_t i = 0; i < E_AXIS_ARRAY; i++) + { + p->delta[i] = cartesianDeltaSteps[i]; + fractionalSteps[i] = difference[i]; + } + p->distance = cartesianDistance; + } + else + { + for (fast8_t i = 0; i < E_AXIS_ARRAY; i++) + { + Printer::destinationSteps[i] = startPosition[i] + (difference[i] * lineNumber) / numLines; + fractionalSteps[i] = Printer::destinationSteps[i] - Printer::currentPositionSteps[i]; + axisDistanceMM[i] = fabs(fractionalSteps[i] * Printer::invAxisStepsPerMM[i]); + } + calculateDirectionAndDelta(fractionalSteps, &p->dir, p->delta); + p->distance = cartesianDistance; + } + + p->joinFlags = 0; + p->secondSpeed = secondSpeed; + p->moveID = lastMoveID; + + // Only set fixed on last segment + if (lineNumber == numLines && !pathOptimize) + p->setEndSpeedFixed(true); + + p->flags = (check_endstops ? FLAG_CHECK_ENDSTOPS : 0); +#if MIXING_EXTRUDER + if(Printer::isAllEMotors()) { + p->flags |= FLAG_ALL_E_MOTORS; + } +#endif + p->numNonlinearSegments = segmentsPerLine; + + uint16_t maxStepsPerSegment = p->calculateNonlinearSubSegments(softEndstop); + if (maxStepsPerSegment == 65535) + { + Com::printWarningFLN(PSTR("in queueDeltaMove to calculateDeltaSubSegments returns error.")); + return false; + } +#ifdef DEBUG_SPLIT + Com::printFLN(Com::tDBGDeltaMaxDS, (int32_t)maxStepsPerSegment); +#endif + int32_t virtualAxisSteps = static_cast(maxStepsPerSegment) * segmentsPerLine; + if (virtualAxisSteps == 0 && p->delta[E_AXIS] == 0) + { + if (numLines != 1) + { + Com::printErrorFLN(Com::tDBGDeltaNoMoveinDSegment); + return false; // Line too short in low precision area + } + } + fast8_t drivingAxis = X_AXIS; + p->primaryAxis = VIRTUAL_AXIS; // Virtual axis will lead Bresenham step either way + if (virtualAxisSteps > p->delta[E_AXIS]) // Is delta move or E axis leading + { + p->stepsRemaining = virtualAxisSteps; + axisDistanceMM[VIRTUAL_AXIS] = p->distance; //virtual_axis_move * Printer::invAxisStepsPerMM[Z_AXIS]; // Steps/unit same as all the towers + // Virtual axis steps per segment + p->numPrimaryStepPerSegment = maxStepsPerSegment; +#if DRIVE_SYSTEM != DELTA + if(cartesianDeltaSteps[Z_AXIS] > cartesianDeltaSteps[X_AXIS] && cartesianDeltaSteps[Z_AXIS] > cartesianDeltaSteps[Y_AXIS]) + drivingAxis = Z_AXIS; +#endif + } + else + { + // Round up the E move to get something divisible by segment count which is greater than E move + p->numPrimaryStepPerSegment = (p->delta[E_AXIS] + segmentsPerLine - 1) / segmentsPerLine; + p->stepsRemaining = p->numPrimaryStepPerSegment * segmentsPerLine; + axisDistanceMM[VIRTUAL_AXIS] = -p->distance; //p->stepsRemaining * Printer::invAxisStepsPerMM[Z_AXIS]; + drivingAxis = E_AXIS; + } +#ifdef DEBUG_SPLIT + Com::printFLN(Com::tDBGDeltaStepsPerSegment, p->numPrimaryStepPerSegment); + Com::printFLN(Com::tDBGDeltaVirtualAxisSteps, p->stepsRemaining); +#endif + p->calculateMove(axisDistanceMM, pathOptimize,drivingAxis); + for (fast8_t i = 0; i < E_AXIS_ARRAY; i++) + { + Printer::currentPositionSteps[i] += fractionalSteps[i]; + } + } + Printer::currentPositionSteps[E_AXIS] = Printer::destinationSteps[E_AXIS] = oldEDestination; + lastMoveID++; // Will wrap at 255 + + return true; // flag success +} + +#endif + +#if ARC_SUPPORT +// Arc function taken from grbl +// The arc is approximated by generating a huge number of tiny, linear segments. The length of each +// segment is configured in settings.mm_per_arc_segment. +void PrintLine::arc(float *position, float *target, float *offset, float radius, uint8_t isclockwise) +{ + // int acceleration_manager_was_enabled = plan_is_acceleration_manager_enabled(); + // plan_set_acceleration_manager_enabled(false); // disable acceleration management for the duration of the arc + float center_axis0 = position[X_AXIS] + offset[X_AXIS]; + float center_axis1 = position[Y_AXIS] + offset[Y_AXIS]; + //float linear_travel = 0; //target[axis_linear] - position[axis_linear]; + float extruder_travel = (Printer::destinationSteps[E_AXIS] - Printer::currentPositionSteps[E_AXIS]) * Printer::invAxisStepsPerMM[E_AXIS]; + float r_axis0 = -offset[0]; // Radius vector from center to current location + float r_axis1 = -offset[1]; + float rt_axis0 = target[0] - center_axis0; + float rt_axis1 = target[1] - center_axis1; + /*long xtarget = Printer::destinationSteps[X_AXIS]; + long ytarget = Printer::destinationSteps[Y_AXIS]; + long ztarget = Printer::destinationSteps[Z_AXIS]; + long etarget = Printer::destinationSteps[E_AXIS]; + */ + // CCW angle between position and target from circle center. Only one atan2() trig computation required. + float angular_travel = atan2(r_axis0 * rt_axis1 - r_axis1 * rt_axis0, r_axis0 * rt_axis0 + r_axis1 * rt_axis1); + if ((!isclockwise && angular_travel <= 0.00001) || (isclockwise && angular_travel < -0.000001)) + { + angular_travel += 2.0f * M_PI; + } + if (isclockwise) + { + angular_travel -= 2.0f * M_PI; + } + + float millimeters_of_travel = fabs(angular_travel)*radius; //hypot(angular_travel*radius, fabs(linear_travel)); + if (millimeters_of_travel < 0.001f) + { + return;// treat as succes because there is nothing to do; + } + //uint16_t segments = (radius>=BIG_ARC_RADIUS ? floor(millimeters_of_travel/MM_PER_ARC_SEGMENT_BIG) : floor(millimeters_of_travel/MM_PER_ARC_SEGMENT)); + // Increase segment size if printing faster then computation speed allows + uint16_t segments = (Printer::feedrate > 60.0f ? floor(millimeters_of_travel / RMath::min(static_cast(MM_PER_ARC_SEGMENT_BIG), Printer::feedrate * 0.01666f * static_cast(MM_PER_ARC_SEGMENT))) : floor(millimeters_of_travel / static_cast(MM_PER_ARC_SEGMENT))); + if(segments == 0) segments = 1; + /* + // Multiply inverse feed_rate to compensate for the fact that this movement is approximated + // by a number of discrete segments. The inverse feed_rate should be correct for the sum of + // all segments. + if (invert_feed_rate) { feed_rate *= segments; } + */ + float theta_per_segment = angular_travel / segments; + //float linear_per_segment = linear_travel/segments; + float extruder_per_segment = extruder_travel / segments; + + /* Vector rotation by transformation matrix: r is the original vector, r_T is the rotated vector, + and phi is the angle of rotation. Based on the solution approach by Jens Geisler. + r_T = [cos(phi) -sin(phi); + sin(phi) cos(phi] * r ; + + For arc generation, the center of the circle is the axis of rotation and the radius vector is + defined from the circle center to the initial position. Each line segment is formed by successive + vector rotations. This requires only two cos() and sin() computations to form the rotation + matrix for the duration of the entire arc. Error may accumulate from numerical round-off, since + all double numbers are single precision on the Arduino. (True double precision will not have + round off issues for CNC applications.) Single precision error can accumulate to be greater than + tool precision in some cases. Therefore, arc path correction is implemented. + + Small angle approximation may be used to reduce computation overhead further. This approximation + holds for everything, but very small circles and large mm_per_arc_segment values. In other words, + theta_per_segment would need to be greater than 0.1 rad and N_ARC_CORRECTION would need to be large + to cause an appreciable drift error. N_ARC_CORRECTION~=25 is more than small enough to correct for + numerical drift error. N_ARC_CORRECTION may be on the order a hundred(s) before error becomes an + issue for CNC machines with the single precision Arduino calculations. + + This approximation also allows mc_arc to immediately insert a line segment into the planner + without the initial overhead of computing cos() or sin(). By the time the arc needs to be applied + a correction, the planner should have caught up to the lag caused by the initial mc_arc overhead. + This is important when there are successive arc motions. + */ + // Vector rotation matrix values + float cos_T = 1 - 0.5 * theta_per_segment * theta_per_segment; // Small angle approximation + float sin_T = theta_per_segment; + + float arc_target[4]; + float sin_Ti; + float cos_Ti; + float r_axisi; + uint16_t i; + int8_t count = 0; + + // Initialize the linear axis + //arc_target[axis_linear] = position[axis_linear]; + + // Initialize the extruder axis + arc_target[E_AXIS] = Printer::currentPositionSteps[E_AXIS] * Printer::invAxisStepsPerMM[E_AXIS]; + + for (i = 1; i < segments; i++) + { + // Increment (segments-1) + + if((count & 3) == 0) + { + GCode::readFromSerial(); + Commands::checkForPeriodicalActions(false); + UI_MEDIUM; // do check encoder + } + + if (count < N_ARC_CORRECTION) //25 pieces + { + // Apply vector rotation matrix + r_axisi = r_axis0 * sin_T + r_axis1 * cos_T; + r_axis0 = r_axis0 * cos_T - r_axis1 * sin_T; + r_axis1 = r_axisi; + count++; + } + else + { + // Arc correction to radius vector. Computed only every N_ARC_CORRECTION increments. + // Compute exact location by applying transformation matrix from initial radius vector(=-offset). + cos_Ti = cos(i * theta_per_segment); + sin_Ti = sin(i * theta_per_segment); + r_axis0 = -offset[0] * cos_Ti + offset[1] * sin_Ti; + r_axis1 = -offset[0] * sin_Ti - offset[1] * cos_Ti; + count = 0; + } + + // Update arc_target location + arc_target[X_AXIS] = center_axis0 + r_axis0; + arc_target[Y_AXIS] = center_axis1 + r_axis1; + //arc_target[axis_linear] += linear_per_segment; + arc_target[E_AXIS] += extruder_per_segment; + Printer::moveToReal(arc_target[X_AXIS],arc_target[Y_AXIS],IGNORE_COORDINATE,arc_target[E_AXIS],IGNORE_COORDINATE); + } + // Ensure last segment arrives at target location. + Printer::moveToReal(target[X_AXIS],target[Y_AXIS],IGNORE_COORDINATE,target[E_AXIS],IGNORE_COORDINATE); +} +#endif + + + +/** + Moves the stepper motors one step. If the last step is reached, the next movement is started. + The function must be called from a timer loop. It returns the time for the next call. + This is a modified version that implements a Bresenham 'multi-step' algorithm where the dominant + Cartesian axis steps may be less than the changing dominant delta axis. +*/ +#if NONLINEAR_SYSTEM +int lastblk =- 1; +int32_t cur_errupd; +// Current nonlinear segment +NonlinearSegment *curd; +// Current nonlinear segment primary error increment +int32_t curd_errupd, stepsPerSegRemaining; +int32_t PrintLine::bresenhamStep() // Version for delta printer +{ +#if CPU_ARCH == ARCH_ARM + if(!PrintLine::nlFlag) +#else + if(cur == NULL) +#endif + { + setCurrentLine(); + if(cur->isBlocked()) // This step is in computation - shouldn't happen + { + if(lastblk != (int)cur) + { + HAL::allowInterrupts(); + lastblk = (int)cur; + Com::printFLN(Com::tBLK, (int32_t)linesCount); + } + cur = NULL; +#if CPU_ARCH == ARCH_ARM + PrintLine::nlFlag = false; +#endif + return 2000; + } + HAL::allowInterrupts(); + lastblk = -1; +#if INCLUDE_DEBUG_NO_MOVE + if(Printer::debugNoMoves()) // simulate a move, but do nothing in reality + { + removeCurrentLineForbidInterrupt(); + if(linesCount == 0) UI_STATUS_F(Com::translatedF(UI_TEXT_IDLE_ID)); + return 1000; + } +#endif + if(cur->isWarmUp()) + { + // This is a warm up move to initialize the path planner correctly. Just waste + // a bit of time to get the planning up to date. + if(linesCount <= cur->getWaitForXLinesFilled()) + { + cur = NULL; +#if CPU_ARCH==ARCH_ARM + PrintLine::nlFlag = false; +#endif + return 2000; + } + long wait = cur->getWaitTicks(); + removeCurrentLineForbidInterrupt(); + return(wait); // waste some time for path optimization to fill up + } // End if WARMUP +#if FEATURE_Z_PROBE + // z move may consist of more then 1 z line segment, so we better ignore them + // if the probe was already hit. + if(Printer::isZProbingActive() && Printer::stepsRemainingAtZHit >= 0) + { + removeCurrentLineForbidInterrupt(); + if(linesCount == 0) UI_STATUS_F(Com::translatedF(UI_TEXT_IDLE_ID)); + return 1000; + } +#endif + + if(cur->isEMove()) { + Extruder::enable(); + } + cur->fixStartAndEndSpeed(); + // Set up delta segments + if (cur->numNonlinearSegments) + { + + // If there are delta segments point to them here + curd = &cur->segments[--cur->numNonlinearSegments]; + // Enable axis - All axis are enabled since they will most probably all be involved in a move + // Since segments could involve different axis this reduces load when switching segments and + // makes disabling easier. + Printer::enableXStepper(); + Printer::enableYStepper(); + Printer::enableZStepper(); + Printer::setXDirection(curd->isXPositiveMove()); + Printer::setYDirection(curd->isYPositiveMove()); + Printer::setZDirection(curd->isZPositiveMove()); + + // Copy across movement into main direction flags so that endstops function correctly +#if DRIVE_SYSTEM == DELTA + cur->dir |= curd->dir; // deltas need this for homing! +#endif + // Initialize Bresenham for the first segment + cur->error[X_AXIS] = cur->error[Y_AXIS] = cur->error[Z_AXIS] = cur->numPrimaryStepPerSegment >> 1; + curd_errupd = cur->numPrimaryStepPerSegment; + stepsPerSegRemaining = cur->numPrimaryStepPerSegment; + } + else curd = NULL; + cur_errupd = cur->stepsRemaining; + + if(!cur->areParameterUpToDate()) // should never happen, but with bad timings??? + { + cur->updateStepsParameter(); + } + Printer::vMaxReached = cur->vStart; + Printer::stepNumber = 0; + Printer::timer = 0; + HAL::forbidInterrupts(); +#if USE_ADVANCE + if(!Printer::isAdvanceActivated()) // Set direction if no advance/OPS enabled +#endif + Extruder::setDirection(cur->isEPositiveMove()); +#if defined(DIRECTION_DELAY) && DIRECTION_DELAY > 0 + // HAL::delayMicroseconds(DIRECTION_DELAY); // We leave interrupt without step so no delay needed here +#endif +#if USE_ADVANCE +#if ENABLE_QUADRATIC_ADVANCE + Printer::advanceExecuted = cur->advanceStart; +#endif + cur->updateAdvanceSteps(cur->vStart, 0, false); +#endif + if(Printer::mode == PRINTER_MODE_FFF) { + Printer::setFanSpeedDirectly(cur->secondSpeed); + } +#if defined(SUPPORT_LASER) && SUPPORT_LASER + else if(Printer::mode == PRINTER_MODE_LASER) + { + LaserDriver::changeIntensity(cur->secondSpeed); + } +#endif + return Printer::interval; // Wait an other 50% from last step to make the 100% full + } // End cur=0 + HAL::allowInterrupts(); + + if(curd != NULL) + { + if(curd->checkEndstops(cur,(cur->isCheckEndstops()))) { // should stop move + cur->stepsRemaining = 0; + curd = NULL; + // eat up all following segments with moveID + uint8_t delId = cur->moveID; + removeCurrentLineForbidInterrupt(); + while(linesCount > 0) { + setCurrentLine(); + if(cur->isBlocked() || cur->moveID != delId) { + break; + } + removeCurrentLineForbidInterrupt(); + } + cur = NULL; +#if CPU_ARCH == ARCH_ARM + nlFlag = false; +#endif + Printer::disableAllowedStepper(); + if(Printer::mode == PRINTER_MODE_FFF) { + Printer::setFanSpeedDirectly(Printer::fanSpeed); + } + #if defined(SUPPORT_LASER) && SUPPORT_LASER + else if(Printer::mode == PRINTER_MODE_LASER) // Last move disables laser for safety! + { + LaserDriver::changeIntensity(0); + } + #endif + return Printer::interval; + } + } + int maxLoops = (Printer::stepsPerTimerCall <= cur->stepsRemaining ? Printer::stepsPerTimerCall : cur->stepsRemaining); + HAL::forbidInterrupts(); + for(int loop = 0; loop < maxLoops; loop++) + { +#if STEPPER_HIGH_DELAY + DOUBLE_STEP_DELAY + if(loop > 0) + HAL::delayMicroseconds(STEPPER_HIGH_DELAY + DOUBLE_STEP_DELAY); +#endif + if((cur->error[E_AXIS] -= cur->delta[E_AXIS]) < 0) + { +#if USE_ADVANCE + if(Printer::isAdvanceActivated()) // Use interrupt for movement + { + if(cur->isEPositiveMove()) + Printer::extruderStepsNeeded++; + else + Printer::extruderStepsNeeded--; + } + else +#endif + Extruder::step(); + cur->error[E_AXIS] += cur_errupd; + } + if (curd) + { + // Take delta steps + if(curd->isXMove()) + if((cur->error[X_AXIS] -= curd->deltaSteps[A_TOWER]) < 0) + { + cur->startXStep(); + cur->error[X_AXIS] += curd_errupd; +#ifdef DEBUG_REAL_POSITION + Printer::realDeltaPositionSteps[A_TOWER] += curd->isXPositiveMove() ? 1 : -1; +#endif +#ifdef DEBUG_STEPCOUNT + cur->totalStepsRemaining--; +#endif + } + + if(curd->isYMove()) + if((cur->error[Y_AXIS] -= curd->deltaSteps[B_TOWER]) < 0) + { + cur->startYStep(); + cur->error[Y_AXIS] += curd_errupd; +#ifdef DEBUG_REAL_POSITION + Printer::realDeltaPositionSteps[B_TOWER] += curd->isYPositiveMove() ? 1 : -1; +#endif +#ifdef DEBUG_STEPCOUNT + cur->totalStepsRemaining--; +#endif + } + + if(curd->isZMove()) + if((cur->error[Z_AXIS] -= curd->deltaSteps[C_TOWER]) < 0) + { + cur->startZStep(); + cur->error[Z_AXIS] += curd_errupd; + Printer::realDeltaPositionSteps[C_TOWER] += curd->isZPositiveMove() ? 1 : -1; +#ifdef DEBUG_STEPCOUNT + cur->totalStepsRemaining--; +#endif + } + stepsPerSegRemaining--; + } +#if CPU_ARCH != ARCH_AVR + if(loop < maxLoops - 1) + { +#endif + Printer::insertStepperHighDelay(); + Printer::endXYZSteps(); +#if USE_ADVANCE + if(!Printer::isAdvanceActivated()) // Use interrupt for movement +#endif + Extruder::unstep(); +#if CPU_ARCH != ARCH_AVR + } +#endif + if (!stepsPerSegRemaining) // start new nonlinear segment + { + if (cur->numNonlinearSegments && curd != NULL) + { + if(FEATURE_BABYSTEPPING && Printer::zBabystepsMissing/* && curd + && (curd->dir & XYZ_STEP) == XYZ_STEP*/) + { + // execute a extra baby step + Printer::zBabystep(); + } + // Get the next delta segment + curd = &cur->segments[--cur->numNonlinearSegments]; + + // Initialize Bresenham for this segment (numPrimaryStepPerSegment is already correct for the half step setting) + cur->error[X_AXIS] = cur->error[Y_AXIS] = cur->error[Z_AXIS] = cur->numPrimaryStepPerSegment >> 1; + + // Reset the counter of the primary steps. This is initialized in the line + // generation so don't have to do this the first time. + stepsPerSegRemaining = cur->numPrimaryStepPerSegment; + + // Change direction if necessary + Printer::setXDirection(curd->dir & X_DIRPOS); + Printer::setYDirection(curd->dir & Y_DIRPOS); + Printer::setZDirection(curd->dir & Z_DIRPOS); +#if defined(DIRECTION_DELAY) && DIRECTION_DELAY > 0 +#if CPU_ARCH != ARCH_AVR + if(loop < maxLoops - 1) +#endif + HAL::delayMicroseconds(DIRECTION_DELAY); +#endif + + } + else + curd = 0;// Release the last segment + //deltaSegmentCount--; + } + } // for loop + + HAL::allowInterrupts(); // Allow interrupts for other types, timer1 is still disabled +#if RAMP_ACCELERATION +//If acceleration is enabled on this move and we are in the acceleration segment, calculate the current interval + if (cur->moveAccelerating()) + { + Printer::vMaxReached = HAL::ComputeV(Printer::timer, cur->fAcceleration) + cur->vStart; + if(Printer::vMaxReached > cur->vMax) Printer::vMaxReached = cur->vMax; + speed_t v = Printer::updateStepsPerTimerCall(Printer::vMaxReached); + Printer::interval = HAL::CPUDivU2(v); + Printer::timer += Printer::interval; + cur->updateAdvanceSteps(Printer::vMaxReached, maxLoops, true); + Printer::stepNumber += maxLoops; // is only used by moveAccelerating + } + else if (cur->moveDecelerating()) // time to slow down + { + speed_t v = HAL::ComputeV(Printer::timer, cur->fAcceleration); + if (v > Printer::vMaxReached) // if deceleration goes too far it can become too large + v = cur->vEnd; + else + { + v = Printer::vMaxReached - v; + if (v < cur->vEnd) v = cur->vEnd; // extra steps at the end of desceleration due to rounding erros + } + cur->updateAdvanceSteps(v, maxLoops, false); + v = Printer::updateStepsPerTimerCall(v); + Printer::interval = HAL::CPUDivU2(v); + Printer::timer += Printer::interval; + } + else + { + // If we had acceleration, we need to use the latest vMaxReached and interval + // If we started full speed, we need to use cur->fullInterval and vMax + cur->updateAdvanceSteps((!cur->accelSteps ? cur->vMax : Printer::vMaxReached), 0, true); + if(!cur->accelSteps) + { + if(cur->vMax > STEP_DOUBLER_FREQUENCY) + { +#if ALLOW_QUADSTEPPING + if(cur->vMax > STEP_DOUBLER_FREQUENCY * 2) + { + Printer::stepsPerTimerCall = 4; + Printer::interval = cur->fullInterval << 2; + } + else + { + Printer::stepsPerTimerCall = 2; + Printer::interval = cur->fullInterval << 1; + } +#else + Printer::stepsPerTimerCall = 2; + Printer::interval = cur->fullInterval << 1; +#endif + } + else + { + Printer::stepsPerTimerCall = 1; + Printer::interval = cur->fullInterval; + } + } + } +#else + Printer::interval = cur->fullInterval; // without RAMPS always use full speed +#endif + PrintLine::cur->stepsRemaining -= maxLoops; + + if(cur->stepsRemaining <= 0 || cur->isNoMove()) // line finished + { + // Release remaining delta segments +#ifdef DEBUG_STEPCOUNT + if(cur->totalStepsRemaining || cur->numNonlinearSegments) + { + Com::printFLN(PSTR("Missed steps:"), cur->totalStepsRemaining); + Com::printFLN(PSTR("Step/seg r:"), stepsPerSegRemaining); + Com::printFLN(PSTR("NDS:"), (int) cur->numNonlinearSegments); + } +#endif + removeCurrentLineForbidInterrupt(); + Printer::disableAllowedStepper(); + if(linesCount == 0) { + UI_STATUS_F(Com::translatedF(UI_TEXT_IDLE_ID)); + if(Printer::mode == PRINTER_MODE_FFF) { + Printer::setFanSpeedDirectly(Printer::fanSpeed); + } +#if defined(SUPPORT_LASER) && SUPPORT_LASER + else if(Printer::mode == PRINTER_MODE_LASER) // Last move disables laser for safety! + { + LaserDriver::changeIntensity(0); + } +#endif + } + Printer::interval >>= 1; // 50% of time to next call to do cur=0 + DEBUG_MEMORY; + } // Do even +#if CPU_ARCH != ARCH_AVR + Printer::insertStepperHighDelay(); + Printer::endXYZSteps(); +#if USE_ADVANCE + if(!Printer::isAdvanceActivated()) // Use interrupt for movement +#endif + Extruder::unstep(); +#endif + return Printer::interval; +} +#else +/** + Moves the stepper motors one step. If the last step is reached, the next movement is started. + The function must be called from a timer loop. It returns the time for the next call. + + Normal linear algorithm +*/ +int lastblk = -1; +int32_t cur_errupd; +int32_t PrintLine::bresenhamStep() // version for Cartesian printer +{ +#if CPU_ARCH == ARCH_ARM + if(!PrintLine::nlFlag) +#else + if(cur == NULL) +#endif + { + setCurrentLine(); + if(cur->isBlocked()) // This step is in computation - shouldn't happen + { + /*if(lastblk!=(int)cur) // can cause output errors! + { + HAL::allowInterrupts(); + lastblk = (int)cur; + Com::printFLN(Com::tBLK,lines_count); + }*/ + cur = NULL; +#if CPU_ARCH==ARCH_ARM + PrintLine::nlFlag = false; +#endif + return 2000; + } + HAL::allowInterrupts(); + lastblk = -1; +#if INCLUDE_DEBUG_NO_MOVE + if(Printer::debugNoMoves()) // simulate a move, but do nothing in reality + { + removeCurrentLineForbidInterrupt(); + return 1000; + } +#endif + ANALYZER_OFF(ANALYZER_CH0); + if(cur->isWarmUp()) + { + // This is a warmup move to initalize the path planner correctly. Just waste + // a bit of time to get the planning up to date. + if(linesCount<=cur->getWaitForXLinesFilled()) + { + cur = NULL; +#if CPU_ARCH == ARCH_ARM + PrintLine::nlFlag = false; +#endif + return 2000; + } + long wait = cur->getWaitTicks(); + removeCurrentLineForbidInterrupt(); + return(wait); // waste some time for path optimization to fill up + } // End if WARMUP + //Only enable axis that are moving. If the axis doesn't need to move then it can stay disabled depending on configuration. +#if GANTRY +#if DRIVE_SYSTEM == XY_GANTRY || DRIVE_SYSTEM == YX_GANTRY + if(cur->isXOrYMove()) + { + Printer::enableXStepper(); + Printer::enableYStepper(); + } + if(cur->isZMove()) Printer::enableZStepper(); +#else // XZ / ZX Gantry + if(cur->isXOrZMove()) + { + Printer::enableXStepper(); + Printer::enableZStepper(); + } + if(cur->isYMove()) Printer::enableYStepper(); +#endif +#else + if(cur->isXMove()) Printer::enableXStepper(); + if(cur->isYMove()) Printer::enableYStepper(); + if(cur->isZMove()) Printer::enableZStepper(); +#endif + if(cur->isEMove()) Extruder::enable(); + cur->fixStartAndEndSpeed(); + HAL::allowInterrupts(); + cur_errupd = cur->delta[cur->primaryAxis]; + if(!cur->areParameterUpToDate()) // should never happen, but with bad timings??? + { + cur->updateStepsParameter(); + } + Printer::vMaxReached = cur->vStart; + Printer::stepNumber=0; + Printer::timer = 0; + HAL::forbidInterrupts(); + //Determine direction of movement,check if endstop was hit +#if !(GANTRY) + Printer::setXDirection(cur->isXPositiveMove()); + Printer::setYDirection(cur->isYPositiveMove()); + Printer::setZDirection(cur->isZPositiveMove()); +#else // Any gantry type + long gdx = (cur->dir & X_DIRPOS ? cur->delta[X_AXIS] : -cur->delta[X_AXIS]); // Compute signed difference in steps +#if DRIVE_SYSTEM == XY_GANTRY || DRIVE_SYSTEM == YX_GANTRY + Printer::setZDirection(cur->isZPositiveMove()); + long gdy = (cur->dir & Y_DIRPOS ? cur->delta[Y_AXIS] : -cur->delta[Y_AXIS]); + Printer::setXDirection(gdx + gdy >= 0); +#if DRIVE_SYSTEM == XY_GANTRY + Printer::setYDirection(gdx > gdy); +#else + Printer::setYDirection(gdx <= gdy); +#endif +#else // XZ or ZX core + Printer::setYDirection(cur->isYPositiveMove()); + long gdz = (cur->dir & Z_DIRPOS ? cur->delta[Z_AXIS] : -cur->delta[Z_AXIS]); + Printer::setXDirection(gdx + gdz >= 0); +#if DRIVE_SYSTEM == XZ_GANTRY + Printer::setZDirection(gdx > gdz); +#else + Printer::setZDirection(gdx <= gdz); +#endif +#endif // YZ or ZY Gantry +#endif // GANTRY +#if USE_ADVANCE + if(!Printer::isAdvanceActivated()) // Set direction if no advance/OPS enabled +#endif + Extruder::setDirection(cur->isEPositiveMove()); +#if defined(DIRECTION_DELAY) && DIRECTION_DELAY > 0 + // HAL::delayMicroseconds(DIRECTION_DELAY); // We leave interrupt without step so no delay needed here +#endif +#if USE_ADVANCE +#if ENABLE_QUADRATIC_ADVANCE + Printer::advanceExecuted = cur->advanceStart; +#endif + cur->updateAdvanceSteps(cur->vStart, 0, false); +#endif + if(Printer::mode == PRINTER_MODE_FFF) { + Printer::setFanSpeedDirectly(cur->secondSpeed); + } +#if defined(SUPPORT_LASER) && SUPPORT_LASER + else if(Printer::mode == PRINTER_MODE_LASER) + { + LaserDriver::changeIntensity(cur->secondSpeed); + } +#endif + return Printer::interval; // Wait an other 50% from last step to make the 100% full + } // End cur=0 + cur->checkEndstops(); + fast8_t max_loops = Printer::stepsPerTimerCall; + if(cur->stepsRemaining < max_loops) + max_loops = cur->stepsRemaining; + for(fast8_t loop = 0; loop < max_loops; loop++) + { +#if STEPPER_HIGH_DELAY + DOUBLE_STEP_DELAY > 0 + if(loop) + HAL::delayMicroseconds(STEPPER_HIGH_DELAY + DOUBLE_STEP_DELAY); +#endif + if((cur->error[E_AXIS] -= cur->delta[E_AXIS]) < 0) + { +#if USE_ADVANCE + if(Printer::isAdvanceActivated()) // Use interrupt for movement + { + if(cur->isEPositiveMove()) + Printer::extruderStepsNeeded++; + else + Printer::extruderStepsNeeded--; + } + else +#endif + Extruder::step(); + cur->error[E_AXIS] += cur_errupd; + } +#if CPU_ARCH == ARCH_AVR + if(cur->isXMove()) +#endif + if((cur->error[X_AXIS] -= cur->delta[X_AXIS]) < 0) + { + cur->startXStep(); + cur->error[X_AXIS] += cur_errupd; + } +#if CPU_ARCH == ARCH_AVR + if(cur->isYMove()) +#endif + if((cur->error[Y_AXIS] -= cur->delta[Y_AXIS]) < 0) + { + cur->startYStep(); + cur->error[Y_AXIS] += cur_errupd; + } +#if CPU_ARCH == ARCH_AVR + if(cur->isZMove()) +#endif + if((cur->error[Z_AXIS] -= cur->delta[Z_AXIS]) < 0) + { + cur->startZStep(); + cur->error[Z_AXIS] += cur_errupd; +#ifdef DEBUG_STEPCOUNT + cur->totalStepsRemaining--; +#endif + } +#if (GANTRY) +#if DRIVE_SYSTEM == XY_GANTRY || DRIVE_SYSTEM == YX_GANTRY + Printer::executeXYGantrySteps(); +#else + Printer::executeXZGantrySteps(); +#endif +#endif + Printer::insertStepperHighDelay(); +#if USE_ADVANCE + if(!Printer::isAdvanceActivated()) // Use interrupt for movement +#endif + Extruder::unstep(); + cur->stepsRemaining--; + Printer::endXYZSteps(); + } // for loop + HAL::allowInterrupts(); // Allow interrupts for other types, timer1 is still disabled +#if RAMP_ACCELERATION + //If acceleration is enabled on this move and we are in the acceleration segment, calculate the current interval + if (cur->moveAccelerating()) // we are accelerating + { + Printer::vMaxReached = HAL::ComputeV(Printer::timer,cur->fAcceleration) + cur->vStart; + if(Printer::vMaxReached > cur->vMax) Printer::vMaxReached = cur->vMax; + unsigned int v = Printer::updateStepsPerTimerCall(Printer::vMaxReached); + Printer::interval = HAL::CPUDivU2(v); + Printer::timer += Printer::interval; + cur->updateAdvanceSteps(Printer::vMaxReached, max_loops, true); + Printer::stepNumber += max_loops; // only used for moveAccelerating + } + else if (cur->moveDecelerating()) // time to slow down + { + unsigned int v = HAL::ComputeV(Printer::timer,cur->fAcceleration); + if (v > Printer::vMaxReached) // if deceleration goes too far it can become too large + v = cur->vEnd; + else + { + v = Printer::vMaxReached - v; + if (vvEnd) v = cur->vEnd; // extra steps at the end of desceleration due to rounding erros + } + cur->updateAdvanceSteps(v,max_loops,false); // needs original v + v = Printer::updateStepsPerTimerCall(v); + Printer::interval = HAL::CPUDivU2(v); + Printer::timer += Printer::interval; + } + else // full speed reached + { + cur->updateAdvanceSteps((!cur->accelSteps ? cur->vMax : Printer::vMaxReached), 0, true); + // constant speed reached + if(cur->vMax > STEP_DOUBLER_FREQUENCY) + { +#if ALLOW_QUADSTEPPING + if(cur->vMax > STEP_DOUBLER_FREQUENCY * 2) + { + Printer::stepsPerTimerCall = 4; + Printer::interval = cur->fullInterval << 2; + } + else + { + Printer::stepsPerTimerCall = 2; + Printer::interval = cur->fullInterval << 1; + } +#else + Printer::stepsPerTimerCall = 2; + Printer::interval = cur->fullInterval << 1; +#endif + } + else + { + Printer::stepsPerTimerCall = 1; + Printer::interval = cur->fullInterval; + } + } +#else + Printer::stepsPerTimerCall = 1; + Printer::interval = cur->fullInterval; // without RAMPS always use full speed +#endif // RAMP_ACCELERATION + long interval = Printer::interval; + if(cur->stepsRemaining <= 0 || cur->isNoMove()) // line finished + { +#ifdef DEBUG_STEPCOUNT + if(cur->totalStepsRemaining) + { + Com::printF(Com::tDBGMissedSteps, cur->totalStepsRemaining); + Com::printFLN(Com::tComma, cur->stepsRemaining); + } +#endif + removeCurrentLineForbidInterrupt(); + Printer::disableAllowedStepper(); + if(linesCount == 0) + { + UI_STATUS_F(Com::translatedF(UI_TEXT_IDLE_ID)); + if(Printer::mode == PRINTER_MODE_FFF) { + Printer::setFanSpeedDirectly(Printer::fanSpeed); + } +#if defined(SUPPORT_LASER) && SUPPORT_LASER + else if(Printer::mode == PRINTER_MODE_LASER) // Last move disables laser for safety! + { + LaserDriver::changeIntensity(0); + } +#endif + } + interval = Printer::interval = interval >> 1; // 50% of time to next call to do cur=0 + DEBUG_MEMORY; + } // Do even + if(FEATURE_BABYSTEPPING && Printer::zBabystepsMissing) + { + HAL::forbidInterrupts(); + Printer::zBabystep(); + } + return interval; +} +#endif diff --git a/trunk/Arduino/Repetier_0.92.9/motion.h b/trunk/Arduino/Repetier_0.92.9/motion.h new file mode 100644 index 00000000..05b7cac5 --- /dev/null +++ b/trunk/Arduino/Repetier_0.92.9/motion.h @@ -0,0 +1,719 @@ +/* + This file is part of Repetier-Firmware. + + Repetier-Firmware is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Repetier-Firmware is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Repetier-Firmware. If not, see . + + This firmware is a nearly complete rewrite of the sprinter firmware + by kliment (https://github.com/kliment/Sprinter) + which based on Tonokip RepRap firmware rewrite based off of Hydra-mmm firmware. +# + Functions in this file are used to communicate using ascii or repetier protocol. +*/ + +#ifndef MOTION_H_INCLUDED +#define MOTION_H_INCLUDED + +/** Marks the first step of a new move */ +#define FLAG_WARMUP 1 +#define FLAG_NOMINAL 2 +#define FLAG_DECELERATING 4 +#define FLAG_ACCELERATION_ENABLED 8 // unused +#define FLAG_CHECK_ENDSTOPS 16 +#define FLAG_ALL_E_MOTORS 32 // For mixed extruder move all motors instead of selected motor +#define FLAG_SKIP_DEACCELERATING 64 // unused +#define FLAG_BLOCKED 128 + +/** Are the step parameter computed */ +#define FLAG_JOIN_STEPPARAMS_COMPUTED 1 +/** The right speed is fixed. Don't check this block or any block to the left. */ +#define FLAG_JOIN_END_FIXED 2 +/** The left speed is fixed. Don't check left block. */ +#define FLAG_JOIN_START_FIXED 4 +/** Start filament retraction at move start */ +#define FLAG_JOIN_START_RETRACT 8 +/** Wait for filament push back, before ending move */ +#define FLAG_JOIN_END_RETRACT 16 +/** Disable retract for this line */ +#define FLAG_JOIN_NO_RETRACT 32 +/** Wait for the extruder to finish it's up movement */ +#define FLAG_JOIN_WAIT_EXTRUDER_UP 64 +/** Wait for the extruder to finish it's down movement */ +#define FLAG_JOIN_WAIT_EXTRUDER_DOWN 128 +// Printing related data +#if NONLINEAR_SYSTEM +// Allow the delta cache to store segments for every line in line cache. Beware this gets big ... fast. + +class PrintLine; +typedef struct +{ + flag8_t dir; ///< Direction of delta movement. + uint16_t deltaSteps[TOWER_ARRAY]; ///< Number of steps in move. + inline bool checkEndstops(PrintLine *cur,bool checkall); + inline void setXMoveFinished() + { + dir &= ~XSTEP; + } + inline void setYMoveFinished() + { + dir &= ~YSTEP; + } + inline void setZMoveFinished() + { + dir &= ~ZSTEP; + } + inline void setXYMoveFinished() + { + dir &= ~XY_STEP; + } + inline bool isXPositiveMove() + { + return (dir & X_STEP_DIRPOS) == X_STEP_DIRPOS; + } + inline bool isXNegativeMove() + { + return (dir & X_STEP_DIRPOS) == XSTEP; + } + inline bool isYPositiveMove() + { + return (dir & Y_STEP_DIRPOS) == Y_STEP_DIRPOS; + } + inline bool isYNegativeMove() + { + return (dir & Y_STEP_DIRPOS) == YSTEP; + } + inline bool isZPositiveMove() + { + return (dir & Z_STEP_DIRPOS) == Z_STEP_DIRPOS; + } + inline bool isZNegativeMove() + { + return (dir & Z_STEP_DIRPOS) == ZSTEP; + } + inline bool isEPositiveMove() + { + return (dir & E_STEP_DIRPOS) == E_STEP_DIRPOS; + } + inline bool isENegativeMove() + { + return (dir & E_STEP_DIRPOS) == ESTEP; + } + inline bool isXMove() + { + return (dir & XSTEP); + } + inline bool isYMove() + { + return (dir & YSTEP); + } + inline bool isXOrYMove() + { + return dir & XY_STEP; + } + inline bool isZMove() + { + return (dir & ZSTEP); + } + inline bool isEMove() + { + return (dir & ESTEP); + } + inline bool isEOnlyMove() + { + return (dir & XYZE_STEP)==ESTEP; + } + inline bool isNoMove() + { + return (dir & XYZE_STEP) == 0; + } + inline bool isXYZMove() + { + return dir & XYZ_STEP; + } + inline bool isMoveOfAxis(uint8_t axis) + { + return (dir & (XSTEP< inside interrupt handle + inline void updateAdvanceSteps(speed_t v, uint8_t max_loops, bool accelerate) + { +#if USE_ADVANCE + if(!Printer::isAdvanceActivated()) return; +#if ENABLE_QUADRATIC_ADVANCE + long advanceTarget = Printer::advanceExecuted; + if(accelerate) + { + for(uint8_t loop = 0; loop < max_loops; loop++) advanceTarget += advanceRate; + if(advanceTarget > advanceFull) + advanceTarget = advanceFull; + } + else + { + for(uint8_t loop = 0; loop < max_loops; loop++) advanceTarget -= advanceRate; + if(advanceTarget < advanceEnd) + advanceTarget = advanceEnd; + } + long h = HAL::mulu16xu16to32(v, advanceL); + int tred = ((advanceTarget + h) >> 16); + HAL::forbidInterrupts(); + Printer::extruderStepsNeeded += tred - Printer::advanceStepsSet; + if(tred > 0 && Printer::advanceStepsSet <= 0) + Printer::extruderStepsNeeded += Extruder::current->advanceBacklash; + else if(tred < 0 && Printer::advanceStepsSet >= 0) + Printer::extruderStepsNeeded -= Extruder::current->advanceBacklash; + Printer::advanceStepsSet = tred; + HAL::allowInterrupts(); + Printer::advanceExecuted = advanceTarget; +#else + int tred = HAL::mulu6xu16shift16(v, advanceL); + HAL::forbidInterrupts(); + Printer::extruderStepsNeeded += tred - Printer::advanceStepsSet; + if(tred > 0 && Printer::advanceStepsSet <= 0) + Printer::extruderStepsNeeded += (Extruder::current->advanceBacklash << 1); + else if(tred < 0 && Printer::advanceStepsSet >= 0) + Printer::extruderStepsNeeded -= (Extruder::current->advanceBacklash << 1); + Printer::advanceStepsSet = tred; + HAL::allowInterrupts(); +#endif +#endif + } + INLINE bool moveDecelerating() + { + if(stepsRemaining <= decelSteps) + { + if (!(flags & FLAG_DECELERATING)) + { + Printer::timer = 0; + flags |= FLAG_DECELERATING; + } + return true; + } + else return false; + } + INLINE bool moveAccelerating() + { + return Printer::stepNumber <= accelSteps; + } + INLINE void startXStep() + { +#if !(GANTRY) || defined(FAST_COREXYZ) + Printer::startXStep(); +#else +#if DRIVE_SYSTEM == XY_GANTRY || DRIVE_SYSTEM == XZ_GANTRY + if(isXPositiveMove()) + { + Printer::motorX++; + Printer::motorYorZ++; + } + else + { + Printer::motorX--; + Printer::motorYorZ--; + } +#endif +#if DRIVE_SYSTEM == YX_GANTRY || DRIVE_SYSTEM == ZX_GANTRY + if(isXPositiveMove()) + { + Printer::motorX++; + Printer::motorYorZ--; + } + else + { + Printer::motorX--; + Printer::motorYorZ++; + } +#endif +#endif +#ifdef DEBUG_STEPCOUNT + totalStepsRemaining--; +#endif + } + INLINE void startYStep() + { +#if !(GANTRY) || DRIVE_SYSTEM == ZX_GANTRY || DRIVE_SYSTEM == XZ_GANTRY || defined(FAST_COREXYZ) + Printer::startYStep(); +#else +#if DRIVE_SYSTEM == XY_GANTRY + if(isYPositiveMove()) + { + Printer::motorX++; + Printer::motorYorZ--; + } + else + { + Printer::motorX--; + Printer::motorYorZ++; + } +#endif +#if DRIVE_SYSTEM == YX_GANTRY + if(isYPositiveMove()) + { + Printer::motorX++; + Printer::motorYorZ++; + } + else + { + Printer::motorX--; + Printer::motorYorZ--; + } +#endif +#endif // GANTRY +#ifdef DEBUG_STEPCOUNT + totalStepsRemaining--; +#endif + + } + INLINE void startZStep() + { +#if !(GANTRY) || DRIVE_SYSTEM == YX_GANTRY || DRIVE_SYSTEM == XY_GANTRY || defined(FAST_COREXYZ) + Printer::startZStep(); +#else +#if DRIVE_SYSTEM == XZ_GANTRY + if(isZPositiveMove()) + { + Printer::motorX++; + Printer::motorYorZ--; + } + else + { + Printer::motorX--; + Printer::motorYorZ++; + } +#endif +#if DRIVE_SYSTEM == ZX_GANTRY + if(isZPositiveMove()) + { + Printer::motorX++; + Printer::motorYorZ++; + } + else + { + Printer::motorX--; + Printer::motorYorZ--; + } +#endif +#endif +#ifdef DEBUG_STEPCOUNT + totalStepsRemaining--; +#endif + } + void updateStepsParameter(); + float safeSpeed(fast8_t drivingAxis); + void calculateMove(float axis_diff[],uint8_t pathOptimize,fast8_t distanceBase); + void logLine(); + INLINE long getWaitTicks() + { + return timeInTicks; + } + INLINE void setWaitTicks(long wait) + { + timeInTicks = wait; + } + + static INLINE bool hasLines() + { + return linesCount; + } + static INLINE void setCurrentLine() + { + cur = &lines[linesPos]; +#if CPU_ARCH==ARCH_ARM + PrintLine::nlFlag = true; +#endif + } + // Only called from within interrupts + static INLINE void removeCurrentLineForbidInterrupt() + { + linesPos++; + if(linesPos >= PRINTLINE_CACHE_SIZE) linesPos = 0; + cur = NULL; +#if CPU_ARCH == ARCH_ARM + nlFlag = false; +#endif + HAL::forbidInterrupts(); + --linesCount; + if(!linesCount) + Printer::setMenuMode(MENU_MODE_PRINTING, false); + } + static INLINE void pushLine() + { + linesWritePos++; + if(linesWritePos >= PRINTLINE_CACHE_SIZE) linesWritePos = 0; + Printer::setMenuMode(MENU_MODE_PRINTING, true); + InterruptProtectedBlock noInts; + linesCount++; + } + static uint8_t getLinesCount() + { + InterruptProtectedBlock noInts; + return linesCount; + } + static PrintLine *getNextWriteLine() + { + return &lines[linesWritePos]; + } + static inline void computeMaxJunctionSpeed(PrintLine *previous,PrintLine *current); + static int32_t bresenhamStep(); + static void waitForXFreeLines(uint8_t b=1, bool allowMoves = false); + static inline void forwardPlanner(ufast8_t p); + static inline void backwardPlanner(ufast8_t p,ufast8_t last); + static void updateTrapezoids(); + static uint8_t insertWaitMovesIfNeeded(uint8_t pathOptimize, uint8_t waitExtraLines); +#if !NONLINEAR_SYSTEM + static void queueCartesianMove(uint8_t check_endstops,uint8_t pathOptimize); +#if DISTORTION_CORRECTION + static void queueCartesianSegmentTo(uint8_t check_endstops, uint8_t pathOptimize); +#endif +#endif + static void moveRelativeDistanceInSteps(int32_t x,int32_t y,int32_t z,int32_t e,float feedrate,bool waitEnd,bool check_endstop,bool pathOptimize = true); + static void moveRelativeDistanceInStepsReal(int32_t x,int32_t y,int32_t z,int32_t e,float feedrate,bool waitEnd,bool pathOptimize = true); +#if ARC_SUPPORT + static void arc(float *position, float *target, float *offset, float radius, uint8_t isclockwise); +#endif + static INLINE void previousPlannerIndex(ufast8_t &p) + { + p = (p ? p - 1 : PRINTLINE_CACHE_SIZE - 1); + } + static INLINE void nextPlannerIndex(ufast8_t& p) + { + p = (p == PRINTLINE_CACHE_SIZE - 1 ? 0 : p + 1); + } +#if NONLINEAR_SYSTEM + static uint8_t queueNonlinearMove(uint8_t check_endstops,uint8_t pathOptimize, uint8_t softEndstop); + static inline void queueEMove(int32_t e_diff,uint8_t check_endstops,uint8_t pathOptimize); + inline uint16_t calculateNonlinearSubSegments(uint8_t softEndstop); + static inline void calculateDirectionAndDelta(int32_t difference[], ufast8_t *dir, int32_t delta[]); + static inline uint8_t calculateDistance(float axis_diff[], uint8_t dir, float *distance); +#if SOFTWARE_LEVELING && DRIVE_SYSTEM == DELTA + static void calculatePlane(int32_t factors[], int32_t p1[], int32_t p2[], int32_t p3[]); + static float calcZOffset(int32_t factors[], int32_t pointX, int32_t pointY); +#endif +#endif +}; + + + +#endif // MOTION_H_INCLUDED diff --git a/trunk/Arduino/Repetier_0.92.9/pins.h b/trunk/Arduino/Repetier_0.92.9/pins.h new file mode 100644 index 00000000..c22d576d --- /dev/null +++ b/trunk/Arduino/Repetier_0.92.9/pins.h @@ -0,0 +1,2860 @@ +#ifndef PINS_H +#define PINS_H + +/* +The board assignment defines the capabilities of the motherboard and the used pins. +Each board definition follows the following scheme: + +CPU_ARCH + ARCH_AVR for AVR based boards + ARCH_ARM for all arm based boards + +STEPPER_CURRENT_CONTROL + CURRENT_CONTROL_MANUAL 1 // mechanical poti, default if not defined + CURRENT_CONTROL_DIGIPOT 2 // Use a digipot like RAMBO does + CURRENT_CONTROL_LTC2600 3 // Use LTC2600 like Foltyn 3D Master + CURRENT_CONTROL_ALLIGATOR 4 //Use External DAC like Alligator +*/ + +#define ARCH_AVR 1 +#define ARCH_ARM 2 + +#define CURRENT_CONTROL_MANUAL 1 // mechanical poti, default if not defined +#define CURRENT_CONTROL_DIGIPOT 2 // Use a digipot like RAMBO does +#define CURRENT_CONTROL_LTC2600 3 // Use LTC2600 like Foltyn 3D Master +#define CURRENT_CONTROL_ALLIGATOR 4 //Use External DAC like Alligator +#define CURRENT_CONTROL_MCP4728 5 // Use an i2c DAC as a digipot like PrintrBoard Rev. F + +/**************************************************************************************** +* Arduino pin assignment +* +* ATMega168 +* +-\/-+ +* PC6 1| |28 PC5 (AI 5 / D19) +* (D 0) PD0 2| |27 PC4 (AI 4 / D18) +* (D 1) PD1 3| |26 PC3 (AI 3 / D17) +* (D 2) PD2 4| |25 PC2 (AI 2 / D16) +* PWM+ (D 3) PD3 5| |24 PC1 (AI 1 / D15) +* (D 4) PD4 6| |23 PC0 (AI 0 / D14) +* VCC 7| |22 GND +* GND 8| |21 AREF +* PB6 9| |20 AVCC +* PB7 10| |19 PB5 (D 13) +* PWM+ (D 5) PD5 11| |18 PB4 (D 12) +* PWM+ (D 6) PD6 12| |17 PB3 (D 11) PWM +* (D 7) PD7 13| |16 PB2 (D 10) PWM +* (D 8) PB0 14| |15 PB1 (D 9) PWM +* +----+ +****************************************************************************************/ +#if MOTHERBOARD == 0 +#define KNOWN_BOARD 1 + +#ifndef __AVR_ATmega168__ +#error Oops! Make sure you have 'Arduino Diecimila' selected from the boards menu. +#endif + +#define ORIG_X_STEP_PIN 2 +#define ORIG_X_DIR_PIN 3 +#define ORIG_X_ENABLE_PIN -1 +#define ORIG_X_MIN_PIN 4 +#define ORIG_X_MAX_PIN 9 + +#define ORIG_Y_STEP_PIN 10 +#define ORIG_Y_DIR_PIN 7 +#define ORIG_Y_ENABLE_PIN -1 +#define ORIG_Y_MIN_PIN 8 +#define ORIG_Y_MAX_PIN 13 + +#define ORIG_Z_STEP_PIN 19 +#define ORIG_Z_DIR_PIN 18 +#define ORIG_Z_ENABLE_PIN 5 +#define ORIG_Z_MIN_PIN 17 +#define ORIG_Z_MAX_PIN 16 + +#define ORIG_E0_STEP_PIN 11 +#define ORIG_E0_DIR_PIN 12 +#define ORIG_E0_ENABLE_PIN -1 + +#define SDPOWER -1 +#define SDSS -1 +#define LED_PIN -1 +#define ORIG_FAN_PIN -1 +#define ORIG_PS_ON_PIN 15 + +#define HEATER_0_PIN 6 +// MUST USE ANALOG INPUT NUMBERING NOT DIGITAL OUTPUT NUMBERING!!!!!!!!! +#define TEMP_0_PIN 0 + + +#endif + + + +/**************************************************************************************** +* Sanguino/RepRap Motherboard with direct-drive extruders +* +* ATMega644P +* +* +---\/---+ +* (D 0) PB0 1| |40 PA0 (AI 0 / D31) +* (D 1) PB1 2| |39 PA1 (AI 1 / D30) +* INT2 (D 2) PB2 3| |38 PA2 (AI 2 / D29) +* PWM (D 3) PB3 4| |37 PA3 (AI 3 / D28) +* PWM (D 4) PB4 5| |36 PA4 (AI 4 / D27) +* MOSI (D 5) PB5 6| |35 PA5 (AI 5 / D26) +* MISO (D 6) PB6 7| |34 PA6 (AI 6 / D25) +* SCK (D 7) PB7 8| |33 PA7 (AI 7 / D24) +* RST 9| |32 AREF +* VCC 10| |31 GND +* GND 11| |30 AVCC +* XTAL2 12| |29 PC7 (D 23) +* XTAL1 13| |28 PC6 (D 22) +* RX0 (D 8) PD0 14| |27 PC5 (D 21) TDI +* TX0 (D 9) PD1 15| |26 PC4 (D 20) TDO +* INT0 RX1 (D 10) PD2 16| |25 PC3 (D 19) TMS +* INT1 TX1 (D 11) PD3 17| |24 PC2 (D 18) TCK +* PWM (D 12) PD4 18| |23 PC1 (D 17) SDA +* PWM (D 13) PD5 19| |22 PC0 (D 16) SCL +* PWM (D 14) PD6 20| |21 PD7 (D 15) PWM +* +--------+ +* +****************************************************************************************/ +#if MOTHERBOARD == 1 +#define KNOWN_BOARD 1 + +#ifndef __AVR_ATmega644P__ +#error Oops! Make sure you have 'Sanguino' selected from the 'Tools -> Boards' menu. +#endif + +#define ORIG_X_STEP_PIN 15 +#define ORIG_X_DIR_PIN 18 +#define ORIG_X_ENABLE_PIN 19 +#define ORIG_X_MIN_PIN 20 +#define ORIG_X_MAX_PIN 21 + +#define ORIG_Y_STEP_PIN 23 +#define ORIG_Y_DIR_PIN 22 +#define ORIG_Y_ENABLE_PIN 19 +#define ORIG_Y_MIN_PIN 25 +#define ORIG_Y_MAX_PIN 26 + +#define ORIG_Z_STEP_PIN 29 +#define ORIG_Z_DIR_PIN 30 +#define ORIG_Z_ENABLE_PIN 31 +#define ORIG_Z_MIN_PIN 2 +#define ORIG_Z_MAX_PIN 1 + +#define ORIG_E0_STEP_PIN 12 +#define ORIG_E0_DIR_PIN 16 +#define ORIG_E0_ENABLE_PIN 3 + +#define SDPOWER -1 +#define SDSS -1 +#define LED_PIN 0 +#define ORIG_FAN_PIN -1 +#define ORIG_PS_ON_PIN -1 + +#define HEATER_0_PIN 14 +//D27 // MUST USE ANALOG INPUT NUMBERING NOT DIGITAL OUTPUT NUMBERING!!!!!!!!! +#define TEMP_0_PIN 4 +#define HEATER_1_PIN -1 +#define TEMP_1_PIN -1 +#define HEATER_2_PIN -1 +#define TEMP_2_PIN -1 + +/* 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) */ + +#define E0_PINS ORIG_E0_STEP_PIN,ORIG_E0_DIR_PIN,ORIG_E0_ENABLE_PIN, +#define E1_PINS + + +#endif + +#if MOTHERBOARD == 91 +#define KNOWN_BOARD 1 + +#if !defined(__AVR_ATmega644P__) && !defined(__AVR_ATmega1284P__) && !defined(__AVR_ATmega644__) && !defined(__AVR_ATmega1284__) +#error Oops! Make sure you have 'OMC with Atmega644 at 20 Mhz' selected from the 'Tools -> Boards' menu. +#endif + +#define ORIG_X_STEP_PIN 26 +#define ORIG_X_DIR_PIN 25 +#define ORIG_X_ENABLE_PIN 10 +#define ORIG_X_MIN_PIN 0 +#define ORIG_X_MAX_PIN -1 + +#define ORIG_Y_STEP_PIN 28 +#define ORIG_Y_DIR_PIN 27 +#define ORIG_Y_ENABLE_PIN 10 +#define ORIG_Y_MIN_PIN 1 +#define ORIG_Y_MAX_PIN -1 + +#define ORIG_Z_STEP_PIN 23 +#define ORIG_Z_DIR_PIN 22 +#define ORIG_Z_ENABLE_PIN 10 +#define ORIG_Z_MIN_PIN 2 +#define ORIG_Z_MAX_PIN -1 + +#define ORIG_E0_STEP_PIN 24 +#define ORIG_E0_DIR_PIN 21 +#define ORIG_E0_ENABLE_PIN 10 + +#define PROBE_PIN 13 + +#define SDPOWER -1 +#define SDSS -1 +#define LED_PIN -1 +#define ORIG_FAN_PIN 14 +#define ORIG_PS_ON_PIN -1 + +#define ORIG_SDCARDDETECT -1 + +#define HEATER_0_PIN 3 +#define TEMP_0_PIN 0 +#define HEATER_1_PIN 4 +#define TEMP_1_PIN 1 +#define HEATER_2_PIN -1 +#define TEMP_2_PIN 2 + +#define SCK_PIN 7 +#define MISO_PIN 6 +#define MOSI_PIN 5 + +#define E0_PINS ORIG_E0_STEP_PIN,ORIG_E0_DIR_PIN,ORIG_E0_ENABLE_PIN, + +#endif + +/**************************************************************************************** +* RepRap Motherboard ****---NOOOOOO RS485/EXTRUDER CONTROLLER!!!!!!!!!!!!!!!!!---******* +* +****************************************************************************************/ +#if MOTHERBOARD == 2 +#define KNOWN_BOARD 1 + +#ifndef __AVR_ATmega644P__ +#error Oops! Make sure you have 'Sanguino' selected from the 'Tools -> Boards' menu. +#endif + +#define ORIG_X_STEP_PIN 15 +#define ORIG_X_DIR_PIN 18 +#define ORIG_X_ENABLE_PIN 19 +#define ORIG_X_MIN_PIN 20 +#define ORIG_X_MAX_PIN 21 + +#define ORIG_Y_STEP_PIN 23 +#define ORIG_Y_DIR_PIN 22 +#define ORIG_Y_ENABLE_PIN 24 +#define ORIG_Y_MIN_PIN 25 +#define ORIG_Y_MAX_PIN 26 + +#define ORIG_Z_STEP_PINN 27 +#define ORIG_Z_DIR_PINN 28 +#define ORIG_Z_ENABLE_PIN 29 +#define ORIG_Z_MIN_PIN 30 +#define ORIG_Z_MAX_PIN 31 + +#define ORIG_E0_STEP_PIN 17 +#define ORIG_E0_DIR_PIN 16 +#define ORIG_E0_ENABLE_PIN -1 + +#define SDPOWER -1 +#define SDSS 4 +#define LED_PIN 0 + +#define SD_CARD_WRITE 2 +#define SD_CARD_DETECT 3 +#define SD_CARD_SELECT 4 + +//our RS485 pins +#define TX_ENABLE_PIN 12 +#define RX_ENABLE_PIN 13 + +//pin for controlling the PSU. +#define ORIG_PS_ON_PIN 14 + +#define ORIG_FAN_PIN -1 + +#define HEATER_0_PIN -1 +// MUST USE ANALOG INPUT NUMBERING NOT DIGITAL OUTPUT NUMBERING!!!!!!!!! +#define TEMP_0_PIN -1 + + +#define E0_PINS ORIG_E0_STEP_PIN,ORIG_E0_DIR_PIN,ORIG_E0_ENABLE_PIN, +#define E1_PINS + + +#endif + +/**************************************************************************************** +* Gen3 PLUS for RepRap Motherboard V1.2 +* +****************************************************************************************/ +#if MOTHERBOARD == 21 +#define KNOWN_BOARD 1 + +#ifndef __AVR_ATmega644P__ +#error Oops! Make sure you have 'Sanguino' selected from the 'Tools -> Boards' menu. +#endif + +//x axis pins +#define ORIG_X_STEP_PIN 15 +#define ORIG_X_DIR_PIN 18 +#define ORIG_X_ENABLE_PIN 19 +#define ORIG_X_MIN_PIN 20 +#define ORIG_X_MAX_PIN -1 + +//y axis pins +#define ORIG_Y_STEP_PIN 23 +#define ORIG_Y_DIR_PIN 22 +#define ORIG_Y_ENABLE_PIN 24 +#define ORIG_Y_MIN_PIN 25 +#define ORIG_Y_MAX_PIN -1 + +//z axis pins +#define ORIG_Z_STEP_PIN 27 +#define ORIG_Z_DIR_PIN 28 +#define ORIG_Z_ENABLE_PIN 29 +#define ORIG_Z_MIN_PIN 30 +#define ORIG_Z_MAX_PIN -1 + +#define ORIG_E0_DIR_PIN 21 +#define ORIG_E0_STEP_PIN 17 +#define ORIG_E0_ENABLE_PIN 13 + +//heaters +// hot end heater +#define HEATER_0_PIN 12 +// heated bed heater +#define HEATER_1_PIN 16 +#define HEATER_2_PIN -1 +#define TEMP_2_PIN -1 + +//pin for debugging. +#define DEBUG_PIN -1 +//SD card pin +#define SDSS 4 +#define SDPOWER -1 +#define ORIG_FAN_PIN -1 +#define TEMP_0_PIN 0 +#define TEMP_1_PIN 5 +#define LED_PIN -1 + +//pin for controlling the PSU. +#define ORIG_PS_ON_PIN 14 +#define E0_PINS ORIG_E0_STEP_PIN,ORIG_E0_DIR_PIN,ORIG_E0_ENABLE_PIN, +#define E1_PINS +#endif +//----------end Gen3 PLUS for RepRap Motherboard V1.2-------------- + +/**************************************************************************************** +* Arduino Mega pin assignment +* +****************************************************************************************/ +#if MOTHERBOARD == 33 +#define KNOWN_BOARD 1 +#define RAMPS_V_1_3 +#elif MOTHERBOARD == 34 +#define KNOWN_BOARD 1 +#define RAMPS_V_1_3 +#define AZTEEG_X3 +#elif MOTHERBOARD == 35 +#define KNOWN_BOARD 1 +#define RAMPS_V_1_3 +#define AZTEEG_X3_PRO +#endif +#if MOTHERBOARD == 3 || MOTHERBOARD == 33 || MOTHERBOARD == 34 || MOTHERBOARD == 35 +#define KNOWN_BOARD 1 + +#if !(defined (__AVR_ATmega1280__ ) || defined (__AVR_ATmega2560__ )) +#error Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu. +#endif + +// uncomment one of the following lines for RAMPS v1.3 or v1.0, comment both for v1.2 or 1.1 +// #define RAMPS_V_1_3 +// #define RAMPS_V_1_0 + +#ifdef RAMPS_V_1_3 + +#define ORIG_X_STEP_PIN 54 +#define ORIG_X_DIR_PIN 55 +#define ORIG_X_ENABLE_PIN 38 +#define ORIG_X_MIN_PIN 3 +#define ORIG_X_MAX_PIN 2 + +#define ORIG_Y_STEP_PIN 60 +#define ORIG_Y_DIR_PIN 61 +#define ORIG_Y_ENABLE_PIN 56 +#define ORIG_Y_MIN_PIN 14 +#define ORIG_Y_MAX_PIN 15 + +#define ORIG_Z_STEP_PIN 46 +#define ORIG_Z_DIR_PIN 48 +#define ORIG_Z_ENABLE_PIN 62 +#define ORIG_Z_MIN_PIN 18 +#define ORIG_Z_MAX_PIN 19 + +#define ORIG_E0_STEP_PIN 26 +#define ORIG_E0_DIR_PIN 28 +#define ORIG_E0_ENABLE_PIN 24 + +#define ORIG_E1_STEP_PIN 36 +#define ORIG_E1_DIR_PIN 34 +#define ORIG_E1_ENABLE_PIN 30 + +#define SDPOWER -1 +#define SDSS 53 +#define ORIG_SDCARDDETECT 49 + +#define LED_PIN 13 +#define ORIG_FAN_PIN 9 +#define ORIG_PS_ON_PIN 12 + +#define HEATER_0_PIN 10 +#define HEATER_1_PIN 8 +#define HEATER_2_PIN 9 +// ANALOG NUMBERING +#define TEMP_0_PIN 13 +#define TEMP_1_PIN 14 +#define TEMP_2_PIN 15 +#define E0_PINS ORIG_E0_STEP_PIN,ORIG_E0_DIR_PIN,ORIG_E0_ENABLE_PIN, +#define E1_PINS ORIG_E1_STEP_PIN,ORIG_E1_DIR_PIN,ORIG_E1_ENABLE_PIN, + + +#else // RAMPS_V_1_1 or RAMPS_V_1_2 as default + +#define ORIG_X_STEP_PIN 26 +#define ORIG_X_DIR_PIN 28 +#define ORIG_X_ENABLE_PIN 24 +#define ORIG_X_MIN_PIN 3 +#define ORIG_X_MAX_PIN -1 //2 + +#define ORIG_Y_STEP_PIN 38 +#define ORIG_Y_DIR_PIN 40 +#define ORIG_Y_ENABLE_PIN 36 +#define ORIG_Y_MIN_PIN 16 +#define ORIG_Y_MAX_PIN -1 //17 + +#define ORIG_Z_STEP_PIN 44 +#define ORIG_Z_DIR_PIN 46 +#define ORIG_Z_ENABLE_PIN 42 +#define ORIG_Z_MIN_PIN 18 +#define ORIG_Z_MAX_PIN -1 //19 + +#define ORIG_E0_STEP_PIN 32 +#define ORIG_E0_DIR_PIN 34 +#define ORIG_E0_ENABLE_PIN 30 + +#define SDPOWER 48 +#define SDSS 53 +#define LED_PIN 13 +#define ORIG_PS_ON_PIN -1 +//#define SCL 21 +//#define SDA 20 + +#define E0_PINS ORIG_E0_STEP_PIN,ORIG_E0_DIR_PIN,ORIG_E0_ENABLE_PIN, +#define E1_PINS + + +#ifdef RAMPS_V_1_0 // RAMPS_V_1_0 +#define HEATER_0_PIN 12 +#define HEATER_1_PIN -1 +#define ORIG_FAN_PIN 11 + +#else // RAMPS_V_1_1 or RAMPS_V_1_2 +#define HEATER_0_PIN 10 +#define HEATER_1_PIN 8 +#define ORIG_FAN_PIN 9 +#endif + +// MUST USE ANALOG INPUT NUMBERING NOT DIGITAL OUTPUT NUMBERING!!!!!!!!! +#define TEMP_0_PIN 2 +#define TEMP_1_PIN 1 +#endif + +// SPI for Max6675 Thermocouple + +// these pins are defined in the SD library if building with SD support +#define SCK_PIN 52 +#define MISO_PIN 50 +#define MOSI_PIN 51 +#define MAX6675_SS 53 + +#ifdef AZTEEG_X3 +#define SDSUPPORT 1 +#define SDCARDDETECTINVERTED 0 +#define ORIG_SDCARDDETECT 49 +#define ORIG_FAN_PIN 4 +#define ORIG_FAN2_PIN 5 +#define LIGHT_PIN 6 +// Activate beeper on extension shield +#define BEEPER_PIN 33 +#define BEEPER_TYPE 1 + +// Only available with X3 shield +#define ORIG_E2_STEP_PIN 27 +#define ORIG_E2_DIR_PIN 29 +#define ORIG_E2_ENABLE_PIN 41 +// Only available with X3 shield +#define ORIG_E3_STEP_PIN 23 +#define ORIG_E3_DIR_PIN 25 +#define ORIG_E3_ENABLE_PIN 40 +// Only available with X3 shield +#define HEATER_3_PIN 17 +#define TEMP_3_PIN 12 +#define HEATER_4_PIN 16 +#define TEMP_4_PIN 5 + + +#define E1_PINS ORIG_E1_STEP_PIN,ORIG_E1_DIR_PIN,ORIG_E1_ENABLE_PIN, +#define E2_PINS ORIG_E2_STEP_PIN,ORIG_E2_DIR_PIN,ORIG_E2_ENABLE_PIN, +#define E3_PINS E3_STEP_PIN,E3_DIR_PIN,E3_ENABLE_PIN, + +#endif + +#ifdef AZTEEG_X3_PRO +#define SDSUPPORT true +#define SDCARDDETECTINVERTED false +#define ORIG_SDCARDDETECT 49 +#define SDSS 53 +#undef ORIG_FAN_PIN +#define ORIG_FAN_PIN 5 +#define ORIG_FAN2_PIN 6 +#define LIGHT_PIN 11 +// Activate beeper on extension shield +#define BEEPER_PIN 33 +#define BEEPER_TYPE 1 + +#define ORIG_E2_STEP_PIN 23 +#define ORIG_E2_DIR_PIN 25 +#define ORIG_E2_ENABLE_PIN 40 +#define ORIG_E3_STEP_PIN 27 +#define ORIG_E3_DIR_PIN 29 +#define ORIG_E3_ENABLE_PIN 41 +#define ORIG_E4_STEP_PIN 43 +#define ORIG_E4_DIR_PIN 37 +#define ORIG_E4_ENABLE_PIN 42 +#define HEATER_0_PIN 10 +// bed +#define HEATER_1_PIN 8 +#define HEATER_2_PIN 9 +#define HEATER_3_PIN 16 +#define HEATER_4_PIN 17 +#define HEATER_5_PIN 4 +// ANALOG NUMBERING +#define TEMP_0_PIN 13 +// BED , ANALOG NUMBERING +#define TEMP_1_PIN 14 +#define TEMP_2_PIN 15 +#define TEMP_3_PIN 12 +#define TEMP_4_PIN 11 +#define TEMP_5_PIN 10 + +// Thermocouple 1 and 2 +#define TEMP_6_PIN 4 +#define TEMP_7_PIN 5 +#define THERMOCOUPLE_0_PIN 4 +#define THERMOCOUPLE_1_PIN 5 + + +#define E1_PINS ORIG_E1_STEP_PIN,ORIG_E1_DIR_PIN,ORIG_E1_ENABLE_PIN, +#define E2_PINS ORIG_E2_STEP_PIN,ORIG_E2_DIR_PIN,ORIG_E2_ENABLE_PIN, +#define E3_PINS ORIG_E3_STEP_PIN,ORIG_E3_DIR_PIN,ORIG_E3_ENABLE_PIN, +#define E4_PINS ORIG_E4_STEP_PIN,ORIG_E4_DIR_PIN,ORIG_E4_ENABLE_PIN, + +#endif + +#endif + +/**************************************************************************************** +* Ultimaker Shield pin assignment v1.5.7 +* +****************************************************************************************/ +#if MOTHERBOARD == 37 +#define ULTIMAKER_157 +#define KNOWN_BOARD 1 + +#define ORIG_X_STEP_PIN 25 +#define ORIG_X_DIR_PIN 23 +#define ORIG_X_MIN_PIN 22 +#define ORIG_X_MAX_PIN 24 +#define ORIG_X_ENABLE_PIN 27 + +#define ORIG_Y_STEP_PIN 31 +#define ORIG_Y_DIR_PIN 33 +#define ORIG_Y_MIN_PIN 26 +#define ORIG_Y_MAX_PIN 28 +#define ORIG_Y_ENABLE_PIN 29 + +#define ORIG_Z_STEP_PIN 37 +#define ORIG_Z_DIR_PIN 39 +#define ORIG_Z_MIN_PIN 30 +#define ORIG_Z_MAX_PIN 32 +#define ORIG_Z_ENABLE_PIN 35 + + // bed +#define HEATER_1_PIN 4 +#define TEMP_1_PIN 10 + +#define HEATER_0_PIN 2 +#define TEMP_0_PIN 8 + +#define HEATER_2_PIN 3 +#define TEMP_2_PIN 9 + +#define HEATER_3_PIN -1 +#define TEMP_3_PIN -1 + +#define ORIG_E0_STEP_PIN 43 +#define ORIG_E0_DIR_PIN 45 +#define ORIG_E0_ENABLE_PIN 41 +#define E0_FAN_PIN -1 +// #define EXT1_EXTRUDER_COOLER_PIN E0_FAN_PIN + +#define ORIG_E1_STEP_PIN 49 +#define ORIG_E1_DIR_PIN 47 +#define ORIG_E1_ENABLE_PIN 48 +#define E1_FAN_PIN -1 +// #define EXT2_EXTRUDER_COOLER_PIN E1_FAN_PIN + +#define LED_PIN 13 +#define ORIG_FAN_PIN 7 +#define ORIG_PS_ON_PIN 12 +#define KILL_PIN -1 +//PIN that has to be turned on right after start, to keep power flowing. +#define SUICIDE_PIN 54 + +#define SCK_PIN 52 +#define MISO_PIN 50 +#define MOSI_PIN 51 +#define SDPOWER -1 +#define SDSS 53 +#define ORIG_SDCARDDETECT 38 + +#define E0_PINS ORIG_E0_STEP_PIN,ORIG_E0_DIR_PIN,ORIG_E0_ENABLE_PIN, +#define E1_PINS ORIG_E1_STEP_PIN,ORIG_E1_DIR_PIN,ORIG_E1_ENABLE_PIN, + +#endif + +/**************************************************************************************** +* RUMBA pin assignment +* +****************************************************************************************/ +#if MOTHERBOARD == 80 +#define KNOWN_BOARD 1 + +#ifndef __AVR_ATmega2560__ +#error Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu. +#endif + +#define ORIG_X_STEP_PIN 17 +#define ORIG_X_DIR_PIN 16 +#define ORIG_X_ENABLE_PIN 48 +#define ORIG_X_MIN_PIN 37 +#define ORIG_X_MAX_PIN 36 + +#define ORIG_Y_STEP_PIN 54 +#define ORIG_Y_DIR_PIN 47 +#define ORIG_Y_ENABLE_PIN 55 +#define ORIG_Y_MIN_PIN 35 +#define ORIG_Y_MAX_PIN 34 + +#define ORIG_Z_STEP_PIN 57 +#define ORIG_Z_DIR_PIN 56 +#define ORIG_Z_ENABLE_PIN 62 +#define ORIG_Z_MIN_PIN 33 +#define ORIG_Z_MAX_PIN 32 + +#define ORIG_E0_STEP_PIN 23 +#define ORIG_E0_DIR_PIN 22 +#define ORIG_E0_ENABLE_PIN 24 + +#define ORIG_E1_STEP_PIN 26 +#define ORIG_E1_DIR_PIN 25 +#define ORIG_E1_ENABLE_PIN 27 + +#define ORIG_E2_STEP_PIN 29 +#define ORIG_E2_DIR_PIN 28 +#define ORIG_E2_ENABLE_PIN 39 + +#define LED_PIN 13 + +#define ORIG_FAN_PIN 7 +#define ORIG_FAN2_PIN 8 // (e.g. useful for electronics fan or light on/off) on PIN 8 + +#define ORIG_PS_ON_PIN 45 + + // EXTRUDER 1 +#define HEATER_0_PIN 2 +// EXTRUDER 2 +#define HEATER_2_PIN 3 +// EXTRUDER 3 +#define HEATER_3_PIN 6 +//optional FAN1 can be used as 4th heater output: #define HEATER_4_PIN 8 // EXTRUDER 4 + // BED +#define HEATER_1_PIN 9 + +// ANALOG NUMBERING +#define TEMP_0_PIN 15 +#define TEMP_2_PIN 14 +#define TEMP_3_PIN 13 +//optional for extruder 4 or chamber: #define TEMP_2_PIN 12 // ANALOG NUMBERING +#define TEMP_1_PIN 11 + +#define SDPOWER -1 +#define SDSS 53 +#define SCK_PIN 52 +#define MISO_PIN 50 +#define MOSI_PIN 51 + +#define E0_PINS ORIG_E0_STEP_PIN,ORIG_E0_DIR_PIN,ORIG_E0_ENABLE_PIN, +#define E1_PINS ORIG_E1_STEP_PIN,ORIG_E1_DIR_PIN,ORIG_E1_ENABLE_PIN, +#define E2_PINS ORIG_E2_STEP_PIN,ORIG_E2_DIR_PIN,ORIG_E2_ENABLE_PIN, + +#endif //MOTHERBOARD==80 + +/**************************************************************************************** +* Duemilanove w/ ATMega328P pin assignment +* +****************************************************************************************/ +#if MOTHERBOARD == 4 +#define KNOWN_BOARD 1 + +#ifndef __AVR_ATmega328P__ +#error Oops! Make sure you have 'Arduino Duemilanove w/ ATMega328' selected from the 'Tools -> Boards' menu. +#endif + +#define ORIG_X_STEP_PIN 19 +#define ORIG_X_DIR_PIN 18 +#define ORIG_X_ENABLE_PIN -1 +#define ORIG_X_MIN_PIN 17 +#define ORIG_X_MAX_PIN -1 + +#define ORIG_Y_STEP_PIN 10 +#define ORIG_Y_DIR_PIN 7 +#define ORIG_Y_ENABLE_PIN -1 +#define ORIG_Y_MIN_PIN 8 +#define ORIG_Y_MAX_PIN -1 + +#define ORIG_Z_STEP_PIN 13 +#define ORIG_Z_DIR_PIN 3 +#define ORIG_Z_ENABLE_PIN 2 +#define ORIG_Z_MIN_PIN 4 +#define ORIG_Z_MAX_PIN -1 + +#define ORIG_E0_STEP_PIN 11 +#define ORIG_E0_DIR_PIN 12 +#define ORIG_E0_ENABLE_PIN -1 + +#define SDPOWER -1 +#define SDSS -1 +#define LED_PIN -1 +#define ORIG_FAN_PIN 5 +#define ORIG_PS_ON_PIN -1 + +#define HEATER_0_PIN 6 +// MUST USE ANALOG INPUT NUMBERING NOT DIGITAL OUTPUT NUMBERING!!!!!!!!! +#define TEMP_0_PIN 0 +#define E0_PINS ORIG_E0_STEP_PIN,ORIG_E0_DIR_PIN,ORIG_E0_ENABLE_PIN, +#define E1_PINS + + +#endif + +/**************************************************************************************** +* Gen6 pin assignment (5) and Gen6 deluxe assignment (51) +* +****************************************************************************************/ +#if MOTHERBOARD == 5 || MOTHERBOARD == 51 +#define KNOWN_BOARD 1 + +#if !defined(__AVR_ATmega644P__) && !defined(__AVR_ATmega1284P__) +#error Oops! Make sure you have 'Sanguino' selected from the 'Tools -> Boards' menu. +#endif + +//x axis pins +#define ORIG_X_STEP_PIN 15 +#define ORIG_X_DIR_PIN 18 +#define ORIG_X_ENABLE_PIN 19 +#define ORIG_X_MIN_PIN 20 +#define ORIG_X_MAX_PIN -1 + +//y axis pins +#define ORIG_Y_STEP_PIN 23 +#define ORIG_Y_DIR_PIN 22 +#define ORIG_Y_ENABLE_PIN 24 +#define ORIG_Y_MIN_PIN 25 +#define ORIG_Y_MAX_PIN -1 + +//z axis pins +#define ORIG_Z_STEP_PIN 27 +#define ORIG_Z_DIR_PIN 28 +#define ORIG_Z_ENABLE_PIN 29 +#define ORIG_Z_MIN_PIN 30 +#define ORIG_Z_MAX_PIN -1 + +//extruder pins +#define ORIG_E0_STEP_PIN 4 +#define ORIG_E0_DIR_PIN 2 +#define ORIG_E0_ENABLE_PIN 3 +#define TEMP_0_PIN 5 +#define HEATER_0_PIN 14 +#if MOTHERBOARD == 5 +#define HEATER_1_PIN -1 +#define TEMP_1_PIN -1 +#else +#define HEATER_1_PIN 1 +#define TEMP_1_PIN 0 +#endif +#define HEATER_2_PIN -1 +#define TEMP_2_PIN -1 + + +#define SDPOWER -1 +// SCL pin of I2C header +#define SDSS 16 +#define LED_PIN -1 +#define ORIG_FAN_PIN -1 +#define ORIG_PS_ON_PIN -1 +//our pin for debugging. + +#define DEBUG_PIN 0 + +//our RS485 pins +#define TX_ENABLE_PIN 12 +#define RX_ENABLE_PIN 13 +#define E0_PINS ORIG_E0_STEP_PIN,ORIG_E0_DIR_PIN,ORIG_E0_ENABLE_PIN, +#define E1_PINS + +#define SCK_PIN 7 +#define MISO_PIN 6 +#define MOSI_PIN 5 + +// #define SCL 16 +// #define SDA 17 + +#endif +/**************************************************************************************** +* Sanguinololu pin assignment +* +****************************************************************************************/ +#if MOTHERBOARD == 62 +#define SANGUINOLOLU_V_1_2 +#endif +#if MOTHERBOARD == 65 +#define AZTEEG_X1 +#define SANGUINOLOLU_V_1_2 +#endif + +#if MOTHERBOARD == 6 || MOTHERBOARD == 62 || MOTHERBOARD == 65 +#define KNOWN_BOARD 1 +//#ifndef __AVR_ATmega644P__ +#if !defined(__AVR_ATmega644P__) && !defined(__AVR_ATmega1284P__) +#error Oops! Make sure you have 'Sanguino' selected from the 'Tools -> Boards' menu. +#endif + +#define ORIG_X_STEP_PIN 15 +#define ORIG_X_DIR_PIN 21 +#define ORIG_X_MIN_PIN 18 +#define ORIG_X_MAX_PIN -2 + +#define ORIG_Y_STEP_PIN 22 +#define ORIG_Y_DIR_PIN 23 +#define ORIG_Y_MIN_PIN 19 +#define ORIG_Y_MAX_PIN -1 + +#define ORIG_Z_STEP_PIN 3 +#define ORIG_Z_DIR_PIN 2 +#define ORIG_Z_MIN_PIN 20 +#define ORIG_Z_MAX_PIN -1 + +#define ORIG_E0_STEP_PIN 1 +#define ORIG_E0_DIR_PIN 0 + +#define LED_PIN -1 + +#define ORIG_FAN_PIN -1 + +#define ORIG_PS_ON_PIN -1 + +// (extruder) +#define HEATER_0_PIN 13 + +#ifdef SANGUINOLOLU_V_1_2 + +// (bed) +#define HEATER_1_PIN 12 +#define ORIG_X_ENABLE_PIN 14 +#define ORIG_Y_ENABLE_PIN 14 +#define ORIG_Z_ENABLE_PIN 26 +#define ORIG_E0_ENABLE_PIN 14 + +#else + +#define HEATER_1_PIN 14 // (bed) +#define ORIG_X_ENABLE_PIN -1 +#define ORIG_Y_ENABLE_PIN -1 +#define ORIG_Z_ENABLE_PIN -1 +#define ORIG_E0_ENABLE_PIN -1 + +#endif + +// MUST USE ANALOG INPUT NUMBERING NOT DIGITAL OUTPUT NUMBERING!!!!!!!!! (pin 33 extruder) +#define TEMP_0_PIN 7 +// MUST USE ANALOG INPUT NUMBERING NOT DIGITAL OUTPUT NUMBERING!!!!!!!!! (pin 34 bed) +#define TEMP_1_PIN 6 +#define SDPOWER -1 +#define SDSS 31 +#define SCK_PIN 7 +#define MISO_PIN 6 +#define MOSI_PIN 5 +#define HEATER_2_PIN -1 +#define TEMP_2_PIN -1 + +#ifdef AZTEEG_X1 +#define ORIG_FAN_PIN 4 +#endif + +#define E0_PINS ORIG_E0_STEP_PIN,ORIG_E0_DIR_PIN,ORIG_E0_ENABLE_PIN, +#define E1_PINS +#define E2_PINS + +#ifndef KNOWN_BOARD +#error Unknown MOTHERBOARD value in configuration.h +#endif + +#endif + +/**************************************************************************************** +* Melzi pin assignment +* +****************************************************************************************/ +#if MOTHERBOARD == 63 +#define KNOWN_BOARD 1 +#ifndef __AVR_ATmega644P__ +#ifndef __AVR_ATmega1284P__ +//#error Oops! Make sure you have 'Sanguino' selected from the 'Tools -> Boards' menu. +#endif +#endif + +#define ORIG_X_STEP_PIN 15 +#define ORIG_X_DIR_PIN 21 +#define ORIG_X_MIN_PIN 18 +#define ORIG_X_MAX_PIN -2 + +#define ORIG_Y_STEP_PIN 22 +#define ORIG_Y_DIR_PIN 23 +#define ORIG_Y_MIN_PIN 19 +#define ORIG_Y_MAX_PIN -1 + +#define ORIG_Z_STEP_PIN 3 +#define ORIG_Z_DIR_PIN 2 +#define ORIG_Z_MIN_PIN 20 +#define ORIG_Z_MAX_PIN -1 + +#define ORIG_E0_STEP_PIN 1 +#define ORIG_E0_DIR_PIN 0 +#define ORIG_E0_ENABLE_PIN 14 + +//29 on Melzi1284p A2 +#define PROBE_PIN -1 + +#define LED_PIN 27 + +#define ORIG_FAN_PIN 4 + +#define ORIG_PS_ON_PIN -1 + +// (extruder) +#define HEATER_0_PIN 13 +#define HEATER_2_PIN -1 +// bed (change to 12 for breakout pin on header) +#define HEATER_1_PIN 10 + +#define ORIG_X_ENABLE_PIN 14 +#define ORIG_Y_ENABLE_PIN 14 +#define ORIG_Z_ENABLE_PIN 26 + +// MUST USE ANALOG INPUT NUMBERING NOT DIGITAL OUTPUT NUMBERING!!!!!!!!! (pin 33 extruder) +#define TEMP_0_PIN 7 +// MUST USE ANALOG INPUT NUMBERING NOT DIGITAL OUTPUT NUMBERING!!!!!!!!! (pin 34 bed) +#define TEMP_1_PIN 6 +#define TEMP_2_PIN -1 +#define SDPOWER -1 +// 31 http://reprap.org/wiki/Melzi#Melzi_Arduino_Pin_Numbers says 31, schamtic show pin 37 = PA0 which is arduino pin 31! +#define SDSS 31 +#define SCK_PIN 7 +#define MISO_PIN 6 +#define MOSI_PIN 5 +#define SDSUPPORT 1 // sd card reader on board +#define ORIG_SDCARDDETECT -1 + +#define E0_PINS ORIG_E0_STEP_PIN,ORIG_E0_DIR_PIN,ORIG_E0_ENABLE_PIN, +#define E1_PINS + +#endif + +#if MOTHERBOARD == 66 +#define KNOWN_BOARD 1 + +#ifndef __AVR_ATmega2560__ +#error Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu. +#endif + +// X/Y/Z Steppers and MIN endstops verified + +#define ORIG_X_STEP_PIN 54 +#define ORIG_X_DIR_PIN 55 +#define ORIG_X_ENABLE_PIN 38 +#define ORIG_X_MIN_PIN 3 +#define ORIG_X_MAX_PIN -1 + +#define ORIG_Y_STEP_PIN 60 +#define ORIG_Y_DIR_PIN 61 +#define ORIG_Y_ENABLE_PIN 56 +#define ORIG_Y_MIN_PIN 14 +#define ORIG_Y_MAX_PIN -1 + +#define ORIG_Z_STEP_PIN 46 +#define ORIG_Z_DIR_PIN 48 +#define ORIG_Z_ENABLE_PIN 63 +#define ORIG_Z_MIN_PIN 18 +#define ORIG_Z_MAX_PIN -1 + +#define ORIG_E0_STEP_PIN 26 +#define ORIG_E0_DIR_PIN 28 +#define ORIG_E0_ENABLE_PIN 24 + +#define ORIG_E1_STEP_PIN -1 +#define ORIG_E1_DIR_PIN -1 +#define ORIG_E1_ENABLE_PIN -1 + +#define SDPOWER -1 +#define SDSS 25 +#define ORIG_SDCARDDETECT -1 + +#define LED_PIN 13 +#define ORIG_FAN_PIN 8 +#define ORIG_PS_ON_PIN -1 + +// schematic: HEATER1 (Extruder) +#define HEATER_0_PIN 10 +// schematic: HEATER2 (Heated Bed) +#define HEATER_1_PIN 9 +#define HEATER_2_PIN -1 + +// ANALOG NUMBERING +// schematic: THERM1 (Extruder) +#define TEMP_0_PIN 13 +// schematic: THERM2 (Heated Bed) +#define TEMP_1_PIN 14 +#define TEMP_2_PIN -1 + +#define E0_PINS ORIG_E0_STEP_PIN,ORIG_E0_DIR_PIN,ORIG_E0_ENABLE_PIN, +#define E1_PINS ORIG_E1_STEP_PIN,ORIG_E1_DIR_PIN,ORIG_E1_ENABLE_PIN, + +// following pins (LCD, ENCODER, SDCARD) reverse engineered from schematic diagram: + +#ifdef ULTRA_LCD +#ifdef NEWPANEL + +#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 BTN_EN1 16 +#define BTN_EN2 17 +#define BTN_ENC 23 + +#endif +#endif //ULTRA_LCD + +#define SCK_PIN 52 +#define MISO_PIN 50 +#define MOSI_PIN 51 +#define MAX6675_SS 53 +#endif + +/**************************************************************************************** +* Gen7 1.1 and above pin assignment +* +****************************************************************************************/ +#if MOTHERBOARD == 7 +#define KNOWN_BOARD 1 + +#if !defined(__AVR_ATmega644P__) && !defined(__AVR_ATmega644__) && !defined(__AVR_ATmega1284P__) +#error Oops! Make sure you have 'Gen7' selected from the 'Tools -> Boards' menu. +#endif + +//x axis pins +#define ORIG_X_STEP_PIN 19 +#define ORIG_X_DIR_PIN 18 +#define ORIG_X_ENABLE_PIN 24 +#define ORIG_X_MIN_PIN 7 +#define ORIG_X_MAX_PIN 6 + +//y axis pins +#define ORIG_Y_STEP_PIN 23 +#define ORIG_Y_DIR_PIN 22 +#define ORIG_Y_ENABLE_PIN 24 +#define ORIG_Y_MIN_PIN 5 +#define ORIG_Y_MAX_PIN 2 + +//z axis pins +#define ORIG_Z_STEP_PIN 26 +#define ORIG_Z_DIR_PIN 25 +#define ORIG_Z_ENABLE_PIN 24 +#define ORIG_Z_MIN_PIN 1 +#define ORIG_Z_MAX_PIN 0 + +//extruder pins +#define ORIG_E0_STEP_PIN 28 +#define ORIG_E0_DIR_PIN 27 +#define ORIG_E0_ENABLE_PIN 24 +#define TEMP_0_PIN 1 +#define TEMP_1_PIN 2 +#define HEATER_0_PIN 4 +#define HEATER_1_PIN 3 +#define HEATER_2_PIN -1 +#define TEMP_2_PIN -1 + + +#define SDPOWER -1 +#define SDSS -1 // SCL pin of I2C header +#define LED_PIN -1 + +#define ORIG_FAN_PIN 31 +#define ORIG_PS_ON_PIN 15 +#define E0_PINS ORIG_E0_STEP_PIN,ORIG_E0_DIR_PIN,ORIG_E0_ENABLE_PIN, +#define E1_PINS + +//our pin for debugging. + +#define DEBUG_PIN 0 + +//our RS485 pins +#define TX_ENABLE_PIN 12 +#define RX_ENABLE_PIN 13 + +#define SCK_PIN 7 +#define SDSSORIG 4 +#define MISO_PIN 6 +#define MOSI_PIN 5 + +#endif +/**************************************************************************************** +* Gen7 1.4.1 pin assignment +* +****************************************************************************************/ +#if MOTHERBOARD == 71 +#define KNOWN_BOARD 1 + +#if !defined(__AVR_ATmega644P__) && !defined(__AVR_ATmega644__) && !defined(__AVR_ATmega1284P__) +#error Oops! Make sure you have 'Gen7' selected from the 'Tools -> Boards' menu. +#endif + +//x axis pins +#define ORIG_X_STEP_PIN 29 +#define ORIG_X_DIR_PIN 28 +#define ORIG_X_ENABLE_PIN 25 +#define ORIG_X_MIN_PIN 0 +#define ORIG_X_MAX_PIN -1 + +//y axis pins +#define ORIG_Y_STEP_PIN 27 +#define ORIG_Y_DIR_PIN 26 +#define ORIG_Y_ENABLE_PIN 25 +#define ORIG_Y_MIN_PIN 1 +#define ORIG_Y_MAX_PIN -1 + +//z axis pins +#define ORIG_Z_STEP_PIN 23 +#define ORIG_Z_DIR_PIN 22 +#define ORIG_Z_ENABLE_PIN 25 +#define ORIG_Z_MIN_PIN 2 +#define ORIG_Z_MAX_PIN -1 + +//extruder pins +#define ORIG_E0_STEP_PIN 19 +#define ORIG_E0_DIR_PIN 18 +#define ORIG_E0_ENABLE_PIN 25 +#define TEMP_0_PIN 1 +#define TEMP_1_PIN 0 +#define HEATER_0_PIN 4 +#define HEATER_1_PIN 3 +#define HEATER_2_PIN -1 +#define TEMP_2_PIN -1 + + +#define SDPOWER -1 +#define SDSS -1 +#define LED_PIN -1 + +#define ORIG_FAN_PIN -1 +#define ORIG_PS_ON_PIN 15 +//our pin for debugging. + +#define DEBUG_PIN 0 + +//our RS485 pins +#define TX_ENABLE_PIN 12 +#define RX_ENABLE_PIN 13 + +#define SDPOWER -1 +#define SDSS -1 +// Needs to set this to output to enable SPI even if other SS is used! +#define SDSSORIG 4 + +#define SCK_PIN 7 +#define MISO_PIN 6 +#define MOSI_PIN 5 +#define E0_PINS ORIG_E0_STEP_PIN,ORIG_E0_DIR_PIN,ORIG_E0_ENABLE_PIN, +#define E1_PINS +#endif + +/**************************************************************************************** +* Sethi 3D_1 Extruder +* +****************************************************************************************/ +#if MOTHERBOARD == 72 +#define KNOWN_BOARD 1 + +#if !defined(__AVR_ATmega644P__) && !defined(__AVR_ATmega644__) && !defined(__AVR_ATmega1284P__) +#error Oops! Make sure you have 'Sethi' selected from the 'Tools -> Boards' menu. +#endif + +//x axis pins +#define ORIG_X_STEP_PIN 19 +#define ORIG_X_DIR_PIN 18 +#define ORIG_X_ENABLE_PIN 24 +#define ORIG_X_MIN_PIN 2 +#define ORIG_X_MAX_PIN 6 + +//y axis pins +#define ORIG_Y_STEP_PIN 23 +#define ORIG_Y_DIR_PIN 22 +#define ORIG_Y_ENABLE_PIN 24 +#define ORIG_Y_MIN_PIN 0 +#define ORIG_Y_MAX_PIN 2 + +//z axis pins +#define ORIG_Z_STEP_PIN 26 +#define ORIG_Z_DIR_PIN 25 +#define ORIG_Z_ENABLE_PIN 24 +#define ORIG_Z_MIN_PIN 1 +#define ORIG_Z_MAX_PIN 0 + +//extruder pins +#define ORIG_E0_STEP_PIN 28 +#define ORIG_E0_DIR_PIN 27 +#define ORIG_E0_ENABLE_PIN 24 +#define TEMP_0_PIN 1 +#define TEMP_1_PIN 2 +#define HEATER_0_PIN 4 +#define HEATER_1_PIN 3 + + +#define SDPOWER -1 +#define SDSS -1 // SCL pin of I2C header +#define LED_PIN -1 + +#define ORIG_FAN_PIN 31 +#define ORIG_PS_ON_PIN 15 +#define E0_PINS ORIG_E0_STEP_PIN,ORIG_E0_DIR_PIN,ORIG_E0_ENABLE_PIN, +#define E1_PINS + +//our pin for debugging. + +#define DEBUG_PIN 0 + +//our RS485 pins +#define TX_ENABLE_PIN 12 +#define RX_ENABLE_PIN 13 + +#define SCK_PIN 7 +#define SDSSORIG 4 +#define MISO_PIN 6 +#define MOSI_PIN 5 + +#endif + +/**************************************************************************************** + OpenHardware.co.za FrontPrint Controller 1.0 +****************************************************************************************/ +#if MOTHERBOARD == 73 +#define KNOWN_BOARD 1 + +#if !defined(AVR_ATmega644P) && !defined(AVR_ATmega644) && !defined(AVR_ATmega1284P) +#error Oops! Make sure you have 'Gen7' selected from the 'Tools -> Boards' menu. +#endif + +//x axis pins +#define ORIG_X_STEP_PIN 29 +#define ORIG_X_DIR_PIN 28 +#define ORIG_X_ENABLE_PIN 25 +#define ORIG_X_MIN_PIN 0 +#define ORIG_X_MAX_PIN -1 + +//y axis pins +#define ORIG_Y_STEP_PIN 27 +#define ORIG_Y_DIR_PIN 26 +#define ORIG_Y_ENABLE_PIN 25 +#define ORIG_Y_MIN_PIN 1 +#define ORIG_Y_MAX_PIN -1 + +//z axis pins +#define ORIG_Z_STEP_PIN 23 +#define ORIG_Z_DIR_PIN 22 +#define ORIG_Z_ENABLE_PIN 25 +#define ORIG_Z_MIN_PIN 2 +#define ORIG_Z_MAX_PIN -1 + +//First extruder pins +#define ORIG_E0_STEP_PIN 19 +#define ORIG_E0_DIR_PIN 18 +#define ORIG_E0_ENABLE_PIN 25 +#define TEMP_0_PIN 1 +#define HEATER_0_PIN 4 + +//Second Extruder pins +#define ORIG_E1_STEP_PIN 20 +#define ORIG_E1_DIR_PIN 18 +#define ORIG_E1_ENABLE_PIN 25 + +#define TEMP_2_PIN 7 +#define HEATER_2_PIN 13 + +//Heated Bed Pins +#define HEATER_1_PIN 3 +#define TEMP_1_PIN 0 + +//SD Card Pins +#define SDPOWER -1 +#define SDSS 14 +#define SCK_PIN 7 +#define MISO_PIN 6 +#define MOSI_PIN 5 + +//FAN and ATX Power Supply Control Pins +#define ORIG_FAN_PIN 21 +#define ORIG_PS_ON_PIN 15 + +#define LED_PIN -1 +#define SDSUPPORT 1 // sd card reader on board +#define ORIG_SDCARDDETECT -1 + +#define E0_PINS ORIG_E0_STEP_PIN,ORIG_E0_DIR_PIN,ORIG_E0_ENABLE_PIN, +#define E1_PINS ORIG_E1_STEP_PIN,ORIG_E1_DIR_PIN,ORIG_E1_ENABLE_PIN, +#endif + +/**************************************************************************************** +* Teensylu 0.7 pin assingments (ATMEGA90USB) +* Requires the Teensyduino software with Teensy2.0++ selected in arduino IDE! +****************************************************************************************/ +#if MOTHERBOARD == 8 +#define KNOWN_BOARD 1 + +#define ORIG_X_STEP_PIN 28 +#define ORIG_X_DIR_PIN 29 +#define ORIG_X_ENABLE_PIN 19 +#define ORIG_X_MIN_PIN 25 +#define ORIG_X_MAX_PIN -1 + +#define ORIG_Y_STEP_PIN 30 +#define ORIG_Y_DIR_PIN 31 +#define ORIG_Y_ENABLE_PIN 20 +#define ORIG_Y_MIN_PIN 26 +#define ORIG_Y_MAX_PIN -1 + +#define ORIG_Z_STEP_PIN 32 +#define ORIG_Z_DIR_PIN 33 +#define ORIG_Z_ENABLE_PIN 17 +#define ORIG_Z_MIN_PIN 27 +#define ORIG_Z_MAX_PIN -1 + +#define ORIG_E0_STEP_PIN 34 +#define ORIG_E0_DIR_PIN 35 +#define ORIG_E0_ENABLE_PIN 13 + +// Extruder - ANALOG PIN NUMBER! +#define TEMP_0_PIN 7 +// Bed - ANALOG PIN NUMBER! +#define TEMP_1_PIN 6 +// Extruder +#define HEATER_0_PIN 15 +// bed +#define HEATER_1_PIN 14 +#define HEATER_2_PIN -1 +#define TEMP_2_PIN -1 + +#define SDPOWER -1 +#define SDSS 20 +#define LED_PIN -1 + +#define ORIG_FAN_PIN 16 // Fan +#define ORIG_PS_ON_PIN -1 + +#define E0_PINS ORIG_E0_STEP_PIN,ORIG_E0_DIR_PIN,ORIG_E0_ENABLE_PIN, +#define E1_PINS + +#if !SDSUPPORT +// these pins are defined in the SD library if building with SD support +#define SCK_PIN 21 +#define MISO_PIN 23 +#define MOSI_PIN 22 +#endif + +#endif + +/**************************************************************************************** +* Unique One rev. A pin assingments (ATMEGA90USB) +* Requires the Teensyduino software with Teensy2.0++ selected in arduino IDE! +****************************************************************************************/ +#if MOTHERBOARD == 88 +#define KNOWN_BOARD 1 + +#define ORIG_X_STEP_PIN 28 +#define ORIG_X_DIR_PIN 29 +#define ORIG_X_ENABLE_PIN 19 +#define ORIG_X_MIN_PIN 25 +#define ORIG_X_MAX_PIN -1 + +#define ORIG_Y_STEP_PIN 30 +#define ORIG_Y_DIR_PIN 31 +#define ORIG_Y_ENABLE_PIN 18 +#define ORIG_Y_MIN_PIN 26 +#define ORIG_Y_MAX_PIN -1 + +#define ORIG_Z_STEP_PIN 32 +#define ORIG_Z_DIR_PIN 33 +#define ORIG_Z_ENABLE_PIN 17 +#define ORIG_Z_MIN_PIN 27 +#define ORIG_Z_MAX_PIN -1 + +#define ORIG_E0_STEP_PIN 34 +#define ORIG_E0_DIR_PIN 35 +#define ORIG_E0_ENABLE_PIN 12 +// Extruder +#define HEATER_0_PIN 8 +// Extruder - ANALOG PIN NUMBER! +#define TEMP_0_PIN 5 + +#define ORIG_E1_STEP_PIN 14 +#define ORIG_E1_DIR_PIN 13 +#define ORIG_E1_ENABLE_PIN 11 +// Extruder +#define HEATER_2_PIN 9 +// Extruder - ANALOG PIN NUMBER! +#define TEMP_2_PIN 6 + +// bed +#define HEATER_1_PIN 10 +// Bed - ANALOG PIN NUMBER! +#define TEMP_1_PIN 7 + +#define SDPOWER -1 +#define SDSS 20 +#define LED_PIN -1 + +// Fan +#define ORIG_FAN_PIN 16 +#define ORIG_PS_ON_PIN -1 + +#define E0_PINS ORIG_E0_STEP_PIN,ORIG_E0_DIR_PIN,ORIG_E0_ENABLE_PIN, +#define E1_PINS ORIG_E1_STEP_PIN,ORIG_E1_DIR_PIN,ORIG_E1_ENABLE_PIN, + +#if !SDSUPPORT +// these pins are defined in the SD library if building with SD support +#define SCK_PIN 21 +#define MISO_PIN 23 +#define MOSI_PIN 22 +#endif + +#endif + +/**************************************************************************************** +* Printrboard Rev. F pin assingments (ATMEGA90USB1286) +* Requires the Teensyduino software with Teensy2.0++ selected in arduino IDE! +* See http://reprap.org/wiki/Printrboard for more info +* +* Rev. F uses an MCP4728 DAC to generate the Reference Voltage used to determine the +* Stepper Driver's maximum current. +* +* On PrintrBoard, with Sense Resistors = 0.11 Ohms, and 2 Amps maximum current rating, +* the Maximum VRef to send is calculated as: +* +* 2.00 Amps Maximum Output * (8 * 0.11 Ohms) = 1.76 Maximum VRef from MCP4728. +* +****************************************************************************************/ +#if MOTHERBOARD == 92 +#define KNOWN_BOARD 1 + +// Definition for current control +#define STEPPER_CURRENT_CONTROL CURRENT_CONTROL_MCP4728 + +#define MCP4728_I2C_ADDRESS 0x60 << 1 // Base Address (0x60); Pre-Shifted Left 1 bit for Repetier HAL. +#define MCP4728_GENERALCALL_ADDRESS 0x00 // General Call Address. Weird, but OK... +#define MCP4728_CMD_MULTI_WRITE 0B01000000 // Writes DAC Settings, Does not update EEPROM. +#define MCP4728_CMD_SEQ_WRITE 0B01010000 // Writes DAC Settings, also persists to EEPROM. +#define MCP4728_CMD_GC_UPDATE 0B00001000 // General Call Update - Update all DAC Outputs (Only way to update DAC Outputs on PrintrBoard Rev F because they tied /LDAC to VDD. +#define MCP4728_CMD_GC_RESET 0B00000110 // General Call Reset +#define MCP4728_VREF 1 // From DataSheet. We will use MCP4728's internal 2.048V as Vref +#define MCP4728_GAIN 0 // From DataSheet. Use 1x Gain Multiplier (0V - 2.048V); +#define MCP4728_NUM_CHANNELS 4 // Duh. Specified here in case there's a beefier chip used on some other board someday. +#define MCP4728_STEPPER_ORDER {3,2,1,0} // PrintrBoard wired 'em up backwards. SMH. X, Y, Z, E +#define MCP4728_VOUT_MAX 3520 // 1.76 Volts * 2000. See DataSheets for the math. Value should be between 0-4095 + +#define ORIG_X_STEP_PIN 28 +#define ORIG_X_DIR_PIN 29 +#define ORIG_X_ENABLE_PIN 19 +#define ORIG_X_MIN_PIN 47 +#define ORIG_X_MAX_PIN -1 + +#define ORIG_Y_STEP_PIN 30 +#define ORIG_Y_DIR_PIN 31 +#define ORIG_Y_ENABLE_PIN 18 +// (Was Pin 20 on Rev B-E); Don't use this if you want to use SD card. Use 37 and put the endstop in the e-stop slot!!! +#define ORIG_Y_MIN_PIN 24 +#define ORIG_Y_MAX_PIN -1 + +#define ORIG_Z_STEP_PIN 32 +#define ORIG_Z_DIR_PIN 33 +#define ORIG_Z_ENABLE_PIN 17 +#define ORIG_Z_MIN_PIN 36 +#define ORIG_Z_MAX_PIN -1 + +#define ORIG_E0_STEP_PIN 34 +#define ORIG_E0_DIR_PIN 35 +#define ORIG_E0_ENABLE_PIN 13 +// Extruder - ANALOG PIN NUMBER! +#define TEMP_0_PIN 1 +// Bed - ANALOG PIN NUMBER! +#define TEMP_1_PIN 0 +// Extruder +#define HEATER_0_PIN 15 +// bed +#define HEATER_1_PIN 14 +#define HEATER_2_PIN -1 +#define TEMP_2_PIN -1 + +#define SDPOWER -1 +// (Was Pin 26 on Rev. B-E); old value 2 +#define SDSS 20 +#define LED_PIN -1 + +// Fan +#define ORIG_FAN_PIN 16 +#define ORIG_PS_ON_PIN -1 + +#define E0_PINS ORIG_E0_STEP_PIN,ORIG_E0_DIR_PIN,ORIG_E0_ENABLE_PIN, +#define E1_PINS +#if !SDSUPPORT +// these pins are defined in the SD library if building with SD support +#define SCK_PIN 21 +#define MISO_PIN 23 +#define MOSI_PIN 22 +#endif + +#endif + + +/**************************************************************************************** +* Printrboard Rev. B pin assingments (ATMEGA90USB1286) +* Requires the Teensyduino software with Teensy2.0++ selected in arduino IDE! +* See http://reprap.org/wiki/Printrboard for more info +****************************************************************************************/ +#if MOTHERBOARD == 9 +#define KNOWN_BOARD 1 + +#define ORIG_X_STEP_PIN 28 +#define ORIG_X_DIR_PIN 29 +#define ORIG_X_ENABLE_PIN 19 +#define ORIG_X_MIN_PIN 47 +#define ORIG_X_MAX_PIN -1 + +#define ORIG_Y_STEP_PIN 30 +#define ORIG_Y_DIR_PIN 31 +#define ORIG_Y_ENABLE_PIN 18 +// Don't use this if you want to use SD card. Use 37 and put the endstop in the e-stop slot!!! +#define ORIG_Y_MIN_PIN 20 +#define ORIG_Y_MAX_PIN -1 + +#define ORIG_Z_STEP_PIN 32 +#define ORIG_Z_DIR_PIN 33 +#define ORIG_Z_ENABLE_PIN 17 +#define ORIG_Z_MIN_PIN 36 +#define ORIG_Z_MAX_PIN -1 + +#define ORIG_E0_STEP_PIN 34 +#define ORIG_E0_DIR_PIN 35 +#define ORIG_E0_ENABLE_PIN 13 +// Extruder - ANALOG PIN NUMBER! +#define TEMP_0_PIN 1 +// Bed - ANALOG PIN NUMBER! +#define TEMP_1_PIN 0 +// Extruder +#define HEATER_0_PIN 15 +// bed +#define HEATER_1_PIN 14 +#define HEATER_2_PIN -1 +#define TEMP_2_PIN -1 + +#define SDPOWER -1 +// old value 2 +#define SDSS 26 +#define LED_PIN -1 + +#define ORIG_FAN_PIN 16 +#define ORIG_PS_ON_PIN -1 + +#define E0_PINS ORIG_E0_STEP_PIN,ORIG_E0_DIR_PIN,ORIG_E0_ENABLE_PIN, +#define E1_PINS +#if !SDSUPPORT +// these pins are defined in the SD library if building with SD support +#define SCK_PIN 21 +#define MISO_PIN 23 +#define MOSI_PIN 22 +#endif + +#endif + +/**************************************************************************************** +* 3D Master pin assignment +* +****************************************************************************************/ +#if MOTHERBOARD == 12 +#define KNOWN_BOARD 1 + +#if !defined(__AVR_ATmega1280__) && !defined(__AVR_ATmega2560__) +#error Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu. +#endif + +// Definition for current control +#define STEPPER_CURRENT_CONTROL CURRENT_CONTROL_LTC2600 +#define LTC2600_CHANNELS {0x30,0x31,0x32,0x33,0x34} +#define LTC2600_NUM_CHANNELS 5 +#define LTC2600_CS_PIN 92 // PIND.4, 47, DA_CS +#define LTC2600_SCK_PIN 93 // PIND.5, 48, DA_SCK +#define LTC2600_SDI_PIN 94 // PIND.6, 49, DA_SDI + +// On board beeper, so define values already here +#define BEEPER_PIN 23 +#define BEEPER_TYPE 1 +#define SDSUPPORT 1 // sd card reader on board +#define ORIG_SDCARDDETECT -1 + +// digital pin mappings +// PINF.0, 97, STP_DRV1 +#define ORIG_X_STEP_PIN 54 +// PINF.1, 96, DIR_DRV1 +#define ORIG_X_DIR_PIN 55 +// PIND.7, 50, ENA_DRV1 +#define ORIG_X_ENABLE_PIN 38 +// PINE.5, 7, OPTO1 +#define ORIG_X_MIN_PIN 3 +#define ORIG_X_MAX_PIN -1 // PINJ.0, 63, OPTO4 (would be "15", -1 = disabled) + +// PINF.6, 91, STP_DRV2 +#define ORIG_Y_STEP_PIN 60 +// PINF.7, 90, DIR_DRV2 +#define ORIG_Y_DIR_PIN 61 +// PINF.2, 95, ENA_DRV2 +#define ORIG_Y_ENABLE_PIN 56 +// PINE.4, 6, OPTO2 +#define ORIG_Y_MIN_PIN 2 +// PIND.3, 46, OPTO5 (would be "18", -1 = disabled +#define ORIG_Y_MAX_PIN -1 + +// PINL.3, 38, STP_DRV3 +#define ORIG_Z_STEP_PIN 46 +// PINL.1, 36, DIR_DRV3 +#define ORIG_Z_DIR_PIN 48 +// PINK.0, 89, ENA_DRV3 +#define ORIG_Z_ENABLE_PIN 62 +// PINJ.1, 64, OPTO3 +#define ORIG_Z_MIN_PIN 14 +#define ORIG_Z_MAX_PIN -1 // PIND.2, 45, OPTO6 (would be "19", -1 = disabled) + +// PINA.4, 74, STP_DRV4 +#define ORIG_E0_STEP_PIN 26 +// PINA.6, 72, DIR_DRV4 +#define ORIG_E0_DIR_PIN 28 +// PINA.2, 76 ENA_DRV4 +#define ORIG_E0_ENABLE_PIN 24 + +// PINC.1, 54, STP_DRV5 +#define ORIG_E1_STEP_PIN 36 +// PINC.3, 56, DIR_DRV5 +#define ORIG_E1_DIR_PIN 34 +// PINC.7, 60, ENA_DRV5 +#define ORIG_E1_ENABLE_PIN 30 + +#define SDPOWER -1 +// PINB.0, 19, SS +#define SDSS 53 +// PINB.7, 26, LED13 +#define LED_PIN 13 +// OUT1 PINA.3, 75, OUT1 +#define ORIG_FAN_PIN 25 +// OUT2 +#define FAN_BOARD_PIN 27 +#define ORIG_PS_ON_PIN -1 + +// PINB.4, 23, HZ1 +#define HEATER_0_PIN 10 +// PINH.6, 18, HZ2 +#define HEATER_1_PIN 9 +// PINH.5, 17, HZ3 +#define HEATER_2_PIN 8 + +// analog pin mappings +// PINK.5, 84, TH1 +#define TEMP_0_PIN 13 + // PINK.6, 83, TH2 +#define TEMP_1_PIN 14 +// PINK.7, 82, TH3 +#define TEMP_2_PIN 15 + +#define E0_PINS ORIG_E0_STEP_PIN,ORIG_E0_DIR_PIN,ORIG_E0_ENABLE_PIN, +#define E1_PINS ORIG_E1_STEP_PIN,ORIG_E1_DIR_PIN,ORIG_E1_ENABLE_PIN, + +// these pins are defined in the SD library if building with SD support +// PINB.1, 20, SCK +#define SCK_PIN 52 +// PINB.3, 22, MISO +#define MISO_PIN 50 +// PINB.2, 21, MOSI +#define MOSI_PIN 51 +// PINB.0, 19, SS +#define MAX6675_SS 53 + +#endif // MOTHERBOARD == 12 + + +/**************************************************************************************** +* MegaTronics +* +****************************************************************************************/ +#if MOTHERBOARD == 70 +#define KNOWN_BOARD 1 + +//////////////////FIX THIS////////////// + +#ifndef __AVR_ATmega2560__ +#error Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu. +#endif + +#define ORIG_X_STEP_PIN 26 +#define ORIG_X_DIR_PIN 28 +#define ORIG_X_ENABLE_PIN 24 +#define ORIG_X_MIN_PIN 41 + //2 //Max endstops default to disabled "-1", set to commented value to enable. +#define ORIG_X_MAX_PIN 37 + +#define ORIG_Y_STEP_PIN 60 +#define ORIG_Y_DIR_PIN 61 +#define ORIG_Y_ENABLE_PIN 22 +#define ORIG_Y_MIN_PIN 14 +#define ORIG_Y_MAX_PIN 15 + +#define ORIG_Z_STEP_PIN 54 +#define ORIG_Z_DIR_PIN 55 +#define ORIG_Z_ENABLE_PIN 56 +#define ORIG_Z_MIN_PIN 18 +#define ORIG_Z_MAX_PIN 19 + +#define ORIG_E0_STEP_PIN 31 +#define ORIG_E0_DIR_PIN 32 +#define ORIG_E0_ENABLE_PIN 38 + +#define ORIG_E1_STEP_PIN 34 +#define ORIG_E1_DIR_PIN 36 +#define ORIG_E1_ENABLE_PIN 30 + +#define SDPOWER -1 +#define SDSS 53 +#define LED_PIN 13 + + +// IO pin. Buffer needed +#define ORIG_FAN_PIN 7 +#define ORIG_PS_ON_PIN 12 + +// EXTRUDER 1 +#define HEATER_0_PIN 9 +// EXTRUDER 2 (FAN On Sprinter) +#define HEATER_1_PIN 8 +// Heated bed +#define HEATER_2_PIN 10 + +#define THERMOCOUPLE_0_PIN 8 +// Thermocouple 0 ANALOG NUMBERING +#define TEMP_3_PIN 8 +// ANALOG NUMBERING +#define TEMP_0_PIN 13 +// ANALOG NUMBERING +#define TEMP_1_PIN 15 +#define TEMP_2_PIN -1 // ANALOG NUMBERING + // BED +#define HEATER_BED_PIN 10 +// ANALOG NUMBERING +#define TEMP_BED_PIN 14 + +// Beeper on AUX-4 +#define BEEPER_PIN 33 +#define BEEPER_TYPE 1 +#define SDSUPPORT 1 // sd card reader on board +#define ORIG_SDCARDDETECT -1 + + +#ifdef ULTRA_LCD + +#ifdef 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 + +//buttons are directly attached using AUX-2 +#define BTN_EN1 37 +#define BTN_EN2 35 +#define BTN_ENC 43 + +#define BLEN_C 2 +#define BLEN_B 1 +#define BLEN_A 0 + +#endif +#endif //ULTRA_LCD + +#define SCK_PIN 52 +#define MISO_PIN 50 +#define MOSI_PIN 51 + +#define E0_PINS ORIG_E0_STEP_PIN,ORIG_E0_DIR_PIN,ORIG_E0_ENABLE_PIN, +#define E1_PINS + +#endif + +/**************************************************************************************** +* FELIXprinters +* +****************************************************************************************/ +#if MOTHERBOARD == 101 +#define KNOWN_BOARD 1 + + +//////////////////FIX THIS////////////// +#ifndef __AVR_ATmega1280__ +#ifndef __AVR_ATmega2560__ +#error Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu. +#endif +#endif + +#define ORIG_X_STEP_PIN 54 +#define ORIG_X_DIR_PIN 55 +#define ORIG_X_ENABLE_PIN 38 +#define ORIG_X_MIN_PIN 3 +#define ORIG_X_MAX_PIN -1 + +#define ORIG_Y_STEP_PIN 60 +#define ORIG_Y_DIR_PIN 61 +#define ORIG_Y_ENABLE_PIN 56 +#define ORIG_Y_MIN_PIN 14 +#define ORIG_Y_MAX_PIN -1 + +#define ORIG_Z_STEP_PIN 46 +#define ORIG_Z_DIR_PIN 48 +#define ORIG_Z_ENABLE_PIN 62 +#define ORIG_Z_MIN_PIN 18 +#define ORIG_Z_MAX_PIN -1 + +#define ORIG_E0_STEP_PIN 26 +#define ORIG_E0_DIR_PIN 28 +#define ORIG_E0_ENABLE_PIN 24 + +#define ORIG_E1_STEP_PIN 36 +#define ORIG_E1_DIR_PIN 34 +#define ORIG_E1_ENABLE_PIN 30 + + + +#define LED_PIN 13 +#define ORIG_FAN_PIN 9 +#define ORIG_PS_ON_PIN 12 +#define KILL_PIN -1 + +#define HEATER_0_PIN 10 +//BED +#define HEATER_1_PIN 8 +#define HEATER_2_PIN 7 + +// ANALOG NUMBERING +#define TEMP_0_PIN 13 + // BED,ANALOG NUMBERING +#define TEMP_1_PIN 14 +#define TEMP_2_PIN 15 + +#define E0_PINS ORIG_E0_STEP_PIN,ORIG_E0_DIR_PIN,ORIG_E0_ENABLE_PIN, +#define E1_PINS ORIG_E1_STEP_PIN,ORIG_E1_DIR_PIN,ORIG_E1_ENABLE_PIN, + +#define SDPOWER 1 +#define SDSS 53 +#define ORIG_SDCARDDETECT 6 +#define SDSUPPORT 1 // already defined in config.h +#define SDCARDDETECTINVERTED 1 // already defined in config.h + +// these pins are defined in the SD library if building with SD support +// PINB.1, 20, SCK +#define SCK_PIN 52 +// PINB.3, 22, MISO +#define MISO_PIN 50 +// PINB.2, 21, MOSI +#define MOSI_PIN 51 +//53 // PINB.0, 19, SS +#define MAX6675_SS -1 + +#define BEEPER_PIN -1 // Activate beeper on extension shield +#define BEEPER_TYPE 1 + +#endif//MOTHERBOARD == 101 + + +/**************************************************************************************** +* MegaTronics v2.0 +* +****************************************************************************************/ +#if MOTHERBOARD == 701 +#define KNOWN_BOARD 1 + + +#ifndef __AVR_ATmega2560__ +#error Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu. +#endif + + +#define ORIG_X_STEP_PIN 26 +#define ORIG_X_DIR_PIN 27 +#define ORIG_X_ENABLE_PIN 25 +#define ORIG_X_MIN_PIN 37 + //2 //Max endstops default to disabled "-1", set to commented value to enable. +#define ORIG_X_MAX_PIN 40 + +#define ORIG_Y_STEP_PIN 4 +#define ORIG_Y_DIR_PIN 54 +#define ORIG_Y_ENABLE_PIN 5 +#define ORIG_Y_MIN_PIN 41 +#define ORIG_Y_MAX_PIN 38 + +#define ORIG_Z_STEP_PIN 56 +#define ORIG_Z_DIR_PIN 60 +#define ORIG_Z_ENABLE_PIN 55 +#define ORIG_Z_MIN_PIN 18 +#define ORIG_Z_MAX_PIN 19 + +#define ORIG_E0_STEP_PIN 35 +#define ORIG_E0_DIR_PIN 36 +#define ORIG_E0_ENABLE_PIN 34 + +#define ORIG_E1_STEP_PIN 29 +#define ORIG_E1_DIR_PIN 39 +#define ORIG_E1_ENABLE_PIN 28 + +#define ORIG_E2_STEP_PIN 23 +#define ORIG_E2_DIR_PIN 24 +#define ORIG_E2_ENABLE_PIN 22 + +#define ORIG_SDCARDDETECT -1 // Ramps does not use this port +#define SDPOWER -1 +#define SDSS 53 + +#define LED_PIN 13 + + +#define ORIG_FAN_PIN 7 +#define ORIG_FAN2_PIN 6 +#define ORIG_PS_ON_PIN 12 + + // EXTRUDER 1 +#define HEATER_0_PIN 9 +// Heated bed +#define HEATER_2_PIN 8 +// EXTRUDER 2 +#define HEATER_1_PIN 10 + +// Thermistor 0 ANALOG NUMBERING +#define TEMP_0_PIN 13 +// Thermistor 1 ANALOG NUMBERING +#define TEMP_2_PIN 15 + // Thermistor 2 for heated bed ANALOG NUMBERING +#define TEMP_1_PIN 14 + // Thermocouple 0 +#define TEMP_3_PIN 8 + // Thermocouple 1 +#define TEMP_4_PIN 4 +#define THERMOCOUPLE_0_PIN 8 +#define THERMOCOUPLE_1_PIN 4 + +// Beeper on AUX-4 +#define BEEPER_PIN 64 + +#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 + + +//buttons are directly attached using AUX-2 +#define BTN_EN1 59 +#define BTN_EN2 64 +#define BTN_ENC 43 + +#define BLEN_C 2 +#define BLEN_B 1 +#define BLEN_A 0 + +#define SCK_PIN 52 +#define MISO_PIN 50 +#define MOSI_PIN 51 + +#define E0_PINS ORIG_E0_STEP_PIN,ORIG_E0_DIR_PIN,ORIG_E0_ENABLE_PIN, +#define E1_PINS ORIG_E1_STEP_PIN,ORIG_E1_DIR_PIN,ORIG_E1_ENABLE_PIN, +#define E2_PINS ORIG_E2_STEP_PIN,ORIG_E2_DIR_PIN,ORIG_E2_ENABLE_PIN, + +#endif + +/**************************************************************************************** +* Minitronics v1.0 +* +****************************************************************************************/ +#if MOTHERBOARD == 702 +#define KNOWN_BOARD 1 + + +#ifndef __AVR_ATmega1281__ +#error Oops! Make sure you have 'Minitronics ' selected from the 'Tools -> Boards' menu. +#endif + +#define LARGE_FLASH true + +#define ORIG_X_STEP_PIN 48 +#define ORIG_X_DIR_PIN 47 +#define ORIG_X_ENABLE_PIN 49 +#define ORIG_X_MIN_PIN 5 +//2 //Max endstops default to disabled "-1", set to commented value to enable. +#define ORIG_X_MAX_PIN -1 + +#define ORIG_Y_STEP_PIN 39 +#define ORIG_Y_DIR_PIN 40 +#define ORIG_Y_ENABLE_PIN 38 +#define ORIG_Y_MIN_PIN 2 +#define ORIG_Y_MAX_PIN -1 + +#define ORIG_Z_STEP_PIN 42 +#define ORIG_Z_DIR_PIN 43 +#define ORIG_Z_ENABLE_PIN 41 +#define ORIG_Z_MIN_PIN 6 +#define ORIG_Z_MAX_PIN -1 + +#define ORIG_E0_STEP_PIN 45 +#define ORIG_E0_DIR_PIN 44 +#define ORIG_E0_ENABLE_PIN 27 + +#define ORIG_E1_STEP_PIN 36 +#define ORIG_E1_DIR_PIN 35 +#define ORIG_E1_ENABLE_PIN 37 + +#define ORIG_E2_STEP_PIN -1 +#define ORIG_E2_DIR_PIN -1 +#define ORIG_E2_ENABLE_PIN -1 + +#define SDPOWER -1 +#define SDSS 16 +#define SCK_PIN 10 +#define MISO_PIN 12 +#define MOSI_PIN 11 +#define LED_PIN 46 + +#define ORIG_FAN_PIN 9 +#define ORIG_FAN2_PIN -1 +#define ORIG_PS_ON_PIN -1 +#define KILL_PIN -1 + +// EXTRUDER 1 +#define HEATER_0_PIN 7 +// BED +#define HEATER_1_PIN 3 +// EXTRUDER 2 +#define HEATER_2_PIN 8 +#define HEATER_3_PIN -1 + + +// ANALOG NUMBERING +#define TEMP_0_PIN 7 +// BED SENSOR ANALOG NUMBERING +#define TEMP_1_PIN 6 +// ANALOG NUMBERING +#define TEMP_2_PIN 6 +// ANALOG NUMBERING +#define TEMP_3_PIN -1 + + +#define BEEPER_PIN -1 + +#define ORIG_SDCARDDETECT -1 // Megatronics does not use this port +#define E0_PINS ORIG_E0_STEP_PIN,ORIG_E0_DIR_PIN,ORIG_E0_ENABLE_PIN, +#define E1_PINS ORIG_E1_STEP_PIN,ORIG_E1_DIR_PIN,ORIG_E1_ENABLE_PIN, +#define E2_PINS + +#endif + + +/**************************************************************************************** +* MegaTronics v3.0 +* +****************************************************************************************/ +#if MOTHERBOARD == 703 +#define KNOWN_BOARD 1 + + +#ifndef __AVR_ATmega2560__ +#error Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu. +#endif + + +#define ORIG_X_STEP_PIN 58 +#define ORIG_X_DIR_PIN 57 +#define ORIG_X_ENABLE_PIN 59 +#define ORIG_X_MIN_PIN 37 +//2 //Max endstops default to disabled "-1", set to commented value to enable. +#define ORIG_X_MAX_PIN 40 + +#define ORIG_Y_STEP_PIN 5 +#define ORIG_Y_DIR_PIN 17 +#define ORIG_Y_ENABLE_PIN 4 +#define ORIG_Y_MIN_PIN 41 +#define ORIG_Y_MAX_PIN 38 + +#define ORIG_Z_STEP_PIN 16 +#define ORIG_Z_DIR_PIN 11 +#define ORIG_Z_ENABLE_PIN 3 +#define ORIG_Z_MIN_PIN 18 +#define ORIG_Z_MAX_PIN 19 + +#define ORIG_E0_STEP_PIN 28 +#define ORIG_E0_DIR_PIN 27 +#define ORIG_E0_ENABLE_PIN 29 + +#define ORIG_E1_STEP_PIN 25 +#define ORIG_E1_DIR_PIN 24 +#define ORIG_E1_ENABLE_PIN 26 + +#define ORIG_E2_STEP_PIN 22 +#define ORIG_E2_DIR_PIN 60 +#define ORIG_E2_ENABLE_PIN 23 + +#define ORIG_SDCARDDETECT -1 // Ramps does not use this port +#define SDPOWER -1 +#define SDSS 53 + +#define LED_PIN 13 + +#define ORIG_FAN_PIN 6 +#define ORIG_FAN2_PIN 7 + +#define ORIG_PS_ON_PIN 12 +//#define KILL_PIN -1 + +// EXTRUDER 0 - changed 10-9-2015 +#define HEATER_0_PIN 2 +// EXTRUDER 1 - changed 10-9-2015 +#define HEATER_2_PIN 9 +// EXTRUDER 2 - changed 10-9-2015 +#define HEATER_3_PIN 8 +// heater bed +#define HEATER_1_PIN 10 + +/* +Temperature sensors +ANALOG NUMBERING! + +Thermistors +T0=15 +T1=14 +T2=13 +T3=12 + +Thermocouple +S0=11 +S1=10 +S2(ext)=8 +S3(ext)=9 +*/ + +// Extruder 1 - Thermistor 1 +#define TEMP_0_PIN 15 +// Extruder 2 - Thermistor 2 +#define TEMP_2_PIN 14 +// Extruder 3 - Thermistor 3 +#define TEMP_3_PIN 13 +// Heated bed - Thermistor 4 +#define TEMP_1_PIN 12 + +#define THERMOCOUPLE_0_PIN 11 +#define THERMOCOUPLE_1_PIN 10 +#define THERMOCOUPLE_2_PIN 8 +#define THERMOCOUPLE_3_PIN 9 + +// Beeper on AUX-4 +#define BEEPER_PIN 61 +#define SDSUPPORT 1 // sd card reader on board + +// #define UI_DISPLAY_RS_PIN 32 +// #define UI_DISPLAY_ENABLE_PIN 31 +// #define UI_DISPLAY_D4_PIN 14 +// #define UI_DISPLAY_D5_PIN 30 +// #define UI_DISPLAY_D6_PIN 39 +// #define UI_DISPLAY_D7_PIN 15 + + +//buttons are directly attached using AUX-2 +////encoder A 59 +////encoder B 64 +////encoder click 33 //the click + +#define SCK_PIN 52 +#define MISO_PIN 50 +#define MOSI_PIN 51 + +#define E0_PINS ORIG_E0_STEP_PIN,ORIG_E0_DIR_PIN,ORIG_E0_ENABLE_PIN, +#define E1_PINS ORIG_E1_STEP_PIN,ORIG_E1_DIR_PIN,ORIG_E1_ENABLE_PIN, +#define E2_PINS ORIG_E2_STEP_PIN,ORIG_E2_DIR_PIN,ORIG_E2_ENABLE_PIN, + + +#endif + + +#if MOTHERBOARD == 301 +#define KNOWN_BOARD +/***************************************************************** +* RAMBo Pin Assignments +******************************************************************/ + +#ifndef __AVR_ATmega2560__ +#error Oops! Make sure you have 'Arduino Mega 2560' selected from the 'Tools -> Boards' menu. +#endif + +#define ORIG_X_STEP_PIN 37 +#define ORIG_X_DIR_PIN 48 +#define ORIG_X_MIN_PIN 12 +#define ORIG_X_MAX_PIN 24 +#define ORIG_X_ENABLE_PIN 29 +#define X_MS1_PIN 40 +#define X_MS2_PIN 41 + +#define ORIG_Y_STEP_PIN 36 +#define ORIG_Y_DIR_PIN 49 +#define ORIG_Y_MIN_PIN 11 +#define ORIG_Y_MAX_PIN 23 +#define ORIG_Y_ENABLE_PIN 28 +#define Y_MS1_PIN 69 +#define Y_MS2_PIN 39 + +#define ORIG_Z_STEP_PIN 35 +#define ORIG_Z_DIR_PIN 47 +#define ORIG_Z_MIN_PIN 10 +#define ORIG_Z_MAX_PIN 30 +#define ORIG_Z_ENABLE_PIN 27 +#define Z_MS1_PIN 68 +#define Z_MS2_PIN 67 + +#define HEATER_0_PIN 9 +#define TEMP_0_PIN 0 + +#define HEATER_1_PIN 3 +// This is T2 on the board! +#define TEMP_1_PIN 2 + +#define HEATER_2_PIN 7 +// This is T1 on the board! +#define TEMP_2_PIN 1 +// T3 on board +#define TEMP_3_PIN 7 + +#define ORIG_E0_STEP_PIN 34 +#define ORIG_E0_DIR_PIN 43 +#define ORIG_E0_ENABLE_PIN 26 +#define E0_MS1_PIN 65 +#define E0_MS2_PIN 66 + +#define ORIG_E1_STEP_PIN 33 +#define ORIG_E1_DIR_PIN 42 +#define ORIG_E1_ENABLE_PIN 25 +#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 SDPOWER -1 +#define SDSS 53 +#define LED_PIN 13 +#define ORIG_FAN_PIN 8 +#define ORIG_FAN2_PIN 6 +#define ORIG_FAN3_PIN 2 +#define ORIG_PS_ON_PIN 4 +#define SUICIDE_PIN -1 //PIN that has to be turned on right after start, to keep power flowing. + +#define E0_PINS ORIG_E0_STEP_PIN,ORIG_E0_DIR_PIN,ORIG_E0_ENABLE_PIN,E0_MS1_PIN,E0_MS2_PIN, +#define E1_PINS + +#define SCK_PIN 52 +#define MISO_PIN 50 +#define MOSI_PIN 51 +#define MAX6675_SS 53 +#define STEPPER_CURRENT_CONTROL CURRENT_CONTROL_DIGIPOT + +#endif + + +/*************************************************************************************** +*PiBot for Repetier pins assignment +*illustration : +* PiBot for Repetier V1.0-1.3 =314 +* PiBot for Repetier V1.4-1.6 =315 +* PiBot Controller Rev2.0 =316 +***************************************************************************************/ + +#if MOTHERBOARD == 316 +#define MOTHERBOARD 314 +#define PiBot_V_2_0 true +#define PiBot_HD_VERSION "Rev2.0" +#ifndef Thermistor_Solution +#define Thermistor_Solution 0 +#endif +// define for temperature senser chip connection +// temperature sensor port in Rev 2.0 for max6675 +// #define MAX6675_TEMP_Senser false ///*** canceled hardware integration +// Temperature sensor port in Rev 2.0 for AD595 +#define AD595_TEMP_Senser false /////*** you can input at port 59 60 61 ///Analoge Pin 8 9 10 +#endif + +#if MOTHERBOARD == 315 +#define MOTHERBOARD 314 +#define PiBot_V_1_6 true +#define PiBot_HD_VERSION "Rev1.6" +#endif + +#if MOTHERBOARD == 314 +#define KNOWN_BOARD 1 +#define PiBot true + +#if PiBot_V_1_4==true || PiBot_V_1_6==true || PiBot_V_2_0==true +#define PiBot_V_1_0 false +#else +#define PiBot_V_1_0 true +#define PiBot_HD_VERSION "Rev1.0" +#endif + +#ifndef PiBotSemitec +#define PiBotSemitec false // for semitec NTC 100K b=4230(test value) default b=4267 +#endif + +#ifndef PI_PRUSA_I3 +#define PI_PRUSA_I3 false +#endif + +#ifndef PiBotMachine +#define PiBotMachine false // if use for pibot 3D printer uncomment this line. +#endif + +#if PI_PRUSA_I3==true +#define PiBotMachine true // if use for pibot 3D printer uncomment this line. +#endif + +// define in AVR public files, when you finish the chip select. +#ifndef __AVR_ATmega1280__ +#ifndef __AVR_ATmega2560__ +#error Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu. +#endif +#endif + +#if PiBot_V_1_0 +#define ORIG_X_STEP_PIN 54 +#define ORIG_X_DIR_PIN 55 +#define ORIG_X_ENABLE_PIN 38 +#define ORIG_X_MIN_PIN 3 +#define ORIG_X_MAX_PIN 2 + +#define ORIG_Y_STEP_PIN 60 +#define ORIG_Y_DIR_PIN 61 +#define ORIG_Y_ENABLE_PIN 56 +#define ORIG_Y_MIN_PIN 14 +#define ORIG_Y_MAX_PIN 15 + +#define ORIG_Z_STEP_PIN 46 +#define ORIG_Z_DIR_PIN 48 +#define ORIG_Z_ENABLE_PIN 62 +#define ORIG_Z_MIN_PIN 18 +#define ORIG_Z_MAX_PIN 19 + +#define ORIG_E0_STEP_PIN 26 +#define ORIG_E0_DIR_PIN 28 +#define ORIG_E0_ENABLE_PIN 24 + +#define ORIG_E1_STEP_PIN 36 +#define ORIG_E1_DIR_PIN 34 +#define ORIG_E1_ENABLE_PIN 30 + +#define SDPOWER -1 +#define ORIG_SDCARDDETECT 49 + +#define LED_PIN 13 +#define ORIG_FAN_PIN 7 +#define ORIG_PS_ON_PIN 12 +#define KILL_PIN -1 + +// Extuder1 +#define HEATER_0_PIN 8 +// Bed +#define HEATER_1_PIN 10 +// Extuder2 +#define HEATER_2_PIN 9 +// ANALOG NUMBERING Extuder1 +#define TEMP_0_PIN 13 +// ANALOG NUMBERING Bed +#define TEMP_1_PIN 15 +// ANALOG NUMBERING Extuder2 +#define TEMP_2_PIN 14 + +// ISP for TFcard +#define SDSS 53 +#define SCK_PIN 52 +#define MISO_PIN 50 +#define MOSI_PIN 51 + +#define E0_PINS ORIG_E0_STEP_PIN,ORIG_E0_DIR_PIN,ORIG_E0_ENABLE_PIN, +#define E1_PINS ORIG_E1_STEP_PIN,ORIG_E1_DIR_PIN,ORIG_E1_ENABLE_PIN, +#endif // end PiBot for Repetier V1.0 + + +#if PiBot_V_1_4==true || PiBot_V_1_6==true +#define ORIG_X_STEP_PIN 4 +#define ORIG_X_DIR_PIN 17 +#define ORIG_X_ENABLE_PIN 16 +#define ORIG_X_MIN_PIN 37 +#define ORIG_X_MAX_PIN 34 + +#define ORIG_Y_STEP_PIN 56 +#define ORIG_Y_DIR_PIN 55 +#define ORIG_Y_ENABLE_PIN 54 +#define ORIG_Y_MIN_PIN 36 +#define ORIG_Y_MAX_PIN 33 + +#define ORIG_Z_STEP_PIN 59 +#define ORIG_Z_DIR_PIN 58 +#define ORIG_Z_ENABLE_PIN 57 +#define ORIG_Z_MIN_PIN 35 +#define ORIG_Z_MAX_PIN 32 + +#define ORIG_E0_STEP_PIN 24 +#define ORIG_E0_DIR_PIN 23 +#define ORIG_E0_ENABLE_PIN 22 + +#define ORIG_E1_STEP_PIN 27 +#define ORIG_E1_DIR_PIN 26 +#define ORIG_E1_ENABLE_PIN 25 + +//uncomment when use 3rd extruder +#define ORIG_E2_STEP_PIN 15 +#define ORIG_E2_DIR_PIN 14 +#define ORIG_E2_ENABLE_PIN 39 + +//uncomment when use 4th extruder +#define ORIG_E3_STEP_PIN 41 +#define ORIG_E3_DIR_PIN 38 +#define ORIG_E3_ENABLE_PIN 13 + +#define SDPOWER -1 +#define ORIG_SDCARDDETECT 10 + +#define LED_PIN 30 +#define ORIG_FAN_PIN 7 +//uncomment when the 2nd fan used - works only without heated bed! +#define ORIG_FAN2_PIN 2 +#define PS_ON_PIN 40 +#define KILL_PIN -1 + +// Extuder1 +#define HEATER_0_PIN 3 +// Bed +#define HEATER_1_PIN 12 +// Extuder2 +#define HEATER_2_PIN 6 + // Extuder3 +#define HEATER_3_PIN 9 +// Extuder4 +#define HEATER_4_PIN 11 + +// ANALOG NUMBERING Extuder1 +#define TEMP_0_PIN 14 +// ANALOG NUMBERING Bed +#define TEMP_1_PIN 15 +// ANALOG NUMBERING Extuder2 +#define TEMP_2_PIN 13 +// ANALOG NUMBERING Extuder3 +#define TEMP_3_PIN 12 +// ANALOG NUMBERING Extuder4 +#define TEMP_4_PIN 11 + +//PiBot use this pin as Z-Probing pin +#define PiBot_Z_PROBE_PIN 64 + +// ISP for TFcard +#define SDSS 53 +#define SCK_PIN 52 +#define MISO_PIN 50 +#define MOSI_PIN 51 + +#define E0_PINS ORIG_E0_STEP_PIN,ORIG_E0_DIR_PIN,ORIG_E0_ENABLE_PIN, +#define E1_PINS ORIG_E1_STEP_PIN,ORIG_E1_DIR_PIN,ORIG_E1_ENABLE_PIN, +#define E2_PINS ORIG_E2_STEP_PIN,ORIG_E2_DIR_PIN,ORIG_E2_ENABLE_PIN, +#define E3_PINS ORIG_E3_STEP_PIN,ORIG_E3_DIR_PIN,ORIG_E3_ENABLE_PIN, + +#endif // end PiBot for Repetier V1.4 or V1.6 + + +#if PiBot_V_2_0==true +#define ORIG_X_STEP_PIN 24 +#define ORIG_X_DIR_PIN 23 +#define ORIG_X_ENABLE_PIN 22 +#define ORIG_X_MIN_PIN 62 +#define ORIG_X_MAX_PIN 63 + +#define ORIG_Y_STEP_PIN 27 +#define ORIG_Y_DIR_PIN 26 +#define ORIG_Y_ENABLE_PIN 25 +#define ORIG_Y_MIN_PIN 64 +#define ORIG_Y_MAX_PIN 65 + +#define ORIG_Z_STEP_PIN 15 +#define ORIG_Z_DIR_PIN 14 +#define ORIG_Z_ENABLE_PIN 39 +#define ORIG_Z_MIN_PIN 66 +#define ORIG_Z_MAX_PIN 67 + +#define ORIG_E0_STEP_PIN 32 +#define ORIG_E0_DIR_PIN 31 +#define ORIG_E0_ENABLE_PIN 30 + +#define ORIG_E1_STEP_PIN 35 +#define ORIG_E1_DIR_PIN 34 +#define ORIG_E1_ENABLE_PIN 33 + +// ========================================= +#define PiBot_Z_PROBE_PIN 68 // PiBot use this pin as Z-Probing pin + +#define LED_PIN -1 + +// PWM6 fan1 +#define ORIG_FAN_PIN 6 + // PWM7 fan2 +#define ORIG_FAN2_PIN 7 + +// have hardware in PiBot HDV2.0 +#define ORIG_PS_ON_PIN 17 +#define KILL_PIN -1 + +// PWM5 Extuder1 +#define HEATER_0_PIN 5 +// PWM4 Bed +#define HEATER_1_PIN 4 +// PWM2 Extuder2 +#define HEATER_2_PIN 2 +// for Pibot PWM Extuder3 +#define HEATER_3_PIN -1 +// for Pibot PWM Extuder4 +#define HEATER_4_PIN -1 + +#if Thermistor_Solution==0 // 000 0 2 4 +// ANALOG NUMBERING Extuder1 +#define TEMP_0_PIN 2 +// ANALOG NUMBERING Bed +#define TEMP_1_PIN 0 +// ANALOG NUMBERING Extuder2 +#define TEMP_2_PIN 4 +#endif +#if Thermistor_Solution==1 // 001 1 2 4 +// ANALOG NUMBERING Extuder1 +#define TEMP_0_PIN 2 +// ANALOG NUMBERING Bed +#define TEMP_1_PIN 1 +// ANALOG NUMBERING Extuder2 +#define TEMP_2_PIN 4 +#endif +#if Thermistor_Solution==2 // 010 0 3 4 +#define TEMP_0_PIN 3 +// ANALOG NUMBERING Bed +#define TEMP_1_PIN 0 +// ANALOG NUMBERING Extuder2 +#define TEMP_2_PIN 4 +#endif +#if Thermistor_Solution==3 // 011 1 3 4 +// ANALOG NUMBERING Extuder1 +#define TEMP_0_PIN 3 +#define TEMP_1_PIN 1 +// ANALOG NUMBERING Extuder2 +#define TEMP_2_PIN 4 +#endif +#if Thermistor_Solution==4 // 100 0 2 5 +// ANALOG NUMBERING Extuder1 +#define TEMP_0_PIN 2 +// ANALOG NUMBERING Bed +#define TEMP_1_PIN 0 +// ANALOG NUMBERING Extuder2 +#define TEMP_2_PIN 5 +#endif +#if Thermistor_Solution==5 // 101 1 2 5 +// ANALOG NUMBERING Extuder1 +#define TEMP_0_PIN 2 +// ANALOG NUMBERING Bed +#define TEMP_1_PIN 1 +// ANALOG NUMBERING Extuder2 +#define TEMP_2_PIN 5 +#endif +#if Thermistor_Solution==6 // 110 0 3 5 +// ANALOG NUMBERING Extuder1 +#define TEMP_0_PIN 3 +// ANALOG NUMBERING Bed +#define TEMP_1_PIN 0 +// ANALOG NUMBERING Extuder2 +#define TEMP_2_PIN 5 +#endif +#if Thermistor_Solution==7 // 111 1 3 5 +// ANALOG NUMBERING Extuder1 +#define TEMP_0_PIN 3 +// ANALOG NUMBERING Bed +#define TEMP_1_PIN 1 +// ANALOG NUMBERING Extuder2 +#define TEMP_2_PIN 5 +#endif +#if !defined(TEMP_0_PIN) || !defined(TEMP_1_PIN) || !defined(TEMP_2_PIN) ||!defined(Thermistor_Solution) +// ANALOG NUMBERING Extuder1 +#define TEMP_0_PIN 2 +// ANALOG NUMBERING Bed +#define TEMP_1_PIN 0 +// ANALOG NUMBERING Extuder2 +#define TEMP_2_PIN 4 +#endif + +// ad595 temp senser +#if AD595_TEMP_Senser==true +// ANALOG NUMBERING Extuder1 +#define TEMP_0_PIN 8 +// ANALOG NUMBERING Bed +#define TEMP_1_PIN 9 +// ANALOG NUMBERING Extuder2 +#define TEMP_2_PIN 10 +#endif + +// max6675 ISP port temp->ISP-ENABLE +// these enable pins have been isolated by capacitor +/*#if MAX6675_TEMP_Senser==true +// ANALOG NUMBERING Extuder1 +#define TEMP_0_PIN 14 // ANALOG NUMBERING Extuder1 +#define TEMP_1_PIN 15 // ANALOG NUMBERING Bed +#define TEMP_2_PIN 13 // ANALOG NUMBERING Extuder2 +//uncomment when 3 extruder used +#define TEMP_3_PIN 12 // ANALOG NUMBERING Extuder3 +#endif*/ + +// ISP for TFcard +#define SDPOWER -1 +#define ORIG_SDCARDDETECT 40 +#define SDSS 53 +#define SCK_PIN 52 +#define MISO_PIN 50 +#define MOSI_PIN 51 + +#define E0_PINS ORIG_E0_STEP_PIN,ORIG_E0_DIR_PIN,ORIG_E0_ENABLE_PIN, +#define E1_PINS ORIG_E1_STEP_PIN,ORIG_E1_DIR_PIN,ORIG_E1_ENABLE_PIN, + +#endif // end PiBot Controller Rev 2.0 + +#endif // end PiBot for Repetier + +/**************************************************************************************** +* Sanguish Beta pin assignment +* +****************************************************************************************/ +#if MOTHERBOARD == 501 +#define KNOWN_BOARD + +#if !defined(__AVR_ATmega644P__) && !defined(__AVR_ATmega644__) && !defined(__AVR_ATmega1284P__) +#error Oops! Make sure you have 'Your MCU/Bootloader' selected from the 'Tools -> Boards' menu. +#endif + +//x axis pins +#define ORIG_X_STEP_PIN 28 +#define ORIG_X_DIR_PIN 27 +#define ORIG_X_ENABLE_PIN 29 +#define ORIG_X_MIN_PIN 2 +#define ORIG_X_MAX_PIN -1 + +//y axis pins +#define ORIG_Y_STEP_PIN 25 +#define ORIG_Y_DIR_PIN 24 +#define ORIG_Y_ENABLE_PIN 26 +#define ORIG_Y_MIN_PIN 5 +#define ORIG_Y_MAX_PIN -1 + +//z axis pins +#define ORIG_Z_STEP_PIN 22 +#define ORIG_Z_DIR_PIN 21 +#define ORIG_Z_ENABLE_PIN 23 +#define ORIG_Z_MIN_PIN 1 +#define ORIG_Z_MAX_PIN -1 + +//extruder pins +#define ORIG_E0_STEP_PIN 19 +#define ORIG_E0_DIR_PIN 18 +#define ORIG_E0_ENABLE_PIN 20 +#define TEMP_0_PIN 1 +#define TEMP_1_PIN 0 +#define HEATER_0_PIN 3 +#define HEATER_1_PIN 4 + + +#define SDPOWER -1 +#define SDSS -1 +#define LED_PIN -1 + +#define ORIG_FAN_PIN -1 +#define ORIG_PS_ON_PIN 0 +//our pin for debugging. + +#define DEBUG_PIN -1 + +//our RS485 pins +#define TX_ENABLE_PIN 12 +#define RX_ENABLE_PIN 13 + +#define SDPOWER -1 +#define SDSS -1 + +#define SCK_PIN 7 +#define MISO_PIN 6 +#define MOSI_PIN 5 +#define E0_PINS ORIG_E0_STEP_PIN,ORIG_E0_DIR_PIN,ORIG_E0_ENABLE_PIN, +#define E1_PINS +#endif + + +#if MOTHERBOARD == 999 +#define KNOWN_BOARD +#include "userpins.h" +#endif + + + +#ifndef CPU_ARCH // Set default architecture +#define CPU_ARCH ARCH_AVR +#endif + +#ifndef SDSSORIG +#define SDSSORIG -1 +#endif + +#ifndef STEPPER_CURRENT_CONTROL // Set default stepper current control if not set yet. +#define STEPPER_CURRENT_CONTROL CURRENT_CONTROL_MANUAL +#endif + +#ifndef FAN_BOARD_PIN +#define FAN_BOARD_PIN -1 +#endif + +#ifndef E2_PINS +#define E2_PINS +#endif + +#if NUM_EXTRUDER==1 +#undef E1_PINS +#define E1_PINS +#endif + +#if NUM_EXTRUDER < 3 +#undef E2_PINS +#define E2_PINS +#endif + +#ifndef HEATER_PINS_INVERTED +#define HEATER_PINS_INVERTED 0 +#endif + +// Original pin assignmats to be used in configuration tool +#define X_STEP_PIN ORIG_X_STEP_PIN +#define X_DIR_PIN ORIG_X_DIR_PIN +#define X_ENABLE_PIN ORIG_X_ENABLE_PIN +#define X_MIN_PIN ORIG_X_MIN_PIN +#define X_MAX_PIN ORIG_X_MAX_PIN + +#define Y_STEP_PIN ORIG_Y_STEP_PIN +#define Y_DIR_PIN ORIG_Y_DIR_PIN +#define Y_ENABLE_PIN ORIG_Y_ENABLE_PIN +#define Y_MIN_PIN ORIG_Y_MIN_PIN +#define Y_MAX_PIN ORIG_Y_MAX_PIN + +#define Z_STEP_PIN ORIG_Z_STEP_PIN +#define Z_DIR_PIN ORIG_Z_DIR_PIN +#define Z_ENABLE_PIN ORIG_Z_ENABLE_PIN +#define Z_MIN_PIN ORIG_Z_MIN_PIN +#define Z_MAX_PIN ORIG_Z_MAX_PIN + +#define E0_STEP_PIN ORIG_E0_STEP_PIN +#define E0_DIR_PIN ORIG_E0_DIR_PIN +#define E0_ENABLE_PIN ORIG_E0_ENABLE_PIN + +#define E1_STEP_PIN ORIG_E1_STEP_PIN +#define E1_DIR_PIN ORIG_E1_DIR_PIN +#define E1_ENABLE_PIN ORIG_E1_ENABLE_PIN + +#define E2_STEP_PIN ORIG_E2_STEP_PIN +#define E2_DIR_PIN ORIG_E2_DIR_PIN +#define E2_ENABLE_PIN ORIG_E2_ENABLE_PIN + +#define E3_STEP_PIN ORIG_E3_STEP_PIN +#define E3_DIR_PIN ORIG_E3_DIR_PIN +#define E3_ENABLE_PIN ORIG_E3_ENABLE_PIN + +#define E4_STEP_PIN ORIG_E4_STEP_PIN +#define E4_DIR_PIN ORIG_E4_DIR_PIN +#define E4_ENABLE_PIN ORIG_E4_ENABLE_PIN + +#define E5_STEP_PIN ORIG_E5_STEP_PIN +#define E5_DIR_PIN ORIG_E5_DIR_PIN +#define E5_ENABLE_PIN ORIG_E5_ENABLE_PIN + +#define FAN_PIN ORIG_FAN_PIN +#ifdef ORIG_FAN2_PIN +#define FAN2_PIN ORIG_FAN2_PIN +#endif + +#define PS_ON_PIN ORIG_PS_ON_PIN + +#ifndef ORIG_SDCARDDETECT +#define ORIG_SDCARDDETECT -1 +#endif +#define SDCARDDETECT ORIG_SDCARDDETECT + +#define SENSITIVE_PINS {0, 1, ORIG_X_STEP_PIN, ORIG_X_DIR_PIN, ORIG_X_ENABLE_PIN, ORIG_X_MIN_PIN, ORIG_X_MAX_PIN, \ + ORIG_Y_STEP_PIN, ORIG_Y_DIR_PIN, ORIG_Y_ENABLE_PIN, ORIG_Y_MIN_PIN, ORIG_Y_MAX_PIN, ORIG_Z_STEP_PIN,\ + ORIG_Z_DIR_PIN, ORIG_Z_ENABLE_PIN, ORIG_Z_MIN_PIN, ORIG_Z_MAX_PIN, LED_PIN, ORIG_PS_ON_PIN, \ + HEATER_0_PIN, HEATER_1_PIN, /*ORIG_FAN_PIN,*/ E0_PINS E1_PINS E2_PINS TEMP_0_PIN, TEMP_1_PIN,SDSS } +#endif + diff --git a/trunk/Arduino/Repetier_0.92.9/u8glib_ex.h b/trunk/Arduino/Repetier_0.92.9/u8glib_ex.h new file mode 100644 index 00000000..27144f19 --- /dev/null +++ b/trunk/Arduino/Repetier_0.92.9/u8glib_ex.h @@ -0,0 +1,10713 @@ +/* + + U8glib.cpp + + C++ Interface + + 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. + + +The U8glib code (http://code.google.com/p/u8glib/) is licensed under the terms of +the new-bsd license (two-clause bsd license). +See also: http://www.opensource.org/licenses/bsd-license.php + +The repository and optionally the releases contain icons, which are +derived from the WPZOOM Developer Icon Set: +http://www.wpzoom.com/wpzoom/new-freebie-wpzoom-developer-icon-set-154-free-icons/ +WPZOOM Developer Icon Set by WPZOOM is licensed under a Creative Commons +Attribution-ShareAlike 3.0 Unported License. + +Fonts are licensed under different conditions. +See http://code.google.com/p/u8glib/wiki/fontgroup for +detailed information on the licensing conditions for each font. + +============ X11 Fonts COUR, HELV, NCEN, TIM, SYMB ============ + +For fonts derived from the following files, the license below applies. +COURB08.BDF COURB10.BDF COURB12.BDF COURB14.BDF COURB18.BDF +COURB24.BDF COURR08.BDF COURR10.BDF COURR12.BDF COURR14.BDF +COURR18.BDF COURR24.BDF HELVB08.BDF HELVB10.BDF HELVB12.BDF HELVB14.BDF +HELVB18.BDF HELVB24.BDF HELVR08.BDF HELVR10.BDF HELVR12.BDF HELVR14.BDF +HELVR18.BDF HELVR24.BDF NCENB08.BDF NCENB10.BDF NCENB12.BDF +NCENB14.BDF NCENB18.BDF NCENB24.BDF NCENR08.BDF NCENR10.BDF +NCENR12.BDF NCENR14.BDF NCENR18.BDF NCENR24.BDF SYMB08.BDF SYMB10.BDF +SYMB12.BDF SYMB14.BDF SYMB18.BDF SYMB24.BDF TIMB08.BDF TIMB10.BDF +TIMB12.BDF TIMB14.BDF TIMB18.BDF TIMB24.BDF TIMR08.BDF TIMR10.BDF +TIMR12.BDF TIMR14.BDF TIMR18.BDF TIMR24.BDF + +Copyright 1984-1989, 1994 Adobe Systems Incorporated. +Copyright 1988, 1994 Digital Equipment Corporation. + +Adobe is a trademark of Adobe Systems Incorporated which may be +registered in certain jurisdictions. +Permission to use these trademarks is hereby granted only in +association with the images described in this file. + +Permission to use, copy, modify, distribute and sell this software +and its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notices appear in all +copies and that both those copyright notices and this permission +notice appear in supporting documentation, and that the names of +Adobe Systems and Digital Equipment Corporation not be used in +advertising or publicity pertaining to distribution of the software +without specific, written prior permission. Adobe Systems and +Digital Equipment Corporation make no representations about the +suitability of this software for any purpose. It is provided "as +is" without express or implied warranty. + + +============ BSD License for U8glib Code ============ + +Universal 8bit Graphics Library (http://code.google.com/p/u8glib/) + +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. + +*/ + +// these warnings appear and are no problem. +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-variable" +#pragma GCC diagnostic ignored "-Wunused-parameter" + +// ============= u8g.h ==================== + +/* + + u8g.h + + 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. + +*/ + +#ifndef _U8G_H +#define _U8G_H + + +/* uncomment the following line to support displays larger than 240x240 */ +//#define U8G_16BIT 1 + +/* comment the following line to generate more compact but interrupt unsafe code */ +#define U8G_INTERRUPT_SAFE 1 + + +#include + +#ifdef __18CXX +typedef unsigned char uint8_t; +typedef signed char int8_t; +typedef unsigned short uint16_t; +typedef signed short int16_t; +#else +#include +#endif + +#if defined(__AVR__) +#include +#endif + +/* + use the com interface directly on any systems which are not AVR or ARDUINO +*/ +#if defined(__AVR__) || defined(ARDUINO) +#define U8G_WITH_PINLIST +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + + +/*===============================================================*/ +#ifdef __GNUC__ +# define U8G_NOINLINE __attribute__((noinline)) +# define U8G_PURE __attribute__ ((pure)) +# define U8G_NOCOMMON __attribute__ ((nocommon)) +# define U8G_SECTION(name) __attribute__ ((section (name))) +# if defined(__MSPGCC__) +/* mspgcc does not have .progmem sections. Use -fdata-sections. */ +# define U8G_FONT_SECTION(name) +# endif +# if defined(__AVR__) +# define U8G_FONT_SECTION(name) U8G_SECTION(".progmem." name) +# endif +#else +# define U8G_NOINLINE +# define U8G_PURE +# define U8G_NOCOMMON +# define U8G_SECTION(name) +#endif + +#ifndef U8G_FONT_SECTION +# define U8G_FONT_SECTION(name) +#endif + + +/*===============================================================*/ +/* flash memory access */ + +#if defined(__AVR__) +/* U8G_PROGMEM is used by the XBM example */ +#define U8G_PROGMEM U8G_SECTION(".progmem.data") +typedef uint8_t PROGMEM u8g_pgm_uint8_t; +typedef uint8_t u8g_fntpgm_uint8_t; +#define u8g_pgm_read(adr) pgm_read_byte_near(adr) +#define U8G_PSTR(s) ((u8g_pgm_uint8_t *)PSTR(s)) + +#else + +#define U8G_PROGMEM +#define PROGMEM +typedef uint8_t u8g_pgm_uint8_t; +typedef uint8_t u8g_fntpgm_uint8_t; +#define u8g_pgm_read(adr) (*(const u8g_pgm_uint8_t *)(adr)) +#define U8G_PSTR(s) ((u8g_pgm_uint8_t *)(s)) + +#endif + +/*===============================================================*/ +/* interrupt safe code */ +#if defined(U8G_INTERRUPT_SAFE) +# if defined(__AVR__) +extern uint8_t global_SREG_backup; /* u8g_state.c */ +# define U8G_ATOMIC_START() do { global_SREG_backup = SREG; cli(); } while(0) +# define U8G_ATOMIC_END() SREG = global_SREG_backup +# define U8G_ATOMIC_OR(ptr, val) do { uint8_t tmpSREG = SREG; cli(); (*(ptr) |= (val)); SREG = tmpSREG; } while(0) +# define U8G_ATOMIC_AND(ptr, val) do { uint8_t tmpSREG = SREG; cli(); (*(ptr) &= (val)); SREG = tmpSREG; } while(0) +# else +# define U8G_ATOMIC_OR(ptr, val) (*(ptr) |= (val)) +# define U8G_ATOMIC_AND(ptr, val) (*(ptr) &= (val)) +# define U8G_ATOMIC_START() +# define U8G_ATOMIC_END() +# endif /* __AVR__ */ +#else +# define U8G_ATOMIC_OR(ptr, val) (*(ptr) |= (val)) +# define U8G_ATOMIC_AND(ptr, val) (*(ptr) &= (val)) +# define U8G_ATOMIC_START() +# define U8G_ATOMIC_END() +#endif /* U8G_INTERRUPT_SAFE */ + + +/*===============================================================*/ +/* forward */ +typedef struct _u8g_t u8g_t; +typedef struct _u8g_dev_t u8g_dev_t; + +typedef struct _u8g_dev_arg_pixel_t u8g_dev_arg_pixel_t; +typedef struct _u8g_dev_arg_bbx_t u8g_dev_arg_bbx_t; +typedef struct _u8g_box_t u8g_box_t; +typedef struct _u8g_dev_arg_irgb_t u8g_dev_arg_irgb_t; + + +/*===============================================================*/ +/* generic */ +#if defined(U8G_16BIT) +typedef uint16_t u8g_uint_t; +typedef int16_t u8g_int_t; +#else +typedef uint8_t u8g_uint_t; +typedef int8_t u8g_int_t; +#endif + +#ifdef OBSOLETE +struct _u8g_box_t +{ + u8g_uint_t x0, y0, x1, y1; +}; +typedef struct _u8g_box_t u8g_box_t; +#endif /* OBSOLETE */ + + +/*===============================================================*/ +/* device structure */ + +#ifdef __XC8 +/* device prototype */ +typedef uint8_t (*u8g_dev_fnptr)(void *u8g, void *dev, uint8_t msg, void *arg); + +/* com prototype */ +typedef uint8_t (*u8g_com_fnptr)(void *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); +#else +/* device prototype */ +typedef uint8_t (*u8g_dev_fnptr)(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg); + +/* com prototype */ +typedef uint8_t (*u8g_com_fnptr)(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); +#endif + + + +struct _u8g_dev_t +{ + u8g_dev_fnptr dev_fn; /* device procedure */ + void *dev_mem; /* device memory */ + u8g_com_fnptr com_fn; /* communication procedure */ +}; + + +/*===============================================================*/ +/* device list */ + +/* Size: 128x64 SDL, u8g_dev_sdl.c */ +extern u8g_dev_t u8g_dev_sdl_1bit; +extern u8g_dev_t u8g_dev_sdl_1bit_h; +extern u8g_dev_t u8g_dev_sdl_2bit; +extern u8g_dev_t u8g_dev_sdl_2bit_double_mem; +extern u8g_dev_t u8g_dev_sdl_8bit; +extern u8g_dev_t u8g_dev_sdl_hicolor; +extern u8g_dev_t u8g_dev_sdl_fullcolor; +int u8g_sdl_get_key(void); + +/* Size: 70x30 monochrom, stdout */ +extern u8g_dev_t u8g_dev_stdout; + +/* Size: monochrom, writes "u8g.pbm" */ +extern u8g_dev_t u8g_dev_pbm; +extern u8g_dev_t u8g_dev_pbm_8h1; +extern u8g_dev_t u8g_dev_pbm_8h2; /* grayscale simulation */ + +/* Size: 128x64 monochrom, no output, used for performance measure */ +extern u8g_dev_t u8g_dev_gprof; + +/* Display: EA DOGS102, Size: 102x64 monochrom */ +extern u8g_dev_t u8g_dev_uc1701_dogs102_sw_spi; +extern u8g_dev_t u8g_dev_uc1701_dogs102_hw_spi; + +extern u8g_dev_t u8g_dev_uc1701_dogs102_2x_sw_spi; +extern u8g_dev_t u8g_dev_uc1701_dogs102_2x_hw_spi; + +/* Display: Mini12864 (dealextreme), Size: 128x64 monochrom */ +extern u8g_dev_t u8g_dev_uc1701_mini12864_sw_spi; +extern u8g_dev_t u8g_dev_uc1701_mini12864_hw_spi; + +extern u8g_dev_t u8g_dev_uc1701_mini12864_2x_sw_spi; +extern u8g_dev_t u8g_dev_uc1701_mini12864_2x_hw_spi; + +/* Display: EA DOGM132, Size: 128x32 monochrom */ +extern u8g_dev_t u8g_dev_st7565_dogm132_sw_spi; +extern u8g_dev_t u8g_dev_st7565_dogm132_hw_spi; + +/* Display: EA DOGM128, Size: 128x64 monochrom */ +extern u8g_dev_t u8g_dev_st7565_dogm128_sw_spi; +extern u8g_dev_t u8g_dev_st7565_dogm128_hw_spi; +extern u8g_dev_t u8g_dev_st7565_dogm128_parallel; + +extern u8g_dev_t u8g_dev_st7565_dogm128_2x_sw_spi; +extern u8g_dev_t u8g_dev_st7565_dogm128_2x_hw_spi; +extern u8g_dev_t u8g_dev_st7565_dogm128_2x_parallel; + +/* Display: Topway LM6059 128x64 (Adafruit) */ +extern u8g_dev_t u8g_dev_st7565_lm6059_sw_spi; +extern u8g_dev_t u8g_dev_st7565_lm6059_hw_spi; +extern u8g_dev_t u8g_dev_st7565_lm6059_2x_sw_spi; +extern u8g_dev_t u8g_dev_st7565_lm6059_2x_hw_spi; +/* Display: Topway LM6063 128x64 */ +extern u8g_dev_t u8g_dev_st7565_lm6063_sw_spi; +extern u8g_dev_t u8g_dev_st7565_lm6063_hw_spi; +extern u8g_dev_t u8g_dev_st7565_lm6063_2x_sw_spi; +extern u8g_dev_t u8g_dev_st7565_lm6063_2x_hw_spi; +/* Display: Newhaven NHD-C12864 */ +extern u8g_dev_t u8g_dev_st7565_nhd_c12864_sw_spi; +extern u8g_dev_t u8g_dev_st7565_nhd_c12864_hw_spi; +extern u8g_dev_t u8g_dev_st7565_nhd_c12864_2x_sw_spi; +extern u8g_dev_t u8g_dev_st7565_nhd_c12864_2x_hw_spi; + +/* Display: Newhaven NHD-C12832 */ +extern u8g_dev_t u8g_dev_st7565_nhd_c12832_sw_spi; +extern u8g_dev_t u8g_dev_st7565_nhd_c12832_hw_spi; +extern u8g_dev_t u8g_dev_st7565_nhd_c12832_parallel; +extern u8g_dev_t u8g_dev_st7565_nhd_c12832_hw_usart_spi; + +/* Display: Displaytech 64128N */ +extern u8g_dev_t u8g_dev_st7565_64128n_sw_spi; +extern u8g_dev_t u8g_dev_st7565_64128n_hw_spi; +extern u8g_dev_t u8g_dev_st7565_64128n_parallel; + +extern u8g_dev_t u8g_dev_st7565_64128n_2x_sw_spi; +extern u8g_dev_t u8g_dev_st7565_64128n_2x_hw_spi; +extern u8g_dev_t u8g_dev_st7565_64128n_2x_parallel; + +/* Display: LCD-AG-C128032R-DIW W/KK E6 PBF */ +extern u8g_dev_t u8g_dev_uc1601_c128032_sw_spi; +extern u8g_dev_t u8g_dev_uc1601_c128032_hw_spi; + +extern u8g_dev_t u8g_dev_uc1601_c128032_2x_sw_spi; +extern u8g_dev_t u8g_dev_uc1601_c128032_2x_hw_spi; + +/* dfrobot 128x64 Graphic LCD (SKU:FIT0021) */ +extern u8g_dev_t u8g_dev_st7920_128x64_sw_spi; +extern u8g_dev_t u8g_dev_st7920_128x64_hw_spi; +extern u8g_dev_t u8g_dev_st7920_128x64_8bit; +extern u8g_dev_t u8g_dev_st7920_128x64_custom; + +extern u8g_dev_t u8g_dev_st7920_128x64_4x_sw_spi; +extern u8g_dev_t u8g_dev_st7920_128x64_4x_hw_spi; +extern u8g_dev_t u8g_dev_st7920_128x64_4x_8bit; +extern u8g_dev_t u8g_dev_st7920_128x64_4x_custom; + +/* NHD-19232WG */ +extern u8g_dev_t u8g_dev_st7920_192x32_sw_spi; +extern u8g_dev_t u8g_dev_st7920_192x32_hw_spi; +extern u8g_dev_t u8g_dev_st7920_192x32_8bit; + +extern u8g_dev_t u8g_dev_st7920_192x32_4x_sw_spi; +extern u8g_dev_t u8g_dev_st7920_192x32_4x_hw_spi; +extern u8g_dev_t u8g_dev_st7920_192x32_4x_8bit; + +/* CrystalFontz CFAG20232 */ +extern u8g_dev_t u8g_dev_st7920_202x32_sw_spi; +extern u8g_dev_t u8g_dev_st7920_202x32_hw_spi; +extern u8g_dev_t u8g_dev_st7920_202x32_8bit; + +extern u8g_dev_t u8g_dev_st7920_202x32_4x_sw_spi; +extern u8g_dev_t u8g_dev_st7920_202x32_4x_hw_spi; +extern u8g_dev_t u8g_dev_st7920_202x32_4x_8bit; + +/* LC7981 160x80 display */ +extern u8g_dev_t u8g_dev_lc7981_160x80_8bit; +/* LC7981 240x64 display */ +extern u8g_dev_t u8g_dev_lc7981_240x64_8bit; +/* LC7981 240x128 display */ +extern u8g_dev_t u8g_dev_lc7981_240x128_8bit; +/* LC7981 320x64 display */ +extern u8g_dev_t u8g_dev_lc7981_320x64_8bit; + +/* T6963, all t6963 devices have double page (2x) */ +extern u8g_dev_t u8g_dev_t6963_240x128_8bit; +extern u8g_dev_t u8g_dev_t6963_240x64_8bit; +extern u8g_dev_t u8g_dev_t6963_128x64_8bit; + +/* Display: EA DOGXL160, Size: 160x104 monochrom & gray level */ +extern u8g_dev_t u8g_dev_uc1610_dogxl160_bw_sw_spi; +extern u8g_dev_t u8g_dev_uc1610_dogxl160_bw_hw_spi; +extern u8g_dev_t u8g_dev_uc1610_dogxl160_gr_sw_spi; +extern u8g_dev_t u8g_dev_uc1610_dogxl160_gr_hw_spi; + +extern u8g_dev_t u8g_dev_uc1610_dogxl160_2x_bw_sw_spi; +extern u8g_dev_t u8g_dev_uc1610_dogxl160_2x_bw_hw_spi; +extern u8g_dev_t u8g_dev_uc1610_dogxl160_2x_gr_sw_spi; +extern u8g_dev_t u8g_dev_uc1610_dogxl160_2x_gr_hw_spi; + +/* Display: Generic KS0108b, Size: 128x64 monochrom */ +extern u8g_dev_t u8g_dev_ks0108_128x64; /* official Arduino Library interface */ +extern u8g_dev_t u8g_dev_ks0108_128x64_fast; /* faster, but uses private tables from the Arduino Library */ + +/* Nokia 84x48 Display with PCD8544 */ +extern u8g_dev_t u8g_dev_pcd8544_84x48_sw_spi; +extern u8g_dev_t u8g_dev_pcd8544_84x48_hw_spi; +extern u8g_dev_t u8g_dev_tls8204_84x48_sw_spi; + +/* Nokia 96x65 Display with PCF8812 */ +extern u8g_dev_t u8g_dev_pcf8812_96x65_sw_spi; +extern u8g_dev_t u8g_dev_pcf8812_96x65_hw_spi; + +/* NHD-2.7-12864UCY3 OLED Display with SSD1325 Controller */ +extern u8g_dev_t u8g_dev_ssd1325_nhd27oled_bw_sw_spi; +extern u8g_dev_t u8g_dev_ssd1325_nhd27oled_bw_hw_spi; +extern u8g_dev_t u8g_dev_ssd1325_nhd27oled_bw_parallel; +extern u8g_dev_t u8g_dev_ssd1325_nhd27oled_gr_sw_spi; +extern u8g_dev_t u8g_dev_ssd1325_nhd27oled_gr_hw_spi; + +extern u8g_dev_t u8g_dev_ssd1325_nhd27oled_2x_bw_sw_spi; +extern u8g_dev_t u8g_dev_ssd1325_nhd27oled_2x_bw_hw_spi; +extern u8g_dev_t u8g_dev_ssd1325_nhd27oled_2x_bw_parallel; +extern u8g_dev_t u8g_dev_ssd1325_nhd27oled_2x_gr_sw_spi; +extern u8g_dev_t u8g_dev_ssd1325_nhd27oled_2x_gr_hw_spi; + +/* LY120 OLED with SSD1327 Controller (tested with Seeedstudio module) */ +extern u8g_dev_t u8g_dev_ssd1327_96x96_gr_sw_spi; +extern u8g_dev_t u8g_dev_ssd1327_96x96_gr_hw_spi; +extern u8g_dev_t u8g_dev_ssd1327_96x96_gr_i2c; + +extern u8g_dev_t u8g_dev_ssd1327_96x96_2x_gr_sw_spi; +extern u8g_dev_t u8g_dev_ssd1327_96x96_2x_gr_hw_spi; +extern u8g_dev_t u8g_dev_ssd1327_96x96_2x_gr_i2c; + +/* NHD-3.12-25664 OLED Display with SSD1322 Controller */ +extern u8g_dev_t u8g_dev_ssd1322_nhd31oled_bw_sw_spi; +extern u8g_dev_t u8g_dev_ssd1322_nhd31oled_bw_hw_spi; +extern u8g_dev_t u8g_dev_ssd1322_nhd31oled_bw_parallel; +extern u8g_dev_t u8g_dev_ssd1322_nhd31oled_2x_bw_sw_spi; +extern u8g_dev_t u8g_dev_ssd1322_nhd31oled_2x_bw_hw_spi; + +extern u8g_dev_t u8g_dev_ssd1322_nhd31oled_gr_sw_spi; +extern u8g_dev_t u8g_dev_ssd1322_nhd31oled_gr_hw_spi; +extern u8g_dev_t u8g_dev_ssd1322_nhd31oled_gr_parallel; +extern u8g_dev_t u8g_dev_ssd1322_nhd31oled_2x_gr_sw_spi; +extern u8g_dev_t u8g_dev_ssd1322_nhd31oled_2x_gr_hw_spi; + +/* OLED 128x64 Display with SSD1306 Controller */ +extern u8g_dev_t u8g_dev_ssd1306_128x64_sw_spi; +extern u8g_dev_t u8g_dev_ssd1306_128x64_hw_spi; +extern u8g_dev_t u8g_dev_ssd1306_128x64_i2c; + +extern u8g_dev_t u8g_dev_ssd1306_128x64_2x_sw_spi; +extern u8g_dev_t u8g_dev_ssd1306_128x64_2x_hw_spi; +extern u8g_dev_t u8g_dev_ssd1306_128x64_2x_i2c; + +/* OLED 128x64 Display with SSD1309 Controller */ +extern u8g_dev_t u8g_dev_ssd1309_128x64_sw_spi; +extern u8g_dev_t u8g_dev_ssd1309_128x64_hw_spi; +extern u8g_dev_t u8g_dev_ssd1309_128x64_i2c; + +/* OLED 128x32 Display with SSD1306 Controller */ +extern u8g_dev_t u8g_dev_ssd1306_128x32_sw_spi; +extern u8g_dev_t u8g_dev_ssd1306_128x32_hw_spi; +extern u8g_dev_t u8g_dev_ssd1306_128x32_i2c; + +extern u8g_dev_t u8g_dev_ssd1306_128x32_2x_sw_spi; +extern u8g_dev_t u8g_dev_ssd1306_128x32_2x_hw_spi; +extern u8g_dev_t u8g_dev_ssd1306_128x32_2x_i2c; + +/* experimental 65K TFT with st7687 controller */ +extern u8g_dev_t u8g_dev_st7687_c144mvgd_sw_spi; +extern u8g_dev_t u8g_dev_st7687_c144mvgd_8bit; + +/* SBN1661/SED1520 display with 122x32 */ +extern u8g_dev_t u8g_dev_sbn1661_122x32; + +/* flip disc matrix */ +extern u8g_dev_t u8g_dev_flipdisc_2x7; +void u8g_SetFlipDiscCallback(u8g_t *u8g, void (*cb)(uint8_t id, uint8_t page, uint8_t width, uint8_t *row1, uint8_t *row2)); + +/* ILI9325D based TFT */ +extern u8g_dev_t u8g_dev_ili9325d_320x240_8bit; + + +/* SSD1351 OLED (breakout board from http://www.kickstarter.com/projects/ilsoftltd/colour-oled-breakout-board) */ +extern u8g_dev_t u8g_dev_ssd1351_128x128_332_sw_spi; +extern u8g_dev_t u8g_dev_ssd1351_128x128_332_hw_spi; +extern u8g_dev_t u8g_dev_ssd1351_128x128_4x_332_sw_spi; +extern u8g_dev_t u8g_dev_ssd1351_128x128_4x_332_hw_spi; +extern u8g_dev_t u8g_dev_ssd1351_128x128_idx_sw_spi; +extern u8g_dev_t u8g_dev_ssd1351_128x128_idx_hw_spi; +extern u8g_dev_t u8g_dev_ssd1351_128x128_hicolor_sw_spi; +extern u8g_dev_t u8g_dev_ssd1351_128x128_hicolor_hw_spi; +extern u8g_dev_t u8g_dev_ssd1351_128x128_4x_hicolor_sw_spi; +extern u8g_dev_t u8g_dev_ssd1351_128x128_4x_hicolor_hw_spi; + +/* SSD1351 OLED (Freetronics, GPIOs set to high level) */ +extern u8g_dev_t u8g_dev_ssd1351_128x128gh_332_sw_spi; +extern u8g_dev_t u8g_dev_ssd1351_128x128gh_332_hw_spi; +extern u8g_dev_t u8g_dev_ssd1351_128x128gh_4x_332_sw_spi; +extern u8g_dev_t u8g_dev_ssd1351_128x128gh_4x_332_hw_spi; +extern u8g_dev_t u8g_dev_ssd1351_128x128gh_hicolor_sw_spi; +extern u8g_dev_t u8g_dev_ssd1351_128x128gh_hicolor_hw_spi; +extern u8g_dev_t u8g_dev_ssd1351_128x128gh_4x_hicolor_sw_spi; +extern u8g_dev_t u8g_dev_ssd1351_128x128gh_4x_hicolor_hw_spi; + +/* HT1632 */ +extern u8g_dev_t u8g_dev_ht1632_24x16; + +/* A2 Micro Printer */ +extern u8g_dev_t u8g_dev_a2_micro_printer_384x240; +extern u8g_dev_t u8g_dev_a2_micro_printer_192x120_ds; + +/* u8g_virtual_screen.c */ +extern u8g_dev_t u8g_dev_vs; + + +/*===============================================================*/ +/* device messages */ + +struct _u8g_dev_arg_pixel_t +{ + u8g_uint_t x, y; /* will be modified */ + uint8_t pixel; /* will be modified, pixel sequence or transparency value */ + uint8_t dir; + uint8_t color; /* color or index value, red value for true color mode */ + uint8_t hi_color; /* high byte for 64K color mode, low byte is in "color", green value for true color mode */ + uint8_t blue; /* blue value in true color mode */ +}; +/* typedef struct _u8g_dev_arg_pixel_t u8g_dev_arg_pixel_t; */ /* forward decl */ + +/* range for r,g,b: 0..255 */ +#define U8G_GET_HICOLOR_BY_RGB(r,g,b) (((uint16_t)((r)&0x0f8))<<8)|(((uint16_t)((g)&0x0fc))<<3)|(((uint16_t)((b)>>3))) + +struct _u8g_dev_arg_bbx_t +{ + u8g_uint_t x, y, w, h; +}; +/* typedef struct _u8g_dev_arg_bbx_t u8g_dev_arg_bbx_t; */ /* forward decl */ + +struct _u8g_box_t +{ + u8g_uint_t x0, y0, x1, y1; +}; +/* typedef struct _u8g_box_t u8g_box_t; */ /* forward decl */ + +struct _u8g_dev_arg_irgb_t +{ + u8g_uint_t idx, r, g, b; /* index with rgb value */ +}; +/* typedef struct _u8g_dev_arg_irgb_t u8g_dev_arg_irgb_t; */ /* forward decl */ + + + +#define U8G_DEV_MSG_INIT 10 +#define U8G_DEV_MSG_STOP 11 + +/* arg: pointer to uint8_t, contranst value between 0 and 255 */ +#define U8G_DEV_MSG_CONTRAST 15 + +#define U8G_DEV_MSG_SLEEP_ON 16 +#define U8G_DEV_MSG_SLEEP_OFF 17 + +#define U8G_DEV_MSG_PAGE_FIRST 20 +#define U8G_DEV_MSG_PAGE_NEXT 21 + +/* arg: u8g_dev_arg_bbx_t * */ +/* new algorithm with U8G_DEV_MSG_GET_PAGE_BOX makes this msg obsolete */ +/* #define U8G_DEV_MSG_IS_BBX_INTERSECTION 22 */ + +/* arg: u8g_box_t *, fill structure with current page properties */ +#define U8G_DEV_MSG_GET_PAGE_BOX 23 + +/* +#define U8G_DEV_MSG_PRIMITIVE_START 30 +#define U8G_DEV_MSG_PRIMITIVE_END 31 +*/ + +/* arg: u8g_dev_arg_pixel_t * */ +#define U8G_DEV_MSG_SET_TPIXEL 44 +#define U8G_DEV_MSG_SET_4TPIXEL 45 + +#define U8G_DEV_MSG_SET_PIXEL 50 +#define U8G_DEV_MSG_SET_8PIXEL 59 + +#define U8G_DEV_MSG_SET_COLOR_ENTRY 60 + +#define U8G_DEV_MSG_SET_XY_CB 61 + +#define U8G_DEV_MSG_GET_WIDTH 70 +#define U8G_DEV_MSG_GET_HEIGHT 71 +#define U8G_DEV_MSG_GET_MODE 72 + +/*===============================================================*/ +/* device modes */ +#define U8G_MODE(is_index_mode, is_color, bits_per_pixel) (((is_index_mode)<<6) | ((is_color)<<5)|(bits_per_pixel)) + +#define U8G_MODE_UNKNOWN 0 +#define U8G_MODE_BW U8G_MODE(0, 0, 1) +#define U8G_MODE_GRAY2BIT U8G_MODE(0, 0, 2) +#define U8G_MODE_R3G3B2 U8G_MODE(0, 1, 8) +#define U8G_MODE_INDEX U8G_MODE(1, 1, 8) +/* hicolor is R5G6B5 */ +#define U8G_MODE_HICOLOR U8G_MODE(0, 1, 16) +/* truecolor */ +#define U8G_MODE_TRUECOLOR U8G_MODE(0, 1, 24) + + +#define U8G_MODE_GET_BITS_PER_PIXEL(mode) ((mode)&31) +#define U8G_MODE_IS_COLOR(mode) (((mode)&32)==0?0:1) +#define U8G_MODE_IS_INDEX_MODE(mode) (((mode)&64)==0?0:1) + + +/*===============================================================*/ +/* com options */ + +/* uncomment the following line for Atmega HW SPI double speed, issue 89 */ +/* #define U8G_HW_SPI_2X 1 */ + +/* com messages */ + +#define U8G_COM_MSG_STOP 0 +#define U8G_COM_MSG_INIT 1 + +#define U8G_COM_MSG_ADDRESS 2 + +/* CHIP_SELECT argument: number of the chip which needs to be activated, so this is more like high active */ +#define U8G_COM_MSG_CHIP_SELECT 3 + +#define U8G_COM_MSG_RESET 4 + +#define U8G_COM_MSG_WRITE_BYTE 5 +#define U8G_COM_MSG_WRITE_SEQ 6 +#define U8G_COM_MSG_WRITE_SEQ_P 7 + + +/* com driver */ +uint8_t u8g_com_null_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); /* u8g_com_null.c */ +uint8_t u8g_com_arduino_std_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); /* u8g_com_arduino_std_sw_spi.c */ +uint8_t u8g_com_arduino_hw_usart_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); /* u8g_com_atmega_hw_usart_spi.c */ +uint8_t u8g_com_arduino_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); /* u8g_com_arduino_sw_spi.c */ +uint8_t u8g_com_arduino_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); /* u8g_com_arduino_hw_spi.c */ +uint8_t u8g_com_arduino_ATtiny85_std_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); /* u8g_arduino_ATTiny85_std_hw_spi.c */ +uint8_t u8g_com_arduino_st7920_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); /* u8g_com_arduino_st7920_spi.c */ +uint8_t u8g_com_arduino_st7920_custom_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); /* u8g_com_arduino_st7920_custom.c */ +uint8_t u8g_com_arduino_st7920_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); /* u8g_com_arduino_st7920_hw_spi.c */ +uint8_t u8g_com_arduino_parallel_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); /* u8g_com_arduino_parallel.c */ +uint8_t u8g_com_arduino_fast_parallel_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); /* u8g_com_arduino_fast_parallel.c */ +uint8_t u8g_com_arduino_port_d_wr_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); /* u8g_com_arduino_port_d_wr.c */ +uint8_t u8g_com_arduino_no_en_parallel_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); /* u8g_com_arduino_no_en_parallel.c */ +uint8_t u8g_com_arduino_ssd_i2c_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); /* u8g_com_arduino_ssd_i2c.c */ +uint8_t u8g_com_arduino_t6963_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); /* u8g_com_arduino_t6963.c */ + + +uint8_t u8g_com_atmega_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); /* u8g_com_atmega_hw_spi.c */ +uint8_t u8g_com_atmega_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); /* u8g_com_atmega_sw_spi.c */ +uint8_t u8g_com_atmega_st7920_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); /* u8g_com_atmega_st7920_spi.c */ +uint8_t u8g_com_atmega_st7920_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); +uint8_t u8g_com_atmega_parallel_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); /* u8g_com_atmega_parallel.c */ + + +/* + Translation of system specific com drives to generic com names + At the moment, the following generic com drives are available + U8G_COM_HW_SPI + U8G_COM_SW_SPI + U8G_COM_PARALLEL + U8G_COM_T6963 + U8G_COM_FAST_PARALLEL + U8G_COM_SSD_I2C + +defined(__18CXX) || defined(__PIC32MX) + +*/ +/* ==== HW SPI, Arduino ====*/ +#if defined(ARDUINO) +#if defined(__AVR__) + +#if defined(__AVR_ATtiny85__) +#define U8G_COM_HW_SPI u8g_com_arduino_ATtiny85_std_hw_spi_fn +#define U8G_COM_ST7920_HW_SPI u8g_com_null_fn +#else + +#define U8G_COM_HW_SPI u8g_com_arduino_hw_spi_fn +#if defined(__AVR_ATmega32U4__) +#define U8G_COM_HW_USART_SPI u8g_com_arduino_hw_usart_spi_fn +#endif /* __AVR_ATmega32U4__ */ +#define U8G_COM_ST7920_HW_SPI u8g_com_arduino_st7920_hw_spi_fn +#endif /* __AVR_ATtiny85__ */ + +#elif defined(__18CXX) || defined(__PIC32MX) +#define U8G_COM_HW_SPI u8g_com_null_fn +#define U8G_COM_ST7920_HW_SPI u8g_com_null_fn +#elif defined(__arm__) /* Arduino Due */ +#define U8G_COM_HW_SPI u8g_com_arduino_hw_spi_fn +#define U8G_COM_ST7920_HW_SPI u8g_com_null_fn +#endif +#endif +/* ==== HW SPI, not Arduino ====*/ +#ifndef U8G_COM_HW_SPI +#if defined(__AVR__) +#define U8G_COM_HW_SPI u8g_com_atmega_hw_spi_fn +#define U8G_COM_ST7920_HW_SPI u8g_com_atmega_st7920_hw_spi_fn +#endif +#endif +#ifndef U8G_COM_HW_SPI +#define U8G_COM_HW_SPI u8g_com_null_fn +#define U8G_COM_ST7920_HW_SPI u8g_com_null_fn +#endif + +#ifndef U8G_COM_HW_USART_SPI +#define U8G_COM_HW_USART_SPI u8g_com_null_fn +#endif + + +/* ==== SW SPI, Arduino ====*/ +#if defined(ARDUINO) +#if defined(__AVR__) +#define U8G_COM_SW_SPI u8g_com_arduino_sw_spi_fn +#define U8G_COM_ST7920_SW_SPI u8g_com_arduino_st7920_spi_fn +#elif defined(__18CXX) || defined(__PIC32MX) +#define U8G_COM_SW_SPI u8g_com_arduino_sw_spi_fn +#define U8G_COM_ST7920_SW_SPI u8g_com_arduino_st7920_spi_fn +#elif defined(__arm__) /* Arduino Due */ +//#define U8G_COM_SW_SPI u8g_com_arduino_std_sw_spi_fn +#define U8G_COM_SW_SPI u8g_com_arduino_sw_spi_fn +#define U8G_COM_ST7920_SW_SPI u8g_com_arduino_st7920_spi_fn +#endif +#endif + +#ifndef U8G_COM_SW_SPI +/* ==== SW SPI, not Arduino ====*/ +#if defined(__AVR__) +#define U8G_COM_SW_SPI u8g_com_atmega_sw_spi_fn +#define U8G_COM_ST7920_SW_SPI u8g_com_atmega_st7920_sw_spi_fn +#endif +#endif +#ifndef U8G_COM_SW_SPI +#define U8G_COM_SW_SPI u8g_com_null_fn +#define U8G_COM_ST7920_SW_SPI u8g_com_null_fn +#endif + +/* ==== Parallel iinterface, Arduino ====*/ +#if defined(ARDUINO) +#if defined(__AVR__) +#define U8G_COM_PARALLEL u8g_com_arduino_parallel_fn +#define U8G_COM_FAST_PARALLEL u8g_com_arduino_fast_parallel_fn +#define U8G_COM_T6963 u8g_com_arduino_t6963_fn +#else /* Arduino Due, Chipkit PIC32 */ +#define U8G_COM_PARALLEL u8g_com_arduino_parallel_fn +#define U8G_COM_FAST_PARALLEL u8g_com_arduino_parallel_fn +#define U8G_COM_T6963 u8g_com_null_fn +#endif +#endif +#ifndef U8G_COM_PARALLEL +#if defined(__AVR__) +#define U8G_COM_PARALLEL u8g_com_atmega_parallel_fn +#define U8G_COM_FAST_PARALLEL u8g_com_atmega_parallel_fn +#define U8G_COM_T6963 u8g_com_null_fn +#endif +#endif +#ifndef U8G_COM_PARALLEL +#define U8G_COM_PARALLEL u8g_com_null_fn +#define U8G_COM_FAST_PARALLEL u8g_com_null_fn +#define U8G_COM_T6963 u8g_com_null_fn +#endif + +#if defined(ARDUINO) +#if defined(__AVR__) +#define U8G_COM_SSD_I2C u8g_com_arduino_ssd_i2c_fn +#endif +#endif + +#ifndef U8G_COM_SSD_I2C +#if defined(__AVR__) +/* AVR variant can use the arduino version at the moment */ +#define U8G_COM_SSD_I2C u8g_com_arduino_ssd_i2c_fn +#endif +#endif +#ifndef U8G_COM_SSD_I2C +#define U8G_COM_SSD_I2C u8g_com_null_fn +#endif + + + +/*===============================================================*/ +/* com api */ + +#define U8G_SPI_CLK_CYCLE_50NS 1 +#define U8G_SPI_CLK_CYCLE_300NS 2 +#define U8G_SPI_CLK_CYCLE_400NS 3 +#define U8G_SPI_CLK_CYCLE_500NS 4 +#define U8G_SPI_CLK_CYCLE_NONE 255 + +uint8_t u8g_InitCom(u8g_t *u8g, u8g_dev_t *dev, uint8_t clk_cycle_time); +void u8g_StopCom(u8g_t *u8g, u8g_dev_t *dev); +void u8g_EnableCom(u8g_t *u8g, u8g_dev_t *dev); /* obsolete */ +void u8g_DisableCom(u8g_t *u8g, u8g_dev_t *dev); /* obsolete */ +void u8g_SetChipSelect(u8g_t *u8g, u8g_dev_t *dev, uint8_t cs); +void u8g_SetResetLow(u8g_t *u8g, u8g_dev_t *dev); +void u8g_SetResetHigh(u8g_t *u8g, u8g_dev_t *dev); +void u8g_SetAddress(u8g_t *u8g, u8g_dev_t *dev, uint8_t address); +uint8_t u8g_WriteByte(u8g_t *u8g, u8g_dev_t *dev, uint8_t val); +uint8_t u8g_WriteSequence(u8g_t *u8g, u8g_dev_t *dev, uint8_t cnt, uint8_t *seq); +uint8_t u8g_WriteSequenceP(u8g_t *u8g, u8g_dev_t *dev, uint8_t cnt, const uint8_t *seq); + + + +#define U8G_ESC_DLY(x) 255, ((x) & 0x7f) +#define U8G_ESC_CS(x) 255, (0xd0 | ((x)&0x0f)) +#define U8G_ESC_ADR(x) 255, (0xe0 | ((x)&0x0f)) +#define U8G_ESC_RST(x) 255, (0xc0 | ((x)&0x0f)) +#define U8G_ESC_VCC(x) 255, (0xbe | ((x)&0x01)) +#define U8G_ESC_END 255, 254 +#define U8G_ESC_255 255, 255 +//uint8_t u8g_WriteEscSeqP(u8g_t *u8g, u8g_dev_t *dev, u8g_pgm_uint8_t *esc_seq); +uint8_t u8g_WriteEscSeqP(u8g_t *u8g, u8g_dev_t *dev, const uint8_t *esc_seq); + + +/* u8g_com_api_16gr.c */ +uint8_t u8g_WriteByteBWTo16GrDevice(u8g_t *u8g, u8g_dev_t *dev, uint8_t b); +uint8_t u8g_WriteSequenceBWTo16GrDevice(u8g_t *u8g, u8g_dev_t *dev, uint8_t cnt, uint8_t *ptr); +uint8_t u8g_WriteByte4LTo16GrDevice(u8g_t *u8g, u8g_dev_t *dev, uint8_t b); +uint8_t u8g_WriteSequence4LTo16GrDevice(u8g_t *u8g, u8g_dev_t *dev, uint8_t cnt, uint8_t *ptr); + + +/*===============================================================*/ +/* u8g_arduino_common.c */ +void u8g_com_arduino_digital_write(u8g_t *u8g, uint8_t pin_index, uint8_t value); +void u8g_com_arduino_assign_pin_output_high(u8g_t *u8g); + +/*===============================================================*/ +/* u8g_com_io.c */ + +/* create internal number from port and pin */ +uint8_t u8g_Pin(uint8_t port, uint8_t bitpos); +#define PN(port,bitpos) u8g_Pin(port,bitpos) + +/* low level procedures */ +void u8g_SetPinOutput(uint8_t internal_pin_number); +void u8g_SetPinLevel(uint8_t internal_pin_number, uint8_t level); +void u8g_SetPinInput(uint8_t internal_pin_number); +uint8_t u8g_GetPinLevel(uint8_t internal_pin_number); + +/* u8g level procedures, expect U8G_PI_xxx macro */ +void u8g_SetPIOutput(u8g_t *u8g, uint8_t pi); +void u8g_SetPILevel(u8g_t *u8g, uint8_t pi, uint8_t level); + + +/*===============================================================*/ +/* page */ +struct _u8g_page_t +{ + u8g_uint_t page_height; + u8g_uint_t total_height; + u8g_uint_t page_y0; + u8g_uint_t page_y1; + uint8_t page; +}; +typedef struct _u8g_page_t u8g_page_t; + +void u8g_page_First(u8g_page_t *p) U8G_NOINLINE; /* u8g_page.c */ +void u8g_page_Init(u8g_page_t *p, u8g_uint_t page_height, u8g_uint_t total_height ) U8G_NOINLINE; /* u8g_page.c */ +uint8_t u8g_page_Next(u8g_page_t *p) U8G_NOINLINE; /* u8g_page.c */ + +/*===============================================================*/ +/* page buffer (pb) */ + +struct _u8g_pb_t +{ + u8g_page_t p; + u8g_uint_t width; /* pixel width */ + void *buf; +}; +typedef struct _u8g_pb_t u8g_pb_t; + + +/* u8g_pb.c */ +void u8g_pb_Clear(u8g_pb_t *b); +uint8_t u8g_pb_IsYIntersection(u8g_pb_t *pb, u8g_uint_t v0, u8g_uint_t v1); +uint8_t u8g_pb_IsXIntersection(u8g_pb_t *b, u8g_uint_t v0, u8g_uint_t v1); +uint8_t u8g_pb_IsIntersection(u8g_pb_t *pb, u8g_dev_arg_bbx_t *bbx); +void u8g_pb_GetPageBox(u8g_pb_t *pb, u8g_box_t *box); +uint8_t u8g_pb_Is8PixelVisible(u8g_pb_t *b, u8g_dev_arg_pixel_t *arg_pixel); +uint8_t u8g_pb_WriteBuffer(u8g_pb_t *b, u8g_t *u8g, u8g_dev_t *dev); + +/* + note on __attribute__ ((nocommon)) + AVR scripts often use --gc-sections on the linker to remove unused section. + This works fine for initialed data and text sections. In principle .bss is also + handled, but the name##_pb definition is not removed. Reason is, that + array definitions are placed in the COMMON section, by default + The attribute "nocommon" removes this automatic assignment to the + COMMON section and directly puts it into .bss. As a result, if more + than one buffer is defined in one file, then it will be removed with --gc-sections + + .. not sure if Arduino IDE uses -fno-common... if yes, then the attribute is + redundant. +*/ +#define U8G_PB_DEV(name, width, height, page_height, dev_fn, com_fn) \ +uint8_t name##_buf[width] U8G_NOCOMMON ; \ +u8g_pb_t name##_pb = { {page_height, height, 0, 0, 0}, width, name##_buf}; \ +u8g_dev_t name = { dev_fn, &name##_pb, com_fn } + + +void u8g_pb8v1_Init(u8g_pb_t *b, void *buf, u8g_uint_t width) U8G_NOINLINE; +void u8g_pb8v1_Clear(u8g_pb_t *b) U8G_NOINLINE; + +uint8_t u8g_pb8v1_IsYIntersection(u8g_pb_t *b, u8g_uint_t v0, u8g_uint_t v1); +uint8_t u8g_pb8v1_IsXIntersection(u8g_pb_t *b, u8g_uint_t v0, u8g_uint_t v1); +uint8_t u8g_pb8v1_WriteBuffer(u8g_pb_t *b, u8g_t *u8g, u8g_dev_t *dev); + +uint8_t u8g_dev_pb8v1_base_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg); + +/* u8g_pb16v1.c */ +uint8_t u8g_dev_pb16v1_base_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg); + +/* u8g_pb14v1.c */ +uint8_t u8g_dev_pb14v1_base_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg); + +/* u8g_pb8v2.c */ +uint8_t u8g_dev_pb8v2_base_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg); + +/* u8g_pb16v2.c (double memory of pb8v2) */ +uint8_t u8g_dev_pb16v2_base_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg); + + +/* u8g_pb8h1.c */ +uint8_t u8g_dev_pb8h1_base_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg); + +/* u8g_pb16h1.c */ +uint8_t u8g_dev_pb16h1_base_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg); + +/* u8g_pb32h1.c */ +uint8_t u8g_dev_pb32h1_base_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg); + + +/* u8g_pb8h2.c 8 pixel rows, byte has horzontal orientation */ +uint8_t u8g_dev_pb8h2_base_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg); + +/* u8g_pb16h2.c */ +uint8_t u8g_dev_pb16h2_base_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg); + + + +/* u8g_pb8h1f.c */ +uint8_t u8g_dev_pb8h1f_base_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg); + +/* u8g_pb8h8.c */ +uint8_t u8g_dev_pb8h8_base_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg); + +/* u8g_pbxh16.c */ +uint8_t u8g_dev_pbxh16_base_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg); + +/* u8g_pbxh24.c */ +uint8_t u8g_dev_pbxh24_base_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg); + + +/*===============================================================*/ +/* u8g_ll_api.c */ + +/* cursor draw callback */ +typedef void (*u8g_draw_cursor_fn)(u8g_t *u8g); + +/* vertical reference point calculation callback */ +typedef u8g_uint_t (*u8g_font_calc_vref_fnptr)(u8g_t *u8g); + +/* state backup and restore procedure */ +typedef void (*u8g_state_cb)(uint8_t msg); + + +/* PI = Pin Index */ + +/* reset pin, usually optional */ +#define U8G_PI_RESET 0 + +/* address / data or instruction */ +#define U8G_PI_A0 1 +#define U8G_PI_DI 1 + +/* chip select line */ +#define U8G_PI_CS 2 +#define U8G_PI_CS1 2 +#define U8G_PI_CS2 3 +/* Feb 2013: A0 state moved from 7 to 3 for t6963 controller*/ +#define U8G_PI_A0_STATE 3 + +/* enable / clock signal */ +#define U8G_PI_EN 4 +#define U8G_PI_CS_STATE 4 +#define U8G_PI_SCK 4 +#define U8G_PI_SCL 4 +#define U8G_PI_RD 4 + + +/* data pins, shared with SPI and I2C pins */ +#define U8G_PI_D0 5 +#define U8G_PI_MOSI 5 +#define U8G_PI_SDA 5 +#define U8G_PI_D1 6 +#define U8G_PI_MISO 6 +#define U8G_PI_D2 7 +#define U8G_PI_D3 8 +#define U8G_PI_SET_A0 8 +#define U8G_PI_D4 9 +#define U8G_PI_D5 10 +#define U8G_PI_I2C_OPTION 11 +#define U8G_PI_D6 11 +#define U8G_PI_D7 12 + +/* read/write pin, must be the last pin in the list, this means U8G_PIN_LIST_LEN = U8G_PI_RW + 1*/ +#define U8G_PI_WR 13 +#define U8G_PI_RW 13 + +#define U8G_PIN_LIST_LEN 14 + + +#define U8G_PIN_DUMMY 254 +#define U8G_PIN_NONE 255 + +#define U8G_FONT_HEIGHT_MODE_TEXT 0 +#define U8G_FONT_HEIGHT_MODE_XTEXT 1 +#define U8G_FONT_HEIGHT_MODE_ALL 2 + +struct _u8g_t +{ + u8g_uint_t width; + u8g_uint_t height; + + + u8g_dev_t *dev; /* first device in the device chain */ + const u8g_pgm_uint8_t *font; /* regular font for all text procedures */ + const u8g_pgm_uint8_t *cursor_font; /* special font for cursor procedures */ + uint8_t cursor_fg_color, cursor_bg_color; + uint8_t cursor_encoding; + uint8_t mode; /* display mode, one of U8G_MODE_xxx */ + u8g_uint_t cursor_x; + u8g_uint_t cursor_y; + u8g_draw_cursor_fn cursor_fn; + + int8_t glyph_dx; + int8_t glyph_x; + int8_t glyph_y; + uint8_t glyph_width; + uint8_t glyph_height; + + u8g_font_calc_vref_fnptr font_calc_vref; + uint8_t font_height_mode; + int8_t font_ref_ascent; + int8_t font_ref_descent; + uint8_t font_line_spacing_factor; /* line_spacing = factor * (ascent - descent) / 64 */ + uint8_t line_spacing; + + u8g_dev_arg_pixel_t arg_pixel; + /* uint8_t color_index; */ + +#ifdef U8G_WITH_PINLIST + uint8_t pin_list[U8G_PIN_LIST_LEN]; +#endif + + u8g_state_cb state_cb; + + u8g_box_t current_page; /* current box of the visible page */ + +}; + +#define u8g_GetFontAscent(u8g) ((u8g)->font_ref_ascent) +#define u8g_GetFontDescent(u8g) ((u8g)->font_ref_descent) +#define u8g_GetFontLineSpacing(u8g) ((u8g)->line_spacing) + +uint8_t u8g_call_dev_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg); + +uint8_t u8g_InitLL(u8g_t *u8g, u8g_dev_t *dev); +void u8g_FirstPageLL(u8g_t *u8g, u8g_dev_t *dev); +uint8_t u8g_NextPageLL(u8g_t *u8g, u8g_dev_t *dev); +uint8_t u8g_SetContrastLL(u8g_t *u8g, u8g_dev_t *dev, uint8_t contrast); +void u8g_DrawPixelLL(u8g_t *u8g, u8g_dev_t *dev, u8g_uint_t x, u8g_uint_t y); +void u8g_Draw8PixelLL(u8g_t *u8g, u8g_dev_t *dev, u8g_uint_t x, u8g_uint_t y, uint8_t dir, uint8_t pixel); +void u8g_Draw4TPixelLL(u8g_t *u8g, u8g_dev_t *dev, u8g_uint_t x, u8g_uint_t y, uint8_t dir, uint8_t pixel); +uint8_t u8g_IsBBXIntersectionLL(u8g_t *u8g, u8g_dev_t *dev, u8g_uint_t x, u8g_uint_t y, u8g_uint_t w, u8g_uint_t h); /* obsolete */ +u8g_uint_t u8g_GetWidthLL(u8g_t *u8g, u8g_dev_t *dev); +u8g_uint_t u8g_GetHeightLL(u8g_t *u8g, u8g_dev_t *dev); + +void u8g_UpdateDimension(u8g_t *u8g); +uint8_t u8g_Begin(u8g_t *u8g); /* reset device, put it into default state and call u8g_UpdateDimension() */ +uint8_t u8g_Init(u8g_t *u8g, u8g_dev_t *dev); /* only usefull if the device only as hardcoded ports */ +uint8_t u8g_InitComFn(u8g_t *u8g, u8g_dev_t *dev, u8g_com_fnptr com_fn); /* Init procedure for anything which is not Arduino or AVR (e.g. ARM, but not Due, which is Arduino) */ +uint8_t u8g_InitSPI(u8g_t *u8g, u8g_dev_t *dev, uint8_t sck, uint8_t mosi, uint8_t cs, uint8_t a0, uint8_t reset); +uint8_t u8g_InitHWSPI(u8g_t *u8g, u8g_dev_t *dev, uint8_t cs, uint8_t a0, uint8_t reset); +uint8_t u8g_InitI2C(u8g_t *u8g, u8g_dev_t *dev, uint8_t options); /* use U8G_I2C_OPT_NONE as options */ +uint8_t u8g_Init8BitFixedPort(u8g_t *u8g, u8g_dev_t *dev, uint8_t en, uint8_t cs, uint8_t di, uint8_t rw, uint8_t reset); +uint8_t u8g_Init8Bit(u8g_t *u8g, u8g_dev_t *dev, uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7, + uint8_t en, uint8_t cs1, uint8_t cs2, uint8_t di, uint8_t rw, uint8_t reset); +uint8_t u8g_InitRW8Bit(u8g_t *u8g, u8g_dev_t *dev, uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7, + uint8_t cs, uint8_t a0, uint8_t wr, uint8_t rd, uint8_t reset); +void u8g_FirstPage(u8g_t *u8g); +uint8_t u8g_NextPage(u8g_t *u8g); +uint8_t u8g_SetContrast(u8g_t *u8g, uint8_t contrast); +void u8g_SleepOn(u8g_t *u8g); +void u8g_SleepOff(u8g_t *u8g); +void u8g_DrawPixel(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y); +void u8g_Draw8Pixel(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, uint8_t dir, uint8_t pixel); +void u8g_Draw4TPixel(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, uint8_t dir, uint8_t pixel); + +uint8_t u8g_Stop(u8g_t *u8g); +void u8g_SetColorEntry(u8g_t *u8g, uint8_t idx, uint8_t r, uint8_t g, uint8_t b); +void u8g_SetColorIndex(u8g_t *u8g, uint8_t idx); +void u8g_SetHiColor(u8g_t *u8g, uint16_t rgb); +void u8g_SetHiColorByRGB(u8g_t *u8g, uint8_t r, uint8_t g, uint8_t b); +void u8g_SetRGB(u8g_t *u8g, uint8_t r, uint8_t g, uint8_t b); +uint8_t u8g_GetColorIndex(u8g_t *u8g); + +uint8_t u8g_GetDefaultForegroundColor(u8g_t *u8g); +void u8g_SetDefaultForegroundColor(u8g_t *u8g); + +uint8_t u8g_GetDefaultBackgroundColor(u8g_t *u8g); +void u8g_SetDefaultBackgroundColor(u8g_t *u8g); + +uint8_t u8g_GetDefaultMidColor(u8g_t *u8g); +void u8g_SetDefaultMidColor(u8g_t *u8g); + +#define u8g_GetWidth(u8g) ((u8g)->width) +#define u8g_GetHeight(u8g) ((u8g)->height) +#define u8g_GetMode(u8g) ((u8g)->mode) +/* + U8G_MODE_GET_BITS_PER_PIXEL(u8g_GetMode(u8g)) + U8G_MODE_IS_COLOR(u8g_GetMode(u8g)) +*/ + +/* u8g_state.c */ +#define U8G_STATE_ENV_IDX 0 +#define U8G_STATE_U8G_IDX 1 +#define U8G_STATE_RESTORE 0 +#define U8G_STATE_BACKUP 1 +#define U8G_STATE_MSG_COMPOSE(cmd,idx) (((cmd)<<1) | (idx)) + +#define U8G_STATE_MSG_RESTORE_ENV U8G_STATE_MSG_COMPOSE(U8G_STATE_RESTORE,U8G_STATE_ENV_IDX) +#define U8G_STATE_MSG_BACKUP_ENV U8G_STATE_MSG_COMPOSE(U8G_STATE_BACKUP,U8G_STATE_ENV_IDX) +#define U8G_STATE_MSG_RESTORE_U8G U8G_STATE_MSG_COMPOSE(U8G_STATE_RESTORE,U8G_STATE_U8G_IDX) +#define U8G_STATE_MSG_BACKUP_U8G U8G_STATE_MSG_COMPOSE(U8G_STATE_BACKUP,U8G_STATE_U8G_IDX) + +#define U8G_STATE_MSG_GET_IDX(msg) ((msg)&1) +#define U8G_STATE_MSG_IS_BACKUP(msg) ((msg)&2) + + + +void u8g_state_dummy_cb(uint8_t msg); +void u8g_backup_spi(uint8_t msg); /* backup SPI state controller */ +/* backward compatible definition */ +#define u8g_backup_avr_spi u8g_backup_spi + +void u8g_SetHardwareBackup(u8g_t *u8g, u8g_state_cb backup_cb); + +/* u8g_clip.c */ + +uint8_t u8g_IsBBXIntersection(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, u8g_uint_t w, u8g_uint_t h); + + +/* u8g_rot.c */ + +void u8g_UndoRotation(u8g_t *u8g); +void u8g_SetRot90(u8g_t *u8g); +void u8g_SetRot180(u8g_t *u8g); +void u8g_SetRot270(u8g_t *u8g); + +/* u8g_scale.c */ + +void u8g_UndoScale(u8g_t *u8g); +void u8g_SetScale2x2(u8g_t *u8g); + + +/* u8g_font.c */ + +size_t u8g_font_GetSize(const void *font); +uint8_t u8g_font_GetFontStartEncoding(const void *font) U8G_NOINLINE; +uint8_t u8g_font_GetFontEndEncoding(const void *font) U8G_NOINLINE; + +void u8g_SetFont(u8g_t *u8g, const u8g_fntpgm_uint8_t *font); + +uint8_t u8g_GetFontBBXWidth(u8g_t *u8g); +uint8_t u8g_GetFontBBXHeight(u8g_t *u8g); +int8_t u8g_GetFontBBXOffX(u8g_t *u8g); +int8_t u8g_GetFontBBXOffY(u8g_t *u8g); +uint8_t u8g_GetFontCapitalAHeight(u8g_t *u8g); + +uint8_t u8g_IsGlyph(u8g_t *u8g, uint8_t requested_encoding); +int8_t u8g_GetGlyphDeltaX(u8g_t *u8g, uint8_t requested_encoding); + +int8_t u8g_draw_glyph(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, uint8_t encoding); /* used by u8g_cursor.c */ + +int8_t u8g_DrawGlyphDir(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, uint8_t dir, uint8_t encoding); +int8_t u8g_DrawGlyph(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, uint8_t encoding); +int8_t u8g_DrawGlyph90(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, uint8_t encoding); +int8_t u8g_DrawGlyph180(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, uint8_t encoding); +int8_t u8g_DrawGlyph270(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, uint8_t encoding); +int8_t u8g_DrawGlyphFontBBX(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, uint8_t dir, uint8_t encoding); + +u8g_uint_t u8g_DrawStr(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, const char *s); +u8g_uint_t u8g_DrawStr90(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, const char *s); +u8g_uint_t u8g_DrawStr180(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, const char *s); +u8g_uint_t u8g_DrawStr270(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, const char *s); + +u8g_uint_t u8g_DrawStrDir(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, uint8_t dir, const char *s); + + +u8g_uint_t u8g_DrawStrP(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, const u8g_pgm_uint8_t *s); +u8g_uint_t u8g_DrawStr90P(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, const u8g_pgm_uint8_t *s); +u8g_uint_t u8g_DrawStr180P(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, const u8g_pgm_uint8_t *s); +u8g_uint_t u8g_DrawStr270P(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, const u8g_pgm_uint8_t *s); + + +void u8g_SetFontRefHeightText(u8g_t *u8g); +void u8g_SetFontRefHeightExtendedText(u8g_t *u8g); +void u8g_SetFontRefHeightAll(u8g_t *u8g); +void u8g_SetFontLineSpacingFactor(u8g_t *u8g, uint8_t factor); + +u8g_uint_t u8g_font_calc_vref_font(u8g_t *u8g); +u8g_uint_t u8g_font_calc_vref_bottom(u8g_t *u8g); +u8g_uint_t u8g_font_calc_vref_top(u8g_t *u8g); +u8g_uint_t u8g_font_calc_vref_center(u8g_t *u8g); + +void u8g_SetFontPosBaseline(u8g_t *u8g); +void u8g_SetFontPosBottom(u8g_t *u8g); +void u8g_SetFontPosCenter(u8g_t *u8g); +void u8g_SetFontPosTop(u8g_t *u8g); + + +u8g_uint_t u8g_GetStrPixelWidth(u8g_t *u8g, const char *s); +u8g_uint_t u8g_GetStrPixelWidthP(u8g_t *u8g, const u8g_pgm_uint8_t *s); +int8_t u8g_GetStrX(u8g_t *u8g, const char *s); +int8_t u8g_GetStrXP(u8g_t *u8g, const u8g_pgm_uint8_t *s); +u8g_uint_t u8g_GetStrWidth(u8g_t *u8g, const char *s); +u8g_uint_t u8g_GetStrWidthP(u8g_t *u8g, const u8g_pgm_uint8_t *s); + +u8g_uint_t u8g_DrawStrFontBBX(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, uint8_t dir, const char *s); + +void u8g_GetStrMinBox(u8g_t *u8g, const char *s, u8g_uint_t *x, u8g_uint_t *y, u8g_uint_t *width, u8g_uint_t *height); +void u8g_GetStrAMinBox(u8g_t *u8g, const char *s, u8g_uint_t *x, u8g_uint_t *y, u8g_uint_t *width, u8g_uint_t *height); + + +u8g_uint_t u8g_DrawAAStr(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, const char *s); + +/* u8g_rect.c */ + +void u8g_draw_box(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, u8g_uint_t w, u8g_uint_t h) U8G_NOINLINE; + +void u8g_DrawHLine(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, u8g_uint_t w); +void u8g_DrawVLine(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, u8g_uint_t w); +void u8g_DrawFrame(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, u8g_uint_t w, u8g_uint_t h); +void u8g_DrawBox(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, u8g_uint_t w, u8g_uint_t h); + +void u8g_DrawRFrame(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, u8g_uint_t w, u8g_uint_t h, u8g_uint_t r); +void u8g_DrawRBox(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, u8g_uint_t w, u8g_uint_t h, u8g_uint_t r); + +/* u8g_bitmap.c */ + +void u8g_DrawHBitmap(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, u8g_uint_t cnt, const uint8_t *bitmap); +void u8g_DrawHBitmapP(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, u8g_uint_t cnt, const u8g_pgm_uint8_t *bitmap); +void u8g_DrawBitmap(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, u8g_uint_t cnt, u8g_uint_t h, const uint8_t *bitmap); +void u8g_DrawBitmapP(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, u8g_uint_t cnt, u8g_uint_t h, const u8g_pgm_uint8_t *bitmap); + +void u8g_DrawXBM(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, u8g_uint_t w, u8g_uint_t h, const uint8_t *bitmap); +void u8g_DrawXBMP(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, u8g_uint_t w, u8g_uint_t h, const u8g_pgm_uint8_t *bitmap); + + +/* u8g_line.c */ +void u8g_DrawLine(u8g_t *u8g, u8g_uint_t x1, u8g_uint_t y1, u8g_uint_t x2, u8g_uint_t y2); + + +/* u8g_circle.c */ + +/* the following, commented code has been rewritten or is not yet finished +#define U8G_CIRC_UPPER_RIGHT 0x01 +#define U8G_CIRC_UPPER_LEFT 0x02 +#define U8G_CIRC_LOWER_LEFT 0x04 +#define U8G_CIRC_LOWER_RIGHT 0x08 +#define U8G_CIRC_ALL (U8G_CIRC_UPPER_RIGHT|U8G_CIRC_UPPER_LEFT|U8G_CIRC_LOWER_RIGHT|U8G_CIRC_LOWER_LEFT) +void u8g_DrawEmpCirc(u8g_t *u8g, u8g_uint_t x0, u8g_uint_t y0, u8g_uint_t rad, uint8_t option); +void u8g_DrawFillCirc(u8g_t *u8g, u8g_uint_t x0, u8g_uint_t y0, u8g_uint_t rad, uint8_t option); +void u8g_DrawEllipseRect(u8g_t *u8g, u8g_uint_t x0, u8g_uint_t y0, u8g_uint_t x1, u8g_uint_t y1); +*/ + +#define U8G_DRAW_UPPER_RIGHT 0x01 +#define U8G_DRAW_UPPER_LEFT 0x02 +#define U8G_DRAW_LOWER_LEFT 0x04 +#define U8G_DRAW_LOWER_RIGHT 0x08 +#define U8G_DRAW_ALL (U8G_DRAW_UPPER_RIGHT|U8G_DRAW_UPPER_LEFT|U8G_DRAW_LOWER_RIGHT|U8G_DRAW_LOWER_LEFT) + +void u8g_draw_circle(u8g_t *u8g, u8g_uint_t x0, u8g_uint_t y0, u8g_uint_t rad, uint8_t option) U8G_NOINLINE; +void u8g_draw_disc(u8g_t *u8g, u8g_uint_t x0, u8g_uint_t y0, u8g_uint_t rad, uint8_t option) U8G_NOINLINE; + +void u8g_DrawCircle(u8g_t *u8g, u8g_uint_t x0, u8g_uint_t y0, u8g_uint_t rad, uint8_t option); +void u8g_DrawDisc(u8g_t *u8g, u8g_uint_t x0, u8g_uint_t y0, u8g_uint_t rad, uint8_t option); + +/* u8g_ellipse.c */ +void u8g_DrawEllipse(u8g_t *u8g, u8g_uint_t x0, u8g_uint_t y0, u8g_uint_t rx, u8g_uint_t ry, uint8_t option); +void u8g_DrawFilledEllipse(u8g_t *u8g, u8g_uint_t x0, u8g_uint_t y0, u8g_uint_t rx, u8g_uint_t ry, uint8_t option); + +/* u8g_clip.c */ +uint8_t u8g_is_box_bbx_intersection(u8g_box_t *box, u8g_dev_arg_bbx_t *bbx); + + +/* u8g_cursor.c */ +void u8g_SetCursorFont(u8g_t *u8g, const u8g_pgm_uint8_t *cursor_font); +void u8g_SetCursorStyle(u8g_t *u8g, uint8_t encoding); +void u8g_SetCursorPos(u8g_t *u8g, u8g_uint_t cursor_x, u8g_uint_t cursor_y); +void u8g_SetCursorColor(u8g_t *u8g, uint8_t fg, uint8_t bg); +void u8g_EnableCursor(u8g_t *u8g); +void u8g_DisableCursor(u8g_t *u8g); +void u8g_DrawCursor(u8g_t *u8g); + + + +/*===============================================================*/ +/* u8g_virtual_screen.c */ +void u8g_SetVirtualScreenDimension(u8g_t *vs_u8g, u8g_uint_t width, u8g_uint_t height); +uint8_t u8g_AddToVirtualScreen(u8g_t *vs_u8g, u8g_uint_t x, u8g_uint_t y, u8g_t *child_u8g); + +/*===============================================================*/ +void st_Draw(uint8_t fps); +void st_Step(uint8_t player_pos, uint8_t is_auto_fire, uint8_t is_fire); + +/*===============================================================*/ +/* u8g_com_i2c.c */ + +/* options for u8g_i2c_init() */ +#define U8G_I2C_OPT_NONE 0 +#define U8G_I2C_OPT_NO_ACK 2 +#define U8G_I2C_OPT_DEV_0 0 +#define U8G_I2C_OPT_DEV_1 4 +#define U8G_I2C_OPT_FAST 16 + +/* u8g_com_i2c.c */ + +/* retrun values from u8g_twi_get_error() */ +#define U8G_I2C_ERR_NONE 0x00 +/* the following values are bit masks */ +#define U8G_I2C_ERR_TIMEOUT 0x01 +#define U8G_I2C_ERR_BUS 0x02 + +void u8g_i2c_clear_error(void) U8G_NOINLINE; +uint8_t u8g_i2c_get_error(void) U8G_NOINLINE; +uint8_t u8g_i2c_get_err_pos(void) U8G_NOINLINE; +void u8g_i2c_init(uint8_t options) U8G_NOINLINE; /* use U8G_I2C_OPT_NONE as options */ +uint8_t u8g_i2c_wait(uint8_t mask, uint8_t pos) U8G_NOINLINE; +uint8_t u8g_i2c_start(uint8_t sla) U8G_NOINLINE; +uint8_t u8g_i2c_send_byte(uint8_t data) U8G_NOINLINE; +void u8g_i2c_stop(void) U8G_NOINLINE; + + +/*===============================================================*/ +/* u8g_u8toa.c */ +/* v = value, d = number of digits */ +const char *u8g_u8toa(uint8_t v, uint8_t d); + +/* u8g_u8toa.c */ +/* v = value, d = number of digits */ +const char *u8g_u16toa(uint16_t v, uint8_t d); + +/*===============================================================*/ +/* u8g_delay.c */ + +/* delay by the specified number of milliseconds */ +void u8g_Delay(uint16_t val); + +/* delay by one microsecond */ +void u8g_MicroDelay(void); + +/* delay by 10 microseconds */ +void u8g_10MicroDelay(void); + +/*===============================================================*/ +/* chessengine.c */ +#define CHESS_KEY_NONE 0 +#define CHESS_KEY_NEXT 1 +#define CHESS_KEY_PREV 2 +#define CHESS_KEY_SELECT 3 +#define CHESS_KEY_BACK 4 + +void chess_Init(u8g_t *u8g, uint8_t empty_body_color); +void chess_Draw(void); +void chess_Step(uint8_t keycode); + +/*===============================================================*/ +/* font definitions */ +extern const u8g_fntpgm_uint8_t u8g_font_m2icon_5[] U8G_FONT_SECTION("u8g_font_m2icon_5"); +extern const u8g_fntpgm_uint8_t u8g_font_m2icon_7[] U8G_FONT_SECTION("u8g_font_m2icon_7"); +extern const u8g_fntpgm_uint8_t u8g_font_m2icon_9[] U8G_FONT_SECTION("u8g_font_m2icon_9"); + +extern const u8g_fntpgm_uint8_t u8g_font_u8glib_4[] U8G_FONT_SECTION("u8g_font_u8glib_4"); +extern const u8g_fntpgm_uint8_t u8g_font_u8glib_4r[] U8G_FONT_SECTION("u8g_font_u8glib_4r"); + + +extern const u8g_fntpgm_uint8_t u8g_font_6x12_75r[] U8G_FONT_SECTION("u8g_font_6x12_75r"); +extern const u8g_fntpgm_uint8_t u8g_font_6x13_75r[] U8G_FONT_SECTION("u8g_font_6x13_75r"); +extern const u8g_fntpgm_uint8_t u8g_font_7x13_75r[] U8G_FONT_SECTION("u8g_font_7x13_75r"); +extern const u8g_fntpgm_uint8_t u8g_font_8x13_75r[] U8G_FONT_SECTION("u8g_font_8x13_75r"); +extern const u8g_fntpgm_uint8_t u8g_font_9x15_75r[] U8G_FONT_SECTION("u8g_font_9x15_75r"); +extern const u8g_fntpgm_uint8_t u8g_font_9x18_75r[] U8G_FONT_SECTION("u8g_font_9x18_75r"); +extern const u8g_fntpgm_uint8_t u8g_font_cu12_75r[] U8G_FONT_SECTION("u8g_font_cu12_75r"); +extern const u8g_fntpgm_uint8_t u8g_font_unifont_75r[] U8G_FONT_SECTION("u8g_font_unifont_75r"); +extern const u8g_fntpgm_uint8_t u8g_font_10x20_75r[] U8G_FONT_SECTION("u8g_font_10x20_75r"); + +extern const u8g_fntpgm_uint8_t u8g_font_10x20_67_75[] U8G_FONT_SECTION("u8g_font_10x20_67_75"); +extern const u8g_fntpgm_uint8_t u8g_font_10x20_78_79[] U8G_FONT_SECTION("u8g_font_10x20_78_79"); +extern const u8g_fntpgm_uint8_t u8g_font_10x20[] U8G_FONT_SECTION("u8g_font_10x20"); +extern const u8g_fntpgm_uint8_t u8g_font_10x20r[] U8G_FONT_SECTION("u8g_font_10x20r"); +extern const u8g_fntpgm_uint8_t u8g_font_4x6[] U8G_FONT_SECTION("u8g_font_4x6"); +extern const u8g_fntpgm_uint8_t u8g_font_4x6r[] U8G_FONT_SECTION("u8g_font_4x6r"); +//extern const u8g_fntpgm_uint8_t u8g_font_4x6n[] U8G_FONT_SECTION("u8g_font_4x6n"); +extern const u8g_fntpgm_uint8_t u8g_font_5x7[] U8G_FONT_SECTION("u8g_font_5x7"); +extern const u8g_fntpgm_uint8_t u8g_font_5x7r[] U8G_FONT_SECTION("u8g_font_5x7r"); +extern const u8g_fntpgm_uint8_t u8g_font_5x8[] U8G_FONT_SECTION("u8g_font_5x8"); +extern const u8g_fntpgm_uint8_t u8g_font_5x8r[] U8G_FONT_SECTION("u8g_font_5x8r"); +extern const u8g_fntpgm_uint8_t u8g_font_6x10[] U8G_FONT_SECTION("u8g_font_6x10"); +extern const u8g_fntpgm_uint8_t u8g_font_6x10r[] U8G_FONT_SECTION("u8g_font_6x10r"); +extern const u8g_fntpgm_uint8_t u8g_font_6x12_67_75[] U8G_FONT_SECTION("u8g_font_6x12_67_75"); +extern const u8g_fntpgm_uint8_t u8g_font_6x12_78_79[] U8G_FONT_SECTION("u8g_font_6x12_78_79"); +extern const u8g_fntpgm_uint8_t u8g_font_6x12[] U8G_FONT_SECTION("u8g_font_6x12"); +extern const u8g_fntpgm_uint8_t u8g_font_6x12r[] U8G_FONT_SECTION("u8g_font_6x12r"); +extern const u8g_fntpgm_uint8_t u8g_font_6x13_67_75[] U8G_FONT_SECTION("u8g_font_6x13_67_75"); +extern const u8g_fntpgm_uint8_t u8g_font_6x13_78_79[] U8G_FONT_SECTION("u8g_font_6x13_78_79"); +extern const u8g_fntpgm_uint8_t u8g_font_6x13B[] U8G_FONT_SECTION("u8g_font_6x13B"); +extern const u8g_fntpgm_uint8_t u8g_font_6x13Br[] U8G_FONT_SECTION("u8g_font_6x13Br"); +extern const u8g_fntpgm_uint8_t u8g_font_6x13[] U8G_FONT_SECTION("u8g_font_6x13"); +extern const u8g_fntpgm_uint8_t u8g_font_6x13r[] U8G_FONT_SECTION("u8g_font_6x13r"); +extern const u8g_fntpgm_uint8_t u8g_font_6x13O[] U8G_FONT_SECTION("u8g_font_6x13O"); +extern const u8g_fntpgm_uint8_t u8g_font_6x13Or[] U8G_FONT_SECTION("u8g_font_6x13Or"); +extern const u8g_fntpgm_uint8_t u8g_font_7x13_67_75[] U8G_FONT_SECTION("u8g_font_7x13_67_75"); +extern const u8g_fntpgm_uint8_t u8g_font_7x13_78_79[] U8G_FONT_SECTION("u8g_font_7x13_78_79"); +extern const u8g_fntpgm_uint8_t u8g_font_7x13B[] U8G_FONT_SECTION("u8g_font_7x13B"); +extern const u8g_fntpgm_uint8_t u8g_font_7x13Br[] U8G_FONT_SECTION("u8g_font_7x13Br"); +extern const u8g_fntpgm_uint8_t u8g_font_7x13[] U8G_FONT_SECTION("u8g_font_7x13"); +extern const u8g_fntpgm_uint8_t u8g_font_7x13r[] U8G_FONT_SECTION("u8g_font_7x13r"); +extern const u8g_fntpgm_uint8_t u8g_font_7x13O[] U8G_FONT_SECTION("u8g_font_7x13O"); +extern const u8g_fntpgm_uint8_t u8g_font_7x13Or[] U8G_FONT_SECTION("u8g_font_7x13Or"); +extern const u8g_fntpgm_uint8_t u8g_font_7x14B[] U8G_FONT_SECTION("u8g_font_7x14B"); +extern const u8g_fntpgm_uint8_t u8g_font_7x14Br[] U8G_FONT_SECTION("u8g_font_7x14Br"); +extern const u8g_fntpgm_uint8_t u8g_font_7x14[] U8G_FONT_SECTION("u8g_font_7x14"); +extern const u8g_fntpgm_uint8_t u8g_font_7x14r[] U8G_FONT_SECTION("u8g_font_7x14r"); +extern const u8g_fntpgm_uint8_t u8g_font_8x13_67_75[] U8G_FONT_SECTION("u8g_font_8x13_67_75"); +extern const u8g_fntpgm_uint8_t u8g_font_8x13B[] U8G_FONT_SECTION("u8g_font_8x13B"); +extern const u8g_fntpgm_uint8_t u8g_font_8x13Br[] U8G_FONT_SECTION("u8g_font_8x13Br"); +extern const u8g_fntpgm_uint8_t u8g_font_8x13[] U8G_FONT_SECTION("u8g_font_8x13"); +extern const u8g_fntpgm_uint8_t u8g_font_8x13r[] U8G_FONT_SECTION("u8g_font_8x13r"); +extern const u8g_fntpgm_uint8_t u8g_font_8x13O[] U8G_FONT_SECTION("u8g_font_8x13O"); +extern const u8g_fntpgm_uint8_t u8g_font_8x13Or[] U8G_FONT_SECTION("u8g_font_8x13Or"); + +extern const u8g_fntpgm_uint8_t u8g_font_9x15_67_75[] U8G_FONT_SECTION("u8g_font_9x15_67_75"); +extern const u8g_fntpgm_uint8_t u8g_font_9x15_78_79[] U8G_FONT_SECTION("u8g_font_9x15_78_79"); +extern const u8g_fntpgm_uint8_t u8g_font_9x15B[] U8G_FONT_SECTION("u8g_font_9x15B"); +extern const u8g_fntpgm_uint8_t u8g_font_9x15Br[] U8G_FONT_SECTION("u8g_font_9x15Br"); +extern const u8g_fntpgm_uint8_t u8g_font_9x15[] U8G_FONT_SECTION("u8g_font_9x15"); +extern const u8g_fntpgm_uint8_t u8g_font_9x15r[] U8G_FONT_SECTION("u8g_font_9x15r"); + +extern const u8g_fntpgm_uint8_t u8g_font_9x18_67_75[] U8G_FONT_SECTION("u8g_font_9x18_67_75"); +extern const u8g_fntpgm_uint8_t u8g_font_9x18_78_79[] U8G_FONT_SECTION("u8g_font_9x18_78_79"); +extern const u8g_fntpgm_uint8_t u8g_font_9x18B[] U8G_FONT_SECTION("u8g_font_9x18B"); +extern const u8g_fntpgm_uint8_t u8g_font_9x18[] U8G_FONT_SECTION("u8g_font_9x18"); +extern const u8g_fntpgm_uint8_t u8g_font_9x18Br[] U8G_FONT_SECTION("u8g_font_9x18Br"); +extern const u8g_fntpgm_uint8_t u8g_font_9x18r[] U8G_FONT_SECTION("u8g_font_9x18r"); + +extern const u8g_fntpgm_uint8_t u8g_font_cursor[] U8G_FONT_SECTION("u8g_font_cursor"); +extern const u8g_fntpgm_uint8_t u8g_font_cursorr[] U8G_FONT_SECTION("u8g_font_cursorr"); +extern const u8g_fntpgm_uint8_t u8g_font_micro[] U8G_FONT_SECTION("u8g_font_micro"); + +extern const u8g_fntpgm_uint8_t u8g_font_cu12_67_75[] U8G_FONT_SECTION("u8g_font_cu12_67_75"); +extern const u8g_fntpgm_uint8_t u8g_font_cu12_78_79[] U8G_FONT_SECTION("u8g_font_cu12_78_79"); +extern const u8g_fntpgm_uint8_t u8g_font_cu12[] U8G_FONT_SECTION("u8g_font_cu12"); + +/* + Free-Universal Bold + r: Reduced char set (codes 32 - 128) + n: Numbers (codes 42 - 57) + no char: Full set (codes 32 - 255) +*/ + +extern const u8g_fntpgm_uint8_t u8g_font_fub11[] U8G_FONT_SECTION("u8g_font_fub11"); +extern const u8g_fntpgm_uint8_t u8g_font_fub11r[] U8G_FONT_SECTION("u8g_font_fub11r"); +extern const u8g_fntpgm_uint8_t u8g_font_fub11n[] U8G_FONT_SECTION("u8g_font_fub11n"); +extern const u8g_fntpgm_uint8_t u8g_font_fub14[] U8G_FONT_SECTION("u8g_font_fub14"); +extern const u8g_fntpgm_uint8_t u8g_font_fub14r[] U8G_FONT_SECTION("u8g_font_fub14r"); +extern const u8g_fntpgm_uint8_t u8g_font_fub14n[] U8G_FONT_SECTION("u8g_font_fub14n"); +extern const u8g_fntpgm_uint8_t u8g_font_fub17[] U8G_FONT_SECTION("u8g_font_fub17"); +extern const u8g_fntpgm_uint8_t u8g_font_fub17r[] U8G_FONT_SECTION("u8g_font_fub17r"); +extern const u8g_fntpgm_uint8_t u8g_font_fub17n[] U8G_FONT_SECTION("u8g_font_fub17n"); +extern const u8g_fntpgm_uint8_t u8g_font_fub20[] U8G_FONT_SECTION("u8g_font_fub20"); +extern const u8g_fntpgm_uint8_t u8g_font_fub20r[] U8G_FONT_SECTION("u8g_font_fub20r"); +extern const u8g_fntpgm_uint8_t u8g_font_fub20n[] U8G_FONT_SECTION("u8g_font_fub20n"); +extern const u8g_fntpgm_uint8_t u8g_font_fub25[] U8G_FONT_SECTION("u8g_font_fub25"); +extern const u8g_fntpgm_uint8_t u8g_font_fub25r[] U8G_FONT_SECTION("u8g_font_fub25r"); +extern const u8g_fntpgm_uint8_t u8g_font_fub25n[] U8G_FONT_SECTION("u8g_font_fub25n"); +extern const u8g_fntpgm_uint8_t u8g_font_fub30[] U8G_FONT_SECTION("u8g_font_fub30"); +extern const u8g_fntpgm_uint8_t u8g_font_fub30r[] U8G_FONT_SECTION("u8g_font_fub30r"); +extern const u8g_fntpgm_uint8_t u8g_font_fub30n[] U8G_FONT_SECTION("u8g_font_fub30n"); +extern const u8g_fntpgm_uint8_t u8g_font_fub35n[] U8G_FONT_SECTION("u8g_font_fub35n"); +extern const u8g_fntpgm_uint8_t u8g_font_fub42n[] U8G_FONT_SECTION("u8g_font_fub42n"); +extern const u8g_fntpgm_uint8_t u8g_font_fub49n[] U8G_FONT_SECTION("u8g_font_fub49n"); + +/* + Free-Universal Regular + r: Reduced char set (codes 32 - 128) + n: Numbers (codes 42 - 57) + no char: Full set (codes 32 - 255) +*/ + +extern const u8g_fntpgm_uint8_t u8g_font_fur11[] U8G_FONT_SECTION("u8g_font_fur11"); +extern const u8g_fntpgm_uint8_t u8g_font_fur11r[] U8G_FONT_SECTION("u8g_font_fur11r"); +extern const u8g_fntpgm_uint8_t u8g_font_fur11n[] U8G_FONT_SECTION("u8g_font_fur11n"); +extern const u8g_fntpgm_uint8_t u8g_font_fur14[] U8G_FONT_SECTION("u8g_font_fur14"); +extern const u8g_fntpgm_uint8_t u8g_font_fur14r[] U8G_FONT_SECTION("u8g_font_fur14r"); +extern const u8g_fntpgm_uint8_t u8g_font_fur14n[] U8G_FONT_SECTION("u8g_font_fur14n"); +extern const u8g_fntpgm_uint8_t u8g_font_fur17[] U8G_FONT_SECTION("u8g_font_fur17"); +extern const u8g_fntpgm_uint8_t u8g_font_fur17r[] U8G_FONT_SECTION("u8g_font_fur17r"); +extern const u8g_fntpgm_uint8_t u8g_font_fur17n[] U8G_FONT_SECTION("u8g_font_fur17n"); +extern const u8g_fntpgm_uint8_t u8g_font_fur20[] U8G_FONT_SECTION("u8g_font_fur20"); +extern const u8g_fntpgm_uint8_t u8g_font_fur20r[] U8G_FONT_SECTION("u8g_font_fur20r"); +extern const u8g_fntpgm_uint8_t u8g_font_fur20n[] U8G_FONT_SECTION("u8g_font_fur20n"); +extern const u8g_fntpgm_uint8_t u8g_font_fur25[] U8G_FONT_SECTION("u8g_font_fur25"); +extern const u8g_fntpgm_uint8_t u8g_font_fur25r[] U8G_FONT_SECTION("u8g_font_fur25r"); +extern const u8g_fntpgm_uint8_t u8g_font_fur25n[] U8G_FONT_SECTION("u8g_font_fur25n"); +extern const u8g_fntpgm_uint8_t u8g_font_fur30[] U8G_FONT_SECTION("u8g_font_fur30"); +extern const u8g_fntpgm_uint8_t u8g_font_fur30r[] U8G_FONT_SECTION("u8g_font_fur30r"); +extern const u8g_fntpgm_uint8_t u8g_font_fur30n[] U8G_FONT_SECTION("u8g_font_fur30n"); +extern const u8g_fntpgm_uint8_t u8g_font_fur35n[] U8G_FONT_SECTION("u8g_font_fur35n"); +extern const u8g_fntpgm_uint8_t u8g_font_fur42n[] U8G_FONT_SECTION("u8g_font_fur42n"); +extern const u8g_fntpgm_uint8_t u8g_font_fur49n[] U8G_FONT_SECTION("u8g_font_fur49n"); + +/* + Gentium Bold + r: Reduced char set (codes 32 - 128) + n: Numbers (codes 42 - 57) + no char: Full set (codes 32 - 255) +*/ + +extern const u8g_fntpgm_uint8_t u8g_font_gdb11[] U8G_FONT_SECTION("u8g_font_gdb11"); +extern const u8g_fntpgm_uint8_t u8g_font_gdb12[] U8G_FONT_SECTION("u8g_font_gdb12"); +extern const u8g_fntpgm_uint8_t u8g_font_gdb14[] U8G_FONT_SECTION("u8g_font_gdb14"); +extern const u8g_fntpgm_uint8_t u8g_font_gdb17[] U8G_FONT_SECTION("u8g_font_gdb17"); +extern const u8g_fntpgm_uint8_t u8g_font_gdb20[] U8G_FONT_SECTION("u8g_font_gdb20"); +extern const u8g_fntpgm_uint8_t u8g_font_gdb25[] U8G_FONT_SECTION("u8g_font_gdb25"); +extern const u8g_fntpgm_uint8_t u8g_font_gdb30[] U8G_FONT_SECTION("u8g_font_gdb30"); + +extern const u8g_fntpgm_uint8_t u8g_font_gdb11r[] U8G_FONT_SECTION("u8g_font_gdb11r"); +extern const u8g_fntpgm_uint8_t u8g_font_gdb12r[] U8G_FONT_SECTION("u8g_font_gdb12r"); +extern const u8g_fntpgm_uint8_t u8g_font_gdb14r[] U8G_FONT_SECTION("u8g_font_gdb14r"); +extern const u8g_fntpgm_uint8_t u8g_font_gdb17r[] U8G_FONT_SECTION("u8g_font_gdb17r"); +extern const u8g_fntpgm_uint8_t u8g_font_gdb20r[] U8G_FONT_SECTION("u8g_font_gdb20r"); +extern const u8g_fntpgm_uint8_t u8g_font_gdb25r[] U8G_FONT_SECTION("u8g_font_gdb25r"); +extern const u8g_fntpgm_uint8_t u8g_font_gdb30r[] U8G_FONT_SECTION("u8g_font_gdb30r"); + +extern const u8g_fntpgm_uint8_t u8g_font_gdb11n[] U8G_FONT_SECTION("u8g_font_gdb11n"); +extern const u8g_fntpgm_uint8_t u8g_font_gdb12n[] U8G_FONT_SECTION("u8g_font_gdb12n"); +extern const u8g_fntpgm_uint8_t u8g_font_gdb14n[] U8G_FONT_SECTION("u8g_font_gdb14n"); +extern const u8g_fntpgm_uint8_t u8g_font_gdb17n[] U8G_FONT_SECTION("u8g_font_gdb17n"); +extern const u8g_fntpgm_uint8_t u8g_font_gdb20n[] U8G_FONT_SECTION("u8g_font_gdb20n"); +extern const u8g_fntpgm_uint8_t u8g_font_gdb25n[] U8G_FONT_SECTION("u8g_font_gdb25n"); +extern const u8g_fntpgm_uint8_t u8g_font_gdb30n[] U8G_FONT_SECTION("u8g_font_gdb30n"); + +/* + Gentium Regular + r: Reduced char set (codes 32 - 128) + n: Numbers (codes 42 - 57) + no char: Full set (codes 32 - 255) +*/ + +extern const u8g_fntpgm_uint8_t u8g_font_gdr9[] U8G_FONT_SECTION("u8g_font_gdr9"); +extern const u8g_fntpgm_uint8_t u8g_font_gdr10[] U8G_FONT_SECTION("u8g_font_gdr10"); +extern const u8g_fntpgm_uint8_t u8g_font_gdr11[] U8G_FONT_SECTION("u8g_font_gdr11"); +extern const u8g_fntpgm_uint8_t u8g_font_gdr12[] U8G_FONT_SECTION("u8g_font_gdr12"); +extern const u8g_fntpgm_uint8_t u8g_font_gdr14[] U8G_FONT_SECTION("u8g_font_gdr14"); +extern const u8g_fntpgm_uint8_t u8g_font_gdr17[] U8G_FONT_SECTION("u8g_font_gdr17"); +extern const u8g_fntpgm_uint8_t u8g_font_gdr20[] U8G_FONT_SECTION("u8g_font_gdr20"); +extern const u8g_fntpgm_uint8_t u8g_font_gdr25[] U8G_FONT_SECTION("u8g_font_gdr25"); +extern const u8g_fntpgm_uint8_t u8g_font_gdr30[] U8G_FONT_SECTION("u8g_font_gdr30"); + +extern const u8g_fntpgm_uint8_t u8g_font_gdr9r[] U8G_FONT_SECTION("u8g_font_gdr9r"); +extern const u8g_fntpgm_uint8_t u8g_font_gdr10r[] U8G_FONT_SECTION("u8g_font_gdr10r"); +extern const u8g_fntpgm_uint8_t u8g_font_gdr11r[] U8G_FONT_SECTION("u8g_font_gdr11r"); +extern const u8g_fntpgm_uint8_t u8g_font_gdr12r[] U8G_FONT_SECTION("u8g_font_gdr12r"); +extern const u8g_fntpgm_uint8_t u8g_font_gdr14r[] U8G_FONT_SECTION("u8g_font_gdr14r"); +extern const u8g_fntpgm_uint8_t u8g_font_gdr17r[] U8G_FONT_SECTION("u8g_font_gdr17r"); +extern const u8g_fntpgm_uint8_t u8g_font_gdr20r[] U8G_FONT_SECTION("u8g_font_gdr20r"); +extern const u8g_fntpgm_uint8_t u8g_font_gdr25r[] U8G_FONT_SECTION("u8g_font_gdr25r"); +extern const u8g_fntpgm_uint8_t u8g_font_gdr30r[] U8G_FONT_SECTION("u8g_font_gdr30r"); + +extern const u8g_fntpgm_uint8_t u8g_font_gdr9n[] U8G_FONT_SECTION("u8g_font_gdr9n"); +extern const u8g_fntpgm_uint8_t u8g_font_gdr10n[] U8G_FONT_SECTION("u8g_font_gdr10n"); +extern const u8g_fntpgm_uint8_t u8g_font_gdr11n[] U8G_FONT_SECTION("u8g_font_gdr11n"); +extern const u8g_fntpgm_uint8_t u8g_font_gdr12n[] U8G_FONT_SECTION("u8g_font_gdr12n"); +extern const u8g_fntpgm_uint8_t u8g_font_gdr14n[] U8G_FONT_SECTION("u8g_font_gdr14n"); +extern const u8g_fntpgm_uint8_t u8g_font_gdr17n[] U8G_FONT_SECTION("u8g_font_gdr17n"); +extern const u8g_fntpgm_uint8_t u8g_font_gdr20n[] U8G_FONT_SECTION("u8g_font_gdr20n"); +extern const u8g_fntpgm_uint8_t u8g_font_gdr25n[] U8G_FONT_SECTION("u8g_font_gdr25n"); +extern const u8g_fntpgm_uint8_t u8g_font_gdr30n[] U8G_FONT_SECTION("u8g_font_gdr30n"); + +/* + Old-Standard Bold + r: Reduced char set (codes 32 - 128) + n: Numbers (codes 42 - 57) + no char: Full set (codes 32 - 255) +*/ + +extern const u8g_fntpgm_uint8_t u8g_font_osb18[] U8G_FONT_SECTION("u8g_font_osb18"); +extern const u8g_fntpgm_uint8_t u8g_font_osb21[] U8G_FONT_SECTION("u8g_font_osb21"); +extern const u8g_fntpgm_uint8_t u8g_font_osb26[] U8G_FONT_SECTION("u8g_font_osb26"); +extern const u8g_fntpgm_uint8_t u8g_font_osb29[] U8G_FONT_SECTION("u8g_font_osb29"); +extern const u8g_fntpgm_uint8_t u8g_font_osb35[] U8G_FONT_SECTION("u8g_font_osb35"); + +extern const u8g_fntpgm_uint8_t u8g_font_osb18r[] U8G_FONT_SECTION("u8g_font_osb18r"); +extern const u8g_fntpgm_uint8_t u8g_font_osb21r[] U8G_FONT_SECTION("u8g_font_osb21r"); +extern const u8g_fntpgm_uint8_t u8g_font_osb26r[] U8G_FONT_SECTION("u8g_font_osb26r"); +extern const u8g_fntpgm_uint8_t u8g_font_osb29r[] U8G_FONT_SECTION("u8g_font_osb29r"); +extern const u8g_fntpgm_uint8_t u8g_font_osb35r[] U8G_FONT_SECTION("u8g_font_osb35r"); + +extern const u8g_fntpgm_uint8_t u8g_font_osb18n[] U8G_FONT_SECTION("u8g_font_osb18n"); +extern const u8g_fntpgm_uint8_t u8g_font_osb21n[] U8G_FONT_SECTION("u8g_font_osb21n"); +extern const u8g_fntpgm_uint8_t u8g_font_osb26n[] U8G_FONT_SECTION("u8g_font_osb26n"); +extern const u8g_fntpgm_uint8_t u8g_font_osb29n[] U8G_FONT_SECTION("u8g_font_osb29n"); +extern const u8g_fntpgm_uint8_t u8g_font_osb35n[] U8G_FONT_SECTION("u8g_font_osb35n"); + +/* + Old-Standard Regular + r: Reduced char set (codes 32 - 128) + n: Numbers (codes 42 - 57) + no char: Full set (codes 32 - 255) +*/ + +extern const u8g_fntpgm_uint8_t u8g_font_osr18[] U8G_FONT_SECTION("u8g_font_osr18"); +extern const u8g_fntpgm_uint8_t u8g_font_osr21[] U8G_FONT_SECTION("u8g_font_osr21"); +extern const u8g_fntpgm_uint8_t u8g_font_osr26[] U8G_FONT_SECTION("u8g_font_osr26"); +extern const u8g_fntpgm_uint8_t u8g_font_osr29[] U8G_FONT_SECTION("u8g_font_osr29"); +extern const u8g_fntpgm_uint8_t u8g_font_osr35[] U8G_FONT_SECTION("u8g_font_osr35"); + +extern const u8g_fntpgm_uint8_t u8g_font_osr18r[] U8G_FONT_SECTION("u8g_font_osr18r"); +extern const u8g_fntpgm_uint8_t u8g_font_osr21r[] U8G_FONT_SECTION("u8g_font_osr21r"); +extern const u8g_fntpgm_uint8_t u8g_font_osr26r[] U8G_FONT_SECTION("u8g_font_osr26r"); +extern const u8g_fntpgm_uint8_t u8g_font_osr29r[] U8G_FONT_SECTION("u8g_font_osr29r"); +extern const u8g_fntpgm_uint8_t u8g_font_osr35r[] U8G_FONT_SECTION("u8g_font_osr35r"); + +extern const u8g_fntpgm_uint8_t u8g_font_osr18n[] U8G_FONT_SECTION("u8g_font_osr18n"); +extern const u8g_fntpgm_uint8_t u8g_font_osr21n[] U8G_FONT_SECTION("u8g_font_osr21n"); +extern const u8g_fntpgm_uint8_t u8g_font_osr26n[] U8G_FONT_SECTION("u8g_font_osr26n"); +extern const u8g_fntpgm_uint8_t u8g_font_osr29n[] U8G_FONT_SECTION("u8g_font_osr29n"); +extern const u8g_fntpgm_uint8_t u8g_font_osr35n[] U8G_FONT_SECTION("u8g_font_osr35n"); + +//extern const u8g_fntpgm_uint8_t u8g_font_osr41[] U8G_FONT_SECTION("u8g_font_osr41"); + +/* GNU unifont */ + +extern const u8g_fntpgm_uint8_t u8g_font_unifont_18_19[] U8G_FONT_SECTION("u8g_font_unifont_18_19"); +extern const u8g_fntpgm_uint8_t u8g_font_unifont_72_73[] U8G_FONT_SECTION("u8g_font_unifont_72_73"); +extern const u8g_fntpgm_uint8_t u8g_font_unifont_67_75[] U8G_FONT_SECTION("u8g_font_unifont_67_75"); +extern const u8g_fntpgm_uint8_t u8g_font_unifont_76[] U8G_FONT_SECTION("u8g_font_unifont_76"); +extern const u8g_fntpgm_uint8_t u8g_font_unifont_77[] U8G_FONT_SECTION("u8g_font_unifont_77"); +extern const u8g_fntpgm_uint8_t u8g_font_unifont_78_79[] U8G_FONT_SECTION("u8g_font_unifont_78_79"); +extern const u8g_fntpgm_uint8_t u8g_font_unifont_86[] U8G_FONT_SECTION("u8g_font_unifont_86"); +extern const u8g_fntpgm_uint8_t u8g_font_unifont[] U8G_FONT_SECTION("u8g_font_unifont"); +extern const u8g_fntpgm_uint8_t u8g_font_unifontr[] U8G_FONT_SECTION("u8g_font_unifontr"); +extern const u8g_fntpgm_uint8_t u8g_font_unifont_0_8[] U8G_FONT_SECTION("u8g_font_unifont_0_8"); +extern const u8g_fntpgm_uint8_t u8g_font_unifont_2_3[] U8G_FONT_SECTION("u8g_font_unifont_2_3"); +extern const u8g_fntpgm_uint8_t u8g_font_unifont_4_5[] U8G_FONT_SECTION("u8g_font_unifont_4_5"); +extern const u8g_fntpgm_uint8_t u8g_font_unifont_8_9[] U8G_FONT_SECTION("u8g_font_unifont_8_9"); +extern const u8g_fntpgm_uint8_t u8g_font_unifont_12_13[] U8G_FONT_SECTION("u8g_font_unifont_12_13"); + + +/* 04b fonts */ + +extern const u8g_fntpgm_uint8_t u8g_font_04b_03b[] U8G_FONT_SECTION("u8g_font_04b_03b"); +extern const u8g_fntpgm_uint8_t u8g_font_04b_03bn[] U8G_FONT_SECTION("u8g_font_04b_03bn"); +extern const u8g_fntpgm_uint8_t u8g_font_04b_03br[] U8G_FONT_SECTION("u8g_font_04b_03br"); +extern const u8g_fntpgm_uint8_t u8g_font_04b_03[] U8G_FONT_SECTION("u8g_font_04b_03"); +extern const u8g_fntpgm_uint8_t u8g_font_04b_03n[] U8G_FONT_SECTION("u8g_font_04b_03n"); +extern const u8g_fntpgm_uint8_t u8g_font_04b_03r[] U8G_FONT_SECTION("u8g_font_04b_03r"); +extern const u8g_fntpgm_uint8_t u8g_font_04b_24[] U8G_FONT_SECTION("u8g_font_04b_24"); +extern const u8g_fntpgm_uint8_t u8g_font_04b_24n[] U8G_FONT_SECTION("u8g_font_04b_24n"); +extern const u8g_fntpgm_uint8_t u8g_font_04b_24r[] U8G_FONT_SECTION("u8g_font_04b_24r"); + +/* orgdot fonts */ + +extern const u8g_fntpgm_uint8_t u8g_font_orgv01[] U8G_FONT_SECTION("u8g_font_orgv01"); +extern const u8g_fntpgm_uint8_t u8g_font_orgv01r[] U8G_FONT_SECTION("u8g_font_orgv01r"); +extern const u8g_fntpgm_uint8_t u8g_font_orgv01n[] U8G_FONT_SECTION("u8g_font_orgv01n"); + +extern const u8g_fntpgm_uint8_t u8g_font_fixed_v0[] U8G_FONT_SECTION("u8g_font_fixed_v0"); +extern const u8g_fntpgm_uint8_t u8g_font_fixed_v0r[] U8G_FONT_SECTION("u8g_font_fixed_v0r"); +extern const u8g_fntpgm_uint8_t u8g_font_fixed_v0n[] U8G_FONT_SECTION("u8g_font_fixed_v0n"); + +extern const u8g_fntpgm_uint8_t u8g_font_tpssb[] U8G_FONT_SECTION("u8g_font_tpssb"); +extern const u8g_fntpgm_uint8_t u8g_font_tpssbr[] U8G_FONT_SECTION("u8g_font_tpssbr"); +extern const u8g_fntpgm_uint8_t u8g_font_tpssbn[] U8G_FONT_SECTION("u8g_font_tpssbn"); + +extern const u8g_fntpgm_uint8_t u8g_font_tpss[] U8G_FONT_SECTION("u8g_font_tpss"); +extern const u8g_fntpgm_uint8_t u8g_font_tpssr[] U8G_FONT_SECTION("u8g_font_tpssr"); +extern const u8g_fntpgm_uint8_t u8g_font_tpssn[] U8G_FONT_SECTION("u8g_font_tpssn"); + +/* contributed */ + +extern const u8g_fntpgm_uint8_t u8g_font_freedoomr25n[] U8G_FONT_SECTION("u8g_font_freedoomr25n"); +extern const u8g_fntpgm_uint8_t u8g_font_freedoomr10r[] U8G_FONT_SECTION("u8g_font_freedoomr10r"); + +/* adobe X11 */ +extern const u8g_fntpgm_uint8_t u8g_font_courB08[] U8G_FONT_SECTION("u8g_font_courB08"); +extern const u8g_fntpgm_uint8_t u8g_font_courB08r[] U8G_FONT_SECTION("u8g_font_courB08r"); +extern const u8g_fntpgm_uint8_t u8g_font_courB10[] U8G_FONT_SECTION("u8g_font_courB10"); +extern const u8g_fntpgm_uint8_t u8g_font_courB10r[] U8G_FONT_SECTION("u8g_font_courB10r"); +extern const u8g_fntpgm_uint8_t u8g_font_courB12[] U8G_FONT_SECTION("u8g_font_courB12"); +extern const u8g_fntpgm_uint8_t u8g_font_courB12r[] U8G_FONT_SECTION("u8g_font_courB12r"); +extern const u8g_fntpgm_uint8_t u8g_font_courB14[] U8G_FONT_SECTION("u8g_font_courB14"); +extern const u8g_fntpgm_uint8_t u8g_font_courB14r[] U8G_FONT_SECTION("u8g_font_courB14r"); +extern const u8g_fntpgm_uint8_t u8g_font_courB18[] U8G_FONT_SECTION("u8g_font_courB18"); +extern const u8g_fntpgm_uint8_t u8g_font_courB18r[] U8G_FONT_SECTION("u8g_font_courB18r"); +extern const u8g_fntpgm_uint8_t u8g_font_courB24[] U8G_FONT_SECTION("u8g_font_courB24"); +extern const u8g_fntpgm_uint8_t u8g_font_courB24r[] U8G_FONT_SECTION("u8g_font_courB24r"); +extern const u8g_fntpgm_uint8_t u8g_font_courB24n[] U8G_FONT_SECTION("u8g_font_courB24n"); + +extern const u8g_fntpgm_uint8_t u8g_font_courR08[] U8G_FONT_SECTION("u8g_font_courR08"); +extern const u8g_fntpgm_uint8_t u8g_font_courR08r[] U8G_FONT_SECTION("u8g_font_courR08r"); +extern const u8g_fntpgm_uint8_t u8g_font_courR10[] U8G_FONT_SECTION("u8g_font_courR10"); +extern const u8g_fntpgm_uint8_t u8g_font_courR10r[] U8G_FONT_SECTION("u8g_font_courR10r"); +extern const u8g_fntpgm_uint8_t u8g_font_courR12[] U8G_FONT_SECTION("u8g_font_courR12"); +extern const u8g_fntpgm_uint8_t u8g_font_courR12r[] U8G_FONT_SECTION("u8g_font_courR12r"); +extern const u8g_fntpgm_uint8_t u8g_font_courR14[] U8G_FONT_SECTION("u8g_font_courR14"); +extern const u8g_fntpgm_uint8_t u8g_font_courR14r[] U8G_FONT_SECTION("u8g_font_courR14r"); +extern const u8g_fntpgm_uint8_t u8g_font_courR18[] U8G_FONT_SECTION("u8g_font_courR18"); +extern const u8g_fntpgm_uint8_t u8g_font_courR18r[] U8G_FONT_SECTION("u8g_font_courR18r"); +extern const u8g_fntpgm_uint8_t u8g_font_courR24[] U8G_FONT_SECTION("u8g_font_courR24"); +extern const u8g_fntpgm_uint8_t u8g_font_courR24r[] U8G_FONT_SECTION("u8g_font_courR24r"); +extern const u8g_fntpgm_uint8_t u8g_font_courR24n[] U8G_FONT_SECTION("u8g_font_courR24n"); + +extern const u8g_fntpgm_uint8_t u8g_font_helvB08[] U8G_FONT_SECTION("u8g_font_helvB08"); +extern const u8g_fntpgm_uint8_t u8g_font_helvB08r[] U8G_FONT_SECTION("u8g_font_helvB08r"); +extern const u8g_fntpgm_uint8_t u8g_font_helvB10[] U8G_FONT_SECTION("u8g_font_helvB10"); +extern const u8g_fntpgm_uint8_t u8g_font_helvB10r[] U8G_FONT_SECTION("u8g_font_helvB10r"); +extern const u8g_fntpgm_uint8_t u8g_font_helvB12[] U8G_FONT_SECTION("u8g_font_helvB12"); +extern const u8g_fntpgm_uint8_t u8g_font_helvB12r[] U8G_FONT_SECTION("u8g_font_helvB12r"); +extern const u8g_fntpgm_uint8_t u8g_font_helvB14[] U8G_FONT_SECTION("u8g_font_helvB14"); +extern const u8g_fntpgm_uint8_t u8g_font_helvB14r[] U8G_FONT_SECTION("u8g_font_helvB14r"); +extern const u8g_fntpgm_uint8_t u8g_font_helvB18[] U8G_FONT_SECTION("u8g_font_helvB18"); +extern const u8g_fntpgm_uint8_t u8g_font_helvB18r[] U8G_FONT_SECTION("u8g_font_helvB18r"); +extern const u8g_fntpgm_uint8_t u8g_font_helvB24[] U8G_FONT_SECTION("u8g_font_helvB24"); +extern const u8g_fntpgm_uint8_t u8g_font_helvB24r[] U8G_FONT_SECTION("u8g_font_helvB24r"); +extern const u8g_fntpgm_uint8_t u8g_font_helvB24n[] U8G_FONT_SECTION("u8g_font_helvB24n"); + +extern const u8g_fntpgm_uint8_t u8g_font_helvR08[] U8G_FONT_SECTION("u8g_font_helvR08"); +extern const u8g_fntpgm_uint8_t u8g_font_helvR08r[] U8G_FONT_SECTION("u8g_font_helvR08r"); +extern const u8g_fntpgm_uint8_t u8g_font_helvR10[] U8G_FONT_SECTION("u8g_font_helvR10"); +extern const u8g_fntpgm_uint8_t u8g_font_helvR10r[] U8G_FONT_SECTION("u8g_font_helvR10r"); +extern const u8g_fntpgm_uint8_t u8g_font_helvR12[] U8G_FONT_SECTION("u8g_font_helvR12"); +extern const u8g_fntpgm_uint8_t u8g_font_helvR12r[] U8G_FONT_SECTION("u8g_font_helvR12r"); +extern const u8g_fntpgm_uint8_t u8g_font_helvR14[] U8G_FONT_SECTION("u8g_font_helvR14"); +extern const u8g_fntpgm_uint8_t u8g_font_helvR14r[] U8G_FONT_SECTION("u8g_font_helvR14r"); +extern const u8g_fntpgm_uint8_t u8g_font_helvR18[] U8G_FONT_SECTION("u8g_font_helvR18"); +extern const u8g_fntpgm_uint8_t u8g_font_helvR18r[] U8G_FONT_SECTION("u8g_font_helvR18r"); +extern const u8g_fntpgm_uint8_t u8g_font_helvR24[] U8G_FONT_SECTION("u8g_font_helvR24"); +extern const u8g_fntpgm_uint8_t u8g_font_helvR24r[] U8G_FONT_SECTION("u8g_font_helvR24r"); +extern const u8g_fntpgm_uint8_t u8g_font_helvR24n[] U8G_FONT_SECTION("u8g_font_helvR24n"); + +extern const u8g_fntpgm_uint8_t u8g_font_ncenB08[] U8G_FONT_SECTION("u8g_font_ncenB08"); +extern const u8g_fntpgm_uint8_t u8g_font_ncenB08r[] U8G_FONT_SECTION("u8g_font_ncenB08r"); +extern const u8g_fntpgm_uint8_t u8g_font_ncenB10[] U8G_FONT_SECTION("u8g_font_ncenB10"); +extern const u8g_fntpgm_uint8_t u8g_font_ncenB10r[] U8G_FONT_SECTION("u8g_font_ncenB10r"); +extern const u8g_fntpgm_uint8_t u8g_font_ncenB12[] U8G_FONT_SECTION("u8g_font_ncenB12"); +extern const u8g_fntpgm_uint8_t u8g_font_ncenB12r[] U8G_FONT_SECTION("u8g_font_ncenB12r"); +extern const u8g_fntpgm_uint8_t u8g_font_ncenB14[] U8G_FONT_SECTION("u8g_font_ncenB14"); +extern const u8g_fntpgm_uint8_t u8g_font_ncenB14r[] U8G_FONT_SECTION("u8g_font_ncenB14r"); +extern const u8g_fntpgm_uint8_t u8g_font_ncenB18[] U8G_FONT_SECTION("u8g_font_ncenB18"); +extern const u8g_fntpgm_uint8_t u8g_font_ncenB18r[] U8G_FONT_SECTION("u8g_font_ncenB18r"); +extern const u8g_fntpgm_uint8_t u8g_font_ncenB24[] U8G_FONT_SECTION("u8g_font_ncenB24"); +extern const u8g_fntpgm_uint8_t u8g_font_ncenB24r[] U8G_FONT_SECTION("u8g_font_ncenB24r"); +extern const u8g_fntpgm_uint8_t u8g_font_ncenB24n[] U8G_FONT_SECTION("u8g_font_ncenB24n"); + +extern const u8g_fntpgm_uint8_t u8g_font_ncenR08[] U8G_FONT_SECTION("u8g_font_ncenR08"); +extern const u8g_fntpgm_uint8_t u8g_font_ncenR08r[] U8G_FONT_SECTION("u8g_font_ncenR08r"); +extern const u8g_fntpgm_uint8_t u8g_font_ncenR10[] U8G_FONT_SECTION("u8g_font_ncenR10"); +extern const u8g_fntpgm_uint8_t u8g_font_ncenR10r[] U8G_FONT_SECTION("u8g_font_ncenR10r"); +extern const u8g_fntpgm_uint8_t u8g_font_ncenR12[] U8G_FONT_SECTION("u8g_font_ncenR12"); +extern const u8g_fntpgm_uint8_t u8g_font_ncenR12r[] U8G_FONT_SECTION("u8g_font_ncenR12r"); +extern const u8g_fntpgm_uint8_t u8g_font_ncenR14[] U8G_FONT_SECTION("u8g_font_ncenR14"); +extern const u8g_fntpgm_uint8_t u8g_font_ncenR14r[] U8G_FONT_SECTION("u8g_font_ncenR14r"); +extern const u8g_fntpgm_uint8_t u8g_font_ncenR18[] U8G_FONT_SECTION("u8g_font_ncenR18"); +extern const u8g_fntpgm_uint8_t u8g_font_ncenR18r[] U8G_FONT_SECTION("u8g_font_ncenR18r"); +extern const u8g_fntpgm_uint8_t u8g_font_ncenR24[] U8G_FONT_SECTION("u8g_font_ncenR24"); +extern const u8g_fntpgm_uint8_t u8g_font_ncenR24r[] U8G_FONT_SECTION("u8g_font_ncenR24r"); +extern const u8g_fntpgm_uint8_t u8g_font_ncenR24n[] U8G_FONT_SECTION("u8g_font_ncenR24n"); + +extern const u8g_fntpgm_uint8_t u8g_font_symb08[] U8G_FONT_SECTION("u8g_font_symb08"); +extern const u8g_fntpgm_uint8_t u8g_font_symb08r[] U8G_FONT_SECTION("u8g_font_symb08r"); +extern const u8g_fntpgm_uint8_t u8g_font_symb10[] U8G_FONT_SECTION("u8g_font_symb10"); +extern const u8g_fntpgm_uint8_t u8g_font_symb10r[] U8G_FONT_SECTION("u8g_font_symb10r"); +extern const u8g_fntpgm_uint8_t u8g_font_symb12[] U8G_FONT_SECTION("u8g_font_symb12"); +extern const u8g_fntpgm_uint8_t u8g_font_symb12r[] U8G_FONT_SECTION("u8g_font_symb12r"); +extern const u8g_fntpgm_uint8_t u8g_font_symb14[] U8G_FONT_SECTION("u8g_font_symb14"); +extern const u8g_fntpgm_uint8_t u8g_font_symb14r[] U8G_FONT_SECTION("u8g_font_symb14r"); +extern const u8g_fntpgm_uint8_t u8g_font_symb18[] U8G_FONT_SECTION("u8g_font_symb18"); +extern const u8g_fntpgm_uint8_t u8g_font_symb18r[] U8G_FONT_SECTION("u8g_font_symb18r"); +extern const u8g_fntpgm_uint8_t u8g_font_symb24[] U8G_FONT_SECTION("u8g_font_symb24"); +extern const u8g_fntpgm_uint8_t u8g_font_symb24r[] U8G_FONT_SECTION("u8g_font_symb24r"); + +extern const u8g_fntpgm_uint8_t u8g_font_timB08[] U8G_FONT_SECTION("u8g_font_timB08"); +extern const u8g_fntpgm_uint8_t u8g_font_timB08r[] U8G_FONT_SECTION("u8g_font_timB08r"); +extern const u8g_fntpgm_uint8_t u8g_font_timB10[] U8G_FONT_SECTION("u8g_font_timB10"); +extern const u8g_fntpgm_uint8_t u8g_font_timB10r[] U8G_FONT_SECTION("u8g_font_timB10r"); +extern const u8g_fntpgm_uint8_t u8g_font_timB12[] U8G_FONT_SECTION("u8g_font_timB12"); +extern const u8g_fntpgm_uint8_t u8g_font_timB12r[] U8G_FONT_SECTION("u8g_font_timB12r"); +extern const u8g_fntpgm_uint8_t u8g_font_timB14[] U8G_FONT_SECTION("u8g_font_timB14"); +extern const u8g_fntpgm_uint8_t u8g_font_timB14r[] U8G_FONT_SECTION("u8g_font_timB14r"); +extern const u8g_fntpgm_uint8_t u8g_font_timB18[] U8G_FONT_SECTION("u8g_font_timB18"); +extern const u8g_fntpgm_uint8_t u8g_font_timB18r[] U8G_FONT_SECTION("u8g_font_timB18r"); +extern const u8g_fntpgm_uint8_t u8g_font_timB24[] U8G_FONT_SECTION("u8g_font_timB24"); +extern const u8g_fntpgm_uint8_t u8g_font_timB24r[] U8G_FONT_SECTION("u8g_font_timB24r"); +extern const u8g_fntpgm_uint8_t u8g_font_timB24n[] U8G_FONT_SECTION("u8g_font_timB24n"); + +extern const u8g_fntpgm_uint8_t u8g_font_timR08[] U8G_FONT_SECTION("u8g_font_timR08"); +extern const u8g_fntpgm_uint8_t u8g_font_timR08r[] U8G_FONT_SECTION("u8g_font_timR08r"); +extern const u8g_fntpgm_uint8_t u8g_font_timR10[] U8G_FONT_SECTION("u8g_font_timR10"); +extern const u8g_fntpgm_uint8_t u8g_font_timR10r[] U8G_FONT_SECTION("u8g_font_timR10r"); +extern const u8g_fntpgm_uint8_t u8g_font_timR12[] U8G_FONT_SECTION("u8g_font_timR12"); +extern const u8g_fntpgm_uint8_t u8g_font_timR12r[] U8G_FONT_SECTION("u8g_font_timR12r"); +extern const u8g_fntpgm_uint8_t u8g_font_timR14[] U8G_FONT_SECTION("u8g_font_timR14"); +extern const u8g_fntpgm_uint8_t u8g_font_timR14r[] U8G_FONT_SECTION("u8g_font_timR14r"); +extern const u8g_fntpgm_uint8_t u8g_font_timR18[] U8G_FONT_SECTION("u8g_font_timR18"); +extern const u8g_fntpgm_uint8_t u8g_font_timR18r[] U8G_FONT_SECTION("u8g_font_timR18r"); +extern const u8g_fntpgm_uint8_t u8g_font_timR24[] U8G_FONT_SECTION("u8g_font_timR24"); +extern const u8g_fntpgm_uint8_t u8g_font_timR24r[] U8G_FONT_SECTION("u8g_font_timR24r"); +extern const u8g_fntpgm_uint8_t u8g_font_timR24n[] U8G_FONT_SECTION("u8g_font_timR24n"); + +/* fontstruct */ + +extern const u8g_fntpgm_uint8_t u8g_font_p01type[] U8G_FONT_SECTION("u8g_font_p01type"); +extern const u8g_fntpgm_uint8_t u8g_font_p01typer[] U8G_FONT_SECTION("u8g_font_p01typer"); +extern const u8g_fntpgm_uint8_t u8g_font_p01typen[] U8G_FONT_SECTION("u8g_font_p01typen"); + +extern const u8g_fntpgm_uint8_t u8g_font_lucasfont_alternate[] U8G_FONT_SECTION("u8g_font_lucasfont_alternate"); +extern const u8g_fntpgm_uint8_t u8g_font_lucasfont_alternater[] U8G_FONT_SECTION("u8g_font_lucasfont_alternater"); +extern const u8g_fntpgm_uint8_t u8g_font_lucasfont_alternaten[] U8G_FONT_SECTION("u8g_font_lucasfont_alternaten"); + +extern const u8g_fntpgm_uint8_t u8g_font_chikita[] U8G_FONT_SECTION("u8g_font_chikita"); +extern const u8g_fntpgm_uint8_t u8g_font_chikitar[] U8G_FONT_SECTION("u8g_font_chikitar"); +extern const u8g_fntpgm_uint8_t u8g_font_chikitan[] U8G_FONT_SECTION("u8g_font_chikitan"); + +extern const u8g_fntpgm_uint8_t u8g_font_pixelle_micro[] U8G_FONT_SECTION("u8g_font_pixelle_micro"); +extern const u8g_fntpgm_uint8_t u8g_font_pixelle_micror[] U8G_FONT_SECTION("u8g_font_pixelle_micror"); +extern const u8g_fntpgm_uint8_t u8g_font_pixelle_micron[] U8G_FONT_SECTION("u8g_font_pixelle_micron"); + +extern const u8g_fntpgm_uint8_t u8g_font_trixel_square[] U8G_FONT_SECTION("u8g_font_trixel_square"); +extern const u8g_fntpgm_uint8_t u8g_font_trixel_squarer[] U8G_FONT_SECTION("u8g_font_trixel_squarer"); +extern const u8g_fntpgm_uint8_t u8g_font_trixel_squaren[] U8G_FONT_SECTION("u8g_font_trixel_squaren"); + +extern const u8g_fntpgm_uint8_t u8g_font_robot_de_niro[] U8G_FONT_SECTION("u8g_font_robot_de_niro"); +extern const u8g_fntpgm_uint8_t u8g_font_robot_de_niror[] U8G_FONT_SECTION("u8g_font_robot_de_niror"); +extern const u8g_fntpgm_uint8_t u8g_font_robot_de_niron[] U8G_FONT_SECTION("u8g_font_robot_de_niron"); + +extern const u8g_fntpgm_uint8_t u8g_font_baby[] U8G_FONT_SECTION("u8g_font_baby"); +extern const u8g_fntpgm_uint8_t u8g_font_babyr[] U8G_FONT_SECTION("u8g_font_babyr"); +extern const u8g_fntpgm_uint8_t u8g_font_babyn[] U8G_FONT_SECTION("u8g_font_babyn"); + +extern const u8g_fntpgm_uint8_t u8g_font_blipfest_07[] U8G_FONT_SECTION("u8g_font_blipfest_07"); +extern const u8g_fntpgm_uint8_t u8g_font_blipfest_07r[] U8G_FONT_SECTION("u8g_font_blipfest_07r"); +extern const u8g_fntpgm_uint8_t u8g_font_blipfest_07n[] U8G_FONT_SECTION("u8g_font_blipfest_07n"); + + + +#ifdef __cplusplus +} +#endif + +#endif /* _U8G_H */ + +/* + Fontname: -Misc-Fixed-Medium-R-Normal--7-70-75-75-C-50-ISO10646-1 + Copyright: Public domain font. Share and enjoy. + Capital A Height: 6, '1' Height: 6 + Calculated Max Values w= 7 h= 8 x= 4 y= 5 dx= 9 dy= 0 ascent= 8 len= 8 + Font Bounding box w= 5 h= 7 x= 0 y=-1 + Calculated Min Values x= 0 y=-1 dx= 0 dy= 0 + Pure Font ascent = 6 descent=-1 + X Font ascent = 6 descent=-1 + Max Font ascent = 8 descent=-1 +*/ +const u8g_fntpgm_uint8_t repetier_5x7[2405] U8G_FONT_SECTION("repetier_5x7") = { + 0,5,7,0,255,6,2,72,3,186,0,255,255,8,255,6, + 255,5,5,5,5,0,0,168,0,136,0,168,5,8,8,6, + 0,0,8,8,8,40,72,248,64,32,3,3,3,6,1,4, + 64,160,64,5,5,5,6,0,0,248,248,248,248,248,5,5, + 5,6,0,0,248,136,136,136,248,5,8,8,6,0,0,32, + 80,80,80,112,248,248,112,7,5,5,9,0,0,28,254,130, + 130,254,5,8,8,6,0,0,136,80,32,136,32,80,136,136, + 6,8,8,6,0,0,72,144,72,252,252,120,48,48,6,8, + 8,6,0,0,36,72,36,252,252,120,48,48,6,5,5,6, + 0,0,252,252,120,48,48,6,2,2,6,0,0,252,252,6, + 6,6,6,0,0,72,144,72,144,252,252,6,6,6,6,0, + 0,36,72,36,72,252,252,7,7,7,7,0,0,130,68,56, + 40,56,68,130,7,7,7,7,0,0,16,16,56,238,56,16, + 16,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,0,0,0,5,4,0,1,6,6,5,2,0,128,128,128, + 128,0,128,3,3,3,5,1,3,160,160,160,5,5,5,5, + 0,0,80,248,80,248,80,5,5,5,5,0,0,112,160,112, + 40,112,4,6,6,5,0,0,128,144,32,64,144,16,4,5, + 5,5,0,0,64,160,64,160,80,1,3,3,5,2,3,128, + 128,128,2,6,6,5,1,0,64,128,128,128,128,64,2,6, + 6,5,1,0,128,64,64,64,64,128,3,5,5,5,1,0, + 160,64,224,64,160,5,5,5,5,0,0,32,32,248,32,32, + 3,3,3,5,1,255,96,64,128,4,1,1,5,0,2,240, + 2,2,2,5,1,0,192,192,4,4,4,5,0,1,16,32, + 64,128,3,6,6,5,1,0,64,160,160,160,160,64,3,6, + 6,5,1,0,64,192,64,64,64,224,4,6,6,5,0,0, + 96,144,16,32,64,240,4,6,6,5,0,0,240,16,96,16, + 144,96,4,6,6,5,0,0,32,96,160,240,32,32,4,6, + 6,5,0,0,240,128,224,16,144,96,4,6,6,5,0,0, + 96,128,224,144,144,96,4,6,6,5,0,0,240,16,32,32, + 64,64,4,6,6,5,0,0,96,144,96,144,144,96,4,6, + 6,5,0,0,96,144,144,112,16,96,2,5,5,5,1,0, + 192,192,0,192,192,3,6,6,5,0,255,96,96,0,96,64, + 128,3,5,5,5,1,0,32,64,128,64,32,4,3,3,5, + 0,1,240,0,240,3,5,5,5,1,0,128,64,32,64,128, + 3,6,6,5,1,0,64,160,32,64,0,64,4,6,6,5, + 0,0,96,144,176,176,128,96,4,6,6,5,0,0,96,144, + 144,240,144,144,4,6,6,5,0,0,224,144,224,144,144,224, + 4,6,6,5,0,0,96,144,128,128,144,96,4,6,6,5, + 0,0,224,144,144,144,144,224,4,6,6,5,0,0,240,128, + 224,128,128,240,4,6,6,5,0,0,240,128,224,128,128,128, + 4,6,6,5,0,0,96,144,128,176,144,112,4,6,6,5, + 0,0,144,144,240,144,144,144,3,6,6,5,1,0,224,64, + 64,64,64,224,4,6,6,5,0,0,16,16,16,16,144,96, + 4,6,6,5,0,0,144,160,192,192,160,144,4,6,6,5, + 0,0,128,128,128,128,128,240,4,6,6,5,0,0,144,240, + 240,144,144,144,4,6,6,5,0,0,144,208,208,176,176,144, + 4,6,6,5,0,0,96,144,144,144,144,96,4,6,6,5, + 0,0,224,144,144,224,128,128,4,7,7,5,0,255,96,144, + 144,144,208,96,16,4,6,6,5,0,0,224,144,144,224,160, + 144,4,6,6,5,0,0,96,144,64,32,144,96,3,6,6, + 5,1,0,224,64,64,64,64,64,4,6,6,5,0,0,144, + 144,144,144,144,96,4,6,6,5,0,0,144,144,144,144,96, + 96,4,6,6,5,0,0,144,144,144,240,240,144,4,6,6, + 5,0,0,144,144,96,96,144,144,3,6,6,5,1,0,160, + 160,160,64,64,64,4,6,6,5,0,0,240,16,32,64,128, + 240,3,6,6,5,1,0,224,128,128,128,128,224,4,4,4, + 5,0,1,128,64,32,16,3,6,6,5,1,0,224,32,32, + 32,32,224,3,2,2,5,1,4,64,160,4,1,1,5,0, + 0,240,2,2,2,5,1,4,128,64,4,4,4,5,0,0, + 112,144,176,80,4,6,6,5,0,0,128,128,224,144,144,224, + 3,4,4,5,0,0,96,128,128,96,4,6,6,5,0,0, + 16,16,112,144,144,112,4,4,4,5,0,0,96,176,192,96, + 4,6,6,5,0,0,32,80,64,224,64,64,4,5,5,5, + 0,255,112,144,96,128,112,4,6,6,5,0,0,128,128,224, + 144,144,144,3,6,6,5,1,0,64,0,192,64,64,224,3, + 7,7,5,1,255,32,0,32,32,32,160,64,4,6,6,5, + 0,0,128,128,160,192,160,144,3,6,6,5,1,0,192,64, + 64,64,64,224,4,4,4,5,0,0,160,240,144,144,4,4, + 4,5,0,0,224,144,144,144,4,4,4,5,0,0,96,144, + 144,96,4,5,5,5,0,255,224,144,144,224,128,4,5,5, + 5,0,255,112,144,144,112,16,4,4,4,5,0,0,224,144, + 128,128,4,4,4,5,0,0,112,192,48,224,4,6,6,5, + 0,0,64,64,224,64,64,48,4,4,4,5,0,0,144,144, + 144,112,3,4,4,5,1,0,160,160,160,64,4,4,4,5, + 0,0,144,144,240,240,4,4,4,5,0,0,144,96,96,144, + 4,5,5,5,0,255,144,144,80,32,64,4,4,4,5,0, + 0,240,32,64,240,3,6,6,5,1,0,32,64,192,64,64, + 32,1,6,6,5,2,0,128,128,128,128,128,128,3,6,6, + 5,1,0,128,64,96,64,64,128,4,2,2,5,0,4,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,5,4,0,1,6,6,5,2,0,128,0, + 128,128,128,128,4,6,6,5,0,255,32,112,160,160,112,32, + 4,5,5,5,0,0,48,64,224,64,176,5,5,5,5,0, + 0,136,112,80,112,136,3,6,6,5,1,0,160,160,64,224, + 64,64,1,5,5,5,2,0,128,128,0,128,128,3,7,7, + 5,1,255,96,128,192,160,96,32,192,3,1,1,5,1,5, + 160,5,7,7,5,0,255,112,136,168,200,168,136,112,3,3, + 3,5,0,3,96,160,96,5,3,3,5,0,1,72,144,72, + 4,2,2,5,0,1,240,16,3,1,1,5,1,2,224,5, + 7,7,5,0,255,112,136,232,200,200,136,112,4,1,1,5, + 0,5,240,3,3,3,5,1,3,64,160,64,5,6,6,5, + 0,0,32,32,248,32,32,248,2,4,4,5,1,2,192,64, + 128,192,2,4,4,5,1,2,192,192,64,192,2,2,2,5, + 1,4,64,128,4,5,5,5,0,255,144,144,144,224,128,4, + 6,6,5,0,0,112,208,208,80,80,80,2,2,2,5,1, + 2,192,192,2,2,2,5,1,255,64,128,3,4,4,5,1, + 2,64,192,64,224,3,3,3,5,0,3,64,160,64,5,3, + 3,5,0,1,144,72,144,4,7,7,5,0,255,128,128,128, + 144,48,112,16,4,7,7,5,0,255,128,128,128,176,16,32, + 48,4,7,7,5,0,255,192,192,64,208,48,112,16,3,6, + 6,5,1,0,64,0,64,128,160,64,4,6,6,5,0,0, + 96,144,144,240,144,144,4,6,6,5,0,0,96,144,144,240, + 144,144,4,6,6,5,0,0,96,144,144,240,144,144,4,6, + 6,5,0,0,96,144,144,240,144,144,4,6,6,5,0,0, + 144,96,144,240,144,144,4,6,6,5,0,0,96,96,144,240, + 144,144,4,6,6,5,0,0,112,160,176,224,160,176,4,7, + 7,5,0,255,96,144,128,128,144,96,64,4,6,6,5,0, + 0,240,128,224,128,128,240,4,6,6,5,0,0,240,128,224, + 128,128,240,4,6,6,5,0,0,240,128,224,128,128,240,4, + 6,6,5,0,0,240,128,224,128,128,240,3,6,6,5,1, + 0,224,64,64,64,64,224,3,6,6,5,1,0,224,64,64, + 64,64,224,3,6,6,5,1,0,224,64,64,64,64,224,3, + 6,6,5,1,0,224,64,64,64,64,224,4,6,6,5,0, + 0,224,80,208,80,80,224,4,6,6,5,0,0,176,144,208, + 176,176,144,4,6,6,5,0,0,96,144,144,144,144,96,4, + 6,6,5,0,0,96,144,144,144,144,96,4,6,6,5,0, + 0,96,144,144,144,144,96,4,6,6,5,0,0,96,144,144, + 144,144,96,4,6,6,5,0,0,144,96,144,144,144,96,4, + 4,4,5,0,0,144,96,96,144,4,6,6,5,0,0,112, + 176,176,208,208,224,4,6,6,5,0,0,144,144,144,144,144, + 96,4,6,6,5,0,0,144,144,144,144,144,96,4,6,6, + 5,0,0,144,144,144,144,144,96,4,6,6,5,0,0,144, + 0,144,144,144,96,3,6,6,5,1,0,160,160,160,64,64, + 64,4,6,6,5,0,0,128,224,144,224,128,128,4,6,6, + 5,0,0,96,144,160,144,144,160,4,6,6,5,0,0,64, + 32,112,144,176,80,4,6,6,5,0,0,32,64,112,144,176, + 80,4,6,6,5,0,0,32,80,112,144,176,80,4,6,6, + 5,0,0,80,160,112,144,176,80,4,6,6,5,0,0,80, + 0,112,144,176,80,4,6,6,5,0,0,96,96,112,144,176, + 80,4,4,4,5,0,0,112,176,160,112,3,5,5,5,1, + 255,96,128,128,96,64,4,6,6,5,0,0,64,32,96,176, + 192,96,4,6,6,5,0,0,32,64,96,176,192,96,4,6, + 6,5,0,0,64,160,96,176,192,96,4,6,6,5,0,0, + 160,0,96,176,192,96,3,6,6,5,1,0,128,64,192,64, + 64,224,3,6,6,5,1,0,64,128,192,64,64,224,3,6, + 6,5,1,0,64,160,192,64,64,224,3,6,6,5,1,0, + 160,0,192,64,64,224,4,6,6,5,0,0,64,48,96,144, + 144,96,4,6,6,5,0,0,80,160,224,144,144,144,4,6, + 6,5,0,0,64,32,96,144,144,96,4,6,6,5,0,0, + 32,64,96,144,144,96,4,6,6,5,0,0,96,0,96,144, + 144,96,4,6,6,5,0,0,80,160,96,144,144,96,4,6, + 6,5,0,0,80,0,96,144,144,96,4,5,5,5,0,0, + 96,0,240,0,96,4,4,4,5,0,0,112,176,208,224,4, + 6,6,5,0,0,64,32,144,144,144,112,4,6,6,5,0, + 0,32,64,144,144,144,112,4,6,6,5,0,0,96,0,144, + 144,144,112,4,6,6,5,0,0,80,0,144,144,144,112,4, + 7,7,5,0,255,32,64,144,144,80,32,64,4,6,6,5, + 0,255,128,224,144,144,224,128,4,7,7,5,0,255,80,0, + 144,144,80,32,64}; + +/* + Fontname: -Misc-Fixed-Medium-R-Normal--10-100-75-75-C-60-ISO10646-1 + Copyright: Public domain terminal emulator font. Share and enjoy. + Capital A Height: 7, '1' Height: 7 + Calculated Max Values w= 7 h= 9 x= 5 y= 7 dx= 9 dy= 0 ascent= 8 len= 9 + Font Bounding box w= 7 h=10 x= 0 y=-2 + Calculated Min Values x= 0 y=-2 dx= 0 dy= 0 + Pure Font ascent = 7 descent=-2 + X Font ascent = 7 descent=-2 + Max Font ascent = 8 descent=-2 +*/ +const u8g_fntpgm_uint8_t repetier_6x10[2625] U8G_FONT_SECTION("repetier_6x10") = { + 0,7,10,0,254,7,2,105,3,251,0,255,254,8,254,7, + 254,5,7,7,6,0,0,168,0,136,0,136,0,168,5,8, + 8,6,0,0,8,8,8,40,72,248,64,32,3,3,3,6, + 1,4,64,160,64,5,5,5,6,0,0,248,248,248,248,248, + 5,5,5,6,0,0,248,136,136,136,248,5,8,8,6,0, + 0,32,80,80,80,112,248,248,112,7,5,5,9,0,0,28, + 254,130,130,254,5,8,8,6,0,0,136,80,32,136,32,80, + 136,136,6,8,8,6,0,0,72,144,72,252,252,120,48,48, + 6,8,8,6,0,0,36,72,36,252,252,120,48,48,6,5, + 5,6,0,0,252,252,120,48,48,6,2,2,6,0,0,252, + 252,6,6,6,6,0,0,72,144,72,144,252,252,6,6,6, + 6,0,0,36,72,36,72,252,252,7,7,7,7,0,0,130, + 68,56,40,56,68,130,7,7,7,7,0,0,16,16,56,238, + 56,16,16,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,0,0,0,6,5,255,1,7,7,6,2,0,128, + 128,128,128,128,0,128,3,3,3,6,1,4,160,160,160,5, + 7,7,6,0,0,80,80,248,80,248,80,80,5,7,7,6, + 0,0,32,112,160,112,40,112,32,6,8,8,6,0,0,68, + 164,72,16,32,72,148,136,5,7,7,6,0,0,64,160,160, + 64,168,144,104,1,3,3,6,2,4,128,128,128,3,7,7, + 6,1,0,32,64,128,128,128,64,32,3,7,7,6,1,0, + 128,64,32,32,32,64,128,5,5,5,6,0,1,136,80,248, + 80,136,5,5,5,6,0,1,32,32,248,32,32,3,3,3, + 6,1,255,96,64,128,4,1,1,6,1,3,240,2,2,2, + 6,1,255,192,192,5,7,7,6,0,0,8,8,16,32,64, + 128,128,5,7,7,6,0,0,32,80,136,136,136,80,32,5, + 7,7,6,0,0,32,96,160,32,32,32,248,5,7,7,6, + 0,0,112,136,8,48,64,128,248,5,7,7,6,0,0,248, + 8,16,48,8,136,112,5,7,7,6,0,0,16,48,80,144, + 248,16,16,5,7,7,6,0,0,248,128,176,200,8,136,112, + 5,7,7,6,0,0,48,64,128,176,200,136,112,5,7,7, + 6,0,0,248,8,16,16,32,64,64,5,7,7,6,0,0, + 112,136,136,112,136,136,112,5,7,7,6,0,0,112,136,152, + 104,8,16,96,2,5,5,6,2,1,192,192,0,192,192,3, + 7,7,6,1,255,64,224,64,0,96,64,128,4,7,7,6, + 1,0,16,32,64,128,64,32,16,5,3,3,6,0,2,248, + 0,248,4,7,7,6,1,0,128,64,32,16,32,64,128,5, + 7,7,6,0,0,112,136,16,32,32,0,32,5,7,7,6, + 0,0,112,136,152,168,176,128,112,5,7,7,6,0,0,32, + 80,136,136,248,136,136,5,7,7,6,0,0,240,72,72,112, + 72,72,240,5,7,7,6,0,0,112,136,128,128,128,136,112, + 5,7,7,6,0,0,240,72,72,72,72,72,240,5,7,7, + 6,0,0,248,128,128,240,128,128,248,5,7,7,6,0,0, + 248,128,128,240,128,128,128,5,7,7,6,0,0,112,136,128, + 128,152,136,112,5,7,7,6,0,0,136,136,136,248,136,136, + 136,3,7,7,6,1,0,224,64,64,64,64,64,224,5,7, + 7,6,0,0,56,16,16,16,16,144,96,5,7,7,6,0, + 0,136,144,160,192,160,144,136,5,7,7,6,0,0,128,128, + 128,128,128,128,248,5,7,7,6,0,0,136,136,216,168,136, + 136,136,5,7,7,6,0,0,136,136,200,168,152,136,136,5, + 7,7,6,0,0,112,136,136,136,136,136,112,5,7,7,6, + 0,0,240,136,136,240,128,128,128,5,8,8,6,0,255,112, + 136,136,136,136,168,112,8,5,7,7,6,0,0,240,136,136, + 240,160,144,136,5,7,7,6,0,0,112,136,128,112,8,136, + 112,5,7,7,6,0,0,248,32,32,32,32,32,32,5,7, + 7,6,0,0,136,136,136,136,136,136,112,5,7,7,6,0, + 0,136,136,136,80,80,80,32,5,7,7,6,0,0,136,136, + 136,168,168,216,136,5,7,7,6,0,0,136,136,80,32,80, + 136,136,5,7,7,6,0,0,136,136,80,32,32,32,32,5, + 7,7,6,0,0,248,8,16,32,64,128,248,3,7,7,6, + 1,0,224,128,128,128,128,128,224,5,7,7,6,0,0,128, + 128,64,32,16,8,8,3,7,7,6,1,0,224,32,32,32, + 32,32,224,5,3,3,6,0,4,32,80,136,5,1,1,6, + 0,255,248,2,2,2,6,2,6,128,64,5,5,5,6,0, + 0,112,8,120,136,120,5,7,7,6,0,0,128,128,176,200, + 136,200,176,5,5,5,6,0,0,112,136,128,136,112,5,7, + 7,6,0,0,8,8,104,152,136,152,104,5,5,5,6,0, + 0,112,136,248,128,112,5,7,7,6,0,0,48,72,64,240, + 64,64,64,5,7,7,6,0,254,120,136,136,120,8,136,112, + 5,7,7,6,0,0,128,128,176,200,136,136,136,3,7,7, + 6,1,0,64,0,192,64,64,64,224,4,9,9,6,1,254, + 16,0,48,16,16,16,144,144,96,5,7,7,6,0,0,128, + 128,136,144,224,144,136,3,7,7,6,1,0,192,64,64,64, + 64,64,224,5,5,5,6,0,0,208,168,168,168,136,5,5, + 5,6,0,0,176,200,136,136,136,5,5,5,6,0,0,112, + 136,136,136,112,5,7,7,6,0,254,176,200,136,200,176,128, + 128,5,7,7,6,0,254,104,152,136,152,104,8,8,5,5, + 5,6,0,0,176,200,128,128,128,5,5,5,6,0,0,112, + 128,112,8,240,5,7,7,6,0,0,64,64,240,64,64,72, + 48,5,5,5,6,0,0,136,136,136,152,104,5,5,5,6, + 0,0,136,136,80,80,32,5,5,5,6,0,0,136,136,168, + 168,80,5,5,5,6,0,0,136,80,32,80,136,5,7,7, + 6,0,254,136,136,152,104,8,136,112,5,5,5,6,0,0, + 248,16,32,64,248,4,7,7,6,1,0,48,64,32,192,32, + 64,48,1,7,7,6,2,0,128,128,128,128,128,128,128,4, + 7,7,6,1,0,192,32,64,48,64,32,192,5,3,3,6, + 0,4,72,168,144,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,255,1,7,7,6,2,0,128,0,128, + 128,128,128,128,5,7,7,6,0,255,32,120,160,160,160,120, + 32,5,7,7,6,0,0,48,72,64,224,64,72,176,5,5, + 5,6,0,0,136,112,80,112,136,5,8,8,6,0,255,136, + 136,80,32,248,32,32,32,1,7,7,6,2,0,128,128,128, + 0,128,128,128,5,8,8,6,0,255,112,128,224,144,72,56, + 8,112,3,1,1,6,1,7,160,5,7,7,6,0,0,112, + 136,168,200,168,136,112,4,6,6,6,1,1,112,144,176,80, + 0,240,6,5,5,6,0,0,36,72,144,72,36,4,2,2, + 6,1,2,240,16,255,5,7,7,6,0,0,112,136,232,200, + 200,136,112,5,1,1,6,0,7,248,3,3,3,6,1,4, + 64,160,64,5,6,6,6,0,0,32,32,248,32,32,248,4, + 5,5,6,1,3,96,144,32,64,240,4,5,5,6,1,3, + 224,16,96,16,224,2,2,2,6,2,6,64,128,255,5,7, + 7,6,0,0,120,232,232,104,40,40,40,1,1,1,6,2, + 3,128,2,2,2,6,2,254,64,128,3,5,5,6,1,3, + 64,192,64,64,224,4,6,6,6,1,1,96,144,144,96,0, + 240,6,5,5,6,0,0,144,72,36,72,144,6,9,9,6, + 0,255,64,192,64,64,228,12,20,60,4,6,9,9,6,0, + 255,64,192,64,64,232,20,4,8,28,5,9,9,6,0,255, + 192,32,64,32,200,24,40,120,8,5,7,7,6,0,0,32, + 0,32,32,64,136,112,5,8,8,6,0,0,64,32,112,136, + 136,248,136,136,5,8,8,6,0,0,16,32,112,136,136,248, + 136,136,5,8,8,6,0,0,32,80,112,136,136,248,136,136, + 5,8,8,6,0,0,72,176,112,136,136,248,136,136,5,8, + 8,6,0,0,80,0,112,136,136,248,136,136,5,8,8,6, + 0,0,32,80,112,136,136,248,136,136,6,7,7,6,0,0, + 60,80,144,156,240,144,156,5,9,9,6,0,254,112,136,128, + 128,128,136,112,32,64,5,8,8,6,0,0,64,248,128,128, + 240,128,128,248,5,8,8,6,0,0,16,248,128,128,240,128, + 128,248,5,8,8,6,0,0,32,248,128,128,240,128,128,248, + 5,8,8,6,0,0,80,248,128,128,240,128,128,248,3,8, + 8,6,1,0,128,64,224,64,64,64,64,224,3,8,8,6, + 1,0,32,64,224,64,64,64,64,224,3,8,8,6,1,0, + 64,160,224,64,64,64,64,224,3,8,8,6,1,0,160,0, + 224,64,64,64,64,224,5,7,7,6,0,0,240,72,72,232, + 72,72,240,5,8,8,6,0,0,40,80,136,200,168,152,136, + 136,5,8,8,6,0,0,64,32,112,136,136,136,136,112,5, + 8,8,6,0,0,16,32,112,136,136,136,136,112,5,8,8, + 6,0,0,32,80,112,136,136,136,136,112,5,8,8,6,0, + 0,40,80,112,136,136,136,136,112,5,8,8,6,0,0,80, + 0,112,136,136,136,136,112,5,5,5,6,0,0,136,80,32, + 80,136,5,7,7,6,0,0,112,152,152,168,200,200,112,5, + 8,8,6,0,0,64,32,136,136,136,136,136,112,5,8,8, + 6,0,0,16,32,136,136,136,136,136,112,5,8,8,6,0, + 0,32,80,0,136,136,136,136,112,5,8,8,6,0,0,80, + 0,136,136,136,136,136,112,5,8,8,6,0,0,16,32,136, + 136,80,32,32,32,5,7,7,6,0,0,128,240,136,240,128, + 128,128,5,7,7,6,0,0,112,136,144,160,144,136,176,5, + 8,8,6,0,0,64,32,0,112,8,120,136,120,5,8,8, + 6,0,0,16,32,0,112,8,120,136,120,5,8,8,6,0, + 0,32,80,0,112,8,120,136,120,5,8,8,6,0,0,40, + 80,0,112,8,120,136,120,5,7,7,6,0,0,80,0,112, + 8,120,136,120,5,8,8,6,0,0,32,80,32,112,8,120, + 136,120,6,5,5,6,0,0,120,20,124,144,124,5,7,7, + 6,0,254,112,136,128,136,112,32,64,5,8,8,6,0,0, + 64,32,0,112,136,248,128,112,5,8,8,6,0,0,16,32, + 0,112,136,248,128,112,5,8,8,6,0,0,32,80,0,112, + 136,248,128,112,5,7,7,6,0,0,80,0,112,136,248,128, + 112,3,8,8,6,1,0,128,64,0,192,64,64,64,224,3, + 8,8,6,1,0,64,128,0,192,64,64,64,224,3,8,8, + 6,1,0,64,160,0,192,64,64,64,224,3,7,7,6,1, + 0,160,0,192,64,64,64,224,5,7,7,6,0,0,192,48, + 112,136,136,136,112,5,8,8,6,0,0,40,80,0,176,200, + 136,136,136,5,8,8,6,0,0,64,32,0,112,136,136,136, + 112,5,8,8,6,0,0,16,32,0,112,136,136,136,112,5, + 8,8,6,0,0,32,80,0,112,136,136,136,112,5,8,8, + 6,0,0,40,80,0,112,136,136,136,112,5,7,7,6,0, + 0,80,0,112,136,136,136,112,5,5,5,6,0,1,32,0, + 248,0,32,5,5,5,6,0,0,120,152,168,200,240,5,8, + 8,6,0,0,64,32,0,136,136,136,152,104,5,8,8,6, + 0,0,16,32,0,136,136,136,152,104,5,8,8,6,0,0, + 32,80,0,136,136,136,152,104,5,7,7,6,0,0,80,0, + 136,136,136,152,104,5,9,9,6,0,254,16,32,136,136,152, + 104,8,136,112,5,8,8,6,0,254,128,240,136,136,136,240, + 128,128,5,9,9,6,0,254,80,0,136,136,152,104,8,136, + 112}; +/* + Fontname: -Misc-Fixed-Medium-R-SemiCondensed--12-110-75-75-C-60-ISO10646-1 + Copyright: Public domain terminal emulator font. Share and enjoy. + Capital A Height: 3, '1' Height: 8 + Calculated Max Values w= 6 h=12 x= 5 y= 8 dx= 6 dy= 0 ascent=10 len=12 + Font Bounding box w= 6 h=12 x= 0 y=-2 + Calculated Min Values x= 0 y=-2 dx= 0 dy= 0 + Pure Font ascent = 3 descent= 0 + X Font ascent = 8 descent= 0 + Max Font ascent =10 descent=-2 +*/ +const u8g_fntpgm_uint8_t u8g_font_6x12_67_75[2382] U8G_FONT_SECTION("u8g_font_6x12_67_75") = { + 1,6,12,0,254,3,2,41,3,99,0,255,0,10,254,8, + 0,2,87,103,168,0,136,0,136,0,168,2,87,103,240,136, + 232,168,232,136,240,2,87,103,112,168,248,168,248,168,112,2, + 87,103,112,136,8,8,8,136,112,18,69,101,96,144,16,144, + 96,1,88,104,112,136,128,128,136,120,8,8,2,87,103,32, + 32,32,32,168,112,32,2,103,103,248,252,252,156,252,252,248, + 2,87,103,112,248,248,168,248,248,112,255,255,255,255,255,255, + 255,3,85,101,32,64,248,64,32,2,87,103,32,112,168,32, + 32,32,32,3,85,101,32,16,248,16,32,2,87,103,32,32, + 32,32,168,112,32,4,83,99,80,248,80,2,87,103,32,112, + 168,32,168,112,32,2,89,105,192,240,224,160,32,16,16,8, + 8,2,89,105,24,120,56,40,32,64,64,128,128,2,89,105, + 128,128,64,64,32,40,56,120,24,2,89,105,8,8,16,16, + 32,160,224,240,192,3,101,101,40,72,252,80,48,3,101,101, + 48,40,252,72,80,4,99,99,192,216,100,4,99,99,12,108, + 152,3,101,101,40,80,252,80,40,2,88,104,32,112,168,112, + 168,32,32,32,3,101,101,80,40,252,40,80,2,88,104,32, + 32,32,168,112,168,112,32,3,101,101,36,72,240,72,36,3, + 101,101,144,72,60,72,144,3,85,101,40,72,248,72,40,2, + 87,103,32,112,168,32,32,32,248,3,85,101,160,144,248,144, + 160,2,87,103,248,32,32,32,168,112,32,2,87,103,32,112, + 168,32,168,112,248,3,101,101,40,68,248,64,32,3,101,101, + 80,136,124,8,16,3,101,101,32,76,252,72,40,3,101,101, + 16,200,252,72,80,3,100,100,72,220,236,72,3,101,101,8, + 88,252,104,64,2,87,103,128,144,176,208,144,56,16,2,88, + 104,32,64,248,72,40,8,8,8,2,88,104,32,16,248,144, + 160,128,128,128,2,88,104,8,8,8,40,72,248,64,32,2, + 87,103,128,128,160,144,248,16,32,3,84,100,240,16,56,16, + 3,85,101,8,8,72,248,64,3,85,101,48,72,72,232,72, + 3,85,101,96,144,144,184,16,2,88,104,248,128,224,192,160, + 32,16,16,2,89,105,160,192,248,192,168,24,248,24,40,2, + 86,102,56,48,168,136,136,112,2,86,102,224,96,168,136,136, + 112,5,83,99,32,64,248,3,83,99,248,64,32,34,56,104, + 128,192,160,128,128,128,128,128,2,56,104,32,96,160,32,32, + 32,32,32,5,83,99,32,16,248,3,83,99,248,16,32,34, + 56,104,128,128,128,128,128,160,192,128,2,56,104,32,32,32, + 32,32,160,96,32,2,89,105,32,16,248,16,32,64,248,64, + 32,2,88,104,80,240,80,80,80,80,120,80,2,89,105,32, + 64,248,64,32,16,248,16,32,2,89,105,32,64,248,64,32, + 64,248,64,32,2,88,104,80,248,80,80,80,80,80,80,2, + 89,105,32,16,248,16,32,16,248,16,32,2,88,104,80,80, + 80,80,80,80,248,80,2,87,103,32,64,248,0,248,16,32, + 2,87,103,32,16,248,0,248,64,32,2,103,103,20,40,124, + 144,124,32,80,2,103,103,8,88,252,164,252,104,64,2,103, + 103,160,80,248,36,248,16,40,3,85,101,32,120,128,120,32, + 2,87,103,32,80,216,80,80,80,80,3,85,101,32,240,8, + 240,32,2,87,103,80,80,80,80,216,80,32,3,101,101,72, + 252,132,252,72,2,88,104,32,80,216,80,80,216,80,32,2, + 102,102,248,160,208,168,148,8,2,102,102,124,20,44,84,164, + 64,2,102,102,64,164,84,44,20,124,2,102,102,8,148,168, + 208,160,248,2,103,103,16,60,64,252,64,60,16,2,103,103, + 32,240,8,252,8,240,32,3,100,100,64,232,212,64,3,100, + 100,8,92,172,8,2,88,104,32,112,168,32,112,32,112,32, + 2,88,104,32,112,32,112,32,168,112,32,3,101,101,32,64, + 212,64,32,2,88,104,32,112,136,32,0,32,0,32,3,101, + 101,16,8,172,8,16,2,88,104,32,0,32,0,32,136,112, + 32,3,85,101,160,192,248,192,160,3,85,101,40,24,248,24, + 40,3,85,101,32,120,136,120,32,2,88,104,32,80,216,80, + 80,80,80,112,3,85,101,32,240,136,240,32,2,88,104,112, + 80,80,80,80,216,80,32,2,89,105,32,80,216,80,112,0, + 112,80,112,2,89,105,32,80,216,80,80,80,216,136,248,2, + 89,105,32,80,248,136,80,80,216,136,248,2,89,105,32,112, + 248,112,112,112,248,168,248,2,89,105,32,80,216,80,216,80, + 80,80,112,2,89,105,32,80,216,80,216,80,216,136,248,3, + 85,101,160,240,136,240,160,2,88,104,248,128,176,160,144,16, + 8,8,2,88,104,128,128,64,72,40,104,8,248,2,88,104, + 32,80,216,80,80,216,80,32,3,101,101,16,104,252,104,16, + 2,88,104,80,120,80,80,80,80,240,80,2,89,105,16,248, + 16,16,248,16,16,248,16,3,101,101,40,72,252,72,40,3, + 101,101,80,72,252,72,80,3,101,101,48,120,252,120,48,3, + 101,101,56,88,252,88,56,3,101,101,112,104,252,104,112,3, + 101,101,48,120,252,120,48,3,85,101,32,96,184,96,32,3, + 85,101,32,48,232,48,32,3,101,101,48,120,180,120,48,6, + 102,102,252,252,252,252,252,252,0,98,98,252,252,0,99,99, + 252,252,252,0,101,101,252,252,252,252,252,0,102,102,252,252, + 252,252,252,252,0,104,104,252,252,252,252,252,252,252,252,0, + 105,105,252,252,252,252,252,252,252,252,252,0,107,107,252,252, + 252,252,252,252,252,252,252,252,252,0,108,108,252,252,252,252, + 252,252,252,252,252,252,252,252,0,92,108,248,248,248,248,248, + 248,248,248,248,248,248,248,0,76,108,240,240,240,240,240,240, + 240,240,240,240,240,240,0,76,108,240,240,240,240,240,240,240, + 240,240,240,240,240,0,60,108,224,224,224,224,224,224,224,224, + 224,224,224,224,0,44,108,192,192,192,192,192,192,192,192,192, + 192,192,192,0,44,108,192,192,192,192,192,192,192,192,192,192, + 192,192,0,28,108,128,128,128,128,128,128,128,128,128,128,128, + 128,48,60,108,224,224,224,224,224,224,224,224,224,224,224,224, + 1,107,107,168,0,84,0,168,0,84,0,168,0,84,0,108, + 108,168,84,168,84,168,84,168,84,168,84,168,84,0,108,108, + 84,252,168,252,84,252,168,252,84,252,168,252,10,98,98,252, + 252,80,28,108,128,128,128,128,128,128,128,128,128,128,128,128, + 0,54,102,224,224,224,224,224,224,48,54,102,224,224,224,224, + 224,224,6,54,102,224,224,224,224,224,224,0,108,108,224,224, + 224,224,224,224,252,252,252,252,252,252,0,108,108,224,224,224, + 224,224,224,28,28,28,28,28,28,0,108,108,252,252,252,252, + 252,252,224,224,224,224,224,224,0,108,108,252,252,252,252,252, + 252,28,28,28,28,28,28,54,54,102,224,224,224,224,224,224, + 0,108,108,28,28,28,28,28,28,224,224,224,224,224,224,0, + 108,108,28,28,28,28,28,28,252,252,252,252,252,252,2,85, + 101,248,248,248,248,248,2,85,101,248,136,136,136,248,2,85, + 101,112,136,136,136,112,2,85,101,248,136,168,136,248,2,85, + 101,248,136,248,136,248,2,85,101,248,168,168,168,248,2,85, + 101,248,168,248,168,248,2,85,101,248,200,168,152,248,2,85, + 101,248,152,168,200,248,2,85,101,248,216,168,216,248,20,51, + 99,224,224,224,20,51,99,224,160,224,3,101,101,252,252,252, + 252,252,3,101,101,252,132,132,132,252,17,74,106,240,240,240, + 240,240,240,240,240,240,240,17,74,106,240,144,144,144,144,144, + 144,144,144,240,4,99,99,60,120,240,4,99,99,60,72,240, + 2,87,103,32,32,112,112,248,248,248,2,87,103,32,32,80, + 80,136,136,248,3,85,101,32,32,112,112,248,3,85,101,32, + 32,80,80,248,18,71,103,128,192,224,240,224,192,128,18,71, + 103,128,192,160,144,160,192,128,19,53,101,128,192,224,192,128, + 19,53,101,128,192,160,192,128,3,101,101,192,240,252,240,192, + 3,101,101,192,176,140,176,192,2,87,103,248,248,248,112,112, + 32,32,2,87,103,248,136,136,80,80,32,32,2,85,101,248, + 112,112,32,32,2,85,101,248,80,80,32,32,18,71,103,16, + 48,112,240,112,48,16,18,71,103,16,48,80,144,80,48,16, + 19,53,101,32,96,224,96,32,19,53,101,32,96,160,96,32, + 3,101,101,12,60,252,60,12,3,101,101,12,52,196,52,12, + 3,85,101,32,112,248,112,32,3,85,101,32,80,136,80,32, + 3,85,101,32,80,168,80,32,2,102,102,48,72,180,180,72, + 48,2,87,103,32,80,80,136,80,80,32,2,102,102,48,72, + 132,132,72,48,2,102,102,32,8,128,4,64,16,2,85,101, + 112,168,168,168,112,2,87,103,112,136,168,216,168,136,112,2, + 102,102,48,120,252,252,120,48,2,102,102,48,104,228,228,104, + 48,2,102,102,48,88,156,156,88,48,2,102,102,48,72,132, + 252,120,48,2,102,102,48,120,252,132,72,48,2,102,102,48, + 88,156,132,72,48,2,102,102,48,104,228,132,72,48,18,89, + 105,8,56,120,120,248,120,120,56,8,2,89,105,128,224,240, + 240,248,240,240,224,128,0,108,108,252,252,252,252,204,132,132, + 204,252,252,252,252,0,108,108,252,252,252,204,180,120,120,180, + 204,252,252,252,6,102,102,252,252,252,204,180,120,0,102,102, + 120,180,204,252,252,252,5,51,99,32,64,128,53,51,99,128, + 64,32,50,51,99,32,64,128,2,51,99,128,64,32,5,99, + 99,48,72,132,2,99,99,132,72,48,2,85,101,8,24,56, + 120,248,2,85,101,128,192,224,240,248,2,85,101,248,240,224, + 192,128,2,85,101,248,120,56,24,8,2,85,101,112,136,136, + 136,112,2,85,101,248,232,232,232,248,2,85,101,248,184,184, + 184,248,2,85,101,248,248,232,200,248,2,85,101,248,152,184, + 248,248,2,85,101,248,168,168,168,248,2,87,103,32,32,80, + 112,168,136,248,2,87,103,32,32,112,112,232,232,248,2,87, + 103,32,32,112,112,184,184,248,2,103,103,48,72,132,132,132, + 72,48,2,85,101,248,168,232,136,248,2,85,101,248,136,232, + 168,248,2,85,101,248,136,184,168,248,2,85,101,248,168,184, + 136,248,2,85,101,112,168,232,136,112,2,85,101,112,136,232, + 168,112,2,85,101,112,136,184,168,112,2,85,101,112,168,184, + 136,112,3,85,101,248,144,160,192,128,3,85,101,248,72,40, + 24,8,3,85,101,128,192,160,144,248,20,68,100,240,144,144, + 240,19,68,100,240,240,240,240,20,68,100,240,144,144,240,20, + 68,100,240,240,240,240,3,85,101,8,24,40,72,248}; +// ======== u8g_dev_st7920_128x64.c ============== + +/* + + u8g_dev_st7920_128x64.c + + 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. + + +*/ + + +#define WIDTH 128 +#define HEIGHT 64 +#define PAGE_HEIGHT 8 + + +/* init sequence from https://github.com/adafruit/ST7565-LCD/blob/master/ST7565/ST7565.cpp */ +static const uint8_t u8g_dev_st7920_128x64_init_seq[] PROGMEM = { + U8G_ESC_CS(0), /* disable chip */ + U8G_ESC_ADR(0), /* instruction mode */ + U8G_ESC_RST(15), /* do reset low pulse with (15*16)+2 milliseconds (=maximum delay)*/ + U8G_ESC_DLY(100), /* 8 Dez 2012: additional delay 100 ms because of reset*/ + U8G_ESC_CS(1), /* enable chip */ + U8G_ESC_DLY(50), /* delay 50 ms */ + + 0x038, /* 8 Bit interface (DL=1), basic instruction set (RE=0) */ + 0x00c, /* display on, cursor & blink off; 0x08: all off */ + 0x006, /* Entry mode: Cursor move to right ,DDRAM address counter (AC) plus 1, no shift */ + 0x002, /* disable scroll, enable CGRAM adress */ + 0x001, /* clear RAM, needs 1.6 ms */ + U8G_ESC_DLY(100), /* delay 100 ms */ + + U8G_ESC_CS(0), /* disable chip */ + U8G_ESC_END /* end of sequence */ +}; + +uint8_t u8g_dev_st7920_128x64_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg) +{ + switch(msg) + { + case U8G_DEV_MSG_INIT: + u8g_InitCom(u8g, dev, U8G_SPI_CLK_CYCLE_400NS); + u8g_WriteEscSeqP(u8g, dev, u8g_dev_st7920_128x64_init_seq); + break; + case U8G_DEV_MSG_STOP: + break; + case U8G_DEV_MSG_PAGE_NEXT: + { + uint8_t y, i; + uint8_t *ptr; + u8g_pb_t *pb = (u8g_pb_t *)(dev->dev_mem); + + u8g_SetAddress(u8g, dev, 0); /* cmd mode */ + u8g_SetChipSelect(u8g, dev, 1); + y = pb->p.page_y0; + ptr = (uint8_t*)pb->buf; + for( i = 0; i < 8; i ++ ) + { + u8g_SetAddress(u8g, dev, 0); /* cmd mode */ + u8g_WriteByte(u8g, dev, 0x03e ); /* enable extended mode */ + + if ( y < 32 ) + { + u8g_WriteByte(u8g, dev, 0x080 | y ); /* y pos */ + u8g_WriteByte(u8g, dev, 0x080 ); /* set x pos to 0*/ + } + else + { + u8g_WriteByte(u8g, dev, 0x080 | (y-32) ); /* y pos */ + u8g_WriteByte(u8g, dev, 0x080 | 8); /* set x pos to 64*/ + } + + u8g_SetAddress(u8g, dev, 1); /* data mode */ + u8g_WriteSequence(u8g, dev, WIDTH/8, ptr); + ptr += WIDTH/8; + y++; + } + u8g_SetChipSelect(u8g, dev, 0); + } + break; + } + return u8g_dev_pb8h1_base_fn(u8g, dev, msg, arg); +} + +uint8_t u8g_dev_st7920_128x64_4x_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg) +{ + switch(msg) + { + case U8G_DEV_MSG_INIT: + u8g_InitCom(u8g, dev, U8G_SPI_CLK_CYCLE_400NS); + u8g_WriteEscSeqP(u8g, dev, u8g_dev_st7920_128x64_init_seq); + break; + case U8G_DEV_MSG_STOP: + break; + case U8G_DEV_MSG_PAGE_NEXT: + { + uint8_t y, i; + uint8_t *ptr; + u8g_pb_t *pb = (u8g_pb_t *)(dev->dev_mem); + + u8g_SetAddress(u8g, dev, 0); /* cmd mode */ + u8g_SetChipSelect(u8g, dev, 1); + y = pb->p.page_y0; + ptr = (uint8_t*)pb->buf; + for( i = 0; i < 32; i ++ ) + { + u8g_SetAddress(u8g, dev, 0); /* cmd mode */ + u8g_WriteByte(u8g, dev, 0x03e ); /* enable extended mode */ + + if ( y < 32 ) + { + u8g_WriteByte(u8g, dev, 0x080 | y ); /* y pos */ + u8g_WriteByte(u8g, dev, 0x080 ); /* set x pos to 0*/ + } + else + { + u8g_WriteByte(u8g, dev, 0x080 | (y-32) ); /* y pos */ + u8g_WriteByte(u8g, dev, 0x080 | 8); /* set x pos to 64*/ + } + + u8g_SetAddress(u8g, dev, 1); /* data mode */ + u8g_WriteSequence(u8g, dev, WIDTH/8, ptr); + ptr += WIDTH/8; + y++; + } + u8g_SetChipSelect(u8g, dev, 0); + } + break; + } + return u8g_dev_pb32h1_base_fn(u8g, dev, msg, arg); +} + +U8G_PB_DEV(u8g_dev_st7920_128x64_sw_spi, WIDTH, HEIGHT, PAGE_HEIGHT, u8g_dev_st7920_128x64_fn, U8G_COM_ST7920_SW_SPI); +U8G_PB_DEV(u8g_dev_st7920_128x64_hw_spi, WIDTH, HEIGHT, PAGE_HEIGHT, u8g_dev_st7920_128x64_fn, U8G_COM_ST7920_HW_SPI); +U8G_PB_DEV(u8g_dev_st7920_128x64_8bit, WIDTH, HEIGHT, PAGE_HEIGHT, u8g_dev_st7920_128x64_fn, U8G_COM_FAST_PARALLEL); +U8G_PB_DEV(u8g_dev_st7920_128x64_custom, WIDTH, HEIGHT, PAGE_HEIGHT, u8g_dev_st7920_128x64_fn, u8g_com_arduino_st7920_custom_fn); + + + +#define QWIDTH (WIDTH*4) +uint8_t u8g_dev_st7920_128x64_4x_buf[QWIDTH] U8G_NOCOMMON ; +u8g_pb_t u8g_dev_st7920_128x64_4x_pb = { {32, HEIGHT, 0, 0, 0}, WIDTH, u8g_dev_st7920_128x64_4x_buf}; +u8g_dev_t u8g_dev_st7920_128x64_4x_sw_spi = { u8g_dev_st7920_128x64_4x_fn, &u8g_dev_st7920_128x64_4x_pb, U8G_COM_ST7920_SW_SPI }; +u8g_dev_t u8g_dev_st7920_128x64_4x_hw_spi = { u8g_dev_st7920_128x64_4x_fn, &u8g_dev_st7920_128x64_4x_pb, U8G_COM_ST7920_HW_SPI }; +u8g_dev_t u8g_dev_st7920_128x64_4x_8bit = { u8g_dev_st7920_128x64_4x_fn, &u8g_dev_st7920_128x64_4x_pb, U8G_COM_FAST_PARALLEL }; +u8g_dev_t u8g_dev_st7920_128x64_4x_custom = { u8g_dev_st7920_128x64_4x_fn, &u8g_dev_st7920_128x64_4x_pb, u8g_com_arduino_st7920_custom_fn }; + +// ================ u8g_dev_ssd1306_128x64.c ========== + +/* + + u8g_dev_ssd1306_128x64.c + + 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. + + +*/ + +#define WIDTH 128 +#define HEIGHT 64 +#define PAGE_HEIGHT 8 + +/* init sequence adafruit 128x64 OLED (NOT TESTED) */ +static const uint8_t u8g_dev_ssd1306_128x64_adafruit1_init_seq[] PROGMEM = { + U8G_ESC_CS(0), /* disable chip */ + U8G_ESC_ADR(0), /* instruction mode */ + U8G_ESC_RST(1), /* do reset low pulse with (1*16)+2 milliseconds */ + U8G_ESC_CS(1), /* enable chip */ + + 0x0ae, /* display off, sleep mode */ + 0x0d5, 0x080, /* clock divide ratio (0x00=1) and oscillator frequency (0x8) */ + 0x0a8, 0x03f, /* */ + + 0x0d3, 0x000, /* */ + + 0x040, /* start line */ + + 0x08d, 0x010, /* [1] charge pump setting (p62): 0x014 enable, 0x010 disable */ + + 0x020, 0x000, /* */ + 0x0a1, /* segment remap a0/a1*/ + 0x0c8, /* c0: scan dir normal, c8: reverse */ + 0x0da, 0x012, /* com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5) */ + 0x081, 0x09f, /* [1] set contrast control */ + 0x0d9, 0x022, /* [1] pre-charge period 0x022/f1*/ + 0x0db, 0x040, /* vcomh deselect level */ + + 0x02e, /* 2012-05-27: Deactivate scroll */ + 0x0a4, /* output ram to display */ + 0x0a6, /* none inverted normal display mode */ + 0x0af, /* display on */ + + U8G_ESC_CS(0), /* disable chip */ + U8G_ESC_END /* end of sequence */ +}; + +/* init sequence adafruit 128x64 OLED (NOT TESTED) */ +static const uint8_t u8g_dev_ssd1306_128x64_adafruit2_init_seq[] PROGMEM = { + U8G_ESC_CS(0), /* disable chip */ + U8G_ESC_ADR(0), /* instruction mode */ + U8G_ESC_RST(1), /* do reset low pulse with (1*16)+2 milliseconds */ + U8G_ESC_CS(1), /* enable chip */ + + 0x0ae, /* display off, sleep mode */ + 0x0d5, 0x080, /* clock divide ratio (0x00=1) and oscillator frequency (0x8) */ + 0x0a8, 0x03f, /* */ + + 0x0d3, 0x000, /* */ + + 0x040, /* start line */ + + 0x08d, 0x014, /* [2] charge pump setting (p62): 0x014 enable, 0x010 disable */ + + 0x020, 0x000, /* */ + 0x0a1, /* segment remap a0/a1*/ + 0x0c8, /* c0: scan dir normal, c8: reverse */ + 0x0da, 0x012, /* com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5) */ + 0x081, 0x0cf, /* [2] set contrast control */ + 0x0d9, 0x0f1, /* [2] pre-charge period 0x022/f1*/ + 0x0db, 0x040, /* vcomh deselect level */ + + 0x02e, /* 2012-05-27: Deactivate scroll */ + 0x0a4, /* output ram to display */ + 0x0a6, /* none inverted normal display mode */ + 0x0af, /* display on */ + + U8G_ESC_CS(0), /* disable chip */ + U8G_ESC_END /* end of sequence */ +}; + +/* init sequence adafruit 128x64 OLED (NOT TESTED), like adafruit3, but with page addressing mode */ +static const uint8_t u8g_dev_ssd1306_128x64_adafruit3_init_seq[] PROGMEM = { + U8G_ESC_CS(0), /* disable chip */ + U8G_ESC_ADR(0), /* instruction mode */ + U8G_ESC_RST(1), /* do reset low pulse with (1*16)+2 milliseconds */ + U8G_ESC_CS(1), /* enable chip */ + + 0x0ae, /* display off, sleep mode */ + 0x0d5, 0x080, /* clock divide ratio (0x00=1) and oscillator frequency (0x8) */ + 0x0a8, 0x03f, /* */ + + 0x0d3, 0x000, /* */ + + 0x040, /* start line */ + + 0x08d, 0x014, /* [2] charge pump setting (p62): 0x014 enable, 0x010 disable */ + + 0x020, 0x002, /* 2012-05-27: page addressing mode */ + 0x0a1, /* segment remap a0/a1*/ + 0x0c8, /* c0: scan dir normal, c8: reverse */ + 0x0da, 0x012, /* com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5) */ + 0x081, 0x0cf, /* [2] set contrast control */ + 0x0d9, 0x0f1, /* [2] pre-charge period 0x022/f1*/ + 0x0db, 0x040, /* vcomh deselect level */ + + 0x02e, /* 2012-05-27: Deactivate scroll */ + 0x0a4, /* output ram to display */ + 0x0a6, /* none inverted normal display mode */ + 0x0af, /* display on */ + + U8G_ESC_CS(0), /* disable chip */ + U8G_ESC_END /* end of sequence */ +}; + +/* init sequence Univision datasheet (NOT TESTED) */ +static const uint8_t u8g_dev_ssd1306_128x64_univision_init_seq[] PROGMEM = { + U8G_ESC_CS(0), /* disable chip */ + U8G_ESC_ADR(0), /* instruction mode */ + U8G_ESC_RST(1), /* do reset low pulse with (1*16)+2 milliseconds */ + U8G_ESC_CS(1), /* enable chip */ + + 0x0ae, /* display off, sleep mode */ + 0x0d5, 0x080, /* clock divide ratio (0x00=1) and oscillator frequency (0x8) */ + 0x0a8, 0x03f, /* multiplex ratio */ + 0x0d3, 0x000, /* display offset */ + 0x040, /* start line */ + 0x08d, 0x010, /* charge pump setting (p62): 0x014 enable, 0x010 disable */ + 0x0a1, /* segment remap a0/a1*/ + 0x0c8, /* c0: scan dir normal, c8: reverse */ + 0x0da, 0x012, /* com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5) */ + 0x081, 0x09f, /* set contrast control */ + 0x0d9, 0x022, /* pre-charge period */ + 0x0db, 0x040, /* vcomh deselect level */ + 0x022, 0x000, /* page addressing mode WRONG: 3 byte cmd! */ + 0x0a4, /* output ram to display */ + 0x0a6, /* none inverted normal display mode */ + 0x0af, /* display on */ + U8G_ESC_CS(0), /* disable chip */ + U8G_ESC_END /* end of sequence */ +}; + +/* select one init sequence here */ +//#define u8g_dev_ssd1306_128x64_init_seq u8g_dev_ssd1306_128x64_univision_init_seq +//#define u8g_dev_ssd1306_128x64_init_seq u8g_dev_ssd1306_128x64_adafruit1_init_seq +// 26. Apr 2014: in this thead: http://forum.arduino.cc/index.php?topic=234930.msg1696754;topicseen#msg1696754 +// it is mentiond, that adafruit2_init_seq works better --> this will be used by the ssd1306_adafruit device +//#define u8g_dev_ssd1306_128x64_init_seq u8g_dev_ssd1306_128x64_adafruit2_init_seq + +#define u8g_dev_ssd1306_128x64_init_seq u8g_dev_ssd1306_128x64_adafruit3_init_seq + + +static const uint8_t u8g_dev_ssd1306_128x64_data_start[] PROGMEM = { + U8G_ESC_ADR(0), /* instruction mode */ + U8G_ESC_CS(1), /* enable chip */ + 0x010, /* set upper 4 bit of the col adr to 0 */ + 0x000, /* set lower 4 bit of the col adr to 0 */ + U8G_ESC_END /* end of sequence */ +}; + +/* the sh1106 is compatible to the ssd1306, but is 132x64. display seems to be centered */ +static const uint8_t u8g_dev_sh1106_128x64_data_start[] PROGMEM = { + U8G_ESC_ADR(0), /* instruction mode */ + U8G_ESC_CS(1), /* enable chip */ + 0x010, /* set upper 4 bit of the col adr to 0 */ + 0x002, /* set lower 4 bit of the col adr to 2 (centered display with sh1106) */ + U8G_ESC_END /* end of sequence */ +}; + +static const uint8_t u8g_dev_ssd13xx_sleep_on[] PROGMEM = { + U8G_ESC_ADR(0), /* instruction mode */ + U8G_ESC_CS(1), /* enable chip */ + 0x0ae, /* display off */ + U8G_ESC_CS(0), /* disable chip, bugfix 12 nov 2014 */ + U8G_ESC_END /* end of sequence */ +}; + +static const uint8_t u8g_dev_ssd13xx_sleep_off[] PROGMEM = { + U8G_ESC_ADR(0), /* instruction mode */ + U8G_ESC_CS(1), /* enable chip */ + 0x0af, /* display on */ + U8G_ESC_DLY(50), /* delay 50 ms */ + U8G_ESC_CS(0), /* disable chip, bugfix 12 nov 2014 */ + U8G_ESC_END /* end of sequence */ +}; + +uint8_t u8g_dev_ssd1306_128x64_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg) +{ + switch(msg) + { + case U8G_DEV_MSG_INIT: + u8g_InitCom(u8g, dev, U8G_SPI_CLK_CYCLE_300NS); + u8g_WriteEscSeqP(u8g, dev, u8g_dev_ssd1306_128x64_adafruit2_init_seq); + break; + case U8G_DEV_MSG_STOP: + break; + case U8G_DEV_MSG_PAGE_NEXT: + { + u8g_pb_t *pb = (u8g_pb_t *)(dev->dev_mem); + u8g_WriteEscSeqP(u8g, dev, u8g_dev_ssd1306_128x64_data_start); + u8g_WriteByte(u8g, dev, 0x0b0 | pb->p.page); /* select current page (SSD1306) */ + u8g_SetAddress(u8g, dev, 1); /* data mode */ + if ( u8g_pb_WriteBuffer(pb, u8g, dev) == 0 ) + return 0; + u8g_SetChipSelect(u8g, dev, 0); + } + break; + case U8G_DEV_MSG_SLEEP_ON: + u8g_WriteEscSeqP(u8g, dev, u8g_dev_ssd13xx_sleep_on); + return 1; + case U8G_DEV_MSG_SLEEP_OFF: + u8g_WriteEscSeqP(u8g, dev, u8g_dev_ssd13xx_sleep_off); + return 1; + } + return u8g_dev_pb8v1_base_fn(u8g, dev, msg, arg); +} + +uint8_t u8g_dev_ssd1306_adafruit_128x64_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg) +{ + switch(msg) + { + case U8G_DEV_MSG_INIT: + u8g_InitCom(u8g, dev, U8G_SPI_CLK_CYCLE_300NS); + u8g_WriteEscSeqP(u8g, dev, u8g_dev_ssd1306_128x64_init_seq); + break; + case U8G_DEV_MSG_STOP: + break; + case U8G_DEV_MSG_PAGE_NEXT: + { + u8g_pb_t *pb = (u8g_pb_t *)(dev->dev_mem); + u8g_WriteEscSeqP(u8g, dev, u8g_dev_ssd1306_128x64_data_start); + u8g_WriteByte(u8g, dev, 0x0b0 | pb->p.page); /* select current page (SSD1306) */ + u8g_SetAddress(u8g, dev, 1); /* data mode */ + if ( u8g_pb_WriteBuffer(pb, u8g, dev) == 0 ) + return 0; + u8g_SetChipSelect(u8g, dev, 0); + } + break; + case U8G_DEV_MSG_SLEEP_ON: + u8g_WriteEscSeqP(u8g, dev, u8g_dev_ssd13xx_sleep_on); + return 1; + case U8G_DEV_MSG_SLEEP_OFF: + u8g_WriteEscSeqP(u8g, dev, u8g_dev_ssd13xx_sleep_off); + return 1; + } + return u8g_dev_pb8v1_base_fn(u8g, dev, msg, arg); +} + +uint8_t u8g_dev_sh1106_128x64_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg) +{ + switch(msg) + { + case U8G_DEV_MSG_INIT: + u8g_InitCom(u8g, dev, U8G_SPI_CLK_CYCLE_300NS); + u8g_WriteEscSeqP(u8g, dev, u8g_dev_ssd1306_128x64_init_seq); + break; + case U8G_DEV_MSG_STOP: + break; + case U8G_DEV_MSG_PAGE_NEXT: + { + u8g_pb_t *pb = (u8g_pb_t *)(dev->dev_mem); + u8g_WriteEscSeqP(u8g, dev, u8g_dev_sh1106_128x64_data_start); + u8g_WriteByte(u8g, dev, 0x0b0 | pb->p.page); /* select current page (SSD1306) */ + u8g_SetAddress(u8g, dev, 1); /* data mode */ + if ( u8g_pb_WriteBuffer(pb, u8g, dev) == 0 ) + return 0; + u8g_SetChipSelect(u8g, dev, 0); + } + break; + case U8G_DEV_MSG_SLEEP_ON: + u8g_WriteEscSeqP(u8g, dev, u8g_dev_ssd13xx_sleep_on); + return 1; + case U8G_DEV_MSG_SLEEP_OFF: + u8g_WriteEscSeqP(u8g, dev, u8g_dev_ssd13xx_sleep_off); + return 1; + } + return u8g_dev_pb8v1_base_fn(u8g, dev, msg, arg); +} + + +uint8_t u8g_dev_ssd1306_128x64_2x_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg) +{ + switch(msg) + { + case U8G_DEV_MSG_INIT: + u8g_InitCom(u8g, dev, U8G_SPI_CLK_CYCLE_300NS); + u8g_WriteEscSeqP(u8g, dev, u8g_dev_ssd1306_128x64_init_seq); + break; + case U8G_DEV_MSG_STOP: + break; + case U8G_DEV_MSG_PAGE_NEXT: + { + u8g_pb_t *pb = (u8g_pb_t *)(dev->dev_mem); + + u8g_WriteEscSeqP(u8g, dev, u8g_dev_ssd1306_128x64_data_start); + u8g_WriteByte(u8g, dev, 0x0b0 | (pb->p.page*2)); /* select current page (SSD1306) */ + u8g_SetAddress(u8g, dev, 1); /* data mode */ + u8g_WriteSequence(u8g, dev, pb->width, (uint8_t *)pb->buf); + u8g_SetChipSelect(u8g, dev, 0); + + u8g_WriteEscSeqP(u8g, dev, u8g_dev_ssd1306_128x64_data_start); + u8g_WriteByte(u8g, dev, 0x0b0 | (pb->p.page*2+1)); /* select current page (SSD1306) */ + u8g_SetAddress(u8g, dev, 1); /* data mode */ + u8g_WriteSequence(u8g, dev, pb->width, (uint8_t *)(pb->buf)+pb->width); + u8g_SetChipSelect(u8g, dev, 0); + } + break; + case U8G_DEV_MSG_SLEEP_ON: + u8g_WriteEscSeqP(u8g, dev, u8g_dev_ssd13xx_sleep_on); + return 1; + case U8G_DEV_MSG_SLEEP_OFF: + u8g_WriteEscSeqP(u8g, dev, u8g_dev_ssd13xx_sleep_off); + return 1; + } + return u8g_dev_pb16v1_base_fn(u8g, dev, msg, arg); +} + +uint8_t u8g_dev_sh1106_128x64_2x_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg) +{ + switch(msg) + { + case U8G_DEV_MSG_INIT: + u8g_InitCom(u8g, dev, U8G_SPI_CLK_CYCLE_300NS); + u8g_WriteEscSeqP(u8g, dev, u8g_dev_ssd1306_128x64_init_seq); + break; + case U8G_DEV_MSG_STOP: + break; + case U8G_DEV_MSG_PAGE_NEXT: + { + u8g_pb_t *pb = (u8g_pb_t *)(dev->dev_mem); + + u8g_WriteEscSeqP(u8g, dev, u8g_dev_sh1106_128x64_data_start); + u8g_WriteByte(u8g, dev, 0x0b0 | (pb->p.page*2)); /* select current page (SSD1306) */ + u8g_SetAddress(u8g, dev, 1); /* data mode */ + u8g_WriteSequence(u8g, dev, pb->width, (uint8_t *)pb->buf); + u8g_SetChipSelect(u8g, dev, 0); + + u8g_WriteEscSeqP(u8g, dev, u8g_dev_sh1106_128x64_data_start); + u8g_WriteByte(u8g, dev, 0x0b0 | (pb->p.page*2+1)); /* select current page (SSD1306) */ + u8g_SetAddress(u8g, dev, 1); /* data mode */ + u8g_WriteSequence(u8g, dev, pb->width, (uint8_t *)(pb->buf)+pb->width); + u8g_SetChipSelect(u8g, dev, 0); + } + break; + case U8G_DEV_MSG_SLEEP_ON: + u8g_WriteEscSeqP(u8g, dev, u8g_dev_ssd13xx_sleep_on); + return 1; + case U8G_DEV_MSG_SLEEP_OFF: + u8g_WriteEscSeqP(u8g, dev, u8g_dev_ssd13xx_sleep_off); + return 1; + } + return u8g_dev_pb16v1_base_fn(u8g, dev, msg, arg); +} + + + + +U8G_PB_DEV(u8g_dev_ssd1306_128x64_sw_spi, WIDTH, HEIGHT, PAGE_HEIGHT, u8g_dev_ssd1306_128x64_fn, U8G_COM_SW_SPI); +U8G_PB_DEV(u8g_dev_ssd1306_128x64_hw_spi, WIDTH, HEIGHT, PAGE_HEIGHT, u8g_dev_ssd1306_128x64_fn, U8G_COM_HW_SPI); +U8G_PB_DEV(u8g_dev_ssd1306_128x64_i2c, WIDTH, HEIGHT, PAGE_HEIGHT, u8g_dev_ssd1306_128x64_fn, U8G_COM_SSD_I2C); + +U8G_PB_DEV(u8g_dev_ssd1306_adafruit_128x64_sw_spi, WIDTH, HEIGHT, PAGE_HEIGHT, u8g_dev_ssd1306_adafruit_128x64_fn, U8G_COM_SW_SPI); +U8G_PB_DEV(u8g_dev_ssd1306_adafruit_128x64_hw_spi, WIDTH, HEIGHT, PAGE_HEIGHT, u8g_dev_ssd1306_adafruit_128x64_fn, U8G_COM_HW_SPI); +U8G_PB_DEV(u8g_dev_ssd1306_adafruit_128x64_i2c, WIDTH, HEIGHT, PAGE_HEIGHT, u8g_dev_ssd1306_adafruit_128x64_fn, U8G_COM_SSD_I2C); + + +uint8_t u8g_dev_ssd1306_128x64_2x_buf[WIDTH*2] U8G_NOCOMMON ; +u8g_pb_t u8g_dev_ssd1306_128x64_2x_pb = { {16, HEIGHT, 0, 0, 0}, WIDTH, u8g_dev_ssd1306_128x64_2x_buf}; +u8g_dev_t u8g_dev_ssd1306_128x64_2x_sw_spi = { u8g_dev_ssd1306_128x64_2x_fn, &u8g_dev_ssd1306_128x64_2x_pb, U8G_COM_SW_SPI }; +u8g_dev_t u8g_dev_ssd1306_128x64_2x_hw_spi = { u8g_dev_ssd1306_128x64_2x_fn, &u8g_dev_ssd1306_128x64_2x_pb, U8G_COM_HW_SPI }; +u8g_dev_t u8g_dev_ssd1306_128x64_2x_i2c = { u8g_dev_ssd1306_128x64_2x_fn, &u8g_dev_ssd1306_128x64_2x_pb, U8G_COM_SSD_I2C }; + + +U8G_PB_DEV(u8g_dev_sh1106_128x64_sw_spi, WIDTH, HEIGHT, PAGE_HEIGHT, u8g_dev_sh1106_128x64_fn, U8G_COM_SW_SPI); +U8G_PB_DEV(u8g_dev_sh1106_128x64_hw_spi, WIDTH, HEIGHT, PAGE_HEIGHT, u8g_dev_sh1106_128x64_fn, U8G_COM_HW_SPI); +U8G_PB_DEV(u8g_dev_sh1106_128x64_i2c, WIDTH, HEIGHT, PAGE_HEIGHT, u8g_dev_sh1106_128x64_fn, U8G_COM_SSD_I2C); + +uint8_t u8g_dev_sh1106_128x64_2x_buf[WIDTH*2] U8G_NOCOMMON ; +u8g_pb_t u8g_dev_sh1106_128x64_2x_pb = { {16, HEIGHT, 0, 0, 0}, WIDTH, u8g_dev_sh1106_128x64_2x_buf}; +u8g_dev_t u8g_dev_sh1106_128x64_2x_sw_spi = { u8g_dev_sh1106_128x64_2x_fn, &u8g_dev_sh1106_128x64_2x_pb, U8G_COM_SW_SPI }; +u8g_dev_t u8g_dev_sh1106_128x64_2x_hw_spi = { u8g_dev_sh1106_128x64_2x_fn, &u8g_dev_sh1106_128x64_2x_pb, U8G_COM_HW_SPI }; +u8g_dev_t u8g_dev_sh1106_128x64_2x_i2c = { u8g_dev_sh1106_128x64_2x_fn, &u8g_dev_sh1106_128x64_2x_pb, U8G_COM_SSD_I2C }; + + +// ================ u8g_font.c =================== + +/* + + u8g_font.c + + U8G Font High Level Interface + + 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. + + +*/ + + +/* font api */ + +/* pointer to the start adress of the glyph, points to progmem area */ +typedef void * u8g_glyph_t; + +/* size of the font data structure, there is no struct or class... */ +#define U8G_FONT_DATA_STRUCT_SIZE 17 + +/* + ... instead the fields of the font data structure are accessed directly by offset + font information + offset + 0 font format + 1 FONTBOUNDINGBOX width unsigned + 2 FONTBOUNDINGBOX height unsigned + 3 FONTBOUNDINGBOX x-offset signed + 4 FONTBOUNDINGBOX y-offset signed + 5 capital A height unsigned + 6 start 'A' + 8 start 'a' + 10 encoding start + 11 encoding end + 12 descent 'g' negative: below baseline + 13 font max ascent + 14 font min decent negative: below baseline + 15 font xascent + 16 font xdecent negative: below baseline + +*/ + +/* use case: What is the width and the height of the minimal box into which string s fints? */ +void u8g_font_GetStrSize(const void *font, const char *s, u8g_uint_t *width, u8g_uint_t *height); +void u8g_font_GetStrSizeP(const void *font, const char *s, u8g_uint_t *width, u8g_uint_t *height); + +/* use case: lower left edge of a minimal box is known, what is the correct x, y position for the string draw procedure */ +void u8g_font_AdjustXYToDraw(const void *font, const char *s, u8g_uint_t *x, u8g_uint_t *y); +void u8g_font_AdjustXYToDrawP(const void *font, const char *s, u8g_uint_t *x, u8g_uint_t *y); + +/* use case: Baseline origin known, return minimal box */ +void u8g_font_GetStrMinBox(u8g_t *u8g, const void *font, const char *s, u8g_uint_t *x, u8g_uint_t *y, u8g_uint_t *width, u8g_uint_t *height); + +/* procedures */ + +/*========================================================================*/ +/* low level byte and word access */ + +/* removed NOINLINE, because it leads to smaller code, might also be faster */ +//static uint8_t u8g_font_get_byte(const u8g_fntpgm_uint8_t *font, uint8_t offset) U8G_NOINLINE; +static uint8_t u8g_font_get_byte(const u8g_fntpgm_uint8_t *font, uint8_t offset) +{ + font += offset; + return u8g_pgm_read( (u8g_pgm_uint8_t *)font ); +} + +static uint16_t u8g_font_get_word(const u8g_fntpgm_uint8_t *font, uint8_t offset) U8G_NOINLINE; +static uint16_t u8g_font_get_word(const u8g_fntpgm_uint8_t *font, uint8_t offset) +{ + uint16_t pos; + font += offset; + pos = u8g_pgm_read( (u8g_pgm_uint8_t *)font ); + font++; + pos <<= 8; + pos += u8g_pgm_read( (u8g_pgm_uint8_t *)font); + return pos; +} + +/*========================================================================*/ +/* direct access on the font */ + +static uint8_t u8g_font_GetFormat(const u8g_fntpgm_uint8_t *font) U8G_NOINLINE; +static uint8_t u8g_font_GetFormat(const u8g_fntpgm_uint8_t *font) +{ + return u8g_font_get_byte((const u8g_fntpgm_uint8_t*)font, 0); +} + +static uint8_t u8g_font_GetFontGlyphStructureSize(const u8g_fntpgm_uint8_t *font) U8G_NOINLINE; +static uint8_t u8g_font_GetFontGlyphStructureSize(const u8g_fntpgm_uint8_t *font) +{ + switch(u8g_font_GetFormat((const u8g_fntpgm_uint8_t*)font)) + { + case 0: return 6; + case 1: return 3; + case 2: return 6; + } + return 3; +} + +static uint8_t u8g_font_GetBBXWidth(const void *font) +{ + return u8g_font_get_byte((const u8g_fntpgm_uint8_t*)font, 1); +} + +static uint8_t u8g_font_GetBBXHeight(const void *font) +{ + return u8g_font_get_byte((const u8g_fntpgm_uint8_t*)font, 2); +} + +static int8_t u8g_font_GetBBXOffX(const void *font) +{ + return u8g_font_get_byte((const u8g_fntpgm_uint8_t*)font, 3); +} + +static int8_t u8g_font_GetBBXOffY(const void *font) +{ + return u8g_font_get_byte((const u8g_fntpgm_uint8_t*)font, 4); +} + +uint8_t u8g_font_GetCapitalAHeight(const void *font) +{ + return u8g_font_get_byte((const u8g_fntpgm_uint8_t*)font, 5); +} + +uint16_t u8g_font_GetEncoding65Pos(const void *font) U8G_NOINLINE; +uint16_t u8g_font_GetEncoding65Pos(const void *font) +{ + return u8g_font_get_word((const u8g_fntpgm_uint8_t*)font, 6); +} + +uint16_t u8g_font_GetEncoding97Pos(const void *font) U8G_NOINLINE; +uint16_t u8g_font_GetEncoding97Pos(const void *font) +{ + return u8g_font_get_word((const u8g_fntpgm_uint8_t*)font, 8); +} + +uint8_t u8g_font_GetFontStartEncoding(const void *font) +{ + return u8g_font_get_byte((const u8g_fntpgm_uint8_t*)font, 10); +} + +uint8_t u8g_font_GetFontEndEncoding(const void *font) +{ + return u8g_font_get_byte((const u8g_fntpgm_uint8_t*)font, 11); +} + +int8_t u8g_font_GetLowerGDescent(const void *font) +{ + return u8g_font_get_byte((const u8g_fntpgm_uint8_t*)font, 12); +} + +int8_t u8g_font_GetFontAscent(const void *font) +{ + return u8g_font_get_byte((const u8g_fntpgm_uint8_t*)font, 13); +} + +int8_t u8g_font_GetFontDescent(const void *font) +{ + return u8g_font_get_byte((const u8g_fntpgm_uint8_t*)font, 14); +} + +int8_t u8g_font_GetFontXAscent(const void *font) +{ + return u8g_font_get_byte((const u8g_fntpgm_uint8_t*)font, 15); +} + +int8_t u8g_font_GetFontXDescent(const void *font) +{ + return u8g_font_get_byte((const u8g_fntpgm_uint8_t*)font, 16); +} + + +/* return the data start for a font and the glyph pointer */ +static uint8_t *u8g_font_GetGlyphDataStart(const void *font, u8g_glyph_t g) +{ + return ((u8g_fntpgm_uint8_t *)g) + u8g_font_GetFontGlyphStructureSize((const u8g_fntpgm_uint8_t*)font); +} + +/* calculate the overall length of the font, only used to create the picture for the google wiki */ +size_t u8g_font_GetSize(const void *font) +{ + uint8_t *p = (uint8_t *)(font); + uint8_t font_format = u8g_font_GetFormat((const u8g_fntpgm_uint8_t*)font); + uint8_t data_structure_size = u8g_font_GetFontGlyphStructureSize((const u8g_fntpgm_uint8_t*)font); + uint8_t start, end; + uint8_t i; + uint8_t mask = 255; + + start = u8g_font_GetFontStartEncoding(font); + end = u8g_font_GetFontEndEncoding(font); + + if ( font_format == 1 ) + mask = 15; + + p += U8G_FONT_DATA_STRUCT_SIZE; /* skip font general information */ + + i = start; + for(;;) + { + if ( u8g_pgm_read((u8g_pgm_uint8_t *)(p)) == 255 ) + { + p += 1; + } + else + { + p += u8g_pgm_read( ((u8g_pgm_uint8_t *)(p)) + 2 ) & mask; + p += data_structure_size; + } + if ( i == end ) + break; + i++; + } + + return p - (uint8_t *)font; +} + +/*========================================================================*/ +/* u8g interface, font access */ + +uint8_t u8g_GetFontBBXWidth(u8g_t *u8g) +{ + return u8g_font_GetBBXWidth(u8g->font); +} + +uint8_t u8g_GetFontBBXHeight(u8g_t *u8g) +{ + return u8g_font_GetBBXHeight(u8g->font); +} + +int8_t u8g_GetFontBBXOffX(u8g_t *u8g) U8G_NOINLINE; +int8_t u8g_GetFontBBXOffX(u8g_t *u8g) +{ + return u8g_font_GetBBXOffX(u8g->font); +} + +int8_t u8g_GetFontBBXOffY(u8g_t *u8g) U8G_NOINLINE; +int8_t u8g_GetFontBBXOffY(u8g_t *u8g) +{ + return u8g_font_GetBBXOffY(u8g->font); +} + +uint8_t u8g_GetFontCapitalAHeight(u8g_t *u8g) U8G_NOINLINE; +uint8_t u8g_GetFontCapitalAHeight(u8g_t *u8g) +{ + return u8g_font_GetCapitalAHeight(u8g->font); +} + +/*========================================================================*/ +/* glyph handling */ + +static void u8g_CopyGlyphDataToCache(u8g_t *u8g, u8g_glyph_t g) +{ + uint8_t tmp; + switch( u8g_font_GetFormat(u8g->font) ) + { + case 0: + case 2: + /* + format 0 + glyph information + offset + 0 BBX width unsigned + 1 BBX height unsigned + 2 data size unsigned (BBX width + 7)/8 * BBX height + 3 DWIDTH signed + 4 BBX xoffset signed + 5 BBX yoffset signed + byte 0 == 255 indicates empty glyph + */ + u8g->glyph_width = u8g_pgm_read( ((u8g_pgm_uint8_t *)g) + 0 ); + u8g->glyph_height = u8g_pgm_read( ((u8g_pgm_uint8_t *)g) + 1 ); + u8g->glyph_dx = u8g_pgm_read( ((u8g_pgm_uint8_t *)g) + 3 ); + u8g->glyph_x = u8g_pgm_read( ((u8g_pgm_uint8_t *)g) + 4 ); + u8g->glyph_y = u8g_pgm_read( ((u8g_pgm_uint8_t *)g) + 5 ); + break; + case 1: + default: + /* +format 1 + 0 BBX xoffset signed --> upper 4 Bit + 0 BBX yoffset signed --> lower 4 Bit + 1 BBX width unsigned --> upper 4 Bit + 1 BBX height unsigned --> lower 4 Bit + 2 data size unsigned -(BBX width + 7)/8 * BBX height --> lower 4 Bit + 2 DWIDTH signed --> upper 4 Bit + byte 0 == 255 indicates empty glyph + */ + + tmp = u8g_pgm_read( ((u8g_pgm_uint8_t *)g) + 0 ); + u8g->glyph_y = tmp & 15; + u8g->glyph_y-=2; + tmp >>= 4; + u8g->glyph_x = tmp; + + tmp = u8g_pgm_read( ((u8g_pgm_uint8_t *)g) + 1 ); + u8g->glyph_height = tmp & 15; + tmp >>= 4; + u8g->glyph_width = tmp; + + tmp = u8g_pgm_read( ((u8g_pgm_uint8_t *)g) + 2 ); + tmp >>= 4; + u8g->glyph_dx = tmp; + + + break; + } +} + +//void u8g_FillEmptyGlyphCache(u8g_t *u8g) U8G_NOINLINE; +static void u8g_FillEmptyGlyphCache(u8g_t *u8g) +{ + u8g->glyph_dx = 0; + u8g->glyph_width = 0; + u8g->glyph_height = 0; + u8g->glyph_x = 0; + u8g->glyph_y = 0; +} + +/* + Find (with some speed optimization) and return a pointer to the glyph data structure + Also uncompress (format 1) and copy the content of the data structure to the u8g structure +*/ +u8g_glyph_t u8g_GetGlyph(u8g_t *u8g, uint8_t requested_encoding) +{ + uint8_t *p = (uint8_t *)(u8g->font); + uint8_t font_format = u8g_font_GetFormat(u8g->font); + uint8_t data_structure_size = u8g_font_GetFontGlyphStructureSize(u8g->font); + uint8_t start, end; + uint16_t pos; + uint8_t i; + uint8_t mask = 255; + + if ( font_format == 1 ) + mask = 15; + + start = u8g_font_GetFontStartEncoding(u8g->font); + end = u8g_font_GetFontEndEncoding(u8g->font); + + pos = u8g_font_GetEncoding97Pos(u8g->font); + if ( requested_encoding >= 97 && pos > 0 ) + { + p+= pos; + start = 97; + } + else + { + pos = u8g_font_GetEncoding65Pos(u8g->font); + if ( requested_encoding >= 65 && pos > 0 ) + { + p+= pos; + start = 65; + } + else + p += U8G_FONT_DATA_STRUCT_SIZE; /* skip font general information */ + } + + if ( requested_encoding > end ) + { + u8g_FillEmptyGlyphCache(u8g); + return NULL; /* not found */ + } + + i = start; + if ( i <= end ) + { + for(;;) + { + if ( u8g_pgm_read((u8g_pgm_uint8_t *)(p)) == 255 ) + { + p += 1; + } + else + { + if ( i == requested_encoding ) + { + u8g_CopyGlyphDataToCache(u8g, p); + return p; + } + p += u8g_pgm_read( ((u8g_pgm_uint8_t *)(p)) + 2 ) & mask; + p += data_structure_size; + } + if ( i == end ) + break; + i++; + } + } + + u8g_FillEmptyGlyphCache(u8g); + + return NULL; +} + +uint8_t u8g_IsGlyph(u8g_t *u8g, uint8_t requested_encoding) +{ + if ( u8g_GetGlyph(u8g, requested_encoding) != NULL ) + return 1; + return 0; +} + +int8_t u8g_GetGlyphDeltaX(u8g_t *u8g, uint8_t requested_encoding) +{ + if ( u8g_GetGlyph(u8g, requested_encoding) == NULL ) + return 0; /* should never happen, so return something */ + return u8g->glyph_dx; +} + + +/*========================================================================*/ +/* glyph drawing procedures */ + +#ifdef OBSOLETE +/* + Draw a glyph + x,y: left baseline position of the glyph +*/ +int8_t u8g_DrawGlyphDir(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, uint8_t dir, uint8_t encoding) +{ + u8g_glyph_t g; + uint8_t w, h, i, j; + const u8g_pgm_uint8_t *data; + uint8_t bytes_per_line; + u8g_uint_t ix, iy; + + g = u8g_GetGlyph(u8g, encoding); + if ( g == NULL ) + return 0; + w = u8g->glyph_width; + h = u8g->glyph_height; + + bytes_per_line = w; + bytes_per_line += 7; + bytes_per_line /= 8; + + data = u8g_font_GetGlyphDataStart(u8g->font, g); + + switch(dir) + { + case 0: + x += u8g->glyph_x; + y -= u8g->glyph_y; + y--; + //u8g_DrawFrame(u8g, x, y-h+1, w, h); + if ( u8g_IsBBXIntersection(u8g, x, y-h+1, w, h) == 0 ) + return u8g->glyph_dx; + + iy = y; + iy -= h; + iy++; + + for( j = 0; j < h; j++ ) + { + ix = x; + for( i = 0; i < bytes_per_line; i++ ) + { + u8g_Draw8Pixel(u8g, ix, iy, dir, u8g_pgm_read(data)); + data++; + ix+=8; + } + iy++; + } + break; + case 1: + x += u8g->glyph_y; + x++; + y += u8g->glyph_x; + //printf("enc %d, dir %d, x %d, y %d, w %d, h %d\n", encoding, dir, x, y, w, h); + //u8g_DrawFrame(u8g, x, y, h, w); + if ( u8g_IsBBXIntersection(u8g, x, y, h, w) == 0 ) + return u8g->glyph_dx; + + ix = x; + ix += h; + ix--; + for( j = 0; j < h; j++ ) + { + iy = y; + for( i = 0; i < bytes_per_line; i++ ) + { + u8g_Draw8Pixel(u8g, ix, iy, dir, u8g_pgm_read(data)); + data++; + iy+=8; + } + ix--; + } + break; + case 2: + x -= u8g->glyph_x; + y += u8g->glyph_y; + y++; + if ( u8g_IsBBXIntersection(u8g, x-w-1, y, w, h) == 0 ) + return u8g->glyph_dx; + + iy = y; + iy += h; + iy--; + for( j = 0; j < h; j++ ) + { + ix = x; + for( i = 0; i < bytes_per_line; i++ ) + { + u8g_Draw8Pixel(u8g, ix, iy, dir, u8g_pgm_read(data)); + data++; + ix-=8; + } + iy--; + } + break; + case 3: + x -= u8g->glyph_y; + x--; + y -= u8g->glyph_x; + + if ( u8g_IsBBXIntersection(u8g, x-h-1, y-w-1, h, w) == 0 ) + return u8g->glyph_dx; + + ix = x; + ix -= h; + ix++; + + for( j = 0; j < h; j++ ) + { + iy = y; + for( i = 0; i < bytes_per_line; i++ ) + { + u8g_Draw8Pixel(u8g, ix, iy, dir, u8g_pgm_read(data)); + data++; + iy-=8; + } + ix++; + } + break; + } + return u8g->glyph_dx; +} +#endif + +int8_t u8g_draw_glyph(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, uint8_t encoding) +{ + const u8g_pgm_uint8_t *data; + uint8_t w, h; + uint8_t i, j; + u8g_uint_t ix, iy; + + { + u8g_glyph_t g = u8g_GetGlyph(u8g, encoding); + if ( g == NULL ) + return 0; + data = u8g_font_GetGlyphDataStart(u8g->font, g); + } + + w = u8g->glyph_width; + h = u8g->glyph_height; + + x += u8g->glyph_x; + y -= u8g->glyph_y; + y--; + + if ( u8g_IsBBXIntersection(u8g, x, y-h+1, w, h) == 0 ) + return u8g->glyph_dx; + + /* now, w is reused as bytes per line */ + w += 7; + w /= 8; + + iy = y; + iy -= h; + iy++; + + for( j = 0; j < h; j++ ) + { + ix = x; + for( i = 0; i < w; i++ ) + { + u8g_Draw8Pixel(u8g, ix, iy, 0, u8g_pgm_read(data)); + data++; + ix+=8; + } + iy++; + } + return u8g->glyph_dx; +} + +int8_t u8g_DrawGlyph(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, uint8_t encoding) +{ + y += u8g->font_calc_vref(u8g); + return u8g_draw_glyph(u8g, x, y, encoding); +} + +int8_t u8g_draw_glyph90(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, uint8_t encoding) +{ + const u8g_pgm_uint8_t *data; + uint8_t w, h; + uint8_t i, j; + u8g_uint_t ix, iy; + + { + u8g_glyph_t g = u8g_GetGlyph(u8g, encoding); + if ( g == NULL ) + return 0; + data = u8g_font_GetGlyphDataStart(u8g->font, g); + } + + w = u8g->glyph_width; + h = u8g->glyph_height; + + x += u8g->glyph_y; + x++; + y += u8g->glyph_x; + + if ( u8g_IsBBXIntersection(u8g, x, y, h, w) == 0 ) + return u8g->glyph_dx; + + /* now, w is reused as bytes per line */ + w += 7; + w /= 8; + + ix = x; + ix += h; + ix--; + for( j = 0; j < h; j++ ) + { + iy = y; + for( i = 0; i < w; i++ ) + { + u8g_Draw8Pixel(u8g, ix, iy, 1, u8g_pgm_read(data)); + data++; + iy+=8; + } + ix--; + } + return u8g->glyph_dx; +} + +int8_t u8g_DrawGlyph90(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, uint8_t encoding) +{ + x -= u8g->font_calc_vref(u8g); + return u8g_draw_glyph90(u8g, x, y, encoding); +} + + +int8_t u8g_draw_glyph180(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, uint8_t encoding) +{ + const u8g_pgm_uint8_t *data; + uint8_t w, h; + uint8_t i, j; + u8g_uint_t ix, iy; + + { + u8g_glyph_t g = u8g_GetGlyph(u8g, encoding); + if ( g == NULL ) + return 0; + data = u8g_font_GetGlyphDataStart(u8g->font, g); + } + + w = u8g->glyph_width; + h = u8g->glyph_height; + + x -= u8g->glyph_x; + y += u8g->glyph_y; + y++; + + if ( u8g_IsBBXIntersection(u8g, x-(w-1), y, w, h) == 0 ) + return u8g->glyph_dx; + + /* now, w is reused as bytes per line */ + w += 7; + w /= 8; + + iy = y; + iy += h; + iy--; + for( j = 0; j < h; j++ ) + { + ix = x; + for( i = 0; i < w; i++ ) + { + u8g_Draw8Pixel(u8g, ix, iy, 2, u8g_pgm_read(data)); + data++; + ix-=8; + } + iy--; + } + return u8g->glyph_dx; +} + +int8_t u8g_DrawGlyph180(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, uint8_t encoding) +{ + y -= u8g->font_calc_vref(u8g); + return u8g_draw_glyph180(u8g, x, y, encoding); +} + + +int8_t u8g_draw_glyph270(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, uint8_t encoding) +{ + const u8g_pgm_uint8_t *data; + uint8_t w, h; + uint8_t i, j; + u8g_uint_t ix, iy; + + { + u8g_glyph_t g = u8g_GetGlyph(u8g, encoding); + if ( g == NULL ) + return 0; + data = u8g_font_GetGlyphDataStart(u8g->font, g); + } + + w = u8g->glyph_width; + h = u8g->glyph_height; + + x -= u8g->glyph_y; + x--; + y -= u8g->glyph_x; + + if ( u8g_IsBBXIntersection(u8g, x-(h-1), y-(w-1), h, w) == 0 ) + return u8g->glyph_dx; + + + /* now, w is reused as bytes per line */ + w += 7; + w /= 8; + + ix = x; + ix -= h; + ix++; + + for( j = 0; j < h; j++ ) + { + iy = y; + for( i = 0; i < w; i++ ) + { + u8g_Draw8Pixel(u8g, ix, iy, 3, u8g_pgm_read(data)); + data++; + iy-=8; + } + ix++; + } + return u8g->glyph_dx; +} + +int8_t u8g_DrawGlyph270(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, uint8_t encoding) +{ + x += u8g->font_calc_vref(u8g); + return u8g_draw_glyph270(u8g, x, y, encoding); +} + + + +#ifdef OBSOLETE +/* + Draw a glyph + x,y: lower left corner of the font bounding box +*/ +int8_t u8g_DrawGlyphFontBBX(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, uint8_t dir, uint8_t encoding) +{ + /* TODO: apply "dir" */ + x -= u8g_GetFontBBXOffX(u8g); + y += u8g_GetFontBBXOffY(u8g); + return u8g_DrawGlyphDir(u8g, x, y, dir, encoding); +} +#endif + +/*========================================================================*/ +/* string drawing procedures */ + + +u8g_uint_t u8g_DrawStr(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, const char *s) +{ + u8g_uint_t t = 0; + int8_t d; + + //u8g_uint_t u8g_GetStrWidth(u8g, s); + //u8g_font_GetFontAscent(u8g->font)-u8g_font_GetFontDescent(u8g->font); + + y += u8g->font_calc_vref(u8g); + + while( *s != '\0' ) + { + d = u8g_draw_glyph(u8g, x, y, *s); + x += d; + t += d; + s++; + } + return t; +} + +u8g_uint_t u8g_DrawStr90(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, const char *s) +{ + u8g_uint_t t = 0; + int8_t d; + + x -= u8g->font_calc_vref(u8g); + + while( *s != '\0' ) + { + d = u8g_draw_glyph90(u8g, x, y, *s); + y += d; + t += d; + s++; + } + return t; +} + +u8g_uint_t u8g_DrawStr180(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, const char *s) +{ + u8g_uint_t t = 0; + int8_t d; + + y -= u8g->font_calc_vref(u8g); + + while( *s != '\0' ) + { + d = u8g_draw_glyph180(u8g, x, y, *s); + x -= d; + t += d; + s++; + } + return t; +} + +u8g_uint_t u8g_DrawStr270(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, const char *s) +{ + u8g_uint_t t = 0; + int8_t d; + + x += u8g->font_calc_vref(u8g); + + while( *s != '\0' ) + { + d = u8g_draw_glyph270(u8g, x, y, *s); + y -= d; + t += d; + s++; + } + return t; +} + +u8g_uint_t u8g_DrawStrDir(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, uint8_t dir, const char *s) +{ + switch(dir) + { + case 0: + return u8g_DrawStr(u8g, x, y, s); + case 1: + return u8g_DrawStr90(u8g, x, y, s); + case 2: + return u8g_DrawStr180(u8g, x, y, s); + case 3: + return u8g_DrawStr270(u8g, x, y, s); + } + return 0; +} + +u8g_uint_t u8g_DrawStrP(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, const u8g_pgm_uint8_t *s) +{ + u8g_uint_t t = 0; + int8_t d; + uint8_t c; + + y += u8g->font_calc_vref(u8g); + + for(;;) + { + c = u8g_pgm_read(s); + if ( c == '\0' ) + break; + d = u8g_draw_glyph(u8g, x, y, c); + x += d; + t += d; + s++; + } + return t; +} + +u8g_uint_t u8g_DrawStr90P(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, const u8g_pgm_uint8_t *s) +{ + u8g_uint_t t = 0; + int8_t d; + + x -= u8g->font_calc_vref(u8g); + + while( *s != '\0' ) + { + d = u8g_DrawGlyph90(u8g, x, y, u8g_pgm_read(s)); + y += d; + t += d; + s++; + } + return t; +} + +u8g_uint_t u8g_DrawStr180P(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, const u8g_pgm_uint8_t *s) +{ + u8g_uint_t t = 0; + int8_t d; + + y -= u8g->font_calc_vref(u8g); + + while( *s != '\0' ) + { + d = u8g_DrawGlyph180(u8g, x, y, u8g_pgm_read(s)); + x -= d; + t += d; + s++; + } + return t; +} + +u8g_uint_t u8g_DrawStr270P(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, const u8g_pgm_uint8_t *s) +{ + u8g_uint_t t = 0; + int8_t d; + + x += u8g->font_calc_vref(u8g); + + while( *s != '\0' ) + { + d = u8g_DrawGlyph270(u8g, x, y, u8g_pgm_read(s)); + y -= d; + t += d; + s++; + } + return t; +} + +u8g_uint_t u8g_DrawStrFontBBX(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, uint8_t dir, const char *s) +{ + x -= u8g_GetFontBBXOffX(u8g); + y += u8g_GetFontBBXOffY(u8g); + return u8g_DrawStrDir(u8g, x, y, dir, s); +} + +/* still used by picgen.c, dir argument is ignored */ +int8_t u8g_DrawGlyphFontBBX(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, uint8_t dir, uint8_t encoding) +{ + x -= u8g_GetFontBBXOffX(u8g); + y += u8g_GetFontBBXOffY(u8g); + u8g_draw_glyph(u8g, x, y, encoding); + return 0; +} + + +/*========================================================================*/ +/* set ascent/descent for reference point calculation */ + +void u8g_UpdateRefHeight(u8g_t *u8g) +{ + uint16_t ls; + if ( u8g->font == NULL ) + return; + if ( u8g->font_height_mode == U8G_FONT_HEIGHT_MODE_TEXT ) + { + u8g->font_ref_ascent = u8g_font_GetCapitalAHeight(u8g->font); + u8g->font_ref_descent = u8g_font_GetLowerGDescent(u8g->font); + } + else if ( u8g->font_height_mode == U8G_FONT_HEIGHT_MODE_XTEXT ) + { + u8g->font_ref_ascent = u8g_font_GetFontXAscent(u8g->font); + u8g->font_ref_descent = u8g_font_GetFontXDescent(u8g->font); + } + else + { + u8g->font_ref_ascent = u8g_font_GetFontAscent(u8g->font); + u8g->font_ref_descent = u8g_font_GetFontDescent(u8g->font); + } + + ls = u8g->font_ref_ascent - u8g->font_ref_descent; + if ( u8g->font_line_spacing_factor != 64 ) + { + ls &= 255; + ls *= u8g->font_line_spacing_factor; + ls >>= 6; + } + u8g->line_spacing = ls; +} + +void u8g_SetFontRefHeightText(u8g_t *u8g) +{ + u8g->font_height_mode = U8G_FONT_HEIGHT_MODE_TEXT; + u8g_UpdateRefHeight(u8g); +} + +void u8g_SetFontRefHeightExtendedText(u8g_t *u8g) +{ + u8g->font_height_mode = U8G_FONT_HEIGHT_MODE_XTEXT; + u8g_UpdateRefHeight(u8g); +} + + +void u8g_SetFontRefHeightAll(u8g_t *u8g) +{ + u8g->font_height_mode = U8G_FONT_HEIGHT_MODE_ALL; + u8g_UpdateRefHeight(u8g); +} + +/* factor = 64: linespaceing == ascent and descent */ +void u8g_SetFontLineSpacingFactor(u8g_t *u8g, uint8_t factor) +{ + u8g->font_line_spacing_factor = factor; + u8g_UpdateRefHeight(u8g); +} + + + +/*========================================================================*/ +/* callback procedures to correct the y position */ + +u8g_uint_t u8g_font_calc_vref_font(u8g_t *u8g) +{ + return 0; +} + +void u8g_SetFontPosBaseline(u8g_t *u8g) +{ + u8g->font_calc_vref = u8g_font_calc_vref_font; +} + + +u8g_uint_t u8g_font_calc_vref_bottom(u8g_t *u8g) +{ + /* y += (u8g_uint_t)(u8g_int_t)(u8g->font_ref_descent); */ + return (u8g_uint_t)(u8g_int_t)(u8g->font_ref_descent); +} + +void u8g_SetFontPosBottom(u8g_t *u8g) +{ + u8g->font_calc_vref = u8g_font_calc_vref_bottom; +} + +u8g_uint_t u8g_font_calc_vref_top(u8g_t *u8g) +{ + u8g_uint_t tmp; + /* reference pos is one pixel above the upper edge of the reference glyph */ + + /* + y += (u8g_uint_t)(u8g_int_t)(u8g->font_ref_ascent); + y++; + */ + tmp = (u8g_uint_t)(u8g_int_t)(u8g->font_ref_ascent); + tmp++; + return tmp; +} + +void u8g_SetFontPosTop(u8g_t *u8g) +{ + u8g->font_calc_vref = u8g_font_calc_vref_top; +} + +u8g_uint_t u8g_font_calc_vref_center(u8g_t *u8g) +{ + int8_t tmp; + tmp = u8g->font_ref_ascent; + tmp -= u8g->font_ref_descent; + tmp /= 2; + tmp += u8g->font_ref_descent; + /* y += (u8g_uint_t)(u8g_int_t)(tmp); */ + return tmp; +} + +void u8g_SetFontPosCenter(u8g_t *u8g) +{ + u8g->font_calc_vref = u8g_font_calc_vref_center; +} + +/*========================================================================*/ +/* string pixel width calculation */ + +char u8g_font_get_char(const void *s) +{ + return *(const char *)(s); +} + +char u8g_font_get_charP(const void *s) +{ + return u8g_pgm_read(s); +} + +typedef char (*u8g_font_get_char_fn)(const void *s); + + +u8g_uint_t u8g_font_calc_str_pixel_width(u8g_t *u8g, const char *s, u8g_font_get_char_fn get_char ) +{ + u8g_uint_t w; + uint8_t enc; + + /* reset the total minimal width to zero, this will be expanded during calculation */ + w = 0; + + enc = get_char(s); + + /* check for empty string, width is already 0 */ + if ( enc == '\0' ) + { + return w; + } + + /* get the glyph information of the first char. This must be valid, because we already checked for the empty string */ + /* if *s is not inside the font, then the cached parameters of the glyph are all zero */ + u8g_GetGlyph(u8g, enc); + + /* strlen(s) == 1: width = width(s[0]) */ + /* strlen(s) == 2: width = - offx(s[0]) + deltax(s[0]) + offx(s[1]) + width(s[1]) */ + /* strlen(s) == 3: width = - offx(s[0]) + deltax(s[0]) + deltax(s[1]) + offx(s[2]) + width(s[2]) */ + + /* assume that the string has size 2 or more, than start with negative offset-x */ + /* for string with size 1, this will be nullified after the loop */ + w = -u8g->glyph_x; + for(;;) + { + + /* check and stop if the end of the string is reached */ + s++; + if ( get_char(s) == '\0' ) + break; + + /* if there are still more characters, add the delta to the next glyph */ + w += u8g->glyph_dx; + + /* store the encoding in a local variable, used also after the for(;;) loop */ + enc = get_char(s); + + /* load the next glyph information */ + u8g_GetGlyph(u8g, enc); + } + + /* finally calculate the width of the last char */ + /* here is another exception, if the last char is a black, use the dx value instead */ + if ( enc != ' ' ) + { + /* if g was not updated in the for loop (strlen() == 1), then the initial offset x gets removed */ + w += u8g->glyph_width; + w += u8g->glyph_x; + } + else + { + w += u8g->glyph_dx; + } + + + return w; +} + +u8g_uint_t u8g_GetStrPixelWidth(u8g_t *u8g, const char *s) +{ + return u8g_font_calc_str_pixel_width(u8g, s, u8g_font_get_char); +} + +u8g_uint_t u8g_GetStrPixelWidthP(u8g_t *u8g, const u8g_pgm_uint8_t *s) +{ + return u8g_font_calc_str_pixel_width(u8g, (const char *)s, u8g_font_get_charP); +} + +int8_t u8g_GetStrX(u8g_t *u8g, const char *s) +{ + u8g_GetGlyph(u8g, *s); + return u8g->glyph_x; +} + +int8_t u8g_GetStrXP(u8g_t *u8g, const u8g_pgm_uint8_t *s) +{ + u8g_GetGlyph(u8g, u8g_pgm_read(s)); + return u8g->glyph_x; +} + +/*========================================================================*/ +/* string width calculation */ + +u8g_uint_t u8g_GetStrWidth(u8g_t *u8g, const char *s) +{ + u8g_uint_t w; + uint8_t encoding; + + /* reset the total width to zero, this will be expanded during calculation */ + w = 0; + + for(;;) + { + encoding = *s; + if ( encoding == 0 ) + break; + + /* load glyph information */ + u8g_GetGlyph(u8g, encoding); + w += u8g->glyph_dx; + + /* goto next char */ + s++; + } + + return w; +} + + +u8g_uint_t u8g_GetStrWidthP(u8g_t *u8g, const u8g_pgm_uint8_t *s) +{ + u8g_uint_t w; + uint8_t encoding; + + /* reset the total width to zero, this will be expanded during calculation */ + w = 0; + + for(;;) + { + encoding = u8g_pgm_read(s); + if ( encoding == 0 ) + break; + + /* load glyph information */ + u8g_GetGlyph(u8g, encoding); + w += u8g->glyph_dx; + + /* goto next char */ + s++; + } + + return w; +} + + +/*========================================================================*/ +/* calculation of font/glyph/string characteristics */ + + +/* + Description: + Calculate parameter for the minimal bounding box on a given string + Output + buf->y_min extend of the lower left edge if the string below (y_min<0) or above (y_min>0) baseline (descent) + buf->y_max extend of the upper left edge if the string below (y_min<0) or above (y_min>0) baseline (ascent) + buf->w the width of the string +*/ +struct u8g_str_size_struct +{ + int8_t y_min; /* descent */ + int8_t y_max; /* ascent */ + int8_t x, y; /* the reference point of the font (negated!) */ + u8g_uint_t w; /* width of the overall string */ +}; +typedef struct u8g_str_size_struct u8g_str_size_t; + +static void u8g_font_calc_str_min_box(u8g_t *u8g, const char *s, u8g_str_size_t *buf) +{ + /* u8g_glyph_t g; */ + int8_t tmp; + + /* reset the total minimal width to zero, this will be expanded during calculation */ + buf->w = 0; + + /* check for empty string, width is already 0, but also reset y_min and y_max to 0 */ + if ( *s == '\0' ) + { + buf->y_min = 0; + buf->y_max = 0; + buf->x = 0; + buf->y = 0; + return; + } + + /* reset y_min to the largest possible value. Later we search for the smallest value */ + /* y_min contains the position [pixel] of the lower left edge of the glyph above (y_min>0) or below (y_min<0) baseline */ + buf->y_min = 127; + /* reset y_max to the smallest possible value. Later we search for the highest value */ + /* y_max contains the position [pixel] of the upper left edge of the glyph above (y_max>0) or below (y_max<0) baseline */ + buf->y_max = -128; + + /* get the glyph information of the first char. This must be valid, because we already checked for the empty string */ + u8g_GetGlyph(u8g, *s); + + /* strlen(s) == 1: width = width(s[0]) */ + /* strlen(s) == 2: width = - offx(s[0]) + deltax(s[0]) + offx(s[1]) + width(s[1]) */ + /* strlen(s) == 3: width = - offx(s[0]) + deltax(s[0]) + deltax(s[1]) + offx(s[2]) + width(s[2]) */ + + /* assume that the string has size 2 or more, than start with negative offset-x */ + /* for string with size 1, this will be nullified after the loop */ + // buf->w = - u8g_font_GetGlyphBBXOffX(u8g->font, g); + buf->w = - u8g->glyph_x; + + /* Also copy the position of the first glyph. This is the reference point of the string (negated) */ + buf->x = u8g->glyph_x; + buf->y = u8g->glyph_y; + + for(;;) + { + + /* calculated y position of the upper left corner (y_max) and lower left corner (y_min) of the string */ + /* relative to the base line */ + + tmp = u8g->glyph_y; + if ( buf->y_min > tmp ) + buf->y_min = tmp; + + tmp +=u8g->glyph_height; + if ( buf->y_max < tmp ) + buf->y_max = tmp; + + /* check and stop if the end of the string is reached */ + s++; + if ( *s == '\0' ) + break; + + /* if there are still more characters, add the delta to the next glyph */ + buf->w += u8g->glyph_dx; + + /* load the next glyph information */ + u8g_GetGlyph(u8g, *s); + } + + /* finally calculate the width of the last char */ + /* if g was not updated in the for loop (strlen() == 1), then the initial offset x gets removed */ + buf->w += u8g->glyph_width; + // buf->w += u8g_font_GetGlyphBBXOffX(u8g->font, g); + + buf->w += u8g->glyph_x; +} + +/* calculate minimal box */ +void u8g_font_box_min(u8g_t *u8g, const char *s, u8g_str_size_t *buf) +{ + u8g_font_calc_str_min_box(u8g, s, buf); +} + +/* calculate gA box, but do not calculate the overall width */ +void u8g_font_box_left_gA(u8g_t *u8g, const char *s, u8g_str_size_t *buf) +{ + +} + +/* calculate gA box, including overall width */ +void u8g_font_box_all_gA(u8g_t *u8g, const char *s, u8g_str_size_t *buf) +{ + +} + + +static void u8g_font_get_str_box_fill_args(u8g_t *u8g, const char *s, u8g_str_size_t *buf, u8g_uint_t *x, u8g_uint_t *y, u8g_uint_t *width, u8g_uint_t *height) +{ + /* + u8g_glyph_t g; + g = + */ + u8g_GetGlyph(u8g, *s); + *x += u8g->glyph_x; + *width = buf->w; + *y -= buf->y_max; + /* +1 because y_max is a height, this compensates the next step */ + //*y += 1; + /* because the reference point is one below the string, this compensates the previous step */ + //*y -= 1; + *height = buf->y_max; + *height -= buf->y_min; +} + + +void u8g_GetStrMinBox(u8g_t *u8g, const char *s, u8g_uint_t *x, u8g_uint_t *y, u8g_uint_t *width, u8g_uint_t *height) +{ + u8g_str_size_t buf; + + if ( *s == '\0' ) + { + *width= 0; + *height = 0; + return; + } + + u8g_font_calc_str_min_box(u8g, s, &buf); + u8g_font_get_str_box_fill_args(u8g, s, &buf, x, y, width, height); +} + + +void u8g_GetStrAMinBox(u8g_t *u8g, const char *s, u8g_uint_t *x, u8g_uint_t *y, u8g_uint_t *width, u8g_uint_t *height) +{ + u8g_str_size_t buf; + uint8_t cap_a; + + if ( *s == '\0' ) + { + *width= 0; + *height = 0; + return; + } + + cap_a = u8g_font_GetCapitalAHeight(u8g->font); + u8g_font_calc_str_min_box(u8g, s, &buf); + if ( buf.y_max < cap_a ) + buf.y_max = cap_a; + u8g_font_get_str_box_fill_args(u8g, s, &buf, x, y, width, height); +} + +void u8g_SetFont(u8g_t *u8g, const u8g_fntpgm_uint8_t *font) +{ + if ( u8g->font != font ) + { + u8g->font = font; + u8g_UpdateRefHeight(u8g); + u8g_SetFontPosBaseline(u8g); + } +} + +/*========================================================================*/ +/* anti aliasing fonts */ + +int8_t u8g_draw_aa_glyph(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, uint8_t encoding) +{ + const u8g_pgm_uint8_t *data; + uint8_t w, h; + uint8_t i, j; + u8g_uint_t ix, iy; + + { + u8g_glyph_t g = u8g_GetGlyph(u8g, encoding); + if ( g == NULL ) + return 0; + data = u8g_font_GetGlyphDataStart(u8g->font, g); + } + + w = u8g->glyph_width; + h = u8g->glyph_height; + + x += u8g->glyph_x; + y -= u8g->glyph_y; + y--; + + if ( u8g_IsBBXIntersection(u8g, x, y-h+1, w, h) == 0 ) + return u8g->glyph_dx; + + /* now, w is reused as bytes per line */ + w += 3; + w /= 4; + + iy = y; + iy -= h; + iy++; + + for( j = 0; j < h; j++ ) + { + ix = x; + for( i = 0; i < w; i++ ) + { + u8g_Draw4TPixel(u8g, ix, iy, 0, u8g_pgm_read(data)); + data++; + ix+=4; + } + iy++; + } + return u8g->glyph_dx; +} + +int8_t u8g_DrawAAGlyph(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, uint8_t encoding) +{ + y += u8g->font_calc_vref(u8g); + return u8g_draw_aa_glyph(u8g, x, y, encoding); +} + +u8g_uint_t u8g_DrawAAStr(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, const char *s) +{ + u8g_uint_t t = 0; + int8_t d; + + if ( u8g_font_GetFormat(u8g->font) != 2 ) + return 0; + //u8g_uint_t u8g_GetStrWidth(u8g, s); + //u8g_font_GetFontAscent(u8g->font)-u8g_font_GetFontDescent(u8g->font); + + y += u8g->font_calc_vref(u8g); + + while( *s != '\0' ) + { + d = u8g_draw_aa_glyph(u8g, x, y, *s); + x += d; + t += d; + s++; + } + return t; +} + +// ============== u8g_page.c ================ + +/* + + u8g_page.c + + page helper functions, only called by the dev handler. + + 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. + + +*/ + +/* + setup page count structure + conditions: page_height <= total_height +*/ +void u8g_page_Init(u8g_page_t *p, u8g_uint_t page_height, u8g_uint_t total_height ) +{ + p->page_height = page_height; + p->total_height = total_height; + p->page = 0; + u8g_page_First(p); +} + +void u8g_page_First(u8g_page_t *p) +{ + p->page_y0 = 0; + p->page_y1 = p->page_height; + p->page_y1--; + p->page = 0; +} + +uint8_t u8g_page_Next(u8g_page_t * p) +{ + register u8g_uint_t y1; + p->page_y0 += p->page_height; + if ( p->page_y0 >= p->total_height ) + return 0; + p->page++; + y1 = p->page_y1; + y1 += p->page_height; + if ( y1 >= p->total_height ) + { + y1 = p->total_height; + y1--; + } + p->page_y1 = y1; + + return 1; +} + +// =============== u8g_clip.c ================ + +/* + + u8g_clip.c + + procedures for clipping + taken over from procs in u8g_pb.c + + Universal 8bit Graphics Library + + Copyright (c) 2012, 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. + + Notes + + This is one of the most critical parts of u8glib. It must be fast, but still reliable. + Based on the intersection program (see tools folder), there is minimized version of + the condition for the intersaction test: + minimized version + ---1----0 1 b1 <= a2 && b1 > b2 + -----1--0 1 b2 >= a1 && b1 > b2 + ---1-1--- 1 b1 <= a2 && b2 >= a1 + It includes the assumption, that a1 <= a2 is always true (correct, because + a1, a2 are the page dimensions. + + The direct implementation of the above result is done in: + uint8_t u8g_is_intersection_boolean(u8g_uint_t a0, u8g_uint_t a1, u8g_uint_t v0, u8g_uint_t v1) + However, this is slower than a decision tree version: + static uint8_t u8g_is_intersection_decision_tree(u8g_uint_t a0, u8g_uint_t a1, u8g_uint_t v0, u8g_uint_t v1) + Also suprising is, that the macro implementation is slower than the inlined version. + + The decision tree is based on the expansion of the truth table. + +*/ + + +#ifdef __GNUC__ +#define U8G_ALWAYS_INLINE __inline__ __attribute__((always_inline)) +#else +#define U8G_ALWAYS_INLINE + #endif + +/* + intersection assumptions: + a1 <= a2 is always true + + minimized version + ---1----0 1 b1 <= a2 && b1 > b2 + -----1--0 1 b2 >= a1 && b1 > b2 + ---1-1--- 1 b1 <= a2 && b2 >= a1 + */ + +#ifdef OLD_CODE_WHICH_IS_TOO_SLOW +static uint8_t u8g_is_intersection_boolean(u8g_uint_t a0, u8g_uint_t a1, u8g_uint_t v0, u8g_uint_t v1) +{ + uint8_t c1, c2, c3, tmp; + c1 = v0 <= a1; + c2 = v1 >= a0; + c3 = v0 > v1; + + tmp = c1; + c1 &= c2; + c2 &= c3; + c3 &= tmp; + c1 |= c2; + c1 |= c3; + return c1 & 1; +} +#endif + +#define U8G_IS_INTERSECTION_MACRO(a0,a1,v0,v1) ((uint8_t)( (v0) <= (a1) ) ? ( ( (v1) >= (a0) ) ? ( 1 ) : ( (v0) > (v1) ) ) : ( ( (v1) >= (a0) ) ? ( (v0) > (v1) ) : ( 0 ) )) + +//static uint8_t u8g_is_intersection_decision_tree(u8g_uint_t a0, u8g_uint_t a1, u8g_uint_t v0, u8g_uint_t v1) U8G_ALWAYS_INLINE; +static uint8_t U8G_ALWAYS_INLINE u8g_is_intersection_decision_tree(u8g_uint_t a0, u8g_uint_t a1, u8g_uint_t v0, u8g_uint_t v1) +{ + /* surprisingly the macro leads to larger code */ + /* return U8G_IS_INTERSECTION_MACRO(a0,a1,v0,v1); */ + if ( v0 <= a1 ) + { + if ( v1 >= a0 ) + { + return 1; + } + else + { + if ( v0 > v1 ) + { + return 1; + } + else + { + return 0; + } + } + } + else + { + if ( v1 >= a0 ) + { + if ( v0 > v1 ) + { + return 1; + } + else + { + return 0; + } + } + else + { + return 0; + } + } +} + + +uint8_t u8g_IsBBXIntersection(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, u8g_uint_t w, u8g_uint_t h) +{ + register u8g_uint_t tmp; + tmp = y; + tmp += h; + tmp--; + if ( u8g_is_intersection_decision_tree(u8g->current_page.y0, u8g->current_page.y1, y, tmp) == 0 ) + return 0; + + tmp = x; + tmp += w; + tmp--; + return u8g_is_intersection_decision_tree(u8g->current_page.x0, u8g->current_page.x1, x, tmp); +} + +// ============= u8g_com_arduino_std_sw_spi.c ===================== + +/* + + u8g_arduino_std_sw_spi.c + + 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. + +*/ + +void u8g_arduino_sw_spi_shift_out(uint8_t dataPin, uint8_t clockPin, uint8_t val) +{ + uint8_t i = 8; + do + { + if ( val & 128 ) + digitalWrite(dataPin, HIGH); + else + digitalWrite(dataPin, LOW); + val <<= 1; + u8g_MicroDelay(); /* 23 Sep 2012 */ + //delay(1); + digitalWrite(clockPin, HIGH); + u8g_MicroDelay(); /* 23 Sep 2012 */ + //delay(1); + digitalWrite(clockPin, LOW); + u8g_MicroDelay(); /* 23 Sep 2012 */ + //delay(1); + i--; + } while( i != 0 ); +} + +uint8_t u8g_com_arduino_std_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) +{ + switch(msg) + { + case U8G_COM_MSG_INIT: + u8g_com_arduino_assign_pin_output_high(u8g); + u8g_com_arduino_digital_write(u8g, U8G_PI_SCK, LOW); + u8g_com_arduino_digital_write(u8g, U8G_PI_MOSI, LOW); + break; + + case U8G_COM_MSG_STOP: + break; + + case U8G_COM_MSG_RESET: + if ( u8g->pin_list[U8G_PI_RESET] != U8G_PIN_NONE ) + u8g_com_arduino_digital_write(u8g, U8G_PI_RESET, arg_val); + break; + + case U8G_COM_MSG_CHIP_SELECT: + if ( arg_val == 0 ) + { + /* disable */ + u8g_com_arduino_digital_write(u8g, U8G_PI_CS, HIGH); + } + else + { + /* enable */ + u8g_com_arduino_digital_write(u8g, U8G_PI_SCK, LOW); + u8g_com_arduino_digital_write(u8g, U8G_PI_CS, LOW); + } + break; + + case U8G_COM_MSG_WRITE_BYTE: + u8g_arduino_sw_spi_shift_out(u8g->pin_list[U8G_PI_MOSI], u8g->pin_list[U8G_PI_SCK], arg_val); + break; + + case U8G_COM_MSG_WRITE_SEQ: + { + register uint8_t *ptr = (uint8_t*)arg_ptr; + while( arg_val > 0 ) + { + u8g_arduino_sw_spi_shift_out(u8g->pin_list[U8G_PI_MOSI], u8g->pin_list[U8G_PI_SCK], *ptr++); + arg_val--; + } + } + break; + + case U8G_COM_MSG_WRITE_SEQ_P: + { + register uint8_t *ptr = (uint8_t*)arg_ptr; + while( arg_val > 0 ) + { + u8g_arduino_sw_spi_shift_out(u8g->pin_list[U8G_PI_MOSI], u8g->pin_list[U8G_PI_SCK], u8g_pgm_read(ptr)); + ptr++; + arg_val--; + } + } + break; + + case U8G_COM_MSG_ADDRESS: /* define cmd (arg_val = 0) or data mode (arg_val = 1) */ + u8g_com_arduino_digital_write(u8g, U8G_PI_A0, arg_val); + break; + } + return 1; +} + + +// ======== u8g_com_atmega_st7920_spi.c ============== + +/* + + u8g_com_atmega_st7920_spi.c + + 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. + + A special SPI interface for ST7920 controller + +*/ + +#if defined(__AVR__) + +static void u8g_atmega_st7920_sw_spi_shift_out(u8g_t *u8g, uint8_t val) U8G_NOINLINE; +static void u8g_atmega_st7920_sw_spi_shift_out(u8g_t *u8g, uint8_t val) +{ + uint8_t i = 8; + do + { + u8g_SetPILevel(u8g, U8G_PI_MOSI, val & 128 ); + val <<= 1; + u8g_SetPILevel(u8g, U8G_PI_SCK, 1 ); + u8g_MicroDelay(); /* 15 Aug 2012: added for high speed uC */ + u8g_SetPILevel(u8g, U8G_PI_SCK, 0 ); + u8g_MicroDelay(); /* 15 Aug 2012: added for high speed uC */ + i--; + } while( i != 0 ); +} + +static void u8g_com_atmega_st7920_write_byte(u8g_t *u8g, uint8_t rs, uint8_t val) U8G_NOINLINE; +static void u8g_com_atmega_st7920_write_byte(u8g_t *u8g, uint8_t rs, uint8_t val) +{ + uint8_t i; + + if ( rs == 0 ) + { + /* command */ + u8g_atmega_st7920_sw_spi_shift_out(u8g, 0x0f8); + } + else if ( rs == 1 ) + { + /* data */ + u8g_atmega_st7920_sw_spi_shift_out(u8g, 0x0fa); + } + + u8g_atmega_st7920_sw_spi_shift_out(u8g, val & 0x0f0); + u8g_atmega_st7920_sw_spi_shift_out(u8g, val << 4); + + for( i = 0; i < 4; i++ ) + u8g_10MicroDelay(); +} + + +uint8_t u8g_com_atmega_st7920_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) +{ + switch(msg) + { + case U8G_COM_MSG_INIT: + u8g_SetPIOutput(u8g, U8G_PI_SCK); + u8g_SetPIOutput(u8g, U8G_PI_MOSI); + /* u8g_SetPIOutput(u8g, U8G_PI_A0); */ + u8g_SetPIOutput(u8g, U8G_PI_CS); + u8g_SetPIOutput(u8g, U8G_PI_RESET); + + u8g_SetPILevel(u8g, U8G_PI_SCK, 0 ); + u8g_SetPILevel(u8g, U8G_PI_MOSI, 0 ); + u8g_SetPILevel(u8g, U8G_PI_CS, 0 ); + /* u8g_SetPILevel(u8g, U8G_PI_A0, 0); */ + + u8g->pin_list[U8G_PI_A0_STATE] = 0; /* inital RS state: command mode */ + break; + + case U8G_COM_MSG_STOP: + break; + + case U8G_COM_MSG_RESET: + u8g_SetPILevel(u8g, U8G_PI_RESET, arg_val); + break; + + case U8G_COM_MSG_ADDRESS: /* define cmd (arg_val = 0) or data mode (arg_val = 1) */ + u8g->pin_list[U8G_PI_A0_STATE] = arg_val; + break; + + case U8G_COM_MSG_CHIP_SELECT: + if ( arg_val == 0 ) + { + /* disable, note: the st7920 has an active high chip select */ + u8g_SetPILevel(u8g, U8G_PI_CS, 0); + } + else + { + /* u8g_SetPILevel(u8g, U8G_PI_SCK, 0 ); */ + /* enable */ + u8g_SetPILevel(u8g, U8G_PI_CS, 1); /* CS = 1 (high active) */ + } + break; + + + case U8G_COM_MSG_WRITE_BYTE: + u8g_com_atmega_st7920_write_byte(u8g, u8g->pin_list[U8G_PI_A0_STATE], arg_val); + u8g->pin_list[U8G_PI_A0_STATE] = 2; + break; + + case U8G_COM_MSG_WRITE_SEQ: + { + register uint8_t *ptr = (uint8_t*)arg_ptr; + while( arg_val > 0 ) + { + u8g_com_atmega_st7920_write_byte(u8g, u8g->pin_list[U8G_PI_A0_STATE], *ptr++); + u8g->pin_list[U8G_PI_A0_STATE] = 2; + arg_val--; + } + } + break; + + case U8G_COM_MSG_WRITE_SEQ_P: + { + register uint8_t *ptr = (uint8_t*)arg_ptr; + while( arg_val > 0 ) + { + u8g_com_atmega_st7920_write_byte(u8g, u8g->pin_list[U8G_PI_A0_STATE], u8g_pgm_read(ptr)); + u8g->pin_list[U8G_PI_A0_STATE] = 2; + ptr++; + arg_val--; + } + } + break; + } + return 1; +} + +#else + + +uint8_t u8g_com_atmega_st7920_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) +{ + return 1; +} + + +#endif + +// ================ u8g_butmap.c =============== + +/* + + u8g_bitmap.c + + 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. + + +*/ + + +void u8g_DrawHBitmap(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, u8g_uint_t cnt, const uint8_t *bitmap) +{ + while( cnt > 0 ) + { + u8g_Draw8Pixel(u8g, x, y, 0, *bitmap); + bitmap++; + cnt--; + x+=8; + } +} + +void u8g_DrawBitmap(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, u8g_uint_t cnt, u8g_uint_t h, const uint8_t *bitmap) +{ + if ( u8g_IsBBXIntersection(u8g, x, y, cnt*8, h) == 0 ) + return; + while( h > 0 ) + { + u8g_DrawHBitmap(u8g, x, y, cnt, bitmap); + bitmap += cnt; + y++; + h--; + } +} + + +void u8g_DrawHBitmapP(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, u8g_uint_t cnt, const u8g_pgm_uint8_t *bitmap) +{ + while( cnt > 0 ) + { + u8g_Draw8Pixel(u8g, x, y, 0, u8g_pgm_read(bitmap)); + bitmap++; + cnt--; + x+=8; + } +} + +void u8g_DrawBitmapP(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, u8g_uint_t cnt, u8g_uint_t h, const u8g_pgm_uint8_t *bitmap) +{ + if ( u8g_IsBBXIntersection(u8g, x, y, cnt*8, h) == 0 ) + return; + while( h > 0 ) + { + u8g_DrawHBitmapP(u8g, x, y, cnt, bitmap); + bitmap += cnt; + y++; + h--; + } +} + +/*=========================================================================*/ + +static void u8g_DrawHXBM(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, u8g_uint_t w, const uint8_t *bitmap) +{ + uint8_t d; + x+=7; + while( w >= 8 ) + { + u8g_Draw8Pixel(u8g, x, y, 2, *bitmap); + bitmap++; + w-= 8; + x+=8; + } + if ( w > 0 ) + { + d = *bitmap; + x -= 7; + do + { + if ( d & 1 ) + u8g_DrawPixel(u8g, x, y); + x++; + w--; + d >>= 1; + } while ( w > 0 ); + } +} + +void u8g_DrawXBM(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, u8g_uint_t w, u8g_uint_t h, const uint8_t *bitmap) +{ + u8g_uint_t b; + b = w; + b += 7; + b >>= 3; + + if ( u8g_IsBBXIntersection(u8g, x, y, w, h) == 0 ) + return; + + while( h > 0 ) + { + u8g_DrawHXBM(u8g, x, y, w, bitmap); + bitmap += b; + y++; + h--; + } +} + +static void u8g_DrawHXBMP(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, u8g_uint_t w, const u8g_pgm_uint8_t *bitmap) +{ + uint8_t d; + x+=7; + while( w >= 8 ) + { + u8g_Draw8Pixel(u8g, x, y, 2, u8g_pgm_read(bitmap)); + bitmap++; + w-= 8; + x+=8; + } + if ( w > 0 ) + { + d = u8g_pgm_read(bitmap); + x -= 7; + do + { + if ( d & 1 ) + u8g_DrawPixel(u8g, x, y); + x++; + w--; + d >>= 1; + } while ( w > 0 ); + } +} + +void u8g_DrawXBMP(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, u8g_uint_t w, u8g_uint_t h, const u8g_pgm_uint8_t *bitmap) +{ + u8g_uint_t b; + b = w; + b += 7; + b >>= 3; + + if ( u8g_IsBBXIntersection(u8g, x, y, w, h) == 0 ) + return; + while( h > 0 ) + { + u8g_DrawHXBMP(u8g, x, y, w, bitmap); + bitmap += b; + y++; + h--; + } +} + +// ============= u8g_api_ii.c =============== + +/* + + u8g_ll_api.c + + low level api + + 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. + + +*/ + +uint8_t u8g_call_dev_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg) +{ + return dev->dev_fn(u8g, dev, msg, arg); +} + +/*====================================================================*/ + +uint8_t u8g_InitLL(u8g_t *u8g, u8g_dev_t *dev) +{ + uint8_t r; + u8g->state_cb(U8G_STATE_MSG_BACKUP_ENV); + r = u8g_call_dev_fn(u8g, dev, U8G_DEV_MSG_INIT, NULL); + u8g->state_cb(U8G_STATE_MSG_BACKUP_U8G); + u8g->state_cb(U8G_STATE_MSG_RESTORE_ENV); + return r; +} + +void u8g_FirstPageLL(u8g_t *u8g, u8g_dev_t *dev) +{ + u8g->state_cb(U8G_STATE_MSG_BACKUP_ENV); + u8g->state_cb(U8G_STATE_MSG_RESTORE_U8G); + u8g_call_dev_fn(u8g, dev, U8G_DEV_MSG_PAGE_FIRST, NULL); + u8g_call_dev_fn(u8g, dev, U8G_DEV_MSG_GET_PAGE_BOX, &(u8g->current_page)); + u8g->state_cb(U8G_STATE_MSG_RESTORE_ENV); +} + +uint8_t u8g_NextPageLL(u8g_t *u8g, u8g_dev_t *dev) +{ + uint8_t r; + u8g->state_cb(U8G_STATE_MSG_BACKUP_ENV); + u8g->state_cb(U8G_STATE_MSG_RESTORE_U8G); + r = u8g_call_dev_fn(u8g, dev, U8G_DEV_MSG_PAGE_NEXT, NULL); + if ( r != 0 ) + { + u8g_call_dev_fn(u8g, dev, U8G_DEV_MSG_GET_PAGE_BOX, &(u8g->current_page)); + } + u8g->state_cb(U8G_STATE_MSG_RESTORE_ENV); + return r; +} + +uint8_t u8g_SetContrastLL(u8g_t *u8g, u8g_dev_t *dev, uint8_t contrast) +{ + return u8g_call_dev_fn(u8g, dev, U8G_DEV_MSG_CONTRAST, &contrast); +} + +void u8g_DrawPixelLL(u8g_t *u8g, u8g_dev_t *dev, u8g_uint_t x, u8g_uint_t y) +{ + u8g_dev_arg_pixel_t *arg = &(u8g->arg_pixel); + arg->x = x; + arg->y = y; + u8g_call_dev_fn(u8g, dev, U8G_DEV_MSG_SET_PIXEL, arg); +} + +void u8g_Draw8PixelLL(u8g_t *u8g, u8g_dev_t *dev, u8g_uint_t x, u8g_uint_t y, uint8_t dir, uint8_t pixel) +{ + u8g_dev_arg_pixel_t *arg = &(u8g->arg_pixel); + arg->x = x; + arg->y = y; + arg->dir = dir; + arg->pixel = pixel; + u8g_call_dev_fn(u8g, dev, U8G_DEV_MSG_SET_8PIXEL, arg); +} + +void u8g_Draw4TPixelLL(u8g_t *u8g, u8g_dev_t *dev, u8g_uint_t x, u8g_uint_t y, uint8_t dir, uint8_t pixel) +{ + u8g_dev_arg_pixel_t *arg = &(u8g->arg_pixel); + arg->x = x; + arg->y = y; + arg->dir = dir; + arg->pixel = pixel; + u8g_call_dev_fn(u8g, dev, U8G_DEV_MSG_SET_4TPIXEL, arg); +} + + +#ifdef U8G_DEV_MSG_IS_BBX_INTERSECTION +uint8_t u8g_IsBBXIntersectionLL(u8g_t *u8g, u8g_dev_t *dev, u8g_uint_t x, u8g_uint_t y, u8g_uint_t w, u8g_uint_t h) +{ + return u8g_call_dev_fn(u8g, dev, U8G_DEV_MSG_IS_BBX_INTERSECTION, &arg); +} +#endif + + + +u8g_uint_t u8g_GetWidthLL(u8g_t *u8g, u8g_dev_t *dev) +{ + u8g_uint_t r; + u8g_call_dev_fn(u8g, dev, U8G_DEV_MSG_GET_WIDTH, &r); + return r; +} + +u8g_uint_t u8g_GetHeightLL(u8g_t *u8g, u8g_dev_t *dev) +{ + u8g_uint_t r; + u8g_call_dev_fn(u8g, dev, U8G_DEV_MSG_GET_HEIGHT, &r); + return r; +} + +u8g_uint_t u8g_GetModeLL(u8g_t *u8g, u8g_dev_t *dev) +{ + return u8g_call_dev_fn(u8g, dev, U8G_DEV_MSG_GET_MODE, NULL); +} + + + +/*====================================================================*/ + +void u8g_UpdateDimension(u8g_t *u8g) +{ + u8g->width = u8g_GetWidthLL(u8g, u8g->dev); + u8g->height = u8g_GetHeightLL(u8g, u8g->dev); + u8g->mode = u8g_GetModeLL(u8g, u8g->dev); + /* 9 Dec 2012: u8g_scale.c requires update of current page */ + u8g_call_dev_fn(u8g, u8g->dev, U8G_DEV_MSG_GET_PAGE_BOX, &(u8g->current_page)); +} + +static void u8g_init_data(u8g_t *u8g) +{ + u8g->font = NULL; + u8g->cursor_font = NULL; + u8g->cursor_bg_color = 0; + u8g->cursor_fg_color = 1; + u8g->cursor_encoding = 34; + u8g->cursor_fn = (u8g_draw_cursor_fn)0; + +#if defined(U8G_WITH_PINLIST) + { + uint8_t i; + for( i = 0; i < U8G_PIN_LIST_LEN; i++ ) + u8g->pin_list[i] = U8G_PIN_NONE; + } +#endif + + u8g_SetColorIndex(u8g, 1); + + u8g_SetFontPosBaseline(u8g); + + u8g->font_height_mode = U8G_FONT_HEIGHT_MODE_XTEXT; + u8g->font_ref_ascent = 0; + u8g->font_ref_descent = 0; + u8g->font_line_spacing_factor = 64; /* 64 = 1.0, 77 = 1.2 line spacing factor */ + u8g->line_spacing = 0; + + u8g->state_cb = u8g_state_dummy_cb; + +} + +uint8_t u8g_Begin(u8g_t *u8g) +{ + /* call and init low level driver and com device */ + if ( u8g_InitLL(u8g, u8g->dev) == 0 ) + return 0; + /* fetch width and height from the low level */ + u8g_UpdateDimension(u8g); + return 1; +} + +uint8_t u8g_Init(u8g_t *u8g, u8g_dev_t *dev) +{ + u8g_init_data(u8g); + u8g->dev = dev; + + /* On the Arduino Environment this will lead to two calls to u8g_Begin(), the following line will be called first (by U8glib constructors) */ + /* if - in future releases - this is removed, then still call u8g_UpdateDimension() */ + /* if Arduino call u8g_UpdateDimension else u8g_Begin */ + /* issue 146 */ + return u8g_Begin(u8g); +} + +/* special init for pure ARM systems */ +uint8_t u8g_InitComFn(u8g_t *u8g, u8g_dev_t *dev, u8g_com_fnptr com_fn) +{ + u8g_init_data(u8g); + +#if defined(U8G_WITH_PINLIST) + { + uint8_t i; + for( i = 0; i < U8G_PIN_LIST_LEN; i++ ) + u8g->pin_list[i] = U8G_PIN_DUMMY; + } +#endif + + u8g->dev = dev; + + /* replace the device procedure with a custom communication procedure */ + u8g->dev->com_fn = com_fn; + + /* On the Arduino Environment this will lead to two calls to u8g_Begin(), the following line will be called first (by U8glib constructors) */ + /* if - in future releases - this is removed, then still call u8g_UpdateDimension() */ + /* if Arduino call u8g_UpdateDimension else u8g_Begin */ + /* issue 146 */ + return u8g_Begin(u8g); +} + + +#if defined(U8G_WITH_PINLIST) +uint8_t u8g_InitSPI(u8g_t *u8g, u8g_dev_t *dev, uint8_t sck, uint8_t mosi, uint8_t cs, uint8_t a0, uint8_t reset) +{ + + /* fill data structure with some suitable values */ + u8g_init_data(u8g); + u8g->dev = dev; + + /* assign user pins */ + u8g->pin_list[U8G_PI_SCK] = sck; + u8g->pin_list[U8G_PI_MOSI] = mosi; + u8g->pin_list[U8G_PI_CS] = cs; + u8g->pin_list[U8G_PI_A0] = a0; + u8g->pin_list[U8G_PI_RESET] = reset; + + /* On the Arduino Environment this will lead to two calls to u8g_Begin(), the following line will be called first (by U8glib constructors) */ + /* if - in future releases - this is removed, then still call u8g_UpdateDimension() */ + /* if Arduino call u8g_UpdateDimension else u8g_Begin */ + /* issue 146 */ + return u8g_Begin(u8g); +} + +uint8_t u8g_InitHWSPI(u8g_t *u8g, u8g_dev_t *dev, uint8_t cs, uint8_t a0, uint8_t reset) +{ + /* fill data structure with some suitable values */ + u8g_init_data(u8g); + u8g->dev = dev; + + + /* assign user pins */ + u8g->pin_list[U8G_PI_CS] = cs; + u8g->pin_list[U8G_PI_A0] = a0; + u8g->pin_list[U8G_PI_RESET] = reset; + + return u8g_Begin(u8g); +} + +uint8_t u8g_InitI2C(u8g_t *u8g, u8g_dev_t *dev, uint8_t options) +{ + /* fill data structure with some suitable values */ + u8g_init_data(u8g); + u8g->dev = dev; + + u8g->pin_list[U8G_PI_I2C_OPTION] = options; + + return u8g_Begin(u8g); +} + + +uint8_t u8g_Init8BitFixedPort(u8g_t *u8g, u8g_dev_t *dev, uint8_t en, uint8_t cs, uint8_t di, uint8_t rw, uint8_t reset) +{ + + /* fill data structure with some suitable values */ + u8g_init_data(u8g); + u8g->dev = dev; + + /* assign user pins */ + + u8g->pin_list[U8G_PI_EN] = en; + u8g->pin_list[U8G_PI_CS] = cs; + u8g->pin_list[U8G_PI_DI] = di; + u8g->pin_list[U8G_PI_RW] = rw; + u8g->pin_list[U8G_PI_RESET] = reset; + + return u8g_Begin(u8g); +} + +uint8_t u8g_Init8Bit(u8g_t *u8g, u8g_dev_t *dev, uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7, + uint8_t en, uint8_t cs1, uint8_t cs2, uint8_t di, uint8_t rw, uint8_t reset) +{ + + /* fill data structure with some suitable values */ + u8g_init_data(u8g); + u8g->dev = dev; + + /* assign user pins */ + + u8g->pin_list[U8G_PI_D0] = d0; + u8g->pin_list[U8G_PI_D1] = d1; + u8g->pin_list[U8G_PI_D2] = d2; + u8g->pin_list[U8G_PI_D3] = d3; + u8g->pin_list[U8G_PI_D4] = d4; + u8g->pin_list[U8G_PI_D5] = d5; + u8g->pin_list[U8G_PI_D6] = d6; + u8g->pin_list[U8G_PI_D7] = d7; + + u8g->pin_list[U8G_PI_EN] = en; + u8g->pin_list[U8G_PI_CS1] = cs1; + u8g->pin_list[U8G_PI_CS2] = cs2; + u8g->pin_list[U8G_PI_DI] = di; + u8g->pin_list[U8G_PI_RW] = rw; + u8g->pin_list[U8G_PI_RESET] = reset; + + return u8g_Begin(u8g); +} + +/* + + PIN_D0 8 + PIN_D1 9 + PIN_D2 10 + PIN_D3 11 + PIN_D4 4 + PIN_D5 5 + PIN_D6 6 + PIN_D7 7 + + PIN_CS 14 + PIN_A0 15 + PIN_RESET 16 + PIN_WR 17 + PIN_RD 18 + + u8g_InitRW8Bit(u8g, dev, d0, d1, d2, d3, d4, d5, d6, d7, cs, a0, wr, rd, reset) + u8g_InitRW8Bit(u8g, dev, 8, 9, 10, 11, 4, 5, 6, 7, 14, 15, 17, 18, 16) + +*/ + +uint8_t u8g_InitRW8Bit(u8g_t *u8g, u8g_dev_t *dev, uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7, + uint8_t cs, uint8_t a0, uint8_t wr, uint8_t rd, uint8_t reset) +{ + + /* fill data structure with some suitable values */ + u8g_init_data(u8g); + u8g->dev = dev; + + /* assign user pins */ + + u8g->pin_list[U8G_PI_D0] = d0; + u8g->pin_list[U8G_PI_D1] = d1; + u8g->pin_list[U8G_PI_D2] = d2; + u8g->pin_list[U8G_PI_D3] = d3; + u8g->pin_list[U8G_PI_D4] = d4; + u8g->pin_list[U8G_PI_D5] = d5; + u8g->pin_list[U8G_PI_D6] = d6; + u8g->pin_list[U8G_PI_D7] = d7; + + u8g->pin_list[U8G_PI_CS] = cs; + u8g->pin_list[U8G_PI_A0] = a0; + u8g->pin_list[U8G_PI_WR] = wr; + u8g->pin_list[U8G_PI_RD] = rd; + u8g->pin_list[U8G_PI_RESET] = reset; + + return u8g_Begin(u8g); +} +#endif /* defined(U8G_WITH_PINLIST) */ + +void u8g_FirstPage(u8g_t *u8g) +{ + u8g_FirstPageLL(u8g, u8g->dev); +} + +uint8_t u8g_NextPage(u8g_t *u8g) +{ + if ( u8g->cursor_fn != (u8g_draw_cursor_fn)0 ) + { + u8g->cursor_fn(u8g); + } + return u8g_NextPageLL(u8g, u8g->dev); +} + +uint8_t u8g_SetContrast(u8g_t *u8g, uint8_t contrast) +{ + return u8g_SetContrastLL(u8g, u8g->dev, contrast); +} + +void u8g_SleepOn(u8g_t *u8g) +{ + u8g_call_dev_fn(u8g, u8g->dev, U8G_DEV_MSG_SLEEP_ON, NULL); +} + +void u8g_SleepOff(u8g_t *u8g) +{ + u8g_call_dev_fn(u8g, u8g->dev, U8G_DEV_MSG_SLEEP_OFF, NULL); +} + + +void u8g_DrawPixel(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y) +{ + u8g_DrawPixelLL(u8g, u8g->dev, x, y); +} + +void u8g_Draw8Pixel(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, uint8_t dir, uint8_t pixel) +{ + u8g_Draw8PixelLL(u8g, u8g->dev, x, y, dir, pixel); +} + +void u8g_Draw4TPixel(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, uint8_t dir, uint8_t pixel) +{ + u8g_Draw4TPixelLL(u8g, u8g->dev, x, y, dir, pixel); +} + + +/* u8g_IsBBXIntersection() has been moved to u8g_clip.c */ +#ifdef OBSOLETE_CODE +uint8_t u8g_IsBBXIntersection(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, u8g_uint_t w, u8g_uint_t h) +{ + /* new code */ + u8g_dev_arg_bbx_t arg; + arg.x = x; + arg.y = y; + arg.w = w; + arg.h = h; + return u8g_is_box_bbx_intersection(&(u8g->current_page), &arg); + + /* old code */ + //return u8g_IsBBXIntersectionLL(u8g, u8g->dev, x, y, w, h); +} +#endif + +/* + idx: index for the palette entry (0..255) + r: value for red (0..255) + g: value for green (0..255) + b: value for blue (0..255) +*/ +void u8g_SetColorEntry(u8g_t *u8g, uint8_t idx, uint8_t r, uint8_t g, uint8_t b) +{ + u8g_dev_arg_irgb_t irgb; + irgb.idx = idx; + irgb.r = r; + irgb.g = g; + irgb.b = b; + u8g_call_dev_fn(u8g, u8g->dev, U8G_DEV_MSG_SET_COLOR_ENTRY, &irgb); +} + +void u8g_SetColorIndex(u8g_t *u8g, uint8_t idx) +{ + u8g->arg_pixel.color = idx; + /*u8g->color_index = idx; */ /* must be removed */ +} + +void u8g_SetHiColor(u8g_t *u8g, uint16_t rgb) +{ + u8g->arg_pixel.color = rgb&255; + u8g->arg_pixel.hi_color = rgb>>8; + /*u8g->color_index = idx; */ /* must be removed */ +} + +void u8g_SetHiColorByRGB(u8g_t *u8g, uint8_t r, uint8_t g, uint8_t b) +{ + + r &= ~7; + g >>= 2; + b >>= 3; + u8g->arg_pixel.color = b; + u8g->arg_pixel.color |= (g & 7) << 5; + u8g->arg_pixel.hi_color = r; + u8g->arg_pixel.hi_color |= (g>>3) & 7; + + //u8g_SetHiColor(u8g, U8G_GET_HICOLOR_BY_RGB(r,g,b)); +} + +void u8g_SetRGB(u8g_t *u8g, uint8_t r, uint8_t g, uint8_t b) +{ + if ( u8g->mode == U8G_MODE_R3G3B2 ) + { + r &= 0x0e0; + g &= 0x0e0; + g >>= 3; + b >>= 6; + u8g->arg_pixel.color = r | g | b; + } + else if ( u8g->mode == U8G_MODE_HICOLOR ) + { + u8g_SetHiColorByRGB(u8g, r,g,b); + } + else + { + u8g->arg_pixel.color = r; + u8g->arg_pixel.hi_color = g; + u8g->arg_pixel.blue = b; + } +} + + +uint8_t u8g_GetColorIndex(u8g_t *u8g) +{ + return u8g->arg_pixel.color; +} + +uint8_t u8g_GetDefaultForegroundColor(u8g_t *u8g) +{ + uint8_t mode; + mode = u8g_GetMode(u8g); + if ( mode == U8G_MODE_R3G3B2 ) + return 255; /* white */ + else if ( u8g_GetMode(u8g) == U8G_MODE_GRAY2BIT ) + return 3; /* max intensity */ + else /* if ( u8g.getMode() == U8G_MODE_BW ) */ + return 1; /* pixel on */ + return 1; +} + +void u8g_SetDefaultForegroundColor(u8g_t *u8g) +{ + if ( u8g->mode == U8G_MODE_HICOLOR ) + { + u8g->arg_pixel.color = 0x0ff; + u8g->arg_pixel.hi_color = 0x0ff; + } + else + { + u8g_SetColorIndex(u8g, u8g_GetDefaultForegroundColor(u8g)); + } +} + +uint8_t u8g_GetDefaultBackgroundColor(u8g_t *u8g) +{ + return 0; +} + +void u8g_SetDefaultBackgroundColor(u8g_t *u8g) +{ + u8g_SetColorIndex(u8g, u8g_GetDefaultBackgroundColor(u8g)); /* pixel on / black */ +} + +uint8_t u8g_GetDefaultMidColor(u8g_t *u8g) +{ + uint8_t mode; + mode = u8g_GetMode(u8g); + if ( mode == U8G_MODE_R3G3B2 ) + return 0x06d; /* gray: 01101101 */ + else if ( u8g_GetMode(u8g) == U8G_MODE_GRAY2BIT ) + return 1; /* low mid intensity */ + else /* if ( u8g.getMode() == U8G_MODE_BW ) */ + return 1; /* pixel on */ + return 1; /* default */ +} + +void u8g_SetDefaultMidColor(u8g_t *u8g) +{ + u8g_SetColorIndex(u8g, u8g_GetDefaultMidColor(u8g)); +} + +// ============== u8g_com_api.c ================== +/* + + u8g_com_api.c + + 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. + + +*/ + + +uint8_t u8g_InitCom(u8g_t *u8g, u8g_dev_t *dev, uint8_t clk_cycle_time) +{ + return dev->com_fn(u8g, U8G_COM_MSG_INIT, clk_cycle_time, NULL); +} + +void u8g_StopCom(u8g_t *u8g, u8g_dev_t *dev) +{ + dev->com_fn(u8g, U8G_COM_MSG_STOP, 0, NULL); +} + +/* cs contains the chip number, which should be enabled */ +void u8g_SetChipSelect(u8g_t *u8g, u8g_dev_t *dev, uint8_t cs) +{ + dev->com_fn(u8g, U8G_COM_MSG_CHIP_SELECT, cs, NULL); +} + +void u8g_SetResetLow(u8g_t *u8g, u8g_dev_t *dev) +{ + dev->com_fn(u8g, U8G_COM_MSG_RESET, 0, NULL); +} + +void u8g_SetResetHigh(u8g_t *u8g, u8g_dev_t *dev) +{ + dev->com_fn(u8g, U8G_COM_MSG_RESET, 1, NULL); +} + + +void u8g_SetAddress(u8g_t *u8g, u8g_dev_t *dev, uint8_t address) +{ + dev->com_fn(u8g, U8G_COM_MSG_ADDRESS, address, NULL); +} + +uint8_t u8g_WriteByte(u8g_t *u8g, u8g_dev_t *dev, uint8_t val) +{ + return dev->com_fn(u8g, U8G_COM_MSG_WRITE_BYTE, val, NULL); +} + +uint8_t u8g_WriteSequence(u8g_t *u8g, u8g_dev_t *dev, uint8_t cnt, uint8_t *seq) +{ + return dev->com_fn(u8g, U8G_COM_MSG_WRITE_SEQ, cnt, seq); +} + +uint8_t u8g_WriteSequenceP(u8g_t *u8g, u8g_dev_t *dev, uint8_t cnt, const uint8_t *seq) +{ + return dev->com_fn(u8g, U8G_COM_MSG_WRITE_SEQ_P, cnt, (void *)seq); +} + +/* + sequence := { direct_value | escape_sequence } + direct_value := 0..254 + escape_sequence := value_255 | sequence_end | delay | adr | cs | not_used + value_255 := 255 255 + sequence_end = 255 254 + delay := 255 0..127 + adr := 255 0x0e0 .. 0x0ef + cs := 255 0x0d0 .. 0x0df + not_used := 255 101..254 + +#define U8G_ESC_DLY(x) 255, ((x) & 0x7f) +#define U8G_ESC_CS(x) 255, (0xd0 | ((x)&0x0f)) +#define U8G_ESC_ADR(x) 255, (0xe0 | ((x)&0x0f)) +#define U8G_ESC_VCC(x) 255, (0xbe | ((x)&0x01)) +#define U8G_ESC_END 255, 254 +#define U8G_ESC_255 255, 255 +#define U8G_ESC_RST(x) 255, (0xc0 | ((x)&0x0f)) + +*/ +uint8_t u8g_WriteEscSeqP(u8g_t *u8g, u8g_dev_t *dev, const uint8_t *esc_seq) +{ + uint8_t is_escape = 0; + uint8_t value; + for(;;) + { + value = u8g_pgm_read(esc_seq); + if ( is_escape == 0 ) + { + if ( value != 255 ) + { + if ( u8g_WriteByte(u8g, dev, value) == 0 ) + return 0; + } + else + { + is_escape = 1; + } + } + else + { + if ( value == 255 ) + { + if ( u8g_WriteByte(u8g, dev, value) == 0 ) + return 0; + } + else if ( value == 254 ) + { + break; + } + else if ( value >= 0x0f0 ) + { + /* not yet used, do nothing */ + } + else if ( value >= 0xe0 ) + { + u8g_SetAddress(u8g, dev, value & 0x0f); + } + else if ( value >= 0xd0 ) + { + u8g_SetChipSelect(u8g, dev, value & 0x0f); + } + else if ( value >= 0xc0 ) + { + u8g_SetResetLow(u8g, dev); + value &= 0x0f; + value <<= 4; + value+=2; + u8g_Delay(value); + u8g_SetResetHigh(u8g, dev); + u8g_Delay(value); + } + else if ( value >= 0xbe ) + { + /* not yet implemented */ + /* u8g_SetVCC(u8g, dev, value & 0x01); */ + } + else if ( value <= 127 ) + { + u8g_Delay(value); + } + is_escape = 0; + } + esc_seq++; + } + return 1; +} + + +// ============ u8g_delay.c =========== +/* + + u8g_delay.c + + 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. + + + void u8g_Delay(uint16_t val) Delay by "val" milliseconds + void u8g_MicroDelay(void) Delay be one microsecond + void u8g_10MicroDelay(void) Delay by 10 microseconds + + +*/ + + + +/*==== Part 1: Derive suitable delay procedure ====*/ + +#if defined(ARDUINO) + +# if defined(__AVR__) +# define USE_AVR_DELAY +# elif defined(__PIC32MX) +# define USE_PIC32_DELAY +# elif defined(__arm__) /* Arduino Due */ +# define USE_ARDUINO_DELAY +# else +# define USE_ARDUINO_DELAY +# endif +#elif defined(__AVR__) +# define USE_AVR_DELAY +#elif defined(__18CXX) +# define USE_PIC18_DELAY +#elif defined(__arm__) +/* do not define anything, all procedures are expected to be defined outside u8glib */ + +/* +void u8g_Delay(uint16_t val); +void u8g_MicroDelay(void); +void u8g_10MicroDelay(void); +*/ + +#else +# define USE_DUMMY_DELAY +#endif + + + +/*==== Part 2: Definition of the delay procedures ====*/ + +/*== AVR Delay ==*/ + +#if defined(USE_AVR_DELAY) +#include +#include +#include + +/* + Delay by the provided number of milliseconds. + Thus, a 16 bit value will allow a delay of 0..65 seconds + Makes use of the _delay_loop_2 + + _delay_loop_2 will do a delay of n * 4 prozessor cycles. + with f = F_CPU cycles per second, + n = f / (1000 * 4 ) + with f = 16000000 the result is 4000 + with f = 1000000 the result is 250 + + the millisec loop, gcc requires the following overhead: + - movev 1 + - subwi 2x2 + - bne i 2 + ==> 7 cycles + ==> must be devided by 4, rounded up 7/4 = 2 +*/ +void u8g_Delay(uint16_t val) +{ + /* old version did a call to the arduino lib: delay(val); */ + while( val != 0 ) + { + _delay_loop_2( (F_CPU / 4000 ) -2); + val--; + } +} + +/* delay by one micro second */ +void u8g_MicroDelay(void) +{ +#if (F_CPU / 4000000 ) > 0 + _delay_loop_2( (F_CPU / 4000000 ) ); +#endif +} + +/* delay by 10 micro seconds */ +void u8g_10MicroDelay(void) +{ +#if (F_CPU / 400000 ) > 0 + _delay_loop_2( (F_CPU / 400000 ) ); +#endif +} + +#endif + + +/*== Delay for PIC18 (not tested) ==*/ + +#if defined(USE_PIC18_DELAY) +#include +#define GetSystemClock() (64000000ul) // Hz +#define GetInstructionClock() (GetSystemClock()/4) + +void u8g_Delay(uint16_t val) +{/* + unsigned int _iTemp = (val); + while(_iTemp--) + Delay1KTCYx((GetInstructionClock()+999999)/1000000); + */ +} +void u8g_MicroDelay(void) +{ + /* not implemented */ +} +void u8g_10MicroDelay(void) +{ + /* not implemented */ +} +#endif + + +/*== Arduino Delay ==*/ +#if defined(USE_ARDUINO_DELAY) +void u8g_Delay(uint16_t val) +{ +#if defined(__arm__) + delayMicroseconds((uint32_t)val*(uint32_t)1000); +#else + delay(val); +#endif +} +void u8g_MicroDelay(void) +{ + delayMicroseconds(1); +} +void u8g_10MicroDelay(void) +{ + delayMicroseconds(10); +} +#endif + +#if defined(USE_PIC32_DELAY) +/* + Assume chipkit here with F_CPU correctly defined + The problem was, that u8g_Delay() is called within the constructor. + It seems that the chipkit is not fully setup at this time, so a + call to delay() will not work. So here is my own implementation. + +*/ +#define CPU_COUNTS_PER_SECOND (F_CPU/2UL) +#define TICKS_PER_MILLISECOND (CPU_COUNTS_PER_SECOND/1000UL) +#include "plib.h" +void u8g_Delay(uint16_t val) +{ + uint32_t d; + uint32_t s; + d = val; + d *= TICKS_PER_MILLISECOND; + s = ReadCoreTimer(); + while ( (uint32_t)(ReadCoreTimer() - s) < d ) + ; +} + +void u8g_MicroDelay(void) +{ + uint32_t d; + uint32_t s; + d = TICKS_PER_MILLISECOND/1000; + s = ReadCoreTimer(); + while ( (uint32_t)(ReadCoreTimer() - s) < d ) + ; +} + +void u8g_10MicroDelay(void) +{ + uint32_t d; + uint32_t s; + d = TICKS_PER_MILLISECOND/100; + s = ReadCoreTimer(); + while ( (uint32_t)(ReadCoreTimer() - s) < d ) + ; +} + +#endif + +/*== Any other systems: Dummy Delay ==*/ +#if defined(USE_DUMMY_DELAY) +void u8g_Delay(uint16_t val) +{ + /* do not know how to delay... */ +} +void u8g_MicroDelay(void) +{ +} +void u8g_10MicroDelay(void) +{ +} +#endif + + +// =============== u8g_state.c ================ + +/* + + u8g_state.c + + backup and restore hardware state + + 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. + + + state callback: backup env U8G_STATE_MSG_BACKUP_ENV + device callback: DEV_MSG_INIT + state callback: backup u8g U8G_STATE_MSG_BACKUP_U8G + state callback: restore env U8G_STATE_MSG_RESTORE_ENV + + state callback: backup env U8G_STATE_MSG_BACKUP_ENV + state callback: retore u8g U8G_STATE_MSG_RESTORE_U8G + DEV_MSG_PAGE_FIRST or DEV_MSG_PAGE_NEXT + state callback: restore env U8G_STATE_MSG_RESTORE_ENV + +*/ + + +void u8g_state_dummy_cb(uint8_t msg) +{ + /* the dummy procedure does nothing */ +} + +void u8g_SetHardwareBackup(u8g_t *u8g, u8g_state_cb backup_cb) +{ + u8g->state_cb = backup_cb; + /* in most cases the init message was already sent, so this will backup the */ + /* current u8g state */ + backup_cb(U8G_STATE_MSG_BACKUP_U8G); +} + + +/*===============================================================*/ +/* register variable for restoring interrupt state */ + +#if defined(__AVR__) +uint8_t global_SREG_backup; +#endif + + + +/*===============================================================*/ +/* AVR */ + +#if defined(__AVR__) +#define U8G_ATMEGA_HW_SPI + +/* remove the definition for attiny */ +#if __AVR_ARCH__ == 2 +#undef U8G_ATMEGA_HW_SPI +#endif +#if __AVR_ARCH__ == 25 +#undef U8G_ATMEGA_HW_SPI +#endif +#endif + +#if defined(U8G_ATMEGA_HW_SPI) +#include +static uint8_t u8g_state_avr_spi_memory[2]; + +void u8g_backup_spi(uint8_t msg) +{ + if ( U8G_STATE_MSG_IS_BACKUP(msg) ) + { + u8g_state_avr_spi_memory[U8G_STATE_MSG_GET_IDX(msg)] = SPCR; + } + else + { + uint8_t tmp = SREG; + cli(); + SPCR = 0; + SPCR = u8g_state_avr_spi_memory[U8G_STATE_MSG_GET_IDX(msg)]; + SREG = tmp; + } +} + +#elif defined(ARDUINO) && defined(__arm__) // Arduino Due, maybe we should better check for __SAM3X8E__ + +#include "sam.h" + +struct sam_backup_struct +{ + uint32_t mr; + uint32_t sr; + uint32_t csr[4]; +} sam_backup[2]; + +void u8g_backup_spi(uint8_t msg) +{ + uint8_t idx = U8G_STATE_MSG_GET_IDX(msg); + if ( U8G_STATE_MSG_IS_BACKUP(msg) ) + { + sam_backup[idx].mr = SPI0->SPI_MR; + sam_backup[idx].sr = SPI0->SPI_SR; + sam_backup[idx].csr[0] = SPI0->SPI_CSR[0]; + sam_backup[idx].csr[1] = SPI0->SPI_CSR[1]; + sam_backup[idx].csr[2] = SPI0->SPI_CSR[2]; + sam_backup[idx].csr[3] = SPI0->SPI_CSR[3]; + } + else + { + SPI0->SPI_MR = sam_backup[idx].mr; + SPI0->SPI_CSR[0] = sam_backup[idx].csr[0]; + SPI0->SPI_CSR[1] = sam_backup[idx].csr[1]; + SPI0->SPI_CSR[2] = sam_backup[idx].csr[2]; + SPI0->SPI_CSR[3] = sam_backup[idx].csr[3]; + } +} + +#else + +void u8g_backup_spi(uint8_t msg) +{ +} + +#endif + +// =========== u8g_pb8h1.c ============== + +/* + + u8g_pb8h1.c + + 8bit height monochrom (1 bit) page buffer + byte has horizontal orientation + + 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. + + + total buffer size is limited to 256 bytes because of the calculation inside the set pixel procedure + + 23. Sep 2012: Bug with down procedure, see FPS 1st page --> fixed (bug located in u8g_clip.c) + +*/ + +#include + +#ifdef __unix__ +#include +#endif + +/* NEW_CODE disabled, because the performance increase was too slow and not worth compared */ +/* to the increase of code size */ +/* #define NEW_CODE */ + +#ifdef __unix__ +void *u8g_buf_lower_limit; +void *u8g_buf_upper_limit; +#endif + +void u8g_pb8h1_Init(u8g_pb_t *b, void *buf, u8g_uint_t width) U8G_NOINLINE; +void u8g_pb8h1_set_pixel(u8g_pb_t *b, u8g_uint_t x, u8g_uint_t y, uint8_t color_index) U8G_NOINLINE; +void u8g_pb8h1_SetPixel(u8g_pb_t *b, const u8g_dev_arg_pixel_t * const arg_pixel) U8G_NOINLINE ; +void u8g_pb8h1_Set8PixelStd(u8g_pb_t *b, u8g_dev_arg_pixel_t *arg_pixel) U8G_NOINLINE; +uint8_t u8g_dev_pb8h1_base_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg); + + +#ifdef NEW_CODE +struct u8g_pb_h1_struct +{ + u8g_uint_t x; + u8g_uint_t y; + uint8_t *ptr; + uint8_t mask; + uint8_t line_byte_len; + uint8_t cnt; +}; + +static uint8_t u8g_pb8h1_bitmask[8] = { 0x080, 0x040, 0x020, 0x010, 0x008, 0x004, 0x002, 0x001 }; + +static void u8g_pb8h1_state_right(struct u8g_pb_h1_struct *s) U8G_NOINLINE; +static void u8g_pb8h1_state_right(struct u8g_pb_h1_struct *s) +{ + register u8g_uint_t x; + x = s->x; + x++; + s->x = x; + x &= 7; + s->mask = u8g_pb8h1_bitmask[x]; + if ( x == 0 ) + s->ptr++; +} + +static void u8g_pb8h1_state_left(struct u8g_pb_h1_struct *s) +{ + register u8g_uint_t x; + x = s->x; + x--; + s->x = x; + x &= 7; + s->mask = u8g_pb8h1_bitmask[x]; + if ( x == 7 ) + s->ptr--; +} + +static void u8g_pb8h1_state_down(struct u8g_pb_h1_struct *s) +{ + s->y++; + s->ptr += s->line_byte_len; +} + +static void u8g_pb8h1_state_up(struct u8g_pb_h1_struct *s) +{ + s->y--; + s->ptr -= s->line_byte_len; +} + +static void u8g_pb8h1_state_init(struct u8g_pb_h1_struct *s, u8g_pb_t *b, u8g_uint_t x, u8g_uint_t y) U8G_NOINLINE; +static void u8g_pb8h1_state_init(struct u8g_pb_h1_struct *s, u8g_pb_t *b, u8g_uint_t x, u8g_uint_t y) +{ + u8g_uint_t tmp; + + uint8_t *ptr = b->buf; + + s->x = x; + s->y = y; + + y -= b->p.page_y0; + + tmp = b->width; + tmp >>= 3; + s->line_byte_len = tmp; + + /* assume negative y values, can be down to -7, subtract this from the pointer and add correction of 8 to y */ + ptr -= tmp*8; + y+=8; + /* it is important that the result of tmp*y can be 16 bit value also for 8 bit mode */ + ptr += tmp*y; + + s->mask = u8g_pb8h1_bitmask[x & 7]; + + /* assume negative x values (to -7), subtract 8 pixel from the pointer and add 8 to x */ + ptr--; + x += 8; + x >>= 3; + ptr += x; + s->ptr = ptr; +} + +static void u8g_pb8h1_state_set_pixel(struct u8g_pb_h1_struct *s, uint8_t color_index) U8G_NOINLINE; +static void u8g_pb8h1_state_set_pixel(struct u8g_pb_h1_struct *s, uint8_t color_index) +{ + +#ifdef __unix__ + assert( s->ptr >= u8g_buf_lower_limit ); + assert( s->ptr < u8g_buf_upper_limit ); +#endif + + if ( color_index ) + { + *s->ptr |= s->mask; + } + else + { + uint8_t mask = s->mask; + mask ^=0xff; + *s->ptr &= mask; + } +} +#endif + + +void u8g_pb8h1_Init(u8g_pb_t *b, void *buf, u8g_uint_t width) +{ + b->buf = buf; + b->width = width; + u8g_pb_Clear(b); +} + +/* limitation: total buffer must not exceed 256 bytes */ +void u8g_pb8h1_set_pixel(u8g_pb_t *b, u8g_uint_t x, u8g_uint_t y, uint8_t color_index) +{ +#ifdef NEW_CODE + struct u8g_pb_h1_struct s; + u8g_pb8h1_state_init(&s, b, x, y); + u8g_pb8h1_state_set_pixel(&s, color_index); + +// u8g_pb8h1_state_up(&s); +// if ( s.y > b->p.page_y1 ) +// return; +// if ( s.x > b->width ) +// return; +// u8g_pb8h1_state_set_pixel(&s, color_index); +#else + register uint8_t mask; + u8g_uint_t tmp; + uint8_t *ptr = (uint8_t*)b->buf; + + y -= b->p.page_y0; + tmp = b->width; + tmp >>= 3; + tmp *= (uint8_t)y; + ptr += tmp; + + mask = 0x080; + mask >>= x & 7; + x >>= 3; + ptr += x; + if ( color_index ) + { + *ptr |= mask; + } + else + { + mask ^=0xff; + *ptr &= mask; + } +#endif +} + + +void u8g_pb8h1_SetPixel(u8g_pb_t *b, const u8g_dev_arg_pixel_t * const arg_pixel) +{ + if ( arg_pixel->y < b->p.page_y0 ) + return; + if ( arg_pixel->y > b->p.page_y1 ) + return; + if ( arg_pixel->x >= b->width ) + return; + u8g_pb8h1_set_pixel(b, arg_pixel->x, arg_pixel->y, arg_pixel->color); +} + +void u8g_pb8h1_Set8PixelStd(u8g_pb_t *b, u8g_dev_arg_pixel_t *arg_pixel) +{ + register uint8_t pixel = arg_pixel->pixel; + do + { + if ( pixel & 128 ) + { + u8g_pb8h1_SetPixel(b, arg_pixel); + } + switch( arg_pixel->dir ) + { + case 0: arg_pixel->x++; break; + case 1: arg_pixel->y++; break; + case 2: arg_pixel->x--; break; + case 3: arg_pixel->y--; break; + } + pixel <<= 1; + } while( pixel != 0 ); +} + +void u8g_pb8h1_Set8PixelOpt2(u8g_pb_t *b, u8g_dev_arg_pixel_t *arg_pixel) +{ + register uint8_t pixel = arg_pixel->pixel; + u8g_uint_t dx = 0; + u8g_uint_t dy = 0; + + switch( arg_pixel->dir ) + { + case 0: dx++; break; + case 1: dy++; break; + case 2: dx--; break; + case 3: dy--; break; + } + + do + { + if ( pixel & 128 ) + u8g_pb8h1_SetPixel(b, arg_pixel); + arg_pixel->x += dx; + arg_pixel->y += dy; + pixel <<= 1; + } while( pixel != 0 ); +} + +#ifdef NEW_CODE +static void u8g_pb8h1_Set8PixelState(u8g_pb_t *b, u8g_dev_arg_pixel_t *arg_pixel) +{ + register uint8_t pixel = arg_pixel->pixel; + struct u8g_pb_h1_struct s; + uint8_t cnt; + u8g_pb8h1_state_init(&s, b, arg_pixel->x, arg_pixel->y); + cnt = 8; + switch( arg_pixel->dir ) + { + case 0: + do + { + if ( s.x < b->width ) + if ( pixel & 128 ) + u8g_pb8h1_state_set_pixel(&s, arg_pixel->color); + u8g_pb8h1_state_right(&s); + pixel <<= 1; + cnt--; + } while( cnt > 0 && pixel != 0 ); + break; + case 1: + do + { + if ( s.y >= b->p.page_y0 ) + if ( s.y <= b->p.page_y1 ) + if ( pixel & 128 ) + u8g_pb8h1_state_set_pixel(&s, arg_pixel->color); + u8g_pb8h1_state_down(&s); + pixel <<= 1; + cnt--; + } while( cnt > 0 && pixel != 0 ); + break; + case 2: + do + { + if ( s.x < b->width ) + if ( pixel & 128 ) + u8g_pb8h1_state_set_pixel(&s, arg_pixel->color); + u8g_pb8h1_state_left(&s); + pixel <<= 1; + cnt--; + } while( cnt > 0 && pixel != 0 ); + break; + case 3: + do + { + if ( s.y >= b->p.page_y0 ) + if ( s.y <= b->p.page_y1 ) + if ( pixel & 128 ) + u8g_pb8h1_state_set_pixel(&s, arg_pixel->color); + u8g_pb8h1_state_up(&s); + pixel <<= 1; + cnt--; + } while( cnt > 0 && pixel != 0 ); + break; + } +} +#endif + +uint8_t u8g_dev_pb8h1_base_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg) +{ + u8g_pb_t *pb = (u8g_pb_t *)(dev->dev_mem); + switch(msg) + { + case U8G_DEV_MSG_SET_8PIXEL: +#ifdef NEW_CODE + if ( u8g_pb_Is8PixelVisible(pb, (u8g_dev_arg_pixel_t *)arg) ) + u8g_pb8h1_Set8PixelState(pb, (u8g_dev_arg_pixel_t *)arg); +#else + if ( u8g_pb_Is8PixelVisible(pb, (u8g_dev_arg_pixel_t *)arg) ) + u8g_pb8h1_Set8PixelOpt2(pb, (u8g_dev_arg_pixel_t *)arg); +#endif + break; + case U8G_DEV_MSG_SET_PIXEL: + u8g_pb8h1_SetPixel(pb, (u8g_dev_arg_pixel_t *)arg); + break; + case U8G_DEV_MSG_INIT: + break; + case U8G_DEV_MSG_STOP: + break; + case U8G_DEV_MSG_PAGE_FIRST: + u8g_pb_Clear(pb); + u8g_page_First(&(pb->p)); + break; + case U8G_DEV_MSG_PAGE_NEXT: + if ( u8g_page_Next(&(pb->p)) == 0 ) + return 0; + u8g_pb_Clear(pb); + break; +#ifdef U8G_DEV_MSG_IS_BBX_INTERSECTION + case U8G_DEV_MSG_IS_BBX_INTERSECTION: + return u8g_pb_IsIntersection(pb, (u8g_dev_arg_bbx_t *)arg); +#endif + case U8G_DEV_MSG_GET_PAGE_BOX: + u8g_pb_GetPageBox(pb, (u8g_box_t *)arg); + break; + case U8G_DEV_MSG_GET_WIDTH: + *((u8g_uint_t *)arg) = pb->width; + break; + case U8G_DEV_MSG_GET_HEIGHT: + *((u8g_uint_t *)arg) = pb->p.total_height; + break; + case U8G_DEV_MSG_SET_COLOR_ENTRY: + break; + case U8G_DEV_MSG_SET_XY_CB: + break; + case U8G_DEV_MSG_GET_MODE: + return U8G_MODE_BW; + } + return 1; +} + +// =========== u8g_com_arduino_st7920_spi.c ============ +/* + + u8g_com_arduino_st7920_spi.c + + 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. + + A special SPI interface for ST7920 controller + + Update for ATOMIC operation done (01 Jun 2013) + U8G_ATOMIC_OR(ptr, val) + U8G_ATOMIC_AND(ptr, val) + U8G_ATOMIC_START(); + U8G_ATOMIC_END(); + + +*/ + + +#if defined(ARDUINO) + +#if defined(__AVR__) + +uint8_t u8g_bitData, u8g_bitNotData; +uint8_t u8g_bitClock, u8g_bitNotClock; +volatile uint8_t *u8g_outData; +volatile uint8_t *u8g_outClock; + +static void u8g_com_arduino_init_shift_out(uint8_t dataPin, uint8_t clockPin) +{ +#ifdef UI_SPI_MOSI + SET_OUTPUT(UI_SPI_MOSI); + SET_OUTPUT(UI_SPI_SCK); + WRITE(UI_SPI_MOSI, LOW); + WRITE(UI_SPI_SCK, HIGH); +#endif +/* + u8g_outData = portOutputRegister(digitalPinToPort(dataPin)); + u8g_outClock = portOutputRegister(digitalPinToPort(clockPin)); + u8g_bitData = digitalPinToBitMask(dataPin); + u8g_bitClock = digitalPinToBitMask(clockPin); + + u8g_bitNotClock = u8g_bitClock; + u8g_bitNotClock ^= 0x0ff; + + u8g_bitNotData = u8g_bitData; + u8g_bitNotData ^= 0x0ff; +*/ +} + +static void u8g_com_arduino_do_shift_out_msb_first(uint8_t val) U8G_NOINLINE; +static void u8g_com_arduino_do_shift_out_msb_first(uint8_t val) +{ +/* + uint8_t cnt = 8; + uint8_t bitData = u8g_bitData; + uint8_t bitNotData = u8g_bitNotData; + uint8_t bitClock = u8g_bitClock; + uint8_t bitNotClock = u8g_bitNotClock; + volatile uint8_t *outData = u8g_outData; + volatile uint8_t *outClock = u8g_outClock; + + + U8G_ATOMIC_START(); + bitData |= *outData; + bitNotData &= *outData; + do + { + if ( val & 128 ) + *outData = bitData; + else + *outData = bitNotData; + val <<= 1; + *outClock &= bitNotClock; + cnt--; + // removed micro delays, because AVRs are too slow and the delay is not required + //u8g_MicroDelay(); + *outClock |= bitClock; + //u8g_MicroDelay(); + } while( cnt != 0 ); + +*/ + U8G_ATOMIC_START(); + #ifdef UI_SPI_MOSI + + for(uint8_t cnt=0; cnt<8; cnt++ ) + { + WRITE(UI_SPI_SCK, LOW); + WRITE(UI_SPI_MOSI, val&0x80); + val<<=1; + asm volatile("nop\n\t" +"nop\n\t" +"nop\n\t" +"nop\n\t" +::); + //u8g_MicroDelay(); + WRITE(UI_SPI_SCK, HIGH); +asm volatile("nop\n\t" +"nop\n\t" +"nop\n\t" +"nop\n\t" +::); + //u8g_MicroDelay(); + } + #endif + U8G_ATOMIC_END(); +} + +#elif defined(__18CXX) || defined(__PIC32MX) + +uint16_t dog_bitData, dog_bitNotData; +uint16_t dog_bitClock, dog_bitNotClock; +volatile uint32_t *dog_outData; +volatile uint32_t *dog_outClock; +volatile uint32_t dog_pic32_spi_tmp; + +static void u8g_com_arduino_init_shift_out(uint8_t dataPin, uint8_t clockPin) +{ + dog_outData = portOutputRegister(digitalPinToPort(dataPin)); + dog_outClock = portOutputRegister(digitalPinToPort(clockPin)); + dog_bitData = digitalPinToBitMask(dataPin); + dog_bitClock = digitalPinToBitMask(clockPin); + + dog_bitNotClock = dog_bitClock; + dog_bitNotClock ^= 0x0ffff; + + dog_bitNotData = dog_bitData; + dog_bitNotData ^= 0x0ffff; +} + +static void u8g_com_arduino_do_shift_out_msb_first(uint8_t val) +{ + uint8_t cnt = 8; + U8G_ATOMIC_START(); + do + { + if ( val & 128 ) + *dog_outData |= dog_bitData; + else + *dog_outData &= dog_bitNotData; + val <<= 1; + //u8g_MicroDelay(); + //*dog_outClock |= dog_bitClock; + *dog_outClock &= dog_bitNotClock; + cnt--; + u8g_MicroDelay(); + //*dog_outClock &= dog_bitNotClock; + *dog_outClock |= dog_bitClock; + u8g_MicroDelay(); + + } while( cnt != 0 ); + U8G_ATOMIC_END(); +} + +#else + +/* default interface, Arduino DUE (__arm__) */ + +uint8_t u8g_data_pin; +uint8_t u8g_clock_pin; + +static void u8g_com_arduino_init_shift_out(uint8_t dataPin, uint8_t clockPin) +{ + u8g_data_pin = dataPin; + u8g_clock_pin = clockPin; +} + +static void u8g_com_arduino_do_shift_out_msb_first(uint8_t val) +{ + uint8_t cnt = 8; + do + { +#ifdef UI_SPI_MOSI + WRITE(UI_SPI_MOSI,val & 128); +#else + if ( val & 128 ) + digitalWrite(u8g_data_pin, HIGH); + else + digitalWrite(u8g_data_pin, LOW); +#endif + val <<= 1; + u8g_MicroDelay(); +#ifdef UI_SPI_SCK + WRITE(UI_SPI_SCK,LOW); +#else + digitalWrite(u8g_clock_pin, LOW); +#endif + cnt--; + u8g_MicroDelay(); +#ifdef UI_SPI_SCK + WRITE(UI_SPI_SCK,HIGH); +#else + digitalWrite(u8g_clock_pin, HIGH); +#endif + u8g_MicroDelay(); + } while( cnt != 0 ); +} + +#endif + + +static void u8g_com_arduino_st7920_write_byte_seq(uint8_t rs, uint8_t *ptr, uint8_t len) +{ + if ( rs == 0 ) + { + /* command */ + u8g_com_arduino_do_shift_out_msb_first(0x0f8); + } + else if ( rs == 1 ) + { + /* data */ + u8g_com_arduino_do_shift_out_msb_first(0x0fa); + } + + while( len > 0 ) + { + u8g_com_arduino_do_shift_out_msb_first(*ptr & 0x0f0); + u8g_com_arduino_do_shift_out_msb_first(*ptr << 4); + ptr++; + len--; +// u8g_10MicroDelay(); + } + +// for( i = 0; i < 4; i++ ) + u8g_10MicroDelay(); +} + +static void u8g_com_arduino_st7920_write_byte(uint8_t rs, uint8_t val) +{ + if ( rs == 0 ) + { + /* command */ + u8g_com_arduino_do_shift_out_msb_first(0x0f8); + } + else if ( rs == 1 ) + { + /* data */ + u8g_com_arduino_do_shift_out_msb_first(0x0fa); + } + + u8g_com_arduino_do_shift_out_msb_first(val & 0x0f0); + u8g_com_arduino_do_shift_out_msb_first(val << 4); + +// for( i = 0; i < 4; i++ ) + u8g_10MicroDelay(); + +} + + +uint8_t u8g_com_arduino_st7920_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) +{ + switch(msg) + { + case U8G_COM_MSG_INIT: + u8g->pin_list[U8G_PI_CS2]=U8G_PIN_NONE; + u8g_com_arduino_assign_pin_output_high(u8g); +#ifdef UI_SPI_CS + WRITE(UI_SPI_CS,LOW); +#else + u8g_com_arduino_digital_write(u8g, U8G_PI_CS, LOW); +#endif + // u8g_com_arduino_digital_write(u8g, U8G_PI_SCK, LOW); +#ifdef UI_SPI_SCK + WRITE(UI_SPI_SCK,HIGH); +#else + u8g_com_arduino_digital_write(u8g, U8G_PI_SCK, HIGH); +#endif +#ifdef UI_SPI_MOSI + WRITE(UI_SPI_MOSI,LOW); +#else + u8g_com_arduino_digital_write(u8g, U8G_PI_MOSI, LOW); +#endif + u8g_com_arduino_init_shift_out(u8g->pin_list[U8G_PI_MOSI], u8g->pin_list[U8G_PI_SCK]); + u8g->pin_list[U8G_PI_A0_STATE] = 0; /* inital RS state: command mode */ + break; + + case U8G_COM_MSG_STOP: + break; + + case U8G_COM_MSG_RESET: + if ( u8g->pin_list[U8G_PI_RESET] != U8G_PIN_NONE ) + u8g_com_arduino_digital_write(u8g, U8G_PI_RESET, arg_val); + break; + + case U8G_COM_MSG_CHIP_SELECT: +#ifdef UI_SPI_CS + WRITE(UI_SPI_CS,arg_val); +#else + if ( arg_val == 0 ) + { + /* disable, note: the st7920 has an active high chip select */ + u8g_com_arduino_digital_write(u8g, U8G_PI_CS, LOW); + } + else + { + /* enable */ + //u8g_com_arduino_digital_write(u8g, U8G_PI_SCK, HIGH); + u8g_com_arduino_digital_write(u8g, U8G_PI_CS, HIGH); + } +#endif + break; + + case U8G_COM_MSG_WRITE_BYTE: + u8g_com_arduino_st7920_write_byte( u8g->pin_list[U8G_PI_A0_STATE], arg_val); + //u8g->pin_list[U8G_PI_A0_STATE] = 2; + //u8g_arduino_sw_spi_shift_out(u8g->pin_list[U8G_PI_MOSI], u8g->pin_list[U8G_PI_SCK], arg_val); + break; + + case U8G_COM_MSG_WRITE_SEQ: + u8g_com_arduino_st7920_write_byte_seq(u8g->pin_list[U8G_PI_A0_STATE], (uint8_t *)arg_ptr, arg_val); + break; + + case U8G_COM_MSG_WRITE_SEQ_P: + { + register uint8_t *ptr = (uint8_t*)arg_ptr; + while( arg_val > 0 ) + { + u8g_com_arduino_st7920_write_byte(u8g->pin_list[U8G_PI_A0_STATE], u8g_pgm_read(ptr) ); + //u8g->pin_list[U8G_PI_A0_STATE] = 2; + ptr++; + arg_val--; + } + } + break; + + case U8G_COM_MSG_ADDRESS: /* define cmd (arg_val = 0) or data mode (arg_val = 1) */ + u8g->pin_list[U8G_PI_A0_STATE] = arg_val; + break; + } + return 1; +} + +#else /* ARDUINO */ + +uint8_t u8g_com_arduino_st7920_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) +{ + return 1; +} + +#endif /* ARDUINO */ + +// ============= u8g_com_arduino_common.c ============= +/* + + u8g_com_arduino_common.c + + shared procedures for the arduino communication procedures + + 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. + + +*/ + + +#if defined(ARDUINO) + + +void u8g_com_arduino_digital_write(u8g_t *u8g, uint8_t pin_index, uint8_t value) +{ + uint8_t pin; + pin = u8g->pin_list[pin_index]; + if ( pin != U8G_PIN_NONE ) + digitalWrite(pin, value); +} + +/* this procedure does not set the RW pin */ +void u8g_com_arduino_assign_pin_output_high(u8g_t *u8g) +{ + uint8_t i; + /* skip the RW pin, which is the last pin in the list */ + for( i = 0; i < U8G_PIN_LIST_LEN-1; i++ ) + { + if ( u8g->pin_list[i] != U8G_PIN_NONE ) + { + pinMode(u8g->pin_list[i], OUTPUT); + digitalWrite(u8g->pin_list[i], HIGH); + } + } +} + + +#endif + +/* + + u8g_pb.c + + common procedures for the page buffer + + 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. + + +*/ + + +void u8g_pb_Clear(u8g_pb_t *b) +{ + uint8_t *ptr = (uint8_t *)b->buf; + uint8_t *end_ptr = ptr; + end_ptr += b->width; + do + { + *ptr++ = 0; + } while( ptr != end_ptr ); +} + +/* the following procedure does not work. why? Can be checked with descpic */ +/* +void u8g_pb_Clear(u8g_pb_t *b) +{ + uint8_t *ptr = (uint8_t *)b->buf; + uint8_t cnt = b->width; + do + { + *ptr++ = 0; + cnt--; + } while( cnt != 0 ); +} +*/ + +/* + intersection assumptions: + a1 <= a2 is always true +*/ + /* + minimized version + ---1----0 1 b1 <= a2 && b1 > b2 + -----1--0 1 b2 >= a1 && b1 > b2 + ---1-1--- 1 b1 <= a2 && b2 >= a1 + */ +/* +uint8_t u8g_pb8v1_IsYIntersection___Old(u8g_pb_t *b, u8g_uint_t v0, u8g_uint_t v1) +{ + uint8_t c0, c1, c; + c0 = v0 <= b->p.page_y1; + c1 = v1 >= b->p.page_y0; + c = v0 > v1; + if ( c0 && c1 ) return 1; + if ( c0 && c ) return 1; + if ( c1 && c ) return 1; + return 0; +} +*/ + +uint8_t u8g_pb_IsYIntersection(u8g_pb_t *pb, u8g_uint_t v0, u8g_uint_t v1) +{ + uint8_t c1, c2, c3, tmp; + c1 = v0 <= pb->p.page_y1; + c2 = v1 >= pb->p.page_y0; + c3 = v0 > v1; + /* + if ( c1 && c2 ) + return 1; + if ( c1 && c3 ) + return 1; + if ( c2 && c3 ) + return 1; + return 0; + */ + + tmp = c1; + c1 &= c2; + c2 &= c3; + c3 &= tmp; + c1 |= c2; + c1 |= c3; + return c1 & 1; +} + + +uint8_t u8g_pb_IsXIntersection(u8g_pb_t *b, u8g_uint_t v0, u8g_uint_t v1) +{ + uint8_t /*c0, c1, */ c2, c3; + /* + conditions: b->p.page_y0 < b->p.page_y1 + there are no restriction on v0 and v1. If v0 > v1, then warp around unsigned is assumed + */ + /* + c0 = v0 < 0; + c1 = v1 < 0; + */ + c2 = v0 > b->width; + c3 = v1 > b->width; + /*if ( c0 && c1 ) return 0;*/ + if ( c2 && c3 ) return 0; + /*if ( c1 && c2 ) return 0;*/ + return 1; +} + +uint8_t u8g_pb_IsIntersection(u8g_pb_t *pb, u8g_dev_arg_bbx_t *bbx) +{ + u8g_uint_t tmp; + + tmp = bbx->y; + tmp += bbx->h; + tmp--; + + if ( u8g_pb_IsYIntersection(pb, bbx->y, tmp) == 0 ) + return 0; + + /* maybe this one can be skiped... probability is very high to have an intersection, so it would be ok to always return 1 */ + tmp = bbx->x; + tmp += bbx->w; + tmp--; + + return u8g_pb_IsXIntersection(pb, bbx->x, tmp); +} + +void u8g_pb_GetPageBox(u8g_pb_t *pb, u8g_box_t *box) +{ + box->x0 = 0; + box->y0 = pb->p.page_y0; + box->x1 = pb->width; + box->x1--; + box->y1 = pb->p.page_y1; +} + + +uint8_t u8g_pb_Is8PixelVisible(u8g_pb_t *b, u8g_dev_arg_pixel_t *arg_pixel) +{ + u8g_uint_t v0, v1; + v0 = arg_pixel->y; + v1 = v0; + switch( arg_pixel->dir ) + { + case 0: + break; + case 1: + v1 += 8; /* this is independent from the page height */ + break; + case 2: + break; + case 3: + v0 -= 8; + break; + } + return u8g_pb_IsYIntersection(b, v0, v1); +} + + + +uint8_t u8g_pb_WriteBuffer(u8g_pb_t *b, u8g_t *u8g, u8g_dev_t *dev) +{ + return u8g_WriteSequence(u8g, dev, b->width,(uint8_t*) b->buf); +} + +/* + + u8g_rect.c + + U8G high level interface for horizontal and vertical things + + 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. + + +*/ + +void u8g_draw_hline(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, u8g_uint_t w) +{ + uint8_t pixel = 0x0ff; + while( w >= 8 ) + { + u8g_Draw8Pixel(u8g, x, y, 0, pixel); + w-=8; + x+=8; + } + if ( w != 0 ) + { + w ^=7; + w++; + pixel <<= w&7; + u8g_Draw8Pixel(u8g, x, y, 0, pixel); + } +} + +void u8g_draw_vline(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, u8g_uint_t h) +{ + uint8_t pixel = 0x0ff; + while( h >= 8 ) + { + u8g_Draw8Pixel(u8g, x, y, 1, pixel); + h-=8; + y+=8; + } + if ( h != 0 ) + { + h ^=7; + h++; + pixel <<= h&7; + u8g_Draw8Pixel(u8g, x, y, 1, pixel); + } +} + +void u8g_DrawHLine(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, u8g_uint_t w) +{ + if ( u8g_IsBBXIntersection(u8g, x, y, w, 1) == 0 ) + return; + u8g_draw_hline(u8g, x, y, w); +} + +void u8g_DrawVLine(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, u8g_uint_t w) +{ + if ( u8g_IsBBXIntersection(u8g, x, y, 1, w) == 0 ) + return; + u8g_draw_vline(u8g, x, y, w); +} + +/* restrictions: w > 0 && h > 0 */ +void u8g_DrawFrame(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, u8g_uint_t w, u8g_uint_t h) +{ + u8g_uint_t xtmp = x; + + if ( u8g_IsBBXIntersection(u8g, x, y, w, h) == 0 ) + return; + + + u8g_draw_hline(u8g, x, y, w); + u8g_draw_vline(u8g, x, y, h); + x+=w; + x--; + u8g_draw_vline(u8g, x, y, h); + y+=h; + y--; + u8g_draw_hline(u8g, xtmp, y, w); +} + +void u8g_draw_box(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, u8g_uint_t w, u8g_uint_t h) +{ + do + { + u8g_draw_hline(u8g, x, y, w); + y++; + h--; + } while( h != 0 ); +} + +/* restrictions: h > 0 */ +void u8g_DrawBox(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, u8g_uint_t w, u8g_uint_t h) +{ + if ( u8g_IsBBXIntersection(u8g, x, y, w, h) == 0 ) + return; + u8g_draw_box(u8g, x, y, w, h); +} + + +void u8g_DrawRFrame(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, u8g_uint_t w, u8g_uint_t h, u8g_uint_t r) +{ + u8g_uint_t xl, yu; + + if ( u8g_IsBBXIntersection(u8g, x, y, w, h) == 0 ) + return; + + xl = x; + xl += r; + yu = y; + yu += r; + + { + u8g_uint_t yl, xr; + + xr = x; + xr += w; + xr -= r; + xr -= 1; + + yl = y; + yl += h; + yl -= r; + yl -= 1; + + u8g_draw_circle(u8g, xl, yu, r, U8G_DRAW_UPPER_LEFT); + u8g_draw_circle(u8g, xr, yu, r, U8G_DRAW_UPPER_RIGHT); + u8g_draw_circle(u8g, xl, yl, r, U8G_DRAW_LOWER_LEFT); + u8g_draw_circle(u8g, xr, yl, r, U8G_DRAW_LOWER_RIGHT); + } + + { + u8g_uint_t ww, hh; + + ww = w; + ww -= r; + ww -= r; + ww -= 2; + hh = h; + hh -= r; + hh -= r; + hh -= 2; + + xl++; + yu++; + h--; + w--; + u8g_draw_hline(u8g, xl, y, ww); + u8g_draw_hline(u8g, xl, y+h, ww); + u8g_draw_vline(u8g, x, yu, hh); + u8g_draw_vline(u8g, x+w, yu, hh); + } +} + +void u8g_DrawRBox(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, u8g_uint_t w, u8g_uint_t h, u8g_uint_t r) +{ + u8g_uint_t xl, yu; + u8g_uint_t yl, xr; + + if ( u8g_IsBBXIntersection(u8g, x, y, w, h) == 0 ) + return; + + xl = x; + xl += r; + yu = y; + yu += r; + + xr = x; + xr += w; + xr -= r; + xr -= 1; + + yl = y; + yl += h; + yl -= r; + yl -= 1; + + u8g_draw_disc(u8g, xl, yu, r, U8G_DRAW_UPPER_LEFT); + u8g_draw_disc(u8g, xr, yu, r, U8G_DRAW_UPPER_RIGHT); + u8g_draw_disc(u8g, xl, yl, r, U8G_DRAW_LOWER_LEFT); + u8g_draw_disc(u8g, xr, yl, r, U8G_DRAW_LOWER_RIGHT); + + { + u8g_uint_t ww, hh; + + ww = w; + ww -= r; + ww -= r; + ww -= 2; + hh = h; + hh -= r; + hh -= r; + hh -= 2; + + xl++; + yu++; + h--; + u8g_draw_box(u8g, xl, y, ww, r+1); + u8g_draw_box(u8g, xl, yl, ww, r+1); + //u8g_draw_hline(u8g, xl, y+h, ww); + u8g_draw_box(u8g, x, yu, w, hh); + //u8g_draw_vline(u8g, x+w, yu, hh); + } +} + +// ============ u8g_com_arduino_ssd_i2c.c ================= + +/* + + u8g_com_arduino_ssd_i2c.c + + com interface for arduino (AND atmega) and the SSDxxxx chip (SOLOMON) variant + I2C protocol + + ToDo: Rename this to u8g_com_avr_ssd_i2c.c + + Universal 8bit Graphics Library + + Copyright (c) 2012, 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. + + Special pin usage: + U8G_PI_I2C_OPTION additional options + U8G_PI_A0_STATE used to store the last value of the command/data register selection + U8G_PI_SET_A0 1: Signal request to update I2C device with new A0_STATE, 0: Do nothing, A0_STATE matches I2C device + U8G_PI_SCL clock line (NOT USED) + U8G_PI_SDA data line (NOT USED) + + U8G_PI_RESET reset line (currently disabled, see below) + + Protocol: + SLA, Cmd/Data Selection, Arguments + The command/data register is selected by a special instruction byte, which is sent after SLA + + The continue bit is always 0 so that a (re)start is equired for the change from cmd to/data mode +*/ + + +#if defined(U8G_WITH_PINLIST) + + +#define I2C_SLA (0x3c*2) +//#define I2C_CMD_MODE 0x080 +#define I2C_CMD_MODE 0x000 +#define I2C_DATA_MODE 0x040 + +uint8_t u8g_com_arduino_ssd_start_sequence(u8g_t *u8g) +{ + /* are we requested to set the a0 state? */ + if ( u8g->pin_list[U8G_PI_SET_A0] == 0 ) + return 1; + + /* setup bus, might be a repeated start */ + if ( u8g_i2c_start(I2C_SLA) == 0 ) + return 0; + if ( u8g->pin_list[U8G_PI_A0_STATE] == 0 ) + { + if ( u8g_i2c_send_byte(I2C_CMD_MODE) == 0 ) + return 0; + } + else + { + if ( u8g_i2c_send_byte(I2C_DATA_MODE) == 0 ) + return 0; + } + + u8g->pin_list[U8G_PI_SET_A0] = 0; + return 1; +} + +uint8_t u8g_com_arduino_ssd_i2c_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) +{ + switch(msg) + { + case U8G_COM_MSG_INIT: + //u8g_com_arduino_digital_write(u8g, U8G_PI_SCL, HIGH); + //u8g_com_arduino_digital_write(u8g, U8G_PI_SDA, HIGH); + //u8g->pin_list[U8G_PI_A0_STATE] = 0; /* inital RS state: unknown mode */ + + u8g_i2c_init(u8g->pin_list[U8G_PI_I2C_OPTION]); + + break; + + case U8G_COM_MSG_STOP: + break; + + case U8G_COM_MSG_RESET: + /* Currently disabled, but it could be enable. Previous restrictions have been removed */ + /* u8g_com_arduino_digital_write(u8g, U8G_PI_RESET, arg_val); */ + break; + + case U8G_COM_MSG_CHIP_SELECT: + u8g->pin_list[U8G_PI_A0_STATE] = 0; + u8g->pin_list[U8G_PI_SET_A0] = 1; /* force a0 to set again, also forces start condition */ + if ( arg_val == 0 ) + { + /* disable chip, send stop condition */ + u8g_i2c_stop(); + } + else + { + /* enable, do nothing: any byte writing will trigger the i2c start */ + } + break; + + case U8G_COM_MSG_WRITE_BYTE: + //u8g->pin_list[U8G_PI_SET_A0] = 1; + if ( u8g_com_arduino_ssd_start_sequence(u8g) == 0 ) + return u8g_i2c_stop(), 0; + if ( u8g_i2c_send_byte(arg_val) == 0 ) + return u8g_i2c_stop(), 0; + // u8g_i2c_stop(); + break; + + case U8G_COM_MSG_WRITE_SEQ: + //u8g->pin_list[U8G_PI_SET_A0] = 1; + if ( u8g_com_arduino_ssd_start_sequence(u8g) == 0 ) + return u8g_i2c_stop(), 0; + { + register uint8_t *ptr = (uint8_t*)arg_ptr; + while( arg_val > 0 ) + { + if ( u8g_i2c_send_byte(*ptr++) == 0 ) + return u8g_i2c_stop(), 0; + arg_val--; + } + } + // u8g_i2c_stop(); + break; + + case U8G_COM_MSG_WRITE_SEQ_P: + //u8g->pin_list[U8G_PI_SET_A0] = 1; + if ( u8g_com_arduino_ssd_start_sequence(u8g) == 0 ) + return u8g_i2c_stop(), 0; + { + register uint8_t *ptr = (uint8_t*)arg_ptr; + while( arg_val > 0 ) + { + if ( u8g_i2c_send_byte(u8g_pgm_read(ptr)) == 0 ) + return 0; + ptr++; + arg_val--; + } + } + // u8g_i2c_stop(); + break; + + case U8G_COM_MSG_ADDRESS: /* define cmd (arg_val = 0) or data mode (arg_val = 1) */ + u8g->pin_list[U8G_PI_A0_STATE] = arg_val; + u8g->pin_list[U8G_PI_SET_A0] = 1; /* force a0 to set again */ + +#ifdef OLD_CODE + if ( i2c_state != 0 ) + { + u8g_i2c_stop(); + i2c_state = 0; + } + + if ( u8g_com_arduino_ssd_start_sequence(arg_val) == 0 ) + return 0; + + /* setup bus, might be a repeated start */ + /* + if ( u8g_i2c_start(I2C_SLA) == 0 ) + return 0; + if ( arg_val == 0 ) + { + i2c_state = 1; + + if ( u8g_i2c_send_byte(I2C_CMD_MODE) == 0 ) + return 0; + } + else + { + i2c_state = 2; + if ( u8g_i2c_send_byte(I2C_DATA_MODE) == 0 ) + return 0; + } + */ +#endif + break; + } + return 1; +} + +#else /* defined(U8G_WITH_PINLIST) */ + +uint8_t u8g_com_arduino_ssd_i2c_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) +{ + return 1; +} + +#endif /* defined(U8G_WITH_PINLIST) */ + +// ============ u8g_com_i2c.c =============== + +/* + + u8g_com_i2c.c + + generic i2c interface + + 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. + +*/ + + +//#define U8G_I2C_WITH_NO_ACK + +static uint8_t u8g_i2c_err_code; +static uint8_t u8g_i2c_opt; /* U8G_I2C_OPT_NO_ACK, SAM: U8G_I2C_OPT_DEV_1 */ +/* + position values + 1: start condition + 2: sla transfer +*/ +static uint8_t u8g_i2c_err_pos; + + +void u8g_i2c_clear_error(void) +{ + u8g_i2c_err_code = U8G_I2C_ERR_NONE; + u8g_i2c_err_pos = 0; +} + +uint8_t u8g_i2c_get_error(void) +{ + return u8g_i2c_err_code; +} + +uint8_t u8g_i2c_get_err_pos(void) +{ + return u8g_i2c_err_pos; +} + +static void u8g_i2c_set_error(uint8_t code, uint8_t pos) +{ + if ( u8g_i2c_err_code > 0 ) + return; + u8g_i2c_err_code |= code; + u8g_i2c_err_pos = pos; +} + + + +#if defined(__AVR__) +#define U8G_ATMEGA_HW_TWI + +/* remove the definition for attiny */ +#if __AVR_ARCH__ == 2 +#undef U8G_ATMEGA_HW_TWI +#endif +#if __AVR_ARCH__ == 25 +#undef U8G_ATMEGA_HW_TWI +#endif +#endif + +#if defined(U8G_ATMEGA_HW_TWI) + +#include +#include + + + +void u8g_i2c_init(uint8_t options) +{ + /* + TWBR: bit rate register + TWSR: status register (contains preselector bits) + + prescalar + 0 1 + 1 4 + 2 16 + 3 64 + + f = F_CPU/(16+2*TWBR*prescalar) + + F_CPU = 16MHz + TWBR = 152; + TWSR = 0; + --> 50KHz + + TWBR = 72; + TWSR = 0; + --> 100KHz + + TWBR = 12; + TWSR = 0; + --> 400KHz + + F_CPU/(2*100000)-8 --> calculate TWBR value for 100KHz +*/ + u8g_i2c_opt = options; + TWSR = 0; + if ( options & U8G_I2C_OPT_FAST ) + { + TWBR = F_CPU/(2*400000)-8; + } + else + { + TWBR = F_CPU/(2*100000)-8; + } + u8g_i2c_clear_error(); +} + +uint8_t u8g_i2c_wait(uint8_t mask, uint8_t pos) +{ + volatile uint16_t cnt = 2000; /* timout value should be > 280 for 50KHz Bus and 16 Mhz CPU, however the start condition might need longer */ + while( !(TWCR & mask) ) + { + if ( cnt == 0 ) + { + if ( u8g_i2c_opt & U8G_I2C_OPT_NO_ACK ) + { + return 1; /* all ok */ + } + else + { + u8g_i2c_set_error(U8G_I2C_ERR_TIMEOUT, pos); + return 0; /* error */ + } + } + cnt--; + } + return 1; /* all ok */ +} + +/* sla includes all 8 bits (with r/w bit), assums master transmit */ +uint8_t u8g_i2c_start(uint8_t sla) +{ + register uint8_t status; + + /* send start */ + TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN); + + /* wait */ + if ( u8g_i2c_wait(_BV(TWINT), 1) == 0 ) + return 0; + + status = TW_STATUS; + + /* check status after start */ + if ( status != TW_START && status != TW_REP_START ) + { + u8g_i2c_set_error(U8G_I2C_ERR_BUS, 1); + return 0; + } + + /* set slave address */ + TWDR = sla; + + /* enable sla transfer */ + TWCR = _BV(TWINT) | _BV(TWEN); + + /* wait */ + if ( u8g_i2c_wait(_BV(TWINT), 2) == 0 ) + return 0; + + if ( u8g_i2c_opt & U8G_I2C_OPT_NO_ACK ) + { + /* do not check for ACK */ + } + else + { + status = TW_STATUS; + /* check status after sla */ + if ( status != TW_MT_SLA_ACK ) + { + u8g_i2c_set_error(U8G_I2C_ERR_BUS, 2); + return 0; + } + } + + return 1; +} + +uint8_t u8g_i2c_send_byte(uint8_t data) +{ + register uint8_t status; + TWDR = data; + TWCR = _BV(TWINT) | _BV(TWEN); + if ( u8g_i2c_wait(_BV(TWINT), 3) == 0 ) + return 0; + + if ( u8g_i2c_opt & U8G_I2C_OPT_NO_ACK ) + { + /* do not check for ACK */ + } + else + { + status = TW_STATUS; + if ( status != TW_MT_DATA_ACK ) + { + u8g_i2c_set_error(U8G_I2C_ERR_BUS, 3); + return 0; + } + } + + return 1; +} + +void u8g_i2c_stop(void) +{ + /* write stop */ + TWCR = _BV(TWINT) | _BV(TWEN) | _BV(TWSTO); + + /* no error is checked for the stop condition */ + u8g_i2c_wait(_BV(TWSTO), 4); + +} + +/* +void twi_send(uint8_t adr, uint8_t data1, uint8_t data2) +{ + u8g_i2c_start(adr<<1); + u8g_i2c_send_byte(data1); + u8g_i2c_send_byte(data2); + u8g_i2c_stop(); +} +*/ + +#elif defined(ARDUINO) && defined(__SAM3X8E__) +/* Arduino Due */ +#include "Arduino.h" +#include "sam.h" + +/* + +Controller + +TWI0 TWCK0 PA18 A DUE PCB: SCL1 +TWI0 TWD0 PA17 A DUE PCB: SDA1 +TWI1 TWCK1 PB13 A DUE PCB: SCL 21 +TWI1 TWD1 PB12 A DUE PCB: SDA 20 + +Arduino definitions + +#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 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 + + +*/ + +static void i2c_400KHz_delay(void) +{ + /* should be at least 4 */ + /* should be 5 for 100KHz transfer speed */ + + + /* + Arduino Due + 0x NOP: 470KHz + 4x NOP: 450KHz + 8x NOP: 430KHz + 16x NOP: 400KHz + */ + + __NOP(); + __NOP(); + __NOP(); + __NOP(); + + __NOP(); + __NOP(); + __NOP(); + __NOP(); + + __NOP(); + __NOP(); + __NOP(); + __NOP(); + + __NOP(); + __NOP(); + __NOP(); + __NOP(); +} + +static void i2c_100KHz_delay(void) +{ + /* + 1x u8g_MicroDelay() ca. 130KHz + 2x u8g_MicroDelay() ca. 80KHz + */ + u8g_MicroDelay(); + u8g_MicroDelay(); +} + + +uint32_t i2c_started = 0; +uint32_t i2c_scl_pin = 0; +uint32_t i2c_sda_pin = 0; +void (*i2c_delay)(void) = i2c_100KHz_delay; + +const PinDescription *i2c_scl_pin_desc; +const PinDescription *i2c_sda_pin_desc; + + +/* maybe this can be optimized */ +static void i2c_init(void) +{ + i2c_sda_pin_desc = &(g_APinDescription[i2c_sda_pin]); + i2c_scl_pin_desc = &(g_APinDescription[i2c_scl_pin]); + pinMode(i2c_sda_pin, OUTPUT); + digitalWrite(i2c_sda_pin, HIGH); + pinMode(i2c_scl_pin, OUTPUT); + digitalWrite(i2c_scl_pin, HIGH); + PIO_Configure( i2c_sda_pin_desc->pPort, PIO_OUTPUT_0, i2c_sda_pin_desc->ulPin, PIO_OPENDRAIN ); + PIO_Configure( i2c_scl_pin_desc->pPort, PIO_OUTPUT_0, i2c_scl_pin_desc->ulPin, PIO_OPENDRAIN ); + PIO_Clear( i2c_sda_pin_desc->pPort, i2c_sda_pin_desc->ulPin) ; + PIO_Clear( i2c_scl_pin_desc->pPort, i2c_scl_pin_desc->ulPin) ; + PIO_Configure( i2c_sda_pin_desc->pPort, PIO_INPUT, i2c_sda_pin_desc->ulPin, PIO_DEFAULT ) ; + PIO_Configure( i2c_scl_pin_desc->pPort, PIO_INPUT, i2c_scl_pin_desc->ulPin, PIO_DEFAULT ) ; + i2c_delay(); +} + +/* actually, the scl line is not observed, so this procedure does not return a value */ +static void i2c_read_scl_and_delay(void) +{ + uint32_t dwMask = i2c_scl_pin_desc->ulPin; + //PIO_Configure( i2c_scl_pin_desc->pPort, PIO_INPUT, i2c_scl_pin_desc->ulPin, PIO_DEFAULT ) ; + //PIO_SetInput( i2c_scl_pin_desc->pPort, i2c_scl_pin_desc->ulPin, PIO_DEFAULT ) ; + + /* set as input */ + i2c_scl_pin_desc->pPort->PIO_ODR = dwMask ; + i2c_scl_pin_desc->pPort->PIO_PER = dwMask ; + + i2c_delay(); +} + +static void i2c_clear_scl(void) +{ + uint32_t dwMask = i2c_scl_pin_desc->ulPin; + + /* set open collector and drive low */ + //PIO_Configure( i2c_scl_pin_desc->pPort, PIO_OUTPUT_0, i2c_scl_pin_desc->ulPin, PIO_OPENDRAIN ); + //PIO_SetOutput( i2c_scl_pin_desc->pPort, i2c_scl_pin_desc->ulPin, 0, 1, 0); + + /* open drain, zero default output */ + i2c_scl_pin_desc->pPort->PIO_MDER = dwMask; + i2c_scl_pin_desc->pPort->PIO_CODR = dwMask; + i2c_scl_pin_desc->pPort->PIO_OER = dwMask; + i2c_scl_pin_desc->pPort->PIO_PER = dwMask; + + //PIO_Clear( i2c_scl_pin_desc->pPort, i2c_scl_pin_desc->ulPin) ; +} + +static uint8_t i2c_read_sda(void) +{ + uint32_t dwMask = i2c_sda_pin_desc->ulPin; + //PIO_Configure( i2c_sda_pin_desc->pPort, PIO_INPUT, i2c_sda_pin_desc->ulPin, PIO_DEFAULT ) ; + //PIO_SetInput( i2c_sda_pin_desc->pPort, i2c_sda_pin_desc->ulPin, PIO_DEFAULT ) ; + + /* set as input */ + i2c_sda_pin_desc->pPort->PIO_ODR = dwMask ; + i2c_sda_pin_desc->pPort->PIO_PER = dwMask ; + + + return 1; +} + +static void i2c_clear_sda(void) +{ + uint32_t dwMask = i2c_sda_pin_desc->ulPin; + + /* set open collector and drive low */ + //PIO_Configure( i2c_sda_pin_desc->pPort, PIO_OUTPUT_0, i2c_sda_pin_desc->ulPin, PIO_OPENDRAIN ); + //PIO_SetOutput( i2c_sda_pin_desc->pPort, i2c_sda_pin_desc->ulPin, 0, 1, 0); + + /* open drain, zero default output */ + i2c_sda_pin_desc->pPort->PIO_MDER = dwMask ; + i2c_sda_pin_desc->pPort->PIO_CODR = dwMask ; + i2c_sda_pin_desc->pPort->PIO_OER = dwMask ; + i2c_sda_pin_desc->pPort->PIO_PER = dwMask ; + + //PIO_Clear( i2c_sda_pin_desc->pPort, i2c_sda_pin_desc->ulPin) ; +} + +static void i2c_start(void) +{ + if ( i2c_started != 0 ) + { + /* if already started: do restart */ + i2c_read_sda(); /* SDA = 1 */ + i2c_delay(); + i2c_read_scl_and_delay(); + } + i2c_read_sda(); + /* + if (i2c_read_sda() == 0) + { + // do something because arbitration is lost + } + */ + /* send the start condition, both lines go from 1 to 0 */ + i2c_clear_sda(); + i2c_delay(); + i2c_clear_scl(); + i2c_started = 1; +} + + +static void i2c_stop(void) +{ + /* set SDA to 0 */ + i2c_clear_sda(); + i2c_delay(); + + /* now release all lines */ + i2c_read_scl_and_delay(); + + /* set SDA to 1 */ + i2c_read_sda(); + i2c_delay(); + i2c_started = 0; +} + +static void i2c_write_bit(uint8_t val) +{ + if (val) + i2c_read_sda(); + else + i2c_clear_sda(); + + i2c_delay(); + i2c_read_scl_and_delay(); + i2c_clear_scl(); +} + +static uint8_t i2c_read_bit(void) +{ + uint8_t val; + /* do not drive SDA */ + i2c_read_sda(); + i2c_delay(); + i2c_read_scl_and_delay(); + val = i2c_read_sda(); + i2c_delay(); + i2c_clear_scl(); + return val; +} + +static uint8_t i2c_write_byte(uint8_t b) +{ + i2c_write_bit(b & 128); + i2c_write_bit(b & 64); + i2c_write_bit(b & 32); + i2c_write_bit(b & 16); + i2c_write_bit(b & 8); + i2c_write_bit(b & 4); + i2c_write_bit(b & 2); + i2c_write_bit(b & 1); + + /* read ack from client */ + /* 0: ack was given by client */ + /* 1: nothing happend during ack cycle */ + return i2c_read_bit(); +} + + + +void u8g_i2c_init(uint8_t options) +{ + u8g_i2c_opt = options; + u8g_i2c_clear_error(); + + if ( u8g_i2c_opt & U8G_I2C_OPT_FAST ) + { + i2c_delay = i2c_400KHz_delay; + } + else + { + i2c_delay = i2c_100KHz_delay; + } + + + if ( u8g_i2c_opt & U8G_I2C_OPT_DEV_1 ) + { + i2c_scl_pin = PIN_WIRE1_SCL; + i2c_sda_pin = PIN_WIRE1_SDA; + + //REG_PIOA_PDR = PIO_PB12A_TWD1 | PIO_PB13A_TWCK1; + } + else + { + + i2c_scl_pin = PIN_WIRE_SCL; + i2c_sda_pin = PIN_WIRE_SDA; + + //REG_PIOA_PDR = PIO_PA17A_TWD0 | PIO_PA18A_TWCK0; + } + + i2c_init(); + +} + +/* sla includes also the r/w bit */ +uint8_t u8g_i2c_start(uint8_t sla) +{ + i2c_start(); + i2c_write_byte(sla); + return 1; +} + +uint8_t u8g_i2c_send_byte(uint8_t data) +{ + return i2c_write_byte(data); +} + +void u8g_i2c_stop(void) +{ + i2c_stop(); +} + + +#elif defined(U8G_RASPBERRY_PI) + +#include +#include +#include +#include +#include + +#define I2C_SLA 0x3c + +static int fd=-1; +static uint8_t i2cMode = 0; + +void u8g_i2c_init(uint8_t options) { + u8g_i2c_clear_error(); + u8g_i2c_opt = options; + + if (wiringPiSetup() == -1) { + printf("wiringPi-Error\n"); + exit(1); + } + + fd = wiringPiI2CSetup(I2C_SLA); + if (fd < 0) { + printf ("Unable to open I2C device 0: %s\n", strerror (errno)) ; + exit (1) ; + } + //u8g_SetPIOutput(u8g, U8G_PI_RESET); + //u8g_SetPIOutput(u8g, U8G_PI_A0); +} +uint8_t u8g_i2c_start(uint8_t sla) { + u8g_i2c_send_mode(0); + + return 1; +} + +void u8g_i2c_stop(void) { +} + +uint8_t u8g_i2c_send_mode(uint8_t mode) { + i2cMode = mode; +} + +uint8_t u8g_i2c_send_byte(uint8_t data) { + wiringPiI2CWriteReg8(fd, i2cMode, data); + + return 1; +} + +uint8_t u8g_i2c_wait(uint8_t mask, uint8_t pos) +{ + return 1; +} + +#else + +/* empty interface */ + +void u8g_i2c_init(uint8_t options) +{ + u8g_i2c_clear_error(); +} + +uint8_t u8g_i2c_wait(uint8_t mask, uint8_t pos) +{ + return 1; +} + +uint8_t u8g_i2c_start(uint8_t sla) +{ + return 1; +} +uint8_t u8g_i2c_send_byte(uint8_t data) +{ + return 1; +} + +void u8g_i2c_stop(void) +{ +} + + +#endif +// ============== u8g_pb8v1.c =============== + +/* + + u8g_pb8v1.c + + 8bit height monochrom (1 bit) page buffer + byte has vertical orientation + + 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. + + +*/ + +void u8g_pb8v1_Init(u8g_pb_t *b, void *buf, u8g_uint_t width) U8G_NOINLINE; +void u8g_pb8v1_set_pixel(u8g_pb_t *b, u8g_uint_t x, u8g_uint_t y, uint8_t color_index) U8G_NOINLINE; +void u8g_pb8v1_SetPixel(u8g_pb_t *b, const u8g_dev_arg_pixel_t * const arg_pixel) U8G_NOINLINE ; +void u8g_pb8v1_Set8PixelStd(u8g_pb_t *b, u8g_dev_arg_pixel_t *arg_pixel) U8G_NOINLINE; + +/* Obsolete, usually set by the init of the structure */ +void u8g_pb8v1_Init(u8g_pb_t *b, void *buf, u8g_uint_t width) +{ + b->buf = buf; + b->width = width; + u8g_pb_Clear(b); +} + +void u8g_pb8v1_set_pixel(u8g_pb_t *b, u8g_uint_t x, u8g_uint_t y, uint8_t color_index) +{ + register uint8_t mask; + uint8_t *ptr = (uint8_t*)b->buf; + + y -= b->p.page_y0; + mask = 1; + y &= 0x07; + mask <<= y; + ptr += x; + if ( color_index ) + { + *ptr |= mask; + } + else + { + mask ^=0xff; + *ptr &= mask; + } +} + + +void u8g_pb8v1_SetPixel(u8g_pb_t *b, const u8g_dev_arg_pixel_t * const arg_pixel) +{ + if ( arg_pixel->y < b->p.page_y0 ) + return; + if ( arg_pixel->y > b->p.page_y1 ) + return; + if ( arg_pixel->x >= b->width ) + return; + u8g_pb8v1_set_pixel(b, arg_pixel->x, arg_pixel->y, arg_pixel->color); +} + +void u8g_pb8v1_Set8PixelStd(u8g_pb_t *b, u8g_dev_arg_pixel_t *arg_pixel) +{ + register uint8_t pixel = arg_pixel->pixel; + do + { + if ( pixel & 128 ) + { + u8g_pb8v1_SetPixel(b, arg_pixel); + } + switch( arg_pixel->dir ) + { + case 0: arg_pixel->x++; break; + case 1: arg_pixel->y++; break; + case 2: arg_pixel->x--; break; + case 3: arg_pixel->y--; break; + } + pixel <<= 1; + } while( pixel != 0 ); +} + + +void u8g_pb8v1_Set8PixelOpt2(u8g_pb_t *b, u8g_dev_arg_pixel_t *arg_pixel) +{ + register uint8_t pixel = arg_pixel->pixel; + u8g_uint_t dx = 0; + u8g_uint_t dy = 0; + + switch( arg_pixel->dir ) + { + case 0: dx++; break; + case 1: dy++; break; + case 2: dx--; break; + case 3: dy--; break; + } + + do + { + if ( pixel & 128 ) + u8g_pb8v1_SetPixel(b, arg_pixel); + arg_pixel->x += dx; + arg_pixel->y += dy; + pixel <<= 1; + } while( pixel != 0 ); + +} + +uint8_t u8g_dev_pb8v1_base_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg) +{ + u8g_pb_t *pb = (u8g_pb_t *)(dev->dev_mem); + switch(msg) + { + case U8G_DEV_MSG_SET_8PIXEL: + if ( u8g_pb_Is8PixelVisible(pb, (u8g_dev_arg_pixel_t *)arg) ) + u8g_pb8v1_Set8PixelOpt2(pb, (u8g_dev_arg_pixel_t *)arg); + break; + case U8G_DEV_MSG_SET_PIXEL: + u8g_pb8v1_SetPixel(pb, (u8g_dev_arg_pixel_t *)arg); + break; + case U8G_DEV_MSG_INIT: + break; + case U8G_DEV_MSG_STOP: + break; + case U8G_DEV_MSG_PAGE_FIRST: + u8g_pb_Clear(pb); + u8g_page_First(&(pb->p)); + break; + case U8G_DEV_MSG_PAGE_NEXT: + if ( u8g_page_Next(&(pb->p)) == 0 ) + return 0; + u8g_pb_Clear(pb); + break; +#ifdef U8G_DEV_MSG_IS_BBX_INTERSECTION + case U8G_DEV_MSG_IS_BBX_INTERSECTION: + return u8g_pb_IsIntersection(pb, (u8g_dev_arg_bbx_t *)arg); +#endif + case U8G_DEV_MSG_GET_PAGE_BOX: + u8g_pb_GetPageBox(pb, (u8g_box_t *)arg); + break; + case U8G_DEV_MSG_GET_WIDTH: + *((u8g_uint_t *)arg) = pb->width; + break; + case U8G_DEV_MSG_GET_HEIGHT: + *((u8g_uint_t *)arg) = pb->p.total_height; + break; + case U8G_DEV_MSG_SET_COLOR_ENTRY: + break; + case U8G_DEV_MSG_SET_XY_CB: + break; + case U8G_DEV_MSG_GET_MODE: + return U8G_MODE_BW; + } + return 1; +} + + +// ============== u8g_pb16v1.c ================ + +/* + + u8g_pb16v1.c + + 16bit height monochrom (1 bit) page buffer + byte has vertical orientation + + 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 + +void u8g_pb16v1_Init(u8g_pb_t *b, void *buf, u8g_uint_t width) U8G_NOINLINE; +void u8g_pb16v1_set_pixel(u8g_pb_t *b, u8g_uint_t x, u8g_uint_t y, uint8_t color_index) U8G_NOINLINE; +void u8g_pb16v1_SetPixel(u8g_pb_t *b, const u8g_dev_arg_pixel_t * const arg_pixel) U8G_NOINLINE ; +void u8g_pb16v1_Set8PixelStd(u8g_pb_t *b, u8g_dev_arg_pixel_t *arg_pixel) U8G_NOINLINE; + + +void u8g_pb16v1_Clear(u8g_pb_t *b) +{ + uint8_t *ptr = (uint8_t *)b->buf; + uint8_t *end_ptr = ptr; + end_ptr += b->width*2; + do + { + *ptr++ = 0; + } while( ptr != end_ptr ); +} + +/* Obsolete, usually set by the init of the structure */ +void u8g_pb16v1_Init(u8g_pb_t *b, void *buf, u8g_uint_t width) +{ + b->buf = buf; + b->width = width; + u8g_pb16v1_Clear(b); +} + +void u8g_pb16v1_set_pixel(u8g_pb_t *b, u8g_uint_t x, u8g_uint_t y, uint8_t color_index) +{ + register uint8_t mask; + uint8_t *ptr = (uint8_t*)b->buf; + + y -= b->p.page_y0; + if ( y >= 8 ) + { + ptr += b->width; + y &= 0x07; + } + mask = 1; + mask <<= y; + ptr += x; + if ( color_index ) + { + *ptr |= mask; + } + else + { + mask ^=0xff; + *ptr &= mask; + } +} + + +void u8g_pb16v1_SetPixel(u8g_pb_t *b, const u8g_dev_arg_pixel_t * const arg_pixel) +{ + if ( arg_pixel->y < b->p.page_y0 ) + return; + if ( arg_pixel->y > b->p.page_y1 ) + return; + if ( arg_pixel->x >= b->width ) + return; + u8g_pb16v1_set_pixel(b, arg_pixel->x, arg_pixel->y, arg_pixel->color); +} + +void u8g_pb16v1_Set8PixelStd(u8g_pb_t *b, u8g_dev_arg_pixel_t *arg_pixel) +{ + register uint8_t pixel = arg_pixel->pixel; + do + { + if ( pixel & 128 ) + { + u8g_pb16v1_SetPixel(b, arg_pixel); + } + switch( arg_pixel->dir ) + { + case 0: arg_pixel->x++; break; + case 1: arg_pixel->y++; break; + case 2: arg_pixel->x--; break; + case 3: arg_pixel->y--; break; + } + pixel <<= 1; + } while( pixel != 0 ); +} + + +void u8g_pb16v1_Set8PixelOpt2(u8g_pb_t *b, u8g_dev_arg_pixel_t *arg_pixel) +{ + register uint8_t pixel = arg_pixel->pixel; + u8g_uint_t dx = 0; + u8g_uint_t dy = 0; + + switch( arg_pixel->dir ) + { + case 0: dx++; break; + case 1: dy++; break; + case 2: dx--; break; + case 3: dy--; break; + } + + do + { + if ( pixel & 128 ) + u8g_pb16v1_SetPixel(b, arg_pixel); + arg_pixel->x += dx; + arg_pixel->y += dy; + pixel <<= 1; + } while( pixel != 0 ); + +} + +uint8_t u8g_dev_pb16v1_base_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg) +{ + u8g_pb_t *pb = (u8g_pb_t *)(dev->dev_mem); + switch(msg) + { + case U8G_DEV_MSG_SET_8PIXEL: + if ( u8g_pb_Is8PixelVisible(pb, (u8g_dev_arg_pixel_t *)arg) ) + u8g_pb16v1_Set8PixelOpt2(pb, (u8g_dev_arg_pixel_t *)arg); + break; + case U8G_DEV_MSG_SET_PIXEL: + u8g_pb16v1_SetPixel(pb, (u8g_dev_arg_pixel_t *)arg); + break; + case U8G_DEV_MSG_INIT: + break; + case U8G_DEV_MSG_STOP: + break; + case U8G_DEV_MSG_PAGE_FIRST: + u8g_pb16v1_Clear(pb); + u8g_page_First(&(pb->p)); + break; + case U8G_DEV_MSG_PAGE_NEXT: + if ( u8g_page_Next(&(pb->p)) == 0 ) + return 0; + u8g_pb16v1_Clear(pb); + break; +#ifdef U8G_DEV_MSG_IS_BBX_INTERSECTION + case U8G_DEV_MSG_IS_BBX_INTERSECTION: + return u8g_pb_IsIntersection(pb, (u8g_dev_arg_bbx_t *)arg); +#endif + case U8G_DEV_MSG_GET_PAGE_BOX: + u8g_pb_GetPageBox(pb, (u8g_box_t *)arg); + break; + case U8G_DEV_MSG_GET_WIDTH: + *((u8g_uint_t *)arg) = pb->width; + break; + case U8G_DEV_MSG_GET_HEIGHT: + *((u8g_uint_t *)arg) = pb->p.total_height; + break; + case U8G_DEV_MSG_SET_COLOR_ENTRY: + break; + case U8G_DEV_MSG_SET_XY_CB: + break; + case U8G_DEV_MSG_GET_MODE: + return U8G_MODE_BW; + } + return 1; +} + +// ========== u8g_arduino_sw_spi.c ================ + +/* + + u8g_arduino_sw_spi.c + + 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. + + Update for ATOMIC operation done (01 Jun 2013) + U8G_ATOMIC_OR(ptr, val) + U8G_ATOMIC_AND(ptr, val) + U8G_ATOMIC_START(); + U8G_ATOMIC_END(); + + +*/ + +#if defined(ARDUINO) + +/*=========================================================*/ +/* Arduino, AVR */ + +#if defined(__AVR__) + +//uint8_t u8g_bitData, u8g_bitNotData; +//uint8_t u8g_bitClock, u8g_bitNotClock; +//volatile uint8_t *u8g_outData; +//volatile uint8_t *u8g_outClock; + +/*static void u8g_com_arduino_init_shift_out(uint8_t dataPin, uint8_t clockPin) +{ + u8g_outData = portOutputRegister(digitalPinToPort(dataPin)); + u8g_outClock = portOutputRegister(digitalPinToPort(clockPin)); + u8g_bitData = digitalPinToBitMask(dataPin); + u8g_bitClock = digitalPinToBitMask(clockPin); + + u8g_bitNotClock = u8g_bitClock; + u8g_bitNotClock ^= 0x0ff; + + u8g_bitNotData = u8g_bitData; + u8g_bitNotData ^= 0x0ff; +} + +static void u8g_com_arduino_do_shift_out_msb_first(uint8_t val) U8G_NOINLINE; +static void u8g_com_arduino_do_shift_out_msb_first(uint8_t val) +{ + uint8_t cnt = 8; + uint8_t bitData = u8g_bitData; + uint8_t bitNotData = u8g_bitNotData; + uint8_t bitClock = u8g_bitClock; + uint8_t bitNotClock = u8g_bitNotClock; + volatile uint8_t *outData = u8g_outData; + volatile uint8_t *outClock = u8g_outClock; + U8G_ATOMIC_START(); + do + { + if ( val & 128 ) + *outData |= bitData; + else + *outData &= bitNotData; + + *outClock |= bitClock; + val <<= 1; + cnt--; + *outClock &= bitNotClock; + } while( cnt != 0 ); + U8G_ATOMIC_END(); +}*/ + +/*=========================================================*/ +/* Arduino, Chipkit */ +#elif defined(__18CXX) || defined(__PIC32MX) + +uint16_t dog_bitData, dog_bitNotData; +uint16_t dog_bitClock, dog_bitNotClock; +volatile uint32_t *dog_outData; +volatile uint32_t *dog_outClock; +volatile uint32_t dog_pic32_spi_tmp; + +static void u8g_com_arduino_init_shift_out(uint8_t dataPin, uint8_t clockPin) +{ + dog_outData = portOutputRegister(digitalPinToPort(dataPin)); + dog_outClock = portOutputRegister(digitalPinToPort(clockPin)); + dog_bitData = digitalPinToBitMask(dataPin); + dog_bitClock = digitalPinToBitMask(clockPin); + + dog_bitNotClock = dog_bitClock; + dog_bitNotClock ^= 0x0ffff; + + dog_bitNotData = dog_bitData; + dog_bitNotData ^= 0x0ffff; +} + +static void u8g_com_arduino_do_shift_out_msb_first(uint8_t val) +{ + uint8_t cnt = 8; + U8G_ATOMIC_START(); + do + { + if ( val & 128 ) + *dog_outData |= dog_bitData; + else + *dog_outData &= dog_bitNotData; + val <<= 1; + /* + There must be some delay here. However + fetching the adress dog_outClock is enough delay, so + do not place dog_outClock in a local variable. This will + break the procedure + */ + *dog_outClock |= dog_bitClock; + cnt--; + *dog_outClock &= dog_bitNotClock; + /* + little additional delay after clk pulse, done by 3x32bit reads + from I/O. Optimized for PIC32 with 80 MHz. + */ + dog_pic32_spi_tmp = *dog_outClock; + dog_pic32_spi_tmp = *dog_outClock; + dog_pic32_spi_tmp = *dog_outClock; + } while( cnt != 0 ); + U8G_ATOMIC_END(); +} + +/*=========================================================*/ +/* Arduino Due */ +#elif defined(__SAM3X8E__) + +/* Due */ + +void u8g_digital_write_sam_high(uint8_t pin) +{ + PIO_Set( g_APinDescription[pin].pPort, g_APinDescription[pin].ulPin) ; +} + +void u8g_digital_write_sam_low(uint8_t pin) +{ + PIO_Clear( g_APinDescription[pin].pPort, g_APinDescription[pin].ulPin) ; +} + +static uint8_t u8g_sam_data_pin; +static uint8_t u8g_sam_clock_pin; + +/*static void u8g_com_arduino_init_shift_out(uint8_t dataPin, uint8_t clockPin) +{ + u8g_sam_data_pin = dataPin; + u8g_sam_clock_pin = clockPin; +} + +static void u8g_com_arduino_do_shift_out_msb_first(uint8_t val) +{ + uint8_t i = 8; + do + { + if ( val & 128 ) + u8g_digital_write_sam_high(u8g_sam_data_pin); + else + u8g_digital_write_sam_low(u8g_sam_data_pin); + val <<= 1; + //u8g_MicroDelay(); + u8g_digital_write_sam_high(u8g_sam_clock_pin); + u8g_MicroDelay(); + u8g_digital_write_sam_low(u8g_sam_clock_pin); + u8g_MicroDelay(); + i--; + } while( i != 0 ); +} +*/ + +#else +/* empty interface */ + +static void u8g_com_arduino_init_shift_out(uint8_t dataPin, uint8_t clockPin) +{ +} + +static void u8g_com_arduino_do_shift_out_msb_first(uint8_t val) +{ +} + +#endif + + +uint8_t u8g_com_arduino_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) +{ + switch(msg) + { + case U8G_COM_MSG_INIT: + u8g_com_arduino_assign_pin_output_high(u8g); + u8g_com_arduino_digital_write(u8g, U8G_PI_SCK, LOW); + u8g_com_arduino_digital_write(u8g, U8G_PI_MOSI, LOW); + u8g_com_arduino_init_shift_out(u8g->pin_list[U8G_PI_MOSI], u8g->pin_list[U8G_PI_SCK]); + break; + + case U8G_COM_MSG_STOP: + break; + + case U8G_COM_MSG_RESET: + if ( u8g->pin_list[U8G_PI_RESET] != U8G_PIN_NONE ) + u8g_com_arduino_digital_write(u8g, U8G_PI_RESET, arg_val); + break; + + case U8G_COM_MSG_CHIP_SELECT: + if ( arg_val == 0 ) + { + /* disable */ + u8g_com_arduino_digital_write(u8g, U8G_PI_CS, HIGH); + } + else + { + /* enable */ + u8g_com_arduino_digital_write(u8g, U8G_PI_SCK, LOW); + u8g_com_arduino_digital_write(u8g, U8G_PI_CS, LOW); + /* issue 227 */ + u8g_com_arduino_init_shift_out(u8g->pin_list[U8G_PI_MOSI], u8g->pin_list[U8G_PI_SCK]); + } + break; + + case U8G_COM_MSG_WRITE_BYTE: + u8g_com_arduino_do_shift_out_msb_first( arg_val ); + //u8g_arduino_sw_spi_shift_out(u8g->pin_list[U8G_PI_MOSI], u8g->pin_list[U8G_PI_SCK], arg_val); + break; + + case U8G_COM_MSG_WRITE_SEQ: + { + register uint8_t *ptr = (uint8_t*)arg_ptr; + while( arg_val > 0 ) + { + u8g_com_arduino_do_shift_out_msb_first(*ptr++); + // u8g_arduino_sw_spi_shift_out(u8g->pin_list[U8G_PI_MOSI], u8g->pin_list[U8G_PI_SCK], *ptr++); + arg_val--; + } + } + break; + + case U8G_COM_MSG_WRITE_SEQ_P: + { + register uint8_t *ptr = (uint8_t*)arg_ptr; + while( arg_val > 0 ) + { + u8g_com_arduino_do_shift_out_msb_first( u8g_pgm_read(ptr) ); + //u8g_arduino_sw_spi_shift_out(u8g->pin_list[U8G_PI_MOSI], u8g->pin_list[U8G_PI_SCK], u8g_pgm_read(ptr)); + ptr++; + arg_val--; + } + } + break; + + case U8G_COM_MSG_ADDRESS: /* define cmd (arg_val = 0) or data mode (arg_val = 1) */ + u8g_com_arduino_digital_write(u8g, U8G_PI_A0, arg_val); + break; + } + return 1; +} + +#else /* ARDUINO */ + +uint8_t u8g_com_arduino_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) +{ + return 1; +} + +#endif /* ARDUINO */ + +// ================ u8g_dev_ks0108_128x64.c =================== + +/* + + u8g_dev_ks0108_128x64.c + + 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. + + + ADDRESS = 0 (Command Mode) + 0x03f Display On + 0x0c0 Start Display at line 0 + 0x040 | y write to y address (y:0..63) + 0x0b8 | x write to page [0..7] + + + u8g_Init8Bit(u8g, dev, d0, d1, d2, d3, d4, d5, d6, d7, en, cs1, cs2, di, rw, reset) + u8g_Init8Bit(u8g, dev, 8, 9, 10, 11, 4, 5, 6, 7, 18, 14, 15, 17, 16, U8G_PIN_NONE) + +*/ + +#define WIDTH 128 +#define HEIGHT 64 +#define PAGE_HEIGHT 8 + +static const uint8_t u8g_dev_ks0108_128x64_init_seq[] PROGMEM = { + U8G_ESC_CS(0), /* disable chip */ + U8G_ESC_ADR(0), /* instruction mode */ + U8G_ESC_RST(1), /* do reset low pulse with (1*16)+2 milliseconds */ + U8G_ESC_CS(1), /* enable chip 1 */ + 0x03f, /* display on */ + 0x0c0, /* start at line 0 */ + U8G_ESC_DLY(20), /* delay 20 ms */ + U8G_ESC_CS(2), /* enable chip 2 */ + 0x03f, /* display on */ + 0x0c0, /* start at line 0 */ + U8G_ESC_DLY(20), /* delay 20 ms */ + U8G_ESC_CS(0), /* disable all chips */ + U8G_ESC_END /* end of sequence */ +}; + + +uint8_t u8g_dev_ks0108_128x64_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg) +{ + + switch(msg) + { + case U8G_DEV_MSG_INIT: + u8g_InitCom(u8g, dev, U8G_SPI_CLK_CYCLE_NONE); + u8g_WriteEscSeqP(u8g, dev, u8g_dev_ks0108_128x64_init_seq); + break; + case U8G_DEV_MSG_STOP: + break; + case U8G_DEV_MSG_PAGE_NEXT: + { + u8g_pb_t *pb = (u8g_pb_t *)(dev->dev_mem); + + u8g_SetAddress(u8g, dev, 0); /* command mode */ + u8g_SetChipSelect(u8g, dev, 2); + u8g_WriteByte(u8g, dev, 0x0b8 | pb->p.page); /* select current page (KS0108b) */ + u8g_WriteByte(u8g, dev, 0x040 ); /* set address 0 */ + u8g_SetAddress(u8g, dev, 1); /* data mode */ + u8g_WriteSequence(u8g, dev, 64, (uint8_t*)pb->buf); + u8g_SetChipSelect(u8g, dev, 0); + + u8g_SetAddress(u8g, dev, 0); /* command mode */ + u8g_SetChipSelect(u8g, dev, 1); + u8g_WriteByte(u8g, dev, 0x0b8 | pb->p.page); /* select current page (KS0108b) */ + u8g_WriteByte(u8g, dev, 0x040 ); /* set address 0 */ + u8g_SetAddress(u8g, dev, 1); /* data mode */ + u8g_WriteSequence(u8g, dev, 64, 64+(uint8_t *)pb->buf); + u8g_SetChipSelect(u8g, dev, 0); + + } + break; + } + return u8g_dev_pb8v1_base_fn(u8g, dev, msg, arg); +} + +U8G_PB_DEV(u8g_dev_ks0108_128x64, WIDTH, HEIGHT, PAGE_HEIGHT, u8g_dev_ks0108_128x64_fn, U8G_COM_PARALLEL); +U8G_PB_DEV(u8g_dev_ks0108_128x64_fast, WIDTH, HEIGHT, PAGE_HEIGHT, u8g_dev_ks0108_128x64_fn, U8G_COM_FAST_PARALLEL); + +// ================= 8g_com_arduino_parallel.c ================== + +/* + + u8g_com_arduino_parallel.c + + 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. + + + PIN_D0 8 + PIN_D1 9 + PIN_D2 10 + PIN_D3 11 + PIN_D4 4 + PIN_D5 5 + PIN_D6 6 + PIN_D7 7 + + PIN_CS1 14 + PIN_CS2 15 + PIN_RW 16 + PIN_DI 17 + PIN_EN 18 + + u8g_Init8Bit(u8g, dev, d0, d1, d2, d3, d4, d5, d6, d7, en, cs1, cs2, di, rw, reset) + u8g_Init8Bit(u8g, dev, 8, 9, 10, 11, 4, 5, 6, 7, 18, 14, 15, 17, 16, U8G_PIN_NONE) + +*/ + +#if defined(ARDUINO) + + +void u8g_com_arduino_parallel_write(u8g_t *u8g, uint8_t val) +{ + u8g_com_arduino_digital_write(u8g, U8G_PI_D0, val&1); + val >>= 1; + u8g_com_arduino_digital_write(u8g, U8G_PI_D1, val&1); + val >>= 1; + u8g_com_arduino_digital_write(u8g, U8G_PI_D2, val&1); + val >>= 1; + u8g_com_arduino_digital_write(u8g, U8G_PI_D3, val&1); + val >>= 1; + u8g_com_arduino_digital_write(u8g, U8G_PI_D4, val&1); + val >>= 1; + u8g_com_arduino_digital_write(u8g, U8G_PI_D5, val&1); + val >>= 1; + u8g_com_arduino_digital_write(u8g, U8G_PI_D6, val&1); + val >>= 1; + u8g_com_arduino_digital_write(u8g, U8G_PI_D7, val&1); + + /* EN cycle time must be 1 micro second, digitalWrite is slow enough to do this */ + u8g_com_arduino_digital_write(u8g, U8G_PI_EN, HIGH); + u8g_MicroDelay(); /* delay by 1000ns, reference: ST7920: 140ns, SBN1661: 100ns */ + u8g_com_arduino_digital_write(u8g, U8G_PI_EN, LOW); + u8g_10MicroDelay(); /* ST7920 commands: 72us */ +} + + +uint8_t u8g_com_arduino_parallel_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) +{ + switch(msg) + { + case U8G_COM_MSG_INIT: + /* setup the RW pin as output and force it to low */ + if ( u8g->pin_list[U8G_PI_RW] != U8G_PIN_NONE ) + { + pinMode(u8g->pin_list[U8G_PI_RW], OUTPUT); + u8g_com_arduino_digital_write(u8g, U8G_PI_RW, LOW); + } + /* set all pins (except RW pin) */ + u8g_com_arduino_assign_pin_output_high(u8g); + break; + case U8G_COM_MSG_STOP: + break; + case U8G_COM_MSG_CHIP_SELECT: + if ( arg_val == 0 ) + { + /* disable */ + u8g_com_arduino_digital_write(u8g, U8G_PI_CS1, HIGH); + u8g_com_arduino_digital_write(u8g, U8G_PI_CS2, HIGH); + } + else if ( arg_val == 1 ) + { + /* enable */ + u8g_com_arduino_digital_write(u8g, U8G_PI_CS1, LOW); + u8g_com_arduino_digital_write(u8g, U8G_PI_CS2, HIGH); + } + else if ( arg_val == 2 ) + { + /* enable */ + u8g_com_arduino_digital_write(u8g, U8G_PI_CS1, HIGH); + u8g_com_arduino_digital_write(u8g, U8G_PI_CS2, LOW); + } + else + { + /* enable */ + u8g_com_arduino_digital_write(u8g, U8G_PI_CS1, LOW); + u8g_com_arduino_digital_write(u8g, U8G_PI_CS2, LOW); + } + break; + case U8G_COM_MSG_WRITE_BYTE: + u8g_com_arduino_parallel_write(u8g, arg_val); + break; + case U8G_COM_MSG_WRITE_SEQ: + { + register uint8_t *ptr = (uint8_t*)arg_ptr; + while( arg_val > 0 ) + { + u8g_com_arduino_parallel_write(u8g, *ptr++); + arg_val--; + } + } + break; + case U8G_COM_MSG_WRITE_SEQ_P: + { + register uint8_t *ptr = (uint8_t*)arg_ptr; + while( arg_val > 0 ) + { + u8g_com_arduino_parallel_write(u8g, u8g_pgm_read(ptr)); + ptr++; + arg_val--; + } + } + break; + case U8G_COM_MSG_ADDRESS: /* define cmd (arg_val = 0) or data mode (arg_val = 1) */ + u8g_com_arduino_digital_write(u8g, U8G_PI_DI, arg_val); + break; + case U8G_COM_MSG_RESET: + if ( u8g->pin_list[U8G_PI_RESET] != U8G_PIN_NONE ) + u8g_com_arduino_digital_write(u8g, U8G_PI_RESET, arg_val); + break; + + } + return 1; +} + +#else + + +uint8_t u8g_com_arduino_parallel_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) +{ + return 1; +} + +#endif /* ARDUINO */ + + +// =============== u8g_arduino_fast_parallel.c ================ +/* + + u8g_arduino_fast_parallel.c + + 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. + + PIN_D0 8 + PIN_D1 9 + PIN_D2 10 + PIN_D3 11 + PIN_D4 4 + PIN_D5 5 + PIN_D6 6 + PIN_D7 7 + + PIN_CS1 14 + PIN_CS2 15 + PIN_RW 16 + PIN_DI 17 + PIN_EN 18 + + u8g_Init8Bit(u8g, dev, d0, d1, d2, d3, d4, d5, d6, d7, en, cs1, cs2, di, rw, reset) + u8g_Init8Bit(u8g, dev, 8, 9, 10, 11, 4, 5, 6, 7, 18, 14, 15, 17, 16, U8G_PIN_NONE) + + Update for ATOMIC operation done (01 Jun 2013) + U8G_ATOMIC_OR(ptr, val) + U8G_ATOMIC_AND(ptr, val) + U8G_ATOMIC_START(); + U8G_ATOMIC_END(); + +*/ + +#if defined(ARDUINO) + +#define PIN_D0 UI_DISPLAY_D0_PIN +#define PIN_D1 UI_DISPLAY_D1_PIN +#define PIN_D2 UI_DISPLAY_D2_PIN +#define PIN_D3 UI_DISPLAY_D3_PIN +#define PIN_D4 UI_DISPLAY_D4_PIN +#define PIN_D5 UI_DISPLAY_D5_PIN +#define PIN_D6 UI_DISPLAY_D6_PIN +#define PIN_D7 UI_DISPLAY_D7_PIN + +#define PIN_CS1 UI_DISPLAY_CS1 +#define PIN_CS2 UI_DISPLAY_CS2 +#define PIN_RW UI_DISPLAY_RW_PIN +#define PIN_DI UI_DISPLAY_DI +#define PIN_EN UI_DISPLAY_ENABLE_PIN + +//#define PIN_RESET + + +#if defined(__PIC32MX) +/* CHIPKIT PIC32 */ +static volatile uint32_t *u8g_data_port[8]; +static uint32_t u8g_data_mask[8]; +#else +static volatile uint8_t *u8g_data_port[8]; +static uint8_t u8g_data_mask[8]; +#endif + + + +static void u8g_com_arduino_fast_parallel_init(u8g_t *u8g) +{ + u8g_data_port[0] = (volatile uint8_t*)portOutputRegister(digitalPinToPort(u8g->pin_list[U8G_PI_D0]));// added conversion for due to compile + u8g_data_mask[0] = digitalPinToBitMask(u8g->pin_list[U8G_PI_D0]); + u8g_data_port[1] = (volatile uint8_t*)portOutputRegister(digitalPinToPort(u8g->pin_list[U8G_PI_D1]));// added conversion for due to compile + u8g_data_mask[1] = digitalPinToBitMask(u8g->pin_list[U8G_PI_D1]); + u8g_data_port[2] = (volatile uint8_t*)portOutputRegister(digitalPinToPort(u8g->pin_list[U8G_PI_D2]));// added conversion for due to compile + u8g_data_mask[2] = digitalPinToBitMask(u8g->pin_list[U8G_PI_D2]); + u8g_data_port[3] = (volatile uint8_t*)portOutputRegister(digitalPinToPort(u8g->pin_list[U8G_PI_D3]));// added conversion for due to compile + u8g_data_mask[3] = digitalPinToBitMask(u8g->pin_list[U8G_PI_D3]); + + u8g_data_port[4] = (volatile uint8_t*)portOutputRegister(digitalPinToPort(u8g->pin_list[U8G_PI_D4])); // added conversion for due to compile + u8g_data_mask[4] = digitalPinToBitMask(u8g->pin_list[U8G_PI_D4]); + u8g_data_port[5] = (volatile uint8_t*)portOutputRegister(digitalPinToPort(u8g->pin_list[U8G_PI_D5]));// added conversion for due to compile + u8g_data_mask[5] = digitalPinToBitMask(u8g->pin_list[U8G_PI_D5]); + u8g_data_port[6] = (volatile uint8_t*)portOutputRegister(digitalPinToPort(u8g->pin_list[U8G_PI_D6]));// added conversion for due to compile + u8g_data_mask[6] = digitalPinToBitMask(u8g->pin_list[U8G_PI_D6]); + u8g_data_port[7] = (volatile uint8_t*)portOutputRegister(digitalPinToPort(u8g->pin_list[U8G_PI_D7]));// added conversion for due to compile + u8g_data_mask[7] = digitalPinToBitMask(u8g->pin_list[U8G_PI_D7]); +} + +/* atomic protection must be done by calling function */ +static void u8g_com_arduino_fast_write_data_pin(uint8_t pin, uint8_t val) +{ + if ( val != 0 ) + *u8g_data_port[pin] |= u8g_data_mask[pin]; + else + *u8g_data_port[pin] &= ~u8g_data_mask[pin]; +} + + +void u8g_com_arduino_fast_parallel_write(u8g_t *u8g, uint8_t val) +{ + U8G_ATOMIC_START(); + u8g_com_arduino_fast_write_data_pin( 0, val&1 ); + val >>= 1; + u8g_com_arduino_fast_write_data_pin( 1, val&1 ); + val >>= 1; + u8g_com_arduino_fast_write_data_pin( 2, val&1 ); + val >>= 1; + u8g_com_arduino_fast_write_data_pin( 3, val&1 ); + val >>= 1; + + u8g_com_arduino_fast_write_data_pin( 4, val&1 ); + val >>= 1; + u8g_com_arduino_fast_write_data_pin( 5, val&1 ); + val >>= 1; + u8g_com_arduino_fast_write_data_pin( 6, val&1 ); + val >>= 1; + u8g_com_arduino_fast_write_data_pin( 7, val&1 ); + val >>= 1; + U8G_ATOMIC_END(); + + /* EN cycle time must be 1 micro second */ + u8g_com_arduino_digital_write(u8g, U8G_PI_EN, HIGH); + u8g_MicroDelay(); /* delay by 1000ns, reference: ST7920: 140ns, SBN1661: 100ns */ + u8g_com_arduino_digital_write(u8g, U8G_PI_EN, LOW); + u8g_10MicroDelay(); /* ST7920 commands: 72us */ + u8g_10MicroDelay(); /* ST7920 commands: 72us */ +} + + +uint8_t u8g_com_arduino_fast_parallel_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) +{ + switch(msg) + { + case U8G_COM_MSG_INIT: + u8g_com_arduino_fast_parallel_init(u8g); + /* setup the RW pin as output and force it to low */ + if ( u8g->pin_list[U8G_PI_RW] != U8G_PIN_NONE ) + { + pinMode(u8g->pin_list[U8G_PI_RW], OUTPUT); + u8g_com_arduino_digital_write(u8g, U8G_PI_RW, LOW); + } + /* set all pins (except RW pin) */ + u8g_com_arduino_assign_pin_output_high(u8g); + break; + case U8G_COM_MSG_STOP: + break; + + case U8G_COM_MSG_CHIP_SELECT: + if ( arg_val == 0 ) + { + /* disable */ + u8g_com_arduino_digital_write(u8g, U8G_PI_CS1, HIGH); + u8g_com_arduino_digital_write(u8g, U8G_PI_CS2, HIGH); + } + else if ( arg_val == 1 ) + { + /* enable */ + u8g_com_arduino_digital_write(u8g, U8G_PI_CS1, LOW); + u8g_com_arduino_digital_write(u8g, U8G_PI_CS2, HIGH); + } + else if ( arg_val == 2 ) + { + /* enable */ + u8g_com_arduino_digital_write(u8g, U8G_PI_CS1, HIGH); + u8g_com_arduino_digital_write(u8g, U8G_PI_CS2, LOW); + } + else + { + /* enable */ + u8g_com_arduino_digital_write(u8g, U8G_PI_CS1, LOW); + u8g_com_arduino_digital_write(u8g, U8G_PI_CS2, LOW); + } + break; + case U8G_COM_MSG_WRITE_BYTE: + u8g_com_arduino_fast_parallel_write(u8g, arg_val); + break; + case U8G_COM_MSG_WRITE_SEQ: + { + register uint8_t *ptr = (uint8_t*)arg_ptr; + while( arg_val > 0 ) + { + u8g_com_arduino_fast_parallel_write(u8g, *ptr++); + arg_val--; + } + } + break; + case U8G_COM_MSG_WRITE_SEQ_P: + { + register uint8_t *ptr = (uint8_t*)arg_ptr; + while( arg_val > 0 ) + { + u8g_com_arduino_fast_parallel_write(u8g, u8g_pgm_read(ptr)); + ptr++; + arg_val--; + } + } + break; + case U8G_COM_MSG_ADDRESS: /* define cmd (arg_val = 0) or data mode (arg_val = 1) */ + u8g_com_arduino_digital_write(u8g, U8G_PI_DI, arg_val); + break; + case U8G_COM_MSG_RESET: + if ( u8g->pin_list[U8G_PI_RESET] != U8G_PIN_NONE ) + u8g_com_arduino_digital_write(u8g, U8G_PI_RESET, arg_val); + break; + + } + return 1; +} + +#else + + +uint8_t u8g_com_arduino_fast_parallel_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) +{ + return 1; +} + + +#endif /* ARDUINO */ + + +/* + + u8g_dev_st7565_nhd_c12864.c + + Support for the NHD-C12864A1Z-FSB-FBW (Newhaven Display) + + Universal 8bit Graphics Library + + Copyright (c) 2012, 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. + + +*/ + +#define WIDTH 128 +#define HEIGHT 64 +#define PAGE_HEIGHT 8 + +const uint8_t u8g_dev_st7565_nhd_c12864_init_seq[] PROGMEM = { + U8G_ESC_CS(0), /* disable chip */ + U8G_ESC_ADR(0), /* instruction mode */ + U8G_ESC_RST(10), /* do reset low pulse with (10*16)+2 milliseconds */ + U8G_ESC_CS(1), /* enable chip */ + + 0x040, /* set display start line */ + 0x0a1, /* ADC set to reverse */ + 0x0c0, /* common output mode: set scan direction normal operation */ + 0x0a6, /* display normal, bit val 0: LCD pixel off. */ + 0x0a2, /* LCD bias 1/9 */ + 0x02f, /* all power control circuits on */ + 0x0f8, /* set booster ratio to */ + 0x000, /* 4x */ + 0x027, /* set V0 voltage resistor ratio to large */ + 0x081, /* set contrast */ + 0x008, /* contrast: 0x008 is a good value for NHD C12864, Nov 2012: User reports that 0x1a is much better */ + 0x0ac, /* indicator */ + 0x000, /* disable */ + 0x0af, /* display on */ + + U8G_ESC_DLY(100), /* delay 100 ms */ + 0x0a5, /* display all points, ST7565 */ + U8G_ESC_DLY(100), /* delay 100 ms */ + U8G_ESC_DLY(100), /* delay 100 ms */ + 0x0a4, /* normal display */ + U8G_ESC_CS(0), /* disable chip */ + U8G_ESC_END /* end of sequence */ +}; + +static const uint8_t u8g_dev_st7565_nhd_c12864_data_start[] PROGMEM = { + U8G_ESC_ADR(0), /* instruction mode */ + U8G_ESC_CS(1), /* enable chip */ + 0x010, /* set upper 4 bit of the col adr to 0 */ + 0x004, /* set lower 4 bit of the col adr to 4 (NHD C12864) */ + U8G_ESC_END /* end of sequence */ +}; + +static const uint8_t u8g_dev_st7565_c12864_sleep_on[] PROGMEM = { + U8G_ESC_ADR(0), /* instruction mode */ + U8G_ESC_CS(1), /* enable chip */ + 0x0ac, /* static indicator off */ + 0x000, /* indicator register set (not sure if this is required) */ + 0x0ae, /* display off */ + 0x0a5, /* all points on */ + U8G_ESC_CS(0), /* disable chip, bugfix 12 nov 2014 */ + U8G_ESC_END /* end of sequence */ +}; + +static const uint8_t u8g_dev_st7565_c12864_sleep_off[] PROGMEM = { + U8G_ESC_ADR(0), /* instruction mode */ + U8G_ESC_CS(1), /* enable chip */ + 0x0a4, /* all points off */ + 0x0af, /* display on */ + U8G_ESC_DLY(50), /* delay 50 ms */ + U8G_ESC_CS(0), /* disable chip, bugfix 12 nov 2014 */ + U8G_ESC_END /* end of sequence */ +}; + +uint8_t u8g_dev_st7565_nhd_c12864_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg) +{ + switch(msg) + { + case U8G_DEV_MSG_INIT: +#if defined(__SAM3X8E__) + u8g_InitCom(u8g, dev, U8G_SPI_CLK_CYCLE_400NS); +#else + u8g_InitCom(u8g, dev, U8G_SPI_CLK_CYCLE_400NS); +#endif + u8g_WriteEscSeqP(u8g, dev, u8g_dev_st7565_nhd_c12864_init_seq); + break; + case U8G_DEV_MSG_STOP: + break; + case U8G_DEV_MSG_PAGE_NEXT: + { + u8g_pb_t *pb = (u8g_pb_t *)(dev->dev_mem); + u8g_WriteEscSeqP(u8g, dev, u8g_dev_st7565_nhd_c12864_data_start); + u8g_WriteByte(u8g, dev, 0x0b0 | pb->p.page); /* select current page (ST7565R) */ + u8g_SetAddress(u8g, dev, 1); /* data mode */ + if ( u8g_pb_WriteBuffer(pb, u8g, dev) == 0 ) + return 0; + u8g_SetChipSelect(u8g, dev, 0); + } + break; + case U8G_DEV_MSG_CONTRAST: + u8g_SetChipSelect(u8g, dev, 1); + u8g_SetAddress(u8g, dev, 0); /* instruction mode */ + u8g_WriteByte(u8g, dev, 0x081); + u8g_WriteByte(u8g, dev, (*(uint8_t *)arg) >> 2); + u8g_SetChipSelect(u8g, dev, 0); + return 1; + case U8G_DEV_MSG_SLEEP_ON: + u8g_WriteEscSeqP(u8g, dev, u8g_dev_st7565_c12864_sleep_on); + return 1; + case U8G_DEV_MSG_SLEEP_OFF: + u8g_WriteEscSeqP(u8g, dev, u8g_dev_st7565_c12864_sleep_off); + return 1; + } + return u8g_dev_pb8v1_base_fn(u8g, dev, msg, arg); +} + +uint8_t u8g_dev_st7565_nhd_c12864_2x_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg) +{ + switch(msg) + { + case U8G_DEV_MSG_INIT: + u8g_InitCom(u8g, dev, U8G_SPI_CLK_CYCLE_400NS); + u8g_WriteEscSeqP(u8g, dev, u8g_dev_st7565_nhd_c12864_init_seq); + break; + case U8G_DEV_MSG_STOP: + break; + case U8G_DEV_MSG_PAGE_NEXT: + { + u8g_pb_t *pb = (u8g_pb_t *)(dev->dev_mem); + + u8g_WriteEscSeqP(u8g, dev, u8g_dev_st7565_nhd_c12864_data_start); + u8g_WriteByte(u8g, dev, 0x0b0 | (2*pb->p.page)); /* select current page (ST7565R) */ + u8g_SetAddress(u8g, dev, 1); /* data mode */ + u8g_WriteSequence(u8g, dev, pb->width, (uint8_t*)pb->buf); + u8g_SetChipSelect(u8g, dev, 0); + + u8g_WriteEscSeqP(u8g, dev, u8g_dev_st7565_nhd_c12864_data_start); + u8g_WriteByte(u8g, dev, 0x0b0 | (2*pb->p.page+1)); /* select current page (ST7565R) */ + u8g_SetAddress(u8g, dev, 1); /* data mode */ + u8g_WriteSequence(u8g, dev, pb->width, (uint8_t *)(pb->buf)+pb->width); + u8g_SetChipSelect(u8g, dev, 0); + } + break; + case U8G_DEV_MSG_CONTRAST: + u8g_SetChipSelect(u8g, dev, 1); + u8g_SetAddress(u8g, dev, 0); /* instruction mode */ + u8g_WriteByte(u8g, dev, 0x081); + u8g_WriteByte(u8g, dev, (*(uint8_t *)arg) >> 2); + u8g_SetChipSelect(u8g, dev, 0); + return 1; + case U8G_DEV_MSG_SLEEP_ON: + u8g_WriteEscSeqP(u8g, dev, u8g_dev_st7565_c12864_sleep_on); + return 1; + case U8G_DEV_MSG_SLEEP_OFF: + u8g_WriteEscSeqP(u8g, dev, u8g_dev_st7565_c12864_sleep_off); + return 1; + } + return u8g_dev_pb16v1_base_fn(u8g, dev, msg, arg); +} + +U8G_PB_DEV(u8g_dev_st7565_nhd_c12864_sw_spi, WIDTH, HEIGHT, PAGE_HEIGHT, u8g_dev_st7565_nhd_c12864_fn, U8G_COM_SW_SPI); +U8G_PB_DEV(u8g_dev_st7565_nhd_c12864_hw_spi, WIDTH, HEIGHT, PAGE_HEIGHT, u8g_dev_st7565_nhd_c12864_fn, U8G_COM_HW_SPI); + + +uint8_t u8g_dev_st7565_nhd_c12864_2x_buf[WIDTH*2] U8G_NOCOMMON ; +u8g_pb_t u8g_dev_st7565_nhd_c12864_2x_pb = { {16, HEIGHT, 0, 0, 0}, WIDTH, u8g_dev_st7565_nhd_c12864_2x_buf}; +u8g_dev_t u8g_dev_st7565_nhd_c12864_2x_sw_spi = { u8g_dev_st7565_nhd_c12864_2x_fn, &u8g_dev_st7565_nhd_c12864_2x_pb, U8G_COM_SW_SPI }; +u8g_dev_t u8g_dev_st7565_nhd_c12864_2x_hw_spi = { u8g_dev_st7565_nhd_c12864_2x_fn, &u8g_dev_st7565_nhd_c12864_2x_pb, U8G_COM_HW_SPI }; + +/* + + u8g_com_arduino_hw_spi.c + + 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. + + SPI Clock Cycle Type + + SSD1351 50ns 20 MHz + SSD1322 300ns 3.3 MHz + SSD1327 300ns + SSD1306 300ns + ST7565 400ns 2.5 MHz + ST7920 400ns + + Arduino DUE + + PA25 MISO + PA26 MOSI 75 + PA27 SCLK 76 + + +typedef struct { + WoReg SPI_CR; (Spi Offset: 0x00) Control Register + RwReg SPI_MR; (Spi Offset: 0x04) Mode Register + RoReg SPI_RDR; (Spi Offset: 0x08) Receive Data Register + WoReg SPI_TDR; (Spi Offset: 0x0C) Transmit Data Register + RoReg SPI_SR; (Spi Offset: 0x10) Status Register + WoReg SPI_IER; (Spi Offset: 0x14) Interrupt Enable Register + WoReg SPI_IDR; (Spi Offset: 0x18) Interrupt Disable Register + RoReg SPI_IMR; (Spi Offset: 0x1C) Interrupt Mask Register + RoReg Reserved1[4]; + RwReg SPI_CSR[4]; (Spi Offset: 0x30) Chip Select Register + RoReg Reserved2[41]; + RwReg SPI_WPMR; (Spi Offset: 0xE4) Write Protection Control Register + RoReg SPI_WPSR; (Spi Offset: 0xE8) Write Protection Status Register +} Spi; + + Power Management Controller (PMC) + arduino-1.5.2/hardware/arduino/sam/system/CMSIS/Device/ATMEL/sam3xa/include/instance/instance_pmc.h + - enable PIO + + REG_PMC_PCER0 = 1UL << ID_PIOA + - enable SPI + REG_PMC_PCER0 = 1UL << ID_SPI0 + + + - enable PIOA and SPI0 + REG_PMC_PCER0 = (1UL << ID_PIOA) | (1UL << ID_SPI0); + + Parallel Input/Output Controller (PIO) + arduino-1.5.2/hardware/arduino/sam/system/CMSIS/Device/ATMEL/sam3xa/include/instance/instance_pioa.h + - enable special function of the pin: disable PIO on A26 and A27: + REG_PIOA_PDR = 0x0c000000 + PIOA->PIO_PDR = 0x0c000000 + + SPI + SPI0->SPI_CR = SPI_CR_SPIDIS + SPI0->SPI_CR = SPI_CR_SWRST ; + SPI0->SPI_CR = SPI_CR_SWRST ; + SPI0->SPI_CR = SPI_CR_SPIEN + + Bit 0: Master Mode = 1 (active) + Bit 1: Peripheral Select = 0 (fixed) + Bit 2: Chip Select Decode Mode = 1 (4 to 16) + Bit 4: Mode Fault Detection = 1 (disabled) + Bit 5: Wait Data Read = 0 (disabled) + Bit 7: Loop Back Mode = 0 (disabled) + Bit 16-19: Peripheral Chip Select = 0 (chip select 0) + SPI0->SPI_MR = SPI_MR_MSTR | SPI_MR_PCSDEC | SPI_MR_MODFDIS + + Bit 0: Clock Polarity = 0 + Bit 1: Clock Phase = 0 + Bit 4-7: Bits = 0 (8 Bit) + Bit 8-15: SCBR = 1 + SPI0->SPI_CSR[0] = SPI_CSR_SCBR(x) Serial Baud Rate + SCBR / 84000000 > 50 / 1000000000 + SCBR / 84 > 5 / 100 + SCBR > 50 *84 / 1000 --> SCBR=5 + SCBR > 300*84 / 1000 --> SCBR=26 + SCBR > 400*84 / 1000 --> SCBR=34 + + Arduino Due test code: + REG_PMC_PCER0 = (1UL << ID_PIOA) | (1UL << ID_SPI0); + REG_PIOA_PDR = 0x0c000000; + SPI0->SPI_CR = SPI_CR_SPIDIS; + SPI0->SPI_CR = SPI_CR_SWRST; + SPI0->SPI_CR = SPI_CR_SWRST; + SPI0->SPI_CR = SPI_CR_SPIEN; + SPI0->SPI_MR = SPI_MR_MSTR | SPI_MR_PCSDEC | SPI_MR_MODFDIS; + SPI0->SPI_CSR[0] = SPI_CSR_SCBR(30); + + for(;;) + { + while( (SPI0->SPI_SR & SPI_SR_TDRE) == 0 ) + ; + SPI0->SPI_TDR = 0x050; + } + +*/ + +#if defined(ARDUINO) + +#if defined(__AVR__) +#define U8G_ARDUINO_ATMEGA_HW_SPI +/* remove the definition for attiny */ +#if __AVR_ARCH__ == 2 +#undef U8G_ARDUINO_ATMEGA_HW_SPI +#endif +#if __AVR_ARCH__ == 25 +#undef U8G_ARDUINO_ATMEGA_HW_SPI +#endif +#endif + +#if defined(U8G_ARDUINO_ATMEGA_HW_SPI) + +//#include +//#include + +#if ARDUINO < 100 + +/* fixed pins */ +#if defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__) // Sanguino.cc board +#define PIN_SCK 7 +#define PIN_MISO 6 +#define PIN_MOSI 5 +#define PIN_CS 4 +#else // Arduino Board +#define PIN_SCK 13 +#define PIN_MISO 12 +#define PIN_MOSI 11 +#define PIN_CS 10 +#endif // (__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__) + +#else + +/* use Arduino pin definitions */ +#define PIN_SCK SCK +#define PIN_MISO MISO_PIN +#define PIN_MOSI MOSI_PIN +#define PIN_CS SS + +#endif + + + +//static uint8_t u8g_spi_out(uint8_t data) U8G_NOINLINE; +static uint8_t u8g_spi_out(uint8_t data) +{ + /* unsigned char x = 100; */ + /* send data */ + SPDR = data; + /* wait for transmission */ + while (!(SPSR & (1<pin_list[U8G_PI_RESET] != U8G_PIN_NONE ) + u8g_com_arduino_digital_write(u8g, U8G_PI_RESET, arg_val); + break; + + case U8G_COM_MSG_WRITE_BYTE: + u8g_spi_out(arg_val); + break; + + case U8G_COM_MSG_WRITE_SEQ: + { + register uint8_t *ptr = (uint8_t*)arg_ptr; + while( arg_val > 0 ) + { + u8g_spi_out(*ptr++); + arg_val--; + } + } + break; + case U8G_COM_MSG_WRITE_SEQ_P: + { + register uint8_t *ptr = (uint8_t*)arg_ptr; + while( arg_val > 0 ) + { + u8g_spi_out(u8g_pgm_read(ptr)); + ptr++; + arg_val--; + } + } + break; + } + return 1; +} + +/* #elif defined(__18CXX) || defined(__PIC32MX) */ + +#elif defined(__SAM3X8E__) // Arduino Due, maybe we should better check for __SAM3X8E__ + +/* use Arduino pin definitions */ +#define PIN_SCK SCK +#define PIN_MISO MISO +#define PIN_MOSI MOSI +#define PIN_CS SS + + +static uint8_t u8g_spi_out(uint8_t data) +{ + /* wait until tx register is empty */ + while( (SPI0->SPI_SR & SPI_SR_TDRE) == 0 ) + ; + /* send data */ + SPI0->SPI_TDR = (uint32_t)data; + return data; +} + + +uint8_t u8g_com_arduino_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) +{ + switch(msg) + { + case U8G_COM_MSG_STOP: + break; + + case U8G_COM_MSG_INIT: + u8g_com_arduino_assign_pin_output_high(u8g); + u8g_com_arduino_digital_write(u8g, U8G_PI_CS, HIGH); + + /* Arduino Due specific code */ + + /* enable PIOA and SPI0 */ + REG_PMC_PCER0 = (1UL << ID_PIOA) | (1UL << ID_SPI0); + + /* disable PIO on A26 and A27 */ + REG_PIOA_PDR = 0x0c000000; + + /* reset SPI0 (from sam lib) */ + SPI0->SPI_CR = SPI_CR_SPIDIS; + SPI0->SPI_CR = SPI_CR_SWRST; + SPI0->SPI_CR = SPI_CR_SWRST; + SPI0->SPI_CR = SPI_CR_SPIEN; + u8g_MicroDelay(); + + /* master mode, no fault detection, chip select 0 */ + SPI0->SPI_MR = SPI_MR_MSTR | SPI_MR_PCSDEC | SPI_MR_MODFDIS; + + /* Polarity, Phase, 8 Bit data transfer, baud rate */ + /* x * 1000 / 84 --> clock cycle in ns + 5 * 1000 / 84 = 58 ns + SCBR > 50 *84 / 1000 --> SCBR=5 + SCBR > 300*84 / 1000 --> SCBR=26 + SCBR > 400*84 / 1000 --> SCBR=34 + */ + + if ( arg_val <= U8G_SPI_CLK_CYCLE_50NS ) + { + SPI0->SPI_CSR[0] = SPI_CSR_SCBR(5) | 1; + } + else if ( arg_val <= U8G_SPI_CLK_CYCLE_300NS ) + { + SPI0->SPI_CSR[0] = SPI_CSR_SCBR(26) | 1; + } + else if ( arg_val <= U8G_SPI_CLK_CYCLE_400NS ) + { + SPI0->SPI_CSR[0] = SPI_CSR_SCBR(34) | 1; + } + else if ( arg_val <= U8G_SPI_CLK_CYCLE_500NS ) + { + SPI0->SPI_CSR[0] = SPI_CSR_SCBR(42) | 1; + } + else + { + SPI0->SPI_CSR[0] = SPI_CSR_SCBR(84) | 1; + } + + u8g_MicroDelay(); + break; + + case U8G_COM_MSG_ADDRESS: /* define cmd (arg_val = 0) or data mode (arg_val = 1) */ + u8g_com_arduino_digital_write(u8g, U8G_PI_A0, arg_val); + u8g_MicroDelay(); + break; + + case U8G_COM_MSG_CHIP_SELECT: + if ( arg_val == 0 ) + { + /* disable */ + u8g_MicroDelay(); /* this delay is required to avoid that the display is switched off too early --> DOGS102 with DUE */ + u8g_com_arduino_digital_write(u8g, U8G_PI_CS, HIGH); + u8g_MicroDelay(); + } + else + { + /* enable */ + //u8g_com_arduino_digital_write(u8g, U8G_PI_SCK, LOW); + u8g_com_arduino_digital_write(u8g, U8G_PI_CS, LOW); + u8g_MicroDelay(); + } + break; + + case U8G_COM_MSG_RESET: + if ( u8g->pin_list[U8G_PI_RESET] != U8G_PIN_NONE ) + u8g_com_arduino_digital_write(u8g, U8G_PI_RESET, arg_val); + break; + + case U8G_COM_MSG_WRITE_BYTE: + u8g_spi_out(arg_val); + u8g_MicroDelay(); + break; + + case U8G_COM_MSG_WRITE_SEQ: + { + register uint8_t *ptr = (uint8_t*)arg_ptr; + while( arg_val > 0 ) + { + u8g_spi_out(*ptr++); + arg_val--; + } + } + break; + case U8G_COM_MSG_WRITE_SEQ_P: + { + register uint8_t *ptr = (uint8_t*)arg_ptr; + while( arg_val > 0 ) + { + u8g_spi_out(u8g_pgm_read(ptr)); + ptr++; + arg_val--; + } + } + break; + } + return 1; +} + + + +#else /* U8G_ARDUINO_ATMEGA_HW_SPI */ + +#endif /* U8G_ARDUINO_ATMEGA_HW_SPI */ + +#else /* ARDUINO */ + +uint8_t u8g_com_arduino_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) +{ + return 1; +} + +#endif /* ARDUINO */ + +/* + + u8g_rot.c + + 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. + + +*/ + +uint8_t u8g_dev_rot90_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg); +uint8_t u8g_dev_rot180_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg); +uint8_t u8g_dev_rot270_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg); + +uint8_t u8g_dev_rot_dummy_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg) +{ + return 0; +} + +u8g_dev_t u8g_dev_rot = { u8g_dev_rot_dummy_fn, NULL, NULL }; + + +void u8g_UndoRotation(u8g_t *u8g) +{ + if ( u8g->dev != &u8g_dev_rot ) + return; + u8g->dev = (u8g_dev_t*)u8g_dev_rot.dev_mem; + u8g_UpdateDimension(u8g); +} + +void u8g_SetRot90(u8g_t *u8g) +{ + if ( u8g->dev != &u8g_dev_rot ) + { + u8g_dev_rot.dev_mem = u8g->dev; + u8g->dev = &u8g_dev_rot; + } + u8g_dev_rot.dev_fn = u8g_dev_rot90_fn; + u8g_UpdateDimension(u8g); +} + +void u8g_SetRot180(u8g_t *u8g) +{ + if ( u8g->dev != &u8g_dev_rot ) + { + u8g_dev_rot.dev_mem = u8g->dev; + u8g->dev = &u8g_dev_rot; + } + u8g_dev_rot.dev_fn = u8g_dev_rot180_fn; + u8g_UpdateDimension(u8g); +} + +void u8g_SetRot270(u8g_t *u8g) +{ + if ( u8g->dev != &u8g_dev_rot ) + { + u8g_dev_rot.dev_mem = u8g->dev; + u8g->dev = &u8g_dev_rot; + } + u8g_dev_rot.dev_fn = u8g_dev_rot270_fn; + u8g_UpdateDimension(u8g); +} + +uint8_t u8g_dev_rot90_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg) +{ + u8g_dev_t *rotation_chain = (u8g_dev_t *)(dev->dev_mem); + switch(msg) + { + default: + /* + case U8G_DEV_MSG_INIT: + case U8G_DEV_MSG_STOP: + case U8G_DEV_MSG_PAGE_FIRST: + case U8G_DEV_MSG_PAGE_NEXT: + case U8G_DEV_MSG_SET_COLOR_ENTRY: + case U8G_DEV_MSG_SET_XY_CB: + */ + return u8g_call_dev_fn(u8g, rotation_chain, msg, arg); +#ifdef U8G_DEV_MSG_IS_BBX_INTERSECTION + case U8G_DEV_MSG_IS_BBX_INTERSECTION: + { + u8g_dev_arg_bbx_t *bbx = (u8g_dev_arg_bbx_t *)arg; + u8g_uint_t x, y, tmp; + + /* transform the reference point */ + y = bbx->x; + x = u8g->height; + /* x = u8g_GetWidthLL(u8g, rotation_chain); */ + x -= bbx->y; + x--; + + /* adjust point to be the uppler left corner again */ + x -= bbx->h; + x++; + + /* swap box dimensions */ + tmp = bbx->w; + bbx->w = bbx->h; + bbx->h = tmp; + + /* store x,y */ + bbx->x = x; + bbx->y = y; + } + return u8g_call_dev_fn(u8g, rotation_chain, msg, arg); +#endif /* U8G_DEV_MSG_IS_BBX_INTERSECTION */ + case U8G_DEV_MSG_GET_PAGE_BOX: + /* get page size from next device in the chain */ + u8g_call_dev_fn(u8g, rotation_chain, msg, arg); + //printf("pre x: %3d..%3d y: %3d..%3d ", ((u8g_box_t *)arg)->x0, ((u8g_box_t *)arg)->x1, ((u8g_box_t *)arg)->y0, ((u8g_box_t *)arg)->y1); + { + u8g_box_t new_box; + //new_box.x0 = u8g_GetHeightLL(u8g,rotation_chain) - ((u8g_box_t *)arg)->y1 - 1; + //new_box.x1 = u8g_GetHeightLL(u8g,rotation_chain) - ((u8g_box_t *)arg)->y0 - 1; + + new_box.x0 = ((u8g_box_t *)arg)->y0; + new_box.x1 = ((u8g_box_t *)arg)->y1; + new_box.y0 = ((u8g_box_t *)arg)->x0; + new_box.y1 = ((u8g_box_t *)arg)->x1; + *((u8g_box_t *)arg) = new_box; + //printf("post x: %3d..%3d y: %3d..%3d\n", ((u8g_box_t *)arg)->x0, ((u8g_box_t *)arg)->x1, ((u8g_box_t *)arg)->y0, ((u8g_box_t *)arg)->y1); + } + break; + case U8G_DEV_MSG_GET_WIDTH: + *((u8g_uint_t *)arg) = u8g_GetHeightLL(u8g,rotation_chain); + break; + case U8G_DEV_MSG_GET_HEIGHT: + *((u8g_uint_t *)arg) = u8g_GetWidthLL(u8g, rotation_chain); + break; + case U8G_DEV_MSG_SET_PIXEL: + case U8G_DEV_MSG_SET_TPIXEL: + { + u8g_uint_t x, y; + y = ((u8g_dev_arg_pixel_t *)arg)->x; + x = u8g_GetWidthLL(u8g, rotation_chain); + x -= ((u8g_dev_arg_pixel_t *)arg)->y; + x--; + ((u8g_dev_arg_pixel_t *)arg)->x = x; + ((u8g_dev_arg_pixel_t *)arg)->y = y; + } + u8g_call_dev_fn(u8g, rotation_chain, msg, arg); + break; + case U8G_DEV_MSG_SET_8PIXEL: + case U8G_DEV_MSG_SET_4TPIXEL: + { + u8g_uint_t x, y; + //uint16_t x,y; + y = ((u8g_dev_arg_pixel_t *)arg)->x; + x = u8g_GetWidthLL(u8g, rotation_chain); + x -= ((u8g_dev_arg_pixel_t *)arg)->y; + x--; + ((u8g_dev_arg_pixel_t *)arg)->x = x; + ((u8g_dev_arg_pixel_t *)arg)->y = y; + ((u8g_dev_arg_pixel_t *)arg)->dir+=1; + ((u8g_dev_arg_pixel_t *)arg)->dir &= 3; + } + u8g_call_dev_fn(u8g, rotation_chain, msg, arg); + break; + } + return 1; +} + +uint8_t u8g_dev_rot180_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg) +{ + u8g_dev_t *rotation_chain = (u8g_dev_t *)(dev->dev_mem); + switch(msg) + { + default: + /* + case U8G_DEV_MSG_INIT: + case U8G_DEV_MSG_STOP: + case U8G_DEV_MSG_PAGE_FIRST: + case U8G_DEV_MSG_PAGE_NEXT: + case U8G_DEV_MSG_SET_COLOR_ENTRY: + case U8G_DEV_MSG_SET_XY_CB: + */ + return u8g_call_dev_fn(u8g, rotation_chain, msg, arg); +#ifdef U8G_DEV_MSG_IS_BBX_INTERSECTION + case U8G_DEV_MSG_IS_BBX_INTERSECTION: + { + u8g_dev_arg_bbx_t *bbx = (u8g_dev_arg_bbx_t *)arg; + u8g_uint_t x, y; + + /* transform the reference point */ + //y = u8g_GetHeightLL(u8g, rotation_chain); + y = u8g->height; + y -= bbx->y; + y--; + + //x = u8g_GetWidthLL(u8g, rotation_chain); + x = u8g->width; + x -= bbx->x; + x--; + + /* adjust point to be the uppler left corner again */ + y -= bbx->h; + y++; + + x -= bbx->w; + x++; + + /* store x,y */ + bbx->x = x; + bbx->y = y; + } + return u8g_call_dev_fn(u8g, rotation_chain, msg, arg); +#endif /* U8G_DEV_MSG_IS_BBX_INTERSECTION */ + case U8G_DEV_MSG_GET_PAGE_BOX: + /* get page size from next device in the chain */ + u8g_call_dev_fn(u8g, rotation_chain, msg, arg); + //printf("pre x: %3d..%3d y: %3d..%3d ", ((u8g_box_t *)arg)->x0, ((u8g_box_t *)arg)->x1, ((u8g_box_t *)arg)->y0, ((u8g_box_t *)arg)->y1); + { + u8g_box_t new_box; + + new_box.x0 = u8g_GetWidthLL(u8g,rotation_chain) - ((u8g_box_t *)arg)->x1 - 1; + new_box.x1 = u8g_GetWidthLL(u8g,rotation_chain) - ((u8g_box_t *)arg)->x0 - 1; + new_box.y0 = u8g_GetHeightLL(u8g,rotation_chain) - ((u8g_box_t *)arg)->y1 - 1; + new_box.y1 = u8g_GetHeightLL(u8g,rotation_chain) - ((u8g_box_t *)arg)->y0 - 1; + *((u8g_box_t *)arg) = new_box; + //printf("post x: %3d..%3d y: %3d..%3d\n", ((u8g_box_t *)arg)->x0, ((u8g_box_t *)arg)->x1, ((u8g_box_t *)arg)->y0, ((u8g_box_t *)arg)->y1); + } + break; + case U8G_DEV_MSG_GET_WIDTH: + *((u8g_uint_t *)arg) = u8g_GetWidthLL(u8g,rotation_chain); + break; + case U8G_DEV_MSG_GET_HEIGHT: + *((u8g_uint_t *)arg) = u8g_GetHeightLL(u8g, rotation_chain); + break; + case U8G_DEV_MSG_SET_PIXEL: + case U8G_DEV_MSG_SET_TPIXEL: + { + u8g_uint_t x, y; + + y = u8g_GetHeightLL(u8g, rotation_chain); + y -= ((u8g_dev_arg_pixel_t *)arg)->y; + y--; + + x = u8g_GetWidthLL(u8g, rotation_chain); + x -= ((u8g_dev_arg_pixel_t *)arg)->x; + x--; + + ((u8g_dev_arg_pixel_t *)arg)->x = x; + ((u8g_dev_arg_pixel_t *)arg)->y = y; + } + u8g_call_dev_fn(u8g, rotation_chain, msg, arg); + break; + case U8G_DEV_MSG_SET_8PIXEL: + case U8G_DEV_MSG_SET_4TPIXEL: + { + u8g_uint_t x, y; + + y = u8g_GetHeightLL(u8g, rotation_chain); + y -= ((u8g_dev_arg_pixel_t *)arg)->y; + y--; + + x = u8g_GetWidthLL(u8g, rotation_chain); + x -= ((u8g_dev_arg_pixel_t *)arg)->x; + x--; + + ((u8g_dev_arg_pixel_t *)arg)->x = x; + ((u8g_dev_arg_pixel_t *)arg)->y = y; + ((u8g_dev_arg_pixel_t *)arg)->dir+=2; + ((u8g_dev_arg_pixel_t *)arg)->dir &= 3; + } + u8g_call_dev_fn(u8g, rotation_chain, msg, arg); + break; + } + return 1; +} + +uint8_t u8g_dev_rot270_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg) +{ + u8g_dev_t *rotation_chain = (u8g_dev_t *)(dev->dev_mem); + switch(msg) + { + default: + /* + case U8G_DEV_MSG_INIT: + case U8G_DEV_MSG_STOP: + case U8G_DEV_MSG_PAGE_FIRST: + case U8G_DEV_MSG_PAGE_NEXT: + case U8G_DEV_MSG_SET_COLOR_ENTRY: + case U8G_DEV_MSG_SET_XY_CB: + */ + return u8g_call_dev_fn(u8g, rotation_chain, msg, arg); +#ifdef U8G_DEV_MSG_IS_BBX_INTERSECTION + case U8G_DEV_MSG_IS_BBX_INTERSECTION: + { + u8g_dev_arg_bbx_t *bbx = (u8g_dev_arg_bbx_t *)arg; + u8g_uint_t x, y, tmp; + + /* transform the reference point */ + x = bbx->y; + + y = u8g->width; + /* y = u8g_GetHeightLL(u8g, rotation_chain); */ + y -= bbx->x; + y--; + + /* adjust point to be the uppler left corner again */ + y -= bbx->w; + y++; + + /* swap box dimensions */ + tmp = bbx->w; + bbx->w = bbx->h; + bbx->h = tmp; + + /* store x,y */ + bbx->x = x; + bbx->y = y; + } + return u8g_call_dev_fn(u8g, rotation_chain, msg, arg); +#endif /* U8G_DEV_MSG_IS_BBX_INTERSECTION */ + case U8G_DEV_MSG_GET_PAGE_BOX: + /* get page size from next device in the chain */ + u8g_call_dev_fn(u8g, rotation_chain, msg, arg); + //printf("pre x: %3d..%3d y: %3d..%3d ", ((u8g_box_t *)arg)->x0, ((u8g_box_t *)arg)->x1, ((u8g_box_t *)arg)->y0, ((u8g_box_t *)arg)->y1); + { + u8g_box_t new_box; + + new_box.x0 = u8g_GetHeightLL(u8g,rotation_chain) - ((u8g_box_t *)arg)->y1 - 1; + new_box.x1 = u8g_GetHeightLL(u8g,rotation_chain) - ((u8g_box_t *)arg)->y0 - 1; + new_box.y0 = u8g_GetWidthLL(u8g,rotation_chain) - ((u8g_box_t *)arg)->x1 - 1; + new_box.y1 = u8g_GetWidthLL(u8g,rotation_chain) - ((u8g_box_t *)arg)->x0 - 1; + *((u8g_box_t *)arg) = new_box; + //printf("post x: %3d..%3d y: %3d..%3d\n", ((u8g_box_t *)arg)->x0, ((u8g_box_t *)arg)->x1, ((u8g_box_t *)arg)->y0, ((u8g_box_t *)arg)->y1); + } + break; + case U8G_DEV_MSG_GET_WIDTH: + *((u8g_uint_t *)arg) = u8g_GetHeightLL(u8g,rotation_chain); + break; + case U8G_DEV_MSG_GET_HEIGHT: + *((u8g_uint_t *)arg) = u8g_GetWidthLL(u8g, rotation_chain); + break; + case U8G_DEV_MSG_SET_PIXEL: + case U8G_DEV_MSG_SET_TPIXEL: + { + u8g_uint_t x, y; + x = ((u8g_dev_arg_pixel_t *)arg)->y; + + y = u8g_GetHeightLL(u8g, rotation_chain); + y -= ((u8g_dev_arg_pixel_t *)arg)->x; + y--; + + /* + x = u8g_GetWidthLL(u8g, rotation_chain); + x -= ((u8g_dev_arg_pixel_t *)arg)->y; + x--; + */ + ((u8g_dev_arg_pixel_t *)arg)->x = x; + ((u8g_dev_arg_pixel_t *)arg)->y = y; + } + u8g_call_dev_fn(u8g, rotation_chain, msg, arg); + break; + case U8G_DEV_MSG_SET_8PIXEL: + case U8G_DEV_MSG_SET_4TPIXEL: + { + u8g_uint_t x, y; + x = ((u8g_dev_arg_pixel_t *)arg)->y; + + y = u8g_GetHeightLL(u8g, rotation_chain); + y -= ((u8g_dev_arg_pixel_t *)arg)->x; + y--; + + /* + x = u8g_GetWidthLL(u8g, rotation_chain); + x -= ((u8g_dev_arg_pixel_t *)arg)->y; + x--; + */ + ((u8g_dev_arg_pixel_t *)arg)->x = x; + ((u8g_dev_arg_pixel_t *)arg)->y = y; + ((u8g_dev_arg_pixel_t *)arg)->dir+=3; + ((u8g_dev_arg_pixel_t *)arg)->dir &= 3; + } + u8g_call_dev_fn(u8g, rotation_chain, msg, arg); + break; + } + return 1; +} + + +#pragma GCC diagnostic push diff --git a/trunk/Arduino/Repetier_0.92.9/ui.cpp b/trunk/Arduino/Repetier_0.92.9/ui.cpp new file mode 100644 index 00000000..97bfd223 --- /dev/null +++ b/trunk/Arduino/Repetier_0.92.9/ui.cpp @@ -0,0 +1,3837 @@ +/* + This file is part of Repetier-Firmware. + + Repetier-Firmware is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Repetier-Firmware is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Repetier-Firmware. If not, see . + +*/ + +#define UI_MAIN 1 +#include "Repetier.h" +// The uimenu.h declares static variables of menus, which must be declared only once. +// It does not define interfaces for other modules, so should never be included elsewhere +#include "uimenu.h" + +extern const int8_t encoder_table[16] PROGMEM ; +#include +#include +#include +#include + +#if FEATURE_SERVO > 0 && UI_SERVO_CONTROL > 0 +#if UI_SERVO_CONTROL == 1 && defined(SERVO0_NEUTRAL_POS) +uint16_t servoPosition = SERVO0_NEUTRAL_POS; +#elif UI_SERVO_CONTROL == 2 && defined(SERVO1_NEUTRAL_POS) +uint16_t servoPosition = SERVO1_NEUTRAL_POS; +#elif UI_SERVO_CONTROL == 3 && defined(SERVO2_NEUTRAL_POS) +uint16_t servoPosition = SERVO2_NEUTRAL_POS; +#elif UI_SERVO_CONTROL == 4 && defined(SERVO3_NEUTRAL_POS) +uint16_t servoPosition = SERVO3_NEUTRAL_POS; +#else +uint16_t servoPosition = 1500; +#endif +#endif + +#if BEEPER_TYPE==2 && defined(UI_HAS_I2C_KEYS) && UI_I2C_KEY_ADDRESS!=BEEPER_ADDRESS +#error Beeper address and i2c key address must be identical +#else +#if BEEPER_TYPE==2 +#define UI_I2C_KEY_ADDRESS BEEPER_ADDRESS +#endif +#endif + +static TemperatureController *currHeaterForSetup; // pointer to extruder or heatbed temperature controller + +#if UI_AUTORETURN_TO_MENU_AFTER != 0 +millis_t ui_autoreturn_time = 0; +#endif +#if FEATURE_BABYSTEPPING +int zBabySteps = 0; +#endif + +void beep(uint8_t duration,uint8_t count) +{ +#if FEATURE_BEEPER +#if BEEPER_TYPE!=0 +#if BEEPER_TYPE==1 && defined(BEEPER_PIN) && BEEPER_PIN>=0 + SET_OUTPUT(BEEPER_PIN); +#endif +#if BEEPER_TYPE==2 + HAL::i2cStartWait(BEEPER_ADDRESS+I2C_WRITE); +#if UI_DISPLAY_I2C_CHIPTYPE==1 + HAL::i2cWrite( 0x14); // Start at port a +#endif +#endif + for(uint8_t i=0; i < count; i++) + { +#if BEEPER_TYPE==1 && defined(BEEPER_PIN) && BEEPER_PIN>=0 +#if defined(BEEPER_TYPE_INVERTING) && BEEPER_TYPE_INVERTING + WRITE(BEEPER_PIN,LOW); +#else + WRITE(BEEPER_PIN,HIGH); +#endif +#else +#if UI_DISPLAY_I2C_CHIPTYPE==0 +#if BEEPER_ADDRESS == UI_DISPLAY_I2C_ADDRESS + HAL::i2cWrite(uid.outputMask & ~BEEPER_PIN); +#else + HAL::i2cWrite(~BEEPER_PIN); +#endif +#endif +#if UI_DISPLAY_I2C_CHIPTYPE==1 + HAL::i2cWrite((BEEPER_PIN) | uid.outputMask); + HAL::i2cWrite(((BEEPER_PIN) | uid.outputMask)>>8); +#endif +#endif + HAL::delayMilliseconds(duration); +#if BEEPER_TYPE==1 && defined(BEEPER_PIN) && BEEPER_PIN>=0 +#if defined(BEEPER_TYPE_INVERTING) && BEEPER_TYPE_INVERTING + WRITE(BEEPER_PIN,HIGH); +#else + WRITE(BEEPER_PIN,LOW); +#endif +#else +#if UI_DISPLAY_I2C_CHIPTYPE==0 + +#if BEEPER_ADDRESS == UI_DISPLAY_I2C_ADDRESS + HAL::i2cWrite((BEEPER_PIN) | uid.outputMask); +#else + HAL::i2cWrite(255); +#endif +#endif +#if UI_DISPLAY_I2C_CHIPTYPE==1 + HAL::i2cWrite( uid.outputMask); + HAL::i2cWrite(uid.outputMask>>8); +#endif +#endif + HAL::delayMilliseconds(duration); + } +#if BEEPER_TYPE==2 + HAL::i2cStop(); +#endif +#endif +#endif +} + +bool UIMenuEntry::showEntry() const +{ + bool ret = true; + uint8_t f, f2; + f = HAL::readFlashByte((PGM_P)&filter); + if(f != 0) + ret = (f & Printer::menuMode) != 0; + if(ret && (f2 = HAL::readFlashByte((PGM_P)&nofilter)) != 0) + ret = (f2 & Printer::menuMode) == 0; + return ret; +} + +#if UI_DISPLAY_TYPE != NO_DISPLAY +UIDisplay uid; +char displayCache[UI_ROWS][MAX_COLS+1]; + +// Menu up sign - code 1 +// ..*.. 4 +// .***. 14 +// *.*.* 21 +// ..*.. 4 +// ..*.. 4 +// ..*.. 4 +// ***.. 28 +// ..... 0 +const uint8_t character_back[8] PROGMEM = {4, 14, 21, 4, 4, 4, 28, 0}; +// Degrees sign - code 2 +// ..*.. 4 +// .*.*. 10 +// ..*.. 4 +// ..... 0 +// ..... 0 +// ..... 0 +// ..... 0 +// ..... 0 +const uint8_t character_degree[8] PROGMEM = {4,10,4,0,0,0,0,0}; +// selected - code 3 +// ..... 0 +// ***** 31 +// ***** 31 +// ***** 31 +// ***** 31 +// ***** 31 +// ***** 31 +// ..... 0 +// ..... 0 +const uint8_t character_selected[8] PROGMEM = {0,31,31,31,31,31,0,0}; +// unselected - code 4 +// ..... 0 +// ***** 31 +// *...* 17 +// *...* 17 +// *...* 17 +// *...* 17 +// ***** 31 +// ..... 0 +// ..... 0 +const uint8_t character_unselected[8] PROGMEM = {0,31,17,17,17,31,0,0}; +// unselected - code 5 +// ..*.. 4 +// .*.*. 10 +// .*.*. 10 +// .*.*. 10 +// .*.*. 10 +// .***. 14 +// ***** 31 +// ***** 31 +// .***. 14 +const uint8_t character_temperature[8] PROGMEM = {4,10,10,10,14,31,31,14}; +// unselected - code 6 +// ..... 0 +// ***.. 28 +// ***** 31 +// *...* 17 +// *...* 17 +// ***** 31 +// ..... 0 +// ..... 0 +const uint8_t character_folder[8] PROGMEM = {0,28,31,17,17,31,0,0}; + +// printer ready - code 7 +// *...* 17 +// .*.*. 10 +// ..*.. 4 +// *...* 17 +// ..*.. 4 +// .*.*. 10 +// *...* 17 +// *...* 17 +const byte character_ready[8] PROGMEM = {17,10,4,17,4,10,17,17}; + +const long baudrates[] PROGMEM = {9600,14400,19200,28800,38400,56000,57600,76800,111112,115200,128000,230400,250000,256000, + 460800,500000,921600,1000000,1500000,0 + }; + +#define LCD_ENTRYMODE 0x04 /**< Set entrymode */ + +/** @name GENERAL COMMANDS */ +/*@{*/ +#define LCD_CLEAR 0x01 /**< Clear screen */ +#define LCD_HOME 0x02 /**< Cursor move to first digit */ +/*@}*/ + +/** @name ENTRYMODES */ +/*@{*/ +#define LCD_ENTRYMODE 0x04 /**< Set entrymode */ +#define LCD_INCREASE LCD_ENTRYMODE | 0x02 /**< Set cursor move direction -- Increase */ +#define LCD_DECREASE LCD_ENTRYMODE | 0x00 /**< Set cursor move direction -- Decrease */ +#define LCD_DISPLAYSHIFTON LCD_ENTRYMODE | 0x01 /**< Display is shifted */ +#define LCD_DISPLAYSHIFTOFF LCD_ENTRYMODE | 0x00 /**< Display is not shifted */ +/*@}*/ + +/** @name DISPLAYMODES */ +/*@{*/ +#define LCD_DISPLAYMODE 0x08 /**< Set displaymode */ +#define LCD_DISPLAYON LCD_DISPLAYMODE | 0x04 /**< Display on */ +#define LCD_DISPLAYOFF LCD_DISPLAYMODE | 0x00 /**< Display off */ +#define LCD_CURSORON LCD_DISPLAYMODE | 0x02 /**< Cursor on */ +#define LCD_CURSOROFF LCD_DISPLAYMODE | 0x00 /**< Cursor off */ +#define LCD_BLINKINGON LCD_DISPLAYMODE | 0x01 /**< Blinking on */ +#define LCD_BLINKINGOFF LCD_DISPLAYMODE | 0x00 /**< Blinking off */ +/*@}*/ + +/** @name SHIFTMODES */ +/*@{*/ +#define LCD_SHIFTMODE 0x10 /**< Set shiftmode */ +#define LCD_DISPLAYSHIFT LCD_SHIFTMODE | 0x08 /**< Display shift */ +#define LCD_CURSORMOVE LCD_SHIFTMODE | 0x00 /**< Cursor move */ +#define LCD_RIGHT LCD_SHIFTMODE | 0x04 /**< Right shift */ +#define LCD_LEFT LCD_SHIFTMODE | 0x00 /**< Left shift */ +/*@}*/ + +/** @name DISPLAY_CONFIGURATION */ +/*@{*/ +#define LCD_CONFIGURATION 0x20 /**< Set function */ +#define LCD_8BIT LCD_CONFIGURATION | 0x10 /**< 8 bits interface */ +#define LCD_4BIT LCD_CONFIGURATION | 0x00 /**< 4 bits interface */ +#define LCD_2LINE LCD_CONFIGURATION | 0x08 /**< 2 line display */ +#define LCD_1LINE LCD_CONFIGURATION | 0x00 /**< 1 line display */ +#define LCD_5X10 LCD_CONFIGURATION | 0x04 /**< 5 X 10 dots */ +#define LCD_5X7 LCD_CONFIGURATION | 0x00 /**< 5 X 7 dots */ + +#define LCD_SETCGRAMADDR 0x40 + +#define lcdPutChar(value) lcdWriteByte(value,1) +#define lcdCommand(value) lcdWriteByte(value,0) + +static const uint8_t LCDLineOffsets[] PROGMEM = UI_LINE_OFFSETS; +static const char versionString[] PROGMEM = UI_VERSION_STRING; + + +#if UI_DISPLAY_TYPE == DISPLAY_I2C + +// ============= I2C LCD Display driver ================ +inline void lcdStartWrite() +{ + HAL::i2cStartWait(UI_DISPLAY_I2C_ADDRESS+I2C_WRITE); +#if UI_DISPLAY_I2C_CHIPTYPE == 1 + HAL::i2cWrite( 0x14); // Start at port a +#endif +} +inline void lcdStopWrite() +{ + HAL::i2cStop(); +} +void lcdWriteNibble(uint8_t value) +{ +#if UI_DISPLAY_I2C_CHIPTYPE==0 + value |= uid.outputMask; +#if UI_DISPLAY_D4_PIN==1 && UI_DISPLAY_D5_PIN==2 && UI_DISPLAY_D6_PIN==4 && UI_DISPLAY_D7_PIN==8 + HAL::i2cWrite((value) | UI_DISPLAY_ENABLE_PIN); + HAL::i2cWrite(value); +#else + uint8_t v=(value & 1?UI_DISPLAY_D4_PIN:0)|(value & 2?UI_DISPLAY_D5_PIN:0)|(value & 4?UI_DISPLAY_D6_PIN:0)|(value & 8?UI_DISPLAY_D7_PIN:0); + HAL::i2cWrite((v) | UI_DISPLAY_ENABLE_PIN); + HAL::i2cWrite(v); +# +#endif +#endif +#if UI_DISPLAY_I2C_CHIPTYPE==1 + unsigned int v=(value & 1?UI_DISPLAY_D4_PIN:0)|(value & 2?UI_DISPLAY_D5_PIN:0)|(value & 4?UI_DISPLAY_D6_PIN:0)|(value & 8?UI_DISPLAY_D7_PIN:0) | uid.outputMask; + unsigned int v2 = v | UI_DISPLAY_ENABLE_PIN; + HAL::i2cWrite(v2 & 255); + HAL::i2cWrite(v2 >> 8); + HAL::i2cWrite(v & 255); + HAL::i2cWrite(v >> 8); +#endif +} +void lcdWriteByte(uint8_t c,uint8_t rs) +{ +#if UI_DISPLAY_I2C_CHIPTYPE==0 + uint8_t mod = (rs?UI_DISPLAY_RS_PIN:0) | uid.outputMask; // | (UI_DISPLAY_RW_PIN); +#if UI_DISPLAY_D4_PIN==1 && UI_DISPLAY_D5_PIN==2 && UI_DISPLAY_D6_PIN==4 && UI_DISPLAY_D7_PIN==8 + uint8_t value = (c >> 4) | mod; + HAL::i2cWrite((value) | UI_DISPLAY_ENABLE_PIN); + HAL::i2cWrite(value); + value = (c & 15) | mod; + HAL::i2cWrite((value) | UI_DISPLAY_ENABLE_PIN); + HAL::i2cWrite(value); +#else + uint8_t value = (c & 16?UI_DISPLAY_D4_PIN:0)|(c & 32?UI_DISPLAY_D5_PIN:0)|(c & 64?UI_DISPLAY_D6_PIN:0)|(c & 128?UI_DISPLAY_D7_PIN:0) | mod; + HAL::i2cWrite((value) | UI_DISPLAY_ENABLE_PIN); + HAL::i2cWrite(value); + value = (c & 1?UI_DISPLAY_D4_PIN:0)|(c & 2?UI_DISPLAY_D5_PIN:0)|(c & 4?UI_DISPLAY_D6_PIN:0)|(c & 8?UI_DISPLAY_D7_PIN:0) | mod; + HAL::i2cWrite((value) | UI_DISPLAY_ENABLE_PIN); + HAL::i2cWrite(value); +#endif +#endif +#if UI_DISPLAY_I2C_CHIPTYPE==1 + unsigned int mod = (rs?UI_DISPLAY_RS_PIN:0) | uid.outputMask; // | (UI_DISPLAY_RW_PIN); + unsigned int value = (c & 16?UI_DISPLAY_D4_PIN:0)|(c & 32?UI_DISPLAY_D5_PIN:0)|(c & 64?UI_DISPLAY_D6_PIN:0)|(c & 128?UI_DISPLAY_D7_PIN:0) | mod; + unsigned int value2 = (value) | UI_DISPLAY_ENABLE_PIN; + HAL::i2cWrite(value2 & 255); + HAL::i2cWrite(value2 >>8); + HAL::i2cWrite(value & 255); + HAL::i2cWrite(value>>8); + value = (c & 1?UI_DISPLAY_D4_PIN:0)|(c & 2?UI_DISPLAY_D5_PIN:0)|(c & 4?UI_DISPLAY_D6_PIN:0)|(c & 8?UI_DISPLAY_D7_PIN:0) | mod; + value2 = (value) | UI_DISPLAY_ENABLE_PIN; + HAL::i2cWrite(value2 & 255); + HAL::i2cWrite(value2 >>8); + HAL::i2cWrite(value & 255); + HAL::i2cWrite(value>>8); +#endif +} +void initializeLCD() +{ + HAL::delayMilliseconds(235); + lcdStartWrite(); + HAL::i2cWrite(uid.outputMask & 255); +#if UI_DISPLAY_I2C_CHIPTYPE==1 + HAL::i2cWrite(uid.outputMask >> 8); +#endif + HAL::delayMicroseconds(20); + lcdWriteNibble(0x03); + HAL::delayMicroseconds(6000); // I have one LCD for which 4500 here was not long enough. + // second try + lcdWriteNibble(0x03); + HAL::delayMicroseconds(180); // wait + // third go! + lcdWriteNibble(0x03); + HAL::delayMicroseconds(180); + // finally, set to 4-bit interface + lcdWriteNibble(0x02); + HAL::delayMicroseconds(180); + // finally, set # lines, font size, etc. + lcdCommand(LCD_4BIT | LCD_2LINE | LCD_5X7); + lcdCommand(LCD_CLEAR); //- Clear Screen + HAL::delayMilliseconds(4); // clear is slow operation + lcdCommand(LCD_INCREASE | LCD_DISPLAYSHIFTOFF); //- Entrymode (Display Shift: off, Increment Address Counter) + lcdCommand(LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKINGOFF); //- Display on + uid.lastSwitch = uid.lastRefresh = HAL::timeInMilliseconds(); + uid.createChar(1,character_back); + uid.createChar(2,character_degree); + uid.createChar(3,character_selected); + uid.createChar(4,character_unselected); + uid.createChar(5,character_temperature); + uid.createChar(6,character_folder); + uid.createChar(7,character_ready); + lcdStopWrite(); +} +#endif +#if UI_DISPLAY_TYPE == DISPLAY_4BIT || UI_DISPLAY_TYPE == DISPLAY_8BIT + +void lcdWriteNibble(uint8_t value) +{ + WRITE(UI_DISPLAY_D4_PIN,value & 1); + WRITE(UI_DISPLAY_D5_PIN,value & 2); + WRITE(UI_DISPLAY_D6_PIN,value & 4); + WRITE(UI_DISPLAY_D7_PIN,value & 8); + DELAY1MICROSECOND; + WRITE(UI_DISPLAY_ENABLE_PIN, HIGH);// enable pulse must be >450ns + HAL::delayMicroseconds(2); + WRITE(UI_DISPLAY_ENABLE_PIN, LOW); + HAL::delayMicroseconds(UI_DELAYPERCHAR); +} + +void lcdWriteByte(uint8_t c,uint8_t rs) +{ +#if false && UI_DISPLAY_RW_PIN >= 0 // not really needed + SET_INPUT(UI_DISPLAY_D4_PIN); + SET_INPUT(UI_DISPLAY_D5_PIN); + SET_INPUT(UI_DISPLAY_D6_PIN); + SET_INPUT(UI_DISPLAY_D7_PIN); + WRITE(UI_DISPLAY_RW_PIN, HIGH); + WRITE(UI_DISPLAY_RS_PIN, LOW); + uint8_t busy; + do + { + WRITE(UI_DISPLAY_ENABLE_PIN, HIGH); + DELAY1MICROSECOND; + busy = READ(UI_DISPLAY_D7_PIN); + WRITE(UI_DISPLAY_ENABLE_PIN, LOW); + DELAY2MICROSECOND; + + WRITE(UI_DISPLAY_ENABLE_PIN, HIGH); + DELAY2MICROSECOND; + + WRITE(UI_DISPLAY_ENABLE_PIN, LOW); + DELAY2MICROSECOND; + + } + while (busy); + SET_OUTPUT(UI_DISPLAY_D4_PIN); + SET_OUTPUT(UI_DISPLAY_D5_PIN); + SET_OUTPUT(UI_DISPLAY_D6_PIN); + SET_OUTPUT(UI_DISPLAY_D7_PIN); + WRITE(UI_DISPLAY_RW_PIN, LOW); +#endif + WRITE(UI_DISPLAY_RS_PIN, rs); + + WRITE(UI_DISPLAY_D4_PIN, c & 0x10); + WRITE(UI_DISPLAY_D5_PIN, c & 0x20); + WRITE(UI_DISPLAY_D6_PIN, c & 0x40); + WRITE(UI_DISPLAY_D7_PIN, c & 0x80); +#if FEATURE_CONTROLLER == CONTROLLER_RADDS + HAL::delayMicroseconds(10); +#else + HAL::delayMicroseconds(2); +#endif + WRITE(UI_DISPLAY_ENABLE_PIN, HIGH); // enable pulse must be >450ns +#if FEATURE_CONTROLLER == CONTROLLER_RADDS + HAL::delayMicroseconds(10); +#else + HAL::delayMicroseconds(2); +#endif + WRITE(UI_DISPLAY_ENABLE_PIN, LOW); + + WRITE(UI_DISPLAY_D4_PIN, c & 0x01); + WRITE(UI_DISPLAY_D5_PIN, c & 0x02); + WRITE(UI_DISPLAY_D6_PIN, c & 0x04); + WRITE(UI_DISPLAY_D7_PIN, c & 0x08); + HAL::delayMicroseconds(2); + WRITE(UI_DISPLAY_ENABLE_PIN, HIGH); // enable pulse must be >450ns + HAL::delayMicroseconds(2); + WRITE(UI_DISPLAY_ENABLE_PIN, LOW); + HAL::delayMicroseconds(100); +} + +#ifdef TRY_AUTOREPAIR_LCD_ERRORS +#define HAS_AUTOREPAIR +/* Fast repair function for displays loosing their settings. + Do not call this if your display has no problems. +*/ +void repairLCD() +{ + // Now we pull both RS and R/W low to begin commands + WRITE(UI_DISPLAY_RS_PIN, LOW); + WRITE(UI_DISPLAY_ENABLE_PIN, LOW); + + //put the LCD into 4 bit mode + // this is according to the hitachi HD44780 datasheet + // figure 24, pg 46 + + // we start in 8bit mode, try to set 4 bit mode + // at this point we are in 8 bit mode but of course in this + // interface 4 pins are dangling unconnected and the values + // on them don't matter for these instructions. + WRITE(UI_DISPLAY_RS_PIN, LOW); + HAL::delayMicroseconds(20); + lcdWriteNibble(0x03); + HAL::delayMicroseconds(5000); // I have one LCD for which 4500 here was not long enough. + // second try + //lcdWriteNibble(0x03); + //HAL::delayMicroseconds(5000); // wait + // third go! + //lcdWriteNibble(0x03); + //HAL::delayMicroseconds(160); + // finally, set to 4-bit interface + lcdWriteNibble(0x02); + HAL::delayMicroseconds(160); + // finally, set # lines, font size, etc. + lcdCommand(LCD_4BIT | LCD_2LINE | LCD_5X7); + lcdCommand(LCD_INCREASE | LCD_DISPLAYSHIFTOFF); //- Entrymode (Display Shift: off, Increment Address Counter) + lcdCommand(LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKINGOFF); //- Display on + uid.lastSwitch = uid.lastRefresh = HAL::timeInMilliseconds(); + uid.createChar(1, character_back); + uid.createChar(2, character_degree); + uid.createChar(3, character_selected); + uid.createChar(4, character_unselected); + uid.createChar(5, character_temperature); + uid.createChar(6, character_folder); + uid.createChar(7, character_ready); +} +#endif + +void initializeLCD() +{ + // SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION! + // according to datasheet, we need at least 40ms after power rises above 2.7V + // before sending commands. Arduino can turn on way before 4.5V. + // is this delay long enough for all cases?? + HAL::delayMilliseconds(235); + SET_OUTPUT(UI_DISPLAY_D4_PIN); + SET_OUTPUT(UI_DISPLAY_D5_PIN); + SET_OUTPUT(UI_DISPLAY_D6_PIN); + SET_OUTPUT(UI_DISPLAY_D7_PIN); + SET_OUTPUT(UI_DISPLAY_RS_PIN); +#if UI_DISPLAY_RW_PIN > -1 + SET_OUTPUT(UI_DISPLAY_RW_PIN); +#endif + SET_OUTPUT(UI_DISPLAY_ENABLE_PIN); + + // Now we pull both RS and R/W low to begin commands + WRITE(UI_DISPLAY_RS_PIN, LOW); + WRITE(UI_DISPLAY_ENABLE_PIN, LOW); + + //put the LCD into 4 bit mode + // this is according to the hitachi HD44780 datasheet + // figure 24, pg 46 + + // we start in 8bit mode, try to set 4 bit mode + // at this point we are in 8 bit mode but of course in this + // interface 4 pins are dangling unconnected and the values + // on them don't matter for these instructions. + WRITE(UI_DISPLAY_RS_PIN, LOW); + HAL::delayMicroseconds(20); + lcdWriteNibble(0x03); + HAL::delayMicroseconds(5000); // I have one LCD for which 4500 here was not long enough. + // second try + lcdWriteNibble(0x03); + HAL::delayMicroseconds(5000); // wait + // third go! + lcdWriteNibble(0x03); + HAL::delayMicroseconds(160); + // finally, set to 4-bit interface + lcdWriteNibble(0x02); + HAL::delayMicroseconds(160); + // finally, set # lines, font size, etc. + lcdCommand(LCD_4BIT | LCD_2LINE | LCD_5X7); + + lcdCommand(LCD_CLEAR); //- Clear Screen + HAL::delayMilliseconds(3); // clear is slow operation + lcdCommand(LCD_INCREASE | LCD_DISPLAYSHIFTOFF); //- Entrymode (Display Shift: off, Increment Address Counter) + lcdCommand(LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKINGOFF); //- Display on + uid.lastSwitch = uid.lastRefresh = HAL::timeInMilliseconds(); + uid.createChar(1, character_back); + uid.createChar(2, character_degree); + uid.createChar(3, character_selected); + uid.createChar(4, character_unselected); + uid.createChar(5, character_temperature); + uid.createChar(6, character_folder); + uid.createChar(7, character_ready); +} +// ----------- end direct LCD driver +#endif +#if UI_DISPLAY_TYPE < DISPLAY_ARDUINO_LIB +void UIDisplay::printRow(uint8_t r,char *txt,char *txt2,uint8_t changeAtCol) +{ + changeAtCol = RMath::min(UI_COLS, changeAtCol); + uint8_t col = 0; +// Set row + if(r >= UI_ROWS) return; +#if UI_DISPLAY_TYPE == DISPLAY_I2C + lcdStartWrite(); +#endif + lcdWriteByte(128 + HAL::readFlashByte((const char *)&LCDLineOffsets[r]), 0); // Position cursor + char c; + while((c = *txt) != 0x00 && col < changeAtCol) + { + txt++; + lcdPutChar(c); + col++; + } + while(col < changeAtCol) + { + lcdPutChar(' '); + col++; + } + if(txt2 != NULL) + { + while((c = *txt2) != 0x00 && col < UI_COLS) + { + txt2++; + lcdPutChar(c); + col++; + } + while(col < UI_COLS) + { + lcdPutChar(' '); + col++; + } + } +#if UI_DISPLAY_TYPE == DISPLAY_I2C + lcdStopWrite(); +#endif +#if UI_HAS_KEYS==1 && UI_HAS_I2C_ENCODER>0 + uiCheckSlowEncoder(); +#endif +} +#endif + +#if UI_DISPLAY_TYPE == DISPLAY_ARDUINO_LIB +// Use LiquidCrystal library instead +#include + +LiquidCrystal lcd(UI_DISPLAY_RS_PIN, UI_DISPLAY_RW_PIN,UI_DISPLAY_ENABLE_PIN,UI_DISPLAY_D4_PIN,UI_DISPLAY_D5_PIN,UI_DISPLAY_D6_PIN,UI_DISPLAY_D7_PIN); + +void UIDisplay::createChar(uint8_t location,const uint8_t charmap[]) +{ + location &= 0x7; // we only have 8 locations 0-7 + uint8_t data[8]; + for (int i = 0; i < 8; i++) + { + data[i] = pgm_read_byte(&(charmap[i])); + } + lcd.createChar(location, data); +} +void UIDisplay::printRow(uint8_t r,char *txt,char *txt2,uint8_t changeAtCol) +{ + changeAtCol = RMath::min(UI_COLS,changeAtCol); + uint8_t col = 0; +// Set row + if(r >= UI_ROWS) return; + lcd.setCursor(0,r); + char c; + while((c = *txt) != 0x00 && col < changeAtCol) + { + txt++; + lcd.write(c); + col++; + } + while(col < changeAtCol) + { + lcd.write(' '); + col++; + } + if(txt2 != NULL) + { + while((c = *txt2) != 0x00 && col < UI_COLS) + { + txt2++; + lcd.write(c); + col++; + } + while(col < UI_COLS) + { + lcd.write(' '); + col++; + } + } +#if UI_HAS_KEYS==1 && UI_HAS_I2C_ENCODER>0 + uiCheckSlowEncoder(); +#endif +} + +void initializeLCD() +{ + lcd.begin(UI_COLS,UI_ROWS); + uid.lastSwitch = uid.lastRefresh = HAL::timeInMilliseconds(); + uid.createChar(1,character_back); + uid.createChar(2,character_degree); + uid.createChar(3,character_selected); + uid.createChar(4,character_unselected); +} +// ------------------ End LiquidCrystal library as LCD driver +#endif // UI_DISPLAY_TYPE == DISPLAY_ARDUINO_LIB + +#if UI_DISPLAY_TYPE == DISPLAY_U8G +//u8glib +#if defined(U8GLIB_ST7920) || defined(U8GLIB_SSD1306_SW_SPI) +#define UI_SPI_SCK UI_DISPLAY_D4_PIN +#define UI_SPI_MOSI UI_DISPLAY_ENABLE_PIN +#define UI_SPI_CS UI_DISPLAY_RS_PIN +#endif +#include "u8glib_ex.h" +#include "logo.h" + +u8g_t u8g; +u8g_uint_t u8_tx = 0, u8_ty = 0; + +void u8PrintChar(char c) +{ + switch((uint8_t)c) + { + case 0x7E: // right arrow + u8g_SetFont(&u8g, u8g_font_6x12_67_75); + u8_tx += u8g_DrawGlyph(&u8g, u8_tx, u8_ty, 0x52); + u8g_SetFont(&u8g, UI_FONT_DEFAULT); + break; + case CHAR_SELECTOR: + u8g_SetFont(&u8g, u8g_font_6x12_67_75); + u8_tx += u8g_DrawGlyph(&u8g, u8_tx, u8_ty, 0xb7); + u8g_SetFont(&u8g, UI_FONT_DEFAULT); + break; + case CHAR_SELECTED: + u8g_SetFont(&u8g, u8g_font_6x12_67_75); + u8_tx += u8g_DrawGlyph(&u8g, u8_tx, u8_ty, 0xb6); + u8g_SetFont(&u8g, UI_FONT_DEFAULT); + break; + case 253: //shift one pixel to right + u8_tx++; + break; + default: + u8_tx += u8g_DrawGlyph(&u8g, u8_tx, u8_ty, c); + } +} +void printU8GRow(uint8_t x,uint8_t y,char *text) +{ + char c; + u8_tx = x; + u8_ty = y; + while((c = *(text++)) != 0) u8PrintChar(c); //version compatible with position adjust +// x += u8g_DrawGlyph(&u8g,x,y,c); +} +void UIDisplay::printRow(uint8_t r,char *txt,char *txt2,uint8_t changeAtCol) +{ + changeAtCol = RMath::min(UI_COLS,changeAtCol); + uint8_t col = 0; +// Set row + if(r >= UI_ROWS) return; + int y = r * UI_FONT_HEIGHT; + if(!u8g_IsBBXIntersection(&u8g,0,y,UI_LCD_WIDTH,UI_FONT_HEIGHT+2)) return; // row not visible + u8_tx = 0; + u8_ty = y+UI_FONT_HEIGHT; //set position + bool highlight = ((uint8_t)(*txt) == CHAR_SELECTOR) || ((uint8_t)(*txt) == CHAR_SELECTED); + if(highlight) + { + u8g_SetColorIndex(&u8g,1); + u8g_draw_box(&u8g, 0, y + 1, u8g_GetWidth(&u8g), UI_FONT_HEIGHT + 1); + u8g_SetColorIndex(&u8g, 0); + } + char c; + while((c = *(txt++)) != 0 && col < changeAtCol) + { + u8PrintChar(c); + col++; + } + if(txt2 != NULL) + { + col = changeAtCol; + u8_tx = col*UI_FONT_WIDTH; //set position + while((c=*(txt2++)) != 0 && col < UI_COLS) + { + u8PrintChar(c); + col++; + } + } + if(highlight) + { + u8g_SetColorIndex(&u8g,1); + } + +#if UI_HAS_KEYS==1 && UI_HAS_I2C_ENCODER>0 + uiCheckSlowEncoder(); +#endif +} + +void initializeLCD() +{ +#ifdef U8GLIB_ST7920 + u8g_InitSPI(&u8g,&u8g_dev_st7920_128x64_sw_spi, UI_DISPLAY_D4_PIN, UI_DISPLAY_ENABLE_PIN, UI_DISPLAY_RS_PIN, U8G_PIN_NONE, U8G_PIN_NONE); +#endif +#ifdef U8GLIB_SSD1306_I2C + u8g_InitI2C(&u8g,&u8g_dev_ssd1306_128x64_i2c,U8G_I2C_OPT_NONE); +#endif +#ifdef U8GLIB_SSD1306_SW_SPI + u8g_InitSPI(&u8g,&u8g_dev_ssd1306_128x64_sw_spi, UI_DISPLAY_D4_PIN, UI_DISPLAY_ENABLE_PIN, UI_DISPLAY_RS_PIN, U8G_PIN_NONE, U8G_PIN_NONE); +#endif +#ifdef U8GLIB_SH1106_SW_SPI + u8g_InitSPI(&u8g,&u8g_dev_sh1106_128x64_sw_spi, UI_DISPLAY_D4_PIN, UI_DISPLAY_ENABLE_PIN, UI_DISPLAY_RS_PIN, U8G_PIN_NONE, U8G_PIN_NONE); +#endif +#ifdef U8GLIB_KS0108_FAST + u8g_Init8Bit(&u8g,&u8g_dev_ks0108_128x64_fast,UI_DISPLAY_D0_PIN,UI_DISPLAY_D1_PIN,UI_DISPLAY_D2_PIN,UI_DISPLAY_D3_PIN,UI_DISPLAY_D4_PIN,UI_DISPLAY_D5_PIN,UI_DISPLAY_D6_PIN,UI_DISPLAY_D7_PIN,UI_DISPLAY_ENABLE_PIN,UI_DISPLAY_CS1,UI_DISPLAY_CS2, + UI_DISPLAY_DI,UI_DISPLAY_RW_PIN,UI_DISPLAY_RESET_PIN); +#endif +#ifdef U8GLIB_KS0108 + u8g_Init8Bit(&u8g,&u8g_dev_ks0108_128x64,UI_DISPLAY_D0_PIN,UI_DISPLAY_D1_PIN,UI_DISPLAY_D2_PIN,UI_DISPLAY_D3_PIN,UI_DISPLAY_D4_PIN,UI_DISPLAY_D5_PIN,UI_DISPLAY_D6_PIN,UI_DISPLAY_D7_PIN,UI_DISPLAY_ENABLE_PIN,UI_DISPLAY_CS1,UI_DISPLAY_CS2, + UI_DISPLAY_DI,UI_DISPLAY_RW_PIN,UI_DISPLAY_RESET_PIN); +#endif +#ifdef U8GLIB_ST7565_NHD_C2832_HW_SPI + u8g_InitHWSPI(&u8g,&u8g_dev_st7565_nhd_c12864_hw_spi,UI_DISPLAY_RS_PIN,UI_DISPLAY_D5_PIN,U8G_PIN_NONE); +#endif +#ifdef U8GLIB_ST7565_NHD_C2832_SW_SPI +u8g_InitSPI(&u8g,&u8g_dev_st7565_nhd_c12864_sw_spi,UI_DISPLAY_D4_PIN,UI_DISPLAY_ENABLE_PIN,UI_DISPLAY_RS_PIN,UI_DISPLAY_D5_PIN,U8G_PIN_NONE); +#endif + u8g_Begin(&u8g); +#ifdef UI_ROTATE_180 + u8g_SetRot180(&u8g); +#endif + u8g_FirstPage(&u8g); + do + { + u8g_SetColorIndex(&u8g, 0); + } + while( u8g_NextPage(&u8g) ); + + u8g_SetFont(&u8g, UI_FONT_DEFAULT); + u8g_SetColorIndex(&u8g, 1); + uid.lastSwitch = uid.lastRefresh = HAL::timeInMilliseconds(); +} +// ------------------ End u8GLIB library as LCD driver +#endif // UI_DISPLAY_TYPE == DISPLAY_U8G + +#if UI_DISPLAY_TYPE == DISPLAY_GAMEDUINO2 +#include "gameduino2.h" +#endif + +UIDisplay::UIDisplay() +{ +} +#if UI_ANIMATION +void slideIn(uint8_t row,FSTRINGPARAM(text)) +{ + char *empty=""; + int8_t i = 0; + uid.col=0; + uid.addStringP(text); + uid.printCols[uid.col]=0; + for(i=UI_COLS-1; i>=0; i--) + { + uid.printRow(row,empty,uid.printCols,i); + HAL::pingWatchdog(); + HAL::delayMilliseconds(10); + } +} +#endif // UI_ANIMATION +void UIDisplay::initialize() +{ + oldMenuLevel = -2; +#ifdef COMPILE_I2C_DRIVER + uid.outputMask = UI_DISPLAY_I2C_OUTPUT_START_MASK; +#if UI_DISPLAY_I2C_CHIPTYPE==0 && BEEPER_TYPE==2 && BEEPER_PIN>=0 +#if BEEPER_ADDRESS == UI_DISPLAY_I2C_ADDRESS + uid.outputMask |= BEEPER_PIN; +#endif +#endif + HAL::i2cInit(UI_I2C_CLOCKSPEED); +#if UI_DISPLAY_I2C_CHIPTYPE==1 + // set direction of pins + HAL::i2cStart(UI_DISPLAY_I2C_ADDRESS + I2C_WRITE); + HAL::i2cWrite(0); // IODIRA + HAL::i2cWrite(~(UI_DISPLAY_I2C_OUTPUT_PINS & 255)); + HAL::i2cWrite(~(UI_DISPLAY_I2C_OUTPUT_PINS >> 8)); + HAL::i2cStop(); + // Set pullups according to UI_DISPLAY_I2C_PULLUP + HAL::i2cStart(UI_DISPLAY_I2C_ADDRESS+I2C_WRITE); + HAL::i2cWrite(0x0C); // GPPUA + HAL::i2cWrite(UI_DISPLAY_I2C_PULLUP & 255); + HAL::i2cWrite(UI_DISPLAY_I2C_PULLUP >> 8); + HAL::i2cStop(); +#endif + +#endif + flags = 0; + menuLevel = 0; + shift = -2; + menuPos[0] = 0; + lastAction = 0; + delayedAction = 0; + lastButtonAction = 0; + activeAction = 0; + statusMsg[0] = 0; + uiInitKeys(); + cwd[0] = '/'; + cwd[1] = 0; + folderLevel = 0; + UI_STATUS_F(Com::translatedF(UI_TEXT_PRINTER_READY_ID)); +#if UI_DISPLAY_TYPE != NO_DISPLAY + initializeLCD(); +#if defined(USER_KEY1_PIN) && USER_KEY1_PIN > -1 + UI_KEYS_INIT_BUTTON_LOW(USER_KEY1_PIN); +#endif +#if defined(USER_KEY2_PIN) && USER_KEY2_PIN > -1 + UI_KEYS_INIT_BUTTON_LOW(USER_KEY2_PIN); +#endif +#if defined(USER_KEY3_PIN) && USER_KEY3_PIN > -1 + UI_KEYS_INIT_BUTTON_LOW(USER_KEY3_PIN); +#endif +#if defined(USER_KEY4_PIN) && USER_KEY4_PIN > -1 + UI_KEYS_INIT_BUTTON_LOW(USER_KEY4_PIN); +#endif +#if UI_DISPLAY_TYPE == DISPLAY_I2C + // I don't know why but after power up the lcd does not come up + // but if I reinitialize i2c and the lcd again here it works. + HAL::delayMilliseconds(10); + HAL::i2cInit(UI_I2C_CLOCKSPEED); + // set direction of pins + HAL::i2cStart(UI_DISPLAY_I2C_ADDRESS+I2C_WRITE); + HAL::i2cWrite(0); // IODIRA + HAL::i2cWrite(~(UI_DISPLAY_I2C_OUTPUT_PINS & 255)); + HAL::i2cWrite(~(UI_DISPLAY_I2C_OUTPUT_PINS >> 8)); + HAL::i2cStop(); + // Set pullups according to UI_DISPLAY_I2C_PULLUP + HAL::i2cStart(UI_DISPLAY_I2C_ADDRESS+I2C_WRITE); + HAL::i2cWrite(0x0C); // GPPUA + HAL::i2cWrite(UI_DISPLAY_I2C_PULLUP & 255); + HAL::i2cWrite(UI_DISPLAY_I2C_PULLUP >> 8); + HAL::i2cStop(); + initializeLCD(); +#endif +#if UI_DISPLAY_TYPE == DISPLAY_GAMEDUINO2 + GD2::startScreen(); +#else +#if UI_ANIMATION==false || UI_DISPLAY_TYPE == DISPLAY_U8G +#if UI_DISPLAY_TYPE == DISPLAY_U8G + //u8g picture loop + u8g_FirstPage(&u8g); + do + { + u8g_DrawBitmapP(&u8g, 128 - LOGO_WIDTH, 0, ((LOGO_WIDTH + 7) / 8), LOGO_HEIGHT, logo); + for(uint8_t y = 0; y < UI_ROWS; y++) displayCache[y][0] = 0; +#ifdef CUSTOM_LOGO + printRowP(4, PSTR("Repetier")); + printRowP(5, PSTR("Ver " REPETIER_VERSION)); +#else + printRowP(0, PSTR("Repetier")); + printRowP(1, PSTR("Ver " REPETIER_VERSION)); + printRowP(3, PSTR("Machine:")); + printRowP(4, PSTR(UI_PRINTER_NAME)); + printRowP(5, PSTR(UI_PRINTER_COMPANY)); +#endif + } + while( u8g_NextPage(&u8g) ); //end picture loop +#else // not DISPLAY_U8G + for(uint8_t y=0; y2 + printRowP(UI_ROWS-1, PSTR(UI_PRINTER_COMPANY)); +#endif +#endif +#else + slideIn(0, versionString); + strcpy(displayCache[0], uid.printCols); + slideIn(1, PSTR(UI_PRINTER_NAME)); + strcpy(displayCache[1], uid.printCols); +#if UI_ROWS>2 + slideIn(UI_ROWS-1, PSTR(UI_PRINTER_COMPANY)); + strcpy(displayCache[UI_ROWS-1], uid.printCols); +#endif +#endif +#endif // gameduino2 + HAL::delayMilliseconds(UI_START_SCREEN_DELAY); +#endif +#if defined(UI_DISPLAY_I2C_CHIPTYPE) && UI_DISPLAY_I2C_CHIPTYPE==0 && (BEEPER_TYPE==2 || defined(UI_HAS_I2C_KEYS)) + // Make sure the beeper is off + HAL::i2cStartWait(UI_I2C_KEY_ADDRESS+I2C_WRITE); + HAL::i2cWrite(255); // Disable beeper, enable read for other pins. + HAL::i2cStop(); +#endif +} +#if UI_DISPLAY_TYPE == DISPLAY_4BIT || UI_DISPLAY_TYPE == DISPLAY_8BIT || UI_DISPLAY_TYPE == DISPLAY_I2C +void UIDisplay::createChar(uint8_t location,const uint8_t charmap[]) +{ + location &= 0x7; // we only have 8 locations 0-7 + lcdCommand(LCD_SETCGRAMADDR | (location << 3)); + for (int i = 0; i < 8; i++) + { + lcdPutChar(pgm_read_byte(&(charmap[i]))); + } +} +#endif +void UIDisplay::waitForKey() +{ + uint16_t nextAction = 0; + + lastButtonAction = 0; + while(lastButtonAction == nextAction) + { + uiCheckSlowKeys(nextAction); + } +} + +void UIDisplay::printRowP(uint8_t r,PGM_P txt) +{ + if(r >= UI_ROWS) return; + col = 0; + addStringP(txt); + uid.printCols[col] = 0; + printRow(r,uid.printCols,NULL,UI_COLS); +} +void UIDisplay::addInt(int value,uint8_t digits,char fillChar) +{ + uint8_t dig = 0, neg = 0; + if(value < 0) + { + value = -value; + neg = 1; + dig++; + } + char buf[7]; // Assumes 8-bit chars plus zero byte. + char *str = &buf[6]; + buf[6] = 0; + do + { + unsigned int m = value; + value /= 10; + char c = m - 10 * value; + *--str = c + '0'; + dig++; + } + while(value); + if(neg) + uid.printCols[col++] = '-'; + if(digits < 6) + while(dig < digits) + { + *--str = fillChar; //' '; + dig++; + } + while(*str && col < MAX_COLS) + { + uid.printCols[col++] = *str; + str++; + } +} +void UIDisplay::addLong(long value,int8_t digits) +{ + uint8_t dig = 0,neg = 0; + byte addspaces = digits > 0; + if (digits < 0) digits = -digits; + if(value < 0) + { + neg = 1; + value = -value; + dig++; + } + char buf[13]; // Assumes 8-bit chars plus zero byte. + char *str = &buf[12]; + buf[12] = 0; + do + { + unsigned long m = value; + value /= 10; + char c = m - 10 * value; + *--str = c + '0'; + dig++; + } + while(value); + if(neg) + uid.printCols[col++] = '-'; + if(addspaces && digits <= 11) + while(dig < digits) + { + *--str = ' '; + dig++; + } + while(*str && col= MAX_COLS) return; + number = -number; + fixdigits--; + } + number += pgm_read_float(&roundingTable[digits]); // for correct rounding + + // Extract the integer part of the number and print it + unsigned long int_part = (unsigned long)number; + float remainder = number - (float)int_part; + addLong(int_part,fixdigits); + if(col >= UI_COLS) return; + + // Print the decimal point, but only if there are digits beyond + if (digits > 0) + { + uid.printCols[col++] = '.'; + } + + // Extract digits from the remainder one at a time + while (col < MAX_COLS && digits-- > 0) + { + remainder *= 10.0; + uint8_t toPrint = uint8_t(remainder); + uid.printCols[col++] = '0' + toPrint; + remainder -= toPrint; + } +} + +void UIDisplay::addStringP(FSTRINGPARAM(text)) +{ + while(col < MAX_COLS) + { + uint8_t c = HAL::readFlashByte(text++); + if(c == 0) return; + uid.printCols[col++] = c; + } +} + +void UIDisplay::addStringOnOff(uint8_t on) +{ + addStringP(on ? Com::translatedF(UI_TEXT_ON_ID) : Com::translatedF(UI_TEXT_OFF_ID)); +} + +void UIDisplay::addChar(const char c) +{ + if(col < UI_COLS) + { + uid.printCols[col++] = c; + } +} +void UIDisplay::addGCode(GCode *code) +{ + // assume volatile and make copy so we dont "see" multple code lines as we go. + //GCode myCode = *code; insuffeicnet memory for this safety check + //code = &myCode; + addChar('#'); + addLong(code->N); + if(code->hasM()) + { + addChar('M'); + addLong((long)code->M); + } + if(code->hasG()) + { + addChar('G'); + addLong((long)code->G); + } + if(code->hasT()) + { + addChar('T'); + addLong((long)code->T); + } + if(code->hasX()) + { + addChar('X'); + addFloat(code->X); + } + if(code->hasY()) + { + addChar('Y'); + addFloat(code->Y); + } + if(code->hasZ()) + { + addChar('Z'); + addFloat(code->Z); + } + if(code->hasE()) + { + addChar('E'); + addFloat(code->E); + } + if(code->hasF()) + { + addChar('F'); + addFloat(code->F); + } + if(code->hasS()) + { + addChar('S'); + addLong(code->S); + } + if(code->hasP()) + { + addChar('P'); + addLong(code->P); + } +#ifdef ARC_SUPPORT + if(code->hasI()) + { + addChar('I'); + addFloat(code->I); + } + if(code->hasJ()) + { + addChar('J'); + addFloat(code->J); + } + if(code->hasR()) + { + addChar('R'); + addFloat(code->R); + } +#endif + // cannot print string, it isnt part of the gcode structure. + //it points to temp memory in a buffer. + //if(code->hasSTRING()) +} + + +void UIDisplay::parse(const char *txt,bool ram) +{ + static uint8_t beepdelay = 0; + int ivalue = 0; + float fvalue = 0; + while(col < MAX_COLS) + { + char c = (ram ? *(txt++) : pgm_read_byte(txt++)); + if(c == 0) break; // finished + if(c != '%') + { + uid.printCols[col++] = c; + continue; + } + // dynamic parameter, parse meaning and replace + char c1 = (ram ? *(txt++) : pgm_read_byte(txt++)); + char c2 = (ram ? *(txt++) : pgm_read_byte(txt++)); + switch(c1) + { + case '%': + { + // print % for input '%%' or '%%%' + if(col < UI_COLS) uid.printCols[col++] = '%'; // if data = '%%?' escaped percent, with left over ? char + if (c2 != '%') txt--; // Be flexible and accept 2 or 3 chars + break; + } // case '%' + + case '?' : // conditional spacer or other char + { + // If something has been printed, check if the last char is c2. + // if not, append c2. + // otherwise do nothing. + if (col > 0 && col < UI_COLS) + { + if (uid.printCols[col - 1] != c2) uid.printCols[col++] = c2; + } + break; + } + case 'a': // Acceleration settings + if(c2 >= 'x' && c2 <= 'z') addFloat(Printer::maxAccelerationMMPerSquareSecond[c2 - 'x'], 5, 0); + else if(c2 >= 'X' && c2 <= 'Z') addFloat(Printer::maxTravelAccelerationMMPerSquareSecond[c2-'X'], 5, 0); + else if(c2 == 'j') addFloat(Printer::maxJerk, 3, 1); +#if DRIVE_SYSTEM != DELTA + else if(c2 == 'J') addFloat(Printer::maxZJerk, 3, 1); +#endif + break; + case 'B': + if(c2 == 'C') //Custom coating + { + addFloat(Printer::zBedOffset, 3, 2); + break; + } + break; + case 'd': // debug boolean + if (c2 == 'o') addStringOnOff(Printer::debugEcho()); + if (c2 == 'i') addStringOnOff(Printer::debugInfo()); + if (c2 == 'e') addStringOnOff(Printer::debugErrors()); + if (c2 == 'd') addStringOnOff(Printer::debugDryrun()); + if (c2 == 'p') addStringOnOff(Printer::debugEndStop()); + if (c2 == 'x') addStringP(Endstops::xMin() ? ui_selected : ui_unselected); + if (c2 == 'X') addStringP(Endstops::xMax() ? ui_selected : ui_unselected); + if (c2 == 'y') addStringP(Endstops::yMin() ? ui_selected : ui_unselected); + if (c2 == 'Y') addStringP(Endstops::yMax() ? ui_selected : ui_unselected); + if (c2 == 'z') addStringP(Endstops::zMin() ? ui_selected : ui_unselected); + if (c2 == 'Z') addStringP(Endstops::zMax() ? ui_selected : ui_unselected); + break; + case 'D': +#if FEATURE_DITTO_PRINTING + if(c2>='0' && c2<='9') + { + addStringP(Extruder::dittoMode==c2-'0' ? ui_selected : ui_unselected); + } +#endif + break; + case 'e': // Extruder temperature + { + if(c2 == 'I') + { + //give integer display + //char c2 = (ram ? *(txt++) : pgm_read_byte(txt++)); + txt++; // just skip c sign + ivalue = 0; + } + else ivalue = UI_TEMP_PRECISION; + + if(c2 == 'r') // Extruder relative mode + { + addStringP(Printer::relativeExtruderCoordinateMode ? Com::translatedF(UI_TEXT_YES_ID) : Com::translatedF(UI_TEXT_NO_ID)); + break; + } +#if FEATURE_DITTO_PRINTING + if(c2 == 'd') { // ditto copy mode + addInt(Extruder::dittoMode,1,' '); + break; + } +#endif +#if NUM_TEMPERATURE_LOOPS > 0 + uint8_t eid = NUM_EXTRUDER; // default = BED if c2 not specified extruder number + if(c2 == 'c') eid = Extruder::current->id; + else if(c2 >= '0' && c2 <= '9') eid = c2 - '0'; + if(Printer::isAnyTempsensorDefect()) + { + if(eid == 0 && ++beepdelay > 30) beepdelay = 0; // beep every 30 seconds + if(beepdelay == 1) BEEP_LONG; + if(tempController[eid]->isSensorDefect()) + { + addStringP(PSTR(" def ")); + break; + } + else if(tempController[eid]->isSensorDecoupled()) + { + addStringP(PSTR(" dec ")); + break; + } + } +#if EXTRUDER_JAM_CONTROL + if(tempController[eid]->isJammed()) + { + if(++beepdelay > 10) beepdelay = 0; // beep every 10 seconds + if(beepdelay == 1) BEEP_LONG; + addStringP(PSTR(" jam ")); + break; + } +#endif +#endif + if(c2 == 'c') fvalue = Extruder::current->tempControl.currentTemperatureC; + else if(c2 >= '0' && c2 <= '9') fvalue=extruder[c2 - '0'].tempControl.currentTemperatureC; + else if(c2 == 'b') fvalue = Extruder::getHeatedBedTemperature(); + else if(c2 == 'B') + { + ivalue = 0; + fvalue = Extruder::getHeatedBedTemperature(); + } + addFloat(fvalue, 3, ivalue); + break; + } + case 'E': // Target extruder temperature + if(c2 == 'c') fvalue = Extruder::current->tempControl.targetTemperatureC; + else if(c2 >= '0' && c2 <= '9') fvalue = extruder[c2 - '0'].tempControl.targetTemperatureC; +#if HAVE_HEATED_BED + else if(c2 == 'b') fvalue = heatedBedController.targetTemperatureC; +#endif + addFloat(fvalue, 3, 0 /*UI_TEMP_PRECISION*/); + break; +#if FAN_PIN > -1 && FEATURE_FAN_CONTROL + case 'F': // FAN speed + if(c2 == 's') addInt(floor(Printer::getFanSpeed() * 100 / 255 + 0.5f), 3); + if(c2=='i') addStringP((Printer::flag2 & PRINTER_FLAG2_IGNORE_M106_COMMAND) ? ui_selected : ui_unselected); + break; +#endif + case 'f': + if(c2 >= 'x' && c2 <= 'z') addFloat(Printer::maxFeedrate[c2 - 'x'], 5, 0); + else if(c2 >= 'X' && c2 <= 'Z') addFloat(Printer::homingFeedrate[c2 - 'X'], 5, 0); + break; + case 'i': + if(c2 == 's') addInt(stepperInactiveTime / 60000, 3); + else if(c2 == 'p') addInt(maxInactiveTime / 60000, 3); + break; + case 'O': // ops related stuff + break; + case 'l': + if(c2 == 'a') addInt(lastAction,4); +#if defined(CASE_LIGHTS_PIN) && CASE_LIGHTS_PIN >= 0 + else if(c2 == 'o') addStringOnOff(READ(CASE_LIGHTS_PIN)); // Lights on/off +#endif +#if FEATURE_AUTOLEVEL + else if(c2 == 'l') addStringOnOff((Printer::isAutolevelActive())); // Autolevel on/off +#endif + break; + case 'o': + if(c2 == 's') + { +#if SDSUPPORT + if(sd.sdactive && sd.sdmode) + { + addStringP(Com::translatedF(UI_TEXT_PRINT_POS_ID)); + float percent; + if(sd.filesize < 2000000) percent = sd.sdpos * 100.0 / sd.filesize; + else percent = (sd.sdpos >> 8) * 100.0 / (sd.filesize >> 8); + addFloat(percent, 3, 1); + if(col < MAX_COLS) + uid.printCols[col++] = '%'; + } + else +#endif + parse(statusMsg, true); + break; + } + if(c2 == 'c') + { + addLong(baudrate, 6); + break; + } + if(c2 == 'e') + { + if(errorMsg != 0) addStringP((char PROGMEM *)errorMsg); + break; + } + if(c2 == 'B') + { + addInt((int)PrintLine::linesCount, 2); + break; + } + if(c2 == 'f') + { + addInt(Printer::extrudeMultiply, 3); + break; + } + if(c2 == 'm') + { + addInt(Printer::feedrateMultiply, 3); + break; + } + if(c2 == 'n') + { + addInt(Extruder::current->id + 1, 1); + break; + } +#if FEATURE_SERVO > 0 && UI_SERVO_CONTROL > 0 + if(c2 == 'S') + { + addInt(servoPosition, 4); + break; + } +#endif +#if FEATURE_BABYSTEPPING + if(c2 == 'Y') + { +// addInt(zBabySteps,0); + addFloat((float)zBabySteps * Printer::invAxisStepsPerMM[Z_AXIS], 2, 2); + break; + } +#endif + // Extruder output level + if(c2 >= '0' && c2 <= '9') ivalue = pwm_pos[c2 - '0']; +#if HAVE_HEATED_BED + else if(c2 == 'b') ivalue = pwm_pos[heatedBedController.pwmIndex]; +#endif + else if(c2 == 'C') ivalue = pwm_pos[Extruder::current->id]; + ivalue = (ivalue * 100) / 255; + addInt(ivalue, 3); + if(col < MAX_COLS) + uid.printCols[col++] = '%'; + break; + case 's': // Endstop positions + if(c2 == 'x') + { +#if (X_MIN_PIN > -1) && MIN_HARDWARE_ENDSTOP_X + addStringOnOff(Endstops::xMin()); +#else + addStringP(Com::translatedF(UI_TEXT_NA_ID)); +#endif + } + if(c2 == 'X') +#if (X_MAX_PIN > -1) && MAX_HARDWARE_ENDSTOP_X + addStringOnOff(Endstops::xMax()); +#else + addStringP(Com::translatedF(UI_TEXT_NA_ID)); +#endif + if(c2 == 'y') +#if (Y_MIN_PIN > -1)&& MIN_HARDWARE_ENDSTOP_Y + addStringOnOff(Endstops::yMin()); +#else + addStringP(Com::translatedF(UI_TEXT_NA_ID)); +#endif + if(c2 == 'Y') +#if (Y_MAX_PIN > -1) && MAX_HARDWARE_ENDSTOP_Y + addStringOnOff(Endstops::yMax()); +#else + addStringP(Com::translatedF(UI_TEXT_NA_ID)); +#endif + if(c2 == 'z') +#if (Z_MIN_PIN > -1) && MIN_HARDWARE_ENDSTOP_Z + addStringOnOff(Endstops::zMin()); +#else + addStringP(Com::translatedF(UI_TEXT_NA_ID)); +#endif + if(c2=='Z') +#if (Z_MAX_PIN > -1) && MAX_HARDWARE_ENDSTOP_Z + addStringOnOff(Endstops::zMax()); +#else + addStringP(Com::translatedF(UI_TEXT_NA_ID)); +#endif + if(c2=='P') +#if (Z_PROBE_PIN > -1) + addStringOnOff(Endstops::zProbe()); +#else + addStringP(Com::translatedF(UI_TEXT_NA_ID)); +#endif + break; + case 'S': + if(c2 >= 'x' && c2 <= 'z') addFloat(Printer::axisStepsPerMM[c2 - 'x'], 3, 1); + if(c2 == 'e') addFloat(Extruder::current->stepsPerMM, 3, 1); + break; + case 'T': // Print offsets + if(c2=='2') + addFloat(-Printer::coordinateOffset[Z_AXIS],2,2); + else + addFloat(-Printer::coordinateOffset[c2-'0'],4,0); + break; + case 'U': + if(c2 == 't') // Printing time + { +#if EEPROM_MODE + bool alloff = true; +#if NUM_TEMPERATURE_LOOPS > 0 + for(uint8_t i = 0; i < NUM_EXTRUDER; i++) + if(tempController[i]->targetTemperatureC > 15) alloff = false; +#endif + long seconds = (alloff ? 0 : (HAL::timeInMilliseconds() - Printer::msecondsPrinting) / 1000) + HAL::eprGetInt32(EPR_PRINTING_TIME); + long tmp = seconds / 86400; + seconds -= tmp * 86400; + addInt(tmp, 5); + addStringP(Com::translatedF(UI_TEXT_PRINTTIME_DAYS_ID)); + tmp = seconds / 3600; + addInt(tmp,2); + addStringP(Com::translatedF(UI_TEXT_PRINTTIME_HOURS_ID)); + seconds -= tmp * 3600; + tmp = seconds / 60; + addInt(tmp,2,'0'); + addStringP(Com::translatedF(UI_TEXT_PRINTTIME_MINUTES_ID)); +#endif + } + else if(c2 == 'f') // Filament usage + { +#if EEPROM_MODE + float dist = Printer::filamentPrinted * 0.001 + HAL::eprGetFloat(EPR_PRINTING_DISTANCE); +#else + float dist = Printer::filamentPrinted * 0.001; +#endif + addFloat(dist, 6, 1); + } + break; + + case 'x': + if(c2>='0' && c2<='4') + { + if(c2=='4') // this sequence save 14 bytes of flash + { + addFloat(Printer::filamentPrinted * 0.001,3,2); + break; + } + if(c2=='0') + fvalue = Printer::realXPosition(); + else if(c2=='1') + fvalue = Printer::realYPosition(); + else if(c2=='2') + fvalue = Printer::realZPosition(); + else + fvalue = (float)Printer::currentPositionSteps[E_AXIS] * Printer::invAxisStepsPerMM[E_AXIS]; + addFloat(fvalue,4,2); + } + break; + + case 'X': // Extruder related +#if NUM_EXTRUDER>0 + if(c2>='0' && c2<='9') + { + addStringP(Extruder::current->id==c2-'0'?ui_selected:ui_unselected); + } +#if TEMP_PID + else if(c2=='i') + { + addFloat(currHeaterForSetup->pidIGain, 4,2); + } + else if(c2=='p') + { + addFloat(currHeaterForSetup->pidPGain, 4,2); + } + else if(c2=='d') + { + addFloat(currHeaterForSetup->pidDGain, 4,2); + } + else if(c2=='m') + { + addInt(currHeaterForSetup->pidDriveMin, 3); + } + else if(c2=='M') + { + addInt(currHeaterForSetup->pidDriveMax, 3); + } + else if(c2=='D') + { + addInt(currHeaterForSetup->pidMax, 3); + } +#endif + else if(c2=='w') + { + addInt(Extruder::current->watchPeriod,4); + } +#if RETRACT_DURING_HEATUP + else if(c2=='T') + { + addInt(Extruder::current->waitRetractTemperature,4); + } + else if(c2=='U') + { + addInt(Extruder::current->waitRetractUnits,2); + } +#endif + else if(c2=='h') + { + uint8_t hm = currHeaterForSetup->heatManager; + if(hm == HTR_PID) + addStringP(Com::translatedF(UI_TEXT_STRING_HM_PID_ID)); + else if(hm == HTR_DEADTIME) + addStringP(Com::translatedF(UI_TEXT_STRING_HM_DEADTIME_ID)); + else if(hm == HTR_SLOWBANG) + addStringP(Com::translatedF(UI_TEXT_STRING_HM_SLOWBANG_ID)); + else + addStringP(Com::translatedF(UI_TEXT_STRING_HM_BANGBANG_ID)); + } +#if USE_ADVANCE +#if ENABLE_QUADRATIC_ADVANCE + else if(c2=='a') + { + addFloat(Extruder::current->advanceK, 3, 0); + } +#endif + else if(c2=='l') + { + addFloat(Extruder::current->advanceL, 3, 0); + } +#endif + else if(c2=='x') + { + addFloat(Extruder::current->xOffset * Printer::invAxisStepsPerMM[X_AXIS], 3, 2); + } + else if(c2=='y') + { + addFloat(Extruder::current->yOffset * Printer::invAxisStepsPerMM[Y_AXIS], 3, 2); + } + else if(c2=='f') + { + addFloat(Extruder::current->maxStartFeedrate,5,0); + } + else if(c2=='F') + { + addFloat(Extruder::current->maxFeedrate,5,0); + } + else if(c2=='A') + { + addFloat(Extruder::current->maxAcceleration,5,0); + } +#endif + break; + case 'y': +#if DRIVE_SYSTEM == DELTA + if(c2 >= '0' && c2 <= '3') fvalue = (float)Printer::currentNonlinearPositionSteps[c2 - '0']*Printer::invAxisStepsPerMM[c2-'0']; + addFloat(fvalue,3,2); +#endif + break; + case 'z': +#if EEPROM_MODE != 0 && FEATURE_Z_PROBE + if(c2 == 'h') { // write z probe height + addFloat(EEPROM::zProbeHeight(),3,2); + break; + } +#endif + if(c2=='2') + addFloat(-Printer::coordinateOffset[Z_AXIS],2,2); + else + addFloat(-Printer::coordinateOffset[c2-'0'],4,0); + break; + } + } + uid.printCols[col] = 0; +} +void UIDisplay::showLanguageSelectionWizard() { +#if EEPROM_MODE != 0 + pushMenu(&ui_menu_languages_wiz,true); +#endif +} +void UIDisplay::setStatusP(PGM_P txt,bool error) +{ + if(!error && Printer::isUIErrorMessage()) return; + uint8_t i=0; + while(i<20) + { + uint8_t c = pgm_read_byte(txt++); + if(!c) break; + statusMsg[i++] = c; + } + statusMsg[i]=0; + if(error) + Printer::setUIErrorMessage(true); +} +void UIDisplay::setStatus(const char *txt,bool error) +{ + if(!error && Printer::isUIErrorMessage()) return; + uint8_t i=0; + while(*txt && i<20) + statusMsg[i++] = *txt++; + statusMsg[i]=0; + if(error) + Printer::setUIErrorMessage(true); +} + +const UIMenu * const ui_pages[UI_NUM_PAGES] PROGMEM = UI_PAGES; +uint16_t nFilesOnCard; +void UIDisplay::updateSDFileCount() +{ +#if SDSUPPORT + dir_t* p = NULL; + SdBaseFile *root = sd.fat.vwd(); + + root->rewind(); + nFilesOnCard = 0; + while ((p = root->getLongFilename(p, NULL, 0, NULL))) + { + if (! (DIR_IS_FILE(p) || DIR_IS_SUBDIR(p))) + continue; + if (folderLevel>=SD_MAX_FOLDER_DEPTH && DIR_IS_SUBDIR(p) && !(p->name[0]=='.' && p->name[1]=='.')) + continue; + nFilesOnCard++; + if (nFilesOnCard > 5000) // Arbitrary maximum, limited only by how long someone would scroll + return; + } +#endif +} + +void getSDFilenameAt(uint16_t filePos,char *filename) +{ +#if SDSUPPORT + dir_t* p = NULL; + SdBaseFile *root = sd.fat.vwd(); + + root->rewind(); + while ((p = root->getLongFilename(p, tempLongFilename, 0, NULL)) != NULL) + { + HAL::pingWatchdog(); + if (!DIR_IS_FILE(p) && !DIR_IS_SUBDIR(p)) continue; + if(uid.folderLevel>=SD_MAX_FOLDER_DEPTH && DIR_IS_SUBDIR(p) && !(p->name[0]=='.' && p->name[1]=='.')) continue; + if (filePos--) + continue; + strcpy(filename, tempLongFilename); + if(DIR_IS_SUBDIR(p)) strcat(filename, "/"); // Set marker for directory + break; + } +#endif +} + +bool UIDisplay::isDirname(char *name) +{ + while(*name) name++; + name--; + return *name=='/'; +} + +void UIDisplay::goDir(char *name) +{ +#if SDSUPPORT + char *p = cwd; + while(*p)p++; + if(name[0]=='.' && name[1]=='.') + { + if(folderLevel==0) return; + p--; + p--; + while(*p!='/') p--; + p++; + *p = 0; + folderLevel--; + } + else + { + if(folderLevel>=SD_MAX_FOLDER_DEPTH) return; + while(*name) *p++ = *name++; + *p = 0; + folderLevel++; + } + sd.fat.chdir(cwd); + updateSDFileCount(); +#endif +} +/** write file names at current position to lcd */ +void sdrefresh(uint16_t &r,char cache[UI_ROWS][MAX_COLS+1]) +{ +#if SDSUPPORT + dir_t* p = NULL; + uint16_t offset = uid.menuTop[uid.menuLevel]; + SdBaseFile *root; + uint16_t length, skip; + + sd.fat.chdir(uid.cwd); + root = sd.fat.vwd(); + root->rewind(); + + skip = (offset > 0 ? offset - 1 : 0); + + while (r + offset < nFilesOnCard + 1 && r < UI_ROWS && (p = root->getLongFilename(p, tempLongFilename, 0, NULL))) + { + HAL::pingWatchdog(); + // done if past last used entry + // skip deleted entry and entries for . and .. + // only list subdirectories and files + if ((DIR_IS_FILE(p) || DIR_IS_SUBDIR(p))) + { + if(uid.folderLevel >= SD_MAX_FOLDER_DEPTH && DIR_IS_SUBDIR(p) && !(p->name[0]=='.' && p->name[1]=='.')) + continue; + if(skip > 0) + { + skip--; + continue; + } + uid.col = 0; + if(r + offset == uid.menuPos[uid.menuLevel]) + uid.printCols[uid.col++] = CHAR_SELECTOR; + else + uid.printCols[uid.col++] = ' '; + // print file name with possible blank fill + if(DIR_IS_SUBDIR(p)) + uid.printCols[uid.col++] = bFOLD; // Prepend folder symbol + length = RMath::min((int)strlen(tempLongFilename), MAX_COLS - uid.col); + memcpy(uid.printCols + uid.col, tempLongFilename, length); + uid.col += length; + uid.printCols[uid.col] = 0; + strcpy(cache[r++],uid.printCols); + } + } +#endif +} + +// Refresh current menu page +void UIDisplay::refreshPage() +{ + Endstops::update(); +#if UI_DISPLAY_TYPE == DISPLAY_GAMEDUINO2 + GD2::refresh(); +#else + uint16_t r; + uint8_t mtype = UI_MENU_TYPE_INFO; + char cache[UI_ROWS][MAX_COLS + 1]; + adjustMenuPos(); +#if UI_AUTORETURN_TO_MENU_AFTER != 0 + // Reset timeout on menu back when user active on menu + if (uid.encoderLast != encoderStartScreen) + ui_autoreturn_time = HAL::timeInMilliseconds() + UI_AUTORETURN_TO_MENU_AFTER; +#endif + encoderStartScreen = uid.encoderLast; + // Copy result into cache + Endstops::update(); + if(menuLevel == 0) // Top level menu + { + UIMenu *men = (UIMenu*)pgm_read_word(&(ui_pages[menuPos[0]])); + uint16_t nr = pgm_read_word_near(&(men->numEntries)); + UIMenuEntry **entries = (UIMenuEntry**)pgm_read_word(&(men->entries)); + for(r = 0; r < nr && r < UI_ROWS; r++) + { + UIMenuEntry *ent = (UIMenuEntry *)pgm_read_word(&(entries[r])); + col = 0; + char *text = (char*)pgm_read_word(&(ent->text)); + if(text == NULL) + text = (char*)Com::translatedF(pgm_read_word(&(ent->translation))); + parse(text,false); + strcpy(cache[r],uid.printCols); + } + } + else + { + UIMenu *men = (UIMenu*)menu[menuLevel]; + uint16_t nr = pgm_read_word_near(&(men->numEntries)); + mtype = pgm_read_byte((void*)&(men->menuType)); + uint16_t offset = menuTop[menuLevel]; + UIMenuEntry **entries = (UIMenuEntry**)pgm_read_word(&(men->entries)); + for(r = 0; r + offset < nr && r < UI_ROWS; ) + { + UIMenuEntry *ent =(UIMenuEntry *)pgm_read_word(&(entries[r + offset])); + if(!ent->showEntry()) + { + offset++; + continue; + } + uint8_t entType = pgm_read_byte(&(ent->entryType)) & 127; + uint16_t entAction = pgm_read_word(&(ent->action)); + col = 0; + if(entType >= 2 && entType <= 4) + { + if(r + offset == menuPos[menuLevel] && activeAction != entAction) + uid.printCols[col++] = CHAR_SELECTOR; + else if(activeAction == entAction) + uid.printCols[col++] = CHAR_SELECTED; + else + uid.printCols[col++]=' '; + } + char *text = (char*)pgm_read_word(&(ent->text)); + if(text == NULL) + text = (char*)Com::translatedF(pgm_read_word(&(ent->translation))); + parse(text,false); + if(entType == 2) // Draw submenu marker at the right side + { + while(colUI_COLS) + { + uid.printCols[RMath::min(UI_COLS - 1,col)] = CHAR_RIGHT; + } + else + uid.printCols[col] = CHAR_RIGHT; // Arrow right + uid.printCols[++col] = 0; + } + strcpy(cache[r],uid.printCols); + r++; + } + } +#if SDSUPPORT + if(mtype == UI_MENU_TYPE_FILE_SELECTOR) + { + sdrefresh(r,cache); + } +#endif + + uid.printCols[0] = 0; + while(r < UI_ROWS) // delete trailing empty rows + strcpy(cache[r++],uid.printCols); + // cache now contains the data to show + // Compute transition + uint8_t transition = 0; // 0 = display, 1 = up, 2 = down, 3 = left, 4 = right +#if UI_ANIMATION + if(menuLevel != oldMenuLevel && !PrintLine::hasLines()) + { + if(oldMenuLevel == 0 || oldMenuLevel == -2) + transition = 1; + else if(menuLevel == 0) + transition = 2; + else if(menuLevel>oldMenuLevel) + transition = 3; + else + transition = 4; + } +#endif + uint8_t loops = 1; + uint8_t dt = 1,y; + if(transition == 1 || transition == 2) loops = UI_ROWS; + else if(transition > 2) + { + dt = (UI_COLS + UI_COLS - 1) / 16; + loops = UI_COLS + 1 / dt; + } + uint8_t off0 = (shift <= 0 ? 0 : shift); + uint8_t scroll = dt; + uint8_t off[UI_ROWS]; + if(transition == 0) // Copy cache to displayCache + { + for(y = 0; y < UI_ROWS; y++) + strcpy(displayCache[y],cache[y]); + } + for(y = 0; y < UI_ROWS; y++) + { + uint8_t len = strlen(displayCache[y]); // length of line content + off[y] = len > UI_COLS ? RMath::min(len - UI_COLS,off0) : 0; + if(len > UI_COLS) + { + off[y] = RMath::min(len - UI_COLS,off0); + if(transition == 0 && (mtype == UI_MENU_TYPE_FILE_SELECTOR || mtype == UI_MENU_TYPE_SUBMENU)) // Copy first char to front + { + //displayCache[y][off[y]] = displayCache[y][0]; + cache[y][off[y]] = cache[y][0]; + } + } + else off[y] = 0; +#if UI_ANIMATION + if(transition == 3) + { + for(r = len; r < MAX_COLS; r++) + { + displayCache[y][r] = 32; + } + displayCache[y][MAX_COLS] = 0; + } + else if(transition == 4) + { + for(r = strlen(cache[y]); r < MAX_COLS; r++) + { + cache[y][r] = 32; + } + cache[y][MAX_COLS] = 0; + } +#endif + } + for(uint8_t l = 0; l-1 && FEATURE_FAN_CONTROL + int fanPercent = 0; + char fanString[2]; +#endif + if(menuLevel == 0 && menuPos[0] == 0 ) // Main menu with special graphics + { +//ext1 and ext2 animation symbols +#if NUM_EXTRUDER < 3 + if(extruder[0].tempControl.targetTemperatureC > 30) +#else + if(Extruder::current->tempControl.targetTemperatureC > 30) +#endif + cache[0][0] = Printer::isAnimation()?'\x08':'\x09'; + else + cache[0][0] = '\x0a'; //off +#if NUM_EXTRUDER == 2 && MIXING_EXTRUDER == 0 + if(extruder[1].tempControl.targetTemperatureC > 30) + cache[1][0] = Printer::isAnimation()?'\x08':'\x09'; + else + cache[1][0] = '\x0a'; //off +#endif +#if HAVE_HEATED_BED + //heated bed animated icons + uint8_t lin = 2 - ((NUM_EXTRUDER != 2) ? 1 : 0); + if(heatedBedController.targetTemperatureC > 30) + cache[lin][0] = Printer::isAnimation() ? '\x0c' : '\x0d'; + else + cache[lin][0] = '\x0b'; +#endif +#if FAN_PIN > -1 && FEATURE_FAN_CONTROL + //fan + fanPercent = Printer::getFanSpeed() * 100 / 255; + fanString[1] = 0; + if(fanPercent > 0) //fan running animation + { + fanString[0] = Printer::isAnimation() ? '\x0e' : '\x0f'; + } + else + { + fanString[0] = '\x0e'; + } +#endif +#if SDSUPPORT + //SD Card + if(sd.sdactive) + { + if(sd.sdactive && sd.sdmode) + { + if(sd.filesize < 20000000) sdPercent = sd.sdpos * 100 / sd.filesize; + else sdPercent = (sd.sdpos >> 8) * 100 / (sd.filesize >> 8); + } + else + { + sdPercent = 0; + } + } +#endif + } +#endif + //u8g picture loop + u8g_FirstPage(&u8g); + do + { +#endif + if(transition == 0) + { +#if UI_DISPLAY_TYPE == DISPLAY_U8G + if(menuLevel == 0 && menuPos[0] == 0 ) + { + u8g_SetFont(&u8g,UI_FONT_SMALL); + uint8_t py = 8; + for(uint8_t r = 0; r < 3; r++) + { + if(u8g_IsBBXIntersection(&u8g, 0, py-UI_FONT_SMALL_HEIGHT, 1, UI_FONT_SMALL_HEIGHT)) + printU8GRow(0, py, cache[r]); + py += 10; + } +#if FAN_PIN>-1 && FEATURE_FAN_CONTROL + //fan + if(u8g_IsBBXIntersection(&u8g, 0, 30 - UI_FONT_SMALL_HEIGHT, 1, UI_FONT_SMALL_HEIGHT)) + printU8GRow(117,30,fanString); + drawVProgressBar(116, 0, 9, 20, fanPercent); +#endif + if(u8g_IsBBXIntersection(&u8g, 0, 42 - UI_FONT_SMALL_HEIGHT, 1, UI_FONT_SMALL_HEIGHT)) + printU8GRow(0,42,cache[3]); //multiplier + extruded + if(u8g_IsBBXIntersection(&u8g, 0, 52 - UI_FONT_SMALL_HEIGHT, 1, UI_FONT_SMALL_HEIGHT)) + printU8GRow(0,52,cache[4]); //buffer usage +#if SDSUPPORT + //SD Card + if(sd.sdactive && u8g_IsBBXIntersection(&u8g, 66, 52 - UI_FONT_SMALL_HEIGHT, 1, UI_FONT_SMALL_HEIGHT)) + { + printU8GRow(66,52,const_cast("SD")); + drawHProgressBar(79,46, 46, 6, sdPercent); + } +#endif + //Status + py = u8g_GetHeight(&u8g) - 2; + if(u8g_IsBBXIntersection(&u8g, 70, py - UI_FONT_SMALL_HEIGHT, 1, UI_FONT_SMALL_HEIGHT)) + printU8GRow(0,py,cache[5]); + + //divider lines + u8g_DrawHLine(&u8g,0, 32, u8g_GetWidth(&u8g)); + if ( u8g_IsBBXIntersection(&u8g, 54, 0, 1, 55) ) + { + u8g_draw_vline(&u8g,112, 0, 32); + u8g_draw_vline(&u8g,62, 0, 54); + } + u8g_SetFont(&u8g, UI_FONT_DEFAULT); + } + else + { +#endif + for(y = 0; y < UI_ROWS; y++) + printRow(y, &cache[y][off[y]], NULL, UI_COLS); +#if UI_DISPLAY_TYPE == DISPLAY_U8G + } +#endif + } +#if UI_ANIMATION + else + { + if(transition == 1) // up + { + if(scroll > UI_ROWS) + { + scroll = UI_ROWS; + l = loops; + } + for(y = 0; y < UI_ROWS - scroll; y++) + { + r = y + scroll; + printRow(y, &displayCache[r][off[r]], NULL, UI_COLS); + } + for(y = 0; y < scroll; y++) + { + printRow(UI_ROWS - scroll + y,cache[y], NULL, UI_COLS); + } + } + else if(transition == 2) // down + { + if(scroll > UI_ROWS) + { + scroll = UI_ROWS; + l = loops; + } + for(y = 0; y < scroll; y++) + { + printRow(y, cache[UI_ROWS - scroll + y], NULL, UI_COLS); + } + for(y = 0; y < UI_ROWS - scroll; y++) + { + r = y + scroll; + printRow(y + scroll, &displayCache[y][off[y]], NULL, UI_COLS); + } + } + else if(transition == 3) // left + { + if(scroll > UI_COLS) + { + scroll = UI_COLS; + l = loops; + } + for(y = 0; y < UI_ROWS; y++) + { + printRow(y,&displayCache[y][off[y] + scroll], cache[y], UI_COLS - scroll); + } + } + else // right + { + if(scroll > UI_COLS) + { + scroll = UI_COLS; + l = loops; + } + for(y = 0; y < UI_ROWS; y++) + { + printRow(y, cache[y] + UI_COLS - scroll, &displayCache[y][off[y]], scroll); + } + } +#if UI_DISPLAY_TYPE != DISPLAY_U8G + HAL::delayMilliseconds(transition < 3 ? 200 : 70); +#endif + HAL::pingWatchdog(); + } +#endif +#if UI_DISPLAY_TYPE == DISPLAY_U8G + } + while( u8g_NextPage(&u8g) ); //end picture loop + Printer::toggleAnimation(); +#endif + } // for l +#if UI_ANIMATION + // copy to last cache + if(transition != 0) + for(y = 0; y < UI_ROWS; y++) + strcpy(displayCache[y], cache[y]); + oldMenuLevel = menuLevel; +#endif +#endif +} + +void UIDisplay::pushMenu(const UIMenu *men, bool refresh) +{ + if(men == menu[menuLevel]) + { + refreshPage(); + return; + } + if(menuLevel == 4) return; // Max. depth reached. No more memory to down further. + menuLevel++; + menu[menuLevel] = men; + menuTop[menuLevel] = menuPos[menuLevel] = 0; +#if SDSUPPORT + UIMenu *men2 = (UIMenu*)menu[menuLevel]; + if(pgm_read_byte(&(men2->menuType)) == 1) + { + // Menu is Open files list + updateSDFileCount(); + // Keep menu positon in file list, more user friendly. + // If file list changed, still need to reset position. + if (menuPos[menuLevel] > nFilesOnCard) + { + //This exception can happen if the card was unplugged or modified. + menuTop[menuLevel] = 0; + menuPos[menuLevel] = UI_MENU_BACKCNT; // if top entry is back, default to next useful item + } + } + else +#endif + { + // With or without SDCARD, being here means the menu is not a files list + // Reset menu to top + menuTop[menuLevel] = 0; + + UIMenuEntry **entries = (UIMenuEntry**)pgm_read_word(&(men->entries)); + UIMenuEntry *ent =(UIMenuEntry *)pgm_read_word(&(entries[0])); + uint16_t entAction = pgm_read_word(&(ent->action)); + menuPos[menuLevel] = entAction == UI_ACTION_BACK ? 1 : 0; // if top entry is back, default to next useful item + } + if(refresh) + refreshPage(); +} +void UIDisplay::popMenu(bool refresh) +{ + if(menuLevel > 0) menuLevel--; + Printer::setAutomount(false); + activeAction = 0; + if(refresh) + refreshPage(); +} +int UIDisplay::okAction(bool allowMoves) +{ + if(Printer::isUIErrorMessage()) + { + Printer::setUIErrorMessage(false); + return 0; + } + BEEP_SHORT +#if UI_HAS_KEYS == 1 + if(menuLevel == 0) // Enter menu + { + menuLevel = 1; + menuTop[1] = 0; + menuPos[1] = UI_MENU_BACKCNT; // if top entry is back, default to next useful item + menu[1] = &ui_menu_main; + return 0; + } + const UIMenu *men = (const UIMenu*)menu[menuLevel]; + //uint8_t nr = pgm_read_word_near(&(menu->numEntries)); + uint8_t mtype = pgm_read_byte(&(men->menuType)); + UIMenuEntry **entries; + UIMenuEntry *ent; + unsigned char entType; + unsigned int action; +#if SDSUPPORT + if(mtype == UI_MENU_TYPE_FILE_SELECTOR) + { + if(menuPos[menuLevel] == 0) // Selected back instead of file + { + return executeAction(UI_ACTION_BACK, allowMoves); + } + + if(!sd.sdactive) + return 0; + uint8_t filePos = menuPos[menuLevel] - 1; + char filename[LONG_FILENAME_LENGTH + 1]; + + getSDFilenameAt(filePos, filename); + if(isDirname(filename)) // Directory change selected + { + goDir(filename); + menuTop[menuLevel] = 0; + menuPos[menuLevel] = 1; + refreshPage(); + oldMenuLevel = -1; + return 0; + } + + int16_t shortAction; // renamed to avoid scope confusion + if (Printer::isAutomount()) + shortAction = UI_ACTION_SD_PRINT; + else + { + men = menu[menuLevel - 1]; + entries = (UIMenuEntry**)pgm_read_word(&(men->entries)); + ent =(UIMenuEntry *)pgm_read_word(&(entries[menuPos[menuLevel-1]])); + shortAction = pgm_read_word(&(ent->action)); + } + sd.file.close(); + sd.fat.chdir(cwd); + EVENT_START_UI_ACTION(shortAction); + switch(shortAction) + { + case UI_ACTION_SD_PRINT: + if (sd.selectFile(filename, false)) + { + sd.startPrint(); + BEEP_LONG; + menuLevel = 0; + } + break; + case UI_ACTION_SD_DELETE: + if(sd.sdactive) + { + sd.sdmode = 0; + sd.file.close(); + if(sd.fat.remove(filename)) + { + Com::printFLN(Com::tFileDeleted); + BEEP_LONG + if(menuPos[menuLevel] > 0) + menuPos[menuLevel]--; + updateSDFileCount(); + } + else + { + Com::printFLN(Com::tDeletionFailed); + } + } + break; + } + return 0; + } +#endif + entries = (UIMenuEntry**)pgm_read_word(&(men->entries)); + ent =(UIMenuEntry *)pgm_read_word(&(entries[menuPos[menuLevel]])); + entType = pgm_read_byte(&(ent->entryType));// 0 = Info, 1 = Headline, 2 = submenu ref, 3 = direct action command, 4 = modify action + action = pgm_read_word(&(ent->action)); + if(mtype == UI_MENU_TYPE_MODIFICATION_MENU) // action menu + { + action = pgm_read_word(&(men->id)); + finishAction(action); + return executeAction(UI_ACTION_BACK, true); + } + if(mtype == UI_MENU_TYPE_SUBMENU && entType == 4) // Modify action + { + if(activeAction) // finish action + { + finishAction(action); + activeAction = 0; + } + else + activeAction = action; + return 0; + } + if(mtype == UI_MENU_TYPE_WIZARD) + { + action = pgm_read_word(&(men->id)); + switch(action) + { +#if FEATURE_RETRACTION + case UI_ACTION_WIZARD_FILAMENTCHANGE: // filament change is finished +// BEEP_SHORT; + popMenu(true); + Extruder::current->retractDistance(EEPROM_FLOAT(RETRACTION_LENGTH)); +#if FILAMENTCHANGE_REHOME +#if Z_HOME_DIR > 0 + Printer::homeAxis(true, true, FILAMENTCHANGE_REHOME == 2); +#else + Printer::homeAxis(true, true, false); +#endif +#endif + Printer::GoToMemoryPosition(true, true, false, false, Printer::homingFeedrate[X_AXIS]); + Printer::GoToMemoryPosition(false, false, true, false, Printer::homingFeedrate[Z_AXIS]); + Extruder::current->retractDistance(-EEPROM_FLOAT(RETRACTION_LENGTH)); + Printer::currentPositionSteps[E_AXIS] = Printer::popWizardVar().l; // set e to starting position + Printer::setBlockingReceive(false); +#if EXTRUDER_JAM_CONTROL + Extruder::markAllUnjammed(); +#endif + Printer::setJamcontrolDisabled(false); + break; +#if EXTRUDER_JAM_CONTROL + case UI_ACTION_WIZARD_JAM_REHEAT: // user saw problem and takes action + popMenu(false); + pushMenu(&ui_wiz_jamwaitheat, true); + Extruder::unpauseExtruders(); + popMenu(false); + pushMenu(&ui_wiz_filamentchange, true); + break; + case UI_ACTION_WIZARD_JAM_WAITHEAT: // called while heating - should do nothing user must wait + BEEP_LONG; + break; +#endif // EXTRUDER_JAM_CONTROL +#endif + } + return 0; + } + if(entType == 2) // Enter submenu + { + pushMenu((UIMenu*)action, false); +// BEEP_SHORT +#if FEATURE_BABYSTEPPING + zBabySteps = 0; +#endif +#if HAVE_HEATED_BED + if(action == pgm_read_word(&ui_menu_conf_bed.action)) // enter Bed configuration menu + currHeaterForSetup = &heatedBedController; + else +#endif + currHeaterForSetup = &(Extruder::current->tempControl); + Printer::setMenuMode(MENU_MODE_FULL_PID, currHeaterForSetup->heatManager == 1); + Printer::setMenuMode(MENU_MODE_DEADTIME, currHeaterForSetup->heatManager == 3); + return 0; + } + if(entType == 3) + { + return executeAction(action, allowMoves); + } + return executeAction(UI_ACTION_BACK, allowMoves); +#endif +} + +//#define INCREMENT_MIN_MAX(a,steps,_min,_max) if ( (increment<0) && (_min>=0) && (a<_min-increment*steps) ) {a=_min;} else { a+=increment*steps; if(a<_min) a=_min; else if(a>_max) a=_max;}; + +// this version not have single byte variable rollover bug +#define INCREMENT_MIN_MAX(a,steps,_min,_max) a = constrain((a + increment*steps), _min, _max); + +void UIDisplay::adjustMenuPos() +{ + if(menuLevel == 0) return; + UIMenu *men = (UIMenu*)menu[menuLevel]; + UIMenuEntry **entries = (UIMenuEntry**)pgm_read_word(&(men->entries)); + uint8_t mtype = HAL::readFlashByte((PGM_P)&(men->menuType)) & 127; + uint16_t numEntries = pgm_read_word(&(men->numEntries)); + if(mtype != 2) return; + UIMenuEntry *entry; + while(menuPos[menuLevel] > 0) // Go up until we reach visible position + { + entry = (UIMenuEntry *)pgm_read_word(&(entries[menuPos[menuLevel]])); + if(pgm_read_byte((void*)&(entry->entryType)) == 1) // skip headlines + menuPos[menuLevel]--; + else if(entry->showEntry()) + break; + else + menuPos[menuLevel]--; + } + + // with bad luck the only visible option was in the opposite direction + while(menuPos[menuLevel] < numEntries - 1) // Go down until we reach visible position + { + entry = (UIMenuEntry *)pgm_read_word(&(entries[menuPos[menuLevel]])); + if(pgm_read_byte((void*)&(entry->entryType)) == 1) // skip headlines + menuPos[menuLevel]++; + else if(entry->showEntry()) + break; + else + menuPos[menuLevel]++; + } + + uint8_t skipped = 0; + bool modified; + if(menuTop[menuLevel] > menuPos[menuLevel]) + menuTop[menuLevel] = menuPos[menuLevel]; + do + { + skipped = 0; + modified = false; + for(uint8_t r = menuTop[menuLevel]; r < menuPos[menuLevel]; r++) + { + UIMenuEntry *ent = (UIMenuEntry *)pgm_read_word(&(entries[r])); + if(!ent->showEntry()) + skipped++; + } + if(menuTop[menuLevel] + skipped + UI_ROWS - 1 < menuPos[menuLevel]) + { + menuTop[menuLevel] = menuPos[menuLevel] + 1 - UI_ROWS; + modified = true; + } + } + while(modified); +} + +bool UIDisplay::isWizardActive() +{ + UIMenu *men = (UIMenu*)menu[menuLevel]; + return (HAL::readFlashByte((PGM_P)&(men->menuType)) & 127) == 5; +} +bool UIDisplay::isSticky() { + UIMenu *men = (UIMenu*)menu[menuLevel]; + uint8_t mt = HAL::readFlashByte((PGM_P)&(men->menuType)); + return ((mt & 128) == 128) || mt == 5; +} + +bool UIDisplay::nextPreviousAction(int16_t next, bool allowMoves) +{ + if(Printer::isUIErrorMessage()) + { + Printer::setUIErrorMessage(false); + return true; + } + millis_t actTime = HAL::timeInMilliseconds(); + millis_t dtReal; + millis_t dt = dtReal = actTime - lastNextPrev; + lastNextPrev = actTime; + if(dt < SPEED_MAX_MILLIS) dt = SPEED_MAX_MILLIS; + if(dt > SPEED_MIN_MILLIS) + { + dt = SPEED_MIN_MILLIS; + lastNextAccumul = 1; + } + float f = (float)(SPEED_MIN_MILLIS - dt) / (float)(SPEED_MIN_MILLIS - SPEED_MAX_MILLIS); + lastNextAccumul = 1.0f + (float)SPEED_MAGNIFICATION * f * f; +#if UI_DYNAMIC_ENCODER_SPEED + int16_t dynSp = lastNextAccumul / 16; + if(dynSp < 1) dynSp = 1; + if(dynSp > 30) dynSp = 30; + next *= dynSp; +#endif + +#if UI_HAS_KEYS == 1 + if(menuLevel == 0) + { + lastSwitch = HAL::timeInMilliseconds(); + if((UI_INVERT_MENU_DIRECTION && next < 0) || (!UI_INVERT_MENU_DIRECTION && next > 0)) + { + menuPos[0]++; + if(menuPos[0] >= UI_NUM_PAGES) + menuPos[0] = 0; + } + else + { + menuPos[0] = (menuPos[0] == 0 ? UI_NUM_PAGES - 1 : menuPos[0] - 1); + } + return true; + } + UIMenu *men = (UIMenu*)menu[menuLevel]; + uint8_t nr = pgm_read_word_near(&(men->numEntries)); + uint8_t mtype = HAL::readFlashByte((PGM_P)&(men->menuType)) & 127; + UIMenuEntry **entries = (UIMenuEntry**)pgm_read_word(&(men->entries)); + UIMenuEntry *ent =(UIMenuEntry *)pgm_read_word(&(entries[menuPos[menuLevel]])); + UIMenuEntry *testEnt; + // 0 = Info, 1 = Headline, 2 = submenu ref, 3 = direct action command + //uint8_t entType = HAL::readFlashByte((PGM_P)&(ent->entryType)); + unsigned int action = pgm_read_word(&(ent->action)); + if(mtype == UI_MENU_TYPE_SUBMENU && activeAction == 0) // browse through menu items + { + if((UI_INVERT_MENU_DIRECTION && next < 0) || (!UI_INVERT_MENU_DIRECTION && next > 0)) + { + while(menuPos[menuLevel] + 1 < nr) + { + menuPos[menuLevel]++; + testEnt = (UIMenuEntry *)pgm_read_word(&(entries[menuPos[menuLevel]])); + if(testEnt->showEntry()) + break; + } + } + else if(menuPos[menuLevel] > 0) + { + while(menuPos[menuLevel] > 0) + { + menuPos[menuLevel]--; + testEnt = (UIMenuEntry *)pgm_read_word(&(entries[menuPos[menuLevel]])); + if(testEnt->showEntry()) + break; + } + } + shift = -2; // reset shift position + adjustMenuPos(); + return true; + } +#if SDSUPPORT + if(mtype == UI_MENU_TYPE_FILE_SELECTOR) // SD listing + { + if((UI_INVERT_MENU_DIRECTION && next < 0) || (!UI_INVERT_MENU_DIRECTION && next > 0)) + { + menuPos[menuLevel] += abs(next); + if(menuPos[menuLevel] > nFilesOnCard) menuPos[menuLevel] = nFilesOnCard; + } + else if(menuPos[menuLevel] > 0) + { + if(menuPos[menuLevel] > abs(next)) + menuPos[menuLevel] -= abs(next); + else + menuPos[menuLevel] = 0; + } + if(menuTop[menuLevel] > menuPos[menuLevel]) + menuTop[menuLevel] = menuPos[menuLevel]; + else if(menuTop[menuLevel] + UI_ROWS - 1 < menuPos[menuLevel]) + menuTop[menuLevel] = menuPos[menuLevel] + 1 - UI_ROWS; + shift = -2; // reset shift position + return true; + } +#endif + if(mtype == UI_MENU_TYPE_MODIFICATION_MENU || mtype == UI_MENU_TYPE_WIZARD) action = pgm_read_word(&(men->id)); + else action = activeAction; + int16_t increment = next; + EVENT_START_NEXTPREVIOUS(action,increment); + switch(action) + { + case UI_ACTION_FANSPEED: + Commands::setFanSpeed(Printer::getFanSpeed() + increment * 3, true); + break; + case UI_ACTION_XPOSITION: + if(!allowMoves) return false; +#if UI_SPEEDDEPENDENT_POSITIONING + { + float d = 0.01*(float)increment * lastNextAccumul; + if(fabs(d) * 1000 > Printer::maxFeedrate[X_AXIS] * dtReal) + d *= Printer::maxFeedrate[X_AXIS]*dtReal / (1000 * fabs(d)); + long steps = (long)(d * Printer::axisStepsPerMM[X_AXIS]); + steps = ( increment < 0 ? RMath::min(steps,(long)increment) : RMath::max(steps,(long)increment)); + PrintLine::moveRelativeDistanceInStepsReal(steps,0,0,0,Printer::maxFeedrate[X_AXIS],false,false); + } +#else + PrintLine::moveRelativeDistanceInStepsReal(increment,0,0,0,Printer::homingFeedrate[X_AXIS],false,false); +#endif + Commands::printCurrentPosition(PSTR("UI_ACTION_XPOSITION ")); + break; + case UI_ACTION_YPOSITION: + if(!allowMoves) return false; +#if UI_SPEEDDEPENDENT_POSITIONING + { + float d = 0.01 * (float)increment * lastNextAccumul; + if(fabs(d) * 1000 > Printer::maxFeedrate[Y_AXIS] * dtReal) + d *= Printer::maxFeedrate[Y_AXIS] * dtReal / (1000 * fabs(d)); + long steps = (long)(d * Printer::axisStepsPerMM[Y_AXIS]); + steps = ( increment < 0 ? RMath::min(steps,(long)increment) : RMath::max(steps,(long)increment)); + PrintLine::moveRelativeDistanceInStepsReal(0,steps,0,0,Printer::maxFeedrate[Y_AXIS],false,false); + } +#else + PrintLine::moveRelativeDistanceInStepsReal(0,increment,0,0,Printer::homingFeedrate[Y_AXIS],false,false); +#endif + Commands::printCurrentPosition(PSTR("UI_ACTION_YPOSITION ")); + break; + case UI_ACTION_ZPOSITION_NOTEST: + if(!allowMoves) return false; + Printer::setNoDestinationCheck(true); + goto ZPOS1; + case UI_ACTION_ZPOSITION: + if(!allowMoves) return false; +ZPOS1: +#if UI_SPEEDDEPENDENT_POSITIONING + { + float d = 0.01 * (float)increment * lastNextAccumul; + if(fabs(d) * 1000 > Printer::maxFeedrate[Z_AXIS] * dtReal) + d *= Printer::maxFeedrate[Z_AXIS] * dtReal / (1000 * fabs(d)); + long steps = (long)(d * Printer::axisStepsPerMM[Z_AXIS]); + steps = ( increment<0 ? RMath::min(steps,(long)increment) : RMath::max(steps,(long)increment)); + PrintLine::moveRelativeDistanceInStepsReal(0,0,steps,0,Printer::maxFeedrate[Z_AXIS],false,false); + } +#else + PrintLine::moveRelativeDistanceInStepsReal(0, 0, ((long)increment * Printer::axisStepsPerMM[Z_AXIS]) / 100, 0, Printer::homingFeedrate[Z_AXIS],false,false); +#endif + Printer::setNoDestinationCheck(false); + Commands::printCurrentPosition(PSTR("UI_ACTION_ZPOSITION ")); + break; + case UI_ACTION_XPOSITION_FAST: + if(!allowMoves) return false; + PrintLine::moveRelativeDistanceInStepsReal(Printer::axisStepsPerMM[X_AXIS] * increment,0,0,0,Printer::homingFeedrate[X_AXIS],true,false); + Commands::printCurrentPosition(PSTR("UI_ACTION_XPOSITION_FAST ")); + break; + case UI_ACTION_YPOSITION_FAST: + if(!allowMoves) return false; + PrintLine::moveRelativeDistanceInStepsReal(0,Printer::axisStepsPerMM[Y_AXIS] * increment,0,0,Printer::homingFeedrate[Y_AXIS],true,false); + Commands::printCurrentPosition(PSTR("UI_ACTION_YPOSITION_FAST ")); + break; + case UI_ACTION_ZPOSITION_FAST_NOTEST: + if(!allowMoves) return false; + Printer::setNoDestinationCheck(true); + goto ZPOS2; + case UI_ACTION_ZPOSITION_FAST: + if(!allowMoves) return false; +ZPOS2: + PrintLine::moveRelativeDistanceInStepsReal(0,0,Printer::axisStepsPerMM[Z_AXIS] * increment,0,Printer::homingFeedrate[Z_AXIS],true,false); + Printer::setNoDestinationCheck(false); + Commands::printCurrentPosition(PSTR("UI_ACTION_ZPOSITION_FAST ")); + break; + case UI_ACTION_EPOSITION: + if(!allowMoves) return false; + PrintLine::moveRelativeDistanceInSteps(0,0,0,Printer::axisStepsPerMM[E_AXIS]*increment / Printer::extrusionFactor,UI_SET_EXTRUDER_FEEDRATE,true,false,false); + Commands::printCurrentPosition(PSTR("UI_ACTION_EPOSITION ")); + break; +#if FEATURE_RETRACTION + case UI_ACTION_WIZARD_FILAMENTCHANGE: // filament change is finished + Extruder::current->retractDistance(-increment); + Commands::waitUntilEndOfAllMoves(); + Extruder::current->disableCurrentExtruderMotor(); + break; +#endif + case UI_ACTION_Z_BABYSTEPS: +#if FEATURE_BABYSTEPPING + { + previousMillisCmd = HAL::timeInMilliseconds(); +#if UI_DYNAMIC_ENCODER_SPEED + increment /= dynSp; // we need fixed speeds or we get in trouble here! +#endif + if((abs((int)Printer::zBabystepsMissing + (increment * BABYSTEP_MULTIPLICATOR))) < 20000) + { + InterruptProtectedBlock noint; + Printer::zBabystepsMissing += increment * BABYSTEP_MULTIPLICATOR; + zBabySteps += increment * BABYSTEP_MULTIPLICATOR; + } + } +#endif + break; + case UI_ACTION_HEATED_BED_TEMP: +#if HAVE_HEATED_BED + { + int tmp = (int)heatedBedController.targetTemperatureC; + if(tmp < UI_SET_MIN_HEATED_BED_TEMP) tmp = 0; + if(tmp == 0 && increment > 0) tmp = UI_SET_MIN_HEATED_BED_TEMP; + else tmp += increment; + if(tmp < UI_SET_MIN_HEATED_BED_TEMP) tmp = 0; + else if(tmp > UI_SET_MAX_HEATED_BED_TEMP) tmp = UI_SET_MAX_HEATED_BED_TEMP; + Extruder::setHeatedBedTemperature(tmp); + } +#endif + break; + + case UI_ACTION_EXTRUDER0_TEMP: +#if NUM_EXTRUDER > 1 + case UI_ACTION_EXTRUDER1_TEMP: +#endif +#if NUM_EXTRUDER > 2 + case UI_ACTION_EXTRUDER2_TEMP: +#endif +#if NUM_EXTRUDER > 3 + case UI_ACTION_EXTRUDER3_TEMP: +#endif +#if NUM_EXTRUDER > 4 + case UI_ACTION_EXTRUDER4_TEMP: +#endif +#if NUM_EXTRUDER > 5 + case UI_ACTION_EXTRUDER5_TEMP: +#endif + { + int tmp = (int)extruder[action - UI_ACTION_EXTRUDER0_TEMP].tempControl.targetTemperatureC; + if(tmp < UI_SET_MIN_EXTRUDER_TEMP) tmp = 0; + if(tmp == 0 && increment > 0) tmp = UI_SET_MIN_EXTRUDER_TEMP; + else tmp += increment; + if(tmp < UI_SET_MIN_EXTRUDER_TEMP) tmp = 0; + else if(tmp > UI_SET_MAX_EXTRUDER_TEMP) tmp = UI_SET_MAX_EXTRUDER_TEMP; + Extruder::setTemperatureForExtruder(tmp, action - UI_ACTION_EXTRUDER0_TEMP); + } + break; + case UI_ACTION_FEEDRATE_MULTIPLY: + { + int fr = Printer::feedrateMultiply; + INCREMENT_MIN_MAX(fr,1,25,500); + Commands::changeFeedrateMultiply(fr); + } + break; + case UI_ACTION_FLOWRATE_MULTIPLY: + { + INCREMENT_MIN_MAX(Printer::extrudeMultiply,1,25,500); + Commands::changeFlowrateMultiply(Printer::extrudeMultiply); + } + break; +#if UI_BED_COATING + case UI_ACTION_COATING_CUSTOM: + INCREMENT_MIN_MAX(Printer::zBedOffset,0.01,-1.0,199.0); + break; +#endif + case UI_ACTION_STEPPER_INACTIVE: + { + uint8_t inactT = stepperInactiveTime / 60000; + INCREMENT_MIN_MAX(inactT,1,0,240); + stepperInactiveTime = inactT * 60000; + } + break; + case UI_ACTION_MAX_INACTIVE: + { + uint8_t inactT = maxInactiveTime / 60000; + INCREMENT_MIN_MAX(inactT,1,0,240); + maxInactiveTime = inactT * 60000; + } + break; + case UI_ACTION_PRINT_ACCEL_X: + case UI_ACTION_PRINT_ACCEL_Y: + case UI_ACTION_PRINT_ACCEL_Z: +#if DRIVE_SYSTEM != DELTA + INCREMENT_MIN_MAX(Printer::maxAccelerationMMPerSquareSecond[action - UI_ACTION_PRINT_ACCEL_X],((action == UI_ACTION_PRINT_ACCEL_Z) ? 1 : 100),0,10000); +#else + INCREMENT_MIN_MAX(Printer::maxAccelerationMMPerSquareSecond[action - UI_ACTION_PRINT_ACCEL_X],100,0,10000); +#endif + Printer::updateDerivedParameter(); + break; + case UI_ACTION_MOVE_ACCEL_X: + case UI_ACTION_MOVE_ACCEL_Y: + case UI_ACTION_MOVE_ACCEL_Z: +#if DRIVE_SYSTEM != DELTA + INCREMENT_MIN_MAX(Printer::maxTravelAccelerationMMPerSquareSecond[action - UI_ACTION_MOVE_ACCEL_X],((action == UI_ACTION_MOVE_ACCEL_Z) ? 1 : 100),0,10000); +#else + INCREMENT_MIN_MAX(Printer::maxTravelAccelerationMMPerSquareSecond[action - UI_ACTION_MOVE_ACCEL_X],100,0,10000); +#endif + Printer::updateDerivedParameter(); + break; + case UI_ACTION_MAX_JERK: + INCREMENT_MIN_MAX(Printer::maxJerk,0.1,1,99.9); + break; +#if DRIVE_SYSTEM != DELTA + case UI_ACTION_MAX_ZJERK: + INCREMENT_MIN_MAX(Printer::maxZJerk,0.1,0.1,99.9); + break; +#endif + case UI_ACTION_HOMING_FEEDRATE_X: + case UI_ACTION_HOMING_FEEDRATE_Y: + case UI_ACTION_HOMING_FEEDRATE_Z: + INCREMENT_MIN_MAX(Printer::homingFeedrate[action - UI_ACTION_HOMING_FEEDRATE_X], 1, 1, 1000); + break; + + case UI_ACTION_MAX_FEEDRATE_X: + case UI_ACTION_MAX_FEEDRATE_Y: + case UI_ACTION_MAX_FEEDRATE_Z: + INCREMENT_MIN_MAX(Printer::maxFeedrate[action - UI_ACTION_MAX_FEEDRATE_X], 1, 1, 1000); + break; + + case UI_ACTION_STEPS_X: + case UI_ACTION_STEPS_Y: + case UI_ACTION_STEPS_Z: + INCREMENT_MIN_MAX(Printer::axisStepsPerMM[action - UI_ACTION_STEPS_X], 0.1, 0, 999); + Printer::updateDerivedParameter(); + break; + + case UI_ACTION_XOFF: + case UI_ACTION_YOFF: + { + float tmp = -Printer::coordinateOffset[action - UI_ACTION_XOFF]; + INCREMENT_MIN_MAX(tmp, 1, -999, 999); + Printer::coordinateOffset[action - UI_ACTION_XOFF] = -tmp; + } + break; + case UI_ACTION_ZOFF: + { + float tmp = -Printer::coordinateOffset[Z_AXIS]; + INCREMENT_MIN_MAX(tmp, 0.01, -9.99, 9.99); + Printer::coordinateOffset[Z_AXIS] = -tmp; + } + break; + + case UI_ACTION_BAUDRATE: +#if EEPROM_MODE != 0 + { + int16_t p = 0; + int32_t rate; + do + { + rate = pgm_read_dword(&(baudrates[(uint8_t)p])); + if(rate == baudrate) break; + p++; + } + while(rate != 0); + if(rate == 0) p -= 2; + p += increment; + if(p < 0) p = 0; + if(p > static_cast(sizeof(baudrates)/4) - 2) + p = sizeof(baudrates)/4 - 2; + baudrate = pgm_read_dword(&(baudrates[p])); + } +#endif + break; + case UI_ACTION_SERVOPOS: +#if FEATURE_SERVO > 0 && UI_SERVO_CONTROL > 0 + INCREMENT_MIN_MAX(servoPosition, 5, 500, 2500); + HAL::servoMicroseconds(UI_SERVO_CONTROL - 1, servoPosition, 500); +#endif + break; +#if TEMP_PID + case UI_ACTION_PID_PGAIN: + INCREMENT_MIN_MAX(currHeaterForSetup->pidPGain, 0.1, 0, 200); + break; + case UI_ACTION_PID_IGAIN: + INCREMENT_MIN_MAX(currHeaterForSetup->pidIGain, 0.01, 0, 100); + if(&Extruder::current->tempControl == currHeaterForSetup) + Extruder::selectExtruderById(Extruder::current->id); + break; + case UI_ACTION_PID_DGAIN: + INCREMENT_MIN_MAX(currHeaterForSetup->pidDGain, 0.1, 0, 200); + break; + case UI_ACTION_DRIVE_MIN: + INCREMENT_MIN_MAX(currHeaterForSetup->pidDriveMin, 1, 1, 255); + break; + case UI_ACTION_DRIVE_MAX: + INCREMENT_MIN_MAX(currHeaterForSetup->pidDriveMax, 1, 1, 255); + break; + case UI_ACTION_PID_MAX: + INCREMENT_MIN_MAX(currHeaterForSetup->pidMax, 1, 1, 255); + break; +#endif + case UI_ACTION_X_OFFSET: + INCREMENT_MIN_MAX(Extruder::current->xOffset, 1, -99999, 99999); + Extruder::selectExtruderById(Extruder::current->id); + break; + case UI_ACTION_Y_OFFSET: + INCREMENT_MIN_MAX(Extruder::current->yOffset, 1, -99999, 99999); + Extruder::selectExtruderById(Extruder::current->id); + break; + case UI_ACTION_EXTR_STEPS: + INCREMENT_MIN_MAX(Extruder::current->stepsPerMM, 0.1, 1, 9999); + Extruder::selectExtruderById(Extruder::current->id); + break; + case UI_ACTION_EXTR_ACCELERATION: + INCREMENT_MIN_MAX(Extruder::current->maxAcceleration, 10, 10, 99999); + Extruder::selectExtruderById(Extruder::current->id); + break; + case UI_ACTION_EXTR_MAX_FEEDRATE: + INCREMENT_MIN_MAX(Extruder::current->maxFeedrate, 1, 1, 999); + Extruder::selectExtruderById(Extruder::current->id); + break; + case UI_ACTION_EXTR_START_FEEDRATE: + INCREMENT_MIN_MAX(Extruder::current->maxStartFeedrate, 1, 1, 999); + Extruder::selectExtruderById(Extruder::current->id); + break; + case UI_ACTION_EXTR_HEATMANAGER: + INCREMENT_MIN_MAX(currHeaterForSetup->heatManager, 1, 0, 3); + Printer::setMenuMode(MENU_MODE_FULL_PID, currHeaterForSetup->heatManager == 1); // show PIDS only with PID controller selected + Printer::setMenuMode(MENU_MODE_DEADTIME, currHeaterForSetup->heatManager == 3); + break; + case UI_ACTION_EXTR_WATCH_PERIOD: + INCREMENT_MIN_MAX(Extruder::current->watchPeriod, 1, 0, 999); + break; +#if RETRACT_DURING_HEATUP + case UI_ACTION_EXTR_WAIT_RETRACT_TEMP: + INCREMENT_MIN_MAX(Extruder::current->waitRetractTemperature, 1, 100, UI_SET_MAX_EXTRUDER_TEMP); + break; + case UI_ACTION_EXTR_WAIT_RETRACT_UNITS: + INCREMENT_MIN_MAX(Extruder::current->waitRetractUnits, 1, 0, 99); + break; +#endif +#if USE_ADVANCE +#if ENABLE_QUADRATIC_ADVANCE + case UI_ACTION_ADVANCE_K: + INCREMENT_MIN_MAX(Extruder::current->advanceK, 1, 0, 200); + break; +#endif + case UI_ACTION_ADVANCE_L: + INCREMENT_MIN_MAX(Extruder::current->advanceL, 1, 0, 600); + break; +#endif + } +#if UI_AUTORETURN_TO_MENU_AFTER!=0 + ui_autoreturn_time = HAL::timeInMilliseconds() + UI_AUTORETURN_TO_MENU_AFTER; +#endif +#endif + return true; +} + +#if UI_BED_COATING +void UIDisplay::menuAdjustHeight(const UIMenu *men,float offset) +{ +#if EEPROM_MODE != 0 + //If there is something to change + if (EEPROM::zProbeZOffset() != offset) + { + HAL::eprSetFloat(EPR_Z_PROBE_Z_OFFSET, offset); + EEPROM::storeDataIntoEEPROM(false); + } +#endif + Printer::zBedOffset = offset; + //Display message + pushMenu(men, false); + BEEP_SHORT; + Printer::homeAxis(true, true, true); + Commands::printCurrentPosition(PSTR("UI_ACTION_HOMEALL ")); + menuLevel = 0; + activeAction = 0; + UI_STATUS_UPD_F(Com::translatedF(UI_TEXT_PRINTER_READY_ID)); +} +#endif + +void UIDisplay::finishAction(unsigned int action) +{ +#if UI_BED_COATING + if (action == UI_ACTION_COATING_CUSTOM) + { + menuAdjustHeight(&ui_menu_coating_custom,Printer::zBedOffset); + } +#endif +} +// Actions are events from user input. Depending on the current state, each +// action can behave differently. Other actions do always the same like home, disable extruder etc. +int UIDisplay::executeAction(unsigned int action, bool allowMoves) +{ + int ret = 0; +#if UI_HAS_KEYS == 1 + if(action & UI_ACTION_TOPMENU) // Go to start menu + { + menuLevel = 0; + } + action &= 8191; // strip out higher level flags + if(action >= 2000 && action < 3000) + { + setStatusP(Com::translatedF(UI_TEXT_STRING_ACTION_ID)); + } + else + switch(action) + { + case UI_ACTION_OK: + ret = okAction(allowMoves); + break; + case UI_ACTION_BACK: + if(uid.isWizardActive()) break; // wizards can not exit before finished + popMenu(false); + break; + case UI_ACTION_NEXT: + if(!nextPreviousAction(1, allowMoves)) + ret = UI_ACTION_NEXT; + break; + case UI_ACTION_PREVIOUS: + if(!nextPreviousAction(-1, allowMoves)) + ret = UI_ACTION_PREVIOUS; + break; + case UI_ACTION_MENU_UP: + if(menuLevel > 0) menuLevel--; + break; + case UI_ACTION_TOP_MENU: + menuLevel = 0; + break; + case UI_ACTION_EMERGENCY_STOP: + Commands::emergencyStop(); + break; + case UI_ACTION_HOME_ALL: + if(!allowMoves) return UI_ACTION_HOME_ALL; + Printer::homeAxis(true, true, true); + Commands::printCurrentPosition(PSTR("UI_ACTION_HOMEALL ")); + break; + case UI_ACTION_HOME_X: + if(!allowMoves) return UI_ACTION_HOME_X; + Printer::homeAxis(true, false, false); + Commands::printCurrentPosition(PSTR("UI_ACTION_HOME_X ")); + break; + case UI_ACTION_HOME_Y: + if(!allowMoves) return UI_ACTION_HOME_Y; + Printer::homeAxis(false, true, false); + Commands::printCurrentPosition(PSTR("UI_ACTION_HOME_Y ")); + break; + case UI_ACTION_HOME_Z: + if(!allowMoves) return UI_ACTION_HOME_Z; + Printer::homeAxis(false, false, true); + Commands::printCurrentPosition(PSTR("UI_ACTION_HOME_Z ")); + break; + case UI_ACTION_SET_ORIGIN: + if(!allowMoves) return UI_ACTION_SET_ORIGIN; + Printer::setOrigin(0, 0, 0); + break; + case UI_ACTION_DEBUG_ECHO: + Printer::toggleEcho(); + break; + case UI_ACTION_DEBUG_INFO: + Printer::toggleInfo(); + break; + case UI_ACTION_DEBUG_ERROR: + Printer::toggleErrors(); + break; + case UI_ACTION_DEBUG_ENDSTOP: + Printer::toggleEndStop(); + break; + case UI_ACTION_DEBUG_DRYRUN: + Printer::toggleDryRun(); + if(Printer::debugDryrun()) // simulate movements without printing + { + for(int i = 0;i < NUM_EXTRUDER; i++) + Extruder::setTemperatureForExtruder(0, i); +#if HAVE_HEATED_BED + Extruder::setHeatedBedTemperature(0); +#endif + } + break; + case UI_ACTION_POWER: +#if PS_ON_PIN >= 0 // avoid compiler errors when the power supply pin is disabled + Commands::waitUntilEndOfAllMoves(); + //SET_OUTPUT(PS_ON_PIN); //GND + TOGGLE(PS_ON_PIN); +#endif + break; +#if CASE_LIGHTS_PIN >= 0 + case UI_ACTION_LIGHTS_ONOFF: + TOGGLE(CASE_LIGHTS_PIN); +#ifdef CASE_LIGHTS2_PIN + TOGGLE(CASE_LIGHTS2_PIN); +#endif + Printer::reportCaseLightStatus(); + UI_STATUS_F(Com::translatedF(UI_TEXT_LIGHTS_ONOFF_ID)); + break; +#endif + case UI_ACTION_PREHEAT_PLA: + UI_STATUS_F(Com::translatedF(UI_TEXT_PREHEAT_PLA_ID)); + Extruder::setTemperatureForExtruder(UI_SET_PRESET_EXTRUDER_TEMP_PLA,0); +#if NUM_EXTRUDER > 1 + Extruder::setTemperatureForExtruder(UI_SET_PRESET_EXTRUDER_TEMP_PLA,1); +#endif +#if NUM_EXTRUDER > 2 + Extruder::setTemperatureForExtruder(UI_SET_PRESET_EXTRUDER_TEMP_PLA,2); +#endif +#if HAVE_HEATED_BED + Extruder::setHeatedBedTemperature(UI_SET_PRESET_HEATED_BED_TEMP_PLA); +#endif + break; + case UI_ACTION_PREHEAT_ABS: + UI_STATUS_F(Com::translatedF(UI_TEXT_PREHEAT_ABS_ID)); + Extruder::setTemperatureForExtruder(UI_SET_PRESET_EXTRUDER_TEMP_ABS,0); +#if NUM_EXTRUDER > 1 + Extruder::setTemperatureForExtruder(UI_SET_PRESET_EXTRUDER_TEMP_ABS,1); +#endif +#if NUM_EXTRUDER > 2 + Extruder::setTemperatureForExtruder(UI_SET_PRESET_EXTRUDER_TEMP_ABS,2); +#endif +#if HAVE_HEATED_BED + Extruder::setHeatedBedTemperature(UI_SET_PRESET_HEATED_BED_TEMP_ABS); +#endif + break; + case UI_ACTION_COOLDOWN: + UI_STATUS_F(Com::translatedF(UI_TEXT_COOLDOWN_ID)); + for(int i = 0;i < NUM_EXTRUDER; i++) + Extruder::setTemperatureForExtruder(0, i); +#if HAVE_HEATED_BED + Extruder::setHeatedBedTemperature(0); +#endif + break; + case UI_ACTION_HEATED_BED_OFF: +#if HAVE_HEATED_BED + Extruder::setHeatedBedTemperature(0); +#endif + break; + case UI_ACTION_EXTRUDER0_OFF: +#if NUM_EXTRUDER > 1 + case UI_ACTION_EXTRUDER1_OFF: +#endif +#if NUM_EXTRUDER > 2 + case UI_ACTION_EXTRUDER2_OFF: +#endif +#if NUM_EXTRUDER > 3 + case UI_ACTION_EXTRUDER3_OFF: +#endif +#if NUM_EXTRUDER > 4 + case UI_ACTION_EXTRUDER4_OFF: +#endif +#if NUM_EXTRUDER > 5 + case UI_ACTION_EXTRUDER5_OFF: +#endif + Extruder::setTemperatureForExtruder(0, action - UI_ACTION_EXTRUDER0_OFF); + break; + case UI_ACTION_DISABLE_STEPPER: + Printer::kill(true); + break; + case UI_ACTION_RESET_EXTRUDER: + Printer::currentPositionSteps[E_AXIS] = 0; + break; + case UI_ACTION_EXTRUDER_RELATIVE: + Printer::relativeExtruderCoordinateMode=!Printer::relativeExtruderCoordinateMode; + break; + case UI_ACTION_SELECT_EXTRUDER0: +#if NUM_EXTRUDER > 1 + case UI_ACTION_SELECT_EXTRUDER1: +#endif +#if NUM_EXTRUDER > 2 + case UI_ACTION_SELECT_EXTRUDER2: +#endif +#if NUM_EXTRUDER > 3 + case UI_ACTION_SELECT_EXTRUDER3: +#endif +#if NUM_EXTRUDER > 4 + case UI_ACTION_SELECT_EXTRUDER4: +#endif +#if NUM_EXTRUDER > 5 + case UI_ACTION_SELECT_EXTRUDER5: +#endif + if(!allowMoves) return action; + Extruder::selectExtruderById(action - UI_ACTION_SELECT_EXTRUDER0); + currHeaterForSetup = &(Extruder::current->tempControl); + Printer::setMenuMode(MENU_MODE_FULL_PID, currHeaterForSetup->heatManager == 1); + Printer::setMenuMode(MENU_MODE_DEADTIME, currHeaterForSetup->heatManager == 3); + break; +#if FEATURE_DITTO_PRINTING + case UI_DITTO_0: + case UI_DITTO_1: + case UI_DITTO_2: + case UI_DITTO_3: + Extruder::dittoMode = action - UI_DITTO_0; + break; +#endif +#if EEPROM_MODE != 0 + case UI_ACTION_STORE_EEPROM: + EEPROM::storeDataIntoEEPROM(false); + pushMenu(&ui_menu_eeprom_saved, false); + BEEP_LONG; + break; + case UI_ACTION_LOAD_EEPROM: + EEPROM::readDataFromEEPROM(true); + Extruder::selectExtruderById(Extruder::current->id); + pushMenu(&ui_menu_eeprom_loaded, false); + BEEP_LONG; + break; +#endif +#if SDSUPPORT + case UI_ACTION_SD_DELETE: + if(sd.sdactive) + { + pushMenu(&ui_menu_sd_fileselector, false); + } + else + { + UI_ERROR_P(Com::translatedF(UI_TEXT_NOSDCARD_ID)); + } + break; + case UI_ACTION_SD_PRINT: + if(sd.sdactive) + { + pushMenu(&ui_menu_sd_fileselector, false); + } + break; + case UI_ACTION_SD_PAUSE: + if(!allowMoves) + ret = UI_ACTION_SD_PAUSE; + else + sd.pausePrint(true); + break; + case UI_ACTION_SD_CONTINUE: + if(!allowMoves) ret = UI_ACTION_SD_CONTINUE; + else sd.continuePrint(true); + break; + case UI_ACTION_SD_PRI_PAU_CONT: + if(!allowMoves) ret = UI_ACTION_SD_PRI_PAU_CONT; + else + { + if(Printer::isMenuMode(MENU_MODE_SD_PRINTING + MENU_MODE_SD_PAUSED)) + sd.continuePrint(); + else if(Printer::isMenuMode(MENU_MODE_SD_PRINTING)) + sd.pausePrint(true); + else if(sd.sdactive) + pushMenu(&ui_menu_sd_fileselector,false); + } + break; + case UI_ACTION_SD_STOP: + if(!allowMoves) ret = UI_ACTION_SD_STOP; + else sd.stopPrint(); + break; + case UI_ACTION_SD_UNMOUNT: + sd.unmount(); + break; + case UI_ACTION_SD_MOUNT: + sd.mount(); + break; + case UI_ACTION_MENU_SDCARD: + pushMenu(&ui_menu_sd, false); + break; +#endif +#if FAN_PIN>-1 && FEATURE_FAN_CONTROL + case UI_ACTION_FAN_OFF: + case UI_ACTION_FAN_25: + case UI_ACTION_FAN_50: + case UI_ACTION_FAN_75: + Commands::setFanSpeed((action - UI_ACTION_FAN_OFF) * 64, true); + break; + case UI_ACTION_FAN_FULL: + Commands::setFanSpeed(255, true); + break; + case UI_ACTION_FAN_SUSPEND: + { + static uint8_t lastFanSpeed = 255; + if(Printer::getFanSpeed()==0) + Commands::setFanSpeed(lastFanSpeed, true); + else + { + lastFanSpeed = Printer::getFanSpeed(); + Commands::setFanSpeed(0, true); + } + } + break; + case UI_ACTION_IGNORE_M106: + Printer::flag2 ^= PRINTER_FLAG2_IGNORE_M106_COMMAND; + break; +#endif + case UI_ACTION_MENU_XPOS: + pushMenu(&ui_menu_xpos, false); + break; + case UI_ACTION_MENU_YPOS: + pushMenu(&ui_menu_ypos, false); + break; + case UI_ACTION_MENU_ZPOS: + pushMenu(&ui_menu_zpos, false); + break; + case UI_ACTION_MENU_XPOSFAST: + pushMenu(&ui_menu_xpos_fast, false); + break; + case UI_ACTION_MENU_YPOSFAST: + pushMenu(&ui_menu_ypos_fast, false); + break; + case UI_ACTION_MENU_ZPOSFAST: + pushMenu(&ui_menu_zpos_fast, false); + break; + case UI_ACTION_MENU_QUICKSETTINGS: + pushMenu(&ui_menu_quick, false); + break; + case UI_ACTION_MENU_EXTRUDER: + pushMenu(&ui_menu_extruder, false); + break; + case UI_ACTION_MENU_POSITIONS: + pushMenu(&ui_menu_positions, false); + break; +#ifdef UI_USERMENU1 + case UI_ACTION_SHOW_USERMENU1: + pushMenu(&UI_USERMENU1, false); + break; +#endif +#ifdef UI_USERMENU2 + case UI_ACTION_SHOW_USERMENU2: + pushMenu(&UI_USERMENU2, false); + break; +#endif +#ifdef UI_USERMENU3 + case UI_ACTION_SHOW_USERMENU3: + pushMenu(&UI_USERMENU3, false); + break; +#endif +#ifdef UI_USERMENU4 + case UI_ACTION_SHOW_USERMENU4: + pushMenu(&UI_USERMENU4, false); + break; +#endif +#ifdef UI_USERMENU5 + case UI_ACTION_SHOW_USERMENU5: + pushMenu(&UI_USERMENU5, false); + break; +#endif +#ifdef UI_USERMENU6 + case UI_ACTION_SHOW_USERMENU6: + pushMenu(&UI_USERMENU6, false); + break; +#endif +#ifdef UI_USERMENU7 + case UI_ACTION_SHOW_USERMENU7: + pushMenu(&UI_USERMENU7, false); + break; +#endif +#ifdef UI_USERMENU8 + case UI_ACTION_SHOW_USERMENU8: + pushMenu(&UI_USERMENU8, false); + break; +#endif +#ifdef UI_USERMENU9 + case UI_ACTION_SHOW_USERMENU9: + pushMenu(&UI_USERMENU9, false); + break; +#endif +#ifdef UI_USERMENU10 + case UI_ACTION_SHOW_USERMENU10: + pushMenu(&UI_USERMENU10, false); + break; +#endif +#if FEATURE_RETRACTION + case UI_ACTION_WIZARD_FILAMENTCHANGE: + { + if(Printer::isBlockingReceive()) break; + Printer::setJamcontrolDisabled(true); + Com::printFLN(PSTR("important: Filament change required!")); + Printer::setBlockingReceive(true); + BEEP_LONG; + pushMenu(&ui_wiz_filamentchange, true); + Printer::resetWizardStack(); + Printer::pushWizardVar(Printer::currentPositionSteps[E_AXIS]); + Printer::MemoryPosition(); + Extruder::current->retractDistance(FILAMENTCHANGE_SHORTRETRACT); + float newZ = FILAMENTCHANGE_Z_ADD + Printer::currentPosition[Z_AXIS]; + Printer::currentPositionSteps[E_AXIS] = 0; + Printer::moveToReal(Printer::currentPosition[X_AXIS], Printer::currentPosition[Y_AXIS], newZ, 0, Printer::homingFeedrate[Z_AXIS]); + Printer::moveToReal(FILAMENTCHANGE_X_POS, FILAMENTCHANGE_Y_POS, newZ, 0, Printer::homingFeedrate[X_AXIS]); + Extruder::current->retractDistance(FILAMENTCHANGE_LONGRETRACT); + Extruder::current->disableCurrentExtruderMotor(); + } + break; +#if EXTRUDER_JAM_CONTROL + case UI_ACTION_WIZARD_JAM_EOF: + { + Extruder::markAllUnjammed(); + Printer::setJamcontrolDisabled(true); + Printer::setBlockingReceive(true); + pushMenu(&ui_wiz_jamreheat, true); + Printer::resetWizardStack(); + Printer::pushWizardVar(Printer::currentPositionSteps[E_AXIS]); + Printer::MemoryPosition(); + Extruder::current->retractDistance(FILAMENTCHANGE_SHORTRETRACT); + float newZ = FILAMENTCHANGE_Z_ADD + Printer::currentPosition[Z_AXIS]; + Printer::currentPositionSteps[E_AXIS] = 0; + Printer::moveToReal(Printer::currentPosition[X_AXIS], Printer::currentPosition[Y_AXIS], newZ, 0, Printer::homingFeedrate[Z_AXIS]); + Printer::moveToReal(FILAMENTCHANGE_X_POS, FILAMENTCHANGE_Y_POS, newZ, 0, Printer::homingFeedrate[X_AXIS]); + //Extruder::current->retractDistance(FILAMENTCHANGE_LONGRETRACT); + Extruder::pauseExtruders(); + Commands::waitUntilEndOfAllMoves(); +#if FILAMENTCHANGE_REHOME + Printer::disableXStepper(); + Printer::disableYStepper(); +#if Z_HOME_DIR > 0 && FILAMENTCHANGE_REHOME == 2 + Printer::disableZStepper(); +#endif +#endif + } + break; +#endif // EXTRUDER_JAM_CONTROL +#endif // FEATURE_RETRACTION + case UI_ACTION_X_UP: + case UI_ACTION_X_DOWN: + if(!allowMoves) return action; + PrintLine::moveRelativeDistanceInStepsReal(((action == UI_ACTION_X_UP) ? 1.0 : -1.0) * Printer::axisStepsPerMM[X_AXIS], 0, 0, 0, Printer::homingFeedrate[X_AXIS], false,false); + break; + case UI_ACTION_Y_UP: + case UI_ACTION_Y_DOWN: + if(!allowMoves) return action; + PrintLine::moveRelativeDistanceInStepsReal(0, ((action == UI_ACTION_Y_UP) ? 1.0 : -1.0) * Printer::axisStepsPerMM[Y_AXIS], 0, 0, Printer::homingFeedrate[Y_AXIS], false,false); + break; + case UI_ACTION_Z_UP: + case UI_ACTION_Z_DOWN: + if(!allowMoves) return action; + PrintLine::moveRelativeDistanceInStepsReal(0, 0, ((action == UI_ACTION_Z_UP) ? 1.0 : -1.0) * Printer::axisStepsPerMM[Z_AXIS], 0, Printer::homingFeedrate[Z_AXIS], false,false); + break; + case UI_ACTION_EXTRUDER_UP: + case UI_ACTION_EXTRUDER_DOWN: + if(!allowMoves) return action; + PrintLine::moveRelativeDistanceInStepsReal(0, 0, 0, ((action == UI_ACTION_EXTRUDER_UP) ? 1.0 : -1.0) * Printer::axisStepsPerMM[E_AXIS], UI_SET_EXTRUDER_FEEDRATE, false,false); + break; + case UI_ACTION_EXTRUDER_TEMP_UP: + { + int tmp = (int)(Extruder::current->tempControl.targetTemperatureC) + 1; + if(tmp == 1) tmp = UI_SET_MIN_EXTRUDER_TEMP; + else if(tmp > UI_SET_MAX_EXTRUDER_TEMP) tmp = UI_SET_MAX_EXTRUDER_TEMP; + Extruder::setTemperatureForExtruder(tmp, Extruder::current->id); + } + break; + case UI_ACTION_EXTRUDER_TEMP_DOWN: + { + int tmp = (int)(Extruder::current->tempControl.targetTemperatureC) - 1; + if(tmp < UI_SET_MIN_EXTRUDER_TEMP) tmp = 0; + Extruder::setTemperatureForExtruder(tmp, Extruder::current->id); + } + break; + case UI_ACTION_HEATED_BED_UP: +#if HAVE_HEATED_BED + { + int tmp = (int)heatedBedController.targetTemperatureC + 1; + if(tmp == 1) tmp = UI_SET_MIN_HEATED_BED_TEMP; + else if(tmp > UI_SET_MAX_HEATED_BED_TEMP) tmp = UI_SET_MAX_HEATED_BED_TEMP; + Extruder::setHeatedBedTemperature(tmp); + } +#endif + break; +#if MAX_HARDWARE_ENDSTOP_Z + case UI_ACTION_SET_MEASURED_ORIGIN: + { + Printer::updateCurrentPosition(); + Printer::zLength -= Printer::currentPosition[Z_AXIS]; + Printer::currentPositionSteps[Z_AXIS] = 0; + Printer::updateDerivedParameter(); +#if NONLINEAR_SYSTEM + transformCartesianStepsToDeltaSteps(Printer::currentPositionSteps, Printer::currentNonlinearPositionSteps); +#endif + Printer::updateCurrentPosition(true); + Com::printFLN(Com::tZProbePrinterHeight, Printer::zLength); +#if EEPROM_MODE != 0 + EEPROM::storeDataIntoEEPROM(false); + Com::printFLN(Com::tEEPROMUpdated); +#endif + Commands::printCurrentPosition(PSTR("UI_ACTION_SET_MEASURED_ORIGIN ")); + } + break; +#endif + case UI_ACTION_SET_P1: +#if SOFTWARE_LEVELING + for (uint8_t i = 0; i < 3; i++) + { + Printer::levelingP1[i] = Printer::currentPositionSteps[i]; + } +#endif + break; + case UI_ACTION_SET_P2: +#if SOFTWARE_LEVELING + for (uint8_t i = 0; i < 3; i++) + { + Printer::levelingP2[i] = Printer::currentPositionSteps[i]; + } +#endif + break; + case UI_ACTION_SET_P3: +#if SOFTWARE_LEVELING + for (uint8_t i = 0; i < 3; i++) + { + Printer::levelingP3[i] = Printer::currentPositionSteps[i]; + } +#endif + break; + case UI_ACTION_CALC_LEVEL: +#if SOFTWARE_LEVELING + int32_t factors[4]; + PrintLine::calculatePlane(factors, Printer::levelingP1, Printer::levelingP2, Printer::levelingP3); + Com::printFLN(Com::tLevelingCalc); + Com::printFLN(Com::tTower1, PrintLine::calcZOffset(factors, Printer::deltaAPosXSteps, Printer::deltaAPosYSteps) * Printer::invAxisStepsPerMM[Z_AXIS]); + Com::printFLN(Com::tTower2, PrintLine::calcZOffset(factors, Printer::deltaBPosXSteps, Printer::deltaBPosYSteps) * Printer::invAxisStepsPerMM[Z_AXIS]); + Com::printFLN(Com::tTower3, PrintLine::calcZOffset(factors, Printer::deltaCPosXSteps, Printer::deltaCPosYSteps) * Printer::invAxisStepsPerMM[Z_AXIS]); +#endif + break; + case UI_ACTION_HEATED_BED_DOWN: +#if HAVE_HEATED_BED + { + int tmp = (int)heatedBedController.targetTemperatureC - 1; + if(tmp < UI_SET_MIN_HEATED_BED_TEMP) tmp = 0; + Extruder::setHeatedBedTemperature(tmp); + } +#endif + break; + case UI_ACTION_FAN_UP: + Commands::setFanSpeed(Printer::getFanSpeed() + 32, true); + break; + case UI_ACTION_FAN_DOWN: + Commands::setFanSpeed(Printer::getFanSpeed() - 32, true); + break; + case UI_ACTION_KILL: + Commands::emergencyStop(); + break; + case UI_ACTION_RESET: + HAL::resetHardware(); + break; + case UI_ACTION_PAUSE: + Com::printFLN(PSTR("RequestPause:")); + break; +#if UI_BED_COATING + case UI_ACTION_NOCOATING: + menuAdjustHeight(&ui_menu_nocoating_action,0); + break; + case UI_ACTION_BUILDTAK: + menuAdjustHeight(&ui_menu_buildtak_action,0.4); + break; + case UI_ACTION_KAPTON: + menuAdjustHeight(&ui_menu_kapton_action,0.04); + break; + case UI_ACTION_GLUESTICK: + menuAdjustHeight(&ui_menu_gluestick_action,0.04); + break; + case UI_ACTION_BLUETAPE: + menuAdjustHeight(&ui_menu_bluetape_action,0.15); + break; + case UI_ACTION_PETTAPE: + menuAdjustHeight(&ui_menu_pettape_action,0.09); + break; +#endif +#if FEATURE_AUTOLEVEL + case UI_ACTION_AUTOLEVEL_ONOFF: + Printer::setAutolevelActive(!Printer::isAutolevelActive()); + break; +#endif +#ifdef DEBUG_PRINT + case UI_ACTION_WRITE_DEBUG: + Com::printF(PSTR("Buf. Read Idx:"),(int)GCode::bufferReadIndex); + Com::printF(PSTR(" Buf. Write Idx:"),(int)GCode::bufferWriteIndex); + Com::printF(PSTR(" Comment:"),(int)GCode::commentDetected); + Com::printF(PSTR(" Buf. Len:"),(int)GCode::bufferLength); + Com::printF(PSTR(" Wait resend:"),(int)GCode::waitingForResend); + Com::printFLN(PSTR(" Recv. Write Pos:"),(int)GCode::commandsReceivingWritePosition); + Com::printF(PSTR("Min. XY Speed:"),Printer::minimumSpeed); + Com::printF(PSTR(" Min. Z Speed:"),Printer::minimumZSpeed); + Com::printF(PSTR(" Buffer:"),PrintLine::linesCount); + Com::printF(PSTR(" Lines pos:"),(int)PrintLine::linesPos); + Com::printFLN(PSTR(" Write Pos:"),(int)PrintLine::linesWritePos); + Com::printFLN(PSTR("Wait loop:"),debugWaitLoop); + Com::printF(PSTR("sd mode:"),(int)sd.sdmode); + Com::printF(PSTR(" pos:"),sd.sdpos); + Com::printFLN(PSTR(" of "),sd.filesize); + break; +#endif + case UI_ACTION_TEMP_DEFECT: + Printer::setAnyTempsensorDefect(); + break; + case UI_ACTION_LANGUAGE_EN: + case UI_ACTION_LANGUAGE_DE: + case UI_ACTION_LANGUAGE_NL: + case UI_ACTION_LANGUAGE_PT: + case UI_ACTION_LANGUAGE_IT: + case UI_ACTION_LANGUAGE_ES: + case UI_ACTION_LANGUAGE_SE: + case UI_ACTION_LANGUAGE_FR: + case UI_ACTION_LANGUAGE_CZ: + case UI_ACTION_LANGUAGE_PL: + case UI_ACTION_LANGUAGE_TR: + case UI_ACTION_LANGUAGE_FI: + Com::selectLanguage(action - UI_ACTION_LANGUAGE_EN); +#if EEPROM_MODE != 0 + EEPROM::storeDataIntoEEPROM(0); // remember for next start +#endif + break; + } + refreshPage(); +#if UI_AUTORETURN_TO_MENU_AFTER!=0 + ui_autoreturn_time = HAL::timeInMilliseconds() + UI_AUTORETURN_TO_MENU_AFTER; +#endif +#endif + return ret; +} +void UIDisplay::mediumAction() +{ +#if UI_HAS_I2C_ENCODER>0 + uiCheckSlowEncoder(); +#endif +} + +// Gets calles from main tread +void UIDisplay::slowAction(bool allowMoves) +{ + millis_t time = HAL::timeInMilliseconds(); + uint8_t refresh = 0; +#if UI_HAS_KEYS == 1 + // delayed action open? + if(allowMoves && delayedAction != 0) + { + executeAction(delayedAction, true); + delayedAction = 0; + } + + // Update key buffer + InterruptProtectedBlock noInts; + if((flags & (UI_FLAG_FAST_KEY_ACTION + UI_FLAG_KEY_TEST_RUNNING)) == 0) + { + flags |= UI_FLAG_KEY_TEST_RUNNING; + noInts.unprotect(); +#if defined(UI_I2C_HOTEND_LED) || defined(UI_I2C_HEATBED_LED) || defined(UI_I2C_FAN_LED) + { + // check temps and set appropriate leds + int led = 0; +#if NUM_EXTRUDER>0 && defined(UI_I2C_HOTEND_LED) + led |= (tempController[Extruder::current->id]->targetTemperatureC > 0 ? UI_I2C_HOTEND_LED : 0); +#endif +#if HAVE_HEATED_BED && defined(UI_I2C_HEATBED_LED) + led |= (heatedBedController.targetTemperatureC > 0 ? UI_I2C_HEATBED_LED : 0); +#endif +#if FAN_PIN>=0 && defined(UI_I2C_FAN_LED) + led |= (Printer::getFanSpeed() > 0 ? UI_I2C_FAN_LED : 0); +#endif + // update the leds + uid.outputMask= ~led & (UI_I2C_HEATBED_LED | UI_I2C_HOTEND_LED | UI_I2C_FAN_LED); + } +#endif + uint16_t nextAction = 0; + uiCheckSlowKeys(nextAction); +#ifdef HAS_USER_KEYS + ui_check_Ukeys(nextAction); +#endif + if(lastButtonAction != nextAction) + { + lastButtonStart = time; + lastButtonAction = nextAction; + noInts.protect(); + flags |= UI_FLAG_SLOW_KEY_ACTION; // Mark slow action + } + noInts.protect(); + flags &= ~UI_FLAG_KEY_TEST_RUNNING; + } + noInts.protect(); + if((flags & UI_FLAG_SLOW_ACTION_RUNNING) == 0) + { + flags |= UI_FLAG_SLOW_ACTION_RUNNING; + // Reset click encoder + noInts.protect(); + int16_t encodeChange = encoderPos; + encoderPos = 0; + noInts.unprotect(); + int newAction; + if(encodeChange) // encoder changed + { + nextPreviousAction(encodeChange, allowMoves); + BEEP_SHORT + refresh = 1; + } + if(lastAction != lastButtonAction) + { + if(lastButtonAction == 0) + { + if(lastAction >= 2000 && lastAction < 3000) + statusMsg[0] = 0; + lastAction = 0; + noInts.protect(); + flags &= ~(UI_FLAG_FAST_KEY_ACTION + UI_FLAG_SLOW_KEY_ACTION); + } + else if(time - lastButtonStart > UI_KEY_BOUNCETIME) // New key pressed + { + lastAction = lastButtonAction; + BEEP_SHORT + if((newAction = executeAction(lastAction, allowMoves)) == 0) + { + nextRepeat = time + UI_KEY_FIRST_REPEAT; + repeatDuration = UI_KEY_FIRST_REPEAT; + } + else + { + if(delayedAction == 0) + delayedAction = newAction; + } + } + } + else if(lastAction < 1000 && lastAction) // Repeatable key + { + if(time - nextRepeat < 10000) + { + if(delayedAction == 0) + delayedAction = executeAction(lastAction, allowMoves); + else + executeAction(lastAction, allowMoves); + repeatDuration -= UI_KEY_REDUCE_REPEAT; + if(repeatDuration < UI_KEY_MIN_REPEAT) repeatDuration = UI_KEY_MIN_REPEAT; + nextRepeat = time + repeatDuration; + BEEP_SHORT + } + } + noInts.protect(); + flags &= ~UI_FLAG_SLOW_ACTION_RUNNING; + } + noInts.unprotect(); +#endif +#if UI_AUTORETURN_TO_MENU_AFTER != 0 + if(menuLevel > 0 && ui_autoreturn_time < time && !uid.isSticky()) // Go to top menu after x seoonds + { + lastSwitch = time; + menuLevel = 0; + activeAction = 0; + } +#endif + if(uid.isWizardActive()) + previousMillisCmd = HAL::timeInMilliseconds(); // prevent stepper/heater disable from timeout during active wizard + if(menuLevel == 0 && time > 4000) // Top menu refresh/switch + { + if(time - lastSwitch > UI_PAGES_DURATION) + { + lastSwitch = time; +#if !defined(UI_DISABLE_AUTO_PAGESWITCH) || !UI_DISABLE_AUTO_PAGESWITCH + menuPos[0]++; + if(menuPos[0] >= UI_NUM_PAGES) + menuPos[0] = 0; +#endif + refresh = 1; + } + else if(time - lastRefresh >= 1000) refresh = 1; + } + else if(time - lastRefresh >= 800) + { + //UIMenu *men = (UIMenu*)menu[menuLevel]; + //uint8_t mtype = pgm_read_byte((void*)&(men->menuType)); + //if(mtype!=1) + refresh = 1; + } + if(refresh) // does lcd need a refresh? + { +#if defined(TRY_AUTOREPAIR_LCD_ERRORS) +#if defined(HAS_AUTOREPAIR) + repairLCD(); +#else +#error TRY_AUTOREPAIR_LCD_ERRORS is not supported for your display type! +#endif +#endif + + if (menuLevel > 1 || Printer::isAutomount()) + { + shift++; + if(shift + UI_COLS > MAX_COLS + 1) + shift = -2; + } + else + shift = -2; + + refreshPage(); + lastRefresh = time; + } +} + + +// Gets called from inside an interrupt with interrupts allowed! +void UIDisplay::fastAction() +{ +#if UI_HAS_KEYS == 1 + // Check keys + InterruptProtectedBlock noInts; + if((flags & (UI_FLAG_KEY_TEST_RUNNING + UI_FLAG_SLOW_KEY_ACTION)) == 0) + { + flags |= UI_FLAG_KEY_TEST_RUNNING; + uint16_t nextAction = 0; + uiCheckKeys(nextAction); +// ui_check_Ukeys(nextAction); + if(lastButtonAction != nextAction) + { + lastButtonStart = HAL::timeInMilliseconds(); + lastButtonAction = nextAction; + flags |= UI_FLAG_FAST_KEY_ACTION; + } + flags &= ~UI_FLAG_KEY_TEST_RUNNING; + } +#endif +} + +#if defined(UI_REVERSE_ENCODER) && UI_REVERSE_ENCODER == 1 +#if UI_ENCODER_SPEED==0 +const int8_t encoder_table[16] PROGMEM = {0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0}; // Full speed +#elif UI_ENCODER_SPEED==1 +const int8_t encoder_table[16] PROGMEM = {0,0,1,0,0,0,0,-1,-1,0,0,0,0,1,0,0}; // Half speed +#else +const int8_t encoder_table[16] PROGMEM = {0,0,0,0,0,0,0,0,0,0,0,1,0,0,-1,0}; // Quart speed +#endif +#else +#if UI_ENCODER_SPEED==0 +const int8_t encoder_table[16] PROGMEM = {0,1,-1,0,-1,0,0,1,1,0,0,-1,0,-1,1,0}; // Full speed +#elif UI_ENCODER_SPEED==1 +const int8_t encoder_table[16] PROGMEM = {0,0,-1,0,0,0,0,1,1,0,0,0,0,-1,0,0}; // Half speed +#else +//const int8_t encoder_table[16] PROGMEM = {0,0,0,0,0,0,0,0,1,0,0,0,0,-1,0,0}; // Quart speed +//const int8_t encoder_table[16] PROGMEM = {0,1,0,0,-1,0,0,0,0,0,0,0,0,0,0,0}; // Quart speed +const int8_t encoder_table[16] PROGMEM = {0,0,0,0,0,0,0,0,0,0,0,-1,0,0,1,0}; // Quart speed +#endif +#endif +#endif + diff --git a/trunk/Arduino/Repetier_0.92.9/ui.h b/trunk/Arduino/Repetier_0.92.9/ui.h new file mode 100644 index 00000000..55e4a797 --- /dev/null +++ b/trunk/Arduino/Repetier_0.92.9/ui.h @@ -0,0 +1,2139 @@ +/* + This file is part of Repetier-Firmware. + + Repetier-Firmware is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Repetier-Firmware is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Repetier-Firmware. If not, see . + +*/ + +#ifndef _ui_h +#define _ui_h + +#include "gcode.h" + +#define NO_DISPLAY 0 +#define DISPLAY_4BIT 1 +#define DISPLAY_8BIT 2 +#define DISPLAY_I2C 3 +#define DISPLAY_ARDUINO_LIB 4 +#define DISPLAY_U8G 5 +#define DISPLAY_GAMEDUINO2 6 + +/** + What display type do you use? + 0 = No display + 1 = LCD Display with 4 bit data bus + 2 = LCD Display with 8 bit data bus (currently not implemented, fallback to 1) + 3 = LCD Display with I2C connection, 4 bit mode + 4 = Use the slower LiquiedCrystal library bundled with arduino. + IMPORTANT: You need to uncomment the LiquidCrystal include in Repetier.pde for it to work. + If you have Sanguino and want to use the library, you need to have Arduino 023 or older. (13.04.2012) + 5 = U8G supported display +*/ + +// ---------------------------------------------------------------------------- +// Action codes +// 1-999 : Autorepeat +// 1000-1999 : Execute +// 2000-2999 : Write code +// 4000-4999 : Show menu +// 5000-5999 : Wizard pages +// Add UI_ACTION_TOPMENU to show a menu as top menu +// Add UI_ACTION_NO_AUTORETURN to prevent autoreturn to start display +// ---------------------------------------------------------------------------- + +#define UI_ACTION_TOPMENU 8192 +#define UI_ACTION_NO_AUTORETURN 16384 + +#define UI_ACTION_NEXT 1 +#define UI_ACTION_PREVIOUS 2 + +#define UI_ACTION_X_UP 100 +#define UI_ACTION_X_DOWN 101 +#define UI_ACTION_Y_UP 102 +#define UI_ACTION_Y_DOWN 103 +#define UI_ACTION_Z_UP 104 +#define UI_ACTION_Z_DOWN 105 +#define UI_ACTION_EXTRUDER_UP 106 +#define UI_ACTION_EXTRUDER_DOWN 107 +#define UI_ACTION_EXTRUDER_TEMP_UP 108 +#define UI_ACTION_EXTRUDER_TEMP_DOWN 109 +#define UI_ACTION_HEATED_BED_UP 110 +#define UI_ACTION_HEATED_BED_DOWN 111 +#define UI_ACTION_FAN_UP 112 +#define UI_ACTION_FAN_DOWN 113 + +#define UI_ACTION_DUMMY 10000 +#define UI_ACTION_BACK 1000 +#define UI_ACTION_OK 1001 +#define UI_ACTION_MENU_UP 1002 +#define UI_ACTION_TOP_MENU 1003 +#define UI_ACTION_EMERGENCY_STOP 1004 +#define UI_ACTION_XPOSITION 1005 +#define UI_ACTION_YPOSITION 1006 +#define UI_ACTION_ZPOSITION 1007 +#define UI_ACTION_EPOSITION 1008 +#define UI_ACTION_BED_TEMP 1009 +#define UI_ACTION_EXTRUDER_TEMP 1010 +#define UI_ACTION_SD_DELETE 1012 +#define UI_ACTION_SD_PRINT 1013 +#define UI_ACTION_SD_PAUSE 1014 +#define UI_ACTION_SD_CONTINUE 1015 +#define UI_ACTION_SD_UNMOUNT 1016 +#define UI_ACTION_SD_MOUNT 1017 +#define UI_ACTION_XPOSITION_FAST 1018 +#define UI_ACTION_YPOSITION_FAST 1019 +#define UI_ACTION_ZPOSITION_FAST 1020 +#define UI_ACTION_HOME_ALL 1021 +#define UI_ACTION_HOME_X 1022 +#define UI_ACTION_HOME_Y 1023 +#define UI_ACTION_HOME_Z 1024 +#define UI_ACTION_STORE_EEPROM 1030 +#define UI_ACTION_LOAD_EEPROM 1031 +#define UI_ACTION_PRINT_ACCEL_X 1032 +#define UI_ACTION_PRINT_ACCEL_Y 1033 +#define UI_ACTION_PRINT_ACCEL_Z 1034 +#define UI_ACTION_MOVE_ACCEL_X 1035 +#define UI_ACTION_MOVE_ACCEL_Y 1036 +#define UI_ACTION_MOVE_ACCEL_Z 1037 +#define UI_ACTION_MAX_JERK 1038 +#define UI_ACTION_MAX_ZJERK 1039 +#define UI_ACTION_BAUDRATE 1040 +#define UI_ACTION_HOMING_FEEDRATE_X 1041 +#define UI_ACTION_HOMING_FEEDRATE_Y 1042 +#define UI_ACTION_HOMING_FEEDRATE_Z 1043 +#define UI_ACTION_MAX_FEEDRATE_X 1044 +#define UI_ACTION_MAX_FEEDRATE_Y 1045 +#define UI_ACTION_MAX_FEEDRATE_Z 1046 +#define UI_ACTION_STEPS_X 1047 +#define UI_ACTION_STEPS_Y 1048 +#define UI_ACTION_STEPS_Z 1049 +#define UI_ACTION_FAN_OFF 1050 +#define UI_ACTION_FAN_25 1051 +#define UI_ACTION_FAN_50 1052 +#define UI_ACTION_FAN_75 1053 +#define UI_ACTION_FAN_FULL 1054 +#define UI_ACTION_FEEDRATE_MULTIPLY 1055 +#define UI_ACTION_STEPPER_INACTIVE 1056 + +#define UI_ACTION_PID_PGAIN 1058 +#define UI_ACTION_PID_IGAIN 1059 +#define UI_ACTION_PID_DGAIN 1060 +#define UI_ACTION_DRIVE_MIN 1061 +#define UI_ACTION_DRIVE_MAX 1062 +#define UI_ACTION_X_OFFSET 1063 +#define UI_ACTION_Y_OFFSET 1064 +#define UI_ACTION_EXTR_STEPS 1065 +#define UI_ACTION_EXTR_ACCELERATION 1066 +#define UI_ACTION_EXTR_MAX_FEEDRATE 1067 +#define UI_ACTION_EXTR_START_FEEDRATE 1068 +#define UI_ACTION_EXTR_HEATMANAGER 1069 +#define UI_ACTION_EXTR_WATCH_PERIOD 1070 +#define UI_ACTION_PID_MAX 1071 +#define UI_ACTION_ADVANCE_K 1072 +#define UI_ACTION_SET_ORIGIN 1073 + +#define UI_ACTION_POWER 1078 +#define UI_ACTION_PREHEAT_PLA 1079 +#define UI_ACTION_COOLDOWN 1080 +#define UI_ACTION_HEATED_BED_OFF 1081 +#define UI_ACTION_EXTRUDER0_OFF 1082 +#define UI_ACTION_EXTRUDER1_OFF 1083 +#define UI_ACTION_EXTRUDER2_OFF 1084 +#define UI_ACTION_EXTRUDER3_OFF 1085 +#define UI_ACTION_EXTRUDER4_OFF 1086 +#define UI_ACTION_EXTRUDER5_OFF 1087 +#define UI_ACTION_OPS_OFF 1088 +#define UI_ACTION_OPS_CLASSIC 1089 +#define UI_ACTION_OPS_FAST 1090 +#define UI_ACTION_DISABLE_STEPPER 1091 +#define UI_ACTION_RESET_EXTRUDER 1092 +#define UI_ACTION_EXTRUDER_RELATIVE 1093 +#define UI_ACTION_ADVANCE_L 1094 +#define UI_ACTION_PREHEAT_ABS 1095 +#define UI_ACTION_FLOWRATE_MULTIPLY 1096 +#define UI_ACTION_KILL 1097 +#define UI_ACTION_RESET 1098 +#define UI_ACTION_PAUSE 1099 +#define UI_ACTION_EXTR_WAIT_RETRACT_TEMP 1100 +#define UI_ACTION_EXTR_WAIT_RETRACT_UNITS 1101 +#define UI_ACTION_WRITE_DEBUG 1105 +#define UI_ACTION_FANSPEED 1106 +#define UI_ACTION_LIGHTS_ONOFF 1107 +#define UI_ACTION_SD_STOP 1108 +#define UI_ACTION_ZPOSITION_NOTEST 1109 +#define UI_ACTION_ZPOSITION_FAST_NOTEST 1110 +#define UI_ACTION_Z_BABYSTEPS 1111 +#define UI_ACTION_MAX_INACTIVE 1112 +#define UI_ACTION_TEMP_DEFECT 1113 +#define UI_ACTION_BED_HEATMANAGER 1114 +#define UI_ACTION_BED_PGAIN 1115 +#define UI_ACTION_BED_IGAIN 1116 +#define UI_ACTION_BED_DGAIN 1117 +#define UI_ACTION_BED_DRIVE_MIN 1118 +#define UI_ACTION_BED_DRIVE_MAX 1119 +#define UI_ACTION_BED_MAX 1120 +#define UI_ACTION_HEATED_BED_TEMP 1121 +#define UI_ACTION_EXTRUDER0_TEMP 1122 +#define UI_ACTION_EXTRUDER1_TEMP 1123 +#define UI_ACTION_EXTRUDER2_TEMP 1124 +#define UI_ACTION_EXTRUDER3_TEMP 1125 +#define UI_ACTION_EXTRUDER4_TEMP 1126 +#define UI_ACTION_EXTRUDER5_TEMP 1127 +#define UI_ACTION_SELECT_EXTRUDER0 1128 +#define UI_ACTION_SELECT_EXTRUDER1 1129 +#define UI_ACTION_SELECT_EXTRUDER2 1130 +#define UI_ACTION_SELECT_EXTRUDER3 1131 +#define UI_ACTION_SELECT_EXTRUDER4 1132 +#define UI_ACTION_SELECT_EXTRUDER5 1133 +#define UI_DITTO_0 1134 +#define UI_DITTO_1 1135 +#define UI_DITTO_2 1136 +#define UI_DITTO_3 1137 + +#define UI_ACTION_DEBUG_ECHO 1150 +#define UI_ACTION_DEBUG_INFO 1151 +#define UI_ACTION_DEBUG_ERROR 1152 +#define UI_ACTION_DEBUG_DRYRUN 1153 +#define UI_ACTION_DEBUG_ENDSTOP 1154 + +#define UI_ACTION_SD_PRI_PAU_CONT 1200 +#define UI_ACTION_FAN_SUSPEND 1201 +#define UI_ACTION_AUTOLEVEL_ONOFF 1202 +#define UI_ACTION_SERVOPOS 1203 +#define UI_ACTION_IGNORE_M106 1204 + +#define UI_ACTION_KAPTON 1205 +#define UI_ACTION_BLUETAPE 1206 +#define UI_ACTION_NOCOATING 1207 +#define UI_ACTION_PETTAPE 1208 +#define UI_ACTION_GLUESTICK 1209 +#define UI_ACTION_RESET_MATRIX 1210 +#define UI_ACTION_CALIBRATE 1211 +#define UI_ACTION_BED_LED_CHANGE 1212 +#define UI_ACTION_COATING_CUSTOM 1213 +#define UI_ACTION_BUILDTAK 1214 + +// 1700-1956 language selectors + +#define UI_ACTION_LANGUAGE_EN 1700 +#define UI_ACTION_LANGUAGE_DE 1701 +#define UI_ACTION_LANGUAGE_NL 1702 +#define UI_ACTION_LANGUAGE_PT 1703 +#define UI_ACTION_LANGUAGE_IT 1704 +#define UI_ACTION_LANGUAGE_ES 1705 +#define UI_ACTION_LANGUAGE_SE 1706 +#define UI_ACTION_LANGUAGE_FR 1707 +#define UI_ACTION_LANGUAGE_CZ 1708 +#define UI_ACTION_LANGUAGE_PL 1709 +#define UI_ACTION_LANGUAGE_TR 1710 +#define UI_ACTION_LANGUAGE_FI 1711 + +#define UI_ACTION_MENU_XPOS 4000 +#define UI_ACTION_MENU_YPOS 4001 +#define UI_ACTION_MENU_ZPOS 4002 +#define UI_ACTION_MENU_XPOSFAST 4003 +#define UI_ACTION_MENU_YPOSFAST 4004 +#define UI_ACTION_MENU_ZPOSFAST 4005 +#define UI_ACTION_MENU_SDCARD 4006 +#define UI_ACTION_MENU_QUICKSETTINGS 4007 +#define UI_ACTION_MENU_EXTRUDER 4008 +#define UI_ACTION_MENU_POSITIONS 4009 +//#define UI_ACTION_SHOW_MEASUREMENT 4010 +//#define UI_ACTION_RESET_MEASUREMENT 4011 +#define UI_ACTION_SET_MEASURED_ORIGIN 4012 +#define UI_ACTION_SET_P1 4013 +#define UI_ACTION_SET_P2 4014 +#define UI_ACTION_SET_P3 4015 +#define UI_ACTION_CALC_LEVEL 4016 +#define UI_ACTION_XOFF 4020 +#define UI_ACTION_YOFF 4021 +#define UI_ACTION_ZOFF 4022 + +#define UI_ACTION_SHOW_USERMENU1 4101 +#define UI_ACTION_SHOW_USERMENU2 4102 +#define UI_ACTION_SHOW_USERMENU3 4103 +#define UI_ACTION_SHOW_USERMENU4 4104 +#define UI_ACTION_SHOW_USERMENU5 4105 +#define UI_ACTION_SHOW_USERMENU6 4106 +#define UI_ACTION_SHOW_USERMENU7 4107 +#define UI_ACTION_SHOW_USERMENU8 4108 +#define UI_ACTION_SHOW_USERMENU9 4109 +#define UI_ACTION_SHOW_USERMENU10 4110 + +#define UI_ACTION_WIZARD_FILAMENTCHANGE 5000 +#define UI_ACTION_WIZARD_JAM_REHEAT 5001 +#define UI_ACTION_WIZARD_JAM_WAITHEAT 5002 +#define UI_ACTION_WIZARD_JAM_EOF 5003 + +// Load basic language definition to make sure all values are defined +//#include "uilang.h" + +#define UI_MENU_TYPE_INFO 0 +#define UI_MENU_TYPE_FILE_SELECTOR 1 +#define UI_MENU_TYPE_SUBMENU 2 +#define UI_MENU_TYPE_MODIFICATION_MENU 3 +#define UI_MENU_TYPE_WIZARD 5 + +struct UIMenuEntry_s { + const char *text; // Menu text + uint8_t entryType; // 0 = Info, 1 = Headline, 2 = submenu ref, 3 = direct action command, 4 = modify action command, + unsigned int action; // must be int so it gets 32 bit on arm! + uint8_t filter; // allows dynamic menu filtering based on Printer::menuMode bits set. + uint8_t nofilter; // Hide if one of these bits are set + int translation; // Translation id + bool showEntry() const; +} ; +typedef const UIMenuEntry_s UIMenuEntry; + +struct UIMenu_s { + // 0 = info page + // 1 = file selector + // 2 = submenu + // 3 = modififaction menu + // 5 = Wizard menu + // +128 = sticky -> no autoreturn to main menuü after timeout + uint8_t menuType; + int id; // Type of modification + int numEntries; + const UIMenuEntry * const * entries; +}; +typedef const UIMenu_s UIMenu; + +extern const int8_t encoder_table[16] PROGMEM ; + +//#ifdef COMPILE_I2C_DRIVER + +/************************************************************************* + Title: C include file for the I2C master interface + (i2cmaster.S or twimaster.c) + Author: Peter Fleury http://jump.to/fleury + File: $Id: i2cmaster.h,v 1.10 2005/03/06 22:39:57 Peter Exp $ + Software: AVR-GCC 3.4.3 / avr-libc 1.2.3 + Target: any AVR device + Usage: see Doxygen manual +**************************************************************************/ + + + + + +//extern const int matrixActions[] PROGMEM; +// Key codes +#define UI_KEYS_INIT_CLICKENCODER_LOW(pinA,pinB) SET_INPUT(pinA);SET_INPUT(pinB); PULLUP(pinA,HIGH);PULLUP(pinB,HIGH); +#define UI_KEYS_INIT_BUTTON_LOW(pin) SET_INPUT(pin);PULLUP(pin,HIGH); +#define UI_KEYS_INIT_CLICKENCODER_HIGH(pinA,pinB) SET_INPUT(pinA);SET_INPUT(pinB); PULLUP(pinA,LOW);PULLUP(pinB,LOW); +#define UI_KEYS_INIT_BUTTON_HIGH(pin) SET_INPUT(pin);PULLUP(pin,LOW); + +#define UI_KEYS_CLICKENCODER_LOW(pinA,pinB) uid.encoderLast = (uid.encoderLast << 2) & 0x0F;if (!READ(pinA)) uid.encoderLast |=2;if (!READ(pinB)) uid.encoderLast |=1; uid.encoderPos += pgm_read_byte(&encoder_table[uid.encoderLast]); +#define UI_KEYS_CLICKENCODER_LOW_REV(pinA,pinB) uid.encoderLast = (uid.encoderLast << 2) & 0x0F;if (!READ(pinA)) uid.encoderLast |=2;if (!READ(pinB)) uid.encoderLast |=1; uid.encoderPos -= pgm_read_byte(&encoder_table[uid.encoderLast]); +#define UI_KEYS_BUTTON_LOW(pin,action_) if(READ(pin)==0) action=action_; +#define UI_KEYS_CLICKENCODER_HIGH(pinA,pinB) uid.encoderLast = (uid.encoderLast << 2) & 0x0F;if (READ(pinA)) uid.encoderLast |=2;if (READ(pinB)) uid.encoderLast |=1; uid.encoderPos += pgm_read_byte(&encoder_table[uid.encoderLast]); +#define UI_KEYS_CLICKENCODER_HIGH_REV(pinA,pinB) uid.encoderLast = (uid.encoderLast << 2) & 0x0F;if (READ(pinA)) uid.encoderLast |=2;if (READ(pinB)) uid.encoderLast |=1; uid.encoderPos -= pgm_read_byte(&encoder_table[uid.encoderLast]); +#define UI_KEYS_BUTTON_HIGH(pin,action_) if(READ(pin)!=0) action=action_; +#define UI_KEYS_INIT_MATRIX(r1,r2,r3,r4,c1,c2,c3,c4) if(c1>=0){SET_INPUT(c1);WRITE(c1,HIGH);}if(c2>=0){SET_INPUT(c2);WRITE(c2,HIGH);}if(c3>=0){SET_INPUT(c3);WRITE(c3,HIGH);}\ + if(c4>=0) {SET_INPUT(c4);WRITE(c4,HIGH);}if(r1>=0)SET_OUTPUT(r1);if(r2>=0)SET_OUTPUT(r2);if(r3>=0)SET_OUTPUT(r3);if(r4>=0)SET_OUTPUT(r4);\ + if(r1>=0)WRITE(r1,LOW);if(r2>=0)WRITE(r2,LOW);if(r3>=0)WRITE(r3,LOW);if(r4>=0)WRITE(r4,LOW); +// out.print_int_P(PSTR("r4=>c1:"),READ(c1));out.print_int_P(PSTR(" c2:"),READ(c2));out.print_int_P(PSTR(" c3:"),READ(c3));out.println_int_P(PSTR(" c4:"),READ(c4)); +#define UI_KEYS_MATRIX(r1,r2,r3,r4,c1,c2,c3,c4) {uint8_t r = (c1>=0?READ(c1):0) && (c2>=0?READ(c2):0) && (c3>=0?READ(c3):0) && (c4>=0?READ(c4):0);\ + if(!r) {\ + r = 255;\ + if(r2>=0)WRITE(r2,HIGH);if(r3>=0)WRITE(r3,HIGH);if(r4>=0)WRITE(r4,HIGH);\ + if(r1>=0) {\ + asm volatile ("nop\nnop\nnop\nnop\nnop");\ + if(!((c1>=0?READ(c1):1) && (c2>=0?READ(c2):1) && (c3>=0?READ(c3):1) && (c4>=0?READ(c4):1))) r = 0;\ + else WRITE(r1,HIGH);\ + }\ + if(r==255 && r2>=0) {\ + WRITE(r2,LOW);asm volatile ("nop\nnop\nnop\nnop\nnop");\ + if(!((c1>=0?READ(c1):1) && (c2>=0?READ(c2):1) && (c3>=0?READ(c3):1) && (c4>=0?READ(c4):1))) r = 4;\ + else WRITE(r2,HIGH);\ + }\ + if(r==255 && r3>=0) {\ + WRITE(r3,LOW);asm volatile ("nop\nnop\nnop\nnop\nnop");\ + if(!((c1>=0?READ(c1):0) && (c2>=0?READ(c2):1) && (c3>=0?READ(c3):1) && (c4>=0?READ(c4):1))) r = 8;\ + else WRITE(r3,HIGH);\ + }\ + if(r==255 && r4>=0) {\ + WRITE(r4,LOW);asm volatile ("nop\nnop\nnop\nnop\nnop");\ + if(!((c1>=0?READ(c1):1) && (c2>=0?READ(c2):1) && (c3>=0?READ(c3):1) && (c4>=0?READ(c4):1))) r = 12;\ + else WRITE(r4,HIGH);\ + }\ + if(c2>=0 && !READ(c2)) r+=1;\ + else if(c3>=0 && !READ(c3)) r+=2;\ + else if(c4>=0 && !READ(c4)) r+=3;\ + if(r<16) {action = pgm_read_word(&(matrixActions[r]));}\ + }if(r1>=0)WRITE(r1,LOW);if(r2>=0)WRITE(r2,LOW);if(r3>=0)WRITE(r3,LOW);if(r4>=0)WRITE(r4,LOW);} +// I2C keymask tests +#define UI_KEYS_I2C_CLICKENCODER_LOW(pinA,pinB) uid.encoderLast = (uid.encoderLast << 2) & 0x0F;if (!(keymask & pinA)) uid.encoderLast |=2;if (!(keymask & pinB)) uid.encoderLast |=1; uid.encoderPos += pgm_read_byte(&encoder_table[uid.encoderLast]); +#define UI_KEYS_I2C_CLICKENCODER_LOW_REV(pinA,pinB) uid.encoderLast = (uid.encoderLast << 2) & 0x0F;if (!(keymask & pinA)) uid.encoderLast |=2;if (!(keymask & pinB)) uid.encoderLast |=1; uid.encoderPos -= pgm_read_byte(&encoder_table[uid.encoderLast]); +#define UI_KEYS_I2C_BUTTON_LOW(pin,action_) if((keymask & pin)==0) action=action_; +#define UI_KEYS_I2C_CLICKENCODER_HIGH(pinA,pinB) uid.encoderLast = (uid.encoderLast << 2) & 0x0F;if (keymask & pinA) uid.encoderLast |=2;if (keymask & pinB) uid.encoderLast |=1; uid.encoderPos += pgm_read_byte(&encoder_table[uid.encoderLast]); +#define UI_KEYS_I2C_CLICKENCODER_HIGH_REV(pinA,pinB) uid.encoderLast = (uid.encoderLast << 2) & 0x0F;if (keymask & pinA) uid.encoderLast |=2;if (keymask & pinB) uid.encoderLast |=1; uid.encoderPos -= pgm_read_byte(&encoder_table[uid.encoderLast]); +#define UI_KEYS_I2C_BUTTON_HIGH(pin,action_) if((pin & keymask) != 0) action=action_; + +#define UI_STRING(name,text) const char PROGMEM name[] = text + +#define UI_PAGE6(name,row1,row2,row3,row4,row5,row6) UI_STRING(name ## _1txt,row1);UI_STRING(name ## _2txt,row2);UI_STRING(name ## _3txt,row3);UI_STRING(name ## _4txt,row4);UI_STRING(name ## _5txt,row5);UI_STRING(name ## _6txt,row6);\ + UIMenuEntry name ## _1 PROGMEM ={name ## _1txt,0,0,0,0,0};\ + UIMenuEntry name ## _2 PROGMEM ={name ## _2txt,0,0,0,0,0};\ + UIMenuEntry name ## _3 PROGMEM ={name ## _3txt,0,0,0,0,0};\ + UIMenuEntry name ## _4 PROGMEM ={name ## _4txt,0,0,0,0,0};\ + UIMenuEntry name ## _5 PROGMEM ={name ## _5txt,0,0,0,0,0};\ + UIMenuEntry name ## _6 PROGMEM ={name ## _6txt,0,0,0,0,0};\ + const UIMenuEntry * const name ## _entries [] PROGMEM = {&name ## _1,&name ## _2,&name ## _3,&name ## _4,&name ## _5,&name ## _6};\ + const UIMenu name PROGMEM = {0,0,6,name ## _entries}; +#define UI_PAGE6_T(name,row1,row2,row3,row4,row5,row6) \ + UIMenuEntry name ## _1 PROGMEM ={0,0,0,0,0,row1};\ + UIMenuEntry name ## _2 PROGMEM ={0,0,0,0,0,row2};\ + UIMenuEntry name ## _3 PROGMEM ={0,0,0,0,0,row3};\ + UIMenuEntry name ## _4 PROGMEM ={0,0,0,0,0,row4};\ + UIMenuEntry name ## _5 PROGMEM ={0,0,0,0,0,row5};\ + UIMenuEntry name ## _6 PROGMEM ={0,0,0,0,0,row6};\ + const UIMenuEntry * const name ## _entries [] PROGMEM = {&name ## _1,&name ## _2,&name ## _3,&name ## _4,&name ## _5,&name ## _6};\ + const UIMenu name PROGMEM = {0,0,6,name ## _entries}; +#define UI_PAGE4(name,row1,row2,row3,row4) UI_STRING(name ## _1txt,row1);UI_STRING(name ## _2txt,row2);UI_STRING(name ## _3txt,row3);UI_STRING(name ## _4txt,row4);\ + UIMenuEntry name ## _1 PROGMEM ={name ## _1txt,0,0,0,0,0};\ + UIMenuEntry name ## _2 PROGMEM ={name ## _2txt,0,0,0,0,0};\ + UIMenuEntry name ## _3 PROGMEM ={name ## _3txt,0,0,0,0,0};\ + UIMenuEntry name ## _4 PROGMEM ={name ## _4txt,0,0,0,0,0};\ + const UIMenuEntry * const name ## _entries [] PROGMEM = {&name ## _1,&name ## _2,&name ## _3,&name ## _4};\ + const UIMenu name PROGMEM = {0,0,4,name ## _entries}; +#define UI_PAGE4_T(name,row1,row2,row3,row4) \ + UIMenuEntry name ## _1 PROGMEM ={0,0,0,0,0,row1};\ + UIMenuEntry name ## _2 PROGMEM ={0,0,0,0,0,row2};\ + UIMenuEntry name ## _3 PROGMEM ={0,0,0,0,0,row3};\ + UIMenuEntry name ## _4 PROGMEM ={0,0,0,0,0,row4};\ + const UIMenuEntry * const name ## _entries [] PROGMEM = {&name ## _1,&name ## _2,&name ## _3,&name ## _4};\ + const UIMenu name PROGMEM = {0,0,4,name ## _entries}; +#define UI_PAGE2(name,row1,row2) UI_STRING(name ## _1txt,row1);UI_STRING(name ## _2txt,row2);\ + UIMenuEntry name ## _1 PROGMEM ={name ## _1txt,0,0,0,0,0};\ + UIMenuEntry name ## _2 PROGMEM ={name ## _2txt,0,0,0,0,0};\ + const UIMenuEntry * const name ## _entries[] PROGMEM = {&name ## _1,&name ## _2};\ + const UIMenu name PROGMEM = {0,0,2,name ## _entries}; +#define UI_PAGE2_T(name,row1,row2) \ + UIMenuEntry name ## _1 PROGMEM ={0,0,0,0,0,row1};\ + UIMenuEntry name ## _2 PROGMEM ={0,0,0,0,0,row2};\ + const UIMenuEntry * const name ## _entries[] PROGMEM = {&name ## _1,&name ## _2};\ + const UIMenu name PROGMEM = {0,0,2,name ## _entries}; +#define UI_WIZARD4(name,action,row1,row2,row3,row4) UI_STRING(name ## _1txt,row1);UI_STRING(name ## _2txt,row2);UI_STRING(name ## _3txt,row3);UI_STRING(name ## _4txt,row4);\ + UIMenuEntry name ## _1 PROGMEM ={name ## _1txt,0,0,0,0,0};\ + UIMenuEntry name ## _2 PROGMEM ={name ## _2txt,0,0,0,0,0};\ + UIMenuEntry name ## _3 PROGMEM ={name ## _3txt,0,0,0,0,0};\ + UIMenuEntry name ## _4 PROGMEM ={name ## _4txt,0,0,0,0,0};\ + const UIMenuEntry * const name ## _entries [] PROGMEM = {&name ## _1,&name ## _2,&name ## _3,&name ## _4};\ + const UIMenu name PROGMEM = {5,action,4,name ## _entries}; +#define UI_WIZARD4_T(name,action,row1,row2,row3,row4) \ + UIMenuEntry name ## _1 PROGMEM ={0,0,0,0,0,row1};\ + UIMenuEntry name ## _2 PROGMEM ={0,0,0,0,0,row2};\ + UIMenuEntry name ## _3 PROGMEM ={0,0,0,0,0,row3};\ + UIMenuEntry name ## _4 PROGMEM ={0,0,0,0,0,row4};\ + const UIMenuEntry * const name ## _entries [] PROGMEM = {&name ## _1,&name ## _2,&name ## _3,&name ## _4};\ + const UIMenu name PROGMEM = {5,action,4,name ## _entries}; +#define UI_WIZARD2(name,action,row1,row2) UI_STRING(name ## _1txt,row1);UI_STRING(name ## _2txt,row2);\ + UIMenuEntry name ## _1 PROGMEM ={name ## _1txt,0,0,0,0,0};\ + UIMenuEntry name ## _2 PROGMEM ={name ## _2txt,0,0,0,0,0};\ + const UIMenuEntry * const name ## _entries[] PROGMEM = {&name ## _1,&name ## _2};\ + const UIMenu name PROGMEM = {5,action,2,name ## _entries}; +#define UI_WIZARD2_T(name,action,row1,row2) \ + UIMenuEntry name ## _1 PROGMEM ={0,0,0,0,0,row1};\ + UIMenuEntry name ## _2 PROGMEM ={0,0,0,0,0,row2};\ + const UIMenuEntry * const name ## _entries[] PROGMEM = {&name ## _1,&name ## _2};\ + const UIMenu name PROGMEM = {5,action,2,name ## _entries}; +#define UI_MENU_ACTION4C(name,action,rows) UI_MENU_ACTION4(name,action,rows) +#define UI_MENU_ACTION2C(name,action,rows) UI_MENU_ACTION2(name,action,rows) +#define UI_MENU_ACTION4C_T(name,action,rows) UI_MENU_ACTION4_T(name,action,rows) +#define UI_MENU_ACTION2C_T(name,action,rows) UI_MENU_ACTION2_T(name,action,rows) +#define UI_MENU_ACTION4(name,action,row1,row2,row3,row4) UI_STRING(name ## _1txt,row1);UI_STRING(name ## _2txt,row2);UI_STRING(name ## _3txt,row3);UI_STRING(name ## _4txt,row4);\ + UIMenuEntry name ## _1 PROGMEM ={name ## _1txt,0,0,0,0,0};\ + UIMenuEntry name ## _2 PROGMEM ={name ## _2txt,0,0,0,0,0};\ + UIMenuEntry name ## _3 PROGMEM ={name ## _3txt,0,0,0,0,0};\ + UIMenuEntry name ## _4 PROGMEM ={name ## _4txt,0,0,0,0,0};\ + const UIMenuEntry * const name ## _entries[] PROGMEM = {&name ## _1,&name ## _2,&name ## _3,&name ## _4};\ + const UIMenu name PROGMEM = {3,action,4,name ## _entries}; +#define UI_MENU_ACTION4_T(name,action,row1,row2,row3,row4) \ + UIMenuEntry name ## _1 PROGMEM ={0,0,0,0,0,row1};\ + UIMenuEntry name ## _2 PROGMEM ={0,0,0,0,0,row2};\ + UIMenuEntry name ## _3 PROGMEM ={0,0,0,0,0,row3};\ + UIMenuEntry name ## _4 PROGMEM ={0,0,0,0,0,row4};\ + const UIMenuEntry * const name ## _entries[] PROGMEM = {&name ## _1,&name ## _2,&name ## _3,&name ## _4};\ + const UIMenu name PROGMEM = {3,action,4,name ## _entries}; +#define UI_MENU_ACTION2(name,action,row1,row2) UI_STRING(name ## _1txt,row1);UI_STRING(name ## _2txt,row2);\ + UIMenuEntry name ## _1 PROGMEM ={name ## _1txt,0,0,0,0,0};\ + UIMenuEntry name ## _2 PROGMEM ={name ## _2txt,0,0,0,0,0};\ + const UIMenuEntry * const name ## _entries[] PROGMEM = {&name ## _1,&name ## _2};\ + const UIMenu name PROGMEM = {3,action,2,name ## _entries}; +#define UI_MENU_ACTION2_T(name,action,row1,row2) \ + UIMenuEntry name ## _1 PROGMEM ={0,0,0,0,0,row1};\ + UIMenuEntry name ## _2 PROGMEM ={0,0,0,0,0,row2};\ + const UIMenuEntry * const name ## _entries[] PROGMEM = {&name ## _1,&name ## _2};\ + const UIMenu name PROGMEM = {3,action,2,name ## _entries}; +#define UI_MENU_HEADLINE(name,text) UI_STRING(name ## _txt,text);UIMenuEntry name PROGMEM = {name ## _txt,1,0,0,0,0}; +#define UI_MENU_HEADLINE_T(name,text) UIMenuEntry name PROGMEM = {0,1,0,0,0,text}; +#define UI_MENU_CHANGEACTION(name,row,action) UI_STRING(name ## _txt,row);UIMenuEntry name PROGMEM = {name ## _txt,4,action,0,0,0}; +#define UI_MENU_CHANGEACTION_T(name,row,action) UIMenuEntry name PROGMEM = {0,4,action,0,0,row}; +#define UI_MENU_ACTIONCOMMAND(name,row,action) UI_STRING(name ## _txt,row);UIMenuEntry name PROGMEM = {name ## _txt,3,action,0,0,0}; +#define UI_MENU_ACTIONCOMMAND_T(name,rowId,action) UIMenuEntry name PROGMEM = {0,3,action,0,0,rowId}; +#define UI_MENU_ACTIONSELECTOR(name,row,entries) UI_STRING(name ## _txt,row);UIMenuEntry name PROGMEM = {name ## _txt,2,(unsigned int)&entries,0,0,0}; +#define UI_MENU_ACTIONSELECTOR_T(name,row,entries) UIMenuEntry name PROGMEM = {0,2,(unsigned int)&entries,0,0,row}; +#define UI_MENU_SUBMENU(name,row,entries) UI_STRING(name ## _txt,row);UIMenuEntry name PROGMEM = {name ## _txt,2,(unsigned int)&entries,0,0,0}; +#define UI_MENU_SUBMENU_T(name,row,entries) UIMenuEntry name PROGMEM = {0,2,(unsigned int)&entries,0,0,row}; +#define UI_MENU_WIZARD(name,row,entries) UI_STRING(name ## _txt,row);UIMenuEntry name PROGMEM = {name ## _txt,5,(unsigned int)&entries,0,0,0}; +#define UI_MENU_WIZARD_T(name,row,entries) UIMenuEntry name PROGMEM = {0,5,(unsigned int)&entries,0,0,row}; +#define UI_MENU_CHANGEACTION_FILTER(name,row,action,filter,nofilter) UI_STRING(name ## _txt,row);UIMenuEntry name PROGMEM = {name ## _txt,4,action,filter,nofilter,0}; +#define UI_MENU_CHANGEACTION_FILTER_T(name,row,action,filter,nofilter) UIMenuEntry name PROGMEM = {0,4,action,filter,nofilter,row}; +#define UI_MENU_ACTIONCOMMAND_FILTER(name,row,action,filter,nofilter) UI_STRING(name ## _txt,row);UIMenuEntry name PROGMEM = {name ## _txt,3,action,filter,nofilter,0}; +#define UI_MENU_ACTIONCOMMAND_FILTER_T(name,row,action,filter,nofilter) UIMenuEntry name PROGMEM = {0,3,action,filter,nofilter,row}; +#define UI_MENU_ACTIONSELECTOR_FILTER(name,row,entries,filter,nofilter) UI_STRING(name ## _txt,row);UIMenuEntry name PROGMEM = {name ## _txt,2,(unsigned int)&entries,filter,nofilter,0}; +#define UI_MENU_ACTIONSELECTOR_FILTER_T(name,row,entries,filter,nofilter) UIMenuEntry name PROGMEM = {0,2,(unsigned int)&entries,filter,nofilter,row}; +#define UI_MENU_SUBMENU_FILTER(name,row,entries,filter,nofilter) UI_STRING(name ## _txt,row);UIMenuEntry name PROGMEM = {name ## _txt,2,(unsigned int)&entries,filter,nofilter,0}; +#define UI_MENU_SUBMENU_FILTER_T(name,row,entries,filter,nofilter) UIMenuEntry name PROGMEM = {0,2,(unsigned int)&entries,filter,nofilter,row}; +#define UI_MENU(name,items,itemsCnt) const UIMenuEntry * const name ## _entries[] PROGMEM = items;const UIMenu name PROGMEM = {2,0,itemsCnt,name ## _entries}; +#define UI_STICKYMENU(name,items,itemsCnt) const UIMenuEntry * const name ## _entries[] PROGMEM = items;const UIMenu name PROGMEM = {2+128,0,itemsCnt,name ## _entries}; +#define UI_MENU_FILESELECT(name,items,itemsCnt) const UIMenuEntry * const name ## _entries[] PROGMEM = items;const UIMenu name PROGMEM = {1,0,itemsCnt,name ## _entries}; + +#if FEATURE_CONTROLLER == CONTROLLER_SMARTRAMPS || FEATURE_CONTROLLER == CONTROLLER_GADGETS3D_SHIELD || FEATURE_CONTROLLER == CONTROLLER_BAM_DICE_DUE || (FEATURE_CONTROLLER == CONTROLLER_REPRAPDISCOUNT_GLCD && MOTHERBOARD != CONTROLLER_FELIX_DUE) +#undef SDCARDDETECT +#if MOTHERBOARD == 37 +#define SDCARDDETECT ORIG_SDCARDDETECT +#else +#define SDCARDDETECT 49 +#endif +#undef SDCARDDETECTINVERTED +#define SDCARDDETECTINVERTED 0 +#undef SDSUPPORT +#define SDSUPPORT 1 +#endif + +#if FEATURE_CONTROLLER == CONTROLLER_VIKI2 +#undef SDCARDDETECT +#define SDCARDDETECT -1 +#undef SDSUPPORT +#define SDSUPPORT 1 +#endif + +#if FEATURE_CONTROLLER == CONTROLLER_RAMBO +#undef SDCARDDETECT +#define SDCARDDETECT 81 +#undef SDCARDDETECTINVERTED +#define SDCARDDETECTINVERTED 0 +#undef SDSUPPORT +#define SDSUPPORT 1 +#endif + + +// Maximum size of a row - if row is larger, text gets scrolled +#if defined(UI_DISPLAY_TYPE) && UI_DISPLAY_TYPE == DISPLAY_GAMEDUINO2 +#define MAX_COLS 50 +#else +#define MAX_COLS 28 +#endif +#define UI_MENU_MAXLEVEL 5 + +#define UI_FLAG_FAST_KEY_ACTION 1 +#define UI_FLAG_SLOW_KEY_ACTION 2 +#define UI_FLAG_SLOW_ACTION_RUNNING 4 +#define UI_FLAG_KEY_TEST_RUNNING 8 + +class UIDisplay { + public: + volatile uint8_t flags; // 1 = fast key action, 2 = slow key action, 4 = slow action running, 8 = key test running + uint8_t col; // current col for buffer prefill + uint8_t menuLevel; // current menu level, 0 = info, 1 = group, 2 = groupdata select, 3 = value change + uint16_t menuPos[UI_MENU_MAXLEVEL]; // Positions in menu + const UIMenu *menu[UI_MENU_MAXLEVEL]; // Menus active + uint16_t menuTop[UI_MENU_MAXLEVEL]; // Top row in menu + int8_t shift; // Display shift for scrolling text + int pageDelay; // Counter. If 0 page is refreshed if menuLevel is 0. + void *errorMsg; + uint16_t activeAction; // action for ok/next/previous + uint16_t lastAction; + uint16_t delayedAction; + millis_t lastSwitch; // Last time display switched pages + millis_t lastRefresh; + uint16_t lastButtonAction; + millis_t lastButtonStart; + millis_t nextRepeat; // Time of next autorepeat + millis_t lastNextPrev; // for increasing speed settings + float lastNextAccumul; // Accumulated value + unsigned int outputMask; // Output mask for backlight, leds etc. + int repeatDuration; // Time beween to actions if autorepeat is enabled + int8_t oldMenuLevel; + uint8_t encoderStartScreen; + char printCols[MAX_COLS + 1]; + void addInt(int value, uint8_t digits, char fillChar = ' '); // Print int into printCols + void addLong(long value, int8_t digits); + inline void addLong(long value) { + addLong(value, -11); + }; + void addFloat(float number, char fixdigits, uint8_t digits); + inline void addFloat(float number) { + addFloat(number, -9, 2); + }; + void addStringP(PGM_P text); + void addStringOnOff(uint8_t); + void addChar(const char c); + void addGCode(GCode *code); + int okAction(bool allowMoves); + bool nextPreviousAction(int16_t next, bool allowMoves); + char statusMsg[21]; + int8_t encoderPos; + int8_t encoderLast; + UIDisplay(); + void createChar(uint8_t location, const uint8_t charmap[]); + void initialize(); // Initialize display and keys + void waitForKey(); + void printRow(uint8_t r, char *txt, char *txt2, uint8_t changeAtCol); // Print row on display + void printRowP(uint8_t r, PGM_P txt); + void parse(const char *txt, bool ram); /// Parse output and write to printCols; + void refreshPage(); + int executeAction(unsigned int action, bool allowMoves); + void finishAction(unsigned int action); + void slowAction(bool allowMoves); + void fastAction(); + void mediumAction(); + void pushMenu(const UIMenu *men, bool refresh); + void popMenu(bool refresh); + void adjustMenuPos(); + void setStatusP(PGM_P txt, bool error = false); + void setStatus(const char *txt, bool error = false); + inline void setOutputMaskBits(unsigned int bits) { + outputMask |= bits; + } + inline void unsetOutputMaskBits(unsigned int bits) { + outputMask &= ~bits; + } + void updateSDFileCount(); + void goDir(char *name); + bool isDirname(char *name); + bool isWizardActive(); + bool isSticky(); + void showLanguageSelectionWizard(); +#if UI_BED_COATING + void menuAdjustHeight(const UIMenu *men, float offset); +#endif + char cwd[SD_MAX_FOLDER_DEPTH * LONG_FILENAME_LENGTH + 2]; + uint8_t folderLevel; +}; +extern UIDisplay uid; + + +#if FEATURE_CONTROLLER == UICONFIG_CONTROLLER +#include "uiconfig.h" +#endif +// No controller at all +#if FEATURE_CONTROLLER == NO_CONTROLLER +#define UI_HAS_KEYS 0 +#define UI_DISPLAY_TYPE NO_DISPLAY +#ifdef UI_MAIN +void uiInitKeys() {} +void uiCheckKeys(uint16_t &action) {} +inline void uiCheckSlowEncoder() {} +void uiCheckSlowKeys(uint16_t &action) {} +#endif // UI_MAIN +#endif // NO_CONTROLLER +#if (FEATURE_CONTROLLER == CONTROLLER_SMARTRAMPS) || (FEATURE_CONTROLLER == CONTROLLER_GADGETS3D_SHIELD) || (FEATURE_CONTROLLER == CONTROLLER_REPRAPDISCOUNT_GLCD) || (FEATURE_CONTROLLER == CONTROLLER_BAM_DICE_DUE) +#define UI_HAS_KEYS 1 +#define UI_HAS_BACK_KEY 0 +#if FEATURE_CONTROLLER == CONTROLLER_REPRAPDISCOUNT_GLCD +#define UI_DISPLAY_TYPE DISPLAY_U8G +#define U8GLIB_ST7920 +#define UI_LCD_WIDTH 128 +#define UI_LCD_HEIGHT 64 +//select font size +#define UI_FONT_6X10 //default font +#ifdef UI_FONT_6X10 +#define UI_FONT_WIDTH 6 +#define UI_FONT_HEIGHT 10 +#define UI_FONT_SMALL_HEIGHT 7 +#define UI_FONT_DEFAULT repetier_6x10 +#define UI_FONT_SMALL repetier_5x7 +#define UI_FONT_SMALL_WIDTH 5 //smaller font for status display +#undef UI_ANIMATION +#define UI_ANIMATION 0 // Animations are too slow +#endif + +//calculate rows and cols available with current font +#define UI_COLS (UI_LCD_WIDTH/UI_FONT_WIDTH) +#define UI_ROWS (UI_LCD_HEIGHT/UI_FONT_HEIGHT) +#define UI_DISPLAY_CHARSET 3 +#else // 40x4 char display +#define UI_DISPLAY_TYPE DISPLAY_4BIT +#define UI_DISPLAY_CHARSET 1 +#define UI_COLS 20 +#define UI_ROWS 4 +#endif + +#define BEEPER_TYPE 1 + +#if FEATURE_CONTROLLER == CONTROLLER_GADGETS3D_SHIELD // Gadgets3d shield + +#undef BEEPER_PIN +#define BEEPER_PIN 33 +#define UI_DISPLAY_RS_PIN 16 +#define UI_DISPLAY_RW_PIN -1 +#define UI_DISPLAY_ENABLE_PIN 17 +#define UI_DISPLAY_D0_PIN 23 +#define UI_DISPLAY_D1_PIN 25 +#define UI_DISPLAY_D2_PIN 27 +#define UI_DISPLAY_D3_PIN 29 +#define UI_DISPLAY_D4_PIN 23 +#define UI_DISPLAY_D5_PIN 25 +#define UI_DISPLAY_D6_PIN 27 +#define UI_DISPLAY_D7_PIN 29 +#define UI_ENCODER_A 35 +#define UI_ENCODER_B 37 +#define UI_ENCODER_CLICK 31 +#define UI_RESET_PIN 41 +#else // Smartcontroller + +#if MOTHERBOARD == 701 // Megatronics v2.0 + +#define UI_DISPLAY_RS_PIN 14 +#define UI_DISPLAY_RW_PIN -1 +#define UI_DISPLAY_ENABLE_PIN 15 +#define UI_DISPLAY_D0_PIN -1 +#define UI_DISPLAY_D1_PIN -1 +#define UI_DISPLAY_D2_PIN -1 +#define UI_DISPLAY_D3_PIN -1 +#define UI_DISPLAY_D4_PIN 30 +#define UI_DISPLAY_D5_PIN 31 +#define UI_DISPLAY_D6_PIN 32 +#define UI_DISPLAY_D7_PIN 33 +#define UI_ENCODER_A 61 +#define UI_ENCODER_B 59 +#define UI_ENCODER_CLICK 43 +#define UI_RESET_PIN 66 // was 41 //AE3 was here and added this line 1/25/2014 (Note pin 41 is Y- endstop!) +#define UI_INVERT_MENU_DIRECTION 1 + +#elif MOTHERBOARD == 703 // Megatronics v3.0 + +#define UI_DISPLAY_RS_PIN 32 +#define UI_DISPLAY_RW_PIN -1 +#define UI_DISPLAY_ENABLE_PIN 31 +#define UI_DISPLAY_D0_PIN -1 +#define UI_DISPLAY_D1_PIN -1 +#define UI_DISPLAY_D2_PIN -1 +#define UI_DISPLAY_D3_PIN -1 +#define UI_DISPLAY_D4_PIN 14 +#define UI_DISPLAY_D5_PIN 30 +#define UI_DISPLAY_D6_PIN 39 +#define UI_DISPLAY_D7_PIN 15 +#define UI_ENCODER_A 45 +#define UI_ENCODER_B 44 +#define UI_ENCODER_CLICK 33 +#define UI_INVERT_MENU_DIRECTION 1 +#define UI_RESET_PIN -1 + +#elif MOTHERBOARD == 80 // Rumba has different pins as RAMPS! + +#undef BEEPER_PIN +#define BEEPER_PIN 44 +#define UI_DISPLAY_RS_PIN 19 +#define UI_DISPLAY_RW_PIN -1 +#define UI_DISPLAY_ENABLE_PIN 42 +#define UI_DISPLAY_D0_PIN -1 +#define UI_DISPLAY_D1_PIN -1 +#define UI_DISPLAY_D2_PIN -1 +#define UI_DISPLAY_D3_PIN -1 +#define UI_DISPLAY_D4_PIN 18 +#define UI_DISPLAY_D5_PIN 38 +#define UI_DISPLAY_D6_PIN 41 +#define UI_DISPLAY_D7_PIN 40 +#define UI_ENCODER_A 12 +#define UI_ENCODER_B 11 +#define UI_ENCODER_CLICK 43 +#define UI_RESET_PIN 46 + +#elif MOTHERBOARD == 37 // UltiMaker 1.5.7 +#undef BEEPER_PIN +#define BEEPER_PIN 18 +#define UI_DISPLAY_RS_PIN 20 +#define UI_DISPLAY_RW_PIN -1 +#define UI_DISPLAY_ENABLE_PIN 17 +#define UI_DISPLAY_D0_PIN -1 +#define UI_DISPLAY_D1_PIN -1 +#define UI_DISPLAY_D2_PIN -1 +#define UI_DISPLAY_D3_PIN -1 +#define UI_DISPLAY_D4_PIN 16 +#define UI_DISPLAY_D5_PIN 21 +#define UI_DISPLAY_D6_PIN 5 +#define UI_DISPLAY_D7_PIN 6 +#define UI_ENCODER_A 42 +#define UI_ENCODER_B 40 +#define UI_ENCODER_CLICK 19 +#define UI_RESET_PIN -1 + +#elif MOTHERBOARD == 301 // Rambo has own pins layout + +#undef BEEPER_PIN +#define BEEPER_PIN 79 +#define UI_DISPLAY_RS_PIN 70 +#define UI_DISPLAY_RW_PIN -1 +#define UI_DISPLAY_ENABLE_PIN 71 +#define UI_DISPLAY_D0_PIN -1 +#define UI_DISPLAY_D1_PIN -1 +#define UI_DISPLAY_D2_PIN -1 +#define UI_DISPLAY_D3_PIN -1 +#define UI_DISPLAY_D4_PIN 72 +#define UI_DISPLAY_D5_PIN 73 +#define UI_DISPLAY_D6_PIN 74 +#define UI_DISPLAY_D7_PIN 75 +#define UI_ENCODER_A 76 +#define UI_ENCODER_B 77 +#define UI_ENCODER_CLICK 78 +#define UI_RESET_PIN 80 +#undef SDCARDDETECT +#define SDCARDDETECT 81 +#undef SDCARDDETECTINVERTED +#define SDCARDDETECTINVERTED 0 +#undef SDSUPPORT +#define SDSUPPORT 1 + +#elif MOTHERBOARD == 501 // Alligator has own pins layout + +#undef BEEPER_PIN +#define BEEPER_PIN 64 +#define UI_DISPLAY_RS_PIN 18 +#define UI_DISPLAY_ENABLE_PIN 15 +#define UI_DISPLAY_D4_PIN 19 +#define UI_ENCODER_A 14 +#define UI_ENCODER_B 16 +#define UI_ENCODER_CLICK 17 +#define UI_RESET_PIN -1 +#undef SDCARDDETECT +#define SDCARDDETECT 87 +#undef SDCARDDETECTINVERTED +#define SDCARDDETECTINVERTED 0 +#ifndef UI_VOLTAGE_LEVEL +#define UI_VOLTAGE_LEVEL 1 // Set 1=5 o 0=3.3 V +#endif + +#elif MOTHERBOARD == CONTROLLER_FELIX_DUE + +#undef BEEPER_PIN +#define BEEPER_PIN -1 +#define UI_DISPLAY_RS_PIN 42 +#define UI_DISPLAY_ENABLE_PIN 44 +#define UI_DISPLAY_D4_PIN 43 +#define UI_ENCODER_A 52 +#define UI_ENCODER_B 50 +#define UI_ENCODER_CLICK 48 +#define UI_RESET_PIN -1 + +#else // RAMPS +#undef BEEPER_PIN +#define BEEPER_PIN 37 +#define UI_DISPLAY_RS_PIN 16 +#define UI_DISPLAY_RW_PIN -1 +#define UI_DISPLAY_ENABLE_PIN 17 +#define UI_DISPLAY_D0_PIN 23 +#define UI_DISPLAY_D1_PIN 25 +#define UI_DISPLAY_D2_PIN 27 +#define UI_DISPLAY_D3_PIN 29 +#define UI_DISPLAY_D4_PIN 23 +#define UI_DISPLAY_D5_PIN 25 +#define UI_DISPLAY_D6_PIN 27 +#define UI_DISPLAY_D7_PIN 29 +#define UI_ENCODER_A 33 +#define UI_ENCODER_B 31 +#define UI_ENCODER_CLICK 35 +#define UI_RESET_PIN 41 +#endif +#endif // smartcontroller +#define UI_DELAYPERCHAR 50 +#if FEATURE_CONTROLLER == CONTROLLER_BAM_DICE_DUE +#define UI_ENCODER_SPEED 2 +#endif +#ifndef UI_INVERT_MENU_DIRECTION +#define UI_INVERT_MENU_DIRECTION 0 +#endif + +#ifdef UI_MAIN +void uiInitKeys() { + UI_KEYS_INIT_CLICKENCODER_LOW(UI_ENCODER_A, UI_ENCODER_B); // click encoder on pins 47 and 45. Phase is connected with gnd for signals. + UI_KEYS_INIT_BUTTON_LOW(UI_ENCODER_CLICK); // push button, connects gnd to pin +#if UI_RESET_PIN > -1 + UI_KEYS_INIT_BUTTON_LOW(UI_RESET_PIN); // Kill pin +#endif +} +void uiCheckKeys(uint16_t &action) { +#if FEATURE_CONTROLLER == CONTROLLER_BAM_DICE_DUE + UI_KEYS_CLICKENCODER_LOW_REV(UI_ENCODER_B, UI_ENCODER_A); // click encoder on pins 47 and 45. Phase is connected with gnd for signals. +#else + UI_KEYS_CLICKENCODER_LOW_REV(UI_ENCODER_A, UI_ENCODER_B); // click encoder on pins 47 and 45. Phase is connected with gnd for signals. +#endif + UI_KEYS_BUTTON_LOW(UI_ENCODER_CLICK, UI_ACTION_OK); // push button, connects gnd to pin +#if UI_RESET_PIN > -1 + UI_KEYS_BUTTON_LOW(UI_RESET_PIN, UI_ACTION_RESET); +#endif +} +inline void uiCheckSlowEncoder() {} +void uiCheckSlowKeys(uint16_t &action) {} +#endif +#endif // Controller 2 and 10 + +#if FEATURE_CONTROLLER == CONTROLLER_ADAFRUIT +#define UI_HAS_KEYS 1 +#define UI_HAS_BACK_KEY 1 +#define UI_DISPLAY_TYPE DISPLAY_I2C +#define UI_DISPLAY_CHARSET 1 +#define UI_COLS 16 +#define UI_ROWS 2 +#define UI_DISPLAY_I2C_CHIPTYPE 1 +#define UI_DISPLAY_I2C_ADDRESS 0x40 +#define UI_DISPLAY_I2C_OUTPUT_PINS 65504 +#define UI_DISPLAY_I2C_OUTPUT_START_MASK 0 +#define UI_DISPLAY_I2C_PULLUP 31 +#define UI_I2C_CLOCKSPEED 400000L +#define UI_DISPLAY_RS_PIN _BV(15) +#define UI_DISPLAY_RW_PIN _BV(14) +#define UI_DISPLAY_ENABLE_PIN _BV(13) +#define UI_DISPLAY_D0_PIN _BV(12) +#define UI_DISPLAY_D1_PIN _BV(11) +#define UI_DISPLAY_D2_PIN _BV(10) +#define UI_DISPLAY_D3_PIN _BV(9) +#define UI_DISPLAY_D4_PIN _BV(12) +#define UI_DISPLAY_D5_PIN _BV(11) +#define UI_DISPLAY_D6_PIN _BV(10) +#define UI_DISPLAY_D7_PIN _BV(9) +#define UI_INVERT_MENU_DIRECTION 1 +#define UI_HAS_I2C_KEYS +#define UI_HAS_I2C_ENCODER 0 +#define UI_I2C_KEY_ADDRESS 0x40 +#ifdef UI_MAIN +void uiInitKeys() {} +void uiCheckKeys(uint16_t &action) {} +inline void uiCheckSlowEncoder() { + HAL::i2cStartWait(UI_DISPLAY_I2C_ADDRESS + I2C_WRITE); + HAL::i2cWrite(0x12); // GIOA + HAL::i2cStop(); + HAL::i2cStartWait(UI_DISPLAY_I2C_ADDRESS + I2C_READ); + uint16_t keymask = HAL::i2cReadAck(); + keymask = keymask + (HAL::i2cReadNak() << 8); + HAL::i2cStop(); +} +void uiCheckSlowKeys(uint16_t &action) { + HAL::i2cStartWait(UI_DISPLAY_I2C_ADDRESS + I2C_WRITE); + HAL::i2cWrite(0x12); // GPIOA + HAL::i2cStop(); + HAL::i2cStartWait(UI_DISPLAY_I2C_ADDRESS + I2C_READ); + uint16_t keymask = HAL::i2cReadAck(); + keymask = keymask + (HAL::i2cReadNak() << 8); + HAL::i2cStop(); + UI_KEYS_I2C_BUTTON_LOW(4, UI_ACTION_PREVIOUS); // Up button + UI_KEYS_I2C_BUTTON_LOW(8, UI_ACTION_NEXT); // down button + UI_KEYS_I2C_BUTTON_LOW(16, UI_ACTION_BACK); // left button + UI_KEYS_I2C_BUTTON_LOW(2, UI_ACTION_OK); // right button + UI_KEYS_I2C_BUTTON_LOW(1, UI_ACTION_MENU_QUICKSETTINGS); //Select button +} +#endif +#endif // Controller 3 + +#if FEATURE_CONTROLLER == CONTROLLER_FOLTYN +#define UI_HAS_KEYS 1 +#define UI_HAS_BACK_KEY 1 +#define UI_DISPLAY_TYPE DISPLAY_4BIT +#define UI_DISPLAY_CHARSET 2 +#define UI_COLS 20 +#define UI_ROWS 4 +// PINK.1, 88, D_RS +#define UI_DISPLAY_RS_PIN 63 +#define UI_DISPLAY_RW_PIN -1 +// PINK.3, 86, D_E +#define UI_DISPLAY_ENABLE_PIN 65 +// PINF.5, 92, D_D4 +#define UI_DISPLAY_D0_PIN 59 +// PINK.2, 87, D_D5 +#define UI_DISPLAY_D1_PIN 64 +// PINL.5, 40, D_D6 +#define UI_DISPLAY_D2_PIN 44 +// PINK.4, 85, D_D7 +#define UI_DISPLAY_D3_PIN 66 +// PINF.5, 92, D_D4 +#define UI_DISPLAY_D4_PIN 59 +// PINK.2, 87, D_D5 +#define UI_DISPLAY_D5_PIN 64 +// PINL.5, 40, D_D6 +#define UI_DISPLAY_D6_PIN 44 +// PINK.4, 85, D_D7 +#define UI_DISPLAY_D7_PIN 66 +#define UI_DELAYPERCHAR 50 +#define UI_INVERT_MENU_DIRECTION 0 +#ifdef UI_MAIN +void uiInitKeys() { + UI_KEYS_INIT_BUTTON_LOW(4); // push button, connects gnd to pin + UI_KEYS_INIT_BUTTON_LOW(5); + UI_KEYS_INIT_BUTTON_LOW(6); + UI_KEYS_INIT_BUTTON_LOW(11); + UI_KEYS_INIT_BUTTON_LOW(42); +} +void uiCheckKeys(uint16_t &action) { + UI_KEYS_BUTTON_LOW(4, UI_ACTION_OK); // push button, connects gnd to pin + UI_KEYS_BUTTON_LOW(5, UI_ACTION_NEXT); // push button, connects gnd to pin + UI_KEYS_BUTTON_LOW(6, UI_ACTION_PREVIOUS); // push button, connects gnd to pin + UI_KEYS_BUTTON_LOW(11, UI_ACTION_BACK); // push button, connects gnd to pin + UI_KEYS_BUTTON_LOW(42, UI_ACTION_SD_PRINT ); // push button, connects gnd to pin +} +inline void uiCheckSlowEncoder() {} +void uiCheckSlowKeys(uint16_t &action) {} +#endif +#endif // Controller 4 + + +#if FEATURE_CONTROLLER == CONTROLLER_VIKI // Viki Lcd + +// You need to change these 3 button according to the positions +// where you put them into your board! +#define UI_ENCODER_A 7 +#define UI_ENCODER_B 22 +#define UI_RESET_PIN 32 +// Set to -1 if you have not connected that pin +#define SDCARDDETECT 49 +#define SDSS 53 + +#define SDSUPPORT 1 +#define SDCARDDETECTINVERTED 0 + +#define UI_HAS_KEYS 1 +#define UI_HAS_BACK_KEY 1 +#define UI_DISPLAY_TYPE DISPLAY_I2C +#define UI_DISPLAY_CHARSET 1 +#define UI_COLS 20 +#define UI_ROWS 4 +#define UI_DISPLAY_I2C_CHIPTYPE 1 +#define UI_DISPLAY_I2C_ADDRESS 0x40 +#define UI_DISPLAY_I2C_OUTPUT_PINS 0xFFE0 +#define UI_DISPLAY_I2C_OUTPUT_START_MASK 0x01C0 // bits that are high always, for now the 3 viki leds +#define UI_DISPLAY_I2C_PULLUP 0x001F +#define UI_I2C_CLOCKSPEED 100000L // Note with very long cables make this much smaller, for 2ft cables I found 80000 worked ok + +#define UI_DISPLAY_RS_PIN _BV(15) +#define UI_DISPLAY_RW_PIN _BV(14) +#define UI_DISPLAY_ENABLE_PIN _BV(13) +#define UI_DISPLAY_D0_PIN _BV(12) +#define UI_DISPLAY_D1_PIN _BV(11) +#define UI_DISPLAY_D2_PIN _BV(10) +#define UI_DISPLAY_D3_PIN _BV(9) +#define UI_DISPLAY_D4_PIN _BV(12) +#define UI_DISPLAY_D5_PIN _BV(11) +#define UI_DISPLAY_D6_PIN _BV(10) +#define UI_DISPLAY_D7_PIN _BV(9) + + +#undef BEEPER_PIN +#define BEEPER_PIN _BV(5) +#define BEEPER_TYPE 2 +#define BEEPER_ADDRESS UI_DISPLAY_I2C_ADDRESS // I2C address of the chip with the beeper pin +#define UI_I2C_HEATBED_LED _BV(8) +#define UI_I2C_HOTEND_LED _BV(7) +#define UI_I2C_FAN_LED _BV(6) + +#define UI_INVERT_MENU_DIRECTION 0 +#define UI_HAS_I2C_KEYS +#define UI_HAS_I2C_ENCODER 0 +#define UI_I2C_KEY_ADDRESS 0x40 +#ifdef UI_MAIN +void uiInitKeys() { + UI_KEYS_INIT_CLICKENCODER_LOW(UI_ENCODER_A, UI_ENCODER_B); // click encoder on real pins. Phase is connected with gnd for signals. + UI_KEYS_INIT_BUTTON_LOW(UI_RESET_PIN); // Kill pin +} +void uiCheckKeys(uint16_t &action) { + UI_KEYS_CLICKENCODER_LOW_REV(UI_ENCODER_A, UI_ENCODER_B); // click encoder on real pins + UI_KEYS_BUTTON_LOW(UI_RESET_PIN, UI_ACTION_RESET); +} +inline void uiCheckSlowEncoder() { }// not used in Viki +void uiCheckSlowKeys(uint16_t &action) { + HAL::i2cStartWait(UI_DISPLAY_I2C_ADDRESS + I2C_WRITE); + HAL::i2cWrite(0x12); // GPIOA + HAL::i2cStop(); + HAL::i2cStartWait(UI_DISPLAY_I2C_ADDRESS + I2C_READ); + unsigned int keymask = HAL::i2cReadAck(); + keymask = keymask + (HAL::i2cReadNak() << 8); + HAL::i2cStop(); + UI_KEYS_I2C_BUTTON_LOW(4, UI_ACTION_MENU_SDCARD); // Up button + UI_KEYS_I2C_BUTTON_LOW(8, UI_ACTION_MENU_QUICKSETTINGS); // down button + UI_KEYS_I2C_BUTTON_LOW(16, UI_ACTION_BACK); // left button + UI_KEYS_I2C_BUTTON_LOW(2, UI_ACTION_MENU_POSITIONS); // right button + UI_KEYS_I2C_BUTTON_LOW(1, UI_ACTION_OK); //Select button + +} +#endif +#endif // Controller 5 + +#if FEATURE_CONTROLLER == CONTROLLER_MEGATRONIC +#define UI_HAS_KEYS 1 +#define UI_HAS_BACK_KEY 0 +#define UI_DISPLAY_TYPE DISPLAY_4BIT +#define UI_DISPLAY_CHARSET 0 +#define UI_COLS 20 +#define UI_ROWS 2 + +#if MOTHERBOARD==701 // Megatronics v2.0 +#define UI_DISPLAY_RS_PIN 14 +#define UI_DISPLAY_RW_PIN -1 +#define UI_DISPLAY_ENABLE_PIN 15 +#define UI_DISPLAY_D4_PIN 30 +#define UI_DISPLAY_D5_PIN 31 +#define UI_DISPLAY_D6_PIN 32 +#define UI_DISPLAY_D7_PIN 33 +#define UI_ENCODER_A 61 +#define UI_ENCODER_B 59 +#define UI_ENCODER_CLICK 43 + +#define UI_SHIFT_OUT 17 +#define UI_SHIFT_LD 42 +#define UI_SHIFT_CLK 63 + +#else // RAMPS 1.4 +#define UI_DISPLAY_RS_PIN 16 +#define UI_DISPLAY_RW_PIN -1 +#define UI_DISPLAY_ENABLE_PIN 17 +#define UI_DISPLAY_D4_PIN 23 +#define UI_DISPLAY_D5_PIN 25 +#define UI_DISPLAY_D6_PIN 27 +#define UI_DISPLAY_D7_PIN 29 +#define UI_ENCODER_A 64 +#define UI_ENCODER_B 59 +#define UI_ENCODER_CLICK 63 + +#define UI_SHIFT_OUT 40 +#define UI_SHIFT_LD 42 +#define UI_SHIFT_CLK 44 +#endif + +#define UI_DELAYPERCHAR 50 +#define UI_INVERT_MENU_DIRECTION 1 +#ifdef UI_MAIN +void uiInitKeys() { + UI_KEYS_INIT_CLICKENCODER_LOW(UI_ENCODER_A, UI_ENCODER_B); + UI_KEYS_INIT_BUTTON_LOW(UI_ENCODER_CLICK); + + SET_OUTPUT(UI_SHIFT_CLK); + SET_OUTPUT(UI_SHIFT_LD); + SET_INPUT(UI_SHIFT_OUT); + + WRITE(UI_SHIFT_OUT, HIGH); + WRITE(UI_SHIFT_LD, HIGH); +} + +void uiCheckKeys(uint16_t &action) { + UI_KEYS_CLICKENCODER_LOW_REV(UI_ENCODER_A, UI_ENCODER_B); + UI_KEYS_BUTTON_LOW(UI_ENCODER_CLICK, UI_ACTION_OK); +} + +inline void uiCheckSlowEncoder() {} // not used + +void uiCheckSlowKeys(uint16_t &action) { + + WRITE(UI_SHIFT_LD, LOW); + WRITE(UI_SHIFT_LD, HIGH); + + for (int8_t i = 1; i <= 8; i++) { + if (!READ(UI_SHIFT_OUT)) { // pressed button = logical 0 (false) + switch (i) { + case 1: action = UI_ACTION_Z_DOWN; break; // F3 + case 2: action = UI_ACTION_Z_UP; break; // F2 + case 3: action = UI_ACTION_EMERGENCY_STOP; break; // F1 + case 4: action = UI_ACTION_Y_UP; break; // UP + case 5: action = UI_ACTION_X_UP; break; // RIGHT + case 6: action = UI_ACTION_HOME_ALL; break; // MID + case 7: action = UI_ACTION_Y_DOWN; break; // DOWN + case 8: action = UI_ACTION_X_DOWN; break; // LEFT + } + i = 9; // if button detected, exit "for loop" + } + WRITE(UI_SHIFT_CLK, HIGH); + WRITE(UI_SHIFT_CLK, LOW); + } +} +#endif +#endif // Controller 6 +#if FEATURE_CONTROLLER == CONTROLLER_RADDS +#undef SDSS +#define SDSS 10 +#undef SPI_PIN +#define SPI_PIN 77 +#undef SPI_CHAN +#define SPI_CHAN 0 +#define UI_HAS_KEYS 1 +#define UI_HAS_BACK_KEY 1 +#define UI_DISPLAY_TYPE DISPLAY_4BIT +#define UI_DISPLAY_CHARSET 1 +#define BEEPER_TYPE 1 +#define UI_COLS 20 +#define UI_ROWS 4 +#undef BEEPER_PIN +#define BEEPER_PIN 41 +#define UI_DISPLAY_RS_PIN 42 +#define UI_DISPLAY_RW_PIN -1 +#define UI_DISPLAY_ENABLE_PIN 43 +#define UI_DISPLAY_D0_PIN 44 +#define UI_DISPLAY_D1_PIN 45 +#define UI_DISPLAY_D2_PIN 46 +#define UI_DISPLAY_D3_PIN 47 +#define UI_DISPLAY_D4_PIN 44 +#define UI_DISPLAY_D5_PIN 45 +#define UI_DISPLAY_D6_PIN 46 +#define UI_DISPLAY_D7_PIN 47 +#define UI_ENCODER_A 50 +#define UI_ENCODER_B 52 +#define UI_ENCODER_CLICK 48 +#define UI_RESET_PIN -1 +#define UI_DELAYPERCHAR 50 +#define UI_INVERT_MENU_DIRECTION 0 +#define UI_BUTTON_BACK 71 +#ifdef UI_MAIN +void uiInitKeys() { + UI_KEYS_INIT_CLICKENCODER_LOW(UI_ENCODER_A, UI_ENCODER_B); // click encoder on pins 47 and 45. Phase is connected with gnd for signals. + UI_KEYS_INIT_BUTTON_LOW(UI_ENCODER_CLICK); // push button, connects gnd to pin + UI_KEYS_INIT_BUTTON_LOW(UI_BUTTON_BACK); +} +void uiCheckKeys(uint16_t &action) { + UI_KEYS_CLICKENCODER_LOW(UI_ENCODER_A, UI_ENCODER_B); // click encoder on pins 47 and 45. Phase is connected with gnd for signals. + UI_KEYS_BUTTON_LOW(UI_ENCODER_CLICK, UI_ACTION_OK); // push button, connects gnd to pin + UI_KEYS_BUTTON_LOW(UI_BUTTON_BACK, UI_ACTION_BACK); +} +inline void uiCheckSlowEncoder() {} +void uiCheckSlowKeys(uint16_t &action) {} +#endif +#endif // Controller 7 + +#if FEATURE_CONTROLLER == CONTROLLER_PIBOT20X4 || FEATURE_CONTROLLER == CONTROLLER_PIBOT16X2 + +#define UI_HAS_KEYS 1 +#define UI_HAS_BACK_KEY 1 +#define UI_DISPLAY_TYPE DISPLAY_4BIT +#define UI_DISPLAY_CHARSET 1 +#define UI_DELAYPERCHAR 50 +#define UI_INVERT_MENU_DIRECTION 1 +#define BEEPER_SHORT_SEQUENCE 6,2 // Needs longer beep sequence +#define BEEPER_LONG_SEQUENCE 24,8 +#define BEEPER_TYPE 1 +#define BEEPER_TYPE_INVERTING 0 + +#if FEATURE_CONTROLLER == CONTROLLER_PIBOT16X2 +#define UI_COLS 16 +#define UI_ROWS 2 +#else ////20x04 Display +#define UI_COLS 20 +#define UI_ROWS 4 +#endif + +#ifdef PiBot_V_1_4 +#undef BEEPER_PIN +#define BEEPER_PIN 31 +#define UI_DISPLAY_RS_PIN 45 +#define UI_DISPLAY_RW_PIN -1 +#define UI_DISPLAY_ENABLE_PIN 44 +#define UI_DISPLAY_D0_PIN 43 +#define UI_DISPLAY_D1_PIN 42 +#define UI_DISPLAY_D2_PIN 19 +#define UI_DISPLAY_D3_PIN 18 +#define UI_DISPLAY_D4_PIN 43 +#define UI_DISPLAY_D5_PIN 42 +#define UI_DISPLAY_D6_PIN 19 +#define UI_DISPLAY_D7_PIN 18 +#define UI_ENCODER_A 61 +#define UI_ENCODER_B 62 +#define UI_ENCODER_CLICK 63 +#define UI_RESET_PIN 28 +#define UI_DELAYPERCHAR 50 +#define UI_BUTTON_OK 49 +#define UI_BUTTON_NEXT 48 +#define UI_BUTTON_PREVIOUS 47 +#define UI_BUTTON_BACK 46 +#define UI_BUTTON_SD_PRINT 29 +#endif + +#if PiBot_V_1_4==true || PiBot_V_1_6==true +#undef BEEPER_PIN +#define BEEPER_PIN 37 +#define UI_DISPLAY_RS_PIN 16 +#define UI_DISPLAY_RW_PIN -1 +#define UI_DISPLAY_ENABLE_PIN 17 +#define UI_DISPLAY_D0_PIN 23 +#define UI_DISPLAY_D1_PIN 25 +#define UI_DISPLAY_D2_PIN 27 +#define UI_DISPLAY_D3_PIN 29 +#define UI_DISPLAY_D4_PIN 23 +#define UI_DISPLAY_D5_PIN 25 +#define UI_DISPLAY_D6_PIN 27 +#define UI_DISPLAY_D7_PIN 29 +#define UI_ENCODER_A 33 +#define UI_ENCODER_B 31 +#define UI_ENCODER_CLICK 35 +#define UI_RESET_PIN 41 +#define UI_DELAYPERCHAR 50 +#define UI_BUTTON_OK 4 +#define UI_BUTTON_NEXT 6 +#define UI_BUTTON_PREVIOUS 5 +#define UI_BUTTON_BACK 11 +#define UI_BUTTON_SD_PRINT 42 +#endif + +#if PiBot_V_2_0 +#undef BEEPER_PIN +#define BEEPER_PIN 16 +#define UI_DISPLAY_RS_PIN 43 +#define UI_DISPLAY_RW_PIN -1 +#define UI_DISPLAY_ENABLE_PIN 42 +#define UI_DISPLAY_D0_PIN 19 +#define UI_DISPLAY_D1_PIN 18 +#define UI_DISPLAY_D2_PIN 38 +#define UI_DISPLAY_D3_PIN 41 +#define UI_DISPLAY_D4_PIN 19 +#define UI_DISPLAY_D5_PIN 18 +#define UI_DISPLAY_D6_PIN 38 +#define UI_DISPLAY_D7_PIN 41 + +#define UI_ENCODER_A 37 +#define UI_ENCODER_B 36 +// Vick BTN +#define UI_ENCODER_CLICK 69 +// if you want, you can get the CNC Pin used 11 +#define UI_RESET_PIN -1 + +#define UI_DELAYPERCHAR 320 +#define UI_BUTTON_OK 47 +#define UI_BUTTON_NEXT 46 +#define UI_BUTTON_PREVIOUS 45 +#define UI_BUTTON_BACK 44 +// if you want, you can get the CNC Pin used 10 +#define UI_BUTTON_SD_PRINT 70 +#endif + +#ifdef UI_MAIN +void uiInitKeys() { + UI_KEYS_INIT_BUTTON_LOW(UI_BUTTON_OK); // push button, connects gnd to pin + UI_KEYS_INIT_BUTTON_LOW(UI_BUTTON_NEXT); + UI_KEYS_INIT_BUTTON_LOW(UI_BUTTON_PREVIOUS); + UI_KEYS_INIT_BUTTON_LOW(UI_BUTTON_BACK); + UI_KEYS_INIT_BUTTON_LOW(UI_BUTTON_SD_PRINT); +} +void uiCheckKeys(uint16_t &action) { + UI_KEYS_BUTTON_LOW(UI_BUTTON_OK, UI_ACTION_OK); // push button, connects gnd to pin + UI_KEYS_BUTTON_LOW(UI_BUTTON_NEXT, UI_ACTION_NEXT); // push button, connects gnd to pin + UI_KEYS_BUTTON_LOW(UI_BUTTON_PREVIOUS, UI_ACTION_PREVIOUS); // push button, connects gnd to pin + UI_KEYS_BUTTON_LOW(UI_BUTTON_BACK, UI_ACTION_BACK); // push button, connects gnd to pin + UI_KEYS_BUTTON_LOW(UI_BUTTON_SD_PRINT, UI_ACTION_SD_PRINT ); // push button, connects gnd to pin +} +inline void uiCheckSlowEncoder() {} +void uiCheckSlowKeys(uint16_t &action) {} +#endif +#endif + +#if FEATURE_CONTROLLER == CONTROLLER_FELIX +#define UI_HAS_KEYS 1 +#define UI_HAS_BACK_KEY 0 +#define UI_DISPLAY_TYPE DISPLAY_4BIT +#define UI_DISPLAY_CHARSET 1 +#define UI_COLS 20 +#define UI_ROWS 4 +#define UI_ENCODER_SPEED 2 +#undef BEEPER_TYPE +#define BEEPER_TYPE 0 +#undef BEEPER_PIN +#define BEEPER_PIN -1 +#define UI_DISPLAY_RS_PIN 16 +#define UI_DISPLAY_RW_PIN -1 +#define UI_DISPLAY_ENABLE_PIN 17 +#define UI_DISPLAY_D0_PIN -1 +#define UI_DISPLAY_D1_PIN -1 +#define UI_DISPLAY_D2_PIN -1 +#define UI_DISPLAY_D3_PIN -1 +#define UI_DISPLAY_D4_PIN 23 +#define UI_DISPLAY_D5_PIN 25 +#define UI_DISPLAY_D6_PIN 27 +#define UI_DISPLAY_D7_PIN 29 +#define UI_ENCODER_A 35 +#define UI_ENCODER_B 37 +#define UI_ENCODER_CLICK 31 +#define UI_DELAYPERCHAR 50 +#define UI_INVERT_MENU_DIRECTION 0 +#ifdef UI_MAIN +void uiInitKeys() { + UI_KEYS_INIT_CLICKENCODER_LOW(UI_ENCODER_A, UI_ENCODER_B); // click encoder on pins 47 and 45. Phase is connected with gnd for signals. + UI_KEYS_INIT_BUTTON_LOW(UI_ENCODER_CLICK); // push button, connects gnd to pin +} +void uiCheckKeys(uint16_t &action) { + UI_KEYS_CLICKENCODER_LOW_REV(UI_ENCODER_A, UI_ENCODER_B); // click encoder on pins 47 and 45. Phase is connected with gnd for signals. + UI_KEYS_BUTTON_LOW(UI_ENCODER_CLICK, UI_ACTION_OK); // push button, connects gnd to pin +} +inline void uiCheckSlowEncoder() {} +void uiCheckSlowKeys(uint16_t &action) {} +#endif +#endif // Controller 12 + +#if FEATURE_CONTROLLER == CONTROLLER_RAMBO // SeeMeCNC LCD + Rambo +#define UI_HAS_KEYS 1 +#define UI_HAS_BACK_KEY 0 +#define UI_DISPLAY_TYPE DISPLAY_4BIT +#define UI_DISPLAY_CHARSET 1 +#define UI_COLS 20 +#define UI_ROWS 4 +#define BEEPER_TYPE 1 +#undef BEEPER_PIN +#define BEEPER_PIN 79 +#define UI_DISPLAY_RS_PIN 70 +#define UI_DISPLAY_RW_PIN -1 +#define UI_DISPLAY_ENABLE_PIN 71 +#define UI_DISPLAY_D0_PIN -1 +#define UI_DISPLAY_D1_PIN -1 +#define UI_DISPLAY_D2_PIN -1 +#define UI_DISPLAY_D3_PIN -1 +#define UI_DISPLAY_D4_PIN 72 +#define UI_DISPLAY_D5_PIN 73 +#define UI_DISPLAY_D6_PIN 74 +#define UI_DISPLAY_D7_PIN 75 +#define UI_ENCODER_A 76 +#define UI_ENCODER_B 77 +#define UI_ENCODER_CLICK 78 +#define UI_KILL_PIN 80 +#define UI_DELAYPERCHAR 50 +#define UI_INVERT_MENU_DIRECTION 0 +#ifdef UI_MAIN +void uiInitKeys() { + UI_KEYS_INIT_CLICKENCODER_LOW(UI_ENCODER_A, UI_ENCODER_B); + UI_KEYS_INIT_BUTTON_LOW(UI_ENCODER_CLICK); + UI_KEYS_INIT_BUTTON_LOW(UI_KILL_PIN); +} +void uiCheckKeys(uint16_t &action) { + UI_KEYS_CLICKENCODER_LOW_REV(UI_ENCODER_A, UI_ENCODER_B); + UI_KEYS_BUTTON_LOW(UI_ENCODER_CLICK, UI_ACTION_OK); + UI_KEYS_BUTTON_LOW(UI_KILL_PIN, UI_ACTION_KILL); +} +inline void uiCheckSlowEncoder() {} +void uiCheckSlowKeys(uint16_t &action) {} +#endif +#endif // Controller 13 + +#if FEATURE_CONTROLLER == CONTROLLER_OPENHARDWARE_LCD2004 +#define SDSUPPORT 1 +#define SDCARDDETECT -1 +#define UI_HAS_KEYS 1 +#define UI_HAS_BACK_KEY 1 +#define UI_DISPLAY_TYPE DISPLAY_I2C +#define UI_DISPLAY_CHARSET 1 +#define UI_COLS 20 +#define UI_ROWS 4 +#define UI_DISPLAY_I2C_CHIPTYPE 1 +#define UI_DISPLAY_I2C_ADDRESS 0x40 +#define UI_DISPLAY_I2C_OUTPUT_PINS 65504 +#define UI_DISPLAY_I2C_OUTPUT_START_MASK 0 +#define UI_DISPLAY_I2C_PULLUP 31 +#define UI_I2C_CLOCKSPEED 400000L +#define UI_DISPLAY_RS_PIN _BV(15) +#define UI_DISPLAY_RW_PIN _BV(14) +#define UI_DISPLAY_ENABLE_PIN _BV(13) +#define UI_DISPLAY_D0_PIN _BV(12) +#define UI_DISPLAY_D1_PIN _BV(11) +#define UI_DISPLAY_D2_PIN _BV(10) +#define UI_DISPLAY_D3_PIN _BV(9) +#define UI_DISPLAY_D4_PIN _BV(12) +#define UI_DISPLAY_D5_PIN _BV(11) +#define UI_DISPLAY_D6_PIN _BV(10) +#define UI_DISPLAY_D7_PIN _BV(9) +#define UI_INVERT_MENU_DIRECTION false +#define UI_HAS_I2C_KEYS +#define UI_HAS_I2C_ENCODER 0 +#define UI_I2C_KEY_ADDRESS 0x40 + +#ifdef UI_MAIN +void uiInitKeys() {} +void uiCheckKeys(uint16_t &action) {} +inline void uiCheckSlowEncoder() { + HAL::i2cStartWait(UI_DISPLAY_I2C_ADDRESS + I2C_WRITE); + HAL::i2cWrite(0x12); // GIOA + HAL::i2cStop(); + HAL::i2cStartWait(UI_DISPLAY_I2C_ADDRESS + I2C_READ); + uint16_t keymask = HAL::i2cReadAck(); + keymask = keymask + (HAL::i2cReadNak() << 8); + HAL::i2cStop(); +} +void uiCheckSlowKeys(uint16_t &action) { + HAL::i2cStartWait(UI_DISPLAY_I2C_ADDRESS + I2C_WRITE); + HAL::i2cWrite(0x12); // GPIOA + HAL::i2cStop(); + HAL::i2cStartWait(UI_DISPLAY_I2C_ADDRESS + I2C_READ); + uint16_t keymask = HAL::i2cReadAck(); + keymask = keymask + (HAL::i2cReadNak() << 8); + HAL::i2cStop(); + UI_KEYS_I2C_BUTTON_LOW(_BV(4), UI_ACTION_OK); // push button, connects gnd to pin + UI_KEYS_I2C_BUTTON_LOW(_BV(1), UI_ACTION_BACK); // push button, connects gnd to pin + UI_KEYS_I2C_BUTTON_LOW(_BV(0), UI_ACTION_SD_PRINT); // push button, connects gnd to pin + UI_KEYS_I2C_BUTTON_LOW(_BV(3), UI_ACTION_PREVIOUS); // Up button + UI_KEYS_I2C_BUTTON_LOW(_BV(2), UI_ACTION_NEXT); // down button +} +#endif +#endif // Controller 14 + +/* + Sanguinololu + panelolu2 +*/ +#if FEATURE_CONTROLLER == CONTROLLER_SANGUINOLOLU_PANELOLU2 +#define UI_HAS_KEYS 1 +#define UI_HAS_BACK_KEY 0 +#define UI_DISPLAY_TYPE DISPLAY_I2C +#define UI_DISPLAY_CHARSET 2 +#define UI_COLS 20 +#define UI_ROWS 4 +#define UI_INVERT_MENU_DIRECTION 0 + +#define UI_DISPLAY_I2C_CHIPTYPE 1 +#define UI_DISPLAY_I2C_ADDRESS 0x40 +#define UI_DISPLAY_I2C_OUTPUT_PINS 65528 +#define UI_DISPLAY_I2C_OUTPUT_START_MASK 0 +#define UI_DISPLAY_I2C_PULLUP 23 +#define UI_I2C_CLOCKSPEED 100000L +//#define UI_HAS_I2C_KEYS +//#define UI_HAS_I2C_ENCODER 0 +//#define UI_I2C_KEY_ADDRESS UI_DISPLAY_I2C_ADDRESS +#define BEEPER_TYPE 2 +#define BEEPER_TYPE_INVERTING 1 +#define BEEPER_ADDRESS UI_DISPLAY_I2C_ADDRESS +#define COMPILE_I2C_DRIVER + +#define UI_DISPLAY_RS_PIN _BV(15) +#define UI_DISPLAY_RW_PIN _BV(14) +#define UI_DISPLAY_ENABLE_PIN _BV(13) +#define UI_DISPLAY_D0_PIN _BV(12) +#define UI_DISPLAY_D1_PIN _BV(11) +#define UI_DISPLAY_D2_PIN _BV(10) +#define UI_DISPLAY_D3_PIN _BV(9) +#define UI_DISPLAY_D4_PIN _BV(12) +#define UI_DISPLAY_D5_PIN _BV(11) +#define UI_DISPLAY_D6_PIN _BV(10) +#define UI_DISPLAY_D7_PIN _BV(9) +#undef BEEPER_PIN +#define BEEPER_PIN _BV(5) +#define UI_I2C_HEATBED_LED _BV(8) +#define UI_I2C_HOTEND_LED _BV(7) +#define UI_I2C_FAN_LED _BV(6) + +#ifdef UI_MAIN +void uiInitKeys() { + UI_KEYS_INIT_CLICKENCODER_LOW(10, 11); // click encoder on pins 47 and 45. Phase is connected with gnd for signals. + UI_KEYS_INIT_BUTTON_LOW(30); // push button, connects gnd to pin +} + +void uiCheckKeys(uint16_t &action) { + UI_KEYS_CLICKENCODER_LOW_REV(10, 11); // click encoder on pins 47 and 45. Phase is connected with gnd for signals. + UI_KEYS_BUTTON_LOW(30, UI_ACTION_OK); // push button, connects gnd to pin +} + +inline void uiCheckSlowEncoder() {} + +void uiCheckSlowKeys(uint16_t &action) {} +#endif // UI_MAIN +#endif // Controller 15 + +#if FEATURE_CONTROLLER == CONTROLLER_GAMEDUINO2 +#define UI_HAS_KEYS 1 +#define UI_HAS_BACK_KEY 0 +#define UI_DISPLAY_TYPE DISPLAY_GAMEDUINO2 +#define UI_DISPLAY_CHARSET 0 +#define UI_COLS 30 +#define UI_ROWS 4 +#define UI_INVERT_MENU_DIRECTION 0 + +#define BEEPER_TYPE 0 +#define BEEPER_TYPE_INVERTING 0 + +#define UI_DISPLAY_CS 49 // Pin for SPI select on gameduino 2 - depends on board and choice + +#endif // Controller 16 +#if FEATURE_CONTROLLER == CONTROLLER_MIREGLI // Miregli +#define UI_HAS_KEYS 1 +#define UI_HAS_BACK_KEY 1 +#define UI_DISPLAY_CHARSET 1 +#define UI_COLS 20 +#define UI_ROWS 4 +#define UI_KILL_PIN 76 +#define UI_ENCODER_A 80 +#define UI_ENCODER_B 73 +#define UI_ENCODER_CLICK 63 +#define UI_DELAYPERCHAR 50 +#define MIREGLI +#define SDCARDDETECT -1 //53 +#define BEEPER 78 +#define LCD_CONTRAST 62 +#define UI_DISPLAY_TYPE 14 +#define LCD_PIN_BL 15 +#define DOGLCD_A0 38 +#define DOGLCD_CS 14 +#define UI_LCD_WIDTH 128 +#define UI_LCD_HEIGHT 64 +#define U8GLIB_ST7920 + +#define UI_INVERT_MENU_DIRECTION false + +//select font size +#define UI_FONT_6X10 //default font +#ifdef UI_FONT_6X10 +#define UI_FONT_WIDTH 6 +#define UI_FONT_HEIGHT 10 +#define UI_FONT_SMALL_HEIGHT 7 +#define UI_FONT_DEFAULT repetier_6x10 +#define UI_FONT_SMALL repetier_5x7 +#define UI_FONT_SMALL_WIDTH 5 //smaller font for status display +#undef UI_ANIMATION +#define UI_ANIMATION 0 // Animations are too slow +#endif + +#ifdef UI_MAIN +void ui_init_keys() { + UI_KEYS_INIT_CLICKENCODER_LOW(UI_ENCODER_A, UI_ENCODER_B); + UI_KEYS_INIT_BUTTON_LOW(UI_ENCODER_CLICK); + UI_KEYS_INIT_BUTTON_LOW(UI_KILL_PIN); +} +void ui_check_keys(int &action) { + UI_KEYS_CLICKENCODER_LOW_REV(UI_ENCODER_A, UI_ENCODER_B); + UI_KEYS_BUTTON_LOW(UI_ENCODER_CLICK, UI_ACTION_OK); + UI_KEYS_BUTTON_LOW(UI_KILL_PIN, UI_ACTION_KILL); +} +inline void ui_check_slow_encoder() {} +void ui_check_slow_keys(int &action) {} +#endif +#endif // Controller 17 +#if FEATURE_CONTROLLER == CONTROLLER_GATE_3NOVATICA +#define UI_HAS_KEYS 1 +#define UI_HAS_BACK_KEY 0 +#define UI_DISPLAY_TYPE DISPLAY_4BIT +#define UI_DISPLAY_CHARSET 1 +#define UI_COLS 20 +#define UI_ROWS 4 +#define BEEPER_TYPE 1 +#undef BEEPER_PIN +#define BEEPER_PIN -1 +#define UI_DISPLAY_RS_PIN 1 +#define UI_DISPLAY_RW_PIN -1 +#define UI_DISPLAY_ENABLE_PIN 3 +#define UI_DISPLAY_D0_PIN -1 +#define UI_DISPLAY_D1_PIN -1 +#define UI_DISPLAY_D2_PIN -1 +#define UI_DISPLAY_D3_PIN -1 +#define UI_DISPLAY_D4_PIN 0 +#define UI_DISPLAY_D5_PIN 2 +#define UI_DISPLAY_D6_PIN 4 +#define UI_DISPLAY_D7_PIN 6 +#define UI_ENCODER_A 5 +#define UI_ENCODER_B 7 +#define UI_ENCODER_CLICK 39 +#define UI_KILL_PIN -1 +#define UI_DELAYPERCHAR 320 // bylo 50 +#define UI_INVERT_MENU_DIRECTION 1 // bylo 0 +#define USER_KEY1_PIN 36 +#define USER_KEY1_ACTION UI_ACTION_LIGHTS_ONOFF +#define USER_KEY2_PIN 40 +#define USER_KEY2_ACTION UI_ACTION_PREHEAT_ABS +#define USER_KEY3_PIN 41 +#define USER_KEY3_ACTION UI_ACTION_WIZARD_FILAMENTCHANGE +#define USER_KEY4_PIN -1 +#define USER_KEY4_ACTION UI_ACTION_DUMMY + +#ifdef UI_MAIN +void uiInitKeys() { + UI_KEYS_INIT_CLICKENCODER_LOW(UI_ENCODER_A, UI_ENCODER_B); + UI_KEYS_INIT_BUTTON_LOW(UI_ENCODER_CLICK); +} +void uiCheckKeys(uint16_t &action) { + UI_KEYS_CLICKENCODER_LOW_REV(UI_ENCODER_A, UI_ENCODER_B); + UI_KEYS_BUTTON_LOW(UI_ENCODER_CLICK, UI_ACTION_OK); +} +inline void uiCheckSlowEncoder() {} +void uiCheckSlowKeys(uint16_t &action) {} +#endif +#endif // CONTROLLER_GATE_3NOVATICA + +#if FEATURE_CONTROLLER == CONTROLLER_SPARKLCD || FEATURE_CONTROLLER == CONTROLLER_SPARKLCD_ADAPTER +#if MOTHERBOARD != 402 +#error This config only works with RADDS motherboard! +#endif +#define UI_DISPLAY_CHARSET 3 +#define UI_DISPLAY_TYPE 5 +#define U8GLIB_ST7920 // Currently only this display from u8g lib is included. +#define UI_LCD_WIDTH 128 +#define UI_LCD_HEIGHT 64 + +//select font size +#define UI_FONT_6X10 //default font +#define UI_FONT_WIDTH 6 +#define UI_FONT_HEIGHT 10 +#define UI_FONT_SMALL_HEIGHT 7 +#define UI_FONT_DEFAULT repetier_6x10 +#define UI_FONT_SMALL repetier_5x7 +#define UI_FONT_SMALL_WIDTH 5 //smaller font for status display +#undef UI_ANIMATION +#define UI_ANIMATION 0 // Animations are too slow +#define UI_DELAYPERCHAR 50 +#define UI_HAS_KEYS 1 +#define UI_HAS_BACK_KEY 0 +#define UI_INVERT_MENU_DIRECTION 0 +#define UI_HAS_I2C_ENCODER 0 +#define UI_ENCODER_SPEED 2 + +//calculate rows and cols available with current font +#define UI_COLS (UI_LCD_WIDTH/UI_FONT_WIDTH) +#define UI_ROWS (UI_LCD_HEIGHT/UI_FONT_HEIGHT) +#define UI_DISPLAY_D0_PIN -1 +#define UI_DISPLAY_D1_PIN -1 +#define UI_DISPLAY_D2_PIN -1 +#define UI_DISPLAY_D3_PIN -1 +#define UI_DISPLAY_D5_PIN -1 +#define UI_DISPLAY_D6_PIN -1 +#define UI_DISPLAY_D7_PIN -1 + +#if FEATURE_CONTROLLER == CONTROLLER_SPARKLCD +// PINK.1, 88, D_RS +#define UI_DISPLAY_RS_PIN 25 +#define UI_DISPLAY_RW_PIN -1 +// PINK.3, 86, D_E +#define UI_DISPLAY_ENABLE_PIN 27 +// PINF.5, 92, D_D4 +// PINF.5, 92, D_D4 +#define UI_DISPLAY_D4_PIN 29 +#define UI_ENCODER_A 35 +#define UI_ENCODER_B 33 +#define UI_ENCODER_CLICK 37 +#else +// PINK.1, 88, D_RS +#define UI_DISPLAY_RS_PIN 44 +#define UI_DISPLAY_RW_PIN -1 +// PINK.3, 86, D_E +#define UI_DISPLAY_ENABLE_PIN 45 +#define UI_DISPLAY_D4_PIN 46 +#define UI_ENCODER_A 52 +#define UI_ENCODER_B 50 +#define UI_ENCODER_CLICK 48 +#endif + +#ifdef UI_MAIN +void uiInitKeys() { + UI_KEYS_INIT_CLICKENCODER_LOW(UI_ENCODER_A, UI_ENCODER_B); // click encoder on pins 47 and 45. Phase is connected with gnd for signals. + UI_KEYS_INIT_BUTTON_LOW(UI_ENCODER_CLICK); // push button, connects gnd to pin; +} +void uiCheckKeys(uint16_t &action) { + UI_KEYS_CLICKENCODER_LOW(UI_ENCODER_A, UI_ENCODER_B); // click encoder on pins 47 and 45. Phase is connected with gnd for signals. + UI_KEYS_BUTTON_LOW(UI_ENCODER_CLICK, UI_ACTION_OK); // push button, connects gnd to pin +} +inline void uiCheckSlowEncoder() {} +void uiCheckSlowKeys(uint16_t &action) {} +#endif + +#endif // CONTROLLER_sparkLCD + +#if FEATURE_CONTROLLER == CONTROLLER_VIKI2 +#define UI_HAS_KEYS 1 +#define UI_HAS_BACK_KEY 0 +#define UI_DISPLAY_TYPE DISPLAY_U8G +//#define U8GLIB_ST7920 +#define U8GLIB_ST7565_NHD_C2832_HW_SPI +#define UI_LCD_WIDTH 128 +#define UI_LCD_HEIGHT 64 +//select font size +#define UI_FONT_6X10 //default font +#define UI_FONT_WIDTH 6 +#define UI_FONT_HEIGHT 10 +#define UI_FONT_SMALL_HEIGHT 7 +#define UI_FONT_DEFAULT repetier_6x10 +#define UI_FONT_SMALL repetier_5x7 +#define UI_FONT_SMALL_WIDTH 5 //smaller font for status display +#undef UI_ANIMATION +#define UI_ANIMATION 0 // Animations are too slow + +//calculate rows and cols available with current font +#define UI_COLS (UI_LCD_WIDTH/UI_FONT_WIDTH) +#define UI_ROWS (UI_LCD_HEIGHT/UI_FONT_HEIGHT) +#define UI_DISPLAY_CHARSET 3 +#define UI_INVERT_MENU_DIRECTION 0 +#undef UI_ENCODER_SPEED +#define UI_ENCODER_SPEED 2 +#define SDCARDDETECT -1 +#define UI_DISPLAY_RW_PIN -1 +#define UI_ROTATE_180 + +#define BEEPER_TYPE 1 + +// SCK Pin: UI_DISPLAY_D4_PIN +// Mosi Pin: UI_DISPLAY_ENABLE_PIN +// CD Pin: UI_DISPLAY_RS_PIN + +#if MOTHERBOARD == 34 // Azteeg X3 + +#define SDCARDDETECT 49 // sd card detect as shown on drawing +#undef BEEPER_PIN +#define BEEPER_PIN 33 +// Display A0 +#define UI_DISPLAY_D5_PIN 31 +// Display CS +#define UI_DISPLAY_RS_PIN 32 +#define UI_ENCODER_A 22 +#define UI_ENCODER_B 7 +#define UI_ENCODER_CLICK 12 +#define UI_RESET_PIN -1 +#define RED_BLUE_STATUS_LEDS +#define RED_STATUS_LED 64 +#define BLUE_STATUS_LED 63 + +#elif MOTHERBOARD == 35 // Azteeg X3 Pro + +#undef SDCARDDETECT +// sd card detect as shown on drawing +#define SDCARDDETECT 49 +#undef BEEPER_PIN +// 33 is the on board beeper +#define BEEPER_PIN 47 +// Display A0 +#define UI_DISPLAY_D5_PIN 44 +// Display CS +#define UI_DISPLAY_RS_PIN 45 +#define UI_ENCODER_A 22 +#define UI_ENCODER_B 7 +#define UI_ENCODER_CLICK 39 +#define UI_RESET_PIN -1 +#define RED_BLUE_STATUS_LEDS +#define RED_STATUS_LED 32 +#define BLUE_STATUS_LED 35 + +#elif MOTHERBOARD == 301 // RAMBO + +#define SDCARDDETECT 72 // sd card detect as shown on drawing +#undef BEEPER_PIN +#define BEEPER_PIN 33 +// Display A0 +#define UI_DISPLAY_D5_PIN 70 +// Display CS +#define UI_DISPLAY_RS_PIN 71 +#define UI_ENCODER_A 85 +#define UI_ENCODER_B 84 +#define UI_ENCODER_CLICK 83 +#define UI_RESET_PIN -1 +#define RED_BLUE_STATUS_LEDS +#define RED_STATUS_LED 22 +#define BLUE_STATUS_LED 32 + +#elif MOTHERBOARD == 9 || MOTHERBOARD == 92 // Printboard +// sd card detect as shown on drawing +#define SDCARDDETECT 72 +#define SDSS 45 +#undef BEEPER_PIN +#define BEEPER_PIN 32 +// Display A0 +#define UI_DISPLAY_D5_PIN 42 +// Display CS +#define UI_DISPLAY_RS_PIN 43 +#define UI_ENCODER_A 26 +#define UI_ENCODER_B 27 +#define UI_ENCODER_CLICK 47 +#define UI_RESET_PIN -1 +#define RED_BLUE_STATUS_LEDS +#define RED_STATUS_LED 12 +#define BLUE_STATUS_LED 10 + +#elif MOTHERBOARD == 402 // RADDS + +#undef SDCARDDETECT +#define SDCARDDETECT 14 // sd card detect as shown on drawing +//#undef SDSS +//#define SDSS 4 +//#define SPI_PIN 87 +//#define SPI_CHAN 1 +/*#define SDSS 10 + #undef SPI_PIN + #define SPI_PIN 77 + #undef SPI_CHAN + #define SPI_CHAN 0 + + #undef SDSUPPORT + #define SDSUPPORT 0 // sd card does not work reliable due to spi sharing +*/ + +#undef BEEPER_PIN +#define BEEPER_PIN 41 +// Hardware SPI creates artifacts on display, so we use software SPI +#undef U8GLIB_ST7565_NHD_C2832_HW_SPI +#define U8GLIB_ST7565_NHD_C2832_SW_SPI +// MOSI 43 +#define UI_DISPLAY_ENABLE_PIN 31 +//#define UI_DISPLAY_ENABLE_PIN 75 +//76 // SCK pin +#define UI_DISPLAY_D4_PIN 33 //44 +// Display A0 => LCD RS +#define UI_DISPLAY_D5_PIN 42 +// Display CS => CS0 //4 //10 +#define UI_DISPLAY_RS_PIN 35 //10 +#define UI_ENCODER_A 50 +#define UI_ENCODER_B 52 +#define UI_ENCODER_CLICK 48 +#define UI_RESET_PIN -1 +#define RED_BLUE_STATUS_LEDS +// PWM2 Pin +#define RED_STATUS_LED 6 +// PWM1 Pin +#define BLUE_STATUS_LED 5 + +#else +#error No predefined Viki 2 mapping for your board available +#endif + +#ifdef UI_MAIN +void uiInitKeys() { + UI_KEYS_INIT_CLICKENCODER_LOW(UI_ENCODER_A, UI_ENCODER_B); // click encoder on pins 47 and 45. Phase is connected with gnd for signals. + UI_KEYS_INIT_BUTTON_LOW(UI_ENCODER_CLICK); // push button, connects gnd to pin +#if UI_RESET_PIN > -1 + UI_KEYS_INIT_BUTTON_LOW(UI_RESET_PIN); // Kill pin +#endif +} +void uiCheckKeys(uint16_t &action) { + UI_KEYS_CLICKENCODER_LOW_REV(UI_ENCODER_B, UI_ENCODER_A); + UI_KEYS_BUTTON_LOW(UI_ENCODER_CLICK, UI_ACTION_OK); +#if UI_RESET_PIN > -1 + UI_KEYS_BUTTON_LOW(UI_RESET_PIN, UI_ACTION_RESET); +#endif +} +inline void uiCheckSlowEncoder() {} +void uiCheckSlowKeys(uint16_t &action) {} +#endif +#endif // Controller VIKI 2 + +#if FEATURE_CONTROLLER == CONTROLLER_LCD_MP_PHARAOH_DUE +#define UI_DISPLAY_TYPE 1 +#define UI_COLS 20 +#define UI_ROWS 4 +#define UI_HAS_KEYS 1 +#define UI_HAS_BACK_KEY 0 +#define UI_INVERT_MENU_DIRECTION 1 +#define UI_DISPLAY_CHARSET 1 +#define UI_DISPLAY_RS_PIN 42 // PINK.1, 88, D_RS +#define UI_DISPLAY_RW_PIN -1 +#define UI_DISPLAY_ENABLE_PIN 43 // PINK.3, 86, D_E +#define UI_DISPLAY_D0_PIN 44 // PINF.5, 92, D_D4 +#define UI_DISPLAY_D1_PIN 45 // PINK.2, 87, D_D5 +#define UI_DISPLAY_D2_PIN 46 // PINL.5, 40, D_D6 +#define UI_DISPLAY_D3_PIN 47 // PINK.4, 85, D_D7 +#define UI_DISPLAY_D4_PIN 44 // PINF.5, 92, D_D4 +#define UI_DISPLAY_D5_PIN 45 // PINK.2, 87, D_D5 +#define UI_DISPLAY_D6_PIN 46 // PINL.5, 40, D_D6 +#define UI_DISPLAY_D7_PIN 47 // PINK.4, 85, D_D7 +#define UI_DELAYPERCHAR 50 + +#ifdef UI_MAIN +void uiInitKeys() { + UI_KEYS_INIT_BUTTON_LOW(33); // push button, connects gnd to pin + UI_KEYS_INIT_BUTTON_LOW(31); + UI_KEYS_INIT_BUTTON_LOW(29); + UI_KEYS_INIT_BUTTON_LOW(37); + UI_KEYS_INIT_BUTTON_LOW(35); + UI_KEYS_INIT_BUTTON_LOW(X_MIN_PIN); +} +void uiCheckKeys(uint16_t &action) { + UI_KEYS_BUTTON_LOW(33, UI_ACTION_OK); //35 push button, connects gnd to pin + UI_KEYS_BUTTON_LOW(35, UI_ACTION_PREVIOUS); //34 push button, connects gnd to pin + UI_KEYS_BUTTON_LOW(31, UI_ACTION_NEXT); //43 push button, connects gnd to pin + UI_KEYS_BUTTON_LOW(29, UI_ACTION_BACK); //44 push button, connects gnd to pin + UI_KEYS_BUTTON_LOW(37, UI_ACTION_MENU_SDCARD ); //33 push button, connects gnd to pin + UI_KEYS_BUTTON_LOW(X_MIN_PIN, UI_ACTION_RESET /*UI_ACTION_PAUSE*/); +} +inline void uiCheckSlowEncoder() {} +void uiCheckSlowKeys(uint16_t &action) {} + +#endif +#endif // CONTROLLER_LCD_MP_PHARAOH_DUE + +#if FEATURE_CONTROLLER == CONTROLLER_ZONESTAR + +// Keypad +#if !defined(ADC_KEYPAD_PIN) || (ADC_KEYPAD_PIN < 0) +#error CONTROLLER_ZONESTAR requres ADC_KEYPAD_PIN = 1 defined in Configuration.h +#endif + +// This must be defined in the Configuration.h since used in ADC tables +//#define ADC_KEYPAD_PIN 1 // A1 (D30, analog numbering) + +// Display +#define UI_DISPLAY_TYPE DISPLAY_4BIT +#define UI_DISPLAY_CHARSET 1 +#define UI_COLS 20 +#define UI_ROWS 4 + +#define UI_DISPLAY_ENABLE_PIN 29 // A2 +#define UI_DISPLAY_RS_PIN 28 // A3 +#define UI_DISPLAY_RW_PIN -1 +#define UI_DISPLAY_D4_PIN 10 +#define UI_DISPLAY_D5_PIN 11 +#define UI_DISPLAY_D6_PIN 16 +#define UI_DISPLAY_D7_PIN 17 + +// UI +#define UI_HAS_KEYS 1 +#define UI_HAS_BACK_KEY 1 +#define UI_DELAYPERCHAR 50 +#define UI_INVERT_MENU_DIRECTION 1 + +// Opportunity to override the Enter key via Configuration.h +// By default it duplicates the Right key, but could be set to +// anything else, e.g. UI_ACTION_TOP_MENU. +#ifndef ADC_KEYPAD_CENTER_ACTION +#define ADC_KEYPAD_CENTER_ACTION UI_ACTION_OK +#endif + +#ifdef UI_MAIN +// Nothing to init since ADC is read in a loop if ADC_KEYPAD_PIN > -1 +inline void uiInitKeys() {} + +// Read and decode ADC keypad (fast reads) +void uiCheckKeys(uint16_t &action) { + struct { + uint16_t min; + uint16_t max; + uint16_t action; + } keys[] = { + { 300, 500, UI_ACTION_BACK }, // Left + { 570, 870, UI_ACTION_PREVIOUS }, // Up + { 1150, 1450, ADC_KEYPAD_CENTER_ACTION }, // Center + { 1900, 2200, UI_ACTION_OK }, // Right + { 2670, 2870, UI_ACTION_NEXT } // Down + }; + const uint8_t numOfKeys = sizeof(keys) / sizeof(keys[0]); + + extern volatile uint16_t osAnalogInputValues[ANALOG_INPUTS]; + uint16_t adc = osAnalogInputValues[KEYPAD_ANALOG_INDEX] >> (ANALOG_REDUCE_BITS); + if (adc < 4000) { + for (int8_t i = 0; i < numOfKeys; ++i) { + if ((adc > keys[i].min) && (adc < keys[i].max)) { + action = keys[i].action; + return; + } + } + } +} + +// Read and decode ADC keypad (slow reads) +inline void uiCheckSlowKeys(uint16_t &action) {} +#endif // UI_MAIN + +#endif // CONTROLLER_ZONESTAR + +#ifndef UI_HAS_I2C_ENCODER +#define UI_HAS_I2C_ENCODER 0 +#endif + +#if FEATURE_CONTROLLER != NO_CONTROLLER +#if UI_ROWS==4 +#if UI_COLS==16 +#define UI_LINE_OFFSETS {0,0x40,0x10,0x50} // 4x16 +#elif UI_COLS==20 +//#define UI_LINE_OFFSETS {0,0x20,0x40,0x60} // 4x20 with KS0073 +#define UI_LINE_OFFSETS {0,0x40,0x14,0x54} // 4x20 with HD44780 +#else +#if UI_DISPLAY_TYPE!=DISPLAY_GAMEDUINO2 +#error Unknown combination off rows/columns - define UI_LINE_OFFSETS manually. +#else +#define UI_LINE_OFFSETS {} // dummy never used +#endif +#endif +#else +#define UI_LINE_OFFSETS {0,0x40,0x10,0x50} // 2x16, 2x20, 2x24 +#endif +#include "uilang.h" +#endif + +#define UI_VERSION_STRING "Repetier " REPETIER_VERSION + +#ifdef UI_HAS_I2C_KEYS +#define COMPILE_I2C_DRIVER +#endif + +#if UI_DISPLAY_TYPE != NO_DISPLAY + + +#if UI_DISPLAY_TYPE == DISPLAY_I2C +#define COMPILE_I2C_DRIVER +#endif + +#ifndef UI_TEMP_PRECISION +#if UI_COLS>16 +#define UI_TEMP_PRECISION 1 +#else +#define UI_TEMP_PRECISION 0 +#endif +#endif + +#define UI_INITIALIZE uid.initialize(); +#define UI_FAST if((counterPeriodical & 3) == 3) {uid.fastAction();} +#define UI_MEDIUM uid.mediumAction(); +#define UI_SLOW(allowMoves) uid.slowAction(allowMoves); +#define UI_STATUS(status) uid.setStatusP(PSTR(status)); +#define UI_STATUS_F(status) uid.setStatusP(status); +#define UI_STATUS_UPD(status) {uid.setStatusP(PSTR(status));uid.refreshPage();} +#define UI_STATUS_UPD_F(status) {uid.setStatusP(status);uid.refreshPage();} +#define UI_STATUS_RAM(status) uid.setStatus(status); +#define UI_STATUS_UPD_RAM(status) {uid.setStatus(status);uid.refreshPage();} +#define UI_ERROR(status) uid.setStatusP(PSTR(status),true); +#define UI_ERROR_P(status) uid.setStatusP(status,true); +#define UI_ERROR_UPD(status) {uid.setStatusP(PSTR(status),true);uid.refreshPage();} +#define UI_ERROR_RAM(status) uid.setStatus(status,true); +#define UI_ERROR_UPD_RAM(status) {uid.setStatus(status,true);uid.refreshPage();} +//#define UI_ERROR(msg) {uid.errorMsg=(void*)PSTR(msg);pushMenu((void*)&ui_menu_error,true);} +#define UI_CLEAR_STATUS {uid.statusMsg[0]=0;} +#else +#define UI_INITIALIZE {} +#define UI_FAST {} +#define UI_MEDIUM {} +#define UI_SLOW(allowMoves) {} +#define UI_STATUS(status) {} +#define UI_STATUS_F(status) {} +#define UI_STATUS_RAM(status) {} +#define UI_STATUS_UPD(status) {} +#define UI_STATUS_UPD_F(status) {} +#define UI_STATUS_UPD_RAM(status) {} +#define UI_CLEAR_STATUS {} +#define UI_ERROR(msg) {} +#define UI_ERROR_P(status) {} +#define UI_ERROR_UPD(status) {} +#define UI_ERROR_RAM(status) {} +#define UI_ERROR_UPD_RAM(status) {} +#endif // Display + +// Beeper methods +#if BEEPER_TYPE==0 + #define BEEP_SHORT {} + #define BEEP_LONG {} +#else + #define BEEP_SHORT beep(BEEPER_SHORT_SEQUENCE); + #define BEEP_LONG beep(BEEPER_LONG_SEQUENCE); +#endif + + +extern void beep(uint8_t duration, uint8_t count); +#if (defined(USER_KEY1_PIN) && USER_KEY1_PIN > -1 && defined(USER_KEY1_ACTION)) || (defined(USER_KEY2_PIN) && USER_KEY2_PIN > -1 && defined(USER_KEY2_ACTION)) || (defined(USER_KEY3_PIN) && USER_KEY3_PIN > -1 && defined(USER_KEY3_ACTION)) || (defined(USER_KEY4_PIN) && USER_KEY4_PIN > -1 && defined(USER_KEY4_ACTION)) +#define HAS_USER_KEYS +static void ui_check_Ukeys(uint16_t &action) { +#if defined(USER_KEY1_PIN) && USER_KEY1_PIN > -1 && defined(USER_KEY1_ACTION) + UI_KEYS_BUTTON_LOW(USER_KEY1_PIN, USER_KEY1_ACTION); +#endif +#if defined(USER_KEY2_PIN) && USER_KEY2_PIN > -1 && defined(USER_KEY2_ACTION) + UI_KEYS_BUTTON_LOW(USER_KEY2_PIN, USER_KEY2_ACTION); +#endif +#if defined(USER_KEY3_PIN) && USER_KEY3_PIN > -1 && defined(USER_KEY3_ACTION) + UI_KEYS_BUTTON_LOW(USER_KEY3_PIN, USER_KEY3_ACTION); +#endif +#if defined(USER_KEY4_PIN) && USER_KEY4_PIN > -1 && defined(USER_KEY4_ACTION) + UI_KEYS_BUTTON_LOW(USER_KEY4_PIN, USER_KEY4_ACTION); +#endif +} +#endif + +#endif + diff --git a/trunk/Arduino/Repetier_0.92.9/uiconfig.h b/trunk/Arduino/Repetier_0.92.9/uiconfig.h new file mode 100644 index 00000000..21c975cb --- /dev/null +++ b/trunk/Arduino/Repetier_0.92.9/uiconfig.h @@ -0,0 +1,455 @@ +/* + This file is part of Repetier-Firmware. + + Repetier-Firmware is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Repetier-Firmware is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Repetier-Firmware. If not, see . + +*/ + +/* ===================== IMPORTANT ======================== + +The LCD and Key support is new. I tested everything as good as possible, +but some combinations may not work as supposed. +The I2C methods rely on a stable I2C connection. Noise may cause wrong signals +which can cause the firmware to freeze. + +The ui adds quite some code, so AVRs with 64kB ram (Sanguino, Gen6) can not handle all features +of the firmware at the same time. You have to disable some features to gain the +ram needed. What should work: +- No sd card - the sd card code is quite large. +- No keys attached - The longest part is the menu handling. +- EEPROM_MODE 0 . + +Currently supported hardware: + +*** Displays *** + +- direct connected lcd with 4 data lines +- connected via i2c + +*** Keys *** + +- rotary encoder +- push button +- key matrix up to 4x4 +- rotary encoder via i2c (only slow turns are captured correct) +- push button via i2c + +*** Buzzer *** + +- directly connected, high = on +- connected via i2c, low = on + +==============================================================*/ + +#ifndef _ui_config_h +#define _ui_config_h + +/** While the ascii chars are all the same, the driver have different charsets +for special chars used in different countries. The charset allows to fix for +this problem. If characters look wrong, try a different charset. If nothing +works, use the ascii charset 0 as fallback. Not the nicest for everything but working! + +0 = ASCII fallback +1 = Default works on most displays. This has some japanese chars in charset +2 = Alternative charset with more european chars + +*/ +#define UI_DISPLAY_CHARSET 2 + +/** Select type of beeper +0 = none +1 = Piezo connected to pin +2 = Piezo connected to a pin over I2C +*/ +#ifndef BEEPER_TYPE +#define BEEPER_TYPE 1 +#define BEEPER_TYPE_INVERTING false +#endif + +#if BEEPER_TYPE==1 && !defined(BEEPER_PIN) +#define BEEPER_PIN 37 +#endif +#if BEEPER_TYPE==2 +#define BEEPER_ADDRESS 0x40 // I2C address of the chip with the beeper pin +#define BEEPER_PIN _BV(7) // Bit value for pin 8 +#define COMPILE_I2C_DRIVER // We need the I2C driver as we are using i2c +#endif + + +/** +What display type do you use? +0 = No display - do not use here. Set FEATURE_CONTROLLER 0 instead +1 = LCD Display with 4 bit data bus +2 = LCD Display with 8 bit data bus (currently not implemented, fallback to 1) +3 = LCD Display with I2C connection, 4 bit mode +4 = Use the slower LiquiedCrystal library bundled with arduino. + IMPORTANT: You need to uncomment the LiquidCrystal include in Repetier.pde for it to work. + If you have Sanguino and want to use the library, you need to have Arduino 023 or older. (13.04.2012) +5 = U8G supported display +*/ +#define UI_DISPLAY_TYPE 5 + +#if UI_DISPLAY_TYPE == DISPLAY_U8G // Special case for graphic displays + +// You need to define which controller you use and set pins accodringly + +// For software spi assign these definitions +// SCK Pin: UI_DISPLAY_D4_PIN +// Mosi Pin: UI_DISPLAY_ENABLE_PIN +// CD Pin: UI_DISPLAY_RS_PIN + +// ST7920 with software SPI +#define U8GLIB_ST7920 +// SSD1306 with software SPI +//#define U8GLIB_SSD1306_SW_SPI +// SH1106 with software SPI +// U8GLIB_SH1106_SW_SPI +// SSD1306 over I2C using hardware I2C pins +//#define U8GLIB_SSD1306_I2C +// For the 8 bit ks0108 display you need to set these pins +// UI_DISPLAY_D0_PIN,UI_DISPLAY_D1_PIN,UI_DISPLAY_D2_PIN,UI_DISPLAY_D3_PIN,UI_DISPLAY_D4_PIN,UI_DISPLAY_D5_PIN,UI_DISPLAY_D6_PIN,UI_DISPLAY_D7_PIN +// UI_DISPLAY_ENABLE_PIN,UI_DISPLAY_CS1,UI_DISPLAY_CS2, +// UI_DISPLAY_DI,UI_DISPLAY_RW_PIN,UI_DISPLAY_RESET_PIN +//#define U8GLIB_KS0108 +//#define U8GLIB_KS0108_FAST +// UI_DISPLAY_RS_PIN = CS +// UI_DISPLAY_D5_PIN = A0 +//#define U8GLIB_ST7565_NHD_C2832_HW_SPI + +#define UI_LCD_WIDTH 128 +#define UI_LCD_HEIGHT 64 + +//select font size +#define UI_FONT_6X10 //default font +#ifdef UI_FONT_6X10 +#define UI_FONT_WIDTH 6 +#define UI_FONT_HEIGHT 10 +#define UI_FONT_SMALL_HEIGHT 7 +#define UI_FONT_DEFAULT repetier_6x10 +#define UI_FONT_SMALL repetier_5x7 +#define UI_FONT_SMALL_WIDTH 5 //smaller font for status display +#define UI_ANIMATION false // Animations are too slow +#endif + +//calculate rows and cols available with current font +#define UI_COLS (UI_LCD_WIDTH/UI_FONT_WIDTH) +#define UI_ROWS (UI_LCD_HEIGHT/UI_FONT_HEIGHT) +#define UI_DISPLAY_CHARSET 3 +#else +/** Number of columns per row +Typical values are 16 and 20 +*/ +#define UI_COLS 20 +/** +Rows of your display. 2 or 4 +*/ +#define UI_ROWS 4 +#endif // UI_DISPLAY_TYPE + +/* What type of chip is used for I2C communication +0 : PCF8574 or PCF8574A or compatible chips. +1 : MCP23017 +*/ +#define UI_DISPLAY_I2C_CHIPTYPE 0 +// 0x40 till 0x4e for PCF8574, 0x40 for the adafruid RGB shield, 0x40 - 0x4e for MCP23017 +// Official addresses have a value half as high! +#define UI_DISPLAY_I2C_ADDRESS 0x4e +// For MCP 23017 define which pins should be output +#define UI_DISPLAY_I2C_OUTPUT_PINS 65504 +// Set the output mask that is or'd over the output data. This is needed to activate +// a backlight switched over the I2C. +// The adafruit RGB shields enables a light if the bit is not set. Bits 6-8 are used for backlight. +#define UI_DISPLAY_I2C_OUTPUT_START_MASK 0 +// For MCP which inputs are with pullup. 31 = pins 0-4 for adafruid rgb shield buttons +#define UI_DISPLAY_I2C_PULLUP 31 +/* How fast should the I2C clock go. The PCF8574 work only with the lowest setting 100000. +A MCP23017 can run also with 400000 Hz */ +#define UI_I2C_CLOCKSPEED 100000L +/** +Define the pin +*/ +#if UI_DISPLAY_TYPE == DISPLAY_I2C // I2C Pin configuration +#define UI_DISPLAY_RS_PIN _BV(4) +#define UI_DISPLAY_RW_PIN _BV(5) +#define UI_DISPLAY_ENABLE_PIN _BV(6) +#define UI_DISPLAY_D0_PIN _BV(0) +#define UI_DISPLAY_D1_PIN _BV(1) +#define UI_DISPLAY_D2_PIN _BV(2) +#define UI_DISPLAY_D3_PIN _BV(3) +#define UI_DISPLAY_D4_PIN _BV(0) +#define UI_DISPLAY_D5_PIN _BV(1) +#define UI_DISPLAY_D6_PIN _BV(2) +#define UI_DISPLAY_D7_PIN _BV(3) + +// uncomment if your using led to indicated the bed is hot +//#define UI_I2C_HEATBED_LED _BV(8) + +// uncomment if your using led to indicated the extruder is hot +//#define UI_I2C_HOTEND_LED _BV(7) + +// uncomment if your using led to indicated the FAN is on +//#define UI_I2C_FAN_LED _BV(6) + +// Pins for adafruid RGB shield +/*#define UI_DISPLAY_RS_PIN _BV(15) +#define UI_DISPLAY_RW_PIN _BV(14) +#define UI_DISPLAY_ENABLE_PIN _BV(13) +#define UI_DISPLAY_D0_PIN _BV(12) +#define UI_DISPLAY_D1_PIN _BV(11) +#define UI_DISPLAY_D2_PIN _BV(10) +#define UI_DISPLAY_D3_PIN _BV(9) +#define UI_DISPLAY_D4_PIN _BV(12) +#define UI_DISPLAY_D5_PIN _BV(11) +#define UI_DISPLAY_D6_PIN _BV(10) +#define UI_DISPLAY_D7_PIN _BV(9)*/ + +#else // Direct display connections +#define UI_DISPLAY_RS_PIN 63 // PINK.1, 88, D_RS +#define UI_DISPLAY_RW_PIN -1 +#define UI_DISPLAY_ENABLE_PIN 65 // PINK.3, 86, D_E +#define UI_DISPLAY_D0_PIN 59 // PINF.5, 92, D_D4 +#define UI_DISPLAY_D1_PIN 64 // PINK.2, 87, D_D5 +#define UI_DISPLAY_D2_PIN 44 // PINL.5, 40, D_D6 +#define UI_DISPLAY_D3_PIN 66 // PINK.4, 85, D_D7 +#define UI_DISPLAY_D4_PIN 59 // PINF.5, 92, D_D4 +#define UI_DISPLAY_D5_PIN 64 // PINK.2, 87, D_D5 +#define UI_DISPLAY_D6_PIN 44 // PINL.5, 40, D_D6 +#define UI_DISPLAY_D7_PIN 66 // PINK.4, 85, D_D7 +#define UI_DELAYPERCHAR 50 + +// Special pins for some u8g driven display + +#define UI_DISPLAY_CS1 59 +#define UI_DISPLAY_CS2 59 +#define UI_DISPLAY_DI 59 +#define UI_DISPLAY_RW_PIN 59 +#define UI_DISPLAY_RESET_PIN 59 +#endif + + +/** \brief Are some keys connected? + +0 = No keys attached - disables also menu +1 = Some keys attached +*/ +#define UI_HAS_KEYS 0 + + +/** \brief Is a back key present. + +If you have menus enabled, you need a method to leave it. If you have a back key, you can always go one level higher. +Without a back key, you need to navigate to the back entry in the menu. Setting this value to 1 removes the back entry. +*/ +#define UI_HAS_BACK_KEY 1 + +/* Then you have the next/previous keys more like up/down keys, it may be more intuitive to change the direction you skip through the menus. +If you set it to true, next will go to previous menu instead of the next menu. + +*/ +#define UI_INVERT_MENU_DIRECTION 0 + +/** Uncomment this, if you have keys connected via i2c to a PCF8574 chip. */ +//#define UI_HAS_I2C_KEYS + +// Do you have a I2C connected encoder? +#define UI_HAS_I2C_ENCODER 0 + +// Under which address can the key status requested. This is the address of your PCF8574 where the keys are connected. +// If you use a MCP23017 the address from display is used also for keys. +#define UI_I2C_KEY_ADDRESS 0x40 + + +#ifdef UI_MAIN +/* ####################################################################### + Key definitions + +The firmware is very flexible regarding your input methods. You can use one +or more of the predefined key macros, to define a mapper. If no matching mapper +is available, you can add you c-code for mapping directly into the keyboard +routines. The predefined macros do the same, just hiding the code behind it. + +For each key, two seperate parts must be defined. The first is the initialization +which must be added inside uiInitKeys() and the second ist a testing routine. +These come into uiCheckKeys() or uiCheckSlowKeys() depending on the time needed +for testing. If you are in doubt, put it in uiCheckSlowKeys(). +uiInitKeys() is called from an interrupt controlling the extruder, so only +fast tests should be put there. +The detect methods need an action identifier. A list of supported ids is found +at the beginning of ui.h It's best to use the symbol name, in case the value changes. + +1. Simple push button connected to gnd if closed on a free arduino pin + init -> UI_KEYS_INIT_BUTTON_LOW(pinNumber); + detect -> UI_KEYS_BUTTON_LOW(pinNumber,action); + +2. Simple push button connected to 5v if closed on a free arduino pin + init -> UI_KEYS_INIT_BUTTON_HIGH(pinNumber); + detect -> UI_KEYS_BUTTON_HIGH(pinNumber,action); + +3. Click encoder, A/B connected to gnd if closed. + init -> UI_KEYS_INIT_CLICKENCODER_LOW(pinA,pinB); + detect -> UI_KEYS_CLICKENCODER_LOW(pinA,pinB); + or UI_KEYS_CLICKENCODER_LOW_REV(pinA,pinB); // reverse direction + If you can move the menu cursor without a click, just be adding some force in one direction, + toggle the _REV with non _REV and toggle pins. + If the direction is wrong, toggle _REV with non _REV version. + For the push button of the encoder use 1. + +4. Click encoder, A/B connected to 5V if closed. + init -> UI_KEYS_INIT_CLICKENCODER_HIGH(pinA,pinB); + detect -> UI_KEYS_CLICKENCODER_HIGH(pinA,pinB); + or UI_KEYS_CLICKENCODER_HIGH_REV(pinA,pinB); // reverse direction + If you can move the menu cursor without a click, just be adding some force in one direction, + toggle the _REV with non _REV and toggle pins. + If the direction is wrong, toggle _REV with non _REV version. + For the push button of the encoder use 2. + +5. Maxtrix keyboard with 1-4 rows and 1-4 columns. + init -> UI_KEYS_INIT_MATRIX(r1,r2,r3,r4,c1,c2,c3,c4); + detect -> UI_KEYS_MATRIX(r1,r2,r3,r4,c1,c2,c3,c4); + In addition you have to set UI_MATRIX_ACTIONS to match your desired actions. + +------- Keys connected via I2C ------------- + +All keys and the buzzer if present must be on a connected to a single PCF8574 chip! +As all I2C request take time, they belong all in uiCheckSlowKeys. +Dont use the pin ids but instead _BV(pinNumber0_7) as pin id. 0 = First pin + +6. Click encoder, A/B connected to gnd if closed. + init -> not needed, but make sure UI_HAS_I2C_KEY is not commented out. + detect -> UI_KEYS_I2C_CLICKENCODER_LOW(pinA,pinB); + or UI_KEYS_I2C_CLICKENCODER_LOW_REV(pinA,pinB); // reverse direction + If you can move the menu cursor without a click, just be adding some force in one direction, + toggle the _REV with non _REV and toggle pins. + If the direction is wrong, toggle _REV with non _REV version. + For the push button of the encoder use 7. + NOTICE: The polling frequency is limited, so only slow turns are captured correct! + +7. Simple push button connected to gnd if closed via I2C on a PCF8574 + init -> not needed, but make sure UI_HAS_I2C_KEY is not commented out. + detect -> UI_KEYS_I2C_BUTTON_LOW(pinNumber,action); + +-------- Some notes on actions ------------- + +There are three kinds of actions. + +Type 1: Immediate actions - these are execute and forget actions like home/pre-heat +Type 2: Parameter change action - these change the mode for next/previous keys. They are valid + until a new change action is initiated or the action is finished with ok button. +Type 3: Show menu action. These actions have a _MENU_ in their name. If they are executed, a new + menu is pushed on the menu stack and you see the menu. If you assign these actions directly + to a key, you might not want this pushing behaviour. In this case add UI_ACTION_TOPMENU to the + action, like UI_ACTION_TOPMENU+UI_ACTION_MENU_XPOSFAST. That will show the menu as top-menu + closing all othe submenus that were open. + + ####################################################################### */ + +// Use these codes for key detect. The main menu will show the pressed action in the lcd display. +// after that assign the desired codes. +//#define UI_MATRIX_ACTIONS {2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015} +// Define your matrix actions +#define UI_MATRIX_ACTIONS {UI_ACTION_HOME_ALL, UI_ACTION_TOP_MENU, UI_ACTION_SET_ORIGIN, UI_ACTION_NEXT,\ + UI_ACTION_HOME_Z, UI_ACTION_MENU_ZPOS, UI_ACTION_COOLDOWN, UI_ACTION_OK,\ + UI_ACTION_HOME_Y, UI_ACTION_MENU_YPOSFAST, UI_ACTION_PREHEAT_ABS, UI_ACTION_PREVIOUS,\ + UI_ACTION_HOME_X, UI_ACTION_MENU_XPOSFAST, UI_ACTION_DISABLE_STEPPER, UI_ACTION_BACK} +#ifdef UI_MATRIX_ACTIONS +const int matrixActions[] PROGMEM = UI_MATRIX_ACTIONS; +#endif + +void uiInitKeys() { +#if UI_HAS_KEYS!=0 + //UI_KEYS_INIT_CLICKENCODER_LOW(33,31); // click encoder on pins 47 and 45. Phase is connected with gnd for signals. + UI_KEYS_INIT_BUTTON_LOW(4); // push button, connects gnd to pin + UI_KEYS_INIT_BUTTON_LOW(5); + UI_KEYS_INIT_BUTTON_LOW(6); + UI_KEYS_INIT_BUTTON_LOW(11); + UI_KEYS_INIT_BUTTON_LOW(42); + +// UI_KEYS_INIT_CLICKENCODER_LOW(47,45); // click encoder on pins 47 and 45. Phase is connected with gnd for signals. +// UI_KEYS_INIT_BUTTON_LOW(43); // push button, connects gnd to pin +// UI_KEYS_INIT_MATRIX(32,47,45,43,41,39,37,35); +#endif +} +void uiCheckKeys(uint16_t &action) { +#if UI_HAS_KEYS!=0 + + //UI_KEYS_CLICKENCODER_LOW_REV(33,31); // click encoder on pins 47 and 45. Phase is connected with gnd for signals. + UI_KEYS_BUTTON_LOW(4,UI_ACTION_OK); // push button, connects gnd to pin + UI_KEYS_BUTTON_LOW(5,UI_ACTION_NEXT); // push button, connects gnd to pin + UI_KEYS_BUTTON_LOW(6,UI_ACTION_PREVIOUS); // push button, connects gnd to pin + UI_KEYS_BUTTON_LOW(11,UI_ACTION_BACK); // push button, connects gnd to pin + UI_KEYS_BUTTON_LOW(42,UI_ACTION_SD_PRINT ); // push button, connects gnd to pin +// UI_KEYS_CLICKENCODER_LOW_REV(47,45); // click encoder on pins 47 and 45. Phase is connected with gnd for signals. +// UI_KEYS_BUTTON_LOW(43,UI_ACTION_OK); // push button, connects gnd to pin +#endif +} +inline void uiCheckSlowEncoder() { +#if defined(UI_HAS_I2C_KEYS) && UI_HAS_KEYS!=0 +#if UI_DISPLAY_I2C_CHIPTYPE==0 + HAL::i2cStartWait(UI_I2C_KEY_ADDRESS+I2C_READ); + uint8_t keymask = HAL::i2cReadNak(); // Read current key mask +#endif +#if UI_DISPLAY_I2C_CHIPTYPE==1 + HAL::i2cStartWait(UI_DISPLAY_I2C_ADDRESS+I2C_WRITE); + HAL::i2cWrite(0x12); // GIOA + HAL::i2cStop(); + HAL::i2cStartWait(UI_DISPLAY_I2C_ADDRESS+I2C_READ); + uint16_t keymask = HAL::i2cReadAck(); + keymask = keymask + (HAL::i2cReadNak()<<8); +#endif + HAL::i2cStop(); + // Add I2C click encoder tests here, all other i2c tests and a copy of the encoder test belog in uiCheckSlowKeys + UI_KEYS_I2C_CLICKENCODER_LOW_REV(_BV(2),_BV(0)); // click encoder on pins 0 and 2. Phase is connected with gnd for signals. +#endif +} +void uiCheckSlowKeys(uint16_t &action) { +#if defined(UI_HAS_I2C_KEYS) && UI_HAS_KEYS!=0 +#if UI_DISPLAY_I2C_CHIPTYPE==0 + HAL::i2cStartWait(UI_I2C_KEY_ADDRESS+I2C_READ); + uint8_t keymask = HAL::i2cReadNak(); // Read current key mask +#endif +#if UI_DISPLAY_I2C_CHIPTYPE==1 + HAL::i2cStartWait(UI_DISPLAY_I2C_ADDRESS+I2C_WRITE); + HAL::i2cWrite(0x12); // GPIOA + HAL::i2cStop(); + HAL::i2cStartWait(UI_DISPLAY_I2C_ADDRESS+I2C_READ); + uint16_t keymask = HAL::i2cReadAck(); + keymask = keymask + (HAL::i2cReadNak()<<8); +#endif + HAL::i2cStop(); + // Add I2C key tests here + UI_KEYS_I2C_CLICKENCODER_LOW_REV(_BV(2),_BV(0)); // click encoder on pins 0 and 2. Phase is connected with gnd for signals. + UI_KEYS_I2C_BUTTON_LOW(_BV(1),UI_ACTION_OK); // push button, connects gnd to pin + UI_KEYS_I2C_BUTTON_LOW(_BV(3),UI_ACTION_BACK); // push button, connects gnd to pin + UI_KEYS_I2C_BUTTON_LOW(_BV(4),UI_ACTION_MENU_QUICKSETTINGS+UI_ACTION_TOPMENU); // push button, connects gnd to pin + UI_KEYS_I2C_BUTTON_LOW(_BV(5),UI_ACTION_MENU_EXTRUDER+UI_ACTION_TOPMENU); // push button, connects gnd to pin + UI_KEYS_I2C_BUTTON_LOW(_BV(6),UI_ACTION_MENU_POSITIONS+UI_ACTION_TOPMENU); // push button, connects gnd to pin +/* + // Button handling for the Adafruit RGB shild + UI_KEYS_I2C_BUTTON_LOW(4,UI_ACTION_PREVIOUS); // Up button + UI_KEYS_I2C_BUTTON_LOW(8,UI_ACTION_NEXT); // down button + UI_KEYS_I2C_BUTTON_LOW(16,UI_ACTION_BACK); // left button + UI_KEYS_I2C_BUTTON_LOW(2,UI_ACTION_OK); // right button + UI_KEYS_I2C_BUTTON_LOW(1,UI_ACTION_MENU_QUICKSETTINGS); //Select button + // ----- End RGB shield ---------- + */ +#endif + + //UI_KEYS_MATRIX(32,47,45,43,41,39,37,35); +} + +#endif +#endif + + + diff --git a/trunk/Arduino/Repetier_0.92.9/uilang.cpp b/trunk/Arduino/Repetier_0.92.9/uilang.cpp new file mode 100644 index 00000000..e01d0703 --- /dev/null +++ b/trunk/Arduino/Repetier_0.92.9/uilang.cpp @@ -0,0 +1,6635 @@ +/* + This file is part of Repetier-Firmware. + + Repetier-Firmware is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Repetier-Firmware is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Repetier-Firmware. If not, see . + + This firmware is a nearly complete rewrite of the sprinter firmware + by kliment (https://github.com/kliment/Sprinter) + which based on Tonokip RepRap firmware rewrite based off of Hydra-mmm firmware. +*/ + +#include "Repetier.h" + +#if UI_DISPLAY_TYPE != NO_DISPLAY + +#if LANGUAGE_EN_ACTIVE+LANGUAGE_DE_ACTIVE+LANGUAGE_ES_ACTIVE+LANGUAGE_PT_ACTIVE+LANGUAGE_FR_ACTIVE+LANGUAGE_NL_ACTIVE+LANGUAGE_IT_ACTIVE+LANGUAGE_SE_ACTIVE+LANGUAGE_CZ_ACTIVE+LANGUAGE_PL_ACTIVE+LANGUAGE_TR_ACTIVE < 1 +#error No language for diplay selected +#endif // LANGUAGE_EN_ACTIVE + +#define TRANS(x) UI_STRING(F ## x,x) + +// Translations of ui + +#if LANGUAGE_EN_ACTIVE +TRANS(UI_TEXT_ON_EN); +TRANS(UI_TEXT_OFF_EN); +TRANS(UI_TEXT_NA_EN); +TRANS(UI_TEXT_YES_EN); +TRANS(UI_TEXT_NO_EN); +TRANS(UI_TEXT_PRINT_POS_EN); +TRANS(UI_TEXT_PRINTING_EN); +TRANS(UI_TEXT_IDLE_EN); +TRANS(UI_TEXT_NOSDCARD_EN); +TRANS(UI_TEXT_ERROR_EN); +TRANS(UI_TEXT_BACK_EN); +TRANS(UI_TEXT_QUICK_SETTINGS_EN); +TRANS(UI_TEXT_ERRORMSG_EN); +TRANS(UI_TEXT_CONFIGURATION_EN); +TRANS(UI_TEXT_POSITION_EN); +TRANS(UI_TEXT_EXTRUDER_EN); +TRANS(UI_TEXT_SD_CARD_EN); +TRANS(UI_TEXT_DEBUGGING_EN); +TRANS(UI_TEXT_HOME_DELTA_EN); +TRANS(UI_TEXT_HOME_ALL_EN); +TRANS(UI_TEXT_HOME_X_EN); +TRANS(UI_TEXT_HOME_Y_EN); +TRANS(UI_TEXT_HOME_Z_EN); +TRANS(UI_TEXT_PREHEAT_PLA_EN); +TRANS(UI_TEXT_PREHEAT_ABS_EN); +TRANS(UI_TEXT_LIGHTS_ONOFF_EN); +TRANS(UI_TEXT_COOLDOWN_EN); +TRANS(UI_TEXT_SET_TO_ORIGIN_EN); +TRANS(UI_TEXT_DISABLE_STEPPER_EN); +TRANS(UI_TEXT_X_POSITION_EN); +TRANS(UI_TEXT_X_POS_FAST_EN); +TRANS(UI_TEXT_Y_POSITION_EN); +TRANS(UI_TEXT_Y_POS_FAST_EN); +TRANS(UI_TEXT_Z_POSITION_EN); +TRANS(UI_TEXT_Z_POS_FAST_EN); +TRANS(UI_TEXT_E_POSITION_EN); +TRANS(UI_TEXT_BED_TEMP_EN); +TRANS(UI_TEXT_EXTR0_TEMP_EN); +TRANS(UI_TEXT_EXTR1_TEMP_EN); +TRANS(UI_TEXT_EXTR2_TEMP_EN); +TRANS(UI_TEXT_EXTR0_OFF_EN); +TRANS(UI_TEXT_EXTR1_OFF_EN); +TRANS(UI_TEXT_EXTR2_OFF_EN); +TRANS(UI_TEXT_EXTR0_SELECT_EN); +TRANS(UI_TEXT_EXTR1_SELECT_EN); +TRANS(UI_TEXT_EXTR2_SELECT_EN); +TRANS(UI_TEXT_EXTR_ORIGIN_EN); +TRANS(UI_TEXT_PRINT_X_EN); +TRANS(UI_TEXT_PRINT_Y_EN); +TRANS(UI_TEXT_PRINT_Z_EN); +TRANS(UI_TEXT_PRINT_Z_DELTA_EN); +TRANS(UI_TEXT_MOVE_X_EN); +TRANS(UI_TEXT_MOVE_Y_EN); +TRANS(UI_TEXT_MOVE_Z_EN); +TRANS(UI_TEXT_MOVE_Z_DELTA_EN); +TRANS(UI_TEXT_JERK_EN); +TRANS(UI_TEXT_ZJERK_EN); +TRANS(UI_TEXT_ACCELERATION_EN); +TRANS(UI_TEXT_STORE_TO_EEPROM_EN); +TRANS(UI_TEXT_LOAD_EEPROM_EN); +TRANS(UI_TEXT_DBG_ECHO_EN); +TRANS(UI_TEXT_DBG_INFO_EN); +TRANS(UI_TEXT_DBG_ERROR_EN); +TRANS(UI_TEXT_DBG_DRYRUN_EN); +TRANS(UI_TEXT_DBG_ENDSTOP_EN); +TRANS(UI_TEXT_OPS_OFF_EN); +TRANS(UI_TEXT_OPS_CLASSIC_EN); +TRANS(UI_TEXT_OPS_FAST_EN); +TRANS(UI_TEXT_OPS_RETRACT_EN); +TRANS(UI_TEXT_OPS_BACKSLASH_EN); +TRANS(UI_TEXT_OPS_MINDIST_EN); +TRANS(UI_TEXT_OPS_MOVE_AFTER_EN); +TRANS(UI_TEXT_ANTI_OOZE_EN); +TRANS(UI_TEXT_PRINT_FILE_EN); +TRANS(UI_TEXT_PAUSE_PRINT_EN); +TRANS(UI_TEXT_CONTINUE_PRINT_EN); +TRANS(UI_TEXT_UNMOUNT_CARD_EN); +TRANS(UI_TEXT_MOUNT_CARD_EN); +TRANS(UI_TEXT_DELETE_FILE_EN); +TRANS(UI_TEXT_FEEDRATE_EN); +TRANS(UI_TEXT_FEED_MAX_X_EN); +TRANS(UI_TEXT_FEED_MAX_Y_EN); +TRANS(UI_TEXT_FEED_MAX_Z_EN); +TRANS(UI_TEXT_FEED_MAX_Z_DELTA_EN); +TRANS(UI_TEXT_FEED_HOME_X_EN); +TRANS(UI_TEXT_FEED_HOME_Y_EN); +TRANS(UI_TEXT_FEED_HOME_Z_EN); +TRANS(UI_TEXT_FEED_HOME_Z_DELTA_EN); +TRANS(UI_TEXT_ACTION_XPOSITION4A_EN); +TRANS(UI_TEXT_ACTION_XPOSITION4B_EN); +TRANS(UI_TEXT_ACTION_XPOSITION4C_EN); +TRANS(UI_TEXT_ACTION_XPOSITION4D_EN); +TRANS(UI_TEXT_ACTION_YPOSITION4A_EN); +TRANS(UI_TEXT_ACTION_YPOSITION4B_EN); +TRANS(UI_TEXT_ACTION_YPOSITION4C_EN); +TRANS(UI_TEXT_ACTION_YPOSITION4D_EN); +TRANS(UI_TEXT_ACTION_ZPOSITION4A_EN); +TRANS(UI_TEXT_ACTION_ZPOSITION4B_EN); +TRANS(UI_TEXT_ACTION_ZPOSITION4C_EN); +TRANS(UI_TEXT_ACTION_ZPOSITION4D_EN); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST4A_EN); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST4B_EN); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST4C_EN); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST4D_EN); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST4A_EN); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST4B_EN); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST4C_EN); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST4D_EN); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST4A_EN); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST4B_EN); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST4C_EN); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST4D_EN); +TRANS(UI_TEXT_ACTION_EPOSITION_FAST2A_EN); +TRANS(UI_TEXT_ACTION_EPOSITION_FAST2B_EN); +TRANS(UI_TEXT_ACTION_XPOSITION2A_EN); +TRANS(UI_TEXT_ACTION_XPOSITION2B_EN); +TRANS(UI_TEXT_ACTION_YPOSITION2A_EN); +TRANS(UI_TEXT_ACTION_YPOSITION2B_EN); +TRANS(UI_TEXT_ACTION_ZPOSITION2A_EN); +TRANS(UI_TEXT_ACTION_ZPOSITION2B_EN); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST2A_EN); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST2B_EN); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST2A_EN); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST2B_EN); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST2A_EN); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST2B_EN); +TRANS(UI_TEXT_FANSPEED_EN); +TRANS(UI_TEXT_ACTION_FANSPEED_EN); +TRANS(UI_TEXT_FAN_OFF_EN); +TRANS(UI_TEXT_FAN_25_EN); +TRANS(UI_TEXT_FAN_50_EN); +TRANS(UI_TEXT_FAN_75_EN); +TRANS(UI_TEXT_FAN_FULL_EN); +TRANS(UI_TEXT_STEPPER_INACTIVE_EN); +TRANS(UI_TEXT_STEPPER_INACTIVE2A_EN); +TRANS(UI_TEXT_STEPPER_INACTIVE2B_EN); +TRANS(UI_TEXT_POWER_INACTIVE_EN); +TRANS(UI_TEXT_POWER_INACTIVE2A_EN); +TRANS(UI_TEXT_POWER_INACTIVE2B_EN); +TRANS(UI_TEXT_GENERAL_EN); +TRANS(UI_TEXT_BAUDRATE_EN); +TRANS(UI_TEXT_EXTR_STEPS_EN); +TRANS(UI_TEXT_EXTR_START_FEED_EN); +TRANS(UI_TEXT_EXTR_MAX_FEED_EN); +TRANS(UI_TEXT_EXTR_ACCEL_EN); +TRANS(UI_TEXT_EXTR_WATCH_EN); +TRANS(UI_TEXT_EXTR_ADVANCE_L_EN); +TRANS(UI_TEXT_EXTR_ADVANCE_K_EN); +TRANS(UI_TEXT_EXTR_MANAGER_EN); +TRANS(UI_TEXT_EXTR_PGAIN_EN); +TRANS(UI_TEXT_EXTR_DEADTIME_EN); +TRANS(UI_TEXT_EXTR_DMAX_DT_EN); +TRANS(UI_TEXT_EXTR_IGAIN_EN); +TRANS(UI_TEXT_EXTR_DGAIN_EN); +TRANS(UI_TEXT_EXTR_DMIN_EN); +TRANS(UI_TEXT_EXTR_DMAX_EN); +TRANS(UI_TEXT_EXTR_PMAX_EN); +TRANS(UI_TEXT_EXTR_XOFF_EN); +TRANS(UI_TEXT_EXTR_YOFF_EN); +TRANS(UI_TEXT_STRING_HM_BANGBANG_EN); +TRANS(UI_TEXT_STRING_HM_PID_EN); +TRANS(UI_TEXT_STRING_ACTION_EN); +TRANS(UI_TEXT_HEATING_EXTRUDER_EN); +TRANS(UI_TEXT_HEATING_BED_EN); +TRANS(UI_TEXT_KILLED_EN); +TRANS(UI_TEXT_STEPPER_DISABLED_EN); +TRANS(UI_TEXT_EEPROM_STOREDA_EN); +TRANS(UI_TEXT_EEPROM_STOREDB_EN); +TRANS(UI_TEXT_EEPROM_LOADEDA_EN); +TRANS(UI_TEXT_EEPROM_LOADEDB_EN); +TRANS(UI_TEXT_UPLOADING_EN); +TRANS(UI_TEXT_PAGE_BUFFER_EN); +TRANS(UI_TEXT_PAGE_EXTRUDER_EN); +TRANS(UI_TEXT_PAGE_EXTRUDER1_EN); +TRANS(UI_TEXT_PAGE_EXTRUDER2_EN); +TRANS(UI_TEXT_PAGE_EXTRUDER3_EN); +TRANS(UI_TEXT_PAGE_BED_EN); +TRANS(UI_TEXT_SPEED_MULTIPLY_EN); +TRANS(UI_TEXT_FLOW_MULTIPLY_EN); +TRANS(UI_TEXT_SHOW_MEASUREMENT_EN); +TRANS(UI_TEXT_RESET_MEASUREMENT_EN); +TRANS(UI_TEXT_SET_MEASURED_ORIGIN_EN); +TRANS(UI_TEXT_ZCALIB_EN); +TRANS(UI_TEXT_SET_P1_EN); +TRANS(UI_TEXT_SET_P2_EN); +TRANS(UI_TEXT_SET_P3_EN); +TRANS(UI_TEXT_CALCULATE_LEVELING_EN); +TRANS(UI_TEXT_LEVEL_EN); +TRANS(UI_TEXT_EXTR_WAIT_RETRACT_TEMP_EN); +TRANS(UI_TEXT_EXTR_WAIT_RETRACT_UNITS_EN); +TRANS(UI_TEXT_SD_REMOVED_EN); +TRANS(UI_TEXT_SD_INSERTED_EN); +TRANS(UI_TEXT_PRINTER_READY_EN); +TRANS(UI_TEXT_PRINTTIME_DAYS_EN); +TRANS(UI_TEXT_PRINTTIME_HOURS_EN); +TRANS(UI_TEXT_PRINTTIME_MINUTES_EN); +TRANS(UI_TEXT_PRINT_TIME_EN); +TRANS(UI_TEXT_PRINT_FILAMENT_EN); +TRANS(UI_TEXT_PRINTED_EN); +TRANS(UI_TEXT_POWER_EN); +TRANS(UI_TEXT_STRING_HM_DEADTIME_EN); +TRANS(UI_TEXT_STRING_HM_SLOWBANG_EN); +TRANS(UI_TEXT_STOP_PRINT_EN); +TRANS(UI_TEXT_Z_BABYSTEPPING_EN); +TRANS(UI_TEXT_CHANGE_FILAMENT_EN); +TRANS(UI_TEXT_WIZ_CH_FILAMENT1_EN); +TRANS(UI_TEXT_WIZ_CH_FILAMENT2_EN); +TRANS(UI_TEXT_WIZ_CH_FILAMENT3_EN); +TRANS(UI_TEXT_CLICK_DONE_EN); +TRANS(UI_TEXT_AUTOLEVEL_ONOFF_EN); +TRANS(UI_TEXT_SERVOPOS_EN); +TRANS(UI_TEXT_IGNORE_M106_EN); +TRANS(UI_TEXT_WIZ_REHEAT1_EN); +TRANS(UI_TEXT_WIZ_REHEAT2_EN); +TRANS(UI_TEXT_WIZ_WAITTEMP1_EN); +TRANS(UI_TEXT_WIZ_WAITTEMP2_EN); +TRANS(UI_TEXT_EXTRUDER_JAM_EN); +TRANS(UI_TEXT_STANDBY_EN); +TRANS(UI_TEXT_BED_COATING_EN); +TRANS(UI_TEXT_BED_COATING_SET1_EN); +TRANS(UI_TEXT_BED_COATING_SET2_EN); +TRANS(UI_TEXT_NOCOATING_EN); +TRANS(UI_TEXT_BUILDTAK_EN); +TRANS(UI_TEXT_KAPTON_EN); +TRANS(UI_TEXT_BLUETAPE_EN); +TRANS(UI_TEXT_PETTAPE_EN); +TRANS(UI_TEXT_GLUESTICK_EN); +TRANS(UI_TEXT_CUSTOM_EN); +TRANS(UI_TEXT_COATING_CUSTOM_EN); +TRANS(UI_TEXT_LANGUAGE_EN); +TRANS(UI_TEXT_MAINPAGE6_1_EN); +TRANS(UI_TEXT_MAINPAGE6_2_EN); +TRANS(UI_TEXT_MAINPAGE6_3_EN); +TRANS(UI_TEXT_MAINPAGE6_4_EN); +TRANS(UI_TEXT_MAINPAGE6_5_EN); +TRANS(UI_TEXT_MAINPAGE6_6_EN); +TRANS(UI_TEXT_MAINPAGE_TEMP_BED_EN); +TRANS(UI_TEXT_MAINPAGE_BED_EN); +TRANS(UI_TEXT_MAINPAGE_Z_BUF_EN); +TRANS(UI_TEXT_MAINPAGE_MUL_EUSAGE_EN); +TRANS(UI_TEXT_MAINPAGE_XY_EN); +TRANS(UI_TEXT_PRINT_TIME_VALUE_EN); +TRANS(UI_TEXT_PRINT_FILAMENT_VALUE_EN); +TRANS(UI_TEXT_METER_PRINTED_EN); +TRANS(UI_TEXT_STATUS_EN); +TRANS(UI_TEXT_EMPTY_EN); +TRANS(UI_TEXT_TEMP_SET_EN); +TRANS(UI_TEXT_CURRENT_TEMP_EN); +TRANS(UI_TEXT_COATING_THICKNESS_EN); +TRANS(UI_TEXT_EXTR3_TEMP_EN); +TRANS(UI_TEXT_EXTR4_TEMP_EN); +TRANS(UI_TEXT_EXTR5_TEMP_EN); +TRANS(UI_TEXT_EXTR3_OFF_EN); +TRANS(UI_TEXT_EXTR4_OFF_EN); +TRANS(UI_TEXT_EXTR5_OFF_EN); +TRANS(UI_TEXT_EXTR3_SELECT_EN); +TRANS(UI_TEXT_EXTR4_SELECT_EN); +TRANS(UI_TEXT_EXTR5_SELECT_EN); +TRANS(UI_TEXT_DITTO_0_EN); +TRANS(UI_TEXT_DITTO_1_EN); +TRANS(UI_TEXT_DITTO_2_EN); +TRANS(UI_TEXT_DITTO_3_EN); +TRANS(UI_TEXT_ZPROBE_HEIGHT_EN); +TRANS(UI_TEXT_OFFSETS_EN); +TRANS(UI_TEXT_X_OFFSET_EN); +TRANS(UI_TEXT_Y_OFFSET_EN); +TRANS(UI_TEXT_Z_OFFSET_EN); + + +PGM_P const translations_en[NUM_TRANSLATED_WORDS] PROGMEM = { + FUI_TEXT_ON_EN, + FUI_TEXT_OFF_EN, + FUI_TEXT_NA_EN, + FUI_TEXT_YES_EN, + FUI_TEXT_NO_EN, + FUI_TEXT_PRINT_POS_EN, + FUI_TEXT_PRINTING_EN, + FUI_TEXT_IDLE_EN, + FUI_TEXT_NOSDCARD_EN, + FUI_TEXT_ERROR_EN, + FUI_TEXT_BACK_EN, + FUI_TEXT_QUICK_SETTINGS_EN, + FUI_TEXT_ERRORMSG_EN, + FUI_TEXT_CONFIGURATION_EN, + FUI_TEXT_POSITION_EN, + FUI_TEXT_EXTRUDER_EN, + FUI_TEXT_SD_CARD_EN, + FUI_TEXT_DEBUGGING_EN, + FUI_TEXT_HOME_DELTA_EN, + FUI_TEXT_HOME_ALL_EN, + FUI_TEXT_HOME_X_EN, + FUI_TEXT_HOME_Y_EN, + FUI_TEXT_HOME_Z_EN, + FUI_TEXT_PREHEAT_PLA_EN, + FUI_TEXT_PREHEAT_ABS_EN, + FUI_TEXT_LIGHTS_ONOFF_EN, + FUI_TEXT_COOLDOWN_EN, + FUI_TEXT_SET_TO_ORIGIN_EN, + FUI_TEXT_DISABLE_STEPPER_EN, + FUI_TEXT_X_POSITION_EN, + FUI_TEXT_X_POS_FAST_EN, + FUI_TEXT_Y_POSITION_EN, + FUI_TEXT_Y_POS_FAST_EN, + FUI_TEXT_Z_POSITION_EN, + FUI_TEXT_Z_POS_FAST_EN, + FUI_TEXT_E_POSITION_EN, + FUI_TEXT_BED_TEMP_EN, + FUI_TEXT_EXTR0_TEMP_EN, + FUI_TEXT_EXTR1_TEMP_EN, + FUI_TEXT_EXTR2_TEMP_EN, + FUI_TEXT_EXTR0_OFF_EN, + FUI_TEXT_EXTR1_OFF_EN, + FUI_TEXT_EXTR2_OFF_EN, + FUI_TEXT_EXTR0_SELECT_EN, + FUI_TEXT_EXTR1_SELECT_EN, + FUI_TEXT_EXTR2_SELECT_EN, + FUI_TEXT_EXTR_ORIGIN_EN, + FUI_TEXT_PRINT_X_EN, + FUI_TEXT_PRINT_Y_EN, + FUI_TEXT_PRINT_Z_EN, + FUI_TEXT_PRINT_Z_DELTA_EN, + FUI_TEXT_MOVE_X_EN, + FUI_TEXT_MOVE_Y_EN, + FUI_TEXT_MOVE_Z_EN, + FUI_TEXT_MOVE_Z_DELTA_EN, + FUI_TEXT_JERK_EN, + FUI_TEXT_ZJERK_EN, + FUI_TEXT_ACCELERATION_EN, + FUI_TEXT_STORE_TO_EEPROM_EN, + FUI_TEXT_LOAD_EEPROM_EN, + FUI_TEXT_DBG_ECHO_EN, + FUI_TEXT_DBG_INFO_EN, + FUI_TEXT_DBG_ERROR_EN, + FUI_TEXT_DBG_DRYRUN_EN, + FUI_TEXT_OPS_OFF_EN, + FUI_TEXT_OPS_CLASSIC_EN, + FUI_TEXT_OPS_FAST_EN, + FUI_TEXT_OPS_RETRACT_EN, + FUI_TEXT_OPS_BACKSLASH_EN, + FUI_TEXT_OPS_MINDIST_EN, + FUI_TEXT_OPS_MOVE_AFTER_EN, + FUI_TEXT_ANTI_OOZE_EN, + FUI_TEXT_PRINT_FILE_EN, + FUI_TEXT_PAUSE_PRINT_EN, + FUI_TEXT_CONTINUE_PRINT_EN, + FUI_TEXT_UNMOUNT_CARD_EN, + FUI_TEXT_MOUNT_CARD_EN, + FUI_TEXT_DELETE_FILE_EN, + FUI_TEXT_FEEDRATE_EN, + FUI_TEXT_FEED_MAX_X_EN, + FUI_TEXT_FEED_MAX_Y_EN, + FUI_TEXT_FEED_MAX_Z_EN, + FUI_TEXT_FEED_MAX_Z_DELTA_EN, + FUI_TEXT_FEED_HOME_X_EN, + FUI_TEXT_FEED_HOME_Y_EN, + FUI_TEXT_FEED_HOME_Z_EN, + FUI_TEXT_FEED_HOME_Z_DELTA_EN, + FUI_TEXT_ACTION_XPOSITION4A_EN, + FUI_TEXT_ACTION_XPOSITION4B_EN, + FUI_TEXT_ACTION_XPOSITION4C_EN, + FUI_TEXT_ACTION_XPOSITION4D_EN, + FUI_TEXT_ACTION_YPOSITION4A_EN, + FUI_TEXT_ACTION_YPOSITION4B_EN, + FUI_TEXT_ACTION_YPOSITION4C_EN, + FUI_TEXT_ACTION_YPOSITION4D_EN, + FUI_TEXT_ACTION_ZPOSITION4A_EN, + FUI_TEXT_ACTION_ZPOSITION4B_EN, + FUI_TEXT_ACTION_ZPOSITION4C_EN, + FUI_TEXT_ACTION_ZPOSITION4D_EN, + FUI_TEXT_ACTION_XPOSITION_FAST4A_EN, + FUI_TEXT_ACTION_XPOSITION_FAST4B_EN, + FUI_TEXT_ACTION_XPOSITION_FAST4C_EN, + FUI_TEXT_ACTION_XPOSITION_FAST4D_EN, + FUI_TEXT_ACTION_YPOSITION_FAST4A_EN, + FUI_TEXT_ACTION_YPOSITION_FAST4B_EN, + FUI_TEXT_ACTION_YPOSITION_FAST4C_EN, + FUI_TEXT_ACTION_YPOSITION_FAST4D_EN, + FUI_TEXT_ACTION_ZPOSITION_FAST4A_EN, + FUI_TEXT_ACTION_ZPOSITION_FAST4B_EN, + FUI_TEXT_ACTION_ZPOSITION_FAST4C_EN, + FUI_TEXT_ACTION_ZPOSITION_FAST4D_EN, + FUI_TEXT_ACTION_EPOSITION_FAST2A_EN, + FUI_TEXT_ACTION_EPOSITION_FAST2B_EN, + FUI_TEXT_ACTION_XPOSITION2A_EN, + FUI_TEXT_ACTION_XPOSITION2B_EN, + FUI_TEXT_ACTION_YPOSITION2A_EN, + FUI_TEXT_ACTION_YPOSITION2B_EN, + FUI_TEXT_ACTION_ZPOSITION2A_EN, + FUI_TEXT_ACTION_ZPOSITION2B_EN, + FUI_TEXT_ACTION_XPOSITION_FAST2A_EN, + FUI_TEXT_ACTION_XPOSITION_FAST2B_EN, + FUI_TEXT_ACTION_YPOSITION_FAST2A_EN, + FUI_TEXT_ACTION_YPOSITION_FAST2B_EN, + FUI_TEXT_ACTION_ZPOSITION_FAST2A_EN, + FUI_TEXT_ACTION_ZPOSITION_FAST2B_EN, + FUI_TEXT_FANSPEED_EN, + FUI_TEXT_ACTION_FANSPEED_EN, + FUI_TEXT_FAN_OFF_EN, + FUI_TEXT_FAN_25_EN, + FUI_TEXT_FAN_50_EN, + FUI_TEXT_FAN_75_EN, + FUI_TEXT_FAN_FULL_EN, + FUI_TEXT_STEPPER_INACTIVE_EN, + FUI_TEXT_STEPPER_INACTIVE2A_EN, + FUI_TEXT_STEPPER_INACTIVE2B_EN, + FUI_TEXT_POWER_INACTIVE_EN, + FUI_TEXT_POWER_INACTIVE2A_EN, + FUI_TEXT_POWER_INACTIVE2B_EN, + FUI_TEXT_GENERAL_EN, + FUI_TEXT_BAUDRATE_EN, + FUI_TEXT_EXTR_STEPS_EN, + FUI_TEXT_EXTR_START_FEED_EN, + FUI_TEXT_EXTR_MAX_FEED_EN, + FUI_TEXT_EXTR_ACCEL_EN, + FUI_TEXT_EXTR_WATCH_EN, + FUI_TEXT_EXTR_ADVANCE_L_EN, + FUI_TEXT_EXTR_ADVANCE_K_EN, + FUI_TEXT_EXTR_MANAGER_EN, + FUI_TEXT_EXTR_PGAIN_EN, + FUI_TEXT_EXTR_DEADTIME_EN, + FUI_TEXT_EXTR_DMAX_DT_EN, + FUI_TEXT_EXTR_IGAIN_EN, + FUI_TEXT_EXTR_DGAIN_EN, + FUI_TEXT_EXTR_DMIN_EN, + FUI_TEXT_EXTR_DMAX_EN, + FUI_TEXT_EXTR_PMAX_EN, + FUI_TEXT_EXTR_XOFF_EN, + FUI_TEXT_EXTR_YOFF_EN, + FUI_TEXT_STRING_HM_BANGBANG_EN, + FUI_TEXT_STRING_HM_PID_EN, + FUI_TEXT_STRING_ACTION_EN, + FUI_TEXT_HEATING_EXTRUDER_EN, + FUI_TEXT_HEATING_BED_EN, + FUI_TEXT_KILLED_EN, + FUI_TEXT_STEPPER_DISABLED_EN, + FUI_TEXT_EEPROM_STOREDA_EN, + FUI_TEXT_EEPROM_STOREDB_EN, + FUI_TEXT_EEPROM_LOADEDA_EN, + FUI_TEXT_EEPROM_LOADEDB_EN, + FUI_TEXT_UPLOADING_EN, + FUI_TEXT_PAGE_BUFFER_EN, + FUI_TEXT_PAGE_EXTRUDER_EN, + FUI_TEXT_PAGE_EXTRUDER1_EN, + FUI_TEXT_PAGE_EXTRUDER2_EN, + FUI_TEXT_PAGE_EXTRUDER3_EN, + FUI_TEXT_PAGE_BED_EN, + FUI_TEXT_SPEED_MULTIPLY_EN, + FUI_TEXT_FLOW_MULTIPLY_EN, + FUI_TEXT_SHOW_MEASUREMENT_EN, + FUI_TEXT_RESET_MEASUREMENT_EN, + FUI_TEXT_SET_MEASURED_ORIGIN_EN, + FUI_TEXT_ZCALIB_EN, + FUI_TEXT_SET_P1_EN, + FUI_TEXT_SET_P2_EN, + FUI_TEXT_SET_P3_EN, + FUI_TEXT_CALCULATE_LEVELING_EN, + FUI_TEXT_LEVEL_EN, + FUI_TEXT_EXTR_WAIT_RETRACT_TEMP_EN, + FUI_TEXT_EXTR_WAIT_RETRACT_UNITS_EN, + FUI_TEXT_SD_REMOVED_EN, + FUI_TEXT_SD_INSERTED_EN, + FUI_TEXT_PRINTER_READY_EN, + FUI_TEXT_PRINTTIME_DAYS_EN, + FUI_TEXT_PRINTTIME_HOURS_EN, + FUI_TEXT_PRINTTIME_MINUTES_EN, + FUI_TEXT_PRINT_TIME_EN, + FUI_TEXT_PRINT_FILAMENT_EN, + FUI_TEXT_PRINTED_EN, + FUI_TEXT_POWER_EN, + FUI_TEXT_STRING_HM_DEADTIME_EN, + FUI_TEXT_STRING_HM_SLOWBANG_EN, + FUI_TEXT_STOP_PRINT_EN, + FUI_TEXT_Z_BABYSTEPPING_EN, + FUI_TEXT_CHANGE_FILAMENT_EN, + FUI_TEXT_WIZ_CH_FILAMENT1_EN, + FUI_TEXT_WIZ_CH_FILAMENT2_EN, + FUI_TEXT_WIZ_CH_FILAMENT3_EN, + FUI_TEXT_CLICK_DONE_EN, + FUI_TEXT_AUTOLEVEL_ONOFF_EN, + FUI_TEXT_SERVOPOS_EN, + FUI_TEXT_IGNORE_M106_EN, + FUI_TEXT_WIZ_REHEAT1_EN, + FUI_TEXT_WIZ_REHEAT2_EN, + FUI_TEXT_WIZ_WAITTEMP1_EN, + FUI_TEXT_WIZ_WAITTEMP2_EN, + FUI_TEXT_EXTRUDER_JAM_EN, + FUI_TEXT_STANDBY_EN, + FUI_TEXT_BED_COATING_EN, + FUI_TEXT_BED_COATING_SET1_EN, + FUI_TEXT_BED_COATING_SET2_EN, + FUI_TEXT_NOCOATING_EN, + FUI_TEXT_BUILDTAK_EN, + FUI_TEXT_KAPTON_EN, + FUI_TEXT_BLUETAPE_EN, + FUI_TEXT_PETTAPE_EN, + FUI_TEXT_GLUESTICK_EN, + FUI_TEXT_CUSTOM_EN, + FUI_TEXT_COATING_CUSTOM_EN, + FUI_TEXT_LANGUAGE_EN, + FUI_TEXT_MAINPAGE6_1_EN, + FUI_TEXT_MAINPAGE6_2_EN, + FUI_TEXT_MAINPAGE6_3_EN, + FUI_TEXT_MAINPAGE6_4_EN, + FUI_TEXT_MAINPAGE6_5_EN, + FUI_TEXT_MAINPAGE6_6_EN, + FUI_TEXT_MAINPAGE_TEMP_BED_EN, + FUI_TEXT_MAINPAGE_BED_EN, + FUI_TEXT_MAINPAGE_Z_BUF_EN, + FUI_TEXT_MAINPAGE_MUL_EUSAGE_EN, + FUI_TEXT_MAINPAGE_XY_EN, + FUI_TEXT_PRINT_TIME_VALUE_EN, + FUI_TEXT_PRINT_FILAMENT_VALUE_EN, + FUI_TEXT_METER_PRINTED_EN, + FUI_TEXT_STATUS_EN, + FUI_TEXT_EMPTY_EN, + FUI_TEXT_TEMP_SET_EN, + FUI_TEXT_CURRENT_TEMP_EN, + FUI_TEXT_COATING_THICKNESS_EN, + FUI_TEXT_EXTR3_TEMP_EN, + FUI_TEXT_EXTR4_TEMP_EN, + FUI_TEXT_EXTR5_TEMP_EN, + FUI_TEXT_EXTR3_OFF_EN, + FUI_TEXT_EXTR4_OFF_EN, + FUI_TEXT_EXTR5_OFF_EN, + FUI_TEXT_EXTR3_SELECT_EN, + FUI_TEXT_EXTR4_SELECT_EN, + FUI_TEXT_EXTR5_SELECT_EN, + FUI_TEXT_DITTO_0_EN, + FUI_TEXT_DITTO_1_EN, + FUI_TEXT_DITTO_2_EN, + FUI_TEXT_DITTO_3_EN, + FUI_TEXT_ZPROBE_HEIGHT_EN, + FUI_TEXT_OFFSETS_EN, + FUI_TEXT_X_OFFSET_EN, + FUI_TEXT_Y_OFFSET_EN, + FUI_TEXT_Z_OFFSET_EN, + FUI_TEXT_DBG_ENDSTOP_EN +}; +#define LANG_EN_TABLE translations_en +#else +#define LANG_EN_TABLE NULL +#endif // LANGUAGE_EN_ACTIVE + +#if LANGUAGE_DE_ACTIVE +TRANS(UI_TEXT_ON_DE); +TRANS(UI_TEXT_OFF_DE); +TRANS(UI_TEXT_NA_DE); +TRANS(UI_TEXT_YES_DE); +TRANS(UI_TEXT_NO_DE); +TRANS(UI_TEXT_PRINT_POS_DE); +TRANS(UI_TEXT_PRINTING_DE); +TRANS(UI_TEXT_IDLE_DE); +TRANS(UI_TEXT_NOSDCARD_DE); +TRANS(UI_TEXT_ERROR_DE); +TRANS(UI_TEXT_BACK_DE); +TRANS(UI_TEXT_QUICK_SETTINGS_DE); +TRANS(UI_TEXT_ERRORMSG_DE); +TRANS(UI_TEXT_CONFIGURATION_DE); +TRANS(UI_TEXT_POSITION_DE); +TRANS(UI_TEXT_EXTRUDER_DE); +TRANS(UI_TEXT_SD_CARD_DE); +TRANS(UI_TEXT_DEBUGGING_DE); +TRANS(UI_TEXT_HOME_DELTA_DE); +TRANS(UI_TEXT_HOME_ALL_DE); +TRANS(UI_TEXT_HOME_X_DE); +TRANS(UI_TEXT_HOME_Y_DE); +TRANS(UI_TEXT_HOME_Z_DE); +TRANS(UI_TEXT_PREHEAT_PLA_DE); +TRANS(UI_TEXT_PREHEAT_ABS_DE); +TRANS(UI_TEXT_LIGHTS_ONOFF_DE); +TRANS(UI_TEXT_COOLDOWN_DE); +TRANS(UI_TEXT_SET_TO_ORIGIN_DE); +TRANS(UI_TEXT_DISABLE_STEPPER_DE); +TRANS(UI_TEXT_X_POSITION_DE); +TRANS(UI_TEXT_X_POS_FAST_DE); +TRANS(UI_TEXT_Y_POSITION_DE); +TRANS(UI_TEXT_Y_POS_FAST_DE); +TRANS(UI_TEXT_Z_POSITION_DE); +TRANS(UI_TEXT_Z_POS_FAST_DE); +TRANS(UI_TEXT_E_POSITION_DE); +TRANS(UI_TEXT_BED_TEMP_DE); +TRANS(UI_TEXT_EXTR0_TEMP_DE); +TRANS(UI_TEXT_EXTR1_TEMP_DE); +TRANS(UI_TEXT_EXTR2_TEMP_DE); +TRANS(UI_TEXT_EXTR0_OFF_DE); +TRANS(UI_TEXT_EXTR1_OFF_DE); +TRANS(UI_TEXT_EXTR2_OFF_DE); +TRANS(UI_TEXT_EXTR0_SELECT_DE); +TRANS(UI_TEXT_EXTR1_SELECT_DE); +TRANS(UI_TEXT_EXTR2_SELECT_DE); +TRANS(UI_TEXT_EXTR_ORIGIN_DE); +TRANS(UI_TEXT_PRINT_X_DE); +TRANS(UI_TEXT_PRINT_Y_DE); +TRANS(UI_TEXT_PRINT_Z_DE); +TRANS(UI_TEXT_PRINT_Z_DELTA_DE); +TRANS(UI_TEXT_MOVE_X_DE); +TRANS(UI_TEXT_MOVE_Y_DE); +TRANS(UI_TEXT_MOVE_Z_DE); +TRANS(UI_TEXT_MOVE_Z_DELTA_DE); +TRANS(UI_TEXT_JERK_DE); +TRANS(UI_TEXT_ZJERK_DE); +TRANS(UI_TEXT_ACCELERATION_DE); +TRANS(UI_TEXT_STORE_TO_EEPROM_DE); +TRANS(UI_TEXT_LOAD_EEPROM_DE); +TRANS(UI_TEXT_DBG_ECHO_DE); +TRANS(UI_TEXT_DBG_INFO_DE); +TRANS(UI_TEXT_DBG_ERROR_DE); +TRANS(UI_TEXT_DBG_DRYRUN_DE); +TRANS(UI_TEXT_DBG_ENDSTOP_DE); +TRANS(UI_TEXT_OPS_OFF_DE); +TRANS(UI_TEXT_OPS_CLASSIC_DE); +TRANS(UI_TEXT_OPS_FAST_DE); +TRANS(UI_TEXT_OPS_RETRACT_DE); +TRANS(UI_TEXT_OPS_BACKSLASH_DE); +TRANS(UI_TEXT_OPS_MINDIST_DE); +TRANS(UI_TEXT_OPS_MOVE_AFTER_DE); +TRANS(UI_TEXT_ANTI_OOZE_DE); +TRANS(UI_TEXT_PRINT_FILE_DE); +TRANS(UI_TEXT_PAUSE_PRINT_DE); +TRANS(UI_TEXT_CONTINUE_PRINT_DE); +TRANS(UI_TEXT_UNMOUNT_CARD_DE); +TRANS(UI_TEXT_MOUNT_CARD_DE); +TRANS(UI_TEXT_DELETE_FILE_DE); +TRANS(UI_TEXT_FEEDRATE_DE); +TRANS(UI_TEXT_FEED_MAX_X_DE); +TRANS(UI_TEXT_FEED_MAX_Y_DE); +TRANS(UI_TEXT_FEED_MAX_Z_DE); +TRANS(UI_TEXT_FEED_MAX_Z_DELTA_DE); +TRANS(UI_TEXT_FEED_HOME_X_DE); +TRANS(UI_TEXT_FEED_HOME_Y_DE); +TRANS(UI_TEXT_FEED_HOME_Z_DE); +TRANS(UI_TEXT_FEED_HOME_Z_DELTA_DE); +TRANS(UI_TEXT_ACTION_XPOSITION4A_DE); +TRANS(UI_TEXT_ACTION_XPOSITION4B_DE); +TRANS(UI_TEXT_ACTION_XPOSITION4C_DE); +TRANS(UI_TEXT_ACTION_XPOSITION4D_DE); +TRANS(UI_TEXT_ACTION_YPOSITION4A_DE); +TRANS(UI_TEXT_ACTION_YPOSITION4B_DE); +TRANS(UI_TEXT_ACTION_YPOSITION4C_DE); +TRANS(UI_TEXT_ACTION_YPOSITION4D_DE); +TRANS(UI_TEXT_ACTION_ZPOSITION4A_DE); +TRANS(UI_TEXT_ACTION_ZPOSITION4B_DE); +TRANS(UI_TEXT_ACTION_ZPOSITION4C_DE); +TRANS(UI_TEXT_ACTION_ZPOSITION4D_DE); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST4A_DE); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST4B_DE); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST4C_DE); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST4D_DE); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST4A_DE); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST4B_DE); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST4C_DE); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST4D_DE); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST4A_DE); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST4B_DE); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST4C_DE); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST4D_DE); +TRANS(UI_TEXT_ACTION_EPOSITION_FAST2A_DE); +TRANS(UI_TEXT_ACTION_EPOSITION_FAST2B_DE); +TRANS(UI_TEXT_ACTION_XPOSITION2A_DE); +TRANS(UI_TEXT_ACTION_XPOSITION2B_DE); +TRANS(UI_TEXT_ACTION_YPOSITION2A_DE); +TRANS(UI_TEXT_ACTION_YPOSITION2B_DE); +TRANS(UI_TEXT_ACTION_ZPOSITION2A_DE); +TRANS(UI_TEXT_ACTION_ZPOSITION2B_DE); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST2A_DE); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST2B_DE); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST2A_DE); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST2B_DE); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST2A_DE); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST2B_DE); +TRANS(UI_TEXT_FANSPEED_DE); +TRANS(UI_TEXT_ACTION_FANSPEED_DE); +TRANS(UI_TEXT_FAN_OFF_DE); +TRANS(UI_TEXT_FAN_25_DE); +TRANS(UI_TEXT_FAN_50_DE); +TRANS(UI_TEXT_FAN_75_DE); +TRANS(UI_TEXT_FAN_FULL_DE); +TRANS(UI_TEXT_STEPPER_INACTIVE_DE); +TRANS(UI_TEXT_STEPPER_INACTIVE2A_DE); +TRANS(UI_TEXT_STEPPER_INACTIVE2B_DE); +TRANS(UI_TEXT_POWER_INACTIVE_DE); +TRANS(UI_TEXT_POWER_INACTIVE2A_DE); +TRANS(UI_TEXT_POWER_INACTIVE2B_DE); +TRANS(UI_TEXT_GENERAL_DE); +TRANS(UI_TEXT_BAUDRATE_DE); +TRANS(UI_TEXT_EXTR_STEPS_DE); +TRANS(UI_TEXT_EXTR_START_FEED_DE); +TRANS(UI_TEXT_EXTR_MAX_FEED_DE); +TRANS(UI_TEXT_EXTR_ACCEL_DE); +TRANS(UI_TEXT_EXTR_WATCH_DE); +TRANS(UI_TEXT_EXTR_ADVANCE_L_DE); +TRANS(UI_TEXT_EXTR_ADVANCE_K_DE); +TRANS(UI_TEXT_EXTR_MANAGER_DE); +TRANS(UI_TEXT_EXTR_PGAIN_DE); +TRANS(UI_TEXT_EXTR_DEADTIME_DE); +TRANS(UI_TEXT_EXTR_DMAX_DT_DE); +TRANS(UI_TEXT_EXTR_IGAIN_DE); +TRANS(UI_TEXT_EXTR_DGAIN_DE); +TRANS(UI_TEXT_EXTR_DMIN_DE); +TRANS(UI_TEXT_EXTR_DMAX_DE); +TRANS(UI_TEXT_EXTR_PMAX_DE); +TRANS(UI_TEXT_EXTR_XOFF_DE); +TRANS(UI_TEXT_EXTR_YOFF_DE); +TRANS(UI_TEXT_STRING_HM_BANGBANG_DE); +TRANS(UI_TEXT_STRING_HM_PID_DE); +TRANS(UI_TEXT_STRING_ACTION_DE); +TRANS(UI_TEXT_HEATING_EXTRUDER_DE); +TRANS(UI_TEXT_HEATING_BED_DE); +TRANS(UI_TEXT_KILLED_DE); +TRANS(UI_TEXT_STEPPER_DISABLED_DE); +TRANS(UI_TEXT_EEPROM_STOREDA_DE); +TRANS(UI_TEXT_EEPROM_STOREDB_DE); +TRANS(UI_TEXT_EEPROM_LOADEDA_DE); +TRANS(UI_TEXT_EEPROM_LOADEDB_DE); +TRANS(UI_TEXT_UPLOADING_DE); +TRANS(UI_TEXT_PAGE_BUFFER_DE); +TRANS(UI_TEXT_PAGE_EXTRUDER_DE); +TRANS(UI_TEXT_PAGE_EXTRUDER1_DE); +TRANS(UI_TEXT_PAGE_EXTRUDER2_DE); +TRANS(UI_TEXT_PAGE_EXTRUDER3_DE); +TRANS(UI_TEXT_PAGE_BED_DE); +TRANS(UI_TEXT_SPEED_MULTIPLY_DE); +TRANS(UI_TEXT_FLOW_MULTIPLY_DE); +TRANS(UI_TEXT_SHOW_MEASUREMENT_DE); +TRANS(UI_TEXT_RESET_MEASUREMENT_DE); +TRANS(UI_TEXT_SET_MEASURED_ORIGIN_DE); +TRANS(UI_TEXT_ZCALIB_DE); +TRANS(UI_TEXT_SET_P1_DE); +TRANS(UI_TEXT_SET_P2_DE); +TRANS(UI_TEXT_SET_P3_DE); +TRANS(UI_TEXT_CALCULATE_LEVELING_DE); +TRANS(UI_TEXT_LEVEL_DE); +TRANS(UI_TEXT_EXTR_WAIT_RETRACT_TEMP_DE); +TRANS(UI_TEXT_EXTR_WAIT_RETRACT_UNITS_DE); +TRANS(UI_TEXT_SD_REMOVED_DE); +TRANS(UI_TEXT_SD_INSERTED_DE); +TRANS(UI_TEXT_PRINTER_READY_DE); +TRANS(UI_TEXT_PRINTTIME_DAYS_DE); +TRANS(UI_TEXT_PRINTTIME_HOURS_DE); +TRANS(UI_TEXT_PRINTTIME_MINUTES_DE); +TRANS(UI_TEXT_PRINT_TIME_DE); +TRANS(UI_TEXT_PRINT_FILAMENT_DE); +TRANS(UI_TEXT_PRINTED_DE); +TRANS(UI_TEXT_POWER_DE); +TRANS(UI_TEXT_STRING_HM_DEADTIME_DE); +TRANS(UI_TEXT_STRING_HM_SLOWBANG_DE); +TRANS(UI_TEXT_STOP_PRINT_DE); +TRANS(UI_TEXT_Z_BABYSTEPPING_DE); +TRANS(UI_TEXT_CHANGE_FILAMENT_DE); +TRANS(UI_TEXT_WIZ_CH_FILAMENT1_DE); +TRANS(UI_TEXT_WIZ_CH_FILAMENT2_DE); +TRANS(UI_TEXT_WIZ_CH_FILAMENT3_DE); +TRANS(UI_TEXT_CLICK_DONE_DE); +TRANS(UI_TEXT_AUTOLEVEL_ONOFF_DE); +TRANS(UI_TEXT_SERVOPOS_DE); +TRANS(UI_TEXT_IGNORE_M106_DE); +TRANS(UI_TEXT_WIZ_REHEAT1_DE); +TRANS(UI_TEXT_WIZ_REHEAT2_DE); +TRANS(UI_TEXT_WIZ_WAITTEMP1_DE); +TRANS(UI_TEXT_WIZ_WAITTEMP2_DE); +TRANS(UI_TEXT_EXTRUDER_JAM_DE); +TRANS(UI_TEXT_STANDBY_DE); +TRANS(UI_TEXT_BED_COATING_DE); +TRANS(UI_TEXT_BED_COATING_SET1_DE); +TRANS(UI_TEXT_BED_COATING_SET2_DE); +TRANS(UI_TEXT_NOCOATING_DE); +TRANS(UI_TEXT_BUILDTAK_DE); +TRANS(UI_TEXT_KAPTON_DE); +TRANS(UI_TEXT_BLUETAPE_DE); +TRANS(UI_TEXT_PETTAPE_DE); +TRANS(UI_TEXT_GLUESTICK_DE); +TRANS(UI_TEXT_CUSTOM_DE); +TRANS(UI_TEXT_COATING_CUSTOM_DE); +TRANS(UI_TEXT_LANGUAGE_DE); +TRANS(UI_TEXT_MAINPAGE6_1_DE); +TRANS(UI_TEXT_MAINPAGE6_2_DE); +TRANS(UI_TEXT_MAINPAGE6_3_DE); +TRANS(UI_TEXT_MAINPAGE6_4_DE); +TRANS(UI_TEXT_MAINPAGE6_5_DE); +TRANS(UI_TEXT_MAINPAGE6_6_DE); +TRANS(UI_TEXT_MAINPAGE_TEMP_BED_DE); +TRANS(UI_TEXT_MAINPAGE_BED_DE); +TRANS(UI_TEXT_MAINPAGE_Z_BUF_DE); +TRANS(UI_TEXT_MAINPAGE_MUL_EUSAGE_DE); +TRANS(UI_TEXT_MAINPAGE_XY_DE); +TRANS(UI_TEXT_PRINT_TIME_VALUE_DE); +TRANS(UI_TEXT_PRINT_FILAMENT_VALUE_DE); +TRANS(UI_TEXT_METER_PRINTED_DE); +TRANS(UI_TEXT_STATUS_DE); +TRANS(UI_TEXT_EMPTY_DE); +TRANS(UI_TEXT_TEMP_SET_DE); +TRANS(UI_TEXT_CURRENT_TEMP_DE); +TRANS(UI_TEXT_COATING_THICKNESS_DE); +TRANS(UI_TEXT_EXTR3_TEMP_DE); +TRANS(UI_TEXT_EXTR4_TEMP_DE); +TRANS(UI_TEXT_EXTR5_TEMP_DE); +TRANS(UI_TEXT_EXTR3_OFF_DE); +TRANS(UI_TEXT_EXTR4_OFF_DE); +TRANS(UI_TEXT_EXTR5_OFF_DE); +TRANS(UI_TEXT_EXTR3_SELECT_DE); +TRANS(UI_TEXT_EXTR4_SELECT_DE); +TRANS(UI_TEXT_EXTR5_SELECT_DE); +TRANS(UI_TEXT_DITTO_0_DE); +TRANS(UI_TEXT_DITTO_1_DE); +TRANS(UI_TEXT_DITTO_2_DE); +TRANS(UI_TEXT_DITTO_3_DE); +TRANS(UI_TEXT_ZPROBE_HEIGHT_DE); +TRANS(UI_TEXT_OFFSETS_DE); +TRANS(UI_TEXT_X_OFFSET_DE); +TRANS(UI_TEXT_Y_OFFSET_DE); +TRANS(UI_TEXT_Z_OFFSET_DE); + +PGM_P const translations_de[NUM_TRANSLATED_WORDS] PROGMEM = { + FUI_TEXT_ON_DE, + FUI_TEXT_OFF_DE, + FUI_TEXT_NA_DE, + FUI_TEXT_YES_DE, + FUI_TEXT_NO_DE, + FUI_TEXT_PRINT_POS_DE, + FUI_TEXT_PRINTING_DE, + FUI_TEXT_IDLE_DE, + FUI_TEXT_NOSDCARD_DE, + FUI_TEXT_ERROR_DE, + FUI_TEXT_BACK_DE, + FUI_TEXT_QUICK_SETTINGS_DE, + FUI_TEXT_ERRORMSG_DE, + FUI_TEXT_CONFIGURATION_DE, + FUI_TEXT_POSITION_DE, + FUI_TEXT_EXTRUDER_DE, + FUI_TEXT_SD_CARD_DE, + FUI_TEXT_DEBUGGING_DE, + FUI_TEXT_HOME_DELTA_DE, + FUI_TEXT_HOME_ALL_DE, + FUI_TEXT_HOME_X_DE, + FUI_TEXT_HOME_Y_DE, + FUI_TEXT_HOME_Z_DE, + FUI_TEXT_PREHEAT_PLA_DE, + FUI_TEXT_PREHEAT_ABS_DE, + FUI_TEXT_LIGHTS_ONOFF_DE, + FUI_TEXT_COOLDOWN_DE, + FUI_TEXT_SET_TO_ORIGIN_DE, + FUI_TEXT_DISABLE_STEPPER_DE, + FUI_TEXT_X_POSITION_DE, + FUI_TEXT_X_POS_FAST_DE, + FUI_TEXT_Y_POSITION_DE, + FUI_TEXT_Y_POS_FAST_DE, + FUI_TEXT_Z_POSITION_DE, + FUI_TEXT_Z_POS_FAST_DE, + FUI_TEXT_E_POSITION_DE, + FUI_TEXT_BED_TEMP_DE, + FUI_TEXT_EXTR0_TEMP_DE, + FUI_TEXT_EXTR1_TEMP_DE, + FUI_TEXT_EXTR2_TEMP_DE, + FUI_TEXT_EXTR0_OFF_DE, + FUI_TEXT_EXTR1_OFF_DE, + FUI_TEXT_EXTR2_OFF_DE, + FUI_TEXT_EXTR0_SELECT_DE, + FUI_TEXT_EXTR1_SELECT_DE, + FUI_TEXT_EXTR2_SELECT_DE, + FUI_TEXT_EXTR_ORIGIN_DE, + FUI_TEXT_PRINT_X_DE, + FUI_TEXT_PRINT_Y_DE, + FUI_TEXT_PRINT_Z_DE, + FUI_TEXT_PRINT_Z_DELTA_DE, + FUI_TEXT_MOVE_X_DE, + FUI_TEXT_MOVE_Y_DE, + FUI_TEXT_MOVE_Z_DE, + FUI_TEXT_MOVE_Z_DELTA_DE, + FUI_TEXT_JERK_DE, + FUI_TEXT_ZJERK_DE, + FUI_TEXT_ACCELERATION_DE, + FUI_TEXT_STORE_TO_EEPROM_DE, + FUI_TEXT_LOAD_EEPROM_DE, + FUI_TEXT_DBG_ECHO_DE, + FUI_TEXT_DBG_INFO_DE, + FUI_TEXT_DBG_ERROR_DE, + FUI_TEXT_DBG_DRYRUN_DE, + FUI_TEXT_OPS_OFF_DE, + FUI_TEXT_OPS_CLASSIC_DE, + FUI_TEXT_OPS_FAST_DE, + FUI_TEXT_OPS_RETRACT_DE, + FUI_TEXT_OPS_BACKSLASH_DE, + FUI_TEXT_OPS_MINDIST_DE, + FUI_TEXT_OPS_MOVE_AFTER_DE, + FUI_TEXT_ANTI_OOZE_DE, + FUI_TEXT_PRINT_FILE_DE, + FUI_TEXT_PAUSE_PRINT_DE, + FUI_TEXT_CONTINUE_PRINT_DE, + FUI_TEXT_UNMOUNT_CARD_DE, + FUI_TEXT_MOUNT_CARD_DE, + FUI_TEXT_DELETE_FILE_DE, + FUI_TEXT_FEEDRATE_DE, + FUI_TEXT_FEED_MAX_X_DE, + FUI_TEXT_FEED_MAX_Y_DE, + FUI_TEXT_FEED_MAX_Z_DE, + FUI_TEXT_FEED_MAX_Z_DELTA_DE, + FUI_TEXT_FEED_HOME_X_DE, + FUI_TEXT_FEED_HOME_Y_DE, + FUI_TEXT_FEED_HOME_Z_DE, + FUI_TEXT_FEED_HOME_Z_DELTA_DE, + FUI_TEXT_ACTION_XPOSITION4A_DE, + FUI_TEXT_ACTION_XPOSITION4B_DE, + FUI_TEXT_ACTION_XPOSITION4C_DE, + FUI_TEXT_ACTION_XPOSITION4D_DE, + FUI_TEXT_ACTION_YPOSITION4A_DE, + FUI_TEXT_ACTION_YPOSITION4B_DE, + FUI_TEXT_ACTION_YPOSITION4C_DE, + FUI_TEXT_ACTION_YPOSITION4D_DE, + FUI_TEXT_ACTION_ZPOSITION4A_DE, + FUI_TEXT_ACTION_ZPOSITION4B_DE, + FUI_TEXT_ACTION_ZPOSITION4C_DE, + FUI_TEXT_ACTION_ZPOSITION4D_DE, + FUI_TEXT_ACTION_XPOSITION_FAST4A_DE, + FUI_TEXT_ACTION_XPOSITION_FAST4B_DE, + FUI_TEXT_ACTION_XPOSITION_FAST4C_DE, + FUI_TEXT_ACTION_XPOSITION_FAST4D_DE, + FUI_TEXT_ACTION_YPOSITION_FAST4A_DE, + FUI_TEXT_ACTION_YPOSITION_FAST4B_DE, + FUI_TEXT_ACTION_YPOSITION_FAST4C_DE, + FUI_TEXT_ACTION_YPOSITION_FAST4D_DE, + FUI_TEXT_ACTION_ZPOSITION_FAST4A_DE, + FUI_TEXT_ACTION_ZPOSITION_FAST4B_DE, + FUI_TEXT_ACTION_ZPOSITION_FAST4C_DE, + FUI_TEXT_ACTION_ZPOSITION_FAST4D_DE, + FUI_TEXT_ACTION_EPOSITION_FAST2A_DE, + FUI_TEXT_ACTION_EPOSITION_FAST2B_DE, + FUI_TEXT_ACTION_XPOSITION2A_DE, + FUI_TEXT_ACTION_XPOSITION2B_DE, + FUI_TEXT_ACTION_YPOSITION2A_DE, + FUI_TEXT_ACTION_YPOSITION2B_DE, + FUI_TEXT_ACTION_ZPOSITION2A_DE, + FUI_TEXT_ACTION_ZPOSITION2B_DE, + FUI_TEXT_ACTION_XPOSITION_FAST2A_DE, + FUI_TEXT_ACTION_XPOSITION_FAST2B_DE, + FUI_TEXT_ACTION_YPOSITION_FAST2A_DE, + FUI_TEXT_ACTION_YPOSITION_FAST2B_DE, + FUI_TEXT_ACTION_ZPOSITION_FAST2A_DE, + FUI_TEXT_ACTION_ZPOSITION_FAST2B_DE, + FUI_TEXT_FANSPEED_DE, + FUI_TEXT_ACTION_FANSPEED_DE, + FUI_TEXT_FAN_OFF_DE, + FUI_TEXT_FAN_25_DE, + FUI_TEXT_FAN_50_DE, + FUI_TEXT_FAN_75_DE, + FUI_TEXT_FAN_FULL_DE, + FUI_TEXT_STEPPER_INACTIVE_DE, + FUI_TEXT_STEPPER_INACTIVE2A_DE, + FUI_TEXT_STEPPER_INACTIVE2B_DE, + FUI_TEXT_POWER_INACTIVE_DE, + FUI_TEXT_POWER_INACTIVE2A_DE, + FUI_TEXT_POWER_INACTIVE2B_DE, + FUI_TEXT_GENERAL_DE, + FUI_TEXT_BAUDRATE_DE, + FUI_TEXT_EXTR_STEPS_DE, + FUI_TEXT_EXTR_START_FEED_DE, + FUI_TEXT_EXTR_MAX_FEED_DE, + FUI_TEXT_EXTR_ACCEL_DE, + FUI_TEXT_EXTR_WATCH_DE, + FUI_TEXT_EXTR_ADVANCE_L_DE, + FUI_TEXT_EXTR_ADVANCE_K_DE, + FUI_TEXT_EXTR_MANAGER_DE, + FUI_TEXT_EXTR_PGAIN_DE, + FUI_TEXT_EXTR_DEADTIME_DE, + FUI_TEXT_EXTR_DMAX_DT_DE, + FUI_TEXT_EXTR_IGAIN_DE, + FUI_TEXT_EXTR_DGAIN_DE, + FUI_TEXT_EXTR_DMIN_DE, + FUI_TEXT_EXTR_DMAX_DE, + FUI_TEXT_EXTR_PMAX_DE, + FUI_TEXT_EXTR_XOFF_DE, + FUI_TEXT_EXTR_YOFF_DE, + FUI_TEXT_STRING_HM_BANGBANG_DE, + FUI_TEXT_STRING_HM_PID_DE, + FUI_TEXT_STRING_ACTION_DE, + FUI_TEXT_HEATING_EXTRUDER_DE, + FUI_TEXT_HEATING_BED_DE, + FUI_TEXT_KILLED_DE, + FUI_TEXT_STEPPER_DISABLED_DE, + FUI_TEXT_EEPROM_STOREDA_DE, + FUI_TEXT_EEPROM_STOREDB_DE, + FUI_TEXT_EEPROM_LOADEDA_DE, + FUI_TEXT_EEPROM_LOADEDB_DE, + FUI_TEXT_UPLOADING_DE, + FUI_TEXT_PAGE_BUFFER_DE, + FUI_TEXT_PAGE_EXTRUDER_DE, + FUI_TEXT_PAGE_EXTRUDER1_DE, + FUI_TEXT_PAGE_EXTRUDER2_DE, + FUI_TEXT_PAGE_EXTRUDER3_DE, + FUI_TEXT_PAGE_BED_DE, + FUI_TEXT_SPEED_MULTIPLY_DE, + FUI_TEXT_FLOW_MULTIPLY_DE, + FUI_TEXT_SHOW_MEASUREMENT_DE, + FUI_TEXT_RESET_MEASUREMENT_DE, + FUI_TEXT_SET_MEASURED_ORIGIN_DE, + FUI_TEXT_ZCALIB_DE, + FUI_TEXT_SET_P1_DE, + FUI_TEXT_SET_P2_DE, + FUI_TEXT_SET_P3_DE, + FUI_TEXT_CALCULATE_LEVELING_DE, + FUI_TEXT_LEVEL_DE, + FUI_TEXT_EXTR_WAIT_RETRACT_TEMP_DE, + FUI_TEXT_EXTR_WAIT_RETRACT_UNITS_DE, + FUI_TEXT_SD_REMOVED_DE, + FUI_TEXT_SD_INSERTED_DE, + FUI_TEXT_PRINTER_READY_DE, + FUI_TEXT_PRINTTIME_DAYS_DE, + FUI_TEXT_PRINTTIME_HOURS_DE, + FUI_TEXT_PRINTTIME_MINUTES_DE, + FUI_TEXT_PRINT_TIME_DE, + FUI_TEXT_PRINT_FILAMENT_DE, + FUI_TEXT_PRINTED_DE, + FUI_TEXT_POWER_DE, + FUI_TEXT_STRING_HM_DEADTIME_DE, + FUI_TEXT_STRING_HM_SLOWBANG_DE, + FUI_TEXT_STOP_PRINT_DE, + FUI_TEXT_Z_BABYSTEPPING_DE, + FUI_TEXT_CHANGE_FILAMENT_DE, + FUI_TEXT_WIZ_CH_FILAMENT1_DE, + FUI_TEXT_WIZ_CH_FILAMENT2_DE, + FUI_TEXT_WIZ_CH_FILAMENT3_DE, + FUI_TEXT_CLICK_DONE_DE, + FUI_TEXT_AUTOLEVEL_ONOFF_DE, + FUI_TEXT_SERVOPOS_DE, + FUI_TEXT_IGNORE_M106_DE, + FUI_TEXT_WIZ_REHEAT1_DE, + FUI_TEXT_WIZ_REHEAT2_DE, + FUI_TEXT_WIZ_WAITTEMP1_DE, + FUI_TEXT_WIZ_WAITTEMP2_DE, + FUI_TEXT_EXTRUDER_JAM_DE, + FUI_TEXT_STANDBY_DE, + FUI_TEXT_BED_COATING_DE, + FUI_TEXT_BED_COATING_SET1_DE, + FUI_TEXT_BED_COATING_SET2_DE, + FUI_TEXT_NOCOATING_DE, + FUI_TEXT_BUILDTAK_DE, + FUI_TEXT_KAPTON_DE, + FUI_TEXT_BLUETAPE_DE, + FUI_TEXT_PETTAPE_DE, + FUI_TEXT_GLUESTICK_DE, + FUI_TEXT_CUSTOM_DE, + FUI_TEXT_COATING_CUSTOM_DE, + FUI_TEXT_LANGUAGE_DE, + FUI_TEXT_MAINPAGE6_1_DE, + FUI_TEXT_MAINPAGE6_2_DE, + FUI_TEXT_MAINPAGE6_3_DE, + FUI_TEXT_MAINPAGE6_4_DE, + FUI_TEXT_MAINPAGE6_5_DE, + FUI_TEXT_MAINPAGE6_6_DE, + FUI_TEXT_MAINPAGE_TEMP_BED_DE, + FUI_TEXT_MAINPAGE_BED_DE, + FUI_TEXT_MAINPAGE_Z_BUF_DE, + FUI_TEXT_MAINPAGE_MUL_EUSAGE_DE, + FUI_TEXT_MAINPAGE_XY_DE, + FUI_TEXT_PRINT_TIME_VALUE_DE, + FUI_TEXT_PRINT_FILAMENT_VALUE_DE, + FUI_TEXT_METER_PRINTED_DE, + FUI_TEXT_STATUS_DE, + FUI_TEXT_EMPTY_DE, + FUI_TEXT_TEMP_SET_DE, + FUI_TEXT_CURRENT_TEMP_DE, + FUI_TEXT_COATING_THICKNESS_DE, + FUI_TEXT_EXTR3_TEMP_DE, + FUI_TEXT_EXTR4_TEMP_DE, + FUI_TEXT_EXTR5_TEMP_DE, + FUI_TEXT_EXTR3_OFF_DE, + FUI_TEXT_EXTR4_OFF_DE, + FUI_TEXT_EXTR5_OFF_DE, + FUI_TEXT_EXTR3_SELECT_DE, + FUI_TEXT_EXTR4_SELECT_DE, + FUI_TEXT_EXTR5_SELECT_DE, + FUI_TEXT_DITTO_0_DE, + FUI_TEXT_DITTO_1_DE, + FUI_TEXT_DITTO_2_DE, + FUI_TEXT_DITTO_3_DE, + FUI_TEXT_ZPROBE_HEIGHT_DE, + FUI_TEXT_OFFSETS_DE, + FUI_TEXT_X_OFFSET_DE, + FUI_TEXT_Y_OFFSET_DE, + FUI_TEXT_Z_OFFSET_DE, + FUI_TEXT_DBG_ENDSTOP_DE +}; +#define LANG_DE_TABLE translations_de +#else +#define LANG_DE_TABLE NULL +#endif // LANGUAGE_DE_ACTIVE + +#if LANGUAGE_NL_ACTIVE +TRANS(UI_TEXT_ON_NL); +TRANS(UI_TEXT_OFF_NL); +TRANS(UI_TEXT_NA_NL); +TRANS(UI_TEXT_YES_NL); +TRANS(UI_TEXT_NO_NL); +TRANS(UI_TEXT_PRINT_POS_NL); +TRANS(UI_TEXT_PRINTING_NL); +TRANS(UI_TEXT_IDLE_NL); +TRANS(UI_TEXT_NOSDCARD_NL); +TRANS(UI_TEXT_ERROR_NL); +TRANS(UI_TEXT_BACK_NL); +TRANS(UI_TEXT_QUICK_SETTINGS_NL); +TRANS(UI_TEXT_ERRORMSG_NL); +TRANS(UI_TEXT_CONFIGURATION_NL); +TRANS(UI_TEXT_POSITION_NL); +TRANS(UI_TEXT_EXTRUDER_NL); +TRANS(UI_TEXT_SD_CARD_NL); +TRANS(UI_TEXT_DEBUGGING_NL); +TRANS(UI_TEXT_HOME_DELTA_NL); +TRANS(UI_TEXT_HOME_ALL_NL); +TRANS(UI_TEXT_HOME_X_NL); +TRANS(UI_TEXT_HOME_Y_NL); +TRANS(UI_TEXT_HOME_Z_NL); +TRANS(UI_TEXT_PREHEAT_PLA_NL); +TRANS(UI_TEXT_PREHEAT_ABS_NL); +TRANS(UI_TEXT_LIGHTS_ONOFF_NL); +TRANS(UI_TEXT_COOLDOWN_NL); +TRANS(UI_TEXT_SET_TO_ORIGIN_NL); +TRANS(UI_TEXT_DISABLE_STEPPER_NL); +TRANS(UI_TEXT_X_POSITION_NL); +TRANS(UI_TEXT_X_POS_FAST_NL); +TRANS(UI_TEXT_Y_POSITION_NL); +TRANS(UI_TEXT_Y_POS_FAST_NL); +TRANS(UI_TEXT_Z_POSITION_NL); +TRANS(UI_TEXT_Z_POS_FAST_NL); +TRANS(UI_TEXT_E_POSITION_NL); +TRANS(UI_TEXT_BED_TEMP_NL); +TRANS(UI_TEXT_EXTR0_TEMP_NL); +TRANS(UI_TEXT_EXTR1_TEMP_NL); +TRANS(UI_TEXT_EXTR2_TEMP_NL); +TRANS(UI_TEXT_EXTR0_OFF_NL); +TRANS(UI_TEXT_EXTR1_OFF_NL); +TRANS(UI_TEXT_EXTR2_OFF_NL); +TRANS(UI_TEXT_EXTR0_SELECT_NL); +TRANS(UI_TEXT_EXTR1_SELECT_NL); +TRANS(UI_TEXT_EXTR2_SELECT_NL); +TRANS(UI_TEXT_EXTR_ORIGIN_NL); +TRANS(UI_TEXT_PRINT_X_NL); +TRANS(UI_TEXT_PRINT_Y_NL); +TRANS(UI_TEXT_PRINT_Z_NL); +TRANS(UI_TEXT_PRINT_Z_DELTA_NL); +TRANS(UI_TEXT_MOVE_X_NL); +TRANS(UI_TEXT_MOVE_Y_NL); +TRANS(UI_TEXT_MOVE_Z_NL); +TRANS(UI_TEXT_MOVE_Z_DELTA_NL); +TRANS(UI_TEXT_JERK_NL); +TRANS(UI_TEXT_ZJERK_NL); +TRANS(UI_TEXT_ACCELERATION_NL); +TRANS(UI_TEXT_STORE_TO_EEPROM_NL); +TRANS(UI_TEXT_LOAD_EEPROM_NL); +TRANS(UI_TEXT_DBG_ECHO_NL); +TRANS(UI_TEXT_DBG_INFO_NL); +TRANS(UI_TEXT_DBG_ERROR_NL); +TRANS(UI_TEXT_DBG_DRYRUN_NL); +TRANS(UI_TEXT_DBG_ENDSTOP_NL); +TRANS(UI_TEXT_OPS_OFF_NL); +TRANS(UI_TEXT_OPS_CLASSIC_NL); +TRANS(UI_TEXT_OPS_FAST_NL); +TRANS(UI_TEXT_OPS_RETRACT_NL); +TRANS(UI_TEXT_OPS_BACKSLASH_NL); +TRANS(UI_TEXT_OPS_MINDIST_NL); +TRANS(UI_TEXT_OPS_MOVE_AFTER_NL); +TRANS(UI_TEXT_ANTI_OOZE_NL); +TRANS(UI_TEXT_PRINT_FILE_NL); +TRANS(UI_TEXT_PAUSE_PRINT_NL); +TRANS(UI_TEXT_CONTINUE_PRINT_NL); +TRANS(UI_TEXT_UNMOUNT_CARD_NL); +TRANS(UI_TEXT_MOUNT_CARD_NL); +TRANS(UI_TEXT_DELETE_FILE_NL); +TRANS(UI_TEXT_FEEDRATE_NL); +TRANS(UI_TEXT_FEED_MAX_X_NL); +TRANS(UI_TEXT_FEED_MAX_Y_NL); +TRANS(UI_TEXT_FEED_MAX_Z_NL); +TRANS(UI_TEXT_FEED_MAX_Z_DELTA_NL); +TRANS(UI_TEXT_FEED_HOME_X_NL); +TRANS(UI_TEXT_FEED_HOME_Y_NL); +TRANS(UI_TEXT_FEED_HOME_Z_NL); +TRANS(UI_TEXT_FEED_HOME_Z_DELTA_NL); +TRANS(UI_TEXT_ACTION_XPOSITION4A_NL); +TRANS(UI_TEXT_ACTION_XPOSITION4B_NL); +TRANS(UI_TEXT_ACTION_XPOSITION4C_NL); +TRANS(UI_TEXT_ACTION_XPOSITION4D_NL); +TRANS(UI_TEXT_ACTION_YPOSITION4A_NL); +TRANS(UI_TEXT_ACTION_YPOSITION4B_NL); +TRANS(UI_TEXT_ACTION_YPOSITION4C_NL); +TRANS(UI_TEXT_ACTION_YPOSITION4D_NL); +TRANS(UI_TEXT_ACTION_ZPOSITION4A_NL); +TRANS(UI_TEXT_ACTION_ZPOSITION4B_NL); +TRANS(UI_TEXT_ACTION_ZPOSITION4C_NL); +TRANS(UI_TEXT_ACTION_ZPOSITION4D_NL); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST4A_NL); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST4B_NL); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST4C_NL); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST4D_NL); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST4A_NL); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST4B_NL); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST4C_NL); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST4D_NL); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST4A_NL); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST4B_NL); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST4C_NL); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST4D_NL); +TRANS(UI_TEXT_ACTION_EPOSITION_FAST2A_NL); +TRANS(UI_TEXT_ACTION_EPOSITION_FAST2B_NL); +TRANS(UI_TEXT_ACTION_XPOSITION2A_NL); +TRANS(UI_TEXT_ACTION_XPOSITION2B_NL); +TRANS(UI_TEXT_ACTION_YPOSITION2A_NL); +TRANS(UI_TEXT_ACTION_YPOSITION2B_NL); +TRANS(UI_TEXT_ACTION_ZPOSITION2A_NL); +TRANS(UI_TEXT_ACTION_ZPOSITION2B_NL); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST2A_NL); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST2B_NL); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST2A_NL); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST2B_NL); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST2A_NL); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST2B_NL); +TRANS(UI_TEXT_FANSPEED_NL); +TRANS(UI_TEXT_ACTION_FANSPEED_NL); +TRANS(UI_TEXT_FAN_OFF_NL); +TRANS(UI_TEXT_FAN_25_NL); +TRANS(UI_TEXT_FAN_50_NL); +TRANS(UI_TEXT_FAN_75_NL); +TRANS(UI_TEXT_FAN_FULL_NL); +TRANS(UI_TEXT_STEPPER_INACTIVE_NL); +TRANS(UI_TEXT_STEPPER_INACTIVE2A_NL); +TRANS(UI_TEXT_STEPPER_INACTIVE2B_NL); +TRANS(UI_TEXT_POWER_INACTIVE_NL); +TRANS(UI_TEXT_POWER_INACTIVE2A_NL); +TRANS(UI_TEXT_POWER_INACTIVE2B_NL); +TRANS(UI_TEXT_GENERAL_NL); +TRANS(UI_TEXT_BAUDRATE_NL); +TRANS(UI_TEXT_EXTR_STEPS_NL); +TRANS(UI_TEXT_EXTR_START_FEED_NL); +TRANS(UI_TEXT_EXTR_MAX_FEED_NL); +TRANS(UI_TEXT_EXTR_ACCEL_NL); +TRANS(UI_TEXT_EXTR_WATCH_NL); +TRANS(UI_TEXT_EXTR_ADVANCE_L_NL); +TRANS(UI_TEXT_EXTR_ADVANCE_K_NL); +TRANS(UI_TEXT_EXTR_MANAGER_NL); +TRANS(UI_TEXT_EXTR_PGAIN_NL); +TRANS(UI_TEXT_EXTR_DEADTIME_NL); +TRANS(UI_TEXT_EXTR_DMAX_DT_NL); +TRANS(UI_TEXT_EXTR_IGAIN_NL); +TRANS(UI_TEXT_EXTR_DGAIN_NL); +TRANS(UI_TEXT_EXTR_DMIN_NL); +TRANS(UI_TEXT_EXTR_DMAX_NL); +TRANS(UI_TEXT_EXTR_PMAX_NL); +TRANS(UI_TEXT_EXTR_XOFF_NL); +TRANS(UI_TEXT_EXTR_YOFF_NL); +TRANS(UI_TEXT_STRING_HM_BANGBANG_NL); +TRANS(UI_TEXT_STRING_HM_PID_NL); +TRANS(UI_TEXT_STRING_ACTION_NL); +TRANS(UI_TEXT_HEATING_EXTRUDER_NL); +TRANS(UI_TEXT_HEATING_BED_NL); +TRANS(UI_TEXT_KILLED_NL); +TRANS(UI_TEXT_STEPPER_DISABLED_NL); +TRANS(UI_TEXT_EEPROM_STOREDA_NL); +TRANS(UI_TEXT_EEPROM_STOREDB_NL); +TRANS(UI_TEXT_EEPROM_LOADEDA_NL); +TRANS(UI_TEXT_EEPROM_LOADEDB_NL); +TRANS(UI_TEXT_UPLOADING_NL); +TRANS(UI_TEXT_PAGE_BUFFER_NL); +TRANS(UI_TEXT_PAGE_EXTRUDER_NL); +TRANS(UI_TEXT_PAGE_EXTRUDER1_NL); +TRANS(UI_TEXT_PAGE_EXTRUDER2_NL); +TRANS(UI_TEXT_PAGE_EXTRUDER3_NL); +TRANS(UI_TEXT_PAGE_BED_NL); +TRANS(UI_TEXT_SPEED_MULTIPLY_NL); +TRANS(UI_TEXT_FLOW_MULTIPLY_NL); +TRANS(UI_TEXT_SHOW_MEASUREMENT_NL); +TRANS(UI_TEXT_RESET_MEASUREMENT_NL); +TRANS(UI_TEXT_SET_MEASURED_ORIGIN_NL); +TRANS(UI_TEXT_ZCALIB_NL); +TRANS(UI_TEXT_SET_P1_NL); +TRANS(UI_TEXT_SET_P2_NL); +TRANS(UI_TEXT_SET_P3_NL); +TRANS(UI_TEXT_CALCULATE_LEVELING_NL); +TRANS(UI_TEXT_LEVEL_NL); +TRANS(UI_TEXT_EXTR_WAIT_RETRACT_TEMP_NL); +TRANS(UI_TEXT_EXTR_WAIT_RETRACT_UNITS_NL); +TRANS(UI_TEXT_SD_REMOVED_NL); +TRANS(UI_TEXT_SD_INSERTED_NL); +TRANS(UI_TEXT_PRINTER_READY_NL); +TRANS(UI_TEXT_PRINTTIME_DAYS_NL); +TRANS(UI_TEXT_PRINTTIME_HOURS_NL); +TRANS(UI_TEXT_PRINTTIME_MINUTES_NL); +TRANS(UI_TEXT_PRINT_TIME_NL); +TRANS(UI_TEXT_PRINT_FILAMENT_NL); +TRANS(UI_TEXT_PRINTED_NL); +TRANS(UI_TEXT_POWER_NL); +TRANS(UI_TEXT_STRING_HM_DEADTIME_NL); +TRANS(UI_TEXT_STRING_HM_SLOWBANG_NL); +TRANS(UI_TEXT_STOP_PRINT_NL); +TRANS(UI_TEXT_Z_BABYSTEPPING_NL); +TRANS(UI_TEXT_CHANGE_FILAMENT_NL); +TRANS(UI_TEXT_WIZ_CH_FILAMENT1_NL); +TRANS(UI_TEXT_WIZ_CH_FILAMENT2_NL); +TRANS(UI_TEXT_WIZ_CH_FILAMENT3_NL); +TRANS(UI_TEXT_CLICK_DONE_NL); +TRANS(UI_TEXT_AUTOLEVEL_ONOFF_NL); +TRANS(UI_TEXT_SERVOPOS_NL); +TRANS(UI_TEXT_IGNORE_M106_NL); +TRANS(UI_TEXT_WIZ_REHEAT1_NL); +TRANS(UI_TEXT_WIZ_REHEAT2_NL); +TRANS(UI_TEXT_WIZ_WAITTEMP1_NL); +TRANS(UI_TEXT_WIZ_WAITTEMP2_NL); +TRANS(UI_TEXT_EXTRUDER_JAM_NL); +TRANS(UI_TEXT_STANDBY_NL); +TRANS(UI_TEXT_BED_COATING_NL); +TRANS(UI_TEXT_BED_COATING_SET1_NL); +TRANS(UI_TEXT_BED_COATING_SET2_NL); +TRANS(UI_TEXT_NOCOATING_NL); +TRANS(UI_TEXT_BUILDTAK_NL); +TRANS(UI_TEXT_KAPTON_NL); +TRANS(UI_TEXT_BLUETAPE_NL); +TRANS(UI_TEXT_PETTAPE_NL); +TRANS(UI_TEXT_GLUESTICK_NL); +TRANS(UI_TEXT_CUSTOM_NL); +TRANS(UI_TEXT_COATING_CUSTOM_NL); +TRANS(UI_TEXT_LANGUAGE_NL); +TRANS(UI_TEXT_MAINPAGE6_1_NL); +TRANS(UI_TEXT_MAINPAGE6_2_NL); +TRANS(UI_TEXT_MAINPAGE6_3_NL); +TRANS(UI_TEXT_MAINPAGE6_4_NL); +TRANS(UI_TEXT_MAINPAGE6_5_NL); +TRANS(UI_TEXT_MAINPAGE6_6_NL); +TRANS(UI_TEXT_MAINPAGE_TEMP_BED_NL); +TRANS(UI_TEXT_MAINPAGE_BED_NL); +TRANS(UI_TEXT_MAINPAGE_Z_BUF_NL); +TRANS(UI_TEXT_MAINPAGE_MUL_EUSAGE_NL); +TRANS(UI_TEXT_MAINPAGE_XY_NL); +TRANS(UI_TEXT_PRINT_TIME_VALUE_NL); +TRANS(UI_TEXT_PRINT_FILAMENT_VALUE_NL); +TRANS(UI_TEXT_METER_PRINTED_NL); +TRANS(UI_TEXT_STATUS_NL); +TRANS(UI_TEXT_EMPTY_NL); +TRANS(UI_TEXT_TEMP_SET_NL); +TRANS(UI_TEXT_CURRENT_TEMP_NL); +TRANS(UI_TEXT_COATING_THICKNESS_NL); +TRANS(UI_TEXT_EXTR3_TEMP_NL); +TRANS(UI_TEXT_EXTR4_TEMP_NL); +TRANS(UI_TEXT_EXTR5_TEMP_NL); +TRANS(UI_TEXT_EXTR3_OFF_NL); +TRANS(UI_TEXT_EXTR4_OFF_NL); +TRANS(UI_TEXT_EXTR5_OFF_NL); +TRANS(UI_TEXT_EXTR3_SELECT_NL); +TRANS(UI_TEXT_EXTR4_SELECT_NL); +TRANS(UI_TEXT_EXTR5_SELECT_NL); +TRANS(UI_TEXT_DITTO_0_NL); +TRANS(UI_TEXT_DITTO_1_NL); +TRANS(UI_TEXT_DITTO_2_NL); +TRANS(UI_TEXT_DITTO_3_NL); +TRANS(UI_TEXT_ZPROBE_HEIGHT_NL); +TRANS(UI_TEXT_OFFSETS_NL); +TRANS(UI_TEXT_X_OFFSET_NL); +TRANS(UI_TEXT_Y_OFFSET_NL); +TRANS(UI_TEXT_Z_OFFSET_NL); + +PGM_P const translations_nl[NUM_TRANSLATED_WORDS] PROGMEM = { + FUI_TEXT_ON_NL, + FUI_TEXT_OFF_NL, + FUI_TEXT_NA_NL, + FUI_TEXT_YES_NL, + FUI_TEXT_NO_NL, + FUI_TEXT_PRINT_POS_NL, + FUI_TEXT_PRINTING_NL, + FUI_TEXT_IDLE_NL, + FUI_TEXT_NOSDCARD_NL, + FUI_TEXT_ERROR_NL, + FUI_TEXT_BACK_NL, + FUI_TEXT_QUICK_SETTINGS_NL, + FUI_TEXT_ERRORMSG_NL, + FUI_TEXT_CONFIGURATION_NL, + FUI_TEXT_POSITION_NL, + FUI_TEXT_EXTRUDER_NL, + FUI_TEXT_SD_CARD_NL, + FUI_TEXT_DEBUGGING_NL, + FUI_TEXT_HOME_DELTA_NL, + FUI_TEXT_HOME_ALL_NL, + FUI_TEXT_HOME_X_NL, + FUI_TEXT_HOME_Y_NL, + FUI_TEXT_HOME_Z_NL, + FUI_TEXT_PREHEAT_PLA_NL, + FUI_TEXT_PREHEAT_ABS_NL, + FUI_TEXT_LIGHTS_ONOFF_NL, + FUI_TEXT_COOLDOWN_NL, + FUI_TEXT_SET_TO_ORIGIN_NL, + FUI_TEXT_DISABLE_STEPPER_NL, + FUI_TEXT_X_POSITION_NL, + FUI_TEXT_X_POS_FAST_NL, + FUI_TEXT_Y_POSITION_NL, + FUI_TEXT_Y_POS_FAST_NL, + FUI_TEXT_Z_POSITION_NL, + FUI_TEXT_Z_POS_FAST_NL, + FUI_TEXT_E_POSITION_NL, + FUI_TEXT_BED_TEMP_NL, + FUI_TEXT_EXTR0_TEMP_NL, + FUI_TEXT_EXTR1_TEMP_NL, + FUI_TEXT_EXTR2_TEMP_NL, + FUI_TEXT_EXTR0_OFF_NL, + FUI_TEXT_EXTR1_OFF_NL, + FUI_TEXT_EXTR2_OFF_NL, + FUI_TEXT_EXTR0_SELECT_NL, + FUI_TEXT_EXTR1_SELECT_NL, + FUI_TEXT_EXTR2_SELECT_NL, + FUI_TEXT_EXTR_ORIGIN_NL, + FUI_TEXT_PRINT_X_NL, + FUI_TEXT_PRINT_Y_NL, + FUI_TEXT_PRINT_Z_NL, + FUI_TEXT_PRINT_Z_DELTA_NL, + FUI_TEXT_MOVE_X_NL, + FUI_TEXT_MOVE_Y_NL, + FUI_TEXT_MOVE_Z_NL, + FUI_TEXT_MOVE_Z_DELTA_NL, + FUI_TEXT_JERK_NL, + FUI_TEXT_ZJERK_NL, + FUI_TEXT_ACCELERATION_NL, + FUI_TEXT_STORE_TO_EEPROM_NL, + FUI_TEXT_LOAD_EEPROM_NL, + FUI_TEXT_DBG_ECHO_NL, + FUI_TEXT_DBG_INFO_NL, + FUI_TEXT_DBG_ERROR_NL, + FUI_TEXT_DBG_DRYRUN_NL, + FUI_TEXT_OPS_OFF_NL, + FUI_TEXT_OPS_CLASSIC_NL, + FUI_TEXT_OPS_FAST_NL, + FUI_TEXT_OPS_RETRACT_NL, + FUI_TEXT_OPS_BACKSLASH_NL, + FUI_TEXT_OPS_MINDIST_NL, + FUI_TEXT_OPS_MOVE_AFTER_NL, + FUI_TEXT_ANTI_OOZE_NL, + FUI_TEXT_PRINT_FILE_NL, + FUI_TEXT_PAUSE_PRINT_NL, + FUI_TEXT_CONTINUE_PRINT_NL, + FUI_TEXT_UNMOUNT_CARD_NL, + FUI_TEXT_MOUNT_CARD_NL, + FUI_TEXT_DELETE_FILE_NL, + FUI_TEXT_FEEDRATE_NL, + FUI_TEXT_FEED_MAX_X_NL, + FUI_TEXT_FEED_MAX_Y_NL, + FUI_TEXT_FEED_MAX_Z_NL, + FUI_TEXT_FEED_MAX_Z_DELTA_NL, + FUI_TEXT_FEED_HOME_X_NL, + FUI_TEXT_FEED_HOME_Y_NL, + FUI_TEXT_FEED_HOME_Z_NL, + FUI_TEXT_FEED_HOME_Z_DELTA_NL, + FUI_TEXT_ACTION_XPOSITION4A_NL, + FUI_TEXT_ACTION_XPOSITION4B_NL, + FUI_TEXT_ACTION_XPOSITION4C_NL, + FUI_TEXT_ACTION_XPOSITION4D_NL, + FUI_TEXT_ACTION_YPOSITION4A_NL, + FUI_TEXT_ACTION_YPOSITION4B_NL, + FUI_TEXT_ACTION_YPOSITION4C_NL, + FUI_TEXT_ACTION_YPOSITION4D_NL, + FUI_TEXT_ACTION_ZPOSITION4A_NL, + FUI_TEXT_ACTION_ZPOSITION4B_NL, + FUI_TEXT_ACTION_ZPOSITION4C_NL, + FUI_TEXT_ACTION_ZPOSITION4D_NL, + FUI_TEXT_ACTION_XPOSITION_FAST4A_NL, + FUI_TEXT_ACTION_XPOSITION_FAST4B_NL, + FUI_TEXT_ACTION_XPOSITION_FAST4C_NL, + FUI_TEXT_ACTION_XPOSITION_FAST4D_NL, + FUI_TEXT_ACTION_YPOSITION_FAST4A_NL, + FUI_TEXT_ACTION_YPOSITION_FAST4B_NL, + FUI_TEXT_ACTION_YPOSITION_FAST4C_NL, + FUI_TEXT_ACTION_YPOSITION_FAST4D_NL, + FUI_TEXT_ACTION_ZPOSITION_FAST4A_NL, + FUI_TEXT_ACTION_ZPOSITION_FAST4B_NL, + FUI_TEXT_ACTION_ZPOSITION_FAST4C_NL, + FUI_TEXT_ACTION_ZPOSITION_FAST4D_NL, + FUI_TEXT_ACTION_EPOSITION_FAST2A_NL, + FUI_TEXT_ACTION_EPOSITION_FAST2B_NL, + FUI_TEXT_ACTION_XPOSITION2A_NL, + FUI_TEXT_ACTION_XPOSITION2B_NL, + FUI_TEXT_ACTION_YPOSITION2A_NL, + FUI_TEXT_ACTION_YPOSITION2B_NL, + FUI_TEXT_ACTION_ZPOSITION2A_NL, + FUI_TEXT_ACTION_ZPOSITION2B_NL, + FUI_TEXT_ACTION_XPOSITION_FAST2A_NL, + FUI_TEXT_ACTION_XPOSITION_FAST2B_NL, + FUI_TEXT_ACTION_YPOSITION_FAST2A_NL, + FUI_TEXT_ACTION_YPOSITION_FAST2B_NL, + FUI_TEXT_ACTION_ZPOSITION_FAST2A_NL, + FUI_TEXT_ACTION_ZPOSITION_FAST2B_NL, + FUI_TEXT_FANSPEED_NL, + FUI_TEXT_ACTION_FANSPEED_NL, + FUI_TEXT_FAN_OFF_NL, + FUI_TEXT_FAN_25_NL, + FUI_TEXT_FAN_50_NL, + FUI_TEXT_FAN_75_NL, + FUI_TEXT_FAN_FULL_NL, + FUI_TEXT_STEPPER_INACTIVE_NL, + FUI_TEXT_STEPPER_INACTIVE2A_NL, + FUI_TEXT_STEPPER_INACTIVE2B_NL, + FUI_TEXT_POWER_INACTIVE_NL, + FUI_TEXT_POWER_INACTIVE2A_NL, + FUI_TEXT_POWER_INACTIVE2B_NL, + FUI_TEXT_GENERAL_NL, + FUI_TEXT_BAUDRATE_NL, + FUI_TEXT_EXTR_STEPS_NL, + FUI_TEXT_EXTR_START_FEED_NL, + FUI_TEXT_EXTR_MAX_FEED_NL, + FUI_TEXT_EXTR_ACCEL_NL, + FUI_TEXT_EXTR_WATCH_NL, + FUI_TEXT_EXTR_ADVANCE_L_NL, + FUI_TEXT_EXTR_ADVANCE_K_NL, + FUI_TEXT_EXTR_MANAGER_NL, + FUI_TEXT_EXTR_PGAIN_NL, + FUI_TEXT_EXTR_DEADTIME_NL, + FUI_TEXT_EXTR_DMAX_DT_NL, + FUI_TEXT_EXTR_IGAIN_NL, + FUI_TEXT_EXTR_DGAIN_NL, + FUI_TEXT_EXTR_DMIN_NL, + FUI_TEXT_EXTR_DMAX_NL, + FUI_TEXT_EXTR_PMAX_NL, + FUI_TEXT_EXTR_XOFF_NL, + FUI_TEXT_EXTR_YOFF_NL, + FUI_TEXT_STRING_HM_BANGBANG_NL, + FUI_TEXT_STRING_HM_PID_NL, + FUI_TEXT_STRING_ACTION_NL, + FUI_TEXT_HEATING_EXTRUDER_NL, + FUI_TEXT_HEATING_BED_NL, + FUI_TEXT_KILLED_NL, + FUI_TEXT_STEPPER_DISABLED_NL, + FUI_TEXT_EEPROM_STOREDA_NL, + FUI_TEXT_EEPROM_STOREDB_NL, + FUI_TEXT_EEPROM_LOADEDA_NL, + FUI_TEXT_EEPROM_LOADEDB_NL, + FUI_TEXT_UPLOADING_NL, + FUI_TEXT_PAGE_BUFFER_NL, + FUI_TEXT_PAGE_EXTRUDER_NL, + FUI_TEXT_PAGE_EXTRUDER1_NL, + FUI_TEXT_PAGE_EXTRUDER2_NL, + FUI_TEXT_PAGE_EXTRUDER3_NL, + FUI_TEXT_PAGE_BED_NL, + FUI_TEXT_SPEED_MULTIPLY_NL, + FUI_TEXT_FLOW_MULTIPLY_NL, + FUI_TEXT_SHOW_MEASUREMENT_NL, + FUI_TEXT_RESET_MEASUREMENT_NL, + FUI_TEXT_SET_MEASURED_ORIGIN_NL, + FUI_TEXT_ZCALIB_NL, + FUI_TEXT_SET_P1_NL, + FUI_TEXT_SET_P2_NL, + FUI_TEXT_SET_P3_NL, + FUI_TEXT_CALCULATE_LEVELING_NL, + FUI_TEXT_LEVEL_NL, + FUI_TEXT_EXTR_WAIT_RETRACT_TEMP_NL, + FUI_TEXT_EXTR_WAIT_RETRACT_UNITS_NL, + FUI_TEXT_SD_REMOVED_NL, + FUI_TEXT_SD_INSERTED_NL, + FUI_TEXT_PRINTER_READY_NL, + FUI_TEXT_PRINTTIME_DAYS_NL, + FUI_TEXT_PRINTTIME_HOURS_NL, + FUI_TEXT_PRINTTIME_MINUTES_NL, + FUI_TEXT_PRINT_TIME_NL, + FUI_TEXT_PRINT_FILAMENT_NL, + FUI_TEXT_PRINTED_NL, + FUI_TEXT_POWER_NL, + FUI_TEXT_STRING_HM_DEADTIME_NL, + FUI_TEXT_STRING_HM_SLOWBANG_NL, + FUI_TEXT_STOP_PRINT_NL, + FUI_TEXT_Z_BABYSTEPPING_NL, + FUI_TEXT_CHANGE_FILAMENT_NL, + FUI_TEXT_WIZ_CH_FILAMENT1_NL, + FUI_TEXT_WIZ_CH_FILAMENT2_NL, + FUI_TEXT_WIZ_CH_FILAMENT3_NL, + FUI_TEXT_CLICK_DONE_NL, + FUI_TEXT_AUTOLEVEL_ONOFF_NL, + FUI_TEXT_SERVOPOS_NL, + FUI_TEXT_IGNORE_M106_NL, + FUI_TEXT_WIZ_REHEAT1_NL, + FUI_TEXT_WIZ_REHEAT2_NL, + FUI_TEXT_WIZ_WAITTEMP1_NL, + FUI_TEXT_WIZ_WAITTEMP2_NL, + FUI_TEXT_EXTRUDER_JAM_NL, + FUI_TEXT_STANDBY_NL, + FUI_TEXT_BED_COATING_NL, + FUI_TEXT_BED_COATING_SET1_NL, + FUI_TEXT_BED_COATING_SET2_NL, + FUI_TEXT_NOCOATING_NL, + FUI_TEXT_BUILDTAK_NL, + FUI_TEXT_KAPTON_NL, + FUI_TEXT_BLUETAPE_NL, + FUI_TEXT_PETTAPE_NL, + FUI_TEXT_GLUESTICK_NL, + FUI_TEXT_CUSTOM_NL, + FUI_TEXT_COATING_CUSTOM_NL, + FUI_TEXT_LANGUAGE_NL, + FUI_TEXT_MAINPAGE6_1_NL, + FUI_TEXT_MAINPAGE6_2_NL, + FUI_TEXT_MAINPAGE6_3_NL, + FUI_TEXT_MAINPAGE6_4_NL, + FUI_TEXT_MAINPAGE6_5_NL, + FUI_TEXT_MAINPAGE6_6_NL, + FUI_TEXT_MAINPAGE_TEMP_BED_NL, + FUI_TEXT_MAINPAGE_BED_NL, + FUI_TEXT_MAINPAGE_Z_BUF_NL, + FUI_TEXT_MAINPAGE_MUL_EUSAGE_NL, + FUI_TEXT_MAINPAGE_XY_NL, + FUI_TEXT_PRINT_TIME_VALUE_NL, + FUI_TEXT_PRINT_FILAMENT_VALUE_NL, + FUI_TEXT_METER_PRINTED_NL, + FUI_TEXT_STATUS_NL, + FUI_TEXT_EMPTY_NL, + FUI_TEXT_TEMP_SET_NL, + FUI_TEXT_CURRENT_TEMP_NL, + FUI_TEXT_COATING_THICKNESS_NL, + FUI_TEXT_EXTR3_TEMP_NL, + FUI_TEXT_EXTR4_TEMP_NL, + FUI_TEXT_EXTR5_TEMP_NL, + FUI_TEXT_EXTR3_OFF_NL, + FUI_TEXT_EXTR4_OFF_NL, + FUI_TEXT_EXTR5_OFF_NL, + FUI_TEXT_EXTR3_SELECT_NL, + FUI_TEXT_EXTR4_SELECT_NL, + FUI_TEXT_EXTR5_SELECT_NL, + FUI_TEXT_DITTO_0_NL, + FUI_TEXT_DITTO_1_NL, + FUI_TEXT_DITTO_2_NL, + FUI_TEXT_DITTO_3_NL, + FUI_TEXT_ZPROBE_HEIGHT_NL, + FUI_TEXT_OFFSETS_NL, + FUI_TEXT_X_OFFSET_NL, + FUI_TEXT_Y_OFFSET_NL, + FUI_TEXT_Z_OFFSET_NL, + FUI_TEXT_DBG_ENDSTOP_NL +}; +#define LANG_NL_TABLE translations_nl +#else +#define LANG_NL_TABLE NULL +#endif // LANGUAGE_NL_ACTIVE + + +#if LANGUAGE_PT_ACTIVE +TRANS(UI_TEXT_ON_PT); +TRANS(UI_TEXT_OFF_PT); +TRANS(UI_TEXT_NA_PT); +TRANS(UI_TEXT_YES_PT); +TRANS(UI_TEXT_NO_PT); +TRANS(UI_TEXT_PRINT_POS_PT); +TRANS(UI_TEXT_PRINTING_PT); +TRANS(UI_TEXT_IDLE_PT); +TRANS(UI_TEXT_NOSDCARD_PT); +TRANS(UI_TEXT_ERROR_PT); +TRANS(UI_TEXT_BACK_PT); +TRANS(UI_TEXT_QUICK_SETTINGS_PT); +TRANS(UI_TEXT_ERRORMSG_PT); +TRANS(UI_TEXT_CONFIGURATION_PT); +TRANS(UI_TEXT_POSITION_PT); +TRANS(UI_TEXT_EXTRUDER_PT); +TRANS(UI_TEXT_SD_CARD_PT); +TRANS(UI_TEXT_DEBUGGING_PT); +TRANS(UI_TEXT_HOME_DELTA_PT); +TRANS(UI_TEXT_HOME_ALL_PT); +TRANS(UI_TEXT_HOME_X_PT); +TRANS(UI_TEXT_HOME_Y_PT); +TRANS(UI_TEXT_HOME_Z_PT); +TRANS(UI_TEXT_PREHEAT_PLA_PT); +TRANS(UI_TEXT_PREHEAT_ABS_PT); +TRANS(UI_TEXT_LIGHTS_ONOFF_PT); +TRANS(UI_TEXT_COOLDOWN_PT); +TRANS(UI_TEXT_SET_TO_ORIGIN_PT); +TRANS(UI_TEXT_DISABLE_STEPPER_PT); +TRANS(UI_TEXT_X_POSITION_PT); +TRANS(UI_TEXT_X_POS_FAST_PT); +TRANS(UI_TEXT_Y_POSITION_PT); +TRANS(UI_TEXT_Y_POS_FAST_PT); +TRANS(UI_TEXT_Z_POSITION_PT); +TRANS(UI_TEXT_Z_POS_FAST_PT); +TRANS(UI_TEXT_E_POSITION_PT); +TRANS(UI_TEXT_BED_TEMP_PT); +TRANS(UI_TEXT_EXTR0_TEMP_PT); +TRANS(UI_TEXT_EXTR1_TEMP_PT); +TRANS(UI_TEXT_EXTR2_TEMP_PT); +TRANS(UI_TEXT_EXTR0_OFF_PT); +TRANS(UI_TEXT_EXTR1_OFF_PT); +TRANS(UI_TEXT_EXTR2_OFF_PT); +TRANS(UI_TEXT_EXTR0_SELECT_PT); +TRANS(UI_TEXT_EXTR1_SELECT_PT); +TRANS(UI_TEXT_EXTR2_SELECT_PT); +TRANS(UI_TEXT_EXTR_ORIGIN_PT); +TRANS(UI_TEXT_PRINT_X_PT); +TRANS(UI_TEXT_PRINT_Y_PT); +TRANS(UI_TEXT_PRINT_Z_PT); +TRANS(UI_TEXT_PRINT_Z_DELTA_PT); +TRANS(UI_TEXT_MOVE_X_PT); +TRANS(UI_TEXT_MOVE_Y_PT); +TRANS(UI_TEXT_MOVE_Z_PT); +TRANS(UI_TEXT_MOVE_Z_DELTA_PT); +TRANS(UI_TEXT_JERK_PT); +TRANS(UI_TEXT_ZJERK_PT); +TRANS(UI_TEXT_ACCELERATION_PT); +TRANS(UI_TEXT_STORE_TO_EEPROM_PT); +TRANS(UI_TEXT_LOAD_EEPROM_PT); +TRANS(UI_TEXT_DBG_ECHO_PT); +TRANS(UI_TEXT_DBG_INFO_PT); +TRANS(UI_TEXT_DBG_ERROR_PT); +TRANS(UI_TEXT_DBG_DRYRUN_PT); +TRANS(UI_TEXT_DBG_ENDSTOP_PT); +TRANS(UI_TEXT_OPS_OFF_PT); +TRANS(UI_TEXT_OPS_CLASSIC_PT); +TRANS(UI_TEXT_OPS_FAST_PT); +TRANS(UI_TEXT_OPS_RETRACT_PT); +TRANS(UI_TEXT_OPS_BACKSLASH_PT); +TRANS(UI_TEXT_OPS_MINDIST_PT); +TRANS(UI_TEXT_OPS_MOVE_AFTER_PT); +TRANS(UI_TEXT_ANTI_OOZE_PT); +TRANS(UI_TEXT_PRINT_FILE_PT); +TRANS(UI_TEXT_PAUSE_PRINT_PT); +TRANS(UI_TEXT_CONTINUE_PRINT_PT); +TRANS(UI_TEXT_UNMOUNT_CARD_PT); +TRANS(UI_TEXT_MOUNT_CARD_PT); +TRANS(UI_TEXT_DELETE_FILE_PT); +TRANS(UI_TEXT_FEEDRATE_PT); +TRANS(UI_TEXT_FEED_MAX_X_PT); +TRANS(UI_TEXT_FEED_MAX_Y_PT); +TRANS(UI_TEXT_FEED_MAX_Z_PT); +TRANS(UI_TEXT_FEED_MAX_Z_DELTA_PT); +TRANS(UI_TEXT_FEED_HOME_X_PT); +TRANS(UI_TEXT_FEED_HOME_Y_PT); +TRANS(UI_TEXT_FEED_HOME_Z_PT); +TRANS(UI_TEXT_FEED_HOME_Z_DELTA_PT); +TRANS(UI_TEXT_ACTION_XPOSITION4A_PT); +TRANS(UI_TEXT_ACTION_XPOSITION4B_PT); +TRANS(UI_TEXT_ACTION_XPOSITION4C_PT); +TRANS(UI_TEXT_ACTION_XPOSITION4D_PT); +TRANS(UI_TEXT_ACTION_YPOSITION4A_PT); +TRANS(UI_TEXT_ACTION_YPOSITION4B_PT); +TRANS(UI_TEXT_ACTION_YPOSITION4C_PT); +TRANS(UI_TEXT_ACTION_YPOSITION4D_PT); +TRANS(UI_TEXT_ACTION_ZPOSITION4A_PT); +TRANS(UI_TEXT_ACTION_ZPOSITION4B_PT); +TRANS(UI_TEXT_ACTION_ZPOSITION4C_PT); +TRANS(UI_TEXT_ACTION_ZPOSITION4D_PT); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST4A_PT); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST4B_PT); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST4C_PT); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST4D_PT); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST4A_PT); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST4B_PT); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST4C_PT); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST4D_PT); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST4A_PT); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST4B_PT); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST4C_PT); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST4D_PT); +TRANS(UI_TEXT_ACTION_EPOSITION_FAST2A_PT); +TRANS(UI_TEXT_ACTION_EPOSITION_FAST2B_PT); +TRANS(UI_TEXT_ACTION_XPOSITION2A_PT); +TRANS(UI_TEXT_ACTION_XPOSITION2B_PT); +TRANS(UI_TEXT_ACTION_YPOSITION2A_PT); +TRANS(UI_TEXT_ACTION_YPOSITION2B_PT); +TRANS(UI_TEXT_ACTION_ZPOSITION2A_PT); +TRANS(UI_TEXT_ACTION_ZPOSITION2B_PT); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST2A_PT); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST2B_PT); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST2A_PT); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST2B_PT); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST2A_PT); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST2B_PT); +TRANS(UI_TEXT_FANSPEED_PT); +TRANS(UI_TEXT_ACTION_FANSPEED_PT); +TRANS(UI_TEXT_FAN_OFF_PT); +TRANS(UI_TEXT_FAN_25_PT); +TRANS(UI_TEXT_FAN_50_PT); +TRANS(UI_TEXT_FAN_75_PT); +TRANS(UI_TEXT_FAN_FULL_PT); +TRANS(UI_TEXT_STEPPER_INACTIVE_PT); +TRANS(UI_TEXT_STEPPER_INACTIVE2A_PT); +TRANS(UI_TEXT_STEPPER_INACTIVE2B_PT); +TRANS(UI_TEXT_POWER_INACTIVE_PT); +TRANS(UI_TEXT_POWER_INACTIVE2A_PT); +TRANS(UI_TEXT_POWER_INACTIVE2B_PT); +TRANS(UI_TEXT_GENERAL_PT); +TRANS(UI_TEXT_BAUDRATE_PT); +TRANS(UI_TEXT_EXTR_STEPS_PT); +TRANS(UI_TEXT_EXTR_START_FEED_PT); +TRANS(UI_TEXT_EXTR_MAX_FEED_PT); +TRANS(UI_TEXT_EXTR_ACCEL_PT); +TRANS(UI_TEXT_EXTR_WATCH_PT); +TRANS(UI_TEXT_EXTR_ADVANCE_L_PT); +TRANS(UI_TEXT_EXTR_ADVANCE_K_PT); +TRANS(UI_TEXT_EXTR_MANAGER_PT); +TRANS(UI_TEXT_EXTR_PGAIN_PT); +TRANS(UI_TEXT_EXTR_DEADTIME_PT); +TRANS(UI_TEXT_EXTR_DMAX_DT_PT); +TRANS(UI_TEXT_EXTR_IGAIN_PT); +TRANS(UI_TEXT_EXTR_DGAIN_PT); +TRANS(UI_TEXT_EXTR_DMIN_PT); +TRANS(UI_TEXT_EXTR_DMAX_PT); +TRANS(UI_TEXT_EXTR_PMAX_PT); +TRANS(UI_TEXT_EXTR_XOFF_PT); +TRANS(UI_TEXT_EXTR_YOFF_PT); +TRANS(UI_TEXT_STRING_HM_BANGBANG_PT); +TRANS(UI_TEXT_STRING_HM_PID_PT); +TRANS(UI_TEXT_STRING_ACTION_PT); +TRANS(UI_TEXT_HEATING_EXTRUDER_PT); +TRANS(UI_TEXT_HEATING_BED_PT); +TRANS(UI_TEXT_KILLED_PT); +TRANS(UI_TEXT_STEPPER_DISABLED_PT); +TRANS(UI_TEXT_EEPROM_STOREDA_PT); +TRANS(UI_TEXT_EEPROM_STOREDB_PT); +TRANS(UI_TEXT_EEPROM_LOADEDA_PT); +TRANS(UI_TEXT_EEPROM_LOADEDB_PT); +TRANS(UI_TEXT_UPLOADING_PT); +TRANS(UI_TEXT_PAGE_BUFFER_PT); +TRANS(UI_TEXT_PAGE_EXTRUDER_PT); +TRANS(UI_TEXT_PAGE_EXTRUDER1_PT); +TRANS(UI_TEXT_PAGE_EXTRUDER2_PT); +TRANS(UI_TEXT_PAGE_EXTRUDER3_PT); +TRANS(UI_TEXT_PAGE_BED_PT); +TRANS(UI_TEXT_SPEED_MULTIPLY_PT); +TRANS(UI_TEXT_FLOW_MULTIPLY_PT); +TRANS(UI_TEXT_SHOW_MEASUREMENT_PT); +TRANS(UI_TEXT_RESET_MEASUREMENT_PT); +TRANS(UI_TEXT_SET_MEASURED_ORIGIN_PT); +TRANS(UI_TEXT_ZCALIB_PT); +TRANS(UI_TEXT_SET_P1_PT); +TRANS(UI_TEXT_SET_P2_PT); +TRANS(UI_TEXT_SET_P3_PT); +TRANS(UI_TEXT_CALCULATE_LEVELING_PT); +TRANS(UI_TEXT_LEVEL_PT); +TRANS(UI_TEXT_EXTR_WAIT_RETRACT_TEMP_PT); +TRANS(UI_TEXT_EXTR_WAIT_RETRACT_UNITS_PT); +TRANS(UI_TEXT_SD_REMOVED_PT); +TRANS(UI_TEXT_SD_INSERTED_PT); +TRANS(UI_TEXT_PRINTER_READY_PT); +TRANS(UI_TEXT_PRINTTIME_DAYS_PT); +TRANS(UI_TEXT_PRINTTIME_HOURS_PT); +TRANS(UI_TEXT_PRINTTIME_MINUTES_PT); +TRANS(UI_TEXT_PRINT_TIME_PT); +TRANS(UI_TEXT_PRINT_FILAMENT_PT); +TRANS(UI_TEXT_PRINTED_PT); +TRANS(UI_TEXT_POWER_PT); +TRANS(UI_TEXT_STRING_HM_DEADTIME_PT); +TRANS(UI_TEXT_STRING_HM_SLOWBANG_PT); +TRANS(UI_TEXT_STOP_PRINT_PT); +TRANS(UI_TEXT_Z_BABYSTEPPING_PT); +TRANS(UI_TEXT_CHANGE_FILAMENT_PT); +TRANS(UI_TEXT_WIZ_CH_FILAMENT1_PT); +TRANS(UI_TEXT_WIZ_CH_FILAMENT2_PT); +TRANS(UI_TEXT_WIZ_CH_FILAMENT3_PT); +TRANS(UI_TEXT_CLICK_DONE_PT); +TRANS(UI_TEXT_AUTOLEVEL_ONOFF_PT); +TRANS(UI_TEXT_SERVOPOS_PT); +TRANS(UI_TEXT_IGNORE_M106_PT); +TRANS(UI_TEXT_WIZ_REHEAT1_PT); +TRANS(UI_TEXT_WIZ_REHEAT2_PT); +TRANS(UI_TEXT_WIZ_WAITTEMP1_PT); +TRANS(UI_TEXT_WIZ_WAITTEMP2_PT); +TRANS(UI_TEXT_EXTRUDER_JAM_PT); +TRANS(UI_TEXT_STANDBY_PT); +TRANS(UI_TEXT_BED_COATING_PT); +TRANS(UI_TEXT_BED_COATING_SET1_PT); +TRANS(UI_TEXT_BED_COATING_SET2_PT); +TRANS(UI_TEXT_NOCOATING_PT); +TRANS(UI_TEXT_BUILDTAK_PT); +TRANS(UI_TEXT_KAPTON_PT); +TRANS(UI_TEXT_BLUETAPE_PT); +TRANS(UI_TEXT_PETTAPE_PT); +TRANS(UI_TEXT_GLUESTICK_PT); +TRANS(UI_TEXT_CUSTOM_PT); +TRANS(UI_TEXT_COATING_CUSTOM_PT); +TRANS(UI_TEXT_LANGUAGE_PT); +TRANS(UI_TEXT_MAINPAGE6_1_PT); +TRANS(UI_TEXT_MAINPAGE6_2_PT); +TRANS(UI_TEXT_MAINPAGE6_3_PT); +TRANS(UI_TEXT_MAINPAGE6_4_PT); +TRANS(UI_TEXT_MAINPAGE6_5_PT); +TRANS(UI_TEXT_MAINPAGE6_6_PT); +TRANS(UI_TEXT_MAINPAGE_TEMP_BED_PT); +TRANS(UI_TEXT_MAINPAGE_BED_PT); +TRANS(UI_TEXT_MAINPAGE_Z_BUF_PT); +TRANS(UI_TEXT_MAINPAGE_MUL_EUSAGE_PT); +TRANS(UI_TEXT_MAINPAGE_XY_PT); +TRANS(UI_TEXT_PRINT_TIME_VALUE_PT); +TRANS(UI_TEXT_PRINT_FILAMENT_VALUE_PT); +TRANS(UI_TEXT_METER_PRINTED_PT); +TRANS(UI_TEXT_STATUS_PT); +TRANS(UI_TEXT_EMPTY_PT); +TRANS(UI_TEXT_TEMP_SET_PT); +TRANS(UI_TEXT_CURRENT_TEMP_PT); +TRANS(UI_TEXT_COATING_THICKNESS_PT); +TRANS(UI_TEXT_EXTR3_TEMP_PT); +TRANS(UI_TEXT_EXTR4_TEMP_PT); +TRANS(UI_TEXT_EXTR5_TEMP_PT); +TRANS(UI_TEXT_EXTR3_OFF_PT); +TRANS(UI_TEXT_EXTR4_OFF_PT); +TRANS(UI_TEXT_EXTR5_OFF_PT); +TRANS(UI_TEXT_EXTR3_SELECT_PT); +TRANS(UI_TEXT_EXTR4_SELECT_PT); +TRANS(UI_TEXT_EXTR5_SELECT_PT); +TRANS(UI_TEXT_DITTO_0_PT); +TRANS(UI_TEXT_DITTO_1_PT); +TRANS(UI_TEXT_DITTO_2_PT); +TRANS(UI_TEXT_DITTO_3_PT); +TRANS(UI_TEXT_ZPROBE_HEIGHT_PT); +TRANS(UI_TEXT_OFFSETS_PT); +TRANS(UI_TEXT_X_OFFSET_PT); +TRANS(UI_TEXT_Y_OFFSET_PT); +TRANS(UI_TEXT_Z_OFFSET_PT); + +PGM_P const translations_pt[NUM_TRANSLATED_WORDS] PROGMEM = { + FUI_TEXT_ON_PT, + FUI_TEXT_OFF_PT, + FUI_TEXT_NA_PT, + FUI_TEXT_YES_PT, + FUI_TEXT_NO_PT, + FUI_TEXT_PRINT_POS_PT, + FUI_TEXT_PRINTING_PT, + FUI_TEXT_IDLE_PT, + FUI_TEXT_NOSDCARD_PT, + FUI_TEXT_ERROR_PT, + FUI_TEXT_BACK_PT, + FUI_TEXT_QUICK_SETTINGS_PT, + FUI_TEXT_ERRORMSG_PT, + FUI_TEXT_CONFIGURATION_PT, + FUI_TEXT_POSITION_PT, + FUI_TEXT_EXTRUDER_PT, + FUI_TEXT_SD_CARD_PT, + FUI_TEXT_DEBUGGING_PT, + FUI_TEXT_HOME_DELTA_PT, + FUI_TEXT_HOME_ALL_PT, + FUI_TEXT_HOME_X_PT, + FUI_TEXT_HOME_Y_PT, + FUI_TEXT_HOME_Z_PT, + FUI_TEXT_PREHEAT_PLA_PT, + FUI_TEXT_PREHEAT_ABS_PT, + FUI_TEXT_LIGHTS_ONOFF_PT, + FUI_TEXT_COOLDOWN_PT, + FUI_TEXT_SET_TO_ORIGIN_PT, + FUI_TEXT_DISABLE_STEPPER_PT, + FUI_TEXT_X_POSITION_PT, + FUI_TEXT_X_POS_FAST_PT, + FUI_TEXT_Y_POSITION_PT, + FUI_TEXT_Y_POS_FAST_PT, + FUI_TEXT_Z_POSITION_PT, + FUI_TEXT_Z_POS_FAST_PT, + FUI_TEXT_E_POSITION_PT, + FUI_TEXT_BED_TEMP_PT, + FUI_TEXT_EXTR0_TEMP_PT, + FUI_TEXT_EXTR1_TEMP_PT, + FUI_TEXT_EXTR2_TEMP_PT, + FUI_TEXT_EXTR0_OFF_PT, + FUI_TEXT_EXTR1_OFF_PT, + FUI_TEXT_EXTR2_OFF_PT, + FUI_TEXT_EXTR0_SELECT_PT, + FUI_TEXT_EXTR1_SELECT_PT, + FUI_TEXT_EXTR2_SELECT_PT, + FUI_TEXT_EXTR_ORIGIN_PT, + FUI_TEXT_PRINT_X_PT, + FUI_TEXT_PRINT_Y_PT, + FUI_TEXT_PRINT_Z_PT, + FUI_TEXT_PRINT_Z_DELTA_PT, + FUI_TEXT_MOVE_X_PT, + FUI_TEXT_MOVE_Y_PT, + FUI_TEXT_MOVE_Z_PT, + FUI_TEXT_MOVE_Z_DELTA_PT, + FUI_TEXT_JERK_PT, + FUI_TEXT_ZJERK_PT, + FUI_TEXT_ACCELERATION_PT, + FUI_TEXT_STORE_TO_EEPROM_PT, + FUI_TEXT_LOAD_EEPROM_PT, + FUI_TEXT_DBG_ECHO_PT, + FUI_TEXT_DBG_INFO_PT, + FUI_TEXT_DBG_ERROR_PT, + FUI_TEXT_DBG_DRYRUN_PT, + FUI_TEXT_OPS_OFF_PT, + FUI_TEXT_OPS_CLASSIC_PT, + FUI_TEXT_OPS_FAST_PT, + FUI_TEXT_OPS_RETRACT_PT, + FUI_TEXT_OPS_BACKSLASH_PT, + FUI_TEXT_OPS_MINDIST_PT, + FUI_TEXT_OPS_MOVE_AFTER_PT, + FUI_TEXT_ANTI_OOZE_PT, + FUI_TEXT_PRINT_FILE_PT, + FUI_TEXT_PAUSE_PRINT_PT, + FUI_TEXT_CONTINUE_PRINT_PT, + FUI_TEXT_UNMOUNT_CARD_PT, + FUI_TEXT_MOUNT_CARD_PT, + FUI_TEXT_DELETE_FILE_PT, + FUI_TEXT_FEEDRATE_PT, + FUI_TEXT_FEED_MAX_X_PT, + FUI_TEXT_FEED_MAX_Y_PT, + FUI_TEXT_FEED_MAX_Z_PT, + FUI_TEXT_FEED_MAX_Z_DELTA_PT, + FUI_TEXT_FEED_HOME_X_PT, + FUI_TEXT_FEED_HOME_Y_PT, + FUI_TEXT_FEED_HOME_Z_PT, + FUI_TEXT_FEED_HOME_Z_DELTA_PT, + FUI_TEXT_ACTION_XPOSITION4A_PT, + FUI_TEXT_ACTION_XPOSITION4B_PT, + FUI_TEXT_ACTION_XPOSITION4C_PT, + FUI_TEXT_ACTION_XPOSITION4D_PT, + FUI_TEXT_ACTION_YPOSITION4A_PT, + FUI_TEXT_ACTION_YPOSITION4B_PT, + FUI_TEXT_ACTION_YPOSITION4C_PT, + FUI_TEXT_ACTION_YPOSITION4D_PT, + FUI_TEXT_ACTION_ZPOSITION4A_PT, + FUI_TEXT_ACTION_ZPOSITION4B_PT, + FUI_TEXT_ACTION_ZPOSITION4C_PT, + FUI_TEXT_ACTION_ZPOSITION4D_PT, + FUI_TEXT_ACTION_XPOSITION_FAST4A_PT, + FUI_TEXT_ACTION_XPOSITION_FAST4B_PT, + FUI_TEXT_ACTION_XPOSITION_FAST4C_PT, + FUI_TEXT_ACTION_XPOSITION_FAST4D_PT, + FUI_TEXT_ACTION_YPOSITION_FAST4A_PT, + FUI_TEXT_ACTION_YPOSITION_FAST4B_PT, + FUI_TEXT_ACTION_YPOSITION_FAST4C_PT, + FUI_TEXT_ACTION_YPOSITION_FAST4D_PT, + FUI_TEXT_ACTION_ZPOSITION_FAST4A_PT, + FUI_TEXT_ACTION_ZPOSITION_FAST4B_PT, + FUI_TEXT_ACTION_ZPOSITION_FAST4C_PT, + FUI_TEXT_ACTION_ZPOSITION_FAST4D_PT, + FUI_TEXT_ACTION_EPOSITION_FAST2A_PT, + FUI_TEXT_ACTION_EPOSITION_FAST2B_PT, + FUI_TEXT_ACTION_XPOSITION2A_PT, + FUI_TEXT_ACTION_XPOSITION2B_PT, + FUI_TEXT_ACTION_YPOSITION2A_PT, + FUI_TEXT_ACTION_YPOSITION2B_PT, + FUI_TEXT_ACTION_ZPOSITION2A_PT, + FUI_TEXT_ACTION_ZPOSITION2B_PT, + FUI_TEXT_ACTION_XPOSITION_FAST2A_PT, + FUI_TEXT_ACTION_XPOSITION_FAST2B_PT, + FUI_TEXT_ACTION_YPOSITION_FAST2A_PT, + FUI_TEXT_ACTION_YPOSITION_FAST2B_PT, + FUI_TEXT_ACTION_ZPOSITION_FAST2A_PT, + FUI_TEXT_ACTION_ZPOSITION_FAST2B_PT, + FUI_TEXT_FANSPEED_PT, + FUI_TEXT_ACTION_FANSPEED_PT, + FUI_TEXT_FAN_OFF_PT, + FUI_TEXT_FAN_25_PT, + FUI_TEXT_FAN_50_PT, + FUI_TEXT_FAN_75_PT, + FUI_TEXT_FAN_FULL_PT, + FUI_TEXT_STEPPER_INACTIVE_PT, + FUI_TEXT_STEPPER_INACTIVE2A_PT, + FUI_TEXT_STEPPER_INACTIVE2B_PT, + FUI_TEXT_POWER_INACTIVE_PT, + FUI_TEXT_POWER_INACTIVE2A_PT, + FUI_TEXT_POWER_INACTIVE2B_PT, + FUI_TEXT_GENERAL_PT, + FUI_TEXT_BAUDRATE_PT, + FUI_TEXT_EXTR_STEPS_PT, + FUI_TEXT_EXTR_START_FEED_PT, + FUI_TEXT_EXTR_MAX_FEED_PT, + FUI_TEXT_EXTR_ACCEL_PT, + FUI_TEXT_EXTR_WATCH_PT, + FUI_TEXT_EXTR_ADVANCE_L_PT, + FUI_TEXT_EXTR_ADVANCE_K_PT, + FUI_TEXT_EXTR_MANAGER_PT, + FUI_TEXT_EXTR_PGAIN_PT, + FUI_TEXT_EXTR_DEADTIME_PT, + FUI_TEXT_EXTR_DMAX_DT_PT, + FUI_TEXT_EXTR_IGAIN_PT, + FUI_TEXT_EXTR_DGAIN_PT, + FUI_TEXT_EXTR_DMIN_PT, + FUI_TEXT_EXTR_DMAX_PT, + FUI_TEXT_EXTR_PMAX_PT, + FUI_TEXT_EXTR_XOFF_PT, + FUI_TEXT_EXTR_YOFF_PT, + FUI_TEXT_STRING_HM_BANGBANG_PT, + FUI_TEXT_STRING_HM_PID_PT, + FUI_TEXT_STRING_ACTION_PT, + FUI_TEXT_HEATING_EXTRUDER_PT, + FUI_TEXT_HEATING_BED_PT, + FUI_TEXT_KILLED_PT, + FUI_TEXT_STEPPER_DISABLED_PT, + FUI_TEXT_EEPROM_STOREDA_PT, + FUI_TEXT_EEPROM_STOREDB_PT, + FUI_TEXT_EEPROM_LOADEDA_PT, + FUI_TEXT_EEPROM_LOADEDB_PT, + FUI_TEXT_UPLOADING_PT, + FUI_TEXT_PAGE_BUFFER_PT, + FUI_TEXT_PAGE_EXTRUDER_PT, + FUI_TEXT_PAGE_EXTRUDER1_PT, + FUI_TEXT_PAGE_EXTRUDER2_PT, + FUI_TEXT_PAGE_EXTRUDER3_PT, + FUI_TEXT_PAGE_BED_PT, + FUI_TEXT_SPEED_MULTIPLY_PT, + FUI_TEXT_FLOW_MULTIPLY_PT, + FUI_TEXT_SHOW_MEASUREMENT_PT, + FUI_TEXT_RESET_MEASUREMENT_PT, + FUI_TEXT_SET_MEASURED_ORIGIN_PT, + FUI_TEXT_ZCALIB_PT, + FUI_TEXT_SET_P1_PT, + FUI_TEXT_SET_P2_PT, + FUI_TEXT_SET_P3_PT, + FUI_TEXT_CALCULATE_LEVELING_PT, + FUI_TEXT_LEVEL_PT, + FUI_TEXT_EXTR_WAIT_RETRACT_TEMP_PT, + FUI_TEXT_EXTR_WAIT_RETRACT_UNITS_PT, + FUI_TEXT_SD_REMOVED_PT, + FUI_TEXT_SD_INSERTED_PT, + FUI_TEXT_PRINTER_READY_PT, + FUI_TEXT_PRINTTIME_DAYS_PT, + FUI_TEXT_PRINTTIME_HOURS_PT, + FUI_TEXT_PRINTTIME_MINUTES_PT, + FUI_TEXT_PRINT_TIME_PT, + FUI_TEXT_PRINT_FILAMENT_PT, + FUI_TEXT_PRINTED_PT, + FUI_TEXT_POWER_PT, + FUI_TEXT_STRING_HM_DEADTIME_PT, + FUI_TEXT_STRING_HM_SLOWBANG_PT, + FUI_TEXT_STOP_PRINT_PT, + FUI_TEXT_Z_BABYSTEPPING_PT, + FUI_TEXT_CHANGE_FILAMENT_PT, + FUI_TEXT_WIZ_CH_FILAMENT1_PT, + FUI_TEXT_WIZ_CH_FILAMENT2_PT, + FUI_TEXT_WIZ_CH_FILAMENT3_PT, + FUI_TEXT_CLICK_DONE_PT, + FUI_TEXT_AUTOLEVEL_ONOFF_PT, + FUI_TEXT_SERVOPOS_PT, + FUI_TEXT_IGNORE_M106_PT, + FUI_TEXT_WIZ_REHEAT1_PT, + FUI_TEXT_WIZ_REHEAT2_PT, + FUI_TEXT_WIZ_WAITTEMP1_PT, + FUI_TEXT_WIZ_WAITTEMP2_PT, + FUI_TEXT_EXTRUDER_JAM_PT, + FUI_TEXT_STANDBY_PT, + FUI_TEXT_BED_COATING_PT, + FUI_TEXT_BED_COATING_SET1_PT, + FUI_TEXT_BED_COATING_SET2_PT, + FUI_TEXT_NOCOATING_PT, + FUI_TEXT_BUILDTAK_PT, + FUI_TEXT_KAPTON_PT, + FUI_TEXT_BLUETAPE_PT, + FUI_TEXT_PETTAPE_PT, + FUI_TEXT_GLUESTICK_PT, + FUI_TEXT_CUSTOM_PT, + FUI_TEXT_COATING_CUSTOM_PT, + FUI_TEXT_LANGUAGE_PT, + FUI_TEXT_MAINPAGE6_1_PT, + FUI_TEXT_MAINPAGE6_2_PT, + FUI_TEXT_MAINPAGE6_3_PT, + FUI_TEXT_MAINPAGE6_4_PT, + FUI_TEXT_MAINPAGE6_5_PT, + FUI_TEXT_MAINPAGE6_6_PT, + FUI_TEXT_MAINPAGE_TEMP_BED_PT, + FUI_TEXT_MAINPAGE_BED_PT, + FUI_TEXT_MAINPAGE_Z_BUF_PT, + FUI_TEXT_MAINPAGE_MUL_EUSAGE_PT, + FUI_TEXT_MAINPAGE_XY_PT, + FUI_TEXT_PRINT_TIME_VALUE_PT, + FUI_TEXT_PRINT_FILAMENT_VALUE_PT, + FUI_TEXT_METER_PRINTED_PT, + FUI_TEXT_STATUS_PT, + FUI_TEXT_EMPTY_PT, + FUI_TEXT_TEMP_SET_PT, + FUI_TEXT_CURRENT_TEMP_PT, + FUI_TEXT_COATING_THICKNESS_PT, + FUI_TEXT_EXTR3_TEMP_PT, + FUI_TEXT_EXTR4_TEMP_PT, + FUI_TEXT_EXTR5_TEMP_PT, + FUI_TEXT_EXTR3_OFF_PT, + FUI_TEXT_EXTR4_OFF_PT, + FUI_TEXT_EXTR5_OFF_PT, + FUI_TEXT_EXTR3_SELECT_PT, + FUI_TEXT_EXTR4_SELECT_PT, + FUI_TEXT_EXTR5_SELECT_PT, + FUI_TEXT_DITTO_0_PT, + FUI_TEXT_DITTO_1_PT, + FUI_TEXT_DITTO_2_PT, + FUI_TEXT_DITTO_3_PT, + FUI_TEXT_ZPROBE_HEIGHT_PT, + FUI_TEXT_OFFSETS_PT, + FUI_TEXT_X_OFFSET_PT, + FUI_TEXT_Y_OFFSET_PT, + FUI_TEXT_Z_OFFSET_PT, + FUI_TEXT_DBG_ENDSTOP_PT +}; +#define LANG_PT_TABLE translations_pt +#else +#define LANG_PT_TABLE NULL +#endif // LANGUAGE_PT_ACTIVE + + +#if LANGUAGE_IT_ACTIVE +TRANS(UI_TEXT_ON_IT); +TRANS(UI_TEXT_OFF_IT); +TRANS(UI_TEXT_NA_IT); +TRANS(UI_TEXT_YES_IT); +TRANS(UI_TEXT_NO_IT); +TRANS(UI_TEXT_PRINT_POS_IT); +TRANS(UI_TEXT_PRINTING_IT); +TRANS(UI_TEXT_IDLE_IT); +TRANS(UI_TEXT_NOSDCARD_IT); +TRANS(UI_TEXT_ERROR_IT); +TRANS(UI_TEXT_BACK_IT); +TRANS(UI_TEXT_QUICK_SETTINGS_IT); +TRANS(UI_TEXT_ERRORMSG_IT); +TRANS(UI_TEXT_CONFIGURATION_IT); +TRANS(UI_TEXT_POSITION_IT); +TRANS(UI_TEXT_EXTRUDER_IT); +TRANS(UI_TEXT_SD_CARD_IT); +TRANS(UI_TEXT_DEBUGGING_IT); +TRANS(UI_TEXT_HOME_DELTA_IT); +TRANS(UI_TEXT_HOME_ALL_IT); +TRANS(UI_TEXT_HOME_X_IT); +TRANS(UI_TEXT_HOME_Y_IT); +TRANS(UI_TEXT_HOME_Z_IT); +TRANS(UI_TEXT_PREHEAT_PLA_IT); +TRANS(UI_TEXT_PREHEAT_ABS_IT); +TRANS(UI_TEXT_LIGHTS_ONOFF_IT); +TRANS(UI_TEXT_COOLDOWN_IT); +TRANS(UI_TEXT_SET_TO_ORIGIN_IT); +TRANS(UI_TEXT_DISABLE_STEPPER_IT); +TRANS(UI_TEXT_X_POSITION_IT); +TRANS(UI_TEXT_X_POS_FAST_IT); +TRANS(UI_TEXT_Y_POSITION_IT); +TRANS(UI_TEXT_Y_POS_FAST_IT); +TRANS(UI_TEXT_Z_POSITION_IT); +TRANS(UI_TEXT_Z_POS_FAST_IT); +TRANS(UI_TEXT_E_POSITION_IT); +TRANS(UI_TEXT_BED_TEMP_IT); +TRANS(UI_TEXT_EXTR0_TEMP_IT); +TRANS(UI_TEXT_EXTR1_TEMP_IT); +TRANS(UI_TEXT_EXTR2_TEMP_IT); +TRANS(UI_TEXT_EXTR0_OFF_IT); +TRANS(UI_TEXT_EXTR1_OFF_IT); +TRANS(UI_TEXT_EXTR2_OFF_IT); +TRANS(UI_TEXT_EXTR0_SELECT_IT); +TRANS(UI_TEXT_EXTR1_SELECT_IT); +TRANS(UI_TEXT_EXTR2_SELECT_IT); +TRANS(UI_TEXT_EXTR_ORIGIN_IT); +TRANS(UI_TEXT_PRINT_X_IT); +TRANS(UI_TEXT_PRINT_Y_IT); +TRANS(UI_TEXT_PRINT_Z_IT); +TRANS(UI_TEXT_PRINT_Z_DELTA_IT); +TRANS(UI_TEXT_MOVE_X_IT); +TRANS(UI_TEXT_MOVE_Y_IT); +TRANS(UI_TEXT_MOVE_Z_IT); +TRANS(UI_TEXT_MOVE_Z_DELTA_IT); +TRANS(UI_TEXT_JERK_IT); +TRANS(UI_TEXT_ZJERK_IT); +TRANS(UI_TEXT_ACCELERATION_IT); +TRANS(UI_TEXT_STORE_TO_EEPROM_IT); +TRANS(UI_TEXT_LOAD_EEPROM_IT); +TRANS(UI_TEXT_DBG_ECHO_IT); +TRANS(UI_TEXT_DBG_INFO_IT); +TRANS(UI_TEXT_DBG_ERROR_IT); +TRANS(UI_TEXT_DBG_DRYRUN_IT); +TRANS(UI_TEXT_DBG_ENDSTOP_IT); +TRANS(UI_TEXT_OPS_OFF_IT); +TRANS(UI_TEXT_OPS_CLASSIC_IT); +TRANS(UI_TEXT_OPS_FAST_IT); +TRANS(UI_TEXT_OPS_RETRACT_IT); +TRANS(UI_TEXT_OPS_BACKSLASH_IT); +TRANS(UI_TEXT_OPS_MINDIST_IT); +TRANS(UI_TEXT_OPS_MOVE_AFTER_IT); +TRANS(UI_TEXT_ANTI_OOZE_IT); +TRANS(UI_TEXT_PRINT_FILE_IT); +TRANS(UI_TEXT_PAUSE_PRINT_IT); +TRANS(UI_TEXT_CONTINUE_PRINT_IT); +TRANS(UI_TEXT_UNMOUNT_CARD_IT); +TRANS(UI_TEXT_MOUNT_CARD_IT); +TRANS(UI_TEXT_DELETE_FILE_IT); +TRANS(UI_TEXT_FEEDRATE_IT); +TRANS(UI_TEXT_FEED_MAX_X_IT); +TRANS(UI_TEXT_FEED_MAX_Y_IT); +TRANS(UI_TEXT_FEED_MAX_Z_IT); +TRANS(UI_TEXT_FEED_MAX_Z_DELTA_IT); +TRANS(UI_TEXT_FEED_HOME_X_IT); +TRANS(UI_TEXT_FEED_HOME_Y_IT); +TRANS(UI_TEXT_FEED_HOME_Z_IT); +TRANS(UI_TEXT_FEED_HOME_Z_DELTA_IT); +TRANS(UI_TEXT_ACTION_XPOSITION4A_IT); +TRANS(UI_TEXT_ACTION_XPOSITION4B_IT); +TRANS(UI_TEXT_ACTION_XPOSITION4C_IT); +TRANS(UI_TEXT_ACTION_XPOSITION4D_IT); +TRANS(UI_TEXT_ACTION_YPOSITION4A_IT); +TRANS(UI_TEXT_ACTION_YPOSITION4B_IT); +TRANS(UI_TEXT_ACTION_YPOSITION4C_IT); +TRANS(UI_TEXT_ACTION_YPOSITION4D_IT); +TRANS(UI_TEXT_ACTION_ZPOSITION4A_IT); +TRANS(UI_TEXT_ACTION_ZPOSITION4B_IT); +TRANS(UI_TEXT_ACTION_ZPOSITION4C_IT); +TRANS(UI_TEXT_ACTION_ZPOSITION4D_IT); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST4A_IT); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST4B_IT); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST4C_IT); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST4D_IT); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST4A_IT); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST4B_IT); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST4C_IT); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST4D_IT); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST4A_IT); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST4B_IT); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST4C_IT); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST4D_IT); +TRANS(UI_TEXT_ACTION_EPOSITION_FAST2A_IT); +TRANS(UI_TEXT_ACTION_EPOSITION_FAST2B_IT); +TRANS(UI_TEXT_ACTION_XPOSITION2A_IT); +TRANS(UI_TEXT_ACTION_XPOSITION2B_IT); +TRANS(UI_TEXT_ACTION_YPOSITION2A_IT); +TRANS(UI_TEXT_ACTION_YPOSITION2B_IT); +TRANS(UI_TEXT_ACTION_ZPOSITION2A_IT); +TRANS(UI_TEXT_ACTION_ZPOSITION2B_IT); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST2A_IT); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST2B_IT); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST2A_IT); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST2B_IT); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST2A_IT); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST2B_IT); +TRANS(UI_TEXT_FANSPEED_IT); +TRANS(UI_TEXT_ACTION_FANSPEED_IT); +TRANS(UI_TEXT_FAN_OFF_IT); +TRANS(UI_TEXT_FAN_25_IT); +TRANS(UI_TEXT_FAN_50_IT); +TRANS(UI_TEXT_FAN_75_IT); +TRANS(UI_TEXT_FAN_FULL_IT); +TRANS(UI_TEXT_STEPPER_INACTIVE_IT); +TRANS(UI_TEXT_STEPPER_INACTIVE2A_IT); +TRANS(UI_TEXT_STEPPER_INACTIVE2B_IT); +TRANS(UI_TEXT_POWER_INACTIVE_IT); +TRANS(UI_TEXT_POWER_INACTIVE2A_IT); +TRANS(UI_TEXT_POWER_INACTIVE2B_IT); +TRANS(UI_TEXT_GENERAL_IT); +TRANS(UI_TEXT_BAUDRATE_IT); +TRANS(UI_TEXT_EXTR_STEPS_IT); +TRANS(UI_TEXT_EXTR_START_FEED_IT); +TRANS(UI_TEXT_EXTR_MAX_FEED_IT); +TRANS(UI_TEXT_EXTR_ACCEL_IT); +TRANS(UI_TEXT_EXTR_WATCH_IT); +TRANS(UI_TEXT_EXTR_ADVANCE_L_IT); +TRANS(UI_TEXT_EXTR_ADVANCE_K_IT); +TRANS(UI_TEXT_EXTR_MANAGER_IT); +TRANS(UI_TEXT_EXTR_PGAIN_IT); +TRANS(UI_TEXT_EXTR_DEADTIME_IT); +TRANS(UI_TEXT_EXTR_DMAX_DT_IT); +TRANS(UI_TEXT_EXTR_IGAIN_IT); +TRANS(UI_TEXT_EXTR_DGAIN_IT); +TRANS(UI_TEXT_EXTR_DMIN_IT); +TRANS(UI_TEXT_EXTR_DMAX_IT); +TRANS(UI_TEXT_EXTR_PMAX_IT); +TRANS(UI_TEXT_EXTR_XOFF_IT); +TRANS(UI_TEXT_EXTR_YOFF_IT); +TRANS(UI_TEXT_STRING_HM_BANGBANG_IT); +TRANS(UI_TEXT_STRING_HM_PID_IT); +TRANS(UI_TEXT_STRING_ACTION_IT); +TRANS(UI_TEXT_HEATING_EXTRUDER_IT); +TRANS(UI_TEXT_HEATING_BED_IT); +TRANS(UI_TEXT_KILLED_IT); +TRANS(UI_TEXT_STEPPER_DISABLED_IT); +TRANS(UI_TEXT_EEPROM_STOREDA_IT); +TRANS(UI_TEXT_EEPROM_STOREDB_IT); +TRANS(UI_TEXT_EEPROM_LOADEDA_IT); +TRANS(UI_TEXT_EEPROM_LOADEDB_IT); +TRANS(UI_TEXT_UPLOADING_IT); +TRANS(UI_TEXT_PAGE_BUFFER_IT); +TRANS(UI_TEXT_PAGE_EXTRUDER_IT); +TRANS(UI_TEXT_PAGE_EXTRUDER1_IT); +TRANS(UI_TEXT_PAGE_EXTRUDER2_IT); +TRANS(UI_TEXT_PAGE_EXTRUDER3_IT); +TRANS(UI_TEXT_PAGE_BED_IT); +TRANS(UI_TEXT_SPEED_MULTIPLY_IT); +TRANS(UI_TEXT_FLOW_MULTIPLY_IT); +TRANS(UI_TEXT_SHOW_MEASUREMENT_IT); +TRANS(UI_TEXT_RESET_MEASUREMENT_IT); +TRANS(UI_TEXT_SET_MEASURED_ORIGIN_IT); +TRANS(UI_TEXT_ZCALIB_IT); +TRANS(UI_TEXT_SET_P1_IT); +TRANS(UI_TEXT_SET_P2_IT); +TRANS(UI_TEXT_SET_P3_IT); +TRANS(UI_TEXT_CALCULATE_LEVELING_IT); +TRANS(UI_TEXT_LEVEL_IT); +TRANS(UI_TEXT_EXTR_WAIT_RETRACT_TEMP_IT); +TRANS(UI_TEXT_EXTR_WAIT_RETRACT_UNITS_IT); +TRANS(UI_TEXT_SD_REMOVED_IT); +TRANS(UI_TEXT_SD_INSERTED_IT); +TRANS(UI_TEXT_PRINTER_READY_IT); +TRANS(UI_TEXT_PRINTTIME_DAYS_IT); +TRANS(UI_TEXT_PRINTTIME_HOURS_IT); +TRANS(UI_TEXT_PRINTTIME_MINUTES_IT); +TRANS(UI_TEXT_PRINT_TIME_IT); +TRANS(UI_TEXT_PRINT_FILAMENT_IT); +TRANS(UI_TEXT_PRINTED_IT); +TRANS(UI_TEXT_POWER_IT); +TRANS(UI_TEXT_STRING_HM_DEADTIME_IT); +TRANS(UI_TEXT_STRING_HM_SLOWBANG_IT); +TRANS(UI_TEXT_STOP_PRINT_IT); +TRANS(UI_TEXT_Z_BABYSTEPPING_IT); +TRANS(UI_TEXT_CHANGE_FILAMENT_IT); +TRANS(UI_TEXT_WIZ_CH_FILAMENT1_IT); +TRANS(UI_TEXT_WIZ_CH_FILAMENT2_IT); +TRANS(UI_TEXT_WIZ_CH_FILAMENT3_IT); +TRANS(UI_TEXT_CLICK_DONE_IT); +TRANS(UI_TEXT_AUTOLEVEL_ONOFF_IT); +TRANS(UI_TEXT_SERVOPOS_IT); +TRANS(UI_TEXT_IGNORE_M106_IT); +TRANS(UI_TEXT_WIZ_REHEAT1_IT); +TRANS(UI_TEXT_WIZ_REHEAT2_IT); +TRANS(UI_TEXT_WIZ_WAITTEMP1_IT); +TRANS(UI_TEXT_WIZ_WAITTEMP2_IT); +TRANS(UI_TEXT_EXTRUDER_JAM_IT); +TRANS(UI_TEXT_STANDBY_IT); +TRANS(UI_TEXT_BED_COATING_IT); +TRANS(UI_TEXT_BED_COATING_SET1_IT); +TRANS(UI_TEXT_BED_COATING_SET2_IT); +TRANS(UI_TEXT_NOCOATING_IT); +TRANS(UI_TEXT_BUILDTAK_IT); +TRANS(UI_TEXT_KAPTON_IT); +TRANS(UI_TEXT_BLUETAPE_IT); +TRANS(UI_TEXT_PETTAPE_IT); +TRANS(UI_TEXT_GLUESTICK_IT); +TRANS(UI_TEXT_CUSTOM_IT); +TRANS(UI_TEXT_COATING_CUSTOM_IT); +TRANS(UI_TEXT_LANGUAGE_IT); +TRANS(UI_TEXT_MAINPAGE6_1_IT); +TRANS(UI_TEXT_MAINPAGE6_2_IT); +TRANS(UI_TEXT_MAINPAGE6_3_IT); +TRANS(UI_TEXT_MAINPAGE6_4_IT); +TRANS(UI_TEXT_MAINPAGE6_5_IT); +TRANS(UI_TEXT_MAINPAGE6_6_IT); +TRANS(UI_TEXT_MAINPAGE_TEMP_BED_IT); +TRANS(UI_TEXT_MAINPAGE_BED_IT); +TRANS(UI_TEXT_MAINPAGE_Z_BUF_IT); +TRANS(UI_TEXT_MAINPAGE_MUL_EUSAGE_IT); +TRANS(UI_TEXT_MAINPAGE_XY_IT); +TRANS(UI_TEXT_PRINT_TIME_VALUE_IT); +TRANS(UI_TEXT_PRINT_FILAMENT_VALUE_IT); +TRANS(UI_TEXT_METER_PRINTED_IT); +TRANS(UI_TEXT_STATUS_IT); +TRANS(UI_TEXT_EMPTY_IT); +TRANS(UI_TEXT_TEMP_SET_IT); +TRANS(UI_TEXT_CURRENT_TEMP_IT); +TRANS(UI_TEXT_COATING_THICKNESS_IT); +TRANS(UI_TEXT_EXTR3_TEMP_IT); +TRANS(UI_TEXT_EXTR4_TEMP_IT); +TRANS(UI_TEXT_EXTR5_TEMP_IT); +TRANS(UI_TEXT_EXTR3_OFF_IT); +TRANS(UI_TEXT_EXTR4_OFF_IT); +TRANS(UI_TEXT_EXTR5_OFF_IT); +TRANS(UI_TEXT_EXTR3_SELECT_IT); +TRANS(UI_TEXT_EXTR4_SELECT_IT); +TRANS(UI_TEXT_EXTR5_SELECT_IT); +TRANS(UI_TEXT_DITTO_0_IT); +TRANS(UI_TEXT_DITTO_1_IT); +TRANS(UI_TEXT_DITTO_2_IT); +TRANS(UI_TEXT_DITTO_3_IT); +TRANS(UI_TEXT_ZPROBE_HEIGHT_IT); +TRANS(UI_TEXT_OFFSETS_IT); +TRANS(UI_TEXT_X_OFFSET_IT); +TRANS(UI_TEXT_Y_OFFSET_IT); +TRANS(UI_TEXT_Z_OFFSET_IT); + +PGM_P const translations_it[NUM_TRANSLATED_WORDS] PROGMEM = { + FUI_TEXT_ON_IT, + FUI_TEXT_OFF_IT, + FUI_TEXT_NA_IT, + FUI_TEXT_YES_IT, + FUI_TEXT_NO_IT, + FUI_TEXT_PRINT_POS_IT, + FUI_TEXT_PRINTING_IT, + FUI_TEXT_IDLE_IT, + FUI_TEXT_NOSDCARD_IT, + FUI_TEXT_ERROR_IT, + FUI_TEXT_BACK_IT, + FUI_TEXT_QUICK_SETTINGS_IT, + FUI_TEXT_ERRORMSG_IT, + FUI_TEXT_CONFIGURATION_IT, + FUI_TEXT_POSITION_IT, + FUI_TEXT_EXTRUDER_IT, + FUI_TEXT_SD_CARD_IT, + FUI_TEXT_DEBUGGING_IT, + FUI_TEXT_HOME_DELTA_IT, + FUI_TEXT_HOME_ALL_IT, + FUI_TEXT_HOME_X_IT, + FUI_TEXT_HOME_Y_IT, + FUI_TEXT_HOME_Z_IT, + FUI_TEXT_PREHEAT_PLA_IT, + FUI_TEXT_PREHEAT_ABS_IT, + FUI_TEXT_LIGHTS_ONOFF_IT, + FUI_TEXT_COOLDOWN_IT, + FUI_TEXT_SET_TO_ORIGIN_IT, + FUI_TEXT_DISABLE_STEPPER_IT, + FUI_TEXT_X_POSITION_IT, + FUI_TEXT_X_POS_FAST_IT, + FUI_TEXT_Y_POSITION_IT, + FUI_TEXT_Y_POS_FAST_IT, + FUI_TEXT_Z_POSITION_IT, + FUI_TEXT_Z_POS_FAST_IT, + FUI_TEXT_E_POSITION_IT, + FUI_TEXT_BED_TEMP_IT, + FUI_TEXT_EXTR0_TEMP_IT, + FUI_TEXT_EXTR1_TEMP_IT, + FUI_TEXT_EXTR2_TEMP_IT, + FUI_TEXT_EXTR0_OFF_IT, + FUI_TEXT_EXTR1_OFF_IT, + FUI_TEXT_EXTR2_OFF_IT, + FUI_TEXT_EXTR0_SELECT_IT, + FUI_TEXT_EXTR1_SELECT_IT, + FUI_TEXT_EXTR2_SELECT_IT, + FUI_TEXT_EXTR_ORIGIN_IT, + FUI_TEXT_PRINT_X_IT, + FUI_TEXT_PRINT_Y_IT, + FUI_TEXT_PRINT_Z_IT, + FUI_TEXT_PRINT_Z_DELTA_IT, + FUI_TEXT_MOVE_X_IT, + FUI_TEXT_MOVE_Y_IT, + FUI_TEXT_MOVE_Z_IT, + FUI_TEXT_MOVE_Z_DELTA_IT, + FUI_TEXT_JERK_IT, + FUI_TEXT_ZJERK_IT, + FUI_TEXT_ACCELERATION_IT, + FUI_TEXT_STORE_TO_EEPROM_IT, + FUI_TEXT_LOAD_EEPROM_IT, + FUI_TEXT_DBG_ECHO_IT, + FUI_TEXT_DBG_INFO_IT, + FUI_TEXT_DBG_ERROR_IT, + FUI_TEXT_DBG_DRYRUN_IT, + FUI_TEXT_OPS_OFF_IT, + FUI_TEXT_OPS_CLASSIC_IT, + FUI_TEXT_OPS_FAST_IT, + FUI_TEXT_OPS_RETRACT_IT, + FUI_TEXT_OPS_BACKSLASH_IT, + FUI_TEXT_OPS_MINDIST_IT, + FUI_TEXT_OPS_MOVE_AFTER_IT, + FUI_TEXT_ANTI_OOZE_IT, + FUI_TEXT_PRINT_FILE_IT, + FUI_TEXT_PAUSE_PRINT_IT, + FUI_TEXT_CONTINUE_PRINT_IT, + FUI_TEXT_UNMOUNT_CARD_IT, + FUI_TEXT_MOUNT_CARD_IT, + FUI_TEXT_DELETE_FILE_IT, + FUI_TEXT_FEEDRATE_IT, + FUI_TEXT_FEED_MAX_X_IT, + FUI_TEXT_FEED_MAX_Y_IT, + FUI_TEXT_FEED_MAX_Z_IT, + FUI_TEXT_FEED_MAX_Z_DELTA_IT, + FUI_TEXT_FEED_HOME_X_IT, + FUI_TEXT_FEED_HOME_Y_IT, + FUI_TEXT_FEED_HOME_Z_IT, + FUI_TEXT_FEED_HOME_Z_DELTA_IT, + FUI_TEXT_ACTION_XPOSITION4A_IT, + FUI_TEXT_ACTION_XPOSITION4B_IT, + FUI_TEXT_ACTION_XPOSITION4C_IT, + FUI_TEXT_ACTION_XPOSITION4D_IT, + FUI_TEXT_ACTION_YPOSITION4A_IT, + FUI_TEXT_ACTION_YPOSITION4B_IT, + FUI_TEXT_ACTION_YPOSITION4C_IT, + FUI_TEXT_ACTION_YPOSITION4D_IT, + FUI_TEXT_ACTION_ZPOSITION4A_IT, + FUI_TEXT_ACTION_ZPOSITION4B_IT, + FUI_TEXT_ACTION_ZPOSITION4C_IT, + FUI_TEXT_ACTION_ZPOSITION4D_IT, + FUI_TEXT_ACTION_XPOSITION_FAST4A_IT, + FUI_TEXT_ACTION_XPOSITION_FAST4B_IT, + FUI_TEXT_ACTION_XPOSITION_FAST4C_IT, + FUI_TEXT_ACTION_XPOSITION_FAST4D_IT, + FUI_TEXT_ACTION_YPOSITION_FAST4A_IT, + FUI_TEXT_ACTION_YPOSITION_FAST4B_IT, + FUI_TEXT_ACTION_YPOSITION_FAST4C_IT, + FUI_TEXT_ACTION_YPOSITION_FAST4D_IT, + FUI_TEXT_ACTION_ZPOSITION_FAST4A_IT, + FUI_TEXT_ACTION_ZPOSITION_FAST4B_IT, + FUI_TEXT_ACTION_ZPOSITION_FAST4C_IT, + FUI_TEXT_ACTION_ZPOSITION_FAST4D_IT, + FUI_TEXT_ACTION_EPOSITION_FAST2A_IT, + FUI_TEXT_ACTION_EPOSITION_FAST2B_IT, + FUI_TEXT_ACTION_XPOSITION2A_IT, + FUI_TEXT_ACTION_XPOSITION2B_IT, + FUI_TEXT_ACTION_YPOSITION2A_IT, + FUI_TEXT_ACTION_YPOSITION2B_IT, + FUI_TEXT_ACTION_ZPOSITION2A_IT, + FUI_TEXT_ACTION_ZPOSITION2B_IT, + FUI_TEXT_ACTION_XPOSITION_FAST2A_IT, + FUI_TEXT_ACTION_XPOSITION_FAST2B_IT, + FUI_TEXT_ACTION_YPOSITION_FAST2A_IT, + FUI_TEXT_ACTION_YPOSITION_FAST2B_IT, + FUI_TEXT_ACTION_ZPOSITION_FAST2A_IT, + FUI_TEXT_ACTION_ZPOSITION_FAST2B_IT, + FUI_TEXT_FANSPEED_IT, + FUI_TEXT_ACTION_FANSPEED_IT, + FUI_TEXT_FAN_OFF_IT, + FUI_TEXT_FAN_25_IT, + FUI_TEXT_FAN_50_IT, + FUI_TEXT_FAN_75_IT, + FUI_TEXT_FAN_FULL_IT, + FUI_TEXT_STEPPER_INACTIVE_IT, + FUI_TEXT_STEPPER_INACTIVE2A_IT, + FUI_TEXT_STEPPER_INACTIVE2B_IT, + FUI_TEXT_POWER_INACTIVE_IT, + FUI_TEXT_POWER_INACTIVE2A_IT, + FUI_TEXT_POWER_INACTIVE2B_IT, + FUI_TEXT_GENERAL_IT, + FUI_TEXT_BAUDRATE_IT, + FUI_TEXT_EXTR_STEPS_IT, + FUI_TEXT_EXTR_START_FEED_IT, + FUI_TEXT_EXTR_MAX_FEED_IT, + FUI_TEXT_EXTR_ACCEL_IT, + FUI_TEXT_EXTR_WATCH_IT, + FUI_TEXT_EXTR_ADVANCE_L_IT, + FUI_TEXT_EXTR_ADVANCE_K_IT, + FUI_TEXT_EXTR_MANAGER_IT, + FUI_TEXT_EXTR_PGAIN_IT, + FUI_TEXT_EXTR_DEADTIME_IT, + FUI_TEXT_EXTR_DMAX_DT_IT, + FUI_TEXT_EXTR_IGAIN_IT, + FUI_TEXT_EXTR_DGAIN_IT, + FUI_TEXT_EXTR_DMIN_IT, + FUI_TEXT_EXTR_DMAX_IT, + FUI_TEXT_EXTR_PMAX_IT, + FUI_TEXT_EXTR_XOFF_IT, + FUI_TEXT_EXTR_YOFF_IT, + FUI_TEXT_STRING_HM_BANGBANG_IT, + FUI_TEXT_STRING_HM_PID_IT, + FUI_TEXT_STRING_ACTION_IT, + FUI_TEXT_HEATING_EXTRUDER_IT, + FUI_TEXT_HEATING_BED_IT, + FUI_TEXT_KILLED_IT, + FUI_TEXT_STEPPER_DISABLED_IT, + FUI_TEXT_EEPROM_STOREDA_IT, + FUI_TEXT_EEPROM_STOREDB_IT, + FUI_TEXT_EEPROM_LOADEDA_IT, + FUI_TEXT_EEPROM_LOADEDB_IT, + FUI_TEXT_UPLOADING_IT, + FUI_TEXT_PAGE_BUFFER_IT, + FUI_TEXT_PAGE_EXTRUDER_IT, + FUI_TEXT_PAGE_EXTRUDER1_IT, + FUI_TEXT_PAGE_EXTRUDER2_IT, + FUI_TEXT_PAGE_EXTRUDER3_IT, + FUI_TEXT_PAGE_BED_IT, + FUI_TEXT_SPEED_MULTIPLY_IT, + FUI_TEXT_FLOW_MULTIPLY_IT, + FUI_TEXT_SHOW_MEASUREMENT_IT, + FUI_TEXT_RESET_MEASUREMENT_IT, + FUI_TEXT_SET_MEASURED_ORIGIN_IT, + FUI_TEXT_ZCALIB_IT, + FUI_TEXT_SET_P1_IT, + FUI_TEXT_SET_P2_IT, + FUI_TEXT_SET_P3_IT, + FUI_TEXT_CALCULATE_LEVELING_IT, + FUI_TEXT_LEVEL_IT, + FUI_TEXT_EXTR_WAIT_RETRACT_TEMP_IT, + FUI_TEXT_EXTR_WAIT_RETRACT_UNITS_IT, + FUI_TEXT_SD_REMOVED_IT, + FUI_TEXT_SD_INSERTED_IT, + FUI_TEXT_PRINTER_READY_IT, + FUI_TEXT_PRINTTIME_DAYS_IT, + FUI_TEXT_PRINTTIME_HOURS_IT, + FUI_TEXT_PRINTTIME_MINUTES_IT, + FUI_TEXT_PRINT_TIME_IT, + FUI_TEXT_PRINT_FILAMENT_IT, + FUI_TEXT_PRINTED_IT, + FUI_TEXT_POWER_IT, + FUI_TEXT_STRING_HM_DEADTIME_IT, + FUI_TEXT_STRING_HM_SLOWBANG_IT, + FUI_TEXT_STOP_PRINT_IT, + FUI_TEXT_Z_BABYSTEPPING_IT, + FUI_TEXT_CHANGE_FILAMENT_IT, + FUI_TEXT_WIZ_CH_FILAMENT1_IT, + FUI_TEXT_WIZ_CH_FILAMENT2_IT, + FUI_TEXT_WIZ_CH_FILAMENT3_IT, + FUI_TEXT_CLICK_DONE_IT, + FUI_TEXT_AUTOLEVEL_ONOFF_IT, + FUI_TEXT_SERVOPOS_IT, + FUI_TEXT_IGNORE_M106_IT, + FUI_TEXT_WIZ_REHEAT1_IT, + FUI_TEXT_WIZ_REHEAT2_IT, + FUI_TEXT_WIZ_WAITTEMP1_IT, + FUI_TEXT_WIZ_WAITTEMP2_IT, + FUI_TEXT_EXTRUDER_JAM_IT, + FUI_TEXT_STANDBY_IT, + FUI_TEXT_BED_COATING_IT, + FUI_TEXT_BED_COATING_SET1_IT, + FUI_TEXT_BED_COATING_SET2_IT, + FUI_TEXT_NOCOATING_IT, + FUI_TEXT_BUILDTAK_IT, + FUI_TEXT_KAPTON_IT, + FUI_TEXT_BLUETAPE_IT, + FUI_TEXT_PETTAPE_IT, + FUI_TEXT_GLUESTICK_IT, + FUI_TEXT_CUSTOM_IT, + FUI_TEXT_COATING_CUSTOM_IT, + FUI_TEXT_LANGUAGE_IT, + FUI_TEXT_MAINPAGE6_1_IT, + FUI_TEXT_MAINPAGE6_2_IT, + FUI_TEXT_MAINPAGE6_3_IT, + FUI_TEXT_MAINPAGE6_4_IT, + FUI_TEXT_MAINPAGE6_5_IT, + FUI_TEXT_MAINPAGE6_6_IT, + FUI_TEXT_MAINPAGE_TEMP_BED_IT, + FUI_TEXT_MAINPAGE_BED_IT, + FUI_TEXT_MAINPAGE_Z_BUF_IT, + FUI_TEXT_MAINPAGE_MUL_EUSAGE_IT, + FUI_TEXT_MAINPAGE_XY_IT, + FUI_TEXT_PRINT_TIME_VALUE_IT, + FUI_TEXT_PRINT_FILAMENT_VALUE_IT, + FUI_TEXT_METER_PRINTED_IT, + FUI_TEXT_STATUS_IT, + FUI_TEXT_EMPTY_IT, + FUI_TEXT_TEMP_SET_IT, + FUI_TEXT_CURRENT_TEMP_IT, + FUI_TEXT_COATING_THICKNESS_IT, + FUI_TEXT_EXTR3_TEMP_IT, + FUI_TEXT_EXTR4_TEMP_IT, + FUI_TEXT_EXTR5_TEMP_IT, + FUI_TEXT_EXTR3_OFF_IT, + FUI_TEXT_EXTR4_OFF_IT, + FUI_TEXT_EXTR5_OFF_IT, + FUI_TEXT_EXTR3_SELECT_IT, + FUI_TEXT_EXTR4_SELECT_IT, + FUI_TEXT_EXTR5_SELECT_IT, + FUI_TEXT_DITTO_0_IT, + FUI_TEXT_DITTO_1_IT, + FUI_TEXT_DITTO_2_IT, + FUI_TEXT_DITTO_3_IT, + FUI_TEXT_ZPROBE_HEIGHT_IT, + FUI_TEXT_OFFSETS_IT, + FUI_TEXT_X_OFFSET_IT, + FUI_TEXT_Y_OFFSET_IT, + FUI_TEXT_Z_OFFSET_IT, + FUI_TEXT_DBG_ENDSTOP_IT +}; +#define LANG_IT_TABLE translations_it +#else +#define LANG_IT_TABLE NULL +#endif // LANGUAGE_IT_ACTIVE + + +#if LANGUAGE_ES_ACTIVE +TRANS(UI_TEXT_ON_ES); +TRANS(UI_TEXT_OFF_ES); +TRANS(UI_TEXT_NA_ES); +TRANS(UI_TEXT_YES_ES); +TRANS(UI_TEXT_NO_ES); +TRANS(UI_TEXT_PRINT_POS_ES); +TRANS(UI_TEXT_PRINTING_ES); +TRANS(UI_TEXT_IDLE_ES); +TRANS(UI_TEXT_NOSDCARD_ES); +TRANS(UI_TEXT_ERROR_ES); +TRANS(UI_TEXT_BACK_ES); +TRANS(UI_TEXT_QUICK_SETTINGS_ES); +TRANS(UI_TEXT_ERRORMSG_ES); +TRANS(UI_TEXT_CONFIGURATION_ES); +TRANS(UI_TEXT_POSITION_ES); +TRANS(UI_TEXT_EXTRUDER_ES); +TRANS(UI_TEXT_SD_CARD_ES); +TRANS(UI_TEXT_DEBUGGING_ES); +TRANS(UI_TEXT_HOME_DELTA_ES); +TRANS(UI_TEXT_HOME_ALL_ES); +TRANS(UI_TEXT_HOME_X_ES); +TRANS(UI_TEXT_HOME_Y_ES); +TRANS(UI_TEXT_HOME_Z_ES); +TRANS(UI_TEXT_PREHEAT_PLA_ES); +TRANS(UI_TEXT_PREHEAT_ABS_ES); +TRANS(UI_TEXT_LIGHTS_ONOFF_ES); +TRANS(UI_TEXT_COOLDOWN_ES); +TRANS(UI_TEXT_SET_TO_ORIGIN_ES); +TRANS(UI_TEXT_DISABLE_STEPPER_ES); +TRANS(UI_TEXT_X_POSITION_ES); +TRANS(UI_TEXT_X_POS_FAST_ES); +TRANS(UI_TEXT_Y_POSITION_ES); +TRANS(UI_TEXT_Y_POS_FAST_ES); +TRANS(UI_TEXT_Z_POSITION_ES); +TRANS(UI_TEXT_Z_POS_FAST_ES); +TRANS(UI_TEXT_E_POSITION_ES); +TRANS(UI_TEXT_BED_TEMP_ES); +TRANS(UI_TEXT_EXTR0_TEMP_ES); +TRANS(UI_TEXT_EXTR1_TEMP_ES); +TRANS(UI_TEXT_EXTR2_TEMP_ES); +TRANS(UI_TEXT_EXTR0_OFF_ES); +TRANS(UI_TEXT_EXTR1_OFF_ES); +TRANS(UI_TEXT_EXTR2_OFF_ES); +TRANS(UI_TEXT_EXTR0_SELECT_ES); +TRANS(UI_TEXT_EXTR1_SELECT_ES); +TRANS(UI_TEXT_EXTR2_SELECT_ES); +TRANS(UI_TEXT_EXTR_ORIGIN_ES); +TRANS(UI_TEXT_PRINT_X_ES); +TRANS(UI_TEXT_PRINT_Y_ES); +TRANS(UI_TEXT_PRINT_Z_ES); +TRANS(UI_TEXT_PRINT_Z_DELTA_ES); +TRANS(UI_TEXT_MOVE_X_ES); +TRANS(UI_TEXT_MOVE_Y_ES); +TRANS(UI_TEXT_MOVE_Z_ES); +TRANS(UI_TEXT_MOVE_Z_DELTA_ES); +TRANS(UI_TEXT_JERK_ES); +TRANS(UI_TEXT_ZJERK_ES); +TRANS(UI_TEXT_ACCELERATION_ES); +TRANS(UI_TEXT_STORE_TO_EEPROM_ES); +TRANS(UI_TEXT_LOAD_EEPROM_ES); +TRANS(UI_TEXT_DBG_ECHO_ES); +TRANS(UI_TEXT_DBG_INFO_ES); +TRANS(UI_TEXT_DBG_ERROR_ES); +TRANS(UI_TEXT_DBG_DRYRUN_ES); +TRANS(UI_TEXT_DBG_ENDSTOP_ES); +TRANS(UI_TEXT_OPS_OFF_ES); +TRANS(UI_TEXT_OPS_CLASSIC_ES); +TRANS(UI_TEXT_OPS_FAST_ES); +TRANS(UI_TEXT_OPS_RETRACT_ES); +TRANS(UI_TEXT_OPS_BACKSLASH_ES); +TRANS(UI_TEXT_OPS_MINDIST_ES); +TRANS(UI_TEXT_OPS_MOVE_AFTER_ES); +TRANS(UI_TEXT_ANTI_OOZE_ES); +TRANS(UI_TEXT_PRINT_FILE_ES); +TRANS(UI_TEXT_PAUSE_PRINT_ES); +TRANS(UI_TEXT_CONTINUE_PRINT_ES); +TRANS(UI_TEXT_UNMOUNT_CARD_ES); +TRANS(UI_TEXT_MOUNT_CARD_ES); +TRANS(UI_TEXT_DELETE_FILE_ES); +TRANS(UI_TEXT_FEEDRATE_ES); +TRANS(UI_TEXT_FEED_MAX_X_ES); +TRANS(UI_TEXT_FEED_MAX_Y_ES); +TRANS(UI_TEXT_FEED_MAX_Z_ES); +TRANS(UI_TEXT_FEED_MAX_Z_DELTA_ES); +TRANS(UI_TEXT_FEED_HOME_X_ES); +TRANS(UI_TEXT_FEED_HOME_Y_ES); +TRANS(UI_TEXT_FEED_HOME_Z_ES); +TRANS(UI_TEXT_FEED_HOME_Z_DELTA_ES); +TRANS(UI_TEXT_ACTION_XPOSITION4A_ES); +TRANS(UI_TEXT_ACTION_XPOSITION4B_ES); +TRANS(UI_TEXT_ACTION_XPOSITION4C_ES); +TRANS(UI_TEXT_ACTION_XPOSITION4D_ES); +TRANS(UI_TEXT_ACTION_YPOSITION4A_ES); +TRANS(UI_TEXT_ACTION_YPOSITION4B_ES); +TRANS(UI_TEXT_ACTION_YPOSITION4C_ES); +TRANS(UI_TEXT_ACTION_YPOSITION4D_ES); +TRANS(UI_TEXT_ACTION_ZPOSITION4A_ES); +TRANS(UI_TEXT_ACTION_ZPOSITION4B_ES); +TRANS(UI_TEXT_ACTION_ZPOSITION4C_ES); +TRANS(UI_TEXT_ACTION_ZPOSITION4D_ES); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST4A_ES); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST4B_ES); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST4C_ES); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST4D_ES); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST4A_ES); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST4B_ES); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST4C_ES); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST4D_ES); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST4A_ES); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST4B_ES); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST4C_ES); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST4D_ES); +TRANS(UI_TEXT_ACTION_EPOSITION_FAST2A_ES); +TRANS(UI_TEXT_ACTION_EPOSITION_FAST2B_ES); +TRANS(UI_TEXT_ACTION_XPOSITION2A_ES); +TRANS(UI_TEXT_ACTION_XPOSITION2B_ES); +TRANS(UI_TEXT_ACTION_YPOSITION2A_ES); +TRANS(UI_TEXT_ACTION_YPOSITION2B_ES); +TRANS(UI_TEXT_ACTION_ZPOSITION2A_ES); +TRANS(UI_TEXT_ACTION_ZPOSITION2B_ES); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST2A_ES); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST2B_ES); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST2A_ES); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST2B_ES); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST2A_ES); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST2B_ES); +TRANS(UI_TEXT_FANSPEED_ES); +TRANS(UI_TEXT_ACTION_FANSPEED_ES); +TRANS(UI_TEXT_FAN_OFF_ES); +TRANS(UI_TEXT_FAN_25_ES); +TRANS(UI_TEXT_FAN_50_ES); +TRANS(UI_TEXT_FAN_75_ES); +TRANS(UI_TEXT_FAN_FULL_ES); +TRANS(UI_TEXT_STEPPER_INACTIVE_ES); +TRANS(UI_TEXT_STEPPER_INACTIVE2A_ES); +TRANS(UI_TEXT_STEPPER_INACTIVE2B_ES); +TRANS(UI_TEXT_POWER_INACTIVE_ES); +TRANS(UI_TEXT_POWER_INACTIVE2A_ES); +TRANS(UI_TEXT_POWER_INACTIVE2B_ES); +TRANS(UI_TEXT_GENERAL_ES); +TRANS(UI_TEXT_BAUDRATE_ES); +TRANS(UI_TEXT_EXTR_STEPS_ES); +TRANS(UI_TEXT_EXTR_START_FEED_ES); +TRANS(UI_TEXT_EXTR_MAX_FEED_ES); +TRANS(UI_TEXT_EXTR_ACCEL_ES); +TRANS(UI_TEXT_EXTR_WATCH_ES); +TRANS(UI_TEXT_EXTR_ADVANCE_L_ES); +TRANS(UI_TEXT_EXTR_ADVANCE_K_ES); +TRANS(UI_TEXT_EXTR_MANAGER_ES); +TRANS(UI_TEXT_EXTR_PGAIN_ES); +TRANS(UI_TEXT_EXTR_DEADTIME_ES); +TRANS(UI_TEXT_EXTR_DMAX_DT_ES); +TRANS(UI_TEXT_EXTR_IGAIN_ES); +TRANS(UI_TEXT_EXTR_DGAIN_ES); +TRANS(UI_TEXT_EXTR_DMIN_ES); +TRANS(UI_TEXT_EXTR_DMAX_ES); +TRANS(UI_TEXT_EXTR_PMAX_ES); +TRANS(UI_TEXT_EXTR_XOFF_ES); +TRANS(UI_TEXT_EXTR_YOFF_ES); +TRANS(UI_TEXT_STRING_HM_BANGBANG_ES); +TRANS(UI_TEXT_STRING_HM_PID_ES); +TRANS(UI_TEXT_STRING_ACTION_ES); +TRANS(UI_TEXT_HEATING_EXTRUDER_ES); +TRANS(UI_TEXT_HEATING_BED_ES); +TRANS(UI_TEXT_KILLED_ES); +TRANS(UI_TEXT_STEPPER_DISABLED_ES); +TRANS(UI_TEXT_EEPROM_STOREDA_ES); +TRANS(UI_TEXT_EEPROM_STOREDB_ES); +TRANS(UI_TEXT_EEPROM_LOADEDA_ES); +TRANS(UI_TEXT_EEPROM_LOADEDB_ES); +TRANS(UI_TEXT_UPLOADING_ES); +TRANS(UI_TEXT_PAGE_BUFFER_ES); +TRANS(UI_TEXT_PAGE_EXTRUDER_ES); +TRANS(UI_TEXT_PAGE_EXTRUDER1_ES); +TRANS(UI_TEXT_PAGE_EXTRUDER2_ES); +TRANS(UI_TEXT_PAGE_EXTRUDER3_ES); +TRANS(UI_TEXT_PAGE_BED_ES); +TRANS(UI_TEXT_SPEED_MULTIPLY_ES); +TRANS(UI_TEXT_FLOW_MULTIPLY_ES); +TRANS(UI_TEXT_SHOW_MEASUREMENT_ES); +TRANS(UI_TEXT_RESET_MEASUREMENT_ES); +TRANS(UI_TEXT_SET_MEASURED_ORIGIN_ES); +TRANS(UI_TEXT_ZCALIB_ES); +TRANS(UI_TEXT_SET_P1_ES); +TRANS(UI_TEXT_SET_P2_ES); +TRANS(UI_TEXT_SET_P3_ES); +TRANS(UI_TEXT_CALCULATE_LEVELING_ES); +TRANS(UI_TEXT_LEVEL_ES); +TRANS(UI_TEXT_EXTR_WAIT_RETRACT_TEMP_ES); +TRANS(UI_TEXT_EXTR_WAIT_RETRACT_UNITS_ES); +TRANS(UI_TEXT_SD_REMOVED_ES); +TRANS(UI_TEXT_SD_INSERTED_ES); +TRANS(UI_TEXT_PRINTER_READY_ES); +TRANS(UI_TEXT_PRINTTIME_DAYS_ES); +TRANS(UI_TEXT_PRINTTIME_HOURS_ES); +TRANS(UI_TEXT_PRINTTIME_MINUTES_ES); +TRANS(UI_TEXT_PRINT_TIME_ES); +TRANS(UI_TEXT_PRINT_FILAMENT_ES); +TRANS(UI_TEXT_PRINTED_ES); +TRANS(UI_TEXT_POWER_ES); +TRANS(UI_TEXT_STRING_HM_DEADTIME_ES); +TRANS(UI_TEXT_STRING_HM_SLOWBANG_ES); +TRANS(UI_TEXT_STOP_PRINT_ES); +TRANS(UI_TEXT_Z_BABYSTEPPING_ES); +TRANS(UI_TEXT_CHANGE_FILAMENT_ES); +TRANS(UI_TEXT_WIZ_CH_FILAMENT1_ES); +TRANS(UI_TEXT_WIZ_CH_FILAMENT2_ES); +TRANS(UI_TEXT_WIZ_CH_FILAMENT3_ES); +TRANS(UI_TEXT_CLICK_DONE_ES); +TRANS(UI_TEXT_AUTOLEVEL_ONOFF_ES); +TRANS(UI_TEXT_SERVOPOS_ES); +TRANS(UI_TEXT_IGNORE_M106_ES); +TRANS(UI_TEXT_WIZ_REHEAT1_ES); +TRANS(UI_TEXT_WIZ_REHEAT2_ES); +TRANS(UI_TEXT_WIZ_WAITTEMP1_ES); +TRANS(UI_TEXT_WIZ_WAITTEMP2_ES); +TRANS(UI_TEXT_EXTRUDER_JAM_ES); +TRANS(UI_TEXT_STANDBY_ES); +TRANS(UI_TEXT_BED_COATING_ES); +TRANS(UI_TEXT_BED_COATING_SET1_ES); +TRANS(UI_TEXT_BED_COATING_SET2_ES); +TRANS(UI_TEXT_NOCOATING_ES); +TRANS(UI_TEXT_BUILDTAK_ES); +TRANS(UI_TEXT_KAPTON_ES); +TRANS(UI_TEXT_BLUETAPE_ES); +TRANS(UI_TEXT_PETTAPE_ES); +TRANS(UI_TEXT_GLUESTICK_ES); +TRANS(UI_TEXT_CUSTOM_ES); +TRANS(UI_TEXT_COATING_CUSTOM_ES); +TRANS(UI_TEXT_LANGUAGE_ES); +TRANS(UI_TEXT_MAINPAGE6_1_ES); +TRANS(UI_TEXT_MAINPAGE6_2_ES); +TRANS(UI_TEXT_MAINPAGE6_3_ES); +TRANS(UI_TEXT_MAINPAGE6_4_ES); +TRANS(UI_TEXT_MAINPAGE6_5_ES); +TRANS(UI_TEXT_MAINPAGE6_6_ES); +TRANS(UI_TEXT_MAINPAGE_TEMP_BED_ES); +TRANS(UI_TEXT_MAINPAGE_BED_ES); +TRANS(UI_TEXT_MAINPAGE_Z_BUF_ES); +TRANS(UI_TEXT_MAINPAGE_MUL_EUSAGE_ES); +TRANS(UI_TEXT_MAINPAGE_XY_ES); +TRANS(UI_TEXT_PRINT_TIME_VALUE_ES); +TRANS(UI_TEXT_PRINT_FILAMENT_VALUE_ES); +TRANS(UI_TEXT_METER_PRINTED_ES); +TRANS(UI_TEXT_STATUS_ES); +TRANS(UI_TEXT_EMPTY_ES); +TRANS(UI_TEXT_TEMP_SET_ES); +TRANS(UI_TEXT_CURRENT_TEMP_ES); +TRANS(UI_TEXT_COATING_THICKNESS_ES); +TRANS(UI_TEXT_EXTR3_TEMP_ES); +TRANS(UI_TEXT_EXTR4_TEMP_ES); +TRANS(UI_TEXT_EXTR5_TEMP_ES); +TRANS(UI_TEXT_EXTR3_OFF_ES); +TRANS(UI_TEXT_EXTR4_OFF_ES); +TRANS(UI_TEXT_EXTR5_OFF_ES); +TRANS(UI_TEXT_EXTR3_SELECT_ES); +TRANS(UI_TEXT_EXTR4_SELECT_ES); +TRANS(UI_TEXT_EXTR5_SELECT_ES); +TRANS(UI_TEXT_DITTO_0_ES); +TRANS(UI_TEXT_DITTO_1_ES); +TRANS(UI_TEXT_DITTO_2_ES); +TRANS(UI_TEXT_DITTO_3_ES); +TRANS(UI_TEXT_ZPROBE_HEIGHT_ES); +TRANS(UI_TEXT_OFFSETS_ES); +TRANS(UI_TEXT_X_OFFSET_ES); +TRANS(UI_TEXT_Y_OFFSET_ES); +TRANS(UI_TEXT_Z_OFFSET_ES); + +PGM_P const translations_es[NUM_TRANSLATED_WORDS] PROGMEM = { + FUI_TEXT_ON_ES, + FUI_TEXT_OFF_ES, + FUI_TEXT_NA_ES, + FUI_TEXT_YES_ES, + FUI_TEXT_NO_ES, + FUI_TEXT_PRINT_POS_ES, + FUI_TEXT_PRINTING_ES, + FUI_TEXT_IDLE_ES, + FUI_TEXT_NOSDCARD_ES, + FUI_TEXT_ERROR_ES, + FUI_TEXT_BACK_ES, + FUI_TEXT_QUICK_SETTINGS_ES, + FUI_TEXT_ERRORMSG_ES, + FUI_TEXT_CONFIGURATION_ES, + FUI_TEXT_POSITION_ES, + FUI_TEXT_EXTRUDER_ES, + FUI_TEXT_SD_CARD_ES, + FUI_TEXT_DEBUGGING_ES, + FUI_TEXT_HOME_DELTA_ES, + FUI_TEXT_HOME_ALL_ES, + FUI_TEXT_HOME_X_ES, + FUI_TEXT_HOME_Y_ES, + FUI_TEXT_HOME_Z_ES, + FUI_TEXT_PREHEAT_PLA_ES, + FUI_TEXT_PREHEAT_ABS_ES, + FUI_TEXT_LIGHTS_ONOFF_ES, + FUI_TEXT_COOLDOWN_ES, + FUI_TEXT_SET_TO_ORIGIN_ES, + FUI_TEXT_DISABLE_STEPPER_ES, + FUI_TEXT_X_POSITION_ES, + FUI_TEXT_X_POS_FAST_ES, + FUI_TEXT_Y_POSITION_ES, + FUI_TEXT_Y_POS_FAST_ES, + FUI_TEXT_Z_POSITION_ES, + FUI_TEXT_Z_POS_FAST_ES, + FUI_TEXT_E_POSITION_ES, + FUI_TEXT_BED_TEMP_ES, + FUI_TEXT_EXTR0_TEMP_ES, + FUI_TEXT_EXTR1_TEMP_ES, + FUI_TEXT_EXTR2_TEMP_ES, + FUI_TEXT_EXTR0_OFF_ES, + FUI_TEXT_EXTR1_OFF_ES, + FUI_TEXT_EXTR2_OFF_ES, + FUI_TEXT_EXTR0_SELECT_ES, + FUI_TEXT_EXTR1_SELECT_ES, + FUI_TEXT_EXTR2_SELECT_ES, + FUI_TEXT_EXTR_ORIGIN_ES, + FUI_TEXT_PRINT_X_ES, + FUI_TEXT_PRINT_Y_ES, + FUI_TEXT_PRINT_Z_ES, + FUI_TEXT_PRINT_Z_DELTA_ES, + FUI_TEXT_MOVE_X_ES, + FUI_TEXT_MOVE_Y_ES, + FUI_TEXT_MOVE_Z_ES, + FUI_TEXT_MOVE_Z_DELTA_ES, + FUI_TEXT_JERK_ES, + FUI_TEXT_ZJERK_ES, + FUI_TEXT_ACCELERATION_ES, + FUI_TEXT_STORE_TO_EEPROM_ES, + FUI_TEXT_LOAD_EEPROM_ES, + FUI_TEXT_DBG_ECHO_ES, + FUI_TEXT_DBG_INFO_ES, + FUI_TEXT_DBG_ERROR_ES, + FUI_TEXT_DBG_DRYRUN_ES, + FUI_TEXT_OPS_OFF_ES, + FUI_TEXT_OPS_CLASSIC_ES, + FUI_TEXT_OPS_FAST_ES, + FUI_TEXT_OPS_RETRACT_ES, + FUI_TEXT_OPS_BACKSLASH_ES, + FUI_TEXT_OPS_MINDIST_ES, + FUI_TEXT_OPS_MOVE_AFTER_ES, + FUI_TEXT_ANTI_OOZE_ES, + FUI_TEXT_PRINT_FILE_ES, + FUI_TEXT_PAUSE_PRINT_ES, + FUI_TEXT_CONTINUE_PRINT_ES, + FUI_TEXT_UNMOUNT_CARD_ES, + FUI_TEXT_MOUNT_CARD_ES, + FUI_TEXT_DELETE_FILE_ES, + FUI_TEXT_FEEDRATE_ES, + FUI_TEXT_FEED_MAX_X_ES, + FUI_TEXT_FEED_MAX_Y_ES, + FUI_TEXT_FEED_MAX_Z_ES, + FUI_TEXT_FEED_MAX_Z_DELTA_ES, + FUI_TEXT_FEED_HOME_X_ES, + FUI_TEXT_FEED_HOME_Y_ES, + FUI_TEXT_FEED_HOME_Z_ES, + FUI_TEXT_FEED_HOME_Z_DELTA_ES, + FUI_TEXT_ACTION_XPOSITION4A_ES, + FUI_TEXT_ACTION_XPOSITION4B_ES, + FUI_TEXT_ACTION_XPOSITION4C_ES, + FUI_TEXT_ACTION_XPOSITION4D_ES, + FUI_TEXT_ACTION_YPOSITION4A_ES, + FUI_TEXT_ACTION_YPOSITION4B_ES, + FUI_TEXT_ACTION_YPOSITION4C_ES, + FUI_TEXT_ACTION_YPOSITION4D_ES, + FUI_TEXT_ACTION_ZPOSITION4A_ES, + FUI_TEXT_ACTION_ZPOSITION4B_ES, + FUI_TEXT_ACTION_ZPOSITION4C_ES, + FUI_TEXT_ACTION_ZPOSITION4D_ES, + FUI_TEXT_ACTION_XPOSITION_FAST4A_ES, + FUI_TEXT_ACTION_XPOSITION_FAST4B_ES, + FUI_TEXT_ACTION_XPOSITION_FAST4C_ES, + FUI_TEXT_ACTION_XPOSITION_FAST4D_ES, + FUI_TEXT_ACTION_YPOSITION_FAST4A_ES, + FUI_TEXT_ACTION_YPOSITION_FAST4B_ES, + FUI_TEXT_ACTION_YPOSITION_FAST4C_ES, + FUI_TEXT_ACTION_YPOSITION_FAST4D_ES, + FUI_TEXT_ACTION_ZPOSITION_FAST4A_ES, + FUI_TEXT_ACTION_ZPOSITION_FAST4B_ES, + FUI_TEXT_ACTION_ZPOSITION_FAST4C_ES, + FUI_TEXT_ACTION_ZPOSITION_FAST4D_ES, + FUI_TEXT_ACTION_EPOSITION_FAST2A_ES, + FUI_TEXT_ACTION_EPOSITION_FAST2B_ES, + FUI_TEXT_ACTION_XPOSITION2A_ES, + FUI_TEXT_ACTION_XPOSITION2B_ES, + FUI_TEXT_ACTION_YPOSITION2A_ES, + FUI_TEXT_ACTION_YPOSITION2B_ES, + FUI_TEXT_ACTION_ZPOSITION2A_ES, + FUI_TEXT_ACTION_ZPOSITION2B_ES, + FUI_TEXT_ACTION_XPOSITION_FAST2A_ES, + FUI_TEXT_ACTION_XPOSITION_FAST2B_ES, + FUI_TEXT_ACTION_YPOSITION_FAST2A_ES, + FUI_TEXT_ACTION_YPOSITION_FAST2B_ES, + FUI_TEXT_ACTION_ZPOSITION_FAST2A_ES, + FUI_TEXT_ACTION_ZPOSITION_FAST2B_ES, + FUI_TEXT_FANSPEED_ES, + FUI_TEXT_ACTION_FANSPEED_ES, + FUI_TEXT_FAN_OFF_ES, + FUI_TEXT_FAN_25_ES, + FUI_TEXT_FAN_50_ES, + FUI_TEXT_FAN_75_ES, + FUI_TEXT_FAN_FULL_ES, + FUI_TEXT_STEPPER_INACTIVE_ES, + FUI_TEXT_STEPPER_INACTIVE2A_ES, + FUI_TEXT_STEPPER_INACTIVE2B_ES, + FUI_TEXT_POWER_INACTIVE_ES, + FUI_TEXT_POWER_INACTIVE2A_ES, + FUI_TEXT_POWER_INACTIVE2B_ES, + FUI_TEXT_GENERAL_ES, + FUI_TEXT_BAUDRATE_ES, + FUI_TEXT_EXTR_STEPS_ES, + FUI_TEXT_EXTR_START_FEED_ES, + FUI_TEXT_EXTR_MAX_FEED_ES, + FUI_TEXT_EXTR_ACCEL_ES, + FUI_TEXT_EXTR_WATCH_ES, + FUI_TEXT_EXTR_ADVANCE_L_ES, + FUI_TEXT_EXTR_ADVANCE_K_ES, + FUI_TEXT_EXTR_MANAGER_ES, + FUI_TEXT_EXTR_PGAIN_ES, + FUI_TEXT_EXTR_DEADTIME_ES, + FUI_TEXT_EXTR_DMAX_DT_ES, + FUI_TEXT_EXTR_IGAIN_ES, + FUI_TEXT_EXTR_DGAIN_ES, + FUI_TEXT_EXTR_DMIN_ES, + FUI_TEXT_EXTR_DMAX_ES, + FUI_TEXT_EXTR_PMAX_ES, + FUI_TEXT_EXTR_XOFF_ES, + FUI_TEXT_EXTR_YOFF_ES, + FUI_TEXT_STRING_HM_BANGBANG_ES, + FUI_TEXT_STRING_HM_PID_ES, + FUI_TEXT_STRING_ACTION_ES, + FUI_TEXT_HEATING_EXTRUDER_ES, + FUI_TEXT_HEATING_BED_ES, + FUI_TEXT_KILLED_ES, + FUI_TEXT_STEPPER_DISABLED_ES, + FUI_TEXT_EEPROM_STOREDA_ES, + FUI_TEXT_EEPROM_STOREDB_ES, + FUI_TEXT_EEPROM_LOADEDA_ES, + FUI_TEXT_EEPROM_LOADEDB_ES, + FUI_TEXT_UPLOADING_ES, + FUI_TEXT_PAGE_BUFFER_ES, + FUI_TEXT_PAGE_EXTRUDER_ES, + FUI_TEXT_PAGE_EXTRUDER1_ES, + FUI_TEXT_PAGE_EXTRUDER2_ES, + FUI_TEXT_PAGE_EXTRUDER3_ES, + FUI_TEXT_PAGE_BED_ES, + FUI_TEXT_SPEED_MULTIPLY_ES, + FUI_TEXT_FLOW_MULTIPLY_ES, + FUI_TEXT_SHOW_MEASUREMENT_ES, + FUI_TEXT_RESET_MEASUREMENT_ES, + FUI_TEXT_SET_MEASURED_ORIGIN_ES, + FUI_TEXT_ZCALIB_ES, + FUI_TEXT_SET_P1_ES, + FUI_TEXT_SET_P2_ES, + FUI_TEXT_SET_P3_ES, + FUI_TEXT_CALCULATE_LEVELING_ES, + FUI_TEXT_LEVEL_ES, + FUI_TEXT_EXTR_WAIT_RETRACT_TEMP_ES, + FUI_TEXT_EXTR_WAIT_RETRACT_UNITS_ES, + FUI_TEXT_SD_REMOVED_ES, + FUI_TEXT_SD_INSERTED_ES, + FUI_TEXT_PRINTER_READY_ES, + FUI_TEXT_PRINTTIME_DAYS_ES, + FUI_TEXT_PRINTTIME_HOURS_ES, + FUI_TEXT_PRINTTIME_MINUTES_ES, + FUI_TEXT_PRINT_TIME_ES, + FUI_TEXT_PRINT_FILAMENT_ES, + FUI_TEXT_PRINTED_ES, + FUI_TEXT_POWER_ES, + FUI_TEXT_STRING_HM_DEADTIME_ES, + FUI_TEXT_STRING_HM_SLOWBANG_ES, + FUI_TEXT_STOP_PRINT_ES, + FUI_TEXT_Z_BABYSTEPPING_ES, + FUI_TEXT_CHANGE_FILAMENT_ES, + FUI_TEXT_WIZ_CH_FILAMENT1_ES, + FUI_TEXT_WIZ_CH_FILAMENT2_ES, + FUI_TEXT_WIZ_CH_FILAMENT3_ES, + FUI_TEXT_CLICK_DONE_ES, + FUI_TEXT_AUTOLEVEL_ONOFF_ES, + FUI_TEXT_SERVOPOS_ES, + FUI_TEXT_IGNORE_M106_ES, + FUI_TEXT_WIZ_REHEAT1_ES, + FUI_TEXT_WIZ_REHEAT2_ES, + FUI_TEXT_WIZ_WAITTEMP1_ES, + FUI_TEXT_WIZ_WAITTEMP2_ES, + FUI_TEXT_EXTRUDER_JAM_ES, + FUI_TEXT_STANDBY_ES, + FUI_TEXT_BED_COATING_ES, + FUI_TEXT_BED_COATING_SET1_ES, + FUI_TEXT_BED_COATING_SET2_ES, + FUI_TEXT_NOCOATING_ES, + FUI_TEXT_BUILDTAK_ES, + FUI_TEXT_KAPTON_ES, + FUI_TEXT_BLUETAPE_ES, + FUI_TEXT_PETTAPE_ES, + FUI_TEXT_GLUESTICK_ES, + FUI_TEXT_CUSTOM_ES, + FUI_TEXT_COATING_CUSTOM_ES, + FUI_TEXT_LANGUAGE_ES, + FUI_TEXT_MAINPAGE6_1_ES, + FUI_TEXT_MAINPAGE6_2_ES, + FUI_TEXT_MAINPAGE6_3_ES, + FUI_TEXT_MAINPAGE6_4_ES, + FUI_TEXT_MAINPAGE6_5_ES, + FUI_TEXT_MAINPAGE6_6_ES, + FUI_TEXT_MAINPAGE_TEMP_BED_ES, + FUI_TEXT_MAINPAGE_BED_ES, + FUI_TEXT_MAINPAGE_Z_BUF_ES, + FUI_TEXT_MAINPAGE_MUL_EUSAGE_ES, + FUI_TEXT_MAINPAGE_XY_ES, + FUI_TEXT_PRINT_TIME_VALUE_ES, + FUI_TEXT_PRINT_FILAMENT_VALUE_ES, + FUI_TEXT_METER_PRINTED_ES, + FUI_TEXT_STATUS_ES, + FUI_TEXT_EMPTY_ES, + FUI_TEXT_TEMP_SET_ES, + FUI_TEXT_CURRENT_TEMP_ES, + FUI_TEXT_COATING_THICKNESS_ES, + FUI_TEXT_EXTR3_TEMP_ES, + FUI_TEXT_EXTR4_TEMP_ES, + FUI_TEXT_EXTR5_TEMP_ES, + FUI_TEXT_EXTR3_OFF_ES, + FUI_TEXT_EXTR4_OFF_ES, + FUI_TEXT_EXTR5_OFF_ES, + FUI_TEXT_EXTR3_SELECT_ES, + FUI_TEXT_EXTR4_SELECT_ES, + FUI_TEXT_EXTR5_SELECT_ES, + FUI_TEXT_DITTO_0_ES, + FUI_TEXT_DITTO_1_ES, + FUI_TEXT_DITTO_2_ES, + FUI_TEXT_DITTO_3_ES, + FUI_TEXT_ZPROBE_HEIGHT_ES, + FUI_TEXT_OFFSETS_ES, + FUI_TEXT_X_OFFSET_ES, + FUI_TEXT_Y_OFFSET_ES, + FUI_TEXT_Z_OFFSET_ES, + FUI_TEXT_DBG_ENDSTOP_ES +}; +#define LANG_ES_TABLE translations_es +#else +#define LANG_ES_TABLE NULL +#endif // LANGUAGE_ES_ACTIVE + + +#if LANGUAGE_SE_ACTIVE +TRANS(UI_TEXT_ON_SE); +TRANS(UI_TEXT_OFF_SE); +TRANS(UI_TEXT_NA_SE); +TRANS(UI_TEXT_YES_SE); +TRANS(UI_TEXT_NO_SE); +TRANS(UI_TEXT_PRINT_POS_SE); +TRANS(UI_TEXT_PRINTING_SE); +TRANS(UI_TEXT_IDLE_SE); +TRANS(UI_TEXT_NOSDCARD_SE); +TRANS(UI_TEXT_ERROR_SE); +TRANS(UI_TEXT_BACK_SE); +TRANS(UI_TEXT_QUICK_SETTINGS_SE); +TRANS(UI_TEXT_ERRORMSG_SE); +TRANS(UI_TEXT_CONFIGURATION_SE); +TRANS(UI_TEXT_POSITION_SE); +TRANS(UI_TEXT_EXTRUDER_SE); +TRANS(UI_TEXT_SD_CARD_SE); +TRANS(UI_TEXT_DEBUGGING_SE); +TRANS(UI_TEXT_HOME_DELTA_SE); +TRANS(UI_TEXT_HOME_ALL_SE); +TRANS(UI_TEXT_HOME_X_SE); +TRANS(UI_TEXT_HOME_Y_SE); +TRANS(UI_TEXT_HOME_Z_SE); +TRANS(UI_TEXT_PREHEAT_PLA_SE); +TRANS(UI_TEXT_PREHEAT_ABS_SE); +TRANS(UI_TEXT_LIGHTS_ONOFF_SE); +TRANS(UI_TEXT_COOLDOWN_SE); +TRANS(UI_TEXT_SET_TO_ORIGIN_SE); +TRANS(UI_TEXT_DISABLE_STEPPER_SE); +TRANS(UI_TEXT_X_POSITION_SE); +TRANS(UI_TEXT_X_POS_FAST_SE); +TRANS(UI_TEXT_Y_POSITION_SE); +TRANS(UI_TEXT_Y_POS_FAST_SE); +TRANS(UI_TEXT_Z_POSITION_SE); +TRANS(UI_TEXT_Z_POS_FAST_SE); +TRANS(UI_TEXT_E_POSITION_SE); +TRANS(UI_TEXT_BED_TEMP_SE); +TRANS(UI_TEXT_EXTR0_TEMP_SE); +TRANS(UI_TEXT_EXTR1_TEMP_SE); +TRANS(UI_TEXT_EXTR2_TEMP_SE); +TRANS(UI_TEXT_EXTR0_OFF_SE); +TRANS(UI_TEXT_EXTR1_OFF_SE); +TRANS(UI_TEXT_EXTR2_OFF_SE); +TRANS(UI_TEXT_EXTR0_SELECT_SE); +TRANS(UI_TEXT_EXTR1_SELECT_SE); +TRANS(UI_TEXT_EXTR2_SELECT_SE); +TRANS(UI_TEXT_EXTR_ORIGIN_SE); +TRANS(UI_TEXT_PRINT_X_SE); +TRANS(UI_TEXT_PRINT_Y_SE); +TRANS(UI_TEXT_PRINT_Z_SE); +TRANS(UI_TEXT_PRINT_Z_DELTA_SE); +TRANS(UI_TEXT_MOVE_X_SE); +TRANS(UI_TEXT_MOVE_Y_SE); +TRANS(UI_TEXT_MOVE_Z_SE); +TRANS(UI_TEXT_MOVE_Z_DELTA_SE); +TRANS(UI_TEXT_JERK_SE); +TRANS(UI_TEXT_ZJERK_SE); +TRANS(UI_TEXT_ACCELERATION_SE); +TRANS(UI_TEXT_STORE_TO_EEPROM_SE); +TRANS(UI_TEXT_LOAD_EEPROM_SE); +TRANS(UI_TEXT_DBG_ECHO_SE); +TRANS(UI_TEXT_DBG_INFO_SE); +TRANS(UI_TEXT_DBG_ERROR_SE); +TRANS(UI_TEXT_DBG_DRYRUN_SE); +TRANS(UI_TEXT_DBG_ENDSTOP_SE); +TRANS(UI_TEXT_OPS_OFF_SE); +TRANS(UI_TEXT_OPS_CLASSIC_SE); +TRANS(UI_TEXT_OPS_FAST_SE); +TRANS(UI_TEXT_OPS_RETRACT_SE); +TRANS(UI_TEXT_OPS_BACKSLASH_SE); +TRANS(UI_TEXT_OPS_MINDIST_SE); +TRANS(UI_TEXT_OPS_MOVE_AFTER_SE); +TRANS(UI_TEXT_ANTI_OOZE_SE); +TRANS(UI_TEXT_PRINT_FILE_SE); +TRANS(UI_TEXT_PAUSE_PRINT_SE); +TRANS(UI_TEXT_CONTINUE_PRINT_SE); +TRANS(UI_TEXT_UNMOUNT_CARD_SE); +TRANS(UI_TEXT_MOUNT_CARD_SE); +TRANS(UI_TEXT_DELETE_FILE_SE); +TRANS(UI_TEXT_FEEDRATE_SE); +TRANS(UI_TEXT_FEED_MAX_X_SE); +TRANS(UI_TEXT_FEED_MAX_Y_SE); +TRANS(UI_TEXT_FEED_MAX_Z_SE); +TRANS(UI_TEXT_FEED_MAX_Z_DELTA_SE); +TRANS(UI_TEXT_FEED_HOME_X_SE); +TRANS(UI_TEXT_FEED_HOME_Y_SE); +TRANS(UI_TEXT_FEED_HOME_Z_SE); +TRANS(UI_TEXT_FEED_HOME_Z_DELTA_SE); +TRANS(UI_TEXT_ACTION_XPOSITION4A_SE); +TRANS(UI_TEXT_ACTION_XPOSITION4B_SE); +TRANS(UI_TEXT_ACTION_XPOSITION4C_SE); +TRANS(UI_TEXT_ACTION_XPOSITION4D_SE); +TRANS(UI_TEXT_ACTION_YPOSITION4A_SE); +TRANS(UI_TEXT_ACTION_YPOSITION4B_SE); +TRANS(UI_TEXT_ACTION_YPOSITION4C_SE); +TRANS(UI_TEXT_ACTION_YPOSITION4D_SE); +TRANS(UI_TEXT_ACTION_ZPOSITION4A_SE); +TRANS(UI_TEXT_ACTION_ZPOSITION4B_SE); +TRANS(UI_TEXT_ACTION_ZPOSITION4C_SE); +TRANS(UI_TEXT_ACTION_ZPOSITION4D_SE); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST4A_SE); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST4B_SE); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST4C_SE); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST4D_SE); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST4A_SE); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST4B_SE); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST4C_SE); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST4D_SE); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST4A_SE); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST4B_SE); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST4C_SE); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST4D_SE); +TRANS(UI_TEXT_ACTION_EPOSITION_FAST2A_SE); +TRANS(UI_TEXT_ACTION_EPOSITION_FAST2B_SE); +TRANS(UI_TEXT_ACTION_XPOSITION2A_SE); +TRANS(UI_TEXT_ACTION_XPOSITION2B_SE); +TRANS(UI_TEXT_ACTION_YPOSITION2A_SE); +TRANS(UI_TEXT_ACTION_YPOSITION2B_SE); +TRANS(UI_TEXT_ACTION_ZPOSITION2A_SE); +TRANS(UI_TEXT_ACTION_ZPOSITION2B_SE); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST2A_SE); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST2B_SE); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST2A_SE); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST2B_SE); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST2A_SE); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST2B_SE); +TRANS(UI_TEXT_FANSPEED_SE); +TRANS(UI_TEXT_ACTION_FANSPEED_SE); +TRANS(UI_TEXT_FAN_OFF_SE); +TRANS(UI_TEXT_FAN_25_SE); +TRANS(UI_TEXT_FAN_50_SE); +TRANS(UI_TEXT_FAN_75_SE); +TRANS(UI_TEXT_FAN_FULL_SE); +TRANS(UI_TEXT_STEPPER_INACTIVE_SE); +TRANS(UI_TEXT_STEPPER_INACTIVE2A_SE); +TRANS(UI_TEXT_STEPPER_INACTIVE2B_SE); +TRANS(UI_TEXT_POWER_INACTIVE_SE); +TRANS(UI_TEXT_POWER_INACTIVE2A_SE); +TRANS(UI_TEXT_POWER_INACTIVE2B_SE); +TRANS(UI_TEXT_GENERAL_SE); +TRANS(UI_TEXT_BAUDRATE_SE); +TRANS(UI_TEXT_EXTR_STEPS_SE); +TRANS(UI_TEXT_EXTR_START_FEED_SE); +TRANS(UI_TEXT_EXTR_MAX_FEED_SE); +TRANS(UI_TEXT_EXTR_ACCEL_SE); +TRANS(UI_TEXT_EXTR_WATCH_SE); +TRANS(UI_TEXT_EXTR_ADVANCE_L_SE); +TRANS(UI_TEXT_EXTR_ADVANCE_K_SE); +TRANS(UI_TEXT_EXTR_MANAGER_SE); +TRANS(UI_TEXT_EXTR_PGAIN_SE); +TRANS(UI_TEXT_EXTR_DEADTIME_SE); +TRANS(UI_TEXT_EXTR_DMAX_DT_SE); +TRANS(UI_TEXT_EXTR_IGAIN_SE); +TRANS(UI_TEXT_EXTR_DGAIN_SE); +TRANS(UI_TEXT_EXTR_DMIN_SE); +TRANS(UI_TEXT_EXTR_DMAX_SE); +TRANS(UI_TEXT_EXTR_PMAX_SE); +TRANS(UI_TEXT_EXTR_XOFF_SE); +TRANS(UI_TEXT_EXTR_YOFF_SE); +TRANS(UI_TEXT_STRING_HM_BANGBANG_SE); +TRANS(UI_TEXT_STRING_HM_PID_SE); +TRANS(UI_TEXT_STRING_ACTION_SE); +TRANS(UI_TEXT_HEATING_EXTRUDER_SE); +TRANS(UI_TEXT_HEATING_BED_SE); +TRANS(UI_TEXT_KILLED_SE); +TRANS(UI_TEXT_STEPPER_DISABLED_SE); +TRANS(UI_TEXT_EEPROM_STOREDA_SE); +TRANS(UI_TEXT_EEPROM_STOREDB_SE); +TRANS(UI_TEXT_EEPROM_LOADEDA_SE); +TRANS(UI_TEXT_EEPROM_LOADEDB_SE); +TRANS(UI_TEXT_UPLOADING_SE); +TRANS(UI_TEXT_PAGE_BUFFER_SE); +TRANS(UI_TEXT_PAGE_EXTRUDER_SE); +TRANS(UI_TEXT_PAGE_EXTRUDER1_SE); +TRANS(UI_TEXT_PAGE_EXTRUDER2_SE); +TRANS(UI_TEXT_PAGE_EXTRUDER3_SE); +TRANS(UI_TEXT_PAGE_BED_SE); +TRANS(UI_TEXT_SPEED_MULTIPLY_SE); +TRANS(UI_TEXT_FLOW_MULTIPLY_SE); +TRANS(UI_TEXT_SHOW_MEASUREMENT_SE); +TRANS(UI_TEXT_RESET_MEASUREMENT_SE); +TRANS(UI_TEXT_SET_MEASURED_ORIGIN_SE); +TRANS(UI_TEXT_ZCALIB_SE); +TRANS(UI_TEXT_SET_P1_SE); +TRANS(UI_TEXT_SET_P2_SE); +TRANS(UI_TEXT_SET_P3_SE); +TRANS(UI_TEXT_CALCULATE_LEVELING_SE); +TRANS(UI_TEXT_LEVEL_SE); +TRANS(UI_TEXT_EXTR_WAIT_RETRACT_TEMP_SE); +TRANS(UI_TEXT_EXTR_WAIT_RETRACT_UNITS_SE); +TRANS(UI_TEXT_SD_REMOVED_SE); +TRANS(UI_TEXT_SD_INSERTED_SE); +TRANS(UI_TEXT_PRINTER_READY_SE); +TRANS(UI_TEXT_PRINTTIME_DAYS_SE); +TRANS(UI_TEXT_PRINTTIME_HOURS_SE); +TRANS(UI_TEXT_PRINTTIME_MINUTES_SE); +TRANS(UI_TEXT_PRINT_TIME_SE); +TRANS(UI_TEXT_PRINT_FILAMENT_SE); +TRANS(UI_TEXT_PRINTED_SE); +TRANS(UI_TEXT_POWER_SE); +TRANS(UI_TEXT_STRING_HM_DEADTIME_SE); +TRANS(UI_TEXT_STRING_HM_SLOWBANG_SE); +TRANS(UI_TEXT_STOP_PRINT_SE); +TRANS(UI_TEXT_Z_BABYSTEPPING_SE); +TRANS(UI_TEXT_CHANGE_FILAMENT_SE); +TRANS(UI_TEXT_WIZ_CH_FILAMENT1_SE); +TRANS(UI_TEXT_WIZ_CH_FILAMENT2_SE); +TRANS(UI_TEXT_WIZ_CH_FILAMENT3_SE); +TRANS(UI_TEXT_CLICK_DONE_SE); +TRANS(UI_TEXT_AUTOLEVEL_ONOFF_SE); +TRANS(UI_TEXT_SERVOPOS_SE); +TRANS(UI_TEXT_IGNORE_M106_SE); +TRANS(UI_TEXT_WIZ_REHEAT1_SE); +TRANS(UI_TEXT_WIZ_REHEAT2_SE); +TRANS(UI_TEXT_WIZ_WAITTEMP1_SE); +TRANS(UI_TEXT_WIZ_WAITTEMP2_SE); +TRANS(UI_TEXT_EXTRUDER_JAM_SE); +TRANS(UI_TEXT_STANDBY_SE); +TRANS(UI_TEXT_BED_COATING_SE); +TRANS(UI_TEXT_BED_COATING_SET1_SE); +TRANS(UI_TEXT_BED_COATING_SET2_SE); +TRANS(UI_TEXT_NOCOATING_SE); +TRANS(UI_TEXT_BUILDTAK_SE); +TRANS(UI_TEXT_KAPTON_SE); +TRANS(UI_TEXT_BLUETAPE_SE); +TRANS(UI_TEXT_PETTAPE_SE); +TRANS(UI_TEXT_GLUESTICK_SE); +TRANS(UI_TEXT_CUSTOM_SE); +TRANS(UI_TEXT_COATING_CUSTOM_SE); +TRANS(UI_TEXT_LANGUAGE_SE); +TRANS(UI_TEXT_MAINPAGE6_1_SE); +TRANS(UI_TEXT_MAINPAGE6_2_SE); +TRANS(UI_TEXT_MAINPAGE6_3_SE); +TRANS(UI_TEXT_MAINPAGE6_4_SE); +TRANS(UI_TEXT_MAINPAGE6_5_SE); +TRANS(UI_TEXT_MAINPAGE6_6_SE); +TRANS(UI_TEXT_MAINPAGE_TEMP_BED_SE); +TRANS(UI_TEXT_MAINPAGE_BED_SE); +TRANS(UI_TEXT_MAINPAGE_Z_BUF_SE); +TRANS(UI_TEXT_MAINPAGE_MUL_EUSAGE_SE); +TRANS(UI_TEXT_MAINPAGE_XY_SE); +TRANS(UI_TEXT_PRINT_TIME_VALUE_SE); +TRANS(UI_TEXT_PRINT_FILAMENT_VALUE_SE); +TRANS(UI_TEXT_METER_PRINTED_SE); +TRANS(UI_TEXT_STATUS_SE); +TRANS(UI_TEXT_EMPTY_SE); +TRANS(UI_TEXT_TEMP_SET_SE); +TRANS(UI_TEXT_CURRENT_TEMP_SE); +TRANS(UI_TEXT_COATING_THICKNESS_SE); +TRANS(UI_TEXT_EXTR3_TEMP_SE); +TRANS(UI_TEXT_EXTR4_TEMP_SE); +TRANS(UI_TEXT_EXTR5_TEMP_SE); +TRANS(UI_TEXT_EXTR3_OFF_SE); +TRANS(UI_TEXT_EXTR4_OFF_SE); +TRANS(UI_TEXT_EXTR5_OFF_SE); +TRANS(UI_TEXT_EXTR3_SELECT_SE); +TRANS(UI_TEXT_EXTR4_SELECT_SE); +TRANS(UI_TEXT_EXTR5_SELECT_SE); +TRANS(UI_TEXT_DITTO_0_SE); +TRANS(UI_TEXT_DITTO_1_SE); +TRANS(UI_TEXT_DITTO_2_SE); +TRANS(UI_TEXT_DITTO_3_SE); +TRANS(UI_TEXT_ZPROBE_HEIGHT_SE); +TRANS(UI_TEXT_OFFSETS_SE); +TRANS(UI_TEXT_X_OFFSET_SE); +TRANS(UI_TEXT_Y_OFFSET_SE); +TRANS(UI_TEXT_Z_OFFSET_SE); + +PGM_P const translations_se[NUM_TRANSLATED_WORDS] PROGMEM = { + FUI_TEXT_ON_SE, + FUI_TEXT_OFF_SE, + FUI_TEXT_NA_SE, + FUI_TEXT_YES_SE, + FUI_TEXT_NO_SE, + FUI_TEXT_PRINT_POS_SE, + FUI_TEXT_PRINTING_SE, + FUI_TEXT_IDLE_SE, + FUI_TEXT_NOSDCARD_SE, + FUI_TEXT_ERROR_SE, + FUI_TEXT_BACK_SE, + FUI_TEXT_QUICK_SETTINGS_SE, + FUI_TEXT_ERRORMSG_SE, + FUI_TEXT_CONFIGURATION_SE, + FUI_TEXT_POSITION_SE, + FUI_TEXT_EXTRUDER_SE, + FUI_TEXT_SD_CARD_SE, + FUI_TEXT_DEBUGGING_SE, + FUI_TEXT_HOME_DELTA_SE, + FUI_TEXT_HOME_ALL_SE, + FUI_TEXT_HOME_X_SE, + FUI_TEXT_HOME_Y_SE, + FUI_TEXT_HOME_Z_SE, + FUI_TEXT_PREHEAT_PLA_SE, + FUI_TEXT_PREHEAT_ABS_SE, + FUI_TEXT_LIGHTS_ONOFF_SE, + FUI_TEXT_COOLDOWN_SE, + FUI_TEXT_SET_TO_ORIGIN_SE, + FUI_TEXT_DISABLE_STEPPER_SE, + FUI_TEXT_X_POSITION_SE, + FUI_TEXT_X_POS_FAST_SE, + FUI_TEXT_Y_POSITION_SE, + FUI_TEXT_Y_POS_FAST_SE, + FUI_TEXT_Z_POSITION_SE, + FUI_TEXT_Z_POS_FAST_SE, + FUI_TEXT_E_POSITION_SE, + FUI_TEXT_BED_TEMP_SE, + FUI_TEXT_EXTR0_TEMP_SE, + FUI_TEXT_EXTR1_TEMP_SE, + FUI_TEXT_EXTR2_TEMP_SE, + FUI_TEXT_EXTR0_OFF_SE, + FUI_TEXT_EXTR1_OFF_SE, + FUI_TEXT_EXTR2_OFF_SE, + FUI_TEXT_EXTR0_SELECT_SE, + FUI_TEXT_EXTR1_SELECT_SE, + FUI_TEXT_EXTR2_SELECT_SE, + FUI_TEXT_EXTR_ORIGIN_SE, + FUI_TEXT_PRINT_X_SE, + FUI_TEXT_PRINT_Y_SE, + FUI_TEXT_PRINT_Z_SE, + FUI_TEXT_PRINT_Z_DELTA_SE, + FUI_TEXT_MOVE_X_SE, + FUI_TEXT_MOVE_Y_SE, + FUI_TEXT_MOVE_Z_SE, + FUI_TEXT_MOVE_Z_DELTA_SE, + FUI_TEXT_JERK_SE, + FUI_TEXT_ZJERK_SE, + FUI_TEXT_ACCELERATION_SE, + FUI_TEXT_STORE_TO_EEPROM_SE, + FUI_TEXT_LOAD_EEPROM_SE, + FUI_TEXT_DBG_ECHO_SE, + FUI_TEXT_DBG_INFO_SE, + FUI_TEXT_DBG_ERROR_SE, + FUI_TEXT_DBG_DRYRUN_SE, + FUI_TEXT_OPS_OFF_SE, + FUI_TEXT_OPS_CLASSIC_SE, + FUI_TEXT_OPS_FAST_SE, + FUI_TEXT_OPS_RETRACT_SE, + FUI_TEXT_OPS_BACKSLASH_SE, + FUI_TEXT_OPS_MINDIST_SE, + FUI_TEXT_OPS_MOVE_AFTER_SE, + FUI_TEXT_ANTI_OOZE_SE, + FUI_TEXT_PRINT_FILE_SE, + FUI_TEXT_PAUSE_PRINT_SE, + FUI_TEXT_CONTINUE_PRINT_SE, + FUI_TEXT_UNMOUNT_CARD_SE, + FUI_TEXT_MOUNT_CARD_SE, + FUI_TEXT_DELETE_FILE_SE, + FUI_TEXT_FEEDRATE_SE, + FUI_TEXT_FEED_MAX_X_SE, + FUI_TEXT_FEED_MAX_Y_SE, + FUI_TEXT_FEED_MAX_Z_SE, + FUI_TEXT_FEED_MAX_Z_DELTA_SE, + FUI_TEXT_FEED_HOME_X_SE, + FUI_TEXT_FEED_HOME_Y_SE, + FUI_TEXT_FEED_HOME_Z_SE, + FUI_TEXT_FEED_HOME_Z_DELTA_SE, + FUI_TEXT_ACTION_XPOSITION4A_SE, + FUI_TEXT_ACTION_XPOSITION4B_SE, + FUI_TEXT_ACTION_XPOSITION4C_SE, + FUI_TEXT_ACTION_XPOSITION4D_SE, + FUI_TEXT_ACTION_YPOSITION4A_SE, + FUI_TEXT_ACTION_YPOSITION4B_SE, + FUI_TEXT_ACTION_YPOSITION4C_SE, + FUI_TEXT_ACTION_YPOSITION4D_SE, + FUI_TEXT_ACTION_ZPOSITION4A_SE, + FUI_TEXT_ACTION_ZPOSITION4B_SE, + FUI_TEXT_ACTION_ZPOSITION4C_SE, + FUI_TEXT_ACTION_ZPOSITION4D_SE, + FUI_TEXT_ACTION_XPOSITION_FAST4A_SE, + FUI_TEXT_ACTION_XPOSITION_FAST4B_SE, + FUI_TEXT_ACTION_XPOSITION_FAST4C_SE, + FUI_TEXT_ACTION_XPOSITION_FAST4D_SE, + FUI_TEXT_ACTION_YPOSITION_FAST4A_SE, + FUI_TEXT_ACTION_YPOSITION_FAST4B_SE, + FUI_TEXT_ACTION_YPOSITION_FAST4C_SE, + FUI_TEXT_ACTION_YPOSITION_FAST4D_SE, + FUI_TEXT_ACTION_ZPOSITION_FAST4A_SE, + FUI_TEXT_ACTION_ZPOSITION_FAST4B_SE, + FUI_TEXT_ACTION_ZPOSITION_FAST4C_SE, + FUI_TEXT_ACTION_ZPOSITION_FAST4D_SE, + FUI_TEXT_ACTION_EPOSITION_FAST2A_SE, + FUI_TEXT_ACTION_EPOSITION_FAST2B_SE, + FUI_TEXT_ACTION_XPOSITION2A_SE, + FUI_TEXT_ACTION_XPOSITION2B_SE, + FUI_TEXT_ACTION_YPOSITION2A_SE, + FUI_TEXT_ACTION_YPOSITION2B_SE, + FUI_TEXT_ACTION_ZPOSITION2A_SE, + FUI_TEXT_ACTION_ZPOSITION2B_SE, + FUI_TEXT_ACTION_XPOSITION_FAST2A_SE, + FUI_TEXT_ACTION_XPOSITION_FAST2B_SE, + FUI_TEXT_ACTION_YPOSITION_FAST2A_SE, + FUI_TEXT_ACTION_YPOSITION_FAST2B_SE, + FUI_TEXT_ACTION_ZPOSITION_FAST2A_SE, + FUI_TEXT_ACTION_ZPOSITION_FAST2B_SE, + FUI_TEXT_FANSPEED_SE, + FUI_TEXT_ACTION_FANSPEED_SE, + FUI_TEXT_FAN_OFF_SE, + FUI_TEXT_FAN_25_SE, + FUI_TEXT_FAN_50_SE, + FUI_TEXT_FAN_75_SE, + FUI_TEXT_FAN_FULL_SE, + FUI_TEXT_STEPPER_INACTIVE_SE, + FUI_TEXT_STEPPER_INACTIVE2A_SE, + FUI_TEXT_STEPPER_INACTIVE2B_SE, + FUI_TEXT_POWER_INACTIVE_SE, + FUI_TEXT_POWER_INACTIVE2A_SE, + FUI_TEXT_POWER_INACTIVE2B_SE, + FUI_TEXT_GENERAL_SE, + FUI_TEXT_BAUDRATE_SE, + FUI_TEXT_EXTR_STEPS_SE, + FUI_TEXT_EXTR_START_FEED_SE, + FUI_TEXT_EXTR_MAX_FEED_SE, + FUI_TEXT_EXTR_ACCEL_SE, + FUI_TEXT_EXTR_WATCH_SE, + FUI_TEXT_EXTR_ADVANCE_L_SE, + FUI_TEXT_EXTR_ADVANCE_K_SE, + FUI_TEXT_EXTR_MANAGER_SE, + FUI_TEXT_EXTR_PGAIN_SE, + FUI_TEXT_EXTR_DEADTIME_SE, + FUI_TEXT_EXTR_DMAX_DT_SE, + FUI_TEXT_EXTR_IGAIN_SE, + FUI_TEXT_EXTR_DGAIN_SE, + FUI_TEXT_EXTR_DMIN_SE, + FUI_TEXT_EXTR_DMAX_SE, + FUI_TEXT_EXTR_PMAX_SE, + FUI_TEXT_EXTR_XOFF_SE, + FUI_TEXT_EXTR_YOFF_SE, + FUI_TEXT_STRING_HM_BANGBANG_SE, + FUI_TEXT_STRING_HM_PID_SE, + FUI_TEXT_STRING_ACTION_SE, + FUI_TEXT_HEATING_EXTRUDER_SE, + FUI_TEXT_HEATING_BED_SE, + FUI_TEXT_KILLED_SE, + FUI_TEXT_STEPPER_DISABLED_SE, + FUI_TEXT_EEPROM_STOREDA_SE, + FUI_TEXT_EEPROM_STOREDB_SE, + FUI_TEXT_EEPROM_LOADEDA_SE, + FUI_TEXT_EEPROM_LOADEDB_SE, + FUI_TEXT_UPLOADING_SE, + FUI_TEXT_PAGE_BUFFER_SE, + FUI_TEXT_PAGE_EXTRUDER_SE, + FUI_TEXT_PAGE_EXTRUDER1_SE, + FUI_TEXT_PAGE_EXTRUDER2_SE, + FUI_TEXT_PAGE_EXTRUDER3_SE, + FUI_TEXT_PAGE_BED_SE, + FUI_TEXT_SPEED_MULTIPLY_SE, + FUI_TEXT_FLOW_MULTIPLY_SE, + FUI_TEXT_SHOW_MEASUREMENT_SE, + FUI_TEXT_RESET_MEASUREMENT_SE, + FUI_TEXT_SET_MEASURED_ORIGIN_SE, + FUI_TEXT_ZCALIB_SE, + FUI_TEXT_SET_P1_SE, + FUI_TEXT_SET_P2_SE, + FUI_TEXT_SET_P3_SE, + FUI_TEXT_CALCULATE_LEVELING_SE, + FUI_TEXT_LEVEL_SE, + FUI_TEXT_EXTR_WAIT_RETRACT_TEMP_SE, + FUI_TEXT_EXTR_WAIT_RETRACT_UNITS_SE, + FUI_TEXT_SD_REMOVED_SE, + FUI_TEXT_SD_INSERTED_SE, + FUI_TEXT_PRINTER_READY_SE, + FUI_TEXT_PRINTTIME_DAYS_SE, + FUI_TEXT_PRINTTIME_HOURS_SE, + FUI_TEXT_PRINTTIME_MINUTES_SE, + FUI_TEXT_PRINT_TIME_SE, + FUI_TEXT_PRINT_FILAMENT_SE, + FUI_TEXT_PRINTED_SE, + FUI_TEXT_POWER_SE, + FUI_TEXT_STRING_HM_DEADTIME_SE, + FUI_TEXT_STRING_HM_SLOWBANG_SE, + FUI_TEXT_STOP_PRINT_SE, + FUI_TEXT_Z_BABYSTEPPING_SE, + FUI_TEXT_CHANGE_FILAMENT_SE, + FUI_TEXT_WIZ_CH_FILAMENT1_SE, + FUI_TEXT_WIZ_CH_FILAMENT2_SE, + FUI_TEXT_WIZ_CH_FILAMENT3_SE, + FUI_TEXT_CLICK_DONE_SE, + FUI_TEXT_AUTOLEVEL_ONOFF_SE, + FUI_TEXT_SERVOPOS_SE, + FUI_TEXT_IGNORE_M106_SE, + FUI_TEXT_WIZ_REHEAT1_SE, + FUI_TEXT_WIZ_REHEAT2_SE, + FUI_TEXT_WIZ_WAITTEMP1_SE, + FUI_TEXT_WIZ_WAITTEMP2_SE, + FUI_TEXT_EXTRUDER_JAM_SE, + FUI_TEXT_STANDBY_SE, + FUI_TEXT_BED_COATING_SE, + FUI_TEXT_BED_COATING_SET1_SE, + FUI_TEXT_BED_COATING_SET2_SE, + FUI_TEXT_NOCOATING_SE, + FUI_TEXT_BUILDTAK_SE, + FUI_TEXT_KAPTON_SE, + FUI_TEXT_BLUETAPE_SE, + FUI_TEXT_PETTAPE_SE, + FUI_TEXT_GLUESTICK_SE, + FUI_TEXT_CUSTOM_SE, + FUI_TEXT_COATING_CUSTOM_SE, + FUI_TEXT_LANGUAGE_SE, + FUI_TEXT_MAINPAGE6_1_SE, + FUI_TEXT_MAINPAGE6_2_SE, + FUI_TEXT_MAINPAGE6_3_SE, + FUI_TEXT_MAINPAGE6_4_SE, + FUI_TEXT_MAINPAGE6_5_SE, + FUI_TEXT_MAINPAGE6_6_SE, + FUI_TEXT_MAINPAGE_TEMP_BED_SE, + FUI_TEXT_MAINPAGE_BED_SE, + FUI_TEXT_MAINPAGE_Z_BUF_SE, + FUI_TEXT_MAINPAGE_MUL_EUSAGE_SE, + FUI_TEXT_MAINPAGE_XY_SE, + FUI_TEXT_PRINT_TIME_VALUE_SE, + FUI_TEXT_PRINT_FILAMENT_VALUE_SE, + FUI_TEXT_METER_PRINTED_SE, + FUI_TEXT_STATUS_SE, + FUI_TEXT_EMPTY_SE, + FUI_TEXT_TEMP_SET_SE, + FUI_TEXT_CURRENT_TEMP_SE, + FUI_TEXT_COATING_THICKNESS_SE, + FUI_TEXT_EXTR3_TEMP_SE, + FUI_TEXT_EXTR4_TEMP_SE, + FUI_TEXT_EXTR5_TEMP_SE, + FUI_TEXT_EXTR3_OFF_SE, + FUI_TEXT_EXTR4_OFF_SE, + FUI_TEXT_EXTR5_OFF_SE, + FUI_TEXT_EXTR3_SELECT_SE, + FUI_TEXT_EXTR4_SELECT_SE, + FUI_TEXT_EXTR5_SELECT_SE, + FUI_TEXT_DITTO_0_SE, + FUI_TEXT_DITTO_1_SE, + FUI_TEXT_DITTO_2_SE, + FUI_TEXT_DITTO_3_SE, + FUI_TEXT_ZPROBE_HEIGHT_SE, + FUI_TEXT_OFFSETS_SE, + FUI_TEXT_X_OFFSET_SE, + FUI_TEXT_Y_OFFSET_SE, + FUI_TEXT_Z_OFFSET_SE, + FUI_TEXT_DBG_ENDSTOP_SE +}; +#define LANG_SE_TABLE translations_se +#else +#define LANG_SE_TABLE NULL +#endif // LANGUAGE_SE_ACTIVE + + +#if LANGUAGE_FR_ACTIVE +TRANS(UI_TEXT_ON_FR); +TRANS(UI_TEXT_OFF_FR); +TRANS(UI_TEXT_NA_FR); +TRANS(UI_TEXT_YES_FR); +TRANS(UI_TEXT_NO_FR); +TRANS(UI_TEXT_PRINT_POS_FR); +TRANS(UI_TEXT_PRINTING_FR); +TRANS(UI_TEXT_IDLE_FR); +TRANS(UI_TEXT_NOSDCARD_FR); +TRANS(UI_TEXT_ERROR_FR); +TRANS(UI_TEXT_BACK_FR); +TRANS(UI_TEXT_QUICK_SETTINGS_FR); +TRANS(UI_TEXT_ERRORMSG_FR); +TRANS(UI_TEXT_CONFIGURATION_FR); +TRANS(UI_TEXT_POSITION_FR); +TRANS(UI_TEXT_EXTRUDER_FR); +TRANS(UI_TEXT_SD_CARD_FR); +TRANS(UI_TEXT_DEBUGGING_FR); +TRANS(UI_TEXT_HOME_DELTA_FR); +TRANS(UI_TEXT_HOME_ALL_FR); +TRANS(UI_TEXT_HOME_X_FR); +TRANS(UI_TEXT_HOME_Y_FR); +TRANS(UI_TEXT_HOME_Z_FR); +TRANS(UI_TEXT_PREHEAT_PLA_FR); +TRANS(UI_TEXT_PREHEAT_ABS_FR); +TRANS(UI_TEXT_LIGHTS_ONOFF_FR); +TRANS(UI_TEXT_COOLDOWN_FR); +TRANS(UI_TEXT_SET_TO_ORIGIN_FR); +TRANS(UI_TEXT_DISABLE_STEPPER_FR); +TRANS(UI_TEXT_X_POSITION_FR); +TRANS(UI_TEXT_X_POS_FAST_FR); +TRANS(UI_TEXT_Y_POSITION_FR); +TRANS(UI_TEXT_Y_POS_FAST_FR); +TRANS(UI_TEXT_Z_POSITION_FR); +TRANS(UI_TEXT_Z_POS_FAST_FR); +TRANS(UI_TEXT_E_POSITION_FR); +TRANS(UI_TEXT_BED_TEMP_FR); +TRANS(UI_TEXT_EXTR0_TEMP_FR); +TRANS(UI_TEXT_EXTR1_TEMP_FR); +TRANS(UI_TEXT_EXTR2_TEMP_FR); +TRANS(UI_TEXT_EXTR0_OFF_FR); +TRANS(UI_TEXT_EXTR1_OFF_FR); +TRANS(UI_TEXT_EXTR2_OFF_FR); +TRANS(UI_TEXT_EXTR0_SELECT_FR); +TRANS(UI_TEXT_EXTR1_SELECT_FR); +TRANS(UI_TEXT_EXTR2_SELECT_FR); +TRANS(UI_TEXT_EXTR_ORIGIN_FR); +TRANS(UI_TEXT_PRINT_X_FR); +TRANS(UI_TEXT_PRINT_Y_FR); +TRANS(UI_TEXT_PRINT_Z_FR); +TRANS(UI_TEXT_PRINT_Z_DELTA_FR); +TRANS(UI_TEXT_MOVE_X_FR); +TRANS(UI_TEXT_MOVE_Y_FR); +TRANS(UI_TEXT_MOVE_Z_FR); +TRANS(UI_TEXT_MOVE_Z_DELTA_FR); +TRANS(UI_TEXT_JERK_FR); +TRANS(UI_TEXT_ZJERK_FR); +TRANS(UI_TEXT_ACCELERATION_FR); +TRANS(UI_TEXT_STORE_TO_EEPROM_FR); +TRANS(UI_TEXT_LOAD_EEPROM_FR); +TRANS(UI_TEXT_DBG_ECHO_FR); +TRANS(UI_TEXT_DBG_INFO_FR); +TRANS(UI_TEXT_DBG_ERROR_FR); +TRANS(UI_TEXT_DBG_DRYRUN_FR); +TRANS(UI_TEXT_DBG_ENDSTOP_FR); +TRANS(UI_TEXT_OPS_OFF_FR); +TRANS(UI_TEXT_OPS_CLASSIC_FR); +TRANS(UI_TEXT_OPS_FAST_FR); +TRANS(UI_TEXT_OPS_RETRACT_FR); +TRANS(UI_TEXT_OPS_BACKSLASH_FR); +TRANS(UI_TEXT_OPS_MINDIST_FR); +TRANS(UI_TEXT_OPS_MOVE_AFTER_FR); +TRANS(UI_TEXT_ANTI_OOZE_FR); +TRANS(UI_TEXT_PRINT_FILE_FR); +TRANS(UI_TEXT_PAUSE_PRINT_FR); +TRANS(UI_TEXT_CONTINUE_PRINT_FR); +TRANS(UI_TEXT_UNMOUNT_CARD_FR); +TRANS(UI_TEXT_MOUNT_CARD_FR); +TRANS(UI_TEXT_DELETE_FILE_FR); +TRANS(UI_TEXT_FEEDRATE_FR); +TRANS(UI_TEXT_FEED_MAX_X_FR); +TRANS(UI_TEXT_FEED_MAX_Y_FR); +TRANS(UI_TEXT_FEED_MAX_Z_FR); +TRANS(UI_TEXT_FEED_MAX_Z_DELTA_FR); +TRANS(UI_TEXT_FEED_HOME_X_FR); +TRANS(UI_TEXT_FEED_HOME_Y_FR); +TRANS(UI_TEXT_FEED_HOME_Z_FR); +TRANS(UI_TEXT_FEED_HOME_Z_DELTA_FR); +TRANS(UI_TEXT_ACTION_XPOSITION4A_FR); +TRANS(UI_TEXT_ACTION_XPOSITION4B_FR); +TRANS(UI_TEXT_ACTION_XPOSITION4C_FR); +TRANS(UI_TEXT_ACTION_XPOSITION4D_FR); +TRANS(UI_TEXT_ACTION_YPOSITION4A_FR); +TRANS(UI_TEXT_ACTION_YPOSITION4B_FR); +TRANS(UI_TEXT_ACTION_YPOSITION4C_FR); +TRANS(UI_TEXT_ACTION_YPOSITION4D_FR); +TRANS(UI_TEXT_ACTION_ZPOSITION4A_FR); +TRANS(UI_TEXT_ACTION_ZPOSITION4B_FR); +TRANS(UI_TEXT_ACTION_ZPOSITION4C_FR); +TRANS(UI_TEXT_ACTION_ZPOSITION4D_FR); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST4A_FR); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST4B_FR); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST4C_FR); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST4D_FR); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST4A_FR); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST4B_FR); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST4C_FR); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST4D_FR); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST4A_FR); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST4B_FR); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST4C_FR); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST4D_FR); +TRANS(UI_TEXT_ACTION_EPOSITION_FAST2A_FR); +TRANS(UI_TEXT_ACTION_EPOSITION_FAST2B_FR); +TRANS(UI_TEXT_ACTION_XPOSITION2A_FR); +TRANS(UI_TEXT_ACTION_XPOSITION2B_FR); +TRANS(UI_TEXT_ACTION_YPOSITION2A_FR); +TRANS(UI_TEXT_ACTION_YPOSITION2B_FR); +TRANS(UI_TEXT_ACTION_ZPOSITION2A_FR); +TRANS(UI_TEXT_ACTION_ZPOSITION2B_FR); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST2A_FR); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST2B_FR); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST2A_FR); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST2B_FR); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST2A_FR); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST2B_FR); +TRANS(UI_TEXT_FANSPEED_FR); +TRANS(UI_TEXT_ACTION_FANSPEED_FR); +TRANS(UI_TEXT_FAN_OFF_FR); +TRANS(UI_TEXT_FAN_25_FR); +TRANS(UI_TEXT_FAN_50_FR); +TRANS(UI_TEXT_FAN_75_FR); +TRANS(UI_TEXT_FAN_FULL_FR); +TRANS(UI_TEXT_STEPPER_INACTIVE_FR); +TRANS(UI_TEXT_STEPPER_INACTIVE2A_FR); +TRANS(UI_TEXT_STEPPER_INACTIVE2B_FR); +TRANS(UI_TEXT_POWER_INACTIVE_FR); +TRANS(UI_TEXT_POWER_INACTIVE2A_FR); +TRANS(UI_TEXT_POWER_INACTIVE2B_FR); +TRANS(UI_TEXT_GENERAL_FR); +TRANS(UI_TEXT_BAUDRATE_FR); +TRANS(UI_TEXT_EXTR_STEPS_FR); +TRANS(UI_TEXT_EXTR_START_FEED_FR); +TRANS(UI_TEXT_EXTR_MAX_FEED_FR); +TRANS(UI_TEXT_EXTR_ACCEL_FR); +TRANS(UI_TEXT_EXTR_WATCH_FR); +TRANS(UI_TEXT_EXTR_ADVANCE_L_FR); +TRANS(UI_TEXT_EXTR_ADVANCE_K_FR); +TRANS(UI_TEXT_EXTR_MANAGER_FR); +TRANS(UI_TEXT_EXTR_PGAIN_FR); +TRANS(UI_TEXT_EXTR_DEADTIME_FR); +TRANS(UI_TEXT_EXTR_DMAX_DT_FR); +TRANS(UI_TEXT_EXTR_IGAIN_FR); +TRANS(UI_TEXT_EXTR_DGAIN_FR); +TRANS(UI_TEXT_EXTR_DMIN_FR); +TRANS(UI_TEXT_EXTR_DMAX_FR); +TRANS(UI_TEXT_EXTR_PMAX_FR); +TRANS(UI_TEXT_EXTR_XOFF_FR); +TRANS(UI_TEXT_EXTR_YOFF_FR); +TRANS(UI_TEXT_STRING_HM_BANGBANG_FR); +TRANS(UI_TEXT_STRING_HM_PID_FR); +TRANS(UI_TEXT_STRING_ACTION_FR); +TRANS(UI_TEXT_HEATING_EXTRUDER_FR); +TRANS(UI_TEXT_HEATING_BED_FR); +TRANS(UI_TEXT_KILLED_FR); +TRANS(UI_TEXT_STEPPER_DISABLED_FR); +TRANS(UI_TEXT_EEPROM_STOREDA_FR); +TRANS(UI_TEXT_EEPROM_STOREDB_FR); +TRANS(UI_TEXT_EEPROM_LOADEDA_FR); +TRANS(UI_TEXT_EEPROM_LOADEDB_FR); +TRANS(UI_TEXT_UPLOADING_FR); +TRANS(UI_TEXT_PAGE_BUFFER_FR); +TRANS(UI_TEXT_PAGE_EXTRUDER_FR); +TRANS(UI_TEXT_PAGE_EXTRUDER1_FR); +TRANS(UI_TEXT_PAGE_EXTRUDER2_FR); +TRANS(UI_TEXT_PAGE_EXTRUDER3_FR); +TRANS(UI_TEXT_PAGE_BED_FR); +TRANS(UI_TEXT_SPEED_MULTIPLY_FR); +TRANS(UI_TEXT_FLOW_MULTIPLY_FR); +TRANS(UI_TEXT_SHOW_MEASUREMENT_FR); +TRANS(UI_TEXT_RESET_MEASUREMENT_FR); +TRANS(UI_TEXT_SET_MEASURED_ORIGIN_FR); +TRANS(UI_TEXT_ZCALIB_FR); +TRANS(UI_TEXT_SET_P1_FR); +TRANS(UI_TEXT_SET_P2_FR); +TRANS(UI_TEXT_SET_P3_FR); +TRANS(UI_TEXT_CALCULATE_LEVELING_FR); +TRANS(UI_TEXT_LEVEL_FR); +TRANS(UI_TEXT_EXTR_WAIT_RETRACT_TEMP_FR); +TRANS(UI_TEXT_EXTR_WAIT_RETRACT_UNITS_FR); +TRANS(UI_TEXT_SD_REMOVED_FR); +TRANS(UI_TEXT_SD_INSERTED_FR); +TRANS(UI_TEXT_PRINTER_READY_FR); +TRANS(UI_TEXT_PRINTTIME_DAYS_FR); +TRANS(UI_TEXT_PRINTTIME_HOURS_FR); +TRANS(UI_TEXT_PRINTTIME_MINUTES_FR); +TRANS(UI_TEXT_PRINT_TIME_FR); +TRANS(UI_TEXT_PRINT_FILAMENT_FR); +TRANS(UI_TEXT_PRINTED_FR); +TRANS(UI_TEXT_POWER_FR); +TRANS(UI_TEXT_STRING_HM_DEADTIME_FR); +TRANS(UI_TEXT_STRING_HM_SLOWBANG_FR); +TRANS(UI_TEXT_STOP_PRINT_FR); +TRANS(UI_TEXT_Z_BABYSTEPPING_FR); +TRANS(UI_TEXT_CHANGE_FILAMENT_FR); +TRANS(UI_TEXT_WIZ_CH_FILAMENT1_FR); +TRANS(UI_TEXT_WIZ_CH_FILAMENT2_FR); +TRANS(UI_TEXT_WIZ_CH_FILAMENT3_FR); +TRANS(UI_TEXT_CLICK_DONE_FR); +TRANS(UI_TEXT_AUTOLEVEL_ONOFF_FR); +TRANS(UI_TEXT_SERVOPOS_FR); +TRANS(UI_TEXT_IGNORE_M106_FR); +TRANS(UI_TEXT_WIZ_REHEAT1_FR); +TRANS(UI_TEXT_WIZ_REHEAT2_FR); +TRANS(UI_TEXT_WIZ_WAITTEMP1_FR); +TRANS(UI_TEXT_WIZ_WAITTEMP2_FR); +TRANS(UI_TEXT_EXTRUDER_JAM_FR); +TRANS(UI_TEXT_STANDBY_FR); +TRANS(UI_TEXT_BED_COATING_FR); +TRANS(UI_TEXT_BED_COATING_SET1_FR); +TRANS(UI_TEXT_BED_COATING_SET2_FR); +TRANS(UI_TEXT_NOCOATING_FR); +TRANS(UI_TEXT_BUILDTAK_FR); +TRANS(UI_TEXT_KAPTON_FR); +TRANS(UI_TEXT_BLUETAPE_FR); +TRANS(UI_TEXT_PETTAPE_FR); +TRANS(UI_TEXT_GLUESTICK_FR); +TRANS(UI_TEXT_CUSTOM_FR); +TRANS(UI_TEXT_COATING_CUSTOM_FR); +TRANS(UI_TEXT_LANGUAGE_FR); +TRANS(UI_TEXT_MAINPAGE6_1_FR); +TRANS(UI_TEXT_MAINPAGE6_2_FR); +TRANS(UI_TEXT_MAINPAGE6_3_FR); +TRANS(UI_TEXT_MAINPAGE6_4_FR); +TRANS(UI_TEXT_MAINPAGE6_5_FR); +TRANS(UI_TEXT_MAINPAGE6_6_FR); +TRANS(UI_TEXT_MAINPAGE_TEMP_BED_FR); +TRANS(UI_TEXT_MAINPAGE_BED_FR); +TRANS(UI_TEXT_MAINPAGE_Z_BUF_FR); +TRANS(UI_TEXT_MAINPAGE_MUL_EUSAGE_FR); +TRANS(UI_TEXT_MAINPAGE_XY_FR); +TRANS(UI_TEXT_PRINT_TIME_VALUE_FR); +TRANS(UI_TEXT_PRINT_FILAMENT_VALUE_FR); +TRANS(UI_TEXT_METER_PRINTED_FR); +TRANS(UI_TEXT_STATUS_FR); +TRANS(UI_TEXT_EMPTY_FR); +TRANS(UI_TEXT_TEMP_SET_FR); +TRANS(UI_TEXT_CURRENT_TEMP_FR); +TRANS(UI_TEXT_COATING_THICKNESS_FR); +TRANS(UI_TEXT_EXTR3_TEMP_FR); +TRANS(UI_TEXT_EXTR4_TEMP_FR); +TRANS(UI_TEXT_EXTR5_TEMP_FR); +TRANS(UI_TEXT_EXTR3_OFF_FR); +TRANS(UI_TEXT_EXTR4_OFF_FR); +TRANS(UI_TEXT_EXTR5_OFF_FR); +TRANS(UI_TEXT_EXTR3_SELECT_FR); +TRANS(UI_TEXT_EXTR4_SELECT_FR); +TRANS(UI_TEXT_EXTR5_SELECT_FR); +TRANS(UI_TEXT_DITTO_0_FR); +TRANS(UI_TEXT_DITTO_1_FR); +TRANS(UI_TEXT_DITTO_2_FR); +TRANS(UI_TEXT_DITTO_3_FR); +TRANS(UI_TEXT_ZPROBE_HEIGHT_FR); +TRANS(UI_TEXT_OFFSETS_FR); +TRANS(UI_TEXT_X_OFFSET_FR); +TRANS(UI_TEXT_Y_OFFSET_FR); +TRANS(UI_TEXT_Z_OFFSET_FR); + +PGM_P const translations_fr[NUM_TRANSLATED_WORDS] PROGMEM = { + FUI_TEXT_ON_FR, + FUI_TEXT_OFF_FR, + FUI_TEXT_NA_FR, + FUI_TEXT_YES_FR, + FUI_TEXT_NO_FR, + FUI_TEXT_PRINT_POS_FR, + FUI_TEXT_PRINTING_FR, + FUI_TEXT_IDLE_FR, + FUI_TEXT_NOSDCARD_FR, + FUI_TEXT_ERROR_FR, + FUI_TEXT_BACK_FR, + FUI_TEXT_QUICK_SETTINGS_FR, + FUI_TEXT_ERRORMSG_FR, + FUI_TEXT_CONFIGURATION_FR, + FUI_TEXT_POSITION_FR, + FUI_TEXT_EXTRUDER_FR, + FUI_TEXT_SD_CARD_FR, + FUI_TEXT_DEBUGGING_FR, + FUI_TEXT_HOME_DELTA_FR, + FUI_TEXT_HOME_ALL_FR, + FUI_TEXT_HOME_X_FR, + FUI_TEXT_HOME_Y_FR, + FUI_TEXT_HOME_Z_FR, + FUI_TEXT_PREHEAT_PLA_FR, + FUI_TEXT_PREHEAT_ABS_FR, + FUI_TEXT_LIGHTS_ONOFF_FR, + FUI_TEXT_COOLDOWN_FR, + FUI_TEXT_SET_TO_ORIGIN_FR, + FUI_TEXT_DISABLE_STEPPER_FR, + FUI_TEXT_X_POSITION_FR, + FUI_TEXT_X_POS_FAST_FR, + FUI_TEXT_Y_POSITION_FR, + FUI_TEXT_Y_POS_FAST_FR, + FUI_TEXT_Z_POSITION_FR, + FUI_TEXT_Z_POS_FAST_FR, + FUI_TEXT_E_POSITION_FR, + FUI_TEXT_BED_TEMP_FR, + FUI_TEXT_EXTR0_TEMP_FR, + FUI_TEXT_EXTR1_TEMP_FR, + FUI_TEXT_EXTR2_TEMP_FR, + FUI_TEXT_EXTR0_OFF_FR, + FUI_TEXT_EXTR1_OFF_FR, + FUI_TEXT_EXTR2_OFF_FR, + FUI_TEXT_EXTR0_SELECT_FR, + FUI_TEXT_EXTR1_SELECT_FR, + FUI_TEXT_EXTR2_SELECT_FR, + FUI_TEXT_EXTR_ORIGIN_FR, + FUI_TEXT_PRINT_X_FR, + FUI_TEXT_PRINT_Y_FR, + FUI_TEXT_PRINT_Z_FR, + FUI_TEXT_PRINT_Z_DELTA_FR, + FUI_TEXT_MOVE_X_FR, + FUI_TEXT_MOVE_Y_FR, + FUI_TEXT_MOVE_Z_FR, + FUI_TEXT_MOVE_Z_DELTA_FR, + FUI_TEXT_JERK_FR, + FUI_TEXT_ZJERK_FR, + FUI_TEXT_ACCELERATION_FR, + FUI_TEXT_STORE_TO_EEPROM_FR, + FUI_TEXT_LOAD_EEPROM_FR, + FUI_TEXT_DBG_ECHO_FR, + FUI_TEXT_DBG_INFO_FR, + FUI_TEXT_DBG_ERROR_FR, + FUI_TEXT_DBG_DRYRUN_FR, + FUI_TEXT_OPS_OFF_FR, + FUI_TEXT_OPS_CLASSIC_FR, + FUI_TEXT_OPS_FAST_FR, + FUI_TEXT_OPS_RETRACT_FR, + FUI_TEXT_OPS_BACKSLASH_FR, + FUI_TEXT_OPS_MINDIST_FR, + FUI_TEXT_OPS_MOVE_AFTER_FR, + FUI_TEXT_ANTI_OOZE_FR, + FUI_TEXT_PRINT_FILE_FR, + FUI_TEXT_PAUSE_PRINT_FR, + FUI_TEXT_CONTINUE_PRINT_FR, + FUI_TEXT_UNMOUNT_CARD_FR, + FUI_TEXT_MOUNT_CARD_FR, + FUI_TEXT_DELETE_FILE_FR, + FUI_TEXT_FEEDRATE_FR, + FUI_TEXT_FEED_MAX_X_FR, + FUI_TEXT_FEED_MAX_Y_FR, + FUI_TEXT_FEED_MAX_Z_FR, + FUI_TEXT_FEED_MAX_Z_DELTA_FR, + FUI_TEXT_FEED_HOME_X_FR, + FUI_TEXT_FEED_HOME_Y_FR, + FUI_TEXT_FEED_HOME_Z_FR, + FUI_TEXT_FEED_HOME_Z_DELTA_FR, + FUI_TEXT_ACTION_XPOSITION4A_FR, + FUI_TEXT_ACTION_XPOSITION4B_FR, + FUI_TEXT_ACTION_XPOSITION4C_FR, + FUI_TEXT_ACTION_XPOSITION4D_FR, + FUI_TEXT_ACTION_YPOSITION4A_FR, + FUI_TEXT_ACTION_YPOSITION4B_FR, + FUI_TEXT_ACTION_YPOSITION4C_FR, + FUI_TEXT_ACTION_YPOSITION4D_FR, + FUI_TEXT_ACTION_ZPOSITION4A_FR, + FUI_TEXT_ACTION_ZPOSITION4B_FR, + FUI_TEXT_ACTION_ZPOSITION4C_FR, + FUI_TEXT_ACTION_ZPOSITION4D_FR, + FUI_TEXT_ACTION_XPOSITION_FAST4A_FR, + FUI_TEXT_ACTION_XPOSITION_FAST4B_FR, + FUI_TEXT_ACTION_XPOSITION_FAST4C_FR, + FUI_TEXT_ACTION_XPOSITION_FAST4D_FR, + FUI_TEXT_ACTION_YPOSITION_FAST4A_FR, + FUI_TEXT_ACTION_YPOSITION_FAST4B_FR, + FUI_TEXT_ACTION_YPOSITION_FAST4C_FR, + FUI_TEXT_ACTION_YPOSITION_FAST4D_FR, + FUI_TEXT_ACTION_ZPOSITION_FAST4A_FR, + FUI_TEXT_ACTION_ZPOSITION_FAST4B_FR, + FUI_TEXT_ACTION_ZPOSITION_FAST4C_FR, + FUI_TEXT_ACTION_ZPOSITION_FAST4D_FR, + FUI_TEXT_ACTION_EPOSITION_FAST2A_FR, + FUI_TEXT_ACTION_EPOSITION_FAST2B_FR, + FUI_TEXT_ACTION_XPOSITION2A_FR, + FUI_TEXT_ACTION_XPOSITION2B_FR, + FUI_TEXT_ACTION_YPOSITION2A_FR, + FUI_TEXT_ACTION_YPOSITION2B_FR, + FUI_TEXT_ACTION_ZPOSITION2A_FR, + FUI_TEXT_ACTION_ZPOSITION2B_FR, + FUI_TEXT_ACTION_XPOSITION_FAST2A_FR, + FUI_TEXT_ACTION_XPOSITION_FAST2B_FR, + FUI_TEXT_ACTION_YPOSITION_FAST2A_FR, + FUI_TEXT_ACTION_YPOSITION_FAST2B_FR, + FUI_TEXT_ACTION_ZPOSITION_FAST2A_FR, + FUI_TEXT_ACTION_ZPOSITION_FAST2B_FR, + FUI_TEXT_FANSPEED_FR, + FUI_TEXT_ACTION_FANSPEED_FR, + FUI_TEXT_FAN_OFF_FR, + FUI_TEXT_FAN_25_FR, + FUI_TEXT_FAN_50_FR, + FUI_TEXT_FAN_75_FR, + FUI_TEXT_FAN_FULL_FR, + FUI_TEXT_STEPPER_INACTIVE_FR, + FUI_TEXT_STEPPER_INACTIVE2A_FR, + FUI_TEXT_STEPPER_INACTIVE2B_FR, + FUI_TEXT_POWER_INACTIVE_FR, + FUI_TEXT_POWER_INACTIVE2A_FR, + FUI_TEXT_POWER_INACTIVE2B_FR, + FUI_TEXT_GENERAL_FR, + FUI_TEXT_BAUDRATE_FR, + FUI_TEXT_EXTR_STEPS_FR, + FUI_TEXT_EXTR_START_FEED_FR, + FUI_TEXT_EXTR_MAX_FEED_FR, + FUI_TEXT_EXTR_ACCEL_FR, + FUI_TEXT_EXTR_WATCH_FR, + FUI_TEXT_EXTR_ADVANCE_L_FR, + FUI_TEXT_EXTR_ADVANCE_K_FR, + FUI_TEXT_EXTR_MANAGER_FR, + FUI_TEXT_EXTR_PGAIN_FR, + FUI_TEXT_EXTR_DEADTIME_FR, + FUI_TEXT_EXTR_DMAX_DT_FR, + FUI_TEXT_EXTR_IGAIN_FR, + FUI_TEXT_EXTR_DGAIN_FR, + FUI_TEXT_EXTR_DMIN_FR, + FUI_TEXT_EXTR_DMAX_FR, + FUI_TEXT_EXTR_PMAX_FR, + FUI_TEXT_EXTR_XOFF_FR, + FUI_TEXT_EXTR_YOFF_FR, + FUI_TEXT_STRING_HM_BANGBANG_FR, + FUI_TEXT_STRING_HM_PID_FR, + FUI_TEXT_STRING_ACTION_FR, + FUI_TEXT_HEATING_EXTRUDER_FR, + FUI_TEXT_HEATING_BED_FR, + FUI_TEXT_KILLED_FR, + FUI_TEXT_STEPPER_DISABLED_FR, + FUI_TEXT_EEPROM_STOREDA_FR, + FUI_TEXT_EEPROM_STOREDB_FR, + FUI_TEXT_EEPROM_LOADEDA_FR, + FUI_TEXT_EEPROM_LOADEDB_FR, + FUI_TEXT_UPLOADING_FR, + FUI_TEXT_PAGE_BUFFER_FR, + FUI_TEXT_PAGE_EXTRUDER_FR, + FUI_TEXT_PAGE_EXTRUDER1_FR, + FUI_TEXT_PAGE_EXTRUDER2_FR, + FUI_TEXT_PAGE_EXTRUDER3_FR, + FUI_TEXT_PAGE_BED_FR, + FUI_TEXT_SPEED_MULTIPLY_FR, + FUI_TEXT_FLOW_MULTIPLY_FR, + FUI_TEXT_SHOW_MEASUREMENT_FR, + FUI_TEXT_RESET_MEASUREMENT_FR, + FUI_TEXT_SET_MEASURED_ORIGIN_FR, + FUI_TEXT_ZCALIB_FR, + FUI_TEXT_SET_P1_FR, + FUI_TEXT_SET_P2_FR, + FUI_TEXT_SET_P3_FR, + FUI_TEXT_CALCULATE_LEVELING_FR, + FUI_TEXT_LEVEL_FR, + FUI_TEXT_EXTR_WAIT_RETRACT_TEMP_FR, + FUI_TEXT_EXTR_WAIT_RETRACT_UNITS_FR, + FUI_TEXT_SD_REMOVED_FR, + FUI_TEXT_SD_INSERTED_FR, + FUI_TEXT_PRINTER_READY_FR, + FUI_TEXT_PRINTTIME_DAYS_FR, + FUI_TEXT_PRINTTIME_HOURS_FR, + FUI_TEXT_PRINTTIME_MINUTES_FR, + FUI_TEXT_PRINT_TIME_FR, + FUI_TEXT_PRINT_FILAMENT_FR, + FUI_TEXT_PRINTED_FR, + FUI_TEXT_POWER_FR, + FUI_TEXT_STRING_HM_DEADTIME_FR, + FUI_TEXT_STRING_HM_SLOWBANG_FR, + FUI_TEXT_STOP_PRINT_FR, + FUI_TEXT_Z_BABYSTEPPING_FR, + FUI_TEXT_CHANGE_FILAMENT_FR, + FUI_TEXT_WIZ_CH_FILAMENT1_FR, + FUI_TEXT_WIZ_CH_FILAMENT2_FR, + FUI_TEXT_WIZ_CH_FILAMENT3_FR, + FUI_TEXT_CLICK_DONE_FR, + FUI_TEXT_AUTOLEVEL_ONOFF_FR, + FUI_TEXT_SERVOPOS_FR, + FUI_TEXT_IGNORE_M106_FR, + FUI_TEXT_WIZ_REHEAT1_FR, + FUI_TEXT_WIZ_REHEAT2_FR, + FUI_TEXT_WIZ_WAITTEMP1_FR, + FUI_TEXT_WIZ_WAITTEMP2_FR, + FUI_TEXT_EXTRUDER_JAM_FR, + FUI_TEXT_STANDBY_FR, + FUI_TEXT_BED_COATING_FR, + FUI_TEXT_BED_COATING_SET1_FR, + FUI_TEXT_BED_COATING_SET2_FR, + FUI_TEXT_NOCOATING_FR, + FUI_TEXT_BUILDTAK_FR, + FUI_TEXT_KAPTON_FR, + FUI_TEXT_BLUETAPE_FR, + FUI_TEXT_PETTAPE_FR, + FUI_TEXT_GLUESTICK_FR, + FUI_TEXT_CUSTOM_FR, + FUI_TEXT_COATING_CUSTOM_FR, + FUI_TEXT_LANGUAGE_FR, + FUI_TEXT_MAINPAGE6_1_FR, + FUI_TEXT_MAINPAGE6_2_FR, + FUI_TEXT_MAINPAGE6_3_FR, + FUI_TEXT_MAINPAGE6_4_FR, + FUI_TEXT_MAINPAGE6_5_FR, + FUI_TEXT_MAINPAGE6_6_FR, + FUI_TEXT_MAINPAGE_TEMP_BED_FR, + FUI_TEXT_MAINPAGE_BED_FR, + FUI_TEXT_MAINPAGE_Z_BUF_FR, + FUI_TEXT_MAINPAGE_MUL_EUSAGE_FR, + FUI_TEXT_MAINPAGE_XY_FR, + FUI_TEXT_PRINT_TIME_VALUE_FR, + FUI_TEXT_PRINT_FILAMENT_VALUE_FR, + FUI_TEXT_METER_PRINTED_FR, + FUI_TEXT_STATUS_FR, + FUI_TEXT_EMPTY_FR, + FUI_TEXT_TEMP_SET_FR, + FUI_TEXT_CURRENT_TEMP_FR, + FUI_TEXT_COATING_THICKNESS_FR, + FUI_TEXT_EXTR3_TEMP_FR, + FUI_TEXT_EXTR4_TEMP_FR, + FUI_TEXT_EXTR5_TEMP_FR, + FUI_TEXT_EXTR3_OFF_FR, + FUI_TEXT_EXTR4_OFF_FR, + FUI_TEXT_EXTR5_OFF_FR, + FUI_TEXT_EXTR3_SELECT_FR, + FUI_TEXT_EXTR4_SELECT_FR, + FUI_TEXT_EXTR5_SELECT_FR, + FUI_TEXT_DITTO_0_FR, + FUI_TEXT_DITTO_1_FR, + FUI_TEXT_DITTO_2_FR, + FUI_TEXT_DITTO_3_FR, + FUI_TEXT_ZPROBE_HEIGHT_FR, + FUI_TEXT_OFFSETS_FR, + FUI_TEXT_X_OFFSET_FR, + FUI_TEXT_Y_OFFSET_FR, + FUI_TEXT_Z_OFFSET_FR, + FUI_TEXT_DBG_ENDSTOP_FR +}; +#define LANG_FR_TABLE translations_fr +#else +#define LANG_FR_TABLE NULL +#endif // LANGUAGE_FR_ACTIVE + + +#if LANGUAGE_CZ_ACTIVE +TRANS(UI_TEXT_ON_CZ); +TRANS(UI_TEXT_OFF_CZ); +TRANS(UI_TEXT_NA_CZ); +TRANS(UI_TEXT_YES_CZ); +TRANS(UI_TEXT_NO_CZ); +TRANS(UI_TEXT_PRINT_POS_CZ); +TRANS(UI_TEXT_PRINTING_CZ); +TRANS(UI_TEXT_IDLE_CZ); +TRANS(UI_TEXT_NOSDCARD_CZ); +TRANS(UI_TEXT_ERROR_CZ); +TRANS(UI_TEXT_BACK_CZ); +TRANS(UI_TEXT_QUICK_SETTINGS_CZ); +TRANS(UI_TEXT_ERRORMSG_CZ); +TRANS(UI_TEXT_CONFIGURATION_CZ); +TRANS(UI_TEXT_POSITION_CZ); +TRANS(UI_TEXT_EXTRUDER_CZ); +TRANS(UI_TEXT_SD_CARD_CZ); +TRANS(UI_TEXT_DEBUGGING_CZ); +TRANS(UI_TEXT_HOME_DELTA_CZ); +TRANS(UI_TEXT_HOME_ALL_CZ); +TRANS(UI_TEXT_HOME_X_CZ); +TRANS(UI_TEXT_HOME_Y_CZ); +TRANS(UI_TEXT_HOME_Z_CZ); +TRANS(UI_TEXT_PREHEAT_PLA_CZ); +TRANS(UI_TEXT_PREHEAT_ABS_CZ); +TRANS(UI_TEXT_LIGHTS_ONOFF_CZ); +TRANS(UI_TEXT_COOLDOWN_CZ); +TRANS(UI_TEXT_SET_TO_ORIGIN_CZ); +TRANS(UI_TEXT_DISABLE_STEPPER_CZ); +TRANS(UI_TEXT_X_POSITION_CZ); +TRANS(UI_TEXT_X_POS_FAST_CZ); +TRANS(UI_TEXT_Y_POSITION_CZ); +TRANS(UI_TEXT_Y_POS_FAST_CZ); +TRANS(UI_TEXT_Z_POSITION_CZ); +TRANS(UI_TEXT_Z_POS_FAST_CZ); +TRANS(UI_TEXT_E_POSITION_CZ); +TRANS(UI_TEXT_BED_TEMP_CZ); +TRANS(UI_TEXT_EXTR0_TEMP_CZ); +TRANS(UI_TEXT_EXTR1_TEMP_CZ); +TRANS(UI_TEXT_EXTR2_TEMP_CZ); +TRANS(UI_TEXT_EXTR0_OFF_CZ); +TRANS(UI_TEXT_EXTR1_OFF_CZ); +TRANS(UI_TEXT_EXTR2_OFF_CZ); +TRANS(UI_TEXT_EXTR0_SELECT_CZ); +TRANS(UI_TEXT_EXTR1_SELECT_CZ); +TRANS(UI_TEXT_EXTR2_SELECT_CZ); +TRANS(UI_TEXT_EXTR_ORIGIN_CZ); +TRANS(UI_TEXT_PRINT_X_CZ); +TRANS(UI_TEXT_PRINT_Y_CZ); +TRANS(UI_TEXT_PRINT_Z_CZ); +TRANS(UI_TEXT_PRINT_Z_DELTA_CZ); +TRANS(UI_TEXT_MOVE_X_CZ); +TRANS(UI_TEXT_MOVE_Y_CZ); +TRANS(UI_TEXT_MOVE_Z_CZ); +TRANS(UI_TEXT_MOVE_Z_DELTA_CZ); +TRANS(UI_TEXT_JERK_CZ); +TRANS(UI_TEXT_ZJERK_CZ); +TRANS(UI_TEXT_ACCELERATION_CZ); +TRANS(UI_TEXT_STORE_TO_EEPROM_CZ); +TRANS(UI_TEXT_LOAD_EEPROM_CZ); +TRANS(UI_TEXT_DBG_ECHO_CZ); +TRANS(UI_TEXT_DBG_INFO_CZ); +TRANS(UI_TEXT_DBG_ERROR_CZ); +TRANS(UI_TEXT_DBG_DRYRUN_CZ); +TRANS(UI_TEXT_DBG_ENDSTOP_CZ); +TRANS(UI_TEXT_OPS_OFF_CZ); +TRANS(UI_TEXT_OPS_CLASSIC_CZ); +TRANS(UI_TEXT_OPS_FAST_CZ); +TRANS(UI_TEXT_OPS_RETRACT_CZ); +TRANS(UI_TEXT_OPS_BACKSLASH_CZ); +TRANS(UI_TEXT_OPS_MINDIST_CZ); +TRANS(UI_TEXT_OPS_MOVE_AFTER_CZ); +TRANS(UI_TEXT_ANTI_OOZE_CZ); +TRANS(UI_TEXT_PRINT_FILE_CZ); +TRANS(UI_TEXT_PAUSE_PRINT_CZ); +TRANS(UI_TEXT_CONTINUE_PRINT_CZ); +TRANS(UI_TEXT_UNMOUNT_CARD_CZ); +TRANS(UI_TEXT_MOUNT_CARD_CZ); +TRANS(UI_TEXT_DELETE_FILE_CZ); +TRANS(UI_TEXT_FEEDRATE_CZ); +TRANS(UI_TEXT_FEED_MAX_X_CZ); +TRANS(UI_TEXT_FEED_MAX_Y_CZ); +TRANS(UI_TEXT_FEED_MAX_Z_CZ); +TRANS(UI_TEXT_FEED_MAX_Z_DELTA_CZ); +TRANS(UI_TEXT_FEED_HOME_X_CZ); +TRANS(UI_TEXT_FEED_HOME_Y_CZ); +TRANS(UI_TEXT_FEED_HOME_Z_CZ); +TRANS(UI_TEXT_FEED_HOME_Z_DELTA_CZ); +TRANS(UI_TEXT_ACTION_XPOSITION4A_CZ); +TRANS(UI_TEXT_ACTION_XPOSITION4B_CZ); +TRANS(UI_TEXT_ACTION_XPOSITION4C_CZ); +TRANS(UI_TEXT_ACTION_XPOSITION4D_CZ); +TRANS(UI_TEXT_ACTION_YPOSITION4A_CZ); +TRANS(UI_TEXT_ACTION_YPOSITION4B_CZ); +TRANS(UI_TEXT_ACTION_YPOSITION4C_CZ); +TRANS(UI_TEXT_ACTION_YPOSITION4D_CZ); +TRANS(UI_TEXT_ACTION_ZPOSITION4A_CZ); +TRANS(UI_TEXT_ACTION_ZPOSITION4B_CZ); +TRANS(UI_TEXT_ACTION_ZPOSITION4C_CZ); +TRANS(UI_TEXT_ACTION_ZPOSITION4D_CZ); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST4A_CZ); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST4B_CZ); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST4C_CZ); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST4D_CZ); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST4A_CZ); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST4B_CZ); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST4C_CZ); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST4D_CZ); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST4A_CZ); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST4B_CZ); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST4C_CZ); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST4D_CZ); +TRANS(UI_TEXT_ACTION_EPOSITION_FAST2A_CZ); +TRANS(UI_TEXT_ACTION_EPOSITION_FAST2B_CZ); +TRANS(UI_TEXT_ACTION_XPOSITION2A_CZ); +TRANS(UI_TEXT_ACTION_XPOSITION2B_CZ); +TRANS(UI_TEXT_ACTION_YPOSITION2A_CZ); +TRANS(UI_TEXT_ACTION_YPOSITION2B_CZ); +TRANS(UI_TEXT_ACTION_ZPOSITION2A_CZ); +TRANS(UI_TEXT_ACTION_ZPOSITION2B_CZ); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST2A_CZ); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST2B_CZ); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST2A_CZ); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST2B_CZ); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST2A_CZ); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST2B_CZ); +TRANS(UI_TEXT_FANSPEED_CZ); +TRANS(UI_TEXT_ACTION_FANSPEED_CZ); +TRANS(UI_TEXT_FAN_OFF_CZ); +TRANS(UI_TEXT_FAN_25_CZ); +TRANS(UI_TEXT_FAN_50_CZ); +TRANS(UI_TEXT_FAN_75_CZ); +TRANS(UI_TEXT_FAN_FULL_CZ); +TRANS(UI_TEXT_STEPPER_INACTIVE_CZ); +TRANS(UI_TEXT_STEPPER_INACTIVE2A_CZ); +TRANS(UI_TEXT_STEPPER_INACTIVE2B_CZ); +TRANS(UI_TEXT_POWER_INACTIVE_CZ); +TRANS(UI_TEXT_POWER_INACTIVE2A_CZ); +TRANS(UI_TEXT_POWER_INACTIVE2B_CZ); +TRANS(UI_TEXT_GENERAL_CZ); +TRANS(UI_TEXT_BAUDRATE_CZ); +TRANS(UI_TEXT_EXTR_STEPS_CZ); +TRANS(UI_TEXT_EXTR_START_FEED_CZ); +TRANS(UI_TEXT_EXTR_MAX_FEED_CZ); +TRANS(UI_TEXT_EXTR_ACCEL_CZ); +TRANS(UI_TEXT_EXTR_WATCH_CZ); +TRANS(UI_TEXT_EXTR_ADVANCE_L_CZ); +TRANS(UI_TEXT_EXTR_ADVANCE_K_CZ); +TRANS(UI_TEXT_EXTR_MANAGER_CZ); +TRANS(UI_TEXT_EXTR_PGAIN_CZ); +TRANS(UI_TEXT_EXTR_DEADTIME_CZ); +TRANS(UI_TEXT_EXTR_DMAX_DT_CZ); +TRANS(UI_TEXT_EXTR_IGAIN_CZ); +TRANS(UI_TEXT_EXTR_DGAIN_CZ); +TRANS(UI_TEXT_EXTR_DMIN_CZ); +TRANS(UI_TEXT_EXTR_DMAX_CZ); +TRANS(UI_TEXT_EXTR_PMAX_CZ); +TRANS(UI_TEXT_EXTR_XOFF_CZ); +TRANS(UI_TEXT_EXTR_YOFF_CZ); +TRANS(UI_TEXT_STRING_HM_BANGBANG_CZ); +TRANS(UI_TEXT_STRING_HM_PID_CZ); +TRANS(UI_TEXT_STRING_ACTION_CZ); +TRANS(UI_TEXT_HEATING_EXTRUDER_CZ); +TRANS(UI_TEXT_HEATING_BED_CZ); +TRANS(UI_TEXT_KILLED_CZ); +TRANS(UI_TEXT_STEPPER_DISABLED_CZ); +TRANS(UI_TEXT_EEPROM_STOREDA_CZ); +TRANS(UI_TEXT_EEPROM_STOREDB_CZ); +TRANS(UI_TEXT_EEPROM_LOADEDA_CZ); +TRANS(UI_TEXT_EEPROM_LOADEDB_CZ); +TRANS(UI_TEXT_UPLOADING_CZ); +TRANS(UI_TEXT_PAGE_BUFFER_CZ); +TRANS(UI_TEXT_PAGE_EXTRUDER_CZ); +TRANS(UI_TEXT_PAGE_EXTRUDER1_CZ); +TRANS(UI_TEXT_PAGE_EXTRUDER2_CZ); +TRANS(UI_TEXT_PAGE_EXTRUDER3_CZ); +TRANS(UI_TEXT_PAGE_BED_CZ); +TRANS(UI_TEXT_SPEED_MULTIPLY_CZ); +TRANS(UI_TEXT_FLOW_MULTIPLY_CZ); +TRANS(UI_TEXT_SHOW_MEASUREMENT_CZ); +TRANS(UI_TEXT_RESET_MEASUREMENT_CZ); +TRANS(UI_TEXT_SET_MEASURED_ORIGIN_CZ); +TRANS(UI_TEXT_ZCALIB_CZ); +TRANS(UI_TEXT_SET_P1_CZ); +TRANS(UI_TEXT_SET_P2_CZ); +TRANS(UI_TEXT_SET_P3_CZ); +TRANS(UI_TEXT_CALCULATE_LEVELING_CZ); +TRANS(UI_TEXT_LEVEL_CZ); +TRANS(UI_TEXT_EXTR_WAIT_RETRACT_TEMP_CZ); +TRANS(UI_TEXT_EXTR_WAIT_RETRACT_UNITS_CZ); +TRANS(UI_TEXT_SD_REMOVED_CZ); +TRANS(UI_TEXT_SD_INSERTED_CZ); +TRANS(UI_TEXT_PRINTER_READY_CZ); +TRANS(UI_TEXT_PRINTTIME_DAYS_CZ); +TRANS(UI_TEXT_PRINTTIME_HOURS_CZ); +TRANS(UI_TEXT_PRINTTIME_MINUTES_CZ); +TRANS(UI_TEXT_PRINT_TIME_CZ); +TRANS(UI_TEXT_PRINT_FILAMENT_CZ); +TRANS(UI_TEXT_PRINTED_CZ); +TRANS(UI_TEXT_POWER_CZ); +TRANS(UI_TEXT_STRING_HM_DEADTIME_CZ); +TRANS(UI_TEXT_STRING_HM_SLOWBANG_CZ); +TRANS(UI_TEXT_STOP_PRINT_CZ); +TRANS(UI_TEXT_Z_BABYSTEPPING_CZ); +TRANS(UI_TEXT_CHANGE_FILAMENT_CZ); +TRANS(UI_TEXT_WIZ_CH_FILAMENT1_CZ); +TRANS(UI_TEXT_WIZ_CH_FILAMENT2_CZ); +TRANS(UI_TEXT_WIZ_CH_FILAMENT3_CZ); +TRANS(UI_TEXT_CLICK_DONE_CZ); +TRANS(UI_TEXT_AUTOLEVEL_ONOFF_CZ); +TRANS(UI_TEXT_SERVOPOS_CZ); +TRANS(UI_TEXT_IGNORE_M106_CZ); +TRANS(UI_TEXT_WIZ_REHEAT1_CZ); +TRANS(UI_TEXT_WIZ_REHEAT2_CZ); +TRANS(UI_TEXT_WIZ_WAITTEMP1_CZ); +TRANS(UI_TEXT_WIZ_WAITTEMP2_CZ); +TRANS(UI_TEXT_EXTRUDER_JAM_CZ); +TRANS(UI_TEXT_STANDBY_CZ); +TRANS(UI_TEXT_BED_COATING_CZ); +TRANS(UI_TEXT_BED_COATING_SET1_CZ); +TRANS(UI_TEXT_BED_COATING_SET2_CZ); +TRANS(UI_TEXT_NOCOATING_CZ); +TRANS(UI_TEXT_BUILDTAK_CZ); +TRANS(UI_TEXT_KAPTON_CZ); +TRANS(UI_TEXT_BLUETAPE_CZ); +TRANS(UI_TEXT_PETTAPE_CZ); +TRANS(UI_TEXT_GLUESTICK_CZ); +TRANS(UI_TEXT_CUSTOM_CZ); +TRANS(UI_TEXT_COATING_CUSTOM_CZ); +TRANS(UI_TEXT_LANGUAGE_CZ); +TRANS(UI_TEXT_MAINPAGE6_1_CZ); +TRANS(UI_TEXT_MAINPAGE6_2_CZ); +TRANS(UI_TEXT_MAINPAGE6_3_CZ); +TRANS(UI_TEXT_MAINPAGE6_4_CZ); +TRANS(UI_TEXT_MAINPAGE6_5_CZ); +TRANS(UI_TEXT_MAINPAGE6_6_CZ); +TRANS(UI_TEXT_MAINPAGE_TEMP_BED_CZ); +TRANS(UI_TEXT_MAINPAGE_BED_CZ); +TRANS(UI_TEXT_MAINPAGE_Z_BUF_CZ); +TRANS(UI_TEXT_MAINPAGE_MUL_EUSAGE_CZ); +TRANS(UI_TEXT_MAINPAGE_XY_CZ); +TRANS(UI_TEXT_PRINT_TIME_VALUE_CZ); +TRANS(UI_TEXT_PRINT_FILAMENT_VALUE_CZ); +TRANS(UI_TEXT_METER_PRINTED_CZ); +TRANS(UI_TEXT_STATUS_CZ); +TRANS(UI_TEXT_EMPTY_CZ); +TRANS(UI_TEXT_TEMP_SET_CZ); +TRANS(UI_TEXT_CURRENT_TEMP_CZ); +TRANS(UI_TEXT_COATING_THICKNESS_CZ); +TRANS(UI_TEXT_EXTR3_TEMP_CZ); +TRANS(UI_TEXT_EXTR4_TEMP_CZ); +TRANS(UI_TEXT_EXTR5_TEMP_CZ); +TRANS(UI_TEXT_EXTR3_OFF_CZ); +TRANS(UI_TEXT_EXTR4_OFF_CZ); +TRANS(UI_TEXT_EXTR5_OFF_CZ); +TRANS(UI_TEXT_EXTR3_SELECT_CZ); +TRANS(UI_TEXT_EXTR4_SELECT_CZ); +TRANS(UI_TEXT_EXTR5_SELECT_CZ); +TRANS(UI_TEXT_DITTO_0_CZ); +TRANS(UI_TEXT_DITTO_1_CZ); +TRANS(UI_TEXT_DITTO_2_CZ); +TRANS(UI_TEXT_DITTO_3_CZ); +TRANS(UI_TEXT_ZPROBE_HEIGHT_CZ); +TRANS(UI_TEXT_OFFSETS_CZ); +TRANS(UI_TEXT_X_OFFSET_CZ); +TRANS(UI_TEXT_Y_OFFSET_CZ); +TRANS(UI_TEXT_Z_OFFSET_CZ); + +PGM_P const translations_cz[NUM_TRANSLATED_WORDS] PROGMEM = { + FUI_TEXT_ON_CZ, + FUI_TEXT_OFF_CZ, + FUI_TEXT_NA_CZ, + FUI_TEXT_YES_CZ, + FUI_TEXT_NO_CZ, + FUI_TEXT_PRINT_POS_CZ, + FUI_TEXT_PRINTING_CZ, + FUI_TEXT_IDLE_CZ, + FUI_TEXT_NOSDCARD_CZ, + FUI_TEXT_ERROR_CZ, + FUI_TEXT_BACK_CZ, + FUI_TEXT_QUICK_SETTINGS_CZ, + FUI_TEXT_ERRORMSG_CZ, + FUI_TEXT_CONFIGURATION_CZ, + FUI_TEXT_POSITION_CZ, + FUI_TEXT_EXTRUDER_CZ, + FUI_TEXT_SD_CARD_CZ, + FUI_TEXT_DEBUGGING_CZ, + FUI_TEXT_HOME_DELTA_CZ, + FUI_TEXT_HOME_ALL_CZ, + FUI_TEXT_HOME_X_CZ, + FUI_TEXT_HOME_Y_CZ, + FUI_TEXT_HOME_Z_CZ, + FUI_TEXT_PREHEAT_PLA_CZ, + FUI_TEXT_PREHEAT_ABS_CZ, + FUI_TEXT_LIGHTS_ONOFF_CZ, + FUI_TEXT_COOLDOWN_CZ, + FUI_TEXT_SET_TO_ORIGIN_CZ, + FUI_TEXT_DISABLE_STEPPER_CZ, + FUI_TEXT_X_POSITION_CZ, + FUI_TEXT_X_POS_FAST_CZ, + FUI_TEXT_Y_POSITION_CZ, + FUI_TEXT_Y_POS_FAST_CZ, + FUI_TEXT_Z_POSITION_CZ, + FUI_TEXT_Z_POS_FAST_CZ, + FUI_TEXT_E_POSITION_CZ, + FUI_TEXT_BED_TEMP_CZ, + FUI_TEXT_EXTR0_TEMP_CZ, + FUI_TEXT_EXTR1_TEMP_CZ, + FUI_TEXT_EXTR2_TEMP_CZ, + FUI_TEXT_EXTR0_OFF_CZ, + FUI_TEXT_EXTR1_OFF_CZ, + FUI_TEXT_EXTR2_OFF_CZ, + FUI_TEXT_EXTR0_SELECT_CZ, + FUI_TEXT_EXTR1_SELECT_CZ, + FUI_TEXT_EXTR2_SELECT_CZ, + FUI_TEXT_EXTR_ORIGIN_CZ, + FUI_TEXT_PRINT_X_CZ, + FUI_TEXT_PRINT_Y_CZ, + FUI_TEXT_PRINT_Z_CZ, + FUI_TEXT_PRINT_Z_DELTA_CZ, + FUI_TEXT_MOVE_X_CZ, + FUI_TEXT_MOVE_Y_CZ, + FUI_TEXT_MOVE_Z_CZ, + FUI_TEXT_MOVE_Z_DELTA_CZ, + FUI_TEXT_JERK_CZ, + FUI_TEXT_ZJERK_CZ, + FUI_TEXT_ACCELERATION_CZ, + FUI_TEXT_STORE_TO_EEPROM_CZ, + FUI_TEXT_LOAD_EEPROM_CZ, + FUI_TEXT_DBG_ECHO_CZ, + FUI_TEXT_DBG_INFO_CZ, + FUI_TEXT_DBG_ERROR_CZ, + FUI_TEXT_DBG_DRYRUN_CZ, + FUI_TEXT_OPS_OFF_CZ, + FUI_TEXT_OPS_CLASSIC_CZ, + FUI_TEXT_OPS_FAST_CZ, + FUI_TEXT_OPS_RETRACT_CZ, + FUI_TEXT_OPS_BACKSLASH_CZ, + FUI_TEXT_OPS_MINDIST_CZ, + FUI_TEXT_OPS_MOVE_AFTER_CZ, + FUI_TEXT_ANTI_OOZE_CZ, + FUI_TEXT_PRINT_FILE_CZ, + FUI_TEXT_PAUSE_PRINT_CZ, + FUI_TEXT_CONTINUE_PRINT_CZ, + FUI_TEXT_UNMOUNT_CARD_CZ, + FUI_TEXT_MOUNT_CARD_CZ, + FUI_TEXT_DELETE_FILE_CZ, + FUI_TEXT_FEEDRATE_CZ, + FUI_TEXT_FEED_MAX_X_CZ, + FUI_TEXT_FEED_MAX_Y_CZ, + FUI_TEXT_FEED_MAX_Z_CZ, + FUI_TEXT_FEED_MAX_Z_DELTA_CZ, + FUI_TEXT_FEED_HOME_X_CZ, + FUI_TEXT_FEED_HOME_Y_CZ, + FUI_TEXT_FEED_HOME_Z_CZ, + FUI_TEXT_FEED_HOME_Z_DELTA_CZ, + FUI_TEXT_ACTION_XPOSITION4A_CZ, + FUI_TEXT_ACTION_XPOSITION4B_CZ, + FUI_TEXT_ACTION_XPOSITION4C_CZ, + FUI_TEXT_ACTION_XPOSITION4D_CZ, + FUI_TEXT_ACTION_YPOSITION4A_CZ, + FUI_TEXT_ACTION_YPOSITION4B_CZ, + FUI_TEXT_ACTION_YPOSITION4C_CZ, + FUI_TEXT_ACTION_YPOSITION4D_CZ, + FUI_TEXT_ACTION_ZPOSITION4A_CZ, + FUI_TEXT_ACTION_ZPOSITION4B_CZ, + FUI_TEXT_ACTION_ZPOSITION4C_CZ, + FUI_TEXT_ACTION_ZPOSITION4D_CZ, + FUI_TEXT_ACTION_XPOSITION_FAST4A_CZ, + FUI_TEXT_ACTION_XPOSITION_FAST4B_CZ, + FUI_TEXT_ACTION_XPOSITION_FAST4C_CZ, + FUI_TEXT_ACTION_XPOSITION_FAST4D_CZ, + FUI_TEXT_ACTION_YPOSITION_FAST4A_CZ, + FUI_TEXT_ACTION_YPOSITION_FAST4B_CZ, + FUI_TEXT_ACTION_YPOSITION_FAST4C_CZ, + FUI_TEXT_ACTION_YPOSITION_FAST4D_CZ, + FUI_TEXT_ACTION_ZPOSITION_FAST4A_CZ, + FUI_TEXT_ACTION_ZPOSITION_FAST4B_CZ, + FUI_TEXT_ACTION_ZPOSITION_FAST4C_CZ, + FUI_TEXT_ACTION_ZPOSITION_FAST4D_CZ, + FUI_TEXT_ACTION_EPOSITION_FAST2A_CZ, + FUI_TEXT_ACTION_EPOSITION_FAST2B_CZ, + FUI_TEXT_ACTION_XPOSITION2A_CZ, + FUI_TEXT_ACTION_XPOSITION2B_CZ, + FUI_TEXT_ACTION_YPOSITION2A_CZ, + FUI_TEXT_ACTION_YPOSITION2B_CZ, + FUI_TEXT_ACTION_ZPOSITION2A_CZ, + FUI_TEXT_ACTION_ZPOSITION2B_CZ, + FUI_TEXT_ACTION_XPOSITION_FAST2A_CZ, + FUI_TEXT_ACTION_XPOSITION_FAST2B_CZ, + FUI_TEXT_ACTION_YPOSITION_FAST2A_CZ, + FUI_TEXT_ACTION_YPOSITION_FAST2B_CZ, + FUI_TEXT_ACTION_ZPOSITION_FAST2A_CZ, + FUI_TEXT_ACTION_ZPOSITION_FAST2B_CZ, + FUI_TEXT_FANSPEED_CZ, + FUI_TEXT_ACTION_FANSPEED_CZ, + FUI_TEXT_FAN_OFF_CZ, + FUI_TEXT_FAN_25_CZ, + FUI_TEXT_FAN_50_CZ, + FUI_TEXT_FAN_75_CZ, + FUI_TEXT_FAN_FULL_CZ, + FUI_TEXT_STEPPER_INACTIVE_CZ, + FUI_TEXT_STEPPER_INACTIVE2A_CZ, + FUI_TEXT_STEPPER_INACTIVE2B_CZ, + FUI_TEXT_POWER_INACTIVE_CZ, + FUI_TEXT_POWER_INACTIVE2A_CZ, + FUI_TEXT_POWER_INACTIVE2B_CZ, + FUI_TEXT_GENERAL_CZ, + FUI_TEXT_BAUDRATE_CZ, + FUI_TEXT_EXTR_STEPS_CZ, + FUI_TEXT_EXTR_START_FEED_CZ, + FUI_TEXT_EXTR_MAX_FEED_CZ, + FUI_TEXT_EXTR_ACCEL_CZ, + FUI_TEXT_EXTR_WATCH_CZ, + FUI_TEXT_EXTR_ADVANCE_L_CZ, + FUI_TEXT_EXTR_ADVANCE_K_CZ, + FUI_TEXT_EXTR_MANAGER_CZ, + FUI_TEXT_EXTR_PGAIN_CZ, + FUI_TEXT_EXTR_DEADTIME_CZ, + FUI_TEXT_EXTR_DMAX_DT_CZ, + FUI_TEXT_EXTR_IGAIN_CZ, + FUI_TEXT_EXTR_DGAIN_CZ, + FUI_TEXT_EXTR_DMIN_CZ, + FUI_TEXT_EXTR_DMAX_CZ, + FUI_TEXT_EXTR_PMAX_CZ, + FUI_TEXT_EXTR_XOFF_CZ, + FUI_TEXT_EXTR_YOFF_CZ, + FUI_TEXT_STRING_HM_BANGBANG_CZ, + FUI_TEXT_STRING_HM_PID_CZ, + FUI_TEXT_STRING_ACTION_CZ, + FUI_TEXT_HEATING_EXTRUDER_CZ, + FUI_TEXT_HEATING_BED_CZ, + FUI_TEXT_KILLED_CZ, + FUI_TEXT_STEPPER_DISABLED_CZ, + FUI_TEXT_EEPROM_STOREDA_CZ, + FUI_TEXT_EEPROM_STOREDB_CZ, + FUI_TEXT_EEPROM_LOADEDA_CZ, + FUI_TEXT_EEPROM_LOADEDB_CZ, + FUI_TEXT_UPLOADING_CZ, + FUI_TEXT_PAGE_BUFFER_CZ, + FUI_TEXT_PAGE_EXTRUDER_CZ, + FUI_TEXT_PAGE_EXTRUDER1_CZ, + FUI_TEXT_PAGE_EXTRUDER2_CZ, + FUI_TEXT_PAGE_EXTRUDER3_CZ, + FUI_TEXT_PAGE_BED_CZ, + FUI_TEXT_SPEED_MULTIPLY_CZ, + FUI_TEXT_FLOW_MULTIPLY_CZ, + FUI_TEXT_SHOW_MEASUREMENT_CZ, + FUI_TEXT_RESET_MEASUREMENT_CZ, + FUI_TEXT_SET_MEASURED_ORIGIN_CZ, + FUI_TEXT_ZCALIB_CZ, + FUI_TEXT_SET_P1_CZ, + FUI_TEXT_SET_P2_CZ, + FUI_TEXT_SET_P3_CZ, + FUI_TEXT_CALCULATE_LEVELING_CZ, + FUI_TEXT_LEVEL_CZ, + FUI_TEXT_EXTR_WAIT_RETRACT_TEMP_CZ, + FUI_TEXT_EXTR_WAIT_RETRACT_UNITS_CZ, + FUI_TEXT_SD_REMOVED_CZ, + FUI_TEXT_SD_INSERTED_CZ, + FUI_TEXT_PRINTER_READY_CZ, + FUI_TEXT_PRINTTIME_DAYS_CZ, + FUI_TEXT_PRINTTIME_HOURS_CZ, + FUI_TEXT_PRINTTIME_MINUTES_CZ, + FUI_TEXT_PRINT_TIME_CZ, + FUI_TEXT_PRINT_FILAMENT_CZ, + FUI_TEXT_PRINTED_CZ, + FUI_TEXT_POWER_CZ, + FUI_TEXT_STRING_HM_DEADTIME_CZ, + FUI_TEXT_STRING_HM_SLOWBANG_CZ, + FUI_TEXT_STOP_PRINT_CZ, + FUI_TEXT_Z_BABYSTEPPING_CZ, + FUI_TEXT_CHANGE_FILAMENT_CZ, + FUI_TEXT_WIZ_CH_FILAMENT1_CZ, + FUI_TEXT_WIZ_CH_FILAMENT2_CZ, + FUI_TEXT_WIZ_CH_FILAMENT3_CZ, + FUI_TEXT_CLICK_DONE_CZ, + FUI_TEXT_AUTOLEVEL_ONOFF_CZ, + FUI_TEXT_SERVOPOS_CZ, + FUI_TEXT_IGNORE_M106_CZ, + FUI_TEXT_WIZ_REHEAT1_CZ, + FUI_TEXT_WIZ_REHEAT2_CZ, + FUI_TEXT_WIZ_WAITTEMP1_CZ, + FUI_TEXT_WIZ_WAITTEMP2_CZ, + FUI_TEXT_EXTRUDER_JAM_CZ, + FUI_TEXT_STANDBY_CZ, + FUI_TEXT_BED_COATING_CZ, + FUI_TEXT_BED_COATING_SET1_CZ, + FUI_TEXT_BED_COATING_SET2_CZ, + FUI_TEXT_NOCOATING_CZ, + FUI_TEXT_BUILDTAK_CZ, + FUI_TEXT_KAPTON_CZ, + FUI_TEXT_BLUETAPE_CZ, + FUI_TEXT_PETTAPE_CZ, + FUI_TEXT_GLUESTICK_CZ, + FUI_TEXT_CUSTOM_CZ, + FUI_TEXT_COATING_CUSTOM_CZ, + FUI_TEXT_LANGUAGE_CZ, + FUI_TEXT_MAINPAGE6_1_CZ, + FUI_TEXT_MAINPAGE6_2_CZ, + FUI_TEXT_MAINPAGE6_3_CZ, + FUI_TEXT_MAINPAGE6_4_CZ, + FUI_TEXT_MAINPAGE6_5_CZ, + FUI_TEXT_MAINPAGE6_6_CZ, + FUI_TEXT_MAINPAGE_TEMP_BED_CZ, + FUI_TEXT_MAINPAGE_BED_CZ, + FUI_TEXT_MAINPAGE_Z_BUF_CZ, + FUI_TEXT_MAINPAGE_MUL_EUSAGE_CZ, + FUI_TEXT_MAINPAGE_XY_CZ, + FUI_TEXT_PRINT_TIME_VALUE_CZ, + FUI_TEXT_PRINT_FILAMENT_VALUE_CZ, + FUI_TEXT_METER_PRINTED_CZ, + FUI_TEXT_STATUS_CZ, + FUI_TEXT_EMPTY_CZ, + FUI_TEXT_TEMP_SET_CZ, + FUI_TEXT_CURRENT_TEMP_CZ, + FUI_TEXT_COATING_THICKNESS_CZ, + FUI_TEXT_EXTR3_TEMP_CZ, + FUI_TEXT_EXTR4_TEMP_CZ, + FUI_TEXT_EXTR5_TEMP_CZ, + FUI_TEXT_EXTR3_OFF_CZ, + FUI_TEXT_EXTR4_OFF_CZ, + FUI_TEXT_EXTR5_OFF_CZ, + FUI_TEXT_EXTR3_SELECT_CZ, + FUI_TEXT_EXTR4_SELECT_CZ, + FUI_TEXT_EXTR5_SELECT_CZ, + FUI_TEXT_DITTO_0_CZ, + FUI_TEXT_DITTO_1_CZ, + FUI_TEXT_DITTO_2_CZ, + FUI_TEXT_DITTO_3_CZ, + FUI_TEXT_ZPROBE_HEIGHT_CZ, + FUI_TEXT_OFFSETS_CZ, + FUI_TEXT_X_OFFSET_CZ, + FUI_TEXT_Y_OFFSET_CZ, + FUI_TEXT_Z_OFFSET_CZ, + FUI_TEXT_DBG_ENDSTOP_CZ +}; +#define LANG_CZ_TABLE translations_cz +#else +#define LANG_CZ_TABLE NULL +#endif // LANGUAGE_CZ_ACTIVE + + +#if LANGUAGE_PL_ACTIVE +TRANS(UI_TEXT_ON_PL); +TRANS(UI_TEXT_OFF_PL); +TRANS(UI_TEXT_NA_PL); +TRANS(UI_TEXT_YES_PL); +TRANS(UI_TEXT_NO_PL); +TRANS(UI_TEXT_PRINT_POS_PL); +TRANS(UI_TEXT_PRINTING_PL); +TRANS(UI_TEXT_IDLE_PL); +TRANS(UI_TEXT_NOSDCARD_PL); +TRANS(UI_TEXT_ERROR_PL); +TRANS(UI_TEXT_BACK_PL); +TRANS(UI_TEXT_QUICK_SETTINGS_PL); +TRANS(UI_TEXT_ERRORMSG_PL); +TRANS(UI_TEXT_CONFIGURATION_PL); +TRANS(UI_TEXT_POSITION_PL); +TRANS(UI_TEXT_EXTRUDER_PL); +TRANS(UI_TEXT_SD_CARD_PL); +TRANS(UI_TEXT_DEBUGGING_PL); +TRANS(UI_TEXT_HOME_DELTA_PL); +TRANS(UI_TEXT_HOME_ALL_PL); +TRANS(UI_TEXT_HOME_X_PL); +TRANS(UI_TEXT_HOME_Y_PL); +TRANS(UI_TEXT_HOME_Z_PL); +TRANS(UI_TEXT_PREHEAT_PLA_PL); +TRANS(UI_TEXT_PREHEAT_ABS_PL); +TRANS(UI_TEXT_LIGHTS_ONOFF_PL); +TRANS(UI_TEXT_COOLDOWN_PL); +TRANS(UI_TEXT_SET_TO_ORIGIN_PL); +TRANS(UI_TEXT_DISABLE_STEPPER_PL); +TRANS(UI_TEXT_X_POSITION_PL); +TRANS(UI_TEXT_X_POS_FAST_PL); +TRANS(UI_TEXT_Y_POSITION_PL); +TRANS(UI_TEXT_Y_POS_FAST_PL); +TRANS(UI_TEXT_Z_POSITION_PL); +TRANS(UI_TEXT_Z_POS_FAST_PL); +TRANS(UI_TEXT_E_POSITION_PL); +TRANS(UI_TEXT_BED_TEMP_PL); +TRANS(UI_TEXT_EXTR0_TEMP_PL); +TRANS(UI_TEXT_EXTR1_TEMP_PL); +TRANS(UI_TEXT_EXTR2_TEMP_PL); +TRANS(UI_TEXT_EXTR0_OFF_PL); +TRANS(UI_TEXT_EXTR1_OFF_PL); +TRANS(UI_TEXT_EXTR2_OFF_PL); +TRANS(UI_TEXT_EXTR0_SELECT_PL); +TRANS(UI_TEXT_EXTR1_SELECT_PL); +TRANS(UI_TEXT_EXTR2_SELECT_PL); +TRANS(UI_TEXT_EXTR_ORIGIN_PL); +TRANS(UI_TEXT_PRINT_X_PL); +TRANS(UI_TEXT_PRINT_Y_PL); +TRANS(UI_TEXT_PRINT_Z_PL); +TRANS(UI_TEXT_PRINT_Z_DELTA_PL); +TRANS(UI_TEXT_MOVE_X_PL); +TRANS(UI_TEXT_MOVE_Y_PL); +TRANS(UI_TEXT_MOVE_Z_PL); +TRANS(UI_TEXT_MOVE_Z_DELTA_PL); +TRANS(UI_TEXT_JERK_PL); +TRANS(UI_TEXT_ZJERK_PL); +TRANS(UI_TEXT_ACCELERATION_PL); +TRANS(UI_TEXT_STORE_TO_EEPROM_PL); +TRANS(UI_TEXT_LOAD_EEPROM_PL); +TRANS(UI_TEXT_DBG_ECHO_PL); +TRANS(UI_TEXT_DBG_INFO_PL); +TRANS(UI_TEXT_DBG_ERROR_PL); +TRANS(UI_TEXT_DBG_DRYRUN_PL); +TRANS(UI_TEXT_DBG_ENDSTOP_PL); +TRANS(UI_TEXT_OPS_OFF_PL); +TRANS(UI_TEXT_OPS_CLASSIC_PL); +TRANS(UI_TEXT_OPS_FAST_PL); +TRANS(UI_TEXT_OPS_RETRACT_PL); +TRANS(UI_TEXT_OPS_BACKSLASH_PL); +TRANS(UI_TEXT_OPS_MINDIST_PL); +TRANS(UI_TEXT_OPS_MOVE_AFTER_PL); +TRANS(UI_TEXT_ANTI_OOZE_PL); +TRANS(UI_TEXT_PRINT_FILE_PL); +TRANS(UI_TEXT_PAUSE_PRINT_PL); +TRANS(UI_TEXT_CONTINUE_PRINT_PL); +TRANS(UI_TEXT_UNMOUNT_CARD_PL); +TRANS(UI_TEXT_MOUNT_CARD_PL); +TRANS(UI_TEXT_DELETE_FILE_PL); +TRANS(UI_TEXT_FEEDRATE_PL); +TRANS(UI_TEXT_FEED_MAX_X_PL); +TRANS(UI_TEXT_FEED_MAX_Y_PL); +TRANS(UI_TEXT_FEED_MAX_Z_PL); +TRANS(UI_TEXT_FEED_MAX_Z_DELTA_PL); +TRANS(UI_TEXT_FEED_HOME_X_PL); +TRANS(UI_TEXT_FEED_HOME_Y_PL); +TRANS(UI_TEXT_FEED_HOME_Z_PL); +TRANS(UI_TEXT_FEED_HOME_Z_DELTA_PL); +TRANS(UI_TEXT_ACTION_XPOSITION4A_PL); +TRANS(UI_TEXT_ACTION_XPOSITION4B_PL); +TRANS(UI_TEXT_ACTION_XPOSITION4C_PL); +TRANS(UI_TEXT_ACTION_XPOSITION4D_PL); +TRANS(UI_TEXT_ACTION_YPOSITION4A_PL); +TRANS(UI_TEXT_ACTION_YPOSITION4B_PL); +TRANS(UI_TEXT_ACTION_YPOSITION4C_PL); +TRANS(UI_TEXT_ACTION_YPOSITION4D_PL); +TRANS(UI_TEXT_ACTION_ZPOSITION4A_PL); +TRANS(UI_TEXT_ACTION_ZPOSITION4B_PL); +TRANS(UI_TEXT_ACTION_ZPOSITION4C_PL); +TRANS(UI_TEXT_ACTION_ZPOSITION4D_PL); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST4A_PL); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST4B_PL); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST4C_PL); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST4D_PL); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST4A_PL); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST4B_PL); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST4C_PL); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST4D_PL); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST4A_PL); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST4B_PL); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST4C_PL); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST4D_PL); +TRANS(UI_TEXT_ACTION_EPOSITION_FAST2A_PL); +TRANS(UI_TEXT_ACTION_EPOSITION_FAST2B_PL); +TRANS(UI_TEXT_ACTION_XPOSITION2A_PL); +TRANS(UI_TEXT_ACTION_XPOSITION2B_PL); +TRANS(UI_TEXT_ACTION_YPOSITION2A_PL); +TRANS(UI_TEXT_ACTION_YPOSITION2B_PL); +TRANS(UI_TEXT_ACTION_ZPOSITION2A_PL); +TRANS(UI_TEXT_ACTION_ZPOSITION2B_PL); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST2A_PL); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST2B_PL); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST2A_PL); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST2B_PL); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST2A_PL); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST2B_PL); +TRANS(UI_TEXT_FANSPEED_PL); +TRANS(UI_TEXT_ACTION_FANSPEED_PL); +TRANS(UI_TEXT_FAN_OFF_PL); +TRANS(UI_TEXT_FAN_25_PL); +TRANS(UI_TEXT_FAN_50_PL); +TRANS(UI_TEXT_FAN_75_PL); +TRANS(UI_TEXT_FAN_FULL_PL); +TRANS(UI_TEXT_STEPPER_INACTIVE_PL); +TRANS(UI_TEXT_STEPPER_INACTIVE2A_PL); +TRANS(UI_TEXT_STEPPER_INACTIVE2B_PL); +TRANS(UI_TEXT_POWER_INACTIVE_PL); +TRANS(UI_TEXT_POWER_INACTIVE2A_PL); +TRANS(UI_TEXT_POWER_INACTIVE2B_PL); +TRANS(UI_TEXT_GENERAL_PL); +TRANS(UI_TEXT_BAUDRATE_PL); +TRANS(UI_TEXT_EXTR_STEPS_PL); +TRANS(UI_TEXT_EXTR_START_FEED_PL); +TRANS(UI_TEXT_EXTR_MAX_FEED_PL); +TRANS(UI_TEXT_EXTR_ACCEL_PL); +TRANS(UI_TEXT_EXTR_WATCH_PL); +TRANS(UI_TEXT_EXTR_ADVANCE_L_PL); +TRANS(UI_TEXT_EXTR_ADVANCE_K_PL); +TRANS(UI_TEXT_EXTR_MANAGER_PL); +TRANS(UI_TEXT_EXTR_PGAIN_PL); +TRANS(UI_TEXT_EXTR_DEADTIME_PL); +TRANS(UI_TEXT_EXTR_DMAX_DT_PL); +TRANS(UI_TEXT_EXTR_IGAIN_PL); +TRANS(UI_TEXT_EXTR_DGAIN_PL); +TRANS(UI_TEXT_EXTR_DMIN_PL); +TRANS(UI_TEXT_EXTR_DMAX_PL); +TRANS(UI_TEXT_EXTR_PMAX_PL); +TRANS(UI_TEXT_EXTR_XOFF_PL); +TRANS(UI_TEXT_EXTR_YOFF_PL); +TRANS(UI_TEXT_STRING_HM_BANGBANG_PL); +TRANS(UI_TEXT_STRING_HM_PID_PL); +TRANS(UI_TEXT_STRING_ACTION_PL); +TRANS(UI_TEXT_HEATING_EXTRUDER_PL); +TRANS(UI_TEXT_HEATING_BED_PL); +TRANS(UI_TEXT_KILLED_PL); +TRANS(UI_TEXT_STEPPER_DISABLED_PL); +TRANS(UI_TEXT_EEPROM_STOREDA_PL); +TRANS(UI_TEXT_EEPROM_STOREDB_PL); +TRANS(UI_TEXT_EEPROM_LOADEDA_PL); +TRANS(UI_TEXT_EEPROM_LOADEDB_PL); +TRANS(UI_TEXT_UPLOADING_PL); +TRANS(UI_TEXT_PAGE_BUFFER_PL); +TRANS(UI_TEXT_PAGE_EXTRUDER_PL); +TRANS(UI_TEXT_PAGE_EXTRUDER1_PL); +TRANS(UI_TEXT_PAGE_EXTRUDER2_PL); +TRANS(UI_TEXT_PAGE_EXTRUDER3_PL); +TRANS(UI_TEXT_PAGE_BED_PL); +TRANS(UI_TEXT_SPEED_MULTIPLY_PL); +TRANS(UI_TEXT_FLOW_MULTIPLY_PL); +TRANS(UI_TEXT_SHOW_MEASUREMENT_PL); +TRANS(UI_TEXT_RESET_MEASUREMENT_PL); +TRANS(UI_TEXT_SET_MEASURED_ORIGIN_PL); +TRANS(UI_TEXT_ZCALIB_PL); +TRANS(UI_TEXT_SET_P1_PL); +TRANS(UI_TEXT_SET_P2_PL); +TRANS(UI_TEXT_SET_P3_PL); +TRANS(UI_TEXT_CALCULATE_LEVELING_PL); +TRANS(UI_TEXT_LEVEL_PL); +TRANS(UI_TEXT_EXTR_WAIT_RETRACT_TEMP_PL); +TRANS(UI_TEXT_EXTR_WAIT_RETRACT_UNITS_PL); +TRANS(UI_TEXT_SD_REMOVED_PL); +TRANS(UI_TEXT_SD_INSERTED_PL); +TRANS(UI_TEXT_PRINTER_READY_PL); +TRANS(UI_TEXT_PRINTTIME_DAYS_PL); +TRANS(UI_TEXT_PRINTTIME_HOURS_PL); +TRANS(UI_TEXT_PRINTTIME_MINUTES_PL); +TRANS(UI_TEXT_PRINT_TIME_PL); +TRANS(UI_TEXT_PRINT_FILAMENT_PL); +TRANS(UI_TEXT_PRINTED_PL); +TRANS(UI_TEXT_POWER_PL); +TRANS(UI_TEXT_STRING_HM_DEADTIME_PL); +TRANS(UI_TEXT_STRING_HM_SLOWBANG_PL); +TRANS(UI_TEXT_STOP_PRINT_PL); +TRANS(UI_TEXT_Z_BABYSTEPPING_PL); +TRANS(UI_TEXT_CHANGE_FILAMENT_PL); +TRANS(UI_TEXT_WIZ_CH_FILAMENT1_PL); +TRANS(UI_TEXT_WIZ_CH_FILAMENT2_PL); +TRANS(UI_TEXT_WIZ_CH_FILAMENT3_PL); +TRANS(UI_TEXT_CLICK_DONE_PL); +TRANS(UI_TEXT_AUTOLEVEL_ONOFF_PL); +TRANS(UI_TEXT_SERVOPOS_PL); +TRANS(UI_TEXT_IGNORE_M106_PL); +TRANS(UI_TEXT_WIZ_REHEAT1_PL); +TRANS(UI_TEXT_WIZ_REHEAT2_PL); +TRANS(UI_TEXT_WIZ_WAITTEMP1_PL); +TRANS(UI_TEXT_WIZ_WAITTEMP2_PL); +TRANS(UI_TEXT_EXTRUDER_JAM_PL); +TRANS(UI_TEXT_STANDBY_PL); +TRANS(UI_TEXT_BED_COATING_PL); +TRANS(UI_TEXT_BED_COATING_SET1_PL); +TRANS(UI_TEXT_BED_COATING_SET2_PL); +TRANS(UI_TEXT_NOCOATING_PL); +TRANS(UI_TEXT_BUILDTAK_PL); +TRANS(UI_TEXT_KAPTON_PL); +TRANS(UI_TEXT_BLUETAPE_PL); +TRANS(UI_TEXT_PETTAPE_PL); +TRANS(UI_TEXT_GLUESTICK_PL); +TRANS(UI_TEXT_CUSTOM_PL); +TRANS(UI_TEXT_COATING_CUSTOM_PL); +TRANS(UI_TEXT_LANGUAGE_PL); +TRANS(UI_TEXT_MAINPAGE6_1_PL); +TRANS(UI_TEXT_MAINPAGE6_2_PL); +TRANS(UI_TEXT_MAINPAGE6_3_PL); +TRANS(UI_TEXT_MAINPAGE6_4_PL); +TRANS(UI_TEXT_MAINPAGE6_5_PL); +TRANS(UI_TEXT_MAINPAGE6_6_PL); +TRANS(UI_TEXT_MAINPAGE_TEMP_BED_PL); +TRANS(UI_TEXT_MAINPAGE_BED_PL); +TRANS(UI_TEXT_MAINPAGE_Z_BUF_PL); +TRANS(UI_TEXT_MAINPAGE_MUL_EUSAGE_PL); +TRANS(UI_TEXT_MAINPAGE_XY_PL); +TRANS(UI_TEXT_PRINT_TIME_VALUE_PL); +TRANS(UI_TEXT_PRINT_FILAMENT_VALUE_PL); +TRANS(UI_TEXT_METER_PRINTED_PL); +TRANS(UI_TEXT_STATUS_PL); +TRANS(UI_TEXT_EMPTY_PL); +TRANS(UI_TEXT_TEMP_SET_PL); +TRANS(UI_TEXT_CURRENT_TEMP_PL); +TRANS(UI_TEXT_COATING_THICKNESS_PL); +TRANS(UI_TEXT_EXTR3_TEMP_PL); +TRANS(UI_TEXT_EXTR4_TEMP_PL); +TRANS(UI_TEXT_EXTR5_TEMP_PL); +TRANS(UI_TEXT_EXTR3_OFF_PL); +TRANS(UI_TEXT_EXTR4_OFF_PL); +TRANS(UI_TEXT_EXTR5_OFF_PL); +TRANS(UI_TEXT_EXTR3_SELECT_PL); +TRANS(UI_TEXT_EXTR4_SELECT_PL); +TRANS(UI_TEXT_EXTR5_SELECT_PL); +TRANS(UI_TEXT_DITTO_0_PL); +TRANS(UI_TEXT_DITTO_1_PL); +TRANS(UI_TEXT_DITTO_2_PL); +TRANS(UI_TEXT_DITTO_3_PL); +TRANS(UI_TEXT_ZPROBE_HEIGHT_PL); +TRANS(UI_TEXT_OFFSETS_PL); +TRANS(UI_TEXT_X_OFFSET_PL); +TRANS(UI_TEXT_Y_OFFSET_PL); +TRANS(UI_TEXT_Z_OFFSET_PL); + +PGM_P const translations_pl[NUM_TRANSLATED_WORDS] PROGMEM = { + FUI_TEXT_ON_PL, + FUI_TEXT_OFF_PL, + FUI_TEXT_NA_PL, + FUI_TEXT_YES_PL, + FUI_TEXT_NO_PL, + FUI_TEXT_PRINT_POS_PL, + FUI_TEXT_PRINTING_PL, + FUI_TEXT_IDLE_PL, + FUI_TEXT_NOSDCARD_PL, + FUI_TEXT_ERROR_PL, + FUI_TEXT_BACK_PL, + FUI_TEXT_QUICK_SETTINGS_PL, + FUI_TEXT_ERRORMSG_PL, + FUI_TEXT_CONFIGURATION_PL, + FUI_TEXT_POSITION_PL, + FUI_TEXT_EXTRUDER_PL, + FUI_TEXT_SD_CARD_PL, + FUI_TEXT_DEBUGGING_PL, + FUI_TEXT_HOME_DELTA_PL, + FUI_TEXT_HOME_ALL_PL, + FUI_TEXT_HOME_X_PL, + FUI_TEXT_HOME_Y_PL, + FUI_TEXT_HOME_Z_PL, + FUI_TEXT_PREHEAT_PLA_PL, + FUI_TEXT_PREHEAT_ABS_PL, + FUI_TEXT_LIGHTS_ONOFF_PL, + FUI_TEXT_COOLDOWN_PL, + FUI_TEXT_SET_TO_ORIGIN_PL, + FUI_TEXT_DISABLE_STEPPER_PL, + FUI_TEXT_X_POSITION_PL, + FUI_TEXT_X_POS_FAST_PL, + FUI_TEXT_Y_POSITION_PL, + FUI_TEXT_Y_POS_FAST_PL, + FUI_TEXT_Z_POSITION_PL, + FUI_TEXT_Z_POS_FAST_PL, + FUI_TEXT_E_POSITION_PL, + FUI_TEXT_BED_TEMP_PL, + FUI_TEXT_EXTR0_TEMP_PL, + FUI_TEXT_EXTR1_TEMP_PL, + FUI_TEXT_EXTR2_TEMP_PL, + FUI_TEXT_EXTR0_OFF_PL, + FUI_TEXT_EXTR1_OFF_PL, + FUI_TEXT_EXTR2_OFF_PL, + FUI_TEXT_EXTR0_SELECT_PL, + FUI_TEXT_EXTR1_SELECT_PL, + FUI_TEXT_EXTR2_SELECT_PL, + FUI_TEXT_EXTR_ORIGIN_PL, + FUI_TEXT_PRINT_X_PL, + FUI_TEXT_PRINT_Y_PL, + FUI_TEXT_PRINT_Z_PL, + FUI_TEXT_PRINT_Z_DELTA_PL, + FUI_TEXT_MOVE_X_PL, + FUI_TEXT_MOVE_Y_PL, + FUI_TEXT_MOVE_Z_PL, + FUI_TEXT_MOVE_Z_DELTA_PL, + FUI_TEXT_JERK_PL, + FUI_TEXT_ZJERK_PL, + FUI_TEXT_ACCELERATION_PL, + FUI_TEXT_STORE_TO_EEPROM_PL, + FUI_TEXT_LOAD_EEPROM_PL, + FUI_TEXT_DBG_ECHO_PL, + FUI_TEXT_DBG_INFO_PL, + FUI_TEXT_DBG_ERROR_PL, + FUI_TEXT_DBG_DRYRUN_PL, + FUI_TEXT_OPS_OFF_PL, + FUI_TEXT_OPS_CLASSIC_PL, + FUI_TEXT_OPS_FAST_PL, + FUI_TEXT_OPS_RETRACT_PL, + FUI_TEXT_OPS_BACKSLASH_PL, + FUI_TEXT_OPS_MINDIST_PL, + FUI_TEXT_OPS_MOVE_AFTER_PL, + FUI_TEXT_ANTI_OOZE_PL, + FUI_TEXT_PRINT_FILE_PL, + FUI_TEXT_PAUSE_PRINT_PL, + FUI_TEXT_CONTINUE_PRINT_PL, + FUI_TEXT_UNMOUNT_CARD_PL, + FUI_TEXT_MOUNT_CARD_PL, + FUI_TEXT_DELETE_FILE_PL, + FUI_TEXT_FEEDRATE_PL, + FUI_TEXT_FEED_MAX_X_PL, + FUI_TEXT_FEED_MAX_Y_PL, + FUI_TEXT_FEED_MAX_Z_PL, + FUI_TEXT_FEED_MAX_Z_DELTA_PL, + FUI_TEXT_FEED_HOME_X_PL, + FUI_TEXT_FEED_HOME_Y_PL, + FUI_TEXT_FEED_HOME_Z_PL, + FUI_TEXT_FEED_HOME_Z_DELTA_PL, + FUI_TEXT_ACTION_XPOSITION4A_PL, + FUI_TEXT_ACTION_XPOSITION4B_PL, + FUI_TEXT_ACTION_XPOSITION4C_PL, + FUI_TEXT_ACTION_XPOSITION4D_PL, + FUI_TEXT_ACTION_YPOSITION4A_PL, + FUI_TEXT_ACTION_YPOSITION4B_PL, + FUI_TEXT_ACTION_YPOSITION4C_PL, + FUI_TEXT_ACTION_YPOSITION4D_PL, + FUI_TEXT_ACTION_ZPOSITION4A_PL, + FUI_TEXT_ACTION_ZPOSITION4B_PL, + FUI_TEXT_ACTION_ZPOSITION4C_PL, + FUI_TEXT_ACTION_ZPOSITION4D_PL, + FUI_TEXT_ACTION_XPOSITION_FAST4A_PL, + FUI_TEXT_ACTION_XPOSITION_FAST4B_PL, + FUI_TEXT_ACTION_XPOSITION_FAST4C_PL, + FUI_TEXT_ACTION_XPOSITION_FAST4D_PL, + FUI_TEXT_ACTION_YPOSITION_FAST4A_PL, + FUI_TEXT_ACTION_YPOSITION_FAST4B_PL, + FUI_TEXT_ACTION_YPOSITION_FAST4C_PL, + FUI_TEXT_ACTION_YPOSITION_FAST4D_PL, + FUI_TEXT_ACTION_ZPOSITION_FAST4A_PL, + FUI_TEXT_ACTION_ZPOSITION_FAST4B_PL, + FUI_TEXT_ACTION_ZPOSITION_FAST4C_PL, + FUI_TEXT_ACTION_ZPOSITION_FAST4D_PL, + FUI_TEXT_ACTION_EPOSITION_FAST2A_PL, + FUI_TEXT_ACTION_EPOSITION_FAST2B_PL, + FUI_TEXT_ACTION_XPOSITION2A_PL, + FUI_TEXT_ACTION_XPOSITION2B_PL, + FUI_TEXT_ACTION_YPOSITION2A_PL, + FUI_TEXT_ACTION_YPOSITION2B_PL, + FUI_TEXT_ACTION_ZPOSITION2A_PL, + FUI_TEXT_ACTION_ZPOSITION2B_PL, + FUI_TEXT_ACTION_XPOSITION_FAST2A_PL, + FUI_TEXT_ACTION_XPOSITION_FAST2B_PL, + FUI_TEXT_ACTION_YPOSITION_FAST2A_PL, + FUI_TEXT_ACTION_YPOSITION_FAST2B_PL, + FUI_TEXT_ACTION_ZPOSITION_FAST2A_PL, + FUI_TEXT_ACTION_ZPOSITION_FAST2B_PL, + FUI_TEXT_FANSPEED_PL, + FUI_TEXT_ACTION_FANSPEED_PL, + FUI_TEXT_FAN_OFF_PL, + FUI_TEXT_FAN_25_PL, + FUI_TEXT_FAN_50_PL, + FUI_TEXT_FAN_75_PL, + FUI_TEXT_FAN_FULL_PL, + FUI_TEXT_STEPPER_INACTIVE_PL, + FUI_TEXT_STEPPER_INACTIVE2A_PL, + FUI_TEXT_STEPPER_INACTIVE2B_PL, + FUI_TEXT_POWER_INACTIVE_PL, + FUI_TEXT_POWER_INACTIVE2A_PL, + FUI_TEXT_POWER_INACTIVE2B_PL, + FUI_TEXT_GENERAL_PL, + FUI_TEXT_BAUDRATE_PL, + FUI_TEXT_EXTR_STEPS_PL, + FUI_TEXT_EXTR_START_FEED_PL, + FUI_TEXT_EXTR_MAX_FEED_PL, + FUI_TEXT_EXTR_ACCEL_PL, + FUI_TEXT_EXTR_WATCH_PL, + FUI_TEXT_EXTR_ADVANCE_L_PL, + FUI_TEXT_EXTR_ADVANCE_K_PL, + FUI_TEXT_EXTR_MANAGER_PL, + FUI_TEXT_EXTR_PGAIN_PL, + FUI_TEXT_EXTR_DEADTIME_PL, + FUI_TEXT_EXTR_DMAX_DT_PL, + FUI_TEXT_EXTR_IGAIN_PL, + FUI_TEXT_EXTR_DGAIN_PL, + FUI_TEXT_EXTR_DMIN_PL, + FUI_TEXT_EXTR_DMAX_PL, + FUI_TEXT_EXTR_PMAX_PL, + FUI_TEXT_EXTR_XOFF_PL, + FUI_TEXT_EXTR_YOFF_PL, + FUI_TEXT_STRING_HM_BANGBANG_PL, + FUI_TEXT_STRING_HM_PID_PL, + FUI_TEXT_STRING_ACTION_PL, + FUI_TEXT_HEATING_EXTRUDER_PL, + FUI_TEXT_HEATING_BED_PL, + FUI_TEXT_KILLED_PL, + FUI_TEXT_STEPPER_DISABLED_PL, + FUI_TEXT_EEPROM_STOREDA_PL, + FUI_TEXT_EEPROM_STOREDB_PL, + FUI_TEXT_EEPROM_LOADEDA_PL, + FUI_TEXT_EEPROM_LOADEDB_PL, + FUI_TEXT_UPLOADING_PL, + FUI_TEXT_PAGE_BUFFER_PL, + FUI_TEXT_PAGE_EXTRUDER_PL, + FUI_TEXT_PAGE_EXTRUDER1_PL, + FUI_TEXT_PAGE_EXTRUDER2_PL, + FUI_TEXT_PAGE_EXTRUDER3_PL, + FUI_TEXT_PAGE_BED_PL, + FUI_TEXT_SPEED_MULTIPLY_PL, + FUI_TEXT_FLOW_MULTIPLY_PL, + FUI_TEXT_SHOW_MEASUREMENT_PL, + FUI_TEXT_RESET_MEASUREMENT_PL, + FUI_TEXT_SET_MEASURED_ORIGIN_PL, + FUI_TEXT_ZCALIB_PL, + FUI_TEXT_SET_P1_PL, + FUI_TEXT_SET_P2_PL, + FUI_TEXT_SET_P3_PL, + FUI_TEXT_CALCULATE_LEVELING_PL, + FUI_TEXT_LEVEL_PL, + FUI_TEXT_EXTR_WAIT_RETRACT_TEMP_PL, + FUI_TEXT_EXTR_WAIT_RETRACT_UNITS_PL, + FUI_TEXT_SD_REMOVED_PL, + FUI_TEXT_SD_INSERTED_PL, + FUI_TEXT_PRINTER_READY_PL, + FUI_TEXT_PRINTTIME_DAYS_PL, + FUI_TEXT_PRINTTIME_HOURS_PL, + FUI_TEXT_PRINTTIME_MINUTES_PL, + FUI_TEXT_PRINT_TIME_PL, + FUI_TEXT_PRINT_FILAMENT_PL, + FUI_TEXT_PRINTED_PL, + FUI_TEXT_POWER_PL, + FUI_TEXT_STRING_HM_DEADTIME_PL, + FUI_TEXT_STRING_HM_SLOWBANG_PL, + FUI_TEXT_STOP_PRINT_PL, + FUI_TEXT_Z_BABYSTEPPING_PL, + FUI_TEXT_CHANGE_FILAMENT_PL, + FUI_TEXT_WIZ_CH_FILAMENT1_PL, + FUI_TEXT_WIZ_CH_FILAMENT2_PL, + FUI_TEXT_WIZ_CH_FILAMENT3_PL, + FUI_TEXT_CLICK_DONE_PL, + FUI_TEXT_AUTOLEVEL_ONOFF_PL, + FUI_TEXT_SERVOPOS_PL, + FUI_TEXT_IGNORE_M106_PL, + FUI_TEXT_WIZ_REHEAT1_PL, + FUI_TEXT_WIZ_REHEAT2_PL, + FUI_TEXT_WIZ_WAITTEMP1_PL, + FUI_TEXT_WIZ_WAITTEMP2_PL, + FUI_TEXT_EXTRUDER_JAM_PL, + FUI_TEXT_STANDBY_PL, + FUI_TEXT_BED_COATING_PL, + FUI_TEXT_BED_COATING_SET1_PL, + FUI_TEXT_BED_COATING_SET2_PL, + FUI_TEXT_NOCOATING_PL, + FUI_TEXT_BUILDTAK_PL, + FUI_TEXT_KAPTON_PL, + FUI_TEXT_BLUETAPE_PL, + FUI_TEXT_PETTAPE_PL, + FUI_TEXT_GLUESTICK_PL, + FUI_TEXT_CUSTOM_PL, + FUI_TEXT_COATING_CUSTOM_PL, + FUI_TEXT_LANGUAGE_PL, + FUI_TEXT_MAINPAGE6_1_PL, + FUI_TEXT_MAINPAGE6_2_PL, + FUI_TEXT_MAINPAGE6_3_PL, + FUI_TEXT_MAINPAGE6_4_PL, + FUI_TEXT_MAINPAGE6_5_PL, + FUI_TEXT_MAINPAGE6_6_PL, + FUI_TEXT_MAINPAGE_TEMP_BED_PL, + FUI_TEXT_MAINPAGE_BED_PL, + FUI_TEXT_MAINPAGE_Z_BUF_PL, + FUI_TEXT_MAINPAGE_MUL_EUSAGE_PL, + FUI_TEXT_MAINPAGE_XY_PL, + FUI_TEXT_PRINT_TIME_VALUE_PL, + FUI_TEXT_PRINT_FILAMENT_VALUE_PL, + FUI_TEXT_METER_PRINTED_PL, + FUI_TEXT_STATUS_PL, + FUI_TEXT_EMPTY_PL, + FUI_TEXT_TEMP_SET_PL, + FUI_TEXT_CURRENT_TEMP_PL, + FUI_TEXT_COATING_THICKNESS_PL, + FUI_TEXT_EXTR3_TEMP_PL, + FUI_TEXT_EXTR4_TEMP_PL, + FUI_TEXT_EXTR5_TEMP_PL, + FUI_TEXT_EXTR3_OFF_PL, + FUI_TEXT_EXTR4_OFF_PL, + FUI_TEXT_EXTR5_OFF_PL, + FUI_TEXT_EXTR3_SELECT_PL, + FUI_TEXT_EXTR4_SELECT_PL, + FUI_TEXT_EXTR5_SELECT_PL, + FUI_TEXT_DITTO_0_PL, + FUI_TEXT_DITTO_1_PL, + FUI_TEXT_DITTO_2_PL, + FUI_TEXT_DITTO_3_PL, + FUI_TEXT_ZPROBE_HEIGHT_PL, + FUI_TEXT_OFFSETS_PL, + FUI_TEXT_X_OFFSET_PL, + FUI_TEXT_Y_OFFSET_PL, + FUI_TEXT_Z_OFFSET_PL, + FUI_TEXT_DBG_ENDSTOP_PL +}; +#define LANG_PL_TABLE translations_pl +#else +#define LANG_PL_TABLE NULL +#endif // LANGUAGE_PL_ACTIVE + +#if LANGUAGE_TR_ACTIVE +TRANS(UI_TEXT_ON_TR); +TRANS(UI_TEXT_OFF_TR); +TRANS(UI_TEXT_NA_TR); +TRANS(UI_TEXT_YES_TR); +TRANS(UI_TEXT_NO_TR); +TRANS(UI_TEXT_PRINT_POS_TR); +TRANS(UI_TEXT_PRINTING_TR); +TRANS(UI_TEXT_IDLE_TR); +TRANS(UI_TEXT_NOSDCARD_TR); +TRANS(UI_TEXT_ERROR_TR); +TRANS(UI_TEXT_BACK_TR); +TRANS(UI_TEXT_QUICK_SETTINGS_TR); +TRANS(UI_TEXT_ERRORMSG_TR); +TRANS(UI_TEXT_CONFIGURATION_TR); +TRANS(UI_TEXT_POSITION_TR); +TRANS(UI_TEXT_EXTRUDER_TR); +TRANS(UI_TEXT_SD_CARD_TR); +TRANS(UI_TEXT_DEBUGGING_TR); +TRANS(UI_TEXT_HOME_DELTA_TR); +TRANS(UI_TEXT_HOME_ALL_TR); +TRANS(UI_TEXT_HOME_X_TR); +TRANS(UI_TEXT_HOME_Y_TR); +TRANS(UI_TEXT_HOME_Z_TR); +TRANS(UI_TEXT_PREHEAT_PLA_TR); +TRANS(UI_TEXT_PREHEAT_ABS_TR); +TRANS(UI_TEXT_LIGHTS_ONOFF_TR); +TRANS(UI_TEXT_COOLDOWN_TR); +TRANS(UI_TEXT_SET_TO_ORIGIN_TR); +TRANS(UI_TEXT_DISABLE_STEPPER_TR); +TRANS(UI_TEXT_X_POSITION_TR); +TRANS(UI_TEXT_X_POS_FAST_TR); +TRANS(UI_TEXT_Y_POSITION_TR); +TRANS(UI_TEXT_Y_POS_FAST_TR); +TRANS(UI_TEXT_Z_POSITION_TR); +TRANS(UI_TEXT_Z_POS_FAST_TR); +TRANS(UI_TEXT_E_POSITION_TR); +TRANS(UI_TEXT_BED_TEMP_TR); +TRANS(UI_TEXT_EXTR0_TEMP_TR); +TRANS(UI_TEXT_EXTR1_TEMP_TR); +TRANS(UI_TEXT_EXTR2_TEMP_TR); +TRANS(UI_TEXT_EXTR0_OFF_TR); +TRANS(UI_TEXT_EXTR1_OFF_TR); +TRANS(UI_TEXT_EXTR2_OFF_TR); +TRANS(UI_TEXT_EXTR0_SELECT_TR); +TRANS(UI_TEXT_EXTR1_SELECT_TR); +TRANS(UI_TEXT_EXTR2_SELECT_TR); +TRANS(UI_TEXT_EXTR_ORIGIN_TR); +TRANS(UI_TEXT_PRINT_X_TR); +TRANS(UI_TEXT_PRINT_Y_TR); +TRANS(UI_TEXT_PRINT_Z_TR); +TRANS(UI_TEXT_PRINT_Z_DELTA_TR); +TRANS(UI_TEXT_MOVE_X_TR); +TRANS(UI_TEXT_MOVE_Y_TR); +TRANS(UI_TEXT_MOVE_Z_TR); +TRANS(UI_TEXT_MOVE_Z_DELTA_TR); +TRANS(UI_TEXT_JERK_TR); +TRANS(UI_TEXT_ZJERK_TR); +TRANS(UI_TEXT_ACCELERATION_TR); +TRANS(UI_TEXT_STORE_TO_EEPROM_TR); +TRANS(UI_TEXT_LOAD_EEPROM_TR); +TRANS(UI_TEXT_DBG_ECHO_TR); +TRANS(UI_TEXT_DBG_INFO_TR); +TRANS(UI_TEXT_DBG_ERROR_TR); +TRANS(UI_TEXT_DBG_DRYRUN_TR); +TRANS(UI_TEXT_DBG_ENDSTOP_TR); +TRANS(UI_TEXT_OPS_OFF_TR); +TRANS(UI_TEXT_OPS_CLASSIC_TR); +TRANS(UI_TEXT_OPS_FAST_TR); +TRANS(UI_TEXT_OPS_RETRACT_TR); +TRANS(UI_TEXT_OPS_BACKSLASH_TR); +TRANS(UI_TEXT_OPS_MINDIST_TR); +TRANS(UI_TEXT_OPS_MOVE_AFTER_TR); +TRANS(UI_TEXT_ANTI_OOZE_TR); +TRANS(UI_TEXT_PRINT_FILE_TR); +TRANS(UI_TEXT_PAUSE_PRINT_TR); +TRANS(UI_TEXT_CONTINUE_PRINT_TR); +TRANS(UI_TEXT_UNMOUNT_CARD_TR); +TRANS(UI_TEXT_MOUNT_CARD_TR); +TRANS(UI_TEXT_DELETE_FILE_TR); +TRANS(UI_TEXT_FEEDRATE_TR); +TRANS(UI_TEXT_FEED_MAX_X_TR); +TRANS(UI_TEXT_FEED_MAX_Y_TR); +TRANS(UI_TEXT_FEED_MAX_Z_TR); +TRANS(UI_TEXT_FEED_MAX_Z_DELTA_TR); +TRANS(UI_TEXT_FEED_HOME_X_TR); +TRANS(UI_TEXT_FEED_HOME_Y_TR); +TRANS(UI_TEXT_FEED_HOME_Z_TR); +TRANS(UI_TEXT_FEED_HOME_Z_DELTA_TR); +TRANS(UI_TEXT_ACTION_XPOSITION4A_TR); +TRANS(UI_TEXT_ACTION_XPOSITION4B_TR); +TRANS(UI_TEXT_ACTION_XPOSITION4C_TR); +TRANS(UI_TEXT_ACTION_XPOSITION4D_TR); +TRANS(UI_TEXT_ACTION_YPOSITION4A_TR); +TRANS(UI_TEXT_ACTION_YPOSITION4B_TR); +TRANS(UI_TEXT_ACTION_YPOSITION4C_TR); +TRANS(UI_TEXT_ACTION_YPOSITION4D_TR); +TRANS(UI_TEXT_ACTION_ZPOSITION4A_TR); +TRANS(UI_TEXT_ACTION_ZPOSITION4B_TR); +TRANS(UI_TEXT_ACTION_ZPOSITION4C_TR); +TRANS(UI_TEXT_ACTION_ZPOSITION4D_TR); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST4A_TR); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST4B_TR); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST4C_TR); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST4D_TR); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST4A_TR); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST4B_TR); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST4C_TR); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST4D_TR); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST4A_TR); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST4B_TR); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST4C_TR); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST4D_TR); +TRANS(UI_TEXT_ACTION_EPOSITION_FAST2A_TR); +TRANS(UI_TEXT_ACTION_EPOSITION_FAST2B_TR); +TRANS(UI_TEXT_ACTION_XPOSITION2A_TR); +TRANS(UI_TEXT_ACTION_XPOSITION2B_TR); +TRANS(UI_TEXT_ACTION_YPOSITION2A_TR); +TRANS(UI_TEXT_ACTION_YPOSITION2B_TR); +TRANS(UI_TEXT_ACTION_ZPOSITION2A_TR); +TRANS(UI_TEXT_ACTION_ZPOSITION2B_TR); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST2A_TR); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST2B_TR); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST2A_TR); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST2B_TR); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST2A_TR); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST2B_TR); +TRANS(UI_TEXT_FANSPEED_TR); +TRANS(UI_TEXT_ACTION_FANSPEED_TR); +TRANS(UI_TEXT_FAN_OFF_TR); +TRANS(UI_TEXT_FAN_25_TR); +TRANS(UI_TEXT_FAN_50_TR); +TRANS(UI_TEXT_FAN_75_TR); +TRANS(UI_TEXT_FAN_FULL_TR); +TRANS(UI_TEXT_STEPPER_INACTIVE_TR); +TRANS(UI_TEXT_STEPPER_INACTIVE2A_TR); +TRANS(UI_TEXT_STEPPER_INACTIVE2B_TR); +TRANS(UI_TEXT_POWER_INACTIVE_TR); +TRANS(UI_TEXT_POWER_INACTIVE2A_TR); +TRANS(UI_TEXT_POWER_INACTIVE2B_TR); +TRANS(UI_TEXT_GENERAL_TR); +TRANS(UI_TEXT_BAUDRATE_TR); +TRANS(UI_TEXT_EXTR_STEPS_TR); +TRANS(UI_TEXT_EXTR_START_FEED_TR); +TRANS(UI_TEXT_EXTR_MAX_FEED_TR); +TRANS(UI_TEXT_EXTR_ACCEL_TR); +TRANS(UI_TEXT_EXTR_WATCH_TR); +TRANS(UI_TEXT_EXTR_ADVANCE_L_TR); +TRANS(UI_TEXT_EXTR_ADVANCE_K_TR); +TRANS(UI_TEXT_EXTR_MANAGER_TR); +TRANS(UI_TEXT_EXTR_PGAIN_TR); +TRANS(UI_TEXT_EXTR_DEADTIME_TR); +TRANS(UI_TEXT_EXTR_DMAX_DT_TR); +TRANS(UI_TEXT_EXTR_IGAIN_TR); +TRANS(UI_TEXT_EXTR_DGAIN_TR); +TRANS(UI_TEXT_EXTR_DMIN_TR); +TRANS(UI_TEXT_EXTR_DMAX_TR); +TRANS(UI_TEXT_EXTR_PMAX_TR); +TRANS(UI_TEXT_EXTR_XOFF_TR); +TRANS(UI_TEXT_EXTR_YOFF_TR); +TRANS(UI_TEXT_STRING_HM_BANGBANG_TR); +TRANS(UI_TEXT_STRING_HM_PID_TR); +TRANS(UI_TEXT_STRING_ACTION_TR); +TRANS(UI_TEXT_HEATING_EXTRUDER_TR); +TRANS(UI_TEXT_HEATING_BED_TR); +TRANS(UI_TEXT_KILLED_TR); +TRANS(UI_TEXT_STEPPER_DISABLED_TR); +TRANS(UI_TEXT_EEPROM_STOREDA_TR); +TRANS(UI_TEXT_EEPROM_STOREDB_TR); +TRANS(UI_TEXT_EEPROM_LOADEDA_TR); +TRANS(UI_TEXT_EEPROM_LOADEDB_TR); +TRANS(UI_TEXT_UPLOADING_TR); +TRANS(UI_TEXT_PAGE_BUFFER_TR); +TRANS(UI_TEXT_PAGE_EXTRUDER_TR); +TRANS(UI_TEXT_PAGE_EXTRUDER1_TR); +TRANS(UI_TEXT_PAGE_EXTRUDER2_TR); +TRANS(UI_TEXT_PAGE_EXTRUDER3_TR); +TRANS(UI_TEXT_PAGE_BED_TR); +TRANS(UI_TEXT_SPEED_MULTIPLY_TR); +TRANS(UI_TEXT_FLOW_MULTIPLY_TR); +TRANS(UI_TEXT_SHOW_MEASUREMENT_TR); +TRANS(UI_TEXT_RESET_MEASUREMENT_TR); +TRANS(UI_TEXT_SET_MEASURED_ORIGIN_TR); +TRANS(UI_TEXT_ZCALIB_TR); +TRANS(UI_TEXT_SET_P1_TR); +TRANS(UI_TEXT_SET_P2_TR); +TRANS(UI_TEXT_SET_P3_TR); +TRANS(UI_TEXT_CALCULATE_LEVELING_TR); +TRANS(UI_TEXT_LEVEL_TR); +TRANS(UI_TEXT_EXTR_WAIT_RETRACT_TEMP_TR); +TRANS(UI_TEXT_EXTR_WAIT_RETRACT_UNITS_TR); +TRANS(UI_TEXT_SD_REMOVED_TR); +TRANS(UI_TEXT_SD_INSERTED_TR); +TRANS(UI_TEXT_PRINTER_READY_TR); +TRANS(UI_TEXT_PRINTTIME_DAYS_TR); +TRANS(UI_TEXT_PRINTTIME_HOURS_TR); +TRANS(UI_TEXT_PRINTTIME_MINUTES_TR); +TRANS(UI_TEXT_PRINT_TIME_TR); +TRANS(UI_TEXT_PRINT_FILAMENT_TR); +TRANS(UI_TEXT_PRINTED_TR); +TRANS(UI_TEXT_POWER_TR); +TRANS(UI_TEXT_STRING_HM_DEADTIME_TR); +TRANS(UI_TEXT_STRING_HM_SLOWBANG_TR); +TRANS(UI_TEXT_STOP_PRINT_TR); +TRANS(UI_TEXT_Z_BABYSTEPPING_TR); +TRANS(UI_TEXT_CHANGE_FILAMENT_TR); +TRANS(UI_TEXT_WIZ_CH_FILAMENT1_TR); +TRANS(UI_TEXT_WIZ_CH_FILAMENT2_TR); +TRANS(UI_TEXT_WIZ_CH_FILAMENT3_TR); +TRANS(UI_TEXT_CLICK_DONE_TR); +TRANS(UI_TEXT_AUTOLEVEL_ONOFF_TR); +TRANS(UI_TEXT_SERVOPOS_TR); +TRANS(UI_TEXT_IGNORE_M106_TR); +TRANS(UI_TEXT_WIZ_REHEAT1_TR); +TRANS(UI_TEXT_WIZ_REHEAT2_TR); +TRANS(UI_TEXT_WIZ_WAITTEMP1_TR); +TRANS(UI_TEXT_WIZ_WAITTEMP2_TR); +TRANS(UI_TEXT_EXTRUDER_JAM_TR); +TRANS(UI_TEXT_STANDBY_TR); +TRANS(UI_TEXT_BED_COATING_TR); +TRANS(UI_TEXT_BED_COATING_SET1_TR); +TRANS(UI_TEXT_BED_COATING_SET2_TR); +TRANS(UI_TEXT_NOCOATING_TR); +TRANS(UI_TEXT_BUILDTAK_TR); +TRANS(UI_TEXT_KAPTON_TR); +TRANS(UI_TEXT_BLUETAPE_TR); +TRANS(UI_TEXT_PETTAPE_TR); +TRANS(UI_TEXT_GLUESTICK_TR); +TRANS(UI_TEXT_CUSTOM_TR); +TRANS(UI_TEXT_COATING_CUSTOM_TR); +TRANS(UI_TEXT_LANGUAGE_TR); +TRANS(UI_TEXT_MAINPAGE6_1_TR); +TRANS(UI_TEXT_MAINPAGE6_2_TR); +TRANS(UI_TEXT_MAINPAGE6_3_TR); +TRANS(UI_TEXT_MAINPAGE6_4_TR); +TRANS(UI_TEXT_MAINPAGE6_5_TR); +TRANS(UI_TEXT_MAINPAGE6_6_TR); +TRANS(UI_TEXT_MAINPAGE_TEMP_BED_TR); +TRANS(UI_TEXT_MAINPAGE_BED_TR); +TRANS(UI_TEXT_MAINPAGE_Z_BUF_TR); +TRANS(UI_TEXT_MAINPAGE_MUL_EUSAGE_TR); +TRANS(UI_TEXT_MAINPAGE_XY_TR); +TRANS(UI_TEXT_PRINT_TIME_VALUE_TR); +TRANS(UI_TEXT_PRINT_FILAMENT_VALUE_TR); +TRANS(UI_TEXT_METER_PRINTED_TR); +TRANS(UI_TEXT_STATUS_TR); +TRANS(UI_TEXT_EMPTY_TR); +TRANS(UI_TEXT_TEMP_SET_TR); +TRANS(UI_TEXT_CURRENT_TEMP_TR); +TRANS(UI_TEXT_COATING_THICKNESS_TR); +TRANS(UI_TEXT_EXTR3_TEMP_TR); +TRANS(UI_TEXT_EXTR4_TEMP_TR); +TRANS(UI_TEXT_EXTR5_TEMP_TR); +TRANS(UI_TEXT_EXTR3_OFF_TR); +TRANS(UI_TEXT_EXTR4_OFF_TR); +TRANS(UI_TEXT_EXTR5_OFF_TR); +TRANS(UI_TEXT_EXTR3_SELECT_TR); +TRANS(UI_TEXT_EXTR4_SELECT_TR); +TRANS(UI_TEXT_EXTR5_SELECT_TR); +TRANS(UI_TEXT_DITTO_0_TR); +TRANS(UI_TEXT_DITTO_1_TR); +TRANS(UI_TEXT_DITTO_2_TR); +TRANS(UI_TEXT_DITTO_3_TR); +TRANS(UI_TEXT_ZPROBE_HEIGHT_TR); +TRANS(UI_TEXT_OFFSETS_TR); +TRANS(UI_TEXT_X_OFFSET_TR); +TRANS(UI_TEXT_Y_OFFSET_TR); +TRANS(UI_TEXT_Z_OFFSET_TR); + + +PGM_P const translations_TR[NUM_TRANSLATED_WORDS] PROGMEM = { + FUI_TEXT_ON_TR, + FUI_TEXT_OFF_TR, + FUI_TEXT_NA_TR, + FUI_TEXT_YES_TR, + FUI_TEXT_NO_TR, + FUI_TEXT_PRINT_POS_TR, + FUI_TEXT_PRINTING_TR, + FUI_TEXT_IDLE_TR, + FUI_TEXT_NOSDCARD_TR, + FUI_TEXT_ERROR_TR, + FUI_TEXT_BACK_TR, + FUI_TEXT_QUICK_SETTINGS_TR, + FUI_TEXT_ERRORMSG_TR, + FUI_TEXT_CONFIGURATION_TR, + FUI_TEXT_POSITION_TR, + FUI_TEXT_EXTRUDER_TR, + FUI_TEXT_SD_CARD_TR, + FUI_TEXT_DEBUGGING_TR, + FUI_TEXT_HOME_DELTA_TR, + FUI_TEXT_HOME_ALL_TR, + FUI_TEXT_HOME_X_TR, + FUI_TEXT_HOME_Y_TR, + FUI_TEXT_HOME_Z_TR, + FUI_TEXT_PREHEAT_PLA_TR, + FUI_TEXT_PREHEAT_ABS_TR, + FUI_TEXT_LIGHTS_ONOFF_TR, + FUI_TEXT_COOLDOWN_TR, + FUI_TEXT_SET_TO_ORIGIN_TR, + FUI_TEXT_DISABLE_STEPPER_TR, + FUI_TEXT_X_POSITION_TR, + FUI_TEXT_X_POS_FAST_TR, + FUI_TEXT_Y_POSITION_TR, + FUI_TEXT_Y_POS_FAST_TR, + FUI_TEXT_Z_POSITION_TR, + FUI_TEXT_Z_POS_FAST_TR, + FUI_TEXT_E_POSITION_TR, + FUI_TEXT_BED_TEMP_TR, + FUI_TEXT_EXTR0_TEMP_TR, + FUI_TEXT_EXTR1_TEMP_TR, + FUI_TEXT_EXTR2_TEMP_TR, + FUI_TEXT_EXTR0_OFF_TR, + FUI_TEXT_EXTR1_OFF_TR, + FUI_TEXT_EXTR2_OFF_TR, + FUI_TEXT_EXTR0_SELECT_TR, + FUI_TEXT_EXTR1_SELECT_TR, + FUI_TEXT_EXTR2_SELECT_TR, + FUI_TEXT_EXTR_ORIGIN_TR, + FUI_TEXT_PRINT_X_TR, + FUI_TEXT_PRINT_Y_TR, + FUI_TEXT_PRINT_Z_TR, + FUI_TEXT_PRINT_Z_DELTA_TR, + FUI_TEXT_MOVE_X_TR, + FUI_TEXT_MOVE_Y_TR, + FUI_TEXT_MOVE_Z_TR, + FUI_TEXT_MOVE_Z_DELTA_TR, + FUI_TEXT_JERK_TR, + FUI_TEXT_ZJERK_TR, + FUI_TEXT_ACCELERATION_TR, + FUI_TEXT_STORE_TO_EEPROM_TR, + FUI_TEXT_LOAD_EEPROM_TR, + FUI_TEXT_DBG_ECHO_TR, + FUI_TEXT_DBG_INFO_TR, + FUI_TEXT_DBG_ERROR_TR, + FUI_TEXT_DBG_DRYRUN_TR, + FUI_TEXT_OPS_OFF_TR, + FUI_TEXT_OPS_CLASSIC_TR, + FUI_TEXT_OPS_FAST_TR, + FUI_TEXT_OPS_RETRACT_TR, + FUI_TEXT_OPS_BACKSLASH_TR, + FUI_TEXT_OPS_MINDIST_TR, + FUI_TEXT_OPS_MOVE_AFTER_TR, + FUI_TEXT_ANTI_OOZE_TR, + FUI_TEXT_PRINT_FILE_TR, + FUI_TEXT_PAUSE_PRINT_TR, + FUI_TEXT_CONTINUE_PRINT_TR, + FUI_TEXT_UNMOUNT_CARD_TR, + FUI_TEXT_MOUNT_CARD_TR, + FUI_TEXT_DELETE_FILE_TR, + FUI_TEXT_FEEDRATE_TR, + FUI_TEXT_FEED_MAX_X_TR, + FUI_TEXT_FEED_MAX_Y_TR, + FUI_TEXT_FEED_MAX_Z_TR, + FUI_TEXT_FEED_MAX_Z_DELTA_TR, + FUI_TEXT_FEED_HOME_X_TR, + FUI_TEXT_FEED_HOME_Y_TR, + FUI_TEXT_FEED_HOME_Z_TR, + FUI_TEXT_FEED_HOME_Z_DELTA_TR, + FUI_TEXT_ACTION_XPOSITION4A_TR, + FUI_TEXT_ACTION_XPOSITION4B_TR, + FUI_TEXT_ACTION_XPOSITION4C_TR, + FUI_TEXT_ACTION_XPOSITION4D_TR, + FUI_TEXT_ACTION_YPOSITION4A_TR, + FUI_TEXT_ACTION_YPOSITION4B_TR, + FUI_TEXT_ACTION_YPOSITION4C_TR, + FUI_TEXT_ACTION_YPOSITION4D_TR, + FUI_TEXT_ACTION_ZPOSITION4A_TR, + FUI_TEXT_ACTION_ZPOSITION4B_TR, + FUI_TEXT_ACTION_ZPOSITION4C_TR, + FUI_TEXT_ACTION_ZPOSITION4D_TR, + FUI_TEXT_ACTION_XPOSITION_FAST4A_TR, + FUI_TEXT_ACTION_XPOSITION_FAST4B_TR, + FUI_TEXT_ACTION_XPOSITION_FAST4C_TR, + FUI_TEXT_ACTION_XPOSITION_FAST4D_TR, + FUI_TEXT_ACTION_YPOSITION_FAST4A_TR, + FUI_TEXT_ACTION_YPOSITION_FAST4B_TR, + FUI_TEXT_ACTION_YPOSITION_FAST4C_TR, + FUI_TEXT_ACTION_YPOSITION_FAST4D_TR, + FUI_TEXT_ACTION_ZPOSITION_FAST4A_TR, + FUI_TEXT_ACTION_ZPOSITION_FAST4B_TR, + FUI_TEXT_ACTION_ZPOSITION_FAST4C_TR, + FUI_TEXT_ACTION_ZPOSITION_FAST4D_TR, + FUI_TEXT_ACTION_EPOSITION_FAST2A_TR, + FUI_TEXT_ACTION_EPOSITION_FAST2B_TR, + FUI_TEXT_ACTION_XPOSITION2A_TR, + FUI_TEXT_ACTION_XPOSITION2B_TR, + FUI_TEXT_ACTION_YPOSITION2A_TR, + FUI_TEXT_ACTION_YPOSITION2B_TR, + FUI_TEXT_ACTION_ZPOSITION2A_TR, + FUI_TEXT_ACTION_ZPOSITION2B_TR, + FUI_TEXT_ACTION_XPOSITION_FAST2A_TR, + FUI_TEXT_ACTION_XPOSITION_FAST2B_TR, + FUI_TEXT_ACTION_YPOSITION_FAST2A_TR, + FUI_TEXT_ACTION_YPOSITION_FAST2B_TR, + FUI_TEXT_ACTION_ZPOSITION_FAST2A_TR, + FUI_TEXT_ACTION_ZPOSITION_FAST2B_TR, + FUI_TEXT_FANSPEED_TR, + FUI_TEXT_ACTION_FANSPEED_TR, + FUI_TEXT_FAN_OFF_TR, + FUI_TEXT_FAN_25_TR, + FUI_TEXT_FAN_50_TR, + FUI_TEXT_FAN_75_TR, + FUI_TEXT_FAN_FULL_TR, + FUI_TEXT_STEPPER_INACTIVE_TR, + FUI_TEXT_STEPPER_INACTIVE2A_TR, + FUI_TEXT_STEPPER_INACTIVE2B_TR, + FUI_TEXT_POWER_INACTIVE_TR, + FUI_TEXT_POWER_INACTIVE2A_TR, + FUI_TEXT_POWER_INACTIVE2B_TR, + FUI_TEXT_GENERAL_TR, + FUI_TEXT_BAUDRATE_TR, + FUI_TEXT_EXTR_STEPS_TR, + FUI_TEXT_EXTR_START_FEED_TR, + FUI_TEXT_EXTR_MAX_FEED_TR, + FUI_TEXT_EXTR_ACCEL_TR, + FUI_TEXT_EXTR_WATCH_TR, + FUI_TEXT_EXTR_ADVANCE_L_TR, + FUI_TEXT_EXTR_ADVANCE_K_TR, + FUI_TEXT_EXTR_MANAGER_TR, + FUI_TEXT_EXTR_PGAIN_TR, + FUI_TEXT_EXTR_DEADTIME_TR, + FUI_TEXT_EXTR_DMAX_DT_TR, + FUI_TEXT_EXTR_IGAIN_TR, + FUI_TEXT_EXTR_DGAIN_TR, + FUI_TEXT_EXTR_DMIN_TR, + FUI_TEXT_EXTR_DMAX_TR, + FUI_TEXT_EXTR_PMAX_TR, + FUI_TEXT_EXTR_XOFF_TR, + FUI_TEXT_EXTR_YOFF_TR, + FUI_TEXT_STRING_HM_BANGBANG_TR, + FUI_TEXT_STRING_HM_PID_TR, + FUI_TEXT_STRING_ACTION_TR, + FUI_TEXT_HEATING_EXTRUDER_TR, + FUI_TEXT_HEATING_BED_TR, + FUI_TEXT_KILLED_TR, + FUI_TEXT_STEPPER_DISABLED_TR, + FUI_TEXT_EEPROM_STOREDA_TR, + FUI_TEXT_EEPROM_STOREDB_TR, + FUI_TEXT_EEPROM_LOADEDA_TR, + FUI_TEXT_EEPROM_LOADEDB_TR, + FUI_TEXT_UPLOADING_TR, + FUI_TEXT_PAGE_BUFFER_TR, + FUI_TEXT_PAGE_EXTRUDER_TR, + FUI_TEXT_PAGE_EXTRUDER1_TR, + FUI_TEXT_PAGE_EXTRUDER2_TR, + FUI_TEXT_PAGE_EXTRUDER3_TR, + FUI_TEXT_PAGE_BED_TR, + FUI_TEXT_SPEED_MULTIPLY_TR, + FUI_TEXT_FLOW_MULTIPLY_TR, + FUI_TEXT_SHOW_MEASUREMENT_TR, + FUI_TEXT_RESET_MEASUREMENT_TR, + FUI_TEXT_SET_MEASURED_ORIGIN_TR, + FUI_TEXT_ZCALIB_TR, + FUI_TEXT_SET_P1_TR, + FUI_TEXT_SET_P2_TR, + FUI_TEXT_SET_P3_TR, + FUI_TEXT_CALCULATE_LEVELING_TR, + FUI_TEXT_LEVEL_TR, + FUI_TEXT_EXTR_WAIT_RETRACT_TEMP_TR, + FUI_TEXT_EXTR_WAIT_RETRACT_UNITS_TR, + FUI_TEXT_SD_REMOVED_TR, + FUI_TEXT_SD_INSERTED_TR, + FUI_TEXT_PRINTER_READY_TR, + FUI_TEXT_PRINTTIME_DAYS_TR, + FUI_TEXT_PRINTTIME_HOURS_TR, + FUI_TEXT_PRINTTIME_MINUTES_TR, + FUI_TEXT_PRINT_TIME_TR, + FUI_TEXT_PRINT_FILAMENT_TR, + FUI_TEXT_PRINTED_TR, + FUI_TEXT_POWER_TR, + FUI_TEXT_STRING_HM_DEADTIME_TR, + FUI_TEXT_STRING_HM_SLOWBANG_TR, + FUI_TEXT_STOP_PRINT_TR, + FUI_TEXT_Z_BABYSTEPPING_TR, + FUI_TEXT_CHANGE_FILAMENT_TR, + FUI_TEXT_WIZ_CH_FILAMENT1_TR, + FUI_TEXT_WIZ_CH_FILAMENT2_TR, + FUI_TEXT_WIZ_CH_FILAMENT3_TR, + FUI_TEXT_CLICK_DONE_TR, + FUI_TEXT_AUTOLEVEL_ONOFF_TR, + FUI_TEXT_SERVOPOS_TR, + FUI_TEXT_IGNORE_M106_TR, + FUI_TEXT_WIZ_REHEAT1_TR, + FUI_TEXT_WIZ_REHEAT2_TR, + FUI_TEXT_WIZ_WAITTEMP1_TR, + FUI_TEXT_WIZ_WAITTEMP2_TR, + FUI_TEXT_EXTRUDER_JAM_TR, + FUI_TEXT_STANDBY_TR, + FUI_TEXT_BED_COATING_TR, + FUI_TEXT_BED_COATING_SET1_TR, + FUI_TEXT_BED_COATING_SET2_TR, + FUI_TEXT_NOCOATING_TR, + FUI_TEXT_BUILDTAK_TR, + FUI_TEXT_KAPTON_TR, + FUI_TEXT_BLUETAPE_TR, + FUI_TEXT_PETTAPE_TR, + FUI_TEXT_GLUESTICK_TR, + FUI_TEXT_CUSTOM_TR, + FUI_TEXT_COATING_CUSTOM_TR, + FUI_TEXT_LANGUAGE_TR, + FUI_TEXT_MAINPAGE6_1_TR, + FUI_TEXT_MAINPAGE6_2_TR, + FUI_TEXT_MAINPAGE6_3_TR, + FUI_TEXT_MAINPAGE6_4_TR, + FUI_TEXT_MAINPAGE6_5_TR, + FUI_TEXT_MAINPAGE6_6_TR, + FUI_TEXT_MAINPAGE_TEMP_BED_TR, + FUI_TEXT_MAINPAGE_BED_TR, + FUI_TEXT_MAINPAGE_Z_BUF_TR, + FUI_TEXT_MAINPAGE_MUL_EUSAGE_TR, + FUI_TEXT_MAINPAGE_XY_TR, + FUI_TEXT_PRINT_TIME_VALUE_TR, + FUI_TEXT_PRINT_FILAMENT_VALUE_TR, + FUI_TEXT_METER_PRINTED_TR, + FUI_TEXT_STATUS_TR, + FUI_TEXT_EMPTY_TR, + FUI_TEXT_TEMP_SET_TR, + FUI_TEXT_CURRENT_TEMP_TR, + FUI_TEXT_COATING_THICKNESS_TR, + FUI_TEXT_EXTR3_TEMP_TR, + FUI_TEXT_EXTR4_TEMP_TR, + FUI_TEXT_EXTR5_TEMP_TR, + FUI_TEXT_EXTR3_OFF_TR, + FUI_TEXT_EXTR4_OFF_TR, + FUI_TEXT_EXTR5_OFF_TR, + FUI_TEXT_EXTR3_SELECT_TR, + FUI_TEXT_EXTR4_SELECT_TR, + FUI_TEXT_EXTR5_SELECT_TR, + FUI_TEXT_DITTO_0_TR, + FUI_TEXT_DITTO_1_TR, + FUI_TEXT_DITTO_2_TR, + FUI_TEXT_DITTO_3_TR, + FUI_TEXT_ZPROBE_HEIGHT_TR, + FUI_TEXT_OFFSETS_TR, + FUI_TEXT_X_OFFSET_TR, + FUI_TEXT_Y_OFFSET_TR, + FUI_TEXT_Z_OFFSET_TR, + FUI_TEXT_DBG_ENDSTOP_TR +}; +#define LANG_TR_TABLE translations_TR +#else +#define LANG_TR_TABLE NULL +#endif // LANGUAGE_TR_ACTIVE + +#if LANGUAGE_TR_ACTIVE +TRANS(UI_TEXT_ON_FI); +TRANS(UI_TEXT_OFF_FI); +TRANS(UI_TEXT_NA_FI); +TRANS(UI_TEXT_YES_FI); +TRANS(UI_TEXT_NO_FI); +TRANS(UI_TEXT_PRINT_POS_FI); +TRANS(UI_TEXT_PRINTING_FI); +TRANS(UI_TEXT_IDLE_FI); +TRANS(UI_TEXT_NOSDCARD_FI); +TRANS(UI_TEXT_ERROR_FI); +TRANS(UI_TEXT_BACK_FI); +TRANS(UI_TEXT_QUICK_SETTINGS_FI); +TRANS(UI_TEXT_ERRORMSG_FI); +TRANS(UI_TEXT_CONFIGURATION_FI); +TRANS(UI_TEXT_POSITION_FI); +TRANS(UI_TEXT_EXTRUDER_FI); +TRANS(UI_TEXT_SD_CARD_FI); +TRANS(UI_TEXT_DEBUGGING_FI); +TRANS(UI_TEXT_HOME_DELTA_FI); +TRANS(UI_TEXT_HOME_ALL_FI); +TRANS(UI_TEXT_HOME_X_FI); +TRANS(UI_TEXT_HOME_Y_FI); +TRANS(UI_TEXT_HOME_Z_FI); +TRANS(UI_TEXT_PREHEAT_PLA_FI); +TRANS(UI_TEXT_PREHEAT_ABS_FI); +TRANS(UI_TEXT_LIGHTS_ONOFF_FI); +TRANS(UI_TEXT_COOLDOWN_FI); +TRANS(UI_TEXT_SET_TO_ORIGIN_FI); +TRANS(UI_TEXT_DISABLE_STEPPER_FI); +TRANS(UI_TEXT_X_POSITION_FI); +TRANS(UI_TEXT_X_POS_FAST_FI); +TRANS(UI_TEXT_Y_POSITION_FI); +TRANS(UI_TEXT_Y_POS_FAST_FI); +TRANS(UI_TEXT_Z_POSITION_FI); +TRANS(UI_TEXT_Z_POS_FAST_FI); +TRANS(UI_TEXT_E_POSITION_FI); +TRANS(UI_TEXT_BED_TEMP_FI); +TRANS(UI_TEXT_EXTR0_TEMP_FI); +TRANS(UI_TEXT_EXTR1_TEMP_FI); +TRANS(UI_TEXT_EXTR2_TEMP_FI); +TRANS(UI_TEXT_EXTR0_OFF_FI); +TRANS(UI_TEXT_EXTR1_OFF_FI); +TRANS(UI_TEXT_EXTR2_OFF_FI); +TRANS(UI_TEXT_EXTR0_SELECT_FI); +TRANS(UI_TEXT_EXTR1_SELECT_FI); +TRANS(UI_TEXT_EXTR2_SELECT_FI); +TRANS(UI_TEXT_EXTR_ORIGIN_FI); +TRANS(UI_TEXT_PRINT_X_FI); +TRANS(UI_TEXT_PRINT_Y_FI); +TRANS(UI_TEXT_PRINT_Z_FI); +TRANS(UI_TEXT_PRINT_Z_DELTA_FI); +TRANS(UI_TEXT_MOVE_X_FI); +TRANS(UI_TEXT_MOVE_Y_FI); +TRANS(UI_TEXT_MOVE_Z_FI); +TRANS(UI_TEXT_MOVE_Z_DELTA_FI); +TRANS(UI_TEXT_JERK_FI); +TRANS(UI_TEXT_ZJERK_FI); +TRANS(UI_TEXT_ACCELERATION_FI); +TRANS(UI_TEXT_STORE_TO_EEPROM_FI); +TRANS(UI_TEXT_LOAD_EEPROM_FI); +TRANS(UI_TEXT_DBG_ECHO_FI); +TRANS(UI_TEXT_DBG_INFO_FI); +TRANS(UI_TEXT_DBG_ERROR_FI); +TRANS(UI_TEXT_DBG_DRYRUN_FI); +TRANS(UI_TEXT_DBG_ENDSTOP_FI); +TRANS(UI_TEXT_OPS_OFF_FI); +TRANS(UI_TEXT_OPS_CLASSIC_FI); +TRANS(UI_TEXT_OPS_FAST_FI); +TRANS(UI_TEXT_OPS_RETRACT_FI); +TRANS(UI_TEXT_OPS_BACKSLASH_FI); +TRANS(UI_TEXT_OPS_MINDIST_FI); +TRANS(UI_TEXT_OPS_MOVE_AFTER_FI); +TRANS(UI_TEXT_ANTI_OOZE_FI); +TRANS(UI_TEXT_PRINT_FILE_FI); +TRANS(UI_TEXT_PAUSE_PRINT_FI); +TRANS(UI_TEXT_CONTINUE_PRINT_FI); +TRANS(UI_TEXT_UNMOUNT_CARD_FI); +TRANS(UI_TEXT_MOUNT_CARD_FI); +TRANS(UI_TEXT_DELETE_FILE_FI); +TRANS(UI_TEXT_FEEDRATE_FI); +TRANS(UI_TEXT_FEED_MAX_X_FI); +TRANS(UI_TEXT_FEED_MAX_Y_FI); +TRANS(UI_TEXT_FEED_MAX_Z_FI); +TRANS(UI_TEXT_FEED_MAX_Z_DELTA_FI); +TRANS(UI_TEXT_FEED_HOME_X_FI); +TRANS(UI_TEXT_FEED_HOME_Y_FI); +TRANS(UI_TEXT_FEED_HOME_Z_FI); +TRANS(UI_TEXT_FEED_HOME_Z_DELTA_FI); +TRANS(UI_TEXT_ACTION_XPOSITION4A_FI); +TRANS(UI_TEXT_ACTION_XPOSITION4B_FI); +TRANS(UI_TEXT_ACTION_XPOSITION4C_FI); +TRANS(UI_TEXT_ACTION_XPOSITION4D_FI); +TRANS(UI_TEXT_ACTION_YPOSITION4A_FI); +TRANS(UI_TEXT_ACTION_YPOSITION4B_FI); +TRANS(UI_TEXT_ACTION_YPOSITION4C_FI); +TRANS(UI_TEXT_ACTION_YPOSITION4D_FI); +TRANS(UI_TEXT_ACTION_ZPOSITION4A_FI); +TRANS(UI_TEXT_ACTION_ZPOSITION4B_FI); +TRANS(UI_TEXT_ACTION_ZPOSITION4C_FI); +TRANS(UI_TEXT_ACTION_ZPOSITION4D_FI); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST4A_FI); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST4B_FI); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST4C_FI); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST4D_FI); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST4A_FI); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST4B_FI); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST4C_FI); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST4D_FI); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST4A_FI); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST4B_FI); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST4C_FI); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST4D_FI); +TRANS(UI_TEXT_ACTION_EPOSITION_FAST2A_FI); +TRANS(UI_TEXT_ACTION_EPOSITION_FAST2B_FI); +TRANS(UI_TEXT_ACTION_XPOSITION2A_FI); +TRANS(UI_TEXT_ACTION_XPOSITION2B_FI); +TRANS(UI_TEXT_ACTION_YPOSITION2A_FI); +TRANS(UI_TEXT_ACTION_YPOSITION2B_FI); +TRANS(UI_TEXT_ACTION_ZPOSITION2A_FI); +TRANS(UI_TEXT_ACTION_ZPOSITION2B_FI); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST2A_FI); +TRANS(UI_TEXT_ACTION_XPOSITION_FAST2B_FI); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST2A_FI); +TRANS(UI_TEXT_ACTION_YPOSITION_FAST2B_FI); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST2A_FI); +TRANS(UI_TEXT_ACTION_ZPOSITION_FAST2B_FI); +TRANS(UI_TEXT_FANSPEED_FI); +TRANS(UI_TEXT_ACTION_FANSPEED_FI); +TRANS(UI_TEXT_FAN_OFF_FI); +TRANS(UI_TEXT_FAN_25_FI); +TRANS(UI_TEXT_FAN_50_FI); +TRANS(UI_TEXT_FAN_75_FI); +TRANS(UI_TEXT_FAN_FULL_FI); +TRANS(UI_TEXT_STEPPER_INACTIVE_FI); +TRANS(UI_TEXT_STEPPER_INACTIVE2A_FI); +TRANS(UI_TEXT_STEPPER_INACTIVE2B_FI); +TRANS(UI_TEXT_POWER_INACTIVE_FI); +TRANS(UI_TEXT_POWER_INACTIVE2A_FI); +TRANS(UI_TEXT_POWER_INACTIVE2B_FI); +TRANS(UI_TEXT_GENERAL_FI); +TRANS(UI_TEXT_BAUDRATE_FI); +TRANS(UI_TEXT_EXTR_STEPS_FI); +TRANS(UI_TEXT_EXTR_START_FEED_FI); +TRANS(UI_TEXT_EXTR_MAX_FEED_FI); +TRANS(UI_TEXT_EXTR_ACCEL_FI); +TRANS(UI_TEXT_EXTR_WATCH_FI); +TRANS(UI_TEXT_EXTR_ADVANCE_L_FI); +TRANS(UI_TEXT_EXTR_ADVANCE_K_FI); +TRANS(UI_TEXT_EXTR_MANAGER_FI); +TRANS(UI_TEXT_EXTR_PGAIN_FI); +TRANS(UI_TEXT_EXTR_DEADTIME_FI); +TRANS(UI_TEXT_EXTR_DMAX_DT_FI); +TRANS(UI_TEXT_EXTR_IGAIN_FI); +TRANS(UI_TEXT_EXTR_DGAIN_FI); +TRANS(UI_TEXT_EXTR_DMIN_FI); +TRANS(UI_TEXT_EXTR_DMAX_FI); +TRANS(UI_TEXT_EXTR_PMAX_FI); +TRANS(UI_TEXT_EXTR_XOFF_FI); +TRANS(UI_TEXT_EXTR_YOFF_FI); +TRANS(UI_TEXT_STRING_HM_BANGBANG_FI); +TRANS(UI_TEXT_STRING_HM_PID_FI); +TRANS(UI_TEXT_STRING_ACTION_FI); +TRANS(UI_TEXT_HEATING_EXTRUDER_FI); +TRANS(UI_TEXT_HEATING_BED_FI); +TRANS(UI_TEXT_KILLED_FI); +TRANS(UI_TEXT_STEPPER_DISABLED_FI); +TRANS(UI_TEXT_EEPROM_STOREDA_FI); +TRANS(UI_TEXT_EEPROM_STOREDB_FI); +TRANS(UI_TEXT_EEPROM_LOADEDA_FI); +TRANS(UI_TEXT_EEPROM_LOADEDB_FI); +TRANS(UI_TEXT_UPLOADING_FI); +TRANS(UI_TEXT_PAGE_BUFFER_FI); +TRANS(UI_TEXT_PAGE_EXTRUDER_FI); +TRANS(UI_TEXT_PAGE_EXTRUDER1_FI); +TRANS(UI_TEXT_PAGE_EXTRUDER2_FI); +TRANS(UI_TEXT_PAGE_EXTRUDER3_FI); +TRANS(UI_TEXT_PAGE_BED_FI); +TRANS(UI_TEXT_SPEED_MULTIPLY_FI); +TRANS(UI_TEXT_FLOW_MULTIPLY_FI); +TRANS(UI_TEXT_SHOW_MEASUREMENT_FI); +TRANS(UI_TEXT_RESET_MEASUREMENT_FI); +TRANS(UI_TEXT_SET_MEASURED_ORIGIN_FI); +TRANS(UI_TEXT_ZCALIB_FI); +TRANS(UI_TEXT_SET_P1_FI); +TRANS(UI_TEXT_SET_P2_FI); +TRANS(UI_TEXT_SET_P3_FI); +TRANS(UI_TEXT_CALCULATE_LEVELING_FI); +TRANS(UI_TEXT_LEVEL_FI); +TRANS(UI_TEXT_EXTR_WAIT_RETRACT_TEMP_FI); +TRANS(UI_TEXT_EXTR_WAIT_RETRACT_UNITS_FI); +TRANS(UI_TEXT_SD_REMOVED_FI); +TRANS(UI_TEXT_SD_INSERTED_FI); +TRANS(UI_TEXT_PRINTER_READY_FI); +TRANS(UI_TEXT_PRINTTIME_DAYS_FI); +TRANS(UI_TEXT_PRINTTIME_HOURS_FI); +TRANS(UI_TEXT_PRINTTIME_MINUTES_FI); +TRANS(UI_TEXT_PRINT_TIME_FI); +TRANS(UI_TEXT_PRINT_FILAMENT_FI); +TRANS(UI_TEXT_PRINTED_FI); +TRANS(UI_TEXT_POWER_FI); +TRANS(UI_TEXT_STRING_HM_DEADTIME_FI); +TRANS(UI_TEXT_STRING_HM_SLOWBANG_FI); +TRANS(UI_TEXT_STOP_PRINT_FI); +TRANS(UI_TEXT_Z_BABYSTEPPING_FI); +TRANS(UI_TEXT_CHANGE_FILAMENT_FI); +TRANS(UI_TEXT_WIZ_CH_FILAMENT1_FI); +TRANS(UI_TEXT_WIZ_CH_FILAMENT2_FI); +TRANS(UI_TEXT_WIZ_CH_FILAMENT3_FI); +TRANS(UI_TEXT_CLICK_DONE_FI); +TRANS(UI_TEXT_AUTOLEVEL_ONOFF_FI); +TRANS(UI_TEXT_SERVOPOS_FI); +TRANS(UI_TEXT_IGNORE_M106_FI); +TRANS(UI_TEXT_WIZ_REHEAT1_FI); +TRANS(UI_TEXT_WIZ_REHEAT2_FI); +TRANS(UI_TEXT_WIZ_WAITTEMP1_FI); +TRANS(UI_TEXT_WIZ_WAITTEMP2_FI); +TRANS(UI_TEXT_EXTRUDER_JAM_FI); +TRANS(UI_TEXT_STANDBY_FI); +TRANS(UI_TEXT_BED_COATING_FI); +TRANS(UI_TEXT_BED_COATING_SET1_FI); +TRANS(UI_TEXT_BED_COATING_SET2_FI); +TRANS(UI_TEXT_NOCOATING_FI); +TRANS(UI_TEXT_BUILDTAK_FI); +TRANS(UI_TEXT_KAPTON_FI); +TRANS(UI_TEXT_BLUETAPE_FI); +TRANS(UI_TEXT_PETTAPE_FI); +TRANS(UI_TEXT_GLUESTICK_FI); +TRANS(UI_TEXT_CUSTOM_FI); +TRANS(UI_TEXT_COATING_CUSTOM_FI); +TRANS(UI_TEXT_LANGUAGE_FI); +TRANS(UI_TEXT_MAINPAGE6_1_FI); +TRANS(UI_TEXT_MAINPAGE6_2_FI); +TRANS(UI_TEXT_MAINPAGE6_3_FI); +TRANS(UI_TEXT_MAINPAGE6_4_FI); +TRANS(UI_TEXT_MAINPAGE6_5_FI); +TRANS(UI_TEXT_MAINPAGE6_6_FI); +TRANS(UI_TEXT_MAINPAGE_TEMP_BED_FI); +TRANS(UI_TEXT_MAINPAGE_BED_FI); +TRANS(UI_TEXT_MAINPAGE_Z_BUF_FI); +TRANS(UI_TEXT_MAINPAGE_MUL_EUSAGE_FI); +TRANS(UI_TEXT_MAINPAGE_XY_FI); +TRANS(UI_TEXT_PRINT_TIME_VALUE_FI); +TRANS(UI_TEXT_PRINT_FILAMENT_VALUE_FI); +TRANS(UI_TEXT_METER_PRINTED_FI); +TRANS(UI_TEXT_STATUS_FI); +TRANS(UI_TEXT_EMPTY_FI); +TRANS(UI_TEXT_TEMP_SET_FI); +TRANS(UI_TEXT_CURRENT_TEMP_FI); +TRANS(UI_TEXT_COATING_THICKNESS_FI); +TRANS(UI_TEXT_EXTR3_TEMP_FI); +TRANS(UI_TEXT_EXTR4_TEMP_FI); +TRANS(UI_TEXT_EXTR5_TEMP_FI); +TRANS(UI_TEXT_EXTR3_OFF_FI); +TRANS(UI_TEXT_EXTR4_OFF_FI); +TRANS(UI_TEXT_EXTR5_OFF_FI); +TRANS(UI_TEXT_EXTR3_SELECT_FI); +TRANS(UI_TEXT_EXTR4_SELECT_FI); +TRANS(UI_TEXT_EXTR5_SELECT_FI); +TRANS(UI_TEXT_DITTO_0_FI); +TRANS(UI_TEXT_DITTO_1_FI); +TRANS(UI_TEXT_DITTO_2_FI); +TRANS(UI_TEXT_DITTO_3_FI); +TRANS(UI_TEXT_ZPROBE_HEIGHT_FI); +TRANS(UI_TEXT_OFFSETS_FI); +TRANS(UI_TEXT_X_OFFSET_FI); +TRANS(UI_TEXT_Y_OFFSET_FI); +TRANS(UI_TEXT_Z_OFFSET_FI); + + +PGM_P const translations_FI[NUM_TRANSLATED_WORDS] PROGMEM = { + FUI_TEXT_ON_FI, + FUI_TEXT_OFF_FI, + FUI_TEXT_NA_FI, + FUI_TEXT_YES_FI, + FUI_TEXT_NO_FI, + FUI_TEXT_PRINT_POS_FI, + FUI_TEXT_PRINTING_FI, + FUI_TEXT_IDLE_FI, + FUI_TEXT_NOSDCARD_FI, + FUI_TEXT_ERROR_FI, + FUI_TEXT_BACK_FI, + FUI_TEXT_QUICK_SETTINGS_FI, + FUI_TEXT_ERRORMSG_FI, + FUI_TEXT_CONFIGURATION_FI, + FUI_TEXT_POSITION_FI, + FUI_TEXT_EXTRUDER_FI, + FUI_TEXT_SD_CARD_FI, + FUI_TEXT_DEBUGGING_FI, + FUI_TEXT_HOME_DELTA_FI, + FUI_TEXT_HOME_ALL_FI, + FUI_TEXT_HOME_X_FI, + FUI_TEXT_HOME_Y_FI, + FUI_TEXT_HOME_Z_FI, + FUI_TEXT_PREHEAT_PLA_FI, + FUI_TEXT_PREHEAT_ABS_FI, + FUI_TEXT_LIGHTS_ONOFF_FI, + FUI_TEXT_COOLDOWN_FI, + FUI_TEXT_SET_TO_ORIGIN_FI, + FUI_TEXT_DISABLE_STEPPER_FI, + FUI_TEXT_X_POSITION_FI, + FUI_TEXT_X_POS_FAST_FI, + FUI_TEXT_Y_POSITION_FI, + FUI_TEXT_Y_POS_FAST_FI, + FUI_TEXT_Z_POSITION_FI, + FUI_TEXT_Z_POS_FAST_FI, + FUI_TEXT_E_POSITION_FI, + FUI_TEXT_BED_TEMP_FI, + FUI_TEXT_EXTR0_TEMP_FI, + FUI_TEXT_EXTR1_TEMP_FI, + FUI_TEXT_EXTR2_TEMP_FI, + FUI_TEXT_EXTR0_OFF_FI, + FUI_TEXT_EXTR1_OFF_FI, + FUI_TEXT_EXTR2_OFF_FI, + FUI_TEXT_EXTR0_SELECT_FI, + FUI_TEXT_EXTR1_SELECT_FI, + FUI_TEXT_EXTR2_SELECT_FI, + FUI_TEXT_EXTR_ORIGIN_FI, + FUI_TEXT_PRINT_X_FI, + FUI_TEXT_PRINT_Y_FI, + FUI_TEXT_PRINT_Z_FI, + FUI_TEXT_PRINT_Z_DELTA_FI, + FUI_TEXT_MOVE_X_FI, + FUI_TEXT_MOVE_Y_FI, + FUI_TEXT_MOVE_Z_FI, + FUI_TEXT_MOVE_Z_DELTA_FI, + FUI_TEXT_JERK_FI, + FUI_TEXT_ZJERK_FI, + FUI_TEXT_ACCELERATION_FI, + FUI_TEXT_STORE_TO_EEPROM_FI, + FUI_TEXT_LOAD_EEPROM_FI, + FUI_TEXT_DBG_ECHO_FI, + FUI_TEXT_DBG_INFO_FI, + FUI_TEXT_DBG_ERROR_FI, + FUI_TEXT_DBG_DRYRUN_FI, + FUI_TEXT_OPS_OFF_FI, + FUI_TEXT_OPS_CLASSIC_FI, + FUI_TEXT_OPS_FAST_FI, + FUI_TEXT_OPS_RETRACT_FI, + FUI_TEXT_OPS_BACKSLASH_FI, + FUI_TEXT_OPS_MINDIST_FI, + FUI_TEXT_OPS_MOVE_AFTER_FI, + FUI_TEXT_ANTI_OOZE_FI, + FUI_TEXT_PRINT_FILE_FI, + FUI_TEXT_PAUSE_PRINT_FI, + FUI_TEXT_CONTINUE_PRINT_FI, + FUI_TEXT_UNMOUNT_CARD_FI, + FUI_TEXT_MOUNT_CARD_FI, + FUI_TEXT_DELETE_FILE_FI, + FUI_TEXT_FEEDRATE_FI, + FUI_TEXT_FEED_MAX_X_FI, + FUI_TEXT_FEED_MAX_Y_FI, + FUI_TEXT_FEED_MAX_Z_FI, + FUI_TEXT_FEED_MAX_Z_DELTA_FI, + FUI_TEXT_FEED_HOME_X_FI, + FUI_TEXT_FEED_HOME_Y_FI, + FUI_TEXT_FEED_HOME_Z_FI, + FUI_TEXT_FEED_HOME_Z_DELTA_FI, + FUI_TEXT_ACTION_XPOSITION4A_FI, + FUI_TEXT_ACTION_XPOSITION4B_FI, + FUI_TEXT_ACTION_XPOSITION4C_FI, + FUI_TEXT_ACTION_XPOSITION4D_FI, + FUI_TEXT_ACTION_YPOSITION4A_FI, + FUI_TEXT_ACTION_YPOSITION4B_FI, + FUI_TEXT_ACTION_YPOSITION4C_FI, + FUI_TEXT_ACTION_YPOSITION4D_FI, + FUI_TEXT_ACTION_ZPOSITION4A_FI, + FUI_TEXT_ACTION_ZPOSITION4B_FI, + FUI_TEXT_ACTION_ZPOSITION4C_FI, + FUI_TEXT_ACTION_ZPOSITION4D_FI, + FUI_TEXT_ACTION_XPOSITION_FAST4A_FI, + FUI_TEXT_ACTION_XPOSITION_FAST4B_FI, + FUI_TEXT_ACTION_XPOSITION_FAST4C_FI, + FUI_TEXT_ACTION_XPOSITION_FAST4D_FI, + FUI_TEXT_ACTION_YPOSITION_FAST4A_FI, + FUI_TEXT_ACTION_YPOSITION_FAST4B_FI, + FUI_TEXT_ACTION_YPOSITION_FAST4C_FI, + FUI_TEXT_ACTION_YPOSITION_FAST4D_FI, + FUI_TEXT_ACTION_ZPOSITION_FAST4A_FI, + FUI_TEXT_ACTION_ZPOSITION_FAST4B_FI, + FUI_TEXT_ACTION_ZPOSITION_FAST4C_FI, + FUI_TEXT_ACTION_ZPOSITION_FAST4D_FI, + FUI_TEXT_ACTION_EPOSITION_FAST2A_FI, + FUI_TEXT_ACTION_EPOSITION_FAST2B_FI, + FUI_TEXT_ACTION_XPOSITION2A_FI, + FUI_TEXT_ACTION_XPOSITION2B_FI, + FUI_TEXT_ACTION_YPOSITION2A_FI, + FUI_TEXT_ACTION_YPOSITION2B_FI, + FUI_TEXT_ACTION_ZPOSITION2A_FI, + FUI_TEXT_ACTION_ZPOSITION2B_FI, + FUI_TEXT_ACTION_XPOSITION_FAST2A_FI, + FUI_TEXT_ACTION_XPOSITION_FAST2B_FI, + FUI_TEXT_ACTION_YPOSITION_FAST2A_FI, + FUI_TEXT_ACTION_YPOSITION_FAST2B_FI, + FUI_TEXT_ACTION_ZPOSITION_FAST2A_FI, + FUI_TEXT_ACTION_ZPOSITION_FAST2B_FI, + FUI_TEXT_FANSPEED_FI, + FUI_TEXT_ACTION_FANSPEED_FI, + FUI_TEXT_FAN_OFF_FI, + FUI_TEXT_FAN_25_FI, + FUI_TEXT_FAN_50_FI, + FUI_TEXT_FAN_75_FI, + FUI_TEXT_FAN_FULL_FI, + FUI_TEXT_STEPPER_INACTIVE_FI, + FUI_TEXT_STEPPER_INACTIVE2A_FI, + FUI_TEXT_STEPPER_INACTIVE2B_FI, + FUI_TEXT_POWER_INACTIVE_FI, + FUI_TEXT_POWER_INACTIVE2A_FI, + FUI_TEXT_POWER_INACTIVE2B_FI, + FUI_TEXT_GENERAL_FI, + FUI_TEXT_BAUDRATE_FI, + FUI_TEXT_EXTR_STEPS_FI, + FUI_TEXT_EXTR_START_FEED_FI, + FUI_TEXT_EXTR_MAX_FEED_FI, + FUI_TEXT_EXTR_ACCEL_FI, + FUI_TEXT_EXTR_WATCH_FI, + FUI_TEXT_EXTR_ADVANCE_L_FI, + FUI_TEXT_EXTR_ADVANCE_K_FI, + FUI_TEXT_EXTR_MANAGER_FI, + FUI_TEXT_EXTR_PGAIN_FI, + FUI_TEXT_EXTR_DEADTIME_FI, + FUI_TEXT_EXTR_DMAX_DT_FI, + FUI_TEXT_EXTR_IGAIN_FI, + FUI_TEXT_EXTR_DGAIN_FI, + FUI_TEXT_EXTR_DMIN_FI, + FUI_TEXT_EXTR_DMAX_FI, + FUI_TEXT_EXTR_PMAX_FI, + FUI_TEXT_EXTR_XOFF_FI, + FUI_TEXT_EXTR_YOFF_FI, + FUI_TEXT_STRING_HM_BANGBANG_FI, + FUI_TEXT_STRING_HM_PID_FI, + FUI_TEXT_STRING_ACTION_FI, + FUI_TEXT_HEATING_EXTRUDER_FI, + FUI_TEXT_HEATING_BED_FI, + FUI_TEXT_KILLED_FI, + FUI_TEXT_STEPPER_DISABLED_FI, + FUI_TEXT_EEPROM_STOREDA_FI, + FUI_TEXT_EEPROM_STOREDB_FI, + FUI_TEXT_EEPROM_LOADEDA_FI, + FUI_TEXT_EEPROM_LOADEDB_FI, + FUI_TEXT_UPLOADING_FI, + FUI_TEXT_PAGE_BUFFER_FI, + FUI_TEXT_PAGE_EXTRUDER_FI, + FUI_TEXT_PAGE_EXTRUDER1_FI, + FUI_TEXT_PAGE_EXTRUDER2_FI, + FUI_TEXT_PAGE_EXTRUDER3_FI, + FUI_TEXT_PAGE_BED_FI, + FUI_TEXT_SPEED_MULTIPLY_FI, + FUI_TEXT_FLOW_MULTIPLY_FI, + FUI_TEXT_SHOW_MEASUREMENT_FI, + FUI_TEXT_RESET_MEASUREMENT_FI, + FUI_TEXT_SET_MEASURED_ORIGIN_FI, + FUI_TEXT_ZCALIB_FI, + FUI_TEXT_SET_P1_FI, + FUI_TEXT_SET_P2_FI, + FUI_TEXT_SET_P3_FI, + FUI_TEXT_CALCULATE_LEVELING_FI, + FUI_TEXT_LEVEL_FI, + FUI_TEXT_EXTR_WAIT_RETRACT_TEMP_FI, + FUI_TEXT_EXTR_WAIT_RETRACT_UNITS_FI, + FUI_TEXT_SD_REMOVED_FI, + FUI_TEXT_SD_INSERTED_FI, + FUI_TEXT_PRINTER_READY_FI, + FUI_TEXT_PRINTTIME_DAYS_FI, + FUI_TEXT_PRINTTIME_HOURS_FI, + FUI_TEXT_PRINTTIME_MINUTES_FI, + FUI_TEXT_PRINT_TIME_FI, + FUI_TEXT_PRINT_FILAMENT_FI, + FUI_TEXT_PRINTED_FI, + FUI_TEXT_POWER_FI, + FUI_TEXT_STRING_HM_DEADTIME_FI, + FUI_TEXT_STRING_HM_SLOWBANG_FI, + FUI_TEXT_STOP_PRINT_FI, + FUI_TEXT_Z_BABYSTEPPING_FI, + FUI_TEXT_CHANGE_FILAMENT_FI, + FUI_TEXT_WIZ_CH_FILAMENT1_FI, + FUI_TEXT_WIZ_CH_FILAMENT2_FI, + FUI_TEXT_WIZ_CH_FILAMENT3_FI, + FUI_TEXT_CLICK_DONE_FI, + FUI_TEXT_AUTOLEVEL_ONOFF_FI, + FUI_TEXT_SERVOPOS_FI, + FUI_TEXT_IGNORE_M106_FI, + FUI_TEXT_WIZ_REHEAT1_FI, + FUI_TEXT_WIZ_REHEAT2_FI, + FUI_TEXT_WIZ_WAITTEMP1_FI, + FUI_TEXT_WIZ_WAITTEMP2_FI, + FUI_TEXT_EXTRUDER_JAM_FI, + FUI_TEXT_STANDBY_FI, + FUI_TEXT_BED_COATING_FI, + FUI_TEXT_BED_COATING_SET1_FI, + FUI_TEXT_BED_COATING_SET2_FI, + FUI_TEXT_NOCOATING_FI, + FUI_TEXT_BUILDTAK_FI, + FUI_TEXT_KAPTON_FI, + FUI_TEXT_BLUETAPE_FI, + FUI_TEXT_PETTAPE_FI, + FUI_TEXT_GLUESTICK_FI, + FUI_TEXT_CUSTOM_FI, + FUI_TEXT_COATING_CUSTOM_FI, + FUI_TEXT_LANGUAGE_FI, + FUI_TEXT_MAINPAGE6_1_FI, + FUI_TEXT_MAINPAGE6_2_FI, + FUI_TEXT_MAINPAGE6_3_FI, + FUI_TEXT_MAINPAGE6_4_FI, + FUI_TEXT_MAINPAGE6_5_FI, + FUI_TEXT_MAINPAGE6_6_FI, + FUI_TEXT_MAINPAGE_TEMP_BED_FI, + FUI_TEXT_MAINPAGE_BED_FI, + FUI_TEXT_MAINPAGE_Z_BUF_FI, + FUI_TEXT_MAINPAGE_MUL_EUSAGE_FI, + FUI_TEXT_MAINPAGE_XY_FI, + FUI_TEXT_PRINT_TIME_VALUE_FI, + FUI_TEXT_PRINT_FILAMENT_VALUE_FI, + FUI_TEXT_METER_PRINTED_FI, + FUI_TEXT_STATUS_FI, + FUI_TEXT_EMPTY_FI, + FUI_TEXT_TEMP_SET_FI, + FUI_TEXT_CURRENT_TEMP_FI, + FUI_TEXT_COATING_THICKNESS_FI, + FUI_TEXT_EXTR3_TEMP_FI, + FUI_TEXT_EXTR4_TEMP_FI, + FUI_TEXT_EXTR5_TEMP_FI, + FUI_TEXT_EXTR3_OFF_FI, + FUI_TEXT_EXTR4_OFF_FI, + FUI_TEXT_EXTR5_OFF_FI, + FUI_TEXT_EXTR3_SELECT_FI, + FUI_TEXT_EXTR4_SELECT_FI, + FUI_TEXT_EXTR5_SELECT_FI, + FUI_TEXT_DITTO_0_FI, + FUI_TEXT_DITTO_1_FI, + FUI_TEXT_DITTO_2_FI, + FUI_TEXT_DITTO_3_FI, + FUI_TEXT_ZPROBE_HEIGHT_FI, + FUI_TEXT_OFFSETS_FI, + FUI_TEXT_X_OFFSET_FI, + FUI_TEXT_Y_OFFSET_FI, + FUI_TEXT_Z_OFFSET_FI, + FUI_TEXT_DBG_ENDSTOP_FI +}; +#define LANG_FI_TABLE translations_FI +#else +#define LANG_FI_TABLE NULL +#endif // LANGUAGE_FI_ACTIVE + +// References to the possible languages + +PGM_P const * const translations[NUM_LANGUAGES_KNOWN] PROGMEM = { + LANG_EN_TABLE, + LANG_DE_TABLE, + LANG_NL_TABLE, + LANG_PT_TABLE, + LANG_IT_TABLE, + LANG_ES_TABLE, + LANG_SE_TABLE, + LANG_FR_TABLE, + LANG_CZ_TABLE, + LANG_PL_TABLE, + LANG_TR_TABLE, + LANG_FI_TABLE +}; + +// Array in flash to select only valid languages + +const uint8_t availableLanguages[] PROGMEM = { +#if LANGUAGE_EN_ACTIVE + 0, +#endif // LANGUAGE_EN_ACTIVE +#if LANGUAGE_DE_ACTIVE + 1, +#endif // LANGUAGE_DE_ACTIVE +#if LANGUAGE_NL_ACTIVE + 2, +#endif // LANGUAGE_NL_ACTIVE +#if LANGUAGE_PT_ACTIVE + 3, +#endif // LANGUAGE_PT_ACTIVE +#if LANGUAGE_IT_ACTIVE + 4, +#endif // LANGUAGE_IT_ACTIVE +#if LANGUAGE_ES_ACTIVE + 5, +#endif // LANGUAGE_ES_ACTIVE +#if LANGUAGE_SE_ACTIVE + 6, +#endif // LANGUAGE_SE_ACTIVE +#if LANGUAGE_FR_ACTIVE + 7, +#endif // LANGUAGE_FR_ACTIVE +#if LANGUAGE_CZ_ACTIVE + 8, +#endif // LANGUAGE_CZ_ACTIVE +#if LANGUAGE_PL_ACTIVE + 9, +#endif // LANGUAGE_PL_ACTIVE +#if LANGUAGE_TR_ACTIVE + 10, +#endif // LANGUAGE_TR_ACTIVE +#if LANGUAGE_FI_ACTIVE + 11, +#endif // LANGUAGE_FI_ACTIVE + 255 +}; + +void Com::selectLanguage(fast8_t lang) { + unsigned int pos = (unsigned int)&availableLanguages; + uint8_t best = 255,cur; + while((cur = HAL::readFlashByte((PGM_P)pos)) != 255) { + if(best == 255 || cur == lang) + best = cur; + pos++; + } + Com::selectedLanguage = best; +} + +const char* Com::translatedF(int textId) { + PGM_P *adr = (PGM_P*)pgm_read_word(&translations[selectedLanguage]); + return (const char *)pgm_read_word(&adr[textId]); +} + +#endif diff --git a/trunk/Arduino/Repetier_0.92.9/uilang.h b/trunk/Arduino/Repetier_0.92.9/uilang.h new file mode 100644 index 00000000..8cbecf00 --- /dev/null +++ b/trunk/Arduino/Repetier_0.92.9/uilang.h @@ -0,0 +1,3893 @@ +/* + This file is part of Repetier-Firmware. + + Repetier-Firmware is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Repetier-Firmware is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Repetier-Firmware. If not, see . + +*/ + +#if !defined(UI_DISPLAY_CHARSET) || UI_DISPLAY_CHARSET > 3 +#define UI_DISPLAY_CHARSET 1 +#endif + +//Symbolic character values for specific symbols. +//May be overridden for different controllers, charactersets, etc. +#define cUP "\001" +#define cDEG "\002" +#define cSEL "\003" +#define cUNSEL "\004" +#define cTEMP "\005" +#define cFOLD "\006" +#define bFOLD 6 +#define cARROW "\176" + +#if UI_DISPLAY_CHARSET == 0 // ASCII fallback +#define CHAR_RIGHT '-' +#define CHAR_SELECTOR '>' +#define CHAR_SELECTED '*' +#define STR_auml "ae" +#define STR_Auml "Ae" +#define STR_uuml "ue" +#define STR_Uuml "Ue" +#define STR_ouml "oe" +#define STR_Ouml "Oe" +#define STR_szlig "ss" +#endif + +#if UI_DISPLAY_CHARSET == 1 // HD44870 charset with knji chars +#define CHAR_RIGHT 0x7e +#define CHAR_SELECTOR '>' +#define CHAR_SELECTED '*' +#define STR_auml "\xe1" +#define STR_Auml "Ae" +#define STR_uuml "\365" +#define STR_Uuml "Ue" +#define STR_ouml "\357" +#define STR_Ouml "Oe" +#define STR_szlig "\342" +#endif + +#if UI_DISPLAY_CHARSET == 2 // Western charset +#define CHAR_RIGHT 0xbc +#define CHAR_SELECTOR 0xf6 +#define CHAR_SELECTED '*' +#define STR_auml "\204" +#define STR_Auml "\216" +#define STR_uuml "\201" +#define STR_Uuml "\212" +#define STR_ouml "\204" +#define STR_Ouml "\211" +#define STR_szlig "160" +#endif + + +#if UI_DISPLAY_CHARSET==3 // U8glib +#define CHAR_RIGHT 187 //>> +#define CHAR_SELECTOR 255 //'>' +#define CHAR_SELECTED 254 //'*' +#define STR_auml "\344" +#define STR_Auml "\304" +#define STR_uuml "\374" +#define STR_Uuml "\334" +#define STR_ouml "\366" +#define STR_Ouml "\326" +#define STR_szlig "\337" +#endif + +#define LANGUAGE_EN_ID 0 +#define LANGUAGE_DE_ID 1 +#define LANGUAGE_NL_ID 2 +#define LANGUAGE_PT_ID 3 +#define LANGAUGE_IT_ID 4 +#define LANGUAGE_ES_ID 5 +#define LANGUAGE_SE_ID 6 +#define LANGUAGE_FR_ID 7 +#define LANGUAGE_CZ_ID 8 +#define LANGUAGE_PL_ID 9 +#define LANGUAGE_TR_ID 10 +#define LANGUAGE_FI_ID 11 + +#define NUM_LANGUAGES_KNOWN 12 +#define NUM_TRANSLATED_WORDS 267 + +// For selectable translations we refer to each text by a id which gets +// defined here. The list starts at 0 and defines the position in the +// translation index. + +#define UI_TEXT_ON_ID 0 // "On" +#define UI_TEXT_OFF_ID 1 // "Off" +#define UI_TEXT_NA_ID 2 // "N/A" // Output for not available +#define UI_TEXT_YES_ID 3 // "Yes" +#define UI_TEXT_NO_ID 4 // "No" +#define UI_TEXT_PRINT_POS_ID 5 // "Printing..." +#define UI_TEXT_PRINTING_ID 6 // "Printing" +#define UI_TEXT_IDLE_ID 7 // "Idle" +#define UI_TEXT_NOSDCARD_ID 8 // "No SD Card" +#define UI_TEXT_ERROR_ID 9 // "**** ERROR ****" +#define UI_TEXT_BACK_ID 10 // "Back " cUP +#define UI_TEXT_QUICK_SETTINGS_ID 11 // "Quick Settings" +#define UI_TEXT_ERRORMSG_ID 12 // "%oe" +#define UI_TEXT_CONFIGURATION_ID 13 // "Configuration" +#define UI_TEXT_POSITION_ID 14 // "Position" +#define UI_TEXT_EXTRUDER_ID 15 // "Extruder" +#define UI_TEXT_SD_CARD_ID 16 // "SD Card" +#define UI_TEXT_DEBUGGING_ID 17 // "Debugging" +#define UI_TEXT_HOME_DELTA_ID 18 // "Home Delta" +#define UI_TEXT_HOME_ALL_ID 19 // "Home All" +#define UI_TEXT_HOME_X_ID 20 // "Home X" +#define UI_TEXT_HOME_Y_ID 21 // "Home Y" +#define UI_TEXT_HOME_Z_ID 22 // "Home Z" +#define UI_TEXT_PREHEAT_PLA_ID 23 // "Preheat PLA" +#define UI_TEXT_PREHEAT_ABS_ID 24 // "Preheat ABS" +#define UI_TEXT_LIGHTS_ONOFF_ID 25 // "Lights :%lo" +#define UI_TEXT_COOLDOWN_ID 26 // "Cooldown" +#define UI_TEXT_SET_TO_ORIGIN_ID 27 // "Set to Origin" +#define UI_TEXT_DISABLE_STEPPER_ID 28 // "Disable stepper" +#define UI_TEXT_X_POSITION_ID 29 // "X Position" +#define UI_TEXT_X_POS_FAST_ID 30 // "X Pos. Fast" +#define UI_TEXT_Y_POSITION_ID 31 // "Y Position" +#define UI_TEXT_Y_POS_FAST_ID 32 // "Y Pos. Fast" +#define UI_TEXT_Z_POSITION_ID 33 // "Z Position" +#define UI_TEXT_Z_POS_FAST_ID 34 // "Z Pos. Fast" +#define UI_TEXT_E_POSITION_ID 35 // "Extr. position" +#define UI_TEXT_BED_TEMP_ID 36 // "Bed Temp: %Eb" cDEG "C" +#define UI_TEXT_EXTR0_TEMP_ID 37 // "Temp. 1 : %E0" cDEG "C" +#define UI_TEXT_EXTR1_TEMP_ID 38 // "Temp. 2 : %E1" cDEG "C" +#define UI_TEXT_EXTR2_TEMP_ID 39 // "Temp. 3 : %E2" cDEG "C" +#define UI_TEXT_EXTR0_OFF_ID 40 // "Turn Extr. 1 Off" +#define UI_TEXT_EXTR1_OFF_ID 41 // "Turn Extr. 2 Off" +#define UI_TEXT_EXTR2_OFF_ID 42 // "Turn Extr. 3 Off" +#define UI_TEXT_EXTR0_SELECT_ID 43 // "%X0 Select Extr. 1" +#define UI_TEXT_EXTR1_SELECT_ID 44 // "%X1 Select Extr. 2" +#define UI_TEXT_EXTR2_SELECT_ID 45 // "%X2 Select Extr. 3" +#define UI_TEXT_EXTR_ORIGIN_ID 46 // "Set Origin" +#define UI_TEXT_PRINT_X_ID 47 // "Print X:%ax" +#define UI_TEXT_PRINT_Y_ID 48 // "Print Y:%ay" +#define UI_TEXT_PRINT_Z_ID 49 // "Print Z:%az" +#define UI_TEXT_PRINT_Z_DELTA_ID 50 // "Print:%az" +#define UI_TEXT_MOVE_X_ID 51 // "Move X :%aX" +#define UI_TEXT_MOVE_Y_ID 52 // "Move Y :%aY" +#define UI_TEXT_MOVE_Z_ID 53 // "Move Z :%aZ" +#define UI_TEXT_MOVE_Z_DELTA_ID 54 // "Move:%aZ" +#define UI_TEXT_JERK_ID 55 // "Jerk :%aj" +#define UI_TEXT_ZJERK_ID 56 // "Z-Jerk :%aJ" +#define UI_TEXT_ACCELERATION_ID 57 // "Acceleration" +#define UI_TEXT_STORE_TO_EEPROM_ID 58 // "Store to EEPROM" +#define UI_TEXT_LOAD_EEPROM_ID 59 // "Load f. EEPROM" +#define UI_TEXT_DBG_ECHO_ID 60 // "Echo :%do" +#define UI_TEXT_DBG_INFO_ID 61 // "Info :%di" +#define UI_TEXT_DBG_ERROR_ID 62 // "Errors :%de" +#define UI_TEXT_DBG_DRYRUN_ID 63 // "Dry run:%dd" +#define UI_TEXT_OPS_OFF_ID 64 // "%O0 OPS Off" +#define UI_TEXT_OPS_CLASSIC_ID 65 // "%O1 OPS Classic" +#define UI_TEXT_OPS_FAST_ID 66 // "%O2 OPS Fast" +#define UI_TEXT_OPS_RETRACT_ID 67 // "Retract :%Or" +#define UI_TEXT_OPS_BACKSLASH_ID 68 // "Backsl. :%Ob" +#define UI_TEXT_OPS_MINDIST_ID 69 // "Min.dist :%Od" +#define UI_TEXT_OPS_MOVE_AFTER_ID 70 // "Move after:%Oa" +#define UI_TEXT_ANTI_OOZE_ID 71 // "Anti Ooze" +#define UI_TEXT_PRINT_FILE_ID 72 // "Print file" +#define UI_TEXT_PAUSE_PRINT_ID 73 // "Pause Print" +#define UI_TEXT_CONTINUE_PRINT_ID 74 // "Continue Print" +#define UI_TEXT_UNMOUNT_CARD_ID 75 // "Unmount Card" +#define UI_TEXT_MOUNT_CARD_ID 76 // "Mount Card" +#define UI_TEXT_DELETE_FILE_ID 77 // "Delete file" +#define UI_TEXT_FEEDRATE_ID 78 // "Feedrate" +#define UI_TEXT_FEED_MAX_X_ID 79 // "Max X:%fx" +#define UI_TEXT_FEED_MAX_Y_ID 80 // "Max Y:%fy" +#define UI_TEXT_FEED_MAX_Z_ID 81 // "Max Z:%fz" +#define UI_TEXT_FEED_MAX_Z_DELTA_ID 82 // "Max:%fz" +#define UI_TEXT_FEED_HOME_X_ID 83 // "Home X:%fX" +#define UI_TEXT_FEED_HOME_Y_ID 84 // "Home Y:%fY" +#define UI_TEXT_FEED_HOME_Z_ID 85 // "Home Z:%fZ" +#define UI_TEXT_FEED_HOME_Z_DELTA_ID 86 // "Home:%fZ" +#define UI_TEXT_ACTION_XPOSITION4A_ID 87 // "X:%x0 mm" +#define UI_TEXT_ACTION_XPOSITION4B_ID 88 // "Min endstop:%sx" +#define UI_TEXT_ACTION_XPOSITION4C_ID 89 // "Max endstop:%sX" +#define UI_TEXT_ACTION_XPOSITION4D_ID 90 // "" +#define UI_TEXT_ACTION_YPOSITION4A_ID 91 // "Y:%x1 mm" +#define UI_TEXT_ACTION_YPOSITION4B_ID 92 // "Min endstop:%sy" +#define UI_TEXT_ACTION_YPOSITION4C_ID 93 // "Max endstop:%sY" +#define UI_TEXT_ACTION_YPOSITION4D_ID 94 // "" +#define UI_TEXT_ACTION_ZPOSITION4A_ID 95 // "Z:%x2 mm" +#define UI_TEXT_ACTION_ZPOSITION4B_ID 96 // "Min endstop:%sz" +#define UI_TEXT_ACTION_ZPOSITION4C_ID 97 // "Max endstop:%sZ" +#define UI_TEXT_ACTION_ZPOSITION4D_ID 98 // "" +#define UI_TEXT_ACTION_XPOSITION_FAST4A_ID 99 // "X:%x0 mm" +#define UI_TEXT_ACTION_XPOSITION_FAST4B_ID 100 // "Min endstop:%sx" +#define UI_TEXT_ACTION_XPOSITION_FAST4C_ID 101 // "Max endstop:%sX" +#define UI_TEXT_ACTION_XPOSITION_FAST4D_ID 102 // "" +#define UI_TEXT_ACTION_YPOSITION_FAST4A_ID 103 // "Y:%x1 mm" +#define UI_TEXT_ACTION_YPOSITION_FAST4B_ID 104 // "Min endstop:%sy" +#define UI_TEXT_ACTION_YPOSITION_FAST4C_ID 105 // "Max endstop:%sY" +#define UI_TEXT_ACTION_YPOSITION_FAST4D_ID 106 // "" +#define UI_TEXT_ACTION_ZPOSITION_FAST4A_ID 107 // "Z:%x2 mm" +#define UI_TEXT_ACTION_ZPOSITION_FAST4B_ID 108 // "Min endstop:%sz" +#define UI_TEXT_ACTION_ZPOSITION_FAST4C_ID 109 // "Max endstop:%sZ" +#define UI_TEXT_ACTION_ZPOSITION_FAST4D_ID 110 // "" +#define UI_TEXT_ACTION_EPOSITION_FAST2A_ID 111 // "E:%x3 mm" +#define UI_TEXT_ACTION_EPOSITION_FAST2B_ID 112 // "1 click = 1 mm" +#define UI_TEXT_ACTION_XPOSITION2A_ID 113 // "X:%x0 mm" +#define UI_TEXT_ACTION_XPOSITION2B_ID 114 // "Min:%sx Max:%sX" +#define UI_TEXT_ACTION_YPOSITION2A_ID 115 // "Y:%x1 mm" +#define UI_TEXT_ACTION_YPOSITION2B_ID 116 // "Min:%sy Max:%sY" +#define UI_TEXT_ACTION_ZPOSITION2A_ID 117 // "Z:%x2 mm" +#define UI_TEXT_ACTION_ZPOSITION2B_ID 118 // "Min:%sz Max:%sZ" +#define UI_TEXT_ACTION_XPOSITION_FAST2A_ID 119 // "X:%x0 mm" +#define UI_TEXT_ACTION_XPOSITION_FAST2B_ID 120 // "Min:%sx Max:%sX" +#define UI_TEXT_ACTION_YPOSITION_FAST2A_ID 121 // "Y:%x1 mm" +#define UI_TEXT_ACTION_YPOSITION_FAST2B_ID 122 // "Min:%sy Max:%sY" +#define UI_TEXT_ACTION_ZPOSITION_FAST2A_ID 123 // "Z:%x2 mm" +#define UI_TEXT_ACTION_ZPOSITION_FAST2B_ID 124 // "Min:%sz Max:%sZ" +#define UI_TEXT_FANSPEED_ID 125 // "Fan speed" +#define UI_TEXT_ACTION_FANSPEED_ID 126 // "Fan speed:%Fs%%%" +#define UI_TEXT_FAN_OFF_ID 127 // "Turn Fan Off" +#define UI_TEXT_FAN_25_ID 128 // "Set Fan 25%%%" +#define UI_TEXT_FAN_50_ID 129 // "Set Fan 50%%%" +#define UI_TEXT_FAN_75_ID 130 // "Set Fan 75%%%" +#define UI_TEXT_FAN_FULL_ID 131 // "Set Fan Full" +#define UI_TEXT_STEPPER_INACTIVE_ID 132 // "Stepper Inactive" +#define UI_TEXT_STEPPER_INACTIVE2A_ID 133 // "Dis. After: %is" +#define UI_TEXT_STEPPER_INACTIVE2B_ID 134 // "[min] 0=Off" +#define UI_TEXT_POWER_INACTIVE_ID 135 // "Max. Inactive" +#define UI_TEXT_POWER_INACTIVE2A_ID 136 // "Dis. After: %ip" +#define UI_TEXT_POWER_INACTIVE2B_ID 137 // "[min] 0=Off" +#define UI_TEXT_GENERAL_ID 138 // "General" +#define UI_TEXT_BAUDRATE_ID 139 // "Baudrate:%oc" +#define UI_TEXT_EXTR_STEPS_ID 140 // "Steps/MM:%Se" +#define UI_TEXT_EXTR_START_FEED_ID 141 // "Start FR:%Xf" +#define UI_TEXT_EXTR_MAX_FEED_ID 142 // "Max FR:%XF" +#define UI_TEXT_EXTR_ACCEL_ID 143 // "Accel:%XA" +#define UI_TEXT_EXTR_WATCH_ID 144 // "Stab.Time:%Xw" +#define UI_TEXT_EXTR_ADVANCE_L_ID 145 // "Advance lin:%Xl" +#define UI_TEXT_EXTR_ADVANCE_K_ID 146 // "Advance quad:%Xa" +#define UI_TEXT_EXTR_MANAGER_ID 147 // "Control:%Xh" +#define UI_TEXT_EXTR_PGAIN_ID 148 // "PID P:%Xp" +#define UI_TEXT_EXTR_DEADTIME_ID 149 // "Deadtime:%Xp" +#define UI_TEXT_EXTR_DMAX_DT_ID 150 // "Control PWM:%XM" +#define UI_TEXT_EXTR_IGAIN_ID 151 // "PID I:%Xi" +#define UI_TEXT_EXTR_DGAIN_ID 152 // "PID D:%Xd" +#define UI_TEXT_EXTR_DMIN_ID 153 // "Drive Min:%Xm" +#define UI_TEXT_EXTR_DMAX_ID 154 // "Drive Max:%XM" +#define UI_TEXT_EXTR_PMAX_ID 155 // "PID Max:%XD" +#define UI_TEXT_EXTR_XOFF_ID 156 // "X-Offset:%Xx" +#define UI_TEXT_EXTR_YOFF_ID 157 // "Y-Offset:%Xy" +#define UI_TEXT_STRING_HM_BANGBANG_ID 158 // "BangBang" +#define UI_TEXT_STRING_HM_PID_ID 159 // "PID" +#define UI_TEXT_STRING_ACTION_ID 160 // "Action:%la" +#define UI_TEXT_HEATING_EXTRUDER_ID 161// "Heating Extruder" +#define UI_TEXT_HEATING_BED_ID 162 // "Heating Bed" +#define UI_TEXT_KILLED_ID 163 // "Killed" +#define UI_TEXT_STEPPER_DISABLED_ID 164 // "Stepper Disabled" +#define UI_TEXT_EEPROM_STOREDA_ID 165 // "Configuration" +#define UI_TEXT_EEPROM_STOREDB_ID 166 // "stored in EEPROM" +#define UI_TEXT_EEPROM_LOADEDA_ID 167 // "Configuration" +#define UI_TEXT_EEPROM_LOADEDB_ID 168 // "loaded f. EEPROM" +#define UI_TEXT_UPLOADING_ID 169 // "Uploading..." +#define UI_TEXT_PAGE_BUFFER_ID 170 // "Buffer:%oB" +#define UI_TEXT_PAGE_EXTRUDER_ID 171 // " E:%ec/%Ec" cDEG "C" cARROW "%oC" +#define UI_TEXT_PAGE_EXTRUDER1_ID 172 // "E1:%e0/%E0" cDEG "C" cARROW "%o0" +#define UI_TEXT_PAGE_EXTRUDER2_ID 173 // "E2:%e1/%E1" cDEG "C" cARROW "%o1" +#define UI_TEXT_PAGE_EXTRUDER3_ID 174 // "E3:%e2/%E2" cDEG "C" cARROW "%o2" +#define UI_TEXT_PAGE_BED_ID 175 // " B:%eb/%Eb" cDEG "C" cARROW "%ob" +#define UI_TEXT_SPEED_MULTIPLY_ID 176 // "Speed Mul.:%om%%%" +#define UI_TEXT_FLOW_MULTIPLY_ID 177 // "Flow Mul. :%of%%%" +#define UI_TEXT_SHOW_MEASUREMENT_ID 178 // "Show meas." +#define UI_TEXT_RESET_MEASUREMENT_ID 179 // "Reset meas." +#define UI_TEXT_SET_MEASURED_ORIGIN_ID 180 // "Set Z=0" +#define UI_TEXT_ZCALIB_ID 181 // "Z Calib." +#define UI_TEXT_SET_P1_ID 182 // "Set P1" +#define UI_TEXT_SET_P2_ID 183 // "Set P2" +#define UI_TEXT_SET_P3_ID 184 // "Set P3" +#define UI_TEXT_CALCULATE_LEVELING_ID 185 // "Calculate Leveling" +#define UI_TEXT_LEVEL_ID 186 // "Level delta" +#define UI_TEXT_EXTR_WAIT_RETRACT_TEMP_ID 187 // "Wait Temp. %XT" cDEG "C" +#define UI_TEXT_EXTR_WAIT_RETRACT_UNITS_ID 188 // "Wait Units: %XU mm" +#define UI_TEXT_SD_REMOVED_ID 189 // "SD Card removed" +#define UI_TEXT_SD_INSERTED_ID 190 // "SD Card inserted" +#define UI_TEXT_PRINTER_READY_ID 191 // "Printer ready." +// Printtime output gets aggregated like UI_TEXT_PRINTTIME_DAYSUI_TEXT_PRINTTIME_HOURSUI_TEXT_PRINTTIME_MINUTES +// ___88 days 12:45 +#define UI_TEXT_PRINTTIME_DAYS_ID 192 // " days " +#define UI_TEXT_PRINTTIME_HOURS_ID 193 // ":" +#define UI_TEXT_PRINTTIME_MINUTES_ID 194 // "" +#define UI_TEXT_PRINT_TIME_ID 195 // "Printing time" +#define UI_TEXT_PRINT_FILAMENT_ID 196 // "Filament printed" +#define UI_TEXT_PRINTED_ID 197 // "printed" +#define UI_TEXT_POWER_ID 198 // "ATX power on/off" +#define UI_TEXT_STRING_HM_DEADTIME_ID 199 // "Dead Time" +#define UI_TEXT_STRING_HM_SLOWBANG_ID 200 // "SlowBang" +#define UI_TEXT_STOP_PRINT_ID 201 // "Stop Print" +#define UI_TEXT_Z_BABYSTEPPING_ID 202 // "Z Babystep.:%oYmm" +#define UI_TEXT_CHANGE_FILAMENT_ID 203 // "Change filament" +#define UI_TEXT_WIZ_CH_FILAMENT1_ID 204 // "Change filament" +#define UI_TEXT_WIZ_CH_FILAMENT2_ID 205 // "Rotate to move" +#define UI_TEXT_WIZ_CH_FILAMENT3_ID 206 // "filament up/down" +#define UI_TEXT_CLICK_DONE_ID 207 // "Click when done" +#define UI_TEXT_AUTOLEVEL_ONOFF_ID 208 // "Autolevel: %ll" +#define UI_TEXT_SERVOPOS_ID 209 // "Servo pos.: %oS" +#define UI_TEXT_IGNORE_M106_ID 210 // "Ignore M106 cmd %Fi" +#define UI_TEXT_WIZ_REHEAT1_ID 211 // "Click to reheat" +#define UI_TEXT_WIZ_REHEAT2_ID 212 // "extruders." +#define UI_TEXT_WIZ_WAITTEMP1_ID 213 // "Wait for target" +#define UI_TEXT_WIZ_WAITTEMP2_ID 214 // "temperatures ..." +#define UI_TEXT_EXTRUDER_JAM_ID 215 // "Extruder Jam" +#define UI_TEXT_STANDBY_ID 216 // "Standby" +#define UI_TEXT_BED_COATING_ID 217 // "Bed Coating" +#define UI_TEXT_BED_COATING_SET1_ID 218 // "Bed coating set to","" +#define UI_TEXT_BED_COATING_SET2_ID 219 // "Bed coating set to","" +#define UI_TEXT_NOCOATING_ID 220 // "No Coating" +#define UI_TEXT_BUILDTAK_ID 221 // "BuildTak" +#define UI_TEXT_KAPTON_ID 222 // "Kapton" +#define UI_TEXT_BLUETAPE_ID 223 // "Blue Paper Tape" +#define UI_TEXT_PETTAPE_ID 224 // "Green PET Tape" +#define UI_TEXT_GLUESTICK_ID 225 // "Glue Stick" +#define UI_TEXT_CUSTOM_ID 226 // "Custom" +#define UI_TEXT_COATING_CUSTOM_ID 227 // "Custom : %oCmm" +#define UI_TEXT_LANGUAGE_ID 228 // "Language" +#define UI_TEXT_MAINPAGE6_1_ID 229 //"\xa %e0/%E0\xb0 X:%x0" +#define UI_TEXT_MAINPAGE6_2_ID 230 //"\xa %e1/%E1\xb0 Y:%x1" +#define UI_TEXT_MAINPAGE6_3_ID 231 //"\xe %eb/%Eb\xb0 Z:%x2", +#define UI_TEXT_MAINPAGE6_4_ID 232 //"Mul: %om%%% \xfd E: %x4m" +#define UI_TEXT_MAINPAGE6_5_ID 233 //"Buf: %oB" +#define UI_TEXT_MAINPAGE6_6_ID 234 //"%os" +#define UI_TEXT_MAINPAGE_TEMP_BED_ID 235 //cTEMP "%ec/%Ec" cDEG "B%eB/%Eb" cDEG +#define UI_TEXT_MAINPAGE_BED_ID 236 //"B%eB/%Eb" cDEG +#define UI_TEXT_MAINPAGE_Z_BUF_ID 237 //"Z:%x2 Buf : %oB" +#define UI_TEXT_MAINPAGE_MUL_EUSAGE_ID 238 //"Mul: %om E:%x4" +#define UI_TEXT_MAINPAGE_XY_ID 239 //"X:%x0 Y:%x1" +#define UI_TEXT_PRINT_TIME_VALUE_ID 240 //"%Ut" +#define UI_TEXT_PRINT_FILAMENT_VALUE_ID 241 //"%Uf m" +#define UI_TEXT_METER_PRINTED_ID 242 //"%Uf m " UI_TEXT_PRINTED +#define UI_TEXT_STATUS_ID 243 //"%os" +#define UI_TEXT_EMPTY_ID 244 //"" +#define UI_TEXT_TEMP_SET_ID 245 //cTEMP "%ec/%Ec" cDEG +#define UI_TEXT_CURRENT_TEMP_ID 246 //cTEMP "%ec" cDEG +#define UI_TEXT_COATING_THICKNESS_ID 247 //" %oCmm" +#define UI_TEXT_EXTR3_TEMP_ID 248 // "Temp. 4 : %E3" cDEG "C" +#define UI_TEXT_EXTR4_TEMP_ID 249 // "Temp. 5 : %E4" cDEG "C" +#define UI_TEXT_EXTR5_TEMP_ID 250 // "Temp. 6 : %E5" cDEG "C" +#define UI_TEXT_EXTR3_OFF_ID 251 +#define UI_TEXT_EXTR4_OFF_ID 252 +#define UI_TEXT_EXTR5_OFF_ID 253 +#define UI_TEXT_EXTR3_SELECT_ID 254 +#define UI_TEXT_EXTR4_SELECT_ID 255 +#define UI_TEXT_EXTR5_SELECT_ID 256 +#define UI_TEXT_DITTO_0_ID 257 +#define UI_TEXT_DITTO_1_ID 258 +#define UI_TEXT_DITTO_2_ID 259 +#define UI_TEXT_DITTO_3_ID 260 +#define UI_TEXT_ZPROBE_HEIGHT_ID 261 +#define UI_TEXT_OFFSETS_ID 262 +#define UI_TEXT_X_OFFSET_ID 263 +#define UI_TEXT_Y_OFFSET_ID 264 +#define UI_TEXT_Z_OFFSET_ID 265 +#define UI_TEXT_DBG_ENDSTOP_ID 266 // "EndStop:%dp" + +// Universal definitions + +#define UI_TEXT_SEL cSEL +#define UI_TEXT_NOSEL cUNSEL + + +// At first all terms in english are defined. After that the selected language +// can overwrite the definition. That way new strings are at least in english +// available. + +#define UI_TEXT_ON_EN "On" +#define UI_TEXT_OFF_EN "Off" +#define UI_TEXT_NA_EN "N/A" // Output for not available +#define UI_TEXT_YES_EN "Yes" +#define UI_TEXT_NO_EN "No" +#define UI_TEXT_PRINT_POS_EN "Printing..." +#define UI_TEXT_PRINTING_EN "Printing" +#define UI_TEXT_IDLE_EN "Idle" +#define UI_TEXT_NOSDCARD_EN "No SD card" +#define UI_TEXT_ERROR_EN "**** ERROR ****" +#define UI_TEXT_BACK_EN "Back " cUP +#define UI_TEXT_QUICK_SETTINGS_EN "Quick settings" +#define UI_TEXT_ERRORMSG_EN "%oe" +#define UI_TEXT_CONFIGURATION_EN "Configuration" +#define UI_TEXT_POSITION_EN "Position" +#define UI_TEXT_EXTRUDER_EN "Extruder" +#define UI_TEXT_SD_CARD_EN "SD card" +#define UI_TEXT_DEBUGGING_EN "Debugging" +#define UI_TEXT_HOME_DELTA_EN "Home delta" +#define UI_TEXT_HOME_ALL_EN "Home all" +#define UI_TEXT_HOME_X_EN "Home X" +#define UI_TEXT_HOME_Y_EN "Home Y" +#define UI_TEXT_HOME_Z_EN "Home Z" +#define UI_TEXT_PREHEAT_PLA_EN "Preheat PLA" +#define UI_TEXT_PREHEAT_ABS_EN "Preheat ABS" +#define UI_TEXT_LIGHTS_ONOFF_EN "Lights:%lo" +#define UI_TEXT_COOLDOWN_EN "Cooldown" +#define UI_TEXT_SET_TO_ORIGIN_EN "Set to origin" +#define UI_TEXT_DISABLE_STEPPER_EN "Disable stepper" +#define UI_TEXT_X_POSITION_EN "X position" +#define UI_TEXT_X_POS_FAST_EN "X pos. fast" +#define UI_TEXT_Y_POSITION_EN "Y position" +#define UI_TEXT_Y_POS_FAST_EN "Y pos. fast" +#define UI_TEXT_Z_POSITION_EN "Z position" +#define UI_TEXT_Z_POS_FAST_EN "Z pos. fast" +#define UI_TEXT_E_POSITION_EN "Extr. position" +#define UI_TEXT_BED_TEMP_EN "Bed temp:%eb/%Eb" cDEG "C" +#define UI_TEXT_EXTR0_TEMP_EN "Temp. 1 :%e0/%E0" cDEG "C" +#define UI_TEXT_EXTR1_TEMP_EN "Temp. 2 :%e1/%E1" cDEG "C" +#define UI_TEXT_EXTR2_TEMP_EN "Temp. 3 :%e2/%E2" cDEG "C" +#define UI_TEXT_EXTR0_OFF_EN "Turn extr. 1 off" +#define UI_TEXT_EXTR1_OFF_EN "Turn extr. 2 off" +#define UI_TEXT_EXTR2_OFF_EN "Turn extr. 3 off" +#define UI_TEXT_EXTR0_SELECT_EN "%X0 Select extr. 1" +#define UI_TEXT_EXTR1_SELECT_EN "%X1 Select extr. 2" +#define UI_TEXT_EXTR2_SELECT_EN "%X2 Select extr. 3" +#define UI_TEXT_EXTR_ORIGIN_EN "Set Origin" +#define UI_TEXT_PRINT_X_EN "Print X:%ax" +#define UI_TEXT_PRINT_Y_EN "Print Y:%ay" +#define UI_TEXT_PRINT_Z_EN "Print Z:%az" +#define UI_TEXT_PRINT_Z_DELTA_EN "Print:%az" +#define UI_TEXT_MOVE_X_EN "Move X :%aX" +#define UI_TEXT_MOVE_Y_EN "Move Y :%aY" +#define UI_TEXT_MOVE_Z_EN "Move Z :%aZ" +#define UI_TEXT_MOVE_Z_DELTA_EN "Move:%aZ" +#define UI_TEXT_JERK_EN "Jerk :%aj" +#define UI_TEXT_ZJERK_EN "Z-Jerk :%aJ" +#define UI_TEXT_ACCELERATION_EN "Acceleration" +#define UI_TEXT_STORE_TO_EEPROM_EN "Store to EEPROM" +#define UI_TEXT_LOAD_EEPROM_EN "Load f. EEPROM" +#define UI_TEXT_DBG_ECHO_EN "Echo :%do" +#define UI_TEXT_DBG_INFO_EN "Info :%di" +#define UI_TEXT_DBG_ERROR_EN "Errors :%de" +#define UI_TEXT_DBG_DRYRUN_EN "Dry run:%dd" +#define UI_TEXT_DBG_ENDSTOP_EN "EndStop:%dp" +#define UI_TEXT_OPS_OFF_EN "%O0 OPS off" +#define UI_TEXT_OPS_CLASSIC_EN "%O1 OPS classic" +#define UI_TEXT_OPS_FAST_EN "%O2 OPS fast" +#define UI_TEXT_OPS_RETRACT_EN "Retract :%Or" +#define UI_TEXT_OPS_BACKSLASH_EN "Backsl. :%Ob" +#define UI_TEXT_OPS_MINDIST_EN "Min.dist :%Od" +#define UI_TEXT_OPS_MOVE_AFTER_EN "Move after:%Oa" +#define UI_TEXT_ANTI_OOZE_EN "Anti ooze" +#define UI_TEXT_PRINT_FILE_EN "Print file" +#define UI_TEXT_PAUSE_PRINT_EN "Pause print" +#define UI_TEXT_CONTINUE_PRINT_EN "Continue print" +#define UI_TEXT_UNMOUNT_CARD_EN "Unmount card" +#define UI_TEXT_MOUNT_CARD_EN "Mount card" +#define UI_TEXT_DELETE_FILE_EN "Delete file" +#define UI_TEXT_FEEDRATE_EN "Feedrate" +#define UI_TEXT_FEED_MAX_X_EN "Max X:%fx" +#define UI_TEXT_FEED_MAX_Y_EN "Max Y:%fy" +#define UI_TEXT_FEED_MAX_Z_EN "Max Z:%fz" +#define UI_TEXT_FEED_MAX_Z_DELTA_EN "Max:%fz" +#define UI_TEXT_FEED_HOME_X_EN "Home X:%fX" +#define UI_TEXT_FEED_HOME_Y_EN "Home Y:%fY" +#define UI_TEXT_FEED_HOME_Z_EN "Home Z:%fZ" +#define UI_TEXT_FEED_HOME_Z_DELTA_EN "Home:%fZ" +#define UI_TEXT_ACTION_XPOSITION4A_EN "X:%x0 mm %dx%dX" +#define UI_TEXT_ACTION_XPOSITION4B_EN "Min endstop:%sx" +#define UI_TEXT_ACTION_XPOSITION4C_EN "Max endstop:%sX" +#define UI_TEXT_ACTION_XPOSITION4D_EN "" +#define UI_TEXT_ACTION_YPOSITION4A_EN "Y:%x1 mm %dy%dY" +#define UI_TEXT_ACTION_YPOSITION4B_EN "Min endstop:%sy" +#define UI_TEXT_ACTION_YPOSITION4C_EN "Max endstop:%sY" +#define UI_TEXT_ACTION_YPOSITION4D_EN "" +#define UI_TEXT_ACTION_ZPOSITION4A_EN "Z:%x2 mm %dz%dZ" +#define UI_TEXT_ACTION_ZPOSITION4B_EN "Min endstop:%sz" +#define UI_TEXT_ACTION_ZPOSITION4C_EN "Max endstop:%sZ" +#define UI_TEXT_ACTION_ZPOSITION4D_EN "" +#define UI_TEXT_ACTION_XPOSITION_FAST4A_EN "X:%x0 mm" +#define UI_TEXT_ACTION_XPOSITION_FAST4B_EN "Min endstop:%sx" +#define UI_TEXT_ACTION_XPOSITION_FAST4C_EN "Max endstop:%sX" +#define UI_TEXT_ACTION_XPOSITION_FAST4D_EN "" +#define UI_TEXT_ACTION_YPOSITION_FAST4A_EN "Y:%x1 mm" +#define UI_TEXT_ACTION_YPOSITION_FAST4B_EN "Min endstop:%sy" +#define UI_TEXT_ACTION_YPOSITION_FAST4C_EN "Max endstop:%sY" +#define UI_TEXT_ACTION_YPOSITION_FAST4D_EN "" +#define UI_TEXT_ACTION_ZPOSITION_FAST4A_EN "Z:%x2 mm" +#define UI_TEXT_ACTION_ZPOSITION_FAST4B_EN "Min endstop:%sz" +#define UI_TEXT_ACTION_ZPOSITION_FAST4C_EN "Max endstop:%sZ" +#define UI_TEXT_ACTION_ZPOSITION_FAST4D_EN "" +#define UI_TEXT_ACTION_EPOSITION_FAST2A_EN "E:%x3 mm" +#define UI_TEXT_ACTION_EPOSITION_FAST2B_EN "1 click = 1 mm" +#define UI_TEXT_ACTION_XPOSITION2A_EN "X:%x0 mm" +#define UI_TEXT_ACTION_XPOSITION2B_EN "Min:%sx Max:%sX" +#define UI_TEXT_ACTION_YPOSITION2A_EN "Y:%x1 mm" +#define UI_TEXT_ACTION_YPOSITION2B_EN "Min:%sy Max:%sY" +#define UI_TEXT_ACTION_ZPOSITION2A_EN "Z:%x2 mm" +#define UI_TEXT_ACTION_ZPOSITION2B_EN "Min:%sz Max:%sZ" +#define UI_TEXT_ACTION_XPOSITION_FAST2A_EN "X:%x0 mm" +#define UI_TEXT_ACTION_XPOSITION_FAST2B_EN "Min:%sx Max:%sX" +#define UI_TEXT_ACTION_YPOSITION_FAST2A_EN "Y:%x1 mm" +#define UI_TEXT_ACTION_YPOSITION_FAST2B_EN "Min:%sy Max:%sY" +#define UI_TEXT_ACTION_ZPOSITION_FAST2A_EN "Z:%x2 mm" +#define UI_TEXT_ACTION_ZPOSITION_FAST2B_EN "Min:%sz Max:%sZ" +#define UI_TEXT_FANSPEED_EN "Fan speed" +#define UI_TEXT_ACTION_FANSPEED_EN "Fan speed:%Fs%%%" +#define UI_TEXT_FAN_OFF_EN "Turn fan Off" +#define UI_TEXT_FAN_25_EN "Set fan 25%%%" +#define UI_TEXT_FAN_50_EN "Set fan 50%%%" +#define UI_TEXT_FAN_75_EN "Set fan 75%%%" +#define UI_TEXT_FAN_FULL_EN "Set fan full" +#define UI_TEXT_STEPPER_INACTIVE_EN "Stepper inactive" +#define UI_TEXT_STEPPER_INACTIVE2A_EN "Dis. after: %is" +#define UI_TEXT_STEPPER_INACTIVE2B_EN "[min] 0=Off" +#define UI_TEXT_POWER_INACTIVE_EN "Max. inactive" +#define UI_TEXT_POWER_INACTIVE2A_EN "Dis. after: %ip" +#define UI_TEXT_POWER_INACTIVE2B_EN "[min] 0=Off" +#define UI_TEXT_GENERAL_EN "General" +#define UI_TEXT_BAUDRATE_EN "Baudrate:%oc" +#define UI_TEXT_EXTR_STEPS_EN "Steps/MM:%Se" +#define UI_TEXT_EXTR_START_FEED_EN "Start FR:%Xf" +#define UI_TEXT_EXTR_MAX_FEED_EN "Max FR:%XF" +#define UI_TEXT_EXTR_ACCEL_EN "Accel:%XA" +#define UI_TEXT_EXTR_WATCH_EN "Stab.Time:%Xw" +#define UI_TEXT_EXTR_ADVANCE_L_EN "Advance lin:%Xl" +#define UI_TEXT_EXTR_ADVANCE_K_EN "Advance quad:%Xa" +#define UI_TEXT_EXTR_MANAGER_EN "Control:%Xh" +#define UI_TEXT_EXTR_PGAIN_EN "PID P:%Xp" +#define UI_TEXT_EXTR_DEADTIME_EN "Deadtime:%Xp" +#define UI_TEXT_EXTR_DMAX_DT_EN "Control PWM:%XM" +#define UI_TEXT_EXTR_IGAIN_EN "PID I:%Xi" +#define UI_TEXT_EXTR_DGAIN_EN "PID D:%Xd" +#define UI_TEXT_EXTR_DMIN_EN "Drive Min:%Xm" +#define UI_TEXT_EXTR_DMAX_EN "Drive Max:%XM" +#define UI_TEXT_EXTR_PMAX_EN "PID Max:%XD" +#define UI_TEXT_EXTR_XOFF_EN "X-Offset:%Xx" +#define UI_TEXT_EXTR_YOFF_EN "Y-Offset:%Xy" +#define UI_TEXT_STRING_HM_BANGBANG_EN "BangBang" +#define UI_TEXT_STRING_HM_PID_EN "PID" +#define UI_TEXT_STRING_ACTION_EN "Action:%la" +#define UI_TEXT_HEATING_EXTRUDER_EN "Heating extruder" +#define UI_TEXT_HEATING_BED_EN "Heating bed" +#define UI_TEXT_KILLED_EN "Killed" +#define UI_TEXT_STEPPER_DISABLED_EN "Stepper disabled" +#define UI_TEXT_EEPROM_STOREDA_EN "Configuration" +#define UI_TEXT_EEPROM_STOREDB_EN "stored in EEPROM" +#define UI_TEXT_EEPROM_LOADEDA_EN "Configuration" +#define UI_TEXT_EEPROM_LOADEDB_EN "loaded f. EEPROM" +#define UI_TEXT_UPLOADING_EN "Uploading..." +#define UI_TEXT_PAGE_BUFFER_EN "Buffer:%oB" +#define UI_TEXT_PAGE_EXTRUDER_EN " E:%ec/%Ec" cDEG "C" cARROW "%oC" +#define UI_TEXT_PAGE_EXTRUDER1_EN "E1:%e0/%E0" cDEG "C" cARROW "%o0" +#define UI_TEXT_PAGE_EXTRUDER2_EN "E2:%e1/%E1" cDEG "C" cARROW "%o1" +#define UI_TEXT_PAGE_EXTRUDER3_EN "E3:%e2/%E2" cDEG "C" cARROW "%o2" +#define UI_TEXT_PAGE_BED_EN " B:%eb/%Eb" cDEG "C" cARROW "%ob" +#define UI_TEXT_SPEED_MULTIPLY_EN "Speed mul.:%om%%%" +#define UI_TEXT_FLOW_MULTIPLY_EN "Flow mul. :%of%%%" +#define UI_TEXT_SHOW_MEASUREMENT_EN "Show meas." +#define UI_TEXT_RESET_MEASUREMENT_EN "Reset meas." +#define UI_TEXT_SET_MEASURED_ORIGIN_EN "Set Z=0" +#define UI_TEXT_ZCALIB_EN "Z calib." +#define UI_TEXT_SET_P1_EN "Set P1" +#define UI_TEXT_SET_P2_EN "Set P2" +#define UI_TEXT_SET_P3_EN "Set P3" +#define UI_TEXT_CALCULATE_LEVELING_EN "Calculate leveling" +#define UI_TEXT_LEVEL_EN "Level delta" +#define UI_TEXT_EXTR_WAIT_RETRACT_TEMP_EN "Wait temp. %XT" cDEG "C" +#define UI_TEXT_EXTR_WAIT_RETRACT_UNITS_EN "Wait retr.:%XU mm" +#define UI_TEXT_SD_REMOVED_EN "SD card removed" +#define UI_TEXT_SD_INSERTED_EN "SD card inserted" +#define UI_TEXT_PRINTER_READY_EN "Printer ready." +// Printtime output gets aggregated like UI_TEXT_PRINTTIME_DAYSUI_TEXT_PRINTTIME_HOURSUI_TEXT_PRINTTIME_MINUTES +// ___88 days 12:45 +#define UI_TEXT_PRINTTIME_DAYS_EN " days " +#define UI_TEXT_PRINTTIME_HOURS_EN ":" +#define UI_TEXT_PRINTTIME_MINUTES_EN "" +#define UI_TEXT_PRINT_TIME_EN "Printing time" +#define UI_TEXT_PRINT_FILAMENT_EN "Filament printed" +#define UI_TEXT_PRINTED_EN "printed" +#define UI_TEXT_POWER_EN "ATX power on/off" +#define UI_TEXT_STRING_HM_DEADTIME_EN "Dead time" +#define UI_TEXT_STRING_HM_SLOWBANG_EN "SlowBang" +#define UI_TEXT_STOP_PRINT_EN "Stop Print" +#define UI_TEXT_Z_BABYSTEPPING_EN "Z babystep.:%oYmm" +#define UI_TEXT_CHANGE_FILAMENT_EN "Change filament" +#define UI_TEXT_WIZ_CH_FILAMENT1_EN "Change filament" +#define UI_TEXT_WIZ_CH_FILAMENT2_EN "Rotate to move" +#define UI_TEXT_WIZ_CH_FILAMENT3_EN "filament up/down" +#define UI_TEXT_CLICK_DONE_EN "Click when done" +#define UI_TEXT_AUTOLEVEL_ONOFF_EN "Autolevel: %ll" +#define UI_TEXT_SERVOPOS_EN "Servo pos.: %oS" +#define UI_TEXT_IGNORE_M106_EN "Ignore M106 cmd %Fi" +#define UI_TEXT_WIZ_REHEAT1_EN "Click to reheat" +#define UI_TEXT_WIZ_REHEAT2_EN "extruders." +#define UI_TEXT_WIZ_WAITTEMP1_EN "Wait for target" +#define UI_TEXT_WIZ_WAITTEMP2_EN "temperatures ..." +#define UI_TEXT_EXTRUDER_JAM_EN "Extruder jam" +#define UI_TEXT_STANDBY_EN "Standby" +#define UI_TEXT_BED_COATING_EN "Bed coating" +#define UI_TEXT_BED_COATING_SET1_EN "Bed coating set to" +#define UI_TEXT_BED_COATING_SET2_EN "" +#define UI_TEXT_NOCOATING_EN "No coating" +#define UI_TEXT_BUILDTAK_EN "BuildTak" +#define UI_TEXT_KAPTON_EN "Kapton" +#define UI_TEXT_BLUETAPE_EN "Blue paper tape" +#define UI_TEXT_PETTAPE_EN "Green PET tape" +#define UI_TEXT_GLUESTICK_EN "Glue stick" +#define UI_TEXT_CUSTOM_EN "Custom" +#define UI_TEXT_COATING_CUSTOM_EN "Custom:%BCmm" +#define UI_TEXT_LANGUAGE_EN "Language" + +#if NUM_EXTRUDER > 2 || MIXING_EXTRUDER != 0 +#define UI_TEXT_MAINPAGE6_1_EN "\xa %ec/%Ec\xb0 X:%x0" +#else +#define UI_TEXT_MAINPAGE6_1_EN "\xa %e0/%E0\xb0 X:%x0" +#endif // NUM_EXTRUDER +#if NUM_EXTRUDER == 2 && MIXING_EXTRUDER == 0 +#define UI_TEXT_MAINPAGE6_2_EN "\xa %e1/%E1\xb0 Y:%x1" +#elif HAVE_HEATED_BED +#define UI_TEXT_MAINPAGE6_2_EN "\xe %eb/%Eb\xb0 Y:%x1" +#else +#define UI_TEXT_MAINPAGE6_2_EN " Y:%x1" +#endif +#if HAVE_HEATED_BED && NUM_EXTRUDER == 2 && MIXING_EXTRUDER == 0 +#define UI_TEXT_MAINPAGE6_3_EN "\xe %eb/%Eb\xb0 Z:%x2" +#elif FEATURE_DITTO_PRINTING +#define UI_TEXT_MAINPAGE6_3_EN "Copies: %ed Z:%x2" +#else +#define UI_TEXT_MAINPAGE6_3_EN "Flow:\xfd %of%%% Z:%x2" +#endif +#define UI_TEXT_MAINPAGE6_4_EN "Mul: %om%%% \xfd E: %x4m" +#define UI_TEXT_MAINPAGE6_5_EN "Buf: %oB" +#define UI_TEXT_MAINPAGE6_6_EN "%os" +#define UI_TEXT_MAINPAGE_TEMP_BED_EN cTEMP "%ec/%Ec" cDEG "B%eB/%Eb" cDEG +#define UI_TEXT_MAINPAGE_BED_EN "B%eB/%Eb" cDEG +#define UI_TEXT_MAINPAGE_Z_BUF_EN "Z:%x2 Buf : %oB" +#define UI_TEXT_MAINPAGE_MUL_EUSAGE_EN "Mul: %om E:%x4" +#define UI_TEXT_MAINPAGE_XY_EN "X:%x0 Y:%x1" +#define UI_TEXT_PRINT_TIME_VALUE_EN "%Ut" +#define UI_TEXT_PRINT_FILAMENT_VALUE_EN "%Uf m" +#define UI_TEXT_METER_PRINTED_EN "%Uf m " UI_TEXT_PRINTED_EN +#define UI_TEXT_STATUS_EN "%os" +#define UI_TEXT_EMPTY_EN "" +#define UI_TEXT_TEMP_SET_EN cTEMP "%ec/%Ec" cDEG +#define UI_TEXT_CURRENT_TEMP_EN cTEMP "%ec" cDEG +#define UI_TEXT_COATING_THICKNESS_EN " %BCmm" +#define UI_TEXT_EXTR3_TEMP_EN "Temp. 4 :%e3/%E3" cDEG "C" +#define UI_TEXT_EXTR4_TEMP_EN "Temp. 5 :%e4/%E4" cDEG "C" +#define UI_TEXT_EXTR5_TEMP_EN "Temp. 6 :%e5/%E5" cDEG "C" +#define UI_TEXT_EXTR3_OFF_EN "Turn extr. 4 off" +#define UI_TEXT_EXTR4_OFF_EN "Turn extr. 5 off" +#define UI_TEXT_EXTR5_OFF_EN "Turn extr. 6 off" +#define UI_TEXT_EXTR3_SELECT_EN "%X3 Select extr. 4" +#define UI_TEXT_EXTR4_SELECT_EN "%X4 Select extr. 5" +#define UI_TEXT_EXTR5_SELECT_EN "%X5 Select extr. 6" +#define UI_TEXT_DITTO_0_EN "%D0 No copies" +#define UI_TEXT_DITTO_1_EN "%D1 1 copy" +#define UI_TEXT_DITTO_2_EN "%D2 2 copies" +#define UI_TEXT_DITTO_3_EN "%D3 3 copies" +#define UI_TEXT_ZPROBE_HEIGHT_EN "Z-probe height:%zh" + +#define UI_TEXT_OFFSETS_EN "Set print offsets" +#define UI_TEXT_X_OFFSET_EN "Set X offset:%T0mm" +#define UI_TEXT_Y_OFFSET_EN "Set Y offset:%T1mm" +#define UI_TEXT_Z_OFFSET_EN "Set Z offset:%T2mm" + + + +// *************** German translation **************** + +#define UI_TEXT_ON_DE "An" +#define UI_TEXT_OFF_DE "Aus" +#define UI_TEXT_NA_DE "nv" +#define UI_TEXT_YES_DE "Ja" +#define UI_TEXT_NO_DE "Nein" +#define UI_TEXT_PRINT_POS_DE "Drucke..." +#define UI_TEXT_PRINTING_DE "Drucken" +#define UI_TEXT_IDLE_DE "Leerlauf" +#define UI_TEXT_NOSDCARD_DE "Keine SD Karte" +#define UI_TEXT_ERROR_DE "**** FEHLER ****" +#define UI_TEXT_BACK_DE "Zur" STR_uuml "ck " cUP +#define UI_TEXT_QUICK_SETTINGS_DE "Schnelleinst." +#define UI_TEXT_ERRORMSG_DE "%oe" +#define UI_TEXT_CONFIGURATION_DE "Konfiguration" +#define UI_TEXT_POSITION_DE "Position" +#define UI_TEXT_EXTRUDER_DE "Extruder" +#define UI_TEXT_SD_CARD_DE "SD Karte" +#define UI_TEXT_DEBUGGING_DE "Debugging" +#define UI_TEXT_HOME_DELTA_DE "Home Delta" +#define UI_TEXT_HOME_ALL_DE "Home Alle" +#define UI_TEXT_HOME_X_DE "Home X" +#define UI_TEXT_HOME_Y_DE "Home Y" +#define UI_TEXT_HOME_Z_DE "Home Z" +#define UI_TEXT_PREHEAT_PLA_DE "Vorheizen PLA" +#define UI_TEXT_PREHEAT_ABS_DE "Vorheizen ABS" +#define UI_TEXT_LIGHTS_ONOFF_DE "Lampen: %lo" +#define UI_TEXT_COOLDOWN_DE "Abk" STR_uuml "hlen" +#define UI_TEXT_SET_TO_ORIGIN_DE "Setze Nullpunkt" +#define UI_TEXT_DISABLE_STEPPER_DE "Motoren Aussch." +#define UI_TEXT_X_POSITION_DE "X Position" +#define UI_TEXT_X_POS_FAST_DE "X Pos. Schnell" +#define UI_TEXT_Y_POSITION_DE "Y Position" +#define UI_TEXT_Y_POS_FAST_DE "Y Pos. Schnell" +#define UI_TEXT_Z_POSITION_DE "Z Position" +#define UI_TEXT_Z_POS_FAST_DE "Z Pos. Schnell" +#define UI_TEXT_E_POSITION_DE "Extr. Position" +#define UI_TEXT_BED_TEMP_DE "Bed Temp:%eb/%Eb" cDEG "C" +#define UI_TEXT_EXTR0_TEMP_DE "Temp. 1 :%e0/%E0" cDEG "C" +#define UI_TEXT_EXTR1_TEMP_DE "Temp. 2 :%e1/%E1" cDEG "C" +#define UI_TEXT_EXTR2_TEMP_DE "Temp. 3 :%e2/%E2" cDEG "C" +#define UI_TEXT_EXTR0_OFF_DE "Extruder 1 Aus" +#define UI_TEXT_EXTR1_OFF_DE "Extruder 2 Aus" +#define UI_TEXT_EXTR2_OFF_DE "Extruder 3 Aus" +#define UI_TEXT_EXTR0_SELECT_DE "%X0 W" STR_auml "hle Extr. 1" +#define UI_TEXT_EXTR1_SELECT_DE "%X1 W" STR_auml "hle Extr. 2" +#define UI_TEXT_EXTR2_SELECT_DE "%X2 W" STR_auml "hle Extr. 3" +#define UI_TEXT_EXTR_ORIGIN_DE "Setze Nullpunkt" +#define UI_TEXT_PRINT_X_DE "Drucken X:%ax" +#define UI_TEXT_PRINT_Y_DE "Drucken Y:%ay" +#define UI_TEXT_PRINT_Z_DE "Drucken Z:%az" +#define UI_TEXT_PRINT_Z_DELTA_DE "Drucken:%az" +#define UI_TEXT_MOVE_X_DE "Bewegen X:%aX" +#define UI_TEXT_MOVE_Y_DE "Bewegen Y:%aY" +#define UI_TEXT_MOVE_Z_DE "Bewegen Z:%aZ" +#define UI_TEXT_MOVE_Z_DELTA_DE "Bewegen:%aZ" +#define UI_TEXT_JERK_DE "Ruck :%aj" +#define UI_TEXT_ZJERK_DE "Z-Ruck :%aJ" +#define UI_TEXT_ACCELERATION_DE "Beschleunigung" +#define UI_TEXT_STORE_TO_EEPROM_DE "Sichere EEPROM" +#define UI_TEXT_LOAD_EEPROM_DE "Lade vom EEPROM" +#define UI_TEXT_DBG_ECHO_DE "Echo :%do" +#define UI_TEXT_DBG_INFO_DE "Info :%di" +#define UI_TEXT_DBG_ERROR_DE "Fehler :%de" +#define UI_TEXT_DBG_DRYRUN_DE "Trockenlauf:%dd" +#define UI_TEXT_DBG_ENDSTOP_DE "EndStop :%dp" +#define UI_TEXT_OPS_OFF_DE "%O0 OPS Aus" +#define UI_TEXT_OPS_CLASSIC_DE "%O1 OPS Klassisch" +#define UI_TEXT_OPS_FAST_DE "%O2 OPS Schnell" +#define UI_TEXT_OPS_RETRACT_DE "Einfahren :%Or" +#define UI_TEXT_OPS_BACKSLASH_DE "Backsl. :%Ob" +#define UI_TEXT_OPS_MINDIST_DE "Min.Abst. :%Od" +#define UI_TEXT_OPS_MOVE_AFTER_DE "Start nach:%Oa" +#define UI_TEXT_ANTI_OOZE_DE "Anti Ooze" +#define UI_TEXT_PRINT_FILE_DE "Drucke Datei" +#define UI_TEXT_PAUSE_PRINT_DE "Druck Pausieren" +#define UI_TEXT_CONTINUE_PRINT_DE "Druck Forts." +#define UI_TEXT_UNMOUNT_CARD_DE "Unmount Karte" +#define UI_TEXT_MOUNT_CARD_DE "Mount Karte" +#define UI_TEXT_DELETE_FILE_DE "Datei l" STR_ouml "schen" +#define UI_TEXT_FEEDRATE_DE "Feedrate" +#define UI_TEXT_FEED_MAX_X_DE "Max X:%fx" +#define UI_TEXT_FEED_MAX_Y_DE "Max Y:%fy" +#define UI_TEXT_FEED_MAX_Z_DE "Max Z:%fz" +#define UI_TEXT_FEED_MAX_Z_DELTA_DE "Max:%fz" +#define UI_TEXT_FEED_HOME_X_DE "Home X:%fX" +#define UI_TEXT_FEED_HOME_Y_DE "Home Y:%fY" +#define UI_TEXT_FEED_HOME_Z_DE "Home Z:%fZ" +#define UI_TEXT_FEED_HOME_Z_DELTA_DE "Home:%fZ" +#define UI_TEXT_ACTION_XPOSITION4A_DE "X:%x0 mm %dx%dX" +#define UI_TEXT_ACTION_XPOSITION4B_DE "Min Endstopp:%sx" +#define UI_TEXT_ACTION_XPOSITION4C_DE "Max Endstopp:%sX" +#define UI_TEXT_ACTION_XPOSITION4D_DE "" +#define UI_TEXT_ACTION_YPOSITION4A_DE "Y:%x1 mm %dy%dY" +#define UI_TEXT_ACTION_YPOSITION4B_DE "Min Endstopp:%sy" +#define UI_TEXT_ACTION_YPOSITION4C_DE "Max Endstopp:%sY" +#define UI_TEXT_ACTION_YPOSITION4D_DE "" +#define UI_TEXT_ACTION_ZPOSITION4A_DE "Z:%x2 mm %dz%dZ" +#define UI_TEXT_ACTION_ZPOSITION4B_DE "Min Endstopp:%sz" +#define UI_TEXT_ACTION_ZPOSITION4C_DE "Max Endstopp:%sZ" +#define UI_TEXT_ACTION_ZPOSITION4D_DE "" +#define UI_TEXT_ACTION_XPOSITION_FAST4A_DE "X:%x0 mm" +#define UI_TEXT_ACTION_XPOSITION_FAST4B_DE "Min Endstopp:%sx" +#define UI_TEXT_ACTION_XPOSITION_FAST4C_DE "Max Endstopp:%sX" +#define UI_TEXT_ACTION_XPOSITION_FAST4D_DE "" +#define UI_TEXT_ACTION_YPOSITION_FAST4A_DE "Y:%x1 mm" +#define UI_TEXT_ACTION_YPOSITION_FAST4B_DE "Min Endstopp:%sy" +#define UI_TEXT_ACTION_YPOSITION_FAST4C_DE "Max Endstopp:%sY" +#define UI_TEXT_ACTION_YPOSITION_FAST4D_DE "" +#define UI_TEXT_ACTION_ZPOSITION_FAST4A_DE "Z:%x2 mm" +#define UI_TEXT_ACTION_ZPOSITION_FAST4B_DE "Min Endstopp:%sz" +#define UI_TEXT_ACTION_ZPOSITION_FAST4C_DE "Max Endstopp:%sZ" +#define UI_TEXT_ACTION_ZPOSITION_FAST4D_DE "" +#define UI_TEXT_ACTION_EPOSITION_FAST2A_DE "E:%x3 mm" +#define UI_TEXT_ACTION_EPOSITION_FAST2B_DE "1 klick = 1 mm" +#define UI_TEXT_ACTION_XPOSITION2A_DE "X:%x0 mm" +#define UI_TEXT_ACTION_XPOSITION2B_DE "Min:%sx Max:%sX" +#define UI_TEXT_ACTION_YPOSITION2A_DE "Y:%x1 mm" +#define UI_TEXT_ACTION_YPOSITION2B_DE "Min:%sy Max:%sY" +#define UI_TEXT_ACTION_ZPOSITION2A_DE "Z:%x2 mm" +#define UI_TEXT_ACTION_ZPOSITION2B_DE "Min:%sz Max:%sZ" +#define UI_TEXT_ACTION_XPOSITION_FAST2A_DE "X:%x0 mm" +#define UI_TEXT_ACTION_XPOSITION_FAST2B_DE "Min:%sx Max:%sX" +#define UI_TEXT_ACTION_YPOSITION_FAST2A_DE "Y:%x1 mm" +#define UI_TEXT_ACTION_YPOSITION_FAST2B_DE "Min:%sy Max:%sY" +#define UI_TEXT_ACTION_ZPOSITION_FAST2A_DE "Z:%x2 mm" +#define UI_TEXT_ACTION_ZPOSITION_FAST2B_DE "Min:%sz Max:%sZ" +#define UI_TEXT_FANSPEED_DE "L" STR_uuml "fter" +#define UI_TEXT_ACTION_FANSPEED_DE "L" STR_uuml "fter:%Fs%%%" +#define UI_TEXT_FAN_OFF_DE "L" STR_uuml "fter Aus" +#define UI_TEXT_FAN_25_DE "L" STR_uuml "fter auf 25%%%" +#define UI_TEXT_FAN_50_DE "L" STR_uuml "fter auf 50%%%" +#define UI_TEXT_FAN_75_DE "L" STR_uuml "fter auf 75%%%" +#define UI_TEXT_FAN_FULL_DE "L" STR_uuml "fter Voll" +#define UI_TEXT_STEPPER_INACTIVE_DE "Motor Inaktiv" +#define UI_TEXT_STEPPER_INACTIVE2A_DE "Aus nach: %is" +#define UI_TEXT_STEPPER_INACTIVE2B_DE "[min] 0=Aus" +#define UI_TEXT_POWER_INACTIVE_DE "Max. Inaktiv" +#define UI_TEXT_POWER_INACTIVE2A_DE "Aus nach: %ip" +#define UI_TEXT_POWER_INACTIVE2B_DE "[min] 0=Aus" +#define UI_TEXT_GENERAL_DE "Allgemein" +#define UI_TEXT_BAUDRATE_DE "Baudrate:%oc" +#define UI_TEXT_EXTR_STEPS_DE "Schr/MM:%Se" +#define UI_TEXT_EXTR_START_FEED_DE "Start FR:%Xf" +#define UI_TEXT_EXTR_MAX_FEED_DE "Max FR:%XF" +#define UI_TEXT_EXTR_ACCEL_DE "Beschl.:%XA" +#define UI_TEXT_EXTR_WATCH_DE "Stab.Zeit:%Xw" +#define UI_TEXT_EXTR_ADVANCE_L_DE "Advance lin:%Xl" +#define UI_TEXT_EXTR_ADVANCE_K_DE "Advance quad:%Xa" +#define UI_TEXT_EXTR_MANAGER_DE "Regler:%Xh" +#define UI_TEXT_EXTR_PGAIN_DE "PID P:%Xp" +#define UI_TEXT_EXTR_DEADTIME_DE "Totzeit:%Xp" +#define UI_TEXT_EXTR_DMAX_DT_DE "Controll-PWM:%XM" +#define UI_TEXT_EXTR_IGAIN_DE "PID I:%Xi" +#define UI_TEXT_EXTR_DGAIN_DE "PID D:%Xd" +#define UI_TEXT_EXTR_DMIN_DE "Drive Min:%Xm" +#define UI_TEXT_EXTR_DMAX_DE "Drive Max:%XM" +#define UI_TEXT_EXTR_PMAX_DE "PID Max:%XD" +#define UI_TEXT_EXTR_XOFF_DE "X-Offset:%Xx" +#define UI_TEXT_EXTR_YOFF_DE "Y-Offset:%Xy" +#define UI_TEXT_STRING_HM_BANGBANG_DE "BangBang" +#define UI_TEXT_STRING_HM_PID_DE "PID" +#define UI_TEXT_STRING_ACTION_DE "Aktion:%la" +#define UI_TEXT_HEATING_EXTRUDER_DE "Heize Extruder" +#define UI_TEXT_HEATING_BED_DE "Heize Druckbett" +#define UI_TEXT_KILLED_DE "Angehalten" +#define UI_TEXT_STEPPER_DISABLED_DE "Motoren Aus" +#define UI_TEXT_EEPROM_STOREDA_DE "Konfiguration" +#define UI_TEXT_EEPROM_STOREDB_DE "gespeichert." +#define UI_TEXT_EEPROM_LOADEDA_DE "Konfiguration" +#define UI_TEXT_EEPROM_LOADEDB_DE "geladen." +#define UI_TEXT_UPLOADING_DE "Hochladen..." +#define UI_TEXT_PAGE_BUFFER_DE "Puffer:%oB" +#define UI_TEXT_PAGE_EXTRUDER_DE " E:%ec/%Ec" cDEG "C" cARROW "%oC" +#define UI_TEXT_PAGE_EXTRUDER1_DE "E1:%e0/%E0" cDEG "C" cARROW "%o0" +#define UI_TEXT_PAGE_EXTRUDER2_DE "E2:%e1/%E1" cDEG "C" cARROW "%o1" +#define UI_TEXT_PAGE_EXTRUDER3_DE "E3:%e2/%E2" cDEG "C" cARROW "%o2" +#define UI_TEXT_PAGE_BED_DE " B:%eb/%Eb" cDEG "C" cARROW "%ob" +#define UI_TEXT_SPEED_MULTIPLY_DE "Geschw.Mul:%om%%%" +#define UI_TEXT_FLOW_MULTIPLY_DE "Flow Mul.:%of%%%" +#define UI_TEXT_SHOW_MEASUREMENT_DE "Zeige Messung" +#define UI_TEXT_RESET_MEASUREMENT_DE "Reset Messung" +#define UI_TEXT_SET_MEASURED_ORIGIN_DE "Setze Z=0" +#define UI_TEXT_ZCALIB_DE "Z Kalib." +#define UI_TEXT_SET_P1_DE "Setze P1" +#define UI_TEXT_SET_P2_DE "Setze P2" +#define UI_TEXT_SET_P3_DE "Setze P3" +#define UI_TEXT_CALCULATE_LEVELING_DE "Berechne Leveling" +#define UI_TEXT_LEVEL_DE "Level delta" +#define UI_TEXT_EXTR_WAIT_RETRACT_TEMP_DE "Wartetemp.%XT" cDEG "C" +#define UI_TEXT_EXTR_WAIT_RETRACT_UNITS_DE "R" STR_uuml "ckz. um:%XU mm" +#define UI_TEXT_SD_REMOVED_DE "SD Karte entfernt" +#define UI_TEXT_SD_INSERTED_DE "SD Karte eingelegt" +#define UI_TEXT_PRINTER_READY_DE "Drucker bereit." +// Printtime output gets aggregated like UI_TEXT_PRINTTIME_DAYSUI_TEXT_PRINTTIME_HOURSUI_TEXT_PRINTTIME_MINUTES +// ___88 days 12:45 +#define UI_TEXT_PRINTTIME_DAYS_DE " Tage " +#define UI_TEXT_PRINTTIME_HOURS_DE ":" +#define UI_TEXT_PRINTTIME_MINUTES_DE "" +#define UI_TEXT_PRINT_TIME_DE "Ges. Druckzeit" +#define UI_TEXT_PRINT_FILAMENT_DE "Filament gedruckt" +#define UI_TEXT_PRINTED_DE "gedruckt" +#define UI_TEXT_POWER_DE "ATX Netzteil an/aus" +#define UI_TEXT_STRING_HM_DEADTIME_DE "Totzeit" +#define UI_TEXT_STRING_HM_SLOWBANG_DE "Langs.BB" +#define UI_TEXT_STOP_PRINT_DE "Druck abbrechen" +#define UI_TEXT_Z_BABYSTEPPING_DE "Z Babyschr.:%oYmm" +#define UI_TEXT_CHANGE_FILAMENT_DE "Filamentwechsel" +#define UI_TEXT_WIZ_CH_FILAMENT1_DE "Filamentwechsel:" +#define UI_TEXT_WIZ_CH_FILAMENT2_DE "Zum man. f" STR_ouml "rdern" +#define UI_TEXT_WIZ_CH_FILAMENT3_DE "Men" STR_uuml "knopf drehen" +#define UI_TEXT_CLICK_DONE_DE "Weiter mit Klick" +#define UI_TEXT_AUTOLEVEL_ONOFF_DE "Autolevel: %ll" +#define UI_TEXT_SERVOPOS_DE "Servo Pos.: %oS" +#define UI_TEXT_IGNORE_M106_DE "Ignoriere M106 %Fi" +#define UI_TEXT_WIZ_REHEAT1_DE "Klicke zum Aufw" STR_auml "rmen" +#define UI_TEXT_WIZ_REHEAT2_DE "der Extruder." +#define UI_TEXT_WIZ_WAITTEMP1_DE "Warte auf" +#define UI_TEXT_WIZ_WAITTEMP2_DE "Zieltemperatur..." +#define UI_TEXT_EXTRUDER_JAM_DE "Extruderstau" +#define UI_TEXT_STANDBY_DE "Standby" +#define UI_TEXT_BED_COATING_DE "Bettbeschichtung" +#define UI_TEXT_BED_COATING_SET1_DE "Bettbeschichtung:" +#define UI_TEXT_BED_COATING_SET2_DE "" +#define UI_TEXT_NOCOATING_DE "Unbeschichtet" +#define UI_TEXT_BUILDTAK_DE "BuildTak" +#define UI_TEXT_KAPTON_DE "Kapton" +#define UI_TEXT_BLUETAPE_DE "Blaues Kreppband" +#define UI_TEXT_PETTAPE_DE "Gr" STR_uuml "nes PET Band" +#define UI_TEXT_GLUESTICK_DE "Klebestift" +#define UI_TEXT_CUSTOM_DE "Individuell" +#define UI_TEXT_COATING_CUSTOM_DE "Indiv.:%BCmm" +#define UI_TEXT_LANGUAGE_DE "Sprache" + +#if NUM_EXTRUDER > 2 || MIXING_EXTRUDER != 0 +#define UI_TEXT_MAINPAGE6_1_DE "\xa %ec/%Ec\xb0 X:%x0" +#else +#define UI_TEXT_MAINPAGE6_1_DE "\xa %e0/%E0\xb0 X:%x0" +#endif // NUM_EXTRUDER +#if NUM_EXTRUDER == 2 && MIXING_EXTRUDER == 0 +#define UI_TEXT_MAINPAGE6_2_DE "\xa %e1/%E1\xb0 Y:%x1" +#elif HAVE_HEATED_BED +#define UI_TEXT_MAINPAGE6_2_DE "\xe %eb/%Eb\xb0 Y:%x1" +#else +#define UI_TEXT_MAINPAGE6_2_DE " Y:%x1" +#endif +#if HAVE_HEATED_BED && NUM_EXTRUDER == 2 && MIXING_EXTRUDER == 0 +#define UI_TEXT_MAINPAGE6_3_DE "\xe %eb/%Eb\xb0 Z:%x2" +#elif FEATURE_DITTO_PRINTING +#define UI_TEXT_MAINPAGE6_3_DE "Kopien: %ed Z:%x2" +#else +#define UI_TEXT_MAINPAGE6_3_DE "Fluss:\xfd %of%%% Z:%x2" +#endif +#define UI_TEXT_MAINPAGE6_4_DE "Mul: %om%%% \xfd E: %x4m" +#define UI_TEXT_MAINPAGE6_5_DE "Puf: %oB" +#define UI_TEXT_MAINPAGE6_6_DE "%os" +#define UI_TEXT_MAINPAGE_TEMP_BED_DE cTEMP "%ec/%Ec" cDEG "B%eB/%Eb" cDEG +#define UI_TEXT_MAINPAGE_BED_DE "B%eB/%Eb" cDEG +#define UI_TEXT_MAINPAGE_Z_BUF_DE "Z:%x2 Buf : %oB" +#define UI_TEXT_MAINPAGE_MUL_EUSAGE_DE "Mul: %om E:%x4" +#define UI_TEXT_MAINPAGE_XY_DE "X:%x0 Y:%x1" +#define UI_TEXT_PRINT_TIME_VALUE_DE "%Ut" +#define UI_TEXT_PRINT_FILAMENT_VALUE_DE "%Uf m" +#define UI_TEXT_METER_PRINTED_DE "%Uf m " UI_TEXT_PRINTED_DE +#define UI_TEXT_STATUS_DE "%os" +#define UI_TEXT_EMPTY_DE "" +#define UI_TEXT_TEMP_SET_DE cTEMP "%ec/%Ec" cDEG +#define UI_TEXT_CURRENT_TEMP_DE cTEMP "%ec" cDEG +#define UI_TEXT_COATING_THICKNESS_DE " %BCmm" +#define UI_TEXT_EXTR3_TEMP_DE "Temp. 4 :%e3/%E3" cDEG "C" +#define UI_TEXT_EXTR4_TEMP_DE "Temp. 5 :%e4/%E4" cDEG "C" +#define UI_TEXT_EXTR5_TEMP_DE "Temp. 6 :%e5/%E5" cDEG "C" +#define UI_TEXT_EXTR3_OFF_DE "Extruder 4 Aus" +#define UI_TEXT_EXTR4_OFF_DE "Extruder 5 Aus" +#define UI_TEXT_EXTR5_OFF_DE "Extruder 6 Aus" +#define UI_TEXT_EXTR3_SELECT_DE "%X3 W" STR_auml "hle Extr. 4" +#define UI_TEXT_EXTR4_SELECT_DE "%X4 W" STR_auml "hle Extr. 5" +#define UI_TEXT_EXTR5_SELECT_DE "%X5 W" STR_auml "hle Extr. 6" +#define UI_TEXT_DITTO_0_DE "%D0 Keine Kopien" +#define UI_TEXT_DITTO_1_DE "%D1 1 Kopie" +#define UI_TEXT_DITTO_2_DE "%D2 2 Kopien" +#define UI_TEXT_DITTO_3_DE "%D3 3 Kopien" +#define UI_TEXT_ZPROBE_HEIGHT_DE "Z-Probenh" STR_ouml "he:%zh" + + + +#define UI_TEXT_OFFSETS_DE "Set print offsets" +#define UI_TEXT_X_OFFSET_DE "X-Offset:%T0mm" +#define UI_TEXT_Y_OFFSET_DE "Y-Offset:%T1mm" +#define UI_TEXT_Z_OFFSET_DE "Z-Offset:%T2mm" + + +// Dutch translation + +#define UI_TEXT_ON_NL "Aan" +#define UI_TEXT_OFF_NL "Uit" +#define UI_TEXT_NA_NL "N/A" // Output for not available +#define UI_TEXT_YES_NL "Ja" +#define UI_TEXT_NO_NL "Nee" +#define UI_TEXT_PRINT_POS_NL "Printen..." +#define UI_TEXT_PRINTING_NL "Printen" +#define UI_TEXT_IDLE_NL "Rust" +#define UI_TEXT_NOSDCARD_NL "Geen SD Kaart" +#define UI_TEXT_ERROR_NL "**** FOUT ****" +#define UI_TEXT_BACK_NL "Terug " cUP +#define UI_TEXT_QUICK_SETTINGS_NL "Snel Instelling" +#define UI_TEXT_ERRORMSG_NL "%oe" +#define UI_TEXT_CONFIGURATION_NL "Configuratie" +#define UI_TEXT_POSITION_NL "Positie" +#define UI_TEXT_EXTRUDER_NL "Extruder" +#define UI_TEXT_SD_CARD_NL "SD Kaart" +#define UI_TEXT_DEBUGGING_NL "Debugging" +#define UI_TEXT_HOME_DELTA_NL "Home Delta" +#define UI_TEXT_HOME_ALL_NL "Home Alles" +#define UI_TEXT_HOME_X_NL "Home X" +#define UI_TEXT_HOME_Y_NL "Home Y" +#define UI_TEXT_HOME_Z_NL "Home Z" +#define UI_TEXT_PREHEAT_PLA_NL "Voorverwarmen PLA" +#define UI_TEXT_PREHEAT_ABS_NL "Voorverwarmen ABS" +#define UI_TEXT_LIGHTS_ONOFF_NL "Lichten:%lo" +#define UI_TEXT_COOLDOWN_NL "Koelen" +#define UI_TEXT_SET_TO_ORIGIN_NL "Zet oorsprong" +#define UI_TEXT_DISABLE_STEPPER_NL "Zet motor uit" +#define UI_TEXT_X_POSITION_NL "X Positie" +#define UI_TEXT_X_POS_FAST_NL "X Pos. Snel" +#define UI_TEXT_Y_POSITION_NL "Y Positie" +#define UI_TEXT_Y_POS_FAST_NL "Y Pos. Snel" +#define UI_TEXT_Z_POSITION_NL "Z Positie" +#define UI_TEXT_Z_POS_FAST_NL "Z Pos. Snel" +#define UI_TEXT_E_POSITION_NL "Extr. positie" +#define UI_TEXT_BED_TEMP_NL "Bed Temp:%eb/%Eb" cDEG "C" +#define UI_TEXT_EXTR0_TEMP_NL "Temp. 1 :%e0/%E0" cDEG "C" +#define UI_TEXT_EXTR1_TEMP_NL "Temp. 2 :%e1/%E1" cDEG "C" +#define UI_TEXT_EXTR2_TEMP_NL "Temp. 3 :%e2/%E2" cDEG "C" +#define UI_TEXT_EXTR0_OFF_NL "Extruder 1 Uit" +#define UI_TEXT_EXTR1_OFF_NL "Extruder 2 Uit" +#define UI_TEXT_EXTR2_OFF_NL "Extruder 3 Uit" +#define UI_TEXT_EXTR0_SELECT_NL "%X0 Select Extr. 1" +#define UI_TEXT_EXTR1_SELECT_NL "%X1 Select Extr. 2" +#define UI_TEXT_EXTR2_SELECT_NL "%X2 Select Extr. 3" +#define UI_TEXT_EXTR_ORIGIN_NL "Zet oorsprong" +#define UI_TEXT_PRINT_X_NL "Print X:%ax" +#define UI_TEXT_PRINT_Y_NL "Print Y:%ay" +#define UI_TEXT_PRINT_Z_NL "Print Z:%az" +#define UI_TEXT_PRINT_Z_DELTA_NL "Print:%az" +#define UI_TEXT_MOVE_X_NL "Beweeg X:%aX" +#define UI_TEXT_MOVE_Y_NL "Beweeg Y:%aY" +#define UI_TEXT_MOVE_Z_NL "Beweeg Z:%aZ" +#define UI_TEXT_MOVE_Z_DELTA_NL "Beweeg:%aZ" +#define UI_TEXT_JERK_NL "Ruk:%aj" +#define UI_TEXT_ZJERK_NL "Z-Ruk:%aJ" +#define UI_TEXT_ACCELERATION_NL "Acceleratie" +#define UI_TEXT_STORE_TO_EEPROM_NL "Opslaan n. EEPROM" +#define UI_TEXT_LOAD_EEPROM_NL "Ladd f. EEPROM" +#define UI_TEXT_DBG_ECHO_NL "Echo :%do" +#define UI_TEXT_DBG_INFO_NL "Info :%di" +#define UI_TEXT_DBG_ERROR_NL "Fouten :%de" +#define UI_TEXT_DBG_DRYRUN_NL "Droogloop:%dd" +#define UI_TEXT_DBG_ENDSTOP_NL "EndStop :%dp" +#define UI_TEXT_OPS_OFF_NL "%O0 OPS Uit" +#define UI_TEXT_OPS_CLASSIC_NL "%O1 OPS Klassiek" +#define UI_TEXT_OPS_FAST_NL "%O2 OPS Snel" +#define UI_TEXT_OPS_RETRACT_NL "Terugtrekken:%Or" +#define UI_TEXT_OPS_BACKSLASH_NL "Backsl. :%Ob" +#define UI_TEXT_OPS_MINDIST_NL "Min. afstand:%Od" +#define UI_TEXT_OPS_MOVE_AFTER_NL "Beweeg na:%Oa" +#define UI_TEXT_ANTI_OOZE_NL "Anti lekken" +#define UI_TEXT_PRINT_FILE_NL "Print bestand" +#define UI_TEXT_PAUSE_PRINT_NL "Pauzeer Print" +#define UI_TEXT_CONTINUE_PRINT_NL "Zet print voort" +#define UI_TEXT_UNMOUNT_CARD_NL "Ontkoppel Kaart" +#define UI_TEXT_MOUNT_CARD_NL "Koppel Kaart" +#define UI_TEXT_DELETE_FILE_NL "Verw. bestand" +#define UI_TEXT_FEEDRATE_NL "Beweeg snelheid" +#define UI_TEXT_FEED_MAX_X_NL "Max X:%fx" +#define UI_TEXT_FEED_MAX_Y_NL "Max Y:%fy" +#define UI_TEXT_FEED_MAX_Z_NL "Max Z:%fz" +#define UI_TEXT_FEED_MAX_Z_DELTA_NL "Max:%fz" +#define UI_TEXT_FEED_HOME_X_NL "Home X:%fX" +#define UI_TEXT_FEED_HOME_Y_NL "Home Y:%fY" +#define UI_TEXT_FEED_HOME_Z_NL "Home Z:%fZ" +#define UI_TEXT_FEED_HOME_Z_DELTA_NL "Home:%fZ" +#define UI_TEXT_ACTION_XPOSITION4A_NL "X:%x0 mm" +#define UI_TEXT_ACTION_XPOSITION4B_NL "Min eindst.:%sx" +#define UI_TEXT_ACTION_XPOSITION4C_NL "Max eindst.:%sX" +#define UI_TEXT_ACTION_XPOSITION4D_NL "" +#define UI_TEXT_ACTION_YPOSITION4A_NL "Y:%x1 mm" +#define UI_TEXT_ACTION_YPOSITION4B_NL "Min eindst.:%sy" +#define UI_TEXT_ACTION_YPOSITION4C_NL "Max eindst.:%sY" +#define UI_TEXT_ACTION_YPOSITION4D_NL "" +#define UI_TEXT_ACTION_ZPOSITION4A_NL "Z:%x2 mm" +#define UI_TEXT_ACTION_ZPOSITION4B_NL "Min eindst.:%sz" +#define UI_TEXT_ACTION_ZPOSITION4C_NL "Max eindst.:%sZ" +#define UI_TEXT_ACTION_ZPOSITION4D_NL "" +#define UI_TEXT_ACTION_XPOSITION_FAST4A_NL "X:%x0 mm" +#define UI_TEXT_ACTION_XPOSITION_FAST4B_NL "Min eindst.:%sx" +#define UI_TEXT_ACTION_XPOSITION_FAST4C_NL "Max eindst.:%sX" +#define UI_TEXT_ACTION_XPOSITION_FAST4D_NL "" +#define UI_TEXT_ACTION_YPOSITION_FAST4A_NL "Y:%x1 mm" +#define UI_TEXT_ACTION_YPOSITION_FAST4B_NL "Min eindst.:%sy" +#define UI_TEXT_ACTION_YPOSITION_FAST4C_NL "Max eindst.:%sY" +#define UI_TEXT_ACTION_YPOSITION_FAST4D_NL "" +#define UI_TEXT_ACTION_ZPOSITION_FAST4A_NL "Z:%x2 mm" +#define UI_TEXT_ACTION_ZPOSITION_FAST4B_NL "Min eindst.:%sz" +#define UI_TEXT_ACTION_ZPOSITION_FAST4C_NL "Max eindst.:%sZ" +#define UI_TEXT_ACTION_ZPOSITION_FAST4D_NL "" +#define UI_TEXT_ACTION_EPOSITION_FAST2A_NL "E:%x3 mm" +#define UI_TEXT_ACTION_EPOSITION_FAST2B_NL "1 klik = 1 mm" +#define UI_TEXT_ACTION_XPOSITION2A_NL "X:%x0 mm" +#define UI_TEXT_ACTION_XPOSITION2B_NL "Min:%sx Max:%sX" +#define UI_TEXT_ACTION_YPOSITION2A_NL "Y:%x1 mm" +#define UI_TEXT_ACTION_YPOSITION2B_NL "Min:%sy Max:%sY" +#define UI_TEXT_ACTION_ZPOSITION2A_NL "Z:%x2 mm" +#define UI_TEXT_ACTION_ZPOSITION2B_NL "Min:%sz Max:%sZ" +#define UI_TEXT_ACTION_XPOSITION_FAST2A_NL "X:%x0 mm" +#define UI_TEXT_ACTION_XPOSITION_FAST2B_NL "Min:%sx Max:%sX" +#define UI_TEXT_ACTION_YPOSITION_FAST2A_NL "Y:%x1 mm" +#define UI_TEXT_ACTION_YPOSITION_FAST2B_NL "Min:%sy Max:%sY" +#define UI_TEXT_ACTION_ZPOSITION_FAST2A_NL "Z:%x2 mm" +#define UI_TEXT_ACTION_ZPOSITION_FAST2B_NL "Min:%sz Max:%sZ" +#define UI_TEXT_FANSPEED_NL "Fan snelheid" +#define UI_TEXT_FAN_OFF_NL "Zet Fan uit" +#define UI_TEXT_ACTION_FANSPEED_NL "Fan snelheid:%Fs%%%" +#define UI_TEXT_FAN_25_NL "Zet Fan 25%%%" +#define UI_TEXT_FAN_50_NL "Zet Fan 50%%%" +#define UI_TEXT_FAN_75_NL "Zet Fan 75%%%" +#define UI_TEXT_FAN_FULL_NL "Zet Fan Vol aan" +#define UI_TEXT_STEPPER_INACTIVE_NL "Motor Inactief" +#define UI_TEXT_STEPPER_INACTIVE2A_NL "Uit na: %is" +#define UI_TEXT_STEPPER_INACTIVE2B_NL "[min] 0=Off" +#define UI_TEXT_POWER_INACTIVE_NL "Max. Inactief" +#define UI_TEXT_POWER_INACTIVE2A_NL "Zet uit na: %ip" +#define UI_TEXT_POWER_INACTIVE2B_NL "[min] 0=Off" +#define UI_TEXT_GENERAL_NL "Algemeen" +#define UI_TEXT_BAUDRATE_NL "Baudrate:%oc" +#define UI_TEXT_EXTR_STEPS_NL "Stappen/MM:%Se" +#define UI_TEXT_EXTR_START_FEED_NL "Start FR.:%Xf" +#define UI_TEXT_EXTR_MAX_FEED_NL "Max FR.:%XF" +#define UI_TEXT_EXTR_ACCEL_NL "Accel:%XA" +#define UI_TEXT_EXTR_WATCH_NL "Stab.Tijd:%Xw" +#define UI_TEXT_EXTR_ADVANCE_L_NL "Advance lin:%Xl" +#define UI_TEXT_EXTR_ADVANCE_K_NL "Advance quad:%Xa" +#define UI_TEXT_EXTR_MANAGER_NL "Control:%Xh" +#define UI_TEXT_EXTR_PGAIN_NL "PID P:%Xp" +#define UI_TEXT_EXTR_DEADTIME_NL "Dode tijd:%Xp" +#define UI_TEXT_EXTR_DMAX_DT_NL "Controle PWM:%XM" +#define UI_TEXT_EXTR_IGAIN_NL "PID I:%Xi" +#define UI_TEXT_EXTR_DGAIN_NL "PID D:%Xd" +#define UI_TEXT_EXTR_DMIN_NL "Drive Min:%Xm" +#define UI_TEXT_EXTR_DMAX_NL "Drive Max:%XM" +#define UI_TEXT_EXTR_PMAX_NL "PID Max:%XD" +#define UI_TEXT_EXTR_XOFF_NL "X-Offset:%Xx" +#define UI_TEXT_EXTR_YOFF_NL "Y-Offset:%Xy" +#define UI_TEXT_STRING_HM_BANGBANG_NL "BangBang" +#define UI_TEXT_STRING_HM_PID_NL "PID" +#define UI_TEXT_STRING_ACTION_NL "Action:%la" +#define UI_TEXT_HEATING_EXTRUDER_NL "Opwarmen Extru." +#define UI_TEXT_HEATING_BED_NL "Opwarmen Bed" +#define UI_TEXT_KILLED_NL "Uitgeschakeld" +#define UI_TEXT_STEPPER_DISABLED_NL "Motor uitgezet" +#define UI_TEXT_EEPROM_STOREDA_NL "Configuratie" +#define UI_TEXT_EEPROM_STOREDB_NL "saved. in EEPROM" +#define UI_TEXT_EEPROM_LOADEDA_NL "Configuratie" +#define UI_TEXT_EEPROM_LOADEDB_NL "loaded f. EEPROM" +#define UI_TEXT_UPLOADING_NL "Uploaden..." +#define UI_TEXT_PAGE_BUFFER_NL "Buffer:%oB" +#define UI_TEXT_PAGE_EXTRUDER_NL " E:%ec/%Ec" cDEG "C" cARROW "%oC" +#define UI_TEXT_PAGE_EXTRUDER1_NL "E1:%e0/%E0" cDEG "C" cARROW "%o0" +#define UI_TEXT_PAGE_EXTRUDER2_NL "E2:%e1/%E1" cDEG "C" cARROW "%o1" +#define UI_TEXT_PAGE_EXTRUDER3_NL "E3:%e2/%E2" cDEG "C" cARROW "%o2" +#define UI_TEXT_PAGE_BED_NL " B:%eb/%Eb" cDEG "C" cARROW "%ob" +#define UI_TEXT_SPEED_MULTIPLY_NL "Snelh. Mul.:%om%%%" +#define UI_TEXT_FLOW_MULTIPLY_NL "Flow Mul.:%of%%%" +#define UI_TEXT_SHOW_MEASUREMENT_NL "Show meting" +#define UI_TEXT_RESET_MEASUREMENT_NL "Reset meting" +#define UI_TEXT_SET_MEASURED_ORIGIN_NL "Set Z=0" +#define UI_TEXT_ZCALIB_NL "Z Calib." +#define UI_TEXT_SET_P1_NL "Set P1" +#define UI_TEXT_SET_P2_NL "Set P2" +#define UI_TEXT_SET_P3_NL "Set P3" +#define UI_TEXT_CALCULATE_LEVELING_NL "Bereken Leveling" +#define UI_TEXT_LEVEL_NL "Level delta" +#define UI_TEXT_EXTR_WAIT_RETRACT_TEMP_NL "Wacht Temp. %XT" cDEG "C" +#define UI_TEXT_EXTR_WAIT_RETRACT_UNITS_NL "Wacht Retr.:%XU mm" +#define UI_TEXT_SD_REMOVED_NL "SD-kaart verwijderd" +#define UI_TEXT_SD_INSERTED_NL "SD-kaart geplaatst" +#define UI_TEXT_PRINTER_READY_NL "Printer klaar." +// Printtime output gets aggregated like UI_TEXT_PRINTTIME_DAYSUI_TEXT_PRINTTIME_HOURSUI_TEXT_PRINTTIME_MINUTES +// ___88 days 12:45 +#define UI_TEXT_PRINTTIME_DAYS_NL " dagen " +#define UI_TEXT_PRINTTIME_HOURS_NL ":" +#define UI_TEXT_PRINTTIME_MINUTES_NL "" +#define UI_TEXT_PRINT_TIME_NL "Printing tijd" +#define UI_TEXT_PRINT_FILAMENT_NL "Filament gedrukt" +#define UI_TEXT_PRINTED_NL "gedrukt" +#define UI_TEXT_POWER_NL "ATX power aan/uit" +#define UI_TEXT_STRING_HM_DEADTIME_NL "Dode tijd" +#define UI_TEXT_STRING_HM_SLOWBANG_NL "SlowBang" +#define UI_TEXT_STOP_PRINT_NL "Stop Print" +#define UI_TEXT_Z_BABYSTEPPING_NL "Z Babystep.:%oYmm" +#define UI_TEXT_CHANGE_FILAMENT_NL "Ruil filament" +#define UI_TEXT_WIZ_CH_FILAMENT1_NL "Ruil filament:" +#define UI_TEXT_WIZ_CH_FILAMENT2_NL "Draaien voor" +#define UI_TEXT_WIZ_CH_FILAMENT3_NL "filament op/omlaag" +#define UI_TEXT_CLICK_DONE_NL "Verder met klik" +#define UI_TEXT_AUTOLEVEL_ONOFF_NL "Autolevel: %ll" +#define UI_TEXT_SERVOPOS_NL "Servo-pos.: %oS" +#define UI_TEXT_IGNORE_M106_NL "Negeer M106 %Fi" +#define UI_TEXT_WIZ_REHEAT1_NL "Klik om extruder" +#define UI_TEXT_WIZ_REHEAT2_NL "verwarmen." +#define UI_TEXT_WIZ_WAITTEMP1_NL "Wachten op" +#define UI_TEXT_WIZ_WAITTEMP2_NL "doeltemperatuur..." +#define UI_TEXT_EXTRUDER_JAM_NL "Extruder jam" +#define UI_TEXT_STANDBY_NL "Standby" +#define UI_TEXT_BED_COATING_NL "Bed bedekking" +#define UI_TEXT_BED_COATING_SET1_NL "Bed bedekking set to" +#define UI_TEXT_BED_COATING_SET2_NL "" +#define UI_TEXT_NOCOATING_NL "Geen bedekking" +#define UI_TEXT_BUILDTAK_NL "BuildTak" +#define UI_TEXT_KAPTON_NL "Kapton" +#define UI_TEXT_BLUETAPE_NL "Blauw afplakband" +#define UI_TEXT_PETTAPE_NL "Groene PET Tape" +#define UI_TEXT_GLUESTICK_NL "Lijmstift" +#define UI_TEXT_CUSTOM_NL "Custom" +#define UI_TEXT_COATING_CUSTOM_NL "Custom:%BCmm" +#define UI_TEXT_LANGUAGE_NL "Taal" + +#if NUM_EXTRUDER > 2 || MIXING_EXTRUDER != 0 +#define UI_TEXT_MAINPAGE6_1_NL "\xa %ec/%Ec\xb0 X:%x0" +#else +#define UI_TEXT_MAINPAGE6_1_NL "\xa %e0/%E0\xb0 X:%x0" +#endif // NUM_EXTRUDER +#if NUM_EXTRUDER == 2 && MIXING_EXTRUDER == 0 +#define UI_TEXT_MAINPAGE6_2_NL "\xa %e1/%E1\xb0 Y:%x1" +#elif HAVE_HEATED_BED +#define UI_TEXT_MAINPAGE6_2_NL "\xe %eb/%Eb\xb0 Y:%x1" +#else +#define UI_TEXT_MAINPAGE6_2_NL " Y:%x1" +#endif +#if HAVE_HEATED_BED && NUM_EXTRUDER == 2 && MIXING_EXTRUDER == 0 +#define UI_TEXT_MAINPAGE6_3_NL "\xe %eb/%Eb\xb0 Z:%x2" +#elif FEATURE_DITTO_PRINTING +#define UI_TEXT_MAINPAGE6_3_NL "Kopieen: %ed Z:%x2" +#else +#define UI_TEXT_MAINPAGE6_3_NL "Flow:\xfd %of%%% Z:%x2" +#endif +#define UI_TEXT_MAINPAGE6_4_NL "Mul: %om%%% \xfd E: %x4m" +#define UI_TEXT_MAINPAGE6_5_NL "Buf: %oB" +#define UI_TEXT_MAINPAGE6_6_NL "%os" +#define UI_TEXT_MAINPAGE_TEMP_BED_NL cTEMP "%ec/%Ec" cDEG "B%eB/%Eb" cDEG +#define UI_TEXT_MAINPAGE_BED_NL "B%eB/%Eb" cDEG +#define UI_TEXT_MAINPAGE_Z_BUF_NL "Z:%x2 Buf : %oB" +#define UI_TEXT_MAINPAGE_MUL_EUSAGE_NL "Mul: %om E:%x4" +#define UI_TEXT_MAINPAGE_XY_NL "X:%x0 Y:%x1" +#define UI_TEXT_PRINT_TIME_VALUE_NL "%Ut" +#define UI_TEXT_PRINT_FILAMENT_VALUE_NL "%Uf m" +#define UI_TEXT_METER_PRINTED_NL "%Uf m " UI_TEXT_PRINTED_NL +#define UI_TEXT_STATUS_NL "%os" +#define UI_TEXT_EMPTY_NL "" +#define UI_TEXT_TEMP_SET_NL cTEMP "%ec/%Ec" cDEG +#define UI_TEXT_CURRENT_TEMP_NL cTEMP "%ec" cDEG +#define UI_TEXT_COATING_THICKNESS_NL " %BCmm" +#define UI_TEXT_EXTR3_TEMP_NL "Temp. 4 :%e3/%E3" cDEG "C" +#define UI_TEXT_EXTR4_TEMP_NL "Temp. 5 :%e4/%E4" cDEG "C" +#define UI_TEXT_EXTR5_TEMP_NL "Temp. 6 :%e5/%E5" cDEG "C" +#define UI_TEXT_EXTR3_OFF_NL "Extruder 4 Uit" +#define UI_TEXT_EXTR4_OFF_NL "Extruder 5 Uit" +#define UI_TEXT_EXTR5_OFF_NL "Extruder 6 Uit" +#define UI_TEXT_EXTR3_SELECT_NL "%X3 Select Extr. 4" +#define UI_TEXT_EXTR4_SELECT_NL "%X4 Select Extr. 5" +#define UI_TEXT_EXTR5_SELECT_NL "%X5 Select Extr. 6" +#define UI_TEXT_DITTO_0_NL "%D0 Geen Kopieen" +#define UI_TEXT_DITTO_1_NL "%D1 1 Kopie" +#define UI_TEXT_DITTO_2_NL "%D2 2 Kopieen" +#define UI_TEXT_DITTO_3_NL "%D3 3 Kopieen" +#define UI_TEXT_ZPROBE_HEIGHT_NL "z-probe hoogte:%zh" + + + +#define UI_TEXT_OFFSETS_NL "Set print offsets" +#define UI_TEXT_X_OFFSET_NL "Set X offset:%T0mm" +#define UI_TEXT_Y_OFFSET_NL "Set Y offset:%T1mm" +#define UI_TEXT_Z_OFFSET_NL "Set Z offset:%T2mm" + + +// *************** Brazilian portuguese translation **************** + +#define UI_TEXT_ON_PT "On" +#define UI_TEXT_OFF_PT "Off" +#define UI_TEXT_NA_PT "N/A" // Output for not available +#define UI_TEXT_YES_PT "Sim" +#define UI_TEXT_NO_PT "Não" +#define UI_TEXT_SEL_PT cSEL +#define UI_TEXT_NOSEL_PT cUNSEL +#define UI_TEXT_PRINT_POS_PT "Imprimindo..." +#define UI_TEXT_PRINTING_PT "Imprimindo" +#define UI_TEXT_IDLE_PT "Ocioso" +#define UI_TEXT_NOSDCARD_PT "Nenhum cartao SD" +#define UI_TEXT_ERROR_PT "**** ERRO ****" +#define UI_TEXT_BACK_PT "Voltar " cUP +#define UI_TEXT_QUICK_SETTINGS_PT "Configuracoes Rapidas" +#define UI_TEXT_ERRORMSG_PT "%oe" +#define UI_TEXT_CONFIGURATION_PT "Configuracao" +#define UI_TEXT_POSITION_PT "Posicao" +#define UI_TEXT_EXTRUDER_PT "Extrusor" +#define UI_TEXT_SD_CARD_PT "Cartao SD" +#define UI_TEXT_DEBUGGING_PT "Depuracao" +#define UI_TEXT_HOME_DELTA_PT "Home delta" +#define UI_TEXT_HOME_ALL_PT "Home todos" +#define UI_TEXT_HOME_X_PT "Home X" +#define UI_TEXT_HOME_Y_PT "Home Y" +#define UI_TEXT_HOME_Z_PT "Home Z" +#define UI_TEXT_PREHEAT_PLA_PT "Pre-aquecer PLA" +#define UI_TEXT_PREHEAT_ABS_PT "Pre-aquecer ABS" +#define UI_TEXT_LIGHTS_ONOFF_PT "Luzes:%lo" +#define UI_TEXT_COOLDOWN_PT "Resfriar" +#define UI_TEXT_SET_TO_ORIGIN_PT "Definir como origem" +#define UI_TEXT_DISABLE_STEPPER_PT "Desabilitar motor" +#define UI_TEXT_X_POSITION_PT "Posicao X" +#define UI_TEXT_X_POS_FAST_PT "Pos. Rapida X" +#define UI_TEXT_Y_POSITION_PT "Posicao Y" +#define UI_TEXT_Y_POS_FAST_PT "Pos. Rapida Y" +#define UI_TEXT_Z_POSITION_PT "Posicao Z" +#define UI_TEXT_Z_POS_FAST_PT "Pos. Rapida Z" +#define UI_TEXT_E_POSITION_PT "Posicao Extrusor" +#define UI_TEXT_BED_TEMP_PT "Tem.Cama:%eb/%Eb" cDEG "C" +#define UI_TEXT_EXTR0_TEMP_PT "Temp. 1 :%e0/%E0" cDEG "C" +#define UI_TEXT_EXTR1_TEMP_PT "Temp. 2 :%e1/%E1" cDEG "C" +#define UI_TEXT_EXTR2_TEMP_PT "Temp. 3 :%e2/%E2" cDEG "C" +#define UI_TEXT_EXTR0_OFF_PT "Extr. 1 Desligado" +#define UI_TEXT_EXTR1_OFF_PT "Extr. 2 Desligado" +#define UI_TEXT_EXTR2_OFF_PT "Extr. 3 Desligado" +#define UI_TEXT_EXTR0_SELECT_PT "%X0 Sel. Extr. 1" +#define UI_TEXT_EXTR1_SELECT_PT "%X1 Sel. Extr. 2" +#define UI_TEXT_EXTR2_SELECT_PT "%X2 Sel. Extr. 3" +#define UI_TEXT_EXTR_ORIGIN_PT "Definir Origem" +#define UI_TEXT_PRINT_X_PT "Imprimir X:%ax" +#define UI_TEXT_PRINT_Y_PT "Imprimir Y:%ay" +#define UI_TEXT_PRINT_Z_PT "Imprimir Z:%az" +#define UI_TEXT_PRINT_Z_DELTA_PT "Imprimir:%az" +#define UI_TEXT_MOVE_X_PT "Mover X:%aX" +#define UI_TEXT_MOVE_Y_PT "Mover Y:%aY" +#define UI_TEXT_MOVE_Z_PT "Mover Z:%aZ" +#define UI_TEXT_MOVE_Z_DELTA_PT "Mover:%aZ" +#define UI_TEXT_JERK_PT "Jerk:%aj" +#define UI_TEXT_ZJERK_PT "Z-Jerk:%aJ" +#define UI_TEXT_ACCELERATION_PT "Aceleracao" +#define UI_TEXT_STORE_TO_EEPROM_PT "Armazenar na EEPROM" +#define UI_TEXT_LOAD_EEPROM_PT "Carregar da EEPROM" +#define UI_TEXT_DBG_ECHO_PT "Echo :%do" +#define UI_TEXT_DBG_INFO_PT "Info :%di" +#define UI_TEXT_DBG_ERROR_PT "Erros :%de" +#define UI_TEXT_DBG_DRYRUN_PT "Dry run:%dd" +#define UI_TEXT_DBG_ENDSTOP_PT "EndStop:%dp" +#define UI_TEXT_OPS_OFF_PT "%O0 OPS Off" +#define UI_TEXT_OPS_CLASSIC_PT "%O1 OPS Classic" +#define UI_TEXT_OPS_FAST_PT "%O2 OPS Fast" +#define UI_TEXT_OPS_RETRACT_PT "Retract :%Or" +#define UI_TEXT_OPS_BACKSLASH_PT "Backsl. :%Ob" +#define UI_TEXT_OPS_MINDIST_PT "Min.dist:%Od" +#define UI_TEXT_OPS_MOVE_AFTER_PT "Move after:%Oa" +#define UI_TEXT_ANTI_OOZE_PT "Anti Ooze" +#define UI_TEXT_PRINT_FILE_PT "Imprimir arquivo" +#define UI_TEXT_PAUSE_PRINT_PT "Pausar Impressao" +#define UI_TEXT_CONTINUE_PRINT_PT "Continuar Impressao" +#define UI_TEXT_UNMOUNT_CARD_PT "Desmontar Cartao" +#define UI_TEXT_MOUNT_CARD_PT "Montar Cartao" +#define UI_TEXT_DELETE_FILE_PT "Deletar arquivo" +#define UI_TEXT_FEEDRATE_PT "Feedrate" +#define UI_TEXT_FEED_MAX_X_PT "Max X:%fx" +#define UI_TEXT_FEED_MAX_Y_PT "Max Y:%fy" +#define UI_TEXT_FEED_MAX_Z_PT "Max Z:%fz" +#define UI_TEXT_FEED_MAX_Z_DELTA_PT "Max:%fz" +#define UI_TEXT_FEED_HOME_X_PT "Home X:%fX" +#define UI_TEXT_FEED_HOME_Y_PT "Home Y:%fY" +#define UI_TEXT_FEED_HOME_Z_PT "Home Z:%fZ" +#define UI_TEXT_FEED_HOME_Z_DELTA_PT "Home:%fZ" +#define UI_TEXT_ACTION_XPOSITION4A_PT "X:%x0 mm %dx%dX" +#define UI_TEXT_ACTION_XPOSITION4B_PT "Min endstop:%sx" +#define UI_TEXT_ACTION_XPOSITION4C_PT "Max endstop:%sX" +#define UI_TEXT_ACTION_XPOSITION4D_PT "" +#define UI_TEXT_ACTION_YPOSITION4A_PT "Y:%x1 mm %dy%dY" +#define UI_TEXT_ACTION_YPOSITION4B_PT "Min endstop:%sy" +#define UI_TEXT_ACTION_YPOSITION4C_PT "Max endstop:%sY" +#define UI_TEXT_ACTION_YPOSITION4D_PT "" +#define UI_TEXT_ACTION_ZPOSITION4A_PT "Z:%x2 mm %dz%dZ" +#define UI_TEXT_ACTION_ZPOSITION4B_PT "Min endstop:%sz" +#define UI_TEXT_ACTION_ZPOSITION4C_PT "Max endstop:%sZ" +#define UI_TEXT_ACTION_ZPOSITION4D_PT "" +#define UI_TEXT_ACTION_XPOSITION_FAST4A_PT "X:%x0 mm" +#define UI_TEXT_ACTION_XPOSITION_FAST4B_PT "Min endstop:%sx" +#define UI_TEXT_ACTION_XPOSITION_FAST4C_PT "Max endstop:%sX" +#define UI_TEXT_ACTION_XPOSITION_FAST4D_PT "" +#define UI_TEXT_ACTION_YPOSITION_FAST4A_PT "Y:%x1 mm" +#define UI_TEXT_ACTION_YPOSITION_FAST4B_PT "Min endstop:%sy" +#define UI_TEXT_ACTION_YPOSITION_FAST4C_PT "Max endstop:%sY" +#define UI_TEXT_ACTION_YPOSITION_FAST4D_PT "" +#define UI_TEXT_ACTION_ZPOSITION_FAST4A_PT "Z:%x2 mm" +#define UI_TEXT_ACTION_ZPOSITION_FAST4B_PT "Min endstop:%sz" +#define UI_TEXT_ACTION_ZPOSITION_FAST4C_PT "Max endstop:%sZ" +#define UI_TEXT_ACTION_ZPOSITION_FAST4D_PT "" +#define UI_TEXT_ACTION_EPOSITION_FAST2A_PT "E:%x3 mm" +#define UI_TEXT_ACTION_EPOSITION_FAST2B_PT "1 click = 1 mm" +#define UI_TEXT_ACTION_XPOSITION2A_PT "X:%x0 mm" +#define UI_TEXT_ACTION_XPOSITION2B_PT "Min:%sx Max:%sX" +#define UI_TEXT_ACTION_YPOSITION2A_PT "Y:%x1 mm" +#define UI_TEXT_ACTION_YPOSITION2B_PT "Min:%sy Max:%sY" +#define UI_TEXT_ACTION_ZPOSITION2A_PT "Z:%x2 mm" +#define UI_TEXT_ACTION_ZPOSITION2B_PT "Min:%sz Max:%sZ" +#define UI_TEXT_ACTION_XPOSITION_FAST2A_PT "X:%x0 mm" +#define UI_TEXT_ACTION_XPOSITION_FAST2B_PT "Min:%sx Max:%sX" +#define UI_TEXT_ACTION_YPOSITION_FAST2A_PT "Y:%x1 mm" +#define UI_TEXT_ACTION_YPOSITION_FAST2B_PT "Min:%sy Max:%sY" +#define UI_TEXT_ACTION_ZPOSITION_FAST2A_PT "Z:%x2 mm" +#define UI_TEXT_ACTION_ZPOSITION_FAST2B_PT "Min:%sz Max:%sZ" +#define UI_TEXT_FANSPEED_PT "Velocidade ventoinha" +#define UI_TEXT_ACTION_FANSPEED_PT "Vel. vent.:%Fs%%%" +#define UI_TEXT_FAN_OFF_PT "Desligar ventoinha" +#define UI_TEXT_FAN_25_PT "Def. ventoinha 25%%%" +#define UI_TEXT_FAN_50_PT "Def. ventoinha 50%%%" +#define UI_TEXT_FAN_75_PT "Def. ventoinha 75%%%" +#define UI_TEXT_FAN_FULL_PT "Def. ventoinha 100%%%" +#define UI_TEXT_STEPPER_INACTIVE_PT "Motor Inativo" +#define UI_TEXT_STEPPER_INACTIVE2A_PT "Des. Depois: %is" +#define UI_TEXT_STEPPER_INACTIVE2B_PT "[min] 0=Off" +#define UI_TEXT_POWER_INACTIVE_PT "Max. Inativo" +#define UI_TEXT_POWER_INACTIVE2A_PT "Des. Depois: %ip" +#define UI_TEXT_POWER_INACTIVE2B_PT "[min] 0=Off" +#define UI_TEXT_GENERAL_PT "Geral" +#define UI_TEXT_BAUDRATE_PT "Baudrate:%oc" +#define UI_TEXT_EXTR_STEPS_PT "Passos/mm:%Se" +#define UI_TEXT_EXTR_START_FEED_PT "Iniciar FR:%Xf" +#define UI_TEXT_EXTR_MAX_FEED_PT "Max FR:%XF" +#define UI_TEXT_EXTR_ACCEL_PT "Accel:%XA" +#define UI_TEXT_EXTR_WATCH_PT "Stab.Time:%Xw" +#define UI_TEXT_EXTR_ADVANCE_L_PT "Advance lin:%Xl" +#define UI_TEXT_EXTR_ADVANCE_K_PT "Advance quad:%Xa" +#define UI_TEXT_EXTR_MANAGER_PT "Controle:%Xh" +#define UI_TEXT_EXTR_PGAIN_PT "PID P:%Xp" +#define UI_TEXT_EXTR_DEADTIME_PT "Tempo morto:%Xp" +#define UI_TEXT_EXTR_DMAX_DT_PT "Controle PWM:%XM" +#define UI_TEXT_EXTR_IGAIN_PT "PID I:%Xi" +#define UI_TEXT_EXTR_DGAIN_PT "PID D:%Xd" +#define UI_TEXT_EXTR_DMIN_PT "Drive Min:%Xm" +#define UI_TEXT_EXTR_DMAX_PT "Drive Max:%XM" +#define UI_TEXT_EXTR_PMAX_PT "PID Max:%XD" +#define UI_TEXT_EXTR_XOFF_PT "Offset X:%Xx" +#define UI_TEXT_EXTR_YOFF_PT "Offset Y:%Xy" +#define UI_TEXT_STRING_HM_BANGBANG_PT "BangBang" +#define UI_TEXT_STRING_HM_PID_PT "PID" +#define UI_TEXT_STRING_ACTION_PT "Acao:%la" +#define UI_TEXT_HEATING_EXTRUDER_PT "Aquecendo Extrusor" +#define UI_TEXT_HEATING_BED_PT "Aquecendo Cama" +#define UI_TEXT_KILLED_PT "Killed" +#define UI_TEXT_STEPPER_DISABLED_PT "Motor Desabilitado" +#define UI_TEXT_EEPROM_STOREDA_PT "Configuracao" +#define UI_TEXT_EEPROM_STOREDB_PT "armazenada na EEPROM" +#define UI_TEXT_EEPROM_LOADEDA_PT "Configuracao" +#define UI_TEXT_EEPROM_LOADEDB_PT "carregada da EEPROM" +#define UI_TEXT_UPLOADING_PT "Enviando..." +#define UI_TEXT_PAGE_BUFFER_PT "Buffer:%oB" +#define UI_TEXT_PAGE_EXTRUDER_PT " E:%ec/%Ec" cDEG "C" cARROW "%oC" +#define UI_TEXT_PAGE_EXTRUDER1_PT "E1:%e0/%E0" cDEG "C" cARROW "%o0" +#define UI_TEXT_PAGE_EXTRUDER2_PT "E2:%e1/%E1" cDEG "C" cARROW "%o1" +#define UI_TEXT_PAGE_EXTRUDER3_PT "E3:%e2/%E2" cDEG "C" cARROW "%o2" +#define UI_TEXT_PAGE_BED_PT " B:%eb/%Eb" cDEG "C" cARROW "%ob" +#define UI_TEXT_SPEED_MULTIPLY_PT "Mult. Veloc.:%om%%%" +#define UI_TEXT_FLOW_MULTIPLY_PT "Mult. Fluxo:%of%%%" +#define UI_TEXT_SHOW_MEASUREMENT_PT "Mostrar medicao" +#define UI_TEXT_RESET_MEASUREMENT_PT "Reset medicao" +#define UI_TEXT_SET_MEASURED_ORIGIN_PT "Set Z=0" +#define UI_TEXT_ZCALIB_PT "Z calib." +#define UI_TEXT_SET_P1_PT "Set P1" +#define UI_TEXT_SET_P2_PT "Set P2" +#define UI_TEXT_SET_P3_PT "Set P3" +#define UI_TEXT_CALCULATE_LEVELING_PT "Calcule nivelamento" +#define UI_TEXT_LEVEL_PT "Nivel delta" +#define UI_TEXT_EXTR_WAIT_RETRACT_TEMP_PT "Aguardar Temp.%XT" cDEG "C" +#define UI_TEXT_EXTR_WAIT_RETRACT_UNITS_PT "Aguardar Unidades:%XUmm" +#define UI_TEXT_SD_REMOVED_PT "Cartao SD removido" +#define UI_TEXT_SD_INSERTED_PT "Cartao SD inserido" +#define UI_TEXT_PRINTER_READY_PT "Impressora pronta." +// Printtime output gets aggregated like UI_TEXT_PRINTTIME_DAYSUI_TEXT_PRINTTIME_HOURSUI_TEXT_PRINTTIME_MINUTES +// ___88 days 12:45 +#define UI_TEXT_PRINTTIME_DAYS_PT " dias " +#define UI_TEXT_PRINTTIME_HOURS_PT ":" +#define UI_TEXT_PRINTTIME_MINUTES_PT "" +#define UI_TEXT_PRINT_TIME_PT "tempo de impressao" +#define UI_TEXT_PRINT_FILAMENT_PT "Filament impresso" +#define UI_TEXT_PRINTED_PT "impresso" +#define UI_TEXT_POWER_PT "ATX poder on/off" +#define UI_TEXT_STRING_HM_DEADTIME_PT "Tempo morto" +#define UI_TEXT_STRING_HM_SLOWBANG_PT "SlowBang" +#define UI_TEXT_STOP_PRINT_PT "Parar impressao" +#define UI_TEXT_Z_BABYSTEPPING_PT "Z babystep.:%oYmm" +#define UI_TEXT_CHANGE_FILAMENT_PT "Alterar filamento" +#define UI_TEXT_WIZ_CH_FILAMENT1_PT "Alterar filamento" +#define UI_TEXT_WIZ_CH_FILAMENT2_PT "Gire para mover" +#define UI_TEXT_WIZ_CH_FILAMENT3_PT "filamento cima/baixo" +#define UI_TEXT_CLICK_DONE_PT "Clique quando feito" +#define UI_TEXT_AUTOLEVEL_ONOFF_PT "Nivel auto: %ll" +#define UI_TEXT_SERVOPOS_PT "Pos. servo: %oS" +#define UI_TEXT_IGNORE_M106_PT "Ignorar M106 %Fi" +#define UI_TEXT_WIZ_REHEAT1_PT "Clique para" +#define UI_TEXT_WIZ_REHEAT2_PT "aquecer extrusora." +#define UI_TEXT_WIZ_WAITTEMP1_PT "Aguardando a" +#define UI_TEXT_WIZ_WAITTEMP2_PT "temperatura alvo ..." +#define UI_TEXT_EXTRUDER_JAM_PT "Extrusora congest." +#define UI_TEXT_STANDBY_PT "Standby" +#define UI_TEXT_BED_COATING_PT "Revest. de leito" +#define UI_TEXT_BED_COATING_SET1_PT "Revest. de leito:" +#define UI_TEXT_BED_COATING_SET2_PT "" +#define UI_TEXT_NOCOATING_PT "Sem revestimento" +#define UI_TEXT_BUILDTAK_PT "BuildTak" +#define UI_TEXT_KAPTON_PT "Kapton" +#define UI_TEXT_BLUETAPE_PT "Fita crepe azul" +#define UI_TEXT_PETTAPE_PT "Fita verde PET" +#define UI_TEXT_GLUESTICK_PT "Cola bastao" +#define UI_TEXT_CUSTOM_PT "Personalizadas" +#define UI_TEXT_COATING_CUSTOM_PT "Person.:%BCmm" +#define UI_TEXT_LANGUAGE_PT "Idioma" + +#if NUM_EXTRUDER > 2 || MIXING_EXTRUDER != 0 +#define UI_TEXT_MAINPAGE6_1_PT "\xa %ec/%Ec\xb0 X:%x0" +#else +#define UI_TEXT_MAINPAGE6_1_PT "\xa %e0/%E0\xb0 X:%x0" +#endif // NUM_EXTRUDER +#if NUM_EXTRUDER == 2 && MIXING_EXTRUDER == 0 +#define UI_TEXT_MAINPAGE6_2_PT "\xa %e1/%E1\xb0 Y:%x1" +#elif HAVE_HEATED_BED +#define UI_TEXT_MAINPAGE6_2_PT "\xe %eb/%Eb\xb0 Y:%x1" +#else +#define UI_TEXT_MAINPAGE6_2_PT " Y:%x1" +#endif +#if HAVE_HEATED_BED && NUM_EXTRUDER == 2 && MIXING_EXTRUDER == 0 +#define UI_TEXT_MAINPAGE6_3_PT "\xe %eb/%Eb\xb0 Z:%x2" +#elif FEATURE_DITTO_PRINTING +#define UI_TEXT_MAINPAGE6_3_PT "Copias: %ed Z:%x2" +#else +#define UI_TEXT_MAINPAGE6_3_PT "Fluxo:\xfd %of%%% Z:%x2" +#endif +#define UI_TEXT_MAINPAGE6_4_PT "Mul: %om%%% \xfd E: %x4m" +#define UI_TEXT_MAINPAGE6_5_PT "Buf: %oB" +#define UI_TEXT_MAINPAGE6_6_PT "%os" +#define UI_TEXT_MAINPAGE_TEMP_BED_PT cTEMP "%ec/%Ec" cDEG "B%eB/%Eb" cDEG +#define UI_TEXT_MAINPAGE_BED_PT "B%eB/%Eb" cDEG +#define UI_TEXT_MAINPAGE_Z_BUF_PT "Z:%x2 Buf : %oB" +#define UI_TEXT_MAINPAGE_MUL_EUSAGE_PT "Mul: %om E:%x4" +#define UI_TEXT_MAINPAGE_XY_PT "X:%x0 Y:%x1" +#define UI_TEXT_PRINT_TIME_VALUE_PT "%Ut" +#define UI_TEXT_PRINT_FILAMENT_VALUE_PT "%Uf m" +#define UI_TEXT_METER_PRINTED_PT "%Uf m " UI_TEXT_PRINTED_EN +#define UI_TEXT_STATUS_PT "%os" +#define UI_TEXT_EMPTY_PT "" +#define UI_TEXT_TEMP_SET_PT cTEMP "%ec/%Ec" cDEG +#define UI_TEXT_CURRENT_TEMP_PT cTEMP "%ec" cDEG +#define UI_TEXT_COATING_THICKNESS_PT " %BCmm" +#define UI_TEXT_EXTR3_TEMP_PT "Temp. 4 :%e3/%E3" cDEG "C" +#define UI_TEXT_EXTR4_TEMP_PT "Temp. 5 :%e4/%E4" cDEG "C" +#define UI_TEXT_EXTR5_TEMP_PT "Temp. 6 :%e5/%E5" cDEG "C" +#define UI_TEXT_EXTR3_OFF_PT "Extr. 4 Desligado" +#define UI_TEXT_EXTR4_OFF_PT "Extr. 5 Desligado" +#define UI_TEXT_EXTR5_OFF_PT "Extr. 6 Desligado" +#define UI_TEXT_EXTR3_SELECT_PT "%X3 Sel. Extr. 4" +#define UI_TEXT_EXTR4_SELECT_PT "%X4 Sel. Extr. 5" +#define UI_TEXT_EXTR5_SELECT_PT "%X5 Sel. Extr. 6" +#define UI_TEXT_DITTO_0_PT "%D0 Nenhuma Copia" +#define UI_TEXT_DITTO_1_PT "%D1 1 Copia" +#define UI_TEXT_DITTO_2_PT "%D2 2 Copias" +#define UI_TEXT_DITTO_3_PT "%D3 3 Copias" +#define UI_TEXT_ZPROBE_HEIGHT_PT "Altura Z-Probe:%zh" + + + +#define UI_TEXT_OFFSETS_PT "Set print offsets" +#define UI_TEXT_X_OFFSET_PT "Set X offset:%T0mm" +#define UI_TEXT_Y_OFFSET_PT "Set Y offset:%T1mm" +#define UI_TEXT_Z_OFFSET_PT "Set Z offset:%T2mm" + + +// *************** Italian translation **************** + +#define UI_TEXT_ON_IT "On" +#define UI_TEXT_OFF_IT "Off" +#define UI_TEXT_NA_IT "N/A" // Output for not available +#define UI_TEXT_YES_IT "Si" +#define UI_TEXT_NO_IT "No" +#define UI_TEXT_PRINT_POS_IT "Stampa..." +#define UI_TEXT_PRINTING_IT "Stampa" +#define UI_TEXT_IDLE_IT "Pausa" +#define UI_TEXT_NOSDCARD_IT "No Scheda SD" +#define UI_TEXT_ERROR_IT "**** ERRORE ****" +#define UI_TEXT_BACK_IT "Indietro " cUP +#define UI_TEXT_QUICK_SETTINGS_IT "Impostazioni veloci" +#define UI_TEXT_ERRORMSG_IT "%oe" +#define UI_TEXT_CONFIGURATION_IT "Configurazione" +#define UI_TEXT_POSITION_IT "Posizione" +#define UI_TEXT_EXTRUDER_IT "Estrusore" +#define UI_TEXT_SD_CARD_IT "Scheda SD" +#define UI_TEXT_DEBUGGING_IT "Sviluppo" +#define UI_TEXT_HOME_DELTA_IT "Origine Delta" +#define UI_TEXT_HOME_ALL_IT "Origine Tutti" +#define UI_TEXT_HOME_X_IT "Origine X" +#define UI_TEXT_HOME_Y_IT "Origine Y" +#define UI_TEXT_HOME_Z_IT "Origine Z" +#define UI_TEXT_PREHEAT_PLA_IT "Presicaldamento PLA" +#define UI_TEXT_PREHEAT_ABS_IT "Presicaldamento ABS" +#define UI_TEXT_LIGHTS_ONOFF_IT "Luci:%lo" +#define UI_TEXT_COOLDOWN_IT "Raffreddamento" +#define UI_TEXT_SET_TO_ORIGIN_IT "Imposta come Origine" +#define UI_TEXT_DISABLE_STEPPER_IT "Disabilita Stepper" +#define UI_TEXT_X_POSITION_IT "Posizione X" +#define UI_TEXT_X_POS_FAST_IT "Pos. X Veloce" +#define UI_TEXT_Y_POSITION_IT "Posizione Y" +#define UI_TEXT_Y_POS_FAST_IT "Pos. Y Veloce" +#define UI_TEXT_Z_POSITION_IT "Posizione Z" +#define UI_TEXT_Z_POS_FAST_IT "Pos. Z Veloce" +#define UI_TEXT_E_POSITION_IT "Posizione Estrusore" +#define UI_TEXT_BED_TEMP_IT "Temp.Piatto:%Eb" cDEG "C" +#define UI_TEXT_EXTR0_TEMP_IT "Temp. 1 :%e0/%E0" cDEG "C" +#define UI_TEXT_EXTR1_TEMP_IT "Temp. 2 :%e1/%E1" cDEG "C" +#define UI_TEXT_EXTR2_TEMP_IT "Temp. 3 :%e2/%E2" cDEG "C" +#define UI_TEXT_EXTR0_OFF_IT "Estrusore 1 Spento" +#define UI_TEXT_EXTR1_OFF_IT "Estrusore 2 Spento" +#define UI_TEXT_EXTR2_OFF_IT "Estrusore 3 Spento" +#define UI_TEXT_EXTR0_SELECT_IT "%X0 Seleziona Estr. 1" +#define UI_TEXT_EXTR1_SELECT_IT "%X1 Seleziona Estr. 2" +#define UI_TEXT_EXTR2_SELECT_IT "%X2 Seleziona Estr. 3" +#define UI_TEXT_EXTR_ORIGIN_IT "Imposta Origine" +#define UI_TEXT_PRINT_X_IT "Stampa X:%ax" +#define UI_TEXT_PRINT_Y_IT "Stampa Y:%ay" +#define UI_TEXT_PRINT_Z_IT "Stampa Z:%az" +#define UI_TEXT_PRINT_Z_DELTA_IT "Stampa:%az" +#define UI_TEXT_MOVE_X_IT "Movimento X:%aX" +#define UI_TEXT_MOVE_Y_IT "Movimento Y:%aY" +#define UI_TEXT_MOVE_Z_IT "Movimento Z:%aZ" +#define UI_TEXT_MOVE_Z_DELTA_IT "Movimento:%aZ" +#define UI_TEXT_JERK_IT "Scatto:%aj" +#define UI_TEXT_ZJERK_IT "Scatto-Z:%aJ" +#define UI_TEXT_ACCELERATION_IT "Accelerazione" +#define UI_TEXT_STORE_TO_EEPROM_IT "Salva in EEPROM" +#define UI_TEXT_LOAD_EEPROM_IT "Carica da EEPROM" +#define UI_TEXT_DBG_ECHO_IT "Eco :%do" +#define UI_TEXT_DBG_INFO_IT "Info :%di" +#define UI_TEXT_DBG_ERROR_IT "Errori :%de" +#define UI_TEXT_DBG_DRYRUN_IT "Simulazione:%dd" +#define UI_TEXT_DBG_ENDSTOP_IT "EndStop:%dp" +#define UI_TEXT_OPS_OFF_IT "%O0 OPS Spento" +#define UI_TEXT_OPS_CLASSIC_IT "%O1 OPS Classico" +#define UI_TEXT_OPS_FAST_IT "%O2 OPS Veloce" +#define UI_TEXT_OPS_RETRACT_IT "Ritiro :%Or" +#define UI_TEXT_OPS_BACKSLASH_IT "Gioco barra:%Ob" +#define UI_TEXT_OPS_MINDIST_IT "Distanza Min.:%Od" +#define UI_TEXT_OPS_MOVE_AFTER_IT "Movimento dopo:%Oa" +#define UI_TEXT_ANTI_OOZE_IT "Anti goccia" +#define UI_TEXT_PRINT_FILE_IT "Stampa file" +#define UI_TEXT_PAUSE_PRINT_IT "Pausa Stampa" +#define UI_TEXT_CONTINUE_PRINT_IT "Continua Stampa" +#define UI_TEXT_UNMOUNT_CARD_IT "Scarica Scheda" +#define UI_TEXT_MOUNT_CARD_IT "Carica Scheda" +#define UI_TEXT_DELETE_FILE_IT "Cancella file" +#define UI_TEXT_FEEDRATE_IT "Velocita'" +#define UI_TEXT_FEED_MAX_X_IT "Massimo X:%fx" +#define UI_TEXT_FEED_MAX_Y_IT "Massimo Y:%fy" +#define UI_TEXT_FEED_MAX_Z_IT "Massimo Z:%fz" +#define UI_TEXT_FEED_MAX_Z_DELTA_IT "Massimo:%fz" +#define UI_TEXT_FEED_HOME_X_IT "Origine X:%fX" +#define UI_TEXT_FEED_HOME_Y_IT "Origine Y:%fY" +#define UI_TEXT_FEED_HOME_Z_IT "Origine Z:%fZ" +#define UI_TEXT_FEED_HOME_Z_DELTA_IT "Origine:%fZ" +#define UI_TEXT_ACTION_XPOSITION4A_IT "X:%x0 mm %dx%dX" +#define UI_TEXT_ACTION_XPOSITION4B_IT "Min finec.:%sx" +#define UI_TEXT_ACTION_XPOSITION4C_IT "Max finec.:%sX" +#define UI_TEXT_ACTION_XPOSITION4D_IT "" +#define UI_TEXT_ACTION_YPOSITION4A_IT "Y:%x1 mm %dy%dY" +#define UI_TEXT_ACTION_YPOSITION4B_IT "Min finec.:%sy" +#define UI_TEXT_ACTION_YPOSITION4C_IT "Max finec.:%sY" +#define UI_TEXT_ACTION_YPOSITION4D_IT "" +#define UI_TEXT_ACTION_ZPOSITION4A_IT "Z:%x2 mm %dz%dZ" +#define UI_TEXT_ACTION_ZPOSITION4B_IT "Min finec.:%sz" +#define UI_TEXT_ACTION_ZPOSITION4C_IT "Max finec.:%sZ" +#define UI_TEXT_ACTION_ZPOSITION4D_IT "" +#define UI_TEXT_ACTION_XPOSITION_FAST4A_IT "X:%x0 mm" +#define UI_TEXT_ACTION_XPOSITION_FAST4B_IT "Min finec.:%sx" +#define UI_TEXT_ACTION_XPOSITION_FAST4C_IT "Max finec.:%sX" +#define UI_TEXT_ACTION_XPOSITION_FAST4D_IT "" +#define UI_TEXT_ACTION_YPOSITION_FAST4A_IT "Y:%x1 mm" +#define UI_TEXT_ACTION_YPOSITION_FAST4B_IT "Min finec.:%sy" +#define UI_TEXT_ACTION_YPOSITION_FAST4C_IT "Max finec.:%sY" +#define UI_TEXT_ACTION_YPOSITION_FAST4D_IT "" +#define UI_TEXT_ACTION_ZPOSITION_FAST4A_IT "Z:%x2 mm" +#define UI_TEXT_ACTION_ZPOSITION_FAST4B_IT "Min finec.:%sz" +#define UI_TEXT_ACTION_ZPOSITION_FAST4C_IT "Max finec.:%sZ" +#define UI_TEXT_ACTION_ZPOSITION_FAST4D_IT "" +#define UI_TEXT_ACTION_EPOSITION_FAST2A_IT "E:%x3 mm" +#define UI_TEXT_ACTION_EPOSITION_FAST2B_IT "1 scatto = 1 mm" +#define UI_TEXT_ACTION_XPOSITION2A_IT "X:%x0 mm" +#define UI_TEXT_ACTION_XPOSITION2B_IT "Min:%sx Max:%sX" +#define UI_TEXT_ACTION_YPOSITION2A_IT "Y:%x1 mm" +#define UI_TEXT_ACTION_YPOSITION2B_IT "Min:%sy Max:%sY" +#define UI_TEXT_ACTION_ZPOSITION2A_IT "Z:%x2 mm" +#define UI_TEXT_ACTION_ZPOSITION2B_IT "Min:%sz Max:%sZ" +#define UI_TEXT_ACTION_XPOSITION_FAST2A_IT "X:%x0 mm" +#define UI_TEXT_ACTION_XPOSITION_FAST2B_IT "Min:%sx Max:%sX" +#define UI_TEXT_ACTION_YPOSITION_FAST2A_IT "Y:%x1 mm" +#define UI_TEXT_ACTION_YPOSITION_FAST2B_IT "Min:%sy Max:%sY" +#define UI_TEXT_ACTION_ZPOSITION_FAST2A_IT "Z:%x2 mm" +#define UI_TEXT_ACTION_ZPOSITION_FAST2B_IT "Min:%sz Max:%sZ" +#define UI_TEXT_FANSPEED_IT "Velocita Ventola" +#define UI_TEXT_ACTION_FANSPEED_IT "Vel. Ventola:%Fs%%%" +#define UI_TEXT_FAN_OFF_IT "Spegnimento Ventola" +#define UI_TEXT_FAN_25_IT "Ventola al 25%%%" +#define UI_TEXT_FAN_50_IT "Ventola al%%%" +#define UI_TEXT_FAN_75_IT "Ventola al%%%" +#define UI_TEXT_FAN_FULL_IT "Ventola al massimo" +#define UI_TEXT_STEPPER_INACTIVE_IT "Stepper Inattivi" +#define UI_TEXT_STEPPER_INACTIVE2A_IT "Dis. dopo: %is" +#define UI_TEXT_STEPPER_INACTIVE2B_IT "[min] 0=Off" +#define UI_TEXT_POWER_INACTIVE_IT "Max. Inattivita'" +#define UI_TEXT_POWER_INACTIVE2A_IT "Dis. After: %ip" +#define UI_TEXT_POWER_INACTIVE2B_IT "[min] 0=Off" +#define UI_TEXT_GENERAL_IT "Generale" +#define UI_TEXT_BAUDRATE_IT "Baudrate:%oc" +#define UI_TEXT_EXTR_STEPS_IT "Passi/mm:%Se" +#define UI_TEXT_EXTR_START_FEED_IT "Velocita' Avvio:%Xf" +#define UI_TEXT_EXTR_MAX_FEED_IT "Velocita' Max:%XF" +#define UI_TEXT_EXTR_ACCEL_IT "Accel:%XA" +#define UI_TEXT_EXTR_WATCH_IT "Tempo Stab.:%Xw" +#define UI_TEXT_EXTR_ADVANCE_L_IT "Avanzamento lin:%Xl" +#define UI_TEXT_EXTR_ADVANCE_K_IT "Avanzamento espon:%Xa" +#define UI_TEXT_EXTR_MANAGER_IT "Controllo:%Xh" +#define UI_TEXT_EXTR_PGAIN_IT "PID P:%Xp" +#define UI_TEXT_EXTR_DEADTIME_IT "Tempo morto:%Xp" +#define UI_TEXT_EXTR_DMAX_DT_IT "Controllo PWM:%XM" +#define UI_TEXT_EXTR_IGAIN_IT "PID I:%Xi" +#define UI_TEXT_EXTR_DGAIN_IT "PID D:%Xd" +#define UI_TEXT_EXTR_DMIN_IT "Drive Min:%Xm" +#define UI_TEXT_EXTR_DMAX_IT "Drive Max:%XM" +#define UI_TEXT_EXTR_PMAX_IT "PID Max:%XD" +#define UI_TEXT_EXTR_XOFF_IT "X-Offset:%Xx" +#define UI_TEXT_EXTR_YOFF_IT "Y-Offset:%Xy" +#define UI_TEXT_STRING_HM_BANGBANG_IT "BangBang" +#define UI_TEXT_STRING_HM_PID_IT "PID" +#define UI_TEXT_STRING_ACTION_IT "Azione:%la" +#define UI_TEXT_HEATING_EXTRUDER_IT "Riscald. Estrusore" +#define UI_TEXT_HEATING_BED_IT "Riscald. Piatto" +#define UI_TEXT_KILLED_IT "Abortito" +#define UI_TEXT_STEPPER_DISABLED_IT "Stepper Disabilitato" +#define UI_TEXT_EEPROM_STOREDA_IT "Configurazione" +#define UI_TEXT_EEPROM_STOREDB_IT "Salvata in EEPROM" +#define UI_TEXT_EEPROM_LOADEDA_IT "Configurazione" +#define UI_TEXT_EEPROM_LOADEDB_IT "Caricata da EEPROM" +#define UI_TEXT_UPLOADING_IT "Caricamento..." +#define UI_TEXT_PAGE_BUFFER_IT "Tampone:%oB" +#define UI_TEXT_PAGE_EXTRUDER_IT " E:%ec/%Ec" cDEG "C" cARROW "%oC" +#define UI_TEXT_PAGE_EXTRUDER1_IT "E1:%e0/%E0" cDEG "C" cARROW "%o0" +#define UI_TEXT_PAGE_EXTRUDER2_IT "E2:%e1/%E1" cDEG "C" cARROW "%o1" +#define UI_TEXT_PAGE_EXTRUDER3_IT "E3:%e2/%E2" cDEG "C" cARROW "%o2" +#define UI_TEXT_PAGE_BED_IT " B:%eb/%Eb" cDEG "C" cARROW "%ob" +#define UI_TEXT_SPEED_MULTIPLY_IT "Molt. Velocita':%om%%%" +#define UI_TEXT_FLOW_MULTIPLY_IT "Molt. Flusso:%of%%%" +#define UI_TEXT_SHOW_MEASUREMENT_IT "Mostra di misura" +#define UI_TEXT_RESET_MEASUREMENT_IT "Ripristino di misura" +#define UI_TEXT_SET_MEASURED_ORIGIN_IT "Set Z=0" +#define UI_TEXT_ZCALIB_IT "Z Calib." +#define UI_TEXT_SET_P1_IT "Impostato P1" +#define UI_TEXT_SET_P2_IT "Impostato P2" +#define UI_TEXT_SET_P3_IT "Impostato P3" +#define UI_TEXT_CALCULATE_LEVELING_IT "Calcol. livellamento" +#define UI_TEXT_LEVEL_IT "Livello delta" +#define UI_TEXT_EXTR_WAIT_RETRACT_TEMP_IT "Attesa Temp.%XT" cDEG "C" +#define UI_TEXT_EXTR_WAIT_RETRACT_UNITS_IT "Attesa Unita':%XUmm" +#define UI_TEXT_SD_REMOVED_IT "SD Card rimosso" +#define UI_TEXT_SD_INSERTED_IT "SD Card inserita" +#define UI_TEXT_PRINTER_READY_IT "Stampante pronta." +// Printtime output gets aggregated like UI_TEXT_PRINTTIME_DAYSUI_TEXT_PRINTTIME_HOURSUI_TEXT_PRINTTIME_MINUTES +// ___88 days 12:45 +#define UI_TEXT_PRINTTIME_DAYS_IT " giorni " +#define UI_TEXT_PRINTTIME_HOURS_IT ":" +#define UI_TEXT_PRINTTIME_MINUTES_IT "" +#define UI_TEXT_PRINT_TIME_IT "Tempo di stampa" +#define UI_TEXT_PRINT_FILAMENT_IT "Filament stampata" +#define UI_TEXT_PRINTED_IT "stampato" +#define UI_TEXT_POWER_IT "ATX on/off" +#define UI_TEXT_STRING_HM_DEADTIME_IT "Tempo morto" +#define UI_TEXT_STRING_HM_SLOWBANG_IT "SlowBang" +#define UI_TEXT_STOP_PRINT_IT "Arresto Stampa" +#define UI_TEXT_Z_BABYSTEPPING_IT "Z Babystep.:%oYmm" +#define UI_TEXT_CHANGE_FILAMENT_IT "Cambia filamento" +#define UI_TEXT_WIZ_CH_FILAMENT1_IT "Cambia filamento" +#define UI_TEXT_WIZ_CH_FILAMENT2_IT "Ruotare per spostare" +#define UI_TEXT_WIZ_CH_FILAMENT3_IT "filamento su/giu" +#define UI_TEXT_CLICK_DONE_IT "Clicca quando fatto" +#define UI_TEXT_AUTOLEVEL_ONOFF_IT "Autoliv.: %ll" +#define UI_TEXT_SERVOPOS_IT "Pos. servo: %oS" +#define UI_TEXT_IGNORE_M106_IT "Ignora M106 cmd %Fi" +#define UI_TEXT_WIZ_REHEAT1_IT "Clicca per" +#define UI_TEXT_WIZ_REHEAT2_IT "riscaldare estrusori" +#define UI_TEXT_WIZ_WAITTEMP1_IT "Attendere che temp." +#define UI_TEXT_WIZ_WAITTEMP2_IT "di destinazione ..." +#define UI_TEXT_EXTRUDER_JAM_IT "Stoccaggio estrusore" +#define UI_TEXT_STANDBY_IT "Stand-by" +#define UI_TEXT_BED_COATING_IT "Rivestimento letto" +#define UI_TEXT_BED_COATING_SET1_IT "Rivestimento letto:" +#define UI_TEXT_BED_COATING_SET2_IT "" +#define UI_TEXT_NOCOATING_IT "Non rivestito" +#define UI_TEXT_BUILDTAK_IT "BuildTak" +#define UI_TEXT_KAPTON_IT "Kapton" +#define UI_TEXT_BLUETAPE_IT "Blu nastro adesivo" +#define UI_TEXT_PETTAPE_IT "Verde PET nastro" +#define UI_TEXT_GLUESTICK_IT "Colla stick" +#define UI_TEXT_CUSTOM_IT "Usanza" +#define UI_TEXT_COATING_CUSTOM_IT "Usanza:%BCmm" +#define UI_TEXT_LANGUAGE_IT "Lingua" + +#if NUM_EXTRUDER > 2 || MIXING_EXTRUDER != 0 +#define UI_TEXT_MAINPAGE6_1_IT "\xa %ec/%Ec\xb0 X:%x0" +#else +#define UI_TEXT_MAINPAGE6_1_IT "\xa %e0/%E0\xb0 X:%x0" +#endif // NUM_EXTRUDER +#if NUM_EXTRUDER == 2 && MIXING_EXTRUDER == 0 +#define UI_TEXT_MAINPAGE6_2_IT "\xa %e1/%E1\xb0 Y:%x1" +#elif HAVE_HEATED_BED +#define UI_TEXT_MAINPAGE6_2_IT "\xe %eb/%Eb\xb0 Y:%x1" +#else +#define UI_TEXT_MAINPAGE6_2_IT " Y:%x1" +#endif +#if HAVE_HEATED_BED && NUM_EXTRUDER == 2 && MIXING_EXTRUDER == 0 +#define UI_TEXT_MAINPAGE6_3_IT "\xe %eb/%Eb\xb0 Z:%x2" +#elif FEATURE_DITTO_PRINTING +#define UI_TEXT_MAINPAGE6_3_IT "Copie: %ed Z:%x2" +#else +#define UI_TEXT_MAINPAGE6_3_IT "Flusso:\xfd %of%%% Z:%x2" +#endif +#define UI_TEXT_MAINPAGE6_4_IT "Mul: %om%%% \xfd E: %x4m" +#define UI_TEXT_MAINPAGE6_5_IT "Buf: %oB" +#define UI_TEXT_MAINPAGE6_6_IT "%os" +#define UI_TEXT_MAINPAGE_TEMP_BED_IT cTEMP "%ec/%Ec" cDEG "B%eB/%Eb" cDEG +#define UI_TEXT_MAINPAGE_BED_IT "B%eB/%Eb" cDEG +#define UI_TEXT_MAINPAGE_Z_BUF_IT "Z:%x2 Buf : %oB" +#define UI_TEXT_MAINPAGE_MUL_EUSAGE_IT "Mul: %om E:%x4" +#define UI_TEXT_MAINPAGE_XY_IT "X:%x0 Y:%x1" +#define UI_TEXT_PRINT_TIME_VALUE_IT "%Ut" +#define UI_TEXT_PRINT_FILAMENT_VALUE_IT "%Uf m" +#define UI_TEXT_METER_PRINTED_IT "%Uf m " UI_TEXT_PRINTED_IT +#define UI_TEXT_STATUS_IT "%os" +#define UI_TEXT_EMPTY_IT "" +#define UI_TEXT_TEMP_SET_IT cTEMP "%ec/%Ec" cDEG +#define UI_TEXT_CURRENT_TEMP_IT cTEMP "%ec" cDEG +#define UI_TEXT_COATING_THICKNESS_IT " %BCmm" +#define UI_TEXT_EXTR3_TEMP_IT "Temp. 4 :%e3/%E3" cDEG "C" +#define UI_TEXT_EXTR4_TEMP_IT "Temp. 5 :%e4/%E4" cDEG "C" +#define UI_TEXT_EXTR5_TEMP_IT "Temp. 6 :%e5/%E5" cDEG "C" +#define UI_TEXT_EXTR3_OFF_IT "Estrusore 4 Spento" +#define UI_TEXT_EXTR4_OFF_IT "Estrusore 5 Spento" +#define UI_TEXT_EXTR5_OFF_IT "Estrusore 6 Spento" +#define UI_TEXT_EXTR3_SELECT_IT "%X3 Seleziona Estr. 4" +#define UI_TEXT_EXTR4_SELECT_IT "%X4 Seleziona Estr. 5" +#define UI_TEXT_EXTR5_SELECT_IT "%X5 Seleziona Estr. 6" +#define UI_TEXT_DITTO_0_IT "%D0 Nessuna Copia" +#define UI_TEXT_DITTO_1_IT "%D1 1 Copia" +#define UI_TEXT_DITTO_2_IT "%D2 2 Copie" +#define UI_TEXT_DITTO_3_IT "%D3 3 Copie" +#define UI_TEXT_ZPROBE_HEIGHT_IT "Altezza Z-Probe:%zh" + + + +#define UI_TEXT_OFFSETS_IT "Set print offsets" +#define UI_TEXT_X_OFFSET_IT "Set X offset:%T0mm" +#define UI_TEXT_Y_OFFSET_IT "Set Y offset:%T1mm" +#define UI_TEXT_Z_OFFSET_IT "Set Z offset:%T2mm" + + +// Spanish translation + +#define UI_TEXT_ON_ES "On" +#define UI_TEXT_OFF_ES "Off" +#define UI_TEXT_NA_ES "N/A" // Output for not available +#define UI_TEXT_YES_ES "Si" +#define UI_TEXT_NO_ES "No" +#define UI_TEXT_PRINT_POS_ES "Imprimiendo..." +#define UI_TEXT_PRINTING_ES "Imprimiendo" +#define UI_TEXT_IDLE_ES "Idle" +#define UI_TEXT_NOSDCARD_ES "Sin tarjeta SD" +#define UI_TEXT_ERROR_ES "**** ERROR ****" +#define UI_TEXT_BACK_ES "Atras " cUP +#define UI_TEXT_QUICK_SETTINGS_ES "Configuracion Rapida" +#define UI_TEXT_ERRORMSG_ES "%oe" +#define UI_TEXT_CONFIGURATION_ES "Configuracion" +#define UI_TEXT_POSITION_ES "Posicion" +#define UI_TEXT_EXTRUDER_ES "Extrusor" +#define UI_TEXT_SD_CARD_ES "Tarjeta SD" +#define UI_TEXT_DEBUGGING_ES "Debugging" +#define UI_TEXT_HOME_DELTA_ES "Delta Home" +#define UI_TEXT_HOME_ALL_ES "Todo Home" +#define UI_TEXT_HOME_X_ES "X Home" +#define UI_TEXT_HOME_Y_ES "Y Home" +#define UI_TEXT_HOME_Z_ES "Z Home" +#define UI_TEXT_PREHEAT_PLA_ES "Precalentar PLA" +#define UI_TEXT_PREHEAT_ABS_ES "Precalentar ABS" +#define UI_TEXT_LIGHTS_ONOFF_ES "Luces:%lo" +#define UI_TEXT_COOLDOWN_ES "Enfriar" +#define UI_TEXT_SET_TO_ORIGIN_ES "Fija a origen" +#define UI_TEXT_DISABLE_STEPPER_ES "Desactiva motor" +#define UI_TEXT_X_POSITION_ES "Posicion X" +#define UI_TEXT_X_POS_FAST_ES "Pos. Rapida X" +#define UI_TEXT_Y_POSITION_ES "Posicion Y" +#define UI_TEXT_Y_POS_FAST_ES "Pos. Rapida Y" +#define UI_TEXT_Z_POSITION_ES "Posicion Z" +#define UI_TEXT_Z_POS_FAST_ES "Pos. Rapida Z" +#define UI_TEXT_E_POSITION_ES "Extr. Posicion" +#define UI_TEXT_BED_TEMP_ES "Temp.Cama:%eb/%Eb" cDEG "C" +#define UI_TEXT_EXTR0_TEMP_ES "Temp. 1 :%e0/%E0" cDEG "C" +#define UI_TEXT_EXTR1_TEMP_ES "Temp. 2 :%e1/%E1" cDEG "C" +#define UI_TEXT_EXTR2_TEMP_ES "Temp. 3 :%e2/%E2" cDEG "C" +#define UI_TEXT_EXTR0_OFF_ES "Extrusor 1 Off" +#define UI_TEXT_EXTR1_OFF_ES "Extrusor 2 Off" +#define UI_TEXT_EXTR2_OFF_ES "Extrusor 3 Off" +#define UI_TEXT_EXTR0_SELECT_ES "%X0 Select Extr. 1" +#define UI_TEXT_EXTR1_SELECT_ES "%X1 Select Extr. 2" +#define UI_TEXT_EXTR2_SELECT_ES "%X2 Select Extr. 3" +#define UI_TEXT_EXTR_ORIGIN_ES "Fija Originen" +#define UI_TEXT_PRINT_X_ES "Print X:%ax" +#define UI_TEXT_PRINT_Y_ES "Print Y:%ay" +#define UI_TEXT_PRINT_Z_ES "Print Z:%az" +#define UI_TEXT_PRINT_Z_DELTA_ES "Print:%az" +#define UI_TEXT_MOVE_X_ES "Mueve X:%aX" +#define UI_TEXT_MOVE_Y_ES "Mueve Y:%aY" +#define UI_TEXT_MOVE_Z_ES "Mueve Z:%aZ" +#define UI_TEXT_MOVE_Z_DELTA_ES "Mueve:%aZ" +#define UI_TEXT_JERK_ES "Jerk:%aj" +#define UI_TEXT_ZJERK_ES "Z-Jerk:%aJ" +#define UI_TEXT_ACCELERATION_ES "Aceleracion" +#define UI_TEXT_STORE_TO_EEPROM_ES "Almacena en EEPROM" +#define UI_TEXT_LOAD_EEPROM_ES "Carga de EEPROM" +#define UI_TEXT_DBG_ECHO_ES "Echo :%do" +#define UI_TEXT_DBG_INFO_ES "Info :%di" +#define UI_TEXT_DBG_ERROR_ES "Errors :%de" +#define UI_TEXT_DBG_DRYRUN_ES "Ejecucion vacio:%dd" +#define UI_TEXT_DBG_ENDSTOP_ES "EndStop:%dp" +#define UI_TEXT_OPS_OFF_ES "%O0 OPS Off" +#define UI_TEXT_OPS_CLASSIC_ES "%O1 OPS Classica" +#define UI_TEXT_OPS_FAST_ES "%O2 OPS Rapida" +#define UI_TEXT_OPS_RETRACT_ES "Retraccion :%Or" +#define UI_TEXT_OPS_BACKSLASH_ES "Backsl. :%Ob" +#define UI_TEXT_OPS_MINDIST_ES "Min.dist:%Od" +#define UI_TEXT_OPS_MOVE_AFTER_ES "Move after:%Oa" +#define UI_TEXT_ANTI_OOZE_ES "Anti Ooze" +#define UI_TEXT_PRINT_FILE_ES "Imprimiendo fichero" +#define UI_TEXT_PAUSE_PRINT_ES "Pausando impresion" +#define UI_TEXT_CONTINUE_PRINT_ES "Continuando impresion" +#define UI_TEXT_UNMOUNT_CARD_ES "Desmontando Tarjeta" +#define UI_TEXT_MOUNT_CARD_ES "Montando Card" +#define UI_TEXT_DELETE_FILE_ES "Borrando fichero" +#define UI_TEXT_FEEDRATE_ES "Feedrate" +#define UI_TEXT_FEED_MAX_X_ES "X Max:%fx" +#define UI_TEXT_FEED_MAX_Y_ES "Y Max:%fy" +#define UI_TEXT_FEED_MAX_Z_ES "Z Max:%fz" +#define UI_TEXT_FEED_MAX_Z_DELTA_ES "Max:%fz" +#define UI_TEXT_FEED_HOME_X_ES "X Home:%fX" +#define UI_TEXT_FEED_HOME_Y_ES "Y Home:%fY" +#define UI_TEXT_FEED_HOME_Z_ES "Z Home:%fZ" +#define UI_TEXT_FEED_HOME_Z_DELTA_ES "Home:%fZ" +#define UI_TEXT_ACTION_XPOSITION4A_ES "X:%x0 mm %dx%dX" +#define UI_TEXT_ACTION_XPOSITION4B_ES "Fin Carrera Min:%sx" +#define UI_TEXT_ACTION_XPOSITION4C_ES "Max:%sX" +#define UI_TEXT_ACTION_XPOSITION4D_ES "" +#define UI_TEXT_ACTION_YPOSITION4A_ES "Y:%x1 mm %dy%dY" +#define UI_TEXT_ACTION_YPOSITION4B_ES "Fin Carrera Min:%sy" +#define UI_TEXT_ACTION_YPOSITION4C_ES "Max:%sY" +#define UI_TEXT_ACTION_YPOSITION4D_ES "" +#define UI_TEXT_ACTION_ZPOSITION4A_ES "Z:%x2 mm %dz%dZ" +#define UI_TEXT_ACTION_ZPOSITION4B_ES "Fin Carrera Min:%sz" +#define UI_TEXT_ACTION_ZPOSITION4C_ES "Max:%sZ" +#define UI_TEXT_ACTION_ZPOSITION4D_ES "" +#define UI_TEXT_ACTION_XPOSITION_FAST4A_ES "X:%x0 mm" +#define UI_TEXT_ACTION_XPOSITION_FAST4B_ES "Fin Carrera Min:%sx" +#define UI_TEXT_ACTION_XPOSITION_FAST4C_ES "Max:%sX" +#define UI_TEXT_ACTION_XPOSITION_FAST4D_ES "" +#define UI_TEXT_ACTION_YPOSITION_FAST4A_ES "Y:%x1 mm" +#define UI_TEXT_ACTION_YPOSITION_FAST4B_ES "Fin Carrera Min:%sy" +#define UI_TEXT_ACTION_YPOSITION_FAST4C_ES "Max:%sY" +#define UI_TEXT_ACTION_YPOSITION_FAST4D_ES "" +#define UI_TEXT_ACTION_ZPOSITION_FAST4A_ES "Z:%x2 mm" +#define UI_TEXT_ACTION_ZPOSITION_FAST4B_ES "Fin Carrera Min:%sz" +#define UI_TEXT_ACTION_ZPOSITION_FAST4C_ES "Max:%sZ" +#define UI_TEXT_ACTION_ZPOSITION_FAST4D_ES "" +#define UI_TEXT_ACTION_EPOSITION_FAST2A_ES "E:%x3 mm" +#define UI_TEXT_ACTION_EPOSITION_FAST2B_ES "1 click = 1 mm" +#define UI_TEXT_ACTION_XPOSITION2A_ES "X:%x0 mm" +#define UI_TEXT_ACTION_XPOSITION2B_ES "Min:%sx Max:%sX" +#define UI_TEXT_ACTION_YPOSITION2A_ES "Y:%x1 mm" +#define UI_TEXT_ACTION_YPOSITION2B_ES "Min:%sy Max:%sY" +#define UI_TEXT_ACTION_ZPOSITION2A_ES "Z:%x2 mm" +#define UI_TEXT_ACTION_ZPOSITION2B_ES "Min:%sz Max:%sZ" +#define UI_TEXT_ACTION_XPOSITION_FAST2A_ES "X:%x0 mm" +#define UI_TEXT_ACTION_XPOSITION_FAST2B_ES "Min:%sx Max:%sX" +#define UI_TEXT_ACTION_YPOSITION_FAST2A_ES "Y:%x1 mm" +#define UI_TEXT_ACTION_YPOSITION_FAST2B_ES "Min:%sy Max:%sY" +#define UI_TEXT_ACTION_ZPOSITION_FAST2A_ES "Z:%x2 mm" +#define UI_TEXT_ACTION_ZPOSITION_FAST2B_ES "Min:%sz Max:%sZ" +#define UI_TEXT_FANSPEED_ES "Velocida ventilador" +#define UI_TEXT_ACTION_FANSPEED_ES "Vel. vent.:%Fs%%%" +#define UI_TEXT_FAN_OFF_ES "Apaga ventilador" +#define UI_TEXT_FAN_25_ES "Ventilador al 25%%%" +#define UI_TEXT_FAN_50_ES "Ventilador al 50%%%" +#define UI_TEXT_FAN_75_ES "Ventilador al 75%%%" +#define UI_TEXT_FAN_FULL_ES "Ventilador al 100%%%" +#define UI_TEXT_STEPPER_INACTIVE_ES "Motor Inactivo" +#define UI_TEXT_STEPPER_INACTIVE2A_ES "Dis. Despues: %is" +#define UI_TEXT_STEPPER_INACTIVE2B_ES "[min] 0=Off" +#define UI_TEXT_POWER_INACTIVE_ES "Max. Inactivo" +#define UI_TEXT_POWER_INACTIVE2A_ES "Dis. Despues: %ip" +#define UI_TEXT_POWER_INACTIVE2B_ES "[min] 0=Off" +#define UI_TEXT_GENERAL_ES "General" +#define UI_TEXT_BAUDRATE_ES "Baudrate:%oc" +#define UI_TEXT_EXTR_STEPS_ES "Pasos/MM:%Se" +#define UI_TEXT_EXTR_START_FEED_ES "Start FR:%Xf" +#define UI_TEXT_EXTR_MAX_FEED_ES "Max FR:%XF" +#define UI_TEXT_EXTR_ACCEL_ES "Acel:%XA" +#define UI_TEXT_EXTR_WATCH_ES "Tiempo Estab.:%Xw" +#define UI_TEXT_EXTR_ADVANCE_L_ES "Advance lin:%Xl" +#define UI_TEXT_EXTR_ADVANCE_K_ES "Advance quad:%Xa" +#define UI_TEXT_EXTR_MANAGER_ES "Control:%Xh" +#define UI_TEXT_EXTR_PGAIN_ES "PID P:%Xp" +#define UI_TEXT_EXTR_DEADTIME_ES "Tiempo muerto:%Xp" +#define UI_TEXT_EXTR_DMAX_DT_ES "PWM control:%XM" +#define UI_TEXT_EXTR_IGAIN_ES "PID I:%Xi" +#define UI_TEXT_EXTR_DGAIN_ES "PID D:%Xd" +#define UI_TEXT_EXTR_DMIN_ES "Drive Min:%Xm" +#define UI_TEXT_EXTR_DMAX_ES "Drive Max:%XM" +#define UI_TEXT_EXTR_PMAX_ES "PID Max:%XD" +#define UI_TEXT_EXTR_XOFF_ES "X-Offset:%Xx" +#define UI_TEXT_EXTR_YOFF_ES "Y-Offset:%Xy" +#define UI_TEXT_STRING_HM_BANGBANG_ES "BangBang" +#define UI_TEXT_STRING_HM_PID_ES "PID" +#define UI_TEXT_STRING_ACTION_ES "Accion:%la" +#define UI_TEXT_HEATING_EXTRUDER_ES "Calentando Extrusor" +#define UI_TEXT_HEATING_BED_ES "Calentando Cama" +#define UI_TEXT_KILLED_ES "Aborta" +#define UI_TEXT_STEPPER_DISABLED_ES "Deshabilita motor" +#define UI_TEXT_EEPROM_STOREDA_ES "Config." +#define UI_TEXT_EEPROM_STOREDB_ES "almacenada en EEPROM" +#define UI_TEXT_EEPROM_LOADEDA_ES "Config." +#define UI_TEXT_EEPROM_LOADEDB_ES "cargada de EEPROM" +#define UI_TEXT_UPLOADING_ES "Actualizando..." +#define UI_TEXT_PAGE_BUFFER_ES "Buffer:%oB" +#define UI_TEXT_PAGE_EXTRUDER_ES " E:%ec/%Ec" cDEG "C" cARROW "%oC" +#define UI_TEXT_PAGE_EXTRUDER1_ES "E1:%e0/%E0" cDEG "C" cARROW "%o0" +#define UI_TEXT_PAGE_EXTRUDER2_ES "E2:%e1/%E1" cDEG "C" cARROW "%o1" +#define UI_TEXT_PAGE_EXTRUDER3_ES "E3:%e2/%E2" cDEG "C" cARROW "%o2" +#define UI_TEXT_PAGE_BED_ES " B:%eb/%Eb" cDEG "C" cARROW "%ob" +#define UI_TEXT_SPEED_MULTIPLY_ES "Mult. Velocidad.:%om%%%" +#define UI_TEXT_FLOW_MULTIPLY_ES "Mult. Flujo:%of%%%" +#define UI_TEXT_SHOW_MEASUREMENT_ES "Mostrar medicion" +#define UI_TEXT_RESET_MEASUREMENT_ES "Resetear medicion" +#define UI_TEXT_SET_MEASURED_ORIGIN_ES "Set Z=0" +#define UI_TEXT_ZCALIB_ES "Z calib." +#define UI_TEXT_SET_P1_ES "Set P1" +#define UI_TEXT_SET_P2_ES "Set P2" +#define UI_TEXT_SET_P3_ES "Set P3" +#define UI_TEXT_CALCULATE_LEVELING_ES "Calcula nivelacion" +#define UI_TEXT_LEVEL_ES "Nivel delta" +#define UI_TEXT_EXTR_WAIT_RETRACT_TEMP_ES "Esperando Temp.%XT" cDEG "C" +#define UI_TEXT_EXTR_WAIT_RETRACT_UNITS_ES "Esperando Unidad:%XUmm" +#define UI_TEXT_SD_REMOVED_ES "Tarjeta SD retira" +#define UI_TEXT_SD_INSERTED_ES "Tarjeta SD insertada" +#define UI_TEXT_PRINTER_READY_ES "Impresora lista." +// Printtime output gets aggregated like UI_TEXT_PRINTTIME_DAYSUI_TEXT_PRINTTIME_HOURSUI_TEXT_PRINTTIME_MINUTES +// ___88 days 12:45 +#define UI_TEXT_PRINTTIME_DAYS_ES " dias " +#define UI_TEXT_PRINTTIME_HOURS_ES ":" +#define UI_TEXT_PRINTTIME_MINUTES_ES "" +#define UI_TEXT_PRINT_TIME_ES "tiempo de impresion" +#define UI_TEXT_PRINT_FILAMENT_ES "Filamento impresa" +#define UI_TEXT_PRINTED_ES "impreso" +#define UI_TEXT_POWER_ES "Energie ATX on/off" +#define UI_TEXT_STRING_HM_DEADTIME_ES "Tiempo muerto" +#define UI_TEXT_STRING_HM_SLOWBANG_ES "SlowBang" +#define UI_TEXT_STOP_PRINT_ES "Detener impresion" +#define UI_TEXT_Z_BABYSTEPPING_ES "Z Babystep.:%oYmm" +#define UI_TEXT_CHANGE_FILAMENT_ES "Cambio filamento" +#define UI_TEXT_WIZ_CH_FILAMENT1_ES "Cambio filamento" +#define UI_TEXT_WIZ_CH_FILAMENT2_ES "Gire para mover" +#define UI_TEXT_WIZ_CH_FILAMENT3_ES "fil. arriba/abajo" +#define UI_TEXT_CLICK_DONE_ES "Clic cuando se hace" +#define UI_TEXT_AUTOLEVEL_ONOFF_ES "Autolevel: %ll" +#define UI_TEXT_SERVOPOS_ES "Pos. servo: %oS" +#define UI_TEXT_IGNORE_M106_ES "Ignorar M106 cmd %Fi" +#define UI_TEXT_WIZ_REHEAT1_ES "Haga clic para" +#define UI_TEXT_WIZ_REHEAT2_ES "recalentar extr." +#define UI_TEXT_WIZ_WAITTEMP1_ES "Espere a temp." +#define UI_TEXT_WIZ_WAITTEMP2_ES "objetivo ..." +#define UI_TEXT_EXTRUDER_JAM_ES "Atasco extrusora" +#define UI_TEXT_STANDBY_ES "Standby" +#define UI_TEXT_BED_COATING_ES "Recubrimiento cama" +#define UI_TEXT_BED_COATING_SET1_ES "Rec. cama ajustado a" +#define UI_TEXT_BED_COATING_SET2_ES "" +#define UI_TEXT_NOCOATING_ES "Sin recubrimiento" +#define UI_TEXT_BUILDTAK_ES "BuildTak" +#define UI_TEXT_KAPTON_ES "Kapton" +#define UI_TEXT_BLUETAPE_ES "Cinta adhesiva azul" +#define UI_TEXT_PETTAPE_ES "Verde PET cinta" +#define UI_TEXT_GLUESTICK_ES "Barra de pegamento" +#define UI_TEXT_CUSTOM_ES "Custom" +#define UI_TEXT_COATING_CUSTOM_ES "Custom:%BCmm" +#define UI_TEXT_LANGUAGE_ES "Idioma" + +#if NUM_EXTRUDER > 2 || MIXING_EXTRUDER != 0 +#define UI_TEXT_MAINPAGE6_1_ES "\xa %ec/%Ec\xb0 X:%x0" +#else +#define UI_TEXT_MAINPAGE6_1_ES "\xa %e0/%E0\xb0 X:%x0" +#endif // NUM_EXTRUDER +#if NUM_EXTRUDER == 2 && MIXING_EXTRUDER == 0 +#define UI_TEXT_MAINPAGE6_2_ES "\xa %e1/%E1\xb0 Y:%x1" +#elif HAVE_HEATED_BED +#define UI_TEXT_MAINPAGE6_2_ES "\xe %eb/%Eb\xb0 Y:%x1" +#else +#define UI_TEXT_MAINPAGE6_2_ES " Y:%x1" +#endif +#if HAVE_HEATED_BED && NUM_EXTRUDER == 2 && MIXING_EXTRUDER == 0 +#define UI_TEXT_MAINPAGE6_3_ES "\xe %eb/%Eb\xb0 Z:%x2" +#elif FEATURE_DITTO_PRINTING +#define UI_TEXT_MAINPAGE6_3_ES "Copias: %ed Z:%x2" +#else +#define UI_TEXT_MAINPAGE6_3_ES "Flujo:\xfd %of%%% Z:%x2" +#endif +#define UI_TEXT_MAINPAGE6_4_ES "Mul: %om%%% \xfd E: %x4m" +#define UI_TEXT_MAINPAGE6_5_ES "Buf: %oB" +#define UI_TEXT_MAINPAGE6_6_ES "%os" +#define UI_TEXT_MAINPAGE_TEMP_BED_ES cTEMP "%ec/%Ec" cDEG "B%eB/%Eb" cDEG +#define UI_TEXT_MAINPAGE_BED_ES "B%eB/%Eb" cDEG +#define UI_TEXT_MAINPAGE_Z_BUF_ES "Z:%x2 Buf : %oB" +#define UI_TEXT_MAINPAGE_MUL_EUSAGE_ES "Mul: %om E:%x4" +#define UI_TEXT_MAINPAGE_XY_ES "X:%x0 Y:%x1" +#define UI_TEXT_PRINT_TIME_VALUE_ES "%Ut" +#define UI_TEXT_PRINT_FILAMENT_VALUE_ES "%Uf m" +#define UI_TEXT_METER_PRINTED_ES "%Uf m " UI_TEXT_PRINTED_ES +#define UI_TEXT_STATUS_ES "%os" +#define UI_TEXT_EMPTY_ES "" +#define UI_TEXT_TEMP_SET_ES cTEMP "%ec/%Ec" cDEG +#define UI_TEXT_CURRENT_TEMP_ES cTEMP "%ec" cDEG +#define UI_TEXT_COATING_THICKNESS_ES " %BCmm" +#define UI_TEXT_EXTR3_TEMP_ES "Temp. 4 :%e3/%E3" cDEG "C" +#define UI_TEXT_EXTR4_TEMP_ES "Temp. 5 :%e4/%E4" cDEG "C" +#define UI_TEXT_EXTR5_TEMP_ES "Temp. 6 :%e5/%E5" cDEG "C" +#define UI_TEXT_EXTR3_OFF_ES "Extrusor 4 Off" +#define UI_TEXT_EXTR4_OFF_ES "Extrusor 5 Off" +#define UI_TEXT_EXTR5_OFF_ES "Extrusor 6 Off" +#define UI_TEXT_EXTR3_SELECT_ES "%X3 Select Extr. 4" +#define UI_TEXT_EXTR4_SELECT_ES "%X4 Select Extr. 5" +#define UI_TEXT_EXTR5_SELECT_ES "%X5 Select Extr. 6" +#define UI_TEXT_DITTO_0_ES "%D0 No Hay Copias" +#define UI_TEXT_DITTO_1_ES "%D1 1 Copia" +#define UI_TEXT_DITTO_2_ES "%D2 2 Copias" +#define UI_TEXT_DITTO_3_ES "%D3 3 Copias" +#define UI_TEXT_ZPROBE_HEIGHT_ES "Altura Z-Probe:%zh" + + +#define UI_TEXT_OFFSETS_ES "Set print offsets" +#define UI_TEXT_X_OFFSET_ES "Set X offset:%T0mm" +#define UI_TEXT_Y_OFFSET_ES "Set Y offset:%T1mm" +#define UI_TEXT_Z_OFFSET_ES "Set Z offset:%T2mm" + + +// *************** Swedish translation **************** +// By Daniel Tedenljung 2013-08-21 + +#define UI_TEXT_ON_SE "P" STR_uuml "" +#define UI_TEXT_OFF_SE "Av" +#define UI_TEXT_NA_SE "N/A" // Output for not available +#define UI_TEXT_YES_SE "Ja" +#define UI_TEXT_NO_SE "Nej" +#define UI_TEXT_PRINT_POS_SE "Skriver ut..." +#define UI_TEXT_PRINTING_SE "Skriver" +#define UI_TEXT_IDLE_SE "Sysslol" STR_ouml "s" +#define UI_TEXT_NOSDCARD_SE "Inget SD-kort" +#define UI_TEXT_ERROR_SE "**** FEL ****" +#define UI_TEXT_BACK_SE "Tillbaka " cUP +#define UI_TEXT_QUICK_SETTINGS_SE "Inst" STR_auml "llnigar" +#define UI_TEXT_ERRORMSG_SE "%oe" +#define UI_TEXT_CONFIGURATION_SE "Konfiguration" +#define UI_TEXT_POSITION_SE "Position" +#define UI_TEXT_EXTRUDER_SE "Extruder" +#define UI_TEXT_SD_CARD_SE "SD-kort" +#define UI_TEXT_DEBUGGING_SE "Debugging" +#define UI_TEXT_HOME_DELTA_SE "Hem delta" +#define UI_TEXT_HOME_ALL_SE "K" STR_ouml "r hem alla" +#define UI_TEXT_HOME_X_SE "K" STR_ouml "r hem X" +#define UI_TEXT_HOME_Y_SE "K" STR_ouml "r hem Y" +#define UI_TEXT_HOME_Z_SE "K" STR_ouml "r hem Z" +#define UI_TEXT_PREHEAT_PLA_SE "F" STR_ouml "rv" STR_auml "rm f" STR_ouml "r PLA" +#define UI_TEXT_PREHEAT_ABS_SE "F" STR_ouml "rv" STR_auml "rm f" STR_ouml "r ABS" +#define UI_TEXT_LIGHTS_ONOFF_SE "Lights:%lo" +#define UI_TEXT_COOLDOWN_SE "Kyl ner" +#define UI_TEXT_SET_TO_ORIGIN_SE "S" STR_auml "tt som origo" +#define UI_TEXT_DISABLE_STEPPER_SE "St" STR_auml "ng av stegmotor" +#define UI_TEXT_X_POSITION_SE "X-position" +#define UI_TEXT_X_POS_FAST_SE "X-pos. snabb" +#define UI_TEXT_Y_POSITION_SE "Y-position" +#define UI_TEXT_Y_POS_FAST_SE "Y-pos. snabb" +#define UI_TEXT_Z_POSITION_SE "Z-osition" +#define UI_TEXT_Z_POS_FAST_SE "Z-pos. snabb" +#define UI_TEXT_E_POSITION_SE "Extr.-position" +#define UI_TEXT_BED_TEMP_SE "B" STR_auml "dd-temp:%eb/%Eb" cDEG "C" +#define UI_TEXT_EXTR0_TEMP_SE "Temp. 1 :%e0/%E0" cDEG "C" +#define UI_TEXT_EXTR1_TEMP_SE "Temp. 2 :%e1/%E1" cDEG "C" +#define UI_TEXT_EXTR2_TEMP_SE "Temp. 3 :%e2/%E2" cDEG "C" +#define UI_TEXT_EXTR0_OFF_SE "Extruder 1 av" +#define UI_TEXT_EXTR1_OFF_SE "Extruder 2 av" +#define UI_TEXT_EXTR2_OFF_SE "Extruder 3 av" +#define UI_TEXT_EXTR0_SELECT_SE "%X0 V" STR_auml "lj Extr. 1" +#define UI_TEXT_EXTR1_SELECT_SE "%X1 V" STR_auml "lj Extr. 2" +#define UI_TEXT_EXTR2_SELECT_SE "%X2 V" STR_auml "lj Extr. 3" +#define UI_TEXT_EXTR_ORIGIN_SE "S" STR_auml "tt origo" +#define UI_TEXT_PRINT_X_SE "Skriv X:%ax" +#define UI_TEXT_PRINT_Y_SE "Skriv Y:%ay" +#define UI_TEXT_PRINT_Z_SE "Skriv Z:%az" +#define UI_TEXT_PRINT_Z_DELTA_SE "Skriv:%az" +#define UI_TEXT_MOVE_X_SE "Transp. X:%aX" +#define UI_TEXT_MOVE_Y_SE "Transp. Y:%aY" +#define UI_TEXT_MOVE_Z_SE "Transp. Z:%aZ" +#define UI_TEXT_MOVE_Z_DELTA_SE "Transp.:%aZ" +#define UI_TEXT_JERK_SE "Ryck: %aj" +#define UI_TEXT_ZJERK_SE "Z-ryck: %aJ" +#define UI_TEXT_ACCELERATION_SE "Acceleration" +#define UI_TEXT_STORE_TO_EEPROM_SE "Spara till EEPROM" +#define UI_TEXT_LOAD_EEPROM_SE "Ladda f. EEPROM" +#define UI_TEXT_DBG_ECHO_SE "Eko: %do" +#define UI_TEXT_DBG_INFO_SE "Info: %di" +#define UI_TEXT_DBG_ERROR_SE "Errors: %de" +#define UI_TEXT_DBG_DRYRUN_SE "Torrk" STR_ouml "r:%dd" +#define UI_TEXT_DBG_ENDSTOP_SE "EndStop:%dp" +#define UI_TEXT_OPS_OFF_SE "%O1 OPS av" +#define UI_TEXT_OPS_CLASSIC_SE "%O2 OPS klassisk" +#define UI_TEXT_OPS_FAST_SE "%O3 OPS snabb" +#define UI_TEXT_OPS_RETRACT_SE "Backa: %Or" +#define UI_TEXT_OPS_BACKSLASH_SE "Backsl. :%Ob" +#define UI_TEXT_OPS_MINDIST_SE "Min.dist: %Od" +#define UI_TEXT_OPS_MOVE_AFTER_SE "Flytta efter:%Oa" +#define UI_TEXT_ANTI_OOZE_SE "Antikladd" +#define UI_TEXT_PRINT_FILE_SE "Skriv ut fil" +#define UI_TEXT_PAUSE_PRINT_SE "Pausa utskrift" +#define UI_TEXT_CONTINUE_PRINT_SE "Forts" STR_auml "tt utskrift" +#define UI_TEXT_UNMOUNT_CARD_SE "Mata ut kort" +#define UI_TEXT_MOUNT_CARD_SE "Anslut kort" +#define UI_TEXT_DELETE_FILE_SE "Radera fil" +#define UI_TEXT_FEEDRATE_SE "Matning" +#define UI_TEXT_FEED_MAX_X_SE "Max X:%fx" +#define UI_TEXT_FEED_MAX_Y_SE "Max Y:%fy" +#define UI_TEXT_FEED_MAX_Z_SE "Max Z:%fz" +#define UI_TEXT_FEED_MAX_Z_DELTA_SE "Max:%fz" +#define UI_TEXT_FEED_HOME_X_SE "Ref X:%fX" +#define UI_TEXT_FEED_HOME_Y_SE "Ref Y:%fY" +#define UI_TEXT_FEED_HOME_Z_SE "Ref Z:%fZ" +#define UI_TEXT_FEED_HOME_Z_DELTA_SE "Ref:%fZ" +#define UI_TEXT_ACTION_XPOSITION4A_SE "X:%x0 mm %dx%dX" +#define UI_TEXT_ACTION_XPOSITION4B_SE "Min " STR_auml "ndl" STR_auml "ge:%sx" +#define UI_TEXT_ACTION_XPOSITION4C_SE "Max " STR_auml "ndl" STR_auml "ge:%sX" +#define UI_TEXT_ACTION_XPOSITION4D_SE "" +#define UI_TEXT_ACTION_YPOSITION4A_SE "Y:%x1 mm %dy%dY" +#define UI_TEXT_ACTION_YPOSITION4B_SE "Min " STR_auml "ndl" STR_auml "ge:%sy" +#define UI_TEXT_ACTION_YPOSITION4C_SE "Max " STR_auml "ndl" STR_auml "ge:%sY" +#define UI_TEXT_ACTION_YPOSITION4D_SE "" +#define UI_TEXT_ACTION_ZPOSITION4A_SE "Z:%x2 mm %dz%dZ" +#define UI_TEXT_ACTION_ZPOSITION4B_SE "Min " STR_auml "ndl" STR_auml "ge:%sz" +#define UI_TEXT_ACTION_ZPOSITION4C_SE "Max " STR_auml "ndl" STR_auml "ge:%sZ" +#define UI_TEXT_ACTION_ZPOSITION4D_SE "" +#define UI_TEXT_ACTION_XPOSITION_FAST4A_SE "X:%x0 mm" +#define UI_TEXT_ACTION_XPOSITION_FAST4B_SE "Min " STR_auml "ndl" STR_auml "ge:%sx" +#define UI_TEXT_ACTION_XPOSITION_FAST4C_SE "Max " STR_auml "ndl" STR_auml "ge:%sX" +#define UI_TEXT_ACTION_XPOSITION_FAST4D_SE "" +#define UI_TEXT_ACTION_YPOSITION_FAST4A_SE "Y:%x1 mm" +#define UI_TEXT_ACTION_YPOSITION_FAST4B_SE "Min " STR_auml "ndl" STR_auml "ge:%sy" +#define UI_TEXT_ACTION_YPOSITION_FAST4C_SE "Max " STR_auml "ndl" STR_auml "ge:%sY" +#define UI_TEXT_ACTION_YPOSITION_FAST4D_SE "" +#define UI_TEXT_ACTION_ZPOSITION_FAST4A_SE "Z:%x2 mm" +#define UI_TEXT_ACTION_ZPOSITION_FAST4B_SE "Min " STR_auml "ndl" STR_auml "ge:%sz" +#define UI_TEXT_ACTION_ZPOSITION_FAST4C_SE "Max " STR_auml "ndl" STR_auml "ge:%sZ" +#define UI_TEXT_ACTION_ZPOSITION_FAST4D_SE "" +#define UI_TEXT_ACTION_EPOSITION_FAST2A_SE "E:%x3 mm" +#define UI_TEXT_ACTION_EPOSITION_FAST2B_SE "1 click = 1 mm" +#define UI_TEXT_ACTION_XPOSITION2A_SE "X:%x0 mm" +#define UI_TEXT_ACTION_XPOSITION2B_SE "Min:%sx Max:%sX" +#define UI_TEXT_ACTION_YPOSITION2A_SE "Y:%x1 mm" +#define UI_TEXT_ACTION_YPOSITION2B_SE "Min:%sy Max:%sY" +#define UI_TEXT_ACTION_ZPOSITION2A_SE "Z:%x2 mm" +#define UI_TEXT_ACTION_ZPOSITION2B_SE "Min:%sz Max:%sZ" +#define UI_TEXT_ACTION_XPOSITION_FAST2A_SE "X:%x0 mm" +#define UI_TEXT_ACTION_XPOSITION_FAST2B_SE "Min:%sx Max:%sX" +#define UI_TEXT_ACTION_YPOSITION_FAST2A_SE "Y:%x1 mm" +#define UI_TEXT_ACTION_YPOSITION_FAST2B_SE "Min:%sy Max:%sY" +#define UI_TEXT_ACTION_ZPOSITION_FAST2A_SE "Z:%x2 mm" +#define UI_TEXT_ACTION_ZPOSITION_FAST2B_SE "Min:%sz Max:%sZ" +#define UI_TEXT_FANSPEED_SE "Fl" STR_auml "kt hast." +#define UI_TEXT_ACTION_FANSPEED_SE "Fl" STR_auml "kt hast.:%Fs%%%" +#define UI_TEXT_FAN_OFF_SE "St" STR_auml "ng av fl" STR_auml "kt" +#define UI_TEXT_FAN_25_SE "Fl" STR_auml "kt 25%%%" +#define UI_TEXT_FAN_50_SE "Fl" STR_auml "kt 50%%%" +#define UI_TEXT_FAN_75_SE "Fl" STR_auml "kt 75%%%" +#define UI_TEXT_FAN_FULL_SE "Full fl" STR_auml "kt" +#define UI_TEXT_STEPPER_INACTIVE_SE "Stegmotorer inakt." +#define UI_TEXT_STEPPER_INACTIVE2A_SE "Inakt. efter: %is" +#define UI_TEXT_STEPPER_INACTIVE2B_SE "[min] 0=Off" +#define UI_TEXT_POWER_INACTIVE_SE "Max. inaktiv" +#define UI_TEXT_POWER_INACTIVE2A_SE "Inakt. efter: %ip" +#define UI_TEXT_POWER_INACTIVE2B_SE "[min] 0=Off" +#define UI_TEXT_GENERAL_SE "Generella" +#define UI_TEXT_BAUDRATE_SE "Baudrate:%oc" +#define UI_TEXT_EXTR_STEPS_SE "Steg/MM:%Se" +#define UI_TEXT_EXTR_START_FEED_SE "Start FR:%Xf" +#define UI_TEXT_EXTR_MAX_FEED_SE "Max FR:%XF" +#define UI_TEXT_EXTR_ACCEL_SE "Accel:%XA" +#define UI_TEXT_EXTR_WATCH_SE "Stab. tid:%Xw" +#define UI_TEXT_EXTR_ADVANCE_L_SE "Advance lin:%Xl" +#define UI_TEXT_EXTR_ADVANCE_K_SE "Advance quad:%Xa" +#define UI_TEXT_EXTR_MANAGER_SE "Control:%Xh" +#define UI_TEXT_EXTR_PGAIN_SE "PID P:%Xp" +#define UI_TEXT_EXTR_DEADTIME_SE "D" STR_ouml "dtid:%Xp" +#define UI_TEXT_EXTR_DMAX_DT_SE "Kontroll PWM:%XM" +#define UI_TEXT_EXTR_IGAIN_SE "PID I:%Xi" +#define UI_TEXT_EXTR_DGAIN_SE "PID D:%Xd" +#define UI_TEXT_EXTR_DMIN_SE "Drive min:%Xm" +#define UI_TEXT_EXTR_DMAX_SE "Drive max:%XM" +#define UI_TEXT_EXTR_PMAX_SE "PID max:%XD" +#define UI_TEXT_EXTR_XOFF_SE "X-offset:%Xx" +#define UI_TEXT_EXTR_YOFF_SE "Y-offset:%Xy" +#define UI_TEXT_STRING_HM_BANGBANG_SE "BangBang" +#define UI_TEXT_STRING_HM_PID_SE "PID" +#define UI_TEXT_STRING_ACTION_SE "Aktion:%la" +#define UI_TEXT_HEATING_EXTRUDER_SE "V" STR_auml "rmer Extruder" +#define UI_TEXT_HEATING_BED_SE "V" STR_auml "rmer B" STR_auml "dd" +#define UI_TEXT_KILLED_SE "D" STR_ouml "dad" +#define UI_TEXT_STEPPER_DISABLED_SE "Stegmotorer av" +#define UI_TEXT_EEPROM_STOREDA_SE "Konfiguration" +#define UI_TEXT_EEPROM_STOREDB_SE "sparad i EEPROM" +#define UI_TEXT_EEPROM_LOADEDA_SE "Konfiguration" +#define UI_TEXT_EEPROM_LOADEDB_SE "laddat fr. EEPROM" +#define UI_TEXT_UPLOADING_SE "Uppladdning..." +#define UI_TEXT_PAGE_BUFFER_SE "Buffer:%oB" +#define UI_TEXT_PAGE_EXTRUDER_SE " E:%ec/%Ec" cDEG "C" cARROW "%oC" +#define UI_TEXT_PAGE_EXTRUDER1_SE "E1:%e0/%E0" cDEG "C" cARROW "%o0" +#define UI_TEXT_PAGE_EXTRUDER2_SE "E2:%e1/%E1" cDEG "C" cARROW "%o1" +#define UI_TEXT_PAGE_EXTRUDER3_SE "E3:%e2/%E2" cDEG "C" cARROW "%o2" +#define UI_TEXT_PAGE_BED_SE " B:%eb/%Eb" cDEG "C" cARROW "%ob" +#define UI_TEXT_SPEED_MULTIPLY_SE "Hast. Mul.:%om%%%" +#define UI_TEXT_FLOW_MULTIPLY_SE "Fl" STR_ouml "de Mul.:%of%%%" +#define UI_TEXT_SHOW_MEASUREMENT_SE "Visa m" STR_auml "tning" +#define UI_TEXT_RESET_MEASUREMENT_SE "Aterst" STR_auml "ll m" STR_auml "tning" +#define UI_TEXT_SET_MEASURED_ORIGIN_SE "St" STR_auml "ll Z=0" +#define UI_TEXT_ZCALIB_SE "Z kalib." +#define UI_TEXT_SET_P1_SE "St" STR_auml "ll P1" +#define UI_TEXT_SET_P2_SE "St" STR_auml "ll P2" +#define UI_TEXT_SET_P3_SE "Set P3" +#define UI_TEXT_CALCULATE_LEVELING_SE "ber" STR_auml "kna nivellering" +#define UI_TEXT_LEVEL_SE "Niva delta" +#define UI_TEXT_EXTR_WAIT_RETRACT_TEMP_SE "Inv" STR_auml "nta temp.%XT" cDEG "C" +#define UI_TEXT_EXTR_WAIT_RETRACT_UNITS_SE "Inv" STR_auml "nta pos:%XUmm" +#define UI_TEXT_SD_REMOVED_SE "SD-kort tas bort" +#define UI_TEXT_SD_INSERTED_SE "SD-kort isatt" +#define UI_TEXT_PRINTER_READY_SE "Utskrift klar." +// Printtime output gets aggregated like UI_TEXT_PRINTTIME_DAYSUI_TEXT_PRINTTIME_HOURSUI_TEXT_PRINTTIME_MINUTES +// ___88 days 12:45 +#define UI_TEXT_PRINTTIME_DAYS_SE " dagar " +#define UI_TEXT_PRINTTIME_HOURS_SE ":" +#define UI_TEXT_PRINTTIME_MINUTES_SE "" +#define UI_TEXT_PRINT_TIME_SE "Tryckningstid" +#define UI_TEXT_PRINT_FILAMENT_SE "Filament tryckt" +#define UI_TEXT_PRINTED_SE "tryckt" +#define UI_TEXT_POWER_SE "ATX str" STR_ouml "m p" STR_uuml "/av" +#define UI_TEXT_STRING_HM_DEADTIME_SE "D" STR_ouml "dtid" +#define UI_TEXT_STRING_HM_SLOWBANG_SE "SlowBang" +#define UI_TEXT_STOP_PRINT_SE "Stopp trycket" +#define UI_TEXT_Z_BABYSTEPPING_SE "Z babystep.:%oYmm" +#define UI_TEXT_CHANGE_FILAMENT_SE "" STR_Auml "ndra filamentet" +#define UI_TEXT_WIZ_CH_FILAMENT1_SE "" STR_Auml "ndra filamentet" +#define UI_TEXT_WIZ_CH_FILAMENT2_SE "Rotera att flytta" +#define UI_TEXT_WIZ_CH_FILAMENT3_SE "filamentet upp/ner" +#define UI_TEXT_CLICK_DONE_SE "Klicka n" STR_auml "r du " STR_auml "r klar" +#define UI_TEXT_AUTOLEVEL_ONOFF_SE "Autolevel: %ll" +#define UI_TEXT_SERVOPOS_SE "Servol" STR_auml "ge: %oS" +#define UI_TEXT_IGNORE_M106_SE "Ignorera M106 %Fi" +#define UI_TEXT_WIZ_REHEAT1_SE "Klicka f" STR_ouml "r att" +#define UI_TEXT_WIZ_REHEAT2_SE "v" STR_auml "rma extrudrar." +#define UI_TEXT_WIZ_WAITTEMP1_SE "V" STR_auml "nta pa" +#define UI_TEXT_WIZ_WAITTEMP2_SE "maltemperaturer ..." +#define UI_TEXT_EXTRUDER_JAM_SE "Extruder tr" STR_auml "ngsel" +#define UI_TEXT_STANDBY_SE "Standby" +#define UI_TEXT_BED_COATING_SE "B" STR_auml "ddbel" STR_auml "ggning" +#define UI_TEXT_BED_COATING_SET1_SE "B" STR_auml "ddbel" STR_auml "ggning:" +#define UI_TEXT_BED_COATING_SET2_SE "" +#define UI_TEXT_NOCOATING_SE "Ingen bel" STR_auml "ggning" +#define UI_TEXT_BUILDTAK_SE "BuildTak" +#define UI_TEXT_KAPTON_SE "Kapton" +#define UI_TEXT_BLUETAPE_SE "Bla maskeringstejp" +#define UI_TEXT_PETTAPE_SE "Gr" STR_ouml "n PET band" +#define UI_TEXT_GLUESTICK_SE "Limstift" +#define UI_TEXT_CUSTOM_SE "Anpassad" +#define UI_TEXT_COATING_CUSTOM_SE "Anpassad:%BCmm" +#define UI_TEXT_LANGUAGE_SE "Sprak" + +#if NUM_EXTRUDER > 2 || MIXING_EXTRUDER != 0 +#define UI_TEXT_MAINPAGE6_1_SE "\xa %ec/%Ec\xb0 X:%x0" +#else +#define UI_TEXT_MAINPAGE6_1_SE "\xa %e0/%E0\xb0 X:%x0" +#endif // NUM_EXTRUDER +#if NUM_EXTRUDER == 2 && MIXING_EXTRUDER == 0 +#define UI_TEXT_MAINPAGE6_2_SE "\xa %e1/%E1\xb0 Y:%x1" +#elif HAVE_HEATED_BED +#define UI_TEXT_MAINPAGE6_2_SE "\xe %eb/%Eb\xb0 Y:%x1" +#else +#define UI_TEXT_MAINPAGE6_2_SE " Y:%x1" +#endif +#if HAVE_HEATED_BED && NUM_EXTRUDER == 2 && MIXING_EXTRUDER == 0 +#define UI_TEXT_MAINPAGE6_3_SE "\xe %eb/%Eb\xb0 Z:%x2" +#elif FEATURE_DITTO_PRINTING +#define UI_TEXT_MAINPAGE6_3_SE "Kopior: %ed Z:%x2" +#else +#define UI_TEXT_MAINPAGE6_3_SE "Fl" STR_ouml "de:\xfd %of%%% Z:%x2" +#endif +#define UI_TEXT_MAINPAGE6_4_SE "Mul: %om%%% \xfd E: %x4m" +#define UI_TEXT_MAINPAGE6_5_SE "Buf: %oB" +#define UI_TEXT_MAINPAGE6_6_SE "%os" +#define UI_TEXT_MAINPAGE_TEMP_BED_SE cTEMP "%ec/%Ec" cDEG "B%eB/%Eb" cDEG +#define UI_TEXT_MAINPAGE_BED_SE "B%eB/%Eb" cDEG +#define UI_TEXT_MAINPAGE_Z_BUF_SE "Z:%x2 Buf : %oB" +#define UI_TEXT_MAINPAGE_MUL_EUSAGE_SE "Mul: %om E:%x4" +#define UI_TEXT_MAINPAGE_XY_SE "X:%x0 Y:%x1" +#define UI_TEXT_PRINT_TIME_VALUE_SE "%Ut" +#define UI_TEXT_PRINT_FILAMENT_VALUE_SE "%Uf m" +#define UI_TEXT_METER_PRINTED_SE "%Uf m " UI_TEXT_PRINTED_SE +#define UI_TEXT_STATUS_SE "%os" +#define UI_TEXT_EMPTY_SE "" +#define UI_TEXT_TEMP_SET_SE cTEMP "%ec/%Ec" cDEG +#define UI_TEXT_CURRENT_TEMP_SE cTEMP "%ec" cDEG +#define UI_TEXT_COATING_THICKNESS_SE " %BCmm" +#define UI_TEXT_EXTR3_TEMP_SE "Temp. 4 :%e3/%E3" cDEG "C" +#define UI_TEXT_EXTR4_TEMP_SE "Temp. 5 :%e4/%E4" cDEG "C" +#define UI_TEXT_EXTR5_TEMP_SE "Temp. 6 :%e5/%E5" cDEG "C" +#define UI_TEXT_EXTR3_OFF_SE "Extruder 4 av" +#define UI_TEXT_EXTR4_OFF_SE "Extruder 5 av" +#define UI_TEXT_EXTR5_OFF_SE "Extruder 6 av" +#define UI_TEXT_EXTR3_SELECT_SE "%X3 V" STR_auml "lj Extr. 4" +#define UI_TEXT_EXTR4_SELECT_SE "%X4 V" STR_auml "lj Extr. 5" +#define UI_TEXT_EXTR5_SELECT_SE "%X5 V" STR_auml "lj Extr. 6" +#define UI_TEXT_DITTO_0_SE "%D0 Inga Kopior" +#define UI_TEXT_DITTO_1_SE "%D1 1 Kopia" +#define UI_TEXT_DITTO_2_SE "%D2 2 Kopior" +#define UI_TEXT_DITTO_3_SE "%D3 3 Kopior" +#define UI_TEXT_ZPROBE_HEIGHT_SE "Z-probh" STR_ouml "jden:%zh" + + + +#define UI_TEXT_OFFSETS_SE "Set print offsets" +#define UI_TEXT_X_OFFSET_SE "Set X offset:%T0mm" +#define UI_TEXT_Y_OFFSET_SE "Set Y offset:%T1mm" +#define UI_TEXT_Z_OFFSET_SE "Set Z offset:%T2mm" + + +// *************** French translation **************** +// *************** By Doudou **************** + +#define UI_TEXT_ON_FR "On" +#define UI_TEXT_OFF_FR "Off" +#define UI_TEXT_NA_FR "N/A" // Output for not available +#define UI_TEXT_YES_FR "Oui" +#define UI_TEXT_NO_FR "Non" +#define UI_TEXT_PRINT_POS_FR "Impression..." +#define UI_TEXT_PRINTING_FR "Impression" +#define UI_TEXT_IDLE_FR "Au Repos" +#define UI_TEXT_NOSDCARD_FR "Pas de Carte SD" +#define UI_TEXT_ERROR_FR "**** ERREUR ****" +#define UI_TEXT_BACK_FR "Retour \001" +#define UI_TEXT_QUICK_SETTINGS_FR "Reglages Rapides" +#define UI_TEXT_ERRORMSG_FR "%oe" +#define UI_TEXT_CONFIGURATION_FR "Configuration" +#define UI_TEXT_POSITION_FR "Position" +#define UI_TEXT_EXTRUDER_FR "Extrudeuse" +#define UI_TEXT_SD_CARD_FR "Carte SD" +#define UI_TEXT_DEBUGGING_FR "Deboguer" +#define UI_TEXT_HOME_DELTA_FR "Accueil Delta" +#define UI_TEXT_HOME_ALL_FR "Accueil XYZ" +#define UI_TEXT_HOME_X_FR "Accueil X" +#define UI_TEXT_HOME_Y_FR "Accueil Y" +#define UI_TEXT_HOME_Z_FR "Accueil Z" +#define UI_TEXT_PREHEAT_PLA_FR "Prechauf. PLA" +#define UI_TEXT_PREHEAT_ABS_FR "Prechauf. ABS" +#define UI_TEXT_LIGHTS_ONOFF_FR "Eclairage :%lo" +#define UI_TEXT_COOLDOWN_FR "Refroidir" +#define UI_TEXT_SET_TO_ORIGIN_FR "Reglez sur Origine" +#define UI_TEXT_DISABLE_STEPPER_FR "Desactiv. Moteurs" +#define UI_TEXT_X_POSITION_FR "Position X" +#define UI_TEXT_X_POS_FAST_FR "Pos. Rapide X" +#define UI_TEXT_Y_POSITION_FR "Position Y" +#define UI_TEXT_Y_POS_FAST_FR "Pos. Rapide Y" +#define UI_TEXT_Z_POSITION_FR "Position Z" +#define UI_TEXT_Z_POS_FAST_FR "Pos. Rapide Z" +#define UI_TEXT_E_POSITION_FR "Position Extr." +#define UI_TEXT_BED_TEMP_FR "Lit Temp:%eb/%Eb\002C" +#define UI_TEXT_EXTR0_TEMP_FR "Temp. 1 :%e0/%E0\002C" +#define UI_TEXT_EXTR1_TEMP_FR "Temp. 2 :%e1/%E1\002C" +#define UI_TEXT_EXTR2_TEMP_FR "Temp. 2 :%e2/%E2\002C" +#define UI_TEXT_EXTR0_OFF_FR "Extrudeuse 1 Off" +#define UI_TEXT_EXTR1_OFF_FR "Extrudeuse 2 Off" +#define UI_TEXT_EXTR2_OFF_FR "Extrudeuse 3 Off" +#define UI_TEXT_EXTR0_SELECT_FR "%X0 Select. Extr. 1" +#define UI_TEXT_EXTR1_SELECT_FR "%X1 Select. Extr. 2" +#define UI_TEXT_EXTR2_SELECT_FR "%X1 Select. Extr. 3" +#define UI_TEXT_EXTR_ORIGIN_FR "Set Origin" +#define UI_TEXT_PRINT_X_FR "Imprim. X:%ax" +#define UI_TEXT_PRINT_Y_FR "Imprim. Y:%ay" +#define UI_TEXT_PRINT_Z_FR "Imprim. Z:%az" +#define UI_TEXT_PRINT_Z_DELTA_FR "Imprim.:%az" +#define UI_TEXT_MOVE_X_FR "Deplac. X:%aX" +#define UI_TEXT_MOVE_Y_FR "Deplac. Y:%aY" +#define UI_TEXT_MOVE_Z_FR "Deplac. Z:%aZ" +#define UI_TEXT_MOVE_Z_DELTA_FR "Deplac.:%aZ" +#define UI_TEXT_JERK_FR "Jerk:%aj" +#define UI_TEXT_ZJERK_FR "Z-Jerk:%aJ" +#define UI_TEXT_ACCELERATION_FR "Acceleration" +#define UI_TEXT_STORE_TO_EEPROM_FR "Stock. Dans EEPROM" +#define UI_TEXT_LOAD_EEPROM_FR "Charg. f. EEPROM" +#define UI_TEXT_DBG_ECHO_FR "Echo :%do" +#define UI_TEXT_DBG_INFO_FR "Info :%di" +#define UI_TEXT_DBG_ERROR_FR "Erreurs :%de" +#define UI_TEXT_DBG_DRYRUN_FR "Fonct. a Vide:%dd" +#define UI_TEXT_DBG_ENDSTOP_FR "Fin de course:%dp" +#define UI_TEXT_OPS_OFF_FR "%O0 OPS Off" +#define UI_TEXT_OPS_CLASSIC_FR "%O1 OPS Classiq." +#define UI_TEXT_OPS_FAST_FR "%O2 OPS Rapide" +#define UI_TEXT_OPS_RETRACT_FR "Retract. :%Or" +#define UI_TEXT_OPS_BACKSLASH_FR "Backsl. :%Ob" +#define UI_TEXT_OPS_MINDIST_FR "Min.dist:%Od" +#define UI_TEXT_OPS_MOVE_AFTER_FR "Déplac. Apres:%Oa" +#define UI_TEXT_ANTI_OOZE_FR "Anti Ooze" +#define UI_TEXT_PRINT_FILE_FR "Imprim. fichier" +#define UI_TEXT_PAUSE_PRINT_FR "Pause Impress." +#define UI_TEXT_CONTINUE_PRINT_FR "Continuer Impress." +#define UI_TEXT_UNMOUNT_CARD_FR "Retirer Carte" +#define UI_TEXT_MOUNT_CARD_FR "Inserer Carte" +#define UI_TEXT_DELETE_FILE_FR "Supp. fichier" +#define UI_TEXT_FEEDRATE_FR "Avance" +#define UI_TEXT_FEED_MAX_X_FR "Max X:%fx" +#define UI_TEXT_FEED_MAX_Y_FR "Max Y:%fy" +#define UI_TEXT_FEED_MAX_Z_FR "Max Z:%fz" +#define UI_TEXT_FEED_MAX_Z_DELTA_FR "Max:%fz" +#define UI_TEXT_FEED_HOME_X_FR "Accueil X:%fX" +#define UI_TEXT_FEED_HOME_Y_FR "Accueil Y:%fY" +#define UI_TEXT_FEED_HOME_Z_FR "Accueil Z:%fZ" +#define UI_TEXT_FEED_HOME_Z_DELTA_FR "Accueil:%fZ" +#define UI_TEXT_ACTION_XPOSITION4A_FR "X:%x0 mm %dx%dX" +#define UI_TEXT_ACTION_XPOSITION4B_FR "Min Butee:%sx" +#define UI_TEXT_ACTION_XPOSITION4C_FR "Max Butee:%sX" +#define UI_TEXT_ACTION_XPOSITION4D_FR "" +#define UI_TEXT_ACTION_YPOSITION4A_FR "Y:%x1 mm %dy%dY" +#define UI_TEXT_ACTION_YPOSITION4B_FR "Min Butee:%sy" +#define UI_TEXT_ACTION_YPOSITION4C_FR "Max Butee:%sY" +#define UI_TEXT_ACTION_YPOSITION4D_FR "" +#define UI_TEXT_ACTION_ZPOSITION4A_FR "Z:%x2 mm %dz%dZ" +#define UI_TEXT_ACTION_ZPOSITION4B_FR "Min Butee:%sz" +#define UI_TEXT_ACTION_ZPOSITION4C_FR "Max Butee:%sZ" +#define UI_TEXT_ACTION_ZPOSITION4D_FR "" +#define UI_TEXT_ACTION_XPOSITION_FAST4A_FR "X:%x0 mm" +#define UI_TEXT_ACTION_XPOSITION_FAST4B_FR "Min Butee:%sx" +#define UI_TEXT_ACTION_XPOSITION_FAST4C_FR "Max Butee:%sX" +#define UI_TEXT_ACTION_XPOSITION_FAST4D_FR "" +#define UI_TEXT_ACTION_YPOSITION_FAST4A_FR "Y:%x1 mm" +#define UI_TEXT_ACTION_YPOSITION_FAST4B_FR "Min Butee:%sy" +#define UI_TEXT_ACTION_YPOSITION_FAST4C_FR "Max Butee:%sY" +#define UI_TEXT_ACTION_YPOSITION_FAST4D_FR "" +#define UI_TEXT_ACTION_ZPOSITION_FAST4A_FR "Z:%x2 mm" +#define UI_TEXT_ACTION_ZPOSITION_FAST4B_FR "Min Butee:%sz" +#define UI_TEXT_ACTION_ZPOSITION_FAST4C_FR "Max Butee:%sZ" +#define UI_TEXT_ACTION_ZPOSITION_FAST4D_FR "" +#define UI_TEXT_ACTION_EPOSITION_FAST2A_FR "E:%x3 mm" +#define UI_TEXT_ACTION_EPOSITION_FAST2B_FR "1 clic = 1 mm" +#define UI_TEXT_ACTION_XPOSITION2A_FR "X:%x0 mm" +#define UI_TEXT_ACTION_XPOSITION2B_FR "Min:%sx Max:%sX" +#define UI_TEXT_ACTION_YPOSITION2A_FR "Y:%x1 mm" +#define UI_TEXT_ACTION_YPOSITION2B_FR "Min:%sy Max:%sY" +#define UI_TEXT_ACTION_ZPOSITION2A_FR "Z:%x2 mm" +#define UI_TEXT_ACTION_ZPOSITION2B_FR "Min:%sz Max:%sZ" +#define UI_TEXT_ACTION_XPOSITION_FAST2A_FR "X:%x0 mm" +#define UI_TEXT_ACTION_XPOSITION_FAST2B_FR "Min:%sx Max:%sX" +#define UI_TEXT_ACTION_YPOSITION_FAST2A_FR "Y:%x1 mm" +#define UI_TEXT_ACTION_YPOSITION_FAST2B_FR "Min:%sy Max:%sY" +#define UI_TEXT_ACTION_ZPOSITION_FAST2A_FR "Z:%x2 mm" +#define UI_TEXT_ACTION_ZPOSITION_FAST2B_FR "Min:%sz Max:%sZ" +#define UI_TEXT_FANSPEED_FR "Vit. Ventil." +#define UI_TEXT_ACTION_FANSPEED_FR "Vit. Ventil.:%Fs%%%" +#define UI_TEXT_FAN_OFF_FR "Arret Ventil." +#define UI_TEXT_FAN_25_FR "Ventil. 25%%%" +#define UI_TEXT_FAN_50_FR "Ventil. 50%%%" +#define UI_TEXT_FAN_75_FR "Ventil. 75%%%" +#define UI_TEXT_FAN_FULL_FR "Ventil. Max" +#define UI_TEXT_STEPPER_INACTIVE_FR "Arret Moteurs" +#define UI_TEXT_STEPPER_INACTIVE2A_FR "Dis. Apres: %is" +#define UI_TEXT_STEPPER_INACTIVE2B_FR "[min] 0=Off" +#define UI_TEXT_POWER_INACTIVE_FR "Arret Alim." +#define UI_TEXT_POWER_INACTIVE2A_FR "Dis. Apres: %ip" +#define UI_TEXT_POWER_INACTIVE2B_FR "[min] 0=Off" +#define UI_TEXT_GENERAL_FR "General" +#define UI_TEXT_BAUDRATE_FR "Baudrate:%oc" +#define UI_TEXT_EXTR_STEPS_FR "Pas/MM:%Se" +#define UI_TEXT_EXTR_START_FEED_FR "Start FR:%Xf" +#define UI_TEXT_EXTR_MAX_FEED_FR "Max FR:%XF" +#define UI_TEXT_EXTR_ACCEL_FR "Accel:%XA" +#define UI_TEXT_EXTR_WATCH_FR "Stab.Temps:%Xw" +#define UI_TEXT_EXTR_ADVANCE_L_FR "Avance lin:%Xl" +#define UI_TEXT_EXTR_ADVANCE_K_FR "Avance quad:%Xa" +#define UI_TEXT_EXTR_MANAGER_FR "Controle:%Xh" +#define UI_TEXT_EXTR_PGAIN_FR "PID P:%Xp" +#define UI_TEXT_EXTR_DEADTIME_FR "Temps Mort:%Xp" +#define UI_TEXT_EXTR_DMAX_DT_FR "PWM Control:%XM" +#define UI_TEXT_EXTR_IGAIN_FR "PID I:%Xi" +#define UI_TEXT_EXTR_DGAIN_FR "PID D:%Xd" +#define UI_TEXT_EXTR_DMIN_FR "Drive Min:%Xm" +#define UI_TEXT_EXTR_DMAX_FR "Drive Max:%XM" +#define UI_TEXT_EXTR_PMAX_FR "PID Max:%XD" +#define UI_TEXT_EXTR_XOFF_FR "X-Offset:%Xx" +#define UI_TEXT_EXTR_YOFF_FR "Y-Offset:%Xy" +#define UI_TEXT_STRING_HM_BANGBANG_FR "BangBang" +#define UI_TEXT_STRING_HM_PID_FR "PID" +#define UI_TEXT_STRING_ACTION_FR "Action:%la" +#define UI_TEXT_HEATING_EXTRUDER_FR "Chauff. Extrud." +#define UI_TEXT_HEATING_BED_FR "Chauff. Lit" +#define UI_TEXT_KILLED_FR "Stoppe" +#define UI_TEXT_STEPPER_DISABLED_FR "Moteurs Arretes" +#define UI_TEXT_EEPROM_STOREDA_FR "Configuration" +#define UI_TEXT_EEPROM_STOREDB_FR "Stock. Dans EEPROM" +#define UI_TEXT_EEPROM_LOADEDA_FR "Configuration" +#define UI_TEXT_EEPROM_LOADEDB_FR "Charg. f. EEPROM" +#define UI_TEXT_UPLOADING_FR "Telechargement.." +#define UI_TEXT_PAGE_BUFFER_FR "Tampon:%oB" +#define UI_TEXT_PAGE_EXTRUDER_FR " E:%ec/%Ec\002C\176%oC" +#define UI_TEXT_PAGE_EXTRUDER1_FR "E1:%e0/%E0\002C\176%o0" +#define UI_TEXT_PAGE_EXTRUDER2_FR "E2:%e1/%E1\002C\176%o1" +#define UI_TEXT_PAGE_EXTRUDER3_FR "E3:%e2/%E2\002C\176%o2" +#define UI_TEXT_PAGE_BED_FR " B:%eb/%Eb\002C\176%ob" +#define UI_TEXT_SPEED_MULTIPLY_FR "Vit. Mul.:%om%%%" +#define UI_TEXT_FLOW_MULTIPLY_FR "Flow Mul.:%of%%%" +#define UI_TEXT_SHOW_MEASUREMENT_FR "Montrer Mesure" +#define UI_TEXT_RESET_MEASUREMENT_FR "Reset Mesure" +#define UI_TEXT_SET_MEASURED_ORIGIN_FR "Regler Z=0" +#define UI_TEXT_ZCALIB_FR "Z Calib." +#define UI_TEXT_SET_P1_FR "Regler P1" +#define UI_TEXT_SET_P2_FR "Regler P2" +#define UI_TEXT_SET_P3_FR "Regler P3" +#define UI_TEXT_CALCULATE_LEVELING_FR "Calculer Nivellement" +#define UI_TEXT_LEVEL_FR "Niveau delta" +#define UI_TEXT_EXTR_WAIT_RETRACT_TEMP_FR "Att. Temp.%XT\002C" +#define UI_TEXT_EXTR_WAIT_RETRACT_UNITS_FR "Att. Units:%XUmm" +#define UI_TEXT_SD_REMOVED_FR "Carte SD retiree" +#define UI_TEXT_SD_INSERTED_FR "Carte SD inseree" +#define UI_TEXT_PRINTER_READY_FR "imprimante prete" +// Printtime output gets aggregated like UI_TEXT_PRINTTIME_DAYSUI_TEXT_PRINTTIME_HOURSUI_TEXT_PRINTTIME_MINUTES +// ___88 days 12:45 +#define UI_TEXT_PRINTTIME_DAYS_FR " jours " +#define UI_TEXT_PRINTTIME_HOURS_FR ":" +#define UI_TEXT_PRINTTIME_MINUTES_FR "" +#define UI_TEXT_PRINT_TIME_FR "Temps Impression" +#define UI_TEXT_PRINT_FILAMENT_FR "Filament Imprime" +#define UI_TEXT_PRINTED_FR "Imprime" +#define UI_TEXT_POWER_FR "ATX power on/off" +#define UI_TEXT_STRING_HM_DEADTIME_FR "Temps Mort" +#define UI_TEXT_STRING_HM_SLOWBANG_FR "Tout ou Rien" +#define UI_TEXT_STOP_PRINT_FR "Arret Impress." +#define UI_TEXT_Z_BABYSTEPPING_FR "Z Babystep.:%oYmm" +#define UI_TEXT_CHANGE_FILAMENT_FR "Changement Filament" +#define UI_TEXT_WIZ_CH_FILAMENT1_FR "Changement Filament" +#define UI_TEXT_WIZ_CH_FILAMENT2_FR "Tournez Deplacer" +#define UI_TEXT_WIZ_CH_FILAMENT3_FR "Filament haut/bas" +#define UI_TEXT_CLICK_DONE_FR "Continuer avec Clic" +#define UI_TEXT_AUTOLEVEL_ONOFF_FR "Autolevel: %ll" +#define UI_TEXT_SERVOPOS_FR "Pos. Servo: %oS" +#define UI_TEXT_IGNORE_M106_FR "Ignorer M106 %Fi" +#define UI_TEXT_WIZ_REHEAT1_FR "Cliquez pour" +#define UI_TEXT_WIZ_REHEAT2_FR "Rechauffer Extrud." +#define UI_TEXT_WIZ_WAITTEMP1_FR "Attendez Temp." +#define UI_TEXT_WIZ_WAITTEMP2_FR "cibles ..." +#define UI_TEXT_EXTRUDER_JAM_FR "Stockage d'Extrusion" +#define UI_TEXT_STANDBY_FR "Standby" +#define UI_TEXT_BED_COATING_FR "Revetement de Lit" +#define UI_TEXT_BED_COATING_SET1_FR "Revetement de Lit:" +#define UI_TEXT_BED_COATING_SET2_FR "" +#define UI_TEXT_NOCOATING_FR "Aucun Revetement" +#define UI_TEXT_BUILDTAK_FR "BuildTak" +#define UI_TEXT_KAPTON_FR "Kapton" +#define UI_TEXT_BLUETAPE_FR "Blue Tape" +#define UI_TEXT_PETTAPE_FR "Ruban vert PET" +#define UI_TEXT_GLUESTICK_FR "Baton de Colle" +#define UI_TEXT_CUSTOM_FR "Coutume" +#define UI_TEXT_COATING_CUSTOM_FR "Coutume:%BCmm" +#define UI_TEXT_LANGUAGE_FR "Langue" + +#if NUM_EXTRUDER > 2 || MIXING_EXTRUDER != 0 +#define UI_TEXT_MAINPAGE6_1_FR "\xa %ec/%Ec\xb0 X:%x0" +#else +#define UI_TEXT_MAINPAGE6_1_FR "\xa %e0/%E0\xb0 X:%x0" +#endif // NUM_EXTRUDER +#if NUM_EXTRUDER == 2 && MIXING_EXTRUDER == 0 +#define UI_TEXT_MAINPAGE6_2_FR "\xa %e1/%E1\xb0 Y:%x1" +#elif HAVE_HEATED_BED +#define UI_TEXT_MAINPAGE6_2_FR "\xe %eb/%Eb\xb0 Y:%x1" +#else +#define UI_TEXT_MAINPAGE6_2_FR " Y:%x1" +#endif +#if HAVE_HEATED_BED && NUM_EXTRUDER == 2 && MIXING_EXTRUDER == 0 +#define UI_TEXT_MAINPAGE6_3_FR "\xe %eb/%Eb\xb0 Z:%x2" +#elif FEATURE_DITTO_PRINTING +#define UI_TEXT_MAINPAGE6_3_FR "Copies: %ed Z:%x2" +#else +#define UI_TEXT_MAINPAGE6_3_FR "Flow:\xfd %of%%% Z:%x2" +#endif +#define UI_TEXT_MAINPAGE6_4_FR "Mul: %om%%% \xfd E: %x4m" +#define UI_TEXT_MAINPAGE6_5_FR "Buf: %oB" +#define UI_TEXT_MAINPAGE6_6_FR "%os" +#define UI_TEXT_MAINPAGE_TEMP_BED_FR cTEMP "%ec/%Ec" cDEG "B%eB/%Eb" cDEG +#define UI_TEXT_MAINPAGE_BED_FR "B%eB/%Eb" cDEG +#define UI_TEXT_MAINPAGE_Z_BUF_FR "Z:%x2 Buf : %oB" +#define UI_TEXT_MAINPAGE_MUL_EUSAGE_FR "Mul: %om E:%x4" +#define UI_TEXT_MAINPAGE_XY_FR "X:%x0 Y:%x1" +#define UI_TEXT_PRINT_TIME_VALUE_FR "%Ut" +#define UI_TEXT_PRINT_FILAMENT_VALUE_FR "%Uf m" +#define UI_TEXT_METER_PRINTED_FR "%Uf m " UI_TEXT_PRINTED_FR +#define UI_TEXT_STATUS_FR "%os" +#define UI_TEXT_EMPTY_FR "" +#define UI_TEXT_TEMP_SET_FR cTEMP "%ec/%Ec" cDEG +#define UI_TEXT_CURRENT_TEMP_FR cTEMP "%ec" cDEG +#define UI_TEXT_COATING_THICKNESS_FR " %BCmm" +#define UI_TEXT_EXTR3_TEMP_FR "Temp. 4 :%e3/%E3" cDEG "C" +#define UI_TEXT_EXTR4_TEMP_FR "Temp. 5 :%e4/%E4" cDEG "C" +#define UI_TEXT_EXTR5_TEMP_FR "Temp. 6 :%e5/%E5" cDEG "C" +#define UI_TEXT_EXTR3_OFF_FR "Extrudeuse 4 Off" +#define UI_TEXT_EXTR4_OFF_FR "Extrudeuse 5 Off" +#define UI_TEXT_EXTR5_OFF_FR "Extrudeuse 6 Off" +#define UI_TEXT_EXTR3_SELECT_FR "%X3 Select. Extr. 4" +#define UI_TEXT_EXTR4_SELECT_FR "%X4 Select. Extr. 5" +#define UI_TEXT_EXTR5_SELECT_FR "%X5 Select. Extr. 6" +#define UI_TEXT_DITTO_0_FR "%D0 Aucune Copie" +#define UI_TEXT_DITTO_1_FR "%D1 1 Copie" +#define UI_TEXT_DITTO_2_FR "%D2 2 Copies" +#define UI_TEXT_DITTO_3_FR "%D3 3 Copies" +#define UI_TEXT_ZPROBE_HEIGHT_FR "Hauteur Z-Sonde:%zh" + + + +#define UI_TEXT_OFFSETS_FR "Set print offsets" +#define UI_TEXT_X_OFFSET_FR "Set X offset:%T0mm" +#define UI_TEXT_Y_OFFSET_FR "Set Y offset:%T1mm" +#define UI_TEXT_Z_OFFSET_FR "Set Z offset:%T2mm" + + +// *************** Czech translation **************** +// *************** By Majkl **************** +// version: 2014/08/27 + + +#define UI_TEXT_ON_CZ "Zap" +#define UI_TEXT_OFF_CZ "Vyp" +#define UI_TEXT_NA_CZ "neni" // Output for not available +#define UI_TEXT_YES_CZ "Ano" +#define UI_TEXT_NO_CZ "Ne" +#define UI_TEXT_PRINT_POS_CZ "Tisknu..." +#define UI_TEXT_PRINTING_CZ "Tisknu" +#define UI_TEXT_IDLE_CZ "V klidu" +#define UI_TEXT_NOSDCARD_CZ "Neni SD karta" +#define UI_TEXT_ERROR_CZ "**** CHYBA ****" +#define UI_TEXT_BACK_CZ "Zpet \001" +#define UI_TEXT_QUICK_SETTINGS_CZ "Zakladni nastaveni" +#define UI_TEXT_ERRORMSG_CZ "%oe" +#define UI_TEXT_CONFIGURATION_CZ "Nastaveni" +#define UI_TEXT_POSITION_CZ "Pozice" +#define UI_TEXT_EXTRUDER_CZ "Extruder" +#define UI_TEXT_SD_CARD_CZ "SD karta" +#define UI_TEXT_DEBUGGING_CZ "Debug" +#define UI_TEXT_HOME_DELTA_CZ "Home delta" +#define UI_TEXT_HOME_ALL_CZ "Home vsech" +#define UI_TEXT_HOME_X_CZ "Home X" +#define UI_TEXT_HOME_Y_CZ "Home Y" +#define UI_TEXT_HOME_Z_CZ "Home Z" +#define UI_TEXT_PREHEAT_PLA_CZ "Ohrat pro PLA" +#define UI_TEXT_PREHEAT_ABS_CZ "Ohrat pro ABS" +#define UI_TEXT_LIGHTS_ONOFF_CZ "Svetla:%lo" +#define UI_TEXT_COOLDOWN_CZ "Zchladit" +#define UI_TEXT_SET_TO_ORIGIN_CZ "Nastavit pocatek" +#define UI_TEXT_DISABLE_STEPPER_CZ "Vypnout motory" +#define UI_TEXT_X_POSITION_CZ "X pozice" +#define UI_TEXT_X_POS_FAST_CZ "X rychle" +#define UI_TEXT_Y_POSITION_CZ "Y pozice" +#define UI_TEXT_Y_POS_FAST_CZ "Y rychle" +#define UI_TEXT_Z_POSITION_CZ "Z pozice" +#define UI_TEXT_Z_POS_FAST_CZ "Z rychle" +#define UI_TEXT_E_POSITION_CZ "Pozice extruderu" +#define UI_TEXT_BED_TEMP_CZ "Teplota desky: %Eb\002C" +#define UI_TEXT_EXTR0_TEMP_CZ "Teplota 1:%e0/%E0\002C" +#define UI_TEXT_EXTR1_TEMP_CZ "Teplota 2:%e1/%E1\002C" +#define UI_TEXT_EXTR2_TEMP_CZ "Teplota 3:%e2/%E2\002C" +#define UI_TEXT_EXTR0_OFF_CZ "Extruder 1 vyp." +#define UI_TEXT_EXTR1_OFF_CZ "Extruder 2 vyp." +#define UI_TEXT_EXTR2_OFF_CZ "Extruder 3 vyp." +#define UI_TEXT_EXTR0_SELECT_CZ "%X0 Zvolit Extr. 1" +#define UI_TEXT_EXTR1_SELECT_CZ "%X1 Zvolit Extr. 2" +#define UI_TEXT_EXTR2_SELECT_CZ "%X1 Zvolit Extr. 3" +#define UI_TEXT_EXTR_ORIGIN_CZ "Nastavit pocatek" +#define UI_TEXT_PRINT_X_CZ "Tisk X:%ax" +#define UI_TEXT_PRINT_Y_CZ "Tisk Y:%ay" +#define UI_TEXT_PRINT_Z_CZ "Tisk Z:%az" +#define UI_TEXT_PRINT_Z_DELTA_CZ "Tisk:%az" +#define UI_TEXT_MOVE_X_CZ "Posun X:%aX" +#define UI_TEXT_MOVE_Y_CZ "Posun Y:%aY" +#define UI_TEXT_MOVE_Z_CZ "Posun Z:%aZ" +#define UI_TEXT_MOVE_Z_DELTA_CZ "Posun:%aZ" +#define UI_TEXT_JERK_CZ "Jerk:%aj" +#define UI_TEXT_ZJERK_CZ "Z-Jerk:%aJ" +#define UI_TEXT_ACCELERATION_CZ "Akcelerace" +#define UI_TEXT_STORE_TO_EEPROM_CZ "Ulozit do EEPROM" +#define UI_TEXT_LOAD_EEPROM_CZ "Nahrat z EEPROM" +#define UI_TEXT_DBG_ECHO_CZ "Echo :%do" +#define UI_TEXT_DBG_INFO_CZ "Info :%di" +#define UI_TEXT_DBG_ERROR_CZ "Chyby :%de" +#define UI_TEXT_DBG_DRYRUN_CZ "Beh nanecisto:%dd" +#define UI_TEXT_DBG_ENDSTOP_CZ "EndStop:%dp" +#define UI_TEXT_OPS_OFF_CZ "%O0 OPS Vypnuto" +#define UI_TEXT_OPS_CLASSIC_CZ "%O1 OPS Klasicke" +#define UI_TEXT_OPS_FAST_CZ "%O2 OPS Rychle" +#define UI_TEXT_OPS_RETRACT_CZ "Retrakce :%Or" +#define UI_TEXT_OPS_BACKSLASH_CZ "Vule. :%Ob" +#define UI_TEXT_OPS_MINDIST_CZ "Min.vzd,:%Od" +#define UI_TEXT_OPS_MOVE_AFTER_CZ "Posunuti po:%Oa" +#define UI_TEXT_ANTI_OOZE_CZ "Proti kapani" +#define UI_TEXT_PRINT_FILE_CZ "Tisknout soubor" +#define UI_TEXT_PAUSE_PRINT_CZ "Pozastavit tisk" +#define UI_TEXT_CONTINUE_PRINT_CZ "Pokracovani tisku" +#define UI_TEXT_UNMOUNT_CARD_CZ "Odpojit kartu" +#define UI_TEXT_MOUNT_CARD_CZ "Pripojit kartu" +#define UI_TEXT_DELETE_FILE_CZ "Smazat soubor" +#define UI_TEXT_FEEDRATE_CZ "Rychlost" +#define UI_TEXT_FEED_MAX_X_CZ "Max X:%fx" +#define UI_TEXT_FEED_MAX_Y_CZ "Max Y:%fy" +#define UI_TEXT_FEED_MAX_Z_CZ "Max Z:%fz" +#define UI_TEXT_FEED_MAX_Z_DELTA_CZ "Max:%fz" +#define UI_TEXT_FEED_HOME_X_CZ "Home X:%fX" +#define UI_TEXT_FEED_HOME_Y_CZ "Home Y:%fY" +#define UI_TEXT_FEED_HOME_Z_CZ "Home Z:%fZ" +#define UI_TEXT_FEED_HOME_Z_DELTA_CZ "Home:%fZ" +#define UI_TEXT_ACTION_XPOSITION4A_CZ "X:%x0 mm %dx%dX" +#define UI_TEXT_ACTION_XPOSITION4B_CZ "Min koncak:%sx" +#define UI_TEXT_ACTION_XPOSITION4C_CZ "Max koncak:%sX" +#define UI_TEXT_ACTION_XPOSITION4D_CZ "" +#define UI_TEXT_ACTION_YPOSITION4A_CZ "Y:%x1 mm %dy%dY" +#define UI_TEXT_ACTION_YPOSITION4B_CZ "Min koncak:%sy" +#define UI_TEXT_ACTION_YPOSITION4C_CZ "Max koncak:%sY" +#define UI_TEXT_ACTION_YPOSITION4D_CZ "" +#define UI_TEXT_ACTION_ZPOSITION4A_CZ "Z:%x2 mm %dz%dZ" +#define UI_TEXT_ACTION_ZPOSITION4B_CZ "Min koncak:%sz" +#define UI_TEXT_ACTION_ZPOSITION4C_CZ "Max koncak:%sZ" +#define UI_TEXT_ACTION_ZPOSITION4D_CZ "" +#define UI_TEXT_ACTION_XPOSITION_FAST4A_CZ "X:%x0 mm" +#define UI_TEXT_ACTION_XPOSITION_FAST4B_CZ "Min koncak:%sx" +#define UI_TEXT_ACTION_XPOSITION_FAST4C_CZ "Max koncak:%sX" +#define UI_TEXT_ACTION_XPOSITION_FAST4D_CZ "" +#define UI_TEXT_ACTION_YPOSITION_FAST4A_CZ "Y:%x1 mm" +#define UI_TEXT_ACTION_YPOSITION_FAST4B_CZ "Min koncak:%sy" +#define UI_TEXT_ACTION_YPOSITION_FAST4C_CZ "Max koncak:%sY" +#define UI_TEXT_ACTION_YPOSITION_FAST4D_CZ "" +#define UI_TEXT_ACTION_ZPOSITION_FAST4A_CZ "Z:%x2 mm" +#define UI_TEXT_ACTION_ZPOSITION_FAST4B_CZ "Min koncak:%sz" +#define UI_TEXT_ACTION_ZPOSITION_FAST4C_CZ "Max koncak:%sZ" +#define UI_TEXT_ACTION_ZPOSITION_FAST4D_CZ "" +#define UI_TEXT_ACTION_EPOSITION_FAST2A_CZ "E:%x3 mm" +#define UI_TEXT_ACTION_EPOSITION_FAST2B_CZ "1 kliknuti = 1 mm" +#define UI_TEXT_ACTION_XPOSITION2A_CZ "X:%x0 mm" +#define UI_TEXT_ACTION_XPOSITION2B_CZ "Min:%sx Max:%sX" +#define UI_TEXT_ACTION_YPOSITION2A_CZ "Y:%x1 mm" +#define UI_TEXT_ACTION_YPOSITION2B_CZ "Min:%sy Max:%sY" +#define UI_TEXT_ACTION_ZPOSITION2A_CZ "Z:%x2 mm" +#define UI_TEXT_ACTION_ZPOSITION2B_CZ "Min:%sz Max:%sZ" +#define UI_TEXT_ACTION_XPOSITION_FAST2A_CZ "X:%x0 mm" +#define UI_TEXT_ACTION_XPOSITION_FAST2B_CZ "Min:%sx Max:%sX" +#define UI_TEXT_ACTION_YPOSITION_FAST2A_CZ "Y:%x1 mm" +#define UI_TEXT_ACTION_YPOSITION_FAST2B_CZ "Min:%sy Max:%sY" +#define UI_TEXT_ACTION_ZPOSITION_FAST2A_CZ "Z:%x2 mm" +#define UI_TEXT_ACTION_ZPOSITION_FAST2B_CZ "Min:%sz Max:%sZ" +#define UI_TEXT_FANSPEED_CZ "Rychlost vetraku" +#define UI_TEXT_ACTION_FANSPEED_CZ "Aktualni rychlost:%Fs%%%" +#define UI_TEXT_FAN_OFF_CZ "Vypnout" +#define UI_TEXT_FAN_25_CZ "Vetrak na 25%%%" +#define UI_TEXT_FAN_50_CZ "Vetrak na 50%%%" +#define UI_TEXT_FAN_75_CZ "Vetrak na 75%%%" +#define UI_TEXT_FAN_FULL_CZ "Vetrak na plno" +#define UI_TEXT_STEPPER_INACTIVE_CZ "Neaktivni motory" +#define UI_TEXT_STEPPER_INACTIVE2A_CZ "Vypnout po :%i m" +#define UI_TEXT_STEPPER_INACTIVE2B_CZ "[min] 0=Off" +#define UI_TEXT_POWER_INACTIVE_CZ "Max. neaktivni" +#define UI_TEXT_POWER_INACTIVE2A_CZ "Vypnout po: %i m" +#define UI_TEXT_POWER_INACTIVE2B_CZ "[min] 0=Off" +#define UI_TEXT_GENERAL_CZ "Zakladni" +#define UI_TEXT_BAUDRATE_CZ "Rychlost:%oc" +#define UI_TEXT_EXTR_STEPS_CZ "kroku/MM:%Se" +#define UI_TEXT_EXTR_START_FEED_CZ "Start FR:%Xf" +#define UI_TEXT_EXTR_MAX_FEED_CZ "Max FR:%XF" +#define UI_TEXT_EXTR_ACCEL_CZ "Zrychl.:%XA" +#define UI_TEXT_EXTR_WATCH_CZ "Stab.cas:%Xw" +#define UI_TEXT_EXTR_ADVANCE_L_CZ "Rozsir. lin:%Xl" +#define UI_TEXT_EXTR_ADVANCE_K_CZ "Rozsir. quad:%Xa" +#define UI_TEXT_EXTR_MANAGER_CZ "Control:%Xh" +#define UI_TEXT_EXTR_PGAIN_CZ "PID P:%Xp" +#define UI_TEXT_EXTR_DEADTIME_CZ "Mrtva doba:%Xp" +#define UI_TEXT_EXTR_DMAX_DT_CZ "Ovladani PWM:%XM" +#define UI_TEXT_EXTR_IGAIN_CZ "PID I:%Xi" +#define UI_TEXT_EXTR_DGAIN_CZ "PID D:%Xd" +#define UI_TEXT_EXTR_DMIN_CZ "Drive Min:%Xm" +#define UI_TEXT_EXTR_DMAX_CZ "Drive Max:%XM" +#define UI_TEXT_EXTR_PMAX_CZ "PID Max:%XD" +#define UI_TEXT_EXTR_XOFF_CZ "X-Offset:%Xx" +#define UI_TEXT_EXTR_YOFF_CZ "Y-Offset:%Xy" +#define UI_TEXT_STRING_HM_BANGBANG_CZ "BangBang" +#define UI_TEXT_STRING_HM_PID_CZ "PID" +#define UI_TEXT_STRING_ACTION_CZ "Akce:%la" +#define UI_TEXT_HEATING_EXTRUDER_CZ "Ohrivani extruderu" +#define UI_TEXT_HEATING_BED_CZ "Ohrivani desky" +#define UI_TEXT_KILLED_CZ "Zastaveno" +#define UI_TEXT_STEPPER_DISABLED_CZ "Motor vypnut" +#define UI_TEXT_EEPROM_STOREDA_CZ "Konfigurace" +#define UI_TEXT_EEPROM_STOREDB_CZ "Ulozena v EEPROM" +#define UI_TEXT_EEPROM_LOADEDA_CZ "Konfigurace" +#define UI_TEXT_EEPROM_LOADEDB_CZ "Nactena z EEPROM" +#define UI_TEXT_UPLOADING_CZ "Nahravam..." +#define UI_TEXT_PAGE_BUFFER_CZ "Buffer:%oB" +#define UI_TEXT_PAGE_EXTRUDER_CZ " E:%ec/%Ec\002C\176%oC" +#define UI_TEXT_PAGE_EXTRUDER1_CZ "E1:%e0/%E0\002C\176%o0" +#define UI_TEXT_PAGE_EXTRUDER2_CZ "E2:%e1/%E1\002C\176%o1" +#define UI_TEXT_PAGE_EXTRUDER3_CZ "E3:%e2/%E2\002C\176%o2" +#define UI_TEXT_PAGE_BED_CZ " B:%eb/%Eb\002C\176%ob" +#define UI_TEXT_SPEED_MULTIPLY_CZ "Rychlost:%om%%%" +#define UI_TEXT_FLOW_MULTIPLY_CZ "Flow nasobit:%of%%%" +#define UI_TEXT_SHOW_MEASUREMENT_CZ "Ukazat merení" +#define UI_TEXT_RESET_MEASUREMENT_CZ "Obnovit mereni" +#define UI_TEXT_SET_MEASURED_ORIGIN_CZ "Set Z=0" +#define UI_TEXT_ZCALIB_CZ "Z kalib." +#define UI_TEXT_SET_P1_CZ "Set P1" +#define UI_TEXT_SET_P2_CZ "Set P2" +#define UI_TEXT_SET_P3_CZ "Set P3" +#define UI_TEXT_CALCULATE_LEVELING_CZ "Vypocitat leveling" +#define UI_TEXT_LEVEL_CZ "Level delta" +#define UI_TEXT_EXTR_WAIT_RETRACT_TEMP_CZ "Tepl. cekani%XT\002C" +#define UI_TEXT_EXTR_WAIT_RETRACT_UNITS_CZ "Jedn. cekani:%XUmm" +#define UI_TEXT_SD_REMOVED_CZ "SD karta vyjmuta." +#define UI_TEXT_SD_INSERTED_CZ "Vlozena SD karta" +#define UI_TEXT_PRINTER_READY_CZ "Tiskarna OK" +// Printtime output gets aggregated like UI_TEXT_PRINTTIME_DAYSUI_TEXT_PRINTTIME_HOURSUI_TEXT_PRINTTIME_MINUTES +// ___88 days 12:45 +#define UI_TEXT_PRINTTIME_DAYS_CZ " dnu " +#define UI_TEXT_PRINTTIME_HOURS_CZ ":" +#define UI_TEXT_PRINTTIME_MINUTES_CZ "" +#define UI_TEXT_PRINT_TIME_CZ "Cas tisku" +#define UI_TEXT_PRINT_FILAMENT_CZ "Filament tisteny" +#define UI_TEXT_PRINTED_CZ "Protisknuto" +#define UI_TEXT_POWER_CZ "Zapnout ATX zdroj" +#define UI_TEXT_STRING_HM_DEADTIME_CZ "Dead Time" +#define UI_TEXT_STRING_HM_SLOWBANG_CZ "SlowBang" +#define UI_TEXT_STOP_PRINT_CZ "Zastavit tisk" +#define UI_TEXT_Z_BABYSTEPPING_CZ "Z babystep.:%oYmm" +#define UI_TEXT_CHANGE_FILAMENT_CZ "Zmena filament" +#define UI_TEXT_WIZ_CH_FILAMENT1_CZ "Zmena filament" +#define UI_TEXT_WIZ_CH_FILAMENT2_CZ "Otocit se pohybovat" +#define UI_TEXT_WIZ_CH_FILAMENT3_CZ "vlaken nahoru/dolu" +#define UI_TEXT_CLICK_DONE_CZ "Pokr. s cvaknutim" +#define UI_TEXT_AUTOLEVEL_ONOFF_CZ "Autolevel: %ll" +#define UI_TEXT_SERVOPOS_CZ "Servo pozice: %oS" +#define UI_TEXT_IGNORE_M106_CZ "Ignorovat M106 %Fi" +#define UI_TEXT_WIZ_REHEAT1_CZ "Klikněte ohrat" +#define UI_TEXT_WIZ_REHEAT2_CZ "extruders." +#define UI_TEXT_WIZ_WAITTEMP1_CZ "Pockejte na cilove" +#define UI_TEXT_WIZ_WAITTEMP2_CZ "teploty ..." +#define UI_TEXT_EXTRUDER_JAM_CZ "Extruder jam" +#define UI_TEXT_STANDBY_CZ "Standby" +#define UI_TEXT_BED_COATING_CZ "Postel nater" +#define UI_TEXT_BED_COATING_SET1_CZ "Postel nater:" +#define UI_TEXT_BED_COATING_SET2_CZ "" +#define UI_TEXT_NOCOATING_CZ "No nater" +#define UI_TEXT_BUILDTAK_CZ "BuildTak" +#define UI_TEXT_KAPTON_CZ "Kapton" +#define UI_TEXT_BLUETAPE_CZ "Modra mask. paska" +#define UI_TEXT_PETTAPE_CZ "Zelena PET paska" +#define UI_TEXT_GLUESTICK_CZ "Lepici tycinka" +#define UI_TEXT_CUSTOM_CZ "Vlastni" +#define UI_TEXT_COATING_CUSTOM_CZ "Vlastni:%BCmm" +#define UI_TEXT_LANGUAGE_CZ "Jazyk" + +#if NUM_EXTRUDER > 2 || MIXING_EXTRUDER != 0 +#define UI_TEXT_MAINPAGE6_1_CZ "\xa %ec/%Ec\xb0 X:%x0" +#else +#define UI_TEXT_MAINPAGE6_1_CZ "\xa %e0/%E0\xb0 X:%x0" +#endif // NUM_EXTRUDER +#if NUM_EXTRUDER == 2 && MIXING_EXTRUDER == 0 +#define UI_TEXT_MAINPAGE6_2_CZ "\xa %e1/%E1\xb0 Y:%x1" +#elif HAVE_HEATED_BED +#define UI_TEXT_MAINPAGE6_2_CZ "\xe %eb/%Eb\xb0 Y:%x1" +#else +#define UI_TEXT_MAINPAGE6_2_CZ " Y:%x1" +#endif +#if HAVE_HEATED_BED && NUM_EXTRUDER == 2 && MIXING_EXTRUDER == 0 +#define UI_TEXT_MAINPAGE6_3_CZ "\xe %eb/%Eb\xb0 Z:%x2" +#elif FEATURE_DITTO_PRINTING +#define UI_TEXT_MAINPAGE6_3_CZ "Kopii: %ed Z:%x2" +#else +#define UI_TEXT_MAINPAGE6_3_CZ "Flow:\xfd %of%%% Z:%x2" +#endif +#define UI_TEXT_MAINPAGE6_4_CZ "Mul: %om%%% \xfd E: %x4m" +#define UI_TEXT_MAINPAGE6_5_CZ "Buf: %oB" +#define UI_TEXT_MAINPAGE6_6_CZ "%os" +#define UI_TEXT_MAINPAGE_TEMP_BED_CZ cTEMP "%ec/%Ec" cDEG "B%eB/%Eb" cDEG +#define UI_TEXT_MAINPAGE_BED_CZ "B%eB/%Eb" cDEG +#define UI_TEXT_MAINPAGE_Z_BUF_CZ "Z:%x2 Buf : %oB" +#define UI_TEXT_MAINPAGE_MUL_EUSAGE_CZ "Mul: %om E:%x4" +#define UI_TEXT_MAINPAGE_XY_CZ "X:%x0 Y:%x1" +#define UI_TEXT_PRINT_TIME_VALUE_CZ "%Ut" +#define UI_TEXT_PRINT_FILAMENT_VALUE_CZ "%Uf m" +#define UI_TEXT_METER_PRINTED_CZ "%Uf m " UI_TEXT_PRINTED_CZ +#define UI_TEXT_STATUS_CZ "%os" +#define UI_TEXT_EMPTY_CZ "" +#define UI_TEXT_TEMP_SET_CZ cTEMP "%ec/%Ec" cDEG +#define UI_TEXT_CURRENT_TEMP_CZ cTEMP "%ec" cDEG +#define UI_TEXT_COATING_THICKNESS_CZ " %BCmm" +#define UI_TEXT_EXTR3_TEMP_CZ "Teplota 4:%e3/%E3" cDEG "C" +#define UI_TEXT_EXTR4_TEMP_CZ "Teplota 5:%e4/%E4" cDEG "C" +#define UI_TEXT_EXTR5_TEMP_CZ "Teplota 6:%e5/%E5" cDEG "C" +#define UI_TEXT_EXTR3_OFF_CZ "Extruder 4 vyp." +#define UI_TEXT_EXTR4_OFF_CZ "Extruder 5 vyp." +#define UI_TEXT_EXTR5_OFF_CZ "Extruder 6 vyp." +#define UI_TEXT_EXTR3_SELECT_CZ "%X3 Zvolit Extr. 4" +#define UI_TEXT_EXTR4_SELECT_CZ "%X4 Zvolit Extr. 5" +#define UI_TEXT_EXTR5_SELECT_CZ "%X5 Zvolit Extr. 6" +#define UI_TEXT_DITTO_0_CZ "%D0 Zadne Kopie" +#define UI_TEXT_DITTO_1_CZ "%D1 1 Kopie" +#define UI_TEXT_DITTO_2_CZ "%D2 2 Kopii" +#define UI_TEXT_DITTO_3_CZ "%D3 3 Kopii" +#define UI_TEXT_ZPROBE_HEIGHT_CZ "Vyska z-test:%zh" + +#define UI_TEXT_OFFSETS_CZ "Set print offsets" +#define UI_TEXT_X_OFFSET_CZ "Set X offset:%T0mm" +#define UI_TEXT_Y_OFFSET_CZ "Set Y offset:%T1mm" +#define UI_TEXT_Z_OFFSET_CZ "Set Z offset:%T2mm" + + +// *************** Polish translation **************** +// *************** By MIS **************** +// version: 2015/01/18 + +#define UI_TEXT_ON_PL "Zal" +#define UI_TEXT_OFF_PL "Wyl" +#define UI_TEXT_NA_PL "Brak" // Output for not available +#define UI_TEXT_YES_PL "Tak" +#define UI_TEXT_NO_PL "Nie" +#define UI_TEXT_PRINT_POS_PL "Drukowanie..." +#define UI_TEXT_PRINTING_PL "Drukowanie" +#define UI_TEXT_IDLE_PL "Wolna" +#define UI_TEXT_NOSDCARD_PL "Brak karty SD" +#define UI_TEXT_ERROR_PL "**** BLAD ****" +#define UI_TEXT_BACK_PL "Powrot " cUP +#define UI_TEXT_QUICK_SETTINGS_PL "Szybkie ustawienia" +#define UI_TEXT_ERRORMSG_PL "%oe" +#define UI_TEXT_CONFIGURATION_PL "Konfiguracja" +#define UI_TEXT_POSITION_PL "Pozycja" +#define UI_TEXT_EXTRUDER_PL "Ekstruder" +#define UI_TEXT_SD_CARD_PL "Karta SD" +#define UI_TEXT_DEBUGGING_PL "Testowanie" +#define UI_TEXT_HOME_DELTA_PL "Home delta" +#define UI_TEXT_HOME_ALL_PL "Zeruj wszystkie osie" +#define UI_TEXT_HOME_X_PL "Zeruj X" +#define UI_TEXT_HOME_Y_PL "Zeruj Y" +#define UI_TEXT_HOME_Z_PL "Zeruj Z" +#define UI_TEXT_PREHEAT_PLA_PL "Rozgrzej PLA" +#define UI_TEXT_PREHEAT_ABS_PL "Rozgrzej ABS" +#define UI_TEXT_LIGHTS_ONOFF_PL "Oswietlenie :%lo" +#define UI_TEXT_COOLDOWN_PL "Chlodzenie" +#define UI_TEXT_SET_TO_ORIGIN_PL "Ustaw jako zero" +#define UI_TEXT_DISABLE_STEPPER_PL "Wylacz silniki" +#define UI_TEXT_X_POSITION_PL "Pozycja X" +#define UI_TEXT_X_POS_FAST_PL "Pozycja X Szybko" +#define UI_TEXT_Y_POSITION_PL "Pozycja Y" +#define UI_TEXT_Y_POS_FAST_PL "Pozycja Y Szybko" +#define UI_TEXT_Z_POSITION_PL "Pozycja Z" +#define UI_TEXT_Z_POS_FAST_PL "Pozycja Z Szybko" +#define UI_TEXT_E_POSITION_PL "Pozycja Extrudera" +#define UI_TEXT_BED_TEMP_PL "Temp.Stolu:%eb/%Eb" cDEG "C" +#define UI_TEXT_EXTR0_TEMP_PL "Temp.Ex1:%e0/%E0" cDEG "C" +#define UI_TEXT_EXTR1_TEMP_PL "Temp.Ex2:%e1/%E1" cDEG "C" +#define UI_TEXT_EXTR2_TEMP_PL "Temp.Ex3:%e2/%E2" cDEG "C" +#define UI_TEXT_EXTR0_OFF_PL "Wyl. Extruder 1" +#define UI_TEXT_EXTR1_OFF_PL "Wyl. Extruder 2" +#define UI_TEXT_EXTR2_OFF_PL "Wyl. Extruder 3" +#define UI_TEXT_EXTR0_SELECT_PL "%X0 Wybierz Extr. 1" +#define UI_TEXT_EXTR1_SELECT_PL "%X1 Wybierz Extr. 2" +#define UI_TEXT_EXTR2_SELECT_PL "%X1 Wybierz Extr. 3" +#define UI_TEXT_EXTR_ORIGIN_PL "Ustaw jako zero" +#define UI_TEXT_PRINT_X_PL "Drukow. X :%ax" +#define UI_TEXT_PRINT_Y_PL "Drukow. Y :%ay" +#define UI_TEXT_PRINT_Z_PL "Drukow. Z :%az" +#define UI_TEXT_PRINT_Z_DELTA_PL "Drukowania :%az" +#define UI_TEXT_MOVE_X_PL "Przesuw. X :%aX" +#define UI_TEXT_MOVE_Y_PL "Przesuw. Y :%aY" +#define UI_TEXT_MOVE_Z_PL "Przesuw. Z :%aZ" +#define UI_TEXT_MOVE_Z_DELTA_PL "Przesuwania :%aZ" +#define UI_TEXT_JERK_PL "Jerk:%aj" +#define UI_TEXT_ZJERK_PL "Z-Jerk:%aJ" +#define UI_TEXT_ACCELERATION_PL "Przyspieszenie" +#define UI_TEXT_STORE_TO_EEPROM_PL "Zapisz do EEPROM" +#define UI_TEXT_LOAD_EEPROM_PL "Odczyt z EEPROM" +#define UI_TEXT_DBG_ECHO_PL "Echo : %do" +#define UI_TEXT_DBG_INFO_PL "Informacje : %di" +#define UI_TEXT_DBG_ERROR_PL "Bledy : %de" +#define UI_TEXT_DBG_DRYRUN_PL "Bez wydruku : %dd" +#define UI_TEXT_DBG_ENDSTOP_PL "EndStop : %dp" +#define UI_TEXT_OPS_OFF_PL "%O0 OPS Off" +#define UI_TEXT_OPS_CLASSIC_PL "%O1 OPS Classic" +#define UI_TEXT_OPS_FAST_PL "%O2 OPS Fast" +#define UI_TEXT_OPS_RETRACT_PL "Retract :%Or" +#define UI_TEXT_OPS_BACKSLASH_PL "Backsl. :%Ob" +#define UI_TEXT_OPS_MINDIST_PL "Min.dist:%Od" +#define UI_TEXT_OPS_MOVE_AFTER_PL "Przesun po:%Oa" +#define UI_TEXT_ANTI_OOZE_PL "Anti Ooze" +#define UI_TEXT_PRINT_FILE_PL "Drukuj z pliku" +#define UI_TEXT_PAUSE_PRINT_PL "Wstrzymaj druk" +#define UI_TEXT_CONTINUE_PRINT_PL "Wznow drukow." +#define UI_TEXT_UNMOUNT_CARD_PL "Odmontuj karte" +#define UI_TEXT_MOUNT_CARD_PL "Zamontuj karte" +#define UI_TEXT_DELETE_FILE_PL "Usun plik" +#define UI_TEXT_FEEDRATE_PL "Szybkosc" +#define UI_TEXT_FEED_MAX_X_PL "Max X:%fx" +#define UI_TEXT_FEED_MAX_Y_PL "Max Y:%fy" +#define UI_TEXT_FEED_MAX_Z_PL "Max Z:%fz" +#define UI_TEXT_FEED_MAX_Z_DELTA_PL "Max:%fz" +#define UI_TEXT_FEED_HOME_X_PL "Powrot X:%fX" +#define UI_TEXT_FEED_HOME_Y_PL "Powrot Y:%fY" +#define UI_TEXT_FEED_HOME_Z_PL "Powrot Z:%fZ" +#define UI_TEXT_FEED_HOME_Z_DELTA_PL "Powrot:%fZ" +#define UI_TEXT_ACTION_XPOSITION4A_PL "X:%x0 mm %dx%dX" +#define UI_TEXT_ACTION_XPOSITION4B_PL "Krancowka MIN: %sx" +#define UI_TEXT_ACTION_XPOSITION4C_PL "Krancowka MAX: %sX" +#define UI_TEXT_ACTION_XPOSITION4D_PL "" +#define UI_TEXT_ACTION_YPOSITION4A_PL "Y:%x1 mm %dy%dY" +#define UI_TEXT_ACTION_YPOSITION4B_PL "Krancowka MIN: %sy" +#define UI_TEXT_ACTION_YPOSITION4C_PL "Krancowka Max: %sY" +#define UI_TEXT_ACTION_YPOSITION4D_PL "" +#define UI_TEXT_ACTION_ZPOSITION4A_PL "Z:%x2 mm %dz%dZ" +#define UI_TEXT_ACTION_ZPOSITION4B_PL "Krancowka MIN: %sz" +#define UI_TEXT_ACTION_ZPOSITION4C_PL "Krancowka Max: %sZ" +#define UI_TEXT_ACTION_ZPOSITION4D_PL "" +#define UI_TEXT_ACTION_XPOSITION_FAST4A_PL "X:%x0 mm" +#define UI_TEXT_ACTION_XPOSITION_FAST4B_PL "Krancowka MIN: %sx" +#define UI_TEXT_ACTION_XPOSITION_FAST4C_PL "Krancowka MAX: %sX" +#define UI_TEXT_ACTION_XPOSITION_FAST4D_PL "" +#define UI_TEXT_ACTION_YPOSITION_FAST4A_PL "Y:%x1 mm" +#define UI_TEXT_ACTION_YPOSITION_FAST4B_PL "Krancowka MIN: %sy" +#define UI_TEXT_ACTION_YPOSITION_FAST4C_PL "Krancowka MAX: %sY" +#define UI_TEXT_ACTION_YPOSITION_FAST4D_PL "" +#define UI_TEXT_ACTION_ZPOSITION_FAST4A_PL "Z:%x2 mm" +#define UI_TEXT_ACTION_ZPOSITION_FAST4B_PL "Krancowka MIN: %sz" +#define UI_TEXT_ACTION_ZPOSITION_FAST4C_PL "Krancowka MAX: %sZ" +#define UI_TEXT_ACTION_ZPOSITION_FAST4D_PL "" +#define UI_TEXT_ACTION_EPOSITION_FAST2A_PL "E:%x3 mm" +#define UI_TEXT_ACTION_EPOSITION_FAST2B_PL "Jednostka 1 mm" +#define UI_TEXT_ACTION_XPOSITION2A_PL "X:%x0 mm" +#define UI_TEXT_ACTION_XPOSITION2B_PL "Min:%sx Max:%sX" +#define UI_TEXT_ACTION_YPOSITION2A_PL "Y:%x1 mm" +#define UI_TEXT_ACTION_YPOSITION2B_PL "Min:%sy Max:%sY" +#define UI_TEXT_ACTION_ZPOSITION2A_PL "Z:%x2 mm" +#define UI_TEXT_ACTION_ZPOSITION2B_PL "Min:%sz Max:%sZ" +#define UI_TEXT_ACTION_XPOSITION_FAST2A_PL "X:%x0 mm" +#define UI_TEXT_ACTION_XPOSITION_FAST2B_PL "Min:%sx Max:%sX" +#define UI_TEXT_ACTION_YPOSITION_FAST2A_PL "Y:%x1 mm" +#define UI_TEXT_ACTION_YPOSITION_FAST2B_PL "Min:%sy Max:%sY" +#define UI_TEXT_ACTION_ZPOSITION_FAST2A_PL "Z:%x2 mm" +#define UI_TEXT_ACTION_ZPOSITION_FAST2B_PL "Min:%sz Max:%sZ" +#define UI_TEXT_FANSPEED_PL "Obroty wiatraka" +#define UI_TEXT_ACTION_FANSPEED_PL "Obroty wiatraka:%Fs%%%" +#define UI_TEXT_FAN_OFF_PL "Wylacz wiatrak" +#define UI_TEXT_FAN_25_PL "Ustaw na 25%%%" +#define UI_TEXT_FAN_50_PL "Ustaw na 50%%%" +#define UI_TEXT_FAN_75_PL "Ustaw na 75%%%" +#define UI_TEXT_FAN_FULL_PL "Ustaw na 100%%%" +#define UI_TEXT_STEPPER_INACTIVE_PL "Wylacz silniki po" +#define UI_TEXT_STEPPER_INACTIVE2A_PL "Wylacz po: %is min." +#define UI_TEXT_STEPPER_INACTIVE2B_PL "0=Nie wylaczaj" +#define UI_TEXT_POWER_INACTIVE_PL "Wylacz zasil. po" +#define UI_TEXT_POWER_INACTIVE2A_PL "Wylacz po: %ip min." +#define UI_TEXT_POWER_INACTIVE2B_PL "0=Nie wylaczaj" +#define UI_TEXT_GENERAL_PL "Ustawienia glowne" +#define UI_TEXT_BAUDRATE_PL "Szybkosc USB:%oc" +#define UI_TEXT_EXTR_STEPS_PL "Kroki/mm : %Se" +#define UI_TEXT_EXTR_START_FEED_PL "Poczatkowa SZ:%Xf" +#define UI_TEXT_EXTR_MAX_FEED_PL "Max Szybkosc :%XF" +#define UI_TEXT_EXTR_ACCEL_PL "Przyspiesz. :%XA" +#define UI_TEXT_EXTR_WATCH_PL "Czas stabil. :%Xws" +#define UI_TEXT_EXTR_ADVANCE_L_PL "Advance lin :%Xl" +#define UI_TEXT_EXTR_ADVANCE_K_PL "Advance quad :%Xa" +#define UI_TEXT_EXTR_MANAGER_PL "Regulator:%Xh" +#define UI_TEXT_EXTR_DEADTIME_PL "Deadtime :%Xp" +#define UI_TEXT_EXTR_DMAX_DT_PL "Max. PWM :%XD" +#define UI_TEXT_EXTR_PGAIN_PL "PID P :%Xp" +#define UI_TEXT_EXTR_IGAIN_PL "PID I :%Xi" +#define UI_TEXT_EXTR_DGAIN_PL "PID D :%Xd" +#define UI_TEXT_EXTR_DMIN_PL "Min I war: %Xm" +#define UI_TEXT_EXTR_DMAX_PL "Max I war: %XM" +#define UI_TEXT_EXTR_PMAX_PL "Max ster.: %XD" +#define UI_TEXT_EXTR_XOFF_PL "Ofset X :%Xx" +#define UI_TEXT_EXTR_YOFF_PL "Ofset Y :%Xy" +#define UI_TEXT_STRING_HM_BANGBANG_PL "Dwustanowy" +#define UI_TEXT_STRING_HM_PID_PL "PID" +#define UI_TEXT_STRING_ACTION_PL "Akcja:%la" +#define UI_TEXT_HEATING_EXTRUDER_PL "Grzanie glowicy" +#define UI_TEXT_HEATING_BED_PL "Grzanie stolu" +#define UI_TEXT_KILLED_PL "Zatrzymany" +#define UI_TEXT_STEPPER_DISABLED_PL "Silniki wylaczone" +#define UI_TEXT_EEPROM_STOREDA_PL "Konfiguracja" +#define UI_TEXT_EEPROM_STOREDB_PL "zapisana do EEPROM" +#define UI_TEXT_EEPROM_LOADEDA_PL "Konfiguracja" +#define UI_TEXT_EEPROM_LOADEDB_PL "odczytana z EEPROM" +#define UI_TEXT_UPLOADING_PL "Ladowanie..." +#define UI_TEXT_PAGE_BUFFER_PL "Bufor:%oB" +#define UI_TEXT_PAGE_EXTRUDER_PL " E:%ec/%Ec" cDEG "C" cARROW "%oC" +#define UI_TEXT_PAGE_EXTRUDER1_PL "E1:%e0/%E0" cDEG "C" cARROW "%o0" +#define UI_TEXT_PAGE_EXTRUDER2_PL "E2:%e1/%E1" cDEG "C" cARROW "%o1" +#define UI_TEXT_PAGE_EXTRUDER3_PL "E3:%e2/%E2" cDEG "C" cARROW "%o2" +#define UI_TEXT_PAGE_BED_PL " B:%eb/%Eb" cDEG "C" cARROW "%ob" +#define UI_TEXT_SPEED_MULTIPLY_PL "Szybkosc druku :%om%%%" +#define UI_TEXT_FLOW_MULTIPLY_PL "Przeplyw filam.:%of%%%" +#define UI_TEXT_SHOW_MEASUREMENT_PL "Pokaz pomiar" +#define UI_TEXT_RESET_MEASUREMENT_PL "Zeruj pomiar" +#define UI_TEXT_SET_MEASURED_ORIGIN_PL "Ustaw Z=0" +#define UI_TEXT_ZCALIB_PL "Z kalib." +#define UI_TEXT_SET_P1_PL "Ustaw P1" +#define UI_TEXT_SET_P2_PL "Ustaw P2" +#define UI_TEXT_SET_P3_PL "Ustaw P3" +#define UI_TEXT_CALCULATE_LEVELING_PL "Oblicz poziomowania" +#define UI_TEXT_LEVEL_PL "Poziom delty" +#define UI_TEXT_EXTR_WAIT_RETRACT_TEMP_PL "MinTemp wysuwu:%XT" cDEG "C" +#define UI_TEXT_EXTR_WAIT_RETRACT_UNITS_PL "Wysuw rozgrzew:%XUmm" +#define UI_TEXT_SD_REMOVED_PL "Karta SD wyjeta" +#define UI_TEXT_SD_INSERTED_PL "Karta SD wlozona" +#define UI_TEXT_PRINTER_READY_PL "Drukarka gotowa" +// Printtime output gets aggregated like UI_TEXT_PRINTTIME_DAYSUI_TEXT_PRINTTIME_HOURSUI_TEXT_PRINTTIME_MINUTES +// ___88 days 12:45 +#define UI_TEXT_PRINTTIME_DAYS_PL " dni, " +#define UI_TEXT_PRINTTIME_HOURS_PL ":" +#define UI_TEXT_PRINTTIME_MINUTES_PL " h." +#define UI_TEXT_PRINT_TIME_PL "Czas pracy" +#define UI_TEXT_PRINT_FILAMENT_PL "Zuzyto filamentu" +#define UI_TEXT_PRINTED_PL "drukowane" +#define UI_TEXT_POWER_PL "Wl/Wyl zasilanie" +#define UI_TEXT_STRING_HM_DEADTIME_PL "Dead Time" +#define UI_TEXT_STRING_HM_SLOWBANG_PL "SlowBang" +#define UI_TEXT_STOP_PRINT_PL "Przerwij wydruk" +#define UI_TEXT_Z_BABYSTEPPING_PL "Doreguluj Z:%oYmm" +#define UI_TEXT_CHANGE_FILAMENT_PL "Zmiana filamentu" +#define UI_TEXT_WIZ_CH_FILAMENT1_PL "Zmien filament" +#define UI_TEXT_WIZ_CH_FILAMENT2_PL "Krec aby przesuwac" +#define UI_TEXT_WIZ_CH_FILAMENT3_PL "filament w gore/dol" +#define UI_TEXT_CLICK_DONE_PL "Kliknij jak gotowe" +#define UI_TEXT_AUTOLEVEL_ONOFF_PL "Autopoziomow.: %ll" +#define UI_TEXT_SERVOPOS_PL "Pozycja Serwa: %oS" +#define UI_TEXT_IGNORE_M106_PL "Ignoruj kom. M106 %Fi" +#define UI_TEXT_WIZ_REHEAT1_PL "Kliknij aby znów" +#define UI_TEXT_WIZ_REHEAT2_PL "rozgrzac ekstrudery" +#define UI_TEXT_WIZ_WAITTEMP1_PL "Poczekaj na zadane" +#define UI_TEXT_WIZ_WAITTEMP2_PL "temperatury ..." +#define UI_TEXT_EXTRUDER_JAM_PL "Ekstruder zablokowany" +#define UI_TEXT_STANDBY_PL "Standby" +#define UI_TEXT_BED_COATING_PL "Pokrycie stolu" +#define UI_TEXT_BED_COATING_SET1_PL "Wybierz material" +#define UI_TEXT_BED_COATING_SET2_PL "stolu:" +#define UI_TEXT_NOCOATING_PL "Czysty stol" +#define UI_TEXT_BUILDTAK_PL "BuildTak" +#define UI_TEXT_KAPTON_PL "Kapton" +#define UI_TEXT_BLUETAPE_PL "Nieb. tasma mask." +#define UI_TEXT_PETTAPE_PL "Zielona tasma PET" +#define UI_TEXT_GLUESTICK_PL "Klej w sztyfcie" +#define UI_TEXT_CUSTOM_PL "Inna" +#define UI_TEXT_COATING_CUSTOM_PL "Inna grubosc:%BCmm" +#define UI_TEXT_LANGUAGE_PL "Jezyk" +#if NUM_EXTRUDER > 2 || MIXING_EXTRUDER != 0 +#define UI_TEXT_MAINPAGE6_1_PL "\xa %ec/%Ec\xb0 X:%x0" +#else +#define UI_TEXT_MAINPAGE6_1_PL "\xa %e0/%E0\xb0 X:%x0" +#endif // NUM_EXTRUDER +#if NUM_EXTRUDER == 2 && MIXING_EXTRUDER == 0 +#define UI_TEXT_MAINPAGE6_2_PL "\xa %e1/%E1\xb0 Y:%x1" +#elif HAVE_HEATED_BED +#define UI_TEXT_MAINPAGE6_2_PL "\xe %eb/%Eb\xb0 Y:%x1" +#else +#define UI_TEXT_MAINPAGE6_2_PL " Y:%x1" +#endif +#if HAVE_HEATED_BED && NUM_EXTRUDER == 2 && MIXING_EXTRUDER == 0 +#define UI_TEXT_MAINPAGE6_3_PL "\xe %eb/%Eb\xb0 Z:%x2" +#elif FEATURE_DITTO_PRINTING +#define UI_TEXT_MAINPAGE6_3_PL "Kopie: %ed Z:%x2" +#else +#define UI_TEXT_MAINPAGE6_3_PL "Przep:\xfd %of%%% Z:%x2" +#endif +#define UI_TEXT_MAINPAGE6_4_PL "Mul: %om%%% \xfd E: %x4m" +#define UI_TEXT_MAINPAGE6_5_PL "Buf: %oB" +#define UI_TEXT_MAINPAGE6_6_PL "%os" +#define UI_TEXT_MAINPAGE_TEMP_BED_PL cTEMP "%ec/%Ec" cDEG "B%eB/%Eb" cDEG +#define UI_TEXT_MAINPAGE_BED_PL "B%eB/%Eb" cDEG +#define UI_TEXT_MAINPAGE_Z_BUF_PL "Z:%x2 Buf : %oB" +#define UI_TEXT_MAINPAGE_MUL_EUSAGE_PL "Mul: %om E:%x4" +#define UI_TEXT_MAINPAGE_XY_PL "X:%x0 Y:%x1" +#define UI_TEXT_PRINT_TIME_VALUE_PL "%Ut" +#define UI_TEXT_PRINT_FILAMENT_VALUE_PL "%Uf m" +#define UI_TEXT_METER_PRINTED_PL "%Uf m " UI_TEXT_PRINTED_PL +#define UI_TEXT_STATUS_PL "%os" +#define UI_TEXT_EMPTY_PL "" +#define UI_TEXT_TEMP_SET_PL cTEMP "%ec/%Ec" cDEG +#define UI_TEXT_CURRENT_TEMP_PL cTEMP "%ec" cDEG +#define UI_TEXT_COATING_THICKNESS_PL " %BCmm" +#define UI_TEXT_EXTR3_TEMP_PL "Temp.Ex4:%e3/%E3" cDEG "C" +#define UI_TEXT_EXTR4_TEMP_PL "Temp.Ex5:%e4/%E4" cDEG "C" +#define UI_TEXT_EXTR5_TEMP_PL "Temp.Ex6:%e5/%E5" cDEG "C" +#define UI_TEXT_EXTR3_OFF_PL "Wyl. Extruder 4" +#define UI_TEXT_EXTR4_OFF_PL "Wyl. Extruder 5" +#define UI_TEXT_EXTR5_OFF_PL "Wyl. Extruder 6" +#define UI_TEXT_EXTR3_SELECT_PL "%X3 Wybierz Extr. 4" +#define UI_TEXT_EXTR4_SELECT_PL "%X4 Wybierz Extr. 5" +#define UI_TEXT_EXTR5_SELECT_PL "%X5 Wybierz Extr. 6" +#define UI_TEXT_DITTO_0_PL "%D0 Nie kopiuj" +#define UI_TEXT_DITTO_1_PL "%D1 1 Kopia" +#define UI_TEXT_DITTO_2_PL "%D2 2 Kopie" +#define UI_TEXT_DITTO_3_PL "%D3 3 Kopie" +#define UI_TEXT_ZPROBE_HEIGHT_PL "Wys. Sondy Z:%zh" + +#define UI_TEXT_OFFSETS_PL "Polozenie wydruku" +#define UI_TEXT_X_OFFSET_PL "Przesun w X : %T0mm" +#define UI_TEXT_Y_OFFSET_PL "Przesun w Y : %T1mm" +#define UI_TEXT_Z_OFFSET_PL "Przesun w Z :%T2mm" + +// Türk + +#define UI_TEXT_ON_TR "Acik" +#define UI_TEXT_OFF_TR "Kapali" +#define UI_TEXT_NA_TR "N/A" // Output for not available +#define UI_TEXT_YES_TR "Evet" +#define UI_TEXT_NO_TR "Hayir" +#define UI_TEXT_PRINT_POS_TR "Yaziyor..." +#define UI_TEXT_PRINTING_TR "Yaziyor" +#define UI_TEXT_IDLE_TR "Bosta" +#define UI_TEXT_NOSDCARD_TR "SD Kart Yok" +#define UI_TEXT_ERROR_TR "**** HATA ****" +#define UI_TEXT_BACK_TR "Geri " cUP +#define UI_TEXT_QUICK_SETTINGS_TR "Hizli Ayar" +#define UI_TEXT_ERRORMSG_TR "%oe" +#define UI_TEXT_CONFIGURATION_TR "Yapilandirma" +#define UI_TEXT_POSITION_TR "Konum-Hareket" +#define UI_TEXT_EXTRUDER_TR "Extruder" +#define UI_TEXT_SD_CARD_TR "SD Kart" +#define UI_TEXT_DEBUGGING_TR "Debugging" +#define UI_TEXT_HOME_DELTA_TR "Deltayi Sifr. Gond." +#define UI_TEXT_HOME_ALL_TR "Hepsini S.Gonder" +#define UI_TEXT_HOME_X_TR "X S.Gonder" +#define UI_TEXT_HOME_Y_TR "Y S.Gonder" +#define UI_TEXT_HOME_Z_TR "Z S.Gonder" +#define UI_TEXT_PREHEAT_PLA_TR "PLA On Isitma" +#define UI_TEXT_PREHEAT_ABS_TR "ABS On Isitma" +#define UI_TEXT_LIGHTS_ONOFF_TR "Isiklar :%lo" +#define UI_TEXT_COOLDOWN_TR "Soguma" +#define UI_TEXT_SET_TO_ORIGIN_TR "Orijine ayarla" +#define UI_TEXT_DISABLE_STEPPER_TR "Motoru Kapat" +#define UI_TEXT_X_POSITION_TR "X Hareketi" +#define UI_TEXT_X_POS_FAST_TR "X Hizli Hareketi" +#define UI_TEXT_Y_POSITION_TR "Y Hareketi" +#define UI_TEXT_Y_POS_FAST_TR "Y Hizli Hareketi" +#define UI_TEXT_Z_POSITION_TR "Z Hareketi" +#define UI_TEXT_Z_POS_FAST_TR "Z Hizli Hareketi" +#define UI_TEXT_E_POSITION_TR "Hareketi" +#define UI_TEXT_BED_TEMP_TR "Tabla Sic: %Eb" cDEG "C" +#define UI_TEXT_EXTR0_TEMP_TR "Sic. 1 : %E0" cDEG "C" +#define UI_TEXT_EXTR1_TEMP_TR "Sic. 2 : %E1" cDEG "C" +#define UI_TEXT_EXTR2_TEMP_TR "Sic. 3 : %E2" cDEG "C" +#define UI_TEXT_EXTR0_OFF_TR "Extr. 1'i Kapa" +#define UI_TEXT_EXTR1_OFF_TR "Extr. 2'i Kapa" +#define UI_TEXT_EXTR2_OFF_TR "Extr. 3'i Kapa" +#define UI_TEXT_EXTR0_SELECT_TR "%X0 Extr. 1'i Sec" +#define UI_TEXT_EXTR1_SELECT_TR "%X1 Extr. 2'yi Sec" +#define UI_TEXT_EXTR2_SELECT_TR "%X2 Extr. 3'u Sec" +#define UI_TEXT_EXTR_ORIGIN_TR "Origin i Ayarla" +#define UI_TEXT_PRINT_X_TR "Yazma H. X:%ax" +#define UI_TEXT_PRINT_Y_TR "Yazma H. Y:%ay" +#define UI_TEXT_PRINT_Z_TR "Yazma H. Z:%az" +#define UI_TEXT_PRINT_Z_DELTA_TR "Yazma H.:%az" +#define UI_TEXT_MOVE_X_TR "Hareket X :%aX" +#define UI_TEXT_MOVE_Y_TR "Hareket Y :%aY" +#define UI_TEXT_MOVE_Z_TR "Hareket Z :%aZ" +#define UI_TEXT_MOVE_Z_DELTA_TR "Hareket :%aZ" +#define UI_TEXT_JERK_TR "X-Y Jerk :%aj" +#define UI_TEXT_ZJERK_TR "Z-Jerk :%aJ" +#define UI_TEXT_ACCELERATION_TR "Ivme" +#define UI_TEXT_STORE_TO_EEPROM_TR "EEPROM'a kaydet" +#define UI_TEXT_LOAD_EEPROM_TR "EEPROM'dan cagir" +#define UI_TEXT_DBG_ECHO_TR "Echo :%do" +#define UI_TEXT_DBG_INFO_TR "Bilgi :%di" +#define UI_TEXT_DBG_ERROR_TR "Hatalar :%de" +#define UI_TEXT_DBG_DRYRUN_TR "Bosta Calis:%dd" +#define UI_TEXT_DBG_ENDSTOP_TR "EndStop :%dp" +#define UI_TEXT_OPS_OFF_TR "%O0 OPS Kapali" +#define UI_TEXT_OPS_CLASSIC_TR "%O1 OPS Klasik" +#define UI_TEXT_OPS_FAST_TR "%O2 OPS Hizli" +#define UI_TEXT_OPS_RETRACT_TR "Geri Cekl.:%Or" +#define UI_TEXT_OPS_BACKSLASH_TR "Eksen Bosl.:%Ob" +#define UI_TEXT_OPS_MINDIST_TR "Min. Mesafe:%Od" +#define UI_TEXT_OPS_MOVE_AFTER_TR "Move after:%Oa" +#define UI_TEXT_ANTI_OOZE_TR "Anti Ooze" +#define UI_TEXT_PRINT_FILE_TR "Dosya Yazdir" +#define UI_TEXT_PAUSE_PRINT_TR "Baskiyi Duraklat" +#define UI_TEXT_CONTINUE_PRINT_TR "Baskiya Devam" +#define UI_TEXT_UNMOUNT_CARD_TR "Karti Cikar" +#define UI_TEXT_MOUNT_CARD_TR "Karti Bagla" +#define UI_TEXT_DELETE_FILE_TR "Dosyayi Sil" +#define UI_TEXT_FEEDRATE_TR "Ilerleme" +#define UI_TEXT_FEED_MAX_X_TR "Max X:%fx" +#define UI_TEXT_FEED_MAX_Y_TR "Max Y:%fy" +#define UI_TEXT_FEED_MAX_Z_TR "Max Z:%fz" +#define UI_TEXT_FEED_MAX_Z_DELTA_TR "Max:%fz" +#define UI_TEXT_FEED_HOME_X_TR "X'i Sif.Gon.Hiz.:%fX" +#define UI_TEXT_FEED_HOME_Y_TR "Y'yi Sif.Gon.Hiz.:%fY" +#define UI_TEXT_FEED_HOME_Z_TR "Z'i Sif.Gon.Hiz:%fZ" +#define UI_TEXT_FEED_HOME_Z_DELTA_TR "Delta Sif.Gon.Hiz:%fZ" +#define UI_TEXT_ACTION_XPOSITION4A_TR "X:%x0 mm %dx%dX" +#define UI_TEXT_ACTION_XPOSITION4B_TR "Min endstop:%sx" +#define UI_TEXT_ACTION_XPOSITION4C_TR "Max endstop:%sX" +#define UI_TEXT_ACTION_XPOSITION4D_TR "" +#define UI_TEXT_ACTION_YPOSITION4A_TR "Y:%x1 mm %dy%dY" +#define UI_TEXT_ACTION_YPOSITION4B_TR "Min endstop:%sy" +#define UI_TEXT_ACTION_YPOSITION4C_TR "Max endstop:%sY" +#define UI_TEXT_ACTION_YPOSITION4D_TR "" +#define UI_TEXT_ACTION_ZPOSITION4A_TR "Z:%x2 mm %dz%dZ" +#define UI_TEXT_ACTION_ZPOSITION4B_TR "Min endstop:%sz" +#define UI_TEXT_ACTION_ZPOSITION4C_TR "Max endstop:%sZ" +#define UI_TEXT_ACTION_ZPOSITION4D_TR "" +#define UI_TEXT_ACTION_XPOSITION_FAST4A_TR "X:%x0 mm" +#define UI_TEXT_ACTION_XPOSITION_FAST4B_TR "Min endstop:%sx" +#define UI_TEXT_ACTION_XPOSITION_FAST4C_TR "Max endstop:%sX" +#define UI_TEXT_ACTION_XPOSITION_FAST4D_TR "" +#define UI_TEXT_ACTION_YPOSITION_FAST4A_TR "Y:%x1 mm" +#define UI_TEXT_ACTION_YPOSITION_FAST4B_TR "Min endstop:%sy" +#define UI_TEXT_ACTION_YPOSITION_FAST4C_TR "Max endstop:%sY" +#define UI_TEXT_ACTION_YPOSITION_FAST4D_TR "" +#define UI_TEXT_ACTION_ZPOSITION_FAST4A_TR "Z:%x2 mm" +#define UI_TEXT_ACTION_ZPOSITION_FAST4B_TR "Min endstop:%sz" +#define UI_TEXT_ACTION_ZPOSITION_FAST4C_TR "Max endstop:%sZ" +#define UI_TEXT_ACTION_ZPOSITION_FAST4D_TR "" +#define UI_TEXT_ACTION_EPOSITION_FAST2A_TR "E:%x3 mm" +#define UI_TEXT_ACTION_EPOSITION_FAST2B_TR "1 tik = 1 mm" +#define UI_TEXT_ACTION_XPOSITION2A_TR "X:%x0 mm" +#define UI_TEXT_ACTION_XPOSITION2B_TR "Min:%sx Max:%sX" +#define UI_TEXT_ACTION_YPOSITION2A_TR "Y:%x1 mm" +#define UI_TEXT_ACTION_YPOSITION2B_TR "Min:%sy Max:%sY" +#define UI_TEXT_ACTION_ZPOSITION2A_TR "Z:%x2 mm" +#define UI_TEXT_ACTION_ZPOSITION2B_TR "Min:%sz Max:%sZ" +#define UI_TEXT_ACTION_XPOSITION_FAST2A_TR "X:%x0 mm" +#define UI_TEXT_ACTION_XPOSITION_FAST2B_TR "Min:%sx Max:%sX" +#define UI_TEXT_ACTION_YPOSITION_FAST2A_TR "Y:%x1 mm" +#define UI_TEXT_ACTION_YPOSITION_FAST2B_TR "Min:%sy Max:%sY" +#define UI_TEXT_ACTION_ZPOSITION_FAST2A_TR "Z:%x2 mm" +#define UI_TEXT_ACTION_ZPOSITION_FAST2B_TR "Min:%sz Max:%sZ" +#define UI_TEXT_FANSPEED_TR "Fan Hizi" +#define UI_TEXT_ACTION_FANSPEED_TR "Fan Hizi:%Fs%%%" +#define UI_TEXT_FAN_OFF_TR "Fan'i Kapat" +#define UI_TEXT_FAN_25_TR "Fan'i Ayarla 25%%%" +#define UI_TEXT_FAN_50_TR "Fan'i Ayarla 50%%%" +#define UI_TEXT_FAN_75_TR "Fan'i Ayarla 75%%%" +#define UI_TEXT_FAN_FULL_TR "Fan Tam Acik" +#define UI_TEXT_STEPPER_INACTIVE_TR "Motorlar Bosta" +#define UI_TEXT_STEPPER_INACTIVE2A_TR "Motor Kapa: %is" +#define UI_TEXT_STEPPER_INACTIVE2B_TR "[min] 0=Off" +#define UI_TEXT_POWER_INACTIVE_TR "Max. Bosta" +#define UI_TEXT_POWER_INACTIVE2A_TR "Kapama sur.: %ip" +#define UI_TEXT_POWER_INACTIVE2B_TR "[min] 0=Kapali" +#define UI_TEXT_GENERAL_TR "Genel" +#define UI_TEXT_BAUDRATE_TR "Baudrate:%oc" +#define UI_TEXT_EXTR_STEPS_TR "Adim/MM:%Se" +#define UI_TEXT_EXTR_START_FEED_TR "Baslangic FR:%Xf" +#define UI_TEXT_EXTR_MAX_FEED_TR "Max FR:%XF" +#define UI_TEXT_EXTR_ACCEL_TR "Ivme:%XA" +#define UI_TEXT_EXTR_WATCH_TR "Stab.Time:%Xw" +#define UI_TEXT_EXTR_ADVANCE_L_TR "Gelismis lin:%Xl" +#define UI_TEXT_EXTR_ADVANCE_K_TR "Gelismis quad:%Xa" +#define UI_TEXT_EXTR_MANAGER_TR "Kontrol:%Xh" +#define UI_TEXT_EXTR_PGAIN_TR "PID P:%Xp" +#define UI_TEXT_EXTR_DEADTIME_TR "Bos Zamn:%Xp" +#define UI_TEXT_EXTR_DMAX_DT_TR "Kontrol PWM:%XM" +#define UI_TEXT_EXTR_IGAIN_TR "PID I:%Xi" +#define UI_TEXT_EXTR_DGAIN_TR "PID D:%Xd" +#define UI_TEXT_EXTR_DMIN_TR "Surucu Min:%Xm" +#define UI_TEXT_EXTR_DMAX_TR "Surucu Max:%XM" +#define UI_TEXT_EXTR_PMAX_TR "PID Max:%XD" +#define UI_TEXT_EXTR_XOFF_TR "X-Ofset:%Xx" +#define UI_TEXT_EXTR_YOFF_TR "Y-Ofset:%Xy" +#define UI_TEXT_STRING_HM_BANGBANG_TR "BangBang" +#define UI_TEXT_STRING_HM_PID_TR "PID" +#define UI_TEXT_STRING_ACTION_TR "Eylem:%la" +#define UI_TEXT_HEATING_EXTRUDER_TR "Extruder Isiniyor" +#define UI_TEXT_HEATING_BED_TR "Bed Isiniyor" +#define UI_TEXT_KILLED_TR "DURDU" +#define UI_TEXT_STEPPER_DISABLED_TR "Motorlar Kapali" +#define UI_TEXT_EEPROM_STOREDA_TR "Konfigurasyon" +#define UI_TEXT_EEPROM_STOREDB_TR "EEPROM'a kaydedildi" +#define UI_TEXT_EEPROM_LOADEDA_TR "Konfigurasyon" +#define UI_TEXT_EEPROM_LOADEDB_TR "EEPROM'dan cagrildi" +#define UI_TEXT_UPLOADING_TR "Yukluyor..." +#define UI_TEXT_PAGE_BUFFER_TR "Onbellek:%oB" +#define UI_TEXT_PAGE_EXTRUDER_TR " E:%ec/%Ec" cDEG "C" cARROW "%oC" +#define UI_TEXT_PAGE_EXTRUDER1_TR "E1:%e0/%E0" cDEG "C" cARROW "%o0" +#define UI_TEXT_PAGE_EXTRUDER2_TR "E2:%e1/%E1" cDEG "C" cARROW "%o1" +#define UI_TEXT_PAGE_EXTRUDER3_TR "E3:%e2/%E2" cDEG "C" cARROW "%o2" +#define UI_TEXT_PAGE_BED_TR " B:%eb/%Eb" cDEG "C" cARROW "%ob" +#define UI_TEXT_SPEED_MULTIPLY_TR "Hiz Carp.:%om%%%" +#define UI_TEXT_FLOW_MULTIPLY_TR "Akis Carp. :%of%%%" +#define UI_TEXT_SHOW_MEASUREMENT_TR "Olcumu Goster" +#define UI_TEXT_RESET_MEASUREMENT_TR "Olcumu Sifirla" +#define UI_TEXT_SET_MEASURED_ORIGIN_TR "Z=0'a ayarla" +#define UI_TEXT_ZCALIB_TR "Z Kalib." +#define UI_TEXT_SET_P1_TR "Set P1" +#define UI_TEXT_SET_P2_TR "Set P2" +#define UI_TEXT_SET_P3_TR "Set P3" +#define UI_TEXT_CALCULATE_LEVELING_TR "Sevieyi Hesapla" +#define UI_TEXT_LEVEL_TR "Deltayi seviyele" +#define UI_TEXT_EXTR_WAIT_RETRACT_TEMP_TR "Bekle Sic. %XT" cDEG "C" +#define UI_TEXT_EXTR_WAIT_RETRACT_UNITS_TR "Bekle: %XU mm" +#define UI_TEXT_SD_REMOVED_TR "SD Card Cikarildi" +#define UI_TEXT_SD_INSERTED_TR "SD Card Takildi" +#define UI_TEXT_PRINTER_READY_TR "Yazici Hazir" +// Printtime output gets aggregated like UI_TEXT_PRINTTIME_DAYSUI_TEXT_PRINTTIME_HOURSUI_TEXT_PRINTTIME_MINUTES +// ___88 days 12:45 +#define UI_TEXT_PRINTTIME_DAYS_TR " gun " +#define UI_TEXT_PRINTTIME_HOURS_TR ":" +#define UI_TEXT_PRINTTIME_MINUTES_TR "" +#define UI_TEXT_PRINT_TIME_TR "Yazdirma Zamani" +#define UI_TEXT_PRINT_FILAMENT_TR "Filament harcandi" +#define UI_TEXT_PRINTED_TR "yazildi" +#define UI_TEXT_POWER_TR "ATX gucu on/off" +#define UI_TEXT_STRING_HM_DEADTIME_TR "Bosta Zaman" +#define UI_TEXT_STRING_HM_SLOWBANG_TR "SlowBang" +#define UI_TEXT_STOP_PRINT_TR "Yazdirmayi durdur" +#define UI_TEXT_Z_BABYSTEPPING_TR "Z Babystep.:%oYmm" +#define UI_TEXT_CHANGE_FILAMENT_TR "Filament degistir" +#define UI_TEXT_WIZ_CH_FILAMENT1_TR "Filament degistir" +#define UI_TEXT_WIZ_CH_FILAMENT2_TR "Filameti yukari asagi" +#define UI_TEXT_WIZ_CH_FILAMENT3_TR "almak icin cevirin" +#define UI_TEXT_CLICK_DONE_TR "Tamamlandiginda butona basin" +#define UI_TEXT_AUTOLEVEL_ONOFF_TR "Oto seviye: %ll" +#define UI_TEXT_SERVOPOS_TR "Servo pos.: %oS" +#define UI_TEXT_IGNORE_M106_TR "M106Yi atla %Fi" +#define UI_TEXT_WIZ_REHEAT1_TR "Extruderlari tekrar" +#define UI_TEXT_WIZ_REHEAT2_TR "isitmak icin tiklayin" +#define UI_TEXT_WIZ_WAITTEMP1_TR "Istnilen sicakliklar" +#define UI_TEXT_WIZ_WAITTEMP2_TR "icin bekleyin" +#define UI_TEXT_EXTRUDER_JAM_TR "Extruder takildi" +#define UI_TEXT_STANDBY_TR "Bekleme Modu" +#define UI_TEXT_BED_COATING_TR "Tabla ustu kaplama" +#define UI_TEXT_BED_COATING_SET1_TR "Kaplama Kalinligi" +#define UI_TEXT_BED_COATING_SET2_TR "" +#define UI_TEXT_NOCOATING_TR "Kaplama Yok" +#define UI_TEXT_BUILDTAK_TR "BuildTak" +#define UI_TEXT_KAPTON_TR "Kapton" +#define UI_TEXT_BLUETAPE_TR "Mavi Boya Kagidi" +#define UI_TEXT_PETTAPE_TR "Yesil PET Tape" +#define UI_TEXT_GLUESTICK_TR "Yapiskan" +#define UI_TEXT_CUSTOM_TR "Diger" +#define UI_TEXT_COATING_CUSTOM_TR "Diger : %oCmm" +#define UI_TEXT_LANGUAGE_TR "Dil" +#if NUM_EXTRUDER > 2 || MIXING_EXTRUDER != 0 +#define UI_TEXT_MAINPAGE6_1_TR "\xa %ec/%Ec\xb0 X:%x0" +#else +#define UI_TEXT_MAINPAGE6_1_TR "\xa %e0/%E0\xb0 X:%x0" +#endif // NUM_EXTRUDER +#if NUM_EXTRUDER == 2 && MIXING_EXTRUDER == 0 +#define UI_TEXT_MAINPAGE6_2_TR "\xa %e1/%E1\xb0 Y:%x1" +#elif HAVE_HEATED_BED +#define UI_TEXT_MAINPAGE6_2_TR "\xe %eb/%Eb\xb0 Y:%x1" +#else +#define UI_TEXT_MAINPAGE6_2_TR " Y:%x1" +#endif +#if HAVE_HEATED_BED && NUM_EXTRUDER == 2 && MIXING_EXTRUDER == 0 +#define UI_TEXT_MAINPAGE6_3_TR "\xe %eb/%Eb\xb0 Z:%x2" +#elif FEATURE_DITTO_PRINTING +#define UI_TEXT_MAINPAGE6_3_TR "Kopie: %ed Z:%x2" +#else +#define UI_TEXT_MAINPAGE6_3_TR "Przep:\xfd %of%%% Z:%x2" +#endif +#define UI_TEXT_MAINPAGE6_4_TR "Mul: %om%%% \xfd E: %x4m" +#define UI_TEXT_MAINPAGE6_5_TR "Buf: %oB" +#define UI_TEXT_MAINPAGE6_6_TR "%os" +#define UI_TEXT_MAINPAGE_TEMP_BED_TR cTEMP "%ec/%Ec" cDEG "B%eB/%Eb" cDEG +#define UI_TEXT_MAINPAGE_BED_TR "B%eB/%Eb" cDEG +#define UI_TEXT_MAINPAGE_Z_BUF_TR "Z:%x2 Buf : %oB" +#define UI_TEXT_MAINPAGE_MUL_EUSAGE_TR "Mul: %om E:%x4" +#define UI_TEXT_MAINPAGE_XY_TR "X:%x0 Y:%x1" +#define UI_TEXT_PRINT_TIME_VALUE_TR "%Ut" +#define UI_TEXT_PRINT_FILAMENT_VALUE_TR "%Uf m" +#define UI_TEXT_METER_PRINTED_TR "%Uf m " UI_TEXT_PRINTED_TR +#define UI_TEXT_STATUS_TR "%os" +#define UI_TEXT_EMPTY_TR "" +#define UI_TEXT_TEMP_SET_TR cTEMP "%ec/%Ec" cDEG +#define UI_TEXT_CURRENT_TEMP_TR cTEMP "%ec" cDEG +#define UI_TEXT_COATING_THICKNESS_TR " %oCmm" +#define UI_TEXT_EXTR3_TEMP_TR "Sic. 4 : %E3" cDEG "C" +#define UI_TEXT_EXTR4_TEMP_TR "Sic. 5 : %E4" cDEG "C" +#define UI_TEXT_EXTR5_TEMP_TR "Sic. 6 : %E5" cDEG "C" +#define UI_TEXT_EXTR3_OFF_TR "Ext. 4’u kapat" +#define UI_TEXT_EXTR4_OFF_TR " Ext. 5’i kapat " +#define UI_TEXT_EXTR5_OFF_TR " Ext. 6’yi kapat " +#define UI_TEXT_EXTR3_SELECT_TR "%X3 Ext. 4’u sec " +#define UI_TEXT_EXTR4_SELECT_TR "%X4 Ext. 5’i sec " +#define UI_TEXT_EXTR5_SELECT_TR "%X5 Ext. 6’yi sec " +#define UI_TEXT_DITTO_0_TR "%D0 Kopyalama" +#define UI_TEXT_DITTO_1_TR "%D1 1 kopya" +#define UI_TEXT_DITTO_2_TR "%D2 2 kopya" +#define UI_TEXT_DITTO_3_TR "%D3 3 kopya" +#define UI_TEXT_ZPROBE_HEIGHT_TR "Z-prob yuksekligi:%zh" +#define UI_TEXT_OFFSETS_TR "Set print offsets" +#define UI_TEXT_X_OFFSET_TR "Set X offset:%T0mm" +#define UI_TEXT_Y_OFFSET_TR "Set Y offset:%T1mm" +#define UI_TEXT_Z_OFFSET_TR "Set Z offset:%T2mm" + +// *************** Finnish translation **************** +// ********** By Matti Granstedt 28.01.2016 *********** + +#define UI_TEXT_ON_FI "P" STR_auml STR_auml "lle" +#define UI_TEXT_OFF_FI "Sammuta" +#define UI_TEXT_NA_FI "N/A" // Output for not available +#define UI_TEXT_YES_FI "Kyll" STR_auml "" +#define UI_TEXT_NO_FI "Ei" +#define UI_TEXT_PRINT_POS_FI "Tulostaa..." +#define UI_TEXT_PRINTING_FI "Tulosta" +#define UI_TEXT_IDLE_FI "Valmis" +#define UI_TEXT_NOSDCARD_FI "Ei SD korttia" +#define UI_TEXT_ERROR_FI "**** VIRHE ****" +#define UI_TEXT_BACK_FI "Takaisin" cUP +#define UI_TEXT_QUICK_SETTINGS_FI "Pika-asetukset" +#define UI_TEXT_ERRORMSG_FI "%oe" +#define UI_TEXT_CONFIGURATION_FI "Kokoonpano" +#define UI_TEXT_POSITION_FI "Paikka" +#define UI_TEXT_EXTRUDER_FI "Pursotin" +#define UI_TEXT_SD_CARD_FI "SD kortti" +#define UI_TEXT_DEBUGGING_FI "Virheenetsint" STR_auml "" +#define UI_TEXT_HOME_DELTA_FI "Koti delta" +#define UI_TEXT_HOME_ALL_FI "Koti kaikki" +#define UI_TEXT_HOME_X_FI "Koti X" +#define UI_TEXT_HOME_Y_FI "Koti Y" +#define UI_TEXT_HOME_Z_FI "Koti Z" +#define UI_TEXT_PREHEAT_PLA_FI "Esilämmitys PLA" +#define UI_TEXT_PREHEAT_ABS_FI "Esilämmitys ABS" +#define UI_TEXT_LIGHTS_ONOFF_FI "Valot:%lo" +#define UI_TEXT_COOLDOWN_FI "J" STR_auml STR_auml "hdytys" +#define UI_TEXT_SET_TO_ORIGIN_FI "Aseta l" STR_auml "ht" STR_ouml "piste" +#define UI_TEXT_DISABLE_STEPPER_FI "Sammuta moottori" +#define UI_TEXT_X_POSITION_FI "X Paikka" +#define UI_TEXT_X_POS_FAST_FI "X Paikka nopea" +#define UI_TEXT_Y_POSITION_FI "Y Paikka" +#define UI_TEXT_Y_POS_FAST_FI "Y Paikka nopea" +#define UI_TEXT_Z_POSITION_FI "Z Paikka" +#define UI_TEXT_Z_POS_FAST_FI "Z Paikka nopea" +#define UI_TEXT_E_POSITION_FI "Pursot. paikka" +#define UI_TEXT_BED_TEMP_FI "Alustan :%eb/%Eb" cDEG "C" +#define UI_TEXT_EXTR0_TEMP_FI "Purso 1 :%e0/%E0" cDEG "C" +#define UI_TEXT_EXTR1_TEMP_FI "Purso 2 :%e1/%E1" cDEG "C" +#define UI_TEXT_EXTR2_TEMP_FI "Purso 3 :%e2/%E2" cDEG "C" +#define UI_TEXT_EXTR0_OFF_FI "Pursotin 1 Ei" +#define UI_TEXT_EXTR1_OFF_FI "Pursotin 2 Ei" +#define UI_TEXT_EXTR2_OFF_FI "Pursotin 3 Ei" +#define UI_TEXT_EXTR0_SELECT_FI "%X0 Valitse purs.1" +#define UI_TEXT_EXTR1_SELECT_FI "%X1 Valitse purs.2" +#define UI_TEXT_EXTR2_SELECT_FI "%X2 Valitse purs.3" +#define UI_TEXT_EXTR_ORIGIN_FI "Aseta l" STR_auml "ht" STR_ouml "piste" +#define UI_TEXT_PRINT_X_FI "Tulosta X:%ax" +#define UI_TEXT_PRINT_Y_FI "Tulosta Y:%ay" +#define UI_TEXT_PRINT_Z_FI "Tulosta Z:%az" +#define UI_TEXT_PRINT_Z_DELTA_FI "Tulosta:%az" +#define UI_TEXT_MOVE_X_FI "Siirr" STR_auml "X :%aX" +#define UI_TEXT_MOVE_Y_FI "Siirr" STR_auml "Y :%aY" +#define UI_TEXT_MOVE_Z_FI "Siirr" STR_auml "Z :%aZ" +#define UI_TEXT_MOVE_Z_DELTA_FI "Siirr" STR_auml ":%aZ" +#define UI_TEXT_JERK_FI "Askel :%aj" +#define UI_TEXT_ZJERK_FI "Z-Askel :%aJ" +#define UI_TEXT_ACCELERATION_FI "Kiihtyvyys" +#define UI_TEXT_STORE_TO_EEPROM_FI "Tallenna EEPROM" +#define UI_TEXT_LOAD_EEPROM_FI "Lataa EEPROM" +#define UI_TEXT_DBG_ECHO_FI "Toista :%do" +#define UI_TEXT_DBG_INFO_FI "Tiedot :%di" +#define UI_TEXT_DBG_ERROR_FI "Virheet :%de" +#define UI_TEXT_DBG_DRYRUN_FI "Kuiva-ajo:%dd" +#define UI_TEXT_DBG_ENDSTOP_FI "EndStop :%dp" +#define UI_TEXT_OPS_OFF_FI "%O0 OPS ei" +#define UI_TEXT_OPS_CLASSIC_FI "%O1 OPS normaali" +#define UI_TEXT_OPS_FAST_FI "%O2 OPS nopea" +#define UI_TEXT_OPS_RETRACT_FI "Peruuta :%Or" +#define UI_TEXT_OPS_BACKSLASH_FI "Backsl. :%Ob" +#define UI_TEXT_OPS_MINDIST_FI "Min.dist :%Od" +#define UI_TEXT_OPS_MOVE_AFTER_FI "Siirr" STR_auml "j" STR_auml "lkeen:%Oa" +#define UI_TEXT_ANTI_OOZE_FI "Vuodon poisto" +#define UI_TEXT_PRINT_FILE_FI "Tulosta Tiedosto" +#define UI_TEXT_PAUSE_PRINT_FI "Tulostustauko" +#define UI_TEXT_CONTINUE_PRINT_FI "Jatka tulostusta" +#define UI_TEXT_UNMOUNT_CARD_FI "Kortti poistettu" +#define UI_TEXT_MOUNT_CARD_FI "Kortti asetettu" +#define UI_TEXT_DELETE_FILE_FI "Poista tiedosto" +#define UI_TEXT_FEEDRATE_FI "Sy" STR_ouml "tt" STR_ouml "nopeus" +#define UI_TEXT_FEED_MAX_X_FI "Maks. X:%fx" +#define UI_TEXT_FEED_MAX_Y_FI "Maks. Y:%fy" +#define UI_TEXT_FEED_MAX_Z_FI "Maks. Z:%fz" +#define UI_TEXT_FEED_MAX_Z_DELTA_FI "Maks.:%fz" +#define UI_TEXT_FEED_HOME_X_FI "Koti X:%fX" +#define UI_TEXT_FEED_HOME_Y_FI "Koti Y:%fY" +#define UI_TEXT_FEED_HOME_Z_FI "Koti Z:%fZ" +#define UI_TEXT_FEED_HOME_Z_DELTA_FI "Koti:%fZ" +#define UI_TEXT_ACTION_XPOSITION4A_FI "X:%x0 mm %dx%dX" +#define UI_TEXT_ACTION_XPOSITION4B_FI "Min. rajoittimesta:%sx" +#define UI_TEXT_ACTION_XPOSITION4C_FI "Maks rajoittimesta:%sX" +#define UI_TEXT_ACTION_XPOSITION4D_FI "" +#define UI_TEXT_ACTION_YPOSITION4A_FI "Y:%x1 mm %dy%dY" +#define UI_TEXT_ACTION_YPOSITION4B_FI "Min. rajoittimesta:%sy" +#define UI_TEXT_ACTION_YPOSITION4C_FI "Maks rajoittimesta:%sY" +#define UI_TEXT_ACTION_YPOSITION4D_FI "" +#define UI_TEXT_ACTION_ZPOSITION4A_FI "Z:%x2 mm %dz%dZ" +#define UI_TEXT_ACTION_ZPOSITION4B_FI "Min. rajoittimesta:%sz" +#define UI_TEXT_ACTION_ZPOSITION4C_FI "Maks rajoittimesta:%sZ" +#define UI_TEXT_ACTION_ZPOSITION4D_FI "" +#define UI_TEXT_ACTION_XPOSITION_FAST4A_FI "X:%x0 mm" +#define UI_TEXT_ACTION_XPOSITION_FAST4B_FI "Min. rajoittimesta:%sx" +#define UI_TEXT_ACTION_XPOSITION_FAST4C_FI "Maks rajoittimesta:%sX" +#define UI_TEXT_ACTION_XPOSITION_FAST4D_FI "" +#define UI_TEXT_ACTION_YPOSITION_FAST4A_FI "Y:%x1 mm" +#define UI_TEXT_ACTION_YPOSITION_FAST4B_FI "Min. rajoittimesta:%sy" +#define UI_TEXT_ACTION_YPOSITION_FAST4C_FI "Maks rajoittimesta:%sY" +#define UI_TEXT_ACTION_YPOSITION_FAST4D_FI "" +#define UI_TEXT_ACTION_ZPOSITION_FAST4A_FI "Z:%x2 mm" +#define UI_TEXT_ACTION_ZPOSITION_FAST4B_FI "Min. rajoittimesta:%sz" +#define UI_TEXT_ACTION_ZPOSITION_FAST4C_FI "Maks rajoittimesta:%sZ" +#define UI_TEXT_ACTION_ZPOSITION_FAST4D_FI "" +#define UI_TEXT_ACTION_EPOSITION_FAST2A_FI "E:%x3 mm" +#define UI_TEXT_ACTION_EPOSITION_FAST2B_FI "1 klikkaus = 1 mm" +#define UI_TEXT_ACTION_XPOSITION2A_FI "X:%x0 mm" +#define UI_TEXT_ACTION_XPOSITION2B_FI "Min:%sx Max:%sX" +#define UI_TEXT_ACTION_YPOSITION2A_FI "Y:%x1 mm" +#define UI_TEXT_ACTION_YPOSITION2B_FI "Min:%sy Max:%sY" +#define UI_TEXT_ACTION_ZPOSITION2A_FI "Z:%x2 mm" +#define UI_TEXT_ACTION_ZPOSITION2B_FI "Min:%sz Max:%sZ" +#define UI_TEXT_ACTION_XPOSITION_FAST2A_FI "X:%x0 mm" +#define UI_TEXT_ACTION_XPOSITION_FAST2B_FI "Min:%sx Max:%sX" +#define UI_TEXT_ACTION_YPOSITION_FAST2A_FI "Y:%x1 mm" +#define UI_TEXT_ACTION_YPOSITION_FAST2B_FI "Min:%sy Max:%sY" +#define UI_TEXT_ACTION_ZPOSITION_FAST2A_FI "Z:%x2 mm" +#define UI_TEXT_ACTION_ZPOSITION_FAST2B_FI "Min:%sz Max:%sZ" +#define UI_TEXT_FANSPEED_FI "Tuulettimen nopeus" +#define UI_TEXT_ACTION_FANSPEED_FI "Tuuletin nopeus:%Fs%%%" +#define UI_TEXT_FAN_OFF_FI "Sammuta tuuletin" +#define UI_TEXT_FAN_25_FI "Aseta nop. 25%%%" +#define UI_TEXT_FAN_50_FI "Aseta nop. 50%%%" +#define UI_TEXT_FAN_75_FI "Aseta nop. 75%%%" +#define UI_TEXT_FAN_FULL_FI "Aseta nop. maks." +#define UI_TEXT_STEPPER_INACTIVE_FI "Moottori toimeton" +#define UI_TEXT_STEPPER_INACTIVE2A_FI "Toimeton j" STR_auml "lkeen: %is" +#define UI_TEXT_STEPPER_INACTIVE2B_FI "[min] 0=sammuta" +#define UI_TEXT_POWER_INACTIVE_FI "Maks. toimeton" +#define UI_TEXT_POWER_INACTIVE2A_FI "Toimeton j" STR_auml "lkeen: %ip" +#define UI_TEXT_POWER_INACTIVE2B_FI "[min] 0=sammuta" +#define UI_TEXT_GENERAL_FI "Yleiset" +#define UI_TEXT_BAUDRATE_FI "Siirtonopeus:%oc" +#define UI_TEXT_EXTR_STEPS_FI "Askelta/MM:%Se" +#define UI_TEXT_EXTR_START_FEED_FI "K" STR_auml "ynnist" STR_auml "FR:%Xf" +#define UI_TEXT_EXTR_MAX_FEED_FI "Maks. FR:%XF" +#define UI_TEXT_EXTR_ACCEL_FI "Kiihdytys:%XA" +#define UI_TEXT_EXTR_WATCH_FI "Stab.Aika:%Xw" +#define UI_TEXT_EXTR_ADVANCE_L_FI "Eteneminen lin:%Xl" +#define UI_TEXT_EXTR_ADVANCE_K_FI "Eteneminen quad:%Xa" +#define UI_TEXT_EXTR_MANAGER_FI "Hallinta:%Xh" +#define UI_TEXT_EXTR_PGAIN_FI "PID P:%Xp" +#define UI_TEXT_EXTR_DEADTIME_FI "Kuollut aika:%Xp" +#define UI_TEXT_EXTR_DMAX_DT_FI "Valvonta PWM:%XM" +#define UI_TEXT_EXTR_IGAIN_FI "PID I:%Xi" +#define UI_TEXT_EXTR_DGAIN_FI "PID D:%Xd" +#define UI_TEXT_EXTR_DMIN_FI "Ajo Min:%Xm" +#define UI_TEXT_EXTR_DMAX_FI "Ajo Max:%XM" +#define UI_TEXT_EXTR_PMAX_FI "PID Max:%XD" +#define UI_TEXT_EXTR_XOFF_FI "X-tasoitus:%Xx" +#define UI_TEXT_EXTR_YOFF_FI "Y-tasoitus:%Xy" +#define UI_TEXT_STRING_HM_BANGBANG_FI "BangBang" +#define UI_TEXT_STRING_HM_PID_FI "PID" +#define UI_TEXT_STRING_ACTION_FI "Toiminta:%la" +#define UI_TEXT_HEATING_EXTRUDER_FI "Kuumentaa Pursot." +#define UI_TEXT_HEATING_BED_FI "Kuumentaa Alustaa" +#define UI_TEXT_KILLED_FI "Poistettu" +#define UI_TEXT_STEPPER_DISABLED_FI "Moottori pois k" STR_auml "yt." +#define UI_TEXT_EEPROM_STOREDA_FI "Kokoonpano" +#define UI_TEXT_EEPROM_STOREDB_FI "Tallennettu EEPROM" +#define UI_TEXT_EEPROM_LOADEDA_FI "Kokoonpano" +#define UI_TEXT_EEPROM_LOADEDB_FI "Ladattu EEPROM" +#define UI_TEXT_UPLOADING_FI "Ladataan..." +#define UI_TEXT_PAGE_BUFFER_FI "Puskuri:%oB" +#define UI_TEXT_PAGE_EXTRUDER_FI " E:%ec/%Ec" cDEG "C" cARROW "%oC" +#define UI_TEXT_PAGE_EXTRUDER1_FI "E1:%e0/%E0" cDEG "C" cARROW "%o0" +#define UI_TEXT_PAGE_EXTRUDER2_FI "E2:%e1/%E1" cDEG "C" cARROW "%o1" +#define UI_TEXT_PAGE_EXTRUDER3_FI "E3:%e2/%E2" cDEG "C" cARROW "%o2" +#define UI_TEXT_PAGE_BED_FI " B:%eb/%Eb" cDEG "C" cARROW "%ob" +#define UI_TEXT_SPEED_MULTIPLY_FI "Nopeuskerroin:%om%%%" +#define UI_TEXT_FLOW_MULTIPLY_FI "Puhalluskerroin:%of%%%" +#define UI_TEXT_SHOW_MEASUREMENT_FI "N" STR_auml "yt" STR_auml " mitat" +#define UI_TEXT_RESET_MEASUREMENT_FI "Poista mitat." +#define UI_TEXT_SET_MEASURED_ORIGIN_FI "Aseta Z=0" +#define UI_TEXT_ZCALIB_FI "Z kalibrointi" +#define UI_TEXT_SET_P1_FI "Aseta P1" +#define UI_TEXT_SET_P2_FI "Aseta P2" +#define UI_TEXT_SET_P3_FI "Aseta P3" +#define UI_TEXT_CALCULATE_LEVELING_FI "Laske tasot" +#define UI_TEXT_LEVEL_FI "Taso delta" +#define UI_TEXT_EXTR_WAIT_RETRACT_TEMP_FI "Odottaa l" STR_auml "mm. %XT" cDEG "C" +#define UI_TEXT_EXTR_WAIT_RETRACT_UNITS_FI "Odottaa yks.:%XU mm" +#define UI_TEXT_SD_REMOVED_FI "SD kortti pois" +#define UI_TEXT_SD_INSERTED_FI "SD kortti on" +#define UI_TEXT_PRINTER_READY_FI "Tulostin valmis." +// Printtime output gets aggregated like UI_TEXT_PRINTTIME_DAYSUI_TEXT_PRINTTIME_HOURSUI_TEXT_PRINTTIME_MINUTES +// ___88 days 12:45 +#define UI_TEXT_PRINTTIME_DAYS_FI " p" STR_auml "iv" STR_auml STR_auml " " +#define UI_TEXT_PRINTTIME_HOURS_FI ":" +#define UI_TEXT_PRINTTIME_MINUTES_FI "" +#define UI_TEXT_PRINT_TIME_FI "Tulostusaika" +#define UI_TEXT_PRINT_FILAMENT_FI "Lanka tulostettu" +#define UI_TEXT_PRINTED_FI "Tulostettu" +#define UI_TEXT_POWER_FI "ATX virtal. on/ei" +#define UI_TEXT_STRING_HM_DEADTIME_FI "Joutoaika" +#define UI_TEXT_STRING_HM_SLOWBANG_FI "SlowBang" +#define UI_TEXT_STOP_PRINT_FI "Lopeta tulostus" +#define UI_TEXT_Z_BABYSTEPPING_FI "Z mikroaskellus:%oYmm" +#define UI_TEXT_CHANGE_FILAMENT_FI "Vaihda tulostuslanka" +#define UI_TEXT_WIZ_CH_FILAMENT1_FI "Vaihda tulostuslanka" +#define UI_TEXT_WIZ_CH_FILAMENT2_FI "Py" STR_ouml "rit" STR_auml " siirr" STR_auml "" +#define UI_TEXT_WIZ_CH_FILAMENT3_FI "Tul.lanka yl" STR_ouml "s/alas" +#define UI_TEXT_CLICK_DONE_FI "Klik kun valmis" +#define UI_TEXT_AUTOLEVEL_ONOFF_FI "Autom.taso: %ll" +#define UI_TEXT_SERVOPOS_FI "Servo paikka: %oS" +#define UI_TEXT_IGNORE_M106_FI "Ohita M106 %Fi" +#define UI_TEXT_WIZ_REHEAT1_FI "Klik uusi kuumennus" +#define UI_TEXT_WIZ_REHEAT2_FI "pursottimet" +#define UI_TEXT_WIZ_WAITTEMP1_FI "Odottaa tavoitetta" +#define UI_TEXT_WIZ_WAITTEMP2_FI "l" STR_auml "mp" STR_ouml "tilat..." +#define UI_TEXT_EXTRUDER_JAM_FI "Pursottimen tukos" +#define UI_TEXT_STANDBY_FI "Valmiina" +#define UI_TEXT_BED_COATING_FI "Alustan pinnote" +#define UI_TEXT_BED_COATING_SET1_FI "Alustan pinta valittu" +#define UI_TEXT_BED_COATING_SET2_FI "" +#define UI_TEXT_NOCOATING_FI "Ei pinnotetta" +#define UI_TEXT_BUILDTAK_FI "BuildTak" +#define UI_TEXT_KAPTON_FI "Kapton" +#define UI_TEXT_BLUETAPE_FI "Sininen paperi teippi" +#define UI_TEXT_PETTAPE_FI "Vihreä PET teippi" +#define UI_TEXT_GLUESTICK_FI "Liimapuikko" +#define UI_TEXT_CUSTOM_FI "Mukautettu" +#define UI_TEXT_COATING_CUSTOM_FI "Mukautettu:%BCmm" +#define UI_TEXT_LANGUAGE_FI "Kieli" + +#if NUM_EXTRUDER > 2 || MIXING_EXTRUDER != 0 +#define UI_TEXT_MAINPAGE6_1_FI "\xa %ec/%Ec\xb0 X:%x0" +#else +#define UI_TEXT_MAINPAGE6_1_FI "\xa %e0/%E0\xb0 X:%x0" +#endif // NUM_EXTRUDER +#if NUM_EXTRUDER == 2 && MIXING_EXTRUDER == 0 +#define UI_TEXT_MAINPAGE6_2_FI "\xa %e1/%E1\xb0 Y:%x1" +#elif HAVE_HEATED_BED +#define UI_TEXT_MAINPAGE6_2_FI "\xe %eb/%Eb\xb0 Y:%x1" +#else +#define UI_TEXT_MAINPAGE6_2_FI " Y:%x1" +#endif +#if HAVE_HEATED_BED && NUM_EXTRUDER == 2 && MIXING_EXTRUDER == 0 +#define UI_TEXT_MAINPAGE6_3_FI "\xe %eb/%Eb\xb0 Z:%x2" +#elif FEATURE_DITTO_PRINTING +#define UI_TEXT_MAINPAGE6_3_FI "Kopiot: %ed Z:%x2" +#else +#define UI_TEXT_MAINPAGE6_3_FI "Virtaus:\xfd %of%%% Z:%x2" +#endif +#define UI_TEXT_MAINPAGE6_4_FI "Mul: %om%%% \xfd E: %x4m" +#define UI_TEXT_MAINPAGE6_5_FI "Buf: %oB" +#define UI_TEXT_MAINPAGE6_6_FI "%os" +#define UI_TEXT_MAINPAGE_TEMP_BED_FI cTEMP "%ec/%Ec" cDEG "B%eB/%Eb" cDEG +#define UI_TEXT_MAINPAGE_BED_FI "B%eB/%Eb" cDEG +#define UI_TEXT_MAINPAGE_Z_BUF_FI "Z:%x2 Buf : %oB" +#define UI_TEXT_MAINPAGE_MUL_EUSAGE_FI "Mul: %om E:%x4" +#define UI_TEXT_MAINPAGE_XY_FI "X:%x0 Y:%x1" +#define UI_TEXT_PRINT_TIME_VALUE_FI "%Ut" +#define UI_TEXT_PRINT_FILAMENT_VALUE_FI "%Uf m" +#define UI_TEXT_METER_PRINTED_FI "%Uf m " UI_TEXT_PRINTED_FI +#define UI_TEXT_STATUS_FI "%os" +#define UI_TEXT_EMPTY_FI "" +#define UI_TEXT_TEMP_SET_FI cTEMP "%ec/%Ec" cDEG +#define UI_TEXT_CURRENT_TEMP_FI cTEMP "%ec" cDEG +#define UI_TEXT_COATING_THICKNESS_FI " %BCmm" +#define UI_TEXT_EXTR3_TEMP_FI "L" STR_auml "mp" STR_ouml " 4 :%e3/%E3" cDEG "C" +#define UI_TEXT_EXTR4_TEMP_FI "L" STR_auml "mp" STR_ouml " 5 :%e4/%E4" cDEG "C" +#define UI_TEXT_EXTR5_TEMP_FI "L" STR_auml "mp" STR_ouml " 6 :%e5/%E5" cDEG "C" +#define UI_TEXT_EXTR3_OFF_FI "Pursotin 4 ei" +#define UI_TEXT_EXTR4_OFF_FI "Pursotin 5 ei" +#define UI_TEXT_EXTR5_OFF_FI "Pursotin 6 ei" +#define UI_TEXT_EXTR3_SELECT_FI "%X3 Valitse purs. 4" +#define UI_TEXT_EXTR4_SELECT_FI "%X4 Valitse purs. 5" +#define UI_TEXT_EXTR5_SELECT_FI "%X5 Valitse purs. 6" +#define UI_TEXT_DITTO_0_FI "%D0 Ei kopiota" +#define UI_TEXT_DITTO_1_FI "%D1 1 kopio" +#define UI_TEXT_DITTO_2_FI "%D2 2 kopiota" +#define UI_TEXT_DITTO_3_FI "%D3 3 kopiota" +#define UI_TEXT_ZPROBE_HEIGHT_FI "Z-anturin korkeus:%zh" + +#define UI_TEXT_OFFSETS_FI "Aseta tulostimen poikkeamat" +#define UI_TEXT_X_OFFSET_FI "Aseta X poikkeama:%T0mm" +#define UI_TEXT_Y_OFFSET_FI "Aseta Y poikkeama:%T1mm" +#define UI_TEXT_Z_OFFSET_FI "Aseta Z poikkeama:%T2mm" diff --git a/trunk/Arduino/Repetier_0.92.9/uimenu.h b/trunk/Arduino/Repetier_0.92.9/uimenu.h new file mode 100644 index 00000000..0c8677e4 --- /dev/null +++ b/trunk/Arduino/Repetier_0.92.9/uimenu.h @@ -0,0 +1,1097 @@ +/* + This file is part of Repetier-Firmware. + + Repetier-Firmware is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Repetier-Firmware is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Repetier-Firmware. If not, see . + +*/ +#if !defined(_UI_MENU_H) +#define _UI_MENU_H + +/*moved to uilang.h + #define cUP "\001" + #define cDEG "\002" + #define cSEL "\003" + #define cUNSEL "\004" + #define cTEMP "\005" + #define cFOLD "\006" + #define cARROW "\176" +*/ +/* + The menu configuration uses dynamic strings. These dynamic strings can contain + a placeholder for special values. During print these placeholder are exchanged + by their current value. Everything else is printed exactly as written. + + A placeholder always has 3 chars. It starts with a % followed by 2 characters + defining the value. You can use any placeholder in any position, also it doesn't + always make sense. + + Special Characters + constant description + cUP Folder up arrow + cDEG Degree mark + cSEL Selected + cUNSEL Unselected + cTEMP Thermometer symbol + cFOLD Folder symbol + + List of placeholder: + %%% : The % char + %% : The % char (also) + + %? : Conditional. Print c if current char is not c. Allows avoiding duplicate character, like space + + acceleration + %ax : X acceleration during print moves + %ay : Y acceleration during print moves + %az : Z acceleration during print moves + %aX : X acceleration during travel moves + %aY : Y acceleration during travel moves + %aZ : Z acceleration during travel moves + %aj : Max. jerk + %aJ : Max. Z-jerk + + debug + %do : Debug echo state. + %di : Debug info state. + %de : Debug error state. + %dd : Debug dry run state. + %dp : Debug end stop state. + endstop stats with only one char + %dx : Debug min x endstop + %dX : Debug max x endstop + %dy : Debug min y endstop + %dY : Debug max y endstop + %dz : Debug min z endstop + %dZ : Debug max z endstop + + extruder + %ec : Current extruder temperature + %ed : Number of copies for ditto mode + %eIc : Current extruder temperature integer (shorter) + %eb : Current heated bed temperature + %e0..9 : Temp. of extruder 0..9 + %er : Extruder relative mode + %Ec : Target temperature of current extruder + %Eb : Target temperature of heated bed + %E0-9 : Target temperature of extruder 0..9 + %D0-3 : Ditto mode selected + feed rate + %fx : Max. feedrate x direction + %fy : Max. feedrate y direction + %fz : Max. feedrate z direction + %fe : Max. feedrate current extruder + %fX : Homing feedrate x direction + %fY : Homing feedrate y direction + %fZ : Homing feedrate z direction + %Fs : Fan speed + %Fi : ignore M106 commands state + + inactivity + %is : Stepper inactive time in minutes + %ip : Max. inactive time in minutes + + random stuff + %os : Status message + %oe : Error message + %oB : Buffer length + %om : Speed multiplier + %of : flow multiplier + %oc : Connection baudrate + %o0..9 : Output level extruder 0..9 is % including %sign. + %oC : Output level current extruder + %ob : Output level heated bed + %PN : Printer name + %on : current extruder number (1,2,3...) + %oS : servo position + %oY : babysteps counter + %BC : Bed coating thickness + + stops + %sx : State of x min endstop. + %sX : State of x max endstop. + %sy : State of y min endstop. + %sY : State of y max endstop. + %sz : State of z min endstop. + %sZ : State of z max endstop. + + steps + %Sx : Steps per mm x direction + %Sy : Steps per mm y direction + %Sz : Steps per mm z direction + %Se : Steps per mm current extruder + + totals + %Ut : Shows printing time + %Uf : Shows total filament usage + + extruder position + %x0 : X position + %x1 : Y position + %x2 : Z position + %x3 : Current extruder position + %x4 : Printed since temperature on in meters (for filament usage) + + Print offsets + %T0 : X offset + %T1 : Y offset + %T2 : Z offset + + extruder parameters + %X0..9 : Extruder selected marker + %Xi : PID I gain + %Xp : PID P gain + %Xd : PID D gain + %Xm : PID drive min + %XM : PID drive max + %XD : PID max + %Xw : Extruder watch period in seconds + %Xh : Extruder heat manager (BangBang/PID) + %Xa : Advance K value + %Xl : Advance L value + %Xx : x offset in steps + %Xy : y offset in steps + %Xf : Extruder max. start feedrate + %XF : Extruder max. feedrate + %XA : Extruder max. acceleration + + delta stuff + %y0-3 : same as %y0-3 back calculated from delta position steps + %Y0-3 : raw delta position steps (no round off error to display it) + %yD : delta printer low tower distance + %YL : delta print envelope radius Limit + %yx : low towers x offset mm + %yy : low towers y offset mm + %Yx : low towers x offset steps + %Yy : low towers y offset steps + %yX : high (Z) tower x offset mm + %yY : high (Z) tower y offset mm + %YX : high (Z) tower x offset steps + %YY : high (Z) tower y offset steps + + Z-Probing + %zh : z-probe height +*/ + +#if UI_DISPLAY_TYPE != NO_DISPLAY + + +// Define precision for temperatures. With small displays only integer values fit. +#ifndef UI_TEMP_PRECISION +#if UI_COLS>16 +#define UI_TEMP_PRECISION 1 +#else +#define UI_TEMP_PRECISION 0 +#endif +#endif + +/* ============= PAGES DEFINITION ============= + + If you are not iside a menu, the firmware displays pages with information. + Especially if you have only a small display it is convenient to have + more then one information page. +*/ + +/* Define your pages using dynamic strings. To define a page use + UI_PAGE6(name,row1,row2,row3,row4,row5,row6); + UI_PAGE4(name,row1,row2,row3,row4); + for 4 row displays and + UI_PAGE2(name,row1,row2); + for 2 row displays. You can add additional pages or change the default pages like you want. +*/ + +#if UI_ROWS>=6 && UI_DISPLAY_TYPE == DISPLAY_U8G + +//graphic main status + +UI_PAGE6_T(ui_page1, UI_TEXT_MAINPAGE6_1_ID, UI_TEXT_MAINPAGE6_2_ID, UI_TEXT_MAINPAGE6_3_ID, UI_TEXT_MAINPAGE6_4_ID, UI_TEXT_MAINPAGE6_5_ID, UI_TEXT_MAINPAGE6_6_ID) + +#if EEPROM_MODE != 0 +UI_PAGE4_T(ui_page2, UI_TEXT_PRINT_TIME_ID, UI_TEXT_PRINT_TIME_VALUE_ID, UI_TEXT_PRINT_FILAMENT_ID, UI_TEXT_PRINT_FILAMENT_VALUE_ID) +#define UI_PRINTTIME_PAGES ,&ui_page2 +#define UI_PRINTTIME_COUNT 1 +#else +#define UI_PRINTTIME_PAGES +#define UI_PRINTTIME_COUNT 0 +#endif + +#if NUM_EXTRUDER > 2 && MIXING_EXTRUDER == 0 +UI_PAGE6_T(ui_page3, UI_TEXT_EXTR0_TEMP_ID, UI_TEXT_EXTR1_TEMP_ID, UI_TEXT_EXTR2_TEMP_ID, +#if NUM_EXTRUDER > 3 + UI_TEXT_EXTR3_TEMP_ID, +#else + UI_TEXT_EMPTY_ID, +#endif +#if NUM_EXTRUDER > 4 + UI_TEXT_EXTR4_TEMP_ID, +#elif HAVE_HEATED_BED + UI_TEXT_BED_TEMP_ID, +#else + UI_TEXT_EMPTY_ID, +#endif + UI_TEXT_STATUS_ID) +#define UI_EXTRUDERS_PAGES ,&ui_page3 +#define UI_EXTRUDERS_PAGES_COUNT 1 +#else +#define UI_EXTRUDERS_PAGES +#define UI_EXTRUDERS_PAGES_COUNT 0 +#endif +/* + Merge pages together. Use the following pattern: + #define UI_PAGES {&name1,&name2,&name3} +*/ +#define UI_PAGES {&ui_page1 UI_PRINTTIME_PAGES UI_EXTRUDERS_PAGES} +// How many pages do you want to have. Minimum is 1. +#define UI_NUM_PAGES 1+UI_PRINTTIME_COUNT+UI_EXTRUDERS_PAGES_COUNT + +#elif UI_ROWS >= 4 +#if HAVE_HEATED_BED +#if NUM_EXTRUDER > 0 +// UI_PAGE4(ui_page1,cTEMP "%ec/%Ec" cDEG "B%eB/%Eb" cDEG,"Z:%x2 Buf : %oB","Mul: %om Flow: %of","%os") +UI_PAGE4_T(ui_page1, UI_TEXT_MAINPAGE_TEMP_BED_ID, UI_TEXT_MAINPAGE_Z_BUF_ID, UI_TEXT_MAINPAGE_MUL_EUSAGE_ID, UI_TEXT_STATUS_ID) +#else +// UI_PAGE4(ui_page1,"B%eB/%Eb" cDEG,"Z:%x2 Buf : %oB","Mul: %om Flow: %of","%os") +UI_PAGE4_T(ui_page1, UI_TEXT_MAINPAGE_BED_ID, UI_TEXT_MAINPAGE_Z_BUF_ID, UI_TEXT_MAINPAGE_MUL_EUSAGE_ID, UI_TEXT_STATUS_ID) +#endif +//UI_PAGE4(ui_page1,UI_TEXT_PAGE_EXTRUDER,UI_TEXT_PAGE_BED,UI_TEXT_PAGE_BUFFER,"%os"); +#else +#if NUM_EXTRUDER > 0 +UI_PAGE4_T(ui_page1, UI_TEXT_PAGE_EXTRUDER_ID, UI_TEXT_ACTION_ZPOSITION4A_ID, UI_TEXT_PAGE_BUFFER_ID, UI_TEXT_STATUS_ID) +#else +UI_PAGE4_T(ui_page1, UI_TEXT_EMPTY_ID, UI_TEXT_ACTION_ZPOSITION4A_ID, UI_TEXT_PAGE_BUFFER_ID, UI_TEXT_STATUS_ID) +#endif +#endif +UI_PAGE4_T(ui_page2, UI_TEXT_ACTION_XPOSITION4A_ID, UI_TEXT_ACTION_YPOSITION4A_ID, UI_TEXT_ACTION_ZPOSITION4A_ID, UI_TEXT_STATUS_ID) +//UI_PAGE4(ui_page2,"dX:%y0 mm %sX","dY:%y1 mm %sY","dZ:%y2 mm %sZ","%os"); +#if NUM_EXTRUDER > 0 +UI_PAGE4_T(ui_page3, UI_TEXT_PAGE_EXTRUDER1_ID +#else +UI_PAGE4_T(ui_page3 +#endif +#if NUM_EXTRUDER > 1 && MIXING_EXTRUDER == 0 + , UI_TEXT_PAGE_EXTRUDER2_ID +#endif +#if NUM_EXTRUDER>2 && MIXING_EXTRUDER == 0 + , UI_TEXT_PAGE_EXTRUDER3_ID +#endif +#if HAVE_HEATED_BED + , UI_TEXT_PAGE_BED_ID +#endif +#if (NUM_EXTRUDER >= 3 && MIXING_EXTRUDER == 0 && !HAVE_HEATED_BED) || (NUM_EXTRUDER==2 && MIXING_EXTRUDER == 0 && HAVE_HEATED_BED==true) + , UI_TEXT_STATUS_ID +#elif (NUM_EXTRUDER == 2 && MIXING_EXTRUDER == 0) || ((NUM_EXTRUDER == 1 || MIXING_EXTRUDER == 1) && HAVE_HEATED_BED) + , UI_TEXT_EMPTY_ID, UI_TEXT_STATUS_ID +#elif (NUM_EXTRUDER == 1 || MIXING_EXTRUDER == 1) || (NUM_EXTRUDER == 0 && HAVE_HEATED_BED) + , UI_TEXT_EMPTY_ID, UI_TEXT_EMPTY_ID, UI_TEXT_STATUS_ID +#elif NUM_EXTRUDER == 0 + , UI_TEXT_EMPTY_ID, UI_TEXT_EMPTY_ID, UI_TEXT_EMPTY_ID, UI_TEXT_STATUS_ID +#endif + ) +#if EEPROM_MODE != 0 +UI_PAGE4_T(ui_page4, UI_TEXT_PRINT_TIME_ID, UI_TEXT_PRINT_TIME_VALUE_ID, UI_TEXT_PRINT_FILAMENT_ID, UI_TEXT_PRINT_FILAMENT_VALUE_ID) +#define UI_PRINTTIME_PAGES ,&ui_page4 +#define UI_PRINTTIME_COUNT 1 +#else +#define UI_PRINTTIME_PAGES +#define UI_PRINTTIME_COUNT 0 +#endif +/* + Merge pages together. Use the following pattern: + #define UI_PAGES {&name1,&name2,&name3} +*/ +#define UI_PAGES {&ui_page1, &ui_page2, &ui_page3 UI_PRINTTIME_PAGES} +// How many pages do you want to have. Minimum is 1. +#define UI_NUM_PAGES 3+UI_PRINTTIME_COUNT +#else +#if HAVE_HEATED_BED +UI_PAGE2_T(ui_page1, UI_TEXT_PAGE_EXTRUDER_ID, UI_TEXT_PAGE_BED_ID) +#else +UI_PAGE2_T(ui_page1, UI_TEXT_PAGE_EXTRUDER_ID, UI_TEXT_STATUS_ID) +#endif +UI_PAGE2_T(ui_page2, UI_TEXT_MAINPAGE_XY_ID, UI_TEXT_STATUS_ID) +UI_PAGE2_T(ui_page3, UI_TEXT_ACTION_ZPOSITION4A_DE, UI_TEXT_STATUS_ID) +/* + Merge pages together. Use the following pattern: + #define UI_PAGES {&name1,&name2,&name3} +*/ +#define UI_PAGES {&ui_page1,&ui_page2,&ui_page3} +// How many pages do you want to have. Minimum is 1. +#define UI_NUM_PAGES 3 +#endif + +/* ============ MENU definition ================ + + The menu works the same as pages. In addion you need to define what the lines do + or where to jump to. For that reason, the menu structure needs to be entered in + reverse order. Starting from the leaves, the menu structure is defined. +*/ + +/* + At first define all actions available in the menu. The actions define, what the + next/previous button will do. All menu actions work the same: + next/previous changes the value + ok sets the value if not already done and goes back to previous menu. +*/ + +UI_MENU_ACTIONCOMMAND_T(ui_menu_back, UI_TEXT_BACK_ID, UI_ACTION_BACK) +#if UI_HAS_BACK_KEY == 0 +#define UI_MENU_ADDCONDBACK &ui_menu_back, +#define UI_MENU_BACKCNT 1 +#else +#define UI_MENU_ADDCONDBACK +#define UI_MENU_BACKCNT 0 +#endif + + +// Language selection menu + +#if EEPROM_MODE != 0 +#define FIRSTLANG 1 +#if LANGUAGE_EN_ACTIVE +UI_MENU_ACTIONCOMMAND(ui_menu_setlang_en, "English", UI_ACTION_LANGUAGE_EN | UI_ACTION_TOPMENU) +#define ADD_LANG_EN &ui_menu_setlang_en +#undef FIRSTLANG +#define FIRSTLANG 0 +#else +#define ADD_LANG_EN +#endif // LANGUAGE_EN_ACTIVE +#if LANGUAGE_DE_ACTIVE +UI_MENU_ACTIONCOMMAND(ui_menu_setlang_de, "Deutsch", UI_ACTION_LANGUAGE_DE | UI_ACTION_TOPMENU) +#if FIRSTLANG +#define ADD_LANG_DE &ui_menu_setlang_de +#undef FIRSTLANG +#define FIRSTLANG 0 +#else +#define ADD_LANG_DE ,&ui_menu_setlang_de +#endif +#else +#define ADD_LANG_DE +#endif // LANGUAGE_DE_ACTIVE +#if LANGUAGE_ES_ACTIVE +UI_MENU_ACTIONCOMMAND(ui_menu_setlang_es, "Espanol", UI_ACTION_LANGUAGE_ES | UI_ACTION_TOPMENU) +#if FIRSTLANG +#define ADD_LANG_ES &ui_menu_setlang_es +#undef FIRSTLANG +#define FIRSTLANG 0 +#else +#define ADD_LANG_ES ,&ui_menu_setlang_es +#endif +#else +#define ADD_LANG_ES +#endif // LANGUAGE_ES_ACTIVE +#if LANGUAGE_PT_ACTIVE +UI_MENU_ACTIONCOMMAND(ui_menu_setlang_pt, "Portugues", UI_ACTION_LANGUAGE_PT | UI_ACTION_TOPMENU) +#if FIRSTLANG +#define ADD_LANG_PT &ui_menu_setlang_pt +#undef FIRSTLANG +#define FIRSTLANG 0 +#else +#define ADD_LANG_PT ,&ui_menu_setlang_pt +#endif +#else +#define ADD_LANG_PT +#endif // LANGUAGE_PT_ACTIVE +#if LANGUAGE_FR_ACTIVE +UI_MENU_ACTIONCOMMAND(ui_menu_setlang_fr, "Francais", UI_ACTION_LANGUAGE_FR | UI_ACTION_TOPMENU) +#if FIRSTLANG +#define ADD_LANG_FR &ui_menu_setlang_fr +#undef FIRSTLANG +#define FIRSTLANG 0 +#else +#define ADD_LANG_FR ,&ui_menu_setlang_fr +#endif +#else +#define ADD_LANG_FR +#endif // LANGUAGE_FR_ACTIVE +#if LANGUAGE_NL_ACTIVE +UI_MENU_ACTIONCOMMAND(ui_menu_setlang_nl, "Nederlandse", UI_ACTION_LANGUAGE_NL | UI_ACTION_TOPMENU) +#if FIRSTLANG +#define ADD_LANG_NL &ui_menu_setlang_nl +#undef FIRSTLANG +#define FIRSTLANG 0 +#else +#define ADD_LANG_NL ,&ui_menu_setlang_nl +#endif +#else +#define ADD_LANG_NL +#endif // LANGUAGE_NL_ACTIVE +#if LANGUAGE_IT_ACTIVE +UI_MENU_ACTIONCOMMAND(ui_menu_setlang_it, "Italiano", UI_ACTION_LANGUAGE_IT | UI_ACTION_TOPMENU) +#if FIRSTLANG +#define ADD_LANG_IT &ui_menu_setlang_it +#undef FIRSTLANG +#define FIRSTLANG 0 +#else +#define ADD_LANG_IT ,&ui_menu_setlang_it +#endif +#else +#define ADD_LANG_IT +#endif // LANGUAGE_IT_ACTIVE +#if LANGUAGE_FI_ACTIVE +UI_MENU_ACTIONCOMMAND(ui_menu_setlang_fi, "Suomi", UI_ACTION_LANGUAGE_FI | UI_ACTION_TOPMENU) +#if FIRSTLANG +#define ADD_LANG_SE &ui_menu_setlang_fi +#undef FIRSTLANG +#define FIRSTLANG 0 +#else +#define ADD_LANG_FI ,&ui_menu_setlang_fi +#endif +#else +#define ADD_LANG_FI +#endif // LANGUAGE_FI_ACTIVE +#if LANGUAGE_SE_ACTIVE +UI_MENU_ACTIONCOMMAND(ui_menu_setlang_se, "Svenska", UI_ACTION_LANGUAGE_SE | UI_ACTION_TOPMENU) +#if FIRSTLANG +#define ADD_LANG_SE &ui_menu_setlang_se +#undef FIRSTLANG +#define FIRSTLANG 0 +#else +#define ADD_LANG_SE ,&ui_menu_setlang_se +#endif +#else +#define ADD_LANG_SE +#endif // LANGUAGE_SE_ACTIVE +#if LANGUAGE_CZ_ACTIVE +UI_MENU_ACTIONCOMMAND(ui_menu_setlang_cz, "Cestina", UI_ACTION_LANGUAGE_CZ | UI_ACTION_TOPMENU) +#if FIRSTLANG +#define ADD_LANG_CZ &ui_menu_setlang_cz +#undef FIRSTLANG +#define FIRSTLANG 0 +#else +#define ADD_LANG_CZ ,&ui_menu_setlang_cz +#endif +#else +#define ADD_LANG_CZ +#endif // LANGUAGE_CZ_ACTIVE +#if LANGUAGE_PL_ACTIVE +UI_MENU_ACTIONCOMMAND(ui_menu_setlang_pl, "Polski", UI_ACTION_LANGUAGE_PL | UI_ACTION_TOPMENU) +#if FIRSTLANG +#define ADD_LANG_PL &ui_menu_setlang_pl +#undef FIRSTLANG +#define FIRSTLANG 0 +#else +#define ADD_LANG_PL ,&ui_menu_setlang_pl +#endif +#else +#define ADD_LANG_PL +#endif // LANGUAGE_PL_ACTIVE +#if LANGUAGE_TR_ACTIVE +UI_MENU_ACTIONCOMMAND(ui_menu_setlang_tr, "T" STR_uuml "rk", UI_ACTION_LANGUAGE_TR | UI_ACTION_TOPMENU) +#if FIRSTLANG +#define ADD_LANG_TR &ui_menu_setlang_tr +#undef FIRSTLANG +#define FIRSTLANG 0 +#else +#define ADD_LANG_TR ,&ui_menu_setlang_tr +#endif +#else +#define ADD_LANG_TR +#endif // LANGUAGE_TR_ACTIVE + +#define UI_MENU_LANGUAGES {UI_MENU_ADDCONDBACK ADD_LANG_EN ADD_LANG_DE ADD_LANG_ES ADD_LANG_PT ADD_LANG_FR ADD_LANG_NL ADD_LANG_IT ADD_LANG_FI ADD_LANG_SE ADD_LANG_CZ ADD_LANG_PL ADD_LANG_TR} +#define UI_MENU_LANGUAGES_WIZ {ADD_LANG_EN ADD_LANG_DE ADD_LANG_ES ADD_LANG_PT ADD_LANG_FR ADD_LANG_NL ADD_LANG_IT ADD_LANG_FI ADD_LANG_SE ADD_LANG_CZ ADD_LANG_PL ADD_LANG_TR} +UI_MENU(ui_menu_languages, UI_MENU_LANGUAGES, UI_MENU_BACKCNT + LANGUAGE_EN_ACTIVE + LANGUAGE_DE_ACTIVE + LANGUAGE_ES_ACTIVE + LANGUAGE_PT_ACTIVE + LANGUAGE_FR_ACTIVE + LANGUAGE_NL_ACTIVE + LANGUAGE_IT_ACTIVE + LANGUAGE_FI_ACTIVE + LANGUAGE_SE_ACTIVE + LANGUAGE_CZ_ACTIVE + LANGUAGE_PL_ACTIVE + LANGUAGE_TR_ACTIVE) +UI_MENU_SUBMENU_T(ui_menu_conf_lang, UI_TEXT_LANGUAGE_ID, ui_menu_languages) +UI_STICKYMENU(ui_menu_languages_wiz, UI_MENU_LANGUAGES_WIZ, LANGUAGE_EN_ACTIVE + LANGUAGE_DE_ACTIVE + LANGUAGE_ES_ACTIVE + LANGUAGE_PT_ACTIVE + LANGUAGE_FR_ACTIVE + LANGUAGE_NL_ACTIVE + LANGUAGE_IT_ACTIVE + LANGUAGE_FI_ACTIVE + LANGUAGE_SE_ACTIVE + LANGUAGE_CZ_ACTIVE + LANGUAGE_PL_ACTIVE + LANGUAGE_TR_ACTIVE) +#define LANGMENU_ENTRY ,&ui_menu_conf_lang +#define LANGMENU_COUNT 1 +#else +#define LANGMENU_ENTRY +#define LANGMENU_COUNT 0 +#endif + +// Error menu + +UI_MENU_ACTION2_T(ui_menu_error, UI_ACTION_DUMMY, UI_TEXT_ERROR_ID, UI_TEXT_ERRORMSG_ID) + +// Filament change wizard + +#if FEATURE_RETRACTION +#if UI_ROWS >= 4 +UI_WIZARD4_T(ui_wiz_filamentchange, UI_ACTION_WIZARD_FILAMENTCHANGE, UI_TEXT_WIZ_CH_FILAMENT1_ID, UI_TEXT_WIZ_CH_FILAMENT2_ID, UI_TEXT_WIZ_CH_FILAMENT3_ID, UI_TEXT_CLICK_DONE_ID) +UI_WIZARD4_T(ui_wiz_jamwaitheat, UI_ACTION_WIZARD_JAM_WAITHEAT, UI_TEXT_WIZ_WAITTEMP1_ID, UI_TEXT_WIZ_WAITTEMP2_ID, UI_TEXT_EMPTY_ID, UI_TEXT_TEMP_SET_ID) +UI_WIZARD4_T(ui_wiz_jamreheat, UI_ACTION_WIZARD_JAM_REHEAT, UI_TEXT_WIZ_REHEAT1_ID, UI_TEXT_WIZ_REHEAT2_ID, UI_TEXT_EMPTY_ID, UI_TEXT_CURRENT_TEMP_ID) +#else +UI_WIZARD2_T(ui_wiz_filamentchange, UI_ACTION_WIZARD_FILAMENTCHANGE, UI_TEXT_WIZ_CH_FILAMENT1_ID, UI_TEXT_CLICK_DONE_ID) +UI_WIZARD2_T(ui_wiz_jamwaitheat, UI_ACTION_WIZARD_JAM_WAITHEAT, UI_TEXT_WIZ_WAITTEMP1_ID, UI_TEXT_WIZ_WAITTEMP2_ID) +UI_WIZARD2_T(ui_wiz_jamreheat, UI_ACTION_WIZARD_JAM_REHEAT, UI_TEXT_WIZ_REHEAT1_ID, UI_TEXT_WIZ_REHEAT2_ID) +#endif +#endif + +// **** Positions submenus + +#if UI_ROWS >= 4 +UI_MENU_ACTION4_T(ui_menu_xpos, UI_ACTION_XPOSITION, UI_TEXT_ACTION_XPOSITION4A_ID, UI_TEXT_ACTION_XPOSITION4B_ID, UI_TEXT_ACTION_XPOSITION4C_ID, UI_TEXT_ACTION_XPOSITION4D_ID) +UI_MENU_ACTION4_T(ui_menu_ypos, UI_ACTION_YPOSITION, UI_TEXT_ACTION_YPOSITION4A_ID, UI_TEXT_ACTION_YPOSITION4B_ID, UI_TEXT_ACTION_YPOSITION4C_ID, UI_TEXT_ACTION_YPOSITION4D_ID) +UI_MENU_ACTION4_T(ui_menu_zpos, UI_ACTION_ZPOSITION, UI_TEXT_ACTION_ZPOSITION4A_ID, UI_TEXT_ACTION_ZPOSITION4B_ID, UI_TEXT_ACTION_ZPOSITION4C_ID, UI_TEXT_ACTION_ZPOSITION4D_ID) +UI_MENU_ACTION4_T(ui_menu_zpos_notest, UI_ACTION_ZPOSITION_NOTEST, UI_TEXT_ACTION_ZPOSITION4A_ID, UI_TEXT_ACTION_ZPOSITION4B_ID, UI_TEXT_ACTION_ZPOSITION4C_ID, UI_TEXT_ACTION_ZPOSITION4D_ID) +UI_MENU_ACTION4_T(ui_menu_xpos_fast, UI_ACTION_XPOSITION_FAST, UI_TEXT_ACTION_XPOSITION_FAST4A_ID, UI_TEXT_ACTION_XPOSITION_FAST4B_ID, UI_TEXT_ACTION_XPOSITION_FAST4C_ID, UI_TEXT_ACTION_XPOSITION_FAST4D_ID) +UI_MENU_ACTION4_T(ui_menu_ypos_fast, UI_ACTION_YPOSITION_FAST, UI_TEXT_ACTION_YPOSITION_FAST4A_ID, UI_TEXT_ACTION_YPOSITION_FAST4B_ID, UI_TEXT_ACTION_YPOSITION_FAST4C_ID, UI_TEXT_ACTION_YPOSITION_FAST4D_ID) +UI_MENU_ACTION4_T(ui_menu_zpos_fast, UI_ACTION_ZPOSITION_FAST, UI_TEXT_ACTION_ZPOSITION_FAST4A_ID, UI_TEXT_ACTION_ZPOSITION_FAST4B_ID, UI_TEXT_ACTION_ZPOSITION_FAST4C_ID, UI_TEXT_ACTION_ZPOSITION_FAST4D_ID) +UI_MENU_ACTION4_T(ui_menu_zpos_fast_notest, UI_ACTION_ZPOSITION_FAST_NOTEST, UI_TEXT_ACTION_ZPOSITION_FAST4A_ID, UI_TEXT_ACTION_ZPOSITION_FAST4B_ID, UI_TEXT_ACTION_ZPOSITION_FAST4C_ID, UI_TEXT_ACTION_ZPOSITION_FAST4D_ID) +UI_MENU_ACTION4_T(ui_menu_epos, UI_ACTION_EPOSITION, UI_TEXT_ACTION_EPOSITION_FAST2A_ID, UI_TEXT_ACTION_EPOSITION_FAST2B_ID, UI_TEXT_PAGE_EXTRUDER_ID, UI_TEXT_METER_PRINTED_ID) +#else +UI_MENU_ACTION2_T(ui_menu_xpos, UI_ACTION_XPOSITION, UI_TEXT_ACTION_XPOSITION2A_ID, UI_TEXT_ACTION_XPOSITION2B_ID) +UI_MENU_ACTION2_T(ui_menu_ypos, UI_ACTION_YPOSITION, UI_TEXT_ACTION_YPOSITION2A_ID, UI_TEXT_ACTION_YPOSITION2B_ID) +UI_MENU_ACTION2_T(ui_menu_zpos, UI_ACTION_ZPOSITION, UI_TEXT_ACTION_ZPOSITION2A_ID, UI_TEXT_ACTION_ZPOSITION2B_ID) +UI_MENU_ACTION2_T(ui_menu_zpos_notest, UI_ACTION_ZPOSITION_NOTEST, UI_TEXT_ACTION_ZPOSITION2A_ID, UI_TEXT_ACTION_ZPOSITION2B_ID) +UI_MENU_ACTION2_T(ui_menu_xpos_fast, UI_ACTION_XPOSITION_FAST, UI_TEXT_ACTION_XPOSITION_FAST2A_ID, UI_TEXT_ACTION_XPOSITION_FAST2B_ID) +UI_MENU_ACTION2_T(ui_menu_ypos_fast, UI_ACTION_YPOSITION_FAST, UI_TEXT_ACTION_YPOSITION_FAST2A_ID, UI_TEXT_ACTION_YPOSITION_FAST2B_ID) +UI_MENU_ACTION2_T(ui_menu_zpos_fast, UI_ACTION_ZPOSITION_FAST, UI_TEXT_ACTION_ZPOSITION_FAST2A_ID, UI_TEXT_ACTION_ZPOSITION_FAST2B_ID) +UI_MENU_ACTION2_T(ui_menu_zpos_fast_notest, UI_ACTION_ZPOSITION_FAST_NOTEST, UI_TEXT_ACTION_ZPOSITION_FAST2A_ID, UI_TEXT_ACTION_ZPOSITION_FAST2B_ID) +UI_MENU_ACTION2_T(ui_menu_epos, UI_ACTION_EPOSITION, UI_TEXT_ACTION_EPOSITION_FAST2A_ID, UI_TEXT_ACTION_EPOSITION_FAST2B_ID) +#endif + +/* + Next step is to define submenus leading to the action. +*/ + +// **** Positionening menu +UI_MENU_ACTIONCOMMAND_FILTER_T(ui_menu_home_all, UI_TEXT_HOME_ALL_ID, UI_ACTION_HOME_ALL, 0, MENU_MODE_PRINTING) +UI_MENU_ACTIONCOMMAND_FILTER_T(ui_menu_home_x, UI_TEXT_HOME_X_ID, UI_ACTION_HOME_X, 0, MENU_MODE_PRINTING) +UI_MENU_ACTIONCOMMAND_FILTER_T(ui_menu_home_y, UI_TEXT_HOME_Y_ID, UI_ACTION_HOME_Y, 0, MENU_MODE_PRINTING) +UI_MENU_ACTIONCOMMAND_FILTER_T(ui_menu_home_z, UI_TEXT_HOME_Z_ID, UI_ACTION_HOME_Z, 0, MENU_MODE_PRINTING) +UI_MENU_ACTIONSELECTOR_T(ui_menu_go_xpos, UI_TEXT_X_POSITION_ID, ui_menu_xpos) +UI_MENU_ACTIONSELECTOR_T(ui_menu_go_ypos, UI_TEXT_Y_POSITION_ID, ui_menu_ypos) +UI_MENU_ACTIONSELECTOR_T(ui_menu_go_zpos, UI_TEXT_Z_POSITION_ID, ui_menu_zpos) +UI_MENU_ACTIONSELECTOR_T(ui_menu_go_zpos_notest, UI_TEXT_Z_POSITION_ID, ui_menu_zpos_notest) +UI_MENU_ACTIONSELECTOR_T(ui_menu_go_epos, UI_TEXT_E_POSITION_ID, ui_menu_epos) +#if !UI_SPEEDDEPENDENT_POSITIONING +UI_MENU_ACTIONSELECTOR_T(ui_menu_go_xfast, UI_TEXT_X_POS_FAST_ID, ui_menu_xpos_fast) +UI_MENU_ACTIONSELECTOR_T(ui_menu_go_yfast, UI_TEXT_Y_POS_FAST_ID, ui_menu_ypos_fast) +UI_MENU_ACTIONSELECTOR_T(ui_menu_go_zfast, UI_TEXT_Z_POS_FAST_ID, ui_menu_zpos_fast) +UI_MENU_ACTIONSELECTOR_T(ui_menu_go_zfast_notest, UI_TEXT_Z_POS_FAST_ID, ui_menu_zpos_fast_notest) +#define UI_SPEED 2 +#define UI_SPEED_X ,&ui_menu_go_xfast,&ui_menu_go_xpos +#define UI_SPEED_Y ,&ui_menu_go_yfast,&ui_menu_go_ypos +#define UI_SPEED_Z ,&ui_menu_go_zfast,&ui_menu_go_zpos +#define UI_SPEED_Z_NOTEST ,&ui_menu_go_zfast_notest,&ui_menu_go_zpos_notest +#else +#define UI_SPEED 1 +#define UI_SPEED_X ,&ui_menu_go_xpos +#define UI_SPEED_Y ,&ui_menu_go_ypos +#define UI_SPEED_Z ,&ui_menu_go_zpos +#define UI_SPEED_Z_NOTEST ,&ui_menu_go_zpos_notest +#endif +#if FEATURE_SERVO > 0 && UI_SERVO_CONTROL > 0 +UI_MENU_CHANGEACTION_T(ui_menu_servopos, UI_TEXT_SERVOPOS_ID, UI_ACTION_SERVOPOS) +#define SERVOPOS_COUNT 1 +#define SERVOPOS_ENTRY ,&ui_menu_servopos +#else +#define SERVOPOS_COUNT 0 +#define SERVOPOS_ENTRY +#endif +// Offsets menu +UI_MENU_CHANGEACTION_T(ui_menu_off_xpos, UI_TEXT_X_OFFSET_ID, UI_ACTION_XOFF) +UI_MENU_CHANGEACTION_T(ui_menu_off_ypos, UI_TEXT_Y_OFFSET_ID, UI_ACTION_YOFF) +UI_MENU_CHANGEACTION_T(ui_menu_off_zpos, UI_TEXT_Z_OFFSET_ID, UI_ACTION_ZOFF) +#define UI_MENU_OFFSETS {UI_MENU_ADDCONDBACK &ui_menu_off_xpos,&ui_menu_off_ypos,&ui_menu_off_zpos} +UI_MENU(ui_menu_offsets, UI_MENU_OFFSETS, UI_MENU_BACKCNT + 3) +UI_MENU_SUBMENU_T(ui_menu_go_offsets, UI_TEXT_OFFSETS_ID, ui_menu_offsets) + +#if DRIVE_SYSTEM != DELTA //Positioning menu for non-delta +#define UI_MENU_POSITIONS {UI_MENU_ADDCONDBACK &ui_menu_home_all,&ui_menu_home_x,&ui_menu_home_y,&ui_menu_home_z UI_SPEED_X UI_SPEED_Y UI_SPEED_Z ,&ui_menu_go_epos SERVOPOS_ENTRY,&ui_menu_go_offsets} +UI_MENU(ui_menu_positions, UI_MENU_POSITIONS, 6 + 3 * UI_SPEED + UI_MENU_BACKCNT + SERVOPOS_COUNT) +#else //Positioning menu for delta (removes individual x,y,z homing) +#define UI_MENU_POSITIONS {UI_MENU_ADDCONDBACK &ui_menu_home_all UI_SPEED_X UI_SPEED_Y UI_SPEED_Z ,&ui_menu_go_epos SERVOPOS_ENTRY,&ui_menu_go_offsets} +UI_MENU(ui_menu_positions, UI_MENU_POSITIONS, 3 + 3 * UI_SPEED + UI_MENU_BACKCNT + SERVOPOS_COUNT) +#endif + +// **** Delta calibration menu +#if Z_HOME_DIR > 0 +UI_MENU_ACTIONCOMMAND_T(ui_menu_set_measured_origin, UI_TEXT_SET_MEASURED_ORIGIN_ID, UI_ACTION_SET_MEASURED_ORIGIN) +#define UI_MENU_DELTA {UI_MENU_ADDCONDBACK &ui_menu_home_all UI_SPEED_Z_NOTEST,&ui_menu_set_measured_origin} +UI_MENU(ui_menu_delta, UI_MENU_DELTA, 2 + UI_SPEED + UI_MENU_BACKCNT) +#endif + +// **** Bed leveling menu +#ifdef SOFTWARE_LEVELING +UI_MENU_ACTIONCOMMAND_T(ui_menu_set_p1, UI_TEXT_SET_P1_ID, UI_ACTION_SET_P1) +UI_MENU_ACTIONCOMMAND_T(ui_menu_set_p2, UI_TEXT_SET_P2_ID, UI_ACTION_SET_P2) +UI_MENU_ACTIONCOMMAND_T(ui_menu_set_p3, UI_TEXT_SET_P3_ID, UI_ACTION_SET_P3) +UI_MENU_ACTIONCOMMAND_T(ui_menu_calculate_leveling, UI_TEXT_CALCULATE_LEVELING_ID, UI_ACTION_CALC_LEVEL) +#define UI_MENU_LEVEL {UI_MENU_ADDCONDBACK &ui_menu_set_p1,&ui_menu_set_p2,&ui_menu_set_p3,&ui_menu_calculate_leveling UI_SPEED_X UI_SPEED_Y UI_SPEED_Z} +UI_MENU(ui_menu_level, UI_MENU_LEVEL, 4 + 3 * UI_SPEED + UI_MENU_BACKCNT) +#endif + +// **** Extruder menu +UI_MENU_CHANGEACTION_T(ui_menu_ext_temp0, UI_TEXT_EXTR0_TEMP_ID, UI_ACTION_EXTRUDER0_TEMP) +#if NUM_EXTRUDER > 1 && MIXING_EXTRUDER == 0 +UI_MENU_CHANGEACTION_T(ui_menu_ext_temp1, UI_TEXT_EXTR1_TEMP_ID, UI_ACTION_EXTRUDER1_TEMP) +#endif +#if NUM_EXTRUDER > 2 && MIXING_EXTRUDER == 0 +UI_MENU_CHANGEACTION_T(ui_menu_ext_temp2, UI_TEXT_EXTR2_TEMP_ID, UI_ACTION_EXTRUDER2_TEMP) +#endif +#if NUM_EXTRUDER > 3 && MIXING_EXTRUDER == 0 +UI_MENU_CHANGEACTION_T(ui_menu_ext_temp3, UI_TEXT_EXTR3_TEMP_ID, UI_ACTION_EXTRUDER3_TEMP) +#endif +#if NUM_EXTRUDER > 4 && MIXING_EXTRUDER == 0 +UI_MENU_CHANGEACTION_T(ui_menu_ext_temp4, UI_TEXT_EXTR4_TEMP_ID, UI_ACTION_EXTRUDER4_TEMP) +#endif +#if NUM_EXTRUDER > 5 && MIXING_EXTRUDER == 0 +UI_MENU_CHANGEACTION_T(ui_menu_ext_temp5, UI_TEXT_EXTR5_TEMP_ID, UI_ACTION_EXTRUDER5_TEMP) +#endif +UI_MENU_CHANGEACTION_T(ui_menu_bed_temp, UI_TEXT_BED_TEMP_ID, UI_ACTION_HEATED_BED_TEMP) +UI_MENU_ACTIONCOMMAND_T(ui_menu_ext_sel0, UI_TEXT_EXTR0_SELECT_ID, UI_ACTION_SELECT_EXTRUDER0) +#if NUM_EXTRUDER > 1 && MIXING_EXTRUDER == 0 +UI_MENU_ACTIONCOMMAND_T(ui_menu_ext_sel1, UI_TEXT_EXTR1_SELECT_ID, UI_ACTION_SELECT_EXTRUDER1) +#endif +#if NUM_EXTRUDER > 2 && MIXING_EXTRUDER == 0 +UI_MENU_ACTIONCOMMAND_T(ui_menu_ext_sel2, UI_TEXT_EXTR2_SELECT_ID, UI_ACTION_SELECT_EXTRUDER2) +#endif +#if NUM_EXTRUDER > 3 && MIXING_EXTRUDER == 0 +UI_MENU_ACTIONCOMMAND_T(ui_menu_ext_sel3, UI_TEXT_EXTR3_SELECT_ID, UI_ACTION_SELECT_EXTRUDER3) +#endif +#if NUM_EXTRUDER > 4 && MIXING_EXTRUDER == 0 +UI_MENU_ACTIONCOMMAND_T(ui_menu_ext_sel4, UI_TEXT_EXTR4_SELECT_ID, UI_ACTION_SELECT_EXTRUDER4) +#endif +#if NUM_EXTRUDER > 5 && MIXING_EXTRUDER == 0 +UI_MENU_ACTIONCOMMAND_T(ui_menu_ext_sel5, UI_TEXT_EXTR5_SELECT_ID, UI_ACTION_SELECT_EXTRUDER5) +#endif +UI_MENU_ACTIONCOMMAND_T(ui_menu_ext_off0, UI_TEXT_EXTR0_OFF_ID, UI_ACTION_EXTRUDER0_OFF) +#if NUM_EXTRUDER > 1 && MIXING_EXTRUDER == 0 +UI_MENU_ACTIONCOMMAND_T(ui_menu_ext_off1, UI_TEXT_EXTR1_OFF_ID, UI_ACTION_EXTRUDER1_OFF) +#endif +#if NUM_EXTRUDER > 2 && MIXING_EXTRUDER == 0 +UI_MENU_ACTIONCOMMAND_T(ui_menu_ext_off2, UI_TEXT_EXTR2_OFF_ID, UI_ACTION_EXTRUDER2_OFF) +#endif +#if NUM_EXTRUDER > 3 && MIXING_EXTRUDER == 0 +UI_MENU_ACTIONCOMMAND_T(ui_menu_ext_off3, UI_TEXT_EXTR3_OFF_ID, UI_ACTION_EXTRUDER3_OFF) +#endif +#if NUM_EXTRUDER > 4 && MIXING_EXTRUDER == 0 +UI_MENU_ACTIONCOMMAND_T(ui_menu_ext_off4, UI_TEXT_EXTR4_OFF_ID, UI_ACTION_EXTRUDER4_OFF) +#endif +#if NUM_EXTRUDER > 5 && MIXING_EXTRUDER == 0 +UI_MENU_ACTIONCOMMAND_T(ui_menu_ext_off5, UI_TEXT_EXTR5_OFF_ID, UI_ACTION_EXTRUDER5_OFF) +#endif +UI_MENU_ACTIONCOMMAND_T(ui_menu_ext_origin, UI_TEXT_EXTR_ORIGIN_ID, UI_ACTION_RESET_EXTRUDER) +#if FEATURE_DITTO_PRINTING +UI_MENU_ACTIONCOMMAND_T(ui_menu_ext_ditto0, UI_TEXT_DITTO_0_ID, UI_DITTO_0) +UI_MENU_ACTIONCOMMAND_T(ui_menu_ext_ditto1, UI_TEXT_DITTO_1_ID, UI_DITTO_1) +UI_MENU_ACTIONCOMMAND_T(ui_menu_ext_ditto2, UI_TEXT_DITTO_2_ID, UI_DITTO_2) +UI_MENU_ACTIONCOMMAND_T(ui_menu_ext_ditto3, UI_TEXT_DITTO_3_ID, UI_DITTO_3) +#if NUM_EXTRUDER == 3 +#define UI_DITTO_COMMANDS ,&ui_menu_ext_ditto0,&ui_menu_ext_ditto1,&ui_menu_ext_ditto2 +#define UI_DITTO_COMMANDS_COUNT 3 +#elif NUM_EXTRUDER == 4 +#define UI_DITTO_COMMANDS ,&ui_menu_ext_ditto0,&ui_menu_ext_ditto1,&ui_menu_ext_ditto2,&ui_menu_ext_ditto3 +#define UI_DITTO_COMMANDS_COUNT 4 +#else +#define UI_DITTO_COMMANDS ,&ui_menu_ext_ditto0,&ui_menu_ext_ditto1 +#define UI_DITTO_COMMANDS_COUNT 2 +#endif +#else +#define UI_DITTO_COMMANDS +#define UI_DITTO_COMMANDS_COUNT 0 +#endif +#if MIXING_EXTRUDER || NUM_EXTRUDER == 1 +#define UI_MENU_EXTCOND &ui_menu_ext_temp0,&ui_menu_ext_off0, +#define UI_MENU_EXTCNT 2 +#elif NUM_EXTRUDER == 2 +#define UI_MENU_EXTCOND &ui_menu_ext_temp0,&ui_menu_ext_temp1,&ui_menu_ext_off0,&ui_menu_ext_off1,&ui_menu_ext_sel0,&ui_menu_ext_sel1, +#define UI_MENU_EXTCNT 6 +#elif NUM_EXTRUDER == 3 +#define UI_MENU_EXTCOND &ui_menu_ext_temp0,&ui_menu_ext_temp1,&ui_menu_ext_temp2,&ui_menu_ext_off0,&ui_menu_ext_off1,&ui_menu_ext_off2,&ui_menu_ext_sel0,&ui_menu_ext_sel1,&ui_menu_ext_sel2, +#define UI_MENU_EXTCNT 9 +#elif NUM_EXTRUDER == 4 +#define UI_MENU_EXTCOND &ui_menu_ext_temp0,&ui_menu_ext_temp1,&ui_menu_ext_temp2,&ui_menu_ext_temp3,&ui_menu_ext_off0,&ui_menu_ext_off1,&ui_menu_ext_off2,&ui_menu_ext_off3,&ui_menu_ext_sel0,&ui_menu_ext_sel1,&ui_menu_ext_sel2,&ui_menu_ext_sel3, +#define UI_MENU_EXTCNT 12 +#elif NUM_EXTRUDER == 5 +#define UI_MENU_EXTCOND &ui_menu_ext_temp0,&ui_menu_ext_temp1,&ui_menu_ext_temp2,&ui_menu_ext_temp3,&ui_menu_ext_temp4,&ui_menu_ext_off0,&ui_menu_ext_off1,&ui_menu_ext_off2,&ui_menu_ext_off3,&ui_menu_ext_off4,&ui_menu_ext_sel0,&ui_menu_ext_sel1,&ui_menu_ext_sel2,&ui_menu_ext_sel3,&ui_menu_ext_sel4, +#define UI_MENU_EXTCNT 15 +#elif NUM_EXTRUDER == 6 +#define UI_MENU_EXTCOND &ui_menu_ext_temp0,&ui_menu_ext_temp1,&ui_menu_ext_temp2,&ui_menu_ext_temp3,&ui_menu_ext_temp4,&ui_menu_ext_temp5,&ui_menu_ext_off0,&ui_menu_ext_off1,&ui_menu_ext_off2,&ui_menu_ext_off3,&ui_menu_ext_off4,&ui_menu_ext_off5,&ui_menu_ext_sel0,&ui_menu_ext_sel1,&ui_menu_ext_sel2,&ui_menu_ext_sel3,&ui_menu_ext_sel4,&ui_menu_ext_sel5, +#define UI_MENU_EXTCNT 18 +#elif NUM_EXTRUDER == 0 +#define UI_MENU_EXTCOND +#define UI_MENU_EXTCNT 0 +#endif +#if HAVE_HEATED_BED +#define UI_MENU_BEDCOND &ui_menu_bed_temp, +#define UI_MENU_BEDCNT 1 +#else +#define UI_MENU_BEDCOND +#define UI_MENU_BEDCNT 0 +#endif + +#define UI_MENU_EXTRUDER {UI_MENU_ADDCONDBACK UI_MENU_BEDCOND UI_MENU_EXTCOND &ui_menu_go_epos,&ui_menu_ext_origin UI_DITTO_COMMANDS} +UI_MENU(ui_menu_extruder, UI_MENU_EXTRUDER, UI_MENU_BACKCNT + UI_MENU_BEDCNT + UI_MENU_EXTCNT + 2 + UI_DITTO_COMMANDS_COUNT) + +// **** SD card menu + +// **** Quick menu +#if PS_ON_PIN > -1 +UI_MENU_ACTIONCOMMAND_T(ui_menu_quick_power, UI_TEXT_POWER_ID, UI_ACTION_POWER) +#define MENU_PSON_COUNT 1 +#define MENU_PSON_ENTRY ,&ui_menu_quick_power +#else +#define MENU_PSON_COUNT 0 +#define MENU_PSON_ENTRY +#endif +#if CASE_LIGHTS_PIN >= 0 +UI_MENU_ACTIONCOMMAND_T(ui_menu_toggle_light, UI_TEXT_LIGHTS_ONOFF_ID, UI_ACTION_LIGHTS_ONOFF) +#define UI_TOOGLE_LIGHT_ENTRY ,&ui_menu_toggle_light +#define UI_TOGGLE_LIGHT_COUNT 1 +#else +#define UI_TOOGLE_LIGHT_ENTRY +#define UI_TOGGLE_LIGHT_COUNT 0 +#endif +UI_MENU_ACTIONCOMMAND_T(ui_menu_quick_preheat_pla, UI_TEXT_PREHEAT_PLA_ID, UI_ACTION_PREHEAT_PLA) +UI_MENU_ACTIONCOMMAND_T(ui_menu_quick_preheat_abs, UI_TEXT_PREHEAT_ABS_ID, UI_ACTION_PREHEAT_ABS) +UI_MENU_ACTIONCOMMAND_T(ui_menu_quick_cooldown, UI_TEXT_COOLDOWN_ID, UI_ACTION_COOLDOWN) +UI_MENU_ACTIONCOMMAND_FILTER_T(ui_menu_quick_origin, UI_TEXT_SET_TO_ORIGIN_ID, UI_ACTION_SET_ORIGIN, 0, MENU_MODE_PRINTING) +UI_MENU_ACTIONCOMMAND_FILTER_T(ui_menu_quick_stopstepper, UI_TEXT_DISABLE_STEPPER_ID, UI_ACTION_DISABLE_STEPPER, 0, MENU_MODE_PRINTING) +#if FEATURE_BABYSTEPPING +UI_MENU_CHANGEACTION_T(ui_menu_quick_zbaby, UI_TEXT_Z_BABYSTEPPING_ID, UI_ACTION_Z_BABYSTEPS) +#define BABY_CNT 1 +#define BABY_ENTRY ,&ui_menu_quick_zbaby +#else +#define BABY_CNT 0 +#define BABY_ENTRY +#endif +UI_MENU_CHANGEACTION_T(ui_menu_quick_speedmultiply, UI_TEXT_SPEED_MULTIPLY_ID, UI_ACTION_FEEDRATE_MULTIPLY) +UI_MENU_CHANGEACTION_T(ui_menu_quick_flowmultiply, UI_TEXT_FLOW_MULTIPLY_ID, UI_ACTION_FLOWRATE_MULTIPLY) +#ifdef DEBUG_PRINT +UI_MENU_ACTIONCOMMAND(ui_menu_quick_debug, "Write Debug", UI_ACTION_WRITE_DEBUG) +#define DEBUG_PRINT_COUNT 1 +#define DEBUG_PRINT_EXTRA ,&ui_menu_quick_debug +#else +#define DEBUG_PRINT_COUNT 0 +#define DEBUG_PRINT_EXTRA +#endif +#if FEATURE_RETRACTION +UI_MENU_ACTIONCOMMAND_T(ui_menu_quick_changefil, UI_TEXT_CHANGE_FILAMENT_ID, UI_ACTION_WIZARD_FILAMENTCHANGE) +#define UI_CHANGE_FIL_CNT 1 +#define UI_CHANGE_FIL_ENT ,&ui_menu_quick_changefil +#else +#define UI_CHANGE_FIL_CNT 0 +#define UI_CHANGE_FIL_ENT +#endif + +#define UI_MENU_QUICK {UI_MENU_ADDCONDBACK &ui_menu_home_all BABY_ENTRY ,&ui_menu_quick_speedmultiply,&ui_menu_quick_flowmultiply UI_TOOGLE_LIGHT_ENTRY UI_CHANGE_FIL_ENT,&ui_menu_quick_preheat_pla,&ui_menu_quick_preheat_abs,&ui_menu_quick_cooldown,&ui_menu_quick_origin,&ui_menu_quick_stopstepper MENU_PSON_ENTRY DEBUG_PRINT_EXTRA} +UI_MENU(ui_menu_quick, UI_MENU_QUICK, 8 + BABY_CNT + UI_MENU_BACKCNT + MENU_PSON_COUNT + DEBUG_PRINT_COUNT + UI_TOGGLE_LIGHT_COUNT + UI_CHANGE_FIL_CNT) + +// **** Bed Coating Menu + +#if UI_BED_COATING +UI_MENU_ACTION2_T(ui_menu_nocoating_action, UI_ACTION_DUMMY, UI_TEXT_BED_COATING_SET1_ID, UI_TEXT_NOCOATING_ID) +UI_MENU_ACTION2_T(ui_menu_buildtak_action, UI_ACTION_DUMMY, UI_TEXT_BED_COATING_SET1_ID, UI_TEXT_BUILDTAK_ID) +UI_MENU_ACTION2_T(ui_menu_kapton_action, UI_ACTION_DUMMY, UI_TEXT_BED_COATING_SET1_ID, UI_TEXT_KAPTON_ID) +UI_MENU_ACTION2_T(ui_menu_bluetape_action, UI_ACTION_DUMMY, UI_TEXT_BED_COATING_SET1_ID, UI_TEXT_BLUETAPE_ID) +UI_MENU_ACTION2_T(ui_menu_pettape_action, UI_ACTION_DUMMY, UI_TEXT_BED_COATING_SET1_ID, UI_TEXT_PETTAPE_ID) +UI_MENU_ACTION2_T(ui_menu_gluestick_action, UI_ACTION_DUMMY, UI_TEXT_BED_COATING_SET1_ID, UI_TEXT_GLUESTICK_ID) +UI_MENU_ACTION2_T(ui_menu_coating_custom, UI_ACTION_DUMMY, UI_TEXT_BED_COATING_SET1_ID, UI_TEXT_COATING_THICKNESS_ID) + +UI_MENU_ACTIONCOMMAND_FILTER_T(ui_menu_adjust_nocoating, UI_TEXT_NOCOATING_ID, UI_ACTION_NOCOATING, 0, MENU_MODE_PRINTING) +UI_MENU_ACTIONCOMMAND_FILTER_T(ui_menu_adjust_buildtak, UI_TEXT_BUILDTAK_ID, UI_ACTION_BUILDTAK, 0, MENU_MODE_PRINTING) +UI_MENU_ACTIONCOMMAND_FILTER_T(ui_menu_adjust_kapton, UI_TEXT_KAPTON_ID, UI_ACTION_KAPTON, 0, MENU_MODE_PRINTING) +UI_MENU_ACTIONCOMMAND_FILTER_T(ui_menu_adjust_bluetape, UI_TEXT_BLUETAPE_ID, UI_ACTION_BLUETAPE, 0, MENU_MODE_PRINTING) +UI_MENU_ACTIONCOMMAND_FILTER_T(ui_menu_adjust_pettape, UI_TEXT_PETTAPE_ID, UI_ACTION_PETTAPE, 0, MENU_MODE_PRINTING) +UI_MENU_ACTIONCOMMAND_FILTER_T(ui_menu_adjust_gluestick, UI_TEXT_GLUESTICK_ID, UI_ACTION_GLUESTICK, 0, MENU_MODE_PRINTING) +UI_MENU_CHANGEACTION_FILTER_T(ui_menu_adjust_custom, UI_TEXT_COATING_CUSTOM_ID, UI_ACTION_COATING_CUSTOM, 0, MENU_MODE_PRINTING) +#define UI_MENU_ADJUST {UI_MENU_ADDCONDBACK &ui_menu_adjust_nocoating,&ui_menu_adjust_buildtak,&ui_menu_adjust_kapton,&ui_menu_adjust_bluetape,&ui_menu_adjust_pettape,&ui_menu_adjust_gluestick,&ui_menu_adjust_custom} +UI_MENU(ui_menu_adjust, UI_MENU_ADJUST, 7 + UI_MENU_BACKCNT) +#define UI_MENU_COATING_CNT 1 +#define UI_MENU_COATING_COND &ui_menu_prepare, +UI_MENU_SUBMENU_FILTER_T(ui_menu_prepare, UI_TEXT_BED_COATING_ID, ui_menu_adjust, 0, MENU_MODE_PRINTING) + +#else +#define UI_MENU_COATING_CNT 0 +#define UI_MENU_COATING_COND +#endif + +// **** Fan menu + +#if FAN_PIN>-1 && FEATURE_FAN_CONTROL +UI_MENU_CHANGEACTION_T(ui_menu_fan_fanspeed, UI_TEXT_ACTION_FANSPEED_ID, UI_ACTION_FANSPEED) +UI_MENU_ACTIONCOMMAND_FILTER_T(ui_menu_fan_off, UI_TEXT_FAN_OFF_ID, UI_ACTION_FAN_OFF, MENU_MODE_FAN_RUNNING, 0) +UI_MENU_ACTIONCOMMAND_T(ui_menu_fan_25, UI_TEXT_FAN_25_ID, UI_ACTION_FAN_25) +UI_MENU_ACTIONCOMMAND_T(ui_menu_fan_50, UI_TEXT_FAN_50_ID, UI_ACTION_FAN_50) +UI_MENU_ACTIONCOMMAND_T(ui_menu_fan_75, UI_TEXT_FAN_75_ID, UI_ACTION_FAN_75) +UI_MENU_ACTIONCOMMAND_T(ui_menu_fan_full, UI_TEXT_FAN_FULL_ID, UI_ACTION_FAN_FULL) +UI_MENU_ACTIONCOMMAND_T(ui_menu_fan_ignoreM106, UI_TEXT_IGNORE_M106_ID, UI_ACTION_IGNORE_M106) +#define UI_MENU_FAN {UI_MENU_ADDCONDBACK &ui_menu_fan_fanspeed,&ui_menu_fan_off,&ui_menu_fan_25,&ui_menu_fan_50,&ui_menu_fan_75,&ui_menu_fan_full,&ui_menu_fan_ignoreM106} +UI_MENU(ui_menu_fan, UI_MENU_FAN, 7 + UI_MENU_BACKCNT) +UI_MENU_SUBMENU_T(ui_menu_fan_sub, UI_TEXT_FANSPEED_ID, ui_menu_fan) +#define UI_MENU_FAN_COND &ui_menu_fan_sub, +#define UI_MENU_FAN_CNT 1 +#else +#define UI_MENU_FAN_COND +#define UI_MENU_FAN_CNT 0 +#endif + +// **** SD card menu + +#if SDSUPPORT + +UI_MENU_HEADLINE_T(ui_menu_sd_askstop_head, UI_TEXT_STOP_PRINT_ID) +UI_MENU_ACTIONCOMMAND_T(ui_menu_sd_askstop_no, UI_TEXT_NO_ID, UI_ACTION_BACK) +UI_MENU_ACTIONCOMMAND_FILTER_T(ui_menu_sd_askstop_yes, UI_TEXT_YES_ID, UI_ACTION_SD_STOP | UI_ACTION_TOPMENU, MENU_MODE_SD_PRINTING, 0) +#define UI_MENU_SD_ASKSTOP {&ui_menu_sd_askstop_head,&ui_menu_sd_askstop_no,&ui_menu_sd_askstop_yes} +UI_MENU(ui_menu_sd_askstop, UI_MENU_SD_ASKSTOP, 3) + +#define UI_MENU_SD_FILESELECTOR {&ui_menu_back} +UI_MENU_FILESELECT(ui_menu_sd_fileselector, UI_MENU_SD_FILESELECTOR, 1) +UI_MENU_ACTIONCOMMAND_FILTER_T(ui_menu_sd_printfile, UI_TEXT_PRINT_FILE_ID, UI_ACTION_SD_PRINT, MENU_MODE_SD_MOUNTED, MENU_MODE_SD_PRINTING) +UI_MENU_ACTIONCOMMAND_FILTER_T(ui_menu_sd_pause, UI_TEXT_PAUSE_PRINT_ID, UI_ACTION_SD_PAUSE, MENU_MODE_SD_PRINTING, MENU_MODE_SD_PAUSED) +UI_MENU_ACTIONCOMMAND_FILTER_T(ui_menu_sd_continue, UI_TEXT_CONTINUE_PRINT_ID, UI_ACTION_SD_CONTINUE, MENU_MODE_SD_PAUSED, 0) +// two versions of stop. Second is with security question since pausing can trigger stop with bad luck! +//UI_MENU_ACTIONCOMMAND_FILTER_T(ui_menu_sd_stop, UI_TEXT_STOP_PRINT_ID, UI_ACTION_SD_STOP, MENU_MODE_SD_PRINTING, 0) +UI_MENU_SUBMENU_FILTER_T(ui_menu_sd_stop, UI_TEXT_STOP_PRINT_ID, ui_menu_sd_askstop, MENU_MODE_SD_PRINTING, 0 ) +#define SD_PRINTFILE_ENTRY &ui_menu_sd_printfile, +#define SD_PRINTFILE_ENTRY_CNT 1 +#if SDCARDDETECT > -1 +#define UI_MOUNT_CNT 0 +#define UI_MOUNT_CMD +#else +UI_MENU_ACTIONCOMMAND_FILTER_T(ui_menu_sd_unmount, UI_TEXT_UNMOUNT_CARD_ID, UI_ACTION_SD_UNMOUNT, MENU_MODE_SD_MOUNTED, 0) +UI_MENU_ACTIONCOMMAND_FILTER_T(ui_menu_sd_mount, UI_TEXT_MOUNT_CARD_ID, UI_ACTION_SD_MOUNT, 0, MENU_MODE_SD_MOUNTED) +#define UI_MOUNT_CNT 2 +#define UI_MOUNT_CMD ,&ui_menu_sd_unmount,&ui_menu_sd_mount +#endif +UI_MENU_ACTIONCOMMAND_FILTER_T(ui_menu_sd_delete, UI_TEXT_DELETE_FILE_ID, UI_ACTION_SD_DELETE, MENU_MODE_SD_MOUNTED, MENU_MODE_SD_PRINTING) +#define UI_MENU_SD {UI_MENU_ADDCONDBACK &ui_menu_sd_printfile,&ui_menu_sd_pause,&ui_menu_sd_continue,&ui_menu_sd_stop UI_MOUNT_CMD ,&ui_menu_sd_delete} +UI_MENU(ui_menu_sd, UI_MENU_SD, UI_MENU_BACKCNT + 5 + UI_MOUNT_CNT) +UI_MENU_SUBMENU_T(ui_menu_sd_sub, UI_TEXT_SD_CARD_ID, ui_menu_sd) + +#define UI_MENU_SD_COND &ui_menu_sd_sub, +#define UI_MENU_SD_CNT 1 +#else +#define UI_MENU_SD_COND +#define UI_MENU_SD_CNT 0 +#define SD_PRINTFILE_ENTRY +#define SD_PRINTFILE_ENTRY_CNT 0 +#endif + + +// **** Debugging menu +UI_MENU_ACTIONCOMMAND_T(ui_menu_debug_echo, UI_TEXT_DBG_ECHO_ID, UI_ACTION_DEBUG_ECHO) +UI_MENU_ACTIONCOMMAND_T(ui_menu_debug_info, UI_TEXT_DBG_INFO_ID, UI_ACTION_DEBUG_INFO) +UI_MENU_ACTIONCOMMAND_T(ui_menu_debug_error, UI_TEXT_DBG_ERROR_ID, UI_ACTION_DEBUG_ERROR) +UI_MENU_ACTIONCOMMAND_T(ui_menu_debug_dryrun, UI_TEXT_DBG_DRYRUN_ID, UI_ACTION_DEBUG_DRYRUN) +UI_MENU_ACTIONCOMMAND_T(ui_menu_debug_endstop, UI_TEXT_DBG_ENDSTOP_ID, UI_ACTION_DEBUG_ENDSTOP) + +#define UI_MENU_DEBUGGING {UI_MENU_ADDCONDBACK &ui_menu_debug_echo,&ui_menu_debug_info,&ui_menu_debug_error,&ui_menu_debug_dryrun,&ui_menu_debug_endstop} +UI_MENU(ui_menu_debugging, UI_MENU_DEBUGGING, 5 + UI_MENU_BACKCNT) + +// **** Acceleration settings +#if DRIVE_SYSTEM != DELTA +UI_MENU_CHANGEACTION_T(ui_menu_accel_printx, UI_TEXT_PRINT_X_ID, UI_ACTION_PRINT_ACCEL_X) +UI_MENU_CHANGEACTION_T(ui_menu_accel_printy, UI_TEXT_PRINT_Y_ID, UI_ACTION_PRINT_ACCEL_Y) +UI_MENU_CHANGEACTION_T(ui_menu_accel_printz, UI_TEXT_PRINT_Z_ID, UI_ACTION_PRINT_ACCEL_Z) +UI_MENU_CHANGEACTION_T(ui_menu_accel_travelx, UI_TEXT_MOVE_X_ID, UI_ACTION_MOVE_ACCEL_X) +UI_MENU_CHANGEACTION_T(ui_menu_accel_travely, UI_TEXT_MOVE_Y_ID, UI_ACTION_MOVE_ACCEL_Y) +UI_MENU_CHANGEACTION_T(ui_menu_accel_travelz, UI_TEXT_MOVE_Z_ID, UI_ACTION_MOVE_ACCEL_Z) +UI_MENU_CHANGEACTION_T(ui_menu_accel_jerk, UI_TEXT_JERK_ID, UI_ACTION_MAX_JERK) +UI_MENU_CHANGEACTION_T(ui_menu_accel_zjerk, UI_TEXT_ZJERK_ID, UI_ACTION_MAX_ZJERK) +#define UI_MENU_ACCEL {UI_MENU_ADDCONDBACK &ui_menu_accel_printx,&ui_menu_accel_printy,&ui_menu_accel_printz,&ui_menu_accel_travelx,&ui_menu_accel_travely,&ui_menu_accel_travelz,&ui_menu_accel_jerk,&ui_menu_accel_zjerk} +UI_MENU(ui_menu_accel, UI_MENU_ACCEL, 8 + UI_MENU_BACKCNT) + +// **** Feedrates +UI_MENU_CHANGEACTION_T(ui_menu_feedrate_maxx, UI_TEXT_FEED_MAX_X_ID, UI_ACTION_MAX_FEEDRATE_X) +UI_MENU_CHANGEACTION_T(ui_menu_feedrate_maxy, UI_TEXT_FEED_MAX_Y_ID, UI_ACTION_MAX_FEEDRATE_Y) +UI_MENU_CHANGEACTION_T(ui_menu_feedrate_maxz, UI_TEXT_FEED_MAX_Z_ID, UI_ACTION_MAX_FEEDRATE_Z) +UI_MENU_CHANGEACTION_T(ui_menu_feedrate_homex, UI_TEXT_FEED_HOME_X_ID, UI_ACTION_HOMING_FEEDRATE_X) +UI_MENU_CHANGEACTION_T(ui_menu_feedrate_homey, UI_TEXT_FEED_HOME_Y_ID, UI_ACTION_HOMING_FEEDRATE_Y) +UI_MENU_CHANGEACTION_T(ui_menu_feedrate_homez, UI_TEXT_FEED_HOME_Z_ID, UI_ACTION_HOMING_FEEDRATE_Z) +#define UI_MENU_FEEDRATE {UI_MENU_ADDCONDBACK &ui_menu_feedrate_maxx,&ui_menu_feedrate_maxy,&ui_menu_feedrate_maxz,&ui_menu_feedrate_homex,&ui_menu_feedrate_homey,&ui_menu_feedrate_homez} +UI_MENU(ui_menu_feedrate, UI_MENU_FEEDRATE, 6 + UI_MENU_BACKCNT) +#else +UI_MENU_CHANGEACTION_T(ui_menu_accel_printz, UI_TEXT_PRINT_Z_DELTA_ID, UI_ACTION_PRINT_ACCEL_Z) +UI_MENU_CHANGEACTION_T(ui_menu_accel_travelz, UI_TEXT_MOVE_Z_DELTA_ID, UI_ACTION_MOVE_ACCEL_Z) +UI_MENU_CHANGEACTION_T(ui_menu_accel_jerk, UI_TEXT_JERK_ID, UI_ACTION_MAX_JERK) +#define UI_MENU_ACCEL {UI_MENU_ADDCONDBACK &ui_menu_accel_printz,&ui_menu_accel_travelz,&ui_menu_accel_jerk} +UI_MENU(ui_menu_accel, UI_MENU_ACCEL, 3 + UI_MENU_BACKCNT) + +// **** Feedrates +UI_MENU_CHANGEACTION_T(ui_menu_feedrate_maxz, UI_TEXT_FEED_MAX_Z_DELTA_ID, UI_ACTION_MAX_FEEDRATE_Z) +UI_MENU_CHANGEACTION_T(ui_menu_feedrate_homez, UI_TEXT_FEED_HOME_Z_DELTA_ID, UI_ACTION_HOMING_FEEDRATE_Z) +#define UI_MENU_FEEDRATE {UI_MENU_ADDCONDBACK &ui_menu_feedrate_maxz,&ui_menu_feedrate_homez} +UI_MENU(ui_menu_feedrate, UI_MENU_FEEDRATE, 2 + UI_MENU_BACKCNT) +#endif + +// **** General configuration settings + +UI_MENU_ACTION2_T(ui_menu_stepper2, UI_ACTION_STEPPER_INACTIVE, UI_TEXT_STEPPER_INACTIVE2A_ID, UI_TEXT_STEPPER_INACTIVE2B_ID) +UI_MENU_ACTION2_T(ui_menu_maxinactive2, UI_ACTION_MAX_INACTIVE, UI_TEXT_POWER_INACTIVE2A_ID, UI_TEXT_POWER_INACTIVE2B_ID) +UI_MENU_CHANGEACTION_T(ui_menu_general_baud, UI_TEXT_BAUDRATE_ID, UI_ACTION_BAUDRATE) +UI_MENU_ACTIONSELECTOR_T(ui_menu_general_stepper_inactive, UI_TEXT_STEPPER_INACTIVE_ID, ui_menu_stepper2) +UI_MENU_ACTIONSELECTOR_T(ui_menu_general_max_inactive, UI_TEXT_POWER_INACTIVE_ID, ui_menu_maxinactive2) +#if FEATURE_AUTOLEVEL +UI_MENU_ACTIONCOMMAND_T(ui_menu_toggle_autolevel, UI_TEXT_AUTOLEVEL_ONOFF_ID, UI_ACTION_AUTOLEVEL_ONOFF) +#define UI_TOOGLE_AUTOLEVEL_ENTRY ,&ui_menu_toggle_autolevel +#define UI_TOGGLE_AUTOLEVEL_COUNT 1 +#else +#define UI_TOOGLE_AUTOLEVEL_ENTRY +#define UI_TOGGLE_AUTOLEVEL_COUNT 0 +#endif +#define UI_MENU_GENERAL {UI_MENU_ADDCONDBACK &ui_menu_general_baud,&ui_menu_general_stepper_inactive,&ui_menu_general_max_inactive UI_TOOGLE_AUTOLEVEL_ENTRY} +UI_MENU(ui_menu_general, UI_MENU_GENERAL, 3 + UI_MENU_BACKCNT + UI_TOGGLE_AUTOLEVEL_COUNT) + +// **** Extruder configuration + +UI_MENU_CHANGEACTION_T(ui_menu_cext_steps, UI_TEXT_EXTR_STEPS_ID, UI_ACTION_EXTR_STEPS) +UI_MENU_CHANGEACTION_T(ui_menu_cext_start_feedrate, UI_TEXT_EXTR_START_FEED_ID, UI_ACTION_EXTR_START_FEEDRATE) +UI_MENU_CHANGEACTION_T(ui_menu_cext_max_feedrate, UI_TEXT_EXTR_MAX_FEED_ID, UI_ACTION_EXTR_MAX_FEEDRATE) +UI_MENU_CHANGEACTION_T(ui_menu_cext_acceleration, UI_TEXT_EXTR_ACCEL_ID, UI_ACTION_EXTR_ACCELERATION) +UI_MENU_CHANGEACTION_T(ui_menu_cext_watch_period, UI_TEXT_EXTR_WATCH_ID, UI_ACTION_EXTR_WATCH_PERIOD) +UI_MENU_CHANGEACTION_T(ui_menu_ext_wait_temp, UI_TEXT_EXTR_WAIT_RETRACT_TEMP_ID, UI_ACTION_EXTR_WAIT_RETRACT_TEMP) +UI_MENU_CHANGEACTION_T(ui_menu_ext_wait_units, UI_TEXT_EXTR_WAIT_RETRACT_UNITS_ID, UI_ACTION_EXTR_WAIT_RETRACT_UNITS) +#define UI_MENU_ADV_CNT 0 +#define UI_MENU_ADVANCE +#if USE_ADVANCE +#undef UI_MENU_ADV_CNT +#define UI_MENU_ADV_CNT 1 +#undef UI_MENU_ADVANCE +#define UI_MENU_ADVANCE ,&ui_menu_cext_advancel +#if ENABLE_QUADRATIC_ADVANCE +#undef UI_MENU_ADV_CNT +#define UI_MENU_ADV_CNT 2 +#undef UI_MENU_ADVANCE +#define UI_MENU_ADVANCE ,&ui_menu_cext_advancel,&ui_menu_cext_advancek +UI_MENU_CHANGEACTION_T(ui_menu_cext_advancek, UI_TEXT_EXTR_ADVANCE_K_ID, UI_ACTION_ADVANCE_K) +#endif +UI_MENU_CHANGEACTION_T(ui_menu_cext_advancel, UI_TEXT_EXTR_ADVANCE_L_ID, UI_ACTION_ADVANCE_L) +#endif +UI_MENU_CHANGEACTION_T( ui_menu_cext_manager, UI_TEXT_EXTR_MANAGER_ID, UI_ACTION_EXTR_HEATMANAGER) +UI_MENU_CHANGEACTION_T( ui_menu_cext_pmax, UI_TEXT_EXTR_PMAX_ID, UI_ACTION_PID_MAX) +#if TEMP_PID +UI_MENU_CHANGEACTION_FILTER_T(ui_menu_cext_pgain, UI_TEXT_EXTR_PGAIN_ID, UI_ACTION_PID_PGAIN, MENU_MODE_FULL_PID, 0) +UI_MENU_CHANGEACTION_FILTER_T(ui_menu_cext_igain, UI_TEXT_EXTR_IGAIN_ID, UI_ACTION_PID_IGAIN, MENU_MODE_FULL_PID, 0) +UI_MENU_CHANGEACTION_FILTER_T(ui_menu_cext_dgain, UI_TEXT_EXTR_DGAIN_ID, UI_ACTION_PID_DGAIN, MENU_MODE_FULL_PID, 0) +UI_MENU_CHANGEACTION_FILTER_T(ui_menu_cext_dmin, UI_TEXT_EXTR_DMIN_ID, UI_ACTION_DRIVE_MIN, MENU_MODE_FULL_PID, 0) +UI_MENU_CHANGEACTION_FILTER_T(ui_menu_cext_dmax, UI_TEXT_EXTR_DMAX_ID, UI_ACTION_DRIVE_MAX, MENU_MODE_FULL_PID, 0) +UI_MENU_CHANGEACTION_FILTER_T(ui_menu_cext_pgain_dt, UI_TEXT_EXTR_DEADTIME_ID, UI_ACTION_PID_PGAIN, MENU_MODE_DEADTIME, 0) +UI_MENU_CHANGEACTION_FILTER_T(ui_menu_cext_dmax_dt, UI_TEXT_EXTR_DMAX_DT_ID, UI_ACTION_DRIVE_MAX, MENU_MODE_DEADTIME, 0) +#define UI_MENU_PIDCOND ,&ui_menu_cext_manager,&ui_menu_cext_pgain,&ui_menu_cext_igain,&ui_menu_cext_dgain,&ui_menu_cext_dmin,&ui_menu_cext_dmax, &ui_menu_cext_pgain_dt,&ui_menu_cext_dmax_dt,&ui_menu_cext_pmax +#define UI_MENU_PIDCNT 9 +#else +#define UI_MENU_PIDCOND ,&ui_menu_cext_manager, &ui_menu_cext_pmax +#define UI_MENU_PIDCNT 2 +#endif +#if NUM_EXTRUDER > 5 && MIXING_EXTRUDER == 0 +UI_MENU_CHANGEACTION_T(ui_menu_cext_xoffset, UI_TEXT_EXTR_XOFF_ID, UI_ACTION_X_OFFSET) +UI_MENU_CHANGEACTION_T(ui_menu_cext_yoffset, UI_TEXT_EXTR_YOFF_ID, UI_ACTION_Y_OFFSET) +#define UI_MENU_CONFEXTCOND &ui_menu_ext_sel0,&ui_menu_ext_sel1,&ui_menu_ext_sel2,&ui_menu_ext_sel3,&ui_menu_ext_sel4,&ui_menu_ext_sel5,&ui_menu_cext_xoffset,&ui_menu_cext_yoffset, +#define UI_MENU_CONFEXTCNT 8 +#elif NUM_EXTRUDER > 4 && MIXING_EXTRUDER == 0 +UI_MENU_CHANGEACTION_T(ui_menu_cext_xoffset, UI_TEXT_EXTR_XOFF_ID, UI_ACTION_X_OFFSET) +UI_MENU_CHANGEACTION_T(ui_menu_cext_yoffset, UI_TEXT_EXTR_YOFF_ID, UI_ACTION_Y_OFFSET) +#define UI_MENU_CONFEXTCOND &ui_menu_ext_sel0,&ui_menu_ext_sel1,&ui_menu_ext_sel2,&ui_menu_ext_sel3,&ui_menu_ext_sel4,&ui_menu_cext_xoffset,&ui_menu_cext_yoffset, +#define UI_MENU_CONFEXTCNT 7 +#elif NUM_EXTRUDER > 3 && MIXING_EXTRUDER == 0 +UI_MENU_CHANGEACTION_T(ui_menu_cext_xoffset, UI_TEXT_EXTR_XOFF_ID, UI_ACTION_X_OFFSET) +UI_MENU_CHANGEACTION_T(ui_menu_cext_yoffset, UI_TEXT_EXTR_YOFF_ID, UI_ACTION_Y_OFFSET) +#define UI_MENU_CONFEXTCOND &ui_menu_ext_sel0,&ui_menu_ext_sel1,&ui_menu_ext_sel2,&ui_menu_ext_sel3,&ui_menu_cext_xoffset,&ui_menu_cext_yoffset, +#define UI_MENU_CONFEXTCNT 6 +#elif NUM_EXTRUDER > 2 && MIXING_EXTRUDER == 0 +UI_MENU_CHANGEACTION_T(ui_menu_cext_xoffset, UI_TEXT_EXTR_XOFF_ID, UI_ACTION_X_OFFSET) +UI_MENU_CHANGEACTION_T(ui_menu_cext_yoffset, UI_TEXT_EXTR_YOFF_ID, UI_ACTION_Y_OFFSET) +#define UI_MENU_CONFEXTCOND &ui_menu_ext_sel0,&ui_menu_ext_sel1,&ui_menu_ext_sel2,&ui_menu_cext_xoffset,&ui_menu_cext_yoffset, +#define UI_MENU_CONFEXTCNT 5 +#elif NUM_EXTRUDER > 1 && MIXING_EXTRUDER == 0 +UI_MENU_CHANGEACTION_T(ui_menu_cext_xoffset, UI_TEXT_EXTR_XOFF_ID, UI_ACTION_X_OFFSET) +UI_MENU_CHANGEACTION_T(ui_menu_cext_yoffset, UI_TEXT_EXTR_YOFF_ID, UI_ACTION_Y_OFFSET) +#define UI_MENU_CONFEXTCOND &ui_menu_ext_sel0,&ui_menu_ext_sel1,&ui_menu_cext_xoffset,&ui_menu_cext_yoffset, +#define UI_MENU_CONFEXTCNT 4 +#else +#define UI_MENU_CONFEXTCOND +#define UI_MENU_CONFEXTCNT 0 +#endif +#define UI_MENU_CEXTR {UI_MENU_ADDCONDBACK UI_MENU_CONFEXTCOND &ui_menu_cext_steps,&ui_menu_cext_start_feedrate,&ui_menu_cext_max_feedrate,&ui_menu_cext_acceleration,&ui_menu_cext_watch_period,&ui_menu_ext_wait_units,&ui_menu_ext_wait_temp UI_MENU_ADVANCE UI_MENU_PIDCOND} +UI_MENU(ui_menu_cextr, UI_MENU_CEXTR, 7 + UI_MENU_BACKCNT + UI_MENU_PIDCNT + UI_MENU_CONFEXTCNT + UI_MENU_ADV_CNT) + +// HeatBed Configuration - use menu actions from extruder configuration +#if HAVE_HEATED_BED +#if TEMP_PID +#define UI_MENU_BEDCONF {UI_MENU_ADDCONDBACK &ui_menu_cext_manager,&ui_menu_cext_pgain,&ui_menu_cext_igain,&ui_menu_cext_dgain,&ui_menu_cext_dmin,&ui_menu_cext_dmax,&ui_menu_cext_pmax} +UI_MENU(ui_menu_bedconf, UI_MENU_BEDCONF, 8) +#else +#define UI_MENU_BEDCONF {UI_MENU_ADDCONDBACK &ui_menu_cext_manager, &ui_menu_cext_pmax} +UI_MENU(ui_menu_bedconf, UI_MENU_BEDCONF, 3) +#endif +#endif + +// **** Configuration menu + +UI_MENU_SUBMENU_T(ui_menu_conf_general, UI_TEXT_GENERAL_ID, ui_menu_general) +UI_MENU_SUBMENU_T(ui_menu_conf_accel, UI_TEXT_ACCELERATION_ID, ui_menu_accel) +UI_MENU_SUBMENU_T(ui_menu_conf_feed, UI_TEXT_FEEDRATE_ID, ui_menu_feedrate) +UI_MENU_SUBMENU_T(ui_menu_conf_extr, UI_TEXT_EXTRUDER_ID, ui_menu_cextr) +#if HAVE_HEATED_BED +UI_MENU_SUBMENU_T(ui_menu_conf_bed, UI_TEXT_HEATING_BED_ID, ui_menu_bedconf) +#define UI_MENU_BEDCONF_COND ,&ui_menu_conf_bed +#define UI_MENU_BEDCONF_CNT 1 +#else +#define UI_MENU_BEDCONF_COND +#define UI_MENU_BEDCONF_CNT 0 +#endif +#if EEPROM_MODE!=0 +UI_MENU_ACTIONCOMMAND_T(ui_menu_conf_to_eeprom, UI_TEXT_STORE_TO_EEPROM_ID, UI_ACTION_STORE_EEPROM) +UI_MENU_ACTIONCOMMAND_T(ui_menu_conf_from_eeprom, UI_TEXT_LOAD_EEPROM_ID, UI_ACTION_LOAD_EEPROM) +#define UI_MENU_EEPROM_COND ,&ui_menu_conf_to_eeprom,&ui_menu_conf_from_eeprom +#define UI_MENU_EEPROM_CNT 2 +UI_MENU_ACTION2_T(ui_menu_eeprom_saved, UI_ACTION_DUMMY, UI_TEXT_EEPROM_STOREDA_ID, UI_TEXT_EEPROM_STOREDB_ID) +UI_MENU_ACTION2_T(ui_menu_eeprom_loaded, UI_ACTION_DUMMY, UI_TEXT_EEPROM_LOADEDA_ID, UI_TEXT_EEPROM_LOADEDB_ID) +#else +#define UI_MENU_EEPROM_COND +#define UI_MENU_EEPROM_CNT 0 +#endif +#if defined(SOFTWARE_LEVELING) && DRIVE_SYSTEM == DELTA +#define UI_MENU_SL_COND ,&ui_menu_conf_level +#define UI_MENU_SL_CNT 1 +UI_MENU_SUBMENU_T(ui_menu_conf_level, UI_TEXT_LEVEL_ID, ui_menu_level) +#else +#define UI_MENU_SL_COND +#define UI_MENU_SL_CNT 0 +#endif +#if Z_HOME_DIR > 0 +#define UI_MENU_DELTA_COND ,&ui_menu_conf_delta +#define UI_MENU_DELTA_CNT 1 +UI_MENU_SUBMENU_T(ui_menu_conf_delta, UI_TEXT_ZCALIB_ID, ui_menu_delta) +#else +#define UI_MENU_DELTA_COND +#define UI_MENU_DELTA_CNT 0 +#endif +#define UI_MENU_CONFIGURATION {UI_MENU_ADDCONDBACK &ui_menu_conf_general LANGMENU_ENTRY ,&ui_menu_conf_accel,&ui_menu_conf_feed,&ui_menu_conf_extr UI_MENU_BEDCONF_COND UI_MENU_EEPROM_COND UI_MENU_DELTA_COND UI_MENU_SL_COND} +UI_MENU(ui_menu_configuration, UI_MENU_CONFIGURATION, UI_MENU_BACKCNT + LANGMENU_COUNT + UI_MENU_EEPROM_CNT + UI_MENU_BEDCONF_CNT + UI_MENU_DELTA_CNT + UI_MENU_SL_CNT + 4) +// Main menu +UI_MENU_SUBMENU_T(ui_menu_main1, UI_TEXT_QUICK_SETTINGS_ID, ui_menu_quick) +UI_MENU_SUBMENU_T(ui_menu_main2, UI_TEXT_POSITION_ID, ui_menu_positions) +UI_MENU_SUBMENU_T(ui_menu_main3, UI_TEXT_EXTRUDER_ID, ui_menu_extruder) +UI_MENU_SUBMENU_T(ui_menu_main4, UI_TEXT_DEBUGGING_ID, ui_menu_debugging) +UI_MENU_SUBMENU_T(ui_menu_main5, UI_TEXT_CONFIGURATION_ID, ui_menu_configuration) +#define UI_MENU_MAIN {UI_MENU_ADDCONDBACK &ui_menu_main1,SD_PRINTFILE_ENTRY &ui_menu_main2,&ui_menu_main3,UI_MENU_FAN_COND UI_MENU_COATING_COND UI_MENU_SD_COND &ui_menu_main4,&ui_menu_main5} +UI_MENU(ui_menu_main, UI_MENU_MAIN, 5 + UI_MENU_BACKCNT + UI_MENU_SD_CNT + UI_MENU_FAN_CNT + SD_PRINTFILE_ENTRY_CNT + UI_MENU_COATING_CNT) + +/* Define menus accessible by action commands + + You can create up to 10 user menus which are accessible by the action commands UI_ACTION_SHOW_USERMENU1 until UI_ACTION_SHOW_USERMENU10 + You this the same way as with the menus above or you use one of the above menus. Then add a define like + + #define UI_USERMENU1 ui_menu_conf_feed + + which assigns the menu stored in ui_menu_conf_feed to the action UI_ACTION_SHOW_USERMENU1. Make sure only to change the numbers and not the name of the define. + + When do you need this? You might want a fast button to change the temperature. In the default menu you have no menu + to change the temperature and view it the same time. So you need to make an action menu for this like: + UI_MENU_ACTION4C(ui_menu_extrtemp,UI_ACTION_EXTRUDER0_TEMP,"Temp. 0 :%E0" cDEG,"","",""); + Then you assign this menu to a usermenu: + #define UI_USERMENU2 ui_menu_extrtemp + + Now you can assign the action UI_ACTION_SHOW_USERMENU2+UI_ACTION_TOPMENU to a key and that will now show the temperture screen and allows + the change of temperature with the next/previous buttons. + +*/ +#endif +#endif // __UI_MENU_H diff --git a/trunk/Arduino/Single_Chip_Computer/EEprom/EEPROM Storage Cad Artwork.oxps b/trunk/Arduino/Single_Chip_Computer/EEprom/EEPROM Storage Cad Artwork.oxps new file mode 100644 index 0000000000000000000000000000000000000000..9a409001ccf24ac906ec3c7113f11e86dd6ed053 GIT binary patch literal 32264 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 literal 0 HcmV?d00001 diff --git a/trunk/Arduino/Single_Chip_Computer/EEprom/EEPROM Storage Card Schematic.png b/trunk/Arduino/Single_Chip_Computer/EEprom/EEPROM Storage Card Schematic.png new file mode 100644 index 0000000000000000000000000000000000000000..bcbecf85ab489f773f0a5204ee3f01f12a534d60 GIT binary patch literal 35067 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%0D}lM48;ff9cPrP^@|T3;n4gs@Sq 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 &ST`vA8B`ZK%jhhk)mlDYg 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 EA3K(D4FCWD literal 0 HcmV?d00001 diff --git a/trunk/Arduino/Single_Chip_Computer/Single_Chip_Computer.ino b/trunk/Arduino/Single_Chip_Computer/Single_Chip_Computer.ino new file mode 100644 index 00000000..f87a5ce6 --- /dev/null +++ b/trunk/Arduino/Single_Chip_Computer/Single_Chip_Computer.ino @@ -0,0 +1,2178 @@ +//////////////////////////////////////////////////////////////////////////////// +// TinyBasic Plus +//////////////////////////////////////////////////////////////////////////////// +// +// Authors: Mike Field +// Scott Lawrence +// Dan +// + +#define kVersion "v0.14" + +// v0.14: 19/04/2014 +// TVout and PS2uartKeyboard Libraries added. +// +// v0.13: 2013-03-04 +// Support for Arduino 1.5 (SPI.h included, additional changes for DUE support) +// +// v0.12: 2013-03-01 +// EEPROM load and save routines added: EFORMAT, ELIST, ELOAD, ESAVE, ECHAIN +// added EAUTORUN option (chains to EEProm saved program on startup) +// Bugfixes to build properly on non-arduino systems (PROGMEM #define workaround) +// cleaned up a bit of the #define options wrt TONE +// +// v0.11: 2013-02-20 +// all display strings and tables moved to PROGMEM to save space +// removed second serial +// removed pinMode completely, autoconf is explicit +// beginnings of EEPROM related functionality (new,load,save,list) +// +// v0.10: 2012-10-15 +// added kAutoConf, which eliminates the "PINMODE" statement. +// now, DWRITE,DREAD,AWRITE,AREAD automatically set the PINMODE appropriately themselves. +// should save a few bytes in your programs. +// +// v0.09: 2012-10-12 +// Fixed directory listings. FILES now always works. (bug in the SD library) +// ref: http://arduino.cc/forum/index.php/topic,124739.0.html +// fixed filesize printouts (added printUnum for unsigned numbers) +// #defineable baud rate for slow connection throttling +//e +// v0.08: 2012-10-02 +// Tone generation through piezo added (TONE, TONEW, NOTONE) +// +// v0.07: 2012-09-30 +// Autorun buildtime configuration feature +// +// v0.06: 2012-09-27 +// Added optional second serial input, used for an external keyboard +// +// v0.05: 2012-09-21 +// CHAIN to load and run a second file +// RND,RSEED for random stuff +// Added "!=" for "<>" synonym +// Added "END" for "STOP" synonym (proper name for the functionality anyway) +// +// v0.04: 2012-09-20 +// DELAY ms - for delaying +// PINMODE , INPUT|IN|I|OUTPUT|OUT|O +// DWRITE , HIGH|HI|1|LOW|LO|0 +// AWRITE , [0..255] +// fixed "save" appending to existing files instead of overwriting +// Updated for building desktop command line app (incomplete) +// +// v0.03: 2012-09-19 +// Integrated Jurg Wullschleger whitespace,unary fix +// Now available through github +// Project renamed from "Tiny Basic in C" to "TinyBasic Plus" +// +// v0.02b: 2012-09-17 Scott Lawrence +// Better FILES listings +// +// v0.02a: 2012-09-17 Scott Lawrence +// Support for SD Library +// Added: SAVE, FILES (mostly works), LOAD (mostly works) (redirects IO) +// Added: MEM, ? (PRINT) +// Quirk: "10 LET A=B+C" is ok "10 LET A = B + C" is not. +// Quirk: INPUT seems broken? + +/* +* Additional Libraries +*/ +// TVout +#include +#include +#include +#include +#include +#include +#include +// PS2 Keyboard +#include + +PS2uartKeyboard keyboard; +TVout TV; + + +// IF testing with Visual C, this needs to be the first thing in the file. +//#include "stdafx.h" + + +char eliminateCompileErrors = 1; // fix to suppress arduino build errors + +// hack to let makefiles work with this file unchanged +#ifdef FORCE_DESKTOP +#undef ARDUINO +#else +#define ARDUINO 1 +#endif + +//////////////////////////////////////////////////////////////////////////////// +// Feature option configuration... + +// This enables LOAD, SAVE, FILES commands through the Arduino SD Library +// it adds 9k of usage as well. +//#define ENABLE_FILEIO 1 +#undef ENABLE_FILEIO + +// this turns on "autorun". if there's FileIO, and a file "autorun.bas", +// then it will load it and run it when starting up +//#define ENABLE_AUTORUN 1 +#undef ENABLE_AUTORUN +// and this is the file that gets run +#define kAutorunFilename "autorun.bas" + +// this is the alternate autorun. Autorun the program in the eeprom. +// it will load whatever is in the EEProm and run it +#define ENABLE_EAUTORUN 1 +//#undef ENABLE_EAUTORUN + +// this will enable the "TONE", "NOTONE" command using a piezo +// element on the specified pin. Wire the red/positive/piezo to the kPiezoPin, +// and the black/negative/metal disc to ground. +// it adds 1.5k of usage as well. +#define ENABLE_TONES 1 +//#undef ENABLE_TONES +#define kPiezoPin 15 + +// we can use the EEProm to store a program during powerdown. This is +// 1keyboardyte on the '328, and 512 bytes on the '168. Enabling this here will +// allow for this funcitonality to work. Note that this only works on AVR +// arduino. Disable it for DUE/other devices. +#define ENABLE_EEPROM 1 +//#undef ENABLE_EEPROM + +// Sometimes, we connect with a slower device as the console. +// Set your console D0/D1 baud rate here (9600 baud default) +#define kConsoleBaud 9600 + +//////////////////////////////////////////////////////////////////////////////// +#ifdef ARDUINO +#ifndef RAMEND +// okay, this is a hack for now +// if we're in here, we're a DUE probably (ARM instead of AVR) + +#define RAMEND 4096-1 + +// turn off EEProm +#undef ENABLE_EEPROM +#undef ENABLE_TONES + +#else +// we're an AVR! + +// we're moving our data strings into progmem +#include +#endif + +// includes, and settings for Arduino-specific functionality +#ifdef ENABLE_EEPROM +#include /* NOTE: case sensitive */ +int eepos = 0; +#endif + + +#ifdef ENABLE_FILEIO +#include +#include /* needed as of 1.5 beta */ + +// Arduino-specific configuration +// set this to the card select for your SD shield +#define kSD_CS 4 + +#define kSD_Fail 0 +#define kSD_OK 1 + +File fp; +#endif + +// set up our RAM buffer size for program and user input +// NOTE: This number will have to change if you include other libraries. +#ifdef ARDUINO +#ifdef ENABLE_FILEIO +#define kRamFileIO (1100) /* approximate */ +#else +#define kRamFileIO (0) +#endif +#ifdef ENABLE_TONES +#define kRamTones (40) +#else +#define kRamTones (0) +#endif +#endif /* ARDUINO */ +#define kRamSize (RAMEND - 8803 - kRamFileIO - kRamTones) +//#define kRamSize 512 + +#ifndef ARDUINO +// Not arduino setup +#include +#include +#undef ENABLE_TONES + +// size of our program ram +#define kRamSize 4096 /* arbitrary */ + +#ifdef ENABLE_FILEIO +FILE * fp; +#endif +#endif + +#ifdef ENABLE_FILEIO +// functions defined elsehwere +void cmd_Files( void ); +#endif + +//////////////////// + +#ifndef boolean +#define boolean int +#define true 1 +#define false 0 +#endif +#endif + +#ifndef byte +typedef unsigned char byte; +#endif + +// some catches for AVR based text string stuff... +#ifndef PROGMEM +#define PROGMEM +#endif +#ifndef pgm_read_byte +#define pgm_read_byte( A ) *(A) +#endif + +//////////////////// + +#ifdef ENABLE_FILEIO +unsigned char * filenameWord(void); +static boolean sd_is_initialized = false; +#endif + +boolean inhibitOutput = false; +static boolean runAfterLoad = false; +static boolean triggerRun = false; + +// these will select, at runtime, where IO happens through for load/save +enum { + kStreamSerial = 0, + kStreamEEProm, + kStreamFile +}; +static unsigned char inStream = kStreamSerial; +static unsigned char outStream = kStreamSerial; + + +//////////////////////////////////////////////////////////////////////////////// +// ASCII Characters +#define CR '\r' +#define NL '\n' +#define LF 0x0a +#define TAB '\t' +#define BELL '\b' +#define SPACE ' ' +#define SQUOTE '\'' +#define DQUOTE '\"' +#define CTRLC 0x1B // Changed to ESC key (27 - 0x1B) +#define CTRLH 0x08 +#define CTRLS 0x13 +#define CTRLX 0x18 + +typedef short unsigned LINENUM; +#ifdef ARDUINO +#define ECHO_CHARS 1 +#else +#define ECHO_CHARS 0 +#endif + + +static unsigned char program[kRamSize]; +static const char * sentinel = "HELLO"; +static unsigned char *txtpos,*list_line; +static unsigned char expression_error; +static unsigned char *tempsp; + +/***********************************************************/ +// Keyword table and constants - the last character has 0x80 added to it +//static unsigned char keywords[] PROGMEM = { +static const unsigned char keywords[] PROGMEM = { + 'L','I','S','T'+0x80, + 'L','O','A','D'+0x80, + 'N','E','W'+0x80, + 'R','U','N'+0x80, + 'S','A','V','E'+0x80, + 'N','E','X','T'+0x80, + 'L','E','T'+0x80, + 'I','F'+0x80, + 'G','O','T','O'+0x80, + 'G','O','S','U','B'+0x80, + 'R','E','T','U','R','N'+0x80, + 'R','E','M'+0x80, + 'F','O','R'+0x80, + 'I','N','P','U','T'+0x80, + 'P','R','I','N','T'+0x80, + 'P','O','K','E'+0x80, + 'S','T','O','P'+0x80, + 'B','Y','E'+0x80, + 'F','I','L','E','S'+0x80, + 'M','E','M'+0x80, + '?'+ 0x80, + '\''+ 0x80, + 'A','W','R','I','T','E'+0x80, + 'D','W','R','I','T','E'+0x80, + 'D','E','L','A','Y'+0x80, + 'E','N','D'+0x80, + 'R','S','E','E','D'+0x80, + 'C','H','A','I','N'+0x80, +#ifdef ENABLE_TONES + 'T','O','N','E','W'+0x80, + 'T','O','N','E'+0x80, + 'N','O','T','O','N','E'+0x80, +#endif +#ifdef ARDUINO +#ifdef ENABLE_EEPROM + 'E','C','H','A','I','N'+0x80, + 'E','L','I','S','T'+0x80, + 'E','L','O','A','D'+0x80, + 'E','F','O','R','M','A','T'+0x80, + 'E','S','A','V','E'+0x80, +#endif +#endif + 0 +}; + +// by moving the command list to an enum, we can easily remove sections +// above and below simultaneously to selectively obliterate functionality. +enum { + KW_LIST = 0, + KW_LOAD, KW_NEW, KW_RUN, KW_SAVE, + KW_NEXT, KW_LET, KW_IF, + KW_GOTO, KW_GOSUB, KW_RETURN, + KW_REM, + KW_FOR, + KW_INPUT, KW_PRINT, + KW_POKE, + KW_STOP, KW_BYE, + KW_FILES, + KW_MEM, + KW_QMARK, KW_QUOTE, + KW_AWRITE, KW_DWRITE, + KW_DELAY, + KW_END, + KW_RSEED, + KW_CHAIN, +#ifdef ENABLE_TONES + KW_TONEW, KW_TONE, KW_NOTONE, +#endif +#ifdef ARDUINO +#ifdef ENABLE_EEPROM + KW_ECHAIN, KW_ELIST, KW_ELOAD, KW_EFORMAT, KW_ESAVE, +#endif +#endif + KW_DEFAULT /* always the final one*/ +}; + +struct stack_for_frame { + char frame_type; + char for_var; + short int terminal; + short int step; + unsigned char *current_line; + unsigned char *txtpos; +}; + +struct stack_gosub_frame { + char frame_type; + unsigned char *current_line; + unsigned char *txtpos; +}; + +//static unsigned char func_tab[] PROGMEM = { +static const unsigned char func_tab[] PROGMEM = { + 'P','E','E','K'+0x80, + 'A','B','S'+0x80, + 'A','R','E','A','D'+0x80, + 'D','R','E','A','D'+0x80, + 'R','N','D'+0x80, + 0 +}; +#define FUNC_PEEK 0 +#define FUNC_ABS 1 +#define FUNC_AREAD 2 +#define FUNC_DREAD 3 +#define FUNC_RND 4 +#define FUNC_UNKNOWN 5 + +//static unsigned char to_tab[] PROGMEM = { +static const unsigned char to_tab[] PROGMEM = { + 'T','O'+0x80, + 0 +}; + +//static unsigned char step_tab[] PROGMEM = { +static const unsigned char step_tab[] PROGMEM = { + 'S','T','E','P'+0x80, + 0 +}; + +//static unsigned char relop_tab[] PROGMEM = { +static const unsigned char relop_tab[] PROGMEM = { + '>','='+0x80, + '<','>'+0x80, + '>'+0x80, + '='+0x80, + '<','='+0x80, + '<'+0x80, + '!','='+0x80, + 0 +}; + +#define RELOP_GE 0 +#define RELOP_NE 1 +#define RELOP_GT 2 +#define RELOP_EQ 3 +#define RELOP_LE 4 +#define RELOP_LT 5 +#define RELOP_NE_BANG 6 +#define RELOP_UNKNOWN 7 + +//static unsigned char highlow_tab[] PROGMEM = { +static const unsigned char highlow_tab[] PROGMEM = { + 'H','I','G','H'+0x80, + 'H','I'+0x80, + 'L','O','W'+0x80, + 'L','O'+0x80, + 0 +}; +#define HIGHLOW_HIGH 1 +#define HIGHLOW_UNKNOWN 4 + +#define STACK_SIZE (sizeof(struct stack_for_frame)*5) +#define VAR_SIZE sizeof(short int) // Size of variables in bytes + +static unsigned char *stack_limit; +static unsigned char *program_start; +static unsigned char *program_end; +static unsigned char *stack; // Software stack for things that should go on the CPU stack +static unsigned char *variables_begin; +static unsigned char *current_line; +static unsigned char *sp1; +#define STACK_GOSUB_FLAG 'G' +#define STACK_FOR_FLAG 'F' +static unsigned char table_index; +static LINENUM linenum; + +static const unsigned char okmsg[] PROGMEM = "OK"; +static const unsigned char whatmsg[] PROGMEM = "What? "; +static const unsigned char howmsg[] PROGMEM = "How?"; +static const unsigned char sorrymsg[] PROGMEM = "Sorry!"; +static const unsigned char initmsg[] PROGMEM = "TinyBasic Plus " kVersion; +static const unsigned char memorymsg[] PROGMEM = " bytes free."; +#ifdef ARDUINO +#ifdef ENABLE_EEPROM +static const unsigned char eeprommsg[] PROGMEM = " EEProm bytes total."; +static const unsigned char eepromamsg[] PROGMEM = " EEProm bytes available."; +#endif +#endif +static const unsigned char breakmsg[] PROGMEM = "break!"; +static const unsigned char unimplimentedmsg[] PROGMEM = "Unimplemented"; +static const unsigned char backspacemsg[] PROGMEM = "\b \b"; +static const unsigned char indentmsg[] PROGMEM = " "; +static const unsigned char sderrormsg[] PROGMEM = "SD card error."; +static const unsigned char sdfilemsg[] PROGMEM = "SD file error."; +static const unsigned char dirextmsg[] PROGMEM = "(dir)"; +static const unsigned char slashmsg[] PROGMEM = "/"; +static const unsigned char spacemsg[] PROGMEM = " "; + +static int inchar(void); +static void outchar(unsigned char c); +static void line_terminator(void); +static short int expression(void); +static unsigned char breakcheck(void); +/***************************************************************************/ +static void ignore_blanks(void) +{ + while(*txtpos == SPACE || *txtpos == TAB) + txtpos++; +} + + +/***************************************************************************/ +static void scantable(const unsigned char *table) +{ + int i = 0; + table_index = 0; + while(1) + { + // Run out of table entries? + if(pgm_read_byte( table ) == 0) + return; + + // Do we match this character? + if(txtpos[i] == pgm_read_byte( table )) + { + i++; + table++; + } + else + { + // do we match the last character of keywork (with 0x80 added)? If so, return + if(txtpos[i]+0x80 == pgm_read_byte( table )) + { + txtpos += i+1; // Advance the pointer to following the keyword + ignore_blanks(); + return; + } + + // Forward to the end of this keyword + while((pgm_read_byte( table ) & 0x80) == 0) + table++; + + // Now move on to the first character of the next word, and reset the position index + table++; + table_index++; + ignore_blanks(); + i = 0; + } + } +} + +/***************************************************************************/ +static void pushb(unsigned char b) +{ + sp1--; + *sp1 = b; +} + +/***************************************************************************/ +static unsigned char popb() +{ + unsigned char b; + b = *sp1; + sp1++; + return b; +} + +/***************************************************************************/ +void printnum(int num) +{ + int digits = 0; + + if(num < 0) + { + num = -num; + outchar('-'); + } + do { + pushb(num%10+'0'); + num = num/10; + digits++; + } + while (num > 0); + + while(digits > 0) + { + outchar(popb()); + digits--; + } +} + +void printUnum(unsigned int num) +{ + int digits = 0; + + do { + pushb(num%10+'0'); + num = num/10; + digits++; + } + while (num > 0); + + while(digits > 0) + { + outchar(popb()); + digits--; + } +} + +/***************************************************************************/ +static unsigned short testnum(void) +{ + unsigned short num = 0; + ignore_blanks(); + + while(*txtpos>= '0' && *txtpos <= '9' ) + { + // Trap overflows + if(num >= 0xFFFF/10) + { + num = 0xFFFF; + break; + } + + num = num *10 + *txtpos - '0'; + txtpos++; + } + return num; +} + +/***************************************************************************/ +static unsigned char print_quoted_string(void) +{ + int i=0; + unsigned char delim = *txtpos; + if(delim != '"' && delim != '\'') + return 0; + txtpos++; + + // Check we have a closing delimiter + while(txtpos[i] != delim) + { + if(txtpos[i] == NL) + return 0; + i++; + } + + // Print the characters + while(*txtpos != delim) + { + outchar(*txtpos); + txtpos++; + } + txtpos++; // Skip over the last delimiter + + return 1; +} + + +/***************************************************************************/ +void printmsgNoNL(const unsigned char *msg) +{ + while( pgm_read_byte( msg ) != 0 ) { + outchar( pgm_read_byte( msg++ ) ); + }; +} + +/***************************************************************************/ +void printmsg(const unsigned char *msg) +{ + printmsgNoNL(msg); + line_terminator(); +} + +/***************************************************************************/ +static void getln(char prompt) +{ + outchar(prompt); + txtpos = program_end+sizeof(LINENUM); + + while(1) + { + char c = inchar(); + switch(c) + { + case NL: + //break; + case CR: + line_terminator(); + // Terminate all strings with a NL + txtpos[0] = NL; + return; + case CTRLH: + if(txtpos == program_end) + break; + txtpos--; + + printmsg(backspacemsg); + break; + default: + // We need to leave at least one space to allow us to shuffle the line into order + if(txtpos == variables_begin-2) + outchar(BELL); + else + { + txtpos[0] = c; + txtpos++; + outchar(c); + } + } + } +} + +/***************************************************************************/ +static unsigned char *findline(void) +{ + unsigned char *line = program_start; + while(1) + { + if(line == program_end) + return line; + + if(((LINENUM *)line)[0] >= linenum) + return line; + + // Add the line length onto the current address, to get to the next line; + line += line[sizeof(LINENUM)]; + } +} + +/***************************************************************************/ +static void toUppercaseBuffer(void) +{ + unsigned char *c = program_end+sizeof(LINENUM); + unsigned char quote = 0; + + while(*c != NL) + { + // Are we in a quoted string? + if(*c == quote) + quote = 0; + else if(*c == '"' || *c == '\'') + quote = *c; + else if(quote == 0 && *c >= 'a' && *c <= 'z') + *c = *c + 'A' - 'a'; + c++; + } +} + +/***************************************************************************/ +void printline() +{ + LINENUM line_num; + + line_num = *((LINENUM *)(list_line)); + list_line += sizeof(LINENUM) + sizeof(char); + + // Output the line */ + printnum(line_num); + outchar(' '); + while(*list_line != NL) + { + outchar(*list_line); + list_line++; + } + list_line++; + line_terminator(); +} + +/***************************************************************************/ +static short int expr4(void) +{ + // fix provided by Jurg Wullschleger wullschleger@gmail.com + // fixes whitespace and unary operations + ignore_blanks(); + + if( *txtpos == '-' ) { + txtpos++; + return -expr4(); + } + // end fix + + if(*txtpos == '0') + { + txtpos++; + return 0; + } + + if(*txtpos >= '1' && *txtpos <= '9') + { + short int a = 0; + do { + a = a*10 + *txtpos - '0'; + txtpos++; + } + while(*txtpos >= '0' && *txtpos <= '9'); + return a; + } + + // Is it a function or variable reference? + if(txtpos[0] >= 'A' && txtpos[0] <= 'Z') + { + short int a; + // Is it a variable reference (single alpha) + if(txtpos[1] < 'A' || txtpos[1] > 'Z') + { + a = ((short int *)variables_begin)[*txtpos - 'A']; + txtpos++; + return a; + } + + // Is it a function with a single parameter + scantable(func_tab); + if(table_index == FUNC_UNKNOWN) + goto expr4_error; + + unsigned char f = table_index; + + if(*txtpos != '(') + goto expr4_error; + + txtpos++; + a = expression(); + if(*txtpos != ')') + goto expr4_error; + txtpos++; + switch(f) + { + case FUNC_PEEK: + return program[a]; + + case FUNC_ABS: + if(a < 0) + return -a; + return a; + +#ifdef ARDUINO + case FUNC_AREAD: + pinMode( a, INPUT ); + return analogRead( a ); + case FUNC_DREAD: + pinMode( a, INPUT ); + return digitalRead( a ); +#endif + + case FUNC_RND: +#ifdef ARDUINO + return( random( a )); +#else + return( rand() % a ); +#endif + } + } + + if(*txtpos == '(') + { + short int a; + txtpos++; + a = expression(); + if(*txtpos != ')') + goto expr4_error; + + txtpos++; + return a; + } + +expr4_error: + expression_error = 1; + return 0; + +} + +/***************************************************************************/ +static short int expr3(void) +{ + short int a,b; + + a = expr4(); + + ignore_blanks(); // fix for eg: 100 a = a + 1 + + while(1) + { + if(*txtpos == '*') + { + txtpos++; + b = expr4(); + a *= b; + } + else if(*txtpos == '/') + { + txtpos++; + b = expr4(); + if(b != 0) + a /= b; + else + expression_error = 1; + } + else + return a; + } +} + +/***************************************************************************/ +static short int expr2(void) +{ + short int a,b; + + if(*txtpos == '-' || *txtpos == '+') + a = 0; + else + a = expr3(); + + while(1) + { + if(*txtpos == '-') + { + txtpos++; + b = expr3(); + a -= b; + } + else if(*txtpos == '+') + { + txtpos++; + b = expr3(); + a += b; + } + else + return a; + } +} +/***************************************************************************/ +static short int expression(void) +{ + short int a,b; + + a = expr2(); + + // Check if we have an error + if(expression_error) return a; + + scantable(relop_tab); + if(table_index == RELOP_UNKNOWN) + return a; + + switch(table_index) + { + case RELOP_GE: + b = expr2(); + if(a >= b) return 1; + break; + case RELOP_NE: + case RELOP_NE_BANG: + b = expr2(); + if(a != b) return 1; + break; + case RELOP_GT: + b = expr2(); + if(a > b) return 1; + break; + case RELOP_EQ: + b = expr2(); + if(a == b) return 1; + break; + case RELOP_LE: + b = expr2(); + if(a <= b) return 1; + break; + case RELOP_LT: + b = expr2(); + if(a < b) return 1; + break; + } + return 0; +} + +/***************************************************************************/ +void loop() +{ + unsigned char *start; + unsigned char *newEnd; + unsigned char linelen; + boolean isDigital; + boolean alsoWait = false; + int val; + +#ifdef ARDUINO +#ifdef ENABLE_TONES + noTone( kPiezoPin ); +#endif +#endif + + program_start = program; + program_end = program_start; + sp1 = program+sizeof(program); // Needed for printnum + stack_limit = program+sizeof(program)-STACK_SIZE; + variables_begin = stack_limit - 27*VAR_SIZE; + + // memory free + printnum(variables_begin-program_end); + printmsg(memorymsg); +#ifdef ARDUINO +#ifdef ENABLE_EEPROM + // eprom size + printnum( E2END+1 ); + printmsg( eeprommsg ); +#endif /* ENABLE_EEPROM */ +#endif /* ARDUINO */ + +warmstart: + // this signifies that it is running in 'direct' mode. + current_line = 0; + sp1 = program+sizeof(program); + printmsg(okmsg); + +prompt: + if( triggerRun ){ + triggerRun = false; + current_line = program_start; + goto execline; + } + + getln( '>' ); + toUppercaseBuffer(); + + txtpos = program_end+sizeof(unsigned short); + + // Find the end of the freshly entered line + while(*txtpos != NL) + txtpos++; + + // Move it to the end of program_memory + { + unsigned char *dest; + dest = variables_begin-1; + while(1) + { + *dest = *txtpos; + if(txtpos == program_end+sizeof(unsigned short)) + break; + dest--; + txtpos--; + } + txtpos = dest; + } + + // Now see if we have a line number + linenum = testnum(); + ignore_blanks(); + if(linenum == 0) + goto direct; + + if(linenum == 0xFFFF) + goto qhow; + + // Find the length of what is left, including the (yet-to-be-populated) line header + linelen = 0; + while(txtpos[linelen] != NL) + linelen++; + linelen++; // Include the NL in the line length + linelen += sizeof(unsigned short)+sizeof(char); // Add space for the line number and line length + + // Now we have the number, add the line header. + txtpos -= 3; + *((unsigned short *)txtpos) = linenum; + txtpos[sizeof(LINENUM)] = linelen; + + + // Merge it into the rest of the program + start = findline(); + + // If a line with that number exists, then remove it + if(start != program_end && *((LINENUM *)start) == linenum) + { + unsigned char *dest, *from; + unsigned tomove; + + from = start + start[sizeof(LINENUM)]; + dest = start; + + tomove = program_end - from; + while( tomove > 0) + { + *dest = *from; + from++; + dest++; + tomove--; + } + program_end = dest; + } + + if(txtpos[sizeof(LINENUM)+sizeof(char)] == NL) // If the line has no txt, it was just a delete + goto prompt; + + + + // Make room for the new line, either all in one hit or lots of little shuffles + while(linelen > 0) + { + unsigned int tomove; + unsigned char *from,*dest; + unsigned int space_to_make; + + space_to_make = txtpos - program_end; + + if(space_to_make > linelen) + space_to_make = linelen; + newEnd = program_end+space_to_make; + tomove = program_end - start; + + + // Source and destination - as these areas may overlap we need to move bottom up + from = program_end; + dest = newEnd; + while(tomove > 0) + { + from--; + dest--; + *dest = *from; + tomove--; + } + + // Copy over the bytes into the new space + for(tomove = 0; tomove < space_to_make; tomove++) + { + *start = *txtpos; + txtpos++; + start++; + linelen--; + } + program_end = newEnd; + } + goto prompt; + +unimplemented: + printmsg(unimplimentedmsg); + goto prompt; + +qhow: + printmsg(howmsg); + goto prompt; + +qwhat: + printmsgNoNL(whatmsg); + if(current_line != NULL) + { + unsigned char tmp = *txtpos; + if(*txtpos != NL) + *txtpos = '^'; + list_line = current_line; + printline(); + *txtpos = tmp; + } + line_terminator(); + goto prompt; + +qsorry: + printmsg(sorrymsg); + goto warmstart; + +run_next_statement: + while(*txtpos == ':') + txtpos++; + ignore_blanks(); + if(*txtpos == NL) + goto execnextline; + goto interperateAtTxtpos; + +direct: + txtpos = program_end+sizeof(LINENUM); + if(*txtpos == NL) + goto prompt; + +interperateAtTxtpos: + if(breakcheck()) + { + printmsg(breakmsg); + goto warmstart; + } + + scantable(keywords); + + switch(table_index) + { + case KW_DELAY: + { +#ifdef ARDUINO + expression_error = 0; + val = expression(); + delay( val ); + goto execnextline; +#else + goto unimplemented; +#endif + } + + case KW_FILES: + goto files; + case KW_LIST: + goto list; + case KW_CHAIN: + goto chain; + case KW_LOAD: + goto load; + case KW_MEM: + goto mem; + case KW_NEW: + if(txtpos[0] != NL) + goto qwhat; + program_end = program_start; + goto prompt; + case KW_RUN: + current_line = program_start; + goto execline; + case KW_SAVE: + goto save; + case KW_NEXT: + goto next; + case KW_LET: + goto assignment; + case KW_IF: + short int val; + expression_error = 0; + val = expression(); + if(expression_error || *txtpos == NL) + goto qhow; + if(val != 0) + goto interperateAtTxtpos; + goto execnextline; + + case KW_GOTO: + expression_error = 0; + linenum = expression(); + if(expression_error || *txtpos != NL) + goto qhow; + current_line = findline(); + goto execline; + + case KW_GOSUB: + goto gosub; + case KW_RETURN: + goto gosub_return; + case KW_REM: + case KW_QUOTE: + goto execnextline; // Ignore line completely + case KW_FOR: + goto forloop; + case KW_INPUT: + goto input; + case KW_PRINT: + case KW_QMARK: + goto print; + case KW_POKE: + goto poke; + case KW_END: + case KW_STOP: + // This is the easy way to end - set the current line to the end of program attempt to run it + if(txtpos[0] != NL) + goto qwhat; + current_line = program_end; + goto execline; + case KW_BYE: + // Leave the basic interperater + return; + + case KW_AWRITE: // AWRITE , HIGH|LOW + isDigital = false; + goto awrite; + case KW_DWRITE: // DWRITE , HIGH|LOW + isDigital = true; + goto dwrite; + + case KW_RSEED: + goto rseed; + +#ifdef ENABLE_TONES + case KW_TONEW: + alsoWait = true; + case KW_TONE: + goto tonegen; + case KW_NOTONE: + goto tonestop; +#endif + +#ifdef ARDUINO +#ifdef ENABLE_EEPROM + case KW_EFORMAT: + goto eformat; + case KW_ESAVE: + goto esave; + case KW_ELOAD: + goto eload; + case KW_ELIST: + goto elist; + case KW_ECHAIN: + goto echain; +#endif +#endif + + case KW_DEFAULT: + goto assignment; + default: + break; + } + +execnextline: + if(current_line == NULL) // Processing direct commands? + goto prompt; + current_line += current_line[sizeof(LINENUM)]; + +execline: + if(current_line == program_end) // Out of lines to run + goto warmstart; + txtpos = current_line+sizeof(LINENUM)+sizeof(char); + goto interperateAtTxtpos; + +#ifdef ARDUINO +#ifdef ENABLE_EEPROM +elist: + { + int i; + for( i = 0 ; i < (E2END +1) ; i++ ) + { + val = EEPROM.read( i ); + + if( val == '\0' ) { + goto execnextline; + } + + if( ((val < ' ') || (val > '~')) && (val != NL) && (val != CR)) { + outchar( '?' ); + } + else { + outchar( val ); + } + } + } + goto execnextline; + +eformat: + { + for( int i = 0 ; i < E2END ; i++ ) + { + if( (i & 0x03f) == 0x20 ) outchar( '.' ); + EEPROM.write( i, 0 ); + } + outchar( LF ); + } + goto execnextline; + +esave: + { + outStream = kStreamEEProm; + eepos = 0; + + // copied from "List" + list_line = findline(); + while(list_line != program_end) + printline(); + + // go back to standard output, close the file + outStream = kStreamSerial; + + goto warmstart; + } + + +echain: + runAfterLoad = true; + +eload: + // clear the program + program_end = program_start; + + // load from a file into memory + eepos = 0; + inStream = kStreamEEProm; + inhibitOutput = true; + goto warmstart; +#endif /* ENABLE_EEPROM */ +#endif + +input: + { + unsigned char var; + ignore_blanks(); + if(*txtpos < 'A' || *txtpos > 'Z') + goto qwhat; + var = *txtpos; + txtpos++; + ignore_blanks(); + if(*txtpos != NL && *txtpos != ':') + goto qwhat; + ((short int *)variables_begin)[var-'A'] = 99; + + goto run_next_statement; + } + +forloop: + { + unsigned char var; + short int initial, step, terminal; + ignore_blanks(); + if(*txtpos < 'A' || *txtpos > 'Z') + goto qwhat; + var = *txtpos; + txtpos++; + ignore_blanks(); + if(*txtpos != '=') + goto qwhat; + txtpos++; + ignore_blanks(); + + expression_error = 0; + initial = expression(); + if(expression_error) + goto qwhat; + + scantable(to_tab); + if(table_index != 0) + goto qwhat; + + terminal = expression(); + if(expression_error) + goto qwhat; + + scantable(step_tab); + if(table_index == 0) + { + step = expression(); + if(expression_error) + goto qwhat; + } + else + step = 1; + ignore_blanks(); + if(*txtpos != NL && *txtpos != ':') + goto qwhat; + + + if(!expression_error && *txtpos == NL) + { + struct stack_for_frame *f; + if(sp1 + sizeof(struct stack_for_frame) < stack_limit) + goto qsorry; + + sp1 -= sizeof(struct stack_for_frame); + f = (struct stack_for_frame *)sp1; + ((short int *)variables_begin)[var-'A'] = initial; + f->frame_type = STACK_FOR_FLAG; + f->for_var = var; + f->terminal = terminal; + f->step = step; + f->txtpos = txtpos; + f->current_line = current_line; + goto run_next_statement; + } + } + goto qhow; + +gosub: + expression_error = 0; + linenum = expression(); + if(!expression_error && *txtpos == NL) + { + struct stack_gosub_frame *f; + if(sp1 + sizeof(struct stack_gosub_frame) < stack_limit) + goto qsorry; + + sp1 -= sizeof(struct stack_gosub_frame); + f = (struct stack_gosub_frame *)sp1; + f->frame_type = STACK_GOSUB_FLAG; + f->txtpos = txtpos; + f->current_line = current_line; + current_line = findline(); + goto execline; + } + goto qhow; + +next: + // Fnd the variable name + ignore_blanks(); + if(*txtpos < 'A' || *txtpos > 'Z') + goto qhow; + txtpos++; + ignore_blanks(); + if(*txtpos != ':' && *txtpos != NL) + goto qwhat; + +gosub_return: + // Now walk up the stack frames and find the frame we want, if present + tempsp = sp1; + while(tempsp < program+sizeof(program)-1) + { + switch(tempsp[0]) + { + case STACK_GOSUB_FLAG: + if(table_index == KW_RETURN) + { + struct stack_gosub_frame *f = (struct stack_gosub_frame *)tempsp; + current_line = f->current_line; + txtpos = f->txtpos; + sp1 += sizeof(struct stack_gosub_frame); + goto run_next_statement; + } + // This is not the loop you are looking for... so Walk back up the stack + tempsp += sizeof(struct stack_gosub_frame); + break; + case STACK_FOR_FLAG: + // Flag, Var, Final, Step + if(table_index == KW_NEXT) + { + struct stack_for_frame *f = (struct stack_for_frame *)tempsp; + // Is the the variable we are looking for? + if(txtpos[-1] == f->for_var) + { + short int *varaddr = ((short int *)variables_begin) + txtpos[-1] - 'A'; + *varaddr = *varaddr + f->step; + // Use a different test depending on the sign of the step increment + if((f->step > 0 && *varaddr <= f->terminal) || (f->step < 0 && *varaddr >= f->terminal)) + { + // We have to loop so don't pop the stack + txtpos = f->txtpos; + current_line = f->current_line; + goto run_next_statement; + } + // We've run to the end of the loop. drop out of the loop, popping the stack + sp1 = tempsp + sizeof(struct stack_for_frame); + goto run_next_statement; + } + } + // This is not the loop you are looking for... so Walk back up the stack + tempsp += sizeof(struct stack_for_frame); + break; + default: + //printf("Stack is stuffed!\n"); + goto warmstart; + } + } + // Didn't find the variable we've been looking for + goto qhow; + +assignment: + { + short int value; + short int *var; + + if(*txtpos < 'A' || *txtpos > 'Z') + goto qhow; + var = (short int *)variables_begin + *txtpos - 'A'; + txtpos++; + + ignore_blanks(); + + if (*txtpos != '=') + goto qwhat; + txtpos++; + ignore_blanks(); + expression_error = 0; + value = expression(); + if(expression_error) + goto qwhat; + // Check that we are at the end of the statement + if(*txtpos != NL && *txtpos != ':') + goto qwhat; + *var = value; + } + goto run_next_statement; +poke: + { + short int value; + unsigned char *address; + + // Work out where to put it + expression_error = 0; + value = expression(); + if(expression_error) + goto qwhat; + address = (unsigned char *)value; + + // check for a comma + ignore_blanks(); + if (*txtpos != ',') + goto qwhat; + txtpos++; + ignore_blanks(); + + // Now get the value to assign + expression_error = 0; + value = expression(); + if(expression_error) + goto qwhat; + //printf("Poke %p value %i\n",address, (unsigned char)value); + // Check that we are at the end of the statement + if(*txtpos != NL && *txtpos != ':') + goto qwhat; + } + goto run_next_statement; + +list: + linenum = testnum(); // Retuns 0 if no line found. + + // Should be EOL + if(txtpos[0] != NL) + goto qwhat; + + // Find the line + list_line = findline(); + while(list_line != program_end) + printline(); + goto warmstart; + +print: + // If we have an empty list then just put out a NL + if(*txtpos == ':' ) + { + line_terminator(); + txtpos++; + goto run_next_statement; + } + if(*txtpos == NL) + { + goto execnextline; + } + + while(1) + { + ignore_blanks(); + if(print_quoted_string()) + { + ; + } + else if(*txtpos == '"' || *txtpos == '\'') + goto qwhat; + else + { + short int e; + expression_error = 0; + e = expression(); + if(expression_error) + goto qwhat; + printnum(e); + } + + // At this point we have three options, a comma or a new line + if(*txtpos == ',') + txtpos++; // Skip the comma and move onto the next + else if(txtpos[0] == ';' && (txtpos[1] == NL || txtpos[1] == ':')) + { + txtpos++; // This has to be the end of the print - no newline + break; + } + else if(*txtpos == NL || *txtpos == ':') + { + line_terminator(); // The end of the print statement + break; + } + else + goto qwhat; + } + goto run_next_statement; + +mem: + // memory free + printnum(variables_begin-program_end); + printmsg(memorymsg); +#ifdef ARDUINO +#ifdef ENABLE_EEPROM + { + // eprom size + printnum( E2END+1 ); + printmsg( eeprommsg ); + + // figure out the memory usage; + val = ' '; + int i; + for( i=0 ; (i<(E2END+1)) && (val != '\0') ; i++ ) { + val = EEPROM.read( i ); + } + printnum( (E2END +1) - (i-1) ); + + printmsg( eepromamsg ); + } +#endif /* ENABLE_EEPROM */ +#endif /* ARDUINO */ + goto run_next_statement; + + + /*************************************************/ + +#ifdef ARDUINO +awrite: // AWRITE ,val +dwrite: + { + short int pinNo; + short int value; + unsigned char *txtposBak; + + // Get the pin number + expression_error = 0; + pinNo = expression(); + if(expression_error) + goto qwhat; + + // check for a comma + ignore_blanks(); + if (*txtpos != ',') + goto qwhat; + txtpos++; + ignore_blanks(); + + + txtposBak = txtpos; + scantable(highlow_tab); + if(table_index != HIGHLOW_UNKNOWN) + { + if( table_index <= HIGHLOW_HIGH ) { + value = 1; + } + else { + value = 0; + } + } + else { + + // and the value (numerical) + expression_error = 0; + value = expression(); + if(expression_error) + goto qwhat; + } + pinMode( pinNo, OUTPUT ); + if( isDigital ) { + digitalWrite( pinNo, value ); + } + else { + analogWrite( pinNo, value ); + } + } + goto run_next_statement; +#else +pinmode: // PINMODE , I/O +awrite: // AWRITE ,val +dwrite: + goto unimplemented; +#endif + + /*************************************************/ +files: + // display a listing of files on the device. + // version 1: no support for subdirectories + +#ifdef ENABLE_FILEIO + cmd_Files(); + goto warmstart; +#else + goto unimplemented; +#endif // ENABLE_FILEIO + + +chain: + runAfterLoad = true; + +load: + // clear the program + program_end = program_start; + + // load from a file into memory +#ifdef ENABLE_FILEIO + { + unsigned char *filename; + + // Work out the filename + expression_error = 0; + filename = filenameWord(); + if(expression_error) + goto qwhat; + +#ifdef ARDUINO + // Arduino specific + if( !SD.exists( (char *)filename )) + { + printmsg( sdfilemsg ); + } + else { + + fp = SD.open( (const char *)filename ); + inStream = kStreamFile; + inhibitOutput = true; + } +#else // ARDUINO + // Desktop specific +#endif // ARDUINO + // this will kickstart a series of events to read in from the file. + + } + goto warmstart; +#else // ENABLE_FILEIO + goto unimplemented; +#endif // ENABLE_FILEIO + + + +save: + // save from memory out to a file +#ifdef ENABLE_FILEIO + { + unsigned char *filename; + + // Work out the filename + expression_error = 0; + filename = filenameWord(); + if(expression_error) + goto qwhat; + +#ifdef ARDUINO + // remove the old file if it exists + if( SD.exists( (char *)filename )) { + SD.remove( (char *)filename ); + } + + // open the file, switch over to file output + fp = SD.open( (const char *)filename, FILE_WRITE ); + outStream = kStreamFile; + + // copied from "List" + list_line = findline(); + while(list_line != program_end) + printline(); + + // go back to standard output, close the file + outStream = kStreamSerial; + + fp.close(); +#else // ARDUINO + // desktop +#endif // ARDUINO + goto warmstart; + } +#else // ENABLE_FILEIO + goto unimplemented; +#endif // ENABLE_FILEIO + +rseed: + { + short int value; + + //Get the pin number + expression_error = 0; + value = expression(); + if(expression_error) + goto qwhat; + +#ifdef ARDUINO + randomSeed( value ); +#else // ARDUINO + srand( value ); +#endif // ARDUINO + goto run_next_statement; + } + +#ifdef ENABLE_TONES +tonestop: + noTone( kPiezoPin ); + goto run_next_statement; + +tonegen: + { + // TONE freq, duration + // if either are 0, tones turned off + short int freq; + short int duration; + + //Get the frequency + expression_error = 0; + freq = expression(); + if(expression_error) + goto qwhat; + + ignore_blanks(); + if (*txtpos != ',') + goto qwhat; + txtpos++; + ignore_blanks(); + + + //Get the duration + expression_error = 0; + duration = expression(); + if(expression_error) + goto qwhat; + + if( freq == 0 || duration == 0 ) + goto tonestop; + + tone( kPiezoPin, freq, duration ); + if( alsoWait ) { + delay( duration ); + alsoWait = false; + } + goto run_next_statement; + } +#endif /* ENABLE_TONES */ +} + +// returns 1 if the character is valid in a filename +static int isValidFnChar( char c ) +{ + if( c >= '0' && c <= '9' ) return 1; // number + if( c >= 'A' && c <= 'Z' ) return 1; // LETTER + if( c >= 'a' && c <= 'z' ) return 1; // letter (for completeness) + if( c == '_' ) return 1; + if( c == '+' ) return 1; + if( c == '.' ) return 1; + if( c == '~' ) return 1; // Window~1.txt + + return 0; +} + +unsigned char * filenameWord(void) +{ + // SDL - I wasn't sure if this functionality existed above, so I figured i'd put it here + unsigned char * ret = txtpos; + expression_error = 0; + + // make sure there are no quotes or spaces, search for valid characters + //while(*txtpos == SPACE || *txtpos == TAB || *txtpos == SQUOTE || *txtpos == DQUOTE ) txtpos++; + while( !isValidFnChar( *txtpos )) txtpos++; + ret = txtpos; + + if( *ret == '\0' ) { + expression_error = 1; + return ret; + } + + // now, find the next nonfnchar + txtpos++; + while( isValidFnChar( *txtpos )) txtpos++; + if( txtpos != ret ) *txtpos = '\0'; + + // set the error code if we've got no string + if( *ret == '\0' ) { + expression_error = 1; + } + + return ret; +} + +/***************************************************************************/ +static void line_terminator(void) +{ + outchar(NL); + outchar(CR); +} + +/***********************************************************/ +void setup() +{ +#ifdef ARDUINO + TV.begin(PAL, 720, 480); + TV.select_font(font6x8); + TV.set_hbi_hook(keyboard.begin()); + + //Serial1.begin(kConsoleBaud); + //Serial1.println(sentinel); + + //TV.println( sentinel ); + printmsg(initmsg); + +#ifdef ENABLE_FILEIO + initSD(); + +#ifdef ENABLE_AUTORUN + if( SD.exists( kAutorunFilename )) { + program_end = program_start; + fp = SD.open( kAutorunFilename ); + inStream = kStreamFile; + inhibitOutput = true; + runAfterLoad = true; + } +#endif /* ENABLE_AUTORUN */ + +#endif /* ENABLE_FILEIO */ + +#ifdef ENABLE_EEPROM +#ifdef ENABLE_EAUTORUN + // read the first byte of the eeprom. if it's a number, assume it's a program we can load + int val = EEPROM.read(0); + if( val >= '0' && val <= '9' ) { + program_end = program_start; + inStream = kStreamEEProm; + eepos = 0; + inhibitOutput = true; + runAfterLoad = true; + } +#endif /* ENABLE_EAUTORUN */ +#endif /* ENABLE_EEPROM */ + +#endif /* ARDUINO */ +} + + +/***********************************************************/ +static unsigned char breakcheck(void) +{ +#ifdef ARDUINO + if(keyboard.available()) + return keyboard.read() == CTRLC; + //else if (Serial1.available()) + //return Serial1.read() == CTRLC; + return 0; +#else +#ifdef __CONIO__ + if(keyboardhit()) + return getch() == CTRLC; + else +#endif + return 0; +#endif +} +/***********************************************************/ +static int inchar() +{ + int v; +#ifdef ARDUINO + + switch( inStream ) { + case( kStreamFile ): +#ifdef ENABLE_FILEIO + v = fp.read(); + if( v == NL ) v=CR; // file translate + if( !fp.available() ) { + fp.close(); + goto inchar_loadfinish; + } + return v; +#else +#endif + break; + case( kStreamEEProm ): +#ifdef ENABLE_EEPROM +#ifdef ARDUINO + v = EEPROM.read( eepos++ ); + if( v == '\0' ) { + goto inchar_loadfinish; + } + return v; +#endif +#else + inStream = kStreamSerial; + return NL; +#endif + break; + case( kStreamSerial ): + default: + while(1) + { + if(keyboard.available()) + return keyboard.read(); + //else if (Serial1.available()) + //return Serial1.read(); + } + } + +inchar_loadfinish: + inStream = kStreamSerial; + inhibitOutput = false; + + if( runAfterLoad ) { + runAfterLoad = false; + triggerRun = true; + } + return NL; // trigger a prompt. + +#else + // otherwise. desktop! + int got = getchar(); + + // translation for desktop systems + if( got == LF ) got = CR; + + return got; +#endif +} + +/***********************************************************/ +static void outchar(unsigned char c) +{ + if( inhibitOutput ) return; + +#ifdef ARDUINO + #ifdef ENABLE_FILEIO + if( outStream == kStreamFile ) { + // output to a file + fp.write( c ); + } + else + #endif + #ifdef ARDUINO + #ifdef ENABLE_EEPROM + if( outStream == kStreamEEProm ) { + EEPROM.write( eepos++, c ); + } + else + #endif /* ENABLE_EEPROM */ + #endif /* ARDUINO */ + TV.print((char)c); + //Serial1.write(c); + +#else + putchar(c); +#endif +} + +/***********************************************************/ +/* SD Card helpers */ + +#if ARDUINO && ENABLE_FILEIO + +static int initSD( void ) +{ + // if the card is already initialized, we just go with it. + // there is no support (yet?) for hot-swap of SD Cards. if you need to + // swap, pop the card, reset the arduino.) + + if( sd_is_initialized == true ) return kSD_OK; + + // due to the way the SD Library works, pin 10 always needs to be + // an output, even when your shield uses another line for CS + pinMode(4, OUTPUT); // change this to 53 on a mega + + if( !SD.begin( kSD_CS )) { + // failed + printmsg( sderrormsg ); + return kSD_Fail; + } + // success - quietly return 0 + sd_is_initialized = true; + + // and our file redirection flags + outStream = kStreamSerial; + inStream = kStreamSerial; + inhibitOutput = false; + + return kSD_OK; +} +#endif + +#if ENABLE_FILEIO +void cmd_Files( void ) +{ + File dir = SD.open( "/" ); + dir.seek(0); + + while( true ) { + File entry = dir.openNextFile(); + if( !entry ) { + entry.close(); + break; + } + + // common header + printmsgNoNL( indentmsg ); + printmsgNoNL( (const unsigned char *)entry.name() ); + if( entry.isDirectory() ) { + printmsgNoNL( slashmsg ); + } + + if( entry.isDirectory() ) { + // directory ending + for( int i=strlen( entry.name()) ; i<16 ; i++ ) { + printmsgNoNL( spacemsg ); + } + printmsgNoNL( dirextmsg ); + } + else { + // file ending + for( int i=strlen( entry.name()) ; i<17 ; i++ ) { + printmsgNoNL( spacemsg ); + } + printUnum( entry.size() ); + } + line_terminator(); + entry.close(); + } + dir.close(); +} +#endif + diff --git a/trunk/Arduino/Single_Chip_Computer/Single_Chip_Computer_1.14.hex b/trunk/Arduino/Single_Chip_Computer/Single_Chip_Computer_1.14.hex new file mode 100644 index 00000000..187dfdf6 --- /dev/null +++ b/trunk/Arduino/Single_Chip_Computer/Single_Chip_Computer_1.14.hex @@ -0,0 +1,1406 @@ +:100000000C9459030C9484030C9484030C9484037F +:100010000C9484030C9484030C9484030C94840344 +:100020000C9484030C941D280C9484030C94840376 +:100030000C9484030C9484030C9484030C9439155D +:100040000C9484030C9484030C94DA220C9484039F +:100050000C9439250C94CF250C9484030C948403C0 +:100060000C9484030C9484030C9484030C948403F4 +:100070000C9472250C941C260C9484030C94840319 +:100080000C9484030C9484030C948403340EA70F03 +:10009000950AA60A000AEE0CA60DAB0AC10A980C36 +:1000A0000E0DFC0AE30BAE0B980EF20DEB0A1510C9 +:1000B000000A1E0F980EFC0A4E0F850A880AEB0AEA +:1000C000B00FA30F810AC20FBE0F8D0B1D0B930B38 +:1000D000400B590BA60D54696E7942617369632018 +:1000E000506C75732076302E31340020627974653F +:1000F0007320667265652E0020454550726F6D2035 +:10010000627974657320746F74616C2E004F4B00BC +:10011000556E696D706C656D656E74656400486FD1 +:10012000773F00576861743F2000536F72727921E6 +:1001300000627265616B21004C4953D44C4F41C43D +:100140004E45D75255CE534156C54E4558D44C45D1 +:10015000D449C6474F54CF474F5355C252455455C3 +:1001600052CE5245CD464FD2494E5055D4505249A9 +:100170004ED4504F4BC553544FD04259C546494CAD +:1001800045D34D45CDBFA74157524954C544575259 +:100190004954C544454C41D9454EC452534545C4C4 +:1001A00043484149CE544F4E45D7544F4EC54E4F0C +:1001B000544F4EC54543484149CE454C4953D4451B +:1001C0004C4F41C445464F524D41D445534156C50D +:1001D0000054CF00535445D00020454550726F6DF8 +:1001E00020627974657320617661696C61626C6507 +:1001F0002E00484947C848C94C4FD74CCF0008206B +:1002000008003EBD3CBEBEBD3CBDBC21BD0050454E +:1002100045CB4142D341524541C444524541C45269 +:100220004EC400060820000000000000000040400E +:1002300040404000400050505000000000000000CE +:1002400050F850F850002070A0702870200000C8AE +:10025000D0205898000020508040A890680040406E +:1002600040000000000010204040402010004020CE +:100270001010102040001038100000000000002076 +:1002800020F82020000000000000001010000000F6 +:1002900000F800000000000000000010000000084E +:1002A0001020408000007088A8A88870000020609E +:1002B0002020207000007088102040F80000F81006 +:1002C000201088700000909090F810100000F880C6 +:1002D000F008887000007080F08888700000F808CE +:1002E000102040800000708870888870000070883E +:1002F0008878087000000000200000200000000046 +:1003000020002020400000186080601800000000DD +:1003100078007800000000C0300830C00000609015 +:10032000202000200000708898A89088700020503D +:1003300088F888880000F088F08888F000007088CD +:10034000808088700000F088888888F00000F8803D +:10035000F88080F80000F880F080808000007088CD +:100360008098887000008888F8888888000070204D +:10037000202020700000381010109060000088903D +:10038000E0A0908800008080808080F8000088D8FD +:10039000A8A8888800008888C8A898880000708865 +:1003A000888888700000F088F08080800000708865 +:1003B00088A890680000F088F0A0908800007880FD +:1003C000700808F00000F820202020200000888815 +:1003D0008888887000008888888850200000888875 +:1003E000A8A8A8500000885020508888000088885D +:1003F000502020200000F808102040F80000E08085 +:10040000808080E000000080402010080000380854 +:10041000080808380000205000000000000000001C +:1004200000000000F80080400000000000000060B4 +:100430001070906000008080E09090E0000000006C +:10044000708080700000101070909070000000604C +:1004500090F0807000003040E040404000000060BC +:100460009070101060008080E0909090000020005C +:1004700020202070000010003010101060008090CC +:10048000A0C0A0900000602020202070000000008C +:1004900050A8A8A800000000F0888888000000008C +:1004A00060909060000000006090F080800000008C +:1004B0006090F01010000000B04840400000003094 +:1004C0004020106000004040E0404040000000003C +:1004D000909090600000000088885020000000008C +:1004E00088A8A85000000088502050880000000014 +:1004F0009090604080000000F02040F0000020401C +:10050000408040402000202020202020200020107B +:1005100010081010200040A810000000000000008B +:1005200000000000000000000000000000000000CB +:10053000000000097E0000000000005121000000C2 +:100540005A5341574000004358444524230000209B +:10055000564654522500004E424847595E0000005E +:100560004D4A55262A00003C4B494F292800003EA1 +:100570003F4C3A505F00000022007B2B000000003F +:100580000D7D007C00000000000000007F000031B5 +:10059000003437000000302E323536381B00002B77 +:1005A000332D2A3900000000000000000000000088 +:1005B0000000000000000009600000000000007161 +:1005C000310000007A73617732000063786465342B +:1005D00033000020766674723500006E62686779B9 +:1005E000360000006D6A75373800002C6B696F307B +:1005F0003900002E2F6C3B702D00000027005B3D62 +:10060000000000000D5D005C000000000000000024 +:100610007F000031003437000000302E323536388C +:100620001B00002B332D2A390000000000000000C1 +:100630002100240027002A000000220025002800B5 +:100640002B000000200023002600290002020202E5 +:100650000202020204040404040404040303030366 +:100660000303030301010101010101010102040867 +:10067000102040800102040810204080010204087C +:10068000102040800102040810204080000000017A +:100690000200080900000000040307060000000033 +:1006A00000000000000000000000000002000E1B1F +:1006B000112711241FBECFEFD0E4DEBFCDBF11E064 +:1006C000A0E0B1E0E0EAF7E500E00BBF02C0079070 +:1006D0000D92AC32B107D9F71BBE13E2ACE2B1E028 +:1006E00001C01D92AD3DB107E1F716E0C2EBD6E0C7 +:1006F00004C02297FE010E94932BCE3AD107C9F77E +:100700000E94A7270C94CE2B0C940000CF93DF936C +:10071000BC018230910510F462E070E0A091DB230F +:10072000B091DC23ED01E0E0F0E040E050E021C0DA +:10073000888199818617970769F48A819B81309710 +:1007400019F09383828304C09093DC238093DB238E +:10075000FE0134C06817790738F44115510519F0C6 +:100760008417950708F4AC01FE018A819B819C01E6 +:10077000E9012097E9F641155105A9F1CA01861B47 +:10078000970B049708F4BA01E0E0F0E02AC08D91DD +:100790009C91119784179507F9F46417750781F4F4 +:1007A00012968D919C911397309719F093838283C1 +:1007B00004C09093DC238093DB23FD0132964CC070 +:1007C000CA01861B970BFD01E80FF91F6193719316 +:1007D00002978D939C9340C0FD01828193819C017F +:1007E000D9011097A1F68091D9239091DA23892B12 +:1007F00041F480910201909103019093DA23809358 +:10080000D92340910401509105014115510541F44E +:100810004DB75EB78091000190910101481B590BC3 +:100820002091D9233091DA23CA01821B930B8617BA +:10083000970780F0AB014E5F5F4F8417950750F02C +:10084000420F531F5093DA234093D923F901619348 +:10085000719302C0E0E0F0E0CF01DF91CF91089505 +:10086000CF93DF93009709F450C0EC0122971B82CD +:100870001A82A091DB23B091DC23109709F140E0AC +:1008800050E0AC17BD0708F1BB83AA83FE0121919C +:100890003191E20FF31FAE17BF0779F48D919C9150 +:1008A0001197280F391F2E5F3F4F398328831296E7 +:1008B0008D919C9113979B838A834115510571F407 +:1008C000D093DC23C093DB2320C012968D919C91A2 +:1008D0001397AD01009711F0DC01D3CFFA01D38358 +:1008E000C28321913191E20FF31FCE17DF0769F424 +:1008F00088819981280F391F2E5F3F4FFA0131837C +:1009000020838A819B8193838283DF91CF91089595 +:10091000A0E0B0E0EEE8F4E00C949F2BEC01A8809E +:10092000B980CA80DB80A114B104C104D10441F4B0 +:1009300084E2A82E89EDB82E8BE5C82E87E0D82E4C +:10094000C601B5012DE133EF41E050E00E94762B66 +:1009500027EA31E440E050E00E940E2B7B018C013D +:10096000C601B5012DE133EF41E050E00E94762B46 +:10097000CA01B9012CEE34EF4FEF5FEF0E940E2B4E +:100980006E0D7F1D801F911F97FF04C06150704046 +:1009900080409048688379838A839B839B01AC0164 +:1009A0005F77B901CA01CDB7DEB7EAE00C94BB2B83 +:1009B0000E948804089586E091E00E9488040895CA +:1009C00060930601709307018093080190930901D9 +:1009D00008951F93AC011092C31FA0913E01B091E6 +:1009E0003F0160E070E010E004C04F5F5F4F60E0E7 +:1009F00070E0FA0124912223A9F1FD01E60FF71F0F +:100A00008081821729F46F5F7F4F4F5F5F4FF1CF77 +:100A100090E080589F4F30E082179307A1F4109325 +:100A2000C31FFB013196EA0FFB1F01C03196808185 +:100A30008032E1F38930D1F3E0933E01F0933F013E +:100A400017C04F5F5F4FFA01849187FFFACF1F5F96 +:100A5000FD0101C03196DF0180818032D9F38930F8 +:100A6000C9F3C3CF1093C31FB0933F01A0933E01BE +:100A70001F910895482F8091350190913601892B5F +:100A8000E1F48091C41F813089F460913301709149 +:100A900034016F5F7F4F7093340160933301615075 +:100AA000704083E190E20E94021B08958DE291E084 +:100AB000642F40E050E00E94BD1308958AE00E9438 +:100AC0003A058DE00E943A050895CF93DF93EC013B +:100AD00005C02196F90184910E943A059E01FE010C +:100AE00084918823B1F7DF91CF9108950E94650525 +:100AF0000E945E0508958DE291E061E040ED20EEF8 +:100B00000E94CE128DE291E063E272E00E94FD123B +:100B10008CE291E00E94DE1ABC018DE291E00E941D +:100B2000C91286ED90E00E94760583E190E260E0D4 +:100B300070E00E94FB1A90E0C0970A97C8F4809179 +:100B400037019091380190933A018093390181E007 +:100B500080933B01109234011092330181E090E0C8 +:100B6000909336018093350190933D0180933C0131 +:100B700008950F931F93CF93DF93EC0197FF06C067 +:100B8000D095C195DF4F8DE20E943A05E091B51FE7 +:100B9000F091B61F00E010E0CE016AE070E00E9424 +:100BA000412B805D8293CE016AE070E00E94412B70 +:100BB000EB010F5F1F4F1616170674F3F093B61F65 +:100BC000E093B51FE091B51FF091B61F8191F093AE +:100BD000B61FE093B51F0E943A050150104091F7EF +:100BE000DF91CF911F910F910895E091C11FF09176 +:100BF000C21F808191813396F093C21FE093C11F81 +:100C00000E94B90580E20E943A050BC00E943A0595 +:100C10008091C11F9091C21F01969093C21F809333 +:100C2000C11FE091C11FF091C21F80818A3071F70E +:100C30003196F093C21FE093C11F0E945E05089594 +:100C40001F93CF93DF93E0913E01F0913F0101C0EC +:100C50003196DF0190819032D9F39930C9F3F09346 +:100C60003F01E0933E019D3261F43196F0933F01E4 +:100C7000E0933E010E94200622273327281B390BD0 +:100C8000C2C0903331F43196F0933F01E0933E01BE +:100C9000B8C0892F81538930D8F420E030E0C901F1 +:100CA00063E0880F991F6A95E1F7220F331F820FC7 +:100CB000931F2D9130E020533040280F391F8C9125 +:100CC00080538A3060F3B0933F01A0933E019BC0F4 +:100CD000892F81548A3108F075C09F012F5F3F4FE3 +:100CE000818181548A3198F0892F90E0815490401D +:100CF000880F991FE091B91FF091BA1FE80FF91FF3 +:100D00008081918130933F0120933E0148C08EE065 +:100D100092E00E94E9041091C31F153009F46EC0DF +:100D2000E0913E01F0913F018081883209F066C078 +:100D30003196F0933F01E0933E010E948007EC0161 +:100D4000E0913E01F0913F018081893209F056C067 +:100D50003196F0933F01E0933E011230C9F0133019 +:100D600028F4112341F0113069F50BC01330C9F09C +:100D7000143041F51EC0CF5BDE4F8881282F30E054 +:100D800042C09E01D7FF3FC0309521953F4F3BC0E9 +:100D90008C2F60E00E9471248C2F0E94D1239C0133 +:100DA00032C08C2F60E00E9471248C2F0E94082595 +:100DB000F6CFBE01882777FD8095982F0E94E42A00 +:100DC0009B0121C0E0913E01F0913F01808188327A +:100DD000A9F43196F0933F01E0933E010E94800711 +:100DE0009C01E0913E01F0913F018081893231F414 +:100DF0003196F0933F01E0933E0105C081E080937E +:100E0000400120E030E0C901DF91CF911F910895AA +:100E10001F93CF93DF930E942006EC01E0913E01E7 +:100E2000F0913F0101C0319680818032E1F3893039 +:100E3000D1F3E0933E01F0933F0111E0E0913E01D8 +:100E4000F0913F0180818A3281F43196F0933F0125 +:100E5000E0933E010E9420069E01289FE001299F09 +:100E6000D00D389FD00D1124E9CF8F3291F43196F7 +:100E7000F0933F01E0933E010E942006BC010097E1 +:100E800029F0CE010E94412BEB01D8CF10934001F5 +:100E9000D5CFCE01DF91CF911F910895CF93DF93EE +:100EA000E0913E01F0913F01E081ED3231F0EB3213 +:100EB00021F00E940807EC0102C0C0E0D0E0E09100 +:100EC0003E01F0913F0180818D3251F43196F093D3 +:100ED0003F01E0933E010E940807C81BD90BEFCFEA +:100EE0008B3251F43196F0933F01E0933E010E9422 +:100EF0000807C80FD91FE3CFCE01DF91CF91089526 +:100F0000CF93DF930E944E07EC018091400188232C +:100F100009F046C082E092E00E94E9048091C31F7C +:100F20008730F1F1833029F1843028F4813099F051 +:100F30008230C0F409C0853051F1853008F1863027 +:100F400051F0C0E0D0E02CC00E944E0720E0C8174E +:100F5000D90724F122C00E944E0720E0C817D90704 +:100F6000E1F41CC00E944E0720E08C179D07B4F4EA +:100F700014C00E944E0720E0C817D90779F40DC0AD +:100F80000E944E0720E08C179D0744F006C00E9487 +:100F90004E0720E0C817D9070CF421E0C22FD0E09B +:100FA000CE01DF91CF9108953F924F925F926F9261 +:100FB0007F928F929F92AF92BF92CF92DF92EF92E9 +:100FC000FF920F931F93CF93DF938FE00E94062829 +:100FD00081E491E0909338018093370190933A0136 +:100FE0008093390105EB1FE11093B61F0093B51FE5 +:100FF00083E89FE19093B81F8093B71F8DE49FE132 +:101000009093BA1F8093B91F8CE09EE10E94B905AE +:101010008BEE90E00E94760580E090E10E94B90599 +:1010200088EF90E00E947605CC24DD24502E412EDE +:101030001092BC1F1092BB1F5092B51F4092B61F5A +:101040008DE091E00E947605A3E68A2E912CF6E4CD +:101050003F2EE1E06E2EE0E17E2E71E0A72EB12C56 +:101060008091BD1F9091BE1F892B29F01092BE1F49 +:101070001092BD1F6BC28EE30E943A058091390128 +:1010800090913A01029690933F0180933E018091A6 +:101090003B01813019F08230B9F422C060913301F4 +:1010A000709134016F5F7F4F70933401609333010F +:1010B0006150704083E190E20E94FB1A282F30E0DB +:1010C0002115310569F022C08CE291E00E94BD1A21 +:1010D0008823D1F38CE291E00E94CA1A9C0116C0C9 +:1010E00010923B01109236011092350180913C0123 +:1010F00090913D01892B41F010923D0110923C01ED +:10110000B092BE1FA092BD1F2AE030E02A3049F005 +:101110002D3039F0E0913E01F0913F01283009F582 +:101120000EC00E945E05E0913E01F0913F018AE011 +:101130008083E0913901F0913A0190E03DC08091C7 +:10114000390190913A01E817F90709F4A0CF3197D6 +:10115000F0933F01E0933E018EEF91E00E9476050F +:1011600096CF8091B91F9091BA1F0297E817F9079F +:1011700011F488E00BC0208380913E0190913F01E3 +:10118000019690933F0180933E01822F0E943A0581 +:101190007ECF891761F0823269F0873259F0992346 +:1011A00041F4813630F08B3720F48052828380E026 +:1011B00001C0892F3196982F82818A3051F7809112 +:1011C000390190913A01029690933F0180933E013C +:1011D00005C03196F0933F01E0933E01E0913E015E +:1011E000F0913F0180818A30A1F7A091B91FB091A1 +:1011F000BA1F1197E0913E01F0913F0180818C93DD +:1012000020913E0130913F018091390190913A0146 +:1012100002962817390741F011972150304030933A +:101220003F0120933E01E6CFB0933F01A0933E01E2 +:1012300005C03196F0933F01E0933E01E0913E01FD +:10124000F0913F0180818032A1F3893091F320E059 +:1012500030E01CC089E12939380718F02FEF3FEF43 +:101260001EC0C90163E0880F991F6A95E1F7220F3C +:10127000331F820F931F242F30E020533040280F5C +:10128000391F3196F0933F01E0933E01E0913E011A +:10129000F0913F014081842F80538A30D8F23093FF +:1012A000C01F2093BF1F05C01196B0933F01A093AC +:1012B0003E01A0913E01B0913F018C918032A1F39B +:1012C000893091F38091BF1F9091C01F009709F45E +:1012D000E5C08F5F9F4F09F496C090E001C09F5F0B +:1012E000FD01E90FF11D80818A30C9F7192F1C5FBC +:1012F000FD013397F0933F01E0933E018091BF1FC2 +:101300009091C01F918380831283A0913701B09187 +:1013100038014091390150913A012091BF1F30911D +:10132000C01FA417B50729F18D919C9111978217C1 +:10133000930708F075C612968C911297A80FB11DED +:10134000F0CF12968C911297FD01E80FF11D4E1B04 +:101350005F0BED019A0104C08191899321503040C7 +:1013600021153105C9F74A0F5B1F50933A0140938D +:101370003901E0913E01F0913F0183818A30E9F526 +:101380006FCEE0913901F0913A0180913E01909148 +:101390003F018E1B9F0B412F50E08417950708F4E7 +:1013A000AC01BF01640F751F9F012A1B3B0BEB01B2 +:1013B00004C082918A932150304021153105C9F72C +:1013C000ED0111C0E0913E01F0913F0180818993D0 +:1013D00080913E0190913F01019690933F0180934F +:1013E0003E012F5F3F4F2417350760F3141BA40FF6 +:1013F000B51F70933A0160933901112311F630CE75 +:1014000080E191E002C08EE191E00E94760528CE55 +:1014100083E291E00E9465058091BB1F9091BC1F03 +:10142000892BC1F0E0913E01F0913F0110811A300B +:1014300011F08EE580838091BB1F9091BC1F90932B +:10144000C21F8093C11F0E94F505E0913E01F091FB +:101450003F0110830E945E0503CE8AE291E03AC00C +:101460003196F0933F01E0933E01E0913E01F0910F +:101470003F0180818A33A1F305C03196F0933F018B +:10148000E0933E01E0913E01F0913F018081803286 +:10149000A1F3893091F38A3079F4AEC0E09139013B +:1014A000F0913A013296F0933F01E0933E0132977A +:1014B00082818A3009F4D4CD8CE291E00E94BD1A79 +:1014C000882359F08CE291E00E94CA1A4B9729F4C4 +:1014D00081E391E00E947605ABCD88E391E00E9424 +:1014E000E9048091C31FE82FF0E0E532F10508F030 +:1014F00083C0EA5BFF4FEE0FFF1F0590F491E02DD4 +:10150000099431E0C32ED12C3DC501E010E0C8C4E0 +:10151000109240010E948007AA2797FDA095BA2F3C +:10152000BC01CD010E94302367C0E0913E01F091E3 +:101530003F0180818A3009F06BCF80913701909113 +:10154000380190933A01809339018ACD8091370117 +:10155000909138014CC0109240010E9480079C017C +:1015600080914001882309F04ECFE0913E01F09137 +:101570003F0180818A3009F446CF232B09F09CCFAC +:101580003BC0109240010E9480079C019093C01FB5 +:101590008093BF1F80914001882309F034CFE091F0 +:1015A0003E01F0913F0180818A3009F02CCFE0911B +:1015B0003701F09138014091390150913A01E41717 +:1015C000F50721F18081918182179307F8F48281D8 +:1015D000E80FF11DF4CFE0913E01F0913F018081D1 +:1015E0008A3009F015CF8091390190913A0190939A +:1015F000BC1F8093BB1F0EC0E091BB1FF091BC1FAE +:10160000309709F42DCD8281E80FF11DF093BC1FB6 +:10161000E093BB1F2091BB1F3091BC1F809139010B +:1016200090913A012817390709F402CD2D5F3F4FF9 +:1016300030933F0120933E013FCFC0E0D0E083E1F3 +:1016400090E2BE010E94FB1A482F282F30E021159E +:10165000310591F2C90180978F35910540F02A300C +:10166000310529F02D30310511F08FE301C0842FB1 +:101670000E943A05219680E1C030D80701F7BCCF1F +:10168000C0E0D0E0CE018F739070809719F48EE2A5 +:101690000E943A0583E190E2BE0140E00E94021BF5 +:1016A00021969FE0CF3FD90769F78AE00E943A056B +:1016B000A3CF81E08093C41F1092340110923301B4 +:1016C000E0913701F09138014091390150913A0190 +:1016D0002091BF1F3091C01FE417F50749F08081AA +:1016E00091818217930720F48281E80FF11DF4CFD6 +:1016F000F093C21FE093C11F02C00E94F505209124 +:10170000C11F3091C21F8091390190913A01281771 +:10171000390799F71092C41F8BCC81E090E0909329 +:101720003D0180933C018091370190913801909365 +:101730003A0180933901109234011092330181E013 +:1017400080933B0181E090E09093360180933501D6 +:101750006FCC3196F0933F01E0933E01E0913E0162 +:10176000F0913F0190819032A1F3993091F3892F4C +:1017700081548A3108F04CCE3196F0933F01E093CA +:101780003E01E0913E01F0913F0180818032A1F362 +:10179000893091F38A3019F08A3309F039CE892FD4 +:1017A00090E081549040880F991FE091B91FF0910B +:1017B000BA1FE80FF91F9182808257CE3196F093BD +:1017C0003F01E0933E01E0913E01F0913F01108125 +:1017D0001032A1F3193091F3812F81548A3108F02E +:1017E00017CE3196F0933F01E0933E01E0913E0128 +:1017F000F0913F0180818032A1F3893091F38D33E4 +:1018000009F006CE3196F0933F01E0933E01E0915E +:101810003E01F0913F0180818032A1F3893091F344 +:10182000109240010E9480077C0180914001882332 +:1018300009F0EECD81ED91E00E94E9048091C31F93 +:10184000882309F0E5CD0E948007EC0180914001DA +:10185000882309F0DDCD84ED91E00E94E9048091B8 +:10186000C31F882319F041E050E00DC00E9480079B +:10187000AC0180914001882331F0CACD3196F093BC +:101880003F01E0933E01E0913E01F0913F019081E4 +:101890009032A1F3993091F39A3019F09A3309F00C +:1018A000B7CD80914001882309F0ADCD9A3009F081 +:1018B000AACDA091B51FB091B61F9D01265F3F4FE5 +:1018C0008091B71F9091B81F2817390708F4C5CD2C +:1018D0001A97B093B61FA093B51F812F90E0815443 +:1018E0009040880F991FE091B91FF091BA1FE80F3F +:1018F000F91FF182E0823C9211961C931197139686 +:10190000DC93CE93129715965C934E931497809127 +:101910003E0190913F0119969C938E931897809168 +:10192000BB1F9091BC1F17969C938E9316979DCDCD +:10193000109240010E9480079093C01F8093BF1FA8 +:1019400080914001882309F05ECDE0913E01F09145 +:101950003F0180818A3009F056CDE091B51FF091AA +:10196000B61F9F012B5F3F4F8091B71F9091B81F0B +:101970002817390708F471CD3597F093B61FE09317 +:10198000B51F87E4808380913E0190913F0194834D +:1019900083838091BB1F9091BC1F92838183E091D0 +:1019A0003701F09138014091390150913A0120916D +:1019B000BF1F3091C01FE417F50709F427CE8081BF +:1019C00091818217930708F021CE8281E80FF11DE3 +:1019D000F2CF3196F0933F01E0933E01E0913E015A +:1019E000F0913F0180818032A1F3893091F38154DD +:1019F0008A3108F008CD3196F0933F01E0933E0123 +:101A0000E0913E01F0913F0180818032A1F3893065 +:101A100091F38A3319F08A3009F0FACC8091B51F1E +:101A20009091B61F9093C61F8093C51F85C08C915F +:101A30008634F9F0873409F0FBCA8091C31F8A30DD +:101A4000B1F411968D919C9112979093BC1F809345 +:101A5000BB1F13968D919C91149790933F01809397 +:101A60003E018091B51F9091B61F05965BC01596FB +:101A70005FC08091C31F853009F059C0E0913E01DD +:101A8000F0913F0131978081282F30E011968C91A1 +:101A90001197992787FD90952817390709F047C0B6 +:101AA00021543040220F331FE091B91FF091BA1F2B +:101AB000E20FF31F2081318114968D919C9115972F +:101AC000280F391F3183208314968D919C9115978F +:101AD0001816190644F412968D919C91139782174B +:101AE000930754F41AC0892BC1F012968D919C91E2 +:101AF0001397281739078CF018968D919C91199798 +:101B000090933F0180933E0116968D919C9117977B +:101B10009093BC1F8093BB1FA8CC8091C51F909150 +:101B2000C61F0A969093B61F8093B51F9ECC1A9637 +:101B3000B093C61FA093C51FA091C51FB091C61F2B +:101B40002FE1A43BB20708F472CF5DCCE0913E01D7 +:101B5000F0913F011081812F81548A3108F053CCDC +:101B6000C091B91FD091BA1F3196F0933F01E09315 +:101B70003E01E0913E01F0913F0180818032A1F36E +:101B8000893091F38D3309F043CC3196F0933F01C6 +:101B9000E0933E01E0913E01F0913F01808180326F +:101BA000A1F3893091F3109240010E9480079C01BB +:101BB00080914001882309F02BCCE0913E01F09107 +:101BC0003F01E081EA3019F0EA3309F021CC812F9E +:101BD00090E081549040880F991FC80FD91F398316 +:101BE000288343CC109240010E94800780914001DD +:101BF000882331F00DCC3196F0933F01E0933E0104 +:101C0000E0913E01F0913F0180818032A1F3893063 +:101C100091F38C3209F0FCCB3196F0933F01E093C5 +:101C20003E01E0913E01F0913F0180818032A1F3BD +:101C3000893091F3109240010E9480078091400109 +:101C4000882309F0E5CBE0913E01F0913F01E0816E +:101C5000EA3009F40ACCEA3309F407CCD9CB31963F +:101C6000F0933F01E0933E01E0913E01F0913F018E +:101C700080818032A1F3893091F320E030E01CC0F4 +:101C800089E12939380718F02FEF3FEF1EC0C9014D +:101C9000A3E0880F991FAA95E1F7220F331F820F47 +:101CA000931F242F30E020533040280F391F3196E6 +:101CB000F0933F01E0933E01E0913E01F0913F013E +:101CC0004081842F80538A30D8F23093C01F2093F4 +:101CD000BF1FE0913E01F0913F0180818A3009F001 +:101CE00097CBE0913701F091380140913901509143 +:101CF0003A01E417F50749F0808191818217930733 +:101D000020F48281E80FF11DF4CFF093C21FE0931D +:101D1000C11F02C00E94F5052091C11F3091C21F52 +:101D20008091390190913A012817390799F780C9B4 +:101D3000E0913E01F0913F01E081EA3361F40E94BD +:101D40005E0580913E0190913F01019690933F0185 +:101D500080933E018ACBEA3031F44ECC3196F09339 +:101D60003F01E0933E01E0913E01F0913F0110817F +:101D70001032A1F3193091F3123211F0173231F50C +:101D80003196F0933F01E0933E01319703C03196C5 +:101D90008A30E1F081818117D1F70BC00E943A05AA +:101DA00080913E0190913F01019690933F01809375 +:101DB0003E01E0913E01F0913F018081811771F772 +:101DC0003196F0933F01E0933E0118C0E0913E014F +:101DD000F0913F01E081E23209F41ACBE73209F4D5 +:101DE00017CB109240010E9480079C018091400116 +:101DF000882309F00DCBC9010E94B905E0913E018D +:101E0000F0913F0180818C3209F4A8CF8B3371F4BB +:101E10009F012F5F3F4F81818A3019F08A3309F08B +:101E2000F7CA30933F0120933E011FCB8A3019F04F +:101E30008A3309F0EDCA0E945E0517CB8091B91F65 +:101E40009091BA1F2091390130913A01821B930B76 +:101E50000E94B9058BEE90E00E94760580E090E14B +:101E60000E94B90588EF90E00E947605C0E0D0E0BE +:101E700083E190E2BE010E94FB1A219690E1C030FE +:101E8000D90711F08823A1F7C3018C1B9D0B0E9479 +:101E9000B90589ED91E00E947605E7CA00E010E0FF +:101EA000109240010E948007F82E80914001882303 +:101EB00031F0AECA3196F0933F01E0933E01E091DC +:101EC0003E01F0913F0180818032A1F3893091F38E +:101ED0008C3209F09DCA3196F0933F01E0933E01A8 +:101EE000E0913E01F0913F0180818032A1F3893081 +:101EF00091F382EF91E00E94E9048091C31F843046 +:101F000041F0823018F0C0E0D0E00DC0C1E0D0E078 +:101F10000AC0109240010E948007EC0180914001AC +:101F2000882309F075CA8F2D61E00E947124012B6E +:101F300029F08F2D6C2F0E94D52497CA8F2DBE01BA +:101F40000E94F32392CAB0923D01A0923C0180917D +:101F500037019091380190933A018093390150CA2A +:101F6000109240010E9480079C01809140018823CB +:101F700009F04ECAC9010E94062B77CA8FE00E9461 +:101F8000062873CA109240010E948007EC018091DC +:101F90004001882331F03CCA3196F0933F01E09331 +:101FA0003E01E0913E01F0913F0180818032A1F33A +:101FB000893091F38C3209F02BCA3196F0933F01AE +:101FC000E0933E01E0913E01F0913F01808180323B +:101FD000A1F3893091F3109240010E9480079C0187 +:101FE00080914001882309F013CA209739F2211506 +:101FF000310521F279010027F7FC0095102F8FE0C1 +:10200000BE01A80197010E947D28C114D10409F4E2 +:102010002CCAC801B7010E943023CC24DD2425CA74 +:102020008217930709F0A5C98CC9DF91CF911F9141 +:102030000F91FF90EF90DF90CF90BF90AF909F9067 +:102040008F907F906F905F904F903F900895FC012C +:10205000613009F1613030F0623009F04BC040E08E +:1020600050E03EC01282138240E050E009C0E0918F +:10207000D81FF091D91FE40FF51F10824F5F5F4FFB +:102080008091D21F2091D31F829FC0011124481735 +:1020900059076CF308951282138240E050E03FEF3D +:1020A00009C0E091D81FF091D91FE40FF51F3083CC +:1020B0004F5F5F4F8091D21F2091D31F829FC0013D +:1020C0001124481759076CF30895E091D81FF09137 +:1020D000D91FE40FF51F8081809580834F5F5F4F8C +:1020E0008091D21F2091D31F829FC00111244817D5 +:1020F00059075CF308952F923F924F925F926F922F +:102100007F928F929F92AF92BF92CF92DF92EF9287 +:10211000FF920F931F93DF93CF93CDB7DEB72C972A +:102120000FB6F894DEBF0FBECDBF9A878987A42F64 +:1021300029012E2D2C2C462F477078E0F72EF41A0B +:10214000EE2039F4F201E00FF11FE4910F5F1F4F11 +:102150002E2F222039F4F201E00FF11FE4910F5FDE +:102160001F4F2E2E822F90E087709070322F369561 +:1021700036953695892B29F0822F8770332E33942C +:1021800002C0332E88E0669566956695262F30E06E +:102190003E832D83642E7724B301680F711D8FEF6A +:1021A00090E0AC01062E02C0559547950A94E2F7DF +:1021B00049839C010F2C02C0220F331F0A94E2F7BF +:1021C0002C834B8368507040062E02C095958795EE +:1021D0000A94E2F7685F7F4F8A83CC24DD248A2F3C +:1021E00090E098878F83A32CBB240894A108B108A2 +:1021F000A5C02F8138852C0D3D1D8091D31F90E007 +:10220000289FD001299FB00D389FB00D1124ED817A +:10221000FE81AE0FBF1FF1E03F1611F4898101C0AE +:1022200080E0E985FA85208131812A0F3B1FF90181 +:10223000E080FC818F2B8E21F9018083A201400F69 +:10224000511F0F5F1F4FFA013491E985FA85808095 +:1022500091808A0E9B1E832F90E0062C02C09595DC +:1022600087950A94E2F7F4012081282B20831196A8 +:102270004501800E911E28C0E985FA850190F08104 +:10228000E02DEA0FFB1FE080832F90E00F2C02C0AF +:10229000880F991F0A94E2F78083FA013491E98547 +:1022A000FA850190F081E02DEA0FFB1F832F90E06B +:1022B000062C02C0959587950A94E2F72081282B79 +:1022C000208311960F5F1F4F4F5F5F4F0815190551 +:1022D00098F26830710574F41197E985FA85808069 +:1022E00091808A0E9B1E1196FB81EF22F401808162 +:1022F0008E2980836930710564F0E985FA858080D4 +:1023000091808A0E9B1EF4018081FA818F23F40153 +:102310008083E985FA85808091808A0E9B1E832FB9 +:1023200090E00F2C02C0880F991F0A94E2F7F40185 +:102330002081282B20830894C11CD11CC21408F4CE +:1023400058CF2C960FB6F894DEBF0FBECDBFCF91FD +:10235000DF911F910F91FF90EF90DF90CF90BF9092 +:10236000AF909F908F907F906F905F904F903F9035 +:102370002F900895CF92DF92EF92FF920F931F93C9 +:10238000CF93DF93413079F1413038F0423009F496 +:1023900054C0433009F0F4C09AC0A091D81FB09146 +:1023A000D91F2091D31F30E0862F90E0829FF0014B +:1023B000839FF00D929FF00D1124EA0FFB1F809177 +:1023C000D21F90E0829FA001839F500D929F500DDD +:1023D00011244A0F5B1F03C080818D9311924E1709 +:1023E0005F07D0F7CDC04091D81F5091D91F2091E1 +:1023F000D31F30E08091D21F90E0289FD001299F09 +:10240000B00D389FB00D1124A40FB51F862F90E09A +:10241000BC01629FC001639F900D729F900D1124BB +:10242000FD01E81BF90B05C080818C931082119788 +:102430003197E417F507C0F7A3C0062F077066951C +:1024400066956695E62EFF2410E0C02FD0E068E088 +:1024500070E06C1B7D0B36C02091D31F129FC00112 +:102460001124E091D81FF091D91FE80FF91FDF0167 +:10247000AE0DBF1D422F50E0425050404E0F5F1F27 +:1024800012C030E00C2E02C0220F331F0A94E2F774 +:102490001D928C9190E0062E02C0959587950A9426 +:1024A000E2F7282B21932C914A175B0750F7822FD4 +:1024B00090E0002E02C0880F991F0A94E2F71C9248 +:1024C00080831F5F8091D21F181730F259C0062FEA +:1024D0000770669566956695862F90E0EE24FF243A +:1024E000E81AF90A10E0E2E0CE2ED12CC02FD0E09D +:1024F00068E070E06C1B7D0B3EC08091D31F482FBD +:1025000050E09A0121503040189FC0011124280F3B +:10251000391FE091D81FF091D91FE20FF31FDF019F +:10252000AE0DBF1DC601841B950BAC014E0F5F1F86 +:1025300013C030E00C2E02C0359527950A94E2F7BF +:102540001C928E9190E0062E02C0880F991F0A946B +:10255000E2F7282B208331972C91A417B50748F771 +:10256000822F90E0002E02C0959587950A94E2F79D +:102570001C9280831F5F8091D21F181708F4BDCF73 +:10258000DF91CF911F910F91FF90EF90DF90CF904F +:10259000089570930B0160930A010895FF920F93C1 +:1025A0001F93CF93DF93EC01F62E022F842F887FA9 +:1025B00011F481E01CC0142F169516951695219FD5 +:1025C000C00111240E9486039C019983888300978F +:1025D00011F484E00CC01A821B828F2D612F402FD2 +:1025E0000E946C14CE0160E00E94271080E0DF9111 +:1025F000CF911F910F91FF900895FC017583648323 +:102600000895DC0113964C9113971496ED91FC916B +:10261000159731966491242F30E08091D21F90E07D +:10262000861B9109281739072CF0CD0140E00E9444 +:10263000BA110895640F13966C930895CF92EF9298 +:102640000F931F93DC01022F1496ED91FC911597C7 +:10265000329684913197C4903197E490081B0C9D79 +:10266000800111240D5F1F4FCD019F010E947B103F +:102670001F910F91EF90CF9008951F93CF93DF9309 +:10268000EC01162F6A3069F06B3030F4662309F4E0 +:102690003EC06830B9F409C06D3091F06E3091F4ED +:1026A00036C01A820E94011332C0EC81FD81E49190 +:1026B0006A816E1B6A834B8120E20E941E1327C031 +:1026C0001A8225C06A81EC81FD81E491262F30E0D9 +:1026D0008091D31F90E043E0880F991F4A95E1F75E +:1026E0008E1B9109281739073CF01A82CE010E94EF +:1026F0000113CE016A8101C0CE014B81212F0E94BE +:102700001E13EC81FD81E4918A818E0F8A83DF9113 +:10271000CF911F910895EF92FF920F931F93CF9344 +:10272000DF93EC017A018B012115310521F4642F2F +:102730000E943D131BC02A303105B1F477FF10C051 +:102740004DE250E060E070E020E030E00E948B134A +:1027500010950095F094E094E11CF11C011D111DF1 +:10276000CE01B801A7012AE00E94D113DF91CF91D9 +:102770001F910F91FF90EF900895EF92FF920F93AA +:102780001F93E62E9A01FF24E7FCF0940F2D1F2DD6 +:10279000B801A7010E948B131F910F91FF90EF903A +:1027A00008952F923F924F925F926F927F928F92F5 +:1027B0009F92AF92BF92CF92DF92EF92FF920F93D0 +:1027C0001F93DF93CF93CDB7DEB7A0970FB6F894E2 +:1027D000DEBF0FBECDBF1C016A017B014115510553 +:1027E0006105710549F440E350E060E070E020E0ED +:1027F00030E00E948B1356C0882499245401422E45 +:1028000055246624772401E010E00C0F1D1F080DED +:10281000191DC701B601A30192010E94542BF801B2 +:1028200060830894811C911CA11CB11CC701B601D6 +:10283000A30192010E94542BC901DA016C017D01B0 +:10284000C114D104E104F104F1F651E0E52EF12CBC +:10285000EC0EFD1EE80CF91C3E010894611C711C75 +:10286000D501C4010197A109B1096C01C818D908A3 +:1028700016C0F601EE0DFF1D40814A3010F4405D98 +:1028800001C0495C552747FD5095652F752FC10143 +:1028900020E030E00E948B130894E108F1086E14E8 +:1028A0007F0439F7A0960FB6F894DEBF0FBECDBFF8 +:1028B000CF91DF911F910F91FF90EF90DF90CF901C +:1028C000BF90AF909F908F907F906F905F904F9050 +:1028D0003F902F9008950895FF920F931F93F82E25 +:1028E000E62F142F3093D91F2093D81F6093D31F46 +:1028F0004093D21F1092CB1F1092CC1F1092CD1F6D +:102900001092CE1F882319F084E091E002C088ED78 +:1029100090E0612F70E00E94412B61506093D51FC1 +:102920000091D51F0093D61F2E2F30E083E0220F99 +:10293000331F8A95E1F7442737FD4095542F60EE09 +:1029400072E080E090E00E94762B243069F0253020 +:1029500018F4233061F410C0253019F0263039F412 +:1029600008C087EC96E10AC08DE097E107C02730E8 +:1029700018F088E796E102C087E497E19093DB1FA7 +:102980008093DA1F0F9A559A17985D9A579A82EC9E +:102990008093800089E180938100412F50E0202FB7 +:1029A000332727FD3095FF2011F12F5F3F4F429FC6 +:1029B000C001439F900D529F900D112462E070E082 +:1029C0000E94412B709561957F4F64566093CF1F95 +:1029D00087EC8093D41F87E08093D71F88E391E032 +:1029E0009093D11F8093D01F8FEF93E021C02F5F72 +:1029F0003F4F429FC001439F900D529F900D112465 +:102A000062E070E00E94412B709561957F4F6557A1 +:102A10006093CF1F8FEB8093D41F83E08093D71FE9 +:102A200086E091E09093D11F8093D01F87EF93E0D1 +:102A300090938700809386008AE490E090938900C9 +:102A4000809388008091D01F9091D11F0196909320 +:102A5000CA1F8093C91F8CEF95E19093DD1F80936F +:102A6000DC1F81E080936F0078941F910F91FF909D +:102A700008951F920F920FB60F920BB60F9211246A +:102A80002F933F934F935F936F937F938F939F9376 +:102A9000AF93BF93EF93FF93E0910A01F0910B0185 +:102AA0000995E091DC1FF091DD1F0995FF91EF91F1 +:102AB000BF91AF919F918F917F916F915F914F9156 +:102AC0003F912F910F900BBE0F900FBE0F901F9054 +:102AD00018952091C91F3091CA1F8091CF1F90E097 +:102AE0002817390779F41092C81F1092C71F8091D8 +:102AF000D51F8093D61F82EA95E19093DD1F8093C6 +:102B0000DC1F16C02091C91F3091CA1F8091D01FB1 +:102B10009091D11F2817390759F48CEF95E19093C4 +:102B2000DD1F8093DC1FE0910C01F0910D010995F0 +:102B30008091C91F9091CA1F01969093CA1F8093DC +:102B4000C91F0895309184002091D41F2A50231B5F +:102B50002350F0F72D5F19F02A9511F001C0000005 +:102B6000E091DA1FF091DB1F09958091D61F882331 +:102B700089F48091D51F8093D61F2091D31F809117 +:102B8000C71F9091C81F820F911D9093C81F8093FB +:102B9000C71F03C081508093D61F4091C91F509119 +:102BA000CA1F4F5F5F4F2091D51F332727FD3095F8 +:102BB0002F5F3F4F8091D21F90E0BC01269FC00144 +:102BC000279F900D369F900D11242091CF1F820FCB +:102BD000911D4817590731F489E695E19093DD1F5F +:102BE0008093DC1F8091C91F9091CA1F019690931A +:102BF000CA1F8093C91F08952091C91F3091CA1F11 +:102C00008091D01F9091D11F281739070CF44EC026 +:102C10008CEA93E090938900809388001092CA1FF9 +:102C20001092C91F8091CB1F9091CC1FA091CD1FF6 +:102C3000B091CE1F0196A11DB11D8093CB1F909323 +:102C4000CC1FA093CD1FB093CE1F8091DE1F90911B +:102C5000DF1FA091E01FB091E11F0097A105B10512 +:102C600009F18091DE1F9091DF1FA091E01FB091CC +:102C7000E11F181619061A061B0684F58091DE1F3F +:102C80009091DF1FA091E01FB091E11F0197A10972 +:102C9000B1098093DE1F9093DF1FA093E01FB093D4 +:102CA000E11F1CC01092B1002F9818C02091C91FBD +:102CB0003091CA1F8091D71F992787FD90952817BB +:102CC000390761F48AE490E090938900809388004A +:102CD00089E695E19093DD1F8093DC1F8091C91FE9 +:102CE0009091CA1F01969093CA1F8093C91F08959F +:102CF0000F93CF93DF93A091D81FB091D91F8091EC +:102D0000C71F9091C81F2091D31FEC01AC0FBD1FAE +:102D100002B10F7703C000FA07F902B90D90000065 +:102D200007FA07F902B900000000000006FA07F9E7 +:102D300002B900000000000005FA07F902B900001E +:102D40000000000004FA07F902B9000000000000CA +:102D500003FA07F902B900000000000002FA07F9BF +:102D600002B900000000000001FA07F902B92A9533 +:102D700091F60000000000FA07F902B902B10F77DE +:102D800007FB07F902B9DF91CF910F9108950F93D7 +:102D9000CF93DF93A091D81FB091D91F8091C71F07 +:102DA0009091C81F2091D31FEC01AC0FBD1F02B141 +:102DB0000F7703C000FA07F902B90D9007FA07F977 +:102DC00002B90000000006FA07F902B9000000008D +:102DD00005FA07F902B90000000004FA07F902B980 +:102DE0000000000003FA07F902B90000000002FA2F +:102DF00007F902B900002A9501FA07F902B9D1F6DC +:102E0000000000FA07F902B902B10F7707FB07F9D2 +:102E100002B9DF91CF910F9108950F93CF93DF9374 +:102E2000A091D81FB091D91F8091C71F9091C81F42 +:102E30002091D31FEC01AC0FBD1F02C0000C02B8E3 +:102E40000D90000002B800000000000C02B8000065 +:102E50000000000C02B800000000000C02B80000E6 +:102E60000000000C02B800000000000C02B80000D6 +:102E7000000C2A9502B811F70000000C02B80000FF +:102E8000000000001798DF91CF910F9108950F93E4 +:102E9000CF93DF93A091D81FB091D91F8091C71F06 +:102EA0009091C81F2091D31FEC01AC0FBD1F2E3194 +:102EB00091F02D3151F02C3149F02B3141F02A3174 +:102EC00039F0293131F0283129F01CC032C048C016 +:102ED0005EC074C08AC00D9002B80000000C02B839 +:102EE0000000000C02B80000000C02B80000000C4A +:102EF00002B80000000C02B80000000C02B800008C +:102F0000000C02B80D9002B80000000C02B80000DE +:102F1000000C02B80000000C02B80000000C02B85F +:102F20000000000C02B80000000C02B80000000C09 +:102F300002B80D9002B80000000C02B80000000CAE +:102F400002B80000000C02B80000000C02B800003B +:102F5000000C02B80000000C02B80000000C02B81F +:102F60000D9002B80000000C02B80000000C02B87E +:102F70000000000C02B80000000C02B80000000CB9 +:102F800002B80000000C02B80000000C02B80D905E +:102F900002B80000000C02B80000000C02B80000EB +:102FA000000C02B80000000C02B80000000C02B8CF +:102FB0000000000C02B80000000C02B80D9002B82E +:102FC0000000000C02B80000000C02B80000000C69 +:102FD00002B80000000C02B80000000C02B80000AB +:102FE000000C02B80000000C02B80D9002B80000FE +:102FF000000C02B80000000C02B80000000C02B87F +:103000000000000C02B80000000C02B80000000C28 +:1030100002B80000000C02B80D9002B80000000CCD +:1030200002B80000000C02B80000000C02B800005A +:10303000000C02B80000000C02B80000000C02B83E +:103040000000000C02B80D9002B80000000C02B89D +:103050000000000C02B80000000C02B80000000CD8 +:1030600002B80000000C02B80000000C02B800001A +:10307000000C02B80D9002B80000000C02B800006D +:10308000000C02B80000000C02B80000000C02B8EE +:103090000000000C02B80000000C02B80000000C98 +:1030A00002B80D9002B80000000C02B80000000C3D +:1030B00002B80000000C02B80000000C02B80000CA +:1030C000000C02B80000000C02B80000000C02B8AE +:1030D0000D9002B80000000C02B80000000C02B80D +:1030E0000000000C02B80000000C02B80000000C48 +:1030F00002B80000000C02B80000000C02B80D90ED +:1031000002B80000000C02B80000000C02B8000079 +:10311000000C02B80000000C02B80000000C02B85D +:103120000000000C02B80000000C02B80D9002B8BC +:103130000000000C02B80000000C02B80000000CF7 +:1031400002B80000000C02B80000000C02B8000039 +:10315000000C02B80000000C02B80D9002B800008C +:10316000000C02B80000000C02B80000000C02B80D +:103170000000000C02B80000000C02B80000000CB7 +:1031800002B80000000C02B80D9002B80000000C5C +:1031900002B80000000C02B80000000C02B80000E9 +:1031A000000C02B80000000C02B80000000C02B8CD +:1031B0000000000C02B80D9002B80000000C02B82C +:1031C0000000000C02B80000000C02B80000000C67 +:1031D00002B80000000C02B80000000C02B80000A9 +:1031E000000C02B80D9002B80000000C02B80000FC +:1031F000000C02B80000000C02B80000000C02B87D +:103200000000000C02B80000000C02B80000000C26 +:1032100002B80D9002B80000000C02B80000000CCB +:1032200002B80000000C02B80000000C02B8000058 +:10323000000C02B80000000C02B80000000C02B83C +:103240000D9002B80000000C02B80000000C02B89B +:103250000000000C02B80000000C02B80000000CD6 +:1032600002B80000000C02B80000000C02B80D907B +:1032700002B80000000C02B80000000C02B8000008 +:10328000000C02B80000000C02B80000000C02B8EC +:103290000000000C02B80000000C02B80D9002B84B +:1032A0000000000C02B80000000C02B80000000C86 +:1032B00002B80000000C02B80000000C02B80000C8 +:1032C000000C02B80000000C02B80D9002B800001B +:1032D000000C02B80000000C02B80000000C02B89C +:1032E0000000000C02B80000000C02B80000000C46 +:1032F00002B80000000C02B80D9002B80000000CEB +:1033000002B80000000C02B80000000C02B8000077 +:10331000000C02B80000000C02B80000000C02B85B +:103320000000000C02B80D9002B80000000C02B8BA +:103330000000000C02B80000000C02B80000000CF5 +:1033400002B80000000C02B80000000C02B8000037 +:10335000000C02B80D9002B80000000C02B800008A +:10336000000C02B80000000C02B80000000C02B80B +:103370000000000C02B80000000C02B80000000CB5 +:1033800002B80D9002B80000000C02B80000000C5A +:1033900002B80000000C02B80000000C02B80000E7 +:1033A000000C02B80000000C02B80000000C02B8CB +:1033B0000D9002B80000000C02B80000000C02B82A +:1033C0000000000C02B80000000C02B80000000C65 +:1033D00002B80000000C02B80000000C02B80D900A +:1033E00002B80000000C02B80000000C02B8000097 +:1033F000000C02B80000000C02B80000000C02B87B +:103400000000000C02B80000000C02B80D9002B8D9 +:103410000000000C02B80000000C02B80000000C14 +:1034200002B80000000C02B80000000C02B8000056 +:10343000000C02B80000000C02B800000000179851 +:10344000DF91CF910F9108958091C00087FF13C045 +:103450009091E21F9F5F9D3208F090E08091E31F02 +:10346000981749F08091C600E92FF0E0EA51F04E3C +:1034700080839093E21F08954091E21F2091E51F01 +:103480003091E31F341759F03F5F3D3208F030E0D0 +:10349000E32FF0E0EA51F04EE081EE2331F4209387 +:1034A000E51F3093E31F80E00895E03F11F42160B1 +:1034B000E9CFE03E11F42260E5CF822F90E020FFBB +:1034C00009C0E23111F42B7F03C0E93509F4277FED +:1034D0002C7FD8CFE23111F42460D4CFE93511F438 +:1034E0002860D0CF21FF2DC0E23719F1E33760F417 +:1034F000EA3529F1EB3518F4EA34A9F51EC0EB36AC +:10350000B1F0E13781F50DC0E53779F0E63718F411 +:10351000E43749F510C0EA3731F0ED3721F589E19C +:1035200023C08FE721C08AE11FC08BE01DC088E067 +:103530001BC08AE019C085E117C08FE215C08DE07D +:1035400013C08C709070892B39F0E43860F4F0E08F +:10355000EA5DFA4F849108C0E43828F4F0E0E655BB +:10356000FA4F849101C080E02C7F882309F48ACF30 +:103570002093E51F3093E31F08958091E41F882373 +:1035800011F081E008950E943C1A8093E41F81119C +:1035900081E008958091E41F882319F01092E41FC0 +:1035A00007C00E943C1A882319F42FEF3FEF04C094 +:1035B000282F332727FD3095C90108951092C000A8 +:1035C00083E390E09093C5008093C40088E18093EA +:1035D000C100E2ECF0E080818064808380818062C1 +:1035E00080838081806180831092E21F1092E31FAC +:1035F00084E29AE10895F999FECF72BD61BDF89A0F +:1036000080B50895F999FECF1FBA72BD61BD40BD66 +:103610000FB6F894FA9AF99A0FBE089510921920ED +:1036200010921A2010921D2010921F2082E090E02C +:10363000A0E0B0E08093202090932120A09322204E +:10364000B0932320109237201092412010924020F6 +:1036500088E191E090933F2080933E201092432098 +:103660000895FF920F931F93CF93DF938B010E94D6 +:103670002223EB01FF24FA94FEBC0DB407FEFDCF1C +:103680008EB58F3F11F481E008C00E9422236C1B8D +:103690007D0B6017710780F380E0DF91CF911F9160 +:1036A0000F91FF900895FC01848160E00E94D52471 +:1036B0000895FC01848161E00E94D5240895DC0115 +:1036C0006EBDFA0120E030E00DB407FEFDCF808131 +:1036D0008EBD0DB407FEFDCF81818EBD2E5F3F4FA5 +:1036E000329682E02030380779F70DB407FEFDCF1F +:1036F0008FEF8EBD0DB407FEFDCF8FEF8EBD0DB4E5 +:1037000007FEFDCF8FEF8EBD0DB407FEFDCF8EB54A +:103710001A968C931A978F71853011F481E0089571 +:1037200081E115968C931597CD010E94591B80E07D +:103730000895FF920F931F93CF93DF93EC010E94A4 +:1037400022238B01FF24FA9409C00E942223601BCC +:10375000710B6D52714010F08FE00DC0FEBC0DB4C6 +:1037600007FEFDCF8EB58A878F3F79F38E3F11F428 +:1037700081E006C08DE08D83CE010E94591B80E060 +:10378000DF91CF911F910F91FF900895CF93DF9319 +:10379000EC018E818823D1F08FEF8EBD2F8138858B +:1037A0004FEF04C00DB407FEFDCF4EBD2F5F3F4F5E +:1037B000C901019781509240A8F338872F830DB437 +:1037C00007FEFDCFCE010E94591B1E82DF91CF91D3 +:1037D0000895DF92EF92FF920F931F93CF93DF93A1 +:1037E000EC01D62E79018A010E94C61BCE010E94EF +:1037F000531BCE016CE271E00E94311B8D2D806461 +:103800008EBD0DB407FEFDCF28E130E0D801C70121 +:10381000022E04C0B695A795979587950A94D2F77E +:103820008EBD0DB407FEFDCF285030408FEF283FEE +:10383000380761F7DD2011F485E906C088E0D81665 +:1038400011F487E801C08FEF8EBD0DB407FEFDCFE8 +:1038500090E02FEF2EBD0DB407FEFDCF8EB587FF94 +:1038600002C09150B9F78A87DF91CF911F910F91D4 +:10387000FF90EF90DF900895CF92DF92EF92FF924A +:103880000F931F93CF93DF93EC017A018B016901B2 +:10389000411551056105710511F482E137C08B8531 +:1038A000833039F029E0EE0CFF1C001F111F2A9510 +:1038B000D1F7CE0168E1A80197010E94E91B882396 +:1038C00011F084E023C0CE016EEFA6010E945F1BC1 +:1038D0008823E9F0CE0168E572E00E94311B88235D +:1038E00011F485E113C0CE016DE020E030E040E04E +:1038F00050E00E94E91B882341F48FEF8EBD0DB488 +:1039000007FEFDCF8EB5882379F084E18D83CE014B +:103910000E94591B80E0DF91CF911F910F91FF9082 +:10392000EF90DF90CF900895CE010E94591B81E067 +:10393000F2CF8F929F92AF92BF92CF92DF92EF928F +:10394000FF920F931F93CF93DF93EC015A016B010A +:1039500049010115110509F47BC0C801820F931FAD +:103960008150924008F06FC08E81882371F0888169 +:103970009981AA81BB81481759076A077B0729F4F7 +:103980008F8198858816990618F5A882B982CA820F +:10399000DB828B85833039F069E0AA0CBB1CCC1C20 +:1039A000DD1C6A95D1F7CE0161E1A60195010E9467 +:1039B000E91B882319F083E08D8345C0CE010E9466 +:1039C000991B882309F43FC018861F8281E08E83EB +:1039D0008FEF8EBD8F8198852FEF05C00DB407FE48 +:1039E000FDCF2EBD019688159905C0F398878F836A +:1039F000D801119720E030E09FEF0BC00DB407FE17 +:103A0000FDCF8EB5F701E20FF31F80839EBD2F5FC0 +:103A10003F4F2A173B0790F30DB407FEFDCF8EB53D +:103A2000AE0DBF1D8C932F813885200F311F388735 +:103A30002F838985882319F02050324048F0CE0129 +:103A40000E94C61B05C0CE010E94591B80E001C028 +:103A500081E0DF91CF911F910F91FF90EF90DF9068 +:103A6000CF90BF90AF909F908F900895EF92FF926C +:103A70000F931F93790120E030E000E012E00E94F4 +:103A8000991C1F910F91FF90EF9008956F927F9274 +:103A90008F929F92AF92BF92CF92DF92EF92FF925E +:103AA0000F931F93CF93DF93EC017A018B012D814C +:103AB000222309F480C08B899C89AD89BE89841733 +:103AC0009507A607B70708F476C085C0E114F1048E +:103AD0000105110549F41E821F82188619861A866F +:103AE0001B861C861D8665C02A853B854C855D85A9 +:103AF000EB8DFC8D858590E009962150304040404B +:103B0000504039014A01082E04C096948794779456 +:103B100067940A94D2F72F5F3F4F4F4F5F4F08943F +:103B2000E108F108010911095701680104C0D694A0 +:103B3000C794B794A7948A95D2F70894E11CF11C16 +:103B4000011D111DA614B704C804D90428F02115BD +:103B500031054105510549F48F89988DA98DBA8D9C +:103B60008E839F83A887B98716C0A618B708C80890 +:103B7000D90811C04E815F81688579858B8D9C8DB8 +:103B800094010E9458210894A108B108C108D108E5 +:103B9000882331F410C086E0882E912C8C0E9D1E57 +:103BA000A114B104C104D10429F7EA86FB860C876D +:103BB0001D8781E001C080E0DF91CF911F910F91BF +:103BC000FF90EF90DF90CF90BF90AF909F908F903D +:103BD0007F906F900895223009F078CFE6CFCF9391 +:103BE000DF93EC01462F6E857F85888999890E9435 +:103BF0008120882319F420E030E00AC08A89282F28 +:103C000030E095E0220F331F9A95E1F7215A3F4D9E +:103C1000C901DF91CF9108950F931F93CF93DF9345 +:103C20008C01FC0185818823D9F1848187FF35C00F +:103C3000C80161E00E94EF1DEC01009789F1F801D5 +:103C40008581823040F483899489A589B6898C8FD7 +:103C50009D8FAE8FBF8FF8018789908D9B8F8A8F44 +:103C60008789908DA18DB28DCD01AA27BB279D8B11 +:103C70008C8BE0915D20F0915E20309751F0BE0179 +:103C80006A5E7F4FCE0148960995888D998D9B8BF2 +:103C90008A8BF80184818F7784830E94462001C03B +:103CA00080E0DF91CF911F910F910895CF93DF9323 +:103CB000EC019C012A5F3F4F8B8D9C8D41E050E0D1 +:103CC00060E070E00E94CB218823A1F08F89988D5D +:103CD000A98DBA8D0097A105B10559F48E819F81F8 +:103CE000A885B9858F8B988FA98FBA8F8C818068B2 +:103CF0008C8381E0DF91CF9108952F923F924F9274 +:103D00005F927F928F929F92AF92BF92CF92DF92FB +:103D1000EF92FF920F931F93DF93CF9300D000D0C9 +:103D200000D0CDB7DEB76C01162F072F5E834D8311 +:103D3000DC0115968C911597813009F070C11496AD +:103D40008C9181FF6CC18EC1F601438954896589CC +:103D5000768982859385A485B58584179507A607FE +:103D6000B70731F0C6010E94461D882309F457C1E8 +:103D7000812F902F9C0129012D803E8017C1D601F3 +:103D80005B96ED91FC915C97DA01C90119E0B6955B +:103D9000A795979587951A95D1F774807A9478228C +:103DA0007FEF872E71E0972E82229322772009F0F1 +:103DB0004EC08114910409F04AC0D60116964D9167 +:103DC0005D916D917C9119974115510561057105C2 +:103DD00081F457968D919D910D90BC91A02D0097E7 +:103DE000A105B10549F1F60186839783A087B187C4 +:103DF0002EC0CF019E012F5F3F4F0E945821882384 +:103E000009F414C129813A814B815C81D6015B960A +:103E1000ED91FC915C978789803129F088EF9FEFC5 +:103E2000AFEFBFE004C088EF9FEFA0E0B0E028173D +:103E300039074A075B0730F0C6010E94561E8823E7 +:103E400031F4EDC0F601268337834087518780E047 +:103E500092E08819990951018215930508F45C01D3 +:103E6000D6015B96ED91FC915C971696ED90FD90D6 +:103E70000D911C9119978EEF9FEFAFEFBFEFE80EFA +:103E8000F91E0A1F1B1F058404C0EE0CFF1C001F37 +:103E9000111F0A94D2F786859785A089B189E80E0B +:103EA000F91E0A1F1B1FE70CF11C011D111D90E0DC +:103EB000A91692E0B90651F580910E0190910F017B +:103EC000A0911001B09111018E159F05A007B107B7 +:103ED00061F48FEF9FEFAFEFBFEF80930E019093F0 +:103EE0000F01A0931001B093110180915F22909176 +:103EF0006022B801A70192010E943C1C882309F4AA +:103F00008EC0A0E0B2E04A0E5B1E3EC08114910458 +:103F100009F5F60122853385448555858389948981 +:103F2000A589B689281739074A075B0798F00E94C8 +:103F30004620882309F473C0E0920E01F0920F012D +:103F40000093100110931101809161228160809390 +:103F5000612208C0C801B70141E00E948120882386 +:103F600009F45DC09401215A3F4DA9014A0D5B1D22 +:103F7000D201F90102C08D918193E417F507D9F7B9 +:103F8000E21BF30B4E0E5F1E2A183B08950140E022 +:103F900050E0F60182859385A485B585820F931F35 +:103FA000A41FB51F82879387A487B587D6011A9669 +:103FB0002D913D914D915C911D972114310409F093 +:103FC000DECE53968D919D910D90BC91A02D8217C0 +:103FD0009307A407B50748F4F601238B348B458B70 +:103FE000568B84818068848311C080915D2090917C +:103FF0005E20892B59F08D819E81892B39F0D60165 +:1040000014968C911497806814968C93F601848191 +:1040100083FF0EC0C6010E940C1E882349F481E074 +:1040200090E0D60113969C938E9312971E821D8268 +:104030008D819E8126960FB6F894DEBF0FBECDBF50 +:10404000CF91DF911F910F91FF90EF90DF90CF9074 +:10405000BF90AF909F908F907F905F904F903F90D8 +:104060002F90089582FD70CE83CEDF93CF930F9271 +:10407000CDB7DEB76983BE016F5F7F4F41E050E08F +:104080000E947D1E0F90CF91DF9108958091612253 +:10409000882399F140910E0150910F016091100118 +:1040A0007091110180915F22909160222FE530E2A2 +:1040B0000E943C1C882319F1409162225091632296 +:1040C0006091642270916522411551056105710569 +:1040D00091F080915F22909160222FE530E20E9462 +:1040E0003C1C882361F0109262221092632210928D +:1040F0006422109265221092612281E0089580E08E +:104100000895DF92EF92FF920F931F937B018C0132 +:10411000D42E80910E0190910F01A0911001B091C9 +:1041200011018E159F05A007B107C1F00E9446201E +:104130008823D9F080915F2290916022B801A70175 +:104140002FE530E20E94361D882379F0E0920E01BF +:10415000F0920F01009310011093110180916122E0 +:104160008D298093612281E001C080E01F910F9131 +:10417000FF90EF90DF9008954F925F926F927F9241 +:104180008F929F92AF92BF92CF92DF92EF92FF9267 +:104190000F931F93CF93DF93EC016A017B012801FA +:1041A0003901423051056105710508F46FC08985F8 +:1041B0009A85AB85BC850196A11DB11D8417950715 +:1041C000A607B70708F462C02B893C894D895E8930 +:1041D0008F89803129F499278F2D7E2D6D2D09C06F +:1041E000C701B60117E096958795779567951A955B +:1041F000D1F74B015C01820E931EA41EB51E809167 +:104200000E0190910F01A0911001B091110188163B +:104210009906AA06BB0639F0C501B40140E00E9428 +:104220008120882399F18F89803149F4F601F0705B +:10423000EE0FFF1FE15AFF4D518240820DC0F60183 +:10424000EF77F070EE0FFF1FEE0FFF1FE15AFF4DEB +:104250004082518262827382809161228160809368 +:1042600061228A89823080F08D819E81AF81B885FC +:10427000880E991EAA1EBB1E809262229092632213 +:10428000A0926422B092652281E001C080E0DF91BB +:10429000CF911F910F91FF90EF90DF90CF90BF9043 +:1042A000AF909F908F907F906F905F904F90089508 +:1042B000CF92DF92EF92FF920F931F93CF93DF93F2 +:1042C000EC017A018B01690189859A85AB85BC85F2 +:1042D0000196A11DB11D84179507A607B70708F41D +:1042E00050C02B893C894D895E898F89803129F4A2 +:1042F0009927812F702F6F2D09C0C801B701E7E002 +:104300009695879577956795EA95D1F7260F371F8C +:10431000481F591F80910E0190910F01A09110012B +:10432000B0911101281739074A075B0739F0CA0114 +:10433000B90140E00E948120882319F18F898031E2 +:1043400059F4F701F070EE0FFF1FE15AFF4D808125 +:104350009181A0E0B0E00EC0F701EF77F070EE0FB2 +:10436000FF1FEE0FFF1FE15AFF4D80819181A28157 +:10437000B381BF70F60180839183A283B38381E010 +:1043800001C080E0DF91CF911F910F91FF90EF90DE +:10439000DF90CF9008952F923F924F925F926F924D +:1043A0007F928F929F92AF92BF92CF92DF92EF92C5 +:1043B000FF920F931F93DF93CF93CDB7DEB72F9765 +:1043C0000FB6F894DEBF0FBECDBF1C014A875B87D6 +:1043D0006C877D873F872E87D9010D911D912D9187 +:1043E0003C91011511052105310549F0480159019C +:1043F0000894811C911CA11CB11C198610C0FC01E1 +:1044000080809180A280B38019868A859B85AC8547 +:10441000BD850197A105B10511F491E09987D101FE +:1044200019968D919D910D90BC91A02D0196A11D85 +:10443000B11D8D839E83AF83B887750164014424C9 +:10444000552432018E010F5F1F4FF1018185928546 +:10445000A385B485481659066A067B0608F090C005 +:104460008D819E81AF81B8858C159D05AE05BF05F8 +:1044700050F482E0882E912CA12CB12CB2E0CB2EEE +:10448000D12CE12CF12CC101B701A60198010E94A9 +:104490005821882309F474C089819A81AB81BC8139 +:1044A000A70196012F5F3F4F4F4F5F4F0097A10528 +:1044B000B10519F049015A010DC0281939094A09F5 +:1044C0005B098A859B85AC85BD85281739074A0716 +:1044D0005B0759F00894411C511C611C711C089425 +:1044E000C11CD11CE11CF11CB0CFC101A601B70158 +:1044F0000FEF1FEF2FEF3FE00E94BC20882399F4BD +:104500003FC026013701089441085108610871082D +:10451000C101B301A201970186010E94BC2088233A +:1045200079F1730162018C149D04AE04BF0448F359 +:10453000AE85BF854D915D916D917C914115510581 +:104540006105710539F0C101950184010E94BC200B +:104550008823B1F0EE85FF8580829182A282B382AA +:10456000F985FF2359F00894811C911CA11CB11CF2 +:10457000D1018D929D92AD92BC92139781E001C0C2 +:1045800080E02F960FB6F894DEBF0FBECDBFCF915F +:10459000DF911F910F91FF90EF90DF90CF90BF9030 +:1045A000AF909F908F907F906F905F904F903F90D3 +:1045B0002F9008951F920F920FB60F9211242F93F0 +:1045C0003F938F939F93AF93BF9380916A22909173 +:1045D0006B22A0916C22B0916D2230916E220196D7 +:1045E000A11DB11D232F2D5F2D3720F02D570196D2 +:1045F000A11DB11D20936E2280936A2290936B229D +:10460000A0936C22B0936D228091662290916722D4 +:10461000A0916822B09169220196A11DB11D8093DD +:10462000662290936722A0936822B0936922BF917B +:10463000AF919F918F913F912F910F900FBE0F904F +:104640001F9018958FB7F89420916A2230916B22B1 +:1046500040916C2250916D228FBFB901CA0108951B +:104660009B01AC017FB7F8948091662290916722FC +:10467000A0916822B091692266B5A89B05C06F3FE2 +:1046800019F00196A11DB11D7FBFBA2FA92F982F38 +:104690008827860F911DA11DB11D62E0880F991F0B +:1046A000AA1FBB1F6A95D1F7BC012DC0FFB7F894B4 +:1046B0008091662290916722A0916822B091692230 +:1046C000E6B5A89B05C0EF3F19F00196A11DB11DED +:1046D000FFBFBA2FA92F982F88278E0F911DA11DDC +:1046E000B11DE2E0880F991FAA1FBB1FEA95D1F701 +:1046F000861B970B885E9340C8F2215030404040A3 +:10470000504068517C4F211531054105510571F626 +:104710000895789484B5826084BD84B5816084BD39 +:1047200085B5826085BD85B5816085BDEEE6F0E02A +:10473000808181608083E1E8F0E010828081826086 +:104740008083808181608083E0E8F0E08081816007 +:104750008083E1EBF0E0808184608083E0EBF0E037 +:10476000808181608083E1E9F0E0808182608083E4 +:10477000808181608083E0E9F0E0808181608083D6 +:10478000EAE7F0E0808184608083808182608083BA +:104790008081816080838081806880831092C100E5 +:1047A0000895982F883108F09851977080911201E0 +:1047B0008295880F880F807C892B80937C00809164 +:1047C0007A00806480937A0080917A0086FDFCCF25 +:1047D0002091780040917900942F80E030E0282BE0 +:1047E000392BC90108951F93CF93DF93182FEB0145 +:1047F00061E00E947124209709F468C0CF3FD10581 +:1048000009F467C0E12FF0E0E457F94F8491843058 +:1048100061F1853040F48230C9F08330E0F48130BA +:1048200009F051C00EC0873091F1883020F48630F5 +:1048300009F049C024C0883091F1893009F043C0A3 +:1048400038C084B5806884BDC7BD47C084B5806268 +:1048500084BDC8BD42C08091800080688093800084 +:10486000D0938900C093880038C080918000806216 +:1048700080938000D0938B00C0938A002EC08091DB +:10488000B00080688093B000C093B30026C08091D0 +:10489000B00080628093B000C093B4001EC08091CD +:1048A0009000806880939000D0939900C093980006 +:1048B00014C080919000806280939000D0939B0000 +:1048C000C0939A000AC0C038D1051CF4812F60E063 +:1048D00002C0812F61E00E94D524DF91CF911F910A +:1048E0000895482F50E0CA018459994FFC01249142 +:1048F000445B594FFA0184918823C1F0E82FF0E01E +:10490000EE0FFF1FE25DF94FA591B491662341F4CC +:104910009FB7F8948C91209582238C939FBF089524 +:104920009FB7F8948C91822B8C939FBF089584300D +:10493000C9F0853038F48230F1F0833078F481307A +:1049400099F516C08730F9F0883018F4863061F593 +:1049500016C08830F1F0893039F521C0809180008F +:104960008F7703C0809180008F7D809380000895B1 +:1049700084B58F7702C084B58F7D84BD0895809102 +:10498000B0008F7703C08091B0008F7D8093B0001E +:104990000895809190008F77809390000895809182 +:1049A00090008F7D809390000895FF920F931F9346 +:1049B000F62E482F50E0CA018457994FFC012491EC +:1049C000CA018459994FFC011491445B594FFA0173 +:1049D00004910023C9F0222319F0822F0E9497240A +:1049E000E02FF0E0EE0FFF1FE85CF94FA591B491C6 +:1049F0009FB7F894FF2021F48C911095812302C079 +:104A00008C91812B8C939FBF1F910F91FF900895E4 +:104A10000F931F93482F50E0CA018457994FFC0110 +:104A20002491CA018459994FFC010491445B594F68 +:104A3000FA011491112319F420E030E015C022236B +:104A400019F0822F0E949724812F90E0880F991FE0 +:104A50008E5B994FFC01A591B4918C9120E030E0E0 +:104A6000802311F021E030E0C9011F910F910895DA +:104A700008951F920F920FB60F920BB60F9211244A +:104A80002F933F934F938F939F93EF93FF93409177 +:104A9000C6002091AF223091B0222F5F3F4F2F737D +:104AA00030708091B1229091B2222817390759F0C5 +:104AB000E091AF22F091B022E159FD4D4083309357 +:104AC000B0222093AF22FF91EF919F918F914F9150 +:104AD0003F912F910F900BBE0F900FBE0F901F9024 +:104AE000189508951F920F920FB60F920BB60F9262 +:104AF00011242F933F934F938F939F93EF93FF93A3 +:104B00004091CE0020913723309138232F5F3F4FC3 +:104B10002F7330708091392390913A2328173907E9 +:104B200059F0E0913723F0913823E950FD4D40834F +:104B30003093382320933723FF91EF919F918F91EA +:104B40004F913F912F910F900BBE0F900FBE0F9082 +:104B50001F901895E0918B23F0918C23E05CFF4F20 +:104B60008191919120813181821B930B8F73907081 +:104B7000892B11F00E943825E091AA23F091AB23F4 +:104B8000E05CFF4F8191919120813181821B930BD9 +:104B90008F739070892B11F00E94712508951F92D8 +:104BA0000F920FB60F920BB60F9211242F933F93D3 +:104BB0004F935F936F937F938F939F93AF93BF9325 +:104BC000EF93FF932091F3223091F4228091F5220C +:104BD0009091F6222817390731F48091C1008F7D1A +:104BE0008093C10016C0E091F522F091F622ED54B9 +:104BF000FD4D40818091F5229091F622019660E46E +:104C000070E00E94412B9093F6228093F52240930E +:104C1000C600FF91EF91BF91AF919F918F917F91CE +:104C20006F915F914F913F912F910F900BBE0F901D +:104C30000FBE0F901F9018951F920F920FB60F92F4 +:104C40000BB60F9211242F933F934F935F936F9363 +:104C50007F938F939F93AF93BF93EF93FF93209195 +:104C60007B2330917C2380917D2390917E23281794 +:104C7000390731F48091C9008F7D8093C90016C037 +:104C8000E0917D23F0917E23E55CFC4D4081809195 +:104C90007D2390917E23019660E470E00E94412B79 +:104CA00090937E2380937D234093CE00FF91EF91DC +:104CB000BF91AF919F918F917F916F915F914F9134 +:104CC0003F912F910F900BBE0F900FBE0F901F9032 +:104CD0001895DC011C96ED91FC911D97E05CFF4F4F +:104CE0002191319180819181281B390B2F73307074 +:104CF000C9010895DC011C96ED91FC911D97E05CC3 +:104D0000FF4F20813181E054F040DF01AE5BBF4FA7 +:104D10008D919C9111972817390719F42FEF3FEFC8 +:104D200007C08D919C91E80FF91F8081282F30E0FA +:104D3000C9010895DC011C96ED91FC911D97E05C82 +:104D4000FF4F20813181E054F040DF01AE5BBF4F67 +:104D50008D919C9111972817390719F42FEF3FEF88 +:104D600010C08D919C911197E80FF91F20818D91B2 +:104D70009C91119701968F73907011969C938E93CE +:104D800030E0C9010895FC0186859785DC01A05CAF +:104D9000BF4FFC01EE5BFF4F2D913C91119780813D +:104DA000918128173907C1F70895CF93DF93EC015C +:104DB000462FEE85FF85E05CFF4F80819181E054B6 +:104DC000F040019660E470E00E94412B9C01DF01FD +:104DD000AE5BBF4F8D919C91119728173907D1F386 +:104DE000E05CFF4F80819181E054F040E80FF91FB3 +:104DF0004083EE85FF85E05CFF4F31832083EE89A1 +:104E0000FF89208181E090E00D8C02C0880F991FFE +:104E10000A94E2F7282B208381E090E0DF91CF9184 +:104E200008951F93109282231092812328EE33E07D +:104E300040E050E0209383233093842340938523E4 +:104E40005093862360E271E07093802360937F2308 +:104E50008FE692E290938C2380938B2383EB92E2F4 +:104E600090938E2380938D2385EC90E090939023F4 +:104E700080938F2384EC90E09093922380939123EE +:104E800080EC90E0909394238093932381EC90E0C6 +:104E9000909396238093952386EC90E090939823AB +:104EA0008093972314E010939923B3E0B0939A234F +:104EB000A7E0A0939B23F5E0F0939C23E1E0E0932F +:104EC0009D231092A1231092A0232093A22330931C +:104ED000A3234093A4235093A52370939F2360930F +:104EE0009E2387EF92E29093AB238093AA238BE3D8 +:104EF00093E29093AD238093AC238DEC90E090935C +:104F0000AF238093AE238CEC90E09093B1238093F9 +:104F1000B02388EC90E09093B3238093B22389EC84 +:104F200090E09093B5238093B4238EEC90E090931F +:104F3000B7238093B6231093B823B093B923A093DB +:104F4000BA23F093BB23E093BC231F910895CF9322 +:104F5000DF930E9489230E947B05CAEAD5E20E9462 +:104F6000D4072097E1F30E94AA25F9CFCF92DF92D0 +:104F7000EF92FF920F931F93CF93DF937C016B010E +:104F80008A01C0E0D0E00FC0D6016D916D01D7015C +:104F9000ED91FC910190F081E02DC7010995C80FBA +:104FA000D91F015010400115110571F7CE01DF9195 +:104FB000CF911F910F91FF90EF90DF90CF900895C8 +:104FC000813051F0813028F0823061F08330E9F493 +:104FD0001AC010926E00089580916F008D7F8093AB +:104FE0006F000895809170008D7F8093700081E044 +:104FF0008093B0008091B100887F84608093B1007D +:105000001092B30008951092710008951F93182F05 +:1050100080911301811711F09FEF06C0ECEAF6E0D2 +:1050200094918FEF80931301892F0E94E027812FA5 +:1050300060E00E94D5241F9108951F920F920FB631 +:105040000F920BB60F9211242F933F934F935F93C0 +:105050006F937F938F939F93AF93BF93EF93FF9340 +:105060008091CB239091CC23A091CD23B091CE23DE +:105070000097A105B10551F1E091CF23F091D02324 +:1050800080819091D123892780838091CB23909137 +:10509000CC23A091CD23B091CE23181619061A0661 +:1050A0001B06C4F48091CB239091CC23A091CD23F7 +:1050B000B091CE230197A109B1098093CB2390939E +:1050C000CC23A093CD23B093CE2304C080911301B1 +:1050D0000E940628FF91EF91BF91AF919F918F9110 +:1050E0007F916F915F914F913F912F910F900BBEE8 +:1050F0000F900FBE0F901F9018952F923F925F92C6 +:105100006F927F928F929F92AF92BF92CF92DF92D7 +:10511000EF92FF920F931F93DF93CF9300D000D0B5 +:10512000CDB7DEB7A82F1B0129833A834B835C835D +:10513000809113018A1721F4ECEAF6E05490AFC095 +:105140008F3F09F02BC2A0931301ECEAF6E05490D4 +:105150002FEF521609F422C281E0581671F185151D +:105160001CF0552051F09BC092E0591609F44BC039 +:10517000B3E05B1609F093C06CC014BC15BC84B5D9 +:10518000826084BD85B5816085BD2A2F30E0F9013C +:10519000E45BF94FE491F0E0EE0FFF1FE85CF94F9C +:1051A000859194919093C2238093C1232459394FC0 +:1051B000F90184918093C32374C0109280001092EF +:1051C00081008091810088608093810080918100BE +:1051D0008160809381002A2F30E0F901E45BF94F70 +:1051E000E491F0E0EE0FFF1FE85CF94F8591949198 +:1051F0009093C9238093C8232459394FF90184918E +:105200008093CA234EC01092B0001092B1008091DA +:10521000B00082608093B0008091B1008160809383 +:10522000B1002A2F30E0F901E45BF94FE491F0E09E +:10523000EE0FFF1FE85CF94F859194919093D02376 +:105240008093CF232459394FF90184918093D1233E +:1052500028C0109290001092910080919100886077 +:1052600080939100809191008160809391002A2F1A +:1052700030E0F901E45BF94FE491F0E0EE0FFF1F3D +:10528000E85CF94F859194919093D7238093D6232E +:105290002459394FF90184918093D82302C057FCD7 +:1052A0007DC18A2F61E00E947124552021F0F2E037 +:1052B0005F1609F0BEC031018824992460E072E1D4 +:1052C0008AE790E0A40193010E94762B59016A01BC +:1052D000860175010894E108F108010911092FEF11 +:1052E000E216F1040105110509F008F499C060E423 +:1052F00072E48FE090E0A40193010E94762B790183 +:105300008A010894E108F1080109110982E05816A0 +:10531000C1F49FEFE916F1040105110509F008F445 +:1053200084C060E970ED83E090E0A40193010E94E5 +:10533000762B79018A010894E108F1080109110925 +:1053400083E0AFEFEA16F1040105110509F008F456 +:1053500068C068E478EE81E090E0A40193010E94C7 +:10536000762B79018A010894E108F10801091109F5 +:10537000552011F483E01DC0B2E05B1611F084E00B +:1053800018C0EFEFEE16F1040105110509F008F45D +:1053900003C164E274EF80E090E0A40193010E94F5 +:1053A000762B79018A010894E108F10801091109B5 +:1053B00085E0FFEFEF16F1040105110591F188F189 +:1053C00062E17AE780E090E0A40193010E94762BED +:1053D00079018A010894E108F108010911095520B1 +:1053E00011F086E001C084E02FEFE216F104010520 +:1053F0001105B9F0B0F0C601B50120E034E040E09D +:1054000050E00E94762B79018A010894E108F108A6 +:1054100001091109552011F087E008C085E003C09B +:1054200081E0552019F485BD44C082E08093B1002D +:1054300040C05101CC24DD2460E072E18AE790E0B5 +:10544000A60195010E94762B79018A010894E10852 +:10545000F1080109110980E0E81680E0F80681E012 +:10546000080780E0180710F491E010C068E478EEB7 +:1054700081E090E0A60195010E94762B79018A01D6 +:105480000894E108F1080109110993E0A1E05A1616 +:1054900039F480918100887F982B9093810009C016 +:1054A000B3E05B1631F480919100887F982B909344 +:1054B000910089819A81AB81BC810097A105B105DA +:1054C00029F48FEF9FEFAFEFBFEF13C0220C331C17 +:1054D000B10180E090E029813A814B815C810E949A +:1054E0000E2B28EE33E040E050E00E94542BC9011F +:1054F000DA01E1E05E16E1F0E5151CF0552049F017 +:105500004DC0F2E05F1631F123E0521609F046C0BB +:1055100031C0E7BC8093BD239093BE23A093BF23EB +:10552000B093C02380916E00826080936E0036C07D +:10553000F0928900E09288008093C4239093C52361 +:10554000A093C623B093C72380916F00826080939D +:105550006F0024C0E092B3008093CB239093CC23C0 +:10556000A093CD23B093CE2380917000826080936E +:10557000700014C0F0929900E09298008093D223BA +:105580009093D323A093D423B093D523809171001B +:1055900082608093710002C084E048CF0F900F902A +:1055A0000F900F90CF91DF911F910F91FF90EF908F +:1055B000DF90CF90BF90AF909F908F907F906F9033 +:1055C0005F903F902F900895EF92FF920F931F935B +:1055D0007B018C01611571058105910529F420E09D +:1055E00030E040E050E00BC00E94DB04A8019701CE +:1055F0000E94762BAC01CB01DA019C01AD01B9010F +:10560000CA011F910F91FF90EF900895009729F024 +:10561000BC0180E090E00E94E0040895629FD00108 +:10562000739FF001829FE00DF11D649FE00DF11D5D +:10563000929FF00D839FF00D749FF00D659FF00D0C +:105640009927729FB00DE11DF91F639FB00DE11DF9 +:10565000F91FBD01CF0111240895AA1BBB1B51E105 +:1056600007C0AA1FBB1FA617B70710F0A61BB70BD2 +:10567000881F991F5A95A9F780959095BC01CD0177 +:10568000089597FB092E07260AD077FD04D0E5DFA1 +:1056900006D000201AF4709561957F4F0895F6F7B3 +:1056A000909581959F4F0895A1E21A2EAA1BBB1BCE +:1056B000FD010DC0AA1FBB1FEE1FFF1FA217B307DE +:1056C000E407F50720F0A21BB30BE40BF50B661FF4 +:1056D000771F881F991F1A9469F7609570958095B8 +:1056E00090959B01AC01BD01CF01089597FB092E58 +:1056F00005260ED057FD04D0D7DF0AD0001C38F4A1 +:1057000050954095309521953F4F4F4F5F4F0895ED +:10571000F6F790958095709561957F4F8F4F9F4FCD +:105720000895EE0FFF1F0590F491E02D09942F923C +:105730003F924F925F926F927F928F929F92AF9221 +:10574000BF92CF92DF92EF92FF920F931F93CF936E +:10575000DF93CDB7DEB7CA1BDB0B0FB6F894DEBF05 +:105760000FBECDBF09942A88398848885F846E842B +:105770007D848C849B84AA84B984C884DF80EE8075 +:10578000FD800C811B81AA81B981CE0FD11D0FB67E +:10579000F894DEBF0FBECDBFED010895F894FFCFA2 +:1057A0002000DD230000010000006B146B14FFFFDC +:1057B000FFFF01FF000000003520B62700000000B9 +:0C57C000D526B62769269A267A26C3262D +:00000001FF diff --git a/trunk/Arduino/Single_Chip_Computer/Single_Chip_Computer_1.15.ino.txt b/trunk/Arduino/Single_Chip_Computer/Single_Chip_Computer_1.15.ino.txt new file mode 100644 index 00000000..ed458c73 --- /dev/null +++ b/trunk/Arduino/Single_Chip_Computer/Single_Chip_Computer_1.15.ino.txt @@ -0,0 +1,2278 @@ +//////////////////////////////////////////////////////////////////////////////// +// TinyBasic Plus +//////////////////////////////////////////////////////////////////////////////// +// +// Authors: Mike Field +// Scott Lawrence +// Dan +// + +#define kVersion "v0.15" + +// v0.15: 13/08/2014 +// Support for external EEPROM (25LC640) added - used for storing programs. +// Requires library for external EEPROM access (SPIEEPROM). SPI pins might not +// be usable for GPIO while the SPIEEPROM library is active in this sketch. +// +// v0.14: 19/04/2014 +// TVout and PS2uartKeyboard Libraries added. +// +// v0.13: 2013-03-04 +// Support for Arduino 1.5 (SPI.h included, additional changes for DUE support) +// +// v0.12: 2013-03-01 +// EEPROM load and save routines added: EFORMAT, ELIST, ELOAD, ESAVE, ECHAIN +// added EAUTORUN option (chains to EEProm saved program on startup) +// Bugfixes to build properly on non-arduino systems (PROGMEM #define workaround) +// cleaned up a bit of the #define options wrt TONE +// +// v0.11: 2013-02-20 +// all display strings and tables moved to PROGMEM to save space +// removed second serial +// removed pinMode completely, autoconf is explicit +// beginnings of EEPROM related functionality (new,load,save,list) +// +// v0.10: 2012-10-15 +// added kAutoConf, which eliminates the "PINMODE" statement. +// now, DWRITE,DREAD,AWRITE,AREAD automatically set the PINMODE appropriately themselves. +// should save a few bytes in your programs. +// +// v0.09: 2012-10-12 +// Fixed directory listings. FILES now always works. (bug in the SD library) +// ref: http://arduino.cc/forum/index.php/topic,124739.0.html +// fixed filesize printouts (added printUnum for unsigned numbers) +// #defineable baud rate for slow connection throttling +//e +// v0.08: 2012-10-02 +// Tone generation through piezo added (TONE, TONEW, NOTONE) +// +// v0.07: 2012-09-30 +// Autorun buildtime configuration feature +// +// v0.06: 2012-09-27 +// Added optional second serial input, used for an external keyboard +// +// v0.05: 2012-09-21 +// CHAIN to load and run a second file +// RND,RSEED for random stuff +// Added "!=" for "<>" synonym +// Added "END" for "STOP" synonym (proper name for the functionality anyway) +// +// v0.04: 2012-09-20 +// DELAY ms - for delaying +// PINMODE , INPUT|IN|I|OUTPUT|OUT|O +// DWRITE , HIGH|HI|1|LOW|LO|0 +// AWRITE , [0..255] +// fixed "save" appending to existing files instead of overwriting +// Updated for building desktop command line app (incomplete) +// +// v0.03: 2012-09-19 +// Integrated Jurg Wullschleger whitespace,unary fix +// Now available through github +// Project renamed from "Tiny Basic in C" to "TinyBasic Plus" +// +// v0.02b: 2012-09-17 Scott Lawrence +// Better FILES listings +// +// v0.02a: 2012-09-17 Scott Lawrence +// Support for SD Library +// Added: SAVE, FILES (mostly works), LOAD (mostly works) (redirects IO) +// Added: MEM, ? (PRINT) +// Quirk: "10 LET A=B+C" is ok "10 LET A = B + C" is not. +// Quirk: INPUT seems broken? + +/* +* Additional Libraries +*/ +// TVout +#include +#include +#include +#include +#include +#include +#include +// PS2 Keyboard +#include + +PS2uartKeyboard keyboard; +TVout TV; + + +// IF testing with Visual C, this needs to be the first thing in the file. +//#include "stdafx.h" + + +char eliminateCompileErrors = 1; // fix to suppress arduino build errors + +// hack to let makefiles work with this file unchanged +#ifdef FORCE_DESKTOP +#undef ARDUINO +#else +#define ARDUINO 1 +#endif + +//////////////////////////////////////////////////////////////////////////////// +// Feature option configuration... + +// This enables LOAD, SAVE, FILES commands through the Arduino SD Library +// it adds 9k of usage as well. +//#define ENABLE_FILEIO 1 +#undef ENABLE_FILEIO + +// this turns on "autorun". if there's FileIO, and a file "autorun.bas", +// then it will load it and run it when starting up +//#define ENABLE_AUTORUN 1 +#undef ENABLE_AUTORUN +// and this is the file that gets run +#define kAutorunFilename "autorun.bas" + +// this is the alternate autorun. Autorun the program in the eeprom. +// it will load whatever is in the EEProm and run it +#define ENABLE_EAUTORUN 1 +//#undef ENABLE_EAUTORUN + +// this will enable the "TONE", "NOTONE" command using a piezo +// element on the specified pin. Wire the red/positive/piezo to the kPiezoPin, +// and the black/negative/metal disc to ground. +// it adds 1.5k of usage as well. +//#define ENABLE_TONES 1 +#undef ENABLE_TONES +#define kPiezoPin 15 + +// we can use the EEProm to store a program during powerdown. This is +// 1keyboardyte on the '328, and 512 bytes on the '168. Enabling this here will +// allow for this funcitonality to work. Note that this only works on AVR +// arduino. Disable it for DUE/other devices. +#define ENABLE_EEPROM 1 +//#undef ENABLE_EEPROM + +// Sometimes, we connect with a slower device as the console. +// Set your console D0/D1 baud rate here (9600 baud default) +#define kConsoleBaud 9600 + +//////////////////////////////////////////////////////////////////////////////// +#ifdef ARDUINO +#ifndef RAMEND +// okay, this is a hack for now +// if we're in here, we're a DUE probably (ARM instead of AVR) + +#define RAMEND 4096-1 + +// turn off EEProm +#undef ENABLE_EEPROM +#undef ENABLE_TONES + +#else +// we're an AVR! + +// we're moving our data strings into progmem +#include +#endif + +// includes, and settings for Arduino-specific functionality +#ifdef ENABLE_EEPROM +// Internal EEPROM +#include /* NOTE: case sensitive */ +long eepos = 0; +// EEPROM Card +#include +#include +SPIEEPROM disk1(0); // Type 0 = 16bit address +boolean use_ecard = false; // true = ECARD, false = internal EEPROM +#endif + + +#ifdef ENABLE_FILEIO +#include +#include /* needed as of 1.5 beta */ + +// Arduino-specific configuration +// set this to the card select for your SD shield +#define kSD_CS 4 + +#define kSD_Fail 0 +#define kSD_OK 1 + +File fp; +#endif + +// set up our RAM buffer size for program and user input +// NOTE: This number will have to change if you include other libraries. +#ifdef ARDUINO +#ifdef ENABLE_FILEIO +#define kRamFileIO (1100) /* approximate */ +#else +#define kRamFileIO (0) +#endif +#ifdef ENABLE_TONES +#define kRamTones (40) +#else +#define kRamTones (0) +#endif +#endif /* ARDUINO */ +#define kRamSize (RAMEND - 8803 - kRamFileIO - kRamTones) + +#ifndef ARDUINO +// Not arduino setup +#include +#include +#undef ENABLE_TONES + +// size of our program ram +#define kRamSize 4096 /* arbitrary */ + +#ifdef ENABLE_FILEIO +FILE * fp; +#endif +#endif + +#ifdef ENABLE_FILEIO +// functions defined elsehwere +void cmd_Files( void ); +#endif + +//////////////////// + +#ifndef boolean +#define boolean int +#define true 1 +#define false 0 +#endif +#endif + +#ifndef byte +typedef unsigned char byte; +#endif + +// some catches for AVR based text string stuff... +#ifndef PROGMEM +#define PROGMEM +#endif +#ifndef pgm_read_byte +#define pgm_read_byte( A ) *(A) +#endif + +//////////////////// + +#ifdef ENABLE_FILEIO +unsigned char * filenameWord(void); +static boolean sd_is_initialized = false; +#endif + +boolean inhibitOutput = false; +static boolean runAfterLoad = false; +static boolean triggerRun = false; + +// these will select, at runtime, where IO happens through for load/save +enum { + kStreamSerial = 0, + kStreamEEProm, + kStreamFile +}; +static unsigned char inStream = kStreamSerial; +static unsigned char outStream = kStreamSerial; + + +//////////////////////////////////////////////////////////////////////////////// +// ASCII Characters +#define CR '\r' +#define NL '\n' +#define LF 0x0a +#define TAB '\t' +#define BELL '\b' +#define SPACE ' ' +#define SQUOTE '\'' +#define DQUOTE '\"' +#define CTRLC 0x1B // Changed to ESC key (27 - 0x1B) +#define CTRLH 0x08 +#define CTRLS 0x13 +#define CTRLX 0x18 + +typedef short unsigned LINENUM; +#ifdef ARDUINO +#define ECHO_CHARS 1 +#else +#define ECHO_CHARS 0 +#endif + + +static unsigned char program[kRamSize]; +static const char * sentinel = "Single Chip Computer V0.3"; +static unsigned char *txtpos,*list_line; +static unsigned char expression_error; +static unsigned char *tempsp; + +/***********************************************************/ +// Keyword table and constants - the last character has 0x80 added to it +static unsigned char keywords[] PROGMEM = { + 'L','I','S','T'+0x80, + 'L','O','A','D'+0x80, + 'N','E','W'+0x80, + 'R','U','N'+0x80, + 'S','A','V','E'+0x80, + 'N','E','X','T'+0x80, + 'L','E','T'+0x80, + 'I','F'+0x80, + 'G','O','T','O'+0x80, + 'G','O','S','U','B'+0x80, + 'R','E','T','U','R','N'+0x80, + 'R','E','M'+0x80, + 'F','O','R'+0x80, + 'I','N','P','U','T'+0x80, + 'P','R','I','N','T'+0x80, + 'P','O','K','E'+0x80, + 'S','T','O','P'+0x80, + 'B','Y','E'+0x80, + 'F','I','L','E','S'+0x80, + 'M','E','M'+0x80, + '?'+ 0x80, + '\''+ 0x80, + 'A','W','R','I','T','E'+0x80, + 'D','W','R','I','T','E'+0x80, + 'D','E','L','A','Y'+0x80, + 'E','N','D'+0x80, + 'R','S','E','E','D'+0x80, + 'C','H','A','I','N'+0x80, +#ifdef ENABLE_TONES + 'T','O','N','E','W'+0x80, + 'T','O','N','E'+0x80, + 'N','O','T','O','N','E'+0x80, +#endif +#ifdef ARDUINO +#ifdef ENABLE_EEPROM + 'E','C','H','A','I','N'+0x80, + 'E','L','I','S','T'+0x80, + 'E','L','O','A','D'+0x80, + 'E','F','O','R','M','A','T'+0x80, + 'E','S','A','V','E'+0x80, +#endif +#endif + 0 +}; + +// by moving the command list to an enum, we can easily remove sections +// above and below simultaneously to selectively obliterate functionality. +enum { + KW_LIST = 0, + KW_LOAD, KW_NEW, KW_RUN, KW_SAVE, + KW_NEXT, KW_LET, KW_IF, + KW_GOTO, KW_GOSUB, KW_RETURN, + KW_REM, + KW_FOR, + KW_INPUT, KW_PRINT, + KW_POKE, + KW_STOP, KW_BYE, + KW_FILES, + KW_MEM, + KW_QMARK, KW_QUOTE, + KW_AWRITE, KW_DWRITE, + KW_DELAY, + KW_END, + KW_RSEED, + KW_CHAIN, +#ifdef ENABLE_TONES + KW_TONEW, KW_TONE, KW_NOTONE, +#endif +#ifdef ARDUINO +#ifdef ENABLE_EEPROM + KW_ECHAIN, KW_ELIST, KW_ELOAD, KW_EFORMAT, KW_ESAVE, +#endif +#endif + KW_DEFAULT /* always the final one*/ +}; + +struct stack_for_frame { + char frame_type; + char for_var; + short int terminal; + short int step; + unsigned char *current_line; + unsigned char *txtpos; +}; + +struct stack_gosub_frame { + char frame_type; + unsigned char *current_line; + unsigned char *txtpos; +}; + +static unsigned char func_tab[] PROGMEM = { + 'P','E','E','K'+0x80, + 'A','B','S'+0x80, + 'A','R','E','A','D'+0x80, + 'D','R','E','A','D'+0x80, + 'R','N','D'+0x80, + 0 +}; +#define FUNC_PEEK 0 +#define FUNC_ABS 1 +#define FUNC_AREAD 2 +#define FUNC_DREAD 3 +#define FUNC_RND 4 +#define FUNC_UNKNOWN 5 + +static unsigned char to_tab[] PROGMEM = { + 'T','O'+0x80, + 0 +}; + +static unsigned char step_tab[] PROGMEM = { + 'S','T','E','P'+0x80, + 0 +}; + +static unsigned char relop_tab[] PROGMEM = { + '>','='+0x80, + '<','>'+0x80, + '>'+0x80, + '='+0x80, + '<','='+0x80, + '<'+0x80, + '!','='+0x80, + 0 +}; + +#define RELOP_GE 0 +#define RELOP_NE 1 +#define RELOP_GT 2 +#define RELOP_EQ 3 +#define RELOP_LE 4 +#define RELOP_LT 5 +#define RELOP_NE_BANG 6 +#define RELOP_UNKNOWN 7 + +static unsigned char highlow_tab[] PROGMEM = { + 'H','I','G','H'+0x80, + 'H','I'+0x80, + 'L','O','W'+0x80, + 'L','O'+0x80, + 0 +}; +#define HIGHLOW_HIGH 1 +#define HIGHLOW_UNKNOWN 4 + +#define STACK_SIZE (sizeof(struct stack_for_frame)*5) +#define VAR_SIZE sizeof(short int) // Size of variables in bytes + +static unsigned char *stack_limit; +static unsigned char *program_start; +static unsigned char *program_end; +static unsigned char *stack; // Software stack for things that should go on the CPU stack +static unsigned char *variables_begin; +static unsigned char *current_line; +static unsigned char *sp1; +#define STACK_GOSUB_FLAG 'G' +#define STACK_FOR_FLAG 'F' +static unsigned char table_index; +static LINENUM linenum; + +static const unsigned char okmsg[] PROGMEM = "OK"; +static const unsigned char whatmsg[] PROGMEM = "What? "; +static const unsigned char howmsg[] PROGMEM = "How?"; +static const unsigned char sorrymsg[] PROGMEM = "Sorry!"; +static const unsigned char initmsg[] PROGMEM = "TinyBasic Plus " kVersion; +static const unsigned char memorymsg[] PROGMEM = " bytes free."; +#ifdef ARDUINO +#ifdef ENABLE_EEPROM +static const unsigned char eeprommsg[] PROGMEM = " EEProm bytes total."; +static const unsigned char eepromamsg[] PROGMEM = " EEProm bytes available."; +#endif +#endif +static const unsigned char breakmsg[] PROGMEM = "break!"; +static const unsigned char unimplimentedmsg[] PROGMEM = "Unimplemented"; +static const unsigned char backspacemsg[] PROGMEM = "\b \b"; +static const unsigned char indentmsg[] PROGMEM = " "; +static const unsigned char sderrormsg[] PROGMEM = "SD card error."; +static const unsigned char sdfilemsg[] PROGMEM = "SD file error."; +static const unsigned char dirextmsg[] PROGMEM = "(dir)"; +static const unsigned char slashmsg[] PROGMEM = "/"; +static const unsigned char spacemsg[] PROGMEM = " "; + +static int inchar(void); +static void outchar(unsigned char c); +static void line_terminator(void); +static short int expression(void); +static unsigned char breakcheck(void); +/***************************************************************************/ +static void ignore_blanks(void) +{ + while(*txtpos == SPACE || *txtpos == TAB) + txtpos++; +} + + +/***************************************************************************/ +static void scantable(unsigned char *table) +{ + int i = 0; + table_index = 0; + while(1) + { + // Run out of table entries? + if(pgm_read_byte( table ) == 0) + return; + + // Do we match this character? + if(txtpos[i] == pgm_read_byte( table )) + { + i++; + table++; + } + else + { + // do we match the last character of keywork (with 0x80 added)? If so, return + if(txtpos[i]+0x80 == pgm_read_byte( table )) + { + txtpos += i+1; // Advance the pointer to following the keyword + ignore_blanks(); + return; + } + + // Forward to the end of this keyword + while((pgm_read_byte( table ) & 0x80) == 0) + table++; + + // Now move on to the first character of the next word, and reset the position index + table++; + table_index++; + ignore_blanks(); + i = 0; + } + } +} + +/***************************************************************************/ +static void pushb(unsigned char b) +{ + sp1--; + *sp1 = b; +} + +/***************************************************************************/ +static unsigned char popb() +{ + unsigned char b; + b = *sp1; + sp1++; + return b; +} + +/***************************************************************************/ +void printnum(int num) +{ + int digits = 0; + + if(num < 0) + { + num = -num; + outchar('-'); + } + do { + pushb(num%10+'0'); + num = num/10; + digits++; + } + while (num > 0); + + while(digits > 0) + { + outchar(popb()); + digits--; + } +} + +void printUnum(unsigned int num) +{ + int digits = 0; + + do { + pushb(num%10+'0'); + num = num/10; + digits++; + } + while (num > 0); + + while(digits > 0) + { + outchar(popb()); + digits--; + } +} + +/***************************************************************************/ +static unsigned short testnum(void) +{ + unsigned short num = 0; + ignore_blanks(); + + while(*txtpos>= '0' && *txtpos <= '9' ) + { + // Trap overflows + if(num >= 0xFFFF/10) + { + num = 0xFFFF; + break; + } + + num = num *10 + *txtpos - '0'; + txtpos++; + } + return num; +} + +/***************************************************************************/ +static unsigned char print_quoted_string(void) +{ + int i=0; + unsigned char delim = *txtpos; + if(delim != '"' && delim != '\'') + return 0; + txtpos++; + + // Check we have a closing delimiter + while(txtpos[i] != delim) + { + if(txtpos[i] == NL) + return 0; + i++; + } + + // Print the characters + while(*txtpos != delim) + { + outchar(*txtpos); + txtpos++; + } + txtpos++; // Skip over the last delimiter + + return 1; +} + + +/***************************************************************************/ +void printmsgNoNL(const unsigned char *msg) +{ + while( pgm_read_byte( msg ) != 0 ) { + outchar( pgm_read_byte( msg++ ) ); + }; +} + +/***************************************************************************/ +void printmsg(const unsigned char *msg) +{ + printmsgNoNL(msg); + line_terminator(); +} + +/***************************************************************************/ +static void getln(char prompt) +{ + outchar(prompt); + txtpos = program_end+sizeof(LINENUM); + + while(1) + { + char c = inchar(); + switch(c) + { + case NL: + //break; + case CR: + line_terminator(); + // Terminate all strings with a NL + txtpos[0] = NL; + return; + case CTRLH: + if(txtpos == program_end) + break; + txtpos--; + + printmsg(backspacemsg); + break; + default: + // We need to leave at least one space to allow us to shuffle the line into order + if(txtpos == variables_begin-2) + outchar(BELL); + else + { + txtpos[0] = c; + txtpos++; + outchar(c); + } + } + } +} + +/***************************************************************************/ +static unsigned char *findline(void) +{ + unsigned char *line = program_start; + while(1) + { + if(line == program_end) + return line; + + if(((LINENUM *)line)[0] >= linenum) + return line; + + // Add the line length onto the current address, to get to the next line; + line += line[sizeof(LINENUM)]; + } +} + +/***************************************************************************/ +static void toUppercaseBuffer(void) +{ + unsigned char *c = program_end+sizeof(LINENUM); + unsigned char quote = 0; + + while(*c != NL) + { + // Are we in a quoted string? + if(*c == quote) + quote = 0; + else if(*c == '"' || *c == '\'') + quote = *c; + else if(quote == 0 && *c >= 'a' && *c <= 'z') + *c = *c + 'A' - 'a'; + c++; + } +} + +/***************************************************************************/ +void printline() +{ + LINENUM line_num; + + line_num = *((LINENUM *)(list_line)); + list_line += sizeof(LINENUM) + sizeof(char); + + // Output the line */ + printnum(line_num); + outchar(' '); + while(*list_line != NL) + { + outchar(*list_line); + list_line++; + } + list_line++; + line_terminator(); +} + +/***************************************************************************/ +static short int expr4(void) +{ + // fix provided by Jurg Wullschleger wullschleger@gmail.com + // fixes whitespace and unary operations + ignore_blanks(); + + if( *txtpos == '-' ) { + txtpos++; + return -expr4(); + } + // end fix + + if(*txtpos == '0') + { + txtpos++; + return 0; + } + + if(*txtpos >= '1' && *txtpos <= '9') + { + short int a = 0; + do { + a = a*10 + *txtpos - '0'; + txtpos++; + } + while(*txtpos >= '0' && *txtpos <= '9'); + return a; + } + + // Is it a function or variable reference? + if(txtpos[0] >= 'A' && txtpos[0] <= 'Z') + { + short int a; + // Is it a variable reference (single alpha) + if(txtpos[1] < 'A' || txtpos[1] > 'Z') + { + a = ((short int *)variables_begin)[*txtpos - 'A']; + txtpos++; + return a; + } + + // Is it a function with a single parameter + scantable(func_tab); + if(table_index == FUNC_UNKNOWN) + goto expr4_error; + + unsigned char f = table_index; + + if(*txtpos != '(') + goto expr4_error; + + txtpos++; + a = expression(); + if(*txtpos != ')') + goto expr4_error; + txtpos++; + switch(f) + { + case FUNC_PEEK: + return program[a]; + + case FUNC_ABS: + if(a < 0) + return -a; + return a; + +#ifdef ARDUINO + case FUNC_AREAD: + pinMode( a, INPUT ); + return analogRead( a ); + case FUNC_DREAD: + pinMode( a, INPUT ); + return digitalRead( a ); +#endif + + case FUNC_RND: +#ifdef ARDUINO + return( random( a )); +#else + return( rand() % a ); +#endif + } + } + + if(*txtpos == '(') + { + short int a; + txtpos++; + a = expression(); + if(*txtpos != ')') + goto expr4_error; + + txtpos++; + return a; + } + +expr4_error: + expression_error = 1; + return 0; + +} + +/***************************************************************************/ +static short int expr3(void) +{ + short int a,b; + + a = expr4(); + + ignore_blanks(); // fix for eg: 100 a = a + 1 + + while(1) + { + if(*txtpos == '*') + { + txtpos++; + b = expr4(); + a *= b; + } + else if(*txtpos == '/') + { + txtpos++; + b = expr4(); + if(b != 0) + a /= b; + else + expression_error = 1; + } + else + return a; + } +} + +/***************************************************************************/ +static short int expr2(void) +{ + short int a,b; + + if(*txtpos == '-' || *txtpos == '+') + a = 0; + else + a = expr3(); + + while(1) + { + if(*txtpos == '-') + { + txtpos++; + b = expr3(); + a -= b; + } + else if(*txtpos == '+') + { + txtpos++; + b = expr3(); + a += b; + } + else + return a; + } +} +/***************************************************************************/ +static short int expression(void) +{ + short int a,b; + + a = expr2(); + + // Check if we have an error + if(expression_error) return a; + + scantable(relop_tab); + if(table_index == RELOP_UNKNOWN) + return a; + + switch(table_index) + { + case RELOP_GE: + b = expr2(); + if(a >= b) return 1; + break; + case RELOP_NE: + case RELOP_NE_BANG: + b = expr2(); + if(a != b) return 1; + break; + case RELOP_GT: + b = expr2(); + if(a > b) return 1; + break; + case RELOP_EQ: + b = expr2(); + if(a == b) return 1; + break; + case RELOP_LE: + b = expr2(); + if(a <= b) return 1; + break; + case RELOP_LT: + b = expr2(); + if(a < b) return 1; + break; + } + return 0; +} + +/***************************************************************************/ +void loop() +{ + unsigned char *start; + unsigned char *newEnd; + unsigned char linelen; + boolean isDigital; + boolean alsoWait = false; + int val; + +#ifdef ARDUINO +#ifdef ENABLE_TONES + noTone( kPiezoPin ); +#endif +#endif + + program_start = program; + program_end = program_start; + sp1 = program+sizeof(program); // Needed for printnum + stack_limit = program+sizeof(program)-STACK_SIZE; + variables_begin = stack_limit - 27*VAR_SIZE; + + // memory free + printnum(variables_begin-program_end); + printmsg(memorymsg); + +warmstart: + // this signifies that it is running in 'direct' mode. + current_line = 0; + sp1 = program+sizeof(program); + printmsg(okmsg); + +prompt: + if( triggerRun ){ + triggerRun = false; + current_line = program_start; + goto execline; + } + + getln( '>' ); + toUppercaseBuffer(); + + txtpos = program_end+sizeof(unsigned short); + + // Find the end of the freshly entered line + while(*txtpos != NL) + txtpos++; + + // Move it to the end of program_memory + { + unsigned char *dest; + dest = variables_begin-1; + while(1) + { + *dest = *txtpos; + if(txtpos == program_end+sizeof(unsigned short)) + break; + dest--; + txtpos--; + } + txtpos = dest; + } + + // Now see if we have a line number + linenum = testnum(); + ignore_blanks(); + if(linenum == 0) + goto direct; + + if(linenum == 0xFFFF) + goto qhow; + + // Find the length of what is left, including the (yet-to-be-populated) line header + linelen = 0; + while(txtpos[linelen] != NL) + linelen++; + linelen++; // Include the NL in the line length + linelen += sizeof(unsigned short)+sizeof(char); // Add space for the line number and line length + + // Now we have the number, add the line header. + txtpos -= 3; + *((unsigned short *)txtpos) = linenum; + txtpos[sizeof(LINENUM)] = linelen; + + + // Merge it into the rest of the program + start = findline(); + + // If a line with that number exists, then remove it + if(start != program_end && *((LINENUM *)start) == linenum) + { + unsigned char *dest, *from; + unsigned tomove; + + from = start + start[sizeof(LINENUM)]; + dest = start; + + tomove = program_end - from; + while( tomove > 0) + { + *dest = *from; + from++; + dest++; + tomove--; + } + program_end = dest; + } + + if(txtpos[sizeof(LINENUM)+sizeof(char)] == NL) // If the line has no txt, it was just a delete + goto prompt; + + + + // Make room for the new line, either all in one hit or lots of little shuffles + while(linelen > 0) + { + unsigned int tomove; + unsigned char *from,*dest; + unsigned int space_to_make; + + space_to_make = txtpos - program_end; + + if(space_to_make > linelen) + space_to_make = linelen; + newEnd = program_end+space_to_make; + tomove = program_end - start; + + + // Source and destination - as these areas may overlap we need to move bottom up + from = program_end; + dest = newEnd; + while(tomove > 0) + { + from--; + dest--; + *dest = *from; + tomove--; + } + + // Copy over the bytes into the new space + for(tomove = 0; tomove < space_to_make; tomove++) + { + *start = *txtpos; + txtpos++; + start++; + linelen--; + } + program_end = newEnd; + } + goto prompt; + +unimplemented: + printmsg(unimplimentedmsg); + goto prompt; + +qhow: + printmsg(howmsg); + goto prompt; + +qwhat: + printmsgNoNL(whatmsg); + if(current_line != NULL) + { + unsigned char tmp = *txtpos; + if(*txtpos != NL) + *txtpos = '^'; + list_line = current_line; + printline(); + *txtpos = tmp; + } + line_terminator(); + goto prompt; + +qsorry: + printmsg(sorrymsg); + goto warmstart; + +run_next_statement: + while(*txtpos == ':') + txtpos++; + ignore_blanks(); + if(*txtpos == NL) + goto execnextline; + goto interperateAtTxtpos; + +direct: + txtpos = program_end+sizeof(LINENUM); + if(*txtpos == NL) + goto prompt; + +interperateAtTxtpos: + if(breakcheck()) + { + printmsg(breakmsg); + goto warmstart; + } + + scantable(keywords); + + switch(table_index) + { + case KW_DELAY: + { +#ifdef ARDUINO + expression_error = 0; + val = expression(); + delay( val ); + goto execnextline; +#else + goto unimplemented; +#endif + } + + case KW_FILES: + goto files; + case KW_LIST: + goto list; + case KW_CHAIN: + goto chain; + case KW_LOAD: + goto load; + case KW_MEM: + goto mem; + case KW_NEW: + if(txtpos[0] != NL) + goto qwhat; + program_end = program_start; + goto prompt; + case KW_RUN: + current_line = program_start; + goto execline; + case KW_SAVE: + goto save; + case KW_NEXT: + goto next; + case KW_LET: + goto assignment; + case KW_IF: + short int val; + expression_error = 0; + val = expression(); + if(expression_error || *txtpos == NL) + goto qhow; + if(val != 0) + goto interperateAtTxtpos; + goto execnextline; + + case KW_GOTO: + expression_error = 0; + linenum = expression(); + if(expression_error || *txtpos != NL) + goto qhow; + current_line = findline(); + goto execline; + + case KW_GOSUB: + goto gosub; + case KW_RETURN: + goto gosub_return; + case KW_REM: + case KW_QUOTE: + goto execnextline; // Ignore line completely + case KW_FOR: + goto forloop; + case KW_INPUT: + goto input; + case KW_PRINT: + case KW_QMARK: + goto print; + case KW_POKE: + goto poke; + case KW_END: + case KW_STOP: + // This is the easy way to end - set the current line to the end of program attempt to run it + if(txtpos[0] != NL) + goto qwhat; + current_line = program_end; + goto execline; + case KW_BYE: + // Leave the basic interperater + return; + + case KW_AWRITE: // AWRITE , HIGH|LOW + isDigital = false; + goto awrite; + case KW_DWRITE: // DWRITE , HIGH|LOW + isDigital = true; + goto dwrite; + + case KW_RSEED: + goto rseed; + +#ifdef ENABLE_TONES + case KW_TONEW: + alsoWait = true; + case KW_TONE: + goto tonegen; + case KW_NOTONE: + goto tonestop; +#endif + +#ifdef ARDUINO +#ifdef ENABLE_EEPROM + case KW_EFORMAT: + goto eformat; + case KW_ESAVE: + goto esave; + case KW_ELOAD: + goto eload; + case KW_ELIST: + goto elist; + case KW_ECHAIN: + goto echain; +#endif +#endif + + case KW_DEFAULT: + goto assignment; + default: + break; + } + +execnextline: + if(current_line == NULL) // Processing direct commands? + goto prompt; + current_line += current_line[sizeof(LINENUM)]; + +execline: + if(current_line == program_end) // Out of lines to run + goto warmstart; + txtpos = current_line+sizeof(LINENUM)+sizeof(char); + goto interperateAtTxtpos; + +#ifdef ARDUINO +#ifdef ENABLE_EEPROM +elist: + { + int i; + + if (use_ecard == true) + { + for (i = 0; i < 8192; i++) + { + val = disk1.read_byte(i); + if( val == '\0' ) { + goto execnextline; + } + + if( ((val < ' ') || (val > '~')) && (val != NL) && (val != CR)) { + outchar( '?' ); + } + else { + outchar( val ); + } + } + } + else if (use_ecard == false) + { + for( i = 0 ; i < (E2END +1) ; i++ ) + { + val = EEPROM.read( i ); + + if( val == '\0' ) { + goto execnextline; + } + + if( ((val < ' ') || (val > '~')) && (val != NL) && (val != CR)) { + outchar( '?' ); + } + else { + outchar( val ); + } + } + } + + } + goto execnextline; + +eformat: + { + if (use_ecard == true) + { + for (int i = 0; i < 8191; i++) + { + if( (i & 0x03f) == 0x20 ) outchar( '.' ); + disk1.write( i, 0 ); + } + } + else if (use_ecard == false) + { + for( int i = 0 ; i < E2END ; i++ ) + { + if( (i & 0x03f) == 0x20 ) outchar( '.' ); + EEPROM.write( i, 0 ); + } + } + outchar( LF ); + } + goto execnextline; + +esave: + { + outStream = kStreamEEProm; + eepos = 0; + + // copied from "List" + list_line = findline(); + while(list_line != program_end) + printline(); + + // go back to standard output, close the file + outStream = kStreamSerial; + + goto warmstart; + } + + +echain: + runAfterLoad = true; + +eload: + // clear the program + program_end = program_start; + + // load from a file into memory + eepos = 0; + inStream = kStreamEEProm; + inhibitOutput = true; + goto warmstart; +#endif /* ENABLE_EEPROM */ +#endif + +input: + { + unsigned char var; + ignore_blanks(); + if(*txtpos < 'A' || *txtpos > 'Z') + goto qwhat; + var = *txtpos; + txtpos++; + ignore_blanks(); + if(*txtpos != NL && *txtpos != ':') + goto qwhat; + ((short int *)variables_begin)[var-'A'] = 99; + + goto run_next_statement; + } + +forloop: + { + unsigned char var; + short int initial, step, terminal; + ignore_blanks(); + if(*txtpos < 'A' || *txtpos > 'Z') + goto qwhat; + var = *txtpos; + txtpos++; + ignore_blanks(); + if(*txtpos != '=') + goto qwhat; + txtpos++; + ignore_blanks(); + + expression_error = 0; + initial = expression(); + if(expression_error) + goto qwhat; + + scantable(to_tab); + if(table_index != 0) + goto qwhat; + + terminal = expression(); + if(expression_error) + goto qwhat; + + scantable(step_tab); + if(table_index == 0) + { + step = expression(); + if(expression_error) + goto qwhat; + } + else + step = 1; + ignore_blanks(); + if(*txtpos != NL && *txtpos != ':') + goto qwhat; + + + if(!expression_error && *txtpos == NL) + { + struct stack_for_frame *f; + if(sp1 + sizeof(struct stack_for_frame) < stack_limit) + goto qsorry; + + sp1 -= sizeof(struct stack_for_frame); + f = (struct stack_for_frame *)sp1; + ((short int *)variables_begin)[var-'A'] = initial; + f->frame_type = STACK_FOR_FLAG; + f->for_var = var; + f->terminal = terminal; + f->step = step; + f->txtpos = txtpos; + f->current_line = current_line; + goto run_next_statement; + } + } + goto qhow; + +gosub: + expression_error = 0; + linenum = expression(); + if(!expression_error && *txtpos == NL) + { + struct stack_gosub_frame *f; + if(sp1 + sizeof(struct stack_gosub_frame) < stack_limit) + goto qsorry; + + sp1 -= sizeof(struct stack_gosub_frame); + f = (struct stack_gosub_frame *)sp1; + f->frame_type = STACK_GOSUB_FLAG; + f->txtpos = txtpos; + f->current_line = current_line; + current_line = findline(); + goto execline; + } + goto qhow; + +next: + // Fnd the variable name + ignore_blanks(); + if(*txtpos < 'A' || *txtpos > 'Z') + goto qhow; + txtpos++; + ignore_blanks(); + if(*txtpos != ':' && *txtpos != NL) + goto qwhat; + +gosub_return: + // Now walk up the stack frames and find the frame we want, if present + tempsp = sp1; + while(tempsp < program+sizeof(program)-1) + { + switch(tempsp[0]) + { + case STACK_GOSUB_FLAG: + if(table_index == KW_RETURN) + { + struct stack_gosub_frame *f = (struct stack_gosub_frame *)tempsp; + current_line = f->current_line; + txtpos = f->txtpos; + sp1 += sizeof(struct stack_gosub_frame); + goto run_next_statement; + } + // This is not the loop you are looking for... so Walk back up the stack + tempsp += sizeof(struct stack_gosub_frame); + break; + case STACK_FOR_FLAG: + // Flag, Var, Final, Step + if(table_index == KW_NEXT) + { + struct stack_for_frame *f = (struct stack_for_frame *)tempsp; + // Is the the variable we are looking for? + if(txtpos[-1] == f->for_var) + { + short int *varaddr = ((short int *)variables_begin) + txtpos[-1] - 'A'; + *varaddr = *varaddr + f->step; + // Use a different test depending on the sign of the step increment + if((f->step > 0 && *varaddr <= f->terminal) || (f->step < 0 && *varaddr >= f->terminal)) + { + // We have to loop so don't pop the stack + txtpos = f->txtpos; + current_line = f->current_line; + goto run_next_statement; + } + // We've run to the end of the loop. drop out of the loop, popping the stack + sp1 = tempsp + sizeof(struct stack_for_frame); + goto run_next_statement; + } + } + // This is not the loop you are looking for... so Walk back up the stack + tempsp += sizeof(struct stack_for_frame); + break; + default: + //printf("Stack is stuffed!\n"); + goto warmstart; + } + } + // Didn't find the variable we've been looking for + goto qhow; + +assignment: + { + short int value; + short int *var; + + if(*txtpos < 'A' || *txtpos > 'Z') + goto qhow; + var = (short int *)variables_begin + *txtpos - 'A'; + txtpos++; + + ignore_blanks(); + + if (*txtpos != '=') + goto qwhat; + txtpos++; + ignore_blanks(); + expression_error = 0; + value = expression(); + if(expression_error) + goto qwhat; + // Check that we are at the end of the statement + if(*txtpos != NL && *txtpos != ':') + goto qwhat; + *var = value; + } + goto run_next_statement; +poke: + { + short int value; + unsigned char *address; + + // Work out where to put it + expression_error = 0; + value = expression(); + if(expression_error) + goto qwhat; + address = (unsigned char *)value; + + // check for a comma + ignore_blanks(); + if (*txtpos != ',') + goto qwhat; + txtpos++; + ignore_blanks(); + + // Now get the value to assign + expression_error = 0; + value = expression(); + if(expression_error) + goto qwhat; + //printf("Poke %p value %i\n",address, (unsigned char)value); + // Check that we are at the end of the statement + if(*txtpos != NL && *txtpos != ':') + goto qwhat; + } + goto run_next_statement; + +list: + linenum = testnum(); // Retuns 0 if no line found. + + // Should be EOL + if(txtpos[0] != NL) + goto qwhat; + + // Find the line + list_line = findline(); + while(list_line != program_end) + printline(); + goto warmstart; + +print: + // If we have an empty list then just put out a NL + if(*txtpos == ':' ) + { + line_terminator(); + txtpos++; + goto run_next_statement; + } + if(*txtpos == NL) + { + goto execnextline; + } + + while(1) + { + ignore_blanks(); + if(print_quoted_string()) + { + ; + } + else if(*txtpos == '"' || *txtpos == '\'') + goto qwhat; + else + { + short int e; + expression_error = 0; + e = expression(); + if(expression_error) + goto qwhat; + printnum(e); + } + + // At this point we have three options, a comma or a new line + if(*txtpos == ',') + txtpos++; // Skip the comma and move onto the next + else if(txtpos[0] == ';' && (txtpos[1] == NL || txtpos[1] == ':')) + { + txtpos++; // This has to be the end of the print - no newline + break; + } + else if(*txtpos == NL || *txtpos == ':') + { + line_terminator(); // The end of the print statement + break; + } + else + goto qwhat; + } + goto run_next_statement; + +mem: + // memory free + printnum(variables_begin-program_end); + printmsg(memorymsg); +#ifdef ARDUINO +#ifdef ENABLE_EEPROM + { + if (use_ecard == true) + { + printnum(8192); + printmsg(eeprommsg); + + val = ' '; + int i; + for( i=0 ; (i<(8192)) && (val != '\0') ; i++ ) { + val = disk1.read_byte( i ); + } + printnum( (8192) - (i-1) ); + + printmsg( eepromamsg ); + } + else if (use_ecard == false) + { + // eprom size + printnum( E2END+1 ); + printmsg( eeprommsg ); + + // figure out the memory usage; + val = ' '; + int i; + for( i=0 ; (i<(E2END+1)) && (val != '\0') ; i++ ) { + val = EEPROM.read( i ); + } + printnum( (E2END +1) - (i-1) ); + + printmsg( eepromamsg ); + } + } +#endif /* ENABLE_EEPROM */ +#endif /* ARDUINO */ + goto run_next_statement; + + + /*************************************************/ + +#ifdef ARDUINO +awrite: // AWRITE ,val +dwrite: + { + short int pinNo; + short int value; + unsigned char *txtposBak; + + // Get the pin number + expression_error = 0; + pinNo = expression(); + if(expression_error) + goto qwhat; + + // check for a comma + ignore_blanks(); + if (*txtpos != ',') + goto qwhat; + txtpos++; + ignore_blanks(); + + + txtposBak = txtpos; + scantable(highlow_tab); + if(table_index != HIGHLOW_UNKNOWN) + { + if( table_index <= HIGHLOW_HIGH ) { + value = 1; + } + else { + value = 0; + } + } + else { + + // and the value (numerical) + expression_error = 0; + value = expression(); + if(expression_error) + goto qwhat; + } + pinMode( pinNo, OUTPUT ); + if( isDigital ) { + digitalWrite( pinNo, value ); + } + else { + analogWrite( pinNo, value ); + } + } + goto run_next_statement; +#else +pinmode: // PINMODE , I/O +awrite: // AWRITE ,val +dwrite: + goto unimplemented; +#endif + + /*************************************************/ +files: + // display a listing of files on the device. + // version 1: no support for subdirectories + +#ifdef ENABLE_FILEIO + cmd_Files(); + goto warmstart; +#else + goto unimplemented; +#endif // ENABLE_FILEIO + + +chain: + runAfterLoad = true; + +load: + // clear the program + program_end = program_start; + + // load from a file into memory +#ifdef ENABLE_FILEIO + { + unsigned char *filename; + + // Work out the filename + expression_error = 0; + filename = filenameWord(); + if(expression_error) + goto qwhat; + +#ifdef ARDUINO + // Arduino specific + if( !SD.exists( (char *)filename )) + { + printmsg( sdfilemsg ); + } + else { + + fp = SD.open( (const char *)filename ); + inStream = kStreamFile; + inhibitOutput = true; + } +#else // ARDUINO + // Desktop specific +#endif // ARDUINO + // this will kickstart a series of events to read in from the file. + + } + goto warmstart; +#else // ENABLE_FILEIO + goto unimplemented; +#endif // ENABLE_FILEIO + + + +save: + // save from memory out to a file +#ifdef ENABLE_FILEIO + { + unsigned char *filename; + + // Work out the filename + expression_error = 0; + filename = filenameWord(); + if(expression_error) + goto qwhat; + +#ifdef ARDUINO + // remove the old file if it exists + if( SD.exists( (char *)filename )) { + SD.remove( (char *)filename ); + } + + // open the file, switch over to file output + fp = SD.open( (const char *)filename, FILE_WRITE ); + outStream = kStreamFile; + + // copied from "List" + list_line = findline(); + while(list_line != program_end) + printline(); + + // go back to standard output, close the file + outStream = kStreamSerial; + + fp.close(); +#else // ARDUINO + // desktop +#endif // ARDUINO + goto warmstart; + } +#else // ENABLE_FILEIO + goto unimplemented; +#endif // ENABLE_FILEIO + +rseed: + { + short int value; + + //Get the pin number + expression_error = 0; + value = expression(); + if(expression_error) + goto qwhat; + +#ifdef ARDUINO + randomSeed( value ); +#else // ARDUINO + srand( value ); +#endif // ARDUINO + goto run_next_statement; + } + +#ifdef ENABLE_TONES +tonestop: + noTone( kPiezoPin ); + goto run_next_statement; + +tonegen: + { + // TONE freq, duration + // if either are 0, tones turned off + short int freq; + short int duration; + + //Get the frequency + expression_error = 0; + freq = expression(); + if(expression_error) + goto qwhat; + + ignore_blanks(); + if (*txtpos != ',') + goto qwhat; + txtpos++; + ignore_blanks(); + + + //Get the duration + expression_error = 0; + duration = expression(); + if(expression_error) + goto qwhat; + + if( freq == 0 || duration == 0 ) + goto tonestop; + + tone( kPiezoPin, freq, duration ); + if( alsoWait ) { + delay( duration ); + alsoWait = false; + } + goto run_next_statement; + } +#endif /* ENABLE_TONES */ +} + +// returns 1 if the character is valid in a filename +static int isValidFnChar( char c ) +{ + if( c >= '0' && c <= '9' ) return 1; // number + if( c >= 'A' && c <= 'Z' ) return 1; // LETTER + if( c >= 'a' && c <= 'z' ) return 1; // letter (for completeness) + if( c == '_' ) return 1; + if( c == '+' ) return 1; + if( c == '.' ) return 1; + if( c == '~' ) return 1; // Window~1.txt + + return 0; +} + +unsigned char * filenameWord(void) +{ + // SDL - I wasn't sure if this functionality existed above, so I figured i'd put it here + unsigned char * ret = txtpos; + expression_error = 0; + + // make sure there are no quotes or spaces, search for valid characters + //while(*txtpos == SPACE || *txtpos == TAB || *txtpos == SQUOTE || *txtpos == DQUOTE ) txtpos++; + while( !isValidFnChar( *txtpos )) txtpos++; + ret = txtpos; + + if( *ret == '\0' ) { + expression_error = 1; + return ret; + } + + // now, find the next nonfnchar + txtpos++; + while( isValidFnChar( *txtpos )) txtpos++; + if( txtpos != ret ) *txtpos = '\0'; + + // set the error code if we've got no string + if( *ret == '\0' ) { + expression_error = 1; + } + + return ret; +} + +/***************************************************************************/ +static void line_terminator(void) +{ + outchar(NL); + outchar(CR); +} + +/***********************************************************/ +void setup() +{ +#ifdef ARDUINO + TV.begin(PAL, 720, 480); + TV.select_font(font6x8); + TV.set_hbi_hook(keyboard.begin()); + + //Serial1.begin(kConsoleBaud); + //Serial1.println(sentinel); + + TV.println( sentinel ); + printmsg(initmsg); + + // Read memory select header + delay(10); + pinMode(9, INPUT); + if (digitalRead(9) == HIGH) + { + use_ecard = true; + disk1.setup(); + } + else if (digitalRead(9) == LOW) + { + use_ecard = false; + } + + #ifdef ENABLE_EEPROM + // eprom size + if (use_ecard == true) + { + printnum(8192); + printmsg(eeprommsg); + } + else if (use_ecard == false) + { + printnum( E2END+1 ); + printmsg( eeprommsg ); + } + #endif /* ENABLE_EEPROM */ + +#ifdef ENABLE_FILEIO + initSD(); + +#ifdef ENABLE_AUTORUN + if( SD.exists( kAutorunFilename )) { + program_end = program_start; + fp = SD.open( kAutorunFilename ); + inStream = kStreamFile; + inhibitOutput = true; + runAfterLoad = true; + } +#endif /* ENABLE_AUTORUN */ + +#endif /* ENABLE_FILEIO */ + +#ifdef ENABLE_EEPROM +#ifdef ENABLE_EAUTORUN + // read the first byte of the eeprom. if it's a number, assume it's a program we can load + int val; + if (use_ecard == true) + { + // ECARD + val = disk1.read_byte(0); + } + else if (use_ecard == false) + { + // Internal EEPROM + val = EEPROM.read(0); + } + + if( val >= '0' && val <= '9' ) { + program_end = program_start; + inStream = kStreamEEProm; + eepos = 0; + inhibitOutput = true; + runAfterLoad = true; + } +#endif /* ENABLE_EAUTORUN */ +#endif /* ENABLE_EEPROM */ + +#endif /* ARDUINO */ +} + + +/***********************************************************/ +static unsigned char breakcheck(void) +{ +#ifdef ARDUINO + if(keyboard.available()) + return keyboard.read() == CTRLC; + //else if (Serial1.available()) + //return Serial1.read() == CTRLC; + return 0; +#else +#ifdef __CONIO__ + if(keyboardhit()) + return getch() == CTRLC; + else +#endif + return 0; +#endif +} +/***********************************************************/ +static int inchar() +{ + int v; +#ifdef ARDUINO + + switch( inStream ) { + case( kStreamFile ): +#ifdef ENABLE_FILEIO + v = fp.read(); + if( v == NL ) v=CR; // file translate + if( !fp.available() ) { + fp.close(); + goto inchar_loadfinish; + } + return v; +#else +#endif + break; + case( kStreamEEProm ): +#ifdef ENABLE_EEPROM +#ifdef ARDUINO + if (use_ecard == true) + { + v = disk1.read_byte(eepos++); + } + else if (use_ecard == false) + { + v = EEPROM.read(eepos++); + } + if( v == '\0' ) { + goto inchar_loadfinish; + } + return v; +#endif +#else + inStream = kStreamSerial; + return NL; +#endif + break; + case( kStreamSerial ): + default: + while(1) + { + if(keyboard.available()) + return keyboard.read(); + //else if (Serial1.available()) + //return Serial1.read(); + } + } + +inchar_loadfinish: + inStream = kStreamSerial; + inhibitOutput = false; + + if( runAfterLoad ) { + runAfterLoad = false; + triggerRun = true; + } + return NL; // trigger a prompt. + +#else + // otherwise. desktop! + int got = getchar(); + + // translation for desktop systems + if( got == LF ) got = CR; + + return got; +#endif +} + +/***********************************************************/ +static void outchar(unsigned char c) +{ + if( inhibitOutput ) return; + +#ifdef ARDUINO + #ifdef ENABLE_FILEIO + if( outStream == kStreamFile ) { + // output to a file + fp.write( c ); + } + else + #endif + #ifdef ARDUINO + #ifdef ENABLE_EEPROM + if( outStream == kStreamEEProm ) { + if (use_ecard == true) + { + disk1.write(eepos++, c); + } + else if (use_ecard == false) + { + EEPROM.write( eepos++, c ); + } + } + else + #endif /* ENABLE_EEPROM */ + #endif /* ARDUINO */ + TV.print((char)c); + //Serial1.write(c); + +#else + putchar(c); +#endif +} + +/***********************************************************/ +/* SD Card helpers */ + +#if ARDUINO && ENABLE_FILEIO + +static int initSD( void ) +{ + // if the card is already initialized, we just go with it. + // there is no support (yet?) for hot-swap of SD Cards. if you need to + // swap, pop the card, reset the arduino.) + + if( sd_is_initialized == true ) return kSD_OK; + + // due to the way the SD Library works, pin 10 always needs to be + // an output, even when your shield uses another line for CS + pinMode(4, OUTPUT); // change this to 53 on a mega + + if( !SD.begin( kSD_CS )) { + // failed + printmsg( sderrormsg ); + return kSD_Fail; + } + // success - quietly return 0 + sd_is_initialized = true; + + // and our file redirection flags + outStream = kStreamSerial; + inStream = kStreamSerial; + inhibitOutput = false; + + return kSD_OK; +} +#endif + +#if ENABLE_FILEIO +void cmd_Files( void ) +{ + File dir = SD.open( "/" ); + dir.seek(0); + + while( true ) { + File entry = dir.openNextFile(); + if( !entry ) { + entry.close(); + break; + } + + // common header + printmsgNoNL( indentmsg ); + printmsgNoNL( (const unsigned char *)entry.name() ); + if( entry.isDirectory() ) { + printmsgNoNL( slashmsg ); + } + + if( entry.isDirectory() ) { + // directory ending + for( int i=strlen( entry.name()) ; i<16 ; i++ ) { + printmsgNoNL( spacemsg ); + } + printmsgNoNL( dirextmsg ); + } + else { + // file ending + for( int i=strlen( entry.name()) ; i<17 ; i++ ) { + printmsgNoNL( spacemsg ); + } + printUnum( entry.size() ); + } + line_terminator(); + entry.close(); + } + dir.close(); +} +#endif + + diff --git a/trunk/Arduino/Single_Chip_Computer/Single_chip_Computer_1.14.ino.txt b/trunk/Arduino/Single_Chip_Computer/Single_chip_Computer_1.14.ino.txt new file mode 100644 index 00000000..8629225b --- /dev/null +++ b/trunk/Arduino/Single_Chip_Computer/Single_chip_Computer_1.14.ino.txt @@ -0,0 +1,2171 @@ +//////////////////////////////////////////////////////////////////////////////// +// TinyBasic Plus +//////////////////////////////////////////////////////////////////////////////// +// +// Authors: Mike Field +// Scott Lawrence +// Dan +// + +#define kVersion "v0.14" + +// v0.14: 19/04/2014 +// TVout and PS2uartKeyboard Libraries added. +// +// v0.13: 2013-03-04 +// Support for Arduino 1.5 (SPI.h included, additional changes for DUE support) +// +// v0.12: 2013-03-01 +// EEPROM load and save routines added: EFORMAT, ELIST, ELOAD, ESAVE, ECHAIN +// added EAUTORUN option (chains to EEProm saved program on startup) +// Bugfixes to build properly on non-arduino systems (PROGMEM #define workaround) +// cleaned up a bit of the #define options wrt TONE +// +// v0.11: 2013-02-20 +// all display strings and tables moved to PROGMEM to save space +// removed second serial +// removed pinMode completely, autoconf is explicit +// beginnings of EEPROM related functionality (new,load,save,list) +// +// v0.10: 2012-10-15 +// added kAutoConf, which eliminates the "PINMODE" statement. +// now, DWRITE,DREAD,AWRITE,AREAD automatically set the PINMODE appropriately themselves. +// should save a few bytes in your programs. +// +// v0.09: 2012-10-12 +// Fixed directory listings. FILES now always works. (bug in the SD library) +// ref: http://arduino.cc/forum/index.php/topic,124739.0.html +// fixed filesize printouts (added printUnum for unsigned numbers) +// #defineable baud rate for slow connection throttling +//e +// v0.08: 2012-10-02 +// Tone generation through piezo added (TONE, TONEW, NOTONE) +// +// v0.07: 2012-09-30 +// Autorun buildtime configuration feature +// +// v0.06: 2012-09-27 +// Added optional second serial input, used for an external keyboard +// +// v0.05: 2012-09-21 +// CHAIN to load and run a second file +// RND,RSEED for random stuff +// Added "!=" for "<>" synonym +// Added "END" for "STOP" synonym (proper name for the functionality anyway) +// +// v0.04: 2012-09-20 +// DELAY ms - for delaying +// PINMODE , INPUT|IN|I|OUTPUT|OUT|O +// DWRITE , HIGH|HI|1|LOW|LO|0 +// AWRITE , [0..255] +// fixed "save" appending to existing files instead of overwriting +// Updated for building desktop command line app (incomplete) +// +// v0.03: 2012-09-19 +// Integrated Jurg Wullschleger whitespace,unary fix +// Now available through github +// Project renamed from "Tiny Basic in C" to "TinyBasic Plus" +// +// v0.02b: 2012-09-17 Scott Lawrence +// Better FILES listings +// +// v0.02a: 2012-09-17 Scott Lawrence +// Support for SD Library +// Added: SAVE, FILES (mostly works), LOAD (mostly works) (redirects IO) +// Added: MEM, ? (PRINT) +// Quirk: "10 LET A=B+C" is ok "10 LET A = B + C" is not. +// Quirk: INPUT seems broken? + +/* +* Additional Libraries +*/ +// TVout +#include +#include +#include +#include +#include +#include +#include +// PS2 Keyboard +#include + +PS2uartKeyboard keyboard; +TVout TV; + + +// IF testing with Visual C, this needs to be the first thing in the file. +//#include "stdafx.h" + + +char eliminateCompileErrors = 1; // fix to suppress arduino build errors + +// hack to let makefiles work with this file unchanged +#ifdef FORCE_DESKTOP +#undef ARDUINO +#else +#define ARDUINO 1 +#endif + +//////////////////////////////////////////////////////////////////////////////// +// Feature option configuration... + +// This enables LOAD, SAVE, FILES commands through the Arduino SD Library +// it adds 9k of usage as well. +//#define ENABLE_FILEIO 1 +#undef ENABLE_FILEIO + +// this turns on "autorun". if there's FileIO, and a file "autorun.bas", +// then it will load it and run it when starting up +//#define ENABLE_AUTORUN 1 +#undef ENABLE_AUTORUN +// and this is the file that gets run +#define kAutorunFilename "autorun.bas" + +// this is the alternate autorun. Autorun the program in the eeprom. +// it will load whatever is in the EEProm and run it +#define ENABLE_EAUTORUN 1 +//#undef ENABLE_EAUTORUN + +// this will enable the "TONE", "NOTONE" command using a piezo +// element on the specified pin. Wire the red/positive/piezo to the kPiezoPin, +// and the black/negative/metal disc to ground. +// it adds 1.5k of usage as well. +#define ENABLE_TONES 1 +//#undef ENABLE_TONES +#define kPiezoPin 15 + +// we can use the EEProm to store a program during powerdown. This is +// 1keyboardyte on the '328, and 512 bytes on the '168. Enabling this here will +// allow for this funcitonality to work. Note that this only works on AVR +// arduino. Disable it for DUE/other devices. +#define ENABLE_EEPROM 1 +//#undef ENABLE_EEPROM + +// Sometimes, we connect with a slower device as the console. +// Set your console D0/D1 baud rate here (9600 baud default) +#define kConsoleBaud 9600 + +//////////////////////////////////////////////////////////////////////////////// +#ifdef ARDUINO +#ifndef RAMEND +// okay, this is a hack for now +// if we're in here, we're a DUE probably (ARM instead of AVR) + +#define RAMEND 4096-1 + +// turn off EEProm +#undef ENABLE_EEPROM +#undef ENABLE_TONES + +#else +// we're an AVR! + +// we're moving our data strings into progmem +#include +#endif + +// includes, and settings for Arduino-specific functionality +#ifdef ENABLE_EEPROM +#include /* NOTE: case sensitive */ +int eepos = 0; +#endif + + +#ifdef ENABLE_FILEIO +#include +#include /* needed as of 1.5 beta */ + +// Arduino-specific configuration +// set this to the card select for your SD shield +#define kSD_CS 4 + +#define kSD_Fail 0 +#define kSD_OK 1 + +File fp; +#endif + +// set up our RAM buffer size for program and user input +// NOTE: This number will have to change if you include other libraries. +#ifdef ARDUINO +#ifdef ENABLE_FILEIO +#define kRamFileIO (1100) /* approximate */ +#else +#define kRamFileIO (0) +#endif +#ifdef ENABLE_TONES +#define kRamTones (40) +#else +#define kRamTones (0) +#endif +#endif /* ARDUINO */ +#define kRamSize (RAMEND - 8803 - kRamFileIO - kRamTones) + +#ifndef ARDUINO +// Not arduino setup +#include +#include +#undef ENABLE_TONES + +// size of our program ram +#define kRamSize 4096 /* arbitrary */ + +#ifdef ENABLE_FILEIO +FILE * fp; +#endif +#endif + +#ifdef ENABLE_FILEIO +// functions defined elsehwere +void cmd_Files( void ); +#endif + +//////////////////// + +#ifndef boolean +#define boolean int +#define true 1 +#define false 0 +#endif +#endif + +#ifndef byte +typedef unsigned char byte; +#endif + +// some catches for AVR based text string stuff... +#ifndef PROGMEM +#define PROGMEM +#endif +#ifndef pgm_read_byte +#define pgm_read_byte( A ) *(A) +#endif + +//////////////////// + +#ifdef ENABLE_FILEIO +unsigned char * filenameWord(void); +static boolean sd_is_initialized = false; +#endif + +boolean inhibitOutput = false; +static boolean runAfterLoad = false; +static boolean triggerRun = false; + +// these will select, at runtime, where IO happens through for load/save +enum { + kStreamSerial = 0, + kStreamEEProm, + kStreamFile +}; +static unsigned char inStream = kStreamSerial; +static unsigned char outStream = kStreamSerial; + + +//////////////////////////////////////////////////////////////////////////////// +// ASCII Characters +#define CR '\r' +#define NL '\n' +#define LF 0x0a +#define TAB '\t' +#define BELL '\b' +#define SPACE ' ' +#define SQUOTE '\'' +#define DQUOTE '\"' +#define CTRLC 0x1B // Changed to ESC key (27 - 0x1B) +#define CTRLH 0x08 +#define CTRLS 0x13 +#define CTRLX 0x18 + +typedef short unsigned LINENUM; +#ifdef ARDUINO +#define ECHO_CHARS 1 +#else +#define ECHO_CHARS 0 +#endif + + +static unsigned char program[kRamSize]; +static const char * sentinel = "HELLO"; +static unsigned char *txtpos,*list_line; +static unsigned char expression_error; +static unsigned char *tempsp; + +/***********************************************************/ +// Keyword table and constants - the last character has 0x80 added to it +static unsigned char keywords[] PROGMEM = { + 'L','I','S','T'+0x80, + 'L','O','A','D'+0x80, + 'N','E','W'+0x80, + 'R','U','N'+0x80, + 'S','A','V','E'+0x80, + 'N','E','X','T'+0x80, + 'L','E','T'+0x80, + 'I','F'+0x80, + 'G','O','T','O'+0x80, + 'G','O','S','U','B'+0x80, + 'R','E','T','U','R','N'+0x80, + 'R','E','M'+0x80, + 'F','O','R'+0x80, + 'I','N','P','U','T'+0x80, + 'P','R','I','N','T'+0x80, + 'P','O','K','E'+0x80, + 'S','T','O','P'+0x80, + 'B','Y','E'+0x80, + 'F','I','L','E','S'+0x80, + 'M','E','M'+0x80, + '?'+ 0x80, + '\''+ 0x80, + 'A','W','R','I','T','E'+0x80, + 'D','W','R','I','T','E'+0x80, + 'D','E','L','A','Y'+0x80, + 'E','N','D'+0x80, + 'R','S','E','E','D'+0x80, + 'C','H','A','I','N'+0x80, +#ifdef ENABLE_TONES + 'T','O','N','E','W'+0x80, + 'T','O','N','E'+0x80, + 'N','O','T','O','N','E'+0x80, +#endif +#ifdef ARDUINO +#ifdef ENABLE_EEPROM + 'E','C','H','A','I','N'+0x80, + 'E','L','I','S','T'+0x80, + 'E','L','O','A','D'+0x80, + 'E','F','O','R','M','A','T'+0x80, + 'E','S','A','V','E'+0x80, +#endif +#endif + 0 +}; + +// by moving the command list to an enum, we can easily remove sections +// above and below simultaneously to selectively obliterate functionality. +enum { + KW_LIST = 0, + KW_LOAD, KW_NEW, KW_RUN, KW_SAVE, + KW_NEXT, KW_LET, KW_IF, + KW_GOTO, KW_GOSUB, KW_RETURN, + KW_REM, + KW_FOR, + KW_INPUT, KW_PRINT, + KW_POKE, + KW_STOP, KW_BYE, + KW_FILES, + KW_MEM, + KW_QMARK, KW_QUOTE, + KW_AWRITE, KW_DWRITE, + KW_DELAY, + KW_END, + KW_RSEED, + KW_CHAIN, +#ifdef ENABLE_TONES + KW_TONEW, KW_TONE, KW_NOTONE, +#endif +#ifdef ARDUINO +#ifdef ENABLE_EEPROM + KW_ECHAIN, KW_ELIST, KW_ELOAD, KW_EFORMAT, KW_ESAVE, +#endif +#endif + KW_DEFAULT /* always the final one*/ +}; + +struct stack_for_frame { + char frame_type; + char for_var; + short int terminal; + short int step; + unsigned char *current_line; + unsigned char *txtpos; +}; + +struct stack_gosub_frame { + char frame_type; + unsigned char *current_line; + unsigned char *txtpos; +}; + +static unsigned char func_tab[] PROGMEM = { + 'P','E','E','K'+0x80, + 'A','B','S'+0x80, + 'A','R','E','A','D'+0x80, + 'D','R','E','A','D'+0x80, + 'R','N','D'+0x80, + 0 +}; +#define FUNC_PEEK 0 +#define FUNC_ABS 1 +#define FUNC_AREAD 2 +#define FUNC_DREAD 3 +#define FUNC_RND 4 +#define FUNC_UNKNOWN 5 + +static unsigned char to_tab[] PROGMEM = { + 'T','O'+0x80, + 0 +}; + +static unsigned char step_tab[] PROGMEM = { + 'S','T','E','P'+0x80, + 0 +}; + +static unsigned char relop_tab[] PROGMEM = { + '>','='+0x80, + '<','>'+0x80, + '>'+0x80, + '='+0x80, + '<','='+0x80, + '<'+0x80, + '!','='+0x80, + 0 +}; + +#define RELOP_GE 0 +#define RELOP_NE 1 +#define RELOP_GT 2 +#define RELOP_EQ 3 +#define RELOP_LE 4 +#define RELOP_LT 5 +#define RELOP_NE_BANG 6 +#define RELOP_UNKNOWN 7 + +static unsigned char highlow_tab[] PROGMEM = { + 'H','I','G','H'+0x80, + 'H','I'+0x80, + 'L','O','W'+0x80, + 'L','O'+0x80, + 0 +}; +#define HIGHLOW_HIGH 1 +#define HIGHLOW_UNKNOWN 4 + +#define STACK_SIZE (sizeof(struct stack_for_frame)*5) +#define VAR_SIZE sizeof(short int) // Size of variables in bytes + +static unsigned char *stack_limit; +static unsigned char *program_start; +static unsigned char *program_end; +static unsigned char *stack; // Software stack for things that should go on the CPU stack +static unsigned char *variables_begin; +static unsigned char *current_line; +static unsigned char *sp1; +#define STACK_GOSUB_FLAG 'G' +#define STACK_FOR_FLAG 'F' +static unsigned char table_index; +static LINENUM linenum; + +static const unsigned char okmsg[] PROGMEM = "OK"; +static const unsigned char whatmsg[] PROGMEM = "What? "; +static const unsigned char howmsg[] PROGMEM = "How?"; +static const unsigned char sorrymsg[] PROGMEM = "Sorry!"; +static const unsigned char initmsg[] PROGMEM = "TinyBasic Plus " kVersion; +static const unsigned char memorymsg[] PROGMEM = " bytes free."; +#ifdef ARDUINO +#ifdef ENABLE_EEPROM +static const unsigned char eeprommsg[] PROGMEM = " EEProm bytes total."; +static const unsigned char eepromamsg[] PROGMEM = " EEProm bytes available."; +#endif +#endif +static const unsigned char breakmsg[] PROGMEM = "break!"; +static const unsigned char unimplimentedmsg[] PROGMEM = "Unimplemented"; +static const unsigned char backspacemsg[] PROGMEM = "\b \b"; +static const unsigned char indentmsg[] PROGMEM = " "; +static const unsigned char sderrormsg[] PROGMEM = "SD card error."; +static const unsigned char sdfilemsg[] PROGMEM = "SD file error."; +static const unsigned char dirextmsg[] PROGMEM = "(dir)"; +static const unsigned char slashmsg[] PROGMEM = "/"; +static const unsigned char spacemsg[] PROGMEM = " "; + +static int inchar(void); +static void outchar(unsigned char c); +static void line_terminator(void); +static short int expression(void); +static unsigned char breakcheck(void); +/***************************************************************************/ +static void ignore_blanks(void) +{ + while(*txtpos == SPACE || *txtpos == TAB) + txtpos++; +} + + +/***************************************************************************/ +static void scantable(unsigned char *table) +{ + int i = 0; + table_index = 0; + while(1) + { + // Run out of table entries? + if(pgm_read_byte( table ) == 0) + return; + + // Do we match this character? + if(txtpos[i] == pgm_read_byte( table )) + { + i++; + table++; + } + else + { + // do we match the last character of keywork (with 0x80 added)? If so, return + if(txtpos[i]+0x80 == pgm_read_byte( table )) + { + txtpos += i+1; // Advance the pointer to following the keyword + ignore_blanks(); + return; + } + + // Forward to the end of this keyword + while((pgm_read_byte( table ) & 0x80) == 0) + table++; + + // Now move on to the first character of the next word, and reset the position index + table++; + table_index++; + ignore_blanks(); + i = 0; + } + } +} + +/***************************************************************************/ +static void pushb(unsigned char b) +{ + sp1--; + *sp1 = b; +} + +/***************************************************************************/ +static unsigned char popb() +{ + unsigned char b; + b = *sp1; + sp1++; + return b; +} + +/***************************************************************************/ +void printnum(int num) +{ + int digits = 0; + + if(num < 0) + { + num = -num; + outchar('-'); + } + do { + pushb(num%10+'0'); + num = num/10; + digits++; + } + while (num > 0); + + while(digits > 0) + { + outchar(popb()); + digits--; + } +} + +void printUnum(unsigned int num) +{ + int digits = 0; + + do { + pushb(num%10+'0'); + num = num/10; + digits++; + } + while (num > 0); + + while(digits > 0) + { + outchar(popb()); + digits--; + } +} + +/***************************************************************************/ +static unsigned short testnum(void) +{ + unsigned short num = 0; + ignore_blanks(); + + while(*txtpos>= '0' && *txtpos <= '9' ) + { + // Trap overflows + if(num >= 0xFFFF/10) + { + num = 0xFFFF; + break; + } + + num = num *10 + *txtpos - '0'; + txtpos++; + } + return num; +} + +/***************************************************************************/ +static unsigned char print_quoted_string(void) +{ + int i=0; + unsigned char delim = *txtpos; + if(delim != '"' && delim != '\'') + return 0; + txtpos++; + + // Check we have a closing delimiter + while(txtpos[i] != delim) + { + if(txtpos[i] == NL) + return 0; + i++; + } + + // Print the characters + while(*txtpos != delim) + { + outchar(*txtpos); + txtpos++; + } + txtpos++; // Skip over the last delimiter + + return 1; +} + + +/***************************************************************************/ +void printmsgNoNL(const unsigned char *msg) +{ + while( pgm_read_byte( msg ) != 0 ) { + outchar( pgm_read_byte( msg++ ) ); + }; +} + +/***************************************************************************/ +void printmsg(const unsigned char *msg) +{ + printmsgNoNL(msg); + line_terminator(); +} + +/***************************************************************************/ +static void getln(char prompt) +{ + outchar(prompt); + txtpos = program_end+sizeof(LINENUM); + + while(1) + { + char c = inchar(); + switch(c) + { + case NL: + //break; + case CR: + line_terminator(); + // Terminate all strings with a NL + txtpos[0] = NL; + return; + case CTRLH: + if(txtpos == program_end) + break; + txtpos--; + + printmsg(backspacemsg); + break; + default: + // We need to leave at least one space to allow us to shuffle the line into order + if(txtpos == variables_begin-2) + outchar(BELL); + else + { + txtpos[0] = c; + txtpos++; + outchar(c); + } + } + } +} + +/***************************************************************************/ +static unsigned char *findline(void) +{ + unsigned char *line = program_start; + while(1) + { + if(line == program_end) + return line; + + if(((LINENUM *)line)[0] >= linenum) + return line; + + // Add the line length onto the current address, to get to the next line; + line += line[sizeof(LINENUM)]; + } +} + +/***************************************************************************/ +static void toUppercaseBuffer(void) +{ + unsigned char *c = program_end+sizeof(LINENUM); + unsigned char quote = 0; + + while(*c != NL) + { + // Are we in a quoted string? + if(*c == quote) + quote = 0; + else if(*c == '"' || *c == '\'') + quote = *c; + else if(quote == 0 && *c >= 'a' && *c <= 'z') + *c = *c + 'A' - 'a'; + c++; + } +} + +/***************************************************************************/ +void printline() +{ + LINENUM line_num; + + line_num = *((LINENUM *)(list_line)); + list_line += sizeof(LINENUM) + sizeof(char); + + // Output the line */ + printnum(line_num); + outchar(' '); + while(*list_line != NL) + { + outchar(*list_line); + list_line++; + } + list_line++; + line_terminator(); +} + +/***************************************************************************/ +static short int expr4(void) +{ + // fix provided by Jurg Wullschleger wullschleger@gmail.com + // fixes whitespace and unary operations + ignore_blanks(); + + if( *txtpos == '-' ) { + txtpos++; + return -expr4(); + } + // end fix + + if(*txtpos == '0') + { + txtpos++; + return 0; + } + + if(*txtpos >= '1' && *txtpos <= '9') + { + short int a = 0; + do { + a = a*10 + *txtpos - '0'; + txtpos++; + } + while(*txtpos >= '0' && *txtpos <= '9'); + return a; + } + + // Is it a function or variable reference? + if(txtpos[0] >= 'A' && txtpos[0] <= 'Z') + { + short int a; + // Is it a variable reference (single alpha) + if(txtpos[1] < 'A' || txtpos[1] > 'Z') + { + a = ((short int *)variables_begin)[*txtpos - 'A']; + txtpos++; + return a; + } + + // Is it a function with a single parameter + scantable(func_tab); + if(table_index == FUNC_UNKNOWN) + goto expr4_error; + + unsigned char f = table_index; + + if(*txtpos != '(') + goto expr4_error; + + txtpos++; + a = expression(); + if(*txtpos != ')') + goto expr4_error; + txtpos++; + switch(f) + { + case FUNC_PEEK: + return program[a]; + + case FUNC_ABS: + if(a < 0) + return -a; + return a; + +#ifdef ARDUINO + case FUNC_AREAD: + pinMode( a, INPUT ); + return analogRead( a ); + case FUNC_DREAD: + pinMode( a, INPUT ); + return digitalRead( a ); +#endif + + case FUNC_RND: +#ifdef ARDUINO + return( random( a )); +#else + return( rand() % a ); +#endif + } + } + + if(*txtpos == '(') + { + short int a; + txtpos++; + a = expression(); + if(*txtpos != ')') + goto expr4_error; + + txtpos++; + return a; + } + +expr4_error: + expression_error = 1; + return 0; + +} + +/***************************************************************************/ +static short int expr3(void) +{ + short int a,b; + + a = expr4(); + + ignore_blanks(); // fix for eg: 100 a = a + 1 + + while(1) + { + if(*txtpos == '*') + { + txtpos++; + b = expr4(); + a *= b; + } + else if(*txtpos == '/') + { + txtpos++; + b = expr4(); + if(b != 0) + a /= b; + else + expression_error = 1; + } + else + return a; + } +} + +/***************************************************************************/ +static short int expr2(void) +{ + short int a,b; + + if(*txtpos == '-' || *txtpos == '+') + a = 0; + else + a = expr3(); + + while(1) + { + if(*txtpos == '-') + { + txtpos++; + b = expr3(); + a -= b; + } + else if(*txtpos == '+') + { + txtpos++; + b = expr3(); + a += b; + } + else + return a; + } +} +/***************************************************************************/ +static short int expression(void) +{ + short int a,b; + + a = expr2(); + + // Check if we have an error + if(expression_error) return a; + + scantable(relop_tab); + if(table_index == RELOP_UNKNOWN) + return a; + + switch(table_index) + { + case RELOP_GE: + b = expr2(); + if(a >= b) return 1; + break; + case RELOP_NE: + case RELOP_NE_BANG: + b = expr2(); + if(a != b) return 1; + break; + case RELOP_GT: + b = expr2(); + if(a > b) return 1; + break; + case RELOP_EQ: + b = expr2(); + if(a == b) return 1; + break; + case RELOP_LE: + b = expr2(); + if(a <= b) return 1; + break; + case RELOP_LT: + b = expr2(); + if(a < b) return 1; + break; + } + return 0; +} + +/***************************************************************************/ +void loop() +{ + unsigned char *start; + unsigned char *newEnd; + unsigned char linelen; + boolean isDigital; + boolean alsoWait = false; + int val; + +#ifdef ARDUINO +#ifdef ENABLE_TONES + noTone( kPiezoPin ); +#endif +#endif + + program_start = program; + program_end = program_start; + sp1 = program+sizeof(program); // Needed for printnum + stack_limit = program+sizeof(program)-STACK_SIZE; + variables_begin = stack_limit - 27*VAR_SIZE; + + // memory free + printnum(variables_begin-program_end); + printmsg(memorymsg); +#ifdef ARDUINO +#ifdef ENABLE_EEPROM + // eprom size + printnum( E2END+1 ); + printmsg( eeprommsg ); +#endif /* ENABLE_EEPROM */ +#endif /* ARDUINO */ + +warmstart: + // this signifies that it is running in 'direct' mode. + current_line = 0; + sp1 = program+sizeof(program); + printmsg(okmsg); + +prompt: + if( triggerRun ){ + triggerRun = false; + current_line = program_start; + goto execline; + } + + getln( '>' ); + toUppercaseBuffer(); + + txtpos = program_end+sizeof(unsigned short); + + // Find the end of the freshly entered line + while(*txtpos != NL) + txtpos++; + + // Move it to the end of program_memory + { + unsigned char *dest; + dest = variables_begin-1; + while(1) + { + *dest = *txtpos; + if(txtpos == program_end+sizeof(unsigned short)) + break; + dest--; + txtpos--; + } + txtpos = dest; + } + + // Now see if we have a line number + linenum = testnum(); + ignore_blanks(); + if(linenum == 0) + goto direct; + + if(linenum == 0xFFFF) + goto qhow; + + // Find the length of what is left, including the (yet-to-be-populated) line header + linelen = 0; + while(txtpos[linelen] != NL) + linelen++; + linelen++; // Include the NL in the line length + linelen += sizeof(unsigned short)+sizeof(char); // Add space for the line number and line length + + // Now we have the number, add the line header. + txtpos -= 3; + *((unsigned short *)txtpos) = linenum; + txtpos[sizeof(LINENUM)] = linelen; + + + // Merge it into the rest of the program + start = findline(); + + // If a line with that number exists, then remove it + if(start != program_end && *((LINENUM *)start) == linenum) + { + unsigned char *dest, *from; + unsigned tomove; + + from = start + start[sizeof(LINENUM)]; + dest = start; + + tomove = program_end - from; + while( tomove > 0) + { + *dest = *from; + from++; + dest++; + tomove--; + } + program_end = dest; + } + + if(txtpos[sizeof(LINENUM)+sizeof(char)] == NL) // If the line has no txt, it was just a delete + goto prompt; + + + + // Make room for the new line, either all in one hit or lots of little shuffles + while(linelen > 0) + { + unsigned int tomove; + unsigned char *from,*dest; + unsigned int space_to_make; + + space_to_make = txtpos - program_end; + + if(space_to_make > linelen) + space_to_make = linelen; + newEnd = program_end+space_to_make; + tomove = program_end - start; + + + // Source and destination - as these areas may overlap we need to move bottom up + from = program_end; + dest = newEnd; + while(tomove > 0) + { + from--; + dest--; + *dest = *from; + tomove--; + } + + // Copy over the bytes into the new space + for(tomove = 0; tomove < space_to_make; tomove++) + { + *start = *txtpos; + txtpos++; + start++; + linelen--; + } + program_end = newEnd; + } + goto prompt; + +unimplemented: + printmsg(unimplimentedmsg); + goto prompt; + +qhow: + printmsg(howmsg); + goto prompt; + +qwhat: + printmsgNoNL(whatmsg); + if(current_line != NULL) + { + unsigned char tmp = *txtpos; + if(*txtpos != NL) + *txtpos = '^'; + list_line = current_line; + printline(); + *txtpos = tmp; + } + line_terminator(); + goto prompt; + +qsorry: + printmsg(sorrymsg); + goto warmstart; + +run_next_statement: + while(*txtpos == ':') + txtpos++; + ignore_blanks(); + if(*txtpos == NL) + goto execnextline; + goto interperateAtTxtpos; + +direct: + txtpos = program_end+sizeof(LINENUM); + if(*txtpos == NL) + goto prompt; + +interperateAtTxtpos: + if(breakcheck()) + { + printmsg(breakmsg); + goto warmstart; + } + + scantable(keywords); + + switch(table_index) + { + case KW_DELAY: + { +#ifdef ARDUINO + expression_error = 0; + val = expression(); + delay( val ); + goto execnextline; +#else + goto unimplemented; +#endif + } + + case KW_FILES: + goto files; + case KW_LIST: + goto list; + case KW_CHAIN: + goto chain; + case KW_LOAD: + goto load; + case KW_MEM: + goto mem; + case KW_NEW: + if(txtpos[0] != NL) + goto qwhat; + program_end = program_start; + goto prompt; + case KW_RUN: + current_line = program_start; + goto execline; + case KW_SAVE: + goto save; + case KW_NEXT: + goto next; + case KW_LET: + goto assignment; + case KW_IF: + short int val; + expression_error = 0; + val = expression(); + if(expression_error || *txtpos == NL) + goto qhow; + if(val != 0) + goto interperateAtTxtpos; + goto execnextline; + + case KW_GOTO: + expression_error = 0; + linenum = expression(); + if(expression_error || *txtpos != NL) + goto qhow; + current_line = findline(); + goto execline; + + case KW_GOSUB: + goto gosub; + case KW_RETURN: + goto gosub_return; + case KW_REM: + case KW_QUOTE: + goto execnextline; // Ignore line completely + case KW_FOR: + goto forloop; + case KW_INPUT: + goto input; + case KW_PRINT: + case KW_QMARK: + goto print; + case KW_POKE: + goto poke; + case KW_END: + case KW_STOP: + // This is the easy way to end - set the current line to the end of program attempt to run it + if(txtpos[0] != NL) + goto qwhat; + current_line = program_end; + goto execline; + case KW_BYE: + // Leave the basic interperater + return; + + case KW_AWRITE: // AWRITE , HIGH|LOW + isDigital = false; + goto awrite; + case KW_DWRITE: // DWRITE , HIGH|LOW + isDigital = true; + goto dwrite; + + case KW_RSEED: + goto rseed; + +#ifdef ENABLE_TONES + case KW_TONEW: + alsoWait = true; + case KW_TONE: + goto tonegen; + case KW_NOTONE: + goto tonestop; +#endif + +#ifdef ARDUINO +#ifdef ENABLE_EEPROM + case KW_EFORMAT: + goto eformat; + case KW_ESAVE: + goto esave; + case KW_ELOAD: + goto eload; + case KW_ELIST: + goto elist; + case KW_ECHAIN: + goto echain; +#endif +#endif + + case KW_DEFAULT: + goto assignment; + default: + break; + } + +execnextline: + if(current_line == NULL) // Processing direct commands? + goto prompt; + current_line += current_line[sizeof(LINENUM)]; + +execline: + if(current_line == program_end) // Out of lines to run + goto warmstart; + txtpos = current_line+sizeof(LINENUM)+sizeof(char); + goto interperateAtTxtpos; + +#ifdef ARDUINO +#ifdef ENABLE_EEPROM +elist: + { + int i; + for( i = 0 ; i < (E2END +1) ; i++ ) + { + val = EEPROM.read( i ); + + if( val == '\0' ) { + goto execnextline; + } + + if( ((val < ' ') || (val > '~')) && (val != NL) && (val != CR)) { + outchar( '?' ); + } + else { + outchar( val ); + } + } + } + goto execnextline; + +eformat: + { + for( int i = 0 ; i < E2END ; i++ ) + { + if( (i & 0x03f) == 0x20 ) outchar( '.' ); + EEPROM.write( i, 0 ); + } + outchar( LF ); + } + goto execnextline; + +esave: + { + outStream = kStreamEEProm; + eepos = 0; + + // copied from "List" + list_line = findline(); + while(list_line != program_end) + printline(); + + // go back to standard output, close the file + outStream = kStreamSerial; + + goto warmstart; + } + + +echain: + runAfterLoad = true; + +eload: + // clear the program + program_end = program_start; + + // load from a file into memory + eepos = 0; + inStream = kStreamEEProm; + inhibitOutput = true; + goto warmstart; +#endif /* ENABLE_EEPROM */ +#endif + +input: + { + unsigned char var; + ignore_blanks(); + if(*txtpos < 'A' || *txtpos > 'Z') + goto qwhat; + var = *txtpos; + txtpos++; + ignore_blanks(); + if(*txtpos != NL && *txtpos != ':') + goto qwhat; + ((short int *)variables_begin)[var-'A'] = 99; + + goto run_next_statement; + } + +forloop: + { + unsigned char var; + short int initial, step, terminal; + ignore_blanks(); + if(*txtpos < 'A' || *txtpos > 'Z') + goto qwhat; + var = *txtpos; + txtpos++; + ignore_blanks(); + if(*txtpos != '=') + goto qwhat; + txtpos++; + ignore_blanks(); + + expression_error = 0; + initial = expression(); + if(expression_error) + goto qwhat; + + scantable(to_tab); + if(table_index != 0) + goto qwhat; + + terminal = expression(); + if(expression_error) + goto qwhat; + + scantable(step_tab); + if(table_index == 0) + { + step = expression(); + if(expression_error) + goto qwhat; + } + else + step = 1; + ignore_blanks(); + if(*txtpos != NL && *txtpos != ':') + goto qwhat; + + + if(!expression_error && *txtpos == NL) + { + struct stack_for_frame *f; + if(sp1 + sizeof(struct stack_for_frame) < stack_limit) + goto qsorry; + + sp1 -= sizeof(struct stack_for_frame); + f = (struct stack_for_frame *)sp1; + ((short int *)variables_begin)[var-'A'] = initial; + f->frame_type = STACK_FOR_FLAG; + f->for_var = var; + f->terminal = terminal; + f->step = step; + f->txtpos = txtpos; + f->current_line = current_line; + goto run_next_statement; + } + } + goto qhow; + +gosub: + expression_error = 0; + linenum = expression(); + if(!expression_error && *txtpos == NL) + { + struct stack_gosub_frame *f; + if(sp1 + sizeof(struct stack_gosub_frame) < stack_limit) + goto qsorry; + + sp1 -= sizeof(struct stack_gosub_frame); + f = (struct stack_gosub_frame *)sp1; + f->frame_type = STACK_GOSUB_FLAG; + f->txtpos = txtpos; + f->current_line = current_line; + current_line = findline(); + goto execline; + } + goto qhow; + +next: + // Fnd the variable name + ignore_blanks(); + if(*txtpos < 'A' || *txtpos > 'Z') + goto qhow; + txtpos++; + ignore_blanks(); + if(*txtpos != ':' && *txtpos != NL) + goto qwhat; + +gosub_return: + // Now walk up the stack frames and find the frame we want, if present + tempsp = sp1; + while(tempsp < program+sizeof(program)-1) + { + switch(tempsp[0]) + { + case STACK_GOSUB_FLAG: + if(table_index == KW_RETURN) + { + struct stack_gosub_frame *f = (struct stack_gosub_frame *)tempsp; + current_line = f->current_line; + txtpos = f->txtpos; + sp1 += sizeof(struct stack_gosub_frame); + goto run_next_statement; + } + // This is not the loop you are looking for... so Walk back up the stack + tempsp += sizeof(struct stack_gosub_frame); + break; + case STACK_FOR_FLAG: + // Flag, Var, Final, Step + if(table_index == KW_NEXT) + { + struct stack_for_frame *f = (struct stack_for_frame *)tempsp; + // Is the the variable we are looking for? + if(txtpos[-1] == f->for_var) + { + short int *varaddr = ((short int *)variables_begin) + txtpos[-1] - 'A'; + *varaddr = *varaddr + f->step; + // Use a different test depending on the sign of the step increment + if((f->step > 0 && *varaddr <= f->terminal) || (f->step < 0 && *varaddr >= f->terminal)) + { + // We have to loop so don't pop the stack + txtpos = f->txtpos; + current_line = f->current_line; + goto run_next_statement; + } + // We've run to the end of the loop. drop out of the loop, popping the stack + sp1 = tempsp + sizeof(struct stack_for_frame); + goto run_next_statement; + } + } + // This is not the loop you are looking for... so Walk back up the stack + tempsp += sizeof(struct stack_for_frame); + break; + default: + //printf("Stack is stuffed!\n"); + goto warmstart; + } + } + // Didn't find the variable we've been looking for + goto qhow; + +assignment: + { + short int value; + short int *var; + + if(*txtpos < 'A' || *txtpos > 'Z') + goto qhow; + var = (short int *)variables_begin + *txtpos - 'A'; + txtpos++; + + ignore_blanks(); + + if (*txtpos != '=') + goto qwhat; + txtpos++; + ignore_blanks(); + expression_error = 0; + value = expression(); + if(expression_error) + goto qwhat; + // Check that we are at the end of the statement + if(*txtpos != NL && *txtpos != ':') + goto qwhat; + *var = value; + } + goto run_next_statement; +poke: + { + short int value; + unsigned char *address; + + // Work out where to put it + expression_error = 0; + value = expression(); + if(expression_error) + goto qwhat; + address = (unsigned char *)value; + + // check for a comma + ignore_blanks(); + if (*txtpos != ',') + goto qwhat; + txtpos++; + ignore_blanks(); + + // Now get the value to assign + expression_error = 0; + value = expression(); + if(expression_error) + goto qwhat; + //printf("Poke %p value %i\n",address, (unsigned char)value); + // Check that we are at the end of the statement + if(*txtpos != NL && *txtpos != ':') + goto qwhat; + } + goto run_next_statement; + +list: + linenum = testnum(); // Retuns 0 if no line found. + + // Should be EOL + if(txtpos[0] != NL) + goto qwhat; + + // Find the line + list_line = findline(); + while(list_line != program_end) + printline(); + goto warmstart; + +print: + // If we have an empty list then just put out a NL + if(*txtpos == ':' ) + { + line_terminator(); + txtpos++; + goto run_next_statement; + } + if(*txtpos == NL) + { + goto execnextline; + } + + while(1) + { + ignore_blanks(); + if(print_quoted_string()) + { + ; + } + else if(*txtpos == '"' || *txtpos == '\'') + goto qwhat; + else + { + short int e; + expression_error = 0; + e = expression(); + if(expression_error) + goto qwhat; + printnum(e); + } + + // At this point we have three options, a comma or a new line + if(*txtpos == ',') + txtpos++; // Skip the comma and move onto the next + else if(txtpos[0] == ';' && (txtpos[1] == NL || txtpos[1] == ':')) + { + txtpos++; // This has to be the end of the print - no newline + break; + } + else if(*txtpos == NL || *txtpos == ':') + { + line_terminator(); // The end of the print statement + break; + } + else + goto qwhat; + } + goto run_next_statement; + +mem: + // memory free + printnum(variables_begin-program_end); + printmsg(memorymsg); +#ifdef ARDUINO +#ifdef ENABLE_EEPROM + { + // eprom size + printnum( E2END+1 ); + printmsg( eeprommsg ); + + // figure out the memory usage; + val = ' '; + int i; + for( i=0 ; (i<(E2END+1)) && (val != '\0') ; i++ ) { + val = EEPROM.read( i ); + } + printnum( (E2END +1) - (i-1) ); + + printmsg( eepromamsg ); + } +#endif /* ENABLE_EEPROM */ +#endif /* ARDUINO */ + goto run_next_statement; + + + /*************************************************/ + +#ifdef ARDUINO +awrite: // AWRITE ,val +dwrite: + { + short int pinNo; + short int value; + unsigned char *txtposBak; + + // Get the pin number + expression_error = 0; + pinNo = expression(); + if(expression_error) + goto qwhat; + + // check for a comma + ignore_blanks(); + if (*txtpos != ',') + goto qwhat; + txtpos++; + ignore_blanks(); + + + txtposBak = txtpos; + scantable(highlow_tab); + if(table_index != HIGHLOW_UNKNOWN) + { + if( table_index <= HIGHLOW_HIGH ) { + value = 1; + } + else { + value = 0; + } + } + else { + + // and the value (numerical) + expression_error = 0; + value = expression(); + if(expression_error) + goto qwhat; + } + pinMode( pinNo, OUTPUT ); + if( isDigital ) { + digitalWrite( pinNo, value ); + } + else { + analogWrite( pinNo, value ); + } + } + goto run_next_statement; +#else +pinmode: // PINMODE , I/O +awrite: // AWRITE ,val +dwrite: + goto unimplemented; +#endif + + /*************************************************/ +files: + // display a listing of files on the device. + // version 1: no support for subdirectories + +#ifdef ENABLE_FILEIO + cmd_Files(); + goto warmstart; +#else + goto unimplemented; +#endif // ENABLE_FILEIO + + +chain: + runAfterLoad = true; + +load: + // clear the program + program_end = program_start; + + // load from a file into memory +#ifdef ENABLE_FILEIO + { + unsigned char *filename; + + // Work out the filename + expression_error = 0; + filename = filenameWord(); + if(expression_error) + goto qwhat; + +#ifdef ARDUINO + // Arduino specific + if( !SD.exists( (char *)filename )) + { + printmsg( sdfilemsg ); + } + else { + + fp = SD.open( (const char *)filename ); + inStream = kStreamFile; + inhibitOutput = true; + } +#else // ARDUINO + // Desktop specific +#endif // ARDUINO + // this will kickstart a series of events to read in from the file. + + } + goto warmstart; +#else // ENABLE_FILEIO + goto unimplemented; +#endif // ENABLE_FILEIO + + + +save: + // save from memory out to a file +#ifdef ENABLE_FILEIO + { + unsigned char *filename; + + // Work out the filename + expression_error = 0; + filename = filenameWord(); + if(expression_error) + goto qwhat; + +#ifdef ARDUINO + // remove the old file if it exists + if( SD.exists( (char *)filename )) { + SD.remove( (char *)filename ); + } + + // open the file, switch over to file output + fp = SD.open( (const char *)filename, FILE_WRITE ); + outStream = kStreamFile; + + // copied from "List" + list_line = findline(); + while(list_line != program_end) + printline(); + + // go back to standard output, close the file + outStream = kStreamSerial; + + fp.close(); +#else // ARDUINO + // desktop +#endif // ARDUINO + goto warmstart; + } +#else // ENABLE_FILEIO + goto unimplemented; +#endif // ENABLE_FILEIO + +rseed: + { + short int value; + + //Get the pin number + expression_error = 0; + value = expression(); + if(expression_error) + goto qwhat; + +#ifdef ARDUINO + randomSeed( value ); +#else // ARDUINO + srand( value ); +#endif // ARDUINO + goto run_next_statement; + } + +#ifdef ENABLE_TONES +tonestop: + noTone( kPiezoPin ); + goto run_next_statement; + +tonegen: + { + // TONE freq, duration + // if either are 0, tones turned off + short int freq; + short int duration; + + //Get the frequency + expression_error = 0; + freq = expression(); + if(expression_error) + goto qwhat; + + ignore_blanks(); + if (*txtpos != ',') + goto qwhat; + txtpos++; + ignore_blanks(); + + + //Get the duration + expression_error = 0; + duration = expression(); + if(expression_error) + goto qwhat; + + if( freq == 0 || duration == 0 ) + goto tonestop; + + tone( kPiezoPin, freq, duration ); + if( alsoWait ) { + delay( duration ); + alsoWait = false; + } + goto run_next_statement; + } +#endif /* ENABLE_TONES */ +} + +// returns 1 if the character is valid in a filename +static int isValidFnChar( char c ) +{ + if( c >= '0' && c <= '9' ) return 1; // number + if( c >= 'A' && c <= 'Z' ) return 1; // LETTER + if( c >= 'a' && c <= 'z' ) return 1; // letter (for completeness) + if( c == '_' ) return 1; + if( c == '+' ) return 1; + if( c == '.' ) return 1; + if( c == '~' ) return 1; // Window~1.txt + + return 0; +} + +unsigned char * filenameWord(void) +{ + // SDL - I wasn't sure if this functionality existed above, so I figured i'd put it here + unsigned char * ret = txtpos; + expression_error = 0; + + // make sure there are no quotes or spaces, search for valid characters + //while(*txtpos == SPACE || *txtpos == TAB || *txtpos == SQUOTE || *txtpos == DQUOTE ) txtpos++; + while( !isValidFnChar( *txtpos )) txtpos++; + ret = txtpos; + + if( *ret == '\0' ) { + expression_error = 1; + return ret; + } + + // now, find the next nonfnchar + txtpos++; + while( isValidFnChar( *txtpos )) txtpos++; + if( txtpos != ret ) *txtpos = '\0'; + + // set the error code if we've got no string + if( *ret == '\0' ) { + expression_error = 1; + } + + return ret; +} + +/***************************************************************************/ +static void line_terminator(void) +{ + outchar(NL); + outchar(CR); +} + +/***********************************************************/ +void setup() +{ +#ifdef ARDUINO + TV.begin(PAL, 720, 480); + TV.select_font(font6x8); + TV.set_hbi_hook(keyboard.begin()); + + //Serial1.begin(kConsoleBaud); + //Serial1.println(sentinel); + + //TV.println( sentinel ); + printmsg(initmsg); + +#ifdef ENABLE_FILEIO + initSD(); + +#ifdef ENABLE_AUTORUN + if( SD.exists( kAutorunFilename )) { + program_end = program_start; + fp = SD.open( kAutorunFilename ); + inStream = kStreamFile; + inhibitOutput = true; + runAfterLoad = true; + } +#endif /* ENABLE_AUTORUN */ + +#endif /* ENABLE_FILEIO */ + +#ifdef ENABLE_EEPROM +#ifdef ENABLE_EAUTORUN + // read the first byte of the eeprom. if it's a number, assume it's a program we can load + int val = EEPROM.read(0); + if( val >= '0' && val <= '9' ) { + program_end = program_start; + inStream = kStreamEEProm; + eepos = 0; + inhibitOutput = true; + runAfterLoad = true; + } +#endif /* ENABLE_EAUTORUN */ +#endif /* ENABLE_EEPROM */ + +#endif /* ARDUINO */ +} + + +/***********************************************************/ +static unsigned char breakcheck(void) +{ +#ifdef ARDUINO + if(keyboard.available()) + return keyboard.read() == CTRLC; + //else if (Serial1.available()) + //return Serial1.read() == CTRLC; + return 0; +#else +#ifdef __CONIO__ + if(keyboardhit()) + return getch() == CTRLC; + else +#endif + return 0; +#endif +} +/***********************************************************/ +static int inchar() +{ + int v; +#ifdef ARDUINO + + switch( inStream ) { + case( kStreamFile ): +#ifdef ENABLE_FILEIO + v = fp.read(); + if( v == NL ) v=CR; // file translate + if( !fp.available() ) { + fp.close(); + goto inchar_loadfinish; + } + return v; +#else +#endif + break; + case( kStreamEEProm ): +#ifdef ENABLE_EEPROM +#ifdef ARDUINO + v = EEPROM.read( eepos++ ); + if( v == '\0' ) { + goto inchar_loadfinish; + } + return v; +#endif +#else + inStream = kStreamSerial; + return NL; +#endif + break; + case( kStreamSerial ): + default: + while(1) + { + if(keyboard.available()) + return keyboard.read(); + //else if (Serial1.available()) + //return Serial1.read(); + } + } + +inchar_loadfinish: + inStream = kStreamSerial; + inhibitOutput = false; + + if( runAfterLoad ) { + runAfterLoad = false; + triggerRun = true; + } + return NL; // trigger a prompt. + +#else + // otherwise. desktop! + int got = getchar(); + + // translation for desktop systems + if( got == LF ) got = CR; + + return got; +#endif +} + +/***********************************************************/ +static void outchar(unsigned char c) +{ + if( inhibitOutput ) return; + +#ifdef ARDUINO + #ifdef ENABLE_FILEIO + if( outStream == kStreamFile ) { + // output to a file + fp.write( c ); + } + else + #endif + #ifdef ARDUINO + #ifdef ENABLE_EEPROM + if( outStream == kStreamEEProm ) { + EEPROM.write( eepos++, c ); + } + else + #endif /* ENABLE_EEPROM */ + #endif /* ARDUINO */ + TV.print((char)c); + //Serial1.write(c); + +#else + putchar(c); +#endif +} + +/***********************************************************/ +/* SD Card helpers */ + +#if ARDUINO && ENABLE_FILEIO + +static int initSD( void ) +{ + // if the card is already initialized, we just go with it. + // there is no support (yet?) for hot-swap of SD Cards. if you need to + // swap, pop the card, reset the arduino.) + + if( sd_is_initialized == true ) return kSD_OK; + + // due to the way the SD Library works, pin 10 always needs to be + // an output, even when your shield uses another line for CS + pinMode(4, OUTPUT); // change this to 53 on a mega + + if( !SD.begin( kSD_CS )) { + // failed + printmsg( sderrormsg ); + return kSD_Fail; + } + // success - quietly return 0 + sd_is_initialized = true; + + // and our file redirection flags + outStream = kStreamSerial; + inStream = kStreamSerial; + inhibitOutput = false; + + return kSD_OK; +} +#endif + +#if ENABLE_FILEIO +void cmd_Files( void ) +{ + File dir = SD.open( "/" ); + dir.seek(0); + + while( true ) { + File entry = dir.openNextFile(); + if( !entry ) { + entry.close(); + break; + } + + // common header + printmsgNoNL( indentmsg ); + printmsgNoNL( (const unsigned char *)entry.name() ); + if( entry.isDirectory() ) { + printmsgNoNL( slashmsg ); + } + + if( entry.isDirectory() ) { + // directory ending + for( int i=strlen( entry.name()) ; i<16 ; i++ ) { + printmsgNoNL( spacemsg ); + } + printmsgNoNL( dirextmsg ); + } + else { + // file ending + for( int i=strlen( entry.name()) ; i<17 ; i++ ) { + printmsgNoNL( spacemsg ); + } + printUnum( entry.size() ); + } + line_terminator(); + entry.close(); + } + dir.close(); +} +#endif + diff --git a/trunk/Arduino/Single_Chip_VIC20/Single_Chip_VIC20.ino b/trunk/Arduino/Single_Chip_VIC20/Single_Chip_VIC20.ino new file mode 100644 index 00000000..108a9f4f --- /dev/null +++ b/trunk/Arduino/Single_Chip_VIC20/Single_Chip_VIC20.ino @@ -0,0 +1,179 @@ +#include + +#include +#include +#include +#include + +//----------------- VideoBlaster definitions ----------------- + +#define DOTCLK 1 // Pixel clock (0 for 8MHz, 1 for 4MHz) +#define HSYNC 132 // Hsync frequency (divided from Fcpu) +#define LINES 261 // Lines per field -1 (261 for NTSC, 311 for PAL) +#define SYNCPIN 4 // Pin in PORTD that rhat is connected for sync +#define INTERLACE 0 // 0 for interlace, 1 for non interlace Running with interlaced video gives more cycles to the application + +volatile byte VBE=0; // Video blanking status. If this is not zero you should sleep to keep the video smooth + +#define WAIT_VBE while (VBE==1) sleep_cpu(); + +unsigned int scanline=0; // Dont touch, not volatile +unsigned int videoptr=0; // Dont touch, not volatile +byte row; // Dont touch, not volatile +byte lace; // Dont touch, not volatile + +// This is the video character ROM (8x8 font definition) +const unsigned char charROM [8] [128] PROGMEM = { 0x1C , 0x18 , 0x7C , 0x1C , 0x78 , 0x7E , 0x7E , 0x1C , 0x42 , 0x1C , 0xE , 0x42 , 0x40 , 0x42 , 0x42 , 0x18 , 0x7C , 0x18 , 0x7C , 0x3C , 0x3E , 0x42 , 0x42 , 0x42 , 0x42 , 0x22 , 0x7E , 0x42 , 0x42 , 0x18 , 0x0 , 0x0 , 0x0 , 0x8 , 0x24 , 0x24 , 0x8 , 0x0 , 0x30 , 0x4 , 0x4 , 0x20 , 0x8 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x3C , 0x8 , 0x3C , 0x3C , 0x4 , 0x7E , 0x1C , 0x7E , 0x3C , 0x3C , 0x0 , 0x0 , 0xE , 0x0 , 0x70 , 0x3C , 0x0 , 0x8 , 0x10 , 0x0 , 0x0 , 0x0 , 0x0 , 0x20 , 0x4 , 0x0 , 0x8 , 0x8 , 0x80 , 0x80 , 0x1 , 0xFF , 0xFF , 0x0 , 0x0 , 0x36 , 0x40 , 0x0 , 0x81 , 0x0 , 0x8 , 0x2 , 0x8 , 0x8 , 0xA0 , 0x8 , 0x0 , 0xFF , 0x0 , 0xF0 , 0x0 , 0xFF , 0x0 , 0x80 , 0xAA , 0x1 , 0x0 , 0xFF , 0x3 , 0x8 , 0x0 , 0x8 , 0x0 , 0x0 , 0x0 , 0x8 , 0x0 , 0x8 , 0xC0 , 0xE0 , 0x7 , 0xFF , 0xFF , 0x0 , 0x1 , 0x0 , 0xF , 0x8 , 0xF0 , 0xF0 , 0x22 , 0x24 , 0x22 , 0x22 , 0x24 , 0x40 , 0x40 , 0x22 , 0x42 , 0x8 , 0x4 , 0x44 , 0x40 , 0x66 , 0x62 , 0x24 , 0x42 , 0x24 , 0x42 , 0x42 , 0x8 , 0x42 , 0x42 , 0x42 , 0x42 , 0x22 , 0x2 , 0x18 , 0x18 , 0x24 , 0x8 , 0x0 , 0x0 , 0x8 , 0x24 , 0x24 , 0x1E , 0x62 , 0x48 , 0x8 , 0x8 , 0x10 , 0x2A , 0x8 , 0x0 , 0x0 , 0x0 , 0x2 , 0x42 , 0x18 , 0x42 , 0x42 , 0xC , 0x40 , 0x20 , 0x42 , 0x42 , 0x42 , 0x0 , 0x0 , 0x18 , 0x0 , 0x18 , 0x42 , 0x0 , 0x1C , 0x10 , 0x0 , 0x0 , 0xFF , 0x0 , 0x20 , 0x4 , 0x0 , 0x8 , 0x8 , 0x80 , 0x40 , 0x2 , 0x80 , 0x1 , 0x3C , 0x0 , 0x7F , 0x40 , 0x0 , 0x42 , 0x3C , 0x1C , 0x2 , 0x1C , 0x8 , 0x50 , 0x8 , 0x0 , 0x7F , 0x0 , 0xF0 , 0x0 , 0x0 , 0x0 , 0x80 , 0x55 , 0x1 , 0x0 , 0xFE , 0x3 , 0x8 , 0x0 , 0x8 , 0x0 , 0x0 , 0x0 , 0x8 , 0x0 , 0x8 , 0xC0 , 0xE0 , 0x7 , 0xFF , 0xFF , 0x0 , 0x1 , 0x0 , 0xF , 0x8 , 0xF0 , 0xF0 , 0x4A , 0x42 , 0x22 , 0x40 , 0x22 , 0x40 , 0x40 , 0x40 , 0x42 , 0x8 , 0x4 , 0x48 , 0x40 , 0x5A , 0x52 , 0x42 , 0x42 , 0x42 , 0x42 , 0x40 , 0x8 , 0x42 , 0x42 , 0x42 , 0x24 , 0x22 , 0x4 , 0x24 , 0x24 , 0x3C , 0x1C , 0x10 , 0x0 , 0x8 , 0x24 , 0x7E , 0x28 , 0x64 , 0x48 , 0x10 , 0x10 , 0x8 , 0x1C , 0x8 , 0x0 , 0x0 , 0x0 , 0x4 , 0x46 , 0x28 , 0x2 , 0x2 , 0x14 , 0x78 , 0x40 , 0x4 , 0x42 , 0x42 , 0x8 , 0x8 , 0x30 , 0x7E , 0xC , 0x2 , 0x0 , 0x3E , 0x10 , 0x0 , 0xFF , 0x0 , 0x0 , 0x20 , 0x4 , 0x0 , 0x8 , 0x8 , 0x80 , 0x20 , 0x4 , 0x80 , 0x1 , 0x7E , 0x0 , 0x7F , 0x40 , 0x0 , 0x24 , 0x42 , 0x2A , 0x2 , 0x3E , 0x8 , 0xA0 , 0x8 , 0x1 , 0x3F , 0x0 , 0xF0 , 0x0 , 0x0 , 0x0 , 0x80 , 0xAA , 0x1 , 0x0 , 0xFC , 0x3 , 0x8 , 0x0 , 0x8 , 0x0 , 0x0 , 0x0 , 0x8 , 0x0 , 0x8 , 0xC0 , 0xE0 , 0x7 , 0x0 , 0xFF , 0x0 , 0x1 , 0x0 , 0xF , 0x8 , 0xF0 , 0xF0 , 0x56 , 0x7E , 0x3C , 0x40 , 0x22 , 0x78 , 0x78 , 0x4E , 0x7E , 0x8 , 0x4 , 0x70 , 0x40 , 0x5A , 0x4A , 0x42 , 0x7C , 0x42 , 0x7C , 0x3C , 0x8 , 0x42 , 0x24 , 0x5A , 0x18 , 0x1C , 0x18 , 0x42 , 0x42 , 0x42 , 0x2A , 0x20 , 0x0 , 0x8 , 0x0 , 0x24 , 0x1C , 0x8 , 0x30 , 0x0 , 0x10 , 0x8 , 0x3E , 0x3E , 0x0 , 0x7E , 0x0 , 0x8 , 0x5A , 0x8 , 0xC , 0x1C , 0x24 , 0x4 , 0x7C , 0x8 , 0x3C , 0x3E , 0x0 , 0x0 , 0x60 , 0x0 , 0x6 , 0xC , 0x0 , 0x7F , 0x10 , 0xFF , 0x0 , 0x0 , 0x0 , 0x20 , 0x4 , 0x0 , 0x4 , 0x10 , 0x80 , 0x10 , 0x8 , 0x80 , 0x1 , 0x7E , 0x0 , 0x7F , 0x40 , 0x0 , 0x18 , 0x42 , 0x77 , 0x2 , 0x7F , 0x8 , 0x50 , 0x8 , 0x3E , 0x1F , 0x0 , 0xF0 , 0x0 , 0x0 , 0x0 , 0x80 , 0x55 , 0x1 , 0x0 , 0xF8 , 0x3 , 0x8 , 0x0 , 0x8 , 0x0 , 0x0 , 0x0 , 0x8 , 0x0 , 0x8 , 0xC0 , 0xE0 , 0x7 , 0x0 , 0x0 , 0x0 , 0x1 , 0x0 , 0xF , 0x8 , 0xF0 , 0xF0 , 0x4C , 0x42 , 0x22 , 0x40 , 0x22 , 0x40 , 0x40 , 0x42 , 0x42 , 0x8 , 0x4 , 0x48 , 0x40 , 0x42 , 0x46 , 0x42 , 0x40 , 0x4A , 0x48 , 0x2 , 0x8 , 0x42 , 0x24 , 0x5A , 0x24 , 0x8 , 0x20 , 0x7E , 0x42 , 0x7E , 0x8 , 0x7F , 0x0 , 0x0 , 0x0 , 0x7E , 0xA , 0x10 , 0x4A , 0x0 , 0x10 , 0x8 , 0x1C , 0x8 , 0x0 , 0x0 , 0x0 , 0x10 , 0x62 , 0x8 , 0x30 , 0x2 , 0x7E , 0x2 , 0x42 , 0x10 , 0x42 , 0x2 , 0x0 , 0x0 , 0x30 , 0x7E , 0xC , 0x10 , 0xFF , 0x7F , 0x10 , 0x0 , 0x0 , 0x0 , 0x0 , 0x20 , 0x4 , 0xE0 , 0x3 , 0xE0 , 0x80 , 0x8 , 0x10 , 0x80 , 0x1 , 0x7E , 0x0 , 0x3E , 0x40 , 0x3 , 0x18 , 0x42 , 0x2A , 0x2 , 0x3E , 0xFF , 0xA0 , 0x8 , 0x54 , 0xF , 0x0 , 0xF0 , 0xFF , 0x0 , 0x0 , 0x80 , 0xAA , 0x1 , 0xAA , 0xF0 , 0x3 , 0xF , 0xF , 0xF , 0xF8 , 0x0 , 0xF , 0xFF , 0xFF , 0xF8 , 0xC0 , 0xE0 , 0x7 , 0x0 , 0x0 , 0x0 , 0x1 , 0xF0 , 0x0 , 0xF8 , 0x0 , 0xF , 0x20 , 0x42 , 0x22 , 0x22 , 0x24 , 0x40 , 0x40 , 0x22 , 0x42 , 0x8 , 0x44 , 0x44 , 0x40 , 0x42 , 0x42 , 0x24 , 0x40 , 0x24 , 0x44 , 0x42 , 0x8 , 0x42 , 0x18 , 0x66 , 0x42 , 0x8 , 0x40 , 0x42 , 0x24 , 0x42 , 0x8 , 0x20 , 0x0 , 0x0 , 0x0 , 0x24 , 0x3C , 0x26 , 0x44 , 0x0 , 0x8 , 0x10 , 0x2A , 0x8 , 0x8 , 0x0 , 0x18 , 0x20 , 0x42 , 0x8 , 0x40 , 0x42 , 0x4 , 0x44 , 0x42 , 0x10 , 0x42 , 0x4 , 0x8 , 0x8 , 0x18 , 0x0 , 0x18 , 0x0 , 0x0 , 0x1C , 0x10 , 0x0 , 0x0 , 0x0 , 0xFF , 0x20 , 0x4 , 0x10 , 0x0 , 0x0 , 0x80 , 0x4 , 0x20 , 0x80 , 0x1 , 0x7E , 0x0 , 0x1C , 0x40 , 0x4 , 0x24 , 0x42 , 0x8 , 0x2 , 0x1C , 0x8 , 0x50 , 0x8 , 0x14 , 0x7 , 0x0 , 0xF0 , 0xFF , 0x0 , 0x0 , 0x80 , 0x55 , 0x1 , 0x55 , 0xE0 , 0x3 , 0x8 , 0xF , 0x0 , 0x8 , 0x0 , 0x8 , 0x0 , 0x8 , 0x8 , 0xC0 , 0xE0 , 0x7 , 0x0 , 0x0 , 0xFF , 0x1 , 0xF0 , 0x0 , 0x0 , 0x0 , 0xF , 0x1E , 0x42 , 0x7C , 0x1C , 0x78 , 0x7E , 0x40 , 0x1C , 0x42 , 0x1C , 0x38 , 0x42 , 0x7E , 0x42 , 0x42 , 0x18 , 0x40 , 0x1A , 0x42 , 0x3C , 0x8 , 0x3C , 0x18 , 0x42 , 0x42 , 0x8 , 0x7E , 0x42 , 0x18 , 0x42 , 0x8 , 0x10 , 0x0 , 0x8 , 0x0 , 0x24 , 0x8 , 0x46 , 0x3A , 0x0 , 0x4 , 0x20 , 0x8 , 0x0 , 0x8 , 0x0 , 0x18 , 0x40 , 0x3C , 0x3E , 0x7E , 0x3C , 0x4 , 0x38 , 0x3C , 0x10 , 0x3C , 0x38 , 0x0 , 0x8 , 0xE , 0x0 , 0x70 , 0x10 , 0x0 , 0x3E , 0x10 , 0x0 , 0x0 , 0x0 , 0x0 , 0x20 , 0x4 , 0x8 , 0x0 , 0x0 , 0x80 , 0x2 , 0x40 , 0x80 , 0x1 , 0x3C , 0xFF , 0x8 , 0x40 , 0x8 , 0x42 , 0x3C , 0x8 , 0x2 , 0x8 , 0x8 , 0xA0 , 0x8 , 0x14 , 0x3 , 0x0 , 0xF0 , 0xFF , 0x0 , 0x0 , 0x80 , 0xAA , 0x1 , 0xAA , 0xC0 , 0x3 , 0x8 , 0xF , 0x0 , 0x8 , 0xFF , 0x8 , 0x0 , 0x8 , 0x8 , 0xC0 , 0xE0 , 0x7 , 0x0 , 0x0 , 0xFF , 0x1 , 0xF0 , 0x0 , 0x0 , 0x0 , 0xF , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x8 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x10 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x10 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x10 , 0x0 , 0x0 , 0x0 , 0x0 , 0x20 , 0x4 , 0x8 , 0x0 , 0x0 , 0xFF , 0x1 , 0x80 , 0x80 , 0x1 , 0x0 , 0x0 , 0x0 , 0x40 , 0x8 , 0x81 , 0x0 , 0x0 , 0x2 , 0x0 , 0x8 , 0x50 , 0x8 , 0x0 , 0x1 , 0x0 , 0xF0 , 0xFF , 0x0 , 0xFF , 0x80 , 0x55 , 0x1 , 0x55 , 0x80 , 0x3 , 0x8 , 0xF , 0x0 , 0x8 , 0xFF , 0x8 , 0x0 , 0x8 , 0x8 , 0xC0 , 0xE0 , 0x7 , 0x0 , 0x0 , 0xFF , 0xFF , 0xF0 , 0x0 , 0x0 , 0x0 , 0xF }; + +#define SYNCDELAY // This makes up the sync pulse low time delay + asm("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n"); \ + asm("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n"); \ + asm("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n"); \ + asm("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n"); \ + asm("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n"); \ + asm("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n"); \ + asm("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n"); \ + asm("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n"); + +const byte MSPIM_SCK = 4; // This is needed for the hardware to work +const byte MSPIM_SS = 5; // This is needed for the hardware to work + +//-------------------------------------------------------------- + + + +char videomem[528]; +char basicram[512]; + +uint8_t RAM[832]; + +extern "C" { + void exec6502(); + void reset6502(); + + void writeEEPROM(unsigned int eeaddress, byte data ) { + if ((eeaddress>7679)&&(eeaddress<8192)) { + videomem[eeaddress-7680+22]=data; + return; + } + if ((eeaddress>1023)&&(eeaddress<2048)) { + digitalWrite(13,HIGH); + EEPROM.write(eeaddress&0x3FF, data); + digitalWrite(13,LOW); + return; + } + if ((eeaddress>2047)&&(eeaddress<7680)) { + basicram[eeaddress&0x1FF]=data; + return; + } + return; +} + + +byte readEEPROM(unsigned int eeaddress ) { + if ((eeaddress>7679)&&(eeaddress<8192)) { + return videomem[eeaddress-7680+22]; + } + if ((eeaddress>1023)&&(eeaddress<2048)) { + return EEPROM.read(eeaddress&0x3FF); + } + if ((eeaddress>2047)&&(eeaddress<7680)) { + return basicram[eeaddress&0x1FF]; + } + return 0xFF; +} +} + + + + +ISR(TIMER0_COMPA_vect){ //Video interrupt. This is called at every line in the frame. + byte c=8; //Back porch + byte d=4; //Left Blank + byte p=22; //Chars per row + PORTD=0; + if ((scanline>2)&&(scanline<40)||(scanline>231)) { + SYNCDELAY + PORTD = SYNCPIN; + VBE=0; + } + + if (scanline<3) { + SYNCDELAY + PORTD =0; + videoptr=0; + row=0; + } + + if ((scanline>39)&&(scanline<232)) { + SYNCDELAY + PORTD = SYNCPIN; + if (lace&1|INTERLACE) { + const register byte * linePtr = &charROM [ row & 0x07 ] [0]; + register byte * messagePtr = (byte *) & videomem [videoptr] ; + while (c--) { + asm("nop\n"); + asm("nop\n"); + } + UCSR0B = _BV(TXEN0); + while (d--) { + while ((UCSR0A & _BV (UDRE0)) == 0) {} + UDR0 = 0; + } + while (p--) { + UDR0 = pgm_read_byte (linePtr + (* messagePtr++)); + while ((UCSR0A & _BV (UDRE0)) == 0) + {} + } + while ((UCSR0A & _BV (UDRE0)) == 0) + {} + UCSR0B = 0; + row++; + videoptr=(row>>3)*22; + VBE=1; + } + } + scanline++; + if (scanline>LINES) { + scanline=0; + lace++; + } +} + +void setup () { + pinMode (MSPIM_SS, OUTPUT); //A must for MSMSPI VIDEO to work + pinMode (MSPIM_SCK, OUTPUT); //A must for MSMSPI VIDEO to work + pinMode(2, OUTPUT); //Set D2 as output for Sync. A must for MSMSPI VIDEO to work + UBRR0 = 0; + UCSR0A = _BV (TXC0); + UCSR0C = _BV (UMSEL00) | _BV (UMSEL01); + UCSR0B = _BV (TXEN0); + UBRR0 = DOTCLK; + cli(); + TCCR0A = 0; + TCCR0B = 0; + TCNT0 = 0; + OCR0A = HSYNC;// = (16*10^6) / (15625*8) - 1 (must be <256) + TCCR0A |= (1 << WGM01); + TCCR0B |= (1 << CS01) | (0 << CS00); + TIMSK0 |= (1 << OCIE0A); + set_sleep_mode (SLEEP_MODE_IDLE); + sei(); + + pinMode(13, OUTPUT); + digitalWrite(13,LOW); + pinMode(1, OUTPUT); //A must for MSMSPI VIDEO to work + digitalWrite(1,LOW); //A must for MSMSPI VIDEO to work + reset6502(); + for (int i=0;i<528;i++) { + videomem[i]=32; + } +} + +void loop () { + WAIT_VBE + exec6502(); + RAM[55]=0; //POKE55,0 + RAM[56]=0x0A; //POKE56,10 lower top of mem to 0x0A +} + diff --git a/trunk/Arduino/Single_Chip_VIC20/cpu.c b/trunk/Arduino/Single_Chip_VIC20/cpu.c new file mode 100644 index 00000000..098570a2 --- /dev/null +++ b/trunk/Arduino/Single_Chip_VIC20/cpu.c @@ -0,0 +1,1384 @@ +#include +#include + +//extern void printhex(uint16_t val); +//extern void serout(uint8_t value); +extern uint8_t RAM[]; + +#define NULL (void *) 0 + +#define RAM_SIZE 832 + +#define FLAG_CARRY 0x01 +#define FLAG_ZERO 0x02 +#define FLAG_INTERRUPT 0x04 +#define FLAG_DECIMAL 0x08 +#define FLAG_BREAK 0x10 +#define FLAG_CONSTANT 0x20 +#define FLAG_OVERFLOW 0x40 +#define FLAG_SIGN 0x80 + +#define BASE_STACK 0x100 + +#define saveaccum(n) a = (uint8_t)((n) & 0x00FF) + + +//flag modifier macros +#define setcarry() cpustatus |= FLAG_CARRY +#define clearcarry() cpustatus &= (~FLAG_CARRY) +#define setzero() cpustatus |= FLAG_ZERO +#define clearzero() cpustatus &= (~FLAG_ZERO) +#define setinterrupt() cpustatus |= FLAG_INTERRUPT +#define clearinterrupt() cpustatus &= (~FLAG_INTERRUPT) +#define setdecimal() cpustatus |= FLAG_DECIMAL +#define cleardecimal() cpustatus &= (~FLAG_DECIMAL) +#define setoverflow() cpustatus |= FLAG_OVERFLOW +#define clearoverflow() cpustatus &= (~FLAG_OVERFLOW) +#define setsign() cpustatus |= FLAG_SIGN +#define clearsign() cpustatus &= (~FLAG_SIGN) + + +//flag calculation macros +#define zerocalc(n) { if ((n) & 0x00FF) clearzero(); else setzero(); } + +#define signcalc(n) { if ((n) & 0x0080) setsign(); else clearsign(); } + +#define carrycalc(n) { if ((n) & 0xFF00) setcarry(); else clearcarry(); } + +#define overflowcalc(n, m, o) { if (((n) ^ (uint16_t)(m)) & ((n) ^ (o)) & 0x0080) setoverflow(); else clearoverflow(); } + + +//6502 CPU registers +uint16_t pc; +uint8_t sp, a, x, y, cpustatus; + + +//helper variables +//uint32_t instructions = 0; //keep track of total instructions executed +//int32_t clockticks6502 = 0, clockgoal6502 = 0; +uint16_t oldpc, ea, reladdr, value, result; +uint8_t opcode, oldcpustatus, useaccum; + +uint8_t RAM[RAM_SIZE]; + +const unsigned char BIOS[16384] PROGMEM = { 0x78 , 0xE3 , 0x67 , 0xE4 , 0x43 , 0x42 , 0x4D , 0x42 , 0x41 , 0x53 , 0x49 , 0x43 , 0x30 , 0xC8 , 0x41 , 0xC7 , 0x1D , 0xCD , 0xF7 , 0xC8 , 0xA4 , 0xCB , 0xBE , 0xCB , 0x80 , 0xD0 , 0x5 , 0xCC , 0xA4 , 0xC9 , 0x9F , 0xC8 , 0x70 , 0xC8 , 0x27 , 0xC9 , 0x1C , 0xC8 , 0x82 , 0xC8 , 0xD1 , 0xC8 , 0x3A , 0xC9 , 0x2E , 0xC8 , 0x4A , 0xC9 , 0x2C , 0xD8 , 0x64 , 0xE1 , 0x52 , 0xE1 , 0x61 , 0xE1 , 0xB2 , 0xD3 , 0x23 , 0xD8 , 0x7F , 0xCA , 0x9F , 0xCA , 0x56 , 0xC8 , 0x9B , 0xC6 , 0x5D , 0xC6 , 0x85 , 0xCA , 0x26 , 0xE1 , 0xBA , 0xE1 , 0xC3 , 0xE1 , 0x7A , 0xCB , 0x41 , 0xC6 , 0x39 , 0xDC , 0xCC , 0xDC , 0x58 , 0xDC , 0x0 , 0x0 , 0x7D , 0xD3 , 0x9E , 0xD3 , 0x71 , 0xDF , 0x94 , 0xE0 , 0xEA , 0xD9 , 0xED , 0xDF , 0x61 , 0xE2 , 0x68 , 0xE2 , 0xB1 , 0xE2 , 0xB , 0xE3 , 0xD , 0xD8 , 0x7C , 0xD7 , 0x65 , 0xD4 , 0xAD , 0xD7 , 0x8B , 0xD7 , 0xEC , 0xD6 , 0x0 , 0xD7 , 0x2C , 0xD7 , 0x37 , 0xD7 , 0x79 , 0x69 , 0xD8 , 0x79 , 0x52 , 0xD8 , 0x7B , 0x2A , 0xDA , 0x7B , 0x11 , 0xDB , 0x7F , 0x7A , 0xDF , 0x50 , 0xE8 , 0xCF , 0x46 , 0xE5 , 0xCF , 0x7D , 0xB3 , 0xDF , 0x5A , 0xD3 , 0xCE , 0x64 , 0x15 , 0xD0 , 0x45 , 0x4E , 0xC4 , 0x46 , 0x4F , 0xD2 , 0x4E , 0x45 , 0x58 , 0xD4 , 0x44 , 0x41 , 0x54 , 0xC1 , 0x49 , 0x4E , 0x50 , 0x55 , 0x54 , 0xA3 , 0x49 , 0x4E , 0x50 , 0x55 , 0xD4 , 0x44 , 0x49 , 0xCD , 0x52 , 0x45 , 0x41 , 0xC4 , 0x4C , 0x45 , 0xD4 , 0x47 , 0x4F , 0x54 , 0xCF , 0x52 , 0x55 , 0xCE , 0x49 , 0xC6 , 0x52 , 0x45 , 0x53 , 0x54 , 0x4F , 0x52 , 0xC5 , 0x47 , 0x4F , 0x53 , 0x55 , 0xC2 , 0x52 , 0x45 , 0x54 , 0x55 , 0x52 , 0xCE , 0x52 , 0x45 , 0xCD , 0x53 , 0x54 , 0x4F , 0xD0 , 0x4F , 0xCE , 0x57 , 0x41 , 0x49 , 0xD4 , 0x4C , 0x4F , 0x41 , 0xC4 , 0x53 , 0x41 , 0x56 , 0xC5 , 0x56 , 0x45 , 0x52 , 0x49 , 0x46 , 0xD9 , 0x44 , 0x45 , 0xC6 , 0x50 , 0x4F , 0x4B , 0xC5 , 0x50 , 0x52 , 0x49 , 0x4E , 0x54 , 0xA3 , 0x50 , 0x52 , 0x49 , 0x4E , 0xD4 , 0x43 , 0x4F , 0x4E , 0xD4 , 0x4C , 0x49 , 0x53 , 0xD4 , 0x43 , 0x4C , 0xD2 , 0x43 , 0x4D , 0xC4 , 0x53 , 0x59 , 0xD3 , 0x4F , 0x50 , 0x45 , 0xCE , 0x43 , 0x4C , 0x4F , 0x53 , 0xC5 , 0x47 , 0x45 , 0xD4 , 0x4E , 0x45 , 0xD7 , 0x54 , 0x41 , 0x42 , 0xA8 , 0x54 , 0xCF , 0x46 , 0xCE , 0x53 , 0x50 , 0x43 , 0xA8 , 0x54 , 0x48 , 0x45 , 0xCE , 0x4E , 0x4F , 0xD4 , 0x53 , 0x54 , 0x45 , 0xD0 , 0xAB , 0xAD , 0xAA , 0xAF , 0xDE , 0x41 , 0x4E , 0xC4 , 0x4F , 0xD2 , 0xBE , 0xBD , 0xBC , 0x53 , 0x47 , 0xCE , 0x49 , 0x4E , 0xD4 , 0x41 , 0x42 , 0xD3 , 0x55 , 0x53 , 0xD2 , 0x46 , 0x52 , 0xC5 , 0x50 , 0x4F , 0xD3 , 0x53 , 0x51 , 0xD2 , 0x52 , 0x4E , 0xC4 , 0x4C , 0x4F , 0xC7 , 0x45 , 0x58 , 0xD0 , 0x43 , 0x4F , 0xD3 , 0x53 , 0x49 , 0xCE , 0x54 , 0x41 , 0xCE , 0x41 , 0x54 , 0xCE , 0x50 , 0x45 , 0x45 , 0xCB , 0x4C , 0x45 , 0xCE , 0x53 , 0x54 , 0x52 , 0xA4 , 0x56 , 0x41 , 0xCC , 0x41 , 0x53 , 0xC3 , 0x43 , 0x48 , 0x52 , 0xA4 , 0x4C , 0x45 , 0x46 , 0x54 , 0xA4 , 0x52 , 0x49 , 0x47 , 0x48 , 0x54 , 0xA4 , 0x4D , 0x49 , 0x44 , 0xA4 , 0x47 , 0xCF , 0x0 , 0x54 , 0x4F , 0x4F , 0x20 , 0x4D , 0x41 , 0x4E , 0x59 , 0x20 , 0x46 , 0x49 , 0x4C , 0x45 , 0xD3 , 0x46 , 0x49 , 0x4C , 0x45 , 0x20 , 0x4F , 0x50 , 0x45 , 0xCE , 0x46 , 0x49 , 0x4C , 0x45 , 0x20 , 0x4E , 0x4F , 0x54 , 0x20 , 0x4F , 0x50 , 0x45 , 0xCE , 0x46 , 0x49 , 0x4C , 0x45 , 0x20 , 0x4E , 0x4F , 0x54 , 0x20 , 0x46 , 0x4F , 0x55 , 0x4E , 0xC4 , 0x44 , 0x45 , 0x56 , 0x49 , 0x43 , 0x45 , 0x20 , 0x4E , 0x4F , 0x54 , 0x20 , 0x50 , 0x52 , 0x45 , 0x53 , 0x45 , 0x4E , 0xD4 , 0x4E , 0x4F , 0x54 , 0x20 , 0x49 , 0x4E , 0x50 , 0x55 , 0x54 , 0x20 , 0x46 , 0x49 , 0x4C , 0xC5 , 0x4E , 0x4F , 0x54 , 0x20 , 0x4F , 0x55 , 0x54 , 0x50 , 0x55 , 0x54 , 0x20 , 0x46 , 0x49 , 0x4C , 0xC5 , 0x4D , 0x49 , 0x53 , 0x53 , 0x49 , 0x4E , 0x47 , 0x20 , 0x46 , 0x49 , 0x4C , 0x45 , 0x20 , 0x4E , 0x41 , 0x4D , 0xC5 , 0x49 , 0x4C , 0x4C , 0x45 , 0x47 , 0x41 , 0x4C , 0x20 , 0x44 , 0x45 , 0x56 , 0x49 , 0x43 , 0x45 , 0x20 , 0x4E , 0x55 , 0x4D , 0x42 , 0x45 , 0xD2 , 0x4E , 0x45 , 0x58 , 0x54 , 0x20 , 0x57 , 0x49 , 0x54 , 0x48 , 0x4F , 0x55 , 0x54 , 0x20 , 0x46 , 0x4F , 0xD2 , 0x53 , 0x59 , 0x4E , 0x54 , 0x41 , 0xD8 , 0x52 , 0x45 , 0x54 , 0x55 , 0x52 , 0x4E , 0x20 , 0x57 , 0x49 , 0x54 , 0x48 , 0x4F , 0x55 , 0x54 , 0x20 , 0x47 , 0x4F , 0x53 , 0x55 , 0xC2 , 0x4F , 0x55 , 0x54 , 0x20 , 0x4F , 0x46 , 0x20 , 0x44 , 0x41 , 0x54 , 0xC1 , 0x49 , 0x4C , 0x4C , 0x45 , 0x47 , 0x41 , 0x4C , 0x20 , 0x51 , 0x55 , 0x41 , 0x4E , 0x54 , 0x49 , 0x54 , 0xD9 , 0x4F , 0x56 , 0x45 , 0x52 , 0x46 , 0x4C , 0x4F , 0xD7 , 0x4F , 0x55 , 0x54 , 0x20 , 0x4F , 0x46 , 0x20 , 0x4D , 0x45 , 0x4D , 0x4F , 0x52 , 0xD9 , 0x55 , 0x4E , 0x44 , 0x45 , 0x46 , 0x27 , 0x44 , 0x20 , 0x53 , 0x54 , 0x41 , 0x54 , 0x45 , 0x4D , 0x45 , 0x4E , 0xD4 , 0x42 , 0x41 , 0x44 , 0x20 , 0x53 , 0x55 , 0x42 , 0x53 , 0x43 , 0x52 , 0x49 , 0x50 , 0xD4 , 0x52 , 0x45 , 0x44 , 0x49 , 0x4D , 0x27 , 0x44 , 0x20 , 0x41 , 0x52 , 0x52 , 0x41 , 0xD9 , 0x44 , 0x49 , 0x56 , 0x49 , 0x53 , 0x49 , 0x4F , 0x4E , 0x20 , 0x42 , 0x59 , 0x20 , 0x5A , 0x45 , 0x52 , 0xCF , 0x49 , 0x4C , 0x4C , 0x45 , 0x47 , 0x41 , 0x4C , 0x20 , 0x44 , 0x49 , 0x52 , 0x45 , 0x43 , 0xD4 , 0x54 , 0x59 , 0x50 , 0x45 , 0x20 , 0x4D , 0x49 , 0x53 , 0x4D , 0x41 , 0x54 , 0x43 , 0xC8 , 0x53 , 0x54 , 0x52 , 0x49 , 0x4E , 0x47 , 0x20 , 0x54 , 0x4F , 0x4F , 0x20 , 0x4C , 0x4F , 0x4E , 0xC7 , 0x46 , 0x49 , 0x4C , 0x45 , 0x20 , 0x44 , 0x41 , 0x54 , 0xC1 , 0x46 , 0x4F , 0x52 , 0x4D , 0x55 , 0x4C , 0x41 , 0x20 , 0x54 , 0x4F , 0x4F , 0x20 , 0x43 , 0x4F , 0x4D , 0x50 , 0x4C , 0x45 , 0xD8 , 0x43 , 0x41 , 0x4E , 0x27 , 0x54 , 0x20 , 0x43 , 0x4F , 0x4E , 0x54 , 0x49 , 0x4E , 0x55 , 0xC5 , 0x55 , 0x4E , 0x44 , 0x45 , 0x46 , 0x27 , 0x44 , 0x20 , 0x46 , 0x55 , 0x4E , 0x43 , 0x54 , 0x49 , 0x4F , 0xCE , 0x56 , 0x45 , 0x52 , 0x49 , 0x46 , 0xD9 , 0x4C , 0x4F , 0x41 , 0xC4 , 0x9E , 0xC1 , 0xAC , 0xC1 , 0xB5 , 0xC1 , 0xC2 , 0xC1 , 0xD0 , 0xC1 , 0xE2 , 0xC1 , 0xF0 , 0xC1 , 0xFF , 0xC1 , 0x10 , 0xC2 , 0x25 , 0xC2 , 0x35 , 0xC2 , 0x3B , 0xC2 , 0x4F , 0xC2 , 0x5A , 0xC2 , 0x6A , 0xC2 , 0x72 , 0xC2 , 0x7F , 0xC2 , 0x90 , 0xC2 , 0x9D , 0xC2 , 0xAA , 0xC2 , 0xBA , 0xC2 , 0xC8 , 0xC2 , 0xD5 , 0xC2 , 0xE4 , 0xC2 , 0xED , 0xC2 , 0x0 , 0xC3 , 0xE , 0xC3 , 0x1E , 0xC3 , 0x24 , 0xC3 , 0x83 , 0xC3 , 0xD , 0x4F , 0x4B , 0xD , 0x0 , 0xD , 0x20 , 0x45 , 0x52 , 0x52 , 0x4F , 0x52 , 0x0 , 0x20 , 0x49 , 0x4E , 0x20 , 0x0 , 0xD , 0xA , 0x52 , 0x45 , 0x41 , 0x44 , 0x59 , 0x2E , 0xD , 0xA , 0x0 , 0xD , 0xA , 0x42 , 0x52 , 0x45 , 0x41 , 0x4B , 0x0 , 0xA0 , 0xBA , 0xE8 , 0xE8 , 0xE8 , 0xE8 , 0xBD , 0x1 , 0x1 , 0xC9 , 0x81 , 0xD0 , 0x21 , 0xA5 , 0x4A , 0xD0 , 0xA , 0xBD , 0x2 , 0x1 , 0x85 , 0x49 , 0xBD , 0x3 , 0x1 , 0x85 , 0x4A , 0xDD , 0x3 , 0x1 , 0xD0 , 0x7 , 0xA5 , 0x49 , 0xDD , 0x2 , 0x1 , 0xF0 , 0x7 , 0x8A , 0x18 , 0x69 , 0x12 , 0xAA , 0xD0 , 0xD8 , 0x60 , 0x20 , 0x8 , 0xC4 , 0x85 , 0x31 , 0x84 , 0x32 , 0x38 , 0xA5 , 0x5A , 0xE5 , 0x5F , 0x85 , 0x22 , 0xA8 , 0xA5 , 0x5B , 0xE5 , 0x60 , 0xAA , 0xE8 , 0x98 , 0xF0 , 0x23 , 0xA5 , 0x5A , 0x38 , 0xE5 , 0x22 , 0x85 , 0x5A , 0xB0 , 0x3 , 0xC6 , 0x5B , 0x38 , 0xA5 , 0x58 , 0xE5 , 0x22 , 0x85 , 0x58 , 0xB0 , 0x8 , 0xC6 , 0x59 , 0x90 , 0x4 , 0xB1 , 0x5A , 0x91 , 0x58 , 0x88 , 0xD0 , 0xF9 , 0xB1 , 0x5A , 0x91 , 0x58 , 0xC6 , 0x5B , 0xC6 , 0x59 , 0xCA , 0xD0 , 0xF2 , 0x60 , 0xA , 0x69 , 0x3E , 0xB0 , 0x35 , 0x85 , 0x22 , 0xBA , 0xE4 , 0x22 , 0x90 , 0x2E , 0x60 , 0xC4 , 0x34 , 0x90 , 0x28 , 0xD0 , 0x4 , 0xC5 , 0x33 , 0x90 , 0x22 , 0x48 , 0xA2 , 0x9 , 0x98 , 0x48 , 0xB5 , 0x57 , 0xCA , 0x10 , 0xFA , 0x20 , 0x26 , 0xD5 , 0xA2 , 0xF7 , 0x68 , 0x95 , 0x61 , 0xE8 , 0x30 , 0xFA , 0x68 , 0xA8 , 0x68 , 0xC4 , 0x34 , 0x90 , 0x6 , 0xD0 , 0x5 , 0xC5 , 0x33 , 0xB0 , 0x1 , 0x60 , 0xA2 , 0x10 , 0x6C , 0x0 , 0x3 , 0x8A , 0xA , 0xAA , 0xBD , 0x26 , 0xC3 , 0x85 , 0x22 , 0xBD , 0x27 , 0xC3 , 0x85 , 0x23 , 0x20 , 0xCC , 0xFF , 0xA9 , 0x0 , 0x85 , 0x13 , 0x20 , 0xD7 , 0xCA , 0x20 , 0x45 , 0xCB , 0xA0 , 0x0 , 0xB1 , 0x22 , 0x48 , 0x29 , 0x7F , 0x20 , 0x47 , 0xCB , 0xC8 , 0x68 , 0x10 , 0xF4 , 0x20 , 0x7A , 0xC6 , 0xA9 , 0x69 , 0xA0 , 0xC3 , 0x20 , 0x1E , 0xCB , 0xA4 , 0x3A , 0xC8 , 0xF0 , 0x3 , 0x20 , 0xC2 , 0xDD , 0xA9 , 0x76 , 0xA0 , 0xC3 , 0x20 , 0x1E , 0xCB , 0xA9 , 0x80 , 0x20 , 0x90 , 0xFF , 0x6C , 0x2 , 0x3 , 0x20 , 0x60 , 0xC5 , 0x86 , 0x7A , 0x84 , 0x7B , 0x20 , 0x73 , 0x0 , 0xAA , 0xF0 , 0xF0 , 0xA2 , 0xFF , 0x86 , 0x3A , 0x90 , 0x6 , 0x20 , 0x79 , 0xC5 , 0x4C , 0xE1 , 0xC7 , 0x20 , 0x6B , 0xC9 , 0x20 , 0x79 , 0xC5 , 0x84 , 0xB , 0x20 , 0x13 , 0xC6 , 0x90 , 0x44 , 0xA0 , 0x1 , 0xB1 , 0x5F , 0x85 , 0x23 , 0xA5 , 0x2D , 0x85 , 0x22 , 0xA5 , 0x60 , 0x85 , 0x25 , 0xA5 , 0x5F , 0x88 , 0xF1 , 0x5F , 0x18 , 0x65 , 0x2D , 0x85 , 0x2D , 0x85 , 0x24 , 0xA5 , 0x2E , 0x69 , 0xFF , 0x85 , 0x2E , 0xE5 , 0x60 , 0xAA , 0x38 , 0xA5 , 0x5F , 0xE5 , 0x2D , 0xA8 , 0xB0 , 0x3 , 0xE8 , 0xC6 , 0x25 , 0x18 , 0x65 , 0x22 , 0x90 , 0x3 , 0xC6 , 0x23 , 0x18 , 0xB1 , 0x22 , 0x91 , 0x24 , 0xC8 , 0xD0 , 0xF9 , 0xE6 , 0x23 , 0xE6 , 0x25 , 0xCA , 0xD0 , 0xF2 , 0x20 , 0x59 , 0xC6 , 0x20 , 0x33 , 0xC5 , 0xAD , 0x0 , 0x2 , 0xF0 , 0x88 , 0x18 , 0xA5 , 0x2D , 0x85 , 0x5A , 0x65 , 0xB , 0x85 , 0x58 , 0xA4 , 0x2E , 0x84 , 0x5B , 0x90 , 0x1 , 0xC8 , 0x84 , 0x59 , 0x20 , 0xB8 , 0xC3 , 0xA5 , 0x14 , 0xA4 , 0x15 , 0x8D , 0xFE , 0x1 , 0x8C , 0xFF , 0x1 , 0xA5 , 0x31 , 0xA4 , 0x32 , 0x85 , 0x2D , 0x84 , 0x2E , 0xA4 , 0xB , 0x88 , 0xB9 , 0xFC , 0x1 , 0x91 , 0x5F , 0x88 , 0x10 , 0xF8 , 0x20 , 0x59 , 0xC6 , 0x20 , 0x33 , 0xC5 , 0x4C , 0x80 , 0xC4 , 0xA5 , 0x2B , 0xA4 , 0x2C , 0x85 , 0x22 , 0x84 , 0x23 , 0x18 , 0xA0 , 0x1 , 0xB1 , 0x22 , 0xF0 , 0x1D , 0xA0 , 0x4 , 0xC8 , 0xB1 , 0x22 , 0xD0 , 0xFB , 0xC8 , 0x98 , 0x65 , 0x22 , 0xAA , 0xA0 , 0x0 , 0x91 , 0x22 , 0xA5 , 0x23 , 0x69 , 0x0 , 0xC8 , 0x91 , 0x22 , 0x86 , 0x22 , 0x85 , 0x23 , 0x90 , 0xDD , 0x60 , 0xA2 , 0x0 , 0x20 , 0xF , 0xE1 , 0xC9 , 0xD , 0xF0 , 0xD , 0x9D , 0x0 , 0x2 , 0xE8 , 0xE0 , 0x59 , 0x90 , 0xF1 , 0xA2 , 0x17 , 0x4C , 0x37 , 0xC4 , 0x4C , 0xCA , 0xCA , 0x6C , 0x4 , 0x3 , 0xA6 , 0x7A , 0xA0 , 0x4 , 0x84 , 0xF , 0xBD , 0x0 , 0x2 , 0x10 , 0x7 , 0xC9 , 0xFF , 0xF0 , 0x3E , 0xE8 , 0xD0 , 0xF4 , 0xC9 , 0x20 , 0xF0 , 0x37 , 0x85 , 0x8 , 0xC9 , 0x22 , 0xF0 , 0x56 , 0x24 , 0xF , 0x70 , 0x2D , 0xC9 , 0x3F , 0xD0 , 0x4 , 0xA9 , 0x99 , 0xD0 , 0x25 , 0xC9 , 0x30 , 0x90 , 0x4 , 0xC9 , 0x3C , 0x90 , 0x1D , 0x84 , 0x71 , 0xA0 , 0x0 , 0x84 , 0xB , 0x88 , 0x86 , 0x7A , 0xCA , 0xC8 , 0xE8 , 0xBD , 0x0 , 0x2 , 0x38 , 0xF9 , 0x9E , 0xC0 , 0xF0 , 0xF5 , 0xC9 , 0x80 , 0xD0 , 0x30 , 0x5 , 0xB , 0xA4 , 0x71 , 0xE8 , 0xC8 , 0x99 , 0xFB , 0x1 , 0xB9 , 0xFB , 0x1 , 0xF0 , 0x36 , 0x38 , 0xE9 , 0x3A , 0xF0 , 0x4 , 0xC9 , 0x49 , 0xD0 , 0x2 , 0x85 , 0xF , 0x38 , 0xE9 , 0x55 , 0xD0 , 0x9F , 0x85 , 0x8 , 0xBD , 0x0 , 0x2 , 0xF0 , 0xDF , 0xC5 , 0x8 , 0xF0 , 0xDB , 0xC8 , 0x99 , 0xFB , 0x1 , 0xE8 , 0xD0 , 0xF0 , 0xA6 , 0x7A , 0xE6 , 0xB , 0xC8 , 0xB9 , 0x9D , 0xC0 , 0x10 , 0xFA , 0xB9 , 0x9E , 0xC0 , 0xD0 , 0xB4 , 0xBD , 0x0 , 0x2 , 0x10 , 0xBE , 0x99 , 0xFD , 0x1 , 0xC6 , 0x7B , 0xA9 , 0xFF , 0x85 , 0x7A , 0x60 , 0xA5 , 0x2B , 0xA6 , 0x2C , 0xA0 , 0x1 , 0x85 , 0x5F , 0x86 , 0x60 , 0xB1 , 0x5F , 0xF0 , 0x1F , 0xC8 , 0xC8 , 0xA5 , 0x15 , 0xD1 , 0x5F , 0x90 , 0x18 , 0xF0 , 0x3 , 0x88 , 0xD0 , 0x9 , 0xA5 , 0x14 , 0x88 , 0xD1 , 0x5F , 0x90 , 0xC , 0xF0 , 0xA , 0x88 , 0xB1 , 0x5F , 0xAA , 0x88 , 0xB1 , 0x5F , 0xB0 , 0xD7 , 0x18 , 0x60 , 0xD0 , 0xFD , 0xA9 , 0x0 , 0xA8 , 0x91 , 0x2B , 0xC8 , 0x91 , 0x2B , 0xA5 , 0x2B , 0x18 , 0x69 , 0x2 , 0x85 , 0x2D , 0xA5 , 0x2C , 0x69 , 0x0 , 0x85 , 0x2E , 0x20 , 0x8E , 0xC6 , 0xA9 , 0x0 , 0xD0 , 0x2D , 0x20 , 0xE7 , 0xFF , 0xA5 , 0x37 , 0xA4 , 0x38 , 0x85 , 0x33 , 0x84 , 0x34 , 0xA5 , 0x2D , 0xA4 , 0x2E , 0x85 , 0x2F , 0x84 , 0x30 , 0x85 , 0x31 , 0x84 , 0x32 , 0x20 , 0x1D , 0xC8 , 0xA2 , 0x19 , 0x86 , 0x16 , 0x68 , 0xA8 , 0x68 , 0xA2 , 0xFA , 0x9A , 0x48 , 0x98 , 0x48 , 0xA9 , 0x0 , 0x85 , 0x3E , 0x85 , 0x10 , 0x60 , 0x18 , 0xA5 , 0x2B , 0x69 , 0xFF , 0x85 , 0x7A , 0xA5 , 0x2C , 0x69 , 0xFF , 0x85 , 0x7B , 0x60 , 0x90 , 0x6 , 0xF0 , 0x4 , 0xC9 , 0xAB , 0xD0 , 0xE9 , 0x20 , 0x6B , 0xC9 , 0x20 , 0x13 , 0xC6 , 0x20 , 0x79 , 0x0 , 0xF0 , 0xC , 0xC9 , 0xAB , 0xD0 , 0x8E , 0x20 , 0x73 , 0x0 , 0x20 , 0x6B , 0xC9 , 0xD0 , 0x86 , 0x68 , 0x68 , 0xA5 , 0x14 , 0x5 , 0x15 , 0xD0 , 0x6 , 0xA9 , 0xFF , 0x85 , 0x14 , 0x85 , 0x15 , 0xA0 , 0x1 , 0x84 , 0xF , 0xB1 , 0x5F , 0xF0 , 0x43 , 0x20 , 0x2C , 0xC8 , 0x20 , 0xD7 , 0xCA , 0xC8 , 0xB1 , 0x5F , 0xAA , 0xC8 , 0xB1 , 0x5F , 0xC5 , 0x15 , 0xD0 , 0x4 , 0xE4 , 0x14 , 0xF0 , 0x2 , 0xB0 , 0x2C , 0x84 , 0x49 , 0x20 , 0xCD , 0xDD , 0xA9 , 0x20 , 0xA4 , 0x49 , 0x29 , 0x7F , 0x20 , 0x47 , 0xCB , 0xC9 , 0x22 , 0xD0 , 0x6 , 0xA5 , 0xF , 0x49 , 0xFF , 0x85 , 0xF , 0xC8 , 0xF0 , 0x11 , 0xB1 , 0x5F , 0xD0 , 0x10 , 0xA8 , 0xB1 , 0x5F , 0xAA , 0xC8 , 0xB1 , 0x5F , 0x86 , 0x5F , 0x85 , 0x60 , 0xD0 , 0xB5 , 0x4C , 0x74 , 0xC4 , 0x6C , 0x6 , 0x3 , 0x10 , 0xD7 , 0xC9 , 0xFF , 0xF0 , 0xD3 , 0x24 , 0xF , 0x30 , 0xCF , 0x38 , 0xE9 , 0x7F , 0xAA , 0x84 , 0x49 , 0xA0 , 0xFF , 0xCA , 0xF0 , 0x8 , 0xC8 , 0xB9 , 0x9E , 0xC0 , 0x10 , 0xFA , 0x30 , 0xF5 , 0xC8 , 0xB9 , 0x9E , 0xC0 , 0x30 , 0xB2 , 0x20 , 0x47 , 0xCB , 0xD0 , 0xF5 , 0xA9 , 0x80 , 0x85 , 0x10 , 0x20 , 0xA5 , 0xC9 , 0x20 , 0x8A , 0xC3 , 0xD0 , 0x5 , 0x8A , 0x69 , 0xF , 0xAA , 0x9A , 0x68 , 0x68 , 0xA9 , 0x9 , 0x20 , 0xFB , 0xC3 , 0x20 , 0x6 , 0xC9 , 0x18 , 0x98 , 0x65 , 0x7A , 0x48 , 0xA5 , 0x7B , 0x69 , 0x0 , 0x48 , 0xA5 , 0x3A , 0x48 , 0xA5 , 0x39 , 0x48 , 0xA9 , 0xA4 , 0x20 , 0xFF , 0xCE , 0x20 , 0x8D , 0xCD , 0x20 , 0x8A , 0xCD , 0xA5 , 0x66 , 0x9 , 0x7F , 0x25 , 0x62 , 0x85 , 0x62 , 0xA9 , 0x8B , 0xA0 , 0xC7 , 0x85 , 0x22 , 0x84 , 0x23 , 0x4C , 0x43 , 0xCE , 0xA9 , 0xBC , 0xA0 , 0xD9 , 0x20 , 0xA2 , 0xDB , 0x20 , 0x79 , 0x0 , 0xC9 , 0xA9 , 0xD0 , 0x6 , 0x20 , 0x73 , 0x0 , 0x20 , 0x8A , 0xCD , 0x20 , 0x2B , 0xDC , 0x20 , 0x38 , 0xCE , 0xA5 , 0x4A , 0x48 , 0xA5 , 0x49 , 0x48 , 0xA9 , 0x81 , 0x48 , 0x20 , 0x2C , 0xC8 , 0xA5 , 0x7A , 0xA4 , 0x7B , 0xC0 , 0x2 , 0xEA , 0xF0 , 0x4 , 0x85 , 0x3D , 0x84 , 0x3E , 0xA0 , 0x0 , 0xB1 , 0x7A , 0xD0 , 0x43 , 0xA0 , 0x2 , 0xB1 , 0x7A , 0x18 , 0xD0 , 0x3 , 0x4C , 0x4B , 0xC8 , 0xC8 , 0xB1 , 0x7A , 0x85 , 0x39 , 0xC8 , 0xB1 , 0x7A , 0x85 , 0x3A , 0x98 , 0x65 , 0x7A , 0x85 , 0x7A , 0x90 , 0x2 , 0xE6 , 0x7B , 0x6C , 0x8 , 0x3 , 0x20 , 0x73 , 0x0 , 0x20 , 0xED , 0xC7 , 0x4C , 0xAE , 0xC7 , 0xF0 , 0x3C , 0xE9 , 0x80 , 0x90 , 0x11 , 0xC9 , 0x23 , 0xB0 , 0x17 , 0xA , 0xA8 , 0xB9 , 0xD , 0xC0 , 0x48 , 0xB9 , 0xC , 0xC0 , 0x48 , 0x4C , 0x73 , 0x0 , 0x4C , 0xA5 , 0xC9 , 0xC9 , 0x3A , 0xF0 , 0xD6 , 0x4C , 0x8 , 0xCF , 0xC9 , 0x4B , 0xD0 , 0xF9 , 0x20 , 0x73 , 0x0 , 0xA9 , 0xA4 , 0x20 , 0xFF , 0xCE , 0x4C , 0xA0 , 0xC8 , 0x38 , 0xA5 , 0x2B , 0xE9 , 0x1 , 0xA4 , 0x2C , 0xB0 , 0x1 , 0x88 , 0x85 , 0x41 , 0x84 , 0x42 , 0x60 , 0x20 , 0xE1 , 0xFF , 0xB0 , 0x1 , 0x18 , 0xD0 , 0x3C , 0xA5 , 0x7A , 0xA4 , 0x7B , 0xA6 , 0x3A , 0xE8 , 0xF0 , 0xC , 0x85 , 0x3D , 0x84 , 0x3E , 0xA5 , 0x39 , 0xA4 , 0x3A , 0x85 , 0x3B , 0x84 , 0x3C , 0x68 , 0x68 , 0xA9 , 0x81 , 0xA0 , 0xC3 , 0x90 , 0x3 , 0x4C , 0x69 , 0xC4 , 0x4C , 0x74 , 0xC4 , 0xD0 , 0x17 , 0xA2 , 0x1A , 0xA4 , 0x3E , 0xD0 , 0x3 , 0x4C , 0x37 , 0xC4 , 0xA5 , 0x3D , 0x85 , 0x7A , 0x84 , 0x7B , 0xA5 , 0x3B , 0xA4 , 0x3C , 0x85 , 0x39 , 0x84 , 0x3A , 0x60 , 0x8 , 0xA9 , 0x0 , 0x20 , 0x90 , 0xFF , 0x28 , 0xD0 , 0x3 , 0x4C , 0x59 , 0xC6 , 0x20 , 0x60 , 0xC6 , 0x4C , 0x97 , 0xC8 , 0xA9 , 0x3 , 0x20 , 0xFB , 0xC3 , 0xA5 , 0x7B , 0x48 , 0xA5 , 0x7A , 0x48 , 0xA5 , 0x3A , 0x48 , 0xA5 , 0x39 , 0x48 , 0xA9 , 0x8D , 0x48 , 0x20 , 0x79 , 0x0 , 0x20 , 0xA0 , 0xC8 , 0x4C , 0xAE , 0xC7 , 0x20 , 0x6B , 0xC9 , 0x20 , 0x9 , 0xC9 , 0x38 , 0xA5 , 0x39 , 0xE5 , 0x14 , 0xA5 , 0x3A , 0xE5 , 0x15 , 0xB0 , 0xB , 0x98 , 0x38 , 0x65 , 0x7A , 0xA6 , 0x7B , 0x90 , 0x7 , 0xE8 , 0xB0 , 0x4 , 0xA5 , 0x2B , 0xA6 , 0x2C , 0x20 , 0x17 , 0xC6 , 0x90 , 0x1E , 0xA5 , 0x5F , 0xE9 , 0x1 , 0x85 , 0x7A , 0xA5 , 0x60 , 0xE9 , 0x0 , 0x85 , 0x7B , 0x60 , 0xD0 , 0xFD , 0xA9 , 0xFF , 0x85 , 0x4A , 0x20 , 0x8A , 0xC3 , 0x9A , 0xC9 , 0x8D , 0xF0 , 0xB , 0xA2 , 0xC , 0x2C , 0xA2 , 0x11 , 0x4C , 0x37 , 0xC4 , 0x4C , 0x8 , 0xCF , 0x68 , 0x68 , 0x85 , 0x39 , 0x68 , 0x85 , 0x3A , 0x68 , 0x85 , 0x7A , 0x68 , 0x85 , 0x7B , 0x20 , 0x6 , 0xC9 , 0x98 , 0x18 , 0x65 , 0x7A , 0x85 , 0x7A , 0x90 , 0x2 , 0xE6 , 0x7B , 0x60 , 0xA2 , 0x3A , 0x2C , 0xA2 , 0x0 , 0x86 , 0x7 , 0xA0 , 0x0 , 0x84 , 0x8 , 0xA5 , 0x8 , 0xA6 , 0x7 , 0x85 , 0x7 , 0x86 , 0x8 , 0xB1 , 0x7A , 0xF0 , 0xE8 , 0xC5 , 0x8 , 0xF0 , 0xE4 , 0xC8 , 0xC9 , 0x22 , 0xD0 , 0xF3 , 0xF0 , 0xE9 , 0x20 , 0x9E , 0xCD , 0x20 , 0x79 , 0x0 , 0xC9 , 0x89 , 0xF0 , 0x5 , 0xA9 , 0xA7 , 0x20 , 0xFF , 0xCE , 0xA5 , 0x61 , 0xD0 , 0x5 , 0x20 , 0x9 , 0xC9 , 0xF0 , 0xBB , 0x20 , 0x79 , 0x0 , 0xB0 , 0x3 , 0x4C , 0xA0 , 0xC8 , 0x4C , 0xED , 0xC7 , 0x20 , 0x9E , 0xD7 , 0x48 , 0xC9 , 0x8D , 0xF0 , 0x4 , 0xC9 , 0x89 , 0xD0 , 0x91 , 0xC6 , 0x65 , 0xD0 , 0x4 , 0x68 , 0x4C , 0xEF , 0xC7 , 0x20 , 0x73 , 0x0 , 0x20 , 0x6B , 0xC9 , 0xC9 , 0x2C , 0xF0 , 0xEE , 0x68 , 0x60 , 0xA2 , 0x0 , 0x86 , 0x14 , 0x86 , 0x15 , 0xB0 , 0xF7 , 0xE9 , 0x2F , 0x85 , 0x7 , 0xA5 , 0x15 , 0x85 , 0x22 , 0xC9 , 0x19 , 0xB0 , 0xD4 , 0xA5 , 0x14 , 0xA , 0x26 , 0x22 , 0xA , 0x26 , 0x22 , 0x65 , 0x14 , 0x85 , 0x14 , 0xA5 , 0x22 , 0x65 , 0x15 , 0x85 , 0x15 , 0x6 , 0x14 , 0x26 , 0x15 , 0xA5 , 0x14 , 0x65 , 0x7 , 0x85 , 0x14 , 0x90 , 0x2 , 0xE6 , 0x15 , 0x20 , 0x73 , 0x0 , 0x4C , 0x71 , 0xC9 , 0x20 , 0x8B , 0xD0 , 0x85 , 0x49 , 0x84 , 0x4A , 0xA9 , 0xB2 , 0x20 , 0xFF , 0xCE , 0xA5 , 0xE , 0x48 , 0xA5 , 0xD , 0x48 , 0x20 , 0x9E , 0xCD , 0x68 , 0x2A , 0x20 , 0x90 , 0xCD , 0xD0 , 0x18 , 0x68 , 0x10 , 0x12 , 0x20 , 0x1B , 0xDC , 0x20 , 0xBF , 0xD1 , 0xA0 , 0x0 , 0xA5 , 0x64 , 0x91 , 0x49 , 0xC8 , 0xA5 , 0x65 , 0x91 , 0x49 , 0x60 , 0x4C , 0xD0 , 0xDB , 0x68 , 0xA4 , 0x4A , 0xC0 , 0xDF , 0xD0 , 0x4C , 0x20 , 0xA6 , 0xD6 , 0xC9 , 0x6 , 0xD0 , 0x3D , 0xA0 , 0x0 , 0x84 , 0x61 , 0x84 , 0x66 , 0x84 , 0x71 , 0x20 , 0x1D , 0xCA , 0x20 , 0xE2 , 0xDA , 0xE6 , 0x71 , 0xA4 , 0x71 , 0x20 , 0x1D , 0xCA , 0x20 , 0xC , 0xDC , 0xAA , 0xF0 , 0x5 , 0xE8 , 0x8A , 0x20 , 0xED , 0xDA , 0xA4 , 0x71 , 0xC8 , 0xC0 , 0x6 , 0xD0 , 0xDF , 0x20 , 0xE2 , 0xDA , 0x20 , 0x9B , 0xDC , 0xA6 , 0x64 , 0xA4 , 0x63 , 0xA5 , 0x65 , 0x4C , 0xDB , 0xFF , 0xB1 , 0x22 , 0x20 , 0x80 , 0x0 , 0x90 , 0x3 , 0x4C , 0x48 , 0xD2 , 0xE9 , 0x2F , 0x4C , 0x7E , 0xDD , 0xA0 , 0x2 , 0xB1 , 0x64 , 0xC5 , 0x34 , 0x90 , 0x17 , 0xD0 , 0x7 , 0x88 , 0xB1 , 0x64 , 0xC5 , 0x33 , 0x90 , 0xE , 0xA4 , 0x65 , 0xC4 , 0x2E , 0x90 , 0x8 , 0xD0 , 0xD , 0xA5 , 0x64 , 0xC5 , 0x2D , 0xB0 , 0x7 , 0xA5 , 0x64 , 0xA4 , 0x65 , 0x4C , 0x68 , 0xCA , 0xA0 , 0x0 , 0xB1 , 0x64 , 0x20 , 0x75 , 0xD4 , 0xA5 , 0x50 , 0xA4 , 0x51 , 0x85 , 0x6F , 0x84 , 0x70 , 0x20 , 0x7A , 0xD6 , 0xA9 , 0x61 , 0xA0 , 0x0 , 0x85 , 0x50 , 0x84 , 0x51 , 0x20 , 0xDB , 0xD6 , 0xA0 , 0x0 , 0xB1 , 0x50 , 0x91 , 0x49 , 0xC8 , 0xB1 , 0x50 , 0x91 , 0x49 , 0xC8 , 0xB1 , 0x50 , 0x91 , 0x49 , 0x60 , 0x20 , 0x86 , 0xCA , 0x4C , 0xB5 , 0xCB , 0x20 , 0x9E , 0xD7 , 0xF0 , 0x5 , 0xA9 , 0x2C , 0x20 , 0xFF , 0xCE , 0x8 , 0x86 , 0x13 , 0x20 , 0x15 , 0xE1 , 0x28 , 0x4C , 0xA0 , 0xCA , 0x20 , 0x21 , 0xCB , 0x20 , 0x79 , 0x0 , 0xF0 , 0x35 , 0xF0 , 0x43 , 0xC9 , 0xA3 , 0xF0 , 0x50 , 0xC9 , 0xA6 , 0x18 , 0xF0 , 0x4B , 0xC9 , 0x2C , 0xF0 , 0x37 , 0xC9 , 0x3B , 0xF0 , 0x5E , 0x20 , 0x9E , 0xCD , 0x24 , 0xD , 0x30 , 0xDE , 0x20 , 0xDD , 0xDD , 0x20 , 0x87 , 0xD4 , 0x20 , 0x21 , 0xCB , 0x20 , 0x3B , 0xCB , 0xD0 , 0xD3 , 0xA9 , 0x0 , 0x9D , 0x0 , 0x2 , 0xA2 , 0xFF , 0xA0 , 0x1 , 0xA5 , 0x13 , 0xD0 , 0x10 , 0xA9 , 0xD , 0x20 , 0x47 , 0xCB , 0x24 , 0x13 , 0x10 , 0x5 , 0xA9 , 0xA , 0x20 , 0x47 , 0xCB , 0x49 , 0xFF , 0x60 , 0x38 , 0x20 , 0xF0 , 0xFF , 0x98 , 0x38 , 0xE9 , 0xB , 0xB0 , 0xFC , 0x49 , 0xFF , 0x69 , 0x1 , 0xD0 , 0x16 , 0x8 , 0x38 , 0x20 , 0xF0 , 0xFF , 0x84 , 0x9 , 0x20 , 0x9B , 0xD7 , 0xC9 , 0x29 , 0xD0 , 0x59 , 0x28 , 0x90 , 0x6 , 0x8A , 0xE5 , 0x9 , 0x90 , 0x5 , 0xAA , 0xE8 , 0xCA , 0xD0 , 0x6 , 0x20 , 0x73 , 0x0 , 0x4C , 0xA2 , 0xCA , 0x20 , 0x3B , 0xCB , 0xD0 , 0xF2 , 0x20 , 0x87 , 0xD4 , 0x20 , 0xA6 , 0xD6 , 0xAA , 0xA0 , 0x0 , 0xE8 , 0xCA , 0xF0 , 0xBC , 0xB1 , 0x22 , 0x20 , 0x47 , 0xCB , 0xC8 , 0xC9 , 0xD , 0xD0 , 0xF3 , 0x20 , 0xE5 , 0xCA , 0x4C , 0x28 , 0xCB , 0xA5 , 0x13 , 0xF0 , 0x3 , 0xA9 , 0x20 , 0x2C , 0xA9 , 0x1D , 0x2C , 0xA9 , 0x3F , 0x20 , 0x9 , 0xE1 , 0x29 , 0xFF , 0x60 , 0xA5 , 0x11 , 0xF0 , 0x11 , 0x30 , 0x4 , 0xA0 , 0xFF , 0xD0 , 0x4 , 0xA5 , 0x3F , 0xA4 , 0x40 , 0x85 , 0x39 , 0x84 , 0x3A , 0x4C , 0x8 , 0xCF , 0xA5 , 0x13 , 0xF0 , 0x5 , 0xA2 , 0x18 , 0x4C , 0x37 , 0xC4 , 0xA9 , 0xC , 0xA0 , 0xCD , 0x20 , 0x1E , 0xCB , 0xA5 , 0x3D , 0xA4 , 0x3E , 0x85 , 0x7A , 0x84 , 0x7B , 0x60 , 0x20 , 0xA6 , 0xD3 , 0xC9 , 0x23 , 0xD0 , 0x10 , 0x20 , 0x73 , 0x0 , 0x20 , 0x9E , 0xD7 , 0xA9 , 0x2C , 0x20 , 0xFF , 0xCE , 0x86 , 0x13 , 0x20 , 0x1B , 0xE1 , 0xA2 , 0x1 , 0xA0 , 0x2 , 0xA9 , 0x0 , 0x8D , 0x1 , 0x2 , 0xA9 , 0x40 , 0x20 , 0xF , 0xCC , 0xA6 , 0x13 , 0xD0 , 0x13 , 0x60 , 0x20 , 0x9E , 0xD7 , 0xA9 , 0x2C , 0x20 , 0xFF , 0xCE , 0x86 , 0x13 , 0x20 , 0x1B , 0xE1 , 0x20 , 0xCE , 0xCB , 0xA5 , 0x13 , 0x20 , 0xCC , 0xFF , 0xA2 , 0x0 , 0x86 , 0x13 , 0x60 , 0xC9 , 0x22 , 0xD0 , 0xB , 0x20 , 0xBD , 0xCE , 0xA9 , 0x3B , 0x20 , 0xFF , 0xCE , 0x20 , 0x21 , 0xCB , 0x20 , 0xA6 , 0xD3 , 0xA9 , 0x2C , 0x8D , 0xFF , 0x1 , 0x20 , 0xF9 , 0xCB , 0xA5 , 0x13 , 0xF0 , 0xD , 0x20 , 0xB7 , 0xFF , 0x29 , 0x2 , 0xF0 , 0x6 , 0x20 , 0xB5 , 0xCB , 0x4C , 0xF8 , 0xC8 , 0xAD , 0x0 , 0x2 , 0xD0 , 0x1E , 0xA5 , 0x13 , 0xD0 , 0xE3 , 0x20 , 0x6 , 0xC9 , 0x4C , 0xFB , 0xC8 , 0xA5 , 0x13 , 0xD0 , 0x6 , 0x20 , 0x45 , 0xCB , 0x20 , 0x3B , 0xCB , 0x4C , 0x60 , 0xC5 , 0xA6 , 0x41 , 0xA4 , 0x42 , 0xA9 , 0x98 , 0x2C , 0xA9 , 0x0 , 0x85 , 0x11 , 0x86 , 0x43 , 0x84 , 0x44 , 0x20 , 0x8B , 0xD0 , 0x85 , 0x49 , 0x84 , 0x4A , 0xA5 , 0x7A , 0xA4 , 0x7B , 0x85 , 0x4B , 0x84 , 0x4C , 0xA6 , 0x43 , 0xA4 , 0x44 , 0x86 , 0x7A , 0x84 , 0x7B , 0x20 , 0x79 , 0x0 , 0xD0 , 0x20 , 0x24 , 0x11 , 0x50 , 0xC , 0x20 , 0x21 , 0xE1 , 0x8D , 0x0 , 0x2 , 0xA2 , 0xFF , 0xA0 , 0x1 , 0xD0 , 0xC , 0x30 , 0x75 , 0xA5 , 0x13 , 0xD0 , 0x3 , 0x20 , 0x45 , 0xCB , 0x20 , 0xF9 , 0xCB , 0x86 , 0x7A , 0x84 , 0x7B , 0x20 , 0x73 , 0x0 , 0x24 , 0xD , 0x10 , 0x31 , 0x24 , 0x11 , 0x50 , 0x9 , 0xE8 , 0x86 , 0x7A , 0xA9 , 0x0 , 0x85 , 0x7 , 0xF0 , 0xC , 0x85 , 0x7 , 0xC9 , 0x22 , 0xF0 , 0x7 , 0xA9 , 0x3A , 0x85 , 0x7 , 0xA9 , 0x2C , 0x18 , 0x85 , 0x8 , 0xA5 , 0x7A , 0xA4 , 0x7B , 0x69 , 0x0 , 0x90 , 0x1 , 0xC8 , 0x20 , 0x8D , 0xD4 , 0x20 , 0xE2 , 0xD7 , 0x20 , 0xDA , 0xC9 , 0x4C , 0x91 , 0xCC , 0x20 , 0xF3 , 0xDC , 0xA5 , 0xE , 0x20 , 0xC2 , 0xC9 , 0x20 , 0x79 , 0x0 , 0xF0 , 0x7 , 0xC9 , 0x2C , 0xF0 , 0x3 , 0x4C , 0x4D , 0xCB , 0xA5 , 0x7A , 0xA4 , 0x7B , 0x85 , 0x43 , 0x84 , 0x44 , 0xA5 , 0x4B , 0xA4 , 0x4C , 0x85 , 0x7A , 0x84 , 0x7B , 0x20 , 0x79 , 0x0 , 0xF0 , 0x2D , 0x20 , 0xFD , 0xCE , 0x4C , 0x15 , 0xCC , 0x20 , 0x6 , 0xC9 , 0xC8 , 0xAA , 0xD0 , 0x12 , 0xA2 , 0xD , 0xC8 , 0xB1 , 0x7A , 0xF0 , 0x6C , 0xC8 , 0xB1 , 0x7A , 0x85 , 0x3F , 0xC8 , 0xB1 , 0x7A , 0xC8 , 0x85 , 0x40 , 0x20 , 0xFB , 0xC8 , 0x20 , 0x79 , 0x0 , 0xAA , 0xE0 , 0x83 , 0xD0 , 0xDC , 0x4C , 0x51 , 0xCC , 0xA5 , 0x43 , 0xA4 , 0x44 , 0xA6 , 0x11 , 0x10 , 0x3 , 0x4C , 0x27 , 0xC8 , 0xA0 , 0x0 , 0xB1 , 0x43 , 0xF0 , 0xB , 0xA5 , 0x13 , 0xD0 , 0x7 , 0xA9 , 0xFC , 0xA0 , 0xCC , 0x4C , 0x1E , 0xCB , 0x60 , 0x3F , 0x45 , 0x58 , 0x54 , 0x52 , 0x41 , 0x20 , 0x49 , 0x47 , 0x4E , 0x4F , 0x52 , 0x45 , 0x44 , 0xD , 0x0 , 0x3F , 0x52 , 0x45 , 0x44 , 0x4F , 0x20 , 0x46 , 0x52 , 0x4F , 0x4D , 0x20 , 0x53 , 0x54 , 0x41 , 0x52 , 0x54 , 0xD , 0x0 , 0xD0 , 0x4 , 0xA0 , 0x0 , 0xF0 , 0x3 , 0x20 , 0x8B , 0xD0 , 0x85 , 0x49 , 0x84 , 0x4A , 0x20 , 0x8A , 0xC3 , 0xF0 , 0x5 , 0xA2 , 0xA , 0x4C , 0x37 , 0xC4 , 0x9A , 0x8A , 0x18 , 0x69 , 0x4 , 0x48 , 0x69 , 0x6 , 0x85 , 0x24 , 0x68 , 0xA0 , 0x1 , 0x20 , 0xA2 , 0xDB , 0xBA , 0xBD , 0x9 , 0x1 , 0x85 , 0x66 , 0xA5 , 0x49 , 0xA4 , 0x4A , 0x20 , 0x67 , 0xD8 , 0x20 , 0xD0 , 0xDB , 0xA0 , 0x1 , 0x20 , 0x5D , 0xDC , 0xBA , 0x38 , 0xFD , 0x9 , 0x1 , 0xF0 , 0x17 , 0xBD , 0xF , 0x1 , 0x85 , 0x39 , 0xBD , 0x10 , 0x1 , 0x85 , 0x3A , 0xBD , 0x12 , 0x1 , 0x85 , 0x7A , 0xBD , 0x11 , 0x1 , 0x85 , 0x7B , 0x4C , 0xAE , 0xC7 , 0x8A , 0x69 , 0x11 , 0xAA , 0x9A , 0x20 , 0x79 , 0x0 , 0xC9 , 0x2C , 0xD0 , 0xF1 , 0x20 , 0x73 , 0x0 , 0x20 , 0x24 , 0xCD , 0x20 , 0x9E , 0xCD , 0x18 , 0x24 , 0x38 , 0x24 , 0xD , 0x30 , 0x3 , 0xB0 , 0x3 , 0x60 , 0xB0 , 0xFD , 0xA2 , 0x16 , 0x4C , 0x37 , 0xC4 , 0xA6 , 0x7A , 0xD0 , 0x2 , 0xC6 , 0x7B , 0xC6 , 0x7A , 0xA2 , 0x0 , 0x24 , 0x48 , 0x8A , 0x48 , 0xA9 , 0x1 , 0x20 , 0xFB , 0xC3 , 0x20 , 0x83 , 0xCE , 0xA9 , 0x0 , 0x85 , 0x4D , 0x20 , 0x79 , 0x0 , 0x38 , 0xE9 , 0xB1 , 0x90 , 0x17 , 0xC9 , 0x3 , 0xB0 , 0x13 , 0xC9 , 0x1 , 0x2A , 0x49 , 0x1 , 0x45 , 0x4D , 0xC5 , 0x4D , 0x90 , 0x61 , 0x85 , 0x4D , 0x20 , 0x73 , 0x0 , 0x4C , 0xBB , 0xCD , 0xA6 , 0x4D , 0xD0 , 0x2C , 0xB0 , 0x7B , 0x69 , 0x7 , 0x90 , 0x77 , 0x65 , 0xD , 0xD0 , 0x3 , 0x4C , 0x3D , 0xD6 , 0x69 , 0xFF , 0x85 , 0x22 , 0xA , 0x65 , 0x22 , 0xA8 , 0x68 , 0xD9 , 0x80 , 0xC0 , 0xB0 , 0x67 , 0x20 , 0x8D , 0xCD , 0x48 , 0x20 , 0x20 , 0xCE , 0x68 , 0xA4 , 0x4B , 0x10 , 0x17 , 0xAA , 0xF0 , 0x56 , 0xD0 , 0x5F , 0x46 , 0xD , 0x8A , 0x2A , 0xA6 , 0x7A , 0xD0 , 0x2 , 0xC6 , 0x7B , 0xC6 , 0x7A , 0xA0 , 0x1B , 0x85 , 0x4D , 0xD0 , 0xD7 , 0xD9 , 0x80 , 0xC0 , 0xB0 , 0x48 , 0x90 , 0xD9 , 0xB9 , 0x82 , 0xC0 , 0x48 , 0xB9 , 0x81 , 0xC0 , 0x48 , 0x20 , 0x33 , 0xCE , 0xA5 , 0x4D , 0x4C , 0xA9 , 0xCD , 0x4C , 0x8 , 0xCF , 0xA5 , 0x66 , 0xBE , 0x80 , 0xC0 , 0xA8 , 0x68 , 0x85 , 0x22 , 0xE6 , 0x22 , 0x68 , 0x85 , 0x23 , 0x98 , 0x48 , 0x20 , 0x1B , 0xDC , 0xA5 , 0x65 , 0x48 , 0xA5 , 0x64 , 0x48 , 0xA5 , 0x63 , 0x48 , 0xA5 , 0x62 , 0x48 , 0xA5 , 0x61 , 0x48 , 0x6C , 0x22 , 0x0 , 0xA0 , 0xFF , 0x68 , 0xF0 , 0x23 , 0xC9 , 0x64 , 0xF0 , 0x3 , 0x20 , 0x8D , 0xCD , 0x84 , 0x4B , 0x68 , 0x4A , 0x85 , 0x12 , 0x68 , 0x85 , 0x69 , 0x68 , 0x85 , 0x6A , 0x68 , 0x85 , 0x6B , 0x68 , 0x85 , 0x6C , 0x68 , 0x85 , 0x6D , 0x68 , 0x85 , 0x6E , 0x45 , 0x66 , 0x85 , 0x6F , 0xA5 , 0x61 , 0x60 , 0x6C , 0xA , 0x3 , 0xA9 , 0x0 , 0x85 , 0xD , 0x20 , 0x73 , 0x0 , 0xB0 , 0x3 , 0x4C , 0xF3 , 0xDC , 0x20 , 0x13 , 0xD1 , 0x90 , 0x3 , 0x4C , 0x28 , 0xCF , 0xC9 , 0xFF , 0xD0 , 0xF , 0xA9 , 0xA8 , 0xA0 , 0xCE , 0x20 , 0xA2 , 0xDB , 0x4C , 0x73 , 0x0 , 0x82 , 0x49 , 0xF , 0xDA , 0xA1 , 0xC9 , 0x2E , 0xF0 , 0xDE , 0xC9 , 0xAB , 0xF0 , 0x58 , 0xC9 , 0xAA , 0xF0 , 0xD1 , 0xC9 , 0x22 , 0xD0 , 0xF , 0xA5 , 0x7A , 0xA4 , 0x7B , 0x69 , 0x0 , 0x90 , 0x1 , 0xC8 , 0x20 , 0x87 , 0xD4 , 0x4C , 0xE2 , 0xD7 , 0xC9 , 0xA8 , 0xD0 , 0x13 , 0xA0 , 0x18 , 0xD0 , 0x3B , 0x20 , 0xBF , 0xD1 , 0xA5 , 0x65 , 0x49 , 0xFF , 0xA8 , 0xA5 , 0x64 , 0x49 , 0xFF , 0x4C , 0x91 , 0xD3 , 0xC9 , 0xA5 , 0xD0 , 0x3 , 0x4C , 0xF4 , 0xD3 , 0xC9 , 0xB4 , 0x90 , 0x3 , 0x4C , 0xA7 , 0xCF , 0x20 , 0xFA , 0xCE , 0x20 , 0x9E , 0xCD , 0xA9 , 0x29 , 0x2C , 0xA9 , 0x28 , 0x2C , 0xA9 , 0x2C , 0xA0 , 0x0 , 0xD1 , 0x7A , 0xD0 , 0x3 , 0x4C , 0x73 , 0x0 , 0xA2 , 0xB , 0x4C , 0x37 , 0xC4 , 0xA0 , 0x15 , 0x68 , 0x68 , 0x4C , 0xFA , 0xCD , 0x38 , 0xA5 , 0x64 , 0xE9 , 0x0 , 0xA5 , 0x65 , 0xE9 , 0xC0 , 0x90 , 0x8 , 0xA9 , 0x87 , 0xE5 , 0x64 , 0xA9 , 0xE3 , 0xE5 , 0x65 , 0x60 , 0x20 , 0x8B , 0xD0 , 0x85 , 0x64 , 0x84 , 0x65 , 0xA6 , 0x45 , 0xA4 , 0x46 , 0xA5 , 0xD , 0xF0 , 0x26 , 0xA9 , 0x0 , 0x85 , 0x70 , 0x20 , 0x14 , 0xCF , 0x90 , 0x1C , 0xE0 , 0x54 , 0xD0 , 0x18 , 0xC0 , 0xC9 , 0xD0 , 0x14 , 0x20 , 0x84 , 0xCF , 0x84 , 0x5E , 0x88 , 0x84 , 0x71 , 0xA0 , 0x6 , 0x84 , 0x5D , 0xA0 , 0x24 , 0x20 , 0x68 , 0xDE , 0x4C , 0x6F , 0xD4 , 0x60 , 0x24 , 0xE , 0x10 , 0xD , 0xA0 , 0x0 , 0xB1 , 0x64 , 0xAA , 0xC8 , 0xB1 , 0x64 , 0xA8 , 0x8A , 0x4C , 0x91 , 0xD3 , 0x20 , 0x14 , 0xCF , 0x90 , 0x2D , 0xE0 , 0x54 , 0xD0 , 0x1B , 0xC0 , 0x49 , 0xD0 , 0x25 , 0x20 , 0x84 , 0xCF , 0x98 , 0xA2 , 0xA0 , 0x4C , 0x4F , 0xDC , 0x20 , 0xDE , 0xFF , 0x86 , 0x64 , 0x84 , 0x63 , 0x85 , 0x65 , 0xA0 , 0x0 , 0x84 , 0x62 , 0x60 , 0xE0 , 0x53 , 0xD0 , 0xA , 0xC0 , 0x54 , 0xD0 , 0x6 , 0x20 , 0xB7 , 0xFF , 0x4C , 0x3C , 0xDC , 0xA5 , 0x64 , 0xA4 , 0x65 , 0x4C , 0xA2 , 0xDB , 0xA , 0x48 , 0xAA , 0x20 , 0x73 , 0x0 , 0xE0 , 0x8F , 0x90 , 0x20 , 0x20 , 0xFA , 0xCE , 0x20 , 0x9E , 0xCD , 0x20 , 0xFD , 0xCE , 0x20 , 0x8F , 0xCD , 0x68 , 0xAA , 0xA5 , 0x65 , 0x48 , 0xA5 , 0x64 , 0x48 , 0x8A , 0x48 , 0x20 , 0x9E , 0xD7 , 0x68 , 0xA8 , 0x8A , 0x48 , 0x4C , 0xD6 , 0xCF , 0x20 , 0xF1 , 0xCE , 0x68 , 0xA8 , 0xB9 , 0xEA , 0xBF , 0x85 , 0x55 , 0xB9 , 0xEB , 0xBF , 0x85 , 0x56 , 0x20 , 0x54 , 0x0 , 0x4C , 0x8D , 0xCD , 0xA0 , 0xFF , 0x2C , 0xA0 , 0x0 , 0x84 , 0xB , 0x20 , 0xBF , 0xD1 , 0xA5 , 0x64 , 0x45 , 0xB , 0x85 , 0x7 , 0xA5 , 0x65 , 0x45 , 0xB , 0x85 , 0x8 , 0x20 , 0xFC , 0xDB , 0x20 , 0xBF , 0xD1 , 0xA5 , 0x65 , 0x45 , 0xB , 0x25 , 0x8 , 0x45 , 0xB , 0xA8 , 0xA5 , 0x64 , 0x45 , 0xB , 0x25 , 0x7 , 0x45 , 0xB , 0x4C , 0x91 , 0xD3 , 0x20 , 0x90 , 0xCD , 0xB0 , 0x13 , 0xA5 , 0x6E , 0x9 , 0x7F , 0x25 , 0x6A , 0x85 , 0x6A , 0xA9 , 0x69 , 0xA0 , 0x0 , 0x20 , 0x5B , 0xDC , 0xAA , 0x4C , 0x61 , 0xD0 , 0xA9 , 0x0 , 0x85 , 0xD , 0xC6 , 0x4D , 0x20 , 0xA6 , 0xD6 , 0x85 , 0x61 , 0x86 , 0x62 , 0x84 , 0x63 , 0xA5 , 0x6C , 0xA4 , 0x6D , 0x20 , 0xAA , 0xD6 , 0x86 , 0x6C , 0x84 , 0x6D , 0xAA , 0x38 , 0xE5 , 0x61 , 0xF0 , 0x8 , 0xA9 , 0x1 , 0x90 , 0x4 , 0xA6 , 0x61 , 0xA9 , 0xFF , 0x85 , 0x66 , 0xA0 , 0xFF , 0xE8 , 0xC8 , 0xCA , 0xD0 , 0x7 , 0xA6 , 0x66 , 0x30 , 0xF , 0x18 , 0x90 , 0xC , 0xB1 , 0x6C , 0xD1 , 0x62 , 0xF0 , 0xEF , 0xA2 , 0xFF , 0xB0 , 0x2 , 0xA2 , 0x1 , 0xE8 , 0x8A , 0x2A , 0x25 , 0x12 , 0xF0 , 0x2 , 0xA9 , 0xFF , 0x4C , 0x3C , 0xDC , 0x20 , 0xFD , 0xCE , 0xAA , 0x20 , 0x90 , 0xD0 , 0x20 , 0x79 , 0x0 , 0xD0 , 0xF4 , 0x60 , 0xA2 , 0x0 , 0x20 , 0x79 , 0x0 , 0x86 , 0xC , 0x85 , 0x45 , 0x20 , 0x79 , 0x0 , 0x20 , 0x13 , 0xD1 , 0xB0 , 0x3 , 0x4C , 0x8 , 0xCF , 0xA2 , 0x0 , 0x86 , 0xD , 0x86 , 0xE , 0x20 , 0x73 , 0x0 , 0x90 , 0x5 , 0x20 , 0x13 , 0xD1 , 0x90 , 0xB , 0xAA , 0x20 , 0x73 , 0x0 , 0x90 , 0xFB , 0x20 , 0x13 , 0xD1 , 0xB0 , 0xF6 , 0xC9 , 0x24 , 0xD0 , 0x6 , 0xA9 , 0xFF , 0x85 , 0xD , 0xD0 , 0x10 , 0xC9 , 0x25 , 0xD0 , 0x13 , 0xA5 , 0x10 , 0xD0 , 0xD0 , 0xA9 , 0x80 , 0x85 , 0xE , 0x5 , 0x45 , 0x85 , 0x45 , 0x8A , 0x9 , 0x80 , 0xAA , 0x20 , 0x73 , 0x0 , 0x86 , 0x46 , 0x38 , 0x5 , 0x10 , 0xE9 , 0x28 , 0xD0 , 0x3 , 0x4C , 0xD1 , 0xD1 , 0xA0 , 0x0 , 0x84 , 0x10 , 0xA5 , 0x2D , 0xA6 , 0x2E , 0x86 , 0x60 , 0x85 , 0x5F , 0xE4 , 0x30 , 0xD0 , 0x4 , 0xC5 , 0x2F , 0xF0 , 0x22 , 0xA5 , 0x45 , 0xD1 , 0x5F , 0xD0 , 0x8 , 0xA5 , 0x46 , 0xC8 , 0xD1 , 0x5F , 0xF0 , 0x7D , 0x88 , 0x18 , 0xA5 , 0x5F , 0x69 , 0x7 , 0x90 , 0xE1 , 0xE8 , 0xD0 , 0xDC , 0xC9 , 0x41 , 0x90 , 0x5 , 0xE9 , 0x5B , 0x38 , 0xE9 , 0xA5 , 0x60 , 0x68 , 0x48 , 0xC9 , 0x2A , 0xD0 , 0x5 , 0xA9 , 0x13 , 0xA0 , 0xDF , 0x60 , 0xA5 , 0x45 , 0xA4 , 0x46 , 0xC9 , 0x54 , 0xD0 , 0xB , 0xC0 , 0xC9 , 0xF0 , 0xEF , 0xC0 , 0x49 , 0xD0 , 0x3 , 0x4C , 0x8 , 0xCF , 0xC9 , 0x53 , 0xD0 , 0x4 , 0xC0 , 0x54 , 0xF0 , 0xF5 , 0xA5 , 0x2F , 0xA4 , 0x30 , 0x85 , 0x5F , 0x84 , 0x60 , 0xA5 , 0x31 , 0xA4 , 0x32 , 0x85 , 0x5A , 0x84 , 0x5B , 0x18 , 0x69 , 0x7 , 0x90 , 0x1 , 0xC8 , 0x85 , 0x58 , 0x84 , 0x59 , 0x20 , 0xB8 , 0xC3 , 0xA5 , 0x58 , 0xA4 , 0x59 , 0xC8 , 0x85 , 0x2F , 0x84 , 0x30 , 0xA0 , 0x0 , 0xA5 , 0x45 , 0x91 , 0x5F , 0xC8 , 0xA5 , 0x46 , 0x91 , 0x5F , 0xA9 , 0x0 , 0xC8 , 0x91 , 0x5F , 0xC8 , 0x91 , 0x5F , 0xC8 , 0x91 , 0x5F , 0xC8 , 0x91 , 0x5F , 0xC8 , 0x91 , 0x5F , 0xA5 , 0x5F , 0x18 , 0x69 , 0x2 , 0xA4 , 0x60 , 0x90 , 0x1 , 0xC8 , 0x85 , 0x47 , 0x84 , 0x48 , 0x60 , 0xA5 , 0xB , 0xA , 0x69 , 0x5 , 0x65 , 0x5F , 0xA4 , 0x60 , 0x90 , 0x1 , 0xC8 , 0x85 , 0x58 , 0x84 , 0x59 , 0x60 , 0x90 , 0x80 , 0x0 , 0x0 , 0x0 , 0x20 , 0xBF , 0xD1 , 0xA5 , 0x64 , 0xA4 , 0x65 , 0x60 , 0x20 , 0x73 , 0x0 , 0x20 , 0x9E , 0xCD , 0x20 , 0x8D , 0xCD , 0xA5 , 0x66 , 0x30 , 0xD , 0xA5 , 0x61 , 0xC9 , 0x90 , 0x90 , 0x9 , 0xA9 , 0xA5 , 0xA0 , 0xD1 , 0x20 , 0x5B , 0xDC , 0xD0 , 0x7A , 0x4C , 0x9B , 0xDC , 0xA5 , 0xC , 0x5 , 0xE , 0x48 , 0xA5 , 0xD , 0x48 , 0xA0 , 0x0 , 0x98 , 0x48 , 0xA5 , 0x46 , 0x48 , 0xA5 , 0x45 , 0x48 , 0x20 , 0xB2 , 0xD1 , 0x68 , 0x85 , 0x45 , 0x68 , 0x85 , 0x46 , 0x68 , 0xA8 , 0xBA , 0xBD , 0x2 , 0x1 , 0x48 , 0xBD , 0x1 , 0x1 , 0x48 , 0xA5 , 0x64 , 0x9D , 0x2 , 0x1 , 0xA5 , 0x65 , 0x9D , 0x1 , 0x1 , 0xC8 , 0x20 , 0x79 , 0x0 , 0xC9 , 0x2C , 0xF0 , 0xD2 , 0x84 , 0xB , 0x20 , 0xF7 , 0xCE , 0x68 , 0x85 , 0xD , 0x68 , 0x85 , 0xE , 0x29 , 0x7F , 0x85 , 0xC , 0xA6 , 0x2F , 0xA5 , 0x30 , 0x86 , 0x5F , 0x85 , 0x60 , 0xC5 , 0x32 , 0xD0 , 0x4 , 0xE4 , 0x31 , 0xF0 , 0x39 , 0xA0 , 0x0 , 0xB1 , 0x5F , 0xC8 , 0xC5 , 0x45 , 0xD0 , 0x6 , 0xA5 , 0x46 , 0xD1 , 0x5F , 0xF0 , 0x16 , 0xC8 , 0xB1 , 0x5F , 0x18 , 0x65 , 0x5F , 0xAA , 0xC8 , 0xB1 , 0x5F , 0x65 , 0x60 , 0x90 , 0xD7 , 0xA2 , 0x12 , 0x2C , 0xA2 , 0xE , 0x4C , 0x37 , 0xC4 , 0xA2 , 0x13 , 0xA5 , 0xC , 0xD0 , 0xF7 , 0x20 , 0x94 , 0xD1 , 0xA5 , 0xB , 0xA0 , 0x4 , 0xD1 , 0x5F , 0xD0 , 0xE7 , 0x4C , 0xEA , 0xD2 , 0x20 , 0x94 , 0xD1 , 0x20 , 0x8 , 0xC4 , 0xA0 , 0x0 , 0x84 , 0x72 , 0xA2 , 0x5 , 0xA5 , 0x45 , 0x91 , 0x5F , 0x10 , 0x1 , 0xCA , 0xC8 , 0xA5 , 0x46 , 0x91 , 0x5F , 0x10 , 0x2 , 0xCA , 0xCA , 0x86 , 0x71 , 0xA5 , 0xB , 0xC8 , 0xC8 , 0xC8 , 0x91 , 0x5F , 0xA2 , 0xB , 0xA9 , 0x0 , 0x24 , 0xC , 0x50 , 0x8 , 0x68 , 0x18 , 0x69 , 0x1 , 0xAA , 0x68 , 0x69 , 0x0 , 0xC8 , 0x91 , 0x5F , 0xC8 , 0x8A , 0x91 , 0x5F , 0x20 , 0x4C , 0xD3 , 0x86 , 0x71 , 0x85 , 0x72 , 0xA4 , 0x22 , 0xC6 , 0xB , 0xD0 , 0xDC , 0x65 , 0x59 , 0xB0 , 0x5D , 0x85 , 0x59 , 0xA8 , 0x8A , 0x65 , 0x58 , 0x90 , 0x3 , 0xC8 , 0xF0 , 0x52 , 0x20 , 0x8 , 0xC4 , 0x85 , 0x31 , 0x84 , 0x32 , 0xA9 , 0x0 , 0xE6 , 0x72 , 0xA4 , 0x71 , 0xF0 , 0x5 , 0x88 , 0x91 , 0x58 , 0xD0 , 0xFB , 0xC6 , 0x59 , 0xC6 , 0x72 , 0xD0 , 0xF5 , 0xE6 , 0x59 , 0x38 , 0xA5 , 0x31 , 0xE5 , 0x5F , 0xA0 , 0x2 , 0x91 , 0x5F , 0xA5 , 0x32 , 0xC8 , 0xE5 , 0x60 , 0x91 , 0x5F , 0xA5 , 0xC , 0xD0 , 0x62 , 0xC8 , 0xB1 , 0x5F , 0x85 , 0xB , 0xA9 , 0x0 , 0x85 , 0x71 , 0x85 , 0x72 , 0xC8 , 0x68 , 0xAA , 0x85 , 0x64 , 0x68 , 0x85 , 0x65 , 0xD1 , 0x5F , 0x90 , 0xE , 0xD0 , 0x6 , 0xC8 , 0x8A , 0xD1 , 0x5F , 0x90 , 0x7 , 0x4C , 0x45 , 0xD2 , 0x4C , 0x35 , 0xC4 , 0xC8 , 0xA5 , 0x72 , 0x5 , 0x71 , 0x18 , 0xF0 , 0xA , 0x20 , 0x4C , 0xD3 , 0x8A , 0x65 , 0x64 , 0xAA , 0x98 , 0xA4 , 0x22 , 0x65 , 0x65 , 0x86 , 0x71 , 0xC6 , 0xB , 0xD0 , 0xCA , 0x85 , 0x72 , 0xA2 , 0x5 , 0xA5 , 0x45 , 0x10 , 0x1 , 0xCA , 0xA5 , 0x46 , 0x10 , 0x2 , 0xCA , 0xCA , 0x86 , 0x28 , 0xA9 , 0x0 , 0x20 , 0x55 , 0xD3 , 0x8A , 0x65 , 0x58 , 0x85 , 0x47 , 0x98 , 0x65 , 0x59 , 0x85 , 0x48 , 0xA8 , 0xA5 , 0x47 , 0x60 , 0x84 , 0x22 , 0xB1 , 0x5F , 0x85 , 0x28 , 0x88 , 0xB1 , 0x5F , 0x85 , 0x29 , 0xA9 , 0x10 , 0x85 , 0x5D , 0xA2 , 0x0 , 0xA0 , 0x0 , 0x8A , 0xA , 0xAA , 0x98 , 0x2A , 0xA8 , 0xB0 , 0xA4 , 0x6 , 0x71 , 0x26 , 0x72 , 0x90 , 0xB , 0x18 , 0x8A , 0x65 , 0x28 , 0xAA , 0x98 , 0x65 , 0x29 , 0xA8 , 0xB0 , 0x93 , 0xC6 , 0x5D , 0xD0 , 0xE3 , 0x60 , 0xA5 , 0xD , 0xF0 , 0x3 , 0x20 , 0xA6 , 0xD6 , 0x20 , 0x26 , 0xD5 , 0x38 , 0xA5 , 0x33 , 0xE5 , 0x31 , 0xA8 , 0xA5 , 0x34 , 0xE5 , 0x32 , 0xA2 , 0x0 , 0x86 , 0xD , 0x85 , 0x62 , 0x84 , 0x63 , 0xA2 , 0x90 , 0x4C , 0x44 , 0xDC , 0x38 , 0x20 , 0xF0 , 0xFF , 0xA9 , 0x0 , 0xF0 , 0xEB , 0xA6 , 0x3A , 0xE8 , 0xD0 , 0xA0 , 0xA2 , 0x15 , 0x2C , 0xA2 , 0x1B , 0x4C , 0x37 , 0xC4 , 0x20 , 0xE1 , 0xD3 , 0x20 , 0xA6 , 0xD3 , 0x20 , 0xFA , 0xCE , 0xA9 , 0x80 , 0x85 , 0x10 , 0x20 , 0x8B , 0xD0 , 0x20 , 0x8D , 0xCD , 0x20 , 0xF7 , 0xCE , 0xA9 , 0xB2 , 0x20 , 0xFF , 0xCE , 0x48 , 0xA5 , 0x48 , 0x48 , 0xA5 , 0x47 , 0x48 , 0xA5 , 0x7B , 0x48 , 0xA5 , 0x7A , 0x48 , 0x20 , 0xF8 , 0xC8 , 0x4C , 0x4F , 0xD4 , 0xA9 , 0xA5 , 0x20 , 0xFF , 0xCE , 0x9 , 0x80 , 0x85 , 0x10 , 0x20 , 0x92 , 0xD0 , 0x85 , 0x4E , 0x84 , 0x4F , 0x4C , 0x8D , 0xCD , 0x20 , 0xE1 , 0xD3 , 0xA5 , 0x4F , 0x48 , 0xA5 , 0x4E , 0x48 , 0x20 , 0xF1 , 0xCE , 0x20 , 0x8D , 0xCD , 0x68 , 0x85 , 0x4E , 0x68 , 0x85 , 0x4F , 0xA0 , 0x2 , 0xB1 , 0x4E , 0x85 , 0x47 , 0xAA , 0xC8 , 0xB1 , 0x4E , 0xF0 , 0x99 , 0x85 , 0x48 , 0xC8 , 0xB1 , 0x47 , 0x48 , 0x88 , 0x10 , 0xFA , 0xA4 , 0x48 , 0x20 , 0xD4 , 0xDB , 0xA5 , 0x7B , 0x48 , 0xA5 , 0x7A , 0x48 , 0xB1 , 0x4E , 0x85 , 0x7A , 0xC8 , 0xB1 , 0x4E , 0x85 , 0x7B , 0xA5 , 0x48 , 0x48 , 0xA5 , 0x47 , 0x48 , 0x20 , 0x8A , 0xCD , 0x68 , 0x85 , 0x4E , 0x68 , 0x85 , 0x4F , 0x20 , 0x79 , 0x0 , 0xF0 , 0x3 , 0x4C , 0x8 , 0xCF , 0x68 , 0x85 , 0x7A , 0x68 , 0x85 , 0x7B , 0xA0 , 0x0 , 0x68 , 0x91 , 0x4E , 0x68 , 0xC8 , 0x91 , 0x4E , 0x68 , 0xC8 , 0x91 , 0x4E , 0x68 , 0xC8 , 0x91 , 0x4E , 0x68 , 0xC8 , 0x91 , 0x4E , 0x60 , 0x20 , 0x8D , 0xCD , 0xA0 , 0x0 , 0x20 , 0xDF , 0xDD , 0x68 , 0x68 , 0xA9 , 0xFF , 0xA0 , 0x0 , 0xF0 , 0x12 , 0xA6 , 0x64 , 0xA4 , 0x65 , 0x86 , 0x50 , 0x84 , 0x51 , 0x20 , 0xF4 , 0xD4 , 0x86 , 0x62 , 0x84 , 0x63 , 0x85 , 0x61 , 0x60 , 0xA2 , 0x22 , 0x86 , 0x7 , 0x86 , 0x8 , 0x85 , 0x6F , 0x84 , 0x70 , 0x85 , 0x62 , 0x84 , 0x63 , 0xA0 , 0xFF , 0xC8 , 0xB1 , 0x6F , 0xF0 , 0xC , 0xC5 , 0x7 , 0xF0 , 0x4 , 0xC5 , 0x8 , 0xD0 , 0xF3 , 0xC9 , 0x22 , 0xF0 , 0x1 , 0x18 , 0x84 , 0x61 , 0x98 , 0x65 , 0x6F , 0x85 , 0x71 , 0xA6 , 0x70 , 0x90 , 0x1 , 0xE8 , 0x86 , 0x72 , 0xA5 , 0x70 , 0xF0 , 0x4 , 0xC9 , 0x2 , 0xD0 , 0xB , 0x98 , 0x20 , 0x75 , 0xD4 , 0xA6 , 0x6F , 0xA4 , 0x70 , 0x20 , 0x88 , 0xD6 , 0xA6 , 0x16 , 0xE0 , 0x22 , 0xD0 , 0x5 , 0xA2 , 0x19 , 0x4C , 0x37 , 0xC4 , 0xA5 , 0x61 , 0x95 , 0x0 , 0xA5 , 0x62 , 0x95 , 0x1 , 0xA5 , 0x63 , 0x95 , 0x2 , 0xA0 , 0x0 , 0x86 , 0x64 , 0x84 , 0x65 , 0x84 , 0x70 , 0x88 , 0x84 , 0xD , 0x86 , 0x17 , 0xE8 , 0xE8 , 0xE8 , 0x86 , 0x16 , 0x60 , 0x46 , 0xF , 0x48 , 0x49 , 0xFF , 0x38 , 0x65 , 0x33 , 0xA4 , 0x34 , 0xB0 , 0x1 , 0x88 , 0xC4 , 0x32 , 0x90 , 0x11 , 0xD0 , 0x4 , 0xC5 , 0x31 , 0x90 , 0xB , 0x85 , 0x33 , 0x84 , 0x34 , 0x85 , 0x35 , 0x84 , 0x36 , 0xAA , 0x68 , 0x60 , 0xA2 , 0x10 , 0xA5 , 0xF , 0x30 , 0xB6 , 0x20 , 0x26 , 0xD5 , 0xA9 , 0x80 , 0x85 , 0xF , 0x68 , 0xD0 , 0xD0 , 0xA6 , 0x37 , 0xA5 , 0x38 , 0x86 , 0x33 , 0x85 , 0x34 , 0xA0 , 0x0 , 0x84 , 0x4F , 0x84 , 0x4E , 0xA5 , 0x31 , 0xA6 , 0x32 , 0x85 , 0x5F , 0x86 , 0x60 , 0xA9 , 0x19 , 0xA2 , 0x0 , 0x85 , 0x22 , 0x86 , 0x23 , 0xC5 , 0x16 , 0xF0 , 0x5 , 0x20 , 0xC7 , 0xD5 , 0xF0 , 0xF7 , 0xA9 , 0x7 , 0x85 , 0x53 , 0xA5 , 0x2D , 0xA6 , 0x2E , 0x85 , 0x22 , 0x86 , 0x23 , 0xE4 , 0x30 , 0xD0 , 0x4 , 0xC5 , 0x2F , 0xF0 , 0x5 , 0x20 , 0xBD , 0xD5 , 0xF0 , 0xF3 , 0x85 , 0x58 , 0x86 , 0x59 , 0xA9 , 0x3 , 0x85 , 0x53 , 0xA5 , 0x58 , 0xA6 , 0x59 , 0xE4 , 0x32 , 0xD0 , 0x7 , 0xC5 , 0x31 , 0xD0 , 0x3 , 0x4C , 0x6 , 0xD6 , 0x85 , 0x22 , 0x86 , 0x23 , 0xA0 , 0x0 , 0xB1 , 0x22 , 0xAA , 0xC8 , 0xB1 , 0x22 , 0x8 , 0xC8 , 0xB1 , 0x22 , 0x65 , 0x58 , 0x85 , 0x58 , 0xC8 , 0xB1 , 0x22 , 0x65 , 0x59 , 0x85 , 0x59 , 0x28 , 0x10 , 0xD3 , 0x8A , 0x30 , 0xD0 , 0xC8 , 0xB1 , 0x22 , 0xA0 , 0x0 , 0xA , 0x69 , 0x5 , 0x65 , 0x22 , 0x85 , 0x22 , 0x90 , 0x2 , 0xE6 , 0x23 , 0xA6 , 0x23 , 0xE4 , 0x59 , 0xD0 , 0x4 , 0xC5 , 0x58 , 0xF0 , 0xBA , 0x20 , 0xC7 , 0xD5 , 0xF0 , 0xF3 , 0xB1 , 0x22 , 0x30 , 0x35 , 0xC8 , 0xB1 , 0x22 , 0x10 , 0x30 , 0xC8 , 0xB1 , 0x22 , 0xF0 , 0x2B , 0xC8 , 0xB1 , 0x22 , 0xAA , 0xC8 , 0xB1 , 0x22 , 0xC5 , 0x34 , 0x90 , 0x6 , 0xD0 , 0x1E , 0xE4 , 0x33 , 0xB0 , 0x1A , 0xC5 , 0x60 , 0x90 , 0x16 , 0xD0 , 0x4 , 0xE4 , 0x5F , 0x90 , 0x10 , 0x86 , 0x5F , 0x85 , 0x60 , 0xA5 , 0x22 , 0xA6 , 0x23 , 0x85 , 0x4E , 0x86 , 0x4F , 0xA5 , 0x53 , 0x85 , 0x55 , 0xA5 , 0x53 , 0x18 , 0x65 , 0x22 , 0x85 , 0x22 , 0x90 , 0x2 , 0xE6 , 0x23 , 0xA6 , 0x23 , 0xA0 , 0x0 , 0x60 , 0xA5 , 0x4F , 0x5 , 0x4E , 0xF0 , 0xF5 , 0xA5 , 0x55 , 0x29 , 0x4 , 0x4A , 0xA8 , 0x85 , 0x55 , 0xB1 , 0x4E , 0x65 , 0x5F , 0x85 , 0x5A , 0xA5 , 0x60 , 0x69 , 0x0 , 0x85 , 0x5B , 0xA5 , 0x33 , 0xA6 , 0x34 , 0x85 , 0x58 , 0x86 , 0x59 , 0x20 , 0xBF , 0xC3 , 0xA4 , 0x55 , 0xC8 , 0xA5 , 0x58 , 0x91 , 0x4E , 0xAA , 0xE6 , 0x59 , 0xA5 , 0x59 , 0xC8 , 0x91 , 0x4E , 0x4C , 0x2A , 0xD5 , 0xA5 , 0x65 , 0x48 , 0xA5 , 0x64 , 0x48 , 0x20 , 0x83 , 0xCE , 0x20 , 0x8F , 0xCD , 0x68 , 0x85 , 0x6F , 0x68 , 0x85 , 0x70 , 0xA0 , 0x0 , 0xB1 , 0x6F , 0x18 , 0x71 , 0x64 , 0x90 , 0x5 , 0xA2 , 0x17 , 0x4C , 0x37 , 0xC4 , 0x20 , 0x75 , 0xD4 , 0x20 , 0x7A , 0xD6 , 0xA5 , 0x50 , 0xA4 , 0x51 , 0x20 , 0xAA , 0xD6 , 0x20 , 0x8C , 0xD6 , 0xA5 , 0x6F , 0xA4 , 0x70 , 0x20 , 0xAA , 0xD6 , 0x20 , 0xCA , 0xD4 , 0x4C , 0xB8 , 0xCD , 0xA0 , 0x0 , 0xB1 , 0x6F , 0x48 , 0xC8 , 0xB1 , 0x6F , 0xAA , 0xC8 , 0xB1 , 0x6F , 0xA8 , 0x68 , 0x86 , 0x22 , 0x84 , 0x23 , 0xA8 , 0xF0 , 0xA , 0x48 , 0x88 , 0xB1 , 0x22 , 0x91 , 0x35 , 0x98 , 0xD0 , 0xF8 , 0x68 , 0x18 , 0x65 , 0x35 , 0x85 , 0x35 , 0x90 , 0x2 , 0xE6 , 0x36 , 0x60 , 0x20 , 0x8F , 0xCD , 0xA5 , 0x64 , 0xA4 , 0x65 , 0x85 , 0x22 , 0x84 , 0x23 , 0x20 , 0xDB , 0xD6 , 0x8 , 0xA0 , 0x0 , 0xB1 , 0x22 , 0x48 , 0xC8 , 0xB1 , 0x22 , 0xAA , 0xC8 , 0xB1 , 0x22 , 0xA8 , 0x68 , 0x28 , 0xD0 , 0x13 , 0xC4 , 0x34 , 0xD0 , 0xF , 0xE4 , 0x33 , 0xD0 , 0xB , 0x48 , 0x18 , 0x65 , 0x33 , 0x85 , 0x33 , 0x90 , 0x2 , 0xE6 , 0x34 , 0x68 , 0x86 , 0x22 , 0x84 , 0x23 , 0x60 , 0xC4 , 0x18 , 0xD0 , 0xC , 0xC5 , 0x17 , 0xD0 , 0x8 , 0x85 , 0x16 , 0xE9 , 0x3 , 0x85 , 0x17 , 0xA0 , 0x0 , 0x60 , 0x20 , 0xA1 , 0xD7 , 0x8A , 0x48 , 0xA9 , 0x1 , 0x20 , 0x7D , 0xD4 , 0x68 , 0xA0 , 0x0 , 0x91 , 0x62 , 0x68 , 0x68 , 0x4C , 0xCA , 0xD4 , 0x20 , 0x61 , 0xD7 , 0xD1 , 0x50 , 0x98 , 0x90 , 0x4 , 0xB1 , 0x50 , 0xAA , 0x98 , 0x48 , 0x8A , 0x48 , 0x20 , 0x7D , 0xD4 , 0xA5 , 0x50 , 0xA4 , 0x51 , 0x20 , 0xAA , 0xD6 , 0x68 , 0xA8 , 0x68 , 0x18 , 0x65 , 0x22 , 0x85 , 0x22 , 0x90 , 0x2 , 0xE6 , 0x23 , 0x98 , 0x20 , 0x8C , 0xD6 , 0x4C , 0xCA , 0xD4 , 0x20 , 0x61 , 0xD7 , 0x18 , 0xF1 , 0x50 , 0x49 , 0xFF , 0x4C , 0x6 , 0xD7 , 0xA9 , 0xFF , 0x85 , 0x65 , 0x20 , 0x79 , 0x0 , 0xC9 , 0x29 , 0xF0 , 0x6 , 0x20 , 0xFD , 0xCE , 0x20 , 0x9E , 0xD7 , 0x20 , 0x61 , 0xD7 , 0xF0 , 0x4B , 0xCA , 0x8A , 0x48 , 0x18 , 0xA2 , 0x0 , 0xF1 , 0x50 , 0xB0 , 0xB6 , 0x49 , 0xFF , 0xC5 , 0x65 , 0x90 , 0xB1 , 0xA5 , 0x65 , 0xB0 , 0xAD , 0x20 , 0xF7 , 0xCE , 0x68 , 0xA8 , 0x68 , 0x85 , 0x55 , 0x68 , 0x68 , 0x68 , 0xAA , 0x68 , 0x85 , 0x50 , 0x68 , 0x85 , 0x51 , 0xA5 , 0x55 , 0x48 , 0x98 , 0x48 , 0xA0 , 0x0 , 0x8A , 0x60 , 0x20 , 0x82 , 0xD7 , 0x4C , 0xA2 , 0xD3 , 0x20 , 0xA3 , 0xD6 , 0xA2 , 0x0 , 0x86 , 0xD , 0xA8 , 0x60 , 0x20 , 0x82 , 0xD7 , 0xF0 , 0x8 , 0xA0 , 0x0 , 0xB1 , 0x22 , 0xA8 , 0x4C , 0xA2 , 0xD3 , 0x4C , 0x48 , 0xD2 , 0x20 , 0x73 , 0x0 , 0x20 , 0x8A , 0xCD , 0x20 , 0xB8 , 0xD1 , 0xA6 , 0x64 , 0xD0 , 0xF0 , 0xA6 , 0x65 , 0x4C , 0x79 , 0x0 , 0x20 , 0x82 , 0xD7 , 0xD0 , 0x3 , 0x4C , 0xF7 , 0xD8 , 0xA6 , 0x7A , 0xA4 , 0x7B , 0x86 , 0x71 , 0x84 , 0x72 , 0xA6 , 0x22 , 0x86 , 0x7A , 0x18 , 0x65 , 0x22 , 0x85 , 0x24 , 0xA6 , 0x23 , 0x86 , 0x7B , 0x90 , 0x1 , 0xE8 , 0x86 , 0x25 , 0xA0 , 0x0 , 0xB1 , 0x24 , 0x48 , 0x98 , 0x91 , 0x24 , 0x20 , 0x79 , 0x0 , 0x20 , 0xF3 , 0xDC , 0x68 , 0xA0 , 0x0 , 0x91 , 0x24 , 0xA6 , 0x71 , 0xA4 , 0x72 , 0x86 , 0x7A , 0x84 , 0x7B , 0x60 , 0x20 , 0x8A , 0xCD , 0x20 , 0xF7 , 0xD7 , 0x20 , 0xFD , 0xCE , 0x4C , 0x9E , 0xD7 , 0xA5 , 0x66 , 0x30 , 0x9D , 0xA5 , 0x61 , 0xC9 , 0x91 , 0xB0 , 0x97 , 0x20 , 0x9B , 0xDC , 0xA5 , 0x64 , 0xA4 , 0x65 , 0x84 , 0x14 , 0x85 , 0x15 , 0x60 , 0xA5 , 0x15 , 0x48 , 0xA5 , 0x14 , 0x48 , 0x20 , 0xF7 , 0xD7 , 0xA0 , 0x0 , 0xB1 , 0x14 , 0xA8 , 0x68 , 0x85 , 0x14 , 0x68 , 0x85 , 0x15 , 0x4C , 0xA2 , 0xD3 , 0x20 , 0xEB , 0xD7 , 0x8A , 0xA0 , 0x0 , 0x91 , 0x14 , 0x60 , 0x20 , 0xEB , 0xD7 , 0x86 , 0x49 , 0xA2 , 0x0 , 0x20 , 0x79 , 0x0 , 0xF0 , 0x3 , 0x20 , 0xF1 , 0xD7 , 0x86 , 0x4A , 0xA0 , 0x0 , 0xB1 , 0x14 , 0x45 , 0x4A , 0x25 , 0x49 , 0xF0 , 0xF8 , 0x60 , 0xA9 , 0x11 , 0xA0 , 0xDF , 0x4C , 0x67 , 0xD8 , 0x20 , 0x8C , 0xDA , 0xA5 , 0x66 , 0x49 , 0xFF , 0x85 , 0x66 , 0x45 , 0x6E , 0x85 , 0x6F , 0xA5 , 0x61 , 0x4C , 0x6A , 0xD8 , 0x20 , 0x99 , 0xD9 , 0x90 , 0x3C , 0x20 , 0x8C , 0xDA , 0xD0 , 0x3 , 0x4C , 0xFC , 0xDB , 0xA6 , 0x70 , 0x86 , 0x56 , 0xA2 , 0x69 , 0xA5 , 0x69 , 0xA8 , 0xF0 , 0xCE , 0x38 , 0xE5 , 0x61 , 0xF0 , 0x24 , 0x90 , 0x12 , 0x84 , 0x61 , 0xA4 , 0x6E , 0x84 , 0x66 , 0x49 , 0xFF , 0x69 , 0x0 , 0xA0 , 0x0 , 0x84 , 0x56 , 0xA2 , 0x61 , 0xD0 , 0x4 , 0xA0 , 0x0 , 0x84 , 0x70 , 0xC9 , 0xF9 , 0x30 , 0xC7 , 0xA8 , 0xA5 , 0x70 , 0x56 , 0x1 , 0x20 , 0xB0 , 0xD9 , 0x24 , 0x6F , 0x10 , 0x57 , 0xA0 , 0x61 , 0xE0 , 0x69 , 0xF0 , 0x2 , 0xA0 , 0x69 , 0x38 , 0x49 , 0xFF , 0x65 , 0x56 , 0x85 , 0x70 , 0xB9 , 0x4 , 0x0 , 0xF5 , 0x4 , 0x85 , 0x65 , 0xB9 , 0x3 , 0x0 , 0xF5 , 0x3 , 0x85 , 0x64 , 0xB9 , 0x2 , 0x0 , 0xF5 , 0x2 , 0x85 , 0x63 , 0xB9 , 0x1 , 0x0 , 0xF5 , 0x1 , 0x85 , 0x62 , 0xB0 , 0x3 , 0x20 , 0x47 , 0xD9 , 0xA0 , 0x0 , 0x98 , 0x18 , 0xA6 , 0x62 , 0xD0 , 0x4A , 0xA6 , 0x63 , 0x86 , 0x62 , 0xA6 , 0x64 , 0x86 , 0x63 , 0xA6 , 0x65 , 0x86 , 0x64 , 0xA6 , 0x70 , 0x86 , 0x65 , 0x84 , 0x70 , 0x69 , 0x8 , 0xC9 , 0x20 , 0xD0 , 0xE4 , 0xA9 , 0x0 , 0x85 , 0x61 , 0x85 , 0x66 , 0x60 , 0x65 , 0x56 , 0x85 , 0x70 , 0xA5 , 0x65 , 0x65 , 0x6D , 0x85 , 0x65 , 0xA5 , 0x64 , 0x65 , 0x6C , 0x85 , 0x64 , 0xA5 , 0x63 , 0x65 , 0x6B , 0x85 , 0x63 , 0xA5 , 0x62 , 0x65 , 0x6A , 0x85 , 0x62 , 0x4C , 0x36 , 0xD9 , 0x69 , 0x1 , 0x6 , 0x70 , 0x26 , 0x65 , 0x26 , 0x64 , 0x26 , 0x63 , 0x26 , 0x62 , 0x10 , 0xF2 , 0x38 , 0xE5 , 0x61 , 0xB0 , 0xC7 , 0x49 , 0xFF , 0x69 , 0x1 , 0x85 , 0x61 , 0x90 , 0xE , 0xE6 , 0x61 , 0xF0 , 0x42 , 0x66 , 0x62 , 0x66 , 0x63 , 0x66 , 0x64 , 0x66 , 0x65 , 0x66 , 0x70 , 0x60 , 0xA5 , 0x66 , 0x49 , 0xFF , 0x85 , 0x66 , 0xA5 , 0x62 , 0x49 , 0xFF , 0x85 , 0x62 , 0xA5 , 0x63 , 0x49 , 0xFF , 0x85 , 0x63 , 0xA5 , 0x64 , 0x49 , 0xFF , 0x85 , 0x64 , 0xA5 , 0x65 , 0x49 , 0xFF , 0x85 , 0x65 , 0xA5 , 0x70 , 0x49 , 0xFF , 0x85 , 0x70 , 0xE6 , 0x70 , 0xD0 , 0xE , 0xE6 , 0x65 , 0xD0 , 0xA , 0xE6 , 0x64 , 0xD0 , 0x6 , 0xE6 , 0x63 , 0xD0 , 0x2 , 0xE6 , 0x62 , 0x60 , 0xA2 , 0xF , 0x4C , 0x37 , 0xC4 , 0xA2 , 0x25 , 0xB4 , 0x4 , 0x84 , 0x70 , 0xB4 , 0x3 , 0x94 , 0x4 , 0xB4 , 0x2 , 0x94 , 0x3 , 0xB4 , 0x1 , 0x94 , 0x2 , 0xA4 , 0x68 , 0x94 , 0x1 , 0x69 , 0x8 , 0x30 , 0xE8 , 0xF0 , 0xE6 , 0xE9 , 0x8 , 0xA8 , 0xA5 , 0x70 , 0xB0 , 0x14 , 0x16 , 0x1 , 0x90 , 0x2 , 0xF6 , 0x1 , 0x76 , 0x1 , 0x76 , 0x1 , 0x76 , 0x2 , 0x76 , 0x3 , 0x76 , 0x4 , 0x6A , 0xC8 , 0xD0 , 0xEC , 0x18 , 0x60 , 0x81 , 0x0 , 0x0 , 0x0 , 0x0 , 0x3 , 0x7F , 0x5E , 0x56 , 0xCB , 0x79 , 0x80 , 0x13 , 0x9B , 0xB , 0x64 , 0x80 , 0x76 , 0x38 , 0x93 , 0x16 , 0x82 , 0x38 , 0xAA , 0x3B , 0x20 , 0x80 , 0x35 , 0x4 , 0xF3 , 0x34 , 0x81 , 0x35 , 0x4 , 0xF3 , 0x34 , 0x80 , 0x80 , 0x0 , 0x0 , 0x0 , 0x80 , 0x31 , 0x72 , 0x17 , 0xF8 , 0x20 , 0x2B , 0xDC , 0xF0 , 0x2 , 0x10 , 0x3 , 0x4C , 0x48 , 0xD2 , 0xA5 , 0x61 , 0xE9 , 0x7F , 0x48 , 0xA9 , 0x80 , 0x85 , 0x61 , 0xA9 , 0xD6 , 0xA0 , 0xD9 , 0x20 , 0x67 , 0xD8 , 0xA9 , 0xDB , 0xA0 , 0xD9 , 0x20 , 0xF , 0xDB , 0xA9 , 0xBC , 0xA0 , 0xD9 , 0x20 , 0x50 , 0xD8 , 0xA9 , 0xC1 , 0xA0 , 0xD9 , 0x20 , 0x40 , 0xE0 , 0xA9 , 0xE0 , 0xA0 , 0xD9 , 0x20 , 0x67 , 0xD8 , 0x68 , 0x20 , 0x7E , 0xDD , 0xA9 , 0xE5 , 0xA0 , 0xD9 , 0x20 , 0x8C , 0xDA , 0xD0 , 0x3 , 0x4C , 0x8B , 0xDA , 0x20 , 0xB7 , 0xDA , 0xA9 , 0x0 , 0x85 , 0x26 , 0x85 , 0x27 , 0x85 , 0x28 , 0x85 , 0x29 , 0xA5 , 0x70 , 0x20 , 0x59 , 0xDA , 0xA5 , 0x65 , 0x20 , 0x59 , 0xDA , 0xA5 , 0x64 , 0x20 , 0x59 , 0xDA , 0xA5 , 0x63 , 0x20 , 0x59 , 0xDA , 0xA5 , 0x62 , 0x20 , 0x5E , 0xDA , 0x4C , 0x8F , 0xDB , 0xD0 , 0x3 , 0x4C , 0x83 , 0xD9 , 0x4A , 0x9 , 0x80 , 0xA8 , 0x90 , 0x19 , 0x18 , 0xA5 , 0x29 , 0x65 , 0x6D , 0x85 , 0x29 , 0xA5 , 0x28 , 0x65 , 0x6C , 0x85 , 0x28 , 0xA5 , 0x27 , 0x65 , 0x6B , 0x85 , 0x27 , 0xA5 , 0x26 , 0x65 , 0x6A , 0x85 , 0x26 , 0x66 , 0x26 , 0x66 , 0x27 , 0x66 , 0x28 , 0x66 , 0x29 , 0x66 , 0x70 , 0x98 , 0x4A , 0xD0 , 0xD6 , 0x60 , 0x85 , 0x22 , 0x84 , 0x23 , 0xA0 , 0x4 , 0xB1 , 0x22 , 0x85 , 0x6D , 0x88 , 0xB1 , 0x22 , 0x85 , 0x6C , 0x88 , 0xB1 , 0x22 , 0x85 , 0x6B , 0x88 , 0xB1 , 0x22 , 0x85 , 0x6E , 0x45 , 0x66 , 0x85 , 0x6F , 0xA5 , 0x6E , 0x9 , 0x80 , 0x85 , 0x6A , 0x88 , 0xB1 , 0x22 , 0x85 , 0x69 , 0xA5 , 0x61 , 0x60 , 0xA5 , 0x69 , 0xF0 , 0x1F , 0x18 , 0x65 , 0x61 , 0x90 , 0x4 , 0x30 , 0x1D , 0x18 , 0x2C , 0x10 , 0x14 , 0x69 , 0x80 , 0x85 , 0x61 , 0xD0 , 0x3 , 0x4C , 0xFB , 0xD8 , 0xA5 , 0x6F , 0x85 , 0x66 , 0x60 , 0xA5 , 0x66 , 0x49 , 0xFF , 0x30 , 0x5 , 0x68 , 0x68 , 0x4C , 0xF7 , 0xD8 , 0x4C , 0x7E , 0xD9 , 0x20 , 0xC , 0xDC , 0xAA , 0xF0 , 0x10 , 0x18 , 0x69 , 0x2 , 0xB0 , 0xF2 , 0xA2 , 0x0 , 0x86 , 0x6F , 0x20 , 0x77 , 0xD8 , 0xE6 , 0x61 , 0xF0 , 0xE7 , 0x60 , 0x84 , 0x20 , 0x0 , 0x0 , 0x0 , 0x20 , 0xC , 0xDC , 0xA9 , 0xF9 , 0xA0 , 0xDA , 0xA2 , 0x0 , 0x86 , 0x6F , 0x20 , 0xA2 , 0xDB , 0x4C , 0x12 , 0xDB , 0x20 , 0x8C , 0xDA , 0xF0 , 0x76 , 0x20 , 0x1B , 0xDC , 0xA9 , 0x0 , 0x38 , 0xE5 , 0x61 , 0x85 , 0x61 , 0x20 , 0xB7 , 0xDA , 0xE6 , 0x61 , 0xF0 , 0xBA , 0xA2 , 0xFC , 0xA9 , 0x1 , 0xA4 , 0x6A , 0xC4 , 0x62 , 0xD0 , 0x10 , 0xA4 , 0x6B , 0xC4 , 0x63 , 0xD0 , 0xA , 0xA4 , 0x6C , 0xC4 , 0x64 , 0xD0 , 0x4 , 0xA4 , 0x6D , 0xC4 , 0x65 , 0x8 , 0x2A , 0x90 , 0x9 , 0xE8 , 0x95 , 0x29 , 0xF0 , 0x32 , 0x10 , 0x34 , 0xA9 , 0x1 , 0x28 , 0xB0 , 0xE , 0x6 , 0x6D , 0x26 , 0x6C , 0x26 , 0x6B , 0x26 , 0x6A , 0xB0 , 0xE6 , 0x30 , 0xCE , 0x10 , 0xE2 , 0xA8 , 0xA5 , 0x6D , 0xE5 , 0x65 , 0x85 , 0x6D , 0xA5 , 0x6C , 0xE5 , 0x64 , 0x85 , 0x6C , 0xA5 , 0x6B , 0xE5 , 0x63 , 0x85 , 0x6B , 0xA5 , 0x6A , 0xE5 , 0x62 , 0x85 , 0x6A , 0x98 , 0x4C , 0x4F , 0xDB , 0xA9 , 0x40 , 0xD0 , 0xCE , 0xA , 0xA , 0xA , 0xA , 0xA , 0xA , 0x85 , 0x70 , 0x28 , 0x4C , 0x8F , 0xDB , 0xA2 , 0x14 , 0x4C , 0x37 , 0xC4 , 0xA5 , 0x26 , 0x85 , 0x62 , 0xA5 , 0x27 , 0x85 , 0x63 , 0xA5 , 0x28 , 0x85 , 0x64 , 0xA5 , 0x29 , 0x85 , 0x65 , 0x4C , 0xD7 , 0xD8 , 0x85 , 0x22 , 0x84 , 0x23 , 0xA0 , 0x4 , 0xB1 , 0x22 , 0x85 , 0x65 , 0x88 , 0xB1 , 0x22 , 0x85 , 0x64 , 0x88 , 0xB1 , 0x22 , 0x85 , 0x63 , 0x88 , 0xB1 , 0x22 , 0x85 , 0x66 , 0x9 , 0x80 , 0x85 , 0x62 , 0x88 , 0xB1 , 0x22 , 0x85 , 0x61 , 0x84 , 0x70 , 0x60 , 0xA2 , 0x5C , 0x2C , 0xA2 , 0x57 , 0xA0 , 0x0 , 0xF0 , 0x4 , 0xA6 , 0x49 , 0xA4 , 0x4A , 0x20 , 0x1B , 0xDC , 0x86 , 0x22 , 0x84 , 0x23 , 0xA0 , 0x4 , 0xA5 , 0x65 , 0x91 , 0x22 , 0x88 , 0xA5 , 0x64 , 0x91 , 0x22 , 0x88 , 0xA5 , 0x63 , 0x91 , 0x22 , 0x88 , 0xA5 , 0x66 , 0x9 , 0x7F , 0x25 , 0x62 , 0x91 , 0x22 , 0x88 , 0xA5 , 0x61 , 0x91 , 0x22 , 0x84 , 0x70 , 0x60 , 0xA5 , 0x6E , 0x85 , 0x66 , 0xA2 , 0x5 , 0xB5 , 0x68 , 0x95 , 0x60 , 0xCA , 0xD0 , 0xF9 , 0x86 , 0x70 , 0x60 , 0x20 , 0x1B , 0xDC , 0xA2 , 0x6 , 0xB5 , 0x60 , 0x95 , 0x68 , 0xCA , 0xD0 , 0xF9 , 0x86 , 0x70 , 0x60 , 0xA5 , 0x61 , 0xF0 , 0xFB , 0x6 , 0x70 , 0x90 , 0xF7 , 0x20 , 0x6F , 0xD9 , 0xD0 , 0xF2 , 0x4C , 0x38 , 0xD9 , 0xA5 , 0x61 , 0xF0 , 0x9 , 0xA5 , 0x66 , 0x2A , 0xA9 , 0xFF , 0xB0 , 0x2 , 0xA9 , 0x1 , 0x60 , 0x20 , 0x2B , 0xDC , 0x85 , 0x62 , 0xA9 , 0x0 , 0x85 , 0x63 , 0xA2 , 0x88 , 0xA5 , 0x62 , 0x49 , 0xFF , 0x2A , 0xA9 , 0x0 , 0x85 , 0x65 , 0x85 , 0x64 , 0x86 , 0x61 , 0x85 , 0x70 , 0x85 , 0x66 , 0x4C , 0xD2 , 0xD8 , 0x46 , 0x66 , 0x60 , 0x85 , 0x24 , 0x84 , 0x25 , 0xA0 , 0x0 , 0xB1 , 0x24 , 0xC8 , 0xAA , 0xF0 , 0xC4 , 0xB1 , 0x24 , 0x45 , 0x66 , 0x30 , 0xC2 , 0xE4 , 0x61 , 0xD0 , 0x21 , 0xB1 , 0x24 , 0x9 , 0x80 , 0xC5 , 0x62 , 0xD0 , 0x19 , 0xC8 , 0xB1 , 0x24 , 0xC5 , 0x63 , 0xD0 , 0x12 , 0xC8 , 0xB1 , 0x24 , 0xC5 , 0x64 , 0xD0 , 0xB , 0xC8 , 0xA9 , 0x7F , 0xC5 , 0x70 , 0xB1 , 0x24 , 0xE5 , 0x65 , 0xF0 , 0x28 , 0xA5 , 0x66 , 0x90 , 0x2 , 0x49 , 0xFF , 0x4C , 0x31 , 0xDC , 0xA5 , 0x61 , 0xF0 , 0x4A , 0x38 , 0xE9 , 0xA0 , 0x24 , 0x66 , 0x10 , 0x9 , 0xAA , 0xA9 , 0xFF , 0x85 , 0x68 , 0x20 , 0x4D , 0xD9 , 0x8A , 0xA2 , 0x61 , 0xC9 , 0xF9 , 0x10 , 0x6 , 0x20 , 0x99 , 0xD9 , 0x84 , 0x68 , 0x60 , 0xA8 , 0xA5 , 0x66 , 0x29 , 0x80 , 0x46 , 0x62 , 0x5 , 0x62 , 0x85 , 0x62 , 0x20 , 0xB0 , 0xD9 , 0x84 , 0x68 , 0x60 , 0xA5 , 0x61 , 0xC9 , 0xA0 , 0xB0 , 0x20 , 0x20 , 0x9B , 0xDC , 0x84 , 0x70 , 0xA5 , 0x66 , 0x84 , 0x66 , 0x49 , 0x80 , 0x2A , 0xA9 , 0xA0 , 0x85 , 0x61 , 0xA5 , 0x65 , 0x85 , 0x7 , 0x4C , 0xD2 , 0xD8 , 0x85 , 0x62 , 0x85 , 0x63 , 0x85 , 0x64 , 0x85 , 0x65 , 0xA8 , 0x60 , 0xA0 , 0x0 , 0xA2 , 0xA , 0x94 , 0x5D , 0xCA , 0x10 , 0xFB , 0x90 , 0xF , 0xC9 , 0x2D , 0xD0 , 0x4 , 0x86 , 0x67 , 0xF0 , 0x4 , 0xC9 , 0x2B , 0xD0 , 0x5 , 0x20 , 0x73 , 0x0 , 0x90 , 0x5B , 0xC9 , 0x2E , 0xF0 , 0x2E , 0xC9 , 0x45 , 0xD0 , 0x30 , 0x20 , 0x73 , 0x0 , 0x90 , 0x17 , 0xC9 , 0xAB , 0xF0 , 0xE , 0xC9 , 0x2D , 0xF0 , 0xA , 0xC9 , 0xAA , 0xF0 , 0x8 , 0xC9 , 0x2B , 0xF0 , 0x4 , 0xD0 , 0x7 , 0x66 , 0x60 , 0x20 , 0x73 , 0x0 , 0x90 , 0x5C , 0x24 , 0x60 , 0x10 , 0xE , 0xA9 , 0x0 , 0x38 , 0xE5 , 0x5E , 0x4C , 0x49 , 0xDD , 0x66 , 0x5F , 0x24 , 0x5F , 0x50 , 0xC3 , 0xA5 , 0x5E , 0x38 , 0xE5 , 0x5D , 0x85 , 0x5E , 0xF0 , 0x12 , 0x10 , 0x9 , 0x20 , 0xFE , 0xDA , 0xE6 , 0x5E , 0xD0 , 0xF9 , 0xF0 , 0x7 , 0x20 , 0xE2 , 0xDA , 0xC6 , 0x5E , 0xD0 , 0xF9 , 0xA5 , 0x67 , 0x30 , 0x1 , 0x60 , 0x4C , 0xB4 , 0xDF , 0x48 , 0x24 , 0x5F , 0x10 , 0x2 , 0xE6 , 0x5D , 0x20 , 0xE2 , 0xDA , 0x68 , 0x38 , 0xE9 , 0x30 , 0x20 , 0x7E , 0xDD , 0x4C , 0xA , 0xDD , 0x48 , 0x20 , 0xC , 0xDC , 0x68 , 0x20 , 0x3C , 0xDC , 0xA5 , 0x6E , 0x45 , 0x66 , 0x85 , 0x6F , 0xA6 , 0x61 , 0x4C , 0x6A , 0xD8 , 0xA5 , 0x5E , 0xC9 , 0xA , 0x90 , 0x9 , 0xA9 , 0x64 , 0x24 , 0x60 , 0x30 , 0x11 , 0x4C , 0x7E , 0xD9 , 0xA , 0xA , 0x18 , 0x65 , 0x5E , 0xA , 0x18 , 0xA0 , 0x0 , 0x71 , 0x7A , 0x38 , 0xE9 , 0x30 , 0x85 , 0x5E , 0x4C , 0x30 , 0xDD , 0x9B , 0x3E , 0xBC , 0x1F , 0xFD , 0x9E , 0x6E , 0x6B , 0x27 , 0xFD , 0x9E , 0x6E , 0x6B , 0x28 , 0x0 , 0xA9 , 0x71 , 0xA0 , 0xC3 , 0x20 , 0xDA , 0xDD , 0xA5 , 0x3A , 0xA6 , 0x39 , 0x85 , 0x62 , 0x86 , 0x63 , 0xA2 , 0x90 , 0x38 , 0x20 , 0x49 , 0xDC , 0x20 , 0xDF , 0xDD , 0x4C , 0x1E , 0xCB , 0xA0 , 0x1 , 0xA9 , 0x20 , 0x24 , 0x66 , 0x10 , 0x2 , 0xA9 , 0x2D , 0x99 , 0xFF , 0x0 , 0x85 , 0x66 , 0x84 , 0x71 , 0xC8 , 0xA9 , 0x30 , 0xA6 , 0x61 , 0xD0 , 0x3 , 0x4C , 0x4 , 0xDF , 0xA9 , 0x0 , 0xE0 , 0x80 , 0xF0 , 0x2 , 0xB0 , 0x9 , 0xA9 , 0xBD , 0xA0 , 0xDD , 0x20 , 0x28 , 0xDA , 0xA9 , 0xF7 , 0x85 , 0x5D , 0xA9 , 0xB8 , 0xA0 , 0xDD , 0x20 , 0x5B , 0xDC , 0xF0 , 0x1E , 0x10 , 0x12 , 0xA9 , 0xB3 , 0xA0 , 0xDD , 0x20 , 0x5B , 0xDC , 0xF0 , 0x2 , 0x10 , 0xE , 0x20 , 0xE2 , 0xDA , 0xC6 , 0x5D , 0xD0 , 0xEE , 0x20 , 0xFE , 0xDA , 0xE6 , 0x5D , 0xD0 , 0xDC , 0x20 , 0x49 , 0xD8 , 0x20 , 0x9B , 0xDC , 0xA2 , 0x1 , 0xA5 , 0x5D , 0x18 , 0x69 , 0xA , 0x30 , 0x9 , 0xC9 , 0xB , 0xB0 , 0x6 , 0x69 , 0xFF , 0xAA , 0xA9 , 0x2 , 0x38 , 0xE9 , 0x2 , 0x85 , 0x5E , 0x86 , 0x5D , 0x8A , 0xF0 , 0x2 , 0x10 , 0x13 , 0xA4 , 0x71 , 0xA9 , 0x2E , 0xC8 , 0x99 , 0xFF , 0x0 , 0x8A , 0xF0 , 0x6 , 0xA9 , 0x30 , 0xC8 , 0x99 , 0xFF , 0x0 , 0x84 , 0x71 , 0xA0 , 0x0 , 0xA2 , 0x80 , 0xA5 , 0x65 , 0x18 , 0x79 , 0x19 , 0xDF , 0x85 , 0x65 , 0xA5 , 0x64 , 0x79 , 0x18 , 0xDF , 0x85 , 0x64 , 0xA5 , 0x63 , 0x79 , 0x17 , 0xDF , 0x85 , 0x63 , 0xA5 , 0x62 , 0x79 , 0x16 , 0xDF , 0x85 , 0x62 , 0xE8 , 0xB0 , 0x4 , 0x10 , 0xDE , 0x30 , 0x2 , 0x30 , 0xDA , 0x8A , 0x90 , 0x4 , 0x49 , 0xFF , 0x69 , 0xA , 0x69 , 0x2F , 0xC8 , 0xC8 , 0xC8 , 0xC8 , 0x84 , 0x47 , 0xA4 , 0x71 , 0xC8 , 0xAA , 0x29 , 0x7F , 0x99 , 0xFF , 0x0 , 0xC6 , 0x5D , 0xD0 , 0x6 , 0xA9 , 0x2E , 0xC8 , 0x99 , 0xFF , 0x0 , 0x84 , 0x71 , 0xA4 , 0x47 , 0x8A , 0x49 , 0xFF , 0x29 , 0x80 , 0xAA , 0xC0 , 0x24 , 0xF0 , 0x4 , 0xC0 , 0x3C , 0xD0 , 0xA6 , 0xA4 , 0x71 , 0xB9 , 0xFF , 0x0 , 0x88 , 0xC9 , 0x30 , 0xF0 , 0xF8 , 0xC9 , 0x2E , 0xF0 , 0x1 , 0xC8 , 0xA9 , 0x2B , 0xA6 , 0x5E , 0xF0 , 0x2E , 0x10 , 0x8 , 0xA9 , 0x0 , 0x38 , 0xE5 , 0x5E , 0xAA , 0xA9 , 0x2D , 0x99 , 0x1 , 0x1 , 0xA9 , 0x45 , 0x99 , 0x0 , 0x1 , 0x8A , 0xA2 , 0x2F , 0x38 , 0xE8 , 0xE9 , 0xA , 0xB0 , 0xFB , 0x69 , 0x3A , 0x99 , 0x3 , 0x1 , 0x8A , 0x99 , 0x2 , 0x1 , 0xA9 , 0x0 , 0x99 , 0x4 , 0x1 , 0xF0 , 0x8 , 0x99 , 0xFF , 0x0 , 0xA9 , 0x0 , 0x99 , 0x0 , 0x1 , 0xA9 , 0x0 , 0xA0 , 0x1 , 0x60 , 0x80 , 0x0 , 0x0 , 0x0 , 0x0 , 0xFA , 0xA , 0x1F , 0x0 , 0x0 , 0x98 , 0x96 , 0x80 , 0xFF , 0xF0 , 0xBD , 0xC0 , 0x0 , 0x1 , 0x86 , 0xA0 , 0xFF , 0xFF , 0xD8 , 0xF0 , 0x0 , 0x0 , 0x3 , 0xE8 , 0xFF , 0xFF , 0xFF , 0x9C , 0x0 , 0x0 , 0x0 , 0xA , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xDF , 0xA , 0x80 , 0x0 , 0x3 , 0x4B , 0xC0 , 0xFF , 0xFF , 0x73 , 0x60 , 0x0 , 0x0 , 0xE , 0x10 , 0xFF , 0xFF , 0xFD , 0xA8 , 0x0 , 0x0 , 0x0 , 0x3C , 0xBF , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0x20 , 0xC , 0xDC , 0xA9 , 0x11 , 0xA0 , 0xDF , 0x20 , 0xA2 , 0xDB , 0xF0 , 0x70 , 0xA5 , 0x69 , 0xD0 , 0x3 , 0x4C , 0xF9 , 0xD8 , 0xA2 , 0x4E , 0xA0 , 0x0 , 0x20 , 0xD4 , 0xDB , 0xA5 , 0x6E , 0x10 , 0xF , 0x20 , 0xCC , 0xDC , 0xA9 , 0x4E , 0xA0 , 0x0 , 0x20 , 0x5B , 0xDC , 0xD0 , 0x3 , 0x98 , 0xA4 , 0x7 , 0x20 , 0xFE , 0xDB , 0x98 , 0x48 , 0x20 , 0xEA , 0xD9 , 0xA9 , 0x4E , 0xA0 , 0x0 , 0x20 , 0x28 , 0xDA , 0x20 , 0xED , 0xDF , 0x68 , 0x4A , 0x90 , 0xA , 0xA5 , 0x61 , 0xF0 , 0x6 , 0xA5 , 0x66 , 0x49 , 0xFF , 0x85 , 0x66 , 0x60 , 0x81 , 0x38 , 0xAA , 0x3B , 0x29 , 0x7 , 0x71 , 0x34 , 0x58 , 0x3E , 0x56 , 0x74 , 0x16 , 0x7E , 0xB3 , 0x1B , 0x77 , 0x2F , 0xEE , 0xE3 , 0x85 , 0x7A , 0x1D , 0x84 , 0x1C , 0x2A , 0x7C , 0x63 , 0x59 , 0x58 , 0xA , 0x7E , 0x75 , 0xFD , 0xE7 , 0xC6 , 0x80 , 0x31 , 0x72 , 0x18 , 0x10 , 0x81 , 0x0 , 0x0 , 0x0 , 0x0 , 0xA9 , 0xBF , 0xA0 , 0xDF , 0x20 , 0x28 , 0xDA , 0xA5 , 0x70 , 0x69 , 0x50 , 0x90 , 0x3 , 0x20 , 0x23 , 0xDC , 0x85 , 0x56 , 0x20 , 0xF , 0xDC , 0xA5 , 0x61 , 0xC9 , 0x88 , 0x90 , 0x3 , 0x20 , 0xD4 , 0xDA , 0x20 , 0xCC , 0xDC , 0xA5 , 0x7 , 0x18 , 0x69 , 0x81 , 0xF0 , 0xF3 , 0x38 , 0xE9 , 0x1 , 0x48 , 0xA2 , 0x5 , 0xB5 , 0x69 , 0xB4 , 0x61 , 0x95 , 0x61 , 0x94 , 0x69 , 0xCA , 0x10 , 0xF5 , 0xA5 , 0x56 , 0x85 , 0x70 , 0x20 , 0x53 , 0xD8 , 0x20 , 0xB4 , 0xDF , 0xA9 , 0xC4 , 0xA0 , 0xDF , 0x20 , 0x56 , 0xE0 , 0xA9 , 0x0 , 0x85 , 0x6F , 0x68 , 0x20 , 0xB9 , 0xDA , 0x60 , 0x85 , 0x71 , 0x84 , 0x72 , 0x20 , 0xCA , 0xDB , 0xA9 , 0x57 , 0x20 , 0x28 , 0xDA , 0x20 , 0x5A , 0xE0 , 0xA9 , 0x57 , 0xA0 , 0x0 , 0x4C , 0x28 , 0xDA , 0x85 , 0x71 , 0x84 , 0x72 , 0x20 , 0xC7 , 0xDB , 0xB1 , 0x71 , 0x85 , 0x67 , 0xA4 , 0x71 , 0xC8 , 0x98 , 0xD0 , 0x2 , 0xE6 , 0x72 , 0x85 , 0x71 , 0xA4 , 0x72 , 0x20 , 0x28 , 0xDA , 0xA5 , 0x71 , 0xA4 , 0x72 , 0x18 , 0x69 , 0x5 , 0x90 , 0x1 , 0xC8 , 0x85 , 0x71 , 0x84 , 0x72 , 0x20 , 0x67 , 0xD8 , 0xA9 , 0x5C , 0xA0 , 0x0 , 0xC6 , 0x67 , 0xD0 , 0xE4 , 0x60 , 0x98 , 0x35 , 0x44 , 0x7A , 0x0 , 0x68 , 0x28 , 0xB1 , 0x46 , 0x0 , 0x20 , 0x2B , 0xDC , 0x30 , 0x37 , 0xD0 , 0x20 , 0x20 , 0xF3 , 0xFF , 0x86 , 0x22 , 0x84 , 0x23 , 0xA0 , 0x4 , 0xB1 , 0x22 , 0x85 , 0x62 , 0xC8 , 0xB1 , 0x22 , 0x85 , 0x64 , 0xA0 , 0x8 , 0xB1 , 0x22 , 0x85 , 0x63 , 0xC8 , 0xB1 , 0x22 , 0x85 , 0x65 , 0x4C , 0xE0 , 0xE0 , 0xA9 , 0x8B , 0xA0 , 0x0 , 0x20 , 0xA2 , 0xDB , 0xA9 , 0x8A , 0xA0 , 0xE0 , 0x20 , 0x28 , 0xDA , 0xA9 , 0x8F , 0xA0 , 0xE0 , 0x20 , 0x67 , 0xD8 , 0xA6 , 0x65 , 0xA5 , 0x62 , 0x85 , 0x65 , 0x86 , 0x62 , 0xA6 , 0x63 , 0xA5 , 0x64 , 0x85 , 0x63 , 0x86 , 0x64 , 0xA9 , 0x0 , 0x85 , 0x66 , 0xA5 , 0x61 , 0x85 , 0x70 , 0xA9 , 0x80 , 0x85 , 0x61 , 0x20 , 0xD7 , 0xD8 , 0xA2 , 0x8B , 0xA0 , 0x0 , 0x4C , 0xD4 , 0xDB , 0xC9 , 0xF0 , 0xD0 , 0x7 , 0x84 , 0x38 , 0x86 , 0x37 , 0x4C , 0x63 , 0xC6 , 0xAA , 0xD0 , 0x2 , 0xA2 , 0x1E , 0x4C , 0x37 , 0xC4 , 0x20 , 0xD2 , 0xFF , 0xB0 , 0xE8 , 0x60 , 0x20 , 0xCF , 0xFF , 0xB0 , 0xE2 , 0x60 , 0x20 , 0xC9 , 0xFF , 0xB0 , 0xDC , 0x60 , 0x20 , 0xC6 , 0xFF , 0xB0 , 0xD6 , 0x60 , 0x20 , 0xE4 , 0xFF , 0xB0 , 0xD0 , 0x60 , 0x20 , 0x8A , 0xCD , 0x20 , 0xF7 , 0xD7 , 0xA9 , 0xE1 , 0x48 , 0xA9 , 0x43 , 0x48 , 0xAD , 0xF , 0x3 , 0x48 , 0xAD , 0xC , 0x3 , 0xAE , 0xD , 0x3 , 0xAC , 0xE , 0x3 , 0x28 , 0x6C , 0x14 , 0x0 , 0x8 , 0x8D , 0xC , 0x3 , 0x8E , 0xD , 0x3 , 0x8C , 0xE , 0x3 , 0x68 , 0x8D , 0xF , 0x3 , 0x60 , 0x20 , 0xD1 , 0xE1 , 0xA6 , 0x2D , 0xA4 , 0x2E , 0xA9 , 0x2B , 0x20 , 0xD8 , 0xFF , 0xB0 , 0x95 , 0x60 , 0xA9 , 0x1 , 0x2C , 0xA9 , 0x0 , 0x85 , 0xA , 0x20 , 0xD1 , 0xE1 , 0xA5 , 0xA , 0xA6 , 0x2B , 0xA4 , 0x2C , 0x20 , 0xD5 , 0xFF , 0xB0 , 0x57 , 0xA5 , 0xA , 0xF0 , 0x1A , 0xA2 , 0x1C , 0x20 , 0xB7 , 0xFF , 0x29 , 0x10 , 0xF0 , 0x3 , 0x4C , 0x37 , 0xC4 , 0xA5 , 0x7A , 0xC9 , 0x2 , 0xF0 , 0x7 , 0xA9 , 0x64 , 0xA0 , 0xC3 , 0x4C , 0x1E , 0xCB , 0x60 , 0x20 , 0xB7 , 0xFF , 0x29 , 0xBF , 0xF0 , 0x5 , 0xA2 , 0x1D , 0x4C , 0x37 , 0xC4 , 0xA5 , 0x7B , 0xC9 , 0x2 , 0xD0 , 0xE , 0x86 , 0x2D , 0x84 , 0x2E , 0xA9 , 0x76 , 0xA0 , 0xC3 , 0x20 , 0x1E , 0xCB , 0x4C , 0x2A , 0xC5 , 0x20 , 0x8E , 0xC6 , 0x4C , 0x76 , 0xE4 , 0x20 , 0x16 , 0xE2 , 0x20 , 0xC0 , 0xFF , 0xB0 , 0xB , 0x60 , 0x20 , 0x16 , 0xE2 , 0xA5 , 0x49 , 0x20 , 0xC3 , 0xFF , 0x90 , 0xC6 , 0x4C , 0xF6 , 0xE0 , 0xA9 , 0x0 , 0x20 , 0xBD , 0xFF , 0xA2 , 0x1 , 0xA0 , 0x0 , 0x20 , 0xBA , 0xFF , 0x20 , 0x3 , 0xE2 , 0x20 , 0x54 , 0xE2 , 0x20 , 0x3 , 0xE2 , 0x20 , 0xFD , 0xE1 , 0xA0 , 0x0 , 0x86 , 0x49 , 0x20 , 0xBA , 0xFF , 0x20 , 0x3 , 0xE2 , 0x20 , 0xFD , 0xE1 , 0x8A , 0xA8 , 0xA6 , 0x49 , 0x4C , 0xBA , 0xFF , 0x20 , 0xB , 0xE2 , 0x4C , 0x9E , 0xD7 , 0x20 , 0x79 , 0x0 , 0xD0 , 0x2 , 0x68 , 0x68 , 0x60 , 0x20 , 0xFD , 0xCE , 0x20 , 0x79 , 0x0 , 0xD0 , 0xF7 , 0x4C , 0x8 , 0xCF , 0xA9 , 0x0 , 0x20 , 0xBD , 0xFF , 0x20 , 0xE , 0xE2 , 0x20 , 0x9E , 0xD7 , 0x86 , 0x49 , 0x8A , 0xA2 , 0x1 , 0xA0 , 0x0 , 0x20 , 0xBA , 0xFF , 0x20 , 0x3 , 0xE2 , 0x20 , 0xFD , 0xE1 , 0x86 , 0x4A , 0xA0 , 0x0 , 0xA5 , 0x49 , 0xE0 , 0x3 , 0x90 , 0x1 , 0x88 , 0x20 , 0xBA , 0xFF , 0x20 , 0x3 , 0xE2 , 0x20 , 0xFD , 0xE1 , 0x8A , 0xA8 , 0xA6 , 0x4A , 0xA5 , 0x49 , 0x20 , 0xBA , 0xFF , 0x20 , 0x3 , 0xE2 , 0x20 , 0xB , 0xE2 , 0x20 , 0x9E , 0xCD , 0x20 , 0xA3 , 0xD6 , 0xA6 , 0x22 , 0xA4 , 0x23 , 0x4C , 0xBD , 0xFF , 0xA9 , 0xDD , 0xA0 , 0xE2 , 0x20 , 0x67 , 0xD8 , 0x20 , 0xC , 0xDC , 0xA9 , 0xE2 , 0xA0 , 0xE2 , 0xA6 , 0x6E , 0x20 , 0x7 , 0xDB , 0x20 , 0xC , 0xDC , 0x20 , 0xCC , 0xDC , 0xA9 , 0x0 , 0x85 , 0x6F , 0x20 , 0x53 , 0xD8 , 0xA9 , 0xE7 , 0xA0 , 0xE2 , 0x20 , 0x50 , 0xD8 , 0xA5 , 0x66 , 0x48 , 0x10 , 0xD , 0x20 , 0x49 , 0xD8 , 0xA5 , 0x66 , 0x30 , 0x9 , 0xA5 , 0x12 , 0x49 , 0xFF , 0x85 , 0x12 , 0x20 , 0xB4 , 0xDF , 0xA9 , 0xE7 , 0xA0 , 0xE2 , 0x20 , 0x67 , 0xD8 , 0x68 , 0x10 , 0x3 , 0x20 , 0xB4 , 0xDF , 0xA9 , 0xEC , 0xA0 , 0xE2 , 0x4C , 0x40 , 0xE0 , 0x20 , 0xCA , 0xDB , 0xA9 , 0x0 , 0x85 , 0x12 , 0x20 , 0x68 , 0xE2 , 0xA2 , 0x4E , 0xA0 , 0x0 , 0x20 , 0xF3 , 0xE0 , 0xA9 , 0x57 , 0xA0 , 0x0 , 0x20 , 0xA2 , 0xDB , 0xA9 , 0x0 , 0x85 , 0x66 , 0xA5 , 0x12 , 0x20 , 0xD9 , 0xE2 , 0xA9 , 0x4E , 0xA0 , 0x0 , 0x4C , 0xF , 0xDB , 0x48 , 0x4C , 0x9A , 0xE2 , 0x81 , 0x49 , 0xF , 0xDA , 0xA2 , 0x83 , 0x49 , 0xF , 0xDA , 0xA2 , 0x7F , 0x0 , 0x0 , 0x0 , 0x0 , 0x5 , 0x84 , 0xE6 , 0x1A , 0x2D , 0x1B , 0x86 , 0x28 , 0x7 , 0xFB , 0xF8 , 0x87 , 0x99 , 0x68 , 0x89 , 0x1 , 0x87 , 0x23 , 0x35 , 0xDF , 0xE1 , 0x86 , 0xA5 , 0x5D , 0xE7 , 0x28 , 0x83 , 0x49 , 0xF , 0xDA , 0xA2 , 0xA5 , 0x66 , 0x48 , 0x10 , 0x3 , 0x20 , 0xB4 , 0xDF , 0xA5 , 0x61 , 0x48 , 0xC9 , 0x81 , 0x90 , 0x7 , 0xA9 , 0xBC , 0xA0 , 0xD9 , 0x20 , 0xF , 0xDB , 0xA9 , 0x3B , 0xA0 , 0xE3 , 0x20 , 0x40 , 0xE0 , 0x68 , 0xC9 , 0x81 , 0x90 , 0x7 , 0xA9 , 0xDD , 0xA0 , 0xE2 , 0x20 , 0x50 , 0xD8 , 0x68 , 0x10 , 0x3 , 0x4C , 0xB4 , 0xDF , 0x60 , 0xB , 0x76 , 0xB3 , 0x83 , 0xBD , 0xD3 , 0x79 , 0x1E , 0xF4 , 0xA6 , 0xF5 , 0x7B , 0x83 , 0xFC , 0xB0 , 0x10 , 0x7C , 0xC , 0x1F , 0x67 , 0xCA , 0x7C , 0xDE , 0x53 , 0xCB , 0xC1 , 0x7D , 0x14 , 0x64 , 0x70 , 0x4C , 0x7D , 0xB7 , 0xEA , 0x51 , 0x7A , 0x7D , 0x63 , 0x30 , 0x88 , 0x7E , 0x7E , 0x92 , 0x44 , 0x99 , 0x3A , 0x7E , 0x4C , 0xCC , 0x91 , 0xC7 , 0x7F , 0xAA , 0xAA , 0xAA , 0x13 , 0x81 , 0x0 , 0x0 , 0x0 , 0x0 , 0x20 , 0x5B , 0xE4 , 0x20 , 0xA4 , 0xE3 , 0x20 , 0x4 , 0xE4 , 0xA2 , 0xFB , 0x9A , 0x4C , 0x74 , 0xC4 , 0xE6 , 0x7A , 0xD0 , 0x2 , 0xE6 , 0x7B , 0xAD , 0x60 , 0xEA , 0xC9 , 0x3A , 0xB0 , 0xA , 0xC9 , 0x20 , 0xF0 , 0xEF , 0x38 , 0xE9 , 0x30 , 0x38 , 0xE9 , 0xD0 , 0x60 , 0x80 , 0x4F , 0xC7 , 0x52 , 0x58 , 0xA9 , 0x4C , 0x85 , 0x54 , 0x85 , 0x0 , 0xA9 , 0x48 , 0xA0 , 0xD2 , 0x85 , 0x1 , 0x84 , 0x2 , 0xA9 , 0x91 , 0xA0 , 0xD3 , 0x85 , 0x5 , 0x84 , 0x6 , 0xA9 , 0xAA , 0xA0 , 0xD1 , 0x85 , 0x3 , 0x84 , 0x4 , 0xA2 , 0x1C , 0xBD , 0x87 , 0xE3 , 0x95 , 0x73 , 0xCA , 0x10 , 0xF8 , 0xA9 , 0x3 , 0x85 , 0x53 , 0xA9 , 0x0 , 0x85 , 0x68 , 0x85 , 0x13 , 0x85 , 0x18 , 0xA2 , 0x1 , 0x8E , 0xFD , 0x1 , 0x8E , 0xFC , 0x1 , 0xA2 , 0x19 , 0x86 , 0x16 , 0x38 , 0x20 , 0x9C , 0xFF , 0x86 , 0x2B , 0x84 , 0x2C , 0x38 , 0x20 , 0x99 , 0xFF , 0x86 , 0x37 , 0x84 , 0x38 , 0x86 , 0x33 , 0x84 , 0x34 , 0xA0 , 0x0 , 0x98 , 0x91 , 0x2B , 0xE6 , 0x2B , 0xD0 , 0x2 , 0xE6 , 0x2C , 0x60 , 0xA5 , 0x2B , 0xA4 , 0x2C , 0x20 , 0x8 , 0xC4 , 0xA9 , 0x36 , 0xA0 , 0xE4 , 0x20 , 0x1E , 0xCB , 0xA5 , 0x37 , 0x38 , 0xE5 , 0x2B , 0xAA , 0xA5 , 0x38 , 0xE5 , 0x2C , 0x20 , 0xCD , 0xDD , 0xA9 , 0x29 , 0xA0 , 0xE4 , 0x20 , 0x1E , 0xCB , 0x4C , 0x44 , 0xC6 , 0x20 , 0x42 , 0x59 , 0x54 , 0x45 , 0x53 , 0x20 , 0x46 , 0x52 , 0x45 , 0x45 , 0xD , 0x0 , 0x93 , 0x2A , 0x2A , 0x2A , 0x2A , 0x20 , 0x43 , 0x42 , 0x4D , 0x20 , 0x42 , 0x41 , 0x53 , 0x49 , 0x43 , 0x20 , 0x56 , 0x32 , 0x20 , 0x2A , 0x2A , 0x2A , 0x2A , 0xD , 0x0 , 0x3A , 0xC4 , 0x83 , 0xC4 , 0x7C , 0xC5 , 0x1A , 0xC7 , 0xE4 , 0xC7 , 0x86 , 0xCE , 0xA2 , 0xB , 0xBD , 0x4F , 0xE4 , 0x9D , 0x0 , 0x3 , 0xCA , 0x10 , 0xF7 , 0x60 , 0x20 , 0xCC , 0xFF , 0xA9 , 0x0 , 0x85 , 0x13 , 0x20 , 0x7A , 0xC6 , 0x58 , 0x4C , 0x74 , 0xC4 , 0xFE , 0x20 , 0x33 , 0xC5 , 0x4C , 0x77 , 0xC6 , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAD , 0x2C , 0x91 , 0x29 , 0xDF , 0x8D , 0x2C , 0x91 , 0x60 , 0xAD , 0x2C , 0x91 , 0x9 , 0x20 , 0x8D , 0x2C , 0x91 , 0x60 , 0xAD , 0x1F , 0x91 , 0xCD , 0x1F , 0x91 , 0xD0 , 0xF8 , 0x4A , 0x60 , 0xA6 , 0xB9 , 0x4C , 0x47 , 0xF6 , 0x8A , 0xD0 , 0x8 , 0xA5 , 0xC3 , 0x85 , 0xAE , 0xA5 , 0xC4 , 0x85 , 0xAF , 0x4C , 0x6A , 0xF6 , 0xAA , 0x38 , 0x2E , 0x20 , 0x91 , 0xAD , 0x21 , 0x91 , 0x6E , 0x20 , 0x91 , 0x29 , 0x40 , 0xF0 , 0x3 , 0x86 , 0x91 , 0x60 , 0x8A , 0x29 , 0xFD , 0x85 , 0x91 , 0x60 , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xA2 , 0x10 , 0xA0 , 0x91 , 0x60 , 0xA2 , 0x16 , 0xA0 , 0x17 , 0x60 , 0xB0 , 0x7 , 0x86 , 0xD6 , 0x84 , 0xD3 , 0x20 , 0x87 , 0xE5 , 0xA6 , 0xD6 , 0xA4 , 0xD3 , 0x60 , 0x20 , 0xBB , 0xE5 , 0xAD , 0x88 , 0x2 , 0x29 , 0xFD , 0xA , 0xA , 0x9 , 0x80 , 0x8D , 0x5 , 0x90 , 0xAD , 0x88 , 0x2 , 0x29 , 0x2 , 0xF0 , 0x8 , 0xA9 , 0x80 , 0xD , 0x2 , 0x90 , 0x8D , 0x2 , 0x90 , 0xA9 , 0x0 , 0x8D , 0x91 , 0x2 , 0x85 , 0xCF , 0xA9 , 0xDC , 0x8D , 0x8F , 0x2 , 0xA9 , 0xEB , 0x8D , 0x90 , 0x2 , 0xA9 , 0xA , 0x8D , 0x89 , 0x2 , 0x8D , 0x8C , 0x2 , 0xA9 , 0x6 , 0x8D , 0x86 , 0x2 , 0xA9 , 0x4 , 0x8D , 0x8B , 0x2 , 0xA9 , 0xC , 0x85 , 0xCD , 0x85 , 0xCC , 0xAD , 0x88 , 0x2 , 0x9 , 0x80 , 0xA8 , 0xA9 , 0x0 , 0xAA , 0x94 , 0xD9 , 0x18 , 0x69 , 0x16 , 0x90 , 0x1 , 0xC8 , 0xE8 , 0xE0 , 0x18 , 0xD0 , 0xF3 , 0xA9 , 0xFF , 0x95 , 0xD9 , 0xA2 , 0x16 , 0x20 , 0x8D , 0xEA , 0xCA , 0x10 , 0xFA , 0xA0 , 0x0 , 0x84 , 0xD3 , 0x84 , 0xD6 , 0xA6 , 0xD6 , 0xA5 , 0xD3 , 0xB4 , 0xD9 , 0x30 , 0x8 , 0x18 , 0x69 , 0x16 , 0x85 , 0xD3 , 0xCA , 0x10 , 0xF4 , 0xB5 , 0xD9 , 0x29 , 0x3 , 0xD , 0x88 , 0x2 , 0x85 , 0xD2 , 0xBD , 0xFD , 0xED , 0x85 , 0xD1 , 0xA9 , 0x15 , 0xE8 , 0xB4 , 0xD9 , 0x30 , 0x6 , 0x18 , 0x69 , 0x16 , 0xE8 , 0x10 , 0xF6 , 0x85 , 0xD5 , 0x60 , 0x20 , 0xBB , 0xE5 , 0x4C , 0x81 , 0xE5 , 0xA9 , 0x3 , 0x85 , 0x9A , 0xA9 , 0x0 , 0x85 , 0x99 , 0xA2 , 0x10 , 0xBD , 0xE3 , 0xED , 0x9D , 0xFF , 0x8F , 0xCA , 0xD0 , 0xF7 , 0x60 , 0xAC , 0x77 , 0x2 , 0xA2 , 0x0 , 0xBD , 0x78 , 0x2 , 0x9D , 0x77 , 0x2 , 0xE8 , 0xE4 , 0xC6 , 0xD0 , 0xF5 , 0xC6 , 0xC6 , 0x98 , 0x58 , 0x18 , 0x60 , 0x20 , 0x42 , 0xE7 , 0xA5 , 0xC6 , 0x85 , 0xCC , 0x8D , 0x92 , 0x2 , 0xF0 , 0xF7 , 0x78 , 0xA5 , 0xCF , 0xF0 , 0xC , 0xA5 , 0xCE , 0xAE , 0x87 , 0x2 , 0xA0 , 0x0 , 0x84 , 0xCF , 0x20 , 0xA1 , 0xEA , 0x20 , 0xCF , 0xE5 , 0xC9 , 0x83 , 0xD0 , 0x10 , 0xA2 , 0x9 , 0x78 , 0x86 , 0xC6 , 0xBD , 0xF3 , 0xED , 0x9D , 0x76 , 0x2 , 0xCA , 0xD0 , 0xF7 , 0xF0 , 0xCF , 0xC9 , 0xD , 0xD0 , 0xC8 , 0xA4 , 0xD5 , 0x84 , 0xD0 , 0xB1 , 0xD1 , 0xC9 , 0x20 , 0xD0 , 0x3 , 0x88 , 0xD0 , 0xF7 , 0xC8 , 0x84 , 0xC8 , 0xA0 , 0x0 , 0x8C , 0x92 , 0x2 , 0x84 , 0xD3 , 0x84 , 0xD4 , 0xA5 , 0xC9 , 0x30 , 0x1D , 0xA6 , 0xD6 , 0x20 , 0x19 , 0xE7 , 0xE4 , 0xC9 , 0xD0 , 0x14 , 0xD0 , 0x12 , 0xA5 , 0xCA , 0x85 , 0xD3 , 0xC5 , 0xC8 , 0x90 , 0xA , 0xB0 , 0x42 , 0x98 , 0x48 , 0x8A , 0x48 , 0xA5 , 0xD0 , 0xF0 , 0x91 , 0xA4 , 0xD3 , 0xB1 , 0xD1 , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0x85 , 0xD7 , 0x29 , 0x3F , 0x6 , 0xD7 , 0x24 , 0xD7 , 0x10 , 0x2 , 0x9 , 0x80 , 0x90 , 0x4 , 0xA6 , 0xD4 , 0xD0 , 0x4 , 0x70 , 0x2 , 0x9 , 0x40 , 0xE6 , 0xD3 , 0x20 , 0xB8 , 0xE6 , 0xC4 , 0xC8 , 0xD0 , 0x17 , 0xA9 , 0x0 , 0x85 , 0xD0 , 0xA9 , 0xD , 0xA6 , 0x99 , 0xE0 , 0x3 , 0xF0 , 0x6 , 0xA6 , 0x9A , 0xE0 , 0x3 , 0xF0 , 0x3 , 0x20 , 0x42 , 0xE7 , 0xA9 , 0xD , 0x85 , 0xD7 , 0x68 , 0xAA , 0x68 , 0xA8 , 0xA5 , 0xD7 , 0xC9 , 0xDE , 0xD0 , 0x2 , 0xA9 , 0xFF , 0x18 , 0x60 , 0xC9 , 0x22 , 0xD0 , 0x8 , 0xA5 , 0xD4 , 0x49 , 0x1 , 0x85 , 0xD4 , 0xA9 , 0x22 , 0x60 , 0x9 , 0x40 , 0xA6 , 0xC7 , 0xF0 , 0x2 , 0x9 , 0x80 , 0xA6 , 0xD8 , 0xF0 , 0x2 , 0xC6 , 0xD8 , 0xAE , 0x86 , 0x2 , 0x20 , 0xA1 , 0xEA , 0x20 , 0xEA , 0xE6 , 0x68 , 0xA8 , 0xA5 , 0xD8 , 0xF0 , 0x2 , 0x46 , 0xD4 , 0x68 , 0xAA , 0x68 , 0x18 , 0x58 , 0x60 , 0x20 , 0xFA , 0xE8 , 0xE6 , 0xD3 , 0xA5 , 0xD5 , 0xC5 , 0xD3 , 0xB0 , 0x37 , 0xC9 , 0x57 , 0xF0 , 0x2A , 0xAD , 0x92 , 0x2 , 0xF0 , 0x3 , 0x4C , 0xF0 , 0xE9 , 0xA6 , 0xD6 , 0xE0 , 0x17 , 0x90 , 0x7 , 0x20 , 0x75 , 0xE9 , 0xC6 , 0xD6 , 0xA6 , 0xD6 , 0x16 , 0xD9 , 0x56 , 0xD9 , 0x4C , 0x5B , 0xED , 0x69 , 0x16 , 0x85 , 0xD5 , 0xB5 , 0xD9 , 0x30 , 0x3 , 0xCA , 0xD0 , 0xF9 , 0x4C , 0x7E , 0xEA , 0xC6 , 0xD6 , 0x20 , 0xC3 , 0xE8 , 0xA9 , 0x0 , 0x85 , 0xD3 , 0x60 , 0xA6 , 0xD6 , 0xD0 , 0x6 , 0x86 , 0xD3 , 0x68 , 0x68 , 0xD0 , 0xA5 , 0xCA , 0x86 , 0xD6 , 0x20 , 0x87 , 0xE5 , 0xA4 , 0xD5 , 0x84 , 0xD3 , 0x60 , 0x48 , 0x85 , 0xD7 , 0x8A , 0x48 , 0x98 , 0x48 , 0xA9 , 0x0 , 0x85 , 0xD0 , 0xA4 , 0xD3 , 0xA5 , 0xD7 , 0x10 , 0x3 , 0x4C , 0x0 , 0xE8 , 0xC9 , 0xD , 0xD0 , 0x3 , 0x4C , 0xD8 , 0xE8 , 0xC9 , 0x20 , 0x90 , 0x10 , 0xC9 , 0x60 , 0x90 , 0x4 , 0x29 , 0xDF , 0xD0 , 0x2 , 0x29 , 0x3F , 0x20 , 0xB8 , 0xE6 , 0x4C , 0xC7 , 0xE6 , 0xA6 , 0xD8 , 0xF0 , 0x3 , 0x4C , 0xCB , 0xE6 , 0xC9 , 0x14 , 0xD0 , 0x2E , 0x98 , 0xD0 , 0x6 , 0x20 , 0x2D , 0xE7 , 0x4C , 0x9F , 0xE7 , 0x20 , 0xE8 , 0xE8 , 0x88 , 0x84 , 0xD3 , 0x20 , 0xB2 , 0xEA , 0xC8 , 0xB1 , 0xD1 , 0x88 , 0x91 , 0xD1 , 0xC8 , 0xB1 , 0xF3 , 0x88 , 0x91 , 0xF3 , 0xC8 , 0xC4 , 0xD5 , 0xD0 , 0xEF , 0xA9 , 0x20 , 0x91 , 0xD1 , 0xAD , 0x86 , 0x2 , 0x91 , 0xF3 , 0x10 , 0x4D , 0xA6 , 0xD4 , 0xF0 , 0x3 , 0x4C , 0xCB , 0xE6 , 0xC9 , 0x12 , 0xD0 , 0x2 , 0x85 , 0xC7 , 0xC9 , 0x13 , 0xD0 , 0x3 , 0x20 , 0x81 , 0xE5 , 0xC9 , 0x1D , 0xD0 , 0x17 , 0xC8 , 0x20 , 0xFA , 0xE8 , 0x84 , 0xD3 , 0x88 , 0xC4 , 0xD5 , 0x90 , 0x9 , 0xC6 , 0xD6 , 0x20 , 0xC3 , 0xE8 , 0xA0 , 0x0 , 0x84 , 0xD3 , 0x4C , 0xDC , 0xE6 , 0xC9 , 0x11 , 0xD0 , 0x1D , 0x18 , 0x98 , 0x69 , 0x16 , 0xA8 , 0xE6 , 0xD6 , 0xC5 , 0xD5 , 0x90 , 0xEC , 0xF0 , 0xEA , 0xC6 , 0xD6 , 0xE9 , 0x16 , 0x90 , 0x4 , 0x85 , 0xD3 , 0xD0 , 0xF8 , 0x20 , 0xC3 , 0xE8 , 0x4C , 0xDC , 0xE6 , 0x20 , 0x12 , 0xE9 , 0x4C , 0x21 , 0xED , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0x29 , 0x7F , 0xC9 , 0x7F , 0xD0 , 0x2 , 0xA9 , 0x5E , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xC9 , 0x20 , 0x90 , 0x3 , 0x4C , 0xC5 , 0xE6 , 0xC9 , 0xD , 0xD0 , 0x3 , 0x4C , 0xD8 , 0xE8 , 0xA6 , 0xD4 , 0xD0 , 0x3F , 0xC9 , 0x14 , 0xD0 , 0x37 , 0xA4 , 0xD5 , 0xB1 , 0xD1 , 0xC9 , 0x20 , 0xD0 , 0x4 , 0xC4 , 0xD3 , 0xD0 , 0x7 , 0xC0 , 0x57 , 0xF0 , 0x24 , 0x20 , 0xEE , 0xE9 , 0xA4 , 0xD5 , 0x20 , 0xB2 , 0xEA , 0x88 , 0xB1 , 0xD1 , 0xC8 , 0x91 , 0xD1 , 0x88 , 0xB1 , 0xF3 , 0xC8 , 0x91 , 0xF3 , 0x88 , 0xC4 , 0xD3 , 0xD0 , 0xEF , 0xA9 , 0x20 , 0x91 , 0xD1 , 0xAD , 0x86 , 0x2 , 0x91 , 0xF3 , 0xE6 , 0xD8 , 0x4C , 0xDC , 0xE6 , 0xA6 , 0xD8 , 0xF0 , 0x5 , 0x9 , 0x40 , 0x4C , 0xCB , 0xE6 , 0xC9 , 0x11 , 0xD0 , 0x16 , 0xA6 , 0xD6 , 0xF0 , 0x37 , 0xC6 , 0xD6 , 0xA5 , 0xD3 , 0x38 , 0xE9 , 0x16 , 0x90 , 0x4 , 0x85 , 0xD3 , 0x10 , 0x2A , 0x20 , 0x87 , 0xE5 , 0xD0 , 0x25 , 0xC9 , 0x12 , 0xD0 , 0x4 , 0xA9 , 0x0 , 0x85 , 0xC7 , 0xC9 , 0x1D , 0xD0 , 0x12 , 0x98 , 0xF0 , 0x9 , 0x20 , 0xE8 , 0xE8 , 0x88 , 0x84 , 0xD3 , 0x4C , 0xDC , 0xE6 , 0x20 , 0x2D , 0xE7 , 0x4C , 0xDC , 0xE6 , 0xC9 , 0x13 , 0xD0 , 0x6 , 0x20 , 0x5F , 0xE5 , 0x4C , 0xDC , 0xE6 , 0x9 , 0x80 , 0x20 , 0x12 , 0xE9 , 0x4C , 0x30 , 0xED , 0x46 , 0xC9 , 0xA6 , 0xD6 , 0xE8 , 0xE0 , 0x17 , 0xD0 , 0x3 , 0x20 , 0x75 , 0xE9 , 0xB5 , 0xD9 , 0x10 , 0xF4 , 0x86 , 0xD6 , 0x4C , 0x87 , 0xE5 , 0xA2 , 0x0 , 0x86 , 0xD8 , 0x86 , 0xC7 , 0x86 , 0xD4 , 0x86 , 0xD3 , 0x20 , 0xC3 , 0xE8 , 0x4C , 0xDC , 0xE6 , 0xA2 , 0x4 , 0xA9 , 0x0 , 0xC5 , 0xD3 , 0xF0 , 0x7 , 0x18 , 0x69 , 0x16 , 0xCA , 0xD0 , 0xF6 , 0x60 , 0xC6 , 0xD6 , 0x60 , 0xA2 , 0x4 , 0xA9 , 0x15 , 0xC5 , 0xD3 , 0xF0 , 0x7 , 0x18 , 0x69 , 0x16 , 0xCA , 0xD0 , 0xF6 , 0x60 , 0xA6 , 0xD6 , 0xE0 , 0x17 , 0xF0 , 0x2 , 0xE6 , 0xD6 , 0x60 , 0xA2 , 0x7 , 0xDD , 0x21 , 0xE9 , 0xF0 , 0x4 , 0xCA , 0x10 , 0xF8 , 0x60 , 0x8E , 0x86 , 0x2 , 0x60 , 0x90 , 0x5 , 0x1C , 0x9F , 0x9C , 0x1E , 0x1F , 0x9E , 0xEF , 0xA1 , 0xDF , 0xA6 , 0xE1 , 0xB1 , 0xE2 , 0xB2 , 0xE3 , 0xB3 , 0xE4 , 0xB4 , 0xE5 , 0xB5 , 0xE6 , 0xB6 , 0xE7 , 0xB7 , 0xE8 , 0xB8 , 0xE9 , 0xB9 , 0xFA , 0xBA , 0xFB , 0xBB , 0xFC , 0xBC , 0xEC , 0xBD , 0xFE , 0xBE , 0x84 , 0xBF , 0xF7 , 0xC0 , 0xF8 , 0xDB , 0xF9 , 0xDD , 0xEA , 0xDE , 0x5E , 0xE0 , 0x5B , 0xE1 , 0x5D , 0xE2 , 0x40 , 0xB0 , 0x61 , 0xB1 , 0x78 , 0xDB , 0x79 , 0xDD , 0x66 , 0xB6 , 0x77 , 0xC0 , 0x70 , 0xF0 , 0x71 , 0xF1 , 0x72 , 0xF2 , 0x73 , 0xF3 , 0x74 , 0xF4 , 0x75 , 0xF5 , 0x76 , 0xF6 , 0x7D , 0xFD , 0xA5 , 0xAC , 0x48 , 0xA5 , 0xAD , 0x48 , 0xA5 , 0xAE , 0x48 , 0xA5 , 0xAF , 0x48 , 0xA2 , 0xFF , 0xC6 , 0xD6 , 0xC6 , 0xC9 , 0xC6 , 0xF2 , 0xE8 , 0x20 , 0x7E , 0xEA , 0xE0 , 0x16 , 0xB0 , 0xC , 0xBD , 0xFE , 0xED , 0x85 , 0xAC , 0xB5 , 0xDA , 0x20 , 0x56 , 0xEA , 0x30 , 0xEC , 0x20 , 0x8D , 0xEA , 0xA2 , 0x0 , 0xB5 , 0xD9 , 0x29 , 0x7F , 0xB4 , 0xDA , 0x10 , 0x2 , 0x9 , 0x80 , 0x95 , 0xD9 , 0xE8 , 0xE0 , 0x16 , 0xD0 , 0xEF , 0xA5 , 0xEF , 0x9 , 0x80 , 0x85 , 0xEF , 0xA5 , 0xD9 , 0x10 , 0xC4 , 0xE6 , 0xD6 , 0xE6 , 0xF2 , 0xA9 , 0xFB , 0x8D , 0x20 , 0x91 , 0xAD , 0x21 , 0x91 , 0xC9 , 0xFE , 0x8 , 0xA9 , 0xF7 , 0x8D , 0x20 , 0x91 , 0x28 , 0xD0 , 0xB , 0xA0 , 0x0 , 0xEA , 0xCA , 0xD0 , 0xFC , 0x88 , 0xD0 , 0xF9 , 0x84 , 0xC6 , 0xA6 , 0xD6 , 0x68 , 0x85 , 0xAF , 0x68 , 0x85 , 0xAE , 0x68 , 0x85 , 0xAD , 0x68 , 0x85 , 0xAC , 0x60 , 0xA6 , 0xD6 , 0xE8 , 0xB5 , 0xD9 , 0x10 , 0xFB , 0x86 , 0xF2 , 0xE0 , 0x16 , 0xF0 , 0xD , 0x90 , 0xB , 0x20 , 0x75 , 0xE9 , 0xA6 , 0xF2 , 0xCA , 0xC6 , 0xD6 , 0x4C , 0xE , 0xE7 , 0xA5 , 0xAC , 0x48 , 0xA5 , 0xAD , 0x48 , 0xA5 , 0xAE , 0x48 , 0xA5 , 0xAF , 0x48 , 0xA2 , 0x17 , 0xCA , 0x20 , 0x7E , 0xEA , 0xE4 , 0xF2 , 0x90 , 0xE , 0xF0 , 0xC , 0xBD , 0xFC , 0xED , 0x85 , 0xAC , 0xB5 , 0xD8 , 0x20 , 0x56 , 0xEA , 0x30 , 0xEA , 0x20 , 0x8D , 0xEA , 0xA2 , 0x15 , 0xE4 , 0xF2 , 0x90 , 0xF , 0xB5 , 0xDA , 0x29 , 0x7F , 0xB4 , 0xD9 , 0x10 , 0x2 , 0x9 , 0x80 , 0x95 , 0xDA , 0xCA , 0xD0 , 0xED , 0xA6 , 0xF2 , 0x20 , 0xE , 0xE7 , 0x68 , 0x85 , 0xAF , 0x68 , 0x85 , 0xAE , 0x68 , 0x85 , 0xAD , 0x68 , 0x85 , 0xAC , 0x60 , 0x29 , 0x3 , 0xD , 0x88 , 0x2 , 0x85 , 0xAD , 0x20 , 0x6E , 0xEA , 0xA0 , 0x15 , 0xB1 , 0xAC , 0x91 , 0xD1 , 0xB1 , 0xAE , 0x91 , 0xF3 , 0x88 , 0x10 , 0xF5 , 0x60 , 0x20 , 0xB2 , 0xEA , 0xA5 , 0xAC , 0x85 , 0xAE , 0xA5 , 0xAD , 0x29 , 0x3 , 0x9 , 0x94 , 0x85 , 0xAF , 0x60 , 0xBD , 0xFD , 0xED , 0x85 , 0xD1 , 0xB5 , 0xD9 , 0x29 , 0x3 , 0xD , 0x88 , 0x2 , 0x85 , 0xD2 , 0x60 , 0xA0 , 0x15 , 0x20 , 0x7E , 0xEA , 0x20 , 0xB2 , 0xEA , 0xA9 , 0x20 , 0x91 , 0xD1 , 0xA9 , 0x1 , 0x91 , 0xF3 , 0x88 , 0x10 , 0xF5 , 0x60 , 0xA8 , 0xA9 , 0x2 , 0x85 , 0xCD , 0x20 , 0xB2 , 0xEA , 0x98 , 0xA4 , 0xD3 , 0x91 , 0xD1 , 0x8A , 0x91 , 0xF3 , 0x60 , 0xA5 , 0xD1 , 0x85 , 0xF3 , 0xA5 , 0xD2 , 0x29 , 0x3 , 0x9 , 0x94 , 0x85 , 0xF4 , 0x60 , 0x20 , 0xEA , 0xFF , 0xA5 , 0xCC , 0xD0 , 0x29 , 0xC6 , 0xCD , 0xD0 , 0x25 , 0xA9 , 0x14 , 0x85 , 0xCD , 0xA4 , 0xD3 , 0x46 , 0xCF , 0xAE , 0x87 , 0x2 , 0xB1 , 0xD1 , 0xB0 , 0x11 , 0xE6 , 0xCF , 0x85 , 0xCE , 0x20 , 0xB2 , 0xEA , 0xB1 , 0xF3 , 0x8D , 0x87 , 0x2 , 0xAE , 0x86 , 0x2 , 0xA5 , 0xCE , 0x49 , 0x80 , 0x20 , 0xAA , 0xEA , 0xAD , 0x1F , 0x91 , 0x29 , 0x40 , 0xF0 , 0xB , 0xA0 , 0x0 , 0x84 , 0xC0 , 0xAD , 0x1C , 0x91 , 0x9 , 0x2 , 0xD0 , 0x9 , 0xA5 , 0xC0 , 0xD0 , 0xD , 0xAD , 0x1C , 0x91 , 0x29 , 0xFD , 0x2C , 0x1E , 0x91 , 0x70 , 0x3 , 0x8D , 0x1C , 0x91 , 0x20 , 0x1E , 0xEB , 0x2C , 0x24 , 0x91 , 0x68 , 0xA8 , 0x68 , 0xAA , 0x68 , 0x40 , 0xA9 , 0x0 , 0x8D , 0x8D , 0x2 , 0xA0 , 0x40 , 0x84 , 0xCB , 0x8D , 0x20 , 0x91 , 0xAE , 0x21 , 0x91 , 0xE0 , 0xFF , 0xF0 , 0x5E , 0xA9 , 0xFE , 0x8D , 0x20 , 0x91 , 0xA0 , 0x0 , 0xA9 , 0x5E , 0x85 , 0xF5 , 0xA9 , 0xEC , 0x85 , 0xF6 , 0xA2 , 0x8 , 0xAD , 0x21 , 0x91 , 0xCD , 0x21 , 0x91 , 0xD0 , 0xF6 , 0x4A , 0xB0 , 0x16 , 0x48 , 0xB1 , 0xF5 , 0xC9 , 0x5 , 0xB0 , 0xC , 0xC9 , 0x3 , 0xF0 , 0x8 , 0xD , 0x8D , 0x2 , 0x8D , 0x8D , 0x2 , 0x10 , 0x2 , 0x84 , 0xCB , 0x68 , 0xC8 , 0xC0 , 0x41 , 0xB0 , 0x9 , 0xCA , 0xD0 , 0xDF , 0x38 , 0x2E , 0x20 , 0x91 , 0xD0 , 0xCF , 0x6C , 0x8F , 0x2 , 0xA4 , 0xCB , 0xB1 , 0xF5 , 0xAA , 0xC4 , 0xC5 , 0xF0 , 0x7 , 0xA0 , 0x10 , 0x8C , 0x8C , 0x2 , 0xD0 , 0x36 , 0x29 , 0x7F , 0x2C , 0x8A , 0x2 , 0x30 , 0x16 , 0x70 , 0x49 , 0xC9 , 0x7F , 0xF0 , 0x29 , 0xC9 , 0x14 , 0xF0 , 0xC , 0xC9 , 0x20 , 0xF0 , 0x8 , 0xC9 , 0x1D , 0xF0 , 0x4 , 0xC9 , 0x11 , 0xD0 , 0x35 , 0xAC , 0x8C , 0x2 , 0xF0 , 0x5 , 0xCE , 0x8C , 0x2 , 0xD0 , 0x2B , 0xCE , 0x8B , 0x2 , 0xD0 , 0x26 , 0xA0 , 0x4 , 0x8C , 0x8B , 0x2 , 0xA4 , 0xC6 , 0x88 , 0x10 , 0x1C , 0xA4 , 0xCB , 0x84 , 0xC5 , 0xAC , 0x8D , 0x2 , 0x8C , 0x8E , 0x2 , 0xE0 , 0xFF , 0xF0 , 0xE , 0x8A , 0xA6 , 0xC6 , 0xEC , 0x89 , 0x2 , 0xB0 , 0x6 , 0x9D , 0x77 , 0x2 , 0xE8 , 0x86 , 0xC6 , 0xA9 , 0xF7 , 0x8D , 0x20 , 0x91 , 0x60 , 0xAD , 0x8D , 0x2 , 0xC9 , 0x3 , 0xD0 , 0x2C , 0xCD , 0x8E , 0x2 , 0xF0 , 0xEE , 0xAD , 0x91 , 0x2 , 0x30 , 0x56 , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xAD , 0x5 , 0x90 , 0x49 , 0x2 , 0x8D , 0x5 , 0x90 , 0xEA , 0xEA , 0xEA , 0xEA , 0x4C , 0x43 , 0xEC , 0xA , 0xC9 , 0x8 , 0x90 , 0x4 , 0xA9 , 0x6 , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xEA , 0xAA , 0xBD , 0x46 , 0xEC , 0x85 , 0xF5 , 0xBD , 0x47 , 0xEC , 0x85 , 0xF6 , 0x4C , 0x74 , 0xEB , 0x5E , 0xEC , 0x9F , 0xEC , 0xE0 , 0xEC , 0xA3 , 0xED , 0x5E , 0xEC , 0x9F , 0xEC , 0x69 , 0xED , 0xA3 , 0xED , 0x21 , 0xED , 0x69 , 0xED , 0x69 , 0xED , 0xA3 , 0xED , 0x31 , 0x33 , 0x35 , 0x37 , 0x39 , 0x2D , 0x3A , 0x14 , 0x5F , 0x57 , 0x52 , 0x59 , 0x49 , 0x50 , 0x40 , 0xD , 0x4 , 0x41 , 0x44 , 0x47 , 0x4A , 0x4C , 0x5B , 0x1D , 0x3 , 0x1 , 0x58 , 0x56 , 0x4E , 0x2C , 0x2F , 0x11 , 0x20 , 0x5A , 0x43 , 0x42 , 0x4D , 0x2E , 0x1 , 0x85 , 0x2 , 0x53 , 0x46 , 0x48 , 0x4B , 0x5C , 0x3B , 0x86 , 0x51 , 0x45 , 0x54 , 0x55 , 0x4F , 0x5D , 0x5E , 0x87 , 0x32 , 0x34 , 0x36 , 0x38 , 0x30 , 0x3D , 0x13 , 0x88 , 0xFF , 0x21 , 0x23 , 0x25 , 0x27 , 0x29 , 0xC0 , 0x2A , 0x94 , 0x5F , 0xD7 , 0xD2 , 0xD9 , 0xC9 , 0xD0 , 0xBA , 0x8D , 0x4 , 0xC1 , 0xC4 , 0xC7 , 0xCA , 0xCC , 0xDB , 0x9D , 0x83 , 0x1 , 0xD8 , 0xD6 , 0xCE , 0x3C , 0x3F , 0x91 , 0xA0 , 0xDA , 0xC3 , 0xC2 , 0xCD , 0x3E , 0x1 , 0x89 , 0x2 , 0xD3 , 0xC6 , 0xC8 , 0xCB , 0xDC , 0x2B , 0x8A , 0xD1 , 0xC5 , 0xD4 , 0xD5 , 0xCF , 0xDD , 0xDE , 0x8B , 0x22 , 0x24 , 0x26 , 0x28 , 0x30 , 0x3D , 0x93 , 0x8C , 0xFF , 0x21 , 0x23 , 0x25 , 0x27 , 0x29 , 0xDF , 0x2A , 0x94 , 0x5F , 0xB3 , 0xB2 , 0xB7 , 0xA2 , 0xAF , 0xA4 , 0x8D , 0x4 , 0xB0 , 0xAC , 0xA5 , 0xB5 , 0xB6 , 0xA8 , 0x9D , 0x83 , 0x1 , 0xBD , 0xBE , 0xAA , 0x3C , 0x3F , 0x91 , 0xA0 , 0xAD , 0xBC , 0xBF , 0xA7 , 0x3E , 0x1 , 0x89 , 0x2 , 0xAE , 0xBB , 0xB4 , 0xA1 , 0xA9 , 0x2B , 0x8A , 0xAB , 0xB1 , 0xA3 , 0xB8 , 0xB9 , 0xA6 , 0xDE , 0x8B , 0x22 , 0x24 , 0x26 , 0x28 , 0x30 , 0x3D , 0x93 , 0x8C , 0xFF , 0xC9 , 0xE , 0xD0 , 0xB , 0xA9 , 0x2 , 0xD , 0x5 , 0x90 , 0x8D , 0x5 , 0x90 , 0x4C , 0xDC , 0xE6 , 0xC9 , 0x8E , 0xD0 , 0xB , 0xA9 , 0xFD , 0x2D , 0x5 , 0x90 , 0x8D , 0x5 , 0x90 , 0x4C , 0xDC , 0xE6 , 0xC9 , 0x8 , 0xD0 , 0xA , 0xA9 , 0x80 , 0xD , 0x91 , 0x2 , 0x8D , 0x91 , 0x2 , 0x30 , 0xEF , 0xC9 , 0x9 , 0xD0 , 0xEB , 0xA9 , 0x7F , 0x2D , 0x91 , 0x2 , 0x8D , 0x91 , 0x2 , 0x10 , 0xE1 , 0xE8 , 0xB5 , 0xD9 , 0x9 , 0x80 , 0x95 , 0xD9 , 0xCA , 0xA5 , 0xD5 , 0x18 , 0x4C , 0x15 , 0xE7 , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0xAA , 0x4 , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xE2 , 0x9D , 0x83 , 0x1 , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0x91 , 0xA0 , 0xFF , 0xFF , 0xFF , 0xFF , 0xEE , 0x1 , 0x89 , 0x2 , 0xFF , 0xFF , 0xFF , 0xFF , 0xE1 , 0xFD , 0x8A , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xB0 , 0xE0 , 0x8B , 0xF2 , 0xF4 , 0xF6 , 0xFF , 0xF0 , 0xED , 0x93 , 0x8C , 0xFF , 0x90 , 0x1C , 0x9C , 0x1F , 0x12 , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0x12 , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0x5 , 0x9F , 0x1E , 0x9E , 0x92 , 0xFF , 0xFF , 0xFF , 0xFF , 0xC , 0x26 , 0x16 , 0x2E , 0x0 , 0xC0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x1B , 0x4C , 0x4F , 0x41 , 0x44 , 0xD , 0x52 , 0x55 , 0x4E , 0xD , 0x0 , 0x16 , 0x2C , 0x42 , 0x58 , 0x6E , 0x84 , 0x9A , 0xB0 , 0xC6 , 0xDC , 0xF2 , 0x8 , 0x1E , 0x34 , 0x4A , 0x60 , 0x76 , 0x8C , 0xA2 , 0xB8 , 0xCE , 0xE4 , 0x9 , 0x40 , 0x2C , 0x9 , 0x20 , 0x20 , 0x60 , 0xF1 , 0x48 , 0x24 , 0x94 , 0x10 , 0xA , 0x38 , 0x66 , 0xA3 , 0x20 , 0x49 , 0xEE , 0x46 , 0x94 , 0x46 , 0xA3 , 0x68 , 0x85 , 0x95 , 0x20 , 0xA0 , 0xE4 , 0xC9 , 0x3F , 0xD0 , 0x3 , 0x20 , 0x84 , 0xEF , 0xAD , 0x1F , 0x91 , 0x9 , 0x80 , 0x8D , 0x1F , 0x91 , 0x20 , 0x8D , 0xEF , 0x20 , 0xA0 , 0xE4 , 0x20 , 0x96 , 0xEF , 0x78 , 0x20 , 0xA0 , 0xE4 , 0x20 , 0xB2 , 0xE4 , 0x4A , 0xB0 , 0x61 , 0x20 , 0x84 , 0xEF , 0x24 , 0xA3 , 0x10 , 0xC , 0x20 , 0xB2 , 0xE4 , 0x4A , 0x90 , 0xFA , 0x20 , 0xB2 , 0xE4 , 0x4A , 0xB0 , 0xFA , 0x20 , 0xB2 , 0xE4 , 0x4A , 0x90 , 0xFA , 0x20 , 0x8D , 0xEF , 0xA9 , 0x8 , 0x85 , 0xA5 , 0xAD , 0x1F , 0x91 , 0xCD , 0x1F , 0x91 , 0xD0 , 0xF8 , 0x4A , 0x4A , 0x90 , 0x38 , 0x66 , 0x95 , 0xB0 , 0x5 , 0x20 , 0xA9 , 0xE4 , 0xD0 , 0x3 , 0x20 , 0xA0 , 0xE4 , 0x20 , 0x84 , 0xEF , 0xEA , 0xEA , 0xEA , 0xEA , 0xAD , 0x2C , 0x91 , 0x29 , 0xDF , 0x9 , 0x2 , 0x8D , 0x2C , 0x91 , 0xC6 , 0xA5 , 0xD0 , 0xD3 , 0xA9 , 0x4 , 0x8D , 0x29 , 0x91 , 0xAD , 0x2D , 0x91 , 0x29 , 0x20 , 0xD0 , 0xB , 0x20 , 0xB2 , 0xE4 , 0x4A , 0xB0 , 0xF3 , 0x58 , 0x60 , 0xA9 , 0x80 , 0x2C , 0xA9 , 0x3 , 0x20 , 0x6A , 0xFE , 0x58 , 0x18 , 0x90 , 0x49 , 0x85 , 0x95 , 0x20 , 0x40 , 0xEE , 0xAD , 0x1F , 0x91 , 0x29 , 0x7F , 0x8D , 0x1F , 0x91 , 0x60 , 0x85 , 0x95 , 0x20 , 0x40 , 0xEE , 0x78 , 0x20 , 0xA9 , 0xE4 , 0x20 , 0xC5 , 0xEE , 0x20 , 0x84 , 0xEF , 0x20 , 0xB2 , 0xE4 , 0xB0 , 0xFB , 0x58 , 0x60 , 0x24 , 0x94 , 0x30 , 0x5 , 0x38 , 0x66 , 0x94 , 0xD0 , 0x5 , 0x48 , 0x20 , 0x49 , 0xEE , 0x68 , 0x85 , 0x95 , 0x18 , 0x60 , 0x20 , 0x8D , 0xEF , 0xAD , 0x1F , 0x91 , 0x9 , 0x80 , 0x8D , 0x1F , 0x91 , 0xA9 , 0x5F , 0x2C , 0xA9 , 0x3F , 0x20 , 0x1C , 0xEE , 0x20 , 0xC5 , 0xEE , 0x8A , 0xA2 , 0xB , 0xCA , 0xD0 , 0xFD , 0xAA , 0x20 , 0x84 , 0xEF , 0x4C , 0xA0 , 0xE4 , 0x78 , 0xA9 , 0x0 , 0x85 , 0xA5 , 0x20 , 0x84 , 0xEF , 0x20 , 0xB2 , 0xE4 , 0x90 , 0xFB , 0x20 , 0xA0 , 0xE4 , 0xA9 , 0x1 , 0x8D , 0x29 , 0x91 , 0xAD , 0x2D , 0x91 , 0x29 , 0x20 , 0xD0 , 0x7 , 0x20 , 0xB2 , 0xE4 , 0xB0 , 0xF4 , 0x90 , 0x18 , 0xA5 , 0xA5 , 0xF0 , 0x5 , 0xA9 , 0x2 , 0x4C , 0xB9 , 0xEE , 0x20 , 0xA9 , 0xE4 , 0x20 , 0xC , 0xEF , 0xA9 , 0x40 , 0x20 , 0x6A , 0xFE , 0xE6 , 0xA5 , 0xD0 , 0xD5 , 0xA9 , 0x8 , 0x85 , 0xA5 , 0xAD , 0x1F , 0x91 , 0xCD , 0x1F , 0x91 , 0xD0 , 0xF8 , 0x4A , 0x90 , 0xF5 , 0x4A , 0x66 , 0xA4 , 0xAD , 0x1F , 0x91 , 0xCD , 0x1F , 0x91 , 0xD0 , 0xF8 , 0x4A , 0xB0 , 0xF5 , 0xC6 , 0xA5 , 0xD0 , 0xE3 , 0x20 , 0xA9 , 0xE4 , 0xA5 , 0x90 , 0xF0 , 0x3 , 0x20 , 0xC , 0xEF , 0xA5 , 0xA4 , 0x58 , 0x18 , 0x60 , 0xAD , 0x2C , 0x91 , 0x29 , 0xFD , 0x8D , 0x2C , 0x91 , 0x60 , 0xAD , 0x2C , 0x91 , 0x9 , 0x2 , 0x8D , 0x2C , 0x91 , 0x60 , 0xA9 , 0x4 , 0x8D , 0x29 , 0x91 , 0xAD , 0x2D , 0x91 , 0x29 , 0x20 , 0xF0 , 0xF9 , 0x60 , 0xA5 , 0xB4 , 0xF0 , 0x47 , 0x30 , 0x3F , 0x46 , 0xB6 , 0xA2 , 0x0 , 0x90 , 0x1 , 0xCA , 0x8A , 0x45 , 0xBD , 0x85 , 0xBD , 0xC6 , 0xB4 , 0xF0 , 0x6 , 0x8A , 0x29 , 0x20 , 0x85 , 0xB5 , 0x60 , 0xA9 , 0x20 , 0x2C , 0x94 , 0x2 , 0xF0 , 0x14 , 0x30 , 0x1C , 0x70 , 0x14 , 0xA5 , 0xBD , 0xD0 , 0x1 , 0xCA , 0xC6 , 0xB4 , 0xAD , 0x93 , 0x2 , 0x10 , 0xE3 , 0xC6 , 0xB4 , 0xD0 , 0xDF , 0xE6 , 0xB4 , 0xD0 , 0xF0 , 0xA5 , 0xBD , 0xF0 , 0xED , 0xD0 , 0xEA , 0x70 , 0xE9 , 0x50 , 0xE6 , 0xE6 , 0xB4 , 0xA2 , 0xFF , 0xD0 , 0xCB , 0xAD , 0x94 , 0x2 , 0x4A , 0x90 , 0x7 , 0x2C , 0x20 , 0x91 , 0x10 , 0x1D , 0x50 , 0x1E , 0xA9 , 0x0 , 0x85 , 0xBD , 0x85 , 0xB5 , 0xAE , 0x98 , 0x2 , 0x86 , 0xB4 , 0xAC , 0x9D , 0x2 , 0xCC , 0x9E , 0x2 , 0xF0 , 0x13 , 0xB1 , 0xF9 , 0x85 , 0xB6 , 0xEE , 0x9D , 0x2 , 0x60 , 0xA9 , 0x40 , 0x2C , 0xA9 , 0x10 , 0xD , 0x97 , 0x2 , 0x8D , 0x97 , 0x2 , 0xA9 , 0x40 , 0x8D , 0x1E , 0x91 , 0x60 , 0xA2 , 0x9 , 0xA9 , 0x20 , 0x2C , 0x93 , 0x2 , 0xF0 , 0x1 , 0xCA , 0x50 , 0x2 , 0xCA , 0xCA , 0x60 , 0xA6 , 0xA9 , 0xD0 , 0x2E , 0xC6 , 0xA8 , 0xF0 , 0x31 , 0x30 , 0xD , 0xA5 , 0xA7 , 0x45 , 0xAB , 0x85 , 0xAB , 0x46 , 0xA7 , 0x66 , 0xAA , 0x60 , 0xC6 , 0xA8 , 0xA5 , 0xA7 , 0xF0 , 0x62 , 0xAD , 0x93 , 0x2 , 0xA , 0xA9 , 0x1 , 0x65 , 0xA8 , 0xD0 , 0xEF , 0xA9 , 0x90 , 0x8D , 0x1E , 0x91 , 0x85 , 0xA9 , 0xA9 , 0x20 , 0x8D , 0x1E , 0x91 , 0x60 , 0xA5 , 0xA7 , 0xD0 , 0xEF , 0x85 , 0xA9 , 0x60 , 0xAC , 0x9B , 0x2 , 0xC8 , 0xCC , 0x9C , 0x2 , 0xF0 , 0x2A , 0x8C , 0x9B , 0x2 , 0x88 , 0xA5 , 0xAA , 0xAE , 0x98 , 0x2 , 0xE0 , 0x9 , 0xF0 , 0x4 , 0x4A , 0xE8 , 0xD0 , 0xF8 , 0x91 , 0xF7 , 0xA9 , 0x20 , 0x2C , 0x94 , 0x2 , 0xF0 , 0xB9 , 0x30 , 0xB6 , 0xA5 , 0xA7 , 0x45 , 0xAB , 0xF0 , 0x3 , 0x70 , 0xAE , 0x2C , 0x50 , 0xAB , 0xA9 , 0x1 , 0x2C , 0xA9 , 0x4 , 0x2C , 0xA9 , 0x80 , 0x2C , 0xA9 , 0x2 , 0xD , 0x97 , 0x2 , 0x8D , 0x97 , 0x2 , 0x4C , 0x5B , 0xF0 , 0xA5 , 0xAA , 0xD0 , 0xF1 , 0xF0 , 0xEC , 0x4C , 0x96 , 0xF7 , 0x85 , 0x9A , 0xAD , 0x94 , 0x2 , 0x4A , 0x90 , 0x27 , 0xA9 , 0x2 , 0x2C , 0x10 , 0x91 , 0x10 , 0x1D , 0xD0 , 0x1E , 0xAD , 0x1E , 0x91 , 0x29 , 0x30 , 0xD0 , 0xF9 , 0x2C , 0x10 , 0x91 , 0x70 , 0xFB , 0xAD , 0x10 , 0x91 , 0x9 , 0x2 , 0x8D , 0x10 , 0x91 , 0x2C , 0x10 , 0x91 , 0x70 , 0x5 , 0x30 , 0xF9 , 0x20 , 0x16 , 0xF0 , 0x18 , 0x60 , 0xAC , 0x9E , 0x2 , 0xC8 , 0xCC , 0x9D , 0x2 , 0xF0 , 0xF7 , 0x8C , 0x9E , 0x2 , 0x88 , 0x91 , 0xF9 , 0x2C , 0x1E , 0x91 , 0x50 , 0x1 , 0x60 , 0xAD , 0x99 , 0x2 , 0x8D , 0x14 , 0x91 , 0xAD , 0x9A , 0x2 , 0x8D , 0x15 , 0x91 , 0xA9 , 0xC0 , 0x8D , 0x1E , 0x91 , 0x4C , 0xEE , 0xEF , 0x85 , 0x99 , 0xAD , 0x94 , 0x2 , 0x4A , 0x90 , 0x28 , 0x29 , 0x8 , 0xF0 , 0x24 , 0xA9 , 0x2 , 0x2C , 0x10 , 0x91 , 0x10 , 0xBF , 0xF0 , 0x19 , 0x2C , 0x1E , 0x91 , 0x70 , 0xFB , 0xAD , 0x10 , 0x91 , 0x29 , 0xFD , 0x8D , 0x10 , 0x91 , 0xAD , 0x10 , 0x91 , 0x29 , 0x4 , 0xF0 , 0xF9 , 0xA9 , 0x90 , 0x8D , 0x1E , 0x91 , 0x18 , 0x60 , 0xAD , 0x1E , 0x91 , 0x29 , 0x30 , 0xF0 , 0xF2 , 0x18 , 0x60 , 0xAC , 0x9C , 0x2 , 0xCC , 0x9B , 0x2 , 0xF0 , 0x6 , 0xB1 , 0xF7 , 0xEE , 0x9C , 0x2 , 0x60 , 0xA9 , 0x0 , 0x60 , 0x48 , 0xAD , 0x1E , 0x91 , 0xF0 , 0xC , 0xAD , 0x1E , 0x91 , 0x29 , 0x60 , 0xD0 , 0xF9 , 0xA9 , 0x10 , 0x8D , 0x1E , 0x91 , 0x68 , 0x60 , 0xD , 0x49 , 0x2F , 0x4F , 0x20 , 0x45 , 0x52 , 0x52 , 0x4F , 0x52 , 0x20 , 0xA3 , 0xD , 0x53 , 0x45 , 0x41 , 0x52 , 0x43 , 0x48 , 0x49 , 0x4E , 0x47 , 0xA0 , 0x46 , 0x4F , 0x52 , 0xA0 , 0xD , 0x50 , 0x52 , 0x45 , 0x53 , 0x53 , 0x20 , 0x50 , 0x4C , 0x41 , 0x59 , 0x20 , 0x4F , 0x4E , 0x20 , 0x54 , 0x41 , 0x50 , 0xC5 , 0x50 , 0x52 , 0x45 , 0x53 , 0x53 , 0x20 , 0x52 , 0x45 , 0x43 , 0x4F , 0x52 , 0x44 , 0x20 , 0x26 , 0x20 , 0x50 , 0x4C , 0x41 , 0x59 , 0x20 , 0x4F , 0x4E , 0x20 , 0x54 , 0x41 , 0x50 , 0xC5 , 0xD , 0x4C , 0x4F , 0x41 , 0x44 , 0x49 , 0x4E , 0xC7 , 0xD , 0x53 , 0x41 , 0x56 , 0x49 , 0x4E , 0x47 , 0xA0 , 0xD , 0x56 , 0x45 , 0x52 , 0x49 , 0x46 , 0x59 , 0x49 , 0x4E , 0xC7 , 0xD , 0x46 , 0x4F , 0x55 , 0x4E , 0x44 , 0xA0 , 0xD , 0x4F , 0x4B , 0x8D , 0x24 , 0x9D , 0x10 , 0xD , 0xB9 , 0x74 , 0xF1 , 0x8 , 0x29 , 0x7F , 0x20 , 0xD2 , 0xFF , 0xC8 , 0x28 , 0x10 , 0xF3 , 0x18 , 0x60 , 0xA5 , 0x99 , 0xD0 , 0x8 , 0xA5 , 0xC6 , 0xF0 , 0x6D , 0x78 , 0x4C , 0xCF , 0xE5 , 0xC9 , 0x2 , 0xD0 , 0x18 , 0x84 , 0x97 , 0x20 , 0x4F , 0xF1 , 0xA4 , 0x97 , 0x18 , 0x60 , 0xA5 , 0x99 , 0xD0 , 0xB , 0xA5 , 0xD3 , 0x85 , 0xCA , 0xA5 , 0xD6 , 0x85 , 0xC9 , 0x4C , 0x4F , 0xE6 , 0xC9 , 0x3 , 0xD0 , 0x9 , 0x85 , 0xD0 , 0xA5 , 0xD5 , 0x85 , 0xC8 , 0x4C , 0x4F , 0xE6 , 0xB0 , 0x38 , 0xC9 , 0x2 , 0xF0 , 0x3F , 0x86 , 0x97 , 0x20 , 0x50 , 0xF2 , 0xB0 , 0x16 , 0x48 , 0x20 , 0x50 , 0xF2 , 0xB0 , 0xD , 0xD0 , 0x5 , 0xA9 , 0x40 , 0x20 , 0x6A , 0xFE , 0xC6 , 0xA6 , 0xA6 , 0x97 , 0x68 , 0x60 , 0xAA , 0x68 , 0x8A , 0xA6 , 0x97 , 0x60 , 0x20 , 0x8A , 0xF8 , 0xD0 , 0xB , 0x20 , 0xC0 , 0xF8 , 0xB0 , 0x11 , 0xA9 , 0x0 , 0x85 , 0xA6 , 0xF0 , 0xF0 , 0xB1 , 0xB2 , 0x18 , 0x60 , 0xA5 , 0x90 , 0xF0 , 0x4 , 0xA9 , 0xD , 0x18 , 0x60 , 0x4C , 0x19 , 0xEF , 0x20 , 0x5 , 0xF2 , 0xB0 , 0x5 , 0xC9 , 0x0 , 0xF0 , 0xF7 , 0x18 , 0x60 , 0x48 , 0xA5 , 0x9A , 0xC9 , 0x3 , 0xD0 , 0x4 , 0x68 , 0x4C , 0x42 , 0xE7 , 0x90 , 0x4 , 0x68 , 0x4C , 0xE4 , 0xEE , 0xC9 , 0x2 , 0xF0 , 0x2A , 0x68 , 0x85 , 0x9E , 0x48 , 0x8A , 0x48 , 0x98 , 0x48 , 0x20 , 0x8A , 0xF8 , 0xD0 , 0xE , 0x20 , 0xE3 , 0xF8 , 0xB0 , 0xE , 0xA9 , 0x2 , 0xA0 , 0x0 , 0x91 , 0xB2 , 0xC8 , 0x84 , 0xA6 , 0xA5 , 0x9E , 0x91 , 0xB2 , 0x18 , 0x68 , 0xA8 , 0x68 , 0xAA , 0x68 , 0x90 , 0x2 , 0xA9 , 0x0 , 0x60 , 0x68 , 0x86 , 0x97 , 0x84 , 0x9E , 0x20 , 0xED , 0xF0 , 0xA6 , 0x97 , 0xA4 , 0x9E , 0x18 , 0x60 , 0x20 , 0xCF , 0xF3 , 0xF0 , 0x3 , 0x4C , 0x84 , 0xF7 , 0x20 , 0xDF , 0xF3 , 0xA5 , 0xBA , 0xF0 , 0x16 , 0xC9 , 0x3 , 0xF0 , 0x12 , 0xB0 , 0x14 , 0xC9 , 0x2 , 0xD0 , 0x3 , 0x4C , 0x16 , 0xF1 , 0xA6 , 0xB9 , 0xE0 , 0x60 , 0xF0 , 0x3 , 0x4C , 0x8D , 0xF7 , 0x85 , 0x99 , 0x18 , 0x60 , 0xAA , 0x20 , 0x14 , 0xEE , 0xA5 , 0xB9 , 0x10 , 0x6 , 0x20 , 0xD3 , 0xEE , 0x4C , 0x1 , 0xF3 , 0x20 , 0xCE , 0xEE , 0x8A , 0x24 , 0x90 , 0x10 , 0xE6 , 0x4C , 0x8A , 0xF7 , 0x20 , 0xCF , 0xF3 , 0xF0 , 0x3 , 0x4C , 0x84 , 0xF7 , 0x20 , 0xDF , 0xF3 , 0xA5 , 0xBA , 0xD0 , 0x3 , 0x4C , 0x90 , 0xF7 , 0xC9 , 0x3 , 0xF0 , 0xF , 0xB0 , 0x11 , 0xC9 , 0x2 , 0xD0 , 0x3 , 0x4C , 0xBC , 0xF0 , 0xA6 , 0xB9 , 0xE0 , 0x60 , 0xF0 , 0xEA , 0x85 , 0x9A , 0x18 , 0x60 , 0xAA , 0x20 , 0x17 , 0xEE , 0xA5 , 0xB9 , 0x10 , 0x5 , 0x20 , 0xC5 , 0xEE , 0xD0 , 0x3 , 0x20 , 0xC0 , 0xEE , 0x8A , 0x24 , 0x90 , 0x10 , 0xE7 , 0x4C , 0x8A , 0xF7 , 0x20 , 0xD4 , 0xF3 , 0xF0 , 0x2 , 0x18 , 0x60 , 0x20 , 0xDF , 0xF3 , 0x8A , 0x48 , 0xA5 , 0xBA , 0xF0 , 0x57 , 0xC9 , 0x3 , 0xF0 , 0x53 , 0xB0 , 0x4E , 0xC9 , 0x2 , 0xD0 , 0x29 , 0x68 , 0x20 , 0xB2 , 0xF3 , 0xA9 , 0x7D , 0x8D , 0x1E , 0x91 , 0xA9 , 0x6 , 0x8D , 0x10 , 0x91 , 0xA9 , 0xEE , 0x8D , 0x1C , 0x91 , 0x20 , 0x75 , 0xFE , 0xA5 , 0xF8 , 0xF0 , 0x1 , 0xC8 , 0xA5 , 0xFA , 0xF0 , 0x1 , 0xC8 , 0xA9 , 0x0 , 0x85 , 0xF8 , 0x85 , 0xFA , 0x4C , 0x3C , 0xF5 , 0xA5 , 0xB9 , 0x29 , 0xF , 0xF0 , 0x1E , 0x20 , 0x4D , 0xF8 , 0xA9 , 0x0 , 0x20 , 0x90 , 0xF2 , 0x4C , 0xCF , 0xE4 , 0xB0 , 0x2E , 0xA5 , 0xB9 , 0xC9 , 0x62 , 0xD0 , 0xB , 0xA9 , 0x5 , 0x20 , 0xE7 , 0xF7 , 0x4C , 0xB1 , 0xF3 , 0x20 , 0xDA , 0xF6 , 0x68 , 0xAA , 0xC6 , 0x98 , 0xE4 , 0x98 , 0xF0 , 0x14 , 0xA4 , 0x98 , 0xB9 , 0x59 , 0x2 , 0x9D , 0x59 , 0x2 , 0xB9 , 0x63 , 0x2 , 0x9D , 0x63 , 0x2 , 0xB9 , 0x6D , 0x2 , 0x9D , 0x6D , 0x2 , 0x18 , 0x60 , 0xA9 , 0x0 , 0x85 , 0x90 , 0x8A , 0xA6 , 0x98 , 0xCA , 0x30 , 0x15 , 0xDD , 0x59 , 0x2 , 0xD0 , 0xF8 , 0x60 , 0xBD , 0x59 , 0x2 , 0x85 , 0xB8 , 0xBD , 0x63 , 0x2 , 0x85 , 0xBA , 0xBD , 0x6D , 0x2 , 0x85 , 0xB9 , 0x60 , 0xA9 , 0x0 , 0x85 , 0x98 , 0xA2 , 0x3 , 0xE4 , 0x9A , 0xB0 , 0x3 , 0x20 , 0x4 , 0xEF , 0xE4 , 0x99 , 0xB0 , 0x3 , 0x20 , 0xF6 , 0xEE , 0x86 , 0x9A , 0xA9 , 0x0 , 0x85 , 0x99 , 0x60 , 0xA6 , 0xB8 , 0xD0 , 0x3 , 0x4C , 0x8D , 0xF7 , 0x20 , 0xCF , 0xF3 , 0xD0 , 0x3 , 0x4C , 0x81 , 0xF7 , 0xA6 , 0x98 , 0xE0 , 0xA , 0x90 , 0x3 , 0x4C , 0x7E , 0xF7 , 0xE6 , 0x98 , 0xA5 , 0xB8 , 0x9D , 0x59 , 0x2 , 0xA5 , 0xB9 , 0x9 , 0x60 , 0x85 , 0xB9 , 0x9D , 0x6D , 0x2 , 0xA5 , 0xBA , 0x9D , 0x63 , 0x2 , 0xF0 , 0x5A , 0xC9 , 0x3 , 0xF0 , 0x56 , 0x90 , 0x5 , 0x20 , 0x95 , 0xF4 , 0x90 , 0x4F , 0xC9 , 0x2 , 0xD0 , 0x3 , 0x4C , 0xC7 , 0xF4 , 0x20 , 0x4D , 0xF8 , 0xB0 , 0x3 , 0x4C , 0x96 , 0xF7 , 0xA5 , 0xB9 , 0x29 , 0xF , 0xD0 , 0x1F , 0x20 , 0x94 , 0xF8 , 0xB0 , 0x36 , 0x20 , 0x47 , 0xF6 , 0xA5 , 0xB7 , 0xF0 , 0xA , 0x20 , 0x67 , 0xF8 , 0x90 , 0x18 , 0xF0 , 0x28 , 0x4C , 0x87 , 0xF7 , 0x20 , 0xAF , 0xF7 , 0xF0 , 0x20 , 0x90 , 0xC , 0xB0 , 0xF4 , 0x20 , 0xB7 , 0xF8 , 0xB0 , 0x17 , 0xA9 , 0x4 , 0x20 , 0xE7 , 0xF7 , 0xA9 , 0xBF , 0xA4 , 0xB9 , 0xC0 , 0x60 , 0xF0 , 0x7 , 0xA0 , 0x0 , 0xA9 , 0x2 , 0x91 , 0xB2 , 0x98 , 0x85 , 0xA6 , 0x18 , 0x60 , 0xA5 , 0xB9 , 0x30 , 0x2C , 0xA4 , 0xB7 , 0xF0 , 0x28 , 0xA5 , 0xBA , 0x20 , 0x17 , 0xEE , 0xA5 , 0xB9 , 0x9 , 0xF0 , 0x20 , 0xC0 , 0xEE , 0xA5 , 0x90 , 0x10 , 0x5 , 0x68 , 0x68 , 0x4C , 0x8A , 0xF7 , 0xA5 , 0xB7 , 0xF0 , 0xC , 0xA0 , 0x0 , 0xB1 , 0xBB , 0x20 , 0xE4 , 0xEE , 0xC8 , 0xC4 , 0xB7 , 0xD0 , 0xF6 , 0x20 , 0x4 , 0xEF , 0x18 , 0x60 , 0xA9 , 0x6 , 0x8D , 0x12 , 0x91 , 0x8D , 0x10 , 0x91 , 0xA9 , 0xEE , 0x8D , 0x1C , 0x91 , 0xA0 , 0x0 , 0x8C , 0x97 , 0x2 , 0xC4 , 0xB7 , 0xF0 , 0xA , 0xB1 , 0xBB , 0x99 , 0x93 , 0x2 , 0xC8 , 0xC0 , 0x4 , 0xD0 , 0xF2 , 0x20 , 0x27 , 0xF0 , 0x8E , 0x98 , 0x2 , 0xAD , 0x93 , 0x2 , 0x29 , 0xF , 0xD0 , 0x0 , 0xA , 0xAA , 0xBD , 0x5A , 0xFF , 0xA , 0xA8 , 0xBD , 0x5B , 0xFF , 0x2A , 0x48 , 0x98 , 0x69 , 0xC8 , 0x8D , 0x99 , 0x2 , 0x68 , 0x69 , 0x0 , 0x8D , 0x9A , 0x2 , 0xAD , 0x94 , 0x2 , 0x4A , 0x90 , 0x9 , 0xAD , 0x20 , 0x91 , 0xA , 0xB0 , 0x3 , 0x4C , 0x16 , 0xF0 , 0xAD , 0x9B , 0x2 , 0x8D , 0x9C , 0x2 , 0xAD , 0x9E , 0x2 , 0x8D , 0x9D , 0x2 , 0x20 , 0x75 , 0xFE , 0xA5 , 0xF8 , 0xD0 , 0x5 , 0x88 , 0x84 , 0xF8 , 0x86 , 0xF7 , 0xA5 , 0xFA , 0xD0 , 0x5 , 0x88 , 0x84 , 0xFA , 0x86 , 0xF9 , 0x38 , 0xA9 , 0xF0 , 0x4C , 0x7B , 0xFE , 0x86 , 0xC3 , 0x84 , 0xC4 , 0x6C , 0x30 , 0x3 , 0x85 , 0x93 , 0xA9 , 0x0 , 0x85 , 0x90 , 0xA5 , 0xBA , 0xD0 , 0x3 , 0x4C , 0x96 , 0xF7 , 0xC9 , 0x3 , 0xF0 , 0xF9 , 0x90 , 0x6E , 0xA4 , 0xB7 , 0xD0 , 0x3 , 0x4C , 0x93 , 0xF7 , 0x20 , 0xBC , 0xE4 , 0xA9 , 0x60 , 0x85 , 0xB9 , 0x20 , 0x95 , 0xF4 , 0xA5 , 0xBA , 0x20 , 0x14 , 0xEE , 0xA5 , 0xB9 , 0x20 , 0xCE , 0xEE , 0x20 , 0x19 , 0xEF , 0x85 , 0xAE , 0xA5 , 0x90 , 0x4A , 0x4A , 0xB0 , 0x45 , 0x20 , 0x19 , 0xEF , 0x85 , 0xAF , 0x20 , 0xC1 , 0xE4 , 0xA9 , 0xFD , 0x25 , 0x90 , 0x85 , 0x90 , 0x20 , 0xE1 , 0xFF , 0xD0 , 0x3 , 0x4C , 0xCB , 0xF6 , 0x20 , 0x19 , 0xEF , 0xAA , 0xA5 , 0x90 , 0x4A , 0x4A , 0xB0 , 0xE8 , 0x8A , 0xA4 , 0x93 , 0xF0 , 0xC , 0xA0 , 0x0 , 0xD1 , 0xAE , 0xF0 , 0x8 , 0xA9 , 0x10 , 0x20 , 0x6A , 0xFE , 0x2C , 0x91 , 0xAE , 0xE6 , 0xAE , 0xD0 , 0x2 , 0xE6 , 0xAF , 0x24 , 0x90 , 0x50 , 0xCB , 0x20 , 0xF6 , 0xEE , 0x20 , 0xDA , 0xF6 , 0x90 , 0x7A , 0x4C , 0x87 , 0xF7 , 0xC9 , 0x2 , 0xD0 , 0x3 , 0x4C , 0xB9 , 0xF0 , 0x20 , 0x4D , 0xF8 , 0xB0 , 0x3 , 0x4C , 0x96 , 0xF7 , 0x20 , 0x94 , 0xF8 , 0xB0 , 0x68 , 0x20 , 0x47 , 0xF6 , 0xA5 , 0xB7 , 0xF0 , 0x9 , 0x20 , 0x67 , 0xF8 , 0x90 , 0xB , 0xF0 , 0x5A , 0xB0 , 0xD9 , 0x20 , 0xAF , 0xF7 , 0xF0 , 0x53 , 0xB0 , 0xD2 , 0xA5 , 0x90 , 0x29 , 0x10 , 0x38 , 0xD0 , 0x4A , 0xE0 , 0x1 , 0xF0 , 0x11 , 0xE0 , 0x3 , 0xD0 , 0xDD , 0xA0 , 0x1 , 0xB1 , 0xB2 , 0x85 , 0xC3 , 0xC8 , 0xB1 , 0xB2 , 0x85 , 0xC4 , 0xB0 , 0x4 , 0xA5 , 0xB9 , 0xD0 , 0xEF , 0xA0 , 0x3 , 0xB1 , 0xB2 , 0xA0 , 0x1 , 0xF1 , 0xB2 , 0xAA , 0xA0 , 0x4 , 0xB1 , 0xB2 , 0xA0 , 0x2 , 0xF1 , 0xB2 , 0xA8 , 0x18 , 0x8A , 0x65 , 0xC3 , 0x85 , 0xAE , 0x98 , 0x65 , 0xC4 , 0x85 , 0xAF , 0xA5 , 0xC3 , 0x85 , 0xC1 , 0xA5 , 0xC4 , 0x85 , 0xC2 , 0x20 , 0x6A , 0xF6 , 0x20 , 0xC9 , 0xF8 , 0x24 , 0x18 , 0xA6 , 0xAE , 0xA4 , 0xAF , 0x60 , 0xA5 , 0x9D , 0x10 , 0x1E , 0xA0 , 0xC , 0x20 , 0xE6 , 0xF1 , 0xA5 , 0xB7 , 0xF0 , 0x15 , 0xA0 , 0x17 , 0x20 , 0xE6 , 0xF1 , 0xA4 , 0xB7 , 0xF0 , 0xC , 0xA0 , 0x0 , 0xB1 , 0xBB , 0x20 , 0xD2 , 0xFF , 0xC8 , 0xC4 , 0xB7 , 0xD0 , 0xF6 , 0x60 , 0xA0 , 0x49 , 0xA5 , 0x93 , 0xF0 , 0x2 , 0xA0 , 0x59 , 0x4C , 0xE2 , 0xF1 , 0x86 , 0xAE , 0x84 , 0xAF , 0xAA , 0xB5 , 0x0 , 0x85 , 0xC1 , 0xB5 , 0x1 , 0x85 , 0xC2 , 0x6C , 0x32 , 0x3 , 0xA5 , 0xBA , 0xD0 , 0x3 , 0x4C , 0x96 , 0xF7 , 0xC9 , 0x3 , 0xF0 , 0xF9 , 0x90 , 0x5F , 0xA9 , 0x61 , 0x85 , 0xB9 , 0xA4 , 0xB7 , 0xD0 , 0x3 , 0x4C , 0x93 , 0xF7 , 0x20 , 0x95 , 0xF4 , 0x20 , 0x28 , 0xF7 , 0xA5 , 0xBA , 0x20 , 0x17 , 0xEE , 0xA5 , 0xB9 , 0x20 , 0xC0 , 0xEE , 0xA0 , 0x0 , 0x20 , 0xD2 , 0xFB , 0xA5 , 0xAC , 0x20 , 0xE4 , 0xEE , 0xA5 , 0xAD , 0x20 , 0xE4 , 0xEE , 0x20 , 0x11 , 0xFD , 0xB0 , 0x16 , 0xB1 , 0xAC , 0x20 , 0xE4 , 0xEE , 0x20 , 0xE1 , 0xFF , 0xD0 , 0x7 , 0x20 , 0xDA , 0xF6 , 0xA9 , 0x0 , 0x38 , 0x60 , 0x20 , 0x1B , 0xFD , 0xD0 , 0xE5 , 0x20 , 0x4 , 0xEF , 0x24 , 0xB9 , 0x30 , 0x11 , 0xA5 , 0xBA , 0x20 , 0x17 , 0xEE , 0xA5 , 0xB9 , 0x29 , 0xEF , 0x9 , 0xE0 , 0x20 , 0xC0 , 0xEE , 0x20 , 0x4 , 0xEF , 0x18 , 0x60 , 0xC9 , 0x2 , 0xD0 , 0x3 , 0x4C , 0xB9 , 0xF0 , 0x20 , 0x4D , 0xF8 , 0x90 , 0x8C , 0x20 , 0xB7 , 0xF8 , 0xB0 , 0x25 , 0x20 , 0x28 , 0xF7 , 0xA2 , 0x3 , 0xA5 , 0xB9 , 0x29 , 0x1 , 0xD0 , 0x2 , 0xA2 , 0x1 , 0x8A , 0x20 , 0xE7 , 0xF7 , 0xB0 , 0x12 , 0x20 , 0xE6 , 0xF8 , 0xB0 , 0xD , 0xA5 , 0xB9 , 0x29 , 0x2 , 0xF0 , 0x6 , 0xA9 , 0x5 , 0x20 , 0xE7 , 0xF7 , 0x24 , 0x18 , 0x60 , 0xA5 , 0x9D , 0x10 , 0xFB , 0xA0 , 0x51 , 0x20 , 0xE6 , 0xF1 , 0x4C , 0x59 , 0xF6 , 0xA2 , 0x0 , 0xE6 , 0xA2 , 0xD0 , 0x6 , 0xE6 , 0xA1 , 0xD0 , 0x2 , 0xE6 , 0xA0 , 0x38 , 0xA5 , 0xA2 , 0xE9 , 0x1 , 0xA5 , 0xA1 , 0xE9 , 0x1A , 0xA5 , 0xA0 , 0xE9 , 0x4F , 0x90 , 0x6 , 0x86 , 0xA0 , 0x86 , 0xA1 , 0x86 , 0xA2 , 0xAD , 0x2F , 0x91 , 0xCD , 0x2F , 0x91 , 0xD0 , 0xF8 , 0x85 , 0x91 , 0x60 , 0x78 , 0xA5 , 0xA2 , 0xA6 , 0xA1 , 0xA4 , 0xA0 , 0x78 , 0x85 , 0xA2 , 0x86 , 0xA1 , 0x84 , 0xA0 , 0x58 , 0x60 , 0xA5 , 0x91 , 0xC9 , 0xFE , 0xD0 , 0x7 , 0x8 , 0x20 , 0xCC , 0xFF , 0x85 , 0xC6 , 0x28 , 0x60 , 0xA9 , 0x1 , 0x2C , 0xA9 , 0x2 , 0x2C , 0xA9 , 0x3 , 0x2C , 0xA9 , 0x4 , 0x2C , 0xA9 , 0x5 , 0x2C , 0xA9 , 0x6 , 0x2C , 0xA9 , 0x7 , 0x2C , 0xA9 , 0x8 , 0x2C , 0xA9 , 0x9 , 0x48 , 0x20 , 0xCC , 0xFF , 0xA0 , 0x0 , 0x24 , 0x9D , 0x50 , 0xA , 0x20 , 0xE6 , 0xF1 , 0x68 , 0x48 , 0x9 , 0x30 , 0x20 , 0xD2 , 0xFF , 0x68 , 0x38 , 0x60 , 0xA5 , 0x93 , 0x48 , 0x20 , 0xC0 , 0xF8 , 0x68 , 0x85 , 0x93 , 0xB0 , 0x2C , 0xA0 , 0x0 , 0xB1 , 0xB2 , 0xC9 , 0x5 , 0xF0 , 0x24 , 0xC9 , 0x1 , 0xF0 , 0x8 , 0xC9 , 0x3 , 0xF0 , 0x4 , 0xC9 , 0x4 , 0xD0 , 0xE1 , 0xAA , 0x24 , 0x9D , 0x10 , 0x11 , 0xA0 , 0x63 , 0x20 , 0xE6 , 0xF1 , 0xA0 , 0x5 , 0xB1 , 0xB2 , 0x20 , 0xD2 , 0xFF , 0xC8 , 0xC0 , 0x15 , 0xD0 , 0xF6 , 0x18 , 0x88 , 0x60 , 0x85 , 0x9E , 0x20 , 0x4D , 0xF8 , 0x90 , 0x5E , 0xA5 , 0xC2 , 0x48 , 0xA5 , 0xC1 , 0x48 , 0xA5 , 0xAF , 0x48 , 0xA5 , 0xAE , 0x48 , 0xA0 , 0xBF , 0xA9 , 0x20 , 0x91 , 0xB2 , 0x88 , 0xD0 , 0xFB , 0xA5 , 0x9E , 0x91 , 0xB2 , 0xC8 , 0xA5 , 0xC1 , 0x91 , 0xB2 , 0xC8 , 0xA5 , 0xC2 , 0x91 , 0xB2 , 0xC8 , 0xA5 , 0xAE , 0x91 , 0xB2 , 0xC8 , 0xA5 , 0xAF , 0x91 , 0xB2 , 0xC8 , 0x84 , 0x9F , 0xA0 , 0x0 , 0x84 , 0x9E , 0xA4 , 0x9E , 0xC4 , 0xB7 , 0xF0 , 0xC , 0xB1 , 0xBB , 0xA4 , 0x9F , 0x91 , 0xB2 , 0xE6 , 0x9E , 0xE6 , 0x9F , 0xD0 , 0xEE , 0x20 , 0x54 , 0xF8 , 0xA9 , 0x69 , 0x85 , 0xAB , 0x20 , 0xEA , 0xF8 , 0xA8 , 0x68 , 0x85 , 0xAE , 0x68 , 0x85 , 0xAF , 0x68 , 0x85 , 0xC1 , 0x68 , 0x85 , 0xC2 , 0x98 , 0x60 , 0xA6 , 0xB2 , 0xA4 , 0xB3 , 0xC0 , 0x2 , 0x60 , 0x20 , 0x4D , 0xF8 , 0x8A , 0x85 , 0xC1 , 0x18 , 0x69 , 0xC0 , 0x85 , 0xAE , 0x98 , 0x85 , 0xC2 , 0x69 , 0x0 , 0x85 , 0xAF , 0x60 , 0x20 , 0xAF , 0xF7 , 0xB0 , 0x1D , 0xA0 , 0x5 , 0x84 , 0x9F , 0xA0 , 0x0 , 0x84 , 0x9E , 0xC4 , 0xB7 , 0xF0 , 0x10 , 0xB1 , 0xBB , 0xA4 , 0x9F , 0xD1 , 0xB2 , 0xD0 , 0xE7 , 0xE6 , 0x9E , 0xE6 , 0x9F , 0xA4 , 0x9E , 0xD0 , 0xEC , 0x18 , 0x60 , 0x20 , 0x4D , 0xF8 , 0xE6 , 0xA6 , 0xA4 , 0xA6 , 0xC0 , 0xC0 , 0x60 , 0x20 , 0xAB , 0xF8 , 0xF0 , 0x1C , 0xA0 , 0x1B , 0x20 , 0xE6 , 0xF1 , 0x20 , 0x4B , 0xF9 , 0x20 , 0xAB , 0xF8 , 0xD0 , 0xF8 , 0xA0 , 0x6A , 0x4C , 0xE6 , 0xF1 , 0xA9 , 0x40 , 0x2C , 0x1F , 0x91 , 0xD0 , 0x3 , 0x2C , 0x1F , 0x91 , 0x18 , 0x60 , 0x20 , 0xAB , 0xF8 , 0xF0 , 0xF9 , 0xA0 , 0x2E , 0xD0 , 0xDB , 0xA9 , 0x0 , 0x85 , 0x90 , 0x85 , 0x93 , 0x20 , 0x54 , 0xF8 , 0x20 , 0x94 , 0xF8 , 0xB0 , 0x1F , 0x78 , 0xA9 , 0x0 , 0x85 , 0xAA , 0x85 , 0xB4 , 0x85 , 0xB0 , 0x85 , 0x9E , 0x85 , 0x9F , 0x85 , 0x9C , 0xA9 , 0x82 , 0xA2 , 0xE , 0xD0 , 0x11 , 0x20 , 0x54 , 0xF8 , 0xA9 , 0x14 , 0x85 , 0xAB , 0x20 , 0xB7 , 0xF8 , 0xB0 , 0x68 , 0x78 , 0xA9 , 0xA0 , 0xA2 , 0x8 , 0xA0 , 0x7F , 0x8C , 0x2E , 0x91 , 0x8D , 0x2E , 0x91 , 0x20 , 0x60 , 0xF1 , 0xAD , 0x14 , 0x3 , 0x8D , 0x9F , 0x2 , 0xAD , 0x15 , 0x3 , 0x8D , 0xA0 , 0x2 , 0x20 , 0xFB , 0xFC , 0xA9 , 0x2 , 0x85 , 0xBE , 0x20 , 0xDB , 0xFB , 0xAD , 0x1C , 0x91 , 0x29 , 0xFD , 0x9 , 0xC , 0x8D , 0x1C , 0x91 , 0x85 , 0xC0 , 0xA2 , 0xFF , 0xA0 , 0xFF , 0x88 , 0xD0 , 0xFD , 0xCA , 0xD0 , 0xF8 , 0x8D , 0x29 , 0x91 , 0x58 , 0xAD , 0xA0 , 0x2 , 0xCD , 0x15 , 0x3 , 0x18 , 0xF0 , 0x1F , 0x20 , 0x4B , 0xF9 , 0xAD , 0x2D , 0x91 , 0x29 , 0x40 , 0xF0 , 0xED , 0xAD , 0x14 , 0x91 , 0x20 , 0x34 , 0xF7 , 0x4C , 0x2F , 0xF9 , 0x20 , 0xE1 , 0xFF , 0x18 , 0xD0 , 0xB , 0x20 , 0xCF , 0xFC , 0x38 , 0x68 , 0x68 , 0xA9 , 0x0 , 0x8D , 0xA0 , 0x2 , 0x60 , 0x86 , 0xB1 , 0xA5 , 0xB0 , 0xA , 0xA , 0x18 , 0x65 , 0xB0 , 0x18 , 0x65 , 0xB1 , 0x85 , 0xB1 , 0xA9 , 0x0 , 0x24 , 0xB0 , 0x30 , 0x1 , 0x2A , 0x6 , 0xB1 , 0x2A , 0x6 , 0xB1 , 0x2A , 0xAA , 0xAD , 0x28 , 0x91 , 0xC9 , 0x15 , 0x90 , 0xF9 , 0x65 , 0xB1 , 0x8D , 0x24 , 0x91 , 0x8A , 0x6D , 0x29 , 0x91 , 0x8D , 0x25 , 0x91 , 0x58 , 0x60 , 0xAE , 0x29 , 0x91 , 0xA0 , 0xFF , 0x98 , 0xED , 0x28 , 0x91 , 0xEC , 0x29 , 0x91 , 0xD0 , 0xF2 , 0x86 , 0xB1 , 0xAA , 0x8C , 0x28 , 0x91 , 0x8C , 0x29 , 0x91 , 0x98 , 0xE5 , 0xB1 , 0x86 , 0xB1 , 0x4A , 0x66 , 0xB1 , 0x4A , 0x66 , 0xB1 , 0xA5 , 0xB0 , 0x18 , 0x69 , 0x3C , 0x2C , 0x21 , 0x91 , 0xC5 , 0xB1 , 0xB0 , 0x4A , 0xA6 , 0x9C , 0xF0 , 0x3 , 0x4C , 0xAD , 0xFA , 0xA6 , 0xA3 , 0x30 , 0x1B , 0xA2 , 0x0 , 0x69 , 0x30 , 0x65 , 0xB0 , 0xC5 , 0xB1 , 0xB0 , 0x1C , 0xE8 , 0x69 , 0x26 , 0x65 , 0xB0 , 0xC5 , 0xB1 , 0xB0 , 0x17 , 0x69 , 0x2C , 0x65 , 0xB0 , 0xC5 , 0xB1 , 0x90 , 0x3 , 0x4C , 0x60 , 0xFA , 0xA5 , 0xB4 , 0xF0 , 0x1D , 0x85 , 0xA8 , 0xD0 , 0x19 , 0xE6 , 0xA9 , 0xB0 , 0x2 , 0xC6 , 0xA9 , 0x38 , 0xE9 , 0x13 , 0xE5 , 0xB1 , 0x65 , 0x92 , 0x85 , 0x92 , 0xA5 , 0xA4 , 0x49 , 0x1 , 0x85 , 0xA4 , 0xF0 , 0x21 , 0x86 , 0xD7 , 0xA5 , 0xB4 , 0xF0 , 0x18 , 0x2C , 0x2D , 0x91 , 0x50 , 0x13 , 0xA9 , 0x0 , 0x85 , 0xA4 , 0xA5 , 0xA3 , 0x10 , 0x30 , 0x30 , 0xC9 , 0xA2 , 0xA6 , 0x20 , 0x5D , 0xF9 , 0xA5 , 0x9B , 0xD0 , 0xC3 , 0x4C , 0x56 , 0xFF , 0xA5 , 0x92 , 0xF0 , 0x7 , 0x30 , 0x3 , 0xC6 , 0xB0 , 0x2C , 0xE6 , 0xB0 , 0xA9 , 0x0 , 0x85 , 0x92 , 0xE4 , 0xD7 , 0xD0 , 0xF , 0x8A , 0xD0 , 0xAA , 0xA5 , 0xA9 , 0x30 , 0xC7 , 0xC9 , 0x10 , 0x90 , 0xC3 , 0x85 , 0x96 , 0xB0 , 0xBF , 0x8A , 0x45 , 0x9B , 0x85 , 0x9B , 0xA5 , 0xB4 , 0xF0 , 0xD2 , 0xC6 , 0xA3 , 0x30 , 0xC5 , 0x46 , 0xD7 , 0x66 , 0xBF , 0xA2 , 0xDA , 0x20 , 0x5D , 0xF9 , 0x4C , 0x56 , 0xFF , 0xA5 , 0x96 , 0xF0 , 0x4 , 0xA5 , 0xB4 , 0xF0 , 0x4 , 0xA5 , 0xA3 , 0x10 , 0x85 , 0x46 , 0xB1 , 0xA9 , 0x93 , 0x38 , 0xE5 , 0xB1 , 0x65 , 0xB0 , 0xA , 0xAA , 0x20 , 0x5D , 0xF9 , 0xE6 , 0x9C , 0xA5 , 0xB4 , 0xD0 , 0x11 , 0xA5 , 0x96 , 0xF0 , 0x26 , 0x85 , 0xA8 , 0xA9 , 0x0 , 0x85 , 0x96 , 0xA9 , 0xC0 , 0x8D , 0x2E , 0x91 , 0x85 , 0xB4 , 0xA5 , 0x96 , 0x85 , 0xB5 , 0xF0 , 0x9 , 0xA9 , 0x0 , 0x85 , 0xB4 , 0xA9 , 0x40 , 0x8D , 0x2E , 0x91 , 0xA5 , 0xBF , 0x85 , 0xBD , 0xA5 , 0xA8 , 0x5 , 0xA9 , 0x85 , 0xB6 , 0x4C , 0x56 , 0xFF , 0x20 , 0xDB , 0xFB , 0x85 , 0x9C , 0xA2 , 0xDA , 0x20 , 0x5D , 0xF9 , 0xA5 , 0xBE , 0xF0 , 0x2 , 0x85 , 0xA7 , 0xA9 , 0xF , 0x24 , 0xAA , 0x10 , 0x17 , 0xA5 , 0xB5 , 0xD0 , 0xC , 0xA6 , 0xBE , 0xCA , 0xD0 , 0xB , 0xA9 , 0x8 , 0x20 , 0x6A , 0xFE , 0xD0 , 0x4 , 0xA9 , 0x0 , 0x85 , 0xAA , 0x4C , 0x56 , 0xFF , 0x70 , 0x31 , 0xD0 , 0x18 , 0xA5 , 0xB5 , 0xD0 , 0xF5 , 0xA5 , 0xB6 , 0xD0 , 0xF1 , 0xA5 , 0xA7 , 0x4A , 0xA5 , 0xBD , 0x30 , 0x3 , 0x90 , 0x18 , 0x18 , 0xB0 , 0x15 , 0x29 , 0xF , 0x85 , 0xAA , 0xC6 , 0xAA , 0xD0 , 0xDD , 0xA9 , 0x40 , 0x85 , 0xAA , 0x20 , 0xD2 , 0xFB , 0xA9 , 0x0 , 0x85 , 0xAB , 0xF0 , 0xD0 , 0xA9 , 0x80 , 0x85 , 0xAA , 0xD0 , 0xCA , 0xA5 , 0xB5 , 0xF0 , 0xA , 0xA9 , 0x4 , 0x20 , 0x6A , 0xFE , 0xA9 , 0x0 , 0x4C , 0x97 , 0xFB , 0x20 , 0x11 , 0xFD , 0x90 , 0x3 , 0x4C , 0x95 , 0xFB , 0xA6 , 0xA7 , 0xCA , 0xF0 , 0x2D , 0xA5 , 0x93 , 0xF0 , 0xC , 0xA0 , 0x0 , 0xA5 , 0xBD , 0xD1 , 0xAC , 0xF0 , 0x4 , 0xA9 , 0x1 , 0x85 , 0xB6 , 0xA5 , 0xB6 , 0xF0 , 0x4B , 0xA2 , 0x3D , 0xE4 , 0x9E , 0x90 , 0x3E , 0xA6 , 0x9E , 0xA5 , 0xAD , 0x9D , 0x1 , 0x1 , 0xA5 , 0xAC , 0x9D , 0x0 , 0x1 , 0xE8 , 0xE8 , 0x86 , 0x9E , 0x4C , 0x87 , 0xFB , 0xA6 , 0x9F , 0xE4 , 0x9E , 0xF0 , 0x35 , 0xA5 , 0xAC , 0xDD , 0x0 , 0x1 , 0xD0 , 0x2E , 0xA5 , 0xAD , 0xDD , 0x1 , 0x1 , 0xD0 , 0x27 , 0xE6 , 0x9F , 0xE6 , 0x9F , 0xA5 , 0x93 , 0xF0 , 0xB , 0xA5 , 0xBD , 0xA0 , 0x0 , 0xD1 , 0xAC , 0xF0 , 0x17 , 0xC8 , 0x84 , 0xB6 , 0xA5 , 0xB6 , 0xF0 , 0x7 , 0xA9 , 0x10 , 0x20 , 0x6A , 0xFE , 0xD0 , 0x9 , 0xA5 , 0x93 , 0xD0 , 0x5 , 0xA8 , 0xA5 , 0xBD , 0x91 , 0xAC , 0x20 , 0x1B , 0xFD , 0xD0 , 0x3A , 0xA9 , 0x80 , 0x85 , 0xAA , 0xA6 , 0xBE , 0xCA , 0x30 , 0x2 , 0x86 , 0xBE , 0xC6 , 0xA7 , 0xF0 , 0x8 , 0xA5 , 0x9E , 0xD0 , 0x27 , 0x85 , 0xBE , 0xF0 , 0x23 , 0x20 , 0xCF , 0xFC , 0x20 , 0xD2 , 0xFB , 0xA0 , 0x0 , 0x84 , 0xAB , 0xB1 , 0xAC , 0x45 , 0xAB , 0x85 , 0xAB , 0x20 , 0x1B , 0xFD , 0x20 , 0x11 , 0xFD , 0x90 , 0xF2 , 0xA5 , 0xAB , 0x45 , 0xBD , 0xF0 , 0x5 , 0xA9 , 0x20 , 0x20 , 0x6A , 0xFE , 0x4C , 0x56 , 0xFF , 0xA5 , 0xC2 , 0x85 , 0xAD , 0xA5 , 0xC1 , 0x85 , 0xAC , 0x60 , 0xA9 , 0x8 , 0x85 , 0xA3 , 0xA9 , 0x0 , 0x85 , 0xA4 , 0x85 , 0xA8 , 0x85 , 0x9B , 0x85 , 0xA9 , 0x60 , 0xA5 , 0xBD , 0x4A , 0xA9 , 0x60 , 0x90 , 0x2 , 0xA9 , 0xB0 , 0xA2 , 0x0 , 0x8D , 0x28 , 0x91 , 0x8E , 0x29 , 0x91 , 0xAD , 0x20 , 0x91 , 0x49 , 0x8 , 0x8D , 0x20 , 0x91 , 0x29 , 0x8 , 0x60 , 0x38 , 0x66 , 0xAD , 0x30 , 0x3C , 0xA5 , 0xA8 , 0xD0 , 0x12 , 0xA9 , 0x10 , 0xA2 , 0x1 , 0x20 , 0xF5 , 0xFB , 0xD0 , 0x2F , 0xE6 , 0xA8 , 0xA5 , 0xAD , 0x10 , 0x29 , 0x4C , 0x95 , 0xFC , 0xA5 , 0xA9 , 0xD0 , 0x9 , 0x20 , 0xF1 , 0xFB , 0xD0 , 0x1D , 0xE6 , 0xA9 , 0xD0 , 0x19 , 0x20 , 0xEA , 0xFB , 0xD0 , 0x14 , 0xA5 , 0xA4 , 0x49 , 0x1 , 0x85 , 0xA4 , 0xF0 , 0xF , 0xA5 , 0xBD , 0x49 , 0x1 , 0x85 , 0xBD , 0x29 , 0x1 , 0x45 , 0x9B , 0x85 , 0x9B , 0x4C , 0x56 , 0xFF , 0x46 , 0xBD , 0xC6 , 0xA3 , 0xA5 , 0xA3 , 0xF0 , 0x3A , 0x10 , 0xF3 , 0x20 , 0xDB , 0xFB , 0x58 , 0xA5 , 0xA5 , 0xF0 , 0x12 , 0xA2 , 0x0 , 0x86 , 0xD7 , 0xC6 , 0xA5 , 0xA6 , 0xBE , 0xE0 , 0x2 , 0xD0 , 0x2 , 0x9 , 0x80 , 0x85 , 0xBD , 0xD0 , 0xD9 , 0x20 , 0x11 , 0xFD , 0x90 , 0xA , 0xD0 , 0x91 , 0xE6 , 0xAD , 0xA5 , 0xD7 , 0x85 , 0xBD , 0xB0 , 0xCA , 0xA0 , 0x0 , 0xB1 , 0xAC , 0x85 , 0xBD , 0x45 , 0xD7 , 0x85 , 0xD7 , 0x20 , 0x1B , 0xFD , 0xD0 , 0xBB , 0xA5 , 0x9B , 0x49 , 0x1 , 0x85 , 0xBD , 0x4C , 0x56 , 0xFF , 0xC6 , 0xBE , 0xD0 , 0x3 , 0x20 , 0x8 , 0xFD , 0xA9 , 0x50 , 0x85 , 0xA7 , 0xA2 , 0x8 , 0x78 , 0x20 , 0xFB , 0xFC , 0xD0 , 0xEA , 0xA9 , 0x78 , 0x20 , 0xF3 , 0xFB , 0xD0 , 0xE3 , 0xC6 , 0xA7 , 0xD0 , 0xDF , 0x20 , 0xDB , 0xFB , 0xC6 , 0xAB , 0x10 , 0xD8 , 0xA2 , 0xA , 0x20 , 0xFB , 0xFC , 0x58 , 0xE6 , 0xAB , 0xA5 , 0xBE , 0xF0 , 0x30 , 0x20 , 0xD2 , 0xFB , 0xA2 , 0x9 , 0x86 , 0xA5 , 0xD0 , 0x85 , 0x8 , 0x78 , 0x20 , 0x8 , 0xFD , 0xA9 , 0x7F , 0x8D , 0x2E , 0x91 , 0xA9 , 0xF7 , 0x8D , 0x20 , 0x91 , 0xA9 , 0x40 , 0x8D , 0x2B , 0x91 , 0x20 , 0x39 , 0xFE , 0xAD , 0xA0 , 0x2 , 0xF0 , 0x9 , 0x8D , 0x15 , 0x3 , 0xAD , 0x9F , 0x2 , 0x8D , 0x14 , 0x3 , 0x28 , 0x60 , 0x20 , 0xCF , 0xFC , 0xF0 , 0x97 , 0xBD , 0xE9 , 0xFD , 0x8D , 0x14 , 0x3 , 0xBD , 0xEA , 0xFD , 0x8D , 0x15 , 0x3 , 0x60 , 0xAD , 0x1C , 0x91 , 0x9 , 0xE , 0x8D , 0x1C , 0x91 , 0x60 , 0x38 , 0xA5 , 0xAC , 0xE5 , 0xAE , 0xA5 , 0xAD , 0xE5 , 0xAF , 0x60 , 0xE6 , 0xAC , 0xD0 , 0x2 , 0xE6 , 0xAD , 0x60 , 0xA2 , 0xFF , 0x78 , 0x9A , 0xD8 , 0x20 , 0x3F , 0xFD , 0xD0 , 0x3 , 0x6C , 0x0 , 0xA0 , 0x20 , 0x8D , 0xFD , 0x20 , 0x52 , 0xFD , 0x20 , 0xF9 , 0xFD , 0x20 , 0x18 , 0xE5 , 0x58 , 0x6C , 0x0 , 0xC0 , 0xA2 , 0x5 , 0xBD , 0x4C , 0xFD , 0xDD , 0x3 , 0xA0 , 0xD0 , 0x3 , 0xCA , 0xD0 , 0xF5 , 0x60 , 0x41 , 0x30 , 0xC3 , 0xC2 , 0xCD , 0xA2 , 0x6D , 0xA0 , 0xFD , 0x18 , 0x86 , 0xC3 , 0x84 , 0xC4 , 0xA0 , 0x1F , 0xB9 , 0x14 , 0x3 , 0xB0 , 0x2 , 0xB1 , 0xC3 , 0x91 , 0xC3 , 0x99 , 0x14 , 0x3 , 0x88 , 0x10 , 0xF1 , 0x60 , 0xBF , 0xEA , 0xD2 , 0xFE , 0xAD , 0xFE , 0xA , 0xF4 , 0x4A , 0xF3 , 0xC7 , 0xF2 , 0x9 , 0xF3 , 0xF3 , 0xF3 , 0xE , 0xF2 , 0x7A , 0xF2 , 0x70 , 0xF7 , 0xF5 , 0xF1 , 0xEF , 0xF3 , 0xD2 , 0xFE , 0x49 , 0xF5 , 0x85 , 0xF6 , 0xA9 , 0x0 , 0xAA , 0x95 , 0x0 , 0x9D , 0x0 , 0x2 , 0x9D , 0x0 , 0x3 , 0xE8 , 0xD0 , 0xF5 , 0xA2 , 0x3C , 0xA0 , 0x3 , 0x86 , 0xB2 , 0x84 , 0xB3 , 0x85 , 0xC1 , 0x85 , 0x97 , 0x8D , 0x81 , 0x2 , 0xA8 , 0xA9 , 0x4 , 0x85 , 0xC2 , 0xE6 , 0xC1 , 0xD0 , 0x2 , 0xE6 , 0xC2 , 0x20 , 0x91 , 0xFE , 0xA5 , 0x97 , 0xF0 , 0x22 , 0xB0 , 0xF1 , 0xA4 , 0xC2 , 0xA6 , 0xC1 , 0xC0 , 0x20 , 0x90 , 0x25 , 0xC0 , 0x21 , 0xB0 , 0x8 , 0xA0 , 0x1E , 0x8C , 0x88 , 0x2 , 0x4C , 0x7B , 0xFE , 0xA9 , 0x12 , 0x8D , 0x82 , 0x2 , 0xA9 , 0x10 , 0x8D , 0x88 , 0x2 , 0xD0 , 0xF1 , 0x90 , 0xCF , 0xA5 , 0xC2 , 0x8D , 0x82 , 0x2 , 0x85 , 0x97 , 0xC9 , 0x11 , 0x90 , 0xC4 , 0x20 , 0xC3 , 0xE5 , 0x4C , 0xEB , 0xFD , 0xA8 , 0xFC , 0xB , 0xFC , 0xBF , 0xEA , 0x8E , 0xF9 , 0xA9 , 0x7F , 0x8D , 0x1E , 0x91 , 0x8D , 0x2E , 0x91 , 0xA9 , 0x40 , 0x8D , 0x2B , 0x91 , 0xA9 , 0x40 , 0x8D , 0x1B , 0x91 , 0xA9 , 0xFE , 0x8D , 0x1C , 0x91 , 0xA9 , 0xDE , 0x8D , 0x2C , 0x91 , 0xA2 , 0x0 , 0x8E , 0x12 , 0x91 , 0xA2 , 0xFF , 0x8E , 0x22 , 0x91 , 0xA2 , 0x0 , 0x8E , 0x23 , 0x91 , 0xA2 , 0x80 , 0x8E , 0x13 , 0x91 , 0xA2 , 0x0 , 0x8E , 0x1F , 0x91 , 0x20 , 0x84 , 0xEF , 0xA9 , 0x82 , 0x8D , 0x1E , 0x91 , 0x20 , 0x8D , 0xEF , 0xA9 , 0xC0 , 0x8D , 0x2E , 0x91 , 0xA9 , 0x26 , 0x8D , 0x24 , 0x91 , 0xA9 , 0x48 , 0x8D , 0x25 , 0x91 , 0x60 , 0x85 , 0xB7 , 0x86 , 0xBB , 0x84 , 0xBC , 0x60 , 0x85 , 0xB8 , 0x86 , 0xBA , 0x84 , 0xB9 , 0x60 , 0xA5 , 0xBA , 0xC9 , 0x2 , 0xD0 , 0xB , 0xAD , 0x97 , 0x2 , 0xA9 , 0x0 , 0x8D , 0x97 , 0x2 , 0x60 , 0x85 , 0x9D , 0xA5 , 0x90 , 0x5 , 0x90 , 0x85 , 0x90 , 0x60 , 0x8D , 0x85 , 0x2 , 0x60 , 0x90 , 0x6 , 0xAE , 0x83 , 0x2 , 0xAC , 0x84 , 0x2 , 0x8E , 0x83 , 0x2 , 0x8C , 0x84 , 0x2 , 0x60 , 0x90 , 0x6 , 0xAE , 0x81 , 0x2 , 0xAC , 0x82 , 0x2 , 0x8E , 0x81 , 0x2 , 0x8C , 0x82 , 0x2 , 0x60 , 0xB1 , 0xC1 , 0xAA , 0xA9 , 0x55 , 0x91 , 0xC1 , 0xD1 , 0xC1 , 0xD0 , 0x8 , 0x6A , 0x91 , 0xC1 , 0xD1 , 0xC1 , 0xD0 , 0x1 , 0xA9 , 0x18 , 0x8A , 0x91 , 0xC1 , 0x60 , 0x78 , 0x6C , 0x18 , 0x3 , 0x48 , 0x8A , 0x48 , 0x98 , 0x48 , 0xAD , 0x1D , 0x91 , 0x10 , 0x48 , 0x2D , 0x1E , 0x91 , 0xAA , 0x29 , 0x2 , 0xF0 , 0x1F , 0x20 , 0x3F , 0xFD , 0xD0 , 0x3 , 0x6C , 0x2 , 0xA0 , 0x2C , 0x11 , 0x91 , 0x20 , 0x34 , 0xF7 , 0x20 , 0xE1 , 0xFF , 0xD0 , 0x2D , 0x20 , 0x52 , 0xFD , 0x20 , 0xF9 , 0xFD , 0x20 , 0x18 , 0xE5 , 0x6C , 0x2 , 0xC0 , 0xAD , 0x1E , 0x91 , 0x9 , 0x80 , 0x48 , 0xA9 , 0x7F , 0x8D , 0x1E , 0x91 , 0x8A , 0x29 , 0x40 , 0xF0 , 0x14 , 0xA9 , 0xCE , 0x5 , 0xB5 , 0x8D , 0x1C , 0x91 , 0xAD , 0x14 , 0x91 , 0x68 , 0x8D , 0x1E , 0x91 , 0x20 , 0xA3 , 0xEF , 0x4C , 0x56 , 0xFF , 0x8A , 0x29 , 0x20 , 0xF0 , 0x25 , 0xAD , 0x10 , 0x91 , 0x29 , 0x1 , 0x85 , 0xA7 , 0xAD , 0x18 , 0x91 , 0xE9 , 0x16 , 0x6D , 0x99 , 0x2 , 0x8D , 0x18 , 0x91 , 0xAD , 0x19 , 0x91 , 0x6D , 0x9A , 0x2 , 0x8D , 0x19 , 0x91 , 0x68 , 0x8D , 0x1E , 0x91 , 0x20 , 0x36 , 0xF0 , 0x4C , 0x56 , 0xFF , 0x8A , 0x29 , 0x10 , 0xF0 , 0x25 , 0xAD , 0x93 , 0x2 , 0x29 , 0xF , 0xD0 , 0x0 , 0xA , 0xAA , 0xBD , 0x5A , 0xFF , 0x8D , 0x18 , 0x91 , 0xBD , 0x5B , 0xFF , 0x8D , 0x19 , 0x91 , 0xAD , 0x10 , 0x91 , 0x68 , 0x9 , 0x20 , 0x29 , 0xEF , 0x8D , 0x1E , 0x91 , 0xAE , 0x98 , 0x2 , 0x86 , 0xA8 , 0x68 , 0xA8 , 0x68 , 0xAA , 0x68 , 0x40 , 0xE6 , 0x2A , 0x78 , 0x1C , 0x49 , 0x13 , 0xB1 , 0xF , 0xA , 0xE , 0xD3 , 0x6 , 0x38 , 0x3 , 0x6A , 0x1 , 0xD0 , 0x0 , 0x83 , 0x0 , 0x36 , 0x0 , 0x48 , 0x8A , 0x48 , 0x98 , 0x48 , 0xBA , 0xBD , 0x4 , 0x1 , 0x29 , 0x10 , 0xF0 , 0x3 , 0x6C , 0x16 , 0x3 , 0x6C , 0x14 , 0x3 , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0x4C , 0x52 , 0xFD , 0x4C , 0x57 , 0xFD , 0x4C , 0x66 , 0xFE , 0x4C , 0xC0 , 0xEE , 0x4C , 0xCE , 0xEE , 0x4C , 0x73 , 0xFE , 0x4C , 0x82 , 0xFE , 0x4C , 0x1E , 0xEB , 0x4C , 0x6F , 0xFE , 0x4C , 0x19 , 0xEF , 0x4C , 0xE4 , 0xEE , 0x4C , 0xF6 , 0xEE , 0x4C , 0x4 , 0xEF , 0x4C , 0x17 , 0xEE , 0x4C , 0x14 , 0xEE , 0x4C , 0x57 , 0xFE , 0x4C , 0x50 , 0xFE , 0x4C , 0x49 , 0xFE , 0x6C , 0x1A , 0x3 , 0x6C , 0x1C , 0x3 , 0x6C , 0x1E , 0x3 , 0x6C , 0x20 , 0x3 , 0x6C , 0x22 , 0x3 , 0x6C , 0x24 , 0x3 , 0x6C , 0x26 , 0x3 , 0x4C , 0x42 , 0xF5 , 0x4C , 0x75 , 0xF6 , 0x4C , 0x67 , 0xF7 , 0x4C , 0x60 , 0xF7 , 0x6C , 0x28 , 0x3 , 0x6C , 0x2A , 0x3 , 0x6C , 0x2C , 0x3 , 0x4C , 0x34 , 0xF7 , 0x4C , 0x5 , 0xE5 , 0x4C , 0xA , 0xE5 , 0x4C , 0x0 , 0xE5 , 0xFF , 0xFF , 0xFF , 0xFF , 0xA9 , 0xFE , 0x22 , 0xFD , 0x72 , 0xFF +}; + +uint8_t read6502(uint16_t address) { + + if (address >= 0xC000) { + return(pgm_read_byte_near(BIOS + (address - 0xC000))); + } + + if (address < RAM_SIZE) return(RAM[address]); + return(readEEPROM(address) ); + +} + +void write6502(uint16_t address, uint8_t value) { + if (address < RAM_SIZE) { + RAM[address] = value; + } + else { + writeEEPROM(address, value ); + + } + +} + + +//a few general functions used by various other functions +void push16(uint16_t pushval) { + write6502(BASE_STACK + sp, (pushval >> 8) & 0xFF); + write6502(BASE_STACK + ((sp - 1) & 0xFF), pushval & 0xFF); + sp -= 2; +} + +void push8(uint8_t pushval) { + write6502(BASE_STACK + sp--, pushval); +} + +uint16_t pull16() { + uint16_t temp16; + temp16 = read6502(BASE_STACK + ((sp + 1) & 0xFF)) | ((uint16_t)read6502(BASE_STACK + ((sp + 2) & 0xFF)) << 8); + sp += 2; + return(temp16); +} + +uint8_t pull8() { + return (read6502(BASE_STACK + ++sp)); +} + +void reset6502() { + pc = (uint16_t)read6502(0xFFFC) | ((uint16_t)read6502(0xFFFD) << 8); + a = 0; + x = 0; + y = 0; + sp = 0xFD; + cpustatus |= FLAG_CONSTANT; +} + +//addressing mode functions, calculates effective addresses +void imp() { //implied +} + +void acc() { //accumulator + useaccum = 1; +} + +void imm() { //immediate + ea = pc++; +} + +void zp() { //zero-page + ea = (uint16_t)read6502((uint16_t)pc++); +} + +void zpx() { //zero-page,X + ea = ((uint16_t)read6502((uint16_t)pc++) + (uint16_t)x) & 0xFF; //zero-page wraparound +} + +void zpy() { //zero-page,Y + ea = ((uint16_t)read6502((uint16_t)pc++) + (uint16_t)y) & 0xFF; //zero-page wraparound +} + +void rel() { //relative for branch ops (8-bit immediate value, sign-extended) + reladdr = (uint16_t)read6502(pc++); + if (reladdr & 0x80) reladdr |= 0xFF00; +} + +void abso() { //absolute + ea = (uint16_t)read6502(pc) | ((uint16_t)read6502(pc+1) << 8); + pc += 2; +} + +void absx() { //absolute,X + uint16_t startpage; + ea = ((uint16_t)read6502(pc) | ((uint16_t)read6502(pc+1) << 8)); + startpage = ea & 0xFF00; + ea += (uint16_t)x; + + pc += 2; +} + +void absy() { //absolute,Y + uint16_t startpage; + ea = ((uint16_t)read6502(pc) | ((uint16_t)read6502(pc+1) << 8)); + startpage = ea & 0xFF00; + ea += (uint16_t)y; + + pc += 2; +} + +void ind() { //indirect + uint16_t eahelp, eahelp2; + eahelp = (uint16_t)read6502(pc) | (uint16_t)((uint16_t)read6502(pc+1) << 8); + eahelp2 = (eahelp & 0xFF00) | ((eahelp + 1) & 0x00FF); //replicate 6502 page-boundary wraparound bug + ea = (uint16_t)read6502(eahelp) | ((uint16_t)read6502(eahelp2) << 8); + pc += 2; +} + +void indx() { // (indirect,X) + uint16_t eahelp; + eahelp = (uint16_t)(((uint16_t)read6502(pc++) + (uint16_t)x) & 0xFF); //zero-page wraparound for table pointer + ea = (uint16_t)read6502(eahelp & 0x00FF) | ((uint16_t)read6502((eahelp+1) & 0x00FF) << 8); +} + +void indy() { // (indirect),Y + uint16_t eahelp, eahelp2, startpage; + eahelp = (uint16_t)read6502(pc++); + eahelp2 = (eahelp & 0xFF00) | ((eahelp + 1) & 0x00FF); //zero-page wraparound + ea = (uint16_t)read6502(eahelp) | ((uint16_t)read6502(eahelp2) << 8); + startpage = ea & 0xFF00; + ea += (uint16_t)y; + +} + +static uint16_t getvalue() { + if (useaccum) return((uint16_t)a); + else return((uint16_t)read6502(ea)); +} + +static uint16_t getvalue16() { + return((uint16_t)read6502(ea) | ((uint16_t)read6502(ea+1) << 8)); +} + +void putvalue(uint16_t saveval) { + if (useaccum) a = (uint8_t)(saveval & 0x00FF); + else write6502(ea, (saveval & 0x00FF)); +} + + +//instruction handler functions +void adc() { + value = getvalue(); + result = (uint16_t)a + value + (uint16_t)(cpustatus & FLAG_CARRY); + + carrycalc(result); + zerocalc(result); + overflowcalc(result, a, value); + signcalc(result); + + #ifndef NES_CPU + if (cpustatus & FLAG_DECIMAL) { + clearcarry(); + + if ((a & 0x0F) > 0x09) { + a += 0x06; + } + if ((a & 0xF0) > 0x90) { + a += 0x60; + setcarry(); + } + + //clockticks6502++; + } + #endif + + saveaccum(result); +} + +void op_and() { + value = getvalue(); + result = (uint16_t)a & value; + + zerocalc(result); + signcalc(result); + + saveaccum(result); +} + +void asl() { + value = getvalue(); + result = value << 1; + + carrycalc(result); + zerocalc(result); + signcalc(result); + + putvalue(result); +} + +void bcc() { + if ((cpustatus & FLAG_CARRY) == 0) { + oldpc = pc; + pc += reladdr; + //if ((oldpc & 0xFF00) != (pc & 0xFF00)) clockticks6502 += 2; //check if jump crossed a page boundary + // else clockticks6502++; + } +} + +void bcs() { + if ((cpustatus & FLAG_CARRY) == FLAG_CARRY) { + oldpc = pc; + pc += reladdr; + //if ((oldpc & 0xFF00) != (pc & 0xFF00)) clockticks6502 += 2; //check if jump crossed a page boundary + // else clockticks6502++; + } +} + +void beq() { + if ((cpustatus & FLAG_ZERO) == FLAG_ZERO) { + oldpc = pc; + pc += reladdr; + //if ((oldpc & 0xFF00) != (pc & 0xFF00)) clockticks6502 += 2; //check if jump crossed a page boundary + // else clockticks6502++; + } +} + +void op_bit() { + value = getvalue(); + result = (uint16_t)a & value; + + zerocalc(result); + cpustatus = (cpustatus & 0x3F) | (uint8_t)(value & 0xC0); +} + +void bmi() { + if ((cpustatus & FLAG_SIGN) == FLAG_SIGN) { + oldpc = pc; + pc += reladdr; + //if ((oldpc & 0xFF00) != (pc & 0xFF00)) clockticks6502 += 2; //check if jump crossed a page boundary + // else clockticks6502++; + } +} + +void bne() { + if ((cpustatus & FLAG_ZERO) == 0) { + oldpc = pc; + pc += reladdr; + //if ((oldpc & 0xFF00) != (pc & 0xFF00)) clockticks6502 += 2; //check if jump crossed a page boundary + // else clockticks6502++; + } +} + +void bpl() { + if ((cpustatus & FLAG_SIGN) == 0) { + oldpc = pc; + pc += reladdr; + //if ((oldpc & 0xFF00) != (pc & 0xFF00)) clockticks6502 += 2; //check if jump crossed a page boundary + // else clockticks6502++; + } +} + +void brk() { + pc++; + push16(pc); //push next instruction address onto stack + push8(cpustatus | FLAG_BREAK); //push CPU cpustatus to stack + setinterrupt(); //set interrupt flag + pc = (uint16_t)read6502(0xFFFE) | ((uint16_t)read6502(0xFFFF) << 8); +} + +void bvc() { + if ((cpustatus & FLAG_OVERFLOW) == 0) { + oldpc = pc; + pc += reladdr; + //if ((oldpc & 0xFF00) != (pc & 0xFF00)) clockticks6502 += 2; //check if jump crossed a page boundary + // else clockticks6502++; + } +} + +void bvs() { + if ((cpustatus & FLAG_OVERFLOW) == FLAG_OVERFLOW) { + oldpc = pc; + pc += reladdr; + //if ((oldpc & 0xFF00) != (pc & 0xFF00)) clockticks6502 += 2; //check if jump crossed a page boundary + // else clockticks6502++; + } +} + +void clc() { + clearcarry(); +} + +void cld() { + cleardecimal(); +} + +void cli() { + clearinterrupt(); +} + +void clv() { + clearoverflow(); +} + +void cmp() { + value = getvalue(); + result = (uint16_t)a - value; + + if (a >= (uint8_t)(value & 0x00FF)) setcarry(); + else clearcarry(); + if (a == (uint8_t)(value & 0x00FF)) setzero(); + else clearzero(); + signcalc(result); +} + +void cpx() { + value = getvalue(); + result = (uint16_t)x - value; + + if (x >= (uint8_t)(value & 0x00FF)) setcarry(); + else clearcarry(); + if (x == (uint8_t)(value & 0x00FF)) setzero(); + else clearzero(); + signcalc(result); +} + +void cpy() { + value = getvalue(); + result = (uint16_t)y - value; + + if (y >= (uint8_t)(value & 0x00FF)) setcarry(); + else clearcarry(); + if (y == (uint8_t)(value & 0x00FF)) setzero(); + else clearzero(); + signcalc(result); +} + +void dec() { + value = getvalue(); + result = value - 1; + + zerocalc(result); + signcalc(result); + + putvalue(result); +} + +void dex() { + x--; + + zerocalc(x); + signcalc(x); +} + +void dey() { + y--; + + zerocalc(y); + signcalc(y); +} + +void eor() { + value = getvalue(); + result = (uint16_t)a ^ value; + + zerocalc(result); + signcalc(result); + + saveaccum(result); +} + +void inc() { + value = getvalue(); + result = value + 1; + + zerocalc(result); + signcalc(result); + + putvalue(result); +} + +void inx() { + x++; + + zerocalc(x); + signcalc(x); +} + +void iny() { + y++; + + zerocalc(y); + signcalc(y); +} + +void jmp() { + pc = ea; +} + +void jsr() { + push16(pc - 1); + pc = ea; +} + +void lda() { + value = getvalue(); + a = (uint8_t)(value & 0x00FF); + + zerocalc(a); + signcalc(a); +} + +void ldx() { + value = getvalue(); + x = (uint8_t)(value & 0x00FF); + + zerocalc(x); + signcalc(x); +} + +void ldy() { + value = getvalue(); + y = (uint8_t)(value & 0x00FF); + + zerocalc(y); + signcalc(y); +} + +void lsr() { + value = getvalue(); + result = value >> 1; + + if (value & 1) setcarry(); + else clearcarry(); + zerocalc(result); + signcalc(result); + + putvalue(result); +} + +void nop() { +} + +void ora() { + value = getvalue(); + result = (uint16_t)a | value; + + zerocalc(result); + signcalc(result); + + saveaccum(result); +} + +void pha() { + push8(a); +} + +void php() { + push8(cpustatus | FLAG_BREAK); +} + +void pla() { + a = pull8(); + + zerocalc(a); + signcalc(a); +} + +void plp() { + cpustatus = pull8() | FLAG_CONSTANT; +} + +void rol() { + value = getvalue(); + result = (value << 1) | (cpustatus & FLAG_CARRY); + + carrycalc(result); + zerocalc(result); + signcalc(result); + + putvalue(result); +} + +void ror() { + value = getvalue(); + result = (value >> 1) | ((cpustatus & FLAG_CARRY) << 7); + + if (value & 1) setcarry(); + else clearcarry(); + zerocalc(result); + signcalc(result); + + putvalue(result); +} + +void rti() { + cpustatus = pull8(); + value = pull16(); + pc = value; +} + +void rts() { + value = pull16(); + pc = value + 1; +} + +void sbc() { + value = getvalue() ^ 0x00FF; + result = (uint16_t)a + value + (uint16_t)(cpustatus & FLAG_CARRY); + + carrycalc(result); + zerocalc(result); + overflowcalc(result, a, value); + signcalc(result); + + #ifndef NES_CPU + if (cpustatus & FLAG_DECIMAL) { + clearcarry(); + + a -= 0x66; + if ((a & 0x0F) > 0x09) { + a += 0x06; + } + if ((a & 0xF0) > 0x90) { + a += 0x60; + setcarry(); + } + + //clockticks6502++; + } + #endif + + saveaccum(result); +} + +void sec() { + setcarry(); +} + +void sed() { + setdecimal(); +} + +void sei() { + setinterrupt(); +} + +void sta() { + putvalue(a); +} + +void stx() { + putvalue(x); +} + +void sty() { + putvalue(y); +} + +void tax() { + x = a; + + zerocalc(x); + signcalc(x); +} + +void tay() { + y = a; + + zerocalc(y); + signcalc(y); +} + +void tsx() { + x = sp; + + zerocalc(x); + signcalc(x); +} + +void txa() { + a = x; + + zerocalc(a); + signcalc(a); +} + +void txs() { + sp = x; +} + +void tya() { + a = y; + + zerocalc(a); + signcalc(a); +} + +//undocumented instructions +#ifdef UNDOCUMENTED + void lax() { + lda(); + ldx(); + } + + void sax() { + sta(); + stx(); + putvalue(a & x); + } + + void dcp() { + dec(); + cmp(); + } + + void isb() { + inc(); + sbc(); + } + + void slo() { + asl(); + ora(); + } + + void rla() { + rol(); + op_and(); + } + + void sre() { + lsr(); + eor(); + } + + void rra() { + ror(); + adc(); + } +#else + #define lax nop + #define sax nop + #define dcp nop + #define isb nop + #define slo nop + #define rla nop + #define sre nop + #define rra nop +#endif + + +void nmi6502() { + push16(pc); + push8(cpustatus); + cpustatus |= FLAG_INTERRUPT; + pc = (uint16_t)read6502(0xFFFA) | ((uint16_t)read6502(0xFFFB) << 8); +} + +void irq6502() { + push16(pc); + push8(cpustatus); + cpustatus |= FLAG_INTERRUPT; + pc = (uint16_t)read6502(0xFFFE) | ((uint16_t)read6502(0xFFFF) << 8); +} + +#ifdef USE_TIMING +prog_char ticktable[256] PROGMEM = { +/* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F | */ +/* 0 */ 7, 6, 2, 8, 3, 3, 5, 5, 3, 2, 2, 2, 4, 4, 6, 6, /* 0 */ +/* 1 */ 2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, /* 1 */ +/* 2 */ 6, 6, 2, 8, 3, 3, 5, 5, 4, 2, 2, 2, 4, 4, 6, 6, /* 2 */ +/* 3 */ 2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, /* 3 */ +/* 4 */ 6, 6, 2, 8, 3, 3, 5, 5, 3, 2, 2, 2, 3, 4, 6, 6, /* 4 */ +/* 5 */ 2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, /* 5 */ +/* 6 */ 6, 6, 2, 8, 3, 3, 5, 5, 4, 2, 2, 2, 5, 4, 6, 6, /* 6 */ +/* 7 */ 2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, /* 7 */ +/* 8 */ 2, 6, 2, 6, 3, 3, 3, 3, 2, 2, 2, 2, 4, 4, 4, 4, /* 8 */ +/* 9 */ 2, 6, 2, 6, 4, 4, 4, 4, 2, 5, 2, 5, 5, 5, 5, 5, /* 9 */ +/* A */ 2, 6, 2, 6, 3, 3, 3, 3, 2, 2, 2, 2, 4, 4, 4, 4, /* A */ +/* B */ 2, 5, 2, 5, 4, 4, 4, 4, 2, 4, 2, 4, 4, 4, 4, 4, /* B */ +/* C */ 2, 6, 2, 8, 3, 3, 5, 5, 2, 2, 2, 2, 4, 4, 6, 6, /* C */ +/* D */ 2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, /* D */ +/* E */ 2, 6, 2, 8, 3, 3, 5, 5, 2, 2, 2, 2, 4, 4, 6, 6, /* E */ +/* F */ 2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7 /* F */ +}; +#endif + +void exec6502() { +#ifdef USE_TIMING + clockgoal6502 += tickcount; + + while (clockgoal6502 > 0) { +#else + //while (tickcount--) { +#endif + opcode = read6502(pc++); + cpustatus |= FLAG_CONSTANT; + + useaccum = 0; + + switch (opcode) { + case 0x0: + imp(); + brk(); + break; + case 0x1: + indx(); + ora(); + break; + case 0x5: + zp(); + ora(); + break; + case 0x6: + zp(); + asl(); + break; + case 0x8: + imp(); + php(); + break; + case 0x9: + imm(); + ora(); + break; + case 0xA: + acc(); + asl(); + break; + case 0xD: + abso(); + ora(); + break; + case 0xE: + abso(); + asl(); + break; + case 0x10: + rel(); + bpl(); + break; + case 0x11: + indy(); + ora(); + break; + case 0x15: + zpx(); + ora(); + break; + case 0x16: + zpx(); + asl(); + break; + case 0x18: + imp(); + clc(); + break; + case 0x19: + absy(); + ora(); + break; + case 0x1D: + absx(); + ora(); + break; + case 0x1E: + absx(); + asl(); + break; + case 0x20: + abso(); + jsr(); + break; + case 0x21: + indx(); + op_and(); + break; + case 0x24: + zp(); + op_bit(); + break; + case 0x25: + zp(); + op_and(); + break; + case 0x26: + zp(); + rol(); + break; + case 0x28: + imp(); + plp(); + break; + case 0x29: + imm(); + op_and(); + break; + case 0x2A: + acc(); + rol(); + break; + case 0x2C: + abso(); + op_bit(); + break; + case 0x2D: + abso(); + op_and(); + break; + case 0x2E: + abso(); + rol(); + break; + case 0x30: + rel(); + bmi(); + break; + case 0x31: + indy(); + op_and(); + break; + case 0x35: + zpx(); + op_and(); + break; + case 0x36: + zpx(); + rol(); + break; + case 0x38: + imp(); + sec(); + break; + case 0x39: + absy(); + op_and(); + break; + case 0x3D: + absx(); + op_and(); + break; + case 0x3E: + absx(); + rol(); + break; + case 0x40: + imp(); + rti(); + break; + case 0x41: + indx(); + eor(); + break; + case 0x45: + zp(); + eor(); + break; + case 0x46: + zp(); + lsr(); + break; + case 0x48: + imp(); + pha(); + break; + case 0x49: + imm(); + eor(); + break; + case 0x4A: + acc(); + lsr(); + break; + case 0x4C: + abso(); + jmp(); + break; + case 0x4D: + abso(); + eor(); + break; + case 0x4E: + abso(); + lsr(); + break; + case 0x50: + rel(); + bvc(); + break; + case 0x51: + indy(); + eor(); + break; + case 0x55: + zpx(); + eor(); + break; + case 0x56: + zpx(); + lsr(); + break; + case 0x58: + imp(); + cli(); + break; + case 0x59: + absy(); + eor(); + break; + case 0x5D: + absx(); + eor(); + break; + case 0x5E: + absx(); + lsr(); + break; + case 0x60: + imp(); + rts(); + break; + case 0x61: + indx(); + adc(); + break; + case 0x65: + zp(); + adc(); + break; + case 0x66: + zp(); + ror(); + break; + case 0x68: + imp(); + pla(); + break; + case 0x69: + imm(); + adc(); + break; + case 0x6A: + acc(); + ror(); + break; + case 0x6C: + ind(); + jmp(); + break; + case 0x6D: + abso(); + adc(); + break; + case 0x6E: + abso(); + ror(); + break; + case 0x70: + rel(); + bvs(); + break; + case 0x71: + indy(); + adc(); + break; + case 0x75: + zpx(); + adc(); + break; + case 0x76: + zpx(); + ror(); + break; + case 0x78: + imp(); + sei(); + break; + case 0x79: + absy(); + adc(); + break; + case 0x7D: + absx(); + adc(); + break; + case 0x7E: + absx(); + ror(); + break; + case 0x81: + indx(); + sta(); + break; + case 0x84: + zp(); + sty(); + break; + case 0x85: + zp(); + sta(); + break; + case 0x86: + zp(); + stx(); + break; + case 0x88: + imp(); + dey(); + break; + case 0x8A: + imp(); + txa(); + break; + case 0x8C: + abso(); + sty(); + break; + case 0x8D: + abso(); + sta(); + break; + case 0x8E: + abso(); + stx(); + break; + case 0x90: + rel(); + bcc(); + break; + case 0x91: + indy(); + sta(); + break; + case 0x94: + zpx(); + sty(); + break; + case 0x95: + zpx(); + sta(); + break; + case 0x96: + zpy(); + stx(); + break; + case 0x98: + imp(); + tya(); + break; + case 0x99: + absy(); + sta(); + break; + case 0x9A: + imp(); + txs(); + break; + case 0x9D: + absx(); + sta(); + break; + case 0xA0: + imm(); + ldy(); + break; + case 0xA1: + indx(); + lda(); + break; + case 0xA2: + imm(); + ldx(); + break; + case 0xA4: + zp(); + ldy(); + break; + case 0xA5: + zp(); + lda(); + break; + case 0xA6: + zp(); + ldx(); + break; + case 0xA8: + imp(); + tay(); + break; + case 0xA9: + imm(); + lda(); + break; + case 0xAA: + imp(); + tax(); + break; + case 0xAC: + abso(); + ldy(); + break; + case 0xAD: + abso(); + lda(); + break; + case 0xAE: + abso(); + ldx(); + break; + case 0xB0: + rel(); + bcs(); + break; + case 0xB1: + indy(); + lda(); + break; + case 0xB4: + zpx(); + ldy(); + break; + case 0xB5: + zpx(); + lda(); + break; + case 0xB6: + zpy(); + ldx(); + break; + case 0xB8: + imp(); + clv(); + break; + case 0xB9: + absy(); + lda(); + break; + case 0xBA: + imp(); + tsx(); + break; + case 0xBC: + absx(); + ldy(); + break; + case 0xBD: + absx(); + lda(); + break; + case 0xBE: + absy(); + ldx(); + break; + case 0xC0: + imm(); + cpy(); + break; + case 0xC1: + indx(); + cmp(); + break; + case 0xC4: + zp(); + cpy(); + break; + case 0xC5: + zp(); + cmp(); + break; + case 0xC6: + zp(); + dec(); + break; + case 0xC8: + imp(); + iny(); + break; + case 0xC9: + imm(); + cmp(); + break; + case 0xCA: + imp(); + dex(); + break; + case 0xCC: + abso(); + cpy(); + break; + case 0xCD: + abso(); + cmp(); + break; + case 0xCE: + abso(); + dec(); + break; + case 0xD0: + rel(); + bne(); + break; + case 0xD1: + indy(); + cmp(); + break; + case 0xD5: + zpx(); + cmp(); + break; + case 0xD6: + zpx(); + dec(); + break; + case 0xD8: + imp(); + cld(); + break; + case 0xD9: + absy(); + cmp(); + break; + case 0xDD: + absx(); + cmp(); + break; + case 0xDE: + absx(); + dec(); + break; + case 0xE0: + imm(); + cpx(); + break; + case 0xE1: + indx(); + sbc(); + break; + case 0xE4: + zp(); + cpx(); + break; + case 0xE5: + zp(); + sbc(); + break; + case 0xE6: + zp(); + inc(); + break; + case 0xE8: + imp(); + inx(); + break; + case 0xE9: + imm(); + sbc(); + break; + case 0xEB: + imm(); + sbc(); + break; + case 0xEC: + abso(); + cpx(); + break; + case 0xED: + abso(); + sbc(); + break; + case 0xEE: + abso(); + inc(); + break; + case 0xF0: + rel(); + beq(); + break; + case 0xF1: + indy(); + sbc(); + break; + case 0xF5: + zpx(); + sbc(); + break; + case 0xF6: + zpx(); + inc(); + break; + case 0xF8: + imp(); + sed(); + break; + case 0xF9: + absy(); + sbc(); + break; + case 0xFD: + absx(); + sbc(); + break; + case 0xFE: + absx(); + inc(); + break; + } +#ifdef USE_TIMING + clockgoal6502 -= (int32_t)pgm_read_byte_near(ticktable + opcode); +#endif + //instructions++; + //} //while +} + +uint16_t getpc() { + return(pc); +} + +uint8_t getop() { + return(opcode); +} + + diff --git a/trunk/Arduino/Single_Chip_VIC20/lightbox_NANO20.jpg b/trunk/Arduino/Single_Chip_VIC20/lightbox_NANO20.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c499e47b90bce7874d15a0eef7e78ea757a98915 GIT binary patch literal 35053 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 z zHM-iS0f;@R(_3uq>HMg5nW4TJyER_I$*91X)d97}Yjw12B5EUYf*0n?cqsI;jKdNQ zLqgi!Yli%hM~rjOBuB*6m#VsVk+XN4jz(PZ$~!gvQP3l<8v?A|EZo27FndV6ATB!YBN;tw!(jn{)xF0@WXXsV@WEsP!&(O42#IY6>VD_F-h-@;=M7-(ps5hj^Lmx5W&X56~(s?>WW%Y-8*bPP?Kj;2Z z6vyGAT#b&^T9Z|3LThk06t4&h2z+fCpcI0|SJHfAm|%Zn_b5B05*Vp+fAjtyjYRwl z;RhhN@h_4sjv+?JI>s_;-{gU_=LA$|vQ)04(?c72H>Y%S2z zL}7SB4G_o1?HQ;)wo#pjHb{+K`{VpdfWL9y=Bva~)ZK=>&1K_TzS)5l9~^m;BZ4cq zZ(SVVs1J0XDwG52OMsMH^ZuKBeIGIaui94l4+~Gs=uGoHb4CdMLRe_hpgcKUoV&bl zbANVf(&MGmvFaDAxpdXV9w1o@+cNBz)#exOimS@aIQ*CW|FZwzB~JdD|NmOT<*)VU z4-4N2toEoWA<5AJSbIgJFf~F?!2?s)bG9rm#Q`K_i_+@p@hFi7wgzCSDxPM*&^yQ8ItM2kCAK;5F0LTCR zz4%WZ>!%@oZf@Z4f0D)j%ve7S>GP=t9R7bXyZ*&kfgybPD{$h}{2gTAw~Vi=p|40f z2idLNC2nKKSYtemm)2EFCSCTcNO?}(_gSN4-M^arWwHPA3G>C;JD|kj zQ49K&FMIUc%59NJVTh(mX9TG;eda`L)5Q&m_m6=D(ZkKEHb=fQx?f?a4>wdEg{)a7pf8B5Qg#W1N@2~r3BlxGSzZRxdR3}%< z`Ovg7mAjR^+7vurEK6?%W-Ym{14Y~5p5UzzWZ$Q3AB2rGPa2h6m4?xjye0BKMzikU zCHj==OZSv9Rtti=wthb}ZaKJnV+rlMB`p%$TZ?v6>ygDz7L_>o=HfeCwQ3-|rlxdD T5)mJ8{+}B2zwD&Q$FctfIQLk; literal 0 HcmV?d00001 diff --git a/trunk/Arduino/esp32-cam-webserver/.gitignore b/trunk/Arduino/esp32-cam-webserver/.gitignore new file mode 100644 index 00000000..4dce4cfb --- /dev/null +++ b/trunk/Arduino/esp32-cam-webserver/.gitignore @@ -0,0 +1,7 @@ +myconfig.h +.pioenvs +.piolibdeps +.clang_complete +.gcc-flags.json +.pio +.vscode \ No newline at end of file diff --git a/trunk/Arduino/esp32-cam-webserver/.travis.yml b/trunk/Arduino/esp32-cam-webserver/.travis.yml new file mode 100644 index 00000000..e0ac0393 --- /dev/null +++ b/trunk/Arduino/esp32-cam-webserver/.travis.yml @@ -0,0 +1,42 @@ +sudo: false + +language: bash + +os: + - linux + +dist: focal + +before_script: + - "export DISPLAY=:99.0" + - sleep 3 # give xvfb some time to start + - wget http://downloads.arduino.cc/arduino-1.8.13-linux64.tar.xz + - tar xf arduino-1.8.13-linux64.tar.xz + - mv arduino-1.8.13 $HOME/arduino_ide + - cd $HOME/arduino_ide/hardware + - mkdir esp32 + - cd esp32 + - git clone --depth 1 https://github.com/espressif/arduino-esp32.git esp32 + - cd esp32 + - git submodule update --init --recursive + - cd tools + - python --version + - python get.py + - pip install --user platformio + - platformio update + +script: + - cd $TRAVIS_BUILD_DIR + - export PATH="$HOME/arduino_ide:$PATH" + - arduino --board esp32:esp32:esp32:PartitionScheme=huge_app,FlashFreq=80 --pref compiler.warning_level=all --save-prefs + - arduino --verbose --verify esp32-cam-webserver.ino + - cp --preserve --verbose myconfig.sample.h myconfig.h + - arduino --verbose --verify esp32-cam-webserver.ino + - platformio run + + +notifications: + email: + on_success: change + on_failure: change + diff --git a/trunk/Arduino/esp32-cam-webserver/API.md b/trunk/Arduino/esp32-cam-webserver/API.md new file mode 100644 index 00000000..90896ec2 --- /dev/null +++ b/trunk/Arduino/esp32-cam-webserver/API.md @@ -0,0 +1,89 @@ +# Basic HTTP Commands; +It's an API Jim, but not as we know it + +The WebUI and camera server communicate entirely via HTTP requests and responses; this makes controlling all functions of the camera via GET requests possible. An API in effect. + +## URI's +### Http Port +* `/` - Default index +* `/?target=full|simple|portal` - Go direct to specific index +* `/capture` - Return a Jpeg snapshot image +* `/status` - Returns a JSON string with all camera status / pairs listed +* `/control?var=&val=` - Set `` to `` +* `/dump` - Status page + +### Stream Port +* `/` - Raw stream +* `/view` - Stream viewer + +## *key / val* settings and commands + +Call the `/status` URI to recieve a JSON response containing all the available settings and current value. + +Call `/control?var=&val=` with a settings key and value to set camera properties or trigger actions. + +#### Settings +``` +lamp - Lamp value in percent; integer, 0 - 100 (-1 = disabled) +framesize - 0=QQVGA, 3=HQVGA, QVGA=4, CIF=5, VGA=6, SVGA=7, XGA=8, SXGA=9, UXGA=10, QXGA(ov3660)=11 +quality - 10 to 63 (ov3660: 4 to 10) +contrast - -2 to 2 (ov3660: -3 to 3) +brightness - -2 to 2 (ov3660: -3 to 3) +saturation - -2 to 2 (ov3660: -4 to 4) +sharpness - (ov3660: -3 to 3) +denoise - (ov3660: 0 to 8) +ae_level - (ov3660: -5 to 5) +special_effect - 0=No Effect, 1=Negative, 2=Grayscale, 3=Red Tint, 4=Green Tint, 5=Blue Tint, 6=Sepia +awb - 0 = disable, 1 = enable +awb_gain - 0 = disable, 1 = enable +wb_mode - if awb enabled: 0=Auto, 1=Sunny, 2=Cloudy, 3=Office, 4=Home +aec - 0 = disable, 1 = enable +aec_value - 0 to 1200 (ov3660: 0 to 1536) +aec2 - 0 = disable, 1 = enable +ae_level - -2 to 2 (not ov3660) +agc - 0 = disable, 1 = enable +agc_gain - 0 to 30 (ov3660: 0 to 64) +gainceiling - 0 to 6 (ov3660: 0 to 511) +bpc - 0 = disable, 1 = enable +wpc - 0 = disable, 1 = enable +raw_gma - 0 = disable, 1 = enable +lenc - 0 = disable, 1 = enable +hmirror - 0 = disable, 1 = enable +vflip - 0 = disable, 1 = enable +rotate - Rotation Angle; integer, only -90, 0, 90 values are recognised +dcw - 0 = disable, 1 = enable +colorbar - Overlays a color test pattern on the stream; integer, 1 = enabled +face_detect - Face Detection; 1 = enabled, Only settable if framesize <= 4 (CIF) +face_recognize - Face recognition; 1 = enabled, only settable if Face detection is already enabled +``` +#### Read Only +These values are returned in the `/status` JSON response, but cannot be set via the `/control` URI. +``` +cam_name - Camera Name; String +code_ver - Code compile date and time; String +stream_url - Raw stream URL; string +``` +#### Commands +These are commands; they can be sent by calling the `/control` URI with them as the `` *(a `` must also be supplied, but can be any value and is ignored)*. +``` +face_enroll - Enroll a new face in the FaceDB (only when face recognition is avctive) +save_prefs - Saves preferences file +clear_prefs - Deletes the preferences file +reboot - Reboots the camera +``` +## Examples +* Flash light: on/mid/off + * `http:///control?var=lamp&val=100` + * `http:///control?var=lamp&val=50` + * `http:///control?var=lamp&val=0` +* Set resolution to VGA + * `http:///control?var=framesize&val=6` +* Show camera details and settings + * All settings are returned via single `status` call in [JSON](https://www.json.org/) format. + * `http:///status` + * Returns: + ``` {"lamp":0,"autolamp":0,"framesize":10,"quality":10,"brightness":0,"contrast":0,"saturation":0,"sharpness":0,"special_effect":0,"wb_mode":0,"awb":1,"awb_gain":1,"aec":1,"aec2":0,"ae_level":0,"aec_value":168,"agc":1,"agc_gain":0,"gainceiling":0,"bpc":0,"wpc":1,"raw_gma":1,"lenc":1,"vflip":0,"hmirror":0,"dcw":1,"colorbar":0,"face_detect":0,"face_enroll":0,"face_recognize":0,"cam_name":"General","code_ver":"Mar 6 2021 @ 17:54:00","rotate":"0","stream_url":"http://10.0.0.190:81/"}``` +* Reboot the camera + * `http:///control?var=reboot&val=0` + +You can try these yourself in a browser address bar, from the commandline with `curl` and co. or use them programatically from your scripting language of choice. diff --git a/trunk/Arduino/esp32-cam-webserver/CONTRIBUTING.md b/trunk/Arduino/esp32-cam-webserver/CONTRIBUTING.md new file mode 100644 index 00000000..cc8b8d63 --- /dev/null +++ b/trunk/Arduino/esp32-cam-webserver/CONTRIBUTING.md @@ -0,0 +1,49 @@ +# Contributing to ESP32-CAM revisited +I love your input! and want to make contributing to this project as easy and transparent as possible, whether it's: + +- Reporting a bug +- Discussing the current state of the code +- Submitting a fix +- Proposing new features +- Becoming a maintainer + +## I Develop with Github +I use github to host code, to track issues and feature requests, as well as accept pull requests. + +## I Use [Github Flow](https://guides.github.com/introduction/flow/index.html), So All Code Changes Happen Through Pull Requests +Pull requests are the best way to propose changes to the codebase (I use [Github Flow](https://guides.github.com/introduction/flow/index.html)). I actively welcome your pull requests: + +1. Fork the repo and create your branch from `master`. +2. Give your branch a clear descriptive name and do your changes there. +3. If you've changed the HTTP APIs, update the documentation. +4. Issue a pull request against a branch *of the same name* in the main repo. +5. Clearly describe your changes and the reason for them in the pull request. + +## Any contributions you make will be under the GNU Lesser General Public License v2.1 +In short, when you submit code changes, your submissions are understood to be under the same [License](./LICENSE) that covers the project. + +## Report bugs using Github's [issues](https://github.com/easytarget/esp32-cam-webserver/issues) +We use GitHub issues to track public bugs. Report a bug by opening a new issue; it's that easy! + +## Write bug reports with detail, background, and sample code + +**Great Bug Reports** tend to have: + +- A quick summary and/or background +- Steps to reproduce + - Be specific! +- What you expected would happen +- What actually happens +- Notes (possibly including why you think this might be happening, or stuff you tried that didn't work) + +People *love* thorough bug reports. I'm not even kidding. + +## Use a Consistent Coding Style +* 4 spaces for indentation rather than tabs in the main code + +## License +By contributing, you agree that your contributions will be licensed under its GNU Lesser General Public License v2.1 + + +## References +This document was adapted from the open-source contribution guidelines for [Facebook's Draft](https://github.com/facebook/draft-js/blob/a9316a723f9e918afde44dea68b5f9f39b7d9b00/CONTRIBUTING.md) diff --git a/trunk/Arduino/esp32-cam-webserver/Docs/board-selection-small.png b/trunk/Arduino/esp32-cam-webserver/Docs/board-selection-small.png new file mode 100644 index 0000000000000000000000000000000000000000..a67680d0c5a1db9a91897f2180b72ce4dffa5539 GIT binary patch literal 223751 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

    5~9IC@a7l`=Q@94H(m(Sh{CVU`QI2DN5u!k;vp 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νDzXD@0xn<1E1A#Aj-KDZru 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 C1abkqC5XI8 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

    )a&na+X&t33Y3Dn) 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

    VZZMM(!Um03b2vXkUETS} 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 +#include + +//int pwmBits = 9; // Number of PWM bits + +int main(int argc, char **argv) { + if (argc != 2) { + printf("\nERROR: This utility expects a single parameter; the bit-width of the PWM stream\n\n"); + return 1; } + + int pwmBits = atoi(argv[1]); + + if (pwmBits < 2 || pwmBits > 16) { + printf("\nERROR: '%s' is not an integer in the range 2-16.\n\n", argv[1]); + return 1; } + + int pwmMax = pow(2,pwmBits)-1; + + printf("\nThe PWM Bit width (resolution) specified is %i, pwm range is from 0 to %i\n-----------\n", pwmBits, pwmMax); + + for (int val = 0; val <= 100; val++) { + int pwm = round((pow(2,(1+(val*0.02)))-2)/6*pwmMax); + printf(" %3i : %5i\n", val, pwm); + } + printf("\n"); + return 0; +} +``` + +Adjust the width as necesscary and compile with: + + $ gcc linearled.c -o linearled -lm + +And run to see the results: +```bash +$ ./linearled 9 + +The PWM Bit width (resolution) specified is 9, pwm range is from 0 to 511 +----------- + 0 : 0 + 1 : 2 + 2 : 5 + 3 : 7 + 4 : 10 + 5 : 12 + 6 : 15 + 7 : 17 + 8 : 20 + 9 : 23 + 10 : 25 + 11 : 28 + 12 : 31 + 13 : 34 + 14 : 36 + 15 : 39 + 16 : 42 + 17 : 45 + 18 : 48 + 19 : 51 + 20 : 54 + 21 : 58 + 22 : 61 + 23 : 64 + 24 : 67 + 25 : 71 + 26 : 74 + 27 : 77 + 28 : 81 + 29 : 84 + 30 : 88 + 31 : 91 + 32 : 95 + 33 : 99 + 34 : 103 + 35 : 106 + 36 : 110 + 37 : 114 + 38 : 118 + 39 : 122 + 40 : 126 + 41 : 130 + 42 : 135 + 43 : 139 + 44 : 143 + 45 : 148 + 46 : 152 + 47 : 156 + 48 : 161 + 49 : 166 + 50 : 170 + 51 : 175 + 52 : 180 + 53 : 185 + 54 : 190 + 55 : 195 + 56 : 200 + 57 : 205 + 58 : 210 + 59 : 216 + 60 : 221 + 61 : 226 + 62 : 232 + 63 : 238 + 64 : 243 + 65 : 249 + 66 : 255 + 67 : 261 + 68 : 267 + 69 : 273 + 70 : 279 + 71 : 285 + 72 : 292 + 73 : 298 + 74 : 305 + 75 : 311 + 76 : 318 + 77 : 325 + 78 : 332 + 79 : 339 + 80 : 346 + 81 : 353 + 82 : 361 + 83 : 368 + 84 : 375 + 85 : 383 + 86 : 391 + 87 : 399 + 88 : 407 + 89 : 415 + 90 : 423 + 91 : 431 + 92 : 439 + 93 : 448 + 94 : 457 + 95 : 465 + 96 : 474 + 97 : 483 + 98 : 492 + 99 : 502 + 100 : 511 +``` + +The code can be adapted into your custom LED setting function + + diff --git a/trunk/Arduino/esp32-cam-webserver/Docs/linearled/linearled.c b/trunk/Arduino/esp32-cam-webserver/Docs/linearled/linearled.c new file mode 100644 index 00000000..98b2e693 --- /dev/null +++ b/trunk/Arduino/esp32-cam-webserver/Docs/linearled/linearled.c @@ -0,0 +1,29 @@ +/* Dump linear led values */ +#include "stdio.h" +#include +#include + +//int pwmBits = 9; // Number of PWM bits + +int main(int argc, char **argv) { + if (argc != 2) { + printf("\nERROR: This utility expects a single parameter; the bit-width of the PWM stream\n\n"); + return 1; } + + int pwmBits = atoi(argv[1]); + + if (pwmBits < 2 || pwmBits > 16) { + printf("\nERROR: '%s' is not an integer in the range 2-16.\n\n", argv[1]); + return 1; } + + int pwmMax = pow(2,pwmBits)-1; + + printf("\nThe PWM Bit width (resolution) specified is %i, pwm range is from 0 to %i\n-----------\n", pwmBits, pwmMax); + + for (int val = 0; val <= 100; val++) { + int pwm = round((pow(2,(1+(val*0.02)))-2)/6*pwmMax); + printf(" %3i : %5i\n", val, pwm); + } + printf("\n"); + return 0; +} diff --git a/trunk/Arduino/esp32-cam-webserver/Docs/logo-big.png b/trunk/Arduino/esp32-cam-webserver/Docs/logo-big.png new file mode 100644 index 0000000000000000000000000000000000000000..04132891b91a75844a235a15df1465b72a6aef0d GIT binary patch literal 37687 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 a|6MK&-(sRWMY3EK0)q`~qmYP>IT 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 + + + + + image/svg+xml + + + + + + + + ESP32 CAM Webserver - logo + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/trunk/Arduino/esp32-cam-webserver/Docs/mygodsitsfullofcats.png b/trunk/Arduino/esp32-cam-webserver/Docs/mygodsitsfullofcats.png new file mode 100644 index 0000000000000000000000000000000000000000..0fe2b07bfaae7751fd00c925575c90aa0ad6c88d GIT binary patch literal 632096 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

    4$RMHen%;gM%2GRa48w57DWX# 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 z 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�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%0DRy6nzp|+XOgy)q#zU3>+T7?;3t<24G&!%7 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Π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'^!pJY08UrO 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 F1OTRL3hw{_ literal 0 HcmV?d00001 diff --git a/trunk/Arduino/esp32-cam-webserver/Docs/favicon-32x32.png b/trunk/Arduino/esp32-cam-webserver/Docs/favicon-32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..c1818b40743cd4434df8d5d3cbebccb0091052b9 GIT binary patch literal 1051 zcmV+$1mydPP)Px#32;bRa{vGZcK`qdcLB)HDWCuV0NYSZR7Ff_ao{o} z=rSkhGAN^Fj_5Kd=rSkhGAQXXDC#mM=rSkiGAHUXCg?IK=`kqjGAQXWDCjXK=rSlK zRIfj7*Xl1O=rSniF(+E6+UPPU=`twjGAJrq!bf%0=rbq*9A0wT^8+%JYvJ^w`20a} z+89QsulfD2`27q*rv^8jlIi)g{r?0toA~+s=`tt*8(c=D)s4>cXWQ~!$>~Cz(MPD) zaI5OV=IC9|_D2reVHUx*rq6Eh$nqVSI~4pVQ!UXlkQXSxXia&i3wU*{~}^}s!4PGMiFX8KfD;(Gd3iM&WD1TYHZpwk;m03_}PK=te5Q$6oxtq3@C3zZ{RdRrQF9s4fJ6 zMF8_J6ae|}N5rUlYF$v1MUMS$1^ZtpSXK|{!c+H37o?+!HKmxK;Ky$FT2=S!HV54! za||%3$_^?f+p4N=4^uo>_f5|GE{2QSszK+V1TI>r zUyAJnxDIFUyb@$V&~NT{Y|*1LzO5+#9rDV~yy4t3e>|2y8AU;&p>>OK>v zV1EI}`DJIfF7004NLRkW; literal 0 HcmV?d00001 diff --git a/trunk/Arduino/esp32-cam-webserver/Docs/favicon-README.md b/trunk/Arduino/esp32-cam-webserver/Docs/favicon-README.md new file mode 100644 index 00000000..524a6a27 --- /dev/null +++ b/trunk/Arduino/esp32-cam-webserver/Docs/favicon-README.md @@ -0,0 +1,21 @@ +# Favicons + +Source: A logo I created from the espressif logo, using inkscape + +![logo image](../Docs/logo.svg) + +## The 16x16 and 32x32 png images were extracted from a Favicon Package + +This package was generated with [RealFaviconGenerator](https://realfavicongenerator.net/) + +A very handy site, dont forget to select compression options in the 'html5' section, they are in a hard to spot tab. Doing this reduced the `.png`sizes by ~74% :-) + +## The favicon.ico itself came from the command line + +The [Imagemagick](https://imagemagick.org/) tool provides a simple image converter that can create `.ico` files from a source image in another format. I simply needed to use this on the 32x32 png icon to make a suitably high-definition icon file. +``` +$ convert favicon-32x32.png favicon.ico +``` + +## favicons.h +The icon files were packed into the `favicons.h` header using `xxd -i ` to generate the C compatible data structures, and then editing that with comments and adding PROGMEM directives to save on ram use. They should be stable and unlikely to change in the future. diff --git a/trunk/Arduino/esp32-cam-webserver/Docs/favicon.ico b/trunk/Arduino/esp32-cam-webserver/Docs/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..99fa5ef52331c31024414aa0c38a65b89444dc86 GIT binary patch literal 4286 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

    LzI} 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�_y8B|X6qa6gy?xUi2lJD~R?^{|1$JW*%` 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¥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%0DhDR0BQZhu~Rrii0ais`%|syj4Q8N10+C(lmr0i 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

    +5r8g}#mCUsNhY%v3mwnq+SdZCjsI!z;D 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�aoBj)e2n3yKln^ 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

  • $W;obLUGIxK(t;rJpc$zSClp1bl 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